From c89e9afc5d43837c498a55f8f13ddf235442b83b Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 12 Jan 2010 15:51:39 +0000 Subject: [PATCH 0001/3781] Initial import of the gstreamer-vaapi hierarchy. --- AUTHORS | 1 + COPYING | 339 +++++++++++++++++++++++++++++++++ Makefile.am | 9 + NEWS | 5 + README | 26 +++ autogen.sh | 3 + configure.ac | 112 +++++++++++ gst-libs/Makefile.am | 4 + gst-libs/gst/Makefile.am | 4 + gst-libs/gst/vaapi/Makefile.am | 13 ++ sys/Makefile.am | 4 + sys/vaapi/Makefile.am | 15 ++ 12 files changed, 535 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100755 autogen.sh create mode 100644 configure.ac create mode 100644 gst-libs/Makefile.am create mode 100644 gst-libs/gst/Makefile.am create mode 100644 gst-libs/gst/vaapi/Makefile.am create mode 100644 sys/Makefile.am create mode 100644 sys/vaapi/Makefile.am diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000000..455858155c --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Gwenole Beauchesne - Primary author diff --git a/COPYING b/COPYING new file mode 100644 index 0000000000..d511905c16 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 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. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000000..d931a82e68 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,9 @@ +AUTOMAKE_OPTIONS = foreign + +SUBDIRS = gst-libs sys + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = \ + aclocal.m4 compile config.guess config.sub \ + configure depcomp install-sh ltmain.sh \ + Makefile.in missing config.h.in diff --git a/NEWS b/NEWS new file mode 100644 index 0000000000..297704a094 --- /dev/null +++ b/NEWS @@ -0,0 +1,5 @@ +gst-vaapi NEWS -- summary of changes. 2010-01-DD +Copyright (C) 2010 Splitted-Desktop Systems + +Version 0.1.0 - DD.Jan.2010 +* Initial release diff --git a/README b/README new file mode 100644 index 0000000000..3dcad3f885 --- /dev/null +++ b/README @@ -0,0 +1,26 @@ + + gst-vaapi + VA API support to GStreamer + + Copyright (C) 2010 Splitted-Desktop Systems + + +License +------- + +gst-vaapi is available under the terms of the GNU General Public +License. + + +Overview +-------- + +gst-vaapi consists in a VA API based videosink for GStreamer and +helper libraries. + + +Requirements +------------ + +gstreamer-0.10 >= 0.10.0 +gstreamer-plugins-base-0.10 >= 0.10.0 diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000000..9c2f4f6699 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,3 @@ +#! /bin/sh +autoreconf -v --install +./configure "$@" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000000..08c64a53e0 --- /dev/null +++ b/configure.ac @@ -0,0 +1,112 @@ +# gst version number +m4_define([gst_major_version], [0]) +m4_define([gst_minor_version], [10]) +m4_define([gst_micro_version], [0]) +m4_define([gst_major_minor_version], + [gst_major_version.gst_minor_version]) +m4_define([gst_version], + [gst_major_version.gst_minor_version.gst_micro_version]) + +# gst plugins-base version number +m4_define([gst_plugins_base_major_version], [0]) +m4_define([gst_plugins_base_minor_version], [10]) +m4_define([gst_plugins_base_micro_version], [0]) +m4_define([gst_plugins_base_version], + [gst_plugins_base_major_version.gst_plugins_base_minor_version.gst_plugins_base_micro_version]) + +# gst_vaapi package version number +m4_define([gst_vaapi_major_version], [0]) +m4_define([gst_vaapi_minor_version], [1]) +m4_define([gst_vaapi_micro_version], [0]) +m4_define([gst_vaapi_version], + [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) + +AC_PREREQ([2.57]) +AC_INIT([gst_vaapi], [gst_vaapi_version], + [gbeauchesne@splitted-desktop.com], + [gstreamer-vaapi]) +AC_CONFIG_SRCDIR([Makefile.am]) +AC_CANONICAL_TARGET +AM_INIT_AUTOMAKE +AM_CONFIG_HEADER([config.h]) + +dnl Versions for GStreamer and plugins-base +GST_MAJORMINOR=gst_major_minor_version +GST_VERSION_REQUIRED=gst_version +GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version +AC_SUBST(GST_MAJORMINOR) + +dnl Check for tools +AC_PROG_CC +AC_PROG_LIBTOOL + +dnl Check for GStreamer +PKG_CHECK_MODULES([GST], + [gstreamer-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED] +) +AC_SUBST(GST_CFLAGS) +AC_SUBST(GST_LIBS) + +dnl Check for GStreamer plugins-base +PKG_CHECK_MODULES([GST_PLUGINS_BASE], + [gstreamer-plugins-base-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED] +) +AC_SUBST(GST_PLUGINS_BASE_CFLAGS) +AC_SUBST(GST_PLUGINS_BASE_LIBS) + +dnl Check for the GStreamer plugins directory +AC_MSG_CHECKING([for GStreamer plugins directory]) +GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_MAJORMINOR --variable pluginsdir` +if test -z "$GST_PLUGINS_DIR"; then + echo "FAIL FAIL FAIL" + GST_PLUGINS_DIR="\$(libdir)/gstreamer-$GST_MAJORMINOR" +fi +AC_MSG_RESULT([$GST_PLUGINS_DIR]) +plugindir="$GST_PLUGINS_DIR" +AC_SUBST(plugindir) + +dnl Check for VA API +PKG_CHECK_MODULES(LIBVA_DEPS, [libva]) +PKG_CHECK_MODULES(LIBVA_X11_DEPS, [libva-x11]) + +dnl Check for SDS extensions to VA API +AC_CACHE_CHECK([for VA API], + ac_cv_libva_sds_extensions, [ + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $LIBVA_DEPS_CFLAGS" + AC_TRY_COMPILE([ + #include + #if VA_MAJOR_VERSION == 0 && VA_MINOR_VERSION == 29 + # if !defined(VA_SDS_VERSION) || (VA_SDS_VERSION < $LIBVA_SDS_VERSION_0_29) + # error "VA API version >= 0.29.0-sds$LIBVA_SDS_VERSION_0_29 is required" + # endif + #elif VA_MAJOR_VERSION == 0 && VA_MINOR_VERSION == 30 + # if !defined(VA_SDS_VERSION) || (VA_SDS_VERSION < $LIBVA_SDS_VERSION_0_30) + # error "VA API version >= 0.30.0-sds$LIBVA_SDS_VERSION_0_30 is required" + # endif + #elif !VA_CHECK_VERSION(0,31,0) + # error "VA API version >= 0.31 is required" + #endif + ], [], + [ac_cv_libva_sds_extensions="yes"], + [ac_cv_libva_sds_extensions="no"]) + CFLAGS="$saved_CFLAGS" +]) +VA_VERSION=`$PKG_CONFIG --modversion libva` +VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1` +VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2` +VA_DRIVER_INIT_FUNC="__vaDriverInit_${VA_MAJOR_VERSION}_${VA_MINOR_VERSION}_sds" +if test "$ac_cv_libva_sds_extensions" = "yes"; then + AC_DEFINE_UNQUOTED([VA_DRIVER_INIT_FUNC], [$VA_DRIVER_INIT_FUNC], [Define driver entry-point]) +else + AC_MSG_ERROR([Your VA API SDK does not include SDS extensions]) +fi + +AC_OUTPUT([ + Makefile + gst-libs/Makefile + gst-libs/gst/Makefile + gst-libs/gst/vaapi/Makefile + sys/Makefile + sys/vaapi/Makefile +]) diff --git a/gst-libs/Makefile.am b/gst-libs/Makefile.am new file mode 100644 index 0000000000..d5356a6f97 --- /dev/null +++ b/gst-libs/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = gst + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am new file mode 100644 index 0000000000..37d365da29 --- /dev/null +++ b/gst-libs/gst/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = vaapi + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am new file mode 100644 index 0000000000..0984d1c51c --- /dev/null +++ b/gst-libs/gst/vaapi/Makefile.am @@ -0,0 +1,13 @@ +lib_LTLIBRARIES = libgstvaapi-@GST_MAJORMINOR@.la + +libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ + $(NULL) + +libgstvaapi_@GST_MAJORMINOR@includedir = \ + $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi + +libgstvaapi_@GST_MAJORMINOR@include_HEADERS = \ + $(NULL) + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/sys/Makefile.am b/sys/Makefile.am new file mode 100644 index 0000000000..37d365da29 --- /dev/null +++ b/sys/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = vaapi + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/sys/vaapi/Makefile.am b/sys/vaapi/Makefile.am new file mode 100644 index 0000000000..648082cd0b --- /dev/null +++ b/sys/vaapi/Makefile.am @@ -0,0 +1,15 @@ +plugin_LTLIBRARIES = libgstvaapisink.la + +libgstvaapisink_la_SOURCES = \ + $(NULL) + +noinst_HEADERS = \ + $(NULL) + +libgstvaapisink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) +libgstvaapisink_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) +libgstvaapisink_la_LDFLAGS = +libgstvaapisink_la_LIBTOOLFLAGS = --tag=disable-static + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in From 59f5b70f3e6edd4a5545866a3f6b2b6193771bbf Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 25 Jan 2010 13:49:55 +0000 Subject: [PATCH 0002/3781] Check for __attribute__((visibility("hidden"))). --- configure.ac | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/configure.ac b/configure.ac index 08c64a53e0..fb68d16463 100644 --- a/configure.ac +++ b/configure.ac @@ -30,6 +30,32 @@ AC_CANONICAL_TARGET AM_INIT_AUTOMAKE AM_CONFIG_HEADER([config.h]) +dnl Check for __attribute__((visibility())) +AC_CACHE_CHECK([whether __attribute__((visibility())) is supported], + vaapi_cv_visibility_attribute, + [cat > conftest.c </dev/null 2>&1; then + if grep '\.hidden.*foo' conftest.s >/dev/null; then + if grep '\.protected.*bar' conftest.s >/dev/null; then + vaapi_cv_visibility_attribute=yes + fi + fi + fi + rm -f conftest.[cs] +]) +if test $vaapi_cv_visibility_attribute = yes; then + vaapi_cv_visibility_attribute_hidden="__attribute__((visibility(\"hidden\")))" +else + vaapi_cv_visibility_attribute_hidden="" +fi +AC_DEFINE_UNQUOTED([attribute_hidden], + [$vaapi_cv_visibility_attribute_hidden], + [Define the "hidden" visibility attribute]) + dnl Versions for GStreamer and plugins-base GST_MAJORMINOR=gst_major_minor_version GST_VERSION_REQUIRED=gst_version From ec24a29c540193266d69f85ee946ece13ad74f03 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 25 Jan 2010 14:59:37 +0000 Subject: [PATCH 0003/3781] Clean up VA-API checks. --- configure.ac | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index fb68d16463..862618a129 100644 --- a/configure.ac +++ b/configure.ac @@ -91,12 +91,12 @@ AC_MSG_RESULT([$GST_PLUGINS_DIR]) plugindir="$GST_PLUGINS_DIR" AC_SUBST(plugindir) -dnl Check for VA API -PKG_CHECK_MODULES(LIBVA_DEPS, [libva]) -PKG_CHECK_MODULES(LIBVA_X11_DEPS, [libva-x11]) +dnl Check for VA-API +PKG_CHECK_MODULES(LIBVA, [libva]) +PKG_CHECK_MODULES(LIBVA_X11, [libva-x11]) -dnl Check for SDS extensions to VA API -AC_CACHE_CHECK([for VA API], +dnl Check for SDS extensions to VA-API +AC_CACHE_CHECK([for VA-API], ac_cv_libva_sds_extensions, [ saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $LIBVA_DEPS_CFLAGS" @@ -104,14 +104,14 @@ AC_CACHE_CHECK([for VA API], #include #if VA_MAJOR_VERSION == 0 && VA_MINOR_VERSION == 29 # if !defined(VA_SDS_VERSION) || (VA_SDS_VERSION < $LIBVA_SDS_VERSION_0_29) - # error "VA API version >= 0.29.0-sds$LIBVA_SDS_VERSION_0_29 is required" + # error "VA-API version >= 0.29.0-sds$LIBVA_SDS_VERSION_0_29 is required" # endif #elif VA_MAJOR_VERSION == 0 && VA_MINOR_VERSION == 30 # if !defined(VA_SDS_VERSION) || (VA_SDS_VERSION < $LIBVA_SDS_VERSION_0_30) - # error "VA API version >= 0.30.0-sds$LIBVA_SDS_VERSION_0_30 is required" + # error "VA-API version >= 0.30.0-sds$LIBVA_SDS_VERSION_0_30 is required" # endif #elif !VA_CHECK_VERSION(0,31,0) - # error "VA API version >= 0.31 is required" + # error "VA-API version >= 0.31 is required" #endif ], [], [ac_cv_libva_sds_extensions="yes"], @@ -125,7 +125,7 @@ VA_DRIVER_INIT_FUNC="__vaDriverInit_${VA_MAJOR_VERSION}_${VA_MINOR_VERSION}_sds" if test "$ac_cv_libva_sds_extensions" = "yes"; then AC_DEFINE_UNQUOTED([VA_DRIVER_INIT_FUNC], [$VA_DRIVER_INIT_FUNC], [Define driver entry-point]) else - AC_MSG_ERROR([Your VA API SDK does not include SDS extensions]) + AC_MSG_ERROR([Your VA-API SDK does not include SDS extensions]) fi AC_OUTPUT([ From 30a2776442f3ad5cb580e2fdc6c82bd4c9037db7 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 25 Jan 2010 15:04:10 +0000 Subject: [PATCH 0004/3781] Add tests infrastructure. --- Makefile.am | 2 +- configure.ac | 3 +++ tests/Makefile.am | 4 ++++ tests/examples/Makefile.am | 4 ++++ tests/examples/generic/Makefile.am | 5 +++++ 5 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/Makefile.am create mode 100644 tests/examples/Makefile.am create mode 100644 tests/examples/generic/Makefile.am diff --git a/Makefile.am b/Makefile.am index d931a82e68..e457ea3134 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign -SUBDIRS = gst-libs sys +SUBDIRS = gst-libs sys tests # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ diff --git a/configure.ac b/configure.ac index 862618a129..261817c8ca 100644 --- a/configure.ac +++ b/configure.ac @@ -135,4 +135,7 @@ AC_OUTPUT([ gst-libs/gst/vaapi/Makefile sys/Makefile sys/vaapi/Makefile + tests/Makefile + tests/examples/Makefile + tests/examples/generic/Makefile ]) diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000000..cbf577e61b --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = examples + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/examples/Makefile.am b/tests/examples/Makefile.am new file mode 100644 index 0000000000..f09ad5903d --- /dev/null +++ b/tests/examples/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = generic + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/examples/generic/Makefile.am b/tests/examples/generic/Makefile.am new file mode 100644 index 0000000000..12a3966ea0 --- /dev/null +++ b/tests/examples/generic/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS = \ + $(NULL) + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in From 693277e278e06be502371afd1a56eb8a28c13b0d Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 25 Jan 2010 16:15:01 +0000 Subject: [PATCH 0005/3781] Add initial VA display abstraction. --- configure.ac | 1 + gst-libs/gst/vaapi/Makefile.am | 37 +++- gst-libs/gst/vaapi/gstvaapidisplay.c | 263 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 77 +++++++ gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 158 ++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 80 +++++++ gst-libs/gst/vaapi/vaapi_debug.h | 33 +++ gst-libs/gst/vaapi/vaapi_utils.c | 98 +++++++++ gst-libs/gst/vaapi/vaapi_utils.h | 48 +++++ tests/examples/generic/Makefile.am | 14 ++ tests/examples/generic/test-display.c | 42 ++++ 11 files changed, 849 insertions(+), 2 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay.c create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay.h create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_x11.c create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_x11.h create mode 100644 gst-libs/gst/vaapi/vaapi_debug.h create mode 100644 gst-libs/gst/vaapi/vaapi_utils.c create mode 100644 gst-libs/gst/vaapi/vaapi_utils.h create mode 100644 tests/examples/generic/test-display.c diff --git a/configure.ac b/configure.ac index 261817c8ca..fee139e6a1 100644 --- a/configure.ac +++ b/configure.ac @@ -93,6 +93,7 @@ AC_SUBST(plugindir) dnl Check for VA-API PKG_CHECK_MODULES(LIBVA, [libva]) +PKG_CHECK_MODULES(X11, [x11]) PKG_CHECK_MODULES(LIBVA_X11, [libva-x11]) dnl Check for SDS extensions to VA-API diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 0984d1c51c..3bb898150c 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -1,12 +1,45 @@ lib_LTLIBRARIES = libgstvaapi-@GST_MAJORMINOR@.la -libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ +libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ + gstvaapidisplay.c \ + vaapi_utils.c \ + $(NULL) + +libgstvaapi_@GST_MAJORMINOR@include_HEADERS = \ + gstvaapidisplay.h \ + vaapi_debug.h \ + vaapi_utils.h \ $(NULL) libgstvaapi_@GST_MAJORMINOR@includedir = \ $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi -libgstvaapi_@GST_MAJORMINOR@include_HEADERS = \ +libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ + $(GST_BASE_CFLAGS) \ + $(GST_CFLAGS) \ + $(LIBVA_CFLAGS) \ + $(NULL) + +libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ + $(GST_BASE_LIBS) \ + $(GST_LIBS) \ + $(LIBVA_LIBS) \ + $(NULL) + +libgstvaapi_@GST_MAJORMINOR@_la_SOURCES += \ + gstvaapidisplay_x11.c \ + $(NULL) + +libgstvaapi_@GST_MAJORMINOR@include_HEADERS += \ + gstvaapidisplay_x11.h \ + $(NULL) + +libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS += \ + $(LIBVA_X11_CFLAGS) \ + $(NULL) + +libgstvaapi_@GST_MAJORMINOR@_la_LIBADD += \ + $(LIBVA_X11_LIBS) \ $(NULL) # Extra clean files so that maintainer-clean removes *everything* diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c new file mode 100644 index 0000000000..9a24e5d894 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -0,0 +1,263 @@ +/* + * gstvaapidisplay.c - VA display abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "vaapi_utils.h" +#include "gstvaapidisplay.h" +#include + +#define DEBUG 1 +#include "vaapi_debug.h" + +G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT); + +#define GST_VAAPI_DISPLAY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DISPLAY, \ + GstVaapiDisplayPrivate)) + +struct _GstVaapiDisplayPrivate { + VADisplay display; + VAProfile *profiles; + unsigned int num_profiles; + VAImageFormat *image_formats; + unsigned int num_image_formats; + VAImageFormat *subpicture_formats; + unsigned int *subpicture_flags; + unsigned int num_subpicture_formats; +}; + +enum { + PROP_0, + + PROP_DISPLAY +}; + +static void +gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display); + +static void +gst_vaapi_display_finalize(GObject *object) +{ + GstVaapiDisplay *display = GST_VAAPI_DISPLAY(object); + GstVaapiDisplayPrivate *priv = display->priv; + + gst_vaapi_display_set_display(display, NULL); + + G_OBJECT_CLASS(gst_vaapi_display_parent_class)->finalize(object); +} + +static void +gst_vaapi_display_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GstVaapiDisplay *display = GST_VAAPI_DISPLAY(object); + GstVaapiDisplayPrivate *priv = display->priv; + + switch (prop_id) { + case PROP_DISPLAY: + gst_vaapi_display_set_display(display, g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_display_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GstVaapiDisplay *display = GST_VAAPI_DISPLAY(object); + GstVaapiDisplayPrivate *priv = display->priv; + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_pointer(value, gst_vaapi_display_get_display(display)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiDisplayPrivate)); + + object_class->finalize = gst_vaapi_display_finalize; + object_class->set_property = gst_vaapi_display_set_property; + object_class->get_property = gst_vaapi_display_get_property; + + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_pointer("display", + "VA display", + "VA display", + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_display_init(GstVaapiDisplay *display) +{ + GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); + + display->priv = priv; + priv->display = NULL; + priv->profiles = 0; + priv->num_profiles = 0; + priv->image_formats = NULL; + priv->num_image_formats = 0; + priv->subpicture_formats = NULL; + priv->subpicture_flags = NULL; + priv->num_subpicture_formats = 0; +} + +VADisplay +gst_vaapi_display_get_display(GstVaapiDisplay *display) +{ + GstVaapiDisplayPrivate *priv = display->priv; + + return priv->display; +} + +static void +gst_vaapi_display_destroy_resources(GstVaapiDisplay *display) +{ + GstVaapiDisplayPrivate *priv = display->priv; + + if (priv->profiles) { + g_free(priv->profiles); + priv->profiles = NULL; + } + + if (priv->image_formats) { + g_free(priv->image_formats); + priv->image_formats = NULL; + } + + if (priv->subpicture_formats) { + g_free(priv->subpicture_formats); + priv->subpicture_formats = NULL; + } + + if (priv->subpicture_flags) { + g_free(priv->subpicture_flags); + priv->subpicture_flags = NULL; + } +} + +static gboolean +gst_vaapi_display_create_resources(GstVaapiDisplay *display) +{ + GstVaapiDisplayPrivate *priv = display->priv; + VAStatus status; + unsigned int i; + + /* VA profiles */ + priv->num_profiles = vaMaxNumProfiles(priv->display); + priv->profiles = g_new(VAProfile, priv->num_profiles); + if (!priv->profiles) + return FALSE; + status = vaQueryConfigProfiles(priv->display, + priv->profiles, + &priv->num_profiles); + if (!vaapi_check_status(status, "vaQueryConfigProfiles()")) + return FALSE; + + D(bug("%d profiles\n", priv->num_profiles)); + for (i = 0; i < priv->num_profiles; i++) + D(bug(" %s\n", string_of_VAProfile(priv->profiles[i]))); + + /* VA image formats */ + priv->num_image_formats = vaMaxNumImageFormats(priv->display); + priv->image_formats = g_new(VAImageFormat, priv->num_image_formats); + if (!priv->image_formats) + return FALSE; + status = vaQueryImageFormats(priv->display, + priv->image_formats, + &priv->num_image_formats); + if (!vaapi_check_status(status, "vaQueryImageFormats()")) + return FALSE; + + D(bug("%d image formats\n", priv->num_image_formats)); + for (i = 0; i < priv->num_image_formats; i++) + D(bug(" %s\n", string_of_FOURCC(priv->image_formats[i].fourcc))); + + /* VA subpicture formats */ + priv->num_subpicture_formats = vaMaxNumSubpictureFormats(priv->display); + priv->subpicture_formats = g_new(VAImageFormat, priv->num_subpicture_formats); + if (!priv->subpicture_formats) + return FALSE; + priv->subpicture_flags = g_new(unsigned int, priv->num_subpicture_formats); + if (!priv->subpicture_flags) + return FALSE; + status = vaQuerySubpictureFormats(priv->display, + priv->subpicture_formats, + priv->subpicture_flags, + &priv->num_image_formats); + if (!vaapi_check_status(status, "vaQuerySubpictureFormats()")) + return FALSE; + + D(bug("%d subpicture formats\n", priv->num_subpicture_formats)); + for (i = 0; i < priv->num_subpicture_formats; i++) + D(bug(" %s\n", string_of_FOURCC(priv->subpicture_formats[i].fourcc))); + + return TRUE; +} + +void +gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display) +{ + GstVaapiDisplayPrivate *priv = display->priv; + VAStatus status; + int major_version, minor_version; + + if (priv->display) { + gst_vaapi_display_destroy_resources(display); + + /* XXX: make sure this VADisplay is really the last occurrence */ + status = vaTerminate(priv->display); + if (!vaapi_check_status(status, "vaTerminate()")) + return; + priv->display = NULL; + } + + if (va_display) { + status = vaInitialize(va_display, &major_version, &minor_version); + if (!vaapi_check_status(status, "vaInitialize()")) + return; + priv->display = va_display; + D(bug("VA-API version %d.%d\n", major_version, minor_version)); + + if (!gst_vaapi_display_create_resources(display)) { + gst_vaapi_display_destroy_resources(display); + return; + } + } +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h new file mode 100644 index 0000000000..942b6e5e64 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -0,0 +1,77 @@ +/* + * gstvaapidisplay.h - VA display abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_DISPLAY_H +#define GST_VAAPI_DISPLAY_H + +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DISPLAY \ + (gst_vaapi_display_get_type()) + +#define GST_VAAPI_DISPLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DISPLAY, \ + GstVaapiDisplay)) + +#define GST_VAAPI_DISPLAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DISPLAY, \ + GstVaapiDisplayClass)) + +#define GST_VAAPI_IS_DISPLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY)) + +#define GST_VAAPI_IS_DISPLAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY)) + +#define GST_VAAPI_DISPLAY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DISPLAY, \ + GstVaapiDisplay)) + +typedef struct _GstVaapiDisplay GstVaapiDisplay; +typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; +typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; + +struct _GstVaapiDisplay { + /*< private >*/ + GObject parent_instance; + + GstVaapiDisplayPrivate *priv; +}; + +struct _GstVaapiDisplayClass { + /*< private >*/ + GObjectClass parent_class; +}; + +GType +gst_vaapi_display_get_type(void); + +VADisplay +gst_vaapi_display_get_display(GstVaapiDisplay *display); + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c new file mode 100644 index 0000000000..d215230fc6 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -0,0 +1,158 @@ +/* + * gstvaapidisplay_x11.c - VA/X11 display abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "vaapi_utils.h" +#include "gstvaapidisplay_x11.h" + +#define DEBUG 1 +#include "vaapi_debug.h" + +G_DEFINE_TYPE(GstVaapiDisplayX11, + gst_vaapi_display_x11, + GST_VAAPI_TYPE_DISPLAY); + +#define GST_VAAPI_DISPLAY_X11_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DISPLAY_X11, \ + GstVaapiDisplayX11Private)) + +struct _GstVaapiDisplayX11Private { + Display *display; +}; + +enum { + PROP_0, + + PROP_X11_DISPLAY +}; + +static void +gst_vaapi_display_x11_set_display(GstVaapiDisplayX11 *display, + Display *x11_display); + +static void +gst_vaapi_display_x11_finalize(GObject *object) +{ + GstVaapiDisplayX11 *display = GST_VAAPI_DISPLAY_X11(object); + GstVaapiDisplayX11Private *priv = display->priv; + + G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class)->finalize(object); +} + +static void +gst_vaapi_display_x11_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GstVaapiDisplayX11 *display = GST_VAAPI_DISPLAY_X11(object); + GstVaapiDisplayX11Private *priv = display->priv; + + switch (prop_id) { + case PROP_X11_DISPLAY: + gst_vaapi_display_x11_set_display(display, g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_display_x11_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GstVaapiDisplayX11 *display = GST_VAAPI_DISPLAY_X11(object); + GstVaapiDisplayX11Private *priv = display->priv; + + switch (prop_id) { + case PROP_X11_DISPLAY: + g_value_set_pointer(value, gst_vaapi_display_x11_get_display(display)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiDisplayX11Private)); + + object_class->finalize = gst_vaapi_display_x11_finalize; + object_class->set_property = gst_vaapi_display_x11_set_property; + object_class->get_property = gst_vaapi_display_x11_get_property; + + g_object_class_install_property + (object_class, + PROP_X11_DISPLAY, + g_param_spec_pointer("x11-display", + "X11 display", + "X11 display", + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) +{ + GstVaapiDisplayX11Private *priv = GST_VAAPI_DISPLAY_X11_GET_PRIVATE(display); + + display->priv = priv; + priv->display = NULL; +} + +Display * +gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) +{ + GstVaapiDisplayX11Private *priv = display->priv; + + return priv->display; +} + +void +gst_vaapi_display_x11_set_display(GstVaapiDisplayX11 *display, + Display *x11_display) +{ + GstVaapiDisplayX11Private *priv = display->priv; + + if (x11_display) { + VADisplay va_display = vaGetDisplay(x11_display); + if (va_display) + g_object_set(GST_VAAPI_DISPLAY(display), + "display", va_display, + NULL); + } + + priv->display = x11_display; +} + +GstVaapiDisplay * +gst_vaapi_display_x11_new(Display *x11_display) +{ + return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, + "x11-display", x11_display, + NULL); +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h new file mode 100644 index 0000000000..8633a02186 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -0,0 +1,80 @@ +/* + * gstvaapidisplay_x11.h - VA/X11 display abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_DISPLAY_X11_H +#define GST_VAAPI_DISPLAY_X11_H + +#include "gstvaapidisplay.h" +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DISPLAY_X11 \ + (gst_vaapi_display_x11_get_type()) + +#define GST_VAAPI_DISPLAY_X11(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DISPLAY_X11, \ + GstVaapiDisplayX11)) + +#define GST_VAAPI_DISPLAY_X11_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DISPLAY_X11, \ + GstVaapiDisplayX11Class)) + +#define GST_VAAPI_IS_DISPLAY_X11(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_X11)) + +#define GST_VAAPI_IS_DISPLAY_X11_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_X11)) + +#define GST_VAAPI_DISPLAY_X11_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DISPLAY_X11, \ + GstVaapiDisplayX11)) + +typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11; +typedef struct _GstVaapiDisplayX11Private GstVaapiDisplayX11Private; +typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class; + +struct _GstVaapiDisplayX11 { + /*< private >*/ + GstVaapiDisplay parent_instance; + + GstVaapiDisplayX11Private *priv; +}; + +struct _GstVaapiDisplayX11Class { + /*< private >*/ + GstVaapiDisplayClass parent_class; +}; + +GType +gst_vaapi_display_x11_get_type(void); + +GstVaapiDisplay * +gst_vaapi_display_x11_new(Display *x11_display); + +Display * +gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display); + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_X11_H */ diff --git a/gst-libs/gst/vaapi/vaapi_debug.h b/gst-libs/gst/vaapi/vaapi_debug.h new file mode 100644 index 0000000000..edda08fa50 --- /dev/null +++ b/gst-libs/gst/vaapi/vaapi_debug.h @@ -0,0 +1,33 @@ +/* + * vaapi_debug.h - VA-API debugging utilities + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef VAAPI_DEBUG_H +#define VAAPI_DEBUG_H + +#include "vaapi_utils.h" + +#if DEBUG +# define D(x) x +#else +# define D(x) +#endif +#define bug vaapi_dprintf + +#endif /* VAAPI_DEBUG_H */ diff --git a/gst-libs/gst/vaapi/vaapi_utils.c b/gst-libs/gst/vaapi/vaapi_utils.c new file mode 100644 index 0000000000..d271bc3f37 --- /dev/null +++ b/gst-libs/gst/vaapi/vaapi_utils.c @@ -0,0 +1,98 @@ +/* + * vaapi_utils.c - VA-API utilities + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "vaapi_utils.h" +#include +#include + +/* Debug output */ +void vaapi_dprintf(const char *format, ...) +{ + va_list args; + va_start(args, format); + fprintf(stdout, "[GstVaapi] "); + vfprintf(stdout, format, args); + va_end(args); +} + +/* Check VA status for success or print out an error */ +int vaapi_check_status(VAStatus status, const char *msg) +{ + if (status != VA_STATUS_SUCCESS) { + vaapi_dprintf("%s: %s\n", msg, vaErrorStr(status)); + return 0; + } + return 1; +} + +/* Return a string representation of a FOURCC */ +const char *string_of_FOURCC(guint32 fourcc) +{ + static int buf; + static char str[2][5]; // XXX: 2 buffers should be enough for most purposes + + buf ^= 1; + str[buf][0] = fourcc; + str[buf][1] = fourcc >> 8; + str[buf][2] = fourcc >> 16; + str[buf][3] = fourcc >> 24; + str[buf][4] = '\0'; + return str[buf]; +} + +/* Return a string representation of a VAProfile */ +const char *string_of_VAProfile(VAProfile profile) +{ + switch (profile) { +#define PROFILE(profile) \ + case VAProfile##profile: return "VAProfile" #profile + PROFILE(MPEG2Simple); + PROFILE(MPEG2Main); + PROFILE(MPEG4Simple); + PROFILE(MPEG4AdvancedSimple); + PROFILE(MPEG4Main); + PROFILE(H264Baseline); + PROFILE(H264Main); + PROFILE(H264High); + PROFILE(VC1Simple); + PROFILE(VC1Main); + PROFILE(VC1Advanced); +#undef PROFILE + default: break; + } + return ""; +} + +/* Return a string representation of a VAEntrypoint */ +const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) +{ + switch (entrypoint) { +#define ENTRYPOINT(entrypoint) \ + case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint + ENTRYPOINT(VLD); + ENTRYPOINT(IZZ); + ENTRYPOINT(IDCT); + ENTRYPOINT(MoComp); + ENTRYPOINT(Deblocking); +#undef ENTRYPOINT + default: break; + } + return ""; +} diff --git a/gst-libs/gst/vaapi/vaapi_utils.h b/gst-libs/gst/vaapi/vaapi_utils.h new file mode 100644 index 0000000000..f44fe42cf9 --- /dev/null +++ b/gst-libs/gst/vaapi/vaapi_utils.h @@ -0,0 +1,48 @@ +/* + * vaapi_utils.h - VA-API utilities + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef VAAPI_UTILS_H +#define VAAPI_UTILS_H + +#include "config.h" +#include +#include + +/** Debug output */ +void vaapi_dprintf(const char *format, ...) + attribute_hidden; + +/** Check VA status for success or print out an error */ +int vaapi_check_status(VAStatus status, const char *msg) + attribute_hidden; + +/** Return a string representation of a FOURCC */ +const char *string_of_FOURCC(guint32 fourcc) + attribute_hidden; + +/** Return a string representation of a VAProfile */ +const char *string_of_VAProfile(VAProfile profile) + attribute_hidden; + +/** Return a string representation of a VAEntrypoint */ +const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) + attribute_hidden; + +#endif /* VAAPI_UTILS_H */ diff --git a/tests/examples/generic/Makefile.am b/tests/examples/generic/Makefile.am index 12a3966ea0..96bddd9cd0 100644 --- a/tests/examples/generic/Makefile.am +++ b/tests/examples/generic/Makefile.am @@ -1,5 +1,19 @@ noinst_PROGRAMS = \ + test-display \ $(NULL) +TEST_CFLAGS = \ + $(GST_CFLAGS) \ + -I$(top_srcdir)/gst-libs \ + $(X11_CFLAGS) + +TEST_LIBS = \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-@GST_MAJORMINOR@.la \ + $(X11_LIBS) + +test_display_SOURCES = test-display.c +test_display_CFLAGS = $(TEST_CFLAGS) +test_display_LDADD = $(TEST_LIBS) + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/examples/generic/test-display.c b/tests/examples/generic/test-display.c new file mode 100644 index 0000000000..5c05511ab9 --- /dev/null +++ b/tests/examples/generic/test-display.c @@ -0,0 +1,42 @@ +/* + * test-display.c - Test GstVaapiDisplayX11 + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +int +main(int argc, char *argv[]) +{ + Display *x11_display; + GstVaapiDisplay *display; + + gst_init(&argc, &argv); + + x11_display = XOpenDisplay(NULL); + if (!x11_display) + g_error("could not create X11 display"); + + display = gst_vaapi_display_x11_new(x11_display); + if (!display) + g_error("could not create VA-API display"); + + g_object_unref(G_OBJECT(display)); + return 0; +} From 6f20d84fa3e971acb335b0018de248e28495218f Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 4 Mar 2010 17:39:01 +0000 Subject: [PATCH 0006/3781] Add VA surface, image, subpicture abstractions. Ported over from Gnash. --- gst-libs/gst/vaapi/Makefile.am | 23 +- gst-libs/gst/vaapi/gstvaapiimage.c | 423 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiimage.h | 115 ++++++ gst-libs/gst/vaapi/gstvaapiimageformat.c | 153 ++++++++ gst-libs/gst/vaapi/gstvaapiimageformat.h | 65 ++++ gst-libs/gst/vaapi/gstvaapisurface.c | 314 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 91 +++++ 7 files changed, 1181 insertions(+), 3 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiimage.c create mode 100644 gst-libs/gst/vaapi/gstvaapiimage.h create mode 100644 gst-libs/gst/vaapi/gstvaapiimageformat.c create mode 100644 gst-libs/gst/vaapi/gstvaapiimageformat.h create mode 100644 gst-libs/gst/vaapi/gstvaapisurface.c create mode 100644 gst-libs/gst/vaapi/gstvaapisurface.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 3bb898150c..edef4fa9f9 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -1,20 +1,37 @@ lib_LTLIBRARIES = libgstvaapi-@GST_MAJORMINOR@.la -libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ +libgstvaapi_source_c = \ gstvaapidisplay.c \ + gstvaapiimage.c \ + gstvaapiimageformat.c \ + gstvaapisubpicture.c \ + gstvaapisurface.c \ vaapi_utils.c \ $(NULL) -libgstvaapi_@GST_MAJORMINOR@include_HEADERS = \ +libgstvaapi_source_h = \ gstvaapidisplay.h \ + gstvaapiimage.h \ + gstvaapiimageformat.h \ + gstvaapisubpicture.h \ + gstvaapisurface.h \ vaapi_debug.h \ vaapi_utils.h \ $(NULL) -libgstvaapi_@GST_MAJORMINOR@includedir = \ +libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ + $(libgstvaapi_source_c) \ + $(NULL) + +libgstvaapi_@GST_MAJORMINOR@include_HEADERS = \ + $(libgstvaapi_source_h) \ + $(NULL) + +libgstvaapi_@GST_MAJORMINOR@includedir = \ $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ + -I$(top_srcdir)/gst-libs \ $(GST_BASE_CFLAGS) \ $(GST_CFLAGS) \ $(LIBVA_CFLAGS) \ diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c new file mode 100644 index 0000000000..2c6c8d88ff --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -0,0 +1,423 @@ +/* + * gstvaapiimage.c - VA image abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include +#include "vaapi_utils.h" +#include "gstvaapiimage.h" +#include + +#define DEBUG 1 +#include "vaapi_debug.h" + +G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, G_TYPE_OBJECT); + +#define GST_VAAPI_IMAGE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_IMAGE, \ + GstVaapiImagePrivate)) + +struct _GstVaapiImagePrivate { + GstVaapiDisplay *display; + VAImage image; + guchar *image_data; + guint width; + guint height; + GstVaapiImageFormat format; +}; + +enum { + PROP_0, + + PROP_DISPLAY, + PROP_IMAGE_ID, + PROP_WIDTH, + PROP_HEIGHT, + PROP_FORMAT +}; + +static void +gst_vaapi_image_destroy(GstVaapiImage *image) +{ + GstVaapiImagePrivate * const priv = image->priv; + VADisplay dpy = gst_vaapi_display_get_display(priv->display); + VAStatus status; + + gst_vaapi_image_unmap(image); + + if (priv->image.image_id != VA_INVALID_ID) { + status = vaDestroyImage(dpy, priv->image.image_id); + if (!vaapi_check_status(status, "vaDestroyImage()")) + g_warning("failed to destroy image 0x%08x\n", priv->image.image_id); + priv->image.image_id = VA_INVALID_ID; + } + + if (priv->display) { + g_object_unref(priv->display); + priv->display = NULL; + } +} + +static gboolean +gst_vaapi_image_create(GstVaapiImage *image) +{ + GstVaapiImagePrivate * const priv = image->priv; + const VAImageFormat *format; + VAStatus status; + + if (!gst_vaapi_display_has_image_format(priv->display, priv->format)) + return FALSE; + + format = gst_vaapi_image_format_get_va_format(priv->format); + + g_return_val_if_fail(format, FALSE); + + status = vaCreateImage( + gst_vaapi_display_get_display(priv->display), + (VAImageFormat *)format, + priv->width, + priv->height, + &priv->image + ); + if (!vaapi_check_status(status, "vaCreateImage()")) + return FALSE; + + return TRUE; +} + +static void +gst_vaapi_image_finalize(GObject *object) +{ + gst_vaapi_image_destroy(GST_VAAPI_IMAGE(object)); + + G_OBJECT_CLASS(gst_vaapi_image_parent_class)->finalize(object); +} + +static void +gst_vaapi_image_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiImage * const image = GST_VAAPI_IMAGE(object); + GstVaapiImagePrivate * const priv = image->priv; + + switch (prop_id) { + case PROP_DISPLAY: + priv->display = g_object_ref(g_value_get_pointer(value)); + break; + case PROP_WIDTH: + priv->width = g_value_get_uint(value); + break; + case PROP_HEIGHT: + priv->height = g_value_get_uint(value); + break; + case PROP_FORMAT: + priv->format = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_image_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiImage * const image = GST_VAAPI_IMAGE(object); + GstVaapiImagePrivate * const priv = image->priv; + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_pointer(value, g_object_ref(priv->display)); + break; + case PROP_IMAGE_ID: + g_value_set_uint(value, gst_vaapi_image_get_id(image)); + break; + case PROP_WIDTH: + g_value_set_uint(value, gst_vaapi_image_get_width(image)); + break; + case PROP_HEIGHT: + g_value_set_uint(value, gst_vaapi_image_get_height(image)); + break; + case PROP_FORMAT: + g_value_set_uint(value, gst_vaapi_image_get_format(image)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static GObject * +gst_vaapi_image_constructor( + GType type, + guint n_params, + GObjectConstructParam *params +) +{ + GstVaapiImage *image; + GObjectClass *parent_class; + GObject *object; + + D(bug("gst_vaapi_image_constructor()\n")); + + parent_class = G_OBJECT_CLASS(gst_vaapi_image_parent_class); + object = parent_class->constructor (type, n_params, params); + + if (object) { + image = GST_VAAPI_IMAGE(object); + if (!gst_vaapi_image_create(image)) { + gst_vaapi_image_destroy(image); + object = NULL; + } + } + return object; +} + +static void +gst_vaapi_image_class_init(GstVaapiImageClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiImagePrivate)); + + object_class->finalize = gst_vaapi_image_finalize; + object_class->set_property = gst_vaapi_image_set_property; + object_class->get_property = gst_vaapi_image_get_property; + object_class->constructor = gst_vaapi_image_constructor; + + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_object("display", + "display", + "GStreamer Va display", + GST_VAAPI_TYPE_DISPLAY, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_IMAGE_ID, + g_param_spec_uint("id", + "VA image id", + "VA image id", + 0, G_MAXUINT32, VA_INVALID_ID, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_uint("width", + "width", + "Image width", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_uint("height", + "height", + "Image height", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_FORMAT, + g_param_spec_uint("format", + "format", + "Image format", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_image_init(GstVaapiImage *image) +{ + GstVaapiImagePrivate *priv = GST_VAAPI_IMAGE_GET_PRIVATE(image); + + D(bug("gst_vaapi_image_init()\n")); + + image->priv = priv; + priv->display = NULL; + priv->image_data = NULL; + priv->width = 0; + priv->height = 0; + priv->format = 0; + + memset(&priv->image, 0, sizeof(priv->image)); + priv->image.image_id = VA_INVALID_ID; + priv->image.buf = VA_INVALID_ID; +} + +GstVaapiImage * +gst_vaapi_image_new( + GstVaapiDisplay *display, + guint width, + guint height, + GstVaapiImageFormat format +) +{ + D(bug("gst_vaapi_image_new(): size %ux%u, format 0x%x\n", + width, height, format)); + + return g_object_new(GST_VAAPI_TYPE_IMAGE, + "display", display, + "width", width, + "height", height, + "format", format, + NULL); +} + +VAImageID +gst_vaapi_image_get_id(GstVaapiImage *image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID); + + return image->priv->image.image_id; +} + +GstVaapiDisplay * +gst_vaapi_image_get_display(GstVaapiImage *image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); + + return g_object_ref(image->priv->display); +} + +guint +gst_vaapi_image_get_width(GstVaapiImage *image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + + return image->priv->width; +} + +guint +gst_vaapi_image_get_height(GstVaapiImage *image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + + return image->priv->height; +} + +guint +gst_vaapi_image_get_format(GstVaapiImage *image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + + return image->priv->format; +} + +static inline gboolean +_gst_vaapi_image_is_mapped(GstVaapiImage *image) +{ + return image->priv->image_data != NULL; +} + +gboolean +gst_vaapi_image_is_mapped(GstVaapiImage *image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + + return _gst_vaapi_image_is_mapped(image); +} + +gboolean +gst_vaapi_image_map(GstVaapiImage *image) +{ + void *image_data; + VAStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + + if (_gst_vaapi_image_is_mapped(image)) + return TRUE; + + status = vaMapBuffer( + gst_vaapi_display_get_display(image->priv->display), + image->priv->image.buf, + &image_data + ); + if (!vaapi_check_status(status, "vaMapBuffer()")) + return FALSE; + + image->priv->image_data = image_data; + return TRUE; +} + +gboolean +gst_vaapi_image_unmap(GstVaapiImage *image) +{ + VAStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + + if (!_gst_vaapi_image_is_mapped(image)) + return FALSE; + + status = vaUnmapBuffer( + gst_vaapi_display_get_display(image->priv->display), + image->priv->image.buf + ); + if (!vaapi_check_status(status, "vaUnmapBuffer()")) + return FALSE; + + image->priv->image_data = NULL; + return TRUE; +} + +guint +gst_vaapi_image_get_plane_count(GstVaapiImage *image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0); + + return image->priv->image.num_planes; +} + +guchar * +gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); + g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL); + g_return_val_if_fail(plane < image->priv->image.num_planes, NULL); + + return image->priv->image_data + image->priv->image.offsets[plane]; +} + +guint +gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0); + g_return_val_if_fail(plane < image->priv->image.num_planes, 0); + + return image->priv->image.pitches[plane]; +} diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h new file mode 100644 index 0000000000..aa92314115 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -0,0 +1,115 @@ +/* + * gstvaapiimage.h - VA image abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_IMAGE_H +#define GST_VAAPI_IMAGE_H + +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_IMAGE \ + (gst_vaapi_image_get_type()) + +#define GST_VAAPI_IMAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_IMAGE, \ + GstVaapiImage)) + +#define GST_VAAPI_IMAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_IMAGE, \ + GstVaapiImageClass)) + +#define GST_VAAPI_IS_IMAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_IMAGE)) + +#define GST_VAAPI_IS_IMAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_IMAGE)) + +#define GST_VAAPI_IMAGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_IMAGE, \ + GstVaapiImage)) + +typedef struct _GstVaapiImage GstVaapiImage; +typedef struct _GstVaapiImagePrivate GstVaapiImagePrivate; +typedef struct _GstVaapiImageClass GstVaapiImageClass; + +struct _GstVaapiImage { + /*< private >*/ + GObject parent_instance; + + GstVaapiImagePrivate *priv; +}; + +struct _GstVaapiImageClass { + /*< private >*/ + GObjectClass parent_class; +}; + +GType +gst_vaapi_image_get_type(void); + +GstVaapiImage * +gst_vaapi_image_new( + GstVaapiDisplay *display, + guint width, + guint height, + GstVaapiImageFormat format +); + +VAImageID +gst_vaapi_image_get_id(GstVaapiImage *image); + +GstVaapiDisplay * +gst_vaapi_image_get_display(GstVaapiImage *image); + +guint +gst_vaapi_image_get_width(GstVaapiImage *image); + +guint +gst_vaapi_image_get_height(GstVaapiImage *image); + +guint +gst_vaapi_image_get_format(GstVaapiImage *image); + +gboolean +gst_vaapi_image_is_mapped(GstVaapiImage *image); + +gboolean +gst_vaapi_image_map(GstVaapiImage *image); + +gboolean +gst_vaapi_image_unmap(GstVaapiImage *image); + +guint +gst_vaapi_image_get_plane_count(GstVaapiImage *image); + +guchar * +gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane); + +guint +gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane); + +G_END_DECLS + +#endif /* GST_VAAPI_IMAGE_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c new file mode 100644 index 0000000000..3303063a60 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -0,0 +1,153 @@ +/* + * gstvaapiimageformat.c - VA image format abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include +#include "gstvaapiimageformat.h" + +typedef enum _GstVaapiImageFormatType GstVaapiImageFormatType; +typedef struct _GstVaapiImageFormatMap GstVaapiImageFormatMap; + +enum _GstVaapiImageFormatType { + GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR = 1, + GST_VAAPI_IMAGE_FORMAT_TYPE_RGB, + GST_VAAPI_IMAGE_FORMAT_TYPE_INDEXED +}; + +struct _GstVaapiImageFormatMap { + GstVaapiImageFormatType type; + GstVaapiImageFormat format; + VAImageFormat va_format; +}; + +#define DEF(TYPE, FORMAT) \ + GST_VAAPI_IMAGE_FORMAT_TYPE_##TYPE, GST_VAAPI_IMAGE_##FORMAT +#define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP) \ + { DEF(YCBCR, FORMAT), \ + { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } +#define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \ + { DEF(RGB, FORMAT), \ + { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } +#define DEF_IDX(FORMAT, FOURCC, ENDIAN, BPP, NPE, EB, C0,C1,C2,C3) \ + { DEF(TYPE, FORMAT), \ + { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, } + +static const GstVaapiImageFormatMap gst_vaapi_image_formats[] = { + DEF_YUV(NV12, ('N','V','1','2'), LSB, 12), + DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12), + DEF_YUV(I420, ('I','4','2','0'), LSB, 12), +#if G_BYTE_ORDER == G_BIG_ENDIAN + DEF_RGB(ARGB, ('A','R','G','B'), MSB, 32, + 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), + DEF_RGB(ABGR, ('A','B','G','R'), MSB, 32, + 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), +#elif G_BYTE_ORDER == G_LITTLE_ENDIAN + DEF_RGB(BGRA, ('B','G','R','A'), LSB, 32, + 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), + DEF_RGB(RGBA, ('R','G','B','A'), LSB, 32, + 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), +#endif + { 0, } +}; + +#undef DEF_IDX +#undef DEF_RGB +#undef DEF_YUV +#undef DEF + +static const GstVaapiImageFormatMap *get_map(const VAImageFormat *va_format) +{ + const GstVaapiImageFormatMap *m; + + for (m = gst_vaapi_image_formats; m->format; m++) + if (m->va_format.fourcc == va_format->fourcc && + (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB ? + (m->va_format.byte_order == va_format->byte_order && + m->va_format.red_mask == va_format->red_mask && + m->va_format.green_mask == va_format->green_mask && + m->va_format.blue_mask == va_format->blue_mask && + m->va_format.alpha_mask == va_format->alpha_mask) : + TRUE)) + return m; + return NULL; +} + +static const GstVaapiImageFormatMap * +get_map_from_gst_vaapi_image_format(GstVaapiImageFormat format) +{ + const GstVaapiImageFormatMap *m; + + for (m = gst_vaapi_image_formats; m->format; m++) + if (m->format == format) + return m; + return NULL; +} + +gboolean +gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format) +{ + const GstVaapiImageFormatMap *m; + + m = get_map_from_gst_vaapi_image_format(format); + + g_return_val_if_fail(m, FALSE); + + return m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB; +} + +gboolean +gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format) +{ + const GstVaapiImageFormatMap *m; + + m = get_map_from_gst_vaapi_image_format(format); + + g_return_val_if_fail(m, FALSE); + + return m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR; +} + +GstVaapiImageFormat +gst_vaapi_image_format(const VAImageFormat *va_format) +{ + const GstVaapiImageFormatMap * const m = get_map(va_format); + + g_return_val_if_fail(m, 0); + + return m->format; +} + +GstVaapiImageFormat +gst_vaapi_image_format_from_fourcc(guint32 fourcc) +{ + return (GstVaapiImageFormat)fourcc; +} + +const VAImageFormat * +gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format) +{ + const GstVaapiImageFormatMap *m; + + m = get_map_from_gst_vaapi_image_format(format); + + g_return_val_if_fail(m, NULL); + + return &m->va_format; +} diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h new file mode 100644 index 0000000000..89987332b7 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -0,0 +1,65 @@ +/* + * gstvaapiimageformat.h - VA image format abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_IMAGE_FORMAT_H +#define GST_VAAPI_IMAGE_FORMAT_H + +#include +#include + +G_BEGIN_DECLS + +typedef enum _GstVaapiImageFormat GstVaapiImageFormat; + +enum _GstVaapiImageFormat { + /** Planar YUV 4:2:0, 12-bit, 1 plane for Y and 1 plane for UV */ + GST_VAAPI_IMAGE_NV12 = VA_FOURCC('N','V','1','2'), + /** Planar YUV 4:2:0, 12-bit, 3 planes for Y V U */ + GST_VAAPI_IMAGE_YV12 = VA_FOURCC('Y','V','1','2'), + /** Planar YUV 4:2:0, 12-bit, 3 planes for Y U V */ + GST_VAAPI_IMAGE_I420 = VA_FOURCC('I','4','2','0'), + /** Packed RGB 8:8:8, 32-bit, A R G B */ + GST_VAAPI_IMAGE_ARGB = VA_FOURCC('A','R','G','B'), + /** Packed RGB 8:8:8, 32-bit, R G B A */ + GST_VAAPI_IMAGE_RGBA = VA_FOURCC('R','G','B','A'), + /** Packed RGB 8:8:8, 32-bit, A R G B */ + GST_VAAPI_IMAGE_ABGR = VA_FOURCC('A','B','G','R'), + /** Packed RGB 8:8:8, 32-bit, R G B A */ + GST_VAAPI_IMAGE_BGRA = VA_FOURCC('B','G','R','A'), +}; + +gboolean +gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format); + +gboolean +gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format); + +GstVaapiImageFormat +gst_vaapi_image_format(const VAImageFormat *va_format); + +GstVaapiImageFormat +gst_vaapi_image_format_from_fourcc(guint32 fourcc); + +const VAImageFormat * +gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format); + +G_END_DECLS + +#endif /* GST_GST_VAAPI_IMAGE_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c new file mode 100644 index 0000000000..2f52850f71 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -0,0 +1,314 @@ +/* + * gstvaapisurface.c - VA surface abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "vaapi_utils.h" +#include "gstvaapisurface.h" +#include + +#define DEBUG 1 +#include "vaapi_debug.h" + +G_DEFINE_TYPE(GstVaapiSurface, gst_vaapi_surface, G_TYPE_OBJECT); + +#define GST_VAAPI_SURFACE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_SURFACE, \ + GstVaapiSurfacePrivate)) + +struct _GstVaapiSurfacePrivate { + GstVaapiDisplay *display; + VASurfaceID surface_id; + guint width; + guint height; + guint format; +}; + +enum { + PROP_0, + + PROP_DISPLAY, + PROP_SURFACE_ID, + PROP_WIDTH, + PROP_HEIGHT, + PROP_FORMAT +}; + +static void +gst_vaapi_surface_destroy(GstVaapiSurface *surface) +{ + GstVaapiSurfacePrivate * const priv = surface->priv; + VADisplay dpy = gst_vaapi_display_get_display(priv->display); + VAStatus status; + + if (priv->surface_id != VA_INVALID_SURFACE) { + status = vaDestroySurfaces(dpy, &priv->surface_id, 1); + if (!vaapi_check_status(status, "vaDestroySurfaces()")) + g_warning("failed to destroy surface 0x%08x\n", priv->surface_id); + priv->surface_id = VA_INVALID_SURFACE; + } + + if (priv->display) { + g_object_unref(priv->display); + priv->display = NULL; + } +} + +static gboolean +gst_vaapi_surface_create(GstVaapiSurface *surface) +{ + GstVaapiSurfacePrivate * const priv = surface->priv; + VASurfaceID surface_id; + VAStatus status; + + status = vaCreateSurfaces( + gst_vaapi_display_get_display(priv->display), + priv->width, + priv->height, + priv->format, + 1, &surface_id + ); + if (!vaapi_check_status(status, "vaCreateSurfaces()")) + return FALSE; + + priv->surface_id = surface_id; + return TRUE; +} + +static void +gst_vaapi_surface_finalize(GObject *object) +{ + gst_vaapi_surface_destroy(GST_VAAPI_SURFACE(object)); + + G_OBJECT_CLASS(gst_vaapi_surface_parent_class)->finalize(object); +} + +static void +gst_vaapi_surface_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); + GstVaapiSurfacePrivate * const priv = surface->priv; + + switch (prop_id) { + case PROP_DISPLAY: + priv->display = g_object_ref(g_value_get_pointer(value)); + break; + case PROP_WIDTH: + priv->width = g_value_get_uint(value); + break; + case PROP_HEIGHT: + priv->height = g_value_get_uint(value); + break; + case PROP_FORMAT: + priv->format = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_surface_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); + GstVaapiSurfacePrivate * const priv = surface->priv; + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_pointer(value, g_object_ref(priv->display)); + break; + case PROP_SURFACE_ID: + g_value_set_uint(value, gst_vaapi_surface_get_id(surface)); + break; + case PROP_WIDTH: + g_value_set_uint(value, gst_vaapi_surface_get_width(surface)); + break; + case PROP_HEIGHT: + g_value_set_uint(value, gst_vaapi_surface_get_height(surface)); + break; + case PROP_FORMAT: + g_value_set_uint(value, gst_vaapi_surface_get_format(surface)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static GObject * +gst_vaapi_surface_constructor(GType type, + guint n_params, + GObjectConstructParam *params) +{ + GstVaapiSurface *surface; + GObjectClass *parent_class; + GObject *object; + + D(bug("gst_vaapi_surface_constructor()\n")); + + parent_class = G_OBJECT_CLASS(gst_vaapi_surface_parent_class); + object = parent_class->constructor (type, n_params, params); + + if (object) { + surface = GST_VAAPI_SURFACE(object); + if (!gst_vaapi_surface_create(surface)) { + gst_vaapi_surface_destroy(surface); + object = NULL; + } + } + return object; +} + +static void +gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiSurfacePrivate)); + + object_class->finalize = gst_vaapi_surface_finalize; + object_class->set_property = gst_vaapi_surface_set_property; + object_class->get_property = gst_vaapi_surface_get_property; + object_class->constructor = gst_vaapi_surface_constructor; + + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_object("display", + "display", + "GStreamer Va display", + GST_VAAPI_TYPE_DISPLAY, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_SURFACE_ID, + g_param_spec_uint("id", + "VA surface id", + "VA surface id", + 0, G_MAXUINT32, VA_INVALID_SURFACE, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_uint("width", + "width", + "VA surface width", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_uint("height", + "height", + "VA surface height", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_FORMAT, + g_param_spec_uint("format", + "format", + "VA surface format", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_surface_init(GstVaapiSurface *surface) +{ + GstVaapiSurfacePrivate *priv = GST_VAAPI_SURFACE_GET_PRIVATE(surface); + + D(bug("gst_vaapi_surface_init()\n")); + + surface->priv = priv; + priv->display = NULL; + priv->surface_id = VA_INVALID_SURFACE; + priv->width = 0; + priv->height = 0; + priv->format = 0; +} + +GstVaapiSurface * +gst_vaapi_surface_new(GstVaapiDisplay *display, + guint width, + guint height, + guint format) +{ + D(bug("gst_vaapi_surface_new(): size %ux%u, format 0x%x\n", + width, height, format)); + + return g_object_new(GST_VAAPI_TYPE_SURFACE, + "display", display, + "width", width, + "height", height, + "format", format, + NULL); +} + +VASurfaceID +gst_vaapi_surface_get_id(GstVaapiSurface *surface) +{ + GstVaapiSurfacePrivate * const priv = surface->priv; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), VA_INVALID_SURFACE); + + return priv->surface_id; +} + +guint +gst_vaapi_surface_get_width(GstVaapiSurface *surface) +{ + GstVaapiSurfacePrivate * const priv = surface->priv; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); + + return priv->width; +} + +guint +gst_vaapi_surface_get_height(GstVaapiSurface *surface) +{ + GstVaapiSurfacePrivate * const priv = surface->priv; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); + + return priv->height; +} + +guint +gst_vaapi_surface_get_format(GstVaapiSurface *surface) +{ + GstVaapiSurfacePrivate *priv = surface->priv; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); + + return priv->format; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h new file mode 100644 index 0000000000..cbbd1baf8d --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -0,0 +1,91 @@ +/* + * gstvaapisurface.h - VA surface abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_SURFACE_H +#define GST_VAAPI_SURFACE_H + +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_SURFACE \ + (gst_vaapi_surface_get_type()) + +#define GST_VAAPI_SURFACE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_SURFACE, \ + GstVaapiSurface)) + +#define GST_VAAPI_SURFACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_SURFACE, \ + GstVaapiSurfaceClass)) + +#define GST_VAAPI_IS_SURFACE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SURFACE)) + +#define GST_VAAPI_IS_SURFACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SURFACE)) + +#define GST_VAAPI_SURFACE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_SURFACE, \ + GstVaapiSurface)) + +typedef struct _GstVaapiSurface GstVaapiSurface; +typedef struct _GstVaapiSurfacePrivate GstVaapiSurfacePrivate; +typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; + +struct _GstVaapiSurface { + /*< private >*/ + GObject parent_instance; + + GstVaapiSurfacePrivate *priv; +}; + +struct _GstVaapiSurfaceClass { + /*< private >*/ + GObjectClass parent_class; +}; + +GType +gst_vaapi_surface_get_type(void); + +GstVaapiSurface * +gst_vaapi_surface_new(GstVaapiDisplay *display, + guint width, + guint height, + guint format); + +VASurfaceID +gst_vaapi_surface_get_id(GstVaapiSurface *surface); + +guint +gst_vaapi_surface_get_width(GstVaapiSurface *surface); + +guint +gst_vaapi_surface_get_height(GstVaapiSurface *surface); + +guint +gst_vaapi_surface_get_format(GstVaapiSurface *surface); + +G_END_DECLS + +#endif /* GST_VAAPI_SURFACE_H */ From ee753479732c65942116ba760984b5b7131cee03 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 4 Mar 2010 17:39:58 +0000 Subject: [PATCH 0007/3781] Really add VA subpicture abstraction. --- gst-libs/gst/vaapi/gstvaapisubpicture.c | 265 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisubpicture.h | 89 ++++++++ 2 files changed, 354 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapisubpicture.c create mode 100644 gst-libs/gst/vaapi/gstvaapisubpicture.h diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c new file mode 100644 index 0000000000..e8efeddc76 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -0,0 +1,265 @@ +/* + * gstvaapisubpicture.c - VA subpicture abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include +#include "vaapi_utils.h" +#include "gstvaapisubpicture.h" +#include + +#define DEBUG 1 +#include "vaapi_debug.h" + +G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, G_TYPE_OBJECT); + +#define GST_VAAPI_SUBPICTURE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_SUBPICTURE, \ + GstVaapiSubpicturePrivate)) + +struct _GstVaapiSubpicturePrivate { + VASubpictureID subpicture_id; + GstVaapiImage *image; +}; + +enum { + PROP_0, + + PROP_SUBPICTURE_ID, + PROP_IMAGE +}; + +static void +gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) +{ + GstVaapiSubpicturePrivate * const priv = subpicture->priv; + GstVaapiDisplay *display; + VAStatus status; + + if (priv->subpicture_id != VA_INVALID_ID) { + display = gst_vaapi_image_get_display(priv->image); + if (display) { + status = vaDestroySubpicture( + gst_vaapi_display_get_display(display), + priv->subpicture_id + ); + g_object_unref(display); + if (!vaapi_check_status(status, "vaDestroySubpicture()")) + g_warning("failed to destroy subpicture 0x%08x\n", + priv->subpicture_id); + } + priv->subpicture_id = VA_INVALID_ID; + } + + if (priv->image) { + g_object_unref(priv->image); + priv->image = NULL; + } +} + +static gboolean +gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture) +{ + GstVaapiSubpicturePrivate * const priv = subpicture->priv; + GstVaapiDisplay *display; + VASubpictureID subpicture_id; + VAStatus status; + + if (!priv->image) + return FALSE; + + display = gst_vaapi_image_get_display(priv->image); + if (!display) + return FALSE; + + status = vaCreateSubpicture( + gst_vaapi_display_get_display(display), + gst_vaapi_image_get_id(priv->image), + &subpicture_id + ); + g_object_unref(display); + if (!vaapi_check_status(status, "vaCreateSubpicture()")) + return FALSE; + + priv->subpicture_id = subpicture_id; + return TRUE; +} + +static void +gst_vaapi_subpicture_finalize(GObject *object) +{ + gst_vaapi_subpicture_destroy(GST_VAAPI_SUBPICTURE(object)); + + G_OBJECT_CLASS(gst_vaapi_subpicture_parent_class)->finalize(object); +} + +static void +gst_vaapi_subpicture_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object); + + switch (prop_id) { + case PROP_IMAGE: + subpicture->priv->image = g_object_ref(g_value_get_object(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_subpicture_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object); + + switch (prop_id) { + case PROP_SUBPICTURE_ID: + g_value_set_uint(value, gst_vaapi_subpicture_get_id(subpicture)); + break; + case PROP_IMAGE: + g_value_set_object(value, gst_vaapi_subpicture_get_image(subpicture)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static GObject * +gst_vaapi_subpicture_constructor( + GType type, + guint n_params, + GObjectConstructParam *params +) +{ + GstVaapiSubpicture *subpicture; + GObjectClass *parent_class; + GObject *object; + + D(bug("gst_vaapi_subpicture_constructor()\n")); + + parent_class = G_OBJECT_CLASS(gst_vaapi_subpicture_parent_class); + object = parent_class->constructor (type, n_params, params); + + if (object) { + subpicture = GST_VAAPI_SUBPICTURE(object); + if (!gst_vaapi_subpicture_create(subpicture)) { + gst_vaapi_subpicture_destroy(subpicture); + object = NULL; + } + } + return object; +} + +static void +gst_vaapi_subpicture_class_init(GstVaapiSubpictureClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiSubpicturePrivate)); + + object_class->finalize = gst_vaapi_subpicture_finalize; + object_class->set_property = gst_vaapi_subpicture_set_property; + object_class->get_property = gst_vaapi_subpicture_get_property; + object_class->constructor = gst_vaapi_subpicture_constructor; + + g_object_class_install_property + (object_class, + PROP_SUBPICTURE_ID, + g_param_spec_uint("id", + "VA subpicture id", + "VA subpicture id", + 0, G_MAXUINT32, VA_INVALID_ID, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, + PROP_IMAGE, + g_param_spec_object("image", + "image", + "GStreamer VA image", + GST_VAAPI_TYPE_IMAGE, + G_PARAM_READWRITE)); +} + +static void +gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture) +{ + GstVaapiSubpicturePrivate *priv = GST_VAAPI_SUBPICTURE_GET_PRIVATE(subpicture); + + D(bug("gst_vaapi_subpicture_init()\n")); + + subpicture->priv = priv; + priv->subpicture_id = VA_INVALID_ID; + priv->image = NULL; +} + +GstVaapiSubpicture * +gst_vaapi_subpicture_new(GstVaapiImage *image) +{ + D(bug("gst_vaapi_subpicture_new(): image 0x%08x\n", + gst_vaapi_image_get_id(image))); + + return g_object_new(GST_VAAPI_TYPE_SUBPICTURE, + "image", image, + NULL); +} + +VASubpictureID +gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture) +{ + g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), VA_INVALID_ID); + + return subpicture->priv->subpicture_id; +} + +GstVaapiImage * +gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture) +{ + g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), NULL); + + return g_object_ref(subpicture->priv->image); +} + +void +gst_vaapi_subpicture_set_image( + GstVaapiSubpicture *subpicture, + GstVaapiImage *image +) +{ + g_return_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture)); + g_return_if_fail(GST_VAAPI_IS_IMAGE(image)); + + gst_vaapi_subpicture_destroy(subpicture); + + subpicture->priv->image = g_object_ref(image); + gst_vaapi_subpicture_create(subpicture); +} diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h new file mode 100644 index 0000000000..763af4e54f --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -0,0 +1,89 @@ +/* + * gstvaapisubpicture.h - VA subpicture abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_SUBPICTURE_H +#define GST_VAAPI_SUBPICTURE_H + +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_SUBPICTURE \ + (gst_vaapi_subpicture_get_type()) + +#define GST_VAAPI_SUBPICTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_SUBPICTURE, \ + GstVaapiSubpicture)) + +#define GST_VAAPI_SUBPICTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_SUBPICTURE, \ + GstVaapiSubpictureClass)) + +#define GST_VAAPI_IS_SUBPICTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SUBPICTURE)) + +#define GST_VAAPI_IS_SUBPICTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SUBPICTURE)) + +#define GST_VAAPI_SUBPICTURE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_SUBPICTURE, \ + GstVaapiSubpicture)) + +typedef struct _GstVaapiSubpicture GstVaapiSubpicture; +typedef struct _GstVaapiSubpicturePrivate GstVaapiSubpicturePrivate; +typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass; + +struct _GstVaapiSubpicture { + /*< private >*/ + GObject parent_instance; + + GstVaapiSubpicturePrivate *priv; +}; + +struct _GstVaapiSubpictureClass { + /*< private >*/ + GObjectClass parent_class; +}; + +GType +gst_vaapi_subpicture_get_type(void); + +GstVaapiSubpicture * +gst_vaapi_subpicture_new(GstVaapiImage *image); + +VASubpictureID +gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture); + +GstVaapiImage * +gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture); + +void +gst_vaapi_subpicture_set_image( + GstVaapiSubpicture *subpicture, + GstVaapiImage *image +); + +G_END_DECLS + +#endif /* GST_VAAPI_SUBPICTURE_H */ From 5809b63aafbaf71e6534ea59e9e83281132e9d44 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 4 Mar 2010 17:40:47 +0000 Subject: [PATCH 0008/3781] Cosmetics (more checks, includes). --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 4 ++++ gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index d215230fc6..3a2db88b8d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -129,6 +129,8 @@ gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) { GstVaapiDisplayX11Private *priv = display->priv; + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); + return priv->display; } @@ -138,6 +140,8 @@ gst_vaapi_display_x11_set_display(GstVaapiDisplayX11 *display, { GstVaapiDisplayX11Private *priv = display->priv; + g_return_if_fail(GST_VAAPI_IS_DISPLAY_X11(display)); + if (x11_display) { VADisplay va_display = vaGetDisplay(x11_display); if (va_display) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 8633a02186..bd7b22394d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -21,7 +21,7 @@ #ifndef GST_VAAPI_DISPLAY_X11_H #define GST_VAAPI_DISPLAY_X11_H -#include "gstvaapidisplay.h" +#include #include G_BEGIN_DECLS From 0b3d5ddd0cc5cffa841926b8b5a62872575c4b9c Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 4 Mar 2010 17:41:34 +0000 Subject: [PATCH 0009/3781] Add utilities to check whether a VA-API driver supports specific image or subpicture format. Likewise for VA profile. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 62 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 16 +++++++ 2 files changed, 78 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 9a24e5d894..d45a66fd77 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -143,6 +143,8 @@ gst_vaapi_display_get_display(GstVaapiDisplay *display) { GstVaapiDisplayPrivate *priv = display->priv; + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + return priv->display; } @@ -238,6 +240,8 @@ gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display) VAStatus status; int major_version, minor_version; + g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); + if (priv->display) { gst_vaapi_display_destroy_resources(display); @@ -261,3 +265,61 @@ gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display) } } } + +gboolean +gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile) +{ + guint i; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + + for (i = 0; i < display->priv->num_profiles; i++) + if (display->priv->profiles[i] == profile) + return TRUE; + return FALSE; +} + +static gboolean +_gst_vaapi_display_has_format( + GstVaapiDisplay *display, + GstVaapiImageFormat format, + const VAImageFormat *va_formats, + guint num_va_formats +) +{ + guint i; + + g_return_val_if_fail(format != 0, FALSE); + + for (i = 0; i < num_va_formats; i++) + if (gst_vaapi_image_format(&va_formats[i]) == format) + return TRUE; + return FALSE; +} + +gboolean +gst_vaapi_display_has_image_format( + GstVaapiDisplay *display, + GstVaapiImageFormat format +) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + + return _gst_vaapi_display_has_format(display, format, + display->priv->image_formats, + display->priv->num_image_formats); +} + +gboolean +gst_vaapi_display_has_subpicture_format( + GstVaapiDisplay *display, + GstVaapiImageFormat format +) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + + return _gst_vaapi_display_has_format(display, format, + display->priv->subpicture_formats, + display->priv->num_subpicture_formats); +} + diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 942b6e5e64..e4a2314237 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -23,6 +23,7 @@ #include #include +#include G_BEGIN_DECLS @@ -72,6 +73,21 @@ gst_vaapi_display_get_type(void); VADisplay gst_vaapi_display_get_display(GstVaapiDisplay *display); +gboolean +gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile); + +gboolean +gst_vaapi_display_has_image_format( + GstVaapiDisplay *display, + GstVaapiImageFormat format +); + +gboolean +gst_vaapi_display_has_subpicture_format( + GstVaapiDisplay *display, + GstVaapiImageFormat format +); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_H */ From 38b0fe7d57d555b1a3b9bcaeb6e2cf493959b78b Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 5 Mar 2010 08:52:20 +0000 Subject: [PATCH 0010/3781] Fix subpicture formats list length. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index d45a66fd77..b1100c7545 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -222,7 +222,7 @@ gst_vaapi_display_create_resources(GstVaapiDisplay *display) status = vaQuerySubpictureFormats(priv->display, priv->subpicture_formats, priv->subpicture_flags, - &priv->num_image_formats); + &priv->num_subpicture_formats); if (!vaapi_check_status(status, "vaQuerySubpictureFormats()")) return FALSE; From 372e9f5d4da67d1013a33bf2b58accd93c2e04c3 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 5 Mar 2010 10:04:55 +0000 Subject: [PATCH 0011/3781] Add helper to get GstVaapiDisplay from a surface. --- gst-libs/gst/vaapi/gstvaapisurface.c | 13 +++++++++++-- gst-libs/gst/vaapi/gstvaapisurface.h | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 2f52850f71..c6ff1c1ee3 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -111,7 +111,7 @@ gst_vaapi_surface_set_property(GObject *object, switch (prop_id) { case PROP_DISPLAY: - priv->display = g_object_ref(g_value_get_pointer(value)); + priv->display = g_object_ref(g_value_get_object(value)); break; case PROP_WIDTH: priv->width = g_value_get_uint(value); @@ -139,7 +139,8 @@ gst_vaapi_surface_get_property(GObject *object, switch (prop_id) { case PROP_DISPLAY: - g_value_set_pointer(value, g_object_ref(priv->display)); + /* gst_vaapi_surface_get_display() already refs the object */ + g_value_take_object(value, gst_vaapi_surface_get_display(surface)); break; case PROP_SURFACE_ID: g_value_set_uint(value, gst_vaapi_surface_get_id(surface)); @@ -283,6 +284,14 @@ gst_vaapi_surface_get_id(GstVaapiSurface *surface) return priv->surface_id; } +GstVaapiDisplay * +gst_vaapi_surface_get_display(GstVaapiSurface *surface) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); + + return g_object_ref(surface->priv->display); +} + guint gst_vaapi_surface_get_width(GstVaapiSurface *surface) { diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index cbbd1baf8d..7d8f27617d 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -77,6 +77,9 @@ gst_vaapi_surface_new(GstVaapiDisplay *display, VASurfaceID gst_vaapi_surface_get_id(GstVaapiSurface *surface); +GstVaapiDisplay * +gst_vaapi_surface_get_display(GstVaapiSurface *surface); + guint gst_vaapi_surface_get_width(GstVaapiSurface *surface); From ffb296984e841d776320eaea99a97e72ba947513 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 5 Mar 2010 10:07:22 +0000 Subject: [PATCH 0012/3781] Shorter code (and more correct). --- gst-libs/gst/vaapi/gstvaapisurface.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index c6ff1c1ee3..fb1aba11b8 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -277,11 +277,9 @@ gst_vaapi_surface_new(GstVaapiDisplay *display, VASurfaceID gst_vaapi_surface_get_id(GstVaapiSurface *surface) { - GstVaapiSurfacePrivate * const priv = surface->priv; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), VA_INVALID_SURFACE); - return priv->surface_id; + return surface->priv->surface_id; } GstVaapiDisplay * @@ -295,29 +293,23 @@ gst_vaapi_surface_get_display(GstVaapiSurface *surface) guint gst_vaapi_surface_get_width(GstVaapiSurface *surface) { - GstVaapiSurfacePrivate * const priv = surface->priv; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); - return priv->width; + return surface->priv->width; } guint gst_vaapi_surface_get_height(GstVaapiSurface *surface) { - GstVaapiSurfacePrivate * const priv = surface->priv; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); - return priv->height; + return surface->priv->height; } guint gst_vaapi_surface_get_format(GstVaapiSurface *surface) { - GstVaapiSurfacePrivate *priv = surface->priv; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); - return priv->format; + return surface->priv->format; } From 11149b012475e144b2897b614095c55154cdaa8d Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 5 Mar 2010 15:26:36 +0000 Subject: [PATCH 0013/3781] Rename to vaapisink. --- sys/{vaapi => vaapisink}/Makefile.am | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sys/{vaapi => vaapisink}/Makefile.am (100%) diff --git a/sys/vaapi/Makefile.am b/sys/vaapisink/Makefile.am similarity index 100% rename from sys/vaapi/Makefile.am rename to sys/vaapisink/Makefile.am From d80785fda6d61d9c83a38832905fce060e5f3ed6 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 5 Mar 2010 15:29:04 +0000 Subject: [PATCH 0014/3781] Add vaapiconvert element hierarchy. --- configure.ac | 3 ++- sys/Makefile.am | 2 +- sys/vaapiconvert/Makefile.am | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 sys/vaapiconvert/Makefile.am diff --git a/configure.ac b/configure.ac index fee139e6a1..0d36f0462d 100644 --- a/configure.ac +++ b/configure.ac @@ -135,7 +135,8 @@ AC_OUTPUT([ gst-libs/gst/Makefile gst-libs/gst/vaapi/Makefile sys/Makefile - sys/vaapi/Makefile + sys/vaapiconvert/Makefile + sys/vaapisink/Makefile tests/Makefile tests/examples/Makefile tests/examples/generic/Makefile diff --git a/sys/Makefile.am b/sys/Makefile.am index 37d365da29..106bb4192e 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = vaapi +SUBDIRS = vaapiconvert vaapisink # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/sys/vaapiconvert/Makefile.am b/sys/vaapiconvert/Makefile.am new file mode 100644 index 0000000000..549bd993c7 --- /dev/null +++ b/sys/vaapiconvert/Makefile.am @@ -0,0 +1,15 @@ +plugin_LTLIBRARIES = libgstvaapiconvert.la + +libgstvaapiconvert_la_SOURCES = \ + $(NULL) + +noinst_HEADERS = \ + $(NULL) + +libgstvaapiconvert_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) +libgstvaapiconvert_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) +libgstvaapiconvert_la_LDFLAGS = +libgstvaapiconvert_la_LIBTOOLFLAGS = --tag=disable-static + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in From 95a4bca0ee45c62ae2915705f08e22ca151c8bd8 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 5 Mar 2010 17:11:52 +0000 Subject: [PATCH 0015/3781] Add boilerplate for vaapiconvert and vaapisink elements. --- configure.ac | 14 ++++ sys/vaapiconvert/Makefile.am | 15 +++- sys/vaapiconvert/gstvaapiconvert.c | 122 +++++++++++++++++++++++++++++ sys/vaapiconvert/gstvaapiconvert.h | 73 +++++++++++++++++ sys/vaapisink/Makefile.am | 15 +++- sys/vaapisink/gstvaapisink.c | 85 ++++++++++++++++++++ sys/vaapisink/gstvaapisink.h | 73 +++++++++++++++++ 7 files changed, 391 insertions(+), 6 deletions(-) create mode 100644 sys/vaapiconvert/gstvaapiconvert.c create mode 100644 sys/vaapiconvert/gstvaapiconvert.h create mode 100644 sys/vaapisink/gstvaapisink.c create mode 100644 sys/vaapisink/gstvaapisink.h diff --git a/configure.ac b/configure.ac index 0d36f0462d..7ada7797a8 100644 --- a/configure.ac +++ b/configure.ac @@ -80,6 +80,20 @@ PKG_CHECK_MODULES([GST_PLUGINS_BASE], AC_SUBST(GST_PLUGINS_BASE_CFLAGS) AC_SUBST(GST_PLUGINS_BASE_LIBS) +dnl Check for GStreamer base +PKG_CHECK_MODULES([GST_BASE], + [gstreamer-base-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED] +) +AC_SUBST(GST_BASE_CFLAGS) +AC_SUBST(GST_BASE_LIBS) + +dnl Check for GStreamer video +PKG_CHECK_MODULES([GST_VIDEO], + [gstreamer-video-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED] +) +AC_SUBST(GST_VIDEO_CFLAGS) +AC_SUBST(GST_VIDEO_LIBS) + dnl Check for the GStreamer plugins directory AC_MSG_CHECKING([for GStreamer plugins directory]) GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_MAJORMINOR --variable pluginsdir` diff --git a/sys/vaapiconvert/Makefile.am b/sys/vaapiconvert/Makefile.am index 549bd993c7..1cb2dbe804 100644 --- a/sys/vaapiconvert/Makefile.am +++ b/sys/vaapiconvert/Makefile.am @@ -1,14 +1,23 @@ plugin_LTLIBRARIES = libgstvaapiconvert.la libgstvaapiconvert_la_SOURCES = \ + gstvaapiconvert.c \ $(NULL) noinst_HEADERS = \ + gstvaapiconvert.h \ $(NULL) -libgstvaapiconvert_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) -libgstvaapiconvert_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) -libgstvaapiconvert_la_LDFLAGS = +libgstvaapiconvert_la_CFLAGS = \ + $(GST_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(GST_PLUGINS_BASE_CFLAGS) + +libgstvaapiconvert_la_LIBADD = \ + $(GST_LIBS) \ + $(GST_BASE_LIBS) \ + $(GST_PLUGINS_BASE_LIBS) + libgstvaapiconvert_la_LIBTOOLFLAGS = --tag=disable-static # Extra clean files so that maintainer-clean removes *everything* diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c new file mode 100644 index 0000000000..4ac789adb6 --- /dev/null +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -0,0 +1,122 @@ +/* + * gstvaapiconvert.c - VA-API video converter + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include +#include "gstvaapiconvert.h" + +/* ElementFactory information */ +static const GstElementDetails gst_vaapiconvert_details = + GST_ELEMENT_DETAILS( + "Video convert", + "Convert/Video", + "A VA-API based videoconvert", + "Gwenole Beauchesne "); + +/* Default templates */ +static GstStaticPadTemplate gst_vaapiconvert_sink_factory = + GST_STATIC_PAD_TEMPLATE( + "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS( + "video/x-raw-yuv, " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]; ")); + +static GstStaticPadTemplate gst_vaapiconvert_src_factory = + GST_STATIC_PAD_TEMPLATE( + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS( + "video/x-vaapi-surface, " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]; ")); + +GST_BOILERPLATE( + GstVaapiConvert, + gst_vaapiconvert, + GstBaseTransform, + GST_TYPE_BASE_TRANSFORM); + +static GstFlowReturn +gst_vaapiconvert_transform( + GstBaseTransform *trans, + GstBuffer *inbuf, + GstBuffer *outbuf +); + +static void gst_vaapiconvert_base_init(gpointer klass) +{ + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + + gst_element_class_set_details(element_class, &gst_vaapiconvert_details); + + gst_element_class_add_pad_template( + element_class, + gst_static_pad_template_get(&gst_vaapiconvert_sink_factory) + ); + gst_element_class_add_pad_template( + element_class, + gst_static_pad_template_get(&gst_vaapiconvert_src_factory) + ); +} + +static void gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); + + trans_class->transform = GST_DEBUG_FUNCPTR(gst_vaapiconvert_transform); +} + +static void +gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) +{ +} + +static GstFlowReturn +gst_vaapiconvert_transform( + GstBaseTransform *trans, + GstBuffer *inbuf, + GstBuffer *outbuf +) +{ + return GST_FLOW_OK; +} + +static gboolean plugin_init(GstPlugin *plugin) +{ + return gst_element_register(plugin, + "vaapiconvert", + GST_RANK_PRIMARY, + GST_TYPE_VAAPICONVERT); +} + +GST_PLUGIN_DEFINE( + GST_VERSION_MAJOR, GST_VERSION_MINOR, + "vaapiconvert", + "A VA-API based video pixels format converter", + plugin_init, + PACKAGE_VERSION, + "GPL", + PACKAGE, + PACKAGE_BUGREPORT); diff --git a/sys/vaapiconvert/gstvaapiconvert.h b/sys/vaapiconvert/gstvaapiconvert.h new file mode 100644 index 0000000000..20189ad066 --- /dev/null +++ b/sys/vaapiconvert/gstvaapiconvert.h @@ -0,0 +1,73 @@ +/* + * gstvaapiconvert.h - VA-API video converter + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPICONVERT_H +#define GST_VAAPICONVERT_H + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPICONVERT \ + (gst_vaapiconvert_get_type()) + +#define GST_VAAPICONVERT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_TYPE_VAAPICONVERT, \ + GstVaapiConvert)) + +#define GST_VAAPICONVERT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_TYPE_VAAPICONVERT, \ + GstVaapiConvertClass)) + +#define GST_IS_VAAPICONVERT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPICONVERT)) + +#define GST_IS_VAAPICONVERT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPICONVERT)) + +#define GST_VAAPICONVERT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_TYPE_VAAPICONVERT, \ + GstVaapiConvert)) + +typedef struct _GstVaapiConvert GstVaapiConvert; +typedef struct _GstVaapiConvertPrivate GstVaapiConvertPrivate; +typedef struct _GstVaapiConvertClass GstVaapiConvertClass; + +struct _GstVaapiConvert { + /*< private >*/ + GstBaseTransform parent_instance; + + GstVaapiConvertPrivate *priv; +}; + +struct _GstVaapiConvertClass { + /*< private >*/ + GstBaseTransformClass parent_class; +}; + +GType +gst_vaapiconvert_get_type(void); + +G_END_DECLS + +#endif /* GST_VAAPICONVERT_H */ diff --git a/sys/vaapisink/Makefile.am b/sys/vaapisink/Makefile.am index 648082cd0b..f886efaf3e 100644 --- a/sys/vaapisink/Makefile.am +++ b/sys/vaapisink/Makefile.am @@ -1,14 +1,23 @@ plugin_LTLIBRARIES = libgstvaapisink.la libgstvaapisink_la_SOURCES = \ + gstvaapisink.c \ $(NULL) noinst_HEADERS = \ + gstvaapisink.h \ $(NULL) -libgstvaapisink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) -libgstvaapisink_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) -libgstvaapisink_la_LDFLAGS = +libgstvaapisink_la_CFLAGS = \ + $(GST_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ + $(GST_PLUGINS_BASE_CFLAGS) + +libgstvaapisink_la_LIBADD = \ + $(GST_LIBS) \ + $(GST_VIDEO_LIBS) \ + $(GST_PLUGINS_BASE_LIBS) + libgstvaapisink_la_LIBTOOLFLAGS = --tag=disable-static # Extra clean files so that maintainer-clean removes *everything* diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c new file mode 100644 index 0000000000..19a0d69fb5 --- /dev/null +++ b/sys/vaapisink/gstvaapisink.c @@ -0,0 +1,85 @@ +/* + * gstvaapisink.c - VA-API video sink + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "gstvaapisink.h" + +/* ElementFactory information */ +static const GstElementDetails gst_vaapisink_details = + GST_ELEMENT_DETAILS( + "Video sink", + "Sink/Video", + "A VA-API based videosink", + "Gwenole Beauchesne "); + +/* Default template */ +static GstStaticPadTemplate gst_vaapisink_sink_factory = + GST_STATIC_PAD_TEMPLATE( + "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS( + "video/x-vaapi-surface, " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]; ")); + +GST_BOILERPLATE(GstVaapiSink, gst_vaapisink, GstVideoSink, GST_TYPE_VIDEO_SINK); + +static void gst_vaapisink_base_init(gpointer klass) +{ + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + + gst_element_class_set_details(element_class, &gst_vaapisink_details); + + gst_element_class_add_pad_template( + element_class, + gst_static_pad_template_get(&gst_vaapisink_sink_factory) + ); +} + +static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass); + GstVideoSinkClass * const videosink_class = GST_VIDEO_SINK_CLASS(klass); +} + +static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) +{ +} + +static gboolean plugin_init(GstPlugin *plugin) +{ + return gst_element_register(plugin, + "vaapisink", + GST_RANK_PRIMARY, + GST_TYPE_VAAPISINK); +} + +GST_PLUGIN_DEFINE( + GST_VERSION_MAJOR, GST_VERSION_MINOR, + "vaapisink", + "A VA-API based videosink", + plugin_init, + PACKAGE_VERSION, + "GPL", + PACKAGE, + PACKAGE_BUGREPORT); diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h new file mode 100644 index 0000000000..270d1a635f --- /dev/null +++ b/sys/vaapisink/gstvaapisink.h @@ -0,0 +1,73 @@ +/* + * gstvaapisink.h - VA-API video sink + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPISINK_H +#define GST_VAAPISINK_H + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPISINK \ + (gst_vaapisink_get_type()) + +#define GST_VAAPISINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_TYPE_VAAPISINK, \ + GstVaapiSink)) + +#define GST_VAAPISINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_TYPE_VAAPISINK, \ + GstVaapiSinkClass)) + +#define GST_IS_VAAPISINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPISINK)) + +#define GST_IS_VAAPISINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPISINK)) + +#define GST_VAAPISINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_TYPE_VAAPISINK, \ + GstVaapiSink)) + +typedef struct _GstVaapiSink GstVaapiSink; +typedef struct _GstVaapiSinkPrivate GstVaapiSinkPrivate; +typedef struct _GstVaapiSinkClass GstVaapiSinkClass; + +struct _GstVaapiSink { + /*< private >*/ + GstVideoSink parent_instance; + + GstVaapiSinkPrivate *priv; +}; + +struct _GstVaapiSinkClass { + /*< private >*/ + GstVideoSinkClass parent_class; +}; + +GType +gst_vaapisink_get_type(void); + +G_END_DECLS + +#endif /* GST_VAAPISINK_H */ From 1689ee112d0e77612f7248eb3b816de571b853e9 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 9 Mar 2010 12:00:32 +0000 Subject: [PATCH 0016/3781] Cosmetics (drop unused variables). --- gst-libs/gst/vaapi/gstvaapidisplay.c | 9 +++------ gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 9 ++------- gst-libs/gst/vaapi/gstvaapisurface.c | 3 +-- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index b1100c7545..c61f02a61e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -56,8 +56,7 @@ gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display); static void gst_vaapi_display_finalize(GObject *object) { - GstVaapiDisplay *display = GST_VAAPI_DISPLAY(object); - GstVaapiDisplayPrivate *priv = display->priv; + GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); gst_vaapi_display_set_display(display, NULL); @@ -70,8 +69,7 @@ gst_vaapi_display_set_property(GObject *object, const GValue *value, GParamSpec *pspec) { - GstVaapiDisplay *display = GST_VAAPI_DISPLAY(object); - GstVaapiDisplayPrivate *priv = display->priv; + GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); switch (prop_id) { case PROP_DISPLAY: @@ -89,8 +87,7 @@ gst_vaapi_display_get_property(GObject *object, GValue *value, GParamSpec *pspec) { - GstVaapiDisplay *display = GST_VAAPI_DISPLAY(object); - GstVaapiDisplayPrivate *priv = display->priv; + GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); switch (prop_id) { case PROP_DISPLAY: diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 3a2db88b8d..273db5e1c8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -51,9 +51,6 @@ gst_vaapi_display_x11_set_display(GstVaapiDisplayX11 *display, static void gst_vaapi_display_x11_finalize(GObject *object) { - GstVaapiDisplayX11 *display = GST_VAAPI_DISPLAY_X11(object); - GstVaapiDisplayX11Private *priv = display->priv; - G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class)->finalize(object); } @@ -63,8 +60,7 @@ gst_vaapi_display_x11_set_property(GObject *object, const GValue *value, GParamSpec *pspec) { - GstVaapiDisplayX11 *display = GST_VAAPI_DISPLAY_X11(object); - GstVaapiDisplayX11Private *priv = display->priv; + GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); switch (prop_id) { case PROP_X11_DISPLAY: @@ -82,8 +78,7 @@ gst_vaapi_display_x11_get_property(GObject *object, GValue *value, GParamSpec *pspec) { - GstVaapiDisplayX11 *display = GST_VAAPI_DISPLAY_X11(object); - GstVaapiDisplayX11Private *priv = display->priv; + GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); switch (prop_id) { case PROP_X11_DISPLAY: diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index fb1aba11b8..d0ee6a24cb 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -134,8 +134,7 @@ gst_vaapi_surface_get_property(GObject *object, GValue *value, GParamSpec *pspec) { - GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); - GstVaapiSurfacePrivate * const priv = surface->priv; + GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); switch (prop_id) { case PROP_DISPLAY: From b5548b7efd78ea92bc7df26663aaf018b6252a7b Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 10 Mar 2010 10:41:12 +0000 Subject: [PATCH 0017/3781] Add helper to convert from GstVaapiImageFormat to GstCaps. --- gst-libs/gst/vaapi/gstvaapiimageformat.c | 33 ++++++++++++++++++------ gst-libs/gst/vaapi/gstvaapiimageformat.h | 3 +++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 3303063a60..8f6e10bcdb 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -20,6 +20,7 @@ #include "config.h" #include +#include #include "gstvaapiimageformat.h" typedef enum _GstVaapiImageFormatType GstVaapiImageFormatType; @@ -34,20 +35,20 @@ enum _GstVaapiImageFormatType { struct _GstVaapiImageFormatMap { GstVaapiImageFormatType type; GstVaapiImageFormat format; + GstStaticCaps caps; VAImageFormat va_format; }; -#define DEF(TYPE, FORMAT) \ - GST_VAAPI_IMAGE_FORMAT_TYPE_##TYPE, GST_VAAPI_IMAGE_##FORMAT +#define DEF(TYPE, FORMAT, CAPS_STR) \ + GST_VAAPI_IMAGE_FORMAT_TYPE_##TYPE, \ + GST_VAAPI_IMAGE_##FORMAT, \ + GST_STATIC_CAPS(CAPS_STR) #define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP) \ - { DEF(YCBCR, FORMAT), \ + { DEF(YCBCR, FORMAT, GST_VIDEO_CAPS_YUV(#FORMAT)), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } #define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \ - { DEF(RGB, FORMAT), \ + { DEF(RGB, FORMAT, GST_VIDEO_CAPS_##FORMAT), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } -#define DEF_IDX(FORMAT, FOURCC, ENDIAN, BPP, NPE, EB, C0,C1,C2,C3) \ - { DEF(TYPE, FORMAT), \ - { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, } static const GstVaapiImageFormatMap gst_vaapi_image_formats[] = { DEF_YUV(NV12, ('N','V','1','2'), LSB, 12), @@ -67,7 +68,6 @@ static const GstVaapiImageFormatMap gst_vaapi_image_formats[] = { { 0, } }; -#undef DEF_IDX #undef DEF_RGB #undef DEF_YUV #undef DEF @@ -151,3 +151,20 @@ gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format) return &m->va_format; } + +GstCaps * +gst_vaapi_image_format_get_caps(GstVaapiImageFormat format) +{ + GstCaps *caps; + const GstVaapiImageFormatMap *m; + + m = get_map_from_gst_vaapi_image_format(format); + + g_return_val_if_fail(m, NULL); + + caps = gst_static_caps_get(&m->caps); + if (!caps) + return NULL; + + return gst_caps_make_writable(caps); +} diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index 89987332b7..90e71ffe01 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -60,6 +60,9 @@ gst_vaapi_image_format_from_fourcc(guint32 fourcc); const VAImageFormat * gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format); +GstCaps * +gst_vaapi_image_format_get_caps(GstVaapiImageFormat format); + G_END_DECLS #endif /* GST_GST_VAAPI_IMAGE_H */ From 0dd58839e13551b566d63a8e9250725e6bf6eca4 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 10 Mar 2010 10:43:31 +0000 Subject: [PATCH 0018/3781] Get VA image & subpicture formats as GstCaps. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 54 +++++++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapidisplay.h | 6 ++++ 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index c61f02a61e..160e9957a6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -278,13 +278,13 @@ gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile) static gboolean _gst_vaapi_display_has_format( - GstVaapiDisplay *display, - GstVaapiImageFormat format, + GstVaapiDisplay *display, + GstVaapiImageFormat format, const VAImageFormat *va_formats, - guint num_va_formats + unsigned int num_va_formats ) { - guint i; + unsigned int i; g_return_val_if_fail(format != 0, FALSE); @@ -294,6 +294,41 @@ _gst_vaapi_display_has_format( return FALSE; } +static GstCaps * +_gst_vaapi_display_get_caps( + GstVaapiDisplay *display, + const VAImageFormat *va_formats, + unsigned int num_va_formats +) +{ + GstCaps *out_caps; + unsigned int i; + + out_caps = gst_caps_new_empty(); + if (!out_caps) + return NULL; + + for (i = 0; i < num_va_formats; i++) { + GstVaapiImageFormat format = gst_vaapi_image_format(&va_formats[i]); + if (format) { + GstCaps * const caps = gst_vaapi_image_format_get_caps(format); + if (caps) + gst_caps_append(out_caps, caps); + } + } + return out_caps; +} + +GstCaps * +gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + return _gst_vaapi_display_get_caps(display, + display->priv->image_formats, + display->priv->num_image_formats); +} + gboolean gst_vaapi_display_has_image_format( GstVaapiDisplay *display, @@ -307,6 +342,16 @@ gst_vaapi_display_has_image_format( display->priv->num_image_formats); } +GstCaps * +gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + return _gst_vaapi_display_get_caps(display, + display->priv->subpicture_formats, + display->priv->num_subpicture_formats); +} + gboolean gst_vaapi_display_has_subpicture_format( GstVaapiDisplay *display, @@ -319,4 +364,3 @@ gst_vaapi_display_has_subpicture_format( display->priv->subpicture_formats, display->priv->num_subpicture_formats); } - diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index e4a2314237..187261c664 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -76,12 +76,18 @@ gst_vaapi_display_get_display(GstVaapiDisplay *display); gboolean gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile); +GstCaps * +gst_vaapi_display_get_image_caps(GstVaapiDisplay *display); + gboolean gst_vaapi_display_has_image_format( GstVaapiDisplay *display, GstVaapiImageFormat format ); +GstCaps * +gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display); + gboolean gst_vaapi_display_has_subpicture_format( GstVaapiDisplay *display, From 5fdc1dc9433e0582bf94ba0b1473d5ff874b31c6 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 10 Mar 2010 12:25:19 +0000 Subject: [PATCH 0019/3781] Fix GstVaapiDisplay initialization. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 222 ++++++++++++----------- gst-libs/gst/vaapi/gstvaapidisplay.h | 3 + gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 32 +--- 3 files changed, 122 insertions(+), 135 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 160e9957a6..b31e6dfefa 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -53,12 +53,110 @@ enum { static void gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display); +static void +gst_vaapi_display_destroy(GstVaapiDisplay *display) +{ + GstVaapiDisplayPrivate * const priv = display->priv; + + if (priv->profiles) { + g_free(priv->profiles); + priv->profiles = NULL; + } + + if (priv->image_formats) { + g_free(priv->image_formats); + priv->image_formats = NULL; + priv->num_image_formats = 0; + } + + if (priv->subpicture_formats) { + g_free(priv->subpicture_formats); + priv->subpicture_formats = NULL; + priv->num_subpicture_formats = 0; + } + + if (priv->subpicture_flags) { + g_free(priv->subpicture_flags); + priv->subpicture_flags = NULL; + } + + if (priv->display) { + vaTerminate(priv->display); + priv->display = NULL; + } +} + +static gboolean +gst_vaapi_display_create(GstVaapiDisplay *display) +{ + GstVaapiDisplayPrivate * const priv = display->priv; + VAStatus status; + int major_version, minor_version; + unsigned int i; + + status = vaInitialize(priv->display, &major_version, &minor_version); + if (!vaapi_check_status(status, "vaInitialize()")) + return FALSE; + D(bug("VA-API version %d.%d\n", major_version, minor_version)); + + /* VA profiles */ + priv->num_profiles = vaMaxNumProfiles(priv->display); + priv->profiles = g_new(VAProfile, priv->num_profiles); + if (!priv->profiles) + return FALSE; + status = vaQueryConfigProfiles(priv->display, + priv->profiles, + &priv->num_profiles); + if (!vaapi_check_status(status, "vaQueryConfigProfiles()")) + return FALSE; + + D(bug("%d profiles\n", priv->num_profiles)); + for (i = 0; i < priv->num_profiles; i++) + D(bug(" %s\n", string_of_VAProfile(priv->profiles[i]))); + + /* VA image formats */ + priv->num_image_formats = vaMaxNumImageFormats(priv->display); + priv->image_formats = g_new(VAImageFormat, priv->num_image_formats); + if (!priv->image_formats) + return FALSE; + status = vaQueryImageFormats(priv->display, + priv->image_formats, + &priv->num_image_formats); + if (!vaapi_check_status(status, "vaQueryImageFormats()")) + return FALSE; + + D(bug("%d image formats\n", priv->num_image_formats)); + for (i = 0; i < priv->num_image_formats; i++) + D(bug(" %s\n", string_of_FOURCC(priv->image_formats[i].fourcc))); + + /* VA subpicture formats */ + priv->num_subpicture_formats = vaMaxNumSubpictureFormats(priv->display); + priv->subpicture_formats = g_new(VAImageFormat, priv->num_subpicture_formats); + if (!priv->subpicture_formats) + return FALSE; + priv->subpicture_flags = g_new(unsigned int, priv->num_subpicture_formats); + if (!priv->subpicture_flags) + return FALSE; + status = vaQuerySubpictureFormats(priv->display, + priv->subpicture_formats, + priv->subpicture_flags, + &priv->num_subpicture_formats); + if (!vaapi_check_status(status, "vaQuerySubpictureFormats()")) + return FALSE; + + D(bug("%d subpicture formats\n", priv->num_subpicture_formats)); + for (i = 0; i < priv->num_subpicture_formats; i++) + D(bug(" %s\n", string_of_FOURCC(priv->subpicture_formats[i].fourcc))); + + return TRUE; +} + static void gst_vaapi_display_finalize(GObject *object) { GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); - gst_vaapi_display_set_display(display, NULL); + gst_vaapi_display_destroy(display); G_OBJECT_CLASS(gst_vaapi_display_parent_class)->finalize(object); } @@ -135,129 +233,37 @@ gst_vaapi_display_init(GstVaapiDisplay *display) priv->num_subpicture_formats = 0; } +GstVaapiDisplay * +gst_vaapi_display_new_with_display(VADisplay va_display) +{ + return g_object_new(GST_VAAPI_TYPE_DISPLAY, + "display", va_display, + NULL); +} + VADisplay gst_vaapi_display_get_display(GstVaapiDisplay *display) { - GstVaapiDisplayPrivate *priv = display->priv; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return priv->display; -} - -static void -gst_vaapi_display_destroy_resources(GstVaapiDisplay *display) -{ - GstVaapiDisplayPrivate *priv = display->priv; - - if (priv->profiles) { - g_free(priv->profiles); - priv->profiles = NULL; - } - - if (priv->image_formats) { - g_free(priv->image_formats); - priv->image_formats = NULL; - } - - if (priv->subpicture_formats) { - g_free(priv->subpicture_formats); - priv->subpicture_formats = NULL; - } - - if (priv->subpicture_flags) { - g_free(priv->subpicture_flags); - priv->subpicture_flags = NULL; - } -} - -static gboolean -gst_vaapi_display_create_resources(GstVaapiDisplay *display) -{ - GstVaapiDisplayPrivate *priv = display->priv; - VAStatus status; - unsigned int i; - - /* VA profiles */ - priv->num_profiles = vaMaxNumProfiles(priv->display); - priv->profiles = g_new(VAProfile, priv->num_profiles); - if (!priv->profiles) - return FALSE; - status = vaQueryConfigProfiles(priv->display, - priv->profiles, - &priv->num_profiles); - if (!vaapi_check_status(status, "vaQueryConfigProfiles()")) - return FALSE; - - D(bug("%d profiles\n", priv->num_profiles)); - for (i = 0; i < priv->num_profiles; i++) - D(bug(" %s\n", string_of_VAProfile(priv->profiles[i]))); - - /* VA image formats */ - priv->num_image_formats = vaMaxNumImageFormats(priv->display); - priv->image_formats = g_new(VAImageFormat, priv->num_image_formats); - if (!priv->image_formats) - return FALSE; - status = vaQueryImageFormats(priv->display, - priv->image_formats, - &priv->num_image_formats); - if (!vaapi_check_status(status, "vaQueryImageFormats()")) - return FALSE; - - D(bug("%d image formats\n", priv->num_image_formats)); - for (i = 0; i < priv->num_image_formats; i++) - D(bug(" %s\n", string_of_FOURCC(priv->image_formats[i].fourcc))); - - /* VA subpicture formats */ - priv->num_subpicture_formats = vaMaxNumSubpictureFormats(priv->display); - priv->subpicture_formats = g_new(VAImageFormat, priv->num_subpicture_formats); - if (!priv->subpicture_formats) - return FALSE; - priv->subpicture_flags = g_new(unsigned int, priv->num_subpicture_formats); - if (!priv->subpicture_flags) - return FALSE; - status = vaQuerySubpictureFormats(priv->display, - priv->subpicture_formats, - priv->subpicture_flags, - &priv->num_subpicture_formats); - if (!vaapi_check_status(status, "vaQuerySubpictureFormats()")) - return FALSE; - - D(bug("%d subpicture formats\n", priv->num_subpicture_formats)); - for (i = 0; i < priv->num_subpicture_formats; i++) - D(bug(" %s\n", string_of_FOURCC(priv->subpicture_formats[i].fourcc))); - - return TRUE; + return display->priv->display; } void gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display) { - GstVaapiDisplayPrivate *priv = display->priv; - VAStatus status; - int major_version, minor_version; + GstVaapiDisplayPrivate * const priv = display->priv; g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); - if (priv->display) { - gst_vaapi_display_destroy_resources(display); - - /* XXX: make sure this VADisplay is really the last occurrence */ - status = vaTerminate(priv->display); - if (!vaapi_check_status(status, "vaTerminate()")) - return; - priv->display = NULL; - } + if (priv->display) + gst_vaapi_display_destroy(display); if (va_display) { - status = vaInitialize(va_display, &major_version, &minor_version); - if (!vaapi_check_status(status, "vaInitialize()")) - return; priv->display = va_display; - D(bug("VA-API version %d.%d\n", major_version, minor_version)); - - if (!gst_vaapi_display_create_resources(display)) { - gst_vaapi_display_destroy_resources(display); + if (!gst_vaapi_display_create(display)) { + printf("FAIL\n"); + gst_vaapi_display_destroy(display); return; } } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 187261c664..a895aaf8b3 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -70,6 +70,9 @@ struct _GstVaapiDisplayClass { GType gst_vaapi_display_get_type(void); +GstVaapiDisplay * +gst_vaapi_display_new_with_display(VADisplay va_display); + VADisplay gst_vaapi_display_get_display(GstVaapiDisplay *display); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 273db5e1c8..305fadcf39 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -44,10 +44,6 @@ enum { PROP_X11_DISPLAY }; -static void -gst_vaapi_display_x11_set_display(GstVaapiDisplayX11 *display, - Display *x11_display); - static void gst_vaapi_display_x11_finalize(GObject *object) { @@ -64,7 +60,7 @@ gst_vaapi_display_x11_set_property(GObject *object, switch (prop_id) { case PROP_X11_DISPLAY: - gst_vaapi_display_x11_set_display(display, g_value_get_pointer(value)); + display->priv->display = g_value_get_pointer(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -122,36 +118,18 @@ gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) Display * gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) { - GstVaapiDisplayX11Private *priv = display->priv; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); - return priv->display; -} - -void -gst_vaapi_display_x11_set_display(GstVaapiDisplayX11 *display, - Display *x11_display) -{ - GstVaapiDisplayX11Private *priv = display->priv; - - g_return_if_fail(GST_VAAPI_IS_DISPLAY_X11(display)); - - if (x11_display) { - VADisplay va_display = vaGetDisplay(x11_display); - if (va_display) - g_object_set(GST_VAAPI_DISPLAY(display), - "display", va_display, - NULL); - } - - priv->display = x11_display; + return display->priv->display; } GstVaapiDisplay * gst_vaapi_display_x11_new(Display *x11_display) { + g_return_val_if_fail(x11_display, NULL); + return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, "x11-display", x11_display, + "display", vaGetDisplay(x11_display), NULL); } From 4f1725345f91c18af931b82605c5073db32eda68 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 10 Mar 2010 12:25:38 +0000 Subject: [PATCH 0020/3781] Dump caps. --- tests/examples/generic/test-display.c | 66 ++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/tests/examples/generic/test-display.c b/tests/examples/generic/test-display.c index 5c05511ab9..bfe405583b 100644 --- a/tests/examples/generic/test-display.c +++ b/tests/examples/generic/test-display.c @@ -18,14 +18,62 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include +#include #include +static void +print_caps(GstCaps *caps, const gchar *name) +{ + guint i, n_caps = gst_caps_get_size(caps); + + g_print("%u %s caps\n", n_caps, name); + + for (i = 0; i < gst_caps_get_size(caps); i++) { + GstStructure * const structure = gst_caps_get_structure(caps, i); + if (!structure) + g_error("could not get caps structure %d", i); + + g_print(" %s:", gst_structure_get_name(structure)); + + if (gst_structure_has_name(structure, "video/x-raw-yuv")) { + guint32 fourcc; + + gst_structure_get_fourcc(structure, "format", &fourcc); + + g_print(" fourcc '%c%c%c%c'", + fourcc & 0xff, + (fourcc >> 8) & 0xff, + (fourcc >> 16) & 0xff, + (fourcc >> 24) & 0xff); + } + else { + gint bpp, endian, rmask, gmask, bmask, amask; + gboolean has_alpha; + + gst_structure_get_int(structure, "bpp", &bpp); + gst_structure_get_int(structure, "endianness", &endian); + gst_structure_get_int(structure, "red_mask", &rmask); + gst_structure_get_int(structure, "blue_mask", &bmask); + gst_structure_get_int(structure, "green_mask", &gmask); + has_alpha = gst_structure_get_int(structure, "alpha_mask", &amask); + + g_print(" %d bits per pixel, %s endian,", + bpp, endian == G_BIG_ENDIAN ? "big" : "little"); + g_print(" %s masks", has_alpha ? "rgba" : "rgb"); + g_print(" 0x%08x 0x%08x 0x%08x", rmask, gmask, bmask); + if (has_alpha) + g_print(" 0x%08x", amask); + } + g_print("\n"); + } +} + int main(int argc, char *argv[]) { Display *x11_display; GstVaapiDisplay *display; + GstCaps *caps; gst_init(&argc, &argv); @@ -37,6 +85,22 @@ main(int argc, char *argv[]) if (!display) g_error("could not create VA-API display"); + caps = gst_vaapi_display_get_image_caps(display); + if (!caps) + g_error("could not get VA image caps"); + + print_caps(caps, "image"); + gst_caps_unref(caps); + + caps = gst_vaapi_display_get_subpicture_caps(display); + if (!caps) + g_error("could not get VA subpicture caps"); + + print_caps(caps, "subpicture"); + gst_caps_unref(caps); + g_object_unref(G_OBJECT(display)); + XCloseDisplay(x11_display); + gst_deinit(); return 0; } From e3b4eff9dcb45f75dcc548329442f3a61776df56 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 10 Mar 2010 13:02:45 +0000 Subject: [PATCH 0021/3781] Fix GstVaapiSurface initialization, override constructed() method, not constructor(). GObject C is awful... --- gst-libs/gst/vaapi/gstvaapisurface.c | 31 +++++++++------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index d0ee6a24cb..e45963ec6a 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -159,28 +159,17 @@ gst_vaapi_surface_get_property(GObject *object, } } -static GObject * -gst_vaapi_surface_constructor(GType type, - guint n_params, - GObjectConstructParam *params) +static void +gst_vaapi_surface_constructed(GObject *object) { - GstVaapiSurface *surface; + GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); GObjectClass *parent_class; - GObject *object; - D(bug("gst_vaapi_surface_constructor()\n")); + gst_vaapi_surface_create(surface); parent_class = G_OBJECT_CLASS(gst_vaapi_surface_parent_class); - object = parent_class->constructor (type, n_params, params); - - if (object) { - surface = GST_VAAPI_SURFACE(object); - if (!gst_vaapi_surface_create(surface)) { - gst_vaapi_surface_destroy(surface); - object = NULL; - } - } - return object; + if (parent_class->constructed) + parent_class->constructed(object); } static void @@ -193,7 +182,7 @@ gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass) object_class->finalize = gst_vaapi_surface_finalize; object_class->set_property = gst_vaapi_surface_set_property; object_class->get_property = gst_vaapi_surface_get_property; - object_class->constructor = gst_vaapi_surface_constructor; + object_class->constructed = gst_vaapi_surface_constructed; g_object_class_install_property (object_class, @@ -267,9 +256,9 @@ gst_vaapi_surface_new(GstVaapiDisplay *display, return g_object_new(GST_VAAPI_TYPE_SURFACE, "display", display, - "width", width, - "height", height, - "format", format, + "width", width, + "height", height, + "format", format, NULL); } From 0bf78c5ef2eaca79d9d06061ce6cae47841356a4 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 10 Mar 2010 13:10:59 +0000 Subject: [PATCH 0022/3781] Fix GstVaapiImage and GstVaapiSubpicture initialization. --- gst-libs/gst/vaapi/gstvaapiimage.c | 29 ++++++++----------------- gst-libs/gst/vaapi/gstvaapisubpicture.c | 29 +------------------------ 2 files changed, 10 insertions(+), 48 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 2c6c8d88ff..eae7708f3d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -173,30 +173,19 @@ gst_vaapi_image_get_property( } } -static GObject * -gst_vaapi_image_constructor( - GType type, - guint n_params, - GObjectConstructParam *params -) +static void +gst_vaapi_image_constructed(GObject *object) { - GstVaapiImage *image; + GstVaapiImage * const image = GST_VAAPI_IMAGE(object); GObjectClass *parent_class; - GObject *object; - D(bug("gst_vaapi_image_constructor()\n")); + D(bug("gst_vaapi_image_constructed()\n")); + + gst_vaapi_image_create(image); parent_class = G_OBJECT_CLASS(gst_vaapi_image_parent_class); - object = parent_class->constructor (type, n_params, params); - - if (object) { - image = GST_VAAPI_IMAGE(object); - if (!gst_vaapi_image_create(image)) { - gst_vaapi_image_destroy(image); - object = NULL; - } - } - return object; + if (parent_class->constructed) + parent_class->constructed(object); } static void @@ -209,7 +198,7 @@ gst_vaapi_image_class_init(GstVaapiImageClass *klass) object_class->finalize = gst_vaapi_image_finalize; object_class->set_property = gst_vaapi_image_set_property; object_class->get_property = gst_vaapi_image_get_property; - object_class->constructor = gst_vaapi_image_constructor; + object_class->constructed = gst_vaapi_image_constructed; g_object_class_install_property (object_class, diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index e8efeddc76..27fb91612e 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -122,7 +122,7 @@ gst_vaapi_subpicture_set_property( switch (prop_id) { case PROP_IMAGE: - subpicture->priv->image = g_object_ref(g_value_get_object(value)); + gst_vaapi_subpicture_set_image(subpicture, g_value_get_object(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -153,32 +153,6 @@ gst_vaapi_subpicture_get_property( } } -static GObject * -gst_vaapi_subpicture_constructor( - GType type, - guint n_params, - GObjectConstructParam *params -) -{ - GstVaapiSubpicture *subpicture; - GObjectClass *parent_class; - GObject *object; - - D(bug("gst_vaapi_subpicture_constructor()\n")); - - parent_class = G_OBJECT_CLASS(gst_vaapi_subpicture_parent_class); - object = parent_class->constructor (type, n_params, params); - - if (object) { - subpicture = GST_VAAPI_SUBPICTURE(object); - if (!gst_vaapi_subpicture_create(subpicture)) { - gst_vaapi_subpicture_destroy(subpicture); - object = NULL; - } - } - return object; -} - static void gst_vaapi_subpicture_class_init(GstVaapiSubpictureClass *klass) { @@ -189,7 +163,6 @@ gst_vaapi_subpicture_class_init(GstVaapiSubpictureClass *klass) object_class->finalize = gst_vaapi_subpicture_finalize; object_class->set_property = gst_vaapi_subpicture_set_property; object_class->get_property = gst_vaapi_subpicture_get_property; - object_class->constructor = gst_vaapi_subpicture_constructor; g_object_class_install_property (object_class, From 5c5b45f4d8fcfff6ffdd2df869e6b1c5f0367ea4 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 10 Mar 2010 13:13:51 +0000 Subject: [PATCH 0023/3781] Use GST_DEBUG. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapiimage.c | 11 +++++------ gst-libs/gst/vaapi/gstvaapisubpicture.c | 7 +++---- gst-libs/gst/vaapi/gstvaapisurface.c | 5 +---- gst-libs/gst/vaapi/vaapi_debug.h | 3 +++ 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index b31e6dfefa..7185bfc05b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -26,6 +26,8 @@ #define DEBUG 1 #include "vaapi_debug.h" +GST_DEBUG_CATEGORY(gst_debug_vaapi); + G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT); #define GST_VAAPI_DISPLAY_GET_PRIVATE(obj) \ @@ -97,7 +99,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) status = vaInitialize(priv->display, &major_version, &minor_version); if (!vaapi_check_status(status, "vaInitialize()")) return FALSE; - D(bug("VA-API version %d.%d\n", major_version, minor_version)); + GST_DEBUG("VA-API version %d.%d", major_version, minor_version); /* VA profiles */ priv->num_profiles = vaMaxNumProfiles(priv->display); @@ -110,9 +112,9 @@ gst_vaapi_display_create(GstVaapiDisplay *display) if (!vaapi_check_status(status, "vaQueryConfigProfiles()")) return FALSE; - D(bug("%d profiles\n", priv->num_profiles)); + GST_DEBUG("%d profiles", priv->num_profiles); for (i = 0; i < priv->num_profiles; i++) - D(bug(" %s\n", string_of_VAProfile(priv->profiles[i]))); + GST_DEBUG(" %s", string_of_VAProfile(priv->profiles[i])); /* VA image formats */ priv->num_image_formats = vaMaxNumImageFormats(priv->display); @@ -125,9 +127,9 @@ gst_vaapi_display_create(GstVaapiDisplay *display) if (!vaapi_check_status(status, "vaQueryImageFormats()")) return FALSE; - D(bug("%d image formats\n", priv->num_image_formats)); + GST_DEBUG("%d image formats", priv->num_image_formats); for (i = 0; i < priv->num_image_formats; i++) - D(bug(" %s\n", string_of_FOURCC(priv->image_formats[i].fourcc))); + GST_DEBUG(" %s", string_of_FOURCC(priv->image_formats[i].fourcc)); /* VA subpicture formats */ priv->num_subpicture_formats = vaMaxNumSubpictureFormats(priv->display); @@ -144,9 +146,9 @@ gst_vaapi_display_create(GstVaapiDisplay *display) if (!vaapi_check_status(status, "vaQuerySubpictureFormats()")) return FALSE; - D(bug("%d subpicture formats\n", priv->num_subpicture_formats)); + GST_DEBUG("%d subpicture formats", priv->num_subpicture_formats); for (i = 0; i < priv->num_subpicture_formats; i++) - D(bug(" %s\n", string_of_FOURCC(priv->subpicture_formats[i].fourcc))); + GST_DEBUG(" %s", string_of_FOURCC(priv->subpicture_formats[i].fourcc)); return TRUE; } @@ -202,6 +204,8 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapi, "vaapi", 0, "VA-API helper"); + g_type_class_add_private(klass, sizeof(GstVaapiDisplayPrivate)); object_class->finalize = gst_vaapi_display_finalize; @@ -254,15 +258,12 @@ gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display) { GstVaapiDisplayPrivate * const priv = display->priv; - g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); - if (priv->display) gst_vaapi_display_destroy(display); if (va_display) { priv->display = va_display; if (!gst_vaapi_display_create(display)) { - printf("FAIL\n"); gst_vaapi_display_destroy(display); return; } diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index eae7708f3d..fdc99f2e99 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -179,8 +179,6 @@ gst_vaapi_image_constructed(GObject *object) GstVaapiImage * const image = GST_VAAPI_IMAGE(object); GObjectClass *parent_class; - D(bug("gst_vaapi_image_constructed()\n")); - gst_vaapi_image_create(image); parent_class = G_OBJECT_CLASS(gst_vaapi_image_parent_class); @@ -251,8 +249,6 @@ gst_vaapi_image_init(GstVaapiImage *image) { GstVaapiImagePrivate *priv = GST_VAAPI_IMAGE_GET_PRIVATE(image); - D(bug("gst_vaapi_image_init()\n")); - image->priv = priv; priv->display = NULL; priv->image_data = NULL; @@ -273,8 +269,11 @@ gst_vaapi_image_new( GstVaapiImageFormat format ) { - D(bug("gst_vaapi_image_new(): size %ux%u, format 0x%x\n", - width, height, format)); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(height > 0, NULL); + + GST_DEBUG("size %ux%u, format 0x%x", width, height, format); return g_object_new(GST_VAAPI_TYPE_IMAGE, "display", display, diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 27fb91612e..5ea5660bd3 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -188,8 +188,6 @@ gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture) { GstVaapiSubpicturePrivate *priv = GST_VAAPI_SUBPICTURE_GET_PRIVATE(subpicture); - D(bug("gst_vaapi_subpicture_init()\n")); - subpicture->priv = priv; priv->subpicture_id = VA_INVALID_ID; priv->image = NULL; @@ -198,8 +196,9 @@ gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture) GstVaapiSubpicture * gst_vaapi_subpicture_new(GstVaapiImage *image) { - D(bug("gst_vaapi_subpicture_new(): image 0x%08x\n", - gst_vaapi_image_get_id(image))); + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); + + GST_DEBUG("image 0x%08x", gst_vaapi_image_get_id(image)); return g_object_new(GST_VAAPI_TYPE_SUBPICTURE, "image", image, diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index e45963ec6a..d3b68cf22f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -235,8 +235,6 @@ gst_vaapi_surface_init(GstVaapiSurface *surface) { GstVaapiSurfacePrivate *priv = GST_VAAPI_SURFACE_GET_PRIVATE(surface); - D(bug("gst_vaapi_surface_init()\n")); - surface->priv = priv; priv->display = NULL; priv->surface_id = VA_INVALID_SURFACE; @@ -251,8 +249,7 @@ gst_vaapi_surface_new(GstVaapiDisplay *display, guint height, guint format) { - D(bug("gst_vaapi_surface_new(): size %ux%u, format 0x%x\n", - width, height, format)); + GST_DEBUG("size %ux%u, format 0x%x", width, height, format); return g_object_new(GST_VAAPI_TYPE_SURFACE, "display", display, diff --git a/gst-libs/gst/vaapi/vaapi_debug.h b/gst-libs/gst/vaapi/vaapi_debug.h index edda08fa50..547fb8c469 100644 --- a/gst-libs/gst/vaapi/vaapi_debug.h +++ b/gst-libs/gst/vaapi/vaapi_debug.h @@ -30,4 +30,7 @@ #endif #define bug vaapi_dprintf +GST_DEBUG_CATEGORY_EXTERN(gst_debug_vaapi); +#define GST_CAT_DEFAULT gst_debug_vaapi + #endif /* VAAPI_DEBUG_H */ From 224d06a03d09810196ddd4ea17ea02ed07bb6d41 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 11 Mar 2010 10:50:27 +0000 Subject: [PATCH 0024/3781] Add helper interface that all VA-API sinks must implement. e.g. vaapisink. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapisinkbase.c | 91 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisinkbase.h | 66 +++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapisinkbase.c create mode 100644 gst-libs/gst/vaapi/gstvaapisinkbase.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index edef4fa9f9..bf7cd1666c 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -4,6 +4,7 @@ libgstvaapi_source_c = \ gstvaapidisplay.c \ gstvaapiimage.c \ gstvaapiimageformat.c \ + gstvaapisinkbase.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ vaapi_utils.c \ @@ -13,6 +14,7 @@ libgstvaapi_source_h = \ gstvaapidisplay.h \ gstvaapiimage.h \ gstvaapiimageformat.h \ + gstvaapisinkbase.h \ gstvaapisubpicture.h \ gstvaapisurface.h \ vaapi_debug.h \ diff --git a/gst-libs/gst/vaapi/gstvaapisinkbase.c b/gst-libs/gst/vaapi/gstvaapisinkbase.c new file mode 100644 index 0000000000..73eede9d6c --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisinkbase.c @@ -0,0 +1,91 @@ +/* + * gstvaapisinkbase.c - VA sink interface + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "gstvaapisinkbase.h" + +static void +gst_vaapisink_base_base_init(gpointer g_class) +{ + static gboolean is_initialized = FALSE; + + if (!is_initialized) { + is_initialized = TRUE; + } +} + +GType +gst_vaapisink_base_get_type(void) +{ + static GType iface_type = 0; + + if (G_UNLIKELY(!iface_type)) { + static const GTypeInfo info = { + sizeof(GstVaapiSinkBaseInterface), + gst_vaapisink_base_base_init, /* base_init */ + NULL, /* base_finalize */ + }; + + iface_type = g_type_register_static( + G_TYPE_INTERFACE, + "GstVaapiSinkBase", + &info, + 0 + ); + } + return iface_type; +} + +GstVaapiDisplay * +gst_vaapisink_base_get_display(GstVaapiSinkBase *sink) +{ + g_return_val_if_fail(GST_IS_VAAPISINK_BASE(sink), NULL); + + return GST_VAAPISINK_BASE_GET_INTERFACE(sink)->get_display(sink); +} + +GstVaapiSinkBase * +gst_vaapisink_base_lookup(GstElement *element) +{ + GstVaapiSinkBase *sink = NULL; + GstPad *pad, *peer; + + g_return_val_if_fail(GST_IS_ELEMENT(element), NULL); + + while (!sink) { + pad = gst_element_get_static_pad(element, "src"); + if (!pad) + break; + + peer = gst_pad_get_peer(pad); + g_object_unref(pad); + if (!peer) + break; + + element = gst_pad_get_parent_element(peer); + if (element) { + if (GST_IS_VAAPISINK_BASE(element)) + sink = GST_VAAPISINK_BASE(element); + g_object_unref(element); + } + g_object_unref(peer); + } + return sink; +} diff --git a/gst-libs/gst/vaapi/gstvaapisinkbase.h b/gst-libs/gst/vaapi/gstvaapisinkbase.h new file mode 100644 index 0000000000..b436f016a8 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisinkbase.h @@ -0,0 +1,66 @@ +/* + * gstvaapisinkbase.h - VA sink interface + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPISINK_BASE_H +#define GST_VAAPISINK_BASE_H + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPISINK_BASE \ + (gst_vaapisink_base_get_type()) + +#define GST_VAAPISINK_BASE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_TYPE_VAAPISINK_BASE, \ + GstVaapiSinkBase)) + +#define GST_IS_VAAPISINK_BASE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPISINK_BASE)) + +#define GST_VAAPISINK_BASE_GET_INTERFACE(obj) \ + (G_TYPE_INSTANCE_GET_INTERFACE((obj), \ + GST_TYPE_VAAPISINK_BASE, \ + GstVaapiSinkBaseInterface)) + +typedef struct _GstVaapiSinkBase GstVaapiSinkBase; /* dummy */ +typedef struct _GstVaapiSinkBaseInterface GstVaapiSinkBaseInterface; + +struct _GstVaapiSinkBaseInterface { + /*< private >*/ + GTypeInterface g_iface; + + GstVaapiDisplay *(*get_display)(GstVaapiSinkBase *sink); +}; + +GType +gst_vaapisink_base_get_type(void); + +GstVaapiDisplay * +gst_vaapisink_base_get_display(GstVaapiSinkBase *sink); + +GstVaapiSinkBase * +gst_vaapisink_base_lookup(GstElement *element); + +G_END_DECLS + +#endif /* GST_VAAPISINK_BASE_H */ From acbab7a1c1bb410fe1c844124da9aa4b7ce174b7 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 11 Mar 2010 12:11:36 +0000 Subject: [PATCH 0025/3781] Filter out any format that is not supported by the library (libgstvaapi). Also sort the formats by HW preference. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 94 ++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiimageformat.c | 13 ++++ gst-libs/gst/vaapi/gstvaapiimageformat.h | 3 + 3 files changed, 103 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 7185bfc05b..8f3f1d643b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -55,6 +55,66 @@ enum { static void gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display); +static void +filter_formats(VAImageFormat *va_formats, unsigned int *pnum_va_formats) +{ + unsigned int i = 0; + + while (i < *pnum_va_formats) { + VAImageFormat * const va_format = &va_formats[i]; + const GstVaapiImageFormat format = gst_vaapi_image_format(va_format); + if (format) + ++i; + else { + /* Remove any format that is not supported by libgstvaapi */ + GST_DEBUG("unsupported format %c%c%c%c", + va_format->fourcc & 0xff, + (va_format->fourcc >> 8) & 0xff, + (va_format->fourcc >> 16) & 0xff, + (va_format->fourcc >> 24) & 0xff); + *va_format = va_formats[--(*pnum_va_formats)]; + } + } +} + +/* Sort image formats. Prefer YUV formats first */ +static int +compare_yuv_formats(const void *a, const void *b) +{ + const GstVaapiImageFormat fmt1 = gst_vaapi_image_format((VAImageFormat *)a); + const GstVaapiImageFormat fmt2 = gst_vaapi_image_format((VAImageFormat *)b); + + g_assert(fmt1 && fmt2); + + const gboolean is_fmt1_yuv = gst_vaapi_image_format_is_yuv(fmt1); + const gboolean is_fmt2_yuv = gst_vaapi_image_format_is_yuv(fmt2); + + if (is_fmt1_yuv != is_fmt2_yuv) + return is_fmt1_yuv ? -1 : 1; + + return ((int)gst_vaapi_image_format_get_score(fmt1) - + (int)gst_vaapi_image_format_get_score(fmt2)); +} + +/* Sort subpicture formats. Prefer RGB formats first */ +static int +compare_rgb_formats(const void *a, const void *b) +{ + const GstVaapiImageFormat fmt1 = gst_vaapi_image_format((VAImageFormat *)a); + const GstVaapiImageFormat fmt2 = gst_vaapi_image_format((VAImageFormat *)b); + + g_assert(fmt1 && fmt2); + + const gboolean is_fmt1_rgb = gst_vaapi_image_format_is_rgb(fmt1); + const gboolean is_fmt2_rgb = gst_vaapi_image_format_is_rgb(fmt2); + + if (is_fmt1_rgb != is_fmt2_rgb) + return is_fmt1_rgb ? -1 : 1; + + return ((int)gst_vaapi_image_format_get_score(fmt1) - + (int)gst_vaapi_image_format_get_score(fmt2)); +} + static void gst_vaapi_display_destroy(GstVaapiDisplay *display) { @@ -121,9 +181,11 @@ gst_vaapi_display_create(GstVaapiDisplay *display) priv->image_formats = g_new(VAImageFormat, priv->num_image_formats); if (!priv->image_formats) return FALSE; - status = vaQueryImageFormats(priv->display, - priv->image_formats, - &priv->num_image_formats); + status = vaQueryImageFormats( + priv->display, + priv->image_formats, + &priv->num_image_formats + ); if (!vaapi_check_status(status, "vaQueryImageFormats()")) return FALSE; @@ -131,6 +193,14 @@ gst_vaapi_display_create(GstVaapiDisplay *display) for (i = 0; i < priv->num_image_formats; i++) GST_DEBUG(" %s", string_of_FOURCC(priv->image_formats[i].fourcc)); + filter_formats(priv->image_formats, &priv->num_image_formats); + qsort( + priv->image_formats, + priv->num_image_formats, + sizeof(priv->image_formats[0]), + compare_yuv_formats + ); + /* VA subpicture formats */ priv->num_subpicture_formats = vaMaxNumSubpictureFormats(priv->display); priv->subpicture_formats = g_new(VAImageFormat, priv->num_subpicture_formats); @@ -139,13 +209,23 @@ gst_vaapi_display_create(GstVaapiDisplay *display) priv->subpicture_flags = g_new(unsigned int, priv->num_subpicture_formats); if (!priv->subpicture_flags) return FALSE; - status = vaQuerySubpictureFormats(priv->display, - priv->subpicture_formats, - priv->subpicture_flags, - &priv->num_subpicture_formats); + status = vaQuerySubpictureFormats( + priv->display, + priv->subpicture_formats, + priv->subpicture_flags, + &priv->num_subpicture_formats + ); if (!vaapi_check_status(status, "vaQuerySubpictureFormats()")) return FALSE; + filter_formats(priv->subpicture_formats, &priv->num_subpicture_formats); + qsort( + priv->subpicture_formats, + priv->num_subpicture_formats, + sizeof(priv->subpicture_formats[0]), + compare_rgb_formats + ); + GST_DEBUG("%d subpicture formats", priv->num_subpicture_formats); for (i = 0; i < priv->num_subpicture_formats; i++) GST_DEBUG(" %s", string_of_FOURCC(priv->subpicture_formats[i].fourcc)); diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 8f6e10bcdb..3b86514610 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -50,6 +50,7 @@ struct _GstVaapiImageFormatMap { { DEF(RGB, FORMAT, GST_VIDEO_CAPS_##FORMAT), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } +/* Image formats, listed in HW order preference */ static const GstVaapiImageFormatMap gst_vaapi_image_formats[] = { DEF_YUV(NV12, ('N','V','1','2'), LSB, 12), DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12), @@ -168,3 +169,15 @@ gst_vaapi_image_format_get_caps(GstVaapiImageFormat format) return gst_caps_make_writable(caps); } + +guint +gst_vaapi_image_format_get_score(GstVaapiImageFormat format) +{ + const GstVaapiImageFormatMap *m; + + m = get_map_from_gst_vaapi_image_format(format); + + g_return_val_if_fail(m, G_MAXUINT); + + return m - &gst_vaapi_image_formats[0]; +} diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index 90e71ffe01..98b1d2c91d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -63,6 +63,9 @@ gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format); GstCaps * gst_vaapi_image_format_get_caps(GstVaapiImageFormat format); +guint +gst_vaapi_image_format_get_score(GstVaapiImageFormat format); + G_END_DECLS #endif /* GST_GST_VAAPI_IMAGE_H */ From e59eff6902732ebfcfcbdea72ab6a2af23f78326 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 11 Mar 2010 12:14:10 +0000 Subject: [PATCH 0026/3781] Don't warn on failure, just return an appropriate error or value. --- gst-libs/gst/vaapi/gstvaapiimageformat.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 3b86514610..370633f6b7 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -107,8 +107,8 @@ gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format) const GstVaapiImageFormatMap *m; m = get_map_from_gst_vaapi_image_format(format); - - g_return_val_if_fail(m, FALSE); + if (!m) + return FALSE; return m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB; } @@ -119,8 +119,8 @@ gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format) const GstVaapiImageFormatMap *m; m = get_map_from_gst_vaapi_image_format(format); - - g_return_val_if_fail(m, FALSE); + if (!m) + return FALSE; return m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR; } @@ -130,7 +130,8 @@ gst_vaapi_image_format(const VAImageFormat *va_format) { const GstVaapiImageFormatMap * const m = get_map(va_format); - g_return_val_if_fail(m, 0); + if (!m) + return 0; return m->format; } @@ -147,8 +148,8 @@ gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format) const GstVaapiImageFormatMap *m; m = get_map_from_gst_vaapi_image_format(format); - - g_return_val_if_fail(m, NULL); + if (!m) + return NULL; return &m->va_format; } @@ -160,8 +161,8 @@ gst_vaapi_image_format_get_caps(GstVaapiImageFormat format) const GstVaapiImageFormatMap *m; m = get_map_from_gst_vaapi_image_format(format); - - g_return_val_if_fail(m, NULL); + if (!m) + return NULL; caps = gst_static_caps_get(&m->caps); if (!caps) @@ -176,8 +177,8 @@ gst_vaapi_image_format_get_score(GstVaapiImageFormat format) const GstVaapiImageFormatMap *m; m = get_map_from_gst_vaapi_image_format(format); - - g_return_val_if_fail(m, G_MAXUINT); + if (!m) + return G_MAXUINT; return m - &gst_vaapi_image_formats[0]; } From ac1243b28c206d317f20ef7f55227a77bde11b24 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 11 Mar 2010 12:30:12 +0000 Subject: [PATCH 0027/3781] New refcounting policy. All getters return a reference, not a copy. So the user shall reference the object itself, should he wish so. --- gst-libs/gst/vaapi/gstvaapiimage.c | 9 ++++----- gst-libs/gst/vaapi/gstvaapisubpicture.c | 4 +--- gst-libs/gst/vaapi/gstvaapisurface.c | 5 ++--- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index fdc99f2e99..fa97e4da08 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -123,7 +123,7 @@ gst_vaapi_image_set_property( switch (prop_id) { case PROP_DISPLAY: - priv->display = g_object_ref(g_value_get_pointer(value)); + priv->display = g_object_ref(g_value_get_object(value)); break; case PROP_WIDTH: priv->width = g_value_get_uint(value); @@ -148,12 +148,11 @@ gst_vaapi_image_get_property( GParamSpec *pspec ) { - GstVaapiImage * const image = GST_VAAPI_IMAGE(object); - GstVaapiImagePrivate * const priv = image->priv; + GstVaapiImage * const image = GST_VAAPI_IMAGE(object); switch (prop_id) { case PROP_DISPLAY: - g_value_set_pointer(value, g_object_ref(priv->display)); + g_value_set_pointer(value, gst_vaapi_image_get_display(image)); break; case PROP_IMAGE_ID: g_value_set_uint(value, gst_vaapi_image_get_id(image)); @@ -296,7 +295,7 @@ gst_vaapi_image_get_display(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); - return g_object_ref(image->priv->display); + return image->priv->display; } guint diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 5ea5660bd3..4c6c4f42d4 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -60,7 +60,6 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) gst_vaapi_display_get_display(display), priv->subpicture_id ); - g_object_unref(display); if (!vaapi_check_status(status, "vaDestroySubpicture()")) g_warning("failed to destroy subpicture 0x%08x\n", priv->subpicture_id); @@ -94,7 +93,6 @@ gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture) gst_vaapi_image_get_id(priv->image), &subpicture_id ); - g_object_unref(display); if (!vaapi_check_status(status, "vaCreateSubpicture()")) return FALSE; @@ -218,7 +216,7 @@ gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture) { g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), NULL); - return g_object_ref(subpicture->priv->image); + return subpicture->priv->image; } void diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index d3b68cf22f..efc971999c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -138,8 +138,7 @@ gst_vaapi_surface_get_property(GObject *object, switch (prop_id) { case PROP_DISPLAY: - /* gst_vaapi_surface_get_display() already refs the object */ - g_value_take_object(value, gst_vaapi_surface_get_display(surface)); + g_value_set_object(value, gst_vaapi_surface_get_display(surface)); break; case PROP_SURFACE_ID: g_value_set_uint(value, gst_vaapi_surface_get_id(surface)); @@ -272,7 +271,7 @@ gst_vaapi_surface_get_display(GstVaapiSurface *surface) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - return g_object_ref(surface->priv->display); + return surface->priv->display; } guint From e284e5e0d0c8e4be2c9c9786da60e6641c68b79e Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 11 Mar 2010 13:58:32 +0000 Subject: [PATCH 0028/3781] Use GstVaapiChromaType abstraction. --- gst-libs/gst/vaapi/gstvaapisurface.c | 96 +++++++++++++++++----------- gst-libs/gst/vaapi/gstvaapisurface.h | 24 +++++-- 2 files changed, 76 insertions(+), 44 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index efc971999c..b15d05ac8c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -38,7 +38,7 @@ struct _GstVaapiSurfacePrivate { VASurfaceID surface_id; guint width; guint height; - guint format; + GstVaapiChromaType chroma_type; }; enum { @@ -48,7 +48,7 @@ enum { PROP_SURFACE_ID, PROP_WIDTH, PROP_HEIGHT, - PROP_FORMAT + PROP_CHROMA_TYPE }; static void @@ -77,12 +77,28 @@ gst_vaapi_surface_create(GstVaapiSurface *surface) GstVaapiSurfacePrivate * const priv = surface->priv; VASurfaceID surface_id; VAStatus status; + guint format; + + switch (priv->chroma_type) { + case GST_VAAPI_CHROMA_TYPE_YUV420: + format = VA_RT_FORMAT_YUV420; + break; + case GST_VAAPI_CHROMA_TYPE_YUV422: + format = VA_RT_FORMAT_YUV422; + break; + case GST_VAAPI_CHROMA_TYPE_YUV444: + format = VA_RT_FORMAT_YUV444; + break; + default: + GST_DEBUG("unsupported chroma-type %u\n", priv->chroma_type); + return FALSE; + } status = vaCreateSurfaces( gst_vaapi_display_get_display(priv->display), priv->width, priv->height, - priv->format, + format, 1, &surface_id ); if (!vaapi_check_status(status, "vaCreateSurfaces()")) @@ -101,10 +117,12 @@ gst_vaapi_surface_finalize(GObject *object) } static void -gst_vaapi_surface_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +gst_vaapi_surface_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) { GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); GstVaapiSurfacePrivate * const priv = surface->priv; @@ -119,8 +137,8 @@ gst_vaapi_surface_set_property(GObject *object, case PROP_HEIGHT: priv->height = g_value_get_uint(value); break; - case PROP_FORMAT: - priv->format = g_value_get_uint(value); + case PROP_CHROMA_TYPE: + priv->chroma_type = g_value_get_uint(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -129,10 +147,12 @@ gst_vaapi_surface_set_property(GObject *object, } static void -gst_vaapi_surface_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +gst_vaapi_surface_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) { GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); @@ -149,8 +169,8 @@ gst_vaapi_surface_get_property(GObject *object, case PROP_HEIGHT: g_value_set_uint(value, gst_vaapi_surface_get_height(surface)); break; - case PROP_FORMAT: - g_value_set_uint(value, gst_vaapi_surface_get_format(surface)); + case PROP_CHROMA_TYPE: + g_value_set_uint(value, gst_vaapi_surface_get_chroma_type(surface)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -221,10 +241,10 @@ gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass) g_object_class_install_property (object_class, - PROP_FORMAT, - g_param_spec_uint("format", - "format", - "VA surface format", + PROP_CHROMA_TYPE, + g_param_spec_uint("chroma-type", + "chroma-type", + "VA surface chroma type", 0, G_MAXUINT32, 0, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } @@ -239,22 +259,24 @@ gst_vaapi_surface_init(GstVaapiSurface *surface) priv->surface_id = VA_INVALID_SURFACE; priv->width = 0; priv->height = 0; - priv->format = 0; + priv->chroma_type = 0; } GstVaapiSurface * -gst_vaapi_surface_new(GstVaapiDisplay *display, - guint width, - guint height, - guint format) +gst_vaapi_surface_new( + GstVaapiDisplay *display, + GstVaapiChromaType chroma_type, + guint width, + guint height +) { - GST_DEBUG("size %ux%u, format 0x%x", width, height, format); + GST_DEBUG("size %ux%u, chroma type 0x%x", width, height, chroma_type); return g_object_new(GST_VAAPI_TYPE_SURFACE, - "display", display, - "width", width, - "height", height, - "format", format, + "display", display, + "width", width, + "height", height, + "chroma-type", chroma_type, NULL); } @@ -274,6 +296,14 @@ gst_vaapi_surface_get_display(GstVaapiSurface *surface) return surface->priv->display; } +GstVaapiChromaType +gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); + + return surface->priv->chroma_type; +} + guint gst_vaapi_surface_get_width(GstVaapiSurface *surface) { @@ -289,11 +319,3 @@ gst_vaapi_surface_get_height(GstVaapiSurface *surface) return surface->priv->height; } - -guint -gst_vaapi_surface_get_format(GstVaapiSurface *surface) -{ - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); - - return surface->priv->format; -} diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 7d8f27617d..43c8f59f95 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -25,6 +25,14 @@ G_BEGIN_DECLS +typedef enum _GstVaapiChromaType GstVaapiChromaType; + +enum _GstVaapiChromaType { + GST_VAAPI_CHROMA_TYPE_YUV420 = 1, + GST_VAAPI_CHROMA_TYPE_YUV422, + GST_VAAPI_CHROMA_TYPE_YUV444 +}; + #define GST_VAAPI_TYPE_SURFACE \ (gst_vaapi_surface_get_type()) @@ -69,10 +77,12 @@ GType gst_vaapi_surface_get_type(void); GstVaapiSurface * -gst_vaapi_surface_new(GstVaapiDisplay *display, - guint width, - guint height, - guint format); +gst_vaapi_surface_new( + GstVaapiDisplay *display, + GstVaapiChromaType chroma_type, + guint width, + guint height +); VASurfaceID gst_vaapi_surface_get_id(GstVaapiSurface *surface); @@ -80,15 +90,15 @@ gst_vaapi_surface_get_id(GstVaapiSurface *surface); GstVaapiDisplay * gst_vaapi_surface_get_display(GstVaapiSurface *surface); +GstVaapiChromaType +gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface); + guint gst_vaapi_surface_get_width(GstVaapiSurface *surface); guint gst_vaapi_surface_get_height(GstVaapiSurface *surface); -guint -gst_vaapi_surface_get_format(GstVaapiSurface *surface); - G_END_DECLS #endif /* GST_VAAPI_SURFACE_H */ From a42754e31eb5b4d0e9a35a8f9bd25f1025a34c9e Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 11 Mar 2010 15:01:00 +0000 Subject: [PATCH 0029/3781] API change: gst_vaapi_display_x11_new() now takes an X11 display name. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 74 ++++++++----- gst-libs/gst/vaapi/gstvaapidisplay.h | 6 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 133 ++++++++++++++++++----- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 2 +- tests/examples/generic/test-display.c | 10 +- 5 files changed, 157 insertions(+), 68 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 8f3f1d643b..f98ba56333 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -37,6 +37,7 @@ G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT); struct _GstVaapiDisplayPrivate { VADisplay display; + gboolean create_display; VAProfile *profiles; unsigned int num_profiles; VAImageFormat *image_formats; @@ -52,9 +53,6 @@ enum { PROP_DISPLAY }; -static void -gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display); - static void filter_formats(VAImageFormat *va_formats, unsigned int *pnum_va_formats) { @@ -146,6 +144,12 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) vaTerminate(priv->display); priv->display = NULL; } + + if (priv->create_display) { + GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); + if (klass->close_display) + klass->close_display(display); + } } static gboolean @@ -156,6 +160,16 @@ gst_vaapi_display_create(GstVaapiDisplay *display) int major_version, minor_version; unsigned int i; + if (!priv->display && priv->create_display) { + GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); + if (klass->open_display && !klass->open_display(display)) + return FALSE; + if (klass->get_display) + priv->display = klass->get_display(display); + } + if (!priv->display) + return FALSE; + status = vaInitialize(priv->display, &major_version, &minor_version); if (!vaapi_check_status(status, "vaInitialize()")) return FALSE; @@ -244,16 +258,17 @@ gst_vaapi_display_finalize(GObject *object) } static void -gst_vaapi_display_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +gst_vaapi_display_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); switch (prop_id) { case PROP_DISPLAY: - gst_vaapi_display_set_display(display, g_value_get_pointer(value)); + display->priv->display = g_value_get_pointer(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -262,10 +277,12 @@ gst_vaapi_display_set_property(GObject *object, } static void -gst_vaapi_display_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +gst_vaapi_display_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) { GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); @@ -279,6 +296,20 @@ gst_vaapi_display_get_property(GObject *object, } } +static void +gst_vaapi_display_constructed(GObject *object) +{ + GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); + GObjectClass *parent_class; + + display->priv->create_display = display->priv->display == NULL; + gst_vaapi_display_create(display); + + parent_class = G_OBJECT_CLASS(gst_vaapi_display_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + static void gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) { @@ -291,6 +322,7 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) object_class->finalize = gst_vaapi_display_finalize; object_class->set_property = gst_vaapi_display_set_property; object_class->get_property = gst_vaapi_display_get_property; + object_class->constructed = gst_vaapi_display_constructed; g_object_class_install_property (object_class, @@ -308,6 +340,7 @@ gst_vaapi_display_init(GstVaapiDisplay *display) display->priv = priv; priv->display = NULL; + priv->create_display = TRUE; priv->profiles = 0; priv->num_profiles = 0; priv->image_formats = NULL; @@ -333,23 +366,6 @@ gst_vaapi_display_get_display(GstVaapiDisplay *display) return display->priv->display; } -void -gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display) -{ - GstVaapiDisplayPrivate * const priv = display->priv; - - if (priv->display) - gst_vaapi_display_destroy(display); - - if (va_display) { - priv->display = va_display; - if (!gst_vaapi_display_create(display)) { - gst_vaapi_display_destroy(display); - return; - } - } -} - gboolean gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index a895aaf8b3..72488ba3cc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -49,7 +49,7 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), \ GST_VAAPI_TYPE_DISPLAY, \ - GstVaapiDisplay)) + GstVaapiDisplayClass)) typedef struct _GstVaapiDisplay GstVaapiDisplay; typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; @@ -65,6 +65,10 @@ struct _GstVaapiDisplay { struct _GstVaapiDisplayClass { /*< private >*/ GObjectClass parent_class; + + gboolean (*open_display) (GstVaapiDisplay *display); + void (*close_display)(GstVaapiDisplay *display); + VADisplay (*get_display) (GstVaapiDisplay *display); }; GType diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 305fadcf39..1f224081d7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -35,12 +35,15 @@ G_DEFINE_TYPE(GstVaapiDisplayX11, GstVaapiDisplayX11Private)) struct _GstVaapiDisplayX11Private { - Display *display; + gchar *display_name; + Display *x11_display; + VADisplay *va_display; }; enum { PROP_0, + PROP_DISPLAY_NAME, PROP_X11_DISPLAY }; @@ -51,16 +54,31 @@ gst_vaapi_display_x11_finalize(GObject *object) } static void -gst_vaapi_display_x11_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name) +{ + GstVaapiDisplayX11Private * const priv = display->priv; + + g_free(priv->display_name); + + if (display_name) + priv->display_name = g_strdup(display_name); + else + priv->display_name = NULL; +} + +static void +gst_vaapi_display_x11_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) { GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); switch (prop_id) { - case PROP_X11_DISPLAY: - display->priv->display = g_value_get_pointer(value); + case PROP_DISPLAY_NAME: + set_display_name(display, g_value_get_string(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -69,14 +87,19 @@ gst_vaapi_display_x11_set_property(GObject *object, } static void -gst_vaapi_display_x11_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +gst_vaapi_display_x11_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) { GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); switch (prop_id) { + case PROP_DISPLAY_NAME: + g_value_set_string(value, display->priv->display_name); + break; case PROP_X11_DISPLAY: g_value_set_pointer(value, gst_vaapi_display_x11_get_display(display)); break; @@ -86,16 +109,61 @@ gst_vaapi_display_x11_get_property(GObject *object, } } +static gboolean +gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) +{ + GstVaapiDisplayX11Private * const priv = + GST_VAAPI_DISPLAY_X11(display)->priv; + + /* XXX: maintain an X11 display cache */ + priv->x11_display = XOpenDisplay(priv->display_name); + if (!priv->x11_display) + return FALSE; + + priv->va_display = vaGetDisplay(priv->x11_display); + return priv->va_display != NULL; +} + +static void +gst_vaapi_display_x11_close_display(GstVaapiDisplay *display) +{ + GstVaapiDisplayX11Private * const priv = + GST_VAAPI_DISPLAY_X11(display)->priv; + + if (priv->x11_display) { + XCloseDisplay(priv->x11_display); + priv->x11_display = NULL; + } + + if (priv->display_name) { + g_free(priv->display_name); + priv->display_name = NULL; + } + + priv->va_display = NULL; +} + +static VADisplay +gst_vaapi_display_x11_get_va_display(GstVaapiDisplay *display) +{ + return GST_VAAPI_DISPLAY_X11(display)->priv->va_display; +} + static void gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); g_type_class_add_private(klass, sizeof(GstVaapiDisplayX11Private)); - object_class->finalize = gst_vaapi_display_x11_finalize; - object_class->set_property = gst_vaapi_display_x11_set_property; - object_class->get_property = gst_vaapi_display_x11_get_property; + object_class->finalize = gst_vaapi_display_x11_finalize; + object_class->set_property = gst_vaapi_display_x11_set_property; + object_class->get_property = gst_vaapi_display_x11_get_property; + + dpy_class->open_display = gst_vaapi_display_x11_open_display; + dpy_class->close_display = gst_vaapi_display_x11_close_display; + dpy_class->get_display = gst_vaapi_display_x11_get_va_display; g_object_class_install_property (object_class, @@ -103,7 +171,16 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) g_param_spec_pointer("x11-display", "X11 display", "X11 display", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, + PROP_DISPLAY_NAME, + g_param_spec_string("display-name", + "X11 display name", + "X11 display name", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -111,8 +188,17 @@ gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) { GstVaapiDisplayX11Private *priv = GST_VAAPI_DISPLAY_X11_GET_PRIVATE(display); - display->priv = priv; - priv->display = NULL; + display->priv = priv; + priv->x11_display = NULL; + priv->display_name = NULL; +} + +GstVaapiDisplay * +gst_vaapi_display_x11_new(const gchar *display_name) +{ + return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, + "display-name", display_name, + NULL); } Display * @@ -120,16 +206,5 @@ gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); - return display->priv->display; -} - -GstVaapiDisplay * -gst_vaapi_display_x11_new(Display *x11_display) -{ - g_return_val_if_fail(x11_display, NULL); - - return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, - "x11-display", x11_display, - "display", vaGetDisplay(x11_display), - NULL); + return display->priv->x11_display; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index bd7b22394d..1881b34ecc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -70,7 +70,7 @@ GType gst_vaapi_display_x11_get_type(void); GstVaapiDisplay * -gst_vaapi_display_x11_new(Display *x11_display); +gst_vaapi_display_x11_new(const gchar *display_name); Display * gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display); diff --git a/tests/examples/generic/test-display.c b/tests/examples/generic/test-display.c index bfe405583b..dbbf1f987f 100644 --- a/tests/examples/generic/test-display.c +++ b/tests/examples/generic/test-display.c @@ -71,17 +71,12 @@ print_caps(GstCaps *caps, const gchar *name) int main(int argc, char *argv[]) { - Display *x11_display; GstVaapiDisplay *display; GstCaps *caps; gst_init(&argc, &argv); - x11_display = XOpenDisplay(NULL); - if (!x11_display) - g_error("could not create X11 display"); - - display = gst_vaapi_display_x11_new(x11_display); + display = gst_vaapi_display_x11_new(NULL); if (!display) g_error("could not create VA-API display"); @@ -99,8 +94,7 @@ main(int argc, char *argv[]) print_caps(caps, "subpicture"); gst_caps_unref(caps); - g_object_unref(G_OBJECT(display)); - XCloseDisplay(x11_display); + g_object_unref(display); gst_deinit(); return 0; } From 0d4b65b7587012cd92a77467fd2544a638173d5a Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 11 Mar 2010 15:04:18 +0000 Subject: [PATCH 0030/3781] Fix *_GET_CLASS() definitions... --- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapiimage.h | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.h | 2 +- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 1881b34ecc..8c660a3912 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -48,7 +48,7 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_X11_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), \ GST_VAAPI_TYPE_DISPLAY_X11, \ - GstVaapiDisplayX11)) + GstVaapiDisplayX11Class)) typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11; typedef struct _GstVaapiDisplayX11Private GstVaapiDisplayX11Private; diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index aa92314115..7d096662c4 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -48,7 +48,7 @@ G_BEGIN_DECLS #define GST_VAAPI_IMAGE_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), \ GST_VAAPI_TYPE_IMAGE, \ - GstVaapiImage)) + GstVaapiImageClass)) typedef struct _GstVaapiImage GstVaapiImage; typedef struct _GstVaapiImagePrivate GstVaapiImagePrivate; diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 763af4e54f..927ba8a94f 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -48,7 +48,7 @@ G_BEGIN_DECLS #define GST_VAAPI_SUBPICTURE_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), \ GST_VAAPI_TYPE_SUBPICTURE, \ - GstVaapiSubpicture)) + GstVaapiSubpictureClass)) typedef struct _GstVaapiSubpicture GstVaapiSubpicture; typedef struct _GstVaapiSubpicturePrivate GstVaapiSubpicturePrivate; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 43c8f59f95..18630974f8 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -55,7 +55,7 @@ enum _GstVaapiChromaType { #define GST_VAAPI_SURFACE_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), \ GST_VAAPI_TYPE_SURFACE, \ - GstVaapiSurface)) + GstVaapiSurfaceClass)) typedef struct _GstVaapiSurface GstVaapiSurface; typedef struct _GstVaapiSurfacePrivate GstVaapiSurfacePrivate; From e4ae48029f479651f97f9cd0300fe4729bbdd993 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 11 Mar 2010 15:21:43 +0000 Subject: [PATCH 0031/3781] Add gst_vaapi_display_x11_new_with_display() API. --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 41 +++++++++++-- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 3 + tests/examples/generic/test-display.c | 75 ++++++++++++++++++++---- 3 files changed, 103 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 1f224081d7..c519dcaf27 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -35,6 +35,7 @@ G_DEFINE_TYPE(GstVaapiDisplayX11, GstVaapiDisplayX11Private)) struct _GstVaapiDisplayX11Private { + gboolean create_display; gchar *display_name; Display *x11_display; VADisplay *va_display; @@ -80,6 +81,9 @@ gst_vaapi_display_x11_set_property( case PROP_DISPLAY_NAME: set_display_name(display, g_value_get_string(value)); break; + case PROP_X11_DISPLAY: + display->priv->x11_display = g_value_get_pointer(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -109,6 +113,19 @@ gst_vaapi_display_x11_get_property( } } +static void +gst_vaapi_display_x11_constructed(GObject *object) +{ + GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); + GObjectClass *parent_class; + + display->priv->create_display = display->priv->x11_display == NULL; + + parent_class = G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + static gboolean gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) { @@ -116,7 +133,8 @@ gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) GST_VAAPI_DISPLAY_X11(display)->priv; /* XXX: maintain an X11 display cache */ - priv->x11_display = XOpenDisplay(priv->display_name); + if (!priv->x11_display && priv->create_display) + priv->x11_display = XOpenDisplay(priv->display_name); if (!priv->x11_display) return FALSE; @@ -131,7 +149,8 @@ gst_vaapi_display_x11_close_display(GstVaapiDisplay *display) GST_VAAPI_DISPLAY_X11(display)->priv; if (priv->x11_display) { - XCloseDisplay(priv->x11_display); + if (priv->create_display) + XCloseDisplay(priv->x11_display); priv->x11_display = NULL; } @@ -160,6 +179,7 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) object_class->finalize = gst_vaapi_display_x11_finalize; object_class->set_property = gst_vaapi_display_x11_set_property; object_class->get_property = gst_vaapi_display_x11_get_property; + object_class->constructed = gst_vaapi_display_x11_constructed; dpy_class->open_display = gst_vaapi_display_x11_open_display; dpy_class->close_display = gst_vaapi_display_x11_close_display; @@ -171,7 +191,7 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) g_param_spec_pointer("x11-display", "X11 display", "X11 display", - G_PARAM_READABLE)); + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, @@ -188,9 +208,10 @@ gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) { GstVaapiDisplayX11Private *priv = GST_VAAPI_DISPLAY_X11_GET_PRIVATE(display); - display->priv = priv; - priv->x11_display = NULL; - priv->display_name = NULL; + display->priv = priv; + priv->create_display = TRUE; + priv->x11_display = NULL; + priv->display_name = NULL; } GstVaapiDisplay * @@ -201,6 +222,14 @@ gst_vaapi_display_x11_new(const gchar *display_name) NULL); } +GstVaapiDisplay * +gst_vaapi_display_x11_new_with_display(Display *x11_display) +{ + return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, + "x11-display", x11_display, + NULL); +} + Display * gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 8c660a3912..baeb15b615 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -72,6 +72,9 @@ gst_vaapi_display_x11_get_type(void); GstVaapiDisplay * gst_vaapi_display_x11_new(const gchar *display_name); +GstVaapiDisplay * +gst_vaapi_display_x11_new_with_display(Display *x11_display); + Display * gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display); diff --git a/tests/examples/generic/test-display.c b/tests/examples/generic/test-display.c index dbbf1f987f..4a510d5371 100644 --- a/tests/examples/generic/test-display.c +++ b/tests/examples/generic/test-display.c @@ -68,18 +68,11 @@ print_caps(GstCaps *caps, const gchar *name) } } -int -main(int argc, char *argv[]) +static void +dump_caps(GstVaapiDisplay *display) { - GstVaapiDisplay *display; GstCaps *caps; - gst_init(&argc, &argv); - - display = gst_vaapi_display_x11_new(NULL); - if (!display) - g_error("could not create VA-API display"); - caps = gst_vaapi_display_get_image_caps(display); if (!caps) g_error("could not get VA image caps"); @@ -93,8 +86,70 @@ main(int argc, char *argv[]) print_caps(caps, "subpicture"); gst_caps_unref(caps); +} + +int +main(int argc, char *argv[]) +{ + Display *x11_display; + VADisplay va_display; + GstVaapiDisplay *display; + + gst_init(&argc, &argv); + + g_print("#\n"); + g_print("# Create display with gst_vaapi_display_x11_new()\n"); + g_print("#\n"); + { + display = gst_vaapi_display_x11_new(NULL); + if (!display) + g_error("could not create Gst/VA display"); + + dump_caps(display); + g_object_unref(display); + } + g_print("\n"); + + g_print("#\n"); + g_print("# Create display with gst_vaapi_display_x11_new_with_display()\n"); + g_print("#\n"); + { + x11_display = XOpenDisplay(NULL); + if (!x11_display) + g_error("could not create X11 display"); + + display = gst_vaapi_display_x11_new_with_display(x11_display); + if (!display) + g_error("could not create Gst/VA display"); + + dump_caps(display); + g_object_unref(display); + XCloseDisplay(x11_display); + } + g_print("\n"); + + g_print("#\n"); + g_print("# Create display with gst_vaapi_display_new_with_display()\n"); + g_print("#\n"); + { + x11_display = XOpenDisplay(NULL); + if (!x11_display) + g_error("could not create X11 display"); + + va_display = vaGetDisplay(x11_display); + if (!va_display) + g_error("could not create VA display"); + + display = gst_vaapi_display_new_with_display(va_display); + if (!display) + g_error("could not create Gst/VA display"); + + dump_caps(display); + g_object_unref(display); + XCloseDisplay(x11_display); + } + g_print("\n"); - g_object_unref(display); gst_deinit(); return 0; } From a0255faa07d7d87828639c174a5ada9fbc89a649 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 11 Mar 2010 15:35:43 +0000 Subject: [PATCH 0032/3781] Reset display-name if the user provided his own X11 display. --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index c519dcaf27..e70e1d866a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -121,6 +121,10 @@ gst_vaapi_display_x11_constructed(GObject *object) display->priv->create_display = display->priv->x11_display == NULL; + /* Reset display-name if the user provided his own X11 display */ + if (!display->priv->create_display) + set_display_name(display, XDisplayString(display->priv->x11_display)); + parent_class = G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class); if (parent_class->constructed) parent_class->constructed(object); From 8e72746f3590bf954091ce23f2acb68e5c0cac3b Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 12 Mar 2010 10:52:08 +0000 Subject: [PATCH 0033/3781] Avoid use of GstStaticCaps since older gstreamer versions (0.10.22) write to it. --- gst-libs/gst/vaapi/gstvaapiimageformat.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 370633f6b7..6679d87bda 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -35,14 +35,14 @@ enum _GstVaapiImageFormatType { struct _GstVaapiImageFormatMap { GstVaapiImageFormatType type; GstVaapiImageFormat format; - GstStaticCaps caps; + const char *caps_str; VAImageFormat va_format; }; #define DEF(TYPE, FORMAT, CAPS_STR) \ GST_VAAPI_IMAGE_FORMAT_TYPE_##TYPE, \ GST_VAAPI_IMAGE_##FORMAT, \ - GST_STATIC_CAPS(CAPS_STR) + CAPS_STR #define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP) \ { DEF(YCBCR, FORMAT, GST_VIDEO_CAPS_YUV(#FORMAT)), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } @@ -157,18 +157,13 @@ gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format) GstCaps * gst_vaapi_image_format_get_caps(GstVaapiImageFormat format) { - GstCaps *caps; const GstVaapiImageFormatMap *m; m = get_map_from_gst_vaapi_image_format(format); if (!m) return NULL; - caps = gst_static_caps_get(&m->caps); - if (!caps) - return NULL; - - return gst_caps_make_writable(caps); + return gst_caps_from_string(m->caps_str); } guint From 5fa32d3cf45893e881a744252b8c3478d5164fc3 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 12 Mar 2010 17:39:11 +0000 Subject: [PATCH 0034/3781] Add gst_vaapi_surface_get_size() helper. --- gst-libs/gst/vaapi/gstvaapisurface.c | 17 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 7 +++++++ 2 files changed, 24 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index b15d05ac8c..dc414957db 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -319,3 +319,20 @@ gst_vaapi_surface_get_height(GstVaapiSurface *surface) return surface->priv->height; } + +void +gst_vaapi_surface_get_size( + GstVaapiSurface *surface, + guint *pwidth, + guint *pheight +) +{ + g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); + + if (pwidth) + *pwidth = gst_vaapi_surface_get_width(surface); + + if (pheight) + *pheight = gst_vaapi_surface_get_height(surface); +} + diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 18630974f8..3e859a33c9 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -99,6 +99,13 @@ gst_vaapi_surface_get_width(GstVaapiSurface *surface); guint gst_vaapi_surface_get_height(GstVaapiSurface *surface); +void +gst_vaapi_surface_get_size( + GstVaapiSurface *surface, + guint *pwidth, + guint *pheight +); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_H */ From d1f3c3e6b007eb605a4738533d15fc56c83bec67 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 12 Mar 2010 17:45:18 +0000 Subject: [PATCH 0035/3781] Add VA surface pool (lazy allocator). --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapisurfacepool.c | 277 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurfacepool.h | 93 ++++++++ 3 files changed, 372 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapisurfacepool.c create mode 100644 gst-libs/gst/vaapi/gstvaapisurfacepool.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index bf7cd1666c..c8385a2f5a 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -7,6 +7,7 @@ libgstvaapi_source_c = \ gstvaapisinkbase.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ + gstvaapisurfacepool.c \ vaapi_utils.c \ $(NULL) @@ -17,6 +18,7 @@ libgstvaapi_source_h = \ gstvaapisinkbase.h \ gstvaapisubpicture.h \ gstvaapisurface.h \ + gstvaapisurfacepool.h \ vaapi_debug.h \ vaapi_utils.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c new file mode 100644 index 0000000000..e389f4ba8a --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -0,0 +1,277 @@ +/* + * gstvaapisurfacepool.c - Gst VA surface pool + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "gstvaapisurfacepool.h" + +#define DEBUG 1 +#include "vaapi_debug.h" + +G_DEFINE_TYPE(GstVaapiSurfacePool, gst_vaapi_surface_pool, G_TYPE_OBJECT); + +#define GST_VAAPI_SURFACE_POOL_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_SURFACE_POOL, \ + GstVaapiSurfacePoolPrivate)) + +struct _GstVaapiSurfacePoolPrivate { + GstVaapiDisplay *display; + GQueue free_surfaces; + GList *used_surfaces; + GstCaps *caps; + GstVaapiChromaType chroma_type; + guint width; + guint height; +}; + +enum { + PROP_0, + + PROP_DISPLAY, + PROP_CAPS, +}; + +static void +gst_vaapi_surface_pool_clear(GstVaapiSurfacePool *pool) +{ + GstVaapiSurfacePoolPrivate * const priv = pool->priv; + GstVaapiSurface *surface; + GList *list, *next; + + for (list = priv->used_surfaces; list; list = next) { + next = list->next; + g_object_unref(list->data); + g_list_free_1(list); + } + priv->used_surfaces = NULL; + + while ((surface = g_queue_pop_head(&priv->free_surfaces))) + g_object_unref(surface); +} + +static void +gst_vaapi_surface_pool_destroy(GstVaapiSurfacePool *pool) +{ + GstVaapiSurfacePoolPrivate * const priv = pool->priv; + + gst_vaapi_surface_pool_clear(pool); + + if (priv->caps) { + gst_caps_unref(priv->caps); + priv->caps = NULL; + } + + if (priv->display) { + g_object_unref(priv->display); + priv->display = NULL; + } +} + +static void +gst_vaapi_surface_pool_finalize(GObject *object) +{ + gst_vaapi_surface_pool_destroy(GST_VAAPI_SURFACE_POOL(object)); + + G_OBJECT_CLASS(gst_vaapi_surface_pool_parent_class)->finalize(object); +} + +static void +gst_vaapi_surface_pool_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(object); + + switch (prop_id) { + case PROP_DISPLAY: + pool->priv->display = g_object_ref(g_value_get_object(value)); + break; + case PROP_CAPS: + gst_vaapi_surface_pool_set_caps(pool, g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_surface_pool_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(object); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_object(value, pool->priv->display); + break; + case PROP_CAPS: + g_value_set_pointer(value, gst_vaapi_surface_pool_get_caps(pool)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_surface_pool_class_init(GstVaapiSurfacePoolClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiSurfacePoolPrivate)); + + object_class->finalize = gst_vaapi_surface_pool_finalize; + object_class->set_property = gst_vaapi_surface_pool_set_property; + object_class->get_property = gst_vaapi_surface_pool_get_property; + + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_object("display", + "display", + "Gstreamer/VA display", + GST_VAAPI_TYPE_DISPLAY, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_CAPS, + g_param_spec_pointer("caps", + "surface caps", + "Surface caps", + G_PARAM_READWRITE)); +} + +static void +gst_vaapi_surface_pool_init(GstVaapiSurfacePool *pool) +{ + GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL_GET_PRIVATE(pool); + + pool->priv = priv; + priv->display = NULL; + priv->used_surfaces = NULL; + priv->caps = NULL; + priv->chroma_type = 0; + priv->width = 0; + priv->height = 0; + + g_queue_init(&priv->free_surfaces); +} + +GstVaapiSurfacePool * +gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps) +{ + return g_object_new(GST_VAAPI_TYPE_SURFACE_POOL, + "display", display, + "caps", caps, + NULL); +} + +GstCaps * +gst_vaapi_surface_pool_get_caps(GstVaapiSurfacePool *pool) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), NULL); + + return pool->priv->caps; +} + +void +gst_vaapi_surface_pool_set_caps(GstVaapiSurfacePool *pool, GstCaps *caps) +{ + GstVaapiSurfacePoolPrivate *priv; + GstStructure *structure; + gint width, height; + + g_return_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool)); + g_return_if_fail(GST_IS_CAPS(caps)); + + priv = pool->priv; + + structure = gst_caps_get_structure(caps, 0); + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + + /* Don't do anything if caps have not changed */ + if (width == priv->width && height == priv->height) + return; + + gst_vaapi_surface_pool_clear(pool); + + priv->caps = gst_caps_ref(caps); + priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + priv->width = width; + priv->height = height; +} + +GstVaapiSurface * +gst_vaapi_surface_pool_new_surface(GstVaapiSurfacePool *pool) +{ + GstVaapiSurfacePoolPrivate *priv; + GstVaapiSurface *surface; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), NULL); + + priv = pool->priv; + + surface = g_queue_pop_head(&priv->free_surfaces); + if (!surface) { + surface = gst_vaapi_surface_new( + priv->display, + priv->chroma_type, + priv->width, + priv->height + ); + if (!surface) + return NULL; + } + + priv->used_surfaces = g_list_prepend(priv->used_surfaces, surface); + return g_object_ref(surface); +} + +void +gst_vaapi_surface_pool_free_surface( + GstVaapiSurfacePool *pool, + GstVaapiSurface *surface +) +{ + GstVaapiSurfacePoolPrivate *priv; + GList *list; + + g_return_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool)); + g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); + + priv = pool->priv; + list = g_list_find(priv->used_surfaces, surface); + if (!list) + return; + + g_object_unref(surface); + priv->used_surfaces = g_list_delete_link(priv->used_surfaces, list); + g_queue_push_tail(&priv->free_surfaces, surface); +} diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h new file mode 100644 index 0000000000..4777e294bd --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -0,0 +1,93 @@ +/* + * gstvaapisurfacepool.h - Gst VA surface pool + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_SURFACE_POOL_H +#define GST_VAAPI_SURFACE_POOL_H + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_SURFACE_POOL \ + (gst_vaapi_surface_pool_get_type()) + +#define GST_VAAPI_SURFACE_POOL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_SURFACE_POOL, \ + GstVaapiSurfacePool)) + +#define GST_VAAPI_SURFACE_POOL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_SURFACE_POOL, \ + GstVaapiSurfacePoolClass)) + +#define GST_VAAPI_IS_SURFACE_POOL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SURFACE_POOL)) + +#define GST_VAAPI_IS_SURFACE_POOL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SURFACE_POOL)) + +#define GST_VAAPI_SURFACE_POOL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_SURFACE_POOL, \ + GstVaapiSurfacePoolClass)) + +typedef struct _GstVaapiSurfacePool GstVaapiSurfacePool; +typedef struct _GstVaapiSurfacePoolPrivate GstVaapiSurfacePoolPrivate; +typedef struct _GstVaapiSurfacePoolClass GstVaapiSurfacePoolClass; + +struct _GstVaapiSurfacePool { + /*< private >*/ + GObject parent_instance; + + GstVaapiSurfacePoolPrivate *priv; +}; + +struct _GstVaapiSurfacePoolClass { + /*< private >*/ + GObjectClass parent_class; +}; + +GType +gst_vaapi_surface_pool_get_type(void); + +GstVaapiSurfacePool * +gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps); + +GstCaps * +gst_vaapi_surface_pool_get_caps(GstVaapiSurfacePool *pool); + +void +gst_vaapi_surface_pool_set_caps(GstVaapiSurfacePool *pool, GstCaps *caps); + +GstVaapiSurface * +gst_vaapi_surface_pool_new_surface(GstVaapiSurfacePool *pool); + +void +gst_vaapi_surface_pool_free_surface( + GstVaapiSurfacePool *pool, + GstVaapiSurface *surface +); + +G_END_DECLS + +#endif /* GST_VAAPI_SURFACE_POOL_H */ From d5253e6e2cc965b7b59a272c490d1c6143951636 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 12 Mar 2010 22:28:01 +0000 Subject: [PATCH 0036/3781] Add gst_vaapi_image_format_from_caps() helper. --- gst-libs/gst/vaapi/gstvaapiimageformat.c | 65 ++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiimageformat.h | 3 ++ 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 6679d87bda..4665493404 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -73,6 +73,16 @@ static const GstVaapiImageFormatMap gst_vaapi_image_formats[] = { #undef DEF_YUV #undef DEF +static inline gboolean +match_va_format_rgb(const VAImageFormat *fmt1, const VAImageFormat *fmt2) +{ + return (fmt1->byte_order == fmt2->byte_order && + fmt1->red_mask == fmt2->red_mask && + fmt1->green_mask == fmt2->green_mask && + fmt1->blue_mask == fmt2->blue_mask && + fmt1->alpha_mask == fmt2->alpha_mask); +} + static const GstVaapiImageFormatMap *get_map(const VAImageFormat *va_format) { const GstVaapiImageFormatMap *m; @@ -80,11 +90,7 @@ static const GstVaapiImageFormatMap *get_map(const VAImageFormat *va_format) for (m = gst_vaapi_image_formats; m->format; m++) if (m->va_format.fourcc == va_format->fourcc && (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB ? - (m->va_format.byte_order == va_format->byte_order && - m->va_format.red_mask == va_format->red_mask && - m->va_format.green_mask == va_format->green_mask && - m->va_format.blue_mask == va_format->blue_mask && - m->va_format.alpha_mask == va_format->alpha_mask) : + match_va_format_rgb(&m->va_format, va_format) : TRUE)) return m; return NULL; @@ -136,6 +142,55 @@ gst_vaapi_image_format(const VAImageFormat *va_format) return m->format; } +GstVaapiImageFormat +gst_vaapi_image_format_from_caps(GstCaps *caps) +{ + const GstVaapiImageFormatMap *m; + GstStructure *structure; + VAImageFormat *va_format, va_formats[2]; + gint endian, rmask, gmask, bmask, amask = 0; + guint32 fourcc; + + if (!caps) + return 0; + + structure = gst_caps_get_structure(caps, 0); + if (!structure) + return 0; + + /* Check for YUV format */ + if (gst_structure_get_fourcc(structure, "format", &fourcc)) + return gst_vaapi_image_format_from_fourcc(fourcc); + + /* Check for RGB format */ + gst_structure_get_int(structure, "endianness", &endian); + gst_structure_get_int(structure, "red_mask", &rmask); + gst_structure_get_int(structure, "green_mask", &gmask); + gst_structure_get_int(structure, "blue_mask", &bmask); + gst_structure_get_int(structure, "alpha_mask", &amask); + + va_format = &va_formats[0]; + va_format->byte_order = endian == G_BIG_ENDIAN ? VA_MSB_FIRST : VA_LSB_FIRST; + va_format->red_mask = rmask; + va_format->green_mask = gmask; + va_format->blue_mask = bmask; + va_format->alpha_mask = amask; + + va_format = &va_formats[1]; + va_format->byte_order = endian == G_BIG_ENDIAN ? VA_LSB_FIRST : VA_MSB_FIRST; + va_format->red_mask = GUINT32_SWAP_LE_BE(rmask); + va_format->green_mask = GUINT32_SWAP_LE_BE(gmask); + va_format->blue_mask = GUINT32_SWAP_LE_BE(bmask); + va_format->alpha_mask = GUINT32_SWAP_LE_BE(amask); + + for (m = gst_vaapi_image_formats; m->format; m++) + if (match_va_format_rgb(&m->va_format, &va_formats[0]) || + match_va_format_rgb(&m->va_format, &va_formats[1])) + return m->format; + + return 0; +} + GstVaapiImageFormat gst_vaapi_image_format_from_fourcc(guint32 fourcc) { diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index 98b1d2c91d..2037002f63 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -54,6 +54,9 @@ gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format); GstVaapiImageFormat gst_vaapi_image_format(const VAImageFormat *va_format); +GstVaapiImageFormat +gst_vaapi_image_format_from_caps(GstCaps *caps); + GstVaapiImageFormat gst_vaapi_image_format_from_fourcc(guint32 fourcc); From 56827ae5b62cad497cf242a80ca16430e2ad0d08 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 12 Mar 2010 22:32:35 +0000 Subject: [PATCH 0037/3781] Simplify format conversion code. --- gst-libs/gst/vaapi/gstvaapiimageformat.c | 67 +++++++----------------- 1 file changed, 19 insertions(+), 48 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 4665493404..24829d7d09 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -83,21 +83,8 @@ match_va_format_rgb(const VAImageFormat *fmt1, const VAImageFormat *fmt2) fmt1->alpha_mask == fmt2->alpha_mask); } -static const GstVaapiImageFormatMap *get_map(const VAImageFormat *va_format) -{ - const GstVaapiImageFormatMap *m; - - for (m = gst_vaapi_image_formats; m->format; m++) - if (m->va_format.fourcc == va_format->fourcc && - (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB ? - match_va_format_rgb(&m->va_format, va_format) : - TRUE)) - return m; - return NULL; -} - static const GstVaapiImageFormatMap * -get_map_from_gst_vaapi_image_format(GstVaapiImageFormat format) +get_map(GstVaapiImageFormat format) { const GstVaapiImageFormatMap *m; @@ -110,36 +97,32 @@ get_map_from_gst_vaapi_image_format(GstVaapiImageFormat format) gboolean gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format) { - const GstVaapiImageFormatMap *m; + const GstVaapiImageFormatMap * const m = get_map(format); - m = get_map_from_gst_vaapi_image_format(format); - if (!m) - return FALSE; - - return m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB; + return m ? (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB) : FALSE; } gboolean gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format) { - const GstVaapiImageFormatMap *m; + const GstVaapiImageFormatMap * const m = get_map(format); - m = get_map_from_gst_vaapi_image_format(format); - if (!m) - return FALSE; - - return m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR; + return m ? (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR) : FALSE; } GstVaapiImageFormat gst_vaapi_image_format(const VAImageFormat *va_format) { - const GstVaapiImageFormatMap * const m = get_map(va_format); + const GstVaapiImageFormatMap *m; - if (!m) - return 0; + for (m = gst_vaapi_image_formats; m->format; m++) + if (m->va_format.fourcc == va_format->fourcc && + (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB ? + match_va_format_rgb(&m->va_format, va_format) : + TRUE)) + return m->format; - return m->format; + return 0; } GstVaapiImageFormat @@ -200,35 +183,23 @@ gst_vaapi_image_format_from_fourcc(guint32 fourcc) const VAImageFormat * gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format) { - const GstVaapiImageFormatMap *m; + const GstVaapiImageFormatMap * const m = get_map(format); - m = get_map_from_gst_vaapi_image_format(format); - if (!m) - return NULL; - - return &m->va_format; + return m ? &m->va_format : NULL; } GstCaps * gst_vaapi_image_format_get_caps(GstVaapiImageFormat format) { - const GstVaapiImageFormatMap *m; + const GstVaapiImageFormatMap * const m = get_map(format); - m = get_map_from_gst_vaapi_image_format(format); - if (!m) - return NULL; - - return gst_caps_from_string(m->caps_str); + return m ? gst_caps_from_string(m->caps_str) : NULL; } guint gst_vaapi_image_format_get_score(GstVaapiImageFormat format) { - const GstVaapiImageFormatMap *m; + const GstVaapiImageFormatMap * const m = get_map(format); - m = get_map_from_gst_vaapi_image_format(format); - if (!m) - return G_MAXUINT; - - return m - &gst_vaapi_image_formats[0]; + return m ? (m - &gst_vaapi_image_formats[0]) : G_MAXUINT; } From 809933a46ba7354824bb2a82cdb8e431217e201c Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 12 Mar 2010 23:47:47 +0000 Subject: [PATCH 0038/3781] Add GstVaapiImagePool and factor out GstVaapiSurfacePool from a base GstVaapiVideoPool. --- gst-libs/gst/vaapi/Makefile.am | 4 + gst-libs/gst/vaapi/gstvaapiimagepool.c | 111 ++++++++++ gst-libs/gst/vaapi/gstvaapiimagepool.h | 77 +++++++ gst-libs/gst/vaapi/gstvaapisurfacepool.c | 222 +++----------------- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 30 +-- gst-libs/gst/vaapi/gstvaapivideopool.c | 249 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivideopool.h | 86 ++++++++ 7 files changed, 562 insertions(+), 217 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiimagepool.c create mode 100644 gst-libs/gst/vaapi/gstvaapiimagepool.h create mode 100644 gst-libs/gst/vaapi/gstvaapivideopool.c create mode 100644 gst-libs/gst/vaapi/gstvaapivideopool.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index c8385a2f5a..d6333d1212 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -4,10 +4,12 @@ libgstvaapi_source_c = \ gstvaapidisplay.c \ gstvaapiimage.c \ gstvaapiimageformat.c \ + gstvaapiimagepool.c \ gstvaapisinkbase.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ gstvaapisurfacepool.c \ + gstvaapivideopool.c \ vaapi_utils.c \ $(NULL) @@ -15,10 +17,12 @@ libgstvaapi_source_h = \ gstvaapidisplay.h \ gstvaapiimage.h \ gstvaapiimageformat.h \ + gstvaapiimagepool.h \ gstvaapisinkbase.h \ gstvaapisubpicture.h \ gstvaapisurface.h \ gstvaapisurfacepool.h \ + gstvaapivideopool.h \ vaapi_debug.h \ vaapi_utils.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c new file mode 100644 index 0000000000..9d7170d80e --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -0,0 +1,111 @@ +/* + * gstvaapiimagepool.c - Gst VA image pool + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "gstvaapiimagepool.h" + +#define DEBUG 1 +#include "vaapi_debug.h" + +G_DEFINE_TYPE( + GstVaapiImagePool, + gst_vaapi_image_pool, + GST_VAAPI_TYPE_VIDEO_POOL); + +#define GST_VAAPI_IMAGE_POOL_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_IMAGE_POOL, \ + GstVaapiImagePoolPrivate)) + +struct _GstVaapiImagePoolPrivate { + GstVaapiImageFormat format; + guint width; + guint height; +}; + +static void +gst_vaapi_image_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) +{ + GstVaapiImagePoolPrivate * const priv = GST_VAAPI_IMAGE_POOL(pool)->priv; + GstStructure *structure; + gint width, height; + + structure = gst_caps_get_structure(caps, 0); + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + + priv->format = gst_vaapi_image_format_from_caps(caps); + priv->width = width; + priv->height = height; +} + +gpointer +gst_vaapi_image_pool_alloc_object( + GstVaapiVideoPool *pool, + GstVaapiDisplay *display +) +{ + GstVaapiImagePoolPrivate * const priv = GST_VAAPI_IMAGE_POOL(pool)->priv; + + return gst_vaapi_image_new(display, + priv->format, + priv->width, + priv->height); +} + +static void +gst_vaapi_image_pool_finalize(GObject *object) +{ + G_OBJECT_CLASS(gst_vaapi_image_pool_parent_class)->finalize(object); +} + +static void +gst_vaapi_image_pool_class_init(GstVaapiImagePoolClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiVideoPoolClass * const pool_class = GST_VAAPI_VIDEO_POOL_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiImagePoolPrivate)); + + object_class->finalize = gst_vaapi_image_pool_finalize; + + pool_class->set_caps = gst_vaapi_image_pool_set_caps; + pool_class->alloc_object = gst_vaapi_image_pool_alloc_object; +} + +static void +gst_vaapi_image_pool_init(GstVaapiImagePool *pool) +{ + GstVaapiImagePoolPrivate *priv = GST_VAAPI_IMAGE_POOL_GET_PRIVATE(pool); + + pool->priv = priv; + priv->format = 0; + priv->width = 0; + priv->height = 0; +} + +GstVaapiVideoPool * +gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps) +{ + return g_object_new(GST_VAAPI_TYPE_IMAGE_POOL, + "display", display, + "caps", caps, + NULL); +} diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h new file mode 100644 index 0000000000..67d0086f15 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -0,0 +1,77 @@ +/* + * gstvaapiimagepool.h - Gst VA image pool + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_IMAGE_POOL_H +#define GST_VAAPI_IMAGE_POOL_H + +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_IMAGE_POOL \ + (gst_vaapi_image_pool_get_type()) + +#define GST_VAAPI_IMAGE_POOL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_IMAGE_POOL, \ + GstVaapiImagePool)) + +#define GST_VAAPI_IMAGE_POOL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_IMAGE_POOL, \ + GstVaapiImagePoolClass)) + +#define GST_VAAPI_IS_IMAGE_POOL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_IMAGE_POOL)) + +#define GST_VAAPI_IS_IMAGE_POOL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_IMAGE_POOL)) + +#define GST_VAAPI_IMAGE_POOL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_IMAGE_POOL, \ + GstVaapiImagePoolClass)) + +typedef struct _GstVaapiImagePool GstVaapiImagePool; +typedef struct _GstVaapiImagePoolPrivate GstVaapiImagePoolPrivate; +typedef struct _GstVaapiImagePoolClass GstVaapiImagePoolClass; + +struct _GstVaapiImagePool { + /*< private >*/ + GstVaapiVideoPool parent_instance; + + GstVaapiImagePoolPrivate *priv; +}; + +struct _GstVaapiImagePoolClass { + /*< private >*/ + GstVaapiVideoPoolClass parent_class; +}; + +GType +gst_vaapi_image_pool_get_type(void); + +GstVaapiVideoPool * +gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps); + +G_END_DECLS + +#endif /* GST_VAAPI_IMAGE_POOL_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index e389f4ba8a..0c9ee5b67c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -24,7 +24,10 @@ #define DEBUG 1 #include "vaapi_debug.h" -G_DEFINE_TYPE(GstVaapiSurfacePool, gst_vaapi_surface_pool, G_TYPE_OBJECT); +G_DEFINE_TYPE( + GstVaapiSurfacePool, + gst_vaapi_surface_pool, + GST_VAAPI_TYPE_VIDEO_POOL); #define GST_VAAPI_SURFACE_POOL_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ @@ -32,139 +35,59 @@ G_DEFINE_TYPE(GstVaapiSurfacePool, gst_vaapi_surface_pool, G_TYPE_OBJECT); GstVaapiSurfacePoolPrivate)) struct _GstVaapiSurfacePoolPrivate { - GstVaapiDisplay *display; - GQueue free_surfaces; - GList *used_surfaces; - GstCaps *caps; GstVaapiChromaType chroma_type; guint width; guint height; }; -enum { - PROP_0, - - PROP_DISPLAY, - PROP_CAPS, -}; - static void -gst_vaapi_surface_pool_clear(GstVaapiSurfacePool *pool) +gst_vaapi_surface_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) { - GstVaapiSurfacePoolPrivate * const priv = pool->priv; - GstVaapiSurface *surface; - GList *list, *next; + GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL(pool)->priv; + GstStructure *structure; + gint width, height; - for (list = priv->used_surfaces; list; list = next) { - next = list->next; - g_object_unref(list->data); - g_list_free_1(list); - } - priv->used_surfaces = NULL; + structure = gst_caps_get_structure(caps, 0); + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); - while ((surface = g_queue_pop_head(&priv->free_surfaces))) - g_object_unref(surface); + priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + priv->width = width; + priv->height = height; } -static void -gst_vaapi_surface_pool_destroy(GstVaapiSurfacePool *pool) +gpointer +gst_vaapi_surface_pool_alloc_object( + GstVaapiVideoPool *pool, + GstVaapiDisplay *display +) { - GstVaapiSurfacePoolPrivate * const priv = pool->priv; + GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL(pool)->priv; - gst_vaapi_surface_pool_clear(pool); - - if (priv->caps) { - gst_caps_unref(priv->caps); - priv->caps = NULL; - } - - if (priv->display) { - g_object_unref(priv->display); - priv->display = NULL; - } + return gst_vaapi_surface_new(display, + priv->chroma_type, + priv->width, + priv->height); } static void gst_vaapi_surface_pool_finalize(GObject *object) { - gst_vaapi_surface_pool_destroy(GST_VAAPI_SURFACE_POOL(object)); - G_OBJECT_CLASS(gst_vaapi_surface_pool_parent_class)->finalize(object); } -static void -gst_vaapi_surface_pool_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(object); - - switch (prop_id) { - case PROP_DISPLAY: - pool->priv->display = g_object_ref(g_value_get_object(value)); - break; - case PROP_CAPS: - gst_vaapi_surface_pool_set_caps(pool, g_value_get_pointer(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_surface_pool_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(object); - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_object(value, pool->priv->display); - break; - case PROP_CAPS: - g_value_set_pointer(value, gst_vaapi_surface_pool_get_caps(pool)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - static void gst_vaapi_surface_pool_class_init(GstVaapiSurfacePoolClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiVideoPoolClass * const pool_class = GST_VAAPI_VIDEO_POOL_CLASS(klass); g_type_class_add_private(klass, sizeof(GstVaapiSurfacePoolPrivate)); object_class->finalize = gst_vaapi_surface_pool_finalize; - object_class->set_property = gst_vaapi_surface_pool_set_property; - object_class->get_property = gst_vaapi_surface_pool_get_property; - g_object_class_install_property - (object_class, - PROP_DISPLAY, - g_param_spec_object("display", - "display", - "Gstreamer/VA display", - GST_VAAPI_TYPE_DISPLAY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_CAPS, - g_param_spec_pointer("caps", - "surface caps", - "Surface caps", - G_PARAM_READWRITE)); + pool_class->set_caps = gst_vaapi_surface_pool_set_caps; + pool_class->alloc_object = gst_vaapi_surface_pool_alloc_object; } static void @@ -173,17 +96,12 @@ gst_vaapi_surface_pool_init(GstVaapiSurfacePool *pool) GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL_GET_PRIVATE(pool); pool->priv = priv; - priv->display = NULL; - priv->used_surfaces = NULL; - priv->caps = NULL; priv->chroma_type = 0; priv->width = 0; priv->height = 0; - - g_queue_init(&priv->free_surfaces); } -GstVaapiSurfacePool * +GstVaapiVideoPool * gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps) { return g_object_new(GST_VAAPI_TYPE_SURFACE_POOL, @@ -191,87 +109,3 @@ gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps) "caps", caps, NULL); } - -GstCaps * -gst_vaapi_surface_pool_get_caps(GstVaapiSurfacePool *pool) -{ - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), NULL); - - return pool->priv->caps; -} - -void -gst_vaapi_surface_pool_set_caps(GstVaapiSurfacePool *pool, GstCaps *caps) -{ - GstVaapiSurfacePoolPrivate *priv; - GstStructure *structure; - gint width, height; - - g_return_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool)); - g_return_if_fail(GST_IS_CAPS(caps)); - - priv = pool->priv; - - structure = gst_caps_get_structure(caps, 0); - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); - - /* Don't do anything if caps have not changed */ - if (width == priv->width && height == priv->height) - return; - - gst_vaapi_surface_pool_clear(pool); - - priv->caps = gst_caps_ref(caps); - priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - priv->width = width; - priv->height = height; -} - -GstVaapiSurface * -gst_vaapi_surface_pool_new_surface(GstVaapiSurfacePool *pool) -{ - GstVaapiSurfacePoolPrivate *priv; - GstVaapiSurface *surface; - - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), NULL); - - priv = pool->priv; - - surface = g_queue_pop_head(&priv->free_surfaces); - if (!surface) { - surface = gst_vaapi_surface_new( - priv->display, - priv->chroma_type, - priv->width, - priv->height - ); - if (!surface) - return NULL; - } - - priv->used_surfaces = g_list_prepend(priv->used_surfaces, surface); - return g_object_ref(surface); -} - -void -gst_vaapi_surface_pool_free_surface( - GstVaapiSurfacePool *pool, - GstVaapiSurface *surface -) -{ - GstVaapiSurfacePoolPrivate *priv; - GList *list; - - g_return_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool)); - g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); - - priv = pool->priv; - list = g_list_find(priv->used_surfaces, surface); - if (!list) - return; - - g_object_unref(surface); - priv->used_surfaces = g_list_delete_link(priv->used_surfaces, list); - g_queue_push_tail(&priv->free_surfaces, surface); -} diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 4777e294bd..16b2bc1729 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -21,9 +21,8 @@ #ifndef GST_VAAPI_SURFACE_POOL_H #define GST_VAAPI_SURFACE_POOL_H -#include -#include #include +#include G_BEGIN_DECLS @@ -51,43 +50,28 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_SURFACE_POOL, \ GstVaapiSurfacePoolClass)) -typedef struct _GstVaapiSurfacePool GstVaapiSurfacePool; -typedef struct _GstVaapiSurfacePoolPrivate GstVaapiSurfacePoolPrivate; -typedef struct _GstVaapiSurfacePoolClass GstVaapiSurfacePoolClass; +typedef struct _GstVaapiSurfacePool GstVaapiSurfacePool; +typedef struct _GstVaapiSurfacePoolPrivate GstVaapiSurfacePoolPrivate; +typedef struct _GstVaapiSurfacePoolClass GstVaapiSurfacePoolClass; struct _GstVaapiSurfacePool { /*< private >*/ - GObject parent_instance; + GstVaapiVideoPool parent_instance; GstVaapiSurfacePoolPrivate *priv; }; struct _GstVaapiSurfacePoolClass { /*< private >*/ - GObjectClass parent_class; + GstVaapiVideoPoolClass parent_class; }; GType gst_vaapi_surface_pool_get_type(void); -GstVaapiSurfacePool * +GstVaapiVideoPool * gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps); -GstCaps * -gst_vaapi_surface_pool_get_caps(GstVaapiSurfacePool *pool); - -void -gst_vaapi_surface_pool_set_caps(GstVaapiSurfacePool *pool, GstCaps *caps); - -GstVaapiSurface * -gst_vaapi_surface_pool_new_surface(GstVaapiSurfacePool *pool); - -void -gst_vaapi_surface_pool_free_surface( - GstVaapiSurfacePool *pool, - GstVaapiSurface *surface -); - G_END_DECLS #endif /* GST_VAAPI_SURFACE_POOL_H */ diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c new file mode 100644 index 0000000000..bf8d41acec --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -0,0 +1,249 @@ +/* + * gstvaapivideopool.c - Video object pool abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "gstvaapivideopool.h" + +#define DEBUG 1 +#include "vaapi_debug.h" + +G_DEFINE_TYPE(GstVaapiVideoPool, gst_vaapi_video_pool, G_TYPE_OBJECT); + +#define GST_VAAPI_VIDEO_POOL_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_VIDEO_POOL, \ + GstVaapiVideoPoolPrivate)) + +struct _GstVaapiVideoPoolPrivate { + GstVaapiDisplay *display; + GQueue free_objects; + GList *used_objects; + GstCaps *caps; +}; + +enum { + PROP_0, + + PROP_DISPLAY, + PROP_CAPS, +}; + +static void +gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps); + +static void +gst_vaapi_video_pool_clear(GstVaapiVideoPool *pool) +{ + GstVaapiVideoPoolPrivate * const priv = pool->priv; + gpointer object; + GList *list, *next; + + for (list = priv->used_objects; list; list = next) { + next = list->next; + g_object_unref(list->data); + g_list_free_1(list); + } + priv->used_objects = NULL; + + while ((object = g_queue_pop_head(&priv->free_objects))) + g_object_unref(object); +} + +static void +gst_vaapi_video_pool_destroy(GstVaapiVideoPool *pool) +{ + GstVaapiVideoPoolPrivate * const priv = pool->priv; + + gst_vaapi_video_pool_clear(pool); + + if (priv->caps) { + gst_caps_unref(priv->caps); + priv->caps = NULL; + } + + if (priv->display) { + g_object_unref(priv->display); + priv->display = NULL; + } +} + +static void +gst_vaapi_video_pool_finalize(GObject *object) +{ + gst_vaapi_video_pool_destroy(GST_VAAPI_VIDEO_POOL(object)); + + G_OBJECT_CLASS(gst_vaapi_video_pool_parent_class)->finalize(object); +} + +static void +gst_vaapi_video_pool_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiVideoPool * const pool = GST_VAAPI_VIDEO_POOL(object); + + switch (prop_id) { + case PROP_DISPLAY: + pool->priv->display = g_object_ref(g_value_get_object(value)); + break; + case PROP_CAPS: + gst_vaapi_video_pool_set_caps(pool, g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_video_pool_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiVideoPool * const pool = GST_VAAPI_VIDEO_POOL(object); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_object(value, pool->priv->display); + break; + case PROP_CAPS: + g_value_set_pointer(value, gst_vaapi_video_pool_get_caps(pool)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_video_pool_class_init(GstVaapiVideoPoolClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiVideoPoolPrivate)); + + object_class->finalize = gst_vaapi_video_pool_finalize; + object_class->set_property = gst_vaapi_video_pool_set_property; + object_class->get_property = gst_vaapi_video_pool_get_property; + + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_object("display", + "display", + "Gstreamer/VA display", + GST_VAAPI_TYPE_DISPLAY, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_CAPS, + g_param_spec_pointer("caps", + "caps", + "Caps", + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_video_pool_init(GstVaapiVideoPool *pool) +{ + GstVaapiVideoPoolPrivate *priv = GST_VAAPI_VIDEO_POOL_GET_PRIVATE(pool); + + pool->priv = priv; + priv->display = NULL; + priv->used_objects = NULL; + priv->caps = NULL; + + g_queue_init(&priv->free_objects); +} + +GstVaapiVideoPool * +gst_vaapi_video_pool_new(GstVaapiDisplay *display, GstCaps *caps) +{ + return g_object_new(GST_VAAPI_TYPE_VIDEO_POOL, + "display", display, + "caps", caps, + NULL); +} + +GstCaps * +gst_vaapi_video_pool_get_caps(GstVaapiVideoPool *pool) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); + + return pool->priv->caps; +} + +void +gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) +{ + GstVaapiVideoPoolClass * const klass = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool); + + pool->priv->caps = gst_caps_ref(caps); + + if (klass->set_caps) + klass->set_caps(pool, caps); +} + +gpointer +gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) +{ + gpointer object; + + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); + + object = g_queue_pop_head(&pool->priv->free_objects); + if (!object) { + object = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool)->alloc_object( + pool, + pool->priv->display + ); + if (!object) + return NULL; + } + + pool->priv->used_objects = g_list_prepend(pool->priv->used_objects, object); + return g_object_ref(object); +} + +void +gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) +{ + GstVaapiVideoPoolPrivate *priv; + GList *elem; + + g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool)); + g_return_if_fail(G_IS_OBJECT(object)); + + priv = pool->priv; + elem = g_list_find(priv->used_objects, object); + if (!elem) + return; + + g_object_unref(object); + priv->used_objects = g_list_delete_link(priv->used_objects, elem); + g_queue_push_tail(&priv->free_objects, object); +} diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h new file mode 100644 index 0000000000..1d3b91a1fe --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -0,0 +1,86 @@ +/* + * gstvaapivideopool.h - Video object pool abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_VIDEO_POOL_H +#define GST_VAAPI_VIDEO_POOL_H + +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_VIDEO_POOL \ + (gst_vaapi_video_pool_get_type()) + +#define GST_VAAPI_VIDEO_POOL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_VIDEO_POOL, \ + GstVaapiVideoPool)) + +#define GST_VAAPI_VIDEO_POOL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_VIDEO_POOL, \ + GstVaapiVideoPoolClass)) + +#define GST_VAAPI_IS_VIDEO_POOL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_POOL)) + +#define GST_VAAPI_IS_VIDEO_POOL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_POOL)) + +#define GST_VAAPI_VIDEO_POOL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_VIDEO_POOL, \ + GstVaapiVideoPoolClass)) + +typedef struct _GstVaapiVideoPool GstVaapiVideoPool; +typedef struct _GstVaapiVideoPoolPrivate GstVaapiVideoPoolPrivate; +typedef struct _GstVaapiVideoPoolClass GstVaapiVideoPoolClass; + +struct _GstVaapiVideoPool { + /*< private >*/ + GObject parent_instance; + + GstVaapiVideoPoolPrivate *priv; +}; + +struct _GstVaapiVideoPoolClass { + /*< private >*/ + GObjectClass parent_class; + + void (*set_caps) (GstVaapiVideoPool *pool, GstCaps *caps); + gpointer (*alloc_object)(GstVaapiVideoPool *pool, GstVaapiDisplay *display); +}; + +GType +gst_vaapi_video_pool_get_type(void); + +GstCaps * +gst_vaapi_video_pool_get_caps(GstVaapiVideoPool *pool); + +gpointer +gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool); + +void +gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_POOL_H */ From c4653948645a63accf0db0bcb3c3c554d36c5838 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 12 Mar 2010 23:48:50 +0000 Subject: [PATCH 0039/3781] Add basic GstVaapiVideoBuffer. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapivideobuffer.c | 188 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivideobuffer.h | 91 +++++++++++ 3 files changed, 281 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapivideobuffer.c create mode 100644 gst-libs/gst/vaapi/gstvaapivideobuffer.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index d6333d1212..f9171c196d 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -9,6 +9,7 @@ libgstvaapi_source_c = \ gstvaapisubpicture.c \ gstvaapisurface.c \ gstvaapisurfacepool.c \ + gstvaapivideobuffer.c \ gstvaapivideopool.c \ vaapi_utils.c \ $(NULL) @@ -22,6 +23,7 @@ libgstvaapi_source_h = \ gstvaapisubpicture.h \ gstvaapisurface.h \ gstvaapisurfacepool.h \ + gstvaapivideobuffer.h \ gstvaapivideopool.h \ vaapi_debug.h \ vaapi_utils.h \ diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c new file mode 100644 index 0000000000..1daeb1e002 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -0,0 +1,188 @@ +/* + * gstvaapivideobuffer.c - Gst VA video buffer + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "gstvaapivideobuffer.h" + +#define DEBUG 1 +#include "vaapi_debug.h" + +G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, GST_TYPE_BUFFER); + +#define GST_VAAPI_VIDEO_BUFFER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_VIDEO_BUFFER, \ + GstVaapiVideoBufferPrivate)) + +struct _GstVaapiVideoBufferPrivate { + GstVaapiVideoPool *pool; + guint pool_type; + GstVaapiImage *image; + GstVaapiSurface *surface; + guint flags; +}; + +enum { + POOL_TYPE_NONE, + POOL_TYPE_IMAGE, + POOL_TYPE_SURFACE +}; + +static void +gst_vaapi_video_buffer_finalize(GstMiniObject *object) +{ + GstVaapiVideoBufferPrivate *priv = GST_VAAPI_VIDEO_BUFFER(object)->priv; + GstMiniObjectClass *parent_class; + + if (priv->image) { + if (priv->pool_type == POOL_TYPE_IMAGE) + gst_vaapi_video_pool_put_object(priv->pool, priv->image); + else + g_object_unref(priv->image); + priv->image = NULL; + } + + if (priv->surface) { + if (priv->pool_type == POOL_TYPE_SURFACE) + gst_vaapi_video_pool_put_object(priv->pool, priv->surface); + else + g_object_unref(priv->surface); + priv->surface = NULL; + } + + if (priv->pool) { + g_object_unref(priv->pool); + priv->pool = NULL; + } + + parent_class = GST_MINI_OBJECT_CLASS(gst_vaapi_video_buffer_parent_class); + if (parent_class->finalize) + parent_class->finalize(object); +} + +static void +gst_vaapi_video_buffer_class_init(GstVaapiVideoBufferClass *klass) +{ + GstMiniObjectClass * const object_class = GST_MINI_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiVideoBufferPrivate)); + + object_class->finalize = gst_vaapi_video_buffer_finalize; +} + +static void +gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) +{ + GstVaapiVideoBufferPrivate *priv; + + priv = GST_VAAPI_VIDEO_BUFFER_GET_PRIVATE(buffer); + buffer->priv = priv; + priv->pool = NULL; + priv->image = NULL; + priv->surface = NULL; +} + +static GstBuffer * +gst_vaapi_video_buffer_new( + GstVaapiVideoPool *pool, + GstVaapiImage *image, + GstVaapiSurface *surface +) +{ + gpointer vobject = NULL; + GstMiniObject *object; + GstVaapiVideoBuffer *buffer; + GstVaapiVideoBufferPrivate *priv; + + object = gst_mini_object_new(GST_VAAPI_TYPE_VIDEO_BUFFER); + if (!object) + return NULL; + + buffer = GST_VAAPI_VIDEO_BUFFER(object); + priv = buffer->priv; + priv->pool = pool; + priv->pool_type = POOL_TYPE_NONE; + priv->image = image; + priv->surface = surface; + + if (pool) { + vobject = gst_vaapi_video_pool_get_object(pool); + if (!vobject) + goto error; + + if (GST_VAAPI_IS_IMAGE(vobject)) { + priv->pool_type = POOL_TYPE_IMAGE; + priv->image = vobject; + } + else if (GST_VAAPI_IS_SURFACE(vobject)) { + priv->pool_type = POOL_TYPE_SURFACE; + priv->surface = vobject; + } + else + goto error; + } + return GST_BUFFER(buffer); + +error: + if (vobject) + gst_vaapi_video_pool_put_object(pool, vobject); + gst_mini_object_unref(object); + return NULL; +} + +GstBuffer * +gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); + + return gst_vaapi_video_buffer_new(g_object_ref(pool), NULL, NULL); +} + +GstBuffer * +gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); + + return gst_vaapi_video_buffer_new(NULL, g_object_ref(image), NULL); +} + +GstBuffer * +gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); + + return gst_vaapi_video_buffer_new(NULL, NULL, g_object_ref(surface)); +} + +GstVaapiImage * +gst_vaapi_video_buffer_get_image(GstVaapiVideoBuffer *buffer) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL); + + return buffer->priv->image; +} + +GstVaapiSurface * +gst_vaapi_video_buffer_get_surface(GstVaapiVideoBuffer *buffer) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL); + + return buffer->priv->surface; +} diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h new file mode 100644 index 0000000000..5cecfec6ff --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -0,0 +1,91 @@ +/* + * gstvaapivideobuffer.h - Gstreamer/VA video buffer + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_VIDEO_BUFFER_H +#define GST_VAAPI_VIDEO_BUFFER_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_VIDEO_BUFFER \ + (gst_vaapi_video_buffer_get_type()) + +#define GST_VAAPI_VIDEO_BUFFER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_VIDEO_BUFFER, \ + GstVaapiVideoBuffer)) + +#define GST_VAAPI_VIDEO_BUFFER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_VIDEO_BUFFER, \ + GstVaapiVideoBufferClass)) + +#define GST_VAAPI_IS_VIDEO_BUFFER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_BUFFER)) + +#define GST_VAAPI_IS_VIDEO_BUFFER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_BUFFER)) + +#define GST_VAAPI_VIDEO_BUFFER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_VIDEO_BUFFER, \ + GstVaapiVideoBufferClass)) + +typedef struct _GstVaapiVideoBuffer GstVaapiVideoBuffer; +typedef struct _GstVaapiVideoBufferPrivate GstVaapiVideoBufferPrivate; +typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass; + +struct _GstVaapiVideoBuffer { + /*< private >*/ + GstBuffer parent_instance; + + GstVaapiVideoBufferPrivate *priv; +}; + +struct _GstVaapiVideoBufferClass { + /*< private >*/ + GstBufferClass parent_class; +}; + +GType +gst_vaapi_video_buffer_get_type(void); + +GstBuffer * +gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); + +GstBuffer * +gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image); + +GstBuffer * +gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface); + +GstVaapiImage * +gst_vaapi_video_buffer_get_image(GstVaapiVideoBuffer *buffer); + +GstVaapiSurface * +gst_vaapi_video_buffer_get_surface(GstVaapiVideoBuffer *buffer); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_BUFFER_H */ From 95a7534e6c9ea4fddc29316f0c2868d89b716f52 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 12 Mar 2010 23:50:09 +0000 Subject: [PATCH 0040/3781] Add surface tests. --- tests/examples/generic/Makefile.am | 5 ++ tests/examples/generic/test-surfaces.c | 108 +++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 tests/examples/generic/test-surfaces.c diff --git a/tests/examples/generic/Makefile.am b/tests/examples/generic/Makefile.am index 96bddd9cd0..a914fff57d 100644 --- a/tests/examples/generic/Makefile.am +++ b/tests/examples/generic/Makefile.am @@ -1,5 +1,6 @@ noinst_PROGRAMS = \ test-display \ + test-surfaces \ $(NULL) TEST_CFLAGS = \ @@ -15,5 +16,9 @@ test_display_SOURCES = test-display.c test_display_CFLAGS = $(TEST_CFLAGS) test_display_LDADD = $(TEST_LIBS) +test_surfaces_SOURCES = test-surfaces.c +test_surfaces_CFLAGS = $(TEST_CFLAGS) +test_surfaces_LDADD = $(TEST_LIBS) + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/examples/generic/test-surfaces.c b/tests/examples/generic/test-surfaces.c new file mode 100644 index 0000000000..d201bdbd29 --- /dev/null +++ b/tests/examples/generic/test-surfaces.c @@ -0,0 +1,108 @@ +/* + * test-surfaces.c - Test GstVaapiSurface and GstVaapiSurfacePool + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include + +#define MAX_SURFACES 4 + +int +main(int argc, char *argv[]) +{ + GstVaapiDisplay *display; + GstVaapiSurface *surface; + GstVaapiSurface *surfaces[MAX_SURFACES]; + GstVaapiVideoPool *pool; + GstCaps *caps; + gint i; + + static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + static const guint width = 320; + static const guint height = 240; + + gst_init(&argc, &argv); + + display = gst_vaapi_display_x11_new(NULL); + if (!display) + g_error("could not create Gst/VA display"); + + surface = gst_vaapi_surface_new(display, chroma_type, width, height); + if (!surface) + g_error("could not create Gst/VA surface"); + g_object_unref(surface); + + caps = gst_caps_new_simple( + "video/x-vaapi-surface", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL + ); + if (!caps) + g_error("cound not create Gst/VA surface caps"); + + pool = gst_vaapi_surface_pool_new(display, caps); + if (!pool) + g_error("could not create Gst/VA surface pool"); + + for (i = 0; i < MAX_SURFACES; i++) { + surface = gst_vaapi_video_pool_get_object(pool); + if (!surface) + g_error("could not allocate Gst/VA surface from pool"); + g_print("created surface 0x%08x from pool\n", + gst_vaapi_surface_get_id(surface)); + surfaces[i] = surface; + } + + /* Check the pool doesn't return the last free'd surface */ + surface = g_object_ref(surfaces[1]); + + for (i = 0; i < 2; i++) + gst_vaapi_video_pool_put_object(pool, surfaces[i]); + + for (i = 0; i < 2; i++) { + surfaces[i] = gst_vaapi_video_pool_get_object(pool); + if (!surfaces[i]) + g_error("could not re-allocate Gst/VA surface%d from pool", i); + g_print("created surface 0x%08x from pool (realloc)\n", + gst_vaapi_surface_get_id(surfaces[i])); + } + + if (surface == surfaces[0]) + g_error("Gst/VA pool doesn't queue free surfaces"); + + for (i = MAX_SURFACES - 1; i >= 0; i--) { + if (!surfaces[i]) + continue; + gst_vaapi_video_pool_put_object(pool, surfaces[i]); + surfaces[i] = NULL; + } + + /* Unref in random order to check objects are correctly refcounted */ + g_print("unref display\n"); + g_object_unref(display); + gst_caps_unref(caps); + g_print("unref pool\n"); + g_object_unref(pool); + g_print("unref surface\n"); + g_object_unref(surface); + gst_deinit(); + return 0; +} From 5c8403fcf7e7349c0e5e8c2c274dde9a8abce728 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 12 Mar 2010 23:53:48 +0000 Subject: [PATCH 0041/3781] Implement GstVaapiSinkBase interface and integrate with GST_DEBUG better. --- sys/vaapisink/Makefile.am | 8 ++ sys/vaapisink/gstvaapisink.c | 151 ++++++++++++++++++++++++++++++++++- sys/vaapisink/gstvaapisink.h | 11 ++- 3 files changed, 163 insertions(+), 7 deletions(-) diff --git a/sys/vaapisink/Makefile.am b/sys/vaapisink/Makefile.am index f886efaf3e..7ef17afd86 100644 --- a/sys/vaapisink/Makefile.am +++ b/sys/vaapisink/Makefile.am @@ -1,5 +1,11 @@ plugin_LTLIBRARIES = libgstvaapisink.la +libgstvaapi_CFLAGS = \ + -I$(top_srcdir)/gst-libs + +libgstvaapi_LIBS = \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la + libgstvaapisink_la_SOURCES = \ gstvaapisink.c \ $(NULL) @@ -9,11 +15,13 @@ noinst_HEADERS = \ $(NULL) libgstvaapisink_la_CFLAGS = \ + $(libgstvaapi_CFLAGS) \ $(GST_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ $(GST_PLUGINS_BASE_CFLAGS) libgstvaapisink_la_LIBADD = \ + $(libgstvaapi_LIBS) \ $(GST_LIBS) \ $(GST_VIDEO_LIBS) \ $(GST_PLUGINS_BASE_LIBS) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 19a0d69fb5..1e7258057d 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -19,8 +19,17 @@ */ #include "config.h" +#include +#include +#include #include "gstvaapisink.h" +#define GST_PLUGIN_NAME "vaapisink" +#define GST_PLUGIN_DESC "A VA-API based videosink" + +GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink); +#define GST_CAT_DEFAULT gst_debug_vaapisink + /* ElementFactory information */ static const GstElementDetails gst_vaapisink_details = GST_ELEMENT_DETAILS( @@ -40,7 +49,106 @@ static GstStaticPadTemplate gst_vaapisink_sink_factory = "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]; ")); -GST_BOILERPLATE(GstVaapiSink, gst_vaapisink, GstVideoSink, GST_TYPE_VIDEO_SINK); +static void gst_vaapisink_iface_init(GType type); + +GST_BOILERPLATE_FULL( + GstVaapiSink, + gst_vaapisink, + GstVideoSink, + GST_TYPE_VIDEO_SINK, + gst_vaapisink_iface_init); + +enum { + PROP_0, + + PROP_DISPLAY, + PROP_DISPLAY_NAME, +}; + +static GstVaapiDisplay * +gst_vaapisink_base_do_get_display(GstVaapiSinkBase *sink) +{ + return gst_vaapisink_get_display(GST_VAAPISINK(sink)); +} + +static void gst_vaapisink_base_iface_init(GstVaapiSinkBaseInterface *iface) +{ + iface->get_display = gst_vaapisink_base_do_get_display; +} + +static void gst_vaapisink_iface_init(GType type) +{ + const GType g_define_type_id = type; + + G_IMPLEMENT_INTERFACE(GST_TYPE_VAAPISINK_BASE, + gst_vaapisink_base_iface_init); +} + +static void +gst_vaapisink_destroy(GstVaapiSink *sink) +{ + if (sink->display) { + g_object_unref(sink->display); + sink->display = NULL; + } + + if (sink->display_name) { + g_free(sink->display_name); + sink->display_name = NULL; + } +} + +static void +gst_vaapisink_finalize(GObject *object) +{ + gst_vaapisink_destroy(GST_VAAPISINK(object)); + + G_OBJECT_CLASS(parent_class)->finalize(object); +} + +static void +gst_vaapisink_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiSink * const sink = GST_VAAPISINK(object); + + switch (prop_id) { + case PROP_DISPLAY_NAME: + g_free(sink->display_name); + sink->display_name = g_strdup(g_value_get_string(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapisink_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiSink * const sink = GST_VAAPISINK(object); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_object(value, sink->display); + break; + case PROP_DISPLAY_NAME: + g_value_set_string(value, sink->display_name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} static void gst_vaapisink_base_init(gpointer klass) { @@ -60,24 +168,59 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass); GstVideoSinkClass * const videosink_class = GST_VIDEO_SINK_CLASS(klass); + + object_class->finalize = gst_vaapisink_finalize; + object_class->set_property = gst_vaapisink_set_property; + object_class->get_property = gst_vaapisink_get_property; + + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_object("display", + "display", + "display", + GST_VAAPI_TYPE_DISPLAY, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, + PROP_DISPLAY_NAME, + g_param_spec_string("display-name", + "X11 display name", + "X11 display name", + "", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) { + sink->display_name = NULL; + sink->display = NULL; +} + +GstVaapiDisplay * +gst_vaapisink_get_display(GstVaapiSink *sink) +{ + if (!sink->display) + sink->display = gst_vaapi_display_x11_new(sink->display_name); + return sink->display; } static gboolean plugin_init(GstPlugin *plugin) { + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapisink, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + return gst_element_register(plugin, - "vaapisink", + GST_PLUGIN_NAME, GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); } GST_PLUGIN_DEFINE( GST_VERSION_MAJOR, GST_VERSION_MINOR, - "vaapisink", - "A VA-API based videosink", + GST_PLUGIN_NAME, + GST_PLUGIN_DESC, plugin_init, PACKAGE_VERSION, "GPL", diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h index 270d1a635f..c0291adeb4 100644 --- a/sys/vaapisink/gstvaapisink.h +++ b/sys/vaapisink/gstvaapisink.h @@ -22,6 +22,8 @@ #define GST_VAAPISINK_H #include +#include +#include G_BEGIN_DECLS @@ -47,17 +49,17 @@ G_BEGIN_DECLS #define GST_VAAPISINK_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), \ GST_TYPE_VAAPISINK, \ - GstVaapiSink)) + GstVaapiSinkClass)) typedef struct _GstVaapiSink GstVaapiSink; -typedef struct _GstVaapiSinkPrivate GstVaapiSinkPrivate; typedef struct _GstVaapiSinkClass GstVaapiSinkClass; struct _GstVaapiSink { /*< private >*/ GstVideoSink parent_instance; - GstVaapiSinkPrivate *priv; + gchar *display_name; + GstVaapiDisplay *display; }; struct _GstVaapiSinkClass { @@ -68,6 +70,9 @@ struct _GstVaapiSinkClass { GType gst_vaapisink_get_type(void); +GstVaapiDisplay * +gst_vaapisink_get_display(GstVaapiSink *sink); + G_END_DECLS #endif /* GST_VAAPISINK_H */ From 541d740ea3ea635909b592d3b07b77c119a50b72 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 10:27:10 +0000 Subject: [PATCH 0042/3781] Add gst_vaapi_image_update_from_buffer() helper. --- gst-libs/gst/vaapi/gstvaapiimage.c | 145 ++++++++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapiimage.h | 8 +- 2 files changed, 138 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index fa97e4da08..52ad80457b 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -36,11 +36,12 @@ G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, G_TYPE_OBJECT); struct _GstVaapiImagePrivate { GstVaapiDisplay *display; + gboolean is_constructed; VAImage image; guchar *image_data; + GstVaapiImageFormat format; guint width; guint height; - GstVaapiImageFormat format; }; enum { @@ -48,9 +49,9 @@ enum { PROP_DISPLAY, PROP_IMAGE_ID, + PROP_FORMAT, PROP_WIDTH, - PROP_HEIGHT, - PROP_FORMAT + PROP_HEIGHT }; static void @@ -125,15 +126,15 @@ gst_vaapi_image_set_property( case PROP_DISPLAY: priv->display = g_object_ref(g_value_get_object(value)); break; + case PROP_FORMAT: + priv->format = g_value_get_uint(value); + break; case PROP_WIDTH: priv->width = g_value_get_uint(value); break; case PROP_HEIGHT: priv->height = g_value_get_uint(value); break; - case PROP_FORMAT: - priv->format = g_value_get_uint(value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -157,15 +158,15 @@ gst_vaapi_image_get_property( case PROP_IMAGE_ID: g_value_set_uint(value, gst_vaapi_image_get_id(image)); break; + case PROP_FORMAT: + g_value_set_uint(value, gst_vaapi_image_get_format(image)); + break; case PROP_WIDTH: g_value_set_uint(value, gst_vaapi_image_get_width(image)); break; case PROP_HEIGHT: g_value_set_uint(value, gst_vaapi_image_get_height(image)); break; - case PROP_FORMAT: - g_value_set_uint(value, gst_vaapi_image_get_format(image)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -178,7 +179,7 @@ gst_vaapi_image_constructed(GObject *object) GstVaapiImage * const image = GST_VAAPI_IMAGE(object); GObjectClass *parent_class; - gst_vaapi_image_create(image); + image->priv->is_constructed = gst_vaapi_image_create(image); parent_class = G_OBJECT_CLASS(gst_vaapi_image_parent_class); if (parent_class->constructed) @@ -263,9 +264,9 @@ gst_vaapi_image_init(GstVaapiImage *image) GstVaapiImage * gst_vaapi_image_new( GstVaapiDisplay *display, + GstVaapiImageFormat format, guint width, - guint height, - GstVaapiImageFormat format + guint height ) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); @@ -276,9 +277,9 @@ gst_vaapi_image_new( return g_object_new(GST_VAAPI_TYPE_IMAGE, "display", display, + "format", format, "width", width, "height", height, - "format", format, NULL); } @@ -286,6 +287,7 @@ VAImageID gst_vaapi_image_get_id(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID); + g_return_val_if_fail(image->priv->is_constructed, FALSE); return image->priv->image.image_id; } @@ -294,6 +296,7 @@ GstVaapiDisplay * gst_vaapi_image_get_display(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); + g_return_val_if_fail(image->priv->is_constructed, FALSE); return image->priv->display; } @@ -302,6 +305,7 @@ guint gst_vaapi_image_get_width(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image->priv->is_constructed, FALSE); return image->priv->width; } @@ -310,6 +314,7 @@ guint gst_vaapi_image_get_height(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image->priv->is_constructed, FALSE); return image->priv->height; } @@ -318,6 +323,7 @@ guint gst_vaapi_image_get_format(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image->priv->is_constructed, FALSE); return image->priv->format; } @@ -332,6 +338,7 @@ gboolean gst_vaapi_image_is_mapped(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image->priv->is_constructed, FALSE); return _gst_vaapi_image_is_mapped(image); } @@ -343,6 +350,7 @@ gst_vaapi_image_map(GstVaapiImage *image) VAStatus status; g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image->priv->is_constructed, FALSE); if (_gst_vaapi_image_is_mapped(image)) return TRUE; @@ -365,6 +373,7 @@ gst_vaapi_image_unmap(GstVaapiImage *image) VAStatus status; g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image->priv->is_constructed, FALSE); if (!_gst_vaapi_image_is_mapped(image)) return FALSE; @@ -384,6 +393,7 @@ guint gst_vaapi_image_get_plane_count(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image->priv->is_constructed, FALSE); g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0); return image->priv->image.num_planes; @@ -393,6 +403,7 @@ guchar * gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); + g_return_val_if_fail(image->priv->is_constructed, FALSE); g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL); g_return_val_if_fail(plane < image->priv->image.num_planes, NULL); @@ -403,8 +414,116 @@ guint gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image->priv->is_constructed, FALSE); g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0); g_return_val_if_fail(plane < image->priv->image.num_planes, 0); return image->priv->image.pitches[plane]; } + +gboolean +gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) +{ + GstVaapiImagePrivate *priv; + GstStructure *structure; + GstCaps *caps; + GstVaapiImageFormat format; + gint width, height; + guint offsets[3], pitches[3], widths[3], heights[3]; + guint i, j; + guchar *data; + guint32 data_size; + + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image->priv->is_constructed, FALSE); + g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE); + + priv = image->priv; + data = GST_BUFFER_DATA(buffer); + data_size = GST_BUFFER_SIZE(buffer); + caps = GST_BUFFER_CAPS(buffer); + + if (!caps) + return FALSE; + + format = gst_vaapi_image_format_from_caps(caps); + if (format != priv->format) + return FALSE; + + structure = gst_caps_get_structure(caps, 0); + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + if (width != priv->width || height != priv->height) + return FALSE; + + if (!gst_vaapi_image_map(image)) + return FALSE; + + if (data_size == priv->image.data_size) + memcpy(priv->image_data, data, data_size); + else { + /* XXX: copied from gst_video_format_get_row_stride() -- no NV12? */ + const guint width2 = (width + 1) / 2; + const guint height2 = (height + 1) / 2; + guint size2; + switch (format) { + case GST_VAAPI_IMAGE_NV12: + offsets[0] = 0; + pitches[0] = GST_ROUND_UP_4(width); + widths [0] = width; + heights[0] = height; + offsets[1] = offsets[0] + height * pitches[0]; + pitches[1] = pitches[0]; + widths [1] = width2 * 2; + heights[1] = height2; + size2 = offsets[1] + height2 * pitches[1]; + break; + case GST_VAAPI_IMAGE_YV12: + case GST_VAAPI_IMAGE_I420: + offsets[0] = 0; + pitches[0] = GST_ROUND_UP_4(width); + widths [0] = width; + heights[0] = height; + offsets[1] = offsets[0] + height * pitches[0]; + pitches[1] = GST_ROUND_UP_4(GST_ROUND_UP_2(width) / 2); + widths [1] = width2; + heights[1] = height2; + offsets[2] = offsets[1] + height2 * pitches[1]; + pitches[2] = pitches[1]; + widths [2] = width2; + heights[2] = height2; + size2 = offsets[2] + height2 * pitches[2]; + break; + case GST_VAAPI_IMAGE_ARGB: + case GST_VAAPI_IMAGE_RGBA: + case GST_VAAPI_IMAGE_ABGR: + case GST_VAAPI_IMAGE_BGRA: + offsets[0] = 0; + pitches[0] = width * 4; + widths [0] = width * 4; + heights[0] = height; + size2 = offsets[0] + height * pitches[0]; + break; + default: + g_error("could not compute row-stride for %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS(format)); + break; + } + if (size2 != data_size) + g_error("data_size mismatch %d / %u", size2, data_size); + for (i = 0; i < priv->image.num_planes; i++) { + guchar *src = data + offsets[i]; + guchar *dst = priv->image_data + priv->image.offsets[i]; + for (j = 0; j < heights[i]; j++) { + memcpy(dst, src, widths[i]); + src += pitches[i]; + dst += priv->image.pitches[i]; + } + } + } + + if (!gst_vaapi_image_unmap(image)) + return FALSE; + + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 7d096662c4..237e8c56d7 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -21,6 +21,7 @@ #ifndef GST_VAAPI_IMAGE_H #define GST_VAAPI_IMAGE_H +#include #include #include @@ -72,9 +73,9 @@ gst_vaapi_image_get_type(void); GstVaapiImage * gst_vaapi_image_new( GstVaapiDisplay *display, + GstVaapiImageFormat format, guint width, - guint height, - GstVaapiImageFormat format + guint height ); VAImageID @@ -110,6 +111,9 @@ gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane); guint gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane); +gboolean +gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer); + G_END_DECLS #endif /* GST_VAAPI_IMAGE_H */ From d69e59ffee2896a6d9988c1674a1b8a8c663a6c1 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 11:49:03 +0000 Subject: [PATCH 0043/3781] Add gst_vaapi_{get,put}_image() API. --- gst-libs/gst/vaapi/gstvaapiimage.c | 13 ++++++ gst-libs/gst/vaapi/gstvaapiimage.h | 3 ++ gst-libs/gst/vaapi/gstvaapisurface.c | 60 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 7 ++++ 4 files changed, 83 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 52ad80457b..d84b8947db 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -319,6 +319,19 @@ gst_vaapi_image_get_height(GstVaapiImage *image) return image->priv->height; } +void +gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image->priv->is_constructed, FALSE); + + if (pwidth) + *pwidth = image->priv->width; + + if (pheight) + *pheight = image->priv->height; +} + guint gst_vaapi_image_get_format(GstVaapiImage *image) { diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 237e8c56d7..eb8f37b125 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -90,6 +90,9 @@ gst_vaapi_image_get_width(GstVaapiImage *image); guint gst_vaapi_image_get_height(GstVaapiImage *image); +void +gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight); + guint gst_vaapi_image_get_format(GstVaapiImage *image); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index dc414957db..4f859f0237 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -336,3 +336,63 @@ gst_vaapi_surface_get_size( *pheight = gst_vaapi_surface_get_height(surface); } +gboolean +gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) +{ + VAImageID image_id; + VAStatus status; + guint width, height; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + + gst_vaapi_image_get_size(image, &width, &height); + if (width != surface->priv->width || height != surface->priv->height) + return FALSE; + + image_id = gst_vaapi_image_get_id(image); + if (image_id == VA_INVALID_ID) + return FALSE; + + status = vaGetImage( + gst_vaapi_display_get_display(surface->priv->display), + surface->priv->surface_id, + 0, 0, width, height, + image_id + ); + if (!vaapi_check_status(status, "vaGetImage()")) + return FALSE; + + return TRUE; +} + +gboolean +gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) +{ + VAImageID image_id; + VAStatus status; + guint width, height; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + + gst_vaapi_image_get_size(image, &width, &height); + if (width != surface->priv->width || height != surface->priv->height) + return FALSE; + + image_id = gst_vaapi_image_get_id(image); + if (image_id == VA_INVALID_ID) + return FALSE; + + status = vaPutImage( + gst_vaapi_display_get_display(surface->priv->display), + surface->priv->surface_id, + image_id, + 0, 0, width, height, + 0, 0, width, height + ); + if (!vaapi_check_status(status, "vaPutImage()")) + return FALSE; + + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 3e859a33c9..445ca8f56f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -21,6 +21,7 @@ #ifndef GST_VAAPI_SURFACE_H #define GST_VAAPI_SURFACE_H +#include #include G_BEGIN_DECLS @@ -106,6 +107,12 @@ gst_vaapi_surface_get_size( guint *pheight ); +gboolean +gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image); + +gboolean +gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_H */ From fe4740d35ad64facc485eaf795cddb9ecefadbe4 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 13:32:37 +0000 Subject: [PATCH 0044/3781] Cosmetics. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index f98ba56333..4606517ca8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -262,7 +262,8 @@ gst_vaapi_display_set_property( GObject *object, guint prop_id, const GValue *value, - GParamSpec *pspec) + GParamSpec *pspec +) { GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); From a3f2975309fb3988ecdf0ddb0abdbad9ad2ce22d Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 14:57:30 +0000 Subject: [PATCH 0045/3781] Fix preconditions. --- gst-libs/gst/vaapi/gstvaapiimage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index d84b8947db..564858e77b 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -322,8 +322,8 @@ gst_vaapi_image_get_height(GstVaapiImage *image) void gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); - g_return_val_if_fail(image->priv->is_constructed, FALSE); + g_return_if_fail(GST_VAAPI_IS_IMAGE(image)); + g_return_if_fail(image->priv->is_constructed); if (pwidth) *pwidth = image->priv->width; From f87dfaacba278ee346f969402f6a5a207bba6cb3 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 14:57:57 +0000 Subject: [PATCH 0046/3781] Add VA and X11 display accessors. --- gst-libs/gst/vaapi/gstvaapidisplay.h | 3 +++ gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 72488ba3cc..cccb095653 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -51,6 +51,9 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DISPLAY, \ GstVaapiDisplayClass)) +#define GST_VAAPI_DISPLAY_VADISPLAY(display) \ + gst_vaapi_display_get_display(display) + typedef struct _GstVaapiDisplay GstVaapiDisplay; typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index baeb15b615..3956315967 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -50,6 +50,9 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DISPLAY_X11, \ GstVaapiDisplayX11Class)) +#define GST_VAAPI_DISPLAY_XDISPLAY(display) \ + gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)) + typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11; typedef struct _GstVaapiDisplayX11Private GstVaapiDisplayX11Private; typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class; From 7fe02f31a50583c6d4d97a29df30c9df83612e37 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 15:12:27 +0000 Subject: [PATCH 0047/3781] Add VA/X11 window abstraction. --- gst-libs/gst/vaapi/Makefile.am | 4 + gst-libs/gst/vaapi/gstvaapiwindow.c | 332 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow.h | 138 ++++++++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 448 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 84 +++++ tests/examples/generic/Makefile.am | 5 + tests/examples/generic/test-windows.c | 120 +++++++ 7 files changed, 1131 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow.c create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow.h create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_x11.c create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_x11.h create mode 100644 tests/examples/generic/test-windows.c diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f9171c196d..127e54cf77 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -11,6 +11,7 @@ libgstvaapi_source_c = \ gstvaapisurfacepool.c \ gstvaapivideobuffer.c \ gstvaapivideopool.c \ + gstvaapiwindow.c \ vaapi_utils.c \ $(NULL) @@ -25,6 +26,7 @@ libgstvaapi_source_h = \ gstvaapisurfacepool.h \ gstvaapivideobuffer.h \ gstvaapivideopool.h \ + gstvaapiwindow.h \ vaapi_debug.h \ vaapi_utils.h \ $(NULL) @@ -55,10 +57,12 @@ libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ libgstvaapi_@GST_MAJORMINOR@_la_SOURCES += \ gstvaapidisplay_x11.c \ + gstvaapiwindow_x11.c \ $(NULL) libgstvaapi_@GST_MAJORMINOR@include_HEADERS += \ gstvaapidisplay_x11.h \ + gstvaapiwindow_x11.h \ $(NULL) libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS += \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c new file mode 100644 index 0000000000..66295649a5 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -0,0 +1,332 @@ +/* + * gstvaapiwindow.c - VA window abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "gstvaapiwindow.h" + +#define DEBUG 1 +#include "vaapi_debug.h" + +G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, G_TYPE_OBJECT); + +#define GST_VAAPI_WINDOW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_WINDOW, \ + GstVaapiWindowPrivate)) + +struct _GstVaapiWindowPrivate { + gboolean is_constructed; + guint width; + guint height; +}; + +enum { + PROP_0, + + PROP_WIDTH, + PROP_HEIGHT +}; + +static void +gst_vaapi_window_destroy(GstVaapiWindow *window) +{ + GST_VAAPI_WINDOW_GET_CLASS(window)->destroy(window); +} + +static gboolean +gst_vaapi_window_create(GstVaapiWindow *window, guint width, guint height) +{ + if (width == 0 || height == 0) + return FALSE; + + return GST_VAAPI_WINDOW_GET_CLASS(window)->create(window, width, height); +} + +static void +gst_vaapi_window_finalize(GObject *object) +{ + gst_vaapi_window_destroy(GST_VAAPI_WINDOW(object)); + + G_OBJECT_CLASS(gst_vaapi_window_parent_class)->finalize(object); +} + +static void +gst_vaapi_window_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiWindow * const window = GST_VAAPI_WINDOW(object); + + switch (prop_id) { + case PROP_WIDTH: + gst_vaapi_window_set_width(window, g_value_get_uint(value)); + break; + case PROP_HEIGHT: + gst_vaapi_window_set_height(window, g_value_get_uint(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_window_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiWindow * const window = GST_VAAPI_WINDOW(object); + + switch (prop_id) { + case PROP_WIDTH: + g_value_set_uint(value, gst_vaapi_window_get_width(window)); + break; + case PROP_HEIGHT: + g_value_set_uint(value, gst_vaapi_window_get_height(window)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_window_constructed(GObject *object) +{ + GstVaapiWindow * const window = GST_VAAPI_WINDOW(object); + GObjectClass *parent_class; + + window->priv->is_constructed = gst_vaapi_window_create( + window, + window->priv->width, + window->priv->height + ); + + parent_class = G_OBJECT_CLASS(gst_vaapi_window_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + +static void +gst_vaapi_window_class_init(GstVaapiWindowClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiWindowPrivate)); + + object_class->finalize = gst_vaapi_window_finalize; + object_class->set_property = gst_vaapi_window_set_property; + object_class->get_property = gst_vaapi_window_get_property; + object_class->constructed = gst_vaapi_window_constructed; + + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_uint("width", + "width", + "Width", + 1, G_MAXUINT32, 1, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_uint("height", + "height", + "Height", + 1, G_MAXUINT32, 1, + G_PARAM_READWRITE)); +} + +static void +gst_vaapi_window_init(GstVaapiWindow *window) +{ + GstVaapiWindowPrivate *priv = GST_VAAPI_WINDOW_GET_PRIVATE(window); + + window->priv = priv; + priv->is_constructed = FALSE; + priv->width = 1; + priv->height = 1; +} + +void +gst_vaapi_window_show(GstVaapiWindow *window) +{ + g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + g_return_if_fail(window->priv->is_constructed); + + GST_VAAPI_WINDOW_GET_CLASS(window)->show(window); +} + +void +gst_vaapi_window_hide(GstVaapiWindow *window) +{ + g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + g_return_if_fail(window->priv->is_constructed); + + GST_VAAPI_WINDOW_GET_CLASS(window)->hide(window); +} + +guint +gst_vaapi_window_get_width(GstVaapiWindow *window) +{ + g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0); + g_return_val_if_fail(window->priv->is_constructed, 0); + + return window->priv->width; +} + +guint +gst_vaapi_window_get_height(GstVaapiWindow *window) +{ + g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0); + g_return_val_if_fail(window->priv->is_constructed, 0); + + return window->priv->height; +} + +void +gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight) +{ + g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + g_return_if_fail(window->priv->is_constructed); + + if (pwidth) + *pwidth = window->priv->width; + + if (pheight) + *pheight = window->priv->height; +} + +void +gst_vaapi_window_set_width(GstVaapiWindow *window, guint width) +{ + g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + + gst_vaapi_window_set_size(window, width, window->priv->height); +} + +void +gst_vaapi_window_set_height(GstVaapiWindow *window, guint height) +{ + g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + + gst_vaapi_window_set_size(window, window->priv->width, height); +} + +void +gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) +{ + g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + + if (width == window->priv->width && height == window->priv->height) + return; + + window->priv->width = width; + window->priv->height = height; + + if (window->priv->is_constructed) + GST_VAAPI_WINDOW_GET_CLASS(window)->resize(window, width, height); +} + +static inline void +get_surface_rect(GstVaapiSurface *surface, GstVideoRectangle *rect) +{ + guint width, height; + + gst_vaapi_surface_get_size(surface, &width, &height); + rect->x = 0; + rect->y = 0; + rect->w = width; + rect->h = height; +} + +static inline void +get_window_rect(GstVaapiWindow *window, GstVideoRectangle *rect) +{ + guint width, height; + + gst_vaapi_window_get_size(window, &width, &height); + rect->x = 0; + rect->y = 0; + rect->w = width; + rect->h = height; +} + +gboolean +gst_vaapi_window_put_surface( + GstVaapiWindow *window, + GstVaapiSurface *surface, + guint flags +) +{ + GstVideoRectangle src_rect, dst_rect; + + g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE); + g_return_val_if_fail(window->priv->is_constructed, FALSE); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + + get_surface_rect(surface, &src_rect); + get_window_rect(window, &dst_rect); + + return GST_VAAPI_WINDOW_GET_CLASS(window)->render(window, + surface, + &src_rect, + &dst_rect, + flags); +} + +gboolean +gst_vaapi_window_put_surface_full( + GstVaapiWindow *window, + GstVaapiSurface *surface, + const GstVideoRectangle *src_rect, + const GstVideoRectangle *dst_rect, + guint flags +) +{ + GstVideoRectangle src_rect_default, dst_rect_default; + + g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE); + g_return_val_if_fail(window->priv->is_constructed, FALSE); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + + if (!src_rect) { + src_rect = &src_rect_default; + get_surface_rect(surface, &src_rect_default); + } + + if (!dst_rect) { + dst_rect = &dst_rect_default; + get_window_rect(window, &dst_rect_default); + } + + return GST_VAAPI_WINDOW_GET_CLASS(window)->render(window, + surface, + src_rect, + dst_rect, + flags); +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h new file mode 100644 index 0000000000..1095f7adaa --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -0,0 +1,138 @@ +/* + * gstvaapiwindow.h - VA window abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_WINDOW_H +#define GST_VAAPI_WINDOW_H + +#include +#include +#include + +G_BEGIN_DECLS + +enum { + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD = 1 << 0, + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD = 1 << 1, + GST_VAAPI_PICTURE_STRUCTURE_FRAME = + ( + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD | + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD + ), + GST_VAAPI_COLOR_STANDARD_ITUR_BT_601 = 1 << 2, + GST_VAAPI_COLOR_STANDARD_ITUR_BT_709 = 1 << 3, +}; + +#define GST_VAAPI_TYPE_WINDOW \ + (gst_vaapi_window_get_type()) + +#define GST_VAAPI_WINDOW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_WINDOW, \ + GstVaapiWindow)) + +#define GST_VAAPI_WINDOW_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_WINDOW, \ + GstVaapiWindowClass)) + +#define GST_VAAPI_IS_WINDOW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW)) + +#define GST_VAAPI_IS_WINDOW_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW)) + +#define GST_VAAPI_WINDOW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_WINDOW, \ + GstVaapiWindowClass)) + +typedef struct _GstVaapiWindow GstVaapiWindow; +typedef struct _GstVaapiWindowPrivate GstVaapiWindowPrivate; +typedef struct _GstVaapiWindowClass GstVaapiWindowClass; + +struct _GstVaapiWindow { + /*< private >*/ + GObject parent_instance; + + GstVaapiWindowPrivate *priv; +}; + +struct _GstVaapiWindowClass { + /*< private >*/ + GObjectClass parent_class; + + gboolean (*create) (GstVaapiWindow *window, guint width, guint height); + void (*destroy)(GstVaapiWindow *window); + gboolean (*show) (GstVaapiWindow *window); + gboolean (*hide) (GstVaapiWindow *window); + gboolean (*resize) (GstVaapiWindow *window, guint width, guint height); + gboolean (*render) (GstVaapiWindow *window, + GstVaapiSurface *surface, + const GstVideoRectangle *src_rect, + const GstVideoRectangle *dst_rect, + guint flags); +}; + +GType +gst_vaapi_window_get_type(void); + +void +gst_vaapi_window_show(GstVaapiWindow *window); + +void +gst_vaapi_window_hide(GstVaapiWindow *window); + +guint +gst_vaapi_window_get_width(GstVaapiWindow *window); + +guint +gst_vaapi_window_get_height(GstVaapiWindow *window); + +void +gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight); + +void +gst_vaapi_window_set_width(GstVaapiWindow *window, guint width); + +void +gst_vaapi_window_set_height(GstVaapiWindow *window, guint height); + +void +gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height); + +gboolean +gst_vaapi_window_put_surface( + GstVaapiWindow *window, + GstVaapiSurface *surface, + guint flags +); + +gboolean +gst_vaapi_window_put_surface_full( + GstVaapiWindow *window, + GstVaapiSurface *surface, + const GstVideoRectangle *src_rect, + const GstVideoRectangle *dst_rect, + guint flags +); + +G_END_DECLS + +#endif /* GST_VAAPI_WINDOW_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c new file mode 100644 index 0000000000..c995a49e00 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -0,0 +1,448 @@ +/* + * gstvaapiwindow_x11.c - VA/X11 window abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "gstvaapiwindow_x11.h" +#include "gstvaapidisplay_x11.h" + +#define DEBUG 1 +#include "vaapi_debug.h" + +G_DEFINE_TYPE(GstVaapiWindowX11, gst_vaapi_window_x11, GST_VAAPI_TYPE_WINDOW); + +#define GST_VAAPI_WINDOW_X11_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_WINDOW_X11, \ + GstVaapiWindowX11Private)) + +struct _GstVaapiWindowX11Private { + gboolean create_window; + GstVaapiDisplay *display; + Window xid; +}; + +enum { + PROP_0, + + PROP_DISPLAY, + PROP_XID, +}; + +// X error trap +static int x11_error_code = 0; +static int (*old_error_handler)(Display *, XErrorEvent *); + +static int error_handler(Display *dpy, XErrorEvent *error) +{ + x11_error_code = error->error_code; + return 0; +} + +static void x11_trap_errors(void) +{ + x11_error_code = 0; + old_error_handler = XSetErrorHandler(error_handler); +} + +static int x11_untrap_errors(void) +{ + XSetErrorHandler(old_error_handler); + return x11_error_code; +} + +// X window management +static const int x11_event_mask = (KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask | + EnterWindowMask | + ExposureMask | + StructureNotifyMask); + +static Window +x11_create_window(Display *display, unsigned int width, unsigned int height) +{ + Window root_window, window; + int screen, depth; + Visual *vis; + XSetWindowAttributes xswa; + unsigned long xswa_mask; + XWindowAttributes wattr; + unsigned long black_pixel, white_pixel; + + screen = DefaultScreen(display); + vis = DefaultVisual(display, screen); + root_window = RootWindow(display, screen); + black_pixel = BlackPixel(display, screen); + white_pixel = WhitePixel(display, screen); + + XGetWindowAttributes(display, root_window, &wattr); + depth = wattr.depth; + if (depth != 15 && depth != 16 && depth != 24 && depth != 32) + depth = 24; + + xswa_mask = CWBorderPixel | CWBackPixel; + xswa.border_pixel = black_pixel; + xswa.background_pixel = white_pixel; + + window = XCreateWindow( + display, + root_window, + 0, 0, width, height, + 0, + depth, + InputOutput, + vis, + xswa_mask, &xswa + ); + if (window) + XSelectInput(display, window, x11_event_mask); + return window; +} + +static gboolean +x11_get_geometry( + Display *dpy, + Drawable drawable, + gint *px, + gint *py, + guint *pwidth, + guint *pheight +) +{ + Window rootwin; + int x, y; + unsigned int width, height, border_width, depth; + + x11_trap_errors(); + XGetGeometry( + dpy, + drawable, + &rootwin, + &x, &y, &width, &height, + &border_width, + &depth + ); + if (x11_untrap_errors()) + return FALSE; + + if (px) *px = x; + if (py) *py = y; + if (pwidth) *pwidth = width; + if (pheight) *pheight = height; + return TRUE; +} + +static void x11_wait_event(Display *dpy, Window w, int type) +{ + XEvent e; + while (!XCheckTypedWindowEvent(dpy, w, type, &e)) + g_usleep(10); +} + +static gboolean +gst_vaapi_window_x11_create(GstVaapiWindow *window, guint width, guint height) +{ + GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + Display *dpy; + + if (!priv->create_window && priv->xid) + return TRUE; + + dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + priv->xid = x11_create_window(dpy, width, height); + + XMapRaised(dpy, priv->xid); + x11_wait_event(dpy, priv->xid, MapNotify); + return TRUE; +} + +static void +gst_vaapi_window_x11_destroy(GstVaapiWindow *window) +{ + GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + + if (priv->create_window && priv->xid) { + XUnmapWindow(dpy, priv->xid); + x11_wait_event(dpy, priv->xid, UnmapNotify); + XDestroyWindow(dpy, priv->xid); + priv->xid = None; + } + + g_object_unref(priv->display); + priv->display = NULL; +} + +static gboolean +gst_vaapi_window_x11_show(GstVaapiWindow *window) +{ + GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + + x11_trap_errors(); + XMapWindow(dpy, priv->xid); + x11_wait_event(dpy, priv->xid, MapNotify); + return x11_untrap_errors() == 0; +} + +static gboolean +gst_vaapi_window_x11_hide(GstVaapiWindow *window) +{ + GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + + x11_trap_errors(); + XUnmapWindow(dpy, priv->xid); + x11_wait_event(dpy, priv->xid, UnmapNotify); + return x11_untrap_errors() == 0; +} + +static gboolean +gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height) +{ + GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + + if (!priv->xid) + return FALSE; + + x11_trap_errors(); + XResizeWindow( + GST_VAAPI_DISPLAY_XDISPLAY(priv->display), + priv->xid, + width, + height + ); + if (x11_untrap_errors() != 0) + return FALSE; + return TRUE; +} + +static gboolean +gst_vaapi_window_x11_render( + GstVaapiWindow *window, + GstVaapiSurface *surface, + const GstVideoRectangle *src_rect, + const GstVideoRectangle *dst_rect, + guint flags +) +{ + VASurfaceID surface_id; + VAStatus status; + unsigned int va_flags = 0; + + surface_id = gst_vaapi_surface_get_id(surface); + if (surface_id == VA_INVALID_ID) + return FALSE; + + if (flags & GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) + va_flags |= VA_TOP_FIELD; + if (flags & GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) + va_flags |= VA_BOTTOM_FIELD; + if ((va_flags ^ (VA_TOP_FIELD|VA_BOTTOM_FIELD)) == 0) + va_flags = VA_FRAME_PICTURE; + + if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_709) + va_flags |= VA_SRC_BT709; + else if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_601) + va_flags |= VA_SRC_BT601; + + status = vaPutSurface( + GST_VAAPI_DISPLAY_VADISPLAY(gst_vaapi_surface_get_display(surface)), + surface_id, + GST_VAAPI_WINDOW_X11(window)->priv->xid, + src_rect->x, + src_rect->y, + src_rect->w, + src_rect->h, + dst_rect->x, + dst_rect->y, + dst_rect->w, + dst_rect->h, + NULL, 0, + va_flags + ); + if (!vaapi_check_status(status, "vaPutSurface()")) + return FALSE; + + return TRUE; +} + +static void +gst_vaapi_window_x11_finalize(GObject *object) +{ + G_OBJECT_CLASS(gst_vaapi_window_x11_parent_class)->finalize(object); +} + +static void +gst_vaapi_window_x11_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiWindowX11 * const window = GST_VAAPI_WINDOW_X11(object); + + switch (prop_id) { + case PROP_DISPLAY: + window->priv->display = g_object_ref(g_value_get_object(value)); + break; + case PROP_XID: + window->priv->xid = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_window_x11_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiWindowX11 * const window = GST_VAAPI_WINDOW_X11(object); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_object(value, window->priv->display); + break; + case PROP_XID: + g_value_set_uint(value, gst_vaapi_window_x11_get_xid(window)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_window_x11_constructed(GObject *object) +{ + GstVaapiWindowX11 * const window = GST_VAAPI_WINDOW_X11(object); + GObjectClass *parent_class; + + window->priv->create_window = window->priv->xid == None; + + parent_class = G_OBJECT_CLASS(gst_vaapi_window_x11_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + +static void +gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiWindowClass * const window_class = GST_VAAPI_WINDOW_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiWindowX11Private)); + + object_class->finalize = gst_vaapi_window_x11_finalize; + object_class->set_property = gst_vaapi_window_x11_set_property; + object_class->get_property = gst_vaapi_window_x11_get_property; + object_class->constructed = gst_vaapi_window_x11_constructed; + + window_class->create = gst_vaapi_window_x11_create; + window_class->destroy = gst_vaapi_window_x11_destroy; + window_class->show = gst_vaapi_window_x11_show; + window_class->hide = gst_vaapi_window_x11_hide; + window_class->resize = gst_vaapi_window_x11_resize; + window_class->render = gst_vaapi_window_x11_render; + + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_object("display", + "display", + "Display", + GST_VAAPI_TYPE_DISPLAY, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_XID, + g_param_spec_uint("xid", + "X window id", + "X window ID", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_window_x11_init(GstVaapiWindowX11 *window) +{ + GstVaapiWindowX11Private *priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); + + window->priv = priv; + priv->create_window = TRUE; + priv->display = NULL; + priv->xid = None; +} + +GstVaapiWindow * +gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) +{ + GST_DEBUG("new window, size %ux%u", width, height); + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(height > 0, NULL); + + return g_object_new(GST_VAAPI_TYPE_WINDOW_X11, + "display", display, + "width", width, + "height", height, + NULL); +} + +GstVaapiWindow * +gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) +{ + Display *dpy; + guint width, height; + + GST_DEBUG("new window from xid 0x%08x", xid); + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + dpy = GST_VAAPI_DISPLAY_XDISPLAY(display); + if (!dpy || !x11_get_geometry(dpy, xid, NULL, NULL, &width, &height)) + return NULL; + + return g_object_new(GST_VAAPI_TYPE_WINDOW_X11, + "display", display, + "xid", xid, + "width", width, + "height", height, + NULL); +} + +Window +gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window) +{ + g_return_val_if_fail(GST_VAAPI_WINDOW_X11(window), None); + + return window->priv->xid; +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h new file mode 100644 index 0000000000..c1af6ec7a8 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -0,0 +1,84 @@ +/* + * gstvaapiwindow_x11.h - VA/X11 window abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_WINDOW_X11_H +#define GST_VAAPI_WINDOW_X11_H + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_WINDOW_X11 \ + (gst_vaapi_window_x11_get_type()) + +#define GST_VAAPI_WINDOW_X11(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_WINDOW_X11, \ + GstVaapiWindowX11)) + +#define GST_VAAPI_WINDOW_X11_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_WINDOW_X11, \ + GstVaapiWindowX11Class)) + +#define GST_VAAPI_IS_WINDOW_X11(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW_X11)) + +#define GST_VAAPI_IS_WINDOW_X11_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW_X11)) + +#define GST_VAAPI_WINDOW_X11_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_WINDOW_X11, \ + GstVaapiWindowX11Class)) + +typedef struct _GstVaapiWindowX11 GstVaapiWindowX11; +typedef struct _GstVaapiWindowX11Private GstVaapiWindowX11Private; +typedef struct _GstVaapiWindowX11Class GstVaapiWindowX11Class; + +struct _GstVaapiWindowX11 { + /*< private >*/ + GstVaapiWindow parent_instance; + + GstVaapiWindowX11Private *priv; +}; + +struct _GstVaapiWindowX11Class { + /*< private >*/ + GstVaapiWindowClass parent_class; +}; + +GType +gst_vaapi_window_x11_get_type(void); + +GstVaapiWindow * +gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height); + +GstVaapiWindow * +gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid); + +Window +gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window); + +G_END_DECLS + +#endif /* GST_VAAPI_WINDOW_X11_H */ diff --git a/tests/examples/generic/Makefile.am b/tests/examples/generic/Makefile.am index a914fff57d..cc7cdcf6a2 100644 --- a/tests/examples/generic/Makefile.am +++ b/tests/examples/generic/Makefile.am @@ -1,6 +1,7 @@ noinst_PROGRAMS = \ test-display \ test-surfaces \ + test-windows \ $(NULL) TEST_CFLAGS = \ @@ -20,5 +21,9 @@ test_surfaces_SOURCES = test-surfaces.c test_surfaces_CFLAGS = $(TEST_CFLAGS) test_surfaces_LDADD = $(TEST_LIBS) +test_windows_SOURCES = test-windows.c +test_windows_CFLAGS = $(TEST_CFLAGS) +test_windows_LDADD = $(TEST_LIBS) + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/examples/generic/test-windows.c b/tests/examples/generic/test-windows.c new file mode 100644 index 0000000000..bd3f106759 --- /dev/null +++ b/tests/examples/generic/test-windows.c @@ -0,0 +1,120 @@ +/* + * test-windows.c - Test GstVaapiWindow + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include + +static inline void pause(void) +{ + g_print("Press any key to continue...\n"); + getchar(); +} + +int +main(int argc, char *argv[]) +{ + GstVaapiDisplay *display; + GstVaapiWindow *window; + GstVaapiSurface *surface; + GstVaapiImage *image; + guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + + static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + static const guint width = 320; + static const guint height = 240; + static const guint win_width = 640; + static const guint win_height = 480; + + gst_init(&argc, &argv); + + display = gst_vaapi_display_x11_new(NULL); + if (!display) + g_error("could not create Gst/VA display"); + + surface = gst_vaapi_surface_new(display, chroma_type, width, height); + if (!surface) + g_error("could not create Gst/VA surface"); + + image = gst_vaapi_image_new(display, GST_VAAPI_IMAGE_NV12, width, height); + if (!image) + g_error("could not create Gst/VA image"); + + g_print("#\n"); + g_print("# Create window with gst_vaapi_window_x11_new()\n"); + g_print("#\n"); + { + window = gst_vaapi_window_x11_new(display, win_width, win_height); + if (!window) + g_error("could not create window"); + + if (!gst_vaapi_window_put_surface(window, surface, flags)) + g_error("could not render surface"); + + pause(); + g_object_unref(window); + } + + g_print("#\n"); + g_print("# Create window with gst_vaapi_window_x11_new_with_xid()\n"); + g_print("#\n"); + { + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(display); + Window rootwin, win; + int screen; + unsigned long white_pixel, black_pixel; + + screen = DefaultScreen(dpy); + rootwin = RootWindow(dpy, screen); + white_pixel = WhitePixel(dpy, screen); + black_pixel = BlackPixel(dpy, screen); + win = XCreateSimpleWindow( + dpy, + rootwin, + 0, 0, win_width, win_height, + 0, black_pixel, + white_pixel + ); + if (!win) + g_error("could not create X window"); + + XMapRaised(dpy, win); + XSync(dpy, False); + + window = gst_vaapi_window_x11_new_with_xid(display, win); + if (!window) + g_error("could not create window"); + + if (!gst_vaapi_window_put_surface(window, surface, flags)) + g_error("could not render surface"); + + pause(); + g_object_unref(window); + XUnmapWindow(dpy, win); + XDestroyWindow(dpy, win); + } + + g_object_unref(image); + g_object_unref(surface); + g_object_unref(display); + gst_deinit(); + return 0; +} From eca4c7da428f284ce89e9ad62d6c7d7569299e79 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 15:55:20 +0000 Subject: [PATCH 0048/3781] Cosmetics. --- gst-libs/gst/vaapi/gstvaapiimage.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapiimage.h | 10 +++++++--- gst-libs/gst/vaapi/gstvaapisurface.c | 8 ++++---- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 564858e77b..75d8c677d5 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -273,7 +273,8 @@ gst_vaapi_image_new( g_return_val_if_fail(width > 0, NULL); g_return_val_if_fail(height > 0, NULL); - GST_DEBUG("size %ux%u, format 0x%x", width, height, format); + GST_DEBUG("size %ux%u, format %" GST_FOURCC_FORMAT, + width, height, GST_FOURCC_ARGS(format)); return g_object_new(GST_VAAPI_TYPE_IMAGE, "display", display, @@ -301,6 +302,15 @@ gst_vaapi_image_get_display(GstVaapiImage *image) return image->priv->display; } +GstVaapiImageFormat +gst_vaapi_image_get_format(GstVaapiImage *image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image->priv->is_constructed, FALSE); + + return image->priv->format; +} + guint gst_vaapi_image_get_width(GstVaapiImage *image) { @@ -332,15 +342,6 @@ gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) *pheight = image->priv->height; } -guint -gst_vaapi_image_get_format(GstVaapiImage *image) -{ - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); - g_return_val_if_fail(image->priv->is_constructed, FALSE); - - return image->priv->format; -} - static inline gboolean _gst_vaapi_image_is_mapped(GstVaapiImage *image) { diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index eb8f37b125..21d41cce46 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -51,6 +51,10 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_IMAGE, \ GstVaapiImageClass)) +#define GST_VAAPI_IMAGE_FORMAT(img) gst_vaapi_image_get_format(img) +#define GST_VAAPI_IMAGE_WIDTH(img) gst_vaapi_image_get_width(img) +#define GST_VAAPI_IMAGE_HEIGHT(img) gst_vaapi_image_get_height(img) + typedef struct _GstVaapiImage GstVaapiImage; typedef struct _GstVaapiImagePrivate GstVaapiImagePrivate; typedef struct _GstVaapiImageClass GstVaapiImageClass; @@ -84,6 +88,9 @@ gst_vaapi_image_get_id(GstVaapiImage *image); GstVaapiDisplay * gst_vaapi_image_get_display(GstVaapiImage *image); +GstVaapiImageFormat +gst_vaapi_image_get_format(GstVaapiImage *image); + guint gst_vaapi_image_get_width(GstVaapiImage *image); @@ -93,9 +100,6 @@ gst_vaapi_image_get_height(GstVaapiImage *image); void gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight); -guint -gst_vaapi_image_get_format(GstVaapiImage *image); - gboolean gst_vaapi_image_is_mapped(GstVaapiImage *image); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 4f859f0237..76f431fcfb 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -55,7 +55,7 @@ static void gst_vaapi_surface_destroy(GstVaapiSurface *surface) { GstVaapiSurfacePrivate * const priv = surface->priv; - VADisplay dpy = gst_vaapi_display_get_display(priv->display); + VADisplay dpy = GST_VAAPI_DISPLAY_VADISPLAY(priv->display); VAStatus status; if (priv->surface_id != VA_INVALID_SURFACE) { @@ -95,7 +95,7 @@ gst_vaapi_surface_create(GstVaapiSurface *surface) } status = vaCreateSurfaces( - gst_vaapi_display_get_display(priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(priv->display), priv->width, priv->height, format, @@ -355,7 +355,7 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) return FALSE; status = vaGetImage( - gst_vaapi_display_get_display(surface->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), surface->priv->surface_id, 0, 0, width, height, image_id @@ -385,7 +385,7 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) return FALSE; status = vaPutImage( - gst_vaapi_display_get_display(surface->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), surface->priv->surface_id, image_id, 0, 0, width, height, From 17d221d7d68afc24f64d4f84737756ad453fd844 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 16:13:37 +0000 Subject: [PATCH 0049/3781] Cosmetics (reverse args order). --- gst-libs/gst/vaapi/gstvaapiimage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 75d8c677d5..038983a2e6 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -273,8 +273,8 @@ gst_vaapi_image_new( g_return_val_if_fail(width > 0, NULL); g_return_val_if_fail(height > 0, NULL); - GST_DEBUG("size %ux%u, format %" GST_FOURCC_FORMAT, - width, height, GST_FOURCC_ARGS(format)); + GST_DEBUG("format %" GST_FOURCC_FORMAT ", size %ux%u", + GST_FOURCC_ARGS(format), width, height); return g_object_new(GST_VAAPI_TYPE_IMAGE, "display", display, From 606c0162633f1ad517ca3ea78672293a46c3fbfd Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 16:13:51 +0000 Subject: [PATCH 0050/3781] Add gst_vaapi_surface_sync(). --- gst-libs/gst/vaapi/gstvaapisurface.c | 17 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 76f431fcfb..0858c17ed6 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -396,3 +396,20 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) return TRUE; } + +gboolean +gst_vaapi_surface_sync(GstVaapiSurface *surface) +{ + VAStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + + status = vaSyncSurface( + GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), + surface->priv->surface_id + ); + if (!vaapi_check_status(status, "vaSyncSurface()")) + return FALSE; + + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 445ca8f56f..1d6d4f7b34 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -113,6 +113,9 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image); gboolean gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image); +gboolean +gst_vaapi_surface_sync(GstVaapiSurface *surface); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_H */ From 09ab81d85ea0e79c7944294450d4ed9493d16419 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 16:57:01 +0000 Subject: [PATCH 0051/3781] Generate R/G/B rects. --- tests/examples/generic/test-windows.c | 149 +++++++++++++++++++++++++- 1 file changed, 148 insertions(+), 1 deletion(-) diff --git a/tests/examples/generic/test-windows.c b/tests/examples/generic/test-windows.c index bd3f106759..07db884d76 100644 --- a/tests/examples/generic/test-windows.c +++ b/tests/examples/generic/test-windows.c @@ -29,6 +29,145 @@ static inline void pause(void) getchar(); } +typedef void (*DrawRectFunc)( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +); + +static void draw_rect_NV12( // Y, UV planes + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + const guchar Y = color >> 16; + const guchar Cb = color >> 8; + const guchar Cr = color; + guchar *dst; + guint i, j; + + dst = pixels[0] + y * stride[0] + x; + for (j = 0; j < height; j++, dst += stride[0]) + for (i = 0; i < width; i++) + dst[i] = Y; + + x /= 2; + y /= 2; + width /= 2; + height /= 2; + + dst = pixels[1] + y * stride[1] + x * 2; + for (j = 0; j < height; j++, dst += stride[1]) + for (i = 0; i < width; i++) { + dst[2*i + 0] = Cb; + dst[2*i + 1] = Cr; + } +} + +static void draw_rect_YV12( // Y, U, V planes + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + const guchar Y = color >> 16; + const guchar Cb = color >> 8; + const guchar Cr = color; + guchar *pY, *pU, *pV; + guint i, j; + + pY = pixels[0] + y * stride[0] + x; + for (j = 0; j < height; j++, pY += stride[0]) + for (i = 0; i < width; i++) + pY[i] = Y; + + x /= 2; + y /= 2; + width /= 2; + height /= 2; + + pU = pixels[1] + y * stride[1] + x; + pV = pixels[2] + y * stride[2] + x; + for (j = 0; j < height; j++, pU += stride[1], pV += stride[2]) + for (i = 0; i < width; i++) { + pU[i] = Cb; + pV[i] = Cr; + } +} + +static gboolean draw_rgb_rects(GstVaapiImage *image) +{ + GstVaapiImageFormat format = GST_VAAPI_IMAGE_FORMAT(image); + guint w = GST_VAAPI_IMAGE_WIDTH(image); + guint h = GST_VAAPI_IMAGE_HEIGHT(image); + guchar *pixels[3]; + guint stride[3]; + guint32 red_color, green_color, blue_color, black_color; + DrawRectFunc draw_rect; + + if (!gst_vaapi_image_map(image)) + return FALSE; + + switch (format) { + case GST_VAAPI_IMAGE_NV12: + draw_rect = draw_rect_NV12; + pixels[0] = gst_vaapi_image_get_plane(image, 0); + stride[0] = gst_vaapi_image_get_pitch(image, 0); + pixels[1] = gst_vaapi_image_get_plane(image, 1); + stride[1] = gst_vaapi_image_get_pitch(image, 1); + goto YUV_colors; + case GST_VAAPI_IMAGE_YV12: + draw_rect = draw_rect_YV12; + pixels[0] = gst_vaapi_image_get_plane(image, 0); + stride[0] = gst_vaapi_image_get_pitch(image, 0); + pixels[1] = gst_vaapi_image_get_plane(image, 2); + stride[1] = gst_vaapi_image_get_pitch(image, 2); + pixels[2] = gst_vaapi_image_get_plane(image, 1); + stride[2] = gst_vaapi_image_get_pitch(image, 1); + goto YUV_colors; + case GST_VAAPI_IMAGE_I420: + draw_rect = draw_rect_YV12; + pixels[0] = gst_vaapi_image_get_plane(image, 0); + stride[0] = gst_vaapi_image_get_pitch(image, 0); + pixels[1] = gst_vaapi_image_get_plane(image, 1); + stride[1] = gst_vaapi_image_get_pitch(image, 1); + pixels[2] = gst_vaapi_image_get_plane(image, 2); + stride[2] = gst_vaapi_image_get_pitch(image, 2); + YUV_colors: + red_color = 0x515af0; + green_color = 0x913622; + blue_color = 0x29f06e; + black_color = 0x108080; + break; + default: + gst_vaapi_image_unmap(image); + return FALSE; + } + + draw_rect(pixels, stride, 0, 0, w/2, h/2, red_color); + draw_rect(pixels, stride, w/2, 0, w/2, h/2, green_color); + draw_rect(pixels, stride, 0, h/2, w/2, h/2, blue_color); + draw_rect(pixels, stride, w/2, h/2, w/2, h/2, black_color); + + if (!gst_vaapi_image_unmap(image)) + return FALSE; + + return TRUE; +} + int main(int argc, char *argv[]) { @@ -57,6 +196,13 @@ main(int argc, char *argv[]) image = gst_vaapi_image_new(display, GST_VAAPI_IMAGE_NV12, width, height); if (!image) g_error("could not create Gst/VA image"); + if (!draw_rgb_rects(image)) + g_error("could not draw RGB rectangels"); + + if (!gst_vaapi_surface_put_image(surface, image)) + g_error("could not upload image"); + if (!gst_vaapi_surface_sync(surface)) + g_error("could not complete image upload"); g_print("#\n"); g_print("# Create window with gst_vaapi_window_x11_new()\n"); @@ -86,7 +232,8 @@ main(int argc, char *argv[]) rootwin = RootWindow(dpy, screen); white_pixel = WhitePixel(dpy, screen); black_pixel = BlackPixel(dpy, screen); - win = XCreateSimpleWindow( + + win = XCreateSimpleWindow( dpy, rootwin, 0, 0, win_width, win_height, From f8c91368e93f852222cbdc35221ce2747ceb0895 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 16:57:37 +0000 Subject: [PATCH 0052/3781] Factor out. --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 77 +++++++++++++------------ 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index c995a49e00..ad5cc3a655 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -113,8 +113,10 @@ x11_create_window(Display *display, unsigned int width, unsigned int height) vis, xswa_mask, &xswa ); - if (window) - XSelectInput(display, window, x11_event_mask); + if (!window) + return None; + + XSelectInput(display, window, x11_event_mask); return window; } @@ -158,40 +160,6 @@ static void x11_wait_event(Display *dpy, Window w, int type) g_usleep(10); } -static gboolean -gst_vaapi_window_x11_create(GstVaapiWindow *window, guint width, guint height) -{ - GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; - Display *dpy; - - if (!priv->create_window && priv->xid) - return TRUE; - - dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - priv->xid = x11_create_window(dpy, width, height); - - XMapRaised(dpy, priv->xid); - x11_wait_event(dpy, priv->xid, MapNotify); - return TRUE; -} - -static void -gst_vaapi_window_x11_destroy(GstVaapiWindow *window) -{ - GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - - if (priv->create_window && priv->xid) { - XUnmapWindow(dpy, priv->xid); - x11_wait_event(dpy, priv->xid, UnmapNotify); - XDestroyWindow(dpy, priv->xid); - priv->xid = None; - } - - g_object_unref(priv->display); - priv->display = NULL; -} - static gboolean gst_vaapi_window_x11_show(GstVaapiWindow *window) { @@ -216,6 +184,43 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) return x11_untrap_errors() == 0; } +static gboolean +gst_vaapi_window_x11_create(GstVaapiWindow *window, guint width, guint height) +{ + GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + Display *dpy; + + if (!priv->create_window && priv->xid) + return TRUE; + + dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + priv->xid = x11_create_window(dpy, width, height); + + if (!gst_vaapi_window_x11_show(window)) + return FALSE; + + x11_trap_errors(); + XRaiseWindow(dpy, priv->xid); + XSync(dpy, False); + return x11_untrap_errors() == 0; +} + +static void +gst_vaapi_window_x11_destroy(GstVaapiWindow *window) +{ + GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + + if (priv->create_window && priv->xid) { + gst_vaapi_window_x11_hide(window); + XDestroyWindow(dpy, priv->xid); + priv->xid = None; + } + + g_object_unref(priv->display); + priv->display = NULL; +} + static gboolean gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height) { From 271d8334ba23b9a1f99aadd3144ba4b016b121fb Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 17:09:12 +0000 Subject: [PATCH 0053/3781] Display frames. --- sys/vaapisink/gstvaapisink.c | 73 ++++++++++++++++++++++++++++++++++-- sys/vaapisink/gstvaapisink.h | 2 + 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 1e7258057d..8853cb31b7 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -20,8 +20,10 @@ #include "config.h" #include +#include #include #include +#include #include "gstvaapisink.h" #define GST_PLUGIN_NAME "vaapisink" @@ -98,6 +100,67 @@ gst_vaapisink_destroy(GstVaapiSink *sink) } } +static inline gboolean +gst_vaapisink_ensure_display(GstVaapiSink *sink) +{ + if (!sink->display) + sink->display = gst_vaapi_display_x11_new(sink->display_name); + return sink->display != NULL; +} + +static gboolean +gst_vaapisink_start(GstBaseSink *base_sink) +{ + GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + + if (!gst_vaapisink_ensure_display(sink)) + return FALSE; + return TRUE; +} + +static gboolean +gst_vaapisink_stop(GstBaseSink *base_sink) +{ + GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + + if (sink->window) { + g_object_unref(sink->window); + sink->window = NULL; + } + + if (sink->display) { + g_object_unref(sink->display); + sink->display = NULL; + } + return TRUE; +} + +static GstFlowReturn +gst_vaapisink_show_frame(GstVideoSink *video_sink, GstBuffer *buffer) +{ + GstVaapiSink * const sink = GST_VAAPISINK(video_sink); + GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); + GstVaapiSurface *surface; + guint width, height, flags; + + surface = gst_vaapi_video_buffer_get_surface(vbuffer); + if (!surface) + return GST_FLOW_UNEXPECTED; + + gst_vaapi_surface_get_size(surface, &width, &height); + if (!sink->window) { + sink->window = gst_vaapi_window_x11_new(sink->display, width, height); + if (!sink->window) + return GST_FLOW_UNEXPECTED; + } + + flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + if (!gst_vaapi_window_put_surface(sink->window, surface, flags)) + return GST_FLOW_UNEXPECTED; + + return GST_FLOW_OK; +} + static void gst_vaapisink_finalize(GObject *object) { @@ -165,7 +228,6 @@ static void gst_vaapisink_base_init(gpointer klass) static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass); GstVideoSinkClass * const videosink_class = GST_VIDEO_SINK_CLASS(klass); @@ -173,6 +235,11 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) object_class->set_property = gst_vaapisink_set_property; object_class->get_property = gst_vaapisink_get_property; + basesink_class->start = gst_vaapisink_start; + basesink_class->stop = gst_vaapisink_stop; + + videosink_class->show_frame = gst_vaapisink_show_frame; + g_object_class_install_property (object_class, PROP_DISPLAY, @@ -201,8 +268,8 @@ static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) GstVaapiDisplay * gst_vaapisink_get_display(GstVaapiSink *sink) { - if (!sink->display) - sink->display = gst_vaapi_display_x11_new(sink->display_name); + if (!gst_vaapisink_ensure_display(sink)) + return NULL; return sink->display; } diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h index c0291adeb4..bc04bfac40 100644 --- a/sys/vaapisink/gstvaapisink.h +++ b/sys/vaapisink/gstvaapisink.h @@ -23,6 +23,7 @@ #include #include +#include #include G_BEGIN_DECLS @@ -60,6 +61,7 @@ struct _GstVaapiSink { gchar *display_name; GstVaapiDisplay *display; + GstVaapiWindow *window; }; struct _GstVaapiSinkClass { From 56820b2bc126123e12cd699338c05fd9b6448afc Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 17:10:56 +0000 Subject: [PATCH 0054/3781] Add initial vaapiconvert plugin. --- sys/vaapiconvert/Makefile.am | 10 + sys/vaapiconvert/gstvaapiconvert.c | 350 +++++++++++++++++++++++++++-- sys/vaapiconvert/gstvaapiconvert.h | 21 +- 3 files changed, 364 insertions(+), 17 deletions(-) diff --git a/sys/vaapiconvert/Makefile.am b/sys/vaapiconvert/Makefile.am index 1cb2dbe804..74e3d37872 100644 --- a/sys/vaapiconvert/Makefile.am +++ b/sys/vaapiconvert/Makefile.am @@ -1,5 +1,11 @@ plugin_LTLIBRARIES = libgstvaapiconvert.la +libgstvaapi_CFLAGS = \ + -I$(top_srcdir)/gst-libs + +libgstvaapi_LIBS = \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la + libgstvaapiconvert_la_SOURCES = \ gstvaapiconvert.c \ $(NULL) @@ -9,13 +15,17 @@ noinst_HEADERS = \ $(NULL) libgstvaapiconvert_la_CFLAGS = \ + $(libgstvaapi_CFLAGS) \ $(GST_CFLAGS) \ $(GST_BASE_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ $(GST_PLUGINS_BASE_CFLAGS) libgstvaapiconvert_la_LIBADD = \ + $(libgstvaapi_LIBS) \ $(GST_LIBS) \ $(GST_BASE_LIBS) \ + $(GST_VIDEO_LIBS) \ $(GST_PLUGINS_BASE_LIBS) libgstvaapiconvert_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index 4ac789adb6..778ff6b29a 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -20,8 +20,16 @@ #include "config.h" #include +#include +#include #include "gstvaapiconvert.h" +#define GST_PLUGIN_NAME "vaapiconvert" +#define GST_PLUGIN_DESC "A VA-API based video pixels format converter" + +GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapiconvert); +#define GST_CAT_DEFAULT gst_debug_vaapiconvert + /* ElementFactory information */ static const GstElementDetails gst_vaapiconvert_details = GST_ELEMENT_DETAILS( @@ -31,25 +39,29 @@ static const GstElementDetails gst_vaapiconvert_details = "Gwenole Beauchesne "); /* Default templates */ +static const char gst_vaapiconvert_yuv_caps_str[] = + "video/x-raw-yuv, " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]; "; + +static const char gst_vaapiconvert_vaapi_caps_str[] = + "video/x-vaapi-surface, " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]; "; + static GstStaticPadTemplate gst_vaapiconvert_sink_factory = GST_STATIC_PAD_TEMPLATE( "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS( - "video/x-raw-yuv, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; ")); + GST_STATIC_CAPS(gst_vaapiconvert_yuv_caps_str)); static GstStaticPadTemplate gst_vaapiconvert_src_factory = GST_STATIC_PAD_TEMPLATE( "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS( - "video/x-vaapi-surface, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; ")); + GST_STATIC_CAPS(gst_vaapiconvert_vaapi_caps_str)); GST_BOILERPLATE( GstVaapiConvert, @@ -57,6 +69,9 @@ GST_BOILERPLATE( GstBaseTransform, GST_TYPE_BASE_TRANSFORM); +static gboolean gst_vaapiconvert_start(GstBaseTransform *trans); +static gboolean gst_vaapiconvert_stop(GstBaseTransform *trans); + static GstFlowReturn gst_vaapiconvert_transform( GstBaseTransform *trans, @@ -64,33 +79,158 @@ gst_vaapiconvert_transform( GstBuffer *outbuf ); +static GstCaps * +gst_vaapiconvert_transform_caps( + GstBaseTransform *trans, + GstPadDirection direction, + GstCaps *caps +); + +static gboolean +gst_vaapiconvert_set_caps( + GstBaseTransform *trans, + GstCaps *incaps, + GstCaps *outcaps +); + +static gboolean +gst_vaapiconvert_get_unit_size( + GstBaseTransform *trans, + GstCaps *caps, + guint *size +); + +static GstFlowReturn +gst_vaapiconvert_sinkpad_buffer_alloc( + GstPad *pad, + guint64 offset, + guint size, + GstCaps *caps, + GstBuffer **pbuf +); + +static GstFlowReturn +gst_vaapiconvert_prepare_output_buffer( + GstBaseTransform *trans, + GstBuffer *inbuf, + gint size, + GstCaps *caps, + GstBuffer **poutbuf +); + +static void +gst_vaapiconvert_destroy(GstVaapiConvert *convert) +{ + if (convert->images) { + g_object_unref(convert->images); + convert->images = NULL; + } + + if (convert->surfaces) { + g_object_unref(convert->surfaces); + convert->surfaces = NULL; + } + + if (convert->display) { + g_object_unref(convert->display); + convert->display = NULL; + } +} + static void gst_vaapiconvert_base_init(gpointer klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); gst_element_class_set_details(element_class, &gst_vaapiconvert_details); + /* sink pad */ gst_element_class_add_pad_template( element_class, gst_static_pad_template_get(&gst_vaapiconvert_sink_factory) ); + + /* src pad */ gst_element_class_add_pad_template( element_class, gst_static_pad_template_get(&gst_vaapiconvert_src_factory) ); } -static void gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) +static void +gst_vaapiconvert_finalize(GObject *object) +{ + gst_vaapiconvert_destroy(GST_VAAPICONVERT(object)); + + G_OBJECT_CLASS(parent_class)->finalize(object); +} + +static void +gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); - trans_class->transform = GST_DEBUG_FUNCPTR(gst_vaapiconvert_transform); + object_class->finalize = gst_vaapiconvert_finalize; + + trans_class->start = gst_vaapiconvert_start; + trans_class->stop = gst_vaapiconvert_stop; + trans_class->transform = gst_vaapiconvert_transform; + trans_class->transform_caps = gst_vaapiconvert_transform_caps; + trans_class->set_caps = gst_vaapiconvert_set_caps; + trans_class->get_unit_size = gst_vaapiconvert_get_unit_size; + trans_class->prepare_output_buffer = gst_vaapiconvert_prepare_output_buffer; } static void gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) { + GstPad *sinkpad; + + convert->display = NULL; + convert->images = NULL; + convert->image_width = 0; + convert->image_height = 0; + convert->surfaces = NULL; + convert->surface_width = 0; + convert->surface_height = 0; + + /* Override buffer allocator on sink pad */ + sinkpad = gst_element_get_static_pad(GST_ELEMENT(convert), "sink"); + gst_pad_set_bufferalloc_function( + sinkpad, + gst_vaapiconvert_sinkpad_buffer_alloc + ); + g_object_unref(sinkpad); +} + +static gboolean gst_vaapiconvert_start(GstBaseTransform *trans) +{ + GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstVaapiSinkBase *sink; + GstVaapiDisplay *display; + + /* Look for a downstream vaapisink */ + sink = gst_vaapisink_base_lookup(GST_ELEMENT(trans)); + if (!sink) + return FALSE; + + display = gst_vaapisink_base_get_display(sink); + if (!display) + return FALSE; + + convert->display = g_object_ref(display); + return TRUE; +} + +static gboolean gst_vaapiconvert_stop(GstBaseTransform *trans) +{ + GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + + if (convert->display) { + g_object_unref(convert->display); + convert->display = NULL; + } + return TRUE; } static GstFlowReturn @@ -100,21 +240,205 @@ gst_vaapiconvert_transform( GstBuffer *outbuf ) { + GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(outbuf); + GstVaapiSurface *surface; + GstVaapiImage *image; + + image = gst_vaapi_video_pool_get_object(convert->images); + if (!image) + return GST_FLOW_UNEXPECTED; + + surface = gst_vaapi_video_buffer_get_surface(vbuffer); + if (!surface) + return GST_FLOW_UNEXPECTED; + + gst_vaapi_image_update_from_buffer(image, inbuf); + gst_vaapi_surface_put_image(surface, image); + gst_vaapi_video_pool_put_object(convert->images, image); + return GST_FLOW_OK; +} + +static GstCaps * +gst_vaapiconvert_transform_caps( + GstBaseTransform *trans, + GstPadDirection direction, + GstCaps *caps +) +{ + GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstCaps *out_caps = NULL; + GstStructure *structure; + const GValue *v_width, *v_height, *v_framerate, *v_par; + + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + structure = gst_caps_get_structure(caps, 0); + v_width = gst_structure_get_value(structure, "width"); + v_height = gst_structure_get_value(structure, "height"); + v_framerate = gst_structure_get_value(structure, "framerate"); + v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); + + if (!v_width || !v_height) + return NULL; + + if (direction == GST_PAD_SINK) { + if (!gst_structure_has_name(structure, "video/x-raw-yuv")) + return NULL; + out_caps = gst_caps_from_string(gst_vaapiconvert_vaapi_caps_str); + } + else { + if (!gst_structure_has_name(structure, "video/x-vaapi-surface")) + return NULL; + out_caps = gst_caps_from_string(gst_vaapiconvert_yuv_caps_str); + if (convert->display) { + GstCaps *allowed_caps, *inter_caps; + allowed_caps = gst_vaapi_display_get_image_caps(convert->display); + if (!allowed_caps) + return NULL; + inter_caps = gst_caps_intersect(out_caps, allowed_caps); + gst_caps_unref(allowed_caps); + gst_caps_unref(out_caps); + out_caps = inter_caps; + } + } + + structure = gst_caps_get_structure(out_caps, 0); + gst_structure_set_value(structure, "width", v_width); + gst_structure_set_value(structure, "height", v_height); + if (v_framerate) + gst_structure_set_value(structure, "framerate", v_framerate); + if (v_par) + gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); + return out_caps; +} + +static gboolean +gst_vaapiconvert_set_caps( + GstBaseTransform *trans, + GstCaps *incaps, + GstCaps *outcaps +) +{ + GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstStructure *structure; + gint width, height; + + structure = gst_caps_get_structure(incaps, 0); + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + + if (width != convert->image_width || height != convert->image_height) { + if (convert->images) + g_object_unref(convert->images); + convert->images = gst_vaapi_image_pool_new(convert->display, incaps); + if (!convert->images) + return FALSE; + } + + structure = gst_caps_get_structure(outcaps, 0); + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + + if (width != convert->surface_width || height != convert->surface_height) { + if (convert->surfaces) + g_object_unref(convert->surfaces); + convert->surfaces = gst_vaapi_surface_pool_new(convert->display, outcaps); + if (!convert->surfaces) + return FALSE; + } + return TRUE; +} + +static gboolean +gst_vaapiconvert_get_unit_size( + GstBaseTransform *trans, + GstCaps *caps, + guint *size +) +{ + GstStructure * const structure = gst_caps_get_structure(caps, 0); + GstVideoFormat format; + gint width, height; + + if (gst_structure_has_name(structure, "video/x-vaapi-surface")) + *size = 0; + else { + if (!gst_video_format_parse_caps(caps, &format, &width, &height)) + return FALSE; + *size = gst_video_format_get_size(format, width, height); + } + return TRUE; +} + +static GstFlowReturn +gst_vaapiconvert_buffer_alloc( + GstBaseTransform *trans, + guint size, + GstCaps *caps, + GstBuffer **pbuf +) +{ + return GST_FLOW_OK; +} + +static GstFlowReturn +gst_vaapiconvert_sinkpad_buffer_alloc( + GstPad *pad, + guint64 offset, + guint size, + GstCaps *caps, + GstBuffer **pbuf +) +{ + GstBaseTransform *trans; + GstFlowReturn ret; + + trans = GST_BASE_TRANSFORM(gst_pad_get_parent_element(pad)); + if (!trans) + return GST_FLOW_UNEXPECTED; + + ret = gst_vaapiconvert_buffer_alloc(trans, size, caps, pbuf); + g_object_unref(trans); + return ret; +} + +static GstFlowReturn +gst_vaapiconvert_prepare_output_buffer( + GstBaseTransform *trans, + GstBuffer *inbuf, + gint size, + GstCaps *caps, + GstBuffer **poutbuf +) +{ + GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstBuffer *buffer; + + buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); + if (!buffer) + return GST_FLOW_UNEXPECTED; + + gst_buffer_set_caps(buffer, caps); + *poutbuf = buffer; return GST_FLOW_OK; } static gboolean plugin_init(GstPlugin *plugin) { + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapiconvert, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + return gst_element_register(plugin, - "vaapiconvert", + GST_PLUGIN_NAME, GST_RANK_PRIMARY, GST_TYPE_VAAPICONVERT); } GST_PLUGIN_DEFINE( GST_VERSION_MAJOR, GST_VERSION_MINOR, - "vaapiconvert", - "A VA-API based video pixels format converter", + GST_PLUGIN_NAME, + GST_PLUGIN_DESC, plugin_init, PACKAGE_VERSION, "GPL", diff --git a/sys/vaapiconvert/gstvaapiconvert.h b/sys/vaapiconvert/gstvaapiconvert.h index 20189ad066..98487f625d 100644 --- a/sys/vaapiconvert/gstvaapiconvert.h +++ b/sys/vaapiconvert/gstvaapiconvert.h @@ -22,6 +22,11 @@ #define GST_VAAPICONVERT_H #include +#include +#include +#include +#include +#include G_BEGIN_DECLS @@ -47,17 +52,25 @@ G_BEGIN_DECLS #define GST_VAAPICONVERT_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), \ GST_TYPE_VAAPICONVERT, \ - GstVaapiConvert)) + GstVaapiConvertClass)) typedef struct _GstVaapiConvert GstVaapiConvert; -typedef struct _GstVaapiConvertPrivate GstVaapiConvertPrivate; typedef struct _GstVaapiConvertClass GstVaapiConvertClass; +/* Max output surfaces */ +#define GST_VAAPICONVERT_MAX_SURFACES 2 + struct _GstVaapiConvert { /*< private >*/ - GstBaseTransform parent_instance; + GstBaseTransform parent_instance; - GstVaapiConvertPrivate *priv; + GstVaapiDisplay *display; + GstVaapiVideoPool *images; + guint image_width; + guint image_height; + GstVaapiVideoPool *surfaces; + guint surface_width; + guint surface_height; }; struct _GstVaapiConvertClass { From 6bc69b5592bfb0f5343f54a470272856990284e4 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 17:43:29 +0000 Subject: [PATCH 0055/3781] Implement I420 and YV12 if the underlying implementation does not. --- gst-libs/gst/vaapi/gstvaapiimage.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 038983a2e6..620971b10d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -447,6 +447,7 @@ gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) guint i, j; guchar *data; guint32 data_size; + gboolean swap_YUV; g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); g_return_val_if_fail(image->priv->is_constructed, FALSE); @@ -461,7 +462,11 @@ gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) return FALSE; format = gst_vaapi_image_format_from_caps(caps); - if (format != priv->format) + swap_YUV = ((format == GST_VAAPI_IMAGE_I420 && + priv->format == GST_VAAPI_IMAGE_YV12) || + (format == GST_VAAPI_IMAGE_YV12 && + priv->format == GST_VAAPI_IMAGE_I420)); + if (format != priv->format && !swap_YUV) return FALSE; structure = gst_caps_get_structure(caps, 0); @@ -473,7 +478,7 @@ gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) if (!gst_vaapi_image_map(image)) return FALSE; - if (data_size == priv->image.data_size) + if (format == priv->format && data_size == priv->image.data_size) memcpy(priv->image_data, data, data_size); else { /* XXX: copied from gst_video_format_get_row_stride() -- no NV12? */ @@ -525,6 +530,20 @@ gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) } if (size2 != data_size) g_error("data_size mismatch %d / %u", size2, data_size); + if (swap_YUV) { + guint offset = offsets[1]; + guint stride = pitches[1]; + guint width = widths [1]; + guint height = heights[1]; + offsets[1] = offsets[2]; + pitches[1] = pitches[2]; + widths [1] = widths [2]; + heights[1] = heights[2]; + offsets[2] = offset; + pitches[2] = stride; + widths [2] = width; + heights[2] = height; + } for (i = 0; i < priv->image.num_planes; i++) { guchar *src = data + offsets[i]; guchar *dst = priv->image_data + priv->image.offsets[i]; From 1c965c3340f75388d181fde4ae873e96deb93966 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 15 Mar 2010 17:44:35 +0000 Subject: [PATCH 0056/3781] Implement I420 (resp. YV12) with YV12 (resp. I420) if the driver does not. --- sys/vaapiconvert/gstvaapiconvert.c | 57 ++++++++++++++++++++++++++++-- sys/vaapiconvert/gstvaapiconvert.h | 5 +++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index 778ff6b29a..1c0cb0955e 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -292,14 +292,41 @@ gst_vaapiconvert_transform_caps( return NULL; out_caps = gst_caps_from_string(gst_vaapiconvert_yuv_caps_str); if (convert->display) { - GstCaps *allowed_caps, *inter_caps; + GstVaapiImageFormat fixup_format; + GstCaps *allowed_caps, *new_caps; + allowed_caps = gst_vaapi_display_get_image_caps(convert->display); if (!allowed_caps) return NULL; - inter_caps = gst_caps_intersect(out_caps, allowed_caps); + + new_caps = gst_caps_intersect(out_caps, allowed_caps); gst_caps_unref(allowed_caps); gst_caps_unref(out_caps); - out_caps = inter_caps; + out_caps = new_caps; + + convert->has_YV12 = gst_vaapi_display_has_image_format( + convert->display, + GST_VAAPI_IMAGE_YV12 + ); + convert->has_I420 = gst_vaapi_display_has_image_format( + convert->display, + GST_VAAPI_IMAGE_I420 + ); + if (convert->has_YV12 && !convert->has_I420) + fixup_format = GST_VAAPI_IMAGE_I420; + else if (convert->has_I420 && !convert->has_YV12) + fixup_format = GST_VAAPI_IMAGE_YV12; + else + fixup_format = 0; + if (fixup_format) { + allowed_caps = gst_vaapi_image_format_get_caps(fixup_format); + if (allowed_caps) { + new_caps = gst_caps_union(out_caps, allowed_caps); + gst_caps_unref(allowed_caps); + gst_caps_unref(out_caps); + out_caps = new_caps; + } + } } } @@ -321,13 +348,34 @@ gst_vaapiconvert_set_caps( ) { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstCaps *fixed_incaps = NULL; GstStructure *structure; gint width, height; + guint32 format; structure = gst_caps_get_structure(incaps, 0); gst_structure_get_int(structure, "width", &width); gst_structure_get_int(structure, "height", &height); +#define GST_FORMAT_YV12 GST_MAKE_FOURCC ('Y', 'V', '1', '2') +#define GST_FORMAT_I420 GST_MAKE_FOURCC ('I', '4', '2', '0') + + /* Fix I420 and YV12 formats */ + if (gst_structure_get_fourcc(structure, "format", &format)) { + if (format == GST_FORMAT_I420 && !convert->has_I420) + format = GST_FORMAT_YV12; + else if (format == GST_FORMAT_YV12 && !convert->has_YV12) + format = GST_FORMAT_I420; + else + format = 0; + if (format) { + fixed_incaps = gst_caps_copy(incaps); + structure = gst_caps_get_structure(fixed_incaps, 0); + gst_structure_set(structure, "format", GST_TYPE_FOURCC, format, NULL); + incaps = fixed_incaps; + } + } + if (width != convert->image_width || height != convert->image_height) { if (convert->images) g_object_unref(convert->images); @@ -347,6 +395,9 @@ gst_vaapiconvert_set_caps( if (!convert->surfaces) return FALSE; } + + if (fixed_incaps) + gst_caps_unref(fixed_incaps); return TRUE; } diff --git a/sys/vaapiconvert/gstvaapiconvert.h b/sys/vaapiconvert/gstvaapiconvert.h index 98487f625d..e81009dd08 100644 --- a/sys/vaapiconvert/gstvaapiconvert.h +++ b/sys/vaapiconvert/gstvaapiconvert.h @@ -65,12 +65,17 @@ struct _GstVaapiConvert { GstBaseTransform parent_instance; GstVaapiDisplay *display; + GstVaapiImageFormat image_format; GstVaapiVideoPool *images; guint image_width; guint image_height; GstVaapiVideoPool *surfaces; guint surface_width; guint surface_height; + + /* XXX: implement YV12 or I420 formats ourselves */ + guint has_YV12 : 1; + guint has_I420 : 1; }; struct _GstVaapiConvertClass { From 69d58a0857f1a4c3483cf91224185199290d82ef Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 08:43:16 +0000 Subject: [PATCH 0057/3781] Handle I420 formats internally in GstVaapiImage. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 57 ++++++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapiimage.c | 59 +++++++++++++++++++++------- sys/vaapiconvert/gstvaapiconvert.c | 57 ++------------------------- sys/vaapiconvert/gstvaapiconvert.h | 5 --- 4 files changed, 99 insertions(+), 79 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 4606517ca8..6910bce26c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -54,15 +54,53 @@ enum { }; static void -filter_formats(VAImageFormat *va_formats, unsigned int *pnum_va_formats) +append_format( + VAImageFormat **pva_formats, + unsigned int *pnum_va_formats, + GstVaapiImageFormat format +) +{ + const VAImageFormat *va_format; + VAImageFormat *new_va_formats; + + va_format = gst_vaapi_image_format_get_va_format(format); + if (!va_format) + return; + + new_va_formats = realloc( + *pva_formats, + sizeof(new_va_formats[0]) * (1 + *pnum_va_formats) + ); + if (!new_va_formats) + return; + + new_va_formats[(*pnum_va_formats)++] = *va_format; + *pva_formats = new_va_formats; +} + +static void +filter_formats(VAImageFormat **pva_formats, unsigned int *pnum_va_formats) { unsigned int i = 0; + gboolean has_YV12 = FALSE; + gboolean has_I420 = FALSE; while (i < *pnum_va_formats) { - VAImageFormat * const va_format = &va_formats[i]; + VAImageFormat * const va_format = &(*pva_formats)[i]; const GstVaapiImageFormat format = gst_vaapi_image_format(va_format); - if (format) + if (format) { ++i; + switch (format) { + case GST_VAAPI_IMAGE_YV12: + has_YV12 = TRUE; + break; + case GST_VAAPI_IMAGE_I420: + has_I420 = TRUE; + break; + default: + break; + } + } else { /* Remove any format that is not supported by libgstvaapi */ GST_DEBUG("unsupported format %c%c%c%c", @@ -70,9 +108,16 @@ filter_formats(VAImageFormat *va_formats, unsigned int *pnum_va_formats) (va_format->fourcc >> 8) & 0xff, (va_format->fourcc >> 16) & 0xff, (va_format->fourcc >> 24) & 0xff); - *va_format = va_formats[--(*pnum_va_formats)]; + *va_format = (*pva_formats)[--(*pnum_va_formats)]; } } + + /* Append I420 (resp. YV12) format if YV12 (resp. I420) is not + supported by the underlying driver */ + if (has_YV12 && !has_I420) + append_format(pva_formats, pnum_va_formats, GST_VAAPI_IMAGE_I420); + else if (has_I420 && !has_YV12) + append_format(pva_formats, pnum_va_formats, GST_VAAPI_IMAGE_YV12); } /* Sort image formats. Prefer YUV formats first */ @@ -207,7 +252,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) for (i = 0; i < priv->num_image_formats; i++) GST_DEBUG(" %s", string_of_FOURCC(priv->image_formats[i].fourcc)); - filter_formats(priv->image_formats, &priv->num_image_formats); + filter_formats(&priv->image_formats, &priv->num_image_formats); qsort( priv->image_formats, priv->num_image_formats, @@ -232,7 +277,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) if (!vaapi_check_status(status, "vaQuerySubpictureFormats()")) return FALSE; - filter_formats(priv->subpicture_formats, &priv->num_subpicture_formats); + filter_formats(&priv->subpicture_formats, &priv->num_subpicture_formats); qsort( priv->subpicture_formats, priv->num_subpicture_formats, diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 620971b10d..f8248afaf8 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -39,6 +39,7 @@ struct _GstVaapiImagePrivate { gboolean is_constructed; VAImage image; guchar *image_data; + GstVaapiImageFormat internal_format; GstVaapiImageFormat format; guint width; guint height; @@ -77,29 +78,57 @@ gst_vaapi_image_destroy(GstVaapiImage *image) } static gboolean -gst_vaapi_image_create(GstVaapiImage *image) +_gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) { GstVaapiImagePrivate * const priv = image->priv; - const VAImageFormat *format; + const VAImageFormat *va_format; VAStatus status; - if (!gst_vaapi_display_has_image_format(priv->display, priv->format)) + if (!gst_vaapi_display_has_image_format(priv->display, format)) return FALSE; - format = gst_vaapi_image_format_get_va_format(priv->format); - - g_return_val_if_fail(format, FALSE); + va_format = gst_vaapi_image_format_get_va_format(format); + if (!va_format) + return FALSE; status = vaCreateImage( gst_vaapi_display_get_display(priv->display), - (VAImageFormat *)format, + (VAImageFormat *)va_format, priv->width, priv->height, &priv->image ); - if (!vaapi_check_status(status, "vaCreateImage()")) + return (status == VA_STATUS_SUCCESS && + priv->image.format.fourcc == va_format->fourcc); +} + +static gboolean +gst_vaapi_image_create(GstVaapiImage *image) +{ + GstVaapiImagePrivate * const priv = image->priv; + + if (_gst_vaapi_image_create(image, priv->format)) { + priv->internal_format = priv->format; + return TRUE; + } + + switch (priv->format) { + case GST_VAAPI_IMAGE_I420: + priv->internal_format = GST_VAAPI_IMAGE_YV12; + break; + case GST_VAAPI_IMAGE_YV12: + priv->internal_format = GST_VAAPI_IMAGE_I420; + break; + default: + priv->internal_format = 0; + break; + } + if (!priv->internal_format) + return FALSE; + if (!_gst_vaapi_image_create(image, priv->internal_format)) return FALSE; + GST_DEBUG("image 0x%08x", priv->image.image_id); return TRUE; } @@ -462,13 +491,15 @@ gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) return FALSE; format = gst_vaapi_image_format_from_caps(caps); - swap_YUV = ((format == GST_VAAPI_IMAGE_I420 && - priv->format == GST_VAAPI_IMAGE_YV12) || - (format == GST_VAAPI_IMAGE_YV12 && - priv->format == GST_VAAPI_IMAGE_I420)); - if (format != priv->format && !swap_YUV) + if (format != priv->format) return FALSE; + swap_YUV = (priv->format != priv->internal_format && + ((priv->format == GST_VAAPI_IMAGE_I420 && + priv->internal_format == GST_VAAPI_IMAGE_YV12) || + (priv->format == GST_VAAPI_IMAGE_YV12 && + priv->internal_format == GST_VAAPI_IMAGE_I420))); + structure = gst_caps_get_structure(caps, 0); gst_structure_get_int(structure, "width", &width); gst_structure_get_int(structure, "height", &height); @@ -478,7 +509,7 @@ gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) if (!gst_vaapi_image_map(image)) return FALSE; - if (format == priv->format && data_size == priv->image.data_size) + if (format == priv->internal_format && data_size == priv->image.data_size) memcpy(priv->image_data, data, data_size); else { /* XXX: copied from gst_video_format_get_row_stride() -- no NV12? */ diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index 1c0cb0955e..778ff6b29a 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -292,41 +292,14 @@ gst_vaapiconvert_transform_caps( return NULL; out_caps = gst_caps_from_string(gst_vaapiconvert_yuv_caps_str); if (convert->display) { - GstVaapiImageFormat fixup_format; - GstCaps *allowed_caps, *new_caps; - + GstCaps *allowed_caps, *inter_caps; allowed_caps = gst_vaapi_display_get_image_caps(convert->display); if (!allowed_caps) return NULL; - - new_caps = gst_caps_intersect(out_caps, allowed_caps); + inter_caps = gst_caps_intersect(out_caps, allowed_caps); gst_caps_unref(allowed_caps); gst_caps_unref(out_caps); - out_caps = new_caps; - - convert->has_YV12 = gst_vaapi_display_has_image_format( - convert->display, - GST_VAAPI_IMAGE_YV12 - ); - convert->has_I420 = gst_vaapi_display_has_image_format( - convert->display, - GST_VAAPI_IMAGE_I420 - ); - if (convert->has_YV12 && !convert->has_I420) - fixup_format = GST_VAAPI_IMAGE_I420; - else if (convert->has_I420 && !convert->has_YV12) - fixup_format = GST_VAAPI_IMAGE_YV12; - else - fixup_format = 0; - if (fixup_format) { - allowed_caps = gst_vaapi_image_format_get_caps(fixup_format); - if (allowed_caps) { - new_caps = gst_caps_union(out_caps, allowed_caps); - gst_caps_unref(allowed_caps); - gst_caps_unref(out_caps); - out_caps = new_caps; - } - } + out_caps = inter_caps; } } @@ -348,34 +321,13 @@ gst_vaapiconvert_set_caps( ) { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); - GstCaps *fixed_incaps = NULL; GstStructure *structure; gint width, height; - guint32 format; structure = gst_caps_get_structure(incaps, 0); gst_structure_get_int(structure, "width", &width); gst_structure_get_int(structure, "height", &height); -#define GST_FORMAT_YV12 GST_MAKE_FOURCC ('Y', 'V', '1', '2') -#define GST_FORMAT_I420 GST_MAKE_FOURCC ('I', '4', '2', '0') - - /* Fix I420 and YV12 formats */ - if (gst_structure_get_fourcc(structure, "format", &format)) { - if (format == GST_FORMAT_I420 && !convert->has_I420) - format = GST_FORMAT_YV12; - else if (format == GST_FORMAT_YV12 && !convert->has_YV12) - format = GST_FORMAT_I420; - else - format = 0; - if (format) { - fixed_incaps = gst_caps_copy(incaps); - structure = gst_caps_get_structure(fixed_incaps, 0); - gst_structure_set(structure, "format", GST_TYPE_FOURCC, format, NULL); - incaps = fixed_incaps; - } - } - if (width != convert->image_width || height != convert->image_height) { if (convert->images) g_object_unref(convert->images); @@ -395,9 +347,6 @@ gst_vaapiconvert_set_caps( if (!convert->surfaces) return FALSE; } - - if (fixed_incaps) - gst_caps_unref(fixed_incaps); return TRUE; } diff --git a/sys/vaapiconvert/gstvaapiconvert.h b/sys/vaapiconvert/gstvaapiconvert.h index e81009dd08..98487f625d 100644 --- a/sys/vaapiconvert/gstvaapiconvert.h +++ b/sys/vaapiconvert/gstvaapiconvert.h @@ -65,17 +65,12 @@ struct _GstVaapiConvert { GstBaseTransform parent_instance; GstVaapiDisplay *display; - GstVaapiImageFormat image_format; GstVaapiVideoPool *images; guint image_width; guint image_height; GstVaapiVideoPool *surfaces; guint surface_width; guint surface_height; - - /* XXX: implement YV12 or I420 formats ourselves */ - guint has_YV12 : 1; - guint has_I420 : 1; }; struct _GstVaapiConvertClass { From 148d104c1ab634d634a2131d3d1c33357dd1a795 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 08:49:16 +0000 Subject: [PATCH 0058/3781] Move tests to top-level tests/ directory. --- configure.ac | 2 -- tests/Makefile.am | 27 +++++++++++++++++- tests/examples/Makefile.am | 4 --- tests/examples/generic/Makefile.am | 29 -------------------- tests/{examples/generic => }/test-display.c | 0 tests/{examples/generic => }/test-surfaces.c | 0 tests/{examples/generic => }/test-windows.c | 0 7 files changed, 26 insertions(+), 36 deletions(-) delete mode 100644 tests/examples/Makefile.am delete mode 100644 tests/examples/generic/Makefile.am rename tests/{examples/generic => }/test-display.c (100%) rename tests/{examples/generic => }/test-surfaces.c (100%) rename tests/{examples/generic => }/test-windows.c (100%) diff --git a/configure.ac b/configure.ac index 7ada7797a8..35f39f9de3 100644 --- a/configure.ac +++ b/configure.ac @@ -152,6 +152,4 @@ AC_OUTPUT([ sys/vaapiconvert/Makefile sys/vaapisink/Makefile tests/Makefile - tests/examples/Makefile - tests/examples/generic/Makefile ]) diff --git a/tests/Makefile.am b/tests/Makefile.am index cbf577e61b..cc7cdcf6a2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,29 @@ -SUBDIRS = examples +noinst_PROGRAMS = \ + test-display \ + test-surfaces \ + test-windows \ + $(NULL) + +TEST_CFLAGS = \ + $(GST_CFLAGS) \ + -I$(top_srcdir)/gst-libs \ + $(X11_CFLAGS) + +TEST_LIBS = \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-@GST_MAJORMINOR@.la \ + $(X11_LIBS) + +test_display_SOURCES = test-display.c +test_display_CFLAGS = $(TEST_CFLAGS) +test_display_LDADD = $(TEST_LIBS) + +test_surfaces_SOURCES = test-surfaces.c +test_surfaces_CFLAGS = $(TEST_CFLAGS) +test_surfaces_LDADD = $(TEST_LIBS) + +test_windows_SOURCES = test-windows.c +test_windows_CFLAGS = $(TEST_CFLAGS) +test_windows_LDADD = $(TEST_LIBS) # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/examples/Makefile.am b/tests/examples/Makefile.am deleted file mode 100644 index f09ad5903d..0000000000 --- a/tests/examples/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -SUBDIRS = generic - -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/examples/generic/Makefile.am b/tests/examples/generic/Makefile.am deleted file mode 100644 index cc7cdcf6a2..0000000000 --- a/tests/examples/generic/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -noinst_PROGRAMS = \ - test-display \ - test-surfaces \ - test-windows \ - $(NULL) - -TEST_CFLAGS = \ - $(GST_CFLAGS) \ - -I$(top_srcdir)/gst-libs \ - $(X11_CFLAGS) - -TEST_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-@GST_MAJORMINOR@.la \ - $(X11_LIBS) - -test_display_SOURCES = test-display.c -test_display_CFLAGS = $(TEST_CFLAGS) -test_display_LDADD = $(TEST_LIBS) - -test_surfaces_SOURCES = test-surfaces.c -test_surfaces_CFLAGS = $(TEST_CFLAGS) -test_surfaces_LDADD = $(TEST_LIBS) - -test_windows_SOURCES = test-windows.c -test_windows_CFLAGS = $(TEST_CFLAGS) -test_windows_LDADD = $(TEST_LIBS) - -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/examples/generic/test-display.c b/tests/test-display.c similarity index 100% rename from tests/examples/generic/test-display.c rename to tests/test-display.c diff --git a/tests/examples/generic/test-surfaces.c b/tests/test-surfaces.c similarity index 100% rename from tests/examples/generic/test-surfaces.c rename to tests/test-surfaces.c diff --git a/tests/examples/generic/test-windows.c b/tests/test-windows.c similarity index 100% rename from tests/examples/generic/test-windows.c rename to tests/test-windows.c From f2af51eefcdac989e8504cbc025962c6c9a3b4ba Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 09:03:10 +0000 Subject: [PATCH 0059/3781] Rename GstVaapiSinkBase to GstVaapiVideoSink. --- gst-libs/gst/vaapi/Makefile.am | 4 +- ...gstvaapisinkbase.c => gstvaapivideosink.c} | 30 ++++++------- ...gstvaapisinkbase.h => gstvaapivideosink.h} | 44 +++++++++---------- sys/vaapiconvert/gstvaapiconvert.c | 8 ++-- sys/vaapisink/gstvaapisink.c | 12 ++--- 5 files changed, 49 insertions(+), 49 deletions(-) rename gst-libs/gst/vaapi/{gstvaapisinkbase.c => gstvaapivideosink.c} (71%) rename gst-libs/gst/vaapi/{gstvaapisinkbase.h => gstvaapivideosink.h} (50%) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 127e54cf77..cf3749a64a 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -5,12 +5,12 @@ libgstvaapi_source_c = \ gstvaapiimage.c \ gstvaapiimageformat.c \ gstvaapiimagepool.c \ - gstvaapisinkbase.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ gstvaapisurfacepool.c \ gstvaapivideobuffer.c \ gstvaapivideopool.c \ + gstvaapivideosink.c \ gstvaapiwindow.c \ vaapi_utils.c \ $(NULL) @@ -20,12 +20,12 @@ libgstvaapi_source_h = \ gstvaapiimage.h \ gstvaapiimageformat.h \ gstvaapiimagepool.h \ - gstvaapisinkbase.h \ gstvaapisubpicture.h \ gstvaapisurface.h \ gstvaapisurfacepool.h \ gstvaapivideobuffer.h \ gstvaapivideopool.h \ + gstvaapivideosink.h \ gstvaapiwindow.h \ vaapi_debug.h \ vaapi_utils.h \ diff --git a/gst-libs/gst/vaapi/gstvaapisinkbase.c b/gst-libs/gst/vaapi/gstvaapivideosink.c similarity index 71% rename from gst-libs/gst/vaapi/gstvaapisinkbase.c rename to gst-libs/gst/vaapi/gstvaapivideosink.c index 73eede9d6c..15d52b50ef 100644 --- a/gst-libs/gst/vaapi/gstvaapisinkbase.c +++ b/gst-libs/gst/vaapi/gstvaapivideosink.c @@ -1,5 +1,5 @@ /* - * gstvaapisinkbase.c - VA sink interface + * gstvaapivideosink.c - VA sink interface * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * @@ -19,10 +19,10 @@ */ #include "config.h" -#include "gstvaapisinkbase.h" +#include "gstvaapivideosink.h" static void -gst_vaapisink_base_base_init(gpointer g_class) +gst_vaapi_video_sink_base_init(gpointer g_class) { static gboolean is_initialized = FALSE; @@ -32,20 +32,20 @@ gst_vaapisink_base_base_init(gpointer g_class) } GType -gst_vaapisink_base_get_type(void) +gst_vaapi_video_sink_get_type(void) { static GType iface_type = 0; if (G_UNLIKELY(!iface_type)) { static const GTypeInfo info = { - sizeof(GstVaapiSinkBaseInterface), - gst_vaapisink_base_base_init, /* base_init */ + sizeof(GstVaapiVideoSinkInterface), + gst_vaapi_video_sink_base_init, /* base_init */ NULL, /* base_finalize */ }; iface_type = g_type_register_static( G_TYPE_INTERFACE, - "GstVaapiSinkBase", + "GstVaapiVideoSink", &info, 0 ); @@ -54,17 +54,17 @@ gst_vaapisink_base_get_type(void) } GstVaapiDisplay * -gst_vaapisink_base_get_display(GstVaapiSinkBase *sink) +gst_vaapi_video_sink_get_display(GstVaapiVideoSink *sink) { - g_return_val_if_fail(GST_IS_VAAPISINK_BASE(sink), NULL); + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_SINK(sink), NULL); - return GST_VAAPISINK_BASE_GET_INTERFACE(sink)->get_display(sink); + return GST_VAAPI_VIDEO_SINK_GET_INTERFACE(sink)->get_display(sink); } -GstVaapiSinkBase * -gst_vaapisink_base_lookup(GstElement *element) +GstVaapiVideoSink * +gst_vaapi_video_sink_lookup(GstElement *element) { - GstVaapiSinkBase *sink = NULL; + GstVaapiVideoSink *sink = NULL; GstPad *pad, *peer; g_return_val_if_fail(GST_IS_ELEMENT(element), NULL); @@ -81,8 +81,8 @@ gst_vaapisink_base_lookup(GstElement *element) element = gst_pad_get_parent_element(peer); if (element) { - if (GST_IS_VAAPISINK_BASE(element)) - sink = GST_VAAPISINK_BASE(element); + if (GST_VAAPI_IS_VIDEO_SINK(element)) + sink = GST_VAAPI_VIDEO_SINK(element); g_object_unref(element); } g_object_unref(peer); diff --git a/gst-libs/gst/vaapi/gstvaapisinkbase.h b/gst-libs/gst/vaapi/gstvaapivideosink.h similarity index 50% rename from gst-libs/gst/vaapi/gstvaapisinkbase.h rename to gst-libs/gst/vaapi/gstvaapivideosink.h index b436f016a8..62ddb59b70 100644 --- a/gst-libs/gst/vaapi/gstvaapisinkbase.h +++ b/gst-libs/gst/vaapi/gstvaapivideosink.h @@ -1,5 +1,5 @@ /* - * gstvaapisinkbase.h - VA sink interface + * gstvaapivideosink.h - VA sink interface * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * @@ -18,49 +18,49 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef GST_VAAPISINK_BASE_H -#define GST_VAAPISINK_BASE_H +#ifndef GST_VAAPI_VIDEO_SINK_H +#define GST_VAAPI_VIDEO_SINK_H #include #include G_BEGIN_DECLS -#define GST_TYPE_VAAPISINK_BASE \ - (gst_vaapisink_base_get_type()) +#define GST_VAAPI_TYPE_VIDEO_SINK \ + (gst_vaapi_video_sink_get_type()) -#define GST_VAAPISINK_BASE(obj) \ +#define GST_VAAPI_VIDEO_SINK(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_TYPE_VAAPISINK_BASE, \ - GstVaapiSinkBase)) + GST_VAAPI_TYPE_VIDEO_SINK, \ + GstVaapiVideoSink)) -#define GST_IS_VAAPISINK_BASE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPISINK_BASE)) +#define GST_VAAPI_IS_VIDEO_SINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_SINK)) -#define GST_VAAPISINK_BASE_GET_INTERFACE(obj) \ +#define GST_VAAPI_VIDEO_SINK_GET_INTERFACE(obj) \ (G_TYPE_INSTANCE_GET_INTERFACE((obj), \ - GST_TYPE_VAAPISINK_BASE, \ - GstVaapiSinkBaseInterface)) + GST_VAAPI_TYPE_VIDEO_SINK, \ + GstVaapiVideoSinkInterface)) -typedef struct _GstVaapiSinkBase GstVaapiSinkBase; /* dummy */ -typedef struct _GstVaapiSinkBaseInterface GstVaapiSinkBaseInterface; +typedef struct _GstVaapiVideoSink GstVaapiVideoSink; /* dummy */ +typedef struct _GstVaapiVideoSinkInterface GstVaapiVideoSinkInterface; -struct _GstVaapiSinkBaseInterface { +struct _GstVaapiVideoSinkInterface { /*< private >*/ GTypeInterface g_iface; - GstVaapiDisplay *(*get_display)(GstVaapiSinkBase *sink); + GstVaapiDisplay *(*get_display)(GstVaapiVideoSink *sink); }; GType -gst_vaapisink_base_get_type(void); +gst_vaapi_video_sink_get_type(void); GstVaapiDisplay * -gst_vaapisink_base_get_display(GstVaapiSinkBase *sink); +gst_vaapi_video_sink_get_display(GstVaapiVideoSink *sink); -GstVaapiSinkBase * -gst_vaapisink_base_lookup(GstElement *element); +GstVaapiVideoSink * +gst_vaapi_video_sink_lookup(GstElement *element); G_END_DECLS -#endif /* GST_VAAPISINK_BASE_H */ +#endif /* GST_VAAPI_VIDEO_SINK_H */ diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index 778ff6b29a..7fb89ce6f6 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -21,7 +21,7 @@ #include "config.h" #include #include -#include +#include #include "gstvaapiconvert.h" #define GST_PLUGIN_NAME "vaapiconvert" @@ -206,15 +206,15 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) static gboolean gst_vaapiconvert_start(GstBaseTransform *trans) { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); - GstVaapiSinkBase *sink; + GstVaapiVideoSink *sink; GstVaapiDisplay *display; /* Look for a downstream vaapisink */ - sink = gst_vaapisink_base_lookup(GST_ELEMENT(trans)); + sink = gst_vaapi_video_sink_lookup(GST_ELEMENT(trans)); if (!sink) return FALSE; - display = gst_vaapisink_base_get_display(sink); + display = gst_vaapi_video_sink_get_display(sink); if (!display) return FALSE; diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 8853cb31b7..6f55f02ee2 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -21,7 +21,7 @@ #include "config.h" #include #include -#include +#include #include #include #include "gstvaapisink.h" @@ -68,22 +68,22 @@ enum { }; static GstVaapiDisplay * -gst_vaapisink_base_do_get_display(GstVaapiSinkBase *sink) +gst_vaapi_video_sink_do_get_display(GstVaapiVideoSink *sink) { return gst_vaapisink_get_display(GST_VAAPISINK(sink)); } -static void gst_vaapisink_base_iface_init(GstVaapiSinkBaseInterface *iface) +static void gst_vaapi_video_sink_iface_init(GstVaapiVideoSinkInterface *iface) { - iface->get_display = gst_vaapisink_base_do_get_display; + iface->get_display = gst_vaapi_video_sink_do_get_display; } static void gst_vaapisink_iface_init(GType type) { const GType g_define_type_id = type; - G_IMPLEMENT_INTERFACE(GST_TYPE_VAAPISINK_BASE, - gst_vaapisink_base_iface_init); + G_IMPLEMENT_INTERFACE(GST_VAAPI_TYPE_VIDEO_SINK, + gst_vaapi_video_sink_iface_init); } static void From 2ca21f9e417895b4d7f47f8525d0053a64d573e5 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 09:12:47 +0000 Subject: [PATCH 0060/3781] Move X11 utilties to gstvaapiutils_x11.[ch]. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapiutils_x11.c | 139 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_x11.h | 52 +++++++++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 116 +------------------- 4 files changed, 194 insertions(+), 115 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_x11.c create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_x11.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index cf3749a64a..5c4c58f62c 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -57,11 +57,13 @@ libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ libgstvaapi_@GST_MAJORMINOR@_la_SOURCES += \ gstvaapidisplay_x11.c \ + gstvaapiutils_x11.c \ gstvaapiwindow_x11.c \ $(NULL) libgstvaapi_@GST_MAJORMINOR@include_HEADERS += \ gstvaapidisplay_x11.h \ + gstvaapiutils_x11.h \ gstvaapiwindow_x11.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c new file mode 100644 index 0000000000..dcc95b5363 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -0,0 +1,139 @@ +/* + * gstvaapiutils_x11.c - X11 utilties + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include +#include +#include "gstvaapiutils_x11.h" + +// X error trap +static int x11_error_code = 0; +static int (*old_error_handler)(Display *, XErrorEvent *); + +static int error_handler(Display *dpy, XErrorEvent *error) +{ + x11_error_code = error->error_code; + return 0; +} + +void x11_trap_errors(void) +{ + x11_error_code = 0; + old_error_handler = XSetErrorHandler(error_handler); +} + +int x11_untrap_errors(void) +{ + XSetErrorHandler(old_error_handler); + return x11_error_code; +} + +// X window management +static const int x11_event_mask = (KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask | + EnterWindowMask | + ExposureMask | + StructureNotifyMask); + +Window +x11_create_window(Display *display, unsigned int width, unsigned int height) +{ + Window root_window, window; + int screen, depth; + Visual *vis; + XSetWindowAttributes xswa; + unsigned long xswa_mask; + XWindowAttributes wattr; + unsigned long black_pixel, white_pixel; + + screen = DefaultScreen(display); + vis = DefaultVisual(display, screen); + root_window = RootWindow(display, screen); + black_pixel = BlackPixel(display, screen); + white_pixel = WhitePixel(display, screen); + + XGetWindowAttributes(display, root_window, &wattr); + depth = wattr.depth; + if (depth != 15 && depth != 16 && depth != 24 && depth != 32) + depth = 24; + + xswa_mask = CWBorderPixel | CWBackPixel; + xswa.border_pixel = black_pixel; + xswa.background_pixel = white_pixel; + + window = XCreateWindow( + display, + root_window, + 0, 0, width, height, + 0, + depth, + InputOutput, + vis, + xswa_mask, &xswa + ); + if (!window) + return None; + + XSelectInput(display, window, x11_event_mask); + return window; +} + +gboolean +x11_get_geometry( + Display *dpy, + Drawable drawable, + gint *px, + gint *py, + guint *pwidth, + guint *pheight +) +{ + Window rootwin; + int x, y; + unsigned int width, height, border_width, depth; + + x11_trap_errors(); + XGetGeometry( + dpy, + drawable, + &rootwin, + &x, &y, &width, &height, + &border_width, + &depth + ); + if (x11_untrap_errors()) + return FALSE; + + if (px) *px = x; + if (py) *py = y; + if (pwidth) *pwidth = width; + if (pheight) *pheight = height; + return TRUE; +} + +void x11_wait_event(Display *dpy, Window w, int type) +{ + XEvent e; + while (!XCheckTypedWindowEvent(dpy, w, type, &e)) + g_usleep(10); +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h new file mode 100644 index 0000000000..ab06ab3170 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -0,0 +1,52 @@ +/* + * gstvaapiutils_x11.h - X11 utilties + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_UTILS_X11_H +#define GST_VAAPI_UTILS_X11_H + +#include "config.h" +#include +#include + +void x11_trap_errors(void) + attribute_hidden; + +int x11_untrap_errors(void) + attribute_hidden; + + +Window +x11_create_window(Display *display, unsigned int width, unsigned int height) + attribute_hidden; + +gboolean +x11_get_geometry( + Display *dpy, + Drawable drawable, + gint *px, + gint *py, + guint *pwidth, + guint *pheight +) attribute_hidden; + +void x11_wait_event(Display *dpy, Window w, int type) + attribute_hidden; + +#endif /* GST_VAAPI_UTILS_X11_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index ad5cc3a655..eb648d8368 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -21,6 +21,7 @@ #include "config.h" #include "gstvaapiwindow_x11.h" #include "gstvaapidisplay_x11.h" +#include "gstvaapiutils_x11.h" #define DEBUG 1 #include "vaapi_debug.h" @@ -45,121 +46,6 @@ enum { PROP_XID, }; -// X error trap -static int x11_error_code = 0; -static int (*old_error_handler)(Display *, XErrorEvent *); - -static int error_handler(Display *dpy, XErrorEvent *error) -{ - x11_error_code = error->error_code; - return 0; -} - -static void x11_trap_errors(void) -{ - x11_error_code = 0; - old_error_handler = XSetErrorHandler(error_handler); -} - -static int x11_untrap_errors(void) -{ - XSetErrorHandler(old_error_handler); - return x11_error_code; -} - -// X window management -static const int x11_event_mask = (KeyPressMask | - KeyReleaseMask | - ButtonPressMask | - ButtonReleaseMask | - PointerMotionMask | - EnterWindowMask | - ExposureMask | - StructureNotifyMask); - -static Window -x11_create_window(Display *display, unsigned int width, unsigned int height) -{ - Window root_window, window; - int screen, depth; - Visual *vis; - XSetWindowAttributes xswa; - unsigned long xswa_mask; - XWindowAttributes wattr; - unsigned long black_pixel, white_pixel; - - screen = DefaultScreen(display); - vis = DefaultVisual(display, screen); - root_window = RootWindow(display, screen); - black_pixel = BlackPixel(display, screen); - white_pixel = WhitePixel(display, screen); - - XGetWindowAttributes(display, root_window, &wattr); - depth = wattr.depth; - if (depth != 15 && depth != 16 && depth != 24 && depth != 32) - depth = 24; - - xswa_mask = CWBorderPixel | CWBackPixel; - xswa.border_pixel = black_pixel; - xswa.background_pixel = white_pixel; - - window = XCreateWindow( - display, - root_window, - 0, 0, width, height, - 0, - depth, - InputOutput, - vis, - xswa_mask, &xswa - ); - if (!window) - return None; - - XSelectInput(display, window, x11_event_mask); - return window; -} - -static gboolean -x11_get_geometry( - Display *dpy, - Drawable drawable, - gint *px, - gint *py, - guint *pwidth, - guint *pheight -) -{ - Window rootwin; - int x, y; - unsigned int width, height, border_width, depth; - - x11_trap_errors(); - XGetGeometry( - dpy, - drawable, - &rootwin, - &x, &y, &width, &height, - &border_width, - &depth - ); - if (x11_untrap_errors()) - return FALSE; - - if (px) *px = x; - if (py) *py = y; - if (pwidth) *pwidth = width; - if (pheight) *pheight = height; - return TRUE; -} - -static void x11_wait_event(Display *dpy, Window w, int type) -{ - XEvent e; - while (!XCheckTypedWindowEvent(dpy, w, type, &e)) - g_usleep(10); -} - static gboolean gst_vaapi_window_x11_show(GstVaapiWindow *window) { From 506122d970fb3425f754bd37f25d3d1358541d85 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 09:13:16 +0000 Subject: [PATCH 0061/3781] Cosmetics (remove an extra line). --- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index ab06ab3170..f6ed6825ed 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -31,7 +31,6 @@ void x11_trap_errors(void) int x11_untrap_errors(void) attribute_hidden; - Window x11_create_window(Display *display, unsigned int width, unsigned int height) attribute_hidden; From 4e2db9d8e4700c35e27a6742ce4437084adb2257 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 09:15:48 +0000 Subject: [PATCH 0062/3781] Move vaapi_utils.* to gstvaapiutils.* --- gst-libs/gst/vaapi/Makefile.am | 4 ++-- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/{vaapi_utils.c => gstvaapiutils.c} | 2 +- gst-libs/gst/vaapi/{vaapi_utils.h => gstvaapiutils.h} | 2 +- gst-libs/gst/vaapi/vaapi_debug.h | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) rename gst-libs/gst/vaapi/{vaapi_utils.c => gstvaapiutils.c} (99%) rename gst-libs/gst/vaapi/{vaapi_utils.h => gstvaapiutils.h} (97%) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 5c4c58f62c..d17ca73fee 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -8,11 +8,11 @@ libgstvaapi_source_c = \ gstvaapisubpicture.c \ gstvaapisurface.c \ gstvaapisurfacepool.c \ + gstvaapiutils.c \ gstvaapivideobuffer.c \ gstvaapivideopool.c \ gstvaapivideosink.c \ gstvaapiwindow.c \ - vaapi_utils.c \ $(NULL) libgstvaapi_source_h = \ @@ -23,12 +23,12 @@ libgstvaapi_source_h = \ gstvaapisubpicture.h \ gstvaapisurface.h \ gstvaapisurfacepool.h \ + gstvaapiutils.h \ gstvaapivideobuffer.h \ gstvaapivideopool.h \ gstvaapivideosink.h \ gstvaapiwindow.h \ vaapi_debug.h \ - vaapi_utils.h \ $(NULL) libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 6910bce26c..6f1896186e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -19,7 +19,7 @@ */ #include "config.h" -#include "vaapi_utils.h" +#include "gstvaapiutils.h" #include "gstvaapidisplay.h" #include diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index e70e1d866a..913ce97f26 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -19,7 +19,7 @@ */ #include "config.h" -#include "vaapi_utils.h" +#include "gstvaapiutils.h" #include "gstvaapidisplay_x11.h" #define DEBUG 1 diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index f8248afaf8..aa55863e83 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -20,7 +20,7 @@ #include "config.h" #include -#include "vaapi_utils.h" +#include "gstvaapiutils.h" #include "gstvaapiimage.h" #include diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 4c6c4f42d4..aa70e46cbd 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -20,7 +20,7 @@ #include "config.h" #include -#include "vaapi_utils.h" +#include "gstvaapiutils.h" #include "gstvaapisubpicture.h" #include diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 0858c17ed6..ef5e228142 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -19,7 +19,7 @@ */ #include "config.h" -#include "vaapi_utils.h" +#include "gstvaapiutils.h" #include "gstvaapisurface.h" #include diff --git a/gst-libs/gst/vaapi/vaapi_utils.c b/gst-libs/gst/vaapi/gstvaapiutils.c similarity index 99% rename from gst-libs/gst/vaapi/vaapi_utils.c rename to gst-libs/gst/vaapi/gstvaapiutils.c index d271bc3f37..608b8d59ca 100644 --- a/gst-libs/gst/vaapi/vaapi_utils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "vaapi_utils.h" +#include "gstvaapiutils.h" #include #include diff --git a/gst-libs/gst/vaapi/vaapi_utils.h b/gst-libs/gst/vaapi/gstvaapiutils.h similarity index 97% rename from gst-libs/gst/vaapi/vaapi_utils.h rename to gst-libs/gst/vaapi/gstvaapiutils.h index f44fe42cf9..3ea908e3ce 100644 --- a/gst-libs/gst/vaapi/vaapi_utils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -1,5 +1,5 @@ /* - * vaapi_utils.h - VA-API utilities + * gstvaapiutils.h - VA-API utilities * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * diff --git a/gst-libs/gst/vaapi/vaapi_debug.h b/gst-libs/gst/vaapi/vaapi_debug.h index 547fb8c469..86d0641818 100644 --- a/gst-libs/gst/vaapi/vaapi_debug.h +++ b/gst-libs/gst/vaapi/vaapi_debug.h @@ -21,7 +21,7 @@ #ifndef VAAPI_DEBUG_H #define VAAPI_DEBUG_H -#include "vaapi_utils.h" +#include "gstvaapiutils.h" #if DEBUG # define D(x) x From d6f883f73a725b099d7be385953e9df9297f8640 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 09:17:41 +0000 Subject: [PATCH 0063/3781] Rename vaapi_debug.h to gstvaapidebug.h. --- gst-libs/gst/vaapi/Makefile.am | 2 +- gst-libs/gst/vaapi/{vaapi_debug.h => gstvaapidebug.h} | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) rename gst-libs/gst/vaapi/{vaapi_debug.h => gstvaapidebug.h} (95%) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index d17ca73fee..f539e37d96 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -16,6 +16,7 @@ libgstvaapi_source_c = \ $(NULL) libgstvaapi_source_h = \ + gstvaapidebug.h \ gstvaapidisplay.h \ gstvaapiimage.h \ gstvaapiimageformat.h \ @@ -28,7 +29,6 @@ libgstvaapi_source_h = \ gstvaapivideopool.h \ gstvaapivideosink.h \ gstvaapiwindow.h \ - vaapi_debug.h \ $(NULL) libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ diff --git a/gst-libs/gst/vaapi/vaapi_debug.h b/gst-libs/gst/vaapi/gstvaapidebug.h similarity index 95% rename from gst-libs/gst/vaapi/vaapi_debug.h rename to gst-libs/gst/vaapi/gstvaapidebug.h index 86d0641818..1430937b12 100644 --- a/gst-libs/gst/vaapi/vaapi_debug.h +++ b/gst-libs/gst/vaapi/gstvaapidebug.h @@ -1,5 +1,5 @@ /* - * vaapi_debug.h - VA-API debugging utilities + * gstvaapidebug.h - VA-API debugging utilities * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 6f1896186e..d9feb7c7f7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -24,7 +24,7 @@ #include #define DEBUG 1 -#include "vaapi_debug.h" +#include "gstvaapidebug.h" GST_DEBUG_CATEGORY(gst_debug_vaapi); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 913ce97f26..bb7badbec2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -23,7 +23,7 @@ #include "gstvaapidisplay_x11.h" #define DEBUG 1 -#include "vaapi_debug.h" +#include "gstvaapidebug.h" G_DEFINE_TYPE(GstVaapiDisplayX11, gst_vaapi_display_x11, diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index aa55863e83..032f59f1fb 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -25,7 +25,7 @@ #include #define DEBUG 1 -#include "vaapi_debug.h" +#include "gstvaapidebug.h" G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, G_TYPE_OBJECT); diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 9d7170d80e..8a6a27c92b 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -22,7 +22,7 @@ #include "gstvaapiimagepool.h" #define DEBUG 1 -#include "vaapi_debug.h" +#include "gstvaapidebug.h" G_DEFINE_TYPE( GstVaapiImagePool, diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index aa70e46cbd..df82ed3728 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -25,7 +25,7 @@ #include #define DEBUG 1 -#include "vaapi_debug.h" +#include "gstvaapidebug.h" G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, G_TYPE_OBJECT); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index ef5e228142..db3dd2004f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -24,7 +24,7 @@ #include #define DEBUG 1 -#include "vaapi_debug.h" +#include "gstvaapidebug.h" G_DEFINE_TYPE(GstVaapiSurface, gst_vaapi_surface, G_TYPE_OBJECT); diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 0c9ee5b67c..4fd8695632 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -22,7 +22,7 @@ #include "gstvaapisurfacepool.h" #define DEBUG 1 -#include "vaapi_debug.h" +#include "gstvaapidebug.h" G_DEFINE_TYPE( GstVaapiSurfacePool, diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 1daeb1e002..a4922bcc3d 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -22,7 +22,7 @@ #include "gstvaapivideobuffer.h" #define DEBUG 1 -#include "vaapi_debug.h" +#include "gstvaapidebug.h" G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, GST_TYPE_BUFFER); diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index bf8d41acec..5b41e42819 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -22,7 +22,7 @@ #include "gstvaapivideopool.h" #define DEBUG 1 -#include "vaapi_debug.h" +#include "gstvaapidebug.h" G_DEFINE_TYPE(GstVaapiVideoPool, gst_vaapi_video_pool, G_TYPE_OBJECT); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 66295649a5..191cbf5039 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -22,7 +22,7 @@ #include "gstvaapiwindow.h" #define DEBUG 1 -#include "vaapi_debug.h" +#include "gstvaapidebug.h" G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, G_TYPE_OBJECT); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index eb648d8368..9f730ff913 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -24,7 +24,7 @@ #include "gstvaapiutils_x11.h" #define DEBUG 1 -#include "vaapi_debug.h" +#include "gstvaapidebug.h" G_DEFINE_TYPE(GstVaapiWindowX11, gst_vaapi_window_x11, GST_VAAPI_TYPE_WINDOW); From 58d3c3665867bc376c7708a4ba2f32dc0f426ca4 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 09:18:57 +0000 Subject: [PATCH 0064/3781] Fix header guards. --- gst-libs/gst/vaapi/gstvaapidebug.h | 6 +++--- gst-libs/gst/vaapi/gstvaapiutils.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils.h | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidebug.h b/gst-libs/gst/vaapi/gstvaapidebug.h index 1430937b12..d94186aa45 100644 --- a/gst-libs/gst/vaapi/gstvaapidebug.h +++ b/gst-libs/gst/vaapi/gstvaapidebug.h @@ -18,8 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef VAAPI_DEBUG_H -#define VAAPI_DEBUG_H +#ifndef GST_VAAPI_DEBUG_H +#define GST_VAAPI_DEBUG_H #include "gstvaapiutils.h" @@ -33,4 +33,4 @@ GST_DEBUG_CATEGORY_EXTERN(gst_debug_vaapi); #define GST_CAT_DEFAULT gst_debug_vaapi -#endif /* VAAPI_DEBUG_H */ +#endif /* GST_VAAPI_DEBUG_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 608b8d59ca..6ed7320b3e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -1,5 +1,5 @@ /* - * vaapi_utils.c - VA-API utilities + * gstvaapiutils.c - VA-API utilities * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 3ea908e3ce..ffdb808f94 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -18,8 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef VAAPI_UTILS_H -#define VAAPI_UTILS_H +#ifndef GST_VAAPI_UTILS_H +#define GST_VAAPI_UTILS_H #include "config.h" #include @@ -45,4 +45,4 @@ const char *string_of_VAProfile(VAProfile profile) const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) attribute_hidden; -#endif /* VAAPI_UTILS_H */ +#endif /* GST_VAAPI_UTILS_H */ From d6a6c1ef989acc1500c7cb87c2d7911e4db72ec8 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 09:21:15 +0000 Subject: [PATCH 0065/3781] Don't install private headers. --- gst-libs/gst/vaapi/Makefile.am | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f539e37d96..656ba43975 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -16,7 +16,6 @@ libgstvaapi_source_c = \ $(NULL) libgstvaapi_source_h = \ - gstvaapidebug.h \ gstvaapidisplay.h \ gstvaapiimage.h \ gstvaapiimageformat.h \ @@ -24,15 +23,20 @@ libgstvaapi_source_h = \ gstvaapisubpicture.h \ gstvaapisurface.h \ gstvaapisurfacepool.h \ - gstvaapiutils.h \ gstvaapivideobuffer.h \ gstvaapivideopool.h \ gstvaapivideosink.h \ gstvaapiwindow.h \ $(NULL) +libgstvaapi_source_priv_h = \ + gstvaapidebug.h \ + gstvaapiutils.h \ + $(NULL) + libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_source_c) \ + $(libgstvaapi_source_priv_h) \ $(NULL) libgstvaapi_@GST_MAJORMINOR@include_HEADERS = \ From ad54bcf903e323209a290c99001a4320c62e4486 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 09:39:07 +0000 Subject: [PATCH 0066/3781] Split X11 support to libgstvaapi-x11-*.so.* --- configure.ac | 5 ++++ gst-libs/gst/vaapi/Makefile.am | 52 ++++++++++++++++++++++++++-------- sys/vaapisink/Makefile.am | 2 +- tests/Makefile.am | 2 +- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index 35f39f9de3..e6a300d799 100644 --- a/configure.ac +++ b/configure.ac @@ -66,6 +66,11 @@ dnl Check for tools AC_PROG_CC AC_PROG_LIBTOOL +dnl Check for GLib +PKG_CHECK_MODULES([GLIB], [glib-2.0]) +AC_SUBST(GLIB_CFLAGS) +AC_SUBST(GLIB_LIBS) + dnl Check for GStreamer PKG_CHECK_MODULES([GST], [gstreamer-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED] diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 656ba43975..25386c6fcd 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -1,4 +1,10 @@ -lib_LTLIBRARIES = libgstvaapi-@GST_MAJORMINOR@.la +lib_LTLIBRARIES = \ + libgstvaapi-@GST_MAJORMINOR@.la \ + libgstvaapi-x11-@GST_MAJORMINOR@.la \ + $(NULL) + +libgstvaapi_includedir = \ + $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi libgstvaapi_source_c = \ gstvaapidisplay.c \ @@ -34,6 +40,23 @@ libgstvaapi_source_priv_h = \ gstvaapiutils.h \ $(NULL) +libgstvaapi_x11_source_c = \ + gstvaapidisplay_x11.c \ + gstvaapiutils.c \ + gstvaapiutils_x11.c \ + gstvaapiwindow_x11.c \ + $(NULL) + +libgstvaapi_x11_source_h = \ + gstvaapidisplay_x11.h \ + gstvaapiwindow_x11.h \ + $(NULL) + +libgstvaapi_x11_source_priv_h = \ + gstvaapiutils.h \ + gstvaapiutils_x11.h \ + $(NULL) + libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_source_c) \ $(libgstvaapi_source_priv_h) \ @@ -44,7 +67,7 @@ libgstvaapi_@GST_MAJORMINOR@include_HEADERS = \ $(NULL) libgstvaapi_@GST_MAJORMINOR@includedir = \ - $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi + $(libgstvaapi_includedir) libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ -I$(top_srcdir)/gst-libs \ @@ -59,24 +82,29 @@ libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ $(LIBVA_LIBS) \ $(NULL) -libgstvaapi_@GST_MAJORMINOR@_la_SOURCES += \ - gstvaapidisplay_x11.c \ - gstvaapiutils_x11.c \ - gstvaapiwindow_x11.c \ +libgstvaapi_x11_@GST_MAJORMINOR@_la_SOURCES = \ + $(libgstvaapi_x11_source_c) \ + $(libgstvaapi_x11_source_priv_h) \ $(NULL) -libgstvaapi_@GST_MAJORMINOR@include_HEADERS += \ - gstvaapidisplay_x11.h \ - gstvaapiutils_x11.h \ - gstvaapiwindow_x11.h \ +libgstvaapi_x11_@GST_MAJORMINOR@include_HEADERS = \ + $(libgstvaapi_x11_source_h) \ $(NULL) -libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS += \ +libgstvaapi_x11_@GST_MAJORMINOR@includedir = \ + $(libgstvaapi_includedir) + +libgstvaapi_x11_@GST_MAJORMINOR@_la_CFLAGS = \ + -I$(top_srcdir)/gst-libs \ + $(GLIB_CFLAGS) \ + $(GST_BASE_CFLAGS) \ $(LIBVA_X11_CFLAGS) \ $(NULL) -libgstvaapi_@GST_MAJORMINOR@_la_LIBADD += \ +libgstvaapi_x11_@GST_MAJORMINOR@_la_LIBADD = \ + $(GLIB_LIBS) \ $(LIBVA_X11_LIBS) \ + libgstvaapi-@GST_MAJORMINOR@.la \ $(NULL) # Extra clean files so that maintainer-clean removes *everything* diff --git a/sys/vaapisink/Makefile.am b/sys/vaapisink/Makefile.am index 7ef17afd86..9fdb92140d 100644 --- a/sys/vaapisink/Makefile.am +++ b/sys/vaapisink/Makefile.am @@ -4,7 +4,7 @@ libgstvaapi_CFLAGS = \ -I$(top_srcdir)/gst-libs libgstvaapi_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la libgstvaapisink_la_SOURCES = \ gstvaapisink.c \ diff --git a/tests/Makefile.am b/tests/Makefile.am index cc7cdcf6a2..de69c18db9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -10,7 +10,7 @@ TEST_CFLAGS = \ $(X11_CFLAGS) TEST_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-@GST_MAJORMINOR@.la \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la \ $(X11_LIBS) test_display_SOURCES = test-display.c From f15f5f6e9833fc149fdfb629f92a56c2ea0ceb4a Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 09:57:25 +0000 Subject: [PATCH 0067/3781] Add pkgconfig files. --- Makefile.am | 2 +- configure.ac | 6 ++++++ pkgconfig/Makefile.am | 18 ++++++++++++++++++ pkgconfig/gstreamer-vaapi-x11.pc.in | 12 ++++++++++++ pkgconfig/gstreamer-vaapi.pc.in | 12 ++++++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 pkgconfig/Makefile.am create mode 100644 pkgconfig/gstreamer-vaapi-x11.pc.in create mode 100644 pkgconfig/gstreamer-vaapi.pc.in diff --git a/Makefile.am b/Makefile.am index e457ea3134..6f737299c2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign -SUBDIRS = gst-libs sys tests +SUBDIRS = gst-libs pkgconfig sys tests # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ diff --git a/configure.ac b/configure.ac index e6a300d799..e4651efb44 100644 --- a/configure.ac +++ b/configure.ac @@ -148,11 +148,17 @@ else AC_MSG_ERROR([Your VA-API SDK does not include SDS extensions]) fi +pkgconfigdir=${libdir}/pkgconfig +AC_SUBST(pkgconfigdir) + AC_OUTPUT([ Makefile gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/vaapi/Makefile + pkgconfig/Makefile + pkgconfig/gstreamer-vaapi.pc + pkgconfig/gstreamer-vaapi-x11.pc sys/Makefile sys/vaapiconvert/Makefile sys/vaapisink/Makefile diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am new file mode 100644 index 0000000000..049d816a4d --- /dev/null +++ b/pkgconfig/Makefile.am @@ -0,0 +1,18 @@ +pcfiles = gstreamer-vaapi-@GST_MAJORMINOR@.pc +pcfiles += gstreamer-vaapi-x11-@GST_MAJORMINOR@.pc + +pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = $(pcfiles) + +EXTRA_DIST = \ + gstreamer-vaapi.pc.in \ + gstreamer-vaapi-x11.pc.in \ + $(NULL) + +CLEANFILES = $(pcfiles) + +%-@GST_MAJORMINOR@.pc: %.pc + cp $< $@ + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/pkgconfig/gstreamer-vaapi-x11.pc.in b/pkgconfig/gstreamer-vaapi-x11.pc.in new file mode 100644 index 0000000000..d3b358d19e --- /dev/null +++ b/pkgconfig/gstreamer-vaapi-x11.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ + +Name: GStreamer VA-API (x11) Plugins Libraries +Description: Streaming media framework, VA-API (x11) plugins libraries +Requires: gstreamer-vaapi-@GST_MAJORMINOR@ libva-x11 +Version: @VERSION@ +Libs: -L${libdir} -lgstvaapi-x11-@GST_MAJORMINOR@ +Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi.pc.in b/pkgconfig/gstreamer-vaapi.pc.in new file mode 100644 index 0000000000..e7d2ec636d --- /dev/null +++ b/pkgconfig/gstreamer-vaapi.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ + +Name: GStreamer VA-API Plugins Libraries +Description: Streaming media framework, VA-API plugins libraries +Requires: gstreamer-@GST_MAJORMINOR@ gstreamer-base-@GST_MAJORMINOR@ libva +Version: @VERSION@ +Libs: -L${libdir} -lgstvaapi-@GST_MAJORMINOR@ +Cflags: -I${includedir} From a681898ce0d41da989a18e014aa7b1c45147b5a7 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 09:59:03 +0000 Subject: [PATCH 0068/3781] Add AM_PROG_CC_C_O, thus fixing this warning: tests/Makefile.am:16: compiling `test-display.c' with per-target flags requires `AM_PROG_CC_C_O' in `configure.ac' --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index e4651efb44..0d72823fda 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,7 @@ AC_SUBST(GST_MAJORMINOR) dnl Check for tools AC_PROG_CC +AM_PROG_CC_C_O AC_PROG_LIBTOOL dnl Check for GLib From 2041c8ca257f89569c3d25bd97602c511ff908a9 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 10:13:36 +0000 Subject: [PATCH 0069/3781] Silence GNU make extensions warning. --- pkgconfig/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index 049d816a4d..1e772a6876 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -1,3 +1,5 @@ +AUTOMAKE_OPTIONS = -Wno-portability + pcfiles = gstreamer-vaapi-@GST_MAJORMINOR@.pc pcfiles += gstreamer-vaapi-x11-@GST_MAJORMINOR@.pc @@ -11,6 +13,7 @@ EXTRA_DIST = \ CLEANFILES = $(pcfiles) +# XXX: this is a GNU make extension %-@GST_MAJORMINOR@.pc: %.pc cp $< $@ From 4a041f42c1e842f4fe4dedb54887e2b65f7777f9 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 13:53:09 +0000 Subject: [PATCH 0070/3781] Add debian packaging. --- Makefile.am | 8 +++++++- configure.ac | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 6f737299c2..99d568d11b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,9 +1,15 @@ AUTOMAKE_OPTIONS = foreign -SUBDIRS = gst-libs pkgconfig sys tests +SUBDIRS = debian gst-libs pkgconfig sys tests # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ aclocal.m4 compile config.guess config.sub \ configure depcomp install-sh ltmain.sh \ Makefile.in missing config.h.in + +deb: dist + -mkdir -p debian-build + cd debian-build && \ + tar zxvf ../$(PACKAGE)-$(VERSION).tar.gz && \ + cd $(PACKAGE)-$(VERSION) && dpkg-buildpackage -rfakeroot -uc -us diff --git a/configure.ac b/configure.ac index 0d72823fda..7325b6d560 100644 --- a/configure.ac +++ b/configure.ac @@ -21,6 +21,18 @@ m4_define([gst_vaapi_micro_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) +# libva package version number +m4_define([libva_sds_version_0_29], [8]) +m4_define([libva_sds_package_version_0_29], [0.29-2+sds11]) +m4_define([libva_sds_version_0_30], [1]) +m4_define([libva_sds_package_version_0_30], [0.30-1+sds1]) +m4_define([libva_glx_sds_version_0_30], [5]) +m4_define([libva_glx_sds_package_version_0_30], [0.30.4-1+sds6]) +m4_define([libva_glx_sds_version_0_31], [1]) +m4_define([libva_glx_sds_package_version_0_31], [0.31.0-1+sds1]) +m4_define([libva_sds_version], [libva_glx_sds_version_0_31]) +m4_define([libva_sds_package_version], [libva_glx_sds_package_version_0_31]) + AC_PREREQ([2.57]) AC_INIT([gst_vaapi], [gst_vaapi_version], [gbeauchesne@splitted-desktop.com], @@ -30,6 +42,15 @@ AC_CANONICAL_TARGET AM_INIT_AUTOMAKE AM_CONFIG_HEADER([config.h]) +TODAY="`LC_ALL=C date +'%a, %d %b %Y %X %z'`" +AC_SUBST(TODAY) + +GST_VAAPI_MAJOR_VERSION=gst_vaapi_major_version +AC_SUBST(GST_VAAPI_MAJOR_VERSION) + +LIBVA_SDS_PACKAGE_VERSION=libva_sds_package_version +AC_SUBST(LIBVA_SDS_PACKAGE_VERSION) + dnl Check for __attribute__((visibility())) AC_CACHE_CHECK([whether __attribute__((visibility())) is supported], vaapi_cv_visibility_attribute, @@ -154,6 +175,13 @@ AC_SUBST(pkgconfigdir) AC_OUTPUT([ Makefile + debian/Makefile + debian/changelog + debian/control + debian/gstreamer$GST_MAJORMINOR-vaapi.install:debian/gstreamer-vaapi.install.in + debian/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:debian/libgstvaapi.install.in + debian/libgstvaapi$GST_VAAPI_MAJOR_VERSION-dev.install:debian/libgstvaapi-dev.install.in + debian/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:debian/libgstvaapi-x11.install.in gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/vaapi/Makefile From 39d5a2f3616feb94e4655ffc7f4a12e1d174e236 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 13:53:54 +0000 Subject: [PATCH 0071/3781] Add debian packaging. --- debian/Makefile.am | 39 +++++++++++++++++++++ debian/changelog.in | 5 +++ debian/compat | 1 + debian/control.in | 57 +++++++++++++++++++++++++++++++ debian/copyright | 34 ++++++++++++++++++ debian/gstreamer-vaapi.install.in | 1 + debian/libgstvaapi-dev.install.in | 3 ++ debian/libgstvaapi-x11.install.in | 1 + debian/libgstvaapi.install.in | 1 + debian/rules | 15 ++++++++ 10 files changed, 157 insertions(+) create mode 100644 debian/Makefile.am create mode 100644 debian/changelog.in create mode 100644 debian/compat create mode 100644 debian/control.in create mode 100644 debian/copyright create mode 100644 debian/gstreamer-vaapi.install.in create mode 100644 debian/libgstvaapi-dev.install.in create mode 100644 debian/libgstvaapi-x11.install.in create mode 100644 debian/libgstvaapi.install.in create mode 100755 debian/rules diff --git a/debian/Makefile.am b/debian/Makefile.am new file mode 100644 index 0000000000..d015ab6372 --- /dev/null +++ b/debian/Makefile.am @@ -0,0 +1,39 @@ +DOCS = \ + AUTHORS \ + COPYING \ + NEWS \ + README \ + $(NULL) + +DEBIANFILES = \ + changelog \ + changelog.in \ + compat \ + control \ + control.in \ + copyright \ + gstreamer-vaapi.install.in \ + gstreamer$(GST_MAJORMINOR)-vaapi.install \ + libgstvaapi.install.in \ + libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ + libgstvaapi-dev.install.in \ + libgstvaapi$(GST_VAAPI_MAJOR_VERSION)-dev.install \ + libgstvaapi-x11.install.in \ + libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ + rules \ + $(NULL) + +DEBIANGENFILES = \ + control \ + changelog \ + gstreamer$(GST_MAJORMINOR)-vaapi.install \ + libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ + libgstvaapi$(GST_VAAPI_MAJOR_VERSION)-dev.install \ + libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ + $(NULL) + +EXTRA_DIST = \ + $(DEBIANFILES) + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in $(DEBIANGENFILES) diff --git a/debian/changelog.in b/debian/changelog.in new file mode 100644 index 0000000000..4ecfad0e9c --- /dev/null +++ b/debian/changelog.in @@ -0,0 +1,5 @@ +gstreamer@GST_MAJORMINOR@-vaapi (@PACKAGE_VERSION@-1) unstable; urgency=low + + * Autogenerated package, see NEWS file for ChangeLog. + + -- Gwenole Beauchesne @TODAY@ diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000000..7ed6ff82de --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control.in b/debian/control.in new file mode 100644 index 0000000000..9db525b9b4 --- /dev/null +++ b/debian/control.in @@ -0,0 +1,57 @@ +Source: gstreamer@GST_MAJORMINOR@-vaapi +Section: libs +Priority: optional +Maintainer: Gwenole Beauchesne +Build-Depends: debhelper (>= 5), + cdbs, + libglib2.0-dev, + libgstreamer@GST_MAJORMINOR@-dev, + libgstreamer-plugins-base@GST_MAJORMINOR@-dev, + libva-dev (>= @LIBVA_SDS_PACKAGE_VERSION@) +Standards-Version: 3.7.2 + +Package: gstreamer@GST_MAJORMINOR@-vaapi +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: VA-API plugins for GStreamer + This package contains GStreamer plugins for VA-API support: + - `vaapiconvert': converts from YUV pixels to VA surfaces + - `vaapisink': a VA-API based video sink + +Package: gstreamer@GST_MAJORMINOR@-vaapi-dbg +Section: libdevel +Architecture: any +Depends: gstreamer@GST_MAJORMINOR@-vaapi (= ${Source-Version}) +Description: VA-API plugins for GStreamer + VA-API support plugins for GStreamer. + . + This package contains the debug files. + +Package: libgstvaapi@GST_VAAPI_MAJOR_VERSION@ +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: GStreamer libraries from the "vaapi" set + VA-API support libraries for GStreamer. + . + This package contains common libraries for the "vaapi" set. + +Package: libgstvaapi-x11-@GST_VAAPI_MAJOR_VERSION@ +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: GStreamer libraries from the "vaapi" set + VA-API support libraries for GStreamer. + . + This package contains x11 libraries for the "vaapi" set. + +Package: libgstvaapi@GST_VAAPI_MAJOR_VERSION@-dev +Architecture: any +Section: libdevel +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: GStreamer development files for libraries from the "vaapi" set + GStreamer/VA-API development files. + . + This package contains development files for GStreamer libraries for + the "vaapi" set. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000000..94da1e1218 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,34 @@ +This package is maintained by: +Gwenole Beauchesne + + +License: + + Copyright (C) 2009, Splitted-Desktop Systems. + All rights reserved. + + Redistribution. Redistribution and use in binary form, without + modification, are permitted provided that the following conditions are + met: + + * Redistributions must reproduce the above copyright notice and the + following disclaimer in the documentation and/or other materials + provided with the distribution. + * Neither the name of Splitted-Desktop Systems nor the names of its + suppliers may be used to endorse or promote products derived from + this software without specific prior written permission. + * No reverse engineering, decompilation, or disassembly of this software + is permitted. + + DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. diff --git a/debian/gstreamer-vaapi.install.in b/debian/gstreamer-vaapi.install.in new file mode 100644 index 0000000000..76b63bdfa5 --- /dev/null +++ b/debian/gstreamer-vaapi.install.in @@ -0,0 +1 @@ +debian/tmp/usr/lib/gstreamer-@GST_MAJORMINOR@/libgstvaapi*.so* diff --git a/debian/libgstvaapi-dev.install.in b/debian/libgstvaapi-dev.install.in new file mode 100644 index 0000000000..a940c52778 --- /dev/null +++ b/debian/libgstvaapi-dev.install.in @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/libgstvaapi*.so +debian/tmp/usr/lib/pkgconfig/gstreamer-vaapi*.pc +debian/tmp/usr/include/gstreamer-@GST_MAJORMINOR@/gst/vaapi/*.h diff --git a/debian/libgstvaapi-x11.install.in b/debian/libgstvaapi-x11.install.in new file mode 100644 index 0000000000..8754fb8456 --- /dev/null +++ b/debian/libgstvaapi-x11.install.in @@ -0,0 +1 @@ +debian/tmp/usr/lib/libgstvaapi-x11-@GST_MAJORMINOR@.so.* diff --git a/debian/libgstvaapi.install.in b/debian/libgstvaapi.install.in new file mode 100644 index 0000000000..e585a6b302 --- /dev/null +++ b/debian/libgstvaapi.install.in @@ -0,0 +1 @@ +debian/tmp/usr/lib/libgstvaapi-@GST_MAJORMINOR@.so.* diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000000..76c4183651 --- /dev/null +++ b/debian/rules @@ -0,0 +1,15 @@ +#!/usr/bin/make -f + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/class/autotools.mk +include /usr/share/cdbs/1/rules/simple-patchsys.mk +include /usr/share/cdbs/1/rules/utils.mk + +# Allow SMP build +ifeq ($(DEBIAN_BUILD_NCPUS),) + DEBIAN_BUILD_NCPUS = $(shell /usr/bin/getconf _NPROCESSORS_ONLN) +endif +ifneq ($(DEBIAN_BUILD_NCPUS),) + EXTRA_MAKE_FLAGS += -j$(DEBIAN_BUILD_NCPUS) +endif +MAKE += $(EXTRA_MAKE_FLAGS) From 8d23df87698792927f7a40d8266b4bc0085e401a Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 13:58:43 +0000 Subject: [PATCH 0072/3781] Update docs. --- NEWS | 4 ++-- README | 21 ++++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index 297704a094..95dc3b24ce 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,5 @@ -gst-vaapi NEWS -- summary of changes. 2010-01-DD +gst-vaapi NEWS -- summary of changes. 2010-03-16 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.1.0 - DD.Jan.2010 +Version 0.1.0 - 16.Mar.2010 * Initial release diff --git a/README b/README index 3dcad3f885..260fe27206 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ - gst-vaapi - VA API support to GStreamer + gstreamer-vaapi + VA-API support to GStreamer Copyright (C) 2010 Splitted-Desktop Systems @@ -8,19 +8,26 @@ License ------- -gst-vaapi is available under the terms of the GNU General Public +gstreamer-vaapi is available under the terms of the GNU General Public License. Overview -------- -gst-vaapi consists in a VA API based videosink for GStreamer and -helper libraries. +gstreamer-vaapi consists in a collection of VA-API based plugins for +GStreamer and helper libraries. + + * `vaapiconvert' is used to convert from video/x-raw-yuv pixels to + video/x-vaapi-surface surfaces + + * `vaapisink' is used to display video/x-vaapi-surface surfaces to + screen. Requirements ------------ -gstreamer-0.10 >= 0.10.0 -gstreamer-plugins-base-0.10 >= 0.10.0 +libgstreamer0.10-dev >= 0.10.0 +libgstreamer-plugins-base0.10-dev >= 0.10.0 +libva-dev >= 0.31.0-1+sds9 From d8e58ec07ebc446b9c494b8c9501b8ba882cf9f1 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 14:07:53 +0000 Subject: [PATCH 0073/3781] Cosmetics (shorten lines). --- configure.ac | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 7325b6d560..f9c65c45ed 100644 --- a/configure.ac +++ b/configure.ac @@ -178,10 +178,14 @@ AC_OUTPUT([ debian/Makefile debian/changelog debian/control - debian/gstreamer$GST_MAJORMINOR-vaapi.install:debian/gstreamer-vaapi.install.in - debian/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:debian/libgstvaapi.install.in - debian/libgstvaapi$GST_VAAPI_MAJOR_VERSION-dev.install:debian/libgstvaapi-dev.install.in - debian/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:debian/libgstvaapi-x11.install.in + debian/gstreamer$GST_MAJORMINOR-vaapi.install:\ +debian/gstreamer-vaapi.install.in + debian/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:\ +debian/libgstvaapi.install.in + debian/libgstvaapi$GST_VAAPI_MAJOR_VERSION-dev.install:\ +debian/libgstvaapi-dev.install.in + debian/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:\ +debian/libgstvaapi-x11.install.in gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/vaapi/Makefile From 0449e62499a2c8bf8fb33d8f18c1c0a0e08c0fb7 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 14:11:46 +0000 Subject: [PATCH 0074/3781] Bump version for development. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index f9c65c45ed..4113f8558f 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ m4_define([gst_plugins_base_version], # gst_vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [1]) -m4_define([gst_vaapi_micro_version], [0]) +m4_define([gst_vaapi_micro_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From 9b9f6de368c8840efcba41fc066ab92ff0d398a4 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 14:12:40 +0000 Subject: [PATCH 0075/3781] Move gstreamer-vaapi package versioning to the top. --- configure.ac | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 4113f8558f..c93f844fab 100644 --- a/configure.ac +++ b/configure.ac @@ -1,3 +1,10 @@ +# gstreamer-vaapi package version number +m4_define([gst_vaapi_major_version], [0]) +m4_define([gst_vaapi_minor_version], [1]) +m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_version], + [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) + # gst version number m4_define([gst_major_version], [0]) m4_define([gst_minor_version], [10]) @@ -14,13 +21,6 @@ m4_define([gst_plugins_base_micro_version], [0]) m4_define([gst_plugins_base_version], [gst_plugins_base_major_version.gst_plugins_base_minor_version.gst_plugins_base_micro_version]) -# gst_vaapi package version number -m4_define([gst_vaapi_major_version], [0]) -m4_define([gst_vaapi_minor_version], [1]) -m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_version], - [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) - # libva package version number m4_define([libva_sds_version_0_29], [8]) m4_define([libva_sds_package_version_0_29], [0.29-2+sds11]) From 8de41f081d85ea6dce12a03c1449b55e2bebb526 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 14:37:47 +0000 Subject: [PATCH 0076/3781] Fix image & surface size cache. --- sys/vaapiconvert/gstvaapiconvert.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index 7fb89ce6f6..afd55784d8 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -329,6 +329,8 @@ gst_vaapiconvert_set_caps( gst_structure_get_int(structure, "height", &height); if (width != convert->image_width || height != convert->image_height) { + convert->image_width = width; + convert->image_height = height; if (convert->images) g_object_unref(convert->images); convert->images = gst_vaapi_image_pool_new(convert->display, incaps); @@ -341,6 +343,8 @@ gst_vaapiconvert_set_caps( gst_structure_get_int(structure, "height", &height); if (width != convert->surface_width || height != convert->surface_height) { + convert->surface_width = width; + convert->surface_height = height; if (convert->surfaces) g_object_unref(convert->surfaces); convert->surfaces = gst_vaapi_surface_pool_new(convert->display, outcaps); From 21a9a0aac205e817f51536c22f866ac7cc34d0d2 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 17:10:02 +0000 Subject: [PATCH 0077/3781] Make GstVaapiVideoBuffer handle two pools. i.e. both image & surface at the same time. --- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 200 ++++++++++++++++------- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 24 +++ 2 files changed, 163 insertions(+), 61 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index a4922bcc3d..8104633ecd 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -20,6 +20,8 @@ #include "config.h" #include "gstvaapivideobuffer.h" +#include +#include #define DEBUG 1 #include "gstvaapidebug.h" @@ -32,45 +34,59 @@ G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, GST_TYPE_BUFFER); GstVaapiVideoBufferPrivate)) struct _GstVaapiVideoBufferPrivate { - GstVaapiVideoPool *pool; - guint pool_type; + GstVaapiVideoPool *image_pool; GstVaapiImage *image; + GstVaapiVideoPool *surface_pool; GstVaapiSurface *surface; guint flags; }; -enum { - POOL_TYPE_NONE, - POOL_TYPE_IMAGE, - POOL_TYPE_SURFACE -}; - static void -gst_vaapi_video_buffer_finalize(GstMiniObject *object) +gst_vaapi_video_buffer_destroy_image(GstVaapiVideoBuffer *buffer) { - GstVaapiVideoBufferPrivate *priv = GST_VAAPI_VIDEO_BUFFER(object)->priv; - GstMiniObjectClass *parent_class; + GstVaapiVideoBufferPrivate * const priv = buffer->priv; if (priv->image) { - if (priv->pool_type == POOL_TYPE_IMAGE) - gst_vaapi_video_pool_put_object(priv->pool, priv->image); + if (priv->image_pool) + gst_vaapi_video_pool_put_object(priv->image_pool, priv->image); else g_object_unref(priv->image); priv->image = NULL; } + if (priv->image_pool) { + g_object_unref(priv->image_pool); + priv->image_pool = NULL; + } +} + +static void +gst_vaapi_video_buffer_destroy_surface(GstVaapiVideoBuffer *buffer) +{ + GstVaapiVideoBufferPrivate * const priv = buffer->priv; + if (priv->surface) { - if (priv->pool_type == POOL_TYPE_SURFACE) - gst_vaapi_video_pool_put_object(priv->pool, priv->surface); + if (priv->surface_pool) + gst_vaapi_video_pool_put_object(priv->surface_pool, priv->surface); else g_object_unref(priv->surface); priv->surface = NULL; } - if (priv->pool) { - g_object_unref(priv->pool); - priv->pool = NULL; + if (priv->surface_pool) { + g_object_unref(priv->surface_pool); + priv->surface_pool = NULL; } +} + +static void +gst_vaapi_video_buffer_finalize(GstMiniObject *object) +{ + GstVaapiVideoBuffer * const buffer = GST_VAAPI_VIDEO_BUFFER(object); + GstMiniObjectClass *parent_class; + + gst_vaapi_video_buffer_destroy_image(buffer); + gst_vaapi_video_buffer_destroy_surface(buffer); parent_class = GST_MINI_OBJECT_CLASS(gst_vaapi_video_buffer_parent_class); if (parent_class->finalize) @@ -94,81 +110,73 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) priv = GST_VAAPI_VIDEO_BUFFER_GET_PRIVATE(buffer); buffer->priv = priv; - priv->pool = NULL; + priv->image_pool = NULL; priv->image = NULL; + priv->surface_pool = NULL; priv->surface = NULL; } -static GstBuffer * -gst_vaapi_video_buffer_new( - GstVaapiVideoPool *pool, - GstVaapiImage *image, - GstVaapiSurface *surface -) +static inline GstVaapiVideoBuffer *gst_vaapi_video_buffer_new(void) { - gpointer vobject = NULL; GstMiniObject *object; - GstVaapiVideoBuffer *buffer; - GstVaapiVideoBufferPrivate *priv; object = gst_mini_object_new(GST_VAAPI_TYPE_VIDEO_BUFFER); if (!object) return NULL; - buffer = GST_VAAPI_VIDEO_BUFFER(object); - priv = buffer->priv; - priv->pool = pool; - priv->pool_type = POOL_TYPE_NONE; - priv->image = image; - priv->surface = surface; - - if (pool) { - vobject = gst_vaapi_video_pool_get_object(pool); - if (!vobject) - goto error; - - if (GST_VAAPI_IS_IMAGE(vobject)) { - priv->pool_type = POOL_TYPE_IMAGE; - priv->image = vobject; - } - else if (GST_VAAPI_IS_SURFACE(vobject)) { - priv->pool_type = POOL_TYPE_SURFACE; - priv->surface = vobject; - } - else - goto error; - } - return GST_BUFFER(buffer); - -error: - if (vobject) - gst_vaapi_video_pool_put_object(pool, vobject); - gst_mini_object_unref(object); - return NULL; + return GST_VAAPI_VIDEO_BUFFER(object); } GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) { + GstVaapiVideoBuffer *buffer; + gboolean is_image_pool, is_surface_pool; + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); - return gst_vaapi_video_buffer_new(g_object_ref(pool), NULL, NULL); + is_image_pool = GST_VAAPI_IS_IMAGE_POOL(pool); + is_surface_pool = GST_VAAPI_IS_SURFACE_POOL(pool); + + if (!is_image_pool && !is_surface_pool) + return NULL; + + buffer = gst_vaapi_video_buffer_new(); + if (buffer && + ((is_image_pool && + gst_vaapi_video_buffer_set_image_from_pool(buffer, pool)) || + (is_surface_pool && + gst_vaapi_video_buffer_set_surface_from_pool(buffer, pool)))) + return GST_BUFFER(buffer); + + gst_mini_object_unref(GST_MINI_OBJECT(buffer)); + return NULL; } GstBuffer * gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) { + GstVaapiVideoBuffer *buffer; + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); - return gst_vaapi_video_buffer_new(NULL, g_object_ref(image), NULL); + buffer = gst_vaapi_video_buffer_new(); + if (buffer) + gst_vaapi_video_buffer_set_image(buffer, image); + return GST_BUFFER(buffer); } GstBuffer * gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) { + GstVaapiVideoBuffer *buffer; + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - return gst_vaapi_video_buffer_new(NULL, NULL, g_object_ref(surface)); + buffer = gst_vaapi_video_buffer_new(); + if (buffer) + gst_vaapi_video_buffer_set_surface(buffer, surface); + return GST_BUFFER(buffer); } GstVaapiImage * @@ -179,6 +187,41 @@ gst_vaapi_video_buffer_get_image(GstVaapiVideoBuffer *buffer) return buffer->priv->image; } +void +gst_vaapi_video_buffer_set_image( + GstVaapiVideoBuffer *buffer, + GstVaapiImage *image +) +{ + g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer)); + g_return_if_fail(GST_VAAPI_IS_IMAGE(image)); + + gst_vaapi_video_buffer_destroy_image(buffer); + + if (image) + buffer->priv->image = g_object_ref(image); +} + +gboolean +gst_vaapi_video_buffer_set_image_from_pool( + GstVaapiVideoBuffer *buffer, + GstVaapiVideoPool *pool +) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_IMAGE_POOL(pool), FALSE); + + gst_vaapi_video_buffer_destroy_image(buffer); + + if (pool) { + buffer->priv->image = gst_vaapi_video_pool_get_object(pool); + if (!buffer->priv->image) + return FALSE; + buffer->priv->image_pool = g_object_ref(pool); + } + return TRUE; +} + GstVaapiSurface * gst_vaapi_video_buffer_get_surface(GstVaapiVideoBuffer *buffer) { @@ -186,3 +229,38 @@ gst_vaapi_video_buffer_get_surface(GstVaapiVideoBuffer *buffer) return buffer->priv->surface; } + +void +gst_vaapi_video_buffer_set_surface( + GstVaapiVideoBuffer *buffer, + GstVaapiSurface *surface +) +{ + g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer)); + g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); + + gst_vaapi_video_buffer_destroy_surface(buffer); + + if (surface) + buffer->priv->surface = g_object_ref(surface); +} + +gboolean +gst_vaapi_video_buffer_set_surface_from_pool( + GstVaapiVideoBuffer *buffer, + GstVaapiVideoPool *pool +) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), FALSE); + + gst_vaapi_video_buffer_destroy_surface(buffer); + + if (pool) { + buffer->priv->surface = gst_vaapi_video_pool_get_object(pool); + if (!buffer->priv->surface) + return FALSE; + buffer->priv->surface_pool = g_object_ref(pool); + } + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index 5cecfec6ff..be19f6f0a8 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -83,9 +83,33 @@ gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface); GstVaapiImage * gst_vaapi_video_buffer_get_image(GstVaapiVideoBuffer *buffer); +void +gst_vaapi_video_buffer_set_image( + GstVaapiVideoBuffer *buffer, + GstVaapiImage *image +); + +gboolean +gst_vaapi_video_buffer_set_image_from_pool( + GstVaapiVideoBuffer *buffer, + GstVaapiVideoPool *pool +); + GstVaapiSurface * gst_vaapi_video_buffer_get_surface(GstVaapiVideoBuffer *buffer); +void +gst_vaapi_video_buffer_set_surface( + GstVaapiVideoBuffer *buffer, + GstVaapiSurface *surface +); + +gboolean +gst_vaapi_video_buffer_set_surface_from_pool( + GstVaapiVideoBuffer *buffer, + GstVaapiVideoPool *pool +); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_BUFFER_H */ From f016dc50c23bc12aeb77a657d762642d3060fe16 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 17:57:23 +0000 Subject: [PATCH 0078/3781] Extend GstVaapiImage API with *_get_image(), *_is_linear(), *_get_data_size(). --- gst-libs/gst/vaapi/gstvaapiimage.c | 80 +++++++++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiimage.h | 9 ++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 032f59f1fb..d18271d7fa 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -55,6 +55,12 @@ enum { PROP_HEIGHT }; +#define SWAP_UINT(a, b) do { \ + unsigned int v = a; \ + a = b; \ + b = v; \ + } while (0) + static void gst_vaapi_image_destroy(GstVaapiImage *image) { @@ -317,11 +323,34 @@ VAImageID gst_vaapi_image_get_id(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID); - g_return_val_if_fail(image->priv->is_constructed, FALSE); + g_return_val_if_fail(image->priv->is_constructed, VA_INVALID_ID); return image->priv->image.image_id; } +gboolean +gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image->priv->is_constructed, FALSE); + + if (!va_image) + return TRUE; + + *va_image = image->priv->image; + + if (image->priv->format != image->priv->internal_format) { + if (!(image->priv->format == GST_VAAPI_IMAGE_I420 && + image->priv->internal_format == GST_VAAPI_IMAGE_YV12) && + !(image->priv->format == GST_VAAPI_IMAGE_YV12 && + image->priv->internal_format == GST_VAAPI_IMAGE_I420)) + return FALSE; + SWAP_UINT(va_image->offsets[1], va_image->offsets[2]); + SWAP_UINT(va_image->pitches[1], va_image->pitches[2]); + } + return TRUE; +} + GstVaapiDisplay * gst_vaapi_image_get_display(GstVaapiImage *image) { @@ -371,6 +400,46 @@ gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) *pheight = image->priv->height; } +gboolean +gst_vaapi_image_is_linear(GstVaapiImage *image) +{ + VAImage va_image; + guint i, width, height, width2, height2, data_size; + + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image->priv->is_constructed, FALSE); + + if (!gst_vaapi_image_get_image(image, &va_image)) + return FALSE; + + for (i = 1; i < va_image.num_planes; i++) + if (va_image.offsets[i] < va_image.offsets[i - 1]) + return FALSE; + + width = image->priv->width; + height = image->priv->height; + width2 = (width + 1) / 2; + height2 = (height + 1) / 2; + + switch (image->priv->internal_format) { + case GST_VAAPI_IMAGE_NV12: + case GST_VAAPI_IMAGE_YV12: + case GST_VAAPI_IMAGE_I420: + data_size = width * height + 2 * width2 * height2; + break; + case GST_VAAPI_IMAGE_ARGB: + case GST_VAAPI_IMAGE_RGBA: + case GST_VAAPI_IMAGE_ABGR: + case GST_VAAPI_IMAGE_BGRA: + data_size = 4 * width * height; + break; + default: + g_error("FIXME: incomplete formats"); + break; + } + return va_image.data_size == data_size; +} + static inline gboolean _gst_vaapi_image_is_mapped(GstVaapiImage *image) { @@ -464,6 +533,15 @@ gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane) return image->priv->image.pitches[plane]; } +guint +gst_vaapi_image_get_data_size(GstVaapiImage *image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image->priv->is_constructed, FALSE); + + return image->priv->image.data_size; +} + gboolean gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) { diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 21d41cce46..322a151c7f 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -85,6 +85,9 @@ gst_vaapi_image_new( VAImageID gst_vaapi_image_get_id(GstVaapiImage *image); +gboolean +gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image); + GstVaapiDisplay * gst_vaapi_image_get_display(GstVaapiImage *image); @@ -100,6 +103,9 @@ gst_vaapi_image_get_height(GstVaapiImage *image); void gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight); +gboolean +gst_vaapi_image_is_linear(GstVaapiImage *image); + gboolean gst_vaapi_image_is_mapped(GstVaapiImage *image); @@ -118,6 +124,9 @@ gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane); guint gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane); +guint +gst_vaapi_image_get_data_size(GstVaapiImage *image); + gboolean gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer); From fae3777c1581e408419035afc2e03e6392a5793a Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 16 Mar 2010 17:57:57 +0000 Subject: [PATCH 0079/3781] Alias sink & src pad buffers whenever possible. --- sys/vaapiconvert/gstvaapiconvert.c | 139 +++++++++++++++++++++++++---- sys/vaapiconvert/gstvaapiconvert.h | 1 + 2 files changed, 121 insertions(+), 19 deletions(-) diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index afd55784d8..c93dee98c0 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -193,6 +193,7 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) convert->surfaces = NULL; convert->surface_width = 0; convert->surface_height = 0; + convert->use_inout_buffers = 0; /* Override buffer allocator on sink pad */ sinkpad = gst_element_get_static_pad(GST_ELEMENT(convert), "sink"); @@ -245,14 +246,34 @@ gst_vaapiconvert_transform( GstVaapiSurface *surface; GstVaapiImage *image; - image = gst_vaapi_video_pool_get_object(convert->images); - if (!image) - return GST_FLOW_UNEXPECTED; - surface = gst_vaapi_video_buffer_get_surface(vbuffer); if (!surface) return GST_FLOW_UNEXPECTED; + if (convert->use_inout_buffers) { + if (!GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) { + GST_DEBUG("GstVaapiVideoBuffer was expected"); + return GST_FLOW_UNEXPECTED; + } + if (inbuf != outbuf) { + GST_DEBUG("same GstVaapiVideoBuffer was expected on both pads"); + return GST_FLOW_UNEXPECTED; + } + + image = gst_vaapi_video_buffer_get_image(vbuffer); + if (!image) + return GST_FLOW_UNEXPECTED; + if (!gst_vaapi_image_unmap(image)) + return GST_FLOW_UNEXPECTED; + + gst_vaapi_surface_put_image(surface, image); + return GST_FLOW_OK; + } + + image = gst_vaapi_video_pool_get_object(convert->images); + if (!image) + return GST_FLOW_UNEXPECTED; + gst_vaapi_image_update_from_buffer(image, inbuf); gst_vaapi_surface_put_image(surface, image); gst_vaapi_video_pool_put_object(convert->images, image); @@ -314,17 +335,13 @@ gst_vaapiconvert_transform_caps( } static gboolean -gst_vaapiconvert_set_caps( - GstBaseTransform *trans, - GstCaps *incaps, - GstCaps *outcaps -) +gst_vaapiconvert_ensure_image_pool(GstVaapiConvert *convert, GstCaps *caps) { - GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); - GstStructure *structure; + GstStructure * const structure = gst_caps_get_structure(caps, 0); + GstVideoFormat vformat; + GstVaapiImage *image; gint width, height; - structure = gst_caps_get_structure(incaps, 0); gst_structure_get_int(structure, "width", &width); gst_structure_get_int(structure, "height", &height); @@ -333,12 +350,31 @@ gst_vaapiconvert_set_caps( convert->image_height = height; if (convert->images) g_object_unref(convert->images); - convert->images = gst_vaapi_image_pool_new(convert->display, incaps); + convert->images = gst_vaapi_image_pool_new(convert->display, caps); if (!convert->images) return FALSE; - } - structure = gst_caps_get_structure(outcaps, 0); + /* Check if we can alias sink & output buffers (same data_size) */ + if (gst_video_format_parse_caps(caps, &vformat, NULL, NULL)) { + image = gst_vaapi_video_pool_get_object(convert->images); + if (image) { + convert->use_inout_buffers = + (gst_vaapi_image_is_linear(image) && + (gst_vaapi_image_get_data_size(image) == + gst_video_format_get_size(vformat, width, height))); + gst_vaapi_video_pool_put_object(convert->images, image); + } + } + } + return TRUE; +} + +static gboolean +gst_vaapiconvert_ensure_surface_pool(GstVaapiConvert *convert, GstCaps *caps) +{ + GstStructure * const structure = gst_caps_get_structure(caps, 0); + gint width, height; + gst_structure_get_int(structure, "width", &width); gst_structure_get_int(structure, "height", &height); @@ -347,13 +383,31 @@ gst_vaapiconvert_set_caps( convert->surface_height = height; if (convert->surfaces) g_object_unref(convert->surfaces); - convert->surfaces = gst_vaapi_surface_pool_new(convert->display, outcaps); + convert->surfaces = gst_vaapi_surface_pool_new(convert->display, caps); if (!convert->surfaces) return FALSE; } return TRUE; } +static gboolean +gst_vaapiconvert_set_caps( + GstBaseTransform *trans, + GstCaps *incaps, + GstCaps *outcaps +) +{ + GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + + if (!gst_vaapiconvert_ensure_image_pool(convert, incaps)) + return FALSE; + + if (!gst_vaapiconvert_ensure_surface_pool(convert, outcaps)) + return FALSE; + + return TRUE; +} + static gboolean gst_vaapiconvert_get_unit_size( GstBaseTransform *trans, @@ -383,6 +437,44 @@ gst_vaapiconvert_buffer_alloc( GstBuffer **pbuf ) { + GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstBuffer *buffer = NULL; + GstVaapiImage *image; + + /* Check if we can use the inout-buffers optimization */ + if (!gst_vaapiconvert_ensure_surface_pool(convert, caps)) + goto error; + if (!gst_vaapiconvert_ensure_image_pool(convert, caps)) + goto error; + if (!convert->use_inout_buffers) + return GST_FLOW_OK; + + buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); + if (!buffer) + goto error; + + GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); + if (!gst_vaapi_video_buffer_set_image_from_pool(vbuffer, convert->images)) + goto error; + + image = gst_vaapi_video_buffer_get_image(vbuffer); + g_assert(image); + + if (!gst_vaapi_image_map(image)) + goto error; + + GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0); + GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image); + + gst_buffer_set_caps(buffer, caps); + *pbuf = buffer; + return GST_FLOW_OK; + +error: + /* We can't use the inout-buffers optimization. Disable it. */ + if (buffer) + gst_buffer_unref(buffer); + convert->use_inout_buffers = FALSE; return GST_FLOW_OK; } @@ -419,9 +511,18 @@ gst_vaapiconvert_prepare_output_buffer( GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); GstBuffer *buffer; - buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); - if (!buffer) - return GST_FLOW_UNEXPECTED; + if (convert->use_inout_buffers) { + if (!GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) { + GST_DEBUG("GstVaapiVideoBuffer was expected"); + return GST_FLOW_UNEXPECTED; + } + buffer = gst_buffer_ref(inbuf); + } + else { + buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); + if (!buffer) + return GST_FLOW_UNEXPECTED; + } gst_buffer_set_caps(buffer, caps); *poutbuf = buffer; diff --git a/sys/vaapiconvert/gstvaapiconvert.h b/sys/vaapiconvert/gstvaapiconvert.h index 98487f625d..aee556ddbf 100644 --- a/sys/vaapiconvert/gstvaapiconvert.h +++ b/sys/vaapiconvert/gstvaapiconvert.h @@ -71,6 +71,7 @@ struct _GstVaapiConvert { GstVaapiVideoPool *surfaces; guint surface_width; guint surface_height; + unsigned int use_inout_buffers : 1; }; struct _GstVaapiConvertClass { From 69943d51ff505d768017c99fd0bbda8a9638e6b1 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 17 Mar 2010 06:49:27 +0000 Subject: [PATCH 0080/3781] Fix gst_vaapi_window_x11_destroy(). --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 9f730ff913..632f79c7ca 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -97,14 +97,18 @@ gst_vaapi_window_x11_destroy(GstVaapiWindow *window) GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - if (priv->create_window && priv->xid) { - gst_vaapi_window_x11_hide(window); - XDestroyWindow(dpy, priv->xid); + if (priv->xid) { + if (priv->create_window) { + gst_vaapi_window_x11_hide(window); + XDestroyWindow(dpy, priv->xid); + } priv->xid = None; } - g_object_unref(priv->display); - priv->display = NULL; + if (priv->display) { + g_object_unref(priv->display); + priv->display = NULL; + } } static gboolean From 912684b9049d4b0c5aa8a41166a1f56957756c85 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 17 Mar 2010 07:17:17 +0000 Subject: [PATCH 0081/3781] Don't show window by default during creation. --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 40 +++++++++++++++++-------- tests/test-windows.c | 7 +++-- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 632f79c7ca..2b85b70e66 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -34,9 +34,10 @@ G_DEFINE_TYPE(GstVaapiWindowX11, gst_vaapi_window_x11, GST_VAAPI_TYPE_WINDOW); GstVaapiWindowX11Private)) struct _GstVaapiWindowX11Private { - gboolean create_window; GstVaapiDisplay *display; Window xid; + unsigned int create_window : 1; + unsigned int is_visible : 1; }; enum { @@ -52,10 +53,18 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + if (priv->is_visible) + return TRUE; + x11_trap_errors(); XMapWindow(dpy, priv->xid); - x11_wait_event(dpy, priv->xid, MapNotify); - return x11_untrap_errors() == 0; + if (priv->create_window) + x11_wait_event(dpy, priv->xid, MapNotify); + if (x11_untrap_errors() != 0) + return FALSE; + + priv->is_visible = TRUE; + return TRUE; } static gboolean @@ -64,10 +73,18 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + if (!priv->is_visible) + return TRUE; + x11_trap_errors(); XUnmapWindow(dpy, priv->xid); - x11_wait_event(dpy, priv->xid, UnmapNotify); - return x11_untrap_errors() == 0; + if (priv->create_window) + x11_wait_event(dpy, priv->xid, UnmapNotify); + if (x11_untrap_errors() != 0) + return FALSE; + + priv->is_visible = FALSE; + return TRUE; } static gboolean @@ -82,13 +99,11 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint width, guint height) dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); priv->xid = x11_create_window(dpy, width, height); - if (!gst_vaapi_window_x11_show(window)) + if (!priv->xid) return FALSE; - x11_trap_errors(); XRaiseWindow(dpy, priv->xid); - XSync(dpy, False); - return x11_untrap_errors() == 0; + return TRUE; } static void @@ -98,10 +113,8 @@ gst_vaapi_window_x11_destroy(GstVaapiWindow *window) Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); if (priv->xid) { - if (priv->create_window) { - gst_vaapi_window_x11_hide(window); + if (priv->create_window) XDestroyWindow(dpy, priv->xid); - } priv->xid = None; } @@ -291,9 +304,10 @@ gst_vaapi_window_x11_init(GstVaapiWindowX11 *window) GstVaapiWindowX11Private *priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); window->priv = priv; - priv->create_window = TRUE; priv->display = NULL; priv->xid = None; + priv->create_window = TRUE; + priv->is_visible = FALSE; } GstVaapiWindow * diff --git a/tests/test-windows.c b/tests/test-windows.c index 07db884d76..e09fd7744c 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -212,6 +212,8 @@ main(int argc, char *argv[]) if (!window) g_error("could not create window"); + gst_vaapi_window_show(window); + if (!gst_vaapi_window_put_surface(window, surface, flags)) g_error("could not render surface"); @@ -243,13 +245,12 @@ main(int argc, char *argv[]) if (!win) g_error("could not create X window"); - XMapRaised(dpy, win); - XSync(dpy, False); - window = gst_vaapi_window_x11_new_with_xid(display, win); if (!window) g_error("could not create window"); + gst_vaapi_window_show(window); + if (!gst_vaapi_window_put_surface(window, surface, flags)) g_error("could not render surface"); From 65cc4aa494dc19d8576b0c74bbb65235ab2624a8 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 17 Mar 2010 07:20:19 +0000 Subject: [PATCH 0082/3781] Initialize the X window in a ::set_caps() handler. Also fix build with GStreamer < 0.10.25. i.e. use preroll/render hooks. --- sys/vaapisink/gstvaapisink.c | 49 +++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 6f55f02ee2..4c00ad44d4 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -135,25 +135,46 @@ gst_vaapisink_stop(GstBaseSink *base_sink) return TRUE; } -static GstFlowReturn -gst_vaapisink_show_frame(GstVideoSink *video_sink, GstBuffer *buffer) +static gboolean +gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { - GstVaapiSink * const sink = GST_VAAPISINK(video_sink); + GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + GstStructure * const structure = gst_caps_get_structure(caps, 0); + gint width, height; + + if (!structure) + return FALSE; + if (!gst_structure_get_int(structure, "width", &width)) + return FALSE; + if (!gst_structure_get_int(structure, "height", &height)) + return FALSE; + + if (sink->window) + gst_vaapi_window_set_size(sink->window, width, height); + else { + sink->window = gst_vaapi_window_x11_new(sink->display, width, height); + if (!sink->window) + return FALSE; + gst_vaapi_window_show(sink->window); + } + return TRUE; +} + +static GstFlowReturn +gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) +{ + GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); GstVaapiSurface *surface; - guint width, height, flags; + guint flags; + + if (!sink->window) + return GST_FLOW_UNEXPECTED; surface = gst_vaapi_video_buffer_get_surface(vbuffer); if (!surface) return GST_FLOW_UNEXPECTED; - gst_vaapi_surface_get_size(surface, &width, &height); - if (!sink->window) { - sink->window = gst_vaapi_window_x11_new(sink->display, width, height); - if (!sink->window) - return GST_FLOW_UNEXPECTED; - } - flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; if (!gst_vaapi_window_put_surface(sink->window, surface, flags)) return GST_FLOW_UNEXPECTED; @@ -229,7 +250,6 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass); - GstVideoSinkClass * const videosink_class = GST_VIDEO_SINK_CLASS(klass); object_class->finalize = gst_vaapisink_finalize; object_class->set_property = gst_vaapisink_set_property; @@ -237,8 +257,9 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->start = gst_vaapisink_start; basesink_class->stop = gst_vaapisink_stop; - - videosink_class->show_frame = gst_vaapisink_show_frame; + basesink_class->set_caps = gst_vaapisink_set_caps; + basesink_class->preroll = gst_vaapisink_show_frame; + basesink_class->render = gst_vaapisink_show_frame; g_object_class_install_property (object_class, From bcb5d3f13877e497974e5fa7432f9b4a55a12216 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 17 Mar 2010 07:59:31 +0000 Subject: [PATCH 0083/3781] Add VA display locking utilities. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 51 +++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapidisplay.h | 20 ++++++++-- gst-libs/gst/vaapi/gstvaapiimage.c | 20 +++++++--- gst-libs/gst/vaapi/gstvaapisubpicture.c | 8 +++- gst-libs/gst/vaapi/gstvaapisurface.c | 18 +++++++-- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 48 ++++++++++++++++------- 6 files changed, 134 insertions(+), 31 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index d9feb7c7f7..ad3f2a616d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -36,6 +36,7 @@ G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT); GstVaapiDisplayPrivate)) struct _GstVaapiDisplayPrivate { + GStaticMutex mutex; VADisplay display; gboolean create_display; VAProfile *profiles; @@ -292,6 +293,18 @@ gst_vaapi_display_create(GstVaapiDisplay *display) return TRUE; } +static void +gst_vaapi_display_lock_default(GstVaapiDisplay *display) +{ + g_static_mutex_lock(&display->priv->mutex); +} + +static void +gst_vaapi_display_unlock_default(GstVaapiDisplay *display) +{ + g_static_mutex_unlock(&display->priv->mutex); +} + static void gst_vaapi_display_finalize(GObject *object) { @@ -360,15 +373,19 @@ static void gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); GST_DEBUG_CATEGORY_INIT(gst_debug_vaapi, "vaapi", 0, "VA-API helper"); g_type_class_add_private(klass, sizeof(GstVaapiDisplayPrivate)); - object_class->finalize = gst_vaapi_display_finalize; - object_class->set_property = gst_vaapi_display_set_property; - object_class->get_property = gst_vaapi_display_get_property; - object_class->constructed = gst_vaapi_display_constructed; + object_class->finalize = gst_vaapi_display_finalize; + object_class->set_property = gst_vaapi_display_set_property; + object_class->get_property = gst_vaapi_display_get_property; + object_class->constructed = gst_vaapi_display_constructed; + + dpy_class->lock_display = gst_vaapi_display_lock_default; + dpy_class->unlock_display = gst_vaapi_display_unlock_default; g_object_class_install_property (object_class, @@ -394,6 +411,8 @@ gst_vaapi_display_init(GstVaapiDisplay *display) priv->subpicture_formats = NULL; priv->subpicture_flags = NULL; priv->num_subpicture_formats = 0; + + g_static_mutex_init(&priv->mutex); } GstVaapiDisplay * @@ -404,6 +423,30 @@ gst_vaapi_display_new_with_display(VADisplay va_display) NULL); } +void +gst_vaapi_display_lock(GstVaapiDisplay *display) +{ + GstVaapiDisplayClass *klass; + + g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); + + klass = GST_VAAPI_DISPLAY_GET_CLASS(display); + if (klass->lock_display) + klass->lock_display(display); +} + +void +gst_vaapi_display_unlock(GstVaapiDisplay *display) +{ + GstVaapiDisplayClass *klass; + + g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); + + klass = GST_VAAPI_DISPLAY_GET_CLASS(display); + if (klass->unlock_display) + klass->unlock_display(display); +} + VADisplay gst_vaapi_display_get_display(GstVaapiDisplay *display) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index cccb095653..de142c91b8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -54,6 +54,12 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_VADISPLAY(display) \ gst_vaapi_display_get_display(display) +#define GST_VAAPI_DISPLAY_LOCK(display) \ + gst_vaapi_display_lock(display) + +#define GST_VAAPI_DISPLAY_UNLOCK(display) \ + gst_vaapi_display_unlock(display) + typedef struct _GstVaapiDisplay GstVaapiDisplay; typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; @@ -69,9 +75,11 @@ struct _GstVaapiDisplayClass { /*< private >*/ GObjectClass parent_class; - gboolean (*open_display) (GstVaapiDisplay *display); - void (*close_display)(GstVaapiDisplay *display); - VADisplay (*get_display) (GstVaapiDisplay *display); + gboolean (*open_display) (GstVaapiDisplay *display); + void (*close_display) (GstVaapiDisplay *display); + void (*lock_display) (GstVaapiDisplay *display); + void (*unlock_display)(GstVaapiDisplay *display); + VADisplay (*get_display) (GstVaapiDisplay *display); }; GType @@ -80,6 +88,12 @@ gst_vaapi_display_get_type(void); GstVaapiDisplay * gst_vaapi_display_new_with_display(VADisplay va_display); +void +gst_vaapi_display_lock(GstVaapiDisplay *display); + +void +gst_vaapi_display_unlock(GstVaapiDisplay *display); + VADisplay gst_vaapi_display_get_display(GstVaapiDisplay *display); diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index d18271d7fa..7d9027be5a 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -65,13 +65,17 @@ static void gst_vaapi_image_destroy(GstVaapiImage *image) { GstVaapiImagePrivate * const priv = image->priv; - VADisplay dpy = gst_vaapi_display_get_display(priv->display); VAStatus status; gst_vaapi_image_unmap(image); if (priv->image.image_id != VA_INVALID_ID) { - status = vaDestroyImage(dpy, priv->image.image_id); + GST_VAAPI_DISPLAY_LOCK(priv->display); + status = vaDestroyImage( + GST_VAAPI_DISPLAY_VADISPLAY(priv->display), + priv->image.image_id + ); + GST_VAAPI_DISPLAY_UNLOCK(priv->display); if (!vaapi_check_status(status, "vaDestroyImage()")) g_warning("failed to destroy image 0x%08x\n", priv->image.image_id); priv->image.image_id = VA_INVALID_ID; @@ -97,13 +101,15 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) if (!va_format) return FALSE; + GST_VAAPI_DISPLAY_LOCK(priv->display); status = vaCreateImage( - gst_vaapi_display_get_display(priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(priv->display), (VAImageFormat *)va_format, priv->width, priv->height, &priv->image ); + GST_VAAPI_DISPLAY_UNLOCK(priv->display); return (status == VA_STATUS_SUCCESS && priv->image.format.fourcc == va_format->fourcc); } @@ -467,11 +473,13 @@ gst_vaapi_image_map(GstVaapiImage *image) if (_gst_vaapi_image_is_mapped(image)) return TRUE; + GST_VAAPI_DISPLAY_LOCK(image->priv->display); status = vaMapBuffer( - gst_vaapi_display_get_display(image->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(image->priv->display), image->priv->image.buf, &image_data ); + GST_VAAPI_DISPLAY_UNLOCK(image->priv->display); if (!vaapi_check_status(status, "vaMapBuffer()")) return FALSE; @@ -490,10 +498,12 @@ gst_vaapi_image_unmap(GstVaapiImage *image) if (!_gst_vaapi_image_is_mapped(image)) return FALSE; + GST_VAAPI_DISPLAY_LOCK(image->priv->display); status = vaUnmapBuffer( - gst_vaapi_display_get_display(image->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(image->priv->display), image->priv->image.buf ); + GST_VAAPI_DISPLAY_UNLOCK(image->priv->display); if (!vaapi_check_status(status, "vaUnmapBuffer()")) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index df82ed3728..e74bfdd413 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -56,10 +56,12 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) if (priv->subpicture_id != VA_INVALID_ID) { display = gst_vaapi_image_get_display(priv->image); if (display) { + GST_VAAPI_DISPLAY_LOCK(display); status = vaDestroySubpicture( - gst_vaapi_display_get_display(display), + GST_VAAPI_DISPLAY_VADISPLAY(display), priv->subpicture_id ); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaDestroySubpicture()")) g_warning("failed to destroy subpicture 0x%08x\n", priv->subpicture_id); @@ -88,11 +90,13 @@ gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture) if (!display) return FALSE; + GST_VAAPI_DISPLAY_LOCK(display); status = vaCreateSubpicture( - gst_vaapi_display_get_display(display), + GST_VAAPI_DISPLAY_VADISPLAY(display), gst_vaapi_image_get_id(priv->image), &subpicture_id ); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaCreateSubpicture()")) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index db3dd2004f..40b5cded66 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -55,11 +55,15 @@ static void gst_vaapi_surface_destroy(GstVaapiSurface *surface) { GstVaapiSurfacePrivate * const priv = surface->priv; - VADisplay dpy = GST_VAAPI_DISPLAY_VADISPLAY(priv->display); VAStatus status; if (priv->surface_id != VA_INVALID_SURFACE) { - status = vaDestroySurfaces(dpy, &priv->surface_id, 1); + GST_VAAPI_DISPLAY_LOCK(priv->display); + status = vaDestroySurfaces( + GST_VAAPI_DISPLAY_VADISPLAY(priv->display), + &priv->surface_id, 1 + ); + GST_VAAPI_DISPLAY_UNLOCK(priv->display); if (!vaapi_check_status(status, "vaDestroySurfaces()")) g_warning("failed to destroy surface 0x%08x\n", priv->surface_id); priv->surface_id = VA_INVALID_SURFACE; @@ -94,6 +98,7 @@ gst_vaapi_surface_create(GstVaapiSurface *surface) return FALSE; } + GST_VAAPI_DISPLAY_LOCK(priv->display); status = vaCreateSurfaces( GST_VAAPI_DISPLAY_VADISPLAY(priv->display), priv->width, @@ -101,6 +106,7 @@ gst_vaapi_surface_create(GstVaapiSurface *surface) format, 1, &surface_id ); + GST_VAAPI_DISPLAY_UNLOCK(priv->display); if (!vaapi_check_status(status, "vaCreateSurfaces()")) return FALSE; @@ -259,7 +265,7 @@ gst_vaapi_surface_init(GstVaapiSurface *surface) priv->surface_id = VA_INVALID_SURFACE; priv->width = 0; priv->height = 0; - priv->chroma_type = 0; + priv->chroma_type = 0; } GstVaapiSurface * @@ -354,12 +360,14 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) if (image_id == VA_INVALID_ID) return FALSE; + GST_VAAPI_DISPLAY_LOCK(surface->priv->display); status = vaGetImage( GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), surface->priv->surface_id, 0, 0, width, height, image_id ); + GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); if (!vaapi_check_status(status, "vaGetImage()")) return FALSE; @@ -384,6 +392,7 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) if (image_id == VA_INVALID_ID) return FALSE; + GST_VAAPI_DISPLAY_LOCK(surface->priv->display); status = vaPutImage( GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), surface->priv->surface_id, @@ -391,6 +400,7 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) 0, 0, width, height, 0, 0, width, height ); + GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); if (!vaapi_check_status(status, "vaPutImage()")) return FALSE; @@ -404,10 +414,12 @@ gst_vaapi_surface_sync(GstVaapiSurface *surface) g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + GST_VAAPI_DISPLAY_LOCK(surface->priv->display); status = vaSyncSurface( GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), surface->priv->surface_id ); + GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); if (!vaapi_check_status(status, "vaSyncSurface()")) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 2b85b70e66..63526d35c9 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -52,15 +52,19 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + gboolean has_errors; if (priv->is_visible) return TRUE; + GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); XMapWindow(dpy, priv->xid); if (priv->create_window) x11_wait_event(dpy, priv->xid, MapNotify); - if (x11_untrap_errors() != 0) + has_errors = x11_untrap_errors() != 0; + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + if (has_errors) return FALSE; priv->is_visible = TRUE; @@ -72,15 +76,19 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + gboolean has_errors; if (!priv->is_visible) return TRUE; + GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); XUnmapWindow(dpy, priv->xid); if (priv->create_window) x11_wait_event(dpy, priv->xid, UnmapNotify); - if (x11_untrap_errors() != 0) + has_errors = x11_untrap_errors() != 0; + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + if (has_errors) return FALSE; priv->is_visible = FALSE; @@ -96,14 +104,14 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint width, guint height) if (!priv->create_window && priv->xid) return TRUE; - dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + + GST_VAAPI_DISPLAY_LOCK(priv->display); priv->xid = x11_create_window(dpy, width, height); - - if (!priv->xid) - return FALSE; - - XRaiseWindow(dpy, priv->xid); - return TRUE; + if (priv->xid) + XRaiseWindow(dpy, priv->xid); + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + return priv->xid != None; } static void @@ -113,8 +121,11 @@ gst_vaapi_window_x11_destroy(GstVaapiWindow *window) Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); if (priv->xid) { - if (priv->create_window) + if (priv->create_window) { + GST_VAAPI_DISPLAY_LOCK(priv->display); XDestroyWindow(dpy, priv->xid); + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + } priv->xid = None; } @@ -128,10 +139,12 @@ static gboolean gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + gboolean has_errors; if (!priv->xid) return FALSE; + GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); XResizeWindow( GST_VAAPI_DISPLAY_XDISPLAY(priv->display), @@ -139,9 +152,9 @@ gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height) width, height ); - if (x11_untrap_errors() != 0) - return FALSE; - return TRUE; + has_errors = x11_untrap_errors() != 0; + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + return !has_errors; } static gboolean @@ -153,10 +166,15 @@ gst_vaapi_window_x11_render( guint flags ) { + GstVaapiDisplay *display; VASurfaceID surface_id; VAStatus status; unsigned int va_flags = 0; + display = gst_vaapi_surface_get_display(surface); + if (!display) + return FALSE; + surface_id = gst_vaapi_surface_get_id(surface); if (surface_id == VA_INVALID_ID) return FALSE; @@ -173,8 +191,9 @@ gst_vaapi_window_x11_render( else if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_601) va_flags |= VA_SRC_BT601; + GST_VAAPI_DISPLAY_LOCK(display); status = vaPutSurface( - GST_VAAPI_DISPLAY_VADISPLAY(gst_vaapi_surface_get_display(surface)), + GST_VAAPI_DISPLAY_VADISPLAY(display), surface_id, GST_VAAPI_WINDOW_X11(window)->priv->xid, src_rect->x, @@ -188,6 +207,7 @@ gst_vaapi_window_x11_render( NULL, 0, va_flags ); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaPutSurface()")) return FALSE; From cf432f9ec8dc08378ab854cd139ddea5e2997058 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 17 Mar 2010 10:43:02 +0000 Subject: [PATCH 0084/3781] Optimize gst_vaapi_image_is_linear() and simplify gst_vaapi_image_update_from_buffer(). --- gst-libs/gst/vaapi/gstvaapiimage.c | 200 ++++++++++++++--------------- 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 7d9027be5a..1d793a8ee7 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -36,13 +36,15 @@ G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, G_TYPE_OBJECT); struct _GstVaapiImagePrivate { GstVaapiDisplay *display; - gboolean is_constructed; + VAImage internal_image; VAImage image; guchar *image_data; GstVaapiImageFormat internal_format; GstVaapiImageFormat format; guint width; guint height; + guint is_constructed : 1; + guint is_linear : 1; }; enum { @@ -69,16 +71,17 @@ gst_vaapi_image_destroy(GstVaapiImage *image) gst_vaapi_image_unmap(image); - if (priv->image.image_id != VA_INVALID_ID) { + if (priv->internal_image.image_id != VA_INVALID_ID) { GST_VAAPI_DISPLAY_LOCK(priv->display); status = vaDestroyImage( GST_VAAPI_DISPLAY_VADISPLAY(priv->display), - priv->image.image_id + priv->internal_image.image_id ); GST_VAAPI_DISPLAY_UNLOCK(priv->display); if (!vaapi_check_status(status, "vaDestroyImage()")) - g_warning("failed to destroy image 0x%08x\n", priv->image.image_id); - priv->image.image_id = VA_INVALID_ID; + g_warning("failed to destroy image 0x%08x\n", + priv->internal_image.image_id); + priv->internal_image.image_id = VA_INVALID_ID; } if (priv->display) { @@ -107,40 +110,93 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) (VAImageFormat *)va_format, priv->width, priv->height, - &priv->image + &priv->internal_image ); GST_VAAPI_DISPLAY_UNLOCK(priv->display); - return (status == VA_STATUS_SUCCESS && - priv->image.format.fourcc == va_format->fourcc); + if (status != VA_STATUS_SUCCESS || + priv->internal_image.format.fourcc != va_format->fourcc) + return FALSE; + + priv->internal_format = format; + return TRUE; +} + +static gboolean +_gst_vaapi_image_is_linear(GstVaapiImage *image) +{ + GstVaapiImagePrivate * const priv = image->priv; + guint i, width, height, width2, height2, data_size; + + for (i = 1; i < priv->image.num_planes; i++) + if (priv->image.offsets[i] < priv->image.offsets[i - 1]) + return FALSE; + + width = priv->width; + height = priv->height; + width2 = (width + 1) / 2; + height2 = (height + 1) / 2; + + switch (priv->internal_format) { + case GST_VAAPI_IMAGE_NV12: + case GST_VAAPI_IMAGE_YV12: + case GST_VAAPI_IMAGE_I420: + data_size = width * height + 2 * width2 * height2; + break; + case GST_VAAPI_IMAGE_ARGB: + case GST_VAAPI_IMAGE_RGBA: + case GST_VAAPI_IMAGE_ABGR: + case GST_VAAPI_IMAGE_BGRA: + data_size = 4 * width * height; + break; + default: + g_error("FIXME: incomplete formats"); + break; + } + return priv->image.data_size == data_size; } static gboolean gst_vaapi_image_create(GstVaapiImage *image) { GstVaapiImagePrivate * const priv = image->priv; + GstVaapiImageFormat format = priv->format; + const VAImageFormat *va_format; - if (_gst_vaapi_image_create(image, priv->format)) { - priv->internal_format = priv->format; - return TRUE; + if (!_gst_vaapi_image_create(image, format)) { + switch (format) { + case GST_VAAPI_IMAGE_I420: + format = GST_VAAPI_IMAGE_YV12; + break; + case GST_VAAPI_IMAGE_YV12: + format = GST_VAAPI_IMAGE_I420; + break; + default: + format = 0; + break; + } + if (!format || !_gst_vaapi_image_create(image, format)) + return FALSE; } + priv->image = priv->internal_image; - switch (priv->format) { - case GST_VAAPI_IMAGE_I420: - priv->internal_format = GST_VAAPI_IMAGE_YV12; - break; - case GST_VAAPI_IMAGE_YV12: - priv->internal_format = GST_VAAPI_IMAGE_I420; - break; - default: - priv->internal_format = 0; - break; + if (priv->format != priv->internal_format) { + switch (priv->format) { + case GST_VAAPI_IMAGE_YV12: + case GST_VAAPI_IMAGE_I420: + va_format = gst_vaapi_image_format_get_va_format(priv->format); + if (!va_format) + return FALSE; + priv->image.format = *va_format; + SWAP_UINT(priv->image.offsets[1], priv->image.offsets[2]); + SWAP_UINT(priv->image.pitches[1], priv->image.pitches[2]); + break; + default: + break; + } } - if (!priv->internal_format) - return FALSE; - if (!_gst_vaapi_image_create(image, priv->internal_format)) - return FALSE; GST_DEBUG("image 0x%08x", priv->image.image_id); + priv->is_linear = _gst_vaapi_image_is_linear(image); return TRUE; } @@ -290,16 +346,23 @@ gst_vaapi_image_init(GstVaapiImage *image) { GstVaapiImagePrivate *priv = GST_VAAPI_IMAGE_GET_PRIVATE(image); - image->priv = priv; - priv->display = NULL; - priv->image_data = NULL; - priv->width = 0; - priv->height = 0; - priv->format = 0; + image->priv = priv; + priv->display = NULL; + priv->image_data = NULL; + priv->width = 0; + priv->height = 0; + priv->internal_format = 0; + priv->format = 0; + priv->is_constructed = FALSE; + priv->is_linear = FALSE; + + memset(&priv->internal_image, 0, sizeof(priv->internal_image)); + priv->internal_image.image_id = VA_INVALID_ID; + priv->internal_image.buf = VA_INVALID_ID; memset(&priv->image, 0, sizeof(priv->image)); - priv->image.image_id = VA_INVALID_ID; - priv->image.buf = VA_INVALID_ID; + priv->image.image_id = VA_INVALID_ID; + priv->image.buf = VA_INVALID_ID; } GstVaapiImage * @@ -340,20 +403,9 @@ gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image) g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); g_return_val_if_fail(image->priv->is_constructed, FALSE); - if (!va_image) - return TRUE; + if (va_image) + *va_image = image->priv->image; - *va_image = image->priv->image; - - if (image->priv->format != image->priv->internal_format) { - if (!(image->priv->format == GST_VAAPI_IMAGE_I420 && - image->priv->internal_format == GST_VAAPI_IMAGE_YV12) && - !(image->priv->format == GST_VAAPI_IMAGE_YV12 && - image->priv->internal_format == GST_VAAPI_IMAGE_I420)) - return FALSE; - SWAP_UINT(va_image->offsets[1], va_image->offsets[2]); - SWAP_UINT(va_image->pitches[1], va_image->pitches[2]); - } return TRUE; } @@ -409,41 +461,10 @@ gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) gboolean gst_vaapi_image_is_linear(GstVaapiImage *image) { - VAImage va_image; - guint i, width, height, width2, height2, data_size; - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); g_return_val_if_fail(image->priv->is_constructed, FALSE); - if (!gst_vaapi_image_get_image(image, &va_image)) - return FALSE; - - for (i = 1; i < va_image.num_planes; i++) - if (va_image.offsets[i] < va_image.offsets[i - 1]) - return FALSE; - - width = image->priv->width; - height = image->priv->height; - width2 = (width + 1) / 2; - height2 = (height + 1) / 2; - - switch (image->priv->internal_format) { - case GST_VAAPI_IMAGE_NV12: - case GST_VAAPI_IMAGE_YV12: - case GST_VAAPI_IMAGE_I420: - data_size = width * height + 2 * width2 * height2; - break; - case GST_VAAPI_IMAGE_ARGB: - case GST_VAAPI_IMAGE_RGBA: - case GST_VAAPI_IMAGE_ABGR: - case GST_VAAPI_IMAGE_BGRA: - data_size = 4 * width * height; - break; - default: - g_error("FIXME: incomplete formats"); - break; - } - return va_image.data_size == data_size; + return image->priv->is_linear; } static inline gboolean @@ -564,7 +585,6 @@ gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) guint i, j; guchar *data; guint32 data_size; - gboolean swap_YUV; g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); g_return_val_if_fail(image->priv->is_constructed, FALSE); @@ -582,12 +602,6 @@ gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) if (format != priv->format) return FALSE; - swap_YUV = (priv->format != priv->internal_format && - ((priv->format == GST_VAAPI_IMAGE_I420 && - priv->internal_format == GST_VAAPI_IMAGE_YV12) || - (priv->format == GST_VAAPI_IMAGE_YV12 && - priv->internal_format == GST_VAAPI_IMAGE_I420))); - structure = gst_caps_get_structure(caps, 0); gst_structure_get_int(structure, "width", &width); gst_structure_get_int(structure, "height", &height); @@ -597,7 +611,7 @@ gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) if (!gst_vaapi_image_map(image)) return FALSE; - if (format == priv->internal_format && data_size == priv->image.data_size) + if (priv->is_linear && data_size == priv->image.data_size) memcpy(priv->image_data, data, data_size); else { /* XXX: copied from gst_video_format_get_row_stride() -- no NV12? */ @@ -649,20 +663,6 @@ gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) } if (size2 != data_size) g_error("data_size mismatch %d / %u", size2, data_size); - if (swap_YUV) { - guint offset = offsets[1]; - guint stride = pitches[1]; - guint width = widths [1]; - guint height = heights[1]; - offsets[1] = offsets[2]; - pitches[1] = pitches[2]; - widths [1] = widths [2]; - heights[1] = heights[2]; - offsets[2] = offset; - pitches[2] = stride; - widths [2] = width; - heights[2] = height; - } for (i = 0; i < priv->image.num_planes; i++) { guchar *src = data + offsets[i]; guchar *dst = priv->image_data + priv->image.offsets[i]; From c561cead2bbba77d57eca92c3afad445e1b63833 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 08:02:25 +0000 Subject: [PATCH 0085/3781] Use gtypes. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 26 ++++++++++++------------- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 6 +++--- sys/vaapiconvert/gstvaapiconvert.h | 2 +- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index ad3f2a616d..78dec96ddd 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -40,12 +40,12 @@ struct _GstVaapiDisplayPrivate { VADisplay display; gboolean create_display; VAProfile *profiles; - unsigned int num_profiles; + guint num_profiles; VAImageFormat *image_formats; - unsigned int num_image_formats; + guint num_image_formats; VAImageFormat *subpicture_formats; - unsigned int *subpicture_flags; - unsigned int num_subpicture_formats; + guint *subpicture_flags; + guint num_subpicture_formats; }; enum { @@ -57,7 +57,7 @@ enum { static void append_format( VAImageFormat **pva_formats, - unsigned int *pnum_va_formats, + guint *pnum_va_formats, GstVaapiImageFormat format ) { @@ -80,9 +80,9 @@ append_format( } static void -filter_formats(VAImageFormat **pva_formats, unsigned int *pnum_va_formats) +filter_formats(VAImageFormat **pva_formats, guint *pnum_va_formats) { - unsigned int i = 0; + guint i = 0; gboolean has_YV12 = FALSE; gboolean has_I420 = FALSE; @@ -204,7 +204,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) GstVaapiDisplayPrivate * const priv = display->priv; VAStatus status; int major_version, minor_version; - unsigned int i; + guint i; if (!priv->display && priv->create_display) { GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); @@ -266,7 +266,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) priv->subpicture_formats = g_new(VAImageFormat, priv->num_subpicture_formats); if (!priv->subpicture_formats) return FALSE; - priv->subpicture_flags = g_new(unsigned int, priv->num_subpicture_formats); + priv->subpicture_flags = g_new(guint, priv->num_subpicture_formats); if (!priv->subpicture_flags) return FALSE; status = vaQuerySubpictureFormats( @@ -473,10 +473,10 @@ _gst_vaapi_display_has_format( GstVaapiDisplay *display, GstVaapiImageFormat format, const VAImageFormat *va_formats, - unsigned int num_va_formats + guint num_va_formats ) { - unsigned int i; + guint i; g_return_val_if_fail(format != 0, FALSE); @@ -490,11 +490,11 @@ static GstCaps * _gst_vaapi_display_get_caps( GstVaapiDisplay *display, const VAImageFormat *va_formats, - unsigned int num_va_formats + guint num_va_formats ) { GstCaps *out_caps; - unsigned int i; + guint i; out_caps = gst_caps_new_empty(); if (!out_caps) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 1d793a8ee7..4b0fd47b64 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -58,7 +58,7 @@ enum { }; #define SWAP_UINT(a, b) do { \ - unsigned int v = a; \ + guint v = a; \ a = b; \ b = v; \ } while (0) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index dcc95b5363..1cfb66bd00 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -56,7 +56,7 @@ static const int x11_event_mask = (KeyPressMask | StructureNotifyMask); Window -x11_create_window(Display *display, unsigned int width, unsigned int height) +x11_create_window(Display *display, guint width, guint height) { Window root_window, window; int screen, depth; @@ -110,7 +110,7 @@ x11_get_geometry( { Window rootwin; int x, y; - unsigned int width, height, border_width, depth; + guint width, height, border_width, depth; x11_trap_errors(); XGetGeometry( diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index f6ed6825ed..402f00817f 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -32,7 +32,7 @@ int x11_untrap_errors(void) attribute_hidden; Window -x11_create_window(Display *display, unsigned int width, unsigned int height) +x11_create_window(Display *display, guint width, guint height) attribute_hidden; gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 63526d35c9..58fe7f9140 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -36,8 +36,8 @@ G_DEFINE_TYPE(GstVaapiWindowX11, gst_vaapi_window_x11, GST_VAAPI_TYPE_WINDOW); struct _GstVaapiWindowX11Private { GstVaapiDisplay *display; Window xid; - unsigned int create_window : 1; - unsigned int is_visible : 1; + guint create_window : 1; + guint is_visible : 1; }; enum { @@ -169,7 +169,7 @@ gst_vaapi_window_x11_render( GstVaapiDisplay *display; VASurfaceID surface_id; VAStatus status; - unsigned int va_flags = 0; + guint va_flags = 0; display = gst_vaapi_surface_get_display(surface); if (!display) diff --git a/sys/vaapiconvert/gstvaapiconvert.h b/sys/vaapiconvert/gstvaapiconvert.h index aee556ddbf..b37ff2d732 100644 --- a/sys/vaapiconvert/gstvaapiconvert.h +++ b/sys/vaapiconvert/gstvaapiconvert.h @@ -71,7 +71,7 @@ struct _GstVaapiConvert { GstVaapiVideoPool *surfaces; guint surface_width; guint surface_height; - unsigned int use_inout_buffers : 1; + guint use_inout_buffers : 1; }; struct _GstVaapiConvertClass { From 79c168751a1fc86f39ed5e04469890fd8849b3f8 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 08:16:59 +0000 Subject: [PATCH 0086/3781] Factor out buffers negotiation and optimization checks. --- sys/vaapiconvert/gstvaapiconvert.c | 48 ++++++++++++++++++++---------- sys/vaapiconvert/gstvaapiconvert.h | 3 +- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index c93dee98c0..a30aceb4f3 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -186,14 +186,15 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) { GstPad *sinkpad; - convert->display = NULL; - convert->images = NULL; - convert->image_width = 0; - convert->image_height = 0; - convert->surfaces = NULL; - convert->surface_width = 0; - convert->surface_height = 0; - convert->use_inout_buffers = 0; + convert->display = NULL; + convert->images = NULL; + convert->image_width = 0; + convert->image_height = 0; + convert->surfaces = NULL; + convert->surface_width = 0; + convert->surface_height = 0; + convert->can_use_inout_buffers = FALSE; + convert->use_inout_buffers = FALSE; /* Override buffer allocator on sink pad */ sinkpad = gst_element_get_static_pad(GST_ELEMENT(convert), "sink"); @@ -358,7 +359,7 @@ gst_vaapiconvert_ensure_image_pool(GstVaapiConvert *convert, GstCaps *caps) if (gst_video_format_parse_caps(caps, &vformat, NULL, NULL)) { image = gst_vaapi_video_pool_get_object(convert->images); if (image) { - convert->use_inout_buffers = + convert->can_use_inout_buffers = (gst_vaapi_image_is_linear(image) && (gst_vaapi_image_get_data_size(image) == gst_video_format_get_size(vformat, width, height))); @@ -390,6 +391,26 @@ gst_vaapiconvert_ensure_surface_pool(GstVaapiConvert *convert, GstCaps *caps) return TRUE; } +static gboolean +gst_vaapiconvert_negotiate_buffers( + GstVaapiConvert *convert, + GstCaps *incaps, + GstCaps *outcaps +) +{ + if (!gst_vaapiconvert_ensure_image_pool(convert, incaps)) + return FALSE; + + if (!gst_vaapiconvert_ensure_surface_pool(convert, outcaps)) + return FALSE; + + convert->use_inout_buffers = convert->can_use_inout_buffers; + GST_DEBUG("use-inout-buffers: %spossible, %s", + convert->can_use_inout_buffers ? "" : "not ", + convert->use_inout_buffers ? "enabled" : "disabled"); + return TRUE; +} + static gboolean gst_vaapiconvert_set_caps( GstBaseTransform *trans, @@ -399,10 +420,7 @@ gst_vaapiconvert_set_caps( { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); - if (!gst_vaapiconvert_ensure_image_pool(convert, incaps)) - return FALSE; - - if (!gst_vaapiconvert_ensure_surface_pool(convert, outcaps)) + if (!gst_vaapiconvert_negotiate_buffers(convert, incaps, outcaps)) return FALSE; return TRUE; @@ -442,9 +460,7 @@ gst_vaapiconvert_buffer_alloc( GstVaapiImage *image; /* Check if we can use the inout-buffers optimization */ - if (!gst_vaapiconvert_ensure_surface_pool(convert, caps)) - goto error; - if (!gst_vaapiconvert_ensure_image_pool(convert, caps)) + if (!gst_vaapiconvert_negotiate_buffers(convert, caps, caps)) goto error; if (!convert->use_inout_buffers) return GST_FLOW_OK; diff --git a/sys/vaapiconvert/gstvaapiconvert.h b/sys/vaapiconvert/gstvaapiconvert.h index b37ff2d732..c41877b36a 100644 --- a/sys/vaapiconvert/gstvaapiconvert.h +++ b/sys/vaapiconvert/gstvaapiconvert.h @@ -71,7 +71,8 @@ struct _GstVaapiConvert { GstVaapiVideoPool *surfaces; guint surface_width; guint surface_height; - guint use_inout_buffers : 1; + guint can_use_inout_buffers : 1; + guint use_inout_buffers : 1; }; struct _GstVaapiConvertClass { From c0462fe0c845b941f1724a93a5bc6041716b48c6 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 08:45:57 +0000 Subject: [PATCH 0087/3781] Check if our inout buffer is still alive or default to a separate output buffer. --- sys/vaapiconvert/gstvaapiconvert.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index a30aceb4f3..5e64ed4445 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -527,14 +527,13 @@ gst_vaapiconvert_prepare_output_buffer( GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); GstBuffer *buffer; - if (convert->use_inout_buffers) { - if (!GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) { - GST_DEBUG("GstVaapiVideoBuffer was expected"); - return GST_FLOW_UNEXPECTED; - } + if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) buffer = gst_buffer_ref(inbuf); - } else { + if (convert->use_inout_buffers) { + GST_DEBUG("upstream element destroyed our inout buffer"); + convert->use_inout_buffers = FALSE; + } buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); if (!buffer) return GST_FLOW_UNEXPECTED; From 941e7d8d63944aca532f64fd60a67b8dbc3540dc Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 12:52:58 +0000 Subject: [PATCH 0088/3781] Fix typo. --- tests/test-windows.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-windows.c b/tests/test-windows.c index e09fd7744c..745208bbdd 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -197,7 +197,7 @@ main(int argc, char *argv[]) if (!image) g_error("could not create Gst/VA image"); if (!draw_rgb_rects(image)) - g_error("could not draw RGB rectangels"); + g_error("could not draw RGB rectangles"); if (!gst_vaapi_surface_put_image(surface, image)) g_error("could not upload image"); From f80e194549aa9dd3e447179e283969e5ef4715e5 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 12:56:53 +0000 Subject: [PATCH 0089/3781] Improve gst_vaapi_image_new() sanity checks. --- gst-libs/gst/vaapi/gstvaapiimage.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 4b0fd47b64..039f55f1d5 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -373,6 +373,8 @@ gst_vaapi_image_new( guint height ) { + GstVaapiImage *image; + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); g_return_val_if_fail(width > 0, NULL); g_return_val_if_fail(height > 0, NULL); @@ -380,12 +382,22 @@ gst_vaapi_image_new( GST_DEBUG("format %" GST_FOURCC_FORMAT ", size %ux%u", GST_FOURCC_ARGS(format), width, height); - return g_object_new(GST_VAAPI_TYPE_IMAGE, - "display", display, - "format", format, - "width", width, - "height", height, - NULL); + image = g_object_new( + GST_VAAPI_TYPE_IMAGE, + "display", display, + "format", format, + "width", width, + "height", height, + NULL + ); + if (!image) + return NULL; + + if (!image->priv->is_constructed) { + g_object_unref(image); + return NULL; + } + return image; } VAImageID From 087b1dabda293dc3d1f2b9919c5714ce033b0f89 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 12:59:55 +0000 Subject: [PATCH 0090/3781] Split map/unmap functions into internal functions that don't check preconditions. --- gst-libs/gst/vaapi/gstvaapiimage.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 039f55f1d5..78f582f2af 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -63,13 +63,19 @@ enum { b = v; \ } while (0) +static gboolean +_gst_vaapi_image_map(GstVaapiImage *image); + +static gboolean +_gst_vaapi_image_unmap(GstVaapiImage *image); + static void gst_vaapi_image_destroy(GstVaapiImage *image) { GstVaapiImagePrivate * const priv = image->priv; VAStatus status; - gst_vaapi_image_unmap(image); + _gst_vaapi_image_unmap(image); if (priv->internal_image.image_id != VA_INVALID_ID) { GST_VAAPI_DISPLAY_LOCK(priv->display); @@ -497,12 +503,18 @@ gst_vaapi_image_is_mapped(GstVaapiImage *image) gboolean gst_vaapi_image_map(GstVaapiImage *image) { - void *image_data; - VAStatus status; - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); g_return_val_if_fail(image->priv->is_constructed, FALSE); + return _gst_vaapi_image_map(image); +} + +gboolean +_gst_vaapi_image_map(GstVaapiImage *image) +{ + void *image_data; + VAStatus status; + if (_gst_vaapi_image_is_mapped(image)) return TRUE; @@ -523,11 +535,17 @@ gst_vaapi_image_map(GstVaapiImage *image) gboolean gst_vaapi_image_unmap(GstVaapiImage *image) { - VAStatus status; - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); g_return_val_if_fail(image->priv->is_constructed, FALSE); + return _gst_vaapi_image_unmap(image); +} + +gboolean +_gst_vaapi_image_unmap(GstVaapiImage *image) +{ + VAStatus status; + if (!_gst_vaapi_image_is_mapped(image)) return FALSE; From 9ecf541b678914288b69e20a58a2fbfa709abc85 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 13:08:17 +0000 Subject: [PATCH 0091/3781] Try YV12 & I420 image formats too. --- tests/test-windows.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tests/test-windows.c b/tests/test-windows.c index 745208bbdd..1e3ca49cb1 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -174,8 +174,17 @@ main(int argc, char *argv[]) GstVaapiDisplay *display; GstVaapiWindow *window; GstVaapiSurface *surface; - GstVaapiImage *image; + GstVaapiImage *image = NULL; + GstVaapiImageFormat format; guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + guint i; + + static const GstVaapiImageFormat image_formats[] = { + GST_VAAPI_IMAGE_NV12, + GST_VAAPI_IMAGE_YV12, + GST_VAAPI_IMAGE_I420, + 0 + }; static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; static const guint width = 320; @@ -193,14 +202,22 @@ main(int argc, char *argv[]) if (!surface) g_error("could not create Gst/VA surface"); - image = gst_vaapi_image_new(display, GST_VAAPI_IMAGE_NV12, width, height); + for (i = 0; image_formats[i]; i++) { + image = gst_vaapi_image_new(display, image_formats[i], width, height); + if (image) { + format = image_formats[i]; + break; + } + } if (!image) g_error("could not create Gst/VA image"); + if (!draw_rgb_rects(image)) g_error("could not draw RGB rectangles"); if (!gst_vaapi_surface_put_image(surface, image)) g_error("could not upload image"); + if (!gst_vaapi_surface_sync(surface)) g_error("could not complete image upload"); From b9bf5678f908c74df68cadc449c51886441e462e Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 13:49:50 +0000 Subject: [PATCH 0092/3781] Make it possible to bin an X11 window to GstVaapiWindowX11 with plain g_object_new() and "xid" property. i.e. get foreign window size in gst_vaapi_window_x11_create(). --- gst-libs/gst/vaapi/gstvaapiwindow.c | 23 +++++++++++++-------- gst-libs/gst/vaapi/gstvaapiwindow.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 27 ++++++++++--------------- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 191cbf5039..d927ad33ad 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -51,12 +51,23 @@ gst_vaapi_window_destroy(GstVaapiWindow *window) } static gboolean -gst_vaapi_window_create(GstVaapiWindow *window, guint width, guint height) +gst_vaapi_window_create(GstVaapiWindow *window) { - if (width == 0 || height == 0) + GstVaapiWindowPrivate * const priv = window->priv; + guint width, height; + + width = priv->width; + height = priv->height; + + if (!GST_VAAPI_WINDOW_GET_CLASS(window)->create(window, &width, &height)) return FALSE; - return GST_VAAPI_WINDOW_GET_CLASS(window)->create(window, width, height); + if (width != priv->width || height != priv->height) { + GST_DEBUG("backend resized window to %ux%u", width, height); + priv->width = width; + priv->height = height; + } + return TRUE; } static void @@ -119,11 +130,7 @@ gst_vaapi_window_constructed(GObject *object) GstVaapiWindow * const window = GST_VAAPI_WINDOW(object); GObjectClass *parent_class; - window->priv->is_constructed = gst_vaapi_window_create( - window, - window->priv->width, - window->priv->height - ); + window->priv->is_constructed = gst_vaapi_window_create(window); parent_class = G_OBJECT_CLASS(gst_vaapi_window_parent_class); if (parent_class->constructed) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 1095f7adaa..7c2fb567a8 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -78,7 +78,7 @@ struct _GstVaapiWindowClass { /*< private >*/ GObjectClass parent_class; - gboolean (*create) (GstVaapiWindow *window, guint width, guint height); + gboolean (*create) (GstVaapiWindow *window, guint *width, guint *height); void (*destroy)(GstVaapiWindow *window); gboolean (*show) (GstVaapiWindow *window); gboolean (*hide) (GstVaapiWindow *window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 58fe7f9140..1063920bae 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -96,18 +96,21 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) } static gboolean -gst_vaapi_window_x11_create(GstVaapiWindow *window, guint width, guint height) +gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; - Display *dpy; + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + gboolean ok; - if (!priv->create_window && priv->xid) - return TRUE; - - dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + if (!priv->create_window && priv->xid) { + GST_VAAPI_DISPLAY_LOCK(priv->display); + ok = x11_get_geometry(dpy, priv->xid, NULL, NULL, width, height); + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + return ok; + } GST_VAAPI_DISPLAY_LOCK(priv->display); - priv->xid = x11_create_window(dpy, width, height); + priv->xid = x11_create_window(dpy, *width, *height); if (priv->xid) XRaiseWindow(dpy, priv->xid); GST_VAAPI_DISPLAY_UNLOCK(priv->display); @@ -349,22 +352,14 @@ gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) GstVaapiWindow * gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) { - Display *dpy; - guint width, height; - GST_DEBUG("new window from xid 0x%08x", xid); g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - - dpy = GST_VAAPI_DISPLAY_XDISPLAY(display); - if (!dpy || !x11_get_geometry(dpy, xid, NULL, NULL, &width, &height)) - return NULL; + g_return_val_if_fail(xid != None, NULL); return g_object_new(GST_VAAPI_TYPE_WINDOW_X11, "display", display, "xid", xid, - "width", width, - "height", height, NULL); } From ea2c6c502ccd49e84a28fa2574b8395c36e5b348 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 15:28:59 +0000 Subject: [PATCH 0093/3781] Add gst_vaapi_surface_derive_image() API. --- gst-libs/gst/vaapi/gstvaapiimage.c | 216 ++++++++++++++++++++++----- gst-libs/gst/vaapi/gstvaapiimage.h | 3 + gst-libs/gst/vaapi/gstvaapisurface.c | 27 ++++ gst-libs/gst/vaapi/gstvaapisurface.h | 3 + 4 files changed, 214 insertions(+), 35 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 78f582f2af..b9ad8dd6cd 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -43,6 +43,7 @@ struct _GstVaapiImagePrivate { GstVaapiImageFormat format; guint width; guint height; + guint create_image : 1; guint is_constructed : 1; guint is_linear : 1; }; @@ -51,6 +52,7 @@ enum { PROP_0, PROP_DISPLAY, + PROP_IMAGE, PROP_IMAGE_ID, PROP_FORMAT, PROP_WIDTH, @@ -69,6 +71,75 @@ _gst_vaapi_image_map(GstVaapiImage *image); static gboolean _gst_vaapi_image_unmap(GstVaapiImage *image); +static gboolean +_gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image); + +/* + * VAImage wrapper + */ + +#define VAAPI_TYPE_IMAGE vaapi_image_get_type() + +static gpointer +vaapi_image_copy(gpointer va_image) +{ + return g_slice_dup(VAImage, va_image); +} + +static void +vaapi_image_free(gpointer va_image) +{ + if (G_LIKELY(va_image)) + g_slice_free(VAImage, va_image); +} + +static GType +vaapi_image_get_type(void) +{ + static GType type = 0; + + if (G_UNLIKELY(type == 0)) + type = g_boxed_type_register_static( + "VAImage", + vaapi_image_copy, + vaapi_image_free + ); + return type; +} + +static gboolean +vaapi_image_is_linear(const VAImage *va_image) +{ + guint i, width, height, width2, height2, data_size; + + for (i = 1; i < va_image->num_planes; i++) + if (va_image->offsets[i] < va_image->offsets[i - 1]) + return FALSE; + + width = va_image->width; + height = va_image->height; + width2 = (width + 1) / 2; + height2 = (height + 1) / 2; + + switch (va_image->format.fourcc) { + case VA_FOURCC('N','V','1','2'): + case VA_FOURCC('Y','V','1','2'): + case VA_FOURCC('I','4','2','0'): + data_size = width * height + 2 * width2 * height2; + break; + case VA_FOURCC('A','R','G','B'): + case VA_FOURCC('R','G','B','A'): + case VA_FOURCC('A','B','G','R'): + case VA_FOURCC('B','G','R','A'): + data_size = 4 * width * height; + break; + default: + g_error("FIXME: incomplete formats"); + break; + } + return va_image->data_size == data_size; +} + static void gst_vaapi_image_destroy(GstVaapiImage *image) { @@ -103,6 +174,10 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) const VAImageFormat *va_format; VAStatus status; + if (!priv->create_image) + return (priv->image.image_id != VA_INVALID_ID && + priv->image.buf != VA_INVALID_ID); + if (!gst_vaapi_display_has_image_format(priv->display, format)) return FALSE; @@ -127,40 +202,6 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) return TRUE; } -static gboolean -_gst_vaapi_image_is_linear(GstVaapiImage *image) -{ - GstVaapiImagePrivate * const priv = image->priv; - guint i, width, height, width2, height2, data_size; - - for (i = 1; i < priv->image.num_planes; i++) - if (priv->image.offsets[i] < priv->image.offsets[i - 1]) - return FALSE; - - width = priv->width; - height = priv->height; - width2 = (width + 1) / 2; - height2 = (height + 1) / 2; - - switch (priv->internal_format) { - case GST_VAAPI_IMAGE_NV12: - case GST_VAAPI_IMAGE_YV12: - case GST_VAAPI_IMAGE_I420: - data_size = width * height + 2 * width2 * height2; - break; - case GST_VAAPI_IMAGE_ARGB: - case GST_VAAPI_IMAGE_RGBA: - case GST_VAAPI_IMAGE_ABGR: - case GST_VAAPI_IMAGE_BGRA: - data_size = 4 * width * height; - break; - default: - g_error("FIXME: incomplete formats"); - break; - } - return priv->image.data_size == data_size; -} - static gboolean gst_vaapi_image_create(GstVaapiImage *image) { @@ -202,7 +243,7 @@ gst_vaapi_image_create(GstVaapiImage *image) } GST_DEBUG("image 0x%08x", priv->image.image_id); - priv->is_linear = _gst_vaapi_image_is_linear(image); + priv->is_linear = vaapi_image_is_linear(&priv->image); return TRUE; } @@ -229,6 +270,12 @@ gst_vaapi_image_set_property( case PROP_DISPLAY: priv->display = g_object_ref(g_value_get_object(value)); break; + case PROP_IMAGE: { + const VAImage * const va_image = g_value_get_boxed(value); + if (va_image) + _gst_vaapi_image_set_image(image, va_image); + break; + } case PROP_FORMAT: priv->format = g_value_get_uint(value); break; @@ -258,6 +305,9 @@ gst_vaapi_image_get_property( case PROP_DISPLAY: g_value_set_pointer(value, gst_vaapi_image_get_display(image)); break; + case PROP_IMAGE: + g_value_set_boxed(value, &image->priv->image); + break; case PROP_IMAGE_ID: g_value_set_uint(value, gst_vaapi_image_get_id(image)); break; @@ -310,6 +360,15 @@ gst_vaapi_image_class_init(GstVaapiImageClass *klass) GST_VAAPI_TYPE_DISPLAY, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property + (object_class, + PROP_IMAGE, + g_param_spec_boxed("image", + "Image", + "The VA image", + VAAPI_TYPE_IMAGE, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_IMAGE_ID, @@ -359,6 +418,7 @@ gst_vaapi_image_init(GstVaapiImage *image) priv->height = 0; priv->internal_format = 0; priv->format = 0; + priv->create_image = TRUE; priv->is_constructed = FALSE; priv->is_linear = FALSE; @@ -406,6 +466,37 @@ gst_vaapi_image_new( return image; } +GstVaapiImage * +gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image) +{ + GstVaapiImage *image; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(va_image, NULL); + g_return_val_if_fail(va_image->image_id != VA_INVALID_ID, NULL); + g_return_val_if_fail(va_image->buf != VA_INVALID_ID, NULL); + + GST_DEBUG("VA image 0x%08x, format %" GST_FOURCC_FORMAT ", size %ux%u", + va_image->image_id, + GST_FOURCC_ARGS(va_image->format.fourcc), + va_image->width, va_image->height); + + image = g_object_new( + GST_VAAPI_TYPE_IMAGE, + "display", display, + "image", va_image, + NULL + ); + if (!image) + return NULL; + + if (!image->priv->is_constructed) { + g_object_unref(image); + return NULL; + } + return image; +} + VAImageID gst_vaapi_image_get_id(GstVaapiImage *image) { @@ -427,6 +518,61 @@ gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image) return TRUE; } +gboolean +_gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) +{ + GstVaapiImagePrivate * const priv = image->priv; + GstVaapiImageFormat format; + VAImage alt_va_image; + const VAImageFormat *alt_va_format; + + if (!va_image) + return FALSE; + + format = gst_vaapi_image_format(&va_image->format); + if (!format) + return FALSE; + + priv->create_image = FALSE; + priv->internal_image = *va_image; + priv->internal_format = format; + priv->is_linear = vaapi_image_is_linear(va_image); + priv->image = *va_image; + priv->format = format; + priv->width = va_image->width; + priv->height = va_image->height; + + /* Try to linearize image */ + if (!priv->is_linear) { + switch (format) { + case GST_VAAPI_IMAGE_I420: + format = GST_VAAPI_IMAGE_YV12; + break; + case GST_VAAPI_IMAGE_YV12: + format = GST_VAAPI_IMAGE_I420; + break; + default: + format = 0; + break; + } + if (format && + (alt_va_format = gst_vaapi_image_format_get_va_format(format))) { + alt_va_image = *va_image; + alt_va_image.format = *alt_va_format; + SWAP_UINT(alt_va_image.offsets[1], alt_va_image.offsets[2]); + SWAP_UINT(alt_va_image.pitches[1], alt_va_image.pitches[2]); + if (vaapi_image_is_linear(&alt_va_image)) { + priv->image = alt_va_image; + priv->format = format; + priv->is_linear = TRUE; + GST_DEBUG("linearized image to %" GST_FOURCC_FORMAT " format", + GST_FOURCC_ARGS(format)); + } + } + } + return TRUE; +} + GstVaapiDisplay * gst_vaapi_image_get_display(GstVaapiImage *image) { diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 322a151c7f..bd9e53b829 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -82,6 +82,9 @@ gst_vaapi_image_new( guint height ); +GstVaapiImage * +gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image); + VAImageID gst_vaapi_image_get_id(GstVaapiImage *image); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 40b5cded66..79ab6e1da8 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -21,6 +21,7 @@ #include "config.h" #include "gstvaapiutils.h" #include "gstvaapisurface.h" +#include "gstvaapiimage.h" #include #define DEBUG 1 @@ -342,6 +343,32 @@ gst_vaapi_surface_get_size( *pheight = gst_vaapi_surface_get_height(surface); } +GstVaapiImage * +gst_vaapi_surface_derive_image(GstVaapiSurface *surface) +{ + VAImage va_image; + VAStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); + + va_image.image_id = VA_INVALID_ID; + va_image.buf = VA_INVALID_ID; + + GST_VAAPI_DISPLAY_LOCK(surface->priv->display); + status = vaDeriveImage( + GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), + surface->priv->surface_id, + &va_image + ); + GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); + if (!vaapi_check_status(status, "vaDeriveImage()")) + return NULL; + if (va_image.image_id == VA_INVALID_ID || va_image.buf == VA_INVALID_ID) + return NULL; + + return gst_vaapi_image_new_with_image(surface->priv->display, &va_image); +} + gboolean gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) { diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 1d6d4f7b34..2fa56aa8c7 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -107,6 +107,9 @@ gst_vaapi_surface_get_size( guint *pheight ); +GstVaapiImage * +gst_vaapi_surface_derive_image(GstVaapiSurface *surface); + gboolean gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image); From 55b45d964d32bc29df3fd0d3997e6017cd1e1e06 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 15:52:20 +0000 Subject: [PATCH 0094/3781] Fix gst_vaapi_image_create() from a foreign VA image. --- gst-libs/gst/vaapi/gstvaapiimage.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index b9ad8dd6cd..ae904ce751 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -174,10 +174,6 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) const VAImageFormat *va_format; VAStatus status; - if (!priv->create_image) - return (priv->image.image_id != VA_INVALID_ID && - priv->image.buf != VA_INVALID_ID); - if (!gst_vaapi_display_has_image_format(priv->display, format)) return FALSE; @@ -209,6 +205,10 @@ gst_vaapi_image_create(GstVaapiImage *image) GstVaapiImageFormat format = priv->format; const VAImageFormat *va_format; + if (!priv->create_image) + return (priv->image.image_id != VA_INVALID_ID && + priv->image.buf != VA_INVALID_ID); + if (!_gst_vaapi_image_create(image, format)) { switch (format) { case GST_VAAPI_IMAGE_I420: From 72cdf859775102431b69cd3deffe0d041e12206a Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 15:53:50 +0000 Subject: [PATCH 0095/3781] Add vaDeriveImage() optimization. --- sys/vaapiconvert/gstvaapiconvert.c | 46 ++++++++++++++++++++++++++---- sys/vaapiconvert/gstvaapiconvert.h | 2 ++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index 5e64ed4445..b184194457 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -195,6 +195,8 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) convert->surface_height = 0; convert->can_use_inout_buffers = FALSE; convert->use_inout_buffers = FALSE; + convert->can_use_derive_image = FALSE; + convert->use_derive_image = FALSE; /* Override buffer allocator on sink pad */ sinkpad = gst_element_get_static_pad(GST_ELEMENT(convert), "sink"); @@ -267,7 +269,8 @@ gst_vaapiconvert_transform( if (!gst_vaapi_image_unmap(image)) return GST_FLOW_UNEXPECTED; - gst_vaapi_surface_put_image(surface, image); + if (!convert->use_derive_image) + gst_vaapi_surface_put_image(surface, image); return GST_FLOW_OK; } @@ -374,6 +377,8 @@ static gboolean gst_vaapiconvert_ensure_surface_pool(GstVaapiConvert *convert, GstCaps *caps) { GstStructure * const structure = gst_caps_get_structure(caps, 0); + GstVaapiSurface *surface; + GstVaapiImage *image; gint width, height; gst_structure_get_int(structure, "width", &width); @@ -387,6 +392,20 @@ gst_vaapiconvert_ensure_surface_pool(GstVaapiConvert *convert, GstCaps *caps) convert->surfaces = gst_vaapi_surface_pool_new(convert->display, caps); if (!convert->surfaces) return FALSE; + + /* Check if we can access to the surface pixels directly */ + surface = gst_vaapi_video_pool_get_object(convert->surfaces); + if (surface) { + image = gst_vaapi_surface_derive_image(surface); + if (image) { + if (gst_vaapi_image_map(image)) { + convert->can_use_derive_image = TRUE; + gst_vaapi_image_unmap(image); + } + g_object_unref(image); + } + gst_vaapi_video_pool_put_object(convert->surfaces, surface); + } } return TRUE; } @@ -408,6 +427,12 @@ gst_vaapiconvert_negotiate_buffers( GST_DEBUG("use-inout-buffers: %spossible, %s", convert->can_use_inout_buffers ? "" : "not ", convert->use_inout_buffers ? "enabled" : "disabled"); + + convert->use_derive_image = + convert->use_inout_buffers && convert->can_use_derive_image; + GST_DEBUG("use-derive-image: %spossible, %s", + convert->can_use_derive_image ? "" : "not ", + convert->use_derive_image ? "enabled" : "disabled"); return TRUE; } @@ -457,7 +482,7 @@ gst_vaapiconvert_buffer_alloc( { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); GstBuffer *buffer = NULL; - GstVaapiImage *image; + GstVaapiImage *image = NULL; /* Check if we can use the inout-buffers optimization */ if (!gst_vaapiconvert_negotiate_buffers(convert, caps, caps)) @@ -470,10 +495,19 @@ gst_vaapiconvert_buffer_alloc( goto error; GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); - if (!gst_vaapi_video_buffer_set_image_from_pool(vbuffer, convert->images)) - goto error; - - image = gst_vaapi_video_buffer_get_image(vbuffer); + if (convert->use_derive_image) { + GstVaapiSurface *surface = gst_vaapi_video_buffer_get_surface(vbuffer); + image = gst_vaapi_surface_derive_image(surface); + if (image) + gst_vaapi_video_buffer_set_image(vbuffer, image); + else /* We can't use the derive-image optimization. Disable it. */ + convert->use_derive_image = FALSE; + } + if (!image) { + if (!gst_vaapi_video_buffer_set_image_from_pool(vbuffer, convert->images)) + goto error; + image = gst_vaapi_video_buffer_get_image(vbuffer); + } g_assert(image); if (!gst_vaapi_image_map(image)) diff --git a/sys/vaapiconvert/gstvaapiconvert.h b/sys/vaapiconvert/gstvaapiconvert.h index c41877b36a..9d9839f2e1 100644 --- a/sys/vaapiconvert/gstvaapiconvert.h +++ b/sys/vaapiconvert/gstvaapiconvert.h @@ -73,6 +73,8 @@ struct _GstVaapiConvert { guint surface_height; guint can_use_inout_buffers : 1; guint use_inout_buffers : 1; + guint can_use_derive_image : 1; + guint use_derive_image : 1; }; struct _GstVaapiConvertClass { From d38a9232f86e2a949cddcd7af768f667b9cd9e70 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 15:58:28 +0000 Subject: [PATCH 0096/3781] Reduce number of debug messaged printed out. --- sys/vaapiconvert/gstvaapiconvert.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index b184194457..7b06dac8fa 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -417,22 +417,27 @@ gst_vaapiconvert_negotiate_buffers( GstCaps *outcaps ) { + gboolean enable; + if (!gst_vaapiconvert_ensure_image_pool(convert, incaps)) return FALSE; if (!gst_vaapiconvert_ensure_surface_pool(convert, outcaps)) return FALSE; - convert->use_inout_buffers = convert->can_use_inout_buffers; - GST_DEBUG("use-inout-buffers: %spossible, %s", - convert->can_use_inout_buffers ? "" : "not ", - convert->use_inout_buffers ? "enabled" : "disabled"); + enable = convert->can_use_inout_buffers; + if (convert->use_inout_buffers != enable) { + convert->use_inout_buffers = enable; + GST_DEBUG("use-inout-buffers: %s", + convert->use_inout_buffers ? "enabled" : "disabled"); + } - convert->use_derive_image = - convert->use_inout_buffers && convert->can_use_derive_image; - GST_DEBUG("use-derive-image: %spossible, %s", - convert->can_use_derive_image ? "" : "not ", - convert->use_derive_image ? "enabled" : "disabled"); + enable = convert->use_inout_buffers && convert->can_use_derive_image; + if (convert->use_derive_image != enable) { + convert->use_derive_image = enable; + GST_DEBUG("use-derive-image: %s", + convert->use_derive_image ? "enabled" : "disabled"); + } return TRUE; } From 6b27844b5b664824ebfc56fb9368621bf27018c8 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 18 Mar 2010 16:18:17 +0000 Subject: [PATCH 0097/3781] Allow user to specify inout-buffers & derive-image optimizations. --- sys/vaapiconvert/gstvaapiconvert.c | 100 ++++++++++++++++++++++++++--- sys/vaapiconvert/gstvaapiconvert.h | 2 + 2 files changed, 92 insertions(+), 10 deletions(-) diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index 7b06dac8fa..5208d497ce 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -69,6 +69,13 @@ GST_BOILERPLATE( GstBaseTransform, GST_TYPE_BASE_TRANSFORM); +enum { + PROP_0, + + PROP_USE_INOUT_BUFFERS, + PROP_USE_DERIVE_IMAGE +}; + static gboolean gst_vaapiconvert_start(GstBaseTransform *trans); static gboolean gst_vaapiconvert_stop(GstBaseTransform *trans); @@ -164,6 +171,53 @@ gst_vaapiconvert_finalize(GObject *object) G_OBJECT_CLASS(parent_class)->finalize(object); } + +static void +gst_vaapiconvert_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiConvert * const convert = GST_VAAPICONVERT(object); + + switch (prop_id) { + case PROP_USE_INOUT_BUFFERS: + convert->allow_use_inout_buffers = g_value_get_boolean(value); + break; + case PROP_USE_DERIVE_IMAGE: + convert->allow_use_derive_image = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapiconvert_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiConvert * const convert = GST_VAAPICONVERT(object); + + switch (prop_id) { + case PROP_USE_INOUT_BUFFERS: + g_value_set_boolean(value, convert->allow_use_inout_buffers); + break; + case PROP_USE_DERIVE_IMAGE: + g_value_set_boolean(value, convert->allow_use_derive_image); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + static void gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) { @@ -171,6 +225,8 @@ gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); object_class->finalize = gst_vaapiconvert_finalize; + object_class->set_property = gst_vaapiconvert_set_property; + object_class->get_property = gst_vaapiconvert_get_property; trans_class->start = gst_vaapiconvert_start; trans_class->stop = gst_vaapiconvert_stop; @@ -179,6 +235,24 @@ gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) trans_class->set_caps = gst_vaapiconvert_set_caps; trans_class->get_unit_size = gst_vaapiconvert_get_unit_size; trans_class->prepare_output_buffer = gst_vaapiconvert_prepare_output_buffer; + + g_object_class_install_property + (object_class, + PROP_USE_INOUT_BUFFERS, + g_param_spec_boolean("use-inout-buffers", + "Use in/out buffers", + "Allow use of in/out buffers whenever possible", + TRUE, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, + PROP_USE_DERIVE_IMAGE, + g_param_spec_boolean("use-derive-image", + "Use vaDeriveImage()", + "Allow use of vaDeriveImage() whenever possible", + TRUE, + G_PARAM_READWRITE)); } static void @@ -193,8 +267,10 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) convert->surfaces = NULL; convert->surface_width = 0; convert->surface_height = 0; + convert->allow_use_inout_buffers = TRUE; convert->can_use_inout_buffers = FALSE; convert->use_inout_buffers = FALSE; + convert->allow_use_derive_image = TRUE; convert->can_use_derive_image = FALSE; convert->use_derive_image = FALSE; @@ -425,18 +501,22 @@ gst_vaapiconvert_negotiate_buffers( if (!gst_vaapiconvert_ensure_surface_pool(convert, outcaps)) return FALSE; - enable = convert->can_use_inout_buffers; - if (convert->use_inout_buffers != enable) { - convert->use_inout_buffers = enable; - GST_DEBUG("use-inout-buffers: %s", - convert->use_inout_buffers ? "enabled" : "disabled"); + if (convert->allow_use_inout_buffers) { + enable = convert->can_use_inout_buffers; + if (convert->use_inout_buffers != enable) { + convert->use_inout_buffers = enable; + GST_DEBUG("use-inout-buffers: %s", + convert->use_inout_buffers ? "enabled" : "disabled"); + } } - enable = convert->use_inout_buffers && convert->can_use_derive_image; - if (convert->use_derive_image != enable) { - convert->use_derive_image = enable; - GST_DEBUG("use-derive-image: %s", - convert->use_derive_image ? "enabled" : "disabled"); + if (convert->allow_use_derive_image) { + enable = convert->use_inout_buffers && convert->can_use_derive_image; + if (convert->use_derive_image != enable) { + convert->use_derive_image = enable; + GST_DEBUG("use-derive-image: %s", + convert->use_derive_image ? "enabled" : "disabled"); + } } return TRUE; } diff --git a/sys/vaapiconvert/gstvaapiconvert.h b/sys/vaapiconvert/gstvaapiconvert.h index 9d9839f2e1..133dd69e65 100644 --- a/sys/vaapiconvert/gstvaapiconvert.h +++ b/sys/vaapiconvert/gstvaapiconvert.h @@ -71,8 +71,10 @@ struct _GstVaapiConvert { GstVaapiVideoPool *surfaces; guint surface_width; guint surface_height; + guint allow_use_inout_buffers : 1; guint can_use_inout_buffers : 1; guint use_inout_buffers : 1; + guint allow_use_derive_image : 1; guint can_use_derive_image : 1; guint use_derive_image : 1; }; From bb66a7ea4a13374dc61b991b349588d7abcf1d58 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 19 Mar 2010 08:42:51 +0000 Subject: [PATCH 0098/3781] Factor out direct-rendering infrastructure. --- NEWS | 5 +- sys/vaapiconvert/gstvaapiconvert.c | 113 ++++++++++++----------------- sys/vaapiconvert/gstvaapiconvert.h | 8 +- 3 files changed, 51 insertions(+), 75 deletions(-) diff --git a/NEWS b/NEWS index 95dc3b24ce..4243881d8d 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,8 @@ -gst-vaapi NEWS -- summary of changes. 2010-03-16 +gst-vaapi NEWS -- summary of changes. 2010-03-DD Copyright (C) 2010 Splitted-Desktop Systems +Version 0.1.1 - DD.Mar.2010 +* Optimize `vaapiconvert' pipeline (direct-rendering) + Version 0.1.0 - 16.Mar.2010 * Initial release diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index 5208d497ce..c61660b3c3 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -69,11 +69,12 @@ GST_BOILERPLATE( GstBaseTransform, GST_TYPE_BASE_TRANSFORM); +#define DIRECT_RENDERING_DEFAULT 2 + enum { PROP_0, - PROP_USE_INOUT_BUFFERS, - PROP_USE_DERIVE_IMAGE + PROP_DIRECT_RENDERING, }; static gboolean gst_vaapiconvert_start(GstBaseTransform *trans); @@ -183,11 +184,8 @@ gst_vaapiconvert_set_property( GstVaapiConvert * const convert = GST_VAAPICONVERT(object); switch (prop_id) { - case PROP_USE_INOUT_BUFFERS: - convert->allow_use_inout_buffers = g_value_get_boolean(value); - break; - case PROP_USE_DERIVE_IMAGE: - convert->allow_use_derive_image = g_value_get_boolean(value); + case PROP_DIRECT_RENDERING: + convert->direct_rendering = g_value_get_uint(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -206,11 +204,8 @@ gst_vaapiconvert_get_property( GstVaapiConvert * const convert = GST_VAAPICONVERT(object); switch (prop_id) { - case PROP_USE_INOUT_BUFFERS: - g_value_set_boolean(value, convert->allow_use_inout_buffers); - break; - case PROP_USE_DERIVE_IMAGE: - g_value_set_boolean(value, convert->allow_use_derive_image); + case PROP_DIRECT_RENDERING: + g_value_set_uint(value, convert->direct_rendering); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -238,21 +233,13 @@ gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) g_object_class_install_property (object_class, - PROP_USE_INOUT_BUFFERS, - g_param_spec_boolean("use-inout-buffers", - "Use in/out buffers", - "Allow use of in/out buffers whenever possible", - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property - (object_class, - PROP_USE_DERIVE_IMAGE, - g_param_spec_boolean("use-derive-image", - "Use vaDeriveImage()", - "Allow use of vaDeriveImage() whenever possible", - TRUE, - G_PARAM_READWRITE)); + PROP_DIRECT_RENDERING, + g_param_spec_uint("direct-rendering", + "Direct rendering", + "Direct rendering level", + 0, 2, + DIRECT_RENDERING_DEFAULT, + G_PARAM_READWRITE)); } static void @@ -267,12 +254,8 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) convert->surfaces = NULL; convert->surface_width = 0; convert->surface_height = 0; - convert->allow_use_inout_buffers = TRUE; - convert->can_use_inout_buffers = FALSE; - convert->use_inout_buffers = FALSE; - convert->allow_use_derive_image = TRUE; - convert->can_use_derive_image = FALSE; - convert->use_derive_image = FALSE; + convert->direct_rendering_caps = 0; + convert->direct_rendering = G_MAXUINT32; /* Override buffer allocator on sink pad */ sinkpad = gst_element_get_static_pad(GST_ELEMENT(convert), "sink"); @@ -329,7 +312,7 @@ gst_vaapiconvert_transform( if (!surface) return GST_FLOW_UNEXPECTED; - if (convert->use_inout_buffers) { + if (convert->direct_rendering) { if (!GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) { GST_DEBUG("GstVaapiVideoBuffer was expected"); return GST_FLOW_UNEXPECTED; @@ -345,7 +328,7 @@ gst_vaapiconvert_transform( if (!gst_vaapi_image_unmap(image)) return GST_FLOW_UNEXPECTED; - if (!convert->use_derive_image) + if (convert->direct_rendering < 2) gst_vaapi_surface_put_image(surface, image); return GST_FLOW_OK; } @@ -438,10 +421,11 @@ gst_vaapiconvert_ensure_image_pool(GstVaapiConvert *convert, GstCaps *caps) if (gst_video_format_parse_caps(caps, &vformat, NULL, NULL)) { image = gst_vaapi_video_pool_get_object(convert->images); if (image) { - convert->can_use_inout_buffers = + if (convert->direct_rendering_caps == 0 && (gst_vaapi_image_is_linear(image) && (gst_vaapi_image_get_data_size(image) == - gst_video_format_get_size(vformat, width, height))); + gst_video_format_get_size(vformat, width, height)))) + convert->direct_rendering_caps = 1; gst_vaapi_video_pool_put_object(convert->images, image); } } @@ -475,7 +459,8 @@ gst_vaapiconvert_ensure_surface_pool(GstVaapiConvert *convert, GstCaps *caps) image = gst_vaapi_surface_derive_image(surface); if (image) { if (gst_vaapi_image_map(image)) { - convert->can_use_derive_image = TRUE; + if (convert->direct_rendering_caps == 1) + convert->direct_rendering_caps = 2; gst_vaapi_image_unmap(image); } g_object_unref(image); @@ -493,7 +478,7 @@ gst_vaapiconvert_negotiate_buffers( GstCaps *outcaps ) { - gboolean enable; + guint dr; if (!gst_vaapiconvert_ensure_image_pool(convert, incaps)) return FALSE; @@ -501,22 +486,10 @@ gst_vaapiconvert_negotiate_buffers( if (!gst_vaapiconvert_ensure_surface_pool(convert, outcaps)) return FALSE; - if (convert->allow_use_inout_buffers) { - enable = convert->can_use_inout_buffers; - if (convert->use_inout_buffers != enable) { - convert->use_inout_buffers = enable; - GST_DEBUG("use-inout-buffers: %s", - convert->use_inout_buffers ? "enabled" : "disabled"); - } - } - - if (convert->allow_use_derive_image) { - enable = convert->use_inout_buffers && convert->can_use_derive_image; - if (convert->use_derive_image != enable) { - convert->use_derive_image = enable; - GST_DEBUG("use-derive-image: %s", - convert->use_derive_image ? "enabled" : "disabled"); - } + dr = MIN(convert->direct_rendering, convert->direct_rendering_caps); + if (convert->direct_rendering != dr) { + convert->direct_rendering = dr; + GST_DEBUG("direct-rendering level: %d", dr); } return TRUE; } @@ -569,10 +542,10 @@ gst_vaapiconvert_buffer_alloc( GstBuffer *buffer = NULL; GstVaapiImage *image = NULL; - /* Check if we can use the inout-buffers optimization */ + /* Check if we can use direct-rendering */ if (!gst_vaapiconvert_negotiate_buffers(convert, caps, caps)) goto error; - if (!convert->use_inout_buffers) + if (!convert->direct_rendering) return GST_FLOW_OK; buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); @@ -580,18 +553,22 @@ gst_vaapiconvert_buffer_alloc( goto error; GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); - if (convert->use_derive_image) { - GstVaapiSurface *surface = gst_vaapi_video_buffer_get_surface(vbuffer); - image = gst_vaapi_surface_derive_image(surface); - if (image) + GstVaapiSurface *surface; + switch (convert->direct_rendering) { + case 2: + surface = gst_vaapi_video_buffer_get_surface(vbuffer); + image = gst_vaapi_surface_derive_image(surface); + if (image) { gst_vaapi_video_buffer_set_image(vbuffer, image); - else /* We can't use the derive-image optimization. Disable it. */ - convert->use_derive_image = FALSE; - } - if (!image) { + break; + } + /* We can't use the derive-image optimization. Disable it. */ + convert->direct_rendering = 1; + case 1: if (!gst_vaapi_video_buffer_set_image_from_pool(vbuffer, convert->images)) goto error; image = gst_vaapi_video_buffer_get_image(vbuffer); + break; } g_assert(image); @@ -609,7 +586,7 @@ error: /* We can't use the inout-buffers optimization. Disable it. */ if (buffer) gst_buffer_unref(buffer); - convert->use_inout_buffers = FALSE; + convert->direct_rendering = 0; return GST_FLOW_OK; } @@ -649,9 +626,9 @@ gst_vaapiconvert_prepare_output_buffer( if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) buffer = gst_buffer_ref(inbuf); else { - if (convert->use_inout_buffers) { + if (convert->direct_rendering) { GST_DEBUG("upstream element destroyed our inout buffer"); - convert->use_inout_buffers = FALSE; + convert->direct_rendering = 0; } buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); if (!buffer) diff --git a/sys/vaapiconvert/gstvaapiconvert.h b/sys/vaapiconvert/gstvaapiconvert.h index 133dd69e65..d5a6bbc62c 100644 --- a/sys/vaapiconvert/gstvaapiconvert.h +++ b/sys/vaapiconvert/gstvaapiconvert.h @@ -71,12 +71,8 @@ struct _GstVaapiConvert { GstVaapiVideoPool *surfaces; guint surface_width; guint surface_height; - guint allow_use_inout_buffers : 1; - guint can_use_inout_buffers : 1; - guint use_inout_buffers : 1; - guint allow_use_derive_image : 1; - guint can_use_derive_image : 1; - guint use_derive_image : 1; + guint direct_rendering_caps; + guint direct_rendering; }; struct _GstVaapiConvertClass { From a318326f7f1b5652d7244b34d900995877dd3e57 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 19 Mar 2010 10:38:45 +0000 Subject: [PATCH 0099/3781] Simplify GstVaapiDisplay (use GArray). --- gst-libs/gst/vaapi/gstvaapidisplay.c | 380 ++++++++++++--------------- 1 file changed, 162 insertions(+), 218 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 78dec96ddd..fb66376987 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -39,13 +39,9 @@ struct _GstVaapiDisplayPrivate { GStaticMutex mutex; VADisplay display; gboolean create_display; - VAProfile *profiles; - guint num_profiles; - VAImageFormat *image_formats; - guint num_image_formats; - VAImageFormat *subpicture_formats; - guint *subpicture_flags; - guint num_subpicture_formats; + GArray *profiles; + GArray *image_formats; + GArray *subpicture_formats; }; enum { @@ -55,80 +51,54 @@ enum { }; static void -append_format( - VAImageFormat **pva_formats, - guint *pnum_va_formats, - GstVaapiImageFormat format -) +append_formats(GArray *array, const VAImageFormat *va_formats, guint n) { - const VAImageFormat *va_format; - VAImageFormat *new_va_formats; - - va_format = gst_vaapi_image_format_get_va_format(format); - if (!va_format) - return; - - new_va_formats = realloc( - *pva_formats, - sizeof(new_va_formats[0]) * (1 + *pnum_va_formats) - ); - if (!new_va_formats) - return; - - new_va_formats[(*pnum_va_formats)++] = *va_format; - *pva_formats = new_va_formats; -} - -static void -filter_formats(VAImageFormat **pva_formats, guint *pnum_va_formats) -{ - guint i = 0; + GstVaapiImageFormat format; gboolean has_YV12 = FALSE; gboolean has_I420 = FALSE; + guint i; - while (i < *pnum_va_formats) { - VAImageFormat * const va_format = &(*pva_formats)[i]; - const GstVaapiImageFormat format = gst_vaapi_image_format(va_format); - if (format) { - ++i; - switch (format) { - case GST_VAAPI_IMAGE_YV12: - has_YV12 = TRUE; - break; - case GST_VAAPI_IMAGE_I420: - has_I420 = TRUE; - break; - default: - break; - } + for (i = 0; i < n; i++) { + const VAImageFormat * const va_format = &va_formats[i]; + + format = gst_vaapi_image_format(va_format); + if (!format) { + GST_DEBUG("unsupported format %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS(va_format->fourcc)); + continue; } - else { - /* Remove any format that is not supported by libgstvaapi */ - GST_DEBUG("unsupported format %c%c%c%c", - va_format->fourcc & 0xff, - (va_format->fourcc >> 8) & 0xff, - (va_format->fourcc >> 16) & 0xff, - (va_format->fourcc >> 24) & 0xff); - *va_format = (*pva_formats)[--(*pnum_va_formats)]; + + switch (format) { + case GST_VAAPI_IMAGE_YV12: + has_YV12 = TRUE; + break; + case GST_VAAPI_IMAGE_I420: + has_I420 = TRUE; + break; + default: + break; } + g_array_append_val(array, format); } /* Append I420 (resp. YV12) format if YV12 (resp. I420) is not supported by the underlying driver */ - if (has_YV12 && !has_I420) - append_format(pva_formats, pnum_va_formats, GST_VAAPI_IMAGE_I420); - else if (has_I420 && !has_YV12) - append_format(pva_formats, pnum_va_formats, GST_VAAPI_IMAGE_YV12); + if (has_YV12 && !has_I420) { + format = GST_VAAPI_IMAGE_I420; + g_array_append_val(array, format); + } + else if (has_I420 && !has_YV12) { + format = GST_VAAPI_IMAGE_YV12; + g_array_append_val(array, format); + } } /* Sort image formats. Prefer YUV formats first */ -static int -compare_yuv_formats(const void *a, const void *b) +static gint +compare_yuv_formats(gconstpointer a, gconstpointer b) { - const GstVaapiImageFormat fmt1 = gst_vaapi_image_format((VAImageFormat *)a); - const GstVaapiImageFormat fmt2 = gst_vaapi_image_format((VAImageFormat *)b); - - g_assert(fmt1 && fmt2); + const GstVaapiImageFormat fmt1 = *(GstVaapiImageFormat *)a; + const GstVaapiImageFormat fmt2 = *(GstVaapiImageFormat *)b; const gboolean is_fmt1_yuv = gst_vaapi_image_format_is_yuv(fmt1); const gboolean is_fmt2_yuv = gst_vaapi_image_format_is_yuv(fmt2); @@ -136,18 +106,16 @@ compare_yuv_formats(const void *a, const void *b) if (is_fmt1_yuv != is_fmt2_yuv) return is_fmt1_yuv ? -1 : 1; - return ((int)gst_vaapi_image_format_get_score(fmt1) - - (int)gst_vaapi_image_format_get_score(fmt2)); + return ((gint)gst_vaapi_image_format_get_score(fmt1) - + (gint)gst_vaapi_image_format_get_score(fmt2)); } /* Sort subpicture formats. Prefer RGB formats first */ -static int -compare_rgb_formats(const void *a, const void *b) +static gint +compare_rgb_formats(gconstpointer a, gconstpointer b) { - const GstVaapiImageFormat fmt1 = gst_vaapi_image_format((VAImageFormat *)a); - const GstVaapiImageFormat fmt2 = gst_vaapi_image_format((VAImageFormat *)b); - - g_assert(fmt1 && fmt2); + const GstVaapiImageFormat fmt1 = *(GstVaapiImageFormat *)a; + const GstVaapiImageFormat fmt2 = *(GstVaapiImageFormat *)b; const gboolean is_fmt1_rgb = gst_vaapi_image_format_is_rgb(fmt1); const gboolean is_fmt2_rgb = gst_vaapi_image_format_is_rgb(fmt2); @@ -155,8 +123,53 @@ compare_rgb_formats(const void *a, const void *b) if (is_fmt1_rgb != is_fmt2_rgb) return is_fmt1_rgb ? -1 : 1; - return ((int)gst_vaapi_image_format_get_score(fmt1) - - (int)gst_vaapi_image_format_get_score(fmt2)); + return ((gint)gst_vaapi_image_format_get_score(fmt1) - + (gint)gst_vaapi_image_format_get_score(fmt2)); +} + +/* Check if profiles array contains profile */ +static inline gboolean +find_profile(GArray *profiles, VAProfile profile) +{ + guint i; + + for (i = 0; i < profiles->len; i++) + if (g_array_index(profiles, VAProfile, i) == profile) + return TRUE; + return FALSE; +} + +/* Check if formats array contains format */ +static inline gboolean +find_format(GArray *formats, GstVaapiImageFormat format) +{ + guint i; + + for (i = 0; i < formats->len; i++) + if (g_array_index(formats, GstVaapiImageFormat, i) == format) + return TRUE; + return FALSE; +} + +/* Convert formats array to GstCaps */ +static GstCaps * +get_caps(GArray *formats) +{ + GstVaapiImageFormat format; + GstCaps *out_caps, *caps; + guint i; + + out_caps = gst_caps_new_empty(); + if (!out_caps) + return NULL; + + for (i = 0; i < formats->len; i++) { + format = g_array_index(formats, GstVaapiImageFormat, i); + caps = gst_vaapi_image_format_get_caps(format); + if (caps) + gst_caps_append(out_caps, caps); + } + return out_caps; } static void @@ -165,25 +178,18 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) GstVaapiDisplayPrivate * const priv = display->priv; if (priv->profiles) { - g_free(priv->profiles); + g_array_free(priv->profiles, TRUE); priv->profiles = NULL; } if (priv->image_formats) { - g_free(priv->image_formats); + g_array_free(priv->image_formats, TRUE); priv->image_formats = NULL; - priv->num_image_formats = 0; } if (priv->subpicture_formats) { - g_free(priv->subpicture_formats); + g_array_free(priv->subpicture_formats, TRUE); priv->subpicture_formats = NULL; - priv->num_subpicture_formats = 0; - } - - if (priv->subpicture_flags) { - g_free(priv->subpicture_flags); - priv->subpicture_flags = NULL; } if (priv->display) { @@ -202,9 +208,12 @@ static gboolean gst_vaapi_display_create(GstVaapiDisplay *display) { GstVaapiDisplayPrivate * const priv = display->priv; - VAStatus status; - int major_version, minor_version; - guint i; + gboolean has_errors = TRUE; + VAProfile *profiles = NULL; + VAImageFormat *formats = NULL; + unsigned int *flags = NULL; + gint i, n, major_version, minor_version; + VAStatus status; if (!priv->display && priv->create_display) { GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); @@ -218,79 +227,72 @@ gst_vaapi_display_create(GstVaapiDisplay *display) status = vaInitialize(priv->display, &major_version, &minor_version); if (!vaapi_check_status(status, "vaInitialize()")) - return FALSE; + goto end; GST_DEBUG("VA-API version %d.%d", major_version, minor_version); /* VA profiles */ - priv->num_profiles = vaMaxNumProfiles(priv->display); - priv->profiles = g_new(VAProfile, priv->num_profiles); - if (!priv->profiles) - return FALSE; - status = vaQueryConfigProfiles(priv->display, - priv->profiles, - &priv->num_profiles); + profiles = g_new(VAProfile, vaMaxNumProfiles(priv->display)); + if (!profiles) + goto end; + status = vaQueryConfigProfiles(priv->display, profiles, &n); if (!vaapi_check_status(status, "vaQueryConfigProfiles()")) - return FALSE; + goto end; - GST_DEBUG("%d profiles", priv->num_profiles); - for (i = 0; i < priv->num_profiles; i++) - GST_DEBUG(" %s", string_of_VAProfile(priv->profiles[i])); + GST_DEBUG("%d profiles", n); + for (i = 0; i < n; i++) + GST_DEBUG(" %s", string_of_VAProfile(profiles[i])); + + priv->profiles = g_array_new(FALSE, FALSE, sizeof(VAProfile)); + if (!priv->profiles) + goto end; + g_array_append_vals(priv->profiles, profiles, n); /* VA image formats */ - priv->num_image_formats = vaMaxNumImageFormats(priv->display); - priv->image_formats = g_new(VAImageFormat, priv->num_image_formats); - if (!priv->image_formats) - return FALSE; - status = vaQueryImageFormats( - priv->display, - priv->image_formats, - &priv->num_image_formats - ); + formats = g_new(VAImageFormat, vaMaxNumImageFormats(priv->display)); + if (!formats) + goto end; + status = vaQueryImageFormats(priv->display, formats, &n); if (!vaapi_check_status(status, "vaQueryImageFormats()")) - return FALSE; + goto end; - GST_DEBUG("%d image formats", priv->num_image_formats); - for (i = 0; i < priv->num_image_formats; i++) - GST_DEBUG(" %s", string_of_FOURCC(priv->image_formats[i].fourcc)); + GST_DEBUG("%d image formats", n); + for (i = 0; i < n; i++) + GST_DEBUG(" %s", string_of_FOURCC(formats[i].fourcc)); - filter_formats(&priv->image_formats, &priv->num_image_formats); - qsort( - priv->image_formats, - priv->num_image_formats, - sizeof(priv->image_formats[0]), - compare_yuv_formats - ); + priv->image_formats = + g_array_new(FALSE, FALSE, sizeof(GstVaapiImageFormat)); + if (!priv->image_formats) + goto end; + append_formats(priv->image_formats, formats, n); + g_array_sort(priv->image_formats, compare_yuv_formats); /* VA subpicture formats */ - priv->num_subpicture_formats = vaMaxNumSubpictureFormats(priv->display); - priv->subpicture_formats = g_new(VAImageFormat, priv->num_subpicture_formats); - if (!priv->subpicture_formats) - return FALSE; - priv->subpicture_flags = g_new(guint, priv->num_subpicture_formats); - if (!priv->subpicture_flags) - return FALSE; - status = vaQuerySubpictureFormats( - priv->display, - priv->subpicture_formats, - priv->subpicture_flags, - &priv->num_subpicture_formats - ); + n = vaMaxNumSubpictureFormats(priv->display); + formats = g_renew(VAImageFormat, formats, n); + flags = g_new(guint, n); + if (!formats || !flags) + goto end; + status = vaQuerySubpictureFormats(priv->display, formats, flags, &n); if (!vaapi_check_status(status, "vaQuerySubpictureFormats()")) - return FALSE; + goto end; - filter_formats(&priv->subpicture_formats, &priv->num_subpicture_formats); - qsort( - priv->subpicture_formats, - priv->num_subpicture_formats, - sizeof(priv->subpicture_formats[0]), - compare_rgb_formats - ); + GST_DEBUG("%d subpicture formats", n); + for (i = 0; i < n; i++) + GST_DEBUG(" %s", string_of_FOURCC(formats[i].fourcc)); - GST_DEBUG("%d subpicture formats", priv->num_subpicture_formats); - for (i = 0; i < priv->num_subpicture_formats; i++) - GST_DEBUG(" %s", string_of_FOURCC(priv->subpicture_formats[i].fourcc)); + priv->subpicture_formats = + g_array_new(FALSE, FALSE, sizeof(GstVaapiImageFormat)); + if (!priv->subpicture_formats) + goto end; + append_formats(priv->subpicture_formats, formats, n); + g_array_sort(priv->subpicture_formats, compare_rgb_formats); - return TRUE; + has_errors = FALSE; +end: + g_free(profiles); + g_free(formats); + g_free(flags); + return !has_errors; } static void @@ -401,16 +403,12 @@ gst_vaapi_display_init(GstVaapiDisplay *display) { GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); - display->priv = priv; - priv->display = NULL; - priv->create_display = TRUE; - priv->profiles = 0; - priv->num_profiles = 0; - priv->image_formats = NULL; - priv->num_image_formats = 0; - priv->subpicture_formats = NULL; - priv->subpicture_flags = NULL; - priv->num_subpicture_formats = 0; + display->priv = priv; + priv->display = NULL; + priv->create_display = TRUE; + priv->profiles = NULL; + priv->image_formats = NULL; + priv->subpicture_formats = NULL; g_static_mutex_init(&priv->mutex); } @@ -458,57 +456,9 @@ gst_vaapi_display_get_display(GstVaapiDisplay *display) gboolean gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile) { - guint i; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); - for (i = 0; i < display->priv->num_profiles; i++) - if (display->priv->profiles[i] == profile) - return TRUE; - return FALSE; -} - -static gboolean -_gst_vaapi_display_has_format( - GstVaapiDisplay *display, - GstVaapiImageFormat format, - const VAImageFormat *va_formats, - guint num_va_formats -) -{ - guint i; - - g_return_val_if_fail(format != 0, FALSE); - - for (i = 0; i < num_va_formats; i++) - if (gst_vaapi_image_format(&va_formats[i]) == format) - return TRUE; - return FALSE; -} - -static GstCaps * -_gst_vaapi_display_get_caps( - GstVaapiDisplay *display, - const VAImageFormat *va_formats, - guint num_va_formats -) -{ - GstCaps *out_caps; - guint i; - - out_caps = gst_caps_new_empty(); - if (!out_caps) - return NULL; - - for (i = 0; i < num_va_formats; i++) { - GstVaapiImageFormat format = gst_vaapi_image_format(&va_formats[i]); - if (format) { - GstCaps * const caps = gst_vaapi_image_format_get_caps(format); - if (caps) - gst_caps_append(out_caps, caps); - } - } - return out_caps; + return find_profile(display->priv->profiles, profile); } GstCaps * @@ -516,9 +466,7 @@ gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return _gst_vaapi_display_get_caps(display, - display->priv->image_formats, - display->priv->num_image_formats); + return get_caps(display->priv->image_formats); } gboolean @@ -528,10 +476,9 @@ gst_vaapi_display_has_image_format( ) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(format, FALSE); - return _gst_vaapi_display_has_format(display, format, - display->priv->image_formats, - display->priv->num_image_formats); + return find_format(display->priv->image_formats, format); } GstCaps * @@ -539,9 +486,7 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return _gst_vaapi_display_get_caps(display, - display->priv->subpicture_formats, - display->priv->num_subpicture_formats); + return get_caps(display->priv->subpicture_formats); } gboolean @@ -551,8 +496,7 @@ gst_vaapi_display_has_subpicture_format( ) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(format, FALSE); - return _gst_vaapi_display_has_format(display, format, - display->priv->subpicture_formats, - display->priv->num_subpicture_formats); + return find_format(display->priv->subpicture_formats, format); } From 9a1741a1936c1a55553cee8716bf4c23d22c5cd8 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 19 Mar 2010 10:42:11 +0000 Subject: [PATCH 0100/3781] Beautify append_formats(). --- gst-libs/gst/vaapi/gstvaapidisplay.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index fb66376987..56f5b39023 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -50,8 +50,16 @@ enum { PROP_DISPLAY }; +/* Append GstVaapiImageFormat to formats array */ +static inline void +append_format(GArray *formats, GstVaapiImageFormat format) +{ + g_array_append_val(formats, format); +} + +/* Append VAImageFormats to formats array */ static void -append_formats(GArray *array, const VAImageFormat *va_formats, guint n) +append_formats(GArray *formats, const VAImageFormat *va_formats, guint n) { GstVaapiImageFormat format; gboolean has_YV12 = FALSE; @@ -78,19 +86,15 @@ append_formats(GArray *array, const VAImageFormat *va_formats, guint n) default: break; } - g_array_append_val(array, format); + append_format(formats, format); } /* Append I420 (resp. YV12) format if YV12 (resp. I420) is not supported by the underlying driver */ - if (has_YV12 && !has_I420) { - format = GST_VAAPI_IMAGE_I420; - g_array_append_val(array, format); - } - else if (has_I420 && !has_YV12) { - format = GST_VAAPI_IMAGE_YV12; - g_array_append_val(array, format); - } + if (has_YV12 && !has_I420) + append_format(formats, GST_VAAPI_IMAGE_I420); + else if (has_I420 && !has_YV12) + append_format(formats, GST_VAAPI_IMAGE_YV12); } /* Sort image formats. Prefer YUV formats first */ From d63f196c731fc095d86066ee1c87b8dd3d3d3860 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 19 Mar 2010 15:45:21 +0000 Subject: [PATCH 0101/3781] Add tedious documentation. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 94 ++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 34 ++++ gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 47 +++++ gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 18 ++ gst-libs/gst/vaapi/gstvaapiimage.c | 218 ++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiimage.h | 37 +++- gst-libs/gst/vaapi/gstvaapiimageformat.c | 85 ++++++++- gst-libs/gst/vaapi/gstvaapiimageformat.h | 26 ++- gst-libs/gst/vaapi/gstvaapisubpicture.c | 54 +++++- gst-libs/gst/vaapi/gstvaapisubpicture.h | 11 ++ gst-libs/gst/vaapi/gstvaapisurface.c | 146 ++++++++++++++- gst-libs/gst/vaapi/gstvaapisurface.h | 19 ++ gst-libs/gst/vaapi/gstvaapivideosink.c | 25 +++ gst-libs/gst/vaapi/gstvaapivideosink.h | 7 + gst-libs/gst/vaapi/gstvaapiwindow.c | 98 +++++++++- gst-libs/gst/vaapi/gstvaapiwindow.h | 17 ++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 53 +++++- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 11 ++ 18 files changed, 962 insertions(+), 38 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 56f5b39023..a6c0f76635 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-display + * @short_description: + */ + #include "config.h" #include "gstvaapiutils.h" #include "gstvaapidisplay.h" @@ -417,6 +422,15 @@ gst_vaapi_display_init(GstVaapiDisplay *display) g_static_mutex_init(&priv->mutex); } +/** + * gst_vaapi_display_new_with_display: + * @va_display: a #VADisplay + * + * Creates a new #GstVaapiDisplay, using @va_display as the VA + * display. + * + * Return value: the newly created #GstVaapiDisplay object + */ GstVaapiDisplay * gst_vaapi_display_new_with_display(VADisplay va_display) { @@ -425,6 +439,14 @@ gst_vaapi_display_new_with_display(VADisplay va_display) NULL); } +/** + * gst_vaapi_display_lock: + * @display: a #GstVaapiDisplay + * + * Locks @display. If @display is already locked by another thread, + * the current thread will block until @display is unlocked by the + * other thread. + */ void gst_vaapi_display_lock(GstVaapiDisplay *display) { @@ -437,6 +459,14 @@ gst_vaapi_display_lock(GstVaapiDisplay *display) klass->lock_display(display); } +/** + * gst_vaapi_display_unlock: + * @display: a #GstVaapiDisplay + * + * Unlocks @display. If another thread is blocked in a + * gst_vaapi_display_lock() call for @display, it will be woken and + * can lock @display itself. + */ void gst_vaapi_display_unlock(GstVaapiDisplay *display) { @@ -449,6 +479,14 @@ gst_vaapi_display_unlock(GstVaapiDisplay *display) klass->unlock_display(display); } +/** + * gst_vaapi_display_get_display: + * @display: a #GstVaapiDisplay + * + * Returns the #VADisplay bound to @display. + * + * Return value: the #VADisplay + */ VADisplay gst_vaapi_display_get_display(GstVaapiDisplay *display) { @@ -457,6 +495,15 @@ gst_vaapi_display_get_display(GstVaapiDisplay *display) return display->priv->display; } +/** + * gst_vaapi_display_has_profile: + * @display: a #GstVaapiDisplay + * @profile: a #VAProfile + * + * Returns whether VA @display supports @profile. + * + * Return value: %TRUE if VA @display supports @profile + */ gboolean gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile) { @@ -465,6 +512,22 @@ gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile) return find_profile(display->priv->profiles, profile); } +/** + * gst_vaapi_display_get_image_caps: + * @display: a #GstVaapiDisplay + * + * Gets the supported image formats for gst_vaapi_surface_get_image() + * or gst_vaapi_surface_put_image() as #GstCaps capabilities. + * + * Note that this method does not necessarily map image formats + * returned by vaQueryImageFormats(). The set of capabilities can be + * stripped down, if gstreamer-vaapi does not support the format, or + * expanded to cover compatible formats not exposed by the underlying + * driver. e.g. I420 can be supported even if the driver only exposes + * YV12. + * + * Return value: a newly allocated #GstCaps object, possibly empty + */ GstCaps * gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) { @@ -473,6 +536,15 @@ gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) return get_caps(display->priv->image_formats); } +/** + * gst_vaapi_display_has_image_format: + * @display: a #GstVaapiDisplay + * @format: a #GstVaapiFormat + * + * Returns whether VA @display supports @format image format. + * + * Return value: %TRUE if VA @display supports @format image format + */ gboolean gst_vaapi_display_has_image_format( GstVaapiDisplay *display, @@ -485,6 +557,19 @@ gst_vaapi_display_has_image_format( return find_format(display->priv->image_formats, format); } +/** + * gst_vaapi_display_get_subpicture_caps: + * @display: a #GstVaapiDisplay + * + * Gets the supported subpicture formats as #GstCaps capabilities. + * + * Note that this method does not necessarily map subpicture formats + * returned by vaQuerySubpictureFormats(). The set of capabilities can + * be stripped down if gstreamer-vaapi does not support the + * format. e.g. this is the case for paletted formats like IA44. + * + * Return value: a newly allocated #GstCaps object, possibly empty + */ GstCaps * gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) { @@ -493,6 +578,15 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) return get_caps(display->priv->subpicture_formats); } +/** + * gst_vaapi_display_has_subpicture_format: + * @display: a #GstVaapiDisplay + * @format: a #GstVaapiFormat + * + * Returns whether VA @display supports @format subpicture format. + * + * Return value: %TRUE if VA @display supports @format subpicture format + */ gboolean gst_vaapi_display_has_subpicture_format( GstVaapiDisplay *display, diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index de142c91b8..5744a74584 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -51,12 +51,30 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DISPLAY, \ GstVaapiDisplayClass)) +/** + * GST_VAAPI_DISPLAY_VADISPLAY: + * @display: a #GstVaapiDisplay + * + * Macro that evaluates to the #VADisplay bound to @display + */ #define GST_VAAPI_DISPLAY_VADISPLAY(display) \ gst_vaapi_display_get_display(display) +/** + * GST_VAAPI_DISPLAY_LOCK: + * @display: a #GstVaapiDisplay + * + * Locks @display + */ #define GST_VAAPI_DISPLAY_LOCK(display) \ gst_vaapi_display_lock(display) +/** + * GST_VAAPI_DISPLAY_UNLOCK: + * @display: a #GstVaapiDisplay + * + * Unlocks @display + */ #define GST_VAAPI_DISPLAY_UNLOCK(display) \ gst_vaapi_display_unlock(display) @@ -64,13 +82,29 @@ typedef struct _GstVaapiDisplay GstVaapiDisplay; typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; +/** + * GstVaapiDisplay: + * + * Base class for VA displays. + */ struct _GstVaapiDisplay { /*< private >*/ GObject parent_instance; + /*< private >*/ GstVaapiDisplayPrivate *priv; }; +/** + * GstVaapiDisplayClass: + * @open_display: virtual function to open a display + * @close_display: virtual function to close a display + * @lock_display: virtual function to lock a display + * @unlock_display: virtual function to unlock a display + * @get_display: virtual function to retrieve the #VADisplay + * + * Base class for VA displays. + */ struct _GstVaapiDisplayClass { /*< private >*/ GObjectClass parent_class; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index bb7badbec2..bfd65897be 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-display-x11 + * @short_description: + */ + #include "config.h" #include "gstvaapiutils.h" #include "gstvaapidisplay_x11.h" @@ -189,6 +194,12 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) dpy_class->close_display = gst_vaapi_display_x11_close_display; dpy_class->get_display = gst_vaapi_display_x11_get_va_display; + /** + * GstVaapiDisplayX11:x11-display: + * + * The X11 #Display that was created by gst_vaapi_display_x11_new() + * or that was bound from gst_vaapi_display_x11_new_with_display(). + */ g_object_class_install_property (object_class, PROP_X11_DISPLAY, @@ -197,6 +208,11 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) "X11 display", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + /** + * GstVaapiDisplayX11:display-name: + * + * The X11 display name. + */ g_object_class_install_property (object_class, PROP_DISPLAY_NAME, @@ -218,6 +234,16 @@ gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) priv->display_name = NULL; } +/** + * 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) { @@ -226,6 +252,17 @@ gst_vaapi_display_x11_new(const gchar *display_name) NULL); } +/** + * 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) { @@ -234,6 +271,16 @@ gst_vaapi_display_x11_new_with_display(Display *x11_display) NULL); } +/** + * 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) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 3956315967..6718d9720e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -50,6 +50,12 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DISPLAY_X11, \ GstVaapiDisplayX11Class)) +/** + * GST_VAAPI_DISPLAY_XDISPLAY: + * @display: a #GstVaapiDisplay + * + * Macro that evaluates to the underlying X11 #Display of @display + */ #define GST_VAAPI_DISPLAY_XDISPLAY(display) \ gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)) @@ -57,13 +63,25 @@ typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11; typedef struct _GstVaapiDisplayX11Private GstVaapiDisplayX11Private; typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class; +/** + * GstVaapiDisplayX11: + * + * VA/X11 display wrapper. + */ struct _GstVaapiDisplayX11 { /*< private >*/ GstVaapiDisplay parent_instance; + /*< private >*/ GstVaapiDisplayX11Private *priv; }; + +/** + * GstVaapiDisplayX11Class: + * + * VA/X11 display wrapper clas. + */ struct _GstVaapiDisplayX11Class { /*< private >*/ GstVaapiDisplayClass parent_class; diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index ae904ce751..df2b676d51 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-image + * @short_description: + */ + #include "config.h" #include #include "gstvaapiutils.h" @@ -351,12 +356,17 @@ gst_vaapi_image_class_init(GstVaapiImageClass *klass) object_class->get_property = gst_vaapi_image_get_property; object_class->constructed = gst_vaapi_image_constructed; + /** + * GstVaapiImage:display: + * + * The #GstVaapiDisplay this image is bound to. + */ g_object_class_install_property (object_class, PROP_DISPLAY, g_param_spec_object("display", - "display", - "GStreamer Va display", + "Display", + "The GstVaapiDisplay this image is bound to", GST_VAAPI_TYPE_DISPLAY, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); @@ -365,16 +375,21 @@ gst_vaapi_image_class_init(GstVaapiImageClass *klass) PROP_IMAGE, g_param_spec_boxed("image", "Image", - "The VA image", + "The underlying VA image", VAAPI_TYPE_IMAGE, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + /** + * GstVaapiImage:id: + * + * The underlying #VAImageID of the image. + */ g_object_class_install_property (object_class, PROP_IMAGE_ID, g_param_spec_uint("id", "VA image id", - "VA image id", + "The underlying VA image id", 0, G_MAXUINT32, VA_INVALID_ID, G_PARAM_READABLE)); @@ -383,7 +398,7 @@ gst_vaapi_image_class_init(GstVaapiImageClass *klass) PROP_WIDTH, g_param_spec_uint("width", "width", - "Image width", + "The image width", 0, G_MAXUINT32, 0, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); @@ -391,17 +406,22 @@ gst_vaapi_image_class_init(GstVaapiImageClass *klass) (object_class, PROP_HEIGHT, g_param_spec_uint("height", - "height", - "Image height", + "heighr", + "The image height", 0, G_MAXUINT32, 0, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + /** + * GstVaapiImage:format: + * + * The #GstVaapiImageFormat of the image + */ g_object_class_install_property (object_class, PROP_FORMAT, g_param_spec_uint("format", - "format", - "Image format", + "Format", + "The underlying image format", 0, G_MAXUINT32, 0, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } @@ -431,6 +451,18 @@ gst_vaapi_image_init(GstVaapiImage *image) priv->image.buf = VA_INVALID_ID; } +/** + * gst_vaapi_image_new: + * @display: a #GstVaapiDisplay + * @format: a #GstVaapiImageFormat + * @width: the requested image width + * @height: the requested image height + * + * Creates a new #GstVaapiImage with the specified format and + * dimensions. + * + * Return value: the newly allocated #GstVaapiImage object + */ GstVaapiImage * gst_vaapi_image_new( GstVaapiDisplay *display, @@ -466,6 +498,18 @@ gst_vaapi_image_new( return image; } +/** + * gst_vaapi_image_new_with_image: + * @display: a #GstVaapiDisplay + * @va_image: a VA image + * + * Creates a new #GstVaapiImage from a foreign VA image. The image + * format and dimensions will be extracted from @va_image. This + * function is mainly used by gst_vaapi_surface_derive_image() to bind + * a VA image to a #GstVaapiImage object. + * + * Return value: the newly allocated #GstVaapiImage object + */ GstVaapiImage * gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image) { @@ -497,6 +541,14 @@ gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image) return image; } +/** + * gst_vaapi_image_get_id: + * @image: a #GstVaapiImage + * + * Returns the underlying VAImageID of the @image. + * + * Return value: the underlying VA image id + */ VAImageID gst_vaapi_image_get_id(GstVaapiImage *image) { @@ -506,6 +558,15 @@ gst_vaapi_image_get_id(GstVaapiImage *image) return image->priv->image.image_id; } +/** + * gst_vaapi_image_get_image: + * @image: a #GstVaapiImage + * @va_image: (output): a VA image + * + * Fills @va_image with the VA image used internally. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image) { @@ -518,6 +579,20 @@ gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image) return TRUE; } +/* + * _gst_vaapi_image_set_image: + * @image: a #GstVaapiImage + * @va_image: a VA image + * + * Initializes #GstVaapiImage with a foreign VA image. This function + * will try to "linearize" the VA image. i.e. making sure that the VA + * image offsets into the data buffer are in increasing order with the + * number of planes available in the image. + * + * This is an internal function used by gst_vaapi_image_new_with_image(). + * + * Return value: %TRUE on success + */ gboolean _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) { @@ -573,6 +648,14 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) return TRUE; } +/** + * gst_vaapi_image_get_display: + * @image: a #GstVaapiImage + * + * Returns the #GstVaapiDisplay this @image is bound to. + * + * Return value: the parent #GstVaapiDisplay object + */ GstVaapiDisplay * gst_vaapi_image_get_display(GstVaapiImage *image) { @@ -582,6 +665,14 @@ gst_vaapi_image_get_display(GstVaapiImage *image) return image->priv->display; } +/** + * gst_vaapi_image_get_format: + * @image: a #GstVaapiImage + * + * Returns the #GstVaapiImageFormat the @image was created with. + * + * Return value: the #GstVaapiImageFormat + */ GstVaapiImageFormat gst_vaapi_image_get_format(GstVaapiImage *image) { @@ -591,6 +682,14 @@ gst_vaapi_image_get_format(GstVaapiImage *image) return image->priv->format; } +/** + * gst_vaapi_image_get_width: + * @image: a #GstVaapiImage + * + * Returns the @image width. + * + * Return value: the image width, in pixels + */ guint gst_vaapi_image_get_width(GstVaapiImage *image) { @@ -600,6 +699,14 @@ gst_vaapi_image_get_width(GstVaapiImage *image) return image->priv->width; } +/** + * gst_vaapi_image_get_height: + * @image: a #GstVaapiImage + * + * Returns the @image height. + * + * Return value: the image height, in pixels. + */ guint gst_vaapi_image_get_height(GstVaapiImage *image) { @@ -609,6 +716,14 @@ gst_vaapi_image_get_height(GstVaapiImage *image) return image->priv->height; } +/** + * gst_vaapi_image_get_size: + * @image: a #GstVaapiImage + * @pwidth: (out) (allow-none): return location for the width, or %NULL + * @pheight: (out) (allow-none): return location for the height, or %NULL + * + * Retrieves the dimensions of a #GstVaapiImage. + */ void gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) { @@ -622,6 +737,16 @@ gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) *pheight = image->priv->height; } +/** + * gst_vaapi_image_is_linear: + * @image: a #GstVaapiImage + * + * Checks whether the @image has data planes allocated from a single + * buffer and offsets into that buffer are in increasing order with + * the number of planes. + * + * Return value: %TRUE if image data planes are allocated from a single buffer + */ gboolean gst_vaapi_image_is_linear(GstVaapiImage *image) { @@ -631,6 +756,14 @@ gst_vaapi_image_is_linear(GstVaapiImage *image) return image->priv->is_linear; } +/** + * gst_vaapi_image_is_mapped: + * @image: a #GstVaapiImage + * + * Checks whether the @image is currently mapped or not. + * + * Return value: %TRUE if the @image is mapped + */ static inline gboolean _gst_vaapi_image_is_mapped(GstVaapiImage *image) { @@ -646,6 +779,15 @@ gst_vaapi_image_is_mapped(GstVaapiImage *image) return _gst_vaapi_image_is_mapped(image); } +/** + * gst_vaapi_image_map: + * @image: a #GstVaapiImage + * + * Maps the image data buffer. The actual pixels are returned by the + * gst_vaapi_image_get_plane() function. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_image_map(GstVaapiImage *image) { @@ -678,6 +820,15 @@ _gst_vaapi_image_map(GstVaapiImage *image) return TRUE; } +/** + * gst_vaapi_image_unmap: + * @image: a #GstVaapiImage + * + * Unmaps the image data buffer. Pointers to pixels returned by + * gst_vaapi_image_get_plane() are then no longer valid. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_image_unmap(GstVaapiImage *image) { @@ -708,6 +859,15 @@ _gst_vaapi_image_unmap(GstVaapiImage *image) return TRUE; } +/** + * gst_vaapi_image_get_plane_count: + * @image: a #GstVaapiImage + * + * Retrieves the number of planes available in the @image. The @image + * must be mapped for this function to work properly. + * + * Return value: the number of planes available in the @image + */ guint gst_vaapi_image_get_plane_count(GstVaapiImage *image) { @@ -718,6 +878,16 @@ gst_vaapi_image_get_plane_count(GstVaapiImage *image) return image->priv->image.num_planes; } +/** + * gst_vaapi_image_get_plane: + * @image: a #GstVaapiImage + * @plane: the requested plane number + * + * Retrieves the pixels data to the specified @plane. The @image must + * be mapped for this function to work properly. + * + * Return value: the pixels data of the specified @plane + */ guchar * gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane) { @@ -729,6 +899,16 @@ gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane) return image->priv->image_data + image->priv->image.offsets[plane]; } +/** + * gst_vaapi_image_get_pitch: + * @image: a #GstVaapiImage + * @plane: the requested plane number + * + * Retrieves the line size (stride) of the specified @plane. The + * @image must be mapped for this function to work properly. + * + * Return value: the line size (stride) of the specified plane + */ guint gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane) { @@ -740,6 +920,16 @@ gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane) return image->priv->image.pitches[plane]; } +/** + * gst_vaapi_image_get_data_size: + * @image: a #GstVaapiImage + * + * Retrieves the underlying image data size. This function could be + * used to determine whether the image has a compatible layout with + * another image structure. + * + * Return value: the whole image data size of the @image + */ guint gst_vaapi_image_get_data_size(GstVaapiImage *image) { @@ -749,6 +939,16 @@ gst_vaapi_image_get_data_size(GstVaapiImage *image) return image->priv->image.data_size; } +/** + * gst_vaapi_image_update_from_buffer: + * @image: a #GstVaapiImage + * @buffer: a #GstBuffer + * + * Transfers pixels data contained in the #GstBuffer into the + * @image. Both image structures shall have the same format. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) { diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index bd9e53b829..df6dd4f835 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -51,21 +51,52 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_IMAGE, \ GstVaapiImageClass)) -#define GST_VAAPI_IMAGE_FORMAT(img) gst_vaapi_image_get_format(img) -#define GST_VAAPI_IMAGE_WIDTH(img) gst_vaapi_image_get_width(img) -#define GST_VAAPI_IMAGE_HEIGHT(img) gst_vaapi_image_get_height(img) +/** + * GST_VAAPI_IMAGE_FORMAT: + * @image: a #GstVaapiImage + * + * Macro that evaluates to the #GstVaapiImageFormat of @image. + */ +#define GST_VAAPI_IMAGE_FORMAT(image) gst_vaapi_image_get_format(image) + +/** + * GST_VAAPI_IMAGE_WIDTH: + * @image: a #GstVaapiImage + * + * Macro that evaluates to the width of @image. + */ +#define GST_VAAPI_IMAGE_WIDTH(image) gst_vaapi_image_get_width(image) + +/** + * GST_VAAPI_IMAGE_HEIGHT: + * @image: a #GstVaapiImage + * + * Macro that evaluates to the height of @image. + */ +#define GST_VAAPI_IMAGE_HEIGHT(image) gst_vaapi_image_get_height(image) typedef struct _GstVaapiImage GstVaapiImage; typedef struct _GstVaapiImagePrivate GstVaapiImagePrivate; typedef struct _GstVaapiImageClass GstVaapiImageClass; +/** + * GstVaapiImage: + * + * A VA image wrapper + */ struct _GstVaapiImage { /*< private >*/ GObject parent_instance; + /*< private >*/ GstVaapiImagePrivate *priv; }; +/** + * GstVaapiImageClass: + * + * A VA image wrapper class + */ struct _GstVaapiImageClass { /*< private >*/ GObjectClass parent_class; diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 24829d7d09..9903190414 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-image-format + * @short_description: + */ + #include "config.h" #include #include @@ -27,9 +32,9 @@ typedef enum _GstVaapiImageFormatType GstVaapiImageFormatType; typedef struct _GstVaapiImageFormatMap GstVaapiImageFormatMap; enum _GstVaapiImageFormatType { - GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR = 1, - GST_VAAPI_IMAGE_FORMAT_TYPE_RGB, - GST_VAAPI_IMAGE_FORMAT_TYPE_INDEXED + GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR = 1, /* YUV */ + GST_VAAPI_IMAGE_FORMAT_TYPE_RGB, /* RGB */ + GST_VAAPI_IMAGE_FORMAT_TYPE_INDEXED /* paletted */ }; struct _GstVaapiImageFormatMap { @@ -94,6 +99,14 @@ get_map(GstVaapiImageFormat format) return NULL; } +/** + * gst_vaapi_image_format_is_rgb: + * @format: a #GstVaapiImageFormat + * + * Checks whether the format is an RGB format. + * + * Return value: %TRUE if @format is RGB format + */ gboolean gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format) { @@ -102,6 +115,14 @@ gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format) return m ? (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB) : FALSE; } +/** + * gst_vaapi_image_format_is_yuv: + * @format: a #GstVaapiImageFormat + * + * Checks whether the format is an YUV format. + * + * Return value: %TRUE if @format is YUV format + */ gboolean gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format) { @@ -110,6 +131,16 @@ gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format) return m ? (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR) : FALSE; } +/** + * gst_vaapi_image_format: + * @va_format: a #VAImageFormat + * + * Converts a VA image format into the corresponding #GstVaapiImageFormat. + * If the image format cannot be represented by #GstVaapiImageFormat, + * then zero is returned. + * + * Return value: the #GstVaapiImageFormat describing the @va_format + */ GstVaapiImageFormat gst_vaapi_image_format(const VAImageFormat *va_format) { @@ -125,6 +156,16 @@ gst_vaapi_image_format(const VAImageFormat *va_format) return 0; } +/** + * gst_vaapi_image_format_from_caps: + * @caps: a #GstCaps + * + * Converts @caps into the corresponding #GstVaapiImageFormat. If the + * image format cannot be represented by #GstVaapiImageFormat, then + * zero is returned. + * + * Return value: the #GstVaapiImageFormat describing the @caps + */ GstVaapiImageFormat gst_vaapi_image_format_from_caps(GstCaps *caps) { @@ -174,12 +215,32 @@ gst_vaapi_image_format_from_caps(GstCaps *caps) return 0; } +/** + * gst_vaapi_image_format_from_fourcc: + * @fourcc: a FOURCC value + * + * Converts a FOURCC value into the corresponding #GstVaapiImageFormat. + * If the image format cannot be represented by #GstVaapiImageFormat, + * then zero is returned. + * + * Return value: the #GstVaapiImageFormat describing the FOURCC value + */ GstVaapiImageFormat gst_vaapi_image_format_from_fourcc(guint32 fourcc) { return (GstVaapiImageFormat)fourcc; } +/** + * gst_vaapi_image_format_get_va_format: + * @format: a #GstVaapiImageFormat + * + * Converts a #GstVaapiImageFormat into the corresponding VA image + * format. If no matching VA image format was found, %NULL is returned + * and this error must be reported to be fixed. + * + * Return value: the VA image format, or %NULL if none was found + */ const VAImageFormat * gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format) { @@ -188,6 +249,15 @@ gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format) return m ? &m->va_format : NULL; } +/** + * gst_vaapi_image_format_get_caps: + * @format: a #GstVaapiImageFormat + * + * Converts a #GstVaapiImageFormat into the corresponding #GstCaps. If + * no matching caps were found, %NULL is returned. + * + * Return value: the newly allocated #GstCaps, or %NULL if none was found + */ GstCaps * gst_vaapi_image_format_get_caps(GstVaapiImageFormat format) { @@ -196,6 +266,15 @@ gst_vaapi_image_format_get_caps(GstVaapiImageFormat format) return m ? gst_caps_from_string(m->caps_str) : NULL; } +/** + * gst_vaapi_image_format_get_score: + * @format: a #GstVaapiImageFormat + * + * Determines how "native" is this @format. The lower is the returned + * score, the best format this is for the underlying hardware. + * + * Return value: the @format score, or %G_MAXUINT if none was found + */ guint gst_vaapi_image_format_get_score(GstVaapiImageFormat format) { diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index 2037002f63..afa5b8c349 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -28,20 +28,32 @@ G_BEGIN_DECLS typedef enum _GstVaapiImageFormat GstVaapiImageFormat; +/** + * GstVaapiImageFormat: + * @GST_VAAPI_IMAGE_NV12: + * planar YUV 4:2:0, 12-bit, 1 plane for Y and 1 plane for UV + * @GST_VAAPI_IMAGE_YV12: + * planar YUV 4:2:0, 12-bit, 3 planes for Y V U + * @GST_VAAPI_IMAGE_I420: + * planar YUV 4:2:0, 12-bit, 3 planes for Y U V + * @GST_VAAPI_IMAGE_ARGB: + * packed RGB 8:8:8, 32-bit, A R G B + * @GST_VAAPI_IMAGE_RGBA: + * packed RGB 8:8:8, 32-bit, R G B A + * @GST_VAAPI_IMAGE_ABGR: + * packed RGB 8:8:8, 32-bit, A B G R + * @GST_VAAPI_IMAGE_BGRA: + * packed RGB 8:8:8, 32-bit, B G R A + * + * The set of all image formats for #GstVaapiImage. + */ enum _GstVaapiImageFormat { - /** Planar YUV 4:2:0, 12-bit, 1 plane for Y and 1 plane for UV */ GST_VAAPI_IMAGE_NV12 = VA_FOURCC('N','V','1','2'), - /** Planar YUV 4:2:0, 12-bit, 3 planes for Y V U */ GST_VAAPI_IMAGE_YV12 = VA_FOURCC('Y','V','1','2'), - /** Planar YUV 4:2:0, 12-bit, 3 planes for Y U V */ GST_VAAPI_IMAGE_I420 = VA_FOURCC('I','4','2','0'), - /** Packed RGB 8:8:8, 32-bit, A R G B */ GST_VAAPI_IMAGE_ARGB = VA_FOURCC('A','R','G','B'), - /** Packed RGB 8:8:8, 32-bit, R G B A */ GST_VAAPI_IMAGE_RGBA = VA_FOURCC('R','G','B','A'), - /** Packed RGB 8:8:8, 32-bit, A R G B */ GST_VAAPI_IMAGE_ABGR = VA_FOURCC('A','B','G','R'), - /** Packed RGB 8:8:8, 32-bit, R G B A */ GST_VAAPI_IMAGE_BGRA = VA_FOURCC('B','G','R','A'), }; diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index e74bfdd413..fff21fe802 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-subpicture + * @short_description: + */ + #include "config.h" #include #include "gstvaapiutils.h" @@ -166,21 +171,31 @@ gst_vaapi_subpicture_class_init(GstVaapiSubpictureClass *klass) object_class->set_property = gst_vaapi_subpicture_set_property; object_class->get_property = gst_vaapi_subpicture_get_property; + /** + * GstVaapiSubpicture:id: + * + * The underlying #VASubpictureID of the subpicture. + */ g_object_class_install_property (object_class, PROP_SUBPICTURE_ID, g_param_spec_uint("id", "VA subpicture id", - "VA subpicture id", + "The underlying VA subpicture id", 0, G_MAXUINT32, VA_INVALID_ID, G_PARAM_READABLE)); + /** + * GstVaapiSubpicture:image: + * + * The #GstVaapiImage this subpicture is bound to. + */ g_object_class_install_property (object_class, PROP_IMAGE, g_param_spec_object("image", - "image", - "GStreamer VA image", + "Image", + "The GstVaapiImage this subpicture is bound to", GST_VAAPI_TYPE_IMAGE, G_PARAM_READWRITE)); } @@ -195,6 +210,15 @@ gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture) priv->image = NULL; } +/** + * gst_vaapi_subpicture_new: + * @image: a #GstVaapiImage + * + * Creates a new #GstVaapiSubpicture with @image as source pixels. The + * newly created object holds a reference on @image. + * + * Return value: the newly allocated #GstVaapiSubpicture object + */ GstVaapiSubpicture * gst_vaapi_subpicture_new(GstVaapiImage *image) { @@ -207,6 +231,14 @@ gst_vaapi_subpicture_new(GstVaapiImage *image) NULL); } +/** + * gst_vaapi_subpicture_get_id: + * @subpicture: a #GstVaapiSubpicture + * + * Returns the underlying VASubpictureID of the @subpicture. + * + * Return value: the underlying VA subpicture id + */ VASubpictureID gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture) { @@ -215,6 +247,14 @@ gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture) return subpicture->priv->subpicture_id; } +/** + * gst_vaapi_subpicture_get_image: + * @subpicture: a #GstVaapiSubpicture + * + * Returns the #GstVaapiImage this @subpicture is bound to. + * + * Return value: the #GstVaapiImage this @subpicture is bound to + */ GstVaapiImage * gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture) { @@ -223,6 +263,14 @@ gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture) return subpicture->priv->image; } +/** + * gst_vaapi_subpicture_set_image: + * @subpicture: a #GstVaapiSubpicture + * @image: a #GstVaapiImage + * + * Binds a new #GstVaapiImage to the @subpicture. The reference to the + * previous image is released a new one acquired on @image. + */ void gst_vaapi_subpicture_set_image( GstVaapiSubpicture *subpicture, diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 927ba8a94f..c453ed917e 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -54,13 +54,24 @@ typedef struct _GstVaapiSubpicture GstVaapiSubpicture; typedef struct _GstVaapiSubpicturePrivate GstVaapiSubpicturePrivate; typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass; +/** + * GstVaapiSubpicture: + * + * A VA subpicture wrapper + */ struct _GstVaapiSubpicture { /*< private >*/ GObject parent_instance; + /*< private >*/ GstVaapiSubpicturePrivate *priv; }; +/** + * GstVaapiSubpictureClass: + * + * A VA subpicture wrapper class + */ struct _GstVaapiSubpictureClass { /*< private >*/ GObjectClass parent_class; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 79ab6e1da8..b82b40d875 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-surface + * @short_description: + */ + #include "config.h" #include "gstvaapiutils.h" #include "gstvaapisurface.h" @@ -210,21 +215,31 @@ gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass) object_class->get_property = gst_vaapi_surface_get_property; object_class->constructed = gst_vaapi_surface_constructed; + /** + * GstVaapiSurface:display: + * + * The #GstVaapiDisplay this surface is bound to. + */ g_object_class_install_property (object_class, PROP_DISPLAY, g_param_spec_object("display", - "display", - "GStreamer Va display", + "Display", + "The GstVaapiDisplay this surface is bound to", GST_VAAPI_TYPE_DISPLAY, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + /** + * GstVaapiSurface:id: + * + * The underlying #VASurfaceID of the surface. + */ g_object_class_install_property (object_class, PROP_SURFACE_ID, g_param_spec_uint("id", "VA surface id", - "VA surface id", + "The underlying VA surface id", 0, G_MAXUINT32, VA_INVALID_SURFACE, G_PARAM_READABLE)); @@ -232,8 +247,8 @@ gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass) (object_class, PROP_WIDTH, g_param_spec_uint("width", - "width", - "VA surface width", + "Width", + "The width of the surface", 0, G_MAXINT32, 0, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); @@ -241,8 +256,8 @@ gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass) (object_class, PROP_HEIGHT, g_param_spec_uint("height", - "height", - "VA surface height", + "Height", + "The height of the surface", 0, G_MAXINT32, 0, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); @@ -250,8 +265,8 @@ gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass) (object_class, PROP_CHROMA_TYPE, g_param_spec_uint("chroma-type", - "chroma-type", - "VA surface chroma type", + "Chroma type", + "The chroma type of the surface", 0, G_MAXUINT32, 0, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } @@ -269,6 +284,18 @@ gst_vaapi_surface_init(GstVaapiSurface *surface) priv->chroma_type = 0; } +/** + * gst_vaapi_surface_new: + * @display: a #GstVaapiDisplay + * @chroma_type: the surface chroma format + * @width: the requested surface width + * @height: the requested surface height + * + * Creates a new #GstVaapiSurface with the specified chroma format and + * dimensions. + * + * Return value: the newly allocated #GstVaapiSurface object + */ GstVaapiSurface * gst_vaapi_surface_new( GstVaapiDisplay *display, @@ -287,6 +314,14 @@ gst_vaapi_surface_new( NULL); } +/** + * gst_vaapi_surface_get_id: + * @surface: a #GstVaapiSurface + * + * Returns the underlying VASurfaceID of the @surface. + * + * Return value: the underlying VA surface id + */ VASurfaceID gst_vaapi_surface_get_id(GstVaapiSurface *surface) { @@ -295,6 +330,14 @@ gst_vaapi_surface_get_id(GstVaapiSurface *surface) return surface->priv->surface_id; } +/** + * gst_vaapi_surface_get_display: + * @surface: a #GstVaapiSurface + * + * Returns the #GstVaapiDisplay this @surface is bound to. + * + * Return value: the parent #GstVaapiDisplay object + */ GstVaapiDisplay * gst_vaapi_surface_get_display(GstVaapiSurface *surface) { @@ -303,6 +346,14 @@ gst_vaapi_surface_get_display(GstVaapiSurface *surface) return surface->priv->display; } +/** + * gst_vaapi_surface_get_chroma_type: + * @surface: a #GstVaapiSurface + * + * Returns the #GstVaapiChromaType the @surface was created with. + * + * Return value: the #GstVaapiChromaType + */ GstVaapiChromaType gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface) { @@ -311,6 +362,14 @@ gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface) return surface->priv->chroma_type; } +/** + * gst_vaapi_surface_get_width: + * @surface: a #GstVaapiSurface + * + * Returns the @surface width. + * + * Return value: the surface width, in pixels + */ guint gst_vaapi_surface_get_width(GstVaapiSurface *surface) { @@ -319,6 +378,14 @@ gst_vaapi_surface_get_width(GstVaapiSurface *surface) return surface->priv->width; } +/** + * gst_vaapi_surface_get_height: + * @surface: a #GstVaapiSurface + * + * Returns the @surface height. + * + * Return value: the surface height, in pixels. + */ guint gst_vaapi_surface_get_height(GstVaapiSurface *surface) { @@ -327,6 +394,14 @@ gst_vaapi_surface_get_height(GstVaapiSurface *surface) return surface->priv->height; } +/** + * gst_vaapi_surface_get_size: + * @surface: a #GstVaapiSurface + * @pwidth: (out) (allow-none): return location for the width, or %NULL + * @pheight: (out) (allow-none): return location for the height, or %NULL + * + * Retrieves the dimensions of a #GstVaapiSurface. + */ void gst_vaapi_surface_get_size( GstVaapiSurface *surface, @@ -343,6 +418,30 @@ gst_vaapi_surface_get_size( *pheight = gst_vaapi_surface_get_height(surface); } +/** + * gst_vaapi_surface_derive_image: + * @surface: a #GstVaapiSurface + * + * Derives a #GstVaapiImage from the @surface. This image buffer can + * then be mapped/unmapped for direct CPU access. This operation is + * only possible if the underlying implementation supports direct + * rendering capabilities and internal surface formats that can be + * represented with a #GstVaapiImage. + * + * When the operation is not possible, the function returns %NULL and + * the user should then fallback to using gst_vaapi_surface_get_image() + * or gst_vaapi_surface_put_image() to accomplish the same task in an + * indirect manner (additional copy). + * + * An image created with gst_vaapi_surface_derive_image() should be + * unreferenced when it's no longer needed. The image and image buffer + * data structures will be destroyed. However, the surface contents + * will remain unchanged until destroyed through the last call to + * g_object_unref(). + * + * Return value: the newly allocated #GstVaapiImage object, or %NULL + * on failure + */ GstVaapiImage * gst_vaapi_surface_derive_image(GstVaapiSurface *surface) { @@ -369,6 +468,16 @@ gst_vaapi_surface_derive_image(GstVaapiSurface *surface) return gst_vaapi_image_new_with_image(surface->priv->display, &va_image); } +/** + * gst_vaapi_surface_get_image + * @surface: a #GstVaapiSurface + * @image: a #GstVaapiImage + * + * Retrieves surface data into a #GstVaapiImage. The @image must have + * a format supported by the @surface. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) { @@ -401,6 +510,16 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) return TRUE; } +/** + * gst_vaapi_surface_put_image: + * @surface: a #GstVaapiSurface + * @image: a #GstVaapiImage + * + * Copies data from a #GstVaapiImage into a @surface. The @image must + * have a format supported by the @surface. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) { @@ -434,6 +553,15 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) return TRUE; } +/** + * gst_vaapi_surface_sync: + * @surface: a #GstVaapiSurface + * + * Blocks until all pending operations on the @surface have been + * completed. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_surface_sync(GstVaapiSurface *surface) { diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 2fa56aa8c7..3f81aa7ef6 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -28,6 +28,14 @@ G_BEGIN_DECLS typedef enum _GstVaapiChromaType GstVaapiChromaType; +/** + * GstVaapiChromaType: + * @GST_VAAPI_CHROMA_TYPE_YUV420: 4:2:0 chroma format + * @GST_VAAPI_CHROMA_TYPE_YUV422: 4:2:2 chroma format + * @GST_VAAPI_CHROMA_TYPE_YUV444: 4:4:4 chroma format + * + * The set of all chroma types for #GstVaapiSurface. + */ enum _GstVaapiChromaType { GST_VAAPI_CHROMA_TYPE_YUV420 = 1, GST_VAAPI_CHROMA_TYPE_YUV422, @@ -62,13 +70,24 @@ typedef struct _GstVaapiSurface GstVaapiSurface; typedef struct _GstVaapiSurfacePrivate GstVaapiSurfacePrivate; typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; +/** + * GstVaapiSurface: + * + * A VA surface wrapper. + */ struct _GstVaapiSurface { /*< private >*/ GObject parent_instance; + /*< private >*/ GstVaapiSurfacePrivate *priv; }; +/** + * GstVaapiSurfaceClass: + * + * A VA surface wrapper class. + */ struct _GstVaapiSurfaceClass { /*< private >*/ GObjectClass parent_class; diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.c b/gst-libs/gst/vaapi/gstvaapivideosink.c index 15d52b50ef..5df81a7222 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.c +++ b/gst-libs/gst/vaapi/gstvaapivideosink.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-video-sink: + * @short_description: An interface for implementing VA-API sink elements + */ + #include "config.h" #include "gstvaapivideosink.h" @@ -53,6 +58,14 @@ gst_vaapi_video_sink_get_type(void) return iface_type; } +/** + * gst_vaapi_video_sink_get_display: + * @sink: a #GstElement + * + * Returns the #GstVaapiDisplay created by the VA-API @sink element. + * + * Return value: the #GstVaapiDisplay created by the @sink element + */ GstVaapiDisplay * gst_vaapi_video_sink_get_display(GstVaapiVideoSink *sink) { @@ -61,6 +74,18 @@ gst_vaapi_video_sink_get_display(GstVaapiVideoSink *sink) return GST_VAAPI_VIDEO_SINK_GET_INTERFACE(sink)->get_display(sink); } +/** + * gst_vaapi_video_sink_lookup: + * @element: a #GstElement + * + * Traverses the whole downstream elements chain and finds a suitable + * #GstVaapiDisplay. This is a helper function for intermediate VA-API + * elements that don't create a #GstVaapiDisplay but require one. + * e.g. the `vaapiconvert' element. + * + * Return value: the #GstVaapiDisplay created by a downstream sink + * element, or %NULL if none was found + */ GstVaapiVideoSink * gst_vaapi_video_sink_lookup(GstElement *element) { diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.h b/gst-libs/gst/vaapi/gstvaapivideosink.h index 62ddb59b70..7254e19b25 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.h +++ b/gst-libs/gst/vaapi/gstvaapivideosink.h @@ -45,10 +45,17 @@ G_BEGIN_DECLS typedef struct _GstVaapiVideoSink GstVaapiVideoSink; /* dummy */ typedef struct _GstVaapiVideoSinkInterface GstVaapiVideoSinkInterface; +/** + * GstVaapiVideoSinkInterface: + * @get_display: virtual function for retrieving the #GstVaapiDisplay created + * by the downstream sink element. The implementation of that virtual + * function is required for all Gstreamer/VAAPI sink elements. + */ struct _GstVaapiVideoSinkInterface { /*< private >*/ GTypeInterface g_iface; + /*< public >*/ GstVaapiDisplay *(*get_display)(GstVaapiVideoSink *sink); }; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index d927ad33ad..6eab9106b5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-window + * @short_description: + */ + #include "config.h" #include "gstvaapiwindow.h" @@ -153,8 +158,8 @@ gst_vaapi_window_class_init(GstVaapiWindowClass *klass) (object_class, PROP_WIDTH, g_param_spec_uint("width", - "width", "Width", + "The window width", 1, G_MAXUINT32, 1, G_PARAM_READWRITE)); @@ -163,7 +168,7 @@ gst_vaapi_window_class_init(GstVaapiWindowClass *klass) PROP_HEIGHT, g_param_spec_uint("height", "height", - "Height", + "The window height", 1, G_MAXUINT32, 1, G_PARAM_READWRITE)); } @@ -179,6 +184,13 @@ gst_vaapi_window_init(GstVaapiWindow *window) priv->height = 1; } +/** + * gst_vaapi_window_show: + * @window: a #GstVaapiWindow + * + * Flags a window to be displayed. Any window that is not shown will + * not appear on the screen. + */ void gst_vaapi_window_show(GstVaapiWindow *window) { @@ -188,6 +200,13 @@ gst_vaapi_window_show(GstVaapiWindow *window) GST_VAAPI_WINDOW_GET_CLASS(window)->show(window); } +/** + * gst_vaapi_window_hide: + * @window: a #GstVaapiWindow + * + * Reverses the effects of gst_vaapi_window_show(), causing the window + * to be hidden (invisible to the user). + */ void gst_vaapi_window_hide(GstVaapiWindow *window) { @@ -197,6 +216,14 @@ gst_vaapi_window_hide(GstVaapiWindow *window) GST_VAAPI_WINDOW_GET_CLASS(window)->hide(window); } +/** + * gst_vaapi_window_get_width: + * @window: a #GstVaapiWindow + * + * Retrieves the width of a #GstVaapiWindow. + * + * Return value: the width of the @window, in pixels + */ guint gst_vaapi_window_get_width(GstVaapiWindow *window) { @@ -206,6 +233,14 @@ gst_vaapi_window_get_width(GstVaapiWindow *window) return window->priv->width; } +/** + * gst_vaapi_window_get_height: + * @window: a #GstVaapiWindow + * + * Retrieves the height of a #GstVaapiWindow + * + * Return value: the height of the @window, in pixels + */ guint gst_vaapi_window_get_height(GstVaapiWindow *window) { @@ -215,6 +250,14 @@ gst_vaapi_window_get_height(GstVaapiWindow *window) return window->priv->height; } +/** + * gst_vaapi_window_get_size: + * @window: a #GstVaapiWindow + * @pwidth: (out) (allow-none): return location for the width, or %NULL + * @pheight: (out) (allow-none): return location for the height, or %NULL + * + * Retrieves the dimensions of a #GstVaapiWindow. + */ void gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight) { @@ -228,6 +271,13 @@ gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight) *pheight = window->priv->height; } +/** + * gst_vaapi_window_set_width: + * @window: a #GstVaapiWindow + * @width: requested new width for the window, in pixels + * + * Resizes the @window to match the specified @width. + */ void gst_vaapi_window_set_width(GstVaapiWindow *window, guint width) { @@ -236,6 +286,13 @@ gst_vaapi_window_set_width(GstVaapiWindow *window, guint width) gst_vaapi_window_set_size(window, width, window->priv->height); } +/** + * gst_vaapi_window_set_height: + * @window: a #GstVaapiWindow + * @height: requested new height for the window, in pixels + * + * Resizes the @window to match the specified @height. + */ void gst_vaapi_window_set_height(GstVaapiWindow *window, guint height) { @@ -244,6 +301,14 @@ gst_vaapi_window_set_height(GstVaapiWindow *window, guint height) gst_vaapi_window_set_size(window, window->priv->width, height); } +/** + * gst_vaapi_window_set_size: + * @window: a #GstVaapiWindow + * @width: requested new width for the window, in pixels + * @height: requested new height for the window, in pixels + * + * Resizes the @window to match the specified @width and @height. + */ void gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) { @@ -283,6 +348,17 @@ get_window_rect(GstVaapiWindow *window, GstVideoRectangle *rect) rect->h = height; } +/** + * gst_vaapi_window_put_surface: + * @window: a #GstVaapiWindow + * @surface: a #GstVaapiSurface + * @flags: postprocessing flags + * + * Renders the whole @surface into the @window. The surface will be + * scale to fit the window, while not preserving aspect ratio. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_window_put_surface( GstVaapiWindow *window, @@ -306,6 +382,24 @@ gst_vaapi_window_put_surface( flags); } +/** + * gst_vaapi_window_put_surface_full: + * @window: a #GstVaapiWindow + * @surface: a #GstVaapiSurface + * @src_rect: (allow-none): the sub-rectangle of the source surface to + * extract and process. If %NULL, the entire surface will be used. + * @dst_rect: (allow-none): the sub-rectangle of the destination + * window into which the surface is rendered. If %NULL, the entire + * window will be used. + * @flags: postprocessing flags. See #GstVaapiSurfaceRenderFlags + * + * Renders the @surface region specified by @src_rect into the @window + * region specified by @dst_rect. The @flags specify how de-interlacing + * (if needed), color space conversion, scaling and other postprocessing + * transformations are performed. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_window_put_surface_full( GstVaapiWindow *window, diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 7c2fb567a8..8ad651be67 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -67,13 +67,30 @@ typedef struct _GstVaapiWindow GstVaapiWindow; typedef struct _GstVaapiWindowPrivate GstVaapiWindowPrivate; typedef struct _GstVaapiWindowClass GstVaapiWindowClass; +/** + * GstVaapiWindow: + * + * Base class for system-dependent windows. + */ struct _GstVaapiWindow { /*< private >*/ GObject parent_instance; + /*< private >*/ GstVaapiWindowPrivate *priv; }; +/** + * GstVaapiWindowClass: + * @create: virtual function to create a window with width and height + * @destroy: virtual function to destroy a window + * @show: virtual function to show (map) a window + * @hide: virtual function to hide (unmap) a window + * @resize: virtual function to resize a window + * @render: virtual function to render a #GstVaapiSurface into a window + * + * Base class for system-dependent windows. + */ struct _GstVaapiWindowClass { /*< private >*/ GObjectClass parent_class; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 1063920bae..573d20ebd8 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-window-x11 + * @short_description: + */ + #include "config.h" #include "gstvaapiwindow_x11.h" #include "gstvaapidisplay_x11.h" @@ -302,21 +307,31 @@ gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) window_class->resize = gst_vaapi_window_x11_resize; window_class->render = gst_vaapi_window_x11_render; + /** + * GstVaapiWindowX11:display: + * + * The #GstVaapiDisplay this window is bound to + */ g_object_class_install_property (object_class, PROP_DISPLAY, g_param_spec_object("display", - "display", "Display", + "The GstVaapiDisplay this window is bound to", GST_VAAPI_TYPE_DISPLAY, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + /** + * GstVaapiWindowX11:xid: + * + * The underlying X11 #Window XID. + */ g_object_class_install_property (object_class, PROP_XID, g_param_spec_uint("xid", "X window id", - "X window ID", + "The underlying X11 window id", 0, G_MAXUINT32, 0, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } @@ -333,6 +348,18 @@ gst_vaapi_window_x11_init(GstVaapiWindowX11 *window) priv->is_visible = FALSE; } +/** + * gst_vaapi_window_x11_new: + * @display: a #GstVaapiDisplay + * @width: the requested window width, in pixels + * @height: the requested windo height, in pixels + * + * Creates a window with the specified @width and @height. The window + * will be attached to the @display and remains invisible to the user + * until gst_vaapi_window_show() is called. + * + * Return value: the newly allocated #GstVaapiWindow object + */ GstVaapiWindow * gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) { @@ -349,6 +376,18 @@ gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) NULL); } +/** + * gst_vaapi_window_x11_new_with_xid: + * @display: a #GstVaapiDisplay + * @xid: an X11 #Window id + * + * Creates a #GstVaapiWindow using the X11 #Window @xid. The caller + * still owns the window and must call XDestroyWindow() when all + * #GstVaapiWindow references are released. Doing so too early can + * yield undefined behaviour. + * + * Return value: the newly allocated #GstVaapiWindow object + */ GstVaapiWindow * gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) { @@ -363,6 +402,16 @@ gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) NULL); } +/** + * gst_vaapi_window_x11_get_xid: + * @window: a #GstVaapiWindowX11 + * + * Returns the underlying X11 #Window that was created by + * gst_vaapi_window_x11_new() or that was bound with + * gst_vaapi_window_x11_new_with_xid(). + * + * Return value: the underlying X11 #Window bound to @window. + */ Window gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window) { diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index c1af6ec7a8..b8bbb5d676 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -55,13 +55,24 @@ typedef struct _GstVaapiWindowX11 GstVaapiWindowX11; typedef struct _GstVaapiWindowX11Private GstVaapiWindowX11Private; typedef struct _GstVaapiWindowX11Class GstVaapiWindowX11Class; +/** + * GstVaapiWindowX11: + * + * An X11 #Window wrapper. + */ struct _GstVaapiWindowX11 { /*< private >*/ GstVaapiWindow parent_instance; + /*< private >*/ GstVaapiWindowX11Private *priv; }; +/** + * GstVaapiWindowX11Class: + * + * An X11 #Window wrapper class. + */ struct _GstVaapiWindowX11Class { /*< private >*/ GstVaapiWindowClass parent_class; From dabb75745850f83aca9ca84750ccd4ef61ed7053 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 19 Mar 2010 16:08:48 +0000 Subject: [PATCH 0102/3781] Document surface & image pools. Drop obsolete gst_vaapi_video_pool_new() function. --- gst-libs/gst/vaapi/gstvaapiimagepool.c | 15 ++++++ gst-libs/gst/vaapi/gstvaapiimagepool.h | 11 ++++ gst-libs/gst/vaapi/gstvaapisurfacepool.c | 15 ++++++ gst-libs/gst/vaapi/gstvaapisurfacepool.h | 11 ++++ gst-libs/gst/vaapi/gstvaapivideopool.c | 67 +++++++++++++++++++----- gst-libs/gst/vaapi/gstvaapivideopool.h | 14 +++++ 6 files changed, 121 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 8a6a27c92b..435140be98 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-image-pool + * @short_description: + */ + #include "config.h" #include "gstvaapiimagepool.h" @@ -101,6 +106,16 @@ gst_vaapi_image_pool_init(GstVaapiImagePool *pool) priv->height = 0; } +/** + * gst_vaapi_image_pool_new: + * @display: a #GstVaapiDisplay + * @caps: a #GstCaps + * + * Creates a new #GstVaapiVideoPool of #GstVaapiImage with the + * specified dimensions in @caps. + * + * Return value: the newly allocated #GstVaapiVideoPool + */ GstVaapiVideoPool * gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps) { diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index 67d0086f15..8e0327799e 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -54,13 +54,24 @@ typedef struct _GstVaapiImagePool GstVaapiImagePool; typedef struct _GstVaapiImagePoolPrivate GstVaapiImagePoolPrivate; typedef struct _GstVaapiImagePoolClass GstVaapiImagePoolClass; +/** + * GstVaapiImagePool: + * + * A pool of lazily allocated #GstVaapiImage objects. + */ struct _GstVaapiImagePool { /*< private >*/ GstVaapiVideoPool parent_instance; + /*< private >*/ GstVaapiImagePoolPrivate *priv; }; +/** + * GstVaapiImagePoolClass: + * + * A pool of lazily allocated #GstVaapiImage objects. + */ struct _GstVaapiImagePoolClass { /*< private >*/ GstVaapiVideoPoolClass parent_class; diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 4fd8695632..1b6f0e94dc 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-surface-pool + * @short_description: + */ + #include "config.h" #include "gstvaapisurfacepool.h" @@ -101,6 +106,16 @@ gst_vaapi_surface_pool_init(GstVaapiSurfacePool *pool) priv->height = 0; } +/** + * gst_vaapi_surface_pool_new: + * @display: a #GstVaapiDisplay + * @caps: a #GstCaps + * + * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the + * specified dimensions in @caps. + * + * Return value: the newly allocated #GstVaapiVideoPool + */ GstVaapiVideoPool * gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps) { diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 16b2bc1729..b1e5f7117e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -54,13 +54,24 @@ typedef struct _GstVaapiSurfacePool GstVaapiSurfacePool; typedef struct _GstVaapiSurfacePoolPrivate GstVaapiSurfacePoolPrivate; typedef struct _GstVaapiSurfacePoolClass GstVaapiSurfacePoolClass; +/** + * GstVaapiSurfacePool: + * + * A pool of lazily allocated #GstVaapiSurface objects. + */ struct _GstVaapiSurfacePool { /*< private >*/ GstVaapiVideoPool parent_instance; + /*< private >*/ GstVaapiSurfacePoolPrivate *priv; }; +/** + * GstVaapiSurfacePoolClass: + * + * A pool of lazily allocated #GstVaapiSurface objects. + */ struct _GstVaapiSurfacePoolClass { /*< private >*/ GstVaapiVideoPoolClass parent_class; diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 5b41e42819..fb78dabc9f 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-video-pool + * @short_description: + */ + #include "config.h" #include "gstvaapivideopool.h" @@ -149,21 +154,32 @@ gst_vaapi_video_pool_class_init(GstVaapiVideoPoolClass *klass) object_class->set_property = gst_vaapi_video_pool_set_property; object_class->get_property = gst_vaapi_video_pool_get_property; + /** + * GstVaapiVideoPool:display: + * + * The #GstVaapiDisplay this pool is bound to. + */ g_object_class_install_property (object_class, PROP_DISPLAY, g_param_spec_object("display", - "display", - "Gstreamer/VA display", + "Display", + "The GstVaapiDisplay this pool is bound to", GST_VAAPI_TYPE_DISPLAY, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + /** + * GstVaapiVidePool:caps: + * + * The video object capabilities represented as a #GstCaps. This + * shall hold at least the "width" and "height" properties. + */ g_object_class_install_property (object_class, PROP_CAPS, g_param_spec_pointer("caps", "caps", - "Caps", + "The video object capabilities", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } @@ -180,15 +196,15 @@ gst_vaapi_video_pool_init(GstVaapiVideoPool *pool) g_queue_init(&priv->free_objects); } -GstVaapiVideoPool * -gst_vaapi_video_pool_new(GstVaapiDisplay *display, GstCaps *caps) -{ - return g_object_new(GST_VAAPI_TYPE_VIDEO_POOL, - "display", display, - "caps", caps, - NULL); -} - +/** + * gst_vaapi_video_pool_get_caps: + * @pool: a #GstVaapiVideoPool + * + * Retrieves the #GstCaps the @pool was created with. The @pool owns + * the returned object and it shall not be unref'ed. + * + * Return value: the #GstCaps the @pool was created with + */ GstCaps * gst_vaapi_video_pool_get_caps(GstVaapiVideoPool *pool) { @@ -197,6 +213,13 @@ gst_vaapi_video_pool_get_caps(GstVaapiVideoPool *pool) return pool->priv->caps; } +/* + * gst_vaapi_video_pool_set_caps: + * @pool: a #GstVaapiVideoPool + * @caps: a #GstCaps + * + * Binds new @caps to the @pool and notify the sub-classes. + */ void gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) { @@ -208,6 +231,17 @@ gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) klass->set_caps(pool, caps); } +/** + * gst_vaapi_video_pool_get_object: + * @pool: a #GstVaapiVideoPool + * + * Retrieves a new object from the @pool, or allocates a new one if + * none was found. The @pool holds a reference on the returned object + * and thus shall be released through gst_vaapi_video_pool_put_object() + * when it's no longer needed. + * + * Return value: a possibly newly allocated object, or %NULL on error + */ gpointer gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) { @@ -229,6 +263,15 @@ gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) return g_object_ref(object); } +/** + * gst_vaapi_video_pool_put_object: + * @pool: a #GstVaapiVideoPool + * @object: the object to add to the pool + * + * Pushes the @object back into the pool. The @object shall be + * previously allocated from the @pool. Calling this function with an + * arbitrary object yields undefined behaviour. + */ void gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) { diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 1d3b91a1fe..69a257bc11 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -54,13 +54,27 @@ typedef struct _GstVaapiVideoPool GstVaapiVideoPool; typedef struct _GstVaapiVideoPoolPrivate GstVaapiVideoPoolPrivate; typedef struct _GstVaapiVideoPoolClass GstVaapiVideoPoolClass; +/** + * GstVaapiVideoPool: + * + * A pool of lazily allocated video objects. e.g. surfaces, images. + */ struct _GstVaapiVideoPool { /*< private >*/ GObject parent_instance; + /*< private >*/ GstVaapiVideoPoolPrivate *priv; }; +/** + * GstVaapiVideoPoolClass: + * @set_caps: virtual function for notifying the subclass of the + * negotiated caps + * @alloc_object: virtual function for allocating a video pool object + * + * A pool base class used to hold video objects. e.g. surfaces, images. + */ struct _GstVaapiVideoPoolClass { /*< private >*/ GObjectClass parent_class; From e24ba07b41ee87abc779e25540a3975cdfaf82c6 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 19 Mar 2010 16:41:52 +0000 Subject: [PATCH 0103/3781] Document GstVaapiVideoBuffer. --- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 100 ++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 11 +++ 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 8104633ecd..9578df27d4 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gst-vaapi-video-buffer + * @short_description: + */ + #include "config.h" #include "gstvaapivideobuffer.h" #include @@ -116,7 +121,8 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) priv->surface = NULL; } -static inline GstVaapiVideoBuffer *gst_vaapi_video_buffer_new(void) +static inline GstVaapiVideoBuffer * +gst_vaapi_video_buffer_new(void) { GstMiniObject *object; @@ -127,6 +133,18 @@ static inline GstVaapiVideoBuffer *gst_vaapi_video_buffer_new(void) return GST_VAAPI_VIDEO_BUFFER(object); } +/** + * gst_vaapi_video_buffer_new_from_pool: + * @pool: a #GstVaapiVideoPool + * + * Creates a #GstBuffer with a video object allocated from a @pool. + * Only #GstVaapiSurfacePool and #GstVaapiImagePool pools are supported. + * + * The buffer is destroyed through the last call to gst_buffer_unref() + * and the video objects are pushed back to their respective pools. + * + * Return value: the newly allocated #GstBuffer, or %NULL on error + */ GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) { @@ -153,6 +171,15 @@ gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) return NULL; } +/** + * gst_vaapi_video_buffer_new_with_image: + * @image: a #GstVaapiImage + * + * Creates a #GstBuffer with the specified @image. The resulting + * buffer holds an additional reference to the @image. + * + * Return value: the newly allocated #GstBuffer, or %NULL on error + */ GstBuffer * gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) { @@ -166,6 +193,15 @@ gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) return GST_BUFFER(buffer); } +/** + * gst_vaapi_video_buffer_new_with_surface: + * @surface: a #GstVaapiSurface + * + * Creates a #GstBuffer with the specified @surface. The resulting + * buffer holds an additional reference to the @surface. + * + * Return value: the newly allocated #GstBuffer, or %NULL on error + */ GstBuffer * gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) { @@ -179,6 +215,17 @@ gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) return GST_BUFFER(buffer); } +/** + * gst_vaapi_video_buffer_get_image: + * @buffer: a #GstVaapiVideoBuffer + * + * Retrieves the #GstVaapiImage bound to the @buffer. The @buffer owns + * the #GstVaapiImage so the caller is responsible for calling + * g_object_ref() when needed. + * + * Return value: the #GstVaapiImage bound to the @buffer, or %NULL if + * there is none + */ GstVaapiImage * gst_vaapi_video_buffer_get_image(GstVaapiVideoBuffer *buffer) { @@ -187,6 +234,15 @@ gst_vaapi_video_buffer_get_image(GstVaapiVideoBuffer *buffer) return buffer->priv->image; } +/** + * gst_vaapi_video_buffer_set_image: + * @buffer: a #GstVaapiVideoBuffer + * @image: a #GstVaapiImage + * + * Binds @image to the @buffer. If the @buffer contains another image + * previously allocated from a pool, it's pushed back to its parent + * pool and the pool is also released. + */ void gst_vaapi_video_buffer_set_image( GstVaapiVideoBuffer *buffer, @@ -202,6 +258,17 @@ gst_vaapi_video_buffer_set_image( buffer->priv->image = g_object_ref(image); } +/** + * gst_vaapi_video_buffer_set_image_from_pool + * @buffer: a #GstVaapiVideoBuffer + * @pool: a #GstVaapiVideoPool + * + * Binds a newly allocated video object from the @pool. The @pool + * shall be of type #GstVaapiImagePool. Previously allocated objects + * are released and returned to their parent pools, if any. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_video_buffer_set_image_from_pool( GstVaapiVideoBuffer *buffer, @@ -222,6 +289,17 @@ gst_vaapi_video_buffer_set_image_from_pool( return TRUE; } +/** + * gst_vaapi_video_buffer_get_surface: + * @buffer: a #GstVaapiVideoBuffer + * + * Retrieves the #GstVaapiSurface bound to the @buffer. The @buffer + * owns the #GstVaapiSurface so the caller is responsible for calling + * g_object_ref() when needed. + * + * Return value: the #GstVaapiSurface bound to the @buffer, or %NULL if + * there is none + */ GstVaapiSurface * gst_vaapi_video_buffer_get_surface(GstVaapiVideoBuffer *buffer) { @@ -230,6 +308,15 @@ gst_vaapi_video_buffer_get_surface(GstVaapiVideoBuffer *buffer) return buffer->priv->surface; } +/** + * gst_vaapi_video_buffer_set_surface: + * @buffer: a #GstVaapiVideoBuffer + * @surface: a #GstVaapiSurface + * + * Binds @surface to the @buffer. If the @buffer contains another + * surface previously allocated from a pool, it's pushed back to its + * parent pool and the pool is also released. + */ void gst_vaapi_video_buffer_set_surface( GstVaapiVideoBuffer *buffer, @@ -245,6 +332,17 @@ gst_vaapi_video_buffer_set_surface( buffer->priv->surface = g_object_ref(surface); } +/** + * gst_vaapi_video_buffer_set_surface_from_pool + * @buffer: a #GstVaapiVideoBuffer + * @pool: a #GstVaapiVideoPool + * + * Binds a newly allocated video object from the @pool. The @pool + * shall be of type #GstVaapiSurfacePool. Previously allocated objects + * are released and returned to their parent pools, if any. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_video_buffer_set_surface_from_pool( GstVaapiVideoBuffer *buffer, diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index be19f6f0a8..7548098651 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -56,13 +56,24 @@ typedef struct _GstVaapiVideoBuffer GstVaapiVideoBuffer; typedef struct _GstVaapiVideoBufferPrivate GstVaapiVideoBufferPrivate; typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass; +/** + * GstVaapiVideoBuffer: + * + * A #GstBuffer holding video objects (#GstVaapiSurface and #GstVaapiImage). + */ struct _GstVaapiVideoBuffer { /*< private >*/ GstBuffer parent_instance; + /*< private >*/ GstVaapiVideoBufferPrivate *priv; }; +/** + * GstVaapiVideoBufferClass: + * + * A #GstBuffer holding video objects + */ struct _GstVaapiVideoBufferClass { /*< private >*/ GstBufferClass parent_class; From 5c0ee54d03ba18bf82f2a9b446c4e846c36ad701 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 19 Mar 2010 17:04:51 +0000 Subject: [PATCH 0104/3781] Document public API for libgstvaapi-*.so.*. --- Makefile.am | 2 +- NEWS | 1 + configure.ac | 8 + docs/Makefile.am | 10 + docs/reference/Makefile.am | 4 + docs/reference/libs/Makefile.am | 105 ++++++++++ docs/reference/libs/libs-docs.xml.in | 28 +++ docs/reference/libs/libs-overrides.txt | 0 docs/reference/libs/libs-sections.txt | 272 +++++++++++++++++++++++++ docs/reference/libs/libs.types | 12 ++ 10 files changed, 441 insertions(+), 1 deletion(-) create mode 100644 docs/Makefile.am create mode 100644 docs/reference/Makefile.am create mode 100644 docs/reference/libs/Makefile.am create mode 100644 docs/reference/libs/libs-docs.xml.in create mode 100644 docs/reference/libs/libs-overrides.txt create mode 100644 docs/reference/libs/libs-sections.txt create mode 100644 docs/reference/libs/libs.types diff --git a/Makefile.am b/Makefile.am index 99d568d11b..8fe73ad7f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign -SUBDIRS = debian gst-libs pkgconfig sys tests +SUBDIRS = debian gst-libs pkgconfig sys tests docs # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ diff --git a/NEWS b/NEWS index 4243881d8d..f17b1ca51e 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ gst-vaapi NEWS -- summary of changes. 2010-03-DD Copyright (C) 2010 Splitted-Desktop Systems Version 0.1.1 - DD.Mar.2010 +* Document public API for libgstvaapi-*.so.* * Optimize `vaapiconvert' pipeline (direct-rendering) Version 0.1.0 - 16.Mar.2010 diff --git a/configure.ac b/configure.ac index c93f844fab..f8f843d719 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,10 @@ AC_PROG_CC AM_PROG_CC_C_O AC_PROG_LIBTOOL +dnl Check for Gtk doc +GTK_DOC_CHECK([1.9]) +AM_CONDITIONAL([BUILD_GTK_DOC], [test "x$enable_gtk_doc" = "xyes"]) + dnl Check for GLib PKG_CHECK_MODULES([GLIB], [glib-2.0]) AC_SUBST(GLIB_CFLAGS) @@ -186,6 +190,10 @@ debian/libgstvaapi.install.in debian/libgstvaapi-dev.install.in debian/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:\ debian/libgstvaapi-x11.install.in + docs/Makefile + docs/reference/Makefile + docs/reference/libs/Makefile + docs/reference/libs/libs-docs.xml gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/vaapi/Makefile diff --git a/docs/Makefile.am b/docs/Makefile.am new file mode 100644 index 0000000000..516af70036 --- /dev/null +++ b/docs/Makefile.am @@ -0,0 +1,10 @@ +SUBDIRS = + +if BUILD_GTK_DOC +SUBDIRS += reference +endif + +DIST_SUBDIRS = reference + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am new file mode 100644 index 0000000000..d29d457676 --- /dev/null +++ b/docs/reference/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = libs + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am new file mode 100644 index 0000000000..8d1a0fcd26 --- /dev/null +++ b/docs/reference/libs/Makefile.am @@ -0,0 +1,105 @@ +## Process this file with automake to produce Makefile.in + +# We require automake 1.6 at least. +AUTOMAKE_OPTIONS = 1.6 + +# This is a blank Makefile.am for using gtk-doc. +# Copy this to your project's API docs directory and modify the variables to +# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples +# of using the various options. + +# The name of the module, e.g. 'glib'. +DOC_MODULE = libs + +# The top-level SGML file. You can change this if you want to. +DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting the functions and macros. +# e.g. DOC_SOURCE_DIR=../../../gtk +DOC_SOURCE_DIR = $(top_srcdir)/gst-libs/gst/vaapi + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS = --type-init-func="g_type_init()" + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS = --deprecated-guards="GST_VAAPI_DISABLE_DEPRECATED" + +# Extra options to supply to gtkdoc-mkdb. +# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml +MKDB_OPTIONS = --sgml-mode --output-format=xml --name-space=$(DOC_MODULE) + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS = + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS = \ + --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib \ + --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/gobject \ + --extra-dir=$(CAIRO_PREFIX)/share/gtk-doc/html/cairo \ + --extra-dir=$(PANGO_PREFIX)/share/gtk-doc/html/pango + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.h +CFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.c + +# Header files to ignore when scanning. +# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h +IGNORE_HFILES = \ + gstvaapidebug.h \ + gstvaapiutils.h \ + gstvaapiutils_x11.h \ + $(NULL) + +EXTRA_HFILES = \ + $(NULL) + +# Images to copy into HTML directory. +# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png +HTML_IMAGES = \ + $(NULL) + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +# e.g. content_files=running.sgml building.sgml changes-2.0.sgml +content_files = \ + $(NULL) + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files = \ + $(NULL) + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/gst-libs \ + -I$(top_srcdir)/gst-libs/gst/vaapi \ + $(GLIB_CFLAGS) + +GTKDOC_LIBS = \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la \ + $(GLIB_LIBS) + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +EXTRA_DIST += \ + $(NULL) + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in lib-docs.xml diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in new file mode 100644 index 0000000000..c9683aca47 --- /dev/null +++ b/docs/reference/libs/libs-docs.xml.in @@ -0,0 +1,28 @@ + + + + + GStreamer VA-API Plugins @GST_MAJORMINOR@ Library Reference Manual + + for GStreamer VA-API Library @GST_MAJORMINOR@ (@PACKAGE_VERSION@) + + + + + GStreamer VA-API Plugins Library + + + + + + + + + + + + + + + diff --git a/docs/reference/libs/libs-overrides.txt b/docs/reference/libs/libs-overrides.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt new file mode 100644 index 0000000000..c919a70fef --- /dev/null +++ b/docs/reference/libs/libs-sections.txt @@ -0,0 +1,272 @@ +
+gstvaapisurfacepool +GstVaapiSurfacePool +GstVaapiSurfacePool +GstVaapiSurfacePoolClass +gst_vaapi_surface_pool_new + +GST_VAAPI_SURFACE_POOL +GST_VAAPI_IS_SURFACE_POOL +GST_VAAPI_TYPE_SURFACE_POOL +gst_vaapi_surface_pool_get_type +GST_VAAPI_SURFACE_POOL_CLASS +GST_VAAPI_IS_SURFACE_POOL_CLASS +GST_VAAPI_SURFACE_POOL_GET_CLASS +
+ +
+gstvaapivideopool +GstVaapiVideoPool +GstVaapiVideoPool +GstVaapiVideoPoolClass +gst_vaapi_video_pool_get_caps +gst_vaapi_video_pool_get_object +gst_vaapi_video_pool_put_object + +GST_VAAPI_VIDEO_POOL +GST_VAAPI_IS_VIDEO_POOL +GST_VAAPI_TYPE_VIDEO_POOL +gst_vaapi_video_pool_get_type +GST_VAAPI_VIDEO_POOL_CLASS +GST_VAAPI_IS_VIDEO_POOL_CLASS +GST_VAAPI_VIDEO_POOL_GET_CLASS +
+ +
+gstvaapivideosink +GstVaapiVideoSink +GST_VAAPI_VIDEO_SINK_GET_INTERFACE +GstVaapiVideoSinkInterface +gst_vaapi_video_sink_get_display +gst_vaapi_video_sink_lookup + +GST_VAAPI_VIDEO_SINK +GST_VAAPI_IS_VIDEO_SINK +GST_VAAPI_TYPE_VIDEO_SINK +gst_vaapi_video_sink_get_type +
+ +
+gstvaapidisplay_x11 +GST_VAAPI_DISPLAY_XDISPLAY +GstVaapiDisplayX11 +GstVaapiDisplayX11 +GstVaapiDisplayX11Class +gst_vaapi_display_x11_new +gst_vaapi_display_x11_new_with_display +gst_vaapi_display_x11_get_display + +GST_VAAPI_DISPLAY_X11 +GST_VAAPI_IS_DISPLAY_X11 +GST_VAAPI_TYPE_DISPLAY_X11 +gst_vaapi_display_x11_get_type +GST_VAAPI_DISPLAY_X11_CLASS +GST_VAAPI_IS_DISPLAY_X11_CLASS +GST_VAAPI_DISPLAY_X11_GET_CLASS +
+ +
+gstvaapiwindow_x11 +GstVaapiWindowX11 +GstVaapiWindowX11 +GstVaapiWindowX11Class +gst_vaapi_window_x11_new +gst_vaapi_window_x11_new_with_xid +gst_vaapi_window_x11_get_xid + +GST_VAAPI_WINDOW_X11 +GST_VAAPI_IS_WINDOW_X11 +GST_VAAPI_TYPE_WINDOW_X11 +gst_vaapi_window_x11_get_type +GST_VAAPI_WINDOW_X11_CLASS +GST_VAAPI_IS_WINDOW_X11_CLASS +GST_VAAPI_WINDOW_X11_GET_CLASS +
+ +
+gstvaapidisplay +GST_VAAPI_DISPLAY_VADISPLAY +GST_VAAPI_DISPLAY_LOCK +GST_VAAPI_DISPLAY_UNLOCK +GstVaapiDisplay +GstVaapiDisplay +GstVaapiDisplayClass +gst_vaapi_display_new_with_display +gst_vaapi_display_lock +gst_vaapi_display_unlock +gst_vaapi_display_get_display +gst_vaapi_display_has_profile +gst_vaapi_display_get_image_caps +gst_vaapi_display_has_image_format +gst_vaapi_display_get_subpicture_caps +gst_vaapi_display_has_subpicture_format + +GST_VAAPI_DISPLAY +GST_VAAPI_IS_DISPLAY +GST_VAAPI_TYPE_DISPLAY +gst_vaapi_display_get_type +GST_VAAPI_DISPLAY_CLASS +GST_VAAPI_IS_DISPLAY_CLASS +GST_VAAPI_DISPLAY_GET_CLASS +
+ +
+gstvaapiimagepool +GstVaapiImagePool +GstVaapiImagePool +GstVaapiImagePoolClass +gst_vaapi_image_pool_new + +GST_VAAPI_IMAGE_POOL +GST_VAAPI_IS_IMAGE_POOL +GST_VAAPI_TYPE_IMAGE_POOL +gst_vaapi_image_pool_get_type +GST_VAAPI_IMAGE_POOL_CLASS +GST_VAAPI_IS_IMAGE_POOL_CLASS +GST_VAAPI_IMAGE_POOL_GET_CLASS +
+ +
+gstvaapivideobuffer +GstVaapiVideoBuffer +GstVaapiVideoBuffer +GstVaapiVideoBufferClass +gst_vaapi_video_buffer_new_from_pool +gst_vaapi_video_buffer_new_with_image +gst_vaapi_video_buffer_new_with_surface +gst_vaapi_video_buffer_get_image +gst_vaapi_video_buffer_set_image +gst_vaapi_video_buffer_set_image_from_pool +gst_vaapi_video_buffer_get_surface +gst_vaapi_video_buffer_set_surface +gst_vaapi_video_buffer_set_surface_from_pool + +GST_VAAPI_VIDEO_BUFFER +GST_VAAPI_IS_VIDEO_BUFFER +GST_VAAPI_TYPE_VIDEO_BUFFER +gst_vaapi_video_buffer_get_type +GST_VAAPI_VIDEO_BUFFER_CLASS +GST_VAAPI_IS_VIDEO_BUFFER_CLASS +GST_VAAPI_VIDEO_BUFFER_GET_CLASS +
+ +
+gstvaapiwindow +GstVaapiWindow +GstVaapiWindow +GstVaapiWindowClass +gst_vaapi_window_show +gst_vaapi_window_hide +gst_vaapi_window_get_width +gst_vaapi_window_get_height +gst_vaapi_window_get_size +gst_vaapi_window_set_width +gst_vaapi_window_set_height +gst_vaapi_window_set_size +gst_vaapi_window_put_surface +gst_vaapi_window_put_surface_full + +GST_VAAPI_WINDOW +GST_VAAPI_IS_WINDOW +GST_VAAPI_TYPE_WINDOW +gst_vaapi_window_get_type +GST_VAAPI_WINDOW_CLASS +GST_VAAPI_IS_WINDOW_CLASS +GST_VAAPI_WINDOW_GET_CLASS +
+ +
+gstvaapiimage +GST_VAAPI_IMAGE_FORMAT +GST_VAAPI_IMAGE_WIDTH +GST_VAAPI_IMAGE_HEIGHT +GstVaapiImage +GstVaapiImage +GstVaapiImageClass +gst_vaapi_image_new +gst_vaapi_image_new_with_image +gst_vaapi_image_get_id +gst_vaapi_image_get_image +gst_vaapi_image_get_display +gst_vaapi_image_get_format +gst_vaapi_image_get_width +gst_vaapi_image_get_height +gst_vaapi_image_get_size +gst_vaapi_image_is_linear +gst_vaapi_image_is_mapped +gst_vaapi_image_map +gst_vaapi_image_unmap +gst_vaapi_image_get_plane_count +gst_vaapi_image_get_plane +gst_vaapi_image_get_pitch +gst_vaapi_image_get_data_size +gst_vaapi_image_update_from_buffer + +GST_VAAPI_IMAGE +GST_VAAPI_IS_IMAGE +GST_VAAPI_TYPE_IMAGE +gst_vaapi_image_get_type +GST_VAAPI_IMAGE_CLASS +GST_VAAPI_IS_IMAGE_CLASS +GST_VAAPI_IMAGE_GET_CLASS +
+ +
+gstvaapisurface +GstVaapiChromaType +GstVaapiSurface +GstVaapiSurface +GstVaapiSurfaceClass +gst_vaapi_surface_new +gst_vaapi_surface_get_id +gst_vaapi_surface_get_display +gst_vaapi_surface_get_chroma_type +gst_vaapi_surface_get_width +gst_vaapi_surface_get_height +gst_vaapi_surface_get_size +gst_vaapi_surface_derive_image +gst_vaapi_surface_get_image +gst_vaapi_surface_put_image +gst_vaapi_surface_sync + +GST_VAAPI_SURFACE +GST_VAAPI_IS_SURFACE +GST_VAAPI_TYPE_SURFACE +gst_vaapi_surface_get_type +GST_VAAPI_SURFACE_CLASS +GST_VAAPI_IS_SURFACE_CLASS +GST_VAAPI_SURFACE_GET_CLASS +
+ +
+gstvaapisubpicture +GstVaapiSubpicture +GstVaapiSubpicture +GstVaapiSubpictureClass +gst_vaapi_subpicture_new +gst_vaapi_subpicture_get_id +gst_vaapi_subpicture_get_image +gst_vaapi_subpicture_set_image + +GST_VAAPI_SUBPICTURE +GST_VAAPI_IS_SUBPICTURE +GST_VAAPI_TYPE_SUBPICTURE +gst_vaapi_subpicture_get_type +GST_VAAPI_SUBPICTURE_CLASS +GST_VAAPI_IS_SUBPICTURE_CLASS +GST_VAAPI_SUBPICTURE_GET_CLASS +
+ +
+gstvaapiimageformat +GstVaapiImageFormat +GstVaapiImageFormat +gst_vaapi_image_format_is_rgb +gst_vaapi_image_format_is_yuv +gst_vaapi_image_format +gst_vaapi_image_format_from_caps +gst_vaapi_image_format_from_fourcc +gst_vaapi_image_format_get_va_format +gst_vaapi_image_format_get_caps +gst_vaapi_image_format_get_score +
diff --git a/docs/reference/libs/libs.types b/docs/reference/libs/libs.types new file mode 100644 index 0000000000..3efeb0a7d8 --- /dev/null +++ b/docs/reference/libs/libs.types @@ -0,0 +1,12 @@ +gst_vaapi_surface_pool_get_type +gst_vaapi_video_pool_get_type +gst_vaapi_video_sink_get_type +gst_vaapi_display_x11_get_type +gst_vaapi_window_x11_get_type +gst_vaapi_display_get_type +gst_vaapi_image_pool_get_type +gst_vaapi_video_buffer_get_type +gst_vaapi_window_get_type +gst_vaapi_image_get_type +gst_vaapi_surface_get_type +gst_vaapi_subpicture_get_type From 69f2b146f723b40bbbfcd7998ba91a2832c403c5 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 19 Mar 2010 17:11:20 +0000 Subject: [PATCH 0105/3781] Generate gtk-doc.make from gtkdocize. --- Makefile.am | 2 +- autogen.sh | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 8fe73ad7f9..51370db28d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,7 +6,7 @@ SUBDIRS = debian gst-libs pkgconfig sys tests docs MAINTAINERCLEANFILES = \ aclocal.m4 compile config.guess config.sub \ configure depcomp install-sh ltmain.sh \ - Makefile.in missing config.h.in + Makefile.in missing config.h.in gtk-doc.make deb: dist -mkdir -p debian-build diff --git a/autogen.sh b/autogen.sh index 9c2f4f6699..d5526f9978 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,3 +1,20 @@ #! /bin/sh + +GTKDOCIZE=`which gtkdocize` +if test -z $GTKDOCIZE; then + echo "*** No gtk-doc support ***" + echo "EXTRA_DIST =" > gtk-doc.make +else + gtkdocize || exit $? + # we need to patch gtk-doc.make to support pretty output with + # libtool 1.x. Should be fixed in the next version of gtk-doc. + # To be more resilient with the various versions of gtk-doc one + # can find, just sed gkt-doc.make rather than patch it. + sed -e 's#) --mode=compile#) --tag=CC --mode=compile#' gtk-doc.make > gtk-doc.temp \ + && mv gtk-doc.temp gtk-doc.make + sed -e 's#) --mode=link#) --tag=CC --mode=link#' gtk-doc.make > gtk-doc.temp \ + && mv gtk-doc.temp gtk-doc.make +fi + autoreconf -v --install ./configure "$@" From 8b93bb8b2a4bd5d9118a63ff5e391a4522203ed3 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 19 Mar 2010 17:13:59 +0000 Subject: [PATCH 0106/3781] Improve autogen.sh. --- autogen.sh | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/autogen.sh b/autogen.sh index d5526f9978..284547f02b 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,4 +1,16 @@ -#! /bin/sh +#!/bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +PROJECT=gstreamer-vaapi +TEST_TYPE=-d +FILE=gst-libs + +test $TEST_TYPE $FILE || { + echo "You must run this script in the top-level $PROJECT directory" + exit 1 +} GTKDOCIZE=`which gtkdocize` if test -z $GTKDOCIZE; then @@ -16,5 +28,12 @@ else && mv gtk-doc.temp gtk-doc.make fi -autoreconf -v --install -./configure "$@" +AUTORECONF=`which autoreconf` +if test -z $AUTORECONF; then + echo "*** No autoreconf found ***" + exit 1 +else + ACLOCAL="${ACLOCAL-aclocal} $ACLOCAL_FLAGS" autoreconf -v --install || exit $? +fi + +./configure "$@" && echo "Now type 'make' to compile $PROJECT." From 2b91d818366b05815d2c1b8974152e8315d6882d Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 19 Mar 2010 17:15:16 +0000 Subject: [PATCH 0107/3781] Fix make dist for --enable-gtk-doc builds. --- docs/reference/libs/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index 8d1a0fcd26..3a753c533a 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -99,6 +99,7 @@ include $(top_srcdir)/gtk-doc.make # Other files to distribute # e.g. EXTRA_DIST += version.xml.in EXTRA_DIST += \ + libs-docs.xml.in \ $(NULL) # Extra clean files so that maintainer-clean removes *everything* From 27307a6c1b963590420b56f1aa53178cfc1388c7 Mon Sep 17 00:00:00 2001 From: gb Date: Sun, 21 Mar 2010 08:12:52 +0000 Subject: [PATCH 0108/3781] Rename gst_vaapi_window_put_surface_full() to plain gst_vaapi_window_put_surface(). --- docs/reference/libs/libs-sections.txt | 1 - gst-libs/gst/vaapi/gstvaapiwindow.c | 36 +-------------------------- gst-libs/gst/vaapi/gstvaapiwindow.h | 7 ------ sys/vaapisink/gstvaapisink.c | 2 +- tests/test-windows.c | 4 +-- 5 files changed, 4 insertions(+), 46 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index c919a70fef..ff1aef0e38 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -164,7 +164,6 @@ gst_vaapi_window_set_width gst_vaapi_window_set_height gst_vaapi_window_set_size gst_vaapi_window_put_surface -gst_vaapi_window_put_surface_full GST_VAAPI_WINDOW GST_VAAPI_IS_WINDOW diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 6eab9106b5..0a1fa07bfa 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -352,40 +352,6 @@ get_window_rect(GstVaapiWindow *window, GstVideoRectangle *rect) * gst_vaapi_window_put_surface: * @window: a #GstVaapiWindow * @surface: a #GstVaapiSurface - * @flags: postprocessing flags - * - * Renders the whole @surface into the @window. The surface will be - * scale to fit the window, while not preserving aspect ratio. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_window_put_surface( - GstVaapiWindow *window, - GstVaapiSurface *surface, - guint flags -) -{ - GstVideoRectangle src_rect, dst_rect; - - g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE); - g_return_val_if_fail(window->priv->is_constructed, FALSE); - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - - get_surface_rect(surface, &src_rect); - get_window_rect(window, &dst_rect); - - return GST_VAAPI_WINDOW_GET_CLASS(window)->render(window, - surface, - &src_rect, - &dst_rect, - flags); -} - -/** - * gst_vaapi_window_put_surface_full: - * @window: a #GstVaapiWindow - * @surface: a #GstVaapiSurface * @src_rect: (allow-none): the sub-rectangle of the source surface to * extract and process. If %NULL, the entire surface will be used. * @dst_rect: (allow-none): the sub-rectangle of the destination @@ -401,7 +367,7 @@ gst_vaapi_window_put_surface( * Return value: %TRUE on success */ gboolean -gst_vaapi_window_put_surface_full( +gst_vaapi_window_put_surface( GstVaapiWindow *window, GstVaapiSurface *surface, const GstVideoRectangle *src_rect, diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 8ad651be67..6138170a65 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -136,13 +136,6 @@ gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height); gboolean gst_vaapi_window_put_surface( - GstVaapiWindow *window, - GstVaapiSurface *surface, - guint flags -); - -gboolean -gst_vaapi_window_put_surface_full( GstVaapiWindow *window, GstVaapiSurface *surface, const GstVideoRectangle *src_rect, diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 4c00ad44d4..70596121d5 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -176,7 +176,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) return GST_FLOW_UNEXPECTED; flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - if (!gst_vaapi_window_put_surface(sink->window, surface, flags)) + if (!gst_vaapi_window_put_surface(sink->window, surface, NULL, NULL, flags)) return GST_FLOW_UNEXPECTED; return GST_FLOW_OK; diff --git a/tests/test-windows.c b/tests/test-windows.c index 1e3ca49cb1..6813c94082 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -231,7 +231,7 @@ main(int argc, char *argv[]) gst_vaapi_window_show(window); - if (!gst_vaapi_window_put_surface(window, surface, flags)) + if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) g_error("could not render surface"); pause(); @@ -268,7 +268,7 @@ main(int argc, char *argv[]) gst_vaapi_window_show(window); - if (!gst_vaapi_window_put_surface(window, surface, flags)) + if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) g_error("could not render surface"); pause(); From 6179b6495e18743164c6552c1c47ddeb01f9953b Mon Sep 17 00:00:00 2001 From: gb Date: Sun, 21 Mar 2010 08:22:46 +0000 Subject: [PATCH 0109/3781] Move GstVaapiSurfaceRenderFlags to gstvaapisurface.h since this will also be useful for e.g. a gstvaapitexture.h. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapisurface.h | 28 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow.h | 12 ------------ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index ff1aef0e38..890b4a99e4 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -213,6 +213,7 @@ GST_VAAPI_IMAGE_GET_CLASS
gstvaapisurface GstVaapiChromaType +GstVaapiSurfaceRenderFlags GstVaapiSurface GstVaapiSurface GstVaapiSurfaceClass diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 3f81aa7ef6..f1a14b51d4 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -27,6 +27,7 @@ G_BEGIN_DECLS typedef enum _GstVaapiChromaType GstVaapiChromaType; +typedef enum _GstVaapiSurfaceRenderFlags GstVaapiSurfaceRenderFlags; /** * GstVaapiChromaType: @@ -42,6 +43,33 @@ enum _GstVaapiChromaType { GST_VAAPI_CHROMA_TYPE_YUV444 }; +/** + * GstVaapiSurfaceRenderFlags + * @GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: + * selects the top field of the surface + * @GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: + * selects the bottom field of the surface + * @GST_VAAPI_PICTURE_STRUCTURE_FRAME: + * selects the entire surface + * @GST_VAAPI_COLOR_STANDARD_ITUR_BT_601: + * uses ITU-R BT.601 standard for color space conversion + * @GST_VAAPI_COLOR_STANDARD_ITUR_BT_709: + * uses ITU-R BT.709 standard for color space conversion + * + * The set of all render flags for gst_vaapi_window_put_surface(). + */ +enum _GstVaapiSurfaceRenderFlags { + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD = 1 << 0, + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD = 1 << 1, + GST_VAAPI_PICTURE_STRUCTURE_FRAME = + ( + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD | + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD + ), + GST_VAAPI_COLOR_STANDARD_ITUR_BT_601 = 1 << 2, + GST_VAAPI_COLOR_STANDARD_ITUR_BT_709 = 1 << 3, +}; + #define GST_VAAPI_TYPE_SURFACE \ (gst_vaapi_surface_get_type()) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 6138170a65..82011af48e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -27,18 +27,6 @@ G_BEGIN_DECLS -enum { - GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD = 1 << 0, - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD = 1 << 1, - GST_VAAPI_PICTURE_STRUCTURE_FRAME = - ( - GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD | - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD - ), - GST_VAAPI_COLOR_STANDARD_ITUR_BT_601 = 1 << 2, - GST_VAAPI_COLOR_STANDARD_ITUR_BT_709 = 1 << 3, -}; - #define GST_VAAPI_TYPE_WINDOW \ (gst_vaapi_window_get_type()) From edea5998f53d56ab7ce29d4ef75871fc07dc5718 Mon Sep 17 00:00:00 2001 From: gb Date: Sun, 21 Mar 2010 08:38:17 +0000 Subject: [PATCH 0110/3781] Move GstVaapiSurfaceRenderFlags conversion to get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(). --- gst-libs/gst/vaapi/gstvaapiutils.c | 30 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 3 +++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 15 +------------ 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 6ed7320b3e..b3c15e8539 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -18,7 +18,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" #include "gstvaapiutils.h" +#include "gstvaapisurface.h" #include #include @@ -96,3 +98,31 @@ const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) } return ""; } + +/** + * get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags: + * + * Converts #GstVaapiSurfaceRenderFlags to flags suitable for + * vaPutSurface(). + */ +guint get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(guint flags) +{ + const guint va_top_bottom_fields = (VA_TOP_FIELD|VA_BOTTOM_FIELD); + guint va_flags = 0; + + if (flags & GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) + va_flags |= VA_TOP_FIELD; + if (flags & GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) + va_flags |= VA_BOTTOM_FIELD; + if ((va_flags & va_top_bottom_fields) == va_top_bottom_fields) { + va_flags &= ~va_top_bottom_fields; + va_flags |= VA_FRAME_PICTURE; + } + + if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_709) + va_flags |= VA_SRC_BT709; + else if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_601) + va_flags |= VA_SRC_BT601; + + return va_flags; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index ffdb808f94..8c18044cfe 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -45,4 +45,7 @@ const char *string_of_VAProfile(VAProfile profile) const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) attribute_hidden; +guint get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(guint flags) + attribute_hidden; + #endif /* GST_VAAPI_UTILS_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 573d20ebd8..69058703a3 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -177,7 +177,6 @@ gst_vaapi_window_x11_render( GstVaapiDisplay *display; VASurfaceID surface_id; VAStatus status; - guint va_flags = 0; display = gst_vaapi_surface_get_display(surface); if (!display) @@ -187,18 +186,6 @@ gst_vaapi_window_x11_render( if (surface_id == VA_INVALID_ID) return FALSE; - if (flags & GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) - va_flags |= VA_TOP_FIELD; - if (flags & GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) - va_flags |= VA_BOTTOM_FIELD; - if ((va_flags ^ (VA_TOP_FIELD|VA_BOTTOM_FIELD)) == 0) - va_flags = VA_FRAME_PICTURE; - - if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_709) - va_flags |= VA_SRC_BT709; - else if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_601) - va_flags |= VA_SRC_BT601; - GST_VAAPI_DISPLAY_LOCK(display); status = vaPutSurface( GST_VAAPI_DISPLAY_VADISPLAY(display), @@ -213,7 +200,7 @@ gst_vaapi_window_x11_render( dst_rect->w, dst_rect->h, NULL, 0, - va_flags + get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(flags) ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaPutSurface()")) From 4f00d5657b95868ef605346d704315576741be71 Mon Sep 17 00:00:00 2001 From: gb Date: Sun, 21 Mar 2010 08:45:09 +0000 Subject: [PATCH 0111/3781] Fix documentation of *Class'es. --- gst-libs/gst/vaapi/gstvaapidisplay.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 1 - gst-libs/gst/vaapi/gstvaapiimage.h | 1 - gst-libs/gst/vaapi/gstvaapiimagepool.h | 1 - gst-libs/gst/vaapi/gstvaapisubpicture.h | 1 - gst-libs/gst/vaapi/gstvaapisurface.h | 1 - gst-libs/gst/vaapi/gstvaapisurfacepool.h | 1 - gst-libs/gst/vaapi/gstvaapivideobuffer.h | 1 - gst-libs/gst/vaapi/gstvaapivideopool.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 1 - 11 files changed, 3 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 5744a74584..95fa54dd55 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -91,7 +91,6 @@ struct _GstVaapiDisplay { /*< private >*/ GObject parent_instance; - /*< private >*/ GstVaapiDisplayPrivate *priv; }; @@ -109,6 +108,7 @@ struct _GstVaapiDisplayClass { /*< private >*/ GObjectClass parent_class; + /*< public >*/ gboolean (*open_display) (GstVaapiDisplay *display); void (*close_display) (GstVaapiDisplay *display); void (*lock_display) (GstVaapiDisplay *display); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 6718d9720e..9cf79b5224 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -72,7 +72,6 @@ struct _GstVaapiDisplayX11 { /*< private >*/ GstVaapiDisplay parent_instance; - /*< private >*/ GstVaapiDisplayX11Private *priv; }; diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index df6dd4f835..6c05717cd8 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -88,7 +88,6 @@ struct _GstVaapiImage { /*< private >*/ GObject parent_instance; - /*< private >*/ GstVaapiImagePrivate *priv; }; diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index 8e0327799e..c5c7a02900 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -63,7 +63,6 @@ struct _GstVaapiImagePool { /*< private >*/ GstVaapiVideoPool parent_instance; - /*< private >*/ GstVaapiImagePoolPrivate *priv; }; diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index c453ed917e..799aae8e97 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -63,7 +63,6 @@ struct _GstVaapiSubpicture { /*< private >*/ GObject parent_instance; - /*< private >*/ GstVaapiSubpicturePrivate *priv; }; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index f1a14b51d4..4a4843811e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -107,7 +107,6 @@ struct _GstVaapiSurface { /*< private >*/ GObject parent_instance; - /*< private >*/ GstVaapiSurfacePrivate *priv; }; diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index b1e5f7117e..66a4654afb 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -63,7 +63,6 @@ struct _GstVaapiSurfacePool { /*< private >*/ GstVaapiVideoPool parent_instance; - /*< private >*/ GstVaapiSurfacePoolPrivate *priv; }; diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index 7548098651..ae737e7fe5 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -65,7 +65,6 @@ struct _GstVaapiVideoBuffer { /*< private >*/ GstBuffer parent_instance; - /*< private >*/ GstVaapiVideoBufferPrivate *priv; }; diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 69a257bc11..d779f43f22 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -63,7 +63,6 @@ struct _GstVaapiVideoPool { /*< private >*/ GObject parent_instance; - /*< private >*/ GstVaapiVideoPoolPrivate *priv; }; @@ -79,6 +78,7 @@ struct _GstVaapiVideoPoolClass { /*< private >*/ GObjectClass parent_class; + /*< public >*/ void (*set_caps) (GstVaapiVideoPool *pool, GstCaps *caps); gpointer (*alloc_object)(GstVaapiVideoPool *pool, GstVaapiDisplay *display); }; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 82011af48e..9e3689bf4f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -64,7 +64,6 @@ struct _GstVaapiWindow { /*< private >*/ GObject parent_instance; - /*< private >*/ GstVaapiWindowPrivate *priv; }; @@ -83,6 +82,7 @@ struct _GstVaapiWindowClass { /*< private >*/ GObjectClass parent_class; + /*< public >*/ gboolean (*create) (GstVaapiWindow *window, guint *width, guint *height); void (*destroy)(GstVaapiWindow *window); gboolean (*show) (GstVaapiWindow *window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index b8bbb5d676..d46b996291 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -64,7 +64,6 @@ struct _GstVaapiWindowX11 { /*< private >*/ GstVaapiWindow parent_instance; - /*< private >*/ GstVaapiWindowX11Private *priv; }; From cc1c61e917b74e98ec5a404b44f0c0cde1b97ce1 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 08:03:12 +0000 Subject: [PATCH 0112/3781] Build-Requires: gstreamer-plugins-base >= 0.10.16. --- configure.ac | 4 +++- debian/control.in | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index f8f843d719..64b2871696 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ m4_define([gst_version], # gst plugins-base version number m4_define([gst_plugins_base_major_version], [0]) m4_define([gst_plugins_base_minor_version], [10]) -m4_define([gst_plugins_base_micro_version], [0]) +m4_define([gst_plugins_base_micro_version], [16]) m4_define([gst_plugins_base_version], [gst_plugins_base_major_version.gst_plugins_base_minor_version.gst_plugins_base_micro_version]) @@ -82,6 +82,8 @@ GST_MAJORMINOR=gst_major_minor_version GST_VERSION_REQUIRED=gst_version GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version AC_SUBST(GST_MAJORMINOR) +AC_SUBST(GST_VERSION_REQUIRED) +AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) dnl Check for tools AC_PROG_CC diff --git a/debian/control.in b/debian/control.in index 9db525b9b4..f547769f94 100644 --- a/debian/control.in +++ b/debian/control.in @@ -5,8 +5,8 @@ Maintainer: Gwenole Beauchesne Build-Depends: debhelper (>= 5), cdbs, libglib2.0-dev, - libgstreamer@GST_MAJORMINOR@-dev, - libgstreamer-plugins-base@GST_MAJORMINOR@-dev, + libgstreamer@GST_MAJORMINOR@-dev (>= @GST_VERSION_REQUIRED@), + libgstreamer-plugins-base@GST_MAJORMINOR@-dev (>= @GST_PLUGINS_BASE_VERSION_REQUIRED@), libva-dev (>= @LIBVA_SDS_PACKAGE_VERSION@) Standards-Version: 3.7.2 From 01cc10fe5147c39a12185efa560aa40814d4cebd Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 08:44:38 +0000 Subject: [PATCH 0113/3781] Add display size accessors. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 86 +++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidisplay.h | 11 +++ gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 23 +++++++ tests/test-display.c | 4 ++ 4 files changed, 123 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index a6c0f76635..fde9043290 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -43,6 +43,8 @@ G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT); struct _GstVaapiDisplayPrivate { GStaticMutex mutex; VADisplay display; + guint width; + guint height; gboolean create_display; GArray *profiles; GArray *image_formats; @@ -52,7 +54,9 @@ struct _GstVaapiDisplayPrivate { enum { PROP_0, - PROP_DISPLAY + PROP_DISPLAY, + PROP_WIDTH, + PROP_HEIGHT }; /* Append GstVaapiImageFormat to formats array */ @@ -230,6 +234,8 @@ gst_vaapi_display_create(GstVaapiDisplay *display) return FALSE; if (klass->get_display) priv->display = klass->get_display(display); + if (klass->get_size) + klass->get_size(display, &priv->width, &priv->height); } if (!priv->display) return FALSE; @@ -360,6 +366,12 @@ gst_vaapi_display_get_property( case PROP_DISPLAY: g_value_set_pointer(value, gst_vaapi_display_get_display(display)); break; + case PROP_WIDTH: + g_value_set_uint(value, gst_vaapi_display_get_width(display)); + break; + case PROP_HEIGHT: + g_value_set_uint(value, gst_vaapi_display_get_height(display)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -405,6 +417,24 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) "VA display", "VA display", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_uint("width", + "Width", + "The display width", + 1, G_MAXUINT32, 1, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_uint("height", + "height", + "The display height", + 1, G_MAXUINT32, 1, + G_PARAM_READABLE)); } static void @@ -414,6 +444,8 @@ gst_vaapi_display_init(GstVaapiDisplay *display) display->priv = priv; priv->display = NULL; + priv->width = 0; + priv->height = 0; priv->create_display = TRUE; priv->profiles = NULL; priv->image_formats = NULL; @@ -495,6 +527,58 @@ gst_vaapi_display_get_display(GstVaapiDisplay *display) return display->priv->display; } +/** + * gst_vaapi_display_get_width: + * @display: a #GstVaapiDisplay + * + * Retrieves the width of a #GstVaapiDisplay. + * + * Return value: the width of the @display, in pixels + */ +guint +gst_vaapi_display_get_width(GstVaapiDisplay *display) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), 0); + + return display->priv->width; +} + +/** + * gst_vaapi_display_get_height: + * @display: a #GstVaapiDisplay + * + * Retrieves the height of a #GstVaapiDisplay + * + * Return value: the height of the @display, in pixels + */ +guint +gst_vaapi_display_get_height(GstVaapiDisplay *display) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), 0); + + return display->priv->height; +} + +/** + * gst_vaapi_display_get_size: + * @display: a #GstVaapiDisplay + * @pwidth: (out) (allow-none): return location for the width, or %NULL + * @pheight: (out) (allow-none): return location for the height, or %NULL + * + * Retrieves the dimensions of a #GstVaapiDisplay. + */ +void +gst_vaapi_display_get_size(GstVaapiDisplay *display, guint *pwidth, guint *pheight) +{ + g_return_if_fail(GST_VAAPI_DISPLAY(display)); + + if (pwidth) + *pwidth = display->priv->width; + + if (pheight) + *pheight = display->priv->height; +} + /** * gst_vaapi_display_has_profile: * @display: a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 95fa54dd55..e1f9f8660c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -101,6 +101,7 @@ struct _GstVaapiDisplay { * @lock_display: virtual function to lock a display * @unlock_display: virtual function to unlock a display * @get_display: virtual function to retrieve the #VADisplay + * @get_size: virtual function to retrieve the display dimensions * * Base class for VA displays. */ @@ -114,6 +115,7 @@ struct _GstVaapiDisplayClass { void (*lock_display) (GstVaapiDisplay *display); void (*unlock_display)(GstVaapiDisplay *display); VADisplay (*get_display) (GstVaapiDisplay *display); + void (*get_size) (GstVaapiDisplay *display, guint *pw, guint *ph); }; GType @@ -131,6 +133,15 @@ gst_vaapi_display_unlock(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); + gboolean gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index bfd65897be..133c808673 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -43,6 +43,7 @@ struct _GstVaapiDisplayX11Private { gboolean create_display; gchar *display_name; Display *x11_display; + int x11_screen; VADisplay *va_display; }; @@ -147,6 +148,7 @@ gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) if (!priv->x11_display) return FALSE; + priv->x11_screen = DefaultScreen(priv->x11_display); priv->va_display = vaGetDisplay(priv->x11_display); return priv->va_display != NULL; } @@ -177,6 +179,25 @@ gst_vaapi_display_x11_get_va_display(GstVaapiDisplay *display) return GST_VAAPI_DISPLAY_X11(display)->priv->va_display; } +static void +gst_vaapi_display_x11_get_size( + GstVaapiDisplay *display, + guint *pwidth, + guint *pheight +) +{ + GstVaapiDisplayX11Private * const priv = GST_VAAPI_DISPLAY_X11(display)->priv; + + 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_class_init(GstVaapiDisplayX11Class *klass) { @@ -193,6 +214,7 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) dpy_class->open_display = gst_vaapi_display_x11_open_display; dpy_class->close_display = gst_vaapi_display_x11_close_display; dpy_class->get_display = gst_vaapi_display_x11_get_va_display; + dpy_class->get_size = gst_vaapi_display_x11_get_size; /** * GstVaapiDisplayX11:x11-display: @@ -231,6 +253,7 @@ gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) display->priv = priv; priv->create_display = TRUE; priv->x11_display = NULL; + priv->x11_screen = 0; priv->display_name = NULL; } diff --git a/tests/test-display.c b/tests/test-display.c index 4a510d5371..388abbfc09 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -94,6 +94,7 @@ main(int argc, char *argv[]) Display *x11_display; VADisplay va_display; GstVaapiDisplay *display; + guint width, height; gst_init(&argc, &argv); @@ -105,6 +106,9 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); + gst_vaapi_display_get_size(display, &width, &height); + g_print("Display size: %ux%u\n", width, height); + dump_caps(display); g_object_unref(display); } From a0ed6ea05bc667d1b34ed59a511ed580137ecd15 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 08:45:03 +0000 Subject: [PATCH 0114/3781] Updates. --- docs/reference/libs/libs-sections.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 890b4a99e4..0907fbd224 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -95,6 +95,9 @@ gst_vaapi_display_new_with_display gst_vaapi_display_lock gst_vaapi_display_unlock gst_vaapi_display_get_display +gst_vaapi_display_get_width +gst_vaapi_display_get_height +gst_vaapi_display_get_size gst_vaapi_display_has_profile gst_vaapi_display_get_image_caps gst_vaapi_display_has_image_format From c13c3c36206dc26b3ae2d9232a740c3b983c94e7 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 09:32:01 +0000 Subject: [PATCH 0115/3781] Add gst_vaapi_display_get_pixel_aspect_ratio(). --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapidisplay.c | 80 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 15 ++++- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 24 ++++++- tests/test-display.c | 5 +- 5 files changed, 121 insertions(+), 4 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 0907fbd224..f0832fa537 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -98,6 +98,7 @@ gst_vaapi_display_get_display gst_vaapi_display_get_width gst_vaapi_display_get_height gst_vaapi_display_get_size +gst_vaapi_display_get_pixel_aspect_ratio gst_vaapi_display_has_profile gst_vaapi_display_get_image_caps gst_vaapi_display_has_image_format diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index fde9043290..e084baf164 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -45,6 +45,10 @@ struct _GstVaapiDisplayPrivate { VADisplay display; guint width; guint height; + guint width_mm; + guint height_mm; + guint par_n; + guint par_d; gboolean create_display; GArray *profiles; GArray *image_formats; @@ -185,6 +189,51 @@ get_caps(GArray *formats) return out_caps; } +static void +gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display) +{ + GstVaapiDisplayPrivate * const priv = display->priv; + gdouble ratio, delta; + gint i, index; + + static const gint par[][2] = { + {1, 1}, /* regular screen */ + {16, 15}, /* PAL TV */ + {11, 10}, /* 525 line Rec.601 video */ + {54, 59}, /* 625 line Rec.601 video */ + {64, 45}, /* 1280x1024 on 16:9 display */ + {5, 3}, /* 1280x1024 on 4:3 display */ + {4, 3} /* 800x600 on 16:9 display */ + }; + + /* First, calculate the "real" ratio based on the X values; + * which is the "physical" w/h divided by the w/h in pixels of the + * display */ + if (!priv->width || !priv->height || !priv->width_mm || !priv->height_mm) + ratio = 1.0; + else + ratio = (gdouble)(priv->width_mm * priv->height) / + (priv->height_mm * priv->width); + GST_DEBUG("calculated pixel aspect ratio: %f", ratio); + + /* Now, find the one from par[][2] with the lowest delta to the real one */ +#define DELTA(idx) (ABS(ratio - ((gdouble)par[idx][0] / par[idx][1]))) + delta = DELTA(0); + index = 0; + + for (i = 1; i < G_N_ELEMENTS(par); i++) { + const gdouble this_delta = DELTA(i); + if (this_delta < delta) { + index = i; + delta = this_delta; + } + } +#undef DELTA + + priv->par_n = par[index][0]; + priv->par_d = par[index][1]; +} + static void gst_vaapi_display_destroy(GstVaapiDisplay *display) { @@ -236,6 +285,9 @@ gst_vaapi_display_create(GstVaapiDisplay *display) priv->display = klass->get_display(display); if (klass->get_size) klass->get_size(display, &priv->width, &priv->height); + if (klass->get_size_mm) + klass->get_size_mm(display, &priv->width_mm, &priv->height_mm); + gst_vaapi_display_calculate_pixel_aspect_ratio(display); } if (!priv->display) return FALSE; @@ -446,6 +498,10 @@ gst_vaapi_display_init(GstVaapiDisplay *display) priv->display = NULL; priv->width = 0; priv->height = 0; + priv->width_mm = 0; + priv->height_mm = 0; + priv->par_n = 1; + priv->par_d = 1; priv->create_display = TRUE; priv->profiles = NULL; priv->image_formats = NULL; @@ -579,6 +635,30 @@ gst_vaapi_display_get_size(GstVaapiDisplay *display, guint *pwidth, guint *pheig *pheight = display->priv->height; } +/** + * gst_vaapi_display_get_pixel_aspect_ratio: + * @display: a #GstVaapiDisplay + * @par_n: (out) (allow-none): return location for the numerator of pixel aspect ratio, or %NULL + * @par_d: (out) (allow-none): return location for the denominator of pixel aspect ratio, or %NULL + * + * Retrieves the pixel aspect ratio of a #GstVaapiDisplay. + */ +void +gst_vaapi_display_get_pixel_aspect_ratio( + GstVaapiDisplay *display, + guint *par_n, + guint *par_d +) +{ + g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); + + if (par_n) + *par_n = display->priv->par_n; + + if (par_d) + *par_d = display->priv->par_d; +} + /** * gst_vaapi_display_has_profile: * @display: a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index e1f9f8660c..8b41d3c3cc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -101,7 +101,8 @@ struct _GstVaapiDisplay { * @lock_display: virtual function to lock a display * @unlock_display: virtual function to unlock a display * @get_display: virtual function to retrieve the #VADisplay - * @get_size: virtual function to retrieve the display dimensions + * @get_size: virtual function to retrieve the display dimensions, in pixels + * @get_size_mm: virtual function to retrieve the display dimensions, in millimeters * * Base class for VA displays. */ @@ -115,7 +116,10 @@ struct _GstVaapiDisplayClass { void (*lock_display) (GstVaapiDisplay *display); void (*unlock_display)(GstVaapiDisplay *display); VADisplay (*get_display) (GstVaapiDisplay *display); - void (*get_size) (GstVaapiDisplay *display, guint *pw, guint *ph); + void (*get_size) (GstVaapiDisplay *display, + guint *pwidth, guint *pheight); + void (*get_size_mm) (GstVaapiDisplay *display, + guint *pwidth, guint *pheight); }; GType @@ -142,6 +146,13 @@ 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_profile(GstVaapiDisplay *display, VAProfile profile); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 133c808673..5553f88b07 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -186,7 +186,8 @@ gst_vaapi_display_x11_get_size( guint *pheight ) { - GstVaapiDisplayX11Private * const priv = GST_VAAPI_DISPLAY_X11(display)->priv; + GstVaapiDisplayX11Private * const priv = + GST_VAAPI_DISPLAY_X11(display)->priv; if (!priv->x11_display) return; @@ -198,6 +199,26 @@ gst_vaapi_display_x11_get_size( *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(display)->priv; + + if (!priv->x11_display) + return; + + if (pwidth) + *pwidth = DisplayWidthMM(priv->x11_display, priv->x11_screen); + + if (pheight) + *pheight = DisplayHeightMM(priv->x11_display, priv->x11_screen); +} + static void gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) { @@ -215,6 +236,7 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) dpy_class->close_display = gst_vaapi_display_x11_close_display; dpy_class->get_display = gst_vaapi_display_x11_get_va_display; dpy_class->get_size = gst_vaapi_display_x11_get_size; + dpy_class->get_size_mm = gst_vaapi_display_x11_get_size_mm; /** * GstVaapiDisplayX11:x11-display: diff --git a/tests/test-display.c b/tests/test-display.c index 388abbfc09..f401de6297 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -94,7 +94,7 @@ main(int argc, char *argv[]) Display *x11_display; VADisplay va_display; GstVaapiDisplay *display; - guint width, height; + guint width, height, par_n, par_d; gst_init(&argc, &argv); @@ -109,6 +109,9 @@ main(int argc, char *argv[]) gst_vaapi_display_get_size(display, &width, &height); g_print("Display size: %ux%u\n", width, height); + gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d); + g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); + dump_caps(display); g_object_unref(display); } From 57c69b85eb3b16f834a558a6b53be496761a5c87 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 10:03:24 +0000 Subject: [PATCH 0116/3781] Size window so that to respect the video and pixel aspect ratio. --- sys/vaapisink/gstvaapisink.c | 64 ++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 70596121d5..65591ebc95 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -140,19 +140,71 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstStructure * const structure = gst_caps_get_structure(caps, 0); - gint width, height; + guint num, den; + guint win_width, win_height; + guint display_width, display_height, display_par_n, display_par_d; + gint video_width, video_height, video_par_n = 1, video_par_d = 1; + gdouble win_ratio; if (!structure) return FALSE; - if (!gst_structure_get_int(structure, "width", &width)) + if (!gst_structure_get_int(structure, "width", &video_width)) return FALSE; - if (!gst_structure_get_int(structure, "height", &height)) + if (!gst_structure_get_int(structure, "height", &video_height)) return FALSE; - if (sink->window) - gst_vaapi_window_set_size(sink->window, width, height); + gst_video_parse_caps_pixel_aspect_ratio(caps, &video_par_n, &video_par_d); + gst_vaapi_display_get_size(sink->display, &display_width, &display_height); + gst_vaapi_display_get_pixel_aspect_ratio( + sink->display, + &display_par_n, &display_par_d + ); + + if (!gst_video_calculate_display_ratio(&num, &den, + video_width, video_height, + video_par_n, video_par_d, + display_par_n, display_par_d)) + return FALSE; + GST_DEBUG("video size %dx%d, calculated display ratio %d/%d", + video_width, video_height, num, den); + + if ((video_height % den) == 0) { + GST_DEBUG("keeping video height"); + win_width = gst_util_uint64_scale_int(video_height, num, den); + win_height = video_height; + } + else if ((video_width % num) == 0) { + GST_DEBUG("keeping video width"); + win_width = video_width; + win_height = gst_util_uint64_scale_int(video_width, den, num); + } else { - sink->window = gst_vaapi_window_x11_new(sink->display, width, height); + GST_DEBUG("approximating while keeping video height"); + win_width = gst_util_uint64_scale_int (video_height, num, den); + win_height = video_height; + } + win_ratio = (gdouble)win_width / win_height; + GST_DEBUG("scaling to %ux%u", win_width, win_height); + + if (win_width > display_width || win_height > display_height) { + if (video_width > video_height) { + win_width = display_width; + win_height = display_width / win_ratio; + } + else { + win_width = display_height * win_ratio; + win_height = display_height; + } + } + GST_DEBUG("window size %ux%u", win_width, win_height); + + if (sink->window) + gst_vaapi_window_set_size(sink->window, win_width, win_height); + else { + sink->window = gst_vaapi_window_x11_new( + sink->display, + win_width, win_height + ); if (!sink->window) return FALSE; gst_vaapi_window_show(sink->window); From b8daf624c5476554a4296efd672f3fb212875e74 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 10:51:49 +0000 Subject: [PATCH 0117/3781] Add gst_vaapi_window_set_fullscreen() API. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapiwindow.c | 28 ++++- gst-libs/gst/vaapi/gstvaapiwindow.h | 5 + gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 154 ++++++++++++++++++++---- 4 files changed, 165 insertions(+), 23 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index f0832fa537..a6b14a3c2e 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -161,6 +161,7 @@ GstVaapiWindow GstVaapiWindowClass gst_vaapi_window_show gst_vaapi_window_hide +gst_vaapi_window_set_fullscreen gst_vaapi_window_get_width gst_vaapi_window_get_height gst_vaapi_window_get_size diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 0a1fa07bfa..58121ac33f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -37,9 +37,10 @@ G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, G_TYPE_OBJECT); GstVaapiWindowPrivate)) struct _GstVaapiWindowPrivate { - gboolean is_constructed; guint width; guint height; + gboolean is_constructed : 1; + guint is_fullscreen : 1; }; enum { @@ -179,9 +180,10 @@ gst_vaapi_window_init(GstVaapiWindow *window) GstVaapiWindowPrivate *priv = GST_VAAPI_WINDOW_GET_PRIVATE(window); window->priv = priv; - priv->is_constructed = FALSE; priv->width = 1; priv->height = 1; + priv->is_constructed = FALSE; + priv->is_fullscreen = FALSE; } /** @@ -216,6 +218,28 @@ gst_vaapi_window_hide(GstVaapiWindow *window) GST_VAAPI_WINDOW_GET_CLASS(window)->hide(window); } +/** + * gst_vaapi_window_set_fullscreen: + * @window: a #GstVaapiWindow + * @fullscreen: %TRUE to request window to get fullscreen + * + * Requests to place the @window in fullscreen or unfullscreen states. + */ +void +gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) +{ + GstVaapiWindowClass *klass; + + g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + + klass = GST_VAAPI_WINDOW_GET_CLASS(window); + + if (window->priv->is_fullscreen != fullscreen && klass->set_fullscreen) { + klass->set_fullscreen(window, fullscreen); + window->priv->is_fullscreen = fullscreen; + } +} + /** * gst_vaapi_window_get_width: * @window: a #GstVaapiWindow diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 9e3689bf4f..804b035abb 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -73,6 +73,7 @@ struct _GstVaapiWindow { * @destroy: virtual function to destroy a window * @show: virtual function to show (map) a window * @hide: virtual function to hide (unmap) a window + * @set_fullscreen: virtual function to change window fullscreen state * @resize: virtual function to resize a window * @render: virtual function to render a #GstVaapiSurface into a window * @@ -87,6 +88,7 @@ struct _GstVaapiWindowClass { void (*destroy)(GstVaapiWindow *window); gboolean (*show) (GstVaapiWindow *window); gboolean (*hide) (GstVaapiWindow *window); + gboolean (*set_fullscreen)(GstVaapiWindow *window, gboolean fullscreen); gboolean (*resize) (GstVaapiWindow *window, guint width, guint height); gboolean (*render) (GstVaapiWindow *window, GstVaapiSurface *surface, @@ -104,6 +106,9 @@ gst_vaapi_window_show(GstVaapiWindow *window); void gst_vaapi_window_hide(GstVaapiWindow *window); +void +gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen); + guint gst_vaapi_window_get_width(GstVaapiWindow *window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 69058703a3..c0b1f0c561 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -24,6 +24,8 @@ */ #include "config.h" +#include +#include #include "gstvaapiwindow_x11.h" #include "gstvaapidisplay_x11.h" #include "gstvaapiutils_x11.h" @@ -41,8 +43,11 @@ G_DEFINE_TYPE(GstVaapiWindowX11, gst_vaapi_window_x11, GST_VAAPI_TYPE_WINDOW); struct _GstVaapiWindowX11Private { GstVaapiDisplay *display; Window xid; - guint create_window : 1; - guint is_visible : 1; + Atom atom_NET_WM_STATE; + Atom atom_NET_WM_STATE_FULLSCREEN; + guint create_window : 1; + guint is_mapped : 1; + guint fullscreen_on_map : 1; }; enum { @@ -52,6 +57,45 @@ enum { PROP_XID, }; +#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ +#define _NET_WM_STATE_ADD 1 /* add/set property */ +#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ + +static gboolean +send_wmspec_change_state(GstVaapiWindowX11 *window, Atom state, gboolean add) +{ + GstVaapiWindowX11Private * const priv = window->priv; + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + gboolean has_errors; + XClientMessageEvent xclient; + + memset(&xclient, 0, sizeof(xclient)); + + xclient.type = ClientMessage; + xclient.window = priv->xid; + xclient.message_type = priv->atom_NET_WM_STATE; + xclient.format = 32; + + xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + xclient.data.l[1] = state; + xclient.data.l[2] = 0; + xclient.data.l[3] = 0; + xclient.data.l[4] = 0; + + GST_VAAPI_DISPLAY_LOCK(priv->display); + x11_trap_errors(); + XSendEvent( + dpy, + DefaultRootWindow(dpy), + False, + SubstructureRedirectMask|SubstructureNotifyMask, + (XEvent *)&xclient + ); + has_errors = x11_untrap_errors() != 0; + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + return !has_errors; +} + static gboolean gst_vaapi_window_x11_show(GstVaapiWindow *window) { @@ -59,7 +103,7 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); gboolean has_errors; - if (priv->is_visible) + if (priv->is_mapped) return TRUE; GST_VAAPI_DISPLAY_LOCK(priv->display); @@ -72,7 +116,7 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) if (has_errors) return FALSE; - priv->is_visible = TRUE; + priv->is_mapped = TRUE; return TRUE; } @@ -83,7 +127,7 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); gboolean has_errors; - if (!priv->is_visible) + if (!priv->is_mapped) return TRUE; GST_VAAPI_DISPLAY_LOCK(priv->display); @@ -96,7 +140,7 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) if (has_errors) return FALSE; - priv->is_visible = FALSE; + priv->is_mapped = FALSE; return TRUE; } @@ -105,8 +149,14 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + Atom atoms[2]; gboolean ok; + static const char *atom_names[2] = { + "_NET_WM_STATE", + "_NET_WM_STATE_FULLSCREEN", + }; + if (!priv->create_window && priv->xid) { GST_VAAPI_DISPLAY_LOCK(priv->display); ok = x11_get_geometry(dpy, priv->xid, NULL, NULL, width, height); @@ -115,6 +165,10 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) } GST_VAAPI_DISPLAY_LOCK(priv->display); + XInternAtoms(dpy, (char **)atom_names, G_N_ELEMENTS(atom_names), False, atoms); + priv->atom_NET_WM_STATE = atoms[0]; + priv->atom_NET_WM_STATE_FULLSCREEN = atoms[1]; + priv->xid = x11_create_window(dpy, *width, *height); if (priv->xid) XRaiseWindow(dpy, priv->xid); @@ -143,6 +197,62 @@ gst_vaapi_window_x11_destroy(GstVaapiWindow *window) } } +static gboolean +gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) +{ + GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + gboolean has_errors; + + if (fullscreen) { + if (!priv->is_mapped) { + priv->fullscreen_on_map = TRUE; + + GST_VAAPI_DISPLAY_LOCK(priv->display); + x11_trap_errors(); + XChangeProperty( + dpy, + priv->xid, + priv->atom_NET_WM_STATE, XA_ATOM, 32, + PropModeReplace, + (unsigned char *)&priv->atom_NET_WM_STATE_FULLSCREEN, 1 + ); + has_errors = x11_untrap_errors() != 0; + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + } + else { + has_errors = !send_wmspec_change_state( + GST_VAAPI_WINDOW_X11(window), + priv->atom_NET_WM_STATE_FULLSCREEN, + TRUE + ); + } + } + else { + if (!priv->is_mapped) { + priv->fullscreen_on_map = FALSE; + + GST_VAAPI_DISPLAY_LOCK(priv->display); + x11_trap_errors(); + XDeleteProperty( + dpy, + priv->xid, + priv->atom_NET_WM_STATE + ); + has_errors = x11_untrap_errors() != 0; + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + } + else { + has_errors = !send_wmspec_change_state( + GST_VAAPI_WINDOW_X11(window), + priv->atom_NET_WM_STATE_FULLSCREEN, + FALSE + ); + } + } + return !has_errors; +} + static gboolean gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height) { @@ -282,17 +392,18 @@ gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) g_type_class_add_private(klass, sizeof(GstVaapiWindowX11Private)); - object_class->finalize = gst_vaapi_window_x11_finalize; - object_class->set_property = gst_vaapi_window_x11_set_property; - object_class->get_property = gst_vaapi_window_x11_get_property; - object_class->constructed = gst_vaapi_window_x11_constructed; + object_class->finalize = gst_vaapi_window_x11_finalize; + object_class->set_property = gst_vaapi_window_x11_set_property; + object_class->get_property = gst_vaapi_window_x11_get_property; + object_class->constructed = gst_vaapi_window_x11_constructed; - window_class->create = gst_vaapi_window_x11_create; - window_class->destroy = gst_vaapi_window_x11_destroy; - window_class->show = gst_vaapi_window_x11_show; - window_class->hide = gst_vaapi_window_x11_hide; - window_class->resize = gst_vaapi_window_x11_resize; - window_class->render = gst_vaapi_window_x11_render; + window_class->create = gst_vaapi_window_x11_create; + window_class->destroy = gst_vaapi_window_x11_destroy; + window_class->show = gst_vaapi_window_x11_show; + window_class->hide = gst_vaapi_window_x11_hide; + window_class->set_fullscreen = gst_vaapi_window_x11_set_fullscreen; + window_class->resize = gst_vaapi_window_x11_resize; + window_class->render = gst_vaapi_window_x11_render; /** * GstVaapiWindowX11:display: @@ -328,11 +439,12 @@ gst_vaapi_window_x11_init(GstVaapiWindowX11 *window) { GstVaapiWindowX11Private *priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); - window->priv = priv; - priv->display = NULL; - priv->xid = None; - priv->create_window = TRUE; - priv->is_visible = FALSE; + window->priv = priv; + priv->display = NULL; + priv->xid = None; + priv->create_window = TRUE; + priv->is_mapped = FALSE; + priv->fullscreen_on_map = FALSE; } /** From f4b2aee89ef37712ebbbaab5111fed7705acc315 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 12:03:26 +0000 Subject: [PATCH 0118/3781] Allow `vaapisink` to render videos in fullscreen mode. --- NEWS | 1 + sys/vaapisink/gstvaapisink.c | 36 ++++++++++++++++++++++++++++++++++-- sys/vaapisink/gstvaapisink.h | 2 ++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index f17b1ca51e..c954d5821d 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ Copyright (C) 2010 Splitted-Desktop Systems Version 0.1.1 - DD.Mar.2010 * Document public API for libgstvaapi-*.so.* * Optimize `vaapiconvert' pipeline (direct-rendering) +* Allow `vaapisink` to render videos in fullscreen mode Version 0.1.0 - 16.Mar.2010 * Initial release diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 65591ebc95..8a6d1d677b 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -65,6 +65,7 @@ enum { PROP_DISPLAY, PROP_DISPLAY_NAME, + PROP_FULLSCREEN }; static GstVaapiDisplay * @@ -140,6 +141,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstStructure * const structure = gst_caps_get_structure(caps, 0); + GstVideoRectangle * const win_rect = &sink->window_rect; guint num, den; guint win_width, win_height; guint display_width, display_height, display_par_n, display_par_d; @@ -186,7 +188,8 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) win_ratio = (gdouble)win_width / win_height; GST_DEBUG("scaling to %ux%u", win_width, win_height); - if (win_width > display_width || win_height > display_height) { + if (sink->fullscreen || + win_width > display_width || win_height > display_height) { if (video_width > video_height) { win_width = display_width; win_height = display_width / win_ratio; @@ -198,6 +201,17 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) } GST_DEBUG("window size %ux%u", win_width, win_height); + if (sink->fullscreen) { + win_rect->x = (display_width - win_width) / 2; + win_rect->y = (display_height - win_height) / 2; + } + else { + win_rect->x = 0; + win_rect->y = 0; + } + win_rect->w = win_width; + win_rect->h = win_height; + if (sink->window) gst_vaapi_window_set_size(sink->window, win_width, win_height); else { @@ -207,6 +221,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) ); if (!sink->window) return FALSE; + gst_vaapi_window_set_fullscreen(sink->window, sink->fullscreen); gst_vaapi_window_show(sink->window); } return TRUE; @@ -228,7 +243,8 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) return GST_FLOW_UNEXPECTED; flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - if (!gst_vaapi_window_put_surface(sink->window, surface, NULL, NULL, flags)) + if (!gst_vaapi_window_put_surface(sink->window, surface, NULL, + &sink->window_rect, flags)) return GST_FLOW_UNEXPECTED; return GST_FLOW_OK; @@ -257,6 +273,9 @@ gst_vaapisink_set_property( g_free(sink->display_name); sink->display_name = g_strdup(g_value_get_string(value)); break; + case PROP_FULLSCREEN: + sink->fullscreen = g_value_get_boolean(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -280,6 +299,9 @@ gst_vaapisink_get_property( case PROP_DISPLAY_NAME: g_value_set_string(value, sink->display_name); break; + case PROP_FULLSCREEN: + g_value_set_boolean(value, sink->fullscreen); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -330,12 +352,22 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) "X11 display name", "", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_FULLSCREEN, + g_param_spec_boolean("fullscreen", + "Fullscreen", + "Requests window in fullscreen state", + FALSE, + G_PARAM_READWRITE)); } static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) { sink->display_name = NULL; sink->display = NULL; + sink->fullscreen = FALSE; } GstVaapiDisplay * diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h index bc04bfac40..8f271917b7 100644 --- a/sys/vaapisink/gstvaapisink.h +++ b/sys/vaapisink/gstvaapisink.h @@ -62,6 +62,8 @@ struct _GstVaapiSink { gchar *display_name; GstVaapiDisplay *display; GstVaapiWindow *window; + GstVideoRectangle window_rect; + guint fullscreen : 1; }; struct _GstVaapiSinkClass { From dba6645641a544551a52ff085080bf4efd9e0e16 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 12:05:11 +0000 Subject: [PATCH 0119/3781] 0.1.1. --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index c954d5821d..561344f4e1 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ -gst-vaapi NEWS -- summary of changes. 2010-03-DD +gst-vaapi NEWS -- summary of changes. 2010-03-22 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.1.1 - DD.Mar.2010 +Version 0.1.1 - 22.Mar.2010 * Document public API for libgstvaapi-*.so.* * Optimize `vaapiconvert' pipeline (direct-rendering) * Allow `vaapisink` to render videos in fullscreen mode From 873d5b7a0437d63e03f1a1e9df44e52bb5dc1cf2 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 12:16:47 +0000 Subject: [PATCH 0120/3781] Add GstVaapiPoint & GstVaapiRectangle data structures. --- docs/reference/libs/libs-docs.xml.in | 1 + docs/reference/libs/libs-sections.txt | 7 +++ gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapitypes.h | 60 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow.c | 26 +++++------ gst-libs/gst/vaapi/gstvaapiwindow.h | 9 ++-- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 12 ++--- sys/vaapisink/gstvaapisink.c | 14 +++--- sys/vaapisink/gstvaapisink.h | 2 +- 9 files changed, 101 insertions(+), 31 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapitypes.h diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index c9683aca47..48fccf22c7 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -11,6 +11,7 @@ GStreamer VA-API Plugins Library + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index a6b14a3c2e..852bd32f82 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -154,6 +154,13 @@ GST_VAAPI_IS_VIDEO_BUFFER_CLASS GST_VAAPI_VIDEO_BUFFER_GET_CLASS
+
+gstvaapitypes +Basic data structures +GstVaapiPoint +GstVaapiRectangle +
+
gstvaapiwindow GstVaapiWindow diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 25386c6fcd..e9e47de04c 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -29,6 +29,7 @@ libgstvaapi_source_h = \ gstvaapisubpicture.h \ gstvaapisurface.h \ gstvaapisurfacepool.h \ + gstvaapitypes.h \ gstvaapivideobuffer.h \ gstvaapivideopool.h \ gstvaapivideosink.h \ diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h new file mode 100644 index 0000000000..97dd598ec4 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -0,0 +1,60 @@ +/* + * gstvaapitypes.h - Misc types + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_TYPES_H +#define GST_VAAPI_TYPES_H + +#include + +G_BEGIN_DECLS + +/** + * GstVaapiPoint: + * @x: X coordinate + * @y: Y coordinate + * + * A location within a surface. + */ +typedef struct _GstVaapiPoint GstVaapiPoint; +struct _GstVaapiPoint { + guint32 x; + guint32 y; +}; + +/** + * GstVaapiRectangle: + * @x: X coordinate + * @y: Y coordinate + * @width: region width + * @height: region height + * + * A rectangle region within a surface. + */ +typedef struct _GstVaapiRectangle GstVaapiRectangle; +struct _GstVaapiRectangle { + guint32 x; + guint32 y; + guint32 width; + guint32 height; +}; + +G_END_DECLS + +#endif /* GST_VAAPI_TYPES_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 58121ac33f..2348540814 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -349,27 +349,27 @@ gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) } static inline void -get_surface_rect(GstVaapiSurface *surface, GstVideoRectangle *rect) +get_surface_rect(GstVaapiSurface *surface, GstVaapiRectangle *rect) { guint width, height; gst_vaapi_surface_get_size(surface, &width, &height); - rect->x = 0; - rect->y = 0; - rect->w = width; - rect->h = height; + rect->x = 0; + rect->y = 0; + rect->width = width; + rect->height = height; } static inline void -get_window_rect(GstVaapiWindow *window, GstVideoRectangle *rect) +get_window_rect(GstVaapiWindow *window, GstVaapiRectangle *rect) { guint width, height; gst_vaapi_window_get_size(window, &width, &height); - rect->x = 0; - rect->y = 0; - rect->w = width; - rect->h = height; + rect->x = 0; + rect->y = 0; + rect->width = width; + rect->height = height; } /** @@ -394,12 +394,12 @@ gboolean gst_vaapi_window_put_surface( GstVaapiWindow *window, GstVaapiSurface *surface, - const GstVideoRectangle *src_rect, - const GstVideoRectangle *dst_rect, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect, guint flags ) { - GstVideoRectangle src_rect_default, dst_rect_default; + GstVaapiRectangle src_rect_default, dst_rect_default; g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE); g_return_val_if_fail(window->priv->is_constructed, FALSE); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 804b035abb..d1db986b01 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -22,6 +22,7 @@ #define GST_VAAPI_WINDOW_H #include +#include #include #include @@ -92,8 +93,8 @@ struct _GstVaapiWindowClass { gboolean (*resize) (GstVaapiWindow *window, guint width, guint height); gboolean (*render) (GstVaapiWindow *window, GstVaapiSurface *surface, - const GstVideoRectangle *src_rect, - const GstVideoRectangle *dst_rect, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect, guint flags); }; @@ -131,8 +132,8 @@ gboolean gst_vaapi_window_put_surface( GstVaapiWindow *window, GstVaapiSurface *surface, - const GstVideoRectangle *src_rect, - const GstVideoRectangle *dst_rect, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect, guint flags ); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index c0b1f0c561..c7474e821f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -279,8 +279,8 @@ static gboolean gst_vaapi_window_x11_render( GstVaapiWindow *window, GstVaapiSurface *surface, - const GstVideoRectangle *src_rect, - const GstVideoRectangle *dst_rect, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect, guint flags ) { @@ -303,12 +303,12 @@ gst_vaapi_window_x11_render( GST_VAAPI_WINDOW_X11(window)->priv->xid, src_rect->x, src_rect->y, - src_rect->w, - src_rect->h, + src_rect->width, + src_rect->height, dst_rect->x, dst_rect->y, - dst_rect->w, - dst_rect->h, + dst_rect->width, + dst_rect->height, NULL, 0, get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(flags) ); diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 8a6d1d677b..a89dce8aa1 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -141,7 +141,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstStructure * const structure = gst_caps_get_structure(caps, 0); - GstVideoRectangle * const win_rect = &sink->window_rect; + GstVaapiRectangle * const win_rect = &sink->window_rect; guint num, den; guint win_width, win_height; guint display_width, display_height, display_par_n, display_par_d; @@ -202,15 +202,15 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) GST_DEBUG("window size %ux%u", win_width, win_height); if (sink->fullscreen) { - win_rect->x = (display_width - win_width) / 2; - win_rect->y = (display_height - win_height) / 2; + win_rect->x = (display_width - win_width) / 2; + win_rect->y = (display_height - win_height) / 2; } else { - win_rect->x = 0; - win_rect->y = 0; + win_rect->x = 0; + win_rect->y = 0; } - win_rect->w = win_width; - win_rect->h = win_height; + win_rect->width = win_width; + win_rect->height = win_height; if (sink->window) gst_vaapi_window_set_size(sink->window, win_width, win_height); diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h index 8f271917b7..d6ff8f3550 100644 --- a/sys/vaapisink/gstvaapisink.h +++ b/sys/vaapisink/gstvaapisink.h @@ -62,7 +62,7 @@ struct _GstVaapiSink { gchar *display_name; GstVaapiDisplay *display; GstVaapiWindow *window; - GstVideoRectangle window_rect; + GstVaapiRectangle window_rect; guint fullscreen : 1; }; From cc10345448e576ed0e1df281ea7e30f4d60192be Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 12:39:02 +0000 Subject: [PATCH 0121/3781] Add gst_vaapi_window_get_display() to base. --- gst-libs/gst/vaapi/gstvaapiwindow.c | 54 +++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiwindow.h | 3 ++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 25 ++---------- 3 files changed, 57 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 2348540814..d93f7afb8d 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -37,15 +37,17 @@ G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, G_TYPE_OBJECT); GstVaapiWindowPrivate)) struct _GstVaapiWindowPrivate { - guint width; - guint height; - gboolean is_constructed : 1; - guint is_fullscreen : 1; + GstVaapiDisplay *display; + guint width; + guint height; + gboolean is_constructed : 1; + guint is_fullscreen : 1; }; enum { PROP_0, + PROP_DISPLAY, PROP_WIDTH, PROP_HEIGHT }; @@ -53,7 +55,14 @@ enum { static void gst_vaapi_window_destroy(GstVaapiWindow *window) { + GstVaapiWindowPrivate * const priv = window->priv; + GST_VAAPI_WINDOW_GET_CLASS(window)->destroy(window); + + if (priv->display) { + g_object_unref(priv->display); + priv->display = NULL; + } } static gboolean @@ -95,6 +104,9 @@ gst_vaapi_window_set_property( GstVaapiWindow * const window = GST_VAAPI_WINDOW(object); switch (prop_id) { + case PROP_DISPLAY: + window->priv->display = g_object_ref(g_value_get_object(value)); + break; case PROP_WIDTH: gst_vaapi_window_set_width(window, g_value_get_uint(value)); break; @@ -118,6 +130,9 @@ gst_vaapi_window_get_property( GstVaapiWindow * const window = GST_VAAPI_WINDOW(object); switch (prop_id) { + case PROP_DISPLAY: + g_value_set_object(value, gst_vaapi_window_get_display(window)); + break; case PROP_WIDTH: g_value_set_uint(value, gst_vaapi_window_get_width(window)); break; @@ -155,6 +170,20 @@ gst_vaapi_window_class_init(GstVaapiWindowClass *klass) object_class->get_property = gst_vaapi_window_get_property; object_class->constructed = gst_vaapi_window_constructed; + /** + * GstVaapiWindowX11:display: + * + * The #GstVaapiDisplay this window is bound to + */ + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_object("display", + "Display", + "The GstVaapiDisplay this window is bound to", + GST_VAAPI_TYPE_DISPLAY, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_WIDTH, @@ -180,12 +209,29 @@ gst_vaapi_window_init(GstVaapiWindow *window) GstVaapiWindowPrivate *priv = GST_VAAPI_WINDOW_GET_PRIVATE(window); window->priv = priv; + priv->display = NULL; priv->width = 1; priv->height = 1; priv->is_constructed = FALSE; priv->is_fullscreen = FALSE; } +/** + * gst_vaapi_window_get_display: + * @window: a #GstVaapiWindow + * + * Returns the #GstVaapiDisplay this @window is bound to. + * + * Return value: the parent #GstVaapiDisplay object + */ +GstVaapiDisplay * +gst_vaapi_window_get_display(GstVaapiWindow *window) +{ + g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), NULL); + + return window->priv->display; +} + /** * gst_vaapi_window_show: * @window: a #GstVaapiWindow diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index d1db986b01..4c2bbcbe8f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -101,6 +101,9 @@ struct _GstVaapiWindowClass { GType gst_vaapi_window_get_type(void); +GstVaapiDisplay * +gst_vaapi_window_get_display(GstVaapiWindow *window); + void gst_vaapi_window_show(GstVaapiWindow *window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index c7474e821f..b58ad95a0f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -53,7 +53,6 @@ struct _GstVaapiWindowX11Private { enum { PROP_0, - PROP_DISPLAY, PROP_XID, }; @@ -336,9 +335,6 @@ gst_vaapi_window_x11_set_property( GstVaapiWindowX11 * const window = GST_VAAPI_WINDOW_X11(object); switch (prop_id) { - case PROP_DISPLAY: - window->priv->display = g_object_ref(g_value_get_object(value)); - break; case PROP_XID: window->priv->xid = g_value_get_uint(value); break; @@ -359,9 +355,6 @@ gst_vaapi_window_x11_get_property( GstVaapiWindowX11 * const window = GST_VAAPI_WINDOW_X11(object); switch (prop_id) { - case PROP_DISPLAY: - g_value_set_object(value, window->priv->display); - break; case PROP_XID: g_value_set_uint(value, gst_vaapi_window_x11_get_xid(window)); break; @@ -375,8 +368,12 @@ static void gst_vaapi_window_x11_constructed(GObject *object) { GstVaapiWindowX11 * const window = GST_VAAPI_WINDOW_X11(object); + GstVaapiDisplay *display; GObjectClass *parent_class; + window->priv->display = + g_object_ref(gst_vaapi_window_get_display(GST_VAAPI_WINDOW(window))); + window->priv->create_window = window->priv->xid == None; parent_class = G_OBJECT_CLASS(gst_vaapi_window_x11_parent_class); @@ -405,20 +402,6 @@ gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) window_class->resize = gst_vaapi_window_x11_resize; window_class->render = gst_vaapi_window_x11_render; - /** - * GstVaapiWindowX11:display: - * - * The #GstVaapiDisplay this window is bound to - */ - g_object_class_install_property - (object_class, - PROP_DISPLAY, - g_param_spec_object("display", - "Display", - "The GstVaapiDisplay this window is bound to", - GST_VAAPI_TYPE_DISPLAY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - /** * GstVaapiWindowX11:xid: * From 8e773e6d107ddf3e0cad7cdedae33cd6d15259ad Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 12:47:13 +0000 Subject: [PATCH 0122/3781] Add gst_vaapi_window_get_fullscreen() helper and "fullscreen" property. --- docs/reference/libs/libs-sections.txt | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow.c | 34 ++++++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiwindow.h | 3 +++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 852bd32f82..f12019b0c1 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -166,8 +166,10 @@ GstVaapiRectangle GstVaapiWindow GstVaapiWindow GstVaapiWindowClass +gst_vaapi_window_get_display gst_vaapi_window_show gst_vaapi_window_hide +gst_vaapi_window_get_fullscreen gst_vaapi_window_set_fullscreen gst_vaapi_window_get_width gst_vaapi_window_get_height diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index d93f7afb8d..9f2d2abf62 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -49,7 +49,8 @@ enum { PROP_DISPLAY, PROP_WIDTH, - PROP_HEIGHT + PROP_HEIGHT, + PROP_FULLSCREEN }; static void @@ -113,6 +114,9 @@ gst_vaapi_window_set_property( case PROP_HEIGHT: gst_vaapi_window_set_height(window, g_value_get_uint(value)); break; + case PROP_FULLSCREEN: + gst_vaapi_window_set_fullscreen(window, g_value_get_boolean(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -139,6 +143,9 @@ gst_vaapi_window_get_property( case PROP_HEIGHT: g_value_set_uint(value, gst_vaapi_window_get_height(window)); break; + case PROP_FULLSCREEN: + g_value_set_boolean(value, window->priv->is_fullscreen); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -201,6 +208,15 @@ gst_vaapi_window_class_init(GstVaapiWindowClass *klass) "The window height", 1, G_MAXUINT32, 1, G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, + PROP_FULLSCREEN, + g_param_spec_boolean("fullscreen", + "Fullscreen", + "The fullscreen state of the window", + FALSE, + G_PARAM_READWRITE)); } static void @@ -264,6 +280,22 @@ gst_vaapi_window_hide(GstVaapiWindow *window) GST_VAAPI_WINDOW_GET_CLASS(window)->hide(window); } +/** + * gst_vaapi_window_get_fullscreen: + * @window: a #GstVaapiWindow + * + * Retrieves whether the @window is fullscreen or not + * + * Return value: %TRUE if the window is fullscreen + */ +gboolean +gst_vaapi_window_get_fullscreen(GstVaapiWindow *window) +{ + g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE); + + return window->priv->is_fullscreen; +} + /** * gst_vaapi_window_set_fullscreen: * @window: a #GstVaapiWindow diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 4c2bbcbe8f..2eb1f0ee83 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -110,6 +110,9 @@ gst_vaapi_window_show(GstVaapiWindow *window); void gst_vaapi_window_hide(GstVaapiWindow *window); +gboolean +gst_vaapi_window_get_fullscreen(GstVaapiWindow *window); + void gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen); From 6407e5339a0c55f0833a8921e5a3f91fa347e6bf Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 13:05:05 +0000 Subject: [PATCH 0123/3781] Add private API to set window size & fullscreen modes without triggering any notification or virtual functions. This is useful for derived class to fix up sizes whenever appropriate. --- gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapiwindow.c | 25 ++++++++++++---- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 38 ++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index e9e47de04c..a8c927eda4 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -39,6 +39,7 @@ libgstvaapi_source_h = \ libgstvaapi_source_priv_h = \ gstvaapidebug.h \ gstvaapiutils.h \ + gstvaapiwindow_priv.h \ $(NULL) libgstvaapi_x11_source_c = \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 9f2d2abf62..049f2855c1 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -25,6 +25,7 @@ #include "config.h" #include "gstvaapiwindow.h" +#include "gstvaapiwindow_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -303,6 +304,12 @@ gst_vaapi_window_get_fullscreen(GstVaapiWindow *window) * * Requests to place the @window in fullscreen or unfullscreen states. */ +void +_gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) +{ + window->priv->is_fullscreen = fullscreen; +} + void gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) { @@ -313,8 +320,8 @@ gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) klass = GST_VAAPI_WINDOW_GET_CLASS(window); if (window->priv->is_fullscreen != fullscreen && klass->set_fullscreen) { + _gst_vaapi_window_set_fullscreen(window, fullscreen); klass->set_fullscreen(window, fullscreen); - window->priv->is_fullscreen = fullscreen; } } @@ -411,17 +418,25 @@ gst_vaapi_window_set_height(GstVaapiWindow *window, guint height) * * Resizes the @window to match the specified @width and @height. */ +gboolean +_gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) +{ + if (width == window->priv->width && height == window->priv->height) + return FALSE; + + window->priv->width = width; + window->priv->height = height; + return TRUE; +} + void gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) { g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); - if (width == window->priv->width && height == window->priv->height) + if (!_gst_vaapi_window_set_size(window, width, height)) return; - window->priv->width = width; - window->priv->height = height; - if (window->priv->is_constructed) GST_VAAPI_WINDOW_GET_CLASS(window)->resize(window, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h new file mode 100644 index 0000000000..4c26027150 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -0,0 +1,38 @@ +/* + * gstvaapiwindow_priv.h - VA window abstraction (private API) + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_WINDOW_PRIVATE_H +#define GST_VAAPI_WINDOW_PRIVATE_H + +#include "config.h" + +G_BEGIN_DECLS + +void +_gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) + attribute_hidden; + +gboolean +_gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) + attribute_hidden; + +G_END_DECLS + +#endif /* GST_VAAPI_WINDOW_H */ From 729f4fc9c631564d649fffb229560b991cee4ac8 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 13:06:41 +0000 Subject: [PATCH 0124/3781] Move _GstVaapiWindowPrivate declaration to gstvaapiwindow_priv.h. --- gst-libs/gst/vaapi/gstvaapiwindow.c | 13 ------------- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 13 +++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 049f2855c1..e18b92b521 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -32,19 +32,6 @@ G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, G_TYPE_OBJECT); -#define GST_VAAPI_WINDOW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_WINDOW, \ - GstVaapiWindowPrivate)) - -struct _GstVaapiWindowPrivate { - GstVaapiDisplay *display; - guint width; - guint height; - gboolean is_constructed : 1; - guint is_fullscreen : 1; -}; - enum { PROP_0, diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index 4c26027150..621817c91c 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -25,6 +25,19 @@ G_BEGIN_DECLS +#define GST_VAAPI_WINDOW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_WINDOW, \ + GstVaapiWindowPrivate)) + +struct _GstVaapiWindowPrivate { + GstVaapiDisplay *display; + guint width; + guint height; + gboolean is_constructed : 1; + guint is_fullscreen : 1; +}; + void _gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) attribute_hidden; From 1c647d1f69a55cf6eb735decebe1084510c18955 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 16:01:34 +0000 Subject: [PATCH 0125/3781] Improve display locking and rework X event wait functions. --- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 7 --- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 3 - gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 84 +++++++++++++++++++------ 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 1cfb66bd00..cb9bfc8ede 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -130,10 +130,3 @@ x11_get_geometry( if (pheight) *pheight = height; return TRUE; } - -void x11_wait_event(Display *dpy, Window w, int type) -{ - XEvent e; - while (!XCheckTypedWindowEvent(dpy, w, type, &e)) - g_usleep(10); -} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index 402f00817f..b66e5c165e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -45,7 +45,4 @@ x11_get_geometry( guint *pheight ) attribute_hidden; -void x11_wait_event(Display *dpy, Window w, int type) - attribute_hidden; - #endif /* GST_VAAPI_UTILS_X11_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index b58ad95a0f..7998949716 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -60,12 +60,11 @@ enum { #define _NET_WM_STATE_ADD 1 /* add/set property */ #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ -static gboolean +static void send_wmspec_change_state(GstVaapiWindowX11 *window, Atom state, gboolean add) { GstVaapiWindowX11Private * const priv = window->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - gboolean has_errors; XClientMessageEvent xclient; memset(&xclient, 0, sizeof(xclient)); @@ -81,8 +80,6 @@ send_wmspec_change_state(GstVaapiWindowX11 *window, Atom state, gboolean add) xclient.data.l[3] = 0; xclient.data.l[4] = 0; - GST_VAAPI_DISPLAY_LOCK(priv->display); - x11_trap_errors(); XSendEvent( dpy, DefaultRootWindow(dpy), @@ -90,9 +87,58 @@ send_wmspec_change_state(GstVaapiWindowX11 *window, Atom state, gboolean add) SubstructureRedirectMask|SubstructureNotifyMask, (XEvent *)&xclient ); - has_errors = x11_untrap_errors() != 0; +} + +static void +wait_event(GstVaapiWindow *window, int type) +{ + GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + XEvent e; + Bool got_event; + + for (;;) { + GST_VAAPI_DISPLAY_LOCK(priv->display); + got_event = XCheckTypedWindowEvent(dpy, priv->xid, type, &e); + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + if (got_event) + break; + g_usleep(10); + } +} + +static gboolean +timed_wait_event(GstVaapiWindow *window, int type, guint64 end_time, XEvent *e) +{ + GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + XEvent tmp_event; + GTimeVal now; + guint64 now_time; + Bool got_event; + + if (!e) + e = &tmp_event; + + GST_VAAPI_DISPLAY_LOCK(priv->display); + got_event = XCheckTypedWindowEvent(dpy, priv->xid, type, e); GST_VAAPI_DISPLAY_UNLOCK(priv->display); - return !has_errors; + if (got_event) + return TRUE; + + do { + g_usleep(10); + GST_VAAPI_DISPLAY_LOCK(priv->display); + got_event = XCheckTypedWindowEvent(dpy, priv->xid, type, e); + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + if (got_event) { + g_print("HERE\n"); + return TRUE; + } + g_get_current_time(&now); + now_time = (guint64)now.tv_sec * 1000000 + now.tv_usec; + } while (now_time < end_time); + return FALSE; } static gboolean @@ -108,13 +154,14 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); XMapWindow(dpy, priv->xid); - if (priv->create_window) - x11_wait_event(dpy, priv->xid, MapNotify); has_errors = x11_untrap_errors() != 0; GST_VAAPI_DISPLAY_UNLOCK(priv->display); if (has_errors) return FALSE; + if (priv->create_window) + wait_event(window, MapNotify); + priv->is_mapped = TRUE; return TRUE; } @@ -132,13 +179,14 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); XUnmapWindow(dpy, priv->xid); - if (priv->create_window) - x11_wait_event(dpy, priv->xid, UnmapNotify); has_errors = x11_untrap_errors() != 0; GST_VAAPI_DISPLAY_UNLOCK(priv->display); if (has_errors) return FALSE; + if (priv->create_window) + wait_event(window, UnmapNotify); + priv->is_mapped = FALSE; return TRUE; } @@ -203,12 +251,12 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); gboolean has_errors; + GST_VAAPI_DISPLAY_LOCK(priv->display); + x11_trap_errors(); if (fullscreen) { if (!priv->is_mapped) { priv->fullscreen_on_map = TRUE; - GST_VAAPI_DISPLAY_LOCK(priv->display); - x11_trap_errors(); XChangeProperty( dpy, priv->xid, @@ -216,11 +264,9 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) PropModeReplace, (unsigned char *)&priv->atom_NET_WM_STATE_FULLSCREEN, 1 ); - has_errors = x11_untrap_errors() != 0; - GST_VAAPI_DISPLAY_UNLOCK(priv->display); } else { - has_errors = !send_wmspec_change_state( + send_wmspec_change_state( GST_VAAPI_WINDOW_X11(window), priv->atom_NET_WM_STATE_FULLSCREEN, TRUE @@ -231,24 +277,22 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) if (!priv->is_mapped) { priv->fullscreen_on_map = FALSE; - GST_VAAPI_DISPLAY_LOCK(priv->display); - x11_trap_errors(); XDeleteProperty( dpy, priv->xid, priv->atom_NET_WM_STATE ); - has_errors = x11_untrap_errors() != 0; - GST_VAAPI_DISPLAY_UNLOCK(priv->display); } else { - has_errors = !send_wmspec_change_state( + send_wmspec_change_state( GST_VAAPI_WINDOW_X11(window), priv->atom_NET_WM_STATE_FULLSCREEN, FALSE ); } } + has_errors = x11_untrap_errors() != 0; + GST_VAAPI_DISPLAY_UNLOCK(priv->display); return !has_errors; } From 3136cdc991028d7bb023e09606c7c5c021125dac Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 16:57:20 +0000 Subject: [PATCH 0126/3781] Try to improve switch to fullscreen mode. --- gst-libs/gst/vaapi/Makefile.am | 1 - gst-libs/gst/vaapi/gstvaapiwindow.c | 71 +++++++++++++++++------- gst-libs/gst/vaapi/gstvaapiwindow.h | 3 + gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 51 ----------------- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 51 +++++++++++++++-- 5 files changed, 100 insertions(+), 77 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index a8c927eda4..e9e47de04c 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -39,7 +39,6 @@ libgstvaapi_source_h = \ libgstvaapi_source_priv_h = \ gstvaapidebug.h \ gstvaapiutils.h \ - gstvaapiwindow_priv.h \ $(NULL) libgstvaapi_x11_source_c = \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index e18b92b521..84e08c1473 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -25,13 +25,26 @@ #include "config.h" #include "gstvaapiwindow.h" -#include "gstvaapiwindow_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, G_TYPE_OBJECT); +#define GST_VAAPI_WINDOW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_WINDOW, \ + GstVaapiWindowPrivate)) + +struct _GstVaapiWindowPrivate { + GstVaapiDisplay *display; + guint width; + guint height; + gboolean is_constructed : 1; + guint is_fullscreen : 1; + guint is_fullscreen_changed : 1; +}; + enum { PROP_0, @@ -41,6 +54,25 @@ enum { PROP_FULLSCREEN }; +static void +gst_vaapi_window_ensure_size(GstVaapiWindow *window) +{ + GstVaapiWindowPrivate * const priv = window->priv; + GstVaapiWindowClass * const klass = GST_VAAPI_WINDOW_GET_CLASS(window); + guint display_width, display_height; + + if (!priv->is_fullscreen_changed) + return; + + if (klass->get_geometry) + klass->get_geometry(window, NULL, NULL, &priv->width, &priv->height); + + gst_vaapi_display_get_size(priv->display, &display_width, &display_height); + priv->is_fullscreen_changed = FALSE; + priv->is_fullscreen = (priv->width == display_width && + priv->height == display_height); +} + static void gst_vaapi_window_destroy(GstVaapiWindow *window) { @@ -218,6 +250,7 @@ gst_vaapi_window_init(GstVaapiWindow *window) priv->height = 1; priv->is_constructed = FALSE; priv->is_fullscreen = FALSE; + priv->is_fullscreen_changed = FALSE; } /** @@ -281,6 +314,8 @@ gst_vaapi_window_get_fullscreen(GstVaapiWindow *window) { g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE); + gst_vaapi_window_ensure_size(window); + return window->priv->is_fullscreen; } @@ -291,12 +326,6 @@ gst_vaapi_window_get_fullscreen(GstVaapiWindow *window) * * Requests to place the @window in fullscreen or unfullscreen states. */ -void -_gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) -{ - window->priv->is_fullscreen = fullscreen; -} - void gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) { @@ -307,8 +336,10 @@ gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) klass = GST_VAAPI_WINDOW_GET_CLASS(window); if (window->priv->is_fullscreen != fullscreen && klass->set_fullscreen) { - _gst_vaapi_window_set_fullscreen(window, fullscreen); - klass->set_fullscreen(window, fullscreen); + if (klass->set_fullscreen(window, fullscreen)) { + window->priv->is_fullscreen = fullscreen; + window->priv->is_fullscreen_changed = TRUE; + } } } @@ -326,6 +357,8 @@ gst_vaapi_window_get_width(GstVaapiWindow *window) g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0); g_return_val_if_fail(window->priv->is_constructed, 0); + gst_vaapi_window_ensure_size(window); + return window->priv->width; } @@ -343,6 +376,8 @@ gst_vaapi_window_get_height(GstVaapiWindow *window) g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0); g_return_val_if_fail(window->priv->is_constructed, 0); + gst_vaapi_window_ensure_size(window); + return window->priv->height; } @@ -360,6 +395,8 @@ gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight) g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); g_return_if_fail(window->priv->is_constructed); + gst_vaapi_window_ensure_size(window); + if (pwidth) *pwidth = window->priv->width; @@ -405,25 +442,17 @@ gst_vaapi_window_set_height(GstVaapiWindow *window, guint height) * * Resizes the @window to match the specified @width and @height. */ -gboolean -_gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) -{ - if (width == window->priv->width && height == window->priv->height) - return FALSE; - - window->priv->width = width; - window->priv->height = height; - return TRUE; -} - void gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) { g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); - if (!_gst_vaapi_window_set_size(window, width, height)) + if (width == window->priv->width && height == window->priv->height) return; + window->priv->width = width; + window->priv->height = height; + if (window->priv->is_constructed) GST_VAAPI_WINDOW_GET_CLASS(window)->resize(window, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 2eb1f0ee83..a7650d89ea 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -89,6 +89,9 @@ struct _GstVaapiWindowClass { void (*destroy)(GstVaapiWindow *window); gboolean (*show) (GstVaapiWindow *window); gboolean (*hide) (GstVaapiWindow *window); + gboolean (*get_geometry) (GstVaapiWindow *window, + gint *px, gint *py, + guint *pwidth, guint *pheight); gboolean (*set_fullscreen)(GstVaapiWindow *window, gboolean fullscreen); gboolean (*resize) (GstVaapiWindow *window, guint width, guint height); gboolean (*render) (GstVaapiWindow *window, diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h deleted file mode 100644 index 621817c91c..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * gstvaapiwindow_priv.h - VA window abstraction (private API) - * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef GST_VAAPI_WINDOW_PRIVATE_H -#define GST_VAAPI_WINDOW_PRIVATE_H - -#include "config.h" - -G_BEGIN_DECLS - -#define GST_VAAPI_WINDOW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_WINDOW, \ - GstVaapiWindowPrivate)) - -struct _GstVaapiWindowPrivate { - GstVaapiDisplay *display; - guint width; - guint height; - gboolean is_constructed : 1; - guint is_fullscreen : 1; -}; - -void -_gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) - attribute_hidden; - -gboolean -_gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) - attribute_hidden; - -G_END_DECLS - -#endif /* GST_VAAPI_WINDOW_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 7998949716..f71ecf89f9 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -131,10 +131,8 @@ timed_wait_event(GstVaapiWindow *window, int type, guint64 end_time, XEvent *e) GST_VAAPI_DISPLAY_LOCK(priv->display); got_event = XCheckTypedWindowEvent(dpy, priv->xid, type, e); GST_VAAPI_DISPLAY_UNLOCK(priv->display); - if (got_event) { - g_print("HERE\n"); + if (got_event) return TRUE; - } g_get_current_time(&now); now_time = (guint64)now.tv_sec * 1000000 + now.tv_usec; } while (now_time < end_time); @@ -163,6 +161,10 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) wait_event(window, MapNotify); priv->is_mapped = TRUE; + + if (priv->fullscreen_on_map) + gst_vaapi_window_set_fullscreen(window, TRUE); + return TRUE; } @@ -244,12 +246,30 @@ gst_vaapi_window_x11_destroy(GstVaapiWindow *window) } } +static gboolean +gst_vaapi_window_x11_get_geometry( + GstVaapiWindow *window, + gint *px, + gint *py, + guint *pwidth, + guint *pheight) +{ + GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + + return x11_get_geometry(dpy, priv->xid, px, py, pwidth, pheight); +} + static gboolean gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + XEvent e; + guint width, height; gboolean has_errors; + GTimeVal now; + guint64 end_time; GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); @@ -291,9 +311,31 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) ); } } + XSync(dpy, False); has_errors = x11_untrap_errors() != 0; GST_VAAPI_DISPLAY_UNLOCK(priv->display); - return !has_errors; + if (has_errors) + return FALSE; + + /* Try to wait for the completion of the fullscreen mode switch */ + if (priv->create_window && priv->is_mapped) { + const guint DELAY = 100000; /* 100 ms */ + g_get_current_time(&now); + end_time = DELAY + ((guint64)now.tv_sec * 1000000 + now.tv_usec); + while (timed_wait_event(window, ConfigureNotify, end_time, &e)) { + if (fullscreen) { + gst_vaapi_display_get_size(priv->display, &width, &height); + if (e.xconfigure.width == width && e.xconfigure.height == height) + return TRUE; + } + else { + gst_vaapi_window_get_size(window, &width, &height); + if (e.xconfigure.width != width || e.xconfigure.height != height) + return TRUE; + } + } + } + return FALSE; } static gboolean @@ -442,6 +484,7 @@ gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) window_class->destroy = gst_vaapi_window_x11_destroy; window_class->show = gst_vaapi_window_x11_show; window_class->hide = gst_vaapi_window_x11_hide; + window_class->get_geometry = gst_vaapi_window_x11_get_geometry; window_class->set_fullscreen = gst_vaapi_window_x11_set_fullscreen; window_class->resize = gst_vaapi_window_x11_resize; window_class->render = gst_vaapi_window_x11_render; From df9e25d4733a4489c9a7723a98f03f3cd0da66ad Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 22 Mar 2010 16:59:29 +0000 Subject: [PATCH 0127/3781] Shorten condition. --- gst-libs/gst/vaapi/gstvaapiwindow.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 84e08c1473..864588a203 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -335,11 +335,10 @@ gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) klass = GST_VAAPI_WINDOW_GET_CLASS(window); - if (window->priv->is_fullscreen != fullscreen && klass->set_fullscreen) { - if (klass->set_fullscreen(window, fullscreen)) { - window->priv->is_fullscreen = fullscreen; - window->priv->is_fullscreen_changed = TRUE; - } + if (window->priv->is_fullscreen != fullscreen && + klass->set_fullscreen && klass->set_fullscreen(window, fullscreen)) { + window->priv->is_fullscreen = fullscreen; + window->priv->is_fullscreen_changed = TRUE; } } From a1b25e880782761bd651ae9154f03d3e5a0b69a8 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 06:40:27 +0000 Subject: [PATCH 0128/3781] Add GST_VAAPI_WINDOW_XWINDOW() helper macro. --- docs/reference/libs/libs-sections.txt | 3 ++- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index f12019b0c1..9178ba7c97 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -48,10 +48,10 @@ gst_vaapi_video_sink_get_type
gstvaapidisplay_x11 -GST_VAAPI_DISPLAY_XDISPLAY GstVaapiDisplayX11 GstVaapiDisplayX11 GstVaapiDisplayX11Class +GST_VAAPI_DISPLAY_XDISPLAY gst_vaapi_display_x11_new gst_vaapi_display_x11_new_with_display gst_vaapi_display_x11_get_display @@ -70,6 +70,7 @@ GST_VAAPI_DISPLAY_X11_GET_CLASS GstVaapiWindowX11 GstVaapiWindowX11 GstVaapiWindowX11Class +GST_VAAPI_WINDOW_XWINDOW gst_vaapi_window_x11_new gst_vaapi_window_x11_new_with_xid gst_vaapi_window_x11_get_xid diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index d46b996291..59fe14088d 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -51,6 +51,15 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_WINDOW_X11, \ GstVaapiWindowX11Class)) +/** + * GST_VAAPI_WINDOW_XWINDOW: + * @window: a #GstVaapiWindow + * + * Macro that evaluates to the underlying X11 #Window of @window + */ +#define GST_VAAPI_WINDOW_XWINDOW(window) \ + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(window)) + typedef struct _GstVaapiWindowX11 GstVaapiWindowX11; typedef struct _GstVaapiWindowX11Private GstVaapiWindowX11Private; typedef struct _GstVaapiWindowX11Class GstVaapiWindowX11Class; From e4a4fd9742fa2e6696f3e0e2228e5c38bb89ed30 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 06:41:29 +0000 Subject: [PATCH 0129/3781] Fix warnings (drop extraneous var). --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index f71ecf89f9..6273ed0212 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -454,7 +454,6 @@ static void gst_vaapi_window_x11_constructed(GObject *object) { GstVaapiWindowX11 * const window = GST_VAAPI_WINDOW_X11(object); - GstVaapiDisplay *display; GObjectClass *parent_class; window->priv->display = From 2023da5a8df5f1b8f7977e12a096db3035177eab Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 07:31:04 +0000 Subject: [PATCH 0130/3781] Add -doc package. --- configure.ac | 11 ++++++++++- debian/Makefile.am | 3 +++ debian/control.in | 9 +++++++++ debian/gstreamer-vaapi-doc.install.in | 1 + debian/rules | 14 ++++++++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 debian/gstreamer-vaapi-doc.install.in diff --git a/configure.ac b/configure.ac index 64b2871696..786ef7b3b5 100644 --- a/configure.ac +++ b/configure.ac @@ -33,6 +33,11 @@ m4_define([libva_glx_sds_package_version_0_31], [0.31.0-1+sds1]) m4_define([libva_sds_version], [libva_glx_sds_version_0_31]) m4_define([libva_sds_package_version], [libva_glx_sds_package_version_0_31]) +# gtk-doc version number +m4_define([gtkdoc_major_version], [1]) +m4_define([gtkdoc_minor_version], [9]) +m4_define([gtkdoc_version], [gtkdoc_major_version.gtkdoc_minor_version]) + AC_PREREQ([2.57]) AC_INIT([gst_vaapi], [gst_vaapi_version], [gbeauchesne@splitted-desktop.com], @@ -91,8 +96,10 @@ AM_PROG_CC_C_O AC_PROG_LIBTOOL dnl Check for Gtk doc -GTK_DOC_CHECK([1.9]) +GTKDOC_VERSION=gtkdoc_version +GTK_DOC_CHECK([$GTKDOC_VERSION]) AM_CONDITIONAL([BUILD_GTK_DOC], [test "x$enable_gtk_doc" = "xyes"]) +AC_SUBST(GTKDOC_VERSION) dnl Check for GLib PKG_CHECK_MODULES([GLIB], [glib-2.0]) @@ -186,6 +193,8 @@ AC_OUTPUT([ debian/control debian/gstreamer$GST_MAJORMINOR-vaapi.install:\ debian/gstreamer-vaapi.install.in + debian/gstreamer$GST_MAJORMINOR-vaapi-doc.install:\ +debian/gstreamer-vaapi-doc.install.in debian/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:\ debian/libgstvaapi.install.in debian/libgstvaapi$GST_VAAPI_MAJOR_VERSION-dev.install:\ diff --git a/debian/Makefile.am b/debian/Makefile.am index d015ab6372..93b9514d5d 100644 --- a/debian/Makefile.am +++ b/debian/Makefile.am @@ -14,6 +14,8 @@ DEBIANFILES = \ copyright \ gstreamer-vaapi.install.in \ gstreamer$(GST_MAJORMINOR)-vaapi.install \ + gstreamer-vaapi-doc.install.in \ + gstreamer$(GST_MAJORMINOR)-vaapi-doc.install \ libgstvaapi.install.in \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-dev.install.in \ @@ -27,6 +29,7 @@ DEBIANGENFILES = \ control \ changelog \ gstreamer$(GST_MAJORMINOR)-vaapi.install \ + gstreamer$(GST_MAJORMINOR)-vaapi-doc.install \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION)-dev.install \ libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ diff --git a/debian/control.in b/debian/control.in index f547769f94..ca4bd120eb 100644 --- a/debian/control.in +++ b/debian/control.in @@ -8,17 +8,26 @@ Build-Depends: debhelper (>= 5), libgstreamer@GST_MAJORMINOR@-dev (>= @GST_VERSION_REQUIRED@), libgstreamer-plugins-base@GST_MAJORMINOR@-dev (>= @GST_PLUGINS_BASE_VERSION_REQUIRED@), libva-dev (>= @LIBVA_SDS_PACKAGE_VERSION@) +Build-Depends-Indep: gtk-doc-tools (>= @GTKDOC_VERSION@) Standards-Version: 3.7.2 Package: gstreamer@GST_MAJORMINOR@-vaapi Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} +Suggests: gstreamer@GST_MAJORMINOR@-vaapi-doc Description: VA-API plugins for GStreamer This package contains GStreamer plugins for VA-API support: - `vaapiconvert': converts from YUV pixels to VA surfaces - `vaapisink': a VA-API based video sink +Package: gstreamer@GST_MAJORMINOR@-vaapi-doc +Architecture: all +Section: doc +Recommends: libgstvaapi@GST_VAAPI_MAJOR_VERSION@-dev (= ${source:Version}) +Description: GStreamer VA-API documentation and manuals + This packages contains documentation for libraries and elements. + Package: gstreamer@GST_MAJORMINOR@-vaapi-dbg Section: libdevel Architecture: any diff --git a/debian/gstreamer-vaapi-doc.install.in b/debian/gstreamer-vaapi-doc.install.in new file mode 100644 index 0000000000..ff84ca1736 --- /dev/null +++ b/debian/gstreamer-vaapi-doc.install.in @@ -0,0 +1 @@ +debian/tmp/usr/share/doc/gstreamer@GST_MAJORMINOR@-vaapi diff --git a/debian/rules b/debian/rules index 76c4183651..0ec96be6ec 100755 --- a/debian/rules +++ b/debian/rules @@ -5,6 +5,8 @@ include /usr/share/cdbs/1/class/autotools.mk include /usr/share/cdbs/1/rules/simple-patchsys.mk include /usr/share/cdbs/1/rules/utils.mk +gst_pkgname = $(shell dpkg-parsechangelog | grep ^Source: | cut -d' ' -f2) + # Allow SMP build ifeq ($(DEBIAN_BUILD_NCPUS),) DEBIAN_BUILD_NCPUS = $(shell /usr/bin/getconf _NPROCESSORS_ONLN) @@ -13,3 +15,15 @@ ifneq ($(DEBIAN_BUILD_NCPUS),) EXTRA_MAKE_FLAGS += -j$(DEBIAN_BUILD_NCPUS) endif MAKE += $(EXTRA_MAKE_FLAGS) + +# Allow HTML documentation build +indep_conf_flags = \ + --with-html-dir=\$${prefix}/share/doc/$(gst_pkgname) + +# only build the docs if gtk-doc-tools is installed, i.e. binary-indep is +# called +ifeq ($(shell test "`dpkg -l gtk-doc-tools | grep ^ii`" && echo binary-indep),binary-indep) +indep_conf_flags += --enable-gtk-doc +endif + +DEB_CONFIGURE_EXTRA_FLAGS += $(indep_conf_flags) From 8bc05b84d0e6465ba36fb71b20cbd9e07227e87f Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 07:34:15 +0000 Subject: [PATCH 0131/3781] Add missing includes. --- sys/vaapisink/gstvaapisink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index a89dce8aa1..f67eed24be 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -20,6 +20,7 @@ #include "config.h" #include +#include #include #include #include From 0bf40c2d44b3dab2961386f892f7d24aa2f50614 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 07:42:05 +0000 Subject: [PATCH 0132/3781] Check whether the foreign XID is mapped at binding time. --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 6273ed0212..18450df43a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -198,6 +198,7 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + XWindowAttributes wattr; Atom atoms[2]; gboolean ok; @@ -208,6 +209,8 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) if (!priv->create_window && priv->xid) { GST_VAAPI_DISPLAY_LOCK(priv->display); + XGetWindowAttributes(dpy, priv->xid, &wattr); + priv->is_mapped = wattr.map_state == IsViewable; ok = x11_get_geometry(dpy, priv->xid, NULL, NULL, width, height); GST_VAAPI_DISPLAY_UNLOCK(priv->display); return ok; From 55c5b220cd9d2162351e4e54f341bb2b04919455 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 08:13:37 +0000 Subject: [PATCH 0133/3781] Wait for MapNotify or UnmapNotify events on foreign windows too. --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 53 ++++++++++++++++++------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 18450df43a..46551cb501 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -144,6 +144,7 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + XWindowAttributes wattr; gboolean has_errors; if (priv->is_mapped) @@ -151,21 +152,31 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); + if (!priv->create_window) { + XGetWindowAttributes(dpy, priv->xid, &wattr); + if (!(wattr.your_event_mask & StructureNotifyMask)) + XSelectInput(dpy, priv->xid, StructureNotifyMask); + } XMapWindow(dpy, priv->xid); has_errors = x11_untrap_errors() != 0; GST_VAAPI_DISPLAY_UNLOCK(priv->display); - if (has_errors) - return FALSE; - if (priv->create_window) + if (!has_errors) { wait_event(window, MapNotify); + if (!priv->create_window && + !(wattr.your_event_mask & StructureNotifyMask)) { + GST_VAAPI_DISPLAY_LOCK(priv->display); + x11_trap_errors(); + XSelectInput(dpy, priv->xid, wattr.your_event_mask); + has_errors = x11_untrap_errors() != 0; + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + } + priv->is_mapped = TRUE; - priv->is_mapped = TRUE; - - if (priv->fullscreen_on_map) - gst_vaapi_window_set_fullscreen(window, TRUE); - - return TRUE; + if (priv->fullscreen_on_map) + gst_vaapi_window_set_fullscreen(window, TRUE); + } + return !has_errors; } static gboolean @@ -173,6 +184,7 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + XWindowAttributes wattr; gboolean has_errors; if (!priv->is_mapped) @@ -180,17 +192,28 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); + if (!priv->create_window) { + XGetWindowAttributes(dpy, priv->xid, &wattr); + if (!(wattr.your_event_mask & StructureNotifyMask)) + XSelectInput(dpy, priv->xid, StructureNotifyMask); + } XUnmapWindow(dpy, priv->xid); has_errors = x11_untrap_errors() != 0; GST_VAAPI_DISPLAY_UNLOCK(priv->display); - if (has_errors) - return FALSE; - if (priv->create_window) + if (!has_errors) { wait_event(window, UnmapNotify); - - priv->is_mapped = FALSE; - return TRUE; + if (!priv->create_window && + !(wattr.your_event_mask & StructureNotifyMask)) { + GST_VAAPI_DISPLAY_LOCK(priv->display); + x11_trap_errors(); + XSelectInput(dpy, priv->xid, wattr.your_event_mask); + has_errors = x11_untrap_errors() != 0; + GST_VAAPI_DISPLAY_UNLOCK(priv->display); + } + priv->is_mapped = FALSE; + } + return !has_errors; } static gboolean From 6a8c6ad04c6f25ed2a5470c5e5b526c83d37503a Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 10:36:20 +0000 Subject: [PATCH 0134/3781] Add gst_vaapi_surface_{,de}associate_subpicture() API. --- docs/reference/libs/libs-sections.txt | 2 + gst-libs/gst/vaapi/gstvaapisurface.c | 138 ++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 18 +++- tests/test-windows.c | 120 ++++++++++++++++++++-- 4 files changed, 271 insertions(+), 7 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 9178ba7c97..2ca43496d3 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -242,6 +242,8 @@ gst_vaapi_surface_get_size gst_vaapi_surface_derive_image gst_vaapi_surface_get_image gst_vaapi_surface_put_image +gst_vaapi_surface_associate_subpicture +gst_vaapi_surface_deassociate_subpicture gst_vaapi_surface_sync GST_VAAPI_SURFACE diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index b82b40d875..eca7b95f44 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -45,6 +45,7 @@ struct _GstVaapiSurfacePrivate { guint width; guint height; GstVaapiChromaType chroma_type; + GPtrArray *subpictures; }; enum { @@ -57,6 +58,12 @@ enum { PROP_CHROMA_TYPE }; +static void +destroy_subpicture_cb(gpointer subpicture, gpointer user_data) +{ + g_object_unref(subpicture); +} + static void gst_vaapi_surface_destroy(GstVaapiSurface *surface) { @@ -75,6 +82,12 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface) priv->surface_id = VA_INVALID_SURFACE; } + if (priv->subpictures) { + g_ptr_array_foreach(priv->subpictures, destroy_subpicture_cb, NULL); + g_ptr_array_free(priv->subpictures, TRUE); + priv->subpictures = NULL; + } + if (priv->display) { g_object_unref(priv->display); priv->display = NULL; @@ -282,6 +295,7 @@ gst_vaapi_surface_init(GstVaapiSurface *surface) priv->width = 0; priv->height = 0; priv->chroma_type = 0; + priv->subpictures = NULL; } /** @@ -553,6 +567,130 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) return TRUE; } +/** + * gst_vaapi_surface_associate_subpicture: + * @surface: a #GstVaapiSurface + * @subpicture: a #GstVaapiSubpicture + * @src_rect: (allow-none): the sub-rectangle of the source subpicture + * image to extract and process. If %NULL, the entire image will be used. + * @dst_rect: (allow-none): the sub-rectangle of the destination + * surface into which the image is rendered. If %NULL, the entire + * surface will be used. + * + * Associates the @subpicture with the @surface. The @src_rect + * coordinates and size are relative to the source image bound to + * @subpicture. The @dst_rect coordinates and size are relative to the + * target @surface. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_surface_associate_subpicture( + GstVaapiSurface *surface, + GstVaapiSubpicture *subpicture, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect +) +{ + GstVaapiRectangle src_rect_default, dst_rect_default; + GstVaapiImage *image; + VAStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); + + if (!gst_vaapi_surface_deassociate_subpicture(surface, subpicture)) + return FALSE; + + if (!surface->priv->subpictures) { + surface->priv->subpictures = g_ptr_array_new(); + if (!surface->priv->subpictures) + return FALSE; + } + + if (!src_rect) { + image = gst_vaapi_subpicture_get_image(subpicture); + if (!image) + return FALSE; + src_rect = &src_rect_default; + src_rect_default.x = 0; + src_rect_default.y = 0; + gst_vaapi_image_get_size( + image, + &src_rect_default.width, + &src_rect_default.height + ); + } + + if (!dst_rect) { + dst_rect = &dst_rect_default; + dst_rect_default.x = 0; + dst_rect_default.y = 0; + dst_rect_default.width = surface->priv->width; + dst_rect_default.height = surface->priv->height; + } + + GST_VAAPI_DISPLAY_LOCK(surface->priv->display); + status = vaAssociateSubpicture( + GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), + gst_vaapi_subpicture_get_id(subpicture), + &surface->priv->surface_id, 1, + src_rect->x, src_rect->y, src_rect->width, src_rect->height, + dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height, + 0 + ); + GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); + if (!vaapi_check_status(status, "vaAssociateSubpicture()")) + return FALSE; + + g_ptr_array_add(surface->priv->subpictures, g_object_ref(subpicture)); + return TRUE; +} + +/** + * gst_vaapi_surface_deassociate_subpicture: + * @surface: a #GstVaapiSurface + * @subpicture: a #GstVaapiSubpicture + * + * Deassociates @subpicture from @surface. Other associations are kept. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_surface_deassociate_subpicture( + GstVaapiSurface *surface, + GstVaapiSubpicture *subpicture +) +{ + VAStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); + + if (!surface->priv->subpictures) + return TRUE; + + /* First, check subpicture was really associated with this surface */ + if (!g_ptr_array_remove_fast(surface->priv->subpictures, subpicture)) { + GST_DEBUG("subpicture 0x%08x was not bound to surface 0x%08x", + gst_vaapi_subpicture_get_id(subpicture), + surface->priv->surface_id); + return TRUE; + } + + GST_VAAPI_DISPLAY_LOCK(surface->priv->display); + status = vaDeassociateSubpicture( + GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), + gst_vaapi_subpicture_get_id(subpicture), + &surface->priv->surface_id, 1 + ); + GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); + g_object_unref(subpicture); + if (!vaapi_check_status(status, "vaDeassociateSubpicture()")) + return FALSE; + return TRUE; +} + /** * gst_vaapi_surface_sync: * @surface: a #GstVaapiSurface diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 4a4843811e..2a8d722ef3 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -21,8 +21,10 @@ #ifndef GST_VAAPI_SURFACE_H #define GST_VAAPI_SURFACE_H -#include +#include #include +#include +#include G_BEGIN_DECLS @@ -162,6 +164,20 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image); gboolean gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image); +gboolean +gst_vaapi_surface_associate_subpicture( + GstVaapiSurface *surface, + GstVaapiSubpicture *subpicture, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect +); + +gboolean +gst_vaapi_surface_deassociate_subpicture( + GstVaapiSurface *surface, + GstVaapiSubpicture *subpicture +); + gboolean gst_vaapi_surface_sync(GstVaapiSurface *surface); diff --git a/tests/test-windows.c b/tests/test-windows.c index 6813c94082..cea4d187c0 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -39,6 +39,77 @@ typedef void (*DrawRectFunc)( guint32 color ); +static void draw_rect_ARGB( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + guint i, j; + + color = GUINT32_TO_BE(color); + + for (j = 0; j < height; j++) { + guint32 *p = (guint32 *)(pixels[0] + (y + j) * stride[0] + x * 4); + for (i = 0; i < width; i++) + p[i] = color; + } +} + +static void draw_rect_BGRA( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + // Converts ARGB color to BGRA + color = GUINT32_SWAP_LE_BE(color); + + draw_rect_ARGB(pixels, stride, x, y, width, height, color); +} + +static void draw_rect_RGBA( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + // Converts ARGB color to RGBA + color = ((color >> 24) & 0xff) | ((color & 0xffffff) << 8); + + draw_rect_ARGB(pixels, stride, x, y, width, height, color); +} + +static void draw_rect_ABGR( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + // Converts ARGB color to ABGR + color = ((color & 0xff00ff00) | + ((color >> 16) & 0xff) | + ((color & 0xff) << 16)); + + draw_rect_ARGB(pixels, stride, x, y, width, height, color); +} + static void draw_rect_NV12( // Y, UV planes guchar *pixels[3], guint stride[3], @@ -122,6 +193,25 @@ static gboolean draw_rgb_rects(GstVaapiImage *image) return FALSE; switch (format) { + case GST_VAAPI_IMAGE_ARGB: + draw_rect = draw_rect_ARGB; + goto RGB_colors; + case GST_VAAPI_IMAGE_BGRA: + draw_rect = draw_rect_BGRA; + goto RGB_colors; + case GST_VAAPI_IMAGE_RGBA: + draw_rect = draw_rect_RGBA; + goto RGB_colors; + case GST_VAAPI_IMAGE_ABGR: + draw_rect = draw_rect_ABGR; + RGB_colors: + pixels[0] = gst_vaapi_image_get_plane(image, 0); + stride[0] = gst_vaapi_image_get_pitch(image, 0); + red_color = 0xffff0000; + green_color = 0xff00ff00; + blue_color = 0xff0000ff; + black_color = 0xff000000; + break; case GST_VAAPI_IMAGE_NV12: draw_rect = draw_rect_NV12; pixels[0] = gst_vaapi_image_get_plane(image, 0); @@ -171,10 +261,11 @@ static gboolean draw_rgb_rects(GstVaapiImage *image) int main(int argc, char *argv[]) { - GstVaapiDisplay *display; - GstVaapiWindow *window; - GstVaapiSurface *surface; - GstVaapiImage *image = NULL; + GstVaapiDisplay *display; + GstVaapiWindow *window; + GstVaapiSurface *surface; + GstVaapiImage *image = NULL; + GstVaapiSubpicture *subpicture = NULL; GstVaapiImageFormat format; guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; guint i; @@ -183,6 +274,10 @@ main(int argc, char *argv[]) GST_VAAPI_IMAGE_NV12, GST_VAAPI_IMAGE_YV12, GST_VAAPI_IMAGE_I420, + GST_VAAPI_IMAGE_ARGB, + GST_VAAPI_IMAGE_BGRA, + GST_VAAPI_IMAGE_RGBA, + GST_VAAPI_IMAGE_ABGR, 0 }; @@ -215,8 +310,19 @@ main(int argc, char *argv[]) if (!draw_rgb_rects(image)) g_error("could not draw RGB rectangles"); - if (!gst_vaapi_surface_put_image(surface, image)) - g_error("could not upload image"); + if (gst_vaapi_image_format_is_rgb(format)) { + subpicture = gst_vaapi_subpicture_new(image); + if (!subpicture) + g_error("could not create Gst/VA subpicture"); + + if (!gst_vaapi_surface_associate_subpicture(surface, subpicture, + NULL, NULL)) + g_error("could not associate subpicture to surface"); + } + else { + if (!gst_vaapi_surface_put_image(surface, image)) + g_error("could not upload image"); + } if (!gst_vaapi_surface_sync(surface)) g_error("could not complete image upload"); @@ -277,6 +383,8 @@ main(int argc, char *argv[]) XDestroyWindow(dpy, win); } + if (subpicture) + g_object_unref(subpicture); g_object_unref(image); g_object_unref(surface); g_object_unref(display); From b3c3554938618357ef99165d00eeed252be5ceca Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 10:48:58 +0000 Subject: [PATCH 0135/3781] Unref subpicture earlier as the surface is supposed to hold a reference to it. --- tests/test-windows.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test-windows.c b/tests/test-windows.c index cea4d187c0..bca4afcab0 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -265,7 +265,7 @@ main(int argc, char *argv[]) GstVaapiWindow *window; GstVaapiSurface *surface; GstVaapiImage *image = NULL; - GstVaapiSubpicture *subpicture = NULL; + GstVaapiSubpicture *subpicture; GstVaapiImageFormat format; guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; guint i; @@ -318,6 +318,9 @@ main(int argc, char *argv[]) if (!gst_vaapi_surface_associate_subpicture(surface, subpicture, NULL, NULL)) g_error("could not associate subpicture to surface"); + + /* The surface holds a reference to the subpicture. This is safe. */ + g_object_unref(subpicture); } else { if (!gst_vaapi_surface_put_image(surface, image)) @@ -383,8 +386,6 @@ main(int argc, char *argv[]) XDestroyWindow(dpy, win); } - if (subpicture) - g_object_unref(subpicture); g_object_unref(image); g_object_unref(surface); g_object_unref(display); From 95edba8907c9fbafd64d189f7aa0fa41fa649ecb Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 10:49:33 +0000 Subject: [PATCH 0136/3781] Improve debugging messages. --- gst-libs/gst/vaapi/gstvaapiimage.c | 2 ++ gst-libs/gst/vaapi/gstvaapisubpicture.c | 5 ++++- gst-libs/gst/vaapi/gstvaapisurface.c | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index df2b676d51..c1d7b40ac3 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -153,6 +153,8 @@ gst_vaapi_image_destroy(GstVaapiImage *image) _gst_vaapi_image_unmap(image); + GST_DEBUG("image 0x%08x", priv->internal_image.image_id); + if (priv->internal_image.image_id != VA_INVALID_ID) { GST_VAAPI_DISPLAY_LOCK(priv->display); status = vaDestroyImage( diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index fff21fe802..40c7447de0 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -58,6 +58,8 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) GstVaapiDisplay *display; VAStatus status; + GST_DEBUG("subpicture 0x%08x", priv->subpicture_id); + if (priv->subpicture_id != VA_INVALID_ID) { display = gst_vaapi_image_get_display(priv->image); if (display) { @@ -105,6 +107,7 @@ gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture) if (!vaapi_check_status(status, "vaCreateSubpicture()")) return FALSE; + GST_DEBUG("subpicture 0x%08x", subpicture_id); priv->subpicture_id = subpicture_id; return TRUE; } @@ -224,7 +227,7 @@ gst_vaapi_subpicture_new(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); - GST_DEBUG("image 0x%08x", gst_vaapi_image_get_id(image)); + GST_DEBUG("create from image 0x%08x", gst_vaapi_image_get_id(image)); return g_object_new(GST_VAAPI_TYPE_SUBPICTURE, "image", image, diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index eca7b95f44..eb45cbe5de 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -70,6 +70,8 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface) GstVaapiSurfacePrivate * const priv = surface->priv; VAStatus status; + GST_DEBUG("surface 0x%08x", priv->surface_id); + if (priv->surface_id != VA_INVALID_SURFACE) { GST_VAAPI_DISPLAY_LOCK(priv->display); status = vaDestroySurfaces( @@ -129,6 +131,7 @@ gst_vaapi_surface_create(GstVaapiSurface *surface) if (!vaapi_check_status(status, "vaCreateSurfaces()")) return FALSE; + GST_DEBUG("surface 0x%08x", surface_id); priv->surface_id = surface_id; return TRUE; } From b4aaa2e8c11ee105382ebf3299546f8991db91d6 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 10:51:35 +0000 Subject: [PATCH 0137/3781] Add note about the fact that the surface holds an extra reference to the subpicture. --- gst-libs/gst/vaapi/gstvaapisurface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index eb45cbe5de..d9c3cbeb9c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -583,7 +583,8 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) * Associates the @subpicture with the @surface. The @src_rect * coordinates and size are relative to the source image bound to * @subpicture. The @dst_rect coordinates and size are relative to the - * target @surface. + * target @surface. Note that the @surface holds an additional + * reference to the @subpicture. * * Return value: %TRUE on success */ From b271ebd760f2309acc2f1fee7bc176abdd576c27 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 13:32:36 +0000 Subject: [PATCH 0138/3781] Drop introspection annotations since they require gtk-doc >= 1.12. --- configure.ac | 1 + docs/reference/libs/libs-docs.xml.in | 1 + gst-libs/gst/vaapi/gstvaapidisplay.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapiimage.c | 6 +++--- gst-libs/gst/vaapi/gstvaapisurface.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapiwindow.c | 8 ++++---- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index 786ef7b3b5..df3296bb44 100644 --- a/configure.ac +++ b/configure.ac @@ -34,6 +34,7 @@ m4_define([libva_sds_version], [libva_glx_sds_version_0_31]) m4_define([libva_sds_package_version], [libva_glx_sds_package_version_0_31]) # gtk-doc version number +# XXX: introspection annotations require gtk-doc >= 1.12 m4_define([gtkdoc_major_version], [1]) m4_define([gtkdoc_minor_version], [9]) m4_define([gtkdoc_version], [gtkdoc_major_version.gtkdoc_minor_version]) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 48fccf22c7..c136180a7a 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -25,5 +25,6 @@ + diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index e084baf164..eb06ac068c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -618,8 +618,8 @@ gst_vaapi_display_get_height(GstVaapiDisplay *display) /** * gst_vaapi_display_get_size: * @display: a #GstVaapiDisplay - * @pwidth: (out) (allow-none): return location for the width, or %NULL - * @pheight: (out) (allow-none): return location for the height, or %NULL + * @pwidth: return location for the width, or %NULL + * @pheight: return location for the height, or %NULL * * Retrieves the dimensions of a #GstVaapiDisplay. */ @@ -638,8 +638,8 @@ gst_vaapi_display_get_size(GstVaapiDisplay *display, guint *pwidth, guint *pheig /** * gst_vaapi_display_get_pixel_aspect_ratio: * @display: a #GstVaapiDisplay - * @par_n: (out) (allow-none): return location for the numerator of pixel aspect ratio, or %NULL - * @par_d: (out) (allow-none): return location for the denominator of pixel aspect ratio, or %NULL + * @par_n: return location for the numerator of pixel aspect ratio, or %NULL + * @par_d: return location for the denominator of pixel aspect ratio, or %NULL * * Retrieves the pixel aspect ratio of a #GstVaapiDisplay. */ diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index c1d7b40ac3..5da91fda84 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -563,7 +563,7 @@ gst_vaapi_image_get_id(GstVaapiImage *image) /** * gst_vaapi_image_get_image: * @image: a #GstVaapiImage - * @va_image: (output): a VA image + * @va_image: a VA image * * Fills @va_image with the VA image used internally. * @@ -721,8 +721,8 @@ gst_vaapi_image_get_height(GstVaapiImage *image) /** * gst_vaapi_image_get_size: * @image: a #GstVaapiImage - * @pwidth: (out) (allow-none): return location for the width, or %NULL - * @pheight: (out) (allow-none): return location for the height, or %NULL + * @pwidth: return location for the width, or %NULL + * @pheight: return location for the height, or %NULL * * Retrieves the dimensions of a #GstVaapiImage. */ diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index d9c3cbeb9c..dd5fca0b2c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -414,8 +414,8 @@ gst_vaapi_surface_get_height(GstVaapiSurface *surface) /** * gst_vaapi_surface_get_size: * @surface: a #GstVaapiSurface - * @pwidth: (out) (allow-none): return location for the width, or %NULL - * @pheight: (out) (allow-none): return location for the height, or %NULL + * @pwidth: return location for the width, or %NULL + * @pheight: return location for the height, or %NULL * * Retrieves the dimensions of a #GstVaapiSurface. */ @@ -574,9 +574,9 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) * gst_vaapi_surface_associate_subpicture: * @surface: a #GstVaapiSurface * @subpicture: a #GstVaapiSubpicture - * @src_rect: (allow-none): the sub-rectangle of the source subpicture + * @src_rect: the sub-rectangle of the source subpicture * image to extract and process. If %NULL, the entire image will be used. - * @dst_rect: (allow-none): the sub-rectangle of the destination + * @dst_rect: the sub-rectangle of the destination * surface into which the image is rendered. If %NULL, the entire * surface will be used. * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 864588a203..86aeb95c46 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -383,8 +383,8 @@ gst_vaapi_window_get_height(GstVaapiWindow *window) /** * gst_vaapi_window_get_size: * @window: a #GstVaapiWindow - * @pwidth: (out) (allow-none): return location for the width, or %NULL - * @pheight: (out) (allow-none): return location for the height, or %NULL + * @pwidth: return location for the width, or %NULL + * @pheight: return location for the height, or %NULL * * Retrieves the dimensions of a #GstVaapiWindow. */ @@ -484,9 +484,9 @@ get_window_rect(GstVaapiWindow *window, GstVaapiRectangle *rect) * gst_vaapi_window_put_surface: * @window: a #GstVaapiWindow * @surface: a #GstVaapiSurface - * @src_rect: (allow-none): the sub-rectangle of the source surface to + * @src_rect: the sub-rectangle of the source surface to * extract and process. If %NULL, the entire surface will be used. - * @dst_rect: (allow-none): the sub-rectangle of the destination + * @dst_rect: the sub-rectangle of the destination * window into which the surface is rendered. If %NULL, the entire * window will be used. * @flags: postprocessing flags. See #GstVaapiSurfaceRenderFlags From 123eb732ff4a4bf9d428adcd902dcb7d39bc518a Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 14:06:42 +0000 Subject: [PATCH 0139/3781] Don't export gst_vaapisink_get_display(). --- sys/vaapisink/gstvaapisink.c | 3 +++ sys/vaapisink/gstvaapisink.h | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index f67eed24be..a4bd7e7137 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -69,6 +69,9 @@ enum { PROP_FULLSCREEN }; +static GstVaapiDisplay * +gst_vaapisink_get_display(GstVaapiSink *sink); + static GstVaapiDisplay * gst_vaapi_video_sink_do_get_display(GstVaapiVideoSink *sink) { diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h index d6ff8f3550..f4a3e085b9 100644 --- a/sys/vaapisink/gstvaapisink.h +++ b/sys/vaapisink/gstvaapisink.h @@ -74,9 +74,6 @@ struct _GstVaapiSinkClass { GType gst_vaapisink_get_type(void); -GstVaapiDisplay * -gst_vaapisink_get_display(GstVaapiSink *sink); - G_END_DECLS #endif /* GST_VAAPISINK_H */ From 49689f8f1eecc99c49d726ffdc79b57d3a51566a Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 14:19:21 +0000 Subject: [PATCH 0140/3781] Add plugins documentation template. --- configure.ac | 2 + docs/reference/Makefile.am | 2 +- docs/reference/plugins/Makefile.am | 105 +++++++++++++++++++ docs/reference/plugins/plugins-docs.xml.in | 29 +++++ docs/reference/plugins/plugins-overrides.txt | 0 docs/reference/plugins/plugins-sections.txt | 28 +++++ docs/reference/plugins/plugins.types | 2 + 7 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 docs/reference/plugins/Makefile.am create mode 100644 docs/reference/plugins/plugins-docs.xml.in create mode 100644 docs/reference/plugins/plugins-overrides.txt create mode 100644 docs/reference/plugins/plugins-sections.txt create mode 100644 docs/reference/plugins/plugins.types diff --git a/configure.ac b/configure.ac index df3296bb44..a478004b26 100644 --- a/configure.ac +++ b/configure.ac @@ -206,6 +206,8 @@ debian/libgstvaapi-x11.install.in docs/reference/Makefile docs/reference/libs/Makefile docs/reference/libs/libs-docs.xml + docs/reference/plugins/Makefile + docs/reference/plugins/plugins-docs.xml gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/vaapi/Makefile diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am index d29d457676..3eef00ec9e 100644 --- a/docs/reference/Makefile.am +++ b/docs/reference/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = libs +SUBDIRS = libs plugins # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/docs/reference/plugins/Makefile.am b/docs/reference/plugins/Makefile.am new file mode 100644 index 0000000000..778dc96790 --- /dev/null +++ b/docs/reference/plugins/Makefile.am @@ -0,0 +1,105 @@ +## Process this file with automake to produce Makefile.in + +# We require automake 1.6 at least. +AUTOMAKE_OPTIONS = 1.6 + +# This is a blank Makefile.am for using gtk-doc. +# Copy this to your project's API docs directory and modify the variables to +# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples +# of using the various options. + +# The name of the module, e.g. 'glib'. +DOC_MODULE = plugins + +# The top-level SGML file. You can change this if you want to. +DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting the functions and macros. +# e.g. DOC_SOURCE_DIR=../../../gtk +DOC_SOURCE_DIR = $(top_srcdir)/sys + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS = --type-init-func="gst_init(NULL, NULL)" + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS = --deprecated-guards="GST_VAAPI_DISABLE_DEPRECATED" + +# Extra options to supply to gtkdoc-mkdb. +# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml +MKDB_OPTIONS = --sgml-mode --output-format=xml --name-space=$(DOC_MODULE) + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS = + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS = \ + --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib \ + --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/gobject \ + --extra-dir=$(CAIRO_PREFIX)/share/gtk-doc/html/cairo \ + --extra-dir=$(PANGO_PREFIX)/share/gtk-doc/html/pango + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB = $(top_srcdir)/sys/*/*.h +CFILE_GLOB = $(top_srcdir)/sys/*/*.c + +# Header files to ignore when scanning. +# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h +IGNORE_HFILES = \ + $(NULL) + +EXTRA_HFILES = \ + $(NULL) + +# Images to copy into HTML directory. +# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png +HTML_IMAGES = \ + $(NULL) + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +# e.g. content_files=running.sgml building.sgml changes-2.0.sgml +content_files = \ + $(NULL) + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files = \ + $(NULL) + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/gst-libs \ + -I$(top_srcdir)/gst-libs/gst/vaapi \ + $(GLIB_CFLAGS) + +GTKDOC_LIBS = \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la \ + $(top_builddir)/sys/vaapiconvert/libgstvaapiconvert.la \ + $(top_builddir)/sys/vaapisink/libgstvaapisink.la \ + $(GLIB_LIBS) + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +EXTRA_DIST += \ + $(DOC_MODULE)-docs.xml.in \ + $(NULL) + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in $(DOC_MODULE)-docs.xml diff --git a/docs/reference/plugins/plugins-docs.xml.in b/docs/reference/plugins/plugins-docs.xml.in new file mode 100644 index 0000000000..fbc2cf5a8f --- /dev/null +++ b/docs/reference/plugins/plugins-docs.xml.in @@ -0,0 +1,29 @@ + + +]> + + + GStreamer VA-API Plugins @GST_MAJORMINOR@ Plugins Reference Manual + + + + gst-plugins-vaapi Plugins + + + + + + Object Hierarchy + + + + + API Index + + + + + diff --git a/docs/reference/plugins/plugins-overrides.txt b/docs/reference/plugins/plugins-overrides.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/reference/plugins/plugins-sections.txt b/docs/reference/plugins/plugins-sections.txt new file mode 100644 index 0000000000..8853004e23 --- /dev/null +++ b/docs/reference/plugins/plugins-sections.txt @@ -0,0 +1,28 @@ +
+gstvaapisink +GstVaapiSink +GstVaapiSink + +GST_VAAPISINK +GST_IS_VAAPISINK +GST_TYPE_VAAPISINK +gst_vaapisink_get_type +GST_VAAPISINK_CLASS +GST_IS_VAAPISINK_CLASS +GST_VAAPISINK_GET_CLASS +
+ +
+gstvaapiconvert +GstVaapiConvert +GstVaapiConvert + +GST_VAAPICONVERT +GST_IS_VAAPICONVERT +GST_TYPE_VAAPICONVERT +gst_vaapiconvert_get_type +GST_VAAPICONVERT_CLASS +GST_IS_VAAPICONVERT_CLASS +GST_VAAPICONVERT_GET_CLASS +
+ diff --git a/docs/reference/plugins/plugins.types b/docs/reference/plugins/plugins.types new file mode 100644 index 0000000000..fab5f67fc3 --- /dev/null +++ b/docs/reference/plugins/plugins.types @@ -0,0 +1,2 @@ +gst_vaapisink_get_type +gst_vaapiconvert_get_type From 232596356f941c727e79d88785c162f19b7166f8 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 15:22:47 +0000 Subject: [PATCH 0141/3781] Document vaapiconvert & vaapisink plugins. --- sys/vaapiconvert/gstvaapiconvert.c | 27 +++++++++++++++++++++++++++ sys/vaapisink/gstvaapisink.c | 9 +++++++++ 2 files changed, 36 insertions(+) diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/sys/vaapiconvert/gstvaapiconvert.c index c61660b3c3..e579eb3672 100644 --- a/sys/vaapiconvert/gstvaapiconvert.c +++ b/sys/vaapiconvert/gstvaapiconvert.c @@ -18,6 +18,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gstvaapiconvert + * @short_description: A VA-API based video pixels format converter + * + * vaapiconvert converts from raw YUV pixels to surfaces suitable for + * the vaapisink element. + */ + #include "config.h" #include #include @@ -231,6 +239,25 @@ gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) trans_class->get_unit_size = gst_vaapiconvert_get_unit_size; trans_class->prepare_output_buffer = gst_vaapiconvert_prepare_output_buffer; + /** + * GstVaapiConvert:direct-rendering: + * + * Selects the direct rendering level. + * + * + * Disables direct rendering. + * + * + * Enables direct rendering to the output buffer. i.e. this + * tries to use a single buffer for both sink and src pads. + * + * + * Enables direct rendering to the underlying surface. i.e. with + * drivers supporting vaDeriveImage(), the output surface pixels + * will be modified directly. + * + * + */ g_object_class_install_property (object_class, PROP_DIRECT_RENDERING, diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index a4bd7e7137..ed8e407c46 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -18,6 +18,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gstvaapisink + * @short_description: A VA-API based videosink + * + * vaapisink renders video frames to a drawable (X #Window) on a local + * display using the Video Acceleration (VA) API. The element will + * create its own internal window and render into it. + */ + #include "config.h" #include #include From 3daf6190065a752ed9b85e510bc2c3ad0daa4771 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 15:28:50 +0000 Subject: [PATCH 0142/3781] Use plain "display" property for the X11 display name. --- sys/vaapisink/gstvaapisink.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index ed8e407c46..8e1a4077f9 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -74,7 +74,6 @@ enum { PROP_0, PROP_DISPLAY, - PROP_DISPLAY_NAME, PROP_FULLSCREEN }; @@ -282,7 +281,7 @@ gst_vaapisink_set_property( GstVaapiSink * const sink = GST_VAAPISINK(object); switch (prop_id) { - case PROP_DISPLAY_NAME: + case PROP_DISPLAY: g_free(sink->display_name); sink->display_name = g_strdup(g_value_get_string(value)); break; @@ -307,9 +306,6 @@ gst_vaapisink_get_property( switch (prop_id) { case PROP_DISPLAY: - g_value_set_object(value, sink->display); - break; - case PROP_DISPLAY_NAME: g_value_set_string(value, sink->display_name); break; case PROP_FULLSCREEN: @@ -351,20 +347,11 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) g_object_class_install_property (object_class, PROP_DISPLAY, - g_param_spec_object("display", - "display", - "display", - GST_VAAPI_TYPE_DISPLAY, - G_PARAM_READABLE)); - - g_object_class_install_property - (object_class, - PROP_DISPLAY_NAME, - g_param_spec_string("display-name", + g_param_spec_string("display", "X11 display name", "X11 display name", "", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE)); g_object_class_install_property (object_class, From 5d44dace530862e9f47b72e27d2ff25f8afa9fbe Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 15:34:51 +0000 Subject: [PATCH 0143/3781] Make sure VA display is valid when created with an explicit "display" name. --- sys/vaapisink/gstvaapisink.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 8e1a4077f9..2c2fb395c7 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -116,8 +116,11 @@ gst_vaapisink_destroy(GstVaapiSink *sink) static inline gboolean gst_vaapisink_ensure_display(GstVaapiSink *sink) { - if (!sink->display) + if (!sink->display) { sink->display = gst_vaapi_display_x11_new(sink->display_name); + if (!sink->display || !gst_vaapi_display_get_display(sink->display)) + return NULL; + } return sink->display != NULL; } From 62df0f9b1c41a5aab69aa1ad82d06a4312498c5a Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 16:11:21 +0000 Subject: [PATCH 0144/3781] Fix return value. --- sys/vaapisink/gstvaapisink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 2c2fb395c7..3103045b23 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -119,7 +119,7 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink) if (!sink->display) { sink->display = gst_vaapi_display_x11_new(sink->display_name); if (!sink->display || !gst_vaapi_display_get_display(sink->display)) - return NULL; + return FALSE; } return sink->display != NULL; } From 2155318d12f35a518f6d58493876a3bfd5f26ff9 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 16:21:28 +0000 Subject: [PATCH 0145/3781] Make GstVaapi{Surface,Image,Subpicture} derive from a GstVaapiObject. --- docs/reference/libs/libs-docs.xml.in | 1 + docs/reference/libs/libs-sections.txt | 18 ++- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapiimage.c | 85 +++++--------- gst-libs/gst/vaapi/gstvaapiimage.h | 8 +- gst-libs/gst/vaapi/gstvaapiobject.c | 147 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiobject.h | 96 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapisubpicture.c | 14 +-- gst-libs/gst/vaapi/gstvaapisubpicture.h | 5 +- gst-libs/gst/vaapi/gstvaapisurface.c | 125 +++++++++----------- gst-libs/gst/vaapi/gstvaapisurface.h | 9 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- 12 files changed, 358 insertions(+), 154 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiobject.c create mode 100644 gst-libs/gst/vaapi/gstvaapiobject.h diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index c136180a7a..af58e673c9 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -16,6 +16,7 @@ + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 2ca43496d3..d512dd96f7 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -189,6 +189,22 @@ GST_VAAPI_IS_WINDOW_CLASS GST_VAAPI_WINDOW_GET_CLASS
+
+gstvaapiobject +GstVaapiObject +GstVaapiObject +GstVaapiObjectClass +gst_vaapi_object_get_display + +GST_VAAPI_OBJECT +GST_VAAPI_IS_OBJECT +GST_VAAPI_TYPE_OBJECT +gst_vaapi_object_get_type +GST_VAAPI_OBJECT_CLASS +GST_VAAPI_IS_OBJECT_CLASS +GST_VAAPI_OBJECT_GET_CLASS +
+
gstvaapiimage GST_VAAPI_IMAGE_FORMAT @@ -201,7 +217,6 @@ gst_vaapi_image_new gst_vaapi_image_new_with_image gst_vaapi_image_get_id gst_vaapi_image_get_image -gst_vaapi_image_get_display gst_vaapi_image_get_format gst_vaapi_image_get_width gst_vaapi_image_get_height @@ -234,7 +249,6 @@ GstVaapiSurface GstVaapiSurfaceClass gst_vaapi_surface_new gst_vaapi_surface_get_id -gst_vaapi_surface_get_display gst_vaapi_surface_get_chroma_type gst_vaapi_surface_get_width gst_vaapi_surface_get_height diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index e9e47de04c..051ef82b55 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -11,6 +11,7 @@ libgstvaapi_source_c = \ gstvaapiimage.c \ gstvaapiimageformat.c \ gstvaapiimagepool.c \ + gstvaapiobject.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ gstvaapisurfacepool.c \ @@ -26,6 +27,7 @@ libgstvaapi_source_h = \ gstvaapiimage.h \ gstvaapiimageformat.h \ gstvaapiimagepool.h \ + gstvaapiobject.h \ gstvaapisubpicture.h \ gstvaapisurface.h \ gstvaapisurfacepool.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 5da91fda84..b612a10887 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -32,7 +32,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, G_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, GST_VAAPI_TYPE_OBJECT); #define GST_VAAPI_IMAGE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ @@ -40,7 +40,6 @@ G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, G_TYPE_OBJECT); GstVaapiImagePrivate)) struct _GstVaapiImagePrivate { - GstVaapiDisplay *display; VAImage internal_image; VAImage image; guchar *image_data; @@ -56,7 +55,6 @@ struct _GstVaapiImagePrivate { enum { PROP_0, - PROP_DISPLAY, PROP_IMAGE, PROP_IMAGE_ID, PROP_FORMAT, @@ -148,6 +146,7 @@ vaapi_image_is_linear(const VAImage *va_image) static void gst_vaapi_image_destroy(GstVaapiImage *image) { + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(image); GstVaapiImagePrivate * const priv = image->priv; VAStatus status; @@ -156,47 +155,43 @@ gst_vaapi_image_destroy(GstVaapiImage *image) GST_DEBUG("image 0x%08x", priv->internal_image.image_id); if (priv->internal_image.image_id != VA_INVALID_ID) { - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_DISPLAY_LOCK(display); status = vaDestroyImage( - GST_VAAPI_DISPLAY_VADISPLAY(priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), priv->internal_image.image_id ); - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaDestroyImage()")) g_warning("failed to destroy image 0x%08x\n", priv->internal_image.image_id); priv->internal_image.image_id = VA_INVALID_ID; } - - if (priv->display) { - g_object_unref(priv->display); - priv->display = NULL; - } } static gboolean _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) { + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(image); GstVaapiImagePrivate * const priv = image->priv; const VAImageFormat *va_format; VAStatus status; - if (!gst_vaapi_display_has_image_format(priv->display, format)) + if (!gst_vaapi_display_has_image_format(display, format)) return FALSE; va_format = gst_vaapi_image_format_get_va_format(format); if (!va_format) return FALSE; - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_DISPLAY_LOCK(display); status = vaCreateImage( - GST_VAAPI_DISPLAY_VADISPLAY(priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), (VAImageFormat *)va_format, priv->width, priv->height, &priv->internal_image ); - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); if (status != VA_STATUS_SUCCESS || priv->internal_image.format.fourcc != va_format->fourcc) return FALSE; @@ -274,9 +269,6 @@ gst_vaapi_image_set_property( GstVaapiImagePrivate * const priv = image->priv; switch (prop_id) { - case PROP_DISPLAY: - priv->display = g_object_ref(g_value_get_object(value)); - break; case PROP_IMAGE: { const VAImage * const va_image = g_value_get_boxed(value); if (va_image) @@ -309,9 +301,6 @@ gst_vaapi_image_get_property( GstVaapiImage * const image = GST_VAAPI_IMAGE(object); switch (prop_id) { - case PROP_DISPLAY: - g_value_set_pointer(value, gst_vaapi_image_get_display(image)); - break; case PROP_IMAGE: g_value_set_boxed(value, &image->priv->image); break; @@ -358,20 +347,6 @@ gst_vaapi_image_class_init(GstVaapiImageClass *klass) object_class->get_property = gst_vaapi_image_get_property; object_class->constructed = gst_vaapi_image_constructed; - /** - * GstVaapiImage:display: - * - * The #GstVaapiDisplay this image is bound to. - */ - g_object_class_install_property - (object_class, - PROP_DISPLAY, - g_param_spec_object("display", - "Display", - "The GstVaapiDisplay this image is bound to", - GST_VAAPI_TYPE_DISPLAY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, PROP_IMAGE, @@ -434,7 +409,6 @@ gst_vaapi_image_init(GstVaapiImage *image) GstVaapiImagePrivate *priv = GST_VAAPI_IMAGE_GET_PRIVATE(image); image->priv = priv; - priv->display = NULL; priv->image_data = NULL; priv->width = 0; priv->height = 0; @@ -650,23 +624,6 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) return TRUE; } -/** - * gst_vaapi_image_get_display: - * @image: a #GstVaapiImage - * - * Returns the #GstVaapiDisplay this @image is bound to. - * - * Return value: the parent #GstVaapiDisplay object - */ -GstVaapiDisplay * -gst_vaapi_image_get_display(GstVaapiImage *image) -{ - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); - g_return_val_if_fail(image->priv->is_constructed, FALSE); - - return image->priv->display; -} - /** * gst_vaapi_image_get_format: * @image: a #GstVaapiImage @@ -802,19 +759,24 @@ gst_vaapi_image_map(GstVaapiImage *image) gboolean _gst_vaapi_image_map(GstVaapiImage *image) { + GstVaapiDisplay *display; void *image_data; VAStatus status; if (_gst_vaapi_image_is_mapped(image)) return TRUE; - GST_VAAPI_DISPLAY_LOCK(image->priv->display); + display = GST_VAAPI_OBJECT_GET_DISPLAY(image); + if (!display) + return FALSE; + + GST_VAAPI_DISPLAY_LOCK(display); status = vaMapBuffer( - GST_VAAPI_DISPLAY_VADISPLAY(image->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), image->priv->image.buf, &image_data ); - GST_VAAPI_DISPLAY_UNLOCK(image->priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaMapBuffer()")) return FALSE; @@ -843,17 +805,22 @@ gst_vaapi_image_unmap(GstVaapiImage *image) gboolean _gst_vaapi_image_unmap(GstVaapiImage *image) { + GstVaapiDisplay *display; VAStatus status; if (!_gst_vaapi_image_is_mapped(image)) return FALSE; - GST_VAAPI_DISPLAY_LOCK(image->priv->display); + display = GST_VAAPI_OBJECT_GET_DISPLAY(image); + if (!display) + return FALSE; + + GST_VAAPI_DISPLAY_LOCK(display); status = vaUnmapBuffer( - GST_VAAPI_DISPLAY_VADISPLAY(image->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), image->priv->image.buf ); - GST_VAAPI_DISPLAY_UNLOCK(image->priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaUnmapBuffer()")) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 6c05717cd8..d15326722f 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -22,6 +22,7 @@ #define GST_VAAPI_IMAGE_H #include +#include #include #include @@ -86,7 +87,7 @@ typedef struct _GstVaapiImageClass GstVaapiImageClass; */ struct _GstVaapiImage { /*< private >*/ - GObject parent_instance; + GstVaapiObject parent_instance; GstVaapiImagePrivate *priv; }; @@ -98,7 +99,7 @@ struct _GstVaapiImage { */ struct _GstVaapiImageClass { /*< private >*/ - GObjectClass parent_class; + GstVaapiObjectClass parent_class; }; GType @@ -121,9 +122,6 @@ gst_vaapi_image_get_id(GstVaapiImage *image); gboolean gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image); -GstVaapiDisplay * -gst_vaapi_image_get_display(GstVaapiImage *image); - GstVaapiImageFormat gst_vaapi_image_get_format(GstVaapiImage *image); diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c new file mode 100644 index 0000000000..cee67b55cc --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -0,0 +1,147 @@ +/* + * gstvaapiobject.c - Base VA object + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "gstvaapiobject.h" + + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiObject, gst_vaapi_object, G_TYPE_OBJECT); + +#define GST_VAAPI_OBJECT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_OBJECT, \ + GstVaapiObjectPrivate)) + +struct _GstVaapiObjectPrivate { + GstVaapiDisplay *display; +}; + +enum { + PROP_0, + + PROP_DISPLAY, +}; + +static void +gst_vaapi_object_finalize(GObject *object) +{ + GstVaapiObjectPrivate * const priv = GST_VAAPI_OBJECT(object)->priv; + + if (priv->display) { + g_object_unref(priv->display); + priv->display = NULL; + } + + G_OBJECT_CLASS(gst_vaapi_object_parent_class)->finalize(object); +} + +static void +gst_vaapi_object_set_property( + GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiObject * const object = GST_VAAPI_OBJECT(gobject); + + switch (prop_id) { + case PROP_DISPLAY: + object->priv->display = g_object_ref(g_value_get_object(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_object_get_property( + GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiObject * const object = GST_VAAPI_OBJECT(gobject); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_object(value, gst_vaapi_object_get_display(object)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_object_class_init(GstVaapiObjectClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiObjectPrivate)); + + object_class->finalize = gst_vaapi_object_finalize; + object_class->set_property = gst_vaapi_object_set_property; + object_class->get_property = gst_vaapi_object_get_property; + + /** + * GstVaapiObject:display: + * + * The #GstVaapiDisplay this object is bound to. + */ + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_object("display", + "Display", + "The GstVaapiDisplay this object is bound to", + GST_VAAPI_TYPE_DISPLAY, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_object_init(GstVaapiObject *object) +{ + GstVaapiObjectPrivate *priv = GST_VAAPI_OBJECT_GET_PRIVATE(object); + + object->priv = priv; + priv->display = NULL; +} + +/** + * gst_vaapi_object_get_display: + * @object: a #GstVaapiObject + * + * Returns the #GstVaapiDisplay this @object is bound to. + * + * Return value: the parent #GstVaapiDisplay object + */ +GstVaapiDisplay * +gst_vaapi_object_get_display(GstVaapiObject *object) +{ + g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), NULL); + + return object->priv->display; +} diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h new file mode 100644 index 0000000000..45f1a6e590 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -0,0 +1,96 @@ +/* + * gstvaapiobject.h - Base VA object + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_OBJECT_H +#define GST_VAAPI_OBJECT_H + +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_OBJECT \ + (gst_vaapi_object_get_type()) + +#define GST_VAAPI_OBJECT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_OBJECT, \ + GstVaapiObject)) + +#define GST_VAAPI_OBJECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_OBJECT, \ + GstVaapiObjectClass)) + +#define GST_VAAPI_IS_OBJECT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_OBJECT)) + +#define GST_VAAPI_IS_OBJECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_OBJECT)) + +#define GST_VAAPI_OBJECT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_OBJECT, \ + GstVaapiObjectClass)) + +/** + * GST_VAAPI_OBJECT_GET_DISPLAY: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the #GstVaapiDisplay @object is bound to. + */ +#define GST_VAAPI_OBJECT_GET_DISPLAY(object) \ + gst_vaapi_object_get_display(GST_VAAPI_OBJECT(object)) + +typedef struct _GstVaapiObject GstVaapiObject; +typedef struct _GstVaapiObjectPrivate GstVaapiObjectPrivate; +typedef struct _GstVaapiObjectClass GstVaapiObjectClass; + +/** + * GstVaapiObject: + * + * VA object base. + */ +struct _GstVaapiObject { + /*< private >*/ + GObject parent_instance; + + GstVaapiObjectPrivate *priv; +}; + +/** + * GstVaapiObjectClass: + * + * VA object base class. + */ +struct _GstVaapiObjectClass { + /*< private >*/ + GObjectClass parent_class; +}; + +GType +gst_vaapi_object_get_type(void); + +GstVaapiDisplay * +gst_vaapi_object_get_display(GstVaapiObject *object); + +G_END_DECLS + +#endif /* GST_VAAPI_OBJECT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 40c7447de0..ca7e57b9a0 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -32,7 +32,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, G_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, GST_VAAPI_TYPE_OBJECT); #define GST_VAAPI_SUBPICTURE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ @@ -54,14 +54,13 @@ enum { static void gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) { + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(subpicture); GstVaapiSubpicturePrivate * const priv = subpicture->priv; - GstVaapiDisplay *display; VAStatus status; GST_DEBUG("subpicture 0x%08x", priv->subpicture_id); if (priv->subpicture_id != VA_INVALID_ID) { - display = gst_vaapi_image_get_display(priv->image); if (display) { GST_VAAPI_DISPLAY_LOCK(display); status = vaDestroySubpicture( @@ -85,18 +84,14 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) static gboolean gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture) { + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(subpicture); GstVaapiSubpicturePrivate * const priv = subpicture->priv; - GstVaapiDisplay *display; VASubpictureID subpicture_id; VAStatus status; if (!priv->image) return FALSE; - display = gst_vaapi_image_get_display(priv->image); - if (!display) - return FALSE; - GST_VAAPI_DISPLAY_LOCK(display); status = vaCreateSubpicture( GST_VAAPI_DISPLAY_VADISPLAY(display), @@ -230,7 +225,8 @@ gst_vaapi_subpicture_new(GstVaapiImage *image) GST_DEBUG("create from image 0x%08x", gst_vaapi_image_get_id(image)); return g_object_new(GST_VAAPI_TYPE_SUBPICTURE, - "image", image, + "display", GST_VAAPI_OBJECT_GET_DISPLAY(image), + "image", image, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 799aae8e97..7c4b125c52 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -21,6 +21,7 @@ #ifndef GST_VAAPI_SUBPICTURE_H #define GST_VAAPI_SUBPICTURE_H +#include #include #include @@ -61,7 +62,7 @@ typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass; */ struct _GstVaapiSubpicture { /*< private >*/ - GObject parent_instance; + GstVaapiObject parent_instance; GstVaapiSubpicturePrivate *priv; }; @@ -73,7 +74,7 @@ struct _GstVaapiSubpicture { */ struct _GstVaapiSubpictureClass { /*< private >*/ - GObjectClass parent_class; + GstVaapiObjectClass parent_class; }; GType diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index dd5fca0b2c..4b20068beb 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -32,7 +32,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiSurface, gst_vaapi_surface, G_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiSurface, gst_vaapi_surface, GST_VAAPI_TYPE_OBJECT); #define GST_VAAPI_SURFACE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ @@ -40,7 +40,6 @@ G_DEFINE_TYPE(GstVaapiSurface, gst_vaapi_surface, G_TYPE_OBJECT); GstVaapiSurfacePrivate)) struct _GstVaapiSurfacePrivate { - GstVaapiDisplay *display; VASurfaceID surface_id; guint width; guint height; @@ -51,7 +50,6 @@ struct _GstVaapiSurfacePrivate { enum { PROP_0, - PROP_DISPLAY, PROP_SURFACE_ID, PROP_WIDTH, PROP_HEIGHT, @@ -67,18 +65,19 @@ destroy_subpicture_cb(gpointer subpicture, gpointer user_data) static void gst_vaapi_surface_destroy(GstVaapiSurface *surface) { + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); GstVaapiSurfacePrivate * const priv = surface->priv; VAStatus status; GST_DEBUG("surface 0x%08x", priv->surface_id); if (priv->surface_id != VA_INVALID_SURFACE) { - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_DISPLAY_LOCK(display); status = vaDestroySurfaces( - GST_VAAPI_DISPLAY_VADISPLAY(priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), &priv->surface_id, 1 ); - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaDestroySurfaces()")) g_warning("failed to destroy surface 0x%08x\n", priv->surface_id); priv->surface_id = VA_INVALID_SURFACE; @@ -89,16 +88,12 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface) g_ptr_array_free(priv->subpictures, TRUE); priv->subpictures = NULL; } - - if (priv->display) { - g_object_unref(priv->display); - priv->display = NULL; - } } static gboolean gst_vaapi_surface_create(GstVaapiSurface *surface) { + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); GstVaapiSurfacePrivate * const priv = surface->priv; VASurfaceID surface_id; VAStatus status; @@ -119,15 +114,15 @@ gst_vaapi_surface_create(GstVaapiSurface *surface) return FALSE; } - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_DISPLAY_LOCK(display); status = vaCreateSurfaces( - GST_VAAPI_DISPLAY_VADISPLAY(priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), priv->width, priv->height, format, 1, &surface_id ); - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaCreateSurfaces()")) return FALSE; @@ -156,9 +151,6 @@ gst_vaapi_surface_set_property( GstVaapiSurfacePrivate * const priv = surface->priv; switch (prop_id) { - case PROP_DISPLAY: - priv->display = g_object_ref(g_value_get_object(value)); - break; case PROP_WIDTH: priv->width = g_value_get_uint(value); break; @@ -185,9 +177,6 @@ gst_vaapi_surface_get_property( GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); switch (prop_id) { - case PROP_DISPLAY: - g_value_set_object(value, gst_vaapi_surface_get_display(surface)); - break; case PROP_SURFACE_ID: g_value_set_uint(value, gst_vaapi_surface_get_id(surface)); break; @@ -231,20 +220,6 @@ gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass) object_class->get_property = gst_vaapi_surface_get_property; object_class->constructed = gst_vaapi_surface_constructed; - /** - * GstVaapiSurface:display: - * - * The #GstVaapiDisplay this surface is bound to. - */ - g_object_class_install_property - (object_class, - PROP_DISPLAY, - g_param_spec_object("display", - "Display", - "The GstVaapiDisplay this surface is bound to", - GST_VAAPI_TYPE_DISPLAY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - /** * GstVaapiSurface:id: * @@ -293,7 +268,6 @@ gst_vaapi_surface_init(GstVaapiSurface *surface) GstVaapiSurfacePrivate *priv = GST_VAAPI_SURFACE_GET_PRIVATE(surface); surface->priv = priv; - priv->display = NULL; priv->surface_id = VA_INVALID_SURFACE; priv->width = 0; priv->height = 0; @@ -347,22 +321,6 @@ gst_vaapi_surface_get_id(GstVaapiSurface *surface) return surface->priv->surface_id; } -/** - * gst_vaapi_surface_get_display: - * @surface: a #GstVaapiSurface - * - * Returns the #GstVaapiDisplay this @surface is bound to. - * - * Return value: the parent #GstVaapiDisplay object - */ -GstVaapiDisplay * -gst_vaapi_surface_get_display(GstVaapiSurface *surface) -{ - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - - return surface->priv->display; -} - /** * gst_vaapi_surface_get_chroma_type: * @surface: a #GstVaapiSurface @@ -462,27 +420,29 @@ gst_vaapi_surface_get_size( GstVaapiImage * gst_vaapi_surface_derive_image(GstVaapiSurface *surface) { + GstVaapiDisplay *display; VAImage va_image; VAStatus status; g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); + display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); va_image.image_id = VA_INVALID_ID; va_image.buf = VA_INVALID_ID; - GST_VAAPI_DISPLAY_LOCK(surface->priv->display); + GST_VAAPI_DISPLAY_LOCK(display); status = vaDeriveImage( - GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), surface->priv->surface_id, &va_image ); - GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaDeriveImage()")) return NULL; if (va_image.image_id == VA_INVALID_ID || va_image.buf == VA_INVALID_ID) return NULL; - return gst_vaapi_image_new_with_image(surface->priv->display, &va_image); + return gst_vaapi_image_new_with_image(display, &va_image); } /** @@ -498,6 +458,7 @@ gst_vaapi_surface_derive_image(GstVaapiSurface *surface) gboolean gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) { + GstVaapiDisplay *display; VAImageID image_id; VAStatus status; guint width, height; @@ -505,6 +466,10 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + if (!display) + return FALSE; + gst_vaapi_image_get_size(image, &width, &height); if (width != surface->priv->width || height != surface->priv->height) return FALSE; @@ -513,14 +478,14 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) if (image_id == VA_INVALID_ID) return FALSE; - GST_VAAPI_DISPLAY_LOCK(surface->priv->display); + GST_VAAPI_DISPLAY_LOCK(display); status = vaGetImage( - GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), surface->priv->surface_id, 0, 0, width, height, image_id ); - GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaGetImage()")) return FALSE; @@ -540,6 +505,7 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) gboolean gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) { + GstVaapiDisplay *display; VAImageID image_id; VAStatus status; guint width, height; @@ -547,6 +513,10 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + if (!display) + return FALSE; + gst_vaapi_image_get_size(image, &width, &height); if (width != surface->priv->width || height != surface->priv->height) return FALSE; @@ -555,15 +525,15 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) if (image_id == VA_INVALID_ID) return FALSE; - GST_VAAPI_DISPLAY_LOCK(surface->priv->display); + GST_VAAPI_DISPLAY_LOCK(display); status = vaPutImage( - GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), surface->priv->surface_id, image_id, 0, 0, width, height, 0, 0, width, height ); - GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaPutImage()")) return FALSE; @@ -596,6 +566,7 @@ gst_vaapi_surface_associate_subpicture( const GstVaapiRectangle *dst_rect ) { + GstVaapiDisplay *display; GstVaapiRectangle src_rect_default, dst_rect_default; GstVaapiImage *image; VAStatus status; @@ -603,6 +574,10 @@ gst_vaapi_surface_associate_subpicture( g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); + display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + if (!display) + return FALSE; + if (!gst_vaapi_surface_deassociate_subpicture(surface, subpicture)) return FALSE; @@ -634,16 +609,16 @@ gst_vaapi_surface_associate_subpicture( dst_rect_default.height = surface->priv->height; } - GST_VAAPI_DISPLAY_LOCK(surface->priv->display); + GST_VAAPI_DISPLAY_LOCK(display); status = vaAssociateSubpicture( - GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), gst_vaapi_subpicture_get_id(subpicture), &surface->priv->surface_id, 1, src_rect->x, src_rect->y, src_rect->width, src_rect->height, dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height, 0 ); - GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaAssociateSubpicture()")) return FALSE; @@ -666,11 +641,16 @@ gst_vaapi_surface_deassociate_subpicture( GstVaapiSubpicture *subpicture ) { + GstVaapiDisplay *display; VAStatus status; g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); + display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + if (!display) + return FALSE; + if (!surface->priv->subpictures) return TRUE; @@ -682,13 +662,13 @@ gst_vaapi_surface_deassociate_subpicture( return TRUE; } - GST_VAAPI_DISPLAY_LOCK(surface->priv->display); + GST_VAAPI_DISPLAY_LOCK(display); status = vaDeassociateSubpicture( - GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), gst_vaapi_subpicture_get_id(subpicture), &surface->priv->surface_id, 1 ); - GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); g_object_unref(subpicture); if (!vaapi_check_status(status, "vaDeassociateSubpicture()")) return FALSE; @@ -707,16 +687,21 @@ gst_vaapi_surface_deassociate_subpicture( gboolean gst_vaapi_surface_sync(GstVaapiSurface *surface) { + GstVaapiDisplay *display; VAStatus status; g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - GST_VAAPI_DISPLAY_LOCK(surface->priv->display); + display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + if (!display) + return FALSE; + + GST_VAAPI_DISPLAY_LOCK(display); status = vaSyncSurface( - GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), + GST_VAAPI_DISPLAY_VADISPLAY(display), surface->priv->surface_id ); - GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display); + GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaSyncSurface()")) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 2a8d722ef3..db92955539 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -21,7 +21,7 @@ #ifndef GST_VAAPI_SURFACE_H #define GST_VAAPI_SURFACE_H -#include +#include #include #include #include @@ -107,7 +107,7 @@ typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; */ struct _GstVaapiSurface { /*< private >*/ - GObject parent_instance; + GstVaapiObject parent_instance; GstVaapiSurfacePrivate *priv; }; @@ -119,7 +119,7 @@ struct _GstVaapiSurface { */ struct _GstVaapiSurfaceClass { /*< private >*/ - GObjectClass parent_class; + GstVaapiObjectClass parent_class; }; GType @@ -136,9 +136,6 @@ gst_vaapi_surface_new( VASurfaceID gst_vaapi_surface_get_id(GstVaapiSurface *surface); -GstVaapiDisplay * -gst_vaapi_surface_get_display(GstVaapiSurface *surface); - GstVaapiChromaType gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 46551cb501..50bd6fcb6f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -399,7 +399,7 @@ gst_vaapi_window_x11_render( VASurfaceID surface_id; VAStatus status; - display = gst_vaapi_surface_get_display(surface); + display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); if (!display) return FALSE; From 2e0112b882665b8b22bfddad81faa3b02dfeaff8 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 16:25:20 +0000 Subject: [PATCH 0146/3781] Improve gst-plugins-vaapi Library reference template. --- docs/reference/libs/libs-docs.xml.in | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index af58e673c9..2bd67ca3dc 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -4,13 +4,10 @@ GStreamer VA-API Plugins @GST_MAJORMINOR@ Library Reference Manual - - for GStreamer VA-API Library @GST_MAJORMINOR@ (@PACKAGE_VERSION@) - - GStreamer VA-API Plugins Library + gst-plugins-vaapi Library @@ -26,6 +23,17 @@ - + + + Object Hierarchy + + + + + API Index + + + + From e403f26bc53661bc95c9e0c350618b8b6f492342 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 17:12:40 +0000 Subject: [PATCH 0147/3781] Add "destroy" signal. --- configure.ac | 1 + docs/reference/libs/libs.types | 1 + gst-libs/gst/vaapi/Makefile.am | 34 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapimarshal.list | 1 + gst-libs/gst/vaapi/gstvaapiobject.c | 44 ++++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiobject.h | 4 +++ tests/test-surfaces.c | 12 +++++++ 7 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 gst-libs/gst/vaapi/gstvaapimarshal.list diff --git a/configure.ac b/configure.ac index a478004b26..cc3d591237 100644 --- a/configure.ac +++ b/configure.ac @@ -103,6 +103,7 @@ AM_CONDITIONAL([BUILD_GTK_DOC], [test "x$enable_gtk_doc" = "xyes"]) AC_SUBST(GTKDOC_VERSION) dnl Check for GLib +AC_PATH_PROG([GLIB_GENMARSHAL], [glib-genmarshal]) PKG_CHECK_MODULES([GLIB], [glib-2.0]) AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LIBS) diff --git a/docs/reference/libs/libs.types b/docs/reference/libs/libs.types index 3efeb0a7d8..ebc148dc13 100644 --- a/docs/reference/libs/libs.types +++ b/docs/reference/libs/libs.types @@ -1,3 +1,4 @@ +gst_vaapi_object_get_type gst_vaapi_surface_pool_get_type gst_vaapi_video_pool_get_type gst_vaapi_video_sink_get_type diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 051ef82b55..8260bdbfa1 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -11,6 +11,7 @@ libgstvaapi_source_c = \ gstvaapiimage.c \ gstvaapiimageformat.c \ gstvaapiimagepool.c \ + gstvaapimarshal.c \ gstvaapiobject.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ @@ -112,3 +113,36 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_LIBADD = \ # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in + +# glib-genmarshal rules +glib_marshal_list = gstvaapimarshal.list +glib_marshal_prefix = gst_vaapi_marshal + +marshal_h = $(glib_marshal_list:.list=.h) +marshal_c = $(glib_marshal_list:.list=.c) + +CLEANFILES = stamp-marshal +DISTCLEANFILES = $(marshal_h) $(marshal_c) +BUILT_SOURCES = $(marshal_h) $(marshal_c) +EXTRA_DIST = $(srcdir)/$(glib_marshal_list) + +stamp-marshal: $(glib_marshal_list) + $(GLIB_GENMARSHAL) \ + --prefix=$(glib_marshal_prefix) \ + --header \ + $(srcdir)/$(glib_marshal_list) > xgen-mh \ + && (cmp -s xgen-mh $(marshal_h) || cp -f xgen-mh $(marshal_h)) \ + && rm -f xgen-mh \ + && echo timestamp > $(@F) + +$(marshal_h): stamp-marshal + @true + +$(marshal_c): $(marshal_h) + (echo "#include \"$(marshal_h)\"" ; \ + $(GLIB_GENMARSHAL) \ + --prefix=$(glib_marshal_prefix) \ + --body \ + $(srcdir)/$(glib_marshal_list)) > xgen-mc \ + && cp xgen-mc $(marshal_c) \ + && rm -f xgen-mc diff --git a/gst-libs/gst/vaapi/gstvaapimarshal.list b/gst-libs/gst/vaapi/gstvaapimarshal.list new file mode 100644 index 0000000000..5b76282c96 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapimarshal.list @@ -0,0 +1 @@ +VOID:VOID diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index cee67b55cc..aad44fa6a1 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -20,7 +20,7 @@ #include "config.h" #include "gstvaapiobject.h" - +#include "gstvaapimarshal.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -34,6 +34,7 @@ G_DEFINE_TYPE(GstVaapiObject, gst_vaapi_object, G_TYPE_OBJECT); struct _GstVaapiObjectPrivate { GstVaapiDisplay *display; + guint is_destroying : 1; }; enum { @@ -42,6 +43,28 @@ enum { PROP_DISPLAY, }; +enum { + DESTROY, + + LAST_SIGNAL +}; + +static guint object_signals[LAST_SIGNAL] = { 0, }; + +static void +gst_vaapi_object_dispose(GObject *object) +{ + GstVaapiObjectPrivate * const priv = GST_VAAPI_OBJECT(object)->priv; + + if (!priv->is_destroying) { + priv->is_destroying = TRUE; + g_signal_emit(object, object_signals[DESTROY], 0); + priv->is_destroying = FALSE; + } + + G_OBJECT_CLASS(gst_vaapi_object_parent_class)->dispose(object); +} + static void gst_vaapi_object_finalize(GObject *object) { @@ -102,6 +125,7 @@ gst_vaapi_object_class_init(GstVaapiObjectClass *klass) g_type_class_add_private(klass, sizeof(GstVaapiObjectPrivate)); + object_class->dispose = gst_vaapi_object_dispose; object_class->finalize = gst_vaapi_object_finalize; object_class->set_property = gst_vaapi_object_set_property; object_class->get_property = gst_vaapi_object_get_property; @@ -119,6 +143,23 @@ gst_vaapi_object_class_init(GstVaapiObjectClass *klass) "The GstVaapiDisplay this object is bound to", GST_VAAPI_TYPE_DISPLAY, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + /** + * GstVaapiObject::destroy: + * @object: the object which received the signal + * + * The ::destroy signal is emitted when an object is destroyed, + * when the user released the last reference to @object. + */ + object_signals[DESTROY] = g_signal_new( + "destroy", + G_TYPE_FROM_CLASS(object_class), + G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + G_STRUCT_OFFSET(GstVaapiObjectClass, destroy), + NULL, NULL, + gst_vaapi_marshal_VOID__VOID, + G_TYPE_NONE, 0 + ); } static void @@ -128,6 +169,7 @@ gst_vaapi_object_init(GstVaapiObject *object) object->priv = priv; priv->display = NULL; + priv->is_destroying = FALSE; } /** diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index 45f1a6e590..5fcd13355f 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -77,12 +77,16 @@ struct _GstVaapiObject { /** * GstVaapiObjectClass: + * @destroy: signal class handler for #GstVaapiObject::destroy * * VA object base class. */ struct _GstVaapiObjectClass { /*< private >*/ GObjectClass parent_class; + + /*< public >*/ + void (*destroy)(GstVaapiObject *oject); }; GType diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index d201bdbd29..fca9f6ac47 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -24,6 +24,12 @@ #define MAX_SURFACES 4 +static void +gst_vaapi_object_destroy_cb(gpointer object, gpointer user_data) +{ + g_print("Destroying GstVaapiObject %p\n", object); +} + int main(int argc, char *argv[]) { @@ -95,6 +101,12 @@ main(int argc, char *argv[]) surfaces[i] = NULL; } + g_signal_connect( + G_OBJECT(surface), + "destroy", + G_CALLBACK(gst_vaapi_object_destroy_cb), NULL + ); + /* Unref in random order to check objects are correctly refcounted */ g_print("unref display\n"); g_object_unref(display); From dfc436db946235f051ea728988ddd3bcf61cf6a4 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 17:18:35 +0000 Subject: [PATCH 0148/3781] 0.1.1. --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 561344f4e1..a1cadd5485 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ -gst-vaapi NEWS -- summary of changes. 2010-03-22 +gst-vaapi NEWS -- summary of changes. 2010-03-23 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.1.1 - 22.Mar.2010 +Version 0.1.1 - 23.Mar.2010 * Document public API for libgstvaapi-*.so.* * Optimize `vaapiconvert' pipeline (direct-rendering) * Allow `vaapisink` to render videos in fullscreen mode From 9df9f60d6202c20c4213ea5bc14cc8db30cbacd7 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 17:29:47 +0000 Subject: [PATCH 0149/3781] Use a black background for new windows. --- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index cb9bfc8ede..46ed19097a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -79,7 +79,7 @@ x11_create_window(Display *display, guint width, guint height) xswa_mask = CWBorderPixel | CWBackPixel; xswa.border_pixel = black_pixel; - xswa.background_pixel = white_pixel; + xswa.background_pixel = black_pixel; window = XCreateWindow( display, From 33d5cf8be2edbc3f469b3d4e0f3c8eccaeba66ee Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 17:40:03 +0000 Subject: [PATCH 0150/3781] Bump version for development. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index cc3d591237..247bdf84cd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [1]) -m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_micro_version], [2]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From b2986daed45ab170df8c5fe0edce2d2eaea4dee6 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 23 Mar 2010 18:45:09 +0000 Subject: [PATCH 0151/3781] Generate upstream packages through make deb.upstream. --- Makefile.am | 19 +++++++++----- configure.ac | 26 +++++++++---------- {debian => debian.upstream}/Makefile.am | 0 {debian => debian.upstream}/changelog.in | 0 {debian => debian.upstream}/compat | 0 {debian => debian.upstream}/control.in | 0 {debian => debian.upstream}/copyright | 0 .../gstreamer-vaapi-doc.install.in | 0 .../gstreamer-vaapi.install.in | 0 .../libgstvaapi-dev.install.in | 0 .../libgstvaapi-x11.install.in | 0 .../libgstvaapi.install.in | 0 {debian => debian.upstream}/rules | 0 13 files changed, 26 insertions(+), 19 deletions(-) rename {debian => debian.upstream}/Makefile.am (100%) rename {debian => debian.upstream}/changelog.in (100%) rename {debian => debian.upstream}/compat (100%) rename {debian => debian.upstream}/control.in (100%) rename {debian => debian.upstream}/copyright (100%) rename {debian => debian.upstream}/gstreamer-vaapi-doc.install.in (100%) rename {debian => debian.upstream}/gstreamer-vaapi.install.in (100%) rename {debian => debian.upstream}/libgstvaapi-dev.install.in (100%) rename {debian => debian.upstream}/libgstvaapi-x11.install.in (100%) rename {debian => debian.upstream}/libgstvaapi.install.in (100%) rename {debian => debian.upstream}/rules (100%) diff --git a/Makefile.am b/Makefile.am index 51370db28d..adaf6740b3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign -SUBDIRS = debian gst-libs pkgconfig sys tests docs +SUBDIRS = debian.upstream gst-libs pkgconfig sys tests docs # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ @@ -8,8 +8,15 @@ MAINTAINERCLEANFILES = \ configure depcomp install-sh ltmain.sh \ Makefile.in missing config.h.in gtk-doc.make -deb: dist - -mkdir -p debian-build - cd debian-build && \ - tar zxvf ../$(PACKAGE)-$(VERSION).tar.gz && \ - cd $(PACKAGE)-$(VERSION) && dpkg-buildpackage -rfakeroot -uc -us +DEB_BUILDDIR = debian.build + +deb: + dpkg-buildpackage -rfakeroot -uc -us + +deb.upstream: dist + -mkdir -p $(DEB_BUILDDIR) + cd $(DEB_BUILDDIR) && \ + tar zxvf ../$(PACKAGE)-$(VERSION).tar.gz && \ + cd $(PACKAGE)-$(VERSION) && \ + $(LN_S) debian.upstream debian && \ + $(MAKE) deb -f Makefile.am diff --git a/configure.ac b/configure.ac index 247bdf84cd..5d1cdfc9da 100644 --- a/configure.ac +++ b/configure.ac @@ -190,19 +190,19 @@ AC_SUBST(pkgconfigdir) AC_OUTPUT([ Makefile - debian/Makefile - debian/changelog - debian/control - debian/gstreamer$GST_MAJORMINOR-vaapi.install:\ -debian/gstreamer-vaapi.install.in - debian/gstreamer$GST_MAJORMINOR-vaapi-doc.install:\ -debian/gstreamer-vaapi-doc.install.in - debian/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:\ -debian/libgstvaapi.install.in - debian/libgstvaapi$GST_VAAPI_MAJOR_VERSION-dev.install:\ -debian/libgstvaapi-dev.install.in - debian/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:\ -debian/libgstvaapi-x11.install.in + debian.upstream/Makefile + debian.upstream/changelog + debian.upstream/control + debian.upstream/gstreamer$GST_MAJORMINOR-vaapi.install:\ +debian.upstream/gstreamer-vaapi.install.in + debian.upstream/gstreamer$GST_MAJORMINOR-vaapi-doc.install:\ +debian.upstream/gstreamer-vaapi-doc.install.in + debian.upstream/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:\ +debian.upstream/libgstvaapi.install.in + debian.upstream/libgstvaapi$GST_VAAPI_MAJOR_VERSION-dev.install:\ +debian.upstream/libgstvaapi-dev.install.in + debian.upstream/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:\ +debian.upstream/libgstvaapi-x11.install.in docs/Makefile docs/reference/Makefile docs/reference/libs/Makefile diff --git a/debian/Makefile.am b/debian.upstream/Makefile.am similarity index 100% rename from debian/Makefile.am rename to debian.upstream/Makefile.am diff --git a/debian/changelog.in b/debian.upstream/changelog.in similarity index 100% rename from debian/changelog.in rename to debian.upstream/changelog.in diff --git a/debian/compat b/debian.upstream/compat similarity index 100% rename from debian/compat rename to debian.upstream/compat diff --git a/debian/control.in b/debian.upstream/control.in similarity index 100% rename from debian/control.in rename to debian.upstream/control.in diff --git a/debian/copyright b/debian.upstream/copyright similarity index 100% rename from debian/copyright rename to debian.upstream/copyright diff --git a/debian/gstreamer-vaapi-doc.install.in b/debian.upstream/gstreamer-vaapi-doc.install.in similarity index 100% rename from debian/gstreamer-vaapi-doc.install.in rename to debian.upstream/gstreamer-vaapi-doc.install.in diff --git a/debian/gstreamer-vaapi.install.in b/debian.upstream/gstreamer-vaapi.install.in similarity index 100% rename from debian/gstreamer-vaapi.install.in rename to debian.upstream/gstreamer-vaapi.install.in diff --git a/debian/libgstvaapi-dev.install.in b/debian.upstream/libgstvaapi-dev.install.in similarity index 100% rename from debian/libgstvaapi-dev.install.in rename to debian.upstream/libgstvaapi-dev.install.in diff --git a/debian/libgstvaapi-x11.install.in b/debian.upstream/libgstvaapi-x11.install.in similarity index 100% rename from debian/libgstvaapi-x11.install.in rename to debian.upstream/libgstvaapi-x11.install.in diff --git a/debian/libgstvaapi.install.in b/debian.upstream/libgstvaapi.install.in similarity index 100% rename from debian/libgstvaapi.install.in rename to debian.upstream/libgstvaapi.install.in diff --git a/debian/rules b/debian.upstream/rules similarity index 100% rename from debian/rules rename to debian.upstream/rules From 755f198a74ab2592c03c4a58330a5ab6193163ad Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 08:16:32 +0000 Subject: [PATCH 0152/3781] Fix short descriptions. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 4 ++-- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiimage.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiimageformat.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiimagepool.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiobject.c | 5 +++++ gst-libs/gst/vaapi/gstvaapisubpicture.c | 4 ++-- gst-libs/gst/vaapi/gstvaapisurface.c | 4 ++-- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 4 ++-- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 4 ++-- gst-libs/gst/vaapi/gstvaapivideopool.c | 4 ++-- gst-libs/gst/vaapi/gstvaapivideosink.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 4 ++-- 14 files changed, 30 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index eb06ac068c..fa9142ed3f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-display - * @short_description: + * SECTION:gstvaapidisplay + * @short_description: VA display abstraction */ #include "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 5553f88b07..a1e34793bb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-display-x11 - * @short_description: + * SECTION:gstvaapidisplay_x11 + * @short_description: VA/X11 display abstraction */ #include "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index b612a10887..21068c26e1 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-image - * @short_description: + * SECTION:gstvaapiimage + * @short_description: VA image abstraction */ #include "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 9903190414..bf52dee006 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-image-format - * @short_description: + * SECTION:gstvaapiimageformat + * @short_description: VA image format abstraction */ #include "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 435140be98..1bdd05936d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-image-pool - * @short_description: + * SECTION:gstvaapiimagepool + * @short_description: VA image pool */ #include "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index aad44fa6a1..0a8853d446 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gstvaapiobject + * @short_description: Base VA object + */ + #include "config.h" #include "gstvaapiobject.h" #include "gstvaapimarshal.h" diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index ca7e57b9a0..f2ae92b129 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-subpicture - * @short_description: + * SECTION:gstvaapisubpicture + * @short_description: VA subpicture abstraction */ #include "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 4b20068beb..d605468f3b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-surface - * @short_description: + * SECTION:gstvaapisurface + * @short_description: VA surface abstraction */ #include "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 1b6f0e94dc..a151b0fd90 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-surface-pool - * @short_description: + * SECTION:gstvaapisurfacepool + * @short_description: VA surface pool */ #include "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 9578df27d4..d40b9de334 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-video-buffer - * @short_description: + * SECTION:gstvaapivideobuffer + * @short_description: VA video buffer for GStreamer */ #include "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index fb78dabc9f..55936125cd 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-video-pool - * @short_description: + * SECTION:gstvaapivideopool + * @short_description: Video object pool abstraction */ #include "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.c b/gst-libs/gst/vaapi/gstvaapivideosink.c index 5df81a7222..ab4e4524e2 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.c +++ b/gst-libs/gst/vaapi/gstvaapivideosink.c @@ -19,7 +19,7 @@ */ /** - * SECTION:gst-vaapi-video-sink: + * SECTION:gstvaapivideosink * @short_description: An interface for implementing VA-API sink elements */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 86aeb95c46..aac518f36f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-window - * @short_description: + * SECTION:gstvaapiwindow + * @short_description: VA window abstraction */ #include "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 50bd6fcb6f..f1fb0a5686 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -19,8 +19,8 @@ */ /** - * SECTION:gst-vaapi-window-x11 - * @short_description: + * SECTION:gstvaapiwindow_x11 + * @short_description: VA/X11 window abstraction */ #include "config.h" From b8b82d333777d3025160114763135816cfc28adb Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 08:32:12 +0000 Subject: [PATCH 0153/3781] Move private definitions and accessors to gstvaapiobject_priv.h. --- gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapiimage.c | 1 + gst-libs/gst/vaapi/gstvaapiobject.c | 11 +---- gst-libs/gst/vaapi/gstvaapiobject.h | 9 ---- gst-libs/gst/vaapi/gstvaapiobject_priv.h | 54 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisubpicture.c | 1 + gst-libs/gst/vaapi/gstvaapisurface.c | 1 + gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 1 + 8 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiobject_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 8260bdbfa1..d5148c33fd 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -41,6 +41,7 @@ libgstvaapi_source_h = \ libgstvaapi_source_priv_h = \ gstvaapidebug.h \ + gstvaapiobject_priv.h \ gstvaapiutils.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 21068c26e1..d6d0a401d0 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -27,6 +27,7 @@ #include #include "gstvaapiutils.h" #include "gstvaapiimage.h" +#include "gstvaapiobject_priv.h" #include #define DEBUG 1 diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 0a8853d446..edb961b8a3 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -25,6 +25,7 @@ #include "config.h" #include "gstvaapiobject.h" +#include "gstvaapiobject_priv.h" #include "gstvaapimarshal.h" #define DEBUG 1 @@ -32,16 +33,6 @@ G_DEFINE_TYPE(GstVaapiObject, gst_vaapi_object, G_TYPE_OBJECT); -#define GST_VAAPI_OBJECT_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_OBJECT, \ - GstVaapiObjectPrivate)) - -struct _GstVaapiObjectPrivate { - GstVaapiDisplay *display; - guint is_destroying : 1; -}; - enum { PROP_0, diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index 5fcd13355f..2c1071094d 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -50,15 +50,6 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_OBJECT, \ GstVaapiObjectClass)) -/** - * GST_VAAPI_OBJECT_GET_DISPLAY: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the #GstVaapiDisplay @object is bound to. - */ -#define GST_VAAPI_OBJECT_GET_DISPLAY(object) \ - gst_vaapi_object_get_display(GST_VAAPI_OBJECT(object)) - typedef struct _GstVaapiObject GstVaapiObject; typedef struct _GstVaapiObjectPrivate GstVaapiObjectPrivate; typedef struct _GstVaapiObjectClass GstVaapiObjectClass; diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h new file mode 100644 index 0000000000..1e38ba8733 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -0,0 +1,54 @@ +/* + * gstvaapiobject_priv.h - Base VA object (private definitions) + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_OBJECT_PRIV_H +#define GST_VAAPI_OBJECT_PRIV_H + +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_OBJECT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_OBJECT, \ + GstVaapiObjectPrivate)) + +/** + * GST_VAAPI_OBJECT_GET_DISPLAY: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the #GstVaapiDisplay @object is bound to. + */ +#define GST_VAAPI_OBJECT_GET_DISPLAY(object) \ + gst_vaapi_object_get_display(GST_VAAPI_OBJECT(object)) + +/** + * GstVaapiObjectPrivate: + * + * VA object base. + */ +struct _GstVaapiObjectPrivate { + GstVaapiDisplay *display; + guint is_destroying : 1; +}; + +G_END_DECLS + +#endif /* GST_VAAPI_OBJECT_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index f2ae92b129..a78e713410 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -27,6 +27,7 @@ #include #include "gstvaapiutils.h" #include "gstvaapisubpicture.h" +#include "gstvaapiobject_priv.h" #include #define DEBUG 1 diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index d605468f3b..34fbb6afe1 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -27,6 +27,7 @@ #include "gstvaapiutils.h" #include "gstvaapisurface.h" #include "gstvaapiimage.h" +#include "gstvaapiobject_priv.h" #include #define DEBUG 1 diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index f1fb0a5686..fd57c652fa 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -29,6 +29,7 @@ #include "gstvaapiwindow_x11.h" #include "gstvaapidisplay_x11.h" #include "gstvaapiutils_x11.h" +#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" From 9233fcf6765e8f0e59614f251354daeb77d10785 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 08:34:11 +0000 Subject: [PATCH 0154/3781] Optimize GST_VAAPI_OBJECT_GET_DISPLAY to avoid a run-time check. --- gst-libs/gst/vaapi/gstvaapiobject_priv.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 1e38ba8733..41664d73ca 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -35,9 +35,10 @@ G_BEGIN_DECLS * @object: a #GstVaapiObject * * Macro that evaluates to the #GstVaapiDisplay @object is bound to. + * This is an internal macro that does not do any run-time type checks. */ #define GST_VAAPI_OBJECT_GET_DISPLAY(object) \ - gst_vaapi_object_get_display(GST_VAAPI_OBJECT(object)) + (((GstVaapiObject *)(object))->priv->display) /** * GstVaapiObjectPrivate: From 63add8fd6306753186b2d6e9a6e3cbc46793f124 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 08:35:27 +0000 Subject: [PATCH 0155/3781] Drop useless include (). --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 - gst-libs/gst/vaapi/gstvaapiimage.c | 1 - gst-libs/gst/vaapi/gstvaapisubpicture.c | 1 - gst-libs/gst/vaapi/gstvaapisurface.c | 1 - 4 files changed, 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index fa9142ed3f..1ef23e497f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -26,7 +26,6 @@ #include "config.h" #include "gstvaapiutils.h" #include "gstvaapidisplay.h" -#include #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index d6d0a401d0..ea2168ef44 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -28,7 +28,6 @@ #include "gstvaapiutils.h" #include "gstvaapiimage.h" #include "gstvaapiobject_priv.h" -#include #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index a78e713410..707ce45b21 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -28,7 +28,6 @@ #include "gstvaapiutils.h" #include "gstvaapisubpicture.h" #include "gstvaapiobject_priv.h" -#include #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 34fbb6afe1..107a78184d 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -28,7 +28,6 @@ #include "gstvaapisurface.h" #include "gstvaapiimage.h" #include "gstvaapiobject_priv.h" -#include #define DEBUG 1 #include "gstvaapidebug.h" From 28afdd6f83b2d83d61f3dd01d57fa480aca813c7 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 09:22:00 +0000 Subject: [PATCH 0156/3781] Sort types. --- docs/reference/libs/libs.types | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/reference/libs/libs.types b/docs/reference/libs/libs.types index ebc148dc13..3d7aca2ae3 100644 --- a/docs/reference/libs/libs.types +++ b/docs/reference/libs/libs.types @@ -1,13 +1,13 @@ +gst_vaapi_display_get_type +gst_vaapi_display_x11_get_type +gst_vaapi_image_get_type +gst_vaapi_image_pool_get_type gst_vaapi_object_get_type +gst_vaapi_subpicture_get_type +gst_vaapi_surface_get_type gst_vaapi_surface_pool_get_type +gst_vaapi_video_buffer_get_type gst_vaapi_video_pool_get_type gst_vaapi_video_sink_get_type -gst_vaapi_display_x11_get_type -gst_vaapi_window_x11_get_type -gst_vaapi_display_get_type -gst_vaapi_image_pool_get_type -gst_vaapi_video_buffer_get_type gst_vaapi_window_get_type -gst_vaapi_image_get_type -gst_vaapi_surface_get_type -gst_vaapi_subpicture_get_type +gst_vaapi_window_x11_get_type From 647621cf3c272891565e2c4c7bdf90da257d21f6 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 09:52:43 +0000 Subject: [PATCH 0157/3781] Add GstVaapiID abstraction. --- docs/reference/libs/libs-sections.txt | 3 + docs/reference/libs/libs.types | 1 + gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapitypes.c | 164 ++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapitypes.h | 53 ++++++++- 5 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapitypes.c diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index d512dd96f7..bc0f2841c6 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -158,6 +158,9 @@ GST_VAAPI_VIDEO_BUFFER_GET_CLASS
gstvaapitypes Basic data structures +GstVaapiID +gst_vaapi_value_get_id +gst_vaapi_value_set_id GstVaapiPoint GstVaapiRectangle
diff --git a/docs/reference/libs/libs.types b/docs/reference/libs/libs.types index 3d7aca2ae3..6678c0d8a7 100644 --- a/docs/reference/libs/libs.types +++ b/docs/reference/libs/libs.types @@ -1,5 +1,6 @@ gst_vaapi_display_get_type gst_vaapi_display_x11_get_type +gst_vaapi_id_get_type gst_vaapi_image_get_type gst_vaapi_image_pool_get_type gst_vaapi_object_get_type diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index d5148c33fd..0b3cb93743 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -16,6 +16,7 @@ libgstvaapi_source_c = \ gstvaapisubpicture.c \ gstvaapisurface.c \ gstvaapisurfacepool.c \ + gstvaapitypes.c \ gstvaapiutils.c \ gstvaapivideobuffer.c \ gstvaapivideopool.c \ diff --git a/gst-libs/gst/vaapi/gstvaapitypes.c b/gst-libs/gst/vaapi/gstvaapitypes.c new file mode 100644 index 0000000000..7a18995ad2 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapitypes.c @@ -0,0 +1,164 @@ +/* + * gstvaapitypes.h - Basic types + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * SECTION:gstvaapitypes + * @short_description: Basic types + */ + +#include "config.h" +#include +#include +#include "gstvaapitypes.h" + +#if GST_VAAPI_TYPE_ID_SIZE == 4 +# define GST_VAAPI_VALUE_ID_(cvalue) ((cvalue).v_int) +# define GST_VAAPI_VALUE_ID_CFORMAT "i" +#elif GST_VAAPI_TYPE_ID_SIZE == 8 +# define GST_VAAPI_VALUE_ID_(cvalue) ((cvalue).v_int64) +# define GST_VAAPI_VALUE_ID_CFORMAT "q" +#else +# error "unsupported GstVaapiID size" +#endif +#define GST_VAAPI_VALUE_ID(value) GST_VAAPI_VALUE_ID_((value)->data[0]) + +static void +gst_vaapi_value_id_init(GValue *value) +{ + GST_VAAPI_VALUE_ID(value) = 0; +} + +static void +gst_vaapi_value_id_copy(const GValue *src_value, GValue *dst_value) +{ + GST_VAAPI_VALUE_ID(dst_value) = GST_VAAPI_VALUE_ID(src_value); +} + +static gchar * +gst_vaapi_value_id_collect( + GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags +) +{ + GST_VAAPI_VALUE_ID(value) = GST_VAAPI_VALUE_ID_(collect_values[0]); + + return NULL; +} + +static gchar * +gst_vaapi_value_id_lcopy( + const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags +) +{ + GstVaapiID *id_p = collect_values[0].v_pointer; + + if (!id_p) + return g_strdup_printf("value location for `%s' passed as NULL", + G_VALUE_TYPE_NAME(value)); + + *id_p = GST_VAAPI_VALUE_ID(value); + return NULL; +} + +static GTypeInfo gst_vaapi_type_info = { + 0, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + NULL, + NULL, +}; + +static GTypeFundamentalInfo gst_vaapi_type_finfo = { + 0 +}; + +#define GST_VAAPI_TYPE_DEFINE(type, name) \ +GType gst_vaapi_ ## type ## _get_type(void) \ +{ \ + static GType gst_vaapi_ ## type ## _type = 0; \ + \ + if (G_UNLIKELY(gst_vaapi_ ## type ## _type == 0)) { \ + gst_vaapi_type_info.value_table = \ + &gst_vaapi_ ## type ## _value_table; \ + gst_vaapi_ ## type ## _type = g_type_register_fundamental( \ + g_type_fundamental_next(), \ + name, \ + &gst_vaapi_type_info, \ + &gst_vaapi_type_finfo, \ + 0 \ + ); \ + } \ + \ + return gst_vaapi_ ## type ## _type; \ +} + +static const GTypeValueTable gst_vaapi_id_value_table = { + gst_vaapi_value_id_init, + NULL, + gst_vaapi_value_id_copy, + NULL, + GST_VAAPI_VALUE_ID_CFORMAT, + gst_vaapi_value_id_collect, + "p", + gst_vaapi_value_id_lcopy +}; + +GST_VAAPI_TYPE_DEFINE(id, "GstVaapiID"); + +/** + * gst_vaapi_value_get_id: + * @value: a GValue initialized to #GstVaapiID + * + * Gets the integer contained in @value. + * + * Return value: the integer contained in @value + */ +GstVaapiID +gst_vaapi_value_get_id(const GValue *value) +{ + g_return_val_if_fail(GST_VAAPI_VALUE_HOLDS_ID(value), 0); + + return GST_VAAPI_VALUE_ID(value); +} + +/** + * gst_vaapi_value_set_id: + * @value: a GValue initialized to #GstVaapiID + * @id: a #GstVaapiID + * + * Sets the integer contained in @id to @value. + */ +void +gst_vaapi_value_set_id(GValue *value, GstVaapiID id) +{ + g_return_if_fail(GST_VAAPI_VALUE_HOLDS_ID(value)); + + GST_VAAPI_VALUE_ID(value) = id; +} diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 97dd598ec4..57b8a81316 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -1,5 +1,5 @@ /* - * gstvaapitypes.h - Misc types + * gstvaapitypes.h - Basic types * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * @@ -21,10 +21,59 @@ #ifndef GST_VAAPI_TYPES_H #define GST_VAAPI_TYPES_H -#include +#include G_BEGIN_DECLS +/** + * GstVaapiID: + * + * An integer large enough to hold a generic VA id or a pointer + * wherever necessary. + */ +#if defined(GLIB_SIZEOF_VOID_P) +# define GST_VAAPI_TYPE_ID_SIZE GLIB_SIZEOF_VOID_P +#elif G_MAXULONG == 0xffffffff +# define GST_VAAPI_TYPE_ID_SIZE 4 +#elif G_MAXULONG == 0xffffffffffffffffull +# define GST_VAAPI_TYPE_ID_SIZE 8 +#else +# error "could not determine size of GstVaapiID" +#endif +#if GST_VAAPI_TYPE_ID_SIZE == 4 +typedef guint32 GstVaapiID; +#elif GST_VAAPI_TYPE_ID_SIZE == 8 +typedef guint64 GstVaapiID; +#else +# error "unsupported value for GST_VAAPI_TYPE_ID_SIZE" +#endif + +/** + * GST_VAAPI_TYPE_ID: + * + * A #GValue type that represents a VA identifier. + * + * Return value: the #GType of GstVaapiID + */ +#define GST_VAAPI_TYPE_ID gst_vaapi_id_get_type() + +/** + * GST_VAAPI_VALUE_HOLDS_ID: + * @x: the #GValue to check + * + * Checks if the given #GValue contains a #GstVaapiID value. + */ +#define GST_VAAPI_VALUE_HOLDS_ID(x) (G_VALUE_HOLDS((x), GST_VAAPI_TYPE_ID)) + +GType +gst_vaapi_id_get_type(void); + +GstVaapiID +gst_vaapi_value_get_id(const GValue *value); + +void +gst_vaapi_value_set_id(GValue *value, GstVaapiID id); + /** * GstVaapiPoint: * @x: X coordinate From a09c84b04dd0f50b334cf2fc1e9673c35a674d47 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 12:38:40 +0000 Subject: [PATCH 0158/3781] Add GST_VAAPI_ID_FORMAT() and GST_VAAPI_ID_ARGS() helpers. --- docs/reference/libs/libs-sections.txt | 2 ++ gst-libs/gst/vaapi/gstvaapitypes.h | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index bc0f2841c6..0b049f8710 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -159,6 +159,8 @@ GST_VAAPI_VIDEO_BUFFER_GET_CLASS gstvaapitypes Basic data structures GstVaapiID +GST_VAAPI_ID_FORMAT +GST_VAAPI_ID_ARGS gst_vaapi_value_get_id gst_vaapi_value_set_id GstVaapiPoint diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 57b8a81316..48aadd38df 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -48,6 +48,28 @@ typedef guint64 GstVaapiID; # error "unsupported value for GST_VAAPI_TYPE_ID_SIZE" #endif +/** + * GST_VAAPI_ID_FORMAT: + * + * Can be used together with #GST_VAAPI_ID_ARGS to properly output an + * integer value in a printf()-style text message. + * + * + * printf("id: %" GST_VAAPI_ID_FORMAT "\n", GST_VAAPI_ID_ARGS(id)); + * + * + */ +#define GST_VAAPI_ID_FORMAT "p" + +/** + * GST_VAAPI_ID_ARGS: + * @id: a #GstVaapiID + * + * Can be used together with #GST_VAAPI_ID_FORMAT to properly output + * an integer value in a printf()-style text message. + */ +#define GST_VAAPI_ID_ARGS(id) GUINT_TO_POINTER(id) + /** * GST_VAAPI_TYPE_ID: * From f935fe4baa584a619d8302eca2f56a853c917e78 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 12:54:52 +0000 Subject: [PATCH 0159/3781] Drop gst_vaapi_id_get_type(). --- docs/reference/libs/libs.types | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/reference/libs/libs.types b/docs/reference/libs/libs.types index 6678c0d8a7..3d7aca2ae3 100644 --- a/docs/reference/libs/libs.types +++ b/docs/reference/libs/libs.types @@ -1,6 +1,5 @@ gst_vaapi_display_get_type gst_vaapi_display_x11_get_type -gst_vaapi_id_get_type gst_vaapi_image_get_type gst_vaapi_image_pool_get_type gst_vaapi_object_get_type From 2cbcd31488e39cfa64d2c66b446a1a389dfb55a8 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 12:57:54 +0000 Subject: [PATCH 0160/3781] Add GParamSpecs for GstVaapiID. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapiparamspecs.c | 134 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiparamspecs.h | 70 +++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiparamspecs.c create mode 100644 gst-libs/gst/vaapi/gstvaapiparamspecs.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 0b3cb93743..4b8280d700 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -13,6 +13,7 @@ libgstvaapi_source_c = \ gstvaapiimagepool.c \ gstvaapimarshal.c \ gstvaapiobject.c \ + gstvaapiparamspecs.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ gstvaapisurfacepool.c \ @@ -30,6 +31,7 @@ libgstvaapi_source_h = \ gstvaapiimageformat.h \ gstvaapiimagepool.h \ gstvaapiobject.h \ + gstvaapiparamspecs.h \ gstvaapisubpicture.h \ gstvaapisurface.h \ gstvaapisurfacepool.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.c b/gst-libs/gst/vaapi/gstvaapiparamspecs.c new file mode 100644 index 0000000000..f297a9c880 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.c @@ -0,0 +1,134 @@ +/* + * gstvaapiparamspecs.c - GParamSpecs for some of our types + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include +#include "gstvaapiparamspecs.h" + +/* --- GstVaapiParamSpecID --- */ + +static void +gst_vaapi_param_id_init(GParamSpec *pspec) +{ + GST_VAAPI_PARAM_SPEC_ID(pspec)->default_value = VA_INVALID_ID; +} + +static void +gst_vaapi_param_id_set_default(GParamSpec *pspec, GValue *value) +{ + gst_vaapi_value_set_id(value, GST_VAAPI_PARAM_SPEC_ID(pspec)->default_value); +} + +static gboolean +gst_vaapi_param_id_validate(GParamSpec *pspec, GValue *value) +{ + /* Return FALSE if everything is OK, otherwise TRUE */ + return FALSE; +} + +static gint +gst_vaapi_param_id_compare( + GParamSpec *pspec, + const GValue *value1, + const GValue *value2 +) +{ + const GstVaapiID v1 = gst_vaapi_value_get_id(value1); + const GstVaapiID v2 = gst_vaapi_value_get_id(value2); + + return (v1 < v2 ? -1 : (v1 > v2 ? 1 : 0)); +} + +GType +gst_vaapi_param_spec_id_get_type(void) +{ + static GType type; + + if (G_UNLIKELY(type == 0)) { + static GParamSpecTypeInfo pspec_info = { + sizeof(GstVaapiParamSpecID), /* instance_size */ + 0, /* n_preallocs */ + gst_vaapi_param_id_init, /* instance_init */ + G_TYPE_INVALID, /* value_type */ + NULL, /* finalize */ + gst_vaapi_param_id_set_default, /* value_set_default */ + gst_vaapi_param_id_validate, /* value_validate */ + gst_vaapi_param_id_compare, /* values_cmp */ + }; + pspec_info.value_type = GST_VAAPI_TYPE_ID; + type = g_param_type_register_static("GstVaapiParamSpecID", &pspec_info); + } + return type; +} + +/** + * gst_vaapi_param_spec_id: + * @name: canonical name of the property specified + * @nick: nick name for the property specified + * @blurb: description of the property specified + * @default_value: default value + * @flags: flags for the property specified + * + * This function creates an ID GParamSpec for use by #GstVaapiObject + * objects. This function is typically used in connection with + * g_object_class_install_property() in a GObjects's instance_init + * function. + * + * Return value: a newly created parameter specification + */ +GParamSpec * +gst_vaapi_param_spec_id( + const gchar *name, + const gchar *nick, + const gchar *blurb, + GstVaapiID default_value, + GParamFlags flags +) +{ + GstVaapiParamSpecID *ispec; + GParamSpec *pspec; + GValue value = { 0, }; + + ispec = g_param_spec_internal( + GST_VAAPI_TYPE_PARAM_ID, + name, + nick, + blurb, + flags + ); + if (!ispec) + return NULL; + + ispec->default_value = default_value; + pspec = G_PARAM_SPEC(ispec); + + /* Validate default value */ + g_value_init(&value, GST_VAAPI_TYPE_ID); + gst_vaapi_value_set_id(&value, default_value); + if (gst_vaapi_param_id_validate(pspec, &value)) { + g_param_spec_ref(pspec); + g_param_spec_sink(pspec); + g_param_spec_unref(pspec); + pspec = NULL; + } + g_value_unset(&value); + + return pspec; +} diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.h b/gst-libs/gst/vaapi/gstvaapiparamspecs.h new file mode 100644 index 0000000000..96cee242df --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.h @@ -0,0 +1,70 @@ +/* + * gstvaapiparamspecs.h - GParamSpecs for some of our types + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_PARAM_SPECS_H +#define GST_VAAPI_PARAM_SPECS_H + +#include +#include + +G_BEGIN_DECLS + +/** + * GstVaapiParamSpecID: + * @parent_instance: super class + * @default_value: default value + * + * A GParamSpec derived structure that contains the meta data for + * #GstVaapiID properties. + */ +typedef struct _GstVaapiParamSpecID GstVaapiParamSpecID; +struct _GstVaapiParamSpecID { + GParamSpec parent_instance; + + GstVaapiID default_value; +}; + +#define GST_VAAPI_TYPE_PARAM_ID \ + (gst_vaapi_param_spec_id_get_type()) + +#define GST_VAAPI_IS_PARAM_SPEC_ID(pspec) \ + (G_TYPE_CHECK_INSTANCE_TYPE((pspec), \ + GST_VAAPI_TYPE_PARAM_ID)) + +#define GST_VAAPI_PARAM_SPEC_ID(pspec) \ + (G_TYPE_CHECK_INSTANCE_CAST((pspec), \ + GST_VAAPI_TYPE_PARAM_ID, \ + GstVaapiParamSpecID)) + +GType +gst_vaapi_param_spec_id_get_type(void); + +GParamSpec * +gst_vaapi_param_spec_id( + const gchar *name, + const gchar *nick, + const gchar *blurb, + GstVaapiID default_value, + GParamFlags flags +); + +G_END_DECLS + +#endif /* GST_VAAPI_PARAM_SPECS_H */ From 1a90e11ae5305f412f2f0ec29285b6e89aaf1b7d Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 12:59:22 +0000 Subject: [PATCH 0161/3781] Cosmetics (drop extraneous empty line). --- gst-libs/gst/vaapi/gstvaapitypes.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapitypes.c b/gst-libs/gst/vaapi/gstvaapitypes.c index 7a18995ad2..42eef03314 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.c +++ b/gst-libs/gst/vaapi/gstvaapitypes.c @@ -115,7 +115,6 @@ GType gst_vaapi_ ## type ## _get_type(void) \ 0 \ ); \ } \ - \ return gst_vaapi_ ## type ## _type; \ } From a91206bbc1589db9973ba907093fc85037829d8f Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 13:19:58 +0000 Subject: [PATCH 0162/3781] Move "id" down to the GstVaapiObject base. --- docs/reference/libs/libs-sections.txt | 4 +- gst-libs/gst/vaapi/gstvaapiimage.c | 60 ++++------------ gst-libs/gst/vaapi/gstvaapiimage.h | 3 - gst-libs/gst/vaapi/gstvaapiobject.c | 41 +++++++++++ gst-libs/gst/vaapi/gstvaapiobject.h | 3 + gst-libs/gst/vaapi/gstvaapiobject_priv.h | 19 ++++- gst-libs/gst/vaapi/gstvaapisubpicture.c | 61 ++++------------ gst-libs/gst/vaapi/gstvaapisubpicture.h | 3 - gst-libs/gst/vaapi/gstvaapisurface.c | 90 +++++++++--------------- gst-libs/gst/vaapi/gstvaapisurface.h | 3 - gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- tests/test-surfaces.c | 29 +++++--- 12 files changed, 143 insertions(+), 175 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 0b049f8710..4894e5f661 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -200,6 +200,7 @@ GST_VAAPI_WINDOW_GET_CLASS GstVaapiObject GstVaapiObjectClass gst_vaapi_object_get_display +gst_vaapi_object_get_id GST_VAAPI_OBJECT GST_VAAPI_IS_OBJECT @@ -220,7 +221,6 @@ GstVaapiImage GstVaapiImageClass gst_vaapi_image_new gst_vaapi_image_new_with_image -gst_vaapi_image_get_id gst_vaapi_image_get_image gst_vaapi_image_get_format gst_vaapi_image_get_width @@ -253,7 +253,6 @@ GstVaapiSurfaceRenderFlags GstVaapiSurface GstVaapiSurfaceClass gst_vaapi_surface_new -gst_vaapi_surface_get_id gst_vaapi_surface_get_chroma_type gst_vaapi_surface_get_width gst_vaapi_surface_get_height @@ -280,7 +279,6 @@ GST_VAAPI_SURFACE_GET_CLASS GstVaapiSubpicture GstVaapiSubpictureClass gst_vaapi_subpicture_new -gst_vaapi_subpicture_get_id gst_vaapi_subpicture_get_image gst_vaapi_subpicture_set_image diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index ea2168ef44..0a354dec9c 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -56,7 +56,6 @@ enum { PROP_0, PROP_IMAGE, - PROP_IMAGE_ID, PROP_FORMAT, PROP_WIDTH, PROP_HEIGHT @@ -147,24 +146,22 @@ static void gst_vaapi_image_destroy(GstVaapiImage *image) { GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(image); - GstVaapiImagePrivate * const priv = image->priv; + VAImageID image_id; VAStatus status; _gst_vaapi_image_unmap(image); - GST_DEBUG("image 0x%08x", priv->internal_image.image_id); + image_id = GST_VAAPI_OBJECT_ID(image); + GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id)); - if (priv->internal_image.image_id != VA_INVALID_ID) { + if (image_id != VA_INVALID_ID) { GST_VAAPI_DISPLAY_LOCK(display); - status = vaDestroyImage( - GST_VAAPI_DISPLAY_VADISPLAY(display), - priv->internal_image.image_id - ); + status = vaDestroyImage(GST_VAAPI_DISPLAY_VADISPLAY(display), image_id); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaDestroyImage()")) - g_warning("failed to destroy image 0x%08x\n", - priv->internal_image.image_id); - priv->internal_image.image_id = VA_INVALID_ID; + g_warning("failed to destroy image %" GST_VAAPI_ID_FORMAT "\n", + GST_VAAPI_ID_ARGS(image_id)); + GST_VAAPI_OBJECT_ID(image) = VA_INVALID_ID; } } @@ -206,6 +203,7 @@ gst_vaapi_image_create(GstVaapiImage *image) GstVaapiImagePrivate * const priv = image->priv; GstVaapiImageFormat format = priv->format; const VAImageFormat *va_format; + VAImageID image_id; if (!priv->create_image) return (priv->image.image_id != VA_INVALID_ID && @@ -227,6 +225,7 @@ gst_vaapi_image_create(GstVaapiImage *image) return FALSE; } priv->image = priv->internal_image; + image_id = priv->image.image_id; if (priv->format != priv->internal_format) { switch (priv->format) { @@ -243,9 +242,10 @@ gst_vaapi_image_create(GstVaapiImage *image) break; } } - - GST_DEBUG("image 0x%08x", priv->image.image_id); priv->is_linear = vaapi_image_is_linear(&priv->image); + + GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id)); + GST_VAAPI_OBJECT_ID(image) = image_id; return TRUE; } @@ -304,9 +304,6 @@ gst_vaapi_image_get_property( case PROP_IMAGE: g_value_set_boxed(value, &image->priv->image); break; - case PROP_IMAGE_ID: - g_value_set_uint(value, gst_vaapi_image_get_id(image)); - break; case PROP_FORMAT: g_value_set_uint(value, gst_vaapi_image_get_format(image)); break; @@ -356,20 +353,6 @@ gst_vaapi_image_class_init(GstVaapiImageClass *klass) VAAPI_TYPE_IMAGE, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - /** - * GstVaapiImage:id: - * - * The underlying #VAImageID of the image. - */ - g_object_class_install_property - (object_class, - PROP_IMAGE_ID, - g_param_spec_uint("id", - "VA image id", - "The underlying VA image id", - 0, G_MAXUINT32, VA_INVALID_ID, - G_PARAM_READABLE)); - g_object_class_install_property (object_class, PROP_WIDTH, @@ -517,23 +500,6 @@ gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image) return image; } -/** - * gst_vaapi_image_get_id: - * @image: a #GstVaapiImage - * - * Returns the underlying VAImageID of the @image. - * - * Return value: the underlying VA image id - */ -VAImageID -gst_vaapi_image_get_id(GstVaapiImage *image) -{ - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID); - g_return_val_if_fail(image->priv->is_constructed, VA_INVALID_ID); - - return image->priv->image.image_id; -} - /** * gst_vaapi_image_get_image: * @image: a #GstVaapiImage diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index d15326722f..f333c1af22 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -116,9 +116,6 @@ gst_vaapi_image_new( GstVaapiImage * gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image); -VAImageID -gst_vaapi_image_get_id(GstVaapiImage *image); - gboolean gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image); diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index edb961b8a3..3e844c723c 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -26,6 +26,7 @@ #include "config.h" #include "gstvaapiobject.h" #include "gstvaapiobject_priv.h" +#include "gstvaapiparamspecs.h" #include "gstvaapimarshal.h" #define DEBUG 1 @@ -37,6 +38,7 @@ enum { PROP_0, PROP_DISPLAY, + PROP_ID }; enum { @@ -66,6 +68,8 @@ gst_vaapi_object_finalize(GObject *object) { GstVaapiObjectPrivate * const priv = GST_VAAPI_OBJECT(object)->priv; + priv->id = VA_INVALID_ID; + if (priv->display) { g_object_unref(priv->display); priv->display = NULL; @@ -88,6 +92,9 @@ gst_vaapi_object_set_property( case PROP_DISPLAY: object->priv->display = g_object_ref(g_value_get_object(value)); break; + case PROP_ID: + object->priv->id = gst_vaapi_value_get_id(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); break; @@ -108,6 +115,9 @@ gst_vaapi_object_get_property( case PROP_DISPLAY: g_value_set_object(value, gst_vaapi_object_get_display(object)); break; + case PROP_ID: + gst_vaapi_value_set_id(value, gst_vaapi_object_get_id(object)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); break; @@ -140,6 +150,20 @@ gst_vaapi_object_class_init(GstVaapiObjectClass *klass) GST_VAAPI_TYPE_DISPLAY, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + /** + * GstVaapiObject:id: + * + * The #GstVaapiID contained in this object. + */ + g_object_class_install_property + (object_class, + PROP_ID, + gst_vaapi_param_spec_id("id", + "ID", + "The GstVaapiID contained in this object", + VA_INVALID_ID, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + /** * GstVaapiObject::destroy: * @object: the object which received the signal @@ -165,6 +189,7 @@ gst_vaapi_object_init(GstVaapiObject *object) object->priv = priv; priv->display = NULL; + priv->id = VA_INVALID_ID; priv->is_destroying = FALSE; } @@ -183,3 +208,19 @@ gst_vaapi_object_get_display(GstVaapiObject *object) return object->priv->display; } + +/** + * gst_vaapi_object_get_id: + * @object: a #GstVaapiObject + * + * Returns the #GstVaapiID contained in the @object. + * + * Return value: the #GstVaapiID of the @object + */ +GstVaapiID +gst_vaapi_object_get_id(GstVaapiObject *object) +{ + g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), NULL); + + return object->priv->id; +} diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index 2c1071094d..877857fb1d 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -86,6 +86,9 @@ gst_vaapi_object_get_type(void); GstVaapiDisplay * gst_vaapi_object_get_display(GstVaapiObject *object); +GstVaapiID +gst_vaapi_object_get_id(GstVaapiObject *object); + G_END_DECLS #endif /* GST_VAAPI_OBJECT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 41664d73ca..aeea393ac9 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -30,15 +30,27 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_OBJECT, \ GstVaapiObjectPrivate)) +#define GST_VAAPI_OBJECT_CAST(object) ((GstVaapiObject *)(object)) + /** * GST_VAAPI_OBJECT_GET_DISPLAY: * @object: a #GstVaapiObject * - * Macro that evaluates to the #GstVaapiDisplay @object is bound to. - * This is an internal macro that does not do any run-time type checks. + * Macro that evaluates to the #GstVaapiDisplay the @object is bound to. + * This is an internal macro that does not do any run-time type check. */ #define GST_VAAPI_OBJECT_GET_DISPLAY(object) \ - (((GstVaapiObject *)(object))->priv->display) + GST_VAAPI_OBJECT_CAST(object)->priv->display + +/** + * GST_VAAPI_OBJECT_ID: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the #GstVaapiID contained in @object. + * This is an internal macro that does not do any run-time type checks. + */ +#define GST_VAAPI_OBJECT_ID(object) \ + GST_VAAPI_OBJECT_CAST(object)->priv->id /** * GstVaapiObjectPrivate: @@ -47,6 +59,7 @@ G_BEGIN_DECLS */ struct _GstVaapiObjectPrivate { GstVaapiDisplay *display; + GstVaapiID id; guint is_destroying : 1; }; diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 707ce45b21..3d964f061f 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -40,14 +40,12 @@ G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, GST_VAAPI_TYPE_OBJECT); GstVaapiSubpicturePrivate)) struct _GstVaapiSubpicturePrivate { - VASubpictureID subpicture_id; GstVaapiImage *image; }; enum { PROP_0, - PROP_SUBPICTURE_ID, PROP_IMAGE }; @@ -56,23 +54,26 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) { GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(subpicture); GstVaapiSubpicturePrivate * const priv = subpicture->priv; + VASubpictureID subpicture_id; VAStatus status; - GST_DEBUG("subpicture 0x%08x", priv->subpicture_id); + subpicture_id = GST_VAAPI_OBJECT_ID(subpicture); + GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(subpicture_id)); - if (priv->subpicture_id != VA_INVALID_ID) { + if (subpicture_id != VA_INVALID_ID) { if (display) { GST_VAAPI_DISPLAY_LOCK(display); status = vaDestroySubpicture( GST_VAAPI_DISPLAY_VADISPLAY(display), - priv->subpicture_id + subpicture_id ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaDestroySubpicture()")) - g_warning("failed to destroy subpicture 0x%08x\n", - priv->subpicture_id); + g_warning("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT "\n", + GST_VAAPI_ID_ARGS(subpicture_id)); } - priv->subpicture_id = VA_INVALID_ID; + GST_VAAPI_OBJECT_ID(subpicture) = VA_INVALID_ID; } if (priv->image) { @@ -95,15 +96,16 @@ gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture) GST_VAAPI_DISPLAY_LOCK(display); status = vaCreateSubpicture( GST_VAAPI_DISPLAY_VADISPLAY(display), - gst_vaapi_image_get_id(priv->image), + GST_VAAPI_OBJECT_ID(priv->image), &subpicture_id ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaCreateSubpicture()")) return FALSE; - GST_DEBUG("subpicture 0x%08x", subpicture_id); - priv->subpicture_id = subpicture_id; + GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(subpicture_id)); + GST_VAAPI_OBJECT_ID(subpicture) = subpicture_id; return TRUE; } @@ -146,9 +148,6 @@ gst_vaapi_subpicture_get_property( GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object); switch (prop_id) { - case PROP_SUBPICTURE_ID: - g_value_set_uint(value, gst_vaapi_subpicture_get_id(subpicture)); - break; case PROP_IMAGE: g_value_set_object(value, gst_vaapi_subpicture_get_image(subpicture)); break; @@ -169,20 +168,6 @@ gst_vaapi_subpicture_class_init(GstVaapiSubpictureClass *klass) object_class->set_property = gst_vaapi_subpicture_set_property; object_class->get_property = gst_vaapi_subpicture_get_property; - /** - * GstVaapiSubpicture:id: - * - * The underlying #VASubpictureID of the subpicture. - */ - g_object_class_install_property - (object_class, - PROP_SUBPICTURE_ID, - g_param_spec_uint("id", - "VA subpicture id", - "The underlying VA subpicture id", - 0, G_MAXUINT32, VA_INVALID_ID, - G_PARAM_READABLE)); - /** * GstVaapiSubpicture:image: * @@ -204,7 +189,6 @@ gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture) GstVaapiSubpicturePrivate *priv = GST_VAAPI_SUBPICTURE_GET_PRIVATE(subpicture); subpicture->priv = priv; - priv->subpicture_id = VA_INVALID_ID; priv->image = NULL; } @@ -222,7 +206,8 @@ gst_vaapi_subpicture_new(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); - GST_DEBUG("create from image 0x%08x", gst_vaapi_image_get_id(image)); + GST_DEBUG("create from image %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(image))); return g_object_new(GST_VAAPI_TYPE_SUBPICTURE, "display", GST_VAAPI_OBJECT_GET_DISPLAY(image), @@ -230,22 +215,6 @@ gst_vaapi_subpicture_new(GstVaapiImage *image) NULL); } -/** - * gst_vaapi_subpicture_get_id: - * @subpicture: a #GstVaapiSubpicture - * - * Returns the underlying VASubpictureID of the @subpicture. - * - * Return value: the underlying VA subpicture id - */ -VASubpictureID -gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture) -{ - g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), VA_INVALID_ID); - - return subpicture->priv->subpicture_id; -} - /** * gst_vaapi_subpicture_get_image: * @subpicture: a #GstVaapiSubpicture diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 7c4b125c52..3103fc334d 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -83,9 +83,6 @@ gst_vaapi_subpicture_get_type(void); GstVaapiSubpicture * gst_vaapi_subpicture_new(GstVaapiImage *image); -VASubpictureID -gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture); - GstVaapiImage * gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 107a78184d..bd35504593 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -40,7 +40,6 @@ G_DEFINE_TYPE(GstVaapiSurface, gst_vaapi_surface, GST_VAAPI_TYPE_OBJECT); GstVaapiSurfacePrivate)) struct _GstVaapiSurfacePrivate { - VASurfaceID surface_id; guint width; guint height; GstVaapiChromaType chroma_type; @@ -50,7 +49,6 @@ struct _GstVaapiSurfacePrivate { enum { PROP_0, - PROP_SURFACE_ID, PROP_WIDTH, PROP_HEIGHT, PROP_CHROMA_TYPE @@ -67,20 +65,23 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface) { GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); GstVaapiSurfacePrivate * const priv = surface->priv; + VASurfaceID surface_id; VAStatus status; - GST_DEBUG("surface 0x%08x", priv->surface_id); + surface_id = GST_VAAPI_OBJECT_ID(surface); + GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); - if (priv->surface_id != VA_INVALID_SURFACE) { + if (surface_id != VA_INVALID_SURFACE) { GST_VAAPI_DISPLAY_LOCK(display); status = vaDestroySurfaces( GST_VAAPI_DISPLAY_VADISPLAY(display), - &priv->surface_id, 1 + &surface_id, 1 ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaDestroySurfaces()")) - g_warning("failed to destroy surface 0x%08x\n", priv->surface_id); - priv->surface_id = VA_INVALID_SURFACE; + g_warning("failed to destroy surface %" GST_VAAPI_ID_FORMAT "\n", + GST_VAAPI_ID_ARGS(surface_id)); + GST_VAAPI_OBJECT_ID(surface) = VA_INVALID_SURFACE; } if (priv->subpictures) { @@ -126,8 +127,8 @@ gst_vaapi_surface_create(GstVaapiSurface *surface) if (!vaapi_check_status(status, "vaCreateSurfaces()")) return FALSE; - GST_DEBUG("surface 0x%08x", surface_id); - priv->surface_id = surface_id; + GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); + GST_VAAPI_OBJECT_ID(surface) = surface_id; return TRUE; } @@ -177,9 +178,6 @@ gst_vaapi_surface_get_property( GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); switch (prop_id) { - case PROP_SURFACE_ID: - g_value_set_uint(value, gst_vaapi_surface_get_id(surface)); - break; case PROP_WIDTH: g_value_set_uint(value, gst_vaapi_surface_get_width(surface)); break; @@ -220,20 +218,6 @@ gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass) object_class->get_property = gst_vaapi_surface_get_property; object_class->constructed = gst_vaapi_surface_constructed; - /** - * GstVaapiSurface:id: - * - * The underlying #VASurfaceID of the surface. - */ - g_object_class_install_property - (object_class, - PROP_SURFACE_ID, - g_param_spec_uint("id", - "VA surface id", - "The underlying VA surface id", - 0, G_MAXUINT32, VA_INVALID_SURFACE, - G_PARAM_READABLE)); - g_object_class_install_property (object_class, PROP_WIDTH, @@ -268,7 +252,6 @@ gst_vaapi_surface_init(GstVaapiSurface *surface) GstVaapiSurfacePrivate *priv = GST_VAAPI_SURFACE_GET_PRIVATE(surface); surface->priv = priv; - priv->surface_id = VA_INVALID_SURFACE; priv->width = 0; priv->height = 0; priv->chroma_type = 0; @@ -305,22 +288,6 @@ gst_vaapi_surface_new( NULL); } -/** - * gst_vaapi_surface_get_id: - * @surface: a #GstVaapiSurface - * - * Returns the underlying VASurfaceID of the @surface. - * - * Return value: the underlying VA surface id - */ -VASurfaceID -gst_vaapi_surface_get_id(GstVaapiSurface *surface) -{ - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), VA_INVALID_SURFACE); - - return surface->priv->surface_id; -} - /** * gst_vaapi_surface_get_chroma_type: * @surface: a #GstVaapiSurface @@ -433,7 +400,7 @@ gst_vaapi_surface_derive_image(GstVaapiSurface *surface) GST_VAAPI_DISPLAY_LOCK(display); status = vaDeriveImage( GST_VAAPI_DISPLAY_VADISPLAY(display), - surface->priv->surface_id, + GST_VAAPI_OBJECT_ID(surface), &va_image ); GST_VAAPI_DISPLAY_UNLOCK(display); @@ -474,14 +441,14 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) if (width != surface->priv->width || height != surface->priv->height) return FALSE; - image_id = gst_vaapi_image_get_id(image); + image_id = GST_VAAPI_OBJECT_ID(image); if (image_id == VA_INVALID_ID) return FALSE; GST_VAAPI_DISPLAY_LOCK(display); status = vaGetImage( GST_VAAPI_DISPLAY_VADISPLAY(display), - surface->priv->surface_id, + GST_VAAPI_OBJECT_ID(surface), 0, 0, width, height, image_id ); @@ -521,14 +488,14 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) if (width != surface->priv->width || height != surface->priv->height) return FALSE; - image_id = gst_vaapi_image_get_id(image); + image_id = GST_VAAPI_OBJECT_ID(image); if (image_id == VA_INVALID_ID) return FALSE; GST_VAAPI_DISPLAY_LOCK(display); status = vaPutImage( GST_VAAPI_DISPLAY_VADISPLAY(display), - surface->priv->surface_id, + GST_VAAPI_OBJECT_ID(surface), image_id, 0, 0, width, height, 0, 0, width, height @@ -569,6 +536,7 @@ gst_vaapi_surface_associate_subpicture( GstVaapiDisplay *display; GstVaapiRectangle src_rect_default, dst_rect_default; GstVaapiImage *image; + VASurfaceID surface_id; VAStatus status; g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); @@ -587,6 +555,10 @@ gst_vaapi_surface_associate_subpicture( return FALSE; } + surface_id = GST_VAAPI_OBJECT_ID(surface); + if (surface_id == VA_INVALID_SURFACE) + return FALSE; + if (!src_rect) { image = gst_vaapi_subpicture_get_image(subpicture); if (!image) @@ -612,8 +584,8 @@ gst_vaapi_surface_associate_subpicture( GST_VAAPI_DISPLAY_LOCK(display); status = vaAssociateSubpicture( GST_VAAPI_DISPLAY_VADISPLAY(display), - gst_vaapi_subpicture_get_id(subpicture), - &surface->priv->surface_id, 1, + GST_VAAPI_OBJECT_ID(subpicture), + &surface_id, 1, src_rect->x, src_rect->y, src_rect->width, src_rect->height, dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height, 0 @@ -642,6 +614,7 @@ gst_vaapi_surface_deassociate_subpicture( ) { GstVaapiDisplay *display; + VASurfaceID surface_id; VAStatus status; g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); @@ -656,17 +629,22 @@ gst_vaapi_surface_deassociate_subpicture( /* First, check subpicture was really associated with this surface */ if (!g_ptr_array_remove_fast(surface->priv->subpictures, subpicture)) { - GST_DEBUG("subpicture 0x%08x was not bound to surface 0x%08x", - gst_vaapi_subpicture_get_id(subpicture), - surface->priv->surface_id); + GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT "was not bound to " + "surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(subpicture)), + GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); return TRUE; } + surface_id = GST_VAAPI_OBJECT_ID(surface); + if (surface_id == VA_INVALID_SURFACE) + return FALSE; + GST_VAAPI_DISPLAY_LOCK(display); status = vaDeassociateSubpicture( GST_VAAPI_DISPLAY_VADISPLAY(display), - gst_vaapi_subpicture_get_id(subpicture), - &surface->priv->surface_id, 1 + GST_VAAPI_OBJECT_ID(subpicture), + &surface_id, 1 ); GST_VAAPI_DISPLAY_UNLOCK(display); g_object_unref(subpicture); @@ -699,7 +677,7 @@ gst_vaapi_surface_sync(GstVaapiSurface *surface) GST_VAAPI_DISPLAY_LOCK(display); status = vaSyncSurface( GST_VAAPI_DISPLAY_VADISPLAY(display), - surface->priv->surface_id + GST_VAAPI_OBJECT_ID(surface) ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaSyncSurface()")) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index db92955539..a0e4379b31 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -133,9 +133,6 @@ gst_vaapi_surface_new( guint height ); -VASurfaceID -gst_vaapi_surface_get_id(GstVaapiSurface *surface); - GstVaapiChromaType gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index fd57c652fa..67457b25cd 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -404,7 +404,7 @@ gst_vaapi_window_x11_render( if (!display) return FALSE; - surface_id = gst_vaapi_surface_get_id(surface); + surface_id = GST_VAAPI_OBJECT_ID(surface); if (surface_id == VA_INVALID_ID) return FALSE; diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index fca9f6ac47..122090301f 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -33,12 +33,13 @@ gst_vaapi_object_destroy_cb(gpointer object, gpointer user_data) int main(int argc, char *argv[]) { - GstVaapiDisplay *display; - GstVaapiSurface *surface; - GstVaapiSurface *surfaces[MAX_SURFACES]; - GstVaapiVideoPool *pool; - GstCaps *caps; - gint i; + GstVaapiDisplay *display; + GstVaapiSurface *surface; + GstVaapiID surface_id; + GstVaapiSurface *surfaces[MAX_SURFACES]; + GstVaapiVideoPool *pool; + GstCaps *caps; + gint i; static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; static const guint width = 320; @@ -53,6 +54,14 @@ main(int argc, char *argv[]) surface = gst_vaapi_surface_new(display, chroma_type, width, height); if (!surface) g_error("could not create Gst/VA surface"); + + /* This also tests for the GstVaapiParamSpecID */ + g_object_get(G_OBJECT(surface), "id", &surface_id, NULL); + if (surface_id != gst_vaapi_object_get_id(GST_VAAPI_OBJECT(surface))) + g_error("could not retrieve the native surface ID"); + g_print("created surface %" GST_VAAPI_ID_FORMAT "\n", + GST_VAAPI_ID_ARGS(surface_id)); + g_object_unref(surface); caps = gst_caps_new_simple( @@ -72,8 +81,8 @@ main(int argc, char *argv[]) surface = gst_vaapi_video_pool_get_object(pool); if (!surface) g_error("could not allocate Gst/VA surface from pool"); - g_print("created surface 0x%08x from pool\n", - gst_vaapi_surface_get_id(surface)); + g_print("created surface %" GST_VAAPI_ID_FORMAT " from pool\n", + GST_VAAPI_ID_ARGS(gst_vaapi_object_get_id(GST_VAAPI_OBJECT(surface)))); surfaces[i] = surface; } @@ -87,8 +96,8 @@ main(int argc, char *argv[]) surfaces[i] = gst_vaapi_video_pool_get_object(pool); if (!surfaces[i]) g_error("could not re-allocate Gst/VA surface%d from pool", i); - g_print("created surface 0x%08x from pool (realloc)\n", - gst_vaapi_surface_get_id(surfaces[i])); + g_print("created surface %" GST_VAAPI_ID_FORMAT " from pool (realloc)\n", + GST_VAAPI_ID_ARGS(gst_vaapi_object_get_id(GST_VAAPI_OBJECT(surfaces[i])))); } if (surface == surfaces[0]) From 358be3dda95ceb1b0cd8d17abfcacb02878ed279 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 13:20:34 +0000 Subject: [PATCH 0163/3781] Fix return value on error. --- gst-libs/gst/vaapi/gstvaapiobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 3e844c723c..8d13c677c1 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -220,7 +220,7 @@ gst_vaapi_object_get_display(GstVaapiObject *object) GstVaapiID gst_vaapi_object_get_id(GstVaapiObject *object) { - g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), NULL); + g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), VA_INVALID_ID); return object->priv->id; } From 1959fa5b202cd2b4aa667cf7ddb5f913f0ebaec9 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 13:21:54 +0000 Subject: [PATCH 0164/3781] Cosmetics (vertical alignment). --- gst-libs/gst/vaapi/gstvaapiobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 8d13c677c1..41b53726be 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -187,8 +187,8 @@ gst_vaapi_object_init(GstVaapiObject *object) { GstVaapiObjectPrivate *priv = GST_VAAPI_OBJECT_GET_PRIVATE(object); - object->priv = priv; - priv->display = NULL; + object->priv = priv; + priv->display = NULL; priv->id = VA_INVALID_ID; priv->is_destroying = FALSE; } From f8f76fdb36d5e529fd317aea69786b5701a8f2b2 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 13:22:25 +0000 Subject: [PATCH 0165/3781] Cosmetics (lowercase for consistency). --- tests/test-surfaces.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index 122090301f..ef8d277172 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -27,7 +27,7 @@ static void gst_vaapi_object_destroy_cb(gpointer object, gpointer user_data) { - g_print("Destroying GstVaapiObject %p\n", object); + g_print("destroying GstVaapiObject %p\n", object); } int From b18236648370591f20b6ab4bb72a678b6eee9982 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 13:37:38 +0000 Subject: [PATCH 0166/3781] Move GValue specific stuff to a dedicated file. --- gst-libs/gst/vaapi/Makefile.am | 3 +- gst-libs/gst/vaapi/gstvaapiobject.c | 1 + gst-libs/gst/vaapi/gstvaapiparamspecs.c | 1 + gst-libs/gst/vaapi/gstvaapitypes.h | 28 +------ .../{gstvaapitypes.c => gstvaapivalue.c} | 83 ++++++++++--------- 5 files changed, 47 insertions(+), 69 deletions(-) rename gst-libs/gst/vaapi/{gstvaapitypes.c => gstvaapivalue.c} (95%) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 4b8280d700..f1ecfce0f8 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -17,8 +17,8 @@ libgstvaapi_source_c = \ gstvaapisubpicture.c \ gstvaapisurface.c \ gstvaapisurfacepool.c \ - gstvaapitypes.c \ gstvaapiutils.c \ + gstvaapivalue.c \ gstvaapivideobuffer.c \ gstvaapivideopool.c \ gstvaapivideosink.c \ @@ -36,6 +36,7 @@ libgstvaapi_source_h = \ gstvaapisurface.h \ gstvaapisurfacepool.h \ gstvaapitypes.h \ + gstvaapivalue.h \ gstvaapivideobuffer.h \ gstvaapivideopool.h \ gstvaapivideosink.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 41b53726be..32f82f1fff 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -27,6 +27,7 @@ #include "gstvaapiobject.h" #include "gstvaapiobject_priv.h" #include "gstvaapiparamspecs.h" +#include "gstvaapivalue.h" #include "gstvaapimarshal.h" #define DEBUG 1 diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.c b/gst-libs/gst/vaapi/gstvaapiparamspecs.c index f297a9c880..0409c6f966 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.c +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.c @@ -21,6 +21,7 @@ #include "config.h" #include #include "gstvaapiparamspecs.h" +#include "gstvaapivalue.h" /* --- GstVaapiParamSpecID --- */ diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 48aadd38df..451486a7aa 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -21,7 +21,7 @@ #ifndef GST_VAAPI_TYPES_H #define GST_VAAPI_TYPES_H -#include +#include G_BEGIN_DECLS @@ -70,32 +70,6 @@ typedef guint64 GstVaapiID; */ #define GST_VAAPI_ID_ARGS(id) GUINT_TO_POINTER(id) -/** - * GST_VAAPI_TYPE_ID: - * - * A #GValue type that represents a VA identifier. - * - * Return value: the #GType of GstVaapiID - */ -#define GST_VAAPI_TYPE_ID gst_vaapi_id_get_type() - -/** - * GST_VAAPI_VALUE_HOLDS_ID: - * @x: the #GValue to check - * - * Checks if the given #GValue contains a #GstVaapiID value. - */ -#define GST_VAAPI_VALUE_HOLDS_ID(x) (G_VALUE_HOLDS((x), GST_VAAPI_TYPE_ID)) - -GType -gst_vaapi_id_get_type(void); - -GstVaapiID -gst_vaapi_value_get_id(const GValue *value); - -void -gst_vaapi_value_set_id(GValue *value, GstVaapiID id); - /** * GstVaapiPoint: * @x: X coordinate diff --git a/gst-libs/gst/vaapi/gstvaapitypes.c b/gst-libs/gst/vaapi/gstvaapivalue.c similarity index 95% rename from gst-libs/gst/vaapi/gstvaapitypes.c rename to gst-libs/gst/vaapi/gstvaapivalue.c index 42eef03314..1ba30deb09 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -1,5 +1,5 @@ /* - * gstvaapitypes.h - Basic types + * gstvaapivalue.c - GValue implementations specific to VA-API * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * @@ -19,14 +19,51 @@ */ /** - * SECTION:gstvaapitypes - * @short_description: Basic types + * SECTION:gstvaapivalue + * @short_description: GValue implementations specific to VA-API */ #include "config.h" -#include #include -#include "gstvaapitypes.h" +#include "gstvaapivalue.h" + +static GTypeInfo gst_vaapi_type_info = { + 0, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + NULL, + NULL, +}; + +static GTypeFundamentalInfo gst_vaapi_type_finfo = { + 0 +}; + +#define GST_VAAPI_TYPE_DEFINE(type, name) \ +GType gst_vaapi_ ## type ## _get_type(void) \ +{ \ + static GType gst_vaapi_ ## type ## _type = 0; \ + \ + if (G_UNLIKELY(gst_vaapi_ ## type ## _type == 0)) { \ + gst_vaapi_type_info.value_table = \ + &gst_vaapi_ ## type ## _value_table; \ + gst_vaapi_ ## type ## _type = g_type_register_fundamental( \ + g_type_fundamental_next(), \ + name, \ + &gst_vaapi_type_info, \ + &gst_vaapi_type_finfo, \ + 0 \ + ); \ + } \ + return gst_vaapi_ ## type ## _type; \ +} + +/* --- GstVaapiID --- */ #if GST_VAAPI_TYPE_ID_SIZE == 4 # define GST_VAAPI_VALUE_ID_(cvalue) ((cvalue).v_int) @@ -82,42 +119,6 @@ gst_vaapi_value_id_lcopy( return NULL; } -static GTypeInfo gst_vaapi_type_info = { - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - 0, - 0, - NULL, - NULL, -}; - -static GTypeFundamentalInfo gst_vaapi_type_finfo = { - 0 -}; - -#define GST_VAAPI_TYPE_DEFINE(type, name) \ -GType gst_vaapi_ ## type ## _get_type(void) \ -{ \ - static GType gst_vaapi_ ## type ## _type = 0; \ - \ - if (G_UNLIKELY(gst_vaapi_ ## type ## _type == 0)) { \ - gst_vaapi_type_info.value_table = \ - &gst_vaapi_ ## type ## _value_table; \ - gst_vaapi_ ## type ## _type = g_type_register_fundamental( \ - g_type_fundamental_next(), \ - name, \ - &gst_vaapi_type_info, \ - &gst_vaapi_type_finfo, \ - 0 \ - ); \ - } \ - return gst_vaapi_ ## type ## _type; \ -} - static const GTypeValueTable gst_vaapi_id_value_table = { gst_vaapi_value_id_init, NULL, From e4d9e0694596f569e1272b96974a97ff274dbc0c Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 13:44:01 +0000 Subject: [PATCH 0167/3781] Fix documentation. --- docs/reference/libs/libs-docs.xml.in | 2 ++ docs/reference/libs/libs-sections.txt | 17 +++++++++++++++-- gst-libs/gst/vaapi/gstvaapiparamspecs.c | 5 +++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 2bd67ca3dc..46a6cb4df1 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -9,6 +9,8 @@ gst-plugins-vaapi Library + + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 4894e5f661..3d3ded2782 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -161,12 +161,25 @@ GST_VAAPI_VIDEO_BUFFER_GET_CLASS GstVaapiID GST_VAAPI_ID_FORMAT GST_VAAPI_ID_ARGS -gst_vaapi_value_get_id -gst_vaapi_value_set_id GstVaapiPoint GstVaapiRectangle
+
+gstvaapivalue + +GST_VAAPI_TYPE_ID +gst_vaapi_value_get_id +gst_vaapi_value_set_id +
+ +
+gstvaapiparamspecs + +GstVaapiParamSpecID +gst_vaapi_param_spec_id +
+
gstvaapiwindow GstVaapiWindow diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.c b/gst-libs/gst/vaapi/gstvaapiparamspecs.c index 0409c6f966..e4e088ae1e 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.c +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * SECTION:gstvaapiparamspecs + * @short_description: GParamSpecs for some of our types + */ + #include "config.h" #include #include "gstvaapiparamspecs.h" From 992df1819e1b3a27b336e002a49928e065dc0e66 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 14:36:39 +0000 Subject: [PATCH 0168/3781] Simplify upload process and fallback to subpictures. --- tests/test-windows.c | 77 ++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/tests/test-windows.c b/tests/test-windows.c index bca4afcab0..b3ecd23320 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -258,15 +258,52 @@ static gboolean draw_rgb_rects(GstVaapiImage *image) return TRUE; } +static gboolean +upload_image(GstVaapiSurface *surface, GstVaapiImage *image) +{ + GstVaapiDisplay *display; + GstVaapiImageFormat format; + GstVaapiSubpicture *subpicture; + + display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); + if (!display) + return FALSE; + + format = gst_vaapi_image_get_format(image); + if (!format) + return FALSE; + + if (gst_vaapi_surface_put_image(surface, image)) + return TRUE; + + g_print("could not upload %" GST_FOURCC_FORMAT" image to surface\n", + GST_FOURCC_ARGS(format)); + + if (!gst_vaapi_display_has_subpicture_format(display, format)) + return FALSE; + + g_print("trying as a subpicture\n"); + + subpicture = gst_vaapi_subpicture_new(image); + if (!subpicture) + g_error("could not create Gst/VA subpicture"); + + if (!gst_vaapi_surface_associate_subpicture(surface, subpicture, + NULL, NULL)) + g_error("could not associate subpicture to surface"); + + /* The surface holds a reference to the subpicture. This is safe */ + g_object_unref(subpicture); + return TRUE; +} + int main(int argc, char *argv[]) { GstVaapiDisplay *display; GstVaapiWindow *window; GstVaapiSurface *surface; - GstVaapiImage *image = NULL; - GstVaapiSubpicture *subpicture; - GstVaapiImageFormat format; + GstVaapiImage *image = NULL; guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; guint i; @@ -298,35 +335,21 @@ main(int argc, char *argv[]) g_error("could not create Gst/VA surface"); for (i = 0; image_formats[i]; i++) { - image = gst_vaapi_image_new(display, image_formats[i], width, height); - if (image) { - format = image_formats[i]; + const GstVaapiImageFormat format = image_formats[i]; + + image = gst_vaapi_image_new(display, format, width, height); + if (!image) + continue; + + if (!draw_rgb_rects(image)) + g_error("could not draw RGB rectangles"); + + if (upload_image(surface, image)) break; - } } if (!image) g_error("could not create Gst/VA image"); - if (!draw_rgb_rects(image)) - g_error("could not draw RGB rectangles"); - - if (gst_vaapi_image_format_is_rgb(format)) { - subpicture = gst_vaapi_subpicture_new(image); - if (!subpicture) - g_error("could not create Gst/VA subpicture"); - - if (!gst_vaapi_surface_associate_subpicture(surface, subpicture, - NULL, NULL)) - g_error("could not associate subpicture to surface"); - - /* The surface holds a reference to the subpicture. This is safe. */ - g_object_unref(subpicture); - } - else { - if (!gst_vaapi_surface_put_image(surface, image)) - g_error("could not upload image"); - } - if (!gst_vaapi_surface_sync(surface)) g_error("could not complete image upload"); From 9713d1a9505f6c1c3c667afb1507525ec1cab089 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 14:46:33 +0000 Subject: [PATCH 0169/3781] Add support for AYUV format. --- NEWS | 5 ++++- gst-libs/gst/vaapi/gstvaapiimage.c | 1 + gst-libs/gst/vaapi/gstvaapiimageformat.c | 1 + gst-libs/gst/vaapi/gstvaapiimageformat.h | 3 +++ tests/test-windows.c | 27 ++++++++++++++++++++++++ 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index a1cadd5485..4f8a184bbc 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2010-03-23 +gst-vaapi NEWS -- summary of changes. 2010-03-DD Copyright (C) 2010 Splitted-Desktop Systems +Version 0.1.2 - DD.Mar.2010 +* Add AYUV image format + Version 0.1.1 - 23.Mar.2010 * Document public API for libgstvaapi-*.so.* * Optimize `vaapiconvert' pipeline (direct-rendering) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 0a354dec9c..e5de6ece4a 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -129,6 +129,7 @@ vaapi_image_is_linear(const VAImage *va_image) case VA_FOURCC('I','4','2','0'): data_size = width * height + 2 * width2 * height2; break; + case VA_FOURCC('A','Y','U','V'): case VA_FOURCC('A','R','G','B'): case VA_FOURCC('R','G','B','A'): case VA_FOURCC('A','B','G','R'): diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index bf52dee006..45d2f75f7e 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -60,6 +60,7 @@ static const GstVaapiImageFormatMap gst_vaapi_image_formats[] = { DEF_YUV(NV12, ('N','V','1','2'), LSB, 12), DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12), DEF_YUV(I420, ('I','4','2','0'), LSB, 12), + DEF_YUV(AYUV, ('A','Y','U','V'), LSB, 32), #if G_BYTE_ORDER == G_BIG_ENDIAN DEF_RGB(ARGB, ('A','R','G','B'), MSB, 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index afa5b8c349..c26f006e67 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -36,6 +36,8 @@ typedef enum _GstVaapiImageFormat GstVaapiImageFormat; * planar YUV 4:2:0, 12-bit, 3 planes for Y V U * @GST_VAAPI_IMAGE_I420: * planar YUV 4:2:0, 12-bit, 3 planes for Y U V + * @GST_VAAPI_IMAGE_AYUV: + * packed YUV 4:4:4, 32-bit, A Y U V, native endian byte-order * @GST_VAAPI_IMAGE_ARGB: * packed RGB 8:8:8, 32-bit, A R G B * @GST_VAAPI_IMAGE_RGBA: @@ -51,6 +53,7 @@ enum _GstVaapiImageFormat { GST_VAAPI_IMAGE_NV12 = VA_FOURCC('N','V','1','2'), GST_VAAPI_IMAGE_YV12 = VA_FOURCC('Y','V','1','2'), GST_VAAPI_IMAGE_I420 = VA_FOURCC('I','4','2','0'), + GST_VAAPI_IMAGE_AYUV = VA_FOURCC('A','Y','U','V'), GST_VAAPI_IMAGE_ARGB = VA_FOURCC('A','R','G','B'), GST_VAAPI_IMAGE_RGBA = VA_FOURCC('R','G','B','A'), GST_VAAPI_IMAGE_ABGR = VA_FOURCC('A','B','G','R'), diff --git a/tests/test-windows.c b/tests/test-windows.c index b3ecd23320..3aa4a509bf 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -179,6 +179,27 @@ static void draw_rect_YV12( // Y, U, V planes } } +static void draw_rect_AYUV( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + guint i, j; + + color = color | 0xff000000; + + for (j = 0; j < height; j++) { + guint32 *p = (guint32 *)(pixels[0] + (y + j) * stride[0] + x * 4); + for (i = 0; i < width; i++) + p[i] = color; + } +} + static gboolean draw_rgb_rects(GstVaapiImage *image) { GstVaapiImageFormat format = GST_VAAPI_IMAGE_FORMAT(image); @@ -236,6 +257,11 @@ static gboolean draw_rgb_rects(GstVaapiImage *image) stride[1] = gst_vaapi_image_get_pitch(image, 1); pixels[2] = gst_vaapi_image_get_plane(image, 2); stride[2] = gst_vaapi_image_get_pitch(image, 2); + goto YUV_colors; + case GST_VAAPI_IMAGE_AYUV: + draw_rect = draw_rect_AYUV; + pixels[0] = gst_vaapi_image_get_plane(image, 0); + stride[0] = gst_vaapi_image_get_pitch(image, 0); YUV_colors: red_color = 0x515af0; green_color = 0x913622; @@ -311,6 +337,7 @@ main(int argc, char *argv[]) GST_VAAPI_IMAGE_NV12, GST_VAAPI_IMAGE_YV12, GST_VAAPI_IMAGE_I420, + GST_VAAPI_IMAGE_AYUV, GST_VAAPI_IMAGE_ARGB, GST_VAAPI_IMAGE_BGRA, GST_VAAPI_IMAGE_RGBA, From c8ec5043435be1020db30ddcc170908746b4eaa7 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 14:57:33 +0000 Subject: [PATCH 0170/3781] Fix destruction order of subpictures. They should be destroyed first. --- gst-libs/gst/vaapi/gstvaapisurface.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index bd35504593..364a51cb25 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -71,6 +71,12 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface) surface_id = GST_VAAPI_OBJECT_ID(surface); GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); + if (priv->subpictures) { + g_ptr_array_foreach(priv->subpictures, destroy_subpicture_cb, NULL); + g_ptr_array_free(priv->subpictures, TRUE); + priv->subpictures = NULL; + } + if (surface_id != VA_INVALID_SURFACE) { GST_VAAPI_DISPLAY_LOCK(display); status = vaDestroySurfaces( @@ -83,12 +89,6 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface) GST_VAAPI_ID_ARGS(surface_id)); GST_VAAPI_OBJECT_ID(surface) = VA_INVALID_SURFACE; } - - if (priv->subpictures) { - g_ptr_array_foreach(priv->subpictures, destroy_subpicture_cb, NULL); - g_ptr_array_free(priv->subpictures, TRUE); - priv->subpictures = NULL; - } } static gboolean From ae6c1637f33e5624a7b4be3042de3902095423bf Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 15:11:26 +0000 Subject: [PATCH 0171/3781] Deassociate subpictures while destroying the surface. --- gst-libs/gst/vaapi/gstvaapisurface.c | 90 +++++++++++++++++++++------- 1 file changed, 70 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 364a51cb25..583b772d57 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -54,9 +54,24 @@ enum { PROP_CHROMA_TYPE }; +static gboolean +_gst_vaapi_surface_associate_subpicture( + GstVaapiSurface *surface, + GstVaapiSubpicture *subpicture, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect +); + +static gboolean +_gst_vaapi_surface_deassociate_subpicture( + GstVaapiSurface *surface, + GstVaapiSubpicture *subpicture +); + static void -destroy_subpicture_cb(gpointer subpicture, gpointer user_data) +destroy_subpicture_cb(gpointer subpicture, gpointer surface) { + _gst_vaapi_surface_deassociate_subpicture(surface, subpicture); g_object_unref(subpicture); } @@ -72,7 +87,7 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface) GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); if (priv->subpictures) { - g_ptr_array_foreach(priv->subpictures, destroy_subpicture_cb, NULL); + g_ptr_array_foreach(priv->subpictures, destroy_subpicture_cb, surface); g_ptr_array_free(priv->subpictures, TRUE); priv->subpictures = NULL; } @@ -533,19 +548,11 @@ gst_vaapi_surface_associate_subpicture( const GstVaapiRectangle *dst_rect ) { - GstVaapiDisplay *display; - GstVaapiRectangle src_rect_default, dst_rect_default; - GstVaapiImage *image; - VASurfaceID surface_id; - VAStatus status; + gboolean success; g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); - display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); - if (!display) - return FALSE; - if (!gst_vaapi_surface_deassociate_subpicture(surface, subpicture)) return FALSE; @@ -555,6 +562,37 @@ gst_vaapi_surface_associate_subpicture( return FALSE; } + success = _gst_vaapi_surface_associate_subpicture( + surface, + subpicture, + src_rect, + dst_rect + ); + if (!success) + return FALSE; + + g_ptr_array_add(surface->priv->subpictures, g_object_ref(subpicture)); + return TRUE; +} + +gboolean +_gst_vaapi_surface_associate_subpicture( + GstVaapiSurface *surface, + GstVaapiSubpicture *subpicture, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect +) +{ + GstVaapiDisplay *display; + GstVaapiRectangle src_rect_default, dst_rect_default; + GstVaapiImage *image; + VASurfaceID surface_id; + VAStatus status; + + display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + if (!display) + return FALSE; + surface_id = GST_VAAPI_OBJECT_ID(surface); if (surface_id == VA_INVALID_SURFACE) return FALSE; @@ -594,7 +632,6 @@ gst_vaapi_surface_associate_subpicture( if (!vaapi_check_status(status, "vaAssociateSubpicture()")) return FALSE; - g_ptr_array_add(surface->priv->subpictures, g_object_ref(subpicture)); return TRUE; } @@ -613,17 +650,11 @@ gst_vaapi_surface_deassociate_subpicture( GstVaapiSubpicture *subpicture ) { - GstVaapiDisplay *display; - VASurfaceID surface_id; - VAStatus status; + gboolean success; g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); - display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); - if (!display) - return FALSE; - if (!surface->priv->subpictures) return TRUE; @@ -636,6 +667,25 @@ gst_vaapi_surface_deassociate_subpicture( return TRUE; } + success = _gst_vaapi_surface_deassociate_subpicture(surface, subpicture); + g_object_unref(subpicture); + return success; +} + +gboolean +_gst_vaapi_surface_deassociate_subpicture( + GstVaapiSurface *surface, + GstVaapiSubpicture *subpicture +) +{ + GstVaapiDisplay *display; + VASurfaceID surface_id; + VAStatus status; + + display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + if (!display) + return FALSE; + surface_id = GST_VAAPI_OBJECT_ID(surface); if (surface_id == VA_INVALID_SURFACE) return FALSE; @@ -647,9 +697,9 @@ gst_vaapi_surface_deassociate_subpicture( &surface_id, 1 ); GST_VAAPI_DISPLAY_UNLOCK(display); - g_object_unref(subpicture); if (!vaapi_check_status(status, "vaDeassociateSubpicture()")) return FALSE; + return TRUE; } From 4f7af960cb8efb6851dbc576dfd146cdd01c2ce2 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 15:12:56 +0000 Subject: [PATCH 0172/3781] Fix g_warning() invocation. --- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index e5de6ece4a..e8752cd978 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -160,7 +160,7 @@ gst_vaapi_image_destroy(GstVaapiImage *image) status = vaDestroyImage(GST_VAAPI_DISPLAY_VADISPLAY(display), image_id); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaDestroyImage()")) - g_warning("failed to destroy image %" GST_VAAPI_ID_FORMAT "\n", + g_warning("failed to destroy image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id)); GST_VAAPI_OBJECT_ID(image) = VA_INVALID_ID; } diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 3d964f061f..9f4948e3a9 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -70,7 +70,7 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaDestroySubpicture()")) - g_warning("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT "\n", + g_warning("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(subpicture_id)); } GST_VAAPI_OBJECT_ID(subpicture) = VA_INVALID_ID; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 583b772d57..0897e147aa 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -100,7 +100,7 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface) ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaDestroySurfaces()")) - g_warning("failed to destroy surface %" GST_VAAPI_ID_FORMAT "\n", + g_warning("failed to destroy surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); GST_VAAPI_OBJECT_ID(surface) = VA_INVALID_SURFACE; } From afa9b9be0635b8cfa01cb9b9112c3cd48b80d1a6 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 15:18:33 +0000 Subject: [PATCH 0173/3781] Add missing file (gstvaapivalue.h). --- gst-libs/gst/vaapi/gstvaapivalue.h | 57 ++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapivalue.h diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h new file mode 100644 index 0000000000..0011984164 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -0,0 +1,57 @@ +/* + * gstvaapivalue.h - GValue implementations specific to VA-API + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_VALUE_H +#define GST_VAAPI_VALUE_H + +#include +#include + +G_BEGIN_DECLS + +/** + * GST_VAAPI_TYPE_ID: + * + * A #GValue type that represents a VA identifier. + * + * Return value: the #GType of GstVaapiID + */ +#define GST_VAAPI_TYPE_ID gst_vaapi_id_get_type() + +/** + * GST_VAAPI_VALUE_HOLDS_ID: + * @x: the #GValue to check + * + * Checks if the given #GValue contains a #GstVaapiID value. + */ +#define GST_VAAPI_VALUE_HOLDS_ID(x) (G_VALUE_HOLDS((x), GST_VAAPI_TYPE_ID)) + +GType +gst_vaapi_id_get_type(void); + +GstVaapiID +gst_vaapi_value_get_id(const GValue *value); + +void +gst_vaapi_value_set_id(GValue *value, GstVaapiID id); + +G_END_DECLS + +#endif /* GST_VAAPI_VALUE_H */ From 725bc7a60730f285b2cb111970062e35584039e1 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 16:17:49 +0000 Subject: [PATCH 0174/3781] Add compatibility with the original VA-API 0.29. --- NEWS | 1 + configure.ac | 78 +++++++++++++--------- gst-libs/gst/vaapi/Makefile.am | 5 ++ gst-libs/gst/vaapi/gstvaapicompat.h | 84 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 7 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 7 +- gst-libs/gst/vaapi/gstvaapiimageformat.h | 8 ++- gst-libs/gst/vaapi/gstvaapiparamspecs.c | 8 ++- gst-libs/gst/vaapi/gstvaapisurface.c | 1 + gst-libs/gst/vaapi/gstvaapiutils.c | 26 ++++---- gst-libs/gst/vaapi/gstvaapiutils.h | 7 +- pkgconfig/gstreamer-vaapi-x11.pc.in | 6 +- pkgconfig/gstreamer-vaapi.pc.in | 6 +- sys/vaapiconvert/Makefile.am | 2 + sys/vaapisink/Makefile.am | 2 + tests/Makefile.am | 2 + 16 files changed, 196 insertions(+), 54 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapicompat.h diff --git a/NEWS b/NEWS index 4f8a184bbc..e2504c402e 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Copyright (C) 2010 Splitted-Desktop Systems Version 0.1.2 - DD.Mar.2010 * Add AYUV image format +* Add compatibility with the original VA-API 0.29 Version 0.1.1 - 23.Mar.2010 * Document public API for libgstvaapi-*.so.* diff --git a/configure.ac b/configure.ac index 5d1cdfc9da..cc996a6786 100644 --- a/configure.ac +++ b/configure.ac @@ -147,43 +147,52 @@ AC_MSG_RESULT([$GST_PLUGINS_DIR]) plugindir="$GST_PLUGINS_DIR" AC_SUBST(plugindir) -dnl Check for VA-API -PKG_CHECK_MODULES(LIBVA, [libva]) +dnl Check for X11 PKG_CHECK_MODULES(X11, [x11]) -PKG_CHECK_MODULES(LIBVA_X11, [libva-x11]) -dnl Check for SDS extensions to VA-API -AC_CACHE_CHECK([for VA-API], - ac_cv_libva_sds_extensions, [ - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $LIBVA_DEPS_CFLAGS" - AC_TRY_COMPILE([ - #include - #if VA_MAJOR_VERSION == 0 && VA_MINOR_VERSION == 29 - # if !defined(VA_SDS_VERSION) || (VA_SDS_VERSION < $LIBVA_SDS_VERSION_0_29) - # error "VA-API version >= 0.29.0-sds$LIBVA_SDS_VERSION_0_29 is required" - # endif - #elif VA_MAJOR_VERSION == 0 && VA_MINOR_VERSION == 30 - # if !defined(VA_SDS_VERSION) || (VA_SDS_VERSION < $LIBVA_SDS_VERSION_0_30) - # error "VA-API version >= 0.30.0-sds$LIBVA_SDS_VERSION_0_30 is required" - # endif - #elif !VA_CHECK_VERSION(0,31,0) - # error "VA-API version >= 0.31 is required" - #endif - ], [], - [ac_cv_libva_sds_extensions="yes"], - [ac_cv_libva_sds_extensions="no"]) - CFLAGS="$saved_CFLAGS" +dnl Check for VA-API +LIBVA_PKGNAME="libva" +PKG_CHECK_MODULES(LIBVA, [$LIBVA_PKGNAME]) +AC_SUBST(LIBVA_PKGNAME) + +AC_CACHE_CHECK([for old VA-API 0.29], + ac_cv_have_vaapi_old, [ + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_TRY_LINK( + [#include ], + [vaGetDisplay(NULL)], + [ac_cv_have_vaapi_old="yes"], + [ac_cv_have_vaapi_old="no"]) + CFLAGS="$saved_CFLAGS" + LIBS="$saved_LIBS" ]) +if test "$ac_cv_have_vaapi_old" = "yes"; then + LIBVA_EXTRA_CFLAGS="$LIBVA_CFLAGS -DGST_VAAPI_USE_OLD_VAAPI_0_29" +fi + +LIBVA_X11_PKGNAME="libva-x11" +PKG_CHECK_MODULES(LIBVA_X11, [$LIBVA_X11_PKGNAME], + [ac_cv_have_vaapi_x11="yes"], + [ac_cv_have_vaapi_x11="no"] +) +if test "$ac_cv_have_vaapi_x11" = "no"; then + if test "$ac_cv_have_vaapi_old" = "yes"; then + LIBVA_X11_PKGNAME="libva" + else + AC_MSG_ERROR([could not find VA-API]) + fi +fi +AC_SUBST(LIBVA_X11_PKGNAME) + +AC_SUBST(LIBVA_EXTRA_CFLAGS) +AC_SUBST(LIBVA_EXTRA_LIBS) + VA_VERSION=`$PKG_CONFIG --modversion libva` VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1` VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2` -VA_DRIVER_INIT_FUNC="__vaDriverInit_${VA_MAJOR_VERSION}_${VA_MINOR_VERSION}_sds" -if test "$ac_cv_libva_sds_extensions" = "yes"; then - AC_DEFINE_UNQUOTED([VA_DRIVER_INIT_FUNC], [$VA_DRIVER_INIT_FUNC], [Define driver entry-point]) -else - AC_MSG_ERROR([Your VA-API SDK does not include SDS extensions]) -fi pkgconfigdir=${libdir}/pkgconfig AC_SUBST(pkgconfigdir) @@ -220,3 +229,10 @@ debian.upstream/libgstvaapi-x11.install.in sys/vaapisink/Makefile tests/Makefile ]) + +dnl Print summary +echo +echo gstreamer-vaapi configuration summary: +echo +echo VA-API version ................... : $VA_VERSION +echo diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f1ecfce0f8..d3299f5922 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -26,6 +26,7 @@ libgstvaapi_source_c = \ $(NULL) libgstvaapi_source_h = \ + gstvaapicompat.h \ gstvaapidisplay.h \ gstvaapiimage.h \ gstvaapiimageformat.h \ @@ -83,12 +84,14 @@ libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ $(GST_BASE_CFLAGS) \ $(GST_CFLAGS) \ $(LIBVA_CFLAGS) \ + $(LIBVA_EXTRA_CFLAGS) \ $(NULL) libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ $(GST_BASE_LIBS) \ $(GST_LIBS) \ $(LIBVA_LIBS) \ + $(LIBVA_EXTRA_LIBS) \ $(NULL) libgstvaapi_x11_@GST_MAJORMINOR@_la_SOURCES = \ @@ -108,11 +111,13 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_CFLAGS = \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ $(LIBVA_X11_CFLAGS) \ + $(LIBVA_EXTRA_CFLAGS) \ $(NULL) libgstvaapi_x11_@GST_MAJORMINOR@_la_LIBADD = \ $(GLIB_LIBS) \ $(LIBVA_X11_LIBS) \ + $(LIBVA_EXTRA_LIBS) \ libgstvaapi-@GST_MAJORMINOR@.la \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h new file mode 100644 index 0000000000..fb7d2129de --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -0,0 +1,84 @@ +/* + * gstvapicompat.h - VA-API compatibility glue + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_COMPAT_H +#define GST_VAAPI_COMPAT_H + +#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 +# include +# include +#else +# include +#endif + +/* Check for VA version */ +#ifndef VA_CHECK_VERSION +#define VA_MAJOR_VERSION 0 +#define VA_MINOR_VERSION 29 +#define VA_MICRO_VERSION 0 +#define VA_SDS_VERSION 0 +#define VA_CHECK_VERSION(major,minor,micro) \ + (VA_MAJOR_VERSION > (major) || \ + (VA_MAJOR_VERSION == (major) && VA_MINOR_VERSION > (minor)) || \ + (VA_MAJOR_VERSION == (major) && VA_MINOR_VERSION == (minor) && VA_MICRO_VERSION >= (micro))) +#endif + +/* Check for VA/SDS version */ +#ifndef VA_CHECK_VERSION_SDS +#define VA_CHECK_VERSION_SDS(major, minor, micro, sds) \ + (VA_CHECK_VERSION(major, minor, (micro)+1) || \ + (VA_CHECK_VERSION(major, minor, micro) && VA_SDS_VERSION >= (sds))) +#endif + +/* Compatibility glue with original VA-API 0.29 */ +#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 +typedef struct _VASliceParameterBufferBase { + unsigned int slice_data_size; + unsigned int slice_data_offset; + unsigned int slice_data_flag; +} VASliceParameterBufferBase; +#endif + +#ifndef VA_FOURCC +#define VA_FOURCC(ch0, ch1, ch2, ch3) \ + ((guint32)(guint8)(ch0) | \ + ((guint32)(guint8)(ch1) << 8) | \ + ((guint32)(guint8)(ch2) << 16) | \ + ((guint32)(guint8)(ch3) << 24 )) +#endif + +#ifndef VA_INVALID_ID +#define VA_INVALID_ID 0xffffffff +#endif +#ifndef VA_INVALID_SURFACE +#define VA_INVALID_SURFACE VA_INVALID_ID +#endif + +/* Compatibility glue with VA-API < 0.31 */ +#if !VA_CHECK_VERSION(0,31,0) +#undef vaSyncSurface +#define vaSyncSurface(dpy, s) (vaSyncSurface)((dpy), VA_INVALID_ID, (s)) +#undef vaPutImage +#define vaPutImage vaPutImage2 +#undef vaAssociateSubpicture +#define vaAssociateSubpicture vaAssociateSubpicture2 +#endif + +#endif /* GST_VAAPI_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 8b41d3c3cc..1dddf59557 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -21,7 +21,12 @@ #ifndef GST_VAAPI_DISPLAY_H #define GST_VAAPI_DISPLAY_H -#include +#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 +# include +#else +# include +#endif + #include #include diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 9cf79b5224..d6c2d15490 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -21,8 +21,13 @@ #ifndef GST_VAAPI_DISPLAY_X11_H #define GST_VAAPI_DISPLAY_X11_H +#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 +# include +#else +# include +#endif + #include -#include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index c26f006e67..46b6aa6e83 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -21,7 +21,13 @@ #ifndef GST_VAAPI_IMAGE_FORMAT_H #define GST_VAAPI_IMAGE_FORMAT_H -#include +#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 +# include +# include +#else +# include +#endif + #include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.c b/gst-libs/gst/vaapi/gstvaapiparamspecs.c index e4e088ae1e..e50fa1e9d2 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.c +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.c @@ -24,9 +24,15 @@ */ #include "config.h" -#include #include "gstvaapiparamspecs.h" #include "gstvaapivalue.h" +#include "gstvaapicompat.h" + +#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 +# include +#else +# include +#endif /* --- GstVaapiParamSpecID --- */ diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 0897e147aa..80ad4f82dc 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -24,6 +24,7 @@ */ #include "config.h" +#include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapisurface.h" #include "gstvaapiimage.h" diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index b3c15e8539..63e0229aa6 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -19,6 +19,7 @@ */ #include "config.h" +#include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapisurface.h" #include @@ -107,22 +108,23 @@ const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) */ guint get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(guint flags) { - const guint va_top_bottom_fields = (VA_TOP_FIELD|VA_BOTTOM_FIELD); - guint va_flags = 0; + guint va_fields = 0, va_csc = 0; if (flags & GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) - va_flags |= VA_TOP_FIELD; + va_fields |= VA_TOP_FIELD; if (flags & GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) - va_flags |= VA_BOTTOM_FIELD; - if ((va_flags & va_top_bottom_fields) == va_top_bottom_fields) { - va_flags &= ~va_top_bottom_fields; - va_flags |= VA_FRAME_PICTURE; - } + va_fields |= VA_BOTTOM_FIELD; + if ((va_fields ^ (VA_TOP_FIELD|VA_BOTTOM_FIELD)) == 0) + va_fields = VA_FRAME_PICTURE; +#ifdef VA_SRC_BT601 + if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_601) + va_csc = VA_SRC_BT601; +#endif +#ifdef VA_SRC_BT709 if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_709) - va_flags |= VA_SRC_BT709; - else if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_601) - va_flags |= VA_SRC_BT601; + va_csc = VA_SRC_BT709; +#endif - return va_flags; + return va_fields|va_csc; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 8c18044cfe..804cec0de0 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -22,9 +22,14 @@ #define GST_VAAPI_UTILS_H #include "config.h" -#include #include +#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 +# include +#else +# include +#endif + /** Debug output */ void vaapi_dprintf(const char *format, ...) attribute_hidden; diff --git a/pkgconfig/gstreamer-vaapi-x11.pc.in b/pkgconfig/gstreamer-vaapi-x11.pc.in index d3b358d19e..1f258dec59 100644 --- a/pkgconfig/gstreamer-vaapi-x11.pc.in +++ b/pkgconfig/gstreamer-vaapi-x11.pc.in @@ -6,7 +6,7 @@ pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ Name: GStreamer VA-API (x11) Plugins Libraries Description: Streaming media framework, VA-API (x11) plugins libraries -Requires: gstreamer-vaapi-@GST_MAJORMINOR@ libva-x11 +Requires: gstreamer-vaapi-@GST_MAJORMINOR@ @LIBVA_X11_PKGNAME@ Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-x11-@GST_MAJORMINOR@ -Cflags: -I${includedir} +Libs: -L${libdir} -lgstvaapi-x11-@GST_MAJORMINOR@ @LIBVA_EXTRA_LIBS@ +Cflags: -I${includedir} @LIBVA_EXTRA_CFLAGS@ diff --git a/pkgconfig/gstreamer-vaapi.pc.in b/pkgconfig/gstreamer-vaapi.pc.in index e7d2ec636d..281dee02c1 100644 --- a/pkgconfig/gstreamer-vaapi.pc.in +++ b/pkgconfig/gstreamer-vaapi.pc.in @@ -6,7 +6,7 @@ pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ Name: GStreamer VA-API Plugins Libraries Description: Streaming media framework, VA-API plugins libraries -Requires: gstreamer-@GST_MAJORMINOR@ gstreamer-base-@GST_MAJORMINOR@ libva +Requires: gstreamer-@GST_MAJORMINOR@ gstreamer-base-@GST_MAJORMINOR@ @LIBVA_PKGNAME@ Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-@GST_MAJORMINOR@ -Cflags: -I${includedir} +Libs: -L${libdir} -lgstvaapi-@GST_MAJORMINOR@ @LIBVA_EXTRA_LIBS@ +Cflags: -I${includedir} @LIBVA_EXTRA_CFLAGS@ diff --git a/sys/vaapiconvert/Makefile.am b/sys/vaapiconvert/Makefile.am index 74e3d37872..b295d0b636 100644 --- a/sys/vaapiconvert/Makefile.am +++ b/sys/vaapiconvert/Makefile.am @@ -1,9 +1,11 @@ plugin_LTLIBRARIES = libgstvaapiconvert.la libgstvaapi_CFLAGS = \ + $(LIBVA_EXTRA_CFLAGS) \ -I$(top_srcdir)/gst-libs libgstvaapi_LIBS = \ + $(LIBVA_EXTRA_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la libgstvaapiconvert_la_SOURCES = \ diff --git a/sys/vaapisink/Makefile.am b/sys/vaapisink/Makefile.am index 9fdb92140d..54cacdb7b3 100644 --- a/sys/vaapisink/Makefile.am +++ b/sys/vaapisink/Makefile.am @@ -1,9 +1,11 @@ plugin_LTLIBRARIES = libgstvaapisink.la libgstvaapi_CFLAGS = \ + $(LIBVA_EXTRA_CFLAGS) \ -I$(top_srcdir)/gst-libs libgstvaapi_LIBS = \ + $(LIBVA_EXTRA_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la libgstvaapisink_la_SOURCES = \ diff --git a/tests/Makefile.am b/tests/Makefile.am index de69c18db9..f42bbeffeb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -5,11 +5,13 @@ noinst_PROGRAMS = \ $(NULL) TEST_CFLAGS = \ + $(LIBVA_EXTRA_CFLAGS) \ $(GST_CFLAGS) \ -I$(top_srcdir)/gst-libs \ $(X11_CFLAGS) TEST_LIBS = \ + $(LIBVA_EXTRA_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la \ $(X11_LIBS) From 1727295d2c37b0508f74d98eef59bdadfd4ee26b Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 16:21:20 +0000 Subject: [PATCH 0175/3781] Drop tedious LIBVA_EXTRA_{CFLAGS,LIBS} definitions in Makefile.am. Override CFLAGS & LIBS instead. --- configure.ac | 2 ++ gst-libs/gst/vaapi/Makefile.am | 4 ---- sys/vaapiconvert/Makefile.am | 2 -- sys/vaapisink/Makefile.am | 2 -- tests/Makefile.am | 2 -- 5 files changed, 2 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index cc996a6786..55fd58c0fc 100644 --- a/configure.ac +++ b/configure.ac @@ -181,6 +181,8 @@ PKG_CHECK_MODULES(LIBVA_X11, [$LIBVA_X11_PKGNAME], if test "$ac_cv_have_vaapi_x11" = "no"; then if test "$ac_cv_have_vaapi_old" = "yes"; then LIBVA_X11_PKGNAME="libva" + CFLAGS="$CFLAGS $LIBVA_EXTRA_CFLAGS" + LIBS="$LIBS $LIBVA_EXTRA_LIBS" else AC_MSG_ERROR([could not find VA-API]) fi diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index d3299f5922..f8d7203ee3 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -84,14 +84,12 @@ libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ $(GST_BASE_CFLAGS) \ $(GST_CFLAGS) \ $(LIBVA_CFLAGS) \ - $(LIBVA_EXTRA_CFLAGS) \ $(NULL) libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ $(GST_BASE_LIBS) \ $(GST_LIBS) \ $(LIBVA_LIBS) \ - $(LIBVA_EXTRA_LIBS) \ $(NULL) libgstvaapi_x11_@GST_MAJORMINOR@_la_SOURCES = \ @@ -111,13 +109,11 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_CFLAGS = \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ $(LIBVA_X11_CFLAGS) \ - $(LIBVA_EXTRA_CFLAGS) \ $(NULL) libgstvaapi_x11_@GST_MAJORMINOR@_la_LIBADD = \ $(GLIB_LIBS) \ $(LIBVA_X11_LIBS) \ - $(LIBVA_EXTRA_LIBS) \ libgstvaapi-@GST_MAJORMINOR@.la \ $(NULL) diff --git a/sys/vaapiconvert/Makefile.am b/sys/vaapiconvert/Makefile.am index b295d0b636..74e3d37872 100644 --- a/sys/vaapiconvert/Makefile.am +++ b/sys/vaapiconvert/Makefile.am @@ -1,11 +1,9 @@ plugin_LTLIBRARIES = libgstvaapiconvert.la libgstvaapi_CFLAGS = \ - $(LIBVA_EXTRA_CFLAGS) \ -I$(top_srcdir)/gst-libs libgstvaapi_LIBS = \ - $(LIBVA_EXTRA_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la libgstvaapiconvert_la_SOURCES = \ diff --git a/sys/vaapisink/Makefile.am b/sys/vaapisink/Makefile.am index 54cacdb7b3..9fdb92140d 100644 --- a/sys/vaapisink/Makefile.am +++ b/sys/vaapisink/Makefile.am @@ -1,11 +1,9 @@ plugin_LTLIBRARIES = libgstvaapisink.la libgstvaapi_CFLAGS = \ - $(LIBVA_EXTRA_CFLAGS) \ -I$(top_srcdir)/gst-libs libgstvaapi_LIBS = \ - $(LIBVA_EXTRA_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la libgstvaapisink_la_SOURCES = \ diff --git a/tests/Makefile.am b/tests/Makefile.am index f42bbeffeb..de69c18db9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -5,13 +5,11 @@ noinst_PROGRAMS = \ $(NULL) TEST_CFLAGS = \ - $(LIBVA_EXTRA_CFLAGS) \ $(GST_CFLAGS) \ -I$(top_srcdir)/gst-libs \ $(X11_CFLAGS) TEST_LIBS = \ - $(LIBVA_EXTRA_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la \ $(X11_LIBS) From 520f7ac5b68d4f2fbca47f8206133dc621bb97c3 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 16:25:56 +0000 Subject: [PATCH 0176/3781] Include gstvaapicompat.h in source files only, not headers. --- gst-libs/gst/vaapi/gstvaapiimage.c | 1 + gst-libs/gst/vaapi/gstvaapiimageformat.c | 2 +- gst-libs/gst/vaapi/gstvaapiimageformat.h | 25 +++++++++--------------- gst-libs/gst/vaapi/gstvaapiobject.c | 1 + gst-libs/gst/vaapi/gstvaapisubpicture.c | 1 + gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 1 + 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index e8752cd978..9413f5e070 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -25,6 +25,7 @@ #include "config.h" #include +#include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapiimage.h" #include "gstvaapiobject_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 45d2f75f7e..038c37d656 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -24,8 +24,8 @@ */ #include "config.h" -#include #include +#include "gstvaapicompat.h" #include "gstvaapiimageformat.h" typedef enum _GstVaapiImageFormatType GstVaapiImageFormatType; diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index 46b6aa6e83..c48635947a 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -21,14 +21,7 @@ #ifndef GST_VAAPI_IMAGE_FORMAT_H #define GST_VAAPI_IMAGE_FORMAT_H -#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 -# include -# include -#else -# include -#endif - -#include +#include G_BEGIN_DECLS @@ -56,14 +49,14 @@ typedef enum _GstVaapiImageFormat GstVaapiImageFormat; * The set of all image formats for #GstVaapiImage. */ enum _GstVaapiImageFormat { - GST_VAAPI_IMAGE_NV12 = VA_FOURCC('N','V','1','2'), - GST_VAAPI_IMAGE_YV12 = VA_FOURCC('Y','V','1','2'), - GST_VAAPI_IMAGE_I420 = VA_FOURCC('I','4','2','0'), - GST_VAAPI_IMAGE_AYUV = VA_FOURCC('A','Y','U','V'), - GST_VAAPI_IMAGE_ARGB = VA_FOURCC('A','R','G','B'), - GST_VAAPI_IMAGE_RGBA = VA_FOURCC('R','G','B','A'), - GST_VAAPI_IMAGE_ABGR = VA_FOURCC('A','B','G','R'), - GST_VAAPI_IMAGE_BGRA = VA_FOURCC('B','G','R','A'), + GST_VAAPI_IMAGE_NV12 = GST_MAKE_FOURCC('N','V','1','2'), + GST_VAAPI_IMAGE_YV12 = GST_MAKE_FOURCC('Y','V','1','2'), + GST_VAAPI_IMAGE_I420 = GST_MAKE_FOURCC('I','4','2','0'), + GST_VAAPI_IMAGE_AYUV = GST_MAKE_FOURCC('A','Y','U','V'), + GST_VAAPI_IMAGE_ARGB = GST_MAKE_FOURCC('A','R','G','B'), + GST_VAAPI_IMAGE_RGBA = GST_MAKE_FOURCC('R','G','B','A'), + GST_VAAPI_IMAGE_ABGR = GST_MAKE_FOURCC('A','B','G','R'), + GST_VAAPI_IMAGE_BGRA = GST_MAKE_FOURCC('B','G','R','A'), }; gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 32f82f1fff..03a9db6606 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -24,6 +24,7 @@ */ #include "config.h" +#include "gstvaapicompat.h" #include "gstvaapiobject.h" #include "gstvaapiobject_priv.h" #include "gstvaapiparamspecs.h" diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 9f4948e3a9..7c922555a4 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -25,6 +25,7 @@ #include "config.h" #include +#include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapisubpicture.h" #include "gstvaapiobject_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 67457b25cd..ce15a63036 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -26,6 +26,7 @@ #include "config.h" #include #include +#include "gstvaapicompat.h" #include "gstvaapiwindow_x11.h" #include "gstvaapidisplay_x11.h" #include "gstvaapiutils_x11.h" From 3fe6ca16e279cd26bbb3d1d7450fb616eda61660 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 16:27:36 +0000 Subject: [PATCH 0177/3781] gstvaapicompat.h is now a private header (not installed). --- gst-libs/gst/vaapi/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f8d7203ee3..b1bef04ee2 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -26,7 +26,6 @@ libgstvaapi_source_c = \ $(NULL) libgstvaapi_source_h = \ - gstvaapicompat.h \ gstvaapidisplay.h \ gstvaapiimage.h \ gstvaapiimageformat.h \ @@ -45,6 +44,7 @@ libgstvaapi_source_h = \ $(NULL) libgstvaapi_source_priv_h = \ + gstvaapicompat.h \ gstvaapidebug.h \ gstvaapiobject_priv.h \ gstvaapiutils.h \ @@ -58,6 +58,7 @@ libgstvaapi_x11_source_c = \ $(NULL) libgstvaapi_x11_source_h = \ + gstvaapicompat.h \ gstvaapidisplay_x11.h \ gstvaapiwindow_x11.h \ $(NULL) From 5b9e2cd7d8e55f512d19d4f6b8c34dc001e73588 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 16:35:36 +0000 Subject: [PATCH 0178/3781] Improve versioning summary. --- configure.ac | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 55fd58c0fc..3e66046a16 100644 --- a/configure.ac +++ b/configure.ac @@ -195,6 +195,13 @@ AC_SUBST(LIBVA_EXTRA_LIBS) VA_VERSION=`$PKG_CONFIG --modversion libva` VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1` VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2` +VA_MICRO_VERSION=`echo "$VA_VERSION" | cut -d'.' -f3` +VA_SDS_VERSION=`$PKG_CONFIG libva --variable sdsversion` + +VA_VERSION_STR="$VA_VERSION" +if test -n "$VA_SDS_VERSION"; then + VA_VERSION_STR="$VA_VERSION_STR-sds$VA_SDS_VERSION" +fi pkgconfigdir=${libdir}/pkgconfig AC_SUBST(pkgconfigdir) @@ -236,5 +243,5 @@ dnl Print summary echo echo gstreamer-vaapi configuration summary: echo -echo VA-API version ................... : $VA_VERSION +echo VA-API version ................... : $VA_VERSION_STR echo From 1661b0a2a7e3ffbeb7b5f85bb60821470f8cf07a Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 16:37:35 +0000 Subject: [PATCH 0179/3781] Factor out use gstreamer-vaapi (PACKAGE name). --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 3e66046a16..a4b9ad3a1b 100644 --- a/configure.ac +++ b/configure.ac @@ -241,7 +241,7 @@ debian.upstream/libgstvaapi-x11.install.in dnl Print summary echo -echo gstreamer-vaapi configuration summary: +echo $PACKAGE configuration summary: echo echo VA-API version ................... : $VA_VERSION_STR echo From 0881507989a455bba73d80573754bb41978f192b Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 17:22:18 +0000 Subject: [PATCH 0180/3781] Make GstVaapiWindow* derive from GstVaapiObject. --- gst-libs/gst/vaapi/gstvaapiwindow.c | 41 ++----- gst-libs/gst/vaapi/gstvaapiwindow.h | 5 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 138 ++++++++---------------- 3 files changed, 54 insertions(+), 130 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index aac518f36f..101a7e0d92 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -25,11 +25,12 @@ #include "config.h" #include "gstvaapiwindow.h" +#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, G_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, GST_VAAPI_TYPE_OBJECT); #define GST_VAAPI_WINDOW_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ @@ -37,7 +38,6 @@ G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, G_TYPE_OBJECT); GstVaapiWindowPrivate)) struct _GstVaapiWindowPrivate { - GstVaapiDisplay *display; guint width; guint height; gboolean is_constructed : 1; @@ -48,7 +48,6 @@ struct _GstVaapiWindowPrivate { enum { PROP_0, - PROP_DISPLAY, PROP_WIDTH, PROP_HEIGHT, PROP_FULLSCREEN @@ -67,7 +66,11 @@ gst_vaapi_window_ensure_size(GstVaapiWindow *window) if (klass->get_geometry) klass->get_geometry(window, NULL, NULL, &priv->width, &priv->height); - gst_vaapi_display_get_size(priv->display, &display_width, &display_height); + gst_vaapi_display_get_size( + GST_VAAPI_OBJECT_GET_DISPLAY(window), + &display_width, + &display_height + ); priv->is_fullscreen_changed = FALSE; priv->is_fullscreen = (priv->width == display_width && priv->height == display_height); @@ -76,14 +79,7 @@ gst_vaapi_window_ensure_size(GstVaapiWindow *window) static void gst_vaapi_window_destroy(GstVaapiWindow *window) { - GstVaapiWindowPrivate * const priv = window->priv; - GST_VAAPI_WINDOW_GET_CLASS(window)->destroy(window); - - if (priv->display) { - g_object_unref(priv->display); - priv->display = NULL; - } } static gboolean @@ -125,9 +121,6 @@ gst_vaapi_window_set_property( GstVaapiWindow * const window = GST_VAAPI_WINDOW(object); switch (prop_id) { - case PROP_DISPLAY: - window->priv->display = g_object_ref(g_value_get_object(value)); - break; case PROP_WIDTH: gst_vaapi_window_set_width(window, g_value_get_uint(value)); break; @@ -154,9 +147,6 @@ gst_vaapi_window_get_property( GstVaapiWindow * const window = GST_VAAPI_WINDOW(object); switch (prop_id) { - case PROP_DISPLAY: - g_value_set_object(value, gst_vaapi_window_get_display(window)); - break; case PROP_WIDTH: g_value_set_uint(value, gst_vaapi_window_get_width(window)); break; @@ -197,20 +187,6 @@ gst_vaapi_window_class_init(GstVaapiWindowClass *klass) object_class->get_property = gst_vaapi_window_get_property; object_class->constructed = gst_vaapi_window_constructed; - /** - * GstVaapiWindowX11:display: - * - * The #GstVaapiDisplay this window is bound to - */ - g_object_class_install_property - (object_class, - PROP_DISPLAY, - g_param_spec_object("display", - "Display", - "The GstVaapiDisplay this window is bound to", - GST_VAAPI_TYPE_DISPLAY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, PROP_WIDTH, @@ -245,7 +221,6 @@ gst_vaapi_window_init(GstVaapiWindow *window) GstVaapiWindowPrivate *priv = GST_VAAPI_WINDOW_GET_PRIVATE(window); window->priv = priv; - priv->display = NULL; priv->width = 1; priv->height = 1; priv->is_constructed = FALSE; @@ -266,7 +241,7 @@ gst_vaapi_window_get_display(GstVaapiWindow *window) { g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), NULL); - return window->priv->display; + return GST_VAAPI_OBJECT_GET_DISPLAY(window); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index a7650d89ea..8988c1cb30 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -63,7 +64,7 @@ typedef struct _GstVaapiWindowClass GstVaapiWindowClass; */ struct _GstVaapiWindow { /*< private >*/ - GObject parent_instance; + GstVaapiObject parent_instance; GstVaapiWindowPrivate *priv; }; @@ -82,7 +83,7 @@ struct _GstVaapiWindow { */ struct _GstVaapiWindowClass { /*< private >*/ - GObjectClass parent_class; + GstVaapiObjectClass parent_class; /*< public >*/ gboolean (*create) (GstVaapiWindow *window, guint *width, guint *height); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index ce15a63036..b93bd9bc68 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -44,7 +44,6 @@ G_DEFINE_TYPE(GstVaapiWindowX11, gst_vaapi_window_x11, GST_VAAPI_TYPE_WINDOW); struct _GstVaapiWindowX11Private { GstVaapiDisplay *display; - Window xid; Atom atom_NET_WM_STATE; Atom atom_NET_WM_STATE_FULLSCREEN; guint create_window : 1; @@ -52,12 +51,6 @@ struct _GstVaapiWindowX11Private { guint fullscreen_on_map : 1; }; -enum { - PROP_0, - - PROP_XID, -}; - #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ #define _NET_WM_STATE_ADD 1 /* add/set property */ #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ @@ -72,7 +65,7 @@ send_wmspec_change_state(GstVaapiWindowX11 *window, Atom state, gboolean add) memset(&xclient, 0, sizeof(xclient)); xclient.type = ClientMessage; - xclient.window = priv->xid; + xclient.window = GST_VAAPI_OBJECT_ID(window); xclient.message_type = priv->atom_NET_WM_STATE; xclient.format = 32; @@ -96,12 +89,13 @@ wait_event(GstVaapiWindow *window, int type) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + const Window xid = GST_VAAPI_OBJECT_ID(window); XEvent e; Bool got_event; for (;;) { GST_VAAPI_DISPLAY_LOCK(priv->display); - got_event = XCheckTypedWindowEvent(dpy, priv->xid, type, &e); + got_event = XCheckTypedWindowEvent(dpy, xid, type, &e); GST_VAAPI_DISPLAY_UNLOCK(priv->display); if (got_event) break; @@ -114,6 +108,7 @@ timed_wait_event(GstVaapiWindow *window, int type, guint64 end_time, XEvent *e) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + const Window xid = GST_VAAPI_OBJECT_ID(window); XEvent tmp_event; GTimeVal now; guint64 now_time; @@ -123,7 +118,7 @@ timed_wait_event(GstVaapiWindow *window, int type, guint64 end_time, XEvent *e) e = &tmp_event; GST_VAAPI_DISPLAY_LOCK(priv->display); - got_event = XCheckTypedWindowEvent(dpy, priv->xid, type, e); + got_event = XCheckTypedWindowEvent(dpy, xid, type, e); GST_VAAPI_DISPLAY_UNLOCK(priv->display); if (got_event) return TRUE; @@ -131,7 +126,7 @@ timed_wait_event(GstVaapiWindow *window, int type, guint64 end_time, XEvent *e) do { g_usleep(10); GST_VAAPI_DISPLAY_LOCK(priv->display); - got_event = XCheckTypedWindowEvent(dpy, priv->xid, type, e); + got_event = XCheckTypedWindowEvent(dpy, xid, type, e); GST_VAAPI_DISPLAY_UNLOCK(priv->display); if (got_event) return TRUE; @@ -146,6 +141,7 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + const Window xid = GST_VAAPI_OBJECT_ID(window); XWindowAttributes wattr; gboolean has_errors; @@ -155,11 +151,11 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); if (!priv->create_window) { - XGetWindowAttributes(dpy, priv->xid, &wattr); + XGetWindowAttributes(dpy, xid, &wattr); if (!(wattr.your_event_mask & StructureNotifyMask)) - XSelectInput(dpy, priv->xid, StructureNotifyMask); + XSelectInput(dpy, xid, StructureNotifyMask); } - XMapWindow(dpy, priv->xid); + XMapWindow(dpy, xid); has_errors = x11_untrap_errors() != 0; GST_VAAPI_DISPLAY_UNLOCK(priv->display); @@ -169,7 +165,7 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) !(wattr.your_event_mask & StructureNotifyMask)) { GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); - XSelectInput(dpy, priv->xid, wattr.your_event_mask); + XSelectInput(dpy, xid, wattr.your_event_mask); has_errors = x11_untrap_errors() != 0; GST_VAAPI_DISPLAY_UNLOCK(priv->display); } @@ -186,6 +182,7 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + const Window xid = GST_VAAPI_OBJECT_ID(window); XWindowAttributes wattr; gboolean has_errors; @@ -195,11 +192,11 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); if (!priv->create_window) { - XGetWindowAttributes(dpy, priv->xid, &wattr); + XGetWindowAttributes(dpy, xid, &wattr); if (!(wattr.your_event_mask & StructureNotifyMask)) - XSelectInput(dpy, priv->xid, StructureNotifyMask); + XSelectInput(dpy, xid, StructureNotifyMask); } - XUnmapWindow(dpy, priv->xid); + XUnmapWindow(dpy, xid); has_errors = x11_untrap_errors() != 0; GST_VAAPI_DISPLAY_UNLOCK(priv->display); @@ -209,7 +206,7 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) !(wattr.your_event_mask & StructureNotifyMask)) { GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); - XSelectInput(dpy, priv->xid, wattr.your_event_mask); + XSelectInput(dpy, xid, wattr.your_event_mask); has_errors = x11_untrap_errors() != 0; GST_VAAPI_DISPLAY_UNLOCK(priv->display); } @@ -223,6 +220,7 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + Window xid = GST_VAAPI_OBJECT_ID(window); XWindowAttributes wattr; Atom atoms[2]; gboolean ok; @@ -232,11 +230,11 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) "_NET_WM_STATE_FULLSCREEN", }; - if (!priv->create_window && priv->xid) { + if (!priv->create_window && xid) { GST_VAAPI_DISPLAY_LOCK(priv->display); - XGetWindowAttributes(dpy, priv->xid, &wattr); + XGetWindowAttributes(dpy, xid, &wattr); priv->is_mapped = wattr.map_state == IsViewable; - ok = x11_get_geometry(dpy, priv->xid, NULL, NULL, width, height); + ok = x11_get_geometry(dpy, xid, NULL, NULL, width, height); GST_VAAPI_DISPLAY_UNLOCK(priv->display); return ok; } @@ -246,11 +244,14 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) priv->atom_NET_WM_STATE = atoms[0]; priv->atom_NET_WM_STATE_FULLSCREEN = atoms[1]; - priv->xid = x11_create_window(dpy, *width, *height); - if (priv->xid) - XRaiseWindow(dpy, priv->xid); + xid = x11_create_window(dpy, *width, *height); + if (xid) + XRaiseWindow(dpy, xid); GST_VAAPI_DISPLAY_UNLOCK(priv->display); - return priv->xid != None; + + GST_DEBUG("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(xid)); + GST_VAAPI_OBJECT_ID(window) = xid; + return xid != None; } static void @@ -258,14 +259,15 @@ gst_vaapi_window_x11_destroy(GstVaapiWindow *window) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + const Window xid = GST_VAAPI_OBJECT_ID(window); - if (priv->xid) { + if (xid) { if (priv->create_window) { GST_VAAPI_DISPLAY_LOCK(priv->display); - XDestroyWindow(dpy, priv->xid); + XDestroyWindow(dpy, xid); GST_VAAPI_DISPLAY_UNLOCK(priv->display); } - priv->xid = None; + GST_VAAPI_OBJECT_ID(window) = None; } if (priv->display) { @@ -284,8 +286,9 @@ gst_vaapi_window_x11_get_geometry( { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + const Window xid = GST_VAAPI_OBJECT_ID(window); - return x11_get_geometry(dpy, priv->xid, px, py, pwidth, pheight); + return x11_get_geometry(dpy, xid, px, py, pwidth, pheight); } static gboolean @@ -293,6 +296,7 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + const Window xid = GST_VAAPI_OBJECT_ID(window); XEvent e; guint width, height; gboolean has_errors; @@ -307,7 +311,7 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) XChangeProperty( dpy, - priv->xid, + xid, priv->atom_NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&priv->atom_NET_WM_STATE_FULLSCREEN, 1 @@ -327,7 +331,7 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) XDeleteProperty( dpy, - priv->xid, + xid, priv->atom_NET_WM_STATE ); } @@ -372,14 +376,14 @@ gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height) GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; gboolean has_errors; - if (!priv->xid) + if (!GST_VAAPI_OBJECT_ID(window)) return FALSE; GST_VAAPI_DISPLAY_LOCK(priv->display); x11_trap_errors(); XResizeWindow( GST_VAAPI_DISPLAY_XDISPLAY(priv->display), - priv->xid, + GST_VAAPI_OBJECT_ID(window), width, height ); @@ -413,7 +417,7 @@ gst_vaapi_window_x11_render( status = vaPutSurface( GST_VAAPI_DISPLAY_VADISPLAY(display), surface_id, - GST_VAAPI_WINDOW_X11(window)->priv->xid, + GST_VAAPI_OBJECT_ID(window), src_rect->x, src_rect->y, src_rect->width, @@ -438,46 +442,6 @@ gst_vaapi_window_x11_finalize(GObject *object) G_OBJECT_CLASS(gst_vaapi_window_x11_parent_class)->finalize(object); } -static void -gst_vaapi_window_x11_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiWindowX11 * const window = GST_VAAPI_WINDOW_X11(object); - - switch (prop_id) { - case PROP_XID: - window->priv->xid = g_value_get_uint(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_window_x11_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiWindowX11 * const window = GST_VAAPI_WINDOW_X11(object); - - switch (prop_id) { - case PROP_XID: - g_value_set_uint(value, gst_vaapi_window_x11_get_xid(window)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - static void gst_vaapi_window_x11_constructed(GObject *object) { @@ -487,7 +451,7 @@ gst_vaapi_window_x11_constructed(GObject *object) window->priv->display = g_object_ref(gst_vaapi_window_get_display(GST_VAAPI_WINDOW(window))); - window->priv->create_window = window->priv->xid == None; + window->priv->create_window = GST_VAAPI_OBJECT_ID(object) == None; parent_class = G_OBJECT_CLASS(gst_vaapi_window_x11_parent_class); if (parent_class->constructed) @@ -503,8 +467,6 @@ gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) g_type_class_add_private(klass, sizeof(GstVaapiWindowX11Private)); object_class->finalize = gst_vaapi_window_x11_finalize; - object_class->set_property = gst_vaapi_window_x11_set_property; - object_class->get_property = gst_vaapi_window_x11_get_property; object_class->constructed = gst_vaapi_window_x11_constructed; window_class->create = gst_vaapi_window_x11_create; @@ -515,20 +477,6 @@ gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) window_class->set_fullscreen = gst_vaapi_window_x11_set_fullscreen; window_class->resize = gst_vaapi_window_x11_resize; window_class->render = gst_vaapi_window_x11_render; - - /** - * GstVaapiWindowX11:xid: - * - * The underlying X11 #Window XID. - */ - g_object_class_install_property - (object_class, - PROP_XID, - g_param_spec_uint("xid", - "X window id", - "The underlying X11 window id", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -538,7 +486,6 @@ gst_vaapi_window_x11_init(GstVaapiWindowX11 *window) window->priv = priv; priv->display = NULL; - priv->xid = None; priv->create_window = TRUE; priv->is_mapped = FALSE; priv->fullscreen_on_map = FALSE; @@ -567,6 +514,7 @@ gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) return g_object_new(GST_VAAPI_TYPE_WINDOW_X11, "display", display, + "id", (GstVaapiID)None, "width", width, "height", height, NULL); @@ -594,7 +542,7 @@ gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) return g_object_new(GST_VAAPI_TYPE_WINDOW_X11, "display", display, - "xid", xid, + "id", (GstVaapiID)xid, NULL); } @@ -613,5 +561,5 @@ gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window) { g_return_val_if_fail(GST_VAAPI_WINDOW_X11(window), None); - return window->priv->xid; + return GST_VAAPI_OBJECT_ID(window); } From 9961c03c6a05fb81c5008c4186dbb05f06946528 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 17:38:23 +0000 Subject: [PATCH 0181/3781] All GstVaapiID are initialized to GST_VAAPI_ID_NONE by default. Besides, all GstVaapiObject derived class shall initialize "id" to a valid value. --- docs/reference/libs/libs-sections.txt | 2 ++ gst-libs/gst/vaapi/gstvaapiimage.c | 2 ++ gst-libs/gst/vaapi/gstvaapiobject.c | 9 ++++----- gst-libs/gst/vaapi/gstvaapiparamspecs.c | 9 +-------- gst-libs/gst/vaapi/gstvaapisubpicture.c | 1 + gst-libs/gst/vaapi/gstvaapisurface.c | 1 + gst-libs/gst/vaapi/gstvaapitypes.h | 15 +++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 4 ++-- 8 files changed, 28 insertions(+), 15 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 3d3ded2782..b5a1ddf61b 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -161,6 +161,8 @@ GST_VAAPI_VIDEO_BUFFER_GET_CLASS GstVaapiID GST_VAAPI_ID_FORMAT GST_VAAPI_ID_ARGS +GST_VAAPI_ID +GST_VAAPI_ID_NONE GstVaapiPoint GstVaapiRectangle
diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 9413f5e070..c4f2b722c9 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -444,6 +444,7 @@ gst_vaapi_image_new( image = g_object_new( GST_VAAPI_TYPE_IMAGE, "display", display, + "id", GST_VAAPI_ID(VA_INVALID_ID), "format", format, "width", width, "height", height, @@ -489,6 +490,7 @@ gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image) image = g_object_new( GST_VAAPI_TYPE_IMAGE, "display", display, + "id", GST_VAAPI_ID(va_image->image_id), "image", va_image, NULL ); diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 03a9db6606..91bb17bb95 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -24,7 +24,6 @@ */ #include "config.h" -#include "gstvaapicompat.h" #include "gstvaapiobject.h" #include "gstvaapiobject_priv.h" #include "gstvaapiparamspecs.h" @@ -70,7 +69,7 @@ gst_vaapi_object_finalize(GObject *object) { GstVaapiObjectPrivate * const priv = GST_VAAPI_OBJECT(object)->priv; - priv->id = VA_INVALID_ID; + priv->id = GST_VAAPI_ID_NONE; if (priv->display) { g_object_unref(priv->display); @@ -163,7 +162,7 @@ gst_vaapi_object_class_init(GstVaapiObjectClass *klass) gst_vaapi_param_spec_id("id", "ID", "The GstVaapiID contained in this object", - VA_INVALID_ID, + GST_VAAPI_ID_NONE, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); /** @@ -191,7 +190,7 @@ gst_vaapi_object_init(GstVaapiObject *object) object->priv = priv; priv->display = NULL; - priv->id = VA_INVALID_ID; + priv->id = GST_VAAPI_ID_NONE; priv->is_destroying = FALSE; } @@ -222,7 +221,7 @@ gst_vaapi_object_get_display(GstVaapiObject *object) GstVaapiID gst_vaapi_object_get_id(GstVaapiObject *object) { - g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), VA_INVALID_ID); + g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), GST_VAAPI_ID_NONE); return object->priv->id; } diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.c b/gst-libs/gst/vaapi/gstvaapiparamspecs.c index e50fa1e9d2..ef85a57f28 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.c +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.c @@ -26,20 +26,13 @@ #include "config.h" #include "gstvaapiparamspecs.h" #include "gstvaapivalue.h" -#include "gstvaapicompat.h" - -#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 -# include -#else -# include -#endif /* --- GstVaapiParamSpecID --- */ static void gst_vaapi_param_id_init(GParamSpec *pspec) { - GST_VAAPI_PARAM_SPEC_ID(pspec)->default_value = VA_INVALID_ID; + GST_VAAPI_PARAM_SPEC_ID(pspec)->default_value = GST_VAAPI_ID_NONE; } static void diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 7c922555a4..eb44ced7f1 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -212,6 +212,7 @@ gst_vaapi_subpicture_new(GstVaapiImage *image) return g_object_new(GST_VAAPI_TYPE_SUBPICTURE, "display", GST_VAAPI_OBJECT_GET_DISPLAY(image), + "id", GST_VAAPI_ID(VA_INVALID_ID), "image", image, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 80ad4f82dc..03ded417a4 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -298,6 +298,7 @@ gst_vaapi_surface_new( return g_object_new(GST_VAAPI_TYPE_SURFACE, "display", display, + "id", GST_VAAPI_ID(VA_INVALID_ID), "width", width, "height", height, "chroma-type", chroma_type, diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 451486a7aa..d35216e56d 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -48,6 +48,21 @@ typedef guint64 GstVaapiID; # error "unsupported value for GST_VAAPI_TYPE_ID_SIZE" #endif +/** + * GST_VAAPI_ID: + * @id: an arbitrary integer value + * + * Macro that creates a #GstVaapiID from @id. + */ +#define GST_VAAPI_ID(id) ((GstVaapiID)(id)) + +/** + * GST_VAAPI_ID_NONE: + * + * Macro that evaluates to the default #GstVaapiID value. + */ +#define GST_VAAPI_ID_NONE GST_VAAPI_ID(0) + /** * GST_VAAPI_ID_FORMAT: * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index b93bd9bc68..2d3ac8a6bf 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -514,7 +514,7 @@ gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) return g_object_new(GST_VAAPI_TYPE_WINDOW_X11, "display", display, - "id", (GstVaapiID)None, + "id", GST_VAAPI_ID(None), "width", width, "height", height, NULL); @@ -542,7 +542,7 @@ gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) return g_object_new(GST_VAAPI_TYPE_WINDOW_X11, "display", display, - "id", (GstVaapiID)xid, + "id", GST_VAAPI_ID(xid), NULL); } From 2ecadd45b8401e4379eda80ff857c4719b018bc9 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 24 Mar 2010 17:40:19 +0000 Subject: [PATCH 0182/3781] Rename to GST_VAAPI_OBJECT_DISPLAY(). --- gst-libs/gst/vaapi/gstvaapiimage.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapiobject_priv.h | 4 ++-- gst-libs/gst/vaapi/gstvaapisubpicture.c | 6 +++--- gst-libs/gst/vaapi/gstvaapisurface.c | 16 ++++++++-------- gst-libs/gst/vaapi/gstvaapiwindow.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index c4f2b722c9..b637484a69 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -147,7 +147,7 @@ vaapi_image_is_linear(const VAImage *va_image) static void gst_vaapi_image_destroy(GstVaapiImage *image) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(image); + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image); VAImageID image_id; VAStatus status; @@ -170,7 +170,7 @@ gst_vaapi_image_destroy(GstVaapiImage *image) static gboolean _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(image); + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image); GstVaapiImagePrivate * const priv = image->priv; const VAImageFormat *va_format; VAStatus status; @@ -736,7 +736,7 @@ _gst_vaapi_image_map(GstVaapiImage *image) if (_gst_vaapi_image_is_mapped(image)) return TRUE; - display = GST_VAAPI_OBJECT_GET_DISPLAY(image); + display = GST_VAAPI_OBJECT_DISPLAY(image); if (!display) return FALSE; @@ -781,7 +781,7 @@ _gst_vaapi_image_unmap(GstVaapiImage *image) if (!_gst_vaapi_image_is_mapped(image)) return FALSE; - display = GST_VAAPI_OBJECT_GET_DISPLAY(image); + display = GST_VAAPI_OBJECT_DISPLAY(image); if (!display) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index aeea393ac9..7bd87b1123 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -33,13 +33,13 @@ G_BEGIN_DECLS #define GST_VAAPI_OBJECT_CAST(object) ((GstVaapiObject *)(object)) /** - * GST_VAAPI_OBJECT_GET_DISPLAY: + * GST_VAAPI_OBJECT_DISPLAY: * @object: a #GstVaapiObject * * Macro that evaluates to the #GstVaapiDisplay the @object is bound to. * This is an internal macro that does not do any run-time type check. */ -#define GST_VAAPI_OBJECT_GET_DISPLAY(object) \ +#define GST_VAAPI_OBJECT_DISPLAY(object) \ GST_VAAPI_OBJECT_CAST(object)->priv->display /** diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index eb44ced7f1..d3047c4814 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -53,7 +53,7 @@ enum { static void gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(subpicture); + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture); GstVaapiSubpicturePrivate * const priv = subpicture->priv; VASubpictureID subpicture_id; VAStatus status; @@ -86,7 +86,7 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) static gboolean gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(subpicture); + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture); GstVaapiSubpicturePrivate * const priv = subpicture->priv; VASubpictureID subpicture_id; VAStatus status; @@ -211,7 +211,7 @@ gst_vaapi_subpicture_new(GstVaapiImage *image) GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(image))); return g_object_new(GST_VAAPI_TYPE_SUBPICTURE, - "display", GST_VAAPI_OBJECT_GET_DISPLAY(image), + "display", GST_VAAPI_OBJECT_DISPLAY(image), "id", GST_VAAPI_ID(VA_INVALID_ID), "image", image, NULL); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 03ded417a4..58026d364b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -79,7 +79,7 @@ destroy_subpicture_cb(gpointer subpicture, gpointer surface) static void gst_vaapi_surface_destroy(GstVaapiSurface *surface) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface); GstVaapiSurfacePrivate * const priv = surface->priv; VASurfaceID surface_id; VAStatus status; @@ -110,7 +110,7 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface) static gboolean gst_vaapi_surface_create(GstVaapiSurface *surface) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface); GstVaapiSurfacePrivate * const priv = surface->priv; VASurfaceID surface_id; VAStatus status; @@ -410,7 +410,7 @@ gst_vaapi_surface_derive_image(GstVaapiSurface *surface) g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + display = GST_VAAPI_OBJECT_DISPLAY(surface); va_image.image_id = VA_INVALID_ID; va_image.buf = VA_INVALID_ID; @@ -450,7 +450,7 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); - display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + display = GST_VAAPI_OBJECT_DISPLAY(surface); if (!display) return FALSE; @@ -497,7 +497,7 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); - display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + display = GST_VAAPI_OBJECT_DISPLAY(surface); if (!display) return FALSE; @@ -591,7 +591,7 @@ _gst_vaapi_surface_associate_subpicture( VASurfaceID surface_id; VAStatus status; - display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + display = GST_VAAPI_OBJECT_DISPLAY(surface); if (!display) return FALSE; @@ -684,7 +684,7 @@ _gst_vaapi_surface_deassociate_subpicture( VASurfaceID surface_id; VAStatus status; - display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + display = GST_VAAPI_OBJECT_DISPLAY(surface); if (!display) return FALSE; @@ -722,7 +722,7 @@ gst_vaapi_surface_sync(GstVaapiSurface *surface) g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + display = GST_VAAPI_OBJECT_DISPLAY(surface); if (!display) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 101a7e0d92..495d86fce8 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -67,7 +67,7 @@ gst_vaapi_window_ensure_size(GstVaapiWindow *window) klass->get_geometry(window, NULL, NULL, &priv->width, &priv->height); gst_vaapi_display_get_size( - GST_VAAPI_OBJECT_GET_DISPLAY(window), + GST_VAAPI_OBJECT_DISPLAY(window), &display_width, &display_height ); @@ -241,7 +241,7 @@ gst_vaapi_window_get_display(GstVaapiWindow *window) { g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), NULL); - return GST_VAAPI_OBJECT_GET_DISPLAY(window); + return GST_VAAPI_OBJECT_DISPLAY(window); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 2d3ac8a6bf..4b8ea27062 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -405,7 +405,7 @@ gst_vaapi_window_x11_render( VASurfaceID surface_id; VAStatus status; - display = GST_VAAPI_OBJECT_GET_DISPLAY(surface); + display = GST_VAAPI_OBJECT_DISPLAY(surface); if (!display) return FALSE; From 56658c7aac67f037eea8c44e59f966fceffe3bd4 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 09:37:40 +0000 Subject: [PATCH 0183/3781] Add more internal helpers. --- gst-libs/gst/vaapi/gstvaapiobject_priv.h | 41 ++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 7bd87b1123..0a8f75e82f 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -42,6 +42,47 @@ G_BEGIN_DECLS #define GST_VAAPI_OBJECT_DISPLAY(object) \ GST_VAAPI_OBJECT_CAST(object)->priv->display +/** + * GST_VAAPI_OBJECT_VADISPLAY: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the #VADisplay of @display. + * This is an internal macro that does not do any run-time type check. + */ +#define GST_VAAPI_OBJECT_VADISPLAY(object) \ + GST_VAAPI_DISPLAY_VADISPLAY(GST_VAAPI_OBJECT_DISPLAY(object)) + +/** + * GST_VAAPI_OBJECT_XDISPLAY: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the underlying X11 #Display of @display. + * This is an internal macro that does not do any run-time type check. + * Besides, this is only valid within libgstvaapi-x11. + */ +#define GST_VAAPI_OBJECT_XDISPLAY(object) \ + GST_VAAPI_DISPLAY_XDISPLAY(GST_VAAPI_OBJECT_DISPLAY(object)) + +/** + * GST_VAAPI_OBJECT_LOCK_DISPLAY: + * @object: a #GstVaapiObject + * + * Macro that locks the #GstVaapiDisplay contained in the @object. + * This is an internal macro that does not do any run-time type check. + */ +#define GST_VAAPI_OBJECT_LOCK_DISPLAY(object) \ + GST_VAAPI_DISPLAY_LOCK(GST_VAAPI_OBJECT_DISPLAY(object)) + +/** + * GST_VAAPI_OBJECT_UNLOCK_DISPLAY: + * @object: a #GstVaapiObject + * + * Macro that unlocks the #GstVaapiDisplay contained in the @object. + * This is an internal macro that does not do any run-time type check. + */ +#define GST_VAAPI_OBJECT_UNLOCK_DISPLAY(object) \ + GST_VAAPI_DISPLAY_UNLOCK(GST_VAAPI_OBJECT_DISPLAY(object)) + /** * GST_VAAPI_OBJECT_ID: * @object: a #GstVaapiObject From e4775c4e16ac74f9589dda5b2a681c58c993387d Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 09:39:17 +0000 Subject: [PATCH 0184/3781] Use the parent display object, no need to maintain another one. In the end, libgstvaapi-x11 reduced by 1 KB in .text vs. 0.1.1. --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 141 +++++++++++------------- 1 file changed, 63 insertions(+), 78 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 4b8ea27062..ffe1a3720f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -43,7 +43,6 @@ G_DEFINE_TYPE(GstVaapiWindowX11, gst_vaapi_window_x11, GST_VAAPI_TYPE_WINDOW); GstVaapiWindowX11Private)) struct _GstVaapiWindowX11Private { - GstVaapiDisplay *display; Atom atom_NET_WM_STATE; Atom atom_NET_WM_STATE_FULLSCREEN; guint create_window : 1; @@ -59,7 +58,7 @@ static void send_wmspec_change_state(GstVaapiWindowX11 *window, Atom state, gboolean add) { GstVaapiWindowX11Private * const priv = window->priv; - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); XClientMessageEvent xclient; memset(&xclient, 0, sizeof(xclient)); @@ -87,16 +86,15 @@ send_wmspec_change_state(GstVaapiWindowX11 *window, Atom state, gboolean add) static void wait_event(GstVaapiWindow *window, int type) { - GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - const Window xid = GST_VAAPI_OBJECT_ID(window); - XEvent e; - Bool got_event; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + const Window xid = GST_VAAPI_OBJECT_ID(window); + XEvent e; + Bool got_event; for (;;) { - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); got_event = XCheckTypedWindowEvent(dpy, xid, type, &e); - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (got_event) break; g_usleep(10); @@ -106,28 +104,27 @@ wait_event(GstVaapiWindow *window, int type) static gboolean timed_wait_event(GstVaapiWindow *window, int type, guint64 end_time, XEvent *e) { - GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - const Window xid = GST_VAAPI_OBJECT_ID(window); - XEvent tmp_event; - GTimeVal now; - guint64 now_time; - Bool got_event; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + const Window xid = GST_VAAPI_OBJECT_ID(window); + XEvent tmp_event; + GTimeVal now; + guint64 now_time; + Bool got_event; if (!e) e = &tmp_event; - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); got_event = XCheckTypedWindowEvent(dpy, xid, type, e); - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (got_event) return TRUE; do { g_usleep(10); - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); got_event = XCheckTypedWindowEvent(dpy, xid, type, e); - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (got_event) return TRUE; g_get_current_time(&now); @@ -140,15 +137,15 @@ static gboolean gst_vaapi_window_x11_show(GstVaapiWindow *window) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - const Window xid = GST_VAAPI_OBJECT_ID(window); - XWindowAttributes wattr; - gboolean has_errors; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + const Window xid = GST_VAAPI_OBJECT_ID(window); + XWindowAttributes wattr; + gboolean has_errors; if (priv->is_mapped) return TRUE; - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); x11_trap_errors(); if (!priv->create_window) { XGetWindowAttributes(dpy, xid, &wattr); @@ -157,17 +154,17 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) } XMapWindow(dpy, xid); has_errors = x11_untrap_errors() != 0; - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (!has_errors) { wait_event(window, MapNotify); if (!priv->create_window && !(wattr.your_event_mask & StructureNotifyMask)) { - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); x11_trap_errors(); XSelectInput(dpy, xid, wattr.your_event_mask); has_errors = x11_untrap_errors() != 0; - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); } priv->is_mapped = TRUE; @@ -181,15 +178,15 @@ static gboolean gst_vaapi_window_x11_hide(GstVaapiWindow *window) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - const Window xid = GST_VAAPI_OBJECT_ID(window); - XWindowAttributes wattr; - gboolean has_errors; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + const Window xid = GST_VAAPI_OBJECT_ID(window); + XWindowAttributes wattr; + gboolean has_errors; if (!priv->is_mapped) return TRUE; - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); x11_trap_errors(); if (!priv->create_window) { XGetWindowAttributes(dpy, xid, &wattr); @@ -198,17 +195,17 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) } XUnmapWindow(dpy, xid); has_errors = x11_untrap_errors() != 0; - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (!has_errors) { wait_event(window, UnmapNotify); if (!priv->create_window && !(wattr.your_event_mask & StructureNotifyMask)) { - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); x11_trap_errors(); XSelectInput(dpy, xid, wattr.your_event_mask); has_errors = x11_untrap_errors() != 0; - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); } priv->is_mapped = FALSE; } @@ -219,11 +216,11 @@ static gboolean gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - Window xid = GST_VAAPI_OBJECT_ID(window); - XWindowAttributes wattr; - Atom atoms[2]; - gboolean ok; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + Window xid = GST_VAAPI_OBJECT_ID(window); + XWindowAttributes wattr; + Atom atoms[2]; + gboolean ok; static const char *atom_names[2] = { "_NET_WM_STATE", @@ -231,15 +228,15 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) }; if (!priv->create_window && xid) { - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); XGetWindowAttributes(dpy, xid, &wattr); priv->is_mapped = wattr.map_state == IsViewable; ok = x11_get_geometry(dpy, xid, NULL, NULL, width, height); - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); return ok; } - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); XInternAtoms(dpy, (char **)atom_names, G_N_ELEMENTS(atom_names), False, atoms); priv->atom_NET_WM_STATE = atoms[0]; priv->atom_NET_WM_STATE_FULLSCREEN = atoms[1]; @@ -247,7 +244,7 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) xid = x11_create_window(dpy, *width, *height); if (xid) XRaiseWindow(dpy, xid); - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); GST_DEBUG("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(xid)); GST_VAAPI_OBJECT_ID(window) = xid; @@ -258,22 +255,17 @@ static void gst_vaapi_window_x11_destroy(GstVaapiWindow *window) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - const Window xid = GST_VAAPI_OBJECT_ID(window); + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + const Window xid = GST_VAAPI_OBJECT_ID(window); if (xid) { if (priv->create_window) { - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); XDestroyWindow(dpy, xid); - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); } GST_VAAPI_OBJECT_ID(window) = None; } - - if (priv->display) { - g_object_unref(priv->display); - priv->display = NULL; - } } static gboolean @@ -284,9 +276,8 @@ gst_vaapi_window_x11_get_geometry( guint *pwidth, guint *pheight) { - GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - const Window xid = GST_VAAPI_OBJECT_ID(window); + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + const Window xid = GST_VAAPI_OBJECT_ID(window); return x11_get_geometry(dpy, xid, px, py, pwidth, pheight); } @@ -295,15 +286,15 @@ static gboolean gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) { GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); - const Window xid = GST_VAAPI_OBJECT_ID(window); + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + const Window xid = GST_VAAPI_OBJECT_ID(window); XEvent e; guint width, height; gboolean has_errors; GTimeVal now; guint64 end_time; - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); x11_trap_errors(); if (fullscreen) { if (!priv->is_mapped) { @@ -345,7 +336,7 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) } XSync(dpy, False); has_errors = x11_untrap_errors() != 0; - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (has_errors) return FALSE; @@ -356,7 +347,11 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) end_time = DELAY + ((guint64)now.tv_sec * 1000000 + now.tv_usec); while (timed_wait_event(window, ConfigureNotify, end_time, &e)) { if (fullscreen) { - gst_vaapi_display_get_size(priv->display, &width, &height); + gst_vaapi_display_get_size( + GST_VAAPI_OBJECT_DISPLAY(window), + &width, + &height + ); if (e.xconfigure.width == width && e.xconfigure.height == height) return TRUE; } @@ -373,22 +368,21 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) static gboolean gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height) { - GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; gboolean has_errors; if (!GST_VAAPI_OBJECT_ID(window)) return FALSE; - GST_VAAPI_DISPLAY_LOCK(priv->display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); x11_trap_errors(); XResizeWindow( - GST_VAAPI_DISPLAY_XDISPLAY(priv->display), + GST_VAAPI_OBJECT_XDISPLAY(window), GST_VAAPI_OBJECT_ID(window), width, height ); has_errors = x11_untrap_errors() != 0; - GST_VAAPI_DISPLAY_UNLOCK(priv->display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); return !has_errors; } @@ -401,21 +395,16 @@ gst_vaapi_window_x11_render( guint flags ) { - GstVaapiDisplay *display; VASurfaceID surface_id; VAStatus status; - display = GST_VAAPI_OBJECT_DISPLAY(surface); - if (!display) - return FALSE; - surface_id = GST_VAAPI_OBJECT_ID(surface); if (surface_id == VA_INVALID_ID) return FALSE; - GST_VAAPI_DISPLAY_LOCK(display); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); status = vaPutSurface( - GST_VAAPI_DISPLAY_VADISPLAY(display), + GST_VAAPI_OBJECT_VADISPLAY(window), surface_id, GST_VAAPI_OBJECT_ID(window), src_rect->x, @@ -429,7 +418,7 @@ gst_vaapi_window_x11_render( NULL, 0, get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(flags) ); - GST_VAAPI_DISPLAY_UNLOCK(display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (!vaapi_check_status(status, "vaPutSurface()")) return FALSE; @@ -448,9 +437,6 @@ gst_vaapi_window_x11_constructed(GObject *object) GstVaapiWindowX11 * const window = GST_VAAPI_WINDOW_X11(object); GObjectClass *parent_class; - window->priv->display = - g_object_ref(gst_vaapi_window_get_display(GST_VAAPI_WINDOW(window))); - window->priv->create_window = GST_VAAPI_OBJECT_ID(object) == None; parent_class = G_OBJECT_CLASS(gst_vaapi_window_x11_parent_class); @@ -485,7 +471,6 @@ gst_vaapi_window_x11_init(GstVaapiWindowX11 *window) GstVaapiWindowX11Private *priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); window->priv = priv; - priv->display = NULL; priv->create_window = TRUE; priv->is_mapped = FALSE; priv->fullscreen_on_map = FALSE; From 1703ef2acad634d764ce8651c74cce40e53c5572 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 09:49:17 +0000 Subject: [PATCH 0185/3781] Restore the gst_vaapi_{surface,image,subpicture}_get_id() interfaces. --- docs/reference/libs/libs-sections.txt | 3 +++ gst-libs/gst/vaapi/gstvaapiimage.c | 17 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapiimage.h | 3 +++ gst-libs/gst/vaapi/gstvaapisubpicture.c | 16 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapisubpicture.h | 3 +++ gst-libs/gst/vaapi/gstvaapisurface.c | 16 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 3 +++ tests/test-surfaces.c | 6 +++--- 8 files changed, 64 insertions(+), 3 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index b5a1ddf61b..2c118668d0 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -236,6 +236,7 @@ GstVaapiImage GstVaapiImageClass gst_vaapi_image_new gst_vaapi_image_new_with_image +gst_vaapi_image_get_id gst_vaapi_image_get_image gst_vaapi_image_get_format gst_vaapi_image_get_width @@ -268,6 +269,7 @@ GstVaapiSurfaceRenderFlags GstVaapiSurface GstVaapiSurfaceClass gst_vaapi_surface_new +gst_vaapi_surface_get_id gst_vaapi_surface_get_chroma_type gst_vaapi_surface_get_width gst_vaapi_surface_get_height @@ -294,6 +296,7 @@ GST_VAAPI_SURFACE_GET_CLASS GstVaapiSubpicture GstVaapiSubpictureClass gst_vaapi_subpicture_new +gst_vaapi_subpicture_get_id gst_vaapi_subpicture_get_image gst_vaapi_subpicture_set_image diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index b637484a69..d993ef877d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -504,6 +504,23 @@ gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image) return image; } +/** + * gst_vaapi_image_get_id: + * @image: a #GstVaapiImage + * + * Returns the underlying VAImageID of the @image. + * + * Return value: the underlying VA image id + */ +VAImageID +gst_vaapi_image_get_id(GstVaapiImage *image) +{ + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID); + g_return_val_if_fail(image->priv->is_constructed, VA_INVALID_ID); + + return GST_VAAPI_OBJECT_ID(image); +} + /** * gst_vaapi_image_get_image: * @image: a #GstVaapiImage diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index f333c1af22..d15326722f 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -116,6 +116,9 @@ gst_vaapi_image_new( GstVaapiImage * gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image); +VAImageID +gst_vaapi_image_get_id(GstVaapiImage *image); + gboolean gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image); diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index d3047c4814..a015042314 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -217,6 +217,22 @@ gst_vaapi_subpicture_new(GstVaapiImage *image) NULL); } +/** + * gst_vaapi_subpicture_get_id: + * @subpicture: a #GstVaapiSubpicture + * + * Returns the underlying VASubpictureID of the @subpicture. + * + * Return value: the underlying VA subpicture id + */ +VASubpictureID +gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture) +{ + g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), VA_INVALID_ID); + + return GST_VAAPI_OBJECT_ID(subpicture); +} + /** * gst_vaapi_subpicture_get_image: * @subpicture: a #GstVaapiSubpicture diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 3103fc334d..7c4b125c52 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -83,6 +83,9 @@ gst_vaapi_subpicture_get_type(void); GstVaapiSubpicture * gst_vaapi_subpicture_new(GstVaapiImage *image); +VASubpictureID +gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture); + GstVaapiImage * gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 58026d364b..2a26eaaeac 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -305,6 +305,22 @@ gst_vaapi_surface_new( NULL); } +/** + * gst_vaapi_surface_get_id: + * @surface: a #GstVaapiSurface + * + * Returns the underlying VASurfaceID of the @surface. + * + * Return value: the underlying VA surface id + */ +VASurfaceID +gst_vaapi_surface_get_id(GstVaapiSurface *surface) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), VA_INVALID_SURFACE); + + return GST_VAAPI_OBJECT_ID(surface); +} + /** * gst_vaapi_surface_get_chroma_type: * @surface: a #GstVaapiSurface diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index a0e4379b31..db92955539 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -133,6 +133,9 @@ gst_vaapi_surface_new( guint height ); +VASurfaceID +gst_vaapi_surface_get_id(GstVaapiSurface *surface); + GstVaapiChromaType gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface); diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index ef8d277172..933239163c 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -57,7 +57,7 @@ main(int argc, char *argv[]) /* This also tests for the GstVaapiParamSpecID */ g_object_get(G_OBJECT(surface), "id", &surface_id, NULL); - if (surface_id != gst_vaapi_object_get_id(GST_VAAPI_OBJECT(surface))) + if (surface_id != gst_vaapi_surface_get_id(surface)) g_error("could not retrieve the native surface ID"); g_print("created surface %" GST_VAAPI_ID_FORMAT "\n", GST_VAAPI_ID_ARGS(surface_id)); @@ -82,7 +82,7 @@ main(int argc, char *argv[]) if (!surface) g_error("could not allocate Gst/VA surface from pool"); g_print("created surface %" GST_VAAPI_ID_FORMAT " from pool\n", - GST_VAAPI_ID_ARGS(gst_vaapi_object_get_id(GST_VAAPI_OBJECT(surface)))); + GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); surfaces[i] = surface; } @@ -97,7 +97,7 @@ main(int argc, char *argv[]) if (!surfaces[i]) g_error("could not re-allocate Gst/VA surface%d from pool", i); g_print("created surface %" GST_VAAPI_ID_FORMAT " from pool (realloc)\n", - GST_VAAPI_ID_ARGS(gst_vaapi_object_get_id(GST_VAAPI_OBJECT(surfaces[i])))); + GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surfaces[i]))); } if (surface == surfaces[0]) From 0eab3408034f1c8ddef8701c10f0e3b0c1314356 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 10:04:39 +0000 Subject: [PATCH 0186/3781] Move __attribute__((visibility("hidden"))) check down. --- configure.ac | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index a4b9ad3a1b..a8d73a0849 100644 --- a/configure.ac +++ b/configure.ac @@ -57,6 +57,19 @@ AC_SUBST(GST_VAAPI_MAJOR_VERSION) LIBVA_SDS_PACKAGE_VERSION=libva_sds_package_version AC_SUBST(LIBVA_SDS_PACKAGE_VERSION) +dnl Versions for GStreamer and plugins-base +GST_MAJORMINOR=gst_major_minor_version +GST_VERSION_REQUIRED=gst_version +GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version +AC_SUBST(GST_MAJORMINOR) +AC_SUBST(GST_VERSION_REQUIRED) +AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) + +dnl Check for tools +AC_PROG_CC +AM_PROG_CC_C_O +AC_PROG_LIBTOOL + dnl Check for __attribute__((visibility())) AC_CACHE_CHECK([whether __attribute__((visibility())) is supported], vaapi_cv_visibility_attribute, @@ -83,19 +96,6 @@ AC_DEFINE_UNQUOTED([attribute_hidden], [$vaapi_cv_visibility_attribute_hidden], [Define the "hidden" visibility attribute]) -dnl Versions for GStreamer and plugins-base -GST_MAJORMINOR=gst_major_minor_version -GST_VERSION_REQUIRED=gst_version -GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version -AC_SUBST(GST_MAJORMINOR) -AC_SUBST(GST_VERSION_REQUIRED) -AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) - -dnl Check for tools -AC_PROG_CC -AM_PROG_CC_C_O -AC_PROG_LIBTOOL - dnl Check for Gtk doc GTKDOC_VERSION=gtkdoc_version GTK_DOC_CHECK([$GTKDOC_VERSION]) From 67de515e637b6d8df3601e46e3f4db2193c4aaa9 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 12:39:54 +0000 Subject: [PATCH 0187/3781] Simplify initialization of VADisplay. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 5 ++++- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 8 ++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 1ef23e497f..0193681bc5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -280,8 +280,11 @@ gst_vaapi_display_create(GstVaapiDisplay *display) GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); if (klass->open_display && !klass->open_display(display)) return FALSE; - if (klass->get_display) + if (klass->get_display) { priv->display = klass->get_display(display); + if (!priv->display) + return FALSE; + } if (klass->get_size) klass->get_size(display, &priv->width, &priv->height); if (klass->get_size_mm) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index a1e34793bb..30f71521e6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -44,7 +44,6 @@ struct _GstVaapiDisplayX11Private { gchar *display_name; Display *x11_display; int x11_screen; - VADisplay *va_display; }; enum { @@ -149,8 +148,7 @@ gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) return FALSE; priv->x11_screen = DefaultScreen(priv->x11_display); - priv->va_display = vaGetDisplay(priv->x11_display); - return priv->va_display != NULL; + return TRUE; } static void @@ -169,14 +167,12 @@ gst_vaapi_display_x11_close_display(GstVaapiDisplay *display) g_free(priv->display_name); priv->display_name = NULL; } - - priv->va_display = NULL; } static VADisplay gst_vaapi_display_x11_get_va_display(GstVaapiDisplay *display) { - return GST_VAAPI_DISPLAY_X11(display)->priv->va_display; + return vaGetDisplay(GST_VAAPI_DISPLAY_XDISPLAY(display)); } static void From 6ad73da390d37d8ac31ea6d91de5499158e817f1 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 13:21:19 +0000 Subject: [PATCH 0188/3781] Fix return value on error (though it's the same in the end). --- gst-libs/gst/vaapi/gstvaapiimage.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index d993ef877d..c7585747c7 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -623,7 +623,7 @@ GstVaapiImageFormat gst_vaapi_image_get_format(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); - g_return_val_if_fail(image->priv->is_constructed, FALSE); + g_return_val_if_fail(image->priv->is_constructed, 0); return image->priv->format; } @@ -640,7 +640,7 @@ guint gst_vaapi_image_get_width(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); - g_return_val_if_fail(image->priv->is_constructed, FALSE); + g_return_val_if_fail(image->priv->is_constructed, 0); return image->priv->width; } @@ -657,7 +657,7 @@ guint gst_vaapi_image_get_height(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); - g_return_val_if_fail(image->priv->is_constructed, FALSE); + g_return_val_if_fail(image->priv->is_constructed, 0); return image->priv->height; } From 86954a32c5af3819765ba9fc1acf05b2cef1d9a2 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 13:54:06 +0000 Subject: [PATCH 0189/3781] Allow window creation with a specific visual (e.g. for GLX support). --- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 20 +++++++++++++++++--- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 46ed19097a..317609a609 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -55,23 +55,37 @@ static const int x11_event_mask = (KeyPressMask | ExposureMask | StructureNotifyMask); +/** + * x11_create_window: + * @display: an X11 #Display + * @width: the requested width, in pixels + * @height: the requested height, in pixels + * @vis: the request visual + * + * Creates a border-less window with the specified dimensions. If @vis + * is %NULL, the default visual for @display will be used. The default + * background color is black. + * + * Return value: the newly created X #Window. + */ Window -x11_create_window(Display *display, guint width, guint height) +x11_create_window(Display *display, guint width, guint height, Visual *vis) { Window root_window, window; int screen, depth; - Visual *vis; XSetWindowAttributes xswa; unsigned long xswa_mask; XWindowAttributes wattr; unsigned long black_pixel, white_pixel; screen = DefaultScreen(display); - vis = DefaultVisual(display, screen); root_window = RootWindow(display, screen); black_pixel = BlackPixel(display, screen); white_pixel = WhitePixel(display, screen); + if (!vis) + vis = DefaultVisual(display, screen); + XGetWindowAttributes(display, root_window, &wattr); depth = wattr.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index b66e5c165e..9ab013141a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -32,7 +32,7 @@ int x11_untrap_errors(void) attribute_hidden; Window -x11_create_window(Display *display, guint width, guint height) +x11_create_window(Display *display, guint width, guint height, Visual *vis) attribute_hidden; gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index ffe1a3720f..2630836e2e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -241,7 +241,7 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) priv->atom_NET_WM_STATE = atoms[0]; priv->atom_NET_WM_STATE_FULLSCREEN = atoms[1]; - xid = x11_create_window(dpy, *width, *height); + xid = x11_create_window(dpy, *width, *height, NULL); if (xid) XRaiseWindow(dpy, xid); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); From b36a2142e466a6d2f4e8072cc99ad336127eef7e Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 17:18:06 +0000 Subject: [PATCH 0190/3781] Allow derived classes to specify custom Visual and Colormap. --- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 47 ++++++++++++++----------- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 24 ++++++++++--- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 7 ++++ 4 files changed, 55 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 317609a609..dc161e1b23 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -57,36 +57,38 @@ static const int x11_event_mask = (KeyPressMask | /** * x11_create_window: - * @display: an X11 #Display - * @width: the requested width, in pixels - * @height: the requested height, in pixels + * @dpy: an X11 #Display + * @w: the requested width, in pixels + * @h: the requested height, in pixels * @vis: the request visual + * @cmap: the request colormap * * Creates a border-less window with the specified dimensions. If @vis - * is %NULL, the default visual for @display will be used. The default - * background color is black. + * is %NULL, the default visual for @display will be used. If @cmap is + * %None, no specific colormap will be bound to the window. Also note + * the default background color is black. * * Return value: the newly created X #Window. */ Window -x11_create_window(Display *display, guint width, guint height, Visual *vis) +x11_create_window(Display *dpy, guint w, guint h, Visual *vis, Colormap cmap) { - Window root_window, window; + Window rootwin, win; int screen, depth; XSetWindowAttributes xswa; unsigned long xswa_mask; XWindowAttributes wattr; unsigned long black_pixel, white_pixel; - screen = DefaultScreen(display); - root_window = RootWindow(display, screen); - black_pixel = BlackPixel(display, screen); - white_pixel = WhitePixel(display, screen); + screen = DefaultScreen(dpy); + rootwin = RootWindow(dpy, screen); + black_pixel = BlackPixel(dpy, screen); + white_pixel = WhitePixel(dpy, screen); if (!vis) - vis = DefaultVisual(display, screen); + vis = DefaultVisual(dpy, screen); - XGetWindowAttributes(display, root_window, &wattr); + XGetWindowAttributes(dpy, rootwin, &wattr); depth = wattr.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) depth = 24; @@ -95,21 +97,26 @@ x11_create_window(Display *display, guint width, guint height, Visual *vis) xswa.border_pixel = black_pixel; xswa.background_pixel = black_pixel; - window = XCreateWindow( - display, - root_window, - 0, 0, width, height, + if (cmap) { + xswa_mask |= CWColormap; + xswa.colormap = cmap; + } + + win = XCreateWindow( + dpy, + rootwin, + 0, 0, w, h, 0, depth, InputOutput, vis, xswa_mask, &xswa ); - if (!window) + if (!win) return None; - XSelectInput(display, window, x11_event_mask); - return window; + XSelectInput(dpy, win, x11_event_mask); + return win; } gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index 9ab013141a..ab8fb5d204 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -32,7 +32,7 @@ int x11_untrap_errors(void) attribute_hidden; Window -x11_create_window(Display *display, guint width, guint height, Visual *vis) +x11_create_window(Display *dpy, guint w, guint h, Visual *vis, Colormap cmap) attribute_hidden; gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 2630836e2e..213e7255e4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -218,6 +218,9 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); Window xid = GST_VAAPI_OBJECT_ID(window); + Visual *vis = NULL; + Colormap cmap = None; + GstVaapiWindowX11Class *klass; XWindowAttributes wattr; Atom atoms[2]; gboolean ok; @@ -236,12 +239,25 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) return ok; } + klass = GST_VAAPI_WINDOW_X11_GET_CLASS(window); + if (klass) { + if (klass->get_visual) + vis = klass->get_visual(window); + if (klass->get_colormap) + cmap = klass->get_colormap(window); + } + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - XInternAtoms(dpy, (char **)atom_names, G_N_ELEMENTS(atom_names), False, atoms); + XInternAtoms( + dpy, + (char **)atom_names, G_N_ELEMENTS(atom_names), + False, + atoms + ); priv->atom_NET_WM_STATE = atoms[0]; priv->atom_NET_WM_STATE_FULLSCREEN = atoms[1]; - xid = x11_create_window(dpy, *width, *height, NULL); + xid = x11_create_window(dpy, *width, *height, vis, cmap); if (xid) XRaiseWindow(dpy, xid); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); @@ -494,7 +510,7 @@ gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) GST_DEBUG("new window, size %ux%u", width, height); g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(width > 0, NULL); g_return_val_if_fail(height > 0, NULL); return g_object_new(GST_VAAPI_TYPE_WINDOW_X11, @@ -544,7 +560,7 @@ gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) Window gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window) { - g_return_val_if_fail(GST_VAAPI_WINDOW_X11(window), None); + g_return_val_if_fail(GST_VAAPI_IS_WINDOW_X11(window), None); return GST_VAAPI_OBJECT_ID(window); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index 59fe14088d..cf3da5dafa 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -78,12 +78,19 @@ struct _GstVaapiWindowX11 { /** * GstVaapiWindowX11Class: + * @get_visual: virtual function to get the desired visual used to + * create the window + * @get_colormap: virtual function to get the desired colormap used to + * create the window * * An X11 #Window wrapper class. */ struct _GstVaapiWindowX11Class { /*< private >*/ GstVaapiWindowClass parent_class; + + Visual * (*get_visual) (GstVaapiWindow *window); + Colormap (*get_colormap) (GstVaapiWindow *window); }; GType From fddeb54248883d5fb1f77eb2fb1827edaf591b23 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 17:18:36 +0000 Subject: [PATCH 0191/3781] Add gst_vaapi_window_x11_is_foreign_xid() helper. --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 17 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 213e7255e4..3ced139cb0 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -564,3 +564,20 @@ gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window) return GST_VAAPI_OBJECT_ID(window); } + +/** + * gst_vaapi_window_x11_is_foreign_xid: + * @window: a #GstVaapiWindowX11 + * + * Checks whether the @window XID was created by gst_vaapi_window_x11_new() or bound with gst_vaapi_window_x11_new_with_xid(). + * + * Return value: %TRUE if the underlying X window is owned by the + * caller (foreign window) + */ +gboolean +gst_vaapi_window_x11_is_foreign_xid(GstVaapiWindowX11 *window) +{ + g_return_val_if_fail(GST_VAAPI_IS_WINDOW_X11(window), FALSE); + + return !window->priv->create_window; +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index cf3da5dafa..424200f861 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -105,6 +105,9 @@ gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid); Window gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window); +gboolean +gst_vaapi_window_x11_is_foreign_xid(GstVaapiWindowX11 *window); + G_END_DECLS #endif /* GST_VAAPI_WINDOW_X11_H */ From d56fcd0c2b60a4bd0ecc138422726febe34304a4 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 17:21:13 +0000 Subject: [PATCH 0192/3781] Only enable GST_DEBUG() if DEBUG is defined. Drop old D(bug()) stuff. --- gst-libs/gst/vaapi/gstvaapidebug.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidebug.h b/gst-libs/gst/vaapi/gstvaapidebug.h index d94186aa45..9b9013ed95 100644 --- a/gst-libs/gst/vaapi/gstvaapidebug.h +++ b/gst-libs/gst/vaapi/gstvaapidebug.h @@ -21,16 +21,11 @@ #ifndef GST_VAAPI_DEBUG_H #define GST_VAAPI_DEBUG_H -#include "gstvaapiutils.h" +#include #if DEBUG -# define D(x) x -#else -# define D(x) -#endif -#define bug vaapi_dprintf - GST_DEBUG_CATEGORY_EXTERN(gst_debug_vaapi); #define GST_CAT_DEFAULT gst_debug_vaapi +#endif #endif /* GST_VAAPI_DEBUG_H */ From 511463c699125fa2387d6e1907aa4d8210854a83 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 17:21:56 +0000 Subject: [PATCH 0193/3781] Add missing includes (for vaapi_check_status()). --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 3ced139cb0..ab8a47d913 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -29,6 +29,7 @@ #include "gstvaapicompat.h" #include "gstvaapiwindow_x11.h" #include "gstvaapidisplay_x11.h" +#include "gstvaapiutils.h" #include "gstvaapiutils_x11.h" #include "gstvaapiobject_priv.h" From 89a99d828c5527baa311b80fa63f5a51c4e78c47 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 17:28:49 +0000 Subject: [PATCH 0194/3781] Add initial VA/GLX support. --- configure.ac | 47 ++- gst-libs/gst/vaapi/Makefile.am | 49 +++ gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 99 +++++ gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 90 +++++ gst-libs/gst/vaapi/gstvaapiutils_glx.c | 183 +++++++++ gst-libs/gst/vaapi/gstvaapiutils_glx.h | 57 +++ gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 488 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 100 +++++ pkgconfig/Makefile.am | 16 +- pkgconfig/gstreamer-vaapi-glx.pc.in | 12 + tests/Makefile.am | 21 +- tests/test-textures.c | 141 +++++++ 12 files changed, 1289 insertions(+), 14 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_glx.c create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_glx.h create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_glx.c create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_glx.h create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_glx.c create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_glx.h create mode 100644 pkgconfig/gstreamer-vaapi-glx.pc.in create mode 100644 tests/test-textures.c diff --git a/configure.ac b/configure.ac index a8d73a0849..3b73507bab 100644 --- a/configure.ac +++ b/configure.ac @@ -70,6 +70,11 @@ AC_PROG_CC AM_PROG_CC_C_O AC_PROG_LIBTOOL +AC_ARG_ENABLE(glx, + AC_HELP_STRING([--enable-glx], + [enable OpenGL/X11 @<:@default=yes@:>@]), + [], [enable_glx="yes"]) + dnl Check for __attribute__((visibility())) AC_CACHE_CHECK([whether __attribute__((visibility())) is supported], vaapi_cv_visibility_attribute, @@ -150,11 +155,28 @@ AC_SUBST(plugindir) dnl Check for X11 PKG_CHECK_MODULES(X11, [x11]) +dnl Check for OpenGL +USE_GLX=1 +if test "$enable_glx" != "yes"; then + USE_GLX=0 +fi +OPENGL_CFLAGS="" +OPENGL_LIBS="" +AC_CHECK_HEADERS([GL/gl.h GL/glext.h GL/glx.h], [], [USE_GLX=0], [ +#ifdef HAVE_GL_GL_H +# include +#endif +]) +AC_CHECK_LIB(GL, glXCreateContext, [OPENGL_LIBS="-lGL -ldl"], [USE_GLX=0]) +AC_SUBST(OPENGL_CFLAGS) +AC_SUBST(OPENGL_LIBS) + dnl Check for VA-API LIBVA_PKGNAME="libva" PKG_CHECK_MODULES(LIBVA, [$LIBVA_PKGNAME]) AC_SUBST(LIBVA_PKGNAME) +dnl ... original VA-API 0.29 AC_CACHE_CHECK([for old VA-API 0.29], ac_cv_have_vaapi_old, [ saved_CFLAGS="$CFLAGS" @@ -173,6 +195,7 @@ if test "$ac_cv_have_vaapi_old" = "yes"; then LIBVA_EXTRA_CFLAGS="$LIBVA_CFLAGS -DGST_VAAPI_USE_OLD_VAAPI_0_29" fi +dnl ... VA-API >= 0.31 or -sds LIBVA_X11_PKGNAME="libva-x11" PKG_CHECK_MODULES(LIBVA_X11, [$LIBVA_X11_PKGNAME], [ac_cv_have_vaapi_x11="yes"], @@ -189,9 +212,24 @@ if test "$ac_cv_have_vaapi_x11" = "no"; then fi AC_SUBST(LIBVA_X11_PKGNAME) +dnl ... VA-API >= 0.31 or -sds +LIBVA_GLX_PKGNAME="libva-glx" +PKG_CHECK_MODULES(LIBVA_GLX, [$LIBVA_GLX_PKGNAME], + [ac_cv_have_vaapi_glx="yes"], + [ac_cv_have_vaapi_glx="no"] +) +if test "$ac_cv_have_vaapi_glx" = "no"; then + AC_MSG_WARN([could not find VA/GLX extensions. Disabling GLX support]) + USE_GLX=0 +fi +AC_SUBST(LIBVA_GLX_PKGNAME) + AC_SUBST(LIBVA_EXTRA_CFLAGS) AC_SUBST(LIBVA_EXTRA_LIBS) +AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) +AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) + VA_VERSION=`$PKG_CONFIG --modversion libva` VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1` VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2` @@ -231,8 +269,12 @@ debian.upstream/libgstvaapi-x11.install.in gst-libs/gst/Makefile gst-libs/gst/vaapi/Makefile pkgconfig/Makefile - pkgconfig/gstreamer-vaapi.pc - pkgconfig/gstreamer-vaapi-x11.pc + pkgconfig/gstreamer-vaapi-$GST_MAJORMINOR.pc:\ +pkgconfig/gstreamer-vaapi.pc.in + pkgconfig/gstreamer-vaapi-glx-$GST_MAJORMINOR.pc:\ +pkgconfig/gstreamer-vaapi-glx.pc.in + pkgconfig/gstreamer-vaapi-x11-$GST_MAJORMINOR.pc:\ +pkgconfig/gstreamer-vaapi-x11.pc.in sys/Makefile sys/vaapiconvert/Makefile sys/vaapisink/Makefile @@ -244,4 +286,5 @@ echo echo $PACKAGE configuration summary: echo echo VA-API version ................... : $VA_VERSION_STR +echo GLX support ...................... : $(test $USE_GLX -eq 1 && echo yes || echo no) echo diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index b1bef04ee2..d9626f9a96 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -3,6 +3,10 @@ lib_LTLIBRARIES = \ libgstvaapi-x11-@GST_MAJORMINOR@.la \ $(NULL) +if USE_GLX +lib_LTLIBRARIES += libgstvaapi-glx-@GST_MAJORMINOR@.la +endif + libgstvaapi_includedir = \ $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi @@ -68,6 +72,26 @@ libgstvaapi_x11_source_priv_h = \ gstvaapiutils_x11.h \ $(NULL) +libgstvaapi_glx_source_c = \ + gstvaapidisplay_glx.c \ + gstvaapiutils.c \ + gstvaapiutils_glx.c \ + gstvaapiutils_x11.c \ + gstvaapiwindow_glx.c \ + $(NULL) + +libgstvaapi_glx_source_h = \ + gstvaapicompat.h \ + gstvaapidisplay_glx.h \ + gstvaapiwindow_glx.h \ + $(NULL) + +libgstvaapi_glx_source_priv_h = \ + gstvaapiutils.h \ + gstvaapiutils_glx.h \ + gstvaapiutils_x11.h \ + $(NULL) + libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_source_c) \ $(libgstvaapi_source_priv_h) \ @@ -118,6 +142,31 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_LIBADD = \ libgstvaapi-@GST_MAJORMINOR@.la \ $(NULL) +libgstvaapi_glx_@GST_MAJORMINOR@_la_SOURCES = \ + $(libgstvaapi_glx_source_c) \ + $(libgstvaapi_glx_source_priv_h) \ + $(NULL) + +libgstvaapi_glx_@GST_MAJORMINOR@include_HEADERS = \ + $(libgstvaapi_glx_source_h) \ + $(NULL) + +libgstvaapi_glx_@GST_MAJORMINOR@includedir = \ + $(libgstvaapi_includedir) + +libgstvaapi_glx_@GST_MAJORMINOR@_la_CFLAGS = \ + -I$(top_srcdir)/gst-libs \ + $(GLIB_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(LIBVA_GLX_CFLAGS) \ + $(NULL) + +libgstvaapi_glx_@GST_MAJORMINOR@_la_LIBADD = \ + $(GLIB_LIBS) \ + $(LIBVA_GLX_LIBS) \ + libgstvaapi-x11-@GST_MAJORMINOR@.la \ + $(NULL) + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c new file mode 100644 index 0000000000..7a078cf7e2 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -0,0 +1,99 @@ +/* + * gstvaapidisplay_glx.c - VA/GLX display abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * SECTION:gstvaapidisplay_glx + * @short_description: VA/GLX display abstraction + */ + +#include "config.h" +#include "gstvaapiutils.h" +#include "gstvaapidisplay_glx.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiDisplayGLX, + gst_vaapi_display_glx, + GST_VAAPI_TYPE_DISPLAY_X11); + +static void +gst_vaapi_display_glx_finalize(GObject *object) +{ + G_OBJECT_CLASS(gst_vaapi_display_glx_parent_class)->finalize(object); +} + +static VADisplay +gst_vaapi_display_glx_get_va_display(GstVaapiDisplay *display) +{ + return vaGetDisplayGLX(GST_VAAPI_DISPLAY_XDISPLAY(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->get_display = gst_vaapi_display_glx_get_va_display; +} + +static void +gst_vaapi_display_glx_init(GstVaapiDisplayGLX *display) +{ +} + +/** + * 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) +{ + return g_object_new(GST_VAAPI_TYPE_DISPLAY_GLX, + "display-name", display_name, + NULL); +} + +/** + * 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) +{ + return g_object_new(GST_VAAPI_TYPE_DISPLAY_GLX, + "x11-display", x11_display, + NULL); +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h new file mode 100644 index 0000000000..6206f1e9c5 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -0,0 +1,90 @@ +/* + * gstvaapidisplay_glx.h - VA/GLX display abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_DISPLAY_GLX_H +#define GST_VAAPI_DISPLAY_GLX_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DISPLAY_GLX \ + (gst_vaapi_display_glx_get_type()) + +#define GST_VAAPI_DISPLAY_GLX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DISPLAY_GLX, \ + GstVaapiDisplayGLX)) + +#define GST_VAAPI_DISPLAY_GLX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DISPLAY_GLX, \ + GstVaapiDisplayGLXClass)) + +#define GST_VAAPI_IS_DISPLAY_GLX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_GLX)) + +#define GST_VAAPI_IS_DISPLAY_GLX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_GLX)) + +#define GST_VAAPI_DISPLAY_GLX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DISPLAY_GLX, \ + GstVaapiDisplayGLXClass)) + +typedef struct _GstVaapiDisplayGLX GstVaapiDisplayGLX; +typedef struct _GstVaapiDisplayGLXClass GstVaapiDisplayGLXClass; + +/** + * GstVaapiDisplayGLX: + * + * VA/GLX display wrapper. + */ +struct _GstVaapiDisplayGLX { + /*< private >*/ + GstVaapiDisplayX11 parent_instance; +}; + + +/** + * GstVaapiDisplayGLXClass: + * + * VA/GLX display wrapper clas. + */ +struct _GstVaapiDisplayGLXClass { + /*< private >*/ + GstVaapiDisplayX11Class parent_class; +}; + +GType +gst_vaapi_display_glx_get_type(void); + +GstVaapiDisplay * +gst_vaapi_display_glx_new(const gchar *display_name); + +GstVaapiDisplay * +gst_vaapi_display_glx_new_with_display(Display *x11_display); + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_GLX_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c new file mode 100644 index 0000000000..8053a54aa7 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -0,0 +1,183 @@ +/* + * gstvaapiutils_glx.c - GLX utilties + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "gstvaapiutils_glx.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +/** + * gl_get_error_string: + * @error: an OpenGL error enumeration + * + * Retrieves the string representation the OpenGL @error. + * + * Return error: the static string representing the OpenGL @error + */ +const char * +gl_get_error_string(GLenum error) +{ + static const struct { + GLenum val; + const char *str; + } + gl_errors[] = { + { GL_NO_ERROR, "no error" }, + { GL_INVALID_ENUM, "invalid enumerant" }, + { GL_INVALID_VALUE, "invalid value" }, + { GL_INVALID_OPERATION, "invalid operation" }, + { GL_STACK_OVERFLOW, "stack overflow" }, + { GL_STACK_UNDERFLOW, "stack underflow" }, + { GL_OUT_OF_MEMORY, "out of memory" }, +#ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT + { GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "invalid framebuffer operation" }, +#endif + { ~0, NULL } + }; + + guint i; + for (i = 0; gl_errors[i].str; i++) { + if (gl_errors[i].val == error) + return gl_errors[i].str; + } + return "unknown"; +} + +/** + * gl_purge_errors: + * + * Purges all OpenGL errors. This function is generally useful to + * clear up the pending errors prior to calling gl_check_error(). + */ +void +gl_purge_errors(void) +{ + while (glGetError() != GL_NO_ERROR) + ; /* nothing */ +} + +/** + * gl_check_error: + * + * Checks whether there is any OpenGL error pending. + * + * Return value: %TRUE if an error was encountered + */ +gboolean +gl_check_error(void) +{ + GLenum error; + gboolean has_errors = FALSE; + + while ((error = glGetError()) != GL_NO_ERROR) { + GST_DEBUG("glError: %s caught", gl_get_error_string(error)); + has_errors = TRUE; + } + return has_errors; +} + +/** + * gl_get_param: + * @param: the parameter name + * @pval: return location for the value + * + * This function is a wrapper around glGetIntegerv() that does extra + * error checking. + * + * Return value: %TRUE on success + */ +gboolean +gl_get_param(GLenum param, guint *pval) +{ + GLint val; + + gl_purge_errors(); + glGetIntegerv(param, &val); + if (gl_check_error()) + return FALSE; + + if (pval) + *pval = val; + return TRUE; +} + +/** + * gl_get_param: + * @param: the parameter name + * @pval: return location for the value + * + * This function is a wrapper around glGetTexLevelParameteriv() that + * does extra error checking. + * + * Return value: %TRUE on success + */ +gboolean +gl_get_texture_param(GLenum param, guint *pval) +{ + GLint val; + + gl_purge_errors(); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, param, &val); + if (gl_check_error()) + return FALSE; + + if (pval) + *pval = val; + return TRUE; +} + +/** + * gl_set_bgcolor: + * @color: the requested RGB color + * + * Sets background color to the RGB @color. This basically is a + * wrapper around glClearColor(). + */ +void +gl_set_bgcolor(guint32 color) +{ + glClearColor( + ((color >> 16) & 0xff) / 255.0f, + ((color >> 8) & 0xff) / 255.0f, + ( color & 0xff) / 255.0f, + 1.0f + ); +} + +/** + * gl_resize: + * @width: the requested width, in pixels + * @height: the requested height, in pixels + * + * Resizes the OpenGL viewport to the specified dimensions, using an + * orthogonal projection. (0,0) represents the top-left corner of the + * window. + */ +void +gl_resize(guint width, guint height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, width, height, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h new file mode 100644 index 0000000000..79328e72bb --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -0,0 +1,57 @@ +/* + * gstvaapiutils_glx.h - GLX utilties + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_UTILS_GLX_H +#define GST_VAAPI_UTILS_GLX_H + +#include "config.h" +#include +#include +#include + +const char * +gl_get_error_string(GLenum error) + attribute_hidden; + +void +gl_purge_errors(void) + attribute_hidden; + +gboolean +gl_check_error(void) + attribute_hidden; + +gboolean +gl_get_param(GLenum param, guint *pval) + attribute_hidden; + +gboolean +gl_get_texture_param(GLenum param, guint *pval) + attribute_hidden; + +void +gl_set_bgcolor(guint32 color) + attribute_hidden; + +void +gl_resize(guint width, guint height) + attribute_hidden; + +#endif /* GST_VAAPI_UTILS_GLX_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c new file mode 100644 index 0000000000..5d91116fca --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -0,0 +1,488 @@ +/* + * gstvaapiwindow_glx.c - VA/GLX window abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * SECTION:gstvaapiwindow_glx + * @short_description: VA/GLX window abstraction + */ + +#include "config.h" +#include "gstvaapiwindow_glx.h" +#include "gstvaapidisplay_x11.h" +#include "gstvaapiutils_x11.h" +#include "gstvaapiutils_glx.h" +#include "gstvaapiobject_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiWindowGLX, + gst_vaapi_window_glx, + GST_VAAPI_TYPE_WINDOW_X11); + +#define GST_VAAPI_WINDOW_GLX_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_WINDOW_GLX, \ + GstVaapiWindowGLXPrivate)) + +struct _GstVaapiWindowGLXPrivate { + XVisualInfo *vi; + XVisualInfo vi_static; + Colormap cmap; + GLXContext context; + guint foreign_context : 1; + guint foreign_window : 1; +}; + +enum { + PROP_0, + + PROP_GLX_CONTEXT +}; + +static XVisualInfo * +gst_vaapi_window_glx_create_visual(GstVaapiWindowGLX *window); + +static inline void +_gst_vaapi_window_glx_set_context( + GstVaapiWindowGLX *window, + GLXContext context, + gboolean is_foreign +) +{ + GstVaapiWindowGLXPrivate * const priv = window->priv; + + priv->context = context; + priv->foreign_context = is_foreign; +} + +static void +gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window) +{ + GstVaapiWindowGLXPrivate * const priv = window->priv; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + + if (priv->context) { + if (!priv->foreign_context) { + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + if (glXGetCurrentContext() == priv->context) + glXMakeCurrent(dpy, None, NULL); + glXDestroyContext(dpy, priv->context); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + } + priv->context = NULL; + priv->foreign_context = FALSE; + } +} + +static gboolean +gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window) +{ + GstVaapiWindowGLXPrivate * const priv = window->priv; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + GLXContext ctx = NULL; + guint width, height; + gboolean has_errors = TRUE; + + if (!gst_vaapi_window_glx_create_visual(window)) + return FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + ctx = glXCreateContext(dpy, priv->vi, NULL, True); + if (ctx && glXIsDirect(dpy, ctx)) { + _gst_vaapi_window_glx_set_context(window, ctx, FALSE); + if (glXMakeCurrent(dpy, GST_VAAPI_OBJECT_ID(window), ctx)) { + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_CULL_FACE); + glDrawBuffer(GL_BACK); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + gst_vaapi_window_get_size(GST_VAAPI_WINDOW(window), &width, &height); + gl_resize(width, height); + + gl_set_bgcolor(0); + glClear(GL_COLOR_BUFFER_BIT); + has_errors = FALSE; + } + } + else if (ctx) + glXDestroyContext(dpy, ctx); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + + return !has_errors; +} + +static inline void +gst_vaapi_window_glx_destroy_visual(GstVaapiWindowGLX *window) +{ + GstVaapiWindowGLXPrivate * const priv = window->priv; + + if (priv->vi) { + if (priv->vi != &priv->vi_static) + XFree(priv->vi); + priv->vi = NULL; + } +} + +static XVisualInfo * +gst_vaapi_window_glx_create_visual(GstVaapiWindowGLX *window) +{ + GstVaapiWindowGLXPrivate * const priv = window->priv; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + XWindowAttributes wattr; + int screen; + gboolean has_errors; + + /* XXX: add and use a GstVaapiWindow:double-buffer property? */ + static GLint gl_visual_attr[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + GL_NONE + }; + + if (!priv->vi) { + /* XXX: add and use a GstVaapiDisplayX11:x11-screen property? */ + screen = DefaultScreen(dpy); + + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + x11_trap_errors(); + if (!priv->foreign_window) + priv->vi = glXChooseVisual(dpy, screen, gl_visual_attr); + else { + XGetWindowAttributes(dpy, GST_VAAPI_OBJECT_ID(window), &wattr); + if (XMatchVisualInfo(dpy, screen, wattr.depth, wattr.visual->class, + &priv->vi_static)) + priv->vi = &priv->vi_static; + } + has_errors = x11_untrap_errors() != 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + + if (has_errors) + return NULL; + } + return priv->vi; +} + +static Visual * +gst_vaapi_window_glx_get_visual(GstVaapiWindow *window) +{ + XVisualInfo *vi; + + vi = gst_vaapi_window_glx_create_visual(GST_VAAPI_WINDOW_GLX(window)); + if (!vi) + return NULL; + return vi->visual; +} + +static void +gst_vaapi_window_glx_destroy_colormap(GstVaapiWindowGLX *window) +{ + GstVaapiWindowGLXPrivate * const priv = window->priv; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + + if (priv->cmap) { + if (!priv->foreign_window) { + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + XFreeColormap(dpy, priv->cmap); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + } + priv->cmap = None; + } +} + +static Colormap +gst_vaapi_window_glx_create_colormap(GstVaapiWindowGLX *window) +{ + GstVaapiWindowGLXPrivate * const priv = window->priv; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + int screen; + XWindowAttributes wattr; + XVisualInfo *vi; + gboolean has_errors; + + if (!priv->cmap) { + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + x11_trap_errors(); + if (!priv->foreign_window) { + vi = gst_vaapi_window_glx_create_visual(window); + if (vi) { + /* XXX: add a GstVaapiDisplayX11:x11-screen property? */ + screen = DefaultScreen(dpy); + priv->cmap = XCreateColormap( + dpy, + RootWindow(dpy, screen), + vi->visual, + AllocNone + ); + } + } + else { + XGetWindowAttributes(dpy, GST_VAAPI_OBJECT_ID(window), &wattr); + priv->cmap = wattr.colormap; + } + has_errors = x11_untrap_errors() != 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + + if (has_errors) + return None; + } + return priv->cmap; +} + +static Colormap +gst_vaapi_window_glx_get_colormap(GstVaapiWindow *window) +{ + return gst_vaapi_window_glx_create_colormap(GST_VAAPI_WINDOW_GLX(window)); +} + +static void +gst_vaapi_window_glx_finalize(GObject *object) +{ + GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(object); + + gst_vaapi_window_glx_destroy_context(window); + gst_vaapi_window_glx_destroy_visual(window); + gst_vaapi_window_glx_destroy_colormap(window); + + G_OBJECT_CLASS(gst_vaapi_window_glx_parent_class)->finalize(object); +} + +static void +gst_vaapi_window_glx_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(object); + + switch (prop_id) { + case PROP_GLX_CONTEXT: + gst_vaapi_window_glx_set_context(window, g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_window_glx_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(object); + + switch (prop_id) { + case PROP_GLX_CONTEXT: + g_value_set_pointer(value, gst_vaapi_window_glx_get_context(window)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_window_glx_constructed(GObject *object) +{ + GstVaapiWindowGLXPrivate * const priv = GST_VAAPI_WINDOW_GLX(object)->priv; + GObjectClass *parent_class; + + priv->foreign_context = priv->context != NULL; + + parent_class = G_OBJECT_CLASS(gst_vaapi_window_glx_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); + + priv->foreign_window = + gst_vaapi_window_x11_is_foreign_xid(GST_VAAPI_WINDOW_X11(object)); + + if (!priv->foreign_context) + gst_vaapi_window_glx_create_context(GST_VAAPI_WINDOW_GLX(object)); +} + +static void +gst_vaapi_window_glx_class_init(GstVaapiWindowGLXClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiWindowX11Class * const xwin_class = GST_VAAPI_WINDOW_X11_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiWindowGLXPrivate)); + + object_class->finalize = gst_vaapi_window_glx_finalize; + object_class->set_property = gst_vaapi_window_glx_set_property; + object_class->get_property = gst_vaapi_window_glx_get_property; + object_class->constructed = gst_vaapi_window_glx_constructed; + + xwin_class->get_visual = gst_vaapi_window_glx_get_visual; + xwin_class->get_colormap = gst_vaapi_window_glx_get_colormap; + + /** + * GstVaapiDisplayGLX:glx-context: + * + * The GLX context that was created by gst_vaapi_window_glx_new() + * or that was bound from gst_vaapi_window_glx_set_context(). + */ + g_object_class_install_property + (object_class, + PROP_GLX_CONTEXT, + g_param_spec_pointer("glx-context", + "GLX context", + "GLX context", + G_PARAM_READWRITE)); +} + +static void +gst_vaapi_window_glx_init(GstVaapiWindowGLX *window) +{ + GstVaapiWindowGLXPrivate *priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); + + window->priv = priv; + priv->vi = NULL; + priv->cmap = None; + priv->context = NULL; + priv->foreign_context = FALSE; +} + +/** + * gst_vaapi_window_glx_new: + * @display: a #GstVaapiDisplay + * @width: the requested window width, in pixels + * @height: the requested windo height, in pixels + * + * Creates a window with the specified @width and @height. The window + * will be attached to the @display and remains invisible to the user + * until gst_vaapi_window_show() is called. + * + * Return value: the newly allocated #GstVaapiWindow object + */ +GstVaapiWindow * +gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(height > 0, NULL); + + return g_object_new(GST_VAAPI_TYPE_WINDOW_GLX, + "display", display, + "id", GST_VAAPI_ID(None), + "width", width, + "height", height, + NULL); +} + +/** + * gst_vaapi_window_glx_new_with_xid: + * @display: a #GstVaapiDisplay + * @xid: an X11 #Window id + * + * Creates a #GstVaapiWindow using the X11 #Window @xid. The caller + * still owns the window and must call XDestroyWindow() when all + * #GstVaapiWindow references are released. Doing so too early can + * yield undefined behaviour. + * + * Return value: the newly allocated #GstVaapiWindow object + */ +GstVaapiWindow * +gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid) +{ + GST_DEBUG("new window from xid 0x%08x", xid); + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(xid != None, NULL); + + return g_object_new(GST_VAAPI_TYPE_WINDOW_GLX, + "display", display, + "id", GST_VAAPI_ID(xid), + NULL); +} + +/** + * gst_vaapi_window_glx_get_context: + * @window: a #GstVaapiWindow + * + * Returns the #GLXContext bound to the @window. + * + * Return value: the #GLXContext bound to the @window + */ +GLXContext +gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window) +{ + g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), NULL); + + return window->priv->context; +} + +/** + * gst_vaapi_window_glx_set_context: + * @window: a #GstVaapiWindow + * @ctx: a GLX context + * + * Binds GLX context @ctx to @window. If @ctx is non %NULL, the caller + * is responsible to making sure it has compatible visual with that of + * the underlying X window. If @ctx is %NULL, a new context is created + * and the @window owns it. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx) +{ + g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE); + + gst_vaapi_window_glx_destroy_context(window); + + if (ctx) { + _gst_vaapi_window_glx_set_context(window, ctx, TRUE); + return TRUE; + } + return gst_vaapi_window_glx_create_context(window); +} + +/** + * gst_vaapi_window_glx_swap_buffers: + * @window: a #GstVaapiWindowGLX + * + * Promotes the contents of the back buffer of @window to become the + * contents of the front buffer of @window. This simply is wrapper + * around glXSwapBuffers(). + */ +void +gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window) +{ + g_return_if_fail(GST_VAAPI_IS_WINDOW_GLX(window)); + + glXSwapBuffers( + GST_VAAPI_OBJECT_XDISPLAY(window), + GST_VAAPI_OBJECT_ID(window) + ); + glClear(GL_COLOR_BUFFER_BIT); +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h new file mode 100644 index 0000000000..b10fcd4d50 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -0,0 +1,100 @@ +/* + * gstvaapiwindow_glx.h - VA/GLX window abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_WINDOW_GLX_H +#define GST_VAAPI_WINDOW_GLX_H + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_WINDOW_GLX \ + (gst_vaapi_window_glx_get_type()) + +#define GST_VAAPI_WINDOW_GLX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_WINDOW_GLX, \ + GstVaapiWindowGLX)) + +#define GST_VAAPI_WINDOW_GLX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_WINDOW_GLX, \ + GstVaapiWindowGLXClass)) + +#define GST_VAAPI_IS_WINDOW_GLX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW_GLX)) + +#define GST_VAAPI_IS_WINDOW_GLX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW_GLX)) + +#define GST_VAAPI_WINDOW_GLX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_WINDOW_GLX, \ + GstVaapiWindowGLXClass)) + +typedef struct _GstVaapiWindowGLX GstVaapiWindowGLX; +typedef struct _GstVaapiWindowGLXPrivate GstVaapiWindowGLXPrivate; +typedef struct _GstVaapiWindowGLXClass GstVaapiWindowGLXClass; + +/** + * GstVaapiWindowGLX: + * + * An X11 #Window suitable for GLX rendering. + */ +struct _GstVaapiWindowGLX { + /*< private >*/ + GstVaapiWindowX11 parent_instance; + + GstVaapiWindowGLXPrivate *priv; +}; + +/** + * GstVaapiWindowGLXClass: + * + * An X11 #Window suitable for GLX rendering. + */ +struct _GstVaapiWindowGLXClass { + /*< private >*/ + GstVaapiWindowX11Class parent_class; +}; + +GType +gst_vaapi_window_glx_get_type(void); + +GstVaapiWindow * +gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height); + +GstVaapiWindow * +gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid); + +GLXContext +gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window); + +gboolean +gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx); + +void +gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window); + +G_END_DECLS + +#endif /* GST_VAAPI_WINDOW_GLX_H */ diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index 1e772a6876..b98888c105 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -1,21 +1,21 @@ -AUTOMAKE_OPTIONS = -Wno-portability +pcfiles_in = gstreamer-vaapi.pc.in +pcfiles_in += gstreamer-vaapi-x11.pc.in +if USE_GLX +pcfiles_in += gstreamer-vaapi-glx.pc.in +endif -pcfiles = gstreamer-vaapi-@GST_MAJORMINOR@.pc -pcfiles += gstreamer-vaapi-x11-@GST_MAJORMINOR@.pc +pcfiles = $(pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc) pkgconfigdir = @pkgconfigdir@ pkgconfig_DATA = $(pcfiles) EXTRA_DIST = \ gstreamer-vaapi.pc.in \ + gstreamer-vaapi-glx.pc.in \ gstreamer-vaapi-x11.pc.in \ $(NULL) -CLEANFILES = $(pcfiles) - -# XXX: this is a GNU make extension -%-@GST_MAJORMINOR@.pc: %.pc - cp $< $@ +DISTCLEANFILES = $(pcfiles) # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/pkgconfig/gstreamer-vaapi-glx.pc.in b/pkgconfig/gstreamer-vaapi-glx.pc.in new file mode 100644 index 0000000000..73b4c1bd7a --- /dev/null +++ b/pkgconfig/gstreamer-vaapi-glx.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ + +Name: GStreamer VA-API (glx) Plugins Libraries +Description: Streaming media framework, VA-API (glx) plugins libraries +Requires: gstreamer-vaapi-@GST_MAJORMINOR@ @LIBVA_GLX_PKGNAME@ +Version: @VERSION@ +Libs: -L${libdir} -lgstvaapi-glx-@GST_MAJORMINOR@ @LIBVA_EXTRA_LIBS@ +Cflags: -I${includedir} @LIBVA_EXTRA_CFLAGS@ diff --git a/tests/Makefile.am b/tests/Makefile.am index de69c18db9..ed9ca0a637 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -4,26 +4,39 @@ noinst_PROGRAMS = \ test-windows \ $(NULL) +noinst_PROGRAMS += \ + test-textures \ + $(NULL) + TEST_CFLAGS = \ $(GST_CFLAGS) \ -I$(top_srcdir)/gst-libs \ $(X11_CFLAGS) TEST_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la \ $(X11_LIBS) +TEST_GLX_LIBS = \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-@GST_MAJORMINOR@.la + +TEST_X11_LIBS = \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la + test_display_SOURCES = test-display.c test_display_CFLAGS = $(TEST_CFLAGS) -test_display_LDADD = $(TEST_LIBS) +test_display_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) test_surfaces_SOURCES = test-surfaces.c test_surfaces_CFLAGS = $(TEST_CFLAGS) -test_surfaces_LDADD = $(TEST_LIBS) +test_surfaces_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) test_windows_SOURCES = test-windows.c test_windows_CFLAGS = $(TEST_CFLAGS) -test_windows_LDADD = $(TEST_LIBS) +test_windows_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) + +test_textures_SOURCES = test-textures.c +test_textures_CFLAGS = $(TEST_CFLAGS) +test_textures_LDADD = $(TEST_LIBS) $(TEST_GLX_LIBS) # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/test-textures.c b/tests/test-textures.c new file mode 100644 index 0000000000..493faa21b2 --- /dev/null +++ b/tests/test-textures.c @@ -0,0 +1,141 @@ +/* + * test-textures.c - Test GstVaapiTexture + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +static inline void pause(void) +{ + g_print("Press any key to continue...\n"); + getchar(); +} + +static void +print_caps(GstCaps *caps, const gchar *name) +{ + guint i, n_caps = gst_caps_get_size(caps); + + g_print("%u %s caps\n", n_caps, name); + + for (i = 0; i < gst_caps_get_size(caps); i++) { + GstStructure * const structure = gst_caps_get_structure(caps, i); + if (!structure) + g_error("could not get caps structure %d", i); + + g_print(" %s:", gst_structure_get_name(structure)); + + if (gst_structure_has_name(structure, "video/x-raw-yuv")) { + guint32 fourcc; + + gst_structure_get_fourcc(structure, "format", &fourcc); + + g_print(" fourcc '%c%c%c%c'", + fourcc & 0xff, + (fourcc >> 8) & 0xff, + (fourcc >> 16) & 0xff, + (fourcc >> 24) & 0xff); + } + else { + gint bpp, endian, rmask, gmask, bmask, amask; + gboolean has_alpha; + + gst_structure_get_int(structure, "bpp", &bpp); + gst_structure_get_int(structure, "endianness", &endian); + gst_structure_get_int(structure, "red_mask", &rmask); + gst_structure_get_int(structure, "blue_mask", &bmask); + gst_structure_get_int(structure, "green_mask", &gmask); + has_alpha = gst_structure_get_int(structure, "alpha_mask", &amask); + + g_print(" %d bits per pixel, %s endian,", + bpp, endian == G_BIG_ENDIAN ? "big" : "little"); + g_print(" %s masks", has_alpha ? "rgba" : "rgb"); + g_print(" 0x%08x 0x%08x 0x%08x", rmask, gmask, bmask); + if (has_alpha) + g_print(" 0x%08x", amask); + } + g_print("\n"); + } +} + +static void +dump_caps(GstVaapiDisplay *display) +{ + GstCaps *caps; + + caps = gst_vaapi_display_get_image_caps(display); + if (!caps) + g_error("could not get VA image caps"); + + print_caps(caps, "image"); + gst_caps_unref(caps); + + caps = gst_vaapi_display_get_subpicture_caps(display); + if (!caps) + g_error("could not get VA subpicture caps"); + + print_caps(caps, "subpicture"); + gst_caps_unref(caps); +} + +int +main(int argc, char *argv[]) +{ + GstVaapiDisplay *display; + GstVaapiWindow *window; + GstVaapiWindowGLX *glx_window; + GLXContext glx_context; + Display *x11_display; + Window x11_window; + + static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + static const guint width = 320; + static const guint height = 240; + static const guint win_width = 640; + static const guint win_height = 480; + + gst_init(&argc, &argv); + + display = gst_vaapi_display_glx_new(NULL); + if (!display) + g_error("could not create Gst/VA display"); + + dump_caps(display); + + window = gst_vaapi_window_glx_new(display, win_width, win_height); + if (!window) + g_error("could not create window"); + + gst_vaapi_window_show(window); + + glx_window = GST_VAAPI_WINDOW_GLX(window); + glx_context = gst_vaapi_window_glx_get_context(glx_window); + x11_display = gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)); + x11_window = gst_vaapi_object_get_id(GST_VAAPI_OBJECT(window)); + + if (!glXMakeCurrent(x11_display, x11_window, glx_context)) + g_error("could not make VA/GLX window context current"); + + pause(); + + g_object_unref(window); + g_object_unref(display); + gst_deinit(); + return 0; +} From 02868d70f78e90f77f8fa61a89e1de7fef0b380f Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 25 Mar 2010 17:39:06 +0000 Subject: [PATCH 0195/3781] Add missing API documentation. --- docs/reference/libs/Makefile.am | 2 ++ docs/reference/libs/libs-docs.xml.in | 2 ++ docs/reference/libs/libs-sections.txt | 38 +++++++++++++++++++++++++++ docs/reference/libs/libs.types | 2 ++ 4 files changed, 44 insertions(+) diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index 3a753c533a..99947eef6f 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -54,6 +54,7 @@ CFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.c IGNORE_HFILES = \ gstvaapidebug.h \ gstvaapiutils.h \ + gstvaapiutils_glx.h \ gstvaapiutils_x11.h \ $(NULL) @@ -91,6 +92,7 @@ INCLUDES = \ GTKDOC_LIBS = \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la \ $(GLIB_LIBS) # This includes the standard gtk-doc make rules, copied by gtkdocize. diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 46a6cb4df1..29ef9b990b 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -13,8 +13,10 @@ + + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 2c118668d0..9ab6b92e08 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -74,6 +74,7 @@ GST_VAAPI_WINDOW_XWINDOW gst_vaapi_window_x11_new gst_vaapi_window_x11_new_with_xid gst_vaapi_window_x11_get_xid +gst_vaapi_window_x11_is_foreign_xid GST_VAAPI_WINDOW_X11 GST_VAAPI_IS_WINDOW_X11 @@ -84,6 +85,43 @@ GST_VAAPI_IS_WINDOW_X11_CLASS GST_VAAPI_WINDOW_X11_GET_CLASS
+
+gstvaapidisplay_glx +GstVaapiDisplayGLX +GstVaapiDisplayGLX +GstVaapiDisplayGLXClass +gst_vaapi_display_glx_new +gst_vaapi_display_glx_new_with_display + +GST_VAAPI_DISPLAY_GLX +GST_VAAPI_IS_DISPLAY_GLX +GST_VAAPI_TYPE_DISPLAY_GLX +gst_vaapi_display_glx_get_type +GST_VAAPI_DISPLAY_GLX_CLASS +GST_VAAPI_IS_DISPLAY_GLX_CLASS +GST_VAAPI_DISPLAY_GLX_GET_CLASS +
+ +
+gstvaapiwindow_glx +GstVaapiWindowGLX +GstVaapiWindowGLX +GstVaapiWindowGLXClass +gst_vaapi_window_glx_new +gst_vaapi_window_glx_new_with_xid +gst_vaapi_window_glx_get_context +gst_vaapi_window_glx_set_context +gst_vaapi_window_glx_swap_buffers + +GST_VAAPI_WINDOW_GLX +GST_VAAPI_IS_WINDOW_GLX +GST_VAAPI_TYPE_WINDOW_GLX +gst_vaapi_window_glx_get_type +GST_VAAPI_WINDOW_GLX_CLASS +GST_VAAPI_IS_WINDOW_GLX_CLASS +GST_VAAPI_WINDOW_GLX_GET_CLASS +
+
gstvaapidisplay GST_VAAPI_DISPLAY_VADISPLAY diff --git a/docs/reference/libs/libs.types b/docs/reference/libs/libs.types index 3d7aca2ae3..0bd9e59ad3 100644 --- a/docs/reference/libs/libs.types +++ b/docs/reference/libs/libs.types @@ -1,4 +1,5 @@ gst_vaapi_display_get_type +gst_vaapi_display_glx_get_type gst_vaapi_display_x11_get_type gst_vaapi_image_get_type gst_vaapi_image_pool_get_type @@ -10,4 +11,5 @@ gst_vaapi_video_buffer_get_type gst_vaapi_video_pool_get_type gst_vaapi_video_sink_get_type gst_vaapi_window_get_type +gst_vaapi_window_glx_get_type gst_vaapi_window_x11_get_type From ec3a04d74d38fcde0f85d9433d0322a3dfe50e7d Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 08:00:32 +0000 Subject: [PATCH 0196/3781] Fix compile flags. --- configure.ac | 10 +++++----- gst-libs/gst/vaapi/Makefile.am | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 3b73507bab..7879b3f0a9 100644 --- a/configure.ac +++ b/configure.ac @@ -160,16 +160,16 @@ USE_GLX=1 if test "$enable_glx" != "yes"; then USE_GLX=0 fi -OPENGL_CFLAGS="" -OPENGL_LIBS="" +GLX_CFLAGS="" +GLX_LIBS="" AC_CHECK_HEADERS([GL/gl.h GL/glext.h GL/glx.h], [], [USE_GLX=0], [ #ifdef HAVE_GL_GL_H # include #endif ]) -AC_CHECK_LIB(GL, glXCreateContext, [OPENGL_LIBS="-lGL -ldl"], [USE_GLX=0]) -AC_SUBST(OPENGL_CFLAGS) -AC_SUBST(OPENGL_LIBS) +AC_CHECK_LIB(GL, glXCreateContext, [GLX_LIBS="-lGL"], [USE_GLX=0]) +AC_SUBST(GLX_CFLAGS) +AC_SUBST(GLX_LIBS) dnl Check for VA-API LIBVA_PKGNAME="libva" diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index d9626f9a96..798ddbd90f 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -133,11 +133,13 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_CFLAGS = \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ + $(X11_CFLAGS) \ $(LIBVA_X11_CFLAGS) \ $(NULL) libgstvaapi_x11_@GST_MAJORMINOR@_la_LIBADD = \ $(GLIB_LIBS) \ + $(X11_LIBS) \ $(LIBVA_X11_LIBS) \ libgstvaapi-@GST_MAJORMINOR@.la \ $(NULL) @@ -158,11 +160,13 @@ libgstvaapi_glx_@GST_MAJORMINOR@_la_CFLAGS = \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ + $(GLX_CFLAGS) \ $(LIBVA_GLX_CFLAGS) \ $(NULL) libgstvaapi_glx_@GST_MAJORMINOR@_la_LIBADD = \ $(GLIB_LIBS) \ + $(GLX_LIBS) \ $(LIBVA_GLX_LIBS) \ libgstvaapi-x11-@GST_MAJORMINOR@.la \ $(NULL) From 1b62b8a642c73f46f7e35aa0108d86aaa0d69939 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 08:10:23 +0000 Subject: [PATCH 0197/3781] Add VA/GLX display tests. --- tests/Makefile.am | 38 +++++++++++++++-------- tests/test-display.c | 70 ++++++++++++++++++++++++++++++++++++++++++- tests/test-textures.c | 69 ------------------------------------------ 3 files changed, 94 insertions(+), 83 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index ed9ca0a637..12ab814e18 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -4,38 +4,50 @@ noinst_PROGRAMS = \ test-windows \ $(NULL) +if USE_GLX noinst_PROGRAMS += \ test-textures \ $(NULL) +endif -TEST_CFLAGS = \ - $(GST_CFLAGS) \ - -I$(top_srcdir)/gst-libs \ - $(X11_CFLAGS) +TEST_CFLAGS = -I$(top_srcdir)/gst-libs $(GST_CFLAGS) +TEST_X11_CFLAGS = -DUSE_X11 $(X11_CFLAGS) +TEST_GLX_CFLAGS = -DUSE_GLX $(GLX_CFLAGS) +TEST_MIX_CFLAGS = $(TEST_X11_CFLAGS) +if USE_GLX +TEST_MIX_CFLAGS += $(TEST_GLX_CFLAGS) +endif TEST_LIBS = \ - $(X11_LIBS) - -TEST_GLX_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-@GST_MAJORMINOR@.la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-@GST_MAJORMINOR@.la TEST_X11_LIBS = \ + $(X11_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la +TEST_GLX_LIBS = \ + $(GLX_LIBS) \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-@GST_MAJORMINOR@.la + +TEST_MIX_LIBS = $(TEST_X11_LIBS) +if USE_GLX +TEST_MIX_LIBS += $(TEST_GLX_LIBS) +endif + test_display_SOURCES = test-display.c -test_display_CFLAGS = $(TEST_CFLAGS) -test_display_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) +test_display_CFLAGS = $(TEST_CFLAGS) $(TEST_MIX_CFLAGS) +test_display_LDADD = $(TEST_LIBS) $(TEST_MIX_LIBS) test_surfaces_SOURCES = test-surfaces.c -test_surfaces_CFLAGS = $(TEST_CFLAGS) +test_surfaces_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) test_surfaces_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) test_windows_SOURCES = test-windows.c -test_windows_CFLAGS = $(TEST_CFLAGS) +test_windows_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) test_windows_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) test_textures_SOURCES = test-textures.c -test_textures_CFLAGS = $(TEST_CFLAGS) +test_textures_CFLAGS = $(TEST_CFLAGS) $(TEST_GLX_CFLAGS) test_textures_LDADD = $(TEST_LIBS) $(TEST_GLX_LIBS) # Extra clean files so that maintainer-clean removes *everything* diff --git a/tests/test-display.c b/tests/test-display.c index f401de6297..87ca968a66 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -19,7 +19,12 @@ */ #include +#ifdef USE_X11 #include +#endif +#ifdef USE_GLX +#include +#endif static void print_caps(GstCaps *caps, const gchar *name) @@ -98,6 +103,7 @@ main(int argc, char *argv[]) gst_init(&argc, &argv); +#ifdef USE_X11 g_print("#\n"); g_print("# Create display with gst_vaapi_display_x11_new()\n"); g_print("#\n"); @@ -136,7 +142,7 @@ main(int argc, char *argv[]) g_print("\n"); g_print("#\n"); - g_print("# Create display with gst_vaapi_display_new_with_display()\n"); + g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplay()]\n"); g_print("#\n"); { x11_display = XOpenDisplay(NULL); @@ -156,6 +162,68 @@ main(int argc, char *argv[]) XCloseDisplay(x11_display); } g_print("\n"); +#endif + +#ifdef USE_GLX + g_print("#\n"); + g_print("# Create display with gst_vaapi_display_glx_new()\n"); + g_print("#\n"); + { + display = gst_vaapi_display_glx_new(NULL); + if (!display) + g_error("could not create Gst/VA display"); + + gst_vaapi_display_get_size(display, &width, &height); + g_print("Display size: %ux%u\n", width, height); + + gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d); + g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); + + dump_caps(display); + g_object_unref(display); + } + g_print("\n"); + + g_print("#\n"); + g_print("# Create display with gst_vaapi_display_glx_new_with_display()\n"); + g_print("#\n"); + { + x11_display = XOpenDisplay(NULL); + if (!x11_display) + g_error("could not create X11 display"); + + display = gst_vaapi_display_glx_new_with_display(x11_display); + if (!display) + g_error("could not create Gst/VA display"); + + dump_caps(display); + g_object_unref(display); + XCloseDisplay(x11_display); + } + g_print("\n"); + + g_print("#\n"); + g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayGLX()]\n"); + g_print("#\n"); + { + x11_display = XOpenDisplay(NULL); + if (!x11_display) + g_error("could not create X11 display"); + + va_display = vaGetDisplayGLX(x11_display); + if (!va_display) + g_error("could not create VA display"); + + display = gst_vaapi_display_new_with_display(va_display); + if (!display) + g_error("could not create Gst/VA display"); + + dump_caps(display); + g_object_unref(display); + XCloseDisplay(x11_display); + } + g_print("\n"); +#endif gst_deinit(); return 0; diff --git a/tests/test-textures.c b/tests/test-textures.c index 493faa21b2..348b7f263a 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -27,73 +27,6 @@ static inline void pause(void) getchar(); } -static void -print_caps(GstCaps *caps, const gchar *name) -{ - guint i, n_caps = gst_caps_get_size(caps); - - g_print("%u %s caps\n", n_caps, name); - - for (i = 0; i < gst_caps_get_size(caps); i++) { - GstStructure * const structure = gst_caps_get_structure(caps, i); - if (!structure) - g_error("could not get caps structure %d", i); - - g_print(" %s:", gst_structure_get_name(structure)); - - if (gst_structure_has_name(structure, "video/x-raw-yuv")) { - guint32 fourcc; - - gst_structure_get_fourcc(structure, "format", &fourcc); - - g_print(" fourcc '%c%c%c%c'", - fourcc & 0xff, - (fourcc >> 8) & 0xff, - (fourcc >> 16) & 0xff, - (fourcc >> 24) & 0xff); - } - else { - gint bpp, endian, rmask, gmask, bmask, amask; - gboolean has_alpha; - - gst_structure_get_int(structure, "bpp", &bpp); - gst_structure_get_int(structure, "endianness", &endian); - gst_structure_get_int(structure, "red_mask", &rmask); - gst_structure_get_int(structure, "blue_mask", &bmask); - gst_structure_get_int(structure, "green_mask", &gmask); - has_alpha = gst_structure_get_int(structure, "alpha_mask", &amask); - - g_print(" %d bits per pixel, %s endian,", - bpp, endian == G_BIG_ENDIAN ? "big" : "little"); - g_print(" %s masks", has_alpha ? "rgba" : "rgb"); - g_print(" 0x%08x 0x%08x 0x%08x", rmask, gmask, bmask); - if (has_alpha) - g_print(" 0x%08x", amask); - } - g_print("\n"); - } -} - -static void -dump_caps(GstVaapiDisplay *display) -{ - GstCaps *caps; - - caps = gst_vaapi_display_get_image_caps(display); - if (!caps) - g_error("could not get VA image caps"); - - print_caps(caps, "image"); - gst_caps_unref(caps); - - caps = gst_vaapi_display_get_subpicture_caps(display); - if (!caps) - g_error("could not get VA subpicture caps"); - - print_caps(caps, "subpicture"); - gst_caps_unref(caps); -} - int main(int argc, char *argv[]) { @@ -116,8 +49,6 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); - dump_caps(display); - window = gst_vaapi_window_glx_new(display, win_width, win_height); if (!window) g_error("could not create window"); From c3dcabd90c29bcd82357d141b471fa1a4fd4a3af Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 08:35:24 +0000 Subject: [PATCH 0198/3781] Check GstVaapiWindow::render() is available prior to calling it. --- gst-libs/gst/vaapi/gstvaapiwindow.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 495d86fce8..5f521d4cae 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -482,12 +482,17 @@ gst_vaapi_window_put_surface( guint flags ) { + GstVaapiWindowClass *klass; GstVaapiRectangle src_rect_default, dst_rect_default; g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE); g_return_val_if_fail(window->priv->is_constructed, FALSE); g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + klass = GST_VAAPI_WINDOW_GET_CLASS(window); + if (!klass->render) + return FALSE; + if (!src_rect) { src_rect = &src_rect_default; get_surface_rect(surface, &src_rect_default); @@ -498,9 +503,5 @@ gst_vaapi_window_put_surface( get_window_rect(window, &dst_rect_default); } - return GST_VAAPI_WINDOW_GET_CLASS(window)->render(window, - surface, - src_rect, - dst_rect, - flags); + return klass->render(window, surface, src_rect, dst_rect, flags); } From c9f62b74053cfd624e02840008844a2d86ba44e2 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 09:41:12 +0000 Subject: [PATCH 0199/3781] Add gst_vaapi_window_glx_make_current(). Handle X11 window size changes and reset the GL viewport. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 28 ++++++++++ gst-libs/gst/vaapi/gstvaapiutils_glx.h | 10 ++++ gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 68 +++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 3 ++ 4 files changed, 106 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 8053a54aa7..61721fb912 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -181,3 +181,31 @@ gl_resize(guint width, guint height) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } + +/** + * gl_make_current: + * @dpy: an X11 #Display + * @win: an X11 #Window + * @ctx: the requested GLX context + * @state: an optional #GLContextState + * + * Makes the @window GLX context the current GLX rendering context of + * the calling thread, replacing the previously current context if + * there was one. + * + * If @state is non %NULL, the previously current GLX context and + * window are recorded. + * + * Return value: %TRUE on success + */ +gboolean +gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state) +{ + if (state) { + state->context = glXGetCurrentContext(); + state->window = glXGetCurrentDrawable(); + if (state->context == ctx && state->window == win) + return TRUE; + } + return glXMakeCurrent(dpy, win, ctx); +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 79328e72bb..7251e22682 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -54,4 +54,14 @@ void gl_resize(guint width, guint height) attribute_hidden; +typedef struct _GLContextState GLContextState; +struct _GLContextState { + GLXContext context; + Window window; +}; + +gboolean +gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state) + attribute_hidden; + #endif /* GST_VAAPI_UTILS_GLX_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 5d91116fca..d448ff4773 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -47,6 +47,7 @@ struct _GstVaapiWindowGLXPrivate { XVisualInfo vi_static; Colormap cmap; GLXContext context; + guint is_constructed : 1; guint foreign_context : 1; guint foreign_window : 1; }; @@ -83,7 +84,7 @@ gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window) if (!priv->foreign_context) { GST_VAAPI_OBJECT_LOCK_DISPLAY(window); if (glXGetCurrentContext() == priv->context) - glXMakeCurrent(dpy, None, NULL); + gl_make_current(dpy, None, NULL, NULL); glXDestroyContext(dpy, priv->context); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); } @@ -98,6 +99,7 @@ gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window) GstVaapiWindowGLXPrivate * const priv = window->priv; Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); GLXContext ctx = NULL; + GLContextState cs; guint width, height; gboolean has_errors = TRUE; @@ -108,7 +110,7 @@ gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window) ctx = glXCreateContext(dpy, priv->vi, NULL, True); if (ctx && glXIsDirect(dpy, ctx)) { _gst_vaapi_window_glx_set_context(window, ctx, FALSE); - if (glXMakeCurrent(dpy, GST_VAAPI_OBJECT_ID(window), ctx)) { + if (gl_make_current(dpy, GST_VAAPI_OBJECT_ID(window), ctx, &cs)) { glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glDisable(GL_CULL_FACE); @@ -122,6 +124,8 @@ gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window) gl_set_bgcolor(0); glClear(GL_COLOR_BUFFER_BIT); + if (cs.context) + gl_make_current(dpy, cs.window, cs.context, NULL); has_errors = FALSE; } } @@ -258,6 +262,26 @@ gst_vaapi_window_glx_get_colormap(GstVaapiWindow *window) return gst_vaapi_window_glx_create_colormap(GST_VAAPI_WINDOW_GLX(window)); } +static gboolean +gst_vaapi_window_glx_resize(GstVaapiWindow *window, guint width, guint height) +{ + GstVaapiWindowGLXPrivate * const priv = GST_VAAPI_WINDOW_GLX(window)->priv; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + GLContextState cs; + + if (!GST_VAAPI_WINDOW_CLASS(gst_vaapi_window_glx_parent_class)-> + resize(window, width, height)) + return FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + if (gl_make_current(dpy, GST_VAAPI_OBJECT_ID(window), priv->context, &cs)) { + gl_resize(width, height); + gl_make_current(dpy, cs.window, cs.context, NULL); + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + return TRUE; +} + static void gst_vaapi_window_glx_finalize(GObject *object) { @@ -325,7 +349,7 @@ gst_vaapi_window_glx_constructed(GObject *object) priv->foreign_window = gst_vaapi_window_x11_is_foreign_xid(GST_VAAPI_WINDOW_X11(object)); - if (!priv->foreign_context) + priv->is_constructed = priv->foreign_context || gst_vaapi_window_glx_create_context(GST_VAAPI_WINDOW_GLX(object)); } @@ -333,6 +357,7 @@ static void gst_vaapi_window_glx_class_init(GstVaapiWindowGLXClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiWindowClass * const win_class = GST_VAAPI_WINDOW_CLASS(klass); GstVaapiWindowX11Class * const xwin_class = GST_VAAPI_WINDOW_X11_CLASS(klass); g_type_class_add_private(klass, sizeof(GstVaapiWindowGLXPrivate)); @@ -342,6 +367,7 @@ gst_vaapi_window_glx_class_init(GstVaapiWindowGLXClass *klass) object_class->get_property = gst_vaapi_window_glx_get_property; object_class->constructed = gst_vaapi_window_glx_constructed; + win_class->resize = gst_vaapi_window_glx_resize; xwin_class->get_visual = gst_vaapi_window_glx_get_visual; xwin_class->get_colormap = gst_vaapi_window_glx_get_colormap; @@ -369,7 +395,9 @@ gst_vaapi_window_glx_init(GstVaapiWindowGLX *window) priv->vi = NULL; priv->cmap = None; priv->context = NULL; + priv->is_constructed = FALSE; priv->foreign_context = FALSE; + priv->foreign_window = FALSE; } /** @@ -437,6 +465,7 @@ GLXContext gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window) { g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), NULL); + g_return_val_if_fail(window->priv->is_constructed, FALSE); return window->priv->context; } @@ -457,6 +486,7 @@ gboolean gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx) { g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE); + g_return_val_if_fail(window->priv->is_constructed, FALSE); gst_vaapi_window_glx_destroy_context(window); @@ -467,6 +497,35 @@ gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx) return gst_vaapi_window_glx_create_context(window); } +/** + * gst_vaapi_window_glx_make_current: + * @window: a #GstVaapiWindowGLX + * + * Makes the @window GLX context the current GLX rendering context of + * the calling thread, replacing the previously current context if + * there was one. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window) +{ + gboolean success; + + g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE); + g_return_val_if_fail(window->priv->is_constructed, FALSE); + + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + success = gl_make_current( + GST_VAAPI_OBJECT_XDISPLAY(window), + GST_VAAPI_OBJECT_ID(window), + window->priv->context, + NULL + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + return success; +} + /** * gst_vaapi_window_glx_swap_buffers: * @window: a #GstVaapiWindowGLX @@ -479,10 +538,13 @@ void gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window) { g_return_if_fail(GST_VAAPI_IS_WINDOW_GLX(window)); + g_return_if_fail(window->priv->is_constructed); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); glXSwapBuffers( GST_VAAPI_OBJECT_XDISPLAY(window), GST_VAAPI_OBJECT_ID(window) ); glClear(GL_COLOR_BUFFER_BIT); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index b10fcd4d50..d336d8953b 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -92,6 +92,9 @@ gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window); gboolean gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx); +gboolean +gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window); + void gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window); From 72fb4f6def132787f748a6a5bb468e0fd286dbc8 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 10:09:23 +0000 Subject: [PATCH 0200/3781] Restore GLX context only if there is one. --- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index d448ff4773..f99caf24fe 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -276,7 +276,8 @@ gst_vaapi_window_glx_resize(GstVaapiWindow *window, guint width, guint height) GST_VAAPI_OBJECT_LOCK_DISPLAY(window); if (gl_make_current(dpy, GST_VAAPI_OBJECT_ID(window), priv->context, &cs)) { gl_resize(width, height); - gl_make_current(dpy, cs.window, cs.context, NULL); + if (cs.context) + gl_make_current(dpy, cs.window, cs.context, NULL); } GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); return TRUE; From 15b2a9beec72eabc108c1e171f89ca7d81607c87 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 11:02:12 +0000 Subject: [PATCH 0201/3781] Only add _display suffix to open & close members because they could be #define to some arbitrary value. lock/unlock are safe names. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 12 ++++++------ gst-libs/gst/vaapi/gstvaapidisplay.h | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 0193681bc5..314bf38af3 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -461,8 +461,8 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) object_class->get_property = gst_vaapi_display_get_property; object_class->constructed = gst_vaapi_display_constructed; - dpy_class->lock_display = gst_vaapi_display_lock_default; - dpy_class->unlock_display = gst_vaapi_display_unlock_default; + dpy_class->lock = gst_vaapi_display_lock_default; + dpy_class->unlock = gst_vaapi_display_unlock_default; g_object_class_install_property (object_class, @@ -545,8 +545,8 @@ gst_vaapi_display_lock(GstVaapiDisplay *display) g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); klass = GST_VAAPI_DISPLAY_GET_CLASS(display); - if (klass->lock_display) - klass->lock_display(display); + if (klass->lock) + klass->lock(display); } /** @@ -565,8 +565,8 @@ gst_vaapi_display_unlock(GstVaapiDisplay *display) g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); klass = GST_VAAPI_DISPLAY_GET_CLASS(display); - if (klass->unlock_display) - klass->unlock_display(display); + if (klass->unlock) + klass->unlock(display); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 1dddf59557..1147d00b33 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -103,8 +103,8 @@ struct _GstVaapiDisplay { * GstVaapiDisplayClass: * @open_display: virtual function to open a display * @close_display: virtual function to close a display - * @lock_display: virtual function to lock a display - * @unlock_display: virtual function to unlock a display + * @lock: virtual function to lock a display + * @unlock: virtual function to unlock a display * @get_display: virtual function to retrieve the #VADisplay * @get_size: virtual function to retrieve the display dimensions, in pixels * @get_size_mm: virtual function to retrieve the display dimensions, in millimeters @@ -118,8 +118,8 @@ struct _GstVaapiDisplayClass { /*< public >*/ gboolean (*open_display) (GstVaapiDisplay *display); void (*close_display) (GstVaapiDisplay *display); - void (*lock_display) (GstVaapiDisplay *display); - void (*unlock_display)(GstVaapiDisplay *display); + void (*lock) (GstVaapiDisplay *display); + void (*unlock) (GstVaapiDisplay *display); VADisplay (*get_display) (GstVaapiDisplay *display); void (*get_size) (GstVaapiDisplay *display, guint *pwidth, guint *pheight); From 8ea56134da261c6087f6d7f9873258da3fa8f5e1 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 11:30:54 +0000 Subject: [PATCH 0202/3781] Add "synchronous" mode. --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 40 +++++++++++++++++++++++- sys/vaapisink/gstvaapisink.c | 26 ++++++++++++++- sys/vaapisink/gstvaapisink.h | 1 + 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 30f71521e6..9f4349e13b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -40,15 +40,17 @@ G_DEFINE_TYPE(GstVaapiDisplayX11, GstVaapiDisplayX11Private)) struct _GstVaapiDisplayX11Private { - gboolean create_display; gchar *display_name; Display *x11_display; int x11_screen; + guint create_display : 1; + guint synchronous : 1; }; enum { PROP_0, + PROP_SYNCHRONOUS, PROP_DISPLAY_NAME, PROP_X11_DISPLAY }; @@ -72,6 +74,18 @@ set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name) priv->display_name = NULL; } +static void +set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous) +{ + GstVaapiDisplayX11Private * const priv = display->priv; + + if (priv->synchronous != synchronous) { + priv->synchronous = synchronous; + if (priv->x11_display) + XSynchronize(priv->x11_display, synchronous); + } +} + static void gst_vaapi_display_x11_set_property( GObject *object, @@ -83,6 +97,9 @@ gst_vaapi_display_x11_set_property( GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); switch (prop_id) { + case PROP_SYNCHRONOUS: + set_synchronous(display, g_value_get_boolean(value)); + break; case PROP_DISPLAY_NAME: set_display_name(display, g_value_get_string(value)); break; @@ -106,6 +123,9 @@ gst_vaapi_display_x11_get_property( GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); switch (prop_id) { + case PROP_SYNCHRONOUS: + g_value_set_boolean(value, display->priv->synchronous); + break; case PROP_DISPLAY_NAME: g_value_set_string(value, display->priv->display_name); break; @@ -147,6 +167,9 @@ gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) if (!priv->x11_display) return FALSE; + if (priv->synchronous) + XSynchronize(priv->x11_display, True); + priv->x11_screen = DefaultScreen(priv->x11_display); return TRUE; } @@ -234,6 +257,21 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) dpy_class->get_size = gst_vaapi_display_x11_get_size; dpy_class->get_size_mm = gst_vaapi_display_x11_get_size_mm; + /** + * GstVaapiDisplayX11:synchronous: + * + * When enabled, runs the X display in synchronous mode. Note that + * this is used only for debugging. + */ + g_object_class_install_property + (object_class, + PROP_SYNCHRONOUS, + g_param_spec_boolean("synchronous", + "Synchronous mode", + "Toggles X display synchronous mode", + FALSE, + G_PARAM_READWRITE)); + /** * GstVaapiDisplayX11:x11-display: * diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 3103045b23..228218952c 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -74,7 +74,8 @@ enum { PROP_0, PROP_DISPLAY, - PROP_FULLSCREEN + PROP_FULLSCREEN, + PROP_SYNCHRONOUS }; static GstVaapiDisplay * @@ -120,6 +121,7 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink) sink->display = gst_vaapi_display_x11_new(sink->display_name); if (!sink->display || !gst_vaapi_display_get_display(sink->display)) return FALSE; + g_object_set(sink, "synchronous", sink->synchronous, NULL); } return sink->display != NULL; } @@ -291,6 +293,9 @@ gst_vaapisink_set_property( case PROP_FULLSCREEN: sink->fullscreen = g_value_get_boolean(value); break; + case PROP_SYNCHRONOUS: + sink->synchronous = g_value_get_boolean(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -314,6 +319,9 @@ gst_vaapisink_get_property( case PROP_FULLSCREEN: g_value_set_boolean(value, sink->fullscreen); break; + case PROP_SYNCHRONOUS: + g_value_set_boolean(value, sink->synchronous); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -364,6 +372,21 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) "Requests window in fullscreen state", FALSE, G_PARAM_READWRITE)); + + /** + * GstVaapiSink:synchronous: + * + * When enabled, runs the X display in synchronous mode. Note that + * this is used only for debugging. + */ + g_object_class_install_property + (object_class, + PROP_SYNCHRONOUS, + g_param_spec_boolean("synchronous", + "Synchronous mode", + "Toggles X display synchronous mode", + FALSE, + G_PARAM_READWRITE)); } static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) @@ -371,6 +394,7 @@ static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) sink->display_name = NULL; sink->display = NULL; sink->fullscreen = FALSE; + sink->synchronous = FALSE; } GstVaapiDisplay * diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h index f4a3e085b9..12b74ca40e 100644 --- a/sys/vaapisink/gstvaapisink.h +++ b/sys/vaapisink/gstvaapisink.h @@ -64,6 +64,7 @@ struct _GstVaapiSink { GstVaapiWindow *window; GstVaapiRectangle window_rect; guint fullscreen : 1; + guint synchronous : 1; }; struct _GstVaapiSinkClass { From 9f369020b59163aeed22078efa36b429acb1c257 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 11:35:20 +0000 Subject: [PATCH 0203/3781] Add gst_vaapi_display_{sync,flush}() helpers. --- docs/reference/libs/libs-sections.txt | 2 + gst-libs/gst/vaapi/gstvaapidisplay.c | 50 +++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidisplay.h | 14 ++++++- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 22 +++++++++++ 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 9ab6b92e08..6de29292aa 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -133,6 +133,8 @@ GstVaapiDisplayClass gst_vaapi_display_new_with_display gst_vaapi_display_lock gst_vaapi_display_unlock +gst_vaapi_display_sync +gst_vaapi_display_flush gst_vaapi_display_get_display gst_vaapi_display_get_width gst_vaapi_display_get_height diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 314bf38af3..f015620c22 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -48,10 +48,10 @@ struct _GstVaapiDisplayPrivate { guint height_mm; guint par_n; guint par_d; - gboolean create_display; GArray *profiles; GArray *image_formats; GArray *subpicture_formats; + guint create_display : 1; }; enum { @@ -504,10 +504,10 @@ gst_vaapi_display_init(GstVaapiDisplay *display) priv->height_mm = 0; priv->par_n = 1; priv->par_d = 1; - priv->create_display = TRUE; priv->profiles = NULL; priv->image_formats = NULL; priv->subpicture_formats = NULL; + priv->create_display = TRUE; g_static_mutex_init(&priv->mutex); } @@ -569,6 +569,52 @@ gst_vaapi_display_unlock(GstVaapiDisplay *display) klass->unlock(display); } +/** + * gst_vaapi_display_sync: + * @display: a #GstVaapiDisplay + * + * Flushes any requests queued for the windowing system and waits until + * all requests have been handled. This is often used for making sure + * that the display is synchronized with the current state of the program. + * + * This is most useful for X11. On windowing systems where requests are + * handled synchronously, this function will do nothing. + */ +void +gst_vaapi_display_sync(GstVaapiDisplay *display) +{ + GstVaapiDisplayClass *klass; + + g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); + + klass = GST_VAAPI_DISPLAY_GET_CLASS(display); + if (klass->sync) + klass->sync(display); + else if (klass->flush) + klass->flush(display); +} + +/** + * gst_vaapi_display_sync: + * @display: a #GstVaapiDisplay + * + * Flushes any requests queued for the windowing system. + * + * This is most useful for X11. On windowing systems where requests + * are handled synchronously, this function will do nothing. + */ +void +gst_vaapi_display_flush(GstVaapiDisplay *display) +{ + GstVaapiDisplayClass *klass; + + g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); + + klass = GST_VAAPI_DISPLAY_GET_CLASS(display); + if (klass->flush) + klass->flush(display); +} + /** * gst_vaapi_display_get_display: * @display: a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 1147d00b33..e654be63ee 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -103,8 +103,10 @@ struct _GstVaapiDisplay { * GstVaapiDisplayClass: * @open_display: virtual function to open a display * @close_display: virtual function to close a display - * @lock: virtual function to lock a display - * @unlock: virtual function to unlock 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 #VADisplay * @get_size: virtual function to retrieve the display dimensions, in pixels * @get_size_mm: virtual function to retrieve the display dimensions, in millimeters @@ -120,6 +122,8 @@ struct _GstVaapiDisplayClass { void (*close_display) (GstVaapiDisplay *display); void (*lock) (GstVaapiDisplay *display); void (*unlock) (GstVaapiDisplay *display); + void (*sync) (GstVaapiDisplay *display); + void (*flush) (GstVaapiDisplay *display); VADisplay (*get_display) (GstVaapiDisplay *display); void (*get_size) (GstVaapiDisplay *display, guint *pwidth, guint *pheight); @@ -139,6 +143,12 @@ 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); + VADisplay gst_vaapi_display_get_display(GstVaapiDisplay *display); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 9f4349e13b..705051b142 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -192,6 +192,26 @@ gst_vaapi_display_x11_close_display(GstVaapiDisplay *display) } } +static void +gst_vaapi_display_x11_sync(GstVaapiDisplay *display) +{ + GstVaapiDisplayX11Private * const priv = + GST_VAAPI_DISPLAY_X11(display)->priv; + + if (priv->x11_display) + XSync(priv->x11_display, False); +} + +static void +gst_vaapi_display_x11_flush(GstVaapiDisplay *display) +{ + GstVaapiDisplayX11Private * const priv = + GST_VAAPI_DISPLAY_X11(display)->priv; + + if (priv->x11_display) + XFlush(priv->x11_display); +} + static VADisplay gst_vaapi_display_x11_get_va_display(GstVaapiDisplay *display) { @@ -253,6 +273,8 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) 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_va_display; dpy_class->get_size = gst_vaapi_display_x11_get_size; dpy_class->get_size_mm = gst_vaapi_display_x11_get_size_mm; From b50e7f1050c652b7eb50f62c60467f5fe2b884b5 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 11:39:20 +0000 Subject: [PATCH 0204/3781] gstvaapicompat.h is a private header, don't install it. --- gst-libs/gst/vaapi/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 798ddbd90f..6b3990b1d6 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -62,12 +62,12 @@ libgstvaapi_x11_source_c = \ $(NULL) libgstvaapi_x11_source_h = \ - gstvaapicompat.h \ gstvaapidisplay_x11.h \ gstvaapiwindow_x11.h \ $(NULL) libgstvaapi_x11_source_priv_h = \ + gstvaapicompat.h \ gstvaapiutils.h \ gstvaapiutils_x11.h \ $(NULL) @@ -81,12 +81,12 @@ libgstvaapi_glx_source_c = \ $(NULL) libgstvaapi_glx_source_h = \ - gstvaapicompat.h \ gstvaapidisplay_glx.h \ gstvaapiwindow_glx.h \ $(NULL) libgstvaapi_glx_source_priv_h = \ + gstvaapicompat.h \ gstvaapiutils.h \ gstvaapiutils_glx.h \ gstvaapiutils_x11.h \ From d84d6b0f8041e2dcfacd9a46e5edb0ed08eacd5f Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 11:50:31 +0000 Subject: [PATCH 0205/3781] Make sure window resize completed prior to resizing the GL viewport. --- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index f99caf24fe..b516a29bd1 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -274,6 +274,7 @@ gst_vaapi_window_glx_resize(GstVaapiWindow *window, guint width, guint height) return FALSE; GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + XSync(dpy, False); /* make sure resize completed */ if (gl_make_current(dpy, GST_VAAPI_OBJECT_ID(window), priv->context, &cs)) { gl_resize(width, height); if (cs.context) From 22fe28b8236b963108118f7888ccc21e9e696c43 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 11:54:43 +0000 Subject: [PATCH 0206/3781] MT-Safe: lock display. --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 705051b142..ebfa14b70b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -198,8 +198,11 @@ gst_vaapi_display_x11_sync(GstVaapiDisplay *display) GstVaapiDisplayX11Private * const priv = GST_VAAPI_DISPLAY_X11(display)->priv; - if (priv->x11_display) + if (priv->x11_display) { + GST_VAAPI_DISPLAY_LOCK(display); XSync(priv->x11_display, False); + GST_VAAPI_DISPLAY_UNLOCK(display); + } } static void @@ -208,8 +211,11 @@ gst_vaapi_display_x11_flush(GstVaapiDisplay *display) GstVaapiDisplayX11Private * const priv = GST_VAAPI_DISPLAY_X11(display)->priv; - if (priv->x11_display) + if (priv->x11_display) { + GST_VAAPI_DISPLAY_LOCK(display); XFlush(priv->x11_display); + GST_VAAPI_DISPLAY_UNLOCK(display); + } } static VADisplay From 9248f187350db7833a1feb1e901044e995061f0b Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 15:16:01 +0000 Subject: [PATCH 0207/3781] Factor out image utilities. --- tests/Makefile.am | 2 +- tests/image.c | 320 +++++++++++++++++++++++++++++++++++++++++++ tests/image.h | 44 ++++++ tests/test-windows.c | 271 +----------------------------------- 4 files changed, 372 insertions(+), 265 deletions(-) create mode 100644 tests/image.c create mode 100644 tests/image.h diff --git a/tests/Makefile.am b/tests/Makefile.am index 12ab814e18..85e326c0c5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -42,7 +42,7 @@ test_surfaces_SOURCES = test-surfaces.c test_surfaces_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) test_surfaces_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) -test_windows_SOURCES = test-windows.c +test_windows_SOURCES = test-windows.c image.c test_windows_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) test_windows_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) diff --git a/tests/image.c b/tests/image.c new file mode 100644 index 0000000000..478ed77c39 --- /dev/null +++ b/tests/image.c @@ -0,0 +1,320 @@ +/* + * image.c - Image utilities for the tests + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "image.h" + +GstVaapiImage * +image_generate( + GstVaapiDisplay *display, + GstVaapiImageFormat format, + guint width, + guint height +) +{ + const guint w = width; + const guint h = height; + GstVaapiImage *image; + + image = gst_vaapi_image_new(display, format, w, h); + if (!image) + return NULL; + + if (image_draw_rectangle(image, 0, 0, w/2, h/2, 0xffff0000) && + image_draw_rectangle(image, w/2, 0, w/2, h/2, 0xff00ff00) && + image_draw_rectangle(image, 0, h/2, w/2, h/2, 0xff0000ff) && + image_draw_rectangle(image, w/2, h/2, w/2, h/2, 0xff000000)) + return image; + + g_object_unref(image); + return NULL; +} + +typedef void (*DrawRectFunc)( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +); + +static void draw_rect_ARGB( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + guint i, j; + + color = GUINT32_TO_BE(color); + + for (j = 0; j < height; j++) { + guint32 *p = (guint32 *)(pixels[0] + (y + j) * stride[0] + x * 4); + for (i = 0; i < width; i++) + p[i] = color; + } +} + +static void draw_rect_BGRA( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + // Converts ARGB color to BGRA + color = GUINT32_SWAP_LE_BE(color); + + draw_rect_ARGB(pixels, stride, x, y, width, height, color); +} + +static void draw_rect_RGBA( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + // Converts ARGB color to RGBA + color = ((color >> 24) & 0xff) | ((color & 0xffffff) << 8); + + draw_rect_ARGB(pixels, stride, x, y, width, height, color); +} + +static void draw_rect_ABGR( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + // Converts ARGB color to ABGR + color = ((color & 0xff00ff00) | + ((color >> 16) & 0xff) | + ((color & 0xff) << 16)); + + draw_rect_ARGB(pixels, stride, x, y, width, height, color); +} + +static void draw_rect_NV12( // Y, UV planes + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + const guchar Y = color >> 16; + const guchar Cb = color >> 8; + const guchar Cr = color; + guchar *dst; + guint i, j; + + dst = pixels[0] + y * stride[0] + x; + for (j = 0; j < height; j++, dst += stride[0]) + for (i = 0; i < width; i++) + dst[i] = Y; + + x /= 2; + y /= 2; + width /= 2; + height /= 2; + + dst = pixels[1] + y * stride[1] + x * 2; + for (j = 0; j < height; j++, dst += stride[1]) + for (i = 0; i < width; i++) { + dst[2*i + 0] = Cb; + dst[2*i + 1] = Cr; + } +} + +static void draw_rect_YV12( // Y, V, U planes + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + const guchar Y = color >> 16; + const guchar Cb = color >> 8; + const guchar Cr = color; + guchar *pY, *pU, *pV; + guint i, j; + + pY = pixels[0] + y * stride[0] + x; + for (j = 0; j < height; j++, pY += stride[0]) + for (i = 0; i < width; i++) + pY[i] = Y; + + x /= 2; + y /= 2; + width /= 2; + height /= 2; + + pU = pixels[1] + y * stride[1] + x; + pV = pixels[2] + y * stride[2] + x; + for (j = 0; j < height; j++, pU += stride[1], pV += stride[2]) + for (i = 0; i < width; i++) { + pU[i] = Cb; + pV[i] = Cr; + } +} + +static void draw_rect_I420( // Y, U, V planes + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + guchar *new_pixels[3] = { pixels[0], pixels[2], pixels[1] }; + guint new_stride[3] = { stride[0], stride[2], stride[1] }; + + draw_rect_YV12(new_pixels, new_stride, x, y, width, height, color); +} + +static void draw_rect_AYUV( + guchar *pixels[3], + guint stride[3], + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + guint i, j; + + color = color | 0xff000000; + + for (j = 0; j < height; j++) { + guint32 *p = (guint32 *)(pixels[0] + (y + j) * stride[0] + x * 4); + for (i = 0; i < width; i++) + p[i] = color; + } +} + +static inline guint32 argb2yuv(guint32 color) +{ + const gint32 r = (color >> 16) & 0xff; + const gint32 g = (color >> 8) & 0xff; + const gint32 b = (color ) & 0xff; + + const guint32 y = (( 263 * r + 516 * g + 100 * b) >> 10) + 16; + const guint32 u = ((-152 * r - 298 * g + 450 * b) >> 10) + 128; + const guint32 v = (( 450 * r - 376 * g - 73 * b) >> 10) + 128; + + return (y << 16) | (u << 8) | v; +} + +gboolean +image_draw_rectangle( + GstVaapiImage *image, + gint x, + gint y, + guint width, + guint height, + guint32 color +) +{ + const GstVaapiImageFormat image_format = gst_vaapi_image_get_format(image); + const guint image_width = gst_vaapi_image_get_width(image); + const guint image_height = gst_vaapi_image_get_height(image); + GstVaapiDisplay *display; + guchar *pixels[3]; + guint stride[3]; + DrawRectFunc draw_rect = NULL; + guint i; + + static const struct { + GstVaapiImageFormat format; + DrawRectFunc draw_rect; + } + map[] = { +#define _(FORMAT) { GST_VAAPI_IMAGE_##FORMAT, draw_rect_##FORMAT } + _(ARGB), + _(BGRA), + _(RGBA), + _(ABGR), + _(NV12), + _(YV12), + _(I420), + _(AYUV), +#undef _ + { 0, } + }; + + for (i = 0; !draw_rect && map[i].format; i++) + if (map[i].format == image_format) + draw_rect = map[i].draw_rect; + if (!draw_rect) + return FALSE; + + display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(image)); + if (!display) + return FALSE; + + if (!gst_vaapi_image_map(image)) + return FALSE; + + for (i = 0; i < gst_vaapi_image_get_plane_count(image); i++) { + pixels[i] = gst_vaapi_image_get_plane(image, i); + stride[i] = gst_vaapi_image_get_pitch(image, i); + } + + if (gst_vaapi_image_format_is_yuv(image_format)) + color = argb2yuv(color); + + if (x < 0) + x = 0; + if (y < 0) + y = 0; + if (width > image_width - x) + width = image_width - x; + if (height > image_height - y) + height = image_height - y; + + gst_vaapi_display_lock(display); + draw_rect(pixels, stride, x, y, width, height, color); + gst_vaapi_display_unlock(display); + return gst_vaapi_image_unmap(image); +} diff --git a/tests/image.h b/tests/image.h new file mode 100644 index 0000000000..eb914de873 --- /dev/null +++ b/tests/image.h @@ -0,0 +1,44 @@ +/* + * image.h - Image utilities for the tests + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef IMAGE_H +#define IMAGE_H + +#include + +GstVaapiImage * +image_generate( + GstVaapiDisplay *display, + GstVaapiImageFormat format, + guint width, + guint height +); + +gboolean +image_draw_rectangle( + GstVaapiImage *image, + gint x, + gint y, + guint width, + guint height, + guint32 color +); + +#endif /* IMAGE_H */ diff --git a/tests/test-windows.c b/tests/test-windows.c index 3aa4a509bf..7292bbaeab 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -22,6 +22,7 @@ #include #include #include +#include "image.h" static inline void pause(void) { @@ -29,261 +30,6 @@ static inline void pause(void) getchar(); } -typedef void (*DrawRectFunc)( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -); - -static void draw_rect_ARGB( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - guint i, j; - - color = GUINT32_TO_BE(color); - - for (j = 0; j < height; j++) { - guint32 *p = (guint32 *)(pixels[0] + (y + j) * stride[0] + x * 4); - for (i = 0; i < width; i++) - p[i] = color; - } -} - -static void draw_rect_BGRA( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - // Converts ARGB color to BGRA - color = GUINT32_SWAP_LE_BE(color); - - draw_rect_ARGB(pixels, stride, x, y, width, height, color); -} - -static void draw_rect_RGBA( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - // Converts ARGB color to RGBA - color = ((color >> 24) & 0xff) | ((color & 0xffffff) << 8); - - draw_rect_ARGB(pixels, stride, x, y, width, height, color); -} - -static void draw_rect_ABGR( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - // Converts ARGB color to ABGR - color = ((color & 0xff00ff00) | - ((color >> 16) & 0xff) | - ((color & 0xff) << 16)); - - draw_rect_ARGB(pixels, stride, x, y, width, height, color); -} - -static void draw_rect_NV12( // Y, UV planes - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - const guchar Y = color >> 16; - const guchar Cb = color >> 8; - const guchar Cr = color; - guchar *dst; - guint i, j; - - dst = pixels[0] + y * stride[0] + x; - for (j = 0; j < height; j++, dst += stride[0]) - for (i = 0; i < width; i++) - dst[i] = Y; - - x /= 2; - y /= 2; - width /= 2; - height /= 2; - - dst = pixels[1] + y * stride[1] + x * 2; - for (j = 0; j < height; j++, dst += stride[1]) - for (i = 0; i < width; i++) { - dst[2*i + 0] = Cb; - dst[2*i + 1] = Cr; - } -} - -static void draw_rect_YV12( // Y, U, V planes - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - const guchar Y = color >> 16; - const guchar Cb = color >> 8; - const guchar Cr = color; - guchar *pY, *pU, *pV; - guint i, j; - - pY = pixels[0] + y * stride[0] + x; - for (j = 0; j < height; j++, pY += stride[0]) - for (i = 0; i < width; i++) - pY[i] = Y; - - x /= 2; - y /= 2; - width /= 2; - height /= 2; - - pU = pixels[1] + y * stride[1] + x; - pV = pixels[2] + y * stride[2] + x; - for (j = 0; j < height; j++, pU += stride[1], pV += stride[2]) - for (i = 0; i < width; i++) { - pU[i] = Cb; - pV[i] = Cr; - } -} - -static void draw_rect_AYUV( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - guint i, j; - - color = color | 0xff000000; - - for (j = 0; j < height; j++) { - guint32 *p = (guint32 *)(pixels[0] + (y + j) * stride[0] + x * 4); - for (i = 0; i < width; i++) - p[i] = color; - } -} - -static gboolean draw_rgb_rects(GstVaapiImage *image) -{ - GstVaapiImageFormat format = GST_VAAPI_IMAGE_FORMAT(image); - guint w = GST_VAAPI_IMAGE_WIDTH(image); - guint h = GST_VAAPI_IMAGE_HEIGHT(image); - guchar *pixels[3]; - guint stride[3]; - guint32 red_color, green_color, blue_color, black_color; - DrawRectFunc draw_rect; - - if (!gst_vaapi_image_map(image)) - return FALSE; - - switch (format) { - case GST_VAAPI_IMAGE_ARGB: - draw_rect = draw_rect_ARGB; - goto RGB_colors; - case GST_VAAPI_IMAGE_BGRA: - draw_rect = draw_rect_BGRA; - goto RGB_colors; - case GST_VAAPI_IMAGE_RGBA: - draw_rect = draw_rect_RGBA; - goto RGB_colors; - case GST_VAAPI_IMAGE_ABGR: - draw_rect = draw_rect_ABGR; - RGB_colors: - pixels[0] = gst_vaapi_image_get_plane(image, 0); - stride[0] = gst_vaapi_image_get_pitch(image, 0); - red_color = 0xffff0000; - green_color = 0xff00ff00; - blue_color = 0xff0000ff; - black_color = 0xff000000; - break; - case GST_VAAPI_IMAGE_NV12: - draw_rect = draw_rect_NV12; - pixels[0] = gst_vaapi_image_get_plane(image, 0); - stride[0] = gst_vaapi_image_get_pitch(image, 0); - pixels[1] = gst_vaapi_image_get_plane(image, 1); - stride[1] = gst_vaapi_image_get_pitch(image, 1); - goto YUV_colors; - case GST_VAAPI_IMAGE_YV12: - draw_rect = draw_rect_YV12; - pixels[0] = gst_vaapi_image_get_plane(image, 0); - stride[0] = gst_vaapi_image_get_pitch(image, 0); - pixels[1] = gst_vaapi_image_get_plane(image, 2); - stride[1] = gst_vaapi_image_get_pitch(image, 2); - pixels[2] = gst_vaapi_image_get_plane(image, 1); - stride[2] = gst_vaapi_image_get_pitch(image, 1); - goto YUV_colors; - case GST_VAAPI_IMAGE_I420: - draw_rect = draw_rect_YV12; - pixels[0] = gst_vaapi_image_get_plane(image, 0); - stride[0] = gst_vaapi_image_get_pitch(image, 0); - pixels[1] = gst_vaapi_image_get_plane(image, 1); - stride[1] = gst_vaapi_image_get_pitch(image, 1); - pixels[2] = gst_vaapi_image_get_plane(image, 2); - stride[2] = gst_vaapi_image_get_pitch(image, 2); - goto YUV_colors; - case GST_VAAPI_IMAGE_AYUV: - draw_rect = draw_rect_AYUV; - pixels[0] = gst_vaapi_image_get_plane(image, 0); - stride[0] = gst_vaapi_image_get_pitch(image, 0); - YUV_colors: - red_color = 0x515af0; - green_color = 0x913622; - blue_color = 0x29f06e; - black_color = 0x108080; - break; - default: - gst_vaapi_image_unmap(image); - return FALSE; - } - - draw_rect(pixels, stride, 0, 0, w/2, h/2, red_color); - draw_rect(pixels, stride, w/2, 0, w/2, h/2, green_color); - draw_rect(pixels, stride, 0, h/2, w/2, h/2, blue_color); - draw_rect(pixels, stride, w/2, h/2, w/2, h/2, black_color); - - if (!gst_vaapi_image_unmap(image)) - return FALSE; - - return TRUE; -} - static gboolean upload_image(GstVaapiSurface *surface, GstVaapiImage *image) { @@ -364,15 +110,12 @@ main(int argc, char *argv[]) for (i = 0; image_formats[i]; i++) { const GstVaapiImageFormat format = image_formats[i]; - image = gst_vaapi_image_new(display, format, width, height); - if (!image) - continue; - - if (!draw_rgb_rects(image)) - g_error("could not draw RGB rectangles"); - - if (upload_image(surface, image)) - break; + image = image_generate(display, format, width, height); + if (image) { + if (upload_image(surface, image)) + break; + g_object_unref(image); + } } if (!image) g_error("could not create Gst/VA image"); From 9981f37de7c990e752c8b9ae134d2a66bef2219f Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 15:22:00 +0000 Subject: [PATCH 0208/3781] Add gst_vaapi_object_{,un}lock_display() helpers. --- docs/reference/libs/libs-sections.txt | 2 ++ gst-libs/gst/vaapi/gstvaapiobject.c | 32 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiobject.h | 6 +++++ 3 files changed, 40 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 6de29292aa..95f822e866 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -255,6 +255,8 @@ GST_VAAPI_WINDOW_GET_CLASS GstVaapiObject GstVaapiObjectClass gst_vaapi_object_get_display +gst_vaapi_object_lock_display +gst_vaapi_object_unlock_display gst_vaapi_object_get_id GST_VAAPI_OBJECT diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 91bb17bb95..9c627b8c6c 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -210,6 +210,38 @@ gst_vaapi_object_get_display(GstVaapiObject *object) return object->priv->display; } +/** + * gst_vaapi_object_lock_display: + * @object: a #GstVaapiObject + * + * Locks @object parent display. If display is already locked by + * another thread, the current thread will block until display is + * unlocked by the other thread. + */ +void +gst_vaapi_object_lock_display(GstVaapiObject *object) +{ + g_return_if_fail(GST_VAAPI_IS_OBJECT(object)); + + GST_VAAPI_OBJECT_LOCK_DISPLAY(object); +} + +/** + * gst_vaapi_object_unlock_display: + * @object: a #GstVaapiObject + * + * Unlocks @object parent display. If another thread is blocked in a + * gst_vaapi_object_lock_display() call, it will be woken and can lock + * display itself. + */ +void +gst_vaapi_object_unlock_display(GstVaapiObject *object) +{ + g_return_if_fail(GST_VAAPI_IS_OBJECT(object)); + + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(object); +} + /** * gst_vaapi_object_get_id: * @object: a #GstVaapiObject diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index 877857fb1d..c0a024e11f 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -86,6 +86,12 @@ gst_vaapi_object_get_type(void); GstVaapiDisplay * gst_vaapi_object_get_display(GstVaapiObject *object); +void +gst_vaapi_object_lock_display(GstVaapiObject *object); + +void +gst_vaapi_object_unlock_display(GstVaapiObject *object); + GstVaapiID gst_vaapi_object_get_id(GstVaapiObject *object); From 10c454e801866feb794ca0ae778e48bd6efeed1e Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 16:52:07 +0000 Subject: [PATCH 0209/3781] Add initial VA/GLX texture abstraction though the API is not good enough yet. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapitexture.c | 468 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapitexture.h | 133 +++++++ gst-libs/gst/vaapi/gstvaapiutils_glx.c | 126 +++++++ gst-libs/gst/vaapi/gstvaapiutils_glx.h | 20 ++ 5 files changed, 749 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapitexture.c create mode 100644 gst-libs/gst/vaapi/gstvaapitexture.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 6b3990b1d6..e650c85882 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -74,6 +74,7 @@ libgstvaapi_x11_source_priv_h = \ libgstvaapi_glx_source_c = \ gstvaapidisplay_glx.c \ + gstvaapitexture.c \ gstvaapiutils.c \ gstvaapiutils_glx.c \ gstvaapiutils_x11.c \ @@ -82,6 +83,7 @@ libgstvaapi_glx_source_c = \ libgstvaapi_glx_source_h = \ gstvaapidisplay_glx.h \ + gstvaapitexture.h \ gstvaapiwindow_glx.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c new file mode 100644 index 0000000000..ff90056716 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -0,0 +1,468 @@ +/* + * gstvaapitexture.c - VA texture abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * SECTION:gstvaapitexture + * @short_description: VA/GLX texture abstraction + */ + +#include "config.h" +#include +#include "gstvaapitexture.h" +#include "gstvaapiutils.h" +#include "gstvaapiutils_glx.h" +#include "gstvaapiobject_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiTexture, gst_vaapi_texture, GST_VAAPI_TYPE_OBJECT); + +#define GST_VAAPI_TEXTURE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_TEXTURE, \ + GstVaapiTexturePrivate)) + +struct _GstVaapiTexturePrivate { + GLenum target; + GLenum format; + guint width; + guint height; + void *gl_surface; + guint foreign_texture : 1; + guint is_constructed : 1; +}; + +enum { + PROP_0, + + PROP_TARGET, + PROP_FORMAT, + PROP_WIDTH, + PROP_HEIGHT +}; + +static void +gst_vaapi_texture_destroy(GstVaapiTexture *texture) +{ + GstVaapiTexturePrivate * const priv = texture->priv; + const GLuint texture_id = GST_VAAPI_OBJECT_ID(texture); + VAStatus status; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + if (priv->gl_surface) { + status = vaDestroySurfaceGLX( + GST_VAAPI_OBJECT_VADISPLAY(texture), + priv->gl_surface + ); + priv->gl_surface = NULL; + } + + if (texture) { + if (!priv->foreign_texture) + glDeleteTextures(1, &texture_id); + GST_VAAPI_OBJECT_ID(texture) = 0; + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); +} + +static gboolean +gst_vaapi_texture_create(GstVaapiTexture *texture) +{ + GstVaapiTexturePrivate * const priv = texture->priv; + GLuint texture_id; + VAStatus status; + + if (priv->foreign_texture) + texture_id = GST_VAAPI_OBJECT_ID(texture); + else { + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + texture_id = gl_create_texture( + priv->target, + priv->format, + priv->width, + priv->height + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!texture_id) + return FALSE; + GST_VAAPI_OBJECT_ID(texture) = texture_id; + } + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + status = vaCreateSurfaceGLX( + GST_VAAPI_OBJECT_VADISPLAY(texture), + priv->target, + texture_id, + &priv->gl_surface + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!vaapi_check_status(status, "vaCreateSurfaceGLX()")) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_texture_finalize(GObject *object) +{ + gst_vaapi_texture_destroy(GST_VAAPI_TEXTURE(object)); + + G_OBJECT_CLASS(gst_vaapi_texture_parent_class)->finalize(object); +} + +static void +gst_vaapi_texture_constructed(GObject *object) +{ + GstVaapiTexture * const texture = GST_VAAPI_TEXTURE(object); + GObjectClass *parent_class; + + texture->priv->foreign_texture = GST_VAAPI_OBJECT_ID(texture) != 0; + texture->priv->is_constructed = gst_vaapi_texture_create(texture); + + parent_class = G_OBJECT_CLASS(gst_vaapi_texture_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + +static void +gst_vaapi_texture_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiTexture * const texture = GST_VAAPI_TEXTURE(object); + + switch (prop_id) { + case PROP_TARGET: + texture->priv->target = g_value_get_uint(value); + break; + case PROP_FORMAT: + texture->priv->format = g_value_get_uint(value); + break; + case PROP_WIDTH: + texture->priv->width = g_value_get_uint(value); + break; + case PROP_HEIGHT: + texture->priv->height = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_texture_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiTexture * const texture = GST_VAAPI_TEXTURE(object); + + switch (prop_id) { + case PROP_TARGET: + g_value_set_uint(value, gst_vaapi_texture_get_target(texture)); + break; + case PROP_FORMAT: + g_value_set_uint(value, gst_vaapi_texture_get_format(texture)); + break; + case PROP_WIDTH: + g_value_set_uint(value, gst_vaapi_texture_get_width(texture)); + break; + case PROP_HEIGHT: + g_value_set_uint(value, gst_vaapi_texture_get_height(texture)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_texture_class_init(GstVaapiTextureClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiTexturePrivate)); + + object_class->finalize = gst_vaapi_texture_finalize; + object_class->set_property = gst_vaapi_texture_set_property; + object_class->get_property = gst_vaapi_texture_get_property; + object_class->constructed = gst_vaapi_texture_constructed; + + g_object_class_install_property + (object_class, + PROP_TARGET, + g_param_spec_uint("target", + "Target", + "The texture target", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_FORMAT, + g_param_spec_uint("format", + "Format", + "The texture format", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_uint("width", + "width", + "The texture width", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_uint("height", + "height", + "The texture height", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_texture_init(GstVaapiTexture *texture) +{ + GstVaapiTexturePrivate *priv = GST_VAAPI_TEXTURE_GET_PRIVATE(texture); + + texture->priv = priv; + priv->target = GL_NONE; + priv->format = GL_NONE; + priv->width = 0; + priv->height = 0; + priv->gl_surface = NULL; + priv->foreign_texture = FALSE; + priv->is_constructed = FALSE; +} + +GstVaapiTexture * +gst_vaapi_texture_new( + GstVaapiDisplay *display, + GLenum target, + GLenum format, + guint width, + guint height +) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + return g_object_new(GST_VAAPI_TYPE_TEXTURE, + "display", display, + "id", GST_VAAPI_ID(0), + "target", target, + "format", format, + "width", width, + "height", height, + NULL); +} + +GstVaapiTexture * +gst_vaapi_texture_new_with_texture( + GstVaapiDisplay *display, + GLuint texture, + GLenum target, + GLenum format +) +{ + guint width, height, border_width; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + /* Check texture dimensions */ + if (!gl_get_texture_param(GL_TEXTURE_WIDTH, &width)) + return NULL; + if (!gl_get_texture_param(GL_TEXTURE_HEIGHT, &height)) + return NULL; + if (!gl_get_texture_param(GL_TEXTURE_BORDER, &border_width)) + return NULL; + + width -= 2 * border_width; + height -= 2 * border_width; + if (width == 0 || height == 0) + return NULL; + + return g_object_new(GST_VAAPI_TYPE_TEXTURE, + "display", display, + "id", GST_VAAPI_ID(texture), + "target", target, + "format", format, + "width", width, + "height", height, + NULL); +} + +/** + * gst_vaapi_texture_get_id: + * @texture: a #GstVaapiTexture + * + * Returns the underlying texture id of the @texture. + * + * Return value: the underlying texture id of the @texture + */ +GLuint +gst_vaapi_texture_get_id(GstVaapiTexture *texture) +{ + g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), 0); + + return GST_VAAPI_OBJECT_ID(texture); +} + +/** + * gst_vaapi_texture_get_target: + * @texture: a #GstVaapiTexture + * + * Returns the @texture target type + * + * Return value: the texture target + */ +GLenum +gst_vaapi_texture_get_target(GstVaapiTexture *texture) +{ + g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), GL_NONE); + g_return_val_if_fail(texture->priv->is_constructed, GL_NONE); + + return texture->priv->target; +} + +/** + * gst_vaapi_texture_get_format + * @texture: a #GstVaapiTexture + * + * Returns the @texture format + * + * Return value: the texture format + */ +GLenum +gst_vaapi_texture_get_format(GstVaapiTexture *texture) +{ + g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), GL_NONE); + g_return_val_if_fail(texture->priv->is_constructed, GL_NONE); + + return texture->priv->format; +} + +/** + * gst_vaapi_texture_get_width: + * @texture: a #GstVaapiTexture + * + * Returns the @texture width. + * + * Return value: the texture width, in pixels + */ +guint +gst_vaapi_texture_get_width(GstVaapiTexture *texture) +{ + g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), 0); + g_return_val_if_fail(texture->priv->is_constructed, 0); + + return texture->priv->width; +} + +/** + * gst_vaapi_texture_get_height: + * @texture: a #GstVaapiTexture + * + * Returns the @texture height. + * + * Return value: the texture height, in pixels. + */ +guint +gst_vaapi_texture_get_height(GstVaapiTexture *texture) +{ + g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), 0); + g_return_val_if_fail(texture->priv->is_constructed, 0); + + return texture->priv->height; +} + +/** + * gst_vaapi_texture_get_size: + * @texture: a #GstVaapiTexture + * @pwidth: return location for the width, or %NULL + * @pheight: return location for the height, or %NULL + * + * Retrieves the dimensions of a #GstVaapiTexture. + */ +void +gst_vaapi_texture_get_size( + GstVaapiTexture *texture, + guint *pwidth, + guint *pheight +) +{ + g_return_if_fail(GST_VAAPI_IS_TEXTURE(texture)); + g_return_if_fail(texture->priv->is_constructed); + + if (pwidth) + *pwidth = texture->priv->width; + + if (pheight) + *pheight = texture->priv->height; +} + +/** + * gst_vaapi_window_put_texture: + * @texture: a #GstVaapiTexture + * @surface: a #GstVaapiSurface + * @flags: postprocessing flags. See #GstVaapiTextureRenderFlags + * + * Renders the @surface into the àtexture. The @flags specify how + * de-interlacing (if needed), color space conversion, scaling and + * other postprocessing transformations are performed. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_texture_put_surface( + GstVaapiTexture *texture, + GstVaapiSurface *surface, + guint flags +) +{ + VAStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), FALSE); + g_return_val_if_fail(texture->priv->is_constructed, FALSE); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + status = vaCopySurfaceGLX( + GST_VAAPI_OBJECT_VADISPLAY(texture), + texture->priv->gl_surface, + GST_VAAPI_OBJECT_ID(surface), + get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(flags) + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + + if (!vaapi_check_status(status, "vaCopySurfaceGLX()")) + return FALSE; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h new file mode 100644 index 0000000000..5620cceccd --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -0,0 +1,133 @@ +/* + * gstvaapitexture.h - VA texture abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_TEXTURE_H +#define GST_VAAPI_TEXTURE_H + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_TEXTURE \ + (gst_vaapi_texture_get_type()) + +#define GST_VAAPI_TEXTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_TEXTURE, \ + GstVaapiTexture)) + +#define GST_VAAPI_TEXTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_TEXTURE, \ + GstVaapiTextureClass)) + +#define GST_VAAPI_IS_TEXTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_TEXTURE)) + +#define GST_VAAPI_IS_TEXTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_TEXTURE)) + +#define GST_VAAPI_TEXTURE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_TEXTURE, \ + GstVaapiTextureClass)) + +typedef struct _GstVaapiTexture GstVaapiTexture; +typedef struct _GstVaapiTexturePrivate GstVaapiTexturePrivate; +typedef struct _GstVaapiTextureClass GstVaapiTextureClass; + +/** + * GstVaapiTexture: + * + * Base class for system-dependent textures. + */ +struct _GstVaapiTexture { + /*< private >*/ + GstVaapiObject parent_instance; + + GstVaapiTexturePrivate *priv; +}; + +/** + * GstVaapiTextureClass: + * + * Base class for system-dependent textures. + */ +struct _GstVaapiTextureClass { + /*< private >*/ + GstVaapiObjectClass parent_class; +}; + +GType +gst_vaapi_texture_get_type(void); + +GstVaapiTexture * +gst_vaapi_texture_new( + GstVaapiDisplay *display, + GLenum target, + GLenum format, + guint width, + guint height +); + +GstVaapiTexture * +gst_vaapi_texture_new_with_texture( + GstVaapiDisplay *display, + GLuint texture, + GLenum target, + GLenum format +); + +GLuint +gst_vaapi_texture_get_id(GstVaapiTexture *texture); + +GLenum +gst_vaapi_texture_get_target(GstVaapiTexture *texture); + +GLenum +gst_vaapi_texture_get_format(GstVaapiTexture *texture); + +guint +gst_vaapi_texture_get_width(GstVaapiTexture *texture); + +guint +gst_vaapi_texture_get_height(GstVaapiTexture *texture); + +void +gst_vaapi_texture_get_size( + GstVaapiTexture *texture, + guint *pwidth, + guint *pheight +); + +gboolean +gst_vaapi_texture_put_surface( + GstVaapiTexture *texture, + GstVaapiSurface *surface, + guint flags +); + +G_END_DECLS + +#endif /* GST_VAAPI_TEXTURE_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 61721fb912..9669ab2992 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -209,3 +209,129 @@ gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state) } return glXMakeCurrent(dpy, win, ctx); } + +/** + * gl_bind_texture: + * @ts: a #GLTextureState + * @target: the target to which the texture is bound + * @texture: the name of a texture + * + * Binds @texture to the specified @target, while recording the + * previous state in @ts. + * + * Return value: %TRUE on success + */ +gboolean +gl_bind_texture(GLTextureState *ts, GLenum target, GLuint texture) +{ + ts->target = target; + ts->old_texture = 0; + ts->was_bound = 0; + ts->was_enabled = glIsEnabled(target); + if (!ts->was_enabled) + glEnable(target); + + GLenum texture_binding; + switch (target) { + case GL_TEXTURE_1D: + texture_binding = GL_TEXTURE_BINDING_1D; + break; + case GL_TEXTURE_2D: + texture_binding = GL_TEXTURE_BINDING_2D; + break; + case GL_TEXTURE_3D: + texture_binding = GL_TEXTURE_BINDING_3D; + break; + case GL_TEXTURE_RECTANGLE_ARB: + texture_binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; + break; + default: + g_assert(!texture); + return FALSE; + } + + if (ts->was_enabled && gl_get_param(texture_binding, &ts->old_texture) < 0) + return FALSE; + + ts->was_bound = texture == ts->old_texture; + if (!ts->was_bound) { + gl_purge_errors(); + glBindTexture(target, texture); + if (gl_check_error()) + return FALSE; + } + return TRUE; +} + +/** + * gl_unbind_texture: + * @ts: a #GLTextureState + * + * Rebinds the texture that was previously bound and recorded in @ts. + */ +void +gl_unbind_texture(GLTextureState *ts) +{ + if (!ts->was_bound && ts->old_texture) + glBindTexture(ts->target, ts->old_texture); + if (!ts->was_enabled) + glDisable(ts->target); +} + +/** + * gl_create_texture: + * @target: the target to which the texture is bound + * @format: the format of the pixel data + * @width: the requested width, in pixels + * @height: the requested height, in pixels + * + * Creates a texture with the specified dimensions and @format. The + * internal format will be automatically derived from @format. + * + * Return value: the newly created texture name + */ +GLuint +gl_create_texture(GLenum target, GLenum format, guint width, guint height) +{ + GLuint texture; + GLTextureState ts; + guint bytes_per_component; + + switch (format) { + case GL_LUMINANCE: + bytes_per_component = 1; + break; + case GL_LUMINANCE_ALPHA: + bytes_per_component = 2; + break; + case GL_RGBA: + case GL_BGRA: + bytes_per_component = 4; + break; + default: + bytes_per_component = 0; + break; + } + g_assert(bytes_per_component > 0); + + glGenTextures(1, &texture); + if (!gl_bind_texture(&ts, target, texture)) + return 0; + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glPixelStorei(GL_UNPACK_ALIGNMENT, bytes_per_component); + glTexImage2D( + target, + 0, + bytes_per_component, + width, height, + 0, + format, + GL_UNSIGNED_BYTE, + NULL + ); + gl_unbind_texture(&ts); + return texture; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 7251e22682..ca88b60e93 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -64,4 +64,24 @@ gboolean gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state) attribute_hidden; +typedef struct _GLTextureState GLTextureState; +struct _GLTextureState { + gboolean was_enabled; + gboolean was_bound; + GLenum target; + GLuint old_texture; +}; + +gboolean +gl_bind_texture(GLTextureState *ts, GLenum target, GLuint texture) + attribute_hidden; + +void +gl_unbind_texture(GLTextureState *ts) + attribute_hidden; + +GLuint +gl_create_texture(GLenum target, GLenum format, guint width, guint height) + attribute_hidden; + #endif /* GST_VAAPI_UTILS_GLX_H */ From 9b66ed12339ac8b47f7e936cad2a997367c3d309 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 26 Mar 2010 17:00:45 +0000 Subject: [PATCH 0210/3781] Move code around. --- tests/image.c | 39 +++++++++++++++++++++++++++++++++++++++ tests/image.h | 4 ++++ tests/test-windows.c | 41 +---------------------------------------- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/tests/image.c b/tests/image.c index 478ed77c39..be628c3d05 100644 --- a/tests/image.c +++ b/tests/image.c @@ -318,3 +318,42 @@ image_draw_rectangle( gst_vaapi_display_unlock(display); return gst_vaapi_image_unmap(image); } + +gboolean +image_upload(GstVaapiImage *image, GstVaapiSurface *surface) +{ + GstVaapiDisplay *display; + GstVaapiImageFormat format; + GstVaapiSubpicture *subpicture; + + display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); + if (!display) + return FALSE; + + format = gst_vaapi_image_get_format(image); + if (!format) + return FALSE; + + if (gst_vaapi_surface_put_image(surface, image)) + return TRUE; + + g_print("could not upload %" GST_FOURCC_FORMAT" image to surface\n", + GST_FOURCC_ARGS(format)); + + if (!gst_vaapi_display_has_subpicture_format(display, format)) + return FALSE; + + g_print("trying as a subpicture\n"); + + subpicture = gst_vaapi_subpicture_new(image); + if (!subpicture) + g_error("could not create VA subpicture"); + + if (!gst_vaapi_surface_associate_subpicture(surface, subpicture, + NULL, NULL)) + g_error("could not associate subpicture to surface"); + + /* The surface holds a reference to the subpicture. This is safe */ + g_object_unref(subpicture); + return TRUE; +} diff --git a/tests/image.h b/tests/image.h index eb914de873..c0558a681d 100644 --- a/tests/image.h +++ b/tests/image.h @@ -22,6 +22,7 @@ #define IMAGE_H #include +#include GstVaapiImage * image_generate( @@ -41,4 +42,7 @@ image_draw_rectangle( guint32 color ); +gboolean +image_upload(GstVaapiImage *image, GstVaapiSurface *surface); + #endif /* IMAGE_H */ diff --git a/tests/test-windows.c b/tests/test-windows.c index 7292bbaeab..d381191035 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -30,45 +30,6 @@ static inline void pause(void) getchar(); } -static gboolean -upload_image(GstVaapiSurface *surface, GstVaapiImage *image) -{ - GstVaapiDisplay *display; - GstVaapiImageFormat format; - GstVaapiSubpicture *subpicture; - - display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); - if (!display) - return FALSE; - - format = gst_vaapi_image_get_format(image); - if (!format) - return FALSE; - - if (gst_vaapi_surface_put_image(surface, image)) - return TRUE; - - g_print("could not upload %" GST_FOURCC_FORMAT" image to surface\n", - GST_FOURCC_ARGS(format)); - - if (!gst_vaapi_display_has_subpicture_format(display, format)) - return FALSE; - - g_print("trying as a subpicture\n"); - - subpicture = gst_vaapi_subpicture_new(image); - if (!subpicture) - g_error("could not create Gst/VA subpicture"); - - if (!gst_vaapi_surface_associate_subpicture(surface, subpicture, - NULL, NULL)) - g_error("could not associate subpicture to surface"); - - /* The surface holds a reference to the subpicture. This is safe */ - g_object_unref(subpicture); - return TRUE; -} - int main(int argc, char *argv[]) { @@ -112,7 +73,7 @@ main(int argc, char *argv[]) image = image_generate(display, format, width, height); if (image) { - if (upload_image(surface, image)) + if (image_upload(image, surface)) break; g_object_unref(image); } From 504dc9bf98a68080946886ca056f7e31af2bec3c Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 09:09:30 +0000 Subject: [PATCH 0211/3781] Fix typos. --- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index b516a29bd1..0f350cb335 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -457,7 +457,7 @@ gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid) /** * gst_vaapi_window_glx_get_context: - * @window: a #GstVaapiWindow + * @window: a #GstVaapiWindowGLX * * Returns the #GLXContext bound to the @window. * @@ -474,7 +474,7 @@ gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window) /** * gst_vaapi_window_glx_set_context: - * @window: a #GstVaapiWindow + * @window: a #GstVaapiWindowGLX * @ctx: a GLX context * * Binds GLX context @ctx to @window. If @ctx is non %NULL, the caller From dd921950930c06cf6a7c61a8676d102f3123fd00 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 10:40:26 +0000 Subject: [PATCH 0212/3781] Add gst_vaapi_window_glx_put_texture() helper. --- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 103 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 9 +++ 2 files changed, 112 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 0f350cb335..025bfbda1e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -61,6 +61,35 @@ enum { static XVisualInfo * gst_vaapi_window_glx_create_visual(GstVaapiWindowGLX *window); +/* Fill rectangle coords with capped bounds */ +static inline void +fill_rect( + GstVaapiRectangle *dst_rect, + const GstVaapiRectangle *src_rect, + guint width, + guint height +) +{ + if (src_rect) { + dst_rect->x = src_rect->x > 0 ? src_rect->x : 0; + dst_rect->y = src_rect->y > 0 ? src_rect->y : 0; + if (src_rect->x + src_rect->width < width) + dst_rect->width = src_rect->width; + else + dst_rect->width = width - dst_rect->x; + if (src_rect->y + src_rect->height < height) + dst_rect->height = src_rect->height; + else + dst_rect->height = height - dst_rect->y; + } + else { + dst_rect->x = 0; + dst_rect->y = 0; + dst_rect->width = width; + dst_rect->height = height; + } +} + static inline void _gst_vaapi_window_glx_set_context( GstVaapiWindowGLX *window, @@ -550,3 +579,77 @@ gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window) glClear(GL_COLOR_BUFFER_BIT); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); } + +/** + * gst_vaapi_window_glx_put_texture: + * @window: a #GstVaapiWindowGLX + * @texture: a #GstVaapiTexture + * @src_rect: the sub-rectangle of the source texture to + * extract and process. If %NULL, the entire texture will be used. + * @dst_rect: the sub-rectangle of the destination + * window into which the texture is rendered. If %NULL, the entire + * window will be used. + * + * Renders the @texture region specified by @src_rect into the @window + * region specified by @dst_rect. + * + * NOTE: only GL_TEXTURE_2D textures are supported at this time. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_window_glx_put_texture( + GstVaapiWindowGLX *window, + GstVaapiTexture *texture, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect +) +{ + GstVaapiRectangle tmp_src_rect, tmp_dst_rect; + GLTextureState ts; + GLenum tex_target; + GLuint tex_id; + guint tex_width, tex_height; + guint win_width, win_height; + + g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), FALSE); + + gst_vaapi_texture_get_size(texture, &tex_width, &tex_height); + fill_rect(&tmp_src_rect, src_rect, tex_width, tex_height); + src_rect = &tmp_src_rect; + + gst_vaapi_window_get_size(GST_VAAPI_WINDOW(window), &win_width, &win_height); + fill_rect(&tmp_dst_rect, dst_rect, win_width, win_height); + dst_rect = &tmp_dst_rect; + + tex_target = gst_vaapi_texture_get_target(texture); + tex_id = gst_vaapi_texture_get_id(texture); + + /* XXX: only GL_TEXTURE_2D textures are supported at this time */ + if (tex_target != GL_TEXTURE_2D) + return FALSE; + + if (!gl_bind_texture(&ts, tex_target, tex_id)) + return FALSE; + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glPushMatrix(); + glTranslatef((GLfloat)dst_rect->x, (GLfloat)dst_rect->y, 0.0f); + glBegin(GL_QUADS); + { + const float tx1 = (float)src_rect->x / tex_width; + const float tx2 = (float)(src_rect->x + src_rect->width) / tex_width; + const float ty1 = (float)src_rect->y / tex_height; + const float ty2 = (float)(src_rect->y + src_rect->height) / tex_height; + const guint w = dst_rect->width; + const guint h = dst_rect->height; + glTexCoord2f(tx1, ty1); glVertex2i(0, 0); + glTexCoord2f(tx1, ty2); glVertex2i(0, h); + glTexCoord2f(tx2, ty2); glVertex2i(w, h); + glTexCoord2f(tx2, ty1); glVertex2i(w, 0); + } + glEnd(); + glPopMatrix(); + gl_unbind_texture(&ts); + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index d336d8953b..2090640fbd 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -24,6 +24,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -98,6 +99,14 @@ gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window); void gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window); +gboolean +gst_vaapi_window_glx_put_texture( + GstVaapiWindowGLX *window, + GstVaapiTexture *texture, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect +); + G_END_DECLS #endif /* GST_VAAPI_WINDOW_GLX_H */ From ab8b90aa5906ac1f359738d6b4240b6f4deb4317 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 11:25:20 +0000 Subject: [PATCH 0213/3781] Fix documentation. --- docs/reference/libs/libs-docs.xml.in | 1 + docs/reference/libs/libs-sections.txt | 26 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapitexture.c | 40 ++++++++++++++++++++++++++- 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 29ef9b990b..53e6741f28 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -22,6 +22,7 @@ + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 95f822e866..b6eacd54f1 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -111,7 +111,9 @@ gst_vaapi_window_glx_new gst_vaapi_window_glx_new_with_xid gst_vaapi_window_glx_get_context gst_vaapi_window_glx_set_context +gst_vaapi_window_glx_make_current gst_vaapi_window_glx_swap_buffers +gst_vaapi_window_glx_put_texture GST_VAAPI_WINDOW_GLX GST_VAAPI_IS_WINDOW_GLX @@ -364,3 +366,27 @@ gst_vaapi_image_format_get_va_format gst_vaapi_image_format_get_caps gst_vaapi_image_format_get_score
+ +
+gstvaapitexture +GstVaapiTexture +GstVaapiTexture +GstVaapiTextureClass +gst_vaapi_texture_new +gst_vaapi_texture_new_with_texture +gst_vaapi_texture_get_id +gst_vaapi_texture_get_target +gst_vaapi_texture_get_format +gst_vaapi_texture_get_width +gst_vaapi_texture_get_height +gst_vaapi_texture_get_size +gst_vaapi_texture_put_surface + +GST_VAAPI_TEXTURE +GST_VAAPI_IS_TEXTURE +GST_VAAPI_TYPE_TEXTURE +gst_vaapi_texture_get_type +GST_VAAPI_TEXTURE_CLASS +GST_VAAPI_IS_TEXTURE_CLASS +GST_VAAPI_TEXTURE_GET_CLASS +
diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index f015620c22..ff10126e8e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -595,7 +595,7 @@ gst_vaapi_display_sync(GstVaapiDisplay *display) } /** - * gst_vaapi_display_sync: + * gst_vaapi_display_flush: * @display: a #GstVaapiDisplay * * Flushes any requests queued for the windowing system. diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index ff90056716..3d69da25d7 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -263,6 +263,25 @@ gst_vaapi_texture_init(GstVaapiTexture *texture) priv->is_constructed = FALSE; } +/** + * gst_vaapi_texture_new: + * @display: a #GstVaapiDisplay + * @target: the target to which the texture is bound + * @format: the format of the pixel data + * @width: the requested width, in pixels + * @height: the requested height, in pixels + * + * Creates a texture with the specified dimensions, @target and + * @format. Note that only GL_TEXTURE_2D @target and GL_RGBA or + * GL_BGRA formats are supported at this time. + * + * The application shall maintain the live GL context itself. That is, + * gst_vaapi_window_glx_make_current() must be called beforehand, or + * any other function like glXMakeCurrent() if the context is managed + * outside of this library. + * + * Return value: the newly created #GstVaapiTexture object + */ GstVaapiTexture * gst_vaapi_texture_new( GstVaapiDisplay *display, @@ -284,6 +303,25 @@ gst_vaapi_texture_new( NULL); } +/** + * gst_vaapi_texture_new_with_texture: + * @display: a #GstVaapiDisplay + * @texture: the foreign GL texture name to use + * @target: the target to which the texture is bound + * @format: the format of the pixel data + * + * Creates a texture from an existing GL texture, with the specified + * @target and @format. Note that only GL_TEXTURE_2D @target and + * GL_RGBA or GL_BGRA formats are supported at this time. The + * dimensions will be retrieved from the @texture. + * + * The application shall maintain the live GL context itself. That is, + * gst_vaapi_window_glx_make_current() must be called beforehand, or + * any other function like glXMakeCurrent() if the context is managed + * outside of this library. + * + * Return value: the newly created #GstVaapiTexture object + */ GstVaapiTexture * gst_vaapi_texture_new_with_texture( GstVaapiDisplay *display, @@ -429,7 +467,7 @@ gst_vaapi_texture_get_size( } /** - * gst_vaapi_window_put_texture: + * gst_vaapi_texture_put_surface: * @texture: a #GstVaapiTexture * @surface: a #GstVaapiSurface * @flags: postprocessing flags. See #GstVaapiTextureRenderFlags From 92553103119115bc5b78cea1f3a571dc5e3fbd44 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 12:51:38 +0000 Subject: [PATCH 0214/3781] Fix texture rendering. --- gst-libs/gst/vaapi/gstvaapitexture.c | 20 ++++++++++++++------ gst-libs/gst/vaapi/gstvaapiutils_glx.c | 9 +++++---- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 3d69da25d7..3932fbed93 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -75,7 +75,7 @@ gst_vaapi_texture_destroy(GstVaapiTexture *texture) priv->gl_surface = NULL; } - if (texture) { + if (texture_id) { if (!priv->foreign_texture) glDeleteTextures(1, &texture_id); GST_VAAPI_OBJECT_ID(texture) = 0; @@ -331,15 +331,23 @@ gst_vaapi_texture_new_with_texture( ) { guint width, height, border_width; + GLTextureState ts; + gboolean success; g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); /* Check texture dimensions */ - if (!gl_get_texture_param(GL_TEXTURE_WIDTH, &width)) - return NULL; - if (!gl_get_texture_param(GL_TEXTURE_HEIGHT, &height)) - return NULL; - if (!gl_get_texture_param(GL_TEXTURE_BORDER, &border_width)) + GST_VAAPI_DISPLAY_LOCK(display); + success = gl_bind_texture(&ts, target, texture); + if (success) { + if (!gl_get_texture_param(target, GL_TEXTURE_WIDTH, &width) || + !gl_get_texture_param(target, GL_TEXTURE_HEIGHT, &height) || + !gl_get_texture_param(target, GL_TEXTURE_BORDER, &border_width)) + success = FALSE; + gl_unbind_texture(&ts); + } + GST_VAAPI_DISPLAY_UNLOCK(display); + if (!success) return NULL; width -= 2 * border_width; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 9669ab2992..de6ea3f6be 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -120,7 +120,8 @@ gl_get_param(GLenum param, guint *pval) } /** - * gl_get_param: + * gl_get_texture_param: + * @target: the target to which the texture is bound * @param: the parameter name * @pval: return location for the value * @@ -130,12 +131,12 @@ gl_get_param(GLenum param, guint *pval) * Return value: %TRUE on success */ gboolean -gl_get_texture_param(GLenum param, guint *pval) +gl_get_texture_param(GLenum target, GLenum param, guint *pval) { GLint val; gl_purge_errors(); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, param, &val); + glGetTexLevelParameteriv(target, 0, param, &val); if (gl_check_error()) return FALSE; @@ -250,7 +251,7 @@ gl_bind_texture(GLTextureState *ts, GLenum target, GLuint texture) return FALSE; } - if (ts->was_enabled && gl_get_param(texture_binding, &ts->old_texture) < 0) + if (ts->was_enabled && !gl_get_param(texture_binding, &ts->old_texture)) return FALSE; ts->was_bound = texture == ts->old_texture; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index ca88b60e93..1902daa411 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -43,7 +43,7 @@ gl_get_param(GLenum param, guint *pval) attribute_hidden; gboolean -gl_get_texture_param(GLenum param, guint *pval) +gl_get_texture_param(GLenum target, GLenum param, guint *pval) attribute_hidden; void From ee230e6a1d86725774abddcd341e0cc622d1a1ae Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 13:27:16 +0000 Subject: [PATCH 0215/3781] Improve VA/GLX textures test. --- tests/Makefile.am | 2 +- tests/test-textures.c | 139 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 130 insertions(+), 11 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 85e326c0c5..2055ef1026 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -46,7 +46,7 @@ test_windows_SOURCES = test-windows.c image.c test_windows_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) test_windows_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) -test_textures_SOURCES = test-textures.c +test_textures_SOURCES = test-textures.c image.c test_textures_CFLAGS = $(TEST_CFLAGS) $(TEST_GLX_CFLAGS) test_textures_LDADD = $(TEST_LIBS) $(TEST_GLX_LIBS) diff --git a/tests/test-textures.c b/tests/test-textures.c index 348b7f263a..2d7f1addab 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -20,6 +20,10 @@ #include #include +#include +#include +#include +#include "image.h" static inline void pause(void) { @@ -27,15 +31,27 @@ static inline void pause(void) getchar(); } +static inline guint gl_get_current_texture_2d(void) +{ + GLint texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture); + return (guint)texture; +} + int main(int argc, char *argv[]) { GstVaapiDisplay *display; GstVaapiWindow *window; GstVaapiWindowGLX *glx_window; - GLXContext glx_context; - Display *x11_display; - Window x11_window; + GstVaapiSurface *surface; + GstVaapiImage *image; + GstVaapiTexture *textures[2]; + GstVaapiTexture *texture; + GLuint texture_id; + GstVaapiRectangle src_rect; + GstVaapiRectangle dst_rect; + guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; static const guint width = 320; @@ -47,24 +63,127 @@ main(int argc, char *argv[]) display = gst_vaapi_display_glx_new(NULL); if (!display) - g_error("could not create Gst/VA display"); + g_error("could not create VA display"); + + surface = gst_vaapi_surface_new(display, chroma_type, width, height); + if (!surface) + g_error("could not create VA surface"); + + image = image_generate(display, GST_VAAPI_IMAGE_NV12, width, height); + if (!image) + g_error("could not create VA image"); + if (!image_upload(image, surface)) + g_error("could not upload VA image to surface"); window = gst_vaapi_window_glx_new(display, win_width, win_height); if (!window) g_error("could not create window"); + glx_window = GST_VAAPI_WINDOW_GLX(window); gst_vaapi_window_show(window); - glx_window = GST_VAAPI_WINDOW_GLX(window); - glx_context = gst_vaapi_window_glx_get_context(glx_window); - x11_display = gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)); - x11_window = gst_vaapi_object_get_id(GST_VAAPI_OBJECT(window)); + if (!gst_vaapi_window_glx_make_current(glx_window)) + g_error("coult not bind GL context"); - if (!glXMakeCurrent(x11_display, x11_window, glx_context)) - g_error("could not make VA/GLX window context current"); + g_print("#\n"); + g_print("# Create texture with gst_vaapi_texture_new()\n"); + g_print("#\n"); + { + texture = gst_vaapi_texture_new( + display, + GL_TEXTURE_2D, + GL_RGBA, + width, + height + ); + if (!texture) + g_error("could not create VA texture"); + textures[0] = texture; + texture_id = gst_vaapi_texture_get_id(texture); + + if (!gst_vaapi_texture_put_surface(texture, surface, flags)) + g_error("could not transfer VA surface to texture"); + + if (!gst_vaapi_window_glx_put_texture(glx_window, texture, NULL, NULL)) + g_error("could not render texture into the window"); + } + + g_print("#\n"); + g_print("# Create texture with gst_vaapi_texture_new_with_texture()\n"); + g_print("#\n"); + { + const GLenum target = GL_TEXTURE_2D; + const GLenum format = GL_BGRA; + + glEnable(target); + glGenTextures(1, &texture_id); + glBindTexture(target, texture_id); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glTexImage2D( + target, + 0, + GL_RGBA8, + width, height, + 0, + format, + GL_UNSIGNED_BYTE, + NULL + ); + glDisable(target); + + texture = gst_vaapi_texture_new_with_texture( + display, + texture_id, + target, + format + ); + if (!texture) + g_error("could not create VA texture"); + + if (texture_id != gst_vaapi_texture_get_id(texture)) + g_error("invalid texture id"); + + if (gl_get_current_texture_2d() != texture_id) + g_error("gst_vaapi_texture_new_with_texture() altered texture bindings"); + + textures[1] = texture; + + if (!gst_vaapi_texture_put_surface(texture, surface, flags)) + g_error("could not transfer VA surface to texture"); + + if (gl_get_current_texture_2d() != texture_id) + g_error("gst_vaapi_texture_put_surface() altered texture bindings"); + + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = width; + src_rect.height = height; + + dst_rect.x = win_width/2; + dst_rect.y = win_height/2; + dst_rect.width = win_width/2; + dst_rect.height = win_height/2; + + if (!gst_vaapi_window_glx_put_texture(glx_window, texture, + &src_rect, &dst_rect)) + g_error("could not render texture into the window"); + + if (gl_get_current_texture_2d() != texture_id) + g_error("gst_vaapi_window_glx_put_texture() altered texture bindings"); + } + + gst_vaapi_window_glx_swap_buffers(glx_window); pause(); + g_object_unref(textures[0]); + g_object_unref(textures[1]); + glDeleteTextures(1, &texture_id); + g_object_unref(window); g_object_unref(display); gst_deinit(); From 1165419fd064d289607234d43a7958eed08a5af1 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 13:40:27 +0000 Subject: [PATCH 0216/3781] Add glXSwapBuffers() workaround for NVIDIA. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 15 +++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_glx.h | 4 ++++ gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 13 +++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index de6ea3f6be..b7ba744d99 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -211,6 +211,21 @@ gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state) return glXMakeCurrent(dpy, win, ctx); } +/** + * gl_swap_buffers: + * @dpy: an X11 #Display + * @win: an X11 #Window + * + * Promotes the contents of the back buffer of the @win window to + * become the contents of the front buffer. This simply is wrapper + * around glXSwapBuffers(). + */ +void +gl_swap_buffers(Display *dpy, Window win) +{ + glXSwapBuffers(dpy, win); +} + /** * gl_bind_texture: * @ts: a #GLTextureState diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 1902daa411..69d0048c37 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -64,6 +64,10 @@ gboolean gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state) attribute_hidden; +void +gl_swap_buffers(Display *dpy, Window win) + attribute_hidden; + typedef struct _GLTextureState GLTextureState; struct _GLTextureState { gboolean was_enabled; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 025bfbda1e..a1f9dc6c8b 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -50,6 +50,7 @@ struct _GstVaapiWindowGLXPrivate { guint is_constructed : 1; guint foreign_context : 1; guint foreign_window : 1; + guint swapped_buffers : 1; }; enum { @@ -112,8 +113,13 @@ gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window) if (priv->context) { if (!priv->foreign_context) { GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - if (glXGetCurrentContext() == priv->context) + if (glXGetCurrentContext() == priv->context) { + /* XXX: if buffers were never swapped, the application + will crash later with the NVIDIA driver */ + if (!priv->swapped_buffers) + gl_swap_buffers(dpy, GST_VAAPI_OBJECT_ID(window)); gl_make_current(dpy, None, NULL, NULL); + } glXDestroyContext(dpy, priv->context); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); } @@ -429,6 +435,7 @@ gst_vaapi_window_glx_init(GstVaapiWindowGLX *window) priv->is_constructed = FALSE; priv->foreign_context = FALSE; priv->foreign_window = FALSE; + priv->swapped_buffers = FALSE; } /** @@ -572,12 +579,14 @@ gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window) g_return_if_fail(window->priv->is_constructed); GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - glXSwapBuffers( + gl_swap_buffers( GST_VAAPI_OBJECT_XDISPLAY(window), GST_VAAPI_OBJECT_ID(window) ); glClear(GL_COLOR_BUFFER_BIT); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + + window->priv->swapped_buffers = TRUE; } /** From 5e8b1d678f09b43411632eca674191af455ecfcf Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 14:13:26 +0000 Subject: [PATCH 0217/3781] Add VA/GLX support to vaapisink. --- sys/vaapisink/Makefile.am | 5 ++ sys/vaapisink/gstvaapisink.c | 97 ++++++++++++++++++++++++++++++++---- sys/vaapisink/gstvaapisink.h | 7 +++ 3 files changed, 100 insertions(+), 9 deletions(-) diff --git a/sys/vaapisink/Makefile.am b/sys/vaapisink/Makefile.am index 9fdb92140d..6342a39d84 100644 --- a/sys/vaapisink/Makefile.am +++ b/sys/vaapisink/Makefile.am @@ -3,8 +3,13 @@ plugin_LTLIBRARIES = libgstvaapisink.la libgstvaapi_CFLAGS = \ -I$(top_srcdir)/gst-libs +if USE_GLX +libgstvaapi_LIBS = \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la +else libgstvaapi_LIBS = \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la +endif libgstvaapisink_la_SOURCES = \ gstvaapisink.c \ diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 228218952c..ea97427fb9 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -34,6 +34,10 @@ #include #include #include +#if USE_GLX +#include +#include +#endif #include "gstvaapisink.h" #define GST_PLUGIN_NAME "vaapisink" @@ -73,6 +77,7 @@ GST_BOILERPLATE_FULL( enum { PROP_0, + PROP_USE_GLX, PROP_DISPLAY, PROP_FULLSCREEN, PROP_SYNCHRONOUS @@ -114,11 +119,32 @@ gst_vaapisink_destroy(GstVaapiSink *sink) } } +static inline gboolean +gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) +{ + GstVaapiDisplay * const display = sink->display; + + if (!sink->window) { +#if USE_GLX + if (sink->use_glx) + sink->window = gst_vaapi_window_glx_new(display, width, height); + else +#endif + sink->window = gst_vaapi_window_x11_new(display, width, height); + } + return sink->window != NULL; +} + static inline gboolean gst_vaapisink_ensure_display(GstVaapiSink *sink) { if (!sink->display) { - sink->display = gst_vaapi_display_x11_new(sink->display_name); +#if USE_GLX + if (sink->use_glx) + sink->display = gst_vaapi_display_glx_new(sink->display_name); + else +#endif + sink->display = gst_vaapi_display_x11_new(sink->display_name); if (!sink->display || !gst_vaapi_display_get_display(sink->display)) return FALSE; g_object_set(sink, "synchronous", sink->synchronous, NULL); @@ -171,6 +197,8 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return FALSE; if (!gst_structure_get_int(structure, "height", &video_height)) return FALSE; + sink->video_width = video_width; + sink->video_height = video_height; gst_video_parse_caps_pixel_aspect_ratio(caps, &video_par_n, &video_par_d); gst_vaapi_display_get_size(sink->display, &display_width, &display_height); @@ -232,11 +260,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) if (sink->window) gst_vaapi_window_set_size(sink->window, win_width, win_height); else { - sink->window = gst_vaapi_window_x11_new( - sink->display, - win_width, win_height - ); - if (!sink->window) + if (!gst_vaapisink_ensure_window(sink, win_width, win_height)) return FALSE; gst_vaapi_window_set_fullscreen(sink->window, sink->fullscreen); gst_vaapi_window_show(sink->window); @@ -260,10 +284,43 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) return GST_FLOW_UNEXPECTED; flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - if (!gst_vaapi_window_put_surface(sink->window, surface, NULL, - &sink->window_rect, flags)) - return GST_FLOW_UNEXPECTED; +#if USE_GLX + if (sink->use_glx) { + GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window); + gst_vaapi_window_glx_make_current(window); + if (!sink->texture) { + sink->texture = gst_vaapi_texture_new( + sink->display, + GL_TEXTURE_2D, + GL_BGRA, + sink->video_width, + sink->video_height + ); + if (!sink->texture) { + GST_DEBUG("could not create VA/GLX texture"); + return GST_FLOW_UNEXPECTED; + } + } + if (!gst_vaapi_texture_put_surface(sink->texture, surface, flags)) { + GST_DEBUG("could not transfer VA surface to texture"); + return GST_FLOW_UNEXPECTED; + } + if (!gst_vaapi_window_glx_put_texture(window, sink->texture, + NULL, &sink->window_rect)) { + GST_DEBUG("could not render VA/GLX texture"); + return GST_FLOW_UNEXPECTED; + } + gst_vaapi_window_glx_swap_buffers(window); + return GST_FLOW_OK; + } +#endif + + if (!gst_vaapi_window_put_surface(sink->window, surface, + NULL, &sink->window_rect, flags)) { + GST_DEBUG("could not render VA surface"); + return GST_FLOW_UNEXPECTED; + } return GST_FLOW_OK; } @@ -286,6 +343,9 @@ gst_vaapisink_set_property( GstVaapiSink * const sink = GST_VAAPISINK(object); switch (prop_id) { + case PROP_USE_GLX: + sink->use_glx = g_value_get_boolean(value); + break; case PROP_DISPLAY: g_free(sink->display_name); sink->display_name = g_strdup(g_value_get_string(value)); @@ -313,6 +373,9 @@ gst_vaapisink_get_property( GstVaapiSink * const sink = GST_VAAPISINK(object); switch (prop_id) { + case PROP_USE_GLX: + g_value_set_boolean(value, sink->use_glx); + break; case PROP_DISPLAY: g_value_set_string(value, sink->display_name); break; @@ -355,6 +418,17 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->preroll = gst_vaapisink_show_frame; basesink_class->render = gst_vaapisink_show_frame; +#if USE_GLX + g_object_class_install_property + (object_class, + PROP_USE_GLX, + g_param_spec_boolean("use-glx", + "GLX rendering", + "Enables GLX rendering", + FALSE, + G_PARAM_READWRITE)); +#endif + g_object_class_install_property (object_class, PROP_DISPLAY, @@ -393,8 +467,13 @@ static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) { sink->display_name = NULL; sink->display = NULL; + sink->window = NULL; + sink->texture = NULL; + sink->video_width = 0; + sink->video_height = 0; sink->fullscreen = FALSE; sink->synchronous = FALSE; + sink->use_glx = FALSE; } GstVaapiDisplay * diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h index 12b74ca40e..349a4b1729 100644 --- a/sys/vaapisink/gstvaapisink.h +++ b/sys/vaapisink/gstvaapisink.h @@ -24,6 +24,9 @@ #include #include #include +#if USE_GLX +#include +#endif #include G_BEGIN_DECLS @@ -63,8 +66,12 @@ struct _GstVaapiSink { GstVaapiDisplay *display; GstVaapiWindow *window; GstVaapiRectangle window_rect; + GstVaapiTexture *texture; + guint video_width; + guint video_height; guint fullscreen : 1; guint synchronous : 1; + guint use_glx : 1; }; struct _GstVaapiSinkClass { From 59421c67e3611f83b75be0caf3cca12882bcbd68 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 14:13:55 +0000 Subject: [PATCH 0218/3781] 0.1.2. --- NEWS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index e2504c402e..08a4f8e924 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2010-03-DD +gst-vaapi NEWS -- summary of changes. 2010-03-29 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.1.2 - DD.Mar.2010 +Version 0.1.2 - 29.Mar.2010 * Add AYUV image format +* Add support for VA/GLX extensions * Add compatibility with the original VA-API 0.29 Version 0.1.1 - 23.Mar.2010 From ff152c2c1b21eceae4826e182613beb3fc290224 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 14:21:51 +0000 Subject: [PATCH 0219/3781] Fix build without GLX. --- sys/vaapisink/gstvaapisink.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h index 349a4b1729..7a5b947718 100644 --- a/sys/vaapisink/gstvaapisink.h +++ b/sys/vaapisink/gstvaapisink.h @@ -58,6 +58,10 @@ G_BEGIN_DECLS typedef struct _GstVaapiSink GstVaapiSink; typedef struct _GstVaapiSinkClass GstVaapiSinkClass; +#if !USE_GLX +typedef struct _GstVaapiTexture GstVaapiTexture; +#endif + struct _GstVaapiSink { /*< private >*/ GstVideoSink parent_instance; From 1df2dfaab0f530cbe68c59c94eb7d146360cf148 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 14:31:17 +0000 Subject: [PATCH 0220/3781] Fix doc build. --- docs/reference/libs/Makefile.am | 30 ++++++++++++++----- .../libs/{libs.types => libs.core.types} | 4 --- docs/reference/libs/libs.glx.types | 3 ++ docs/reference/libs/libs.x11.types | 2 ++ 4 files changed, 28 insertions(+), 11 deletions(-) rename docs/reference/libs/{libs.types => libs.core.types} (72%) create mode 100644 docs/reference/libs/libs.glx.types create mode 100644 docs/reference/libs/libs.x11.types diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index 99947eef6f..6ed7d8ac87 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -23,6 +23,13 @@ DOC_SOURCE_DIR = $(top_srcdir)/gst-libs/gst/vaapi # Extra options to pass to gtkdoc-scangobj. Not normally needed. SCANGOBJ_OPTIONS = --type-init-func="g_type_init()" +# List files used by scanobj +SCANOBJ_TYPES = $(srcdir)/$(DOC_MODULE).core.types +SCANOBJ_TYPES += $(srcdir)/$(DOC_MODULE).x11.types +if USE_GLX +SCANOBJ_TYPES += $(srcdir)/$(DOC_MODULE).glx.types +endif + # Extra options to supply to gtkdoc-scan. # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" SCAN_OPTIONS = --deprecated-guards="GST_VAAPI_DISABLE_DEPRECATED" @@ -47,7 +54,7 @@ FIXXREF_OPTIONS = \ # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c HFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.h -CFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.c +CFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.c $(srcdir)/$(DOC_MODULE).types # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h @@ -84,16 +91,25 @@ expand_content_files = \ # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) INCLUDES = \ + $(GLIB_CFLAGS) \ -I$(top_srcdir) \ -I$(top_srcdir)/gst-libs \ - -I$(top_srcdir)/gst-libs/gst/vaapi \ - $(GLIB_CFLAGS) + -I$(top_srcdir)/gst-libs/gst/vaapi GTKDOC_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la \ - $(GLIB_LIBS) + $(GLIB_LIBS) \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la + +GTKDOC_LIBS += \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la + +if USE_GLX +GTKDOC_LIBS += \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la +endif + +$(srcdir)/$(DOC_MODULE).types: $(SCANOBJ_TYPES) + cat $(SCANOBJ_TYPES) > $@ # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make diff --git a/docs/reference/libs/libs.types b/docs/reference/libs/libs.core.types similarity index 72% rename from docs/reference/libs/libs.types rename to docs/reference/libs/libs.core.types index 0bd9e59ad3..a33c353370 100644 --- a/docs/reference/libs/libs.types +++ b/docs/reference/libs/libs.core.types @@ -1,6 +1,4 @@ gst_vaapi_display_get_type -gst_vaapi_display_glx_get_type -gst_vaapi_display_x11_get_type gst_vaapi_image_get_type gst_vaapi_image_pool_get_type gst_vaapi_object_get_type @@ -11,5 +9,3 @@ gst_vaapi_video_buffer_get_type gst_vaapi_video_pool_get_type gst_vaapi_video_sink_get_type gst_vaapi_window_get_type -gst_vaapi_window_glx_get_type -gst_vaapi_window_x11_get_type diff --git a/docs/reference/libs/libs.glx.types b/docs/reference/libs/libs.glx.types new file mode 100644 index 0000000000..6ecd3545e8 --- /dev/null +++ b/docs/reference/libs/libs.glx.types @@ -0,0 +1,3 @@ +gst_vaapi_display_glx_get_type +gst_vaapi_texture_get_type +gst_vaapi_window_glx_get_type diff --git a/docs/reference/libs/libs.x11.types b/docs/reference/libs/libs.x11.types new file mode 100644 index 0000000000..c083ce07d4 --- /dev/null +++ b/docs/reference/libs/libs.x11.types @@ -0,0 +1,2 @@ +gst_vaapi_display_x11_get_type +gst_vaapi_window_x11_get_type From 7c7a772824df8042c0fec863b4b7a7ed901929df Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 14:40:26 +0000 Subject: [PATCH 0221/3781] Fix make dist. --- tests/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Makefile.am b/tests/Makefile.am index 2055ef1026..8b3f9bd137 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -50,5 +50,7 @@ test_textures_SOURCES = test-textures.c image.c test_textures_CFLAGS = $(TEST_CFLAGS) $(TEST_GLX_CFLAGS) test_textures_LDADD = $(TEST_LIBS) $(TEST_GLX_LIBS) +EXTRA_DIST = image.h + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in From c7ab525a97fc528a4ca32f8c2518b2f1e83ed2d4 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 14:42:57 +0000 Subject: [PATCH 0222/3781] Fix make distclean. --- pkgconfig/Makefile.am | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index b98888c105..2998e5d832 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -6,6 +6,14 @@ endif pcfiles = $(pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc) +all_pcfiles_in = gstreamer-vaapi.pc.in +all_pcfiles_in += gstreamer-vaapi-x11.pc.in +if USE_GLX +all_pcfiles_in += gstreamer-vaapi-glx.pc.in +endif + +all_pcfiles = $(all_pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc) + pkgconfigdir = @pkgconfigdir@ pkgconfig_DATA = $(pcfiles) @@ -15,7 +23,7 @@ EXTRA_DIST = \ gstreamer-vaapi-x11.pc.in \ $(NULL) -DISTCLEANFILES = $(pcfiles) +DISTCLEANFILES = $(all_pcfiles) # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in From a744a498b151c058dbee0d58f8b8f105ee96f85a Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 14:43:22 +0000 Subject: [PATCH 0223/3781] Fix make dist. --- docs/reference/libs/Makefile.am | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index 6ed7d8ac87..e8d184077b 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -118,7 +118,13 @@ include $(top_srcdir)/gtk-doc.make # e.g. EXTRA_DIST += version.xml.in EXTRA_DIST += \ libs-docs.xml.in \ + libs.core.types \ + libs.x11.types \ + libs.glx.types \ $(NULL) +DISTCLEANFILES = $(srcdir)/$(DOC_MODULE).types +BUILT_SOURCES = $(srcdir)/$(DOC_MODULE).types + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in lib-docs.xml From b4868f9f505c70a5c8ab199b50f8f89066cf58d7 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 14:47:49 +0000 Subject: [PATCH 0224/3781] Really fix make distclean. --- pkgconfig/Makefile.am | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index 2998e5d832..22628bdd50 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -8,9 +8,7 @@ pcfiles = $(pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc) all_pcfiles_in = gstreamer-vaapi.pc.in all_pcfiles_in += gstreamer-vaapi-x11.pc.in -if USE_GLX all_pcfiles_in += gstreamer-vaapi-glx.pc.in -endif all_pcfiles = $(all_pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc) From 28e2b37cfbccf8cacecf14dde63d234449bbf845 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 14:50:52 +0000 Subject: [PATCH 0225/3781] Add libgstvaapi-glx-0 package. --- configure.ac | 2 ++ debian.upstream/Makefile.am | 3 +++ debian.upstream/control.in | 9 +++++++++ debian.upstream/libgstvaapi-glx.install.in | 1 + 4 files changed, 15 insertions(+) create mode 100644 debian.upstream/libgstvaapi-glx.install.in diff --git a/configure.ac b/configure.ac index 7879b3f0a9..7d358b01e7 100644 --- a/configure.ac +++ b/configure.ac @@ -259,6 +259,8 @@ debian.upstream/libgstvaapi.install.in debian.upstream/libgstvaapi-dev.install.in debian.upstream/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi-x11.install.in + debian.upstream/libgstvaapi-glx-$GST_VAAPI_MAJOR_VERSION.install:\ +debian.upstream/libgstvaapi-glx.install.in docs/Makefile docs/reference/Makefile docs/reference/libs/Makefile diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index 93b9514d5d..74906e629d 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -22,6 +22,8 @@ DEBIANFILES = \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION)-dev.install \ libgstvaapi-x11.install.in \ libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ + libgstvaapi-glx.install.in \ + libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ rules \ $(NULL) @@ -33,6 +35,7 @@ DEBIANGENFILES = \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION)-dev.install \ libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ + libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ $(NULL) EXTRA_DIST = \ diff --git a/debian.upstream/control.in b/debian.upstream/control.in index ca4bd120eb..20301a87d0 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -55,6 +55,15 @@ Description: GStreamer libraries from the "vaapi" set . This package contains x11 libraries for the "vaapi" set. +Package: libgstvaapi-glx-@GST_VAAPI_MAJOR_VERSION@ +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: GStreamer libraries from the "vaapi" set + VA-API support libraries for GStreamer. + . + This package contains glx libraries for the "vaapi" set. + Package: libgstvaapi@GST_VAAPI_MAJOR_VERSION@-dev Architecture: any Section: libdevel diff --git a/debian.upstream/libgstvaapi-glx.install.in b/debian.upstream/libgstvaapi-glx.install.in new file mode 100644 index 0000000000..cd7352a2b4 --- /dev/null +++ b/debian.upstream/libgstvaapi-glx.install.in @@ -0,0 +1 @@ +debian/tmp/usr/lib/libgstvaapi-glx-@GST_MAJORMINOR@.so.* From 3c48a3004c7bc09911777fe7ad9171c03ab03a89 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 15:03:30 +0000 Subject: [PATCH 0226/3781] Don't build vaapisink/gl by default. However, if this is enabled, use the GL renderer by default. --- configure.ac | 17 +++++++++++++++++ sys/vaapisink/Makefile.am | 2 +- sys/vaapisink/gstvaapisink.c | 14 +++++++------- sys/vaapisink/gstvaapisink.h | 4 ++-- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 7d358b01e7..b12e87d093 100644 --- a/configure.ac +++ b/configure.ac @@ -75,6 +75,11 @@ AC_ARG_ENABLE(glx, [enable OpenGL/X11 @<:@default=yes@:>@]), [], [enable_glx="yes"]) +AC_ARG_ENABLE(vaapisink-glx, + AC_HELP_STRING([--enable-vaapisink-glx], + [enable OpenGL/X11 to vaapisink @<:@default=yes@:>@]), + [], [enable_vaapisink_glx="no"]) + dnl Check for __attribute__((visibility())) AC_CACHE_CHECK([whether __attribute__((visibility())) is supported], vaapi_cv_visibility_attribute, @@ -227,9 +232,20 @@ AC_SUBST(LIBVA_GLX_PKGNAME) AC_SUBST(LIBVA_EXTRA_CFLAGS) AC_SUBST(LIBVA_EXTRA_LIBS) +dnl Check for OpenGL support to +if test "$enable_vaapisink_glx:$USE_GLX" = "yes:1"; then + USE_VAAPISINK_GLX=1 +else + USE_VAAPISINK_GLX=0 +fi + AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) +AC_DEFINE_UNQUOTED(USE_VAAPISINK_GLX, $USE_VAAPISINK_GLX, + [Defined to 1 to enable GLX support to vaapisink]) +AM_CONDITIONAL(USE_VAAPISINK_GLX, test $USE_VAAPISINK_GLX -eq 1) + VA_VERSION=`$PKG_CONFIG --modversion libva` VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1` VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2` @@ -289,4 +305,5 @@ echo $PACKAGE configuration summary: echo echo VA-API version ................... : $VA_VERSION_STR echo GLX support ...................... : $(test $USE_GLX -eq 1 && echo yes || echo no) +echo Build vaapisink with OpenGL ...... : $(test $USE_VAAPISINK_GLX -eq 1 && echo yes || echo no) echo diff --git a/sys/vaapisink/Makefile.am b/sys/vaapisink/Makefile.am index 6342a39d84..3265f33be0 100644 --- a/sys/vaapisink/Makefile.am +++ b/sys/vaapisink/Makefile.am @@ -3,7 +3,7 @@ plugin_LTLIBRARIES = libgstvaapisink.la libgstvaapi_CFLAGS = \ -I$(top_srcdir)/gst-libs -if USE_GLX +if USE_VAAPISINK_GLX libgstvaapi_LIBS = \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la else diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index ea97427fb9..fc0704ec66 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -34,7 +34,7 @@ #include #include #include -#if USE_GLX +#if USE_VAAPISINK_GLX #include #include #endif @@ -125,7 +125,7 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) GstVaapiDisplay * const display = sink->display; if (!sink->window) { -#if USE_GLX +#if USE_VAAPISINK_GLX if (sink->use_glx) sink->window = gst_vaapi_window_glx_new(display, width, height); else @@ -139,7 +139,7 @@ static inline gboolean gst_vaapisink_ensure_display(GstVaapiSink *sink) { if (!sink->display) { -#if USE_GLX +#if USE_VAAPISINK_GLX if (sink->use_glx) sink->display = gst_vaapi_display_glx_new(sink->display_name); else @@ -285,7 +285,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; -#if USE_GLX +#if USE_VAAPISINK_GLX if (sink->use_glx) { GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window); gst_vaapi_window_glx_make_current(window); @@ -418,14 +418,14 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->preroll = gst_vaapisink_show_frame; basesink_class->render = gst_vaapisink_show_frame; -#if USE_GLX +#if USE_VAAPISINK_GLX g_object_class_install_property (object_class, PROP_USE_GLX, g_param_spec_boolean("use-glx", "GLX rendering", "Enables GLX rendering", - FALSE, + TRUE, G_PARAM_READWRITE)); #endif @@ -473,7 +473,7 @@ static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) sink->video_height = 0; sink->fullscreen = FALSE; sink->synchronous = FALSE; - sink->use_glx = FALSE; + sink->use_glx = USE_VAAPISINK_GLX; } GstVaapiDisplay * diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h index 7a5b947718..914af826cc 100644 --- a/sys/vaapisink/gstvaapisink.h +++ b/sys/vaapisink/gstvaapisink.h @@ -24,7 +24,7 @@ #include #include #include -#if USE_GLX +#if USE_VAAPISINK_GLX #include #endif #include @@ -58,7 +58,7 @@ G_BEGIN_DECLS typedef struct _GstVaapiSink GstVaapiSink; typedef struct _GstVaapiSinkClass GstVaapiSinkClass; -#if !USE_GLX +#if !USE_VAAPISINK_GLX typedef struct _GstVaapiTexture GstVaapiTexture; #endif From 201a7c9ce1126105c3cd4bb8d81705c884a3d2ad Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 15:51:54 +0000 Subject: [PATCH 0227/3781] Use a projection suitable for rotation around the Y axis. --- configure.ac | 3 ++ gst-libs/gst/vaapi/gstvaapiutils_glx.c | 66 +++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b12e87d093..ab19b03166 100644 --- a/configure.ac +++ b/configure.ac @@ -106,6 +106,9 @@ AC_DEFINE_UNQUOTED([attribute_hidden], [$vaapi_cv_visibility_attribute_hidden], [Define the "hidden" visibility attribute]) +dnl Check for basic libraries +AC_CHECK_LIB(m, tan) + dnl Check for Gtk doc GTKDOC_VERSION=gtkdoc_version GTK_DOC_CHECK([$GTKDOC_VERSION]) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index b7ba744d99..5947ed7bf8 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -19,6 +19,7 @@ */ #include "config.h" +#include #include "gstvaapiutils_glx.h" #define DEBUG 1 @@ -163,6 +164,59 @@ gl_set_bgcolor(guint32 color) ); } +/** + * gl_perspective: + * @fovy: the field of view angle, in degrees, in the y direction + * @aspect: the aspect ratio that determines the field of view in the + * x direction. The aspect ratio is the ratio of x (width) to y + * (height) + * @zNear: the distance from the viewer to the near clipping plane + * (always positive) + * @zFar: the distance from the viewer to the far clipping plane + * (always positive) + * + * Specified a viewing frustum into the world coordinate system. This + * basically is the Mesa implementation of gluPerspective(). + */ +static void +frustum(GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval) +{ + GLdouble x, y, a, b, c, d; + GLdouble m[16]; + + x = (2.0 * nearval) / (right - left); + y = (2.0 * nearval) / (top - bottom); + a = (right + left) / (right - left); + b = (top + bottom) / (top - bottom); + c = -(farval + nearval) / ( farval - nearval); + d = -(2.0 * farval * nearval) / (farval - nearval); + +#define M(row,col) m[col*4+row] + M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F; + M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F; + M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d; + M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F; +#undef M + + glMultMatrixd(m); +} + +static void +gl_perspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) +{ + GLdouble xmin, xmax, ymin, ymax; + + ymax = zNear * tan(fovy * M_PI / 360.0); + ymin = -ymax; + xmin = ymin * aspect; + xmax = ymax * aspect; + + /* Don't call glFrustum() because of error semantics (covglu) */ + frustum(xmin, xmax, ymin, ymax, zNear, zFar); +} + /** * gl_resize: * @width: the requested width, in pixels @@ -175,12 +229,22 @@ gl_set_bgcolor(guint32 color) void gl_resize(guint width, guint height) { +#define FOVY 60.0f +#define ASPECT 1.0f +#define Z_NEAR 0.1f +#define Z_FAR 100.0f +#define Z_CAMERA 0.869f + glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glOrtho(0, width, height, 0, -1, 1); + gl_perspective(FOVY, ASPECT, Z_NEAR, Z_FAR); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); + + glTranslatef(-0.5f, -0.5f, -Z_CAMERA); + glScalef(1.0f/width, -1.0f/height, 1.0f/width); + glTranslatef(0.0f, -1.0f*height, 0.0f); } /** From c5ff5963160d3167b8b1f87f0ed214af14467e6c Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 15:59:44 +0000 Subject: [PATCH 0228/3781] Add OpenGL reflection effect ("use-reflection"). --- sys/vaapisink/gstvaapisink.c | 159 ++++++++++++++++++++++++++++++++--- sys/vaapisink/gstvaapisink.h | 1 + 2 files changed, 148 insertions(+), 12 deletions(-) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index fc0704ec66..2384830fe8 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -80,7 +80,8 @@ enum { PROP_USE_GLX, PROP_DISPLAY, PROP_FULLSCREEN, - PROP_SYNCHRONOUS + PROP_SYNCHRONOUS, + PROP_USE_REFLECTION }; static GstVaapiDisplay * @@ -268,6 +269,125 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return TRUE; } +#if USE_VAAPISINK_GLX +static void +render_background(GstVaapiSink *sink) +{ + /* Original code from Mirco Muller (MacSlow): + */ + GLfloat fStartX = 0.0f; + GLfloat fStartY = 0.0f; + GLfloat fWidth = (GLfloat)sink->window_rect.width; + GLfloat fHeight = (GLfloat)sink->window_rect.height; + + glClear(GL_COLOR_BUFFER_BIT); + glBegin(GL_QUADS); + { + /* top third, darker grey to white */ + glColor3f(0.85f, 0.85f, 0.85f); + glVertex3f(fStartX, fStartY, 0.0f); + glColor3f(0.85f, 0.85f, 0.85f); + glVertex3f(fStartX + fWidth, fStartY, 0.0f); + glColor3f(1.0f, 1.0f, 1.0f); + glVertex3f(fStartX + fWidth, fStartY + fHeight / 3.0f, 0.0f); + glColor3f(1.0f, 1.0f, 1.0f); + glVertex3f(fStartX, fStartY + fHeight / 3.0f, 0.0f); + + /* middle third, just plain white */ + glColor3f(1.0f, 1.0f, 1.0f); + glVertex3f(fStartX, fStartY + fHeight / 3.0f, 0.0f); + glVertex3f(fStartX + fWidth, fStartY + fHeight / 3.0f, 0.0f); + glVertex3f(fStartX + fWidth, fStartY + 2.0f * fHeight / 3.0f, 0.0f); + glVertex3f(fStartX, fStartY + 2.0f * fHeight / 3.0f, 0.0f); + + /* bottom third, white to lighter grey */ + glColor3f(1.0f, 1.0f, 1.0f); + glVertex3f(fStartX, fStartY + 2.0f * fHeight / 3.0f, 0.0f); + glColor3f(1.0f, 1.0f, 1.0f); + glVertex3f(fStartX + fWidth, fStartY + 2.0f * fHeight / 3.0f, 0.0f); + glColor3f(0.62f, 0.66f, 0.69f); + glVertex3f(fStartX + fWidth, fStartY + fHeight, 0.0f); + glColor3f(0.62f, 0.66f, 0.69f); + glVertex3f(fStartX, fStartY + fHeight, 0.0f); + } + glEnd(); +} + +static void +render_frame(GstVaapiSink *sink) +{ + const guint w = sink->window_rect.width; + const guint h = sink->window_rect.height; + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glBegin(GL_QUADS); + { + glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0); + glTexCoord2f(0.0f, 1.0f); glVertex2i(0, h); + glTexCoord2f(1.0f, 1.0f); glVertex2i(w, h); + glTexCoord2f(1.0f, 0.0f); glVertex2i(w, 0); + } + glEnd(); +} + +static void +render_reflection(GstVaapiSink *sink) +{ + const guint w = sink->window_rect.width; + const guint h = sink->window_rect.height; + const guint rh = h / 5; + GLfloat ry = 1.0f - (GLfloat)rh / (GLfloat)h; + + glBegin(GL_QUADS); + { + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glTexCoord2f(0.0f, 1.0f); glVertex2i(0, 0); + glTexCoord2f(1.0f, 1.0f); glVertex2i(w, 0); + + glColor4f(1.0f, 1.0f, 1.0f, 0.0f); + glTexCoord2f(1.0f, ry); glVertex2i(w, rh); + glTexCoord2f(0.0f, ry); glVertex2i(0, rh); + } + glEnd(); +} + +static gboolean +gst_vaapisink_show_frame_glx(GstVaapiSink *sink) +{ + GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window); + GLenum target; + GLuint texture; + + if (!sink->use_reflection) + return gst_vaapi_window_glx_put_texture(window, sink->texture, + NULL, &sink->window_rect); + + target = gst_vaapi_texture_get_target(sink->texture); + texture = gst_vaapi_texture_get_id(sink->texture); + if (target != GL_TEXTURE_2D || !texture) + return FALSE; + + render_background(sink); + + glEnable(target); + glBindTexture(target, texture); + { + glPushMatrix(); + glRotatef(20.0f, 0.0f, 1.0f, 0.0f); + glTranslatef(50.0f, 0.0f, 0.0f); + render_frame(sink); + glPushMatrix(); + glTranslatef(0.0, (GLfloat)sink->window_rect.height + 5.0f, 0.0f); + render_reflection(sink); + glPopMatrix(); + glPopMatrix(); + } + glBindTexture(target, 0); + glDisable(target); + return TRUE; +} +#endif + static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) { @@ -306,8 +426,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) GST_DEBUG("could not transfer VA surface to texture"); return GST_FLOW_UNEXPECTED; } - if (!gst_vaapi_window_glx_put_texture(window, sink->texture, - NULL, &sink->window_rect)) { + if (!gst_vaapisink_show_frame_glx(sink)) { GST_DEBUG("could not render VA/GLX texture"); return GST_FLOW_UNEXPECTED; } @@ -356,6 +475,9 @@ gst_vaapisink_set_property( case PROP_SYNCHRONOUS: sink->synchronous = g_value_get_boolean(value); break; + case PROP_USE_REFLECTION: + sink->use_reflection = g_value_get_boolean(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -385,6 +507,9 @@ gst_vaapisink_get_property( case PROP_SYNCHRONOUS: g_value_set_boolean(value, sink->synchronous); break; + case PROP_USE_REFLECTION: + g_value_set_boolean(value, sink->use_reflection); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -427,6 +552,15 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) "Enables GLX rendering", TRUE, G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, + PROP_USE_REFLECTION, + g_param_spec_boolean("use-reflection", + "Reflection effect", + "Enables OpenGL reflection effect", + FALSE, + G_PARAM_READWRITE)); #endif g_object_class_install_property @@ -465,15 +599,16 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) { - sink->display_name = NULL; - sink->display = NULL; - sink->window = NULL; - sink->texture = NULL; - sink->video_width = 0; - sink->video_height = 0; - sink->fullscreen = FALSE; - sink->synchronous = FALSE; - sink->use_glx = USE_VAAPISINK_GLX; + sink->display_name = NULL; + sink->display = NULL; + sink->window = NULL; + sink->texture = NULL; + sink->video_width = 0; + sink->video_height = 0; + sink->fullscreen = FALSE; + sink->synchronous = FALSE; + sink->use_glx = USE_VAAPISINK_GLX; + sink->use_reflection = FALSE; } GstVaapiDisplay * diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h index 914af826cc..1809212fde 100644 --- a/sys/vaapisink/gstvaapisink.h +++ b/sys/vaapisink/gstvaapisink.h @@ -76,6 +76,7 @@ struct _GstVaapiSink { guint fullscreen : 1; guint synchronous : 1; guint use_glx : 1; + guint use_reflection : 1; }; struct _GstVaapiSinkClass { From fc05ddf201cd12bda852299b452a6f1b2a1de9ee Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 16:17:38 +0000 Subject: [PATCH 0229/3781] Fix fullscreen mode. --- sys/vaapisink/gstvaapisink.c | 40 +++++++++++++++++++++--------------- sys/vaapisink/gstvaapisink.h | 4 +++- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 2384830fe8..9bba20c989 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -185,7 +185,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstStructure * const structure = gst_caps_get_structure(caps, 0); - GstVaapiRectangle * const win_rect = &sink->window_rect; + GstVaapiRectangle * const disp_rect = &sink->display_rect; guint num, den; guint win_width, win_height; guint display_width, display_height, display_par_n, display_par_d; @@ -248,24 +248,30 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) GST_DEBUG("window size %ux%u", win_width, win_height); if (sink->fullscreen) { - win_rect->x = (display_width - win_width) / 2; - win_rect->y = (display_height - win_height) / 2; + disp_rect->x = (display_width - win_width) / 2; + disp_rect->y = (display_height - win_height) / 2; } else { - win_rect->x = 0; - win_rect->y = 0; + disp_rect->x = 0; + disp_rect->y = 0; } - win_rect->width = win_width; - win_rect->height = win_height; + disp_rect->width = win_width; + disp_rect->height = win_height; if (sink->window) gst_vaapi_window_set_size(sink->window, win_width, win_height); else { + if (sink->fullscreen) { + win_width = display_width; + win_height = display_height; + } if (!gst_vaapisink_ensure_window(sink, win_width, win_height)) return FALSE; gst_vaapi_window_set_fullscreen(sink->window, sink->fullscreen); gst_vaapi_window_show(sink->window); } + sink->window_width = win_width; + sink->window_height = win_height; return TRUE; } @@ -277,8 +283,8 @@ render_background(GstVaapiSink *sink) */ GLfloat fStartX = 0.0f; GLfloat fStartY = 0.0f; - GLfloat fWidth = (GLfloat)sink->window_rect.width; - GLfloat fHeight = (GLfloat)sink->window_rect.height; + GLfloat fWidth = (GLfloat)sink->window_width; + GLfloat fHeight = (GLfloat)sink->window_height; glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_QUADS); @@ -316,8 +322,8 @@ render_background(GstVaapiSink *sink) static void render_frame(GstVaapiSink *sink) { - const guint w = sink->window_rect.width; - const guint h = sink->window_rect.height; + const guint w = sink->window_width; + const guint h = sink->window_height; glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); @@ -333,8 +339,8 @@ render_frame(GstVaapiSink *sink) static void render_reflection(GstVaapiSink *sink) { - const guint w = sink->window_rect.width; - const guint h = sink->window_rect.height; + const guint w = sink->window_width; + const guint h = sink->window_height; const guint rh = h / 5; GLfloat ry = 1.0f - (GLfloat)rh / (GLfloat)h; @@ -360,7 +366,7 @@ gst_vaapisink_show_frame_glx(GstVaapiSink *sink) if (!sink->use_reflection) return gst_vaapi_window_glx_put_texture(window, sink->texture, - NULL, &sink->window_rect); + NULL, &sink->display_rect); target = gst_vaapi_texture_get_target(sink->texture); texture = gst_vaapi_texture_get_id(sink->texture); @@ -377,7 +383,7 @@ gst_vaapisink_show_frame_glx(GstVaapiSink *sink) glTranslatef(50.0f, 0.0f, 0.0f); render_frame(sink); glPushMatrix(); - glTranslatef(0.0, (GLfloat)sink->window_rect.height + 5.0f, 0.0f); + glTranslatef(0.0, (GLfloat)sink->window_height + 5.0f, 0.0f); render_reflection(sink); glPopMatrix(); glPopMatrix(); @@ -436,7 +442,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) #endif if (!gst_vaapi_window_put_surface(sink->window, surface, - NULL, &sink->window_rect, flags)) { + NULL, &sink->display_rect, flags)) { GST_DEBUG("could not render VA surface"); return GST_FLOW_UNEXPECTED; } @@ -602,6 +608,8 @@ static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) sink->display_name = NULL; sink->display = NULL; sink->window = NULL; + sink->window_width = 0; + sink->window_height = 0; sink->texture = NULL; sink->video_width = 0; sink->video_height = 0; diff --git a/sys/vaapisink/gstvaapisink.h b/sys/vaapisink/gstvaapisink.h index 1809212fde..c7ceae43d9 100644 --- a/sys/vaapisink/gstvaapisink.h +++ b/sys/vaapisink/gstvaapisink.h @@ -69,10 +69,12 @@ struct _GstVaapiSink { gchar *display_name; GstVaapiDisplay *display; GstVaapiWindow *window; - GstVaapiRectangle window_rect; + guint window_width; + guint window_height; GstVaapiTexture *texture; guint video_width; guint video_height; + GstVaapiRectangle display_rect; guint fullscreen : 1; guint synchronous : 1; guint use_glx : 1; From 63a0dfcd3f00bc50ca748e3527e50f13412f14a4 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 29 Mar 2010 16:24:37 +0000 Subject: [PATCH 0230/3781] Fix reflection code to preserve aspect ratio. --- sys/vaapisink/gstvaapisink.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/sys/vaapisink/gstvaapisink.c b/sys/vaapisink/gstvaapisink.c index 9bba20c989..51cea5b163 100644 --- a/sys/vaapisink/gstvaapisink.c +++ b/sys/vaapisink/gstvaapisink.c @@ -322,16 +322,18 @@ render_background(GstVaapiSink *sink) static void render_frame(GstVaapiSink *sink) { - const guint w = sink->window_width; - const guint h = sink->window_height; + const guint x1 = sink->display_rect.x; + const guint x2 = sink->display_rect.x + sink->display_rect.width; + const guint y1 = sink->display_rect.y; + const guint y2 = sink->display_rect.y + sink->display_rect.height; glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); { - glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0); - glTexCoord2f(0.0f, 1.0f); glVertex2i(0, h); - glTexCoord2f(1.0f, 1.0f); glVertex2i(w, h); - glTexCoord2f(1.0f, 0.0f); glVertex2i(w, 0); + glTexCoord2f(0.0f, 0.0f); glVertex2i(x1, y1); + glTexCoord2f(0.0f, 1.0f); glVertex2i(x1, y2); + glTexCoord2f(1.0f, 1.0f); glVertex2i(x2, y2); + glTexCoord2f(1.0f, 0.0f); glVertex2i(x2, y1); } glEnd(); } @@ -339,20 +341,21 @@ render_frame(GstVaapiSink *sink) static void render_reflection(GstVaapiSink *sink) { - const guint w = sink->window_width; - const guint h = sink->window_height; - const guint rh = h / 5; - GLfloat ry = 1.0f - (GLfloat)rh / (GLfloat)h; + const guint x1 = sink->display_rect.x; + const guint x2 = sink->display_rect.x + sink->display_rect.width; + const guint y1 = sink->display_rect.y; + const guint rh = sink->display_rect.height / 5; + GLfloat ry = 1.0f - (GLfloat)rh / (GLfloat)sink->display_rect.height; glBegin(GL_QUADS); { glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glTexCoord2f(0.0f, 1.0f); glVertex2i(0, 0); - glTexCoord2f(1.0f, 1.0f); glVertex2i(w, 0); + glTexCoord2f(0.0f, 1.0f); glVertex2i(x1, y1); + glTexCoord2f(1.0f, 1.0f); glVertex2i(x2, y1); glColor4f(1.0f, 1.0f, 1.0f, 0.0f); - glTexCoord2f(1.0f, ry); glVertex2i(w, rh); - glTexCoord2f(0.0f, ry); glVertex2i(0, rh); + glTexCoord2f(1.0f, ry); glVertex2i(x2, y1 + rh); + glTexCoord2f(0.0f, ry); glVertex2i(x1, y1 + rh); } glEnd(); } @@ -383,7 +386,7 @@ gst_vaapisink_show_frame_glx(GstVaapiSink *sink) glTranslatef(50.0f, 0.0f, 0.0f); render_frame(sink); glPushMatrix(); - glTranslatef(0.0, (GLfloat)sink->window_height + 5.0f, 0.0f); + glTranslatef(0.0, (GLfloat)sink->display_rect.height + 5.0f, 0.0f); render_reflection(sink); glPopMatrix(); glPopMatrix(); From 05a1ed2d233f33454524191580cc452579cbe900 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 07:39:16 +0000 Subject: [PATCH 0231/3781] Try to not reference VA-API types directly. --- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.h | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.h | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index c7585747c7..d21bda2bec 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -512,7 +512,7 @@ gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image) * * Return value: the underlying VA image id */ -VAImageID +GstVaapiID gst_vaapi_image_get_id(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID); diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index d15326722f..a9a865187c 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -116,7 +116,7 @@ gst_vaapi_image_new( GstVaapiImage * gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image); -VAImageID +GstVaapiID gst_vaapi_image_get_id(GstVaapiImage *image); gboolean diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index a015042314..4566a321b2 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -225,7 +225,7 @@ gst_vaapi_subpicture_new(GstVaapiImage *image) * * Return value: the underlying VA subpicture id */ -VASubpictureID +GstVaapiID gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture) { g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), VA_INVALID_ID); diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 7c4b125c52..237aa5c6ee 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -83,7 +83,7 @@ gst_vaapi_subpicture_get_type(void); GstVaapiSubpicture * gst_vaapi_subpicture_new(GstVaapiImage *image); -VASubpictureID +GstVaapiID gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture); GstVaapiImage * diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 2a26eaaeac..c1456df7f1 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -313,7 +313,7 @@ gst_vaapi_surface_new( * * Return value: the underlying VA surface id */ -VASurfaceID +GstVaapiID gst_vaapi_surface_get_id(GstVaapiSurface *surface) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), VA_INVALID_SURFACE); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index db92955539..5893d72f06 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -133,7 +133,7 @@ gst_vaapi_surface_new( guint height ); -VASurfaceID +GstVaapiID gst_vaapi_surface_get_id(GstVaapiSurface *surface); GstVaapiChromaType From fb4fffd5cb54143983de1c5175398b4af2ed1b81 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 07:46:47 +0000 Subject: [PATCH 0232/3781] Rename to gst/ as sys/ was too vague. --- Makefile.am | 2 +- configure.ac | 6 +++--- docs/reference/plugins/Makefile.am | 8 ++++---- {sys => gst}/Makefile.am | 0 {sys => gst}/vaapiconvert/Makefile.am | 0 {sys => gst}/vaapiconvert/gstvaapiconvert.c | 0 {sys => gst}/vaapiconvert/gstvaapiconvert.h | 0 {sys => gst}/vaapisink/Makefile.am | 0 {sys => gst}/vaapisink/gstvaapisink.c | 0 {sys => gst}/vaapisink/gstvaapisink.h | 0 10 files changed, 8 insertions(+), 8 deletions(-) rename {sys => gst}/Makefile.am (100%) rename {sys => gst}/vaapiconvert/Makefile.am (100%) rename {sys => gst}/vaapiconvert/gstvaapiconvert.c (100%) rename {sys => gst}/vaapiconvert/gstvaapiconvert.h (100%) rename {sys => gst}/vaapisink/Makefile.am (100%) rename {sys => gst}/vaapisink/gstvaapisink.c (100%) rename {sys => gst}/vaapisink/gstvaapisink.h (100%) diff --git a/Makefile.am b/Makefile.am index adaf6740b3..578a41bd8e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign -SUBDIRS = debian.upstream gst-libs pkgconfig sys tests docs +SUBDIRS = debian.upstream gst-libs gst pkgconfig tests docs # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ diff --git a/configure.ac b/configure.ac index ab19b03166..e6ed60c6ad 100644 --- a/configure.ac +++ b/configure.ac @@ -296,9 +296,9 @@ pkgconfig/gstreamer-vaapi.pc.in pkgconfig/gstreamer-vaapi-glx.pc.in pkgconfig/gstreamer-vaapi-x11-$GST_MAJORMINOR.pc:\ pkgconfig/gstreamer-vaapi-x11.pc.in - sys/Makefile - sys/vaapiconvert/Makefile - sys/vaapisink/Makefile + gst/Makefile + gst/vaapiconvert/Makefile + gst/vaapisink/Makefile tests/Makefile ]) diff --git a/docs/reference/plugins/Makefile.am b/docs/reference/plugins/Makefile.am index 778dc96790..90595ff947 100644 --- a/docs/reference/plugins/Makefile.am +++ b/docs/reference/plugins/Makefile.am @@ -46,8 +46,8 @@ FIXXREF_OPTIONS = \ # Used for dependencies. The docs will be rebuilt if any of these change. # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB = $(top_srcdir)/sys/*/*.h -CFILE_GLOB = $(top_srcdir)/sys/*/*.c +HFILE_GLOB = $(top_srcdir)/gst/*/*.h +CFILE_GLOB = $(top_srcdir)/gst/*/*.c # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h @@ -88,8 +88,8 @@ INCLUDES = \ GTKDOC_LIBS = \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la \ - $(top_builddir)/sys/vaapiconvert/libgstvaapiconvert.la \ - $(top_builddir)/sys/vaapisink/libgstvaapisink.la \ + $(top_builddir)/gst/vaapiconvert/libgstvaapiconvert.la \ + $(top_builddir)/gst/vaapisink/libgstvaapisink.la \ $(GLIB_LIBS) # This includes the standard gtk-doc make rules, copied by gtkdocize. diff --git a/sys/Makefile.am b/gst/Makefile.am similarity index 100% rename from sys/Makefile.am rename to gst/Makefile.am diff --git a/sys/vaapiconvert/Makefile.am b/gst/vaapiconvert/Makefile.am similarity index 100% rename from sys/vaapiconvert/Makefile.am rename to gst/vaapiconvert/Makefile.am diff --git a/sys/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c similarity index 100% rename from sys/vaapiconvert/gstvaapiconvert.c rename to gst/vaapiconvert/gstvaapiconvert.c diff --git a/sys/vaapiconvert/gstvaapiconvert.h b/gst/vaapiconvert/gstvaapiconvert.h similarity index 100% rename from sys/vaapiconvert/gstvaapiconvert.h rename to gst/vaapiconvert/gstvaapiconvert.h diff --git a/sys/vaapisink/Makefile.am b/gst/vaapisink/Makefile.am similarity index 100% rename from sys/vaapisink/Makefile.am rename to gst/vaapisink/Makefile.am diff --git a/sys/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c similarity index 100% rename from sys/vaapisink/gstvaapisink.c rename to gst/vaapisink/gstvaapisink.c diff --git a/sys/vaapisink/gstvaapisink.h b/gst/vaapisink/gstvaapisink.h similarity index 100% rename from sys/vaapisink/gstvaapisink.h rename to gst/vaapisink/gstvaapisink.h From 35b6198d554e8161c36187151e5696702653ce40 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 07:50:11 +0000 Subject: [PATCH 0233/3781] Fix leftover during migration. --- docs/reference/plugins/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/plugins/Makefile.am b/docs/reference/plugins/Makefile.am index 90595ff947..8f10c708b0 100644 --- a/docs/reference/plugins/Makefile.am +++ b/docs/reference/plugins/Makefile.am @@ -18,7 +18,7 @@ DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml # gtk-doc will search all .c & .h files beneath here for inline comments # documenting the functions and macros. # e.g. DOC_SOURCE_DIR=../../../gtk -DOC_SOURCE_DIR = $(top_srcdir)/sys +DOC_SOURCE_DIR = $(top_srcdir)/gst # Extra options to pass to gtkdoc-scangobj. Not normally needed. SCANGOBJ_OPTIONS = --type-init-func="gst_init(NULL, NULL)" From a1dbe90077b29885695c54a1ce615d72ca39e83d Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 08:11:50 +0000 Subject: [PATCH 0234/3781] Add gst_vaapi_surface_query_status() wrapper. --- docs/reference/libs/libs-sections.txt | 2 ++ gst-libs/gst/vaapi/gstvaapisurface.c | 36 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 27 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.c | 39 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 3 +++ 5 files changed, 107 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index b6eacd54f1..9847492370 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -308,6 +308,7 @@ GST_VAAPI_IMAGE_GET_CLASS
gstvaapisurface GstVaapiChromaType +GstVaapiSurfaceStatus GstVaapiSurfaceRenderFlags GstVaapiSurface GstVaapiSurface @@ -324,6 +325,7 @@ gst_vaapi_surface_put_image gst_vaapi_surface_associate_subpicture gst_vaapi_surface_deassociate_subpicture gst_vaapi_surface_sync +gst_vaapi_surface_query_status GST_VAAPI_SURFACE GST_VAAPI_IS_SURFACE diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index c1456df7f1..635f111bc8 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -753,3 +753,39 @@ gst_vaapi_surface_sync(GstVaapiSurface *surface) return TRUE; } + +/** + * gst_vaapi_surface_query_status: + * @surface: a #GstVaapiSurface + * @pstatus: return location for the #GstVaapiSurfaceStatus + * + * Finds out any pending operations on the @surface. The + * #GstVaapiSurfaceStatus flags are returned into @pstatus. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_surface_query_status( + GstVaapiSurface *surface, + GstVaapiSurfaceStatus *pstatus +) +{ + VASurfaceStatus surface_status; + VAStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + + GST_VAAPI_OBJECT_LOCK_DISPLAY(surface); + status = vaQuerySurfaceStatus( + GST_VAAPI_OBJECT_VADISPLAY(surface), + GST_VAAPI_OBJECT_ID(surface), + &surface_status + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(surface); + if (!vaapi_check_status(status, "vaQuerySurfaceStatus()")) + return FALSE; + + if (pstatus) + *pstatus = to_GstVaapiSurfaceStatus(surface_status); + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 5893d72f06..668af90e46 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -29,6 +29,7 @@ G_BEGIN_DECLS typedef enum _GstVaapiChromaType GstVaapiChromaType; +typedef enum _GstVaapiSurfaceStatus GstVaapiSurfaceStatus; typedef enum _GstVaapiSurfaceRenderFlags GstVaapiSurfaceRenderFlags; /** @@ -45,6 +46,26 @@ enum _GstVaapiChromaType { GST_VAAPI_CHROMA_TYPE_YUV444 }; +/** + * GstVaapiSurfaceStatus: + * @GST_VAAPI_SURFACE_STATUS_IDLE: + * the surface is not being rendered or displayed + * @GST_VAAPI_SURFACE_STATUS_RENDERING: + * the surface is used for rendering (decoding to the surface in progress) + * @GST_VAAPI_SURFACE_STATUS_DISPLAYING: + * the surface is being displayed to screen + * @GST_VAAPI_SURFACE_STATUS_SKIPPED: + * indicates a skipped frame during encode + * + * The set of all surface status for #GstVaapiSurface. + */ +enum _GstVaapiSurfaceStatus { + GST_VAAPI_SURFACE_STATUS_IDLE = 1 << 0, + GST_VAAPI_SURFACE_STATUS_RENDERING = 1 << 1, + GST_VAAPI_SURFACE_STATUS_DISPLAYING = 1 << 2, + GST_VAAPI_SURFACE_STATUS_SKIPPED = 1 << 3 +}; + /** * GstVaapiSurfaceRenderFlags * @GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: @@ -178,6 +199,12 @@ gst_vaapi_surface_deassociate_subpicture( gboolean gst_vaapi_surface_sync(GstVaapiSurface *surface); +gboolean +gst_vaapi_surface_query_status( + GstVaapiSurface *surface, + GstVaapiSurfaceStatus *pstatus +); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 63e0229aa6..2000433b94 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -128,3 +128,42 @@ guint get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(guint flags) return va_fields|va_csc; } + +/** + * to_GstVaapiSurfaceStatus: + * @flags: the #GstVaapiSurfaceStatus flags to translate + * + * Converts vaQuerySurfaceStatus() @flags to #GstVaapiSurfaceStatus + * flags. + * + * Return value: the #GstVaapiSurfaceStatus flags + */ +guint to_GstVaapiSurfaceStatus(guint va_flags) +{ + guint flags; + const guint va_flags_mask = (VASurfaceReady| + VASurfaceRendering| + VASurfaceDisplaying); + + /* Check for core status */ + switch (va_flags & va_flags_mask) { + case VASurfaceReady: + flags = GST_VAAPI_SURFACE_STATUS_IDLE; + break; + case VASurfaceRendering: + flags = GST_VAAPI_SURFACE_STATUS_RENDERING; + break; + case VASurfaceDisplaying: + flags = GST_VAAPI_SURFACE_STATUS_DISPLAYING; + break; + default: + flags = 0; + break; + } + + /* Check for encoder status */ + if (va_flags & VASurfaceSkipped) + flags |= GST_VAAPI_SURFACE_STATUS_SKIPPED; + + return flags; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 804cec0de0..7363947561 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -53,4 +53,7 @@ const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) guint get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(guint flags) attribute_hidden; +guint to_GstVaapiSurfaceStatus(guint va_flags) + attribute_hidden; + #endif /* GST_VAAPI_UTILS_H */ From c58a45f099eb188b5284a7f96b1bbc6d7eb3b5b9 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 08:13:34 +0000 Subject: [PATCH 0235/3781] Use a shorter function name. --- gst-libs/gst/vaapi/gstvaapitexture.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils.c | 5 +++-- gst-libs/gst/vaapi/gstvaapiutils.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 3932fbed93..b86f84285c 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -504,7 +504,7 @@ gst_vaapi_texture_put_surface( GST_VAAPI_OBJECT_VADISPLAY(texture), texture->priv->gl_surface, GST_VAAPI_OBJECT_ID(surface), - get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(flags) + from_GstVaapiSurfaceRenderFlags(flags) ); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 2000433b94..c40bc6e1db 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -101,12 +101,13 @@ const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) } /** - * get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags: + * from_GstVaapiSurfaceRenderFlags: + * @flags: the #GstVaapiSurfaceRenderFlags * * Converts #GstVaapiSurfaceRenderFlags to flags suitable for * vaPutSurface(). */ -guint get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(guint flags) +guint from_GstVaapiSurfaceRenderFlags(guint flags) { guint va_fields = 0, va_csc = 0; diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 7363947561..f5cd4b9b2c 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -50,7 +50,7 @@ const char *string_of_VAProfile(VAProfile profile) const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) attribute_hidden; -guint get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(guint flags) +guint from_GstVaapiSurfaceRenderFlags(guint flags) attribute_hidden; guint to_GstVaapiSurfaceStatus(guint va_flags) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index ab8a47d913..f10860c581 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -433,7 +433,7 @@ gst_vaapi_window_x11_render( dst_rect->width, dst_rect->height, NULL, 0, - get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(flags) + from_GstVaapiSurfaceRenderFlags(flags) ); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (!vaapi_check_status(status, "vaPutSurface()")) From 4ff830812fb1c99648d9a215493db3f349153bb2 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 12:55:27 +0000 Subject: [PATCH 0236/3781] Cosmetics. Make vaapi_check_status() use GST_DEBUG() for error messages. --- gst-libs/gst/vaapi/gstvaapiutils.c | 26 +++++++++++--------------- gst-libs/gst/vaapi/gstvaapiutils.h | 13 ++++++------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index c40bc6e1db..f222f10eca 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -25,24 +25,18 @@ #include #include -/* Debug output */ -void vaapi_dprintf(const char *format, ...) -{ - va_list args; - va_start(args, format); - fprintf(stdout, "[GstVaapi] "); - vfprintf(stdout, format, args); - va_end(args); -} +#define DEBUG 1 +#include "gstvaapidebug.h" /* Check VA status for success or print out an error */ -int vaapi_check_status(VAStatus status, const char *msg) +gboolean +vaapi_check_status(VAStatus status, const char *msg) { if (status != VA_STATUS_SUCCESS) { - vaapi_dprintf("%s: %s\n", msg, vaErrorStr(status)); - return 0; + GST_DEBUG("%s: %s", msg, vaErrorStr(status)); + return FALSE; } - return 1; + return TRUE; } /* Return a string representation of a FOURCC */ @@ -107,7 +101,8 @@ const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) * Converts #GstVaapiSurfaceRenderFlags to flags suitable for * vaPutSurface(). */ -guint from_GstVaapiSurfaceRenderFlags(guint flags) +guint +from_GstVaapiSurfaceRenderFlags(guint flags) { guint va_fields = 0, va_csc = 0; @@ -139,7 +134,8 @@ guint from_GstVaapiSurfaceRenderFlags(guint flags) * * Return value: the #GstVaapiSurfaceStatus flags */ -guint to_GstVaapiSurfaceStatus(guint va_flags) +guint +to_GstVaapiSurfaceStatus(guint va_flags) { guint flags; const guint va_flags_mask = (VASurfaceReady| diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index f5cd4b9b2c..2ac019715f 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -30,12 +30,9 @@ # include #endif -/** Debug output */ -void vaapi_dprintf(const char *format, ...) - attribute_hidden; - /** Check VA status for success or print out an error */ -int vaapi_check_status(VAStatus status, const char *msg) +gboolean +vaapi_check_status(VAStatus status, const char *msg) attribute_hidden; /** Return a string representation of a FOURCC */ @@ -50,10 +47,12 @@ const char *string_of_VAProfile(VAProfile profile) const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) attribute_hidden; -guint from_GstVaapiSurfaceRenderFlags(guint flags) +guint +from_GstVaapiSurfaceRenderFlags(guint flags) attribute_hidden; -guint to_GstVaapiSurfaceStatus(guint va_flags) +guint +to_GstVaapiSurfaceStatus(guint va_flags) attribute_hidden; #endif /* GST_VAAPI_UTILS_H */ From 502dec7c1cd6533dec99452a7422a3dc2f351259 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 12:59:15 +0000 Subject: [PATCH 0237/3781] Add TFP and FBO helpers. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 616 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_glx.h | 102 ++++ 2 files changed, 718 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 5947ed7bf8..93e846508f 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -18,13 +18,38 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#define _GNU_SOURCE 1 /* RTLD_DEFAULT */ #include "config.h" +#include #include +#include #include "gstvaapiutils_glx.h" +#include "gstvaapiutils_x11.h" #define DEBUG 1 #include "gstvaapidebug.h" +/** Lookup for substring NAME in string EXT using SEP as separators */ +static gboolean +find_string(const char *name, const char *ext, const char *sep) +{ + const char *end; + int name_len, n; + + if (!name || !ext) + return FALSE; + + end = ext + strlen(ext); + name_len = strlen(name); + while (ext < end) { + n = strcspn(ext, sep); + if (n == name_len && strncmp(name, ext, n) == 0) + return TRUE; + ext += (n + 1); + } + return FALSE; +} + /** * gl_get_error_string: * @error: an OpenGL error enumeration @@ -415,3 +440,594 @@ gl_create_texture(GLenum target, GLenum format, guint width, guint height) gl_unbind_texture(&ts); return texture; } + +/** + * get_proc_address: + * @name: the name of the OpenGL extension function to lookup + * + * Returns the specified OpenGL extension function + * + * Return value: the OpenGL extension matching @name, or %NULL if none + * was found + */ +typedef void (*GLFuncPtr)(void); +typedef GLFuncPtr (*GLXGetProcAddressProc)(const char *); + +static GLFuncPtr +get_proc_address_default(const char *name) +{ + return NULL; +} + +static GLXGetProcAddressProc +get_proc_address_func(void) +{ + GLXGetProcAddressProc get_proc_func; + + dlerror(); + get_proc_func = (GLXGetProcAddressProc) + dlsym(RTLD_DEFAULT, "glXGetProcAddress"); + if (!dlerror()) + return get_proc_func; + + get_proc_func = (GLXGetProcAddressProc) + dlsym(RTLD_DEFAULT, "glXGetProcAddressARB"); + if (!dlerror()) + return get_proc_func; + + return get_proc_address_default; +} + +static inline GLFuncPtr +get_proc_address(const char *name) +{ + static GLXGetProcAddressProc get_proc_func = NULL; + if (!get_proc_func) + get_proc_func = get_proc_address_func(); + return get_proc_func(name); +} + +/** + * gl_init_vtable: + * + * Initializes the global #GLVTable. + * + * Return value: the #GLVTable filled in with OpenGL extensions, or + * %NULL on error. + */ +static GLVTable gl_vtable_static; + +static GLVTable * +gl_init_vtable(void) +{ + GLVTable * const gl_vtable = &gl_vtable_static; + const gchar *gl_extensions = (const gchar *)glGetString(GL_EXTENSIONS); + gboolean has_extension; + + /* GLX_EXT_texture_from_pixmap */ + gl_vtable->glx_bind_tex_image = (PFNGLXBINDTEXIMAGEEXTPROC) + get_proc_address("glXBindTexImageEXT"); + if (!gl_vtable->glx_bind_tex_image) + return NULL; + gl_vtable->glx_release_tex_image = (PFNGLXRELEASETEXIMAGEEXTPROC) + get_proc_address("glXReleaseTexImageEXT"); + if (!gl_vtable->glx_release_tex_image) + return NULL; + + /* GL_ARB_framebuffer_object */ + has_extension = ( + find_string("GL_ARB_framebuffer_object", gl_extensions, " ") || + find_string("GL_EXT_framebuffer_object", gl_extensions, " ") + ); + if (has_extension) { + gl_vtable->gl_gen_framebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC) + get_proc_address("glGenFramebuffersEXT"); + if (!gl_vtable->gl_gen_framebuffers) + return NULL; + gl_vtable->gl_delete_framebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC) + get_proc_address("glDeleteFramebuffersEXT"); + if (!gl_vtable->gl_delete_framebuffers) + return NULL; + gl_vtable->gl_bind_framebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC) + get_proc_address("glBindFramebufferEXT"); + if (!gl_vtable->gl_bind_framebuffer) + return NULL; + gl_vtable->gl_gen_renderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC) + get_proc_address("glGenRenderbuffersEXT"); + if (!gl_vtable->gl_gen_renderbuffers) + return NULL; + gl_vtable->gl_delete_renderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC) + get_proc_address("glDeleteRenderbuffersEXT"); + if (!gl_vtable->gl_delete_renderbuffers) + return NULL; + gl_vtable->gl_bind_renderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC) + get_proc_address("glBindRenderbufferEXT"); + if (!gl_vtable->gl_bind_renderbuffer) + return NULL; + gl_vtable->gl_renderbuffer_storage = (PFNGLRENDERBUFFERSTORAGEEXTPROC) + get_proc_address("glRenderbufferStorageEXT"); + if (!gl_vtable->gl_renderbuffer_storage) + return NULL; + gl_vtable->gl_framebuffer_renderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) + get_proc_address("glFramebufferRenderbufferEXT"); + if (!gl_vtable->gl_framebuffer_renderbuffer) + return NULL; + gl_vtable->gl_framebuffer_texture_2d = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) + get_proc_address("glFramebufferTexture2DEXT"); + if (!gl_vtable->gl_framebuffer_texture_2d) + return NULL; + gl_vtable->gl_check_framebuffer_status = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) + get_proc_address("glCheckFramebufferStatusEXT"); + if (!gl_vtable->gl_check_framebuffer_status) + return NULL; + gl_vtable->has_framebuffer_object = TRUE; + } + + /* GL_ARB_fragment_program */ + has_extension = ( + find_string("GL_ARB_fragment_program", gl_extensions, " ") + ); + if (has_extension) { + gl_vtable->gl_gen_programs = (PFNGLGENPROGRAMSARBPROC) + get_proc_address("glGenProgramsARB"); + if (!gl_vtable->gl_gen_programs) + return NULL; + gl_vtable->gl_delete_programs = (PFNGLDELETEPROGRAMSARBPROC) + get_proc_address("glDeleteProgramsARB"); + if (!gl_vtable->gl_delete_programs) + return NULL; + gl_vtable->gl_bind_program = (PFNGLBINDPROGRAMARBPROC) + get_proc_address("glBindProgramARB"); + if (!gl_vtable->gl_bind_program) + return NULL; + gl_vtable->gl_program_string = (PFNGLPROGRAMSTRINGARBPROC) + get_proc_address("glProgramStringARB"); + if (!gl_vtable->gl_program_string) + return NULL; + gl_vtable->gl_get_program_iv = (PFNGLGETPROGRAMIVARBPROC) + get_proc_address("glGetProgramivARB"); + if (!gl_vtable->gl_get_program_iv) + return NULL; + gl_vtable->gl_program_local_parameter_4fv = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) + get_proc_address("glProgramLocalParameter4fvARB"); + if (!gl_vtable->gl_program_local_parameter_4fv) + return NULL; + gl_vtable->has_fragment_program = TRUE; + } + + /* GL_ARB_multitexture */ + has_extension = ( + find_string("GL_ARB_multitexture", gl_extensions, " ") + ); + if (has_extension) { + gl_vtable->gl_active_texture = (PFNGLACTIVETEXTUREPROC) + get_proc_address("glActiveTextureARB"); + if (!gl_vtable->gl_active_texture) + return NULL; + gl_vtable->gl_multi_tex_coord_2f = (PFNGLMULTITEXCOORD2FPROC) + get_proc_address("glMultiTexCoord2fARB"); + if (!gl_vtable->gl_multi_tex_coord_2f) + return NULL; + gl_vtable->has_multitexture = TRUE; + } + return gl_vtable; +} + +/** + * gl_get_vtable: + * + * Retrieves a VTable for OpenGL extensions. + * + * Return value: VTable for OpenGL extensions + */ +GLVTable * +gl_get_vtable(void) +{ + static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + static gboolean gl_vtable_init = TRUE; + static GLVTable *gl_vtable = NULL; + + g_static_mutex_lock(&mutex); + if (gl_vtable_init) { + gl_vtable_init = FALSE; + gl_vtable = gl_init_vtable(); + } + g_static_mutex_unlock(&mutex); + return gl_vtable; +} + +/** + * gl_create_pixmap_object: + * @dpy: an X11 #Display + * @width: the request width, in pixels + * @height: the request height, in pixels + * + * Creates a #GLPixmapObject of the specified dimensions. This + * requires the GLX_EXT_texture_from_pixmap extension. + * + * Return value: the newly created #GLPixmapObject object + */ +GLPixmapObject * +gl_create_pixmap_object(Display *dpy, guint width, guint height) +{ + GLVTable * const gl_vtable = gl_get_vtable(); + GLPixmapObject *pixo; + GLXFBConfig *fbconfig; + int screen; + Window rootwin; + XWindowAttributes wattr; + int *attr; + int n_fbconfig_attrs; + + int fbconfig_attrs[32] = { + GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, + GLX_DOUBLEBUFFER, GL_TRUE, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_X_RENDERABLE, GL_TRUE, + GLX_Y_INVERTED_EXT, GL_TRUE, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GL_NONE, + }; + + int pixmap_attrs[10] = { + GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, + GLX_MIPMAP_TEXTURE_EXT, GL_FALSE, + GL_NONE, + }; + + if (!gl_vtable) + return NULL; + + screen = DefaultScreen(dpy); + rootwin = RootWindow(dpy, screen); + + /* XXX: this won't work for different displays */ + if (!gl_vtable->has_texture_from_pixmap) { + const char *glx_extensions; + int glx_major, glx_minor; + glx_extensions = glXQueryExtensionsString(dpy, screen); + if (!glx_extensions) + return NULL; + if (!find_string("GLX_EXT_texture_from_pixmap", glx_extensions, " ")) + return NULL; + if (!glXQueryVersion(dpy, &glx_major, &glx_minor)) + return NULL; + if (glx_major < 0 || (glx_major == 1 && glx_minor < 3)) /* 1.3 */ + return NULL; + gl_vtable->has_texture_from_pixmap = TRUE; + } + + pixo = calloc(1, sizeof(*pixo)); + if (!pixo) + return NULL; + + pixo->dpy = dpy; + pixo->width = width; + pixo->height = height; + pixo->pixmap = None; + pixo->glx_pixmap = None; + pixo->is_bound = FALSE; + + XGetWindowAttributes(dpy, rootwin, &wattr); + pixo->pixmap = XCreatePixmap(dpy, rootwin, width, height, wattr.depth); + if (!pixo->pixmap) + goto error; + + /* Initialize FBConfig attributes */ + for (attr = fbconfig_attrs; *attr != GL_NONE; attr += 2) + ; + *attr++ = GLX_DEPTH_SIZE; *attr++ = wattr.depth; + if (wattr.depth == 32) { + *attr++ = GLX_ALPHA_SIZE; *attr++ = 8; + *attr++ = GLX_BIND_TO_TEXTURE_RGBA_EXT; *attr++ = GL_TRUE; + } + else { + *attr++ = GLX_BIND_TO_TEXTURE_RGB_EXT; *attr++ = GL_TRUE; + } + *attr++ = GL_NONE; + + fbconfig = glXChooseFBConfig( + dpy, + screen, + fbconfig_attrs, &n_fbconfig_attrs + ); + if (!fbconfig) + goto error; + + /* Initialize GLX Pixmap attrutes */ + for (attr = pixmap_attrs; *attr != GL_NONE; attr += 2) + ; + *attr++ = GLX_TEXTURE_FORMAT_EXT; + if (wattr.depth == 32) + *attr++ = GLX_TEXTURE_FORMAT_RGBA_EXT; + else + *attr++ = GLX_TEXTURE_FORMAT_RGB_EXT; + *attr++ = GL_NONE; + + x11_trap_errors(); + pixo->glx_pixmap = glXCreatePixmap(dpy, fbconfig[0], pixo->pixmap, pixmap_attrs); + free(fbconfig); + if (x11_untrap_errors() != 0) + goto error; + return pixo; + +error: + gl_destroy_pixmap_object(pixo); + return NULL; +} + +/** + * gl_destroy_pixmap_object: + * @pixo: a #GLPixmapObject + * + * Destroys the #GLPixmapObject object. + */ +void +gl_destroy_pixmap_object(GLPixmapObject *pixo) +{ + if (!pixo) + return; + + gl_unbind_pixmap_object(pixo); + + if (pixo->glx_pixmap) { + glXDestroyPixmap(pixo->dpy, pixo->glx_pixmap); + pixo->glx_pixmap = None; + } + + if (pixo->pixmap) { + XFreePixmap(pixo->dpy, pixo->pixmap); + pixo->pixmap = None; + } + free(pixo); +} + +/** + * gl_bind_pixmap_object: + * @pixo: a #GLPixmapObject + * + * Defines a two-dimensional texture image. The texture image is taken + * from the @pixo pixmap and need not be copied. The texture target, + * format and size are derived from attributes of the @pixo pixmap. + * + * Return value: %TRUE on success + */ +gboolean +gl_bind_pixmap_object(GLPixmapObject *pixo) +{ + GLVTable * const gl_vtable = gl_get_vtable(); + + if (pixo->is_bound) + return TRUE; + + x11_trap_errors(); + gl_vtable->glx_bind_tex_image( + pixo->dpy, + pixo->glx_pixmap, + GLX_FRONT_LEFT_EXT, + NULL + ); + XSync(pixo->dpy, False); + if (x11_untrap_errors() != 0) { + GST_DEBUG("failed to bind pixmap"); + return FALSE; + } + + pixo->is_bound = TRUE; + return TRUE; +} + +/** + * gl_unbind_pixmap_object: + * @pixo: a #GLPixmapObject + * + * Releases a color buffers that is being used as a texture. + * + * Return value: %TRUE on success + */ +gboolean +gl_unbind_pixmap_object(GLPixmapObject *pixo) +{ + GLVTable * const gl_vtable = gl_get_vtable(); + + if (!pixo->is_bound) + return TRUE; + + x11_trap_errors(); + gl_vtable->glx_release_tex_image( + pixo->dpy, + pixo->glx_pixmap, + GLX_FRONT_LEFT_EXT + ); + XSync(pixo->dpy, False); + if (x11_untrap_errors() != 0) { + GST_DEBUG("failed to release pixmap"); + return FALSE; + } + + pixo->is_bound = FALSE; + return TRUE; +} + +/** + * gl_create_framebuffer_object: + * @target: the target to which the texture is bound + * @texture: the GL texture to hold the framebuffer + * @width: the requested width, in pixels + * @height: the requested height, in pixels + * + * Creates an FBO with the specified texture and size. + * + * Return value: the newly created #GLFramebufferObject, or %NULL if + * an error occurred + */ +GLFramebufferObject * +gl_create_framebuffer_object( + GLenum target, + GLuint texture, + guint width, + guint height +) +{ + GLVTable * const gl_vtable = gl_get_vtable(); + GLFramebufferObject *fbo; + GLTextureState ts; + GLenum status; + gboolean texture_was_bound; + + if (!gl_vtable || !gl_vtable->has_framebuffer_object) + return NULL; + + /* XXX: we only support GL_TEXTURE_2D at this time */ + if (target != GL_TEXTURE_2D) + return NULL; + + fbo = calloc(1, sizeof(*fbo)); + if (!fbo) + return NULL; + + fbo->width = width; + fbo->height = height; + fbo->fbo = 0; + fbo->fbo_buffer = 0; + fbo->fbo_target = target; + fbo->fbo_texture = 0; + fbo->old_fbo = 0; + fbo->is_bound = FALSE; + + fbo->fbo_texture = gl_create_texture(target, GL_BGRA, width, height); + if (!fbo->fbo_texture) + goto error; + + gl_get_param(GL_FRAMEBUFFER_BINDING, &fbo->old_fbo); + gl_vtable->gl_gen_framebuffers(1, &fbo->fbo); + gl_vtable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo->fbo); + gl_vtable->gl_gen_renderbuffers(1, &fbo->fbo_buffer); + gl_vtable->gl_bind_renderbuffer(GL_RENDERBUFFER_EXT, fbo->fbo_buffer); + + texture_was_bound = gl_bind_texture(&ts, target, texture); + if (texture_was_bound) { + gl_vtable->gl_framebuffer_texture_2d( + GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + target, texture, + 0 + ); + gl_unbind_texture(&ts); + } + status = gl_vtable->gl_check_framebuffer_status(GL_DRAW_FRAMEBUFFER_EXT); + gl_vtable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo->old_fbo); + if (!texture_was_bound || status != GL_FRAMEBUFFER_COMPLETE_EXT) + goto error; + return fbo; + +error: + gl_destroy_framebuffer_object(fbo); + return NULL; +} + +/** + * gl_destroy_framebuffer_object: + * @fbo: a #GLFramebufferObject + * + * Destroys the @fbo object. + */ +void +gl_destroy_framebuffer_object(GLFramebufferObject *fbo) +{ + GLVTable * const gl_vtable = gl_get_vtable(); + + if (!fbo) + return; + + gl_unbind_framebuffer_object(fbo); + + if (fbo->fbo_texture) { + glDeleteTextures(1, &fbo->fbo_texture); + fbo->fbo_texture = 0; + } + + if (fbo->fbo_buffer) { + gl_vtable->gl_delete_renderbuffers(1, &fbo->fbo_buffer); + fbo->fbo_buffer = 0; + } + + if (fbo->fbo) { + gl_vtable->gl_delete_framebuffers(1, &fbo->fbo); + fbo->fbo = 0; + } + free(fbo); +} + +/** + * gl_bind_framebuffer_object: + * @fbo: a #GLFramebufferObject + * + * Binds @fbo object. + * + * Return value: %TRUE on success + */ +gboolean +gl_bind_framebuffer_object(GLFramebufferObject *fbo) +{ + GLVTable * const gl_vtable = gl_get_vtable(); + const guint width = fbo->width; + const guint height = fbo->height; + + const guint attribs = (GL_VIEWPORT_BIT| + GL_CURRENT_BIT| + GL_ENABLE_BIT| + GL_TEXTURE_BIT| + GL_COLOR_BUFFER_BIT); + + if (fbo->is_bound) + return TRUE; + + gl_get_param(GL_FRAMEBUFFER_BINDING, &fbo->old_fbo); + gl_vtable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo->fbo); + glPushAttrib(attribs); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glViewport(0, 0, width, height); + glTranslatef(-1.0f, -1.0f, 0.0f); + glScalef(2.0f / width, 2.0f / height, 1.0f); + + if (!gl_bind_texture(&fbo->old_texture, fbo->fbo_target, fbo->fbo_texture)) + return FALSE; + + fbo->is_bound = TRUE; + return TRUE; +} + +/** + * gl_unbind_framebuffer_object: + * @fbo: a #GLFramebufferObject + * + * Releases @fbo object. + * + * Return value: %TRUE on success + */ +gboolean +gl_unbind_framebuffer_object(GLFramebufferObject *fbo) +{ + GLVTable * const gl_vtable = gl_get_vtable(); + + if (!fbo->is_bound) + return TRUE; + + glPopAttrib(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + gl_vtable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo->old_fbo); + + fbo->is_bound = FALSE; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 69d0048c37..3c83da2374 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -23,9 +23,20 @@ #include "config.h" #include +#include #include +#include #include +#if GLX_GLXEXT_VERSION < 18 +typedef void (*PFNGLXBINDTEXIMAGEEXTPROC)(Display *, GLXDrawable, int, const int *); +typedef void (*PFNGLXRELEASETEXIMAGEEXTPROC)(Display *, GLXDrawable, int); +#endif + +#ifndef GL_FRAMEBUFFER_BINDING +#define GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_EXT +#endif + const char * gl_get_error_string(GLenum error) attribute_hidden; @@ -88,4 +99,95 @@ GLuint gl_create_texture(GLenum target, GLenum format, guint width, guint height) attribute_hidden; +typedef struct _GLVTable GLVTable; +struct _GLVTable { + PFNGLXBINDTEXIMAGEEXTPROC glx_bind_tex_image; + PFNGLXRELEASETEXIMAGEEXTPROC glx_release_tex_image; + PFNGLGENFRAMEBUFFERSEXTPROC gl_gen_framebuffers; + PFNGLDELETEFRAMEBUFFERSEXTPROC gl_delete_framebuffers; + PFNGLBINDFRAMEBUFFEREXTPROC gl_bind_framebuffer; + PFNGLGENRENDERBUFFERSEXTPROC gl_gen_renderbuffers; + PFNGLDELETERENDERBUFFERSEXTPROC gl_delete_renderbuffers; + PFNGLBINDRENDERBUFFEREXTPROC gl_bind_renderbuffer; + PFNGLRENDERBUFFERSTORAGEEXTPROC gl_renderbuffer_storage; + PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC gl_framebuffer_renderbuffer; + PFNGLFRAMEBUFFERTEXTURE2DEXTPROC gl_framebuffer_texture_2d; + PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC gl_check_framebuffer_status; + PFNGLGENPROGRAMSARBPROC gl_gen_programs; + PFNGLDELETEPROGRAMSARBPROC gl_delete_programs; + PFNGLBINDPROGRAMARBPROC gl_bind_program; + PFNGLPROGRAMSTRINGARBPROC gl_program_string; + PFNGLGETPROGRAMIVARBPROC gl_get_program_iv; + PFNGLPROGRAMLOCALPARAMETER4FVARBPROC gl_program_local_parameter_4fv; + PFNGLACTIVETEXTUREPROC gl_active_texture; + PFNGLMULTITEXCOORD2FPROC gl_multi_tex_coord_2f; + guint has_texture_from_pixmap : 1; + guint has_framebuffer_object : 1; + guint has_fragment_program : 1; + guint has_multitexture : 1; +}; + +GLVTable * +gl_get_vtable(void) + attribute_hidden; + +typedef struct _GLPixmapObject GLPixmapObject; +struct _GLPixmapObject { + Display *dpy; + guint width; + guint height; + Pixmap pixmap; + GLXPixmap glx_pixmap; + guint is_bound : 1; +}; + +GLPixmapObject * +gl_create_pixmap_object(Display *dpy, guint width, guint height) + attribute_hidden; + +void +gl_destroy_pixmap_object(GLPixmapObject *pixo) + attribute_hidden; + +gboolean +gl_bind_pixmap_object(GLPixmapObject *pixo) + attribute_hidden; + +gboolean +gl_unbind_pixmap_object(GLPixmapObject *pixo) + attribute_hidden; + +typedef struct _GLFramebufferObject GLFramebufferObject; +struct _GLFramebufferObject { + guint width; + guint height; + GLuint fbo; + GLuint fbo_buffer; + GLenum fbo_target; + GLuint fbo_texture; + GLuint old_fbo; + GLTextureState old_texture; + guint is_bound : 1; +}; + +GLFramebufferObject * +gl_create_framebuffer_object( + GLenum target, + GLuint texture, + guint width, + guint height +) attribute_hidden; + +void +gl_destroy_framebuffer_object(GLFramebufferObject *fbo) + attribute_hidden; + +gboolean +gl_bind_framebuffer_object(GLFramebufferObject *fbo) + attribute_hidden; + +gboolean +gl_unbind_framebuffer_object(GLFramebufferObject *fbo) + attribute_hidden; + #endif /* GST_VAAPI_UTILS_GLX_H */ From 28f73fb582b5bd1913dc97fb019fa11035e44c2b Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 13:01:34 +0000 Subject: [PATCH 0238/3781] Enable build without VA/GLX extensions. i.e. fallback to TFP + FBO. --- configure.ac | 43 +++-- gst-libs/gst/vaapi/gstvaapicompat.h | 6 + gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 1 - gst-libs/gst/vaapi/gstvaapitexture.c | 209 ++++++++++++++++++----- tests/test-display.c | 6 + 6 files changed, 215 insertions(+), 51 deletions(-) diff --git a/configure.ac b/configure.ac index e6ed60c6ad..f008506112 100644 --- a/configure.ac +++ b/configure.ac @@ -75,6 +75,11 @@ AC_ARG_ENABLE(glx, [enable OpenGL/X11 @<:@default=yes@:>@]), [], [enable_glx="yes"]) +AC_ARG_ENABLE(vaapi-glx, + AC_HELP_STRING([--enable-vaapi-glx], + [enable VA/GLX extensions @<:@default=yes@:>@]), + [], [enable_vaapi_glx="yes"]) + AC_ARG_ENABLE(vaapisink-glx, AC_HELP_STRING([--enable-vaapisink-glx], [enable OpenGL/X11 to vaapisink @<:@default=yes@:>@]), @@ -220,15 +225,20 @@ if test "$ac_cv_have_vaapi_x11" = "no"; then fi AC_SUBST(LIBVA_X11_PKGNAME) -dnl ... VA-API >= 0.31 or -sds -LIBVA_GLX_PKGNAME="libva-glx" -PKG_CHECK_MODULES(LIBVA_GLX, [$LIBVA_GLX_PKGNAME], - [ac_cv_have_vaapi_glx="yes"], - [ac_cv_have_vaapi_glx="no"] -) -if test "$ac_cv_have_vaapi_glx" = "no"; then - AC_MSG_WARN([could not find VA/GLX extensions. Disabling GLX support]) - USE_GLX=0 +dnl ... VA-API >= 0.31 or -sds (VA/GLX extensions) +USE_VAAPI_GLX=0 +if test $USE_GLX -eq 1; then + if test "$enable_vaapi_glx" = "yes"; then + LIBVA_GLX_PKGNAME="libva-glx" + PKG_CHECK_MODULES(LIBVA_GLX, [$LIBVA_GLX_PKGNAME], + [ac_cv_have_vaapi_glx="yes" USE_VAAPI_GLX=1], + [ac_cv_have_vaapi_glx="no"] + ) + fi + if test $USE_VAAPI_GLX -eq 0; then + AC_MSG_WARN([VA/GLX not found or disabled. Fallbacking to TFP+FBO]) + LIBVA_GLX_PKGNAME="$LIBVA_X11_PKGNAME" + fi fi AC_SUBST(LIBVA_GLX_PKGNAME) @@ -242,9 +252,14 @@ else USE_VAAPISINK_GLX=0 fi -AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) +AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, + [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) +AC_DEFINE_UNQUOTED(USE_VAAPI_GLX, $USE_VAAPI_GLX, + [Defined to 1 if VA/GLX is enabled]) +AM_CONDITIONAL(USE_VAAPI_GLX, test $USE_VAAPI_GLX -eq 1) + AC_DEFINE_UNQUOTED(USE_VAAPISINK_GLX, $USE_VAAPISINK_GLX, [Defined to 1 to enable GLX support to vaapisink]) AM_CONDITIONAL(USE_VAAPISINK_GLX, test $USE_VAAPISINK_GLX -eq 1) @@ -303,10 +318,14 @@ pkgconfig/gstreamer-vaapi-x11.pc.in ]) dnl Print summary +conf_glx=$(test $USE_GLX -eq 1 && echo yes || echo no) +conf_vaapi_glx=$(test $USE_VAAPI_GLX -eq 1 && echo yes || echo no) +conf_vaapisink_glx=$(test $USE_VAAPISINK_GLX -eq 1 && echo yes || echo no) echo echo $PACKAGE configuration summary: echo echo VA-API version ................... : $VA_VERSION_STR -echo GLX support ...................... : $(test $USE_GLX -eq 1 && echo yes || echo no) -echo Build vaapisink with OpenGL ...... : $(test $USE_VAAPISINK_GLX -eq 1 && echo yes || echo no) +echo GLX support ...................... : $conf_glx +echo VA/GLX support ................... : $conf_vaapi_glx +echo VaapiSink/GL ..................... : $conf_vaapisink_glx echo diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index fb7d2129de..158cc78566 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -28,6 +28,12 @@ # include #endif +#if USE_VAAPI_GLX +# include +#else +# define vaGetDisplayGLX(dpy) vaGetDisplay(dpy) +#endif + /* Check for VA version */ #ifndef VA_CHECK_VERSION #define VA_MAJOR_VERSION 0 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 7a078cf7e2..c4722d3081 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -24,6 +24,7 @@ */ #include "config.h" +#include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapidisplay_glx.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index 6206f1e9c5..6f43368fc9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -23,7 +23,6 @@ #include #include -#include #include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index b86f84285c..2022c293f1 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -24,10 +24,11 @@ */ #include "config.h" -#include #include "gstvaapitexture.h" +#include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapiutils_glx.h" +#include "gstvaapidisplay_glx.h" #include "gstvaapiobject_priv.h" #define DEBUG 1 @@ -41,13 +42,15 @@ G_DEFINE_TYPE(GstVaapiTexture, gst_vaapi_texture, GST_VAAPI_TYPE_OBJECT); GstVaapiTexturePrivate)) struct _GstVaapiTexturePrivate { - GLenum target; - GLenum format; - guint width; - guint height; - void *gl_surface; - guint foreign_texture : 1; - guint is_constructed : 1; + GLenum target; + GLenum format; + guint width; + guint height; + void *gl_surface; + GLPixmapObject *pixo; + GLFramebufferObject *fbo; + guint foreign_texture : 1; + guint is_constructed : 1; }; enum { @@ -60,27 +63,87 @@ enum { }; static void -gst_vaapi_texture_destroy(GstVaapiTexture *texture) +_gst_vaapi_texture_destroy_objects(GstVaapiTexture *texture) { GstVaapiTexturePrivate * const priv = texture->priv; - const GLuint texture_id = GST_VAAPI_OBJECT_ID(texture); - VAStatus status; +#if USE_VAAPI_GLX GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); if (priv->gl_surface) { - status = vaDestroySurfaceGLX( + vaDestroySurfaceGLX( GST_VAAPI_OBJECT_VADISPLAY(texture), priv->gl_surface ); priv->gl_surface = NULL; } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); +#else + if (priv->fbo) { + gl_destroy_framebuffer_object(priv->fbo); + priv->fbo = NULL; + } + + if (priv->pixo) { + gl_destroy_pixmap_object(priv->pixo); + priv->pixo = NULL; + } +#endif +} + +static void +gst_vaapi_texture_destroy(GstVaapiTexture *texture) +{ + GstVaapiTexturePrivate * const priv = texture->priv; + const GLuint texture_id = GST_VAAPI_OBJECT_ID(texture); + + _gst_vaapi_texture_destroy_objects(texture); if (texture_id) { if (!priv->foreign_texture) glDeleteTextures(1, &texture_id); GST_VAAPI_OBJECT_ID(texture) = 0; } +} + +static gboolean +_gst_vaapi_texture_create_objects(GstVaapiTexture *texture, GLuint texture_id) +{ + GstVaapiTexturePrivate * const priv = texture->priv; + +#if USE_VAAPI_GLX + VAStatus status; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + status = vaCreateSurfaceGLX( + GST_VAAPI_OBJECT_VADISPLAY(texture), + priv->target, + texture_id, + &priv->gl_surface + ); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!vaapi_check_status(status, "vaCreateSurfaceGLX()")) + return FALSE; +#else + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + priv->pixo = gl_create_pixmap_object( + GST_VAAPI_OBJECT_XDISPLAY(texture), + priv->width, + priv->height + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!priv->pixo) + return FALSE; + + priv->fbo = gl_create_framebuffer_object( + priv->target, + texture_id, + priv->width, + priv->height + ); + if (!priv->fbo) + return FALSE; +#endif + return TRUE; } static gboolean @@ -88,7 +151,6 @@ gst_vaapi_texture_create(GstVaapiTexture *texture) { GstVaapiTexturePrivate * const priv = texture->priv; GLuint texture_id; - VAStatus status; if (priv->foreign_texture) texture_id = GST_VAAPI_OBJECT_ID(texture); @@ -106,17 +168,7 @@ gst_vaapi_texture_create(GstVaapiTexture *texture) GST_VAAPI_OBJECT_ID(texture) = texture_id; } - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - status = vaCreateSurfaceGLX( - GST_VAAPI_OBJECT_VADISPLAY(texture), - priv->target, - texture_id, - &priv->gl_surface - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - if (!vaapi_check_status(status, "vaCreateSurfaceGLX()")) - return FALSE; - return TRUE; + return _gst_vaapi_texture_create_objects(texture, texture_id); } static void @@ -259,6 +311,8 @@ gst_vaapi_texture_init(GstVaapiTexture *texture) priv->width = 0; priv->height = 0; priv->gl_surface = NULL; + priv->pixo = NULL; + priv->fbo = NULL; priv->foreign_texture = FALSE; priv->is_constructed = FALSE; } @@ -486,6 +540,98 @@ gst_vaapi_texture_get_size( * * Return value: %TRUE on success */ +static gboolean +_gst_vaapi_texture_put_surface( + GstVaapiTexture *texture, + GstVaapiSurface *surface, + guint flags +) +{ + GstVaapiTexturePrivate * const priv = texture->priv; + VAStatus status; + +#if USE_VAAPI_GLX + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + status = vaCopySurfaceGLX( + GST_VAAPI_OBJECT_VADISPLAY(texture), + priv->gl_surface, + GST_VAAPI_OBJECT_ID(surface), + from_GstVaapiSurfaceRenderFlags(flags) + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!vaapi_check_status(status, "vaCopySurfaceGLX()")) + return FALSE; +#else + guint surface_width, surface_height; + GLTextureState ts; + gboolean success = FALSE; + + gst_vaapi_surface_get_size(surface, &surface_width, &surface_height); + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + status = vaPutSurface( + GST_VAAPI_OBJECT_VADISPLAY(texture), + GST_VAAPI_OBJECT_ID(surface), + priv->pixo->pixmap, + 0, 0, surface_width, surface_height, + 0, 0, priv->width, priv->height, + NULL, 0, + from_GstVaapiSurfaceRenderFlags(flags) + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!vaapi_check_status(status, "vaPutSurface() [TFP]")) + return FALSE; + + if (!gl_bind_texture(&ts, priv->target, GST_VAAPI_OBJECT_ID(texture))) + return FALSE; + + success = gl_bind_framebuffer_object(priv->fbo); + if (!success) { + GST_DEBUG("could not bind FBO"); + goto out_unbind_texture; + } + + success = gst_vaapi_surface_sync(surface); + if (!success) { + GST_DEBUG("could not render surface to pixmap"); + goto out_unbind_fbo; + } + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + success = gl_bind_pixmap_object(priv->pixo); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!success) { + GST_DEBUG("could not bind GLX pixmap"); + goto out_unbind_fbo; + } + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glBegin(GL_QUADS); + { + glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0 ); + glTexCoord2f(0.0f, 1.0f); glVertex2i(0, priv->height); + glTexCoord2f(1.0f, 1.0f); glVertex2i(priv->width, priv->height); + glTexCoord2f(1.0f, 0.0f); glVertex2i(priv->width, 0 ); + } + glEnd(); + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + success = gl_unbind_pixmap_object(priv->pixo); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!success) { + GST_DEBUG("could not release GLX pixmap"); + goto out_unbind_fbo; + } + +out_unbind_fbo: + success = gl_unbind_framebuffer_object(priv->fbo); +out_unbind_texture: + gl_unbind_texture(&ts); + return success; +#endif + return TRUE; +} + gboolean gst_vaapi_texture_put_surface( GstVaapiTexture *texture, @@ -493,22 +639,9 @@ gst_vaapi_texture_put_surface( guint flags ) { - VAStatus status; - g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), FALSE); g_return_val_if_fail(texture->priv->is_constructed, FALSE); g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - status = vaCopySurfaceGLX( - GST_VAAPI_OBJECT_VADISPLAY(texture), - texture->priv->gl_surface, - GST_VAAPI_OBJECT_ID(surface), - from_GstVaapiSurfaceRenderFlags(flags) - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - - if (!vaapi_check_status(status, "vaCopySurfaceGLX()")) - return FALSE; - return TRUE; + return _gst_vaapi_texture_put_surface(texture, surface, flags); } diff --git a/tests/test-display.c b/tests/test-display.c index 87ca968a66..54b136ec77 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -26,6 +26,12 @@ #include #endif +#if USE_VAAPI_GLX +# include +#else +# define vaGetDisplayGLX(dpy) vaGetDisplay(dpy) +#endif + static void print_caps(GstCaps *caps, const gchar *name) { From ea1fdba72381356fd24b36257fa14125f883665d Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 13:05:31 +0000 Subject: [PATCH 0239/3781] Fix build with VA-API < 0.30. --- gst-libs/gst/vaapi/gstvaapiutils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index f222f10eca..53c405d645 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -159,8 +159,9 @@ to_GstVaapiSurfaceStatus(guint va_flags) } /* Check for encoder status */ +#if VA_CHECK_VERSION(0,30,0) if (va_flags & VASurfaceSkipped) flags |= GST_VAAPI_SURFACE_STATUS_SKIPPED; - +#endif return flags; } From 9f7d2909addbd3db5365d6aec5e373c840dcc248 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 13:17:12 +0000 Subject: [PATCH 0240/3781] Updates. --- NEWS | 6 +++--- README | 11 +++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 08a4f8e924..f74ae74ad9 100644 --- a/NEWS +++ b/NEWS @@ -1,10 +1,10 @@ -gst-vaapi NEWS -- summary of changes. 2010-03-29 +gst-vaapi NEWS -- summary of changes. 2010-03-30 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.1.2 - 29.Mar.2010 +Version 0.1.2 - 30.Mar.2010 * Add AYUV image format -* Add support for VA/GLX extensions * Add compatibility with the original VA-API 0.29 +* Add OpenGL support through VA/GLX extensions or TFP+FBO fallback Version 0.1.1 - 23.Mar.2010 * Document public API for libgstvaapi-*.so.* diff --git a/README b/README index 260fe27206..28431431ab 100644 --- a/README +++ b/README @@ -19,15 +19,22 @@ gstreamer-vaapi consists in a collection of VA-API based plugins for GStreamer and helper libraries. * `vaapiconvert' is used to convert from video/x-raw-yuv pixels to - video/x-vaapi-surface surfaces + video/x-vaapi-surface surfaces. * `vaapisink' is used to display video/x-vaapi-surface surfaces to screen. +Features +-------- + + * VA-API support from 0.29 to 0.31 + * OpenGL rendering through VA/GLX or GLX texture-from-pixmap + FBO + + Requirements ------------ libgstreamer0.10-dev >= 0.10.0 libgstreamer-plugins-base0.10-dev >= 0.10.0 -libva-dev >= 0.31.0-1+sds9 +libva-dev >= 0.31.0-1+sds9 (VA/GLX) From fa12d470206f9e15aa3c0cf737d09ea19f2c7487 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 13:29:34 +0000 Subject: [PATCH 0241/3781] Rename -dev package to libgstvaapi-dev. --- configure.ac | 3 +-- debian.upstream/Makefile.am | 4 ++-- debian.upstream/control.in | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index f008506112..9999b27732 100644 --- a/configure.ac +++ b/configure.ac @@ -289,8 +289,7 @@ debian.upstream/gstreamer-vaapi.install.in debian.upstream/gstreamer-vaapi-doc.install.in debian.upstream/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi.install.in - debian.upstream/libgstvaapi$GST_VAAPI_MAJOR_VERSION-dev.install:\ -debian.upstream/libgstvaapi-dev.install.in + debian.upstream/libgstvaapi-dev.install debian.upstream/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi-x11.install.in debian.upstream/libgstvaapi-glx-$GST_VAAPI_MAJOR_VERSION.install:\ diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index 74906e629d..5dc3152621 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -19,7 +19,7 @@ DEBIANFILES = \ libgstvaapi.install.in \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-dev.install.in \ - libgstvaapi$(GST_VAAPI_MAJOR_VERSION)-dev.install \ + libgstvaapi-dev.install \ libgstvaapi-x11.install.in \ libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-glx.install.in \ @@ -33,7 +33,7 @@ DEBIANGENFILES = \ gstreamer$(GST_MAJORMINOR)-vaapi.install \ gstreamer$(GST_MAJORMINOR)-vaapi-doc.install \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ - libgstvaapi$(GST_VAAPI_MAJOR_VERSION)-dev.install \ + libgstvaapi-dev.install \ libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ $(NULL) diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 20301a87d0..e463f37cc0 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -64,7 +64,7 @@ Description: GStreamer libraries from the "vaapi" set . This package contains glx libraries for the "vaapi" set. -Package: libgstvaapi@GST_VAAPI_MAJOR_VERSION@-dev +Package: libgstvaapi-dev Architecture: any Section: libdevel Depends: ${shlibs:Depends}, ${misc:Depends} From 39ac673b588cf48e859901cdbf117fd1e5744e08 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 13:33:12 +0000 Subject: [PATCH 0242/3781] Bump version for development. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 9999b27732..fc3ec41668 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [1]) -m4_define([gst_vaapi_micro_version], [2]) +m4_define([gst_vaapi_micro_version], [3]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From bc9060f425333d88ead3c9b53432665125c10d06 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 16:41:21 +0000 Subject: [PATCH 0243/3781] Simplify summary. --- configure.ac | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index fc3ec41668..df2a5e4d0b 100644 --- a/configure.ac +++ b/configure.ac @@ -317,14 +317,15 @@ pkgconfig/gstreamer-vaapi-x11.pc.in ]) dnl Print summary -conf_glx=$(test $USE_GLX -eq 1 && echo yes || echo no) -conf_vaapi_glx=$(test $USE_VAAPI_GLX -eq 1 && echo yes || echo no) -conf_vaapisink_glx=$(test $USE_VAAPISINK_GLX -eq 1 && echo yes || echo no) +yesno() { + test $1 -eq 1 && echo yes || echo no +} + echo echo $PACKAGE configuration summary: echo echo VA-API version ................... : $VA_VERSION_STR -echo GLX support ...................... : $conf_glx -echo VA/GLX support ................... : $conf_vaapi_glx -echo VaapiSink/GL ..................... : $conf_vaapisink_glx +echo GLX support ...................... : $(yesno $USE_GLX) +echo VA/GLX support ................... : $(yesno $USE_VAAPI_GLX) +echo VaapiSink/GL ..................... : $(yesno $USE_VAAPISINK_GLX) echo From 702f844a7e61488bdb6f2fcfcd24a291ba456501 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 31 Mar 2010 15:25:19 +0000 Subject: [PATCH 0244/3781] Improve handling of GL contexts. --- gst-libs/gst/vaapi/gstvaapitexture.c | 21 ++ gst-libs/gst/vaapi/gstvaapiutils_glx.c | 151 ++++++++++-- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 25 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 295 +++++++++--------------- 4 files changed, 291 insertions(+), 201 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 2022c293f1..155d7d4bed 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -46,6 +46,7 @@ struct _GstVaapiTexturePrivate { GLenum format; guint width; guint height; + GLContextState *gl_context; void *gl_surface; GLPixmapObject *pixo; GLFramebufferObject *fbo; @@ -103,6 +104,13 @@ gst_vaapi_texture_destroy(GstVaapiTexture *texture) glDeleteTextures(1, &texture_id); GST_VAAPI_OBJECT_ID(texture) = 0; } + + if (priv->gl_context) { + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + gl_destroy_context(priv->gl_context); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + priv->gl_context = NULL; + } } static gboolean @@ -151,6 +159,18 @@ gst_vaapi_texture_create(GstVaapiTexture *texture) { GstVaapiTexturePrivate * const priv = texture->priv; GLuint texture_id; + GLContextState old_cs; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + gl_get_current_context(&old_cs); + priv->gl_context = gl_create_context( + GST_VAAPI_OBJECT_XDISPLAY(texture), + DefaultScreen(GST_VAAPI_OBJECT_XDISPLAY(texture)), + &old_cs + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!priv->gl_context) + return FALSE; if (priv->foreign_texture) texture_id = GST_VAAPI_OBJECT_ID(texture); @@ -310,6 +330,7 @@ gst_vaapi_texture_init(GstVaapiTexture *texture) priv->format = GL_NONE; priv->width = 0; priv->height = 0; + priv->gl_context = NULL; priv->gl_surface = NULL; priv->pixo = NULL; priv->fbo = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 93e846508f..60a7bc7e98 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -273,46 +273,165 @@ gl_resize(guint width, guint height) } /** - * gl_make_current: + * gl_create_context: * @dpy: an X11 #Display - * @win: an X11 #Window - * @ctx: the requested GLX context - * @state: an optional #GLContextState + * @screen: the associated screen of @dpy + * @parent: the parent #GLContextState, or %NULL if none is to be used * - * Makes the @window GLX context the current GLX rendering context of + * Creates a GLX context sharing textures and displays lists with + * @parent, if not %NULL. + * + * Return value: the newly created GLX context + */ +GLContextState * +gl_create_context(Display *dpy, int screen, GLContextState *parent) +{ + GLContextState *cs; + GLXFBConfig *fb_configs = NULL; + int n_fb_configs; + + static GLint fb_config_attrs[] = { + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DOUBLEBUFFER, True, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + None + }; + + cs = malloc(sizeof(*cs)); + if (!cs) + goto error; + + cs->display = dpy; + cs->window = parent ? parent->window : None; + cs->visual = NULL; + cs->context = NULL; + cs->swapped_buffers = FALSE; + + fb_configs = glXChooseFBConfig(dpy, screen, fb_config_attrs, &n_fb_configs); + if (!fb_configs) + goto error; + + cs->visual = glXGetVisualFromFBConfig(dpy, fb_configs[0]); + if (!cs->visual) + goto error; + + cs->context = glXCreateNewContext( + dpy, + fb_configs[0], + GLX_RGBA_TYPE, + parent ? parent->context : NULL, + True + ); + if (cs->context) + goto end; + +error: + gl_destroy_context(cs); + cs = NULL; +end: + if (fb_configs) + XFree(fb_configs); + return cs; +} + +/** + * gl_destroy_context: + * @cs: a #GLContextState + * + * Destroys the GLX context @cs + */ +void +gl_destroy_context(GLContextState *cs) +{ + if (!cs) + return; + + if (cs->visual) { + XFree(cs->visual); + cs->visual = NULL; + } + + if (cs->display && cs->context) { + if (glXGetCurrentContext() == cs->context) { + /* XXX: if buffers were never swapped, the application + will crash later with the NVIDIA driver */ + if (!cs->swapped_buffers) + gl_swap_buffers(cs); + glXMakeCurrent(cs->display, None, NULL); + } + glXDestroyContext(cs->display, cs->context); + cs->display = NULL; + cs->context = NULL; + } + free(cs); +} + +/** + * gl_get_current_context: + * @cs: return location to the current #GLContextState + * + * Retrieves the current GLX context, display and drawable packed into + * the #GLContextState struct. + */ +void +gl_get_current_context(GLContextState *cs) +{ + cs->display = glXGetCurrentDisplay(); + cs->window = glXGetCurrentDrawable(); + cs->context = glXGetCurrentContext(); +} + +/** + * gl_set_current_context: + * @new_cs: the requested new #GLContextState + * @old_cs: return location to the context that was previously current + * + * Makes the @new_cs GLX context the current GLX rendering context of * the calling thread, replacing the previously current context if * there was one. * - * If @state is non %NULL, the previously current GLX context and + * If @old_cs is non %NULL, the previously current GLX context and * window are recorded. * * Return value: %TRUE on success */ gboolean -gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state) +gl_set_current_context(GLContextState *new_cs, GLContextState *old_cs) { - if (state) { - state->context = glXGetCurrentContext(); - state->window = glXGetCurrentDrawable(); - if (state->context == ctx && state->window == win) + /* If display is NULL, this could be that new_cs was retrieved from + gl_get_current_context() with none set previously. If that case, + the other fields are also NULL and we don't return an error */ + if (!new_cs->display) + return !new_cs->window && !new_cs->context; + + if (old_cs) { + if (old_cs == new_cs) + return TRUE; + gl_get_current_context(old_cs); + if (old_cs->display == new_cs->display && + old_cs->window == new_cs->window && + old_cs->context == new_cs->context) return TRUE; } - return glXMakeCurrent(dpy, win, ctx); + return glXMakeCurrent(new_cs->display, new_cs->window, new_cs->context); } /** * gl_swap_buffers: - * @dpy: an X11 #Display - * @win: an X11 #Window + * @cs: a #GLContextState * * Promotes the contents of the back buffer of the @win window to * become the contents of the front buffer. This simply is wrapper * around glXSwapBuffers(). */ void -gl_swap_buffers(Display *dpy, Window win) +gl_swap_buffers(GLContextState *cs) { - glXSwapBuffers(dpy, win); + glXSwapBuffers(cs->display, cs->window); + cs->swapped_buffers = TRUE; } /** diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 3c83da2374..a13adbd236 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -67,16 +67,31 @@ gl_resize(guint width, guint height) typedef struct _GLContextState GLContextState; struct _GLContextState { - GLXContext context; - Window window; + Display *display; + Window window; + XVisualInfo *visual; + GLXContext context; + guint swapped_buffers; }; -gboolean -gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state) +GLContextState * +gl_create_context(Display *dpy, int screen, GLContextState *parent) attribute_hidden; void -gl_swap_buffers(Display *dpy, Window win) +gl_destroy_context(GLContextState *cs) + attribute_hidden; + +void +gl_get_current_context(GLContextState *cs) + attribute_hidden; + +gboolean +gl_set_current_context(GLContextState *new_cs, GLContextState *old_cs) + attribute_hidden; + +void +gl_swap_buffers(GLContextState *cs) attribute_hidden; typedef struct _GLTextureState GLTextureState; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index a1f9dc6c8b..bd905e95c4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -43,14 +43,10 @@ G_DEFINE_TYPE(GstVaapiWindowGLX, GstVaapiWindowGLXPrivate)) struct _GstVaapiWindowGLXPrivate { - XVisualInfo *vi; - XVisualInfo vi_static; Colormap cmap; - GLXContext context; + GLContextState *gl_context; guint is_constructed : 1; - guint foreign_context : 1; guint foreign_window : 1; - guint swapped_buffers : 1; }; enum { @@ -59,9 +55,6 @@ enum { PROP_GLX_CONTEXT }; -static XVisualInfo * -gst_vaapi_window_glx_create_visual(GstVaapiWindowGLX *window); - /* Fill rectangle coords with capped bounds */ static inline void fill_rect( @@ -91,149 +84,114 @@ fill_rect( } } -static inline void -_gst_vaapi_window_glx_set_context( +static void +_gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window) +{ + GstVaapiWindowGLXPrivate * const priv = window->priv; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + if (priv->gl_context) { + gl_destroy_context(priv->gl_context); + priv->gl_context = NULL; + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); +} + +static gboolean +_gst_vaapi_window_glx_create_context( GstVaapiWindowGLX *window, - GLXContext context, - gboolean is_foreign + GLXContext foreign_context +) +{ + GstVaapiWindowGLXPrivate * const priv = window->priv; + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + GLContextState parent_cs; + + parent_cs.display = dpy; + parent_cs.window = None; + parent_cs.context = foreign_context; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + priv->gl_context = gl_create_context(dpy, DefaultScreen(dpy), &parent_cs); + if (!priv->gl_context) { + GST_DEBUG("could not create GLX context"); + goto end; + } + + if (!glXIsDirect(dpy, priv->gl_context->context)) { + GST_DEBUG("could not create a direct-rendering GLX context"); + goto out_destroy_context; + } + goto end; + +out_destroy_context: + gl_destroy_context(priv->gl_context); + priv->gl_context = NULL; +end: + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + return priv->gl_context != NULL; +} + +static gboolean +_gst_vaapi_window_glx_ensure_context( + GstVaapiWindowGLX *window, + GLXContext foreign_context ) { GstVaapiWindowGLXPrivate * const priv = window->priv; - priv->context = context; - priv->foreign_context = is_foreign; -} - -static void -gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window) -{ - GstVaapiWindowGLXPrivate * const priv = window->priv; - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - - if (priv->context) { - if (!priv->foreign_context) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - if (glXGetCurrentContext() == priv->context) { - /* XXX: if buffers were never swapped, the application - will crash later with the NVIDIA driver */ - if (!priv->swapped_buffers) - gl_swap_buffers(dpy, GST_VAAPI_OBJECT_ID(window)); - gl_make_current(dpy, None, NULL, NULL); - } - glXDestroyContext(dpy, priv->context); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - } - priv->context = NULL; - priv->foreign_context = FALSE; + if (priv->gl_context) { + if (!foreign_context || foreign_context == priv->gl_context->context) + return TRUE; + _gst_vaapi_window_glx_destroy_context(window); } + return _gst_vaapi_window_glx_create_context(window, foreign_context); } static gboolean -gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window) +gst_vaapi_window_glx_ensure_context( + GstVaapiWindowGLX *window, + GLXContext foreign_context +) { GstVaapiWindowGLXPrivate * const priv = window->priv; - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - GLXContext ctx = NULL; - GLContextState cs; - guint width, height; - gboolean has_errors = TRUE; + GLContextState old_cs; + guint width, height; - if (!gst_vaapi_window_glx_create_visual(window)) + if (!_gst_vaapi_window_glx_ensure_context(window, foreign_context)) return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - ctx = glXCreateContext(dpy, priv->vi, NULL, True); - if (ctx && glXIsDirect(dpy, ctx)) { - _gst_vaapi_window_glx_set_context(window, ctx, FALSE); - if (gl_make_current(dpy, GST_VAAPI_OBJECT_ID(window), ctx, &cs)) { - glDisable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - glDisable(GL_CULL_FACE); - glDrawBuffer(GL_BACK); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - gst_vaapi_window_get_size(GST_VAAPI_WINDOW(window), &width, &height); - gl_resize(width, height); - - gl_set_bgcolor(0); - glClear(GL_COLOR_BUFFER_BIT); - if (cs.context) - gl_make_current(dpy, cs.window, cs.context, NULL); - has_errors = FALSE; - } + priv->gl_context->window = GST_VAAPI_OBJECT_ID(window); + if (!gl_set_current_context(priv->gl_context, &old_cs)) { + GST_DEBUG("could not make newly created GLX context current"); + return FALSE; } - else if (ctx) - glXDestroyContext(dpy, ctx); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - return !has_errors; -} + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_CULL_FACE); + glDrawBuffer(GL_BACK); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -static inline void -gst_vaapi_window_glx_destroy_visual(GstVaapiWindowGLX *window) -{ - GstVaapiWindowGLXPrivate * const priv = window->priv; + gst_vaapi_window_get_size(GST_VAAPI_WINDOW(window), &width, &height); + gl_resize(width, height); - if (priv->vi) { - if (priv->vi != &priv->vi_static) - XFree(priv->vi); - priv->vi = NULL; - } -} - -static XVisualInfo * -gst_vaapi_window_glx_create_visual(GstVaapiWindowGLX *window) -{ - GstVaapiWindowGLXPrivate * const priv = window->priv; - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - XWindowAttributes wattr; - int screen; - gboolean has_errors; - - /* XXX: add and use a GstVaapiWindow:double-buffer property? */ - static GLint gl_visual_attr[] = { - GLX_RGBA, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_DOUBLEBUFFER, - GL_NONE - }; - - if (!priv->vi) { - /* XXX: add and use a GstVaapiDisplayX11:x11-screen property? */ - screen = DefaultScreen(dpy); - - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - x11_trap_errors(); - if (!priv->foreign_window) - priv->vi = glXChooseVisual(dpy, screen, gl_visual_attr); - else { - XGetWindowAttributes(dpy, GST_VAAPI_OBJECT_ID(window), &wattr); - if (XMatchVisualInfo(dpy, screen, wattr.depth, wattr.visual->class, - &priv->vi_static)) - priv->vi = &priv->vi_static; - } - has_errors = x11_untrap_errors() != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - - if (has_errors) - return NULL; - } - return priv->vi; + gl_set_bgcolor(0); + glClear(GL_COLOR_BUFFER_BIT); + gl_set_current_context(&old_cs, NULL); + return TRUE; } static Visual * gst_vaapi_window_glx_get_visual(GstVaapiWindow *window) { - XVisualInfo *vi; + GstVaapiWindowGLX * const glx_window = GST_VAAPI_WINDOW_GLX(window); - vi = gst_vaapi_window_glx_create_visual(GST_VAAPI_WINDOW_GLX(window)); - if (!vi) + if (!_gst_vaapi_window_glx_ensure_context(glx_window, NULL)) return NULL; - return vi->visual; + return glx_window->priv->gl_context->visual->visual; } static void @@ -259,33 +217,34 @@ gst_vaapi_window_glx_create_colormap(GstVaapiWindowGLX *window) Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); int screen; XWindowAttributes wattr; - XVisualInfo *vi; - gboolean has_errors; + gboolean success = FALSE; if (!priv->cmap) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - x11_trap_errors(); if (!priv->foreign_window) { - vi = gst_vaapi_window_glx_create_visual(window); - if (vi) { - /* XXX: add a GstVaapiDisplayX11:x11-screen property? */ - screen = DefaultScreen(dpy); - priv->cmap = XCreateColormap( - dpy, - RootWindow(dpy, screen), - vi->visual, - AllocNone - ); - } + if (!_gst_vaapi_window_glx_ensure_context(window, NULL)) + return None; + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + x11_trap_errors(); + /* XXX: add a GstVaapiDisplayX11:x11-screen property? */ + screen = DefaultScreen(dpy); + priv->cmap = XCreateColormap( + dpy, + RootWindow(dpy, screen), + priv->gl_context->visual->visual, + AllocNone + ); + success = x11_untrap_errors() == 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); } else { + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + x11_trap_errors(); XGetWindowAttributes(dpy, GST_VAAPI_OBJECT_ID(window), &wattr); priv->cmap = wattr.colormap; + success = x11_untrap_errors() == 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); } - has_errors = x11_untrap_errors() != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - - if (has_errors) + if (!success) return None; } return priv->cmap; @@ -302,7 +261,7 @@ gst_vaapi_window_glx_resize(GstVaapiWindow *window, guint width, guint height) { GstVaapiWindowGLXPrivate * const priv = GST_VAAPI_WINDOW_GLX(window)->priv; Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - GLContextState cs; + GLContextState old_cs; if (!GST_VAAPI_WINDOW_CLASS(gst_vaapi_window_glx_parent_class)-> resize(window, width, height)) @@ -310,10 +269,9 @@ gst_vaapi_window_glx_resize(GstVaapiWindow *window, guint width, guint height) GST_VAAPI_OBJECT_LOCK_DISPLAY(window); XSync(dpy, False); /* make sure resize completed */ - if (gl_make_current(dpy, GST_VAAPI_OBJECT_ID(window), priv->context, &cs)) { + if (gl_set_current_context(priv->gl_context, &old_cs)) { gl_resize(width, height); - if (cs.context) - gl_make_current(dpy, cs.window, cs.context, NULL); + gl_set_current_context(&old_cs, NULL); } GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); return TRUE; @@ -324,8 +282,7 @@ gst_vaapi_window_glx_finalize(GObject *object) { GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(object); - gst_vaapi_window_glx_destroy_context(window); - gst_vaapi_window_glx_destroy_visual(window); + _gst_vaapi_window_glx_destroy_context(window); gst_vaapi_window_glx_destroy_colormap(window); G_OBJECT_CLASS(gst_vaapi_window_glx_parent_class)->finalize(object); @@ -377,8 +334,6 @@ gst_vaapi_window_glx_constructed(GObject *object) GstVaapiWindowGLXPrivate * const priv = GST_VAAPI_WINDOW_GLX(object)->priv; GObjectClass *parent_class; - priv->foreign_context = priv->context != NULL; - parent_class = G_OBJECT_CLASS(gst_vaapi_window_glx_parent_class); if (parent_class->constructed) parent_class->constructed(object); @@ -386,8 +341,8 @@ gst_vaapi_window_glx_constructed(GObject *object) priv->foreign_window = gst_vaapi_window_x11_is_foreign_xid(GST_VAAPI_WINDOW_X11(object)); - priv->is_constructed = priv->foreign_context || - gst_vaapi_window_glx_create_context(GST_VAAPI_WINDOW_GLX(object)); + priv->is_constructed = + gst_vaapi_window_glx_ensure_context(GST_VAAPI_WINDOW_GLX(object), NULL); } static void @@ -429,13 +384,10 @@ gst_vaapi_window_glx_init(GstVaapiWindowGLX *window) GstVaapiWindowGLXPrivate *priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); window->priv = priv; - priv->vi = NULL; priv->cmap = None; - priv->context = NULL; + priv->gl_context = NULL; priv->is_constructed = FALSE; - priv->foreign_context = FALSE; priv->foreign_window = FALSE; - priv->swapped_buffers = FALSE; } /** @@ -505,7 +457,7 @@ gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window) g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), NULL); g_return_val_if_fail(window->priv->is_constructed, FALSE); - return window->priv->context; + return window->priv->gl_context->context; } /** @@ -526,13 +478,7 @@ gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx) g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE); g_return_val_if_fail(window->priv->is_constructed, FALSE); - gst_vaapi_window_glx_destroy_context(window); - - if (ctx) { - _gst_vaapi_window_glx_set_context(window, ctx, TRUE); - return TRUE; - } - return gst_vaapi_window_glx_create_context(window); + return gst_vaapi_window_glx_ensure_context(window, ctx); } /** @@ -554,12 +500,7 @@ gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window) g_return_val_if_fail(window->priv->is_constructed, FALSE); GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - success = gl_make_current( - GST_VAAPI_OBJECT_XDISPLAY(window), - GST_VAAPI_OBJECT_ID(window), - window->priv->context, - NULL - ); + success = gl_set_current_context(window->priv->gl_context, NULL); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); return success; } @@ -579,14 +520,8 @@ gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window) g_return_if_fail(window->priv->is_constructed); GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - gl_swap_buffers( - GST_VAAPI_OBJECT_XDISPLAY(window), - GST_VAAPI_OBJECT_ID(window) - ); - glClear(GL_COLOR_BUFFER_BIT); + gl_swap_buffers(window->priv->gl_context); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - - window->priv->swapped_buffers = TRUE; } /** From 6b56ca0068321b7688dde0b49c5110295b2edf43 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 1 Apr 2010 09:47:59 +0000 Subject: [PATCH 0245/3781] Move GST_VAAPI_DISPLAY_VADISPLAY() and GST_VAAPI_DISPLAY_{LOCK,UNLOCK}() to gstvaapidisplay_priv.h. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapi_priv.h | 27 +++++++ gst-libs/gst/vaapi/gstvaapidisplay.c | 21 +----- gst-libs/gst/vaapi/gstvaapidisplay.h | 27 ------- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 85 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 1 + gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapiobject.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapitexture.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- 15 files changed, 125 insertions(+), 55 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapi_priv.h create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index e650c85882..3a9295bf0c 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -50,8 +50,10 @@ libgstvaapi_source_h = \ libgstvaapi_source_priv_h = \ gstvaapicompat.h \ gstvaapidebug.h \ + gstvaapidisplay_priv.h \ gstvaapiobject_priv.h \ gstvaapiutils.h \ + gstvaapi_priv.h \ $(NULL) libgstvaapi_x11_source_c = \ diff --git a/gst-libs/gst/vaapi/gstvaapi_priv.h b/gst-libs/gst/vaapi/gstvaapi_priv.h new file mode 100644 index 0000000000..fa8ce58514 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapi_priv.h @@ -0,0 +1,27 @@ +/* + * gstvaapi_priv.h - Helper to include all private headers + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_PRIV_H +#define GST_VAAPI_PRIV_H + +#include +#include + +#endif /* GST_VAAPI_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index ff10126e8e..d879a18305 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -26,6 +26,7 @@ #include "config.h" #include "gstvaapiutils.h" #include "gstvaapidisplay.h" +#include "gstvaapidisplay_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -34,26 +35,6 @@ GST_DEBUG_CATEGORY(gst_debug_vaapi); G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT); -#define GST_VAAPI_DISPLAY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DISPLAY, \ - GstVaapiDisplayPrivate)) - -struct _GstVaapiDisplayPrivate { - GStaticMutex mutex; - VADisplay display; - guint width; - guint height; - guint width_mm; - guint height_mm; - guint par_n; - guint par_d; - GArray *profiles; - GArray *image_formats; - GArray *subpicture_formats; - guint create_display : 1; -}; - enum { PROP_0, diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index e654be63ee..8f605f8d07 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -56,33 +56,6 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DISPLAY, \ GstVaapiDisplayClass)) -/** - * GST_VAAPI_DISPLAY_VADISPLAY: - * @display: a #GstVaapiDisplay - * - * Macro that evaluates to the #VADisplay bound to @display - */ -#define GST_VAAPI_DISPLAY_VADISPLAY(display) \ - gst_vaapi_display_get_display(display) - -/** - * GST_VAAPI_DISPLAY_LOCK: - * @display: a #GstVaapiDisplay - * - * Locks @display - */ -#define GST_VAAPI_DISPLAY_LOCK(display) \ - gst_vaapi_display_lock(display) - -/** - * GST_VAAPI_DISPLAY_UNLOCK: - * @display: a #GstVaapiDisplay - * - * Unlocks @display - */ -#define GST_VAAPI_DISPLAY_UNLOCK(display) \ - gst_vaapi_display_unlock(display) - typedef struct _GstVaapiDisplay GstVaapiDisplay; typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index c4722d3081..d6d4e46f4f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -27,6 +27,7 @@ #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapidisplay_glx.h" +#include "gstvaapidisplay_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h new file mode 100644 index 0000000000..7cc40fdfec --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -0,0 +1,85 @@ +/* + * gstvaapidisplay_priv.h - Base VA display (private definitions) + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_DISPLAY_PRIV_H +#define GST_VAAPI_DISPLAY_PRIV_H + +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_DISPLAY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DISPLAY, \ + GstVaapiDisplayPrivate)) + +#define GST_VAAPI_DISPLAY_CAST(display) ((GstVaapiDisplay *)(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. + */ +#define GST_VAAPI_DISPLAY_VADISPLAY(display_) \ + GST_VAAPI_DISPLAY_CAST(display_)->priv->display + +/** + * GST_VAAPI_DISPLAY_LOCK: + * @display: a #GstVaapiDisplay + * + * Locks @display + */ +#define GST_VAAPI_DISPLAY_LOCK(display) \ + gst_vaapi_display_lock(display) + +/** + * GST_VAAPI_DISPLAY_UNLOCK: + * @display: a #GstVaapiDisplay + * + * Unlocks @display + */ +#define GST_VAAPI_DISPLAY_UNLOCK(display) \ + gst_vaapi_display_unlock(display) + +/** + * GstVaapiDisplayPrivate: + * + * Base class for VA displays. + */ +struct _GstVaapiDisplayPrivate { + GStaticMutex mutex; + VADisplay display; + guint width; + guint height; + guint width_mm; + guint height_mm; + guint par_n; + guint par_d; + GArray *profiles; + GArray *image_formats; + GArray *subpicture_formats; + guint create_display : 1; +}; + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index ebfa14b70b..b0f6bdfd44 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -26,6 +26,7 @@ #include "config.h" #include "gstvaapiutils.h" #include "gstvaapidisplay_x11.h" +#include "gstvaapidisplay_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index d21bda2bec..3cc2251238 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -28,7 +28,7 @@ #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapiimage.h" -#include "gstvaapiobject_priv.h" +#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 9c627b8c6c..368166f96d 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -25,7 +25,7 @@ #include "config.h" #include "gstvaapiobject.h" -#include "gstvaapiobject_priv.h" +#include "gstvaapi_priv.h" #include "gstvaapiparamspecs.h" #include "gstvaapivalue.h" #include "gstvaapimarshal.h" diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 4566a321b2..ae79b7842b 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -28,7 +28,7 @@ #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapisubpicture.h" -#include "gstvaapiobject_priv.h" +#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 635f111bc8..08269a8040 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -28,7 +28,7 @@ #include "gstvaapiutils.h" #include "gstvaapisurface.h" #include "gstvaapiimage.h" -#include "gstvaapiobject_priv.h" +#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 155d7d4bed..92f9994d14 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -29,7 +29,7 @@ #include "gstvaapiutils.h" #include "gstvaapiutils_glx.h" #include "gstvaapidisplay_glx.h" -#include "gstvaapiobject_priv.h" +#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 5f521d4cae..8e5e58b654 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -25,7 +25,7 @@ #include "config.h" #include "gstvaapiwindow.h" -#include "gstvaapiobject_priv.h" +#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index bd905e95c4..d050c4f6f2 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -28,7 +28,7 @@ #include "gstvaapidisplay_x11.h" #include "gstvaapiutils_x11.h" #include "gstvaapiutils_glx.h" -#include "gstvaapiobject_priv.h" +#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index f10860c581..f2ffbefadc 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -31,7 +31,7 @@ #include "gstvaapidisplay_x11.h" #include "gstvaapiutils.h" #include "gstvaapiutils_x11.h" -#include "gstvaapiobject_priv.h" +#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" From 7edf8c9bb76cf917923981f2d83ec68aa5dc5e1c Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 1 Apr 2010 13:41:24 +0000 Subject: [PATCH 0246/3781] Make more helpers internal, thus reducing .text size further. Add gst_vaapi_display_x11_get_screen() helper along the way. --- docs/reference/libs/libs-sections.txt | 2 +- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 5 +- gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 33 +++++++++ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 7 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 69 ++++++++++++++----- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 12 +--- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 66 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiobject_priv.h | 60 ++++++++++++---- gst-libs/gst/vaapi/gstvaapitexture.c | 3 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 9 ++- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 1 + tests/test-windows.c | 2 +- 13 files changed, 223 insertions(+), 48 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 9847492370..7a8414dc03 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -51,10 +51,10 @@ gst_vaapi_video_sink_get_type GstVaapiDisplayX11 GstVaapiDisplayX11 GstVaapiDisplayX11Class -GST_VAAPI_DISPLAY_XDISPLAY gst_vaapi_display_x11_new gst_vaapi_display_x11_new_with_display gst_vaapi_display_x11_get_display +gst_vaapi_display_x11_get_screen GST_VAAPI_DISPLAY_X11 GST_VAAPI_IS_DISPLAY_X11 diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 3a9295bf0c..6809431019 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -70,6 +70,7 @@ libgstvaapi_x11_source_h = \ libgstvaapi_x11_source_priv_h = \ gstvaapicompat.h \ + gstvaapidisplay_x11_priv.h \ gstvaapiutils.h \ gstvaapiutils_x11.h \ $(NULL) @@ -91,6 +92,7 @@ libgstvaapi_glx_source_h = \ libgstvaapi_glx_source_priv_h = \ gstvaapicompat.h \ + gstvaapidisplay_glx_priv.h \ gstvaapiutils.h \ gstvaapiutils_glx.h \ gstvaapiutils_x11.h \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index d6d4e46f4f..14cc35b189 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -26,8 +26,11 @@ #include "config.h" #include "gstvaapicompat.h" #include "gstvaapiutils.h" -#include "gstvaapidisplay_glx.h" +#include "gstvaapiutils_glx.h" #include "gstvaapidisplay_priv.h" +#include "gstvaapidisplay_x11_priv.h" +#include "gstvaapidisplay_glx.h" +#include "gstvaapidisplay_glx_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h new file mode 100644 index 0000000000..d6758b02f4 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -0,0 +1,33 @@ +/* + * gstvaapidisplay_glx_priv.h - Internal VA/GLX interface + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 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 +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_DISPLAY_GLX_CAST(display) ((GstVaapiDisplayGLX *)(display)) + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_GLX_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 7cc40fdfec..0f8adbd04a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -39,6 +39,7 @@ G_BEGIN_DECLS * 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_CAST(display_)->priv->display @@ -48,8 +49,9 @@ G_BEGIN_DECLS * * Locks @display */ +#undef GST_VAAPI_DISPLAY_LOCK #define GST_VAAPI_DISPLAY_LOCK(display) \ - gst_vaapi_display_lock(display) + gst_vaapi_display_lock(GST_VAAPI_DISPLAY_CAST(display)) /** * GST_VAAPI_DISPLAY_UNLOCK: @@ -57,8 +59,9 @@ G_BEGIN_DECLS * * Unlocks @display */ +#undef GST_VAAPI_DISPLAY_UNLOCK #define GST_VAAPI_DISPLAY_UNLOCK(display) \ - gst_vaapi_display_unlock(display) + gst_vaapi_display_unlock(GST_VAAPI_DISPLAY_CAST(display)) /** * GstVaapiDisplayPrivate: diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index b0f6bdfd44..f61a8632da 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -25,8 +25,9 @@ #include "config.h" #include "gstvaapiutils.h" -#include "gstvaapidisplay_x11.h" #include "gstvaapidisplay_priv.h" +#include "gstvaapidisplay_x11.h" +#include "gstvaapidisplay_x11_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -35,25 +36,13 @@ G_DEFINE_TYPE(GstVaapiDisplayX11, gst_vaapi_display_x11, GST_VAAPI_TYPE_DISPLAY); -#define GST_VAAPI_DISPLAY_X11_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DISPLAY_X11, \ - GstVaapiDisplayX11Private)) - -struct _GstVaapiDisplayX11Private { - gchar *display_name; - Display *x11_display; - int x11_screen; - guint create_display : 1; - guint synchronous : 1; -}; - enum { PROP_0, PROP_SYNCHRONOUS, PROP_DISPLAY_NAME, - PROP_X11_DISPLAY + PROP_X11_DISPLAY, + PROP_X11_SCREEN }; static void @@ -107,6 +96,9 @@ gst_vaapi_display_x11_set_property( case PROP_X11_DISPLAY: display->priv->x11_display = g_value_get_pointer(value); break; + case PROP_X11_SCREEN: + display->priv->x11_screen = g_value_get_int(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -133,6 +125,9 @@ gst_vaapi_display_x11_get_property( case PROP_X11_DISPLAY: g_value_set_pointer(value, gst_vaapi_display_x11_get_display(display)); break; + case PROP_X11_SCREEN: + g_value_set_int(value, gst_vaapi_display_x11_get_screen(display)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -163,15 +158,17 @@ gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) GST_VAAPI_DISPLAY_X11(display)->priv; /* XXX: maintain an X11 display cache */ - if (!priv->x11_display && priv->create_display) + if (priv->create_display) { priv->x11_display = XOpenDisplay(priv->display_name); + if (!priv->x11_display) + return FALSE; + priv->x11_screen = DefaultScreen(priv->x11_display); + } if (!priv->x11_display) return FALSE; if (priv->synchronous) XSynchronize(priv->x11_display, True); - - priv->x11_screen = DefaultScreen(priv->x11_display); return TRUE; } @@ -315,6 +312,21 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) "X11 display", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + /** + * GstVaapiDisplayX11:x11-screen: + * + * The X11 screen that was created by gst_vaapi_display_x11_new() + * or that was bound from gst_vaapi_display_x11_new_with_display(). + */ + g_object_class_install_property + (object_class, + PROP_X11_SCREEN, + g_param_spec_int("x11-screen", + "X11 screen", + "X11 screen", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + /** * GstVaapiDisplayX11:display-name: * @@ -374,8 +386,11 @@ gst_vaapi_display_x11_new(const gchar *display_name) GstVaapiDisplay * gst_vaapi_display_x11_new_with_display(Display *x11_display) { + g_return_val_if_fail(x11_display, NULL); + return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, "x11-display", x11_display, + "x11-screen", DefaultScreen(x11_display), NULL); } @@ -396,3 +411,21 @@ gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) return display->priv->x11_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 display->priv->x11_screen; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index d6c2d15490..8a52c577cb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -55,15 +55,6 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DISPLAY_X11, \ GstVaapiDisplayX11Class)) -/** - * GST_VAAPI_DISPLAY_XDISPLAY: - * @display: a #GstVaapiDisplay - * - * Macro that evaluates to the underlying X11 #Display of @display - */ -#define GST_VAAPI_DISPLAY_XDISPLAY(display) \ - gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)) - typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11; typedef struct _GstVaapiDisplayX11Private GstVaapiDisplayX11Private; typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class; @@ -103,6 +94,9 @@ gst_vaapi_display_x11_new_with_display(Display *x11_display); Display * gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display); +int +gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_X11_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h new file mode 100644 index 0000000000..9ffb1aa188 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -0,0 +1,66 @@ +/* + * gstvaapidisplay_x11_priv.h - Internal VA/X11 interface + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 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 +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_DISPLAY_X11_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DISPLAY_X11, \ + GstVaapiDisplayX11Private)) + +#define GST_VAAPI_DISPLAY_X11_CAST(display) ((GstVaapiDisplayX11 *)(display)) + +/** + * 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_CAST(display)->priv->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_CAST(display)->priv->x11_screen + +struct _GstVaapiDisplayX11Private { + gchar *display_name; + Display *x11_display; + int x11_screen; + guint create_display : 1; + guint synchronous : 1; +}; + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_X11_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 0a8f75e82f..1720d62ff1 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -42,12 +42,45 @@ G_BEGIN_DECLS #define GST_VAAPI_OBJECT_DISPLAY(object) \ GST_VAAPI_OBJECT_CAST(object)->priv->display +/** + * GST_VAAPI_OBJECT_ID: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the #GstVaapiID contained in @object. + * This is an internal macro that does not do any run-time type checks. + */ +#define GST_VAAPI_OBJECT_ID(object) \ + GST_VAAPI_OBJECT_CAST(object)->priv->id + +/** + * GST_VAAPI_OBJECT_DISPLAY_X11: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the #GstVaapiDisplayX11 the @object is bound to. + * This is an internal macro that does not do any run-time type check + * and requires #include "gstvaapidisplay_x11_priv.h" + */ +#define GST_VAAPI_OBJECT_DISPLAY_X11(object) \ + GST_VAAPI_DISPLAY_X11_CAST(GST_VAAPI_OBJECT_DISPLAY(object)) + +/** + * GST_VAAPI_OBJECT_DISPLAY_GLX: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the #GstVaapiDisplayGLX the @object is bound to. + * This is an internal macro that does not do any run-time type check + * and requires #include "gstvaapidisplay_glx_priv.h". + */ +#define GST_VAAPI_OBJECT_DISPLAY_GLX(object) \ + GST_VAAPI_DISPLAY_GLX_CAST(GST_VAAPI_OBJECT_DISPLAY(object)) + /** * GST_VAAPI_OBJECT_VADISPLAY: * @object: a #GstVaapiObject * * Macro that evaluates to the #VADisplay of @display. - * This is an internal macro that does not do any run-time type check. + * This is an internal macro that does not do any run-time type check + * and requires #include "gstvaapidisplay_priv.h". */ #define GST_VAAPI_OBJECT_VADISPLAY(object) \ GST_VAAPI_DISPLAY_VADISPLAY(GST_VAAPI_OBJECT_DISPLAY(object)) @@ -57,12 +90,23 @@ G_BEGIN_DECLS * @object: a #GstVaapiObject * * Macro that evaluates to the underlying X11 #Display of @display. - * This is an internal macro that does not do any run-time type check. - * Besides, this is only valid within libgstvaapi-x11. + * This is an internal macro that does not do any run-time type check + * and requires #include "gstvaapidisplay_x11_priv.h". */ #define GST_VAAPI_OBJECT_XDISPLAY(object) \ GST_VAAPI_DISPLAY_XDISPLAY(GST_VAAPI_OBJECT_DISPLAY(object)) +/** + * GST_VAAPI_OBJECT_XSCREEN: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the underlying X11 screen of @display. + * This is an internal macro that does not do any run-time type check + * and requires #include "gstvaapidisplay_x11_priv.h". + */ +#define GST_VAAPI_OBJECT_XSCREEN(object) \ + GST_VAAPI_DISPLAY_XSCREEN(GST_VAAPI_OBJECT_DISPLAY(object)) + /** * GST_VAAPI_OBJECT_LOCK_DISPLAY: * @object: a #GstVaapiObject @@ -83,16 +127,6 @@ G_BEGIN_DECLS #define GST_VAAPI_OBJECT_UNLOCK_DISPLAY(object) \ GST_VAAPI_DISPLAY_UNLOCK(GST_VAAPI_OBJECT_DISPLAY(object)) -/** - * GST_VAAPI_OBJECT_ID: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the #GstVaapiID contained in @object. - * This is an internal macro that does not do any run-time type checks. - */ -#define GST_VAAPI_OBJECT_ID(object) \ - GST_VAAPI_OBJECT_CAST(object)->priv->id - /** * GstVaapiObjectPrivate: * diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 92f9994d14..949ef85d2f 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -30,6 +30,7 @@ #include "gstvaapiutils_glx.h" #include "gstvaapidisplay_glx.h" #include "gstvaapi_priv.h" +#include "gstvaapidisplay_x11_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -165,7 +166,7 @@ gst_vaapi_texture_create(GstVaapiTexture *texture) gl_get_current_context(&old_cs); priv->gl_context = gl_create_context( GST_VAAPI_OBJECT_XDISPLAY(texture), - DefaultScreen(GST_VAAPI_OBJECT_XDISPLAY(texture)), + GST_VAAPI_OBJECT_XSCREEN(texture), &old_cs ); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index d050c4f6f2..9ca7b7cfb9 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -26,6 +26,7 @@ #include "config.h" #include "gstvaapiwindow_glx.h" #include "gstvaapidisplay_x11.h" +#include "gstvaapidisplay_x11_priv.h" #include "gstvaapiutils_x11.h" #include "gstvaapiutils_glx.h" #include "gstvaapi_priv.h" @@ -112,7 +113,11 @@ _gst_vaapi_window_glx_create_context( parent_cs.context = foreign_context; GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - priv->gl_context = gl_create_context(dpy, DefaultScreen(dpy), &parent_cs); + priv->gl_context = gl_create_context( + dpy, + GST_VAAPI_OBJECT_XSCREEN(window), + &parent_cs + ); if (!priv->gl_context) { GST_DEBUG("could not create GLX context"); goto end; @@ -226,7 +231,7 @@ gst_vaapi_window_glx_create_colormap(GstVaapiWindowGLX *window) GST_VAAPI_OBJECT_LOCK_DISPLAY(window); x11_trap_errors(); /* XXX: add a GstVaapiDisplayX11:x11-screen property? */ - screen = DefaultScreen(dpy); + screen = GST_VAAPI_OBJECT_XSCREEN(window); priv->cmap = XCreateColormap( dpy, RootWindow(dpy, screen), diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index f2ffbefadc..b46f08ae9f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -29,6 +29,7 @@ #include "gstvaapicompat.h" #include "gstvaapiwindow_x11.h" #include "gstvaapidisplay_x11.h" +#include "gstvaapidisplay_x11_priv.h" #include "gstvaapiutils.h" #include "gstvaapiutils_x11.h" #include "gstvaapi_priv.h" diff --git a/tests/test-windows.c b/tests/test-windows.c index d381191035..f6ea9d811b 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -105,7 +105,7 @@ main(int argc, char *argv[]) g_print("# Create window with gst_vaapi_window_x11_new_with_xid()\n"); g_print("#\n"); { - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(display); + Display * const dpy = gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)); Window rootwin, win; int screen; unsigned long white_pixel, black_pixel; From 9075c8d23def829426538c3b6d7271beb747ca1d Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 1 Apr 2010 13:55:19 +0000 Subject: [PATCH 0247/3781] Shorter structs. --- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index a13adbd236..58b85b4ab0 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -71,7 +71,7 @@ struct _GLContextState { Window window; XVisualInfo *visual; GLXContext context; - guint swapped_buffers; + guint swapped_buffers : 1; }; GLContextState * @@ -96,10 +96,10 @@ gl_swap_buffers(GLContextState *cs) typedef struct _GLTextureState GLTextureState; struct _GLTextureState { - gboolean was_enabled; - gboolean was_bound; GLenum target; GLuint old_texture; + guint was_enabled : 1; + guint was_bound : 1; }; gboolean From 3ddab3f2537cc87f72920fb34c05cca5fe5a1ca2 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 1 Apr 2010 15:38:59 +0000 Subject: [PATCH 0248/3781] The shared GL context in GstVaapiTexture is only useful for cases where TFP+FBO are used, thus avoiding the need fully preserve the states and call into glGet*() functions that need synchronization. --- gst-libs/gst/vaapi/gstvaapitexture.c | 105 ++++++++++++++---------- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 5 +- 2 files changed, 63 insertions(+), 47 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 949ef85d2f..578e4c97ab 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -80,6 +80,12 @@ _gst_vaapi_texture_destroy_objects(GstVaapiTexture *texture) } GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); #else + GLContextState old_cs; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + if (priv->gl_context) + gl_set_current_context(priv->gl_context, &old_cs); + if (priv->fbo) { gl_destroy_framebuffer_object(priv->fbo); priv->fbo = NULL; @@ -89,6 +95,13 @@ _gst_vaapi_texture_destroy_objects(GstVaapiTexture *texture) gl_destroy_pixmap_object(priv->pixo); priv->pixo = NULL; } + + if (priv->gl_context) { + gl_set_current_context(&old_cs, NULL); + gl_destroy_context(priv->gl_context); + priv->gl_context = NULL; + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); #endif } @@ -105,19 +118,13 @@ gst_vaapi_texture_destroy(GstVaapiTexture *texture) glDeleteTextures(1, &texture_id); GST_VAAPI_OBJECT_ID(texture) = 0; } - - if (priv->gl_context) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - gl_destroy_context(priv->gl_context); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - priv->gl_context = NULL; - } } static gboolean _gst_vaapi_texture_create_objects(GstVaapiTexture *texture, GLuint texture_id) { GstVaapiTexturePrivate * const priv = texture->priv; + gboolean success = FALSE; #if USE_VAAPI_GLX VAStatus status; @@ -130,36 +137,8 @@ _gst_vaapi_texture_create_objects(GstVaapiTexture *texture, GLuint texture_id) &priv->gl_surface ); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - if (!vaapi_check_status(status, "vaCreateSurfaceGLX()")) - return FALSE; + success = vaapi_check_status(status, "vaCreateSurfaceGLX()"); #else - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - priv->pixo = gl_create_pixmap_object( - GST_VAAPI_OBJECT_XDISPLAY(texture), - priv->width, - priv->height - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - if (!priv->pixo) - return FALSE; - - priv->fbo = gl_create_framebuffer_object( - priv->target, - texture_id, - priv->width, - priv->height - ); - if (!priv->fbo) - return FALSE; -#endif - return TRUE; -} - -static gboolean -gst_vaapi_texture_create(GstVaapiTexture *texture) -{ - GstVaapiTexturePrivate * const priv = texture->priv; - GLuint texture_id; GLContextState old_cs; GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); @@ -169,9 +148,37 @@ gst_vaapi_texture_create(GstVaapiTexture *texture) GST_VAAPI_OBJECT_XSCREEN(texture), &old_cs ); + if (!priv->gl_context || !gl_set_current_context(priv->gl_context, NULL)) + goto end; + + priv->pixo = gl_create_pixmap_object( + GST_VAAPI_OBJECT_XDISPLAY(texture), + priv->width, + priv->height + ); + if (!priv->pixo) + goto end; + + priv->fbo = gl_create_framebuffer_object( + priv->target, + texture_id, + priv->width, + priv->height + ); + if (priv->fbo) + success = TRUE; +end: + gl_set_current_context(&old_cs, NULL); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - if (!priv->gl_context) - return FALSE; +#endif + return success; +} + +static gboolean +gst_vaapi_texture_create(GstVaapiTexture *texture) +{ + GstVaapiTexturePrivate * const priv = texture->priv; + GLuint texture_id; if (priv->foreign_texture) texture_id = GST_VAAPI_OBJECT_ID(texture); @@ -585,6 +592,7 @@ _gst_vaapi_texture_put_surface( return FALSE; #else guint surface_width, surface_height; + GLContextState old_cs; GLTextureState ts; gboolean success = FALSE; @@ -604,8 +612,15 @@ _gst_vaapi_texture_put_surface( if (!vaapi_check_status(status, "vaPutSurface() [TFP]")) return FALSE; - if (!gl_bind_texture(&ts, priv->target, GST_VAAPI_OBJECT_ID(texture))) - return FALSE; + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + success = gl_set_current_context(priv->gl_context, &old_cs); + if (!success) + goto end; + + if (!gl_bind_texture(&ts, priv->target, GST_VAAPI_OBJECT_ID(texture))) { + GST_DEBUG("could not bind texture %u", GST_VAAPI_OBJECT_ID(texture)); + goto out_reset_context; + } success = gl_bind_framebuffer_object(priv->fbo); if (!success) { @@ -613,15 +628,15 @@ _gst_vaapi_texture_put_surface( goto out_unbind_texture; } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); success = gst_vaapi_surface_sync(surface); + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); if (!success) { GST_DEBUG("could not render surface to pixmap"); goto out_unbind_fbo; } - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); success = gl_bind_pixmap_object(priv->pixo); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); if (!success) { GST_DEBUG("could not bind GLX pixmap"); goto out_unbind_fbo; @@ -637,9 +652,7 @@ _gst_vaapi_texture_put_surface( } glEnd(); - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); success = gl_unbind_pixmap_object(priv->pixo); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); if (!success) { GST_DEBUG("could not release GLX pixmap"); goto out_unbind_fbo; @@ -649,6 +662,10 @@ out_unbind_fbo: success = gl_unbind_framebuffer_object(priv->fbo); out_unbind_texture: gl_unbind_texture(&ts); +out_reset_context: + success = gl_set_current_context(&old_cs, NULL); +end: + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); return success; #endif return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 9ca7b7cfb9..1dcf4a5d12 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -572,13 +572,12 @@ gst_vaapi_window_glx_put_texture( fill_rect(&tmp_dst_rect, dst_rect, win_width, win_height); dst_rect = &tmp_dst_rect; - tex_target = gst_vaapi_texture_get_target(texture); - tex_id = gst_vaapi_texture_get_id(texture); - /* XXX: only GL_TEXTURE_2D textures are supported at this time */ + tex_target = gst_vaapi_texture_get_target(texture); if (tex_target != GL_TEXTURE_2D) return FALSE; + tex_id = gst_vaapi_texture_get_id(texture); if (!gl_bind_texture(&ts, tex_target, tex_id)) return FALSE; glColor4f(1.0f, 1.0f, 1.0f, 1.0f); From 8e6dea5b74b489318c55d7d5694f27d16ec0f0dd Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 1 Apr 2010 16:11:54 +0000 Subject: [PATCH 0249/3781] Fix get-out conditions. --- gst-libs/gst/vaapi/gstvaapitexture.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 578e4c97ab..199ea11ad9 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -659,11 +659,13 @@ _gst_vaapi_texture_put_surface( } out_unbind_fbo: - success = gl_unbind_framebuffer_object(priv->fbo); + if (!gl_unbind_framebuffer_object(priv->fbo)) + success = FALSE; out_unbind_texture: gl_unbind_texture(&ts); out_reset_context: - success = gl_set_current_context(&old_cs, NULL); + if (!gl_set_current_context(&old_cs, NULL)) + success = FALSE; end: GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); return success; From b8aadb9e82fa9b4f5e5fb6e7d191e21261ca0dce Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 2 Apr 2010 11:27:23 +0000 Subject: [PATCH 0250/3781] Fix TFP logic and simplify the FBO model. i.e. it's not necessary to create another texture (and storage) for the TFP, simply a new texture name. --- gst-libs/gst/vaapi/gstvaapitexture.c | 18 +++---- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 66 +++++++++++--------------- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 19 ++++---- 3 files changed, 43 insertions(+), 60 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 199ea11ad9..083f0346a7 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -593,7 +593,6 @@ _gst_vaapi_texture_put_surface( #else guint surface_width, surface_height; GLContextState old_cs; - GLTextureState ts; gboolean success = FALSE; gst_vaapi_surface_get_size(surface, &surface_width, &surface_height); @@ -613,19 +612,16 @@ _gst_vaapi_texture_put_surface( return FALSE; GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - success = gl_set_current_context(priv->gl_context, &old_cs); - if (!success) - goto end; - - if (!gl_bind_texture(&ts, priv->target, GST_VAAPI_OBJECT_ID(texture))) { - GST_DEBUG("could not bind texture %u", GST_VAAPI_OBJECT_ID(texture)); - goto out_reset_context; + if (priv->gl_context) { + success = gl_set_current_context(priv->gl_context, &old_cs); + if (!success) + goto end; } success = gl_bind_framebuffer_object(priv->fbo); if (!success) { GST_DEBUG("could not bind FBO"); - goto out_unbind_texture; + goto out_reset_context; } GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); @@ -661,10 +657,8 @@ _gst_vaapi_texture_put_surface( out_unbind_fbo: if (!gl_unbind_framebuffer_object(priv->fbo)) success = FALSE; -out_unbind_texture: - gl_unbind_texture(&ts); out_reset_context: - if (!gl_set_current_context(&old_cs, NULL)) + if (priv->gl_context && !gl_set_current_context(&old_cs, NULL)) success = FALSE; end: GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 60a7bc7e98..3e6632bb83 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -474,7 +474,7 @@ gl_bind_texture(GLTextureState *ts, GLenum target, GLuint texture) return FALSE; } - if (ts->was_enabled && !gl_get_param(texture_binding, &ts->old_texture)) + if (!gl_get_param(texture_binding, &ts->old_texture)) return FALSE; ts->was_bound = texture == ts->old_texture; @@ -780,7 +780,7 @@ gl_create_pixmap_object(Display *dpy, guint width, guint height) int fbconfig_attrs[32] = { GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, - GLX_DOUBLEBUFFER, GL_TRUE, + GLX_DOUBLEBUFFER, GL_FALSE, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_RENDERABLE, GL_TRUE, GLX_Y_INVERTED_EXT, GL_TRUE, @@ -855,7 +855,7 @@ gl_create_pixmap_object(Display *dpy, guint width, guint height) if (!fbconfig) goto error; - /* Initialize GLX Pixmap attrutes */ + /* Initialize GLX Pixmap attributes */ for (attr = pixmap_attrs; *attr != GL_NONE; attr += 2) ; *attr++ = GLX_TEXTURE_FORMAT_EXT; @@ -870,6 +870,14 @@ gl_create_pixmap_object(Display *dpy, guint width, guint height) free(fbconfig); if (x11_untrap_errors() != 0) goto error; + + pixo->target = GL_TEXTURE_2D; + glGenTextures(1, &pixo->texture); + if (!gl_bind_texture(&pixo->old_texture, pixo->target, pixo->texture)) + goto error; + glTexParameteri(pixo->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(pixo->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl_unbind_texture(&pixo->old_texture); return pixo; error: @@ -891,6 +899,11 @@ gl_destroy_pixmap_object(GLPixmapObject *pixo) gl_unbind_pixmap_object(pixo); + if (pixo->texture) { + glDeleteTextures(1, &pixo->texture); + pixo->texture = 0; + } + if (pixo->glx_pixmap) { glXDestroyPixmap(pixo->dpy, pixo->glx_pixmap); pixo->glx_pixmap = None; @@ -921,6 +934,9 @@ gl_bind_pixmap_object(GLPixmapObject *pixo) if (pixo->is_bound) return TRUE; + if (!gl_bind_texture(&pixo->old_texture, pixo->target, pixo->texture)) + return FALSE; + x11_trap_errors(); gl_vtable->glx_bind_tex_image( pixo->dpy, @@ -966,6 +982,8 @@ gl_unbind_pixmap_object(GLPixmapObject *pixo) return FALSE; } + gl_unbind_texture(&pixo->old_texture); + pixo->is_bound = FALSE; return TRUE; } @@ -992,9 +1010,7 @@ gl_create_framebuffer_object( { GLVTable * const gl_vtable = gl_get_vtable(); GLFramebufferObject *fbo; - GLTextureState ts; GLenum status; - gboolean texture_was_bound; if (!gl_vtable || !gl_vtable->has_framebuffer_object) return NULL; @@ -1010,35 +1026,22 @@ gl_create_framebuffer_object( fbo->width = width; fbo->height = height; fbo->fbo = 0; - fbo->fbo_buffer = 0; - fbo->fbo_target = target; - fbo->fbo_texture = 0; fbo->old_fbo = 0; fbo->is_bound = FALSE; - fbo->fbo_texture = gl_create_texture(target, GL_BGRA, width, height); - if (!fbo->fbo_texture) - goto error; - gl_get_param(GL_FRAMEBUFFER_BINDING, &fbo->old_fbo); gl_vtable->gl_gen_framebuffers(1, &fbo->fbo); gl_vtable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo->fbo); - gl_vtable->gl_gen_renderbuffers(1, &fbo->fbo_buffer); - gl_vtable->gl_bind_renderbuffer(GL_RENDERBUFFER_EXT, fbo->fbo_buffer); + gl_vtable->gl_framebuffer_texture_2d( + GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + target, texture, + 0 + ); - texture_was_bound = gl_bind_texture(&ts, target, texture); - if (texture_was_bound) { - gl_vtable->gl_framebuffer_texture_2d( - GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, texture, - 0 - ); - gl_unbind_texture(&ts); - } status = gl_vtable->gl_check_framebuffer_status(GL_DRAW_FRAMEBUFFER_EXT); gl_vtable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo->old_fbo); - if (!texture_was_bound || status != GL_FRAMEBUFFER_COMPLETE_EXT) + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) goto error; return fbo; @@ -1063,16 +1066,6 @@ gl_destroy_framebuffer_object(GLFramebufferObject *fbo) gl_unbind_framebuffer_object(fbo); - if (fbo->fbo_texture) { - glDeleteTextures(1, &fbo->fbo_texture); - fbo->fbo_texture = 0; - } - - if (fbo->fbo_buffer) { - gl_vtable->gl_delete_renderbuffers(1, &fbo->fbo_buffer); - fbo->fbo_buffer = 0; - } - if (fbo->fbo) { gl_vtable->gl_delete_framebuffers(1, &fbo->fbo); fbo->fbo = 0; @@ -1117,9 +1110,6 @@ gl_bind_framebuffer_object(GLFramebufferObject *fbo) glTranslatef(-1.0f, -1.0f, 0.0f); glScalef(2.0f / width, 2.0f / height, 1.0f); - if (!gl_bind_texture(&fbo->old_texture, fbo->fbo_target, fbo->fbo_texture)) - return FALSE; - fbo->is_bound = TRUE; return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 58b85b4ab0..4d09fdd740 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -148,12 +148,15 @@ gl_get_vtable(void) typedef struct _GLPixmapObject GLPixmapObject; struct _GLPixmapObject { - Display *dpy; - guint width; - guint height; - Pixmap pixmap; - GLXPixmap glx_pixmap; - guint is_bound : 1; + Display *dpy; + GLenum target; + GLuint texture; + GLTextureState old_texture; + guint width; + guint height; + Pixmap pixmap; + GLXPixmap glx_pixmap; + guint is_bound : 1; }; GLPixmapObject * @@ -177,11 +180,7 @@ struct _GLFramebufferObject { guint width; guint height; GLuint fbo; - GLuint fbo_buffer; - GLenum fbo_target; - GLuint fbo_texture; GLuint old_fbo; - GLTextureState old_texture; guint is_bound : 1; }; From d1709fef62ac07358e5e55663c5c7dbfe77fd7c4 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 16 Apr 2010 13:47:30 +0000 Subject: [PATCH 0251/3781] Fix gl_create_context() to find a GLXFBConfig compatible with the parent GL context. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 63 ++++++++++++++++++++------ 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 3e6632bb83..6cd88af8d9 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -287,16 +287,17 @@ GLContextState * gl_create_context(Display *dpy, int screen, GLContextState *parent) { GLContextState *cs; - GLXFBConfig *fb_configs = NULL; - int n_fb_configs; + GLXFBConfig *fbconfigs = NULL; + int fbconfig_id, val, n, n_fbconfigs; + Status status; - static GLint fb_config_attrs[] = { + static GLint fbconfig_attrs[] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DOUBLEBUFFER, True, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, None }; @@ -310,17 +311,49 @@ gl_create_context(Display *dpy, int screen, GLContextState *parent) cs->context = NULL; cs->swapped_buffers = FALSE; - fb_configs = glXChooseFBConfig(dpy, screen, fb_config_attrs, &n_fb_configs); - if (!fb_configs) - goto error; + if (parent && parent->context) { + status = glXQueryContext( + parent->display, + parent->context, + GLX_FBCONFIG_ID, &fbconfig_id + ); + if (status != Success) + goto error; - cs->visual = glXGetVisualFromFBConfig(dpy, fb_configs[0]); - if (!cs->visual) - goto error; + fbconfigs = glXGetFBConfigs(dpy, screen, &n_fbconfigs); + if (!fbconfigs) + goto error; + /* Find out a GLXFBConfig compatible with the parent context */ + for (n = 0; n < n_fbconfigs; n++) { + status = glXGetFBConfigAttrib( + dpy, + fbconfigs[n], + GLX_FBCONFIG_ID, &val + ); + if (status == Success && val == fbconfig_id) + break; + } + if (n == n_fbconfigs) + goto error; + } + else { + fbconfigs = glXChooseFBConfig( + dpy, + screen, + fbconfig_attrs, &n_fbconfigs + ); + if (!fbconfigs) + goto error; + + /* Select the first one */ + n = 0; + } + + cs->visual = glXGetVisualFromFBConfig(dpy, fbconfigs[n]); cs->context = glXCreateNewContext( dpy, - fb_configs[0], + fbconfigs[n], GLX_RGBA_TYPE, parent ? parent->context : NULL, True @@ -332,8 +365,8 @@ error: gl_destroy_context(cs); cs = NULL; end: - if (fb_configs) - XFree(fb_configs); + if (fbconfigs) + XFree(fbconfigs); return cs; } From fa11094655dc5751646c73c48e42801f9a5fe16c Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 20 Apr 2010 07:51:23 +0000 Subject: [PATCH 0252/3781] Fix OpenGL rendering on G45 systems. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 6cd88af8d9..d84edfb857 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -320,6 +320,9 @@ gl_create_context(Display *dpy, int screen, GLContextState *parent) if (status != Success) goto error; + if (fbconfig_id == GLX_DONT_CARE) + goto choose_fbconfig; + fbconfigs = glXGetFBConfigs(dpy, screen, &n_fbconfigs); if (!fbconfigs) goto error; @@ -338,6 +341,7 @@ gl_create_context(Display *dpy, int screen, GLContextState *parent) goto error; } else { + choose_fbconfig: fbconfigs = glXChooseFBConfig( dpy, screen, From 508edba9a0cb6d783efe7e307b0d5e2ad9d37a69 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 20 Apr 2010 13:36:04 +0000 Subject: [PATCH 0253/3781] Add VA profile abstraction. --- docs/reference/libs/libs-docs.xml.in | 1 + docs/reference/libs/libs-sections.txt | 17 +- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidisplay.c | 163 ++++++++++++++++-- gst-libs/gst/vaapi/gstvaapidisplay.h | 18 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 3 +- gst-libs/gst/vaapi/gstvaapiprofile.c | 200 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiprofile.h | 115 +++++++++++++ tests/test-display.c | 51 +++++- 9 files changed, 546 insertions(+), 24 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiprofile.c create mode 100644 gst-libs/gst/vaapi/gstvaapiprofile.h diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 53e6741f28..1fc8b46b48 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -23,6 +23,7 @@ + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 7a8414dc03..0f2389d3f9 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -142,7 +142,10 @@ gst_vaapi_display_get_width gst_vaapi_display_get_height gst_vaapi_display_get_size gst_vaapi_display_get_pixel_aspect_ratio -gst_vaapi_display_has_profile +gst_vaapi_display_get_decode_caps +gst_vaapi_display_has_decoder +gst_vaapi_display_get_encode_caps +gst_vaapi_display_has_encoder gst_vaapi_display_get_image_caps gst_vaapi_display_has_image_format gst_vaapi_display_get_subpicture_caps @@ -369,6 +372,18 @@ gst_vaapi_image_format_get_caps gst_vaapi_image_format_get_score
+
+gstvaapiprofile +GstVaapiProfile +GstVaapiCodec +GstVaapiProfile +gst_vaapi_profile +gst_vaapi_profile_from_caps +gst_vaapi_profile_get_va_profile +gst_vaapi_profile_get_caps +gst_vaapi_profile_get_codec +
+
gstvaapitexture GstVaapiTexture diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 6809431019..f8c59de9e2 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -18,6 +18,7 @@ libgstvaapi_source_c = \ gstvaapimarshal.c \ gstvaapiobject.c \ gstvaapiparamspecs.c \ + gstvaapiprofile.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ gstvaapisurfacepool.c \ @@ -36,6 +37,7 @@ libgstvaapi_source_h = \ gstvaapiimagepool.h \ gstvaapiobject.h \ gstvaapiparamspecs.h \ + gstvaapiprofile.h \ gstvaapisubpicture.h \ gstvaapisurface.h \ gstvaapisurfacepool.h \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index d879a18305..bb4694e3ec 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -126,16 +126,37 @@ compare_rgb_formats(gconstpointer a, gconstpointer b) /* Check if profiles array contains profile */ static inline gboolean -find_profile(GArray *profiles, VAProfile profile) +find_profile(GArray *profiles, GstVaapiProfile profile) { guint i; for (i = 0; i < profiles->len; i++) - if (g_array_index(profiles, VAProfile, i) == profile) + if (g_array_index(profiles, GstVaapiProfile, i) == profile) return TRUE; return FALSE; } +/* Convert profiles array to GstCaps */ +static GstCaps * +get_profile_caps(GArray *profiles) +{ + GstVaapiProfile profile; + GstCaps *out_caps, *caps; + guint i; + + out_caps = gst_caps_new_empty(); + if (!out_caps) + return NULL; + + for (i = 0; i < profiles->len; i++) { + profile = g_array_index(profiles, GstVaapiProfile, i); + caps = gst_vaapi_profile_get_caps(profile); + if (caps) + gst_caps_append(out_caps, caps); + } + return out_caps; +} + /* Check if formats array contains format */ static inline gboolean find_format(GArray *formats, GstVaapiImageFormat format) @@ -150,7 +171,7 @@ find_format(GArray *formats, GstVaapiImageFormat format) /* Convert formats array to GstCaps */ static GstCaps * -get_caps(GArray *formats) +get_format_caps(GArray *formats) { GstVaapiImageFormat format; GstCaps *out_caps, *caps; @@ -219,9 +240,14 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) { GstVaapiDisplayPrivate * const priv = display->priv; - if (priv->profiles) { - g_array_free(priv->profiles, TRUE); - priv->profiles = NULL; + if (priv->decoders) { + g_array_free(priv->decoders, TRUE); + priv->decoders = NULL; + } + + if (priv->encoders) { + g_array_free(priv->encoders, TRUE); + priv->encoders = NULL; } if (priv->image_formats) { @@ -252,9 +278,10 @@ gst_vaapi_display_create(GstVaapiDisplay *display) GstVaapiDisplayPrivate * const priv = display->priv; gboolean has_errors = TRUE; VAProfile *profiles = NULL; + VAEntrypoint *entrypoints = NULL; VAImageFormat *formats = NULL; unsigned int *flags = NULL; - gint i, n, major_version, minor_version; + gint i, j, n, num_entrypoints, major_version, minor_version; VAStatus status; if (!priv->display && priv->create_display) { @@ -284,6 +311,9 @@ gst_vaapi_display_create(GstVaapiDisplay *display) profiles = g_new(VAProfile, vaMaxNumProfiles(priv->display)); if (!profiles) goto end; + entrypoints = g_new(VAEntrypoint, vaMaxNumEntrypoints(priv->display)); + if (!entrypoints) + goto end; status = vaQueryConfigProfiles(priv->display, profiles, &n); if (!vaapi_check_status(status, "vaQueryConfigProfiles()")) goto end; @@ -292,10 +322,50 @@ gst_vaapi_display_create(GstVaapiDisplay *display) for (i = 0; i < n; i++) GST_DEBUG(" %s", string_of_VAProfile(profiles[i])); - priv->profiles = g_array_new(FALSE, FALSE, sizeof(VAProfile)); - if (!priv->profiles) + priv->decoders = g_array_new(FALSE, FALSE, sizeof(GstVaapiProfile)); + if (!priv->decoders) goto end; - g_array_append_vals(priv->profiles, profiles, n); + priv->encoders = g_array_new(FALSE, FALSE, sizeof(GstVaapiProfile)); + if (!priv->encoders) + goto end; + + for (i = 0; i < n; i++) { + GstVaapiProfile profile; + gboolean has_decoder = FALSE, has_encoder = FALSE; + + profile = gst_vaapi_profile(profiles[i]); + if (!profile) + continue; + + status = vaQueryConfigEntrypoints( + priv->display, + profiles[i], + entrypoints, &num_entrypoints + ); + if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()")) + goto end; + + for (j = 0; j < num_entrypoints; j++) { + switch (entrypoints[j]) { + case VAEntrypointVLD: + case VAEntrypointIZZ: + case VAEntrypointIDCT: + case VAEntrypointMoComp: + case VAEntrypointDeblocking: + has_decoder = TRUE; + break; +#if VA_CHECK_VERSION(0,30,0) + case VAEntrypointEncSlice: + has_encoder = TRUE; + break; +#endif + } + } + if (has_decoder) + g_array_append_val(priv->decoders, profile); + if (has_encoder) + g_array_append_val(priv->encoders, profile); + } /* VA image formats */ formats = g_new(VAImageFormat, vaMaxNumImageFormats(priv->display)); @@ -340,6 +410,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) has_errors = FALSE; end: g_free(profiles); + g_free(entrypoints); g_free(formats); g_free(flags); return !has_errors; @@ -485,7 +556,8 @@ gst_vaapi_display_init(GstVaapiDisplay *display) priv->height_mm = 0; priv->par_n = 1; priv->par_d = 1; - priv->profiles = NULL; + priv->decoders = NULL; + priv->encoders = NULL; priv->image_formats = NULL; priv->subpicture_formats = NULL; priv->create_display = TRUE; @@ -689,20 +761,75 @@ gst_vaapi_display_get_pixel_aspect_ratio( } /** - * gst_vaapi_display_has_profile: + * gst_vaapi_display_get_decode_caps: + * @display: a #GstVaapiDisplay + * + * Gets the supported profiles for decoding as #GstCaps capabilities. + * + * Return value: a newly allocated #GstCaps object, possibly empty + */ +GstCaps * +gst_vaapi_display_get_decode_caps(GstVaapiDisplay *display) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + return get_profile_caps(display->priv->decoders); +} + +/** + * gst_vaapi_display_has_decoder: * @display: a #GstVaapiDisplay * @profile: a #VAProfile * - * Returns whether VA @display supports @profile. + * Returns whether VA @display supports @profile for decoding. * - * Return value: %TRUE if VA @display supports @profile + * Return value: %TRUE if VA @display supports @profile for decoding. */ gboolean -gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile) +gst_vaapi_display_has_decoder( + GstVaapiDisplay *display, + GstVaapiProfile profile +) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); - return find_profile(display->priv->profiles, profile); + return find_profile(display->priv->decoders, profile); +} + +/** + * gst_vaapi_display_get_encode_caps: + * @display: a #GstVaapiDisplay + * + * Gets the supported profiles for decoding as #GstCaps capabilities. + * + * Return value: a newly allocated #GstCaps object, possibly empty + */ +GstCaps * +gst_vaapi_display_get_encode_caps(GstVaapiDisplay *display) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + return get_profile_caps(display->priv->encoders); +} + +/** + * gst_vaapi_display_has_encoder: + * @display: a #GstVaapiDisplay + * @profile: a #VAProfile + * + * Returns whether VA @display supports @profile for encoding. + * + * Return value: %TRUE if VA @display supports @profile for encoding. + */ +gboolean +gst_vaapi_display_has_encoder( + GstVaapiDisplay *display, + GstVaapiProfile profile +) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + + return find_profile(display->priv->encoders, profile); } /** @@ -726,7 +853,7 @@ gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return get_caps(display->priv->image_formats); + return get_format_caps(display->priv->image_formats); } /** @@ -768,7 +895,7 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return get_caps(display->priv->subpicture_formats); + return get_format_caps(display->priv->subpicture_formats); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 8f605f8d07..b66cdf89d9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -29,6 +29,7 @@ #include #include +#include G_BEGIN_DECLS @@ -141,8 +142,23 @@ gst_vaapi_display_get_pixel_aspect_ratio( guint *par_d ); +GstCaps * +gst_vaapi_display_get_decode_caps(GstVaapiDisplay *display); + gboolean -gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile); +gst_vaapi_display_has_decoder( + GstVaapiDisplay *display, + GstVaapiProfile profile +); + +GstCaps * +gst_vaapi_display_get_encode_caps(GstVaapiDisplay *display); + +gboolean +gst_vaapi_display_has_encoder( + GstVaapiDisplay *display, + GstVaapiProfile profile +); GstCaps * gst_vaapi_display_get_image_caps(GstVaapiDisplay *display); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 0f8adbd04a..2427babf1c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -77,7 +77,8 @@ struct _GstVaapiDisplayPrivate { guint height_mm; guint par_n; guint par_d; - GArray *profiles; + GArray *decoders; + GArray *encoders; GArray *image_formats; GArray *subpicture_formats; guint create_display : 1; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c new file mode 100644 index 0000000000..9421fda6e3 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -0,0 +1,200 @@ +/* + * gstvaapiprofile.c - VA profile abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * SECTION:gstvaapiprofile + * @short_description: VA profile abstraction + */ + +#include "config.h" +#include +#include "gstvaapicompat.h" +#include "gstvaapiprofile.h" + +typedef struct _GstVaapiProfileMap GstVaapiProfileMap; + +struct _GstVaapiProfileMap { + GstVaapiProfile profile; + VAProfile va_profile; + const char *caps_str; +}; + +/* Profiles */ +static const GstVaapiProfileMap gst_vaapi_profiles[] = { + { GST_VAAPI_PROFILE_MPEG2_SIMPLE, VAProfileMPEG2Simple, + "video/mpeg, mpegversion=2, profile=simple" + }, + { GST_VAAPI_PROFILE_MPEG2_MAIN, VAProfileMPEG2Main, + "video/mpeg, mpegversion=2, profile=main" + }, + { GST_VAAPI_PROFILE_MPEG4_SIMPLE, VAProfileMPEG4Simple, + "video/mpeg, mpegversion=4, profile=simple" + }, + { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, + "video/mpeg, mpegversion=4, profile=advanced-simple" + }, + { GST_VAAPI_PROFILE_MPEG4_MAIN, VAProfileMPEG4Main, + "video/mpeg, mpegversion=4, profile=main" + }, +#if VA_CHECK_VERSION(0,30,0) + { GST_VAAPI_PROFILE_H263_BASELINE, VAProfileH263Baseline, + "video/x-h263, variant=itu, h263version=h263, profile=baseline" + }, +#endif + { GST_VAAPI_PROFILE_H264_BASELINE, VAProfileH264Baseline, + "video/x-h264, variant=itu, profile=baseline" + }, + { GST_VAAPI_PROFILE_H264_MAIN, VAProfileH264Main, + "video/x-h264, variant=itu, profile=main" + }, + { GST_VAAPI_PROFILE_H264_HIGH, VAProfileH264High, + "video/x-h264, variant=itu, profile=high" + }, + { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, + "video/x-vc1, profile=simple" + }, + { GST_VAAPI_PROFILE_VC1_MAIN, VAProfileVC1Main, + "video/x-vc1, profile=main" + }, + { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, + "video/x-vc1, profile=advanced" + }, + { 0, } +}; + +static const GstVaapiProfileMap * +get_map(GstVaapiProfile profile) +{ + const GstVaapiProfileMap *m; + + for (m = gst_vaapi_profiles; m->profile; m++) + if (m->profile == profile) + return m; + return NULL; +} + +/** + * gst_vaapi_profile: + * @va_profile: a #VAProfile + * + * Converts a VA profile into the corresponding #GstVaapiProfile. If the profile cannot be represented by #GstVaapiProfile, then zero is returned. + * + * Return value: the #GstVaapiProfile describing the @va_profile + */ +GstVaapiProfile +gst_vaapi_profile(VAProfile profile) +{ + const GstVaapiProfileMap *m; + + for (m = gst_vaapi_profiles; m->profile; m++) + if (m->va_profile == profile) + return m->profile; + return 0; +} + +/** + * gst_vaapi_profile_from_caps: + * @caps: a #GstCaps + * + * Converts @caps into the corresponding #GstVaapiProfile. If the + * profile cannot be represented by #GstVaapiProfile, then zero is + * returned. + * + * Return value: the #GstVaapiProfile describing the @caps + */ +GstVaapiProfile +gst_vaapi_profile_from_caps(GstCaps *caps) +{ + const GstVaapiProfileMap *m; + GstCaps *caps_test; + GstStructure *structure; + const gchar *name; + gsize namelen; + gboolean found; + + if (!caps) + return 0; + + structure = gst_caps_get_structure(caps, 0); + if (!structure) + return 0; + + name = gst_structure_get_name(structure); + namelen = strlen(name); + + found = FALSE; + for (m = gst_vaapi_profiles; !found && m->profile; m++) { + if (strncmp(name, m->caps_str, namelen) != 0) + continue; + caps_test = gst_caps_from_string(m->caps_str); + found = gst_caps_is_always_compatible(caps_test, caps); + gst_caps_unref(caps_test); + } + return found ? m->va_profile : 0; +} + +/** + * gst_vaapi_profile_get_va_profile: + * @profile: a #GstVaapiProfile + * + * Converts a #GstVaapiProfile into the corresponding VA profile. If + * no matching VA profile was found, -1 is returned and this error + * must be reported to be fixed. + * + * Return value: the VA profile, or -1 if none was found + */ +VAProfile +gst_vaapi_profile_get_va_profile(GstVaapiProfile profile) +{ + const GstVaapiProfileMap * const m = get_map(profile); + + return m ? m->va_profile : (VAProfile)-1; +} + +/** + * gst_vaapi_profile_get_caps: + * @profile: a #GstVaapiProfile + * + * Converts a #GstVaapiProfile into the corresponding #GstCaps. If no + * matching caps were found, %NULL is returned. + * + * Return value: the newly allocated #GstCaps, or %NULL if none was found + */ +GstCaps * +gst_vaapi_profile_get_caps(GstVaapiProfile profile) +{ + const GstVaapiProfileMap * const m = get_map(profile); + + return m ? gst_caps_from_string(m->caps_str) : NULL; +} + +/** + * gst_vaapi_profile_get_codec: + * @profile: a #GstVaapiProfile + * + * Extracts the #GstVaapiCodec from @profile. + * + * Return value: the #GstVaapiCodec from @profile + */ +GstVaapiCodec +gst_vaapi_profile_get_codec(GstVaapiProfile profile) +{ + return (GstVaapiCodec)(((guint32)profile) & 0xffffff00); +} diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h new file mode 100644 index 0000000000..62d0ccbbee --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -0,0 +1,115 @@ +/* + * gstvaapiprofile.h - VA profile abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_PROFILE_H +#define GST_VAAPI_PROFILE_H + +#include + +G_BEGIN_DECLS + +typedef enum _GstVaapiCodec GstVaapiCodec; +typedef enum _GstVaapiProfile GstVaapiProfile; + +/** + * GstVaapiCodec: + * @GST_VAAPI_CODEC_MPEG1: MPEG-1 (ISO/IEC 11172) + * @GST_VAAPI_CODEC_MPEG2: MPEG-2 (ISO/IEC 13818-2) + * @GST_VAAPI_CODEC_MPEG4: MPEG-4 Part 2 (ISO/IEC 14496-2) + * @GST_VAAPI_CODEC_H263: H.263 + * @GST_VAAPI_CODEC_H264: H.264 aka MPEG-4 Part 10 (ISO/IEC 14496-10) + * @GST_VAAPI_CODEC_VC1: VC-1 (SMPTE 421M) + * + * The set of all codecs for #GstVaapiCodec. + */ +enum _GstVaapiCodec { + GST_VAAPI_CODEC_MPEG1 = GST_MAKE_FOURCC('M','P','1',0), + GST_VAAPI_CODEC_MPEG2 = GST_MAKE_FOURCC('M','P','2',0), + GST_VAAPI_CODEC_MPEG4 = GST_MAKE_FOURCC('M','P','4',0), + GST_VAAPI_CODEC_H263 = GST_MAKE_FOURCC('2','6','3',0), + GST_VAAPI_CODEC_H264 = GST_MAKE_FOURCC('2','6','4',0), + GST_VAAPI_CODEC_VC1 = GST_MAKE_FOURCC('V','C','1',0), +}; + +/** + * GstVaapiProfile: + * @GST_VAAPI_PROFILE_MPEG1: + * MPEG-1 + * @GST_VAAPI_PROFILE_MPEG2_SIMPLE: + * MPEG-2 simple profile + * @GST_VAAPI_PROFILE_MPEG2_MAIN: + * MPEG-2 main profile + * @GST_VAAPI_PROFILE_MPEG4_SIMPLE: + * MPEG-4 Part-2 simple profile + * @GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE: + * MPEG-4 Part-2 advanced simple profile + * @GST_VAAPI_PROFILE_MPEG4_MAIN: + * MPEG-4 Part-2 main profile + * @GST_VAAPI_PROFILE_H263_BASELINE: + * H.263 baseline profile + * @GST_VAAPI_PROFILE_H264_BASELINE: + * H.264 (MPEG-4 Part-10) baseline profile + * @GST_VAAPI_PROFILE_H264_MAIN: + * H.264 (MPEG-4 Part-10) main profile + * @GST_VAAPI_PROFILE_H264_HIGH: + * H.264 (MPEG-4 Part-10) high profile + * @GST_VAAPI_PROFILE_VC1_SIMPLE: + * VC-1 simple profile + * @GST_VAAPI_PROFILE_VC1_MAIN: + * VC-1 main profile (WMV3) + * @GST_VAAPI_PROFILE_VC1_ADVANCED: + * VC-1 advanced profile + * + * The set of all profile for #GstVaapiProfile. + */ +enum _GstVaapiProfile { + GST_VAAPI_PROFILE_MPEG1 = GST_VAAPI_CODEC_MPEG1|1, + GST_VAAPI_PROFILE_MPEG2_SIMPLE = GST_VAAPI_CODEC_MPEG2|1, + GST_VAAPI_PROFILE_MPEG2_MAIN = GST_VAAPI_CODEC_MPEG2|2, + GST_VAAPI_PROFILE_MPEG4_SIMPLE = GST_VAAPI_CODEC_MPEG4|1, + GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE = GST_VAAPI_CODEC_MPEG4|2, + GST_VAAPI_PROFILE_MPEG4_MAIN = GST_VAAPI_CODEC_MPEG4|3, + GST_VAAPI_PROFILE_H263_BASELINE = GST_VAAPI_CODEC_H263|1, + GST_VAAPI_PROFILE_H264_BASELINE = GST_VAAPI_CODEC_H264|1, + GST_VAAPI_PROFILE_H264_MAIN = GST_VAAPI_CODEC_H264|2, + GST_VAAPI_PROFILE_H264_HIGH = GST_VAAPI_CODEC_H264|3, + GST_VAAPI_PROFILE_VC1_SIMPLE = GST_VAAPI_CODEC_VC1|1, + GST_VAAPI_PROFILE_VC1_MAIN = GST_VAAPI_CODEC_VC1|2, + GST_VAAPI_PROFILE_VC1_ADVANCED = GST_VAAPI_CODEC_VC1|3, +}; + +GstVaapiProfile +gst_vaapi_profile(VAProfile profile); + +GstVaapiProfile +gst_vaapi_profile_from_caps(GstCaps *caps); + +VAProfile +gst_vaapi_profile_get_va_profile(GstVaapiProfile profile); + +GstCaps * +gst_vaapi_profile_get_caps(GstVaapiProfile profile); + +GstVaapiCodec +gst_vaapi_profile_get_codec(GstVaapiProfile profile); + +G_END_DECLS + +#endif /* GST_GST_VAAPI_IMAGE_H */ diff --git a/tests/test-display.c b/tests/test-display.c index 54b136ec77..57972e7db8 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -33,7 +33,38 @@ #endif static void -print_caps(GstCaps *caps, const gchar *name) +print_profile_caps(GstCaps *caps, const gchar *name) +{ + guint i, n_caps = gst_caps_get_size(caps); + gint version; + const gchar *profile; + gboolean has_version; + + g_print("%u %s caps\n", n_caps, name); + + for (i = 0; i < gst_caps_get_size(caps); i++) { + GstStructure * const structure = gst_caps_get_structure(caps, i); + if (!structure) + g_error("could not get caps structure %d", i); + + has_version = ( + gst_structure_get_int(structure, "version", &version) || + gst_structure_get_int(structure, "mpegversion", &version) + ); + + g_print(" %s", gst_structure_get_name(structure)); + if (has_version) + g_print("%d", version); + + profile = gst_structure_get_string(structure, "profile"); + if (!profile) + g_error("could not get structure profile"); + g_print(": %s profile\n", profile); + } +} + +static void +print_format_caps(GstCaps *caps, const gchar *name) { guint i, n_caps = gst_caps_get_size(caps); @@ -84,18 +115,32 @@ dump_caps(GstVaapiDisplay *display) { GstCaps *caps; + caps = gst_vaapi_display_get_decode_caps(display); + if (!caps) + g_error("could not get VA decode caps"); + + print_profile_caps(caps, "decoders"); + gst_caps_unref(caps); + + caps = gst_vaapi_display_get_encode_caps(display); + if (!caps) + g_error("could not get VA encode caps"); + + print_profile_caps(caps, "encoders"); + gst_caps_unref(caps); + caps = gst_vaapi_display_get_image_caps(display); if (!caps) g_error("could not get VA image caps"); - print_caps(caps, "image"); + print_format_caps(caps, "image"); gst_caps_unref(caps); caps = gst_vaapi_display_get_subpicture_caps(display); if (!caps) g_error("could not get VA subpicture caps"); - print_caps(caps, "subpicture"); + print_format_caps(caps, "subpicture"); gst_caps_unref(caps); } From 30fbcb1ee86af9caf652100c28602945485b3bd1 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 21 Apr 2010 15:02:23 +0000 Subject: [PATCH 0254/3781] Add VA entrypoint abstraction. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 78 +++++++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapiprofile.h | 23 +++++++- 2 files changed, 94 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 9421fda6e3..385228b039 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -29,6 +29,7 @@ #include "gstvaapiprofile.h" typedef struct _GstVaapiProfileMap GstVaapiProfileMap; +typedef struct _GstVaapiEntrypointMap GstVaapiEntrypointMap; struct _GstVaapiProfileMap { GstVaapiProfile profile; @@ -36,6 +37,11 @@ struct _GstVaapiProfileMap { const char *caps_str; }; +struct _GstVaapiEntrypointMap { + GstVaapiEntrypoint entrypoint; + VAEntrypoint va_entrypoint; +}; + /* Profiles */ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_MPEG2_SIMPLE, VAProfileMPEG2Simple, @@ -79,8 +85,16 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { 0, } }; +/* Entry-points */ +static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = { + { GST_VAAPI_ENTRYPOINT_VLD, VAEntrypointVLD }, + { GST_VAAPI_ENTRYPOINT_IDCT, VAEntrypointIDCT }, + { GST_VAAPI_ENTRYPOINT_MOCO, VAEntrypointMoComp }, + { 0, } +}; + static const GstVaapiProfileMap * -get_map(GstVaapiProfile profile) +get_profiles_map(GstVaapiProfile profile) { const GstVaapiProfileMap *m; @@ -90,13 +104,26 @@ get_map(GstVaapiProfile profile) return NULL; } +static const GstVaapiEntrypointMap * +get_entrypoints_map(GstVaapiEntrypoint entrypoint) +{ + const GstVaapiEntrypointMap *m; + + for (m = gst_vaapi_entrypoints; m->entrypoint; m++) + if (m->entrypoint == entrypoint) + return m; + return NULL; +} + /** * gst_vaapi_profile: - * @va_profile: a #VAProfile + * @profile: a #VAProfile * - * Converts a VA profile into the corresponding #GstVaapiProfile. If the profile cannot be represented by #GstVaapiProfile, then zero is returned. + * Converts a VA profile into the corresponding #GstVaapiProfile. If + * the profile cannot be represented by #GstVaapiProfile, then zero is + * returned. * - * Return value: the #GstVaapiProfile describing the @va_profile + * Return value: the #GstVaapiProfile describing the @profile */ GstVaapiProfile gst_vaapi_profile(VAProfile profile) @@ -163,7 +190,7 @@ gst_vaapi_profile_from_caps(GstCaps *caps) VAProfile gst_vaapi_profile_get_va_profile(GstVaapiProfile profile) { - const GstVaapiProfileMap * const m = get_map(profile); + const GstVaapiProfileMap * const m = get_profiles_map(profile); return m ? m->va_profile : (VAProfile)-1; } @@ -180,7 +207,7 @@ gst_vaapi_profile_get_va_profile(GstVaapiProfile profile) GstCaps * gst_vaapi_profile_get_caps(GstVaapiProfile profile) { - const GstVaapiProfileMap * const m = get_map(profile); + const GstVaapiProfileMap * const m = get_profiles_map(profile); return m ? gst_caps_from_string(m->caps_str) : NULL; } @@ -198,3 +225,42 @@ gst_vaapi_profile_get_codec(GstVaapiProfile profile) { return (GstVaapiCodec)(((guint32)profile) & 0xffffff00); } + +/** + * gst_vaapi_entrypoint: + * @entryprofile: a #VAEntrypoint + * + * Converts a VA entry-point into the corresponding #GstVaapiEntrypoint. + * If the entry-point cannot be represented by #GstVaapiEntrypoint, + * then zero is returned. + * + * Return value: the #GstVaapiEntrypoint describing the @entrypoint + */ +GstVaapiEntrypoint +gst_vaapi_entrypoint(VAEntrypoint entrypoint) +{ + const GstVaapiEntrypointMap *m; + + for (m = gst_vaapi_entrypoints; m->entrypoint; m++) + if (m->va_entrypoint == entrypoint) + return m->entrypoint; + return 0; +} + +/** + * gst_vaapi_entrypoint_get_va_entrypoint: + * @entrypoint: a #GstVaapiEntrypoint + * + * Converts a #GstVaapiEntrypoint into the corresponding VA + * entry-point. If no matching VA entry-point was found, -1 is + * returned and this error must be reported to be fixed. + * + * Return value: the VA entry-point, or -1 if none was found + */ +VAEntrypoint +gst_vaapi_entrypoint_get_va_entrypoint(GstVaapiEntrypoint entrypoint) +{ + const GstVaapiEntrypointMap * const m = get_entrypoints_map(entrypoint); + + return m ? m->va_entrypoint : (VAEntrypoint)-1; +} diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 62d0ccbbee..614ec6a458 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -27,6 +27,7 @@ G_BEGIN_DECLS typedef enum _GstVaapiCodec GstVaapiCodec; typedef enum _GstVaapiProfile GstVaapiProfile; +typedef enum _GstVaapiEntrypoint GstVaapiEntrypoint; /** * GstVaapiCodec: @@ -77,7 +78,7 @@ enum _GstVaapiCodec { * @GST_VAAPI_PROFILE_VC1_ADVANCED: * VC-1 advanced profile * - * The set of all profile for #GstVaapiProfile. + * The set of all profiles for #GstVaapiProfile. */ enum _GstVaapiProfile { GST_VAAPI_PROFILE_MPEG1 = GST_VAAPI_CODEC_MPEG1|1, @@ -95,6 +96,20 @@ enum _GstVaapiProfile { GST_VAAPI_PROFILE_VC1_ADVANCED = GST_VAAPI_CODEC_VC1|3, }; +/** + * GstVaapiEntrypoint: + * @GST_VAAPI_ENTRYPOINT_VLD: Variable Length Decoding + * @GST_VAAPI_ENTRYPOINT_IDCT: Inverse Decrete Cosine Transform + * @GST_VAAPI_ENTRYPOINT_MOCO: Motion Compensation + * + * The set of all entrypoints for #GstVaapiEntrypoint + */ +enum _GstVaapiEntrypoint { + GST_VAAPI_ENTRYPOINT_VLD = 1, + GST_VAAPI_ENTRYPOINT_IDCT, + GST_VAAPI_ENTRYPOINT_MOCO +}; + GstVaapiProfile gst_vaapi_profile(VAProfile profile); @@ -110,6 +125,12 @@ gst_vaapi_profile_get_caps(GstVaapiProfile profile); GstVaapiCodec gst_vaapi_profile_get_codec(GstVaapiProfile profile); +GstVaapiEntrypoint +gst_vaapi_entrypoint(VAEntrypoint entrypoint); + +VAEntrypoint +gst_vaapi_entrypoint_get_va_entrypoint(GstVaapiEntrypoint entrypoint); + G_END_DECLS #endif /* GST_GST_VAAPI_IMAGE_H */ From b0493e729c533b8aaa7f1ad4e85bc364aa2f2cde Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 21 Apr 2010 15:03:31 +0000 Subject: [PATCH 0255/3781] Add a means to cap the number of objects allocated in the pool. --- gst-libs/gst/vaapi/gstvaapivideopool.c | 187 +++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapivideopool.h | 19 +++ 2 files changed, 197 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 55936125cd..985742ef8a 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -41,6 +41,8 @@ struct _GstVaapiVideoPoolPrivate { GQueue free_objects; GList *used_objects; GstCaps *caps; + guint used_count; + guint capacity; }; enum { @@ -48,11 +50,20 @@ enum { PROP_DISPLAY, PROP_CAPS, + PROP_CAPACITY }; static void gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps); +static inline gpointer +gst_vaapi_video_pool_alloc_object(GstVaapiVideoPool *pool) +{ + GstVaapiVideoPoolClass * const klass = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool); + + return klass->alloc_object(pool, pool->priv->display); +} + static void gst_vaapi_video_pool_clear(GstVaapiVideoPool *pool) { @@ -114,6 +125,9 @@ gst_vaapi_video_pool_set_property( case PROP_CAPS: gst_vaapi_video_pool_set_caps(pool, g_value_get_pointer(value)); break; + case PROP_CAPACITY: + gst_vaapi_video_pool_set_capacity(pool, g_value_get_uint(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -137,6 +151,9 @@ gst_vaapi_video_pool_get_property( case PROP_CAPS: g_value_set_pointer(value, gst_vaapi_video_pool_get_caps(pool)); break; + case PROP_CAPACITY: + g_value_set_uint(value, gst_vaapi_video_pool_get_capacity(pool)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -181,6 +198,21 @@ gst_vaapi_video_pool_class_init(GstVaapiVideoPoolClass *klass) "caps", "The video object capabilities", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + /** + * GstVaapiVidePool:capacity: + * + * The maximum number of objects in the pool. Or zero, the pool + * will allocate as many objects as possible. + */ + g_object_class_install_property + (object_class, + PROP_CAPACITY, + g_param_spec_uint("capacity", + "capacity", + "The maximum number of objects in the pool", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE)); } static void @@ -192,6 +224,8 @@ gst_vaapi_video_pool_init(GstVaapiVideoPool *pool) priv->display = NULL; priv->used_objects = NULL; priv->caps = NULL; + priv->used_count = 0; + priv->capacity = 0; g_queue_init(&priv->free_objects); } @@ -245,32 +279,36 @@ gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) gpointer gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) { + GstVaapiVideoPoolPrivate *priv; gpointer object; g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); - object = g_queue_pop_head(&pool->priv->free_objects); + priv = pool->priv; + if (priv->capacity && priv->used_count >= priv->capacity) + return NULL; + + object = g_queue_pop_head(&priv->free_objects); if (!object) { - object = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool)->alloc_object( - pool, - pool->priv->display - ); + object = gst_vaapi_video_pool_alloc_object(pool); if (!object) return NULL; } - pool->priv->used_objects = g_list_prepend(pool->priv->used_objects, object); + ++priv->used_count; + priv->used_objects = g_list_prepend(priv->used_objects, object); return g_object_ref(object); } /** * gst_vaapi_video_pool_put_object: * @pool: a #GstVaapiVideoPool - * @object: the object to add to the pool + * @object: the object to add back to the pool * * Pushes the @object back into the pool. The @object shall be - * previously allocated from the @pool. Calling this function with an - * arbitrary object yields undefined behaviour. + * obtained from the @pool through gst_vaapi_video_pool_get_object(). + * Calling this function with an arbitrary object yields undefined + * behaviour. */ void gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) @@ -287,6 +325,137 @@ gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) return; g_object_unref(object); + --priv->used_count; priv->used_objects = g_list_delete_link(priv->used_objects, elem); g_queue_push_tail(&priv->free_objects, object); } + +/** + * gst_vaapi_video_pool_add_object: + * @pool: a #GstVaapiVideoPool + * @object: the object to add to the pool + * + * Adds the @object to the pool. The pool then holds a reference on + * the @object. This operation does not change the capacity of the + * pool. + * + * Return value: %TRUE on success. + */ +gboolean +gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE); + g_return_val_if_fail(G_IS_OBJECT(object), FALSE); + + g_queue_push_tail(&pool->priv->free_objects, g_object_ref(object)); + return TRUE; +} + +/** + * gst_vaapi_video_pool_add_objects: + * @pool: a #GstVaapiVideoPool + * @objects: a #GPtrArray of objects + * + * Adds the @objects to the pool. The pool then holds a reference on + * the @objects. This operation does not change the capacity of the + * pool and is just a wrapper around gst_vaapi_video_pool_add_object(). + * + * Return value: %TRUE on success. + */ +gboolean +gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects) +{ + guint i; + + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE); + + for (i = 0; i < objects->len; i++) { + gpointer const object = g_ptr_array_index(objects, i); + if (!gst_vaapi_video_pool_add_object(pool, object)) + return FALSE; + } + return TRUE; +} + +/** + * gst_vaapi_video_pool_get_size: + * @pool: a #GstVaapiVideoPool + * + * Returns the number of free objects available in the pool. + * + * Return value: number of free objects in the pool + */ +guint +gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0); + + return g_queue_get_length(&pool->priv->free_objects); +} + +/** + * gst_vaapi_video_pool_reserve: + * @pool: a #GstVaapiVideoPool + * @n: the number of objects to pre-allocate + * + * Pre-allocates up to @n objects in the pool. If @n is less than or + * equal to the number of free and used objects in the pool, this call + * has no effect. Otherwise, it is a request for allocation of + * additional objects. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n) +{ + guint i, num_allocated; + + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0); + + num_allocated = gst_vaapi_video_pool_get_size(pool) + pool->priv->used_count; + if (n < num_allocated) + return TRUE; + + if ((n -= num_allocated) > pool->priv->capacity) + n = pool->priv->capacity; + + for (i = num_allocated; i < n; i++) { + gpointer const object = gst_vaapi_video_pool_alloc_object(pool); + if (!object) + return FALSE; + g_queue_push_tail(&pool->priv->free_objects, object); + } + return TRUE; +} + +/** + * gst_vaapi_video_pool_get_capacity: + * @pool: a #GstVaapiVideoPool + * + * Returns the maximum number of objects in the pool. i.e. the maximum + * number of objects that can be returned by gst_vaapi_video_pool_get_object(). + * + * Return value: the capacity of the pool + */ +guint +gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0); + + return pool->priv->capacity; +} + +/** + * gst_vaapi_video_pool_set_capacity: + * @pool: a #GstVaapiVideoPool + * @capacity: the maximal capacity of the pool + * + * Sets the maximum number of objects that can be allocated in the pool. + */ +void +gst_vaapi_video_pool_set_capacity(GstVaapiVideoPool *pool, guint capacity) +{ + g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool)); + + pool->priv->capacity = capacity; +} diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index d779f43f22..5dce39f28f 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -21,6 +21,7 @@ #ifndef GST_VAAPI_VIDEO_POOL_H #define GST_VAAPI_VIDEO_POOL_H +#include #include #include @@ -95,6 +96,24 @@ gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool); void gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object); +gboolean +gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object); + +gboolean +gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects); + +guint +gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool); + +gboolean +gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n); + +guint +gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool); + +void +gst_vaapi_video_pool_set_capacity(GstVaapiVideoPool *pool, guint capacity); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_POOL_H */ From 6cb6c387e9bb8f95be2d217d6fd62c398ce60983 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 23 Apr 2010 10:58:19 +0000 Subject: [PATCH 0256/3781] Fix VA profiles definitions for gst_vaapi_profile_get_codec() to work. --- gst-libs/gst/vaapi/gstvaapiprofile.h | 37 ++++++++++++++++++---------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 614ec6a458..4746f69bc1 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -49,6 +49,17 @@ enum _GstVaapiCodec { GST_VAAPI_CODEC_VC1 = GST_MAKE_FOURCC('V','C','1',0), }; +/** + * GST_VAAPI_MAKE_PROFILE: + * @codec: the #GstVaapiCodec without the GST_VAAPI_CODEC_ prefix + * @sub_id: a non-zero sub-codec id + * + * Macro that evaluates to the profile composed from @codec and + * @sub_id. + */ +#define GST_VAAPI_MAKE_PROFILE(codec, sub_id) \ + (GST_VAAPI_CODEC_##codec | GST_MAKE_FOURCC(0,0,0,sub_id)) + /** * GstVaapiProfile: * @GST_VAAPI_PROFILE_MPEG1: @@ -81,19 +92,19 @@ enum _GstVaapiCodec { * The set of all profiles for #GstVaapiProfile. */ enum _GstVaapiProfile { - GST_VAAPI_PROFILE_MPEG1 = GST_VAAPI_CODEC_MPEG1|1, - GST_VAAPI_PROFILE_MPEG2_SIMPLE = GST_VAAPI_CODEC_MPEG2|1, - GST_VAAPI_PROFILE_MPEG2_MAIN = GST_VAAPI_CODEC_MPEG2|2, - GST_VAAPI_PROFILE_MPEG4_SIMPLE = GST_VAAPI_CODEC_MPEG4|1, - GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE = GST_VAAPI_CODEC_MPEG4|2, - GST_VAAPI_PROFILE_MPEG4_MAIN = GST_VAAPI_CODEC_MPEG4|3, - GST_VAAPI_PROFILE_H263_BASELINE = GST_VAAPI_CODEC_H263|1, - GST_VAAPI_PROFILE_H264_BASELINE = GST_VAAPI_CODEC_H264|1, - GST_VAAPI_PROFILE_H264_MAIN = GST_VAAPI_CODEC_H264|2, - GST_VAAPI_PROFILE_H264_HIGH = GST_VAAPI_CODEC_H264|3, - GST_VAAPI_PROFILE_VC1_SIMPLE = GST_VAAPI_CODEC_VC1|1, - GST_VAAPI_PROFILE_VC1_MAIN = GST_VAAPI_CODEC_VC1|2, - GST_VAAPI_PROFILE_VC1_ADVANCED = GST_VAAPI_CODEC_VC1|3, + GST_VAAPI_PROFILE_MPEG1 = GST_VAAPI_MAKE_PROFILE(MPEG1,1), + GST_VAAPI_PROFILE_MPEG2_SIMPLE = GST_VAAPI_MAKE_PROFILE(MPEG2,1), + GST_VAAPI_PROFILE_MPEG2_MAIN = GST_VAAPI_MAKE_PROFILE(MPEG2,2), + GST_VAAPI_PROFILE_MPEG4_SIMPLE = GST_VAAPI_MAKE_PROFILE(MPEG4,1), + GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE = GST_VAAPI_MAKE_PROFILE(MPEG4,2), + GST_VAAPI_PROFILE_MPEG4_MAIN = GST_VAAPI_MAKE_PROFILE(MPEG4,3), + GST_VAAPI_PROFILE_H263_BASELINE = GST_VAAPI_MAKE_PROFILE(H263,1), + GST_VAAPI_PROFILE_H264_BASELINE = GST_VAAPI_MAKE_PROFILE(H264,1), + GST_VAAPI_PROFILE_H264_MAIN = GST_VAAPI_MAKE_PROFILE(H264,2), + GST_VAAPI_PROFILE_H264_HIGH = GST_VAAPI_MAKE_PROFILE(H264,3), + GST_VAAPI_PROFILE_VC1_SIMPLE = GST_VAAPI_MAKE_PROFILE(VC1,1), + GST_VAAPI_PROFILE_VC1_MAIN = GST_VAAPI_MAKE_PROFILE(VC1,2), + GST_VAAPI_PROFILE_VC1_ADVANCED = GST_VAAPI_MAKE_PROFILE(VC1,3), }; /** From ecf60d2284f47a15b5caf992dc066eb9e025e03c Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 23 Apr 2010 15:59:31 +0000 Subject: [PATCH 0257/3781] Add VA context abstraction. --- gst-libs/gst/vaapi/gstvaapicontext.c | 662 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapicontext.h | 132 ++++++ 2 files changed, 794 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapicontext.c create mode 100644 gst-libs/gst/vaapi/gstvaapicontext.h diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c new file mode 100644 index 0000000000..aeb34913dd --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -0,0 +1,662 @@ +/* + * gstvaapicontext.c - VA context abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * SECTION:gstvaapicontext + * @short_description: VA context abstraction + */ + +#include "config.h" +#include +#include "gstvaapicompat.h" +#include "gstvaapicontext.h" +#include "gstvaapisurfacepool.h" +#include "gstvaapiutils.h" +#include "gstvaapi_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiContext, gst_vaapi_context, GST_VAAPI_TYPE_OBJECT); + +#define GST_VAAPI_CONTEXT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_CONTEXT, \ + GstVaapiContextPrivate)) + +/* XXX: optimize for the effective number of reference frames */ +struct _GstVaapiContextPrivate { + VAConfigID config_id; + GPtrArray *surfaces; + GstVaapiVideoPool *surfaces_pool; + GstVaapiProfile profile; + GstVaapiEntrypoint entrypoint; + guint width; + guint height; + guint is_constructed : 1; +}; + +enum { + PROP_0, + + PROP_PROFILE, + PROP_ENTRYPOINT, + PROP_WIDTH, + PROP_HEIGHT +}; + +static void +unref_surface_cb(gpointer data, gpointer user_data) +{ + g_object_unref(GST_VAAPI_SURFACE(data)); +} + +static void +gst_vaapi_context_destroy_surfaces(GstVaapiContext *context) +{ + GstVaapiContextPrivate * const priv = context->priv; + + if (priv->surfaces) { + g_ptr_array_foreach(priv->surfaces, unref_surface_cb, NULL); + g_ptr_array_free(priv->surfaces, TRUE); + priv->surfaces = NULL; + } + + if (priv->surfaces_pool) { + g_object_unref(priv->surfaces_pool); + priv->surfaces_pool = NULL; + } +} + +static void +gst_vaapi_context_destroy(GstVaapiContext *context) +{ + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context); + GstVaapiContextPrivate * const priv = context->priv; + VAContextID context_id; + VAStatus status; + + context_id = GST_VAAPI_OBJECT_ID(context); + GST_DEBUG("context %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(context_id)); + + 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()")) + g_warning("failed to destroy context %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(context_id)); + GST_VAAPI_OBJECT_ID(context) = VA_INVALID_ID; + } + + if (priv->config_id != VA_INVALID_ID) { + GST_VAAPI_DISPLAY_LOCK(display); + status = vaDestroyConfig( + GST_VAAPI_DISPLAY_VADISPLAY(display), + priv->config_id + ); + GST_VAAPI_DISPLAY_UNLOCK(display); + if (!vaapi_check_status(status, "vaDestroyConfig()")) + g_warning("failed to destroy config %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(priv->config_id)); + priv->config_id = VA_INVALID_ID; + } +} + +static gboolean +gst_vaapi_context_create_surfaces(GstVaapiContext *context) +{ + GstVaapiContextPrivate * const priv = context->priv; + GstCaps *caps; + GstVaapiSurface *surface; + guint i, num_ref_frames, num_surfaces; + + /* Number of scratch surfaces beyond those used as reference */ + const guint SCRATCH_SURFACES_COUNT = 4; + + if (!priv->surfaces) { + priv->surfaces = g_ptr_array_new(); + if (!priv->surfaces) + return FALSE; + } + + if (!priv->surfaces_pool) { + caps = gst_caps_new_simple( + "video/x-vaapi-surface", + "width", G_TYPE_INT, priv->width, + "height", G_TYPE_INT, priv->height, + NULL + ); + if (!caps) + return FALSE; + priv->surfaces_pool = gst_vaapi_surface_pool_new( + GST_VAAPI_OBJECT_DISPLAY(context), + caps + ); + gst_caps_unref(caps); + if (!priv->surfaces_pool) + return FALSE; + } + + num_ref_frames = 2; + if (gst_vaapi_profile_get_codec(priv->profile) == GST_VAAPI_CODEC_H264) + num_ref_frames = 16; + num_surfaces = num_ref_frames + SCRATCH_SURFACES_COUNT; + + gst_vaapi_video_pool_set_capacity(priv->surfaces_pool, num_surfaces); + + for (i = priv->surfaces->len; i < num_surfaces; i++) { + surface = gst_vaapi_surface_new( + GST_VAAPI_OBJECT_DISPLAY(context), + GST_VAAPI_CHROMA_TYPE_YUV420, + priv->width, priv->height + ); + if (!surface) + return FALSE; + g_ptr_array_add(priv->surfaces, surface); + if (!gst_vaapi_video_pool_add_object(priv->surfaces_pool, surface)) + return FALSE; + } + return TRUE; +} + +static gboolean +gst_vaapi_context_create(GstVaapiContext *context) +{ + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context); + GstVaapiContextPrivate * const priv = context->priv; + VAProfile va_profile; + VAEntrypoint va_entrypoint; + VAConfigAttrib attrib; + VAContextID context_id; + VASurfaceID surface_id; + VAStatus status; + GArray *surfaces = NULL; + gboolean success = FALSE; + guint i; + + if (!priv->surfaces && !gst_vaapi_context_create_surfaces(context)) + goto end; + + surfaces = g_array_sized_new( + FALSE, + FALSE, + sizeof(VASurfaceID), + priv->surfaces->len + ); + if (!surfaces) + goto end; + + for (i = 0; i < priv->surfaces->len; i++) { + GstVaapiSurface * const surface = g_ptr_array_index(priv->surfaces, i); + if (!surface) + goto end; + surface_id = GST_VAAPI_OBJECT_ID(surface); + g_array_append_val(surfaces, surface_id); + } + assert(surfaces->len == priv->surfaces->len); + + if (!priv->profile || !priv->entrypoint) + goto end; + va_profile = gst_vaapi_profile_get_va_profile(priv->profile); + va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint(priv->entrypoint); + + GST_VAAPI_DISPLAY_LOCK(display); + attrib.type = VAConfigAttribRTFormat; + status = vaGetConfigAttributes( + GST_VAAPI_DISPLAY_VADISPLAY(display), + va_profile, + va_entrypoint, + &attrib, 1 + ); + GST_VAAPI_DISPLAY_UNLOCK(display); + if (!vaapi_check_status(status, "vaGetConfigAttributes()")) + goto end; + if (!(attrib.value & VA_RT_FORMAT_YUV420)) + goto end; + + GST_VAAPI_DISPLAY_LOCK(display); + status = vaCreateConfig( + GST_VAAPI_DISPLAY_VADISPLAY(display), + va_profile, + va_entrypoint, + &attrib, 1, + &priv->config_id + ); + GST_VAAPI_DISPLAY_UNLOCK(display); + if (!vaapi_check_status(status, "vaCreateConfig()")) + goto end; + + GST_VAAPI_DISPLAY_LOCK(display); + status = vaCreateContext( + GST_VAAPI_DISPLAY_VADISPLAY(display), + priv->config_id, + priv->width, priv->height, + VA_PROGRESSIVE, + (VASurfaceID *)surfaces->data, surfaces->len, + &context_id + ); + GST_VAAPI_DISPLAY_UNLOCK(display); + if (!vaapi_check_status(status, "vaCreateContext()")) + goto end; + + GST_DEBUG("context %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(context_id)); + GST_VAAPI_OBJECT_ID(context) = context_id; + success = TRUE; +end: + if (surfaces) + g_array_free(surfaces, TRUE); + return success; +} + +static void +gst_vaapi_context_finalize(GObject *object) +{ + GstVaapiContext * const context = GST_VAAPI_CONTEXT(object); + + gst_vaapi_context_destroy(context); + gst_vaapi_context_destroy_surfaces(context); + + G_OBJECT_CLASS(gst_vaapi_context_parent_class)->finalize(object); +} + +static void +gst_vaapi_context_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiContext * const context = GST_VAAPI_CONTEXT(object); + GstVaapiContextPrivate * const priv = context->priv; + + switch (prop_id) { + case PROP_PROFILE: + gst_vaapi_context_set_profile(context, g_value_get_uint(value)); + break; + case PROP_ENTRYPOINT: + priv->entrypoint = g_value_get_uint(value); + break; + case PROP_WIDTH: + priv->width = g_value_get_uint(value); + break; + case PROP_HEIGHT: + priv->height = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_context_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiContext * const context = GST_VAAPI_CONTEXT(object); + GstVaapiContextPrivate * const priv = context->priv; + + switch (prop_id) { + case PROP_PROFILE: + g_value_set_uint(value, gst_vaapi_context_get_profile(context)); + break; + case PROP_ENTRYPOINT: + g_value_set_uint(value, gst_vaapi_context_get_entrypoint(context)); + break; + case PROP_WIDTH: + g_value_set_uint(value, priv->width); + break; + case PROP_HEIGHT: + g_value_set_uint(value, priv->height); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_context_class_init(GstVaapiContextClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiContextPrivate)); + + object_class->finalize = gst_vaapi_context_finalize; + object_class->set_property = gst_vaapi_context_set_property; + object_class->get_property = gst_vaapi_context_get_property; + + g_object_class_install_property + (object_class, + PROP_PROFILE, + g_param_spec_uint("profile", + "Profile", + "The profile used for decoding", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, + PROP_ENTRYPOINT, + g_param_spec_uint("entrypoint", + "Entrypoint", + "The decoder entrypoint", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_uint("width", + "Width", + "The width of decoded surfaces", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_uint("height", + "Height", + "The height of the decoded surfaces", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_context_init(GstVaapiContext *context) +{ + GstVaapiContextPrivate *priv = GST_VAAPI_CONTEXT_GET_PRIVATE(context); + + context->priv = priv; + priv->config_id = VA_INVALID_ID; + priv->surfaces = NULL; + priv->surfaces_pool = NULL; + priv->profile = 0; + priv->entrypoint = 0; + priv->width = 0; + priv->height = 0; +} + +/** + * gst_vaapi_context_new: + * @display: a #GstVaapiDisplay + * @profile: a #GstVaapiProfile + * @entrypoint: a #GstVaapiEntrypoint + * @width: coded width from the bitstream + * @height: coded height from the bitstream + * + * Creates a new #GstVaapiContext with the specified codec @profile + * and @entrypoint. + * + * Return value: the newly allocated #GstVaapiContext object + */ +GstVaapiContext * +gst_vaapi_context_new( + GstVaapiDisplay *display, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint, + unsigned int width, + unsigned int height +) +{ + GstVaapiContext *context; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(profile, NULL); + g_return_val_if_fail(entrypoint, NULL); + g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(height > 0, NULL); + + context = g_object_new( + GST_VAAPI_TYPE_CONTEXT, + "display", display, + "id", GST_VAAPI_ID(VA_INVALID_ID), + "profile", profile, + "entrypoint", entrypoint, + "width", width, + "height", height, + NULL + ); + if (!context->priv->is_constructed) { + g_object_unref(context); + return NULL; + } + return context; +} + +/** + * gst_vaapi_context_reset: + * @context: a #GstVaapiContext + * @profile: a #GstVaapiProfile + * @entrypoint: a #GstVaapiEntrypoint + * @width: coded width from the bitstream + * @height: coded height from the bitstream + * + * Resets @context to the specified codec @profile and @entrypoint. + * The surfaces will be reallocated if the coded size changed. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_context_reset( + GstVaapiContext *context, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint, + unsigned int width, + unsigned int height +) +{ + GstVaapiContextPrivate * const priv = context->priv; + gboolean size_changed, codec_changed; + + size_changed = priv->width != width || priv->height != height; + if (size_changed) { + gst_vaapi_context_destroy_surfaces(context); + priv->width = width; + priv->height = height; + } + + codec_changed = priv->profile != profile || priv->entrypoint != entrypoint; + if (codec_changed) { + gst_vaapi_context_destroy(context); + priv->profile = profile; + priv->entrypoint = entrypoint; + } + + if (size_changed && !gst_vaapi_context_create_surfaces(context)) + return FALSE; + + if (codec_changed && !gst_vaapi_context_create(context)) + return FALSE; + + priv->is_constructed = TRUE; + 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(GST_VAAPI_IS_CONTEXT(context), VA_INVALID_ID); + + return GST_VAAPI_OBJECT_ID(context); +} + +/** + * gst_vaapi_context_get_profile: + * @context: a #GstVaapiContext + * + * Returns the VA profile used by the @context. + * + * Return value: the VA profile used by the @context + */ +GstVaapiProfile +gst_vaapi_context_get_profile(GstVaapiContext *context) +{ + g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0); + + return context->priv->profile; +} + +/** + * gst_vaapi_context_set_profile: + * @context: a #GstVaapiContext + * @profile: the new #GstVaapiProfile to use + * + * Sets the new @profile to use with the @context. If @profile matches + * the previous profile, this call has no effect. Otherwise, the + * underlying VA context is recreated, while keeping the previously + * allocated surfaces. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile) +{ + g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE); + g_return_val_if_fail(profile, FALSE); + + return gst_vaapi_context_reset(context, + profile, + context->priv->entrypoint, + context->priv->width, + context->priv->height); +} + +/** + * gst_vaapi_context_get_entrypoint: + * @context: a #GstVaapiContext + * + * Returns the VA entrypoint used by the @context + * + * Return value: the VA entrypoint used by the @context + */ +GstVaapiEntrypoint +gst_vaapi_context_get_entrypoint(GstVaapiContext *context) +{ + g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0); + + return context->priv->entrypoint; +} + +/** + * gst_vaapi_context_get_size: + * @context: a #GstVaapiContext + * @pwidth: return location for the width, or %NULL + * @pheight: return location for the height, or %NULL + * + * Retrieves the size of the surfaces attached to @context. + */ +void +gst_vaapi_context_get_size( + GstVaapiContext *context, + guint *pwidth, + guint *pheight +) +{ + g_return_if_fail(GST_VAAPI_IS_CONTEXT(context)); + + if (pwidth) + *pwidth = context->priv->width; + + if (pheight) + *pheight = context->priv->height; +} + +/** + * gst_vaapi_context_get_surface: + * @context: a #GstVaapiContext + * + * Acquires a free surface. The returned surface but be released with + * gst_vaapi_context_put_surface(). 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 + */ +GstVaapiSurface * +gst_vaapi_context_get_surface(GstVaapiContext *context) +{ + g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); + + return gst_vaapi_video_pool_get_object(context->priv->surfaces_pool); +} + +/** + * gst_vaapi_context_put_surface: + * @context: a #GstVaapiContext + * @surface: the #GstVaapiSurface to release + * + * Releases a surface acquired by gst_vaapi_context_get_surface(). + */ +void +gst_vaapi_context_put_surface(GstVaapiContext *context, GstVaapiSurface *surface) +{ + g_return_if_fail(GST_VAAPI_IS_CONTEXT(context)); + g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); + + gst_vaapi_video_pool_put_object(context->priv->surfaces_pool, surface); +} + +/** + * gst_vaapi_context_find_surface_by_id: + * @context: a #GstVaapiContext + * @id: the VA surface id to find + * + * Finds VA surface by @id in the list of surfaces attached to the @context. + * + * Return value: the matching #GstVaapiSurface object, or %NULL if + * none was found + */ +GstVaapiSurface * +gst_vaapi_context_find_surface_by_id(GstVaapiContext *context, GstVaapiID id) +{ + GstVaapiContextPrivate *priv; + GstVaapiSurface *surface; + guint i; + + g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); + + priv = context->priv; + g_return_val_if_fail(priv->surfaces, NULL); + + for (i = 0; i < priv->surfaces->len; i++) { + surface = g_ptr_array_index(priv->surfaces, i); + if (GST_VAAPI_OBJECT_ID(surface) == id) + return surface; + } + return NULL; +} diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h new file mode 100644 index 0000000000..f9ade817f1 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -0,0 +1,132 @@ +/* + * gstvaapicontext.h - VA context abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_CONTEXT_H +#define GST_VAAPI_CONTEXT_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_CONTEXT \ + (gst_vaapi_context_get_type()) + +#define GST_VAAPI_CONTEXT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_CONTEXT, \ + GstVaapiContext)) + +#define GST_VAAPI_CONTEXT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_CONTEXT, \ + GstVaapiContextClass)) + +#define GST_VAAPI_IS_CONTEXT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_CONTEXT)) + +#define GST_VAAPI_IS_CONTEXT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_CONTEXT)) + +#define GST_VAAPI_CONTEXT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_CONTEXT, \ + GstVaapiContextClass)) + +typedef struct _GstVaapiContext GstVaapiContext; +typedef struct _GstVaapiContextPrivate GstVaapiContextPrivate; +typedef struct _GstVaapiContextClass GstVaapiContextClass; + +/** + * GstVaapiContext: + * + * A VA context wrapper. + */ +struct _GstVaapiContext { + /*< private >*/ + GstVaapiObject parent_instance; + + GstVaapiContextPrivate *priv; +}; + +/** + * GstVaapiContextClass: + * + * A VA context wrapper class. + */ +struct _GstVaapiContextClass { + /*< private >*/ + GstVaapiObjectClass parent_class; +}; + +GType +gst_vaapi_context_get_type(void); + +GstVaapiContext * +gst_vaapi_context_new( + GstVaapiDisplay *display, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint, + guint width, + guint height +); + +gboolean +gst_vaapi_context_reset( + GstVaapiContext *context, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint, + unsigned int width, + unsigned int height +); + +GstVaapiID +gst_vaapi_context_get_id(GstVaapiContext *context); + +GstVaapiProfile +gst_vaapi_context_get_profile(GstVaapiContext *context); + +gboolean +gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile); + +GstVaapiEntrypoint +gst_vaapi_context_get_entrypoint(GstVaapiContext *context); + +void +gst_vaapi_context_get_size( + GstVaapiContext *context, + guint *pwidth, + guint *pheight +); + +GstVaapiSurface * +gst_vaapi_context_get_surface(GstVaapiContext *context); + +void +gst_vaapi_context_put_surface(GstVaapiContext *context, GstVaapiSurface *surface); + +GstVaapiSurface * +gst_vaapi_context_find_surface_by_id(GstVaapiContext *context, GstVaapiID id); + +G_END_DECLS + +#endif /* GST_VAAPI_CONTEXT_H */ From 5fb146c298d717789bd40e63d390dc13da0189b5 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 23 Apr 2010 16:00:50 +0000 Subject: [PATCH 0258/3781] Add surface proxy that holds a reference to the parent surface and that returns the surface to that context on destruction. --- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 246 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 108 ++++++++++ 2 files changed, 354 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapisurfaceproxy.c create mode 100644 gst-libs/gst/vaapi/gstvaapisurfaceproxy.h diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c new file mode 100644 index 0000000000..ff53ab8166 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -0,0 +1,246 @@ +/* + * gstvaapisurfaceproxy.c - VA surface proxy + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * SECTION:gstvaapisurfaceproxy + * @short_description: VA surface proxy + */ + +#include "config.h" +#include "gstvaapisurfaceproxy.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiSurfaceProxy, gst_vaapi_surface_proxy, G_TYPE_OBJECT); + +enum { + PROP_0, + + PROP_CONTEXT, + PROP_SURFACE +}; + +static void +gst_vaapi_surface_proxy_finalize(GObject *object) +{ + GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(object); + + if (proxy->surface) { + if (proxy->context) + gst_vaapi_context_put_surface(proxy->context, proxy->surface); + g_object_unref(proxy->surface); + proxy->surface = NULL; + } + + if (proxy->context) { + g_object_unref(proxy->context); + proxy->context = NULL; + } + + G_OBJECT_CLASS(gst_vaapi_surface_proxy_parent_class)->finalize(object); +} + +static void +gst_vaapi_surface_proxy_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(object); + + switch (prop_id) { + case PROP_CONTEXT: + gst_vaapi_surface_proxy_set_context(proxy, g_value_get_pointer(value)); + break; + case PROP_SURFACE: + gst_vaapi_surface_proxy_set_surface(proxy, g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_surface_proxy_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(object); + + switch (prop_id) { + case PROP_CONTEXT: + g_value_set_pointer(value, gst_vaapi_surface_proxy_get_context(proxy)); + break; + case PROP_SURFACE: + g_value_set_pointer(value, gst_vaapi_surface_proxy_get_surface(proxy)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_surface_proxy_class_init(GstVaapiSurfaceProxyClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + object_class->finalize = gst_vaapi_surface_proxy_finalize; + object_class->set_property = gst_vaapi_surface_proxy_set_property; + object_class->get_property = gst_vaapi_surface_proxy_get_property; + + g_object_class_install_property + (object_class, + PROP_CONTEXT, + g_param_spec_pointer("context", + "Context", + "The context stored in the proxy", + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, + PROP_SURFACE, + g_param_spec_pointer("surface", + "Surface", + "The surface stored in the proxy", + G_PARAM_READWRITE)); +} + +static void +gst_vaapi_surface_proxy_init(GstVaapiSurfaceProxy *proxy) +{ + proxy->context = NULL; + proxy->surface = NULL; +} + +/** + * gst_vaapi_surface_proxy_new: + * @context: a #GstVaapiContext + * @surface: a #GstVaapiSurface + * + * Creates a new #GstVaapiSurfaceProxy with the specified context and + * surface. + * + * Return value: the newly allocated #GstVaapiSurfaceProxy object + */ +GstVaapiSurfaceProxy * +gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface) +{ + g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); + + return g_object_new(GST_VAAPI_TYPE_SURFACE_PROXY, + "context", context, + "surface", surface, + NULL); +} + +/** + * gst_vaapi_surface_proxy_get_context: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the #GstVaapiContext stored in the @proxy. + * + * Return value: the #GstVaapiContext + */ +GstVaapiContext * +gst_vaapi_surface_proxy_get_context(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); + + return proxy->context; +} + +/** + * gst_vaapi_surface_proxy_set_context: + * @proxy: a #GstVaapiSurfaceProxy + * @context: the new #GstVaapiContext to be stored in @proxy + * + * Stores a new @context into the @proxy. The proxy releases the + * previous reference, if any, and then holds a reference to the new + * @context. + */ +void +gst_vaapi_surface_proxy_set_context( + GstVaapiSurfaceProxy *proxy, + GstVaapiContext *context +) +{ + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + g_return_if_fail(GST_VAAPI_IS_CONTEXT(context)); + + if (proxy->context) { + g_object_unref(proxy->context); + proxy->context = NULL; + } + + if (context) + proxy->context = g_object_ref(context); +} + +/** + * gst_vaapi_surface_proxy_get_surface: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the #GstVaapiSurface stored in the @proxy. + * + * Return value: the #GstVaapiSurface + */ +GstVaapiSurface * +gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); + + return proxy->surface; +} + +/** + * gst_vaapi_surface_proxy_set_surface: + * @proxy: a #GstVaapiSurfaceProxy + * @surface: the new #GstVaapiSurface to be stored in @proxy + * + * Stores a new @surface into the @proxy. The proxy releases the + * previous reference, if any, and then holds a reference to the new + * @surface. + */ +void +gst_vaapi_surface_proxy_set_surface( + GstVaapiSurfaceProxy *proxy, + GstVaapiSurface *surface +) +{ + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); + + if (proxy->surface) { + g_object_unref(proxy->surface); + proxy->surface = NULL; + } + + if (surface) + proxy->surface = g_object_ref(surface); +} diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h new file mode 100644 index 0000000000..d19ef687a8 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -0,0 +1,108 @@ +/* + * gstvaapisurfaceproxy.h - VA surface proxy + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_SURFACE_PROXY_H +#define GST_VAAPI_SURFACE_PROXY_H + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_SURFACE_PROXY \ + (gst_vaapi_surface_proxy_get_type()) + +#define GST_VAAPI_SURFACE_PROXY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_SURFACE_PROXY, \ + GstVaapiSurfaceProxy)) + +#define GST_VAAPI_SURFACE_PROXY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_SURFACE_PROXY, \ + GstVaapiSurfaceProxyClass)) + +#define GST_VAAPI_IS_SURFACE_PROXY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SURFACE_PROXY)) + +#define GST_VAAPI_IS_SURFACE_PROXY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SURFACE_PROXY)) + +#define GST_VAAPI_SURFACE_PROXY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_SURFACE_PROXY, \ + GstVaapiSurfaceProxyClass)) + +typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; +typedef struct _GstVaapiSurfaceProxyClass GstVaapiSurfaceProxyClass; + +/** + * GstVaapiSurfaceProxy: + * @surface: a #GstVaapiSurface + * @context: the #GstVaapiContext to which the @surface is bound + * + * A wrapper around a VA surface and context. + */ +struct _GstVaapiSurfaceProxy { + /*< private >*/ + GObject parent_instance; + + GstVaapiContext *context; + GstVaapiSurface *surface; +}; + +/** + * GstVaapiSurfaceProxyClass: + * + * A wrapper around a VA surface and context. + */ +struct _GstVaapiSurfaceProxyClass { + /*< private >*/ + GObjectClass parent_class; +}; + +GType +gst_vaapi_surface_proxy_get_type(void); + +GstVaapiSurfaceProxy * +gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface); + +GstVaapiContext * +gst_vaapi_surface_proxy_get_context(GstVaapiSurfaceProxy *proxy); + +void +gst_vaapi_surface_proxy_set_context( + GstVaapiSurfaceProxy *proxy, + GstVaapiContext *context +); + +GstVaapiSurface * +gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy); + +void +gst_vaapi_surface_proxy_set_surface( + GstVaapiSurfaceProxy *proxy, + GstVaapiSurface *surface +); + +G_END_DECLS + +#endif /* GST_VAAPI_SURFACE_PROXY_H */ From a203d19a35f2d5f64f4f239e1c6519fb21424094 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 23 Apr 2010 16:05:58 +0000 Subject: [PATCH 0259/3781] Add initial (multithreaded) decoder based on FFmpeg. There are tons of bugs left: - Decoder API not nice enough with error conditions - FFmpeg parser is sometimes broken - Packets queue can be lost --- configure.ac | 8 + gst-libs/gst/vaapi/Makefile.am | 25 + gst-libs/gst/vaapi/gstvaapidecoder.c | 617 ++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder.h | 137 +++++ gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 610 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h | 86 +++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 123 ++++ 7 files changed, 1606 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder.h create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_priv.h diff --git a/configure.ac b/configure.ac index df2a5e4d0b..07b50abac2 100644 --- a/configure.ac +++ b/configure.ac @@ -252,6 +252,14 @@ else USE_VAAPISINK_GLX=0 fi +dnl Check for FFmpeg +PKG_CHECK_MODULES(LIBAVFORMAT, [libavformat]) +AC_CHECK_HEADERS([libavformat/avformat.h]) + +PKG_CHECK_MODULES(LIBAVCODEC, [libavcodec]) +AC_CHECK_HEADERS([libavcodec/avcodec.h]) +AC_CHECK_HEADERS([libavcodec/vaapi.h]) + AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f8c59de9e2..04a4547b43 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -10,7 +10,20 @@ endif libgstvaapi_includedir = \ $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi +libgstvaapi_ffmpeg_source_c = \ + gstvaapidecoder_ffmpeg.c \ + $(NULL) + +libgstvaapi_ffmpeg_source_h = \ + gstvaapidecoder_ffmpeg.h \ + $(NULL) + +libgstvaapi_ffmpeg_source_priv_h = \ + $(NULL) + libgstvaapi_source_c = \ + gstvaapicontext.c \ + gstvaapidecoder.c \ gstvaapidisplay.c \ gstvaapiimage.c \ gstvaapiimageformat.c \ @@ -22,15 +35,19 @@ libgstvaapi_source_c = \ gstvaapisubpicture.c \ gstvaapisurface.c \ gstvaapisurfacepool.c \ + gstvaapisurfaceproxy.c \ gstvaapiutils.c \ gstvaapivalue.c \ gstvaapivideobuffer.c \ gstvaapivideopool.c \ gstvaapivideosink.c \ gstvaapiwindow.c \ + $(libgstvaapi_ffmpeg_source_c) \ $(NULL) libgstvaapi_source_h = \ + gstvaapicontext.h \ + gstvaapidecoder.h \ gstvaapidisplay.h \ gstvaapiimage.h \ gstvaapiimageformat.h \ @@ -41,21 +58,25 @@ libgstvaapi_source_h = \ gstvaapisubpicture.h \ gstvaapisurface.h \ gstvaapisurfacepool.h \ + gstvaapisurfaceproxy.h \ gstvaapitypes.h \ gstvaapivalue.h \ gstvaapivideobuffer.h \ gstvaapivideopool.h \ gstvaapivideosink.h \ gstvaapiwindow.h \ + $(libgstvaapi_ffmpeg_source_h) \ $(NULL) libgstvaapi_source_priv_h = \ gstvaapicompat.h \ gstvaapidebug.h \ + gstvaapidecoder_priv.h \ gstvaapidisplay_priv.h \ gstvaapiobject_priv.h \ gstvaapiutils.h \ gstvaapi_priv.h \ + $(libgst_vaapi_ffmpeg_source_priv_h) \ $(NULL) libgstvaapi_x11_source_c = \ @@ -116,12 +137,16 @@ libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ -I$(top_srcdir)/gst-libs \ $(GST_BASE_CFLAGS) \ $(GST_CFLAGS) \ + $(LIBAVCODEC_CFLAGS) \ + $(LIBAVFORMAT_CFLAGS) \ $(LIBVA_CFLAGS) \ $(NULL) libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ $(GST_BASE_LIBS) \ $(GST_LIBS) \ + $(LIBAVCODEC_LIBS) \ + $(LIBAVFORMAT_LIBS) \ $(LIBVA_LIBS) \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c new file mode 100644 index 0000000000..fc80e6ec10 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -0,0 +1,617 @@ +/* + * gstvaapidecoder.c - VA decoder abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * SECTION:gstvaapidecoder + * @short_description: VA decoder abstraction + */ + +#include "config.h" +#include +#include +#include "gstvaapicompat.h" +#include "gstvaapidecoder.h" +#include "gstvaapidecoder_priv.h" +#include "gstvaapiutils.h" +#include "gstvaapi_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiDecoder, gst_vaapi_decoder, G_TYPE_OBJECT); + +enum { + PROP_0, + + PROP_DISPLAY, + PROP_CODEC, +}; + +static gpointer +decoder_thread_cb(gpointer data) +{ + GstVaapiDecoder * const decoder = data; + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (!klass->decode) { + g_error("unimplemented GstVaapiDecoder::decode() function"); + return NULL; + } + + while (!priv->decoder_thread_cancel) { + g_mutex_lock(priv->adapter_mutex); + while (!gst_adapter_available(priv->adapter)) { + g_cond_wait(priv->adapter_cond, priv->adapter_mutex); + if (priv->decoder_thread_cancel) + break; + } + g_mutex_unlock(priv->adapter_mutex); + + if (!priv->decoder_thread_cancel) { + if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) { + g_object_ref(decoder); + status = klass->decode(decoder); + g_object_unref(decoder); + GST_DEBUG("decode frame (status = %d)", status); + } + else { + /* XXX: something went wrong, simply destroy any + buffer until this decoder is destroyed */ + g_mutex_lock(priv->adapter_mutex); + gst_adapter_clear(priv->adapter); + g_mutex_unlock(priv->adapter_mutex); + + /* Signal the main thread we got an error */ + gst_vaapi_decoder_push_surface(decoder, NULL); + } + } + } + return NULL; +} + +static GstBuffer * +create_buffer(const guchar *buf, guint buf_size, gboolean copy) +{ + GstBuffer *buffer; + + buffer = gst_buffer_new(); + if (!buffer) + return NULL; + + if (copy) { + buffer->malloc_data = g_malloc(buf_size); + if (!buffer->malloc_data) { + gst_buffer_unref(buffer); + return NULL; + } + memcpy(buffer->malloc_data, buf, buf_size); + GST_BUFFER_DATA(buffer) = buffer->malloc_data; + GST_BUFFER_SIZE(buffer) = buf_size; + } + else { + GST_BUFFER_DATA(buffer) = (guint8 *)buf; + GST_BUFFER_SIZE(buffer) = buf_size; + } + return buffer; +} + +static gboolean +push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (!buffer) + return FALSE; + + g_return_val_if_fail(priv->adapter_mutex && priv->adapter_cond, FALSE); + + GST_DEBUG("queue encoded data buffer %p (%d bytes)", + buffer, GST_BUFFER_SIZE(buffer)); + + /* XXX: add a mechanism to wait for enough buffer bytes to be consumed */ + g_mutex_lock(priv->adapter_mutex); + gst_adapter_push(priv->adapter, buffer); + g_cond_signal(priv->adapter_cond); + g_mutex_unlock(priv->adapter_mutex); + + if (!priv->decoder_thread) { + priv->decoder_thread = g_thread_create( + decoder_thread_cb, decoder, + TRUE, + NULL + ); + if (!priv->decoder_thread) + return FALSE; + } + return TRUE; +} + +static void +unref_surface_cb(gpointer surface, gpointer user_data) +{ + if (surface) + g_object_unref(GST_VAAPI_SURFACE(surface)); +} + +static void +gst_vaapi_decoder_finalize(GObject *object) +{ + GstVaapiDecoderPrivate * const priv = GST_VAAPI_DECODER(object)->priv; + + if (priv->decoder_thread) { + priv->decoder_thread_cancel = TRUE; + if (priv->adapter_mutex && priv->adapter_cond) { + g_mutex_lock(priv->adapter_mutex); + g_cond_signal(priv->adapter_cond); + g_mutex_unlock(priv->adapter_mutex); + } + g_thread_join(priv->decoder_thread); + priv->decoder_thread = NULL; + } + + if (priv->adapter) { + gst_adapter_clear(priv->adapter); + g_object_unref(priv->adapter); + priv->adapter = NULL; + } + + if (priv->adapter_cond) { + g_cond_free(priv->adapter_cond); + priv->adapter_cond = NULL; + } + + if (priv->adapter_mutex) { + g_mutex_free(priv->adapter_mutex); + priv->adapter_mutex = NULL; + } + + if (priv->context) { + g_object_unref(priv->context); + priv->context = NULL; + } + + g_queue_foreach(&priv->surfaces, unref_surface_cb, NULL); + + if (priv->surfaces_cond) { + g_cond_free(priv->surfaces_cond); + priv->surfaces_cond = NULL; + } + + if (priv->surfaces_mutex) { + g_mutex_free(priv->surfaces_mutex); + priv->surfaces_mutex = NULL; + } + + if (priv->display) { + g_object_unref(priv->display); + priv->display = NULL; + } + + G_OBJECT_CLASS(gst_vaapi_decoder_parent_class)->finalize(object); +} + +static void +gst_vaapi_decoder_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiDecoderPrivate * const priv = GST_VAAPI_DECODER(object)->priv; + + switch (prop_id) { + case PROP_DISPLAY: + priv->display = g_object_ref(g_value_get_object(value)); + break; + case PROP_CODEC: + priv->codec = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_decoder_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiDecoderPrivate * const priv = GST_VAAPI_DECODER(object)->priv; + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_object(value, priv->display); + break; + case PROP_CODEC: + g_value_set_uint(value, priv->codec); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiDecoderPrivate)); + + object_class->finalize = gst_vaapi_decoder_finalize; + object_class->set_property = gst_vaapi_decoder_set_property; + object_class->get_property = gst_vaapi_decoder_get_property; + + /** + * GstVaapiDecoder:display: + * + * The #GstVaapiDisplay this decoder is bound to. + */ + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_object("display", + "Display", + "The GstVaapiDisplay this decoder is bound to", + GST_VAAPI_TYPE_DISPLAY, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_CODEC, + g_param_spec_uint("codec", + "Codec", + "The codec handled by the decoder", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_decoder_init(GstVaapiDecoder *decoder) +{ + GstVaapiDecoderPrivate *priv = GST_VAAPI_DECODER_GET_PRIVATE(decoder); + + decoder->priv = priv; + priv->context = NULL; + priv->codec = 0; + priv->adapter = gst_adapter_new(); + priv->adapter_mutex = g_mutex_new(); + priv->adapter_cond = g_cond_new(); + priv->surfaces_mutex = g_mutex_new(); + priv->surfaces_cond = g_cond_new(); + priv->decoder_thread = NULL; + priv->decoder_thread_cancel = FALSE; + + g_queue_init(&priv->surfaces); +} + +/** + * gst_vaapi_decoder_put_buffer_data: + * @decoder: a #GstVaapiDecoder + * @buf: pointer to buffer data + * @buf_size: size of buffer data in bytes + * + * Queues @buf_size bytes from the data @buf to the HW decoder. The + * caller is responsible for making sure @buf is live beyond this + * function. So, this function is mostly useful with static data + * buffers. gst_vaapi_decoder_put_buffer_data_copy() does the same but + * copies the data. + * + * Caller can notify an End-Of-Stream with @buf set to %NULL and + * @buf_size set to zero. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_decoder_put_buffer_data( + GstVaapiDecoder *decoder, + const guchar *buf, + guint buf_size +) +{ + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); + g_return_val_if_fail(buf, FALSE); + g_return_val_if_fail(buf_size > 0, FALSE); + + return push_buffer(decoder, create_buffer(buf, buf_size, FALSE)); +} + +/** + * gst_vaapi_decoder_put_buffer_data_copy: + * @decoder: a #GstVaapiDecoder + * @buf: pointer to buffer data + * @buf_size: size of buffer data in bytes + * + * Queues a copy of @buf to the HW decoder. + * + * Caller can notify an End-Of-Stream with @buf set to %NULL and + * @buf_size set to zero. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_decoder_put_buffer_data_copy( + GstVaapiDecoder *decoder, + const guchar *buf, + guint buf_size +) +{ + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); + g_return_val_if_fail(buf, FALSE); + g_return_val_if_fail(buf_size > 0, FALSE); + + return push_buffer(decoder, create_buffer(buf, buf_size, TRUE)); +} + +/** + * gst_vaapi_decoder_put_buffer: + * @decoder: a #GstVaapiDecoder + * @buf: a #GstBuffer + * + * Queues a #GstBuffer to the HW decoder. The decoder holds a + * reference to @buf. + * + * Caller can notify an End-Of-Stream with @buf set to %NULL. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf) +{ + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); + g_return_val_if_fail(GST_IS_BUFFER(buf), FALSE); + + return push_buffer(decoder, gst_buffer_ref(buf)); +} + +/** + * gst_vaapi_decoder_get_surface: + * @decoder: a #GstVaapiDecoder + * @pstatus: return location for the decoder status, or %NULL + * + * Waits for a decoded surface to arrive. This functions blocks until + * the @decoder has a surface ready for the caller. @pstatus is + * optional but it can help to know what went wrong during the + * decoding process. + * + * Return value: a #GstVaapiSurfaceProxy holding the decoded surface, + * or %NULL if none is available (e.g. an error). Caller owns the + * returned object. g_object_unref() after usage. + */ +static GstVaapiSurface * +_gst_vaapi_decoder_get_surface( + GstVaapiDecoder *decoder, + GTimeVal *timeout, + GstVaapiDecoderStatus *pstatus +) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiSurface *surface; + + g_mutex_lock(priv->surfaces_mutex); + while (g_queue_is_empty(&priv->surfaces)) + if (!g_cond_timed_wait(priv->surfaces_cond, priv->surfaces_mutex, timeout)) + break; + surface = g_queue_pop_head(&priv->surfaces); + g_mutex_unlock(priv->surfaces_mutex); + + if (surface) + *pstatus = GST_VAAPI_DECODER_STATUS_SUCCESS; + else { + g_mutex_lock(priv->adapter_mutex); + if (gst_adapter_available(priv->adapter)) + *pstatus = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + else if (timeout) + *pstatus = GST_VAAPI_DECODER_STATUS_TIMEOUT; + else + *pstatus = GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + g_mutex_unlock(priv->adapter_mutex); + } + return surface; +} + +GstVaapiSurfaceProxy * +gst_vaapi_decoder_get_surface( + GstVaapiDecoder *decoder, + GstVaapiDecoderStatus *pstatus +) +{ + GstVaapiSurfaceProxy *proxy = NULL; + GstVaapiSurface *surface; + GstVaapiDecoderStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + surface = _gst_vaapi_decoder_get_surface(decoder, NULL, &status); + if (surface) { + proxy = gst_vaapi_surface_proxy_new(decoder->priv->context, surface); + if (!proxy) + status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + g_object_unref(surface); + } + + if (pstatus) + *pstatus = status; + return proxy; +} + +/** + * gst_vaapi_decoder_timed_get_surface: + * @decoder: a #GstVaapiDecoder + * @timeout: the number of microseconds to wait for the decoded surface + * @pstatus: return location for the decoder status, or %NULL + * + * Waits for a decoded surface to arrive. This function blocks for at + * least @timeout microseconds. @pstatus is optional but it can help + * to know what went wrong during the decoding process. + * + * Return value: a #GstVaapiSurfaceProxy holding the decoded surface, + * or %NULL if none is available (e.g. an error). Caller owns the + * returned object. g_object_unref() after usage. + */ +GstVaapiSurfaceProxy * +gst_vaapi_decoder_timed_get_surface( + GstVaapiDecoder *decoder, + guint32 timeout, + GstVaapiDecoderStatus *pstatus +) +{ + GstVaapiSurfaceProxy *proxy = NULL; + GstVaapiSurface *surface; + GstVaapiDecoderStatus status; + GTimeVal end_time; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + g_get_current_time(&end_time); + g_time_val_add(&end_time, timeout); + + surface = _gst_vaapi_decoder_get_surface(decoder, &end_time, &status); + if (surface) { + proxy = gst_vaapi_surface_proxy_new(decoder->priv->context, surface); + if (!proxy) + status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + g_object_unref(surface); + } + + if (pstatus) + *pstatus = status; + return proxy; +} + +gboolean +gst_vaapi_decoder_ensure_context( + GstVaapiDecoder *decoder, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint, + guint width, + guint height +) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (priv->context) + return gst_vaapi_context_reset(priv->context, + profile, entrypoint, width, height); + + priv->context = gst_vaapi_context_new( + priv->display, + profile, + entrypoint, + width, + height + ); + return priv->context != NULL; +} + +guint +gst_vaapi_decoder_copy( + GstVaapiDecoder *decoder, + guint offset, + guchar *buf, + guint buf_size +) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + guint avail; + + if (!buf || !buf_size) + return 0; + + avail = gst_vaapi_decoder_read_avail(decoder); + if (offset >= avail) + return 0; + if (buf_size > avail - offset) + buf_size = avail - offset; + + if (buf_size > 0) { + g_mutex_lock(priv->adapter_mutex); + gst_adapter_copy(priv->adapter, buf, offset, buf_size); + g_mutex_unlock(priv->adapter_mutex); + } + return buf_size; +} + +guint +gst_vaapi_decoder_read_avail(GstVaapiDecoder *decoder) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + guint avail; + + g_mutex_lock(priv->adapter_mutex); + avail = gst_adapter_available(priv->adapter); + g_mutex_unlock(priv->adapter_mutex); + return avail; +} + +guint +gst_vaapi_decoder_read(GstVaapiDecoder *decoder, guchar *buf, guint buf_size) +{ + buf_size = gst_vaapi_decoder_copy(decoder, 0, buf, buf_size); + if (buf_size > 0) + gst_vaapi_decoder_flush(decoder, buf_size); + return buf_size; +} + +void +gst_vaapi_decoder_flush(GstVaapiDecoder *decoder, guint buf_size) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + guint avail; + + if (!buf_size) + return; + + avail = gst_vaapi_decoder_read_avail(decoder); + if (buf_size > avail) + buf_size = avail; + + g_mutex_lock(priv->adapter_mutex); + gst_adapter_flush(priv->adapter, buf_size); + g_mutex_unlock(priv->adapter_mutex); +} + +gboolean +gst_vaapi_decoder_push_surface( + GstVaapiDecoder *decoder, + GstVaapiSurface *surface +) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (surface) + GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); + else + GST_DEBUG("queue null surface to signal an error"); + + g_mutex_lock(priv->surfaces_mutex); + g_queue_push_tail(&priv->surfaces, surface ? g_object_ref(surface) : NULL); + g_cond_signal(priv->surfaces_cond); + g_mutex_unlock(priv->surfaces_mutex); + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h new file mode 100644 index 0000000000..4c2d4c0728 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -0,0 +1,137 @@ +/* + * gstvaapidecoder.h - VA decoder abstraction + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_DECODER_H +#define GST_VAAPI_DECODER_H + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DECODER \ + (gst_vaapi_decoder_get_type()) + +#define GST_VAAPI_DECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DECODER, \ + GstVaapiDecoder)) + +#define GST_VAAPI_DECODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DECODER, \ + GstVaapiDecoderClass)) + +#define GST_VAAPI_IS_DECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER)) + +#define GST_VAAPI_IS_DECODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER)) + +#define GST_VAAPI_DECODER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DECODER, \ + GstVaapiDecoderClass)) + +typedef enum _GstVaapiDecoderStatus GstVaapiDecoderStatus; +typedef struct _GstVaapiDecoder GstVaapiDecoder; +typedef struct _GstVaapiDecoderPrivate GstVaapiDecoderPrivate; +typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; + +/** + * GstVaapiDecoderStatus: + * @GST_VAAPI_DECODER_STATUS_SUCCESS: Success. + * @GST_VAAPI_DECODER_STATUS_TIMEOUT: Timeout. Try again later. + * @GST_VAAPI_DECODER_STATUS_EOS: End-Of-Stream. + * @GST_VAAPI_DECODER_STATUS_ERROR: Unknown error. + * + * Decoder status for gst_vaapi_decoder_get_surface(). + */ +enum _GstVaapiDecoderStatus { + GST_VAAPI_DECODER_STATUS_SUCCESS = 0, + GST_VAAPI_DECODER_STATUS_TIMEOUT, + 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_UNKNOWN +}; + +/** + * GstVaapiDecoder: + * + * A VA decoder base instance. + */ +struct _GstVaapiDecoder { + /*< private >*/ + GObject parent_instance; + + GstVaapiDecoderPrivate *priv; +}; + +/** + * GstVaapiDecoderClass: + * @decode: decode one frame. + * + * A VA decoder base class. + */ +struct _GstVaapiDecoderClass { + /*< private >*/ + GObjectClass parent_class; + + GstVaapiDecoderStatus (*decode)(GstVaapiDecoder *decoder); +}; + +GType +gst_vaapi_decoder_get_type(void); + +gboolean +gst_vaapi_decoder_put_buffer_data( + GstVaapiDecoder *decoder, + const guchar *buf, + guint buf_size +); + +gboolean +gst_vaapi_decoder_put_buffer_data_copy( + GstVaapiDecoder *decoder, + const guchar *buf, + guint buf_size +); + +gboolean +gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf); + +GstVaapiSurfaceProxy * +gst_vaapi_decoder_get_surface( + GstVaapiDecoder *decoder, + GstVaapiDecoderStatus *pstatus +); + +GstVaapiSurfaceProxy * +gst_vaapi_decoder_timed_get_surface( + GstVaapiDecoder *decoder, + guint32 timeout, + GstVaapiDecoderStatus *pstatus +); + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c new file mode 100644 index 0000000000..f375a70b67 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -0,0 +1,610 @@ +/* + * gstvaapidecoder_ffmpeg.c - FFmpeg-based decoder + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * SECTION:gstvaapidecoder_ffmpeg + * @short_description: FFmpeg-based decoder + */ + +#include "config.h" +#include +#include +#include +#include "gstvaapidecoder_ffmpeg.h" +#include "gstvaapidecoder_priv.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapiobject_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiDecoderFfmpeg, + gst_vaapi_decoder_ffmpeg, + GST_VAAPI_TYPE_DECODER); + +#define GST_VAAPI_DECODER_FFMPEG_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DECODER_FFMPEG, \ + GstVaapiDecoderFfmpegPrivate)) + +/** Default I/O buffer size (32 KB) */ +#define DEFAULT_IOBUF_SIZE (32 * 1024) + +typedef struct _GstVaapiContextFfmpeg GstVaapiContextFfmpeg; +struct _GstVaapiContextFfmpeg { + struct vaapi_context base; + GstVaapiDecoderFfmpeg *decoder; +}; + +struct _GstVaapiDecoderFfmpegPrivate { + AVPacket packet; + AVFrame *frame; + guchar *iobuf; + guint iobuf_pos; + guint iobuf_size; + ByteIOContext ioctx; + AVFormatContext *fmtctx; + AVCodecContext *avctx; + GstVaapiContextFfmpeg *vactx; + guint video_stream_index; + guint is_constructed : 1; +}; + +/** Converts codec to FFmpeg codec id */ +static enum CodecID +get_codec_id_from_codec(GstVaapiCodec codec) +{ + switch (codec) { + case GST_VAAPI_CODEC_MPEG1: return CODEC_ID_MPEG1VIDEO; + case GST_VAAPI_CODEC_MPEG2: return CODEC_ID_MPEG2VIDEO; + case GST_VAAPI_CODEC_MPEG4: return CODEC_ID_MPEG4; + case GST_VAAPI_CODEC_H263: return CODEC_ID_H263; + case GST_VAAPI_CODEC_H264: return CODEC_ID_H264; + case GST_VAAPI_CODEC_VC1: return CODEC_ID_VC1; + } + return CODEC_ID_NONE; +} + +/** Converts codec to FFmpeg raw bitstream format */ +static const gchar * +get_raw_format_from_codec(GstVaapiCodec codec) +{ + switch (codec) { + case GST_VAAPI_CODEC_MPEG1: return "mpegvideo"; + case GST_VAAPI_CODEC_MPEG2: return "mpegvideo"; + case GST_VAAPI_CODEC_MPEG4: return "m4v"; + case GST_VAAPI_CODEC_H263: return "h263"; + case GST_VAAPI_CODEC_H264: return "h264"; + case GST_VAAPI_CODEC_VC1: return "vc1"; + } + return NULL; +} + +/** Finds a suitable profile from FFmpeg context */ +static GstVaapiProfile +get_profile(AVCodecContext *avctx) +{ + GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; + GstVaapiDisplay *display; + GstVaapiProfile test_profiles[4]; + guint i, n_profiles = 0; + +#define ADD_PROFILE(profile) do { \ + test_profiles[n_profiles++] = GST_VAAPI_PROFILE_##profile; \ + } while (0) + + switch (avctx->codec_id) { + case CODEC_ID_MPEG1VIDEO: + ADD_PROFILE(MPEG1); + break; + case CODEC_ID_MPEG2VIDEO: + ADD_PROFILE(MPEG2_MAIN); + ADD_PROFILE(MPEG2_SIMPLE); + break; + case CODEC_ID_H263: + ADD_PROFILE(H263_BASELINE); + /* fall-through */ + case CODEC_ID_MPEG4: + ADD_PROFILE(MPEG4_MAIN); + ADD_PROFILE(MPEG4_ADVANCED_SIMPLE); + ADD_PROFILE(MPEG4_SIMPLE); + break; + case CODEC_ID_H264: + if (avctx->profile == 66) /* baseline */ + ADD_PROFILE(H264_BASELINE); + else { + if (avctx->profile == 77) /* main */ + ADD_PROFILE(H264_MAIN); + ADD_PROFILE(H264_HIGH); + } + break; + case CODEC_ID_WMV3: + if (avctx->profile == 0) /* simple */ + ADD_PROFILE(VC1_SIMPLE); + ADD_PROFILE(VC1_MAIN); + break; + case CODEC_ID_VC1: + ADD_PROFILE(VC1_ADVANCED); + break; + default: + break; + } + +#undef ADD_PROFILE + + display = GST_VAAPI_DECODER_DISPLAY(vactx->decoder); + if (!display) + return 0; + + for (i = 0; i < n_profiles; i++) + if (gst_vaapi_display_has_decoder(display, test_profiles[i])) + return test_profiles[i]; + return 0; +} + +/** Probes FFmpeg format from input stream */ +static AVInputFormat * +get_probed_format(GstVaapiDecoder *decoder) +{ + GstVaapiDecoderFfmpegPrivate * const priv = + GST_VAAPI_DECODER_FFMPEG(decoder)->priv; + + AVProbeData pd; + pd.filename = ""; + pd.buf = priv->iobuf; + pd.buf_size = MIN(gst_vaapi_decoder_read_avail(decoder), priv->iobuf_size); + if (!gst_vaapi_decoder_copy(decoder, 0, pd.buf, pd.buf_size)) + return FALSE; + + GST_DEBUG("probing format from buffer %p [%d bytes]", pd.buf, pd.buf_size); + return av_probe_input_format(&pd, 1); +} + +/** Tries to get an FFmpeg format from the raw bitstream */ +static AVInputFormat * +get_raw_format(GstVaapiDecoder *decoder) +{ + const gchar *raw_format; + + raw_format = get_raw_format_from_codec(GST_VAAPI_DECODER_CODEC(decoder)); + if (!raw_format) + return NULL; + + GST_DEBUG("trying raw format %s", raw_format); + return av_find_input_format(raw_format); +} + +/** Reads one packet */ +static int +stream_read(void *opaque, uint8_t *buf, int buf_size) +{ + GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(opaque); + GstVaapiDecoderFfmpegPrivate * const priv = + GST_VAAPI_DECODER_FFMPEG(decoder)->priv; + + if (buf_size > 0) { + if (priv->is_constructed) { + buf_size = gst_vaapi_decoder_read(decoder, buf, buf_size); + } + else { + buf_size = gst_vaapi_decoder_copy( + decoder, + priv->iobuf_pos, + buf, buf_size + ); + priv->iobuf_pos += buf_size; + } + } + return buf_size; +} + +/** Seeks into stream */ +static int64_t +stream_seek(void *opaque, int64_t offset, int whence) +{ + GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(opaque); + GstVaapiDecoderFfmpegPrivate * const priv = + GST_VAAPI_DECODER_FFMPEG(decoder)->priv; + + /* If we parsed the headers (decoder is constructed), we can no + longer seek into the stream */ + if (priv->is_constructed && + !((whence == SEEK_SET || whence == SEEK_CUR) && offset == 0)) + return -1; + + switch (whence) { + case SEEK_SET: + priv->iobuf_pos = offset; + break; + case SEEK_CUR: + priv->iobuf_pos += offset; + break; + case SEEK_END: + priv->iobuf_pos = gst_vaapi_decoder_read_avail(decoder) + offset; + break; + default: + return -1; + } + return priv->iobuf_pos; +} + +/** AVCodecContext.get_format() implementation */ +static enum PixelFormat +gst_vaapi_decoder_ffmpeg_get_format(AVCodecContext *avctx, const enum PixelFormat *fmt) +{ + GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; + GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(vactx->decoder); + GstVaapiProfile profile; + gboolean success; + guint i; + + profile = get_profile(avctx); + if (!profile) + return PIX_FMT_NONE; + + /* XXX: only VLD entrypoint is supported at this time */ + for (i = 0; fmt[i] != PIX_FMT_NONE; i++) + if (fmt[i] == PIX_FMT_VAAPI_VLD) + break; + + success = gst_vaapi_decoder_ensure_context( + decoder, + profile, + GST_VAAPI_ENTRYPOINT_VLD, + avctx->width, avctx->height + ); + if (success) { + GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder); + GstVaapiContext * const context = GST_VAAPI_DECODER_CONTEXT(decoder); + vactx->base.display = GST_VAAPI_DISPLAY_VADISPLAY(display); + vactx->base.context_id = GST_VAAPI_OBJECT_ID(context); + return fmt[i]; + } + return PIX_FMT_NONE; +} + +/** AVCodecContext.get_buffer() implementation */ +static int +gst_vaapi_decoder_ffmpeg_get_buffer(AVCodecContext *avctx, AVFrame *pic) +{ + GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; + GstVaapiContext * const context = GST_VAAPI_DECODER_CONTEXT(vactx->decoder); + GstVaapiSurface *surface; + GstVaapiID surface_id; + + surface = gst_vaapi_context_get_surface(context); + if (!surface) { + GST_DEBUG("failed to get a free VA surface"); + return -1; + } + + surface_id = GST_VAAPI_OBJECT_ID(surface); + GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); + + pic->type = FF_BUFFER_TYPE_USER; + pic->age = 1; + pic->data[0] = (uint8_t *)surface; + pic->data[1] = NULL; + pic->data[2] = NULL; + pic->data[3] = (uint8_t *)(uintptr_t)surface_id; + pic->linesize[0] = 0; + pic->linesize[1] = 0; + pic->linesize[2] = 0; + pic->linesize[3] = 0; + return 0; +} + +/** AVCodecContext.reget_buffer() implementation */ +static int +gst_vaapi_decoder_ffmpeg_reget_buffer(AVCodecContext *avctx, AVFrame *pic) +{ + GST_DEBUG("UNIMPLEMENTED"); + return -1; +} + +/** AVCodecContext.release_buffer() implementation */ +static void +gst_vaapi_decoder_ffmpeg_release_buffer(AVCodecContext *avctx, AVFrame *pic) +{ + GstVaapiID surface_id = GST_VAAPI_ID(GPOINTER_TO_UINT(pic->data[3])); + + GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); + + pic->data[0] = NULL; + pic->data[1] = NULL; + pic->data[2] = NULL; + pic->data[3] = NULL; +} + +static void +gst_vaapi_decoder_ffmpeg_destroy(GstVaapiDecoderFfmpeg *ffdecoder) +{ + GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; + + if (priv->avctx) { + avcodec_close(priv->avctx); + priv->avctx = NULL; + } + + if (priv->vactx) { + g_free(priv->vactx); + priv->vactx = NULL; + } + + if (priv->fmtctx) { + av_close_input_stream(priv->fmtctx); + priv->fmtctx = NULL; + } + + if (priv->iobuf) { + g_free(priv->iobuf); + priv->iobuf = NULL; + priv->iobuf_pos = 0; + } + + av_freep(&priv->frame); + av_free_packet(&priv->packet); +} + +static gboolean +gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) +{ + GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(ffdecoder); + GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; + GstVaapiCodec codec = GST_VAAPI_DECODER_CODEC(decoder); + enum CodecID codec_id = get_codec_id_from_codec(codec); + typedef AVInputFormat *(*GetFormatFunc)(GstVaapiDecoder *); + GetFormatFunc get_format[2]; + AVInputFormat *format; + AVStream *video_stream; + AVCodec *ffcodec; + guint i; + + if (!priv->vactx) { + priv->vactx = g_new(GstVaapiContextFfmpeg, 1); + if (!priv->vactx) + return FALSE; + } + memset(&priv->vactx->base, 0, sizeof(priv->vactx->base)); + priv->vactx->decoder = ffdecoder; + + if (!priv->frame) { + priv->frame = avcodec_alloc_frame(); + if (!priv->frame) + return FALSE; + } + + if (!priv->iobuf) { + priv->iobuf = g_malloc0(priv->iobuf_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!priv->iobuf) + return FALSE; + } + + get_format[ !codec] = get_raw_format; + get_format[!!codec] = get_probed_format; + for (i = 0; i < 2; i++) { + format = get_format[i](decoder); + if (!format) + continue; + + priv->iobuf_pos = 0; + init_put_byte( + &priv->ioctx, + priv->iobuf, + priv->iobuf_size, + 0, /* write flags */ + ffdecoder, + stream_read, + NULL, /* no packet writer callback */ + stream_seek + ); + priv->ioctx.is_streamed = 1; + + if (av_open_input_stream(&priv->fmtctx, &priv->ioctx, "", format, NULL) < 0) + continue; + + if (av_find_stream_info(priv->fmtctx) >= 0) + break; + + av_close_input_stream(priv->fmtctx); + priv->fmtctx = NULL; + } + if (!priv->fmtctx) + return FALSE; + + if (av_find_stream_info(priv->fmtctx) < 0) + return FALSE; + dump_format(priv->fmtctx, 0, "", 0); + + video_stream = NULL; + for (i = 0; i < priv->fmtctx->nb_streams; i++) { + AVStream * const stream = priv->fmtctx->streams[i]; + if (!video_stream && + stream->codec->codec_type == CODEC_TYPE_VIDEO && + (codec ? (stream->codec->codec_id == codec_id) : 1)) { + video_stream = stream; + } + else + stream->discard = AVDISCARD_ALL; + } + if (!video_stream) + return FALSE; + + priv->video_stream_index = video_stream->index; + priv->avctx = video_stream->codec; + priv->avctx->hwaccel_context = priv->vactx; + priv->avctx->get_format = gst_vaapi_decoder_ffmpeg_get_format; + priv->avctx->get_buffer = gst_vaapi_decoder_ffmpeg_get_buffer; + priv->avctx->reget_buffer = gst_vaapi_decoder_ffmpeg_reget_buffer; + priv->avctx->release_buffer = gst_vaapi_decoder_ffmpeg_release_buffer; + priv->avctx->thread_count = 1; + priv->avctx->draw_horiz_band = NULL; + priv->avctx->slice_flags = SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; + + ffcodec = avcodec_find_decoder(priv->avctx->codec_id); + if (!ffcodec || avcodec_open(priv->avctx, ffcodec) < 0) + return FALSE; + + av_init_packet(&priv->packet); + return TRUE; +} + +static GstVaapiSurface * +decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; + GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(ffdecoder); + GstVaapiSurface *surface = NULL; + int got_picture = 0; + + GST_VAAPI_DISPLAY_LOCK(display); + avcodec_decode_video( + priv->avctx, + priv->frame, + &got_picture, + buf, buf_size + ); + GST_VAAPI_DISPLAY_UNLOCK(display); + + if (got_picture) { + surface = gst_vaapi_context_find_surface_by_id( + GST_VAAPI_DECODER_CONTEXT(ffdecoder), + GPOINTER_TO_UINT(priv->frame->data[3]) + ); + } + return surface; +} + +GstVaapiDecoderStatus +gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder) +{ + GstVaapiDecoderFfmpeg * const ffdecoder = GST_VAAPI_DECODER_FFMPEG(decoder); + GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; + GstVaapiSurface *surface = NULL; + AVPacket packet; + + if (!priv->is_constructed) { + priv->is_constructed = gst_vaapi_decoder_ffmpeg_create(ffdecoder); + if (!priv->is_constructed) { + gst_vaapi_decoder_ffmpeg_destroy(ffdecoder); + return GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED; + } + } + + av_init_packet(&packet); + while (av_read_frame(priv->fmtctx, &packet) == 0) { + if (packet.stream_index != priv->video_stream_index) + continue; + + surface = decode_frame(ffdecoder, packet.data, packet.size); + if (surface) /* decode a single frame only */ + break; + } + if (!surface) + surface = decode_frame(ffdecoder, NULL, 0); + av_free_packet(&packet); + + if (surface && gst_vaapi_decoder_push_surface(decoder, surface)) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; +} + +static void +gst_vaapi_decoder_ffmpeg_finalize(GObject *object) +{ + GstVaapiDecoderFfmpeg * const ffdecoder = GST_VAAPI_DECODER_FFMPEG(object); + + gst_vaapi_decoder_ffmpeg_destroy(ffdecoder); + + G_OBJECT_CLASS(gst_vaapi_decoder_ffmpeg_parent_class)->finalize(object); +} + +static void +gst_vaapi_decoder_ffmpeg_class_init(GstVaapiDecoderFfmpegClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiDecoderFfmpegPrivate)); + + object_class->finalize = gst_vaapi_decoder_ffmpeg_finalize; + + decoder_class->decode = gst_vaapi_decoder_ffmpeg_decode; +} + +static gpointer +gst_vaapi_decoder_ffmpeg_init_once_cb(gpointer user_data) +{ + av_register_all(); + return NULL; +} + +static inline void +gst_vaapi_decoder_ffmpeg_init_once(void) +{ + static GOnce once = G_ONCE_INIT; + + g_once(&once, gst_vaapi_decoder_ffmpeg_init_once_cb, NULL); +} + +static void +gst_vaapi_decoder_ffmpeg_init(GstVaapiDecoderFfmpeg *decoder) +{ + GstVaapiDecoderFfmpegPrivate *priv; + + gst_vaapi_decoder_ffmpeg_init_once(); + + priv = GST_VAAPI_DECODER_FFMPEG_GET_PRIVATE(decoder); + decoder->priv = priv; + priv->frame = NULL; + priv->iobuf = NULL; + priv->iobuf_pos = 0; + priv->iobuf_size = DEFAULT_IOBUF_SIZE; + priv->fmtctx = NULL; + priv->avctx = NULL; + priv->vactx = NULL; + priv->video_stream_index = 0; + priv->is_constructed = FALSE; + + av_init_packet(&priv->packet); +} + +/** + * gst_vaapi_decoder_ffmpeg_new: + * @display: a #GstVaapiDisplay + * @codec: a #GstVaapiCodec + * + * Creates a new #GstVaapiDecoder with the specified @codec bound to + * @display. If @codec is zero, the first video stream will be + * selected. Otherwise, the first video stream matching @codec is + * used, if any. + * + * Return value: the newly allocated #GstVaapiDecoder object + */ +GstVaapiDecoder * +gst_vaapi_decoder_ffmpeg_new(GstVaapiDisplay *display, GstVaapiCodec codec) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + return g_object_new(GST_VAAPI_TYPE_DECODER_FFMPEG, + "display", display, + "codec", codec, + NULL); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h new file mode 100644 index 0000000000..184759a687 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h @@ -0,0 +1,86 @@ +/* + * gstvaapidecoder_ffmpeg.h - FFmpeg-based decoder + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_DECODER_FFMPEG_H +#define GST_VAAPI_DECODER_FFMPEG_H + +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DECODER_FFMPEG \ + (gst_vaapi_decoder_ffmpeg_get_type()) + +#define GST_VAAPI_DECODER_FFMPEG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DECODER_FFMPEG, \ + GstVaapiDecoderFfmpeg)) + +#define GST_VAAPI_DECODER_FFMPEG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DECODER_FFMPEG, \ + GstVaapiDecoderFfmpegClass)) + +#define GST_VAAPI_IS_DECODER_FFMPEG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_FFMPEG)) + +#define GST_VAAPI_IS_DECODER_FFMPEG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_FFMPEG)) + +#define GST_VAAPI_DECODER_FFMPEG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DECODER_FFMPEG, \ + GstVaapiDecoderFfmpegClass)) + +typedef struct _GstVaapiDecoderFfmpeg GstVaapiDecoderFfmpeg; +typedef struct _GstVaapiDecoderFfmpegPrivate GstVaapiDecoderFfmpegPrivate; +typedef struct _GstVaapiDecoderFfmpegClass GstVaapiDecoderFfmpegClass; + +/** + * GstVaapiDecoderFfmpeg: + * + * A decoder based on FFmpeg. + */ +struct _GstVaapiDecoderFfmpeg { + /*< private >*/ + GstVaapiDecoder parent_instance; + + GstVaapiDecoderFfmpegPrivate *priv; +}; + +/** + * GstVaapiDecoderFfmpegClass: + * + * A decoder class based on FFmpeg. + */ +struct _GstVaapiDecoderFfmpegClass { + /*< private >*/ + GstVaapiDecoderClass parent_class; +}; + +GType +gst_vaapi_decoder_ffmpeg_get_type(void); + +GstVaapiDecoder * +gst_vaapi_decoder_ffmpeg_new(GstVaapiDisplay *display, GstVaapiCodec codec); + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_FFMPEG_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h new file mode 100644 index 0000000000..bfc05a7b84 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -0,0 +1,123 @@ +/* + * gstvaapidecoder_priv.h - VA decoder abstraction (private definitions) + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPI_DECODER_PRIV_H +#define GST_VAAPI_DECODER_PRIV_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_DECODER_CAST(decoder) ((GstVaapiDecoder *)(decoder)) + +/** + * 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)->priv->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)->priv->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)->priv->codec + +#define GST_VAAPI_DECODER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DECODER, \ + GstVaapiDecoderPrivate)) + +struct _GstVaapiDecoderPrivate { + GstVaapiDisplay *display; + GstVaapiContext *context; + GstVaapiCodec codec; + GstAdapter *adapter; + GMutex *adapter_mutex; + GCond *adapter_cond; + GQueue surfaces; + GMutex *surfaces_mutex; + GCond *surfaces_cond; + GThread *decoder_thread; + guint decoder_thread_cancel : 1; +}; + +gboolean +gst_vaapi_decoder_ensure_context( + GstVaapiDecoder *decoder, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint, + guint width, + guint height +) attribute_hidden; + +guint +gst_vaapi_decoder_copy( + GstVaapiDecoder *decoder, + guint offset, + guchar *buf, + guint buf_size +) attribute_hidden; + +guint +gst_vaapi_decoder_read_avail(GstVaapiDecoder *decoder) + attribute_hidden; + +guint +gst_vaapi_decoder_read(GstVaapiDecoder *decoder, guchar *buf, guint buf_size) + attribute_hidden; + +void +gst_vaapi_decoder_flush(GstVaapiDecoder *decoder, guint buf_size) + attribute_hidden; + +gboolean +gst_vaapi_decoder_push_surface( + GstVaapiDecoder *decoder, + GstVaapiSurface *surface +) attribute_hidden; + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_PRIV_H */ + From 62358dce926601cbe10b58d66fb899c2a4e61e07 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 23 Apr 2010 16:11:55 +0000 Subject: [PATCH 0260/3781] Add decoder demos. Use -c (mpeg2|h264|vc1) to select the codec. XXX: only VC-1 decoding works at this time because of awful bugs left in GstVaapiDecoderFfmpeg et al. --- tests/Makefile.am | 10 +- tests/test-decode.c | 152 ++++ tests/test-h264.c | 1106 +++++++++++++++++++++++++++ tests/test-h264.h | 28 + tests/test-mpeg2.c | 1645 +++++++++++++++++++++++++++++++++++++++ tests/test-mpeg2.h | 28 + tests/test-vc1.c | 1774 +++++++++++++++++++++++++++++++++++++++++++ tests/test-vc1.h | 28 + 8 files changed, 4770 insertions(+), 1 deletion(-) create mode 100644 tests/test-decode.c create mode 100644 tests/test-h264.c create mode 100644 tests/test-h264.h create mode 100644 tests/test-mpeg2.c create mode 100644 tests/test-mpeg2.h create mode 100644 tests/test-vc1.c create mode 100644 tests/test-vc1.h diff --git a/tests/Makefile.am b/tests/Makefile.am index 8b3f9bd137..0147c9f19a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,5 @@ noinst_PROGRAMS = \ + test-decode \ test-display \ test-surfaces \ test-windows \ @@ -34,6 +35,13 @@ if USE_GLX TEST_MIX_LIBS += $(TEST_GLX_LIBS) endif +test_codecs_source_c = test-mpeg2.c test-h264.c test-vc1.c +test_codecs_source_h = $(test_codecs_source_c:%.c=%.h) + +test_decode_SOURCES = test-decode.c $(test_codecs_source_c) +test_decode_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) +test_decode_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) + test_display_SOURCES = test-display.c test_display_CFLAGS = $(TEST_CFLAGS) $(TEST_MIX_CFLAGS) test_display_LDADD = $(TEST_LIBS) $(TEST_MIX_LIBS) @@ -50,7 +58,7 @@ test_textures_SOURCES = test-textures.c image.c test_textures_CFLAGS = $(TEST_CFLAGS) $(TEST_GLX_CFLAGS) test_textures_LDADD = $(TEST_LIBS) $(TEST_GLX_LIBS) -EXTRA_DIST = image.h +EXTRA_DIST = image.h $(test_codecs_source_c) $(test_codecs_source_h) # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/test-decode.c b/tests/test-decode.c new file mode 100644 index 0000000000..a08383f7ff --- /dev/null +++ b/tests/test-decode.c @@ -0,0 +1,152 @@ +/* + * test-decode.c - Test GstVaapiDecoder + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include +#include "test-mpeg2.h" +#include "test-h264.h" +#include "test-vc1.h" + +/* Default timeout to wait for the first decoded frame (10 ms) */ +/* Defined to -1 if the application indefintely waits for the decoded frame */ +#define TIMEOUT -1 + +typedef void (*GetVideoDataFunc)(const guchar **data, guint *size); + +typedef struct _CodecDefs CodecDefs; +struct _CodecDefs { + const gchar *codec_str; + GstVaapiCodec codec; + GetVideoDataFunc get_video_data; +}; + +static const CodecDefs g_codec_defs[] = { + { "mpeg2", GST_VAAPI_CODEC_MPEG2, mpeg2_get_video_data }, + { "h264", GST_VAAPI_CODEC_H264, h264_get_video_data }, + { "vc1", GST_VAAPI_CODEC_VC1, vc1_get_video_data }, + { NULL, } +}; + +static const CodecDefs * +get_codec_defs(const gchar *codec_str) +{ + const CodecDefs *c; + for (c = g_codec_defs; c->codec_str; c++) + if (strcmp(codec_str, c->codec_str) == 0) + return c; + return NULL; +} + +static inline void pause(void) +{ + g_print("Press any key to continue...\n"); + getchar(); +} + +static gchar *g_codec_str; + +static GOptionEntry g_options[] = { + { "codec", 'c', + 0, + G_OPTION_ARG_STRING, &g_codec_str, + "codec to test", NULL }, + { NULL, } +}; + +int +main(int argc, char *argv[]) +{ + GOptionContext *options; + GstVaapiDisplay *display; + GstVaapiWindow *window; + GstVaapiDecoder *decoder; + GstVaapiDecoderStatus status; + const CodecDefs *codec; + GstVaapiSurfaceProxy *proxy; + const guchar *vdata; + guint vdata_size; + + static const guint win_width = 640; + static const guint win_height = 480; + + gst_init(&argc, &argv); + + options = g_option_context_new(" - test-decode options"); + g_option_context_add_main_entries(options, g_options, NULL); + g_option_context_parse(options, &argc, &argv, NULL); + g_option_context_free(options); + + if (!g_codec_str) + g_codec_str = g_strdup("h264"); + + g_print("Test %s decode\n", g_codec_str); + codec = get_codec_defs(g_codec_str); + if (!codec) + g_error("no %s codec data found", g_codec_str); + + display = gst_vaapi_display_x11_new(NULL); + if (!display) + g_error("could not create VA display"); + + window = gst_vaapi_window_x11_new(display, win_width, win_height); + if (!window) + g_error("could not create window"); + + codec->get_video_data(&vdata, &vdata_size); + decoder = gst_vaapi_decoder_ffmpeg_new(display, codec->codec); + if (!decoder) + g_error("could not create FFmpeg decoder"); + + if (!gst_vaapi_decoder_put_buffer_data(decoder, vdata, vdata_size)) + g_error("could not send video data to the decoder"); + if (0 && !gst_vaapi_decoder_put_buffer(decoder, NULL)) + g_error("could not send EOS to the decoder"); + + if (TIMEOUT < 0) { + proxy = gst_vaapi_decoder_get_surface(decoder, &status); + if (!proxy) + g_error("could not get decoded surface"); + } + else { + proxy = gst_vaapi_decoder_timed_get_surface(decoder, TIMEOUT, &status); + if (!proxy) + g_warning("Could not get decoded surface after %d us", TIMEOUT); + } + + gst_vaapi_window_show(window); + + if (!gst_vaapi_window_put_surface(window, proxy->surface, NULL, NULL, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + g_error("could not render surface"); + + pause(); + + g_object_unref(proxy); + g_object_unref(decoder); + g_object_unref(window); + g_object_unref(display); + g_free(g_codec_str); + gst_deinit(); + return 0; +} diff --git a/tests/test-h264.c b/tests/test-h264.c new file mode 100644 index 0000000000..1d921c5fee --- /dev/null +++ b/tests/test-h264.c @@ -0,0 +1,1106 @@ +/* + * test-h264.c - H.264 test data + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "test-h264.h" + +#define H264_CLIP_WIDTH 320 +#define H264_CLIP_HEIGHT 240 +#define H264_CLIP_SLICE_OFFSET 52 +#define H264_CLIP_SLICE_SIZE 12071 + +/* Data dump of a 320x240 H.264 video clip (h264.mp4), it has a single frame */ +static const guchar h264_clip[] = { + 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6f, 0x6d, + 0x00, 0x00, 0x02, 0x00, 0x69, 0x73, 0x6f, 0x6d, 0x69, 0x73, 0x6f, 0x32, + 0x61, 0x76, 0x63, 0x31, 0x6d, 0x70, 0x34, 0x31, 0x00, 0x00, 0x00, 0x08, + 0x66, 0x72, 0x65, 0x65, 0x00, 0x00, 0x2f, 0x33, 0x6d, 0x64, 0x61, 0x74, + 0x00, 0x00, 0x2f, 0x27, 0x65, 0x88, 0x82, 0x00, 0x45, 0xbb, 0x9d, 0x38, + 0x9b, 0xe8, 0x48, 0xef, 0xed, 0xa7, 0xd7, 0x9c, 0x19, 0x9b, 0x5a, 0xca, + 0x00, 0x0d, 0x54, 0x0c, 0xe3, 0xd5, 0xad, 0xa9, 0x5d, 0x71, 0x24, 0x83, + 0xbb, 0x36, 0x4d, 0xb1, 0xf5, 0x0f, 0xc6, 0x66, 0xb6, 0x6d, 0x1d, 0xa5, + 0x45, 0xfc, 0xa0, 0x4c, 0xbf, 0xfb, 0x2f, 0x5c, 0x1a, 0x5a, 0x3b, 0x29, + 0xe0, 0x35, 0x95, 0x44, 0x8e, 0x2f, 0x22, 0xd3, 0x3a, 0x48, 0x88, 0x7d, + 0x32, 0x97, 0xff, 0xd8, 0x54, 0x7f, 0x7f, 0x65, 0x57, 0x71, 0xaf, 0xba, + 0x17, 0xe0, 0x12, 0x24, 0xc9, 0x5b, 0xaa, 0xc7, 0xd5, 0x27, 0xc9, 0x64, + 0x5d, 0x5e, 0xa0, 0xea, 0x57, 0xd2, 0x7d, 0x55, 0x6c, 0xf2, 0x44, 0x2f, + 0x4b, 0x5d, 0xbd, 0x62, 0xb9, 0xc2, 0xfa, 0x1e, 0x8f, 0xbc, 0x57, 0x5f, + 0xc1, 0x2d, 0xb3, 0x9a, 0x0e, 0x58, 0x75, 0xf7, 0x08, 0xdf, 0x2d, 0xda, + 0xc1, 0xa5, 0x55, 0x76, 0x06, 0xaf, 0x92, 0x28, 0x43, 0xc5, 0x20, 0x16, + 0x96, 0xf5, 0x79, 0x1e, 0x88, 0x77, 0xb3, 0x4e, 0xb8, 0x4f, 0x3e, 0x51, + 0x3c, 0xcf, 0xc0, 0x28, 0xda, 0xb8, 0xa3, 0x1d, 0xed, 0x8e, 0x04, 0x74, + 0x82, 0xc1, 0x5d, 0xa8, 0x3c, 0x25, 0xd2, 0x84, 0x0b, 0x34, 0x40, 0x8b, + 0x7f, 0xee, 0xae, 0xf8, 0xde, 0x6e, 0x28, 0xf6, 0xfc, 0xfc, 0x14, 0x7e, + 0x95, 0xd9, 0xd8, 0x2c, 0x09, 0x49, 0x27, 0x64, 0x13, 0x83, 0x5c, 0x6f, + 0xd4, 0x09, 0x48, 0xa8, 0xd4, 0x1b, 0x6e, 0x4d, 0x05, 0x0a, 0xbe, 0x27, + 0xff, 0xf4, 0x27, 0x04, 0x41, 0xa0, 0x23, 0x61, 0xe6, 0x26, 0x32, 0xf4, + 0xa3, 0xca, 0x97, 0xfc, 0xeb, 0x6b, 0x45, 0x35, 0x13, 0x69, 0xd9, 0x41, + 0x0f, 0xa6, 0xc0, 0xbe, 0xd5, 0xfa, 0x28, 0xa6, 0x4f, 0x62, 0x3e, 0x1f, + 0xcb, 0x98, 0x0a, 0x70, 0x09, 0xc1, 0xe3, 0x69, 0x30, 0x20, 0xe7, 0xd5, + 0x1c, 0xf0, 0x7e, 0x52, 0x1d, 0x6a, 0xdd, 0x14, 0x58, 0x5e, 0x7a, 0x35, + 0x57, 0xa1, 0xe6, 0x83, 0x46, 0x57, 0x6e, 0x57, 0x7f, 0x72, 0x5d, 0x0c, + 0x0c, 0xf4, 0x40, 0x11, 0x8c, 0xbb, 0xdf, 0xd1, 0x54, 0xfb, 0x7d, 0xf7, + 0x03, 0xb9, 0x4e, 0xa3, 0x76, 0x4c, 0xce, 0xfb, 0x9e, 0x39, 0x02, 0xf0, + 0x48, 0xb5, 0x8c, 0x36, 0x6e, 0x93, 0x79, 0x48, 0xcc, 0x28, 0xec, 0xd7, + 0xb8, 0x02, 0xe5, 0xa3, 0x37, 0x01, 0xe1, 0x3c, 0x40, 0x8f, 0x68, 0x27, + 0xbc, 0xec, 0x6b, 0x59, 0xb9, 0xfe, 0xb8, 0x67, 0x68, 0x83, 0x99, 0x97, + 0x1e, 0xcc, 0x4e, 0x23, 0x82, 0x26, 0x93, 0x7b, 0x7a, 0x9e, 0xdc, 0x42, + 0xca, 0x1b, 0x3e, 0x13, 0x19, 0x45, 0x03, 0x40, 0xab, 0xd2, 0xda, 0x6b, + 0x6c, 0x26, 0xdb, 0xe3, 0x72, 0x06, 0x89, 0xea, 0x03, 0x95, 0xe3, 0x14, + 0xe1, 0x4a, 0x16, 0x58, 0x2d, 0x67, 0xaa, 0xbf, 0xbe, 0x37, 0x54, 0x19, + 0xb1, 0x57, 0x61, 0x85, 0x82, 0x5f, 0x63, 0x33, 0xe2, 0xf8, 0x7f, 0x4f, + 0x21, 0x44, 0x8a, 0x0e, 0x21, 0x2b, 0x12, 0x99, 0x4d, 0xd9, 0x2e, 0xea, + 0x36, 0x2d, 0x45, 0xcb, 0xe2, 0xfe, 0xdd, 0x03, 0x3b, 0x08, 0x58, 0x60, + 0x1e, 0xb2, 0xfa, 0x3b, 0x89, 0xa5, 0x03, 0xde, 0xab, 0x71, 0x32, 0x48, + 0x46, 0x2c, 0xfb, 0x2b, 0x84, 0x83, 0xc9, 0xff, 0xf6, 0xf5, 0x2f, 0xe7, + 0x2f, 0x6a, 0x5d, 0x86, 0xe2, 0x48, 0x23, 0x6d, 0x84, 0x60, 0x9b, 0xc0, + 0x25, 0x1e, 0xff, 0x94, 0xe8, 0xf4, 0xd0, 0x4e, 0x11, 0x60, 0xda, 0x20, + 0xa8, 0xfd, 0xf3, 0x00, 0x4f, 0x0e, 0x4f, 0xa2, 0xeb, 0xe1, 0xa8, 0xb3, + 0x47, 0x35, 0x62, 0x83, 0x6f, 0x08, 0x6b, 0xb8, 0x82, 0x04, 0xcc, 0x63, + 0x69, 0xd7, 0xba, 0x10, 0xd4, 0x51, 0xe6, 0xb5, 0x34, 0xe8, 0x7d, 0xaf, + 0x87, 0xcf, 0x1d, 0xeb, 0x46, 0xc1, 0xcd, 0xcb, 0xf2, 0x3b, 0x3e, 0xa0, + 0x61, 0xc7, 0x68, 0x86, 0x0b, 0x9f, 0x0b, 0x59, 0xc0, 0x79, 0x4e, 0xcc, + 0x79, 0x91, 0xa0, 0xe8, 0x80, 0x6c, 0xbd, 0x35, 0x12, 0x71, 0x2f, 0x5e, + 0xa4, 0xfc, 0xe6, 0x51, 0xe0, 0xbe, 0x41, 0x1a, 0x19, 0x60, 0xd8, 0xac, + 0xcd, 0x93, 0x05, 0x70, 0xa0, 0xda, 0x53, 0x4e, 0x5a, 0x6d, 0x9b, 0x3f, + 0x28, 0x73, 0x87, 0x6f, 0x6d, 0x41, 0x5a, 0x13, 0xd0, 0xea, 0x19, 0xb3, + 0xb7, 0xf1, 0x75, 0x92, 0xae, 0x43, 0x9d, 0xe3, 0xa7, 0x4d, 0x5a, 0x52, + 0x36, 0xce, 0x6b, 0x1e, 0x2b, 0x2e, 0xab, 0x0c, 0xd7, 0xe4, 0x1c, 0x44, + 0x72, 0x9d, 0x86, 0xb6, 0xeb, 0xe5, 0x80, 0xc4, 0x45, 0x21, 0x8b, 0xe0, + 0xe0, 0x9d, 0x09, 0xfa, 0x0b, 0x59, 0x0c, 0x2c, 0x9d, 0x97, 0x15, 0x56, + 0xd0, 0x21, 0xd8, 0x90, 0xb4, 0x89, 0xc4, 0x96, 0x76, 0xf1, 0x64, 0xa5, + 0x85, 0x2a, 0x13, 0xfb, 0xfa, 0x11, 0x1e, 0x2d, 0x63, 0xc2, 0x9a, 0x87, + 0x99, 0x2c, 0x18, 0xb8, 0xeb, 0x6a, 0x5c, 0x68, 0x26, 0x63, 0xcc, 0x1b, + 0x1a, 0x5c, 0x7f, 0x0d, 0x45, 0xcc, 0x56, 0x46, 0x92, 0xbb, 0x76, 0xf2, + 0x2e, 0x52, 0x05, 0x3c, 0xe3, 0xbb, 0x59, 0x9b, 0x89, 0x03, 0x0d, 0x48, + 0xb1, 0xdc, 0x78, 0x04, 0x03, 0x24, 0xf4, 0x62, 0xcf, 0xb1, 0xc6, 0x64, + 0x05, 0xbd, 0x89, 0x94, 0x1a, 0x8d, 0xc1, 0xbe, 0xac, 0xe0, 0xed, 0x89, + 0xf3, 0x47, 0x81, 0x82, 0xb9, 0x64, 0xcc, 0x8e, 0xc4, 0x1e, 0xa9, 0xf6, + 0xde, 0x8d, 0xb7, 0x33, 0xba, 0x5b, 0x49, 0x0d, 0x0a, 0x16, 0x96, 0x7d, + 0x89, 0x82, 0xe0, 0x5a, 0x08, 0x55, 0xbd, 0xce, 0xca, 0xc0, 0x46, 0x1a, + 0x6b, 0xf9, 0x7d, 0x03, 0xe8, 0x35, 0x69, 0x7d, 0x87, 0xc9, 0x71, 0x01, + 0x7e, 0xa8, 0x3a, 0x9c, 0xd5, 0xe2, 0x71, 0xa6, 0xc7, 0xe2, 0x2d, 0xf3, + 0x6f, 0x74, 0x0f, 0x3e, 0x03, 0x70, 0x5e, 0xec, 0x8c, 0x66, 0xf9, 0x71, + 0x9a, 0xd2, 0x56, 0x57, 0x37, 0xcd, 0x50, 0x55, 0x97, 0xea, 0x67, 0x20, + 0x59, 0x06, 0x4d, 0x22, 0xa0, 0x85, 0x90, 0xb3, 0x59, 0x15, 0x75, 0x0d, + 0x70, 0xbd, 0xb5, 0x7d, 0x72, 0xaa, 0xea, 0xfc, 0x9d, 0x08, 0x8d, 0xdf, + 0x31, 0x21, 0x2d, 0xef, 0x00, 0x24, 0x6c, 0xae, 0x82, 0x6e, 0x1a, 0x4b, + 0x28, 0xa5, 0x6d, 0x98, 0xeb, 0x50, 0x87, 0x6f, 0x1b, 0xa5, 0xba, 0x1c, + 0xda, 0x59, 0xb8, 0x4c, 0x17, 0xe3, 0xd5, 0x10, 0x46, 0x94, 0x91, 0xed, + 0x0b, 0xd3, 0xfc, 0x06, 0x81, 0x60, 0x88, 0x5f, 0x58, 0x81, 0x26, 0x54, + 0xdc, 0xd5, 0x7c, 0xbe, 0x30, 0x04, 0x17, 0x84, 0x76, 0xe8, 0xb6, 0x8a, + 0xec, 0x84, 0x02, 0xcf, 0xc7, 0xda, 0x2d, 0x2e, 0x31, 0xc2, 0x77, 0x31, + 0x54, 0x32, 0xbd, 0x77, 0xa2, 0xa5, 0x5d, 0xec, 0x1c, 0x27, 0xf6, 0xec, + 0xc8, 0x3f, 0xeb, 0x1a, 0x24, 0xcb, 0x74, 0xd0, 0xb3, 0x52, 0xa8, 0x8f, + 0x4c, 0x26, 0xbf, 0x68, 0xb2, 0x87, 0xf3, 0xa8, 0xa9, 0x4f, 0x71, 0x57, + 0xc7, 0xa8, 0x34, 0x5a, 0x01, 0x68, 0xae, 0x5c, 0xb3, 0xd8, 0x23, 0x6b, + 0xea, 0x18, 0xdf, 0xa9, 0xe5, 0xc4, 0x11, 0x49, 0x2b, 0xfa, 0xa8, 0xf3, + 0x8f, 0x80, 0x47, 0xa0, 0x19, 0xc7, 0x20, 0xef, 0xbf, 0xed, 0xe1, 0x38, + 0x8b, 0x16, 0x54, 0x36, 0x60, 0x8b, 0x04, 0x26, 0x9c, 0x6b, 0x1a, 0x95, + 0x4c, 0x94, 0x6a, 0x53, 0xcf, 0xb4, 0x4b, 0x38, 0x3a, 0x15, 0x26, 0x94, + 0x10, 0x1c, 0x35, 0xe4, 0x57, 0x80, 0x19, 0xad, 0x1f, 0x82, 0xe8, 0x47, + 0xe4, 0x90, 0xa2, 0x42, 0x30, 0x43, 0x15, 0x92, 0x2b, 0x39, 0xfb, 0x7b, + 0xb3, 0xdb, 0xc7, 0x5b, 0x79, 0x5e, 0x91, 0xba, 0x38, 0x74, 0xd6, 0x00, + 0x26, 0xa5, 0x8f, 0xa4, 0x31, 0xe6, 0x7b, 0xeb, 0x52, 0xc2, 0xe2, 0xa1, + 0x6b, 0x5f, 0x17, 0xf1, 0x15, 0xc9, 0x4b, 0x44, 0x93, 0x77, 0x28, 0xdf, + 0x2a, 0xc0, 0xb5, 0x97, 0xfc, 0xbe, 0x2e, 0x72, 0x53, 0x58, 0xf9, 0x33, + 0x3a, 0xb0, 0x6e, 0xaf, 0x0c, 0x1b, 0xcf, 0x71, 0x37, 0x6b, 0x4a, 0x9a, + 0x66, 0x16, 0x90, 0x43, 0x9b, 0x70, 0x0d, 0x8f, 0xd3, 0x04, 0x4b, 0x14, + 0xf2, 0x58, 0x9f, 0x64, 0x33, 0x21, 0xdc, 0x02, 0x8a, 0x5b, 0xd6, 0x80, + 0x9c, 0x22, 0xc8, 0x39, 0x7d, 0x2d, 0x7c, 0x09, 0x4e, 0x6a, 0x8c, 0x8d, + 0x0c, 0xc4, 0xfe, 0x6f, 0x8c, 0x50, 0xf2, 0x75, 0xc0, 0x12, 0x6f, 0xd3, + 0x9d, 0x07, 0xc0, 0xe9, 0xdf, 0x36, 0xa2, 0x6f, 0xca, 0x14, 0x5b, 0x0f, + 0x5a, 0xd8, 0x35, 0x72, 0x07, 0x08, 0x80, 0xba, 0x2f, 0x61, 0x7f, 0xb0, + 0x5e, 0xbb, 0xb1, 0x47, 0x6a, 0xbd, 0x6a, 0xe4, 0xb6, 0xa2, 0xec, 0x2e, + 0x27, 0x43, 0xbc, 0xd7, 0x2c, 0x2c, 0xf3, 0x6c, 0x12, 0x4c, 0x86, 0x5a, + 0x38, 0xa4, 0x87, 0xa8, 0xe1, 0x70, 0x17, 0x15, 0xd0, 0x2b, 0x87, 0xdb, + 0x87, 0xc0, 0x85, 0x57, 0x30, 0x31, 0x16, 0x07, 0x9b, 0x72, 0x07, 0xf5, + 0x18, 0x6d, 0xd1, 0x8d, 0x31, 0xa1, 0x25, 0x6a, 0xb4, 0xf3, 0x07, 0x5f, + 0x0c, 0x99, 0x33, 0x68, 0xbf, 0x2c, 0xa1, 0xfd, 0xde, 0x16, 0x2d, 0x4a, + 0x5a, 0xa0, 0x7e, 0xe5, 0x9b, 0x89, 0x4a, 0x8d, 0xe7, 0x18, 0x21, 0x32, + 0x47, 0x3c, 0x9d, 0x48, 0xab, 0x7d, 0xca, 0xb4, 0x63, 0xd9, 0xfd, 0x29, + 0x2d, 0x4c, 0xf1, 0xf2, 0x20, 0x0a, 0x91, 0x2e, 0x2c, 0xa1, 0x49, 0x83, + 0x73, 0x15, 0xa0, 0x7d, 0x6e, 0xae, 0x51, 0x45, 0x0d, 0x09, 0x1f, 0x8f, + 0x61, 0x42, 0xbd, 0x24, 0xcd, 0x3e, 0xe8, 0x66, 0x84, 0xc6, 0x97, 0x08, + 0x7b, 0x72, 0x73, 0x7e, 0xe7, 0x99, 0x05, 0xab, 0x63, 0xff, 0x3c, 0x44, + 0xa1, 0xc0, 0x1b, 0xfc, 0xff, 0x27, 0xe9, 0x45, 0x82, 0x75, 0x82, 0x6f, + 0x9c, 0x65, 0xef, 0x67, 0xd6, 0x00, 0xd1, 0x9f, 0x61, 0x9f, 0x38, 0xdd, + 0x7f, 0x5f, 0x4d, 0x67, 0x5b, 0x5d, 0xff, 0x98, 0x6b, 0x13, 0xe0, 0xe7, + 0x69, 0xcb, 0x7f, 0x7c, 0x11, 0x91, 0xe0, 0x05, 0xb9, 0x64, 0xd0, 0xb7, + 0x91, 0xe5, 0xd4, 0x3a, 0x47, 0x05, 0x25, 0x4f, 0x15, 0x46, 0xaf, 0x41, + 0x9e, 0xc7, 0x49, 0x15, 0x17, 0xd1, 0x9c, 0x28, 0xef, 0x80, 0xa3, 0x8b, + 0x60, 0xcc, 0x60, 0xeb, 0x96, 0x36, 0x3a, 0x23, 0x94, 0xf3, 0x6c, 0xe5, + 0x3f, 0xe8, 0x8b, 0x5c, 0x8c, 0xfe, 0x6f, 0x91, 0x65, 0x19, 0xa1, 0x4d, + 0x45, 0x7b, 0x06, 0x0f, 0x71, 0xb7, 0x9a, 0x8d, 0x8e, 0x82, 0x7b, 0x68, + 0x44, 0xa4, 0xa6, 0xc3, 0xe5, 0x67, 0x9f, 0x6c, 0xd0, 0xe4, 0xe8, 0x37, + 0x08, 0x6b, 0xbb, 0xa0, 0x3a, 0xd0, 0xa9, 0xd9, 0x04, 0xaa, 0x91, 0xac, + 0x71, 0xff, 0xec, 0x7e, 0xaf, 0xa9, 0x99, 0xa2, 0x8d, 0x91, 0x95, 0xb3, + 0xd8, 0xe4, 0xf3, 0x3f, 0xa6, 0x4b, 0x0c, 0x19, 0x23, 0xf7, 0xa7, 0xcd, + 0x4c, 0x41, 0x28, 0x63, 0x9f, 0x0b, 0x8f, 0x70, 0x70, 0xbd, 0x25, 0x16, + 0x8e, 0x86, 0x8a, 0x69, 0xe3, 0x6a, 0xd4, 0x98, 0x42, 0x56, 0x15, 0x2d, + 0x3d, 0xdb, 0x17, 0x1b, 0x23, 0x58, 0x82, 0x56, 0x11, 0x97, 0x85, 0xf2, + 0x68, 0x95, 0x92, 0xd5, 0x9e, 0x91, 0x05, 0x70, 0xc8, 0x96, 0xb2, 0x73, + 0x6d, 0x1e, 0x12, 0x8c, 0xa0, 0xe4, 0x1a, 0x84, 0x5b, 0xb4, 0x32, 0xf7, + 0x9e, 0x08, 0xd0, 0x6c, 0x42, 0xf0, 0x0b, 0xc4, 0x1f, 0xe0, 0xbb, 0x71, + 0xe1, 0x2d, 0x86, 0xd7, 0x77, 0x24, 0x43, 0x53, 0x0c, 0x88, 0x21, 0x75, + 0x95, 0xd0, 0xfe, 0x10, 0x23, 0xcd, 0xba, 0x77, 0x3d, 0x9b, 0x0f, 0xb2, + 0xe2, 0xcc, 0x0f, 0x94, 0xe0, 0x66, 0x90, 0x0e, 0xf7, 0x6a, 0x3c, 0x9f, + 0xc0, 0xf6, 0x98, 0x1c, 0x4c, 0x9f, 0x25, 0xc4, 0xeb, 0x1d, 0x91, 0x32, + 0x29, 0x34, 0x2a, 0xb0, 0x7e, 0x1c, 0x09, 0x77, 0x13, 0x83, 0xfa, 0xcf, + 0x24, 0xa2, 0x5f, 0x79, 0x78, 0x64, 0xf7, 0x45, 0x81, 0xbe, 0x6a, 0x82, + 0x26, 0xfd, 0xe7, 0xc3, 0x61, 0x41, 0x27, 0xcc, 0x99, 0x69, 0x77, 0xc8, + 0xa7, 0xf3, 0x52, 0x01, 0xa7, 0x8c, 0x0b, 0x7d, 0x86, 0x8d, 0xbb, 0x31, + 0xd6, 0x67, 0xf9, 0xa7, 0x8f, 0x76, 0xb6, 0x74, 0x26, 0x43, 0x35, 0xb8, + 0x83, 0x7c, 0x16, 0x34, 0x88, 0x0c, 0xb6, 0xec, 0xf0, 0x01, 0x8c, 0x1c, + 0xe5, 0x52, 0xd4, 0xca, 0x01, 0x2e, 0xb5, 0x87, 0xc1, 0xc1, 0x1b, 0xa3, + 0x02, 0x17, 0x13, 0xd3, 0x35, 0xe8, 0x80, 0xe1, 0xd1, 0x01, 0x9c, 0x0a, + 0x62, 0x7d, 0x98, 0x7c, 0x68, 0xa4, 0x8e, 0x3a, 0x50, 0x4b, 0x95, 0x59, + 0xa3, 0x11, 0xf6, 0xa3, 0xde, 0x92, 0x65, 0x00, 0xa0, 0xe8, 0x32, 0xf0, + 0xc3, 0x77, 0x68, 0x0b, 0xed, 0xc1, 0x69, 0xd2, 0x6e, 0xce, 0x80, 0xe4, + 0x56, 0x9b, 0x15, 0xbf, 0x3c, 0x4a, 0x38, 0x26, 0xf6, 0x6a, 0xdb, 0x62, + 0x7a, 0xab, 0xb1, 0x77, 0x75, 0x0d, 0xa7, 0xa4, 0xcf, 0x5e, 0x2d, 0xea, + 0x24, 0x84, 0xbd, 0x83, 0x8e, 0xaa, 0x91, 0xe1, 0x72, 0x5f, 0x7f, 0x26, + 0x54, 0x4f, 0xab, 0xa6, 0x50, 0x22, 0x68, 0x8c, 0xa6, 0x06, 0x67, 0x3c, + 0x3e, 0x93, 0x9a, 0xc2, 0x53, 0x15, 0x08, 0x1a, 0x3c, 0xb3, 0x3f, 0xf0, + 0x83, 0xf5, 0x0d, 0x9c, 0xe3, 0x76, 0x11, 0x45, 0x21, 0x6b, 0x65, 0x97, + 0xea, 0x3c, 0xdb, 0x0d, 0xcd, 0x6e, 0xb7, 0x26, 0x7b, 0x82, 0x63, 0x35, + 0x7e, 0x76, 0xf4, 0xb8, 0x0e, 0xe5, 0x1d, 0x95, 0x94, 0x1c, 0x60, 0xc7, + 0xea, 0x9c, 0x1c, 0x73, 0x75, 0x0e, 0x9b, 0x5f, 0x78, 0x09, 0x4f, 0x90, + 0x31, 0x5c, 0xc8, 0x5b, 0x78, 0xce, 0xb3, 0x3e, 0x31, 0x61, 0x90, 0xba, + 0xe0, 0xe1, 0x57, 0x1d, 0x71, 0x80, 0x92, 0x6b, 0x75, 0xe1, 0x34, 0x95, + 0xeb, 0x88, 0xe4, 0x0b, 0x72, 0xdc, 0x34, 0x24, 0x3b, 0x6d, 0x94, 0xc9, + 0xe9, 0x8d, 0x38, 0x72, 0x9c, 0x61, 0x6e, 0x07, 0xd7, 0x35, 0xa1, 0x74, + 0xc2, 0x0c, 0x36, 0xc3, 0x54, 0xd3, 0xe5, 0xd1, 0x08, 0x8e, 0x24, 0x77, + 0xf5, 0x61, 0xcf, 0x69, 0x9b, 0x27, 0x70, 0xe7, 0x52, 0xf6, 0xef, 0x66, + 0x8f, 0x0e, 0x8b, 0xc0, 0xf3, 0x64, 0x2a, 0xa8, 0xff, 0xcc, 0xd9, 0x61, + 0x53, 0xac, 0x36, 0x23, 0x4f, 0x3c, 0x0f, 0xe0, 0xec, 0xad, 0xc5, 0x35, + 0x3f, 0x3b, 0x74, 0x26, 0x84, 0x48, 0xd1, 0xfe, 0x72, 0x01, 0xea, 0x4d, + 0x03, 0x46, 0x66, 0x5a, 0xc4, 0x0a, 0x55, 0x43, 0x61, 0x36, 0x6a, 0xc1, + 0xd2, 0x74, 0x0a, 0x8f, 0x01, 0xb2, 0xc2, 0xaa, 0xd7, 0x2d, 0x0a, 0x0f, + 0x67, 0xa1, 0x25, 0x7d, 0x45, 0x60, 0x0f, 0x06, 0xfb, 0x8f, 0x8b, 0xe0, + 0x4a, 0x8c, 0xd7, 0x19, 0xac, 0xcc, 0x47, 0xa2, 0x7c, 0x30, 0x90, 0x94, + 0x81, 0xab, 0xde, 0x38, 0xb8, 0xc9, 0xdb, 0x63, 0x9c, 0xcb, 0xdd, 0x71, + 0xde, 0x4f, 0x1e, 0x43, 0x08, 0xe4, 0xe3, 0x83, 0x86, 0x0f, 0x34, 0xb7, + 0x1e, 0x53, 0xc1, 0xde, 0x46, 0xf1, 0x70, 0xf5, 0xd8, 0x47, 0xd2, 0x9b, + 0x44, 0x88, 0x85, 0x8e, 0x32, 0xa9, 0x0c, 0x09, 0x2f, 0xd0, 0xe4, 0x4b, + 0x30, 0x3a, 0x2e, 0x65, 0x0c, 0xff, 0xb4, 0x0d, 0xa8, 0x8f, 0x61, 0x3e, + 0x7e, 0x90, 0x66, 0xbb, 0xf6, 0xbe, 0xfd, 0x7d, 0xe4, 0xdc, 0x2c, 0x59, + 0x87, 0x81, 0x60, 0x96, 0xd7, 0x1d, 0x10, 0x02, 0x35, 0xdd, 0x16, 0x4c, + 0xe9, 0x2d, 0x52, 0x45, 0xdd, 0x3f, 0xc9, 0xff, 0x8d, 0x19, 0xad, 0x02, + 0x74, 0xf1, 0x09, 0x99, 0x94, 0x66, 0x2e, 0x8b, 0xa3, 0xdc, 0x3d, 0xf3, + 0xf5, 0x85, 0xf2, 0x60, 0x7d, 0x9d, 0xe0, 0xd3, 0x0f, 0xa4, 0x92, 0xf3, + 0x55, 0xbc, 0x7b, 0x20, 0x6b, 0xf6, 0xc4, 0xc4, 0x0f, 0x8a, 0xd7, 0x5a, + 0x02, 0xb0, 0xb7, 0x78, 0xb4, 0x9e, 0xb6, 0x93, 0x95, 0x2e, 0x76, 0x06, + 0x1e, 0x34, 0x5d, 0x34, 0x77, 0x77, 0x6d, 0x32, 0xbb, 0x46, 0xad, 0x43, + 0xd7, 0x72, 0x61, 0x33, 0x4f, 0x98, 0xe9, 0x56, 0x3a, 0x96, 0x89, 0x6e, + 0x1f, 0xaf, 0x6b, 0xa0, 0x9a, 0xe4, 0x42, 0x5a, 0xb3, 0xb8, 0x2a, 0xe1, + 0x2d, 0xa6, 0x32, 0xa2, 0x01, 0xf5, 0x3a, 0x9a, 0xbb, 0x06, 0x76, 0x0b, + 0xa8, 0xac, 0x02, 0x96, 0x0c, 0x58, 0xd3, 0x64, 0xc8, 0xe2, 0xae, 0x6c, + 0xf7, 0xa7, 0x32, 0x4b, 0x51, 0x50, 0x11, 0x90, 0xcf, 0x37, 0xed, 0xd2, + 0xa0, 0xa4, 0x97, 0xb3, 0x45, 0x1d, 0x7d, 0xf3, 0xff, 0xde, 0x9f, 0x80, + 0xa9, 0x61, 0xac, 0x37, 0x7f, 0x5d, 0xc9, 0xf6, 0xdc, 0x26, 0xd0, 0x65, + 0xf2, 0xdc, 0x0c, 0x1a, 0xcb, 0xde, 0x6b, 0x77, 0xf3, 0x08, 0xa4, 0x93, + 0xab, 0x2a, 0xdf, 0x18, 0x1a, 0xc7, 0xa6, 0xa1, 0x7e, 0x43, 0x75, 0xca, + 0x88, 0xcc, 0x6f, 0xa2, 0x85, 0x0e, 0xb0, 0xd5, 0xcd, 0x8a, 0xff, 0xc1, + 0x57, 0x20, 0x66, 0xf7, 0x19, 0x7a, 0x52, 0x5b, 0x46, 0x87, 0x5f, 0xf7, + 0x77, 0xe2, 0xab, 0x4e, 0x4a, 0xce, 0x8f, 0x3f, 0xe6, 0x9f, 0x88, 0x3a, + 0x33, 0x65, 0x3c, 0x3a, 0x41, 0xc3, 0x8e, 0xee, 0x79, 0xe7, 0x2c, 0xb0, + 0x3b, 0x93, 0x82, 0xa0, 0x1a, 0x71, 0x0e, 0xf6, 0x31, 0xc5, 0x6f, 0xc1, + 0xa8, 0x32, 0x89, 0x3b, 0x33, 0x68, 0x53, 0x81, 0x15, 0x70, 0x5e, 0x22, + 0xdc, 0x99, 0xc6, 0x88, 0xf8, 0x11, 0x06, 0x56, 0x1f, 0x80, 0x7e, 0x0b, + 0x27, 0x90, 0xfc, 0x97, 0x76, 0x61, 0xdc, 0x30, 0x5d, 0x34, 0x4e, 0x83, + 0x85, 0xce, 0xe2, 0x91, 0x4d, 0x8d, 0x92, 0x88, 0x26, 0xa0, 0xde, 0x47, + 0x82, 0xd2, 0xa8, 0xa5, 0xe7, 0x27, 0x0c, 0x45, 0x41, 0x85, 0xa1, 0x12, + 0xcb, 0x3a, 0x74, 0x53, 0x93, 0x77, 0xd0, 0x8b, 0x42, 0x8d, 0x00, 0xca, + 0x44, 0x67, 0xa0, 0x6a, 0xbd, 0xcd, 0x4a, 0x3c, 0xfe, 0x6c, 0xa1, 0x48, + 0x26, 0x0d, 0x51, 0x54, 0x59, 0xc9, 0xf9, 0x51, 0x5c, 0xd3, 0x55, 0xf0, + 0x72, 0x77, 0xdb, 0x52, 0xee, 0x0a, 0x5e, 0x8a, 0xf0, 0xbe, 0x9a, 0x37, + 0xa0, 0x1b, 0x94, 0xe3, 0x2d, 0x17, 0xc4, 0xbe, 0x9c, 0xad, 0x9c, 0xd1, + 0xc6, 0xbc, 0x36, 0x5c, 0x3b, 0xe3, 0x2e, 0x66, 0x29, 0x0c, 0x3a, 0x3d, + 0xe7, 0xe3, 0xf3, 0x58, 0x70, 0x3e, 0x59, 0xb2, 0x6c, 0x91, 0x14, 0xfe, + 0x9e, 0x5e, 0x5d, 0xb2, 0x7b, 0x46, 0x66, 0x46, 0x55, 0xe2, 0x78, 0x47, + 0xeb, 0xdf, 0x2b, 0xb4, 0xf2, 0xb2, 0x14, 0xbe, 0x64, 0x9e, 0x17, 0x16, + 0x9f, 0xf5, 0x6a, 0xdd, 0x25, 0xa1, 0x55, 0x6e, 0xb1, 0xfa, 0x09, 0xd0, + 0x97, 0x7c, 0x13, 0xde, 0x1d, 0xd4, 0x94, 0x19, 0xde, 0x8b, 0x4d, 0xe7, + 0xee, 0x1f, 0xdf, 0xe5, 0x3b, 0xdd, 0xbd, 0x13, 0x9c, 0xec, 0xcd, 0xb6, + 0xb6, 0xbb, 0x3f, 0xbd, 0x54, 0xca, 0x47, 0x5c, 0x05, 0x3c, 0x03, 0x30, + 0x9d, 0x56, 0xf6, 0xc6, 0x48, 0x6b, 0x74, 0x49, 0x58, 0xa2, 0xd8, 0x45, + 0x42, 0x6f, 0xe4, 0x46, 0x27, 0x92, 0x83, 0x78, 0x97, 0x55, 0x5b, 0x82, + 0xce, 0x2a, 0x08, 0x41, 0xb9, 0x7a, 0x66, 0x0f, 0x3c, 0x5b, 0xdf, 0x8d, + 0x1d, 0x02, 0x11, 0xa4, 0xa7, 0x0a, 0x80, 0x1e, 0xbb, 0x7a, 0xc9, 0x2f, + 0xb9, 0x35, 0xc8, 0xd7, 0x98, 0x04, 0x29, 0xaa, 0x4b, 0x88, 0x66, 0x73, + 0xe4, 0x59, 0xc4, 0x3e, 0x50, 0xad, 0xe5, 0x64, 0x54, 0xf0, 0x29, 0x38, + 0xee, 0xc0, 0x00, 0xc4, 0x22, 0x16, 0xf2, 0xc5, 0x46, 0x5c, 0xee, 0x9e, + 0xf2, 0x9a, 0xe7, 0xfd, 0x62, 0x50, 0xa2, 0xeb, 0x47, 0x56, 0x4c, 0xe4, + 0x75, 0x46, 0xe4, 0xd5, 0x25, 0xec, 0xe0, 0x35, 0x33, 0x31, 0x34, 0x1b, + 0xcb, 0x72, 0x78, 0x1c, 0x4d, 0x3a, 0x19, 0x2e, 0xc4, 0xb7, 0xa4, 0x80, + 0xd2, 0x91, 0xeb, 0x2a, 0x1d, 0xf2, 0xd1, 0xa3, 0xae, 0xac, 0x41, 0xae, + 0xc2, 0x44, 0xd2, 0x3f, 0xb4, 0x87, 0x8d, 0x69, 0x6c, 0x67, 0xd6, 0x85, + 0xee, 0xd6, 0x3b, 0x03, 0xdc, 0x58, 0x46, 0x07, 0x73, 0xb4, 0xb0, 0x3f, + 0x5e, 0xc1, 0x13, 0x2c, 0x36, 0x58, 0xd0, 0x1c, 0x34, 0x3e, 0x01, 0x88, + 0xfa, 0xb1, 0x9a, 0x03, 0x85, 0x4f, 0x4c, 0xd2, 0xac, 0xd9, 0x12, 0x09, + 0xaa, 0x5f, 0x20, 0x06, 0x1f, 0x0a, 0x44, 0x28, 0x50, 0xd1, 0x8f, 0x51, + 0x8a, 0x1d, 0xfa, 0xaa, 0x46, 0x33, 0xac, 0x0c, 0xb3, 0x10, 0xcf, 0x24, + 0x4d, 0x0f, 0xcd, 0xee, 0xd9, 0x64, 0x4a, 0x1a, 0x84, 0x0f, 0xff, 0x48, + 0x8d, 0x79, 0xd4, 0x43, 0x70, 0x1c, 0x7e, 0x7e, 0x12, 0x43, 0x51, 0x4a, + 0x7e, 0x45, 0x9e, 0xa4, 0x3c, 0x12, 0xbd, 0x95, 0xe9, 0xd6, 0xd4, 0x3f, + 0xbf, 0x03, 0xae, 0x9e, 0x24, 0x1a, 0x36, 0xbd, 0xea, 0x5d, 0x65, 0xff, + 0x9f, 0x95, 0x70, 0xda, 0xb0, 0x53, 0x6a, 0x5f, 0x64, 0x7b, 0xb6, 0x7a, + 0x8d, 0xa2, 0xd4, 0x9c, 0xb1, 0xf9, 0xe6, 0x14, 0x62, 0x3b, 0xe7, 0x5b, + 0x40, 0x9d, 0xf4, 0x19, 0xb5, 0x50, 0xc8, 0xbd, 0x76, 0xd3, 0xbc, 0x0e, + 0x6d, 0x62, 0x91, 0x73, 0x3e, 0x7f, 0xbf, 0xd0, 0xf0, 0x33, 0xf8, 0x6a, + 0x9f, 0xa6, 0xad, 0xc3, 0xa0, 0x8f, 0x45, 0x99, 0x86, 0xa7, 0x49, 0x18, + 0x8a, 0xed, 0xf1, 0x7d, 0x39, 0xf4, 0xb4, 0xf9, 0x82, 0x62, 0xd0, 0xa1, + 0xb8, 0x3f, 0xe8, 0x25, 0xf7, 0xb1, 0x59, 0xce, 0x31, 0xba, 0x1d, 0x0b, + 0x1f, 0x3d, 0x6c, 0x8b, 0xd2, 0xc5, 0x4e, 0x8e, 0xe8, 0x09, 0x9e, 0x1f, + 0xf3, 0x67, 0x6f, 0x09, 0x03, 0x9d, 0xfe, 0x57, 0x6d, 0x9b, 0xce, 0x99, + 0x7b, 0x01, 0x04, 0x52, 0xf5, 0x41, 0x7e, 0x38, 0x56, 0xb8, 0x71, 0x44, + 0x43, 0x2c, 0x5e, 0x92, 0x9d, 0x95, 0xff, 0x0b, 0xf8, 0xfa, 0x89, 0x2c, + 0x58, 0xde, 0xc5, 0x4e, 0x02, 0xe3, 0x82, 0xf7, 0xdc, 0x92, 0xa8, 0x7c, + 0x39, 0x32, 0x76, 0x68, 0x9c, 0x73, 0x75, 0x1f, 0xbc, 0x6b, 0x46, 0x33, + 0x5a, 0xdb, 0x94, 0x8c, 0x76, 0x79, 0x7e, 0x9b, 0xcc, 0x37, 0xeb, 0xed, + 0xdc, 0xd5, 0xee, 0x2b, 0x30, 0x3f, 0x7b, 0x9b, 0xac, 0x38, 0x8f, 0xf1, + 0x5e, 0xec, 0xa0, 0x46, 0x2c, 0xd1, 0x27, 0x19, 0x60, 0xec, 0xe2, 0xa7, + 0x45, 0x61, 0x2d, 0xa8, 0x7e, 0xa9, 0xf8, 0x93, 0xa4, 0x23, 0x3e, 0xd8, + 0x9c, 0xcc, 0xb3, 0xee, 0xc3, 0x1c, 0xfb, 0xbb, 0xad, 0xec, 0x73, 0x66, + 0x31, 0x5d, 0x88, 0x9a, 0xec, 0x84, 0x91, 0x1e, 0x58, 0xdd, 0xb0, 0x01, + 0x46, 0x18, 0x43, 0x64, 0xe2, 0xad, 0xac, 0x5a, 0x63, 0x4c, 0x32, 0x6b, + 0xfd, 0xff, 0x66, 0x6d, 0xb4, 0x66, 0x88, 0xec, 0xfe, 0x23, 0xaa, 0x3a, + 0x2a, 0xd5, 0xff, 0xed, 0x3a, 0x13, 0x9a, 0xae, 0x73, 0xc5, 0x62, 0x32, + 0x47, 0x89, 0x19, 0x7f, 0x2c, 0x88, 0x62, 0x34, 0xc2, 0x90, 0xa9, 0x59, + 0x7c, 0x45, 0xdb, 0x98, 0xaf, 0xf4, 0xba, 0x4e, 0x45, 0x55, 0xfc, 0x70, + 0xa9, 0xfd, 0xb4, 0xa3, 0xd9, 0xa8, 0xfb, 0xe2, 0xe6, 0xf9, 0x60, 0xc1, + 0x42, 0x70, 0x3d, 0xa5, 0x28, 0xcc, 0xd3, 0x54, 0x87, 0xda, 0x93, 0x91, + 0x42, 0xa8, 0x8b, 0x62, 0xf3, 0x4e, 0xb7, 0x86, 0xfa, 0x52, 0x19, 0x69, + 0xe3, 0x6c, 0xd1, 0xc3, 0x23, 0x82, 0xf7, 0x1d, 0xa1, 0x80, 0x92, 0xcd, + 0x5e, 0x1a, 0x62, 0x3e, 0x1b, 0x31, 0x9d, 0x0d, 0xa8, 0x25, 0x3e, 0x83, + 0xae, 0x36, 0xce, 0xfd, 0xac, 0xf7, 0x35, 0x7f, 0x74, 0xf4, 0x66, 0xa3, + 0x5f, 0x00, 0xe5, 0x30, 0xc1, 0x11, 0x70, 0x00, 0xb5, 0xd9, 0xd4, 0x6e, + 0x95, 0xc4, 0xbc, 0x5b, 0x7d, 0x62, 0x6c, 0xd5, 0xc0, 0x1e, 0x81, 0xc0, + 0x61, 0x69, 0x13, 0x63, 0xbc, 0x7f, 0x70, 0x3f, 0x3d, 0x96, 0x18, 0x39, + 0xef, 0x51, 0xc6, 0xe9, 0xcc, 0x59, 0xda, 0xc7, 0x5d, 0xb5, 0x59, 0xb0, + 0xf2, 0x99, 0x5a, 0x36, 0x21, 0x0d, 0xcc, 0x97, 0x16, 0x2b, 0x61, 0x3d, + 0x0a, 0xd1, 0x6e, 0x05, 0x86, 0x42, 0xff, 0xd8, 0xa7, 0x5c, 0x02, 0xcf, + 0x90, 0x6b, 0x4e, 0xee, 0x4e, 0xca, 0xdb, 0xd3, 0xfe, 0x7e, 0x9b, 0xe2, + 0xf0, 0xa3, 0x45, 0x6d, 0xa9, 0x92, 0xba, 0xce, 0xc6, 0x2e, 0x0a, 0xbc, + 0xb2, 0x7a, 0x57, 0x07, 0x33, 0xc2, 0xa7, 0x16, 0x25, 0x06, 0x36, 0x83, + 0x35, 0x31, 0x87, 0x18, 0x83, 0xa3, 0xc2, 0x88, 0x55, 0xcc, 0xe4, 0x84, + 0x4c, 0xce, 0xb9, 0xeb, 0xd5, 0xb2, 0xbe, 0x3d, 0x76, 0x85, 0x10, 0x07, + 0x83, 0xfa, 0x1c, 0x42, 0xbc, 0xa3, 0x4c, 0x29, 0x49, 0xe6, 0xc0, 0x30, + 0x59, 0xe0, 0xc6, 0xbe, 0xa7, 0x48, 0x4a, 0xcf, 0x0e, 0x8e, 0xb7, 0x38, + 0xf2, 0xa6, 0x26, 0xd3, 0x88, 0x06, 0x99, 0x46, 0x19, 0x65, 0x1c, 0x91, + 0x8e, 0xae, 0x90, 0x78, 0x77, 0x7f, 0xe0, 0xc2, 0x51, 0x6f, 0xb6, 0x44, + 0x15, 0xf9, 0xc5, 0x8a, 0x6c, 0x33, 0xd5, 0x90, 0x17, 0xc2, 0xca, 0x4e, + 0xe1, 0x1f, 0xef, 0x02, 0x43, 0x05, 0x3f, 0x1e, 0xb1, 0x13, 0x23, 0x1f, + 0xd6, 0xc2, 0xac, 0xc4, 0x49, 0x7a, 0x86, 0x06, 0x4b, 0xa1, 0x55, 0x6a, + 0x75, 0x91, 0x4e, 0x6b, 0x86, 0x95, 0xa7, 0xbc, 0xdc, 0x64, 0xdb, 0x81, + 0xc6, 0xa5, 0x33, 0x38, 0x98, 0xbb, 0xac, 0x03, 0xf0, 0xba, 0x49, 0xcf, + 0x1c, 0xce, 0xe2, 0x3d, 0xe5, 0x06, 0xbc, 0x5e, 0xd0, 0xf7, 0x1c, 0xbb, + 0x52, 0xa1, 0x47, 0x98, 0x12, 0xef, 0x1c, 0xb9, 0x53, 0xec, 0x67, 0x2c, + 0xf0, 0x7d, 0x85, 0x9e, 0x45, 0x87, 0x00, 0x67, 0x2f, 0xa5, 0x19, 0x9f, + 0x3e, 0x20, 0x8c, 0xe9, 0xfa, 0x8a, 0xd8, 0x02, 0x6e, 0x16, 0xc4, 0x43, + 0xff, 0x08, 0x3f, 0xf3, 0x76, 0x53, 0x95, 0x17, 0x6e, 0x74, 0xfe, 0x7e, + 0x87, 0x66, 0xc9, 0xe8, 0x8d, 0x21, 0xea, 0xd2, 0x4d, 0xc7, 0x9c, 0x5a, + 0xef, 0xd5, 0xe1, 0x12, 0x85, 0x22, 0x40, 0x3c, 0x9d, 0x89, 0x4f, 0x12, + 0xb5, 0x01, 0x95, 0x0e, 0x9b, 0xd3, 0x38, 0x5e, 0x21, 0x5a, 0x4e, 0x7e, + 0xce, 0xf7, 0xa6, 0x5a, 0x63, 0x78, 0x40, 0xba, 0x9f, 0x29, 0xf0, 0x75, + 0xb6, 0x8b, 0xd9, 0x4c, 0xab, 0xb9, 0xf4, 0xe9, 0x1f, 0x39, 0x01, 0xb3, + 0xfc, 0x2c, 0xa4, 0x74, 0xa9, 0xa9, 0x90, 0xed, 0x77, 0xd8, 0x0c, 0x6d, + 0x5c, 0x7b, 0xfc, 0xbd, 0x96, 0x96, 0xcb, 0x9b, 0x9f, 0x88, 0x86, 0x5c, + 0x3c, 0x0a, 0xde, 0x28, 0x7c, 0xf0, 0x91, 0x1c, 0x06, 0x52, 0xbe, 0xad, + 0xc8, 0xef, 0xa5, 0xd3, 0x1e, 0x29, 0xbd, 0x1d, 0xd5, 0xba, 0xf4, 0x83, + 0x2d, 0x36, 0x9a, 0x8c, 0x8d, 0x83, 0xac, 0x3f, 0xea, 0xd2, 0x2e, 0xfb, + 0xf1, 0xaa, 0x7a, 0x2e, 0xce, 0xd3, 0x90, 0x9f, 0x3c, 0x2c, 0xee, 0xed, + 0xf8, 0xfc, 0x3c, 0x0e, 0x5f, 0xd1, 0xda, 0x9c, 0x32, 0x52, 0xcd, 0x09, + 0xa1, 0x53, 0x33, 0x37, 0xe0, 0x37, 0x95, 0xb2, 0x8d, 0x03, 0x46, 0x1f, + 0xb5, 0x99, 0x65, 0x54, 0x61, 0xa2, 0xdc, 0xe9, 0x87, 0x4d, 0x41, 0xdf, + 0xd1, 0xb5, 0x2c, 0x7a, 0x46, 0x08, 0x5e, 0x0f, 0xcc, 0x80, 0x96, 0x52, + 0x98, 0xa0, 0x82, 0x52, 0x6d, 0x62, 0x6f, 0xd9, 0x48, 0xc1, 0x36, 0x0c, + 0x5c, 0x7f, 0xad, 0x2c, 0x27, 0xcf, 0x17, 0xee, 0xfa, 0xca, 0x14, 0xe7, + 0x88, 0xc4, 0x20, 0xb2, 0xa1, 0xd2, 0x66, 0xe8, 0x81, 0xce, 0x35, 0x2b, + 0x30, 0x54, 0x16, 0x9e, 0x42, 0x77, 0x16, 0x3b, 0x84, 0x77, 0x42, 0x71, + 0x33, 0xf8, 0x62, 0x9e, 0xd4, 0x1d, 0x1d, 0xf3, 0x91, 0x60, 0x97, 0xd8, + 0x10, 0x29, 0xc8, 0xf9, 0xfa, 0xca, 0x0a, 0xe9, 0x50, 0xe1, 0xcc, 0xa7, + 0xe3, 0x77, 0xc2, 0x93, 0x68, 0x50, 0x1a, 0x98, 0xd7, 0x68, 0x40, 0x80, + 0x12, 0x64, 0xa7, 0x1d, 0xb4, 0x52, 0x85, 0x7b, 0x0e, 0x85, 0x0a, 0x59, + 0x6a, 0xc8, 0xe4, 0x4b, 0xff, 0xd7, 0x0d, 0x7d, 0x9e, 0xef, 0x07, 0x2f, + 0x6d, 0x46, 0x05, 0xf9, 0x05, 0xb1, 0x97, 0x94, 0x23, 0xc5, 0x2a, 0x99, + 0xcc, 0x9c, 0xc2, 0x82, 0x97, 0xbc, 0x24, 0x9b, 0xe4, 0xf2, 0xb3, 0x12, + 0x84, 0xa0, 0x2a, 0xc4, 0x7d, 0x29, 0x4d, 0xa4, 0x97, 0xd0, 0x85, 0xa6, + 0x39, 0x18, 0xd2, 0xfb, 0xa7, 0x08, 0x53, 0x75, 0x6b, 0xbd, 0xe3, 0x98, + 0x4c, 0x94, 0xdd, 0xd4, 0x86, 0x94, 0xc2, 0x6a, 0x14, 0x23, 0xdd, 0x69, + 0xae, 0x53, 0xec, 0x83, 0x58, 0x8e, 0x87, 0x7b, 0xf1, 0xcf, 0xff, 0x34, + 0xda, 0x39, 0x67, 0xba, 0x90, 0xc5, 0xec, 0xe0, 0xb3, 0xad, 0xad, 0x3d, + 0x4c, 0x8e, 0x3f, 0x08, 0x62, 0x80, 0x5b, 0x2d, 0xf8, 0xe1, 0x67, 0x61, + 0x79, 0xf5, 0xc9, 0xbe, 0x74, 0x1b, 0x72, 0x02, 0x56, 0xc6, 0xf8, 0xd5, + 0x87, 0x3a, 0x08, 0x7b, 0x35, 0x8f, 0xdf, 0xdf, 0x87, 0x3e, 0x09, 0xf7, + 0xd2, 0x74, 0xbb, 0xec, 0x8c, 0x49, 0x0c, 0xb5, 0x3a, 0x6b, 0x33, 0x43, + 0x52, 0xe2, 0x2f, 0x71, 0x3e, 0x6f, 0x59, 0x52, 0x50, 0x8f, 0xdb, 0xa6, + 0x52, 0xa7, 0x5d, 0xda, 0x16, 0x71, 0xb2, 0x52, 0xd7, 0x3e, 0x2d, 0xf6, + 0x98, 0x53, 0x0f, 0x8f, 0xc1, 0x79, 0xd0, 0xcf, 0xe0, 0xc8, 0x22, 0x27, + 0x41, 0x14, 0xe8, 0xb8, 0xed, 0x65, 0x3c, 0xaa, 0x11, 0x72, 0x41, 0xa8, + 0xd8, 0x0b, 0x35, 0x81, 0xec, 0xa6, 0x12, 0x30, 0x23, 0x0b, 0x71, 0x7a, + 0x28, 0xd9, 0x01, 0x82, 0x35, 0xd1, 0x64, 0x6d, 0xf3, 0x63, 0x69, 0x78, + 0xb4, 0x93, 0x1e, 0x05, 0xc9, 0xb3, 0xbc, 0xb6, 0xc4, 0x5e, 0xb6, 0x2a, + 0x6e, 0xec, 0x91, 0x4a, 0x5c, 0xa2, 0x5c, 0xea, 0x2b, 0xe3, 0x33, 0x1a, + 0xb3, 0x70, 0xd5, 0x39, 0x77, 0x3e, 0xa2, 0x96, 0xd5, 0x10, 0x75, 0x8a, + 0x91, 0xc6, 0xbc, 0xb6, 0x86, 0xa6, 0x8f, 0xd3, 0x50, 0x09, 0xa3, 0x9a, + 0x1f, 0xd0, 0xd7, 0xd7, 0x23, 0xa0, 0x32, 0xd0, 0x69, 0x33, 0x2f, 0x18, + 0xf2, 0x6f, 0xe2, 0xbc, 0x2f, 0x7f, 0xf5, 0x46, 0x81, 0x2e, 0xad, 0x14, + 0xc9, 0x57, 0x10, 0xa4, 0x71, 0xa9, 0xa4, 0x05, 0x50, 0xcb, 0x93, 0xc7, + 0x53, 0x84, 0x68, 0xa5, 0x7c, 0x65, 0xc0, 0xe0, 0x37, 0xd6, 0xc3, 0xbb, + 0x36, 0xef, 0x22, 0x9e, 0x09, 0x32, 0xa5, 0xa6, 0x73, 0x61, 0xb6, 0x3c, + 0x5a, 0xbe, 0x2f, 0x63, 0x01, 0x35, 0xfe, 0xd8, 0x98, 0xd5, 0x7e, 0xfd, + 0x68, 0xd8, 0x96, 0x51, 0x6e, 0x3a, 0x17, 0x90, 0x16, 0xeb, 0x03, 0xfa, + 0x0a, 0x83, 0x1a, 0xc9, 0x48, 0x14, 0x31, 0x32, 0x07, 0x7d, 0xa8, 0xa8, + 0x64, 0xd8, 0xba, 0xcf, 0x87, 0xc5, 0x0e, 0xc3, 0x1c, 0x5b, 0xfe, 0x31, + 0x98, 0xea, 0x25, 0x29, 0x9c, 0x77, 0xf2, 0x9f, 0x5e, 0x16, 0x11, 0x6b, + 0x29, 0x08, 0xab, 0xb0, 0x57, 0xd8, 0x3d, 0x85, 0xdc, 0x3b, 0x69, 0xea, + 0xd5, 0xe6, 0x90, 0xfa, 0x95, 0x8d, 0xcc, 0x3c, 0x2d, 0x86, 0x07, 0xc6, + 0x7e, 0x8d, 0xc4, 0x7a, 0x3a, 0xcd, 0x61, 0xa4, 0x1f, 0xd9, 0x6f, 0x07, + 0xa3, 0x45, 0xe8, 0x41, 0xed, 0x51, 0x14, 0xe4, 0x3d, 0x20, 0x3b, 0x11, + 0x9e, 0x93, 0xc3, 0x2e, 0xcd, 0x29, 0x85, 0xf0, 0x61, 0x68, 0x8e, 0x19, + 0xdc, 0x20, 0x0a, 0xbd, 0xc0, 0x15, 0x90, 0x08, 0x96, 0xcf, 0x9b, 0xf3, + 0xb5, 0x7b, 0xe4, 0x9a, 0x97, 0x22, 0x93, 0x40, 0xd4, 0xde, 0x7a, 0x6e, + 0x6b, 0xc4, 0x16, 0x9e, 0x1c, 0x98, 0x9b, 0x83, 0x6e, 0x4d, 0xde, 0x11, + 0x4f, 0x22, 0xed, 0x2d, 0xe1, 0xb3, 0xfa, 0x86, 0xb0, 0xd2, 0x53, 0xd2, + 0x34, 0x8a, 0x58, 0xdc, 0x8c, 0xd9, 0x60, 0xd3, 0x46, 0x0a, 0xde, 0x48, + 0xa3, 0xda, 0x5b, 0x74, 0x3e, 0x4c, 0x51, 0xa6, 0x02, 0x20, 0xc6, 0x0d, + 0xdb, 0x13, 0x42, 0xad, 0xc6, 0x90, 0xb1, 0xe0, 0xb0, 0xac, 0xdc, 0xa7, + 0x48, 0xf8, 0x2d, 0x8f, 0xd7, 0xd9, 0x10, 0xeb, 0xd8, 0xdb, 0xf0, 0x53, + 0x67, 0xa9, 0x03, 0x3e, 0x97, 0xbf, 0xe6, 0xc3, 0xa8, 0x87, 0x3a, 0x91, + 0xb8, 0xcf, 0x88, 0x5b, 0x0d, 0x06, 0xe1, 0xe2, 0x39, 0x74, 0xc8, 0x59, + 0xe0, 0x90, 0x9f, 0xc9, 0x0a, 0x74, 0xa3, 0xb2, 0xae, 0x69, 0x79, 0xfa, + 0x0d, 0xf2, 0xee, 0xde, 0xec, 0x88, 0xbf, 0x09, 0x54, 0xd6, 0xbe, 0xbb, + 0x25, 0x91, 0xe4, 0x66, 0xd2, 0x08, 0x78, 0xda, 0x9d, 0x07, 0xc3, 0x0b, + 0x3f, 0x1a, 0xd9, 0xf4, 0xb2, 0x2d, 0x69, 0x74, 0xb1, 0x78, 0x5f, 0xc1, + 0xaf, 0x7f, 0x6d, 0x17, 0xfc, 0x2c, 0x67, 0x62, 0xce, 0xb4, 0x41, 0x6e, + 0x21, 0x4b, 0x5c, 0x77, 0xa1, 0x1f, 0xfe, 0xe6, 0x28, 0xc8, 0x52, 0xd1, + 0x8e, 0x66, 0x88, 0x65, 0x0c, 0x58, 0xec, 0x1c, 0x71, 0x4c, 0x8a, 0xc0, + 0xef, 0x3e, 0x34, 0xf7, 0x90, 0x67, 0x28, 0x16, 0x20, 0x3a, 0x2c, 0x3f, + 0x51, 0x53, 0x15, 0x1c, 0x6c, 0x75, 0x0e, 0xe1, 0xb4, 0xf3, 0x7f, 0x60, + 0x3a, 0x81, 0x34, 0x82, 0x51, 0x5e, 0x75, 0xb0, 0x5c, 0x37, 0x87, 0x2d, + 0xd5, 0xc5, 0x2c, 0xab, 0x33, 0x8a, 0x60, 0x49, 0x2c, 0xde, 0x90, 0x12, + 0x11, 0x1f, 0x4b, 0x27, 0x15, 0x92, 0xa2, 0xf1, 0x1a, 0xde, 0x35, 0x34, + 0x4d, 0x52, 0xcd, 0xc0, 0x71, 0x46, 0x7f, 0x3e, 0x21, 0x92, 0x5f, 0xc8, + 0x25, 0xd4, 0x2c, 0xf4, 0xd9, 0x38, 0xde, 0xa5, 0xae, 0x83, 0xe3, 0x50, + 0x9b, 0x1b, 0xad, 0x4b, 0xd8, 0x3f, 0x0a, 0x23, 0x40, 0x1e, 0x46, 0x7a, + 0x71, 0x06, 0xac, 0x9e, 0x06, 0xb8, 0x96, 0xef, 0x07, 0xef, 0x38, 0xe9, + 0x79, 0xaa, 0x64, 0x44, 0xa9, 0xa3, 0xc5, 0x1d, 0x5d, 0xd3, 0xa7, 0x01, + 0xef, 0xf6, 0x3b, 0x15, 0x00, 0x0c, 0xf7, 0x59, 0x4a, 0x1c, 0x12, 0x20, + 0x89, 0xa8, 0x4e, 0x7b, 0xf8, 0x9d, 0x02, 0xa6, 0x5e, 0x19, 0x7e, 0xb8, + 0x5f, 0x46, 0xd9, 0xb1, 0xbe, 0x25, 0x2c, 0x3c, 0xe7, 0x5d, 0x3b, 0x3f, + 0x6f, 0x6e, 0x94, 0x83, 0xc3, 0x8e, 0x85, 0x65, 0xff, 0xe9, 0x8e, 0x32, + 0xcc, 0x68, 0x51, 0x14, 0xbf, 0x94, 0x21, 0x3f, 0x85, 0xa8, 0x76, 0x44, + 0xe6, 0xca, 0x20, 0x84, 0xec, 0x83, 0x84, 0x64, 0xfb, 0x80, 0x01, 0x73, + 0x76, 0x21, 0xd3, 0xf0, 0x7b, 0x74, 0x5c, 0xbf, 0x71, 0xe6, 0x34, 0xff, + 0x58, 0xe8, 0x6f, 0x88, 0xa6, 0xad, 0xcf, 0x93, 0x2a, 0xc5, 0xc5, 0x23, + 0x32, 0xc8, 0xec, 0xbd, 0xf9, 0x54, 0x3d, 0xda, 0xe4, 0x81, 0x74, 0x94, + 0xbf, 0x36, 0x72, 0x11, 0xf0, 0x8a, 0x8f, 0x1b, 0x55, 0x47, 0x70, 0x7d, + 0x61, 0xf0, 0x7b, 0x11, 0x56, 0xdb, 0xbc, 0xe5, 0x72, 0xf2, 0xbd, 0x0b, + 0xa0, 0x80, 0x03, 0x1a, 0xc6, 0xe9, 0xfc, 0xcd, 0xde, 0x42, 0xae, 0x1a, + 0x7d, 0x90, 0x5d, 0x21, 0x5b, 0x3d, 0x69, 0x6f, 0x42, 0x42, 0xf2, 0x8a, + 0xc8, 0xfc, 0xb9, 0xa9, 0xdf, 0x18, 0xc4, 0x97, 0x91, 0x21, 0x28, 0xfd, + 0x82, 0x8a, 0xe7, 0xac, 0xe5, 0x5d, 0x33, 0x7b, 0x78, 0x0a, 0x48, 0x43, + 0xfe, 0xfe, 0xcf, 0x09, 0x5f, 0xed, 0x18, 0x33, 0x0c, 0xab, 0x8a, 0x5d, + 0x63, 0xd5, 0x43, 0x0b, 0xde, 0x75, 0x56, 0xef, 0x11, 0x05, 0x8c, 0xbb, + 0xc0, 0x10, 0x4e, 0x85, 0x70, 0xe1, 0x7e, 0x62, 0xb6, 0x3a, 0x84, 0x80, + 0x17, 0xab, 0x38, 0x59, 0x0b, 0xe2, 0xb1, 0x31, 0xb8, 0xb5, 0xf5, 0xad, + 0xf6, 0xbf, 0x5b, 0xfb, 0x69, 0xc8, 0xb3, 0xce, 0x65, 0xd4, 0x8e, 0x04, + 0xc5, 0xc4, 0x09, 0xba, 0x36, 0xc9, 0x90, 0xe0, 0xc2, 0x21, 0x3a, 0x94, + 0x83, 0xa5, 0xd1, 0xb2, 0xe1, 0xae, 0x6a, 0x28, 0x22, 0x59, 0x79, 0x72, + 0x82, 0x42, 0x89, 0x42, 0x9c, 0xc3, 0xdf, 0x8d, 0x15, 0x22, 0x14, 0xb3, + 0xfd, 0x2a, 0x85, 0xbe, 0xd3, 0x12, 0xa5, 0x3b, 0x0c, 0x99, 0xb2, 0xe5, + 0x43, 0x8d, 0xd7, 0xc0, 0xa1, 0xb6, 0xb2, 0xae, 0x42, 0x4a, 0xc0, 0xe5, + 0x09, 0xa2, 0xf6, 0xa4, 0xbc, 0x01, 0xee, 0x94, 0xd2, 0x0b, 0xeb, 0x28, + 0x80, 0xc9, 0x7a, 0x07, 0xd7, 0x4b, 0xee, 0x01, 0x10, 0x48, 0xcc, 0xc6, + 0x03, 0x99, 0x9d, 0x67, 0x2a, 0xbd, 0xa0, 0x6f, 0x51, 0xa4, 0x75, 0x50, + 0xe1, 0x84, 0x8e, 0xda, 0x7b, 0x5e, 0x9e, 0x78, 0x18, 0x2a, 0x6b, 0xfa, + 0xef, 0x87, 0x81, 0xe9, 0x48, 0x3f, 0x29, 0x2d, 0xfb, 0x15, 0xd2, 0x15, + 0xb5, 0x5c, 0xed, 0x45, 0x48, 0x30, 0xec, 0x00, 0x55, 0x15, 0x13, 0xc7, + 0x11, 0xc4, 0x29, 0xef, 0x0f, 0xa8, 0xa6, 0xef, 0x19, 0x41, 0xc2, 0xb6, + 0x11, 0xdc, 0xe8, 0xf4, 0xa7, 0x03, 0x80, 0x2d, 0x92, 0xad, 0x7e, 0x7e, + 0x8a, 0x71, 0xa4, 0x6c, 0x16, 0xb9, 0x84, 0xf5, 0x8d, 0x94, 0xc5, 0xd5, + 0x82, 0x29, 0x42, 0x22, 0x1f, 0x06, 0xca, 0xdd, 0xbf, 0x74, 0x0f, 0x14, + 0x79, 0x26, 0x9c, 0x79, 0x30, 0xcb, 0x01, 0x02, 0x76, 0x22, 0x4f, 0x54, + 0xff, 0x49, 0xa3, 0x03, 0x35, 0x23, 0x45, 0x91, 0xac, 0xed, 0x13, 0x31, + 0xa4, 0x4e, 0x51, 0xe8, 0x9c, 0x5b, 0xe4, 0xcf, 0x41, 0xd3, 0xa0, 0x86, + 0x7f, 0x3a, 0x4d, 0xaf, 0xa7, 0x49, 0x63, 0x47, 0x86, 0x08, 0x88, 0xcf, + 0x01, 0x7a, 0xc4, 0xf5, 0x29, 0x67, 0x8a, 0xd4, 0xdd, 0x6a, 0x6d, 0x81, + 0xb8, 0x29, 0x9d, 0x7c, 0x32, 0x4e, 0x8f, 0x0c, 0x9f, 0x8c, 0x7e, 0x76, + 0xa3, 0xd4, 0x32, 0x80, 0xd0, 0x79, 0x7d, 0x56, 0x99, 0x6d, 0x0b, 0x88, + 0xfc, 0x98, 0xdb, 0xaf, 0x13, 0xf3, 0xb2, 0x20, 0x3f, 0x19, 0xe1, 0x83, + 0x70, 0xd2, 0x26, 0xd0, 0xd2, 0xad, 0x11, 0xeb, 0x3b, 0x31, 0x03, 0x55, + 0x62, 0xca, 0xb5, 0x87, 0x31, 0x7a, 0x11, 0x4c, 0xf2, 0xc3, 0xc2, 0x1c, + 0x42, 0x94, 0x7b, 0xe6, 0x29, 0x86, 0x70, 0x8e, 0x51, 0x4a, 0xa3, 0xf2, + 0xf0, 0xed, 0xa1, 0xc6, 0x18, 0xff, 0xf2, 0xff, 0xe0, 0x07, 0x85, 0xf1, + 0x93, 0x5a, 0x83, 0x1c, 0x4c, 0xa9, 0x9b, 0xc5, 0x0c, 0xc4, 0xf0, 0xde, + 0x71, 0x93, 0x78, 0xd1, 0x3b, 0xcc, 0x5b, 0x51, 0x1f, 0xd7, 0x21, 0x12, + 0x57, 0xd5, 0x2a, 0xea, 0x64, 0x08, 0x0e, 0xf0, 0x3d, 0x42, 0xe7, 0xdf, + 0xc8, 0xea, 0x42, 0x2b, 0x41, 0x55, 0x85, 0xb8, 0x54, 0xa4, 0xc9, 0x3f, + 0xce, 0xfc, 0x1a, 0xde, 0x73, 0x08, 0xaa, 0x09, 0x25, 0x08, 0xa0, 0xdc, + 0x64, 0xb7, 0xe7, 0xcc, 0xde, 0x85, 0xa6, 0xc3, 0xe9, 0xe1, 0x43, 0x71, + 0x86, 0x05, 0x55, 0x86, 0x47, 0xf8, 0x71, 0xbd, 0xf5, 0xd7, 0x38, 0x64, + 0x7f, 0x71, 0x63, 0xe1, 0x22, 0x39, 0x99, 0xc3, 0xdf, 0x27, 0x5d, 0xdd, + 0xd0, 0x57, 0x99, 0xd5, 0x97, 0xcd, 0xd4, 0x2e, 0xc1, 0x25, 0x3d, 0x2e, + 0x03, 0x0b, 0x04, 0x20, 0x70, 0xec, 0x46, 0x6c, 0x4b, 0x55, 0x16, 0x02, + 0x00, 0x71, 0xfd, 0x8a, 0xa0, 0x1e, 0x5f, 0x41, 0xe6, 0x96, 0x58, 0xbe, + 0x02, 0x73, 0x91, 0x71, 0xb2, 0x7e, 0xc4, 0xcd, 0xce, 0xa5, 0x26, 0xee, + 0xff, 0x8c, 0x9a, 0x4c, 0xf4, 0x0a, 0x89, 0xba, 0x14, 0x6e, 0x06, 0x86, + 0xb0, 0xba, 0x41, 0xdd, 0x27, 0xf8, 0xc3, 0x46, 0x4f, 0x39, 0xac, 0x2c, + 0x8a, 0x69, 0x09, 0xb7, 0x36, 0x0f, 0xe0, 0x8d, 0x31, 0x0f, 0xc3, 0xee, + 0x3a, 0x6a, 0x9e, 0x96, 0x91, 0xf5, 0x6a, 0x12, 0x98, 0x5a, 0xc3, 0xf3, + 0xb8, 0x9b, 0x07, 0xdb, 0x8e, 0x2a, 0xb0, 0x91, 0x86, 0xb5, 0xc7, 0xe9, + 0x06, 0xe1, 0x4e, 0x83, 0x28, 0x3a, 0x0e, 0x67, 0xe5, 0x7e, 0x88, 0x2a, + 0x31, 0xd2, 0xfe, 0xf6, 0x19, 0x3d, 0x09, 0xd1, 0xef, 0x5d, 0xe1, 0x15, + 0x2d, 0xb4, 0xec, 0x23, 0xc2, 0x0c, 0x7a, 0xbf, 0xd3, 0x6f, 0xf7, 0x8a, + 0x3b, 0x3a, 0x0f, 0x20, 0xc4, 0x78, 0xbe, 0x46, 0x30, 0x0f, 0xc2, 0xd0, + 0x8c, 0x23, 0xb7, 0xfa, 0x3c, 0x19, 0x35, 0x53, 0x5f, 0xf9, 0x94, 0xf5, + 0x23, 0xbe, 0xb3, 0x56, 0x42, 0xa1, 0x27, 0xff, 0xac, 0xbf, 0x72, 0x7e, + 0x89, 0xbe, 0xb9, 0x6d, 0x2d, 0xc4, 0x3f, 0x6c, 0x7f, 0xc4, 0x7e, 0x01, + 0x09, 0xc8, 0x35, 0x80, 0x99, 0x8f, 0x1c, 0x43, 0xd3, 0xb2, 0x4a, 0xb7, + 0x08, 0x06, 0x63, 0xcd, 0x8a, 0x5e, 0x64, 0xa2, 0x93, 0xa5, 0x15, 0xa0, + 0x38, 0xa0, 0xf2, 0x1c, 0xab, 0xe1, 0x2d, 0x19, 0x30, 0xee, 0x9b, 0x87, + 0x42, 0x54, 0xfb, 0xcc, 0xfe, 0x2a, 0xcd, 0x54, 0xf5, 0xeb, 0x52, 0x6b, + 0xd4, 0x1d, 0xa3, 0x7c, 0xec, 0xf2, 0x56, 0x51, 0x54, 0xab, 0x66, 0xb0, + 0x73, 0x49, 0x3e, 0xc4, 0x89, 0xac, 0xb0, 0xc1, 0x41, 0x6f, 0x19, 0xd6, + 0x41, 0xbd, 0xc2, 0xe2, 0x1a, 0x56, 0xb3, 0x01, 0xc9, 0xdf, 0x46, 0xe7, + 0xa1, 0x42, 0xfa, 0x1c, 0x18, 0x86, 0xe2, 0x07, 0xe4, 0xfe, 0x19, 0x03, + 0x7d, 0xc4, 0x51, 0x78, 0x29, 0x68, 0x73, 0x70, 0x82, 0x98, 0x34, 0x2e, + 0x41, 0x59, 0xd5, 0x20, 0x36, 0xe3, 0xe5, 0x2c, 0xbe, 0x76, 0x23, 0x5d, + 0xb1, 0xf0, 0xda, 0xee, 0x65, 0x54, 0xd9, 0xa1, 0x77, 0x6e, 0xd8, 0x56, + 0xcb, 0x6a, 0x35, 0xb5, 0xaa, 0x97, 0x22, 0x28, 0x4d, 0x74, 0x13, 0x96, + 0x59, 0x3d, 0x3a, 0xe2, 0x26, 0xde, 0xd3, 0xc7, 0xed, 0x97, 0x98, 0xa8, + 0x4a, 0x6b, 0x4b, 0xd1, 0x52, 0xca, 0x84, 0xd6, 0x19, 0x7a, 0x6c, 0x0d, + 0xb4, 0x28, 0x4f, 0xb1, 0xa2, 0xcc, 0x07, 0x08, 0x57, 0xc9, 0x32, 0xd4, + 0xe0, 0xef, 0x96, 0x9a, 0x31, 0x1e, 0x68, 0x1d, 0x7b, 0x57, 0x26, 0x62, + 0xa4, 0x26, 0xaf, 0xc7, 0xd0, 0xab, 0xb6, 0x9e, 0x00, 0x6d, 0xfe, 0x29, + 0x30, 0x53, 0xcd, 0xb8, 0x4e, 0x30, 0x4e, 0xa5, 0xcc, 0xf6, 0xab, 0xca, + 0x4d, 0x74, 0x40, 0xc2, 0xb4, 0xfb, 0x3f, 0x75, 0x0a, 0x9d, 0x88, 0xa3, + 0xb0, 0x5b, 0x4e, 0x88, 0x50, 0x90, 0xcb, 0x5c, 0xcd, 0xc7, 0xff, 0x75, + 0x97, 0xc4, 0x1b, 0xe9, 0x03, 0x8a, 0xa7, 0x62, 0x32, 0x98, 0x60, 0x39, + 0x56, 0xe5, 0x25, 0xed, 0xba, 0x58, 0x67, 0xa3, 0xe8, 0x23, 0xd1, 0x55, + 0xb3, 0xa5, 0xc0, 0xc9, 0x75, 0x14, 0x91, 0xe6, 0x7d, 0x0e, 0xe3, 0xac, + 0xc8, 0x6b, 0xa7, 0xdb, 0x36, 0xe8, 0x44, 0x92, 0x72, 0xf2, 0x6d, 0x10, + 0xeb, 0xd0, 0x7a, 0xdd, 0x00, 0x9b, 0xf8, 0x65, 0xaa, 0xef, 0xed, 0xfb, + 0x84, 0x5f, 0xfb, 0xd8, 0xe9, 0xa8, 0x71, 0xab, 0x20, 0x98, 0x4f, 0x21, + 0x7d, 0x33, 0xe2, 0xb1, 0x3f, 0x95, 0x9c, 0x28, 0xf5, 0xd5, 0x83, 0x01, + 0xe9, 0x71, 0x68, 0xa9, 0x3d, 0x9e, 0x49, 0xfb, 0x6c, 0x83, 0x5f, 0x48, + 0x9d, 0x91, 0x00, 0xab, 0x54, 0x17, 0x11, 0x5b, 0x9d, 0x0a, 0x17, 0x8e, + 0x3a, 0xbc, 0xd5, 0x33, 0xcd, 0x2a, 0x5b, 0x14, 0x39, 0xe4, 0x30, 0x45, + 0xde, 0x6e, 0xde, 0x92, 0x7f, 0xb5, 0x91, 0x5d, 0x5b, 0xe4, 0x18, 0x17, + 0x7c, 0x22, 0x1e, 0x2d, 0x97, 0x8b, 0x6f, 0xe0, 0x54, 0x2e, 0x25, 0xbc, + 0x5f, 0xef, 0x27, 0x1b, 0x95, 0x71, 0xcc, 0x29, 0x96, 0x30, 0x82, 0xb1, + 0x99, 0x98, 0x28, 0x36, 0x5f, 0xd6, 0xf9, 0x13, 0xb3, 0x3d, 0x14, 0x91, + 0x8a, 0x2f, 0xbf, 0x6e, 0x8c, 0x57, 0xf6, 0x8e, 0x32, 0xf2, 0xd3, 0xa5, + 0x1b, 0x2b, 0xba, 0xc8, 0x0d, 0xa4, 0xd3, 0xc2, 0x16, 0x1f, 0x5f, 0xb6, + 0x89, 0x77, 0xa9, 0xf3, 0x7b, 0xb8, 0x11, 0x23, 0x41, 0xd6, 0xe0, 0x47, + 0x3c, 0x94, 0xe0, 0xed, 0xa9, 0xb1, 0x0e, 0x90, 0x38, 0xdd, 0x60, 0xcd, + 0x75, 0x00, 0x36, 0x3a, 0x42, 0xbb, 0xfd, 0xd7, 0xc6, 0x16, 0x38, 0xb4, + 0xc0, 0x1d, 0xb6, 0x46, 0x5c, 0x2f, 0x70, 0x95, 0x8d, 0x74, 0x68, 0xb2, + 0xb5, 0xae, 0x73, 0x22, 0xa1, 0xca, 0x5d, 0xd4, 0x28, 0x1a, 0xd2, 0x19, + 0x1c, 0x43, 0x5e, 0x12, 0x16, 0x15, 0xb4, 0x97, 0x64, 0x10, 0x07, 0x48, + 0xf8, 0xe3, 0xfb, 0x3e, 0xa5, 0x05, 0xcd, 0xc1, 0x29, 0xf0, 0x67, 0xb7, + 0x24, 0x02, 0xac, 0x76, 0x91, 0x64, 0x63, 0x46, 0xfb, 0xfd, 0xaa, 0x5b, + 0x3f, 0xeb, 0xe0, 0xb2, 0x5a, 0x8d, 0xde, 0xdc, 0x92, 0x0c, 0x1e, 0xfc, + 0x82, 0x55, 0xc7, 0x8a, 0xe3, 0x28, 0x57, 0xfe, 0x10, 0xe1, 0xa3, 0x5a, + 0x9e, 0x67, 0x86, 0xf4, 0xa5, 0xf5, 0xa0, 0xbd, 0xa4, 0x3c, 0xda, 0xf3, + 0x83, 0x27, 0x2f, 0x55, 0x73, 0xb6, 0x74, 0x3e, 0xd3, 0xc9, 0x84, 0x1d, + 0xff, 0x61, 0x01, 0x56, 0x30, 0x2a, 0x23, 0x57, 0xbc, 0x88, 0xa7, 0x2f, + 0x6f, 0x95, 0x91, 0x4e, 0x5b, 0x41, 0xd9, 0x95, 0x1f, 0x09, 0x95, 0x79, + 0x36, 0xe3, 0x7f, 0xbd, 0x4b, 0x09, 0x4e, 0x7f, 0x6a, 0x58, 0x6e, 0xd0, + 0x60, 0xaf, 0xf1, 0x8f, 0x4c, 0xc5, 0x5a, 0x5c, 0xb7, 0x74, 0x83, 0x3c, + 0xb3, 0x7e, 0xdc, 0x76, 0x89, 0xa5, 0xca, 0xd7, 0x75, 0x35, 0xb2, 0x4c, + 0x0a, 0x67, 0x2b, 0x7a, 0xe8, 0xac, 0x9e, 0x26, 0xa3, 0xae, 0x87, 0x66, + 0x12, 0x4e, 0x74, 0xc8, 0xd8, 0x6d, 0x89, 0x9c, 0x34, 0x63, 0x61, 0x33, + 0x1b, 0x6a, 0x78, 0x7f, 0x2f, 0xa7, 0x9b, 0xe7, 0x42, 0x0d, 0xcb, 0xc9, + 0xf0, 0xa6, 0xb5, 0x38, 0x66, 0x80, 0xca, 0x7a, 0xa9, 0xe4, 0x93, 0xe3, + 0xfc, 0x7d, 0x38, 0x7d, 0x7a, 0x2c, 0x03, 0xb4, 0x35, 0xde, 0x1b, 0x2e, + 0x29, 0x24, 0x40, 0x93, 0x6c, 0x52, 0x21, 0xd6, 0x70, 0x88, 0xfd, 0xc7, + 0x5c, 0x94, 0x95, 0xc0, 0x03, 0xce, 0x1b, 0xb3, 0x0e, 0x87, 0xac, 0xa0, + 0x88, 0xcd, 0x20, 0x3d, 0x88, 0x6f, 0xac, 0x29, 0x2e, 0xcc, 0x7d, 0xa7, + 0x09, 0x16, 0xc0, 0xcc, 0x55, 0x43, 0x19, 0xdc, 0x5e, 0xc4, 0xe5, 0x7c, + 0xfb, 0x50, 0x01, 0x41, 0xe1, 0x70, 0x84, 0x3e, 0x60, 0x88, 0x05, 0x27, + 0x4b, 0x6c, 0x59, 0x9a, 0x01, 0x50, 0xec, 0x74, 0x6a, 0x98, 0x57, 0xfe, + 0xf5, 0x63, 0xc3, 0x60, 0x55, 0x23, 0x33, 0xf9, 0x2d, 0xf0, 0x68, 0xff, + 0xad, 0x61, 0xdb, 0x5e, 0xdb, 0x0c, 0x54, 0x68, 0x8c, 0x4b, 0x64, 0x94, + 0x3c, 0xa8, 0xb1, 0x31, 0x61, 0xf3, 0xb3, 0xed, 0x8f, 0xd5, 0x07, 0x27, + 0xbf, 0xa3, 0xa2, 0x42, 0x4a, 0xa1, 0x5e, 0xc9, 0xb3, 0x9a, 0x0f, 0xbb, + 0xf7, 0xc7, 0x4d, 0x0b, 0xee, 0xbd, 0xce, 0x9e, 0x8c, 0x14, 0x7e, 0x06, + 0x6e, 0x6d, 0x9b, 0xdd, 0x22, 0xc6, 0xc2, 0x62, 0xa5, 0x45, 0xc1, 0xe1, + 0x97, 0xe2, 0x50, 0x25, 0xcc, 0x9b, 0xc4, 0x5d, 0x2d, 0x45, 0x10, 0xad, + 0xa8, 0x4f, 0x27, 0xc3, 0x1a, 0x2c, 0xef, 0x38, 0x2d, 0xa7, 0xaf, 0xe5, + 0x23, 0x7a, 0x8f, 0xbf, 0x9c, 0xd0, 0xb6, 0x31, 0x5c, 0xaa, 0xd2, 0x8c, + 0xd8, 0x91, 0x00, 0xa1, 0x8b, 0x4d, 0x3e, 0x27, 0x22, 0x6c, 0x0f, 0x64, + 0x95, 0x89, 0xa6, 0x29, 0x90, 0xf9, 0xa9, 0x24, 0x24, 0xb8, 0x71, 0x56, + 0x7a, 0xc5, 0xa9, 0x26, 0x9f, 0xf6, 0x2a, 0xa6, 0xf1, 0xca, 0x2a, 0x17, + 0x14, 0x8c, 0x8d, 0xf2, 0x44, 0x7d, 0x49, 0x4e, 0x9b, 0x4f, 0xef, 0x72, + 0x7e, 0xe8, 0x0f, 0x45, 0xb3, 0x3d, 0x61, 0xf5, 0x9d, 0x3f, 0x9a, 0xe3, + 0x93, 0xdd, 0x3d, 0x02, 0x84, 0x7d, 0xd4, 0x84, 0xa8, 0x23, 0xe9, 0x43, + 0xb6, 0x66, 0xf2, 0xb7, 0x35, 0xcf, 0xa3, 0x2f, 0xbe, 0x48, 0x0e, 0xaa, + 0xfe, 0xe9, 0x7e, 0xb0, 0x4d, 0xb3, 0x6b, 0x69, 0xdc, 0xef, 0x20, 0xec, + 0xce, 0x6c, 0xad, 0x7a, 0x20, 0x35, 0xf2, 0xfd, 0x09, 0xe1, 0xdb, 0xca, + 0x2a, 0x55, 0xf7, 0x60, 0xca, 0xf3, 0x85, 0x12, 0xe6, 0x05, 0x4f, 0xc8, + 0x6e, 0x76, 0xda, 0x5f, 0x45, 0x1e, 0xed, 0xdf, 0x57, 0x4c, 0xeb, 0x7e, + 0x28, 0xf7, 0x39, 0xc4, 0xd0, 0x10, 0x32, 0xa9, 0xcc, 0x25, 0xd9, 0x0b, + 0x8c, 0x8a, 0xf6, 0x6c, 0x84, 0xde, 0x09, 0x8c, 0xf6, 0xa4, 0x95, 0xb3, + 0x65, 0x5e, 0x49, 0x36, 0x8c, 0x51, 0x85, 0x62, 0xcc, 0xe6, 0x2a, 0x3d, + 0xdc, 0x68, 0x08, 0x41, 0x73, 0x18, 0x74, 0x10, 0xe5, 0x18, 0xfa, 0xbe, + 0x2f, 0xaa, 0x98, 0x3c, 0x7c, 0x44, 0x43, 0x3f, 0xd6, 0x27, 0xd3, 0x28, + 0xf0, 0x2b, 0xeb, 0xf2, 0x46, 0xfc, 0xf6, 0x3f, 0xc7, 0xa8, 0xc0, 0xf0, + 0x17, 0xef, 0x35, 0xde, 0x55, 0x30, 0xef, 0xf7, 0x7b, 0x57, 0xf3, 0x9f, + 0x00, 0xb5, 0x49, 0x1e, 0xc4, 0x6a, 0xea, 0x0e, 0x40, 0x95, 0x47, 0x55, + 0x32, 0x4f, 0x4f, 0x24, 0x5a, 0x10, 0xaa, 0x1f, 0x5b, 0x9b, 0xc1, 0xb3, + 0xaa, 0xa3, 0x40, 0x32, 0x56, 0x80, 0xbf, 0x38, 0xbc, 0x89, 0xad, 0xa8, + 0x0e, 0x8f, 0x8e, 0x14, 0x17, 0x5a, 0x9b, 0x25, 0x85, 0x85, 0xa7, 0x43, + 0xc8, 0x19, 0x21, 0xf9, 0xa3, 0xdc, 0xb9, 0xc8, 0x70, 0x7b, 0xc8, 0x42, + 0x38, 0x50, 0xb9, 0xcf, 0x90, 0x6e, 0x88, 0x7f, 0x5a, 0x56, 0xc8, 0xd7, + 0x84, 0x7b, 0x69, 0xe1, 0x31, 0x6d, 0xe9, 0xc7, 0x7f, 0x39, 0x78, 0x52, + 0xa2, 0x0c, 0xc7, 0x3b, 0x89, 0x05, 0x9d, 0x66, 0xc6, 0xea, 0x48, 0x75, + 0xa5, 0xd6, 0x89, 0x8e, 0x47, 0xdf, 0x81, 0x28, 0x94, 0xc7, 0x98, 0xd4, + 0x1c, 0x6f, 0x95, 0xdd, 0x20, 0x74, 0xe9, 0xde, 0xb5, 0x3b, 0x87, 0xa1, + 0x1a, 0x1e, 0xee, 0xc7, 0xbc, 0xa4, 0x12, 0x30, 0x92, 0x60, 0x9f, 0x0d, + 0x4d, 0x23, 0x1f, 0xa0, 0xea, 0x07, 0x84, 0x10, 0xb3, 0xd3, 0x2a, 0x2f, + 0x27, 0xdb, 0x27, 0x76, 0xb8, 0x43, 0xe2, 0x9a, 0xfc, 0x9b, 0x81, 0x43, + 0xd2, 0xbc, 0xc2, 0xbb, 0x40, 0xbd, 0xe8, 0x10, 0xd5, 0xca, 0xd2, 0x10, + 0x5e, 0x18, 0xfe, 0x45, 0x1d, 0xc2, 0xf9, 0x99, 0x50, 0xbe, 0x7e, 0xca, + 0x1a, 0x45, 0x17, 0x99, 0x03, 0x9d, 0x2b, 0x68, 0xb7, 0x76, 0x3e, 0x68, + 0x41, 0x81, 0x6d, 0xe3, 0x77, 0xbe, 0x4e, 0xc9, 0x41, 0xb7, 0x8a, 0xb7, + 0xa7, 0x59, 0xfa, 0x04, 0x7b, 0xde, 0xd0, 0x3f, 0x7a, 0x57, 0xa3, 0xf1, + 0x9e, 0x0a, 0x66, 0x98, 0xb0, 0xc1, 0xc2, 0xb4, 0x7a, 0x3b, 0x2f, 0x54, + 0x3b, 0x66, 0xe6, 0x6b, 0xc5, 0x2c, 0xa1, 0xb1, 0xd2, 0xee, 0xd8, 0x30, + 0xf3, 0xa9, 0x2f, 0xe8, 0xf0, 0x3e, 0xd8, 0x2b, 0x9a, 0x75, 0x58, 0x59, + 0xc7, 0x3a, 0x39, 0xa1, 0x58, 0x19, 0x87, 0x3f, 0x90, 0xe5, 0xb3, 0xb6, + 0xfe, 0x39, 0x34, 0xc8, 0x4c, 0x21, 0x7b, 0x96, 0x9e, 0x3e, 0x38, 0x48, + 0x3e, 0xaa, 0x0b, 0x1b, 0xbf, 0xa9, 0x45, 0x83, 0x8e, 0x38, 0xf3, 0x96, + 0xb8, 0x24, 0x23, 0xc1, 0xd3, 0x5c, 0x77, 0xeb, 0x6f, 0xf8, 0x16, 0xa8, + 0x94, 0xbc, 0xab, 0x2a, 0x20, 0x52, 0xec, 0x9a, 0x5c, 0xd9, 0x99, 0xb4, + 0x84, 0x50, 0x90, 0xbb, 0xf7, 0x80, 0x51, 0x61, 0x95, 0x61, 0xaa, 0x03, + 0xd6, 0xd4, 0xa9, 0x73, 0x86, 0x3b, 0xf1, 0x7e, 0xca, 0x7c, 0xfb, 0xf9, + 0x33, 0xe6, 0x96, 0x66, 0x13, 0x7a, 0x35, 0xae, 0x71, 0xcc, 0x13, 0x4b, + 0x5e, 0x73, 0xbd, 0xf8, 0xf2, 0x5e, 0x51, 0x5c, 0x50, 0x09, 0x3c, 0x59, + 0xfa, 0xd0, 0xd4, 0x8e, 0xe0, 0x21, 0xb4, 0x97, 0xa4, 0x7d, 0xeb, 0x17, + 0xef, 0x4c, 0xf4, 0xd0, 0x0b, 0xf5, 0x42, 0xaf, 0x07, 0x8e, 0xe9, 0x5f, + 0x2b, 0xce, 0xb4, 0xf9, 0x17, 0xea, 0x9e, 0x83, 0x94, 0xf5, 0x1d, 0x49, + 0x91, 0x42, 0x65, 0x84, 0x77, 0x56, 0xc0, 0x4f, 0x67, 0x37, 0xed, 0xa3, + 0x18, 0x22, 0x69, 0xd7, 0x40, 0xfb, 0x39, 0xfd, 0xc2, 0x37, 0x68, 0x98, + 0x30, 0x6a, 0x33, 0xad, 0x2f, 0xf2, 0x3d, 0x5c, 0xe0, 0x4a, 0x29, 0x38, + 0xe5, 0xe0, 0x5c, 0xb3, 0x79, 0xd5, 0x8c, 0xcd, 0x25, 0xad, 0xab, 0xd3, + 0x75, 0x2f, 0x54, 0x3a, 0xfe, 0x8e, 0x0d, 0x3f, 0xfa, 0x6e, 0xcc, 0x80, + 0x26, 0x08, 0x7f, 0xa3, 0x9e, 0xba, 0x80, 0x4c, 0x36, 0x4c, 0x4d, 0x74, + 0xc0, 0x3f, 0xd1, 0xb3, 0xad, 0xa3, 0xc8, 0xcf, 0x7a, 0x73, 0xb7, 0x09, + 0x67, 0x3b, 0xf8, 0x6f, 0x7a, 0x26, 0x57, 0x65, 0x83, 0xcf, 0x18, 0x3c, + 0x86, 0x2c, 0xb4, 0xcd, 0xe8, 0x74, 0xfa, 0x63, 0xd4, 0xb4, 0x36, 0x36, + 0xd9, 0xb0, 0xeb, 0x29, 0xe3, 0x3a, 0x7f, 0x06, 0x80, 0x29, 0x4c, 0x86, + 0x94, 0x49, 0x42, 0x22, 0x57, 0x0c, 0x4f, 0xfa, 0x08, 0xb5, 0x12, 0xbe, + 0x76, 0xf5, 0x52, 0x10, 0x47, 0x48, 0x1f, 0xbd, 0x87, 0x51, 0xd1, 0x39, + 0xc8, 0x50, 0x7c, 0xfa, 0x92, 0xe7, 0xea, 0x40, 0x55, 0xf7, 0x61, 0x9f, + 0x19, 0xc2, 0x65, 0x23, 0x6d, 0xe0, 0x41, 0xb9, 0x5b, 0xb7, 0x8c, 0x9a, + 0xee, 0x50, 0x53, 0xa6, 0xe8, 0x80, 0x14, 0x8c, 0xeb, 0x2a, 0xc1, 0x44, + 0xda, 0x6d, 0x90, 0x96, 0xb8, 0xf1, 0xc4, 0x0d, 0xf1, 0xd8, 0x8e, 0xd0, + 0xb4, 0x73, 0x49, 0xe5, 0x34, 0xab, 0x00, 0x0f, 0x0b, 0x7b, 0xc3, 0x7d, + 0x53, 0x1d, 0x75, 0xef, 0x27, 0xfb, 0xdf, 0x29, 0xfd, 0x61, 0xb3, 0x71, + 0x25, 0xac, 0x62, 0x2d, 0xaa, 0x1a, 0x2a, 0x55, 0x6e, 0x11, 0x50, 0x4b, + 0x2c, 0x3d, 0xd8, 0x8d, 0xb9, 0xcb, 0xc2, 0x21, 0x77, 0x4e, 0x40, 0x56, + 0x45, 0xc1, 0x07, 0x79, 0xdb, 0x66, 0x2f, 0x6d, 0x4d, 0xac, 0x2b, 0x2d, + 0x29, 0xff, 0xa1, 0x79, 0x10, 0x03, 0x72, 0x09, 0xe8, 0xe9, 0x31, 0xd5, + 0x6f, 0x42, 0x97, 0x3e, 0x09, 0xf0, 0x4a, 0xb5, 0xe6, 0x73, 0x94, 0xc1, + 0xb4, 0x94, 0xa1, 0xd9, 0x44, 0xe8, 0x50, 0xe2, 0x6c, 0x82, 0xea, 0x89, + 0x06, 0xd6, 0x44, 0xe9, 0x53, 0xd0, 0x5c, 0xcf, 0x0a, 0x3b, 0x89, 0x50, + 0x8d, 0x1e, 0x44, 0xbd, 0xb2, 0xb6, 0x68, 0xf4, 0xbb, 0x2d, 0x65, 0x95, + 0x5c, 0xb5, 0xdc, 0xe2, 0xb7, 0x70, 0x86, 0xfd, 0x5b, 0xcc, 0x99, 0x41, + 0x5d, 0x22, 0x11, 0xa8, 0x22, 0x8c, 0xc1, 0x73, 0x70, 0x5b, 0x31, 0x11, + 0xc3, 0xdb, 0x7f, 0xca, 0x2b, 0xcb, 0xeb, 0x7d, 0x2b, 0xd1, 0x32, 0xe6, + 0xf8, 0x22, 0x22, 0x69, 0xea, 0xb7, 0xcd, 0x25, 0x22, 0x33, 0x2f, 0x83, + 0x3f, 0xb7, 0x2d, 0x22, 0x61, 0x24, 0x01, 0xb3, 0xe9, 0xd0, 0xf6, 0x21, + 0xe6, 0x2d, 0xea, 0x0e, 0x53, 0x7a, 0x97, 0xcd, 0xcf, 0x6c, 0xe2, 0xd5, + 0x8b, 0xdc, 0xe9, 0xe0, 0xfd, 0xd0, 0xa0, 0xbf, 0xa5, 0x39, 0x7e, 0xd4, + 0xdd, 0xfe, 0x1a, 0xce, 0xb0, 0x85, 0x8e, 0xc1, 0x05, 0x36, 0xf9, 0xd3, + 0x6a, 0x35, 0xab, 0x53, 0x1d, 0xc2, 0xa0, 0xfa, 0xc2, 0x6b, 0x8b, 0x8c, + 0x2d, 0x5d, 0x5f, 0xb8, 0x18, 0x43, 0x53, 0xb9, 0x5d, 0x08, 0x07, 0xd1, + 0x8f, 0xc6, 0xe9, 0xef, 0xaf, 0x3b, 0xbb, 0x60, 0xaa, 0x28, 0xac, 0x4c, + 0x03, 0x5d, 0xc8, 0x05, 0xba, 0x82, 0x5c, 0xcb, 0xc6, 0x2a, 0x13, 0xf6, + 0xfc, 0x54, 0xf3, 0xea, 0x20, 0xce, 0xcf, 0x05, 0x00, 0xb9, 0x98, 0x0b, + 0x9f, 0x96, 0xe0, 0x7b, 0x85, 0x8e, 0x43, 0xbd, 0xf2, 0x3e, 0x17, 0x19, + 0x8d, 0x23, 0x72, 0x85, 0x93, 0xdf, 0x3a, 0x21, 0x94, 0x34, 0x32, 0x53, + 0x02, 0xba, 0x34, 0xba, 0xa5, 0x2e, 0x5c, 0x0b, 0x1e, 0x3f, 0xa9, 0x83, + 0x92, 0x63, 0x0b, 0x12, 0xc9, 0xf8, 0x35, 0xef, 0x78, 0xa0, 0xee, 0xc0, + 0xbb, 0x14, 0xd4, 0x68, 0x39, 0xa0, 0x00, 0x38, 0x77, 0x1e, 0xfc, 0x94, + 0xb4, 0xd4, 0xc1, 0x98, 0xe1, 0x43, 0x8e, 0xc6, 0xa7, 0x58, 0x33, 0x1b, + 0xa3, 0x73, 0xf7, 0x4c, 0x49, 0x9d, 0xc0, 0xb8, 0xbf, 0x30, 0x84, 0x2e, + 0x5a, 0x8b, 0x6c, 0xa5, 0xde, 0xb5, 0x6a, 0x79, 0x67, 0x54, 0xe7, 0x8c, + 0x3c, 0xf3, 0x70, 0x1b, 0x3d, 0x35, 0x23, 0x65, 0x17, 0xc9, 0x74, 0x11, + 0x0b, 0xb1, 0x64, 0xc0, 0x65, 0xa3, 0x9e, 0x5a, 0x7b, 0xa2, 0xda, 0xe1, + 0xf4, 0xeb, 0xb8, 0x13, 0x90, 0x30, 0xc1, 0x72, 0x6a, 0x2a, 0x13, 0xe3, + 0x36, 0xe1, 0x05, 0x47, 0x56, 0x42, 0xf2, 0x59, 0x44, 0x12, 0x23, 0x27, + 0xe4, 0xfe, 0xae, 0x83, 0x39, 0x0f, 0x4c, 0x85, 0x3f, 0xaf, 0x97, 0x2e, + 0xae, 0x3c, 0x12, 0x0e, 0xfd, 0x5b, 0xfd, 0x8e, 0x58, 0x58, 0x4a, 0xbd, + 0x05, 0x98, 0x6b, 0x82, 0x03, 0x02, 0x0a, 0x2d, 0x1c, 0x19, 0x0f, 0x95, + 0x12, 0x5d, 0x8c, 0x1e, 0x7b, 0x49, 0xbb, 0x83, 0xe2, 0xd2, 0x53, 0x60, + 0xe1, 0xab, 0xd2, 0x8b, 0x02, 0xeb, 0x49, 0x27, 0xd7, 0xda, 0x22, 0xd3, + 0x26, 0x6f, 0x3e, 0x5b, 0x3f, 0x33, 0xcb, 0xa8, 0x08, 0x98, 0xa6, 0xc5, + 0x35, 0xc1, 0x81, 0xc1, 0xd6, 0x28, 0xe5, 0xba, 0x50, 0xe9, 0x14, 0x1a, + 0x0b, 0x0a, 0x8a, 0x9e, 0xa3, 0xaa, 0xbc, 0x3b, 0x38, 0x5b, 0xe0, 0x1f, + 0xf6, 0xb8, 0x95, 0x79, 0xa4, 0x45, 0x5f, 0xc4, 0x63, 0x86, 0xd0, 0x15, + 0xe0, 0x25, 0x6e, 0x5f, 0x8d, 0x75, 0x25, 0x67, 0xea, 0xf3, 0x92, 0x33, + 0xd1, 0x07, 0xf3, 0x43, 0x21, 0x42, 0x40, 0x70, 0x9b, 0x8e, 0x0b, 0x41, + 0x54, 0x30, 0x73, 0xd0, 0x49, 0xe4, 0x70, 0xf6, 0xd3, 0x7d, 0x59, 0xd6, + 0x1f, 0x06, 0xfc, 0x12, 0x89, 0x9f, 0x26, 0x09, 0x34, 0xf6, 0x64, 0x56, + 0x37, 0x68, 0x59, 0x33, 0x9c, 0xa0, 0xfa, 0x65, 0x70, 0xb3, 0xe1, 0x29, + 0xd1, 0x5b, 0xaf, 0xe7, 0xa5, 0x39, 0x64, 0x38, 0x8b, 0xb1, 0xd6, 0xce, + 0xa4, 0xb4, 0xb6, 0xdb, 0x01, 0xb4, 0xf9, 0xb7, 0x1f, 0x8f, 0xcd, 0x28, + 0xe6, 0x27, 0x47, 0xf2, 0x53, 0x1d, 0xea, 0xb4, 0x53, 0xfa, 0xe0, 0x22, + 0xea, 0xc5, 0xd2, 0xfc, 0x4e, 0x45, 0xcf, 0xef, 0xaa, 0xea, 0xaf, 0x7e, + 0x77, 0xe2, 0x39, 0x1c, 0x5d, 0x9c, 0x77, 0x7b, 0x71, 0xb5, 0x11, 0xef, + 0xc7, 0xf8, 0xba, 0x2b, 0x7b, 0x15, 0xfa, 0x2d, 0xd5, 0xd8, 0xe0, 0xee, + 0xbe, 0x10, 0xd6, 0xdb, 0x47, 0xf1, 0x11, 0xcc, 0x35, 0x4c, 0x2d, 0xa8, + 0x12, 0x12, 0x23, 0x78, 0x0b, 0xd3, 0xb8, 0x90, 0x8a, 0x1d, 0xc4, 0x90, + 0x4b, 0x7e, 0x35, 0xb9, 0x9f, 0x5b, 0x68, 0x97, 0x9c, 0x09, 0xc3, 0x0d, + 0x0a, 0x20, 0xd9, 0x25, 0x07, 0xeb, 0x56, 0xb5, 0xd6, 0x93, 0x31, 0x3d, + 0x71, 0x7c, 0x0f, 0x48, 0x26, 0x32, 0x0f, 0x1b, 0x43, 0x75, 0xc2, 0xcd, + 0xf6, 0xaa, 0x88, 0x38, 0x7b, 0xe9, 0xc0, 0x98, 0x51, 0xa4, 0x06, 0x15, + 0x7f, 0x11, 0x0b, 0x91, 0xcb, 0x59, 0x92, 0x1c, 0xa1, 0x44, 0x63, 0xa4, + 0x3a, 0xad, 0xd7, 0x1d, 0x9e, 0x63, 0xfb, 0xb9, 0x7d, 0x43, 0x80, 0x79, + 0xe8, 0x01, 0xba, 0x08, 0x47, 0x78, 0x57, 0xd6, 0x0b, 0x38, 0x94, 0x64, + 0xac, 0x64, 0x77, 0xdc, 0xb8, 0xa9, 0xa5, 0xa2, 0x62, 0x70, 0x36, 0x4f, + 0x39, 0xd9, 0xae, 0x2f, 0x15, 0xd3, 0x07, 0xc4, 0x01, 0x03, 0x96, 0x5e, + 0x51, 0xa7, 0x15, 0x2a, 0x9d, 0x22, 0x74, 0xae, 0x8a, 0xd4, 0xb9, 0x91, + 0xed, 0xad, 0xa7, 0x76, 0xad, 0x38, 0x33, 0xef, 0x3c, 0xe4, 0xd0, 0x7c, + 0x6e, 0x53, 0xae, 0x0c, 0x7a, 0xdf, 0x2c, 0x18, 0xeb, 0xc4, 0x8c, 0xfe, + 0xab, 0x10, 0xcd, 0xaf, 0x8f, 0x88, 0x3f, 0xac, 0xe3, 0x20, 0xed, 0x0c, + 0x62, 0x81, 0x2e, 0x12, 0xa9, 0xa5, 0xe7, 0xd5, 0x3a, 0xef, 0x40, 0xb4, + 0x91, 0x52, 0x4c, 0xfd, 0xd5, 0xb8, 0x98, 0x19, 0xcd, 0x1b, 0xa9, 0x17, + 0xe7, 0x9a, 0xda, 0x8a, 0xb4, 0x8f, 0x1a, 0x5c, 0x78, 0xd2, 0x28, 0x7a, + 0xb6, 0x66, 0xac, 0x73, 0xd4, 0x11, 0xc0, 0x81, 0xff, 0x71, 0x57, 0x4c, + 0x23, 0x90, 0x2a, 0xd8, 0x67, 0x7a, 0x6a, 0x58, 0xb7, 0x5b, 0xbe, 0x80, + 0x62, 0x17, 0x10, 0x90, 0xc1, 0xb7, 0x2c, 0xbe, 0xbe, 0x97, 0x2e, 0x85, + 0x36, 0x07, 0x8e, 0x63, 0xfc, 0x38, 0xc5, 0x66, 0x20, 0x33, 0x2b, 0xe8, + 0x25, 0x25, 0xc1, 0x11, 0xba, 0x5b, 0x12, 0xd9, 0x06, 0x4d, 0xfc, 0x49, + 0x20, 0x27, 0x6b, 0x79, 0x92, 0x8b, 0xde, 0x22, 0x39, 0xf9, 0x2e, 0xc9, + 0x1b, 0xb9, 0x97, 0x2f, 0xc3, 0x37, 0xf5, 0xa3, 0x6b, 0xd3, 0x3b, 0x94, + 0xa5, 0x56, 0xb7, 0x81, 0x7c, 0x9d, 0x28, 0xff, 0x57, 0xe7, 0x02, 0xa1, + 0xd1, 0x3a, 0x3d, 0xac, 0x74, 0x45, 0xb3, 0xab, 0x95, 0xec, 0x68, 0x8a, + 0x9c, 0xf7, 0x43, 0xa4, 0x14, 0x0d, 0x68, 0x40, 0x5f, 0x7e, 0x25, 0x8a, + 0x47, 0x3f, 0x9c, 0xaf, 0x88, 0x0b, 0x4a, 0xc0, 0x98, 0xc2, 0x57, 0xf4, + 0xde, 0x04, 0x09, 0x37, 0x9c, 0x87, 0x83, 0xb6, 0xa5, 0xa8, 0x5e, 0xc4, + 0xec, 0x2e, 0xfd, 0xc9, 0xf3, 0x85, 0x4f, 0x7d, 0xb8, 0xba, 0x6e, 0x6d, + 0xc0, 0xd2, 0x37, 0xb2, 0xba, 0x17, 0xad, 0x29, 0xf8, 0x71, 0x74, 0x0c, + 0x93, 0x1e, 0x07, 0x34, 0xec, 0xc3, 0x5f, 0x15, 0x21, 0x49, 0x0f, 0xa7, + 0x7e, 0x72, 0x79, 0x66, 0xfd, 0x3e, 0x29, 0xce, 0x12, 0xeb, 0x57, 0x88, + 0xd8, 0xcc, 0x14, 0x96, 0x33, 0x44, 0x64, 0x6c, 0x34, 0x55, 0xb3, 0x76, + 0xc9, 0xa7, 0x3f, 0x7b, 0x16, 0x9d, 0x7e, 0x95, 0x4c, 0xfa, 0xc9, 0x46, + 0x17, 0x18, 0x18, 0x78, 0xe7, 0xfb, 0x6b, 0x86, 0xf4, 0x25, 0x3a, 0x0b, + 0x4a, 0xcd, 0x1a, 0x51, 0xde, 0xa4, 0x45, 0xdd, 0xdb, 0xc9, 0x9f, 0xa9, + 0xc3, 0x58, 0xb2, 0x43, 0x90, 0x8b, 0xc1, 0x59, 0x47, 0x1a, 0x89, 0xcb, + 0x9c, 0x6d, 0x46, 0x1f, 0x0d, 0xe9, 0xfa, 0xd8, 0xe9, 0xde, 0xdb, 0xf5, + 0x22, 0x9b, 0xe3, 0xef, 0xb4, 0x0c, 0xc7, 0x34, 0xd0, 0x2a, 0x0f, 0x0b, + 0x8e, 0x11, 0x88, 0x91, 0xb7, 0xce, 0x92, 0xf2, 0x83, 0x3c, 0xd2, 0xf8, + 0x42, 0x32, 0x82, 0x48, 0xad, 0x67, 0x44, 0x45, 0x59, 0xac, 0x57, 0xb7, + 0x7e, 0x1b, 0xce, 0xca, 0x51, 0xfb, 0x1b, 0x12, 0x39, 0xaf, 0xe4, 0xfb, + 0xdb, 0xc5, 0xb7, 0xcc, 0x4a, 0x5d, 0xc4, 0xa6, 0x95, 0xaf, 0x5b, 0x39, + 0x4e, 0x47, 0xc5, 0x50, 0x67, 0x92, 0x84, 0x62, 0xeb, 0x81, 0x77, 0x24, + 0xda, 0x27, 0x64, 0xfe, 0xe4, 0x83, 0x40, 0x33, 0xc8, 0xb1, 0xaa, 0xbb, + 0xbf, 0x13, 0xc3, 0x18, 0x9a, 0x24, 0x06, 0xbd, 0x0a, 0x07, 0xa3, 0xd6, + 0xd8, 0x38, 0x32, 0x73, 0x8d, 0x40, 0x5f, 0xc2, 0x3f, 0xeb, 0xd2, 0x0e, + 0x3d, 0x6d, 0xf5, 0x72, 0x5a, 0xa6, 0x56, 0x22, 0x41, 0xe5, 0x0c, 0xb5, + 0x0c, 0xda, 0xcd, 0x46, 0xbc, 0xd7, 0x98, 0x89, 0x5e, 0x97, 0x54, 0x4f, + 0x4b, 0xc0, 0x27, 0x51, 0x0d, 0x20, 0x3f, 0x55, 0x78, 0xdc, 0x5a, 0x79, + 0x08, 0xed, 0xd3, 0xaa, 0x9c, 0xc3, 0x7d, 0x75, 0x76, 0x81, 0xa4, 0xe0, + 0xfc, 0x90, 0x6a, 0x83, 0x37, 0x53, 0xb8, 0xb5, 0xd9, 0x7a, 0xd9, 0x7d, + 0xeb, 0x50, 0x72, 0xd3, 0x5d, 0xed, 0x22, 0xfb, 0x6e, 0x67, 0x79, 0x9c, + 0xb9, 0xea, 0xac, 0xc1, 0x6d, 0x68, 0xf5, 0x12, 0xaa, 0x54, 0x90, 0xd8, + 0x7f, 0xe0, 0xf4, 0xdd, 0x3b, 0x88, 0xe3, 0xec, 0x7f, 0x1c, 0x2b, 0x08, + 0x32, 0xc6, 0x05, 0x53, 0xae, 0xa4, 0x46, 0xa7, 0xf3, 0xe6, 0xcb, 0xe7, + 0x04, 0xc1, 0x52, 0xa7, 0xfe, 0x68, 0x55, 0xc1, 0x91, 0xb2, 0x9a, 0x3b, + 0x05, 0xc6, 0xae, 0x15, 0x89, 0xdc, 0xb2, 0x0b, 0xeb, 0x19, 0x96, 0x62, + 0xe3, 0x67, 0xc5, 0xdc, 0xf5, 0xe8, 0xbe, 0x16, 0xbe, 0xf6, 0xe4, 0x0b, + 0xeb, 0x99, 0x82, 0x65, 0x0a, 0x97, 0xf5, 0xc2, 0x19, 0x1c, 0x1e, 0xa1, + 0xf1, 0x75, 0x06, 0xa7, 0xdb, 0x97, 0x68, 0x94, 0x0b, 0xea, 0xc4, 0xda, + 0x70, 0x72, 0x3e, 0x9f, 0xfc, 0x20, 0x4e, 0x54, 0xfb, 0x18, 0x01, 0x74, + 0x9a, 0x24, 0x1d, 0x20, 0x3a, 0x25, 0xe1, 0xd8, 0xaf, 0xe3, 0x76, 0xe0, + 0x47, 0x53, 0x86, 0xd9, 0x3f, 0xc2, 0x46, 0x4a, 0x02, 0x05, 0xaf, 0xbf, + 0x49, 0x12, 0x22, 0x66, 0x81, 0xf5, 0x9d, 0xdd, 0xae, 0x7f, 0xf5, 0x99, + 0x2b, 0x89, 0xa6, 0x25, 0x30, 0xd6, 0xb3, 0x00, 0xa4, 0x62, 0xd2, 0xb3, + 0x8e, 0xdd, 0xc2, 0x04, 0x62, 0x17, 0x44, 0xa3, 0x62, 0xf7, 0x8c, 0x56, + 0x00, 0x4f, 0x98, 0xfe, 0x7a, 0xdf, 0x9d, 0x47, 0xab, 0xc9, 0xb7, 0x0e, + 0x0d, 0x02, 0x54, 0x6a, 0xab, 0xf9, 0x22, 0xb9, 0x11, 0xb3, 0xec, 0x17, + 0xb9, 0xc9, 0x86, 0xf6, 0x66, 0x97, 0x1f, 0xa9, 0x38, 0xd8, 0x66, 0x8e, + 0x41, 0xd9, 0x9a, 0x35, 0xfd, 0x19, 0x64, 0xcb, 0x1e, 0x77, 0x80, 0xd4, + 0x6d, 0xea, 0x00, 0xf5, 0x9b, 0xc9, 0x55, 0xef, 0x80, 0x14, 0x79, 0xab, + 0xf5, 0x5e, 0xb0, 0x4b, 0x73, 0x52, 0x17, 0x2a, 0xd7, 0x68, 0x79, 0x6a, + 0xf1, 0xc0, 0x04, 0xce, 0x33, 0xd2, 0x18, 0xad, 0x39, 0x4d, 0xda, 0x40, + 0x49, 0xce, 0x00, 0xca, 0x89, 0xf3, 0xbd, 0x13, 0xe5, 0x7a, 0x03, 0x99, + 0xa3, 0x4b, 0x29, 0xcd, 0x18, 0xbd, 0xc8, 0xd7, 0x30, 0xcd, 0x4f, 0x65, + 0xdc, 0xca, 0xc2, 0x9f, 0x84, 0x2d, 0x83, 0xf6, 0x69, 0x0d, 0x55, 0x08, + 0x5b, 0x6c, 0x87, 0x53, 0xda, 0x13, 0x2a, 0x34, 0xf7, 0xea, 0x13, 0xec, + 0x14, 0x90, 0xe8, 0x94, 0xdc, 0xa6, 0xcf, 0xe9, 0x9b, 0x99, 0x63, 0x48, + 0xf3, 0x34, 0xac, 0xf2, 0x78, 0x76, 0x90, 0x46, 0xd8, 0x7d, 0x2b, 0xc1, + 0xd2, 0xdd, 0xf1, 0xda, 0x23, 0xc8, 0x3c, 0xd6, 0x58, 0x2e, 0xaf, 0x2c, + 0xf6, 0x8a, 0xb3, 0x93, 0x0e, 0x4f, 0x82, 0x7e, 0x26, 0x88, 0x0b, 0x3b, + 0xe4, 0xe9, 0x85, 0x2b, 0x99, 0xca, 0xdc, 0xad, 0x84, 0x26, 0xee, 0x35, + 0x6a, 0x50, 0xc4, 0xae, 0x95, 0x30, 0x0d, 0x09, 0xef, 0xdb, 0x4b, 0x4c, + 0x9b, 0x0f, 0x04, 0x0a, 0x6e, 0xf0, 0x92, 0x43, 0x06, 0xb9, 0x73, 0x16, + 0x79, 0x15, 0x3f, 0x08, 0xcc, 0x78, 0x2b, 0x35, 0x8c, 0xa3, 0x2a, 0x6e, + 0xf6, 0x5c, 0x61, 0xf3, 0xc6, 0x4b, 0x8a, 0xbc, 0x75, 0x1f, 0x4a, 0x00, + 0x4e, 0x5f, 0x9e, 0x24, 0x03, 0x2d, 0x86, 0x26, 0xa7, 0x78, 0xb7, 0xc3, + 0x6f, 0x74, 0x6d, 0x32, 0x34, 0xcd, 0x37, 0x42, 0x56, 0x24, 0x83, 0x7f, + 0xa8, 0x1b, 0x9b, 0xae, 0x97, 0x55, 0x2d, 0xba, 0x67, 0x75, 0x67, 0xca, + 0xa5, 0xd1, 0x6e, 0xd6, 0x48, 0xaf, 0xeb, 0x71, 0xdc, 0x31, 0xfb, 0x3b, + 0xe3, 0x7c, 0x64, 0x9d, 0xe5, 0x5a, 0xe4, 0x87, 0x6e, 0xed, 0xed, 0xca, + 0xb6, 0x51, 0xfd, 0x73, 0xef, 0x7c, 0xbc, 0x15, 0x69, 0xfd, 0x9f, 0x1f, + 0x0f, 0x17, 0x1a, 0x8d, 0x73, 0x61, 0x7d, 0xf1, 0x09, 0x97, 0x06, 0xbe, + 0x90, 0x38, 0xdf, 0xac, 0xfd, 0xe2, 0x87, 0xe8, 0xc1, 0xc3, 0x9b, 0x83, + 0x79, 0xa6, 0xdd, 0x6d, 0x58, 0x4d, 0x03, 0x26, 0x99, 0x1d, 0x2e, 0x47, + 0xb0, 0x20, 0x3f, 0x84, 0xaf, 0xfa, 0xf9, 0xf1, 0x62, 0xd5, 0x80, 0xb8, + 0x6e, 0x69, 0x7e, 0x53, 0x80, 0x05, 0xc4, 0x2f, 0xba, 0xed, 0x0d, 0x75, + 0xca, 0x01, 0xde, 0x6e, 0xf0, 0xd3, 0x23, 0x9b, 0x1e, 0xae, 0x02, 0x57, + 0xeb, 0x40, 0xf2, 0x55, 0x89, 0xd7, 0x70, 0xd6, 0x45, 0xe7, 0x67, 0xd3, + 0x3e, 0x21, 0xda, 0xb6, 0xae, 0xe5, 0xe6, 0x82, 0x0c, 0x3e, 0x3e, 0xe8, + 0xbe, 0x85, 0x3d, 0x79, 0x75, 0x90, 0x9b, 0x9c, 0x01, 0x88, 0x8d, 0x5a, + 0x34, 0x1d, 0x10, 0x83, 0x85, 0x08, 0xea, 0x88, 0x51, 0x29, 0xea, 0x95, + 0x40, 0x2f, 0x16, 0x90, 0xec, 0x1b, 0xb7, 0x22, 0x81, 0xcb, 0x1b, 0x8c, + 0xf5, 0xe2, 0xfd, 0xcb, 0x1f, 0xe7, 0xb0, 0x4b, 0x4d, 0x7c, 0x7d, 0x11, + 0x17, 0x20, 0x89, 0x8b, 0x4a, 0x80, 0xa3, 0x10, 0x6f, 0x68, 0x09, 0x01, + 0x68, 0x86, 0x3b, 0x2a, 0xfb, 0x48, 0x80, 0xa0, 0xd1, 0xdb, 0x3f, 0x91, + 0x44, 0x58, 0x83, 0xc6, 0x85, 0x77, 0x6b, 0xb1, 0x35, 0x4a, 0x03, 0xa2, + 0xcf, 0x2f, 0xbd, 0xcd, 0x4b, 0xfa, 0x5a, 0x5e, 0x8f, 0x8b, 0x95, 0x62, + 0xaa, 0xe7, 0x3b, 0x54, 0xb1, 0xec, 0xd5, 0x85, 0x4f, 0xd9, 0x59, 0x56, + 0xb4, 0xec, 0xc1, 0x21, 0xc5, 0xa6, 0x35, 0x1d, 0x7b, 0x60, 0xe1, 0xb1, + 0x7c, 0x8f, 0x47, 0xa1, 0xf1, 0x13, 0x4b, 0xaf, 0x23, 0xcb, 0x5e, 0xe2, + 0x74, 0x16, 0x16, 0x96, 0x3b, 0xff, 0xbf, 0x26, 0x5f, 0x68, 0xd5, 0x64, + 0xc6, 0x62, 0xaf, 0x4a, 0xfc, 0x0f, 0x27, 0x3e, 0x96, 0x5b, 0x7c, 0xeb, + 0x78, 0x81, 0x3c, 0x0a, 0x63, 0xd5, 0x6b, 0x3c, 0xa9, 0xd4, 0x37, 0x03, + 0x3b, 0x5c, 0x62, 0x7a, 0xd5, 0x69, 0xbe, 0x44, 0x50, 0xab, 0x0a, 0x54, + 0x31, 0x5c, 0x44, 0x52, 0xfe, 0xde, 0xbb, 0x10, 0x80, 0x79, 0xb2, 0x69, + 0xc5, 0x75, 0x8b, 0xba, 0x1d, 0x4d, 0x2d, 0xfa, 0xc8, 0x0e, 0xc0, 0xaf, + 0xc2, 0x31, 0xa1, 0x53, 0xc7, 0x9f, 0x3e, 0x1f, 0x38, 0x8c, 0x1e, 0x00, + 0x78, 0x76, 0xb6, 0xb5, 0x68, 0xa4, 0x68, 0xe9, 0xba, 0xda, 0x97, 0xca, + 0x16, 0xde, 0xba, 0xa1, 0xb7, 0x17, 0x26, 0xb3, 0x4b, 0x4b, 0x4e, 0x21, + 0x9c, 0xaf, 0xce, 0xf0, 0x52, 0x41, 0x13, 0x87, 0x75, 0xc4, 0xd7, 0x34, + 0x0c, 0x2d, 0xfe, 0xc1, 0xb6, 0x60, 0x84, 0xd2, 0x57, 0xc2, 0xb2, 0x6c, + 0xa6, 0x97, 0x51, 0xea, 0x49, 0x07, 0x7d, 0xac, 0x15, 0x75, 0x71, 0x67, + 0x2c, 0xdf, 0x09, 0x0c, 0x63, 0x38, 0x6a, 0x25, 0xf3, 0x9b, 0x5d, 0x5d, + 0x63, 0xe7, 0x20, 0xa3, 0xf5, 0x6f, 0x8c, 0x77, 0x91, 0xb0, 0x6d, 0xad, + 0x01, 0x1d, 0x40, 0x65, 0xcd, 0x31, 0xbf, 0xb2, 0x0a, 0x1f, 0xf9, 0xb0, + 0x34, 0x7f, 0x6a, 0xfe, 0xca, 0x2e, 0x28, 0xc4, 0x5b, 0xdb, 0xa9, 0xd4, + 0xdc, 0xe6, 0x3a, 0x0a, 0xeb, 0xe2, 0xc5, 0xb8, 0xbe, 0xad, 0x8d, 0x7d, + 0xa2, 0x5e, 0x88, 0xad, 0xb8, 0xda, 0x41, 0x12, 0x1f, 0xc5, 0x85, 0xa1, + 0x83, 0x3d, 0xc7, 0xbb, 0x6d, 0x55, 0x63, 0xd0, 0x8b, 0x06, 0x76, 0x96, + 0xf5, 0x0b, 0xd9, 0x2f, 0x45, 0xf4, 0x9b, 0xc8, 0x18, 0xba, 0xbd, 0x30, + 0xdc, 0x4d, 0x47, 0xde, 0xbc, 0xc0, 0xc0, 0xca, 0x9f, 0xd7, 0xda, 0xcb, + 0xd8, 0xdd, 0x7e, 0x98, 0x25, 0xfd, 0x9f, 0xa4, 0x22, 0x5d, 0x4b, 0x63, + 0x1b, 0xfa, 0x78, 0xdb, 0x3d, 0x39, 0xcc, 0x26, 0x00, 0x70, 0x0e, 0xac, + 0xf7, 0x30, 0xc0, 0x8c, 0x97, 0xbe, 0x57, 0xeb, 0x1a, 0xc0, 0xfd, 0x4c, + 0x81, 0x69, 0x54, 0x1b, 0xd4, 0x8c, 0xb2, 0xe7, 0xf0, 0x5f, 0x0e, 0x46, + 0x95, 0x7a, 0x2b, 0x0c, 0x69, 0x37, 0x89, 0x45, 0x6a, 0xb2, 0x9f, 0xa8, + 0x99, 0xd2, 0x6c, 0xa0, 0x9d, 0xc0, 0x36, 0x65, 0x2f, 0x37, 0xe3, 0xc8, + 0xba, 0x4f, 0xd2, 0x4c, 0x69, 0x2e, 0x15, 0x2c, 0x92, 0x13, 0x44, 0x96, + 0xa5, 0xe9, 0x90, 0x24, 0x0a, 0x94, 0x44, 0x16, 0x6a, 0x8e, 0x4a, 0x7b, + 0xf4, 0x65, 0x41, 0xd0, 0x4e, 0xf3, 0xf2, 0x6d, 0x8e, 0xc0, 0x70, 0xdf, + 0x56, 0x2f, 0x11, 0x80, 0x03, 0x42, 0xb5, 0x9c, 0x59, 0xea, 0xe1, 0x2d, + 0xc7, 0xd1, 0x29, 0x4a, 0xce, 0x78, 0x83, 0x8f, 0x9b, 0xd4, 0x6b, 0x91, + 0xd8, 0x7b, 0xd1, 0x03, 0xc1, 0xe8, 0x84, 0xbc, 0xca, 0x64, 0xdd, 0xac, + 0xdd, 0x39, 0xaf, 0x7c, 0x5d, 0x7a, 0x5f, 0xc3, 0x8b, 0x0f, 0xd7, 0x18, + 0x43, 0x4a, 0x8e, 0x3f, 0x2f, 0x02, 0x91, 0xa2, 0xdc, 0x3e, 0x2c, 0x9c, + 0x3b, 0x3c, 0xe3, 0xd4, 0x9a, 0xb3, 0x59, 0x43, 0xd4, 0x75, 0x1c, 0x4b, + 0x0b, 0xad, 0x84, 0x2d, 0xbd, 0x05, 0x66, 0xdb, 0x0a, 0xda, 0x77, 0x75, + 0x46, 0x78, 0x99, 0x44, 0xdf, 0x12, 0x58, 0xa9, 0x3a, 0x5f, 0x04, 0x18, + 0x81, 0xa2, 0x2d, 0xcf, 0x9c, 0x35, 0x8d, 0x67, 0x73, 0x9e, 0x8d, 0xe4, + 0xc9, 0x9d, 0x15, 0x80, 0xe3, 0x36, 0xf9, 0xbd, 0xf2, 0x65, 0xb2, 0x10, + 0xa9, 0xe8, 0x2a, 0x03, 0x9d, 0x03, 0x11, 0xe5, 0xcc, 0x32, 0x12, 0xef, + 0xee, 0x22, 0xa3, 0x0c, 0x35, 0x28, 0xc0, 0x17, 0x9b, 0x43, 0x75, 0x5f, + 0x2c, 0xbf, 0xeb, 0xc4, 0xf2, 0xa0, 0x6e, 0xcb, 0x06, 0x1c, 0x5c, 0xd9, + 0xe8, 0x56, 0xaf, 0xe4, 0x2c, 0x6a, 0x8a, 0x9e, 0xea, 0x34, 0x60, 0x09, + 0x94, 0xe7, 0xb2, 0x50, 0x4b, 0xc9, 0xeb, 0xce, 0xd2, 0x7f, 0x1d, 0xc1, + 0x22, 0xe1, 0x71, 0x1f, 0xac, 0xb7, 0xb9, 0x5c, 0x8e, 0x44, 0xe9, 0x51, + 0x58, 0x5c, 0x0e, 0x12, 0x34, 0xb5, 0xab, 0xa1, 0x0d, 0xf1, 0xc6, 0x71, + 0xf0, 0x51, 0x6f, 0xa8, 0x72, 0xde, 0xad, 0x42, 0xe6, 0x39, 0x28, 0xb0, + 0x66, 0xf8, 0xcb, 0x09, 0xb2, 0x82, 0x5a, 0x02, 0x15, 0xca, 0x17, 0xa9, + 0x63, 0xd8, 0xac, 0x18, 0x49, 0xf7, 0xfa, 0x6d, 0xad, 0x3f, 0xf5, 0x2a, + 0xd2, 0x1a, 0x9e, 0x4f, 0xdc, 0xb1, 0xb5, 0x5b, 0x93, 0x59, 0x44, 0x72, + 0x0c, 0xf4, 0x7e, 0xe4, 0x62, 0x10, 0x64, 0xad, 0x2d, 0xb0, 0x2e, 0xcb, + 0xf8, 0xd9, 0xbb, 0xf9, 0xfc, 0xc5, 0xe1, 0x31, 0x6e, 0x0e, 0x8b, 0x12, + 0x62, 0x25, 0x92, 0xd6, 0xb0, 0x0d, 0x78, 0x7e, 0x03, 0x13, 0x65, 0xe0, + 0xa3, 0x5d, 0x33, 0xc7, 0x04, 0x8b, 0xe7, 0x45, 0xa8, 0x9f, 0xd1, 0x70, + 0x27, 0x32, 0x6e, 0x50, 0x48, 0x6a, 0xd3, 0x32, 0xcb, 0xca, 0xd5, 0xcd, + 0xd4, 0x0a, 0x76, 0x8e, 0x6b, 0xb1, 0x73, 0x68, 0x38, 0xf5, 0x73, 0xb2, + 0x46, 0x7a, 0xb5, 0xff, 0xea, 0x52, 0xc9, 0x5b, 0x56, 0xff, 0xf0, 0x35, + 0x4b, 0xae, 0x88, 0x61, 0x8a, 0x3c, 0xb9, 0x78, 0x1c, 0x51, 0xaa, 0x5d, + 0xaf, 0xe0, 0xe7, 0x8c, 0x03, 0x85, 0x6a, 0x1f, 0xca, 0xb9, 0x8c, 0xf4, + 0x37, 0xea, 0xae, 0x54, 0xf1, 0xb8, 0x4c, 0x94, 0x42, 0xcf, 0x2a, 0x8d, + 0x13, 0xef, 0x66, 0xf8, 0x1b, 0xbe, 0x5d, 0x9a, 0x24, 0x12, 0xb5, 0xe8, + 0xe8, 0x44, 0x6b, 0x95, 0xd6, 0xed, 0x98, 0xd8, 0x10, 0xeb, 0x19, 0xe5, + 0x42, 0x01, 0xaa, 0x1c, 0x6a, 0x62, 0xd2, 0xf0, 0xc3, 0x33, 0x4d, 0xf0, + 0x3e, 0x76, 0x8d, 0xec, 0xbb, 0xb9, 0xeb, 0x14, 0x77, 0x02, 0x39, 0xb7, + 0x75, 0x21, 0x3a, 0xa5, 0xef, 0x04, 0xb3, 0x20, 0x50, 0xaf, 0xed, 0x99, + 0x0b, 0xec, 0x12, 0x6d, 0xad, 0x9f, 0x23, 0x02, 0xc0, 0x01, 0x5a, 0xfe, + 0xfc, 0xee, 0xa9, 0xc1, 0x23, 0x51, 0x71, 0xb0, 0xe6, 0xee, 0xcc, 0xcd, + 0x6a, 0x59, 0xcf, 0xad, 0xff, 0x4b, 0x36, 0xbf, 0x2a, 0xaf, 0x56, 0xae, + 0xd7, 0x35, 0x47, 0xc4, 0x11, 0xef, 0x66, 0x18, 0xd1, 0xec, 0x2a, 0x5c, + 0xca, 0xfe, 0x8f, 0x8b, 0xa2, 0x80, 0x57, 0x42, 0xe5, 0xa5, 0xb4, 0x7a, + 0x34, 0xd0, 0x1b, 0xca, 0xb3, 0x7f, 0x2c, 0x54, 0x47, 0x50, 0xf0, 0xdd, + 0xde, 0x87, 0xc0, 0x8f, 0x3a, 0x79, 0x49, 0x50, 0xe9, 0x4a, 0xe2, 0x74, + 0x08, 0x18, 0x61, 0xaa, 0x17, 0xe4, 0x44, 0xdf, 0xeb, 0xf8, 0x2f, 0x5f, + 0x06, 0x19, 0x06, 0x13, 0xec, 0x14, 0x47, 0x04, 0x51, 0x03, 0x55, 0x62, + 0x78, 0x73, 0x7d, 0xe9, 0x15, 0xff, 0xd3, 0xb2, 0x5c, 0x54, 0x79, 0xca, + 0x58, 0x10, 0x86, 0x66, 0x4d, 0x6a, 0x73, 0x13, 0x20, 0x60, 0xd1, 0xaa, + 0x54, 0xa8, 0xf3, 0x45, 0x1c, 0x02, 0x23, 0xc6, 0x43, 0xee, 0xb4, 0xf4, + 0xed, 0xa3, 0x59, 0xb7, 0xb3, 0x4e, 0xda, 0xdf, 0x5f, 0x12, 0xed, 0xb0, + 0x03, 0x93, 0xc7, 0xb7, 0xa9, 0x52, 0xdb, 0x91, 0x39, 0x4f, 0x0d, 0x6d, + 0x31, 0x08, 0xf5, 0x91, 0x90, 0xe5, 0x11, 0xbf, 0x33, 0x4d, 0x3f, 0x7b, + 0xc8, 0x46, 0xbf, 0x8f, 0x27, 0x61, 0xc3, 0x6c, 0xea, 0xfa, 0xaf, 0xeb, + 0x92, 0xd1, 0x86, 0xb4, 0x50, 0x64, 0x6c, 0xba, 0xdf, 0x1f, 0xe9, 0xc6, + 0x2f, 0xad, 0x8d, 0x95, 0xe7, 0xfe, 0xcb, 0xbf, 0xcc, 0xba, 0xbd, 0xcc, + 0x62, 0x85, 0x62, 0x7a, 0x96, 0x85, 0x02, 0x1c, 0xc1, 0x8f, 0x4b, 0xfc, + 0x4f, 0xea, 0x69, 0x8b, 0x1c, 0x83, 0x81, 0x34, 0x15, 0x12, 0x16, 0x6f, + 0x9c, 0x0e, 0xa4, 0x83, 0xb6, 0x28, 0x2f, 0xd7, 0x6d, 0x2e, 0x98, 0x6a, + 0xe7, 0x6f, 0x53, 0x83, 0x18, 0x43, 0x75, 0x25, 0x97, 0x14, 0x15, 0x8d, + 0x2f, 0x7f, 0x72, 0x1a, 0x07, 0x42, 0x2a, 0x7a, 0xe4, 0x7e, 0xc4, 0x7a, + 0x6a, 0xc9, 0x0f, 0xeb, 0x4b, 0x60, 0x56, 0x15, 0x51, 0x23, 0x5d, 0xfa, + 0x0e, 0x56, 0x06, 0x35, 0x89, 0x89, 0x77, 0x55, 0xd3, 0xd7, 0x22, 0x2f, + 0x41, 0xc5, 0x70, 0x3f, 0x57, 0x80, 0xc6, 0xab, 0x30, 0x7e, 0xd8, 0x2b, + 0xd2, 0xd2, 0xa2, 0xfc, 0xf9, 0x32, 0x22, 0x9e, 0x63, 0x67, 0x8a, 0x55, + 0xac, 0x4e, 0x66, 0x98, 0xe6, 0x20, 0xea, 0xbd, 0x64, 0xe9, 0xd5, 0x06, + 0x33, 0x33, 0xbf, 0xe2, 0x89, 0x49, 0x91, 0x92, 0x4e, 0xf9, 0xcc, 0x23, + 0xad, 0x26, 0x1a, 0xb1, 0x01, 0x40, 0x9b, 0x3f, 0x30, 0x5c, 0x88, 0xaf, + 0xce, 0x83, 0xc3, 0x45, 0x90, 0xdc, 0xa6, 0x20, 0x3e, 0x15, 0x96, 0x25, + 0xdf, 0xe1, 0xa6, 0xd6, 0x78, 0xaf, 0xda, 0xc0, 0x0c, 0xf1, 0x21, 0x03, + 0xf9, 0x7f, 0xb5, 0xfd, 0x59, 0x20, 0x3d, 0x73, 0xad, 0xfb, 0x2b, 0x5f, + 0x88, 0xbc, 0x17, 0xaf, 0x1c, 0xaa, 0x5d, 0x17, 0x8f, 0xb7, 0x60, 0x9c, + 0xc7, 0xc4, 0xe4, 0xf4, 0xdb, 0xa9, 0x39, 0xb0, 0xd1, 0xb4, 0x6b, 0x4b, + 0x20, 0xaf, 0xd5, 0xcc, 0xd9, 0x68, 0x17, 0x4c, 0x9a, 0xd4, 0x35, 0x25, + 0x17, 0x3b, 0xc3, 0x41, 0x7b, 0x05, 0xe9, 0xe8, 0xdd, 0x02, 0x9d, 0x0f, + 0x6a, 0xd7, 0xf5, 0xfa, 0xae, 0xf2, 0x5b, 0xfe, 0xc4, 0x44, 0x62, 0xd6, + 0xc4, 0x8e, 0x4b, 0x28, 0x6a, 0x87, 0x3c, 0xe3, 0xf8, 0x01, 0xb5, 0xf9, + 0x77, 0x4e, 0x07, 0x8f, 0x40, 0x02, 0x72, 0x81, 0xa9, 0x6e, 0xa8, 0x84, + 0x1f, 0xfe, 0x2e, 0x06, 0x83, 0xb8, 0x14, 0x2b, 0xf8, 0x6e, 0x8b, 0xb2, + 0xed, 0xff, 0xc5, 0x90, 0x09, 0x86, 0xef, 0xe7, 0x64, 0xb3, 0x3f, 0x10, + 0xe1, 0x47, 0xff, 0x4f, 0xac, 0x76, 0x45, 0xa8, 0xba, 0xac, 0xab, 0x82, + 0x07, 0x86, 0x8a, 0x24, 0xf5, 0xc0, 0x01, 0x5f, 0x54, 0x8b, 0xdc, 0xbd, + 0xd6, 0x28, 0x05, 0x56, 0xfd, 0x13, 0xdf, 0x93, 0x9b, 0x68, 0x03, 0x90, + 0x2c, 0x08, 0xcc, 0x0b, 0xf9, 0x14, 0x44, 0x84, 0x79, 0x15, 0xab, 0xbc, + 0x54, 0x1b, 0x76, 0xe3, 0xfa, 0xf8, 0x32, 0xab, 0xf2, 0xcd, 0xed, 0x04, + 0x15, 0x94, 0xb4, 0xb3, 0xcc, 0x09, 0xf1, 0xb2, 0x35, 0x60, 0x0b, 0x05, + 0xa1, 0x31, 0xd6, 0x6d, 0xc6, 0x46, 0x6d, 0xe4, 0xe7, 0xbc, 0x5f, 0x3a, + 0x72, 0xfd, 0x42, 0xb0, 0x0e, 0xbb, 0xd2, 0xeb, 0x50, 0x26, 0x60, 0x38, + 0xd6, 0x96, 0x1b, 0x5b, 0x9d, 0xcc, 0xb4, 0x98, 0x9f, 0xe8, 0xf2, 0x95, + 0xa3, 0x11, 0x9a, 0xcb, 0x6d, 0x56, 0x87, 0x4b, 0x95, 0xb9, 0x41, 0xa3, + 0x89, 0x2d, 0x2c, 0x29, 0xe8, 0x29, 0x86, 0x47, 0x3e, 0x91, 0x2a, 0x59, + 0x7d, 0x9c, 0x03, 0x9d, 0x2d, 0xff, 0x05, 0x50, 0x21, 0x88, 0x12, 0x55, + 0x2b, 0x25, 0x0c, 0x0c, 0x59, 0xa9, 0x1f, 0xbd, 0x1c, 0xa0, 0xf9, 0xc2, + 0x23, 0x4b, 0xaa, 0xbe, 0x10, 0x4f, 0xf7, 0x5a, 0x25, 0x49, 0xb2, 0xc8, + 0xdc, 0xf7, 0xb1, 0x45, 0xdf, 0xbb, 0x15, 0xd9, 0x48, 0x49, 0x01, 0x27, + 0xf6, 0xdc, 0x59, 0x48, 0xb7, 0xd7, 0x5e, 0x46, 0xde, 0x2c, 0x27, 0x64, + 0xf9, 0xc2, 0xc5, 0x37, 0x21, 0x9a, 0xbf, 0x62, 0x14, 0xdd, 0x13, 0x26, + 0x9f, 0x62, 0x65, 0x55, 0xe8, 0xd7, 0x6f, 0x10, 0x5c, 0xd7, 0x19, 0x16, + 0x1b, 0x87, 0xd3, 0x74, 0xd2, 0x8a, 0x89, 0x15, 0x17, 0xd8, 0x83, 0x8f, + 0x3f, 0x38, 0x98, 0x9b, 0x25, 0x03, 0xc7, 0x7c, 0x35, 0x88, 0x53, 0x48, + 0xca, 0xd6, 0x4d, 0x20, 0x23, 0x54, 0x15, 0x51, 0xda, 0xfb, 0x7e, 0x41, + 0xbc, 0x88, 0xf5, 0x53, 0xf6, 0xe2, 0x54, 0xe6, 0xa8, 0xb1, 0x04, 0xac, + 0xd1, 0xd6, 0x37, 0xd2, 0xa9, 0x6f, 0x96, 0xc0, 0x6a, 0xb1, 0xd4, 0xcf, + 0x1e, 0xda, 0xda, 0x72, 0x43, 0xaa, 0x7b, 0x7d, 0x39, 0x19, 0x11, 0x06, + 0x2a, 0x73, 0x87, 0xe6, 0xdb, 0x8a, 0xcf, 0x66, 0xf2, 0x77, 0xc9, 0x0a, + 0xe2, 0x13, 0x90, 0xd6, 0x1b, 0xa6, 0xfb, 0xfd, 0xda, 0x63, 0x80, 0x81, + 0x55, 0x7a, 0x4b, 0xea, 0x79, 0x4d, 0xa9, 0x46, 0x2b, 0xb1, 0xa5, 0x98, + 0x8d, 0x34, 0x32, 0x07, 0xc6, 0xff, 0x98, 0x17, 0xd1, 0x55, 0x85, 0xc6, + 0x8d, 0x0a, 0x3b, 0x58, 0x1e, 0x82, 0x24, 0xa2, 0xef, 0x83, 0xed, 0xf6, + 0xe2, 0x79, 0x1b, 0x2b, 0x46, 0x7e, 0x94, 0x5b, 0xc8, 0x5a, 0x93, 0xef, + 0xca, 0x76, 0xc7, 0xef, 0x71, 0xce, 0x15, 0x33, 0x91, 0xef, 0x46, 0xa9, + 0x58, 0xd8, 0x6d, 0xa9, 0x47, 0x45, 0x35, 0xbb, 0xce, 0x96, 0xb7, 0x44, + 0xd4, 0x7a, 0x90, 0xd4, 0xcb, 0x18, 0xbc, 0x7b, 0x64, 0xf3, 0x8e, 0xf5, + 0xd5, 0xf7, 0x82, 0xdb, 0xff, 0xd6, 0x50, 0x17, 0xdf, 0x9a, 0x11, 0x75, + 0x85, 0x36, 0xc8, 0x0c, 0x44, 0xcc, 0xdc, 0x76, 0xfc, 0x9f, 0x3e, 0x84, + 0x8f, 0xea, 0xc6, 0xb1, 0xfa, 0x97, 0x75, 0x31, 0xe8, 0xc2, 0x81, 0x7b, + 0x39, 0x14, 0xad, 0xdf, 0x67, 0xf2, 0x44, 0xe0, 0xc4, 0x7a, 0x21, 0x63, + 0x74, 0x73, 0x41, 0xf4, 0xb5, 0xbd, 0x87, 0x36, 0xd0, 0x64, 0xb6, 0x8e, + 0x98, 0xd2, 0x79, 0x5f, 0x4d, 0x22, 0x8c, 0xc1, 0x41, 0x4c, 0xea, 0xb7, + 0xab, 0x4b, 0x2e, 0xca, 0x35, 0x14, 0xd3, 0x90, 0x9e, 0xd6, 0x94, 0x3e, + 0x7e, 0xe4, 0x57, 0x09, 0x22, 0x3c, 0xe6, 0xbe, 0x04, 0x95, 0x75, 0xf8, + 0xe0, 0x42, 0xe9, 0xe2, 0x5e, 0x2e, 0x2a, 0xc6, 0x48, 0x55, 0x42, 0x39, + 0xc4, 0x81, 0x6a, 0xc6, 0x19, 0xea, 0x4c, 0x63, 0x60, 0x11, 0xdf, 0xe7, + 0xde, 0x4d, 0x0f, 0xec, 0x0c, 0x8f, 0x21, 0xe7, 0x94, 0x72, 0x24, 0x4d, + 0xc0, 0x44, 0x30, 0x63, 0x18, 0x06, 0x9b, 0xb9, 0x63, 0xc2, 0x94, 0x6d, + 0x78, 0xba, 0x36, 0x58, 0xe3, 0x07, 0x0f, 0xd4, 0x16, 0xe5, 0xc7, 0x58, + 0xb1, 0x5e, 0x96, 0x25, 0x80, 0xc0, 0x0c, 0x4d, 0xf1, 0xda, 0x8b, 0xc6, + 0x66, 0x56, 0x1e, 0x7c, 0x64, 0x6b, 0x2c, 0xb2, 0x8c, 0xed, 0x07, 0xa7, + 0x52, 0x70, 0xbd, 0x68, 0xd3, 0x48, 0x18, 0x38, 0xa6, 0x60, 0x18, 0x97, + 0x4a, 0xd0, 0x88, 0xed, 0x4c, 0x99, 0xad, 0x88, 0x56, 0xec, 0x2b, 0xd7, + 0xb4, 0xd6, 0xc6, 0x43, 0x58, 0xf6, 0x9b, 0xfb, 0x28, 0xa7, 0xb4, 0xaa, + 0x61, 0xc4, 0x09, 0x0b, 0xa7, 0x51, 0x7a, 0xd3, 0x2f, 0x84, 0xeb, 0x9e, + 0xc9, 0xc9, 0xac, 0x7e, 0x80, 0x2e, 0xa6, 0x88, 0x84, 0xd2, 0x54, 0xca, + 0xe6, 0xf1, 0x7c, 0x97, 0x7c, 0x8a, 0x8a, 0x66, 0x7f, 0x00, 0x4b, 0x73, + 0x3f, 0x2e, 0xfb, 0xcc, 0xe5, 0x07, 0xe6, 0x4e, 0xa1, 0x8e, 0xfc, 0x62, + 0xb7, 0xd7, 0xbe, 0xa4, 0x4a, 0x65, 0xd7, 0xe2, 0xaa, 0x0c, 0xdd, 0x93, + 0x93, 0x63, 0x56, 0x46, 0xe5, 0xe5, 0xf5, 0x47, 0xb1, 0xe4, 0x4e, 0x60, + 0x97, 0x83, 0x82, 0x23, 0x84, 0x37, 0x20, 0xbd, 0xb5, 0x8b, 0x9d, 0x5d, + 0xc8, 0xca, 0xe1, 0xa8, 0x5a, 0xc4, 0xaa, 0xe2, 0x79, 0xda, 0x1d, 0x48, + 0x60, 0x4c, 0x2e, 0x06, 0x95, 0xb4, 0x76, 0x42, 0xa0, 0x6e, 0x52, 0x52, + 0x0f, 0xf8, 0x24, 0x81, 0x21, 0x6f, 0x67, 0x27, 0x9e, 0xe5, 0xf9, 0x9b, + 0x8c, 0x82, 0x90, 0x90, 0xdd, 0xe7, 0xd4, 0x24, 0x54, 0xa7, 0x26, 0x41, + 0xd2, 0x54, 0x50, 0x6a, 0x66, 0xf0, 0xd5, 0x68, 0xaf, 0xd1, 0xd2, 0x00, + 0x66, 0xa1, 0x9e, 0x1b, 0xab, 0xe6, 0x43, 0xa2, 0xb8, 0x05, 0x2f, 0xae, + 0x9b, 0xce, 0x15, 0xa2, 0x5b, 0xd1, 0xb5, 0x53, 0x66, 0x6e, 0xc9, 0x44, + 0x7b, 0x8c, 0x5d, 0x94, 0x63, 0x3c, 0xa5, 0xc5, 0x81, 0x48, 0xd7, 0x98, + 0x6b, 0xb7, 0xce, 0xe4, 0xd9, 0xaf, 0x1c, 0xa9, 0x76, 0x8c, 0x1b, 0x4b, + 0x5c, 0x1e, 0x9c, 0x98, 0xef, 0x74, 0x40, 0xe3, 0xf1, 0x48, 0x8c, 0x14, + 0x66, 0xe4, 0x7d, 0xbd, 0xff, 0xcf, 0xae, 0xf8, 0x36, 0x79, 0x83, 0x76, + 0xe7, 0x66, 0x36, 0x12, 0x60, 0x17, 0x2f, 0xb0, 0x2f, 0x22, 0x32, 0x4b, + 0x42, 0x65, 0xed, 0x76, 0x6e, 0x4c, 0x9d, 0xb9, 0x54, 0x9b, 0x98, 0x8b, + 0x79, 0x8b, 0x0e, 0xaf, 0x9c, 0x8c, 0xa9, 0x58, 0xaa, 0xa2, 0xde, 0x1a, + 0x9b, 0x6d, 0x75, 0x0f, 0xd2, 0xd4, 0x28, 0xdc, 0xca, 0xcd, 0x91, 0x66, + 0xd0, 0xd9, 0xab, 0x3c, 0x22, 0x55, 0x36, 0x87, 0x4f, 0x41, 0x24, 0x5c, + 0xee, 0x5a, 0x54, 0x1a, 0xe0, 0xf5, 0x2c, 0x01, 0x98, 0xa3, 0x54, 0x6e, + 0x6f, 0xdc, 0x88, 0xf7, 0x86, 0xba, 0xe2, 0x8d, 0x84, 0x95, 0x78, 0x84, + 0x8c, 0xc1, 0xae, 0x8c, 0x7f, 0xa7, 0x91, 0xbc, 0x6d, 0x3b, 0x48, 0x7a, + 0x42, 0xa0, 0xc0, 0x0a, 0xfe, 0xda, 0xbc, 0xe7, 0xa6, 0x76, 0xcb, 0xca, + 0x68, 0xb0, 0xda, 0xb3, 0x2e, 0x4c, 0x57, 0x50, 0xeb, 0xbb, 0x0a, 0x35, + 0x94, 0x80, 0xab, 0xcf, 0xa7, 0xdc, 0xab, 0x31, 0x54, 0xef, 0xe0, 0x77, + 0xa5, 0x7e, 0x9e, 0x76, 0x96, 0x62, 0x92, 0x25, 0xf1, 0xa1, 0xa5, 0x91, + 0x06, 0x9e, 0x2f, 0x81, 0xd8, 0x5f, 0x2e, 0xe4, 0xe8, 0xda, 0x9f, 0xe1, + 0x62, 0xe1, 0x30, 0xd0, 0x16, 0x02, 0xc6, 0xeb, 0x3a, 0x43, 0x4e, 0x64, + 0x07, 0x77, 0xf2, 0xda, 0x0d, 0xf5, 0xd3, 0x1c, 0x26, 0x4c, 0xcd, 0xa4, + 0xb3, 0xc5, 0xd6, 0x73, 0xb4, 0xbc, 0xc0, 0x07, 0x64, 0x98, 0xfb, 0xf6, + 0x32, 0xe4, 0xe1, 0xca, 0x74, 0x4c, 0x64, 0xad, 0x04, 0x53, 0x1b, 0x99, + 0x24, 0x7b, 0x2e, 0xd7, 0x3e, 0x07, 0xba, 0x7a, 0x08, 0x7b, 0xb1, 0xb0, + 0x11, 0x3f, 0x4e, 0x66, 0xd8, 0xa5, 0x4e, 0x72, 0x67, 0xa6, 0xbe, 0x38, + 0x76, 0xcf, 0x72, 0x07, 0x9a, 0x57, 0x2f, 0x29, 0x6d, 0x55, 0xcd, 0x69, + 0xed, 0xcf, 0x59, 0x5e, 0xd9, 0xe5, 0x29, 0x5b, 0xd0, 0x4d, 0x85, 0xea, + 0x44, 0x0c, 0xac, 0x2d, 0x76, 0x28, 0x65, 0x39, 0x2a, 0xfc, 0x9f, 0xe8, + 0xd8, 0xce, 0x5c, 0x56, 0xc0, 0x33, 0xa4, 0xcc, 0x32, 0xa6, 0x00, 0xd8, + 0x9d, 0x9d, 0x0a, 0x28, 0x27, 0x15, 0x42, 0x8e, 0xeb, 0xb0, 0xef, 0x6f, + 0xb8, 0x93, 0xe2, 0xdf, 0x6e, 0x17, 0x46, 0x67, 0x59, 0x05, 0x92, 0xad, + 0x87, 0xc6, 0x06, 0x35, 0xc8, 0x4c, 0x05, 0x1c, 0x9f, 0xf4, 0xa4, 0xa4, + 0xa1, 0x8d, 0x11, 0xc7, 0xab, 0x4b, 0x9b, 0x3a, 0x71, 0xcb, 0x2d, 0x1f, + 0xec, 0x61, 0xa0, 0x66, 0x5f, 0x3d, 0xa3, 0x95, 0x39, 0x7f, 0x98, 0x34, + 0x79, 0x32, 0x15, 0x94, 0xa0, 0x16, 0xa4, 0xf3, 0x45, 0x7b, 0x31, 0xfe, + 0xf2, 0xe3, 0x65, 0x01, 0xc1, 0xf7, 0xcd, 0xcb, 0x59, 0x52, 0xbb, 0xf6, + 0xa4, 0x12, 0x22, 0x9e, 0x5f, 0xd0, 0x50, 0x8a, 0x43, 0x62, 0xfd, 0x22, + 0x21, 0xfb, 0xae, 0x08, 0x57, 0xc7, 0x00, 0xa6, 0x48, 0x2e, 0xcb, 0x0b, + 0x76, 0x08, 0xf9, 0xd4, 0x14, 0x9a, 0xb5, 0xcd, 0xb8, 0x33, 0xc3, 0x0d, + 0x2a, 0x3a, 0xf0, 0xe2, 0x5f, 0x0e, 0x1f, 0xa1, 0x1c, 0x71, 0x38, 0x2e, + 0x8e, 0x93, 0x13, 0x27, 0xa2, 0x4a, 0xdc, 0x95, 0x1e, 0x26, 0x30, 0x5f, + 0xdd, 0xc4, 0x15, 0x8e, 0xa8, 0xfd, 0x80, 0xf4, 0x9e, 0x31, 0x80, 0xc9, + 0xa0, 0xf7, 0x61, 0xb5, 0x55, 0x40, 0xb4, 0x7f, 0xd8, 0xb2, 0x6b, 0x58, + 0xba, 0x34, 0xba, 0x78, 0xa0, 0xee, 0xa2, 0xc4, 0x73, 0x19, 0xc7, 0xdf, + 0x1b, 0x46, 0x3c, 0xe0, 0x7c, 0xb3, 0xf9, 0x7c, 0x35, 0xd5, 0xf0, 0xbf, + 0x2c, 0xed, 0xa4, 0x20, 0x95, 0x0b, 0x05, 0x7a, 0xce, 0xdc, 0x81, 0x95, + 0xf3, 0x12, 0x8a, 0x7f, 0xcb, 0xa8, 0xdc, 0x77, 0xbf, 0x8b, 0xdf, 0xf6, + 0xb0, 0xce, 0xce, 0x0b, 0xdf, 0xe9, 0xcf, 0x92, 0x02, 0x20, 0x82, 0x81, + 0x9c, 0x03, 0x72, 0xe8, 0x41, 0x6b, 0xbe, 0xb6, 0x87, 0x8b, 0xf9, 0x9e, + 0x49, 0x77, 0xc5, 0xcf, 0x73, 0x9d, 0xf6, 0x1c, 0x42, 0x7c, 0xa8, 0xbb, + 0xe3, 0x24, 0x70, 0x9f, 0xef, 0x28, 0xce, 0x45, 0x13, 0x13, 0x5f, 0xad, + 0x02, 0x2a, 0xb4, 0x14, 0x80, 0x66, 0xe1, 0x6b, 0x29, 0x72, 0x77, 0xa3, + 0x04, 0x36, 0x28, 0x8d, 0xc6, 0x39, 0xa3, 0x29, 0x59, 0xbf, 0x1e, 0x69, + 0xcc, 0x8f, 0x25, 0x28, 0xb8, 0x24, 0x7c, 0xea, 0xe9, 0x4c, 0x43, 0x6e, + 0x6c, 0x7b, 0x1d, 0x41, 0x7f, 0xd9, 0xd9, 0x59, 0x1e, 0x45, 0x76, 0xcc, + 0x26, 0x6e, 0xe1, 0x80, 0x73, 0x4d, 0x79, 0x3c, 0x5c, 0x1d, 0x78, 0xf3, + 0xf9, 0x75, 0x2c, 0x9d, 0x9d, 0x8e, 0x90, 0x23, 0xf3, 0xf9, 0xd7, 0x68, + 0x14, 0xf3, 0x09, 0x2f, 0xa1, 0x86, 0xb1, 0x9d, 0xe2, 0x3c, 0xd3, 0x16, + 0xc4, 0xdf, 0x7c, 0xcf, 0xc5, 0xf2, 0x3e, 0x67, 0x8b, 0xc8, 0x3e, 0x23, + 0x17, 0xbf, 0x75, 0x1e, 0xf3, 0x35, 0xee, 0x9f, 0x14, 0xae, 0xc1, 0x5b, + 0xe7, 0x92, 0x68, 0xb8, 0x0f, 0x95, 0x67, 0x1b, 0x55, 0xe7, 0x90, 0x6f, + 0x72, 0xa0, 0x78, 0xd2, 0x57, 0xca, 0x0a, 0x92, 0x62, 0x8d, 0x20, 0x52, + 0x84, 0xb3, 0xae, 0x8e, 0x22, 0x3d, 0x36, 0x3a, 0xfe, 0x68, 0x2d, 0x89, + 0x8f, 0x51, 0x5b, 0x87, 0x87, 0x21, 0x69, 0x1a, 0x90, 0x97, 0x9e, 0x2f, + 0x91, 0xae, 0x32, 0x17, 0x08, 0x0b, 0x3e, 0x65, 0x8a, 0xaa, 0x8e, 0xf3, + 0x7b, 0x43, 0xc4, 0x2d, 0x05, 0xac, 0x7a, 0xd9, 0x29, 0x41, 0xf8, 0x80, + 0x64, 0x99, 0x98, 0xc3, 0xb8, 0x4b, 0x4a, 0x4b, 0x48, 0x2a, 0xbd, 0x38, + 0x42, 0x3a, 0xf1, 0x67, 0x03, 0x1d, 0xd8, 0x00, 0x50, 0xc9, 0xce, 0x3a, + 0x34, 0xe5, 0xac, 0x5f, 0x36, 0x55, 0xf4, 0xf2, 0xa6, 0x09, 0x04, 0x20, + 0x64, 0x56, 0xa1, 0x15, 0x65, 0x4d, 0x07, 0x7e, 0x47, 0xf7, 0x34, 0x30, + 0x3a, 0xbe, 0x49, 0xc1, 0x75, 0xa3, 0x7d, 0xe5, 0x0e, 0xba, 0xdf, 0x81, + 0xc0, 0x94, 0xf8, 0xec, 0x1d, 0x81, 0x63, 0x48, 0x12, 0x16, 0x82, 0x12, + 0x8b, 0x2a, 0xf7, 0x6e, 0x23, 0xa4, 0x11, 0x8b, 0x70, 0xb3, 0x8a, 0xce, + 0xd0, 0xdf, 0xc4, 0x6f, 0x65, 0x01, 0xe4, 0x6e, 0x61, 0x58, 0x78, 0x2a, + 0x4b, 0x9a, 0x1b, 0x65, 0x94, 0xc4, 0xc5, 0x9d, 0x95, 0xc6, 0x12, 0x6f, + 0xfc, 0x8a, 0x5e, 0x7f, 0xc8, 0xbe, 0xa9, 0xf0, 0x65, 0xb9, 0xa7, 0xe5, + 0xa9, 0x39, 0xc3, 0x7a, 0x79, 0x05, 0x72, 0x77, 0x1f, 0xf7, 0x2b, 0x29, + 0xf5, 0xb9, 0xce, 0x20, 0x82, 0x01, 0x21, 0xa0, 0x0c, 0xd5, 0x7c, 0x7b, + 0xe5, 0x9a, 0xea, 0xdb, 0x71, 0xa6, 0xef, 0x57, 0xca, 0x0d, 0x55, 0x3e, + 0x3c, 0x9e, 0xac, 0x6c, 0x18, 0x4e, 0xe9, 0xc4, 0x67, 0x00, 0x1d, 0xc3, + 0xf6, 0x88, 0x9d, 0xd5, 0xb4, 0x1a, 0xa8, 0xde, 0xfa, 0x8c, 0xe8, 0xb5, + 0x8a, 0xec, 0x6c, 0x94, 0x62, 0x63, 0x00, 0xaf, 0x8a, 0x91, 0x4b, 0x1b, + 0x01, 0x90, 0x72, 0xa5, 0x0a, 0x03, 0x50, 0xc7, 0x0d, 0x66, 0xaf, 0xca, + 0xae, 0xe5, 0x7f, 0x00, 0x00, 0x02, 0xc6, 0x6d, 0x6f, 0x6f, 0x76, 0x00, + 0x00, 0x00, 0x6c, 0x6d, 0x76, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0x25, 0xb0, 0x80, 0x7c, 0x25, 0xb0, 0x80, 0x00, 0x00, 0x03, 0xe8, 0x00, + 0x00, 0x00, 0x54, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x01, 0xf1, 0x74, 0x72, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x5c, 0x74, + 0x6b, 0x68, 0x64, 0x00, 0x00, 0x00, 0x0f, 0x7c, 0x25, 0xb0, 0x80, 0x7c, + 0x25, 0xb0, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8d, 0x6d, 0x64, 0x69, 0x61, 0x00, + 0x00, 0x00, 0x20, 0x6d, 0x64, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0x25, 0xb0, 0x80, 0x7c, 0x25, 0xb0, 0x80, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x01, 0x55, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x68, + 0x64, 0x6c, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, + 0x69, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x01, 0x38, 0x6d, 0x69, 0x6e, 0x66, + 0x00, 0x00, 0x00, 0x14, 0x76, 0x6d, 0x68, 0x64, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, + 0x64, 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, 0x66, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, + 0x75, 0x72, 0x6c, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf8, + 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, 0x94, 0x73, 0x74, 0x73, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x84, + 0x61, 0x76, 0x63, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0xf0, 0x00, 0x48, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x2e, 0x61, 0x76, 0x63, 0x43, 0x01, 0x4d, 0x40, 0x0d, 0xff, 0xe1, + 0x00, 0x17, 0x67, 0x4d, 0x40, 0x0d, 0xab, 0x40, 0xa0, 0xfd, 0x80, 0x88, + 0x00, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0xc4, 0x78, 0xa1, + 0x55, 0x01, 0x00, 0x04, 0x68, 0xee, 0x32, 0xc8, 0x00, 0x00, 0x00, 0x18, + 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, + 0x73, 0x74, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x14, 0x73, 0x74, 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2f, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, + 0x73, 0x74, 0x63, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x61, 0x75, 0x64, 0x74, 0x61, + 0x00, 0x00, 0x00, 0x59, 0x6d, 0x65, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x22, 0x68, 0x64, 0x6c, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6d, 0x64, 0x69, 0x72, 0x61, 0x70, 0x70, 0x6c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2b, 0x69, 0x6c, 0x73, 0x74, 0x00, 0x00, 0x00, 0x23, 0xa9, 0x74, + 0x6f, 0x6f, 0x00, 0x00, 0x00, 0x1b, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x61, 0x76, 0x66, 0x35, 0x32, + 0x2e, 0x33, 0x32, 0x2e, 0x30 +}; + +void h264_get_video_data(const guchar **data, guint *size) +{ + *data = h264_clip; + *size = sizeof(h264_clip); +} diff --git a/tests/test-h264.h b/tests/test-h264.h new file mode 100644 index 0000000000..ee022985e1 --- /dev/null +++ b/tests/test-h264.h @@ -0,0 +1,28 @@ +/* + * test-h264.h - H.264 test data + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef TEST_H264_H +#define TEST_H264_H + +#include + +void h264_get_video_data(const guchar **data, guint *size); + +#endif /* TEST_H264_H */ diff --git a/tests/test-mpeg2.c b/tests/test-mpeg2.c new file mode 100644 index 0000000000..2817b30086 --- /dev/null +++ b/tests/test-mpeg2.c @@ -0,0 +1,1645 @@ +/* + * test-mpeg2.c - MPEG-2 test data + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "test-mpeg2.h" + +#define MPEG2_CLIP_WIDTH 320 +#define MPEG2_CLIP_HEIGHT 240 +#define MPEG2_CLIP_DATA_SIZE 19311 + +/* Data dump of a 320x240 MPEG-2 video clip (mpeg2.m2v), it has a single frame */ +static const guchar mpeg2_clip[MPEG2_CLIP_DATA_SIZE] = { + 0x00, 0x00, 0x01, 0xb3, 0x14, 0x00, 0xf0, 0x12, 0x07, 0x53, 0x23, 0x80, + 0x00, 0x00, 0x01, 0xb5, 0x14, 0x8a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xb5, 0x2b, 0x02, 0x02, 0x02, 0x05, 0x02, 0x07, 0x80, 0x00, 0x00, + 0x01, 0xb8, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, + 0xff, 0xf8, 0x00, 0x00, 0x01, 0xb5, 0x8f, 0xff, 0xf7, 0x5d, 0x80, 0x00, + 0x00, 0x01, 0x01, 0x43, 0xf8, 0x90, 0x03, 0xee, 0x36, 0xd4, 0x92, 0x85, + 0x86, 0x37, 0x48, 0x01, 0xb3, 0xf7, 0x9a, 0x1d, 0x5c, 0x38, 0xb1, 0x95, + 0xb9, 0x42, 0x43, 0xb2, 0xc2, 0x51, 0x24, 0x31, 0xb2, 0xed, 0x20, 0x73, + 0xd9, 0x08, 0xcc, 0x5b, 0xe2, 0x39, 0xbc, 0xdb, 0x12, 0xb7, 0x8c, 0x31, + 0xbf, 0x6c, 0x00, 0xc3, 0xeb, 0xc3, 0xd0, 0x6c, 0x3e, 0x16, 0xde, 0xa8, + 0x89, 0xf3, 0xc1, 0x17, 0xda, 0x5a, 0x4f, 0xca, 0xb0, 0x6b, 0x7c, 0x07, + 0xbb, 0x6c, 0x95, 0x8f, 0x74, 0x35, 0xaa, 0x45, 0x65, 0xb4, 0x35, 0xbf, + 0xd4, 0x22, 0xab, 0xfe, 0x80, 0x07, 0x7c, 0xed, 0x7a, 0x97, 0x2b, 0xaf, + 0x2f, 0x72, 0x64, 0x81, 0x86, 0x0f, 0x6f, 0x9a, 0x7b, 0x02, 0x10, 0x07, + 0x76, 0x2f, 0x01, 0x30, 0x01, 0x2d, 0x21, 0x37, 0x89, 0xbc, 0x74, 0x00, + 0xf4, 0xc3, 0x6b, 0xa4, 0x1f, 0x65, 0xa7, 0xb6, 0xff, 0x6d, 0x9f, 0x6f, + 0x6f, 0x77, 0xa8, 0x5b, 0xa7, 0x95, 0x90, 0x2e, 0x2b, 0x71, 0xec, 0x35, + 0xf4, 0x96, 0x92, 0x33, 0xa9, 0x92, 0x48, 0xdf, 0xcf, 0x50, 0x39, 0x13, + 0xd1, 0xbd, 0x25, 0x4f, 0xbe, 0x5b, 0x10, 0x25, 0x6e, 0x14, 0xdc, 0x5e, + 0xe0, 0x7b, 0x7a, 0x3d, 0x04, 0x2f, 0xf2, 0xb8, 0x84, 0x38, 0xdd, 0x16, + 0x94, 0xdb, 0x46, 0xfd, 0xdf, 0x3a, 0x00, 0x7a, 0xf9, 0x49, 0x45, 0xb7, + 0x52, 0xe9, 0x03, 0x9a, 0x4a, 0x40, 0xf8, 0x14, 0xdc, 0xa7, 0x4d, 0xf7, + 0xbc, 0x25, 0x04, 0xa0, 0x04, 0x2a, 0x81, 0x6d, 0xda, 0x36, 0x67, 0x1b, + 0xb8, 0x48, 0x96, 0xb7, 0x49, 0xea, 0xd9, 0x1c, 0x8d, 0xf8, 0xfb, 0x80, + 0x07, 0x50, 0x9c, 0x13, 0x43, 0xae, 0x94, 0x07, 0x36, 0xff, 0x8b, 0x00, + 0x1c, 0x8a, 0x35, 0x00, 0x20, 0x49, 0x40, 0xdb, 0x74, 0x05, 0x82, 0x10, + 0x03, 0xcd, 0x28, 0x29, 0x06, 0x56, 0xf1, 0x2f, 0xc0, 0x03, 0xd1, 0x22, + 0x26, 0xd0, 0x08, 0x0a, 0x03, 0x4d, 0x27, 0x37, 0x5d, 0x2f, 0x36, 0xb7, + 0xe9, 0xef, 0x7a, 0x00, 0xd0, 0x83, 0xe5, 0x14, 0x65, 0x8a, 0x62, 0xd9, + 0xe2, 0x31, 0xb8, 0x3e, 0xef, 0x15, 0xbd, 0xdc, 0xb8, 0xf4, 0xa3, 0x4a, + 0xb9, 0x36, 0x1c, 0xde, 0xe7, 0x41, 0x08, 0x01, 0xb8, 0x79, 0xe0, 0x11, + 0x4a, 0xbe, 0x07, 0xca, 0xdf, 0x2d, 0xea, 0x5d, 0x11, 0x99, 0xb0, 0x2c, + 0x3a, 0x6e, 0x41, 0xaa, 0x5b, 0x23, 0xf2, 0xb5, 0x5a, 0x41, 0xcd, 0xd8, + 0x42, 0xad, 0xf7, 0x78, 0xc8, 0x2d, 0xdc, 0x51, 0x70, 0x72, 0xcc, 0xd8, + 0xb4, 0x75, 0x85, 0x43, 0x94, 0x25, 0xbd, 0x5e, 0xf9, 0x3c, 0x49, 0xbc, + 0xe5, 0xa3, 0x2b, 0xb8, 0x49, 0x0a, 0x26, 0xd2, 0xa7, 0xea, 0x8d, 0xfd, + 0xb1, 0xf7, 0xdd, 0x22, 0x8b, 0xef, 0xce, 0x5a, 0x51, 0x66, 0x64, 0x33, + 0x8a, 0x85, 0x53, 0xc0, 0x7b, 0x51, 0x22, 0x34, 0xe8, 0xd7, 0xd0, 0x09, + 0x8f, 0x5a, 0x53, 0xb8, 0x54, 0x1b, 0x4b, 0x2c, 0xbb, 0xaa, 0x18, 0xd5, + 0x69, 0x6d, 0xd2, 0xfa, 0xba, 0x5b, 0x7c, 0x67, 0xc9, 0x37, 0x51, 0x02, + 0x37, 0x8a, 0x6a, 0xec, 0x2b, 0x03, 0x94, 0xe4, 0x1e, 0xad, 0xce, 0x96, + 0x95, 0x84, 0x34, 0x5a, 0x38, 0x63, 0x58, 0x90, 0x44, 0x0e, 0xa1, 0x35, + 0xf4, 0xa0, 0xf3, 0xe1, 0x55, 0x0a, 0x46, 0x12, 0x5b, 0x93, 0x2c, 0x0c, + 0x95, 0x51, 0x62, 0x94, 0x34, 0x34, 0x2d, 0xaa, 0x36, 0x8d, 0xf3, 0xbb, + 0x0e, 0xe3, 0x37, 0x54, 0x02, 0x32, 0x83, 0x29, 0xd0, 0xea, 0xce, 0x7e, + 0x95, 0x3c, 0x26, 0x9a, 0xd0, 0xcb, 0x9c, 0xba, 0xa8, 0x49, 0x8e, 0x2d, + 0x68, 0x4d, 0x65, 0xa9, 0xaa, 0x05, 0xb2, 0x8c, 0x37, 0xe9, 0x5e, 0xfc, + 0x00, 0x7a, 0xe7, 0x4e, 0x1e, 0xa3, 0xe5, 0x9b, 0xb9, 0x42, 0x52, 0xc3, + 0xe3, 0x3f, 0x3f, 0x39, 0x86, 0x59, 0xb8, 0x80, 0x2a, 0xa9, 0x65, 0x3d, + 0xa9, 0xd4, 0xfb, 0xf4, 0xf9, 0x65, 0x1e, 0xa9, 0x62, 0x6c, 0x18, 0x30, + 0xf8, 0xdb, 0x5f, 0xb7, 0x8e, 0xde, 0xe7, 0x1b, 0xe2, 0x84, 0xc0, 0x86, + 0xe3, 0x71, 0x37, 0x0a, 0x0b, 0x29, 0xbc, 0xe4, 0x33, 0x31, 0xbd, 0x1c, + 0xf3, 0x40, 0x1e, 0xee, 0x3b, 0x4c, 0x5f, 0xd0, 0x21, 0x00, 0x36, 0x96, + 0x3c, 0x7b, 0x76, 0xbd, 0xe9, 0xb5, 0xfd, 0x74, 0x81, 0xb6, 0xba, 0xdc, + 0x25, 0x14, 0xde, 0x6f, 0xda, 0x80, 0x1f, 0xa4, 0xf3, 0x08, 0x0b, 0x38, + 0x68, 0x6b, 0x75, 0x48, 0xdc, 0x52, 0x27, 0x1e, 0xf6, 0xa8, 0x0a, 0xaf, + 0x91, 0xb9, 0x68, 0x48, 0x67, 0x8b, 0x70, 0xf7, 0xc7, 0x96, 0x3a, 0x5f, + 0x59, 0x22, 0x59, 0xe2, 0xdc, 0xd7, 0x0c, 0xb9, 0x40, 0x07, 0xad, 0xf0, + 0x7e, 0x82, 0x74, 0x8c, 0x01, 0x6a, 0xe9, 0x63, 0x75, 0xcf, 0x59, 0x43, + 0xa1, 0x92, 0x04, 0x37, 0x86, 0xe2, 0xa5, 0x74, 0x50, 0x90, 0x1c, 0x43, + 0x3c, 0x6d, 0xf0, 0x18, 0xdb, 0xf6, 0xce, 0x24, 0x28, 0x29, 0xb9, 0xb4, + 0xac, 0xc0, 0x29, 0xbd, 0x2d, 0xab, 0xb6, 0xa3, 0x6a, 0xdf, 0xa6, 0x8e, + 0x73, 0xc5, 0xbb, 0x99, 0x90, 0x04, 0x66, 0x17, 0xea, 0xa7, 0xb7, 0xa5, + 0xe4, 0xa7, 0x6e, 0x69, 0x41, 0xbf, 0x9a, 0x60, 0xf3, 0xe0, 0xc6, 0x41, + 0x74, 0x02, 0xbe, 0x38, 0x7e, 0x50, 0x4a, 0xff, 0xd9, 0x2d, 0x0d, 0x29, + 0x7c, 0x1b, 0xaa, 0x27, 0x5c, 0x00, 0xdb, 0xfa, 0x20, 0x5b, 0xe2, 0x52, + 0xe5, 0x8f, 0x11, 0xa6, 0xd8, 0x58, 0x6a, 0x52, 0x15, 0x6d, 0x0b, 0xb5, + 0x40, 0xb6, 0x4d, 0xf0, 0x35, 0xb3, 0x76, 0xfa, 0xfe, 0x4b, 0xd0, 0x08, + 0x31, 0xb4, 0x40, 0x1a, 0xab, 0x62, 0x80, 0x84, 0x01, 0x35, 0xe0, 0x9b, + 0xff, 0xb2, 0x12, 0x19, 0x53, 0x94, 0x96, 0xd2, 0xdd, 0xbb, 0x0a, 0x66, + 0xd0, 0x1a, 0x36, 0x21, 0x40, 0x85, 0xff, 0x1b, 0x8f, 0x9e, 0xa6, 0x2a, + 0xb7, 0x75, 0xe3, 0x09, 0x0d, 0xb4, 0x18, 0xd4, 0xdd, 0xaf, 0x0e, 0x70, + 0xba, 0x4a, 0x56, 0xe5, 0x11, 0x4f, 0x95, 0x28, 0x0a, 0xa8, 0xc6, 0xf4, + 0x77, 0xf3, 0x79, 0x52, 0x4b, 0x4a, 0x5a, 0xb7, 0x3e, 0x7e, 0x6d, 0x24, + 0x23, 0x44, 0x2d, 0x5b, 0xc2, 0x2d, 0x76, 0x6d, 0xa4, 0x3a, 0xdd, 0x61, + 0x30, 0x00, 0xfe, 0x61, 0x26, 0x46, 0xfa, 0x10, 0x03, 0xf2, 0x2e, 0x00, + 0x16, 0xfd, 0xb1, 0xfe, 0xdb, 0x32, 0x95, 0xa5, 0x08, 0xaf, 0x9c, 0xc1, + 0xc5, 0x28, 0x6b, 0x7a, 0x80, 0x02, 0xd1, 0x16, 0xfb, 0xbc, 0x56, 0xe0, + 0x5e, 0x8f, 0x75, 0x0d, 0x81, 0xac, 0x13, 0x21, 0xa4, 0x8a, 0x48, 0x63, + 0x62, 0x42, 0xe3, 0x7e, 0xc1, 0xe0, 0x0f, 0xf9, 0x00, 0x72, 0x28, 0x4d, + 0x14, 0xfb, 0x92, 0x1d, 0x8e, 0xb6, 0xa6, 0x58, 0x5d, 0xf4, 0xac, 0x7e, + 0x40, 0x15, 0x80, 0x19, 0x7b, 0x3d, 0xf3, 0x65, 0xc2, 0xa7, 0x2e, 0xc3, + 0xee, 0xc5, 0x28, 0xe6, 0x4f, 0xf8, 0xbf, 0x6f, 0x97, 0x0b, 0xe3, 0xae, + 0xf5, 0x4a, 0x2f, 0x69, 0x61, 0x63, 0x5b, 0xb6, 0x46, 0x00, 0x63, 0x74, + 0x4a, 0xdc, 0xd7, 0xe5, 0x4c, 0x42, 0xdb, 0x1d, 0xe3, 0x7b, 0xa4, 0xd7, + 0x8d, 0x28, 0x32, 0x35, 0x99, 0x75, 0x4b, 0x78, 0x64, 0x0c, 0x8d, 0xfc, + 0xa0, 0x00, 0x9c, 0x59, 0x10, 0x89, 0x79, 0x77, 0xc8, 0xa7, 0x95, 0x0d, + 0xc7, 0x96, 0x51, 0x87, 0xc5, 0xad, 0x84, 0x01, 0x1b, 0xaf, 0xdc, 0x40, + 0xa1, 0x79, 0xce, 0x52, 0xe5, 0x93, 0x1e, 0x56, 0x55, 0x01, 0xec, 0xf5, + 0x6f, 0xd0, 0xa4, 0x6f, 0xe8, 0x01, 0xef, 0xc4, 0xde, 0x49, 0xef, 0x5b, + 0x36, 0x6c, 0x3a, 0xa5, 0x2e, 0x56, 0xee, 0xdd, 0x98, 0x62, 0x5a, 0x15, + 0xb4, 0xb4, 0x6e, 0xfd, 0x44, 0x21, 0x96, 0x31, 0xba, 0x1f, 0x62, 0x20, + 0x0f, 0x98, 0x00, 0x00, 0x01, 0x02, 0x43, 0xf8, 0x37, 0x13, 0x05, 0xdd, + 0xbe, 0xa9, 0x4b, 0x6c, 0xa2, 0xbc, 0xc5, 0x6e, 0x6c, 0x21, 0x12, 0x23, + 0x77, 0x3e, 0x68, 0x05, 0xa2, 0xdf, 0x8e, 0xcf, 0x02, 0xe1, 0x60, 0x73, + 0x79, 0x09, 0x08, 0x0e, 0x74, 0x25, 0x49, 0x1b, 0xcc, 0x42, 0xca, 0x21, + 0xb7, 0x90, 0xdf, 0x40, 0x10, 0xff, 0xe7, 0x1d, 0x2e, 0x92, 0x59, 0x94, + 0x80, 0x94, 0xbf, 0x16, 0xe7, 0xdc, 0x34, 0xb6, 0xd7, 0xb0, 0xd9, 0x2d, + 0x50, 0x81, 0xc5, 0x35, 0x0f, 0x6a, 0x6f, 0xd4, 0xea, 0xfd, 0x5e, 0xa0, + 0x03, 0x0a, 0xad, 0xc9, 0xee, 0x5f, 0x8e, 0x78, 0xb2, 0xc0, 0xc0, 0xe2, + 0xbd, 0x4a, 0x46, 0xd5, 0xed, 0x27, 0x2e, 0xe1, 0xea, 0x13, 0x76, 0xd1, + 0xc1, 0x65, 0x90, 0x99, 0xb6, 0x00, 0x1a, 0x24, 0x9e, 0x12, 0x87, 0xc8, + 0x14, 0x96, 0x10, 0xda, 0x60, 0x74, 0xd0, 0x2d, 0x85, 0x30, 0xaa, 0xdf, + 0x15, 0xff, 0x9c, 0x02, 0xaa, 0x36, 0xdb, 0x2d, 0xdb, 0x9b, 0xa0, 0x10, + 0xc4, 0x94, 0x87, 0x1b, 0x3e, 0x02, 0x17, 0xfc, 0x6b, 0x88, 0x70, 0xf4, + 0x21, 0x37, 0x7c, 0x5c, 0x9c, 0xba, 0xda, 0xac, 0x13, 0x59, 0x1f, 0x1b, + 0xca, 0x2b, 0x30, 0x5e, 0xe3, 0xa2, 0x78, 0xd0, 0xe2, 0x43, 0x7b, 0x87, + 0x53, 0x70, 0xbc, 0xa1, 0xb0, 0xf8, 0x12, 0xde, 0x44, 0x01, 0xf8, 0xaa, + 0x94, 0xf9, 0x43, 0x71, 0x51, 0xb4, 0x3f, 0x20, 0x9e, 0x6c, 0x49, 0x03, + 0x75, 0x76, 0x86, 0x42, 0x96, 0x95, 0x2b, 0x5a, 0x07, 0xb6, 0xfc, 0x97, + 0x8d, 0xfa, 0x7f, 0xa3, 0xcd, 0x91, 0xe6, 0x78, 0xc2, 0xc2, 0x5b, 0x77, + 0x7b, 0x48, 0xf6, 0x3d, 0x03, 0x21, 0xbd, 0x62, 0x58, 0x16, 0xb1, 0xbc, + 0xdc, 0xe7, 0xce, 0x77, 0x2b, 0xf4, 0x05, 0x7d, 0x29, 0x30, 0x69, 0xf2, + 0x37, 0x55, 0xd8, 0x00, 0x73, 0x3b, 0x89, 0x02, 0xad, 0x2c, 0x84, 0x3d, + 0xb0, 0x43, 0x25, 0x6c, 0x2c, 0x4a, 0xab, 0xe8, 0xde, 0x7d, 0xe3, 0x40, + 0x1d, 0x3f, 0xb7, 0x89, 0x90, 0x35, 0x1d, 0x76, 0xa8, 0xd2, 0x6c, 0x2d, + 0x28, 0x5b, 0x78, 0xb7, 0xf3, 0x7e, 0x57, 0xcc, 0x22, 0x49, 0xdd, 0x2a, + 0xa0, 0xd2, 0x83, 0x29, 0x6d, 0xf6, 0x3d, 0xbe, 0x73, 0x1c, 0x80, 0x10, + 0x45, 0x25, 0xa9, 0x5e, 0xad, 0xe0, 0xc5, 0xf2, 0x00, 0x70, 0x27, 0x84, + 0xd8, 0xa7, 0xee, 0xee, 0x59, 0x9b, 0x83, 0x40, 0x79, 0x22, 0xb5, 0x38, + 0x0c, 0xc5, 0x6e, 0x8c, 0xa0, 0x16, 0x87, 0x90, 0xa3, 0x6f, 0xed, 0x2f, + 0x0f, 0xf3, 0x59, 0x20, 0x13, 0x0f, 0x2d, 0x4e, 0x0a, 0x30, 0x39, 0x84, + 0xd3, 0x69, 0x8b, 0x92, 0x04, 0x17, 0x8e, 0x81, 0x1b, 0x15, 0x6e, 0x8e, + 0x29, 0xb8, 0x9c, 0x39, 0x53, 0x12, 0x5a, 0x51, 0x65, 0x42, 0xa4, 0x2b, + 0xd2, 0x9c, 0xdb, 0x38, 0x9e, 0x7a, 0x8b, 0x42, 0x4b, 0x2c, 0x30, 0xe4, + 0x6e, 0x88, 0x53, 0x7a, 0x27, 0xc6, 0xf0, 0xe8, 0x21, 0x00, 0x45, 0x28, + 0x92, 0xb5, 0x46, 0x1e, 0x7b, 0x64, 0x32, 0x6c, 0x9e, 0x31, 0x15, 0x15, + 0xb7, 0xe1, 0x68, 0x52, 0x80, 0x8a, 0xd1, 0xcd, 0xa2, 0x6d, 0xe6, 0x3f, + 0x65, 0xaa, 0x33, 0x0a, 0xc9, 0x12, 0x05, 0xa8, 0xd0, 0x86, 0x6c, 0x37, + 0xc6, 0xd8, 0x85, 0x94, 0x07, 0x36, 0x7e, 0xad, 0xeb, 0x92, 0x45, 0x2d, + 0xb6, 0x69, 0x99, 0xb8, 0x50, 0x16, 0xdc, 0x30, 0x43, 0x00, 0x77, 0x3a, + 0x80, 0x0c, 0x59, 0x1c, 0xd9, 0xcf, 0xc6, 0xd6, 0xf4, 0x11, 0xb0, 0x00, + 0xf4, 0x5e, 0x15, 0xe2, 0x91, 0x07, 0xb7, 0xad, 0xc9, 0x99, 0xed, 0x53, + 0x03, 0x22, 0xea, 0xcb, 0x40, 0x44, 0x3c, 0x73, 0x78, 0x31, 0x91, 0xbd, + 0x75, 0x04, 0x2f, 0xf7, 0xde, 0xc9, 0x20, 0x73, 0x61, 0x69, 0xcd, 0x82, + 0x90, 0x7c, 0x90, 0x86, 0xdd, 0x32, 0x25, 0x75, 0xd9, 0x03, 0x10, 0xec, + 0xb7, 0xc0, 0x73, 0x74, 0x76, 0x65, 0xce, 0x6c, 0xd0, 0x83, 0x65, 0x90, + 0x34, 0x7b, 0x70, 0xdc, 0x1d, 0xe6, 0x70, 0x46, 0x4c, 0xe0, 0xaf, 0x1a, + 0xdd, 0xcd, 0x04, 0x20, 0x08, 0xda, 0x62, 0x04, 0xaa, 0xcf, 0x45, 0x52, + 0x4b, 0x68, 0x37, 0x21, 0x21, 0xb6, 0xda, 0x01, 0x52, 0xe1, 0x0a, 0x96, + 0xdf, 0x21, 0x7c, 0x8f, 0xf5, 0x8d, 0x6f, 0x60, 0x85, 0xfe, 0x0e, 0x11, + 0x08, 0x66, 0xd2, 0x11, 0x4b, 0x58, 0x6c, 0xa9, 0x55, 0xbd, 0x08, 0xb9, + 0x48, 0xbd, 0xd3, 0x82, 0x90, 0xc8, 0x07, 0xb6, 0x81, 0xad, 0xe7, 0x37, + 0xd0, 0xa5, 0x18, 0x07, 0x36, 0x5e, 0x4a, 0x76, 0x72, 0x42, 0xbe, 0x44, + 0xb6, 0xd6, 0x8a, 0x8c, 0xbc, 0xda, 0xf7, 0x3a, 0xe6, 0x50, 0xbc, 0xa9, + 0xe8, 0x74, 0xa4, 0xb6, 0x89, 0xf8, 0xad, 0x03, 0x5b, 0xa3, 0x98, 0x96, + 0x69, 0x25, 0x5a, 0xc2, 0x3a, 0x8a, 0xc3, 0x70, 0xa1, 0xf1, 0x1e, 0x9b, + 0x21, 0xc1, 0x95, 0xae, 0xae, 0x27, 0x79, 0x4b, 0x09, 0x11, 0xba, 0xe4, + 0x6c, 0x00, 0xb3, 0xaf, 0x32, 0x6d, 0x1c, 0x41, 0xf3, 0x96, 0x58, 0x01, + 0xfb, 0x73, 0x3a, 0xc4, 0x90, 0x96, 0x48, 0x60, 0xf9, 0x63, 0x7e, 0x28, + 0x8b, 0x28, 0x9e, 0xa6, 0x1b, 0x03, 0x15, 0x64, 0x41, 0xad, 0xec, 0xbe, + 0x5d, 0xaf, 0x15, 0x9a, 0xfc, 0x81, 0xb7, 0x0e, 0xa9, 0xea, 0xd9, 0xba, + 0xcb, 0x61, 0xa5, 0xd0, 0xc5, 0x1c, 0xde, 0x87, 0xcf, 0x8f, 0xed, 0x11, + 0x98, 0x2f, 0x29, 0x69, 0x70, 0x02, 0xb7, 0xe4, 0x85, 0xcf, 0x05, 0xa3, + 0x1a, 0xf2, 0x17, 0x11, 0x93, 0x7d, 0xb0, 0x06, 0x7b, 0x99, 0xa4, 0x7e, + 0xa9, 0x03, 0x99, 0x2a, 0x79, 0xc7, 0x3f, 0x52, 0xde, 0x29, 0x94, 0xa5, + 0x8a, 0x4b, 0x8d, 0xe3, 0xdf, 0xf9, 0x6f, 0xba, 0x80, 0x3d, 0x15, 0xfe, + 0x00, 0x7d, 0x9e, 0xfc, 0x7b, 0x91, 0x93, 0x62, 0xe9, 0x3f, 0x9c, 0xcf, + 0x27, 0x07, 0xdb, 0x46, 0x16, 0x5a, 0xc6, 0xe2, 0x8b, 0xfb, 0xe8, 0x02, + 0x37, 0x88, 0x77, 0xc4, 0x1c, 0x95, 0x64, 0xaf, 0xde, 0x6c, 0xf2, 0x85, + 0x41, 0xc5, 0xb2, 0xb6, 0x57, 0xcb, 0x28, 0xf4, 0x89, 0x19, 0xd1, 0x96, + 0x50, 0xa6, 0xfc, 0xf7, 0xfc, 0x53, 0xfd, 0xc8, 0xf9, 0x9c, 0x3e, 0x06, + 0x27, 0x39, 0x78, 0xd4, 0x01, 0x5c, 0xa8, 0xa7, 0x0e, 0x6f, 0xd4, 0x42, + 0x01, 0x0b, 0xfc, 0xfe, 0x04, 0xb8, 0x84, 0xf9, 0x6c, 0xf0, 0x2c, 0xa6, + 0xc9, 0xfd, 0xdb, 0xfe, 0xfa, 0x72, 0xb6, 0x84, 0x38, 0xd4, 0x7f, 0xa8, + 0xea, 0xda, 0x44, 0xe0, 0x01, 0x9f, 0xb8, 0xbd, 0x72, 0x86, 0x99, 0x52, + 0x42, 0x14, 0x6e, 0xbd, 0x86, 0xee, 0x12, 0xe4, 0x6e, 0xbd, 0x86, 0xee, + 0x12, 0xe4, 0x6e, 0x90, 0x07, 0xbe, 0xfd, 0xf3, 0xcc, 0x86, 0x3e, 0xd4, + 0x92, 0x01, 0x87, 0x64, 0x5f, 0x16, 0xe9, 0x09, 0xef, 0x9d, 0x7d, 0xb6, + 0xbf, 0x68, 0xd5, 0x6d, 0x6d, 0xe0, 0x80, 0x14, 0x68, 0x20, 0x80, 0xaf, + 0xde, 0x73, 0xce, 0x50, 0xc9, 0xc4, 0x3b, 0x68, 0xcf, 0x46, 0xdd, 0x4b, + 0x3d, 0xb5, 0x54, 0xdb, 0x1b, 0xe7, 0x00, 0x3d, 0xfa, 0x40, 0x07, 0x8f, + 0xc7, 0x11, 0xf1, 0x5e, 0x55, 0x5a, 0xe7, 0x47, 0x47, 0xe4, 0x9e, 0x6a, + 0x88, 0x10, 0xdf, 0x17, 0x11, 0xf1, 0x84, 0x6b, 0xd0, 0x05, 0x84, 0xe9, + 0x3f, 0x44, 0xe9, 0x62, 0x5c, 0x1a, 0xdf, 0x4e, 0x00, 0x78, 0x00, 0xbb, + 0xb1, 0x3d, 0x63, 0x9f, 0xc6, 0x3e, 0x9a, 0xb2, 0xed, 0x19, 0xb1, 0xb1, + 0x00, 0x39, 0x00, 0x71, 0xf2, 0x00, 0xe0, 0x01, 0x97, 0x4e, 0xce, 0xf9, + 0xcd, 0xc8, 0x31, 0xf6, 0xea, 0x24, 0x31, 0xa0, 0xe8, 0xdc, 0xd4, 0xac, + 0x2e, 0xc6, 0x00, 0x00, 0x01, 0x03, 0x43, 0xf9, 0x6d, 0x84, 0xef, 0x3a, + 0x09, 0x80, 0x07, 0x34, 0x90, 0xde, 0x07, 0x7f, 0x39, 0x63, 0x7b, 0xb7, + 0x1b, 0xc6, 0xf3, 0x32, 0xc0, 0x8d, 0xe0, 0xbb, 0x14, 0x2a, 0x56, 0xf2, + 0x02, 0xdc, 0x4f, 0xe5, 0xf3, 0x3c, 0x7c, 0xdc, 0x5a, 0x1c, 0x7a, 0x37, + 0x04, 0xa6, 0x48, 0xad, 0xe3, 0xa1, 0x6d, 0xd7, 0x6d, 0x55, 0x38, 0x32, + 0x35, 0x87, 0xed, 0x02, 0x9b, 0x47, 0x21, 0xeb, 0x93, 0xd6, 0x56, 0xae, + 0x97, 0x24, 0x9b, 0xe2, 0x35, 0xb3, 0x83, 0x99, 0x46, 0xdd, 0xf0, 0x00, + 0xec, 0x80, 0x58, 0x51, 0xb0, 0x0a, 0x56, 0x5f, 0x6b, 0x05, 0x70, 0x2b, + 0x22, 0x00, 0x8f, 0x82, 0xc9, 0x76, 0xd2, 0x5b, 0x50, 0xe8, 0x64, 0x8b, + 0x42, 0x5b, 0x15, 0x0e, 0xad, 0x9c, 0x39, 0xae, 0x0d, 0x6d, 0xf1, 0x73, + 0x12, 0xdf, 0x4b, 0x0e, 0x09, 0x6f, 0x46, 0xec, 0x00, 0x3d, 0x8f, 0xe0, + 0xa0, 0xb5, 0x59, 0xe0, 0xde, 0x6e, 0xfe, 0x4d, 0x00, 0x18, 0x37, 0xd0, + 0x7b, 0x04, 0x2f, 0xf0, 0x7f, 0xb9, 0x94, 0x00, 0x68, 0x9e, 0xa9, 0x1b, + 0x40, 0x1c, 0xc0, 0x3d, 0x90, 0xd6, 0xec, 0x10, 0x9c, 0xe9, 0x44, 0x35, + 0x6e, 0x57, 0xb3, 0xed, 0xe7, 0x5d, 0xb1, 0xc0, 0x3d, 0x0e, 0xbd, 0x59, + 0xe8, 0x85, 0xaf, 0x83, 0x72, 0xb7, 0x1d, 0x9d, 0xbb, 0xcb, 0x8a, 0x1a, + 0x6c, 0x3f, 0x10, 0xf1, 0x8a, 0xb5, 0xae, 0x15, 0x8f, 0x17, 0xcf, 0x2f, + 0x2c, 0x31, 0x66, 0x15, 0x1b, 0x48, 0x54, 0x29, 0xb7, 0x71, 0x75, 0xbe, + 0xbb, 0x9f, 0xbd, 0x8a, 0x99, 0x29, 0xc3, 0x9f, 0x90, 0xaa, 0x36, 0x9d, + 0x47, 0xb7, 0xb2, 0xe7, 0x1d, 0xf3, 0x1d, 0x90, 0xf3, 0xcd, 0xe6, 0x5b, + 0x43, 0x46, 0x0d, 0x6f, 0x9a, 0x13, 0x76, 0x90, 0xed, 0xa1, 0xf6, 0xb7, + 0xbe, 0x70, 0x21, 0x7f, 0xbb, 0xb9, 0x88, 0x01, 0x0b, 0x73, 0x6a, 0x24, + 0x5a, 0xd3, 0x96, 0xe4, 0x02, 0x9b, 0xf4, 0xda, 0xe9, 0xb6, 0x94, 0x12, + 0x73, 0x57, 0xef, 0xaf, 0x77, 0x16, 0xf1, 0x14, 0x70, 0x6b, 0x71, 0x30, + 0x53, 0x88, 0x97, 0xb7, 0x76, 0x60, 0x23, 0xff, 0xea, 0xbe, 0x18, 0xea, + 0x12, 0x10, 0xda, 0x7d, 0xb8, 0xc7, 0xce, 0x73, 0xb4, 0x87, 0x16, 0x1d, + 0xb2, 0xaa, 0x90, 0xda, 0x5e, 0xe5, 0xd1, 0xad, 0x8e, 0x8e, 0xb7, 0xd5, + 0xbe, 0x60, 0x03, 0x39, 0x82, 0x34, 0xce, 0xe4, 0x83, 0x9f, 0x46, 0x0f, + 0x6f, 0x35, 0x7f, 0x2f, 0x97, 0x21, 0x45, 0x5f, 0x35, 0x81, 0xd6, 0x40, + 0xea, 0x58, 0x69, 0x0d, 0xbd, 0xe0, 0x03, 0xae, 0x60, 0xb8, 0x6f, 0x0f, + 0xd0, 0xdf, 0x2a, 0x5e, 0x6a, 0x87, 0x1a, 0x65, 0x3c, 0xe6, 0xe6, 0xff, + 0xf2, 0x00, 0x38, 0xf6, 0xc1, 0x5d, 0x85, 0xd8, 0xfb, 0xa8, 0xe2, 0xd6, + 0x07, 0x84, 0x1e, 0x18, 0xdb, 0xe4, 0x34, 0xbc, 0x6e, 0xb7, 0x42, 0x7e, + 0xcb, 0x9e, 0x0d, 0xf8, 0xc9, 0x22, 0x65, 0x94, 0x2e, 0xd4, 0x58, 0xa7, + 0x0d, 0x6b, 0xcd, 0x84, 0x67, 0xc7, 0xd9, 0x42, 0x0b, 0x2b, 0xd4, 0x63, + 0x67, 0x72, 0x48, 0x89, 0x28, 0xd4, 0x76, 0xbe, 0x2d, 0x94, 0xaa, 0x7a, + 0x8c, 0x6c, 0xb5, 0x05, 0x5c, 0x84, 0xa2, 0x90, 0x29, 0xb7, 0x6f, 0x4e, + 0x0d, 0x6c, 0x4a, 0x6c, 0xc0, 0x29, 0xb9, 0x20, 0x13, 0x69, 0x22, 0x48, + 0xdd, 0x42, 0x6e, 0xd8, 0x57, 0x8b, 0x74, 0x7f, 0xe6, 0x09, 0x23, 0x4e, + 0x1c, 0xfb, 0x03, 0x3b, 0xf3, 0xb1, 0xc8, 0x4d, 0x1a, 0xd9, 0x4b, 0xe5, + 0xb6, 0x46, 0xe1, 0x80, 0x84, 0x00, 0xc0, 0x7b, 0x7e, 0x78, 0x5e, 0x51, + 0x7c, 0x45, 0x8d, 0xec, 0x3d, 0xf0, 0xcd, 0x7d, 0x28, 0x02, 0x35, 0x88, + 0xdb, 0x3b, 0x7d, 0x13, 0x36, 0xf7, 0x02, 0x43, 0xf3, 0x35, 0x27, 0x85, + 0x6f, 0x6e, 0x45, 0x80, 0x07, 0x0f, 0xe6, 0x96, 0x13, 0x82, 0x7c, 0xec, + 0x40, 0x82, 0xc0, 0xe6, 0xe4, 0xea, 0xf9, 0x73, 0x94, 0x00, 0x67, 0x00, + 0xa6, 0xc9, 0xda, 0x41, 0x7f, 0x06, 0x7a, 0xeb, 0x7f, 0x34, 0xf7, 0x94, + 0x5f, 0x1c, 0x3c, 0x13, 0x3f, 0xe8, 0xa8, 0xde, 0xaf, 0xeb, 0x97, 0xfd, + 0xd6, 0xed, 0xb4, 0x21, 0x6c, 0x24, 0xb7, 0x43, 0xee, 0xe9, 0x7b, 0xcc, + 0xb4, 0x26, 0x79, 0xcb, 0x65, 0xf4, 0x1c, 0xd4, 0x80, 0x3a, 0xde, 0x54, + 0x0c, 0x20, 0xe7, 0xc3, 0xae, 0xe4, 0xa0, 0x53, 0x73, 0x3b, 0x0c, 0x74, + 0x9c, 0xca, 0x17, 0x6b, 0x57, 0x09, 0xf0, 0xe9, 0xe7, 0x3c, 0x6d, 0x6f, + 0x88, 0x26, 0x82, 0x17, 0xfc, 0x6e, 0x4f, 0x04, 0xa5, 0x56, 0xe9, 0x1b, + 0x37, 0x6c, 0xc6, 0xbc, 0x88, 0xfe, 0xc4, 0x4d, 0x7a, 0xc9, 0x50, 0x3a, + 0xc9, 0x29, 0x9b, 0x14, 0x28, 0x60, 0x4b, 0x75, 0x3f, 0xbd, 0x3f, 0x9f, + 0x39, 0xe6, 0x1b, 0x8a, 0xa7, 0x4b, 0x10, 0x65, 0x52, 0x82, 0xe0, 0xd6, + 0xf4, 0x26, 0x51, 0x78, 0x1d, 0x5b, 0x95, 0x0d, 0x53, 0x2b, 0x7e, 0x2f, + 0xe8, 0xf9, 0x9d, 0x47, 0xf6, 0x58, 0xe9, 0x30, 0xe2, 0xc3, 0xe1, 0x6d, + 0xdc, 0x50, 0x03, 0xdb, 0xcc, 0x94, 0x00, 0x5d, 0xe0, 0x07, 0xb6, 0x2f, + 0x97, 0xef, 0xc6, 0x3a, 0xc2, 0xc0, 0x99, 0xe7, 0x65, 0x89, 0x1b, 0x4e, + 0x59, 0x1f, 0xe7, 0xae, 0xc0, 0x1e, 0x61, 0x92, 0x5f, 0x55, 0xaa, 0x51, + 0xcc, 0xf6, 0x4e, 0x32, 0x56, 0x76, 0x99, 0x2b, 0x6e, 0xe8, 0x5c, 0xc9, + 0xe2, 0xa8, 0x78, 0x4b, 0x76, 0x85, 0xf3, 0x34, 0x5c, 0x52, 0x8e, 0xa5, + 0xed, 0x4a, 0x87, 0x9e, 0x3e, 0x90, 0x9b, 0xcf, 0xec, 0x57, 0x4b, 0x60, + 0x5a, 0xc9, 0x69, 0x0c, 0x63, 0x7a, 0x01, 0x26, 0x88, 0xb9, 0x32, 0x82, + 0x48, 0x02, 0x1b, 0x2c, 0xbe, 0x95, 0xb9, 0x2f, 0xe1, 0x4b, 0x6c, 0x4e, + 0x03, 0xdb, 0xc7, 0xce, 0xcf, 0x67, 0xf1, 0x1f, 0x83, 0xca, 0xb6, 0x20, + 0x06, 0xcd, 0xb8, 0xd9, 0xcb, 0x94, 0xb0, 0xa1, 0x88, 0xdc, 0xf9, 0x2c, + 0x4a, 0xb6, 0x85, 0x14, 0x42, 0x6c, 0xbb, 0x0d, 0x48, 0xd6, 0x51, 0x8f, + 0x21, 0x4a, 0xd4, 0x74, 0x6f, 0xdf, 0x89, 0x76, 0xf2, 0xe7, 0xcd, 0x32, + 0xc4, 0x4b, 0x52, 0xca, 0x5c, 0x08, 0x2c, 0x6b, 0x76, 0x88, 0xa4, 0x41, + 0x62, 0xed, 0x96, 0x71, 0xb0, 0xa4, 0x37, 0x2d, 0x91, 0x60, 0x69, 0x6d, + 0xee, 0x00, 0x18, 0x6f, 0x20, 0x0d, 0x48, 0xff, 0xd7, 0x2c, 0xb5, 0x4b, + 0x27, 0xf3, 0x91, 0xf3, 0x6a, 0x20, 0x04, 0xc5, 0x95, 0x10, 0x36, 0x0f, + 0x6f, 0x4c, 0x00, 0xc0, 0x57, 0x3e, 0xc0, 0x16, 0xcd, 0xba, 0x30, 0xcc, + 0x28, 0xed, 0xa7, 0xcf, 0x35, 0x94, 0xe0, 0xb6, 0x39, 0xdc, 0xb1, 0x25, + 0x09, 0x42, 0xd1, 0x8d, 0x7c, 0x87, 0x20, 0x53, 0x7b, 0xc0, 0x1b, 0x5d, + 0x00, 0x7f, 0xc3, 0xdf, 0xc6, 0xa1, 0x68, 0x61, 0x3c, 0xdb, 0x65, 0xf1, + 0x2d, 0xbd, 0xc3, 0x7c, 0x6c, 0x01, 0xa0, 0x9e, 0xd3, 0x9d, 0xd9, 0xd8, + 0xeb, 0x73, 0x5f, 0x76, 0xdd, 0x41, 0xe1, 0x6d, 0xcf, 0x00, 0x64, 0x44, + 0xea, 0x6c, 0x36, 0xdb, 0x40, 0x95, 0x2e, 0x9b, 0x42, 0x5b, 0x32, 0x36, + 0xba, 0x8b, 0x9b, 0x8e, 0xb4, 0x78, 0x6d, 0x87, 0x1e, 0xda, 0x08, 0xb3, + 0x75, 0x64, 0x6f, 0xeb, 0x3f, 0xcf, 0x7e, 0x85, 0x77, 0x8f, 0xcd, 0x55, + 0x87, 0x48, 0x75, 0x4a, 0x48, 0x6e, 0x00, 0xb0, 0x06, 0xe0, 0x07, 0xdc, + 0xd2, 0x33, 0xa7, 0x38, 0x54, 0x92, 0x1b, 0xa9, 0x5c, 0xa5, 0x64, 0x31, + 0x07, 0x37, 0x88, 0x00, 0x36, 0x20, 0x88, 0xa5, 0x8b, 0x90, 0xfc, 0xe2, + 0xcb, 0x24, 0x55, 0x01, 0xec, 0x6e, 0x37, 0xcf, 0xcf, 0xf0, 0x55, 0x99, + 0xf1, 0xe7, 0x4f, 0x77, 0x7b, 0x22, 0xc1, 0xab, 0x4f, 0x83, 0x23, 0x3f, + 0x8e, 0x37, 0x5c, 0x81, 0xf0, 0xea, 0x95, 0x0b, 0xad, 0x5c, 0x65, 0x41, + 0xad, 0xc0, 0x02, 0xe1, 0x53, 0xfc, 0x2a, 0x6b, 0xe8, 0x6d, 0xd7, 0x86, + 0xa1, 0x4d, 0xdc, 0x23, 0x00, 0x3c, 0xe8, 0x01, 0xb8, 0x03, 0x8f, 0x3e, + 0xfd, 0xf9, 0xda, 0x51, 0xb3, 0x99, 0xce, 0xd8, 0x71, 0x43, 0x46, 0x64, + 0x6f, 0x82, 0x11, 0x25, 0x11, 0xb9, 0x74, 0x0f, 0x1d, 0x46, 0x37, 0xb1, + 0x00, 0x68, 0x44, 0xa0, 0x0e, 0xc4, 0x60, 0x9f, 0x9e, 0xcc, 0x5b, 0x35, + 0xff, 0x9d, 0xd4, 0x37, 0x00, 0xc2, 0x7e, 0x14, 0x38, 0xa3, 0xe8, 0x5b, + 0x6f, 0xe4, 0x41, 0xb2, 0x46, 0x84, 0x8f, 0x49, 0x11, 0x80, 0x00, 0x00, + 0x01, 0x04, 0x43, 0xf9, 0x8e, 0xd8, 0xe7, 0x69, 0x90, 0x2f, 0x79, 0x44, + 0x6c, 0xf5, 0xf4, 0x47, 0x79, 0x4e, 0x1e, 0xb2, 0x59, 0x54, 0x21, 0x18, + 0x3d, 0xd3, 0x49, 0x98, 0x1a, 0x07, 0x35, 0x22, 0x72, 0x71, 0xd1, 0x70, + 0xe2, 0xd5, 0x75, 0x0a, 0x50, 0xd6, 0xf3, 0x52, 0xc6, 0xf1, 0xd1, 0xbc, + 0xba, 0xa0, 0x16, 0x17, 0xea, 0x39, 0xb4, 0x7c, 0xd3, 0x0d, 0x92, 0x8f, + 0x92, 0x27, 0x8b, 0x58, 0x28, 0x9f, 0xbc, 0xcd, 0xba, 0x52, 0x87, 0x5c, + 0x52, 0xdb, 0x41, 0x13, 0xb9, 0xcc, 0x42, 0x74, 0xa3, 0xeb, 0x86, 0x6d, + 0x55, 0x3a, 0xd6, 0x71, 0xf2, 0x2a, 0x33, 0xa3, 0x9b, 0xf2, 0xde, 0xee, + 0xd7, 0x3e, 0x15, 0x95, 0x81, 0x1f, 0x8d, 0xe4, 0x44, 0xba, 0x14, 0x7c, + 0xb2, 0xb7, 0xb1, 0x10, 0xab, 0x32, 0xdf, 0x09, 0x15, 0x5b, 0xb3, 0xda, + 0xfd, 0x79, 0x12, 0xb9, 0x28, 0x45, 0x92, 0x42, 0x13, 0x72, 0xcb, 0x16, + 0x12, 0x58, 0x54, 0x46, 0xfc, 0x88, 0x03, 0xf4, 0xb4, 0x9f, 0x54, 0x05, + 0x51, 0x7c, 0x9d, 0xe2, 0xa8, 0x58, 0x59, 0x6c, 0xa2, 0x93, 0xda, 0x1b, + 0xa8, 0x13, 0xb2, 0xc5, 0x6f, 0x47, 0x25, 0x15, 0xce, 0x5c, 0xa0, 0x94, + 0x01, 0x19, 0x6d, 0x04, 0xbf, 0xfd, 0x56, 0xf1, 0xd0, 0x0c, 0x15, 0x6f, + 0xa3, 0x77, 0x0f, 0x56, 0xd0, 0xe6, 0xe8, 0xb3, 0xcf, 0xac, 0xd4, 0xf5, + 0x29, 0xba, 0x1b, 0xf8, 0x39, 0xb0, 0xcc, 0x9f, 0x3a, 0xe9, 0xa4, 0x26, + 0xee, 0xbf, 0x3f, 0x09, 0x08, 0x6d, 0x34, 0xb9, 0x5a, 0x1b, 0xe4, 0xb7, + 0x53, 0xd8, 0x10, 0xbf, 0xdf, 0x98, 0x4b, 0xd8, 0xb3, 0xc5, 0xa8, 0xef, + 0x3c, 0xae, 0xc5, 0x08, 0x59, 0x49, 0x32, 0x8c, 0x6e, 0x74, 0x2e, 0xd2, + 0x4b, 0x21, 0xac, 0x37, 0xf5, 0x69, 0xf9, 0x52, 0x5c, 0x88, 0x4b, 0x6c, + 0x4f, 0xa0, 0x16, 0xf3, 0xe7, 0x68, 0x04, 0x1b, 0x8b, 0xe2, 0x91, 0x09, + 0x0c, 0xb9, 0x00, 0x0d, 0xf0, 0x5c, 0x04, 0xcf, 0xfd, 0x5a, 0x49, 0x67, + 0xe1, 0x31, 0xfc, 0x19, 0xb4, 0x30, 0xd7, 0x1b, 0x3d, 0x14, 0xef, 0x14, + 0xac, 0xc6, 0x23, 0x41, 0xe0, 0x73, 0x7e, 0x53, 0x78, 0xdf, 0xb7, 0x3f, + 0x1c, 0x73, 0x20, 0x6a, 0xe6, 0x72, 0x60, 0xe2, 0x62, 0xa5, 0xf5, 0x6d, + 0xbf, 0x6c, 0x84, 0x7f, 0xad, 0x4e, 0x2c, 0x80, 0x4e, 0xf3, 0x32, 0xe6, + 0xc3, 0xe9, 0x49, 0x06, 0xb6, 0x69, 0xc6, 0x4f, 0x8e, 0x04, 0x3d, 0xf3, + 0x29, 0x36, 0x5e, 0x73, 0x7c, 0xcc, 0x96, 0x2a, 0x15, 0x51, 0x67, 0x85, + 0x8d, 0x89, 0xfa, 0x7c, 0x84, 0x39, 0x80, 0x5b, 0x3b, 0x52, 0x54, 0x6f, + 0x57, 0x69, 0xb9, 0xb6, 0x37, 0xf4, 0x70, 0x07, 0x22, 0xe7, 0xc7, 0xdb, + 0x78, 0x7b, 0xc2, 0x73, 0x2c, 0xb1, 0x17, 0xf1, 0x1b, 0xe7, 0x3f, 0x7e, + 0xb7, 0xfc, 0x47, 0x9e, 0x41, 0x17, 0x28, 0xed, 0x3a, 0xc6, 0xf7, 0xbf, + 0xe7, 0x82, 0x0f, 0xf6, 0x4a, 0x2e, 0x00, 0x41, 0xba, 0xb7, 0x28, 0x5b, + 0x7b, 0xad, 0xda, 0x4e, 0xb7, 0x25, 0x0c, 0xb5, 0x0a, 0x6e, 0x5c, 0x8b, + 0xb2, 0xc6, 0xe1, 0xe3, 0x10, 0x5c, 0xb2, 0x04, 0x2b, 0x7f, 0x9e, 0x2d, + 0xf3, 0xf3, 0x03, 0x87, 0x86, 0x96, 0xdd, 0x61, 0x38, 0xed, 0x77, 0xcc, + 0x35, 0x60, 0xfb, 0x64, 0xa6, 0x0d, 0x1f, 0x69, 0x6d, 0x39, 0xb4, 0x01, + 0xb0, 0x9f, 0xf7, 0x2f, 0xd0, 0x9d, 0x7f, 0x0a, 0xeb, 0x69, 0xe0, 0x4c, + 0xa8, 0xdd, 0x27, 0x15, 0x9d, 0xed, 0x0b, 0x57, 0xea, 0x96, 0x03, 0x26, + 0xd2, 0x2b, 0xa2, 0x90, 0xf6, 0x36, 0xf0, 0x0c, 0x4b, 0x00, 0x06, 0x72, + 0xb7, 0xa6, 0x02, 0x17, 0xf8, 0x91, 0x63, 0xa4, 0x80, 0x3d, 0x37, 0xdf, + 0x78, 0x33, 0x21, 0xe4, 0xd5, 0x2a, 0x20, 0x4b, 0x7d, 0x7b, 0xe6, 0x02, + 0x0f, 0xf5, 0x80, 0x2c, 0xfe, 0x66, 0x89, 0xe2, 0x69, 0x59, 0x9b, 0xef, + 0xed, 0xe7, 0x27, 0x91, 0xf6, 0x93, 0xf6, 0x54, 0xa0, 0x11, 0x4b, 0x5b, + 0xe5, 0x30, 0x10, 0xbf, 0xea, 0xbe, 0xd8, 0x37, 0xf5, 0x62, 0x6d, 0xbe, + 0x0d, 0xd8, 0xfa, 0x7f, 0xb8, 0x00, 0x77, 0xef, 0x9e, 0x69, 0x47, 0xa3, + 0xb8, 0xf3, 0xc8, 0x32, 0x87, 0xe9, 0x52, 0x2b, 0x73, 0xce, 0x6e, 0x26, + 0x45, 0x08, 0x2d, 0xb8, 0xf2, 0xa2, 0x23, 0x7e, 0xbf, 0x1f, 0x9b, 0x73, + 0x53, 0x60, 0x4c, 0x29, 0x46, 0x52, 0xdb, 0xa4, 0x00, 0xa4, 0x8b, 0x9f, + 0x7e, 0x05, 0x88, 0x9a, 0xe9, 0x46, 0x51, 0x5f, 0x4f, 0x73, 0x37, 0xcc, + 0xf9, 0xfa, 0x85, 0xa9, 0xe3, 0x9b, 0xe7, 0x22, 0xe0, 0x01, 0xf6, 0x8a, + 0x8f, 0xd0, 0x9b, 0x78, 0xc4, 0x2c, 0x04, 0x68, 0x53, 0x7b, 0x5a, 0xa4, + 0x52, 0x0e, 0x4d, 0x30, 0x05, 0x7c, 0xae, 0x9e, 0x1d, 0x60, 0xd0, 0xb6, + 0xf2, 0x72, 0x82, 0x17, 0xfd, 0x57, 0x5c, 0x81, 0xb7, 0x4c, 0x29, 0xb0, + 0x85, 0xec, 0x2b, 0xc6, 0x46, 0xf3, 0x80, 0x14, 0xf0, 0xf0, 0x07, 0x3f, + 0x4e, 0x7d, 0xb1, 0xd0, 0x27, 0x7a, 0x7e, 0x2b, 0xa5, 0x2e, 0x15, 0x29, + 0xd5, 0xb2, 0xfc, 0x3e, 0x00, 0x3a, 0xf7, 0xbb, 0x64, 0x41, 0xdd, 0x3a, + 0x2e, 0x21, 0xc7, 0x16, 0xaa, 0x17, 0x55, 0xbe, 0xac, 0x00, 0xab, 0xa7, + 0x7c, 0x80, 0x57, 0xbd, 0xbf, 0x68, 0x11, 0xf9, 0xd0, 0xfc, 0x29, 0x00, + 0x8a, 0x34, 0x92, 0xdf, 0x37, 0x00, 0x75, 0xed, 0xee, 0x00, 0xfb, 0xdb, + 0x33, 0xa8, 0x47, 0xed, 0xf6, 0x2e, 0x87, 0x1d, 0x31, 0xce, 0x88, 0x54, + 0x29, 0xbd, 0x47, 0x3e, 0x0b, 0x15, 0x33, 0x4c, 0x09, 0x2e, 0xa5, 0xbe, + 0x2d, 0xbe, 0x6a, 0xc2, 0xd0, 0x25, 0xbf, 0x9b, 0x57, 0x66, 0xf0, 0x63, + 0xb2, 0x05, 0x0f, 0x0b, 0x6d, 0x2f, 0x2e, 0xd0, 0x29, 0xb6, 0x88, 0xdd, + 0xeb, 0x80, 0x09, 0xec, 0x2c, 0x07, 0xb6, 0x4f, 0x16, 0x8e, 0x12, 0x08, + 0x3f, 0xd8, 0x00, 0xfb, 0x39, 0x4a, 0x3d, 0x60, 0x8e, 0x64, 0xd7, 0x14, + 0xb0, 0xed, 0x2e, 0x5b, 0x43, 0x28, 0xe6, 0xdc, 0xc5, 0x80, 0x53, 0x4c, + 0x94, 0xb4, 0x6f, 0x29, 0x1b, 0x9b, 0x7e, 0xa4, 0xe3, 0x32, 0xd4, 0x8b, + 0x78, 0x8f, 0x4e, 0x4d, 0x01, 0xc2, 0x98, 0x6a, 0x0d, 0x2c, 0xf0, 0xc5, + 0x6f, 0x68, 0x22, 0xf6, 0x23, 0xe9, 0x05, 0x5e, 0xf2, 0x8e, 0xab, 0xd6, + 0xba, 0x2c, 0x0f, 0x85, 0x4b, 0x0a, 0x94, 0x28, 0x7b, 0x69, 0x00, 0x5e, + 0x4f, 0x00, 0x6a, 0x00, 0xe3, 0xdb, 0xb1, 0x79, 0xb4, 0x73, 0x85, 0x93, + 0xd7, 0x8e, 0x7b, 0x3f, 0x2a, 0x6c, 0x40, 0x1c, 0x51, 0x8d, 0xfa, 0x34, + 0x01, 0x0f, 0xdf, 0x5f, 0x44, 0x89, 0xcc, 0x90, 0xbb, 0x43, 0xde, 0xf2, + 0xc7, 0xdf, 0x5a, 0xd4, 0x2c, 0xae, 0x34, 0xbf, 0x06, 0xd9, 0xe5, 0xbb, + 0x4b, 0x6f, 0xf2, 0x77, 0x29, 0xc4, 0x85, 0xb6, 0x7e, 0xe2, 0xd8, 0x8d, + 0xfa, 0xc8, 0x00, 0x9c, 0x01, 0xc8, 0xbd, 0xd8, 0x1d, 0x1d, 0x90, 0x98, + 0x12, 0xd9, 0x40, 0x08, 0x7f, 0xfa, 0x46, 0x11, 0x49, 0xe2, 0x64, 0x2a, + 0x79, 0x98, 0xb4, 0xab, 0x4a, 0x8d, 0x98, 0x9e, 0x25, 0xb4, 0xf6, 0x5d, + 0xba, 0x55, 0x3d, 0xbf, 0x9b, 0x80, 0x3b, 0xf8, 0x70, 0x02, 0xf2, 0x30, + 0x03, 0xbb, 0xde, 0xad, 0xa5, 0x66, 0x80, 0x1e, 0x4e, 0x26, 0xbb, 0x50, + 0xba, 0x7e, 0xd4, 0x48, 0x58, 0x4b, 0x79, 0xa2, 0x27, 0x0f, 0xf7, 0xeb, + 0x48, 0xfd, 0x5a, 0x32, 0xc4, 0xeb, 0x72, 0x2c, 0x38, 0xed, 0xb5, 0x61, + 0x0a, 0x37, 0xe9, 0x7f, 0x9d, 0xbf, 0x5f, 0xef, 0xb8, 0xbd, 0xf5, 0xed, + 0xf6, 0xc8, 0x15, 0x87, 0x48, 0x14, 0xdf, 0x9f, 0x80, 0x1e, 0xf5, 0xa0, + 0x05, 0x14, 0x8d, 0xec, 0x2c, 0xe2, 0xe3, 0xed, 0xc1, 0x0e, 0x79, 0x47, + 0x13, 0x0b, 0xa9, 0xe0, 0x5a, 0xb4, 0x8b, 0xa4, 0xe3, 0x4e, 0x0a, 0x4b, + 0x63, 0x3e, 0x7f, 0x0a, 0x4a, 0xa7, 0x37, 0xcd, 0xfb, 0xb9, 0xc2, 0xdd, + 0xc6, 0xeb, 0xec, 0x1b, 0x92, 0x59, 0xfb, 0x39, 0xbe, 0x96, 0x00, 0xfc, + 0x5e, 0x09, 0xf7, 0x13, 0x38, 0xe8, 0x6a, 0x68, 0x05, 0x44, 0xcc, 0x7d, + 0x01, 0x5e, 0xd2, 0x8e, 0x1a, 0xad, 0xf3, 0x5f, 0xee, 0x7b, 0x7d, 0x44, + 0x5d, 0x15, 0x62, 0x25, 0x9b, 0xa1, 0x86, 0x14, 0x6f, 0x89, 0x41, 0x25, + 0x56, 0xfb, 0x57, 0xf0, 0x8b, 0x84, 0x5f, 0xbf, 0x7b, 0xc6, 0x8c, 0x47, + 0x64, 0x87, 0x3a, 0x21, 0x54, 0x7d, 0x3d, 0xb8, 0x7b, 0x78, 0x05, 0xa4, + 0xc9, 0xa1, 0x91, 0x1a, 0x1f, 0xa4, 0xfa, 0x52, 0xb7, 0xe4, 0x88, 0x00, + 0x15, 0x0a, 0x16, 0x96, 0xac, 0x55, 0x7d, 0x7e, 0x99, 0x86, 0xd2, 0xce, + 0xb0, 0x6d, 0x09, 0x6f, 0x19, 0xe7, 0x3d, 0xac, 0x8e, 0x7e, 0xd5, 0x36, + 0x9f, 0x86, 0xd5, 0x0b, 0x6f, 0x60, 0x00, 0xe8, 0x8b, 0x08, 0xc8, 0xfd, + 0x99, 0xa5, 0x96, 0xeb, 0x26, 0x45, 0x0b, 0xaa, 0x73, 0x7c, 0x9f, 0xda, + 0xd0, 0x06, 0xdf, 0x42, 0x27, 0x62, 0xc0, 0x45, 0xe6, 0xfb, 0x56, 0x0c, + 0x26, 0x4b, 0x0a, 0x2d, 0xa7, 0x93, 0x27, 0x42, 0x16, 0x0f, 0x53, 0x69, + 0xd0, 0x69, 0xc5, 0xb7, 0x3d, 0xb2, 0x4c, 0x58, 0xdf, 0x24, 0x01, 0xf9, + 0x3b, 0xa1, 0x04, 0x6e, 0xc4, 0xfc, 0x6a, 0x5b, 0x3c, 0xe3, 0xb7, 0x83, + 0x43, 0xe0, 0x65, 0xb0, 0xab, 0x65, 0x46, 0xfd, 0x38, 0x00, 0x8c, 0x8a, + 0x08, 0x3f, 0xcc, 0x00, 0xfc, 0x8e, 0xf0, 0x0b, 0x34, 0x11, 0xc0, 0x13, + 0x8f, 0x20, 0x31, 0x0a, 0x53, 0xb4, 0x7e, 0x9f, 0xe8, 0xde, 0x0f, 0xfb, + 0xcd, 0x00, 0x4a, 0x47, 0xd7, 0x79, 0x41, 0xf8, 0x01, 0x66, 0x49, 0x6e, + 0xd3, 0xc0, 0x72, 0x19, 0x09, 0x2d, 0xef, 0xdd, 0x1d, 0x04, 0xbe, 0x19, + 0x80, 0x2b, 0xc7, 0x07, 0x6a, 0x0e, 0x45, 0x43, 0x9b, 0xd6, 0xe3, 0x6f, + 0x39, 0x15, 0x60, 0xca, 0x6c, 0xab, 0x47, 0x37, 0x6c, 0xa6, 0xd6, 0x00, + 0x00, 0x01, 0x05, 0x43, 0xf9, 0x7d, 0x74, 0xbc, 0x58, 0xed, 0x01, 0x5e, + 0xd0, 0x82, 0x99, 0x05, 0xde, 0x29, 0x32, 0x84, 0xea, 0x9f, 0x46, 0x37, + 0x4e, 0x3e, 0x5b, 0x4c, 0xb6, 0x0e, 0x68, 0x2b, 0xdd, 0xc6, 0x95, 0x92, + 0xc5, 0x4d, 0xf0, 0x6e, 0x02, 0x9b, 0xc7, 0xc5, 0xd3, 0xa3, 0x7c, 0xf1, + 0x6e, 0xbb, 0x25, 0x90, 0x22, 0x69, 0xb2, 0x21, 0x46, 0xb3, 0x0b, 0xe7, + 0x9a, 0xfd, 0x76, 0x5a, 0xa6, 0xcf, 0x38, 0x8e, 0x9b, 0xa7, 0x19, 0x50, + 0xc8, 0xdd, 0x93, 0x43, 0x9e, 0x1e, 0xed, 0xb1, 0x66, 0x07, 0x2a, 0xa5, + 0x6d, 0xbb, 0x45, 0xba, 0x7d, 0x44, 0xce, 0x3b, 0xd2, 0xe5, 0x9d, 0x47, + 0xd7, 0x75, 0x77, 0x89, 0x15, 0x0f, 0x02, 0x75, 0xb9, 0x4d, 0x27, 0x45, + 0x3d, 0xb7, 0x2e, 0xa8, 0x1c, 0xdf, 0x96, 0xda, 0x6d, 0x88, 0xde, 0xcd, + 0xdc, 0x80, 0x1f, 0xf2, 0xfc, 0x92, 0x41, 0xf5, 0xf1, 0x02, 0xe0, 0xda, + 0x84, 0x36, 0xf2, 0xdc, 0x97, 0xc7, 0x04, 0x8b, 0x1b, 0x03, 0x9d, 0x05, + 0x7b, 0xf4, 0x6d, 0x9e, 0x18, 0x85, 0xb4, 0x5a, 0x38, 0x86, 0xdc, 0xd4, + 0xa9, 0x1b, 0xeb, 0x67, 0x37, 0xfd, 0xd6, 0x3b, 0xb7, 0xe4, 0x2c, 0xcc, + 0xd7, 0x98, 0x8f, 0xb2, 0x15, 0x0b, 0x44, 0x54, 0x6f, 0x1a, 0x08, 0x60, + 0x0d, 0x55, 0xbb, 0x02, 0x2a, 0xe5, 0xf2, 0xf4, 0x36, 0xd4, 0x6e, 0x56, + 0xc3, 0x1d, 0x29, 0x2f, 0x25, 0x6f, 0x42, 0x50, 0xea, 0xa4, 0x36, 0xd8, + 0x7b, 0x7b, 0xc4, 0x82, 0x17, 0xfa, 0xd7, 0xe4, 0x40, 0xb4, 0x46, 0xb4, + 0x8d, 0xd6, 0xf5, 0xa6, 0xbe, 0xd1, 0x85, 0x41, 0xed, 0xe8, 0x2a, 0xe5, + 0xe7, 0x49, 0x76, 0xda, 0xde, 0x66, 0x54, 0x73, 0xac, 0xbe, 0x3a, 0x89, + 0xe2, 0x39, 0xae, 0x87, 0x69, 0xed, 0x27, 0x37, 0xb4, 0x45, 0x00, 0x3e, + 0x84, 0x5e, 0x57, 0x01, 0x20, 0x00, 0xf9, 0x99, 0x38, 0x9e, 0x0a, 0x5c, + 0x21, 0x37, 0x9b, 0x81, 0xcd, 0xdb, 0xe9, 0xf3, 0xfd, 0xc7, 0x1e, 0x72, + 0x51, 0xb2, 0x58, 0xdc, 0x22, 0x63, 0x72, 0x8d, 0xac, 0xce, 0x6f, 0xd2, + 0x11, 0xb8, 0x04, 0x1f, 0xed, 0xc1, 0x1d, 0xca, 0x13, 0xe7, 0xbb, 0x56, + 0x0c, 0x19, 0x31, 0xaf, 0xc5, 0x00, 0x74, 0xf2, 0x31, 0x88, 0x1b, 0x37, + 0xbf, 0x3b, 0x76, 0x1e, 0x03, 0x88, 0x52, 0xa3, 0x72, 0xf9, 0x40, 0x07, + 0x3b, 0xf1, 0x99, 0x60, 0x4c, 0x32, 0xdb, 0x28, 0x4a, 0xa9, 0x2e, 0x35, + 0x9c, 0x60, 0x20, 0x80, 0x9f, 0x5e, 0xd2, 0xcf, 0x1e, 0x05, 0xc5, 0xf0, + 0xbc, 0x92, 0x1b, 0x53, 0xdb, 0xaa, 0xad, 0x45, 0x21, 0xab, 0x7b, 0xf7, + 0x99, 0xcf, 0x1b, 0x0c, 0xca, 0x39, 0x3d, 0xb5, 0xd3, 0x28, 0xca, 0x76, + 0xd2, 0xe9, 0x66, 0x36, 0x57, 0x99, 0xf1, 0xcd, 0xbe, 0x55, 0x3f, 0x69, + 0x66, 0xc1, 0xaa, 0x3e, 0x01, 0xcd, 0xe8, 0xfa, 0x7e, 0x80, 0x33, 0xc2, + 0x7c, 0xf3, 0x0a, 0xe1, 0xd6, 0x63, 0xa8, 0x0a, 0xe4, 0xb6, 0x94, 0x10, + 0x18, 0xd9, 0x79, 0xdb, 0xf4, 0xa2, 0x75, 0xf4, 0x2a, 0x7c, 0x9b, 0x84, + 0x38, 0x8a, 0xda, 0x35, 0xe7, 0xe4, 0xca, 0x4a, 0x6f, 0x85, 0xd0, 0x21, + 0x7f, 0xd3, 0xd7, 0x77, 0xc2, 0x18, 0xb7, 0xc2, 0xd6, 0xfa, 0xef, 0xd2, + 0xcf, 0xf8, 0x8d, 0x45, 0x01, 0x14, 0xb2, 0xc8, 0x34, 0x63, 0x7c, 0x75, + 0x17, 0x72, 0x12, 0xa2, 0x92, 0x0e, 0x6e, 0x8d, 0x90, 0x5f, 0x3a, 0xed, + 0x30, 0x2a, 0x3e, 0x36, 0x1a, 0x1d, 0x1b, 0x7e, 0x40, 0xc7, 0x56, 0xfa, + 0x46, 0xee, 0xd8, 0x08, 0x20, 0x27, 0x40, 0x1c, 0x79, 0x4a, 0x17, 0xd6, + 0x3e, 0xda, 0x17, 0x36, 0x55, 0xa1, 0x4d, 0xec, 0x85, 0xcd, 0xf7, 0x17, + 0xbc, 0x10, 0x2d, 0x2f, 0x6d, 0x0f, 0xc7, 0x9a, 0xf1, 0x87, 0x06, 0x50, + 0x96, 0xf0, 0xfd, 0x02, 0x10, 0x06, 0x8a, 0xe8, 0x41, 0x0b, 0x63, 0xf7, + 0x3c, 0x26, 0xd6, 0xf7, 0x3f, 0xcd, 0x84, 0x7d, 0x12, 0x84, 0x3b, 0x57, + 0xc4, 0x7f, 0xab, 0x71, 0x4c, 0x00, 0xab, 0x76, 0x5f, 0x57, 0xa5, 0xcf, + 0x16, 0xe4, 0xb8, 0x40, 0xd7, 0x80, 0x0c, 0x6a, 0xb7, 0xe7, 0xb5, 0xd5, + 0xd7, 0x8e, 0x28, 0xc4, 0x57, 0xc9, 0x4e, 0xb4, 0xba, 0x5d, 0x6f, 0xa0, + 0xe6, 0x0b, 0xff, 0x8a, 0x17, 0x79, 0xf2, 0x59, 0x2c, 0x37, 0x3a, 0xe6, + 0xba, 0x18, 0x7c, 0x2e, 0x01, 0xed, 0xe5, 0xba, 0xe4, 0x00, 0xe3, 0xa1, + 0x7d, 0x3e, 0xd8, 0x3c, 0xed, 0xb2, 0x85, 0x18, 0x5b, 0x7a, 0x3c, 0x73, + 0xc1, 0x03, 0xf3, 0x39, 0xe2, 0xd9, 0x88, 0x71, 0x3b, 0xbe, 0x3c, 0xe9, + 0x67, 0xc0, 0xe2, 0xe0, 0x14, 0xd9, 0x77, 0x41, 0x08, 0x01, 0xab, 0xe2, + 0x10, 0x9b, 0x91, 0xe0, 0x67, 0x89, 0x72, 0xb7, 0xe4, 0x7e, 0x3a, 0x00, + 0xb3, 0x5d, 0x85, 0xd9, 0x6c, 0x52, 0x8b, 0xbe, 0xb0, 0x08, 0x6e, 0x98, + 0x03, 0xed, 0x78, 0x03, 0xf1, 0x66, 0x3b, 0x8c, 0x83, 0x97, 0x30, 0x9a, + 0x5a, 0x40, 0xe9, 0x6c, 0x3e, 0x86, 0xb7, 0xe9, 0x10, 0x40, 0xfd, 0x40, + 0x07, 0x3d, 0xf0, 0x00, 0xf3, 0x8f, 0x61, 0x5a, 0xec, 0x85, 0xf2, 0xff, + 0x24, 0x29, 0xc6, 0x87, 0x7e, 0x83, 0x24, 0x6d, 0x60, 0x04, 0xa0, 0x0e, + 0x7d, 0xfa, 0x17, 0xb8, 0xf9, 0xe5, 0x92, 0x4c, 0x97, 0xcd, 0xf9, 0x13, + 0x6d, 0x32, 0x1c, 0xdd, 0x9f, 0x27, 0xad, 0x50, 0xb6, 0xea, 0x16, 0x7c, + 0xb5, 0x5b, 0xfc, 0xda, 0x00, 0xf3, 0xe3, 0xbe, 0x39, 0xf2, 0xe1, 0xef, + 0xe4, 0xb5, 0xcc, 0x78, 0x01, 0xf3, 0x88, 0x3b, 0xe5, 0x09, 0xf2, 0x42, + 0xac, 0x4b, 0x54, 0x7d, 0xad, 0xd4, 0xe2, 0xec, 0x15, 0xb8, 0x64, 0x08, + 0xb9, 0xb4, 0xf1, 0x9e, 0x10, 0x2d, 0xbe, 0xb6, 0x00, 0x8f, 0xa8, 0x00, + 0xc0, 0x01, 0x16, 0xef, 0x3c, 0xf2, 0x85, 0xf9, 0x63, 0xc4, 0x8b, 0x72, + 0x53, 0x43, 0xcb, 0x5c, 0x52, 0x4b, 0x6e, 0x04, 0x0f, 0xd3, 0x00, 0xb3, + 0x28, 0xbe, 0xdf, 0x75, 0xf2, 0x1d, 0x15, 0x6c, 0x8d, 0xbb, 0xe5, 0xba, + 0xb7, 0xd6, 0x42, 0x98, 0xee, 0x79, 0x6c, 0xb6, 0x37, 0xf8, 0xdd, 0xd8, + 0x00, 0x26, 0x5a, 0x09, 0x80, 0x06, 0xe9, 0x67, 0xab, 0x7d, 0x14, 0x10, + 0x3f, 0x38, 0x8c, 0x08, 0x3f, 0xae, 0x00, 0xf3, 0x04, 0x08, 0x23, 0xf0, + 0x84, 0xd3, 0x3e, 0x5f, 0xb2, 0x10, 0x38, 0x42, 0x7d, 0x85, 0x86, 0xb8, + 0x6b, 0x7e, 0xaa, 0x00, 0x27, 0x00, 0x7e, 0x2c, 0x01, 0xc8, 0x03, 0xb7, + 0x82, 0x10, 0x03, 0x3f, 0x6a, 0x4c, 0xeb, 0xae, 0xa9, 0x50, 0xcb, 0x4d, + 0xda, 0x81, 0x2d, 0xed, 0xb0, 0x3a, 0xd5, 0x6e, 0x9d, 0x2e, 0xb6, 0xda, + 0x5d, 0xa8, 0xde, 0x62, 0x28, 0x9e, 0x48, 0xbf, 0x71, 0x62, 0xc4, 0xf7, + 0xa0, 0x3d, 0xde, 0x5e, 0xfb, 0x74, 0x74, 0x85, 0x0e, 0x92, 0x23, 0x74, + 0xdb, 0x2e, 0x16, 0xc7, 0x22, 0x36, 0xcd, 0xab, 0x61, 0xd3, 0xcb, 0x69, + 0x21, 0xa7, 0x54, 0x83, 0xd5, 0x95, 0xb1, 0xe0, 0x21, 0x00, 0x35, 0xd6, + 0xc0, 0xe8, 0x00, 0x6f, 0x65, 0x9e, 0xb9, 0x24, 0x66, 0xc3, 0x70, 0x53, + 0xa8, 0x03, 0x0f, 0x7f, 0xaf, 0x5b, 0x1c, 0x5c, 0x57, 0xd2, 0x03, 0xec, + 0x93, 0x24, 0x2e, 0xa8, 0xe3, 0x83, 0x1b, 0xe6, 0xe6, 0x91, 0x1e, 0x44, + 0xfb, 0x80, 0x5a, 0xf1, 0x24, 0xd7, 0x16, 0xfa, 0xf9, 0x03, 0x89, 0x96, + 0x19, 0xb3, 0x03, 0x0a, 0x19, 0x1b, 0xed, 0x0a, 0x1d, 0x69, 0x21, 0xbf, + 0x18, 0xbd, 0xc0, 0x06, 0x8f, 0xf8, 0x7c, 0xa1, 0xab, 0x3e, 0x28, 0xa4, + 0x04, 0xb0, 0x03, 0x31, 0x47, 0x8e, 0x6f, 0x2e, 0x50, 0x03, 0xea, 0x92, + 0x78, 0xd2, 0xc9, 0x4d, 0xc9, 0x00, 0xc6, 0xa3, 0x7e, 0x9b, 0xfe, 0x2b, + 0x3b, 0xeb, 0x8b, 0xbd, 0xc1, 0xd7, 0x31, 0xcf, 0xd8, 0x62, 0x15, 0x2a, + 0x1c, 0x7b, 0x75, 0xb2, 0x76, 0x45, 0x17, 0xed, 0xbf, 0xee, 0x2e, 0x96, + 0x99, 0x8f, 0xd2, 0xe2, 0x42, 0xc7, 0x0d, 0x6e, 0x01, 0x13, 0x1c, 0x00, + 0xa4, 0x4f, 0xb7, 0x6e, 0xd8, 0x38, 0x02, 0x9d, 0xe1, 0x66, 0xd3, 0xd5, + 0x20, 0xd6, 0xfa, 0x8c, 0x17, 0x80, 0x0f, 0x38, 0x9f, 0x8c, 0xa9, 0x15, + 0x4d, 0xc9, 0x25, 0x1a, 0x31, 0x54, 0xa6, 0xf3, 0x9e, 0x9c, 0xcd, 0x58, + 0xa3, 0x91, 0x51, 0x28, 0x5b, 0x72, 0xd2, 0xe5, 0x95, 0xbc, 0x00, 0x0e, + 0x7e, 0xef, 0x23, 0x47, 0xe3, 0xf5, 0xce, 0x2a, 0x13, 0xc3, 0xd5, 0x14, + 0x04, 0x45, 0x29, 0x29, 0xbe, 0x72, 0x00, 0xf7, 0x0d, 0x17, 0xed, 0xc7, + 0x7c, 0x00, 0xaa, 0x4e, 0x35, 0xea, 0xf2, 0xc7, 0x42, 0xa9, 0x47, 0x9e, + 0xde, 0xf3, 0x3a, 0x7f, 0x3b, 0xcb, 0xd3, 0x06, 0x5c, 0x26, 0x96, 0xa3, + 0x0b, 0x43, 0xda, 0xae, 0xa7, 0xbf, 0x31, 0x34, 0xc4, 0x1b, 0x38, 0xbc, + 0x42, 0xae, 0xd0, 0xc5, 0x6e, 0xbd, 0xbb, 0xb2, 0xe1, 0xb4, 0x34, 0xc4, + 0x56, 0xa5, 0xa8, 0x8a, 0xdf, 0x40, 0x8d, 0x39, 0xfe, 0xf1, 0xcc, 0x94, + 0x68, 0x79, 0x99, 0xdd, 0x8e, 0x8a, 0x5a, 0xab, 0xa8, 0xd5, 0x29, 0xb9, + 0xc0, 0x0e, 0x05, 0x80, 0x19, 0x73, 0x3a, 0x31, 0x00, 0x25, 0x8f, 0xda, + 0x4c, 0x94, 0x38, 0xed, 0xf5, 0x6e, 0x48, 0x8e, 0x9f, 0xf1, 0xcb, 0xb7, + 0xad, 0xb4, 0x05, 0x7c, 0xc2, 0x60, 0xdf, 0x06, 0xf9, 0x71, 0xa0, 0x02, + 0x6d, 0x15, 0xaf, 0xb2, 0x0c, 0x86, 0xf1, 0xb2, 0xdf, 0x46, 0xc7, 0xb7, + 0x9a, 0x2c, 0xcb, 0xe9, 0x30, 0xa8, 0xa0, 0x53, 0x25, 0x31, 0xf5, 0x51, + 0x80, 0x00, 0x00, 0x01, 0x06, 0x43, 0xf8, 0xce, 0x95, 0xb6, 0x28, 0x43, + 0x6a, 0xca, 0xf1, 0x3b, 0x30, 0xc4, 0x1c, 0x79, 0x7e, 0x81, 0x8d, 0x9b, + 0x67, 0x9f, 0x09, 0x81, 0x4d, 0xd8, 0x13, 0x08, 0x2e, 0x3f, 0xc5, 0x5b, + 0xc6, 0x45, 0x6f, 0x08, 0x73, 0x68, 0x2b, 0x2b, 0xa4, 0xcc, 0xf1, 0xa3, + 0x47, 0x35, 0x3d, 0x3a, 0x3b, 0xad, 0x4b, 0x24, 0x1b, 0x55, 0xb6, 0x5d, + 0x00, 0xb2, 0xda, 0xb0, 0x31, 0x25, 0x2d, 0xb9, 0xe4, 0xdc, 0x6c, 0x49, + 0x92, 0x44, 0x65, 0x92, 0x45, 0xad, 0xf7, 0xb4, 0x10, 0xbf, 0xc8, 0x67, + 0xa3, 0x07, 0xf6, 0x40, 0x10, 0x23, 0x97, 0x58, 0x1b, 0x23, 0xbc, 0xd6, + 0xc0, 0x08, 0xd1, 0xba, 0xcf, 0x04, 0x2f, 0xf1, 0x36, 0x12, 0x9b, 0xc0, + 0x7b, 0x60, 0x21, 0x80, 0x53, 0xa0, 0x5a, 0x3b, 0x32, 0x97, 0xe1, 0x4b, + 0x6e, 0x95, 0x58, 0x50, 0x00, 0xd5, 0xac, 0xf6, 0xf6, 0x91, 0x64, 0x23, + 0x76, 0x9b, 0x9e, 0x2a, 0x8a, 0xd5, 0xa8, 0x01, 0xee, 0x3b, 0x24, 0xf5, + 0xa7, 0x85, 0x37, 0xab, 0xea, 0xdc, 0x76, 0xba, 0xa8, 0x4c, 0xaa, 0x93, + 0xc4, 0x63, 0x78, 0xc4, 0xbb, 0xce, 0x52, 0x87, 0x52, 0xa4, 0x54, 0x09, + 0x6d, 0x00, 0x4a, 0xe5, 0xf5, 0x46, 0xb1, 0xad, 0xfa, 0xd8, 0x1c, 0x68, + 0x16, 0xde, 0x33, 0x01, 0x08, 0x02, 0xbb, 0x76, 0x6a, 0xf8, 0xe4, 0x01, + 0xf3, 0x7a, 0x23, 0x29, 0x3b, 0x81, 0x66, 0xba, 0x86, 0xce, 0x5c, 0x74, + 0x3c, 0xf0, 0xc6, 0xf9, 0xe7, 0x40, 0x84, 0x00, 0xce, 0x10, 0x58, 0x5e, + 0xcd, 0xc5, 0xa3, 0x8b, 0x4a, 0x31, 0x87, 0x01, 0x8c, 0x9b, 0x48, 0x4d, + 0x67, 0xc6, 0xfa, 0xc7, 0x48, 0xd5, 0xd2, 0xa4, 0x6d, 0x52, 0x99, 0x24, + 0xbe, 0xa8, 0x8d, 0xd7, 0x12, 0xe7, 0xff, 0x5c, 0xee, 0x2e, 0x69, 0xf7, + 0xc9, 0x7c, 0xff, 0x63, 0x0a, 0x1e, 0xc9, 0x93, 0x75, 0x22, 0x7c, 0xd7, + 0x1e, 0x80, 0x12, 0x4b, 0xbc, 0xdd, 0xa7, 0x7e, 0x8e, 0x28, 0xf3, 0xca, + 0x6c, 0xef, 0xbe, 0x77, 0x99, 0x28, 0x51, 0x93, 0x64, 0x90, 0x05, 0x45, + 0x97, 0x02, 0x9b, 0xb0, 0x4e, 0x00, 0x34, 0x73, 0xfc, 0x94, 0xe5, 0xa8, + 0xe0, 0x17, 0xb5, 0x0e, 0x5b, 0x2b, 0xec, 0xa7, 0x9d, 0x31, 0xdd, 0x87, + 0xc3, 0xc7, 0xea, 0x7a, 0xb6, 0xa7, 0xab, 0x7a, 0x64, 0xd3, 0x63, 0x79, + 0x72, 0x80, 0x1b, 0xde, 0x72, 0xcc, 0x87, 0xad, 0xcd, 0xe5, 0x66, 0x05, + 0xdc, 0x90, 0x86, 0xde, 0x9d, 0xdb, 0x7d, 0x85, 0x09, 0x36, 0x4a, 0x04, + 0xdc, 0xe7, 0x79, 0x76, 0xda, 0x79, 0xfa, 0xf2, 0xe7, 0xa2, 0xb7, 0x0b, + 0x8b, 0x7e, 0xbb, 0x5d, 0xda, 0x2c, 0xa6, 0xe4, 0x20, 0x3d, 0xe5, 0x24, + 0x2e, 0xaa, 0x01, 0x07, 0x8c, 0x69, 0xa8, 0x2f, 0x45, 0x53, 0x29, 0xd4, + 0x3a, 0x8a, 0x7b, 0xc8, 0x45, 0x07, 0xd0, 0xa2, 0x9b, 0x43, 0x9a, 0x69, + 0x73, 0x1b, 0xaa, 0x55, 0x8a, 0x80, 0x11, 0x28, 0x0b, 0x9b, 0x4c, 0x03, + 0x2f, 0x88, 0x9e, 0x38, 0x57, 0x83, 0x63, 0xdf, 0xca, 0xc2, 0x5d, 0x95, + 0xba, 0xbc, 0x82, 0x10, 0x05, 0x3e, 0x44, 0x00, 0x87, 0x2e, 0x7a, 0x29, + 0x71, 0xa1, 0xbb, 0x9b, 0xc9, 0xd8, 0x7d, 0xc7, 0xe5, 0x08, 0xbe, 0x52, + 0xca, 0xdc, 0xc8, 0xbf, 0x4b, 0xef, 0x89, 0x06, 0xd2, 0xa7, 0x2b, 0x14, + 0x24, 0xa8, 0xde, 0xc7, 0x6c, 0x8e, 0x15, 0x24, 0x2c, 0x27, 0x05, 0x80, + 0x0c, 0x4e, 0x6c, 0x1d, 0xed, 0xe7, 0x8f, 0x3c, 0x81, 0x0b, 0xc4, 0xb4, + 0x0a, 0x56, 0x4d, 0x34, 0x3a, 0x56, 0xfc, 0x87, 0xe3, 0xdd, 0x4c, 0xe6, + 0xc3, 0xf3, 0x0d, 0xb8, 0x90, 0xb2, 0x91, 0x5b, 0xef, 0x8e, 0x78, 0xa0, + 0x40, 0xfd, 0x31, 0x60, 0x0f, 0x3b, 0xd7, 0x28, 0x0f, 0x77, 0x97, 0x72, + 0x36, 0x96, 0x57, 0x92, 0xb7, 0xc6, 0x5d, 0xef, 0x99, 0xaf, 0x7f, 0x0f, + 0x2c, 0xbc, 0xfc, 0x29, 0xdb, 0x49, 0xa5, 0xb5, 0x5e, 0xd9, 0x9f, 0xf2, + 0x38, 0x8e, 0x39, 0xb2, 0x06, 0x3b, 0x9e, 0x66, 0x68, 0xe0, 0xd1, 0xa1, + 0x2c, 0x17, 0xb5, 0xbc, 0xb1, 0xb2, 0x37, 0xfd, 0x08, 0xfb, 0x71, 0xdb, + 0xf7, 0xe0, 0x5c, 0xb1, 0x01, 0x14, 0x01, 0x39, 0x2e, 0x59, 0x65, 0xf1, + 0x66, 0xff, 0x60, 0xb7, 0x67, 0xc7, 0xbd, 0xcc, 0x4a, 0x08, 0x80, 0x09, + 0xb6, 0x24, 0xb5, 0x42, 0x46, 0xb7, 0xce, 0x00, 0x09, 0xb6, 0x80, 0x2d, + 0x00, 0x75, 0xef, 0xaf, 0xa1, 0x86, 0x88, 0x73, 0xec, 0x4a, 0x14, 0x3a, + 0x84, 0x37, 0xd0, 0xfd, 0xb2, 0xf6, 0xee, 0x6c, 0x4a, 0x02, 0xad, 0x2b, + 0x14, 0x20, 0x73, 0x74, 0x94, 0x03, 0x46, 0xec, 0x0c, 0x6f, 0xd4, 0xdd, + 0x27, 0xda, 0x6b, 0x3e, 0x53, 0x35, 0xb0, 0xe0, 0x05, 0x36, 0xb5, 0xd2, + 0x93, 0xa5, 0x24, 0xb5, 0xc6, 0x51, 0xbb, 0x9d, 0x5b, 0x0e, 0x01, 0x89, + 0x09, 0x2d, 0x44, 0x86, 0x56, 0xa7, 0x0a, 0x67, 0x19, 0x37, 0xbc, 0x9a, + 0xd7, 0x4a, 0x5b, 0x62, 0x9f, 0x9c, 0x6d, 0x54, 0x3a, 0x56, 0x6c, 0xdb, + 0xe2, 0xf0, 0x08, 0x40, 0x13, 0x15, 0xab, 0x00, 0x9f, 0x61, 0x25, 0xb3, + 0x00, 0xe0, 0x9c, 0x84, 0xb6, 0xdc, 0xab, 0x76, 0x40, 0xa5, 0xcb, 0xb2, + 0x10, 0x9a, 0x20, 0x75, 0xb0, 0x94, 0xc1, 0xd6, 0xb7, 0xdb, 0x77, 0xe6, + 0x21, 0x2d, 0xbe, 0x20, 0x00, 0xaf, 0x8a, 0x00, 0x4d, 0x04, 0x7d, 0x39, + 0x9b, 0x0e, 0xaa, 0xf7, 0x3a, 0xf9, 0x58, 0x30, 0x3a, 0x6d, 0x54, 0x29, + 0xbe, 0x99, 0xf0, 0xf7, 0x7b, 0xb8, 0xde, 0x70, 0xa2, 0x8b, 0x2e, 0x85, + 0x37, 0x75, 0xcf, 0xa4, 0x0d, 0xd7, 0x4a, 0x19, 0x6c, 0x8b, 0x15, 0xb8, + 0xee, 0xa7, 0xb7, 0x20, 0x03, 0xe6, 0xc2, 0xd4, 0xe2, 0xd6, 0xff, 0x23, + 0x73, 0x2a, 0x9f, 0xe0, 0xb1, 0xbe, 0x90, 0x2b, 0x8d, 0xe7, 0xad, 0xdd, + 0xcd, 0xa0, 0x2a, 0xda, 0xb1, 0x02, 0x0a, 0xa7, 0x04, 0x2d, 0x6f, 0xa4, + 0x80, 0x21, 0xfb, 0x80, 0x58, 0x29, 0xce, 0xaf, 0xc8, 0x54, 0x36, 0xad, + 0x1a, 0xdb, 0x88, 0xbf, 0x5d, 0x12, 0x00, 0xf7, 0x67, 0x31, 0x3f, 0x59, + 0x32, 0x01, 0x03, 0x6b, 0x72, 0x89, 0x70, 0x05, 0xbc, 0xc4, 0xf5, 0x87, + 0xb6, 0x3c, 0xcf, 0x3d, 0x84, 0xb8, 0xdf, 0x24, 0x01, 0xcf, 0x1b, 0xf5, + 0xeb, 0x70, 0x8d, 0xe7, 0x40, 0x05, 0x35, 0x2c, 0xaf, 0x74, 0x3a, 0x24, + 0xb4, 0x7b, 0x79, 0x72, 0x2f, 0x00, 0x06, 0x9f, 0x51, 0x46, 0xe3, 0xa5, + 0x28, 0x39, 0x1d, 0x6b, 0xed, 0x52, 0xcf, 0x48, 0x5c, 0x6f, 0x42, 0x00, + 0xfa, 0x8a, 0xfe, 0x77, 0x66, 0x73, 0x65, 0x96, 0x13, 0x24, 0xab, 0x4b, + 0x1f, 0x03, 0x0f, 0x6f, 0x2a, 0x08, 0x00, 0x5b, 0xf5, 0xe3, 0x91, 0x35, + 0xfd, 0x7b, 0x29, 0xd2, 0xe5, 0xda, 0x04, 0x15, 0x9b, 0x2c, 0x0c, 0x28, + 0x63, 0x77, 0x5a, 0x95, 0x6b, 0x69, 0xb4, 0x38, 0xda, 0x4b, 0x6f, 0x18, + 0x03, 0x97, 0x67, 0xc8, 0x97, 0x71, 0xc7, 0xb2, 0x1c, 0x5c, 0x73, 0x89, + 0xa8, 0x34, 0xb6, 0xf9, 0x29, 0x1f, 0x8e, 0x40, 0x1d, 0x5f, 0xa3, 0xed, + 0xc3, 0xae, 0x5d, 0x9c, 0x3b, 0x26, 0xc8, 0x7c, 0x3c, 0xc2, 0xdb, 0xe8, + 0x40, 0x05, 0x9e, 0xfd, 0x88, 0xfe, 0x40, 0x0a, 0xf3, 0xe2, 0x55, 0xe2, + 0x93, 0xb8, 0xe2, 0x07, 0xbd, 0xf3, 0x4c, 0x45, 0xa1, 0x0d, 0xe7, 0x6f, + 0x45, 0x4e, 0x84, 0x6c, 0x15, 0xaf, 0x7e, 0x57, 0x64, 0x44, 0xd8, 0xf9, + 0xa5, 0x6e, 0x5f, 0x52, 0xdb, 0x93, 0x97, 0x5f, 0x28, 0x96, 0xc1, 0x95, + 0x62, 0x2b, 0x48, 0xb8, 0x1c, 0x55, 0x60, 0x00, 0x00, 0x01, 0x07, 0x43, + 0xf9, 0xef, 0xbc, 0xbd, 0xf1, 0x2e, 0xf8, 0x28, 0xda, 0x7b, 0x6b, 0xe9, + 0xf8, 0x44, 0xed, 0xfc, 0xf3, 0xe1, 0x2d, 0x92, 0x40, 0xa6, 0xf6, 0xa0, + 0x0f, 0xc5, 0x69, 0x17, 0xdb, 0x08, 0xe2, 0x62, 0x0d, 0x41, 0x5b, 0xd5, + 0x93, 0x9b, 0x03, 0xaf, 0xe7, 0x16, 0x20, 0x4b, 0x5c, 0x08, 0x1f, 0x9e, + 0x44, 0xe0, 0x01, 0x87, 0xff, 0xdf, 0xe2, 0x0a, 0xdb, 0x0a, 0xf3, 0xdb, + 0xc6, 0xba, 0xcd, 0x87, 0x00, 0x4f, 0xc0, 0x49, 0x54, 0xa0, 0xc6, 0xf2, + 0xec, 0xb9, 0x6b, 0x78, 0xef, 0x94, 0x3e, 0x56, 0xfe, 0x39, 0x92, 0x3b, + 0x12, 0x4f, 0x09, 0x1b, 0x66, 0x82, 0x17, 0xfc, 0xcd, 0x6c, 0xfc, 0xca, + 0x55, 0xb0, 0x25, 0xbd, 0x28, 0x98, 0x4f, 0x17, 0xb4, 0xb0, 0xa7, 0xbb, + 0x10, 0x30, 0xf5, 0xb2, 0xdf, 0x4a, 0xdc, 0x96, 0x1b, 0x91, 0xb0, 0xd8, + 0xb1, 0xbb, 0xc4, 0x69, 0x3f, 0xe7, 0x93, 0x00, 0x06, 0x90, 0xb4, 0x08, + 0x6f, 0x99, 0x4f, 0xd4, 0x21, 0x15, 0x00, 0xa8, 0xdf, 0x53, 0x13, 0x6b, + 0xf2, 0xcc, 0x50, 0x11, 0x66, 0x2a, 0x8d, 0x3e, 0xc0, 0x29, 0xbe, 0x64, + 0xf2, 0xab, 0xa9, 0x2a, 0xc6, 0xde, 0xc2, 0xca, 0x21, 0xab, 0x69, 0x43, + 0xeb, 0x7e, 0xc0, 0x52, 0x91, 0xf6, 0xe9, 0x9a, 0x03, 0xca, 0x61, 0x55, + 0xbd, 0x30, 0x9d, 0x04, 0x1f, 0xeb, 0x22, 0x0a, 0xa0, 0x15, 0x8e, 0x88, + 0x64, 0x35, 0x40, 0x21, 0x30, 0xb0, 0xb2, 0x9b, 0xc2, 0xcf, 0xc9, 0xab, + 0xe1, 0x36, 0xb7, 0xd3, 0xa3, 0x9e, 0x00, 0xff, 0xb7, 0xc3, 0xc3, 0x2c, + 0x77, 0x2e, 0x31, 0x22, 0x9c, 0x66, 0x9f, 0xe2, 0xb2, 0x36, 0xce, 0x2b, + 0x6c, 0x80, 0x03, 0x36, 0xb3, 0x9b, 0xbc, 0x8e, 0x47, 0xe9, 0xc0, 0x0f, + 0x40, 0x1a, 0x64, 0xf6, 0x75, 0xa1, 0xe7, 0xf0, 0x2e, 0x5e, 0xf3, 0x4e, + 0x54, 0xb1, 0x56, 0xa1, 0x47, 0x14, 0xad, 0xf1, 0xaf, 0xfb, 0xf8, 0x14, + 0x67, 0x13, 0x75, 0x28, 0x09, 0x40, 0x0f, 0xbc, 0xaf, 0x39, 0x07, 0x15, + 0x12, 0x4d, 0xa3, 0xcb, 0x18, 0xde, 0xfb, 0xe0, 0xc1, 0x5e, 0xd9, 0xd3, + 0xf6, 0x86, 0x43, 0x70, 0xf1, 0x84, 0xc2, 0x9b, 0xca, 0xce, 0x5e, 0x00, + 0xe8, 0x50, 0x8e, 0x44, 0xbf, 0x27, 0xea, 0x4a, 0x2f, 0xcf, 0xbc, 0x83, + 0x40, 0x71, 0xc6, 0xc8, 0x64, 0xa0, 0x2a, 0x88, 0x5b, 0x72, 0x24, 0xb8, + 0xe5, 0xf5, 0x91, 0xaa, 0x07, 0xc8, 0xdf, 0x8e, 0xe3, 0x2b, 0x85, 0xbe, + 0xdc, 0x1e, 0x92, 0x6c, 0x83, 0x42, 0x80, 0xb6, 0xe8, 0x80, 0x34, 0xf8, + 0x9d, 0xf2, 0xf5, 0xf3, 0x79, 0x6a, 0x6d, 0x2e, 0xad, 0x03, 0x9b, 0x97, + 0x92, 0x7b, 0x3b, 0xaf, 0x30, 0x08, 0x67, 0x7e, 0x7b, 0x02, 0xe1, 0xb2, + 0xd9, 0xe1, 0x1b, 0x36, 0x6c, 0xc9, 0x69, 0x41, 0x76, 0x92, 0x9b, 0xbe, + 0xd6, 0xde, 0xd4, 0x8d, 0xfb, 0x2e, 0x1c, 0x00, 0x6e, 0x2b, 0xcb, 0xac, + 0x41, 0xa9, 0xb1, 0xd6, 0xca, 0x36, 0xd2, 0xcf, 0x2d, 0x91, 0x2c, 0xd7, + 0xa9, 0x61, 0x13, 0x99, 0x7d, 0x43, 0x1b, 0x86, 0x46, 0x80, 0x16, 0xf7, + 0x75, 0x02, 0x2b, 0xf6, 0x44, 0x1f, 0x5b, 0xd4, 0x13, 0x45, 0x3e, 0xdc, + 0x09, 0xb8, 0xaa, 0x10, 0x74, 0x89, 0x59, 0xb7, 0x58, 0x04, 0xea, 0xda, + 0x77, 0x63, 0xf3, 0x26, 0xe8, 0x64, 0x27, 0xb9, 0xda, 0x50, 0xd3, 0xb6, + 0xc3, 0xe0, 0x50, 0xd6, 0xeb, 0x79, 0x80, 0x1d, 0x80, 0x59, 0x2d, 0x1a, + 0x51, 0x3e, 0x7c, 0x73, 0x74, 0x34, 0x3a, 0xba, 0xd4, 0xb0, 0x21, 0xb9, + 0x50, 0xcf, 0x7b, 0xb5, 0x7c, 0x33, 0x6e, 0x6c, 0x01, 0x10, 0xdb, 0x60, + 0x51, 0x8c, 0xee, 0xd2, 0x7c, 0xfb, 0x97, 0x00, 0x45, 0xe6, 0xe5, 0x38, + 0x08, 0x54, 0x0e, 0x2c, 0x09, 0x6b, 0x6d, 0x87, 0x36, 0xd4, 0xbb, 0x57, + 0xd6, 0x52, 0x9b, 0xaa, 0xe5, 0xe1, 0xc2, 0xf7, 0x02, 0xcc, 0xdd, 0x4b, + 0x02, 0xcc, 0x1a, 0xdc, 0xf1, 0x33, 0x78, 0xdc, 0xcc, 0x41, 0xcf, 0x8f, + 0xf2, 0xb0, 0xbf, 0x16, 0x5e, 0x26, 0x10, 0x66, 0x3f, 0x03, 0x0f, 0xb5, + 0x4b, 0x2a, 0x9e, 0x31, 0xa5, 0xba, 0x1b, 0x7e, 0xb1, 0x61, 0x9a, 0x16, + 0x08, 0x5f, 0xf0, 0xbb, 0x84, 0x34, 0x29, 0xb5, 0xd9, 0x05, 0xd7, 0x62, + 0x06, 0xa1, 0x3a, 0xe4, 0x21, 0x2e, 0x36, 0x7e, 0xd1, 0xdc, 0x73, 0xc7, + 0x3a, 0x80, 0x4d, 0xc5, 0x26, 0x69, 0xf4, 0xf3, 0xa5, 0x95, 0xb7, 0xe5, + 0xbb, 0xc5, 0x72, 0x51, 0xa5, 0xc4, 0xee, 0xb8, 0x02, 0x23, 0x1e, 0x70, + 0x5c, 0x66, 0xd0, 0xdf, 0x89, 0x16, 0x68, 0xaa, 0x21, 0x22, 0x84, 0x8a, + 0xb8, 0x6a, 0x8f, 0x0c, 0x6a, 0xce, 0xd3, 0x0f, 0x1a, 0xb2, 0x2d, 0x6f, + 0x4e, 0x2b, 0x34, 0x01, 0xe0, 0xb8, 0xe7, 0xb8, 0x22, 0xed, 0x76, 0xc2, + 0xd4, 0x72, 0xcb, 0x03, 0x1b, 0xc5, 0x7c, 0x75, 0xce, 0xf4, 0x7e, 0xd0, + 0xa2, 0xca, 0xa5, 0xc2, 0xa8, 0xe8, 0xca, 0xb7, 0x9b, 0x43, 0xae, 0x12, + 0x1b, 0xfa, 0xe7, 0xfb, 0xb0, 0x41, 0xfc, 0xf2, 0x38, 0x03, 0xec, 0xe3, + 0x6c, 0x1d, 0x2b, 0xf8, 0xaf, 0x2d, 0x42, 0x30, 0x94, 0xdf, 0xb3, 0x9d, + 0xaa, 0xaa, 0xdf, 0xcf, 0x3d, 0x9b, 0xdb, 0xec, 0x8a, 0x02, 0x2d, 0x38, + 0x7b, 0x7e, 0xb4, 0x00, 0x6d, 0x01, 0x07, 0xf6, 0x3f, 0x84, 0x77, 0xe0, + 0x25, 0x00, 0x25, 0xec, 0xd9, 0x00, 0x47, 0x06, 0xb5, 0x40, 0xf6, 0xa8, + 0x1e, 0xdf, 0xd9, 0x78, 0x03, 0x2d, 0xa1, 0xc5, 0x56, 0xe4, 0xe0, 0x19, + 0xc4, 0x66, 0xe0, 0x0c, 0x5a, 0xdb, 0xb6, 0xed, 0xea, 0xe2, 0x99, 0x1b, + 0x99, 0xc7, 0xe1, 0xb9, 0x62, 0x2c, 0x96, 0x49, 0xb6, 0x0d, 0x8b, 0x1b, + 0x8f, 0xf6, 0xd0, 0x03, 0xcf, 0x77, 0xe4, 0x99, 0x4f, 0x9b, 0x2c, 0x59, + 0xb2, 0xc0, 0xa6, 0x50, 0xaa, 0xd1, 0x2a, 0x37, 0xeb, 0x05, 0x02, 0x17, + 0xfb, 0xa6, 0xcf, 0x41, 0xad, 0xea, 0x25, 0x36, 0x54, 0x6f, 0xce, 0xdf, + 0xcf, 0x69, 0xae, 0x14, 0xe5, 0xc5, 0x39, 0xe2, 0xe0, 0xb7, 0x38, 0xd2, + 0xbf, 0x15, 0x2c, 0xda, 0x75, 0xb0, 0x69, 0x71, 0xbe, 0xde, 0x20, 0x10, + 0x80, 0x2f, 0xdd, 0xf3, 0xd6, 0x22, 0xb6, 0x3c, 0x5f, 0x37, 0x16, 0x42, + 0x65, 0x29, 0xb8, 0x5b, 0x78, 0x09, 0x97, 0xa0, 0x4d, 0x00, 0x34, 0x6d, + 0xbd, 0xc4, 0x14, 0x2f, 0x41, 0x30, 0x01, 0x26, 0x94, 0xde, 0x2c, 0x8d, + 0xd0, 0x05, 0x62, 0x3d, 0x95, 0xda, 0x1b, 0x39, 0xe3, 0x69, 0x70, 0xe3, + 0x8b, 0x29, 0xbd, 0x58, 0x80, 0x0a, 0x75, 0xcf, 0x2c, 0x26, 0x6b, 0x96, + 0x90, 0x95, 0xa7, 0x8d, 0x97, 0x87, 0xca, 0x00, 0x34, 0x2f, 0xd1, 0x2b, + 0x10, 0x99, 0x54, 0x84, 0xdf, 0x3c, 0x01, 0xb8, 0x9c, 0xf2, 0xae, 0x97, + 0x1d, 0x16, 0xd7, 0xcc, 0x40, 0x1c, 0xc5, 0xba, 0x70, 0xf6, 0xf3, 0x7c, + 0x7f, 0x2d, 0xf9, 0xf8, 0x13, 0x7d, 0xa5, 0x01, 0xe3, 0xf1, 0xe8, 0x56, + 0x54, 0x45, 0x5c, 0x2d, 0x1a, 0xcf, 0x8d, 0x22, 0x00, 0x3a, 0xfb, 0xe5, + 0x15, 0xd8, 0xbc, 0x2a, 0xcb, 0xaf, 0x4b, 0x32, 0xf0, 0xf8, 0x6c, 0x83, + 0x4e, 0x1a, 0xde, 0x4c, 0x10, 0x00, 0xb0, 0x48, 0x01, 0xb0, 0x05, 0xb7, + 0xdf, 0x38, 0xd8, 0xb5, 0x09, 0xd8, 0x4d, 0xba, 0x93, 0x15, 0x5b, 0xe7, + 0xf3, 0xd9, 0xfc, 0x98, 0x6d, 0x90, 0x71, 0xc3, 0x4e, 0x18, 0x1a, 0x48, + 0x6c, 0x77, 0x2d, 0x8a, 0xad, 0xfb, 0x80, 0x07, 0x4b, 0xc7, 0x66, 0xf0, + 0xfc, 0x0c, 0xb3, 0x1e, 0x51, 0x44, 0x8a, 0xde, 0x64, 0x00, 0xb3, 0xdf, + 0x8f, 0x61, 0x78, 0x6f, 0x1d, 0xe4, 0x2d, 0x2c, 0xd8, 0x53, 0xcc, 0x0e, + 0xb5, 0xbe, 0x32, 0xff, 0x69, 0x40, 0x1e, 0x57, 0x3b, 0x1d, 0x4a, 0xbb, + 0x26, 0xe3, 0xcf, 0xee, 0x87, 0xe2, 0x4a, 0x74, 0x30, 0xe4, 0x6e, 0x50, + 0x00, 0x9f, 0x8c, 0x7a, 0x0a, 0xe9, 0xc3, 0x00, 0x2d, 0x7c, 0xc9, 0x6d, + 0xfc, 0x5b, 0x2d, 0x92, 0x51, 0xaa, 0x53, 0x7d, 0x01, 0x93, 0x55, 0x20, + 0x1b, 0x6e, 0xae, 0x64, 0xa4, 0xc8, 0xdf, 0xa6, 0xe0, 0x8b, 0xf6, 0x23, + 0x7d, 0x3d, 0xba, 0xf6, 0x78, 0xbf, 0x25, 0xf2, 0xdd, 0xa8, 0xbb, 0xa3, + 0x64, 0x5a, 0x52, 0xa4, 0x29, 0xa8, 0xfb, 0x00, 0x3b, 0x7e, 0x76, 0x41, + 0xef, 0xd9, 0xcf, 0x92, 0xcf, 0x37, 0x87, 0x2f, 0x94, 0x87, 0x59, 0x14, + 0x62, 0xb7, 0x91, 0x82, 0x7e, 0xae, 0xc3, 0x7e, 0x66, 0x4c, 0x2f, 0x05, + 0x3a, 0x19, 0x34, 0xad, 0xa6, 0x94, 0x70, 0xc6, 0xf5, 0x60, 0x09, 0x67, + 0x42, 0xdf, 0xb1, 0xdf, 0x3a, 0xa1, 0xd4, 0x6d, 0x44, 0x90, 0xba, 0x3c, + 0x73, 0x59, 0x6d, 0xd0, 0x13, 0x5b, 0xec, 0xfb, 0x08, 0xe9, 0xd9, 0xdd, + 0x10, 0x00, 0xf4, 0x5e, 0x5b, 0x2e, 0x3f, 0x45, 0xc0, 0x45, 0x00, 0x6d, + 0xb4, 0xd2, 0x6a, 0x9e, 0x50, 0xf6, 0xf2, 0x1f, 0x40, 0x07, 0xe2, 0xfa, + 0x4c, 0x00, 0x3e, 0x14, 0xe9, 0x25, 0x9e, 0xce, 0xc2, 0x91, 0xd0, 0x37, + 0xd6, 0x8f, 0x6e, 0x6f, 0xf5, 0xf9, 0xcf, 0x0e, 0xf3, 0x88, 0x04, 0x3b, + 0x9c, 0xd2, 0x61, 0xb1, 0x52, 0x98, 0xa5, 0x29, 0xfe, 0x8d, 0xb8, 0x00, + 0x4e, 0xe7, 0x0b, 0xda, 0x65, 0x45, 0xb8, 0x1d, 0x0d, 0x54, 0x55, 0x21, + 0x2b, 0x38, 0xc3, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, 0xf3, 0xc0, 0x0f, + 0xbd, 0x85, 0x00, 0x3b, 0xfb, 0x8a, 0xeb, 0x9e, 0x5c, 0x74, 0x97, 0xca, + 0x4d, 0xd3, 0x21, 0x32, 0x45, 0x52, 0xbd, 0x20, 0xe6, 0xfb, 0x10, 0x20, + 0x01, 0x6b, 0xaf, 0xd7, 0xa9, 0xcf, 0xd1, 0xd7, 0x6f, 0xee, 0x72, 0x65, + 0xdc, 0x86, 0x87, 0x4a, 0xa5, 0x15, 0xe2, 0xdf, 0x0a, 0x7d, 0xf3, 0xb2, + 0x44, 0x1c, 0x51, 0x48, 0xde, 0x82, 0x6d, 0x7c, 0x6e, 0x51, 0xf5, 0xbc, + 0xa2, 0xa5, 0x2d, 0xbe, 0x71, 0x1e, 0xdf, 0x61, 0x7d, 0x2a, 0xc3, 0xe6, + 0xaf, 0x56, 0x13, 0xd6, 0x1d, 0xf9, 0x88, 0x77, 0x8c, 0x6d, 0x54, 0x0c, + 0x20, 0x26, 0xff, 0xdd, 0x80, 0x02, 0xd2, 0x43, 0x6a, 0xd5, 0x73, 0xb5, + 0xef, 0x50, 0xa9, 0x13, 0x50, 0x23, 0x56, 0x95, 0x42, 0x47, 0x35, 0xdf, + 0x34, 0x50, 0x03, 0x7f, 0xb7, 0xd8, 0x4b, 0x9e, 0xa3, 0x2a, 0x89, 0xc0, + 0xba, 0x55, 0xbb, 0x4a, 0x0b, 0x2d, 0xb9, 0x6d, 0x5b, 0x2b, 0x03, 0x29, + 0x24, 0x0e, 0x6f, 0xd2, 0x80, 0x3b, 0x50, 0x05, 0x7f, 0xcf, 0x8d, 0xc3, + 0x87, 0x76, 0xfd, 0x93, 0x89, 0x60, 0x23, 0xff, 0xed, 0xfd, 0x46, 0xf8, + 0x80, 0xb3, 0x40, 0x1e, 0x09, 0xf8, 0xb4, 0x2e, 0x68, 0x8d, 0x14, 0xfb, + 0x01, 0x28, 0x01, 0x75, 0xc4, 0x86, 0xfd, 0xa9, 0xbd, 0xf9, 0x80, 0x3b, + 0xef, 0x9b, 0x68, 0xeb, 0x7b, 0x73, 0xf7, 0x38, 0x48, 0x5a, 0x07, 0x5b, + 0x0e, 0x38, 0x75, 0x6f, 0xca, 0x42, 0xaf, 0x3f, 0xce, 0xbf, 0xef, 0xb6, + 0x86, 0x71, 0x2d, 0x11, 0xed, 0x31, 0xc3, 0x49, 0xae, 0xe1, 0x57, 0x42, + 0x54, 0x63, 0x68, 0x4c, 0x90, 0x0b, 0x62, 0xd2, 0xdb, 0xf1, 0x6e, 0xa4, + 0xfb, 0x25, 0x8d, 0xf7, 0xd7, 0x72, 0xf7, 0x38, 0x01, 0xef, 0x74, 0x5b, + 0xb0, 0x65, 0xe0, 0x57, 0xcf, 0x7d, 0xee, 0x45, 0x3c, 0x08, 0x40, 0x08, + 0x13, 0x1b, 0xe4, 0xc0, 0x0f, 0xd4, 0x01, 0x18, 0x03, 0xef, 0xa7, 0x28, + 0x17, 0x5f, 0x6f, 0x19, 0x07, 0x1f, 0x29, 0x70, 0x2a, 0xa3, 0x7e, 0x94, + 0x00, 0x5b, 0x98, 0x23, 0x9e, 0x70, 0x50, 0x9e, 0x60, 0xc0, 0xfe, 0x37, + 0x62, 0x43, 0xec, 0x2c, 0x30, 0x2d, 0xbc, 0x1e, 0x85, 0x51, 0x06, 0x3f, + 0x98, 0xa1, 0x97, 0xf4, 0xad, 0x89, 0x86, 0x1f, 0xea, 0x31, 0xbf, 0xcf, + 0x40, 0x0f, 0xe6, 0x70, 0xfd, 0xb2, 0x51, 0xf4, 0xdb, 0x64, 0x8d, 0xc9, + 0xf7, 0xec, 0x00, 0xf1, 0xd6, 0xed, 0x81, 0xb1, 0x68, 0xc8, 0xdd, 0xe1, + 0x58, 0x00, 0x65, 0xe6, 0xf2, 0xf2, 0x9e, 0x4c, 0x96, 0xac, 0xf0, 0x6f, + 0x9f, 0x09, 0x9d, 0x09, 0xf8, 0x5a, 0x90, 0x25, 0xda, 0x1d, 0x29, 0xf0, + 0x6b, 0x75, 0x82, 0x1f, 0xfd, 0x4d, 0x84, 0x2a, 0xc2, 0x1a, 0xad, 0xe1, + 0xf9, 0x2f, 0xb8, 0xf4, 0x0a, 0xd7, 0x64, 0x56, 0x5e, 0x6d, 0xcc, 0x7f, + 0x25, 0x86, 0xcb, 0x76, 0x44, 0x90, 0x2a, 0x01, 0xed, 0xde, 0x7e, 0xa0, + 0xb7, 0xdf, 0x4a, 0x38, 0x29, 0x98, 0x4d, 0x37, 0xad, 0x76, 0xcf, 0x16, + 0xeb, 0x90, 0xb2, 0x9b, 0x5c, 0x1a, 0xdf, 0x8e, 0xe5, 0x5c, 0x6d, 0xa8, + 0x14, 0xb2, 0x7a, 0xd2, 0xdb, 0xd6, 0xc7, 0xcf, 0x9a, 0x92, 0xd0, 0xbd, + 0x76, 0xec, 0xd0, 0xa8, 0xb5, 0x4a, 0x0c, 0xaa, 0xd8, 0xbb, 0x80, 0x16, + 0x53, 0x37, 0x65, 0x0b, 0xa3, 0x42, 0xda, 0x02, 0x1f, 0xfd, 0x66, 0x3e, + 0x50, 0xab, 0x72, 0x12, 0x49, 0x05, 0xb6, 0xf9, 0xf9, 0x8d, 0xd7, 0x00, + 0x29, 0x6f, 0x4c, 0xd2, 0x78, 0xb1, 0x49, 0x02, 0x56, 0xbf, 0x0a, 0xb0, + 0x24, 0x63, 0x59, 0xde, 0xcf, 0x2b, 0x2b, 0xd4, 0x00, 0x53, 0x04, 0x41, + 0x4e, 0xb6, 0x82, 0x3f, 0xfe, 0x64, 0xa0, 0x51, 0xed, 0x97, 0x6d, 0xcd, + 0xdd, 0x93, 0x46, 0x95, 0x9c, 0x19, 0x36, 0x8d, 0xa5, 0x9a, 0x51, 0x61, + 0x2d, 0xd8, 0xee, 0x00, 0x1e, 0xbb, 0xaa, 0xf7, 0x0f, 0xae, 0x97, 0x33, + 0x5e, 0xf0, 0xc3, 0xd6, 0x15, 0x09, 0x2d, 0xd0, 0xdd, 0xc3, 0x9b, 0xaf, + 0xac, 0xa4, 0x5c, 0xba, 0x96, 0x45, 0x59, 0xba, 0x31, 0xba, 0x1c, 0xbe, + 0x6f, 0x9e, 0xdc, 0x00, 0x85, 0xdb, 0x0d, 0x42, 0x8e, 0x09, 0x6a, 0x74, + 0x9f, 0xf2, 0xfc, 0xe5, 0xd6, 0x86, 0xa7, 0x46, 0x50, 0xf0, 0x11, 0x9e, + 0x5b, 0x0a, 0xaf, 0xfb, 0xf5, 0x24, 0x09, 0x8f, 0xb2, 0x10, 0xe8, 0xca, + 0xd0, 0xda, 0x9e, 0xd8, 0xc4, 0xf9, 0xef, 0xa4, 0x08, 0x5d, 0x29, 0x14, + 0x2a, 0x36, 0xfb, 0x40, 0x2b, 0x17, 0xc7, 0x21, 0xe1, 0x16, 0x64, 0x73, + 0xe0, 0x5e, 0xfe, 0xa0, 0x59, 0x4d, 0x57, 0x69, 0xf6, 0x13, 0x9c, 0x72, + 0x81, 0x69, 0x13, 0x40, 0xea, 0xd4, 0x67, 0x37, 0xdb, 0x1e, 0xed, 0xd0, + 0x4a, 0xff, 0x9c, 0xca, 0x58, 0x40, 0xef, 0x05, 0x6b, 0x64, 0xde, 0x8a, + 0xbc, 0xc7, 0xd9, 0x14, 0x08, 0xdb, 0x9e, 0xf2, 0x4a, 0x30, 0x07, 0x33, + 0x88, 0x96, 0x85, 0x37, 0x87, 0xc8, 0x68, 0x8f, 0x6c, 0x7e, 0x84, 0xdb, + 0x68, 0x7a, 0x04, 0x23, 0x7d, 0x02, 0x82, 0x10, 0x03, 0x89, 0xf6, 0xc9, + 0x94, 0x12, 0x3f, 0xf7, 0x1d, 0x39, 0x77, 0x8e, 0x19, 0xb2, 0x90, 0xdb, + 0xe6, 0x8f, 0x90, 0x57, 0xd7, 0xae, 0x65, 0x0a, 0xc1, 0x56, 0x1a, 0xa7, + 0x9f, 0x06, 0xc0, 0xb6, 0x88, 0x53, 0x71, 0xd0, 0x30, 0x53, 0x7e, 0xe9, + 0xe9, 0xd1, 0x1c, 0x5e, 0x3b, 0xc7, 0x83, 0x16, 0xdf, 0x46, 0xf7, 0x9f, + 0xc8, 0x08, 0x3f, 0x95, 0xcf, 0xf8, 0x4a, 0x50, 0x49, 0xff, 0xde, 0x2c, + 0x80, 0x96, 0x00, 0x65, 0x12, 0x5b, 0xe0, 0x62, 0xac, 0x77, 0x9e, 0xdc, + 0x83, 0x12, 0x4a, 0x54, 0xf0, 0x6f, 0xb7, 0x7b, 0xc0, 0x41, 0xfc, 0x40, + 0x01, 0x16, 0x20, 0x04, 0x37, 0x99, 0x28, 0x59, 0x8b, 0x69, 0x29, 0xad, + 0x4e, 0x24, 0xb6, 0x14, 0xba, 0xdf, 0xec, 0x25, 0x41, 0xbe, 0x8a, 0xde, + 0x30, 0x01, 0xf3, 0xc1, 0x04, 0x06, 0x40, 0x1f, 0xfc, 0x8a, 0x77, 0x8d, + 0xe1, 0xf5, 0x60, 0x08, 0xaa, 0x07, 0xc0, 0xa6, 0xf5, 0x90, 0xaa, 0x00, + 0x2e, 0x6f, 0xcb, 0xe0, 0x0f, 0x90, 0x10, 0x00, 0xeb, 0x8e, 0x3e, 0xba, + 0x09, 0x7f, 0xf7, 0x49, 0xce, 0xa3, 0x0e, 0xb4, 0x9b, 0xe3, 0x0e, 0x6d, + 0x4e, 0xad, 0xbc, 0x29, 0x5b, 0xf0, 0x00, 0x0c, 0x3d, 0xba, 0x7f, 0xdb, + 0x8c, 0xf8, 0xce, 0x20, 0xfd, 0xe7, 0x7c, 0xa6, 0x2d, 0x0d, 0x39, 0xac, + 0xff, 0x0a, 0xe1, 0xfd, 0x57, 0xd7, 0xe4, 0x91, 0x77, 0x5f, 0xb9, 0x61, + 0xb6, 0xda, 0x87, 0xa0, 0xe0, 0x96, 0xe0, 0x89, 0xf2, 0xe4, 0xd8, 0xb5, + 0x00, 0x95, 0x1c, 0xad, 0xab, 0xce, 0x80, 0x3b, 0x00, 0x32, 0xc1, 0x5b, + 0x2c, 0x04, 0x6f, 0xfa, 0x7f, 0x91, 0x98, 0x34, 0x9a, 0x6d, 0x89, 0x02, + 0xdb, 0xcf, 0x44, 0x76, 0xda, 0x42, 0x46, 0xe5, 0xb0, 0x39, 0x5b, 0xfd, + 0x1f, 0xf7, 0xea, 0x82, 0x07, 0xe7, 0xf1, 0x08, 0x9e, 0xd7, 0x06, 0x79, + 0x79, 0xce, 0x57, 0xbc, 0x1c, 0x1d, 0x83, 0x2d, 0x6e, 0xf8, 0x03, 0x2e, + 0x78, 0x00, 0x4d, 0xce, 0x6f, 0x9d, 0x0c, 0x80, 0x3d, 0x0b, 0x0c, 0x87, + 0xb7, 0x8d, 0x04, 0x00, 0x2a, 0x73, 0xc0, 0x1b, 0x39, 0xef, 0xf9, 0x17, + 0x69, 0x6b, 0x99, 0xca, 0xd3, 0x62, 0xd3, 0x6c, 0x50, 0x96, 0xf9, 0xd8, + 0xae, 0x35, 0xdf, 0x13, 0x20, 0x8b, 0x85, 0xa6, 0x4c, 0x45, 0x8b, 0x36, + 0xae, 0x97, 0x7c, 0x5b, 0x67, 0xd8, 0x6b, 0xf7, 0x69, 0x08, 0xa6, 0xea, + 0xe4, 0xbb, 0xb6, 0xd0, 0x29, 0xbf, 0xa5, 0x80, 0x17, 0x7d, 0x4d, 0xf7, + 0xbb, 0xf3, 0xc3, 0xb9, 0x8a, 0x86, 0xa0, 0xc9, 0x85, 0x17, 0x10, 0xf3, + 0xc3, 0x15, 0xbc, 0x68, 0x03, 0x22, 0x37, 0x5d, 0x7b, 0x0a, 0x70, 0x05, + 0xbe, 0xd6, 0x93, 0x79, 0x78, 0xdd, 0x32, 0x40, 0xf1, 0xc5, 0x2b, 0x64, + 0x00, 0x71, 0xf6, 0xe6, 0x7b, 0xc5, 0x78, 0x9d, 0xb0, 0x9b, 0x77, 0x6a, + 0xdd, 0x58, 0x92, 0x14, 0x10, 0x34, 0xb6, 0xe6, 0x00, 0x36, 0x23, 0x70, + 0x66, 0x2d, 0xef, 0x6f, 0xed, 0xdc, 0x21, 0xd9, 0x0f, 0xa5, 0x86, 0xb2, + 0x7e, 0xd7, 0xf3, 0xbb, 0xb7, 0xc5, 0xb7, 0x7d, 0x37, 0x6d, 0xad, 0xf5, + 0xba, 0x00, 0x39, 0xde, 0x65, 0xdd, 0xe7, 0x30, 0x10, 0xc0, 0x18, 0x50, + 0xa7, 0x18, 0x92, 0xe6, 0xed, 0x1a, 0xef, 0xd5, 0x8d, 0x90, 0x01, 0xe7, + 0x64, 0x77, 0x89, 0xc5, 0xf6, 0x32, 0xd0, 0xff, 0x67, 0x47, 0x48, 0x90, + 0x83, 0x4d, 0xd8, 0x4b, 0xad, 0xe6, 0xc5, 0x3a, 0x74, 0x22, 0x4e, 0x84, + 0x70, 0x34, 0xd9, 0xc6, 0x7e, 0xf6, 0xd3, 0x82, 0x9a, 0xe7, 0xed, 0x79, + 0x8f, 0x5e, 0x72, 0xa2, 0xb8, 0xcd, 0x28, 0x98, 0x1c, 0x3a, 0x94, 0x06, + 0xdb, 0x48, 0xda, 0xd6, 0xfb, 0xa4, 0x4e, 0x05, 0x70, 0x46, 0xda, 0xef, + 0x7a, 0xfc, 0x53, 0x04, 0xf2, 0xf9, 0x0e, 0x98, 0x52, 0x87, 0xc8, 0x3e, + 0xd6, 0x6f, 0x60, 0x07, 0xa4, 0x71, 0x3d, 0xe6, 0xbf, 0x8c, 0x53, 0x03, + 0xac, 0xb1, 0x46, 0x14, 0x54, 0x1d, 0x06, 0xb7, 0x20, 0x00, 0xf7, 0xa7, + 0x77, 0xb1, 0xd3, 0x99, 0x8a, 0x82, 0xf4, 0x80, 0xbe, 0x72, 0xca, 0x38, + 0xa3, 0xe1, 0xde, 0xad, 0x97, 0xd9, 0xe2, 0xfd, 0xf9, 0x90, 0xc9, 0x46, + 0xa9, 0xb5, 0x10, 0xc8, 0x04, 0x1e, 0xa3, 0x98, 0xf1, 0x66, 0xdf, 0xa3, + 0x00, 0x58, 0xef, 0x97, 0x59, 0xcf, 0xd7, 0xdd, 0xfb, 0x4e, 0x99, 0x6a, + 0x80, 0xe3, 0x0f, 0x38, 0x61, 0x4d, 0xc0, 0xae, 0xeb, 0x32, 0xb8, 0x43, + 0xa1, 0x45, 0x16, 0x91, 0x0b, 0x0a, 0x6c, 0xde, 0xcb, 0x4c, 0x20, 0x4c, + 0x39, 0x74, 0xa8, 0x56, 0x8e, 0xf0, 0x02, 0xdb, 0xa7, 0xf1, 0x9c, 0xc7, + 0x50, 0x0b, 0x7b, 0xda, 0x74, 0x2e, 0xa2, 0xc7, 0x43, 0xd9, 0xc6, 0x6d, + 0xf9, 0xf3, 0x74, 0xcc, 0x36, 0x62, 0x8d, 0xa6, 0x1e, 0x8a, 0x58, 0x6b, + 0x27, 0x79, 0x5f, 0x83, 0x69, 0xe1, 0x65, 0x56, 0xee, 0x7c, 0xba, 0x8b, + 0xd9, 0x72, 0x00, 0x45, 0x98, 0x61, 0x67, 0x31, 0x7d, 0xe0, 0x57, 0xbd, + 0x58, 0x13, 0xb0, 0xeb, 0x3d, 0x51, 0x15, 0x86, 0x55, 0x80, 0x00, 0x00, + 0x01, 0x09, 0x43, 0xf1, 0xf9, 0x49, 0xf9, 0x85, 0x04, 0xad, 0x6e, 0xaf, + 0x32, 0x6e, 0x16, 0xdf, 0x2a, 0x77, 0x52, 0x11, 0xf8, 0xb7, 0x60, 0xe5, + 0x32, 0xc8, 0x58, 0xc2, 0xca, 0x4a, 0xa1, 0x2d, 0xf6, 0xba, 0x47, 0x22, + 0x00, 0x2d, 0x00, 0x7d, 0xbb, 0xbc, 0xdd, 0x4b, 0x49, 0xdd, 0x88, 0xe6, + 0x07, 0x2e, 0x07, 0xc3, 0xa5, 0x1a, 0x8d, 0xe5, 0xb8, 0xa6, 0xf3, 0x55, + 0x5b, 0xc0, 0xf7, 0x49, 0xde, 0xf0, 0x42, 0x36, 0x4b, 0xe0, 0xb6, 0x2b, + 0x6f, 0x73, 0xf4, 0x51, 0x1c, 0x01, 0xe7, 0xdb, 0x9a, 0x13, 0x7b, 0xf9, + 0x15, 0x1c, 0x4f, 0x04, 0x80, 0x03, 0xdd, 0x2f, 0x8a, 0x15, 0x0e, 0xa7, + 0xb7, 0xa8, 0x16, 0x45, 0xf6, 0xfa, 0x11, 0x4d, 0xf8, 0x82, 0xcc, 0x36, + 0xe6, 0xbf, 0x2f, 0x95, 0x55, 0x86, 0x7e, 0xad, 0x3d, 0x4b, 0x90, 0x21, + 0xba, 0x22, 0x7b, 0xa0, 0x0f, 0xbe, 0x9f, 0x77, 0x73, 0xc5, 0x8f, 0x7f, + 0x2f, 0x7d, 0x9b, 0x1f, 0xb1, 0xfa, 0xfd, 0x44, 0x43, 0xca, 0x8e, 0x0b, + 0x56, 0xe7, 0x75, 0xf2, 0xa3, 0x02, 0xab, 0x2d, 0x44, 0x6f, 0xd8, 0x73, + 0xae, 0x23, 0x7f, 0x04, 0xee, 0x3e, 0x00, 0x0a, 0x5d, 0xcf, 0x4b, 0x38, + 0xc9, 0x03, 0xc0, 0x4b, 0x0a, 0x43, 0x0a, 0xad, 0xf0, 0x40, 0x03, 0xb8, + 0xe7, 0xf9, 0xfb, 0x58, 0x7a, 0x6d, 0xd9, 0x9b, 0x57, 0x07, 0x15, 0x8a, + 0x6d, 0x0a, 0x46, 0xfd, 0x0f, 0xf4, 0x16, 0x00, 0x6b, 0xc7, 0xff, 0xb1, + 0x51, 0xf2, 0x9f, 0x78, 0xcd, 0x00, 0xb7, 0x6e, 0x53, 0xa9, 0x34, 0x3e, + 0x9b, 0x0e, 0x1b, 0x1b, 0xf2, 0x63, 0xe4, 0x11, 0x82, 0xa4, 0x80, 0x94, + 0x00, 0x66, 0x52, 0x51, 0x25, 0x9e, 0x16, 0xab, 0x3d, 0x23, 0x48, 0x0e, + 0x35, 0xbf, 0xae, 0x08, 0xfa, 0xb8, 0x10, 0x3f, 0x2c, 0x4e, 0x8b, 0xe3, + 0xbb, 0x40, 0x8e, 0x3e, 0x38, 0xeb, 0x88, 0xf9, 0xb0, 0xf0, 0xf7, 0xed, + 0xab, 0x14, 0x32, 0x14, 0xdf, 0x50, 0xf9, 0xf8, 0xc0, 0x02, 0x8e, 0x1c, + 0xe8, 0xb0, 0x11, 0xff, 0xee, 0xdb, 0x69, 0x60, 0x3c, 0x58, 0x52, 0x12, + 0x5b, 0xf2, 0xfe, 0x80, 0x53, 0x5b, 0xf4, 0x38, 0x03, 0xc7, 0xc0, 0x04, + 0xff, 0xe1, 0x7f, 0xdf, 0xb4, 0xc8, 0x08, 0xc0, 0x0a, 0xb4, 0x0c, 0xa6, + 0x07, 0x50, 0x1c, 0xd1, 0x88, 0x58, 0xd1, 0xb5, 0xb9, 0x75, 0x1d, 0xd3, + 0xf5, 0x7c, 0x21, 0x49, 0x4e, 0x1f, 0x5b, 0x38, 0x5b, 0xae, 0xcf, 0x04, + 0x3d, 0xbf, 0xce, 0x9f, 0x71, 0x0f, 0x00, 0x2e, 0xfb, 0xbb, 0x1d, 0x65, + 0x01, 0xe6, 0xbc, 0x46, 0xbb, 0x60, 0xca, 0x58, 0x45, 0x25, 0xb7, 0xce, + 0x3a, 0xe8, 0x02, 0xbe, 0xdc, 0x4f, 0x2c, 0x62, 0xc3, 0x15, 0xbf, 0x5c, + 0x00, 0x30, 0x17, 0xa0, 0x80, 0x05, 0x59, 0xef, 0xff, 0x16, 0x22, 0x4f, + 0xd7, 0x5c, 0x3d, 0xc8, 0x66, 0xd4, 0x27, 0x9d, 0x4d, 0x8b, 0x50, 0x68, + 0xd6, 0xfc, 0xd0, 0xfa, 0xf1, 0x7f, 0x24, 0x67, 0x71, 0x21, 0xd9, 0x5e, + 0x4f, 0xec, 0xc9, 0x93, 0x21, 0x74, 0x3c, 0x74, 0x6e, 0x82, 0x6f, 0x3b, + 0xa8, 0x43, 0xad, 0xa2, 0x96, 0xb5, 0xbc, 0x8f, 0xeb, 0x1c, 0x22, 0x47, + 0x64, 0xf5, 0x3e, 0xda, 0xa3, 0x4b, 0x6b, 0x08, 0xce, 0x00, 0x33, 0xf7, + 0x9b, 0x25, 0x0c, 0xaf, 0x32, 0x19, 0x46, 0xb7, 0xa7, 0x42, 0x01, 0xaf, + 0x7c, 0xb8, 0x03, 0xde, 0x79, 0x93, 0x80, 0xa2, 0xb2, 0x0c, 0x81, 0xa5, + 0xd6, 0xc1, 0xf7, 0x37, 0x0a, 0x44, 0x3d, 0x4a, 0x87, 0x86, 0x00, 0xd5, + 0x96, 0x4b, 0xae, 0x46, 0x4a, 0x52, 0xb7, 0xd0, 0xec, 0x5e, 0x11, 0xb8, + 0x7e, 0xbf, 0xac, 0x2c, 0xad, 0xe7, 0x1f, 0x93, 0x8b, 0x76, 0xa3, 0x8f, + 0x8a, 0x51, 0x94, 0xb4, 0x2b, 0x0f, 0x8d, 0xc0, 0xe6, 0x68, 0x19, 0xca, + 0x9e, 0x25, 0x29, 0x29, 0xb0, 0xf1, 0x28, 0xa1, 0x6e, 0xb7, 0x72, 0x06, + 0x45, 0x58, 0x9e, 0x10, 0x68, 0x4b, 0x52, 0x46, 0xcc, 0x7b, 0xb6, 0xe2, + 0x50, 0xab, 0x0a, 0x02, 0xeb, 0x5d, 0x87, 0x2d, 0xf5, 0x6d, 0xcf, 0xa0, + 0x5b, 0x7d, 0x61, 0x6b, 0xcd, 0xe2, 0xd9, 0x2f, 0x83, 0xf0, 0xaa, 0x10, + 0x31, 0xb7, 0xe4, 0xc8, 0x47, 0x94, 0xde, 0x02, 0xb5, 0xfb, 0x2e, 0x5b, + 0x16, 0x9d, 0xa0, 0x5b, 0x69, 0x23, 0x7e, 0x7b, 0x23, 0x75, 0xbb, 0x29, + 0xd0, 0xbf, 0x7f, 0x3b, 0x4b, 0x0c, 0x30, 0xda, 0x7b, 0x61, 0xd9, 0x39, + 0x14, 0x23, 0x70, 0xc8, 0x55, 0x31, 0xd4, 0xc7, 0x1c, 0x4c, 0x51, 0x81, + 0x67, 0xb7, 0xa0, 0x32, 0xb7, 0xa2, 0x8a, 0x8d, 0xea, 0xf6, 0xcb, 0xe5, + 0x78, 0xd8, 0xa7, 0xd2, 0xd5, 0xd2, 0x1c, 0x58, 0xe1, 0xed, 0xb7, 0x87, + 0xf9, 0x11, 0x95, 0x50, 0x72, 0x6e, 0x17, 0xa3, 0x09, 0x88, 0x31, 0xb9, + 0x76, 0x1b, 0xf3, 0x9b, 0x54, 0x05, 0x77, 0x8d, 0xc2, 0xe1, 0x30, 0x71, + 0xfe, 0xad, 0xd2, 0x17, 0x40, 0x0e, 0x05, 0xbe, 0x97, 0x46, 0x9a, 0x6b, + 0xb3, 0x32, 0x94, 0x04, 0x50, 0xf2, 0xef, 0x8c, 0x29, 0x93, 0x6e, 0xde, + 0x5c, 0xc2, 0x7f, 0x34, 0x9d, 0x81, 0x92, 0x72, 0xfc, 0x9b, 0x47, 0x0d, + 0x28, 0xf0, 0x98, 0xce, 0x45, 0x7c, 0xe8, 0x00, 0xfe, 0x1a, 0x19, 0x49, + 0xce, 0xe4, 0xc4, 0xd8, 0x1b, 0x64, 0xcb, 0x4a, 0x0d, 0x62, 0xe7, 0xef, + 0x59, 0xef, 0xbb, 0x25, 0x1c, 0x82, 0xf4, 0xc9, 0x29, 0xe3, 0x92, 0x92, + 0x1b, 0x1c, 0x33, 0xe1, 0xfd, 0xdb, 0x40, 0x47, 0xe6, 0xe5, 0x51, 0x83, + 0x0d, 0x18, 0x10, 0xd4, 0xd2, 0x73, 0x74, 0x08, 0x96, 0x71, 0x45, 0xe4, + 0xd4, 0x1c, 0x4f, 0x3f, 0x21, 0xd7, 0xc5, 0xb1, 0xdd, 0xa0, 0x0e, 0xbe, + 0x9d, 0x63, 0xed, 0x0d, 0xb3, 0xcf, 0x75, 0x29, 0xe3, 0xf7, 0x6c, 0xf4, + 0xb5, 0x97, 0x94, 0xb9, 0x66, 0x1b, 0xe2, 0x05, 0x1c, 0xdd, 0x5e, 0x45, + 0xc7, 0x6f, 0xe6, 0x4a, 0x59, 0x53, 0x75, 0x4c, 0x1e, 0x70, 0x4d, 0x61, + 0xa6, 0x95, 0x1b, 0xf1, 0x9e, 0xf2, 0x89, 0x99, 0x32, 0xca, 0x39, 0x43, + 0x4e, 0x6f, 0xd3, 0x1f, 0xde, 0xb4, 0x10, 0x3f, 0x2f, 0xee, 0xe2, 0x37, + 0xb7, 0xbc, 0xa5, 0xe6, 0xf5, 0x9d, 0xfb, 0x6b, 0xf5, 0xf9, 0x4f, 0x85, + 0xe5, 0x92, 0x2d, 0x09, 0x2d, 0xbe, 0x46, 0x6c, 0x9b, 0x23, 0xcb, 0x19, + 0x85, 0x86, 0x96, 0x88, 0xa5, 0x37, 0xbf, 0xff, 0x3b, 0x8c, 0x00, 0x79, + 0x77, 0xe3, 0xa1, 0x14, 0xf0, 0x0b, 0x45, 0xba, 0xd5, 0x79, 0xa6, 0xc9, + 0x61, 0x45, 0xda, 0x07, 0xb6, 0x67, 0xa4, 0x6c, 0x39, 0x45, 0x8d, 0xfd, + 0xc4, 0x00, 0xb0, 0x01, 0xf8, 0x8f, 0x6b, 0xcf, 0x9b, 0xaa, 0x5b, 0x16, + 0x21, 0x52, 0x7e, 0xc6, 0xc1, 0x90, 0xf1, 0xad, 0xf9, 0x59, 0x1d, 0xf1, + 0xf6, 0xf8, 0xf8, 0xf6, 0x99, 0x49, 0x86, 0xee, 0x75, 0xc6, 0x61, 0xb7, + 0x2d, 0x5a, 0xbb, 0x0f, 0xda, 0x79, 0xf5, 0xbb, 0xc2, 0xa0, 0x92, 0x7e, + 0xbf, 0x90, 0x0b, 0x61, 0x44, 0xed, 0x26, 0xe5, 0x91, 0xd9, 0x52, 0x69, + 0x95, 0x0b, 0x2e, 0x84, 0x56, 0xc9, 0xd8, 0xae, 0x45, 0x2e, 0x0a, 0x7c, + 0xb4, 0x9b, 0x15, 0x20, 0xfa, 0x6d, 0x2c, 0x28, 0xe6, 0xd2, 0x15, 0x1b, + 0x4d, 0xa5, 0x14, 0xdf, 0x3f, 0x9f, 0x3d, 0x89, 0xba, 0x87, 0x41, 0xaa, + 0x56, 0x0d, 0x56, 0xdf, 0x95, 0xf3, 0xdf, 0x2b, 0xf3, 0x68, 0xc7, 0x60, + 0xc9, 0x4b, 0x38, 0xaa, 0x71, 0x4d, 0x9f, 0xa9, 0x39, 0xdc, 0x5c, 0x29, + 0x7f, 0x57, 0x52, 0xdd, 0x42, 0x9b, 0xa5, 0x9d, 0x3f, 0x7e, 0x2c, 0xb7, + 0x61, 0x41, 0xd0, 0xa8, 0x54, 0x54, 0x0d, 0x38, 0x29, 0xa1, 0xb5, 0xab, + 0x4f, 0x6f, 0x3f, 0xd3, 0x89, 0xd7, 0x55, 0xe4, 0xed, 0xe7, 0x69, 0x35, + 0x06, 0x59, 0x22, 0x97, 0x4b, 0xfd, 0xb2, 0x74, 0x21, 0xf2, 0x45, 0x7d, + 0x50, 0xa3, 0xea, 0xa0, 0xf6, 0xe8, 0xfd, 0x44, 0x65, 0xe8, 0x07, 0x2f, + 0x55, 0xa6, 0xae, 0x52, 0xb1, 0x0a, 0x46, 0xe1, 0x3d, 0xdc, 0x60, 0xbf, + 0x38, 0x6c, 0x28, 0xf3, 0x0a, 0x85, 0x94, 0x3e, 0x56, 0x43, 0x19, 0xb7, + 0xaa, 0xf3, 0x79, 0xcc, 0x9c, 0x61, 0x94, 0xab, 0x62, 0x0c, 0x0a, 0x6d, + 0x80, 0x64, 0x59, 0x1b, 0x88, 0xe7, 0xec, 0x3c, 0x9d, 0x9c, 0xd7, 0xda, + 0xba, 0x8a, 0x34, 0x6b, 0x73, 0x5d, 0xd9, 0x07, 0xbd, 0xbc, 0xb8, 0xa2, + 0xee, 0x63, 0xae, 0x07, 0x5a, 0x85, 0x1e, 0x87, 0xd1, 0x8c, 0x80, 0x07, + 0xd1, 0xde, 0xd3, 0x9c, 0x2c, 0xb5, 0x58, 0x34, 0xb2, 0xe4, 0x0a, 0x8c, + 0xda, 0x63, 0x7d, 0xd1, 0x22, 0xc8, 0x9a, 0xec, 0xd3, 0x0d, 0x01, 0xc7, + 0x2f, 0xe4, 0xe8, 0x1f, 0x28, 0xcd, 0x81, 0x03, 0x55, 0xba, 0x93, 0xfe, + 0xff, 0x6b, 0xce, 0xcd, 0xef, 0x64, 0xd9, 0x8f, 0x9b, 0x2e, 0xdb, 0x38, + 0xc3, 0xe2, 0x0e, 0x29, 0xb8, 0x3f, 0x7e, 0x48, 0xc2, 0x3b, 0xd9, 0xb2, + 0xd3, 0xea, 0xef, 0x26, 0xe4, 0xae, 0x42, 0x8a, 0xa7, 0xdf, 0x02, 0x9b, + 0x3f, 0x26, 0x7c, 0xf4, 0x23, 0x5e, 0x3a, 0x4e, 0x21, 0xa9, 0x6c, 0xb4, + 0x62, 0x4a, 0x1a, 0xc0, 0xd6, 0x8c, 0x4b, 0x95, 0xbc, 0x4f, 0xde, 0x5c, + 0xec, 0x82, 0xde, 0xe2, 0xe9, 0x8e, 0x9c, 0xad, 0xa9, 0x87, 0xd2, 0x1b, + 0x5b, 0xee, 0x88, 0x92, 0xc8, 0x78, 0xd3, 0x88, 0x4d, 0xdf, 0x13, 0x3a, + 0xff, 0x7c, 0xe5, 0x76, 0x65, 0x4a, 0x1e, 0x9e, 0x56, 0x22, 0xd0, 0x21, + 0x07, 0x8f, 0x6f, 0x3b, 0xb6, 0x39, 0xef, 0xf2, 0x33, 0xc7, 0x24, 0xd4, + 0x38, 0x2d, 0x93, 0x69, 0x2a, 0xca, 0xda, 0x71, 0x6c, 0x7b, 0xf5, 0x42, + 0x92, 0x0f, 0x85, 0x46, 0xd9, 0xfc, 0xe7, 0x9f, 0x7e, 0x46, 0x0e, 0x48, + 0x5d, 0x64, 0x7e, 0xdf, 0x9c, 0x97, 0x8d, 0x94, 0x62, 0x1b, 0x84, 0xb4, + 0xa7, 0x05, 0x36, 0x98, 0xfb, 0xa2, 0x5d, 0x73, 0x85, 0xa3, 0x69, 0xea, + 0x50, 0x71, 0xd5, 0x88, 0xcd, 0xb4, 0x23, 0x3a, 0xf1, 0x96, 0x1b, 0xb2, + 0x04, 0x0e, 0x87, 0xfa, 0xb6, 0x67, 0xe4, 0xd7, 0x3a, 0x79, 0x50, 0xc3, + 0x12, 0x97, 0xbe, 0x07, 0x33, 0xba, 0x51, 0x1d, 0x24, 0x7d, 0x1d, 0xaf, + 0xd4, 0x2c, 0xe6, 0xe6, 0xcc, 0x9e, 0x7a, 0xb4, 0x26, 0xca, 0x7a, 0x50, + 0x1e, 0xb3, 0x8d, 0x6c, 0x00, 0x00, 0x01, 0x0a, 0x43, 0xf9, 0x00, 0x03, + 0xbf, 0xe0, 0xb1, 0x5c, 0x93, 0xba, 0x30, 0x72, 0x79, 0xf1, 0x4d, 0x53, + 0xac, 0x3e, 0x58, 0x53, 0x6f, 0xf9, 0x99, 0xc9, 0x1e, 0xf5, 0x2c, 0x80, + 0x4f, 0x96, 0xd8, 0xba, 0x81, 0x8a, 0x39, 0xbd, 0x28, 0x03, 0x87, 0xb8, + 0x8c, 0x29, 0xd6, 0xe4, 0x09, 0xdf, 0x3b, 0xaf, 0xa5, 0xa1, 0xf1, 0x55, + 0x21, 0xc3, 0x1b, 0xce, 0x08, 0xcf, 0x21, 0x4b, 0x2f, 0x8c, 0x6f, 0x1b, + 0x70, 0x9e, 0x4f, 0x8e, 0x50, 0x9c, 0xb1, 0x15, 0xbc, 0x74, 0x1c, 0xde, + 0xd0, 0xee, 0xf1, 0xd3, 0x20, 0x66, 0x61, 0x44, 0xda, 0x15, 0x21, 0x55, + 0xbd, 0x68, 0x03, 0xc7, 0xf1, 0xd7, 0x98, 0xbd, 0x4a, 0x7d, 0x97, 0x97, + 0xbe, 0xee, 0x97, 0x22, 0x42, 0xa8, 0xc8, 0x14, 0xde, 0x14, 0x9b, 0xce, + 0xad, 0x6b, 0x76, 0x51, 0x69, 0x90, 0x28, 0xa3, 0xda, 0x21, 0x52, 0x52, + 0x5b, 0x46, 0x1f, 0x15, 0xbf, 0xa0, 0x7b, 0x25, 0x11, 0xdf, 0x61, 0x20, + 0x13, 0xfe, 0x22, 0x14, 0x58, 0x70, 0xd2, 0xdb, 0xca, 0xda, 0x01, 0x53, + 0xdd, 0xb6, 0x20, 0xc2, 0xe7, 0x8b, 0x71, 0x04, 0x3a, 0x0a, 0xe6, 0x6e, + 0xec, 0x0d, 0x59, 0x12, 0x4f, 0x14, 0xad, 0xba, 0x02, 0x17, 0xfd, 0x3b, + 0x69, 0x2e, 0x92, 0x58, 0x2a, 0xd8, 0xa4, 0x26, 0xac, 0x2b, 0x15, 0xbf, + 0xb6, 0x80, 0x3b, 0x00, 0x5f, 0xec, 0x00, 0x5f, 0xfc, 0x8f, 0xe2, 0x74, + 0xa8, 0x4f, 0xc1, 0x62, 0x35, 0x61, 0x97, 0x13, 0x72, 0x9e, 0x10, 0xdf, + 0x6e, 0x11, 0xff, 0xe7, 0xa0, 0x06, 0x6f, 0xe5, 0xeb, 0xa3, 0x39, 0x79, + 0x97, 0x64, 0xa8, 0x9c, 0x5c, 0x59, 0x07, 0xb7, 0xe4, 0xfe, 0xf9, 0x00, + 0x35, 0xf6, 0x9c, 0xf9, 0xa4, 0x2e, 0x90, 0x3a, 0x49, 0x3b, 0xe4, 0x71, + 0x46, 0xd2, 0xa4, 0x3d, 0xbd, 0x0f, 0xfb, 0xed, 0x9f, 0x04, 0x70, 0x0a, + 0xfe, 0x05, 0x6d, 0x2f, 0xf2, 0x41, 0x5f, 0xc6, 0x61, 0x84, 0x0c, 0xcf, + 0xc2, 0x55, 0xb8, 0x78, 0x63, 0x67, 0xd3, 0xcc, 0xdf, 0x3b, 0x6a, 0x0f, + 0x74, 0x58, 0x81, 0x6d, 0xae, 0x5b, 0xa5, 0xd5, 0x0a, 0x6f, 0x9e, 0x2b, + 0x9a, 0x00, 0xf8, 0x8d, 0x9c, 0x65, 0x5b, 0x57, 0x79, 0x47, 0x48, 0x5d, + 0x55, 0x1a, 0x4a, 0x6f, 0x00, 0x2d, 0x61, 0x91, 0x47, 0x42, 0xc7, 0x48, + 0x51, 0xed, 0xea, 0xf5, 0xdc, 0x00, 0x3a, 0xec, 0x8a, 0x44, 0xec, 0x9f, + 0x00, 0x05, 0x3d, 0x90, 0x33, 0xbe, 0x6e, 0x69, 0xf0, 0x38, 0xb3, 0x2a, + 0x78, 0x94, 0xde, 0x0b, 0xfd, 0x40, 0x2d, 0xd7, 0xeb, 0x90, 0x35, 0x2e, + 0xd5, 0x83, 0x08, 0x4d, 0x35, 0x76, 0x54, 0xb0, 0x30, 0x29, 0xb0, 0xb0, + 0xb6, 0xfa, 0x36, 0xd7, 0xc8, 0xf9, 0x7d, 0x0a, 0xa0, 0x6d, 0xae, 0x27, + 0x10, 0x04, 0xdc, 0x40, 0x85, 0xb1, 0x5b, 0x81, 0xd6, 0x00, 0x19, 0x59, + 0x9a, 0xf0, 0x9b, 0x04, 0xcb, 0x81, 0x87, 0x05, 0xb6, 0x5f, 0xa7, 0x40, + 0x16, 0x08, 0x13, 0xcc, 0x81, 0x31, 0x0c, 0x84, 0xba, 0xdb, 0x4b, 0xe6, + 0xb2, 0x90, 0xd9, 0xd8, 0x39, 0xba, 0x78, 0x80, 0x07, 0xc2, 0x1d, 0x32, + 0xbe, 0x06, 0xcd, 0x47, 0x86, 0x0c, 0x94, 0x69, 0xe1, 0x8d, 0xbb, 0xdc, + 0xd0, 0x03, 0x9a, 0x40, 0x2a, 0xa5, 0x86, 0xe2, 0x26, 0xcf, 0x0d, 0x96, + 0x51, 0xc1, 0x8d, 0x92, 0xd7, 0xfd, 0x76, 0x0a, 0xc7, 0x28, 0xcc, 0x0f, + 0xe7, 0x22, 0x3e, 0x87, 0x43, 0xf4, 0x60, 0x62, 0x16, 0x5b, 0x6b, 0x22, + 0x6d, 0xf6, 0x23, 0x47, 0x62, 0x5a, 0xb6, 0xd8, 0x2b, 0xa8, 0xe9, 0xb7, + 0x76, 0x97, 0x4d, 0xd5, 0xb6, 0x90, 0xdb, 0x3f, 0xd4, 0x25, 0xb6, 0xd4, + 0xb6, 0xef, 0x32, 0x47, 0x45, 0x2c, 0xa3, 0xb3, 0xbd, 0x2b, 0x68, 0x1f, + 0x0a, 0x66, 0xe3, 0x00, 0x0f, 0xa1, 0x39, 0xf4, 0x6a, 0x20, 0x7e, 0x4a, + 0xa8, 0x70, 0xd5, 0x0d, 0x6b, 0x26, 0x5f, 0xbb, 0xf3, 0x64, 0xa1, 0x8b, + 0x5d, 0xbb, 0x2c, 0x08, 0x92, 0x17, 0xe0, 0xd4, 0xb9, 0xcb, 0xce, 0xf7, + 0x14, 0x24, 0x81, 0x66, 0x42, 0x13, 0x77, 0x40, 0x32, 0xa0, 0x5b, 0x7a, + 0x50, 0x0c, 0xcd, 0x24, 0xd6, 0xcb, 0xb5, 0x63, 0x9d, 0x28, 0x61, 0xb9, + 0xdb, 0xb0, 0xc8, 0x83, 0x07, 0x1e, 0x16, 0xdd, 0xb7, 0xe0, 0x00, 0x92, + 0xbd, 0xd2, 0x3a, 0xcf, 0xd0, 0x09, 0x2d, 0xa8, 0x7c, 0x58, 0x89, 0x14, + 0x22, 0xa3, 0x73, 0xfb, 0xb7, 0xdc, 0x40, 0x99, 0x2d, 0x01, 0x54, 0x9a, + 0x85, 0x1c, 0x37, 0x29, 0xc3, 0x4e, 0x6f, 0x57, 0xd7, 0x90, 0x8f, 0x81, + 0x62, 0x5d, 0xcb, 0xac, 0x01, 0x27, 0x90, 0xbc, 0xa9, 0x03, 0xd6, 0x02, + 0x27, 0xfe, 0x5b, 0x22, 0xf8, 0x28, 0xf6, 0xdd, 0xba, 0x23, 0x7c, 0xad, + 0xef, 0x7d, 0x9e, 0x27, 0x8c, 0xb9, 0x07, 0xee, 0xd7, 0x73, 0xbc, 0xef, + 0xe8, 0xe8, 0xa5, 0x7a, 0x37, 0x93, 0xd3, 0x45, 0x66, 0x27, 0x28, 0x19, + 0x6e, 0x6f, 0x9c, 0x18, 0x32, 0xd6, 0xd9, 0x78, 0x82, 0x81, 0x0b, 0xfe, + 0xab, 0xa0, 0xc2, 0xe5, 0x2a, 0xd2, 0x11, 0x5e, 0x25, 0xb6, 0x9c, 0xe5, + 0xef, 0x15, 0xaa, 0xe7, 0x02, 0x40, 0x01, 0x9b, 0xbb, 0x5f, 0xa1, 0x45, + 0x1c, 0x16, 0xc3, 0x4a, 0x23, 0x71, 0xdb, 0xbd, 0xbd, 0x79, 0x96, 0xd2, + 0x63, 0xb2, 0x3e, 0x2c, 0xb2, 0xd3, 0x51, 0x26, 0xf8, 0xb7, 0x4c, 0x49, + 0x31, 0xca, 0x65, 0x29, 0x10, 0xe4, 0xb1, 0x47, 0x35, 0x3f, 0x5e, 0x9f, + 0xc9, 0x75, 0x21, 0x72, 0xfe, 0xa2, 0xae, 0x12, 0xa8, 0xc6, 0xeb, 0xba, + 0xce, 0xc5, 0xde, 0x7a, 0xb4, 0x11, 0xbf, 0xf3, 0x75, 0xcf, 0x92, 0xcc, + 0xc0, 0xe8, 0x54, 0xab, 0x0b, 0x69, 0x67, 0x0f, 0xad, 0xd1, 0x9d, 0xed, + 0x17, 0x97, 0xbe, 0x86, 0xdc, 0x29, 0x4a, 0xbf, 0xaa, 0x36, 0x1c, 0x53, + 0x59, 0xed, 0xf1, 0x1c, 0xf7, 0xef, 0x1d, 0xc9, 0x40, 0x73, 0xb7, 0x56, + 0x3a, 0x64, 0x18, 0x16, 0x59, 0x61, 0x8d, 0x9c, 0x51, 0x05, 0xdd, 0x4a, + 0x27, 0x98, 0x34, 0x3a, 0xf2, 0xa9, 0x91, 0x0a, 0x2b, 0x00, 0xb6, 0x5d, + 0xef, 0x51, 0x5d, 0x62, 0x14, 0x4e, 0x92, 0xd2, 0xb1, 0xc7, 0xda, 0x58, + 0xe5, 0x0c, 0x66, 0xca, 0x16, 0x73, 0x7d, 0x22, 0x27, 0x09, 0x9a, 0x27, + 0xdf, 0x4d, 0x28, 0xb9, 0xba, 0xa8, 0x64, 0x2c, 0xe2, 0x8a, 0x88, 0x53, + 0x5b, 0xf5, 0xe2, 0x68, 0x18, 0x15, 0x24, 0xfd, 0x43, 0x6e, 0xd4, 0x43, + 0xb7, 0x16, 0x0e, 0x29, 0x5b, 0x17, 0x5b, 0x78, 0x78, 0x19, 0xe5, 0x3f, + 0x75, 0xcb, 0xbb, 0x46, 0x28, 0xd8, 0x73, 0x65, 0x8e, 0x77, 0x22, 0xb7, + 0x4d, 0x86, 0x0d, 0xbb, 0x6a, 0x98, 0x30, 0x60, 0x4b, 0x26, 0x1b, 0xb3, + 0xe1, 0xfa, 0x2b, 0xf2, 0x26, 0xa9, 0x52, 0xec, 0xda, 0x76, 0x49, 0x10, + 0x86, 0x31, 0xb4, 0xdf, 0x67, 0xfb, 0xbd, 0xf3, 0x5f, 0xaa, 0x52, 0x47, + 0xd9, 0x09, 0x67, 0x34, 0xde, 0x54, 0x4c, 0xb7, 0x28, 0x4e, 0x43, 0xc0, + 0x7c, 0xd6, 0x71, 0xa4, 0xe9, 0x76, 0xc8, 0xa7, 0x93, 0x6c, 0x98, 0xb4, + 0xb1, 0xb0, 0x74, 0x69, 0x6d, 0x02, 0x5b, 0xbb, 0xd8, 0x52, 0x71, 0xaf, + 0xbc, 0xc5, 0x50, 0xec, 0x94, 0xa8, 0x8a, 0x94, 0xb9, 0x3c, 0x5b, 0x95, + 0xc8, 0xb7, 0x0a, 0x7d, 0x97, 0x31, 0x0e, 0xb2, 0x3a, 0xa9, 0x91, 0x4b, + 0x29, 0x61, 0x5e, 0xac, 0xc4, 0xfa, 0x2a, 0x41, 0x83, 0x2e, 0x9a, 0x92, + 0x0e, 0x1e, 0x48, 0x6d, 0xdf, 0x63, 0x5f, 0x7b, 0xe6, 0xeb, 0xf7, 0x4f, + 0x9f, 0x89, 0x46, 0x42, 0x8b, 0x96, 0x8c, 0x60, 0xf6, 0x84, 0xb2, 0x9c, + 0xde, 0x5d, 0xdd, 0xf9, 0x85, 0xad, 0x9f, 0xa8, 0xa7, 0x59, 0xfa, 0x0c, + 0x1a, 0x16, 0xd7, 0xf3, 0xf3, 0xc7, 0x1c, 0xc9, 0x3a, 0xe0, 0x6d, 0xb5, + 0xd8, 0xb0, 0xe0, 0xc4, 0x6a, 0xba, 0x92, 0x45, 0x3e, 0x9e, 0x62, 0x42, + 0xfc, 0x4f, 0x6c, 0x1c, 0x3e, 0xf2, 0x65, 0x48, 0x75, 0x42, 0xe8, 0xd8, + 0x54, 0x61, 0x8d, 0x39, 0xbf, 0x5b, 0xf3, 0xce, 0x77, 0xf0, 0x27, 0x20, + 0x91, 0x68, 0x4c, 0xfc, 0xde, 0x52, 0x4e, 0x20, 0x66, 0x6c, 0x1b, 0x4a, + 0xa7, 0xc1, 0x8d, 0xcf, 0x13, 0xa2, 0x80, 0x0f, 0xdd, 0x82, 0xe6, 0x17, + 0x16, 0xe4, 0x18, 0x71, 0xa7, 0x28, 0x63, 0x73, 0x1d, 0x2b, 0x8a, 0x2c, + 0xa3, 0xcd, 0x7c, 0x85, 0x2c, 0x6e, 0x87, 0xb3, 0x8d, 0xcd, 0xba, 0xa3, + 0xe4, 0xa6, 0xe2, 0x50, 0xa6, 0x50, 0xa6, 0xdb, 0x75, 0x6d, 0x6e, 0xbf, + 0xc7, 0x96, 0x3b, 0x83, 0x90, 0xa7, 0x22, 0x19, 0x31, 0x14, 0x6a, 0x35, + 0x4e, 0xf3, 0x10, 0x29, 0xce, 0xb7, 0x6d, 0x3c, 0x3e, 0xf6, 0xb6, 0x0c, + 0x19, 0x69, 0xed, 0x5e, 0xdc, 0x11, 0xc6, 0x24, 0x09, 0x99, 0x6a, 0x16, + 0x16, 0x18, 0xda, 0x66, 0xaf, 0x9d, 0x36, 0x8d, 0x43, 0xc9, 0x8a, 0xc4, + 0x65, 0x68, 0x68, 0x16, 0xdf, 0x2b, 0xa7, 0x4e, 0xaf, 0x4f, 0xb2, 0x53, + 0x8a, 0xb6, 0xa5, 0xa4, 0x82, 0xe1, 0x2d, 0xac, 0xe3, 0xbc, 0xe3, 0x92, + 0xe6, 0x28, 0x0f, 0x10, 0xe1, 0x9e, 0x8d, 0x83, 0xab, 0xae, 0x32, 0x49, + 0x11, 0x20, 0xd0, 0x82, 0x9a, 0xcf, 0x8d, 0x7c, 0x73, 0x8d, 0xb6, 0xa8, + 0x10, 0x7d, 0x01, 0xab, 0x07, 0x30, 0x7d, 0x6d, 0xe6, 0x6b, 0x9d, 0xb6, + 0xbe, 0x8c, 0x08, 0x6a, 0x16, 0x72, 0xb2, 0x94, 0x04, 0x64, 0x85, 0xc0, + 0x92, 0xda, 0xae, 0x5d, 0xc6, 0x62, 0x71, 0xa1, 0x36, 0x86, 0x36, 0x0c, + 0xdd, 0xc9, 0x2b, 0xc2, 0xa0, 0x67, 0x84, 0x64, 0xc3, 0x00, 0x00, 0x00, + 0x01, 0x0b, 0x43, 0xf9, 0x16, 0xdf, 0x37, 0xad, 0x9e, 0xa7, 0x46, 0xde, + 0xf0, 0xfc, 0xc2, 0xef, 0x8b, 0x71, 0xd3, 0xcf, 0x16, 0x92, 0x8a, 0x6f, + 0x57, 0xc8, 0x21, 0x7f, 0xc8, 0x16, 0xb5, 0xbc, 0xb8, 0x52, 0xda, 0x43, + 0x6f, 0x16, 0x37, 0x5b, 0xd7, 0x0f, 0x0a, 0x1e, 0x1a, 0xd2, 0x53, 0x39, + 0xa0, 0x5b, 0x6c, 0x9f, 0x8b, 0x72, 0x7a, 0xca, 0xdc, 0xa9, 0x25, 0xc9, + 0x00, 0x20, 0x43, 0xa8, 0x09, 0x69, 0xed, 0x3a, 0x1f, 0x23, 0x4d, 0x2d, + 0xbe, 0x59, 0x84, 0x04, 0x99, 0x40, 0x47, 0x0c, 0x85, 0x85, 0x97, 0x49, + 0x2d, 0xda, 0x04, 0x3f, 0xfa, 0xb4, 0x92, 0xdc, 0x48, 0x08, 0x40, 0x0e, + 0x4e, 0x2b, 0xd7, 0x6d, 0x25, 0x95, 0x09, 0x4d, 0xe9, 0x39, 0xcb, 0xc9, + 0xb8, 0x43, 0xb1, 0xb1, 0xa3, 0x09, 0x0c, 0x8e, 0x46, 0xfa, 0x72, 0x10, + 0x76, 0x66, 0xdf, 0x0d, 0xb2, 0x2b, 0x68, 0x00, 0x6c, 0x28, 0x00, 0xf9, + 0xe4, 0x45, 0x35, 0x6a, 0x62, 0xd2, 0x21, 0x19, 0xe0, 0x66, 0x80, 0x47, + 0x69, 0xc1, 0x2a, 0x8c, 0x45, 0xc8, 0x2f, 0x2e, 0x2d, 0x38, 0xa5, 0x1b, + 0x83, 0x61, 0x55, 0xbd, 0x29, 0x17, 0xef, 0x84, 0x4f, 0x9b, 0xc3, 0xa0, + 0xf8, 0x6b, 0x84, 0xf5, 0x5f, 0xd1, 0x6e, 0xf3, 0xa1, 0xf9, 0x64, 0x9b, + 0x32, 0x14, 0x75, 0x52, 0xeb, 0x79, 0xf1, 0xe4, 0xe3, 0x0a, 0xa1, 0x54, + 0xb2, 0x89, 0x5e, 0x8d, 0x56, 0x1a, 0xdf, 0x82, 0xed, 0xfb, 0xc7, 0x41, + 0xe6, 0x58, 0x96, 0x1a, 0xae, 0x0b, 0x1c, 0x35, 0x0a, 0x18, 0xde, 0x64, + 0x5f, 0x39, 0xc7, 0xbe, 0x47, 0x66, 0xc3, 0xe6, 0xd5, 0x88, 0x51, 0xd4, + 0xf0, 0xca, 0xde, 0x88, 0x01, 0x87, 0xc7, 0x3d, 0x7f, 0x5d, 0xf3, 0xcf, + 0x2f, 0xe4, 0x99, 0x4c, 0x78, 0xa7, 0x65, 0x80, 0x16, 0x66, 0x2d, 0x57, + 0xa0, 0xca, 0x12, 0xdc, 0x3a, 0x2f, 0xa1, 0x1e, 0x5b, 0xcf, 0x57, 0x4e, + 0xdd, 0x4d, 0x89, 0x2d, 0x91, 0x70, 0xfa, 0xb2, 0x54, 0xa7, 0x96, 0xdd, + 0xb7, 0x12, 0x6c, 0x84, 0x30, 0x2d, 0xb7, 0xa5, 0x37, 0x9d, 0xf9, 0x78, + 0xeb, 0x64, 0xa1, 0x1b, 0x29, 0x5a, 0x80, 0x2b, 0x6c, 0x93, 0xf3, 0xce, + 0x61, 0x61, 0x85, 0xd9, 0x09, 0x2d, 0x8c, 0x57, 0x19, 0xf0, 0x29, 0xd3, + 0x24, 0x1b, 0x4f, 0xda, 0xfd, 0xa3, 0x49, 0xb6, 0xd5, 0xad, 0xa3, 0x87, + 0xe8, 0x9c, 0xe7, 0x78, 0x88, 0x00, 0x28, 0xce, 0x24, 0xbb, 0x54, 0xe1, + 0xb4, 0xe2, 0x13, 0x2b, 0x16, 0xd6, 0x8a, 0xdd, 0xc4, 0x6e, 0x35, 0xd8, + 0x9e, 0x7b, 0x46, 0xe9, 0xb8, 0xec, 0xc9, 0x2a, 0xad, 0xa8, 0x83, 0x6b, + 0x74, 0xfe, 0x6b, 0x80, 0x1c, 0xfc, 0x58, 0xee, 0xdf, 0x06, 0xe6, 0x3f, + 0x87, 0xf3, 0xc6, 0x44, 0x89, 0x29, 0x32, 0xa2, 0x4a, 0x59, 0xd5, 0x0f, + 0x6f, 0x31, 0x27, 0x96, 0xee, 0xa0, 0x52, 0x17, 0x5b, 0x50, 0x73, 0xf7, + 0x6e, 0x14, 0x03, 0xdd, 0x96, 0x14, 0x30, 0xea, 0xa3, 0x5b, 0x7d, 0xaa, + 0x95, 0xb7, 0xa3, 0x5b, 0xe9, 0x7f, 0x8d, 0x14, 0x26, 0x9a, 0xbe, 0x30, + 0xb9, 0x06, 0x96, 0xdb, 0xb6, 0x93, 0xba, 0xe9, 0xda, 0x09, 0x7f, 0xf5, + 0xed, 0xa8, 0xa7, 0x0e, 0x56, 0xf2, 0x7b, 0x60, 0x81, 0x0e, 0x96, 0xd0, + 0xd5, 0xbe, 0x28, 0xde, 0xfb, 0xea, 0xe7, 0x39, 0xe2, 0x78, 0x7e, 0x50, + 0xd9, 0xbf, 0x33, 0x49, 0xf6, 0x1c, 0x7b, 0xd6, 0x5c, 0xb9, 0x4a, 0x0a, + 0x66, 0xb7, 0x9d, 0x80, 0x53, 0x6d, 0x00, 0x29, 0xb2, 0xb6, 0xa2, 0xb9, + 0x04, 0x1f, 0xec, 0x7e, 0xf6, 0xed, 0x51, 0xc8, 0xe2, 0xa2, 0x8d, 0x2e, + 0xc5, 0x18, 0x59, 0xc9, 0x5b, 0xa5, 0x2c, 0xfb, 0x65, 0x9a, 0x19, 0x71, + 0x08, 0xe9, 0x6d, 0x90, 0x27, 0x92, 0xe2, 0xb5, 0x1f, 0xde, 0x60, 0x91, + 0x1d, 0x3d, 0xf7, 0x02, 0xc5, 0x74, 0x24, 0x53, 0xec, 0x38, 0xed, 0xa5, + 0xfa, 0x36, 0xc9, 0xba, 0x47, 0xc7, 0xde, 0x94, 0x32, 0xf1, 0x82, 0x77, + 0x9b, 0x14, 0x36, 0x06, 0x00, 0x8e, 0x37, 0x63, 0x7a, 0x0d, 0xf9, 0xde, + 0x67, 0x1d, 0x5f, 0x82, 0xb6, 0x9c, 0x98, 0x4e, 0x7c, 0xd4, 0x2d, 0x50, + 0xa3, 0x88, 0x6a, 0xdb, 0x78, 0xea, 0x77, 0xbf, 0x97, 0xbe, 0x81, 0x10, + 0x3b, 0x6c, 0xbf, 0xb1, 0xdb, 0x06, 0x78, 0x04, 0xb4, 0x12, 0x08, 0x40, + 0x0d, 0xb4, 0xd9, 0x60, 0x62, 0x3a, 0xd2, 0xd5, 0x61, 0xd4, 0xa2, 0x86, + 0x9e, 0xdc, 0xec, 0xa0, 0x06, 0x9d, 0xf3, 0xa9, 0x06, 0xa8, 0x04, 0xb5, + 0x7c, 0x07, 0xd3, 0xa0, 0x53, 0x03, 0x1a, 0x46, 0xb6, 0x08, 0xd3, 0x87, + 0x88, 0xdb, 0x82, 0xf9, 0x90, 0xac, 0xfc, 0xae, 0x19, 0x9c, 0x13, 0x57, + 0xc5, 0xba, 0x3b, 0x08, 0x3d, 0x42, 0x7c, 0x01, 0x56, 0x6c, 0x42, 0x9b, + 0xe7, 0x46, 0x87, 0xd8, 0x90, 0x30, 0xca, 0x02, 0xe6, 0xfa, 0xc1, 0x16, + 0xc0, 0x06, 0x64, 0x4e, 0xcd, 0x72, 0x14, 0xbb, 0xca, 0xae, 0x4d, 0x92, + 0xa1, 0xe8, 0x96, 0xc0, 0xa6, 0x74, 0xa6, 0x9c, 0xab, 0x4a, 0x6f, 0x33, + 0x9d, 0x39, 0xef, 0xa0, 0xeb, 0x42, 0xf6, 0x45, 0x1c, 0x77, 0xab, 0x76, + 0x1d, 0xef, 0xe4, 0x56, 0x2a, 0x16, 0x93, 0x12, 0x48, 0x65, 0x2d, 0x46, + 0x36, 0x5f, 0x90, 0x43, 0xff, 0x87, 0x59, 0xab, 0x12, 0xe4, 0x2a, 0x4d, + 0x2e, 0x55, 0x85, 0x21, 0xda, 0x16, 0xd8, 0x1f, 0xbc, 0x13, 0x9d, 0x92, + 0xec, 0x1b, 0x99, 0x72, 0x9d, 0x9a, 0x35, 0x4b, 0x3a, 0x05, 0x36, 0x67, + 0x36, 0x97, 0x4a, 0x46, 0xfd, 0x07, 0x3e, 0xe0, 0x16, 0x3e, 0xf1, 0x26, + 0x01, 0x2e, 0xf3, 0xa1, 0xd5, 0xd2, 0xc2, 0xce, 0xa3, 0x06, 0xfa, 0xb7, + 0x0e, 0x0b, 0xe0, 0x4f, 0x59, 0x93, 0x62, 0x17, 0x67, 0x73, 0x26, 0x62, + 0x6a, 0x06, 0x8d, 0xbe, 0x0c, 0x3b, 0xb8, 0x2f, 0x87, 0x64, 0xa3, 0x91, + 0xdc, 0xcd, 0x54, 0x28, 0x79, 0x0d, 0x83, 0xde, 0x62, 0x47, 0xa5, 0x38, + 0x9b, 0x2a, 0x98, 0x32, 0x9c, 0x8d, 0x11, 0xab, 0x46, 0xb6, 0xcf, 0xb2, + 0x72, 0x86, 0x6c, 0xa5, 0xfe, 0xd1, 0x12, 0xc2, 0xa3, 0x40, 0x0b, 0x6e, + 0x99, 0x71, 0x03, 0x26, 0x86, 0xa2, 0x56, 0x77, 0xdf, 0x37, 0xec, 0x5d, + 0x1d, 0x24, 0x51, 0x8d, 0x8b, 0xaf, 0xc1, 0x69, 0x07, 0xaa, 0x0c, 0x18, + 0xc4, 0x6a, 0xad, 0xd5, 0xe7, 0xc3, 0x8c, 0x7c, 0xcd, 0x2d, 0x69, 0x86, + 0x0f, 0x3e, 0x14, 0xa8, 0x4b, 0x6d, 0xa2, 0x77, 0xce, 0xd8, 0xeb, 0xd8, + 0x0f, 0x16, 0xd9, 0x2c, 0x88, 0x51, 0xed, 0xc2, 0x8f, 0x36, 0xc3, 0x10, + 0x75, 0x56, 0xec, 0xe7, 0x2f, 0x17, 0x7c, 0xaa, 0x4a, 0x02, 0x22, 0xd1, + 0x0f, 0x62, 0x14, 0xc5, 0x2e, 0x37, 0x7e, 0xc9, 0xc4, 0xb8, 0x90, 0x2f, + 0xd4, 0x05, 0xed, 0x9c, 0xc3, 0x76, 0xd5, 0x08, 0x4b, 0x1b, 0xaa, 0xe9, + 0xe5, 0x8b, 0x54, 0xa4, 0x6e, 0x7e, 0xd7, 0x64, 0x0e, 0x94, 0xe2, 0xcb, + 0xa5, 0x14, 0x35, 0xa0, 0x61, 0x4d, 0xaa, 0x96, 0x5b, 0x6a, 0xb9, 0xb7, + 0xf6, 0x19, 0x30, 0xb2, 0xea, 0xad, 0x6c, 0x5b, 0xcb, 0x8c, 0xcf, 0x2b, + 0x14, 0xea, 0xa8, 0x5c, 0x52, 0xce, 0x6e, 0x98, 0xae, 0xd0, 0xdb, 0x2d, + 0x19, 0x25, 0x42, 0xc8, 0x6d, 0xcc, 0xfc, 0xf5, 0x96, 0xee, 0xd1, 0xe3, + 0x68, 0x53, 0x38, 0xd9, 0x9c, 0xde, 0xff, 0xc4, 0xe6, 0xc3, 0x68, 0x59, + 0xed, 0x88, 0x57, 0x3b, 0x95, 0x77, 0x3c, 0x06, 0x23, 0x54, 0x25, 0xdc, + 0xf2, 0xe5, 0xe7, 0x8e, 0x1f, 0x94, 0x39, 0xf2, 0x53, 0x9b, 0xe8, 0x00, + 0x81, 0xfa, 0xa0, 0x0f, 0xbe, 0x40, 0x1e, 0xfd, 0xb8, 0x8e, 0x16, 0xe3, + 0x4d, 0x97, 0xae, 0x05, 0xee, 0x43, 0x2c, 0x7e, 0x5b, 0x03, 0xe5, 0x38, + 0x7b, 0x54, 0x65, 0x1b, 0xf9, 0xe9, 0x13, 0x1e, 0x91, 0x47, 0x14, 0x79, + 0x74, 0xa6, 0x4b, 0xd5, 0xc1, 0x56, 0xaa, 0x84, 0x54, 0x59, 0x11, 0x61, + 0x45, 0x0c, 0x6f, 0xba, 0x02, 0x07, 0xe7, 0x80, 0x59, 0x9f, 0xda, 0xe1, + 0x19, 0x34, 0x38, 0xde, 0x5f, 0x61, 0x97, 0x65, 0xc8, 0x62, 0xda, 0x3c, + 0xb4, 0x8d, 0xec, 0x7e, 0x08, 0xa4, 0x70, 0x06, 0xbf, 0xf8, 0xfa, 0xfe, + 0xe8, 0x76, 0x4b, 0x86, 0xc8, 0x4c, 0xcc, 0x83, 0x1b, 0xcd, 0x22, 0x73, + 0x1d, 0xcb, 0x9f, 0x96, 0x51, 0xd2, 0x37, 0x08, 0x87, 0x99, 0xb9, 0xb3, + 0xd1, 0xbf, 0x92, 0x02, 0x07, 0xe6, 0x7d, 0xa0, 0x03, 0x3f, 0xe3, 0xf8, + 0xf8, 0xf9, 0xca, 0x95, 0x1d, 0xe6, 0x85, 0xe3, 0x9f, 0x0b, 0x85, 0x50, + 0xc5, 0x6f, 0xd0, 0x00, 0x05, 0x20, 0x0e, 0x44, 0xfd, 0x40, 0x1f, 0xf7, + 0xaf, 0xeb, 0x40, 0x8e, 0xb8, 0xc2, 0xec, 0x31, 0x57, 0x74, 0x29, 0xbb, + 0xe0, 0x0c, 0x39, 0xdf, 0x8e, 0xe5, 0xde, 0x10, 0x22, 0xc0, 0x2e, 0x36, + 0x92, 0x25, 0xd1, 0x3f, 0x05, 0x50, 0x92, 0x88, 0x48, 0xd6, 0x20, 0x5f, + 0x06, 0x39, 0xf7, 0x28, 0x4e, 0x36, 0x5c, 0x24, 0xc9, 0x6b, 0x00, 0x00, + 0x00, 0x01, 0x0c, 0x43, 0xd4, 0x08, 0x1f, 0xa2, 0x01, 0x61, 0x14, 0x5e, + 0x67, 0xf0, 0x4e, 0xcf, 0xd6, 0xf2, 0xfe, 0x71, 0x0c, 0xe2, 0x54, 0xda, + 0xb6, 0x8c, 0x0a, 0xad, 0xd1, 0x00, 0x63, 0x8f, 0x22, 0x88, 0x22, 0xbb, + 0xbb, 0x4e, 0x04, 0x50, 0x0f, 0xb9, 0x5f, 0x25, 0x0f, 0xfd, 0xf9, 0xe4, + 0x28, 0x25, 0xbe, 0xad, 0xa2, 0xdc, 0x00, 0xd0, 0x00, 0x45, 0x9c, 0x50, + 0xc0, 0xe8, 0x6e, 0xbe, 0xad, 0x32, 0xfe, 0xe5, 0x26, 0xc2, 0x86, 0x54, + 0x63, 0xc8, 0x82, 0x7f, 0xc8, 0x03, 0xd0, 0xfb, 0x6f, 0xec, 0x10, 0x80, + 0x2a, 0xbf, 0xcc, 0x02, 0x27, 0x75, 0x2c, 0x0d, 0x3d, 0xbc, 0x2a, 0x93, + 0x65, 0x28, 0x02, 0x23, 0xdb, 0x8b, 0x74, 0xc2, 0xe9, 0x09, 0xbf, 0xc9, + 0x70, 0x10, 0x80, 0x1e, 0x47, 0xa4, 0x0d, 0xab, 0x52, 0x0e, 0x3a, 0x8d, + 0xa1, 0x6c, 0x2e, 0x2c, 0x59, 0xb4, 0x36, 0xda, 0x53, 0x0c, 0xfc, 0x57, + 0x00, 0x0c, 0x24, 0x39, 0x9c, 0xb7, 0x8d, 0xf4, 0x2d, 0xb7, 0x85, 0xda, + 0xdc, 0x0d, 0xf2, 0xb9, 0x03, 0x12, 0x42, 0x44, 0x6f, 0x75, 0xb2, 0xf6, + 0xfe, 0xcd, 0x0a, 0x0f, 0x35, 0xbc, 0xe6, 0x97, 0x8a, 0x42, 0xa6, 0x52, + 0x5a, 0x37, 0xd3, 0x04, 0xbf, 0xf3, 0x6b, 0xac, 0x0d, 0xf3, 0xdd, 0xd9, + 0x26, 0x1e, 0x36, 0x5a, 0x54, 0x3c, 0x6b, 0x4c, 0x2e, 0xa1, 0x29, 0x59, + 0x46, 0xf7, 0x7d, 0xbe, 0x35, 0xcf, 0xfe, 0xbb, 0x45, 0xe9, 0xd2, 0xeb, + 0x89, 0xfc, 0xef, 0x7c, 0xbe, 0x58, 0x6c, 0xa9, 0xe7, 0x13, 0x33, 0x32, + 0x18, 0x7c, 0x0b, 0x6f, 0x9d, 0x4e, 0x32, 0xe7, 0x19, 0x96, 0x0f, 0xb9, + 0x0e, 0xa6, 0x42, 0xce, 0x5a, 0x5d, 0x6a, 0x28, 0x88, 0xe7, 0x4f, 0x2b, + 0x90, 0x73, 0xed, 0x98, 0xaf, 0x53, 0xcb, 0x44, 0x08, 0x6b, 0x30, 0x38, + 0x5e, 0x6c, 0x88, 0x02, 0xb9, 0x57, 0xd6, 0x37, 0x9c, 0x98, 0x61, 0x49, + 0x46, 0xa6, 0x52, 0x99, 0x99, 0x23, 0x7d, 0x90, 0x05, 0x84, 0x52, 0x38, + 0xaf, 0xa8, 0x94, 0xf6, 0x2c, 0x11, 0x00, 0x17, 0x08, 0x98, 0xe3, 0x66, + 0xf2, 0x62, 0xc5, 0xf2, 0x0c, 0xa1, 0x4d, 0xf2, 0x27, 0x49, 0x38, 0x73, + 0x8b, 0x1e, 0x54, 0x87, 0x81, 0x4d, 0xd1, 0xca, 0x00, 0x64, 0xe7, 0x29, + 0x0a, 0x94, 0xdc, 0xc5, 0x9e, 0x51, 0xf5, 0x42, 0x0d, 0x75, 0x84, 0x30, + 0xc6, 0xf4, 0xf2, 0x2e, 0x54, 0xf4, 0x56, 0xe9, 0x90, 0xaa, 0x49, 0x6c, + 0x9e, 0xe0, 0x2d, 0xb3, 0xd4, 0x14, 0xf8, 0x00, 0x31, 0x88, 0xdd, 0xf2, + 0x3b, 0xaf, 0x3a, 0x59, 0x0d, 0xb2, 0x55, 0xfa, 0x1b, 0x62, 0xd0, 0xb2, + 0x43, 0x22, 0x64, 0x64, 0x39, 0xbe, 0x54, 0x4e, 0xf3, 0x11, 0x43, 0x0f, + 0x48, 0xbe, 0xad, 0xa3, 0xad, 0xd1, 0x53, 0xf2, 0xa0, 0x53, 0x71, 0xac, + 0x3a, 0xa8, 0x4a, 0x94, 0xdd, 0x17, 0xec, 0x58, 0x6a, 0x06, 0x29, 0x4a, + 0x39, 0xa1, 0x4e, 0x8c, 0xe3, 0x68, 0xa0, 0x16, 0xf1, 0xc6, 0xcd, 0x09, + 0x2e, 0x4a, 0xbe, 0xad, 0xfa, 0x64, 0x01, 0xb8, 0x9a, 0x00, 0xeb, 0xee, + 0x00, 0xe7, 0x7d, 0xfc, 0xa4, 0x28, 0xcc, 0x00, 0x3d, 0x17, 0xc3, 0x9d, + 0x07, 0x95, 0x84, 0xed, 0xb8, 0xb4, 0x07, 0x8b, 0x6b, 0x7e, 0x71, 0xdf, + 0xcb, 0xf2, 0x10, 0x8a, 0x6f, 0xd3, 0x20, 0x0a, 0x14, 0x10, 0x40, 0x4c, + 0x8f, 0xdd, 0xf3, 0xa0, 0x11, 0x73, 0xb9, 0xb0, 0x05, 0x4a, 0xb4, 0x34, + 0x62, 0xb7, 0x36, 0x6c, 0xe3, 0x7c, 0xb2, 0xe0, 0x6a, 0xee, 0xc0, 0x86, + 0x98, 0x5e, 0xe4, 0x25, 0xb7, 0xf2, 0x89, 0x08, 0x3e, 0xf4, 0x55, 0x40, + 0x47, 0xff, 0xd8, 0x27, 0x5d, 0xce, 0x48, 0x08, 0xff, 0xfb, 0xf8, 0x99, + 0xa5, 0x04, 0x94, 0x5b, 0x74, 0x2e, 0x80, 0x1f, 0x00, 0x1b, 0x23, 0xe5, + 0x02, 0x64, 0x76, 0x76, 0xa5, 0x94, 0x4c, 0xcd, 0x2e, 0x12, 0x9b, 0x37, + 0x34, 0x0c, 0x11, 0x4e, 0x0c, 0xbd, 0x0a, 0x17, 0x2e, 0x20, 0xdf, 0xd6, + 0xe6, 0x6d, 0x01, 0x1d, 0x48, 0xdd, 0x4b, 0x00, 0x0f, 0x05, 0x0a, 0xe1, + 0x36, 0x06, 0x42, 0x2c, 0x7c, 0xc0, 0xc1, 0x9e, 0x72, 0x16, 0x18, 0xde, + 0xb0, 0xc6, 0xf6, 0xcf, 0x6f, 0xce, 0x7b, 0x26, 0x4d, 0x4d, 0x7d, 0x18, + 0x55, 0x33, 0x65, 0xbb, 0x14, 0x08, 0x7d, 0xb5, 0xb8, 0xcb, 0x5d, 0xc7, + 0x1b, 0x60, 0xec, 0x99, 0x2c, 0x0e, 0x1e, 0x03, 0x36, 0xeb, 0x48, 0xff, + 0x62, 0x05, 0xb8, 0x58, 0xd4, 0x15, 0x3c, 0xb6, 0xd3, 0xa0, 0xd9, 0xa9, + 0xe2, 0xad, 0x97, 0x90, 0x42, 0xff, 0x5d, 0xbc, 0x20, 0x5e, 0x24, 0x2e, + 0xfa, 0x12, 0x98, 0x87, 0xb5, 0x53, 0x9b, 0x41, 0x22, 0xf4, 0x5f, 0x7c, + 0xef, 0x96, 0xd8, 0x32, 0x4e, 0x9c, 0x62, 0x8d, 0xfd, 0xac, 0x29, 0xbd, + 0x29, 0x19, 0xd3, 0xeb, 0xfd, 0xee, 0xd1, 0x7b, 0x75, 0x64, 0x7c, 0x5c, + 0xd9, 0x92, 0x4a, 0xba, 0x9e, 0x70, 0x9a, 0x90, 0x39, 0xb8, 0x2b, 0x09, + 0xf9, 0x64, 0x09, 0xb1, 0x70, 0xe1, 0xa7, 0x44, 0x3c, 0x21, 0xae, 0x74, + 0xd7, 0x08, 0xce, 0x67, 0x36, 0xd4, 0x3b, 0x69, 0x91, 0xd2, 0x58, 0x7a, + 0xc2, 0x83, 0x94, 0xb6, 0x89, 0x1b, 0x3a, 0x54, 0x56, 0xf4, 0xdc, 0xf6, + 0x15, 0xaf, 0xa2, 0xb2, 0x40, 0x09, 0x6c, 0x31, 0x16, 0xa1, 0xc3, 0xce, + 0x39, 0xb0, 0xe5, 0x79, 0x3d, 0xf5, 0xf2, 0x2f, 0xe9, 0x23, 0xa2, 0xa5, + 0x3c, 0x29, 0xbb, 0x3c, 0xdd, 0x14, 0x2f, 0x71, 0x0b, 0x3b, 0x3c, 0xae, + 0x38, 0xfa, 0x12, 0x35, 0x02, 0x5b, 0x3a, 0xce, 0xd3, 0x8e, 0x8b, 0x02, + 0x43, 0xb0, 0x3e, 0x0f, 0x2a, 0xfa, 0xb4, 0xc8, 0x53, 0x6d, 0xb5, 0x6b, + 0x6d, 0xce, 0xae, 0x5d, 0x18, 0x7c, 0x2d, 0x42, 0x9a, 0xfd, 0xd8, 0xfb, + 0x37, 0x28, 0x4d, 0xa5, 0x9c, 0x15, 0xea, 0xdc, 0x8e, 0xb2, 0xe7, 0x50, + 0xe8, 0x3e, 0x86, 0x8c, 0x21, 0x04, 0xb5, 0xb7, 0x11, 0xf0, 0xb1, 0xc7, + 0x0f, 0x30, 0xf2, 0xda, 0x6b, 0x68, 0xde, 0xcc, 0xf3, 0x72, 0xee, 0xbe, + 0x8e, 0xc2, 0xce, 0x90, 0x90, 0xdc, 0xd1, 0x40, 0x61, 0xd6, 0xdb, 0xb4, + 0xe0, 0xc1, 0xc8, 0xcc, 0x08, 0x60, 0x0b, 0x99, 0xa3, 0x4e, 0xab, 0xa3, + 0x1b, 0x1b, 0xdf, 0xe7, 0x61, 0xc0, 0x3c, 0x33, 0x2c, 0x09, 0x0d, 0x62, + 0x56, 0x2b, 0x76, 0x75, 0x72, 0xda, 0x99, 0x96, 0x8d, 0xb6, 0x16, 0xd8, + 0xf2, 0x9b, 0xce, 0x92, 0x0f, 0x6d, 0x8e, 0x7d, 0xc7, 0x9b, 0x32, 0x0d, + 0x2f, 0x10, 0xb8, 0xa5, 0x9c, 0xce, 0x26, 0x00, 0x1f, 0xfb, 0x48, 0x81, + 0xa6, 0xdc, 0xb9, 0xb3, 0xd4, 0xe6, 0x89, 0x52, 0x94, 0xd9, 0x66, 0xcc, + 0x79, 0x4d, 0xd3, 0x99, 0x67, 0x05, 0xa4, 0x0b, 0x53, 0xdb, 0xd4, 0x80, + 0x37, 0x14, 0xef, 0xaf, 0x5b, 0xc3, 0xbd, 0xf9, 0xca, 0x96, 0xbb, 0x1f, + 0xbc, 0x2d, 0x93, 0x5d, 0x77, 0x28, 0x6a, 0x96, 0xde, 0x9f, 0xe4, 0x47, + 0xbf, 0xfc, 0x01, 0x8f, 0x5f, 0x0e, 0x76, 0xaa, 0x19, 0x86, 0xbd, 0xff, + 0xb1, 0xbe, 0x90, 0xb6, 0xc1, 0x05, 0xf1, 0xbf, 0x1f, 0x1c, 0x00, 0x56, + 0xf9, 0x2e, 0x69, 0x3a, 0xf3, 0xd1, 0x99, 0xa5, 0x87, 0xa8, 0x79, 0x92, + 0x16, 0x10, 0xdc, 0xbd, 0x07, 0x00, 0xe4, 0x84, 0xde, 0x68, 0x89, 0xe5, + 0x57, 0x42, 0x9b, 0xe9, 0x80, 0x14, 0xfc, 0x8a, 0x77, 0x28, 0x2a, 0x3a, + 0x87, 0x4f, 0x37, 0x17, 0x71, 0x12, 0x1b, 0x0e, 0xf5, 0x6e, 0xc8, 0x01, + 0x3f, 0xce, 0x7c, 0x90, 0x26, 0xfb, 0x75, 0xfb, 0xf2, 0x79, 0x92, 0x9b, + 0x13, 0xf0, 0xb6, 0x0f, 0x5b, 0x5b, 0xd9, 0x80, 0x3c, 0xff, 0xe7, 0xc9, + 0x07, 0x7a, 0x9d, 0xc9, 0x40, 0x27, 0x2e, 0x66, 0xdb, 0x51, 0x74, 0xe1, + 0xd5, 0x50, 0xe8, 0xad, 0xee, 0xfe, 0x3f, 0xa2, 0x9e, 0x2c, 0x5e, 0x76, + 0xf7, 0xc0, 0x1e, 0x73, 0x39, 0xc7, 0xc8, 0x90, 0x38, 0x3a, 0xad, 0x44, + 0x38, 0x31, 0xbc, 0xde, 0xc4, 0x0a, 0xb8, 0x55, 0x2c, 0x34, 0xe8, 0x8d, + 0xca, 0xe7, 0x70, 0x88, 0x58, 0x5b, 0x7f, 0x34, 0x00, 0x78, 0x23, 0x90, + 0x03, 0x5e, 0xfd, 0xe7, 0xce, 0x5a, 0x4d, 0xe6, 0xbf, 0x76, 0xed, 0xa6, + 0x17, 0x87, 0x7a, 0x1c, 0xdd, 0xd0, 0x04, 0xd8, 0x29, 0xfb, 0x5f, 0xc6, + 0xec, 0x85, 0x2f, 0x96, 0xd5, 0xf2, 0x0b, 0xc0, 0xc6, 0xbb, 0xe8, 0x47, + 0x70, 0x03, 0xa2, 0x27, 0xba, 0xc1, 0x38, 0xaa, 0x66, 0x13, 0x95, 0x64, + 0xb1, 0x69, 0x41, 0x10, 0xb6, 0xf8, 0xb7, 0xb8, 0x8a, 0x46, 0xaf, 0x93, + 0xe3, 0x61, 0xf3, 0x97, 0x73, 0x1e, 0x67, 0x9c, 0x3a, 0xc5, 0x68, 0x7b, + 0xb8, 0xe9, 0x54, 0xa1, 0xb4, 0x04, 0x4d, 0xcd, 0x33, 0x31, 0x16, 0x46, + 0xfe, 0xd4, 0x00, 0xe9, 0xdc, 0x7c, 0x08, 0x7e, 0xe4, 0xbb, 0x52, 0x07, + 0xea, 0x54, 0x92, 0x0d, 0x6f, 0x0f, 0x7b, 0xc7, 0x6f, 0x4e, 0xeb, 0x50, + 0x11, 0xff, 0xef, 0x74, 0xcc, 0x43, 0xce, 0xaa, 0xdc, 0x91, 0x41, 0xc2, + 0xc8, 0xb3, 0x71, 0x00, 0x8c, 0x9d, 0xed, 0xc9, 0x10, 0xea, 0x6a, 0xe4, + 0x5a, 0x18, 0xdc, 0x20, 0x0a, 0x3a, 0xf6, 0x7f, 0x0e, 0xa2, 0x5c, 0x3b, + 0x76, 0xcc, 0xab, 0x2c, 0x4a, 0x50, 0x6f, 0x83, 0x79, 0xfc, 0x8a, 0x9e, + 0x4e, 0x8e, 0x74, 0xa1, 0x35, 0x5b, 0x33, 0x11, 0x12, 0x37, 0xd7, 0x00, + 0x40, 0xff, 0x79, 0xa2, 0x1d, 0x5d, 0x5d, 0x2a, 0xd9, 0x5e, 0xe3, 0x0d, + 0xa1, 0x6d, 0xf6, 0x00, 0x05, 0xdf, 0x34, 0x01, 0xb8, 0x03, 0xce, 0x6f, + 0x7d, 0x82, 0x47, 0xfe, 0x38, 0xda, 0x62, 0x1f, 0x0b, 0x81, 0xad, 0xf0, + 0xbe, 0xbe, 0xff, 0x22, 0x44, 0xed, 0xdf, 0x83, 0x16, 0xd8, 0xe7, 0x66, + 0xa1, 0x86, 0xdf, 0xca, 0x25, 0x28, 0xf8, 0xdf, 0x5c, 0x9f, 0x5e, 0xff, + 0xe2, 0xb7, 0xae, 0xf9, 0xe6, 0x8d, 0x2a, 0xd5, 0x36, 0x40, 0xc6, 0xf6, + 0x36, 0xbf, 0x97, 0xc3, 0x6e, 0x96, 0x4a, 0x6d, 0xa0, 0x7d, 0x8a, 0x4a, + 0x60, 0x00, 0x00, 0x01, 0x0d, 0x43, 0xf7, 0xdd, 0x8a, 0x78, 0x80, 0x06, + 0xc0, 0x0d, 0x05, 0x73, 0x52, 0x25, 0x20, 0x02, 0x10, 0x03, 0xf7, 0x2b, + 0x8d, 0x50, 0xea, 0x6d, 0xa5, 0x95, 0x43, 0x65, 0x6f, 0x4c, 0x00, 0xf8, + 0x5b, 0x80, 0x1b, 0x77, 0xcf, 0xcd, 0xdc, 0xa3, 0xe7, 0x9f, 0x0b, 0x24, + 0x3a, 0xfe, 0xa5, 0x29, 0x43, 0x1a, 0x10, 0x34, 0x89, 0xcd, 0xde, 0x5f, + 0xc5, 0xa7, 0x77, 0x37, 0xc9, 0x21, 0x8a, 0x61, 0xc1, 0x2d, 0xf3, 0xe0, + 0x07, 0xc0, 0x0d, 0x78, 0xe7, 0xe4, 0x88, 0xff, 0x6f, 0x68, 0x85, 0xf9, + 0x3e, 0x6d, 0x96, 0x6e, 0x2a, 0x40, 0xe9, 0x21, 0x77, 0xc1, 0xbc, 0x34, + 0xfc, 0x56, 0xe7, 0x96, 0x64, 0xb2, 0xac, 0xa5, 0x8e, 0x52, 0x82, 0x02, + 0x5b, 0xf8, 0x7d, 0xcb, 0xe7, 0x95, 0x60, 0x62, 0x4b, 0x2c, 0x21, 0x56, + 0xd9, 0x06, 0xd6, 0xfa, 0xb0, 0x02, 0x1c, 0x80, 0x09, 0x1c, 0x28, 0x89, + 0xf5, 0x10, 0xf8, 0x1d, 0x67, 0x7c, 0xf6, 0xee, 0xa4, 0x35, 0xda, 0x5e, + 0x54, 0x1c, 0xa3, 0x61, 0x4d, 0x98, 0x10, 0x3f, 0x4b, 0xf9, 0xa0, 0x0f, + 0xfe, 0x33, 0x3d, 0x88, 0xf9, 0x46, 0x49, 0xdb, 0xf2, 0x24, 0xe3, 0x4b, + 0xb8, 0xaa, 0xd9, 0xc2, 0xe2, 0x94, 0xde, 0x7b, 0xe1, 0xcd, 0xf1, 0x80, + 0x1c, 0x8a, 0xec, 0x01, 0x0f, 0xf0, 0x43, 0xb5, 0xd8, 0x1b, 0x39, 0x9d, + 0x87, 0x28, 0x0a, 0xa8, 0xdf, 0x46, 0xfb, 0x7f, 0x7e, 0x77, 0xfe, 0x40, + 0x31, 0xf4, 0x63, 0xae, 0x3b, 0xf3, 0x77, 0xc1, 0x0a, 0x40, 0xb6, 0xfa, + 0x37, 0xf7, 0xe7, 0xbf, 0xa8, 0x03, 0x71, 0x62, 0x44, 0xe8, 0x62, 0x6b, + 0xd4, 0x39, 0x3f, 0x08, 0x98, 0x32, 0x48, 0xdf, 0x3f, 0xfe, 0x0b, 0x00, + 0x10, 0x67, 0x57, 0x66, 0x0c, 0xa5, 0xe1, 0x65, 0x9e, 0xd3, 0x23, 0xba, + 0xe5, 0xf6, 0xda, 0x02, 0x29, 0x0b, 0x6b, 0xdb, 0x31, 0xf4, 0xbf, 0x06, + 0xfe, 0x5f, 0xdf, 0xbe, 0xfd, 0xb2, 0x75, 0xd6, 0xd4, 0x2d, 0x65, 0x88, + 0x89, 0xe8, 0xde, 0x08, 0x00, 0xf5, 0xe2, 0x3d, 0x9c, 0xfe, 0x79, 0xc9, + 0x13, 0xf0, 0xee, 0xe0, 0xea, 0x03, 0x56, 0xfa, 0x3f, 0xd5, 0xc0, 0x82, + 0x02, 0x7e, 0xdc, 0x9a, 0x5c, 0x39, 0x49, 0xf9, 0x21, 0xdb, 0x25, 0x2e, + 0x0d, 0x6f, 0x8d, 0x75, 0x67, 0x44, 0x0e, 0x6a, 0x84, 0x3d, 0x72, 0x98, + 0x38, 0xe1, 0xc3, 0x5b, 0x93, 0x78, 0x82, 0x66, 0xbb, 0x89, 0x83, 0xe2, + 0x5c, 0x6c, 0x2c, 0x34, 0xa8, 0xda, 0x11, 0x45, 0xe0, 0x87, 0x53, 0x2b, + 0x8e, 0x53, 0x35, 0x15, 0x2a, 0x1c, 0x1a, 0x90, 0xe6, 0xa3, 0xfb, 0xb6, + 0xed, 0xb6, 0x00, 0x46, 0x5d, 0x28, 0x28, 0x31, 0xbd, 0x8e, 0x77, 0x78, + 0xa2, 0xf5, 0xd8, 0x17, 0x69, 0xcd, 0xe0, 0x3e, 0xd2, 0xfd, 0x51, 0x20, + 0x5e, 0xcd, 0xca, 0xa8, 0x71, 0x68, 0xde, 0x97, 0xee, 0xb6, 0x92, 0x14, + 0x5b, 0x76, 0xce, 0x9d, 0xc0, 0x9d, 0x57, 0x00, 0xaa, 0xa0, 0xd8, 0x31, + 0xbc, 0xe0, 0xa9, 0x38, 0xe1, 0xda, 0x50, 0x48, 0xc8, 0xad, 0xf4, 0x0e, + 0x45, 0xe6, 0xfd, 0x26, 0xc7, 0xe1, 0x55, 0x1e, 0xb5, 0xd9, 0xa1, 0xd4, + 0x3c, 0x7c, 0x94, 0xa3, 0xda, 0x00, 0x27, 0xf9, 0xf6, 0xfa, 0x8a, 0x23, + 0x77, 0x5f, 0x14, 0x11, 0x00, 0x13, 0xae, 0xc8, 0x84, 0x7e, 0xf8, 0x8e, + 0x81, 0x1b, 0xc6, 0xae, 0xc8, 0x34, 0xa2, 0x8b, 0x6a, 0x44, 0x18, 0xda, + 0x13, 0x65, 0x6f, 0xe6, 0xe0, 0x38, 0xdb, 0x23, 0x6d, 0xd2, 0xe0, 0x16, + 0xd9, 0x3d, 0xdd, 0x08, 0x12, 0x3b, 0x68, 0x69, 0xb6, 0x8f, 0x2d, 0xb7, + 0xda, 0xaf, 0xb4, 0xc0, 0x82, 0xc6, 0x34, 0x51, 0xa4, 0xa6, 0x34, 0xaa, + 0xde, 0xde, 0xcc, 0x32, 0xcb, 0x35, 0x06, 0xd8, 0x55, 0x42, 0xd4, 0x7b, + 0x75, 0xbe, 0x94, 0x02, 0xdf, 0x99, 0x5e, 0xfc, 0x0c, 0x8e, 0xda, 0x52, + 0xd0, 0xc5, 0xb1, 0xb9, 0xe4, 0x68, 0xff, 0x97, 0xdd, 0x2c, 0xe5, 0x5d, + 0xdf, 0x27, 0x2c, 0xc2, 0xce, 0x3e, 0xb6, 0xbe, 0xb9, 0xbe, 0xde, 0xd8, + 0xee, 0x02, 0x6c, 0xc9, 0x0a, 0x83, 0x21, 0x50, 0x73, 0x73, 0xd3, 0x64, + 0x96, 0x46, 0x76, 0xa5, 0x6f, 0xde, 0xdb, 0xa4, 0x7f, 0x8f, 0x67, 0x6d, + 0xa3, 0xd2, 0xb8, 0x47, 0x75, 0xca, 0x02, 0x27, 0x48, 0x88, 0xdc, 0xdc, + 0xc9, 0x74, 0x5a, 0x84, 0x7e, 0x04, 0xf6, 0x28, 0x5d, 0xc1, 0xb0, 0xe9, + 0x69, 0x96, 0x84, 0x94, 0xc9, 0xec, 0x08, 0x5f, 0xe3, 0xc7, 0x3d, 0x6e, + 0xd3, 0xca, 0xd0, 0x33, 0x1f, 0x80, 0x03, 0x57, 0x4d, 0x8a, 0x13, 0x2b, + 0x55, 0x2c, 0xe3, 0x9e, 0xa9, 0x0f, 0x8d, 0xf6, 0xd5, 0x5a, 0xb4, 0xb9, + 0xc3, 0xa9, 0xc1, 0x0d, 0xea, 0x48, 0x6a, 0x92, 0x5b, 0xd5, 0x81, 0xf3, + 0x49, 0x2d, 0xd1, 0x51, 0xe0, 0x07, 0x06, 0xe2, 0x01, 0x08, 0x40, 0x17, + 0x28, 0xf3, 0xb6, 0xad, 0x24, 0xb2, 0xc3, 0x48, 0xfe, 0x7a, 0x58, 0x0a, + 0xdd, 0xd7, 0x25, 0x78, 0xe2, 0xab, 0x68, 0x11, 0xcb, 0xc5, 0x73, 0x56, + 0x3c, 0xc5, 0x49, 0x1d, 0xdf, 0x6f, 0xdb, 0x03, 0x52, 0xdd, 0x90, 0xa9, + 0x47, 0x4b, 0x5a, 0xb7, 0x61, 0x02, 0xfd, 0x1d, 0xde, 0x84, 0x95, 0x9b, + 0xd6, 0x5b, 0x4a, 0x42, 0xd1, 0x17, 0xc5, 0xae, 0x94, 0xda, 0xc6, 0xeb, + 0x9c, 0xc1, 0x74, 0x54, 0xcc, 0x2c, 0x62, 0xef, 0x12, 0xc2, 0xcf, 0x19, + 0x46, 0x9e, 0x1a, 0xcb, 0x0d, 0xe3, 0xe4, 0x46, 0x98, 0x78, 0xe1, 0x4e, + 0xb3, 0x74, 0x69, 0x34, 0xaa, 0xa8, 0xc7, 0x9e, 0x70, 0x89, 0x9e, 0xd3, + 0x9b, 0x46, 0xd5, 0x82, 0x7a, 0xb9, 0xe6, 0x30, 0xe0, 0xca, 0xd8, 0xdc, + 0x67, 0x0e, 0xce, 0x27, 0x8e, 0x45, 0x7f, 0xa2, 0xd2, 0x9a, 0x0e, 0x6a, + 0x3e, 0x37, 0xae, 0x13, 0xb6, 0xdf, 0x2c, 0xc8, 0x33, 0xf1, 0x9b, 0x4b, + 0xa1, 0x6c, 0x65, 0x33, 0x87, 0xc4, 0x81, 0x17, 0xb7, 0xe9, 0xe7, 0x0d, + 0x90, 0x61, 0x25, 0xab, 0x7d, 0xcd, 0x49, 0x29, 0x43, 0x25, 0x3b, 0x0b, + 0x83, 0x8f, 0x24, 0x35, 0x7c, 0x4d, 0xd7, 0xee, 0x94, 0x36, 0xc9, 0xae, + 0x86, 0x95, 0x4b, 0xa5, 0x9e, 0x30, 0x35, 0x6b, 0x45, 0x6b, 0x6e, 0xe7, + 0x5d, 0xd8, 0x03, 0x9b, 0x4e, 0x5b, 0xb2, 0xd3, 0x90, 0x86, 0xd5, 0xed, + 0x91, 0x40, 0xea, 0xa3, 0x9b, 0x35, 0x48, 0x92, 0xc0, 0x82, 0xda, 0xf9, + 0xf9, 0xd3, 0xc0, 0x22, 0xf5, 0x3d, 0x86, 0xb6, 0xe5, 0xc5, 0xb8, 0x68, + 0x52, 0x1a, 0x74, 0x39, 0x97, 0x9e, 0x88, 0x3e, 0xd9, 0xbc, 0xc5, 0x29, + 0x2e, 0x49, 0x4c, 0xcb, 0x42, 0x62, 0x95, 0x68, 0x53, 0x73, 0xfa, 0x97, + 0x8e, 0xe4, 0xdf, 0x49, 0x14, 0x34, 0x31, 0xba, 0x3f, 0x4e, 0xb0, 0x01, + 0xc8, 0x9c, 0x27, 0xe9, 0x65, 0x07, 0xf4, 0x56, 0x13, 0xa8, 0x0a, 0xdf, + 0x43, 0x4e, 0x0b, 0x68, 0x1a, 0x53, 0x73, 0xf0, 0x06, 0x35, 0x6f, 0xa3, + 0x7f, 0x47, 0x00, 0x5a, 0x01, 0x67, 0xdc, 0x8a, 0xef, 0x8d, 0x10, 0xf3, + 0xa4, 0xb8, 0x41, 0x73, 0xe7, 0x98, 0xd3, 0xa6, 0x15, 0x61, 0x43, 0xea, + 0xb7, 0x98, 0x12, 0xe0, 0x01, 0x0f, 0xb0, 0x8e, 0x5f, 0xe1, 0x38, 0x93, + 0x09, 0x46, 0x36, 0x0f, 0x6c, 0x98, 0x47, 0xd8, 0xfd, 0xc1, 0xf6, 0xbb, + 0x0c, 0x33, 0x4a, 0x1e, 0x32, 0x8e, 0x39, 0xbb, 0x80, 0x0f, 0x28, 0xb0, + 0x06, 0x20, 0x0f, 0xf8, 0xe2, 0x71, 0xb0, 0x75, 0xd2, 0x75, 0xd7, 0x24, + 0x0f, 0xa5, 0xc2, 0xa1, 0x51, 0xb9, 0xf2, 0xf9, 0x49, 0x29, 0x29, 0xbc, + 0x5c, 0x86, 0x61, 0x4d, 0xfb, 0x01, 0x5c, 0x00, 0x19, 0x77, 0xdf, 0x29, + 0x81, 0xa6, 0xb9, 0xf2, 0x4c, 0x5f, 0x16, 0xf9, 0x5c, 0x81, 0xdd, 0x6d, + 0xf1, 0x5c, 0xca, 0x43, 0xb2, 0x29, 0x29, 0xbe, 0x9e, 0x00, 0xd8, 0x58, + 0x20, 0x80, 0xb7, 0x06, 0x91, 0xc9, 0xd0, 0x67, 0x13, 0x6f, 0x16, 0x3a, + 0xc2, 0x6d, 0x01, 0xc8, 0xf4, 0x28, 0x6b, 0x7c, 0xaf, 0x8b, 0x75, 0xdf, + 0x17, 0x9c, 0x09, 0xb9, 0xcf, 0x95, 0x40, 0x11, 0x5d, 0xb0, 0xa8, 0xd8, + 0xec, 0x3f, 0x00, 0x06, 0x4a, 0xd9, 0x50, 0xd6, 0xfd, 0x57, 0xbc, 0xde, + 0xb9, 0xc7, 0xae, 0x06, 0x6c, 0x55, 0xcb, 0x02, 0x2c, 0x2d, 0xbe, 0x82, + 0x00, 0xec, 0x50, 0x01, 0xd3, 0xbb, 0x27, 0x9a, 0x3e, 0xf6, 0xf1, 0x3b, + 0xa1, 0xf9, 0x4a, 0xc3, 0xa2, 0xc9, 0x32, 0x14, 0x3d, 0xbc, 0xe7, 0xc6, + 0xf3, 0xfe, 0x82, 0x9d, 0xcb, 0xdc, 0x59, 0x30, 0xcd, 0xdb, 0xae, 0x1e, + 0x9e, 0x45, 0xc0, 0xf8, 0x30, 0x9a, 0xdd, 0xbf, 0xf6, 0x75, 0xf5, 0xbc, + 0x0a, 0xe3, 0x32, 0x1d, 0x26, 0xdb, 0x15, 0xc8, 0x7a, 0xac, 0x1b, 0x42, + 0x9b, 0xcc, 0xb8, 0xa7, 0x27, 0x80, 0x1e, 0xd9, 0x86, 0xc6, 0xf8, 0x7f, + 0x5f, 0x8e, 0x5f, 0xc0, 0xa1, 0x3b, 0x47, 0x57, 0x6b, 0xb2, 0xec, 0x83, + 0x8f, 0x80, 0x72, 0x36, 0xe0, 0x05, 0xe0, 0x0f, 0x2e, 0x91, 0xfc, 0x9e, + 0xeb, 0x95, 0x51, 0xfb, 0x62, 0xdc, 0xcb, 0x69, 0x90, 0xbd, 0x18, 0xad, + 0x8b, 0x8d, 0x70, 0x02, 0x69, 0xc7, 0x02, 0xdd, 0x40, 0x7b, 0x16, 0x2a, + 0xc4, 0x32, 0x1e, 0x50, 0xc0, 0xa8, 0xde, 0xa8, 0x00, 0xab, 0x6f, 0xf7, + 0xb1, 0x7d, 0x8a, 0x96, 0x8f, 0x86, 0xf3, 0xce, 0xe9, 0x65, 0x5a, 0x85, + 0xd5, 0x28, 0x96, 0xda, 0xda, 0x9b, 0x61, 0x4c, 0xee, 0x96, 0xdf, 0x9d, + 0xe8, 0xd0, 0x02, 0x87, 0x6a, 0xf7, 0x46, 0xae, 0xe8, 0xbd, 0xde, 0x70, + 0xb1, 0x9e, 0x5f, 0xa8, 0xbe, 0x2d, 0xe3, 0xdf, 0x79, 0xfe, 0xce, 0x11, + 0xc1, 0x92, 0xd7, 0xa2, 0x78, 0xa9, 0xde, 0x2d, 0xf4, 0x37, 0x89, 0x80, + 0x82, 0x02, 0xbb, 0xce, 0xc7, 0x58, 0x4c, 0xb2, 0x3d, 0x33, 0x24, 0xa1, + 0x11, 0x0a, 0x81, 0x4c, 0xbf, 0xdd, 0x84, 0x4f, 0x7e, 0xf4, 0x5b, 0xe2, + 0x2c, 0xb8, 0x66, 0x6d, 0x86, 0x60, 0xf0, 0x89, 0x1b, 0x1e, 0x83, 0xae, + 0x69, 0x0a, 0xb3, 0x85, 0x40, 0x2d, 0xbe, 0x98, 0xbe, 0xef, 0xc7, 0x2f, + 0x9f, 0x3d, 0xdd, 0xd3, 0xb8, 0xd9, 0x29, 0x86, 0x5b, 0xb4, 0x7e, 0x53, + 0x92, 0x28, 0xe6, 0xf2, 0xdf, 0x4e, 0x34, 0x01, 0xac, 0xf8, 0x9f, 0x99, + 0xfb, 0xdd, 0xd4, 0x95, 0x6e, 0xd2, 0xc9, 0xa7, 0xa0, 0xd6, 0xe7, 0x11, + 0x26, 0xfd, 0xc8, 0xc2, 0x05, 0xfb, 0x60, 0x6e, 0x65, 0x7e, 0x5b, 0xbb, + 0x20, 0x61, 0x69, 0x5b, 0x38, 0x03, 0x17, 0x71, 0xf4, 0xf7, 0xdc, 0x0f, + 0x87, 0xad, 0xce, 0x7a, 0x90, 0xd4, 0x0d, 0xc9, 0x62, 0xf8, 0xb7, 0x4f, + 0x12, 0xb9, 0xd9, 0xb2, 0x84, 0xa4, 0x58, 0x42, 0x69, 0x18, 0x05, 0x30, + 0x00, 0x00, 0x01, 0x0e, 0x43, 0xfa, 0xd0, 0x87, 0x4c, 0x11, 0xbc, 0xe4, + 0x90, 0xb2, 0xea, 0x14, 0x60, 0x5b, 0x78, 0x70, 0x02, 0x7e, 0x7a, 0x00, + 0x75, 0xd1, 0x02, 0xef, 0x35, 0x60, 0x22, 0x00, 0x26, 0x5b, 0x8f, 0xbb, + 0x80, 0x60, 0xc3, 0x14, 0xc3, 0xe1, 0x61, 0x81, 0x8d, 0xed, 0x7e, 0xa0, + 0x16, 0x00, 0x2d, 0x23, 0x5d, 0xe9, 0x2d, 0x2a, 0xae, 0x75, 0xa0, 0x66, + 0xcb, 0x2a, 0x16, 0x59, 0x29, 0xbb, 0x82, 0x78, 0xe7, 0x3d, 0xf8, 0x00, + 0xb2, 0x55, 0xab, 0x86, 0x3e, 0x1f, 0x1f, 0x4a, 0x91, 0x14, 0x69, 0x6d, + 0xf3, 0x59, 0x24, 0xd3, 0x2d, 0x21, 0x9c, 0xde, 0x45, 0x95, 0xf5, 0x27, + 0x82, 0xc6, 0xf5, 0x72, 0xed, 0x00, 0x2f, 0x79, 0x16, 0x41, 0x7c, 0xdf, + 0xdd, 0xef, 0x34, 0xcb, 0x84, 0x13, 0x09, 0xee, 0x8b, 0x92, 0xcb, 0x5d, + 0xe4, 0xa8, 0x72, 0xb7, 0xbf, 0xb5, 0xdb, 0xc4, 0x55, 0x83, 0x2e, 0xab, + 0xd6, 0x50, 0x11, 0x01, 0xed, 0xc5, 0xb6, 0x80, 0x5b, 0x65, 0xb4, 0xb4, + 0x59, 0x9b, 0x91, 0x14, 0x9b, 0x4b, 0xb4, 0xf2, 0xdb, 0xad, 0x9b, 0xb5, + 0xf2, 0x05, 0x98, 0x52, 0x4b, 0xfa, 0x18, 0x59, 0xde, 0xad, 0xb3, 0xa7, + 0x9a, 0x18, 0xa4, 0x86, 0xf4, 0x23, 0x7d, 0x0c, 0x5c, 0x2d, 0x03, 0x29, + 0x71, 0x65, 0x18, 0x43, 0x6f, 0x2c, 0x00, 0xb7, 0xe7, 0xcb, 0x24, 0xcc, + 0x71, 0x63, 0x4a, 0x1a, 0xde, 0x96, 0x48, 0xbb, 0x2e, 0x51, 0xb5, 0x21, + 0x85, 0xca, 0x49, 0x6c, 0x79, 0x2e, 0xba, 0x47, 0x5b, 0x07, 0x87, 0xd8, + 0x50, 0x61, 0x43, 0xeb, 0x68, 0xfe, 0x77, 0x87, 0x67, 0x94, 0xf0, 0xa7, + 0xd4, 0xac, 0xae, 0xdc, 0x85, 0x4f, 0x56, 0xfc, 0x08, 0x03, 0x59, 0x00, + 0x1e, 0x6f, 0xff, 0x79, 0xe2, 0x04, 0x08, 0x22, 0x67, 0x2b, 0x40, 0x4b, + 0x69, 0xbc, 0xac, 0x41, 0xd0, 0x3e, 0xb7, 0xe3, 0x8f, 0xaf, 0x0f, 0x22, + 0x66, 0x9a, 0x65, 0x83, 0x53, 0x2a, 0x12, 0x4a, 0x6f, 0xe8, 0x24, 0xc7, + 0x67, 0x7e, 0x56, 0xed, 0x43, 0xab, 0xdc, 0x1c, 0xa4, 0x30, 0xe8, 0xdf, + 0x9c, 0xc0, 0x14, 0x13, 0xc0, 0x16, 0x0a, 0xb7, 0x9e, 0xf6, 0xd1, 0xaa, + 0x23, 0x2d, 0xd3, 0x0e, 0xb4, 0x38, 0x64, 0x81, 0x2d, 0xc8, 0xe8, 0x01, + 0x66, 0xc9, 0x7c, 0x57, 0xc4, 0xf6, 0xe6, 0x52, 0x75, 0x02, 0xdb, 0xfc, + 0xdb, 0xf0, 0x23, 0x05, 0xab, 0xd0, 0x32, 0x1c, 0x69, 0xde, 0x0c, 0x04, + 0xd0, 0x0b, 0x5f, 0x35, 0x60, 0x0a, 0x83, 0xa1, 0x94, 0x2c, 0xb3, 0xa3, + 0x7b, 0x5f, 0xae, 0xe8, 0x94, 0xe3, 0x16, 0x0d, 0x2e, 0x42, 0xd2, 0x86, + 0x41, 0x8d, 0xc7, 0x71, 0x3f, 0xe3, 0xbe, 0x0d, 0xa5, 0x8c, 0x2a, 0xc9, + 0x43, 0x1b, 0x47, 0x2d, 0xe3, 0x2d, 0x94, 0x30, 0x2d, 0xb3, 0x95, 0x4f, + 0x6f, 0x73, 0xf3, 0x5f, 0xf7, 0x22, 0x0a, 0xee, 0x65, 0x3b, 0x03, 0xf9, + 0x17, 0x7a, 0xd4, 0xa3, 0x13, 0x39, 0xb1, 0x55, 0x47, 0x16, 0xdc, 0xc1, + 0x55, 0xff, 0x41, 0x1d, 0x70, 0x4f, 0x09, 0xd8, 0x28, 0x53, 0x9c, 0x48, + 0x89, 0x14, 0x32, 0x37, 0xbb, 0x11, 0x1c, 0x00, 0xe5, 0xff, 0xfe, 0x32, + 0x4a, 0x52, 0x9b, 0xc7, 0xdb, 0xda, 0x89, 0x36, 0xe0, 0xd3, 0x62, 0x55, + 0xb3, 0x46, 0xa0, 0xda, 0x31, 0xbe, 0x6e, 0x47, 0xf6, 0x76, 0xe6, 0x6e, + 0x65, 0xc3, 0x91, 0x75, 0x0d, 0x44, 0x08, 0x6d, 0x31, 0x34, 0xc2, 0xe0, + 0x04, 0x55, 0xad, 0x47, 0x90, 0x9b, 0xed, 0x09, 0x15, 0x08, 0xdc, 0xfc, + 0xd9, 0x9c, 0xf9, 0x97, 0x2c, 0xe7, 0xbc, 0x97, 0x75, 0xd1, 0xc9, 0x61, + 0x6a, 0x85, 0xd6, 0xf2, 0xd5, 0x04, 0x0b, 0xa6, 0x37, 0xa5, 0x76, 0x52, + 0x2f, 0x6e, 0x16, 0xe9, 0xe9, 0x4b, 0x40, 0xb6, 0xcc, 0x2d, 0x7e, 0xc4, + 0x61, 0x4f, 0x7d, 0xa0, 0x93, 0xff, 0x85, 0x81, 0xca, 0x16, 0xd9, 0x3a, + 0x1b, 0xb9, 0x64, 0x0a, 0xab, 0x63, 0x67, 0x90, 0xe6, 0xfc, 0xc3, 0xa5, + 0x17, 0x12, 0x10, 0xd0, 0x90, 0xde, 0x84, 0xd3, 0x79, 0x0e, 0xc0, 0xb9, + 0x46, 0x8c, 0x64, 0x00, 0x7f, 0x27, 0x5f, 0x3a, 0x57, 0x86, 0x8f, 0x6a, + 0x37, 0x2e, 0xf5, 0x29, 0x41, 0x11, 0x10, 0xe2, 0x9b, 0x59, 0x67, 0x92, + 0x56, 0xb3, 0xa2, 0x5f, 0x56, 0xfd, 0x4c, 0xda, 0x47, 0xf3, 0x87, 0x82, + 0x38, 0x01, 0xc5, 0xcb, 0x76, 0x80, 0x8a, 0xc3, 0x7c, 0x22, 0xb6, 0xaf, + 0x70, 0x42, 0x00, 0x8d, 0x7b, 0xac, 0x0a, 0x00, 0xa8, 0xce, 0xaa, 0x84, + 0xa9, 0x97, 0xd0, 0xb8, 0xd9, 0xf4, 0x10, 0xbf, 0xc4, 0x02, 0xaa, 0x58, + 0x24, 0xff, 0xde, 0x79, 0x96, 0x12, 0x92, 0xd2, 0x53, 0x77, 0x72, 0xd7, + 0x60, 0x9b, 0x3d, 0x3d, 0xb7, 0x5e, 0x9e, 0x0f, 0xb8, 0x00, 0x30, 0x56, + 0xe8, 0x80, 0x85, 0xff, 0x53, 0x40, 0xe6, 0xef, 0x80, 0x85, 0xff, 0x53, + 0x40, 0xe2, 0x43, 0x7e, 0x50, 0xa0, 0x07, 0xd7, 0x39, 0xa8, 0x13, 0xa2, + 0x6e, 0x3a, 0xf8, 0x99, 0x97, 0x03, 0x06, 0xd6, 0xeb, 0x60, 0x7e, 0xe3, + 0xad, 0xa1, 0x92, 0x81, 0x9b, 0x20, 0x5d, 0xc5, 0x02, 0x9b, 0x9e, 0x5f, + 0x1b, 0xd4, 0xce, 0x22, 0x17, 0x65, 0x00, 0x3d, 0xef, 0xe6, 0x49, 0x60, + 0x65, 0xb2, 0x2f, 0x8a, 0x63, 0x5f, 0x96, 0xd0, 0xfb, 0x43, 0x0b, 0xee, + 0xa6, 0x6a, 0x9c, 0x58, 0xd0, 0xd3, 0x9b, 0x73, 0x9b, 0xb0, 0xf0, 0x39, + 0xbc, 0xe2, 0x4c, 0xfb, 0x91, 0x84, 0x57, 0x48, 0x11, 0x6d, 0xba, 0x1b, + 0x43, 0xc3, 0xda, 0x77, 0x60, 0x89, 0xed, 0x74, 0xf0, 0x1e, 0xf5, 0xce, + 0x07, 0x00, 0x89, 0x06, 0xd3, 0xbc, 0x1b, 0xa2, 0x21, 0x3f, 0xe2, 0x7a, + 0x2b, 0xc3, 0x21, 0x72, 0x9c, 0xd5, 0xbf, 0x00, 0x2a, 0x13, 0xc6, 0xad, + 0x18, 0xaa, 0x61, 0x84, 0x34, 0x28, 0x94, 0xd0, 0xda, 0xd2, 0xdb, 0xc7, + 0xcc, 0x59, 0x72, 0x18, 0x30, 0x68, 0xca, 0x12, 0x8d, 0x5b, 0x83, 0xe6, + 0xe8, 0xc0, 0xca, 0x64, 0x08, 0x2d, 0x15, 0xb6, 0xee, 0xe3, 0xb8, 0x20, + 0xcd, 0xa1, 0x98, 0xb5, 0x03, 0x69, 0x34, 0x35, 0xb1, 0x3f, 0x26, 0xe4, + 0xa5, 0x85, 0x5b, 0x28, 0x0d, 0x58, 0x60, 0x73, 0x76, 0x6a, 0x9b, 0x69, + 0x09, 0xb9, 0x12, 0x63, 0x9d, 0x10, 0x87, 0x4e, 0xf5, 0x6d, 0x99, 0x27, + 0xb3, 0xf2, 0xa3, 0x73, 0xe2, 0xe4, 0xcd, 0x84, 0x35, 0x91, 0x91, 0xf1, + 0x83, 0x9b, 0xba, 0x47, 0xce, 0x31, 0xfe, 0x74, 0x74, 0x4b, 0xb2, 0x25, + 0x38, 0x71, 0xea, 0xdc, 0xc5, 0xb3, 0xdc, 0x0c, 0x41, 0xf4, 0x3a, 0x48, + 0x54, 0x3e, 0x9e, 0x36, 0xd6, 0xe9, 0x5a, 0x6c, 0x75, 0x50, 0x95, 0x83, + 0x7d, 0x5b, 0x6f, 0xde, 0x9b, 0x1c, 0x20, 0x56, 0x40, 0x1e, 0x3d, 0xf8, + 0xff, 0xcb, 0xa1, 0xde, 0x2a, 0xd9, 0xe4, 0x36, 0x65, 0x2f, 0xc2, 0xb7, + 0x87, 0x03, 0x8c, 0x00, 0x18, 0x37, 0x85, 0xe2, 0xbc, 0xfa, 0xe9, 0xcf, + 0xe3, 0x81, 0x98, 0x6d, 0x43, 0x31, 0x10, 0x79, 0x0d, 0xbe, 0x89, 0xf7, + 0xf9, 0x23, 0x7b, 0x91, 0xb1, 0xef, 0xe6, 0x3e, 0x17, 0x45, 0x73, 0x9b, + 0x09, 0xb2, 0x51, 0xd4, 0x61, 0x2d, 0xbc, 0x3f, 0xc7, 0x52, 0x2e, 0xee, + 0x8f, 0xba, 0x56, 0x64, 0x91, 0x0a, 0x38, 0x07, 0xb6, 0xd5, 0x6d, 0xcf, + 0x33, 0xe7, 0xdb, 0xdb, 0x65, 0x43, 0xae, 0x65, 0x0e, 0xdb, 0x6c, 0xa9, + 0x4e, 0xd3, 0x8a, 0x28, 0x63, 0x73, 0x5a, 0x4e, 0x29, 0x42, 0x56, 0x36, + 0x4d, 0xfb, 0xa0, 0x06, 0x3e, 0xd0, 0x8d, 0xf5, 0x76, 0xa7, 0x32, 0x95, + 0x09, 0xd5, 0xee, 0xdc, 0x57, 0x80, 0xac, 0x34, 0x63, 0x0f, 0xf8, 0x03, + 0x51, 0x1f, 0x3d, 0x3b, 0x9e, 0x74, 0x53, 0xec, 0x0f, 0x9c, 0x08, 0xde, + 0x03, 0xc9, 0xf6, 0x16, 0xb1, 0x54, 0xa4, 0x3c, 0x39, 0x8e, 0x7c, 0x8a, + 0x00, 0x45, 0xef, 0x1e, 0x47, 0xe2, 0xf1, 0x88, 0xee, 0x2e, 0x51, 0x77, + 0x9f, 0x2c, 0x7e, 0x97, 0xb5, 0x35, 0x24, 0xb4, 0x60, 0xc5, 0x6f, 0x25, + 0x9c, 0x5f, 0x62, 0x2f, 0xdf, 0xab, 0xe7, 0x64, 0x01, 0x26, 0x3c, 0x8d, + 0x97, 0x5e, 0xe9, 0x56, 0xd3, 0x4c, 0xe4, 0xac, 0xa8, 0x3a, 0xdc, 0x56, + 0x29, 0x65, 0x94, 0x34, 0x6c, 0x3d, 0xaa, 0x94, 0xdf, 0xb3, 0x13, 0xf0, + 0x23, 0x3e, 0xb7, 0x9e, 0x33, 0xb7, 0x6a, 0x21, 0xaf, 0x14, 0xf7, 0x6f, + 0x96, 0x18, 0xa7, 0x4b, 0x12, 0x01, 0x03, 0xaa, 0x36, 0x7f, 0xe8, 0x91, + 0x0e, 0x11, 0x5c, 0x25, 0xfc, 0xb8, 0xeb, 0xc3, 0xf8, 0xce, 0xde, 0xee, + 0x0a, 0xfc, 0xc3, 0xe5, 0x19, 0xad, 0xf1, 0x8e, 0x30, 0x02, 0xde, 0x05, + 0x23, 0x8c, 0x81, 0x9b, 0x20, 0xc2, 0xbf, 0x43, 0xfc, 0x1b, 0xe9, 0x7f, + 0x04, 0x57, 0x80, 0x3d, 0xeb, 0x81, 0x73, 0x45, 0x67, 0xea, 0x3a, 0x75, + 0xbd, 0xcd, 0xcc, 0x85, 0x50, 0x31, 0xe5, 0x4b, 0x95, 0x8e, 0xec, 0xc4, + 0x92, 0x40, 0x9b, 0x16, 0xb6, 0x74, 0x07, 0xed, 0xf4, 0x72, 0x3c, 0x50, + 0xa5, 0xdb, 0x69, 0x5f, 0x9d, 0x97, 0x23, 0xf5, 0xcb, 0x16, 0x7e, 0xcb, + 0xa8, 0x71, 0xcc, 0xa0, 0x0b, 0x7e, 0x1f, 0x2f, 0x4f, 0x8f, 0x83, 0xf2, + 0xe3, 0xdd, 0xae, 0xcd, 0x94, 0xaa, 0x36, 0x0c, 0xb0, 0x7a, 0x37, 0x50, + 0x8b, 0x9d, 0x00, 0x31, 0xea, 0x91, 0xb4, 0x5c, 0x95, 0x30, 0x3b, 0x3e, + 0x9f, 0x57, 0xbb, 0x98, 0x5a, 0x2f, 0x95, 0x87, 0xa8, 0x4a, 0x58, 0x8d, + 0xe5, 0x00, 0x1a, 0x11, 0xbd, 0xb0, 0x57, 0x5c, 0x4c, 0xeb, 0x21, 0x77, + 0xcb, 0x80, 0xc8, 0x34, 0xb4, 0x1b, 0x5b, 0x91, 0xf5, 0x65, 0x52, 0x15, + 0x29, 0x9d, 0xa5, 0xd6, 0xfe, 0xac, 0x47, 0x12, 0x08, 0x5f, 0xdc, 0xf3, + 0x7c, 0x8a, 0xa9, 0xbc, 0x75, 0xb6, 0xa5, 0x8b, 0x68, 0xd0, 0xd4, 0x6e, + 0x37, 0xb7, 0x02, 0x38, 0xe8, 0xcd, 0x74, 0x44, 0x9e, 0x5b, 0x14, 0xf8, + 0xad, 0xe8, 0xc0, 0x15, 0x09, 0xe4, 0x00, 0xac, 0x56, 0x11, 0xc8, 0x95, + 0xe7, 0x4a, 0x01, 0x63, 0x89, 0xcf, 0x7e, 0xb8, 0x11, 0x00, 0x10, 0x6c, + 0x3c, 0xcc, 0x2f, 0xd5, 0xbd, 0x00, 0x01, 0x8f, 0xb7, 0x5e, 0xe2, 0xdd, + 0xd0, 0x93, 0x76, 0xc0, 0x09, 0x97, 0x9e, 0x39, 0xf2, 0x7a, 0x96, 0xe0, + 0x20, 0x30, 0x31, 0xb9, 0xc5, 0x87, 0x49, 0x2c, 0x09, 0x09, 0x8d, 0x3c, + 0x93, 0x12, 0x84, 0xb7, 0xf2, 0x0f, 0x79, 0x3e, 0xb7, 0xe3, 0x1d, 0x64, + 0x0d, 0xd5, 0x32, 0xf8, 0x58, 0xde, 0x97, 0xb1, 0x64, 0x07, 0x5a, 0xe9, + 0x98, 0x12, 0x61, 0xb6, 0xd3, 0xdb, 0xea, 0xa0, 0x05, 0xe2, 0x63, 0xb3, + 0xbb, 0xe7, 0x12, 0x19, 0x9a, 0xec, 0xc7, 0xe8, 0x18, 0x94, 0xfb, 0xe4, + 0xe9, 0x4e, 0xba, 0x91, 0x42, 0x1b, 0xe0, 0xc2, 0x83, 0xa6, 0x6a, 0xe0, + 0xfc, 0x0e, 0xdf, 0xd5, 0x3d, 0xbb, 0x37, 0xf2, 0x5e, 0x2b, 0x1b, 0x92, + 0x6b, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x43, 0xfd, 0x0a, 0x00, 0xf4, 0x58, + 0xaf, 0xbf, 0xbf, 0x02, 0x2d, 0x72, 0xa2, 0x9b, 0x98, 0xeb, 0x6b, 0xe4, + 0xc3, 0x96, 0xc9, 0x0b, 0x46, 0xf4, 0x06, 0xf1, 0xd7, 0x0b, 0xa5, 0x14, + 0x5c, 0xcb, 0xb2, 0x19, 0x4e, 0xa7, 0x97, 0x5b, 0x9b, 0xc3, 0x80, 0x0f, + 0x9f, 0xab, 0x9a, 0xa3, 0x1d, 0xa9, 0x53, 0x2d, 0xc4, 0x52, 0xea, 0x14, + 0xa3, 0x56, 0x37, 0x20, 0x52, 0xe7, 0x31, 0xcf, 0xd3, 0x51, 0x03, 0xf7, + 0xbe, 0x13, 0x2e, 0xd0, 0xc2, 0xc7, 0x51, 0xed, 0xf2, 0x99, 0x52, 0xac, + 0xf0, 0x2d, 0xb8, 0x60, 0xfb, 0x5b, 0xf5, 0x02, 0xaa, 0x6f, 0x36, 0x65, + 0x88, 0x50, 0x74, 0x42, 0x86, 0x9c, 0x1a, 0x81, 0xad, 0xe4, 0x00, 0x1e, + 0x4e, 0xfe, 0x3e, 0xf9, 0x32, 0x45, 0x29, 0x03, 0xae, 0xf9, 0x5d, 0x96, + 0x18, 0x58, 0xf8, 0xbe, 0x0d, 0xe1, 0xc0, 0x17, 0x6f, 0x04, 0x6e, 0x78, + 0x32, 0xe5, 0x5b, 0x53, 0x74, 0x53, 0xcb, 0xc9, 0xa1, 0xf4, 0x39, 0xf2, + 0x17, 0x6c, 0x6d, 0x9f, 0x02, 0xbb, 0xcf, 0xa7, 0xd6, 0xc1, 0x7c, 0x82, + 0x30, 0x02, 0x55, 0x0f, 0x0e, 0x85, 0x00, 0x90, 0xe5, 0xb6, 0x2f, 0x83, + 0x67, 0x31, 0x66, 0x92, 0x55, 0xb9, 0xb0, 0x3a, 0x2b, 0x7f, 0x41, 0xff, + 0x40, 0x03, 0xfe, 0x85, 0xf0, 0xf3, 0x28, 0x23, 0xff, 0xef, 0x0f, 0x0f, + 0xd3, 0x62, 0x8f, 0xa1, 0xa5, 0xb0, 0x14, 0xb8, 0x2a, 0x71, 0xc8, 0x98, + 0x01, 0x2e, 0x6c, 0xd5, 0x74, 0xe3, 0x30, 0xaf, 0x5b, 0x4e, 0x0d, 0x46, + 0xe3, 0xf1, 0x7b, 0xff, 0xd2, 0x29, 0xb5, 0xd0, 0xb3, 0x37, 0xc9, 0xdb, + 0xbc, 0xee, 0x39, 0xe5, 0xee, 0x01, 0x8b, 0x61, 0x34, 0x29, 0xbd, 0x0f, + 0xdf, 0xbd, 0xd8, 0xb8, 0xea, 0x1d, 0x9f, 0x8c, 0xf3, 0xde, 0x7c, 0xa9, + 0xa7, 0x87, 0x45, 0x2c, 0xc3, 0x94, 0x63, 0x6a, 0x64, 0xd5, 0xa8, 0xda, + 0xa4, 0xdc, 0x02, 0xdb, 0xe3, 0xf5, 0xf0, 0xe0, 0x04, 0x80, 0x06, 0xaf, + 0xaf, 0x50, 0x26, 0xf1, 0xbc, 0x4a, 0xe5, 0x85, 0x93, 0x6d, 0x54, 0x50, + 0xb6, 0xfc, 0xff, 0xf5, 0xcc, 0xcb, 0x0c, 0x37, 0xc6, 0x4a, 0xdf, 0xa5, + 0x48, 0xb9, 0xc5, 0x22, 0x7c, 0xf7, 0x95, 0x16, 0xc9, 0xb3, 0x31, 0x0d, + 0xb4, 0xf3, 0xec, 0xb1, 0x56, 0x24, 0x29, 0x5b, 0xe4, 0x80, 0x0d, 0xfe, + 0x01, 0x04, 0x06, 0x7f, 0xb3, 0x39, 0x15, 0xc8, 0xc0, 0xe2, 0x0b, 0x97, + 0xcc, 0xb0, 0x20, 0x29, 0xb0, 0x32, 0x66, 0x3b, 0x25, 0x0a, 0x7b, 0x64, + 0xf9, 0xe5, 0x24, 0x4f, 0x16, 0xfc, 0x30, 0xbd, 0xc0, 0x07, 0x9f, 0xfd, + 0xe7, 0x3c, 0xd4, 0x6a, 0x49, 0x64, 0x32, 0x37, 0x91, 0x22, 0xf7, 0xc1, + 0x17, 0x34, 0x40, 0x8e, 0xea, 0x17, 0x25, 0xe7, 0x16, 0xf3, 0xd6, 0x6c, + 0x35, 0x3c, 0xae, 0x1e, 0xb0, 0xa3, 0x9b, 0xe9, 0xc0, 0x05, 0x70, 0x57, + 0x0f, 0xdf, 0x8f, 0xe4, 0x01, 0xe6, 0x87, 0x1a, 0x5d, 0x94, 0xc9, 0xbe, + 0x5b, 0x96, 0x5b, 0x2c, 0x6f, 0x94, 0x49, 0xf8, 0xf8, 0x9a, 0xa1, 0x73, + 0x9c, 0x36, 0xda, 0x1a, 0x5c, 0x25, 0x37, 0x6e, 0x5a, 0x9f, 0x9a, 0x15, + 0x56, 0x94, 0xcc, 0xfb, 0x1b, 0x0e, 0x96, 0x00, 0x5b, 0x4d, 0xc0, 0x15, + 0xaa, 0x43, 0xc3, 0x21, 0xed, 0x88, 0xae, 0x05, 0x77, 0x00, 0x06, 0x7a, + 0xaa, 0x48, 0x46, 0xfa, 0xaf, 0xbd, 0xd9, 0xfc, 0x12, 0x46, 0xd3, 0x34, + 0x30, 0x0c, 0xf9, 0xfb, 0x66, 0xc0, 0xf3, 0xa6, 0x48, 0x6c, 0x94, 0xa3, + 0xea, 0x37, 0xcd, 0x36, 0xf9, 0xbf, 0x05, 0xe5, 0x08, 0x84, 0x02, 0xb5, + 0xb4, 0x96, 0xdc, 0xc8, 0xbe, 0x87, 0x10, 0xd9, 0xc3, 0x9b, 0xfa, 0x6f, + 0xc0, 0xbf, 0x70, 0x02, 0x3f, 0x69, 0xbd, 0x08, 0xed, 0x41, 0x10, 0x01, + 0x30, 0x51, 0xaa, 0x80, 0x91, 0xff, 0x92, 0xfe, 0xe0, 0xe5, 0xaa, 0xdb, + 0x3f, 0xff, 0x34, 0x01, 0xf6, 0x91, 0x08, 0xc2, 0x62, 0x9f, 0x69, 0xbc, + 0x71, 0xbf, 0x9d, 0x26, 0xd2, 0xad, 0x85, 0x41, 0xad, 0xe4, 0x3b, 0xf8, + 0x04, 0x1f, 0xd9, 0x00, 0x12, 0x00, 0x5b, 0x68, 0x64, 0x36, 0x3c, 0xca, + 0x38, 0x3f, 0xc8, 0xe4, 0xa5, 0xf8, 0x37, 0xe8, 0x2f, 0x91, 0x3b, 0xcf, + 0xb8, 0xb8, 0x06, 0x60, 0xc7, 0x5e, 0xdd, 0xa8, 0x93, 0x53, 0x15, 0x23, + 0xee, 0x20, 0xc2, 0x1b, 0x79, 0xef, 0x90, 0x52, 0x5d, 0xa0, 0x03, 0x46, + 0xca, 0x95, 0x16, 0x7a, 0xb7, 0xf1, 0x30, 0x07, 0x74, 0x10, 0x40, 0x5c, + 0x4f, 0xf7, 0xda, 0x20, 0xf5, 0xcf, 0x7e, 0x9c, 0x1f, 0x6c, 0x2a, 0x9b, + 0x62, 0xac, 0x92, 0xa0, 0xc1, 0xed, 0xf2, 0x8e, 0x13, 0x8b, 0xb7, 0x6f, + 0x81, 0x8b, 0x3c, 0x5b, 0xf4, 0xf9, 0x10, 0x48, 0x20, 0x80, 0xe7, 0xd3, + 0x3e, 0x5d, 0x9c, 0xe9, 0x76, 0xde, 0x36, 0xbf, 0x4d, 0xab, 0x7c, 0xe9, + 0x4b, 0x9a, 0x7a, 0xa5, 0x3d, 0x5b, 0xf3, 0x5f, 0xcc, 0x20, 0x76, 0xf7, + 0x49, 0x7c, 0x26, 0x6d, 0x1f, 0x06, 0x6b, 0x75, 0x17, 0xde, 0x9b, 0xe8, + 0x3e, 0x05, 0xb6, 0xaa, 0xa7, 0xb7, 0xc4, 0xe3, 0x83, 0x76, 0x65, 0x40, + 0x08, 0xee, 0x2b, 0x7b, 0xf8, 0x08, 0x40, 0x15, 0xa2, 0xce, 0x90, 0xf0, + 0x43, 0x00, 0x68, 0x14, 0x79, 0x3e, 0x58, 0x49, 0x6f, 0x17, 0x26, 0xf9, + 0xe1, 0x6a, 0x3b, 0xf3, 0x6b, 0xac, 0xf0, 0xa0, 0x6d, 0xbd, 0xc6, 0x4b, + 0xd0, 0x81, 0x32, 0x5a, 0x11, 0x1d, 0xc6, 0x85, 0x02, 0x27, 0xfd, 0x6a, + 0xfa, 0x48, 0xde, 0xb5, 0x0f, 0x6f, 0x41, 0x49, 0xe0, 0x73, 0x74, 0x71, + 0x9c, 0xce, 0xdd, 0xf8, 0xa1, 0x7e, 0xdb, 0xef, 0xc8, 0x4d, 0x59, 0xb3, + 0x56, 0xc1, 0xc9, 0x2c, 0xad, 0x81, 0xe6, 0x68, 0xbf, 0x7f, 0x6d, 0x81, + 0x59, 0xf3, 0x5d, 0xbc, 0x51, 0xc1, 0xc6, 0x58, 0x78, 0x49, 0x4c, 0xfd, + 0x3a, 0xd1, 0x5c, 0x77, 0x65, 0x83, 0x03, 0xbf, 0x92, 0xcd, 0xb0, 0xf3, + 0xf7, 0x39, 0x59, 0x00, 0x46, 0x5a, 0xb6, 0xbd, 0xc7, 0x89, 0xeb, 0xef, + 0xca, 0xe5, 0x5a, 0x56, 0xe0, 0x87, 0x88, 0xc7, 0xe4, 0x3c, 0x02, 0x57, + 0x6e, 0xfa, 0x16, 0xda, 0xb7, 0x54, 0x6f, 0x9b, 0x43, 0xde, 0x2a, 0xf8, + 0xc3, 0x62, 0x14, 0x12, 0x91, 0xbd, 0x35, 0xda, 0x44, 0x30, 0xcd, 0xf4, + 0xd7, 0xd2, 0xbd, 0x2a, 0x92, 0xdb, 0x83, 0xdc, 0xb9, 0x5d, 0x73, 0x9a, + 0x3e, 0x58, 0xf7, 0xdd, 0x88, 0x4c, 0x38, 0xb1, 0x81, 0x55, 0xba, 0x76, + 0x00, 0x1b, 0x07, 0x27, 0x8e, 0xf9, 0xd4, 0x1a, 0x73, 0x65, 0x5b, 0xa0, + 0xf5, 0x6f, 0x90, 0x58, 0xa3, 0x0b, 0xf5, 0x83, 0x82, 0xd4, 0x84, 0xc7, + 0x7f, 0x39, 0x0b, 0xf5, 0x80, 0x7c, 0x6b, 0xea, 0x67, 0x56, 0xcb, 0x68, + 0x61, 0xb8, 0x97, 0x4a, 0x1c, 0xa3, 0xce, 0x68, 0xf7, 0x57, 0xd8, 0xf8, + 0x81, 0xa9, 0x9a, 0x51, 0x0d, 0x19, 0x1c, 0xc1, 0xe8, 0xde, 0x19, 0x08, + 0x19, 0x14, 0xb0, 0x98, 0x9b, 0xe8, 0x39, 0xb9, 0xcf, 0x2b, 0x70, 0x95, + 0x28, 0xc0, 0xa0, 0xd6, 0xed, 0x2b, 0xde, 0xf9, 0x66, 0x21, 0xe0, 0x88, + 0x00, 0x95, 0x54, 0x2a, 0x61, 0xed, 0xc0, 0x2b, 0x08, 0x13, 0x3d, 0x75, + 0x2c, 0x24, 0xc6, 0x9a, 0xca, 0x14, 0x07, 0x37, 0xf6, 0x90, 0x02, 0x5f, + 0x20, 0x02, 0xd0, 0x06, 0xd3, 0xd9, 0xdb, 0x68, 0x0f, 0x7b, 0x27, 0xf0, + 0xfc, 0xe2, 0x4a, 0xb7, 0xf7, 0x76, 0x67, 0x85, 0xb1, 0xbd, 0x4f, 0x6f, + 0xd0, 0x40, 0x03, 0x9e, 0x78, 0x9b, 0xba, 0xa3, 0x41, 0x0b, 0xfd, 0x67, + 0x3a, 0x78, 0x4e, 0x6c, 0x5b, 0x7c, 0x63, 0x7d, 0x7b, 0xeb, 0x01, 0x07, + 0xf9, 0x7f, 0xff, 0x57, 0xeb, 0xac, 0x02, 0x7c, 0xec, 0xde, 0x1f, 0x83, + 0x0e, 0x5c, 0xd9, 0x24, 0x81, 0x8d, 0xf3, 0x90, 0x02, 0x3f, 0xf0, 0x81, + 0x00, 0x0d, 0xb3, 0xe3, 0xec, 0xfe, 0x51, 0x4c, 0x7f, 0x3d, 0x75, 0x90, + 0x9f, 0xce, 0xca, 0x86, 0x9b, 0x69, 0x85, 0xaa, 0x54, 0x34, 0x73, 0x46, + 0xda, 0xba, 0x57, 0x81, 0x88, 0xde, 0x5e, 0xae, 0x2a, 0x92, 0x9b, 0xf8, + 0x90, 0x02, 0x12, 0x33, 0xc0, 0x1d, 0x80, 0x36, 0x7c, 0x17, 0x2c, 0x1b, + 0x25, 0xeb, 0x9b, 0x24, 0xfd, 0xc2, 0xb4, 0x6c, 0xc1, 0xcd, 0xc9, 0xfa, + 0xf5, 0xbf, 0x04, 0x5e, 0x05, 0xf5, 0xcc, 0x3a, 0xa6, 0xe4, 0x78, 0x75, + 0x18, 0x3e, 0x58, 0xdf, 0xba, 0x3e, 0x5f, 0x48, 0xbf, 0x7f, 0x71, 0x7d, + 0xdd, 0x1b, 0x4b, 0xe7, 0x9b, 0xa6, 0x0c, 0xfd, 0x69, 0xd2, 0x05, 0x37, + 0xe6, 0xbf, 0xee, 0x02, 0x08, 0x16, 0x0b, 0xff, 0x74, 0x81, 0x5b, 0xc0, + 0xa3, 0x2f, 0x86, 0xdb, 0x6c, 0x21, 0xd6, 0xe7, 0xa8, 0xed, 0xb0, 0x96, + 0x3d, 0xb0, 0xdf, 0xc5, 0xad, 0xfc, 0x61, 0xe0, 0x63, 0x32, 0x90, 0xed, + 0x6d, 0x7e, 0xdb, 0xa0, 0x0c, 0x1d, 0xf7, 0x16, 0xb2, 0x06, 0x4f, 0xe8, + 0x92, 0xb2, 0xd0, 0xc2, 0x07, 0x19, 0x8b, 0xeb, 0x5b, 0xec, 0x80, 0x0b, + 0x5d, 0xef, 0xcf, 0xd8, 0x01, 0xcd, 0x17, 0x2a, 0x93, 0x60, 0x87, 0x11, + 0xcc, 0xe9, 0xd6, 0xa7, 0xe2, 0xcd, 0x7f, 0x12, 0x52, 0x86, 0x8c, 0xd6, + 0xf1, 0x20, 0x05, 0xa2, 0x27, 0xb8, 0x02, 0xa1, 0x64, 0x1d, 0xd3, 0x83, + 0x93, 0xe0, 0x5e, 0xe5, 0xca, 0x34, 0x3b, 0x69, 0x25, 0x2b, 0x67, 0x3f, + 0x25, 0x4f, 0x11, 0xed, 0x16, 0x0d, 0x24, 0x37, 0xf1, 0x28, 0x08, 0x5f, + 0xef, 0x38, 0x8b, 0xe3, 0x2d, 0xa4, 0xa8, 0xdd, 0xdf, 0x28, 0x00, 0xee, + 0x8a, 0xc0, 0x4c, 0x00, 0x3a, 0xa9, 0xea, 0xdc, 0xfe, 0xf1, 0xf4, 0x5e, + 0x72, 0xe7, 0xca, 0x36, 0x57, 0x2e, 0x6c, 0xb0, 0x22, 0x95, 0x5b, 0xed, + 0x40, 0x04, 0xa2, 0xa8, 0x01, 0x79, 0x1b, 0x31, 0xcf, 0x01, 0x13, 0xec, + 0x48, 0xa3, 0x29, 0x6a, 0x32, 0xb6, 0x8e, 0xa4, 0x0d, 0x7d, 0x21, 0x58, + 0xca, 0x94, 0x5b, 0x7b, 0xf9, 0x76, 0xfb, 0xc0, 0x06, 0x25, 0x06, 0x5b, + 0x3e, 0x84, 0xe9, 0xc4, 0x18, 0x4d, 0x59, 0xab, 0x42, 0x92, 0x37, 0x80, + 0x00, 0x77, 0xf0, 0x2f, 0x3d, 0xc5, 0xf5, 0xc3, 0xf8, 0xd8, 0xb2, 0xe4, + 0x7b, 0xf2, 0x6a, 0x51, 0x95, 0x06, 0x5f, 0x16, 0xfa, 0xc7, 0xd3, 0xbd, + 0xe0, 0x8b, 0xec, 0x27, 0xe6, 0x0e, 0x0e, 0xb9, 0xde, 0x57, 0x39, 0x69, + 0x51, 0x2d, 0xa5, 0x14, 0xd8, 0xa5, 0xc0, 0x06, 0x40, 0x0f, 0x1f, 0xf1, + 0x40, 0x2c, 0xc2, 0xd3, 0x2b, 0xb8, 0x7a, 0xe7, 0x9d, 0xbe, 0x7a, 0x36, + 0x16, 0x43, 0xad, 0xe3, 0xf5, 0x7c, 0xf5, 0x66, 0xc0, 0xca, 0xb9, 0x02, + 0xdb, 0x29, 0x4e, 0x46, 0xfe, 0x72, 0xe7, 0x4d, 0x00, 0xb3, 0x2c, 0xf0, + 0xef, 0x61, 0xa0, 0x97, 0xff, 0xb6, 0x2a, 0x05, 0xb7, 0xea, 0x88, 0x21, + 0xd8, 0x2b, 0xdb, 0x9e, 0x08, 0x0a, 0x02, 0x5d, 0xe6, 0xb8, 0xf9, 0x0a, + 0xa5, 0x0c, 0x2c, 0x7b, 0x7e, 0x5a, 0x9a, 0x01, 0x5c, 0xe2, 0x60, 0x04, + 0x22, 0xf7, 0x24, 0x21, 0xa4, 0x6f, 0xd3, 0xe0, 0x0f, 0x81, 0x0b, 0xfd, + 0x33, 0x9b, 0x6b, 0xc6, 0xc4, 0x90, 0x99, 0x92, 0x87, 0x86, 0x5b, 0xb5, + 0x59, 0x65, 0x20, 0x13, 0xac, 0xb0, 0x34, 0x3c, 0xf9, 0x5a, 0xf2, 0xcd, + 0x4a, 0xad, 0xf4, 0x12, 0x7c, 0x11, 0x7b, 0xcb, 0x8e, 0xb2, 0x9a, 0xeb, + 0x21, 0xa9, 0x12, 0x87, 0xe2, 0xee, 0xcb, 0x55, 0x15, 0x46, 0xb7, 0xe6, + 0x71, 0x1e, 0xcf, 0xf8, 0x00, 0x71, 0xd7, 0xb6, 0x3d, 0x60, 0xd0, 0x42, + 0x00, 0x69, 0x69, 0x48, 0x51, 0x61, 0xf6, 0xac, 0x85, 0x1e, 0x5b, 0x7d, + 0xcf, 0xe4, 0x89, 0xc0, 0x03, 0x0e, 0xe3, 0x9f, 0xb2, 0x29, 0xab, 0xc0, + 0x01, 0xec, 0x27, 0xe6, 0xeb, 0xcf, 0x44, 0xb0, 0xb8, 0x91, 0x1b, 0xd7, + 0xfd, 0xfd, 0xde, 0x00, 0xdf, 0xe6, 0x13, 0xd7, 0xf5, 0x09, 0xde, 0x46, + 0xd3, 0x2d, 0x2f, 0x7f, 0x6a, 0x64, 0x50, 0xe3, 0x8b, 0x6e, 0x9b, 0x2f, + 0x2f, 0xc3, 0x28, 0x00, 0xd0, 0xf5, 0x6e, 0x8a, 0x54, 0x95, 0x58, 0x00, + 0x00, 0x01, 0xb7 +}; + +void mpeg2_get_video_data(const guchar **data, guint *size) +{ + *data = mpeg2_clip; + *size = MPEG2_CLIP_DATA_SIZE; +} diff --git a/tests/test-mpeg2.h b/tests/test-mpeg2.h new file mode 100644 index 0000000000..8b3e43e6de --- /dev/null +++ b/tests/test-mpeg2.h @@ -0,0 +1,28 @@ +/* + * test-mpeg2.h - MPEG-2 test data + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef TEST_MPEG2_H +#define TEST_MPEG2_H + +#include + +void mpeg2_get_video_data(const guchar **data, guint *size); + +#endif /* TEST_MPEG2_H */ diff --git a/tests/test-vc1.c b/tests/test-vc1.c new file mode 100644 index 0000000000..e15bb82aa3 --- /dev/null +++ b/tests/test-vc1.c @@ -0,0 +1,1774 @@ +/* + * test-vc1.c - VC-1 test data + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "test-vc1.h" + +#define VC1_CLIP_WIDTH 320 +#define VC1_CLIP_HEIGHT 240 +#define VC1_CLIP_DATA_SIZE 20860 + +/* Data dump of a 320x240 VC-1 video clip (vc1.raw), it has a single frame */ +static const guchar vc1_clip[VC1_CLIP_DATA_SIZE] = { + 0x00, 0x00, 0x01, 0x0f, 0xca, 0x00, 0x09, 0xf0, 0x77, 0x0a, 0x09, 0x20, + 0x1d, 0xff, 0x0a, 0x0b, 0x80, 0x84, 0x80, 0x00, 0x00, 0x01, 0x0e, 0x4c, + 0x10, 0x80, 0x00, 0x00, 0x01, 0x0d, 0xc1, 0xd8, 0xd4, 0x47, 0xd0, 0xaa, + 0xc4, 0x45, 0xaa, 0xb8, 0x01, 0xdf, 0x4c, 0xc1, 0x3a, 0xfa, 0x13, 0x67, + 0x6a, 0xed, 0x2c, 0x67, 0xbc, 0xef, 0xdc, 0x69, 0x99, 0xf8, 0x53, 0x97, + 0x01, 0xdc, 0xbe, 0xd8, 0x3b, 0xa2, 0x96, 0xe8, 0xa1, 0x94, 0x02, 0x57, + 0x82, 0x82, 0xd6, 0x14, 0xc7, 0x61, 0x5a, 0x00, 0x22, 0x81, 0x73, 0x33, + 0x20, 0x00, 0xa0, 0x09, 0xc0, 0x50, 0xfa, 0x06, 0xce, 0x35, 0x91, 0x8d, + 0x19, 0x0f, 0x07, 0x1e, 0x84, 0x5b, 0x3a, 0x29, 0x03, 0xad, 0x8f, 0x8a, + 0xd2, 0x22, 0xf0, 0xfc, 0x28, 0xd2, 0x95, 0x4a, 0xfe, 0x74, 0x4b, 0x23, + 0xe7, 0xd4, 0x12, 0x1f, 0x37, 0x01, 0x88, 0xf8, 0xa4, 0x09, 0x76, 0x51, + 0xae, 0xf4, 0x23, 0x6d, 0x29, 0x8c, 0x54, 0xaa, 0x2c, 0x68, 0x10, 0x7e, + 0x71, 0xbf, 0x10, 0xb4, 0x77, 0x97, 0x8b, 0xa1, 0x54, 0xd1, 0xda, 0xb5, + 0x5f, 0x61, 0xf0, 0x64, 0x64, 0x29, 0x25, 0x7d, 0x42, 0xe0, 0xff, 0x2a, + 0x83, 0x29, 0x61, 0xfc, 0xee, 0xe5, 0x11, 0x04, 0xc0, 0x43, 0xc0, 0xc4, + 0x0e, 0x18, 0x43, 0xb6, 0x08, 0x55, 0xa0, 0x22, 0xf4, 0x58, 0x01, 0xc6, + 0x43, 0x0d, 0xba, 0x04, 0x3e, 0x8e, 0x5f, 0xc1, 0x11, 0x56, 0xef, 0xd7, + 0x78, 0xe2, 0xd2, 0xdb, 0x84, 0x16, 0x76, 0xc6, 0x92, 0x15, 0xf6, 0xc2, + 0x76, 0x2f, 0xd2, 0xef, 0x46, 0x02, 0x60, 0x24, 0xda, 0x16, 0x48, 0x95, + 0xc4, 0x87, 0x81, 0xa7, 0xdd, 0xd7, 0x77, 0x56, 0xb7, 0xb5, 0x28, 0x9d, + 0x6b, 0x7b, 0xd6, 0x8b, 0x80, 0x42, 0x28, 0xb0, 0x28, 0x82, 0x50, 0x04, + 0x65, 0x1a, 0xc3, 0x79, 0x74, 0x6c, 0x3e, 0x9e, 0x69, 0x0e, 0xc1, 0xed, + 0x8d, 0xe9, 0xf0, 0xf4, 0xf8, 0xde, 0xc1, 0x62, 0x1d, 0x1f, 0x4a, 0x5d, + 0x02, 0x11, 0xfa, 0xd8, 0x10, 0xb8, 0xa0, 0xc5, 0xf5, 0x85, 0xd1, 0x19, + 0x14, 0x06, 0x21, 0x5b, 0xa5, 0x37, 0xcd, 0xf2, 0xbc, 0x3b, 0x7f, 0xe3, + 0x1c, 0x62, 0x51, 0x4b, 0x09, 0x2e, 0x48, 0x1f, 0x4e, 0x19, 0xe4, 0x90, + 0x22, 0x81, 0xf4, 0xf7, 0x16, 0x4f, 0xe5, 0x97, 0x12, 0x9b, 0x92, 0x6e, + 0xcc, 0x61, 0xd6, 0x4a, 0x59, 0x66, 0x7d, 0xc2, 0x1d, 0x33, 0x7e, 0x62, + 0x29, 0x81, 0x80, 0xb7, 0xa4, 0xcb, 0xc4, 0xc3, 0x9b, 0x1d, 0x2b, 0x00, + 0xc9, 0x78, 0x82, 0xef, 0xd7, 0xa5, 0xad, 0x08, 0x18, 0x7c, 0x97, 0x61, + 0x3e, 0xaf, 0x4e, 0x21, 0xd6, 0x5a, 0x35, 0xd6, 0xf9, 0xdf, 0x89, 0xe9, + 0x09, 0x99, 0x3e, 0x53, 0x81, 0x80, 0x21, 0xd9, 0x44, 0x7f, 0xb9, 0xe7, + 0x7d, 0x1d, 0xa6, 0xd4, 0xb6, 0x60, 0x71, 0xa3, 0x87, 0x13, 0x40, 0x7a, + 0x50, 0xac, 0x02, 0x87, 0xe3, 0x7a, 0xab, 0xce, 0x11, 0xed, 0x51, 0x97, + 0xc5, 0xf0, 0x33, 0xf5, 0x3b, 0x7e, 0x05, 0xda, 0x4d, 0x29, 0x23, 0xa7, + 0xca, 0x43, 0x0e, 0x72, 0xf0, 0x96, 0xe9, 0x95, 0x4a, 0x32, 0xb0, 0xc4, + 0xe5, 0x65, 0x73, 0xc3, 0x30, 0xea, 0xfb, 0x93, 0x04, 0x64, 0x48, 0x48, + 0x20, 0x1a, 0x8c, 0xde, 0xb0, 0x24, 0x7d, 0xd6, 0xe9, 0x5b, 0xb9, 0x0b, + 0x18, 0xb9, 0xc4, 0x4a, 0x81, 0xaa, 0xfb, 0x6b, 0x2f, 0xe6, 0x77, 0x00, + 0x17, 0xa8, 0x1f, 0x7f, 0x8b, 0xcd, 0xaf, 0xb5, 0xc1, 0x26, 0x99, 0x3f, + 0x74, 0xd9, 0x69, 0x4c, 0x4c, 0xe5, 0x8a, 0x51, 0x3b, 0x47, 0x18, 0x33, + 0x1a, 0xc5, 0xc3, 0xe1, 0xeb, 0xc7, 0x80, 0xa4, 0xb3, 0x5f, 0x22, 0x64, + 0xcc, 0x97, 0xcb, 0xdb, 0xe5, 0xc9, 0x09, 0x89, 0x65, 0xfd, 0x61, 0x76, + 0xc3, 0xf7, 0xfe, 0x7d, 0xe1, 0x70, 0x07, 0x9a, 0x17, 0x95, 0x08, 0x4d, + 0xec, 0xfb, 0x38, 0x61, 0x06, 0x1e, 0x96, 0x91, 0x19, 0x42, 0x88, 0xf1, + 0x45, 0x04, 0x69, 0x63, 0x1c, 0x99, 0xf8, 0x26, 0xf4, 0xfc, 0xf0, 0xeb, + 0x48, 0x06, 0x9d, 0xef, 0x46, 0x72, 0x41, 0xa9, 0xa5, 0xb8, 0x4a, 0xf0, + 0xd3, 0x82, 0x65, 0x88, 0x98, 0x40, 0x97, 0x4a, 0x95, 0x10, 0x52, 0xca, + 0x47, 0xec, 0x14, 0x75, 0x86, 0xd5, 0x7d, 0xf7, 0xda, 0xa5, 0x09, 0xc6, + 0x50, 0x02, 0x8f, 0xd7, 0x51, 0x42, 0x43, 0x60, 0x27, 0x67, 0xa0, 0xd6, + 0xd8, 0xcf, 0x58, 0xc5, 0x13, 0x27, 0xa2, 0x4e, 0x4f, 0xc3, 0xc2, 0x50, + 0xcb, 0x8d, 0x00, 0x53, 0x87, 0x5a, 0x6b, 0x4d, 0xb4, 0x07, 0x0b, 0x40, + 0xb3, 0xba, 0xc3, 0x14, 0xb8, 0x75, 0xda, 0x84, 0x50, 0x96, 0x12, 0xc6, + 0xd1, 0x00, 0xa5, 0xa3, 0x4c, 0x11, 0x45, 0x02, 0xc7, 0x2f, 0xe2, 0x8f, + 0xb7, 0xe9, 0xff, 0xe2, 0x48, 0x8b, 0x28, 0x1c, 0x38, 0x8c, 0x41, 0xc9, + 0xd0, 0xfa, 0x13, 0x4f, 0xfd, 0x6b, 0x72, 0xa5, 0x0e, 0xd7, 0x2f, 0x2b, + 0xee, 0x37, 0xe6, 0xb0, 0x41, 0x4d, 0x45, 0x83, 0x88, 0x6d, 0x14, 0x6d, + 0xa6, 0xb1, 0x59, 0x7d, 0x7e, 0xa7, 0x8d, 0x48, 0xc3, 0x4c, 0x80, 0x91, + 0xf0, 0x4d, 0xfc, 0xaf, 0xe6, 0xae, 0x9a, 0x24, 0xca, 0x73, 0xc4, 0x13, + 0xf8, 0x28, 0xd2, 0xbf, 0xdf, 0xc4, 0xd0, 0x4e, 0xf4, 0x3e, 0x2c, 0x60, + 0x6a, 0xd4, 0x6e, 0x44, 0x8a, 0xae, 0x09, 0x37, 0xb1, 0x98, 0xaf, 0x69, + 0xf0, 0xee, 0x6f, 0x0a, 0x55, 0x6d, 0x12, 0x7c, 0xf0, 0x08, 0x78, 0xd2, + 0x98, 0x7c, 0xdf, 0xd7, 0xa0, 0x0d, 0xf3, 0x52, 0x65, 0xf6, 0xb9, 0xfe, + 0xf3, 0x73, 0x4c, 0xe2, 0x3a, 0x27, 0x64, 0x00, 0x28, 0x54, 0x2d, 0x4a, + 0x59, 0x42, 0x43, 0xea, 0x26, 0xeb, 0x13, 0x2a, 0x5a, 0x9a, 0x35, 0xe9, + 0xe3, 0xe0, 0x3d, 0x84, 0xf0, 0x12, 0xbe, 0x84, 0x3f, 0x1c, 0xe6, 0x06, + 0xab, 0x30, 0x0d, 0xa3, 0xba, 0xe4, 0x24, 0xe0, 0x6f, 0x5c, 0xab, 0x43, + 0x9a, 0xf6, 0xf4, 0xd9, 0x74, 0x7e, 0x2c, 0x63, 0xf3, 0xd2, 0x17, 0x0b, + 0x57, 0xda, 0x1d, 0xd0, 0x47, 0x52, 0xc7, 0xc9, 0xb8, 0x14, 0x12, 0x23, + 0xc1, 0x23, 0x9b, 0x78, 0x51, 0x81, 0x7b, 0x66, 0x48, 0xbb, 0xc8, 0x7a, + 0x67, 0x84, 0x0a, 0xff, 0x82, 0xe9, 0x7e, 0xea, 0x5f, 0x5b, 0x94, 0xd6, + 0x24, 0x48, 0x3b, 0xa6, 0x25, 0x29, 0xd1, 0x92, 0x12, 0x9a, 0x5f, 0x84, + 0x3e, 0xb4, 0xe4, 0x3f, 0x15, 0xad, 0xe9, 0xec, 0xbc, 0x10, 0x7d, 0xc9, + 0xcd, 0xeb, 0x71, 0xd3, 0x79, 0x1a, 0xc2, 0xf5, 0x0d, 0x31, 0xac, 0x6a, + 0xac, 0xbc, 0x7f, 0x67, 0x43, 0x78, 0xc5, 0x23, 0x97, 0x56, 0x88, 0x3c, + 0xb0, 0x8e, 0x2c, 0x8a, 0x2b, 0x63, 0xfe, 0xb2, 0xaa, 0xb1, 0x71, 0x72, + 0x74, 0x41, 0xc3, 0x78, 0x0c, 0x5f, 0x92, 0x8d, 0x64, 0xe0, 0xf8, 0xde, + 0x09, 0x8f, 0xcd, 0x39, 0x45, 0x5a, 0x5d, 0x12, 0x6b, 0x26, 0xad, 0xfe, + 0xc0, 0x51, 0x1e, 0x00, 0xe9, 0x36, 0xf1, 0xb6, 0x74, 0x7b, 0x67, 0x6e, + 0xe2, 0xe4, 0xf4, 0x8e, 0x40, 0x87, 0xc6, 0x14, 0xcc, 0xa8, 0x25, 0x37, + 0x72, 0x0c, 0xc0, 0xf4, 0xff, 0xf4, 0x7d, 0xdc, 0xa8, 0xda, 0x68, 0xa5, + 0xbf, 0x04, 0xa3, 0x2c, 0x9f, 0xc7, 0x0a, 0x7c, 0x37, 0x86, 0xe7, 0x76, + 0x4e, 0x50, 0x79, 0xa5, 0xd1, 0x5f, 0x2e, 0x6f, 0x9a, 0x5c, 0x75, 0x73, + 0xd3, 0x7a, 0x10, 0x69, 0x45, 0xf1, 0x99, 0xca, 0x04, 0x24, 0x0a, 0x76, + 0xf5, 0xb9, 0xf7, 0xca, 0xf3, 0xfe, 0xde, 0x28, 0x70, 0x47, 0x3c, 0x35, + 0x17, 0x70, 0x21, 0x42, 0x32, 0x81, 0xfb, 0x3d, 0xc8, 0xf0, 0x35, 0xfe, + 0xe7, 0xee, 0x1b, 0x1e, 0xdd, 0xce, 0x19, 0xa2, 0x95, 0x95, 0x43, 0x2f, + 0xb2, 0x26, 0xcc, 0xbb, 0xb7, 0x8b, 0x8b, 0xff, 0x1c, 0xeb, 0x82, 0xa9, + 0x4f, 0x25, 0x58, 0xfa, 0x41, 0x22, 0x4a, 0xcb, 0x38, 0xc4, 0xff, 0x12, + 0x0d, 0xf7, 0x3b, 0xed, 0x0c, 0x7e, 0x29, 0xd3, 0x19, 0xe2, 0x2c, 0xff, + 0x8e, 0xbf, 0xe1, 0x1b, 0xc9, 0x6f, 0xac, 0x51, 0x97, 0x49, 0x68, 0x4d, + 0x20, 0x27, 0x3f, 0x11, 0xfe, 0x1e, 0x7f, 0xef, 0xda, 0x76, 0xba, 0xba, + 0xf2, 0xdb, 0x60, 0x36, 0x9a, 0xa3, 0x28, 0x89, 0xc8, 0x64, 0xb0, 0x90, + 0x79, 0xcb, 0x9d, 0x45, 0xcc, 0xdd, 0x6d, 0xf0, 0xd5, 0xb5, 0x8a, 0x64, + 0x51, 0x96, 0xcb, 0x12, 0x70, 0x0a, 0xca, 0x69, 0x34, 0x20, 0x43, 0x31, + 0x3c, 0xba, 0xb2, 0x80, 0xe1, 0xb2, 0x65, 0x79, 0x6f, 0x4e, 0x6e, 0x92, + 0x4b, 0xbf, 0x80, 0x2a, 0xb7, 0x97, 0x7f, 0xc9, 0xf5, 0xbc, 0xef, 0x1e, + 0x7f, 0xc9, 0xb6, 0x3d, 0x86, 0x4c, 0x89, 0x62, 0xac, 0x2b, 0xd0, 0x26, + 0x9d, 0xab, 0xeb, 0xfb, 0x5d, 0x4b, 0x6c, 0xe5, 0x58, 0x29, 0xb3, 0x4a, + 0x09, 0xed, 0x17, 0xf1, 0x00, 0xbb, 0x5c, 0x17, 0xc4, 0x56, 0x3b, 0xfc, + 0x13, 0x08, 0xc5, 0xcf, 0xc4, 0x14, 0x5f, 0xe2, 0xf8, 0xa5, 0xe2, 0xde, + 0x2f, 0x85, 0xde, 0xf7, 0xf7, 0x4d, 0xcd, 0x7b, 0xf2, 0xb6, 0x8b, 0x72, + 0x03, 0x6b, 0x2c, 0x7f, 0xde, 0x40, 0xf4, 0x76, 0x52, 0x2b, 0x61, 0x2d, + 0x72, 0xa2, 0x21, 0x0c, 0x1b, 0x44, 0x6c, 0x40, 0x04, 0xbc, 0x5e, 0xff, + 0xcb, 0xb6, 0x65, 0x99, 0xc6, 0xdb, 0xf7, 0x6f, 0xbc, 0x75, 0xd6, 0xcb, + 0x79, 0x6d, 0xd6, 0x94, 0xbd, 0xb7, 0x47, 0x89, 0xc6, 0xf6, 0xf0, 0xab, + 0x67, 0x60, 0x37, 0x32, 0x7d, 0x0f, 0x31, 0x08, 0xe2, 0x4e, 0x11, 0x0d, + 0x64, 0x1e, 0x66, 0xc6, 0xc6, 0xc5, 0x34, 0x56, 0xf8, 0xbf, 0x12, 0x83, + 0x7a, 0x75, 0xe0, 0x67, 0xae, 0x7b, 0x7e, 0xfb, 0xb6, 0x33, 0x38, 0xaa, + 0xea, 0x98, 0x9b, 0xfd, 0x36, 0x0d, 0x7e, 0x0f, 0xd4, 0xf9, 0x56, 0x6a, + 0xd5, 0x40, 0xb4, 0x38, 0xae, 0x6a, 0x7a, 0xc5, 0x40, 0x2c, 0x87, 0x72, + 0x80, 0x3e, 0x20, 0xf3, 0x48, 0xed, 0xbd, 0xb8, 0x13, 0xdf, 0xb7, 0xae, + 0x6a, 0xe6, 0x62, 0x6e, 0x73, 0x4c, 0xf0, 0x06, 0xba, 0x6c, 0xb2, 0xed, + 0xb6, 0x83, 0x32, 0x77, 0x63, 0xff, 0x84, 0x7e, 0xca, 0x91, 0xd7, 0x14, + 0xc7, 0xae, 0x12, 0x91, 0x49, 0xb6, 0x32, 0x92, 0x97, 0x5e, 0x39, 0x5a, + 0x71, 0x86, 0xdc, 0x92, 0xbb, 0x47, 0x8c, 0x3e, 0x24, 0xfc, 0x05, 0xf2, + 0x38, 0x7b, 0xdd, 0x4c, 0xec, 0x52, 0x8f, 0x80, 0x57, 0xd1, 0x52, 0x6b, + 0x0a, 0xb9, 0x81, 0xfd, 0x6b, 0xd2, 0x43, 0x58, 0x2c, 0x2a, 0xb8, 0x3d, + 0x66, 0xb0, 0x61, 0x9b, 0x3e, 0x7a, 0xc9, 0x38, 0x62, 0xc8, 0x6b, 0x4f, + 0xa0, 0xe3, 0xed, 0x13, 0x7b, 0xd6, 0x7c, 0xbb, 0x35, 0xaf, 0x81, 0xed, + 0x88, 0x91, 0x35, 0x2a, 0x5c, 0x5f, 0x47, 0xa7, 0x2f, 0x6f, 0xf5, 0x23, + 0x38, 0x20, 0x87, 0x5f, 0x65, 0x81, 0xfa, 0x44, 0x88, 0xd4, 0x96, 0x5e, + 0xc2, 0x84, 0xca, 0x39, 0x20, 0x28, 0x93, 0x94, 0x06, 0x4f, 0xc5, 0x41, + 0xff, 0x4e, 0x9d, 0xe6, 0xdb, 0x29, 0x50, 0xaf, 0x46, 0x49, 0x00, 0x24, + 0x04, 0xf2, 0xcd, 0x13, 0x84, 0x82, 0xa3, 0xc9, 0x21, 0x36, 0x26, 0x6f, + 0xad, 0xff, 0xb7, 0x6f, 0xf2, 0x6e, 0x15, 0x83, 0xa8, 0xb5, 0x2e, 0x89, + 0xfb, 0xca, 0xfe, 0xfa, 0x80, 0x2d, 0xc7, 0x43, 0xfe, 0xbe, 0xd5, 0x1b, + 0x8a, 0x4d, 0x08, 0xed, 0x55, 0x2c, 0x83, 0xc1, 0xe5, 0x7b, 0xc5, 0x1b, + 0x5d, 0xdd, 0xb7, 0x53, 0xf1, 0x3b, 0xd7, 0x7d, 0xed, 0xe6, 0x11, 0xbe, + 0x75, 0xb5, 0xb4, 0x22, 0x42, 0x53, 0x10, 0x81, 0x34, 0x7b, 0x81, 0x3c, + 0x94, 0x13, 0xc7, 0x2c, 0xed, 0xa1, 0xa3, 0x0a, 0x15, 0x7a, 0xb0, 0x26, + 0x69, 0xe0, 0x45, 0x19, 0xb1, 0x9c, 0x88, 0x9d, 0xe1, 0x61, 0x20, 0xee, + 0x3f, 0xe6, 0xa3, 0x8c, 0x61, 0x85, 0xa7, 0x28, 0xd2, 0x09, 0x7b, 0x69, + 0xb0, 0x95, 0x37, 0xd8, 0x96, 0x3c, 0xcc, 0x2c, 0x90, 0x83, 0x28, 0x8c, + 0x8b, 0x3b, 0xfe, 0xb7, 0xb5, 0x19, 0x15, 0x5e, 0xcf, 0x5f, 0xaf, 0x8c, + 0x76, 0x95, 0x02, 0x97, 0xe9, 0xac, 0x02, 0xb2, 0xee, 0x82, 0xe7, 0x16, + 0xca, 0x5b, 0x08, 0x22, 0xc6, 0x4e, 0xd2, 0xab, 0x10, 0x0f, 0x68, 0x5c, + 0xc2, 0x3d, 0x16, 0xf8, 0x74, 0x11, 0xd6, 0x4c, 0x65, 0xe1, 0x26, 0x9a, + 0x2d, 0xb0, 0x20, 0x66, 0xd2, 0xed, 0x60, 0xf4, 0xd1, 0xc2, 0x7d, 0x44, + 0xd7, 0xbd, 0x45, 0x36, 0x7b, 0xdc, 0xef, 0x87, 0xba, 0xbe, 0x16, 0x40, + 0x13, 0xa3, 0x3a, 0x6e, 0x12, 0xc0, 0xa3, 0xe2, 0x01, 0xfa, 0xde, 0xe5, + 0x75, 0xb9, 0x8a, 0x12, 0x19, 0x44, 0x8a, 0x12, 0xc9, 0x51, 0x84, 0xa5, + 0xcb, 0xc0, 0xec, 0xee, 0xd3, 0xaf, 0x34, 0xa4, 0x91, 0x34, 0x52, 0x01, + 0xeb, 0x00, 0x8e, 0x62, 0x71, 0x6f, 0x32, 0x80, 0x3e, 0xdc, 0x17, 0x3b, + 0x7d, 0x4b, 0x50, 0x4e, 0x81, 0x90, 0x98, 0xde, 0x4c, 0xc6, 0x90, 0x09, + 0x6e, 0xbb, 0x4e, 0x1f, 0x87, 0x0b, 0x2e, 0x1f, 0xed, 0x42, 0x0e, 0x2d, + 0x04, 0x24, 0xb0, 0x40, 0xc3, 0xde, 0x12, 0x24, 0x15, 0x2a, 0x68, 0x09, + 0xf8, 0xf8, 0x71, 0xf1, 0x85, 0x16, 0x12, 0xa4, 0x58, 0xc1, 0xa6, 0x19, + 0x1a, 0x68, 0x9d, 0xa1, 0x94, 0x32, 0x08, 0x11, 0x51, 0x14, 0xb1, 0xa4, + 0x24, 0x0c, 0xdd, 0x2c, 0x04, 0x20, 0x19, 0x72, 0x35, 0x60, 0xda, 0x79, + 0x84, 0x11, 0x05, 0xf0, 0xe6, 0x52, 0xf8, 0x9f, 0x3a, 0xd0, 0x9e, 0xe1, + 0xe4, 0x50, 0x99, 0x8c, 0xb4, 0xba, 0x33, 0xc7, 0xc0, 0x33, 0x00, 0x76, + 0x0e, 0x10, 0x19, 0x31, 0x23, 0x8d, 0x34, 0x96, 0xdf, 0xd8, 0x6b, 0x24, + 0x65, 0x3f, 0x4d, 0x1c, 0x95, 0x5a, 0x79, 0xc2, 0xe5, 0xb2, 0x36, 0xc5, + 0xa6, 0x8b, 0x28, 0x03, 0x95, 0xda, 0x51, 0xa3, 0x96, 0x00, 0xf9, 0xe0, + 0xbc, 0x7e, 0xc5, 0xab, 0x8a, 0x64, 0xa5, 0x7c, 0xf3, 0x65, 0x98, 0xc1, + 0x92, 0x4b, 0x9f, 0xa6, 0x87, 0x8a, 0x35, 0xa5, 0x35, 0x14, 0x93, 0x26, + 0x05, 0xfe, 0xec, 0x4b, 0xdc, 0xea, 0xd6, 0xb6, 0x54, 0x23, 0x2c, 0x24, + 0x72, 0xfe, 0x71, 0x90, 0x31, 0xfd, 0x00, 0x84, 0xc2, 0xc8, 0x63, 0x8a, + 0x88, 0xcb, 0x27, 0xf0, 0x7e, 0x05, 0x1e, 0xf3, 0xb4, 0xfa, 0x7e, 0xe1, + 0x77, 0x67, 0xe3, 0xa6, 0x28, 0x11, 0x48, 0xe3, 0xbd, 0x00, 0x25, 0x7b, + 0x30, 0xcb, 0xec, 0x27, 0xc1, 0x61, 0x28, 0x1c, 0x56, 0x66, 0x12, 0x10, + 0xba, 0x08, 0x03, 0x91, 0x43, 0xd3, 0x6d, 0x2a, 0xcd, 0x2a, 0x58, 0x64, + 0x68, 0x24, 0x4f, 0xc7, 0x47, 0xf1, 0x7c, 0x69, 0x9a, 0x14, 0x64, 0x5e, + 0x53, 0xbd, 0x74, 0x85, 0xa9, 0x29, 0xa6, 0x7e, 0xae, 0x39, 0x35, 0x40, + 0x8c, 0xe5, 0x59, 0x30, 0x5c, 0x7f, 0x46, 0xa1, 0x37, 0x29, 0x04, 0x07, + 0xc5, 0xf1, 0xcf, 0x30, 0x0f, 0x89, 0x87, 0x31, 0x4f, 0x33, 0xa2, 0x04, + 0xb2, 0x9b, 0x30, 0x55, 0x14, 0xb1, 0x82, 0xac, 0x3e, 0xb8, 0x1a, 0xb9, + 0xca, 0xa5, 0xe9, 0x4b, 0x28, 0x77, 0x3a, 0x63, 0xe8, 0xad, 0xbe, 0x98, + 0xd2, 0x2d, 0x32, 0xc6, 0x30, 0x82, 0x0e, 0xc1, 0x8f, 0xb9, 0x70, 0x13, + 0xca, 0x42, 0xd8, 0x07, 0x0f, 0x23, 0xd9, 0x5a, 0xed, 0x92, 0x9b, 0x38, + 0xc5, 0xa0, 0x65, 0xb1, 0x08, 0x90, 0xcb, 0x61, 0x2c, 0x05, 0x1f, 0xa6, + 0x2a, 0x55, 0x24, 0x2f, 0x40, 0xc2, 0x4f, 0x5c, 0xb3, 0xcc, 0xd5, 0xfb, + 0x57, 0xda, 0x92, 0x08, 0xed, 0x0e, 0x56, 0x4e, 0x55, 0x6d, 0xfc, 0xc3, + 0x66, 0x95, 0x9c, 0x81, 0x27, 0xe5, 0x6c, 0x9d, 0x42, 0x94, 0x38, 0x68, + 0x48, 0x22, 0x58, 0x48, 0x86, 0xfa, 0x83, 0x66, 0xb6, 0xbd, 0xca, 0x0d, + 0x0c, 0x72, 0x68, 0xd6, 0x07, 0xe4, 0xcc, 0x84, 0x76, 0x85, 0x0f, 0x9c, + 0x7a, 0x2d, 0x6a, 0xed, 0x3e, 0x34, 0xda, 0x2b, 0xf2, 0xf4, 0x67, 0xa6, + 0x00, 0xd1, 0x64, 0x5e, 0x45, 0x12, 0x82, 0x2d, 0x95, 0x2f, 0xac, 0x58, + 0xf9, 0xea, 0x65, 0x4b, 0x27, 0xdb, 0x3d, 0xdd, 0x8d, 0x8a, 0x5e, 0xda, + 0xb5, 0xd6, 0x05, 0x88, 0x64, 0x1c, 0x84, 0x7f, 0x69, 0x12, 0x11, 0x2f, + 0x80, 0x7d, 0x12, 0xbb, 0xaa, 0x50, 0x71, 0x9b, 0x4c, 0xba, 0xdf, 0xaa, + 0x5e, 0xf6, 0x34, 0x1f, 0xef, 0xa5, 0x4f, 0xfa, 0x95, 0x34, 0xef, 0x84, + 0xed, 0xd9, 0x2f, 0x1c, 0xcd, 0xc6, 0x5e, 0x90, 0xfb, 0x13, 0xf3, 0xf0, + 0xfa, 0x3f, 0x7f, 0x77, 0xca, 0x76, 0x12, 0x9a, 0x3c, 0x92, 0x86, 0xed, + 0xcb, 0xe0, 0x22, 0x84, 0x86, 0x5d, 0x02, 0xf2, 0xfa, 0x37, 0x83, 0x64, + 0xad, 0x1f, 0x0d, 0xdb, 0x95, 0x8f, 0x3d, 0x70, 0xbe, 0xff, 0xfb, 0x5d, + 0xfd, 0xbe, 0x1b, 0x92, 0xcc, 0xb6, 0x95, 0xef, 0x63, 0x8a, 0x72, 0xc8, + 0x4e, 0x88, 0xf9, 0xa3, 0xb9, 0x07, 0x9c, 0xb3, 0x3f, 0xad, 0xca, 0x84, + 0xb2, 0x06, 0x42, 0x28, 0xb7, 0xc4, 0xf1, 0x07, 0x9c, 0xcf, 0x8e, 0xe7, + 0xd9, 0xc9, 0xa8, 0xf8, 0x9e, 0x1b, 0x96, 0x48, 0xf6, 0xa9, 0x55, 0x5d, + 0x6d, 0xff, 0xff, 0xed, 0x49, 0xc8, 0x82, 0x8e, 0x33, 0x09, 0x78, 0x68, + 0x44, 0x2c, 0xd9, 0xbf, 0xd4, 0x22, 0x03, 0xad, 0x38, 0x01, 0x7b, 0xeb, + 0x1b, 0x8b, 0x6c, 0x94, 0xda, 0x81, 0x6e, 0xd8, 0x6a, 0x26, 0x02, 0x28, + 0xa3, 0x2f, 0xa8, 0x0f, 0xef, 0x0d, 0xbc, 0xb9, 0xa2, 0x57, 0xb2, 0x72, + 0x28, 0x81, 0x9b, 0x5d, 0x54, 0x86, 0x7b, 0xf9, 0xed, 0x13, 0xe1, 0x8c, + 0xa4, 0x32, 0x35, 0xe4, 0x8e, 0x01, 0xe1, 0xdd, 0x71, 0xc5, 0xfe, 0x50, + 0x53, 0xdf, 0xef, 0x6b, 0x69, 0x81, 0x35, 0x5a, 0x65, 0x16, 0x87, 0xce, + 0x42, 0x86, 0x32, 0xd4, 0x48, 0x97, 0x3f, 0x10, 0x39, 0xa3, 0xf6, 0x03, + 0xc1, 0xb2, 0xe7, 0xe3, 0xed, 0xae, 0x92, 0x06, 0xca, 0xd0, 0xd0, 0x96, + 0x51, 0xd2, 0x4b, 0x9f, 0xef, 0x5a, 0xdc, 0x66, 0x2b, 0x56, 0xa3, 0x5f, + 0xe3, 0x4b, 0x67, 0x39, 0x09, 0x6f, 0x27, 0x68, 0xd0, 0x75, 0x66, 0xf3, + 0x5c, 0x7c, 0x99, 0x97, 0xbe, 0x95, 0xb7, 0x22, 0xde, 0x54, 0x77, 0x8e, + 0x97, 0x05, 0x21, 0xa4, 0x00, 0x9a, 0x1d, 0xcc, 0xf5, 0x5e, 0xc6, 0xcf, + 0x48, 0x84, 0xab, 0x80, 0xe4, 0x3d, 0x25, 0xc0, 0x88, 0xc7, 0x62, 0xce, + 0x40, 0x32, 0x45, 0xc4, 0x89, 0x44, 0x64, 0xeb, 0x20, 0xe7, 0xba, 0x5a, + 0x97, 0xe7, 0xb1, 0x1a, 0xa6, 0xeb, 0xe2, 0x4f, 0x30, 0x03, 0x60, 0xc2, + 0x84, 0xcc, 0xf0, 0x0a, 0xa8, 0xb0, 0x97, 0x22, 0x48, 0x78, 0x40, 0x46, + 0x9f, 0xc4, 0x83, 0xfe, 0x62, 0x7b, 0xfe, 0xbb, 0xfb, 0x3d, 0x36, 0x2a, + 0xf5, 0xde, 0xb3, 0xbd, 0xf9, 0x4f, 0xcb, 0x1e, 0xbf, 0xcd, 0xe0, 0xef, + 0x3f, 0x34, 0x9b, 0xf3, 0x96, 0xd1, 0x30, 0x84, 0x69, 0x8d, 0x00, 0xf3, + 0x77, 0x1e, 0x06, 0x66, 0x09, 0x3d, 0xd2, 0xeb, 0x76, 0x2f, 0x96, 0xba, + 0x56, 0x73, 0x18, 0x6b, 0x5b, 0x89, 0xef, 0x1e, 0x9f, 0x4e, 0x5c, 0x62, + 0x73, 0xa5, 0x71, 0x7f, 0xa6, 0xb6, 0x27, 0x05, 0x89, 0xa6, 0x34, 0x6f, + 0xb8, 0x6a, 0x5c, 0xb3, 0x72, 0xe7, 0xc1, 0x2a, 0x9e, 0xc1, 0x3f, 0xbf, + 0x7f, 0x71, 0x7f, 0x6f, 0x3b, 0xfd, 0xf7, 0xbf, 0xb1, 0xfd, 0xaa, 0xdf, + 0x4b, 0x7f, 0x73, 0x6d, 0x7a, 0x2e, 0x2f, 0x95, 0xb6, 0xe6, 0xe5, 0xbc, + 0x18, 0x58, 0xcc, 0x4c, 0x3b, 0x49, 0x10, 0x88, 0x3e, 0x20, 0xe6, 0xfe, + 0x33, 0x5c, 0xc2, 0xc7, 0x6e, 0xbe, 0x7a, 0xbb, 0xaa, 0xd6, 0xd7, 0x13, + 0x81, 0xfb, 0xfd, 0xfe, 0x76, 0xfa, 0x26, 0xb9, 0x01, 0x87, 0x3d, 0x8f, + 0x5d, 0xe2, 0xa1, 0xc6, 0xa9, 0x2a, 0x26, 0xf7, 0x8f, 0x04, 0x23, 0x0c, + 0xd5, 0x49, 0x36, 0x72, 0x25, 0x74, 0x12, 0x66, 0xee, 0x7b, 0xe6, 0x2f, + 0xbf, 0x1f, 0xdf, 0xcc, 0xd2, 0x7d, 0xfd, 0xd5, 0x0b, 0x2d, 0xf7, 0xe3, + 0x37, 0x5b, 0xf7, 0xe3, 0xf7, 0xe5, 0x09, 0xfe, 0x7b, 0xca, 0xc7, 0x68, + 0xa7, 0xcb, 0x9d, 0xec, 0x38, 0xe4, 0x5e, 0xec, 0x02, 0x87, 0xd4, 0xc3, + 0xd9, 0x51, 0x5f, 0x3b, 0xef, 0xed, 0x78, 0x14, 0xe9, 0xde, 0xb7, 0xff, + 0x4f, 0x6d, 0x5d, 0x1c, 0x36, 0xed, 0xe5, 0x57, 0xe5, 0xd8, 0x39, 0x87, + 0x8b, 0x8e, 0xc7, 0x57, 0x97, 0xdd, 0x8a, 0x76, 0x40, 0xba, 0x23, 0xee, + 0x4d, 0x7c, 0x65, 0x72, 0xc8, 0x9d, 0x2f, 0xee, 0x36, 0xd4, 0xfb, 0xd6, + 0xff, 0x49, 0x7a, 0x7f, 0x93, 0xfa, 0x7b, 0x3f, 0x5a, 0x79, 0xf9, 0x85, + 0xd6, 0xeb, 0x7b, 0xf5, 0xd1, 0x64, 0x2e, 0x72, 0xf0, 0x98, 0x36, 0x03, + 0xed, 0xfe, 0xc0, 0x4e, 0x06, 0xec, 0x09, 0x8b, 0x83, 0x8d, 0x7f, 0x7b, + 0xa6, 0x75, 0xd7, 0x6e, 0xf3, 0xa8, 0xdb, 0xd2, 0xb6, 0x5b, 0xf8, 0xc5, + 0xe3, 0x86, 0xd1, 0x5a, 0xf9, 0xe7, 0x4e, 0x7a, 0x69, 0xb1, 0x65, 0xc3, + 0xc9, 0xb0, 0xfb, 0xbd, 0xea, 0xb7, 0x05, 0xd2, 0x73, 0x9a, 0x39, 0xdc, + 0xde, 0x2a, 0xef, 0xdf, 0x8c, 0xc3, 0xcd, 0xdf, 0x85, 0xf4, 0x89, 0xae, + 0xbc, 0xeb, 0xbf, 0xe7, 0xad, 0xe6, 0x9c, 0x6a, 0x60, 0xef, 0x5a, 0xff, + 0x4e, 0x95, 0xa6, 0x96, 0x2f, 0x3f, 0x97, 0x2c, 0x4d, 0x96, 0xd6, 0xe7, + 0xf4, 0x11, 0xe9, 0x5d, 0x5e, 0x28, 0x9c, 0x75, 0x55, 0xcc, 0xef, 0x65, + 0x6a, 0x2b, 0x29, 0xb7, 0xff, 0x43, 0x9d, 0xcb, 0x91, 0x60, 0x58, 0x50, + 0x79, 0xef, 0xb4, 0xd8, 0x7a, 0x1d, 0x94, 0x2a, 0xe4, 0x54, 0x74, 0x4c, + 0xe5, 0x8c, 0xeb, 0xfb, 0x13, 0xfd, 0x4a, 0xc3, 0xee, 0x3f, 0x71, 0x33, + 0xf9, 0xba, 0xa5, 0x17, 0xde, 0xcf, 0x45, 0x28, 0x75, 0xfe, 0xb8, 0x35, + 0xa5, 0x79, 0x9b, 0x54, 0x37, 0xc8, 0xa7, 0x8b, 0x0d, 0x56, 0x92, 0x3f, + 0xd8, 0xc8, 0x68, 0xf4, 0xe2, 0x1c, 0xbc, 0x4a, 0x5a, 0x9d, 0xea, 0x85, + 0x57, 0xa1, 0x45, 0x58, 0xb9, 0xc8, 0x23, 0x7a, 0xc5, 0xfe, 0x2f, 0xbd, + 0x9d, 0xe9, 0xbf, 0x19, 0x2a, 0x14, 0x0d, 0x78, 0xa4, 0x01, 0x03, 0x0e, + 0x97, 0x91, 0x0c, 0x5c, 0x6b, 0x9d, 0x29, 0x50, 0x5e, 0xfc, 0x18, 0x51, + 0x91, 0x9b, 0x03, 0x41, 0x1c, 0xb9, 0xe4, 0x42, 0x59, 0xcf, 0x3b, 0xd6, + 0xe9, 0xe3, 0x19, 0xc0, 0x82, 0x28, 0x60, 0x3f, 0x1e, 0x32, 0xe0, 0x05, + 0xca, 0x07, 0x5c, 0x8e, 0x37, 0xb0, 0xcb, 0x0d, 0xf1, 0x21, 0x91, 0x96, + 0x41, 0xb4, 0x67, 0x56, 0xab, 0x7d, 0x75, 0x02, 0x86, 0x83, 0xbf, 0x39, + 0x7b, 0x9d, 0x0c, 0x7c, 0xb0, 0x7d, 0x38, 0x4f, 0x9c, 0xf2, 0xe6, 0x52, + 0xdd, 0x2f, 0xc4, 0x3d, 0x75, 0x5e, 0xbb, 0x53, 0x7a, 0x4f, 0xa6, 0xf5, + 0x3a, 0xdb, 0xa1, 0xc0, 0x02, 0x62, 0xf2, 0xe6, 0x90, 0xca, 0x92, 0x3e, + 0x9c, 0x9f, 0x72, 0x0b, 0x7f, 0x63, 0xa7, 0x5f, 0x07, 0x2a, 0x62, 0xa9, + 0xe6, 0x22, 0x25, 0xb7, 0x96, 0xad, 0x51, 0x0b, 0xc6, 0x47, 0x9d, 0x76, + 0xbc, 0x1f, 0x83, 0x2c, 0x65, 0xd9, 0x15, 0xfb, 0x7c, 0x85, 0x6a, 0xd6, + 0xa6, 0xc8, 0x04, 0x5c, 0x25, 0xa1, 0x96, 0x91, 0xfa, 0x31, 0xaf, 0xd2, + 0x0d, 0xdd, 0x7f, 0x8a, 0x09, 0x4f, 0xd9, 0x38, 0x3f, 0xb6, 0x1e, 0x52, + 0xf3, 0x8a, 0x27, 0x25, 0xe2, 0x93, 0x08, 0x7c, 0x69, 0xa4, 0x39, 0xd6, + 0x59, 0x07, 0x0c, 0xd2, 0x91, 0x9c, 0xf3, 0x04, 0xf7, 0x7b, 0x99, 0x72, + 0x2c, 0x73, 0x7b, 0x6d, 0xe7, 0x7b, 0x1a, 0x8b, 0x71, 0x8e, 0x8c, 0xf2, + 0xea, 0x3a, 0x52, 0xee, 0x44, 0x91, 0xf8, 0x26, 0xfc, 0xc2, 0xde, 0x9b, + 0xd9, 0x6c, 0x3c, 0xc4, 0xaf, 0x75, 0x64, 0x3c, 0xa4, 0x27, 0xdc, 0xf8, + 0x5f, 0x91, 0x28, 0x87, 0xaa, 0xce, 0xea, 0x6e, 0x5c, 0xa2, 0x00, 0x04, + 0xcb, 0x4c, 0xe5, 0x99, 0xca, 0x00, 0x27, 0x34, 0x72, 0x5e, 0x0b, 0x4e, + 0x03, 0xbd, 0x7d, 0x10, 0x11, 0x90, 0xca, 0x8c, 0xbf, 0x04, 0xbe, 0xb2, + 0x5b, 0x65, 0xf1, 0x22, 0x83, 0xd1, 0x84, 0x3d, 0x16, 0x26, 0x30, 0xf1, + 0x03, 0xe6, 0x64, 0xa8, 0xc8, 0x20, 0x3c, 0x3b, 0x01, 0x72, 0xbc, 0xea, + 0xaa, 0x94, 0xf2, 0x80, 0x1d, 0x93, 0xc3, 0x3c, 0xbf, 0x4f, 0xce, 0x48, + 0x8f, 0xb5, 0x38, 0x83, 0x5c, 0x4d, 0x7f, 0xd6, 0x68, 0x70, 0x0c, 0x90, + 0x8c, 0x5d, 0x2b, 0xc2, 0x60, 0x51, 0xad, 0xfb, 0xfb, 0x22, 0x97, 0x02, + 0xe6, 0xda, 0x4c, 0x7c, 0x46, 0xfe, 0x36, 0xec, 0x8b, 0x9a, 0x09, 0x48, + 0x7d, 0x13, 0x2e, 0xd7, 0x1b, 0x3f, 0xcb, 0xe9, 0xa5, 0x90, 0xc4, 0x30, + 0x0c, 0x92, 0x23, 0x22, 0x89, 0x91, 0x62, 0x73, 0xb0, 0x8f, 0x55, 0xd2, + 0x9e, 0x1c, 0x3a, 0x22, 0x57, 0x87, 0xd9, 0x6e, 0x47, 0x93, 0xdd, 0xfd, + 0x53, 0xa0, 0x5e, 0x40, 0x92, 0x04, 0x54, 0x57, 0x3a, 0x69, 0x45, 0x7f, + 0xe7, 0x8d, 0x03, 0x8b, 0xff, 0xe2, 0x76, 0x13, 0xc1, 0x22, 0x2d, 0xf3, + 0xa9, 0x8b, 0xb9, 0x63, 0x33, 0x56, 0xa3, 0x9f, 0x02, 0xf5, 0x3d, 0x6c, + 0x89, 0xe3, 0xc9, 0x88, 0xc3, 0xa3, 0xf0, 0x5e, 0x05, 0xcd, 0x22, 0xeb, + 0xe1, 0x0c, 0x36, 0x2c, 0xb6, 0x7b, 0x40, 0x30, 0xf3, 0xab, 0x2f, 0xe0, + 0x4f, 0x03, 0x97, 0x2b, 0xd9, 0xfe, 0xfe, 0x23, 0xa7, 0x9f, 0x05, 0xdc, + 0x66, 0x82, 0xd2, 0x54, 0x6d, 0x87, 0xfa, 0x0c, 0x8e, 0x48, 0x25, 0xde, + 0xb0, 0x13, 0x77, 0x71, 0x55, 0x1e, 0x89, 0x63, 0x8d, 0xdb, 0x8a, 0x1c, + 0x31, 0x0d, 0xa2, 0xfa, 0xa0, 0x5c, 0x50, 0x34, 0x11, 0x22, 0x61, 0x1e, + 0xe0, 0x55, 0xfe, 0xd7, 0x5a, 0x5c, 0x91, 0x2b, 0xaf, 0x65, 0x91, 0x8c, + 0xe7, 0x1c, 0x34, 0x88, 0x22, 0x63, 0x2c, 0x56, 0x70, 0x4e, 0x15, 0x02, + 0x9b, 0x52, 0xff, 0x22, 0x14, 0xff, 0xb3, 0x05, 0x6e, 0xb7, 0xb6, 0x41, + 0x11, 0x21, 0x44, 0xe4, 0xf6, 0x90, 0xf0, 0x4d, 0x79, 0xf3, 0x34, 0x32, + 0xf2, 0x33, 0xb4, 0x94, 0x69, 0x49, 0xeb, 0xd3, 0x43, 0x7b, 0x07, 0x60, + 0xd1, 0xdc, 0x81, 0x43, 0x1a, 0x68, 0x1c, 0x9f, 0x64, 0xe3, 0x1c, 0x8d, + 0xaf, 0x40, 0x52, 0xd5, 0x28, 0x26, 0x69, 0x9c, 0x9a, 0x26, 0x80, 0x4e, + 0xc8, 0x12, 0x24, 0xeb, 0x56, 0x54, 0xe9, 0xb5, 0x2a, 0x0c, 0x44, 0xd2, + 0xd2, 0xe7, 0x56, 0xab, 0x97, 0x16, 0xac, 0x18, 0x41, 0x28, 0x4e, 0x11, + 0x46, 0x03, 0x2c, 0x79, 0x8c, 0x3f, 0xcf, 0x77, 0x96, 0x84, 0xc9, 0x03, + 0x26, 0xee, 0x7d, 0x3e, 0x15, 0xb6, 0x6b, 0x1d, 0x90, 0xdd, 0x87, 0x29, + 0x88, 0x06, 0x69, 0x19, 0x8c, 0x27, 0xef, 0x9d, 0x1a, 0x9f, 0xca, 0x12, + 0xff, 0x70, 0xee, 0x16, 0x10, 0x71, 0x95, 0x2a, 0x19, 0x79, 0x54, 0x3e, + 0x8b, 0xa7, 0x49, 0xc4, 0xe8, 0x4f, 0x2a, 0xac, 0xe0, 0x04, 0x66, 0x28, + 0xcf, 0x2a, 0x87, 0x64, 0x3e, 0x5d, 0x04, 0x3e, 0xc4, 0x89, 0x06, 0xc9, + 0x64, 0x98, 0xa0, 0xe7, 0x07, 0x6f, 0x05, 0xb4, 0xfb, 0x66, 0x9e, 0x33, + 0xb3, 0xbc, 0xe3, 0x10, 0x86, 0xa4, 0x10, 0xc9, 0xfd, 0x89, 0x97, 0x13, + 0x9e, 0x74, 0x49, 0x61, 0x29, 0xca, 0x9b, 0x98, 0x1a, 0x10, 0x84, 0x89, + 0xac, 0x02, 0xa3, 0xbf, 0xf2, 0x5f, 0xff, 0x8a, 0xfc, 0xf9, 0xab, 0xd6, + 0x90, 0xe5, 0xe0, 0x58, 0x2f, 0xd1, 0xde, 0x44, 0xc0, 0x5a, 0x67, 0x52, + 0x63, 0x28, 0x0a, 0x04, 0x63, 0xcf, 0xc1, 0x21, 0x38, 0xe9, 0x8b, 0xaf, + 0x2e, 0x4e, 0x40, 0x81, 0xa0, 0x9a, 0x1b, 0x69, 0x3f, 0x67, 0x07, 0x28, + 0x8c, 0x24, 0x24, 0x68, 0x63, 0x12, 0xee, 0xce, 0xdf, 0x8b, 0xeb, 0x4d, + 0x45, 0x07, 0xe7, 0xea, 0x49, 0xbb, 0xd1, 0x36, 0x6e, 0xdd, 0xd7, 0xe0, + 0xaf, 0x12, 0xf4, 0x08, 0x48, 0x9b, 0xd4, 0x26, 0x19, 0x6a, 0x5e, 0x7b, + 0xce, 0xd7, 0xde, 0xdd, 0x6a, 0x1f, 0xc1, 0x9b, 0xbd, 0x13, 0xb6, 0x1d, + 0x84, 0x15, 0x93, 0x3c, 0xf4, 0xf0, 0x06, 0xfa, 0xcd, 0xce, 0x89, 0x78, + 0x76, 0xe7, 0x23, 0x72, 0xe7, 0xf1, 0x3e, 0x27, 0x86, 0x54, 0x75, 0xec, + 0xef, 0x9e, 0x7b, 0xf2, 0x75, 0x57, 0x46, 0xc4, 0x2b, 0xf0, 0x55, 0x6c, + 0x95, 0x71, 0xc4, 0xf7, 0xd6, 0x32, 0xee, 0xd9, 0xa5, 0x8c, 0x6d, 0xce, + 0x40, 0x25, 0xc9, 0x01, 0x80, 0x7d, 0x75, 0xbf, 0x8a, 0xeb, 0xbc, 0x48, + 0xe7, 0xa7, 0x2e, 0x58, 0x06, 0x2c, 0xd5, 0xee, 0x20, 0x90, 0x22, 0xa8, + 0x4a, 0x41, 0x1e, 0xe7, 0x62, 0x9b, 0x13, 0x28, 0x02, 0x4d, 0xd6, 0xd0, + 0xb1, 0x80, 0x96, 0x39, 0xa3, 0x4c, 0xa4, 0x7b, 0x83, 0xf7, 0x78, 0x9f, + 0xbe, 0x0a, 0xf9, 0x98, 0xcb, 0x17, 0x7d, 0x46, 0xe4, 0x10, 0xbd, 0xa6, + 0x89, 0xca, 0x00, 0x98, 0xd0, 0x2f, 0xaa, 0x84, 0x09, 0xc2, 0xac, 0xc5, + 0xd6, 0xe9, 0x91, 0x1b, 0x5e, 0x49, 0x52, 0x73, 0x15, 0xf5, 0x6b, 0xf0, + 0xdb, 0xd4, 0x32, 0x8d, 0x34, 0xb8, 0x5c, 0x25, 0xe4, 0x21, 0x7a, 0x7c, + 0x44, 0x2e, 0x54, 0xe3, 0x5d, 0xf2, 0x59, 0xfd, 0x63, 0x6b, 0xb6, 0x2f, + 0x3b, 0xdb, 0xb3, 0x39, 0x94, 0xe5, 0x26, 0x26, 0x79, 0x5a, 0x0c, 0x26, + 0x12, 0xfc, 0x41, 0x57, 0x89, 0x63, 0x11, 0x0b, 0xc6, 0x46, 0x57, 0xa3, + 0xb2, 0xa5, 0x2a, 0x5d, 0xf6, 0xfd, 0x7c, 0x73, 0xe2, 0xaf, 0x6f, 0x5b, + 0xa4, 0xb3, 0x05, 0x1c, 0x7d, 0xc1, 0x89, 0xfa, 0xcd, 0x03, 0x29, 0xa0, + 0x25, 0x18, 0xcd, 0xe1, 0xf1, 0xee, 0x5a, 0x21, 0xbf, 0x4a, 0xb8, 0x4c, + 0x9c, 0x87, 0x21, 0x09, 0x19, 0xe4, 0xa5, 0xe2, 0x03, 0x50, 0x31, 0x34, + 0x7c, 0x49, 0xbf, 0xe6, 0x56, 0x6c, 0xb6, 0xdf, 0x4e, 0xa6, 0x34, 0xd9, + 0xd8, 0x90, 0x50, 0x26, 0x54, 0x11, 0x14, 0x08, 0x28, 0x1f, 0x05, 0x1b, + 0xa6, 0x5d, 0x39, 0x42, 0x77, 0xb6, 0xc7, 0xc4, 0xfa, 0xb1, 0x43, 0x0a, + 0x93, 0x86, 0xf9, 0xe0, 0xfe, 0xa9, 0x65, 0x99, 0xfe, 0xeb, 0x93, 0xe3, + 0x61, 0xb2, 0x2b, 0x6c, 0xde, 0xd6, 0xc6, 0x02, 0xc5, 0xc1, 0x91, 0x53, + 0x5e, 0xf4, 0xcb, 0xf9, 0x70, 0x03, 0xb0, 0xde, 0x85, 0x18, 0xc6, 0x4b, + 0xd0, 0xe2, 0x7a, 0x6a, 0x28, 0xc3, 0xec, 0x45, 0xc4, 0xf1, 0x91, 0x4a, + 0x44, 0x4c, 0x78, 0xe3, 0xa4, 0x47, 0xd8, 0x6a, 0x9a, 0xc8, 0x21, 0x67, + 0x10, 0x11, 0x35, 0x36, 0x42, 0xa2, 0xde, 0x4d, 0xb0, 0xc3, 0xb2, 0x5d, + 0x44, 0x27, 0x18, 0xbc, 0xd5, 0xbf, 0xd4, 0x9d, 0xe4, 0xb5, 0x50, 0x88, + 0x3a, 0xf8, 0x30, 0x8f, 0x64, 0xed, 0xbb, 0x28, 0x9e, 0x78, 0x9e, 0x41, + 0x6d, 0x98, 0x2f, 0x6c, 0x1c, 0xe9, 0xe0, 0x51, 0x93, 0x2a, 0xd2, 0xa7, + 0xdc, 0xcc, 0x91, 0x70, 0x40, 0xc9, 0x99, 0x82, 0x10, 0xec, 0xa9, 0xf9, + 0xde, 0x9d, 0x5b, 0xd6, 0x9d, 0xb7, 0xb5, 0xb3, 0xe8, 0x33, 0x31, 0x0e, + 0x49, 0x79, 0x25, 0x65, 0x51, 0x99, 0x28, 0x01, 0x3f, 0xad, 0x50, 0x9e, + 0x5f, 0x5c, 0x0c, 0x73, 0x42, 0xac, 0x53, 0xb7, 0x71, 0x87, 0x5d, 0x3b, + 0x53, 0x03, 0x30, 0x06, 0x7c, 0x66, 0xfa, 0x34, 0xfe, 0xa9, 0x41, 0xbf, + 0xba, 0x85, 0xf6, 0xa8, 0xe4, 0xbb, 0x95, 0xf2, 0xce, 0x59, 0x01, 0x32, + 0x50, 0x92, 0x13, 0xf8, 0xa9, 0x42, 0xad, 0x36, 0x27, 0x84, 0xd8, 0x5c, + 0xe8, 0x84, 0xa4, 0x0a, 0x43, 0xc4, 0x7d, 0xdb, 0x8a, 0x8e, 0xdb, 0x4f, + 0x34, 0xb8, 0x29, 0x1f, 0x4e, 0xa0, 0xc8, 0xa8, 0x88, 0xbf, 0xda, 0x86, + 0xcf, 0xc5, 0xac, 0xed, 0x0e, 0x37, 0x26, 0xa4, 0xba, 0x6e, 0x40, 0xc3, + 0x3a, 0x1f, 0x12, 0x44, 0xa4, 0xb0, 0x27, 0x28, 0x34, 0xe7, 0x7b, 0x2f, + 0x87, 0xe7, 0x86, 0xfe, 0xce, 0x04, 0x38, 0xd3, 0x18, 0x99, 0x30, 0x29, + 0xd6, 0x42, 0xce, 0xba, 0x73, 0xd8, 0x35, 0x6f, 0x43, 0x6a, 0x82, 0x5b, + 0x51, 0x12, 0x0e, 0xd4, 0x61, 0x48, 0xb9, 0x4a, 0xfb, 0x34, 0x95, 0x71, + 0x4c, 0xb8, 0x9a, 0xa7, 0x6e, 0xc6, 0x81, 0x38, 0xa4, 0x57, 0x83, 0xca, + 0x64, 0x19, 0xb4, 0x90, 0x91, 0x32, 0xac, 0x9b, 0x79, 0xce, 0x42, 0x01, + 0xf0, 0x66, 0x7f, 0x38, 0xa5, 0xad, 0x44, 0x43, 0x1f, 0xca, 0x0f, 0x59, + 0xbe, 0x8f, 0x9d, 0xff, 0x16, 0xc9, 0xb6, 0xb7, 0x37, 0xa4, 0x46, 0x54, + 0x62, 0xac, 0x03, 0x2a, 0xac, 0x07, 0x39, 0xf1, 0xc9, 0xcd, 0x9b, 0xd7, + 0x6b, 0x47, 0x13, 0x25, 0xb0, 0x68, 0x24, 0x1e, 0xb0, 0xb8, 0xec, 0x19, + 0xa7, 0x2e, 0xaf, 0x0e, 0xb2, 0x1b, 0xd1, 0x63, 0x56, 0x83, 0xce, 0x19, + 0xe9, 0xcb, 0x14, 0x0b, 0x19, 0x4f, 0xc3, 0x61, 0x55, 0x8d, 0xfe, 0x94, + 0x86, 0x4a, 0x0d, 0x78, 0xbb, 0x1b, 0x8a, 0x8d, 0x3d, 0xe4, 0xbe, 0x0e, + 0xf4, 0xa0, 0x97, 0x91, 0x02, 0xfe, 0x7d, 0xf4, 0xda, 0x44, 0x07, 0x79, + 0xc8, 0xa2, 0x4d, 0x24, 0x50, 0x39, 0x3f, 0x9c, 0x0f, 0x33, 0xba, 0x96, + 0x0b, 0xf9, 0x2b, 0xb7, 0x87, 0xc5, 0x74, 0x69, 0xba, 0xb6, 0xe2, 0x67, + 0x2d, 0xe0, 0xcc, 0x00, 0x0d, 0x5b, 0x64, 0x77, 0xb8, 0x4d, 0x1a, 0x23, + 0x2f, 0xd3, 0xf6, 0x47, 0x76, 0xff, 0x6d, 0x74, 0xde, 0x84, 0x36, 0xc3, + 0x7b, 0x62, 0x8c, 0x2f, 0xc4, 0x54, 0x15, 0x16, 0xc7, 0xd8, 0x10, 0xd7, + 0xa6, 0x0e, 0xd9, 0xa3, 0x1a, 0x41, 0x19, 0x76, 0x44, 0xa5, 0xda, 0x9e, + 0x6b, 0x0a, 0xaf, 0xea, 0x27, 0x29, 0x3f, 0xaf, 0x01, 0xb7, 0xb0, 0x31, + 0xff, 0x9e, 0x15, 0x21, 0x3d, 0xec, 0x3e, 0x24, 0x8a, 0x38, 0x63, 0x94, + 0x3c, 0x08, 0x39, 0xd9, 0x44, 0x99, 0x28, 0x64, 0x6b, 0x09, 0xcd, 0xe8, + 0xf8, 0x99, 0xb1, 0x33, 0x6d, 0xd6, 0xa4, 0xa5, 0xd2, 0x3c, 0x09, 0x39, + 0x38, 0x8b, 0x23, 0x14, 0x64, 0xb6, 0x01, 0xa2, 0x7e, 0x2c, 0xbe, 0xd5, + 0x24, 0xe5, 0xd8, 0x19, 0xce, 0xc8, 0x77, 0x8c, 0xec, 0x6c, 0x8a, 0x38, + 0x2d, 0x8b, 0xa8, 0x42, 0x2d, 0xb1, 0x34, 0x28, 0x9c, 0x85, 0x19, 0x78, + 0x40, 0x0a, 0xee, 0xff, 0xfa, 0xa3, 0xd9, 0xa2, 0x26, 0x55, 0xdb, 0x8f, + 0xa0, 0xc5, 0xd7, 0xa1, 0x07, 0x67, 0x87, 0x0f, 0x4e, 0x31, 0x09, 0x74, + 0x2a, 0xd2, 0xf3, 0xfb, 0xf3, 0x8c, 0x51, 0x65, 0x27, 0x74, 0x67, 0x2c, + 0x64, 0x7e, 0x6e, 0x32, 0xce, 0x12, 0x0b, 0x1b, 0xb6, 0xa2, 0xda, 0xb4, + 0xc2, 0xf4, 0xaa, 0xfe, 0x3a, 0x47, 0x52, 0x9c, 0x91, 0x43, 0x1f, 0xe7, + 0xee, 0x71, 0x8e, 0xa2, 0x3e, 0xbd, 0xf3, 0x2e, 0xbd, 0xbc, 0xae, 0x76, + 0x7f, 0x15, 0x3d, 0x41, 0xc1, 0xf3, 0xed, 0xc2, 0xdb, 0x3a, 0xcd, 0x2d, + 0xf4, 0xd4, 0x5e, 0x10, 0x02, 0x84, 0xd1, 0x23, 0x5d, 0xac, 0x86, 0x4c, + 0x7d, 0x17, 0xd3, 0xbc, 0x7f, 0xec, 0x42, 0xa9, 0x74, 0x01, 0x01, 0xa3, + 0x8e, 0x20, 0x8c, 0x26, 0x66, 0x4e, 0x03, 0xf5, 0x07, 0xac, 0x2b, 0xaf, + 0x5a, 0xd2, 0xbf, 0xef, 0x74, 0xf1, 0x5c, 0xb1, 0xa7, 0x48, 0x1a, 0x48, + 0x0c, 0x69, 0xc6, 0x32, 0xc0, 0x70, 0x80, 0x77, 0x9a, 0x4c, 0x6f, 0xd7, + 0x22, 0xd8, 0xcd, 0x42, 0x3f, 0xae, 0xf9, 0x01, 0x08, 0x06, 0x9c, 0xca, + 0xc8, 0x3d, 0x63, 0x2b, 0x54, 0x7e, 0x76, 0xc1, 0x2c, 0xe0, 0xf5, 0x50, + 0x54, 0x51, 0x1b, 0xcb, 0x77, 0x36, 0xed, 0x30, 0x2e, 0x63, 0xad, 0x34, + 0x38, 0x9a, 0xd6, 0x9b, 0x0c, 0xcd, 0x2c, 0x91, 0x7f, 0x19, 0xfc, 0x4d, + 0x58, 0xac, 0x47, 0xdd, 0x17, 0xf3, 0xb8, 0xa0, 0x10, 0x3f, 0x16, 0xad, + 0x9b, 0x06, 0xc9, 0x97, 0x7b, 0x3f, 0x40, 0xb0, 0x0d, 0x1d, 0x85, 0xcb, + 0x12, 0x79, 0x61, 0x8e, 0x31, 0x20, 0x51, 0x9e, 0x59, 0x97, 0x87, 0x6d, + 0xfa, 0x4a, 0x43, 0x70, 0x8f, 0x75, 0x9f, 0x31, 0x75, 0xd9, 0xa6, 0x84, + 0x9b, 0x40, 0xaf, 0x62, 0xa1, 0x7b, 0x4a, 0x6e, 0x72, 0xdc, 0xd0, 0xa0, + 0x04, 0x35, 0x94, 0xd5, 0xa7, 0x3e, 0xc6, 0xd3, 0x73, 0x7b, 0xfd, 0x5b, + 0x64, 0x1d, 0x94, 0x48, 0x69, 0x8a, 0x89, 0xd8, 0x50, 0x22, 0x30, 0x94, + 0xfb, 0x5f, 0xaa, 0x53, 0x0b, 0xb9, 0x53, 0xe4, 0xbe, 0x0a, 0x27, 0x97, + 0x77, 0x53, 0x0d, 0xc5, 0xde, 0x64, 0x7f, 0x73, 0x77, 0x23, 0x5a, 0x47, + 0xb0, 0xda, 0x7c, 0x3e, 0x00, 0xd4, 0x4f, 0x80, 0x3c, 0xd8, 0x7f, 0x4d, + 0x76, 0x56, 0x8f, 0x55, 0xdd, 0x6d, 0x63, 0xde, 0xeb, 0xa3, 0x8e, 0x44, + 0xcf, 0xcc, 0x9e, 0xe7, 0x42, 0x94, 0x7b, 0xb9, 0x1d, 0x7d, 0x15, 0xb3, + 0x0a, 0x9e, 0xe8, 0xd5, 0x8f, 0x2e, 0xe4, 0xa6, 0x79, 0x55, 0x82, 0xff, + 0xfe, 0x79, 0x3a, 0x3d, 0xa7, 0x02, 0x04, 0x8d, 0x65, 0x6e, 0xab, 0x9c, + 0x62, 0xd8, 0x6f, 0x7e, 0xab, 0x21, 0x70, 0x12, 0x88, 0x76, 0x68, 0x5b, + 0xe2, 0x4b, 0xc6, 0x69, 0x0d, 0x5f, 0xf8, 0x21, 0x92, 0xe5, 0x49, 0xef, + 0xe6, 0x79, 0x9d, 0xcf, 0x6d, 0x5a, 0x7d, 0xbf, 0x08, 0x61, 0x62, 0xbd, + 0x87, 0x75, 0x8e, 0x36, 0x1c, 0x0a, 0x13, 0x94, 0x9c, 0x03, 0x01, 0x2e, + 0x47, 0xd8, 0x93, 0x13, 0xab, 0xab, 0x8d, 0xfe, 0x4d, 0xb3, 0x4e, 0x0a, + 0x18, 0x67, 0x84, 0x38, 0x21, 0x11, 0xb0, 0x58, 0x7c, 0x78, 0x23, 0xaf, + 0xbc, 0x58, 0xf7, 0x3b, 0xeb, 0x69, 0x59, 0xc9, 0x1a, 0x03, 0xe6, 0x00, + 0x43, 0xc0, 0x15, 0x56, 0x9b, 0x19, 0xb3, 0xbc, 0xdb, 0xeb, 0xec, 0xca, + 0xb8, 0x6a, 0x18, 0x7c, 0x59, 0xba, 0xa4, 0xc6, 0x84, 0x91, 0x12, 0x4b, + 0x41, 0xf2, 0xbc, 0x5a, 0x52, 0x29, 0x99, 0x0c, 0x5e, 0xb0, 0x9f, 0x0c, + 0xd4, 0xc5, 0x6e, 0xed, 0xf9, 0xb0, 0xc1, 0xc1, 0x7d, 0xae, 0x67, 0x4c, + 0xc0, 0x55, 0xf4, 0xed, 0x03, 0xad, 0xc5, 0xb4, 0x83, 0xfe, 0xec, 0x16, + 0x70, 0x08, 0xdd, 0x5c, 0x45, 0xb4, 0xb7, 0x99, 0x9b, 0xec, 0xa0, 0x06, + 0x42, 0x44, 0xd0, 0x9f, 0xda, 0x05, 0xb7, 0xef, 0x7c, 0xd5, 0xa3, 0x0f, + 0x4c, 0x36, 0xf7, 0x92, 0x98, 0xc4, 0x64, 0x89, 0xa7, 0x2a, 0x39, 0x41, + 0xa1, 0x28, 0xcb, 0xc4, 0xc1, 0x77, 0xda, 0x49, 0xf7, 0xfa, 0xb3, 0x72, + 0x93, 0xa0, 0xad, 0x09, 0x9b, 0xd9, 0x82, 0x44, 0xf6, 0x84, 0x9c, 0xbf, + 0xad, 0x73, 0xde, 0x15, 0x76, 0xee, 0x9c, 0x4f, 0xce, 0x5f, 0x5d, 0xf4, + 0x90, 0x51, 0xfc, 0xaf, 0xfc, 0x59, 0x2a, 0x70, 0x92, 0x66, 0xeb, 0xd3, + 0x04, 0x29, 0xc8, 0xc2, 0x49, 0x40, 0x9a, 0xac, 0xff, 0x94, 0x31, 0x42, + 0x81, 0x83, 0x17, 0x6f, 0x87, 0xdc, 0x62, 0xe7, 0x74, 0x50, 0xc9, 0xc6, + 0x83, 0xbf, 0x7a, 0xe0, 0xae, 0x11, 0xbd, 0x86, 0x0f, 0x02, 0xdc, 0x2a, + 0x58, 0xee, 0x50, 0x04, 0xcf, 0x28, 0x7d, 0xa0, 0xdf, 0xd8, 0x2b, 0xec, + 0xe3, 0x79, 0xff, 0xd9, 0x2b, 0xc3, 0x23, 0x3a, 0x4a, 0x19, 0x26, 0x69, + 0x7c, 0x5a, 0xcb, 0xf5, 0x66, 0x11, 0xdd, 0x7e, 0x4f, 0x99, 0xc6, 0xf2, + 0x6f, 0xf6, 0xe5, 0x3f, 0x60, 0x46, 0xfe, 0x52, 0x26, 0xab, 0x3a, 0xcc, + 0x48, 0xbf, 0xdf, 0xcc, 0xaf, 0x67, 0xc5, 0x02, 0x99, 0x93, 0x43, 0x0b, + 0x11, 0x31, 0xda, 0x9c, 0xa6, 0x64, 0xb9, 0x4b, 0xed, 0x05, 0x56, 0xf8, + 0x75, 0xdf, 0xbc, 0x7d, 0xfd, 0xee, 0x69, 0x59, 0xfb, 0x68, 0x7e, 0xfd, + 0x94, 0xd3, 0x46, 0x1d, 0xa2, 0x61, 0x59, 0x8c, 0x7b, 0x05, 0x58, 0x07, + 0x8a, 0xfe, 0x37, 0x7b, 0xbc, 0x9c, 0x40, 0x04, 0x4d, 0x08, 0x31, 0xca, + 0x3c, 0xb9, 0x74, 0x67, 0x46, 0xbc, 0xc9, 0x79, 0x78, 0x4e, 0x60, 0xbf, + 0xf8, 0x92, 0x51, 0xa4, 0xda, 0x35, 0xfd, 0xe8, 0x89, 0x4b, 0xe0, 0xc8, + 0x9c, 0xb2, 0xbe, 0xb9, 0x3c, 0x26, 0x4b, 0x6a, 0x8a, 0xfa, 0xa8, 0x5c, + 0xd3, 0x0b, 0x9a, 0x86, 0xd9, 0x5a, 0xa1, 0x2b, 0x13, 0x2d, 0xf1, 0xe9, + 0xde, 0x99, 0x78, 0x0d, 0xc9, 0xae, 0x6d, 0x4e, 0x8e, 0x3c, 0x25, 0x2d, + 0x1f, 0xb1, 0x04, 0x69, 0x86, 0x4b, 0x23, 0xc3, 0x70, 0x8c, 0x5d, 0x08, + 0xc0, 0x3b, 0x8f, 0x88, 0x8f, 0x82, 0x42, 0x20, 0xef, 0xf8, 0xbb, 0x92, + 0x06, 0x8b, 0x19, 0x3e, 0xc6, 0x34, 0xa5, 0x95, 0x90, 0xf0, 0x16, 0xac, + 0xee, 0x4b, 0xed, 0x7c, 0xb6, 0x83, 0x2a, 0x67, 0x14, 0x8d, 0xec, 0x4c, + 0xe5, 0x6e, 0x96, 0x92, 0xa6, 0x05, 0x2a, 0xb1, 0x57, 0xb8, 0x7c, 0x31, + 0xc7, 0x56, 0xf4, 0xf3, 0xc9, 0x06, 0x3f, 0x51, 0x8e, 0x93, 0x45, 0xe6, + 0x22, 0xed, 0x44, 0x71, 0xff, 0x61, 0x38, 0x7f, 0xc4, 0x57, 0xff, 0x3c, + 0x04, 0x1a, 0xa1, 0xc8, 0x80, 0xb0, 0x97, 0x30, 0x2b, 0x17, 0xe5, 0x67, + 0xa2, 0x54, 0x38, 0xdc, 0x5e, 0x48, 0x27, 0xe8, 0x08, 0xd7, 0xfd, 0xef, + 0x99, 0x34, 0xb1, 0x40, 0x06, 0x14, 0x49, 0x43, 0x2b, 0x18, 0xbe, 0x5a, + 0x1d, 0xc1, 0x8e, 0xcf, 0x0a, 0xca, 0xf0, 0x13, 0x5b, 0x8b, 0x3f, 0xe8, + 0x3c, 0xa0, 0x84, 0x46, 0x09, 0x69, 0x14, 0x70, 0x1f, 0x06, 0x61, 0x3d, + 0xd3, 0x25, 0x24, 0x5f, 0x37, 0x0b, 0x36, 0xea, 0xbd, 0xce, 0xd9, 0xb5, + 0x0f, 0x21, 0x84, 0x25, 0xb4, 0x8b, 0x34, 0xe5, 0x41, 0xa7, 0x58, 0x47, + 0xcc, 0x97, 0x91, 0x1e, 0xcc, 0x63, 0x88, 0x8b, 0x84, 0xb9, 0xf7, 0x0c, + 0x59, 0xb4, 0x28, 0x8a, 0xa8, 0xcc, 0xa9, 0xc4, 0x9a, 0xb6, 0x2e, 0xca, + 0x0d, 0x8c, 0x52, 0x08, 0x9b, 0xd7, 0xee, 0x2a, 0x1b, 0x0e, 0xde, 0x81, + 0x38, 0x62, 0x97, 0x43, 0xe3, 0xd2, 0x20, 0x5a, 0x30, 0x92, 0xe9, 0x1f, + 0x14, 0x99, 0x69, 0x8c, 0xa1, 0x13, 0xc8, 0x48, 0x4e, 0xf5, 0x73, 0x3a, + 0xf4, 0xa1, 0xfb, 0xf4, 0x7c, 0xfb, 0x3f, 0x2d, 0xe6, 0x2d, 0x78, 0x10, + 0x03, 0x70, 0x7c, 0xc1, 0x90, 0x96, 0x4f, 0x09, 0x04, 0xfd, 0x03, 0x55, + 0xf7, 0x1a, 0x58, 0x5f, 0x6a, 0x26, 0x25, 0x80, 0xc6, 0x9f, 0xf7, 0x1b, + 0x45, 0x06, 0xdc, 0xcd, 0xf4, 0x65, 0x4b, 0xfb, 0xbe, 0xd7, 0x45, 0x19, + 0x1d, 0x41, 0x90, 0x82, 0x39, 0x14, 0x83, 0x35, 0x9c, 0xf3, 0xd7, 0x9f, + 0x9a, 0x70, 0x43, 0x03, 0x90, 0xde, 0x6d, 0x84, 0xb0, 0xe9, 0x55, 0x68, + 0xfb, 0xcd, 0xfb, 0x3c, 0x9b, 0x44, 0xb0, 0x22, 0x8b, 0x97, 0x79, 0x83, + 0xe9, 0xee, 0x5b, 0x59, 0xab, 0x8a, 0x69, 0x85, 0x37, 0x57, 0x11, 0x8f, + 0x97, 0x21, 0x80, 0xa1, 0x2c, 0x89, 0xc9, 0xed, 0x6c, 0xce, 0x4d, 0xb5, + 0xe2, 0xb7, 0xd2, 0xc4, 0xa2, 0x70, 0xe1, 0xb4, 0x45, 0x78, 0x2f, 0x0e, + 0x63, 0x06, 0x33, 0xc7, 0x9d, 0x1a, 0x52, 0x13, 0xdf, 0xda, 0xdb, 0xe8, + 0x57, 0x49, 0x1d, 0x81, 0xac, 0x71, 0x8c, 0x64, 0x90, 0x29, 0x19, 0xd1, + 0x33, 0xf9, 0xc0, 0xce, 0x13, 0xf2, 0x59, 0x16, 0xf0, 0xea, 0x6a, 0x75, + 0x78, 0x07, 0x75, 0xf0, 0xf9, 0x0a, 0x66, 0x52, 0x48, 0xd0, 0x4e, 0xd0, + 0x6b, 0x89, 0xd6, 0x9b, 0xef, 0x7e, 0xef, 0x23, 0x29, 0x0a, 0x4c, 0x28, + 0xe4, 0xc8, 0x1f, 0x15, 0x13, 0x3a, 0xca, 0x98, 0x20, 0x7f, 0xe2, 0x9d, + 0x2a, 0xe6, 0x1c, 0x77, 0xa5, 0x06, 0xe3, 0x19, 0xce, 0x7f, 0x38, 0xcf, + 0x5e, 0xd1, 0xef, 0xf8, 0x81, 0x20, 0xfa, 0x98, 0x45, 0x9f, 0x2b, 0x27, + 0xe0, 0x73, 0x8c, 0xe1, 0x01, 0x2c, 0x05, 0x0a, 0xa7, 0x19, 0xd9, 0xe5, + 0xf6, 0x06, 0xd4, 0x02, 0xdb, 0xee, 0x38, 0x41, 0x35, 0x02, 0x48, 0xa4, + 0x72, 0x0a, 0xa2, 0x6c, 0x6a, 0x8a, 0x18, 0x08, 0x4b, 0x26, 0x44, 0xa4, + 0x0a, 0x1e, 0x20, 0xcf, 0xfc, 0xa8, 0x72, 0x37, 0xe6, 0xe4, 0xea, 0xb4, + 0x4c, 0xe9, 0xe5, 0x6e, 0x1c, 0x57, 0x83, 0x2f, 0x44, 0x50, 0xc0, 0x3c, + 0x37, 0x07, 0x38, 0xbd, 0x6a, 0xc7, 0x88, 0x90, 0x0b, 0x7d, 0xe9, 0x20, + 0x2a, 0xbc, 0x73, 0xad, 0x07, 0x60, 0x52, 0x9a, 0x47, 0x2f, 0xe2, 0xc6, + 0x9a, 0xc0, 0x0d, 0x37, 0x12, 0x60, 0x99, 0x51, 0xfc, 0x5e, 0xdf, 0xc0, + 0x23, 0x7f, 0x47, 0xa2, 0x5c, 0xa6, 0x2f, 0xa5, 0x62, 0x13, 0xc6, 0x3b, + 0x61, 0xf1, 0x52, 0xe1, 0x90, 0x9b, 0xba, 0x4a, 0x67, 0x02, 0x3f, 0xfd, + 0x8d, 0xfe, 0xd7, 0xe1, 0xed, 0xd6, 0x26, 0x3a, 0xd9, 0x48, 0x3c, 0x00, + 0x11, 0x36, 0x33, 0x18, 0x6c, 0x9e, 0x57, 0x89, 0xe5, 0x44, 0xfe, 0xae, + 0x69, 0xd9, 0x4c, 0x22, 0x1f, 0x18, 0xe9, 0x07, 0xf8, 0xbf, 0x42, 0x8c, + 0x0b, 0xf1, 0xb5, 0x6c, 0x95, 0x2f, 0xcb, 0x0c, 0x85, 0x90, 0xc0, 0xfa, + 0x98, 0xcb, 0x32, 0xd8, 0xfb, 0x1a, 0x57, 0x49, 0xf5, 0xea, 0x9b, 0x27, + 0x3d, 0xf6, 0x11, 0xf5, 0xfc, 0xa9, 0x7f, 0xca, 0xe3, 0xf5, 0xb3, 0x50, + 0xd5, 0x78, 0xcf, 0x28, 0x99, 0x82, 0x11, 0x96, 0x46, 0x51, 0x00, 0x25, + 0x56, 0x4e, 0xf6, 0xa6, 0x59, 0xd3, 0x97, 0xdf, 0x0c, 0x1f, 0x4e, 0xa6, + 0x69, 0x50, 0x2f, 0xad, 0xe4, 0x84, 0x8b, 0x82, 0xc6, 0x45, 0x2f, 0xb8, + 0x07, 0x9a, 0x5c, 0x1e, 0xa8, 0xe7, 0x9a, 0xcc, 0xff, 0xf4, 0x89, 0x30, + 0xa7, 0x52, 0x9b, 0x99, 0x65, 0x28, 0xda, 0xef, 0x4f, 0x5a, 0x8c, 0x27, + 0x36, 0x4a, 0x06, 0x5d, 0xc0, 0x5c, 0x79, 0x96, 0xbf, 0x2d, 0xd6, 0xcb, + 0xa4, 0xcc, 0xc7, 0x15, 0xa0, 0x93, 0xb0, 0x2f, 0xa1, 0x19, 0x5f, 0x6e, + 0x66, 0x94, 0xe7, 0x37, 0x74, 0xf8, 0x22, 0x57, 0xed, 0xca, 0x0f, 0x0d, + 0x31, 0x54, 0xe2, 0x5b, 0xc6, 0xb1, 0x3d, 0x97, 0xb5, 0xdb, 0xaa, 0x5d, + 0x60, 0x0f, 0x08, 0x22, 0x1e, 0x2d, 0x80, 0x99, 0x92, 0x1a, 0x4d, 0x2d, + 0x90, 0x41, 0x38, 0x40, 0x0d, 0x07, 0xe0, 0xbc, 0x0c, 0x76, 0x58, 0x61, + 0xb2, 0xd1, 0x4b, 0x97, 0x68, 0x12, 0x3f, 0x6a, 0x4f, 0xc3, 0xf9, 0x1f, + 0xc8, 0x58, 0x39, 0x7b, 0xbc, 0x7f, 0x5a, 0xf9, 0xc4, 0x1a, 0x14, 0x88, + 0x27, 0x1d, 0xc6, 0xf6, 0x66, 0x95, 0x87, 0xcb, 0x99, 0xee, 0x50, 0x8d, + 0x56, 0xff, 0x90, 0x0b, 0xb4, 0x94, 0x77, 0xcb, 0x06, 0x63, 0x7a, 0x65, + 0xf1, 0xfc, 0x35, 0x59, 0x68, 0xee, 0x50, 0x25, 0xf2, 0x5c, 0xff, 0x28, + 0x9e, 0xd1, 0xd5, 0xea, 0x84, 0x14, 0x90, 0x28, 0xfc, 0x5f, 0xa0, 0x3e, + 0xc8, 0xee, 0x61, 0xeb, 0x05, 0x9c, 0x6e, 0x44, 0x58, 0x78, 0xfc, 0xfe, + 0x0c, 0xb5, 0x01, 0xf9, 0xab, 0xf3, 0xbf, 0xcd, 0x6f, 0x8e, 0x31, 0xdc, + 0x4a, 0xb4, 0x12, 0xe9, 0x8a, 0x15, 0x90, 0x62, 0x4d, 0xc1, 0xef, 0xbf, + 0x53, 0xeb, 0x8f, 0x90, 0x1d, 0x17, 0xbf, 0xc7, 0xa3, 0x0c, 0x35, 0x26, + 0x76, 0x9b, 0xa4, 0x56, 0xf0, 0xfc, 0x41, 0xe0, 0x96, 0x02, 0x75, 0x9b, + 0x0f, 0xfe, 0x1a, 0x9c, 0x10, 0x79, 0xa5, 0xfa, 0x2c, 0x5b, 0x6f, 0xfa, + 0xf3, 0x16, 0xea, 0xca, 0xed, 0xb5, 0xe9, 0xd3, 0x73, 0xf0, 0x41, 0x29, + 0x98, 0x4a, 0x00, 0x10, 0x03, 0xe8, 0x02, 0x6f, 0x15, 0xf8, 0x42, 0x65, + 0xb6, 0x8b, 0xf7, 0x12, 0x96, 0x55, 0xf6, 0x0e, 0x38, 0xaa, 0xc7, 0x6f, + 0x70, 0x7b, 0x40, 0x0f, 0xce, 0x02, 0xa7, 0xe3, 0xba, 0x8f, 0xff, 0xaa, + 0x76, 0x7e, 0x3c, 0xc9, 0x43, 0x98, 0x59, 0xa5, 0x4c, 0x68, 0x99, 0x03, + 0x01, 0x45, 0x11, 0x0d, 0x04, 0x60, 0xfa, 0x9d, 0xa9, 0xf7, 0xfd, 0x9e, + 0x3b, 0xac, 0xc6, 0xf9, 0xdd, 0xd2, 0x8c, 0x9b, 0x13, 0x58, 0x83, 0xcc, + 0x69, 0x6e, 0x63, 0x58, 0x79, 0x80, 0x10, 0xc6, 0x61, 0x21, 0xe0, 0x61, + 0x42, 0xac, 0x07, 0x95, 0xfd, 0xbd, 0xb7, 0xa8, 0x17, 0xed, 0x71, 0xc2, + 0x58, 0xf3, 0x36, 0x5e, 0x4e, 0x09, 0xe0, 0x3f, 0x6e, 0x1d, 0x28, 0x7c, + 0x4b, 0x9d, 0x1f, 0xd7, 0x84, 0x27, 0x29, 0xd3, 0x1f, 0xcf, 0x0a, 0xfc, + 0xdb, 0x3a, 0xde, 0xda, 0xd1, 0x3a, 0x50, 0x4a, 0x5a, 0x82, 0x80, 0x48, + 0xd1, 0x38, 0x49, 0x9d, 0x88, 0xb7, 0x39, 0x16, 0xa7, 0xb7, 0xbb, 0xdf, + 0x82, 0xfa, 0xa4, 0x08, 0xca, 0x13, 0x20, 0xe4, 0xcc, 0x69, 0x10, 0x89, + 0x85, 0xdc, 0xfe, 0xca, 0xd5, 0xbb, 0x1c, 0x75, 0x71, 0x94, 0x70, 0xce, + 0x46, 0x58, 0x33, 0x92, 0x5d, 0x61, 0x29, 0xe4, 0xa1, 0xaf, 0xed, 0x8e, + 0x35, 0x89, 0xa7, 0x45, 0x82, 0x33, 0x85, 0xa5, 0x36, 0x9f, 0x70, 0xbd, + 0xf4, 0x63, 0x5d, 0xc2, 0x3c, 0xd8, 0xea, 0x53, 0x7b, 0x6a, 0xf0, 0xa9, + 0x19, 0xbb, 0x9b, 0x1d, 0xf5, 0xaf, 0x4e, 0x71, 0xf4, 0xae, 0x44, 0x12, + 0x18, 0x71, 0x03, 0x4d, 0x9d, 0x04, 0x89, 0x47, 0xc4, 0x02, 0x69, 0xb9, + 0x6b, 0x79, 0x76, 0x29, 0x6f, 0xe6, 0x9b, 0x40, 0xe8, 0x4b, 0x94, 0x84, + 0xd1, 0x90, 0x3d, 0xaf, 0xcf, 0x3e, 0xdb, 0xe5, 0xec, 0x5e, 0x2d, 0x7f, + 0x1a, 0x92, 0x32, 0x10, 0xcc, 0xcb, 0xb5, 0xf0, 0x13, 0x15, 0xb4, 0x2e, + 0xec, 0x11, 0x65, 0x90, 0x42, 0x1b, 0xb5, 0x20, 0xa7, 0x7c, 0x92, 0xd1, + 0x33, 0x9d, 0xea, 0xa8, 0x46, 0xca, 0x2a, 0x60, 0x3d, 0xcf, 0x5d, 0x8f, + 0xa5, 0x25, 0x42, 0xe5, 0xff, 0x2a, 0x0b, 0x60, 0xcf, 0xfd, 0x8c, 0xb7, + 0xd9, 0x83, 0xa2, 0xc9, 0x6f, 0xc2, 0x5a, 0x30, 0xc2, 0xd8, 0x41, 0xd7, + 0x9a, 0xbe, 0x1b, 0xfe, 0x3c, 0xa3, 0x0f, 0x2d, 0x02, 0xe0, 0x4a, 0x66, + 0x92, 0x2d, 0xb4, 0x11, 0x48, 0xcb, 0xed, 0x04, 0xd9, 0xd1, 0x5b, 0xe3, + 0x7f, 0x9f, 0x99, 0x3b, 0x92, 0x95, 0x51, 0x64, 0x3a, 0x5d, 0x94, 0xce, + 0xfb, 0x73, 0xf1, 0xde, 0x2b, 0xf0, 0xcf, 0xb2, 0x00, 0x44, 0xe4, 0x92, + 0xbd, 0x3f, 0x5b, 0xa5, 0x1f, 0x97, 0xeb, 0x84, 0x52, 0x18, 0xd5, 0xad, + 0x79, 0x2d, 0x47, 0xfd, 0x24, 0xa3, 0x43, 0x2d, 0x0f, 0xa2, 0x9a, 0xd0, + 0xe5, 0x70, 0x23, 0x04, 0x82, 0x3d, 0x84, 0xab, 0x22, 0xf8, 0x82, 0x90, + 0x48, 0x56, 0x50, 0xb7, 0x9a, 0x41, 0x2d, 0xfc, 0x6f, 0x25, 0x0b, 0x86, + 0x01, 0x8b, 0x35, 0x18, 0xc4, 0xa4, 0x68, 0x78, 0x3a, 0x99, 0xd4, 0xa0, + 0xd3, 0xa3, 0x23, 0xf5, 0xde, 0x69, 0xba, 0x22, 0x60, 0x89, 0x56, 0x51, + 0x87, 0xe9, 0xea, 0x48, 0xbc, 0xdf, 0xe2, 0x9e, 0x7b, 0xfc, 0x88, 0x6b, + 0x6a, 0xe9, 0x65, 0xb8, 0x9c, 0xe9, 0x72, 0x28, 0xc9, 0xe9, 0x89, 0x11, + 0xf1, 0x2a, 0xd1, 0x4f, 0x7e, 0xf9, 0x5e, 0x07, 0x4f, 0xee, 0xdc, 0x82, + 0x4a, 0x53, 0x30, 0xf9, 0x96, 0x85, 0x1f, 0x99, 0xac, 0xd9, 0xfa, 0x44, + 0xa4, 0xe5, 0x4f, 0x16, 0xe7, 0x9c, 0x42, 0x11, 0x2d, 0x95, 0x2c, 0xbf, + 0x00, 0x17, 0x9e, 0x98, 0xc9, 0x9e, 0x77, 0x85, 0xe2, 0x0b, 0x29, 0xb7, + 0xa2, 0x4f, 0x04, 0xc9, 0x2d, 0xa3, 0x04, 0x8f, 0x82, 0x5e, 0x16, 0x58, + 0x33, 0x00, 0x21, 0x34, 0x72, 0xe4, 0x2a, 0xd9, 0x44, 0x7a, 0x63, 0xfc, + 0xf5, 0xa5, 0x80, 0x7f, 0x9e, 0xb6, 0xb9, 0xa5, 0xe3, 0xb4, 0x99, 0x1f, + 0x4d, 0x61, 0x1e, 0xcd, 0xa6, 0x37, 0x9f, 0x38, 0x8c, 0xfa, 0x28, 0xa5, + 0x81, 0x18, 0xe4, 0xbb, 0x29, 0xcf, 0x1c, 0x74, 0xd7, 0x69, 0xa7, 0xd9, + 0xed, 0x4c, 0x10, 0x93, 0xf3, 0x47, 0x81, 0xe7, 0x90, 0x32, 0x6d, 0xc4, + 0x74, 0x2a, 0xcd, 0x2f, 0x04, 0xd2, 0x00, 0xcc, 0x20, 0x7e, 0x71, 0xab, + 0x73, 0xf4, 0xda, 0xd9, 0xe2, 0xf7, 0x2c, 0xf4, 0x86, 0x42, 0x85, 0x13, + 0x47, 0x25, 0x2e, 0xe0, 0x65, 0x6f, 0x5a, 0x22, 0xbc, 0x1c, 0xf1, 0x8f, + 0x87, 0xff, 0xda, 0x99, 0x50, 0x54, 0xa4, 0x48, 0x47, 0x0f, 0xf6, 0x2d, + 0xdf, 0x99, 0xc9, 0xb4, 0xb4, 0x67, 0x8c, 0x06, 0x3e, 0x80, 0xf9, 0x9a, + 0x03, 0x25, 0x97, 0x84, 0x04, 0x93, 0x97, 0xa5, 0x52, 0xc4, 0x43, 0x0e, + 0x91, 0x45, 0x0c, 0x06, 0xf5, 0x15, 0x89, 0x47, 0x15, 0xba, 0xaa, 0x03, + 0x90, 0xf1, 0x43, 0x8a, 0x33, 0xc6, 0xc7, 0x19, 0x21, 0x47, 0x00, 0xac, + 0x89, 0xec, 0xa9, 0xb6, 0xb8, 0x34, 0x7b, 0xf2, 0x51, 0xd3, 0xf9, 0xf4, + 0x18, 0x19, 0x87, 0xd0, 0x07, 0x54, 0x70, 0xf9, 0x79, 0x74, 0x51, 0xee, + 0x41, 0x0d, 0xfa, 0xed, 0x8f, 0x0e, 0x2f, 0xf7, 0xd4, 0x8b, 0xc3, 0xb5, + 0x72, 0x26, 0x5c, 0xe5, 0xbe, 0x9c, 0x3e, 0x01, 0x04, 0xfc, 0x6d, 0x7b, + 0xc2, 0x4f, 0xfe, 0x2c, 0x5e, 0xea, 0xf1, 0x64, 0x31, 0xc5, 0x31, 0x31, + 0x42, 0x7d, 0x98, 0x80, 0x64, 0x42, 0x47, 0xc4, 0x45, 0xed, 0xfc, 0xf2, + 0x9f, 0x45, 0xad, 0xda, 0xaf, 0x51, 0x61, 0x97, 0x45, 0x68, 0x31, 0xc9, + 0xa1, 0x46, 0x5e, 0x03, 0xa9, 0xaa, 0x05, 0x14, 0x51, 0x61, 0xe9, 0xbd, + 0x58, 0x6c, 0x6d, 0x09, 0xd2, 0x48, 0x65, 0x7d, 0x79, 0xd9, 0xc9, 0x1e, + 0xca, 0xa5, 0xdc, 0xa7, 0x86, 0x77, 0xd6, 0x41, 0x45, 0x0f, 0x88, 0x7e, + 0xb1, 0xa5, 0xfa, 0xdd, 0xaa, 0x2d, 0xa8, 0x89, 0xa1, 0x32, 0x3b, 0x0b, + 0xe0, 0x0a, 0xf5, 0x72, 0x29, 0x9c, 0x03, 0xce, 0x00, 0x42, 0x46, 0x06, + 0x79, 0xbc, 0xd2, 0xfd, 0x23, 0x08, 0x00, 0x7c, 0xad, 0x65, 0xc5, 0x69, + 0x51, 0xa8, 0xcc, 0x68, 0x45, 0x7b, 0xc4, 0x72, 0xdc, 0xf0, 0x43, 0xd0, + 0xa3, 0x24, 0x94, 0x4f, 0xd3, 0x03, 0x53, 0xf9, 0x47, 0xf2, 0xcd, 0x79, + 0xa7, 0x4b, 0x7c, 0xbb, 0x69, 0x00, 0x51, 0xaf, 0x4e, 0x11, 0xf1, 0x3e, + 0x80, 0xaa, 0x8d, 0x57, 0x2f, 0xc9, 0x6a, 0xff, 0x3d, 0xbc, 0xdb, 0xad, + 0xea, 0x75, 0xfb, 0xdb, 0x70, 0x64, 0xd1, 0x1b, 0xed, 0x4a, 0x55, 0x01, + 0xe0, 0x6d, 0x99, 0x6f, 0x17, 0x56, 0x2d, 0x1e, 0x17, 0x47, 0x26, 0x1d, + 0x50, 0xcf, 0x00, 0xdc, 0xb2, 0x28, 0x2a, 0x9f, 0xd7, 0xf7, 0x2e, 0xb6, + 0xb9, 0xe3, 0x91, 0xca, 0x9e, 0x58, 0xdb, 0x64, 0x4a, 0x42, 0x31, 0xfa, + 0x8a, 0xba, 0x7c, 0xa5, 0x8a, 0x76, 0xce, 0xdc, 0x47, 0xe3, 0xf8, 0xeb, + 0x3a, 0xdc, 0x90, 0xb1, 0xc4, 0x28, 0x1c, 0xaa, 0x08, 0x51, 0xfb, 0x74, + 0x76, 0xbd, 0x83, 0x75, 0x3e, 0xef, 0x2d, 0xb3, 0x21, 0x60, 0x04, 0xa2, + 0xf8, 0x05, 0x14, 0x72, 0xa8, 0x61, 0x20, 0xe5, 0x26, 0x77, 0x71, 0x70, + 0x4f, 0x8a, 0xfa, 0x3b, 0x88, 0x7b, 0x59, 0x65, 0x10, 0xdd, 0xa2, 0x22, + 0x55, 0x58, 0x28, 0xfc, 0xb5, 0xe9, 0x91, 0x7a, 0xf2, 0x35, 0x08, 0x50, + 0x9a, 0x5f, 0xd2, 0xda, 0xb6, 0x5b, 0xda, 0xb9, 0x14, 0x83, 0xb2, 0x5f, + 0xee, 0x73, 0x0f, 0xa8, 0x6c, 0xb3, 0xe2, 0x4a, 0x47, 0xc1, 0x3d, 0xf5, + 0x44, 0x8d, 0x50, 0xfa, 0xa2, 0x3e, 0x85, 0xf0, 0x1f, 0x7d, 0x49, 0x47, + 0xc5, 0x43, 0x7f, 0x40, 0xa5, 0xe2, 0x09, 0x03, 0xae, 0x98, 0x4b, 0xd3, + 0x07, 0xb9, 0x1e, 0x05, 0x7c, 0xf1, 0xb1, 0xe7, 0x26, 0xd6, 0xc9, 0xc9, + 0x0f, 0x06, 0xd6, 0x9d, 0xfc, 0x2a, 0xdb, 0x7f, 0x43, 0x39, 0x61, 0x69, + 0x32, 0xe7, 0x98, 0xdb, 0xde, 0x51, 0xd7, 0x21, 0xd1, 0x2a, 0x84, 0x9d, + 0x16, 0x32, 0xa1, 0x4e, 0x70, 0x41, 0x23, 0x97, 0x2f, 0xa2, 0x4f, 0x4e, + 0xb4, 0x97, 0xae, 0x5e, 0x6f, 0x05, 0x03, 0x7a, 0x23, 0x40, 0x3c, 0x2d, + 0x42, 0xa5, 0x95, 0x6c, 0x40, 0xec, 0x65, 0x30, 0x72, 0x8e, 0x11, 0x0c, + 0x49, 0xa0, 0x9b, 0x28, 0xcf, 0x9f, 0xca, 0x67, 0x7b, 0xa0, 0x68, 0x16, + 0xf1, 0x31, 0xe3, 0x6f, 0xc2, 0xb6, 0xee, 0xf3, 0xd6, 0xb6, 0x68, 0x19, + 0x86, 0x97, 0xc5, 0x22, 0x57, 0xa8, 0x1b, 0xe4, 0x78, 0xd7, 0x1d, 0xf9, + 0xe8, 0xcf, 0x15, 0x9b, 0x73, 0x48, 0xc2, 0xd5, 0x50, 0xd1, 0x6d, 0x3d, + 0xf8, 0xfd, 0xdb, 0x57, 0x90, 0x60, 0xdf, 0x30, 0xdd, 0x85, 0x47, 0xc6, + 0xa3, 0x5e, 0x19, 0xef, 0x8c, 0xd9, 0x29, 0xe2, 0x46, 0x59, 0xb1, 0x72, + 0x9d, 0x59, 0xbf, 0x72, 0xae, 0x37, 0x1c, 0xc4, 0x87, 0xc5, 0x23, 0x15, + 0xc3, 0xc2, 0xcb, 0xe1, 0x1a, 0x52, 0x48, 0x21, 0xf7, 0x20, 0xd8, 0xb9, + 0xdf, 0xbd, 0xd5, 0x4e, 0x45, 0x50, 0x29, 0x16, 0xe4, 0xc8, 0x4d, 0xf1, + 0x8a, 0x34, 0x61, 0x0e, 0x50, 0xca, 0x22, 0x7e, 0x22, 0x31, 0xd9, 0xc5, + 0x67, 0xa6, 0x83, 0x1a, 0x5c, 0x91, 0x0c, 0xf2, 0xdf, 0x19, 0x9d, 0x00, + 0x95, 0x0f, 0x72, 0xba, 0xa2, 0xd9, 0xff, 0x1f, 0xc7, 0x45, 0xbc, 0xcc, + 0x49, 0x90, 0xc9, 0x78, 0xc1, 0x8e, 0x98, 0x51, 0x10, 0x34, 0xf6, 0xc9, + 0x64, 0xd5, 0x55, 0x14, 0xc5, 0xc5, 0x71, 0x2e, 0x51, 0x79, 0xbe, 0xaa, + 0xff, 0xa6, 0xb3, 0x8d, 0x62, 0x34, 0x49, 0x63, 0xa3, 0x51, 0xd0, 0x91, + 0x23, 0x29, 0x11, 0xe2, 0x85, 0xdc, 0xd2, 0x61, 0x57, 0x25, 0x76, 0x2b, + 0x42, 0x08, 0x69, 0xac, 0x57, 0xa4, 0x35, 0x34, 0x4b, 0xd5, 0x86, 0xf0, + 0x35, 0x9d, 0xb9, 0x17, 0x98, 0xbe, 0x69, 0x70, 0xd9, 0xcd, 0x0f, 0xe5, + 0xe5, 0xaf, 0x97, 0x1f, 0xa4, 0xc7, 0xd3, 0x8b, 0x22, 0x32, 0x78, 0x49, + 0x84, 0x64, 0xaa, 0xe7, 0xe9, 0x86, 0xd8, 0xb8, 0xad, 0xe9, 0xc5, 0x11, + 0xcb, 0xf3, 0xad, 0xb5, 0x14, 0xa5, 0xe2, 0xf1, 0x43, 0xb5, 0xdf, 0xd3, + 0x7e, 0xb7, 0x9e, 0x50, 0x68, 0xf6, 0xcb, 0x9e, 0x43, 0x4b, 0xf5, 0x19, + 0x0c, 0xa9, 0x1f, 0xd6, 0x14, 0x0e, 0xdc, 0xe0, 0x09, 0x64, 0xa5, 0xe6, + 0x02, 0x95, 0x71, 0x7c, 0xed, 0xb9, 0xb4, 0x87, 0x6c, 0x96, 0x50, 0xcc, + 0x13, 0xa1, 0x36, 0xee, 0xbf, 0x7e, 0xdc, 0x58, 0xf7, 0x7f, 0xd1, 0x04, + 0x13, 0x01, 0xa4, 0x6d, 0xb4, 0x9a, 0x1a, 0xd0, 0x9e, 0x4f, 0xe0, 0xe7, + 0xdc, 0x93, 0xb6, 0xfd, 0xd4, 0x54, 0xd8, 0xed, 0x0b, 0xeb, 0x38, 0x5b, + 0xfe, 0xde, 0xf9, 0x0e, 0x0f, 0xad, 0x17, 0x04, 0x84, 0x2c, 0x25, 0x0f, + 0x99, 0xd2, 0x10, 0xcb, 0x19, 0x1a, 0xcc, 0x59, 0x6f, 0xe8, 0x17, 0x6f, + 0xe5, 0x04, 0xb3, 0x40, 0x00, 0x02, 0x40, 0x77, 0x01, 0x1b, 0x6a, 0xb0, + 0x55, 0xf7, 0x29, 0x1c, 0x95, 0x64, 0x42, 0xdd, 0xbf, 0x21, 0x1d, 0xa9, + 0x43, 0x24, 0x8b, 0xfc, 0x52, 0xc0, 0xce, 0x58, 0x00, 0xf0, 0x1d, 0x19, + 0x7d, 0x2c, 0x52, 0xfe, 0x5f, 0x3d, 0x5e, 0x94, 0x05, 0x22, 0x72, 0x87, + 0x80, 0xb1, 0x4b, 0xb4, 0x94, 0xb2, 0x4d, 0x2f, 0x8e, 0x25, 0xbb, 0x22, + 0x6c, 0x35, 0x03, 0x4c, 0xcd, 0x16, 0x45, 0xf2, 0x64, 0x9f, 0x82, 0x08, + 0x78, 0x33, 0x8d, 0x1a, 0x20, 0x78, 0xbb, 0x99, 0xbf, 0xf8, 0x4e, 0x91, + 0x76, 0x5d, 0x26, 0x18, 0x5b, 0x0c, 0xf0, 0x42, 0x6a, 0xa0, 0x71, 0xfe, + 0xa7, 0xd2, 0x26, 0xd1, 0x69, 0x5e, 0x73, 0x42, 0x1d, 0xb0, 0x99, 0xd6, + 0x49, 0x03, 0xe2, 0x2e, 0x1d, 0xd1, 0x86, 0x6c, 0x95, 0xf5, 0x14, 0x13, + 0x56, 0xb5, 0x6e, 0x0a, 0xde, 0x8a, 0x28, 0x62, 0x37, 0x9d, 0x99, 0x29, + 0xd0, 0x86, 0x14, 0x26, 0x81, 0x6a, 0xa8, 0x07, 0xbb, 0x23, 0x58, 0x54, + 0xd7, 0x5a, 0x36, 0xef, 0xe7, 0xd8, 0x1b, 0x86, 0xba, 0x6e, 0x29, 0xe6, + 0x9c, 0x91, 0xb8, 0x19, 0xe7, 0xb3, 0x03, 0xba, 0x1a, 0x39, 0x64, 0x34, + 0x8f, 0x72, 0x0f, 0x2d, 0xff, 0x0d, 0x8a, 0xaf, 0x34, 0x4e, 0x31, 0xf6, + 0x64, 0xbb, 0x5c, 0x0c, 0x66, 0x87, 0xb4, 0xd0, 0x95, 0x37, 0x98, 0x14, + 0x48, 0x01, 0x10, 0x8d, 0x60, 0x1b, 0xd2, 0xc6, 0xe9, 0x02, 0xff, 0x3c, + 0x01, 0xcc, 0xa5, 0x95, 0xa3, 0x42, 0x4d, 0x59, 0x00, 0x33, 0x5d, 0x38, + 0xe7, 0x71, 0x79, 0xeb, 0xcc, 0x2b, 0xd3, 0x34, 0xb5, 0xd7, 0x61, 0xac, + 0x14, 0xb2, 0xec, 0x52, 0x1a, 0x0e, 0x97, 0x02, 0x49, 0xed, 0xfc, 0x06, + 0xbb, 0x7f, 0x6f, 0xfa, 0x23, 0xad, 0x6f, 0x96, 0x2e, 0xee, 0x03, 0x36, + 0x34, 0x08, 0x4f, 0x26, 0x4f, 0xcd, 0x3e, 0x28, 0x54, 0x97, 0xbd, 0xfb, + 0x31, 0x46, 0x1a, 0x6b, 0x9b, 0xcf, 0x2d, 0xca, 0x37, 0xab, 0x8f, 0xd6, + 0x30, 0xc5, 0x95, 0x6d, 0xfe, 0x6f, 0xc8, 0x1b, 0x70, 0x90, 0x25, 0xb1, + 0x92, 0x02, 0xb0, 0x9d, 0x81, 0x0e, 0x26, 0x51, 0x97, 0x60, 0xbe, 0x25, + 0x62, 0xae, 0x5c, 0xd6, 0xbd, 0xfc, 0xca, 0xad, 0x6a, 0x6a, 0xdb, 0x4b, + 0x19, 0x8a, 0x04, 0xce, 0x73, 0x73, 0x39, 0x22, 0x6b, 0x2f, 0x5f, 0x22, + 0x78, 0xd6, 0xd1, 0xcb, 0xa3, 0xf0, 0x48, 0x78, 0x80, 0xb9, 0x69, 0xe4, + 0x57, 0xdc, 0x0e, 0x47, 0x6a, 0x28, 0x94, 0x88, 0xca, 0xac, 0x83, 0x27, + 0xbb, 0x11, 0x74, 0x74, 0xc8, 0xce, 0x11, 0x01, 0xc0, 0x0e, 0x92, 0xaf, + 0x58, 0xf9, 0xd3, 0xae, 0xa5, 0xed, 0x81, 0x84, 0x69, 0xd5, 0xcb, 0xe3, + 0x65, 0xc9, 0x84, 0xbb, 0x5d, 0x89, 0xe3, 0x8f, 0x98, 0x04, 0xf7, 0x06, + 0x93, 0x9f, 0xd8, 0xb3, 0x61, 0xfe, 0xfa, 0xd2, 0x86, 0x39, 0x53, 0xed, + 0x58, 0x0b, 0x61, 0x88, 0x46, 0x8f, 0x8f, 0x1f, 0xdf, 0x1a, 0x7a, 0x77, + 0x06, 0x72, 0xc5, 0x6a, 0x88, 0x60, 0x2f, 0x4a, 0x60, 0xe4, 0xbe, 0xa0, + 0x59, 0x69, 0xb0, 0xc6, 0x49, 0x7a, 0x95, 0x03, 0x0e, 0xa9, 0x60, 0x22, + 0xa3, 0xd4, 0xc6, 0x54, 0x63, 0xdc, 0x1c, 0x5a, 0x8a, 0x25, 0x19, 0x4f, + 0xc4, 0x8d, 0xae, 0xba, 0x9b, 0x3e, 0xe1, 0xd2, 0x27, 0x1c, 0x68, 0x87, + 0x18, 0x06, 0x5f, 0x64, 0x25, 0xba, 0x67, 0x0e, 0xda, 0x9a, 0xb9, 0x97, + 0x9e, 0x52, 0x32, 0x44, 0x25, 0x9a, 0xa7, 0xa3, 0xae, 0xce, 0x19, 0x6d, + 0x33, 0x04, 0x63, 0x93, 0x14, 0x43, 0x8c, 0xaf, 0xa8, 0x4f, 0xa8, 0xe3, + 0x53, 0x6f, 0x77, 0x4b, 0xc6, 0xd9, 0x6c, 0x02, 0x8f, 0xd8, 0x17, 0x9d, + 0x52, 0x10, 0x2b, 0x4f, 0x92, 0x91, 0xd1, 0xa2, 0x94, 0x8f, 0xd5, 0xb9, + 0xd2, 0xf5, 0xd9, 0xec, 0x47, 0x4f, 0x27, 0x87, 0x21, 0x6d, 0x2c, 0x81, + 0x87, 0x07, 0xb5, 0x29, 0x26, 0x46, 0x7c, 0x47, 0x38, 0x97, 0x98, 0x13, + 0xa2, 0xaa, 0x47, 0x9d, 0x23, 0x3c, 0x9c, 0x2d, 0x80, 0x56, 0x10, 0xb9, + 0xbe, 0x78, 0xe8, 0x61, 0x17, 0x92, 0x8b, 0x88, 0x70, 0xf4, 0x31, 0xf0, + 0x0c, 0x07, 0xe7, 0xbd, 0x1c, 0x34, 0xe5, 0x8e, 0x8c, 0xe8, 0xd6, 0x4e, + 0x38, 0xef, 0x0b, 0x59, 0xf7, 0xc1, 0x5f, 0x0f, 0xa4, 0x21, 0x93, 0x90, + 0x27, 0x80, 0x21, 0x29, 0xe5, 0x7d, 0x12, 0xfd, 0x0e, 0x27, 0x0b, 0x42, + 0x8e, 0xcd, 0x12, 0x50, 0x96, 0x5b, 0x94, 0xa0, 0x3e, 0x29, 0xee, 0x1a, + 0x6f, 0xc5, 0x07, 0x9a, 0xef, 0xbc, 0x9e, 0x9e, 0x8b, 0x6f, 0x99, 0x96, + 0x78, 0x3b, 0x2c, 0xd2, 0xc5, 0x05, 0x91, 0x96, 0x5e, 0x39, 0x06, 0xb2, + 0x0f, 0x34, 0xa5, 0x98, 0x98, 0x67, 0xd9, 0x4e, 0x92, 0xb8, 0x46, 0xc0, + 0x7a, 0xf4, 0xf2, 0x90, 0x97, 0xcf, 0x33, 0x9e, 0x0b, 0xb7, 0xf3, 0xef, + 0xa5, 0xa5, 0xbf, 0x97, 0xf9, 0x04, 0x46, 0xea, 0x31, 0x21, 0x94, 0x61, + 0x19, 0x17, 0xd1, 0x9d, 0xe7, 0xfa, 0x3a, 0xaa, 0x52, 0x55, 0x46, 0x72, + 0x1b, 0x97, 0xd9, 0x6b, 0x5e, 0x3d, 0x15, 0x83, 0x55, 0x01, 0x95, 0x52, + 0x27, 0xd1, 0x0c, 0x41, 0x90, 0x67, 0x44, 0x7d, 0x4f, 0xd8, 0x7a, 0x3e, + 0x9f, 0xae, 0xc3, 0x00, 0x86, 0xc3, 0xc2, 0x06, 0xd8, 0x99, 0xb4, 0xfc, + 0x00, 0xbf, 0x8e, 0xa3, 0x0c, 0xf9, 0x14, 0x48, 0x2a, 0xb0, 0x5e, 0xf8, + 0xfe, 0x6b, 0x83, 0x13, 0xaa, 0x94, 0xd0, 0x62, 0x9b, 0xbb, 0xa7, 0x33, + 0x26, 0x18, 0xca, 0x60, 0x48, 0x0c, 0x5c, 0xe3, 0x13, 0x94, 0x24, 0xfe, + 0x00, 0xf3, 0x1f, 0xa2, 0x2f, 0xae, 0x49, 0x92, 0xe7, 0xf6, 0x49, 0x1e, + 0xf7, 0x57, 0x4c, 0xe5, 0x4c, 0x5f, 0x8c, 0xa3, 0xdc, 0x70, 0xbe, 0x5b, + 0x8c, 0x3c, 0xdb, 0xd3, 0x84, 0x02, 0x6e, 0xdc, 0xd5, 0x6a, 0xc9, 0xc2, + 0x5f, 0x95, 0x3a, 0x2d, 0x44, 0x87, 0x09, 0x52, 0x90, 0x41, 0x1f, 0xa8, + 0x93, 0x76, 0xae, 0x53, 0xd3, 0xef, 0x26, 0x15, 0x27, 0x38, 0x04, 0xc7, + 0xda, 0xed, 0xb1, 0x11, 0xe8, 0x2a, 0x67, 0x03, 0xd0, 0xfe, 0x5f, 0x85, + 0xfc, 0xa0, 0x6a, 0x73, 0x6e, 0xac, 0x15, 0x8d, 0xa2, 0xca, 0x5b, 0x32, + 0x52, 0xc1, 0x2e, 0xf4, 0xe6, 0x68, 0x99, 0xbd, 0xeb, 0x05, 0x4e, 0x8f, + 0xb7, 0x5c, 0xd1, 0x31, 0x5b, 0x17, 0x98, 0x81, 0xef, 0x69, 0x3d, 0x23, + 0x01, 0xc3, 0x34, 0xc7, 0x69, 0x39, 0x5e, 0xb3, 0x1e, 0x99, 0xa6, 0xbf, + 0x78, 0xee, 0x88, 0xe2, 0xdb, 0xd7, 0x4e, 0x17, 0xa0, 0x27, 0x0f, 0xe6, + 0x9f, 0x9f, 0x74, 0x0c, 0xa4, 0xd2, 0x47, 0xe3, 0xc1, 0xb5, 0xc9, 0x13, + 0xaa, 0x72, 0x22, 0xbb, 0x7d, 0xd6, 0xb8, 0x76, 0x6c, 0x5e, 0xd5, 0xf7, + 0x22, 0x69, 0x7c, 0x40, 0x4f, 0x64, 0xcd, 0x02, 0x43, 0x4a, 0x09, 0x1d, + 0x95, 0x90, 0x16, 0x3f, 0xaa, 0x4d, 0xdf, 0x5d, 0xea, 0x76, 0xb0, 0x52, + 0x92, 0xa1, 0xde, 0xd6, 0x2f, 0x66, 0x7d, 0x53, 0x65, 0xb4, 0xa6, 0x3e, + 0x0a, 0x85, 0x03, 0x56, 0x82, 0x6f, 0x17, 0xe6, 0xb6, 0xef, 0x0f, 0x4e, + 0x01, 0xc5, 0xba, 0x01, 0xdb, 0x23, 0x4c, 0x9f, 0x11, 0x59, 0x28, 0x71, + 0xc4, 0xf2, 0xeb, 0x00, 0xa9, 0x72, 0x7b, 0xd7, 0x02, 0x94, 0xd8, 0xaf, + 0xad, 0x16, 0x92, 0x51, 0xea, 0xe4, 0xb6, 0xf6, 0xe1, 0x80, 0xaf, 0x6b, + 0x0d, 0x2c, 0xbc, 0x6f, 0xb4, 0x0c, 0xa9, 0xd4, 0xf8, 0xb8, 0x19, 0xc5, + 0x69, 0x5d, 0x8f, 0xce, 0x4b, 0x98, 0x11, 0xae, 0x66, 0x19, 0x66, 0x6e, + 0xe5, 0x88, 0xc9, 0x23, 0xf5, 0xc6, 0x3d, 0x52, 0x4d, 0x5a, 0x6d, 0x5e, + 0xdc, 0x00, 0x21, 0x41, 0x53, 0xab, 0x97, 0x3d, 0xa3, 0xfb, 0xd9, 0xdf, + 0x90, 0x77, 0xeb, 0x4f, 0x8d, 0xec, 0xca, 0x17, 0xad, 0x65, 0xb9, 0x92, + 0x0c, 0x24, 0xd4, 0x80, 0x19, 0x78, 0x49, 0x7d, 0x9b, 0xcf, 0xdd, 0xaf, + 0xfd, 0xb8, 0xdd, 0x89, 0x4b, 0xe5, 0xb9, 0x99, 0x9b, 0x70, 0x24, 0xc5, + 0x86, 0x42, 0x92, 0x2c, 0x47, 0xd5, 0x1a, 0x50, 0x5d, 0x4d, 0xcf, 0xdc, + 0xb4, 0x19, 0x9a, 0xe2, 0x94, 0x5f, 0x1b, 0x19, 0x40, 0xd3, 0x5c, 0xe3, + 0x09, 0xe3, 0x7c, 0x15, 0x60, 0x49, 0xf7, 0xf9, 0xdb, 0x8e, 0x38, 0x69, + 0xfa, 0xa2, 0xe6, 0x18, 0x11, 0xc3, 0x57, 0xa0, 0xec, 0x1b, 0x43, 0x3a, + 0xb1, 0x5a, 0x6a, 0xcd, 0x5a, 0x2e, 0x59, 0x10, 0x8b, 0xc1, 0xfc, 0xbd, + 0x75, 0xc9, 0x5e, 0x5c, 0xe2, 0x28, 0xb8, 0x72, 0xbc, 0xb3, 0x8a, 0x5e, + 0x82, 0x32, 0x50, 0xa3, 0xe0, 0x77, 0xf6, 0xe0, 0x46, 0xbe, 0xda, 0x52, + 0xa5, 0x13, 0xa5, 0x99, 0xcd, 0xc3, 0x55, 0x31, 0x83, 0x10, 0x72, 0xa3, + 0x2d, 0x14, 0x49, 0xda, 0x57, 0x81, 0xd7, 0x7f, 0xbd, 0x29, 0x6d, 0xb8, + 0x21, 0xe4, 0x4b, 0x58, 0x99, 0x74, 0x84, 0xef, 0x77, 0xd6, 0x92, 0xe0, + 0x81, 0xe1, 0xc0, 0x3c, 0x10, 0x81, 0xf9, 0xa9, 0xaa, 0x63, 0x74, 0x98, + 0x91, 0xa8, 0x72, 0x16, 0xa6, 0xf3, 0xf9, 0x89, 0xe4, 0xe6, 0x48, 0xac, + 0x50, 0x65, 0x11, 0x4c, 0xef, 0xfe, 0xcf, 0x89, 0xd3, 0x9f, 0xc1, 0xfc, + 0xdc, 0xea, 0x75, 0x19, 0xc7, 0xd0, 0x12, 0xaf, 0x20, 0x64, 0x82, 0x08, + 0x8e, 0xc8, 0x0f, 0x15, 0x51, 0x7b, 0xe2, 0x6b, 0xb0, 0x1c, 0xcd, 0xad, + 0xd1, 0x77, 0x2d, 0xad, 0xa0, 0xec, 0x81, 0xa7, 0xa8, 0x28, 0xcd, 0xb1, + 0xcc, 0xa5, 0x43, 0xc4, 0x5b, 0xb8, 0x9c, 0x84, 0xa5, 0x2c, 0xac, 0xba, + 0xc0, 0x2a, 0x61, 0xc7, 0xf1, 0xb6, 0x57, 0x56, 0xe5, 0xca, 0x96, 0xbb, + 0xfb, 0x8e, 0x49, 0x3e, 0x50, 0x2f, 0x36, 0x73, 0x5b, 0x44, 0x5b, 0x36, + 0x9c, 0xa0, 0x90, 0xc6, 0x96, 0x4e, 0x73, 0x1f, 0x68, 0x47, 0x43, 0xd3, + 0x6b, 0x1f, 0x4d, 0x43, 0x1e, 0xbf, 0x1c, 0x28, 0xe9, 0xf5, 0x3d, 0xac, + 0x48, 0x4c, 0xd4, 0x6d, 0x32, 0x25, 0xf3, 0x71, 0x29, 0xe9, 0xf0, 0x08, + 0x2a, 0xd2, 0x75, 0xc1, 0xa6, 0x5f, 0x1f, 0xca, 0xbb, 0x76, 0x91, 0xdc, + 0xca, 0x13, 0x3b, 0x18, 0xd9, 0x66, 0x48, 0xb0, 0x29, 0x01, 0x39, 0xfd, + 0x35, 0x8b, 0xd7, 0xac, 0xeb, 0xe3, 0x92, 0x96, 0xef, 0xe1, 0x7e, 0xd7, + 0xd0, 0xe9, 0xd6, 0xcf, 0xd7, 0x28, 0x58, 0x0a, 0x20, 0xcc, 0xc1, 0x8a, + 0x45, 0x45, 0xe0, 0x71, 0xca, 0x66, 0x75, 0xb0, 0x97, 0x89, 0x13, 0x7b, + 0xa3, 0x27, 0x5d, 0xce, 0x36, 0x58, 0xf6, 0x0a, 0x66, 0xf5, 0x83, 0xc8, + 0xef, 0x6e, 0x6f, 0x98, 0x79, 0x52, 0xd7, 0xd4, 0xa3, 0x3f, 0xda, 0x70, + 0xe2, 0x41, 0x10, 0x55, 0x20, 0x71, 0xb0, 0xd8, 0xd9, 0x14, 0x19, 0xc6, + 0x76, 0x0d, 0x45, 0x78, 0xb5, 0x70, 0x88, 0x65, 0x5a, 0x6b, 0xeb, 0x2f, + 0x28, 0x38, 0xf9, 0xbc, 0x28, 0xbe, 0xca, 0x44, 0x86, 0x4e, 0xd4, 0x29, + 0xc6, 0x16, 0xca, 0x3e, 0xb7, 0x33, 0x58, 0x04, 0x33, 0x7c, 0xac, 0xb5, + 0x9f, 0xf9, 0xfd, 0x6d, 0xb9, 0xff, 0x5a, 0x35, 0xa6, 0xd8, 0xa5, 0x28, + 0x30, 0xf5, 0x16, 0x95, 0xa9, 0x14, 0x65, 0x97, 0x56, 0x01, 0x4d, 0xf8, + 0x71, 0xc9, 0x93, 0xad, 0xac, 0x97, 0x1d, 0xab, 0x70, 0x21, 0x2d, 0xf3, + 0x26, 0x16, 0x66, 0xcb, 0xa2, 0x67, 0x56, 0x09, 0xd9, 0x9d, 0x9c, 0xec, + 0x37, 0x4d, 0x71, 0xbd, 0xef, 0xaf, 0x22, 0x78, 0xd9, 0x4c, 0xdd, 0xab, + 0x9a, 0x12, 0x28, 0x7d, 0xb4, 0xd4, 0x9c, 0x01, 0xf2, 0x85, 0x2f, 0xbc, + 0x58, 0x77, 0x85, 0x32, 0xdf, 0x4e, 0x79, 0x41, 0x41, 0xda, 0x6e, 0x9f, + 0x60, 0x09, 0x82, 0xf4, 0x50, 0x15, 0x68, 0x0f, 0xfd, 0x0b, 0x5b, 0x09, + 0x33, 0x98, 0x9c, 0x92, 0x1d, 0xc1, 0x38, 0xbe, 0xdc, 0x17, 0xbe, 0x88, + 0xa8, 0xa6, 0x88, 0xa2, 0x0f, 0x81, 0xcd, 0xb6, 0xde, 0x42, 0xc7, 0x7d, + 0x53, 0xc6, 0xab, 0xd3, 0x94, 0x9d, 0x2e, 0x79, 0x2f, 0x0b, 0x76, 0x63, + 0x36, 0xa5, 0x85, 0x7f, 0x94, 0x07, 0x53, 0xe7, 0xa8, 0x6a, 0x0d, 0xb1, + 0xda, 0x1f, 0xad, 0xb6, 0x5b, 0x13, 0xe7, 0x21, 0xcc, 0xe7, 0x29, 0x09, + 0x48, 0x1a, 0x19, 0x7e, 0x22, 0x1b, 0x1b, 0xe5, 0xf2, 0x1a, 0x08, 0x25, + 0x30, 0xca, 0xf1, 0xd6, 0x97, 0x56, 0x3a, 0xa7, 0x3f, 0x0b, 0xce, 0xaf, + 0xfc, 0x50, 0x24, 0x34, 0xab, 0xf0, 0x9c, 0x91, 0x12, 0xc0, 0x4f, 0xd5, + 0xed, 0xa4, 0xf4, 0xe4, 0x36, 0x54, 0x49, 0xed, 0x36, 0x61, 0x6d, 0xa4, + 0x1e, 0x63, 0x24, 0x3c, 0x40, 0xb0, 0xb2, 0x44, 0xe3, 0x6d, 0xf2, 0xa6, + 0x96, 0x97, 0xe9, 0x97, 0xd4, 0x76, 0x80, 0x0c, 0x6d, 0xa8, 0xb1, 0x39, + 0x48, 0x48, 0x7c, 0x1b, 0x46, 0x9e, 0x94, 0x7a, 0xbf, 0xfd, 0xc6, 0xff, + 0x72, 0xf0, 0x4d, 0x4b, 0x22, 0x46, 0x32, 0x8e, 0x51, 0x23, 0xe7, 0xb2, + 0xe7, 0xa7, 0x05, 0x38, 0xb9, 0x25, 0xcc, 0xe2, 0xbf, 0x08, 0xff, 0x77, + 0xf9, 0xb6, 0x37, 0xcd, 0x29, 0x47, 0xc3, 0x10, 0xe4, 0xc9, 0xd5, 0xaa, + 0x41, 0xe8, 0x6c, 0x6d, 0x17, 0xa2, 0x8a, 0x08, 0xcc, 0xde, 0xa3, 0xcb, + 0xeb, 0x66, 0x86, 0x2c, 0x0b, 0xd3, 0xeb, 0xb3, 0x4b, 0x9e, 0x64, 0x70, + 0xf3, 0xa2, 0x8e, 0x30, 0x14, 0x32, 0x09, 0xea, 0xbd, 0x57, 0x4b, 0x6b, + 0x1e, 0xa3, 0x12, 0x01, 0xc2, 0x46, 0x65, 0x23, 0xe9, 0xac, 0x21, 0xb2, + 0xba, 0x60, 0xef, 0x6e, 0xa8, 0x32, 0x16, 0x1b, 0x69, 0x41, 0x23, 0x93, + 0xfb, 0x48, 0x7a, 0xb3, 0xe2, 0xab, 0x9b, 0x1a, 0x44, 0xce, 0x8a, 0x35, + 0xfc, 0x87, 0x3e, 0xe4, 0xa5, 0xec, 0xcf, 0x98, 0x04, 0x32, 0xc2, 0x32, + 0x4b, 0x48, 0x96, 0xed, 0x6a, 0xd1, 0xca, 0x3a, 0xf0, 0xb9, 0x32, 0x14, + 0xe3, 0x11, 0x23, 0x87, 0x09, 0x49, 0x59, 0x20, 0x6b, 0x3a, 0xb7, 0xc5, + 0xa7, 0xb3, 0x86, 0xd1, 0x87, 0x0d, 0xcf, 0x04, 0x92, 0x2a, 0x87, 0xa4, + 0x36, 0xc9, 0x03, 0x3f, 0x05, 0x2f, 0x39, 0xad, 0xfb, 0xbb, 0x25, 0x0c, + 0xbe, 0x23, 0xe4, 0x18, 0x1c, 0x24, 0x71, 0xd1, 0x6c, 0xba, 0x6a, 0xba, + 0xa6, 0xa7, 0x93, 0x08, 0x43, 0x92, 0x13, 0xfa, 0x02, 0xe0, 0x0e, 0xf6, + 0x26, 0x20, 0x11, 0x5c, 0x4f, 0x54, 0xc0, 0xb2, 0x0b, 0x5e, 0x79, 0x41, + 0xd9, 0x03, 0xd8, 0x4f, 0xb4, 0x60, 0xf7, 0x2c, 0xbd, 0xd8, 0xcd, 0xdd, + 0x19, 0xee, 0x46, 0x5f, 0x44, 0x2b, 0x57, 0x3f, 0xe3, 0x6b, 0x41, 0x4b, + 0x63, 0x19, 0x2b, 0x69, 0xb3, 0xe4, 0x14, 0xe0, 0xfc, 0x70, 0x6f, 0xc5, + 0x9e, 0xe2, 0x56, 0xfe, 0x62, 0xc7, 0x2b, 0x68, 0x43, 0x34, 0xb0, 0xf8, + 0x71, 0xd9, 0x0e, 0xbd, 0x20, 0x29, 0x83, 0xf1, 0xfe, 0xed, 0xec, 0xd5, + 0xeb, 0x12, 0xc9, 0x13, 0x9d, 0x1f, 0xb4, 0xce, 0x39, 0xd8, 0x15, 0xa9, + 0x6c, 0x24, 0x8d, 0x6f, 0xc5, 0x0a, 0x0c, 0xa2, 0x7e, 0x29, 0x67, 0xf1, + 0x3a, 0xf8, 0xd6, 0xd0, 0x3b, 0x28, 0x30, 0x94, 0x0c, 0x28, 0x77, 0x06, + 0x79, 0x3f, 0xfc, 0x67, 0xf2, 0x76, 0x8b, 0xb5, 0xc0, 0x4a, 0x1a, 0x79, + 0x9c, 0x04, 0xef, 0xc1, 0x61, 0x0e, 0xe9, 0xe0, 0xf3, 0x4a, 0x03, 0x00, + 0xf1, 0x4a, 0xa6, 0x66, 0x51, 0x53, 0x76, 0x35, 0x72, 0xc7, 0x59, 0x4b, + 0x34, 0x34, 0xc9, 0x1d, 0x91, 0x21, 0x1a, 0x5f, 0xb6, 0x81, 0x9e, 0x7a, + 0x62, 0x4a, 0xb8, 0x54, 0xb7, 0xdf, 0xe7, 0xd7, 0xb0, 0x5f, 0xa8, 0x1c, + 0x93, 0xae, 0x94, 0x3d, 0x82, 0x83, 0xe7, 0x9c, 0x50, 0x79, 0xa5, 0x03, + 0xf2, 0x3f, 0x19, 0xd7, 0x3f, 0x5f, 0x33, 0xf1, 0x5b, 0x65, 0x03, 0x4d, + 0x40, 0x88, 0x66, 0x67, 0x3f, 0x16, 0x8e, 0x7c, 0x4f, 0xd6, 0x15, 0xb3, + 0x1d, 0xed, 0x86, 0xc7, 0x2b, 0x82, 0x4e, 0x4e, 0xc1, 0x9b, 0x25, 0xc1, + 0xf5, 0x3f, 0x6e, 0xde, 0xbd, 0x23, 0x44, 0xa1, 0xb4, 0x84, 0xfb, 0x0a, + 0x95, 0x59, 0x57, 0x60, 0x73, 0x54, 0xcf, 0x4d, 0x2d, 0x5d, 0x8d, 0xc3, + 0xc8, 0x2a, 0x98, 0x7d, 0xb2, 0x59, 0x94, 0xe6, 0x90, 0x43, 0xed, 0xa2, + 0xc2, 0x13, 0x33, 0xf5, 0xee, 0x21, 0x72, 0x82, 0xaa, 0x33, 0xfc, 0x92, + 0x15, 0xc1, 0xf6, 0xef, 0x7d, 0xdf, 0x25, 0x8a, 0xbe, 0x36, 0xe8, 0x69, + 0x91, 0x42, 0x93, 0x4f, 0x1d, 0xc4, 0x92, 0xa5, 0xf3, 0xc1, 0x5d, 0x3d, + 0x1b, 0x36, 0xd7, 0xc4, 0x35, 0x7d, 0xe5, 0x02, 0x5b, 0xca, 0x8f, 0xcc, + 0x0c, 0x86, 0x7b, 0x20, 0xbc, 0xc2, 0xc1, 0x6f, 0x5a, 0x7c, 0xfe, 0x66, + 0x6d, 0xeb, 0x5e, 0xa5, 0xba, 0xbe, 0x26, 0xd3, 0xda, 0xe8, 0x51, 0x26, + 0x57, 0xac, 0xcf, 0x3f, 0x86, 0x1d, 0x38, 0x71, 0xa4, 0x35, 0x70, 0xe9, + 0x50, 0x02, 0x72, 0xc2, 0x22, 0x79, 0x78, 0xeb, 0x7d, 0xcf, 0xc7, 0x87, + 0xbc, 0x7e, 0xc7, 0x1c, 0x8d, 0x13, 0x44, 0xf3, 0xd0, 0x8a, 0x25, 0xf6, + 0xf7, 0x3c, 0xd9, 0x6f, 0xf2, 0x37, 0x9e, 0xad, 0x33, 0x43, 0x86, 0x40, + 0x4e, 0x90, 0x92, 0x33, 0x8c, 0x49, 0x90, 0x26, 0xf5, 0x25, 0x7d, 0xfe, + 0xf7, 0x16, 0x7e, 0x57, 0xef, 0xde, 0x6f, 0x2f, 0x93, 0xbe, 0x57, 0xda, + 0xae, 0x04, 0x35, 0x40, 0xcc, 0x4d, 0x72, 0x03, 0x2b, 0xb8, 0x1a, 0xfb, + 0xda, 0x1b, 0xb6, 0xff, 0x86, 0x6b, 0x76, 0xa6, 0xee, 0x71, 0xdd, 0xe8, + 0x10, 0xd8, 0x00, 0x94, 0x00, 0xa4, 0x6b, 0x00, 0x46, 0xd3, 0x8d, 0x16, + 0x64, 0x4c, 0x21, 0xd5, 0xc0, 0xca, 0x64, 0x44, 0xd2, 0xe6, 0xee, 0x4f, + 0xc4, 0xfa, 0x35, 0x45, 0x64, 0xc5, 0x51, 0xa8, 0x7c, 0x14, 0x77, 0xeb, + 0x97, 0x87, 0x0b, 0xae, 0x1d, 0x9c, 0x6e, 0x0d, 0xba, 0xb8, 0xa8, 0x8c, + 0xc8, 0x97, 0xd7, 0xb5, 0x43, 0xf3, 0x6b, 0x2d, 0x86, 0xdd, 0x01, 0xf6, + 0x07, 0xde, 0x7d, 0x7f, 0xb7, 0x3c, 0xe2, 0x30, 0x6b, 0x98, 0x99, 0xce, + 0xa6, 0xcb, 0x18, 0xa4, 0xa7, 0x3b, 0xc9, 0x62, 0xb9, 0x61, 0x3c, 0x87, + 0xe0, 0x7f, 0x85, 0x0f, 0xda, 0x1f, 0x83, 0x76, 0x6e, 0x9c, 0x53, 0x95, + 0x0c, 0x75, 0xe3, 0xc2, 0x90, 0x91, 0x96, 0x54, 0x87, 0x70, 0xcf, 0xb6, + 0x84, 0xe2, 0xbe, 0x31, 0xe5, 0x4a, 0x79, 0x00, 0x4a, 0x25, 0x06, 0x54, + 0x19, 0x39, 0x4d, 0x14, 0x28, 0xfd, 0x71, 0x91, 0xa2, 0x69, 0xee, 0x2b, + 0xa2, 0x88, 0x97, 0x37, 0x4f, 0x3e, 0xfa, 0xb7, 0x2a, 0x41, 0x55, 0x10, + 0xdf, 0xc4, 0x24, 0xfc, 0xde, 0xa9, 0x45, 0x74, 0xb5, 0xb9, 0xee, 0xef, + 0xd7, 0xb3, 0x8d, 0xc3, 0x41, 0x0c, 0xe8, 0x23, 0x5e, 0x41, 0x29, 0x83, + 0x23, 0x90, 0xc9, 0xf1, 0x54, 0x0e, 0xb8, 0xbf, 0x95, 0x5a, 0x28, 0x2c, + 0x5d, 0xd2, 0xd6, 0x50, 0x60, 0x5b, 0x1d, 0xbe, 0x64, 0x4d, 0x10, 0x28, + 0x92, 0x87, 0x88, 0x7d, 0x3f, 0x8d, 0xaf, 0xfc, 0x0f, 0x0c, 0x00, 0xa3, + 0x29, 0xd2, 0x10, 0x8b, 0xd9, 0x14, 0xb8, 0x3b, 0x81, 0x76, 0x64, 0xc2, + 0x97, 0xbe, 0x6f, 0x92, 0x61, 0x8b, 0xb7, 0x05, 0xbd, 0x3e, 0x6d, 0x54, + 0x50, 0x0c, 0x87, 0x95, 0x97, 0xf4, 0x49, 0x2d, 0x06, 0xac, 0xb8, 0xa9, + 0x31, 0xd3, 0x76, 0x92, 0x4a, 0xa3, 0xd9, 0x1f, 0xf4, 0x08, 0xd9, 0x29, + 0x49, 0xa9, 0xe3, 0x65, 0xee, 0x68, 0x60, 0x12, 0x97, 0xcc, 0xfc, 0xe1, + 0x5d, 0x26, 0xcc, 0xbe, 0xa8, 0x4e, 0xdd, 0x9a, 0x28, 0x21, 0xc3, 0x41, + 0x2f, 0x8a, 0x4e, 0x60, 0xb7, 0x03, 0x8c, 0x1f, 0x6f, 0x05, 0x5e, 0x99, + 0x73, 0x33, 0x43, 0xd2, 0xe7, 0x22, 0x75, 0xbc, 0x98, 0xe0, 0x34, 0x7e, + 0x2c, 0xb0, 0x0f, 0xa9, 0xee, 0xbc, 0x82, 0xa8, 0x1d, 0xa0, 0xd0, 0x95, + 0x5e, 0xa1, 0x33, 0x95, 0xf4, 0xdb, 0xe0, 0xf5, 0x3c, 0x1c, 0xa4, 0x5e, + 0x12, 0x08, 0x40, 0x7c, 0xc6, 0x12, 0x22, 0xb3, 0x6d, 0x81, 0xa2, 0x88, + 0xac, 0x97, 0x6f, 0x2a, 0xc9, 0xd6, 0xde, 0x6b, 0xb6, 0x02, 0x58, 0x18, + 0x40, 0xc7, 0x92, 0x06, 0x63, 0x26, 0x11, 0x98, 0xf1, 0x05, 0x50, 0x73, + 0x37, 0x4c, 0xcf, 0x8e, 0x77, 0xe6, 0x0f, 0x6e, 0x4f, 0x36, 0x5e, 0x7a, + 0x94, 0xd1, 0x13, 0xa5, 0xb1, 0x22, 0x0c, 0x20, 0xa1, 0x97, 0x8c, 0x7e, + 0xcb, 0xf9, 0xfa, 0x17, 0x4a, 0x4a, 0x40, 0x5e, 0xef, 0xe6, 0x48, 0x6c, + 0x3b, 0x18, 0xca, 0x2c, 0x67, 0x91, 0x09, 0x85, 0x6a, 0xcd, 0xdd, 0xdb, + 0xdb, 0x82, 0x07, 0xa7, 0x57, 0xa2, 0x42, 0x84, 0xf8, 0xe7, 0xd2, 0xbe, + 0x8b, 0x80, 0xe4, 0xda, 0x07, 0x4e, 0xcc, 0x11, 0xc9, 0xf6, 0x5f, 0x5e, + 0x22, 0xcd, 0xf3, 0x82, 0xa9, 0x6d, 0x7a, 0xc4, 0x26, 0x70, 0xec, 0x1d, + 0x6a, 0x79, 0x7f, 0x37, 0x28, 0x88, 0x1a, 0x53, 0x84, 0xf8, 0x00, 0xad, + 0x47, 0x7b, 0xfe, 0x19, 0xc9, 0xac, 0xab, 0x55, 0x76, 0xde, 0x4b, 0x6d, + 0x6f, 0x2e, 0x77, 0xca, 0xd7, 0x4e, 0x73, 0x18, 0xcd, 0xc3, 0x41, 0xac, + 0x39, 0x9a, 0x22, 0xac, 0xbf, 0xd2, 0xc0, 0xec, 0x4c, 0x54, 0xfb, 0xb9, + 0x76, 0x39, 0xd4, 0xcf, 0x63, 0xd6, 0xd6, 0x3c, 0xfe, 0x6f, 0xc0, 0x22, + 0xc0, 0x14, 0x36, 0xb8, 0x02, 0x19, 0x1e, 0x6a, 0x8b, 0xa3, 0x39, 0x78, + 0x1a, 0x82, 0x9e, 0x78, 0xf6, 0x58, 0xdb, 0x2e, 0x0a, 0x70, 0xc3, 0xa7, + 0x45, 0x41, 0x19, 0x8d, 0xca, 0x91, 0xed, 0x28, 0x12, 0x8c, 0xbb, 0x91, + 0xbd, 0xb3, 0xf0, 0x6a, 0xff, 0x79, 0x7f, 0xdf, 0xbc, 0x03, 0x6c, 0x4f, + 0x05, 0xe1, 0xaf, 0x39, 0x14, 0x37, 0x08, 0xbd, 0xd8, 0xa5, 0x3a, 0x0d, + 0xe2, 0x65, 0xdd, 0x9f, 0x80, 0x0c, 0xca, 0xd2, 0x19, 0x36, 0x1d, 0x84, + 0xfa, 0xa0, 0xa7, 0xb3, 0x26, 0x14, 0x4e, 0x53, 0xb5, 0x98, 0x15, 0x7b, + 0x53, 0x55, 0xc7, 0x55, 0x59, 0x65, 0xf7, 0xf9, 0xb5, 0x6b, 0x96, 0x59, + 0x7d, 0xb6, 0xf2, 0xab, 0x6f, 0x4e, 0x48, 0xa1, 0x30, 0x18, 0x01, 0x2a, + 0x3e, 0x20, 0x3a, 0xc6, 0x6d, 0x2a, 0x23, 0x0d, 0x17, 0x3d, 0x66, 0x30, + 0xe5, 0xe5, 0xac, 0x86, 0x84, 0x08, 0x01, 0x7a, 0xcc, 0xed, 0xf9, 0xfa, + 0x83, 0xcf, 0x09, 0x95, 0xdf, 0xf8, 0xed, 0x8c, 0x12, 0x7d, 0xf0, 0xcc, + 0x3e, 0x35, 0xfe, 0x10, 0x50, 0xed, 0x35, 0xcc, 0x8a, 0x13, 0x18, 0x67, + 0x22, 0x79, 0x04, 0xd8, 0x43, 0xd2, 0x38, 0xb3, 0xe8, 0x4c, 0x57, 0x6b, + 0xab, 0xfa, 0x95, 0x4e, 0x2c, 0x5e, 0x14, 0x0e, 0x7e, 0x06, 0xd6, 0x7d, + 0xcd, 0xe9, 0xb7, 0xbb, 0x8b, 0x76, 0x35, 0xe5, 0xf1, 0x87, 0x6c, 0x92, + 0x2c, 0x44, 0x8e, 0x59, 0xa3, 0x84, 0x27, 0x55, 0xaa, 0xe7, 0x8a, 0xda, + 0x3a, 0x08, 0xa3, 0x3c, 0x94, 0x69, 0x07, 0x98, 0xf9, 0x33, 0x0a, 0xe8, + 0xfe, 0xfd, 0x7e, 0x55, 0x0c, 0x5b, 0x81, 0xba, 0x56, 0xb4, 0x86, 0xd9, + 0xca, 0x80, 0xc8, 0x12, 0xe8, 0x83, 0x8d, 0x51, 0x04, 0xb9, 0xcf, 0xe8, + 0x0f, 0x34, 0x97, 0xe7, 0x3b, 0xab, 0xaf, 0x85, 0x7f, 0x6f, 0x38, 0x1e, + 0x7b, 0xd8, 0x54, 0x31, 0xa7, 0x82, 0x4f, 0x2c, 0xa0, 0xff, 0x18, 0x73, + 0x8f, 0xbc, 0x57, 0xfe, 0x8f, 0x7f, 0xe5, 0x34, 0xfa, 0x16, 0x59, 0xa5, + 0x36, 0x3c, 0x01, 0x22, 0x89, 0x33, 0x99, 0x73, 0x93, 0xf1, 0x6b, 0x99, + 0xe3, 0xaa, 0xab, 0xf0, 0x37, 0x21, 0x09, 0xb2, 0x5d, 0x5a, 0x61, 0x89, + 0xb9, 0x62, 0xaf, 0x90, 0x3f, 0x8a, 0x42, 0x9d, 0x6b, 0x41, 0x86, 0x00, + 0x51, 0x78, 0x28, 0x41, 0x37, 0x35, 0x84, 0x73, 0xc6, 0x1e, 0x42, 0x52, + 0x91, 0x4a, 0x93, 0xce, 0x78, 0x0a, 0x08, 0x51, 0xec, 0x92, 0x15, 0x48, + 0x58, 0xe4, 0x94, 0x48, 0xbb, 0x8b, 0xd7, 0xf6, 0x5b, 0xac, 0x69, 0x5f, + 0x9a, 0x9d, 0x6c, 0xd9, 0x8e, 0xef, 0xb0, 0x71, 0xf8, 0x1a, 0xc4, 0xa8, + 0x90, 0x93, 0xec, 0x1a, 0x66, 0xbd, 0x29, 0x0f, 0xa9, 0xce, 0xf1, 0x65, + 0xb2, 0xc7, 0xb4, 0x4a, 0x92, 0x3d, 0x94, 0xcb, 0xae, 0x15, 0xc8, 0x99, + 0x44, 0x6d, 0x82, 0x00, 0x89, 0x20, 0x96, 0x97, 0x38, 0xd0, 0x5b, 0x8e, + 0xfa, 0x6d, 0x6a, 0x40, 0xa0, 0x72, 0xb2, 0x92, 0x27, 0xb5, 0xbc, 0x34, + 0x50, 0xfa, 0x5f, 0x1a, 0xfa, 0xe5, 0xdd, 0x75, 0x76, 0xb7, 0x7c, 0x19, + 0xbb, 0xe2, 0x89, 0x31, 0xab, 0xc9, 0x59, 0x72, 0x19, 0x7f, 0x3e, 0x60, + 0x9c, 0x8d, 0x4d, 0xdf, 0x90, 0xea, 0xcb, 0x65, 0xca, 0x03, 0x96, 0x59, + 0x22, 0x32, 0x8c, 0xfc, 0x0c, 0x97, 0x1f, 0x39, 0x75, 0xff, 0xd1, 0x79, + 0x9b, 0xce, 0x89, 0xd2, 0xe5, 0x8d, 0x04, 0xf0, 0xe2, 0x59, 0x48, 0xd0, + 0xf9, 0xc3, 0xbe, 0xee, 0x58, 0x06, 0xb7, 0xe6, 0xd1, 0x80, 0x6b, 0x13, + 0xb4, 0x41, 0x11, 0x06, 0x51, 0x8c, 0x66, 0xf9, 0x7e, 0x34, 0x07, 0xc1, + 0x4f, 0xfe, 0x9b, 0x31, 0xdf, 0x1e, 0x62, 0x44, 0xe7, 0x26, 0xc6, 0xa2, + 0x28, 0x25, 0x22, 0x28, 0xf8, 0x8d, 0xad, 0x27, 0x0b, 0xc7, 0x78, 0x01, + 0x82, 0x8c, 0x15, 0xe7, 0x96, 0x55, 0x1c, 0x63, 0xf1, 0xcc, 0x5d, 0xba, + 0x89, 0xbf, 0x1a, 0xd9, 0x98, 0xaf, 0xa1, 0x87, 0x6c, 0x8c, 0x86, 0xf4, + 0x4f, 0xc7, 0xf3, 0x13, 0x7c, 0x94, 0x5d, 0x95, 0x46, 0xbf, 0xad, 0x0d, + 0x9d, 0x3c, 0xe8, 0x12, 0x88, 0x99, 0x92, 0x5a, 0x15, 0x62, 0x50, 0xdb, + 0x67, 0x7a, 0xf3, 0x53, 0x6d, 0x5a, 0xd2, 0x12, 0x2f, 0x2e, 0xd0, 0x50, + 0x22, 0x8c, 0x3f, 0x3b, 0x45, 0x54, 0x5c, 0x54, 0x35, 0xe7, 0xb3, 0x78, + 0xf5, 0x10, 0x53, 0x38, 0xd8, 0xa1, 0x5f, 0x28, 0xe4, 0xc1, 0xf0, 0x66, + 0x54, 0x56, 0xdb, 0xed, 0xff, 0xd3, 0x60, 0x08, 0x41, 0xb5, 0xa0, 0x41, + 0x8c, 0x51, 0x96, 0x60, 0x0e, 0x3a, 0x5a, 0xf0, 0x13, 0xbc, 0x49, 0xd5, + 0xf9, 0xd7, 0xcf, 0xcc, 0x04, 0x20, 0x97, 0x64, 0x1a, 0xe6, 0x36, 0x03, + 0xa1, 0x4b, 0xaf, 0x34, 0x1d, 0x06, 0x31, 0x80, 0x8c, 0x0a, 0x5c, 0xf0, + 0x93, 0x03, 0xde, 0xb3, 0xd9, 0xca, 0xda, 0x9e, 0xd8, 0x99, 0xce, 0x9b, + 0xef, 0x72, 0x29, 0x72, 0x79, 0xfc, 0x5f, 0x01, 0xd7, 0x36, 0x93, 0x03, + 0xda, 0xcf, 0xd3, 0x2f, 0xa0, 0xad, 0xb4, 0x3f, 0xc7, 0x30, 0x92, 0xf0, + 0x3b, 0x49, 0x5d, 0xa2, 0x5c, 0xd2, 0x39, 0x45, 0x2f, 0xe8, 0xad, 0xfc, + 0xa6, 0x3f, 0xed, 0x61, 0x3d, 0x0a, 0x24, 0x1c, 0x02, 0x78, 0x41, 0xda, + 0xff, 0x02, 0xaa, 0xcf, 0xb1, 0xf3, 0xa3, 0xae, 0x72, 0xff, 0xe2, 0x83, + 0xfa, 0x92, 0xf6, 0xe3, 0x45, 0x8a, 0xcb, 0x10, 0x74, 0x19, 0xdc, 0x97, + 0x8d, 0x02, 0x75, 0x17, 0x0b, 0x05, 0x2f, 0x59, 0x62, 0x48, 0x61, 0xca, + 0x18, 0x07, 0x65, 0x11, 0x8e, 0x63, 0xde, 0xd2, 0xaf, 0xb6, 0x66, 0xaf, + 0xd1, 0x1f, 0xaf, 0x63, 0xe4, 0xc3, 0x50, 0xf1, 0xd0, 0x04, 0xc6, 0x3b, + 0x66, 0xc9, 0xd6, 0x25, 0xe2, 0xe7, 0xfa, 0xdf, 0xca, 0x26, 0xde, 0x2f, + 0xdc, 0xf9, 0x33, 0x13, 0x72, 0xa8, 0x9e, 0x6c, 0x18, 0x09, 0xc1, 0x39, + 0x1a, 0x6e, 0x81, 0x80, 0x4f, 0x2c, 0xde, 0xb3, 0xae, 0xf2, 0xf6, 0xbe, + 0xa5, 0xed, 0x7d, 0x66, 0xac, 0xd0, 0x63, 0xba, 0x74, 0x9a, 0x4e, 0xe7, + 0x18, 0x71, 0x4d, 0xf0, 0xfb, 0x72, 0x49, 0x13, 0x72, 0x6b, 0x00, 0xf3, + 0x6e, 0xc8, 0x76, 0x3a, 0xf2, 0xba, 0x5b, 0xf8, 0xd8, 0x70, 0x8a, 0x1a, + 0x16, 0x7e, 0x43, 0x41, 0xde, 0x02, 0x50, 0x23, 0x70, 0xa5, 0x90, 0x2b, + 0x22, 0x97, 0xc1, 0xf2, 0xb9, 0xe9, 0xa9, 0x43, 0xb0, 0x43, 0xf9, 0x37, + 0x8c, 0x6a, 0x86, 0x49, 0x13, 0xca, 0x03, 0xc1, 0x32, 0x68, 0x1d, 0xd3, + 0x2e, 0x9b, 0x6f, 0x51, 0xb8, 0x46, 0x19, 0x51, 0x34, 0x64, 0xd0, 0x62, + 0x23, 0xf1, 0x7c, 0x46, 0x60, 0xdf, 0xca, 0xd6, 0x6a, 0xf3, 0x9e, 0x20, + 0x00, 0xd1, 0x94, 0xa8, 0x04, 0xb0, 0xf0, 0x41, 0xf3, 0xd6, 0xad, 0xb3, + 0x8a, 0x30, 0xb3, 0x4a, 0x53, 0x11, 0x8d, 0x1b, 0xd0, 0x0f, 0xc5, 0x97, + 0xd0, 0x20, 0x4f, 0x4b, 0x36, 0xe2, 0x06, 0x14, 0xd9, 0xa0, 0x18, 0x78, + 0x05, 0x02, 0x23, 0x09, 0xcf, 0xe3, 0xfa, 0x0a, 0x66, 0x71, 0xf6, 0xe0, + 0xf1, 0xc0, 0xc5, 0xa0, 0xa7, 0xff, 0xb5, 0xca, 0x89, 0x2d, 0x3c, 0x67, + 0x3f, 0x37, 0x80, 0xce, 0x59, 0x5f, 0x3f, 0xa8, 0x4b, 0xa6, 0xcd, 0x0a, + 0x65, 0x1a, 0x25, 0x13, 0x18, 0x5e, 0xb2, 0x7b, 0x9f, 0x35, 0xc6, 0xc6, + 0x45, 0x7b, 0x3b, 0x32, 0x8c, 0x04, 0xcc, 0x85, 0xe8, 0x68, 0xd2, 0x62, + 0xed, 0xe7, 0x57, 0x18, 0xad, 0xda, 0xe1, 0xd9, 0x89, 0x09, 0x1f, 0x06, + 0x79, 0x5e, 0x82, 0xcd, 0x80, 0x61, 0xb1, 0x0b, 0x8a, 0x24, 0x09, 0xc1, + 0xe9, 0x4a, 0xac, 0x8d, 0xe7, 0x55, 0xcc, 0x55, 0x07, 0x7d, 0xdb, 0xbd, + 0x8b, 0x29, 0x4e, 0x78, 0xfb, 0x46, 0x64, 0x94, 0xaf, 0xa1, 0x19, 0x6f, + 0xcd, 0xbe, 0x72, 0x60, 0xe3, 0x55, 0xe1, 0xa5, 0x61, 0x83, 0xbb, 0xce, + 0x8c, 0x62, 0xe3, 0x2e, 0x84, 0x1f, 0x3c, 0xdc, 0x03, 0xf4, 0x41, 0xab, + 0x68, 0x63, 0xe3, 0x94, 0x8e, 0x1c, 0xe4, 0x80, 0xc6, 0xfb, 0x10, 0xb9, + 0xaf, 0xee, 0xcd, 0xfe, 0xfa, 0x9c, 0x18, 0xd8, 0xbc, 0xd6, 0xe0, 0xa8, + 0xe1, 0xfe, 0x78, 0x82, 0x0e, 0xd7, 0x0e, 0x80, 0xc9, 0x1f, 0x11, 0x5e, + 0x57, 0x35, 0x41, 0xdb, 0x6c, 0x39, 0xdb, 0xda, 0xfc, 0xb3, 0x12, 0x26, + 0x05, 0x9a, 0x01, 0xd4, 0x86, 0x4e, 0x60, 0x6a, 0x69, 0x72, 0xf1, 0x15, + 0x9f, 0x63, 0xaf, 0x9b, 0xe7, 0x1c, 0xbc, 0x33, 0xde, 0x3b, 0x6a, 0x74, + 0x8a, 0x9e, 0x74, 0x5c, 0xa0, 0x64, 0xc3, 0x01, 0xf1, 0x04, 0xef, 0xaf, + 0x45, 0x52, 0x5b, 0xed, 0xb2, 0xf8, 0x80, 0xb9, 0xc6, 0x04, 0x40, 0x1e, + 0x0b, 0xd0, 0x0f, 0xcf, 0x73, 0x2a, 0x65, 0xd2, 0xee, 0xcc, 0xdb, 0xe6, + 0xe8, 0x84, 0xff, 0xda, 0xb1, 0x25, 0x3a, 0x14, 0x94, 0x67, 0x0e, 0x03, + 0xdc, 0x93, 0xfe, 0x50, 0x19, 0x60, 0x61, 0xa5, 0xf3, 0xd2, 0x2d, 0x8e, + 0x6b, 0xa2, 0xc5, 0x63, 0xa9, 0x99, 0x8e, 0xe7, 0x21, 0x5e, 0x08, 0x4c, + 0xe5, 0x22, 0x66, 0x88, 0xc0, 0x7c, 0x0e, 0x5d, 0x97, 0xb2, 0x15, 0x30, + 0xd5, 0xee, 0xd4, 0x25, 0x22, 0x82, 0x28, 0x64, 0xc9, 0x96, 0x12, 0x46, + 0x53, 0xcb, 0xa1, 0xb7, 0x38, 0xe2, 0x8e, 0x52, 0x5a, 0x03, 0x1e, 0xf4, + 0x4a, 0xb2, 0x8e, 0x77, 0xfa, 0x6b, 0xe6, 0x8c, 0x12, 0xc3, 0x4d, 0x12, + 0x87, 0xc1, 0x78, 0x29, 0xfa, 0x86, 0xd9, 0xe0, 0xbc, 0x10, 0x87, 0xc6, + 0x42, 0x13, 0x8d, 0x19, 0x0f, 0x02, 0x4f, 0x56, 0xac, 0xb3, 0xce, 0x6a, + 0x84, 0xb9, 0x39, 0x59, 0x26, 0x23, 0xe0, 0xcf, 0x72, 0x2e, 0xb9, 0xa2, + 0xda, 0x32, 0x18, 0x77, 0x12, 0xc9, 0xc1, 0x95, 0x80, 0x93, 0x93, 0xac, + 0x2d, 0xdf, 0x4c, 0xc2, 0x53, 0x0d, 0xa3, 0x2c, 0xac, 0x3e, 0xfe, 0x72, + 0xdb, 0xf6, 0x20, 0x80, 0x21, 0xbd, 0x98, 0x71, 0x5d, 0x21, 0xf3, 0x45, + 0x64, 0x71, 0x0b, 0xb0, 0x33, 0x40, 0xa3, 0x33, 0x57, 0xe5, 0x96, 0x87, + 0xc4, 0xec, 0x80, 0x90, 0x1d, 0xfb, 0x31, 0x73, 0x5d, 0x7f, 0x70, 0xb3, + 0x61, 0xa4, 0x8b, 0x3c, 0xc8, 0x44, 0x4d, 0x09, 0xb2, 0x32, 0x74, 0x3e, + 0xa0, 0xaf, 0xd7, 0x66, 0xe8, 0xd0, 0xb1, 0xc3, 0xa8, 0x81, 0xbc, 0x70, + 0xe8, 0x6e, 0x68, 0x89, 0x14, 0xaf, 0x8f, 0x4b, 0x60, 0xae, 0x6a, 0xcd, + 0xa8, 0xbc, 0xd7, 0xbd, 0x35, 0x15, 0xbc, 0xcb, 0x9c, 0x84, 0x27, 0x86, + 0x69, 0xe5, 0x09, 0x21, 0xf6, 0xa4, 0xd9, 0xaf, 0x33, 0x48, 0x84, 0x93, + 0x91, 0x24, 0x96, 0xe5, 0x4c, 0x78, 0xee, 0xec, 0x79, 0x5b, 0x0a, 0x3c, + 0xa8, 0x62, 0xe9, 0xa9, 0x68, 0x21, 0x2c, 0x6a, 0x48, 0x4a, 0x17, 0x19, + 0x60, 0x65, 0xa5, 0x0c, 0x97, 0xd4, 0xc9, 0xde, 0x56, 0xe9, 0xf0, 0xf7, + 0x56, 0x57, 0x6c, 0x8e, 0x3e, 0xf6, 0x52, 0xe1, 0x86, 0x42, 0x80, 0x01, + 0x80, 0xa1, 0x28, 0x64, 0x32, 0x8f, 0x80, 0xf3, 0x7d, 0xa2, 0x97, 0x84, + 0x82, 0xe7, 0x91, 0x41, 0x92, 0x08, 0xe6, 0x02, 0x69, 0x37, 0xfe, 0xcd, + 0xa2, 0x85, 0xfa, 0xb7, 0x64, 0xab, 0x78, 0x95, 0xb4, 0x85, 0x44, 0x28, + 0xa5, 0xe5, 0xb8, 0xc0, 0x11, 0xac, 0x21, 0x5a, 0xd3, 0x98, 0x5e, 0x8a, + 0x08, 0x60, 0x14, 0x0d, 0x53, 0xde, 0xce, 0x06, 0xd4, 0x37, 0xb1, 0x22, + 0xe2, 0x68, 0x34, 0xc7, 0xc5, 0xa3, 0xf5, 0x1b, 0xce, 0xed, 0x45, 0x24, + 0xd9, 0x4a, 0x08, 0xdd, 0x65, 0x07, 0x8b, 0xbf, 0x81, 0xda, 0x3b, 0x31, + 0xdc, 0xb1, 0x7b, 0x3d, 0x8a, 0xb4, 0x74, 0x6e, 0xc8, 0xd4, 0x46, 0xd9, + 0xb6, 0x97, 0x45, 0x3b, 0xa0, 0x24, 0x88, 0xc3, 0xc4, 0x1d, 0x58, 0xa5, + 0xa7, 0xf0, 0x7c, 0xae, 0xd6, 0x77, 0x47, 0x7c, 0xe2, 0xb0, 0x18, 0xef, + 0x2c, 0x35, 0x82, 0x8c, 0x89, 0x93, 0x76, 0x40, 0x52, 0xbc, 0xf1, 0xf9, + 0x7f, 0x77, 0x03, 0x74, 0xdc, 0x12, 0xfd, 0x74, 0x2e, 0x16, 0xe6, 0x19, + 0xd5, 0xe0, 0x8b, 0x06, 0x4b, 0x99, 0x1f, 0x68, 0x3c, 0xd1, 0xbe, 0xe8, + 0x9c, 0xf7, 0xb5, 0x9d, 0x17, 0x1f, 0xaf, 0x47, 0xc5, 0x38, 0x92, 0x2c, + 0x1b, 0x54, 0x6f, 0x2b, 0x1d, 0x09, 0xeb, 0x4d, 0x89, 0x8e, 0x32, 0xe7, + 0x59, 0x84, 0x91, 0xfd, 0x57, 0xd9, 0x79, 0x4f, 0x8a, 0xdb, 0xc3, 0x3a, + 0x09, 0xe0, 0x07, 0x36, 0xdd, 0x93, 0x94, 0x1e, 0x69, 0x6b, 0xe1, 0x31, + 0xae, 0x72, 0xed, 0x66, 0x80, 0x06, 0x1b, 0x4a, 0x45, 0xdc, 0xbc, 0xdc, + 0x93, 0x44, 0xce, 0xf4, 0x01, 0xdc, 0x08, 0x73, 0x02, 0x32, 0xa3, 0xf0, + 0x61, 0x9a, 0x50, 0x04, 0x3b, 0x28, 0xb3, 0x9a, 0xbf, 0xe7, 0x5c, 0x5a, + 0x99, 0x4b, 0xf7, 0xff, 0x3b, 0x76, 0x7b, 0x7a, 0xcc, 0xcd, 0x49, 0xdf, + 0x49, 0x48, 0xcc, 0x99, 0x34, 0x14, 0x07, 0xda, 0x06, 0xfb, 0x9d, 0x97, + 0xc4, 0xd9, 0x2e, 0x25, 0x34, 0x63, 0x0c, 0x97, 0xce, 0xfa, 0x3b, 0xcf, + 0x87, 0x18, 0xdd, 0xf7, 0x3f, 0x8b, 0xe1, 0x00, 0xcb, 0x61, 0x03, 0x2c, + 0x38, 0xbc, 0x31, 0xdc, 0x80, 0xc4, 0x3f, 0xd5, 0x8c, 0x64, 0xe1, 0x09, + 0x4e, 0x86, 0x59, 0xec, 0x85, 0x55, 0xf0, 0x3a, 0xa7, 0xae, 0xae, 0x02, + 0xd1, 0x9c, 0x00, 0xc9, 0x20, 0x3e, 0x3c, 0x3f, 0x6e, 0x2e, 0xd9, 0x64, + 0xb9, 0x0c, 0x82, 0x32, 0x81, 0xe7, 0x46, 0xf5, 0x72, 0xb5, 0x70, 0x5c, + 0x4c, 0xaf, 0xda, 0xfc, 0x29, 0x07, 0x12, 0x3b, 0x09, 0xde, 0xd3, 0x29, + 0x06, 0xa0, 0x66, 0x94, 0x72, 0xbe, 0xa0, 0x3f, 0xc3, 0xef, 0x4f, 0xf2, + 0x77, 0x21, 0x37, 0x58, 0xd9, 0x62, 0x25, 0x08, 0x41, 0xf4, 0x47, 0xc4, + 0xcb, 0xcb, 0xac, 0x63, 0x14, 0x12, 0xb6, 0xe8, 0xfa, 0xb7, 0x12, 0x6d, + 0x41, 0xd1, 0x1c, 0x8c, 0x3b, 0x3d, 0x10, 0x20, 0xcb, 0xcb, 0x9c, 0xab, + 0x1a, 0x27, 0xe1, 0x71, 0xce, 0x95, 0x67, 0x02, 0xe4, 0x8b, 0x90, 0xe2, + 0x13, 0xb3, 0xb3, 0x0d, 0x33, 0xb3, 0xb3, 0x96, 0x7e, 0xb3, 0xb6, 0x89, + 0x44, 0x94, 0x0a, 0x0c, 0xc0, 0xd6, 0xc3, 0xe9, 0x14, 0x19, 0x0a, 0xfb, + 0xd0, 0x9d, 0x0a, 0x39, 0x61, 0xbe, 0xbb, 0x5f, 0xa4, 0xd4, 0xf8, 0xc4, + 0x7c, 0x91, 0x18, 0xe8, 0x84, 0x46, 0x1f, 0x25, 0x29, 0x9c, 0xbb, 0xd4, + 0x41, 0x9e, 0xdb, 0x04, 0x3b, 0xef, 0x46, 0x72, 0xc6, 0xdb, 0x40, 0x25, + 0x92, 0x7c, 0x34, 0x68, 0x2b, 0x43, 0xbd, 0x4b, 0xfd, 0x8c, 0x51, 0xa2, + 0xcd, 0x91, 0x3e, 0x7b, 0xfe, 0x67, 0xb7, 0x93, 0x5b, 0x62, 0x43, 0x25, + 0x7f, 0xd2, 0x98, 0xd5, 0xfd, 0x63, 0x21, 0x2a, 0x18, 0x0d, 0x0a, 0x3d, + 0xc6, 0x78, 0xe5, 0xd2, 0x92, 0xb1, 0x2a, 0x11, 0xd0, 0x9b, 0xa0, 0x4a, + 0x54, 0x1a, 0x68, 0x04, 0xca, 0x18, 0x7a, 0xc0, 0x4b, 0xeb, 0x76, 0xc9, + 0x81, 0x8e, 0x32, 0xb4, 0x5b, 0x50, 0xa0, 0x94, 0xe6, 0x80, 0xc9, 0x19, + 0xf8, 0x26, 0x57, 0xef, 0xf7, 0x29, 0x71, 0x17, 0xfb, 0xeb, 0x85, 0xa8, + 0xa8, 0x41, 0x5b, 0x26, 0x48, 0x51, 0x83, 0x4c, 0x89, 0x1b, 0xa1, 0x8e, + 0x91, 0xf1, 0xe9, 0x8c, 0xff, 0xba, 0xee, 0xd7, 0x6b, 0x0f, 0xf5, 0x39, + 0x60, 0x69, 0xda, 0xbc, 0x76, 0xd8, 0x15, 0x79, 0x9a, 0x79, 0x59, 0x54, + 0xa5, 0x46, 0xb2, 0x65, 0x7e, 0x34, 0xd4, 0xc4, 0xf6, 0xc7, 0x98, 0x26, + 0x39, 0x9c, 0x30, 0x18, 0xc0, 0x04, 0xac, 0xba, 0xca, 0x5f, 0xcd, 0x7b, + 0x03, 0xd7, 0x0d, 0xa0, 0x71, 0xdd, 0x90, 0x86, 0x85, 0x5e, 0x44, 0xfc, + 0xe3, 0x41, 0xf7, 0xc2, 0xd6, 0x6b, 0xee, 0xa5, 0x6b, 0x2f, 0x72, 0x18, + 0xbb, 0xc8, 0x48, 0xa0, 0x26, 0x48, 0x9b, 0xca, 0xac, 0x6d, 0x73, 0x5a, + 0x5d, 0x3d, 0xef, 0x97, 0xdc, 0x83, 0x4d, 0x47, 0x40, 0xee, 0x60, 0x85, + 0x61, 0xf6, 0x23, 0x2c, 0x80, 0x7c, 0x45, 0x5b, 0x49, 0x91, 0x43, 0x0c, + 0x50, 0x6c, 0xa2, 0x19, 0x0c, 0x03, 0x1f, 0xe7, 0x85, 0x15, 0x7f, 0x75, + 0xb2, 0xf2, 0x64, 0x05, 0x1a, 0x28, 0xbc, 0xa9, 0x21, 0x97, 0x42, 0x86, + 0x5e, 0x10, 0x01, 0xb9, 0x3c, 0x91, 0xfb, 0x95, 0x32, 0xde, 0x1a, 0xdd, + 0x32, 0x09, 0x81, 0x94, 0x9d, 0xda, 0x12, 0xed, 0x5a, 0x53, 0x4a, 0xc8, + 0xa2, 0xeb, 0xa8, 0x41, 0xcd, 0xaf, 0xfc, 0xe3, 0xb5, 0x89, 0x53, 0x90, + 0x30, 0x22, 0x59, 0x0a, 0x00, 0xcb, 0x01, 0xf0, 0x49, 0xb3, 0x5b, 0x7f, + 0x61, 0xc3, 0xc8, 0xee, 0xd9, 0x6d, 0xc8, 0xe1, 0x01, 0xa6, 0xe7, 0x26, + 0x84, 0xe8, 0xc8, 0x9c, 0x20, 0x3e, 0x18, 0x2a, 0xb7, 0x15, 0xd6, 0x66, + 0xb1, 0x51, 0x09, 0x20, 0xc1, 0x1a, 0x8b, 0x2d, 0x01, 0xdc, 0xac, 0xf6, + 0x1f, 0x6a, 0x74, 0x58, 0x8f, 0x30, 0x61, 0x46, 0x0e, 0x04, 0x91, 0x73, + 0x29, 0x08, 0x51, 0x0f, 0x92, 0x6f, 0x03, 0xaa, 0x88, 0x1d, 0x95, 0x57, + 0x6e, 0xec, 0xc2, 0xf8, 0xae, 0x43, 0x50, 0x14, 0xa4, 0x18, 0x19, 0x50, + 0x19, 0x08, 0x7c, 0x78, 0xde, 0xe7, 0xb3, 0x5e, 0x5c, 0x17, 0xde, 0xc0, + 0x66, 0x90, 0xed, 0x65, 0xaa, 0x00, 0x4e, 0x85, 0x3c, 0x6c, 0x79, 0x20, + 0x0d, 0x0f, 0xaa, 0x95, 0xa8, 0x5e, 0xb7, 0x8f, 0xbf, 0x3c, 0x07, 0x12, + 0x11, 0x91, 0xbd, 0xa9, 0x1f, 0x31, 0xf3, 0xd7, 0x8a, 0x6c, 0xd2, 0xa9, + 0xbd, 0x7d, 0xd1, 0x63, 0x39, 0x63, 0x64, 0x85, 0xe1, 0x94, 0xba, 0xb1, + 0xb5, 0xc0, 0xf4, 0xe2, 0xf7, 0x7b, 0xab, 0xc3, 0x99, 0xee, 0x43, 0x23, + 0x18, 0x80, 0x18, 0x50, 0xc3, 0xc0, 0x8e, 0x42, 0xf9, 0xef, 0xe5, 0xad, + 0xe2, 0x6d, 0xd8, 0xb6, 0x2e, 0xde, 0x45, 0xa3, 0x21, 0x87, 0x97, 0x70, + 0x33, 0xcb, 0xfa, 0xe6, 0x45, 0x7b, 0x46, 0x89, 0xf9, 0xa1, 0x2b, 0x09, + 0x65, 0x28, 0x87, 0x9b, 0xb8, 0x79, 0x04, 0x69, 0x01, 0xda, 0xbd, 0x17, + 0x7c, 0x84, 0x94, 0x23, 0x4b, 0x0a, 0x57, 0xe3, 0xf3, 0xed, 0x5d, 0x27, + 0xcc, 0x12, 0xe4, 0x07, 0xd3, 0x01, 0x46, 0x49, 0x43, 0x26, 0xf4, 0x70, + 0x85, 0x6b, 0x65, 0x9f, 0xaa, 0xa4, 0x88, 0x66, 0x20, 0x88, 0x44, 0x03, + 0x4c, 0x32, 0xa0, 0xa2, 0x5c, 0x8f, 0xb4, 0x0d, 0x90, 0x1f, 0x39, 0x41, + 0xfb, 0x48, 0x5c, 0x04, 0x70, 0xd9, 0x47, 0xec, 0x43, 0xae, 0x77, 0x33, + 0x84, 0xda, 0x48, 0xa6, 0xbd, 0xed, 0x92, 0xca, 0x38, 0x60, 0x28, 0x80, + 0x18, 0xd1, 0xa1, 0xd9, 0x46, 0xc7, 0xae, 0x2e, 0xcf, 0xd6, 0x4f, 0xb3, + 0x3c, 0xb7, 0xd0, 0x01, 0x03, 0x31, 0x97, 0xda, 0xd5, 0xee, 0xd7, 0x26, + 0x06, 0x12, 0xa5, 0xe8, 0x2f, 0xdf, 0x80, 0x18, 0xe2, 0x59, 0x64, 0xe1, + 0x20, 0x10, 0xc8, 0x97, 0x92, 0x4b, 0xad, 0x54, 0x02, 0x12, 0xc3, 0xcd, + 0x8a, 0x33, 0xc7, 0xf4, 0xfd, 0x4d, 0xeb, 0x6d, 0x4c, 0xa3, 0x34, 0x00, + 0xf8, 0xa8, 0xc8, 0x21, 0x90, 0x43, 0x3f, 0xae, 0x7b, 0xaf, 0x37, 0x7a, + 0x72, 0xc3, 0x47, 0xce, 0xbb, 0xbf, 0xd0, 0x80, 0x6e, 0x00, 0xd6, 0x71, + 0x42, 0x92, 0x12, 0x9c, 0x62, 0x09, 0xc7, 0x3f, 0x62, 0x36, 0xd2, 0xfe, + 0xff, 0xba, 0xb5, 0x08, 0x27, 0x88, 0x26, 0x86, 0x3b, 0xd4, 0x34, 0x8c, + 0x08, 0xf8, 0x24, 0xb3, 0x46, 0x1b, 0x60, 0xf3, 0x86, 0x32, 0x90, 0x47, + 0xb6, 0x92, 0x1f, 0x8b, 0xb6, 0xa1, 0x7a, 0x4e, 0x67, 0x04, 0x86, 0x51, + 0xfa, 0x96, 0xb4, 0xba, 0xe3, 0xe3, 0x6a, 0x97, 0x0a, 0x02, 0x30, 0x0a, + 0xd5, 0x08, 0x35, 0x42, 0x67, 0x00, 0xac, 0xa0, 0xd6, 0x6a, 0xcc, 0x52, + 0xa3, 0xe5, 0xec, 0xb9, 0x9c, 0xcb, 0xce, 0x53, 0xca, 0x63, 0x97, 0x95, + 0x91, 0x16, 0x6c, 0x65, 0x16, 0xcb, 0x6c, 0x3c, 0xa0, 0xa3, 0x34, 0x42, + 0x29, 0x5e, 0x01, 0x5e, 0xf4, 0xd2, 0xe1, 0x32, 0x9e, 0x42, 0x12, 0x3f, + 0x72, 0x3a, 0x8d, 0xe8, 0xab, 0x8b, 0x0a, 0x86, 0x29, 0x99, 0x00, 0xe3, + 0x38, 0x9a, 0x34, 0x0c, 0xd0, 0xcb, 0x4a, 0x21, 0x11, 0xdc, 0x07, 0xad, + 0x53, 0xe5, 0xb2, 0x30, 0x69, 0x13, 0x92, 0xc9, 0x64, 0xb3, 0x00, 0x35, + 0x33, 0x4d, 0xc0, 0xca, 0x64, 0x3e, 0x08, 0x03, 0x3a, 0x38, 0xde, 0x0d, + 0xd2, 0x96, 0xb7, 0xb7, 0xab, 0xc4, 0x9a, 0x26, 0x74, 0x27, 0xe9, 0xf1, + 0x0a, 0xc3, 0x6f, 0x5a, 0x79, 0xd5, 0xf2, 0x92, 0xd5, 0x33, 0x30, 0x40, + 0x41, 0x06, 0x81, 0x8d, 0xe1, 0xde, 0x9c, 0x8a, 0xbd, 0xb4, 0xb5, 0xc5, + 0x82, 0x8b, 0xe3, 0xc3, 0xf3, 0x03, 0xd3, 0x84, 0xa2, 0xcc, 0x03, 0xed, + 0x67, 0xe6, 0x20, 0x32, 0x94, 0x92, 0x18, 0x0e, 0x44, 0x61, 0x52, 0xaf, + 0xb8, 0x51, 0x7c, 0xac, 0x20, 0x67, 0x2c, 0x3b, 0x90, 0xe1, 0x90, 0x99, + 0x43, 0x24, 0x3d, 0x3f, 0x68, 0xad, 0xda, 0x91, 0x3e, 0x30, 0xc5, 0x2f, + 0xf1, 0x50, 0x71, 0x45, 0xf0, 0x09, 0x4e, 0x34, 0xd2, 0x7d, 0x94, 0xb3, + 0xe9, 0xbd, 0x44, 0x0d, 0x34, 0x18, 0x4f, 0xc4, 0x5c, 0xc3, 0x04, 0x3c, + 0x9b, 0x08, 0xc5, 0x2d, 0x65, 0x23, 0x40, 0x64, 0xa5, 0xf4, 0x77, 0xfb, + 0xbf, 0xca, 0x23, 0x89, 0x8d, 0x03, 0x4b, 0x40, 0xf6, 0xb4, 0x49, 0x39, + 0x24, 0x7c, 0x4f, 0x79, 0xce, 0x13, 0x0b, 0x38, 0xc9, 0xbf, 0xc5, 0x94, + 0x64, 0x07, 0xd0, 0x2d, 0xed, 0xe0, 0x30, 0x14, 0x68, 0xfd, 0x3f, 0x08, + 0x42, 0x62, 0xa3, 0xd3, 0x1c, 0x88, 0x58, 0xe8, 0x8c, 0x9b, 0x22, 0x3c, + 0x41, 0xa6, 0xa5, 0x7d, 0x1d, 0xbf, 0xc0, 0xf9, 0xf9, 0xbe, 0x78, 0x67, + 0x0a, 0x2f, 0xbf, 0x39, 0xd4, 0xb2, 0x6f, 0x07, 0xcc, 0x09, 0xe5, 0x7d, + 0x54, 0xfc, 0xbb, 0x30, 0xc6, 0x22, 0x66, 0x84, 0xf2, 0xb4, 0x8c, 0xa1, + 0x74, 0xaf, 0x04, 0x8e, 0x73, 0x71, 0x1a, 0xf0, 0x67, 0xad, 0x8a, 0x18, + 0xd0, 0xf1, 0x63, 0x95, 0xf4, 0xc7, 0xc4, 0x7e, 0x75, 0xb6, 0x12, 0xd8, + 0xd4, 0xe7, 0x03, 0x11, 0xb2, 0x1e, 0x70, 0x8f, 0xb2, 0xbf, 0x18, 0x7b, + 0xf8, 0x98, 0x97, 0xe1, 0xe7, 0x08, 0x0c, 0x6f, 0x55, 0x19, 0x94, 0xfa, + 0xd5, 0x89, 0xb7, 0xdc, 0xf1, 0x2b, 0xc6, 0x4b, 0x32, 0x8c, 0x26, 0x26, + 0x96, 0x72, 0x4d, 0x55, 0x3d, 0xba, 0x6e, 0xbc, 0xb6, 0x98, 0xe1, 0x9c, + 0x6e, 0x18, 0x12, 0x84, 0xf1, 0x8d, 0x14, 0x0e, 0x5e, 0x01, 0xe2, 0x74, + 0xf7, 0x4a, 0x55, 0xff, 0xb7, 0x3c, 0xe7, 0xfe, 0xd2, 0x97, 0xce, 0xed, + 0xc6, 0xc6, 0xec, 0xfd, 0x89, 0xe9, 0x52, 0x26, 0x8b, 0x82, 0xfa, 0x44, + 0x8c, 0x21, 0xbc, 0xa5, 0x79, 0x76, 0x5b, 0xb7, 0x93, 0x70, 0x56, 0xe0, + 0x00, 0x48, 0x84, 0xee, 0x09, 0x17, 0x61, 0x46, 0x90, 0x44, 0x07, 0x32, + 0x9c, 0xc7, 0x71, 0x56, 0x64, 0x67, 0x46, 0x3e, 0xbf, 0x93, 0xdf, 0x4e, + 0xa6, 0x2c, 0x0a, 0x05, 0x0a, 0x6b, 0x15, 0x0f, 0xe9, 0x0d, 0xb6, 0xf0, + 0xce, 0x0a, 0x32, 0xa1, 0x59, 0x11, 0xe3, 0xa6, 0xac, 0xe1, 0xb4, 0xc4, + 0xbf, 0xcc, 0xac, 0x9d, 0xed, 0xe7, 0x34, 0x49, 0xf1, 0x26, 0xad, 0x58, + 0xdb, 0xf1, 0xb5, 0x00, 0xa1, 0x05, 0xed, 0xb2, 0xe0, 0xc2, 0x96, 0x82, + 0x05, 0xa4, 0x95, 0x59, 0x76, 0xbf, 0xe6, 0x96, 0xb8, 0xd0, 0x29, 0xe5, + 0xad, 0x2b, 0x7b, 0x73, 0xb3, 0x2d, 0x01, 0x20, 0x4d, 0x12, 0x72, 0xdc, + 0x92, 0x5d, 0x1c, 0x24, 0x2e, 0xb8, 0x33, 0x70, 0xe9, 0x41, 0x56, 0xaf, + 0x9f, 0xeb, 0x1a, 0xa5, 0xae, 0x1a, 0x74, 0x68, 0x04, 0x24, 0xc0, 0x01, + 0x38, 0x4e, 0xc8, 0xc9, 0x9f, 0x01, 0xc3, 0x39, 0xc3, 0xb5, 0x0c, 0xa3, + 0xe2, 0xaa, 0x6e, 0xf0, 0x69, 0x07, 0xda, 0x17, 0xbf, 0x6a, 0xcd, 0x92, + 0x26, 0x87, 0xd7, 0x87, 0xae, 0x0a, 0x3d, 0xf5, 0x87, 0xfc, 0x3b, 0x9c, + 0xb1, 0xf2, 0xe8, 0x90, 0x12, 0x92, 0x27, 0xb9, 0x40, 0xea, 0xc5, 0x63, + 0xab, 0xfe, 0xf3, 0xbe, 0x62, 0x07, 0xa2, 0x95, 0xf3, 0x47, 0x72, 0x1b, + 0xd9, 0xaf, 0xd2, 0x2c, 0x51, 0x28, 0x8c, 0x9f, 0xcc, 0xe4, 0xfb, 0x83, + 0x33, 0xdd, 0xba, 0xbe, 0xb4, 0xbb, 0x33, 0xf7, 0x4d, 0x8c, 0xe0, 0xb6, + 0x41, 0xc9, 0x13, 0xc3, 0x72, 0xad, 0xd1, 0xd1, 0xed, 0x58, 0x16, 0xf9, + 0xff, 0xde, 0xf5, 0x0b, 0xfb, 0x38, 0xbb, 0x1b, 0x8c, 0x1e, 0xdf, 0x9a, + 0x5f, 0xd5, 0x8d, 0xb9, 0x8c, 0x60, 0x1c, 0xbc, 0xc2, 0x58, 0x44, 0x23, + 0x94, 0x67, 0xf4, 0x1d, 0x27, 0x10, 0x46, 0xfb, 0x75, 0xa0, 0xc3, 0x22, + 0x6d, 0x45, 0xc1, 0x94, 0xa6, 0xc5, 0x08, 0x7e, 0x30, 0x56, 0x7d, 0xb6, + 0x59, 0xcd, 0x35, 0xfe, 0xcf, 0xfc, 0xf0, 0x1a, 0xe7, 0xb8, 0xf3, 0x04, + 0x0c, 0xa7, 0x05, 0x09, 0xe0, 0x15, 0x86, 0x4e, 0x56, 0xce, 0xff, 0x8b, + 0x6e, 0xed, 0x94, 0x26, 0x79, 0xa2, 0x12, 0xe4, 0x25, 0x38, 0x12, 0xce, + 0xe7, 0x92, 0xfa, 0x6a, 0xaa, 0xb6, 0xa8, 0x84, 0x71, 0xd9, 0x9b, 0x72, + 0xd9, 0x14, 0xb1, 0x66, 0x85, 0x09, 0x91, 0x29, 0xe5, 0xc9, 0x17, 0xa0, + 0x09, 0xfa, 0x20, 0xa5, 0xc3, 0x66, 0x2e, 0x3b, 0x53, 0x59, 0xd1, 0x0c, + 0x40, 0x5c, 0xd2, 0xf7, 0x95, 0x46, 0x53, 0x01, 0x10, 0x4e, 0x53, 0xfd, + 0x46, 0xb7, 0x82, 0x6b, 0xe8, 0xea, 0x52, 0xc6, 0x9b, 0xe5, 0xa5, 0x88, + 0x2a, 0xf0, 0x28, 0x23, 0x51, 0x99, 0x77, 0x00, 0x46, 0x77, 0x3c, 0x9a, + 0xfa, 0x51, 0x28, 0xad, 0x8d, 0x13, 0x0d, 0xe9, 0x41, 0x1a, 0x12, 0x43, + 0xee, 0x12, 0x28, 0xbb, 0x8e, 0xf6, 0x0e, 0x18, 0xc0, 0x57, 0x6f, 0x2d, + 0x28, 0x32, 0x33, 0xf2, 0xa4, 0x06, 0xf2, 0x7b, 0xa3, 0xf1, 0x6b, 0x06, + 0xcf, 0x23, 0x81, 0xe7, 0x90, 0xc5, 0xa8, 0xa9, 0x27, 0x64, 0x97, 0x44, + 0xba, 0x07, 0x1a, 0x52, 0xc9, 0xa2, 0x97, 0x56, 0x19, 0xca, 0x2a, 0x7e, + 0xd8, 0x92, 0x79, 0xbd, 0x7a, 0x0d, 0xf9, 0x61, 0x80, 0x9b, 0x83, 0x31, + 0xa6, 0xa6, 0xe8, 0x32, 0x38, 0x40, 0x99, 0x81, 0x75, 0xd5, 0xa5, 0xd8, + 0xbd, 0x0c, 0x71, 0xb8, 0x1c, 0xe5, 0x65, 0x99, 0x50, 0x09, 0x0c, 0xb3, + 0xe2, 0x7b, 0x5a, 0xbc, 0x1c, 0x0d, 0x21, 0xa9, 0xc8, 0x33, 0x01, 0x2c, + 0x64, 0x66, 0x6f, 0x49, 0xf4, 0xf8, 0xb7, 0x5a, 0x5f, 0xe8, 0x86, 0x10, + 0xcc, 0x01, 0x08, 0xc6, 0x9e, 0x8b, 0xc8, 0x91, 0x47, 0x72, 0x22, 0x55, + 0x83, 0xfb, 0xa5, 0xa7, 0x50, 0xd3, 0x4d, 0xcb, 0xd2, 0xa5, 0x96, 0x60, + 0x35, 0x1e, 0x52, 0x00, 0xa3, 0x39, 0x23, 0xf6, 0x4c, 0x6d, 0x4b, 0x14, + 0x96, 0xf9, 0xa9, 0x43, 0xd9, 0x80, 0x27, 0x6a, 0xf3, 0xa2, 0xcf, 0xc3, + 0x19, 0x19, 0x4f, 0x2a, 0x69, 0x72, 0x32, 0x95, 0x65, 0x3e, 0x9b, 0xfa, + 0x8e, 0x23, 0x36, 0x83, 0xb0, 0x71, 0xd4, 0x0d, 0x52, 0xaf, 0x99, 0x02, + 0xf9, 0x7b, 0x20, 0x8c, 0x82, 0x33, 0x8e, 0x5d, 0xb1, 0x34, 0x18, 0x1c, + 0x32, 0xad, 0x70, 0x4c, 0x88, 0x95, 0x1e, 0xc2, 0xf8, 0xda, 0x70, 0xe0, + 0xc8, 0x62, 0xfc, 0xdc, 0xc8, 0x96, 0x02, 0x83, 0x41, 0x56, 0xbf, 0xc5, + 0xfc, 0xba, 0xdc, 0x53, 0x94, 0x9c, 0x63, 0x38, 0x9c, 0x19, 0x29, 0x99, + 0xa4, 0x60, 0x12, 0xac, 0x53, 0x6b, 0xcc, 0xb1, 0xc3, 0xca, 0x50, 0x24, + 0x4f, 0x68, 0x12, 0x35, 0x53, 0x3b, 0xbe, 0xca, 0x08, 0x87, 0x79, 0x49, + 0x20, 0xd5, 0x60, 0xea, 0x68, 0xc4, 0x50, 0xcb, 0x29, 0x50, 0xf7, 0x02, + 0xfe, 0xba, 0x30, 0x35, 0x3e, 0x06, 0xf5, 0x86, 0x7c, 0x32, 0x22, 0x53, + 0x24, 0xa2, 0x82, 0x33, 0x19, 0x3e, 0xc8, 0x35, 0xbb, 0x30, 0xd2, 0x05, + 0x8b, 0x9f, 0xf0, 0x22, 0xdd, 0xa3, 0x22, 0x81, 0x48, 0x37, 0xda, 0x88, + 0x20, 0xae, 0x96, 0x5c, 0xa1, 0xbd, 0x18, 0x49, 0xe6, 0xe6, 0x6b, 0xdb, + 0xeb, 0x19, 0x06, 0x9c, 0xe8, 0x99, 0x11, 0x93, 0xc9, 0x7d, 0x42, 0xff, + 0xe3, 0xa3, 0x00, 0x82, 0x88, 0x1e, 0x94, 0x67, 0x47, 0xe2, 0xd6, 0x5a, + 0x64, 0xb2, 0x26, 0x40, 0xa1, 0xe9, 0xc2, 0x45, 0x33, 0x4a, 0x8a, 0x5f, + 0x61, 0x3c, 0x11, 0x2d, 0x23, 0xa6, 0x9c, 0xe4, 0x8a, 0x17, 0xa0, 0x4f, + 0xe2, 0xf8, 0xb8, 0xbc, 0xd1, 0x6a, 0x34, 0xa1, 0x94, 0x19, 0x32, 0x97, + 0x80, 0xd5, 0x67, 0x26, 0x01, 0xce, 0x95, 0x41, 0xcb, 0x42, 0x8e, 0x50, + 0x83, 0x0e, 0x70, 0x8d, 0xc0, 0x7a, 0xdc, 0x88, 0xa2, 0x48, 0x9c, 0xf2, + 0x52, 0xfb, 0x6c, 0x49, 0x62, 0xec, 0xcd, 0xe1, 0x39, 0x06, 0xfb, 0x09, + 0xf6, 0x8e, 0x84, 0x8e, 0xe9, 0x25, 0xb9, 0x39, 0x7e, 0x9c, 0xaf, 0x11, + 0x1b, 0x04, 0xf9, 0x7d, 0x9a, 0x1a, 0x4a, 0xab, 0x00, 0xdb, 0xba, 0x4a, + 0xe6, 0xd2, 0x6b, 0x9b, 0x85, 0xf2, 0xcc, 0x32, 0xab, 0xc7, 0x2d, 0x21, + 0x59, 0x3a, 0xb0, 0x27, 0xbf, 0xc5, 0xf2, 0x7b, 0x3f, 0x43, 0x6c, 0xab, + 0xbf, 0xd5, 0xe5, 0x2e, 0xcd, 0x4e, 0xbe, 0xe1, 0xc8, 0x3c, 0x96, 0x13, + 0xed, 0x14, 0xe8, 0xf8, 0x81, 0x7c, 0x49, 0x06, 0x5b, 0xd1, 0xca, 0x45, + 0x2f, 0x2a, 0x34, 0x2e, 0x03, 0xc5, 0x86, 0x64, 0x40, 0x8e, 0x1e, 0x80, + 0x0d, 0x42, 0x14, 0x80, 0x6f, 0xb4, 0xc9, 0xe4, 0xf6, 0xed, 0xda, 0xd4, + 0x45, 0x0d, 0x42, 0xc1, 0x76, 0xe2, 0xbb, 0xd1, 0x05, 0x66, 0x4a, 0xd4, + 0xd1, 0xca, 0x85, 0xc8, 0xcb, 0xfb, 0x84, 0xa5, 0xca, 0x98, 0x8f, 0xbf, + 0xcf, 0xc5, 0x71, 0x5f, 0xfe, 0xe6, 0x92, 0x56, 0x20, 0xa4, 0x34, 0x8a, + 0x35, 0x7a, 0xaa, 0xa2, 0xb5, 0x79, 0xe1, 0x24, 0xa9, 0xee, 0xc3, 0x2c, + 0x4d, 0x59, 0xa0, 0x41, 0xf5, 0x87, 0xa8, 0xa0, 0xeb, 0x02, 0xe9, 0xfd, + 0xdf, 0x77, 0xbb, 0x72, 0xc4, 0x17, 0x9e, 0xdb, 0xe1, 0x18, 0x70, 0xca, + 0x6a, 0x87, 0x24, 0x68, 0xb8, 0x80, 0x84, 0x94, 0xc1, 0xe7, 0xd5, 0x07, + 0xde, 0xd4, 0xdc, 0xce, 0x2a, 0xde, 0x74, 0xb8, 0xd9, 0xfd, 0x5a, 0x0f, + 0x91, 0x9a, 0x70, 0x8a, 0x34, 0x0a, 0xc9, 0x5f, 0x88, 0x28, 0xf9, 0x3a, + 0x79, 0xd6, 0xee, 0x4c, 0x82, 0xa4, 0x97, 0x24, 0x4a, 0x43, 0x2b, 0x25, + 0xf5, 0x55, 0xcb, 0x6f, 0x23, 0xb1, 0x2c, 0x9a, 0x43, 0xe6, 0x9e, 0xe1, + 0x70, 0x77, 0x07, 0x09, 0x14, 0x9c, 0x00, 0x5e, 0xb9, 0x22, 0x28, 0xd7, + 0xf9, 0x41, 0xe6, 0x13, 0xa6, 0x2b, 0x73, 0x5a, 0x4f, 0x6b, 0x98, 0x39, + 0xba, 0xf8, 0xa7, 0xfc, 0x07, 0x1d, 0xbf, 0x69, 0xcc, 0x00, 0xd1, 0x66, + 0xa6, 0x41, 0x00, 0x91, 0x41, 0x1e, 0xe0, 0x07, 0xcb, 0x16, 0xfe, 0xc6, + 0xe6, 0xd5, 0x54, 0xb4, 0x51, 0x4e, 0xf7, 0x2a, 0xb4, 0x86, 0xa0, 0x77, + 0xb8, 0x2b, 0xf2, 0x41, 0x2f, 0xb2, 0x03, 0xc0, 0x7a, 0x92, 0x7b, 0xcb, + 0xd5, 0x9a, 0x65, 0xd2, 0x37, 0x80, 0xbe, 0xdc, 0x4e, 0x0c, 0x3e, 0xaa, + 0x86, 0xef, 0x86, 0x01, 0xa8, 0x77, 0x36, 0xd7, 0xf2, 0xf5, 0xb9, 0xeb, + 0xd8, 0x6e, 0x5e, 0x12, 0x5d, 0xfc, 0xf7, 0x93, 0xb6, 0x91, 0xbc, 0x00, + 0x04, 0x67, 0x97, 0xf7, 0x37, 0xac, 0x3b, 0x81, 0xbe, 0xab, 0x3e, 0xfa, + 0x92, 0x67, 0xb1, 0x60, 0x4e, 0xf4, 0x64, 0x27, 0x08, 0x08, 0x32, 0x40, + 0x9a, 0x3e, 0x2c, 0x4c, 0x9a, 0x53, 0x45, 0xcc, 0xe1, 0xfa, 0x70, 0xda, + 0x8c, 0x00, 0x49, 0x6d, 0x0e, 0x4b, 0x22, 0xf6, 0x7f, 0xd1, 0x49, 0x37, + 0xa0, 0x28, 0x48, 0x5e, 0xa4, 0xc5, 0x76, 0xb8, 0x86, 0x1a, 0xa5, 0x34, + 0xe6, 0x0a, 0x25, 0x80, 0x48, 0x9f, 0x01, 0x25, 0xb3, 0xde, 0xf1, 0x0b, + 0xaf, 0x6b, 0x22, 0x1c, 0x60, 0x1c, 0xc9, 0xa3, 0x17, 0x96, 0x19, 0xb2, + 0x1b, 0xcb, 0xc2, 0x1d, 0xf6, 0x9f, 0xc2, 0x89, 0x99, 0xcd, 0x9b, 0x7f, + 0x67, 0x7e, 0x39, 0xdf, 0x37, 0x9b, 0xd3, 0xf3, 0x7f, 0xfe, 0xb8, 0x34, + 0xb0, 0xf0, 0x03, 0xbf, 0x33, 0x23, 0xa5, 0x01, 0x51, 0x28, 0x09, 0x90, + 0x89, 0x78, 0x4f, 0xd0, 0x1c, 0xf6, 0x61, 0xc6, 0xb4, 0xd4, 0x08, 0x9d, + 0x22, 0xcf, 0x08, 0xa4, 0x70, 0xc6, 0x79, 0x77, 0xa8, 0x15, 0xe9, 0x0d, + 0x74, 0x0a, 0xc6, 0x04, 0xb0, 0x6f, 0x39, 0x80, 0x43, 0xcc, 0xa8, 0xfc, + 0x5a, 0x32, 0xa0, 0x2a, 0xd6, 0x01, 0xb9, 0x41, 0xd1, 0xd8, 0x96, 0x5a, + 0x07, 0x25, 0xf4, 0x5c, 0x48, 0x1f, 0x0b, 0x38, 0x4c, 0x2e, 0x15, 0x23, + 0x32, 0xe2, 0xee, 0x7c, 0x7d, 0xf8, 0xa5, 0x89, 0xde, 0x89, 0x2f, 0xc7, + 0x4d, 0xba, 0x2f, 0xfe, 0x48, 0x95, 0x19, 0x4e, 0x06, 0x64, 0x4e, 0x54, + 0xfc, 0x0c, 0xf6, 0xc3, 0x5a, 0x17, 0xb0, 0x90, 0x9e, 0x52, 0x5c, 0xf2, + 0x51, 0xa4, 0x15, 0xc5, 0xf2, 0x98, 0xce, 0x50, 0xfc, 0xef, 0x86, 0x91, + 0x5b, 0x95, 0x23, 0x42, 0x48, 0xa3, 0x90, 0xea, 0xcb, 0x47, 0x98, 0xdf, + 0xf2, 0xcc, 0xfc, 0x5b, 0x0d, 0xdc, 0x8e, 0x78, 0x86, 0x58, 0xf2, 0xed, + 0xa0, 0x6a, 0xea, 0xe1, 0x51, 0xf1, 0x0c, 0xfb, 0x3a, 0x2c, 0x4e, 0x59, + 0xec, 0x82, 0x32, 0x65, 0x93, 0xc2, 0xd9, 0xa4, 0x32, 0x72, 0x41, 0x91, + 0x45, 0x23, 0x43, 0xc3, 0xab, 0x8a, 0xfb, 0xaf, 0x21, 0xc6, 0x42, 0x85, + 0x61, 0x24, 0xcb, 0x25, 0x09, 0xf4, 0xf6, 0x54, 0x1e, 0x45, 0xe1, 0x42, + 0x19, 0x49, 0x1c, 0x96, 0x11, 0x3c, 0x89, 0x2f, 0xf3, 0xa9, 0x48, 0x39, + 0x02, 0x14, 0x50, 0x26, 0x8f, 0x64, 0x33, 0x85, 0x4f, 0x35, 0x85, 0xe7, + 0xdd, 0x7f, 0x7d, 0xfb, 0xd9, 0xd4, 0x62, 0x06, 0x1a, 0x57, 0x10, 0xfe, + 0x12, 0xc6, 0x9e, 0x26, 0xb6, 0x5d, 0x41, 0xde, 0x66, 0x1e, 0xcf, 0x32, + 0x7b, 0x20, 0x4e, 0xec, 0xf1, 0x84, 0xb2, 0x28, 0x55, 0xd2, 0x4f, 0xcd, + 0x23, 0xff, 0xcb, 0xd4, 0x96, 0x6a, 0x16, 0xc9, 0x1a, 0xd8, 0x02, 0x59, + 0x7f, 0x06, 0x3e, 0x7d, 0xe1, 0x0f, 0x60, 0x79, 0xec, 0x1b, 0x41, 0x5f, + 0x99, 0xb9, 0x65, 0x5d, 0x82, 0xbe, 0x2f, 0x97, 0x8f, 0xd2, 0xef, 0x0e, + 0x32, 0xd7, 0xab, 0x65, 0xc5, 0xa1, 0x92, 0xf1, 0x74, 0x65, 0xf3, 0x00, + 0xb1, 0xab, 0x54, 0x7f, 0x26, 0x43, 0x2c, 0x4e, 0xba, 0x6d, 0x83, 0xb9, + 0x1a, 0x75, 0xec, 0x98, 0x6d, 0x1f, 0xa1, 0x37, 0xdb, 0xaa, 0x3e, 0xb4, + 0x1a, 0xef, 0xe9, 0x4a, 0x7a, 0x76, 0xe3, 0x66, 0x0c, 0x92, 0xf5, 0x06, + 0xcc, 0x39, 0x3d, 0x78, 0x84, 0x7a, 0x7e, 0xb0, 0x7d, 0xd5, 0xff, 0x20, + 0x07, 0x08, 0x68, 0x35, 0xbf, 0x04, 0xd8, 0xc6, 0x59, 0x67, 0xec, 0xa4, + 0x24, 0xfc, 0xce, 0x83, 0x4f, 0x44, 0x3e, 0xde, 0x86, 0xd4, 0x79, 0x9b, + 0xb0, 0xaf, 0x98, 0x4c, 0xf2, 0xa8, 0xe0, 0x1f, 0x47, 0x83, 0x85, 0x12, + 0xfb, 0x32, 0x01, 0x0a, 0x5a, 0xca, 0xc6, 0x92, 0x31, 0x8a, 0x45, 0x1a, + 0x3f, 0x57, 0x1f, 0xb8, 0x96, 0xe1, 0xfd, 0x20, 0xc8, 0x98, 0x54, 0x56, + 0x01, 0x27, 0x2a, 0x50, 0xcd, 0x0f, 0x9e, 0x36, 0xe2, 0x97, 0xae, 0x69, + 0x36, 0x86, 0x5e, 0x54, 0xcc, 0x68, 0x69, 0x73, 0x32, 0xdb, 0x56, 0xbf, + 0xfb, 0xa7, 0x66, 0x20, 0xd6, 0xcb, 0x06, 0x82, 0x07, 0x98, 0x46, 0x6f, + 0xb9, 0x61, 0xbe, 0x3d, 0x57, 0x3d, 0xed, 0x8f, 0x50, 0x2e, 0x56, 0x2f, + 0x37, 0x75, 0xed, 0x94, 0xc2, 0x72, 0x66, 0x91, 0x07, 0x95, 0xa5, 0x6d, + 0xf1, 0xb5, 0xaf, 0x8e, 0xd8, 0xcb, 0x20, 0x1a, 0x44, 0x09, 0xbc, 0xd0, + 0x13, 0x2c, 0x12, 0xb2, 0xa1, 0xf1, 0x3e, 0xda, 0x6b, 0x21, 0xad, 0x9d, + 0x53, 0x59, 0x33, 0x6e, 0x1a, 0x50, 0xb0, 0xc3, 0x19, 0x55, 0x31, 0x00, + 0x61, 0x7c, 0xa9, 0xe5, 0xf8, 0xb7, 0x7f, 0x2e, 0x8f, 0x9b, 0x6e, 0xd1, + 0x3a, 0x1c, 0x66, 0xd0, 0x65, 0xc3, 0x04, 0xe6, 0xe6, 0xf0, 0x98, 0x09, + 0x21, 0x95, 0xe2, 0x18, 0xa7, 0xb2, 0xbd, 0x90, 0x14, 0x05, 0x78, 0xcf, + 0x21, 0x65, 0xa1, 0x93, 0x47, 0x09, 0x15, 0xbe, 0x1f, 0x92, 0xf0, 0x15, + 0x32, 0x84, 0xd8, 0xe0, 0x22, 0x8c, 0xdc, 0xa3, 0x2f, 0x83, 0xf1, 0x43, + 0x14, 0x4c, 0x7e, 0xe1, 0xa0, 0x18, 0xef, 0x5f, 0xa2, 0x1b, 0xe6, 0x66, + 0x97, 0x2a, 0x3e, 0x2d, 0x7f, 0x80, 0x5a, 0x1b, 0xc7, 0x2e, 0x94, 0xdf, + 0x17, 0xe0, 0xfe, 0x8a, 0x77, 0x05, 0xc3, 0x3c, 0x33, 0x28, 0xc2, 0x90, + 0xc9, 0x66, 0x0a, 0x2a, 0x60, 0xa6, 0xec, 0x11, 0x9e, 0x54, 0xd2, 0x82, + 0x5f, 0xdc, 0x10, 0x88, 0x5b, 0x24, 0x6f, 0x4f, 0x69, 0x4a, 0xf5, 0xb8, + 0x5c, 0xac, 0xc6, 0xf7, 0x77, 0x35, 0x19, 0x81, 0x0a, 0x32, 0x0d, 0x92, + 0x11, 0xa3, 0xf1, 0xa2, 0xc8, 0x99, 0x4c, 0xb9, 0x43, 0x2d, 0x28, 0x4a, + 0xf5, 0x3e, 0x23, 0x36, 0x1d, 0xd1, 0xc3, 0x94, 0x87, 0xdc, 0x06, 0xfb, + 0x07, 0x78, 0x60, 0xed, 0x05, 0x2c, 0x9f, 0x65, 0x0f, 0xe5, 0x09, 0x53, + 0x9e, 0x84, 0x91, 0x66, 0x72, 0x4f, 0xc7, 0x1f, 0x05, 0xd6, 0x68, 0x7c, + 0x58, 0xd0, 0xcc, 0xd0, 0xec, 0xc2, 0x86, 0x98, 0x51, 0x7c, 0xa6, 0xa3, + 0x33, 0x56, 0xa1, 0x6f, 0xf1, 0xf8, 0x20, 0xcc, 0x48, 0xed, 0x46, 0xf2, + 0x69, 0x72, 0xf1, 0x72, 0x39, 0x69, 0x09, 0xde, 0x33, 0xf1, 0x54, 0x2b, + 0xcc, 0x4e, 0x3e, 0x52, 0x29, 0x11, 0xd8, 0x4f, 0x8f, 0x06, 0x60, 0xfd, + 0xdd, 0x5d, 0x34, 0xae, 0x37, 0xe6, 0x5c, 0x5e, 0x75, 0xc1, 0xd3, 0xbe, + 0x50, 0x24, 0xb6, 0xf7, 0x23, 0x87, 0xa5, 0xc3, 0x94, 0x12, 0xfc, 0x01, + 0xf7, 0xfb, 0xfb, 0x3b, 0xbe, 0x9e, 0xea, 0xce, 0x5e, 0x2e, 0xf5, 0xba, + 0x4f, 0x90, 0x5e, 0xa6, 0x8e, 0x4f, 0x4e, 0x84, 0x8d, 0x0f, 0x14, 0x61, + 0xf6, 0xe9, 0xd5, 0x5e, 0x6b, 0x35, 0x5b, 0xea, 0xba, 0xd0, 0x3b, 0xd4, + 0xb5, 0x33, 0x37, 0x63, 0xb7, 0x94, 0x98, 0x99, 0x4f, 0x2a, 0x7e, 0x3b, + 0x48, 0x1c, 0xeb, 0xb4, 0xa6, 0x9e, 0x76, 0x2b, 0xc2, 0x89, 0x3b, 0xf8, + 0x36, 0x55, 0xce, 0x57, 0x8d, 0xd0, 0x0b, 0xdd, 0x53, 0x34, 0xa0, 0x93, + 0x01, 0xb1, 0x80, 0x25, 0xa5, 0x51, 0xf1, 0x3d, 0x3e, 0xbc, 0xb3, 0x56, + 0x99, 0xb7, 0x12, 0xa1, 0x73, 0x23, 0x5f, 0x14, 0xf1, 0xb8, 0x83, 0x2e, + 0x73, 0x84, 0xf8, 0x82, 0xb4, 0x54, 0xcb, 0x4c, 0x6b, 0xdb, 0xf3, 0xf1, + 0x04, 0xad, 0x66, 0xb6, 0x7b, 0x9a, 0x25, 0x2c, 0x63, 0x80, 0xfb, 0x61, + 0x8c, 0x0d, 0x1e, 0xe0, 0x4e, 0xfe, 0x37, 0x63, 0x1e, 0x7a, 0x86, 0xfe, + 0xb7, 0x9d, 0x2b, 0x79, 0xd7, 0x9c, 0x0a, 0x0d, 0x35, 0x12, 0x40, 0x83, + 0x49, 0x55, 0x8c, 0x3d, 0x3a, 0xfb, 0x4a, 0x3e, 0xb6, 0xb6, 0xbb, 0xed, + 0x13, 0x6d, 0x2f, 0x9d, 0x95, 0x6e, 0xdc, 0xa9, 0x09, 0x9e, 0x7c, 0xfe, + 0x9c, 0xd5, 0xdd, 0x9d, 0xf3, 0x9e, 0xcf, 0xcb, 0xb9, 0x7e, 0xd7, 0x16, + 0xa2, 0x21, 0x08, 0x27, 0xa0, 0x8c, 0xb2, 0x20, 0x84, 0x6c, 0xee, 0xed, + 0xd3, 0x85, 0xee, 0x7c, 0x6d, 0xc1, 0x18, 0xf4, 0x55, 0x42, 0xa2, 0x29, + 0x55, 0x60, 0x27, 0xdb, 0xbd, 0x76, 0x26, 0x7a, 0x8f, 0x98, 0xcd, 0xa2, + 0xe9, 0xa9, 0x1e, 0xd0, 0x08, 0x4c, 0x26, 0xa8, 0x44, 0x61, 0x89, 0xab, + 0x01, 0xe1, 0xff, 0xb9, 0xbb, 0xc9, 0xc0, 0x14, 0xff, 0xfb, 0x38, 0xb7, + 0xcd, 0x04, 0xa1, 0xe5, 0x81, 0x38, 0xd8, 0x0a, 0x14, 0x6a, 0xd7, 0xe9, + 0x17, 0xb9, 0x25, 0xd0, 0xac, 0xff, 0x0b, 0xff, 0xb4, 0x60, 0xba, 0xbf, + 0x14, 0x9d, 0xee, 0x9b, 0xb3, 0x5c, 0x36, 0xe1, 0x1b, 0x07, 0x70, 0xec, + 0x25, 0x04, 0x03, 0x5e, 0x1d, 0x64, 0x4d, 0x3a, 0xb0, 0xdb, 0xab, 0x34, + 0xf4, 0xff, 0xbc, 0xb0, 0xda, 0x45, 0xa4, 0x96, 0x4f, 0xd8, 0x9b, 0x81, + 0x7f, 0xcd, 0x7e, 0xb6, 0xfb, 0x82, 0x4d, 0x88, 0x35, 0x25, 0x6c, 0x64, + 0x17, 0x97, 0x02, 0x29, 0x14, 0x92, 0x11, 0xf3, 0x2f, 0xf5, 0x69, 0x5c, + 0x40, 0x36, 0x9c, 0xf0, 0x29, 0xc3, 0x40, 0xb6, 0x58, 0x14, 0x27, 0x31, + 0x42, 0x0a, 0xcd, 0x12, 0x7b, 0x83, 0x82, 0x79, 0x2d, 0x7f, 0x1d, 0x07, + 0x43, 0x8e, 0x96, 0x8c, 0x98, 0xa0, 0xf3, 0xcf, 0x90, 0x4e, 0x1f, 0x77, + 0x4a, 0x95, 0xaf, 0x3e, 0x8d, 0x81, 0x9f, 0x79, 0x66, 0x73, 0x92, 0x43, + 0xb8, 0x07, 0x8b, 0xba, 0xc1, 0xaf, 0xbd, 0xee, 0x7f, 0x99, 0xbf, 0x1c, + 0xde, 0x07, 0xac, 0xb2, 0x24, 0x83, 0xb2, 0x38, 0x76, 0xca, 0xf0, 0xdc, + 0x5a, 0xf6, 0xf7, 0xfd, 0xdc, 0xb8, 0xc4, 0xf6, 0xc4, 0x50, 0xe3, 0x48, + 0x11, 0x4e, 0x64, 0xbd, 0xa7, 0x2e, 0x73, 0x94, 0xaa, 0xc3, 0xe2, 0x3d, + 0xec, 0x8f, 0xb7, 0xff, 0xe3, 0x30, 0xbe, 0x4e, 0x5d, 0x0d, 0xb1, 0xa1, + 0xe9, 0xfb, 0x29, 0x07, 0xd8, 0x37, 0xd1, 0xd7, 0xea, 0x2e, 0x3f, 0x5c, + 0x3a, 0xf0, 0xa9, 0x75, 0xd9, 0x5d, 0x54, 0xbf, 0x2f, 0x9e, 0x9d, 0x2b, + 0x73, 0x97, 0xe1, 0x88, 0x5c, 0xe2, 0xe2, 0xa2, 0xd8, 0xe4, 0xbc, 0xe4, + 0xa3, 0x0c, 0x30, 0x25, 0x77, 0x00, 0x88, 0xea, 0x97, 0x2b, 0xfe, 0xae, + 0xdd, 0xdd, 0x6a, 0x16, 0x26, 0x40, 0xa9, 0xc4, 0x03, 0x2d, 0x89, 0x82, + 0x06, 0x9a, 0x33, 0xbd, 0x3e, 0x20, 0x8e, 0xc5, 0x8b, 0x63, 0xda, 0xf5, + 0xed, 0xaf, 0x83, 0xfd, 0xd8, 0x65, 0x62, 0x0e, 0xd2, 0x72, 0xa3, 0x0a, + 0x1d, 0x90, 0xeb, 0x8e, 0xdd, 0xf7, 0x58, 0xdf, 0x8f, 0x65, 0xec, 0x3b, + 0x5c, 0x18, 0x8c, 0xb6, 0x22, 0x4a, 0x7d, 0x63, 0x90, 0xc0, 0x9c, 0x3c, + 0x9c, 0x65, 0x04, 0x7e, 0xc3, 0xe7, 0xa5, 0x12, 0x57, 0x96, 0x63, 0x31, + 0xeb, 0xe6, 0x29, 0x9e, 0xdc, 0xab, 0x30, 0x3b, 0x18, 0x58, 0x38, 0x28, + 0x20, 0x40, 0x3e, 0x01, 0x56, 0x41, 0xe2, 0xf2, 0x3f, 0x7b, 0xf3, 0x37, + 0x60, 0x53, 0x14, 0xd6, 0x75, 0xe8, 0xb1, 0xfe, 0xb7, 0x06, 0x1b, 0x7c, + 0x36, 0x36, 0xcc, 0x88, 0x94, 0xf5, 0x03, 0x89, 0x09, 0x42, 0x3e, 0x8b, + 0x8d, 0x58, 0xfd, 0x5c, 0xcd, 0x2f, 0xd9, 0x96, 0xcd, 0xd7, 0x3d, 0x9d, + 0x88, 0x13, 0x91, 0x16, 0x31, 0x38, 0xaf, 0x47, 0xb5, 0xbd, 0x88, 0x48, + 0xfd, 0x2f, 0x39, 0xa5, 0xe0, 0x59, 0x31, 0x52, 0x99, 0xbf, 0x23, 0x72, + 0x3b, 0xf5, 0xbb, 0xd7, 0xdd, 0xda, 0xa6, 0x26, 0x0d, 0x4c, 0x8d, 0x13, + 0x93, 0xda, 0x52, 0x43, 0x22, 0x02, 0xa1, 0x66, 0xb8, 0x71, 0x7c, 0xad, + 0x57, 0x9b, 0x65, 0x53, 0x2b, 0x32, 0xa7, 0x04, 0xd1, 0x0c, 0x8e, 0x34, + 0xf2, 0xcf, 0x88, 0x3c, 0xd2, 0xd1, 0x9f, 0x17, 0xfd, 0x4e, 0x2d, 0xb7, + 0x62, 0xac, 0x9d, 0xef, 0xb4, 0x96, 0x1b, 0x52, 0x94, 0x16, 0x69, 0xa6, + 0x65, 0xa4, 0xac, 0x04, 0x94, 0x4f, 0x89, 0xd3, 0x7d, 0xde, 0xe1, 0xba, + 0xd3, 0x2d, 0x8f, 0x05, 0x19, 0xa2, 0x89, 0x92, 0x3f, 0x10, 0xce, 0xb0, + 0xf9, 0x5e, 0xfb, 0x3c, 0xb6, 0x59, 0xe5, 0xab, 0xb0, 0x21, 0x7d, 0xb3, + 0x57, 0xf2, 0x82, 0xbf, 0x63, 0xce, 0x0c, 0x00, 0x16, 0x7e, 0xdb, 0x22, + 0x0c, 0xb1, 0xa4, 0x72, 0x49, 0x1f, 0xb4, 0x4f, 0x51, 0xb0, 0xe9, 0xba, + 0x69, 0xb7, 0x6a, 0xc8, 0xc4, 0x57, 0xfc, 0x94, 0xa1, 0xf4, 0x93, 0xd9, + 0x02, 0xe3, 0xde, 0xde, 0x7f, 0x6a, 0x19, 0x52, 0xa2, 0xd0, 0xc1, 0x87, + 0x40, 0xe3, 0x00, 0x52, 0xf6, 0x04, 0x85, 0x64, 0xc5, 0xd5, 0xa7, 0x98, + 0x36, 0xea, 0x7c, 0xce, 0x84, 0x32, 0x93, 0x1c, 0x95, 0x06, 0x38, 0x4b, + 0xe1, 0xa3, 0xf0, 0x22, 0x4f, 0x3e, 0xa4, 0x0c, 0x19, 0x2f, 0x70, 0x0b, + 0x50, 0x8a, 0x9a, 0x2d, 0x87, 0x5f, 0xc6, 0xa8, 0x6c, 0xa8, 0xd7, 0xa1, + 0x46, 0x02, 0xe8, 0x22, 0x4d, 0x01, 0x29, 0x19, 0x7c, 0xf2, 0xdf, 0xcd, + 0xdc, 0xbb, 0xce, 0x11, 0x93, 0x4a, 0xca, 0x95, 0x58, 0x24, 0x6d, 0x7f, + 0xf3, 0xd2, 0xdd, 0x16, 0xcb, 0x1f, 0x3c, 0xeb, 0xce, 0x8a, 0x24, 0x44, + 0xb4, 0xfb, 0x12, 0x46, 0x61, 0x12, 0x32, 0x91, 0xab, 0x27, 0x49, 0x3f, + 0x31, 0x13, 0xae, 0xba, 0x4f, 0x6f, 0x0a, 0x39, 0x7a, 0xc6, 0x9e, 0x43, + 0x1f, 0x34, 0x56, 0x00, 0xf1, 0xad, 0x68, 0x63, 0xa5, 0x51, 0x03, 0x09, + 0x38, 0xd9, 0x1e, 0xdf, 0xd8, 0x39, 0xd7, 0x07, 0x6c, 0x77, 0x51, 0xb8, + 0x6a, 0xf6, 0x82, 0x3b, 0x46, 0x58, 0xd5, 0x69, 0xd1, 0xf7, 0xf3, 0xef, + 0xb8, 0xf7, 0xb8, 0x7f, 0xc7, 0x7f, 0x8f, 0xeb, 0xb1, 0xe6, 0x3d, 0x1a, + 0xcb, 0x0a, 0xc7, 0x0d, 0x3a, 0xbe, 0xb3, 0x2d, 0x00, 0x52, 0x89, 0x85, + 0xf2, 0x08, 0x50, 0xad, 0xfc, 0x50, 0xa0, 0x25, 0x0f, 0x02, 0x78, 0x82, + 0x9f, 0xf2, 0x56, 0x86, 0x81, 0x9b, 0xb9, 0x9e, 0x49, 0x23, 0xe2, 0xd3, + 0x3b, 0x28, 0x9c, 0x32, 0x18, 0x07, 0xcf, 0x32, 0xbc, 0x2f, 0xe4, 0xa0, + 0xbc, 0x68, 0x08, 0x94, 0x01, 0xe1, 0x0f, 0x33, 0x43, 0x27, 0xf1, 0x68, + 0x8f, 0xb0, 0xcf, 0x3e, 0x27, 0x2d, 0xd4, 0xd3, 0x2f, 0x3e, 0x17, 0xa9, + 0x49, 0xa6, 0x08, 0x9a, 0x04, 0xd0, 0xc8, 0xa4, 0xb9, 0xd6, 0x98, 0xdd, + 0x37, 0xe2, 0x9c, 0xe7, 0x3c, 0x49, 0xc0, 0x58, 0xd4, 0x4e, 0x8e, 0x5f, + 0xc7, 0xf5, 0x7e, 0x6f, 0xcb, 0x3c, 0x28, 0x4b, 0x58, 0x78, 0x00, 0xa0, + 0x27, 0x94, 0x12, 0x87, 0x81, 0x67, 0x14, 0x10, 0x82, 0x89, 0xc9, 0xcc, + 0x4e, 0x85, 0xdd, 0x5a, 0xeb, 0x11, 0xc9, 0x08, 0x28, 0xa9, 0x86, 0x39, + 0x8c, 0x1b, 0x08, 0x16, 0xc7, 0xfb, 0xb4, 0xd3, 0x98, 0x9f, 0xd5, 0xe8, + 0x3e, 0x41, 0x30, 0x4b, 0x2c, 0x29, 0x02, 0x4f, 0x81, 0xbf, 0xd1, 0xeb, + 0x55, 0x7e, 0xc2, 0xcb, 0x84, 0xc1, 0x4f, 0x5c, 0xac, 0x59, 0x94, 0x94, + 0xb7, 0x86, 0x7f, 0x31, 0xf6, 0xb8, 0xd7, 0x0b, 0x22, 0x7c, 0x47, 0x6c, + 0xd0, 0xa8, 0xff, 0x6f, 0x82, 0x63, 0x17, 0x6c, 0xa8, 0x09, 0x48, 0x4b, + 0xc1, 0xab, 0x50, 0xda, 0xa3, 0xaf, 0xfa, 0xe4, 0x2f, 0x7c, 0x83, 0xa4, + 0x8e, 0xc0, 0xd5, 0xec, 0x70, 0xef, 0x24, 0x8e, 0xe1, 0x2f, 0x29, 0x64, + 0xef, 0x58, 0xc2, 0xea, 0xf1, 0xe1, 0xb3, 0xce, 0xa9, 0xd4, 0x62, 0x89, + 0x96, 0x42, 0x9c, 0xa6, 0x72, 0x21, 0x2c, 0xe0, 0xef, 0x9d, 0xbd, 0x6d, + 0x7f, 0xf8, 0xa7, 0x5e, 0x0f, 0xb2, 0xcb, 0x61, 0x24, 0x51, 0x80, 0x91, + 0x02, 0x54, 0x12, 0x33, 0xfa, 0x3b, 0x2a, 0x38, 0xb7, 0x97, 0xc0, 0x5b, + 0x42, 0x8d, 0xed, 0xf8, 0xc8, 0x93, 0x96, 0x0c, 0x14, 0x72, 0xa7, 0x3b, + 0xd6, 0xa3, 0xf7, 0xf9, 0xff, 0x79, 0xd9, 0x9b, 0x63, 0x83, 0xa4, 0x08, + 0x67, 0x13, 0x48, 0xa5, 0xe3, 0x9a, 0x13, 0xee, 0x21, 0xab, 0x97, 0x69, + 0xc3, 0xd0, 0xe8, 0x6b, 0x23, 0x44, 0x23, 0x7b, 0x47, 0x0e, 0x0a, 0x52, + 0x47, 0xed, 0x2e, 0xe2, 0x5c, 0x6e, 0x75, 0x68, 0xea, 0xf6, 0x02, 0x70, + 0xf4, 0x86, 0x32, 0xe7, 0x34, 0x32, 0x11, 0xc9, 0xca, 0x85, 0x64, 0x3d, + 0x2b, 0x5a, 0x80, 0x71, 0x0c, 0x09, 0x78, 0xa6, 0x11, 0xf1, 0x10, 0x4a, + 0xac, 0x11, 0x03, 0x32, 0x7c, 0xca, 0x80, 0xba, 0x99, 0x92, 0xb2, 0xdd, + 0x92, 0xfd, 0x33, 0xfb, 0x69, 0x6d, 0x45, 0x0b, 0x76, 0xb7, 0x03, 0x0c, + 0x84, 0xa6, 0x52, 0x89, 0x22, 0x85, 0xe9, 0xc2, 0x14, 0xe4, 0x4d, 0xa5, + 0x39, 0xe5, 0x05, 0x09, 0x81, 0x97, 0x0e, 0x52, 0x57, 0xc7, 0x3e, 0x8b, + 0xec, 0x3d, 0x3d, 0x41, 0xb9, 0x41, 0x23, 0xb2, 0x61, 0x91, 0x9c, 0x25, + 0x02, 0xe5, 0x1c, 0xa1, 0x3f, 0xb1, 0xab, 0x31, 0x45, 0xe8, 0x97, 0xdb, + 0x97, 0x9d, 0x19, 0x40, 0x86, 0x5a, 0x43, 0x09, 0x2b, 0xd1, 0x14, 0x3e, + 0x2e, 0x5f, 0xa6, 0xaa, 0x2c, 0x85, 0x10, 0x68, 0x20, 0x91, 0xf9, 0xc4, + 0xa7, 0x3f, 0x98, 0x37, 0xa7, 0xe7, 0x82, 0xff, 0x18, 0xb4, 0x38, 0x71, + 0x43, 0x00, 0x09, 0x59, 0x82, 0x4d, 0xad, 0xbf, 0x59, 0xe7, 0x71, 0x0b, + 0x09, 0x98, 0x34, 0xd8, 0xee, 0xe4, 0x19, 0x48, 0x37, 0x6a, 0x51, 0x95, + 0x60, 0x0a, 0xb4, 0x39, 0x05, 0xc3, 0x21, 0x94, 0x8a, 0x18, 0x0a, 0x11, + 0xa0, 0x04, 0x4c, 0xde, 0xad, 0xe3, 0x5c, 0xe3, 0x5e, 0x5b, 0xa3, 0xba, + 0x46, 0xbf, 0x63, 0xa1, 0x50, 0xf2, 0x0d, 0xe5, 0xd5, 0x4f, 0xc8, 0xf1, + 0x5c, 0xde, 0xa2, 0x83, 0xec, 0xcf, 0x3d, 0x5e, 0xfe, 0x56, 0xf3, 0xad, + 0xe5, 0x57, 0x92, 0xc9, 0xa5, 0x25, 0x4d, 0x97, 0x22, 0x11, 0x67, 0x62, + 0x4b, 0x46, 0x58, 0x97, 0xd0, 0x13, 0x6f, 0x7f, 0xa7, 0xe5, 0x62, 0xf3, + 0xc3, 0x00, 0x95, 0x48, 0x69, 0x25, 0x81, 0x7f, 0xc1, 0xee, 0xb0, 0x58, + 0x6d, 0x79, 0x9f, 0x53, 0x9e, 0xa8, 0xbb, 0x93, 0x90, 0xc2, 0x08, 0x0a, + 0x22, 0x53, 0xab, 0x53, 0x26, 0x7c, 0xbc, 0x26, 0x9f, 0xe2, 0xc8, 0x78, + 0x75, 0x3b, 0x08, 0x54, 0xf2, 0x86, 0x44, 0x63, 0x6c, 0x48, 0x9c, 0x67, + 0xee, 0x3e, 0x01, 0xf0, 0xb6, 0x6c, 0x8d, 0xf9, 0x22, 0xb8, 0xbe, 0xfe, + 0xb5, 0x7d, 0xda, 0x99, 0x7b, 0xa5, 0x3c, 0x60, 0x8d, 0x24, 0xb1, 0x40, + 0xf7, 0x26, 0x7e, 0x2b, 0x40, 0x4f, 0x67, 0x4d, 0x90, 0xe6, 0x43, 0x7c, + 0x53, 0x58, 0x2e, 0x09, 0x3d, 0x89, 0xff, 0xb7, 0x76, 0x5f, 0x8d, 0xf9, + 0x85, 0x92, 0xe1, 0xbb, 0x50, 0x3b, 0x5e, 0x50, 0x46, 0x7d, 0xa3, 0x1a, + 0x00, 0x7d, 0x85, 0xd1, 0xce, 0x62, 0x79, 0xf3, 0xaa, 0x93, 0x23, 0x39, + 0xb8, 0x2a, 0x09, 0x13, 0x94, 0x32, 0x7e, 0x2e, 0xbb, 0x7d, 0x05, 0x4d, + 0x25, 0x05, 0x53, 0xfd, 0x4d, 0xb8, 0x69, 0xe3, 0xb1, 0x6a, 0x8f, 0x44, + 0x20, 0x46, 0x4e, 0x7e, 0x07, 0x57, 0x7e, 0xe5, 0xad, 0xfb, 0xcf, 0x79, + 0xed, 0xd7, 0x09, 0x27, 0xaa, 0x0f, 0x5f, 0xd3, 0xd1, 0x0c, 0xc0, 0xc9, + 0x95, 0xa9, 0x63, 0x0e, 0xe0, 0x43, 0xa4, 0x77, 0x40, 0xfc, 0xda, 0xa7, + 0x7d, 0xb6, 0xd4, 0x35, 0xd9, 0x9e, 0x4f, 0x62, 0x45, 0x2b, 0x62, 0x84, + 0x86, 0xe7, 0x07, 0x70, 0xbb, 0xef, 0x7e, 0x0b, 0x7e, 0xe3, 0xa3, 0xc0, + 0x74, 0xc0, 0x1d, 0xf0, 0xe5, 0x18, 0x00, 0x08, 0x83, 0x40, 0xe5, 0xca, + 0x58, 0x4b, 0x7c, 0x36, 0x76, 0x29, 0x65, 0x05, 0x49, 0xf7, 0xdf, 0xe5, + 0x44, 0xe7, 0x71, 0x74, 0xe7, 0x83, 0x7b, 0x53, 0x0d, 0x3a, 0x78, 0xf2, + 0x40, 0x22, 0x11, 0x4b, 0x97, 0x88, 0xae, 0xec, 0xa7, 0x3f, 0x21, 0x5a, + 0x81, 0x9e, 0x9f, 0x4b, 0x7d, 0xb1, 0xa2, 0xa7, 0x08, 0x96, 0x70, 0x96, + 0xc6, 0xb1, 0x6a, 0x36, 0xe2, 0x15, 0x75, 0xb0, 0xca, 0x95, 0x7e, 0x45, + 0xc0, 0x45, 0xb2, 0xb4, 0x6b, 0xc3, 0x0c, 0x28, 0x25, 0x64, 0xfe, 0xa2, + 0x15, 0x03, 0x3f, 0xaa, 0xde, 0xf2, 0xb5, 0xed, 0xe4, 0x03, 0x38, 0x37, + 0xb2, 0x48, 0xa0, 0x8b, 0x60, 0x28, 0xcb, 0x2d, 0xa7, 0x84, 0x2e, 0x2d, + 0xe3, 0x0a, 0x37, 0x36, 0xca, 0x1a, 0xaa, 0x03, 0xb4, 0x2f, 0xe5, 0xad, + 0xf7, 0xc9, 0x0f, 0x8b, 0xab, 0x47, 0x66, 0xcb, 0x99, 0x83, 0x52, 0xc7, + 0xa0, 0x96, 0x2a, 0xc3, 0x17, 0xbf, 0xe0, 0x62, 0xde, 0xe2, 0x1d, 0x21, + 0x0b, 0x4f, 0x1d, 0x0c, 0x97, 0xda, 0x8b, 0xc2, 0x9e, 0xea, 0x1e, 0xd5, + 0x88, 0x1b, 0x4e, 0xec, 0xca, 0xd0, 0x08, 0x0d, 0x20, 0x65, 0x29, 0x48, + 0x7c, 0xc0, 0x9f, 0xce, 0x3a, 0xaf, 0xe2, 0x5b, 0xfd, 0xfc, 0xb7, 0x63, + 0xbd, 0x6c, 0x40, 0x10, 0xab, 0xda, 0x72, 0xce, 0x88, 0xca, 0x1f, 0x6d, + 0x49, 0x02, 0x76, 0x22, 0x5a, 0x27, 0xe2, 0x82, 0xa3, 0x9f, 0xdb, 0xdd, + 0xa6, 0xfc, 0x09, 0xd6, 0xce, 0xec, 0xde, 0xe9, 0x34, 0xe0, 0x76, 0xa3, + 0x33, 0x29, 0x83, 0x4d, 0xd0, 0x39, 0x04, 0x19, 0xdf, 0xb5, 0x4f, 0xd8, + 0x29, 0xe5, 0x21, 0xba, 0x63, 0x67, 0x73, 0x40, 0x13, 0xbc, 0x3d, 0x39, + 0x94, 0x21, 0x28, 0x43, 0x59, 0x13, 0xe2, 0x7b, 0xdc, 0xb8, 0x0e, 0x75, + 0xdd, 0x96, 0x7d, 0x63, 0x52, 0xd9, 0x9b, 0x8d, 0xb1, 0xa0, 0x8f, 0x81, + 0x7e, 0x5f, 0x67, 0xfe, 0xae, 0x20, 0x58, 0xb3, 0x54, 0xe1, 0x9c, 0x98, + 0x3b, 0xed, 0x13, 0x2c, 0x47, 0x91, 0x38, 0x05, 0x0c, 0x24, 0x20, 0x03, + 0xc7, 0x83, 0x2f, 0xde, 0x76, 0xd3, 0xa1, 0xfc, 0x83, 0x65, 0xc2, 0xae, + 0xc6, 0x7f, 0xda, 0x0d, 0x68, 0xa1, 0x03, 0xce, 0x54, 0x75, 0x97, 0xe1, + 0x46, 0x7c, 0xd7, 0x9b, 0x9e, 0x0f, 0xed, 0x17, 0xb1, 0xf9, 0x7a, 0x86, + 0xc5, 0x54, 0x8b, 0xd3, 0x92, 0xac, 0x91, 0x83, 0x1e, 0xa2, 0x81, 0xcc, + 0xe8, 0x94, 0x3e, 0xaf, 0x17, 0x33, 0x37, 0x2f, 0x2b, 0x1f, 0x88, 0x75, + 0x27, 0x84, 0xda, 0x89, 0x72, 0x10, 0x9a, 0x13, 0x03, 0x19, 0x9e, 0x69, + 0x1f, 0x03, 0x3a, 0xb4, 0x2b, 0xaf, 0x1c, 0xf4, 0x4e, 0xf4, 0x26, 0xc6, + 0x14, 0x02, 0xf4, 0x4c, 0x2d, 0x90, 0xe5, 0x8c, 0x95, 0x8f, 0xf5, 0xf9, + 0x1e, 0x38, 0x1f, 0xc7, 0x57, 0x45, 0xdd, 0xab, 0x14, 0x24, 0x1e, 0x16, + 0xf3, 0x1c, 0x7b, 0xeb, 0x60, 0x3e, 0xa9, 0x75, 0xe4, 0xbd, 0xe7, 0xa7, + 0x66, 0x72, 0x2e, 0xec, 0xa1, 0x6a, 0x9d, 0xc9, 0x3c, 0x79, 0xb4, 0x07, + 0x95, 0x48, 0x88, 0x21, 0xa1, 0xf5, 0x33, 0x26, 0x34, 0x54, 0xf3, 0xc5, + 0x44, 0x1a, 0x61, 0xea, 0x27, 0x82, 0x84, 0xe4, 0x7e, 0xa9, 0x06, 0x1e, + 0x49, 0xc7, 0x1a, 0x62, 0x8c, 0x84, 0x33, 0x79, 0xcd, 0xa5, 0xb3, 0xb9, + 0x4f, 0x1d, 0x1f, 0xab, 0x89, 0x3b, 0xbc, 0x08, 0x64, 0x78, 0x31, 0xd1, + 0x9d, 0x5e, 0x60, 0x8a, 0x08, 0xf7, 0x31, 0xe7, 0xb3, 0x88, 0x65, 0x73, + 0x01, 0x46, 0x02, 0x8c, 0xcc, 0xa4, 0x8a, 0x07, 0x2e, 0x59, 0x5f, 0x3c, + 0x16, 0xcc, 0xda, 0x51, 0x69, 0x04, 0x20, 0xd5, 0x14, 0x8c, 0x26, 0x34, + 0xbe, 0x39, 0x00, 0x8c, 0x60, 0xc6, 0x83, 0xd0, 0x93, 0x99, 0xf7, 0x29, + 0x81, 0x0c, 0x31, 0x21, 0x0f, 0x32, 0xc7, 0x00, 0x48, 0x25, 0x9f, 0xb3, + 0x84, 0x89, 0xe1, 0x3e, 0x90, 0xf8, 0x0d, 0x66, 0x4e, 0xed, 0xc5, 0x3e, + 0xd3, 0x14, 0xce, 0x55, 0x3e, 0xf6, 0x0d, 0xc5, 0x6d, 0xe3, 0xad, 0x68, + 0x8a, 0x07, 0x19, 0xf1, 0x8a, 0xca, 0x28, 0xf3, 0x6b, 0x54, 0x31, 0x97, + 0x8c, 0xf2, 0x90, 0xc2, 0x17, 0xef, 0x13, 0x63, 0x8d, 0xbd, 0x29, 0x8a, + 0x46, 0x48, 0x63, 0xe5, 0xa5, 0x65, 0xf8, 0x19, 0x92, 0xc5, 0x6d, 0x3a, + 0x95, 0xd9, 0xce, 0xdc, 0x03, 0x01, 0x9c, 0x28, 0x55, 0x32, 0x49, 0x24, + 0x0f, 0x39, 0x5d, 0x66, 0x55, 0xac, 0x5b, 0x4d, 0xc3, 0xa7, 0xe7, 0x70, + 0x9c, 0x57, 0x42, 0xbc, 0x95, 0xa6, 0xa2, 0xc0, 0xa2, 0x4f, 0x64, 0xef, + 0x38, 0x20, 0xce, 0x2a, 0x0b, 0xf1, 0x74, 0x7f, 0x6f, 0x94, 0xf7, 0xac, + 0xa0, 0xaf, 0xd3, 0x97, 0xbc, 0xb5, 0x8a, 0x81, 0x18, 0xd8, 0x74, 0x28, + 0x50, 0xf9, 0xfe, 0xdb, 0x69, 0x9a, 0xfc, 0xb5, 0x3a, 0xbc, 0xa2, 0x89, + 0x74, 0xb3, 0x92, 0xf0, 0x05, 0x5f, 0xde, 0xd1, 0x0b, 0xea, 0xc1, 0x23, + 0x31, 0x87, 0xed, 0x24, 0x67, 0x38, 0x00, 0x3f, 0x38, 0xde, 0xba, 0x70, + 0xbc, 0x57, 0x90, 0x30, 0xa0, 0x66, 0x32, 0x53, 0x43, 0xb2, 0x78, 0x50, + 0xf3, 0x28, 0x06, 0xf9, 0x94, 0xba, 0x7b, 0xbd, 0xf6, 0x7b, 0x6f, 0xfd, + 0xce, 0x5f, 0xae, 0xc3, 0x1c, 0x3f, 0x4b, 0x66, 0x25, 0xa2, 0x27, 0x49, + 0xe6, 0xed, 0x0a, 0x22, 0x84, 0xeb, 0x22, 0xf8, 0xf6, 0xb3, 0xf1, 0xdf, + 0x9b, 0xa7, 0x17, 0x07, 0x28, 0xd3, 0xc4, 0x93, 0x46, 0x41, 0x06, 0x19, + 0x39, 0x04, 0x7c, 0x41, 0x16, 0x66, 0xf0, 0x7b, 0x0a, 0x6e, 0x3b, 0xc7, + 0x3a, 0xc9, 0x3e, 0x3d, 0x5d, 0x2f, 0x4d, 0xdd, 0xea, 0x14, 0x0e, 0x50, + 0x22, 0x8e, 0x2e, 0x1f, 0x64, 0x4f, 0x0d, 0x58, 0x07, 0x37, 0x5d, 0x84, + 0x45, 0x69, 0xdc, 0x43, 0xa8, 0x18, 0xd3, 0x92, 0x32, 0x42, 0x68, 0x1a, + 0xb1, 0x4b, 0x16, 0x70, 0xab, 0x94, 0xa2, 0x89, 0xd6, 0xdc, 0xf7, 0x5f, + 0xe0, 0x0f, 0xf6, 0xd7, 0x3a, 0xe6, 0x1e, 0x46, 0xca, 0x30, 0xa9, 0xa1, + 0x90, 0x32, 0xa0, 0x5f, 0x88, 0x27, 0x41, 0x1f, 0xa8, 0x34, 0xd9, 0xe7, + 0x49, 0x27, 0x68, 0xba, 0x5b, 0x1d, 0x75, 0x13, 0xc9, 0x9c, 0x96, 0x4f, + 0xc1, 0x37, 0x39, 0xdf, 0xae, 0x4d, 0x6b, 0xe4, 0x84, 0x63, 0x11, 0xf1, + 0x50, 0x08, 0xf8, 0xc8, 0x50, 0xb1, 0xbe, 0xdf, 0x52, 0x69, 0x89, 0x8a, + 0x9d, 0xb9, 0x96, 0x30, 0x23, 0x22, 0x18, 0x43, 0x8a, 0xf4, 0xbb, 0x46, + 0xed, 0x72, 0x67, 0x08, 0x5c, 0x7a, 0x9f, 0xa8, 0x18, 0xf8, 0xc1, 0x21, + 0x34, 0x67, 0xe9, 0xfa, 0xad, 0xc8, 0x53, 0x18, 0x50, 0x12, 0xa1, 0x21, + 0x33, 0x92, 0xf0, 0x89, 0xf5, 0x65, 0xfc, 0xba, 0x8a, 0x18, 0xba, 0xba, + 0x66, 0x06, 0x3e, 0x64, 0x68, 0xb6, 0x83, 0xcf, 0x79, 0x75, 0xf9, 0x90, + 0x86, 0x4b, 0xc5, 0x5f, 0xff, 0x6c, 0xa3, 0xab, 0x8a, 0x43, 0x28, 0xf4, + 0x7d, 0x4e, 0x69, 0x13, 0x30, 0x32, 0xea, 0xf4, 0xea, 0xd8, 0xc7, 0xf4, + 0xcb, 0xff, 0x4b, 0xd3, 0x8a, 0x36, 0x0c, 0xf0, 0x1f, 0x01, 0x4c, 0xd7, + 0x41, 0x20, 0xc4, 0xde, 0xc7, 0xa5, 0x76, 0xf0, 0x65, 0xf3, 0x03, 0x10, + 0x8e, 0xda, 0x7f, 0xd9, 0x89, 0x47, 0xce, 0x11, 0x88, 0x45, 0x36, 0x9d, + 0x4c, 0x65, 0x5b, 0xea, 0xc5, 0xe5, 0x87, 0x75, 0x29, 0xd4, 0xff, 0x15, + 0x4f, 0x7a, 0x3c, 0x4d, 0x07, 0x62, 0x8e, 0xab, 0x73, 0x26, 0x50, 0x02, + 0xc6, 0x11, 0xf3, 0x34, 0x3b, 0x82, 0x52, 0xb1, 0xe1, 0x64, 0x9e, 0x9b, + 0xff, 0x10, 0x40, 0x08, 0x0e, 0x34, 0x01, 0x33, 0x82, 0x6f, 0x4b, 0x46, + 0x80, 0x42, 0xb2, 0xb1, 0x45, 0xdd, 0xed, 0x99, 0x39, 0x18, 0x28, 0xbc, + 0xa8, 0xe1, 0xf1, 0x90, 0x4b, 0xfa, 0xf2, 0x6a, 0x9c, 0xa2, 0x06, 0xdc, + 0xfe, 0x97, 0x20, 0x51, 0x24, 0xb8, 0x07, 0x1a, 0x1c, 0x7d, 0xa4, 0x7b, + 0x68, 0x93, 0x9e, 0x2e, 0x4c, 0x3b, 0xd9, 0xae, 0x77, 0x97, 0x40, 0xd2, + 0xd4, 0x92, 0x51, 0x39, 0x2a, 0x19, 0x10, 0x05, 0x91, 0xfc, 0x7f, 0x96, + 0x34, 0x80, 0x4b, 0x8c, 0x0c, 0x61, 0x46, 0x8f, 0xd1, 0xf7, 0x62, 0xad, + 0x6a, 0xfd, 0x78, 0xb9, 0x9d, 0x45, 0x8c, 0x95, 0x44, 0x21, 0xdc, 0x35, + 0xa9, 0x92, 0x31, 0xb5, 0x06, 0x1a, 0x79, 0x46, 0x16, 0x28, 0x51, 0x4b, + 0x48, 0x56, 0x68, 0x31, 0x45, 0x46, 0xcd, 0x05, 0x0a, 0x18, 0x7c, 0x9f, + 0x64, 0xec, 0xb6, 0x6a, 0xf4, 0xed, 0x0f, 0x86, 0xd0, 0x28, 0x24, 0x5e, + 0x86, 0x1c, 0xa5, 0x61, 0x03, 0x95, 0x39, 0x40, 0x17, 0xf9, 0x82, 0xd3, + 0xf8, 0xc5, 0x2a, 0x8c, 0xde, 0x73, 0xc3, 0x7a, 0x7b, 0x91, 0x61, 0x86, + 0x83, 0x09, 0xcf, 0xb0, 0x74, 0x3e, 0x7a, 0xc7, 0xe6, 0x76, 0x47, 0x2a, + 0xf4, 0x7c, 0xe7, 0x0c, 0xc2, 0x63, 0x64, 0xc6, 0x57, 0x80, 0x17, 0x08, + 0x14, 0x17, 0xe7, 0x21, 0xdb, 0x66, 0x54, 0x18, 0x88, 0x0b, 0x65, 0x42, + 0x97, 0x46, 0x7d, 0x91, 0x26, 0x5e, 0x59, 0x3c, 0x48, 0x06, 0xbc, 0x20, + 0x66, 0x89, 0x39, 0x64, 0xd6, 0x5a, 0x7a, 0x05, 0x10, 0x89, 0x44, 0x4a, + 0x73, 0x98, 0x3e, 0x9f, 0xb0, 0xc3, 0x3c, 0xea, 0x77, 0x95, 0xc6, 0xc5, + 0x5b, 0x08, 0x07, 0x2b, 0xaa, 0x63, 0x25, 0x4c, 0xf6, 0xa7, 0x08, 0xf9, + 0x42, 0x4c, 0xc7, 0xa9, 0xe9, 0x58, 0x0a, 0x9e, 0x4a, 0x0e, 0xf6, 0x2b, + 0xf5, 0x35, 0x20, 0x55, 0x65, 0x46, 0xda, 0x32, 0xdc, 0xb5, 0x29, 0x4a, + 0x79, 0x2a, 0x1e, 0x20, 0xa3, 0x3f, 0xfb, 0x5c, 0xf7, 0xce, 0x5f, 0x3b, + 0x96, 0xb9, 0x16, 0xf4, 0x6f, 0xe9, 0x5b, 0x63, 0x86, 0x85, 0xbe, 0x7f, + 0xe8, 0x3b, 0x30, 0xdb, 0xc0, 0xd4, 0xeb, 0xf8, 0xcd, 0x40, 0x4e, 0x72, + 0x1f, 0x37, 0x74, 0xb7, 0x28, 0x93, 0xe2, 0x0d, 0xdf, 0x5b, 0x9f, 0xa0, + 0x1b, 0x82, 0x13, 0x2d, 0x52, 0x3b, 0xdd, 0x17, 0x32, 0x93, 0x36, 0x82, + 0x5f, 0x68, 0x3c, 0x1d, 0xf3, 0x54, 0xcd, 0x2e, 0x24, 0x5f, 0xcb, 0x73, + 0x5e, 0xf1, 0x31, 0xf7, 0xb5, 0x3d, 0x6c, 0x43, 0x65, 0x2a, 0x8d, 0xf9, + 0x05, 0xb2, 0xa4, 0x67, 0x46, 0x50, 0x65, 0x8a, 0xb0, 0xcc, 0xbf, 0xea, + 0xa5, 0x46, 0xfd, 0x39, 0xb7, 0x75, 0xa8, 0x8f, 0xd3, 0x91, 0x5a, 0x79, + 0x98, 0x2b, 0x7b, 0xa3, 0x97, 0x49, 0xa1, 0x08, 0xb4, 0x62, 0x97, 0x58, + 0x13, 0x9b, 0xef, 0x5e, 0x7e, 0xfd, 0x23, 0xf7, 0x6f, 0xf2, 0xfc, 0x79, + 0x9f, 0x5a, 0x56, 0x33, 0x0d, 0x73, 0x67, 0x9a, 0x9b, 0xed, 0xc0, 0x30, + 0xe2, 0xa3, 0x5e, 0x12, 0x91, 0x3f, 0x68, 0x95, 0xbf, 0x77, 0xfd, 0xd4, + 0x4d, 0x8b, 0xd5, 0xf6, 0xb1, 0x4c, 0x95, 0xb7, 0x50, 0xba, 0xb5, 0xf1, + 0x06, 0x33, 0xd2, 0x9b, 0x32, 0x8b, 0xb9, 0x34, 0x4b, 0xe3, 0x4c, 0x91, + 0xdc, 0x27, 0xd7, 0xa9, 0x61, 0xe2, 0xfb, 0x41, 0xf7, 0xf6, 0xb9, 0x67, + 0x3d, 0x38, 0x5a, 0xc7, 0xf5, 0x62, 0xae, 0x9b, 0x86, 0x65, 0x29, 0xa8, + 0x90, 0x03, 0x3a, 0x27, 0x48, 0xe2, 0x63, 0x0c, 0xaf, 0xa8, 0x26, 0xfd, + 0x8f, 0xee, 0xb7, 0x22, 0xa9, 0x97, 0x6d, 0x8b, 0xe7, 0x56, 0x56, 0xec, + 0x50, 0x9d, 0x18, 0x20, 0x59, 0xc8, 0x4c, 0x9d, 0xe8, 0xfd, 0x86, 0x6e, + 0xb9, 0xfd, 0xa6, 0x95, 0x30, 0x02, 0xa9, 0x4b, 0xb0, 0x83, 0x51, 0x8f, + 0x6d, 0x00, 0x75, 0xd1, 0x37, 0x85, 0x47, 0xec, 0x75, 0xb3, 0xab, 0xb3, + 0xf4, 0xd3, 0x62, 0x2d, 0x95, 0x0f, 0xe6, 0xd6, 0xbb, 0x49, 0xc2, 0x08, + 0x77, 0x4b, 0x91, 0x18, 0xc2, 0xb3, 0x90, 0x99, 0x90, 0x81, 0x2b, 0xc9, + 0xba, 0x79, 0xe3, 0xca, 0x1b, 0x71, 0x5a, 0x6d, 0xbc, 0xd9, 0x98, 0x92, + 0xba, 0x7b, 0xe5, 0xeb, 0x9b, 0x29, 0xde, 0x6e, 0x85, 0x20, 0x10, 0x82, + 0xb0, 0x0a, 0x73, 0x3a, 0xd1, 0xf6, 0x58, 0x5a, 0xd7, 0xc6, 0xb6, 0x29, + 0x42, 0xca, 0x32, 0x3b, 0x04, 0xa2, 0xd4, 0x09, 0x93, 0xf6, 0xb9, 0x2a, + 0x12, 0xfb, 0x52, 0x22, 0xfc, 0xbe, 0x66, 0xb3, 0x71, 0xd1, 0xdc, 0xe6, + 0xf5, 0xd4, 0x09, 0xea, 0xd5, 0x57, 0x35, 0x1d, 0x00, 0x09, 0x44, 0xcc, + 0x94, 0x65, 0x4a, 0x52, 0xee, 0x44, 0xb5, 0x26, 0xe3, 0x8c, 0xef, 0x61, + 0x65, 0x73, 0x37, 0xed, 0x4b, 0x8c, 0xa4, 0x08, 0x32, 0x87, 0x21, 0xd1, + 0x26, 0xad, 0xbf, 0xb4, 0xf6, 0x4e, 0x57, 0x4e, 0x53, 0xa2, 0xed, 0x3c, + 0xdd, 0xda, 0x70, 0x93, 0xd3, 0x12, 0x9d, 0x69, 0x85, 0x02, 0x06, 0x3c, + 0x27, 0x27, 0x0b, 0xc9, 0x21, 0xe0, 0x7f, 0xf6, 0xb1, 0x38, 0xe9, 0xbd, + 0x22, 0x14, 0xd8, 0x83, 0x79, 0x36, 0x90, 0x08, 0x76, 0x50, 0xb0, 0xab, + 0xc6, 0xd6, 0x75, 0xe5, 0x32, 0x3f, 0xcf, 0xc7, 0x05, 0x7e, 0x98, 0x9b, + 0xe4, 0x1b, 0xda, 0x72, 0x06, 0xc2, 0x45, 0x5e, 0x9b, 0xf6, 0x6d, 0xcb, + 0xe7, 0x82, 0x8c, 0xc7, 0xff, 0x56, 0xdc, 0xb2, 0x2f, 0xee, 0x6d, 0xe0, + 0xd3, 0x5d, 0x87, 0xcc, 0x8a, 0xbc, 0xe3, 0xb5, 0xa3, 0xe9, 0xb2, 0x89, + 0x82, 0x60, 0xb7, 0x73, 0x74, 0xb0, 0xf0, 0x3b, 0x28, 0x20, 0xb0, 0x1e, + 0xe3, 0x3f, 0x8b, 0x7f, 0xf7, 0xf6, 0x43, 0x4d, 0x33, 0xb2, 0x02, 0x27, + 0x4d, 0x8d, 0x80, 0xfc, 0xd1, 0xe0, 0x24, 0xe7, 0x82, 0xdf, 0xe9, 0x1c, + 0x62, 0x34, 0xd2, 0x9b, 0xd1, 0x9a, 0x5f, 0x61, 0x6a, 0xd4, 0xd9, 0x8f, + 0x5c, 0x8e, 0xa3, 0x19, 0x6b, 0xd2, 0xda, 0x16, 0x54, 0xc4, 0xf8, 0xb1, + 0x95, 0x48, 0x3e, 0x26, 0x5c, 0x27, 0x1c, 0xf2, 0xd2, 0x0d, 0x36, 0x3f, + 0x69, 0x9e, 0x6d, 0x81, 0x86, 0x1f, 0x50, 0xcd, 0xa9, 0x76, 0x08, 0xe1, + 0xd3, 0xb0, 0xda, 0xfb, 0xd8, 0x5d, 0x93, 0xb1, 0x8e, 0x6d, 0x14, 0xed, + 0xdf, 0xf7, 0x57, 0xff, 0xff, 0x8c, 0x4d, 0x15, 0x36, 0x21, 0x87, 0x64, + 0xb0, 0x67, 0xe5, 0x89, 0x90, 0x9a, 0x26, 0x86, 0xa5, 0x2c, 0x20, 0xc3, + 0xcd, 0x4b, 0x7c, 0x6c, 0xc0, 0xfa, 0x40, 0xca, 0x08, 0x65, 0xa3, 0x40, + 0x31, 0x9a, 0x59, 0xfb, 0x46, 0xd7, 0xe7, 0xda, 0xa1, 0x46, 0x9b, 0x3c, + 0x05, 0x40, 0x11, 0x5e, 0x7e, 0xd5, 0x8e, 0x58, 0xaf, 0x43, 0x0c, 0x86, + 0x5f, 0x88, 0x37, 0x81, 0x4e, 0x7c, 0xea, 0xdf, 0x32, 0xde, 0x9d, 0x7f, + 0x43, 0x1c, 0x15, 0x96, 0x10, 0xe4, 0xe8, 0x50, 0xab, 0x6f, 0x37, 0x6a, + 0xf7, 0x6c, 0x68, 0x21, 0xda, 0x19, 0x5d, 0x2d, 0xc7, 0x9d, 0xcc, 0x88, + 0x18, 0x8c, 0xe3, 0x00, 0x68, 0x05, 0x1c, 0xa2, 0x6a, 0xc3, 0xaf, 0xbd, + 0xd1, 0xb3, 0xc5, 0xba, 0xa5, 0xb7, 0xc6, 0x91, 0xf3, 0x4f, 0x1c, 0xba, + 0x10, 0x23, 0x21, 0x2a, 0x4e, 0xd8, 0xf9, 0x72, 0xf1, 0x3a, 0x7b, 0xab, + 0x9c, 0x2d, 0xec, 0x6f, 0x2b, 0x15, 0xcb, 0x38, 0xa6, 0x60, 0x83, 0x5a, + 0x08, 0x9d, 0xed, 0x67, 0xb5, 0x27, 0x2b, 0xb9, 0x0b, 0xa0, 0x8f, 0xf6, + 0xfd, 0x68, 0x27, 0xe6, 0xbb, 0x6b, 0x53, 0x86, 0x30, 0x14, 0x1b, 0x89, + 0x51, 0x39, 0x5b, 0x38, 0x60, 0xce, 0x8d, 0x65, 0xc7, 0x81, 0xbd, 0x5e, + 0xd1, 0x08, 0xdd, 0x65, 0x15, 0x1d, 0xff, 0xfa, 0x86, 0x2d, 0x9c, 0x1d, + 0xf3, 0x01, 0xc3, 0xc3, 0x38, 0x6a, 0x9a, 0x65, 0x38, 0xc2, 0x82, 0x38, + 0xef, 0xe3, 0x70, 0xc2, 0xc9, 0xf3, 0xc3, 0x99, 0x75, 0x14, 0xa9, 0x85, + 0x21, 0x5a, 0xd2, 0xd0, 0xd0, 0x4a, 0x26, 0x31, 0xc7, 0x90, 0xee, 0x41, + 0x9a, 0x8f, 0xbf, 0x9d, 0xaf, 0x4b, 0x7b, 0x56, 0x23, 0x6e, 0xbf, 0x6b, + 0x87, 0x1a, 0x56, 0x91, 0xe5, 0xec, 0xf9, 0xbe, 0xe1, 0x51, 0xaf, 0x50, + 0xcb, 0xee, 0x4e, 0x33, 0xdf, 0xb3, 0xbe, 0x8e, 0xed, 0x7a, 0x47, 0x12, + 0x0e, 0x28, 0xa8, 0xe3, 0x41, 0xb0, 0xdb, 0x12, 0xaf, 0x10, 0x0e, 0x32, + 0x13, 0x99, 0xf9, 0xf0, 0xf5, 0x48, 0x61, 0xa2, 0xec, 0x3a, 0x8c, 0x5c, + 0xa8, 0xab, 0xef, 0x77, 0xea, 0xe2, 0x8a, 0xc8, 0xb3, 0x8d, 0xcf, 0x70, + 0xf0, 0x4d, 0x7e, 0x1c, 0xa2, 0x40, 0x6a, 0x28, 0x50, 0x3e, 0x29, 0x5f, + 0x76, 0x05, 0x99, 0x90, 0x18, 0xf8, 0x48, 0xa8, 0xb5, 0x77, 0xd9, 0xb8, + 0xd5, 0xba, 0x6a, 0x58, 0xdb, 0x83, 0x72, 0x62, 0xee, 0xfa, 0x70, 0x4b, + 0x97, 0x4b, 0x45, 0x00, 0x68, 0xc1, 0x23, 0xdc, 0x09, 0xd8, 0x3c, 0xca, + 0xb8, 0x73, 0xab, 0x6d, 0x6e, 0x27, 0x95, 0xcd, 0x42, 0x2f, 0x51, 0x2e, + 0x70, 0x65, 0x1a, 0x06, 0x67, 0x1b, 0x09, 0xf6, 0xf0, 0x02, 0x40, 0x59, + 0x3a, 0x77, 0x1b, 0x9d, 0x52, 0x3e, 0x46, 0xc7, 0x5a, 0x4e, 0xdc, 0xa6, + 0x6e, 0x3f, 0x6c, 0xdc, 0x82, 0x1b, 0x16, 0x66, 0x43, 0x23, 0x32, 0xab, + 0x27, 0x78, 0xb1, 0x5d, 0xad, 0x54, 0x48, 0x9a, 0x3e, 0x7b, 0x49, 0x60, + 0x6d, 0x2d, 0xd9, 0xbf, 0x29, 0xa1, 0xa7, 0xb7, 0x34, 0x09, 0x94, 0xa0, + 0x64, 0xbf, 0x04, 0xf7, 0x8f, 0x5b, 0x71, 0xfa, 0xa5, 0x9c, 0xdb, 0x43, + 0x1c, 0x0c, 0x66, 0x7b, 0x21, 0xd3, 0xe3, 0x69, 0x6e, 0xf8, 0x67, 0x04, + 0x3c, 0xb1, 0xa6, 0x7c, 0x57, 0xea, 0x83, 0x08, 0x45, 0x2e, 0x5d, 0x1a, + 0x8d, 0x02, 0xe4, 0xe5, 0xfc, 0x61, 0x50, 0x61, 0x13, 0x9b, 0x6e, 0x54, + 0x28, 0x0a, 0x09, 0xd7, 0x97, 0x2c, 0x72, 0x27, 0xb6, 0xa8, 0xe5, 0x43, + 0x27, 0x29, 0xcf, 0xc4, 0x05, 0x2b, 0x78, 0xed, 0x69, 0xe0, 0x20, 0x48, + 0x8c, 0x02, 0x5f, 0x40, 0x71, 0xfd, 0x39, 0xbe, 0x2f, 0xbb, 0xeb, 0xde, + 0xbd, 0xb4, 0x2f, 0x97, 0xa0, 0xcc, 0xdb, 0xed, 0x1c, 0x73, 0x5e, 0x70, + 0x32, 0xdf, 0x45, 0xcc, 0xf2, 0xbe, 0x80, 0xed, 0xf6, 0xce, 0x60, 0xeb, + 0x66, 0x4a, 0x4b, 0x17, 0x87, 0xf1, 0x8c, 0x46, 0x0b, 0x5a, 0x74, 0x13, + 0xcf, 0x51, 0x4c, 0xfa, 0x37, 0xb8, 0xe7, 0xf7, 0xf8, 0xbf, 0xb7, 0x0e, + 0xee, 0x74, 0xff, 0x3e, 0x35, 0x0c, 0x3e, 0x5b, 0x64, 0x82, 0x27, 0x63, + 0x27, 0x24, 0xa1, 0xf6, 0x0d, 0x99, 0xae, 0x3a, 0xe7, 0xe2, 0xf7, 0xdc, + 0x47, 0x45, 0x00, 0x93, 0x0d, 0x9b, 0x37, 0xba, 0xce, 0x1c, 0x80, 0x44, + 0x81, 0x4a, 0x28, 0x9a, 0xc1, 0xce, 0x2d, 0x49, 0xea, 0xe2, 0x73, 0xe7, + 0xb0, 0x4c, 0xe3, 0x0d, 0x4e, 0xf7, 0x9a, 0x5c, 0x1d, 0xa0, 0xa2, 0xf4, + 0x06, 0x12, 0x0f, 0x3d, 0x2d, 0x3f, 0xb7, 0xe5, 0xbf, 0xff, 0x60, 0x84, + 0x94, 0x7a, 0xef, 0xce, 0xd2, 0x15, 0x1a, 0x80, 0x75, 0x18, 0x28, 0xb0, + 0x9a, 0x08, 0x48, 0x43, 0x84, 0x6f, 0x83, 0xdb, 0xb0, 0xd0, 0x51, 0xf5, + 0x15, 0x19, 0xc2, 0xc2, 0x53, 0xf9, 0xbf, 0x93, 0x37, 0xfc, 0xcb, 0x3a, + 0x2f, 0x16, 0x6a, 0x54, 0x67, 0xa7, 0xa6, 0xe4, 0xd1, 0x25, 0xe0, 0x30, + 0x06, 0x13, 0x00, 0x0a, 0x2e, 0x11, 0xf1, 0x33, 0x9e, 0xb4, 0xe7, 0x1c, + 0xe3, 0x0c, 0x91, 0xfb, 0x52, 0x62, 0x46, 0xcd, 0xed, 0x77, 0x12, 0xff, + 0x15, 0x7b, 0xd7, 0x3b, 0x22, 0xcd, 0xd7, 0xf4, 0x0c, 0xe1, 0x85, 0x68, + 0x0a, 0x24, 0xd0, 0x07, 0x0e, 0xf5, 0x68, 0x5d, 0x55, 0xb5, 0xe3, 0x28, + 0x68, 0x23, 0x40, 0xec, 0x0d, 0x94, 0x8c, 0xa8, 0x09, 0x77, 0x16, 0xe5, + 0xab, 0xc5, 0xe8, 0x53, 0xe2, 0xc1, 0xce, 0x5c, 0xa9, 0x55, 0x10, 0xea, + 0x9b, 0x3e, 0x8a, 0x1d, 0xae, 0x60, 0x1d, 0x09, 0xc7, 0xf7, 0xf5, 0xca, + 0x92, 0x02, 0x5f, 0x35, 0x96, 0x74, 0x72, 0x85, 0x29, 0xf8, 0x04, 0x20, + 0x70, 0xf7, 0xb9, 0x34, 0x46, 0x3a, 0xb2, 0x92, 0x05, 0x1f, 0xa3, 0x05, + 0x5d, 0xb0, 0x10, 0x15, 0xbe, 0x01, 0x21, 0x03, 0x57, 0x46, 0xef, 0x43, + 0x80, 0x10, 0xc9, 0x78, 0xf2, 0x33, 0x39, 0xd3, 0xc0, 0x6a, 0x92, 0xd9, + 0x69, 0x22, 0xbf, 0xd9, 0xd1, 0xf4, 0xda, 0xb5, 0xe9, 0xe8, 0x65, 0x1a, + 0x60, 0x3b, 0x19, 0xbd, 0x44, 0xe8, 0x89, 0x77, 0x28, 0xb9, 0xbb, 0xcd, + 0x2d, 0xfb, 0x7b, 0xf0, 0x74, 0x32, 0xbf, 0x6f, 0x4c, 0x74, 0xf8, 0x0a, + 0x0f, 0x31, 0x24, 0x51, 0xfa, 0x01, 0x51, 0xe3, 0x8d, 0x4f, 0xfe, 0x08, + 0x8d, 0x02, 0xd8, 0x71, 0xa3, 0xfd, 0xc8, 0x19, 0x7b, 0xd1, 0x87, 0x6c, + 0x72, 0x73, 0x7f, 0x9e, 0x31, 0xb7, 0xbf, 0xc3, 0x6f, 0xcf, 0xd3, 0xd9, + 0x7a, 0x3a, 0x76, 0xc5, 0xe5, 0xb9, 0x7b, 0x20, 0x13, 0xa3, 0x2d, 0xa1, + 0x7a, 0xa2, 0x60, 0x49, 0xfd, 0xba, 0x2f, 0x2c, 0xb9, 0x48, 0x49, 0xfe, + 0x80, 0x8e, 0xc4, 0xd0, 0x96, 0x92, 0xf7, 0x0e, 0x4e, 0x6d, 0x8c, 0x32, + 0x1a, 0x3f, 0x14, 0xf8, 0x2d, 0x63, 0x44, 0x1d, 0x1d, 0xba, 0xc2, 0xcc, + 0xa6, 0x36, 0x8b, 0x48, 0xd5, 0xea, 0x8e, 0x87, 0xce, 0x0c, 0xfb, 0x46, + 0x0e, 0xb9, 0xa4, 0x68, 0x0c, 0x9f, 0xa6, 0xb3, 0xfd, 0x39, 0xad, 0x69, + 0x2e, 0x53, 0x48, 0x9c, 0x02, 0xac, 0x51, 0xd8, 0x19, 0x24, 0x82, 0x1e, + 0x24, 0x91, 0x52, 0x0f, 0xba, 0x53, 0x25, 0x07, 0x0e, 0x83, 0xe0, 0x09, + 0x72, 0xa2, 0x32, 0x2c, 0xee, 0x0e, 0x88, 0x5b, 0x42, 0x25, 0x3c, 0x69, + 0xb7, 0xc5, 0x9a, 0x07, 0xc0, 0x6b, 0x94, 0x28, 0x01, 0x39, 0x34, 0xd1, + 0xab, 0xf4, 0x32, 0x55, 0x82, 0x3c, 0x07, 0x2a, 0x11, 0x7a, 0x10, 0xc9, + 0x55, 0xaa, 0x84, 0x39, 0xd8, 0x3c, 0x4e, 0x09, 0x65, 0xe9, 0x03, 0x39, + 0xd0, 0xf1, 0x79, 0x70, 0x83, 0x07, 0x68, 0x72, 0x4f, 0x3f, 0x8e, 0x05, + 0xe1, 0x41, 0xe4, 0xf8, 0x1b, 0xc6, 0x13, 0xd4, 0x95, 0xed, 0xe5, 0x2f, + 0xab, 0x97, 0xaf, 0xa9, 0x6b, 0x59, 0x3c, 0x09, 0xe3, 0x3d, 0x26, 0xdb, + 0x04, 0x72, 0x19, 0x05, 0x28, 0x1f, 0x00, 0x67, 0x29, 0x2a, 0xe1, 0x7b, + 0xdb, 0x8b, 0xfb, 0x71, 0xde, 0x13, 0x5f, 0xe1, 0xb6, 0x91, 0x99, 0x90, + 0x99, 0x4a, 0xf8, 0xf0, 0x79, 0xe2, 0x2d, 0x76, 0x9b, 0x1e, 0x29, 0xed, + 0xf7, 0x8b, 0xa2, 0x1c, 0xf9, 0xec, 0xde, 0xf4, 0x35, 0x40, 0xca, 0x4c, + 0xf0, 0x30, 0x4a, 0xcb, 0x9f, 0x72, 0x0f, 0xfe, 0x06, 0xcd, 0x54, 0xb0, + 0x5d, 0x30, 0x59, 0xd6, 0x0d, 0x7e, 0x7e, 0x71, 0x45, 0xb6, 0xc3, 0xac, + 0x5b, 0x76, 0xa7, 0xc6, 0x67, 0x08, 0x2d, 0xd1, 0xa7, 0x32, 0x1a, 0x90, + 0x83, 0xc1, 0x55, 0x6a, 0xca, 0x9c, 0x8e, 0xb3, 0x7b, 0x8f, 0xc5, 0x05, + 0x4f, 0x91, 0xef, 0xee, 0xa5, 0x7d, 0xcd, 0xd6, 0xb0, 0xad, 0xc1, 0x94, + 0x98, 0x20, 0x04, 0x26, 0x54, 0xd6, 0x72, 0xb4, 0x28, 0xe4, 0xe4, 0xdf, + 0x43, 0x7e, 0xfd, 0x15, 0x17, 0x8d, 0xd9, 0xd4, 0x62, 0xa9, 0x62, 0x47, + 0x6d, 0x32, 0x26, 0x11, 0x41, 0x04, 0x6f, 0x50, 0x3c, 0xd2, 0x9a, 0xeb, + 0x76, 0x2e, 0x7e, 0xcf, 0xfe, 0xbc, 0xbd, 0xae, 0x5f, 0x23, 0x77, 0x86, + 0x9c, 0xf1, 0x99, 0xa7, 0x8c, 0xd9, 0x21, 0x58, 0x07, 0x9b, 0x3b, 0xfa, + 0xe4, 0xc1, 0x72, 0xd9, 0x01, 0xc5, 0xe5, 0xb8, 0xc0, 0xe8, 0xb9, 0x11, + 0x96, 0xcf, 0x39, 0x8c, 0x8a, 0x77, 0x3e, 0xd7, 0x8d, 0x27, 0xf1, 0x0b, + 0xfc, 0xa0, 0xa7, 0x7a, 0x61, 0x44, 0xcc, 0xfc, 0x15, 0xea, 0x0b, 0xf7, + 0x74, 0x9b, 0xa7, 0xda, 0x73, 0x9b, 0xec, 0x62, 0x43, 0x19, 0xbb, 0x16, + 0xba, 0x0d, 0x1e, 0xd6, 0xa1, 0x4c, 0xbd, 0x58, 0xac, 0xcf, 0x79, 0x9d, + 0xf2, 0xbd, 0xfa, 0x9c, 0xfd, 0x79, 0x81, 0x0c, 0x7d, 0xb8, 0xe9, 0xf9, + 0x99, 0x64, 0xee, 0xa9, 0xa4, 0xe9, 0xcc, 0x94, 0x09, 0x6c, 0x3d, 0x7e, + 0x59, 0x55, 0x80, 0x5e, 0xf1, 0xf5, 0xff, 0x5d, 0x74, 0xf2, 0xea, 0xe6, + 0xfa, 0xb1, 0x7a, 0x48, 0xeb, 0x72, 0x53, 0x18, 0x60, 0x14, 0xfb, 0x54, + 0x72, 0xab, 0x04, 0x13, 0xa7, 0x47, 0xfb, 0xbb, 0x21, 0x14, 0x3d, 0xd3, + 0x56, 0x53, 0x89, 0xa4, 0x6b, 0x02, 0x79, 0x83, 0x74, 0x85, 0x2e, 0x9c, + 0xbe, 0x03, 0xf4, 0x0b, 0xa2, 0xdc, 0xf2, 0xdb, 0x57, 0x2a, 0x25, 0x5b, + 0x63, 0x01, 0x67, 0x18, 0xc4, 0x1c, 0xa7, 0xfa, 0x99, 0xc2, 0x3d, 0x26, + 0xaf, 0x9b, 0x9f, 0x9f, 0x4c, 0x03, 0x73, 0xb9, 0xd7, 0x98, 0x22, 0x67, + 0x0e, 0x5c, 0x60, 0xc8, 0xf8, 0xc0, 0x54, 0x9b, 0xfb, 0x4c, 0xd9, 0x38, + 0xf8, 0xfc, 0x90, 0x78, 0x5b, 0xeb, 0xf0, 0xe9, 0x3f, 0xa5, 0x32, 0xc8, + 0x28, 0xc3, 0xf8, 0x6f, 0x63, 0x62, 0x59, 0x54, 0xf1, 0x81, 0xc9, 0xa1, + 0xf3, 0x97, 0xdf, 0x1f, 0xff, 0xfb, 0x75, 0xe3, 0xf2, 0xc3, 0x2d, 0x7c, + 0x6f, 0x41, 0xa1, 0xa0, 0x1d, 0xc8, 0x34, 0x44, 0xca, 0x15, 0x93, 0xde, + 0xda, 0xb9, 0x17, 0x93, 0x7f, 0x17, 0x5a, 0xfe, 0xe1, 0x3b, 0x94, 0x4c, + 0xd9, 0x54, 0x27, 0x08, 0x13, 0x9c, 0x04, 0x89, 0x65, 0x51, 0xee, 0x41, + 0xd7, 0x93, 0x1b, 0xef, 0x40, 0x6f, 0xac, 0xc5, 0x55, 0xe5, 0xad, 0x42, + 0xa2, 0x65, 0xf7, 0x7a, 0xc3, 0xae, 0x99, 0xc8, 0xd3, 0x44, 0x7d, 0x36, + 0x47, 0xaa, 0xe2, 0xd9, 0xe2, 0xa0, 0xcf, 0x34, 0xb7, 0xca, 0x0f, 0x2e, + 0x9f, 0xa5, 0x21, 0x07, 0xf6, 0x70, 0x32, 0x34, 0xf2, 0xcf, 0x19, 0x19, + 0xa2, 0x28, 0x4b, 0xea, 0x0f, 0x34, 0xbb, 0x4a, 0x27, 0x17, 0x35, 0xc7, + 0x27, 0x12, 0xda, 0xd7, 0x9d, 0xde, 0x30, 0x71, 0xda, 0x0c, 0x6a, 0xbe, + 0x72, 0x0c, 0x6b, 0x00, 0xa6, 0xb7, 0xc5, 0x3a, 0x43, 0xfb, 0x3b, 0xe4, + 0x20, 0x5a, 0x79, 0x10, 0xa9, 0x9e, 0xfc, 0x84, 0x48, 0xc6, 0x2b, 0xa0, + 0xa4, 0x5a, 0x90, 0x13, 0x9e, 0xf1, 0x5f, 0x0f, 0x97, 0x0e, 0x5e, 0x10, + 0xe2, 0x42, 0x1f, 0x22, 0x73, 0xe4, 0xe0, 0xa5, 0x2a, 0x0c, 0x7c, 0xae, + 0x95, 0x57, 0x95, 0xb1, 0x40, 0x76, 0xc7, 0x0d, 0xa2, 0xe0, 0x30, 0x62, + 0x77, 0x07, 0x07, 0x65, 0xd6, 0xef, 0x23, 0x8d, 0xac, 0x3c, 0xc9, 0x45, + 0xe5, 0x21, 0xe2, 0x1f, 0xee, 0x96, 0x60, 0xae, 0x6f, 0x51, 0x3f, 0x11, + 0x0c, 0xcd, 0x1a, 0x7b, 0x32, 0xa1, 0xda, 0xe3, 0x90, 0x05, 0x0a, 0xa9, + 0x27, 0xaf, 0xc8, 0x39, 0xbe, 0xe1, 0x7a, 0xf7, 0x94, 0x22, 0x1a, 0xd2, + 0xad, 0xc6, 0xa7, 0xb8, 0x77, 0x5b, 0x93, 0xe5, 0x4e, 0x50, 0x30, 0x8c, + 0x0e, 0x12, 0x0f, 0x34, 0xb6, 0x7b, 0xe0, 0xef, 0x3b, 0xbb, 0xb6, 0x92, + 0xe8, 0xfc, 0xd4, 0x1d, 0x67, 0x18, 0x8a, 0x50, 0x9a, 0x48, 0x81, 0x4f, + 0x2f, 0x54, 0x12, 0xbe, 0xdb, 0xd2, 0x67, 0xae, 0x1d, 0x2a, 0x5f, 0x8d, + 0x0f, 0x55, 0xbf, 0x40 +}; + +void vc1_get_video_data(const guchar **data, guint *size) +{ + *data = vc1_clip; + *size = VC1_CLIP_DATA_SIZE; +} diff --git a/tests/test-vc1.h b/tests/test-vc1.h new file mode 100644 index 0000000000..ac35d2b327 --- /dev/null +++ b/tests/test-vc1.h @@ -0,0 +1,28 @@ +/* + * test-vc1.h - VC-1 test data + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef TEST_VC1_H +#define TEST_VC1_H + +#include + +void vc1_get_video_data(const guchar **data, guint *size); + +#endif /* TEST_VC1_H */ From edef951fb2866f2b846297505c1fd19edfa750d8 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 26 Apr 2010 08:15:58 +0000 Subject: [PATCH 0261/3781] Regenerate correct clips. --- tests/test-h264.c | 2087 ++++++++++++++++++++++----------------------- tests/test-vc1.c | 8 +- 2 files changed, 1017 insertions(+), 1078 deletions(-) diff --git a/tests/test-h264.c b/tests/test-h264.c index 1d921c5fee..e4c0f37ee6 100644 --- a/tests/test-h264.c +++ b/tests/test-h264.c @@ -22,1085 +22,1024 @@ #define H264_CLIP_WIDTH 320 #define H264_CLIP_HEIGHT 240 -#define H264_CLIP_SLICE_OFFSET 52 -#define H264_CLIP_SLICE_SIZE 12071 +#define H264_CLIP_DATA_SIZE 12111 /* Data dump of a 320x240 H.264 video clip (h264.mp4), it has a single frame */ -static const guchar h264_clip[] = { - 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6f, 0x6d, - 0x00, 0x00, 0x02, 0x00, 0x69, 0x73, 0x6f, 0x6d, 0x69, 0x73, 0x6f, 0x32, - 0x61, 0x76, 0x63, 0x31, 0x6d, 0x70, 0x34, 0x31, 0x00, 0x00, 0x00, 0x08, - 0x66, 0x72, 0x65, 0x65, 0x00, 0x00, 0x2f, 0x33, 0x6d, 0x64, 0x61, 0x74, - 0x00, 0x00, 0x2f, 0x27, 0x65, 0x88, 0x82, 0x00, 0x45, 0xbb, 0x9d, 0x38, - 0x9b, 0xe8, 0x48, 0xef, 0xed, 0xa7, 0xd7, 0x9c, 0x19, 0x9b, 0x5a, 0xca, - 0x00, 0x0d, 0x54, 0x0c, 0xe3, 0xd5, 0xad, 0xa9, 0x5d, 0x71, 0x24, 0x83, - 0xbb, 0x36, 0x4d, 0xb1, 0xf5, 0x0f, 0xc6, 0x66, 0xb6, 0x6d, 0x1d, 0xa5, - 0x45, 0xfc, 0xa0, 0x4c, 0xbf, 0xfb, 0x2f, 0x5c, 0x1a, 0x5a, 0x3b, 0x29, - 0xe0, 0x35, 0x95, 0x44, 0x8e, 0x2f, 0x22, 0xd3, 0x3a, 0x48, 0x88, 0x7d, - 0x32, 0x97, 0xff, 0xd8, 0x54, 0x7f, 0x7f, 0x65, 0x57, 0x71, 0xaf, 0xba, - 0x17, 0xe0, 0x12, 0x24, 0xc9, 0x5b, 0xaa, 0xc7, 0xd5, 0x27, 0xc9, 0x64, - 0x5d, 0x5e, 0xa0, 0xea, 0x57, 0xd2, 0x7d, 0x55, 0x6c, 0xf2, 0x44, 0x2f, - 0x4b, 0x5d, 0xbd, 0x62, 0xb9, 0xc2, 0xfa, 0x1e, 0x8f, 0xbc, 0x57, 0x5f, - 0xc1, 0x2d, 0xb3, 0x9a, 0x0e, 0x58, 0x75, 0xf7, 0x08, 0xdf, 0x2d, 0xda, - 0xc1, 0xa5, 0x55, 0x76, 0x06, 0xaf, 0x92, 0x28, 0x43, 0xc5, 0x20, 0x16, - 0x96, 0xf5, 0x79, 0x1e, 0x88, 0x77, 0xb3, 0x4e, 0xb8, 0x4f, 0x3e, 0x51, - 0x3c, 0xcf, 0xc0, 0x28, 0xda, 0xb8, 0xa3, 0x1d, 0xed, 0x8e, 0x04, 0x74, - 0x82, 0xc1, 0x5d, 0xa8, 0x3c, 0x25, 0xd2, 0x84, 0x0b, 0x34, 0x40, 0x8b, - 0x7f, 0xee, 0xae, 0xf8, 0xde, 0x6e, 0x28, 0xf6, 0xfc, 0xfc, 0x14, 0x7e, - 0x95, 0xd9, 0xd8, 0x2c, 0x09, 0x49, 0x27, 0x64, 0x13, 0x83, 0x5c, 0x6f, - 0xd4, 0x09, 0x48, 0xa8, 0xd4, 0x1b, 0x6e, 0x4d, 0x05, 0x0a, 0xbe, 0x27, - 0xff, 0xf4, 0x27, 0x04, 0x41, 0xa0, 0x23, 0x61, 0xe6, 0x26, 0x32, 0xf4, - 0xa3, 0xca, 0x97, 0xfc, 0xeb, 0x6b, 0x45, 0x35, 0x13, 0x69, 0xd9, 0x41, - 0x0f, 0xa6, 0xc0, 0xbe, 0xd5, 0xfa, 0x28, 0xa6, 0x4f, 0x62, 0x3e, 0x1f, - 0xcb, 0x98, 0x0a, 0x70, 0x09, 0xc1, 0xe3, 0x69, 0x30, 0x20, 0xe7, 0xd5, - 0x1c, 0xf0, 0x7e, 0x52, 0x1d, 0x6a, 0xdd, 0x14, 0x58, 0x5e, 0x7a, 0x35, - 0x57, 0xa1, 0xe6, 0x83, 0x46, 0x57, 0x6e, 0x57, 0x7f, 0x72, 0x5d, 0x0c, - 0x0c, 0xf4, 0x40, 0x11, 0x8c, 0xbb, 0xdf, 0xd1, 0x54, 0xfb, 0x7d, 0xf7, - 0x03, 0xb9, 0x4e, 0xa3, 0x76, 0x4c, 0xce, 0xfb, 0x9e, 0x39, 0x02, 0xf0, - 0x48, 0xb5, 0x8c, 0x36, 0x6e, 0x93, 0x79, 0x48, 0xcc, 0x28, 0xec, 0xd7, - 0xb8, 0x02, 0xe5, 0xa3, 0x37, 0x01, 0xe1, 0x3c, 0x40, 0x8f, 0x68, 0x27, - 0xbc, 0xec, 0x6b, 0x59, 0xb9, 0xfe, 0xb8, 0x67, 0x68, 0x83, 0x99, 0x97, - 0x1e, 0xcc, 0x4e, 0x23, 0x82, 0x26, 0x93, 0x7b, 0x7a, 0x9e, 0xdc, 0x42, - 0xca, 0x1b, 0x3e, 0x13, 0x19, 0x45, 0x03, 0x40, 0xab, 0xd2, 0xda, 0x6b, - 0x6c, 0x26, 0xdb, 0xe3, 0x72, 0x06, 0x89, 0xea, 0x03, 0x95, 0xe3, 0x14, - 0xe1, 0x4a, 0x16, 0x58, 0x2d, 0x67, 0xaa, 0xbf, 0xbe, 0x37, 0x54, 0x19, - 0xb1, 0x57, 0x61, 0x85, 0x82, 0x5f, 0x63, 0x33, 0xe2, 0xf8, 0x7f, 0x4f, - 0x21, 0x44, 0x8a, 0x0e, 0x21, 0x2b, 0x12, 0x99, 0x4d, 0xd9, 0x2e, 0xea, - 0x36, 0x2d, 0x45, 0xcb, 0xe2, 0xfe, 0xdd, 0x03, 0x3b, 0x08, 0x58, 0x60, - 0x1e, 0xb2, 0xfa, 0x3b, 0x89, 0xa5, 0x03, 0xde, 0xab, 0x71, 0x32, 0x48, - 0x46, 0x2c, 0xfb, 0x2b, 0x84, 0x83, 0xc9, 0xff, 0xf6, 0xf5, 0x2f, 0xe7, - 0x2f, 0x6a, 0x5d, 0x86, 0xe2, 0x48, 0x23, 0x6d, 0x84, 0x60, 0x9b, 0xc0, - 0x25, 0x1e, 0xff, 0x94, 0xe8, 0xf4, 0xd0, 0x4e, 0x11, 0x60, 0xda, 0x20, - 0xa8, 0xfd, 0xf3, 0x00, 0x4f, 0x0e, 0x4f, 0xa2, 0xeb, 0xe1, 0xa8, 0xb3, - 0x47, 0x35, 0x62, 0x83, 0x6f, 0x08, 0x6b, 0xb8, 0x82, 0x04, 0xcc, 0x63, - 0x69, 0xd7, 0xba, 0x10, 0xd4, 0x51, 0xe6, 0xb5, 0x34, 0xe8, 0x7d, 0xaf, - 0x87, 0xcf, 0x1d, 0xeb, 0x46, 0xc1, 0xcd, 0xcb, 0xf2, 0x3b, 0x3e, 0xa0, - 0x61, 0xc7, 0x68, 0x86, 0x0b, 0x9f, 0x0b, 0x59, 0xc0, 0x79, 0x4e, 0xcc, - 0x79, 0x91, 0xa0, 0xe8, 0x80, 0x6c, 0xbd, 0x35, 0x12, 0x71, 0x2f, 0x5e, - 0xa4, 0xfc, 0xe6, 0x51, 0xe0, 0xbe, 0x41, 0x1a, 0x19, 0x60, 0xd8, 0xac, - 0xcd, 0x93, 0x05, 0x70, 0xa0, 0xda, 0x53, 0x4e, 0x5a, 0x6d, 0x9b, 0x3f, - 0x28, 0x73, 0x87, 0x6f, 0x6d, 0x41, 0x5a, 0x13, 0xd0, 0xea, 0x19, 0xb3, - 0xb7, 0xf1, 0x75, 0x92, 0xae, 0x43, 0x9d, 0xe3, 0xa7, 0x4d, 0x5a, 0x52, - 0x36, 0xce, 0x6b, 0x1e, 0x2b, 0x2e, 0xab, 0x0c, 0xd7, 0xe4, 0x1c, 0x44, - 0x72, 0x9d, 0x86, 0xb6, 0xeb, 0xe5, 0x80, 0xc4, 0x45, 0x21, 0x8b, 0xe0, - 0xe0, 0x9d, 0x09, 0xfa, 0x0b, 0x59, 0x0c, 0x2c, 0x9d, 0x97, 0x15, 0x56, - 0xd0, 0x21, 0xd8, 0x90, 0xb4, 0x89, 0xc4, 0x96, 0x76, 0xf1, 0x64, 0xa5, - 0x85, 0x2a, 0x13, 0xfb, 0xfa, 0x11, 0x1e, 0x2d, 0x63, 0xc2, 0x9a, 0x87, - 0x99, 0x2c, 0x18, 0xb8, 0xeb, 0x6a, 0x5c, 0x68, 0x26, 0x63, 0xcc, 0x1b, - 0x1a, 0x5c, 0x7f, 0x0d, 0x45, 0xcc, 0x56, 0x46, 0x92, 0xbb, 0x76, 0xf2, - 0x2e, 0x52, 0x05, 0x3c, 0xe3, 0xbb, 0x59, 0x9b, 0x89, 0x03, 0x0d, 0x48, - 0xb1, 0xdc, 0x78, 0x04, 0x03, 0x24, 0xf4, 0x62, 0xcf, 0xb1, 0xc6, 0x64, - 0x05, 0xbd, 0x89, 0x94, 0x1a, 0x8d, 0xc1, 0xbe, 0xac, 0xe0, 0xed, 0x89, - 0xf3, 0x47, 0x81, 0x82, 0xb9, 0x64, 0xcc, 0x8e, 0xc4, 0x1e, 0xa9, 0xf6, - 0xde, 0x8d, 0xb7, 0x33, 0xba, 0x5b, 0x49, 0x0d, 0x0a, 0x16, 0x96, 0x7d, - 0x89, 0x82, 0xe0, 0x5a, 0x08, 0x55, 0xbd, 0xce, 0xca, 0xc0, 0x46, 0x1a, - 0x6b, 0xf9, 0x7d, 0x03, 0xe8, 0x35, 0x69, 0x7d, 0x87, 0xc9, 0x71, 0x01, - 0x7e, 0xa8, 0x3a, 0x9c, 0xd5, 0xe2, 0x71, 0xa6, 0xc7, 0xe2, 0x2d, 0xf3, - 0x6f, 0x74, 0x0f, 0x3e, 0x03, 0x70, 0x5e, 0xec, 0x8c, 0x66, 0xf9, 0x71, - 0x9a, 0xd2, 0x56, 0x57, 0x37, 0xcd, 0x50, 0x55, 0x97, 0xea, 0x67, 0x20, - 0x59, 0x06, 0x4d, 0x22, 0xa0, 0x85, 0x90, 0xb3, 0x59, 0x15, 0x75, 0x0d, - 0x70, 0xbd, 0xb5, 0x7d, 0x72, 0xaa, 0xea, 0xfc, 0x9d, 0x08, 0x8d, 0xdf, - 0x31, 0x21, 0x2d, 0xef, 0x00, 0x24, 0x6c, 0xae, 0x82, 0x6e, 0x1a, 0x4b, - 0x28, 0xa5, 0x6d, 0x98, 0xeb, 0x50, 0x87, 0x6f, 0x1b, 0xa5, 0xba, 0x1c, - 0xda, 0x59, 0xb8, 0x4c, 0x17, 0xe3, 0xd5, 0x10, 0x46, 0x94, 0x91, 0xed, - 0x0b, 0xd3, 0xfc, 0x06, 0x81, 0x60, 0x88, 0x5f, 0x58, 0x81, 0x26, 0x54, - 0xdc, 0xd5, 0x7c, 0xbe, 0x30, 0x04, 0x17, 0x84, 0x76, 0xe8, 0xb6, 0x8a, - 0xec, 0x84, 0x02, 0xcf, 0xc7, 0xda, 0x2d, 0x2e, 0x31, 0xc2, 0x77, 0x31, - 0x54, 0x32, 0xbd, 0x77, 0xa2, 0xa5, 0x5d, 0xec, 0x1c, 0x27, 0xf6, 0xec, - 0xc8, 0x3f, 0xeb, 0x1a, 0x24, 0xcb, 0x74, 0xd0, 0xb3, 0x52, 0xa8, 0x8f, - 0x4c, 0x26, 0xbf, 0x68, 0xb2, 0x87, 0xf3, 0xa8, 0xa9, 0x4f, 0x71, 0x57, - 0xc7, 0xa8, 0x34, 0x5a, 0x01, 0x68, 0xae, 0x5c, 0xb3, 0xd8, 0x23, 0x6b, - 0xea, 0x18, 0xdf, 0xa9, 0xe5, 0xc4, 0x11, 0x49, 0x2b, 0xfa, 0xa8, 0xf3, - 0x8f, 0x80, 0x47, 0xa0, 0x19, 0xc7, 0x20, 0xef, 0xbf, 0xed, 0xe1, 0x38, - 0x8b, 0x16, 0x54, 0x36, 0x60, 0x8b, 0x04, 0x26, 0x9c, 0x6b, 0x1a, 0x95, - 0x4c, 0x94, 0x6a, 0x53, 0xcf, 0xb4, 0x4b, 0x38, 0x3a, 0x15, 0x26, 0x94, - 0x10, 0x1c, 0x35, 0xe4, 0x57, 0x80, 0x19, 0xad, 0x1f, 0x82, 0xe8, 0x47, - 0xe4, 0x90, 0xa2, 0x42, 0x30, 0x43, 0x15, 0x92, 0x2b, 0x39, 0xfb, 0x7b, - 0xb3, 0xdb, 0xc7, 0x5b, 0x79, 0x5e, 0x91, 0xba, 0x38, 0x74, 0xd6, 0x00, - 0x26, 0xa5, 0x8f, 0xa4, 0x31, 0xe6, 0x7b, 0xeb, 0x52, 0xc2, 0xe2, 0xa1, - 0x6b, 0x5f, 0x17, 0xf1, 0x15, 0xc9, 0x4b, 0x44, 0x93, 0x77, 0x28, 0xdf, - 0x2a, 0xc0, 0xb5, 0x97, 0xfc, 0xbe, 0x2e, 0x72, 0x53, 0x58, 0xf9, 0x33, - 0x3a, 0xb0, 0x6e, 0xaf, 0x0c, 0x1b, 0xcf, 0x71, 0x37, 0x6b, 0x4a, 0x9a, - 0x66, 0x16, 0x90, 0x43, 0x9b, 0x70, 0x0d, 0x8f, 0xd3, 0x04, 0x4b, 0x14, - 0xf2, 0x58, 0x9f, 0x64, 0x33, 0x21, 0xdc, 0x02, 0x8a, 0x5b, 0xd6, 0x80, - 0x9c, 0x22, 0xc8, 0x39, 0x7d, 0x2d, 0x7c, 0x09, 0x4e, 0x6a, 0x8c, 0x8d, - 0x0c, 0xc4, 0xfe, 0x6f, 0x8c, 0x50, 0xf2, 0x75, 0xc0, 0x12, 0x6f, 0xd3, - 0x9d, 0x07, 0xc0, 0xe9, 0xdf, 0x36, 0xa2, 0x6f, 0xca, 0x14, 0x5b, 0x0f, - 0x5a, 0xd8, 0x35, 0x72, 0x07, 0x08, 0x80, 0xba, 0x2f, 0x61, 0x7f, 0xb0, - 0x5e, 0xbb, 0xb1, 0x47, 0x6a, 0xbd, 0x6a, 0xe4, 0xb6, 0xa2, 0xec, 0x2e, - 0x27, 0x43, 0xbc, 0xd7, 0x2c, 0x2c, 0xf3, 0x6c, 0x12, 0x4c, 0x86, 0x5a, - 0x38, 0xa4, 0x87, 0xa8, 0xe1, 0x70, 0x17, 0x15, 0xd0, 0x2b, 0x87, 0xdb, - 0x87, 0xc0, 0x85, 0x57, 0x30, 0x31, 0x16, 0x07, 0x9b, 0x72, 0x07, 0xf5, - 0x18, 0x6d, 0xd1, 0x8d, 0x31, 0xa1, 0x25, 0x6a, 0xb4, 0xf3, 0x07, 0x5f, - 0x0c, 0x99, 0x33, 0x68, 0xbf, 0x2c, 0xa1, 0xfd, 0xde, 0x16, 0x2d, 0x4a, - 0x5a, 0xa0, 0x7e, 0xe5, 0x9b, 0x89, 0x4a, 0x8d, 0xe7, 0x18, 0x21, 0x32, - 0x47, 0x3c, 0x9d, 0x48, 0xab, 0x7d, 0xca, 0xb4, 0x63, 0xd9, 0xfd, 0x29, - 0x2d, 0x4c, 0xf1, 0xf2, 0x20, 0x0a, 0x91, 0x2e, 0x2c, 0xa1, 0x49, 0x83, - 0x73, 0x15, 0xa0, 0x7d, 0x6e, 0xae, 0x51, 0x45, 0x0d, 0x09, 0x1f, 0x8f, - 0x61, 0x42, 0xbd, 0x24, 0xcd, 0x3e, 0xe8, 0x66, 0x84, 0xc6, 0x97, 0x08, - 0x7b, 0x72, 0x73, 0x7e, 0xe7, 0x99, 0x05, 0xab, 0x63, 0xff, 0x3c, 0x44, - 0xa1, 0xc0, 0x1b, 0xfc, 0xff, 0x27, 0xe9, 0x45, 0x82, 0x75, 0x82, 0x6f, - 0x9c, 0x65, 0xef, 0x67, 0xd6, 0x00, 0xd1, 0x9f, 0x61, 0x9f, 0x38, 0xdd, - 0x7f, 0x5f, 0x4d, 0x67, 0x5b, 0x5d, 0xff, 0x98, 0x6b, 0x13, 0xe0, 0xe7, - 0x69, 0xcb, 0x7f, 0x7c, 0x11, 0x91, 0xe0, 0x05, 0xb9, 0x64, 0xd0, 0xb7, - 0x91, 0xe5, 0xd4, 0x3a, 0x47, 0x05, 0x25, 0x4f, 0x15, 0x46, 0xaf, 0x41, - 0x9e, 0xc7, 0x49, 0x15, 0x17, 0xd1, 0x9c, 0x28, 0xef, 0x80, 0xa3, 0x8b, - 0x60, 0xcc, 0x60, 0xeb, 0x96, 0x36, 0x3a, 0x23, 0x94, 0xf3, 0x6c, 0xe5, - 0x3f, 0xe8, 0x8b, 0x5c, 0x8c, 0xfe, 0x6f, 0x91, 0x65, 0x19, 0xa1, 0x4d, - 0x45, 0x7b, 0x06, 0x0f, 0x71, 0xb7, 0x9a, 0x8d, 0x8e, 0x82, 0x7b, 0x68, - 0x44, 0xa4, 0xa6, 0xc3, 0xe5, 0x67, 0x9f, 0x6c, 0xd0, 0xe4, 0xe8, 0x37, - 0x08, 0x6b, 0xbb, 0xa0, 0x3a, 0xd0, 0xa9, 0xd9, 0x04, 0xaa, 0x91, 0xac, - 0x71, 0xff, 0xec, 0x7e, 0xaf, 0xa9, 0x99, 0xa2, 0x8d, 0x91, 0x95, 0xb3, - 0xd8, 0xe4, 0xf3, 0x3f, 0xa6, 0x4b, 0x0c, 0x19, 0x23, 0xf7, 0xa7, 0xcd, - 0x4c, 0x41, 0x28, 0x63, 0x9f, 0x0b, 0x8f, 0x70, 0x70, 0xbd, 0x25, 0x16, - 0x8e, 0x86, 0x8a, 0x69, 0xe3, 0x6a, 0xd4, 0x98, 0x42, 0x56, 0x15, 0x2d, - 0x3d, 0xdb, 0x17, 0x1b, 0x23, 0x58, 0x82, 0x56, 0x11, 0x97, 0x85, 0xf2, - 0x68, 0x95, 0x92, 0xd5, 0x9e, 0x91, 0x05, 0x70, 0xc8, 0x96, 0xb2, 0x73, - 0x6d, 0x1e, 0x12, 0x8c, 0xa0, 0xe4, 0x1a, 0x84, 0x5b, 0xb4, 0x32, 0xf7, - 0x9e, 0x08, 0xd0, 0x6c, 0x42, 0xf0, 0x0b, 0xc4, 0x1f, 0xe0, 0xbb, 0x71, - 0xe1, 0x2d, 0x86, 0xd7, 0x77, 0x24, 0x43, 0x53, 0x0c, 0x88, 0x21, 0x75, - 0x95, 0xd0, 0xfe, 0x10, 0x23, 0xcd, 0xba, 0x77, 0x3d, 0x9b, 0x0f, 0xb2, - 0xe2, 0xcc, 0x0f, 0x94, 0xe0, 0x66, 0x90, 0x0e, 0xf7, 0x6a, 0x3c, 0x9f, - 0xc0, 0xf6, 0x98, 0x1c, 0x4c, 0x9f, 0x25, 0xc4, 0xeb, 0x1d, 0x91, 0x32, - 0x29, 0x34, 0x2a, 0xb0, 0x7e, 0x1c, 0x09, 0x77, 0x13, 0x83, 0xfa, 0xcf, - 0x24, 0xa2, 0x5f, 0x79, 0x78, 0x64, 0xf7, 0x45, 0x81, 0xbe, 0x6a, 0x82, - 0x26, 0xfd, 0xe7, 0xc3, 0x61, 0x41, 0x27, 0xcc, 0x99, 0x69, 0x77, 0xc8, - 0xa7, 0xf3, 0x52, 0x01, 0xa7, 0x8c, 0x0b, 0x7d, 0x86, 0x8d, 0xbb, 0x31, - 0xd6, 0x67, 0xf9, 0xa7, 0x8f, 0x76, 0xb6, 0x74, 0x26, 0x43, 0x35, 0xb8, - 0x83, 0x7c, 0x16, 0x34, 0x88, 0x0c, 0xb6, 0xec, 0xf0, 0x01, 0x8c, 0x1c, - 0xe5, 0x52, 0xd4, 0xca, 0x01, 0x2e, 0xb5, 0x87, 0xc1, 0xc1, 0x1b, 0xa3, - 0x02, 0x17, 0x13, 0xd3, 0x35, 0xe8, 0x80, 0xe1, 0xd1, 0x01, 0x9c, 0x0a, - 0x62, 0x7d, 0x98, 0x7c, 0x68, 0xa4, 0x8e, 0x3a, 0x50, 0x4b, 0x95, 0x59, - 0xa3, 0x11, 0xf6, 0xa3, 0xde, 0x92, 0x65, 0x00, 0xa0, 0xe8, 0x32, 0xf0, - 0xc3, 0x77, 0x68, 0x0b, 0xed, 0xc1, 0x69, 0xd2, 0x6e, 0xce, 0x80, 0xe4, - 0x56, 0x9b, 0x15, 0xbf, 0x3c, 0x4a, 0x38, 0x26, 0xf6, 0x6a, 0xdb, 0x62, - 0x7a, 0xab, 0xb1, 0x77, 0x75, 0x0d, 0xa7, 0xa4, 0xcf, 0x5e, 0x2d, 0xea, - 0x24, 0x84, 0xbd, 0x83, 0x8e, 0xaa, 0x91, 0xe1, 0x72, 0x5f, 0x7f, 0x26, - 0x54, 0x4f, 0xab, 0xa6, 0x50, 0x22, 0x68, 0x8c, 0xa6, 0x06, 0x67, 0x3c, - 0x3e, 0x93, 0x9a, 0xc2, 0x53, 0x15, 0x08, 0x1a, 0x3c, 0xb3, 0x3f, 0xf0, - 0x83, 0xf5, 0x0d, 0x9c, 0xe3, 0x76, 0x11, 0x45, 0x21, 0x6b, 0x65, 0x97, - 0xea, 0x3c, 0xdb, 0x0d, 0xcd, 0x6e, 0xb7, 0x26, 0x7b, 0x82, 0x63, 0x35, - 0x7e, 0x76, 0xf4, 0xb8, 0x0e, 0xe5, 0x1d, 0x95, 0x94, 0x1c, 0x60, 0xc7, - 0xea, 0x9c, 0x1c, 0x73, 0x75, 0x0e, 0x9b, 0x5f, 0x78, 0x09, 0x4f, 0x90, - 0x31, 0x5c, 0xc8, 0x5b, 0x78, 0xce, 0xb3, 0x3e, 0x31, 0x61, 0x90, 0xba, - 0xe0, 0xe1, 0x57, 0x1d, 0x71, 0x80, 0x92, 0x6b, 0x75, 0xe1, 0x34, 0x95, - 0xeb, 0x88, 0xe4, 0x0b, 0x72, 0xdc, 0x34, 0x24, 0x3b, 0x6d, 0x94, 0xc9, - 0xe9, 0x8d, 0x38, 0x72, 0x9c, 0x61, 0x6e, 0x07, 0xd7, 0x35, 0xa1, 0x74, - 0xc2, 0x0c, 0x36, 0xc3, 0x54, 0xd3, 0xe5, 0xd1, 0x08, 0x8e, 0x24, 0x77, - 0xf5, 0x61, 0xcf, 0x69, 0x9b, 0x27, 0x70, 0xe7, 0x52, 0xf6, 0xef, 0x66, - 0x8f, 0x0e, 0x8b, 0xc0, 0xf3, 0x64, 0x2a, 0xa8, 0xff, 0xcc, 0xd9, 0x61, - 0x53, 0xac, 0x36, 0x23, 0x4f, 0x3c, 0x0f, 0xe0, 0xec, 0xad, 0xc5, 0x35, - 0x3f, 0x3b, 0x74, 0x26, 0x84, 0x48, 0xd1, 0xfe, 0x72, 0x01, 0xea, 0x4d, - 0x03, 0x46, 0x66, 0x5a, 0xc4, 0x0a, 0x55, 0x43, 0x61, 0x36, 0x6a, 0xc1, - 0xd2, 0x74, 0x0a, 0x8f, 0x01, 0xb2, 0xc2, 0xaa, 0xd7, 0x2d, 0x0a, 0x0f, - 0x67, 0xa1, 0x25, 0x7d, 0x45, 0x60, 0x0f, 0x06, 0xfb, 0x8f, 0x8b, 0xe0, - 0x4a, 0x8c, 0xd7, 0x19, 0xac, 0xcc, 0x47, 0xa2, 0x7c, 0x30, 0x90, 0x94, - 0x81, 0xab, 0xde, 0x38, 0xb8, 0xc9, 0xdb, 0x63, 0x9c, 0xcb, 0xdd, 0x71, - 0xde, 0x4f, 0x1e, 0x43, 0x08, 0xe4, 0xe3, 0x83, 0x86, 0x0f, 0x34, 0xb7, - 0x1e, 0x53, 0xc1, 0xde, 0x46, 0xf1, 0x70, 0xf5, 0xd8, 0x47, 0xd2, 0x9b, - 0x44, 0x88, 0x85, 0x8e, 0x32, 0xa9, 0x0c, 0x09, 0x2f, 0xd0, 0xe4, 0x4b, - 0x30, 0x3a, 0x2e, 0x65, 0x0c, 0xff, 0xb4, 0x0d, 0xa8, 0x8f, 0x61, 0x3e, - 0x7e, 0x90, 0x66, 0xbb, 0xf6, 0xbe, 0xfd, 0x7d, 0xe4, 0xdc, 0x2c, 0x59, - 0x87, 0x81, 0x60, 0x96, 0xd7, 0x1d, 0x10, 0x02, 0x35, 0xdd, 0x16, 0x4c, - 0xe9, 0x2d, 0x52, 0x45, 0xdd, 0x3f, 0xc9, 0xff, 0x8d, 0x19, 0xad, 0x02, - 0x74, 0xf1, 0x09, 0x99, 0x94, 0x66, 0x2e, 0x8b, 0xa3, 0xdc, 0x3d, 0xf3, - 0xf5, 0x85, 0xf2, 0x60, 0x7d, 0x9d, 0xe0, 0xd3, 0x0f, 0xa4, 0x92, 0xf3, - 0x55, 0xbc, 0x7b, 0x20, 0x6b, 0xf6, 0xc4, 0xc4, 0x0f, 0x8a, 0xd7, 0x5a, - 0x02, 0xb0, 0xb7, 0x78, 0xb4, 0x9e, 0xb6, 0x93, 0x95, 0x2e, 0x76, 0x06, - 0x1e, 0x34, 0x5d, 0x34, 0x77, 0x77, 0x6d, 0x32, 0xbb, 0x46, 0xad, 0x43, - 0xd7, 0x72, 0x61, 0x33, 0x4f, 0x98, 0xe9, 0x56, 0x3a, 0x96, 0x89, 0x6e, - 0x1f, 0xaf, 0x6b, 0xa0, 0x9a, 0xe4, 0x42, 0x5a, 0xb3, 0xb8, 0x2a, 0xe1, - 0x2d, 0xa6, 0x32, 0xa2, 0x01, 0xf5, 0x3a, 0x9a, 0xbb, 0x06, 0x76, 0x0b, - 0xa8, 0xac, 0x02, 0x96, 0x0c, 0x58, 0xd3, 0x64, 0xc8, 0xe2, 0xae, 0x6c, - 0xf7, 0xa7, 0x32, 0x4b, 0x51, 0x50, 0x11, 0x90, 0xcf, 0x37, 0xed, 0xd2, - 0xa0, 0xa4, 0x97, 0xb3, 0x45, 0x1d, 0x7d, 0xf3, 0xff, 0xde, 0x9f, 0x80, - 0xa9, 0x61, 0xac, 0x37, 0x7f, 0x5d, 0xc9, 0xf6, 0xdc, 0x26, 0xd0, 0x65, - 0xf2, 0xdc, 0x0c, 0x1a, 0xcb, 0xde, 0x6b, 0x77, 0xf3, 0x08, 0xa4, 0x93, - 0xab, 0x2a, 0xdf, 0x18, 0x1a, 0xc7, 0xa6, 0xa1, 0x7e, 0x43, 0x75, 0xca, - 0x88, 0xcc, 0x6f, 0xa2, 0x85, 0x0e, 0xb0, 0xd5, 0xcd, 0x8a, 0xff, 0xc1, - 0x57, 0x20, 0x66, 0xf7, 0x19, 0x7a, 0x52, 0x5b, 0x46, 0x87, 0x5f, 0xf7, - 0x77, 0xe2, 0xab, 0x4e, 0x4a, 0xce, 0x8f, 0x3f, 0xe6, 0x9f, 0x88, 0x3a, - 0x33, 0x65, 0x3c, 0x3a, 0x41, 0xc3, 0x8e, 0xee, 0x79, 0xe7, 0x2c, 0xb0, - 0x3b, 0x93, 0x82, 0xa0, 0x1a, 0x71, 0x0e, 0xf6, 0x31, 0xc5, 0x6f, 0xc1, - 0xa8, 0x32, 0x89, 0x3b, 0x33, 0x68, 0x53, 0x81, 0x15, 0x70, 0x5e, 0x22, - 0xdc, 0x99, 0xc6, 0x88, 0xf8, 0x11, 0x06, 0x56, 0x1f, 0x80, 0x7e, 0x0b, - 0x27, 0x90, 0xfc, 0x97, 0x76, 0x61, 0xdc, 0x30, 0x5d, 0x34, 0x4e, 0x83, - 0x85, 0xce, 0xe2, 0x91, 0x4d, 0x8d, 0x92, 0x88, 0x26, 0xa0, 0xde, 0x47, - 0x82, 0xd2, 0xa8, 0xa5, 0xe7, 0x27, 0x0c, 0x45, 0x41, 0x85, 0xa1, 0x12, - 0xcb, 0x3a, 0x74, 0x53, 0x93, 0x77, 0xd0, 0x8b, 0x42, 0x8d, 0x00, 0xca, - 0x44, 0x67, 0xa0, 0x6a, 0xbd, 0xcd, 0x4a, 0x3c, 0xfe, 0x6c, 0xa1, 0x48, - 0x26, 0x0d, 0x51, 0x54, 0x59, 0xc9, 0xf9, 0x51, 0x5c, 0xd3, 0x55, 0xf0, - 0x72, 0x77, 0xdb, 0x52, 0xee, 0x0a, 0x5e, 0x8a, 0xf0, 0xbe, 0x9a, 0x37, - 0xa0, 0x1b, 0x94, 0xe3, 0x2d, 0x17, 0xc4, 0xbe, 0x9c, 0xad, 0x9c, 0xd1, - 0xc6, 0xbc, 0x36, 0x5c, 0x3b, 0xe3, 0x2e, 0x66, 0x29, 0x0c, 0x3a, 0x3d, - 0xe7, 0xe3, 0xf3, 0x58, 0x70, 0x3e, 0x59, 0xb2, 0x6c, 0x91, 0x14, 0xfe, - 0x9e, 0x5e, 0x5d, 0xb2, 0x7b, 0x46, 0x66, 0x46, 0x55, 0xe2, 0x78, 0x47, - 0xeb, 0xdf, 0x2b, 0xb4, 0xf2, 0xb2, 0x14, 0xbe, 0x64, 0x9e, 0x17, 0x16, - 0x9f, 0xf5, 0x6a, 0xdd, 0x25, 0xa1, 0x55, 0x6e, 0xb1, 0xfa, 0x09, 0xd0, - 0x97, 0x7c, 0x13, 0xde, 0x1d, 0xd4, 0x94, 0x19, 0xde, 0x8b, 0x4d, 0xe7, - 0xee, 0x1f, 0xdf, 0xe5, 0x3b, 0xdd, 0xbd, 0x13, 0x9c, 0xec, 0xcd, 0xb6, - 0xb6, 0xbb, 0x3f, 0xbd, 0x54, 0xca, 0x47, 0x5c, 0x05, 0x3c, 0x03, 0x30, - 0x9d, 0x56, 0xf6, 0xc6, 0x48, 0x6b, 0x74, 0x49, 0x58, 0xa2, 0xd8, 0x45, - 0x42, 0x6f, 0xe4, 0x46, 0x27, 0x92, 0x83, 0x78, 0x97, 0x55, 0x5b, 0x82, - 0xce, 0x2a, 0x08, 0x41, 0xb9, 0x7a, 0x66, 0x0f, 0x3c, 0x5b, 0xdf, 0x8d, - 0x1d, 0x02, 0x11, 0xa4, 0xa7, 0x0a, 0x80, 0x1e, 0xbb, 0x7a, 0xc9, 0x2f, - 0xb9, 0x35, 0xc8, 0xd7, 0x98, 0x04, 0x29, 0xaa, 0x4b, 0x88, 0x66, 0x73, - 0xe4, 0x59, 0xc4, 0x3e, 0x50, 0xad, 0xe5, 0x64, 0x54, 0xf0, 0x29, 0x38, - 0xee, 0xc0, 0x00, 0xc4, 0x22, 0x16, 0xf2, 0xc5, 0x46, 0x5c, 0xee, 0x9e, - 0xf2, 0x9a, 0xe7, 0xfd, 0x62, 0x50, 0xa2, 0xeb, 0x47, 0x56, 0x4c, 0xe4, - 0x75, 0x46, 0xe4, 0xd5, 0x25, 0xec, 0xe0, 0x35, 0x33, 0x31, 0x34, 0x1b, - 0xcb, 0x72, 0x78, 0x1c, 0x4d, 0x3a, 0x19, 0x2e, 0xc4, 0xb7, 0xa4, 0x80, - 0xd2, 0x91, 0xeb, 0x2a, 0x1d, 0xf2, 0xd1, 0xa3, 0xae, 0xac, 0x41, 0xae, - 0xc2, 0x44, 0xd2, 0x3f, 0xb4, 0x87, 0x8d, 0x69, 0x6c, 0x67, 0xd6, 0x85, - 0xee, 0xd6, 0x3b, 0x03, 0xdc, 0x58, 0x46, 0x07, 0x73, 0xb4, 0xb0, 0x3f, - 0x5e, 0xc1, 0x13, 0x2c, 0x36, 0x58, 0xd0, 0x1c, 0x34, 0x3e, 0x01, 0x88, - 0xfa, 0xb1, 0x9a, 0x03, 0x85, 0x4f, 0x4c, 0xd2, 0xac, 0xd9, 0x12, 0x09, - 0xaa, 0x5f, 0x20, 0x06, 0x1f, 0x0a, 0x44, 0x28, 0x50, 0xd1, 0x8f, 0x51, - 0x8a, 0x1d, 0xfa, 0xaa, 0x46, 0x33, 0xac, 0x0c, 0xb3, 0x10, 0xcf, 0x24, - 0x4d, 0x0f, 0xcd, 0xee, 0xd9, 0x64, 0x4a, 0x1a, 0x84, 0x0f, 0xff, 0x48, - 0x8d, 0x79, 0xd4, 0x43, 0x70, 0x1c, 0x7e, 0x7e, 0x12, 0x43, 0x51, 0x4a, - 0x7e, 0x45, 0x9e, 0xa4, 0x3c, 0x12, 0xbd, 0x95, 0xe9, 0xd6, 0xd4, 0x3f, - 0xbf, 0x03, 0xae, 0x9e, 0x24, 0x1a, 0x36, 0xbd, 0xea, 0x5d, 0x65, 0xff, - 0x9f, 0x95, 0x70, 0xda, 0xb0, 0x53, 0x6a, 0x5f, 0x64, 0x7b, 0xb6, 0x7a, - 0x8d, 0xa2, 0xd4, 0x9c, 0xb1, 0xf9, 0xe6, 0x14, 0x62, 0x3b, 0xe7, 0x5b, - 0x40, 0x9d, 0xf4, 0x19, 0xb5, 0x50, 0xc8, 0xbd, 0x76, 0xd3, 0xbc, 0x0e, - 0x6d, 0x62, 0x91, 0x73, 0x3e, 0x7f, 0xbf, 0xd0, 0xf0, 0x33, 0xf8, 0x6a, - 0x9f, 0xa6, 0xad, 0xc3, 0xa0, 0x8f, 0x45, 0x99, 0x86, 0xa7, 0x49, 0x18, - 0x8a, 0xed, 0xf1, 0x7d, 0x39, 0xf4, 0xb4, 0xf9, 0x82, 0x62, 0xd0, 0xa1, - 0xb8, 0x3f, 0xe8, 0x25, 0xf7, 0xb1, 0x59, 0xce, 0x31, 0xba, 0x1d, 0x0b, - 0x1f, 0x3d, 0x6c, 0x8b, 0xd2, 0xc5, 0x4e, 0x8e, 0xe8, 0x09, 0x9e, 0x1f, - 0xf3, 0x67, 0x6f, 0x09, 0x03, 0x9d, 0xfe, 0x57, 0x6d, 0x9b, 0xce, 0x99, - 0x7b, 0x01, 0x04, 0x52, 0xf5, 0x41, 0x7e, 0x38, 0x56, 0xb8, 0x71, 0x44, - 0x43, 0x2c, 0x5e, 0x92, 0x9d, 0x95, 0xff, 0x0b, 0xf8, 0xfa, 0x89, 0x2c, - 0x58, 0xde, 0xc5, 0x4e, 0x02, 0xe3, 0x82, 0xf7, 0xdc, 0x92, 0xa8, 0x7c, - 0x39, 0x32, 0x76, 0x68, 0x9c, 0x73, 0x75, 0x1f, 0xbc, 0x6b, 0x46, 0x33, - 0x5a, 0xdb, 0x94, 0x8c, 0x76, 0x79, 0x7e, 0x9b, 0xcc, 0x37, 0xeb, 0xed, - 0xdc, 0xd5, 0xee, 0x2b, 0x30, 0x3f, 0x7b, 0x9b, 0xac, 0x38, 0x8f, 0xf1, - 0x5e, 0xec, 0xa0, 0x46, 0x2c, 0xd1, 0x27, 0x19, 0x60, 0xec, 0xe2, 0xa7, - 0x45, 0x61, 0x2d, 0xa8, 0x7e, 0xa9, 0xf8, 0x93, 0xa4, 0x23, 0x3e, 0xd8, - 0x9c, 0xcc, 0xb3, 0xee, 0xc3, 0x1c, 0xfb, 0xbb, 0xad, 0xec, 0x73, 0x66, - 0x31, 0x5d, 0x88, 0x9a, 0xec, 0x84, 0x91, 0x1e, 0x58, 0xdd, 0xb0, 0x01, - 0x46, 0x18, 0x43, 0x64, 0xe2, 0xad, 0xac, 0x5a, 0x63, 0x4c, 0x32, 0x6b, - 0xfd, 0xff, 0x66, 0x6d, 0xb4, 0x66, 0x88, 0xec, 0xfe, 0x23, 0xaa, 0x3a, - 0x2a, 0xd5, 0xff, 0xed, 0x3a, 0x13, 0x9a, 0xae, 0x73, 0xc5, 0x62, 0x32, - 0x47, 0x89, 0x19, 0x7f, 0x2c, 0x88, 0x62, 0x34, 0xc2, 0x90, 0xa9, 0x59, - 0x7c, 0x45, 0xdb, 0x98, 0xaf, 0xf4, 0xba, 0x4e, 0x45, 0x55, 0xfc, 0x70, - 0xa9, 0xfd, 0xb4, 0xa3, 0xd9, 0xa8, 0xfb, 0xe2, 0xe6, 0xf9, 0x60, 0xc1, - 0x42, 0x70, 0x3d, 0xa5, 0x28, 0xcc, 0xd3, 0x54, 0x87, 0xda, 0x93, 0x91, - 0x42, 0xa8, 0x8b, 0x62, 0xf3, 0x4e, 0xb7, 0x86, 0xfa, 0x52, 0x19, 0x69, - 0xe3, 0x6c, 0xd1, 0xc3, 0x23, 0x82, 0xf7, 0x1d, 0xa1, 0x80, 0x92, 0xcd, - 0x5e, 0x1a, 0x62, 0x3e, 0x1b, 0x31, 0x9d, 0x0d, 0xa8, 0x25, 0x3e, 0x83, - 0xae, 0x36, 0xce, 0xfd, 0xac, 0xf7, 0x35, 0x7f, 0x74, 0xf4, 0x66, 0xa3, - 0x5f, 0x00, 0xe5, 0x30, 0xc1, 0x11, 0x70, 0x00, 0xb5, 0xd9, 0xd4, 0x6e, - 0x95, 0xc4, 0xbc, 0x5b, 0x7d, 0x62, 0x6c, 0xd5, 0xc0, 0x1e, 0x81, 0xc0, - 0x61, 0x69, 0x13, 0x63, 0xbc, 0x7f, 0x70, 0x3f, 0x3d, 0x96, 0x18, 0x39, - 0xef, 0x51, 0xc6, 0xe9, 0xcc, 0x59, 0xda, 0xc7, 0x5d, 0xb5, 0x59, 0xb0, - 0xf2, 0x99, 0x5a, 0x36, 0x21, 0x0d, 0xcc, 0x97, 0x16, 0x2b, 0x61, 0x3d, - 0x0a, 0xd1, 0x6e, 0x05, 0x86, 0x42, 0xff, 0xd8, 0xa7, 0x5c, 0x02, 0xcf, - 0x90, 0x6b, 0x4e, 0xee, 0x4e, 0xca, 0xdb, 0xd3, 0xfe, 0x7e, 0x9b, 0xe2, - 0xf0, 0xa3, 0x45, 0x6d, 0xa9, 0x92, 0xba, 0xce, 0xc6, 0x2e, 0x0a, 0xbc, - 0xb2, 0x7a, 0x57, 0x07, 0x33, 0xc2, 0xa7, 0x16, 0x25, 0x06, 0x36, 0x83, - 0x35, 0x31, 0x87, 0x18, 0x83, 0xa3, 0xc2, 0x88, 0x55, 0xcc, 0xe4, 0x84, - 0x4c, 0xce, 0xb9, 0xeb, 0xd5, 0xb2, 0xbe, 0x3d, 0x76, 0x85, 0x10, 0x07, - 0x83, 0xfa, 0x1c, 0x42, 0xbc, 0xa3, 0x4c, 0x29, 0x49, 0xe6, 0xc0, 0x30, - 0x59, 0xe0, 0xc6, 0xbe, 0xa7, 0x48, 0x4a, 0xcf, 0x0e, 0x8e, 0xb7, 0x38, - 0xf2, 0xa6, 0x26, 0xd3, 0x88, 0x06, 0x99, 0x46, 0x19, 0x65, 0x1c, 0x91, - 0x8e, 0xae, 0x90, 0x78, 0x77, 0x7f, 0xe0, 0xc2, 0x51, 0x6f, 0xb6, 0x44, - 0x15, 0xf9, 0xc5, 0x8a, 0x6c, 0x33, 0xd5, 0x90, 0x17, 0xc2, 0xca, 0x4e, - 0xe1, 0x1f, 0xef, 0x02, 0x43, 0x05, 0x3f, 0x1e, 0xb1, 0x13, 0x23, 0x1f, - 0xd6, 0xc2, 0xac, 0xc4, 0x49, 0x7a, 0x86, 0x06, 0x4b, 0xa1, 0x55, 0x6a, - 0x75, 0x91, 0x4e, 0x6b, 0x86, 0x95, 0xa7, 0xbc, 0xdc, 0x64, 0xdb, 0x81, - 0xc6, 0xa5, 0x33, 0x38, 0x98, 0xbb, 0xac, 0x03, 0xf0, 0xba, 0x49, 0xcf, - 0x1c, 0xce, 0xe2, 0x3d, 0xe5, 0x06, 0xbc, 0x5e, 0xd0, 0xf7, 0x1c, 0xbb, - 0x52, 0xa1, 0x47, 0x98, 0x12, 0xef, 0x1c, 0xb9, 0x53, 0xec, 0x67, 0x2c, - 0xf0, 0x7d, 0x85, 0x9e, 0x45, 0x87, 0x00, 0x67, 0x2f, 0xa5, 0x19, 0x9f, - 0x3e, 0x20, 0x8c, 0xe9, 0xfa, 0x8a, 0xd8, 0x02, 0x6e, 0x16, 0xc4, 0x43, - 0xff, 0x08, 0x3f, 0xf3, 0x76, 0x53, 0x95, 0x17, 0x6e, 0x74, 0xfe, 0x7e, - 0x87, 0x66, 0xc9, 0xe8, 0x8d, 0x21, 0xea, 0xd2, 0x4d, 0xc7, 0x9c, 0x5a, - 0xef, 0xd5, 0xe1, 0x12, 0x85, 0x22, 0x40, 0x3c, 0x9d, 0x89, 0x4f, 0x12, - 0xb5, 0x01, 0x95, 0x0e, 0x9b, 0xd3, 0x38, 0x5e, 0x21, 0x5a, 0x4e, 0x7e, - 0xce, 0xf7, 0xa6, 0x5a, 0x63, 0x78, 0x40, 0xba, 0x9f, 0x29, 0xf0, 0x75, - 0xb6, 0x8b, 0xd9, 0x4c, 0xab, 0xb9, 0xf4, 0xe9, 0x1f, 0x39, 0x01, 0xb3, - 0xfc, 0x2c, 0xa4, 0x74, 0xa9, 0xa9, 0x90, 0xed, 0x77, 0xd8, 0x0c, 0x6d, - 0x5c, 0x7b, 0xfc, 0xbd, 0x96, 0x96, 0xcb, 0x9b, 0x9f, 0x88, 0x86, 0x5c, - 0x3c, 0x0a, 0xde, 0x28, 0x7c, 0xf0, 0x91, 0x1c, 0x06, 0x52, 0xbe, 0xad, - 0xc8, 0xef, 0xa5, 0xd3, 0x1e, 0x29, 0xbd, 0x1d, 0xd5, 0xba, 0xf4, 0x83, - 0x2d, 0x36, 0x9a, 0x8c, 0x8d, 0x83, 0xac, 0x3f, 0xea, 0xd2, 0x2e, 0xfb, - 0xf1, 0xaa, 0x7a, 0x2e, 0xce, 0xd3, 0x90, 0x9f, 0x3c, 0x2c, 0xee, 0xed, - 0xf8, 0xfc, 0x3c, 0x0e, 0x5f, 0xd1, 0xda, 0x9c, 0x32, 0x52, 0xcd, 0x09, - 0xa1, 0x53, 0x33, 0x37, 0xe0, 0x37, 0x95, 0xb2, 0x8d, 0x03, 0x46, 0x1f, - 0xb5, 0x99, 0x65, 0x54, 0x61, 0xa2, 0xdc, 0xe9, 0x87, 0x4d, 0x41, 0xdf, - 0xd1, 0xb5, 0x2c, 0x7a, 0x46, 0x08, 0x5e, 0x0f, 0xcc, 0x80, 0x96, 0x52, - 0x98, 0xa0, 0x82, 0x52, 0x6d, 0x62, 0x6f, 0xd9, 0x48, 0xc1, 0x36, 0x0c, - 0x5c, 0x7f, 0xad, 0x2c, 0x27, 0xcf, 0x17, 0xee, 0xfa, 0xca, 0x14, 0xe7, - 0x88, 0xc4, 0x20, 0xb2, 0xa1, 0xd2, 0x66, 0xe8, 0x81, 0xce, 0x35, 0x2b, - 0x30, 0x54, 0x16, 0x9e, 0x42, 0x77, 0x16, 0x3b, 0x84, 0x77, 0x42, 0x71, - 0x33, 0xf8, 0x62, 0x9e, 0xd4, 0x1d, 0x1d, 0xf3, 0x91, 0x60, 0x97, 0xd8, - 0x10, 0x29, 0xc8, 0xf9, 0xfa, 0xca, 0x0a, 0xe9, 0x50, 0xe1, 0xcc, 0xa7, - 0xe3, 0x77, 0xc2, 0x93, 0x68, 0x50, 0x1a, 0x98, 0xd7, 0x68, 0x40, 0x80, - 0x12, 0x64, 0xa7, 0x1d, 0xb4, 0x52, 0x85, 0x7b, 0x0e, 0x85, 0x0a, 0x59, - 0x6a, 0xc8, 0xe4, 0x4b, 0xff, 0xd7, 0x0d, 0x7d, 0x9e, 0xef, 0x07, 0x2f, - 0x6d, 0x46, 0x05, 0xf9, 0x05, 0xb1, 0x97, 0x94, 0x23, 0xc5, 0x2a, 0x99, - 0xcc, 0x9c, 0xc2, 0x82, 0x97, 0xbc, 0x24, 0x9b, 0xe4, 0xf2, 0xb3, 0x12, - 0x84, 0xa0, 0x2a, 0xc4, 0x7d, 0x29, 0x4d, 0xa4, 0x97, 0xd0, 0x85, 0xa6, - 0x39, 0x18, 0xd2, 0xfb, 0xa7, 0x08, 0x53, 0x75, 0x6b, 0xbd, 0xe3, 0x98, - 0x4c, 0x94, 0xdd, 0xd4, 0x86, 0x94, 0xc2, 0x6a, 0x14, 0x23, 0xdd, 0x69, - 0xae, 0x53, 0xec, 0x83, 0x58, 0x8e, 0x87, 0x7b, 0xf1, 0xcf, 0xff, 0x34, - 0xda, 0x39, 0x67, 0xba, 0x90, 0xc5, 0xec, 0xe0, 0xb3, 0xad, 0xad, 0x3d, - 0x4c, 0x8e, 0x3f, 0x08, 0x62, 0x80, 0x5b, 0x2d, 0xf8, 0xe1, 0x67, 0x61, - 0x79, 0xf5, 0xc9, 0xbe, 0x74, 0x1b, 0x72, 0x02, 0x56, 0xc6, 0xf8, 0xd5, - 0x87, 0x3a, 0x08, 0x7b, 0x35, 0x8f, 0xdf, 0xdf, 0x87, 0x3e, 0x09, 0xf7, - 0xd2, 0x74, 0xbb, 0xec, 0x8c, 0x49, 0x0c, 0xb5, 0x3a, 0x6b, 0x33, 0x43, - 0x52, 0xe2, 0x2f, 0x71, 0x3e, 0x6f, 0x59, 0x52, 0x50, 0x8f, 0xdb, 0xa6, - 0x52, 0xa7, 0x5d, 0xda, 0x16, 0x71, 0xb2, 0x52, 0xd7, 0x3e, 0x2d, 0xf6, - 0x98, 0x53, 0x0f, 0x8f, 0xc1, 0x79, 0xd0, 0xcf, 0xe0, 0xc8, 0x22, 0x27, - 0x41, 0x14, 0xe8, 0xb8, 0xed, 0x65, 0x3c, 0xaa, 0x11, 0x72, 0x41, 0xa8, - 0xd8, 0x0b, 0x35, 0x81, 0xec, 0xa6, 0x12, 0x30, 0x23, 0x0b, 0x71, 0x7a, - 0x28, 0xd9, 0x01, 0x82, 0x35, 0xd1, 0x64, 0x6d, 0xf3, 0x63, 0x69, 0x78, - 0xb4, 0x93, 0x1e, 0x05, 0xc9, 0xb3, 0xbc, 0xb6, 0xc4, 0x5e, 0xb6, 0x2a, - 0x6e, 0xec, 0x91, 0x4a, 0x5c, 0xa2, 0x5c, 0xea, 0x2b, 0xe3, 0x33, 0x1a, - 0xb3, 0x70, 0xd5, 0x39, 0x77, 0x3e, 0xa2, 0x96, 0xd5, 0x10, 0x75, 0x8a, - 0x91, 0xc6, 0xbc, 0xb6, 0x86, 0xa6, 0x8f, 0xd3, 0x50, 0x09, 0xa3, 0x9a, - 0x1f, 0xd0, 0xd7, 0xd7, 0x23, 0xa0, 0x32, 0xd0, 0x69, 0x33, 0x2f, 0x18, - 0xf2, 0x6f, 0xe2, 0xbc, 0x2f, 0x7f, 0xf5, 0x46, 0x81, 0x2e, 0xad, 0x14, - 0xc9, 0x57, 0x10, 0xa4, 0x71, 0xa9, 0xa4, 0x05, 0x50, 0xcb, 0x93, 0xc7, - 0x53, 0x84, 0x68, 0xa5, 0x7c, 0x65, 0xc0, 0xe0, 0x37, 0xd6, 0xc3, 0xbb, - 0x36, 0xef, 0x22, 0x9e, 0x09, 0x32, 0xa5, 0xa6, 0x73, 0x61, 0xb6, 0x3c, - 0x5a, 0xbe, 0x2f, 0x63, 0x01, 0x35, 0xfe, 0xd8, 0x98, 0xd5, 0x7e, 0xfd, - 0x68, 0xd8, 0x96, 0x51, 0x6e, 0x3a, 0x17, 0x90, 0x16, 0xeb, 0x03, 0xfa, - 0x0a, 0x83, 0x1a, 0xc9, 0x48, 0x14, 0x31, 0x32, 0x07, 0x7d, 0xa8, 0xa8, - 0x64, 0xd8, 0xba, 0xcf, 0x87, 0xc5, 0x0e, 0xc3, 0x1c, 0x5b, 0xfe, 0x31, - 0x98, 0xea, 0x25, 0x29, 0x9c, 0x77, 0xf2, 0x9f, 0x5e, 0x16, 0x11, 0x6b, - 0x29, 0x08, 0xab, 0xb0, 0x57, 0xd8, 0x3d, 0x85, 0xdc, 0x3b, 0x69, 0xea, - 0xd5, 0xe6, 0x90, 0xfa, 0x95, 0x8d, 0xcc, 0x3c, 0x2d, 0x86, 0x07, 0xc6, - 0x7e, 0x8d, 0xc4, 0x7a, 0x3a, 0xcd, 0x61, 0xa4, 0x1f, 0xd9, 0x6f, 0x07, - 0xa3, 0x45, 0xe8, 0x41, 0xed, 0x51, 0x14, 0xe4, 0x3d, 0x20, 0x3b, 0x11, - 0x9e, 0x93, 0xc3, 0x2e, 0xcd, 0x29, 0x85, 0xf0, 0x61, 0x68, 0x8e, 0x19, - 0xdc, 0x20, 0x0a, 0xbd, 0xc0, 0x15, 0x90, 0x08, 0x96, 0xcf, 0x9b, 0xf3, - 0xb5, 0x7b, 0xe4, 0x9a, 0x97, 0x22, 0x93, 0x40, 0xd4, 0xde, 0x7a, 0x6e, - 0x6b, 0xc4, 0x16, 0x9e, 0x1c, 0x98, 0x9b, 0x83, 0x6e, 0x4d, 0xde, 0x11, - 0x4f, 0x22, 0xed, 0x2d, 0xe1, 0xb3, 0xfa, 0x86, 0xb0, 0xd2, 0x53, 0xd2, - 0x34, 0x8a, 0x58, 0xdc, 0x8c, 0xd9, 0x60, 0xd3, 0x46, 0x0a, 0xde, 0x48, - 0xa3, 0xda, 0x5b, 0x74, 0x3e, 0x4c, 0x51, 0xa6, 0x02, 0x20, 0xc6, 0x0d, - 0xdb, 0x13, 0x42, 0xad, 0xc6, 0x90, 0xb1, 0xe0, 0xb0, 0xac, 0xdc, 0xa7, - 0x48, 0xf8, 0x2d, 0x8f, 0xd7, 0xd9, 0x10, 0xeb, 0xd8, 0xdb, 0xf0, 0x53, - 0x67, 0xa9, 0x03, 0x3e, 0x97, 0xbf, 0xe6, 0xc3, 0xa8, 0x87, 0x3a, 0x91, - 0xb8, 0xcf, 0x88, 0x5b, 0x0d, 0x06, 0xe1, 0xe2, 0x39, 0x74, 0xc8, 0x59, - 0xe0, 0x90, 0x9f, 0xc9, 0x0a, 0x74, 0xa3, 0xb2, 0xae, 0x69, 0x79, 0xfa, - 0x0d, 0xf2, 0xee, 0xde, 0xec, 0x88, 0xbf, 0x09, 0x54, 0xd6, 0xbe, 0xbb, - 0x25, 0x91, 0xe4, 0x66, 0xd2, 0x08, 0x78, 0xda, 0x9d, 0x07, 0xc3, 0x0b, - 0x3f, 0x1a, 0xd9, 0xf4, 0xb2, 0x2d, 0x69, 0x74, 0xb1, 0x78, 0x5f, 0xc1, - 0xaf, 0x7f, 0x6d, 0x17, 0xfc, 0x2c, 0x67, 0x62, 0xce, 0xb4, 0x41, 0x6e, - 0x21, 0x4b, 0x5c, 0x77, 0xa1, 0x1f, 0xfe, 0xe6, 0x28, 0xc8, 0x52, 0xd1, - 0x8e, 0x66, 0x88, 0x65, 0x0c, 0x58, 0xec, 0x1c, 0x71, 0x4c, 0x8a, 0xc0, - 0xef, 0x3e, 0x34, 0xf7, 0x90, 0x67, 0x28, 0x16, 0x20, 0x3a, 0x2c, 0x3f, - 0x51, 0x53, 0x15, 0x1c, 0x6c, 0x75, 0x0e, 0xe1, 0xb4, 0xf3, 0x7f, 0x60, - 0x3a, 0x81, 0x34, 0x82, 0x51, 0x5e, 0x75, 0xb0, 0x5c, 0x37, 0x87, 0x2d, - 0xd5, 0xc5, 0x2c, 0xab, 0x33, 0x8a, 0x60, 0x49, 0x2c, 0xde, 0x90, 0x12, - 0x11, 0x1f, 0x4b, 0x27, 0x15, 0x92, 0xa2, 0xf1, 0x1a, 0xde, 0x35, 0x34, - 0x4d, 0x52, 0xcd, 0xc0, 0x71, 0x46, 0x7f, 0x3e, 0x21, 0x92, 0x5f, 0xc8, - 0x25, 0xd4, 0x2c, 0xf4, 0xd9, 0x38, 0xde, 0xa5, 0xae, 0x83, 0xe3, 0x50, - 0x9b, 0x1b, 0xad, 0x4b, 0xd8, 0x3f, 0x0a, 0x23, 0x40, 0x1e, 0x46, 0x7a, - 0x71, 0x06, 0xac, 0x9e, 0x06, 0xb8, 0x96, 0xef, 0x07, 0xef, 0x38, 0xe9, - 0x79, 0xaa, 0x64, 0x44, 0xa9, 0xa3, 0xc5, 0x1d, 0x5d, 0xd3, 0xa7, 0x01, - 0xef, 0xf6, 0x3b, 0x15, 0x00, 0x0c, 0xf7, 0x59, 0x4a, 0x1c, 0x12, 0x20, - 0x89, 0xa8, 0x4e, 0x7b, 0xf8, 0x9d, 0x02, 0xa6, 0x5e, 0x19, 0x7e, 0xb8, - 0x5f, 0x46, 0xd9, 0xb1, 0xbe, 0x25, 0x2c, 0x3c, 0xe7, 0x5d, 0x3b, 0x3f, - 0x6f, 0x6e, 0x94, 0x83, 0xc3, 0x8e, 0x85, 0x65, 0xff, 0xe9, 0x8e, 0x32, - 0xcc, 0x68, 0x51, 0x14, 0xbf, 0x94, 0x21, 0x3f, 0x85, 0xa8, 0x76, 0x44, - 0xe6, 0xca, 0x20, 0x84, 0xec, 0x83, 0x84, 0x64, 0xfb, 0x80, 0x01, 0x73, - 0x76, 0x21, 0xd3, 0xf0, 0x7b, 0x74, 0x5c, 0xbf, 0x71, 0xe6, 0x34, 0xff, - 0x58, 0xe8, 0x6f, 0x88, 0xa6, 0xad, 0xcf, 0x93, 0x2a, 0xc5, 0xc5, 0x23, - 0x32, 0xc8, 0xec, 0xbd, 0xf9, 0x54, 0x3d, 0xda, 0xe4, 0x81, 0x74, 0x94, - 0xbf, 0x36, 0x72, 0x11, 0xf0, 0x8a, 0x8f, 0x1b, 0x55, 0x47, 0x70, 0x7d, - 0x61, 0xf0, 0x7b, 0x11, 0x56, 0xdb, 0xbc, 0xe5, 0x72, 0xf2, 0xbd, 0x0b, - 0xa0, 0x80, 0x03, 0x1a, 0xc6, 0xe9, 0xfc, 0xcd, 0xde, 0x42, 0xae, 0x1a, - 0x7d, 0x90, 0x5d, 0x21, 0x5b, 0x3d, 0x69, 0x6f, 0x42, 0x42, 0xf2, 0x8a, - 0xc8, 0xfc, 0xb9, 0xa9, 0xdf, 0x18, 0xc4, 0x97, 0x91, 0x21, 0x28, 0xfd, - 0x82, 0x8a, 0xe7, 0xac, 0xe5, 0x5d, 0x33, 0x7b, 0x78, 0x0a, 0x48, 0x43, - 0xfe, 0xfe, 0xcf, 0x09, 0x5f, 0xed, 0x18, 0x33, 0x0c, 0xab, 0x8a, 0x5d, - 0x63, 0xd5, 0x43, 0x0b, 0xde, 0x75, 0x56, 0xef, 0x11, 0x05, 0x8c, 0xbb, - 0xc0, 0x10, 0x4e, 0x85, 0x70, 0xe1, 0x7e, 0x62, 0xb6, 0x3a, 0x84, 0x80, - 0x17, 0xab, 0x38, 0x59, 0x0b, 0xe2, 0xb1, 0x31, 0xb8, 0xb5, 0xf5, 0xad, - 0xf6, 0xbf, 0x5b, 0xfb, 0x69, 0xc8, 0xb3, 0xce, 0x65, 0xd4, 0x8e, 0x04, - 0xc5, 0xc4, 0x09, 0xba, 0x36, 0xc9, 0x90, 0xe0, 0xc2, 0x21, 0x3a, 0x94, - 0x83, 0xa5, 0xd1, 0xb2, 0xe1, 0xae, 0x6a, 0x28, 0x22, 0x59, 0x79, 0x72, - 0x82, 0x42, 0x89, 0x42, 0x9c, 0xc3, 0xdf, 0x8d, 0x15, 0x22, 0x14, 0xb3, - 0xfd, 0x2a, 0x85, 0xbe, 0xd3, 0x12, 0xa5, 0x3b, 0x0c, 0x99, 0xb2, 0xe5, - 0x43, 0x8d, 0xd7, 0xc0, 0xa1, 0xb6, 0xb2, 0xae, 0x42, 0x4a, 0xc0, 0xe5, - 0x09, 0xa2, 0xf6, 0xa4, 0xbc, 0x01, 0xee, 0x94, 0xd2, 0x0b, 0xeb, 0x28, - 0x80, 0xc9, 0x7a, 0x07, 0xd7, 0x4b, 0xee, 0x01, 0x10, 0x48, 0xcc, 0xc6, - 0x03, 0x99, 0x9d, 0x67, 0x2a, 0xbd, 0xa0, 0x6f, 0x51, 0xa4, 0x75, 0x50, - 0xe1, 0x84, 0x8e, 0xda, 0x7b, 0x5e, 0x9e, 0x78, 0x18, 0x2a, 0x6b, 0xfa, - 0xef, 0x87, 0x81, 0xe9, 0x48, 0x3f, 0x29, 0x2d, 0xfb, 0x15, 0xd2, 0x15, - 0xb5, 0x5c, 0xed, 0x45, 0x48, 0x30, 0xec, 0x00, 0x55, 0x15, 0x13, 0xc7, - 0x11, 0xc4, 0x29, 0xef, 0x0f, 0xa8, 0xa6, 0xef, 0x19, 0x41, 0xc2, 0xb6, - 0x11, 0xdc, 0xe8, 0xf4, 0xa7, 0x03, 0x80, 0x2d, 0x92, 0xad, 0x7e, 0x7e, - 0x8a, 0x71, 0xa4, 0x6c, 0x16, 0xb9, 0x84, 0xf5, 0x8d, 0x94, 0xc5, 0xd5, - 0x82, 0x29, 0x42, 0x22, 0x1f, 0x06, 0xca, 0xdd, 0xbf, 0x74, 0x0f, 0x14, - 0x79, 0x26, 0x9c, 0x79, 0x30, 0xcb, 0x01, 0x02, 0x76, 0x22, 0x4f, 0x54, - 0xff, 0x49, 0xa3, 0x03, 0x35, 0x23, 0x45, 0x91, 0xac, 0xed, 0x13, 0x31, - 0xa4, 0x4e, 0x51, 0xe8, 0x9c, 0x5b, 0xe4, 0xcf, 0x41, 0xd3, 0xa0, 0x86, - 0x7f, 0x3a, 0x4d, 0xaf, 0xa7, 0x49, 0x63, 0x47, 0x86, 0x08, 0x88, 0xcf, - 0x01, 0x7a, 0xc4, 0xf5, 0x29, 0x67, 0x8a, 0xd4, 0xdd, 0x6a, 0x6d, 0x81, - 0xb8, 0x29, 0x9d, 0x7c, 0x32, 0x4e, 0x8f, 0x0c, 0x9f, 0x8c, 0x7e, 0x76, - 0xa3, 0xd4, 0x32, 0x80, 0xd0, 0x79, 0x7d, 0x56, 0x99, 0x6d, 0x0b, 0x88, - 0xfc, 0x98, 0xdb, 0xaf, 0x13, 0xf3, 0xb2, 0x20, 0x3f, 0x19, 0xe1, 0x83, - 0x70, 0xd2, 0x26, 0xd0, 0xd2, 0xad, 0x11, 0xeb, 0x3b, 0x31, 0x03, 0x55, - 0x62, 0xca, 0xb5, 0x87, 0x31, 0x7a, 0x11, 0x4c, 0xf2, 0xc3, 0xc2, 0x1c, - 0x42, 0x94, 0x7b, 0xe6, 0x29, 0x86, 0x70, 0x8e, 0x51, 0x4a, 0xa3, 0xf2, - 0xf0, 0xed, 0xa1, 0xc6, 0x18, 0xff, 0xf2, 0xff, 0xe0, 0x07, 0x85, 0xf1, - 0x93, 0x5a, 0x83, 0x1c, 0x4c, 0xa9, 0x9b, 0xc5, 0x0c, 0xc4, 0xf0, 0xde, - 0x71, 0x93, 0x78, 0xd1, 0x3b, 0xcc, 0x5b, 0x51, 0x1f, 0xd7, 0x21, 0x12, - 0x57, 0xd5, 0x2a, 0xea, 0x64, 0x08, 0x0e, 0xf0, 0x3d, 0x42, 0xe7, 0xdf, - 0xc8, 0xea, 0x42, 0x2b, 0x41, 0x55, 0x85, 0xb8, 0x54, 0xa4, 0xc9, 0x3f, - 0xce, 0xfc, 0x1a, 0xde, 0x73, 0x08, 0xaa, 0x09, 0x25, 0x08, 0xa0, 0xdc, - 0x64, 0xb7, 0xe7, 0xcc, 0xde, 0x85, 0xa6, 0xc3, 0xe9, 0xe1, 0x43, 0x71, - 0x86, 0x05, 0x55, 0x86, 0x47, 0xf8, 0x71, 0xbd, 0xf5, 0xd7, 0x38, 0x64, - 0x7f, 0x71, 0x63, 0xe1, 0x22, 0x39, 0x99, 0xc3, 0xdf, 0x27, 0x5d, 0xdd, - 0xd0, 0x57, 0x99, 0xd5, 0x97, 0xcd, 0xd4, 0x2e, 0xc1, 0x25, 0x3d, 0x2e, - 0x03, 0x0b, 0x04, 0x20, 0x70, 0xec, 0x46, 0x6c, 0x4b, 0x55, 0x16, 0x02, - 0x00, 0x71, 0xfd, 0x8a, 0xa0, 0x1e, 0x5f, 0x41, 0xe6, 0x96, 0x58, 0xbe, - 0x02, 0x73, 0x91, 0x71, 0xb2, 0x7e, 0xc4, 0xcd, 0xce, 0xa5, 0x26, 0xee, - 0xff, 0x8c, 0x9a, 0x4c, 0xf4, 0x0a, 0x89, 0xba, 0x14, 0x6e, 0x06, 0x86, - 0xb0, 0xba, 0x41, 0xdd, 0x27, 0xf8, 0xc3, 0x46, 0x4f, 0x39, 0xac, 0x2c, - 0x8a, 0x69, 0x09, 0xb7, 0x36, 0x0f, 0xe0, 0x8d, 0x31, 0x0f, 0xc3, 0xee, - 0x3a, 0x6a, 0x9e, 0x96, 0x91, 0xf5, 0x6a, 0x12, 0x98, 0x5a, 0xc3, 0xf3, - 0xb8, 0x9b, 0x07, 0xdb, 0x8e, 0x2a, 0xb0, 0x91, 0x86, 0xb5, 0xc7, 0xe9, - 0x06, 0xe1, 0x4e, 0x83, 0x28, 0x3a, 0x0e, 0x67, 0xe5, 0x7e, 0x88, 0x2a, - 0x31, 0xd2, 0xfe, 0xf6, 0x19, 0x3d, 0x09, 0xd1, 0xef, 0x5d, 0xe1, 0x15, - 0x2d, 0xb4, 0xec, 0x23, 0xc2, 0x0c, 0x7a, 0xbf, 0xd3, 0x6f, 0xf7, 0x8a, - 0x3b, 0x3a, 0x0f, 0x20, 0xc4, 0x78, 0xbe, 0x46, 0x30, 0x0f, 0xc2, 0xd0, - 0x8c, 0x23, 0xb7, 0xfa, 0x3c, 0x19, 0x35, 0x53, 0x5f, 0xf9, 0x94, 0xf5, - 0x23, 0xbe, 0xb3, 0x56, 0x42, 0xa1, 0x27, 0xff, 0xac, 0xbf, 0x72, 0x7e, - 0x89, 0xbe, 0xb9, 0x6d, 0x2d, 0xc4, 0x3f, 0x6c, 0x7f, 0xc4, 0x7e, 0x01, - 0x09, 0xc8, 0x35, 0x80, 0x99, 0x8f, 0x1c, 0x43, 0xd3, 0xb2, 0x4a, 0xb7, - 0x08, 0x06, 0x63, 0xcd, 0x8a, 0x5e, 0x64, 0xa2, 0x93, 0xa5, 0x15, 0xa0, - 0x38, 0xa0, 0xf2, 0x1c, 0xab, 0xe1, 0x2d, 0x19, 0x30, 0xee, 0x9b, 0x87, - 0x42, 0x54, 0xfb, 0xcc, 0xfe, 0x2a, 0xcd, 0x54, 0xf5, 0xeb, 0x52, 0x6b, - 0xd4, 0x1d, 0xa3, 0x7c, 0xec, 0xf2, 0x56, 0x51, 0x54, 0xab, 0x66, 0xb0, - 0x73, 0x49, 0x3e, 0xc4, 0x89, 0xac, 0xb0, 0xc1, 0x41, 0x6f, 0x19, 0xd6, - 0x41, 0xbd, 0xc2, 0xe2, 0x1a, 0x56, 0xb3, 0x01, 0xc9, 0xdf, 0x46, 0xe7, - 0xa1, 0x42, 0xfa, 0x1c, 0x18, 0x86, 0xe2, 0x07, 0xe4, 0xfe, 0x19, 0x03, - 0x7d, 0xc4, 0x51, 0x78, 0x29, 0x68, 0x73, 0x70, 0x82, 0x98, 0x34, 0x2e, - 0x41, 0x59, 0xd5, 0x20, 0x36, 0xe3, 0xe5, 0x2c, 0xbe, 0x76, 0x23, 0x5d, - 0xb1, 0xf0, 0xda, 0xee, 0x65, 0x54, 0xd9, 0xa1, 0x77, 0x6e, 0xd8, 0x56, - 0xcb, 0x6a, 0x35, 0xb5, 0xaa, 0x97, 0x22, 0x28, 0x4d, 0x74, 0x13, 0x96, - 0x59, 0x3d, 0x3a, 0xe2, 0x26, 0xde, 0xd3, 0xc7, 0xed, 0x97, 0x98, 0xa8, - 0x4a, 0x6b, 0x4b, 0xd1, 0x52, 0xca, 0x84, 0xd6, 0x19, 0x7a, 0x6c, 0x0d, - 0xb4, 0x28, 0x4f, 0xb1, 0xa2, 0xcc, 0x07, 0x08, 0x57, 0xc9, 0x32, 0xd4, - 0xe0, 0xef, 0x96, 0x9a, 0x31, 0x1e, 0x68, 0x1d, 0x7b, 0x57, 0x26, 0x62, - 0xa4, 0x26, 0xaf, 0xc7, 0xd0, 0xab, 0xb6, 0x9e, 0x00, 0x6d, 0xfe, 0x29, - 0x30, 0x53, 0xcd, 0xb8, 0x4e, 0x30, 0x4e, 0xa5, 0xcc, 0xf6, 0xab, 0xca, - 0x4d, 0x74, 0x40, 0xc2, 0xb4, 0xfb, 0x3f, 0x75, 0x0a, 0x9d, 0x88, 0xa3, - 0xb0, 0x5b, 0x4e, 0x88, 0x50, 0x90, 0xcb, 0x5c, 0xcd, 0xc7, 0xff, 0x75, - 0x97, 0xc4, 0x1b, 0xe9, 0x03, 0x8a, 0xa7, 0x62, 0x32, 0x98, 0x60, 0x39, - 0x56, 0xe5, 0x25, 0xed, 0xba, 0x58, 0x67, 0xa3, 0xe8, 0x23, 0xd1, 0x55, - 0xb3, 0xa5, 0xc0, 0xc9, 0x75, 0x14, 0x91, 0xe6, 0x7d, 0x0e, 0xe3, 0xac, - 0xc8, 0x6b, 0xa7, 0xdb, 0x36, 0xe8, 0x44, 0x92, 0x72, 0xf2, 0x6d, 0x10, - 0xeb, 0xd0, 0x7a, 0xdd, 0x00, 0x9b, 0xf8, 0x65, 0xaa, 0xef, 0xed, 0xfb, - 0x84, 0x5f, 0xfb, 0xd8, 0xe9, 0xa8, 0x71, 0xab, 0x20, 0x98, 0x4f, 0x21, - 0x7d, 0x33, 0xe2, 0xb1, 0x3f, 0x95, 0x9c, 0x28, 0xf5, 0xd5, 0x83, 0x01, - 0xe9, 0x71, 0x68, 0xa9, 0x3d, 0x9e, 0x49, 0xfb, 0x6c, 0x83, 0x5f, 0x48, - 0x9d, 0x91, 0x00, 0xab, 0x54, 0x17, 0x11, 0x5b, 0x9d, 0x0a, 0x17, 0x8e, - 0x3a, 0xbc, 0xd5, 0x33, 0xcd, 0x2a, 0x5b, 0x14, 0x39, 0xe4, 0x30, 0x45, - 0xde, 0x6e, 0xde, 0x92, 0x7f, 0xb5, 0x91, 0x5d, 0x5b, 0xe4, 0x18, 0x17, - 0x7c, 0x22, 0x1e, 0x2d, 0x97, 0x8b, 0x6f, 0xe0, 0x54, 0x2e, 0x25, 0xbc, - 0x5f, 0xef, 0x27, 0x1b, 0x95, 0x71, 0xcc, 0x29, 0x96, 0x30, 0x82, 0xb1, - 0x99, 0x98, 0x28, 0x36, 0x5f, 0xd6, 0xf9, 0x13, 0xb3, 0x3d, 0x14, 0x91, - 0x8a, 0x2f, 0xbf, 0x6e, 0x8c, 0x57, 0xf6, 0x8e, 0x32, 0xf2, 0xd3, 0xa5, - 0x1b, 0x2b, 0xba, 0xc8, 0x0d, 0xa4, 0xd3, 0xc2, 0x16, 0x1f, 0x5f, 0xb6, - 0x89, 0x77, 0xa9, 0xf3, 0x7b, 0xb8, 0x11, 0x23, 0x41, 0xd6, 0xe0, 0x47, - 0x3c, 0x94, 0xe0, 0xed, 0xa9, 0xb1, 0x0e, 0x90, 0x38, 0xdd, 0x60, 0xcd, - 0x75, 0x00, 0x36, 0x3a, 0x42, 0xbb, 0xfd, 0xd7, 0xc6, 0x16, 0x38, 0xb4, - 0xc0, 0x1d, 0xb6, 0x46, 0x5c, 0x2f, 0x70, 0x95, 0x8d, 0x74, 0x68, 0xb2, - 0xb5, 0xae, 0x73, 0x22, 0xa1, 0xca, 0x5d, 0xd4, 0x28, 0x1a, 0xd2, 0x19, - 0x1c, 0x43, 0x5e, 0x12, 0x16, 0x15, 0xb4, 0x97, 0x64, 0x10, 0x07, 0x48, - 0xf8, 0xe3, 0xfb, 0x3e, 0xa5, 0x05, 0xcd, 0xc1, 0x29, 0xf0, 0x67, 0xb7, - 0x24, 0x02, 0xac, 0x76, 0x91, 0x64, 0x63, 0x46, 0xfb, 0xfd, 0xaa, 0x5b, - 0x3f, 0xeb, 0xe0, 0xb2, 0x5a, 0x8d, 0xde, 0xdc, 0x92, 0x0c, 0x1e, 0xfc, - 0x82, 0x55, 0xc7, 0x8a, 0xe3, 0x28, 0x57, 0xfe, 0x10, 0xe1, 0xa3, 0x5a, - 0x9e, 0x67, 0x86, 0xf4, 0xa5, 0xf5, 0xa0, 0xbd, 0xa4, 0x3c, 0xda, 0xf3, - 0x83, 0x27, 0x2f, 0x55, 0x73, 0xb6, 0x74, 0x3e, 0xd3, 0xc9, 0x84, 0x1d, - 0xff, 0x61, 0x01, 0x56, 0x30, 0x2a, 0x23, 0x57, 0xbc, 0x88, 0xa7, 0x2f, - 0x6f, 0x95, 0x91, 0x4e, 0x5b, 0x41, 0xd9, 0x95, 0x1f, 0x09, 0x95, 0x79, - 0x36, 0xe3, 0x7f, 0xbd, 0x4b, 0x09, 0x4e, 0x7f, 0x6a, 0x58, 0x6e, 0xd0, - 0x60, 0xaf, 0xf1, 0x8f, 0x4c, 0xc5, 0x5a, 0x5c, 0xb7, 0x74, 0x83, 0x3c, - 0xb3, 0x7e, 0xdc, 0x76, 0x89, 0xa5, 0xca, 0xd7, 0x75, 0x35, 0xb2, 0x4c, - 0x0a, 0x67, 0x2b, 0x7a, 0xe8, 0xac, 0x9e, 0x26, 0xa3, 0xae, 0x87, 0x66, - 0x12, 0x4e, 0x74, 0xc8, 0xd8, 0x6d, 0x89, 0x9c, 0x34, 0x63, 0x61, 0x33, - 0x1b, 0x6a, 0x78, 0x7f, 0x2f, 0xa7, 0x9b, 0xe7, 0x42, 0x0d, 0xcb, 0xc9, - 0xf0, 0xa6, 0xb5, 0x38, 0x66, 0x80, 0xca, 0x7a, 0xa9, 0xe4, 0x93, 0xe3, - 0xfc, 0x7d, 0x38, 0x7d, 0x7a, 0x2c, 0x03, 0xb4, 0x35, 0xde, 0x1b, 0x2e, - 0x29, 0x24, 0x40, 0x93, 0x6c, 0x52, 0x21, 0xd6, 0x70, 0x88, 0xfd, 0xc7, - 0x5c, 0x94, 0x95, 0xc0, 0x03, 0xce, 0x1b, 0xb3, 0x0e, 0x87, 0xac, 0xa0, - 0x88, 0xcd, 0x20, 0x3d, 0x88, 0x6f, 0xac, 0x29, 0x2e, 0xcc, 0x7d, 0xa7, - 0x09, 0x16, 0xc0, 0xcc, 0x55, 0x43, 0x19, 0xdc, 0x5e, 0xc4, 0xe5, 0x7c, - 0xfb, 0x50, 0x01, 0x41, 0xe1, 0x70, 0x84, 0x3e, 0x60, 0x88, 0x05, 0x27, - 0x4b, 0x6c, 0x59, 0x9a, 0x01, 0x50, 0xec, 0x74, 0x6a, 0x98, 0x57, 0xfe, - 0xf5, 0x63, 0xc3, 0x60, 0x55, 0x23, 0x33, 0xf9, 0x2d, 0xf0, 0x68, 0xff, - 0xad, 0x61, 0xdb, 0x5e, 0xdb, 0x0c, 0x54, 0x68, 0x8c, 0x4b, 0x64, 0x94, - 0x3c, 0xa8, 0xb1, 0x31, 0x61, 0xf3, 0xb3, 0xed, 0x8f, 0xd5, 0x07, 0x27, - 0xbf, 0xa3, 0xa2, 0x42, 0x4a, 0xa1, 0x5e, 0xc9, 0xb3, 0x9a, 0x0f, 0xbb, - 0xf7, 0xc7, 0x4d, 0x0b, 0xee, 0xbd, 0xce, 0x9e, 0x8c, 0x14, 0x7e, 0x06, - 0x6e, 0x6d, 0x9b, 0xdd, 0x22, 0xc6, 0xc2, 0x62, 0xa5, 0x45, 0xc1, 0xe1, - 0x97, 0xe2, 0x50, 0x25, 0xcc, 0x9b, 0xc4, 0x5d, 0x2d, 0x45, 0x10, 0xad, - 0xa8, 0x4f, 0x27, 0xc3, 0x1a, 0x2c, 0xef, 0x38, 0x2d, 0xa7, 0xaf, 0xe5, - 0x23, 0x7a, 0x8f, 0xbf, 0x9c, 0xd0, 0xb6, 0x31, 0x5c, 0xaa, 0xd2, 0x8c, - 0xd8, 0x91, 0x00, 0xa1, 0x8b, 0x4d, 0x3e, 0x27, 0x22, 0x6c, 0x0f, 0x64, - 0x95, 0x89, 0xa6, 0x29, 0x90, 0xf9, 0xa9, 0x24, 0x24, 0xb8, 0x71, 0x56, - 0x7a, 0xc5, 0xa9, 0x26, 0x9f, 0xf6, 0x2a, 0xa6, 0xf1, 0xca, 0x2a, 0x17, - 0x14, 0x8c, 0x8d, 0xf2, 0x44, 0x7d, 0x49, 0x4e, 0x9b, 0x4f, 0xef, 0x72, - 0x7e, 0xe8, 0x0f, 0x45, 0xb3, 0x3d, 0x61, 0xf5, 0x9d, 0x3f, 0x9a, 0xe3, - 0x93, 0xdd, 0x3d, 0x02, 0x84, 0x7d, 0xd4, 0x84, 0xa8, 0x23, 0xe9, 0x43, - 0xb6, 0x66, 0xf2, 0xb7, 0x35, 0xcf, 0xa3, 0x2f, 0xbe, 0x48, 0x0e, 0xaa, - 0xfe, 0xe9, 0x7e, 0xb0, 0x4d, 0xb3, 0x6b, 0x69, 0xdc, 0xef, 0x20, 0xec, - 0xce, 0x6c, 0xad, 0x7a, 0x20, 0x35, 0xf2, 0xfd, 0x09, 0xe1, 0xdb, 0xca, - 0x2a, 0x55, 0xf7, 0x60, 0xca, 0xf3, 0x85, 0x12, 0xe6, 0x05, 0x4f, 0xc8, - 0x6e, 0x76, 0xda, 0x5f, 0x45, 0x1e, 0xed, 0xdf, 0x57, 0x4c, 0xeb, 0x7e, - 0x28, 0xf7, 0x39, 0xc4, 0xd0, 0x10, 0x32, 0xa9, 0xcc, 0x25, 0xd9, 0x0b, - 0x8c, 0x8a, 0xf6, 0x6c, 0x84, 0xde, 0x09, 0x8c, 0xf6, 0xa4, 0x95, 0xb3, - 0x65, 0x5e, 0x49, 0x36, 0x8c, 0x51, 0x85, 0x62, 0xcc, 0xe6, 0x2a, 0x3d, - 0xdc, 0x68, 0x08, 0x41, 0x73, 0x18, 0x74, 0x10, 0xe5, 0x18, 0xfa, 0xbe, - 0x2f, 0xaa, 0x98, 0x3c, 0x7c, 0x44, 0x43, 0x3f, 0xd6, 0x27, 0xd3, 0x28, - 0xf0, 0x2b, 0xeb, 0xf2, 0x46, 0xfc, 0xf6, 0x3f, 0xc7, 0xa8, 0xc0, 0xf0, - 0x17, 0xef, 0x35, 0xde, 0x55, 0x30, 0xef, 0xf7, 0x7b, 0x57, 0xf3, 0x9f, - 0x00, 0xb5, 0x49, 0x1e, 0xc4, 0x6a, 0xea, 0x0e, 0x40, 0x95, 0x47, 0x55, - 0x32, 0x4f, 0x4f, 0x24, 0x5a, 0x10, 0xaa, 0x1f, 0x5b, 0x9b, 0xc1, 0xb3, - 0xaa, 0xa3, 0x40, 0x32, 0x56, 0x80, 0xbf, 0x38, 0xbc, 0x89, 0xad, 0xa8, - 0x0e, 0x8f, 0x8e, 0x14, 0x17, 0x5a, 0x9b, 0x25, 0x85, 0x85, 0xa7, 0x43, - 0xc8, 0x19, 0x21, 0xf9, 0xa3, 0xdc, 0xb9, 0xc8, 0x70, 0x7b, 0xc8, 0x42, - 0x38, 0x50, 0xb9, 0xcf, 0x90, 0x6e, 0x88, 0x7f, 0x5a, 0x56, 0xc8, 0xd7, - 0x84, 0x7b, 0x69, 0xe1, 0x31, 0x6d, 0xe9, 0xc7, 0x7f, 0x39, 0x78, 0x52, - 0xa2, 0x0c, 0xc7, 0x3b, 0x89, 0x05, 0x9d, 0x66, 0xc6, 0xea, 0x48, 0x75, - 0xa5, 0xd6, 0x89, 0x8e, 0x47, 0xdf, 0x81, 0x28, 0x94, 0xc7, 0x98, 0xd4, - 0x1c, 0x6f, 0x95, 0xdd, 0x20, 0x74, 0xe9, 0xde, 0xb5, 0x3b, 0x87, 0xa1, - 0x1a, 0x1e, 0xee, 0xc7, 0xbc, 0xa4, 0x12, 0x30, 0x92, 0x60, 0x9f, 0x0d, - 0x4d, 0x23, 0x1f, 0xa0, 0xea, 0x07, 0x84, 0x10, 0xb3, 0xd3, 0x2a, 0x2f, - 0x27, 0xdb, 0x27, 0x76, 0xb8, 0x43, 0xe2, 0x9a, 0xfc, 0x9b, 0x81, 0x43, - 0xd2, 0xbc, 0xc2, 0xbb, 0x40, 0xbd, 0xe8, 0x10, 0xd5, 0xca, 0xd2, 0x10, - 0x5e, 0x18, 0xfe, 0x45, 0x1d, 0xc2, 0xf9, 0x99, 0x50, 0xbe, 0x7e, 0xca, - 0x1a, 0x45, 0x17, 0x99, 0x03, 0x9d, 0x2b, 0x68, 0xb7, 0x76, 0x3e, 0x68, - 0x41, 0x81, 0x6d, 0xe3, 0x77, 0xbe, 0x4e, 0xc9, 0x41, 0xb7, 0x8a, 0xb7, - 0xa7, 0x59, 0xfa, 0x04, 0x7b, 0xde, 0xd0, 0x3f, 0x7a, 0x57, 0xa3, 0xf1, - 0x9e, 0x0a, 0x66, 0x98, 0xb0, 0xc1, 0xc2, 0xb4, 0x7a, 0x3b, 0x2f, 0x54, - 0x3b, 0x66, 0xe6, 0x6b, 0xc5, 0x2c, 0xa1, 0xb1, 0xd2, 0xee, 0xd8, 0x30, - 0xf3, 0xa9, 0x2f, 0xe8, 0xf0, 0x3e, 0xd8, 0x2b, 0x9a, 0x75, 0x58, 0x59, - 0xc7, 0x3a, 0x39, 0xa1, 0x58, 0x19, 0x87, 0x3f, 0x90, 0xe5, 0xb3, 0xb6, - 0xfe, 0x39, 0x34, 0xc8, 0x4c, 0x21, 0x7b, 0x96, 0x9e, 0x3e, 0x38, 0x48, - 0x3e, 0xaa, 0x0b, 0x1b, 0xbf, 0xa9, 0x45, 0x83, 0x8e, 0x38, 0xf3, 0x96, - 0xb8, 0x24, 0x23, 0xc1, 0xd3, 0x5c, 0x77, 0xeb, 0x6f, 0xf8, 0x16, 0xa8, - 0x94, 0xbc, 0xab, 0x2a, 0x20, 0x52, 0xec, 0x9a, 0x5c, 0xd9, 0x99, 0xb4, - 0x84, 0x50, 0x90, 0xbb, 0xf7, 0x80, 0x51, 0x61, 0x95, 0x61, 0xaa, 0x03, - 0xd6, 0xd4, 0xa9, 0x73, 0x86, 0x3b, 0xf1, 0x7e, 0xca, 0x7c, 0xfb, 0xf9, - 0x33, 0xe6, 0x96, 0x66, 0x13, 0x7a, 0x35, 0xae, 0x71, 0xcc, 0x13, 0x4b, - 0x5e, 0x73, 0xbd, 0xf8, 0xf2, 0x5e, 0x51, 0x5c, 0x50, 0x09, 0x3c, 0x59, - 0xfa, 0xd0, 0xd4, 0x8e, 0xe0, 0x21, 0xb4, 0x97, 0xa4, 0x7d, 0xeb, 0x17, - 0xef, 0x4c, 0xf4, 0xd0, 0x0b, 0xf5, 0x42, 0xaf, 0x07, 0x8e, 0xe9, 0x5f, - 0x2b, 0xce, 0xb4, 0xf9, 0x17, 0xea, 0x9e, 0x83, 0x94, 0xf5, 0x1d, 0x49, - 0x91, 0x42, 0x65, 0x84, 0x77, 0x56, 0xc0, 0x4f, 0x67, 0x37, 0xed, 0xa3, - 0x18, 0x22, 0x69, 0xd7, 0x40, 0xfb, 0x39, 0xfd, 0xc2, 0x37, 0x68, 0x98, - 0x30, 0x6a, 0x33, 0xad, 0x2f, 0xf2, 0x3d, 0x5c, 0xe0, 0x4a, 0x29, 0x38, - 0xe5, 0xe0, 0x5c, 0xb3, 0x79, 0xd5, 0x8c, 0xcd, 0x25, 0xad, 0xab, 0xd3, - 0x75, 0x2f, 0x54, 0x3a, 0xfe, 0x8e, 0x0d, 0x3f, 0xfa, 0x6e, 0xcc, 0x80, - 0x26, 0x08, 0x7f, 0xa3, 0x9e, 0xba, 0x80, 0x4c, 0x36, 0x4c, 0x4d, 0x74, - 0xc0, 0x3f, 0xd1, 0xb3, 0xad, 0xa3, 0xc8, 0xcf, 0x7a, 0x73, 0xb7, 0x09, - 0x67, 0x3b, 0xf8, 0x6f, 0x7a, 0x26, 0x57, 0x65, 0x83, 0xcf, 0x18, 0x3c, - 0x86, 0x2c, 0xb4, 0xcd, 0xe8, 0x74, 0xfa, 0x63, 0xd4, 0xb4, 0x36, 0x36, - 0xd9, 0xb0, 0xeb, 0x29, 0xe3, 0x3a, 0x7f, 0x06, 0x80, 0x29, 0x4c, 0x86, - 0x94, 0x49, 0x42, 0x22, 0x57, 0x0c, 0x4f, 0xfa, 0x08, 0xb5, 0x12, 0xbe, - 0x76, 0xf5, 0x52, 0x10, 0x47, 0x48, 0x1f, 0xbd, 0x87, 0x51, 0xd1, 0x39, - 0xc8, 0x50, 0x7c, 0xfa, 0x92, 0xe7, 0xea, 0x40, 0x55, 0xf7, 0x61, 0x9f, - 0x19, 0xc2, 0x65, 0x23, 0x6d, 0xe0, 0x41, 0xb9, 0x5b, 0xb7, 0x8c, 0x9a, - 0xee, 0x50, 0x53, 0xa6, 0xe8, 0x80, 0x14, 0x8c, 0xeb, 0x2a, 0xc1, 0x44, - 0xda, 0x6d, 0x90, 0x96, 0xb8, 0xf1, 0xc4, 0x0d, 0xf1, 0xd8, 0x8e, 0xd0, - 0xb4, 0x73, 0x49, 0xe5, 0x34, 0xab, 0x00, 0x0f, 0x0b, 0x7b, 0xc3, 0x7d, - 0x53, 0x1d, 0x75, 0xef, 0x27, 0xfb, 0xdf, 0x29, 0xfd, 0x61, 0xb3, 0x71, - 0x25, 0xac, 0x62, 0x2d, 0xaa, 0x1a, 0x2a, 0x55, 0x6e, 0x11, 0x50, 0x4b, - 0x2c, 0x3d, 0xd8, 0x8d, 0xb9, 0xcb, 0xc2, 0x21, 0x77, 0x4e, 0x40, 0x56, - 0x45, 0xc1, 0x07, 0x79, 0xdb, 0x66, 0x2f, 0x6d, 0x4d, 0xac, 0x2b, 0x2d, - 0x29, 0xff, 0xa1, 0x79, 0x10, 0x03, 0x72, 0x09, 0xe8, 0xe9, 0x31, 0xd5, - 0x6f, 0x42, 0x97, 0x3e, 0x09, 0xf0, 0x4a, 0xb5, 0xe6, 0x73, 0x94, 0xc1, - 0xb4, 0x94, 0xa1, 0xd9, 0x44, 0xe8, 0x50, 0xe2, 0x6c, 0x82, 0xea, 0x89, - 0x06, 0xd6, 0x44, 0xe9, 0x53, 0xd0, 0x5c, 0xcf, 0x0a, 0x3b, 0x89, 0x50, - 0x8d, 0x1e, 0x44, 0xbd, 0xb2, 0xb6, 0x68, 0xf4, 0xbb, 0x2d, 0x65, 0x95, - 0x5c, 0xb5, 0xdc, 0xe2, 0xb7, 0x70, 0x86, 0xfd, 0x5b, 0xcc, 0x99, 0x41, - 0x5d, 0x22, 0x11, 0xa8, 0x22, 0x8c, 0xc1, 0x73, 0x70, 0x5b, 0x31, 0x11, - 0xc3, 0xdb, 0x7f, 0xca, 0x2b, 0xcb, 0xeb, 0x7d, 0x2b, 0xd1, 0x32, 0xe6, - 0xf8, 0x22, 0x22, 0x69, 0xea, 0xb7, 0xcd, 0x25, 0x22, 0x33, 0x2f, 0x83, - 0x3f, 0xb7, 0x2d, 0x22, 0x61, 0x24, 0x01, 0xb3, 0xe9, 0xd0, 0xf6, 0x21, - 0xe6, 0x2d, 0xea, 0x0e, 0x53, 0x7a, 0x97, 0xcd, 0xcf, 0x6c, 0xe2, 0xd5, - 0x8b, 0xdc, 0xe9, 0xe0, 0xfd, 0xd0, 0xa0, 0xbf, 0xa5, 0x39, 0x7e, 0xd4, - 0xdd, 0xfe, 0x1a, 0xce, 0xb0, 0x85, 0x8e, 0xc1, 0x05, 0x36, 0xf9, 0xd3, - 0x6a, 0x35, 0xab, 0x53, 0x1d, 0xc2, 0xa0, 0xfa, 0xc2, 0x6b, 0x8b, 0x8c, - 0x2d, 0x5d, 0x5f, 0xb8, 0x18, 0x43, 0x53, 0xb9, 0x5d, 0x08, 0x07, 0xd1, - 0x8f, 0xc6, 0xe9, 0xef, 0xaf, 0x3b, 0xbb, 0x60, 0xaa, 0x28, 0xac, 0x4c, - 0x03, 0x5d, 0xc8, 0x05, 0xba, 0x82, 0x5c, 0xcb, 0xc6, 0x2a, 0x13, 0xf6, - 0xfc, 0x54, 0xf3, 0xea, 0x20, 0xce, 0xcf, 0x05, 0x00, 0xb9, 0x98, 0x0b, - 0x9f, 0x96, 0xe0, 0x7b, 0x85, 0x8e, 0x43, 0xbd, 0xf2, 0x3e, 0x17, 0x19, - 0x8d, 0x23, 0x72, 0x85, 0x93, 0xdf, 0x3a, 0x21, 0x94, 0x34, 0x32, 0x53, - 0x02, 0xba, 0x34, 0xba, 0xa5, 0x2e, 0x5c, 0x0b, 0x1e, 0x3f, 0xa9, 0x83, - 0x92, 0x63, 0x0b, 0x12, 0xc9, 0xf8, 0x35, 0xef, 0x78, 0xa0, 0xee, 0xc0, - 0xbb, 0x14, 0xd4, 0x68, 0x39, 0xa0, 0x00, 0x38, 0x77, 0x1e, 0xfc, 0x94, - 0xb4, 0xd4, 0xc1, 0x98, 0xe1, 0x43, 0x8e, 0xc6, 0xa7, 0x58, 0x33, 0x1b, - 0xa3, 0x73, 0xf7, 0x4c, 0x49, 0x9d, 0xc0, 0xb8, 0xbf, 0x30, 0x84, 0x2e, - 0x5a, 0x8b, 0x6c, 0xa5, 0xde, 0xb5, 0x6a, 0x79, 0x67, 0x54, 0xe7, 0x8c, - 0x3c, 0xf3, 0x70, 0x1b, 0x3d, 0x35, 0x23, 0x65, 0x17, 0xc9, 0x74, 0x11, - 0x0b, 0xb1, 0x64, 0xc0, 0x65, 0xa3, 0x9e, 0x5a, 0x7b, 0xa2, 0xda, 0xe1, - 0xf4, 0xeb, 0xb8, 0x13, 0x90, 0x30, 0xc1, 0x72, 0x6a, 0x2a, 0x13, 0xe3, - 0x36, 0xe1, 0x05, 0x47, 0x56, 0x42, 0xf2, 0x59, 0x44, 0x12, 0x23, 0x27, - 0xe4, 0xfe, 0xae, 0x83, 0x39, 0x0f, 0x4c, 0x85, 0x3f, 0xaf, 0x97, 0x2e, - 0xae, 0x3c, 0x12, 0x0e, 0xfd, 0x5b, 0xfd, 0x8e, 0x58, 0x58, 0x4a, 0xbd, - 0x05, 0x98, 0x6b, 0x82, 0x03, 0x02, 0x0a, 0x2d, 0x1c, 0x19, 0x0f, 0x95, - 0x12, 0x5d, 0x8c, 0x1e, 0x7b, 0x49, 0xbb, 0x83, 0xe2, 0xd2, 0x53, 0x60, - 0xe1, 0xab, 0xd2, 0x8b, 0x02, 0xeb, 0x49, 0x27, 0xd7, 0xda, 0x22, 0xd3, - 0x26, 0x6f, 0x3e, 0x5b, 0x3f, 0x33, 0xcb, 0xa8, 0x08, 0x98, 0xa6, 0xc5, - 0x35, 0xc1, 0x81, 0xc1, 0xd6, 0x28, 0xe5, 0xba, 0x50, 0xe9, 0x14, 0x1a, - 0x0b, 0x0a, 0x8a, 0x9e, 0xa3, 0xaa, 0xbc, 0x3b, 0x38, 0x5b, 0xe0, 0x1f, - 0xf6, 0xb8, 0x95, 0x79, 0xa4, 0x45, 0x5f, 0xc4, 0x63, 0x86, 0xd0, 0x15, - 0xe0, 0x25, 0x6e, 0x5f, 0x8d, 0x75, 0x25, 0x67, 0xea, 0xf3, 0x92, 0x33, - 0xd1, 0x07, 0xf3, 0x43, 0x21, 0x42, 0x40, 0x70, 0x9b, 0x8e, 0x0b, 0x41, - 0x54, 0x30, 0x73, 0xd0, 0x49, 0xe4, 0x70, 0xf6, 0xd3, 0x7d, 0x59, 0xd6, - 0x1f, 0x06, 0xfc, 0x12, 0x89, 0x9f, 0x26, 0x09, 0x34, 0xf6, 0x64, 0x56, - 0x37, 0x68, 0x59, 0x33, 0x9c, 0xa0, 0xfa, 0x65, 0x70, 0xb3, 0xe1, 0x29, - 0xd1, 0x5b, 0xaf, 0xe7, 0xa5, 0x39, 0x64, 0x38, 0x8b, 0xb1, 0xd6, 0xce, - 0xa4, 0xb4, 0xb6, 0xdb, 0x01, 0xb4, 0xf9, 0xb7, 0x1f, 0x8f, 0xcd, 0x28, - 0xe6, 0x27, 0x47, 0xf2, 0x53, 0x1d, 0xea, 0xb4, 0x53, 0xfa, 0xe0, 0x22, - 0xea, 0xc5, 0xd2, 0xfc, 0x4e, 0x45, 0xcf, 0xef, 0xaa, 0xea, 0xaf, 0x7e, - 0x77, 0xe2, 0x39, 0x1c, 0x5d, 0x9c, 0x77, 0x7b, 0x71, 0xb5, 0x11, 0xef, - 0xc7, 0xf8, 0xba, 0x2b, 0x7b, 0x15, 0xfa, 0x2d, 0xd5, 0xd8, 0xe0, 0xee, - 0xbe, 0x10, 0xd6, 0xdb, 0x47, 0xf1, 0x11, 0xcc, 0x35, 0x4c, 0x2d, 0xa8, - 0x12, 0x12, 0x23, 0x78, 0x0b, 0xd3, 0xb8, 0x90, 0x8a, 0x1d, 0xc4, 0x90, - 0x4b, 0x7e, 0x35, 0xb9, 0x9f, 0x5b, 0x68, 0x97, 0x9c, 0x09, 0xc3, 0x0d, - 0x0a, 0x20, 0xd9, 0x25, 0x07, 0xeb, 0x56, 0xb5, 0xd6, 0x93, 0x31, 0x3d, - 0x71, 0x7c, 0x0f, 0x48, 0x26, 0x32, 0x0f, 0x1b, 0x43, 0x75, 0xc2, 0xcd, - 0xf6, 0xaa, 0x88, 0x38, 0x7b, 0xe9, 0xc0, 0x98, 0x51, 0xa4, 0x06, 0x15, - 0x7f, 0x11, 0x0b, 0x91, 0xcb, 0x59, 0x92, 0x1c, 0xa1, 0x44, 0x63, 0xa4, - 0x3a, 0xad, 0xd7, 0x1d, 0x9e, 0x63, 0xfb, 0xb9, 0x7d, 0x43, 0x80, 0x79, - 0xe8, 0x01, 0xba, 0x08, 0x47, 0x78, 0x57, 0xd6, 0x0b, 0x38, 0x94, 0x64, - 0xac, 0x64, 0x77, 0xdc, 0xb8, 0xa9, 0xa5, 0xa2, 0x62, 0x70, 0x36, 0x4f, - 0x39, 0xd9, 0xae, 0x2f, 0x15, 0xd3, 0x07, 0xc4, 0x01, 0x03, 0x96, 0x5e, - 0x51, 0xa7, 0x15, 0x2a, 0x9d, 0x22, 0x74, 0xae, 0x8a, 0xd4, 0xb9, 0x91, - 0xed, 0xad, 0xa7, 0x76, 0xad, 0x38, 0x33, 0xef, 0x3c, 0xe4, 0xd0, 0x7c, - 0x6e, 0x53, 0xae, 0x0c, 0x7a, 0xdf, 0x2c, 0x18, 0xeb, 0xc4, 0x8c, 0xfe, - 0xab, 0x10, 0xcd, 0xaf, 0x8f, 0x88, 0x3f, 0xac, 0xe3, 0x20, 0xed, 0x0c, - 0x62, 0x81, 0x2e, 0x12, 0xa9, 0xa5, 0xe7, 0xd5, 0x3a, 0xef, 0x40, 0xb4, - 0x91, 0x52, 0x4c, 0xfd, 0xd5, 0xb8, 0x98, 0x19, 0xcd, 0x1b, 0xa9, 0x17, - 0xe7, 0x9a, 0xda, 0x8a, 0xb4, 0x8f, 0x1a, 0x5c, 0x78, 0xd2, 0x28, 0x7a, - 0xb6, 0x66, 0xac, 0x73, 0xd4, 0x11, 0xc0, 0x81, 0xff, 0x71, 0x57, 0x4c, - 0x23, 0x90, 0x2a, 0xd8, 0x67, 0x7a, 0x6a, 0x58, 0xb7, 0x5b, 0xbe, 0x80, - 0x62, 0x17, 0x10, 0x90, 0xc1, 0xb7, 0x2c, 0xbe, 0xbe, 0x97, 0x2e, 0x85, - 0x36, 0x07, 0x8e, 0x63, 0xfc, 0x38, 0xc5, 0x66, 0x20, 0x33, 0x2b, 0xe8, - 0x25, 0x25, 0xc1, 0x11, 0xba, 0x5b, 0x12, 0xd9, 0x06, 0x4d, 0xfc, 0x49, - 0x20, 0x27, 0x6b, 0x79, 0x92, 0x8b, 0xde, 0x22, 0x39, 0xf9, 0x2e, 0xc9, - 0x1b, 0xb9, 0x97, 0x2f, 0xc3, 0x37, 0xf5, 0xa3, 0x6b, 0xd3, 0x3b, 0x94, - 0xa5, 0x56, 0xb7, 0x81, 0x7c, 0x9d, 0x28, 0xff, 0x57, 0xe7, 0x02, 0xa1, - 0xd1, 0x3a, 0x3d, 0xac, 0x74, 0x45, 0xb3, 0xab, 0x95, 0xec, 0x68, 0x8a, - 0x9c, 0xf7, 0x43, 0xa4, 0x14, 0x0d, 0x68, 0x40, 0x5f, 0x7e, 0x25, 0x8a, - 0x47, 0x3f, 0x9c, 0xaf, 0x88, 0x0b, 0x4a, 0xc0, 0x98, 0xc2, 0x57, 0xf4, - 0xde, 0x04, 0x09, 0x37, 0x9c, 0x87, 0x83, 0xb6, 0xa5, 0xa8, 0x5e, 0xc4, - 0xec, 0x2e, 0xfd, 0xc9, 0xf3, 0x85, 0x4f, 0x7d, 0xb8, 0xba, 0x6e, 0x6d, - 0xc0, 0xd2, 0x37, 0xb2, 0xba, 0x17, 0xad, 0x29, 0xf8, 0x71, 0x74, 0x0c, - 0x93, 0x1e, 0x07, 0x34, 0xec, 0xc3, 0x5f, 0x15, 0x21, 0x49, 0x0f, 0xa7, - 0x7e, 0x72, 0x79, 0x66, 0xfd, 0x3e, 0x29, 0xce, 0x12, 0xeb, 0x57, 0x88, - 0xd8, 0xcc, 0x14, 0x96, 0x33, 0x44, 0x64, 0x6c, 0x34, 0x55, 0xb3, 0x76, - 0xc9, 0xa7, 0x3f, 0x7b, 0x16, 0x9d, 0x7e, 0x95, 0x4c, 0xfa, 0xc9, 0x46, - 0x17, 0x18, 0x18, 0x78, 0xe7, 0xfb, 0x6b, 0x86, 0xf4, 0x25, 0x3a, 0x0b, - 0x4a, 0xcd, 0x1a, 0x51, 0xde, 0xa4, 0x45, 0xdd, 0xdb, 0xc9, 0x9f, 0xa9, - 0xc3, 0x58, 0xb2, 0x43, 0x90, 0x8b, 0xc1, 0x59, 0x47, 0x1a, 0x89, 0xcb, - 0x9c, 0x6d, 0x46, 0x1f, 0x0d, 0xe9, 0xfa, 0xd8, 0xe9, 0xde, 0xdb, 0xf5, - 0x22, 0x9b, 0xe3, 0xef, 0xb4, 0x0c, 0xc7, 0x34, 0xd0, 0x2a, 0x0f, 0x0b, - 0x8e, 0x11, 0x88, 0x91, 0xb7, 0xce, 0x92, 0xf2, 0x83, 0x3c, 0xd2, 0xf8, - 0x42, 0x32, 0x82, 0x48, 0xad, 0x67, 0x44, 0x45, 0x59, 0xac, 0x57, 0xb7, - 0x7e, 0x1b, 0xce, 0xca, 0x51, 0xfb, 0x1b, 0x12, 0x39, 0xaf, 0xe4, 0xfb, - 0xdb, 0xc5, 0xb7, 0xcc, 0x4a, 0x5d, 0xc4, 0xa6, 0x95, 0xaf, 0x5b, 0x39, - 0x4e, 0x47, 0xc5, 0x50, 0x67, 0x92, 0x84, 0x62, 0xeb, 0x81, 0x77, 0x24, - 0xda, 0x27, 0x64, 0xfe, 0xe4, 0x83, 0x40, 0x33, 0xc8, 0xb1, 0xaa, 0xbb, - 0xbf, 0x13, 0xc3, 0x18, 0x9a, 0x24, 0x06, 0xbd, 0x0a, 0x07, 0xa3, 0xd6, - 0xd8, 0x38, 0x32, 0x73, 0x8d, 0x40, 0x5f, 0xc2, 0x3f, 0xeb, 0xd2, 0x0e, - 0x3d, 0x6d, 0xf5, 0x72, 0x5a, 0xa6, 0x56, 0x22, 0x41, 0xe5, 0x0c, 0xb5, - 0x0c, 0xda, 0xcd, 0x46, 0xbc, 0xd7, 0x98, 0x89, 0x5e, 0x97, 0x54, 0x4f, - 0x4b, 0xc0, 0x27, 0x51, 0x0d, 0x20, 0x3f, 0x55, 0x78, 0xdc, 0x5a, 0x79, - 0x08, 0xed, 0xd3, 0xaa, 0x9c, 0xc3, 0x7d, 0x75, 0x76, 0x81, 0xa4, 0xe0, - 0xfc, 0x90, 0x6a, 0x83, 0x37, 0x53, 0xb8, 0xb5, 0xd9, 0x7a, 0xd9, 0x7d, - 0xeb, 0x50, 0x72, 0xd3, 0x5d, 0xed, 0x22, 0xfb, 0x6e, 0x67, 0x79, 0x9c, - 0xb9, 0xea, 0xac, 0xc1, 0x6d, 0x68, 0xf5, 0x12, 0xaa, 0x54, 0x90, 0xd8, - 0x7f, 0xe0, 0xf4, 0xdd, 0x3b, 0x88, 0xe3, 0xec, 0x7f, 0x1c, 0x2b, 0x08, - 0x32, 0xc6, 0x05, 0x53, 0xae, 0xa4, 0x46, 0xa7, 0xf3, 0xe6, 0xcb, 0xe7, - 0x04, 0xc1, 0x52, 0xa7, 0xfe, 0x68, 0x55, 0xc1, 0x91, 0xb2, 0x9a, 0x3b, - 0x05, 0xc6, 0xae, 0x15, 0x89, 0xdc, 0xb2, 0x0b, 0xeb, 0x19, 0x96, 0x62, - 0xe3, 0x67, 0xc5, 0xdc, 0xf5, 0xe8, 0xbe, 0x16, 0xbe, 0xf6, 0xe4, 0x0b, - 0xeb, 0x99, 0x82, 0x65, 0x0a, 0x97, 0xf5, 0xc2, 0x19, 0x1c, 0x1e, 0xa1, - 0xf1, 0x75, 0x06, 0xa7, 0xdb, 0x97, 0x68, 0x94, 0x0b, 0xea, 0xc4, 0xda, - 0x70, 0x72, 0x3e, 0x9f, 0xfc, 0x20, 0x4e, 0x54, 0xfb, 0x18, 0x01, 0x74, - 0x9a, 0x24, 0x1d, 0x20, 0x3a, 0x25, 0xe1, 0xd8, 0xaf, 0xe3, 0x76, 0xe0, - 0x47, 0x53, 0x86, 0xd9, 0x3f, 0xc2, 0x46, 0x4a, 0x02, 0x05, 0xaf, 0xbf, - 0x49, 0x12, 0x22, 0x66, 0x81, 0xf5, 0x9d, 0xdd, 0xae, 0x7f, 0xf5, 0x99, - 0x2b, 0x89, 0xa6, 0x25, 0x30, 0xd6, 0xb3, 0x00, 0xa4, 0x62, 0xd2, 0xb3, - 0x8e, 0xdd, 0xc2, 0x04, 0x62, 0x17, 0x44, 0xa3, 0x62, 0xf7, 0x8c, 0x56, - 0x00, 0x4f, 0x98, 0xfe, 0x7a, 0xdf, 0x9d, 0x47, 0xab, 0xc9, 0xb7, 0x0e, - 0x0d, 0x02, 0x54, 0x6a, 0xab, 0xf9, 0x22, 0xb9, 0x11, 0xb3, 0xec, 0x17, - 0xb9, 0xc9, 0x86, 0xf6, 0x66, 0x97, 0x1f, 0xa9, 0x38, 0xd8, 0x66, 0x8e, - 0x41, 0xd9, 0x9a, 0x35, 0xfd, 0x19, 0x64, 0xcb, 0x1e, 0x77, 0x80, 0xd4, - 0x6d, 0xea, 0x00, 0xf5, 0x9b, 0xc9, 0x55, 0xef, 0x80, 0x14, 0x79, 0xab, - 0xf5, 0x5e, 0xb0, 0x4b, 0x73, 0x52, 0x17, 0x2a, 0xd7, 0x68, 0x79, 0x6a, - 0xf1, 0xc0, 0x04, 0xce, 0x33, 0xd2, 0x18, 0xad, 0x39, 0x4d, 0xda, 0x40, - 0x49, 0xce, 0x00, 0xca, 0x89, 0xf3, 0xbd, 0x13, 0xe5, 0x7a, 0x03, 0x99, - 0xa3, 0x4b, 0x29, 0xcd, 0x18, 0xbd, 0xc8, 0xd7, 0x30, 0xcd, 0x4f, 0x65, - 0xdc, 0xca, 0xc2, 0x9f, 0x84, 0x2d, 0x83, 0xf6, 0x69, 0x0d, 0x55, 0x08, - 0x5b, 0x6c, 0x87, 0x53, 0xda, 0x13, 0x2a, 0x34, 0xf7, 0xea, 0x13, 0xec, - 0x14, 0x90, 0xe8, 0x94, 0xdc, 0xa6, 0xcf, 0xe9, 0x9b, 0x99, 0x63, 0x48, - 0xf3, 0x34, 0xac, 0xf2, 0x78, 0x76, 0x90, 0x46, 0xd8, 0x7d, 0x2b, 0xc1, - 0xd2, 0xdd, 0xf1, 0xda, 0x23, 0xc8, 0x3c, 0xd6, 0x58, 0x2e, 0xaf, 0x2c, - 0xf6, 0x8a, 0xb3, 0x93, 0x0e, 0x4f, 0x82, 0x7e, 0x26, 0x88, 0x0b, 0x3b, - 0xe4, 0xe9, 0x85, 0x2b, 0x99, 0xca, 0xdc, 0xad, 0x84, 0x26, 0xee, 0x35, - 0x6a, 0x50, 0xc4, 0xae, 0x95, 0x30, 0x0d, 0x09, 0xef, 0xdb, 0x4b, 0x4c, - 0x9b, 0x0f, 0x04, 0x0a, 0x6e, 0xf0, 0x92, 0x43, 0x06, 0xb9, 0x73, 0x16, - 0x79, 0x15, 0x3f, 0x08, 0xcc, 0x78, 0x2b, 0x35, 0x8c, 0xa3, 0x2a, 0x6e, - 0xf6, 0x5c, 0x61, 0xf3, 0xc6, 0x4b, 0x8a, 0xbc, 0x75, 0x1f, 0x4a, 0x00, - 0x4e, 0x5f, 0x9e, 0x24, 0x03, 0x2d, 0x86, 0x26, 0xa7, 0x78, 0xb7, 0xc3, - 0x6f, 0x74, 0x6d, 0x32, 0x34, 0xcd, 0x37, 0x42, 0x56, 0x24, 0x83, 0x7f, - 0xa8, 0x1b, 0x9b, 0xae, 0x97, 0x55, 0x2d, 0xba, 0x67, 0x75, 0x67, 0xca, - 0xa5, 0xd1, 0x6e, 0xd6, 0x48, 0xaf, 0xeb, 0x71, 0xdc, 0x31, 0xfb, 0x3b, - 0xe3, 0x7c, 0x64, 0x9d, 0xe5, 0x5a, 0xe4, 0x87, 0x6e, 0xed, 0xed, 0xca, - 0xb6, 0x51, 0xfd, 0x73, 0xef, 0x7c, 0xbc, 0x15, 0x69, 0xfd, 0x9f, 0x1f, - 0x0f, 0x17, 0x1a, 0x8d, 0x73, 0x61, 0x7d, 0xf1, 0x09, 0x97, 0x06, 0xbe, - 0x90, 0x38, 0xdf, 0xac, 0xfd, 0xe2, 0x87, 0xe8, 0xc1, 0xc3, 0x9b, 0x83, - 0x79, 0xa6, 0xdd, 0x6d, 0x58, 0x4d, 0x03, 0x26, 0x99, 0x1d, 0x2e, 0x47, - 0xb0, 0x20, 0x3f, 0x84, 0xaf, 0xfa, 0xf9, 0xf1, 0x62, 0xd5, 0x80, 0xb8, - 0x6e, 0x69, 0x7e, 0x53, 0x80, 0x05, 0xc4, 0x2f, 0xba, 0xed, 0x0d, 0x75, - 0xca, 0x01, 0xde, 0x6e, 0xf0, 0xd3, 0x23, 0x9b, 0x1e, 0xae, 0x02, 0x57, - 0xeb, 0x40, 0xf2, 0x55, 0x89, 0xd7, 0x70, 0xd6, 0x45, 0xe7, 0x67, 0xd3, - 0x3e, 0x21, 0xda, 0xb6, 0xae, 0xe5, 0xe6, 0x82, 0x0c, 0x3e, 0x3e, 0xe8, - 0xbe, 0x85, 0x3d, 0x79, 0x75, 0x90, 0x9b, 0x9c, 0x01, 0x88, 0x8d, 0x5a, - 0x34, 0x1d, 0x10, 0x83, 0x85, 0x08, 0xea, 0x88, 0x51, 0x29, 0xea, 0x95, - 0x40, 0x2f, 0x16, 0x90, 0xec, 0x1b, 0xb7, 0x22, 0x81, 0xcb, 0x1b, 0x8c, - 0xf5, 0xe2, 0xfd, 0xcb, 0x1f, 0xe7, 0xb0, 0x4b, 0x4d, 0x7c, 0x7d, 0x11, - 0x17, 0x20, 0x89, 0x8b, 0x4a, 0x80, 0xa3, 0x10, 0x6f, 0x68, 0x09, 0x01, - 0x68, 0x86, 0x3b, 0x2a, 0xfb, 0x48, 0x80, 0xa0, 0xd1, 0xdb, 0x3f, 0x91, - 0x44, 0x58, 0x83, 0xc6, 0x85, 0x77, 0x6b, 0xb1, 0x35, 0x4a, 0x03, 0xa2, - 0xcf, 0x2f, 0xbd, 0xcd, 0x4b, 0xfa, 0x5a, 0x5e, 0x8f, 0x8b, 0x95, 0x62, - 0xaa, 0xe7, 0x3b, 0x54, 0xb1, 0xec, 0xd5, 0x85, 0x4f, 0xd9, 0x59, 0x56, - 0xb4, 0xec, 0xc1, 0x21, 0xc5, 0xa6, 0x35, 0x1d, 0x7b, 0x60, 0xe1, 0xb1, - 0x7c, 0x8f, 0x47, 0xa1, 0xf1, 0x13, 0x4b, 0xaf, 0x23, 0xcb, 0x5e, 0xe2, - 0x74, 0x16, 0x16, 0x96, 0x3b, 0xff, 0xbf, 0x26, 0x5f, 0x68, 0xd5, 0x64, - 0xc6, 0x62, 0xaf, 0x4a, 0xfc, 0x0f, 0x27, 0x3e, 0x96, 0x5b, 0x7c, 0xeb, - 0x78, 0x81, 0x3c, 0x0a, 0x63, 0xd5, 0x6b, 0x3c, 0xa9, 0xd4, 0x37, 0x03, - 0x3b, 0x5c, 0x62, 0x7a, 0xd5, 0x69, 0xbe, 0x44, 0x50, 0xab, 0x0a, 0x54, - 0x31, 0x5c, 0x44, 0x52, 0xfe, 0xde, 0xbb, 0x10, 0x80, 0x79, 0xb2, 0x69, - 0xc5, 0x75, 0x8b, 0xba, 0x1d, 0x4d, 0x2d, 0xfa, 0xc8, 0x0e, 0xc0, 0xaf, - 0xc2, 0x31, 0xa1, 0x53, 0xc7, 0x9f, 0x3e, 0x1f, 0x38, 0x8c, 0x1e, 0x00, - 0x78, 0x76, 0xb6, 0xb5, 0x68, 0xa4, 0x68, 0xe9, 0xba, 0xda, 0x97, 0xca, - 0x16, 0xde, 0xba, 0xa1, 0xb7, 0x17, 0x26, 0xb3, 0x4b, 0x4b, 0x4e, 0x21, - 0x9c, 0xaf, 0xce, 0xf0, 0x52, 0x41, 0x13, 0x87, 0x75, 0xc4, 0xd7, 0x34, - 0x0c, 0x2d, 0xfe, 0xc1, 0xb6, 0x60, 0x84, 0xd2, 0x57, 0xc2, 0xb2, 0x6c, - 0xa6, 0x97, 0x51, 0xea, 0x49, 0x07, 0x7d, 0xac, 0x15, 0x75, 0x71, 0x67, - 0x2c, 0xdf, 0x09, 0x0c, 0x63, 0x38, 0x6a, 0x25, 0xf3, 0x9b, 0x5d, 0x5d, - 0x63, 0xe7, 0x20, 0xa3, 0xf5, 0x6f, 0x8c, 0x77, 0x91, 0xb0, 0x6d, 0xad, - 0x01, 0x1d, 0x40, 0x65, 0xcd, 0x31, 0xbf, 0xb2, 0x0a, 0x1f, 0xf9, 0xb0, - 0x34, 0x7f, 0x6a, 0xfe, 0xca, 0x2e, 0x28, 0xc4, 0x5b, 0xdb, 0xa9, 0xd4, - 0xdc, 0xe6, 0x3a, 0x0a, 0xeb, 0xe2, 0xc5, 0xb8, 0xbe, 0xad, 0x8d, 0x7d, - 0xa2, 0x5e, 0x88, 0xad, 0xb8, 0xda, 0x41, 0x12, 0x1f, 0xc5, 0x85, 0xa1, - 0x83, 0x3d, 0xc7, 0xbb, 0x6d, 0x55, 0x63, 0xd0, 0x8b, 0x06, 0x76, 0x96, - 0xf5, 0x0b, 0xd9, 0x2f, 0x45, 0xf4, 0x9b, 0xc8, 0x18, 0xba, 0xbd, 0x30, - 0xdc, 0x4d, 0x47, 0xde, 0xbc, 0xc0, 0xc0, 0xca, 0x9f, 0xd7, 0xda, 0xcb, - 0xd8, 0xdd, 0x7e, 0x98, 0x25, 0xfd, 0x9f, 0xa4, 0x22, 0x5d, 0x4b, 0x63, - 0x1b, 0xfa, 0x78, 0xdb, 0x3d, 0x39, 0xcc, 0x26, 0x00, 0x70, 0x0e, 0xac, - 0xf7, 0x30, 0xc0, 0x8c, 0x97, 0xbe, 0x57, 0xeb, 0x1a, 0xc0, 0xfd, 0x4c, - 0x81, 0x69, 0x54, 0x1b, 0xd4, 0x8c, 0xb2, 0xe7, 0xf0, 0x5f, 0x0e, 0x46, - 0x95, 0x7a, 0x2b, 0x0c, 0x69, 0x37, 0x89, 0x45, 0x6a, 0xb2, 0x9f, 0xa8, - 0x99, 0xd2, 0x6c, 0xa0, 0x9d, 0xc0, 0x36, 0x65, 0x2f, 0x37, 0xe3, 0xc8, - 0xba, 0x4f, 0xd2, 0x4c, 0x69, 0x2e, 0x15, 0x2c, 0x92, 0x13, 0x44, 0x96, - 0xa5, 0xe9, 0x90, 0x24, 0x0a, 0x94, 0x44, 0x16, 0x6a, 0x8e, 0x4a, 0x7b, - 0xf4, 0x65, 0x41, 0xd0, 0x4e, 0xf3, 0xf2, 0x6d, 0x8e, 0xc0, 0x70, 0xdf, - 0x56, 0x2f, 0x11, 0x80, 0x03, 0x42, 0xb5, 0x9c, 0x59, 0xea, 0xe1, 0x2d, - 0xc7, 0xd1, 0x29, 0x4a, 0xce, 0x78, 0x83, 0x8f, 0x9b, 0xd4, 0x6b, 0x91, - 0xd8, 0x7b, 0xd1, 0x03, 0xc1, 0xe8, 0x84, 0xbc, 0xca, 0x64, 0xdd, 0xac, - 0xdd, 0x39, 0xaf, 0x7c, 0x5d, 0x7a, 0x5f, 0xc3, 0x8b, 0x0f, 0xd7, 0x18, - 0x43, 0x4a, 0x8e, 0x3f, 0x2f, 0x02, 0x91, 0xa2, 0xdc, 0x3e, 0x2c, 0x9c, - 0x3b, 0x3c, 0xe3, 0xd4, 0x9a, 0xb3, 0x59, 0x43, 0xd4, 0x75, 0x1c, 0x4b, - 0x0b, 0xad, 0x84, 0x2d, 0xbd, 0x05, 0x66, 0xdb, 0x0a, 0xda, 0x77, 0x75, - 0x46, 0x78, 0x99, 0x44, 0xdf, 0x12, 0x58, 0xa9, 0x3a, 0x5f, 0x04, 0x18, - 0x81, 0xa2, 0x2d, 0xcf, 0x9c, 0x35, 0x8d, 0x67, 0x73, 0x9e, 0x8d, 0xe4, - 0xc9, 0x9d, 0x15, 0x80, 0xe3, 0x36, 0xf9, 0xbd, 0xf2, 0x65, 0xb2, 0x10, - 0xa9, 0xe8, 0x2a, 0x03, 0x9d, 0x03, 0x11, 0xe5, 0xcc, 0x32, 0x12, 0xef, - 0xee, 0x22, 0xa3, 0x0c, 0x35, 0x28, 0xc0, 0x17, 0x9b, 0x43, 0x75, 0x5f, - 0x2c, 0xbf, 0xeb, 0xc4, 0xf2, 0xa0, 0x6e, 0xcb, 0x06, 0x1c, 0x5c, 0xd9, - 0xe8, 0x56, 0xaf, 0xe4, 0x2c, 0x6a, 0x8a, 0x9e, 0xea, 0x34, 0x60, 0x09, - 0x94, 0xe7, 0xb2, 0x50, 0x4b, 0xc9, 0xeb, 0xce, 0xd2, 0x7f, 0x1d, 0xc1, - 0x22, 0xe1, 0x71, 0x1f, 0xac, 0xb7, 0xb9, 0x5c, 0x8e, 0x44, 0xe9, 0x51, - 0x58, 0x5c, 0x0e, 0x12, 0x34, 0xb5, 0xab, 0xa1, 0x0d, 0xf1, 0xc6, 0x71, - 0xf0, 0x51, 0x6f, 0xa8, 0x72, 0xde, 0xad, 0x42, 0xe6, 0x39, 0x28, 0xb0, - 0x66, 0xf8, 0xcb, 0x09, 0xb2, 0x82, 0x5a, 0x02, 0x15, 0xca, 0x17, 0xa9, - 0x63, 0xd8, 0xac, 0x18, 0x49, 0xf7, 0xfa, 0x6d, 0xad, 0x3f, 0xf5, 0x2a, - 0xd2, 0x1a, 0x9e, 0x4f, 0xdc, 0xb1, 0xb5, 0x5b, 0x93, 0x59, 0x44, 0x72, - 0x0c, 0xf4, 0x7e, 0xe4, 0x62, 0x10, 0x64, 0xad, 0x2d, 0xb0, 0x2e, 0xcb, - 0xf8, 0xd9, 0xbb, 0xf9, 0xfc, 0xc5, 0xe1, 0x31, 0x6e, 0x0e, 0x8b, 0x12, - 0x62, 0x25, 0x92, 0xd6, 0xb0, 0x0d, 0x78, 0x7e, 0x03, 0x13, 0x65, 0xe0, - 0xa3, 0x5d, 0x33, 0xc7, 0x04, 0x8b, 0xe7, 0x45, 0xa8, 0x9f, 0xd1, 0x70, - 0x27, 0x32, 0x6e, 0x50, 0x48, 0x6a, 0xd3, 0x32, 0xcb, 0xca, 0xd5, 0xcd, - 0xd4, 0x0a, 0x76, 0x8e, 0x6b, 0xb1, 0x73, 0x68, 0x38, 0xf5, 0x73, 0xb2, - 0x46, 0x7a, 0xb5, 0xff, 0xea, 0x52, 0xc9, 0x5b, 0x56, 0xff, 0xf0, 0x35, - 0x4b, 0xae, 0x88, 0x61, 0x8a, 0x3c, 0xb9, 0x78, 0x1c, 0x51, 0xaa, 0x5d, - 0xaf, 0xe0, 0xe7, 0x8c, 0x03, 0x85, 0x6a, 0x1f, 0xca, 0xb9, 0x8c, 0xf4, - 0x37, 0xea, 0xae, 0x54, 0xf1, 0xb8, 0x4c, 0x94, 0x42, 0xcf, 0x2a, 0x8d, - 0x13, 0xef, 0x66, 0xf8, 0x1b, 0xbe, 0x5d, 0x9a, 0x24, 0x12, 0xb5, 0xe8, - 0xe8, 0x44, 0x6b, 0x95, 0xd6, 0xed, 0x98, 0xd8, 0x10, 0xeb, 0x19, 0xe5, - 0x42, 0x01, 0xaa, 0x1c, 0x6a, 0x62, 0xd2, 0xf0, 0xc3, 0x33, 0x4d, 0xf0, - 0x3e, 0x76, 0x8d, 0xec, 0xbb, 0xb9, 0xeb, 0x14, 0x77, 0x02, 0x39, 0xb7, - 0x75, 0x21, 0x3a, 0xa5, 0xef, 0x04, 0xb3, 0x20, 0x50, 0xaf, 0xed, 0x99, - 0x0b, 0xec, 0x12, 0x6d, 0xad, 0x9f, 0x23, 0x02, 0xc0, 0x01, 0x5a, 0xfe, - 0xfc, 0xee, 0xa9, 0xc1, 0x23, 0x51, 0x71, 0xb0, 0xe6, 0xee, 0xcc, 0xcd, - 0x6a, 0x59, 0xcf, 0xad, 0xff, 0x4b, 0x36, 0xbf, 0x2a, 0xaf, 0x56, 0xae, - 0xd7, 0x35, 0x47, 0xc4, 0x11, 0xef, 0x66, 0x18, 0xd1, 0xec, 0x2a, 0x5c, - 0xca, 0xfe, 0x8f, 0x8b, 0xa2, 0x80, 0x57, 0x42, 0xe5, 0xa5, 0xb4, 0x7a, - 0x34, 0xd0, 0x1b, 0xca, 0xb3, 0x7f, 0x2c, 0x54, 0x47, 0x50, 0xf0, 0xdd, - 0xde, 0x87, 0xc0, 0x8f, 0x3a, 0x79, 0x49, 0x50, 0xe9, 0x4a, 0xe2, 0x74, - 0x08, 0x18, 0x61, 0xaa, 0x17, 0xe4, 0x44, 0xdf, 0xeb, 0xf8, 0x2f, 0x5f, - 0x06, 0x19, 0x06, 0x13, 0xec, 0x14, 0x47, 0x04, 0x51, 0x03, 0x55, 0x62, - 0x78, 0x73, 0x7d, 0xe9, 0x15, 0xff, 0xd3, 0xb2, 0x5c, 0x54, 0x79, 0xca, - 0x58, 0x10, 0x86, 0x66, 0x4d, 0x6a, 0x73, 0x13, 0x20, 0x60, 0xd1, 0xaa, - 0x54, 0xa8, 0xf3, 0x45, 0x1c, 0x02, 0x23, 0xc6, 0x43, 0xee, 0xb4, 0xf4, - 0xed, 0xa3, 0x59, 0xb7, 0xb3, 0x4e, 0xda, 0xdf, 0x5f, 0x12, 0xed, 0xb0, - 0x03, 0x93, 0xc7, 0xb7, 0xa9, 0x52, 0xdb, 0x91, 0x39, 0x4f, 0x0d, 0x6d, - 0x31, 0x08, 0xf5, 0x91, 0x90, 0xe5, 0x11, 0xbf, 0x33, 0x4d, 0x3f, 0x7b, - 0xc8, 0x46, 0xbf, 0x8f, 0x27, 0x61, 0xc3, 0x6c, 0xea, 0xfa, 0xaf, 0xeb, - 0x92, 0xd1, 0x86, 0xb4, 0x50, 0x64, 0x6c, 0xba, 0xdf, 0x1f, 0xe9, 0xc6, - 0x2f, 0xad, 0x8d, 0x95, 0xe7, 0xfe, 0xcb, 0xbf, 0xcc, 0xba, 0xbd, 0xcc, - 0x62, 0x85, 0x62, 0x7a, 0x96, 0x85, 0x02, 0x1c, 0xc1, 0x8f, 0x4b, 0xfc, - 0x4f, 0xea, 0x69, 0x8b, 0x1c, 0x83, 0x81, 0x34, 0x15, 0x12, 0x16, 0x6f, - 0x9c, 0x0e, 0xa4, 0x83, 0xb6, 0x28, 0x2f, 0xd7, 0x6d, 0x2e, 0x98, 0x6a, - 0xe7, 0x6f, 0x53, 0x83, 0x18, 0x43, 0x75, 0x25, 0x97, 0x14, 0x15, 0x8d, - 0x2f, 0x7f, 0x72, 0x1a, 0x07, 0x42, 0x2a, 0x7a, 0xe4, 0x7e, 0xc4, 0x7a, - 0x6a, 0xc9, 0x0f, 0xeb, 0x4b, 0x60, 0x56, 0x15, 0x51, 0x23, 0x5d, 0xfa, - 0x0e, 0x56, 0x06, 0x35, 0x89, 0x89, 0x77, 0x55, 0xd3, 0xd7, 0x22, 0x2f, - 0x41, 0xc5, 0x70, 0x3f, 0x57, 0x80, 0xc6, 0xab, 0x30, 0x7e, 0xd8, 0x2b, - 0xd2, 0xd2, 0xa2, 0xfc, 0xf9, 0x32, 0x22, 0x9e, 0x63, 0x67, 0x8a, 0x55, - 0xac, 0x4e, 0x66, 0x98, 0xe6, 0x20, 0xea, 0xbd, 0x64, 0xe9, 0xd5, 0x06, - 0x33, 0x33, 0xbf, 0xe2, 0x89, 0x49, 0x91, 0x92, 0x4e, 0xf9, 0xcc, 0x23, - 0xad, 0x26, 0x1a, 0xb1, 0x01, 0x40, 0x9b, 0x3f, 0x30, 0x5c, 0x88, 0xaf, - 0xce, 0x83, 0xc3, 0x45, 0x90, 0xdc, 0xa6, 0x20, 0x3e, 0x15, 0x96, 0x25, - 0xdf, 0xe1, 0xa6, 0xd6, 0x78, 0xaf, 0xda, 0xc0, 0x0c, 0xf1, 0x21, 0x03, - 0xf9, 0x7f, 0xb5, 0xfd, 0x59, 0x20, 0x3d, 0x73, 0xad, 0xfb, 0x2b, 0x5f, - 0x88, 0xbc, 0x17, 0xaf, 0x1c, 0xaa, 0x5d, 0x17, 0x8f, 0xb7, 0x60, 0x9c, - 0xc7, 0xc4, 0xe4, 0xf4, 0xdb, 0xa9, 0x39, 0xb0, 0xd1, 0xb4, 0x6b, 0x4b, - 0x20, 0xaf, 0xd5, 0xcc, 0xd9, 0x68, 0x17, 0x4c, 0x9a, 0xd4, 0x35, 0x25, - 0x17, 0x3b, 0xc3, 0x41, 0x7b, 0x05, 0xe9, 0xe8, 0xdd, 0x02, 0x9d, 0x0f, - 0x6a, 0xd7, 0xf5, 0xfa, 0xae, 0xf2, 0x5b, 0xfe, 0xc4, 0x44, 0x62, 0xd6, - 0xc4, 0x8e, 0x4b, 0x28, 0x6a, 0x87, 0x3c, 0xe3, 0xf8, 0x01, 0xb5, 0xf9, - 0x77, 0x4e, 0x07, 0x8f, 0x40, 0x02, 0x72, 0x81, 0xa9, 0x6e, 0xa8, 0x84, - 0x1f, 0xfe, 0x2e, 0x06, 0x83, 0xb8, 0x14, 0x2b, 0xf8, 0x6e, 0x8b, 0xb2, - 0xed, 0xff, 0xc5, 0x90, 0x09, 0x86, 0xef, 0xe7, 0x64, 0xb3, 0x3f, 0x10, - 0xe1, 0x47, 0xff, 0x4f, 0xac, 0x76, 0x45, 0xa8, 0xba, 0xac, 0xab, 0x82, - 0x07, 0x86, 0x8a, 0x24, 0xf5, 0xc0, 0x01, 0x5f, 0x54, 0x8b, 0xdc, 0xbd, - 0xd6, 0x28, 0x05, 0x56, 0xfd, 0x13, 0xdf, 0x93, 0x9b, 0x68, 0x03, 0x90, - 0x2c, 0x08, 0xcc, 0x0b, 0xf9, 0x14, 0x44, 0x84, 0x79, 0x15, 0xab, 0xbc, - 0x54, 0x1b, 0x76, 0xe3, 0xfa, 0xf8, 0x32, 0xab, 0xf2, 0xcd, 0xed, 0x04, - 0x15, 0x94, 0xb4, 0xb3, 0xcc, 0x09, 0xf1, 0xb2, 0x35, 0x60, 0x0b, 0x05, - 0xa1, 0x31, 0xd6, 0x6d, 0xc6, 0x46, 0x6d, 0xe4, 0xe7, 0xbc, 0x5f, 0x3a, - 0x72, 0xfd, 0x42, 0xb0, 0x0e, 0xbb, 0xd2, 0xeb, 0x50, 0x26, 0x60, 0x38, - 0xd6, 0x96, 0x1b, 0x5b, 0x9d, 0xcc, 0xb4, 0x98, 0x9f, 0xe8, 0xf2, 0x95, - 0xa3, 0x11, 0x9a, 0xcb, 0x6d, 0x56, 0x87, 0x4b, 0x95, 0xb9, 0x41, 0xa3, - 0x89, 0x2d, 0x2c, 0x29, 0xe8, 0x29, 0x86, 0x47, 0x3e, 0x91, 0x2a, 0x59, - 0x7d, 0x9c, 0x03, 0x9d, 0x2d, 0xff, 0x05, 0x50, 0x21, 0x88, 0x12, 0x55, - 0x2b, 0x25, 0x0c, 0x0c, 0x59, 0xa9, 0x1f, 0xbd, 0x1c, 0xa0, 0xf9, 0xc2, - 0x23, 0x4b, 0xaa, 0xbe, 0x10, 0x4f, 0xf7, 0x5a, 0x25, 0x49, 0xb2, 0xc8, - 0xdc, 0xf7, 0xb1, 0x45, 0xdf, 0xbb, 0x15, 0xd9, 0x48, 0x49, 0x01, 0x27, - 0xf6, 0xdc, 0x59, 0x48, 0xb7, 0xd7, 0x5e, 0x46, 0xde, 0x2c, 0x27, 0x64, - 0xf9, 0xc2, 0xc5, 0x37, 0x21, 0x9a, 0xbf, 0x62, 0x14, 0xdd, 0x13, 0x26, - 0x9f, 0x62, 0x65, 0x55, 0xe8, 0xd7, 0x6f, 0x10, 0x5c, 0xd7, 0x19, 0x16, - 0x1b, 0x87, 0xd3, 0x74, 0xd2, 0x8a, 0x89, 0x15, 0x17, 0xd8, 0x83, 0x8f, - 0x3f, 0x38, 0x98, 0x9b, 0x25, 0x03, 0xc7, 0x7c, 0x35, 0x88, 0x53, 0x48, - 0xca, 0xd6, 0x4d, 0x20, 0x23, 0x54, 0x15, 0x51, 0xda, 0xfb, 0x7e, 0x41, - 0xbc, 0x88, 0xf5, 0x53, 0xf6, 0xe2, 0x54, 0xe6, 0xa8, 0xb1, 0x04, 0xac, - 0xd1, 0xd6, 0x37, 0xd2, 0xa9, 0x6f, 0x96, 0xc0, 0x6a, 0xb1, 0xd4, 0xcf, - 0x1e, 0xda, 0xda, 0x72, 0x43, 0xaa, 0x7b, 0x7d, 0x39, 0x19, 0x11, 0x06, - 0x2a, 0x73, 0x87, 0xe6, 0xdb, 0x8a, 0xcf, 0x66, 0xf2, 0x77, 0xc9, 0x0a, - 0xe2, 0x13, 0x90, 0xd6, 0x1b, 0xa6, 0xfb, 0xfd, 0xda, 0x63, 0x80, 0x81, - 0x55, 0x7a, 0x4b, 0xea, 0x79, 0x4d, 0xa9, 0x46, 0x2b, 0xb1, 0xa5, 0x98, - 0x8d, 0x34, 0x32, 0x07, 0xc6, 0xff, 0x98, 0x17, 0xd1, 0x55, 0x85, 0xc6, - 0x8d, 0x0a, 0x3b, 0x58, 0x1e, 0x82, 0x24, 0xa2, 0xef, 0x83, 0xed, 0xf6, - 0xe2, 0x79, 0x1b, 0x2b, 0x46, 0x7e, 0x94, 0x5b, 0xc8, 0x5a, 0x93, 0xef, - 0xca, 0x76, 0xc7, 0xef, 0x71, 0xce, 0x15, 0x33, 0x91, 0xef, 0x46, 0xa9, - 0x58, 0xd8, 0x6d, 0xa9, 0x47, 0x45, 0x35, 0xbb, 0xce, 0x96, 0xb7, 0x44, - 0xd4, 0x7a, 0x90, 0xd4, 0xcb, 0x18, 0xbc, 0x7b, 0x64, 0xf3, 0x8e, 0xf5, - 0xd5, 0xf7, 0x82, 0xdb, 0xff, 0xd6, 0x50, 0x17, 0xdf, 0x9a, 0x11, 0x75, - 0x85, 0x36, 0xc8, 0x0c, 0x44, 0xcc, 0xdc, 0x76, 0xfc, 0x9f, 0x3e, 0x84, - 0x8f, 0xea, 0xc6, 0xb1, 0xfa, 0x97, 0x75, 0x31, 0xe8, 0xc2, 0x81, 0x7b, - 0x39, 0x14, 0xad, 0xdf, 0x67, 0xf2, 0x44, 0xe0, 0xc4, 0x7a, 0x21, 0x63, - 0x74, 0x73, 0x41, 0xf4, 0xb5, 0xbd, 0x87, 0x36, 0xd0, 0x64, 0xb6, 0x8e, - 0x98, 0xd2, 0x79, 0x5f, 0x4d, 0x22, 0x8c, 0xc1, 0x41, 0x4c, 0xea, 0xb7, - 0xab, 0x4b, 0x2e, 0xca, 0x35, 0x14, 0xd3, 0x90, 0x9e, 0xd6, 0x94, 0x3e, - 0x7e, 0xe4, 0x57, 0x09, 0x22, 0x3c, 0xe6, 0xbe, 0x04, 0x95, 0x75, 0xf8, - 0xe0, 0x42, 0xe9, 0xe2, 0x5e, 0x2e, 0x2a, 0xc6, 0x48, 0x55, 0x42, 0x39, - 0xc4, 0x81, 0x6a, 0xc6, 0x19, 0xea, 0x4c, 0x63, 0x60, 0x11, 0xdf, 0xe7, - 0xde, 0x4d, 0x0f, 0xec, 0x0c, 0x8f, 0x21, 0xe7, 0x94, 0x72, 0x24, 0x4d, - 0xc0, 0x44, 0x30, 0x63, 0x18, 0x06, 0x9b, 0xb9, 0x63, 0xc2, 0x94, 0x6d, - 0x78, 0xba, 0x36, 0x58, 0xe3, 0x07, 0x0f, 0xd4, 0x16, 0xe5, 0xc7, 0x58, - 0xb1, 0x5e, 0x96, 0x25, 0x80, 0xc0, 0x0c, 0x4d, 0xf1, 0xda, 0x8b, 0xc6, - 0x66, 0x56, 0x1e, 0x7c, 0x64, 0x6b, 0x2c, 0xb2, 0x8c, 0xed, 0x07, 0xa7, - 0x52, 0x70, 0xbd, 0x68, 0xd3, 0x48, 0x18, 0x38, 0xa6, 0x60, 0x18, 0x97, - 0x4a, 0xd0, 0x88, 0xed, 0x4c, 0x99, 0xad, 0x88, 0x56, 0xec, 0x2b, 0xd7, - 0xb4, 0xd6, 0xc6, 0x43, 0x58, 0xf6, 0x9b, 0xfb, 0x28, 0xa7, 0xb4, 0xaa, - 0x61, 0xc4, 0x09, 0x0b, 0xa7, 0x51, 0x7a, 0xd3, 0x2f, 0x84, 0xeb, 0x9e, - 0xc9, 0xc9, 0xac, 0x7e, 0x80, 0x2e, 0xa6, 0x88, 0x84, 0xd2, 0x54, 0xca, - 0xe6, 0xf1, 0x7c, 0x97, 0x7c, 0x8a, 0x8a, 0x66, 0x7f, 0x00, 0x4b, 0x73, - 0x3f, 0x2e, 0xfb, 0xcc, 0xe5, 0x07, 0xe6, 0x4e, 0xa1, 0x8e, 0xfc, 0x62, - 0xb7, 0xd7, 0xbe, 0xa4, 0x4a, 0x65, 0xd7, 0xe2, 0xaa, 0x0c, 0xdd, 0x93, - 0x93, 0x63, 0x56, 0x46, 0xe5, 0xe5, 0xf5, 0x47, 0xb1, 0xe4, 0x4e, 0x60, - 0x97, 0x83, 0x82, 0x23, 0x84, 0x37, 0x20, 0xbd, 0xb5, 0x8b, 0x9d, 0x5d, - 0xc8, 0xca, 0xe1, 0xa8, 0x5a, 0xc4, 0xaa, 0xe2, 0x79, 0xda, 0x1d, 0x48, - 0x60, 0x4c, 0x2e, 0x06, 0x95, 0xb4, 0x76, 0x42, 0xa0, 0x6e, 0x52, 0x52, - 0x0f, 0xf8, 0x24, 0x81, 0x21, 0x6f, 0x67, 0x27, 0x9e, 0xe5, 0xf9, 0x9b, - 0x8c, 0x82, 0x90, 0x90, 0xdd, 0xe7, 0xd4, 0x24, 0x54, 0xa7, 0x26, 0x41, - 0xd2, 0x54, 0x50, 0x6a, 0x66, 0xf0, 0xd5, 0x68, 0xaf, 0xd1, 0xd2, 0x00, - 0x66, 0xa1, 0x9e, 0x1b, 0xab, 0xe6, 0x43, 0xa2, 0xb8, 0x05, 0x2f, 0xae, - 0x9b, 0xce, 0x15, 0xa2, 0x5b, 0xd1, 0xb5, 0x53, 0x66, 0x6e, 0xc9, 0x44, - 0x7b, 0x8c, 0x5d, 0x94, 0x63, 0x3c, 0xa5, 0xc5, 0x81, 0x48, 0xd7, 0x98, - 0x6b, 0xb7, 0xce, 0xe4, 0xd9, 0xaf, 0x1c, 0xa9, 0x76, 0x8c, 0x1b, 0x4b, - 0x5c, 0x1e, 0x9c, 0x98, 0xef, 0x74, 0x40, 0xe3, 0xf1, 0x48, 0x8c, 0x14, - 0x66, 0xe4, 0x7d, 0xbd, 0xff, 0xcf, 0xae, 0xf8, 0x36, 0x79, 0x83, 0x76, - 0xe7, 0x66, 0x36, 0x12, 0x60, 0x17, 0x2f, 0xb0, 0x2f, 0x22, 0x32, 0x4b, - 0x42, 0x65, 0xed, 0x76, 0x6e, 0x4c, 0x9d, 0xb9, 0x54, 0x9b, 0x98, 0x8b, - 0x79, 0x8b, 0x0e, 0xaf, 0x9c, 0x8c, 0xa9, 0x58, 0xaa, 0xa2, 0xde, 0x1a, - 0x9b, 0x6d, 0x75, 0x0f, 0xd2, 0xd4, 0x28, 0xdc, 0xca, 0xcd, 0x91, 0x66, - 0xd0, 0xd9, 0xab, 0x3c, 0x22, 0x55, 0x36, 0x87, 0x4f, 0x41, 0x24, 0x5c, - 0xee, 0x5a, 0x54, 0x1a, 0xe0, 0xf5, 0x2c, 0x01, 0x98, 0xa3, 0x54, 0x6e, - 0x6f, 0xdc, 0x88, 0xf7, 0x86, 0xba, 0xe2, 0x8d, 0x84, 0x95, 0x78, 0x84, - 0x8c, 0xc1, 0xae, 0x8c, 0x7f, 0xa7, 0x91, 0xbc, 0x6d, 0x3b, 0x48, 0x7a, - 0x42, 0xa0, 0xc0, 0x0a, 0xfe, 0xda, 0xbc, 0xe7, 0xa6, 0x76, 0xcb, 0xca, - 0x68, 0xb0, 0xda, 0xb3, 0x2e, 0x4c, 0x57, 0x50, 0xeb, 0xbb, 0x0a, 0x35, - 0x94, 0x80, 0xab, 0xcf, 0xa7, 0xdc, 0xab, 0x31, 0x54, 0xef, 0xe0, 0x77, - 0xa5, 0x7e, 0x9e, 0x76, 0x96, 0x62, 0x92, 0x25, 0xf1, 0xa1, 0xa5, 0x91, - 0x06, 0x9e, 0x2f, 0x81, 0xd8, 0x5f, 0x2e, 0xe4, 0xe8, 0xda, 0x9f, 0xe1, - 0x62, 0xe1, 0x30, 0xd0, 0x16, 0x02, 0xc6, 0xeb, 0x3a, 0x43, 0x4e, 0x64, - 0x07, 0x77, 0xf2, 0xda, 0x0d, 0xf5, 0xd3, 0x1c, 0x26, 0x4c, 0xcd, 0xa4, - 0xb3, 0xc5, 0xd6, 0x73, 0xb4, 0xbc, 0xc0, 0x07, 0x64, 0x98, 0xfb, 0xf6, - 0x32, 0xe4, 0xe1, 0xca, 0x74, 0x4c, 0x64, 0xad, 0x04, 0x53, 0x1b, 0x99, - 0x24, 0x7b, 0x2e, 0xd7, 0x3e, 0x07, 0xba, 0x7a, 0x08, 0x7b, 0xb1, 0xb0, - 0x11, 0x3f, 0x4e, 0x66, 0xd8, 0xa5, 0x4e, 0x72, 0x67, 0xa6, 0xbe, 0x38, - 0x76, 0xcf, 0x72, 0x07, 0x9a, 0x57, 0x2f, 0x29, 0x6d, 0x55, 0xcd, 0x69, - 0xed, 0xcf, 0x59, 0x5e, 0xd9, 0xe5, 0x29, 0x5b, 0xd0, 0x4d, 0x85, 0xea, - 0x44, 0x0c, 0xac, 0x2d, 0x76, 0x28, 0x65, 0x39, 0x2a, 0xfc, 0x9f, 0xe8, - 0xd8, 0xce, 0x5c, 0x56, 0xc0, 0x33, 0xa4, 0xcc, 0x32, 0xa6, 0x00, 0xd8, - 0x9d, 0x9d, 0x0a, 0x28, 0x27, 0x15, 0x42, 0x8e, 0xeb, 0xb0, 0xef, 0x6f, - 0xb8, 0x93, 0xe2, 0xdf, 0x6e, 0x17, 0x46, 0x67, 0x59, 0x05, 0x92, 0xad, - 0x87, 0xc6, 0x06, 0x35, 0xc8, 0x4c, 0x05, 0x1c, 0x9f, 0xf4, 0xa4, 0xa4, - 0xa1, 0x8d, 0x11, 0xc7, 0xab, 0x4b, 0x9b, 0x3a, 0x71, 0xcb, 0x2d, 0x1f, - 0xec, 0x61, 0xa0, 0x66, 0x5f, 0x3d, 0xa3, 0x95, 0x39, 0x7f, 0x98, 0x34, - 0x79, 0x32, 0x15, 0x94, 0xa0, 0x16, 0xa4, 0xf3, 0x45, 0x7b, 0x31, 0xfe, - 0xf2, 0xe3, 0x65, 0x01, 0xc1, 0xf7, 0xcd, 0xcb, 0x59, 0x52, 0xbb, 0xf6, - 0xa4, 0x12, 0x22, 0x9e, 0x5f, 0xd0, 0x50, 0x8a, 0x43, 0x62, 0xfd, 0x22, - 0x21, 0xfb, 0xae, 0x08, 0x57, 0xc7, 0x00, 0xa6, 0x48, 0x2e, 0xcb, 0x0b, - 0x76, 0x08, 0xf9, 0xd4, 0x14, 0x9a, 0xb5, 0xcd, 0xb8, 0x33, 0xc3, 0x0d, - 0x2a, 0x3a, 0xf0, 0xe2, 0x5f, 0x0e, 0x1f, 0xa1, 0x1c, 0x71, 0x38, 0x2e, - 0x8e, 0x93, 0x13, 0x27, 0xa2, 0x4a, 0xdc, 0x95, 0x1e, 0x26, 0x30, 0x5f, - 0xdd, 0xc4, 0x15, 0x8e, 0xa8, 0xfd, 0x80, 0xf4, 0x9e, 0x31, 0x80, 0xc9, - 0xa0, 0xf7, 0x61, 0xb5, 0x55, 0x40, 0xb4, 0x7f, 0xd8, 0xb2, 0x6b, 0x58, - 0xba, 0x34, 0xba, 0x78, 0xa0, 0xee, 0xa2, 0xc4, 0x73, 0x19, 0xc7, 0xdf, - 0x1b, 0x46, 0x3c, 0xe0, 0x7c, 0xb3, 0xf9, 0x7c, 0x35, 0xd5, 0xf0, 0xbf, - 0x2c, 0xed, 0xa4, 0x20, 0x95, 0x0b, 0x05, 0x7a, 0xce, 0xdc, 0x81, 0x95, - 0xf3, 0x12, 0x8a, 0x7f, 0xcb, 0xa8, 0xdc, 0x77, 0xbf, 0x8b, 0xdf, 0xf6, - 0xb0, 0xce, 0xce, 0x0b, 0xdf, 0xe9, 0xcf, 0x92, 0x02, 0x20, 0x82, 0x81, - 0x9c, 0x03, 0x72, 0xe8, 0x41, 0x6b, 0xbe, 0xb6, 0x87, 0x8b, 0xf9, 0x9e, - 0x49, 0x77, 0xc5, 0xcf, 0x73, 0x9d, 0xf6, 0x1c, 0x42, 0x7c, 0xa8, 0xbb, - 0xe3, 0x24, 0x70, 0x9f, 0xef, 0x28, 0xce, 0x45, 0x13, 0x13, 0x5f, 0xad, - 0x02, 0x2a, 0xb4, 0x14, 0x80, 0x66, 0xe1, 0x6b, 0x29, 0x72, 0x77, 0xa3, - 0x04, 0x36, 0x28, 0x8d, 0xc6, 0x39, 0xa3, 0x29, 0x59, 0xbf, 0x1e, 0x69, - 0xcc, 0x8f, 0x25, 0x28, 0xb8, 0x24, 0x7c, 0xea, 0xe9, 0x4c, 0x43, 0x6e, - 0x6c, 0x7b, 0x1d, 0x41, 0x7f, 0xd9, 0xd9, 0x59, 0x1e, 0x45, 0x76, 0xcc, - 0x26, 0x6e, 0xe1, 0x80, 0x73, 0x4d, 0x79, 0x3c, 0x5c, 0x1d, 0x78, 0xf3, - 0xf9, 0x75, 0x2c, 0x9d, 0x9d, 0x8e, 0x90, 0x23, 0xf3, 0xf9, 0xd7, 0x68, - 0x14, 0xf3, 0x09, 0x2f, 0xa1, 0x86, 0xb1, 0x9d, 0xe2, 0x3c, 0xd3, 0x16, - 0xc4, 0xdf, 0x7c, 0xcf, 0xc5, 0xf2, 0x3e, 0x67, 0x8b, 0xc8, 0x3e, 0x23, - 0x17, 0xbf, 0x75, 0x1e, 0xf3, 0x35, 0xee, 0x9f, 0x14, 0xae, 0xc1, 0x5b, - 0xe7, 0x92, 0x68, 0xb8, 0x0f, 0x95, 0x67, 0x1b, 0x55, 0xe7, 0x90, 0x6f, - 0x72, 0xa0, 0x78, 0xd2, 0x57, 0xca, 0x0a, 0x92, 0x62, 0x8d, 0x20, 0x52, - 0x84, 0xb3, 0xae, 0x8e, 0x22, 0x3d, 0x36, 0x3a, 0xfe, 0x68, 0x2d, 0x89, - 0x8f, 0x51, 0x5b, 0x87, 0x87, 0x21, 0x69, 0x1a, 0x90, 0x97, 0x9e, 0x2f, - 0x91, 0xae, 0x32, 0x17, 0x08, 0x0b, 0x3e, 0x65, 0x8a, 0xaa, 0x8e, 0xf3, - 0x7b, 0x43, 0xc4, 0x2d, 0x05, 0xac, 0x7a, 0xd9, 0x29, 0x41, 0xf8, 0x80, - 0x64, 0x99, 0x98, 0xc3, 0xb8, 0x4b, 0x4a, 0x4b, 0x48, 0x2a, 0xbd, 0x38, - 0x42, 0x3a, 0xf1, 0x67, 0x03, 0x1d, 0xd8, 0x00, 0x50, 0xc9, 0xce, 0x3a, - 0x34, 0xe5, 0xac, 0x5f, 0x36, 0x55, 0xf4, 0xf2, 0xa6, 0x09, 0x04, 0x20, - 0x64, 0x56, 0xa1, 0x15, 0x65, 0x4d, 0x07, 0x7e, 0x47, 0xf7, 0x34, 0x30, - 0x3a, 0xbe, 0x49, 0xc1, 0x75, 0xa3, 0x7d, 0xe5, 0x0e, 0xba, 0xdf, 0x81, - 0xc0, 0x94, 0xf8, 0xec, 0x1d, 0x81, 0x63, 0x48, 0x12, 0x16, 0x82, 0x12, - 0x8b, 0x2a, 0xf7, 0x6e, 0x23, 0xa4, 0x11, 0x8b, 0x70, 0xb3, 0x8a, 0xce, - 0xd0, 0xdf, 0xc4, 0x6f, 0x65, 0x01, 0xe4, 0x6e, 0x61, 0x58, 0x78, 0x2a, - 0x4b, 0x9a, 0x1b, 0x65, 0x94, 0xc4, 0xc5, 0x9d, 0x95, 0xc6, 0x12, 0x6f, - 0xfc, 0x8a, 0x5e, 0x7f, 0xc8, 0xbe, 0xa9, 0xf0, 0x65, 0xb9, 0xa7, 0xe5, - 0xa9, 0x39, 0xc3, 0x7a, 0x79, 0x05, 0x72, 0x77, 0x1f, 0xf7, 0x2b, 0x29, - 0xf5, 0xb9, 0xce, 0x20, 0x82, 0x01, 0x21, 0xa0, 0x0c, 0xd5, 0x7c, 0x7b, - 0xe5, 0x9a, 0xea, 0xdb, 0x71, 0xa6, 0xef, 0x57, 0xca, 0x0d, 0x55, 0x3e, - 0x3c, 0x9e, 0xac, 0x6c, 0x18, 0x4e, 0xe9, 0xc4, 0x67, 0x00, 0x1d, 0xc3, - 0xf6, 0x88, 0x9d, 0xd5, 0xb4, 0x1a, 0xa8, 0xde, 0xfa, 0x8c, 0xe8, 0xb5, - 0x8a, 0xec, 0x6c, 0x94, 0x62, 0x63, 0x00, 0xaf, 0x8a, 0x91, 0x4b, 0x1b, - 0x01, 0x90, 0x72, 0xa5, 0x0a, 0x03, 0x50, 0xc7, 0x0d, 0x66, 0xaf, 0xca, - 0xae, 0xe5, 0x7f, 0x00, 0x00, 0x02, 0xc6, 0x6d, 0x6f, 0x6f, 0x76, 0x00, - 0x00, 0x00, 0x6c, 0x6d, 0x76, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0x7c, - 0x25, 0xb0, 0x80, 0x7c, 0x25, 0xb0, 0x80, 0x00, 0x00, 0x03, 0xe8, 0x00, - 0x00, 0x00, 0x54, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x01, 0xf1, 0x74, 0x72, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x5c, 0x74, - 0x6b, 0x68, 0x64, 0x00, 0x00, 0x00, 0x0f, 0x7c, 0x25, 0xb0, 0x80, 0x7c, - 0x25, 0xb0, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, - 0xf0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8d, 0x6d, 0x64, 0x69, 0x61, 0x00, - 0x00, 0x00, 0x20, 0x6d, 0x64, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0x7c, - 0x25, 0xb0, 0x80, 0x7c, 0x25, 0xb0, 0x80, 0x00, 0x00, 0x00, 0x0c, 0x00, - 0x00, 0x00, 0x01, 0x55, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x68, - 0x64, 0x6c, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, - 0x69, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, - 0x64, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x01, 0x38, 0x6d, 0x69, 0x6e, 0x66, - 0x00, 0x00, 0x00, 0x14, 0x76, 0x6d, 0x68, 0x64, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, - 0x64, 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, 0x66, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, - 0x75, 0x72, 0x6c, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf8, - 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, 0x94, 0x73, 0x74, 0x73, 0x64, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x84, - 0x61, 0x76, 0x63, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0xf0, 0x00, 0x48, 0x00, 0x00, - 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x2e, 0x61, 0x76, 0x63, 0x43, 0x01, 0x4d, 0x40, 0x0d, 0xff, 0xe1, - 0x00, 0x17, 0x67, 0x4d, 0x40, 0x0d, 0xab, 0x40, 0xa0, 0xfd, 0x80, 0x88, - 0x00, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0xc4, 0x78, 0xa1, - 0x55, 0x01, 0x00, 0x04, 0x68, 0xee, 0x32, 0xc8, 0x00, 0x00, 0x00, 0x18, - 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, - 0x73, 0x74, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x14, 0x73, 0x74, 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x2f, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, - 0x73, 0x74, 0x63, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x61, 0x75, 0x64, 0x74, 0x61, - 0x00, 0x00, 0x00, 0x59, 0x6d, 0x65, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x22, 0x68, 0x64, 0x6c, 0x72, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6d, 0x64, 0x69, 0x72, 0x61, 0x70, 0x70, 0x6c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x2b, 0x69, 0x6c, 0x73, 0x74, 0x00, 0x00, 0x00, 0x23, 0xa9, 0x74, - 0x6f, 0x6f, 0x00, 0x00, 0x00, 0x1b, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x61, 0x76, 0x66, 0x35, 0x32, - 0x2e, 0x33, 0x32, 0x2e, 0x30 +static const guchar h264_clip[H264_CLIP_DATA_SIZE] = { + 0x00, 0x00, 0x01, 0x67, 0x4d, 0x40, 0x0d, 0xab, 0x40, 0xa0, 0xfd, 0x80, + 0x88, 0x00, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0xc4, 0x78, + 0xa1, 0x55, 0x00, 0x00, 0x01, 0x68, 0xee, 0x32, 0xc8, 0x00, 0x00, 0x01, + 0x65, 0x88, 0x82, 0x00, 0x45, 0xbb, 0x9d, 0x38, 0x9b, 0xe8, 0x48, 0xef, + 0xed, 0xa7, 0xd7, 0x9c, 0x19, 0x9b, 0x5a, 0xca, 0x00, 0x0d, 0x54, 0x0c, + 0xe3, 0xd5, 0xad, 0xa9, 0x5d, 0x71, 0x24, 0x83, 0xbb, 0x36, 0x4d, 0xb1, + 0xf5, 0x0f, 0xc6, 0x66, 0xb6, 0x6d, 0x1d, 0xa5, 0x45, 0xfc, 0xa0, 0x4c, + 0xbf, 0xfb, 0x2f, 0x5c, 0x1a, 0x5a, 0x3b, 0x29, 0xe0, 0x35, 0x95, 0x44, + 0x8e, 0x2f, 0x22, 0xd3, 0x3a, 0x48, 0x88, 0x7d, 0x32, 0x97, 0xff, 0xd8, + 0x54, 0x7f, 0x7f, 0x65, 0x57, 0x71, 0xaf, 0xba, 0x17, 0xe0, 0x12, 0x24, + 0xc9, 0x5b, 0xaa, 0xc7, 0xd5, 0x27, 0xc9, 0x64, 0x5d, 0x5e, 0xa0, 0xea, + 0x57, 0xd2, 0x7d, 0x55, 0x6c, 0xf2, 0x44, 0x2f, 0x4b, 0x5d, 0xbd, 0x62, + 0xb9, 0xc2, 0xfa, 0x1e, 0x8f, 0xbc, 0x57, 0x5f, 0xc1, 0x2d, 0xb3, 0x9a, + 0x0e, 0x58, 0x75, 0xf7, 0x08, 0xdf, 0x2d, 0xda, 0xc1, 0xa5, 0x55, 0x76, + 0x06, 0xaf, 0x92, 0x28, 0x43, 0xc5, 0x20, 0x16, 0x96, 0xf5, 0x79, 0x1e, + 0x88, 0x77, 0xb3, 0x4e, 0xb8, 0x4f, 0x3e, 0x51, 0x3c, 0xcf, 0xc0, 0x28, + 0xda, 0xb8, 0xa3, 0x1d, 0xed, 0x8e, 0x04, 0x74, 0x82, 0xc1, 0x5d, 0xa8, + 0x3c, 0x25, 0xd2, 0x84, 0x0b, 0x34, 0x40, 0x8b, 0x7f, 0xee, 0xae, 0xf8, + 0xde, 0x6e, 0x28, 0xf6, 0xfc, 0xfc, 0x14, 0x7e, 0x95, 0xd9, 0xd8, 0x2c, + 0x09, 0x49, 0x27, 0x64, 0x13, 0x83, 0x5c, 0x6f, 0xd4, 0x09, 0x48, 0xa8, + 0xd4, 0x1b, 0x6e, 0x4d, 0x05, 0x0a, 0xbe, 0x27, 0xff, 0xf4, 0x27, 0x04, + 0x41, 0xa0, 0x23, 0x61, 0xe6, 0x26, 0x32, 0xf4, 0xa3, 0xca, 0x97, 0xfc, + 0xeb, 0x6b, 0x45, 0x35, 0x13, 0x69, 0xd9, 0x41, 0x0f, 0xa6, 0xc0, 0xbe, + 0xd5, 0xfa, 0x28, 0xa6, 0x4f, 0x62, 0x3e, 0x1f, 0xcb, 0x98, 0x0a, 0x70, + 0x09, 0xc1, 0xe3, 0x69, 0x30, 0x20, 0xe7, 0xd5, 0x1c, 0xf0, 0x7e, 0x52, + 0x1d, 0x6a, 0xdd, 0x14, 0x58, 0x5e, 0x7a, 0x35, 0x57, 0xa1, 0xe6, 0x83, + 0x46, 0x57, 0x6e, 0x57, 0x7f, 0x72, 0x5d, 0x0c, 0x0c, 0xf4, 0x40, 0x11, + 0x8c, 0xbb, 0xdf, 0xd1, 0x54, 0xfb, 0x7d, 0xf7, 0x03, 0xb9, 0x4e, 0xa3, + 0x76, 0x4c, 0xce, 0xfb, 0x9e, 0x39, 0x02, 0xf0, 0x48, 0xb5, 0x8c, 0x36, + 0x6e, 0x93, 0x79, 0x48, 0xcc, 0x28, 0xec, 0xd7, 0xb8, 0x02, 0xe5, 0xa3, + 0x37, 0x01, 0xe1, 0x3c, 0x40, 0x8f, 0x68, 0x27, 0xbc, 0xec, 0x6b, 0x59, + 0xb9, 0xfe, 0xb8, 0x67, 0x68, 0x83, 0x99, 0x97, 0x1e, 0xcc, 0x4e, 0x23, + 0x82, 0x26, 0x93, 0x7b, 0x7a, 0x9e, 0xdc, 0x42, 0xca, 0x1b, 0x3e, 0x13, + 0x19, 0x45, 0x03, 0x40, 0xab, 0xd2, 0xda, 0x6b, 0x6c, 0x26, 0xdb, 0xe3, + 0x72, 0x06, 0x89, 0xea, 0x03, 0x95, 0xe3, 0x14, 0xe1, 0x4a, 0x16, 0x58, + 0x2d, 0x67, 0xaa, 0xbf, 0xbe, 0x37, 0x54, 0x19, 0xb1, 0x57, 0x61, 0x85, + 0x82, 0x5f, 0x63, 0x33, 0xe2, 0xf8, 0x7f, 0x4f, 0x21, 0x44, 0x8a, 0x0e, + 0x21, 0x2b, 0x12, 0x99, 0x4d, 0xd9, 0x2e, 0xea, 0x36, 0x2d, 0x45, 0xcb, + 0xe2, 0xfe, 0xdd, 0x03, 0x3b, 0x08, 0x58, 0x60, 0x1e, 0xb2, 0xfa, 0x3b, + 0x89, 0xa5, 0x03, 0xde, 0xab, 0x71, 0x32, 0x48, 0x46, 0x2c, 0xfb, 0x2b, + 0x84, 0x83, 0xc9, 0xff, 0xf6, 0xf5, 0x2f, 0xe7, 0x2f, 0x6a, 0x5d, 0x86, + 0xe2, 0x48, 0x23, 0x6d, 0x84, 0x60, 0x9b, 0xc0, 0x25, 0x1e, 0xff, 0x94, + 0xe8, 0xf4, 0xd0, 0x4e, 0x11, 0x60, 0xda, 0x20, 0xa8, 0xfd, 0xf3, 0x00, + 0x4f, 0x0e, 0x4f, 0xa2, 0xeb, 0xe1, 0xa8, 0xb3, 0x47, 0x35, 0x62, 0x83, + 0x6f, 0x08, 0x6b, 0xb8, 0x82, 0x04, 0xcc, 0x63, 0x69, 0xd7, 0xba, 0x10, + 0xd4, 0x51, 0xe6, 0xb5, 0x34, 0xe8, 0x7d, 0xaf, 0x87, 0xcf, 0x1d, 0xeb, + 0x46, 0xc1, 0xcd, 0xcb, 0xf2, 0x3b, 0x3e, 0xa0, 0x61, 0xc7, 0x68, 0x86, + 0x0b, 0x9f, 0x0b, 0x59, 0xc0, 0x79, 0x4e, 0xcc, 0x79, 0x91, 0xa0, 0xe8, + 0x80, 0x6c, 0xbd, 0x35, 0x12, 0x71, 0x2f, 0x5e, 0xa4, 0xfc, 0xe6, 0x51, + 0xe0, 0xbe, 0x41, 0x1a, 0x19, 0x60, 0xd8, 0xac, 0xcd, 0x93, 0x05, 0x70, + 0xa0, 0xda, 0x53, 0x4e, 0x5a, 0x6d, 0x9b, 0x3f, 0x28, 0x73, 0x87, 0x6f, + 0x6d, 0x41, 0x5a, 0x13, 0xd0, 0xea, 0x19, 0xb3, 0xb7, 0xf1, 0x75, 0x92, + 0xae, 0x43, 0x9d, 0xe3, 0xa7, 0x4d, 0x5a, 0x52, 0x36, 0xce, 0x6b, 0x1e, + 0x2b, 0x2e, 0xab, 0x0c, 0xd7, 0xe4, 0x1c, 0x44, 0x72, 0x9d, 0x86, 0xb6, + 0xeb, 0xe5, 0x80, 0xc4, 0x45, 0x21, 0x8b, 0xe0, 0xe0, 0x9d, 0x09, 0xfa, + 0x0b, 0x59, 0x0c, 0x2c, 0x9d, 0x97, 0x15, 0x56, 0xd0, 0x21, 0xd8, 0x90, + 0xb4, 0x89, 0xc4, 0x96, 0x76, 0xf1, 0x64, 0xa5, 0x85, 0x2a, 0x13, 0xfb, + 0xfa, 0x11, 0x1e, 0x2d, 0x63, 0xc2, 0x9a, 0x87, 0x99, 0x2c, 0x18, 0xb8, + 0xeb, 0x6a, 0x5c, 0x68, 0x26, 0x63, 0xcc, 0x1b, 0x1a, 0x5c, 0x7f, 0x0d, + 0x45, 0xcc, 0x56, 0x46, 0x92, 0xbb, 0x76, 0xf2, 0x2e, 0x52, 0x05, 0x3c, + 0xe3, 0xbb, 0x59, 0x9b, 0x89, 0x03, 0x0d, 0x48, 0xb1, 0xdc, 0x78, 0x04, + 0x03, 0x24, 0xf4, 0x62, 0xcf, 0xb1, 0xc6, 0x64, 0x05, 0xbd, 0x89, 0x94, + 0x1a, 0x8d, 0xc1, 0xbe, 0xac, 0xe0, 0xed, 0x89, 0xf3, 0x47, 0x81, 0x82, + 0xb9, 0x64, 0xcc, 0x8e, 0xc4, 0x1e, 0xa9, 0xf6, 0xde, 0x8d, 0xb7, 0x33, + 0xba, 0x5b, 0x49, 0x0d, 0x0a, 0x16, 0x96, 0x7d, 0x89, 0x82, 0xe0, 0x5a, + 0x08, 0x55, 0xbd, 0xce, 0xca, 0xc0, 0x46, 0x1a, 0x6b, 0xf9, 0x7d, 0x03, + 0xe8, 0x35, 0x69, 0x7d, 0x87, 0xc9, 0x71, 0x01, 0x7e, 0xa8, 0x3a, 0x9c, + 0xd5, 0xe2, 0x71, 0xa6, 0xc7, 0xe2, 0x2d, 0xf3, 0x6f, 0x74, 0x0f, 0x3e, + 0x03, 0x70, 0x5e, 0xec, 0x8c, 0x66, 0xf9, 0x71, 0x9a, 0xd2, 0x56, 0x57, + 0x37, 0xcd, 0x50, 0x55, 0x97, 0xea, 0x67, 0x20, 0x59, 0x06, 0x4d, 0x22, + 0xa0, 0x85, 0x90, 0xb3, 0x59, 0x15, 0x75, 0x0d, 0x70, 0xbd, 0xb5, 0x7d, + 0x72, 0xaa, 0xea, 0xfc, 0x9d, 0x08, 0x8d, 0xdf, 0x31, 0x21, 0x2d, 0xef, + 0x00, 0x24, 0x6c, 0xae, 0x82, 0x6e, 0x1a, 0x4b, 0x28, 0xa5, 0x6d, 0x98, + 0xeb, 0x50, 0x87, 0x6f, 0x1b, 0xa5, 0xba, 0x1c, 0xda, 0x59, 0xb8, 0x4c, + 0x17, 0xe3, 0xd5, 0x10, 0x46, 0x94, 0x91, 0xed, 0x0b, 0xd3, 0xfc, 0x06, + 0x81, 0x60, 0x88, 0x5f, 0x58, 0x81, 0x26, 0x54, 0xdc, 0xd5, 0x7c, 0xbe, + 0x30, 0x04, 0x17, 0x84, 0x76, 0xe8, 0xb6, 0x8a, 0xec, 0x84, 0x02, 0xcf, + 0xc7, 0xda, 0x2d, 0x2e, 0x31, 0xc2, 0x77, 0x31, 0x54, 0x32, 0xbd, 0x77, + 0xa2, 0xa5, 0x5d, 0xec, 0x1c, 0x27, 0xf6, 0xec, 0xc8, 0x3f, 0xeb, 0x1a, + 0x24, 0xcb, 0x74, 0xd0, 0xb3, 0x52, 0xa8, 0x8f, 0x4c, 0x26, 0xbf, 0x68, + 0xb2, 0x87, 0xf3, 0xa8, 0xa9, 0x4f, 0x71, 0x57, 0xc7, 0xa8, 0x34, 0x5a, + 0x01, 0x68, 0xae, 0x5c, 0xb3, 0xd8, 0x23, 0x6b, 0xea, 0x18, 0xdf, 0xa9, + 0xe5, 0xc4, 0x11, 0x49, 0x2b, 0xfa, 0xa8, 0xf3, 0x8f, 0x80, 0x47, 0xa0, + 0x19, 0xc7, 0x20, 0xef, 0xbf, 0xed, 0xe1, 0x38, 0x8b, 0x16, 0x54, 0x36, + 0x60, 0x8b, 0x04, 0x26, 0x9c, 0x6b, 0x1a, 0x95, 0x4c, 0x94, 0x6a, 0x53, + 0xcf, 0xb4, 0x4b, 0x38, 0x3a, 0x15, 0x26, 0x94, 0x10, 0x1c, 0x35, 0xe4, + 0x57, 0x80, 0x19, 0xad, 0x1f, 0x82, 0xe8, 0x47, 0xe4, 0x90, 0xa2, 0x42, + 0x30, 0x43, 0x15, 0x92, 0x2b, 0x39, 0xfb, 0x7b, 0xb3, 0xdb, 0xc7, 0x5b, + 0x79, 0x5e, 0x91, 0xba, 0x38, 0x74, 0xd6, 0x00, 0x26, 0xa5, 0x8f, 0xa4, + 0x31, 0xe6, 0x7b, 0xeb, 0x52, 0xc2, 0xe2, 0xa1, 0x6b, 0x5f, 0x17, 0xf1, + 0x15, 0xc9, 0x4b, 0x44, 0x93, 0x77, 0x28, 0xdf, 0x2a, 0xc0, 0xb5, 0x97, + 0xfc, 0xbe, 0x2e, 0x72, 0x53, 0x58, 0xf9, 0x33, 0x3a, 0xb0, 0x6e, 0xaf, + 0x0c, 0x1b, 0xcf, 0x71, 0x37, 0x6b, 0x4a, 0x9a, 0x66, 0x16, 0x90, 0x43, + 0x9b, 0x70, 0x0d, 0x8f, 0xd3, 0x04, 0x4b, 0x14, 0xf2, 0x58, 0x9f, 0x64, + 0x33, 0x21, 0xdc, 0x02, 0x8a, 0x5b, 0xd6, 0x80, 0x9c, 0x22, 0xc8, 0x39, + 0x7d, 0x2d, 0x7c, 0x09, 0x4e, 0x6a, 0x8c, 0x8d, 0x0c, 0xc4, 0xfe, 0x6f, + 0x8c, 0x50, 0xf2, 0x75, 0xc0, 0x12, 0x6f, 0xd3, 0x9d, 0x07, 0xc0, 0xe9, + 0xdf, 0x36, 0xa2, 0x6f, 0xca, 0x14, 0x5b, 0x0f, 0x5a, 0xd8, 0x35, 0x72, + 0x07, 0x08, 0x80, 0xba, 0x2f, 0x61, 0x7f, 0xb0, 0x5e, 0xbb, 0xb1, 0x47, + 0x6a, 0xbd, 0x6a, 0xe4, 0xb6, 0xa2, 0xec, 0x2e, 0x27, 0x43, 0xbc, 0xd7, + 0x2c, 0x2c, 0xf3, 0x6c, 0x12, 0x4c, 0x86, 0x5a, 0x38, 0xa4, 0x87, 0xa8, + 0xe1, 0x70, 0x17, 0x15, 0xd0, 0x2b, 0x87, 0xdb, 0x87, 0xc0, 0x85, 0x57, + 0x30, 0x31, 0x16, 0x07, 0x9b, 0x72, 0x07, 0xf5, 0x18, 0x6d, 0xd1, 0x8d, + 0x31, 0xa1, 0x25, 0x6a, 0xb4, 0xf3, 0x07, 0x5f, 0x0c, 0x99, 0x33, 0x68, + 0xbf, 0x2c, 0xa1, 0xfd, 0xde, 0x16, 0x2d, 0x4a, 0x5a, 0xa0, 0x7e, 0xe5, + 0x9b, 0x89, 0x4a, 0x8d, 0xe7, 0x18, 0x21, 0x32, 0x47, 0x3c, 0x9d, 0x48, + 0xab, 0x7d, 0xca, 0xb4, 0x63, 0xd9, 0xfd, 0x29, 0x2d, 0x4c, 0xf1, 0xf2, + 0x20, 0x0a, 0x91, 0x2e, 0x2c, 0xa1, 0x49, 0x83, 0x73, 0x15, 0xa0, 0x7d, + 0x6e, 0xae, 0x51, 0x45, 0x0d, 0x09, 0x1f, 0x8f, 0x61, 0x42, 0xbd, 0x24, + 0xcd, 0x3e, 0xe8, 0x66, 0x84, 0xc6, 0x97, 0x08, 0x7b, 0x72, 0x73, 0x7e, + 0xe7, 0x99, 0x05, 0xab, 0x63, 0xff, 0x3c, 0x44, 0xa1, 0xc0, 0x1b, 0xfc, + 0xff, 0x27, 0xe9, 0x45, 0x82, 0x75, 0x82, 0x6f, 0x9c, 0x65, 0xef, 0x67, + 0xd6, 0x00, 0xd1, 0x9f, 0x61, 0x9f, 0x38, 0xdd, 0x7f, 0x5f, 0x4d, 0x67, + 0x5b, 0x5d, 0xff, 0x98, 0x6b, 0x13, 0xe0, 0xe7, 0x69, 0xcb, 0x7f, 0x7c, + 0x11, 0x91, 0xe0, 0x05, 0xb9, 0x64, 0xd0, 0xb7, 0x91, 0xe5, 0xd4, 0x3a, + 0x47, 0x05, 0x25, 0x4f, 0x15, 0x46, 0xaf, 0x41, 0x9e, 0xc7, 0x49, 0x15, + 0x17, 0xd1, 0x9c, 0x28, 0xef, 0x80, 0xa3, 0x8b, 0x60, 0xcc, 0x60, 0xeb, + 0x96, 0x36, 0x3a, 0x23, 0x94, 0xf3, 0x6c, 0xe5, 0x3f, 0xe8, 0x8b, 0x5c, + 0x8c, 0xfe, 0x6f, 0x91, 0x65, 0x19, 0xa1, 0x4d, 0x45, 0x7b, 0x06, 0x0f, + 0x71, 0xb7, 0x9a, 0x8d, 0x8e, 0x82, 0x7b, 0x68, 0x44, 0xa4, 0xa6, 0xc3, + 0xe5, 0x67, 0x9f, 0x6c, 0xd0, 0xe4, 0xe8, 0x37, 0x08, 0x6b, 0xbb, 0xa0, + 0x3a, 0xd0, 0xa9, 0xd9, 0x04, 0xaa, 0x91, 0xac, 0x71, 0xff, 0xec, 0x7e, + 0xaf, 0xa9, 0x99, 0xa2, 0x8d, 0x91, 0x95, 0xb3, 0xd8, 0xe4, 0xf3, 0x3f, + 0xa6, 0x4b, 0x0c, 0x19, 0x23, 0xf7, 0xa7, 0xcd, 0x4c, 0x41, 0x28, 0x63, + 0x9f, 0x0b, 0x8f, 0x70, 0x70, 0xbd, 0x25, 0x16, 0x8e, 0x86, 0x8a, 0x69, + 0xe3, 0x6a, 0xd4, 0x98, 0x42, 0x56, 0x15, 0x2d, 0x3d, 0xdb, 0x17, 0x1b, + 0x23, 0x58, 0x82, 0x56, 0x11, 0x97, 0x85, 0xf2, 0x68, 0x95, 0x92, 0xd5, + 0x9e, 0x91, 0x05, 0x70, 0xc8, 0x96, 0xb2, 0x73, 0x6d, 0x1e, 0x12, 0x8c, + 0xa0, 0xe4, 0x1a, 0x84, 0x5b, 0xb4, 0x32, 0xf7, 0x9e, 0x08, 0xd0, 0x6c, + 0x42, 0xf0, 0x0b, 0xc4, 0x1f, 0xe0, 0xbb, 0x71, 0xe1, 0x2d, 0x86, 0xd7, + 0x77, 0x24, 0x43, 0x53, 0x0c, 0x88, 0x21, 0x75, 0x95, 0xd0, 0xfe, 0x10, + 0x23, 0xcd, 0xba, 0x77, 0x3d, 0x9b, 0x0f, 0xb2, 0xe2, 0xcc, 0x0f, 0x94, + 0xe0, 0x66, 0x90, 0x0e, 0xf7, 0x6a, 0x3c, 0x9f, 0xc0, 0xf6, 0x98, 0x1c, + 0x4c, 0x9f, 0x25, 0xc4, 0xeb, 0x1d, 0x91, 0x32, 0x29, 0x34, 0x2a, 0xb0, + 0x7e, 0x1c, 0x09, 0x77, 0x13, 0x83, 0xfa, 0xcf, 0x24, 0xa2, 0x5f, 0x79, + 0x78, 0x64, 0xf7, 0x45, 0x81, 0xbe, 0x6a, 0x82, 0x26, 0xfd, 0xe7, 0xc3, + 0x61, 0x41, 0x27, 0xcc, 0x99, 0x69, 0x77, 0xc8, 0xa7, 0xf3, 0x52, 0x01, + 0xa7, 0x8c, 0x0b, 0x7d, 0x86, 0x8d, 0xbb, 0x31, 0xd6, 0x67, 0xf9, 0xa7, + 0x8f, 0x76, 0xb6, 0x74, 0x26, 0x43, 0x35, 0xb8, 0x83, 0x7c, 0x16, 0x34, + 0x88, 0x0c, 0xb6, 0xec, 0xf0, 0x01, 0x8c, 0x1c, 0xe5, 0x52, 0xd4, 0xca, + 0x01, 0x2e, 0xb5, 0x87, 0xc1, 0xc1, 0x1b, 0xa3, 0x02, 0x17, 0x13, 0xd3, + 0x35, 0xe8, 0x80, 0xe1, 0xd1, 0x01, 0x9c, 0x0a, 0x62, 0x7d, 0x98, 0x7c, + 0x68, 0xa4, 0x8e, 0x3a, 0x50, 0x4b, 0x95, 0x59, 0xa3, 0x11, 0xf6, 0xa3, + 0xde, 0x92, 0x65, 0x00, 0xa0, 0xe8, 0x32, 0xf0, 0xc3, 0x77, 0x68, 0x0b, + 0xed, 0xc1, 0x69, 0xd2, 0x6e, 0xce, 0x80, 0xe4, 0x56, 0x9b, 0x15, 0xbf, + 0x3c, 0x4a, 0x38, 0x26, 0xf6, 0x6a, 0xdb, 0x62, 0x7a, 0xab, 0xb1, 0x77, + 0x75, 0x0d, 0xa7, 0xa4, 0xcf, 0x5e, 0x2d, 0xea, 0x24, 0x84, 0xbd, 0x83, + 0x8e, 0xaa, 0x91, 0xe1, 0x72, 0x5f, 0x7f, 0x26, 0x54, 0x4f, 0xab, 0xa6, + 0x50, 0x22, 0x68, 0x8c, 0xa6, 0x06, 0x67, 0x3c, 0x3e, 0x93, 0x9a, 0xc2, + 0x53, 0x15, 0x08, 0x1a, 0x3c, 0xb3, 0x3f, 0xf0, 0x83, 0xf5, 0x0d, 0x9c, + 0xe3, 0x76, 0x11, 0x45, 0x21, 0x6b, 0x65, 0x97, 0xea, 0x3c, 0xdb, 0x0d, + 0xcd, 0x6e, 0xb7, 0x26, 0x7b, 0x82, 0x63, 0x35, 0x7e, 0x76, 0xf4, 0xb8, + 0x0e, 0xe5, 0x1d, 0x95, 0x94, 0x1c, 0x60, 0xc7, 0xea, 0x9c, 0x1c, 0x73, + 0x75, 0x0e, 0x9b, 0x5f, 0x78, 0x09, 0x4f, 0x90, 0x31, 0x5c, 0xc8, 0x5b, + 0x78, 0xce, 0xb3, 0x3e, 0x31, 0x61, 0x90, 0xba, 0xe0, 0xe1, 0x57, 0x1d, + 0x71, 0x80, 0x92, 0x6b, 0x75, 0xe1, 0x34, 0x95, 0xeb, 0x88, 0xe4, 0x0b, + 0x72, 0xdc, 0x34, 0x24, 0x3b, 0x6d, 0x94, 0xc9, 0xe9, 0x8d, 0x38, 0x72, + 0x9c, 0x61, 0x6e, 0x07, 0xd7, 0x35, 0xa1, 0x74, 0xc2, 0x0c, 0x36, 0xc3, + 0x54, 0xd3, 0xe5, 0xd1, 0x08, 0x8e, 0x24, 0x77, 0xf5, 0x61, 0xcf, 0x69, + 0x9b, 0x27, 0x70, 0xe7, 0x52, 0xf6, 0xef, 0x66, 0x8f, 0x0e, 0x8b, 0xc0, + 0xf3, 0x64, 0x2a, 0xa8, 0xff, 0xcc, 0xd9, 0x61, 0x53, 0xac, 0x36, 0x23, + 0x4f, 0x3c, 0x0f, 0xe0, 0xec, 0xad, 0xc5, 0x35, 0x3f, 0x3b, 0x74, 0x26, + 0x84, 0x48, 0xd1, 0xfe, 0x72, 0x01, 0xea, 0x4d, 0x03, 0x46, 0x66, 0x5a, + 0xc4, 0x0a, 0x55, 0x43, 0x61, 0x36, 0x6a, 0xc1, 0xd2, 0x74, 0x0a, 0x8f, + 0x01, 0xb2, 0xc2, 0xaa, 0xd7, 0x2d, 0x0a, 0x0f, 0x67, 0xa1, 0x25, 0x7d, + 0x45, 0x60, 0x0f, 0x06, 0xfb, 0x8f, 0x8b, 0xe0, 0x4a, 0x8c, 0xd7, 0x19, + 0xac, 0xcc, 0x47, 0xa2, 0x7c, 0x30, 0x90, 0x94, 0x81, 0xab, 0xde, 0x38, + 0xb8, 0xc9, 0xdb, 0x63, 0x9c, 0xcb, 0xdd, 0x71, 0xde, 0x4f, 0x1e, 0x43, + 0x08, 0xe4, 0xe3, 0x83, 0x86, 0x0f, 0x34, 0xb7, 0x1e, 0x53, 0xc1, 0xde, + 0x46, 0xf1, 0x70, 0xf5, 0xd8, 0x47, 0xd2, 0x9b, 0x44, 0x88, 0x85, 0x8e, + 0x32, 0xa9, 0x0c, 0x09, 0x2f, 0xd0, 0xe4, 0x4b, 0x30, 0x3a, 0x2e, 0x65, + 0x0c, 0xff, 0xb4, 0x0d, 0xa8, 0x8f, 0x61, 0x3e, 0x7e, 0x90, 0x66, 0xbb, + 0xf6, 0xbe, 0xfd, 0x7d, 0xe4, 0xdc, 0x2c, 0x59, 0x87, 0x81, 0x60, 0x96, + 0xd7, 0x1d, 0x10, 0x02, 0x35, 0xdd, 0x16, 0x4c, 0xe9, 0x2d, 0x52, 0x45, + 0xdd, 0x3f, 0xc9, 0xff, 0x8d, 0x19, 0xad, 0x02, 0x74, 0xf1, 0x09, 0x99, + 0x94, 0x66, 0x2e, 0x8b, 0xa3, 0xdc, 0x3d, 0xf3, 0xf5, 0x85, 0xf2, 0x60, + 0x7d, 0x9d, 0xe0, 0xd3, 0x0f, 0xa4, 0x92, 0xf3, 0x55, 0xbc, 0x7b, 0x20, + 0x6b, 0xf6, 0xc4, 0xc4, 0x0f, 0x8a, 0xd7, 0x5a, 0x02, 0xb0, 0xb7, 0x78, + 0xb4, 0x9e, 0xb6, 0x93, 0x95, 0x2e, 0x76, 0x06, 0x1e, 0x34, 0x5d, 0x34, + 0x77, 0x77, 0x6d, 0x32, 0xbb, 0x46, 0xad, 0x43, 0xd7, 0x72, 0x61, 0x33, + 0x4f, 0x98, 0xe9, 0x56, 0x3a, 0x96, 0x89, 0x6e, 0x1f, 0xaf, 0x6b, 0xa0, + 0x9a, 0xe4, 0x42, 0x5a, 0xb3, 0xb8, 0x2a, 0xe1, 0x2d, 0xa6, 0x32, 0xa2, + 0x01, 0xf5, 0x3a, 0x9a, 0xbb, 0x06, 0x76, 0x0b, 0xa8, 0xac, 0x02, 0x96, + 0x0c, 0x58, 0xd3, 0x64, 0xc8, 0xe2, 0xae, 0x6c, 0xf7, 0xa7, 0x32, 0x4b, + 0x51, 0x50, 0x11, 0x90, 0xcf, 0x37, 0xed, 0xd2, 0xa0, 0xa4, 0x97, 0xb3, + 0x45, 0x1d, 0x7d, 0xf3, 0xff, 0xde, 0x9f, 0x80, 0xa9, 0x61, 0xac, 0x37, + 0x7f, 0x5d, 0xc9, 0xf6, 0xdc, 0x26, 0xd0, 0x65, 0xf2, 0xdc, 0x0c, 0x1a, + 0xcb, 0xde, 0x6b, 0x77, 0xf3, 0x08, 0xa4, 0x93, 0xab, 0x2a, 0xdf, 0x18, + 0x1a, 0xc7, 0xa6, 0xa1, 0x7e, 0x43, 0x75, 0xca, 0x88, 0xcc, 0x6f, 0xa2, + 0x85, 0x0e, 0xb0, 0xd5, 0xcd, 0x8a, 0xff, 0xc1, 0x57, 0x20, 0x66, 0xf7, + 0x19, 0x7a, 0x52, 0x5b, 0x46, 0x87, 0x5f, 0xf7, 0x77, 0xe2, 0xab, 0x4e, + 0x4a, 0xce, 0x8f, 0x3f, 0xe6, 0x9f, 0x88, 0x3a, 0x33, 0x65, 0x3c, 0x3a, + 0x41, 0xc3, 0x8e, 0xee, 0x79, 0xe7, 0x2c, 0xb0, 0x3b, 0x93, 0x82, 0xa0, + 0x1a, 0x71, 0x0e, 0xf6, 0x31, 0xc5, 0x6f, 0xc1, 0xa8, 0x32, 0x89, 0x3b, + 0x33, 0x68, 0x53, 0x81, 0x15, 0x70, 0x5e, 0x22, 0xdc, 0x99, 0xc6, 0x88, + 0xf8, 0x11, 0x06, 0x56, 0x1f, 0x80, 0x7e, 0x0b, 0x27, 0x90, 0xfc, 0x97, + 0x76, 0x61, 0xdc, 0x30, 0x5d, 0x34, 0x4e, 0x83, 0x85, 0xce, 0xe2, 0x91, + 0x4d, 0x8d, 0x92, 0x88, 0x26, 0xa0, 0xde, 0x47, 0x82, 0xd2, 0xa8, 0xa5, + 0xe7, 0x27, 0x0c, 0x45, 0x41, 0x85, 0xa1, 0x12, 0xcb, 0x3a, 0x74, 0x53, + 0x93, 0x77, 0xd0, 0x8b, 0x42, 0x8d, 0x00, 0xca, 0x44, 0x67, 0xa0, 0x6a, + 0xbd, 0xcd, 0x4a, 0x3c, 0xfe, 0x6c, 0xa1, 0x48, 0x26, 0x0d, 0x51, 0x54, + 0x59, 0xc9, 0xf9, 0x51, 0x5c, 0xd3, 0x55, 0xf0, 0x72, 0x77, 0xdb, 0x52, + 0xee, 0x0a, 0x5e, 0x8a, 0xf0, 0xbe, 0x9a, 0x37, 0xa0, 0x1b, 0x94, 0xe3, + 0x2d, 0x17, 0xc4, 0xbe, 0x9c, 0xad, 0x9c, 0xd1, 0xc6, 0xbc, 0x36, 0x5c, + 0x3b, 0xe3, 0x2e, 0x66, 0x29, 0x0c, 0x3a, 0x3d, 0xe7, 0xe3, 0xf3, 0x58, + 0x70, 0x3e, 0x59, 0xb2, 0x6c, 0x91, 0x14, 0xfe, 0x9e, 0x5e, 0x5d, 0xb2, + 0x7b, 0x46, 0x66, 0x46, 0x55, 0xe2, 0x78, 0x47, 0xeb, 0xdf, 0x2b, 0xb4, + 0xf2, 0xb2, 0x14, 0xbe, 0x64, 0x9e, 0x17, 0x16, 0x9f, 0xf5, 0x6a, 0xdd, + 0x25, 0xa1, 0x55, 0x6e, 0xb1, 0xfa, 0x09, 0xd0, 0x97, 0x7c, 0x13, 0xde, + 0x1d, 0xd4, 0x94, 0x19, 0xde, 0x8b, 0x4d, 0xe7, 0xee, 0x1f, 0xdf, 0xe5, + 0x3b, 0xdd, 0xbd, 0x13, 0x9c, 0xec, 0xcd, 0xb6, 0xb6, 0xbb, 0x3f, 0xbd, + 0x54, 0xca, 0x47, 0x5c, 0x05, 0x3c, 0x03, 0x30, 0x9d, 0x56, 0xf6, 0xc6, + 0x48, 0x6b, 0x74, 0x49, 0x58, 0xa2, 0xd8, 0x45, 0x42, 0x6f, 0xe4, 0x46, + 0x27, 0x92, 0x83, 0x78, 0x97, 0x55, 0x5b, 0x82, 0xce, 0x2a, 0x08, 0x41, + 0xb9, 0x7a, 0x66, 0x0f, 0x3c, 0x5b, 0xdf, 0x8d, 0x1d, 0x02, 0x11, 0xa4, + 0xa7, 0x0a, 0x80, 0x1e, 0xbb, 0x7a, 0xc9, 0x2f, 0xb9, 0x35, 0xc8, 0xd7, + 0x98, 0x04, 0x29, 0xaa, 0x4b, 0x88, 0x66, 0x73, 0xe4, 0x59, 0xc4, 0x3e, + 0x50, 0xad, 0xe5, 0x64, 0x54, 0xf0, 0x29, 0x38, 0xee, 0xc0, 0x00, 0xc4, + 0x22, 0x16, 0xf2, 0xc5, 0x46, 0x5c, 0xee, 0x9e, 0xf2, 0x9a, 0xe7, 0xfd, + 0x62, 0x50, 0xa2, 0xeb, 0x47, 0x56, 0x4c, 0xe4, 0x75, 0x46, 0xe4, 0xd5, + 0x25, 0xec, 0xe0, 0x35, 0x33, 0x31, 0x34, 0x1b, 0xcb, 0x72, 0x78, 0x1c, + 0x4d, 0x3a, 0x19, 0x2e, 0xc4, 0xb7, 0xa4, 0x80, 0xd2, 0x91, 0xeb, 0x2a, + 0x1d, 0xf2, 0xd1, 0xa3, 0xae, 0xac, 0x41, 0xae, 0xc2, 0x44, 0xd2, 0x3f, + 0xb4, 0x87, 0x8d, 0x69, 0x6c, 0x67, 0xd6, 0x85, 0xee, 0xd6, 0x3b, 0x03, + 0xdc, 0x58, 0x46, 0x07, 0x73, 0xb4, 0xb0, 0x3f, 0x5e, 0xc1, 0x13, 0x2c, + 0x36, 0x58, 0xd0, 0x1c, 0x34, 0x3e, 0x01, 0x88, 0xfa, 0xb1, 0x9a, 0x03, + 0x85, 0x4f, 0x4c, 0xd2, 0xac, 0xd9, 0x12, 0x09, 0xaa, 0x5f, 0x20, 0x06, + 0x1f, 0x0a, 0x44, 0x28, 0x50, 0xd1, 0x8f, 0x51, 0x8a, 0x1d, 0xfa, 0xaa, + 0x46, 0x33, 0xac, 0x0c, 0xb3, 0x10, 0xcf, 0x24, 0x4d, 0x0f, 0xcd, 0xee, + 0xd9, 0x64, 0x4a, 0x1a, 0x84, 0x0f, 0xff, 0x48, 0x8d, 0x79, 0xd4, 0x43, + 0x70, 0x1c, 0x7e, 0x7e, 0x12, 0x43, 0x51, 0x4a, 0x7e, 0x45, 0x9e, 0xa4, + 0x3c, 0x12, 0xbd, 0x95, 0xe9, 0xd6, 0xd4, 0x3f, 0xbf, 0x03, 0xae, 0x9e, + 0x24, 0x1a, 0x36, 0xbd, 0xea, 0x5d, 0x65, 0xff, 0x9f, 0x95, 0x70, 0xda, + 0xb0, 0x53, 0x6a, 0x5f, 0x64, 0x7b, 0xb6, 0x7a, 0x8d, 0xa2, 0xd4, 0x9c, + 0xb1, 0xf9, 0xe6, 0x14, 0x62, 0x3b, 0xe7, 0x5b, 0x40, 0x9d, 0xf4, 0x19, + 0xb5, 0x50, 0xc8, 0xbd, 0x76, 0xd3, 0xbc, 0x0e, 0x6d, 0x62, 0x91, 0x73, + 0x3e, 0x7f, 0xbf, 0xd0, 0xf0, 0x33, 0xf8, 0x6a, 0x9f, 0xa6, 0xad, 0xc3, + 0xa0, 0x8f, 0x45, 0x99, 0x86, 0xa7, 0x49, 0x18, 0x8a, 0xed, 0xf1, 0x7d, + 0x39, 0xf4, 0xb4, 0xf9, 0x82, 0x62, 0xd0, 0xa1, 0xb8, 0x3f, 0xe8, 0x25, + 0xf7, 0xb1, 0x59, 0xce, 0x31, 0xba, 0x1d, 0x0b, 0x1f, 0x3d, 0x6c, 0x8b, + 0xd2, 0xc5, 0x4e, 0x8e, 0xe8, 0x09, 0x9e, 0x1f, 0xf3, 0x67, 0x6f, 0x09, + 0x03, 0x9d, 0xfe, 0x57, 0x6d, 0x9b, 0xce, 0x99, 0x7b, 0x01, 0x04, 0x52, + 0xf5, 0x41, 0x7e, 0x38, 0x56, 0xb8, 0x71, 0x44, 0x43, 0x2c, 0x5e, 0x92, + 0x9d, 0x95, 0xff, 0x0b, 0xf8, 0xfa, 0x89, 0x2c, 0x58, 0xde, 0xc5, 0x4e, + 0x02, 0xe3, 0x82, 0xf7, 0xdc, 0x92, 0xa8, 0x7c, 0x39, 0x32, 0x76, 0x68, + 0x9c, 0x73, 0x75, 0x1f, 0xbc, 0x6b, 0x46, 0x33, 0x5a, 0xdb, 0x94, 0x8c, + 0x76, 0x79, 0x7e, 0x9b, 0xcc, 0x37, 0xeb, 0xed, 0xdc, 0xd5, 0xee, 0x2b, + 0x30, 0x3f, 0x7b, 0x9b, 0xac, 0x38, 0x8f, 0xf1, 0x5e, 0xec, 0xa0, 0x46, + 0x2c, 0xd1, 0x27, 0x19, 0x60, 0xec, 0xe2, 0xa7, 0x45, 0x61, 0x2d, 0xa8, + 0x7e, 0xa9, 0xf8, 0x93, 0xa4, 0x23, 0x3e, 0xd8, 0x9c, 0xcc, 0xb3, 0xee, + 0xc3, 0x1c, 0xfb, 0xbb, 0xad, 0xec, 0x73, 0x66, 0x31, 0x5d, 0x88, 0x9a, + 0xec, 0x84, 0x91, 0x1e, 0x58, 0xdd, 0xb0, 0x01, 0x46, 0x18, 0x43, 0x64, + 0xe2, 0xad, 0xac, 0x5a, 0x63, 0x4c, 0x32, 0x6b, 0xfd, 0xff, 0x66, 0x6d, + 0xb4, 0x66, 0x88, 0xec, 0xfe, 0x23, 0xaa, 0x3a, 0x2a, 0xd5, 0xff, 0xed, + 0x3a, 0x13, 0x9a, 0xae, 0x73, 0xc5, 0x62, 0x32, 0x47, 0x89, 0x19, 0x7f, + 0x2c, 0x88, 0x62, 0x34, 0xc2, 0x90, 0xa9, 0x59, 0x7c, 0x45, 0xdb, 0x98, + 0xaf, 0xf4, 0xba, 0x4e, 0x45, 0x55, 0xfc, 0x70, 0xa9, 0xfd, 0xb4, 0xa3, + 0xd9, 0xa8, 0xfb, 0xe2, 0xe6, 0xf9, 0x60, 0xc1, 0x42, 0x70, 0x3d, 0xa5, + 0x28, 0xcc, 0xd3, 0x54, 0x87, 0xda, 0x93, 0x91, 0x42, 0xa8, 0x8b, 0x62, + 0xf3, 0x4e, 0xb7, 0x86, 0xfa, 0x52, 0x19, 0x69, 0xe3, 0x6c, 0xd1, 0xc3, + 0x23, 0x82, 0xf7, 0x1d, 0xa1, 0x80, 0x92, 0xcd, 0x5e, 0x1a, 0x62, 0x3e, + 0x1b, 0x31, 0x9d, 0x0d, 0xa8, 0x25, 0x3e, 0x83, 0xae, 0x36, 0xce, 0xfd, + 0xac, 0xf7, 0x35, 0x7f, 0x74, 0xf4, 0x66, 0xa3, 0x5f, 0x00, 0xe5, 0x30, + 0xc1, 0x11, 0x70, 0x00, 0xb5, 0xd9, 0xd4, 0x6e, 0x95, 0xc4, 0xbc, 0x5b, + 0x7d, 0x62, 0x6c, 0xd5, 0xc0, 0x1e, 0x81, 0xc0, 0x61, 0x69, 0x13, 0x63, + 0xbc, 0x7f, 0x70, 0x3f, 0x3d, 0x96, 0x18, 0x39, 0xef, 0x51, 0xc6, 0xe9, + 0xcc, 0x59, 0xda, 0xc7, 0x5d, 0xb5, 0x59, 0xb0, 0xf2, 0x99, 0x5a, 0x36, + 0x21, 0x0d, 0xcc, 0x97, 0x16, 0x2b, 0x61, 0x3d, 0x0a, 0xd1, 0x6e, 0x05, + 0x86, 0x42, 0xff, 0xd8, 0xa7, 0x5c, 0x02, 0xcf, 0x90, 0x6b, 0x4e, 0xee, + 0x4e, 0xca, 0xdb, 0xd3, 0xfe, 0x7e, 0x9b, 0xe2, 0xf0, 0xa3, 0x45, 0x6d, + 0xa9, 0x92, 0xba, 0xce, 0xc6, 0x2e, 0x0a, 0xbc, 0xb2, 0x7a, 0x57, 0x07, + 0x33, 0xc2, 0xa7, 0x16, 0x25, 0x06, 0x36, 0x83, 0x35, 0x31, 0x87, 0x18, + 0x83, 0xa3, 0xc2, 0x88, 0x55, 0xcc, 0xe4, 0x84, 0x4c, 0xce, 0xb9, 0xeb, + 0xd5, 0xb2, 0xbe, 0x3d, 0x76, 0x85, 0x10, 0x07, 0x83, 0xfa, 0x1c, 0x42, + 0xbc, 0xa3, 0x4c, 0x29, 0x49, 0xe6, 0xc0, 0x30, 0x59, 0xe0, 0xc6, 0xbe, + 0xa7, 0x48, 0x4a, 0xcf, 0x0e, 0x8e, 0xb7, 0x38, 0xf2, 0xa6, 0x26, 0xd3, + 0x88, 0x06, 0x99, 0x46, 0x19, 0x65, 0x1c, 0x91, 0x8e, 0xae, 0x90, 0x78, + 0x77, 0x7f, 0xe0, 0xc2, 0x51, 0x6f, 0xb6, 0x44, 0x15, 0xf9, 0xc5, 0x8a, + 0x6c, 0x33, 0xd5, 0x90, 0x17, 0xc2, 0xca, 0x4e, 0xe1, 0x1f, 0xef, 0x02, + 0x43, 0x05, 0x3f, 0x1e, 0xb1, 0x13, 0x23, 0x1f, 0xd6, 0xc2, 0xac, 0xc4, + 0x49, 0x7a, 0x86, 0x06, 0x4b, 0xa1, 0x55, 0x6a, 0x75, 0x91, 0x4e, 0x6b, + 0x86, 0x95, 0xa7, 0xbc, 0xdc, 0x64, 0xdb, 0x81, 0xc6, 0xa5, 0x33, 0x38, + 0x98, 0xbb, 0xac, 0x03, 0xf0, 0xba, 0x49, 0xcf, 0x1c, 0xce, 0xe2, 0x3d, + 0xe5, 0x06, 0xbc, 0x5e, 0xd0, 0xf7, 0x1c, 0xbb, 0x52, 0xa1, 0x47, 0x98, + 0x12, 0xef, 0x1c, 0xb9, 0x53, 0xec, 0x67, 0x2c, 0xf0, 0x7d, 0x85, 0x9e, + 0x45, 0x87, 0x00, 0x67, 0x2f, 0xa5, 0x19, 0x9f, 0x3e, 0x20, 0x8c, 0xe9, + 0xfa, 0x8a, 0xd8, 0x02, 0x6e, 0x16, 0xc4, 0x43, 0xff, 0x08, 0x3f, 0xf3, + 0x76, 0x53, 0x95, 0x17, 0x6e, 0x74, 0xfe, 0x7e, 0x87, 0x66, 0xc9, 0xe8, + 0x8d, 0x21, 0xea, 0xd2, 0x4d, 0xc7, 0x9c, 0x5a, 0xef, 0xd5, 0xe1, 0x12, + 0x85, 0x22, 0x40, 0x3c, 0x9d, 0x89, 0x4f, 0x12, 0xb5, 0x01, 0x95, 0x0e, + 0x9b, 0xd3, 0x38, 0x5e, 0x21, 0x5a, 0x4e, 0x7e, 0xce, 0xf7, 0xa6, 0x5a, + 0x63, 0x78, 0x40, 0xba, 0x9f, 0x29, 0xf0, 0x75, 0xb6, 0x8b, 0xd9, 0x4c, + 0xab, 0xb9, 0xf4, 0xe9, 0x1f, 0x39, 0x01, 0xb3, 0xfc, 0x2c, 0xa4, 0x74, + 0xa9, 0xa9, 0x90, 0xed, 0x77, 0xd8, 0x0c, 0x6d, 0x5c, 0x7b, 0xfc, 0xbd, + 0x96, 0x96, 0xcb, 0x9b, 0x9f, 0x88, 0x86, 0x5c, 0x3c, 0x0a, 0xde, 0x28, + 0x7c, 0xf0, 0x91, 0x1c, 0x06, 0x52, 0xbe, 0xad, 0xc8, 0xef, 0xa5, 0xd3, + 0x1e, 0x29, 0xbd, 0x1d, 0xd5, 0xba, 0xf4, 0x83, 0x2d, 0x36, 0x9a, 0x8c, + 0x8d, 0x83, 0xac, 0x3f, 0xea, 0xd2, 0x2e, 0xfb, 0xf1, 0xaa, 0x7a, 0x2e, + 0xce, 0xd3, 0x90, 0x9f, 0x3c, 0x2c, 0xee, 0xed, 0xf8, 0xfc, 0x3c, 0x0e, + 0x5f, 0xd1, 0xda, 0x9c, 0x32, 0x52, 0xcd, 0x09, 0xa1, 0x53, 0x33, 0x37, + 0xe0, 0x37, 0x95, 0xb2, 0x8d, 0x03, 0x46, 0x1f, 0xb5, 0x99, 0x65, 0x54, + 0x61, 0xa2, 0xdc, 0xe9, 0x87, 0x4d, 0x41, 0xdf, 0xd1, 0xb5, 0x2c, 0x7a, + 0x46, 0x08, 0x5e, 0x0f, 0xcc, 0x80, 0x96, 0x52, 0x98, 0xa0, 0x82, 0x52, + 0x6d, 0x62, 0x6f, 0xd9, 0x48, 0xc1, 0x36, 0x0c, 0x5c, 0x7f, 0xad, 0x2c, + 0x27, 0xcf, 0x17, 0xee, 0xfa, 0xca, 0x14, 0xe7, 0x88, 0xc4, 0x20, 0xb2, + 0xa1, 0xd2, 0x66, 0xe8, 0x81, 0xce, 0x35, 0x2b, 0x30, 0x54, 0x16, 0x9e, + 0x42, 0x77, 0x16, 0x3b, 0x84, 0x77, 0x42, 0x71, 0x33, 0xf8, 0x62, 0x9e, + 0xd4, 0x1d, 0x1d, 0xf3, 0x91, 0x60, 0x97, 0xd8, 0x10, 0x29, 0xc8, 0xf9, + 0xfa, 0xca, 0x0a, 0xe9, 0x50, 0xe1, 0xcc, 0xa7, 0xe3, 0x77, 0xc2, 0x93, + 0x68, 0x50, 0x1a, 0x98, 0xd7, 0x68, 0x40, 0x80, 0x12, 0x64, 0xa7, 0x1d, + 0xb4, 0x52, 0x85, 0x7b, 0x0e, 0x85, 0x0a, 0x59, 0x6a, 0xc8, 0xe4, 0x4b, + 0xff, 0xd7, 0x0d, 0x7d, 0x9e, 0xef, 0x07, 0x2f, 0x6d, 0x46, 0x05, 0xf9, + 0x05, 0xb1, 0x97, 0x94, 0x23, 0xc5, 0x2a, 0x99, 0xcc, 0x9c, 0xc2, 0x82, + 0x97, 0xbc, 0x24, 0x9b, 0xe4, 0xf2, 0xb3, 0x12, 0x84, 0xa0, 0x2a, 0xc4, + 0x7d, 0x29, 0x4d, 0xa4, 0x97, 0xd0, 0x85, 0xa6, 0x39, 0x18, 0xd2, 0xfb, + 0xa7, 0x08, 0x53, 0x75, 0x6b, 0xbd, 0xe3, 0x98, 0x4c, 0x94, 0xdd, 0xd4, + 0x86, 0x94, 0xc2, 0x6a, 0x14, 0x23, 0xdd, 0x69, 0xae, 0x53, 0xec, 0x83, + 0x58, 0x8e, 0x87, 0x7b, 0xf1, 0xcf, 0xff, 0x34, 0xda, 0x39, 0x67, 0xba, + 0x90, 0xc5, 0xec, 0xe0, 0xb3, 0xad, 0xad, 0x3d, 0x4c, 0x8e, 0x3f, 0x08, + 0x62, 0x80, 0x5b, 0x2d, 0xf8, 0xe1, 0x67, 0x61, 0x79, 0xf5, 0xc9, 0xbe, + 0x74, 0x1b, 0x72, 0x02, 0x56, 0xc6, 0xf8, 0xd5, 0x87, 0x3a, 0x08, 0x7b, + 0x35, 0x8f, 0xdf, 0xdf, 0x87, 0x3e, 0x09, 0xf7, 0xd2, 0x74, 0xbb, 0xec, + 0x8c, 0x49, 0x0c, 0xb5, 0x3a, 0x6b, 0x33, 0x43, 0x52, 0xe2, 0x2f, 0x71, + 0x3e, 0x6f, 0x59, 0x52, 0x50, 0x8f, 0xdb, 0xa6, 0x52, 0xa7, 0x5d, 0xda, + 0x16, 0x71, 0xb2, 0x52, 0xd7, 0x3e, 0x2d, 0xf6, 0x98, 0x53, 0x0f, 0x8f, + 0xc1, 0x79, 0xd0, 0xcf, 0xe0, 0xc8, 0x22, 0x27, 0x41, 0x14, 0xe8, 0xb8, + 0xed, 0x65, 0x3c, 0xaa, 0x11, 0x72, 0x41, 0xa8, 0xd8, 0x0b, 0x35, 0x81, + 0xec, 0xa6, 0x12, 0x30, 0x23, 0x0b, 0x71, 0x7a, 0x28, 0xd9, 0x01, 0x82, + 0x35, 0xd1, 0x64, 0x6d, 0xf3, 0x63, 0x69, 0x78, 0xb4, 0x93, 0x1e, 0x05, + 0xc9, 0xb3, 0xbc, 0xb6, 0xc4, 0x5e, 0xb6, 0x2a, 0x6e, 0xec, 0x91, 0x4a, + 0x5c, 0xa2, 0x5c, 0xea, 0x2b, 0xe3, 0x33, 0x1a, 0xb3, 0x70, 0xd5, 0x39, + 0x77, 0x3e, 0xa2, 0x96, 0xd5, 0x10, 0x75, 0x8a, 0x91, 0xc6, 0xbc, 0xb6, + 0x86, 0xa6, 0x8f, 0xd3, 0x50, 0x09, 0xa3, 0x9a, 0x1f, 0xd0, 0xd7, 0xd7, + 0x23, 0xa0, 0x32, 0xd0, 0x69, 0x33, 0x2f, 0x18, 0xf2, 0x6f, 0xe2, 0xbc, + 0x2f, 0x7f, 0xf5, 0x46, 0x81, 0x2e, 0xad, 0x14, 0xc9, 0x57, 0x10, 0xa4, + 0x71, 0xa9, 0xa4, 0x05, 0x50, 0xcb, 0x93, 0xc7, 0x53, 0x84, 0x68, 0xa5, + 0x7c, 0x65, 0xc0, 0xe0, 0x37, 0xd6, 0xc3, 0xbb, 0x36, 0xef, 0x22, 0x9e, + 0x09, 0x32, 0xa5, 0xa6, 0x73, 0x61, 0xb6, 0x3c, 0x5a, 0xbe, 0x2f, 0x63, + 0x01, 0x35, 0xfe, 0xd8, 0x98, 0xd5, 0x7e, 0xfd, 0x68, 0xd8, 0x96, 0x51, + 0x6e, 0x3a, 0x17, 0x90, 0x16, 0xeb, 0x03, 0xfa, 0x0a, 0x83, 0x1a, 0xc9, + 0x48, 0x14, 0x31, 0x32, 0x07, 0x7d, 0xa8, 0xa8, 0x64, 0xd8, 0xba, 0xcf, + 0x87, 0xc5, 0x0e, 0xc3, 0x1c, 0x5b, 0xfe, 0x31, 0x98, 0xea, 0x25, 0x29, + 0x9c, 0x77, 0xf2, 0x9f, 0x5e, 0x16, 0x11, 0x6b, 0x29, 0x08, 0xab, 0xb0, + 0x57, 0xd8, 0x3d, 0x85, 0xdc, 0x3b, 0x69, 0xea, 0xd5, 0xe6, 0x90, 0xfa, + 0x95, 0x8d, 0xcc, 0x3c, 0x2d, 0x86, 0x07, 0xc6, 0x7e, 0x8d, 0xc4, 0x7a, + 0x3a, 0xcd, 0x61, 0xa4, 0x1f, 0xd9, 0x6f, 0x07, 0xa3, 0x45, 0xe8, 0x41, + 0xed, 0x51, 0x14, 0xe4, 0x3d, 0x20, 0x3b, 0x11, 0x9e, 0x93, 0xc3, 0x2e, + 0xcd, 0x29, 0x85, 0xf0, 0x61, 0x68, 0x8e, 0x19, 0xdc, 0x20, 0x0a, 0xbd, + 0xc0, 0x15, 0x90, 0x08, 0x96, 0xcf, 0x9b, 0xf3, 0xb5, 0x7b, 0xe4, 0x9a, + 0x97, 0x22, 0x93, 0x40, 0xd4, 0xde, 0x7a, 0x6e, 0x6b, 0xc4, 0x16, 0x9e, + 0x1c, 0x98, 0x9b, 0x83, 0x6e, 0x4d, 0xde, 0x11, 0x4f, 0x22, 0xed, 0x2d, + 0xe1, 0xb3, 0xfa, 0x86, 0xb0, 0xd2, 0x53, 0xd2, 0x34, 0x8a, 0x58, 0xdc, + 0x8c, 0xd9, 0x60, 0xd3, 0x46, 0x0a, 0xde, 0x48, 0xa3, 0xda, 0x5b, 0x74, + 0x3e, 0x4c, 0x51, 0xa6, 0x02, 0x20, 0xc6, 0x0d, 0xdb, 0x13, 0x42, 0xad, + 0xc6, 0x90, 0xb1, 0xe0, 0xb0, 0xac, 0xdc, 0xa7, 0x48, 0xf8, 0x2d, 0x8f, + 0xd7, 0xd9, 0x10, 0xeb, 0xd8, 0xdb, 0xf0, 0x53, 0x67, 0xa9, 0x03, 0x3e, + 0x97, 0xbf, 0xe6, 0xc3, 0xa8, 0x87, 0x3a, 0x91, 0xb8, 0xcf, 0x88, 0x5b, + 0x0d, 0x06, 0xe1, 0xe2, 0x39, 0x74, 0xc8, 0x59, 0xe0, 0x90, 0x9f, 0xc9, + 0x0a, 0x74, 0xa3, 0xb2, 0xae, 0x69, 0x79, 0xfa, 0x0d, 0xf2, 0xee, 0xde, + 0xec, 0x88, 0xbf, 0x09, 0x54, 0xd6, 0xbe, 0xbb, 0x25, 0x91, 0xe4, 0x66, + 0xd2, 0x08, 0x78, 0xda, 0x9d, 0x07, 0xc3, 0x0b, 0x3f, 0x1a, 0xd9, 0xf4, + 0xb2, 0x2d, 0x69, 0x74, 0xb1, 0x78, 0x5f, 0xc1, 0xaf, 0x7f, 0x6d, 0x17, + 0xfc, 0x2c, 0x67, 0x62, 0xce, 0xb4, 0x41, 0x6e, 0x21, 0x4b, 0x5c, 0x77, + 0xa1, 0x1f, 0xfe, 0xe6, 0x28, 0xc8, 0x52, 0xd1, 0x8e, 0x66, 0x88, 0x65, + 0x0c, 0x58, 0xec, 0x1c, 0x71, 0x4c, 0x8a, 0xc0, 0xef, 0x3e, 0x34, 0xf7, + 0x90, 0x67, 0x28, 0x16, 0x20, 0x3a, 0x2c, 0x3f, 0x51, 0x53, 0x15, 0x1c, + 0x6c, 0x75, 0x0e, 0xe1, 0xb4, 0xf3, 0x7f, 0x60, 0x3a, 0x81, 0x34, 0x82, + 0x51, 0x5e, 0x75, 0xb0, 0x5c, 0x37, 0x87, 0x2d, 0xd5, 0xc5, 0x2c, 0xab, + 0x33, 0x8a, 0x60, 0x49, 0x2c, 0xde, 0x90, 0x12, 0x11, 0x1f, 0x4b, 0x27, + 0x15, 0x92, 0xa2, 0xf1, 0x1a, 0xde, 0x35, 0x34, 0x4d, 0x52, 0xcd, 0xc0, + 0x71, 0x46, 0x7f, 0x3e, 0x21, 0x92, 0x5f, 0xc8, 0x25, 0xd4, 0x2c, 0xf4, + 0xd9, 0x38, 0xde, 0xa5, 0xae, 0x83, 0xe3, 0x50, 0x9b, 0x1b, 0xad, 0x4b, + 0xd8, 0x3f, 0x0a, 0x23, 0x40, 0x1e, 0x46, 0x7a, 0x71, 0x06, 0xac, 0x9e, + 0x06, 0xb8, 0x96, 0xef, 0x07, 0xef, 0x38, 0xe9, 0x79, 0xaa, 0x64, 0x44, + 0xa9, 0xa3, 0xc5, 0x1d, 0x5d, 0xd3, 0xa7, 0x01, 0xef, 0xf6, 0x3b, 0x15, + 0x00, 0x0c, 0xf7, 0x59, 0x4a, 0x1c, 0x12, 0x20, 0x89, 0xa8, 0x4e, 0x7b, + 0xf8, 0x9d, 0x02, 0xa6, 0x5e, 0x19, 0x7e, 0xb8, 0x5f, 0x46, 0xd9, 0xb1, + 0xbe, 0x25, 0x2c, 0x3c, 0xe7, 0x5d, 0x3b, 0x3f, 0x6f, 0x6e, 0x94, 0x83, + 0xc3, 0x8e, 0x85, 0x65, 0xff, 0xe9, 0x8e, 0x32, 0xcc, 0x68, 0x51, 0x14, + 0xbf, 0x94, 0x21, 0x3f, 0x85, 0xa8, 0x76, 0x44, 0xe6, 0xca, 0x20, 0x84, + 0xec, 0x83, 0x84, 0x64, 0xfb, 0x80, 0x01, 0x73, 0x76, 0x21, 0xd3, 0xf0, + 0x7b, 0x74, 0x5c, 0xbf, 0x71, 0xe6, 0x34, 0xff, 0x58, 0xe8, 0x6f, 0x88, + 0xa6, 0xad, 0xcf, 0x93, 0x2a, 0xc5, 0xc5, 0x23, 0x32, 0xc8, 0xec, 0xbd, + 0xf9, 0x54, 0x3d, 0xda, 0xe4, 0x81, 0x74, 0x94, 0xbf, 0x36, 0x72, 0x11, + 0xf0, 0x8a, 0x8f, 0x1b, 0x55, 0x47, 0x70, 0x7d, 0x61, 0xf0, 0x7b, 0x11, + 0x56, 0xdb, 0xbc, 0xe5, 0x72, 0xf2, 0xbd, 0x0b, 0xa0, 0x80, 0x03, 0x1a, + 0xc6, 0xe9, 0xfc, 0xcd, 0xde, 0x42, 0xae, 0x1a, 0x7d, 0x90, 0x5d, 0x21, + 0x5b, 0x3d, 0x69, 0x6f, 0x42, 0x42, 0xf2, 0x8a, 0xc8, 0xfc, 0xb9, 0xa9, + 0xdf, 0x18, 0xc4, 0x97, 0x91, 0x21, 0x28, 0xfd, 0x82, 0x8a, 0xe7, 0xac, + 0xe5, 0x5d, 0x33, 0x7b, 0x78, 0x0a, 0x48, 0x43, 0xfe, 0xfe, 0xcf, 0x09, + 0x5f, 0xed, 0x18, 0x33, 0x0c, 0xab, 0x8a, 0x5d, 0x63, 0xd5, 0x43, 0x0b, + 0xde, 0x75, 0x56, 0xef, 0x11, 0x05, 0x8c, 0xbb, 0xc0, 0x10, 0x4e, 0x85, + 0x70, 0xe1, 0x7e, 0x62, 0xb6, 0x3a, 0x84, 0x80, 0x17, 0xab, 0x38, 0x59, + 0x0b, 0xe2, 0xb1, 0x31, 0xb8, 0xb5, 0xf5, 0xad, 0xf6, 0xbf, 0x5b, 0xfb, + 0x69, 0xc8, 0xb3, 0xce, 0x65, 0xd4, 0x8e, 0x04, 0xc5, 0xc4, 0x09, 0xba, + 0x36, 0xc9, 0x90, 0xe0, 0xc2, 0x21, 0x3a, 0x94, 0x83, 0xa5, 0xd1, 0xb2, + 0xe1, 0xae, 0x6a, 0x28, 0x22, 0x59, 0x79, 0x72, 0x82, 0x42, 0x89, 0x42, + 0x9c, 0xc3, 0xdf, 0x8d, 0x15, 0x22, 0x14, 0xb3, 0xfd, 0x2a, 0x85, 0xbe, + 0xd3, 0x12, 0xa5, 0x3b, 0x0c, 0x99, 0xb2, 0xe5, 0x43, 0x8d, 0xd7, 0xc0, + 0xa1, 0xb6, 0xb2, 0xae, 0x42, 0x4a, 0xc0, 0xe5, 0x09, 0xa2, 0xf6, 0xa4, + 0xbc, 0x01, 0xee, 0x94, 0xd2, 0x0b, 0xeb, 0x28, 0x80, 0xc9, 0x7a, 0x07, + 0xd7, 0x4b, 0xee, 0x01, 0x10, 0x48, 0xcc, 0xc6, 0x03, 0x99, 0x9d, 0x67, + 0x2a, 0xbd, 0xa0, 0x6f, 0x51, 0xa4, 0x75, 0x50, 0xe1, 0x84, 0x8e, 0xda, + 0x7b, 0x5e, 0x9e, 0x78, 0x18, 0x2a, 0x6b, 0xfa, 0xef, 0x87, 0x81, 0xe9, + 0x48, 0x3f, 0x29, 0x2d, 0xfb, 0x15, 0xd2, 0x15, 0xb5, 0x5c, 0xed, 0x45, + 0x48, 0x30, 0xec, 0x00, 0x55, 0x15, 0x13, 0xc7, 0x11, 0xc4, 0x29, 0xef, + 0x0f, 0xa8, 0xa6, 0xef, 0x19, 0x41, 0xc2, 0xb6, 0x11, 0xdc, 0xe8, 0xf4, + 0xa7, 0x03, 0x80, 0x2d, 0x92, 0xad, 0x7e, 0x7e, 0x8a, 0x71, 0xa4, 0x6c, + 0x16, 0xb9, 0x84, 0xf5, 0x8d, 0x94, 0xc5, 0xd5, 0x82, 0x29, 0x42, 0x22, + 0x1f, 0x06, 0xca, 0xdd, 0xbf, 0x74, 0x0f, 0x14, 0x79, 0x26, 0x9c, 0x79, + 0x30, 0xcb, 0x01, 0x02, 0x76, 0x22, 0x4f, 0x54, 0xff, 0x49, 0xa3, 0x03, + 0x35, 0x23, 0x45, 0x91, 0xac, 0xed, 0x13, 0x31, 0xa4, 0x4e, 0x51, 0xe8, + 0x9c, 0x5b, 0xe4, 0xcf, 0x41, 0xd3, 0xa0, 0x86, 0x7f, 0x3a, 0x4d, 0xaf, + 0xa7, 0x49, 0x63, 0x47, 0x86, 0x08, 0x88, 0xcf, 0x01, 0x7a, 0xc4, 0xf5, + 0x29, 0x67, 0x8a, 0xd4, 0xdd, 0x6a, 0x6d, 0x81, 0xb8, 0x29, 0x9d, 0x7c, + 0x32, 0x4e, 0x8f, 0x0c, 0x9f, 0x8c, 0x7e, 0x76, 0xa3, 0xd4, 0x32, 0x80, + 0xd0, 0x79, 0x7d, 0x56, 0x99, 0x6d, 0x0b, 0x88, 0xfc, 0x98, 0xdb, 0xaf, + 0x13, 0xf3, 0xb2, 0x20, 0x3f, 0x19, 0xe1, 0x83, 0x70, 0xd2, 0x26, 0xd0, + 0xd2, 0xad, 0x11, 0xeb, 0x3b, 0x31, 0x03, 0x55, 0x62, 0xca, 0xb5, 0x87, + 0x31, 0x7a, 0x11, 0x4c, 0xf2, 0xc3, 0xc2, 0x1c, 0x42, 0x94, 0x7b, 0xe6, + 0x29, 0x86, 0x70, 0x8e, 0x51, 0x4a, 0xa3, 0xf2, 0xf0, 0xed, 0xa1, 0xc6, + 0x18, 0xff, 0xf2, 0xff, 0xe0, 0x07, 0x85, 0xf1, 0x93, 0x5a, 0x83, 0x1c, + 0x4c, 0xa9, 0x9b, 0xc5, 0x0c, 0xc4, 0xf0, 0xde, 0x71, 0x93, 0x78, 0xd1, + 0x3b, 0xcc, 0x5b, 0x51, 0x1f, 0xd7, 0x21, 0x12, 0x57, 0xd5, 0x2a, 0xea, + 0x64, 0x08, 0x0e, 0xf0, 0x3d, 0x42, 0xe7, 0xdf, 0xc8, 0xea, 0x42, 0x2b, + 0x41, 0x55, 0x85, 0xb8, 0x54, 0xa4, 0xc9, 0x3f, 0xce, 0xfc, 0x1a, 0xde, + 0x73, 0x08, 0xaa, 0x09, 0x25, 0x08, 0xa0, 0xdc, 0x64, 0xb7, 0xe7, 0xcc, + 0xde, 0x85, 0xa6, 0xc3, 0xe9, 0xe1, 0x43, 0x71, 0x86, 0x05, 0x55, 0x86, + 0x47, 0xf8, 0x71, 0xbd, 0xf5, 0xd7, 0x38, 0x64, 0x7f, 0x71, 0x63, 0xe1, + 0x22, 0x39, 0x99, 0xc3, 0xdf, 0x27, 0x5d, 0xdd, 0xd0, 0x57, 0x99, 0xd5, + 0x97, 0xcd, 0xd4, 0x2e, 0xc1, 0x25, 0x3d, 0x2e, 0x03, 0x0b, 0x04, 0x20, + 0x70, 0xec, 0x46, 0x6c, 0x4b, 0x55, 0x16, 0x02, 0x00, 0x71, 0xfd, 0x8a, + 0xa0, 0x1e, 0x5f, 0x41, 0xe6, 0x96, 0x58, 0xbe, 0x02, 0x73, 0x91, 0x71, + 0xb2, 0x7e, 0xc4, 0xcd, 0xce, 0xa5, 0x26, 0xee, 0xff, 0x8c, 0x9a, 0x4c, + 0xf4, 0x0a, 0x89, 0xba, 0x14, 0x6e, 0x06, 0x86, 0xb0, 0xba, 0x41, 0xdd, + 0x27, 0xf8, 0xc3, 0x46, 0x4f, 0x39, 0xac, 0x2c, 0x8a, 0x69, 0x09, 0xb7, + 0x36, 0x0f, 0xe0, 0x8d, 0x31, 0x0f, 0xc3, 0xee, 0x3a, 0x6a, 0x9e, 0x96, + 0x91, 0xf5, 0x6a, 0x12, 0x98, 0x5a, 0xc3, 0xf3, 0xb8, 0x9b, 0x07, 0xdb, + 0x8e, 0x2a, 0xb0, 0x91, 0x86, 0xb5, 0xc7, 0xe9, 0x06, 0xe1, 0x4e, 0x83, + 0x28, 0x3a, 0x0e, 0x67, 0xe5, 0x7e, 0x88, 0x2a, 0x31, 0xd2, 0xfe, 0xf6, + 0x19, 0x3d, 0x09, 0xd1, 0xef, 0x5d, 0xe1, 0x15, 0x2d, 0xb4, 0xec, 0x23, + 0xc2, 0x0c, 0x7a, 0xbf, 0xd3, 0x6f, 0xf7, 0x8a, 0x3b, 0x3a, 0x0f, 0x20, + 0xc4, 0x78, 0xbe, 0x46, 0x30, 0x0f, 0xc2, 0xd0, 0x8c, 0x23, 0xb7, 0xfa, + 0x3c, 0x19, 0x35, 0x53, 0x5f, 0xf9, 0x94, 0xf5, 0x23, 0xbe, 0xb3, 0x56, + 0x42, 0xa1, 0x27, 0xff, 0xac, 0xbf, 0x72, 0x7e, 0x89, 0xbe, 0xb9, 0x6d, + 0x2d, 0xc4, 0x3f, 0x6c, 0x7f, 0xc4, 0x7e, 0x01, 0x09, 0xc8, 0x35, 0x80, + 0x99, 0x8f, 0x1c, 0x43, 0xd3, 0xb2, 0x4a, 0xb7, 0x08, 0x06, 0x63, 0xcd, + 0x8a, 0x5e, 0x64, 0xa2, 0x93, 0xa5, 0x15, 0xa0, 0x38, 0xa0, 0xf2, 0x1c, + 0xab, 0xe1, 0x2d, 0x19, 0x30, 0xee, 0x9b, 0x87, 0x42, 0x54, 0xfb, 0xcc, + 0xfe, 0x2a, 0xcd, 0x54, 0xf5, 0xeb, 0x52, 0x6b, 0xd4, 0x1d, 0xa3, 0x7c, + 0xec, 0xf2, 0x56, 0x51, 0x54, 0xab, 0x66, 0xb0, 0x73, 0x49, 0x3e, 0xc4, + 0x89, 0xac, 0xb0, 0xc1, 0x41, 0x6f, 0x19, 0xd6, 0x41, 0xbd, 0xc2, 0xe2, + 0x1a, 0x56, 0xb3, 0x01, 0xc9, 0xdf, 0x46, 0xe7, 0xa1, 0x42, 0xfa, 0x1c, + 0x18, 0x86, 0xe2, 0x07, 0xe4, 0xfe, 0x19, 0x03, 0x7d, 0xc4, 0x51, 0x78, + 0x29, 0x68, 0x73, 0x70, 0x82, 0x98, 0x34, 0x2e, 0x41, 0x59, 0xd5, 0x20, + 0x36, 0xe3, 0xe5, 0x2c, 0xbe, 0x76, 0x23, 0x5d, 0xb1, 0xf0, 0xda, 0xee, + 0x65, 0x54, 0xd9, 0xa1, 0x77, 0x6e, 0xd8, 0x56, 0xcb, 0x6a, 0x35, 0xb5, + 0xaa, 0x97, 0x22, 0x28, 0x4d, 0x74, 0x13, 0x96, 0x59, 0x3d, 0x3a, 0xe2, + 0x26, 0xde, 0xd3, 0xc7, 0xed, 0x97, 0x98, 0xa8, 0x4a, 0x6b, 0x4b, 0xd1, + 0x52, 0xca, 0x84, 0xd6, 0x19, 0x7a, 0x6c, 0x0d, 0xb4, 0x28, 0x4f, 0xb1, + 0xa2, 0xcc, 0x07, 0x08, 0x57, 0xc9, 0x32, 0xd4, 0xe0, 0xef, 0x96, 0x9a, + 0x31, 0x1e, 0x68, 0x1d, 0x7b, 0x57, 0x26, 0x62, 0xa4, 0x26, 0xaf, 0xc7, + 0xd0, 0xab, 0xb6, 0x9e, 0x00, 0x6d, 0xfe, 0x29, 0x30, 0x53, 0xcd, 0xb8, + 0x4e, 0x30, 0x4e, 0xa5, 0xcc, 0xf6, 0xab, 0xca, 0x4d, 0x74, 0x40, 0xc2, + 0xb4, 0xfb, 0x3f, 0x75, 0x0a, 0x9d, 0x88, 0xa3, 0xb0, 0x5b, 0x4e, 0x88, + 0x50, 0x90, 0xcb, 0x5c, 0xcd, 0xc7, 0xff, 0x75, 0x97, 0xc4, 0x1b, 0xe9, + 0x03, 0x8a, 0xa7, 0x62, 0x32, 0x98, 0x60, 0x39, 0x56, 0xe5, 0x25, 0xed, + 0xba, 0x58, 0x67, 0xa3, 0xe8, 0x23, 0xd1, 0x55, 0xb3, 0xa5, 0xc0, 0xc9, + 0x75, 0x14, 0x91, 0xe6, 0x7d, 0x0e, 0xe3, 0xac, 0xc8, 0x6b, 0xa7, 0xdb, + 0x36, 0xe8, 0x44, 0x92, 0x72, 0xf2, 0x6d, 0x10, 0xeb, 0xd0, 0x7a, 0xdd, + 0x00, 0x9b, 0xf8, 0x65, 0xaa, 0xef, 0xed, 0xfb, 0x84, 0x5f, 0xfb, 0xd8, + 0xe9, 0xa8, 0x71, 0xab, 0x20, 0x98, 0x4f, 0x21, 0x7d, 0x33, 0xe2, 0xb1, + 0x3f, 0x95, 0x9c, 0x28, 0xf5, 0xd5, 0x83, 0x01, 0xe9, 0x71, 0x68, 0xa9, + 0x3d, 0x9e, 0x49, 0xfb, 0x6c, 0x83, 0x5f, 0x48, 0x9d, 0x91, 0x00, 0xab, + 0x54, 0x17, 0x11, 0x5b, 0x9d, 0x0a, 0x17, 0x8e, 0x3a, 0xbc, 0xd5, 0x33, + 0xcd, 0x2a, 0x5b, 0x14, 0x39, 0xe4, 0x30, 0x45, 0xde, 0x6e, 0xde, 0x92, + 0x7f, 0xb5, 0x91, 0x5d, 0x5b, 0xe4, 0x18, 0x17, 0x7c, 0x22, 0x1e, 0x2d, + 0x97, 0x8b, 0x6f, 0xe0, 0x54, 0x2e, 0x25, 0xbc, 0x5f, 0xef, 0x27, 0x1b, + 0x95, 0x71, 0xcc, 0x29, 0x96, 0x30, 0x82, 0xb1, 0x99, 0x98, 0x28, 0x36, + 0x5f, 0xd6, 0xf9, 0x13, 0xb3, 0x3d, 0x14, 0x91, 0x8a, 0x2f, 0xbf, 0x6e, + 0x8c, 0x57, 0xf6, 0x8e, 0x32, 0xf2, 0xd3, 0xa5, 0x1b, 0x2b, 0xba, 0xc8, + 0x0d, 0xa4, 0xd3, 0xc2, 0x16, 0x1f, 0x5f, 0xb6, 0x89, 0x77, 0xa9, 0xf3, + 0x7b, 0xb8, 0x11, 0x23, 0x41, 0xd6, 0xe0, 0x47, 0x3c, 0x94, 0xe0, 0xed, + 0xa9, 0xb1, 0x0e, 0x90, 0x38, 0xdd, 0x60, 0xcd, 0x75, 0x00, 0x36, 0x3a, + 0x42, 0xbb, 0xfd, 0xd7, 0xc6, 0x16, 0x38, 0xb4, 0xc0, 0x1d, 0xb6, 0x46, + 0x5c, 0x2f, 0x70, 0x95, 0x8d, 0x74, 0x68, 0xb2, 0xb5, 0xae, 0x73, 0x22, + 0xa1, 0xca, 0x5d, 0xd4, 0x28, 0x1a, 0xd2, 0x19, 0x1c, 0x43, 0x5e, 0x12, + 0x16, 0x15, 0xb4, 0x97, 0x64, 0x10, 0x07, 0x48, 0xf8, 0xe3, 0xfb, 0x3e, + 0xa5, 0x05, 0xcd, 0xc1, 0x29, 0xf0, 0x67, 0xb7, 0x24, 0x02, 0xac, 0x76, + 0x91, 0x64, 0x63, 0x46, 0xfb, 0xfd, 0xaa, 0x5b, 0x3f, 0xeb, 0xe0, 0xb2, + 0x5a, 0x8d, 0xde, 0xdc, 0x92, 0x0c, 0x1e, 0xfc, 0x82, 0x55, 0xc7, 0x8a, + 0xe3, 0x28, 0x57, 0xfe, 0x10, 0xe1, 0xa3, 0x5a, 0x9e, 0x67, 0x86, 0xf4, + 0xa5, 0xf5, 0xa0, 0xbd, 0xa4, 0x3c, 0xda, 0xf3, 0x83, 0x27, 0x2f, 0x55, + 0x73, 0xb6, 0x74, 0x3e, 0xd3, 0xc9, 0x84, 0x1d, 0xff, 0x61, 0x01, 0x56, + 0x30, 0x2a, 0x23, 0x57, 0xbc, 0x88, 0xa7, 0x2f, 0x6f, 0x95, 0x91, 0x4e, + 0x5b, 0x41, 0xd9, 0x95, 0x1f, 0x09, 0x95, 0x79, 0x36, 0xe3, 0x7f, 0xbd, + 0x4b, 0x09, 0x4e, 0x7f, 0x6a, 0x58, 0x6e, 0xd0, 0x60, 0xaf, 0xf1, 0x8f, + 0x4c, 0xc5, 0x5a, 0x5c, 0xb7, 0x74, 0x83, 0x3c, 0xb3, 0x7e, 0xdc, 0x76, + 0x89, 0xa5, 0xca, 0xd7, 0x75, 0x35, 0xb2, 0x4c, 0x0a, 0x67, 0x2b, 0x7a, + 0xe8, 0xac, 0x9e, 0x26, 0xa3, 0xae, 0x87, 0x66, 0x12, 0x4e, 0x74, 0xc8, + 0xd8, 0x6d, 0x89, 0x9c, 0x34, 0x63, 0x61, 0x33, 0x1b, 0x6a, 0x78, 0x7f, + 0x2f, 0xa7, 0x9b, 0xe7, 0x42, 0x0d, 0xcb, 0xc9, 0xf0, 0xa6, 0xb5, 0x38, + 0x66, 0x80, 0xca, 0x7a, 0xa9, 0xe4, 0x93, 0xe3, 0xfc, 0x7d, 0x38, 0x7d, + 0x7a, 0x2c, 0x03, 0xb4, 0x35, 0xde, 0x1b, 0x2e, 0x29, 0x24, 0x40, 0x93, + 0x6c, 0x52, 0x21, 0xd6, 0x70, 0x88, 0xfd, 0xc7, 0x5c, 0x94, 0x95, 0xc0, + 0x03, 0xce, 0x1b, 0xb3, 0x0e, 0x87, 0xac, 0xa0, 0x88, 0xcd, 0x20, 0x3d, + 0x88, 0x6f, 0xac, 0x29, 0x2e, 0xcc, 0x7d, 0xa7, 0x09, 0x16, 0xc0, 0xcc, + 0x55, 0x43, 0x19, 0xdc, 0x5e, 0xc4, 0xe5, 0x7c, 0xfb, 0x50, 0x01, 0x41, + 0xe1, 0x70, 0x84, 0x3e, 0x60, 0x88, 0x05, 0x27, 0x4b, 0x6c, 0x59, 0x9a, + 0x01, 0x50, 0xec, 0x74, 0x6a, 0x98, 0x57, 0xfe, 0xf5, 0x63, 0xc3, 0x60, + 0x55, 0x23, 0x33, 0xf9, 0x2d, 0xf0, 0x68, 0xff, 0xad, 0x61, 0xdb, 0x5e, + 0xdb, 0x0c, 0x54, 0x68, 0x8c, 0x4b, 0x64, 0x94, 0x3c, 0xa8, 0xb1, 0x31, + 0x61, 0xf3, 0xb3, 0xed, 0x8f, 0xd5, 0x07, 0x27, 0xbf, 0xa3, 0xa2, 0x42, + 0x4a, 0xa1, 0x5e, 0xc9, 0xb3, 0x9a, 0x0f, 0xbb, 0xf7, 0xc7, 0x4d, 0x0b, + 0xee, 0xbd, 0xce, 0x9e, 0x8c, 0x14, 0x7e, 0x06, 0x6e, 0x6d, 0x9b, 0xdd, + 0x22, 0xc6, 0xc2, 0x62, 0xa5, 0x45, 0xc1, 0xe1, 0x97, 0xe2, 0x50, 0x25, + 0xcc, 0x9b, 0xc4, 0x5d, 0x2d, 0x45, 0x10, 0xad, 0xa8, 0x4f, 0x27, 0xc3, + 0x1a, 0x2c, 0xef, 0x38, 0x2d, 0xa7, 0xaf, 0xe5, 0x23, 0x7a, 0x8f, 0xbf, + 0x9c, 0xd0, 0xb6, 0x31, 0x5c, 0xaa, 0xd2, 0x8c, 0xd8, 0x91, 0x00, 0xa1, + 0x8b, 0x4d, 0x3e, 0x27, 0x22, 0x6c, 0x0f, 0x64, 0x95, 0x89, 0xa6, 0x29, + 0x90, 0xf9, 0xa9, 0x24, 0x24, 0xb8, 0x71, 0x56, 0x7a, 0xc5, 0xa9, 0x26, + 0x9f, 0xf6, 0x2a, 0xa6, 0xf1, 0xca, 0x2a, 0x17, 0x14, 0x8c, 0x8d, 0xf2, + 0x44, 0x7d, 0x49, 0x4e, 0x9b, 0x4f, 0xef, 0x72, 0x7e, 0xe8, 0x0f, 0x45, + 0xb3, 0x3d, 0x61, 0xf5, 0x9d, 0x3f, 0x9a, 0xe3, 0x93, 0xdd, 0x3d, 0x02, + 0x84, 0x7d, 0xd4, 0x84, 0xa8, 0x23, 0xe9, 0x43, 0xb6, 0x66, 0xf2, 0xb7, + 0x35, 0xcf, 0xa3, 0x2f, 0xbe, 0x48, 0x0e, 0xaa, 0xfe, 0xe9, 0x7e, 0xb0, + 0x4d, 0xb3, 0x6b, 0x69, 0xdc, 0xef, 0x20, 0xec, 0xce, 0x6c, 0xad, 0x7a, + 0x20, 0x35, 0xf2, 0xfd, 0x09, 0xe1, 0xdb, 0xca, 0x2a, 0x55, 0xf7, 0x60, + 0xca, 0xf3, 0x85, 0x12, 0xe6, 0x05, 0x4f, 0xc8, 0x6e, 0x76, 0xda, 0x5f, + 0x45, 0x1e, 0xed, 0xdf, 0x57, 0x4c, 0xeb, 0x7e, 0x28, 0xf7, 0x39, 0xc4, + 0xd0, 0x10, 0x32, 0xa9, 0xcc, 0x25, 0xd9, 0x0b, 0x8c, 0x8a, 0xf6, 0x6c, + 0x84, 0xde, 0x09, 0x8c, 0xf6, 0xa4, 0x95, 0xb3, 0x65, 0x5e, 0x49, 0x36, + 0x8c, 0x51, 0x85, 0x62, 0xcc, 0xe6, 0x2a, 0x3d, 0xdc, 0x68, 0x08, 0x41, + 0x73, 0x18, 0x74, 0x10, 0xe5, 0x18, 0xfa, 0xbe, 0x2f, 0xaa, 0x98, 0x3c, + 0x7c, 0x44, 0x43, 0x3f, 0xd6, 0x27, 0xd3, 0x28, 0xf0, 0x2b, 0xeb, 0xf2, + 0x46, 0xfc, 0xf6, 0x3f, 0xc7, 0xa8, 0xc0, 0xf0, 0x17, 0xef, 0x35, 0xde, + 0x55, 0x30, 0xef, 0xf7, 0x7b, 0x57, 0xf3, 0x9f, 0x00, 0xb5, 0x49, 0x1e, + 0xc4, 0x6a, 0xea, 0x0e, 0x40, 0x95, 0x47, 0x55, 0x32, 0x4f, 0x4f, 0x24, + 0x5a, 0x10, 0xaa, 0x1f, 0x5b, 0x9b, 0xc1, 0xb3, 0xaa, 0xa3, 0x40, 0x32, + 0x56, 0x80, 0xbf, 0x38, 0xbc, 0x89, 0xad, 0xa8, 0x0e, 0x8f, 0x8e, 0x14, + 0x17, 0x5a, 0x9b, 0x25, 0x85, 0x85, 0xa7, 0x43, 0xc8, 0x19, 0x21, 0xf9, + 0xa3, 0xdc, 0xb9, 0xc8, 0x70, 0x7b, 0xc8, 0x42, 0x38, 0x50, 0xb9, 0xcf, + 0x90, 0x6e, 0x88, 0x7f, 0x5a, 0x56, 0xc8, 0xd7, 0x84, 0x7b, 0x69, 0xe1, + 0x31, 0x6d, 0xe9, 0xc7, 0x7f, 0x39, 0x78, 0x52, 0xa2, 0x0c, 0xc7, 0x3b, + 0x89, 0x05, 0x9d, 0x66, 0xc6, 0xea, 0x48, 0x75, 0xa5, 0xd6, 0x89, 0x8e, + 0x47, 0xdf, 0x81, 0x28, 0x94, 0xc7, 0x98, 0xd4, 0x1c, 0x6f, 0x95, 0xdd, + 0x20, 0x74, 0xe9, 0xde, 0xb5, 0x3b, 0x87, 0xa1, 0x1a, 0x1e, 0xee, 0xc7, + 0xbc, 0xa4, 0x12, 0x30, 0x92, 0x60, 0x9f, 0x0d, 0x4d, 0x23, 0x1f, 0xa0, + 0xea, 0x07, 0x84, 0x10, 0xb3, 0xd3, 0x2a, 0x2f, 0x27, 0xdb, 0x27, 0x76, + 0xb8, 0x43, 0xe2, 0x9a, 0xfc, 0x9b, 0x81, 0x43, 0xd2, 0xbc, 0xc2, 0xbb, + 0x40, 0xbd, 0xe8, 0x10, 0xd5, 0xca, 0xd2, 0x10, 0x5e, 0x18, 0xfe, 0x45, + 0x1d, 0xc2, 0xf9, 0x99, 0x50, 0xbe, 0x7e, 0xca, 0x1a, 0x45, 0x17, 0x99, + 0x03, 0x9d, 0x2b, 0x68, 0xb7, 0x76, 0x3e, 0x68, 0x41, 0x81, 0x6d, 0xe3, + 0x77, 0xbe, 0x4e, 0xc9, 0x41, 0xb7, 0x8a, 0xb7, 0xa7, 0x59, 0xfa, 0x04, + 0x7b, 0xde, 0xd0, 0x3f, 0x7a, 0x57, 0xa3, 0xf1, 0x9e, 0x0a, 0x66, 0x98, + 0xb0, 0xc1, 0xc2, 0xb4, 0x7a, 0x3b, 0x2f, 0x54, 0x3b, 0x66, 0xe6, 0x6b, + 0xc5, 0x2c, 0xa1, 0xb1, 0xd2, 0xee, 0xd8, 0x30, 0xf3, 0xa9, 0x2f, 0xe8, + 0xf0, 0x3e, 0xd8, 0x2b, 0x9a, 0x75, 0x58, 0x59, 0xc7, 0x3a, 0x39, 0xa1, + 0x58, 0x19, 0x87, 0x3f, 0x90, 0xe5, 0xb3, 0xb6, 0xfe, 0x39, 0x34, 0xc8, + 0x4c, 0x21, 0x7b, 0x96, 0x9e, 0x3e, 0x38, 0x48, 0x3e, 0xaa, 0x0b, 0x1b, + 0xbf, 0xa9, 0x45, 0x83, 0x8e, 0x38, 0xf3, 0x96, 0xb8, 0x24, 0x23, 0xc1, + 0xd3, 0x5c, 0x77, 0xeb, 0x6f, 0xf8, 0x16, 0xa8, 0x94, 0xbc, 0xab, 0x2a, + 0x20, 0x52, 0xec, 0x9a, 0x5c, 0xd9, 0x99, 0xb4, 0x84, 0x50, 0x90, 0xbb, + 0xf7, 0x80, 0x51, 0x61, 0x95, 0x61, 0xaa, 0x03, 0xd6, 0xd4, 0xa9, 0x73, + 0x86, 0x3b, 0xf1, 0x7e, 0xca, 0x7c, 0xfb, 0xf9, 0x33, 0xe6, 0x96, 0x66, + 0x13, 0x7a, 0x35, 0xae, 0x71, 0xcc, 0x13, 0x4b, 0x5e, 0x73, 0xbd, 0xf8, + 0xf2, 0x5e, 0x51, 0x5c, 0x50, 0x09, 0x3c, 0x59, 0xfa, 0xd0, 0xd4, 0x8e, + 0xe0, 0x21, 0xb4, 0x97, 0xa4, 0x7d, 0xeb, 0x17, 0xef, 0x4c, 0xf4, 0xd0, + 0x0b, 0xf5, 0x42, 0xaf, 0x07, 0x8e, 0xe9, 0x5f, 0x2b, 0xce, 0xb4, 0xf9, + 0x17, 0xea, 0x9e, 0x83, 0x94, 0xf5, 0x1d, 0x49, 0x91, 0x42, 0x65, 0x84, + 0x77, 0x56, 0xc0, 0x4f, 0x67, 0x37, 0xed, 0xa3, 0x18, 0x22, 0x69, 0xd7, + 0x40, 0xfb, 0x39, 0xfd, 0xc2, 0x37, 0x68, 0x98, 0x30, 0x6a, 0x33, 0xad, + 0x2f, 0xf2, 0x3d, 0x5c, 0xe0, 0x4a, 0x29, 0x38, 0xe5, 0xe0, 0x5c, 0xb3, + 0x79, 0xd5, 0x8c, 0xcd, 0x25, 0xad, 0xab, 0xd3, 0x75, 0x2f, 0x54, 0x3a, + 0xfe, 0x8e, 0x0d, 0x3f, 0xfa, 0x6e, 0xcc, 0x80, 0x26, 0x08, 0x7f, 0xa3, + 0x9e, 0xba, 0x80, 0x4c, 0x36, 0x4c, 0x4d, 0x74, 0xc0, 0x3f, 0xd1, 0xb3, + 0xad, 0xa3, 0xc8, 0xcf, 0x7a, 0x73, 0xb7, 0x09, 0x67, 0x3b, 0xf8, 0x6f, + 0x7a, 0x26, 0x57, 0x65, 0x83, 0xcf, 0x18, 0x3c, 0x86, 0x2c, 0xb4, 0xcd, + 0xe8, 0x74, 0xfa, 0x63, 0xd4, 0xb4, 0x36, 0x36, 0xd9, 0xb0, 0xeb, 0x29, + 0xe3, 0x3a, 0x7f, 0x06, 0x80, 0x29, 0x4c, 0x86, 0x94, 0x49, 0x42, 0x22, + 0x57, 0x0c, 0x4f, 0xfa, 0x08, 0xb5, 0x12, 0xbe, 0x76, 0xf5, 0x52, 0x10, + 0x47, 0x48, 0x1f, 0xbd, 0x87, 0x51, 0xd1, 0x39, 0xc8, 0x50, 0x7c, 0xfa, + 0x92, 0xe7, 0xea, 0x40, 0x55, 0xf7, 0x61, 0x9f, 0x19, 0xc2, 0x65, 0x23, + 0x6d, 0xe0, 0x41, 0xb9, 0x5b, 0xb7, 0x8c, 0x9a, 0xee, 0x50, 0x53, 0xa6, + 0xe8, 0x80, 0x14, 0x8c, 0xeb, 0x2a, 0xc1, 0x44, 0xda, 0x6d, 0x90, 0x96, + 0xb8, 0xf1, 0xc4, 0x0d, 0xf1, 0xd8, 0x8e, 0xd0, 0xb4, 0x73, 0x49, 0xe5, + 0x34, 0xab, 0x00, 0x0f, 0x0b, 0x7b, 0xc3, 0x7d, 0x53, 0x1d, 0x75, 0xef, + 0x27, 0xfb, 0xdf, 0x29, 0xfd, 0x61, 0xb3, 0x71, 0x25, 0xac, 0x62, 0x2d, + 0xaa, 0x1a, 0x2a, 0x55, 0x6e, 0x11, 0x50, 0x4b, 0x2c, 0x3d, 0xd8, 0x8d, + 0xb9, 0xcb, 0xc2, 0x21, 0x77, 0x4e, 0x40, 0x56, 0x45, 0xc1, 0x07, 0x79, + 0xdb, 0x66, 0x2f, 0x6d, 0x4d, 0xac, 0x2b, 0x2d, 0x29, 0xff, 0xa1, 0x79, + 0x10, 0x03, 0x72, 0x09, 0xe8, 0xe9, 0x31, 0xd5, 0x6f, 0x42, 0x97, 0x3e, + 0x09, 0xf0, 0x4a, 0xb5, 0xe6, 0x73, 0x94, 0xc1, 0xb4, 0x94, 0xa1, 0xd9, + 0x44, 0xe8, 0x50, 0xe2, 0x6c, 0x82, 0xea, 0x89, 0x06, 0xd6, 0x44, 0xe9, + 0x53, 0xd0, 0x5c, 0xcf, 0x0a, 0x3b, 0x89, 0x50, 0x8d, 0x1e, 0x44, 0xbd, + 0xb2, 0xb6, 0x68, 0xf4, 0xbb, 0x2d, 0x65, 0x95, 0x5c, 0xb5, 0xdc, 0xe2, + 0xb7, 0x70, 0x86, 0xfd, 0x5b, 0xcc, 0x99, 0x41, 0x5d, 0x22, 0x11, 0xa8, + 0x22, 0x8c, 0xc1, 0x73, 0x70, 0x5b, 0x31, 0x11, 0xc3, 0xdb, 0x7f, 0xca, + 0x2b, 0xcb, 0xeb, 0x7d, 0x2b, 0xd1, 0x32, 0xe6, 0xf8, 0x22, 0x22, 0x69, + 0xea, 0xb7, 0xcd, 0x25, 0x22, 0x33, 0x2f, 0x83, 0x3f, 0xb7, 0x2d, 0x22, + 0x61, 0x24, 0x01, 0xb3, 0xe9, 0xd0, 0xf6, 0x21, 0xe6, 0x2d, 0xea, 0x0e, + 0x53, 0x7a, 0x97, 0xcd, 0xcf, 0x6c, 0xe2, 0xd5, 0x8b, 0xdc, 0xe9, 0xe0, + 0xfd, 0xd0, 0xa0, 0xbf, 0xa5, 0x39, 0x7e, 0xd4, 0xdd, 0xfe, 0x1a, 0xce, + 0xb0, 0x85, 0x8e, 0xc1, 0x05, 0x36, 0xf9, 0xd3, 0x6a, 0x35, 0xab, 0x53, + 0x1d, 0xc2, 0xa0, 0xfa, 0xc2, 0x6b, 0x8b, 0x8c, 0x2d, 0x5d, 0x5f, 0xb8, + 0x18, 0x43, 0x53, 0xb9, 0x5d, 0x08, 0x07, 0xd1, 0x8f, 0xc6, 0xe9, 0xef, + 0xaf, 0x3b, 0xbb, 0x60, 0xaa, 0x28, 0xac, 0x4c, 0x03, 0x5d, 0xc8, 0x05, + 0xba, 0x82, 0x5c, 0xcb, 0xc6, 0x2a, 0x13, 0xf6, 0xfc, 0x54, 0xf3, 0xea, + 0x20, 0xce, 0xcf, 0x05, 0x00, 0xb9, 0x98, 0x0b, 0x9f, 0x96, 0xe0, 0x7b, + 0x85, 0x8e, 0x43, 0xbd, 0xf2, 0x3e, 0x17, 0x19, 0x8d, 0x23, 0x72, 0x85, + 0x93, 0xdf, 0x3a, 0x21, 0x94, 0x34, 0x32, 0x53, 0x02, 0xba, 0x34, 0xba, + 0xa5, 0x2e, 0x5c, 0x0b, 0x1e, 0x3f, 0xa9, 0x83, 0x92, 0x63, 0x0b, 0x12, + 0xc9, 0xf8, 0x35, 0xef, 0x78, 0xa0, 0xee, 0xc0, 0xbb, 0x14, 0xd4, 0x68, + 0x39, 0xa0, 0x00, 0x38, 0x77, 0x1e, 0xfc, 0x94, 0xb4, 0xd4, 0xc1, 0x98, + 0xe1, 0x43, 0x8e, 0xc6, 0xa7, 0x58, 0x33, 0x1b, 0xa3, 0x73, 0xf7, 0x4c, + 0x49, 0x9d, 0xc0, 0xb8, 0xbf, 0x30, 0x84, 0x2e, 0x5a, 0x8b, 0x6c, 0xa5, + 0xde, 0xb5, 0x6a, 0x79, 0x67, 0x54, 0xe7, 0x8c, 0x3c, 0xf3, 0x70, 0x1b, + 0x3d, 0x35, 0x23, 0x65, 0x17, 0xc9, 0x74, 0x11, 0x0b, 0xb1, 0x64, 0xc0, + 0x65, 0xa3, 0x9e, 0x5a, 0x7b, 0xa2, 0xda, 0xe1, 0xf4, 0xeb, 0xb8, 0x13, + 0x90, 0x30, 0xc1, 0x72, 0x6a, 0x2a, 0x13, 0xe3, 0x36, 0xe1, 0x05, 0x47, + 0x56, 0x42, 0xf2, 0x59, 0x44, 0x12, 0x23, 0x27, 0xe4, 0xfe, 0xae, 0x83, + 0x39, 0x0f, 0x4c, 0x85, 0x3f, 0xaf, 0x97, 0x2e, 0xae, 0x3c, 0x12, 0x0e, + 0xfd, 0x5b, 0xfd, 0x8e, 0x58, 0x58, 0x4a, 0xbd, 0x05, 0x98, 0x6b, 0x82, + 0x03, 0x02, 0x0a, 0x2d, 0x1c, 0x19, 0x0f, 0x95, 0x12, 0x5d, 0x8c, 0x1e, + 0x7b, 0x49, 0xbb, 0x83, 0xe2, 0xd2, 0x53, 0x60, 0xe1, 0xab, 0xd2, 0x8b, + 0x02, 0xeb, 0x49, 0x27, 0xd7, 0xda, 0x22, 0xd3, 0x26, 0x6f, 0x3e, 0x5b, + 0x3f, 0x33, 0xcb, 0xa8, 0x08, 0x98, 0xa6, 0xc5, 0x35, 0xc1, 0x81, 0xc1, + 0xd6, 0x28, 0xe5, 0xba, 0x50, 0xe9, 0x14, 0x1a, 0x0b, 0x0a, 0x8a, 0x9e, + 0xa3, 0xaa, 0xbc, 0x3b, 0x38, 0x5b, 0xe0, 0x1f, 0xf6, 0xb8, 0x95, 0x79, + 0xa4, 0x45, 0x5f, 0xc4, 0x63, 0x86, 0xd0, 0x15, 0xe0, 0x25, 0x6e, 0x5f, + 0x8d, 0x75, 0x25, 0x67, 0xea, 0xf3, 0x92, 0x33, 0xd1, 0x07, 0xf3, 0x43, + 0x21, 0x42, 0x40, 0x70, 0x9b, 0x8e, 0x0b, 0x41, 0x54, 0x30, 0x73, 0xd0, + 0x49, 0xe4, 0x70, 0xf6, 0xd3, 0x7d, 0x59, 0xd6, 0x1f, 0x06, 0xfc, 0x12, + 0x89, 0x9f, 0x26, 0x09, 0x34, 0xf6, 0x64, 0x56, 0x37, 0x68, 0x59, 0x33, + 0x9c, 0xa0, 0xfa, 0x65, 0x70, 0xb3, 0xe1, 0x29, 0xd1, 0x5b, 0xaf, 0xe7, + 0xa5, 0x39, 0x64, 0x38, 0x8b, 0xb1, 0xd6, 0xce, 0xa4, 0xb4, 0xb6, 0xdb, + 0x01, 0xb4, 0xf9, 0xb7, 0x1f, 0x8f, 0xcd, 0x28, 0xe6, 0x27, 0x47, 0xf2, + 0x53, 0x1d, 0xea, 0xb4, 0x53, 0xfa, 0xe0, 0x22, 0xea, 0xc5, 0xd2, 0xfc, + 0x4e, 0x45, 0xcf, 0xef, 0xaa, 0xea, 0xaf, 0x7e, 0x77, 0xe2, 0x39, 0x1c, + 0x5d, 0x9c, 0x77, 0x7b, 0x71, 0xb5, 0x11, 0xef, 0xc7, 0xf8, 0xba, 0x2b, + 0x7b, 0x15, 0xfa, 0x2d, 0xd5, 0xd8, 0xe0, 0xee, 0xbe, 0x10, 0xd6, 0xdb, + 0x47, 0xf1, 0x11, 0xcc, 0x35, 0x4c, 0x2d, 0xa8, 0x12, 0x12, 0x23, 0x78, + 0x0b, 0xd3, 0xb8, 0x90, 0x8a, 0x1d, 0xc4, 0x90, 0x4b, 0x7e, 0x35, 0xb9, + 0x9f, 0x5b, 0x68, 0x97, 0x9c, 0x09, 0xc3, 0x0d, 0x0a, 0x20, 0xd9, 0x25, + 0x07, 0xeb, 0x56, 0xb5, 0xd6, 0x93, 0x31, 0x3d, 0x71, 0x7c, 0x0f, 0x48, + 0x26, 0x32, 0x0f, 0x1b, 0x43, 0x75, 0xc2, 0xcd, 0xf6, 0xaa, 0x88, 0x38, + 0x7b, 0xe9, 0xc0, 0x98, 0x51, 0xa4, 0x06, 0x15, 0x7f, 0x11, 0x0b, 0x91, + 0xcb, 0x59, 0x92, 0x1c, 0xa1, 0x44, 0x63, 0xa4, 0x3a, 0xad, 0xd7, 0x1d, + 0x9e, 0x63, 0xfb, 0xb9, 0x7d, 0x43, 0x80, 0x79, 0xe8, 0x01, 0xba, 0x08, + 0x47, 0x78, 0x57, 0xd6, 0x0b, 0x38, 0x94, 0x64, 0xac, 0x64, 0x77, 0xdc, + 0xb8, 0xa9, 0xa5, 0xa2, 0x62, 0x70, 0x36, 0x4f, 0x39, 0xd9, 0xae, 0x2f, + 0x15, 0xd3, 0x07, 0xc4, 0x01, 0x03, 0x96, 0x5e, 0x51, 0xa7, 0x15, 0x2a, + 0x9d, 0x22, 0x74, 0xae, 0x8a, 0xd4, 0xb9, 0x91, 0xed, 0xad, 0xa7, 0x76, + 0xad, 0x38, 0x33, 0xef, 0x3c, 0xe4, 0xd0, 0x7c, 0x6e, 0x53, 0xae, 0x0c, + 0x7a, 0xdf, 0x2c, 0x18, 0xeb, 0xc4, 0x8c, 0xfe, 0xab, 0x10, 0xcd, 0xaf, + 0x8f, 0x88, 0x3f, 0xac, 0xe3, 0x20, 0xed, 0x0c, 0x62, 0x81, 0x2e, 0x12, + 0xa9, 0xa5, 0xe7, 0xd5, 0x3a, 0xef, 0x40, 0xb4, 0x91, 0x52, 0x4c, 0xfd, + 0xd5, 0xb8, 0x98, 0x19, 0xcd, 0x1b, 0xa9, 0x17, 0xe7, 0x9a, 0xda, 0x8a, + 0xb4, 0x8f, 0x1a, 0x5c, 0x78, 0xd2, 0x28, 0x7a, 0xb6, 0x66, 0xac, 0x73, + 0xd4, 0x11, 0xc0, 0x81, 0xff, 0x71, 0x57, 0x4c, 0x23, 0x90, 0x2a, 0xd8, + 0x67, 0x7a, 0x6a, 0x58, 0xb7, 0x5b, 0xbe, 0x80, 0x62, 0x17, 0x10, 0x90, + 0xc1, 0xb7, 0x2c, 0xbe, 0xbe, 0x97, 0x2e, 0x85, 0x36, 0x07, 0x8e, 0x63, + 0xfc, 0x38, 0xc5, 0x66, 0x20, 0x33, 0x2b, 0xe8, 0x25, 0x25, 0xc1, 0x11, + 0xba, 0x5b, 0x12, 0xd9, 0x06, 0x4d, 0xfc, 0x49, 0x20, 0x27, 0x6b, 0x79, + 0x92, 0x8b, 0xde, 0x22, 0x39, 0xf9, 0x2e, 0xc9, 0x1b, 0xb9, 0x97, 0x2f, + 0xc3, 0x37, 0xf5, 0xa3, 0x6b, 0xd3, 0x3b, 0x94, 0xa5, 0x56, 0xb7, 0x81, + 0x7c, 0x9d, 0x28, 0xff, 0x57, 0xe7, 0x02, 0xa1, 0xd1, 0x3a, 0x3d, 0xac, + 0x74, 0x45, 0xb3, 0xab, 0x95, 0xec, 0x68, 0x8a, 0x9c, 0xf7, 0x43, 0xa4, + 0x14, 0x0d, 0x68, 0x40, 0x5f, 0x7e, 0x25, 0x8a, 0x47, 0x3f, 0x9c, 0xaf, + 0x88, 0x0b, 0x4a, 0xc0, 0x98, 0xc2, 0x57, 0xf4, 0xde, 0x04, 0x09, 0x37, + 0x9c, 0x87, 0x83, 0xb6, 0xa5, 0xa8, 0x5e, 0xc4, 0xec, 0x2e, 0xfd, 0xc9, + 0xf3, 0x85, 0x4f, 0x7d, 0xb8, 0xba, 0x6e, 0x6d, 0xc0, 0xd2, 0x37, 0xb2, + 0xba, 0x17, 0xad, 0x29, 0xf8, 0x71, 0x74, 0x0c, 0x93, 0x1e, 0x07, 0x34, + 0xec, 0xc3, 0x5f, 0x15, 0x21, 0x49, 0x0f, 0xa7, 0x7e, 0x72, 0x79, 0x66, + 0xfd, 0x3e, 0x29, 0xce, 0x12, 0xeb, 0x57, 0x88, 0xd8, 0xcc, 0x14, 0x96, + 0x33, 0x44, 0x64, 0x6c, 0x34, 0x55, 0xb3, 0x76, 0xc9, 0xa7, 0x3f, 0x7b, + 0x16, 0x9d, 0x7e, 0x95, 0x4c, 0xfa, 0xc9, 0x46, 0x17, 0x18, 0x18, 0x78, + 0xe7, 0xfb, 0x6b, 0x86, 0xf4, 0x25, 0x3a, 0x0b, 0x4a, 0xcd, 0x1a, 0x51, + 0xde, 0xa4, 0x45, 0xdd, 0xdb, 0xc9, 0x9f, 0xa9, 0xc3, 0x58, 0xb2, 0x43, + 0x90, 0x8b, 0xc1, 0x59, 0x47, 0x1a, 0x89, 0xcb, 0x9c, 0x6d, 0x46, 0x1f, + 0x0d, 0xe9, 0xfa, 0xd8, 0xe9, 0xde, 0xdb, 0xf5, 0x22, 0x9b, 0xe3, 0xef, + 0xb4, 0x0c, 0xc7, 0x34, 0xd0, 0x2a, 0x0f, 0x0b, 0x8e, 0x11, 0x88, 0x91, + 0xb7, 0xce, 0x92, 0xf2, 0x83, 0x3c, 0xd2, 0xf8, 0x42, 0x32, 0x82, 0x48, + 0xad, 0x67, 0x44, 0x45, 0x59, 0xac, 0x57, 0xb7, 0x7e, 0x1b, 0xce, 0xca, + 0x51, 0xfb, 0x1b, 0x12, 0x39, 0xaf, 0xe4, 0xfb, 0xdb, 0xc5, 0xb7, 0xcc, + 0x4a, 0x5d, 0xc4, 0xa6, 0x95, 0xaf, 0x5b, 0x39, 0x4e, 0x47, 0xc5, 0x50, + 0x67, 0x92, 0x84, 0x62, 0xeb, 0x81, 0x77, 0x24, 0xda, 0x27, 0x64, 0xfe, + 0xe4, 0x83, 0x40, 0x33, 0xc8, 0xb1, 0xaa, 0xbb, 0xbf, 0x13, 0xc3, 0x18, + 0x9a, 0x24, 0x06, 0xbd, 0x0a, 0x07, 0xa3, 0xd6, 0xd8, 0x38, 0x32, 0x73, + 0x8d, 0x40, 0x5f, 0xc2, 0x3f, 0xeb, 0xd2, 0x0e, 0x3d, 0x6d, 0xf5, 0x72, + 0x5a, 0xa6, 0x56, 0x22, 0x41, 0xe5, 0x0c, 0xb5, 0x0c, 0xda, 0xcd, 0x46, + 0xbc, 0xd7, 0x98, 0x89, 0x5e, 0x97, 0x54, 0x4f, 0x4b, 0xc0, 0x27, 0x51, + 0x0d, 0x20, 0x3f, 0x55, 0x78, 0xdc, 0x5a, 0x79, 0x08, 0xed, 0xd3, 0xaa, + 0x9c, 0xc3, 0x7d, 0x75, 0x76, 0x81, 0xa4, 0xe0, 0xfc, 0x90, 0x6a, 0x83, + 0x37, 0x53, 0xb8, 0xb5, 0xd9, 0x7a, 0xd9, 0x7d, 0xeb, 0x50, 0x72, 0xd3, + 0x5d, 0xed, 0x22, 0xfb, 0x6e, 0x67, 0x79, 0x9c, 0xb9, 0xea, 0xac, 0xc1, + 0x6d, 0x68, 0xf5, 0x12, 0xaa, 0x54, 0x90, 0xd8, 0x7f, 0xe0, 0xf4, 0xdd, + 0x3b, 0x88, 0xe3, 0xec, 0x7f, 0x1c, 0x2b, 0x08, 0x32, 0xc6, 0x05, 0x53, + 0xae, 0xa4, 0x46, 0xa7, 0xf3, 0xe6, 0xcb, 0xe7, 0x04, 0xc1, 0x52, 0xa7, + 0xfe, 0x68, 0x55, 0xc1, 0x91, 0xb2, 0x9a, 0x3b, 0x05, 0xc6, 0xae, 0x15, + 0x89, 0xdc, 0xb2, 0x0b, 0xeb, 0x19, 0x96, 0x62, 0xe3, 0x67, 0xc5, 0xdc, + 0xf5, 0xe8, 0xbe, 0x16, 0xbe, 0xf6, 0xe4, 0x0b, 0xeb, 0x99, 0x82, 0x65, + 0x0a, 0x97, 0xf5, 0xc2, 0x19, 0x1c, 0x1e, 0xa1, 0xf1, 0x75, 0x06, 0xa7, + 0xdb, 0x97, 0x68, 0x94, 0x0b, 0xea, 0xc4, 0xda, 0x70, 0x72, 0x3e, 0x9f, + 0xfc, 0x20, 0x4e, 0x54, 0xfb, 0x18, 0x01, 0x74, 0x9a, 0x24, 0x1d, 0x20, + 0x3a, 0x25, 0xe1, 0xd8, 0xaf, 0xe3, 0x76, 0xe0, 0x47, 0x53, 0x86, 0xd9, + 0x3f, 0xc2, 0x46, 0x4a, 0x02, 0x05, 0xaf, 0xbf, 0x49, 0x12, 0x22, 0x66, + 0x81, 0xf5, 0x9d, 0xdd, 0xae, 0x7f, 0xf5, 0x99, 0x2b, 0x89, 0xa6, 0x25, + 0x30, 0xd6, 0xb3, 0x00, 0xa4, 0x62, 0xd2, 0xb3, 0x8e, 0xdd, 0xc2, 0x04, + 0x62, 0x17, 0x44, 0xa3, 0x62, 0xf7, 0x8c, 0x56, 0x00, 0x4f, 0x98, 0xfe, + 0x7a, 0xdf, 0x9d, 0x47, 0xab, 0xc9, 0xb7, 0x0e, 0x0d, 0x02, 0x54, 0x6a, + 0xab, 0xf9, 0x22, 0xb9, 0x11, 0xb3, 0xec, 0x17, 0xb9, 0xc9, 0x86, 0xf6, + 0x66, 0x97, 0x1f, 0xa9, 0x38, 0xd8, 0x66, 0x8e, 0x41, 0xd9, 0x9a, 0x35, + 0xfd, 0x19, 0x64, 0xcb, 0x1e, 0x77, 0x80, 0xd4, 0x6d, 0xea, 0x00, 0xf5, + 0x9b, 0xc9, 0x55, 0xef, 0x80, 0x14, 0x79, 0xab, 0xf5, 0x5e, 0xb0, 0x4b, + 0x73, 0x52, 0x17, 0x2a, 0xd7, 0x68, 0x79, 0x6a, 0xf1, 0xc0, 0x04, 0xce, + 0x33, 0xd2, 0x18, 0xad, 0x39, 0x4d, 0xda, 0x40, 0x49, 0xce, 0x00, 0xca, + 0x89, 0xf3, 0xbd, 0x13, 0xe5, 0x7a, 0x03, 0x99, 0xa3, 0x4b, 0x29, 0xcd, + 0x18, 0xbd, 0xc8, 0xd7, 0x30, 0xcd, 0x4f, 0x65, 0xdc, 0xca, 0xc2, 0x9f, + 0x84, 0x2d, 0x83, 0xf6, 0x69, 0x0d, 0x55, 0x08, 0x5b, 0x6c, 0x87, 0x53, + 0xda, 0x13, 0x2a, 0x34, 0xf7, 0xea, 0x13, 0xec, 0x14, 0x90, 0xe8, 0x94, + 0xdc, 0xa6, 0xcf, 0xe9, 0x9b, 0x99, 0x63, 0x48, 0xf3, 0x34, 0xac, 0xf2, + 0x78, 0x76, 0x90, 0x46, 0xd8, 0x7d, 0x2b, 0xc1, 0xd2, 0xdd, 0xf1, 0xda, + 0x23, 0xc8, 0x3c, 0xd6, 0x58, 0x2e, 0xaf, 0x2c, 0xf6, 0x8a, 0xb3, 0x93, + 0x0e, 0x4f, 0x82, 0x7e, 0x26, 0x88, 0x0b, 0x3b, 0xe4, 0xe9, 0x85, 0x2b, + 0x99, 0xca, 0xdc, 0xad, 0x84, 0x26, 0xee, 0x35, 0x6a, 0x50, 0xc4, 0xae, + 0x95, 0x30, 0x0d, 0x09, 0xef, 0xdb, 0x4b, 0x4c, 0x9b, 0x0f, 0x04, 0x0a, + 0x6e, 0xf0, 0x92, 0x43, 0x06, 0xb9, 0x73, 0x16, 0x79, 0x15, 0x3f, 0x08, + 0xcc, 0x78, 0x2b, 0x35, 0x8c, 0xa3, 0x2a, 0x6e, 0xf6, 0x5c, 0x61, 0xf3, + 0xc6, 0x4b, 0x8a, 0xbc, 0x75, 0x1f, 0x4a, 0x00, 0x4e, 0x5f, 0x9e, 0x24, + 0x03, 0x2d, 0x86, 0x26, 0xa7, 0x78, 0xb7, 0xc3, 0x6f, 0x74, 0x6d, 0x32, + 0x34, 0xcd, 0x37, 0x42, 0x56, 0x24, 0x83, 0x7f, 0xa8, 0x1b, 0x9b, 0xae, + 0x97, 0x55, 0x2d, 0xba, 0x67, 0x75, 0x67, 0xca, 0xa5, 0xd1, 0x6e, 0xd6, + 0x48, 0xaf, 0xeb, 0x71, 0xdc, 0x31, 0xfb, 0x3b, 0xe3, 0x7c, 0x64, 0x9d, + 0xe5, 0x5a, 0xe4, 0x87, 0x6e, 0xed, 0xed, 0xca, 0xb6, 0x51, 0xfd, 0x73, + 0xef, 0x7c, 0xbc, 0x15, 0x69, 0xfd, 0x9f, 0x1f, 0x0f, 0x17, 0x1a, 0x8d, + 0x73, 0x61, 0x7d, 0xf1, 0x09, 0x97, 0x06, 0xbe, 0x90, 0x38, 0xdf, 0xac, + 0xfd, 0xe2, 0x87, 0xe8, 0xc1, 0xc3, 0x9b, 0x83, 0x79, 0xa6, 0xdd, 0x6d, + 0x58, 0x4d, 0x03, 0x26, 0x99, 0x1d, 0x2e, 0x47, 0xb0, 0x20, 0x3f, 0x84, + 0xaf, 0xfa, 0xf9, 0xf1, 0x62, 0xd5, 0x80, 0xb8, 0x6e, 0x69, 0x7e, 0x53, + 0x80, 0x05, 0xc4, 0x2f, 0xba, 0xed, 0x0d, 0x75, 0xca, 0x01, 0xde, 0x6e, + 0xf0, 0xd3, 0x23, 0x9b, 0x1e, 0xae, 0x02, 0x57, 0xeb, 0x40, 0xf2, 0x55, + 0x89, 0xd7, 0x70, 0xd6, 0x45, 0xe7, 0x67, 0xd3, 0x3e, 0x21, 0xda, 0xb6, + 0xae, 0xe5, 0xe6, 0x82, 0x0c, 0x3e, 0x3e, 0xe8, 0xbe, 0x85, 0x3d, 0x79, + 0x75, 0x90, 0x9b, 0x9c, 0x01, 0x88, 0x8d, 0x5a, 0x34, 0x1d, 0x10, 0x83, + 0x85, 0x08, 0xea, 0x88, 0x51, 0x29, 0xea, 0x95, 0x40, 0x2f, 0x16, 0x90, + 0xec, 0x1b, 0xb7, 0x22, 0x81, 0xcb, 0x1b, 0x8c, 0xf5, 0xe2, 0xfd, 0xcb, + 0x1f, 0xe7, 0xb0, 0x4b, 0x4d, 0x7c, 0x7d, 0x11, 0x17, 0x20, 0x89, 0x8b, + 0x4a, 0x80, 0xa3, 0x10, 0x6f, 0x68, 0x09, 0x01, 0x68, 0x86, 0x3b, 0x2a, + 0xfb, 0x48, 0x80, 0xa0, 0xd1, 0xdb, 0x3f, 0x91, 0x44, 0x58, 0x83, 0xc6, + 0x85, 0x77, 0x6b, 0xb1, 0x35, 0x4a, 0x03, 0xa2, 0xcf, 0x2f, 0xbd, 0xcd, + 0x4b, 0xfa, 0x5a, 0x5e, 0x8f, 0x8b, 0x95, 0x62, 0xaa, 0xe7, 0x3b, 0x54, + 0xb1, 0xec, 0xd5, 0x85, 0x4f, 0xd9, 0x59, 0x56, 0xb4, 0xec, 0xc1, 0x21, + 0xc5, 0xa6, 0x35, 0x1d, 0x7b, 0x60, 0xe1, 0xb1, 0x7c, 0x8f, 0x47, 0xa1, + 0xf1, 0x13, 0x4b, 0xaf, 0x23, 0xcb, 0x5e, 0xe2, 0x74, 0x16, 0x16, 0x96, + 0x3b, 0xff, 0xbf, 0x26, 0x5f, 0x68, 0xd5, 0x64, 0xc6, 0x62, 0xaf, 0x4a, + 0xfc, 0x0f, 0x27, 0x3e, 0x96, 0x5b, 0x7c, 0xeb, 0x78, 0x81, 0x3c, 0x0a, + 0x63, 0xd5, 0x6b, 0x3c, 0xa9, 0xd4, 0x37, 0x03, 0x3b, 0x5c, 0x62, 0x7a, + 0xd5, 0x69, 0xbe, 0x44, 0x50, 0xab, 0x0a, 0x54, 0x31, 0x5c, 0x44, 0x52, + 0xfe, 0xde, 0xbb, 0x10, 0x80, 0x79, 0xb2, 0x69, 0xc5, 0x75, 0x8b, 0xba, + 0x1d, 0x4d, 0x2d, 0xfa, 0xc8, 0x0e, 0xc0, 0xaf, 0xc2, 0x31, 0xa1, 0x53, + 0xc7, 0x9f, 0x3e, 0x1f, 0x38, 0x8c, 0x1e, 0x00, 0x78, 0x76, 0xb6, 0xb5, + 0x68, 0xa4, 0x68, 0xe9, 0xba, 0xda, 0x97, 0xca, 0x16, 0xde, 0xba, 0xa1, + 0xb7, 0x17, 0x26, 0xb3, 0x4b, 0x4b, 0x4e, 0x21, 0x9c, 0xaf, 0xce, 0xf0, + 0x52, 0x41, 0x13, 0x87, 0x75, 0xc4, 0xd7, 0x34, 0x0c, 0x2d, 0xfe, 0xc1, + 0xb6, 0x60, 0x84, 0xd2, 0x57, 0xc2, 0xb2, 0x6c, 0xa6, 0x97, 0x51, 0xea, + 0x49, 0x07, 0x7d, 0xac, 0x15, 0x75, 0x71, 0x67, 0x2c, 0xdf, 0x09, 0x0c, + 0x63, 0x38, 0x6a, 0x25, 0xf3, 0x9b, 0x5d, 0x5d, 0x63, 0xe7, 0x20, 0xa3, + 0xf5, 0x6f, 0x8c, 0x77, 0x91, 0xb0, 0x6d, 0xad, 0x01, 0x1d, 0x40, 0x65, + 0xcd, 0x31, 0xbf, 0xb2, 0x0a, 0x1f, 0xf9, 0xb0, 0x34, 0x7f, 0x6a, 0xfe, + 0xca, 0x2e, 0x28, 0xc4, 0x5b, 0xdb, 0xa9, 0xd4, 0xdc, 0xe6, 0x3a, 0x0a, + 0xeb, 0xe2, 0xc5, 0xb8, 0xbe, 0xad, 0x8d, 0x7d, 0xa2, 0x5e, 0x88, 0xad, + 0xb8, 0xda, 0x41, 0x12, 0x1f, 0xc5, 0x85, 0xa1, 0x83, 0x3d, 0xc7, 0xbb, + 0x6d, 0x55, 0x63, 0xd0, 0x8b, 0x06, 0x76, 0x96, 0xf5, 0x0b, 0xd9, 0x2f, + 0x45, 0xf4, 0x9b, 0xc8, 0x18, 0xba, 0xbd, 0x30, 0xdc, 0x4d, 0x47, 0xde, + 0xbc, 0xc0, 0xc0, 0xca, 0x9f, 0xd7, 0xda, 0xcb, 0xd8, 0xdd, 0x7e, 0x98, + 0x25, 0xfd, 0x9f, 0xa4, 0x22, 0x5d, 0x4b, 0x63, 0x1b, 0xfa, 0x78, 0xdb, + 0x3d, 0x39, 0xcc, 0x26, 0x00, 0x70, 0x0e, 0xac, 0xf7, 0x30, 0xc0, 0x8c, + 0x97, 0xbe, 0x57, 0xeb, 0x1a, 0xc0, 0xfd, 0x4c, 0x81, 0x69, 0x54, 0x1b, + 0xd4, 0x8c, 0xb2, 0xe7, 0xf0, 0x5f, 0x0e, 0x46, 0x95, 0x7a, 0x2b, 0x0c, + 0x69, 0x37, 0x89, 0x45, 0x6a, 0xb2, 0x9f, 0xa8, 0x99, 0xd2, 0x6c, 0xa0, + 0x9d, 0xc0, 0x36, 0x65, 0x2f, 0x37, 0xe3, 0xc8, 0xba, 0x4f, 0xd2, 0x4c, + 0x69, 0x2e, 0x15, 0x2c, 0x92, 0x13, 0x44, 0x96, 0xa5, 0xe9, 0x90, 0x24, + 0x0a, 0x94, 0x44, 0x16, 0x6a, 0x8e, 0x4a, 0x7b, 0xf4, 0x65, 0x41, 0xd0, + 0x4e, 0xf3, 0xf2, 0x6d, 0x8e, 0xc0, 0x70, 0xdf, 0x56, 0x2f, 0x11, 0x80, + 0x03, 0x42, 0xb5, 0x9c, 0x59, 0xea, 0xe1, 0x2d, 0xc7, 0xd1, 0x29, 0x4a, + 0xce, 0x78, 0x83, 0x8f, 0x9b, 0xd4, 0x6b, 0x91, 0xd8, 0x7b, 0xd1, 0x03, + 0xc1, 0xe8, 0x84, 0xbc, 0xca, 0x64, 0xdd, 0xac, 0xdd, 0x39, 0xaf, 0x7c, + 0x5d, 0x7a, 0x5f, 0xc3, 0x8b, 0x0f, 0xd7, 0x18, 0x43, 0x4a, 0x8e, 0x3f, + 0x2f, 0x02, 0x91, 0xa2, 0xdc, 0x3e, 0x2c, 0x9c, 0x3b, 0x3c, 0xe3, 0xd4, + 0x9a, 0xb3, 0x59, 0x43, 0xd4, 0x75, 0x1c, 0x4b, 0x0b, 0xad, 0x84, 0x2d, + 0xbd, 0x05, 0x66, 0xdb, 0x0a, 0xda, 0x77, 0x75, 0x46, 0x78, 0x99, 0x44, + 0xdf, 0x12, 0x58, 0xa9, 0x3a, 0x5f, 0x04, 0x18, 0x81, 0xa2, 0x2d, 0xcf, + 0x9c, 0x35, 0x8d, 0x67, 0x73, 0x9e, 0x8d, 0xe4, 0xc9, 0x9d, 0x15, 0x80, + 0xe3, 0x36, 0xf9, 0xbd, 0xf2, 0x65, 0xb2, 0x10, 0xa9, 0xe8, 0x2a, 0x03, + 0x9d, 0x03, 0x11, 0xe5, 0xcc, 0x32, 0x12, 0xef, 0xee, 0x22, 0xa3, 0x0c, + 0x35, 0x28, 0xc0, 0x17, 0x9b, 0x43, 0x75, 0x5f, 0x2c, 0xbf, 0xeb, 0xc4, + 0xf2, 0xa0, 0x6e, 0xcb, 0x06, 0x1c, 0x5c, 0xd9, 0xe8, 0x56, 0xaf, 0xe4, + 0x2c, 0x6a, 0x8a, 0x9e, 0xea, 0x34, 0x60, 0x09, 0x94, 0xe7, 0xb2, 0x50, + 0x4b, 0xc9, 0xeb, 0xce, 0xd2, 0x7f, 0x1d, 0xc1, 0x22, 0xe1, 0x71, 0x1f, + 0xac, 0xb7, 0xb9, 0x5c, 0x8e, 0x44, 0xe9, 0x51, 0x58, 0x5c, 0x0e, 0x12, + 0x34, 0xb5, 0xab, 0xa1, 0x0d, 0xf1, 0xc6, 0x71, 0xf0, 0x51, 0x6f, 0xa8, + 0x72, 0xde, 0xad, 0x42, 0xe6, 0x39, 0x28, 0xb0, 0x66, 0xf8, 0xcb, 0x09, + 0xb2, 0x82, 0x5a, 0x02, 0x15, 0xca, 0x17, 0xa9, 0x63, 0xd8, 0xac, 0x18, + 0x49, 0xf7, 0xfa, 0x6d, 0xad, 0x3f, 0xf5, 0x2a, 0xd2, 0x1a, 0x9e, 0x4f, + 0xdc, 0xb1, 0xb5, 0x5b, 0x93, 0x59, 0x44, 0x72, 0x0c, 0xf4, 0x7e, 0xe4, + 0x62, 0x10, 0x64, 0xad, 0x2d, 0xb0, 0x2e, 0xcb, 0xf8, 0xd9, 0xbb, 0xf9, + 0xfc, 0xc5, 0xe1, 0x31, 0x6e, 0x0e, 0x8b, 0x12, 0x62, 0x25, 0x92, 0xd6, + 0xb0, 0x0d, 0x78, 0x7e, 0x03, 0x13, 0x65, 0xe0, 0xa3, 0x5d, 0x33, 0xc7, + 0x04, 0x8b, 0xe7, 0x45, 0xa8, 0x9f, 0xd1, 0x70, 0x27, 0x32, 0x6e, 0x50, + 0x48, 0x6a, 0xd3, 0x32, 0xcb, 0xca, 0xd5, 0xcd, 0xd4, 0x0a, 0x76, 0x8e, + 0x6b, 0xb1, 0x73, 0x68, 0x38, 0xf5, 0x73, 0xb2, 0x46, 0x7a, 0xb5, 0xff, + 0xea, 0x52, 0xc9, 0x5b, 0x56, 0xff, 0xf0, 0x35, 0x4b, 0xae, 0x88, 0x61, + 0x8a, 0x3c, 0xb9, 0x78, 0x1c, 0x51, 0xaa, 0x5d, 0xaf, 0xe0, 0xe7, 0x8c, + 0x03, 0x85, 0x6a, 0x1f, 0xca, 0xb9, 0x8c, 0xf4, 0x37, 0xea, 0xae, 0x54, + 0xf1, 0xb8, 0x4c, 0x94, 0x42, 0xcf, 0x2a, 0x8d, 0x13, 0xef, 0x66, 0xf8, + 0x1b, 0xbe, 0x5d, 0x9a, 0x24, 0x12, 0xb5, 0xe8, 0xe8, 0x44, 0x6b, 0x95, + 0xd6, 0xed, 0x98, 0xd8, 0x10, 0xeb, 0x19, 0xe5, 0x42, 0x01, 0xaa, 0x1c, + 0x6a, 0x62, 0xd2, 0xf0, 0xc3, 0x33, 0x4d, 0xf0, 0x3e, 0x76, 0x8d, 0xec, + 0xbb, 0xb9, 0xeb, 0x14, 0x77, 0x02, 0x39, 0xb7, 0x75, 0x21, 0x3a, 0xa5, + 0xef, 0x04, 0xb3, 0x20, 0x50, 0xaf, 0xed, 0x99, 0x0b, 0xec, 0x12, 0x6d, + 0xad, 0x9f, 0x23, 0x02, 0xc0, 0x01, 0x5a, 0xfe, 0xfc, 0xee, 0xa9, 0xc1, + 0x23, 0x51, 0x71, 0xb0, 0xe6, 0xee, 0xcc, 0xcd, 0x6a, 0x59, 0xcf, 0xad, + 0xff, 0x4b, 0x36, 0xbf, 0x2a, 0xaf, 0x56, 0xae, 0xd7, 0x35, 0x47, 0xc4, + 0x11, 0xef, 0x66, 0x18, 0xd1, 0xec, 0x2a, 0x5c, 0xca, 0xfe, 0x8f, 0x8b, + 0xa2, 0x80, 0x57, 0x42, 0xe5, 0xa5, 0xb4, 0x7a, 0x34, 0xd0, 0x1b, 0xca, + 0xb3, 0x7f, 0x2c, 0x54, 0x47, 0x50, 0xf0, 0xdd, 0xde, 0x87, 0xc0, 0x8f, + 0x3a, 0x79, 0x49, 0x50, 0xe9, 0x4a, 0xe2, 0x74, 0x08, 0x18, 0x61, 0xaa, + 0x17, 0xe4, 0x44, 0xdf, 0xeb, 0xf8, 0x2f, 0x5f, 0x06, 0x19, 0x06, 0x13, + 0xec, 0x14, 0x47, 0x04, 0x51, 0x03, 0x55, 0x62, 0x78, 0x73, 0x7d, 0xe9, + 0x15, 0xff, 0xd3, 0xb2, 0x5c, 0x54, 0x79, 0xca, 0x58, 0x10, 0x86, 0x66, + 0x4d, 0x6a, 0x73, 0x13, 0x20, 0x60, 0xd1, 0xaa, 0x54, 0xa8, 0xf3, 0x45, + 0x1c, 0x02, 0x23, 0xc6, 0x43, 0xee, 0xb4, 0xf4, 0xed, 0xa3, 0x59, 0xb7, + 0xb3, 0x4e, 0xda, 0xdf, 0x5f, 0x12, 0xed, 0xb0, 0x03, 0x93, 0xc7, 0xb7, + 0xa9, 0x52, 0xdb, 0x91, 0x39, 0x4f, 0x0d, 0x6d, 0x31, 0x08, 0xf5, 0x91, + 0x90, 0xe5, 0x11, 0xbf, 0x33, 0x4d, 0x3f, 0x7b, 0xc8, 0x46, 0xbf, 0x8f, + 0x27, 0x61, 0xc3, 0x6c, 0xea, 0xfa, 0xaf, 0xeb, 0x92, 0xd1, 0x86, 0xb4, + 0x50, 0x64, 0x6c, 0xba, 0xdf, 0x1f, 0xe9, 0xc6, 0x2f, 0xad, 0x8d, 0x95, + 0xe7, 0xfe, 0xcb, 0xbf, 0xcc, 0xba, 0xbd, 0xcc, 0x62, 0x85, 0x62, 0x7a, + 0x96, 0x85, 0x02, 0x1c, 0xc1, 0x8f, 0x4b, 0xfc, 0x4f, 0xea, 0x69, 0x8b, + 0x1c, 0x83, 0x81, 0x34, 0x15, 0x12, 0x16, 0x6f, 0x9c, 0x0e, 0xa4, 0x83, + 0xb6, 0x28, 0x2f, 0xd7, 0x6d, 0x2e, 0x98, 0x6a, 0xe7, 0x6f, 0x53, 0x83, + 0x18, 0x43, 0x75, 0x25, 0x97, 0x14, 0x15, 0x8d, 0x2f, 0x7f, 0x72, 0x1a, + 0x07, 0x42, 0x2a, 0x7a, 0xe4, 0x7e, 0xc4, 0x7a, 0x6a, 0xc9, 0x0f, 0xeb, + 0x4b, 0x60, 0x56, 0x15, 0x51, 0x23, 0x5d, 0xfa, 0x0e, 0x56, 0x06, 0x35, + 0x89, 0x89, 0x77, 0x55, 0xd3, 0xd7, 0x22, 0x2f, 0x41, 0xc5, 0x70, 0x3f, + 0x57, 0x80, 0xc6, 0xab, 0x30, 0x7e, 0xd8, 0x2b, 0xd2, 0xd2, 0xa2, 0xfc, + 0xf9, 0x32, 0x22, 0x9e, 0x63, 0x67, 0x8a, 0x55, 0xac, 0x4e, 0x66, 0x98, + 0xe6, 0x20, 0xea, 0xbd, 0x64, 0xe9, 0xd5, 0x06, 0x33, 0x33, 0xbf, 0xe2, + 0x89, 0x49, 0x91, 0x92, 0x4e, 0xf9, 0xcc, 0x23, 0xad, 0x26, 0x1a, 0xb1, + 0x01, 0x40, 0x9b, 0x3f, 0x30, 0x5c, 0x88, 0xaf, 0xce, 0x83, 0xc3, 0x45, + 0x90, 0xdc, 0xa6, 0x20, 0x3e, 0x15, 0x96, 0x25, 0xdf, 0xe1, 0xa6, 0xd6, + 0x78, 0xaf, 0xda, 0xc0, 0x0c, 0xf1, 0x21, 0x03, 0xf9, 0x7f, 0xb5, 0xfd, + 0x59, 0x20, 0x3d, 0x73, 0xad, 0xfb, 0x2b, 0x5f, 0x88, 0xbc, 0x17, 0xaf, + 0x1c, 0xaa, 0x5d, 0x17, 0x8f, 0xb7, 0x60, 0x9c, 0xc7, 0xc4, 0xe4, 0xf4, + 0xdb, 0xa9, 0x39, 0xb0, 0xd1, 0xb4, 0x6b, 0x4b, 0x20, 0xaf, 0xd5, 0xcc, + 0xd9, 0x68, 0x17, 0x4c, 0x9a, 0xd4, 0x35, 0x25, 0x17, 0x3b, 0xc3, 0x41, + 0x7b, 0x05, 0xe9, 0xe8, 0xdd, 0x02, 0x9d, 0x0f, 0x6a, 0xd7, 0xf5, 0xfa, + 0xae, 0xf2, 0x5b, 0xfe, 0xc4, 0x44, 0x62, 0xd6, 0xc4, 0x8e, 0x4b, 0x28, + 0x6a, 0x87, 0x3c, 0xe3, 0xf8, 0x01, 0xb5, 0xf9, 0x77, 0x4e, 0x07, 0x8f, + 0x40, 0x02, 0x72, 0x81, 0xa9, 0x6e, 0xa8, 0x84, 0x1f, 0xfe, 0x2e, 0x06, + 0x83, 0xb8, 0x14, 0x2b, 0xf8, 0x6e, 0x8b, 0xb2, 0xed, 0xff, 0xc5, 0x90, + 0x09, 0x86, 0xef, 0xe7, 0x64, 0xb3, 0x3f, 0x10, 0xe1, 0x47, 0xff, 0x4f, + 0xac, 0x76, 0x45, 0xa8, 0xba, 0xac, 0xab, 0x82, 0x07, 0x86, 0x8a, 0x24, + 0xf5, 0xc0, 0x01, 0x5f, 0x54, 0x8b, 0xdc, 0xbd, 0xd6, 0x28, 0x05, 0x56, + 0xfd, 0x13, 0xdf, 0x93, 0x9b, 0x68, 0x03, 0x90, 0x2c, 0x08, 0xcc, 0x0b, + 0xf9, 0x14, 0x44, 0x84, 0x79, 0x15, 0xab, 0xbc, 0x54, 0x1b, 0x76, 0xe3, + 0xfa, 0xf8, 0x32, 0xab, 0xf2, 0xcd, 0xed, 0x04, 0x15, 0x94, 0xb4, 0xb3, + 0xcc, 0x09, 0xf1, 0xb2, 0x35, 0x60, 0x0b, 0x05, 0xa1, 0x31, 0xd6, 0x6d, + 0xc6, 0x46, 0x6d, 0xe4, 0xe7, 0xbc, 0x5f, 0x3a, 0x72, 0xfd, 0x42, 0xb0, + 0x0e, 0xbb, 0xd2, 0xeb, 0x50, 0x26, 0x60, 0x38, 0xd6, 0x96, 0x1b, 0x5b, + 0x9d, 0xcc, 0xb4, 0x98, 0x9f, 0xe8, 0xf2, 0x95, 0xa3, 0x11, 0x9a, 0xcb, + 0x6d, 0x56, 0x87, 0x4b, 0x95, 0xb9, 0x41, 0xa3, 0x89, 0x2d, 0x2c, 0x29, + 0xe8, 0x29, 0x86, 0x47, 0x3e, 0x91, 0x2a, 0x59, 0x7d, 0x9c, 0x03, 0x9d, + 0x2d, 0xff, 0x05, 0x50, 0x21, 0x88, 0x12, 0x55, 0x2b, 0x25, 0x0c, 0x0c, + 0x59, 0xa9, 0x1f, 0xbd, 0x1c, 0xa0, 0xf9, 0xc2, 0x23, 0x4b, 0xaa, 0xbe, + 0x10, 0x4f, 0xf7, 0x5a, 0x25, 0x49, 0xb2, 0xc8, 0xdc, 0xf7, 0xb1, 0x45, + 0xdf, 0xbb, 0x15, 0xd9, 0x48, 0x49, 0x01, 0x27, 0xf6, 0xdc, 0x59, 0x48, + 0xb7, 0xd7, 0x5e, 0x46, 0xde, 0x2c, 0x27, 0x64, 0xf9, 0xc2, 0xc5, 0x37, + 0x21, 0x9a, 0xbf, 0x62, 0x14, 0xdd, 0x13, 0x26, 0x9f, 0x62, 0x65, 0x55, + 0xe8, 0xd7, 0x6f, 0x10, 0x5c, 0xd7, 0x19, 0x16, 0x1b, 0x87, 0xd3, 0x74, + 0xd2, 0x8a, 0x89, 0x15, 0x17, 0xd8, 0x83, 0x8f, 0x3f, 0x38, 0x98, 0x9b, + 0x25, 0x03, 0xc7, 0x7c, 0x35, 0x88, 0x53, 0x48, 0xca, 0xd6, 0x4d, 0x20, + 0x23, 0x54, 0x15, 0x51, 0xda, 0xfb, 0x7e, 0x41, 0xbc, 0x88, 0xf5, 0x53, + 0xf6, 0xe2, 0x54, 0xe6, 0xa8, 0xb1, 0x04, 0xac, 0xd1, 0xd6, 0x37, 0xd2, + 0xa9, 0x6f, 0x96, 0xc0, 0x6a, 0xb1, 0xd4, 0xcf, 0x1e, 0xda, 0xda, 0x72, + 0x43, 0xaa, 0x7b, 0x7d, 0x39, 0x19, 0x11, 0x06, 0x2a, 0x73, 0x87, 0xe6, + 0xdb, 0x8a, 0xcf, 0x66, 0xf2, 0x77, 0xc9, 0x0a, 0xe2, 0x13, 0x90, 0xd6, + 0x1b, 0xa6, 0xfb, 0xfd, 0xda, 0x63, 0x80, 0x81, 0x55, 0x7a, 0x4b, 0xea, + 0x79, 0x4d, 0xa9, 0x46, 0x2b, 0xb1, 0xa5, 0x98, 0x8d, 0x34, 0x32, 0x07, + 0xc6, 0xff, 0x98, 0x17, 0xd1, 0x55, 0x85, 0xc6, 0x8d, 0x0a, 0x3b, 0x58, + 0x1e, 0x82, 0x24, 0xa2, 0xef, 0x83, 0xed, 0xf6, 0xe2, 0x79, 0x1b, 0x2b, + 0x46, 0x7e, 0x94, 0x5b, 0xc8, 0x5a, 0x93, 0xef, 0xca, 0x76, 0xc7, 0xef, + 0x71, 0xce, 0x15, 0x33, 0x91, 0xef, 0x46, 0xa9, 0x58, 0xd8, 0x6d, 0xa9, + 0x47, 0x45, 0x35, 0xbb, 0xce, 0x96, 0xb7, 0x44, 0xd4, 0x7a, 0x90, 0xd4, + 0xcb, 0x18, 0xbc, 0x7b, 0x64, 0xf3, 0x8e, 0xf5, 0xd5, 0xf7, 0x82, 0xdb, + 0xff, 0xd6, 0x50, 0x17, 0xdf, 0x9a, 0x11, 0x75, 0x85, 0x36, 0xc8, 0x0c, + 0x44, 0xcc, 0xdc, 0x76, 0xfc, 0x9f, 0x3e, 0x84, 0x8f, 0xea, 0xc6, 0xb1, + 0xfa, 0x97, 0x75, 0x31, 0xe8, 0xc2, 0x81, 0x7b, 0x39, 0x14, 0xad, 0xdf, + 0x67, 0xf2, 0x44, 0xe0, 0xc4, 0x7a, 0x21, 0x63, 0x74, 0x73, 0x41, 0xf4, + 0xb5, 0xbd, 0x87, 0x36, 0xd0, 0x64, 0xb6, 0x8e, 0x98, 0xd2, 0x79, 0x5f, + 0x4d, 0x22, 0x8c, 0xc1, 0x41, 0x4c, 0xea, 0xb7, 0xab, 0x4b, 0x2e, 0xca, + 0x35, 0x14, 0xd3, 0x90, 0x9e, 0xd6, 0x94, 0x3e, 0x7e, 0xe4, 0x57, 0x09, + 0x22, 0x3c, 0xe6, 0xbe, 0x04, 0x95, 0x75, 0xf8, 0xe0, 0x42, 0xe9, 0xe2, + 0x5e, 0x2e, 0x2a, 0xc6, 0x48, 0x55, 0x42, 0x39, 0xc4, 0x81, 0x6a, 0xc6, + 0x19, 0xea, 0x4c, 0x63, 0x60, 0x11, 0xdf, 0xe7, 0xde, 0x4d, 0x0f, 0xec, + 0x0c, 0x8f, 0x21, 0xe7, 0x94, 0x72, 0x24, 0x4d, 0xc0, 0x44, 0x30, 0x63, + 0x18, 0x06, 0x9b, 0xb9, 0x63, 0xc2, 0x94, 0x6d, 0x78, 0xba, 0x36, 0x58, + 0xe3, 0x07, 0x0f, 0xd4, 0x16, 0xe5, 0xc7, 0x58, 0xb1, 0x5e, 0x96, 0x25, + 0x80, 0xc0, 0x0c, 0x4d, 0xf1, 0xda, 0x8b, 0xc6, 0x66, 0x56, 0x1e, 0x7c, + 0x64, 0x6b, 0x2c, 0xb2, 0x8c, 0xed, 0x07, 0xa7, 0x52, 0x70, 0xbd, 0x68, + 0xd3, 0x48, 0x18, 0x38, 0xa6, 0x60, 0x18, 0x97, 0x4a, 0xd0, 0x88, 0xed, + 0x4c, 0x99, 0xad, 0x88, 0x56, 0xec, 0x2b, 0xd7, 0xb4, 0xd6, 0xc6, 0x43, + 0x58, 0xf6, 0x9b, 0xfb, 0x28, 0xa7, 0xb4, 0xaa, 0x61, 0xc4, 0x09, 0x0b, + 0xa7, 0x51, 0x7a, 0xd3, 0x2f, 0x84, 0xeb, 0x9e, 0xc9, 0xc9, 0xac, 0x7e, + 0x80, 0x2e, 0xa6, 0x88, 0x84, 0xd2, 0x54, 0xca, 0xe6, 0xf1, 0x7c, 0x97, + 0x7c, 0x8a, 0x8a, 0x66, 0x7f, 0x00, 0x4b, 0x73, 0x3f, 0x2e, 0xfb, 0xcc, + 0xe5, 0x07, 0xe6, 0x4e, 0xa1, 0x8e, 0xfc, 0x62, 0xb7, 0xd7, 0xbe, 0xa4, + 0x4a, 0x65, 0xd7, 0xe2, 0xaa, 0x0c, 0xdd, 0x93, 0x93, 0x63, 0x56, 0x46, + 0xe5, 0xe5, 0xf5, 0x47, 0xb1, 0xe4, 0x4e, 0x60, 0x97, 0x83, 0x82, 0x23, + 0x84, 0x37, 0x20, 0xbd, 0xb5, 0x8b, 0x9d, 0x5d, 0xc8, 0xca, 0xe1, 0xa8, + 0x5a, 0xc4, 0xaa, 0xe2, 0x79, 0xda, 0x1d, 0x48, 0x60, 0x4c, 0x2e, 0x06, + 0x95, 0xb4, 0x76, 0x42, 0xa0, 0x6e, 0x52, 0x52, 0x0f, 0xf8, 0x24, 0x81, + 0x21, 0x6f, 0x67, 0x27, 0x9e, 0xe5, 0xf9, 0x9b, 0x8c, 0x82, 0x90, 0x90, + 0xdd, 0xe7, 0xd4, 0x24, 0x54, 0xa7, 0x26, 0x41, 0xd2, 0x54, 0x50, 0x6a, + 0x66, 0xf0, 0xd5, 0x68, 0xaf, 0xd1, 0xd2, 0x00, 0x66, 0xa1, 0x9e, 0x1b, + 0xab, 0xe6, 0x43, 0xa2, 0xb8, 0x05, 0x2f, 0xae, 0x9b, 0xce, 0x15, 0xa2, + 0x5b, 0xd1, 0xb5, 0x53, 0x66, 0x6e, 0xc9, 0x44, 0x7b, 0x8c, 0x5d, 0x94, + 0x63, 0x3c, 0xa5, 0xc5, 0x81, 0x48, 0xd7, 0x98, 0x6b, 0xb7, 0xce, 0xe4, + 0xd9, 0xaf, 0x1c, 0xa9, 0x76, 0x8c, 0x1b, 0x4b, 0x5c, 0x1e, 0x9c, 0x98, + 0xef, 0x74, 0x40, 0xe3, 0xf1, 0x48, 0x8c, 0x14, 0x66, 0xe4, 0x7d, 0xbd, + 0xff, 0xcf, 0xae, 0xf8, 0x36, 0x79, 0x83, 0x76, 0xe7, 0x66, 0x36, 0x12, + 0x60, 0x17, 0x2f, 0xb0, 0x2f, 0x22, 0x32, 0x4b, 0x42, 0x65, 0xed, 0x76, + 0x6e, 0x4c, 0x9d, 0xb9, 0x54, 0x9b, 0x98, 0x8b, 0x79, 0x8b, 0x0e, 0xaf, + 0x9c, 0x8c, 0xa9, 0x58, 0xaa, 0xa2, 0xde, 0x1a, 0x9b, 0x6d, 0x75, 0x0f, + 0xd2, 0xd4, 0x28, 0xdc, 0xca, 0xcd, 0x91, 0x66, 0xd0, 0xd9, 0xab, 0x3c, + 0x22, 0x55, 0x36, 0x87, 0x4f, 0x41, 0x24, 0x5c, 0xee, 0x5a, 0x54, 0x1a, + 0xe0, 0xf5, 0x2c, 0x01, 0x98, 0xa3, 0x54, 0x6e, 0x6f, 0xdc, 0x88, 0xf7, + 0x86, 0xba, 0xe2, 0x8d, 0x84, 0x95, 0x78, 0x84, 0x8c, 0xc1, 0xae, 0x8c, + 0x7f, 0xa7, 0x91, 0xbc, 0x6d, 0x3b, 0x48, 0x7a, 0x42, 0xa0, 0xc0, 0x0a, + 0xfe, 0xda, 0xbc, 0xe7, 0xa6, 0x76, 0xcb, 0xca, 0x68, 0xb0, 0xda, 0xb3, + 0x2e, 0x4c, 0x57, 0x50, 0xeb, 0xbb, 0x0a, 0x35, 0x94, 0x80, 0xab, 0xcf, + 0xa7, 0xdc, 0xab, 0x31, 0x54, 0xef, 0xe0, 0x77, 0xa5, 0x7e, 0x9e, 0x76, + 0x96, 0x62, 0x92, 0x25, 0xf1, 0xa1, 0xa5, 0x91, 0x06, 0x9e, 0x2f, 0x81, + 0xd8, 0x5f, 0x2e, 0xe4, 0xe8, 0xda, 0x9f, 0xe1, 0x62, 0xe1, 0x30, 0xd0, + 0x16, 0x02, 0xc6, 0xeb, 0x3a, 0x43, 0x4e, 0x64, 0x07, 0x77, 0xf2, 0xda, + 0x0d, 0xf5, 0xd3, 0x1c, 0x26, 0x4c, 0xcd, 0xa4, 0xb3, 0xc5, 0xd6, 0x73, + 0xb4, 0xbc, 0xc0, 0x07, 0x64, 0x98, 0xfb, 0xf6, 0x32, 0xe4, 0xe1, 0xca, + 0x74, 0x4c, 0x64, 0xad, 0x04, 0x53, 0x1b, 0x99, 0x24, 0x7b, 0x2e, 0xd7, + 0x3e, 0x07, 0xba, 0x7a, 0x08, 0x7b, 0xb1, 0xb0, 0x11, 0x3f, 0x4e, 0x66, + 0xd8, 0xa5, 0x4e, 0x72, 0x67, 0xa6, 0xbe, 0x38, 0x76, 0xcf, 0x72, 0x07, + 0x9a, 0x57, 0x2f, 0x29, 0x6d, 0x55, 0xcd, 0x69, 0xed, 0xcf, 0x59, 0x5e, + 0xd9, 0xe5, 0x29, 0x5b, 0xd0, 0x4d, 0x85, 0xea, 0x44, 0x0c, 0xac, 0x2d, + 0x76, 0x28, 0x65, 0x39, 0x2a, 0xfc, 0x9f, 0xe8, 0xd8, 0xce, 0x5c, 0x56, + 0xc0, 0x33, 0xa4, 0xcc, 0x32, 0xa6, 0x00, 0xd8, 0x9d, 0x9d, 0x0a, 0x28, + 0x27, 0x15, 0x42, 0x8e, 0xeb, 0xb0, 0xef, 0x6f, 0xb8, 0x93, 0xe2, 0xdf, + 0x6e, 0x17, 0x46, 0x67, 0x59, 0x05, 0x92, 0xad, 0x87, 0xc6, 0x06, 0x35, + 0xc8, 0x4c, 0x05, 0x1c, 0x9f, 0xf4, 0xa4, 0xa4, 0xa1, 0x8d, 0x11, 0xc7, + 0xab, 0x4b, 0x9b, 0x3a, 0x71, 0xcb, 0x2d, 0x1f, 0xec, 0x61, 0xa0, 0x66, + 0x5f, 0x3d, 0xa3, 0x95, 0x39, 0x7f, 0x98, 0x34, 0x79, 0x32, 0x15, 0x94, + 0xa0, 0x16, 0xa4, 0xf3, 0x45, 0x7b, 0x31, 0xfe, 0xf2, 0xe3, 0x65, 0x01, + 0xc1, 0xf7, 0xcd, 0xcb, 0x59, 0x52, 0xbb, 0xf6, 0xa4, 0x12, 0x22, 0x9e, + 0x5f, 0xd0, 0x50, 0x8a, 0x43, 0x62, 0xfd, 0x22, 0x21, 0xfb, 0xae, 0x08, + 0x57, 0xc7, 0x00, 0xa6, 0x48, 0x2e, 0xcb, 0x0b, 0x76, 0x08, 0xf9, 0xd4, + 0x14, 0x9a, 0xb5, 0xcd, 0xb8, 0x33, 0xc3, 0x0d, 0x2a, 0x3a, 0xf0, 0xe2, + 0x5f, 0x0e, 0x1f, 0xa1, 0x1c, 0x71, 0x38, 0x2e, 0x8e, 0x93, 0x13, 0x27, + 0xa2, 0x4a, 0xdc, 0x95, 0x1e, 0x26, 0x30, 0x5f, 0xdd, 0xc4, 0x15, 0x8e, + 0xa8, 0xfd, 0x80, 0xf4, 0x9e, 0x31, 0x80, 0xc9, 0xa0, 0xf7, 0x61, 0xb5, + 0x55, 0x40, 0xb4, 0x7f, 0xd8, 0xb2, 0x6b, 0x58, 0xba, 0x34, 0xba, 0x78, + 0xa0, 0xee, 0xa2, 0xc4, 0x73, 0x19, 0xc7, 0xdf, 0x1b, 0x46, 0x3c, 0xe0, + 0x7c, 0xb3, 0xf9, 0x7c, 0x35, 0xd5, 0xf0, 0xbf, 0x2c, 0xed, 0xa4, 0x20, + 0x95, 0x0b, 0x05, 0x7a, 0xce, 0xdc, 0x81, 0x95, 0xf3, 0x12, 0x8a, 0x7f, + 0xcb, 0xa8, 0xdc, 0x77, 0xbf, 0x8b, 0xdf, 0xf6, 0xb0, 0xce, 0xce, 0x0b, + 0xdf, 0xe9, 0xcf, 0x92, 0x02, 0x20, 0x82, 0x81, 0x9c, 0x03, 0x72, 0xe8, + 0x41, 0x6b, 0xbe, 0xb6, 0x87, 0x8b, 0xf9, 0x9e, 0x49, 0x77, 0xc5, 0xcf, + 0x73, 0x9d, 0xf6, 0x1c, 0x42, 0x7c, 0xa8, 0xbb, 0xe3, 0x24, 0x70, 0x9f, + 0xef, 0x28, 0xce, 0x45, 0x13, 0x13, 0x5f, 0xad, 0x02, 0x2a, 0xb4, 0x14, + 0x80, 0x66, 0xe1, 0x6b, 0x29, 0x72, 0x77, 0xa3, 0x04, 0x36, 0x28, 0x8d, + 0xc6, 0x39, 0xa3, 0x29, 0x59, 0xbf, 0x1e, 0x69, 0xcc, 0x8f, 0x25, 0x28, + 0xb8, 0x24, 0x7c, 0xea, 0xe9, 0x4c, 0x43, 0x6e, 0x6c, 0x7b, 0x1d, 0x41, + 0x7f, 0xd9, 0xd9, 0x59, 0x1e, 0x45, 0x76, 0xcc, 0x26, 0x6e, 0xe1, 0x80, + 0x73, 0x4d, 0x79, 0x3c, 0x5c, 0x1d, 0x78, 0xf3, 0xf9, 0x75, 0x2c, 0x9d, + 0x9d, 0x8e, 0x90, 0x23, 0xf3, 0xf9, 0xd7, 0x68, 0x14, 0xf3, 0x09, 0x2f, + 0xa1, 0x86, 0xb1, 0x9d, 0xe2, 0x3c, 0xd3, 0x16, 0xc4, 0xdf, 0x7c, 0xcf, + 0xc5, 0xf2, 0x3e, 0x67, 0x8b, 0xc8, 0x3e, 0x23, 0x17, 0xbf, 0x75, 0x1e, + 0xf3, 0x35, 0xee, 0x9f, 0x14, 0xae, 0xc1, 0x5b, 0xe7, 0x92, 0x68, 0xb8, + 0x0f, 0x95, 0x67, 0x1b, 0x55, 0xe7, 0x90, 0x6f, 0x72, 0xa0, 0x78, 0xd2, + 0x57, 0xca, 0x0a, 0x92, 0x62, 0x8d, 0x20, 0x52, 0x84, 0xb3, 0xae, 0x8e, + 0x22, 0x3d, 0x36, 0x3a, 0xfe, 0x68, 0x2d, 0x89, 0x8f, 0x51, 0x5b, 0x87, + 0x87, 0x21, 0x69, 0x1a, 0x90, 0x97, 0x9e, 0x2f, 0x91, 0xae, 0x32, 0x17, + 0x08, 0x0b, 0x3e, 0x65, 0x8a, 0xaa, 0x8e, 0xf3, 0x7b, 0x43, 0xc4, 0x2d, + 0x05, 0xac, 0x7a, 0xd9, 0x29, 0x41, 0xf8, 0x80, 0x64, 0x99, 0x98, 0xc3, + 0xb8, 0x4b, 0x4a, 0x4b, 0x48, 0x2a, 0xbd, 0x38, 0x42, 0x3a, 0xf1, 0x67, + 0x03, 0x1d, 0xd8, 0x00, 0x50, 0xc9, 0xce, 0x3a, 0x34, 0xe5, 0xac, 0x5f, + 0x36, 0x55, 0xf4, 0xf2, 0xa6, 0x09, 0x04, 0x20, 0x64, 0x56, 0xa1, 0x15, + 0x65, 0x4d, 0x07, 0x7e, 0x47, 0xf7, 0x34, 0x30, 0x3a, 0xbe, 0x49, 0xc1, + 0x75, 0xa3, 0x7d, 0xe5, 0x0e, 0xba, 0xdf, 0x81, 0xc0, 0x94, 0xf8, 0xec, + 0x1d, 0x81, 0x63, 0x48, 0x12, 0x16, 0x82, 0x12, 0x8b, 0x2a, 0xf7, 0x6e, + 0x23, 0xa4, 0x11, 0x8b, 0x70, 0xb3, 0x8a, 0xce, 0xd0, 0xdf, 0xc4, 0x6f, + 0x65, 0x01, 0xe4, 0x6e, 0x61, 0x58, 0x78, 0x2a, 0x4b, 0x9a, 0x1b, 0x65, + 0x94, 0xc4, 0xc5, 0x9d, 0x95, 0xc6, 0x12, 0x6f, 0xfc, 0x8a, 0x5e, 0x7f, + 0xc8, 0xbe, 0xa9, 0xf0, 0x65, 0xb9, 0xa7, 0xe5, 0xa9, 0x39, 0xc3, 0x7a, + 0x79, 0x05, 0x72, 0x77, 0x1f, 0xf7, 0x2b, 0x29, 0xf5, 0xb9, 0xce, 0x20, + 0x82, 0x01, 0x21, 0xa0, 0x0c, 0xd5, 0x7c, 0x7b, 0xe5, 0x9a, 0xea, 0xdb, + 0x71, 0xa6, 0xef, 0x57, 0xca, 0x0d, 0x55, 0x3e, 0x3c, 0x9e, 0xac, 0x6c, + 0x18, 0x4e, 0xe9, 0xc4, 0x67, 0x00, 0x1d, 0xc3, 0xf6, 0x88, 0x9d, 0xd5, + 0xb4, 0x1a, 0xa8, 0xde, 0xfa, 0x8c, 0xe8, 0xb5, 0x8a, 0xec, 0x6c, 0x94, + 0x62, 0x63, 0x00, 0xaf, 0x8a, 0x91, 0x4b, 0x1b, 0x01, 0x90, 0x72, 0xa5, + 0x0a, 0x03, 0x50, 0xc7, 0x0d, 0x66, 0xaf, 0xca, 0xae, 0xe5, 0x7f, 0x00, + 0x00, 0x01, 0x0a }; void h264_get_video_data(const guchar **data, guint *size) { *data = h264_clip; - *size = sizeof(h264_clip); + *size = H264_CLIP_DATA_SIZE; } diff --git a/tests/test-vc1.c b/tests/test-vc1.c index e15bb82aa3..80a56fcb67 100644 --- a/tests/test-vc1.c +++ b/tests/test-vc1.c @@ -20,9 +20,9 @@ #include "test-vc1.h" -#define VC1_CLIP_WIDTH 320 -#define VC1_CLIP_HEIGHT 240 -#define VC1_CLIP_DATA_SIZE 20860 +#define VC1_CLIP_WIDTH 320 +#define VC1_CLIP_HEIGHT 240 +#define VC1_CLIP_DATA_SIZE 20864 /* Data dump of a 320x240 VC-1 video clip (vc1.raw), it has a single frame */ static const guchar vc1_clip[VC1_CLIP_DATA_SIZE] = { @@ -1764,7 +1764,7 @@ static const guchar vc1_clip[VC1_CLIP_DATA_SIZE] = { 0x0e, 0x12, 0x0f, 0x34, 0xb6, 0x7b, 0xe0, 0xef, 0x3b, 0xbb, 0xb6, 0x92, 0xe8, 0xfc, 0xd4, 0x1d, 0x67, 0x18, 0x8a, 0x50, 0x9a, 0x48, 0x81, 0x4f, 0x2f, 0x54, 0x12, 0xbe, 0xdb, 0xd2, 0x67, 0xae, 0x1d, 0x2a, 0x5f, 0x8d, - 0x0f, 0x55, 0xbf, 0x40 + 0x0f, 0x55, 0xbf, 0x40, 0x00, 0x00, 0x01, 0x0a }; void vc1_get_video_data(const guchar **data, guint *size) From da3948bdebf3b9eceb0df6a6b16a08f20f10f186 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 26 Apr 2010 08:40:27 +0000 Subject: [PATCH 0262/3781] Use a recursive mutex so that a single thread can lock several times. This fixes decoding of MPEG-2 and H.264 because those created a GstVaapiContext later through avcodec_decode_video() that was a protected call. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 6 +++--- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index bb4694e3ec..d002b53734 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -419,13 +419,13 @@ end: static void gst_vaapi_display_lock_default(GstVaapiDisplay *display) { - g_static_mutex_lock(&display->priv->mutex); + g_static_rec_mutex_lock(&display->priv->mutex); } static void gst_vaapi_display_unlock_default(GstVaapiDisplay *display) { - g_static_mutex_unlock(&display->priv->mutex); + g_static_rec_mutex_unlock(&display->priv->mutex); } static void @@ -562,7 +562,7 @@ gst_vaapi_display_init(GstVaapiDisplay *display) priv->subpicture_formats = NULL; priv->create_display = TRUE; - g_static_mutex_init(&priv->mutex); + g_static_rec_mutex_init(&priv->mutex); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 2427babf1c..308da874f3 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -69,7 +69,7 @@ G_BEGIN_DECLS * Base class for VA displays. */ struct _GstVaapiDisplayPrivate { - GStaticMutex mutex; + GStaticRecMutex mutex; VADisplay display; guint width; guint height; From 0d7164c96c9b78a42a5a454552f69a63b97ee7ee Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 26 Apr 2010 08:53:18 +0000 Subject: [PATCH 0263/3781] Flush stream only if avcodec_decode_video() read something. Otherwise, we might still have to seek into the stream. i.e. keep the data longer. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 38 ++++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index f375a70b67..d83e94d556 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -191,6 +191,20 @@ get_raw_format(GstVaapiDecoder *decoder) return av_find_input_format(raw_format); } +/** Flushes n bytes from the stream */ +static void +stream_flush(GstVaapiDecoder *decoder, int buf_size) +{ + GstVaapiDecoderFfmpegPrivate * const priv = + GST_VAAPI_DECODER_FFMPEG(decoder)->priv; + + gst_vaapi_decoder_flush(decoder, buf_size); + if (priv->iobuf_pos > buf_size) + priv->iobuf_pos -= buf_size; + else + priv->iobuf_pos = 0; +} + /** Reads one packet */ static int stream_read(void *opaque, uint8_t *buf, int buf_size) @@ -200,17 +214,12 @@ stream_read(void *opaque, uint8_t *buf, int buf_size) GST_VAAPI_DECODER_FFMPEG(decoder)->priv; if (buf_size > 0) { - if (priv->is_constructed) { - buf_size = gst_vaapi_decoder_read(decoder, buf, buf_size); - } - else { - buf_size = gst_vaapi_decoder_copy( - decoder, - priv->iobuf_pos, - buf, buf_size - ); - priv->iobuf_pos += buf_size; - } + buf_size = gst_vaapi_decoder_copy( + decoder, + priv->iobuf_pos, + buf, buf_size + ); + priv->iobuf_pos += buf_size; } return buf_size; } @@ -472,10 +481,10 @@ decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(ffdecoder); GstVaapiSurface *surface = NULL; - int got_picture = 0; + int bytes_read, got_picture = 0; GST_VAAPI_DISPLAY_LOCK(display); - avcodec_decode_video( + bytes_read = avcodec_decode_video( priv->avctx, priv->frame, &got_picture, @@ -483,6 +492,9 @@ decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) ); GST_VAAPI_DISPLAY_UNLOCK(display); + if (bytes_read > 0) + stream_flush(GST_VAAPI_DECODER_CAST(ffdecoder), bytes_read); + if (got_picture) { surface = gst_vaapi_context_find_surface_by_id( GST_VAAPI_DECODER_CONTEXT(ffdecoder), From 68101c13b35a34443ee3d369d37f28913b0150a5 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 26 Apr 2010 11:36:12 +0000 Subject: [PATCH 0264/3781] Drop useless End-of-Sequence marker. --- tests/test-vc1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-vc1.c b/tests/test-vc1.c index 80a56fcb67..2838015265 100644 --- a/tests/test-vc1.c +++ b/tests/test-vc1.c @@ -22,7 +22,7 @@ #define VC1_CLIP_WIDTH 320 #define VC1_CLIP_HEIGHT 240 -#define VC1_CLIP_DATA_SIZE 20864 +#define VC1_CLIP_DATA_SIZE 20860 /* Data dump of a 320x240 VC-1 video clip (vc1.raw), it has a single frame */ static const guchar vc1_clip[VC1_CLIP_DATA_SIZE] = { @@ -1764,7 +1764,7 @@ static const guchar vc1_clip[VC1_CLIP_DATA_SIZE] = { 0x0e, 0x12, 0x0f, 0x34, 0xb6, 0x7b, 0xe0, 0xef, 0x3b, 0xbb, 0xb6, 0x92, 0xe8, 0xfc, 0xd4, 0x1d, 0x67, 0x18, 0x8a, 0x50, 0x9a, 0x48, 0x81, 0x4f, 0x2f, 0x54, 0x12, 0xbe, 0xdb, 0xd2, 0x67, 0xae, 0x1d, 0x2a, 0x5f, 0x8d, - 0x0f, 0x55, 0xbf, 0x40, 0x00, 0x00, 0x01, 0x0a + 0x0f, 0x55, 0xbf, 0x40 }; void vc1_get_video_data(const guchar **data, guint *size) From d7e4bca05b54a0d5c59bea13c561eb3e8c6cb466 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 26 Apr 2010 11:44:32 +0000 Subject: [PATCH 0265/3781] Handle user end-of-streams. Add gst_vaapi_decoder_{start,stop}() helpers. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 121 ++++++++++++++++------ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 12 +++ tests/test-decode.c | 2 +- 3 files changed, 104 insertions(+), 31 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index fc80e6ec10..dabb8aa369 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -44,6 +44,12 @@ enum { PROP_CODEC, }; +static gboolean +gst_vaapi_decoder_start(GstVaapiDecoder *decoder); + +static gboolean +gst_vaapi_decoder_stop(GstVaapiDecoder *decoder); + static gpointer decoder_thread_cb(gpointer data) { @@ -71,6 +77,13 @@ decoder_thread_cb(gpointer data) g_object_ref(decoder); status = klass->decode(decoder); g_object_unref(decoder); + + /* Detect End-of-Stream conditions */ + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS && + priv->is_eos && + gst_vaapi_decoder_read_avail(decoder) == 0) + status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + GST_DEBUG("decode frame (status = %d)", status); } else { @@ -81,9 +94,14 @@ decoder_thread_cb(gpointer data) g_mutex_unlock(priv->adapter_mutex); /* Signal the main thread we got an error */ - gst_vaapi_decoder_push_surface(decoder, NULL); + if (status != GST_VAAPI_DECODER_STATUS_END_OF_STREAM) + gst_vaapi_decoder_push_surface(decoder, NULL); } } + + /* End-of-Stream reached, decoder thread is no longer necessary */ + if (status == GST_VAAPI_DECODER_STATUS_END_OF_STREAM) + break; } return NULL; } @@ -93,6 +111,9 @@ create_buffer(const guchar *buf, guint buf_size, gboolean copy) { GstBuffer *buffer; + if (!buf || !buf_size) + return NULL; + buffer = gst_buffer_new(); if (!buffer) return NULL; @@ -119,29 +140,24 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) { GstVaapiDecoderPrivate * const priv = decoder->priv; - if (!buffer) - return FALSE; + if (!buffer) { + priv->is_eos = TRUE; + return TRUE; + } g_return_val_if_fail(priv->adapter_mutex && priv->adapter_cond, FALSE); GST_DEBUG("queue encoded data buffer %p (%d bytes)", buffer, GST_BUFFER_SIZE(buffer)); + if (!priv->decoder_thread && !gst_vaapi_decoder_start(decoder)) + return FALSE; + /* XXX: add a mechanism to wait for enough buffer bytes to be consumed */ g_mutex_lock(priv->adapter_mutex); gst_adapter_push(priv->adapter, buffer); g_cond_signal(priv->adapter_cond); g_mutex_unlock(priv->adapter_mutex); - - if (!priv->decoder_thread) { - priv->decoder_thread = g_thread_create( - decoder_thread_cb, decoder, - TRUE, - NULL - ); - if (!priv->decoder_thread) - return FALSE; - } return TRUE; } @@ -155,18 +171,10 @@ unref_surface_cb(gpointer surface, gpointer user_data) static void gst_vaapi_decoder_finalize(GObject *object) { - GstVaapiDecoderPrivate * const priv = GST_VAAPI_DECODER(object)->priv; + GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object); + GstVaapiDecoderPrivate * const priv = decoder->priv; - if (priv->decoder_thread) { - priv->decoder_thread_cancel = TRUE; - if (priv->adapter_mutex && priv->adapter_cond) { - g_mutex_lock(priv->adapter_mutex); - g_cond_signal(priv->adapter_cond); - g_mutex_unlock(priv->adapter_mutex); - } - g_thread_join(priv->decoder_thread); - priv->decoder_thread = NULL; - } + gst_vaapi_decoder_stop(decoder); if (priv->adapter) { gst_adapter_clear(priv->adapter); @@ -305,10 +313,68 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->surfaces_cond = g_cond_new(); priv->decoder_thread = NULL; priv->decoder_thread_cancel = FALSE; + priv->is_eos = FALSE; g_queue_init(&priv->surfaces); } +/** + * gst_vaapi_decoder_start: + * @decoder: a #GstVaapiDecoder + * + * Starts the decoder. This creates the internal decoder thread, if + * necessary. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_decoder_start(GstVaapiDecoder *decoder) +{ + /* This is an internal function */ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (!priv->decoder_thread) { + priv->decoder_thread = g_thread_create( + decoder_thread_cb, decoder, + TRUE, + NULL + ); + if (!priv->decoder_thread) + return FALSE; + } + return TRUE; +} + +/** + * gst_vaapi_decoder_stop: + * @decoder: a #GstVaapiDecoder + * + * Stops the decoder. This destroys any decoding thread that was + * previously created by gst_vaapi_decoder_start(). Only + * gst_vaapi_decoder_get_surface() on the queued surfaces will be + * allowed at this point. + * + * Return value: %FALSE on success + */ +gboolean +gst_vaapi_decoder_stop(GstVaapiDecoder *decoder) +{ + /* This is an internal function */ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (priv->decoder_thread) { + priv->decoder_thread_cancel = TRUE; + if (priv->adapter_mutex && priv->adapter_cond) { + g_mutex_lock(priv->adapter_mutex); + g_cond_signal(priv->adapter_cond); + g_mutex_unlock(priv->adapter_mutex); + } + g_thread_join(priv->decoder_thread); + priv->decoder_thread = NULL; + } + return TRUE; +} + /** * gst_vaapi_decoder_put_buffer_data: * @decoder: a #GstVaapiDecoder @@ -334,8 +400,6 @@ gst_vaapi_decoder_put_buffer_data( ) { g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); - g_return_val_if_fail(buf, FALSE); - g_return_val_if_fail(buf_size > 0, FALSE); return push_buffer(decoder, create_buffer(buf, buf_size, FALSE)); } @@ -361,8 +425,6 @@ gst_vaapi_decoder_put_buffer_data_copy( ) { g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); - g_return_val_if_fail(buf, FALSE); - g_return_val_if_fail(buf_size > 0, FALSE); return push_buffer(decoder, create_buffer(buf, buf_size, TRUE)); } @@ -383,9 +445,8 @@ gboolean gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf) { g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); - g_return_val_if_fail(GST_IS_BUFFER(buf), FALSE); - return push_buffer(decoder, gst_buffer_ref(buf)); + return push_buffer(decoder, buf ? gst_buffer_ref(buf) : NULL); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index bfc05a7b84..fed19005b4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -63,6 +63,17 @@ G_BEGIN_DECLS #define GST_VAAPI_DECODER_CODEC(decoder) \ GST_VAAPI_DECODER_CAST(decoder)->priv->codec +/** + * GST_VAAPI_DECODER_IS_EOS: + * @decoder: a #GstVaapiDecoder + * + * Macro that checks if the @decoder reached an End-Of-Stream. + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_DECODER_IS_EOS +#define GST_VAAPI_DECODER_IS_EOS(decoder) \ + GST_VAAPI_DECODER_CAST(decoder)->priv->is_eos + #define GST_VAAPI_DECODER_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ GST_VAAPI_TYPE_DECODER, \ @@ -80,6 +91,7 @@ struct _GstVaapiDecoderPrivate { GCond *surfaces_cond; GThread *decoder_thread; guint decoder_thread_cancel : 1; + guint is_eos : 1; }; gboolean diff --git a/tests/test-decode.c b/tests/test-decode.c index a08383f7ff..7702f60f67 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -120,7 +120,7 @@ main(int argc, char *argv[]) if (!gst_vaapi_decoder_put_buffer_data(decoder, vdata, vdata_size)) g_error("could not send video data to the decoder"); - if (0 && !gst_vaapi_decoder_put_buffer(decoder, NULL)) + if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) g_error("could not send EOS to the decoder"); if (TIMEOUT < 0) { From eddf6b0d6c919a5d134bb4aa8a6a93f4ebb14b07 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 26 Apr 2010 13:30:27 +0000 Subject: [PATCH 0266/3781] Fix gst_vaapi_profile_get_codec(). Improve gst_vaapi_profile_from_caps() for H.264 & caps with "codec-data". --- gst-libs/gst/vaapi/gstvaapiprofile.c | 75 +++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 385228b039..ae1d909f9a 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -25,9 +25,13 @@ #include "config.h" #include +#include #include "gstvaapicompat.h" #include "gstvaapiprofile.h" +#define GST_VAAPI_PROFILE_CODEC(profile) \ + ((GstVaapiCodec)(((guint32)profile) & GST_MAKE_FOURCC(0xff,0xff,0xff,0))) + typedef struct _GstVaapiProfileMap GstVaapiProfileMap; typedef struct _GstVaapiEntrypointMap GstVaapiEntrypointMap; @@ -136,6 +140,51 @@ gst_vaapi_profile(VAProfile profile) return 0; } +/** + * gst_vaapi_profile_from_codec_data: + * @codec: a #GstVaapiCodec + * @buffer: a #GstBuffer holding code data + * + * Tries to parse VA profile from @buffer data and @codec information. + * + * Return value: the #GstVaapiProfile described in @buffer + */ +static GstVaapiProfile +gst_vaapi_profile_from_codec_data_h264(GstBuffer *buffer) +{ + /* MPEG-4 Part 15: Advanced Video Coding (AVC) file format */ + uint8_t * const buf = GST_BUFFER_DATA(buffer); + + if (buf[0] != 1) /* configurationVersion = 1 */ + return 0; + + switch (buf[1]) { /* AVCProfileIndication */ + case 66: return GST_VAAPI_PROFILE_H264_BASELINE; + case 77: return GST_VAAPI_PROFILE_H264_MAIN; + case 100: return GST_VAAPI_PROFILE_H264_HIGH; + } + return 0; +} + +static GstVaapiProfile +gst_vaapi_profile_from_codec_data(GstVaapiCodec codec, GstBuffer *buffer) +{ + GstVaapiProfile profile; + + if (!codec || !buffer) + return 0; + + switch (codec) { + case GST_VAAPI_CODEC_H264: + profile = gst_vaapi_profile_from_codec_data_h264(buffer); + break; + default: + profile = 0; + break; + } + return profile; +} + /** * gst_vaapi_profile_from_caps: * @caps: a #GstCaps @@ -152,9 +201,10 @@ gst_vaapi_profile_from_caps(GstCaps *caps) const GstVaapiProfileMap *m; GstCaps *caps_test; GstStructure *structure; + GstVaapiProfile profile; + GstBuffer *codec_data = NULL; const gchar *name; gsize namelen; - gboolean found; if (!caps) return 0; @@ -166,15 +216,28 @@ gst_vaapi_profile_from_caps(GstCaps *caps) name = gst_structure_get_name(structure); namelen = strlen(name); - found = FALSE; - for (m = gst_vaapi_profiles; !found && m->profile; m++) { + if (!gst_structure_has_field(structure, "profile")) { + const GValue *v_codec_data; + v_codec_data = gst_structure_get_value(structure, "codec_data"); + if (v_codec_data) + codec_data = gst_value_get_buffer(v_codec_data); + } + + profile = 0; + for (m = gst_vaapi_profiles; !profile && m->profile; m++) { if (strncmp(name, m->caps_str, namelen) != 0) continue; caps_test = gst_caps_from_string(m->caps_str); - found = gst_caps_is_always_compatible(caps_test, caps); + if (gst_caps_is_always_compatible(caps, caps_test)) + profile = m->profile; + else if (codec_data) + profile = gst_vaapi_profile_from_codec_data( + GST_VAAPI_PROFILE_CODEC(m->profile), + codec_data + ); gst_caps_unref(caps_test); } - return found ? m->va_profile : 0; + return profile; } /** @@ -223,7 +286,7 @@ gst_vaapi_profile_get_caps(GstVaapiProfile profile) GstVaapiCodec gst_vaapi_profile_get_codec(GstVaapiProfile profile) { - return (GstVaapiCodec)(((guint32)profile) & 0xffffff00); + return GST_VAAPI_PROFILE_CODEC(profile); } /** From 29f1784dd705f6ea007eb4fc77584b5a0132e311 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 27 Apr 2010 11:59:23 +0000 Subject: [PATCH 0267/3781] Add more error codes. Fix documentation. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 10 +++++++--- gst-libs/gst/vaapi/gstvaapidecoder.h | 10 ++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index dabb8aa369..2c07c57496 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -73,7 +73,10 @@ decoder_thread_cb(gpointer data) g_mutex_unlock(priv->adapter_mutex); if (!priv->decoder_thread_cancel) { - if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) { + switch (status) { + case GST_VAAPI_DECODER_STATUS_SUCCESS: + case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: + GST_DEBUG("decode"); g_object_ref(decoder); status = klass->decode(decoder); g_object_unref(decoder); @@ -85,8 +88,8 @@ decoder_thread_cb(gpointer data) status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM; GST_DEBUG("decode frame (status = %d)", status); - } - else { + break; + default: /* XXX: something went wrong, simply destroy any buffer until this decoder is destroyed */ g_mutex_lock(priv->adapter_mutex); @@ -96,6 +99,7 @@ decoder_thread_cb(gpointer data) /* Signal the main thread we got an error */ if (status != GST_VAAPI_DECODER_STATUS_END_OF_STREAM) gst_vaapi_decoder_push_surface(decoder, NULL); + break; } } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 4c2d4c0728..3a33db086c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -60,8 +60,12 @@ typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; * GstVaapiDecoderStatus: * @GST_VAAPI_DECODER_STATUS_SUCCESS: Success. * @GST_VAAPI_DECODER_STATUS_TIMEOUT: Timeout. Try again later. - * @GST_VAAPI_DECODER_STATUS_EOS: End-Of-Stream. - * @GST_VAAPI_DECODER_STATUS_ERROR: Unknown error. + * @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_NO_DATA: Not enough input data to decode. + * @GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE: Invalid surface. + * @GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN: Unknown error. * * Decoder status for gst_vaapi_decoder_get_surface(). */ @@ -71,6 +75,8 @@ enum _GstVaapiDecoderStatus { 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_NO_DATA, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN }; From cc28cdbd606f020b84af45991fcf1bc6ac74f3b1 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 27 Apr 2010 15:26:19 +0000 Subject: [PATCH 0268/3781] - Add PTS and framerate information. - Simplify parsing with an AVCodeParserContext. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 382 ++++++++------------ gst-libs/gst/vaapi/gstvaapidecoder.h | 16 +- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 327 +++++------------ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 54 +-- 4 files changed, 265 insertions(+), 514 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 2c07c57496..d9e17ebdda 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -50,66 +50,59 @@ gst_vaapi_decoder_start(GstVaapiDecoder *decoder); static gboolean gst_vaapi_decoder_stop(GstVaapiDecoder *decoder); +static GstBuffer * +pop_buffer(GstVaapiDecoder *decoder); + static gpointer decoder_thread_cb(gpointer data) { GstVaapiDecoder * const decoder = data; GstVaapiDecoderPrivate * const priv = decoder->priv; GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); - GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; - - if (!klass->decode) { - g_error("unimplemented GstVaapiDecoder::decode() function"); - return NULL; - } + GstBuffer *buffer; + g_object_ref(decoder); while (!priv->decoder_thread_cancel) { - g_mutex_lock(priv->adapter_mutex); - while (!gst_adapter_available(priv->adapter)) { - g_cond_wait(priv->adapter_cond, priv->adapter_mutex); - if (priv->decoder_thread_cancel) - break; - } - g_mutex_unlock(priv->adapter_mutex); - - if (!priv->decoder_thread_cancel) { - switch (status) { - case GST_VAAPI_DECODER_STATUS_SUCCESS: - case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: - GST_DEBUG("decode"); - g_object_ref(decoder); - status = klass->decode(decoder); - g_object_unref(decoder); - - /* Detect End-of-Stream conditions */ - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS && - priv->is_eos && - gst_vaapi_decoder_read_avail(decoder) == 0) - status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM; - - GST_DEBUG("decode frame (status = %d)", status); - break; - default: - /* XXX: something went wrong, simply destroy any - buffer until this decoder is destroyed */ - g_mutex_lock(priv->adapter_mutex); - gst_adapter_clear(priv->adapter); - g_mutex_unlock(priv->adapter_mutex); - - /* Signal the main thread we got an error */ - if (status != GST_VAAPI_DECODER_STATUS_END_OF_STREAM) - gst_vaapi_decoder_push_surface(decoder, NULL); - break; - } - } - - /* End-of-Stream reached, decoder thread is no longer necessary */ - if (status == GST_VAAPI_DECODER_STATUS_END_OF_STREAM) + buffer = pop_buffer(decoder); + priv->decoder_status = klass->decode(decoder, buffer); + GST_DEBUG("decode frame (status = %d)", priv->decoder_status); + switch (priv->decoder_status) { + case GST_VAAPI_DECODER_STATUS_SUCCESS: + case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: break; + default: + priv->decoder_thread_cancel = TRUE; + break; + } + gst_buffer_unref(buffer); } + g_object_unref(decoder); return NULL; } +static inline void +init_buffer(GstBuffer *buffer, const guchar *buf, guint buf_size) +{ + GST_BUFFER_DATA(buffer) = (guint8 *)buf; + GST_BUFFER_SIZE(buffer) = buf_size; + GST_BUFFER_TIMESTAMP(buffer) = GST_CLOCK_TIME_NONE; + GST_BUFFER_DURATION(buffer) = GST_CLOCK_TIME_NONE; +} + +static inline GstBuffer * +create_eos_buffer(void) +{ + GstBuffer *buffer; + + buffer = gst_buffer_new(); + if (!buffer) + return NULL; + + init_buffer(buffer, NULL, 0); + GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_EOS); + return buffer; +} + static GstBuffer * create_buffer(const guchar *buf, guint buf_size, gboolean copy) { @@ -129,13 +122,9 @@ create_buffer(const guchar *buf, guint buf_size, gboolean copy) return NULL; } memcpy(buffer->malloc_data, buf, buf_size); - GST_BUFFER_DATA(buffer) = buffer->malloc_data; - GST_BUFFER_SIZE(buffer) = buf_size; - } - else { - GST_BUFFER_DATA(buffer) = (guint8 *)buf; - GST_BUFFER_SIZE(buffer) = buf_size; + buf = buffer->malloc_data; } + init_buffer(buffer, buf, buf_size); return buffer; } @@ -145,31 +134,42 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) GstVaapiDecoderPrivate * const priv = decoder->priv; if (!buffer) { - priv->is_eos = TRUE; - return TRUE; + buffer = create_eos_buffer(); + if (!buffer) + return FALSE; } - g_return_val_if_fail(priv->adapter_mutex && priv->adapter_cond, FALSE); - GST_DEBUG("queue encoded data buffer %p (%d bytes)", buffer, GST_BUFFER_SIZE(buffer)); if (!priv->decoder_thread && !gst_vaapi_decoder_start(decoder)) return FALSE; - /* XXX: add a mechanism to wait for enough buffer bytes to be consumed */ - g_mutex_lock(priv->adapter_mutex); - gst_adapter_push(priv->adapter, buffer); - g_cond_signal(priv->adapter_cond); - g_mutex_unlock(priv->adapter_mutex); + g_async_queue_push(priv->buffers, buffer); return TRUE; } -static void -unref_surface_cb(gpointer surface, gpointer user_data) +static GstBuffer * +pop_buffer(GstVaapiDecoder *decoder) { - if (surface) - g_object_unref(GST_VAAPI_SURFACE(surface)); + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstBuffer *buffer; + + buffer = g_async_queue_pop(priv->buffers); + g_return_val_if_fail(buffer, NULL); + + if (!GST_BUFFER_TIMESTAMP_IS_VALID(buffer)) + GST_BUFFER_TIMESTAMP(buffer) = priv->next_ts; + return buffer; +} + +static void +clear_async_queue(GAsyncQueue *q) +{ + guint i, qlen = g_async_queue_length(q); + + for (i = 0; i < qlen; i++) + g_object_unref(g_async_queue_pop(q)); } static void @@ -180,37 +180,21 @@ gst_vaapi_decoder_finalize(GObject *object) gst_vaapi_decoder_stop(decoder); - if (priv->adapter) { - gst_adapter_clear(priv->adapter); - g_object_unref(priv->adapter); - priv->adapter = NULL; - } - - if (priv->adapter_cond) { - g_cond_free(priv->adapter_cond); - priv->adapter_cond = NULL; - } - - if (priv->adapter_mutex) { - g_mutex_free(priv->adapter_mutex); - priv->adapter_mutex = NULL; - } - if (priv->context) { g_object_unref(priv->context); priv->context = NULL; } - g_queue_foreach(&priv->surfaces, unref_surface_cb, NULL); - - if (priv->surfaces_cond) { - g_cond_free(priv->surfaces_cond); - priv->surfaces_cond = NULL; + if (priv->buffers) { + clear_async_queue(priv->buffers); + g_object_unref(priv->buffers); + priv->buffers = NULL; } - if (priv->surfaces_mutex) { - g_mutex_free(priv->surfaces_mutex); - priv->surfaces_mutex = NULL; + if (priv->surfaces) { + clear_async_queue(priv->surfaces); + g_object_unref(priv->surfaces); + priv->surfaces = NULL; } if (priv->display) { @@ -310,16 +294,13 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) decoder->priv = priv; priv->context = NULL; priv->codec = 0; - priv->adapter = gst_adapter_new(); - priv->adapter_mutex = g_mutex_new(); - priv->adapter_cond = g_cond_new(); - priv->surfaces_mutex = g_mutex_new(); - priv->surfaces_cond = g_cond_new(); + priv->fps_n = 1000; + priv->fps_d = 30; + priv->next_ts = 0; + priv->buffers = g_async_queue_new(); + priv->surfaces = g_async_queue_new(); priv->decoder_thread = NULL; priv->decoder_thread_cancel = FALSE; - priv->is_eos = FALSE; - - g_queue_init(&priv->surfaces); } /** @@ -367,18 +348,62 @@ gst_vaapi_decoder_stop(GstVaapiDecoder *decoder) GstVaapiDecoderPrivate * const priv = decoder->priv; if (priv->decoder_thread) { + push_buffer(decoder, NULL); priv->decoder_thread_cancel = TRUE; - if (priv->adapter_mutex && priv->adapter_cond) { - g_mutex_lock(priv->adapter_mutex); - g_cond_signal(priv->adapter_cond); - g_mutex_unlock(priv->adapter_mutex); - } g_thread_join(priv->decoder_thread); priv->decoder_thread = NULL; } return TRUE; } +/** + * gst_vaapi_decoder_get_frame_rate: + * @decoder: a #GstVaapiDecoder + * @num: return location for the numerator of the frame rate + * @den: return location for the denominator of the frame rate + * + * Retrieves the current frame rate as the fraction @num / @den. The + * default frame rate is 30 fps. + */ +void +gst_vaapi_decoder_get_frame_rate( + GstVaapiDecoder *decoder, + guint *num, + guint *den +) +{ + g_return_if_fail(GST_VAAPI_IS_DECODER(decoder)); + + if (num) + *num = decoder->priv->fps_n; + + if (den) + *den = decoder->priv->fps_d; +} + +/** + * gst_vaapi_decoder_set_frame_rate: + * @decoder: a #GstVaapiDecoder + * @num: the numerator of the frame rate + * @den: the denominator of the frame rate + * + * Sets the frame rate for the stream to @num / @den. By default, the + * decoder will use the frame rate encoded in the elementary stream. + * If none is available, the decoder will default to 30 fps. + */ +void +gst_vaapi_decoder_set_frame_rate( + GstVaapiDecoder *decoder, + guint num, + guint den +) +{ + g_return_if_fail(GST_VAAPI_IS_DECODER(decoder)); + + decoder->priv->fps_n = num; + decoder->priv->fps_d = den; +} + /** * gst_vaapi_decoder_put_buffer_data: * @decoder: a #GstVaapiDecoder @@ -467,36 +492,35 @@ gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf) * or %NULL if none is available (e.g. an error). Caller owns the * returned object. g_object_unref() after usage. */ -static GstVaapiSurface * +static GstVaapiSurfaceProxy * _gst_vaapi_decoder_get_surface( GstVaapiDecoder *decoder, - GTimeVal *timeout, + GTimeVal *end_time, GstVaapiDecoderStatus *pstatus ) { GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiDecoderStatus status; GstVaapiSurface *surface; + GstVaapiSurfaceProxy *proxy = NULL; - g_mutex_lock(priv->surfaces_mutex); - while (g_queue_is_empty(&priv->surfaces)) - if (!g_cond_timed_wait(priv->surfaces_cond, priv->surfaces_mutex, timeout)) - break; - surface = g_queue_pop_head(&priv->surfaces); - g_mutex_unlock(priv->surfaces_mutex); + surface = g_async_queue_timed_pop(priv->surfaces, end_time); - if (surface) - *pstatus = GST_VAAPI_DECODER_STATUS_SUCCESS; - else { - g_mutex_lock(priv->adapter_mutex); - if (gst_adapter_available(priv->adapter)) - *pstatus = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - else if (timeout) - *pstatus = GST_VAAPI_DECODER_STATUS_TIMEOUT; - else - *pstatus = GST_VAAPI_DECODER_STATUS_END_OF_STREAM; - g_mutex_unlock(priv->adapter_mutex); + if (surface) { + proxy = gst_vaapi_surface_proxy_new(priv->context, surface); + status = (proxy ? + GST_VAAPI_DECODER_STATUS_SUCCESS : + GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED); + g_object_unref(surface); } - return surface; + else if (end_time) + status = GST_VAAPI_DECODER_STATUS_TIMEOUT; + else + status = priv->decoder_status; + + if (pstatus) + *pstatus = status; + return proxy; } GstVaapiSurfaceProxy * @@ -505,23 +529,9 @@ gst_vaapi_decoder_get_surface( GstVaapiDecoderStatus *pstatus ) { - GstVaapiSurfaceProxy *proxy = NULL; - GstVaapiSurface *surface; - GstVaapiDecoderStatus status; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - surface = _gst_vaapi_decoder_get_surface(decoder, NULL, &status); - if (surface) { - proxy = gst_vaapi_surface_proxy_new(decoder->priv->context, surface); - if (!proxy) - status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - g_object_unref(surface); - } - - if (pstatus) - *pstatus = status; - return proxy; + return _gst_vaapi_decoder_get_surface(decoder, NULL, pstatus); } /** @@ -545,9 +555,6 @@ gst_vaapi_decoder_timed_get_surface( GstVaapiDecoderStatus *pstatus ) { - GstVaapiSurfaceProxy *proxy = NULL; - GstVaapiSurface *surface; - GstVaapiDecoderStatus status; GTimeVal end_time; g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); @@ -555,17 +562,7 @@ gst_vaapi_decoder_timed_get_surface( g_get_current_time(&end_time); g_time_val_add(&end_time, timeout); - surface = _gst_vaapi_decoder_get_surface(decoder, &end_time, &status); - if (surface) { - proxy = gst_vaapi_surface_proxy_new(decoder->priv->context, surface); - if (!proxy) - status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - g_object_unref(surface); - } - - if (pstatus) - *pstatus = status; - return proxy; + return _gst_vaapi_decoder_get_surface(decoder, &end_time, pstatus); } gboolean @@ -593,73 +590,6 @@ gst_vaapi_decoder_ensure_context( return priv->context != NULL; } -guint -gst_vaapi_decoder_copy( - GstVaapiDecoder *decoder, - guint offset, - guchar *buf, - guint buf_size -) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - guint avail; - - if (!buf || !buf_size) - return 0; - - avail = gst_vaapi_decoder_read_avail(decoder); - if (offset >= avail) - return 0; - if (buf_size > avail - offset) - buf_size = avail - offset; - - if (buf_size > 0) { - g_mutex_lock(priv->adapter_mutex); - gst_adapter_copy(priv->adapter, buf, offset, buf_size); - g_mutex_unlock(priv->adapter_mutex); - } - return buf_size; -} - -guint -gst_vaapi_decoder_read_avail(GstVaapiDecoder *decoder) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - guint avail; - - g_mutex_lock(priv->adapter_mutex); - avail = gst_adapter_available(priv->adapter); - g_mutex_unlock(priv->adapter_mutex); - return avail; -} - -guint -gst_vaapi_decoder_read(GstVaapiDecoder *decoder, guchar *buf, guint buf_size) -{ - buf_size = gst_vaapi_decoder_copy(decoder, 0, buf, buf_size); - if (buf_size > 0) - gst_vaapi_decoder_flush(decoder, buf_size); - return buf_size; -} - -void -gst_vaapi_decoder_flush(GstVaapiDecoder *decoder, guint buf_size) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - guint avail; - - if (!buf_size) - return; - - avail = gst_vaapi_decoder_read_avail(decoder); - if (buf_size > avail) - buf_size = avail; - - g_mutex_lock(priv->adapter_mutex); - gst_adapter_flush(priv->adapter, buf_size); - g_mutex_unlock(priv->adapter_mutex); -} - gboolean gst_vaapi_decoder_push_surface( GstVaapiDecoder *decoder, @@ -668,15 +598,11 @@ gst_vaapi_decoder_push_surface( { GstVaapiDecoderPrivate * const priv = decoder->priv; - if (surface) - GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); - else - GST_DEBUG("queue null surface to signal an error"); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - g_mutex_lock(priv->surfaces_mutex); - g_queue_push_tail(&priv->surfaces, surface ? g_object_ref(surface) : NULL); - g_cond_signal(priv->surfaces_cond); - g_mutex_unlock(priv->surfaces_mutex); + GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); + + g_async_queue_push(priv->surfaces, g_object_ref(surface)); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 3a33db086c..4a96bb081a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -102,12 +102,26 @@ struct _GstVaapiDecoderClass { /*< private >*/ GObjectClass parent_class; - GstVaapiDecoderStatus (*decode)(GstVaapiDecoder *decoder); + GstVaapiDecoderStatus (*decode)(GstVaapiDecoder *decoder, GstBuffer *buffer); }; GType gst_vaapi_decoder_get_type(void); +void +gst_vaapi_decoder_get_frame_rate( + GstVaapiDecoder *decoder, + guint *num, + guint *den +); + +void +gst_vaapi_decoder_set_frame_rate( + GstVaapiDecoder *decoder, + guint num, + guint den +); + gboolean gst_vaapi_decoder_put_buffer_data( GstVaapiDecoder *decoder, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index d83e94d556..7a6d6edc76 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -44,9 +44,6 @@ G_DEFINE_TYPE(GstVaapiDecoderFfmpeg, GST_VAAPI_TYPE_DECODER_FFMPEG, \ GstVaapiDecoderFfmpegPrivate)) -/** Default I/O buffer size (32 KB) */ -#define DEFAULT_IOBUF_SIZE (32 * 1024) - typedef struct _GstVaapiContextFfmpeg GstVaapiContextFfmpeg; struct _GstVaapiContextFfmpeg { struct vaapi_context base; @@ -54,16 +51,10 @@ struct _GstVaapiContextFfmpeg { }; struct _GstVaapiDecoderFfmpegPrivate { - AVPacket packet; AVFrame *frame; - guchar *iobuf; - guint iobuf_pos; - guint iobuf_size; - ByteIOContext ioctx; - AVFormatContext *fmtctx; + AVCodecParserContext *pctx; AVCodecContext *avctx; GstVaapiContextFfmpeg *vactx; - guint video_stream_index; guint is_constructed : 1; }; @@ -82,21 +73,6 @@ get_codec_id_from_codec(GstVaapiCodec codec) return CODEC_ID_NONE; } -/** Converts codec to FFmpeg raw bitstream format */ -static const gchar * -get_raw_format_from_codec(GstVaapiCodec codec) -{ - switch (codec) { - case GST_VAAPI_CODEC_MPEG1: return "mpegvideo"; - case GST_VAAPI_CODEC_MPEG2: return "mpegvideo"; - case GST_VAAPI_CODEC_MPEG4: return "m4v"; - case GST_VAAPI_CODEC_H263: return "h263"; - case GST_VAAPI_CODEC_H264: return "h264"; - case GST_VAAPI_CODEC_VC1: return "vc1"; - } - return NULL; -} - /** Finds a suitable profile from FFmpeg context */ static GstVaapiProfile get_profile(AVCodecContext *avctx) @@ -159,101 +135,6 @@ get_profile(AVCodecContext *avctx) return 0; } -/** Probes FFmpeg format from input stream */ -static AVInputFormat * -get_probed_format(GstVaapiDecoder *decoder) -{ - GstVaapiDecoderFfmpegPrivate * const priv = - GST_VAAPI_DECODER_FFMPEG(decoder)->priv; - - AVProbeData pd; - pd.filename = ""; - pd.buf = priv->iobuf; - pd.buf_size = MIN(gst_vaapi_decoder_read_avail(decoder), priv->iobuf_size); - if (!gst_vaapi_decoder_copy(decoder, 0, pd.buf, pd.buf_size)) - return FALSE; - - GST_DEBUG("probing format from buffer %p [%d bytes]", pd.buf, pd.buf_size); - return av_probe_input_format(&pd, 1); -} - -/** Tries to get an FFmpeg format from the raw bitstream */ -static AVInputFormat * -get_raw_format(GstVaapiDecoder *decoder) -{ - const gchar *raw_format; - - raw_format = get_raw_format_from_codec(GST_VAAPI_DECODER_CODEC(decoder)); - if (!raw_format) - return NULL; - - GST_DEBUG("trying raw format %s", raw_format); - return av_find_input_format(raw_format); -} - -/** Flushes n bytes from the stream */ -static void -stream_flush(GstVaapiDecoder *decoder, int buf_size) -{ - GstVaapiDecoderFfmpegPrivate * const priv = - GST_VAAPI_DECODER_FFMPEG(decoder)->priv; - - gst_vaapi_decoder_flush(decoder, buf_size); - if (priv->iobuf_pos > buf_size) - priv->iobuf_pos -= buf_size; - else - priv->iobuf_pos = 0; -} - -/** Reads one packet */ -static int -stream_read(void *opaque, uint8_t *buf, int buf_size) -{ - GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(opaque); - GstVaapiDecoderFfmpegPrivate * const priv = - GST_VAAPI_DECODER_FFMPEG(decoder)->priv; - - if (buf_size > 0) { - buf_size = gst_vaapi_decoder_copy( - decoder, - priv->iobuf_pos, - buf, buf_size - ); - priv->iobuf_pos += buf_size; - } - return buf_size; -} - -/** Seeks into stream */ -static int64_t -stream_seek(void *opaque, int64_t offset, int whence) -{ - GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(opaque); - GstVaapiDecoderFfmpegPrivate * const priv = - GST_VAAPI_DECODER_FFMPEG(decoder)->priv; - - /* If we parsed the headers (decoder is constructed), we can no - longer seek into the stream */ - if (priv->is_constructed && - !((whence == SEEK_SET || whence == SEEK_CUR) && offset == 0)) - return -1; - - switch (whence) { - case SEEK_SET: - priv->iobuf_pos = offset; - break; - case SEEK_CUR: - priv->iobuf_pos += offset; - break; - case SEEK_END: - priv->iobuf_pos = gst_vaapi_decoder_read_avail(decoder) + offset; - break; - default: - return -1; - } - return priv->iobuf_pos; -} - /** AVCodecContext.get_format() implementation */ static enum PixelFormat gst_vaapi_decoder_ffmpeg_get_format(AVCodecContext *avctx, const enum PixelFormat *fmt) @@ -347,29 +228,22 @@ gst_vaapi_decoder_ffmpeg_destroy(GstVaapiDecoderFfmpeg *ffdecoder) { GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - if (priv->avctx) { - avcodec_close(priv->avctx); - priv->avctx = NULL; - } - if (priv->vactx) { g_free(priv->vactx); priv->vactx = NULL; } - if (priv->fmtctx) { - av_close_input_stream(priv->fmtctx); - priv->fmtctx = NULL; + if (priv->avctx) { + avcodec_close(priv->avctx); + priv->avctx = NULL; } - if (priv->iobuf) { - g_free(priv->iobuf); - priv->iobuf = NULL; - priv->iobuf_pos = 0; + if (priv->pctx) { + av_parser_close(priv->pctx); + priv->pctx = NULL; } av_freep(&priv->frame); - av_free_packet(&priv->packet); } static gboolean @@ -378,13 +252,28 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(ffdecoder); GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; GstVaapiCodec codec = GST_VAAPI_DECODER_CODEC(decoder); - enum CodecID codec_id = get_codec_id_from_codec(codec); - typedef AVInputFormat *(*GetFormatFunc)(GstVaapiDecoder *); - GetFormatFunc get_format[2]; - AVInputFormat *format; - AVStream *video_stream; + enum CodecID codec_id; AVCodec *ffcodec; - guint i; + + codec_id = get_codec_id_from_codec(codec); + if (codec_id == CODEC_ID_NONE) + return FALSE; + + ffcodec = avcodec_find_decoder(codec_id); + if (!ffcodec) + return FALSE; + + if (!priv->frame) { + priv->frame = avcodec_alloc_frame(); + if (!priv->frame) + return FALSE; + } + + if (!priv->avctx) { + priv->avctx = avcodec_alloc_context(); + if (!priv->avctx) + return FALSE; + } if (!priv->vactx) { priv->vactx = g_new(GstVaapiContextFfmpeg, 1); @@ -394,70 +283,6 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) memset(&priv->vactx->base, 0, sizeof(priv->vactx->base)); priv->vactx->decoder = ffdecoder; - if (!priv->frame) { - priv->frame = avcodec_alloc_frame(); - if (!priv->frame) - return FALSE; - } - - if (!priv->iobuf) { - priv->iobuf = g_malloc0(priv->iobuf_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!priv->iobuf) - return FALSE; - } - - get_format[ !codec] = get_raw_format; - get_format[!!codec] = get_probed_format; - for (i = 0; i < 2; i++) { - format = get_format[i](decoder); - if (!format) - continue; - - priv->iobuf_pos = 0; - init_put_byte( - &priv->ioctx, - priv->iobuf, - priv->iobuf_size, - 0, /* write flags */ - ffdecoder, - stream_read, - NULL, /* no packet writer callback */ - stream_seek - ); - priv->ioctx.is_streamed = 1; - - if (av_open_input_stream(&priv->fmtctx, &priv->ioctx, "", format, NULL) < 0) - continue; - - if (av_find_stream_info(priv->fmtctx) >= 0) - break; - - av_close_input_stream(priv->fmtctx); - priv->fmtctx = NULL; - } - if (!priv->fmtctx) - return FALSE; - - if (av_find_stream_info(priv->fmtctx) < 0) - return FALSE; - dump_format(priv->fmtctx, 0, "", 0); - - video_stream = NULL; - for (i = 0; i < priv->fmtctx->nb_streams; i++) { - AVStream * const stream = priv->fmtctx->streams[i]; - if (!video_stream && - stream->codec->codec_type == CODEC_TYPE_VIDEO && - (codec ? (stream->codec->codec_id == codec_id) : 1)) { - video_stream = stream; - } - else - stream->discard = AVDISCARD_ALL; - } - if (!video_stream) - return FALSE; - - priv->video_stream_index = video_stream->index; - priv->avctx = video_stream->codec; priv->avctx->hwaccel_context = priv->vactx; priv->avctx->get_format = gst_vaapi_decoder_ffmpeg_get_format; priv->avctx->get_buffer = gst_vaapi_decoder_ffmpeg_get_buffer; @@ -467,20 +292,24 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) priv->avctx->draw_horiz_band = NULL; priv->avctx->slice_flags = SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; - ffcodec = avcodec_find_decoder(priv->avctx->codec_id); - if (!ffcodec || avcodec_open(priv->avctx, ffcodec) < 0) + if (priv->pctx) + av_parser_close(priv->pctx); + priv->pctx = av_parser_init(codec_id); + if (!priv->pctx) return FALSE; - av_init_packet(&priv->packet); + /* XXX: lock display? */ + if (avcodec_open(priv->avctx, ffcodec) < 0) + return FALSE; return TRUE; } -static GstVaapiSurface * +static GstVaapiDecoderStatus decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) { GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(ffdecoder); - GstVaapiSurface *surface = NULL; + GstVaapiSurface *surface; int bytes_read, got_picture = 0; GST_VAAPI_DISPLAY_LOCK(display); @@ -491,51 +320,65 @@ decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) buf, buf_size ); GST_VAAPI_DISPLAY_UNLOCK(display); + if (bytes_read < 0) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + if (!got_picture) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - if (bytes_read > 0) - stream_flush(GST_VAAPI_DECODER_CAST(ffdecoder), bytes_read); + surface = gst_vaapi_context_find_surface_by_id( + GST_VAAPI_DECODER_CONTEXT(ffdecoder), + GPOINTER_TO_UINT(priv->frame->data[3]) + ); + if (!surface) + return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; - if (got_picture) { - surface = gst_vaapi_context_find_surface_by_id( - GST_VAAPI_DECODER_CONTEXT(ffdecoder), - GPOINTER_TO_UINT(priv->frame->data[3]) - ); - } - return surface; + gst_vaapi_decoder_push_surface(GST_VAAPI_DECODER_CAST(ffdecoder), surface); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } GstVaapiDecoderStatus -gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder) +gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) { GstVaapiDecoderFfmpeg * const ffdecoder = GST_VAAPI_DECODER_FFMPEG(decoder); GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - GstVaapiSurface *surface = NULL; - AVPacket packet; + GstVaapiDecoderStatus status; + GstClockTime inbuf_ts; + guchar *inbuf, *outbuf; + gint inbuf_size, outbuf_size; + gboolean got_frame; if (!priv->is_constructed) { priv->is_constructed = gst_vaapi_decoder_ffmpeg_create(ffdecoder); - if (!priv->is_constructed) { - gst_vaapi_decoder_ffmpeg_destroy(ffdecoder); + if (!priv->is_constructed) return GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED; + } + + inbuf = GST_BUFFER_DATA(buffer); + inbuf_size = GST_BUFFER_SIZE(buffer); + inbuf_ts = GST_BUFFER_TIMESTAMP(buffer); + + do { + int parsed_size = av_parser_parse( + priv->pctx, + priv->avctx, + &outbuf, &outbuf_size, + inbuf, inbuf_size, + inbuf_ts, inbuf_ts + ); + got_frame = outbuf && outbuf_size > 0; + GST_DEBUG("outbuf %p (%d bytes), got frame %d, parsed size %d", + outbuf, outbuf_size, got_frame, parsed_size); + + if (parsed_size > 0) { + inbuf += parsed_size; + inbuf_size -= parsed_size; } - } + } while (!got_frame && inbuf_size > 0); - av_init_packet(&packet); - while (av_read_frame(priv->fmtctx, &packet) == 0) { - if (packet.stream_index != priv->video_stream_index) - continue; + if (!got_frame && !GST_BUFFER_IS_EOS(buffer)) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - surface = decode_frame(ffdecoder, packet.data, packet.size); - if (surface) /* decode a single frame only */ - break; - } - if (!surface) - surface = decode_frame(ffdecoder, NULL, 0); - av_free_packet(&packet); - - if (surface && gst_vaapi_decoder_push_surface(decoder, surface)) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + return decode_frame(ffdecoder, outbuf, outbuf_size); } static void @@ -586,16 +429,10 @@ gst_vaapi_decoder_ffmpeg_init(GstVaapiDecoderFfmpeg *decoder) priv = GST_VAAPI_DECODER_FFMPEG_GET_PRIVATE(decoder); decoder->priv = priv; priv->frame = NULL; - priv->iobuf = NULL; - priv->iobuf_pos = 0; - priv->iobuf_size = DEFAULT_IOBUF_SIZE; - priv->fmtctx = NULL; + priv->pctx = NULL; priv->avctx = NULL; priv->vactx = NULL; - priv->video_stream_index = 0; priv->is_constructed = FALSE; - - av_init_packet(&priv->packet); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index fed19005b4..ab1c6f1b17 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -63,16 +63,11 @@ G_BEGIN_DECLS #define GST_VAAPI_DECODER_CODEC(decoder) \ GST_VAAPI_DECODER_CAST(decoder)->priv->codec -/** - * GST_VAAPI_DECODER_IS_EOS: - * @decoder: a #GstVaapiDecoder - * - * Macro that checks if the @decoder reached an End-Of-Stream. - * This is an internal macro that does not do any run-time type check. - */ -#undef GST_VAAPI_DECODER_IS_EOS -#define GST_VAAPI_DECODER_IS_EOS(decoder) \ - GST_VAAPI_DECODER_CAST(decoder)->priv->is_eos +/* 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), \ @@ -80,18 +75,17 @@ G_BEGIN_DECLS GstVaapiDecoderPrivate)) struct _GstVaapiDecoderPrivate { - GstVaapiDisplay *display; - GstVaapiContext *context; - GstVaapiCodec codec; - GstAdapter *adapter; - GMutex *adapter_mutex; - GCond *adapter_cond; - GQueue surfaces; - GMutex *surfaces_mutex; - GCond *surfaces_cond; + GstVaapiDisplay *display; + GstVaapiContext *context; + GstVaapiCodec codec; + guint fps_n; + guint fps_d; + GstClockTime next_ts; + GAsyncQueue *buffers; + GAsyncQueue *surfaces; GThread *decoder_thread; + GstVaapiDecoderStatus decoder_status; guint decoder_thread_cancel : 1; - guint is_eos : 1; }; gboolean @@ -103,26 +97,6 @@ gst_vaapi_decoder_ensure_context( guint height ) attribute_hidden; -guint -gst_vaapi_decoder_copy( - GstVaapiDecoder *decoder, - guint offset, - guchar *buf, - guint buf_size -) attribute_hidden; - -guint -gst_vaapi_decoder_read_avail(GstVaapiDecoder *decoder) - attribute_hidden; - -guint -gst_vaapi_decoder_read(GstVaapiDecoder *decoder, guchar *buf, guint buf_size) - attribute_hidden; - -void -gst_vaapi_decoder_flush(GstVaapiDecoder *decoder, guint buf_size) - attribute_hidden; - gboolean gst_vaapi_decoder_push_surface( GstVaapiDecoder *decoder, From 86afcbb02447288ccc33da965f5084870a3bf31d Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 28 Apr 2010 09:07:45 +0000 Subject: [PATCH 0269/3781] Fix check for VA-API enabled FFmpeg. --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 07b50abac2..10c258b59d 100644 --- a/configure.ac +++ b/configure.ac @@ -258,7 +258,8 @@ AC_CHECK_HEADERS([libavformat/avformat.h]) PKG_CHECK_MODULES(LIBAVCODEC, [libavcodec]) AC_CHECK_HEADERS([libavcodec/avcodec.h]) -AC_CHECK_HEADERS([libavcodec/vaapi.h]) +AC_CHECK_HEADERS([libavcodec/vaapi.h], [], + AC_MSG_ERROR([The system FFmpeg headers do not support VA-API])) AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) From 42248445f2babf0507214d69da3ad2633d711f50 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 28 Apr 2010 21:15:55 +0000 Subject: [PATCH 0270/3781] Cosmetics (extraneous variable, debug message). --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 7a6d6edc76..eae18eb118 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -341,7 +341,6 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) { GstVaapiDecoderFfmpeg * const ffdecoder = GST_VAAPI_DECODER_FFMPEG(decoder); GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - GstVaapiDecoderStatus status; GstClockTime inbuf_ts; guchar *inbuf, *outbuf; gint inbuf_size, outbuf_size; @@ -366,8 +365,6 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) inbuf_ts, inbuf_ts ); got_frame = outbuf && outbuf_size > 0; - GST_DEBUG("outbuf %p (%d bytes), got frame %d, parsed size %d", - outbuf, outbuf_size, got_frame, parsed_size); if (parsed_size > 0) { inbuf += parsed_size; From 664542fe2e4f7f06ef7ab0b8a26adaa13f602bd2 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 28 Apr 2010 21:20:19 +0000 Subject: [PATCH 0271/3781] Cosmetics (weird indentation). --- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index ab1c6f1b17..146c760de1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -79,13 +79,13 @@ struct _GstVaapiDecoderPrivate { GstVaapiContext *context; GstVaapiCodec codec; guint fps_n; - guint fps_d; - GstClockTime next_ts; - GAsyncQueue *buffers; - GAsyncQueue *surfaces; - GThread *decoder_thread; - GstVaapiDecoderStatus decoder_status; - guint decoder_thread_cancel : 1; + guint fps_d; + GstClockTime next_ts; + GAsyncQueue *buffers; + GAsyncQueue *surfaces; + GThread *decoder_thread; + GstVaapiDecoderStatus decoder_status; + guint decoder_thread_cancel : 1; }; gboolean From 89c094d659f909e0e5ed956382b68fcb14d8c4d8 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 28 Apr 2010 21:50:44 +0000 Subject: [PATCH 0272/3781] Add "codec-data" property for additional codec data. e.g. VC-1 sequence headers for elementary streams. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 33 +++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 30 +++++++++++++++---- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h | 6 +++- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 13 ++++++++ tests/test-decode.c | 2 +- 5 files changed, 76 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index d9e17ebdda..a2d9400a59 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -42,6 +42,7 @@ enum { PROP_DISPLAY, PROP_CODEC, + PROP_CODEC_DATA }; static gboolean @@ -163,6 +164,20 @@ pop_buffer(GstVaapiDecoder *decoder) return buffer; } +static inline void +set_codec_data(GstVaapiDecoder *decoder, GstBuffer *codec_data) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (priv->codec_data) { + gst_buffer_unref(priv->codec_data); + priv->codec_data = NULL; + } + + if (codec_data) + priv->codec_data = gst_buffer_ref(codec_data); +} + static void clear_async_queue(GAsyncQueue *q) { @@ -180,6 +195,8 @@ gst_vaapi_decoder_finalize(GObject *object) gst_vaapi_decoder_stop(decoder); + set_codec_data(decoder, NULL); + if (priv->context) { g_object_unref(priv->context); priv->context = NULL; @@ -222,6 +239,9 @@ gst_vaapi_decoder_set_property( case PROP_CODEC: priv->codec = g_value_get_uint(value); break; + case PROP_CODEC_DATA: + set_codec_data(GST_VAAPI_DECODER(object), gst_value_get_buffer(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -245,6 +265,9 @@ gst_vaapi_decoder_get_property( case PROP_CODEC: g_value_set_uint(value, priv->codec); break; + case PROP_CODEC_DATA: + gst_value_set_buffer(value, priv->codec_data); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -284,6 +307,15 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass) "The codec handled by the decoder", 0, G_MAXINT32, 0, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_CODEC_DATA, + gst_param_spec_mini_object("codec-data", + "Codec data", + "Extra codec data", + GST_TYPE_BUFFER, + G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -294,6 +326,7 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) decoder->priv = priv; priv->context = NULL; priv->codec = 0; + priv->codec_data = NULL; priv->fps_n = 1000; priv->fps_d = 30; priv->next_ts = 0; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index eae18eb118..6361eaf78b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -234,6 +234,7 @@ gst_vaapi_decoder_ffmpeg_destroy(GstVaapiDecoderFfmpeg *ffdecoder) } if (priv->avctx) { + av_freep(&priv->avctx->extradata); avcodec_close(priv->avctx); priv->avctx = NULL; } @@ -252,6 +253,7 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(ffdecoder); GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; GstVaapiCodec codec = GST_VAAPI_DECODER_CODEC(decoder); + GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); enum CodecID codec_id; AVCodec *ffcodec; @@ -275,6 +277,18 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) return FALSE; } + if (codec_data) { + const guchar *data = GST_BUFFER_DATA(codec_data); + const guint size = GST_BUFFER_SIZE(codec_data); + av_freep(&priv->avctx->extradata); + priv->avctx->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!priv->avctx->extradata) + return FALSE; + priv->avctx->extradata_size = size; + memcpy(priv->avctx->extradata, data, size); + memset(priv->avctx->extradata + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + } + if (!priv->vactx) { priv->vactx = g_new(GstVaapiContextFfmpeg, 1); if (!priv->vactx) @@ -436,21 +450,25 @@ gst_vaapi_decoder_ffmpeg_init(GstVaapiDecoderFfmpeg *decoder) * gst_vaapi_decoder_ffmpeg_new: * @display: a #GstVaapiDisplay * @codec: a #GstVaapiCodec + * @codec_data: an optional #GstBuffer holding extra codec data, or %NULL * * Creates a new #GstVaapiDecoder with the specified @codec bound to - * @display. If @codec is zero, the first video stream will be - * selected. Otherwise, the first video stream matching @codec is - * used, if any. + * @display. @codec_data holds extra codec data like sequence headers. * * Return value: the newly allocated #GstVaapiDecoder object */ GstVaapiDecoder * -gst_vaapi_decoder_ffmpeg_new(GstVaapiDisplay *display, GstVaapiCodec codec) +gst_vaapi_decoder_ffmpeg_new( + GstVaapiDisplay *display, + GstVaapiCodec codec, + GstBuffer *codec_data +) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); return g_object_new(GST_VAAPI_TYPE_DECODER_FFMPEG, - "display", display, - "codec", codec, + "display", display, + "codec", codec, + "codec-data", codec_data, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h index 184759a687..487a9a66aa 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h @@ -79,7 +79,11 @@ GType gst_vaapi_decoder_ffmpeg_get_type(void); GstVaapiDecoder * -gst_vaapi_decoder_ffmpeg_new(GstVaapiDisplay *display, GstVaapiCodec codec); +gst_vaapi_decoder_ffmpeg_new( + GstVaapiDisplay *display, + GstVaapiCodec codec, + GstBuffer *codec_data +); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 146c760de1..e5f87e6ecd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -63,6 +63,18 @@ G_BEGIN_DECLS #define GST_VAAPI_DECODER_CODEC(decoder) \ GST_VAAPI_DECODER_CAST(decoder)->priv->codec +/** + * 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_CAST(decoder)->priv->codec_data + /* End-of-Stream buffer */ #define GST_BUFFER_FLAG_EOS (GST_BUFFER_FLAG_LAST + 0) @@ -78,6 +90,7 @@ struct _GstVaapiDecoderPrivate { GstVaapiDisplay *display; GstVaapiContext *context; GstVaapiCodec codec; + GstBuffer *codec_data; guint fps_n; guint fps_d; GstClockTime next_ts; diff --git a/tests/test-decode.c b/tests/test-decode.c index 7702f60f67..f076ec1e7b 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -114,7 +114,7 @@ main(int argc, char *argv[]) g_error("could not create window"); codec->get_video_data(&vdata, &vdata_size); - decoder = gst_vaapi_decoder_ffmpeg_new(display, codec->codec); + decoder = gst_vaapi_decoder_ffmpeg_new(display, codec->codec, NULL); if (!decoder) g_error("could not create FFmpeg decoder"); From ff193a22b9ba785e7b7ef20fcad130884ebfd446 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 28 Apr 2010 21:58:58 +0000 Subject: [PATCH 0273/3781] Move gst_vaapi_decoder_ffmpeg_create() call to object constructor. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 22 ++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 6361eaf78b..a41e1c92df 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -360,11 +360,8 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) gint inbuf_size, outbuf_size; gboolean got_frame; - if (!priv->is_constructed) { - priv->is_constructed = gst_vaapi_decoder_ffmpeg_create(ffdecoder); - if (!priv->is_constructed) - return GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED; - } + g_return_val_if_fail(priv->is_constructed, + GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); inbuf = GST_BUFFER_DATA(buffer); inbuf_size = GST_BUFFER_SIZE(buffer); @@ -402,6 +399,20 @@ gst_vaapi_decoder_ffmpeg_finalize(GObject *object) G_OBJECT_CLASS(gst_vaapi_decoder_ffmpeg_parent_class)->finalize(object); } +static void +gst_vaapi_decoder_ffmpeg_constructed(GObject *object) +{ + GstVaapiDecoderFfmpeg * const ffdecoder = GST_VAAPI_DECODER_FFMPEG(object); + GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; + GObjectClass *parent_class; + + parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_ffmpeg_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); + + priv->is_constructed = gst_vaapi_decoder_ffmpeg_create(ffdecoder); +} + static void gst_vaapi_decoder_ffmpeg_class_init(GstVaapiDecoderFfmpegClass *klass) { @@ -411,6 +422,7 @@ gst_vaapi_decoder_ffmpeg_class_init(GstVaapiDecoderFfmpegClass *klass) g_type_class_add_private(klass, sizeof(GstVaapiDecoderFfmpegPrivate)); object_class->finalize = gst_vaapi_decoder_ffmpeg_finalize; + object_class->constructed = gst_vaapi_decoder_ffmpeg_constructed; decoder_class->decode = gst_vaapi_decoder_ffmpeg_decode; } From 61ae27d84cb9ac5e1390f7f185af184addf4deba Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 28 Apr 2010 22:16:10 +0000 Subject: [PATCH 0274/3781] Split decoder creation with actual resources allocation and codec setup (probe). This fixes a memory leak (avctx, pctx) on destroy and most interestingly makes it possible to detect unsupported codecs. --- gst-libs/gst/vaapi/gstvaapidecoder.h | 2 + gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 76 ++++++++++++++------- 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 4a96bb081a..b11cf00d13 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -63,6 +63,7 @@ typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; * @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_INVALID_SURFACE: Invalid surface. * @GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN: Unknown error. @@ -75,6 +76,7 @@ enum _GstVaapiDecoderStatus { 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_INVALID_SURFACE, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index a41e1c92df..d8e01e9dc0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -56,6 +56,7 @@ struct _GstVaapiDecoderFfmpegPrivate { AVCodecContext *avctx; GstVaapiContextFfmpeg *vactx; guint is_constructed : 1; + guint is_open : 1; }; /** Converts codec to FFmpeg codec id */ @@ -224,38 +225,30 @@ gst_vaapi_decoder_ffmpeg_release_buffer(AVCodecContext *avctx, AVFrame *pic) } static void -gst_vaapi_decoder_ffmpeg_destroy(GstVaapiDecoderFfmpeg *ffdecoder) +gst_vaapi_decoder_ffmpeg_close(GstVaapiDecoderFfmpeg *ffdecoder) { GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - if (priv->vactx) { - g_free(priv->vactx); - priv->vactx = NULL; - } - if (priv->avctx) { av_freep(&priv->avctx->extradata); avcodec_close(priv->avctx); - priv->avctx = NULL; } - if (priv->pctx) { + if (priv->pctx) av_parser_close(priv->pctx); - priv->pctx = NULL; - } - - av_freep(&priv->frame); } static gboolean -gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) +gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffer) { - GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(ffdecoder); GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - GstVaapiCodec codec = GST_VAAPI_DECODER_CODEC(decoder); - GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); + GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(ffdecoder); + GstVaapiCodec codec = GST_VAAPI_DECODER_CODEC(ffdecoder); enum CodecID codec_id; AVCodec *ffcodec; + int ret; + + gst_vaapi_decoder_ffmpeg_close(ffdecoder); codec_id = get_codec_id_from_codec(codec); if (codec_id == CODEC_ID_NONE) @@ -265,6 +258,40 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) if (!ffcodec) return FALSE; + priv->pctx = av_parser_init(codec_id); + if (!priv->pctx) + return FALSE; + + GST_VAAPI_DISPLAY_LOCK(display); + ret = avcodec_open(priv->avctx, ffcodec); + GST_VAAPI_DISPLAY_UNLOCK(display); + return ret == 0; +} + +static void +gst_vaapi_decoder_ffmpeg_destroy(GstVaapiDecoderFfmpeg *ffdecoder) +{ + GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; + + gst_vaapi_decoder_ffmpeg_close(ffdecoder); + + if (priv->vactx) { + g_free(priv->vactx); + priv->vactx = NULL; + } + + av_freep(&priv->avctx); + av_freep(&priv->pctx); + av_freep(&priv->frame); +} + +static gboolean +gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) +{ + GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(ffdecoder); + GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; + GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); + if (!priv->frame) { priv->frame = avcodec_alloc_frame(); if (!priv->frame) @@ -305,16 +332,6 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) priv->avctx->thread_count = 1; priv->avctx->draw_horiz_band = NULL; priv->avctx->slice_flags = SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; - - if (priv->pctx) - av_parser_close(priv->pctx); - priv->pctx = av_parser_init(codec_id); - if (!priv->pctx) - return FALSE; - - /* XXX: lock display? */ - if (avcodec_open(priv->avctx, ffcodec) < 0) - return FALSE; return TRUE; } @@ -363,6 +380,12 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) g_return_val_if_fail(priv->is_constructed, GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); + if (!priv->is_open) { + priv->is_open = gst_vaapi_decoder_ffmpeg_open(ffdecoder, buffer); + if (!priv->is_open) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + } + inbuf = GST_BUFFER_DATA(buffer); inbuf_size = GST_BUFFER_SIZE(buffer); inbuf_ts = GST_BUFFER_TIMESTAMP(buffer); @@ -456,6 +479,7 @@ gst_vaapi_decoder_ffmpeg_init(GstVaapiDecoderFfmpeg *decoder) priv->avctx = NULL; priv->vactx = NULL; priv->is_constructed = FALSE; + priv->is_open = FALSE; } /** From 1def875b95cadd9bbea1cdfcaf5de09da828ede7 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 28 Apr 2010 22:30:50 +0000 Subject: [PATCH 0275/3781] Fix VC-1 codec initialization, it really needs an extradata buffer. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 31 +++++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index d8e01e9dc0..6ab342c53d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -136,6 +136,20 @@ get_profile(AVCodecContext *avctx) return 0; } +/** Sets AVCodecContext.extradata with additional codec data */ +static gboolean +set_codec_data(AVCodecContext *avctx, const guchar *buf, guint buf_size) +{ + av_freep(&avctx->extradata); + avctx->extradata = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return FALSE; + avctx->extradata_size = buf_size; + memcpy(avctx->extradata, buf, buf_size); + memset(avctx->extradata + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + return TRUE; +} + /** AVCodecContext.get_format() implementation */ static enum PixelFormat gst_vaapi_decoder_ffmpeg_get_format(AVCodecContext *avctx, const enum PixelFormat *fmt) @@ -262,6 +276,16 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe if (!priv->pctx) return FALSE; + /* XXX: av_find_stream_info() does this and some codecs really + want hard an extradata buffer for initialization (e.g. VC-1) */ + if (!priv->avctx->extradata && priv->pctx->parser->split) { + const guchar *buf = GST_BUFFER_DATA(buffer); + guint buf_size = GST_BUFFER_SIZE(buffer); + buf_size = priv->pctx->parser->split(priv->avctx, buf, buf_size); + if (buf_size > 0 && !set_codec_data(priv->avctx, buf, buf_size)) + return FALSE; + } + GST_VAAPI_DISPLAY_LOCK(display); ret = avcodec_open(priv->avctx, ffcodec); GST_VAAPI_DISPLAY_UNLOCK(display); @@ -307,13 +331,8 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) if (codec_data) { const guchar *data = GST_BUFFER_DATA(codec_data); const guint size = GST_BUFFER_SIZE(codec_data); - av_freep(&priv->avctx->extradata); - priv->avctx->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!priv->avctx->extradata) + if (!set_codec_data(priv->avctx, data, size)) return FALSE; - priv->avctx->extradata_size = size; - memcpy(priv->avctx->extradata, data, size); - memset(priv->avctx->extradata + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); } if (!priv->vactx) { From 1c48fa3a23f0cb4c2aa4a53e66ba9fde00861e97 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 28 Apr 2010 23:09:52 +0000 Subject: [PATCH 0276/3781] Make sure gst_vaapi_decoder_get_surface() gets unblocked on error. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 101 ++++++++++++++++++++------- 1 file changed, 74 insertions(+), 27 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index a2d9400a59..2820048c59 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -37,6 +37,13 @@ G_DEFINE_TYPE(GstVaapiDecoder, gst_vaapi_decoder, G_TYPE_OBJECT); +/* XXX: Make it a GstVaapiDecodedSurface + propagate PTS */ +typedef struct _DecodedSurface DecodedSurface; +struct _DecodedSurface { + GstVaapiSurfaceProxy *proxy; + GstVaapiDecoderStatus status; +}; + enum { PROP_0, @@ -54,6 +61,12 @@ gst_vaapi_decoder_stop(GstVaapiDecoder *decoder); static GstBuffer * pop_buffer(GstVaapiDecoder *decoder); +static gboolean +push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface); + +static DecodedSurface * +pop_surface(GstVaapiDecoder *decoder, GTimeVal *end_time); + static gpointer decoder_thread_cb(gpointer data) { @@ -72,6 +85,8 @@ decoder_thread_cb(gpointer data) case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: break; default: + /* Send an empty surface to signal an error */ + push_surface(decoder, NULL); priv->decoder_thread_cancel = TRUE; break; } @@ -164,6 +179,50 @@ pop_buffer(GstVaapiDecoder *decoder) return buffer; } +static inline DecodedSurface * +create_surface(void) +{ + return g_slice_new0(DecodedSurface); +} + +static inline void +destroy_surface(DecodedSurface *ds) +{ + g_slice_free(DecodedSurface, ds); +} + +static gboolean +push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiDecoderStatus status = priv->decoder_status; + DecodedSurface *ds; + + ds = create_surface(); + if (!ds) + return FALSE; + + if (surface) { + GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); + ds->proxy = gst_vaapi_surface_proxy_new(priv->context, surface); + if (!ds->proxy) + status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + ds->status = status; + + g_async_queue_push(priv->surfaces, ds); + return TRUE; +} + +static inline DecodedSurface * +pop_surface(GstVaapiDecoder *decoder, GTimeVal *end_time) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + return g_async_queue_timed_pop(priv->surfaces, end_time); +} + static inline void set_codec_data(GstVaapiDecoder *decoder, GstBuffer *codec_data) { @@ -179,12 +238,12 @@ set_codec_data(GstVaapiDecoder *decoder, GstBuffer *codec_data) } static void -clear_async_queue(GAsyncQueue *q) +clear_async_queue(GAsyncQueue *q, GDestroyNotify destroy) { guint i, qlen = g_async_queue_length(q); for (i = 0; i < qlen; i++) - g_object_unref(g_async_queue_pop(q)); + destroy(g_async_queue_pop(q)); } static void @@ -203,13 +262,13 @@ gst_vaapi_decoder_finalize(GObject *object) } if (priv->buffers) { - clear_async_queue(priv->buffers); + clear_async_queue(priv->buffers, (GDestroyNotify)g_object_unref); g_object_unref(priv->buffers); priv->buffers = NULL; } if (priv->surfaces) { - clear_async_queue(priv->surfaces); + clear_async_queue(priv->surfaces, (GDestroyNotify)destroy_surface); g_object_unref(priv->surfaces); priv->surfaces = NULL; } @@ -532,24 +591,20 @@ _gst_vaapi_decoder_get_surface( GstVaapiDecoderStatus *pstatus ) { - GstVaapiDecoderPrivate * const priv = decoder->priv; GstVaapiDecoderStatus status; - GstVaapiSurface *surface; - GstVaapiSurfaceProxy *proxy = NULL; + GstVaapiSurfaceProxy *proxy; + DecodedSurface *ds; - surface = g_async_queue_timed_pop(priv->surfaces, end_time); - - if (surface) { - proxy = gst_vaapi_surface_proxy_new(priv->context, surface); - status = (proxy ? - GST_VAAPI_DECODER_STATUS_SUCCESS : - GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED); - g_object_unref(surface); + ds = pop_surface(decoder, end_time); + if (ds) { + proxy = ds->proxy; + status = ds->status; + destroy_surface(ds); } - else if (end_time) + else { + proxy = NULL; status = GST_VAAPI_DECODER_STATUS_TIMEOUT; - else - status = priv->decoder_status; + } if (pstatus) *pstatus = status; @@ -629,13 +684,5 @@ gst_vaapi_decoder_push_surface( GstVaapiSurface *surface ) { - GstVaapiDecoderPrivate * const priv = decoder->priv; - - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - - GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); - - g_async_queue_push(priv->surfaces, g_object_ref(surface)); - return TRUE; + return push_surface(decoder, surface); } From 1f4e67503c8424922a7403cd4167acc1c59b2ec9 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 09:34:54 +0000 Subject: [PATCH 0277/3781] Improve heuristics to find the best profile. Use the highest one if no explicit match on "profile" field. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 44 ++++++++++++++++------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index ae1d909f9a..e0c089204f 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -39,6 +39,7 @@ struct _GstVaapiProfileMap { GstVaapiProfile profile; VAProfile va_profile; const char *caps_str; + const gchar *profile_str; }; struct _GstVaapiEntrypointMap { @@ -49,42 +50,42 @@ struct _GstVaapiEntrypointMap { /* Profiles */ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_MPEG2_SIMPLE, VAProfileMPEG2Simple, - "video/mpeg, mpegversion=2, profile=simple" + "video/mpeg, mpegversion=2", "simple" }, { GST_VAAPI_PROFILE_MPEG2_MAIN, VAProfileMPEG2Main, - "video/mpeg, mpegversion=2, profile=main" + "video/mpeg, mpegversion=2", "main" }, { GST_VAAPI_PROFILE_MPEG4_SIMPLE, VAProfileMPEG4Simple, - "video/mpeg, mpegversion=4, profile=simple" + "video/mpeg, mpegversion=4", "simple" }, { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, - "video/mpeg, mpegversion=4, profile=advanced-simple" + "video/mpeg, mpegversion=4", "advanced-simple", }, { GST_VAAPI_PROFILE_MPEG4_MAIN, VAProfileMPEG4Main, - "video/mpeg, mpegversion=4, profile=main" + "video/mpeg, mpegversion=4", "main" }, #if VA_CHECK_VERSION(0,30,0) { GST_VAAPI_PROFILE_H263_BASELINE, VAProfileH263Baseline, - "video/x-h263, variant=itu, h263version=h263, profile=baseline" + "video/x-h263, variant=itu, h263version=h263", "baseline" }, #endif { GST_VAAPI_PROFILE_H264_BASELINE, VAProfileH264Baseline, - "video/x-h264, variant=itu, profile=baseline" + "video/x-h264, variant=itu", "baseline" }, { GST_VAAPI_PROFILE_H264_MAIN, VAProfileH264Main, - "video/x-h264, variant=itu, profile=main" + "video/x-h264, variant=itu", "main" }, { GST_VAAPI_PROFILE_H264_HIGH, VAProfileH264High, - "video/x-h264, variant=itu, profile=high" + "video/x-h264, variant=itu", "high" }, { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, - "video/x-vc1, profile=simple" + "video/x-vc1", "simple" }, { GST_VAAPI_PROFILE_VC1_MAIN, VAProfileVC1Main, - "video/x-vc1, profile=main" + "video/x-vc1", "main" }, { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, - "video/x-vc1, profile=advanced" + "video/x-vc1", "advanced" }, { 0, } }; @@ -201,7 +202,8 @@ gst_vaapi_profile_from_caps(GstCaps *caps) const GstVaapiProfileMap *m; GstCaps *caps_test; GstStructure *structure; - GstVaapiProfile profile; + const gchar *profile_str; + GstVaapiProfile profile, best_profile; GstBuffer *codec_data = NULL; const gchar *name; gsize namelen; @@ -216,7 +218,8 @@ gst_vaapi_profile_from_caps(GstCaps *caps) name = gst_structure_get_name(structure); namelen = strlen(name); - if (!gst_structure_has_field(structure, "profile")) { + profile_str = gst_structure_get_string(structure, "profile"); + if (!profile_str) { const GValue *v_codec_data; v_codec_data = gst_structure_get_value(structure, "codec_data"); if (v_codec_data) @@ -224,12 +227,17 @@ gst_vaapi_profile_from_caps(GstCaps *caps) } profile = 0; + best_profile = 0; for (m = gst_vaapi_profiles; !profile && m->profile; m++) { if (strncmp(name, m->caps_str, namelen) != 0) continue; - caps_test = gst_caps_from_string(m->caps_str); - if (gst_caps_is_always_compatible(caps, caps_test)) - profile = m->profile; + caps_test = gst_caps_from_string(m->caps_str);; + if (gst_caps_is_always_compatible(caps, caps_test)) { + best_profile = m->profile; + if (profile_str && m->profile_str && + strcmp(profile_str, m->profile_str) == 0) + profile = best_profile; + } else if (codec_data) profile = gst_vaapi_profile_from_codec_data( GST_VAAPI_PROFILE_CODEC(m->profile), @@ -237,7 +245,7 @@ gst_vaapi_profile_from_caps(GstCaps *caps) ); gst_caps_unref(caps_test); } - return profile; + return profile ? profile : best_profile; } /** From 4350de601b624cfb9aa5d819b4f372ea63827937 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 09:35:54 +0000 Subject: [PATCH 0278/3781] Prefer profile from codec-data if any was found there. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index e0c089204f..c832a2baa1 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -238,7 +238,7 @@ gst_vaapi_profile_from_caps(GstCaps *caps) strcmp(profile_str, m->profile_str) == 0) profile = best_profile; } - else if (codec_data) + if (!profile) profile = gst_vaapi_profile_from_codec_data( GST_VAAPI_PROFILE_CODEC(m->profile), codec_data From 6a3b05dbca32462b20314ee9ef93d1f552263cff Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 09:40:38 +0000 Subject: [PATCH 0279/3781] Fix destructor, av_parser_close() does destroy the struct already, unliker avcodec_close()... --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 6ab342c53d..365cbde774 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -248,8 +248,10 @@ gst_vaapi_decoder_ffmpeg_close(GstVaapiDecoderFfmpeg *ffdecoder) avcodec_close(priv->avctx); } - if (priv->pctx) + if (priv->pctx) { av_parser_close(priv->pctx); + priv->pctx = NULL; + } } static gboolean @@ -305,7 +307,6 @@ gst_vaapi_decoder_ffmpeg_destroy(GstVaapiDecoderFfmpeg *ffdecoder) } av_freep(&priv->avctx); - av_freep(&priv->pctx); av_freep(&priv->frame); } From 7a3934d01da8e3223010afa2a8d48fd3b0779edc Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 09:43:40 +0000 Subject: [PATCH 0280/3781] Fix GstVaapiDecoder::destroy(): GASyncQueue is not a GObject, likewise for GstBuffer. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 2820048c59..46362e8195 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -262,14 +262,14 @@ gst_vaapi_decoder_finalize(GObject *object) } if (priv->buffers) { - clear_async_queue(priv->buffers, (GDestroyNotify)g_object_unref); - g_object_unref(priv->buffers); + clear_async_queue(priv->buffers, (GDestroyNotify)gst_buffer_unref); + g_async_queue_unref(priv->buffers); priv->buffers = NULL; } if (priv->surfaces) { clear_async_queue(priv->surfaces, (GDestroyNotify)destroy_surface); - g_object_unref(priv->surfaces); + g_async_queue_unref(priv->surfaces); priv->surfaces = NULL; } From a14711b93559c66e65011a089dcd28401e0840e6 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 12:52:27 +0000 Subject: [PATCH 0281/3781] Add timestamps to GstVaapiSurfaceProxy. --- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 118 +++++++++++++++++----- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 32 +++++- tests/test-decode.c | 5 +- 3 files changed, 128 insertions(+), 27 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index ff53ab8166..22737aaa74 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -31,28 +31,41 @@ G_DEFINE_TYPE(GstVaapiSurfaceProxy, gst_vaapi_surface_proxy, G_TYPE_OBJECT); +#define GST_VAAPI_SURFACE_PROXY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_SURFACE_PROXY, \ + GstVaapiSurfaceProxyPrivate)) + +struct _GstVaapiSurfaceProxyPrivate { + GstVaapiContext *context; + GstVaapiSurface *surface; + GstClockTime timestamp; +}; + enum { PROP_0, PROP_CONTEXT, - PROP_SURFACE + PROP_SURFACE, + PROP_TIMESTAMP }; static void gst_vaapi_surface_proxy_finalize(GObject *object) { GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(object); + GstVaapiSurfaceProxyPrivate * const priv = proxy->priv; - if (proxy->surface) { - if (proxy->context) - gst_vaapi_context_put_surface(proxy->context, proxy->surface); - g_object_unref(proxy->surface); - proxy->surface = NULL; + if (priv->surface) { + if (priv->context) + gst_vaapi_context_put_surface(priv->context, priv->surface); + g_object_unref(priv->surface); + priv->surface = NULL; } - if (proxy->context) { - g_object_unref(proxy->context); - proxy->context = NULL; + if (priv->context) { + g_object_unref(priv->context); + priv->context = NULL; } G_OBJECT_CLASS(gst_vaapi_surface_proxy_parent_class)->finalize(object); @@ -75,6 +88,9 @@ gst_vaapi_surface_proxy_set_property( case PROP_SURFACE: gst_vaapi_surface_proxy_set_surface(proxy, g_value_get_pointer(value)); break; + case PROP_TIMESTAMP: + gst_vaapi_surface_proxy_set_timestamp(proxy, g_value_get_uint64(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -98,6 +114,9 @@ gst_vaapi_surface_proxy_get_property( case PROP_SURFACE: g_value_set_pointer(value, gst_vaapi_surface_proxy_get_surface(proxy)); break; + case PROP_TIMESTAMP: + g_value_set_uint64(value, gst_vaapi_surface_proxy_get_timestamp(proxy)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -109,6 +128,8 @@ gst_vaapi_surface_proxy_class_init(GstVaapiSurfaceProxyClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); + g_type_class_add_private(klass, sizeof(GstVaapiSurfaceProxyPrivate)); + object_class->finalize = gst_vaapi_surface_proxy_finalize; object_class->set_property = gst_vaapi_surface_proxy_set_property; object_class->get_property = gst_vaapi_surface_proxy_get_property; @@ -128,13 +149,27 @@ gst_vaapi_surface_proxy_class_init(GstVaapiSurfaceProxyClass *klass) "Surface", "The surface stored in the proxy", G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, + PROP_TIMESTAMP, + g_param_spec_uint64("timestamp", + "Timestamp", + "The presentation time of the surface", + 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, + G_PARAM_READWRITE)); } static void gst_vaapi_surface_proxy_init(GstVaapiSurfaceProxy *proxy) -{ - proxy->context = NULL; - proxy->surface = NULL; +{ + GstVaapiSurfaceProxyPrivate *priv; + + priv = GST_VAAPI_SURFACE_PROXY_GET_PRIVATE(proxy); + proxy->priv = priv; + priv->context = NULL; + priv->surface = NULL; + priv->timestamp = GST_CLOCK_TIME_NONE; } /** @@ -154,8 +189,8 @@ gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface) g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); return g_object_new(GST_VAAPI_TYPE_SURFACE_PROXY, - "context", context, - "surface", surface, + "context", context, + "surface", surface, NULL); } @@ -172,7 +207,7 @@ gst_vaapi_surface_proxy_get_context(GstVaapiSurfaceProxy *proxy) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); - return proxy->context; + return proxy->priv->context; } /** @@ -193,13 +228,13 @@ gst_vaapi_surface_proxy_set_context( g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); g_return_if_fail(GST_VAAPI_IS_CONTEXT(context)); - if (proxy->context) { - g_object_unref(proxy->context); - proxy->context = NULL; + if (proxy->priv->context) { + g_object_unref(proxy->priv->context); + proxy->priv->context = NULL; } if (context) - proxy->context = g_object_ref(context); + proxy->priv->context = g_object_ref(context); } /** @@ -215,7 +250,7 @@ gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); - return proxy->surface; + return proxy->priv->surface; } /** @@ -236,11 +271,46 @@ gst_vaapi_surface_proxy_set_surface( g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); - if (proxy->surface) { - g_object_unref(proxy->surface); - proxy->surface = NULL; + if (proxy->priv->surface) { + g_object_unref(proxy->priv->surface); + proxy->priv->surface = NULL; } if (surface) - proxy->surface = g_object_ref(surface); + proxy->priv->surface = g_object_ref(surface); +} + +/** + * gst_vaapi_surface_proxy_get_timestamp: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the presentation timestamp of the #GstVaapiSurface held by @proxy. + * + * Return value: the presentation timestamp of the surface, or + * %GST_CLOCK_TIME_NONE is none was set + */ +GstClockTime +gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), GST_CLOCK_TIME_NONE); + + return proxy->priv->timestamp; +} + +/** + * gst_vaapi_surface_proxy_set_timestamp: + * @proxy: a #GstVaapiSurfaceProxy + * @timestamp: the new presentation timestamp as a #GstClockTime + * + * Sets the presentation timestamp of the @proxy surface to @timestamp. + */ +void +gst_vaapi_surface_proxy_set_timestamp( + GstVaapiSurfaceProxy *proxy, + GstClockTime timestamp +) +{ + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + + proxy->priv->timestamp = timestamp; } diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index d19ef687a8..5e2d833fba 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -51,7 +51,27 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_SURFACE_PROXY, \ GstVaapiSurfaceProxyClass)) +/** + * GST_VAAPI_SURFACE_PROXY_SURFACE: + * @surface: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the #GstVaapiSurface of @surface. + */ +#define GST_VAAPI_SURFACE_PROXY_SURFACE(surface) \ + gst_vaapi_surface_proxy_get_surface(surface) + +/** + * GST_VAAPI_SURFACE_PROXY_TIMESTAMP: + * @surface: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the @surface timestamp, or + * %GST_CLOCK_TIME_NONE if none was set. + */ +#define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(surface) \ + gst_vaapi_surface_proxy_get_timestamp(surface) + typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; +typedef struct _GstVaapiSurfaceProxyPrivate GstVaapiSurfaceProxyPrivate; typedef struct _GstVaapiSurfaceProxyClass GstVaapiSurfaceProxyClass; /** @@ -65,8 +85,7 @@ struct _GstVaapiSurfaceProxy { /*< private >*/ GObject parent_instance; - GstVaapiContext *context; - GstVaapiSurface *surface; + GstVaapiSurfaceProxyPrivate *priv; }; /** @@ -103,6 +122,15 @@ gst_vaapi_surface_proxy_set_surface( GstVaapiSurface *surface ); +GstClockTime +gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy); + +void +gst_vaapi_surface_proxy_set_timestamp( + GstVaapiSurfaceProxy *proxy, + GstClockTime timestamp +); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_PROXY_H */ diff --git a/tests/test-decode.c b/tests/test-decode.c index f076ec1e7b..36d07afa76 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -136,7 +136,10 @@ main(int argc, char *argv[]) gst_vaapi_window_show(window); - if (!gst_vaapi_window_put_surface(window, proxy->surface, NULL, NULL, + if (!gst_vaapi_window_put_surface(window, + GST_VAAPI_SURFACE_PROXY_SURFACE(proxy), + NULL, + NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) g_error("could not render surface"); From bda32435c2d4c7067ab5ff955ac8b3b8045189e6 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 14:28:43 +0000 Subject: [PATCH 0282/3781] Try to set correct timestamps to the decoded surface proxy. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 38 ++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 3 +- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 46362e8195..6ad1c9db6a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -96,6 +96,30 @@ decoder_thread_cb(gpointer data) return NULL; } +static void +update_clock(GstVaapiDecoder *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstClockTime timestamp, duration; + + timestamp = GST_BUFFER_TIMESTAMP(buffer); + duration = GST_BUFFER_DURATION(buffer); + + if (GST_CLOCK_TIME_IS_VALID(duration)) { + if (GST_CLOCK_TIME_IS_VALID(timestamp)) + priv->surface_timestamp = timestamp; + priv->surface_duration = duration; + } + else { + /* Assumes those are user-generated buffers with no timestamp + or duration information. Try to rely on "framerate". */ + if (!GST_CLOCK_TIME_IS_VALID(priv->surface_timestamp)) + priv->surface_timestamp = 0; + priv->surface_duration = + gst_util_uint64_scale_int(GST_SECOND, priv->fps_d, priv->fps_n); + } +} + static inline void init_buffer(GstBuffer *buffer, const guchar *buf, guint buf_size) { @@ -174,8 +198,10 @@ pop_buffer(GstVaapiDecoder *decoder) buffer = g_async_queue_pop(priv->buffers); g_return_val_if_fail(buffer, NULL); - if (!GST_BUFFER_TIMESTAMP_IS_VALID(buffer)) - GST_BUFFER_TIMESTAMP(buffer) = priv->next_ts; + GST_DEBUG("dequeue buffer %p for decoding (%d bytes)", + buffer, GST_BUFFER_SIZE(buffer)); + + update_clock(decoder, buffer); return buffer; } @@ -206,7 +232,10 @@ push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface) GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); ds->proxy = gst_vaapi_surface_proxy_new(priv->context, surface); - if (!ds->proxy) + if (ds->proxy) + gst_vaapi_surface_proxy_set_timestamp( + ds->proxy, priv->surface_timestamp); + else status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } ds->status = status; @@ -388,7 +417,8 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->codec_data = NULL; priv->fps_n = 1000; priv->fps_d = 30; - priv->next_ts = 0; + priv->surface_timestamp = GST_CLOCK_TIME_NONE; + priv->surface_duration = GST_CLOCK_TIME_NONE; priv->buffers = g_async_queue_new(); priv->surfaces = g_async_queue_new(); priv->decoder_thread = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index e5f87e6ecd..be28904308 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -93,9 +93,10 @@ struct _GstVaapiDecoderPrivate { GstBuffer *codec_data; guint fps_n; guint fps_d; - GstClockTime next_ts; GAsyncQueue *buffers; GAsyncQueue *surfaces; + GstClockTime surface_timestamp; + GstClockTime surface_duration; GThread *decoder_thread; GstVaapiDecoderStatus decoder_status; guint decoder_thread_cancel : 1; From 0596777703279c4aa5edb3da0d011440ce7ca84b Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 14:58:45 +0000 Subject: [PATCH 0283/3781] Fix gst_vaapi_decoder_get_surface() status. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 6ad1c9db6a..97657fc8f0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -221,7 +221,6 @@ static gboolean push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface) { GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVaapiDecoderStatus status = priv->decoder_status; DecodedSurface *ds; ds = create_surface(); @@ -232,13 +231,16 @@ push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface) GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); ds->proxy = gst_vaapi_surface_proxy_new(priv->context, surface); - if (ds->proxy) + if (ds->proxy) { + ds->status = GST_VAAPI_DECODER_STATUS_SUCCESS; gst_vaapi_surface_proxy_set_timestamp( ds->proxy, priv->surface_timestamp); + } else - status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + ds->status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } - ds->status = status; + else + ds->status = priv->decoder_status; g_async_queue_push(priv->surfaces, ds); return TRUE; From a1fddf8bcc74aa4394fa3dedef528d23f678f739 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 15:45:44 +0000 Subject: [PATCH 0284/3781] Add support for GstVaapiSurfaceProxy to GstVaapiVideoBuffer. --- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 85 ++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 13 ++++ 2 files changed, 93 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index d40b9de334..fbb4f1ffc2 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -39,11 +39,12 @@ G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, GST_TYPE_BUFFER); GstVaapiVideoBufferPrivate)) struct _GstVaapiVideoBufferPrivate { - GstVaapiVideoPool *image_pool; - GstVaapiImage *image; - GstVaapiVideoPool *surface_pool; - GstVaapiSurface *surface; - guint flags; + GstVaapiVideoPool *image_pool; + GstVaapiImage *image; + GstVaapiVideoPool *surface_pool; + GstVaapiSurface *surface; + GstVaapiSurfaceProxy *proxy; + guint flags; }; static void @@ -70,6 +71,11 @@ gst_vaapi_video_buffer_destroy_surface(GstVaapiVideoBuffer *buffer) { GstVaapiVideoBufferPrivate * const priv = buffer->priv; + if (priv->proxy) { + g_object_unref(priv->proxy); + priv->proxy = NULL; + } + if (priv->surface) { if (priv->surface_pool) gst_vaapi_video_pool_put_object(priv->surface_pool, priv->surface); @@ -119,6 +125,7 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) priv->image = NULL; priv->surface_pool = NULL; priv->surface = NULL; + priv->proxy = NULL; } static inline GstVaapiVideoBuffer * @@ -215,6 +222,28 @@ gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) return GST_BUFFER(buffer); } +/** + * gst_vaapi_video_buffer_new_with_surface_proxy: + * @proxy: a #GstVaapiSurfaceProxy + * + * Creates a #GstBuffer with the specified surface @proxy. The + * resulting buffer holds an additional reference to the @proxy. + * + * Return value: the newly allocated #GstBuffer, or %NULL on error + */ +GstBuffer * +gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) +{ + GstVaapiVideoBuffer *buffer; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); + + buffer = gst_vaapi_video_buffer_new(); + if (buffer) + gst_vaapi_video_buffer_set_surface_proxy(buffer, proxy); + return GST_BUFFER(buffer); +} + /** * gst_vaapi_video_buffer_get_image: * @buffer: a #GstVaapiVideoBuffer @@ -362,3 +391,49 @@ gst_vaapi_video_buffer_set_surface_from_pool( } return TRUE; } + +/** + * gst_vaapi_video_buffer_get_surface_proxy: + * @buffer: a #GstVaapiVideoBuffer + * + * Retrieves the #GstVaapiSurfaceProxy bound to the @buffer. The @buffer + * owns the #GstVaapiSurfaceProxy so the caller is responsible for calling + * g_object_ref() when needed. + * + * Return value: the #GstVaapiSurfaceProxy bound to the @buffer, or + * %NULL if there is none + */ +GstVaapiSurfaceProxy * +gst_vaapi_video_buffer_get_surface_proxy(GstVaapiVideoBuffer *buffer) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL); + + return buffer->priv->proxy; +} + +/** + * gst_vaapi_video_buffer_set_surface_proxy: + * @buffer: a #GstVaapiVideoBuffer + * @proxy: a #GstVaapiSurfaceProxy + * + * Binds surface @proxy to the @buffer. If the @buffer contains another + * surface previously allocated from a pool, it's pushed back to its + * parent pool and the pool is also released. + */ +void +gst_vaapi_video_buffer_set_surface_proxy( + GstVaapiVideoBuffer *buffer, + GstVaapiSurfaceProxy *proxy +) +{ + g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer)); + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + + gst_vaapi_video_buffer_destroy_surface(buffer); + + if (proxy) { + GstVaapiVideoBufferPrivate * const priv = buffer->priv; + priv->proxy = g_object_ref(proxy); + priv->surface = g_object_ref(GST_VAAPI_SURFACE_PROXY_SURFACE(proxy)); + } +} diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index ae737e7fe5..1303df7cf2 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -24,6 +24,7 @@ #include #include #include +#include #include G_BEGIN_DECLS @@ -90,6 +91,9 @@ gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image); GstBuffer * gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface); +GstBuffer * +gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); + GstVaapiImage * gst_vaapi_video_buffer_get_image(GstVaapiVideoBuffer *buffer); @@ -120,6 +124,15 @@ gst_vaapi_video_buffer_set_surface_from_pool( GstVaapiVideoPool *pool ); +GstVaapiSurfaceProxy * +gst_vaapi_video_buffer_get_surface_proxy(GstVaapiVideoBuffer *buffer); + +void +gst_vaapi_video_buffer_set_surface_proxy( + GstVaapiVideoBuffer *buffer, + GstVaapiSurfaceProxy *proxy +); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_BUFFER_H */ From 5f5ed724ddec58230feea11519e25127c138c3d9 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 16:08:46 +0000 Subject: [PATCH 0285/3781] Drop extraneous var. --- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index fbb4f1ffc2..bb002bfc78 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -44,7 +44,6 @@ struct _GstVaapiVideoBufferPrivate { GstVaapiVideoPool *surface_pool; GstVaapiSurface *surface; GstVaapiSurfaceProxy *proxy; - guint flags; }; static void From 2356ceb0d91660049a23a4a52f709cceba950a98 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 17:11:32 +0000 Subject: [PATCH 0286/3781] Use a GstTask with start/stop semantics for the decoder thread. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 100 +++++++++++----------- gst-libs/gst/vaapi/gstvaapidecoder.h | 6 ++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 6 +- 3 files changed, 59 insertions(+), 53 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 97657fc8f0..568212bacd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -52,11 +52,8 @@ enum { PROP_CODEC_DATA }; -static gboolean -gst_vaapi_decoder_start(GstVaapiDecoder *decoder); - -static gboolean -gst_vaapi_decoder_stop(GstVaapiDecoder *decoder); +/* Wait _at most_ 10 ms for encoded buffers between each decoding step */ +#define GST_VAAPI_DECODER_TIMEOUT (10000) static GstBuffer * pop_buffer(GstVaapiDecoder *decoder); @@ -67,33 +64,31 @@ push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface); static DecodedSurface * pop_surface(GstVaapiDecoder *decoder, GTimeVal *end_time); -static gpointer -decoder_thread_cb(gpointer data) +static void +decoder_task(gpointer data) { - GstVaapiDecoder * const decoder = data; + GstVaapiDecoder * const decoder = GST_VAAPI_DECODER_CAST(data); GstVaapiDecoderPrivate * const priv = decoder->priv; GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); GstBuffer *buffer; - g_object_ref(decoder); - while (!priv->decoder_thread_cancel) { - buffer = pop_buffer(decoder); - priv->decoder_status = klass->decode(decoder, buffer); - GST_DEBUG("decode frame (status = %d)", priv->decoder_status); - switch (priv->decoder_status) { - case GST_VAAPI_DECODER_STATUS_SUCCESS: - case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: - break; - default: - /* Send an empty surface to signal an error */ - push_surface(decoder, NULL); - priv->decoder_thread_cancel = TRUE; - break; - } - gst_buffer_unref(buffer); + buffer = pop_buffer(decoder); + if (!buffer) + return; + + priv->decoder_status = klass->decode(decoder, buffer); + GST_DEBUG("decode frame (status = %d)", priv->decoder_status); + + switch (priv->decoder_status) { + case GST_VAAPI_DECODER_STATUS_SUCCESS: + case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: + break; + default: + /* Send an empty surface to signal an error */ + push_surface(decoder, NULL); + gst_task_pause(priv->decoder_task); + break; } - g_object_unref(decoder); - return NULL; } static void @@ -182,9 +177,6 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) GST_DEBUG("queue encoded data buffer %p (%d bytes)", buffer, GST_BUFFER_SIZE(buffer)); - if (!priv->decoder_thread && !gst_vaapi_decoder_start(decoder)) - return FALSE; - g_async_queue_push(priv->buffers, buffer); return TRUE; } @@ -193,10 +185,15 @@ static GstBuffer * pop_buffer(GstVaapiDecoder *decoder) { GstVaapiDecoderPrivate * const priv = decoder->priv; + GTimeVal end_time; GstBuffer *buffer; - buffer = g_async_queue_pop(priv->buffers); - g_return_val_if_fail(buffer, NULL); + g_get_current_time(&end_time); + g_time_val_add(&end_time, GST_VAAPI_DECODER_TIMEOUT); + + buffer = g_async_queue_timed_pop(priv->buffers, &end_time); + if (!buffer) + return NULL; GST_DEBUG("dequeue buffer %p for decoding (%d bytes)", buffer, GST_BUFFER_SIZE(buffer)); @@ -251,6 +248,9 @@ pop_surface(GstVaapiDecoder *decoder, GTimeVal *end_time) { GstVaapiDecoderPrivate * const priv = decoder->priv; + if (!gst_vaapi_decoder_start(decoder)) + return NULL; + return g_async_queue_timed_pop(priv->surfaces, end_time); } @@ -423,8 +423,9 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->surface_duration = GST_CLOCK_TIME_NONE; priv->buffers = g_async_queue_new(); priv->surfaces = g_async_queue_new(); - priv->decoder_thread = NULL; - priv->decoder_thread_cancel = FALSE; + priv->decoder_task = NULL; + + g_static_rec_mutex_init(&priv->decoder_task_lock); } /** @@ -442,16 +443,15 @@ gst_vaapi_decoder_start(GstVaapiDecoder *decoder) /* This is an internal function */ GstVaapiDecoderPrivate * const priv = decoder->priv; - if (!priv->decoder_thread) { - priv->decoder_thread = g_thread_create( - decoder_thread_cb, decoder, - TRUE, - NULL - ); - if (!priv->decoder_thread) - return FALSE; - } - return TRUE; + if (priv->decoder_task) + return TRUE; + + priv->decoder_task = gst_task_create(decoder_task, decoder); + if (!priv->decoder_task) + return FALSE; + + gst_task_set_lock(priv->decoder_task, &priv->decoder_task_lock); + return gst_task_start(priv->decoder_task); } /** @@ -470,14 +470,14 @@ gst_vaapi_decoder_stop(GstVaapiDecoder *decoder) { /* This is an internal function */ GstVaapiDecoderPrivate * const priv = decoder->priv; + gboolean success; - if (priv->decoder_thread) { - push_buffer(decoder, NULL); - priv->decoder_thread_cancel = TRUE; - g_thread_join(priv->decoder_thread); - priv->decoder_thread = NULL; - } - return TRUE; + if (!priv->decoder_task) + return FALSE; + + success = gst_task_join(priv->decoder_task); + priv->decoder_task = NULL; + return success; } /** diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index b11cf00d13..f526cde980 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -124,6 +124,12 @@ gst_vaapi_decoder_set_frame_rate( guint den ); +gboolean +gst_vaapi_decoder_start(GstVaapiDecoder *decoder); + +gboolean +gst_vaapi_decoder_stop(GstVaapiDecoder *decoder); + gboolean gst_vaapi_decoder_put_buffer_data( GstVaapiDecoder *decoder, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index be28904308..a27199561a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -22,7 +22,7 @@ #define GST_VAAPI_DECODER_PRIV_H #include -#include +#include #include #include @@ -97,9 +97,9 @@ struct _GstVaapiDecoderPrivate { GAsyncQueue *surfaces; GstClockTime surface_timestamp; GstClockTime surface_duration; - GThread *decoder_thread; + GstTask *decoder_task; + GStaticRecMutex decoder_task_lock; GstVaapiDecoderStatus decoder_status; - guint decoder_thread_cancel : 1; }; gboolean From 5d1eb8ce896f7a4140bab2f3de8862d9eaf986ed Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 17:51:57 +0000 Subject: [PATCH 0287/3781] Add gst_vaapi_decoder_pause(). --- gst-libs/gst/vaapi/gstvaapidecoder.c | 42 ++++++++++++++++++++-------- gst-libs/gst/vaapi/gstvaapidecoder.h | 3 ++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 568212bacd..a6c848ca2b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -440,18 +440,35 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) gboolean gst_vaapi_decoder_start(GstVaapiDecoder *decoder) { - /* This is an internal function */ - GstVaapiDecoderPrivate * const priv = decoder->priv; + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); - if (priv->decoder_task) + if (decoder->priv->decoder_task) return TRUE; - priv->decoder_task = gst_task_create(decoder_task, decoder); - if (!priv->decoder_task) + decoder->priv->decoder_task = gst_task_create(decoder_task, decoder); + if (!decoder->priv->decoder_task) return FALSE; - gst_task_set_lock(priv->decoder_task, &priv->decoder_task_lock); - return gst_task_start(priv->decoder_task); + gst_task_set_lock(decoder->priv->decoder_task, &decoder->priv->decoder_task_lock); + return gst_task_start(decoder->priv->decoder_task); +} + +/** + * gst_vaapi_decoder_pause: + * @decoder: a #GstVaapiDecoder + * + * Pauses the decoder. It can be made active again through + * gst_vaapi_decoder_start() or definitely stopped through + * gst_vaapi_decoder_stop(). + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_decoder_pause(GstVaapiDecoder *decoder) +{ + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); + + return gst_task_pause(decoder->priv->decoder_task); } /** @@ -468,15 +485,16 @@ gst_vaapi_decoder_start(GstVaapiDecoder *decoder) gboolean gst_vaapi_decoder_stop(GstVaapiDecoder *decoder) { - /* This is an internal function */ - GstVaapiDecoderPrivate * const priv = decoder->priv; gboolean success; - if (!priv->decoder_task) + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); + + if (!decoder->priv->decoder_task) return FALSE; - success = gst_task_join(priv->decoder_task); - priv->decoder_task = NULL; + success = gst_task_join(decoder->priv->decoder_task); + g_object_unref(decoder->priv->decoder_task); + decoder->priv->decoder_task = NULL; return success; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index f526cde980..b3a212e26f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -127,6 +127,9 @@ gst_vaapi_decoder_set_frame_rate( gboolean gst_vaapi_decoder_start(GstVaapiDecoder *decoder); +gboolean +gst_vaapi_decoder_pause(GstVaapiDecoder *decoder); + gboolean gst_vaapi_decoder_stop(GstVaapiDecoder *decoder); From 3f3055af1fc8409efc2ded9ec03c1b044ad158bf Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 17:55:58 +0000 Subject: [PATCH 0288/3781] Add FFmpeg/VAAPI decoder for the new `vaapidecode' element. --- NEWS | 5 +- configure.ac | 1 + gst/Makefile.am | 2 +- gst/vaapidecode/Makefile.am | 34 ++ gst/vaapidecode/gstvaapidecode.c | 524 +++++++++++++++++++++++++++++++ gst/vaapidecode/gstvaapidecode.h | 83 +++++ 6 files changed, 647 insertions(+), 2 deletions(-) create mode 100644 gst/vaapidecode/Makefile.am create mode 100644 gst/vaapidecode/gstvaapidecode.c create mode 100644 gst/vaapidecode/gstvaapidecode.h diff --git a/NEWS b/NEWS index f74ae74ad9..e96e568e23 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2010-03-30 +gst-vaapi NEWS -- summary of changes. 2010-04-DD Copyright (C) 2010 Splitted-Desktop Systems +Version 0.2.0 - DD.Apr.2010 +* Add FFmpeg/VAAPI decoder for the new `vaapidecode' element + Version 0.1.2 - 30.Mar.2010 * Add AYUV image format * Add compatibility with the original VA-API 0.29 diff --git a/configure.ac b/configure.ac index 10c258b59d..2b60cf58ca 100644 --- a/configure.ac +++ b/configure.ac @@ -321,6 +321,7 @@ pkgconfig/gstreamer-vaapi-glx.pc.in pkgconfig/gstreamer-vaapi-x11.pc.in gst/Makefile gst/vaapiconvert/Makefile + gst/vaapidecode/Makefile gst/vaapisink/Makefile tests/Makefile ]) diff --git a/gst/Makefile.am b/gst/Makefile.am index 106bb4192e..195d0e9dd2 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = vaapiconvert vaapisink +SUBDIRS = vaapiconvert vaapidecode vaapisink # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/gst/vaapidecode/Makefile.am b/gst/vaapidecode/Makefile.am new file mode 100644 index 0000000000..b5a230e302 --- /dev/null +++ b/gst/vaapidecode/Makefile.am @@ -0,0 +1,34 @@ +plugin_LTLIBRARIES = libgstvaapidecode.la + +libgstvaapi_CFLAGS = \ + -I$(top_srcdir)/gst-libs + +libgstvaapi_LIBS = \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la + +libgstvaapidecode_la_SOURCES = \ + gstvaapidecode.c \ + $(NULL) + +noinst_HEADERS = \ + gstvaapidecode.h \ + $(NULL) + +libgstvaapidecode_la_CFLAGS = \ + $(libgstvaapi_CFLAGS) \ + $(GST_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ + $(GST_PLUGINS_BASE_CFLAGS) + +libgstvaapidecode_la_LIBADD = \ + $(libgstvaapi_LIBS) \ + $(GST_LIBS) \ + $(GST_BASE_LIBS) \ + $(GST_VIDEO_LIBS) \ + $(GST_PLUGINS_BASE_LIBS) + +libgstvaapidecode_la_LIBTOOLFLAGS = --tag=disable-static + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c new file mode 100644 index 0000000000..9600858a3a --- /dev/null +++ b/gst/vaapidecode/gstvaapidecode.c @@ -0,0 +1,524 @@ +/* + * gstvaapidecode.c - VA-API video decoder + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * SECTION:gstvaapidecode + * @short_description: A VA-API based video decoder + * + * vaapidecode decodes from raw bitstreams to surfaces suitable for + * the vaapisink element. + */ + +#include "config.h" +#include "gstvaapidecode.h" +#include +#include +#include + +#define GST_PLUGIN_NAME "vaapidecode" +#define GST_PLUGIN_DESC "A VA-API based video decoder" + +GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapidecode); +#define GST_CAT_DEFAULT gst_debug_vaapidecode + +/* ElementFactory information */ +static const GstElementDetails gst_vaapidecode_details = + GST_ELEMENT_DETAILS( + "Video decode", + "Codec/Decoder/Video", + GST_PLUGIN_DESC, + "Gwenole Beauchesne "); + +/* Default templates */ +#define GST_CAPS_CODEC(CODEC) \ + CODEC ", " \ + "width = (int) [ 1, MAX ], " \ + "height = (int) [ 1, MAX ]; " + +static const char gst_vaapidecode_sink_caps_str[] = + GST_CAPS_CODEC("video/mpeg, mpegversion=2") + GST_CAPS_CODEC("video/mpeg, mpegversion=4") + GST_CAPS_CODEC("video/x-h263") + GST_CAPS_CODEC("video/x-h264") + GST_CAPS_CODEC("video/x-vc1") + ; + +static const char gst_vaapidecode_src_caps_str[] = + "video/x-vaapi-surface, " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]; "; + +static GstStaticPadTemplate gst_vaapidecode_sink_factory = + GST_STATIC_PAD_TEMPLATE( + "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS(gst_vaapidecode_sink_caps_str)); + +static GstStaticPadTemplate gst_vaapidecode_src_factory = + GST_STATIC_PAD_TEMPLATE( + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS(gst_vaapidecode_src_caps_str)); + +GST_BOILERPLATE( + GstVaapiDecode, + gst_vaapidecode, + GstElement, + GST_TYPE_ELEMENT); + +enum { + PROP_0, + + PROP_USE_FFMPEG, +}; + +static void +gst_vaapidecode_task_cb(gpointer data) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(data); + GstVaapiDecoderStatus status; + GstVaapiSurfaceProxy *proxy; + GstBuffer *buffer; + GstFlowReturn ret; + + proxy = gst_vaapi_decoder_timed_get_surface(decode->decoder, 10000, &status); + if (!proxy || status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return; + + buffer = NULL; + ret = gst_pad_alloc_buffer(decode->srcpad, 0, 0, GST_PAD_CAPS(decode->srcpad), &buffer); + if (ret != GST_FLOW_OK || !buffer) + goto error_create_buffer; + + GST_BUFFER_TIMESTAMP(buffer) = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); + + ret = gst_pad_push(decode->srcpad, buffer); + if (ret != GST_FLOW_OK) + goto error_commit_buffer; + + g_object_unref(proxy); + return; + + /* ERRORS */ +error_create_buffer: + { + const GstVaapiID surface_id = + gst_vaapi_surface_get_id(GST_VAAPI_SURFACE_PROXY_SURFACE(proxy)); + + GST_DEBUG("video sink failed to create video buffer for proxy'ed " + "surface %" GST_VAAPI_ID_FORMAT " (error %d)", + GST_VAAPI_ID_ARGS(surface_id), ret); + g_object_unref(proxy); + return; + } +error_commit_buffer: + { + GST_DEBUG("video sink rejected the video buffer (error %d)", ret); + g_object_unref(proxy); + return; + } +} + +static gboolean +gst_vaapidecode_start(GstVaapiDecode *decode) +{ + if (gst_task_get_state(decode->decoder_task) == GST_TASK_STARTED) + return TRUE; + + GST_DEBUG("start decoding threads"); + if (!gst_vaapi_decoder_start(decode->decoder)) + return FALSE; + return gst_task_start(decode->decoder_task); +} + +static gboolean +gst_vaapidecode_pause(GstVaapiDecode *decode) +{ + if (gst_task_get_state(decode->decoder_task) == GST_TASK_PAUSED) + return TRUE; + + GST_DEBUG("pause decoding threads"); + if (!gst_vaapi_decoder_pause(decode->decoder)) + return FALSE; + return gst_task_pause(decode->decoder_task); +} + +static gboolean +gst_vaapidecode_stop(GstVaapiDecode *decode) +{ + if (gst_task_get_state(decode->decoder_task) == GST_TASK_STOPPED) + return TRUE; + + GST_DEBUG("stop decoding threads"); + if (!gst_vaapi_decoder_stop(decode->decoder)) + return FALSE; + return gst_task_stop(decode->decoder_task); +} + +static gboolean +gst_vaapidecode_create(GstVaapiDecode *decode) +{ + GstVaapiVideoSink *sink; + GstVaapiDisplay *display; + GstVaapiCodec codec; + + /* Look for a downstream vaapisink */ + sink = gst_vaapi_video_sink_lookup(GST_ELEMENT(decode)); + if (!sink) + return FALSE; + + display = gst_vaapi_video_sink_get_display(sink); + if (!display) + return FALSE; + + decode->display = g_object_ref(display); + + codec = gst_vaapi_profile_get_codec(decode->profile); + if (!codec) + return FALSE; + + if (decode->use_ffmpeg) + decode->decoder = + gst_vaapi_decoder_ffmpeg_new(display, codec, decode->codec_data); + if (!decode->decoder) + return FALSE; + + decode->decoder_task = gst_task_create(gst_vaapidecode_task_cb, decode); + if (!decode->decoder_task) + return FALSE; + + gst_task_set_lock(decode->decoder_task, &decode->decoder_task_lock); + return TRUE; +} + +static void +gst_vaapidecode_destroy(GstVaapiDecode *decode) +{ + if (decode->decoder_task) { + gst_task_join(decode->decoder_task); + g_object_unref(decode->decoder_task); + decode->decoder_task = NULL; + } + + if (decode->decoder) { + gst_vaapi_decoder_put_buffer(decode->decoder, NULL); + g_object_unref(decode->decoder); + decode->decoder = NULL; + } + + if (decode->codec_data) { + gst_buffer_unref(decode->codec_data); + decode->codec_data = NULL; + } + + if (decode->display) { + g_object_unref(decode->display); + decode->display = NULL; + } +} + +static void gst_vaapidecode_base_init(gpointer klass) +{ + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + + gst_element_class_set_details(element_class, &gst_vaapidecode_details); + + /* sink pad */ + gst_element_class_add_pad_template( + element_class, + gst_static_pad_template_get(&gst_vaapidecode_sink_factory) + ); + + /* src pad */ + gst_element_class_add_pad_template( + element_class, + gst_static_pad_template_get(&gst_vaapidecode_src_factory) + ); +} + +static void +gst_vaapidecode_finalize(GObject *object) +{ + gst_vaapidecode_destroy(GST_VAAPIDECODE(object)); + + G_OBJECT_CLASS(parent_class)->finalize(object); +} + +static void +gst_vaapidecode_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(object); + + switch (prop_id) { + case PROP_USE_FFMPEG: + decode->use_ffmpeg = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapidecode_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(object); + + switch (prop_id) { + case PROP_USE_FFMPEG: + g_value_set_boolean(value, decode->use_ffmpeg); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static GstStateChangeReturn +gst_vaapidecode_change_state(GstElement *element, GstStateChange transition) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(element); + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + if (!gst_vaapidecode_start(decode)) + return GST_STATE_CHANGE_FAILURE; + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition); + if (ret != GST_STATE_CHANGE_SUCCESS) + return ret; + + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + if (!gst_vaapidecode_pause(decode)) + return GST_STATE_CHANGE_FAILURE; + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + if (!gst_vaapidecode_stop(decode)) + return GST_STATE_CHANGE_FAILURE; + break; + default: + break; + } + return GST_STATE_CHANGE_SUCCESS; +} + +static void +gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + + object_class->finalize = gst_vaapidecode_finalize; + object_class->set_property = gst_vaapidecode_set_property; + object_class->get_property = gst_vaapidecode_get_property; + + element_class->change_state = gst_vaapidecode_change_state; + + g_object_class_install_property + (object_class, + PROP_USE_FFMPEG, + g_param_spec_boolean("use-ffmpeg", + "Use FFmpeg/VAAPI for decoding", + "Uses FFmpeg/VAAPI for decoding", + TRUE, + G_PARAM_READWRITE)); +} + +static gboolean +gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); + GstPad *other_pad; + GstCaps *other_caps = NULL; + GstStructure *structure; + const GValue *v_width, *v_height, *v_framerate, *v_par, *v_codec_data; + + if (pad == decode->sinkpad) { + other_pad = decode->srcpad; + other_caps = gst_caps_from_string(gst_vaapidecode_src_caps_str); + } + else { + other_pad = decode->sinkpad; + other_caps = gst_caps_from_string(gst_vaapidecode_sink_caps_str); + } + + /* Negotiation succeeded, so now configure ourselves */ + structure = gst_caps_get_structure(caps, 0); + v_width = gst_structure_get_value(structure, "width"); + v_height = gst_structure_get_value(structure, "height"); + v_framerate = gst_structure_get_value(structure, "framerate"); + v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); + v_codec_data = gst_structure_get_value(structure, "codec_data"); + + if (pad == decode->sinkpad) { + decode->profile = gst_vaapi_profile_from_caps(caps); + if (v_codec_data) + decode->codec_data = + gst_buffer_ref(gst_value_get_buffer(v_codec_data)); + } + + structure = gst_caps_get_structure(other_caps, 0); + gst_structure_set_value(structure, "width", v_width); + gst_structure_set_value(structure, "height", v_height); + if (v_framerate) + gst_structure_set_value(structure, "framerate", v_framerate); + if (v_par) + gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); + + return gst_pad_set_caps(other_pad, other_caps); +} + +static GstFlowReturn +gst_vaapidecode_chain(GstPad *pad, GstBuffer *buf) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); + + if (!decode->decoder) { + if (!gst_vaapidecode_create(decode)) + goto error_create_decoder; + } + + if (!gst_vaapidecode_start(decode)) + goto error_start_decoder; + + if (!gst_vaapi_decoder_put_buffer(decode->decoder, buf)) + goto error_push_buffer; + + gst_buffer_unref(buf); + return GST_FLOW_OK; + + /* ERRORS */ +error_create_decoder: + { + GST_DEBUG("failed to create decoder"); + gst_buffer_unref(buf); + return GST_FLOW_UNEXPECTED; + } +error_start_decoder: + { + GST_DEBUG("failed to start decoder"); + gst_buffer_unref(buf); + return GST_FLOW_UNEXPECTED; + } +error_push_buffer: + { + GST_DEBUG("failed to push input buffer to decoder"); + gst_buffer_unref(buf); + return GST_FLOW_UNEXPECTED; + } +} + +static gboolean +gst_vaapidecode_sink_event(GstPad *pad, GstEvent *event) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); + + GST_DEBUG("handle sink event '%s'", GST_EVENT_TYPE_NAME(event)); + + /* Propagate event downstream */ + return gst_pad_push_event(decode->srcpad, event); +} + +static gboolean +gst_vaapidecode_src_event(GstPad *pad, GstEvent *event) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); + + GST_DEBUG("handle src event '%s'", GST_EVENT_TYPE_NAME(event)); + + /* Propagate event upstream */ + return gst_pad_push_event(decode->sinkpad, event); +} + +static void +gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) +{ + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + + decode->display = NULL; + decode->profile = 0; + decode->codec_data = NULL; + decode->decoder = NULL; + decode->decoder_task = NULL; + decode->use_ffmpeg = TRUE; + + g_static_rec_mutex_init(&decode->decoder_task_lock); + + /* Pad through which data comes in to the element */ + decode->sinkpad = gst_pad_new_from_template( + gst_element_class_get_pad_template(element_class, "sink"), + "sink" + ); + + gst_pad_set_setcaps_function(decode->sinkpad, gst_vaapidecode_set_caps); + gst_pad_set_chain_function(decode->sinkpad, gst_vaapidecode_chain); + gst_pad_set_event_function(decode->sinkpad, gst_vaapidecode_sink_event); + gst_element_add_pad(GST_ELEMENT(decode), decode->sinkpad); + + /* Pad through which data goes out of the element */ + decode->srcpad = gst_pad_new_from_template( + gst_element_class_get_pad_template(element_class, "src"), + "src" + ); + + gst_pad_set_event_function(decode->srcpad, gst_vaapidecode_src_event); + gst_element_add_pad(GST_ELEMENT(decode), decode->srcpad); +} + +static gboolean plugin_init(GstPlugin *plugin) +{ + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + return gst_element_register(plugin, + GST_PLUGIN_NAME, + GST_RANK_PRIMARY, + GST_TYPE_VAAPIDECODE); +} + +GST_PLUGIN_DEFINE( + GST_VERSION_MAJOR, GST_VERSION_MINOR, + GST_PLUGIN_NAME, + GST_PLUGIN_DESC, + plugin_init, + PACKAGE_VERSION, + "GPL", + PACKAGE, + PACKAGE_BUGREPORT); diff --git a/gst/vaapidecode/gstvaapidecode.h b/gst/vaapidecode/gstvaapidecode.h new file mode 100644 index 0000000000..0772c39ce1 --- /dev/null +++ b/gst/vaapidecode/gstvaapidecode.h @@ -0,0 +1,83 @@ +/* + * gstvaapidecode.h - VA-API video decoder + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_VAAPIDECODE_H +#define GST_VAAPIDECODE_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIDECODE \ + (gst_vaapidecode_get_type()) + +#define GST_VAAPIDECODE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_TYPE_VAAPIDECODE, \ + GstVaapiDecode)) + +#define GST_VAAPIDECODE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_TYPE_VAAPIDECODE, \ + GstVaapiDecodeClass)) + +#define GST_IS_VAAPIDECODE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPIDECODE)) + +#define GST_IS_VAAPIDECODE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPIDECODE)) + +#define GST_VAAPIDECODE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_TYPE_VAAPIDECODE, \ + GstVaapiDecodeClass)) + +typedef struct _GstVaapiDecode GstVaapiDecode; +typedef struct _GstVaapiDecodeClass GstVaapiDecodeClass; + +struct _GstVaapiDecode { + /*< private >*/ + GstElement parent_instance; + + GstPad *sinkpad; + GstPad *srcpad; + GstVaapiDisplay *display; + GstVaapiProfile profile; + GstBuffer *codec_data; + GstVaapiDecoder *decoder; + GstTask *decoder_task; + GStaticRecMutex decoder_task_lock; + unsigned int use_ffmpeg : 1; +}; + +struct _GstVaapiDecodeClass { + /*< private >*/ + GstElementClass parent_class; +}; + +GType +gst_vaapidecode_get_type(void); + +G_END_DECLS + +#endif /* GST_VAAPIDECODE_H */ From 875352c12dddfdfed0ab3b05b9bdb2c3a50a4489 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 17:56:42 +0000 Subject: [PATCH 0289/3781] Fix comment. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 2b60cf58ca..e56ded6b07 100644 --- a/configure.ac +++ b/configure.ac @@ -245,7 +245,7 @@ AC_SUBST(LIBVA_GLX_PKGNAME) AC_SUBST(LIBVA_EXTRA_CFLAGS) AC_SUBST(LIBVA_EXTRA_LIBS) -dnl Check for OpenGL support to +dnl Check for OpenGL support to vaapisink if test "$enable_vaapisink_glx:$USE_GLX" = "yes:1"; then USE_VAAPISINK_GLX=1 else From 8c17e2f99d46ec7d3377ec28d0a1eb06afd06610 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 21:12:30 +0000 Subject: [PATCH 0290/3781] Fix gst_vaapi_profile_get_caps() to include the "profile" field. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index c832a2baa1..11c67ad05d 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -279,8 +279,17 @@ GstCaps * gst_vaapi_profile_get_caps(GstVaapiProfile profile) { const GstVaapiProfileMap * const m = get_profiles_map(profile); + GstCaps *caps; - return m ? gst_caps_from_string(m->caps_str) : NULL; + if (!m) + return NULL; + + caps = gst_caps_from_string(m->caps_str); + if (!caps) + return NULL; + + gst_caps_set_simple(caps, "profile", G_TYPE_STRING, m->profile_str, NULL); + return caps; } /** From f1fc4b52c561b04bd6c1cf2fc5c6091cd716e2a0 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 21:56:10 +0000 Subject: [PATCH 0291/3781] Export gst_vaapi_video_buffer_new(). --- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 33 +++++++++++++++--------- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 3 +++ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index bb002bfc78..113df760ef 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -127,16 +127,25 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) priv->proxy = NULL; } -static inline GstVaapiVideoBuffer * +/** + * gst_vaapi_video_buffer_new: + * + * Creates an empty #GstBuffer. The caller is responsible for completing + * the initialization of the buffer with the gst_vaapi_video_buffer_set_*() + * functions. + * + * Return value: the newly allocated #GstBuffer, or %NULL or error + */ +static inline gpointer +_gst_vaapi_video_buffer_new(void) +{ + return gst_mini_object_new(GST_VAAPI_TYPE_VIDEO_BUFFER); +} + +GstBuffer * gst_vaapi_video_buffer_new(void) { - GstMiniObject *object; - - object = gst_mini_object_new(GST_VAAPI_TYPE_VIDEO_BUFFER); - if (!object) - return NULL; - - return GST_VAAPI_VIDEO_BUFFER(object); + return _gst_vaapi_video_buffer_new(); } /** @@ -165,7 +174,7 @@ gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) if (!is_image_pool && !is_surface_pool) return NULL; - buffer = gst_vaapi_video_buffer_new(); + buffer = _gst_vaapi_video_buffer_new(); if (buffer && ((is_image_pool && gst_vaapi_video_buffer_set_image_from_pool(buffer, pool)) || @@ -193,7 +202,7 @@ gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); - buffer = gst_vaapi_video_buffer_new(); + buffer = _gst_vaapi_video_buffer_new(); if (buffer) gst_vaapi_video_buffer_set_image(buffer, image); return GST_BUFFER(buffer); @@ -215,7 +224,7 @@ gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - buffer = gst_vaapi_video_buffer_new(); + buffer = _gst_vaapi_video_buffer_new(); if (buffer) gst_vaapi_video_buffer_set_surface(buffer, surface); return GST_BUFFER(buffer); @@ -237,7 +246,7 @@ gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); - buffer = gst_vaapi_video_buffer_new(); + buffer = _gst_vaapi_video_buffer_new(); if (buffer) gst_vaapi_video_buffer_set_surface_proxy(buffer, proxy); return GST_BUFFER(buffer); diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index 1303df7cf2..55b4633791 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -82,6 +82,9 @@ struct _GstVaapiVideoBufferClass { GType gst_vaapi_video_buffer_get_type(void); +GstBuffer * +gst_vaapi_video_buffer_new(void); + GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); From 73b50487f35a8c98ce5e1451fcbf7c03b874c05b Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 21:59:14 +0000 Subject: [PATCH 0292/3781] Add missing GstBaseSink::buffer_alloc() override. i.e. make sure to allocate a GstVaapiVideoBuffer instead of a plain GstBuffer from the peer pad. --- gst/vaapisink/gstvaapisink.c | 69 ++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 51cea5b163..bb56b75705 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -275,6 +275,54 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return TRUE; } +static GstFlowReturn +gst_vaapisink_buffer_alloc( + GstBaseSink *base_sink, + guint64 offset, + guint size, + GstCaps *caps, + GstBuffer **pout_buffer +) +{ + GstBuffer *buffer; + GstCaps *sink_caps; + + sink_caps = gst_static_pad_template_get_caps(&gst_vaapisink_sink_factory); + if (!sink_caps) + goto error_no_sink_caps; + + if (!gst_caps_is_always_compatible(caps, sink_caps)) + goto error_invalid_caps; + + buffer = gst_vaapi_video_buffer_new(); + if (!buffer) + goto error_create_buffer; + + gst_buffer_set_caps(buffer, caps); + gst_caps_unref(sink_caps); + *pout_buffer = buffer; + return GST_FLOW_OK; + + /* ERRORS */ +error_no_sink_caps: + { + GST_DEBUG("failed to get static sink caps"); + return GST_FLOW_UNEXPECTED; + } +error_invalid_caps: + { + GST_DEBUG("failed to validate input caps"); + gst_caps_unref(sink_caps); + return GST_FLOW_UNEXPECTED; + } +error_create_buffer: + { + GST_DEBUG("failed to create video buffer"); + gst_caps_unref(sink_caps); + return GST_FLOW_UNEXPECTED; + } +} + #if USE_VAAPISINK_GLX static void render_background(GstVaapiSink *sink) @@ -539,18 +587,19 @@ static void gst_vaapisink_base_init(gpointer klass) static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass); + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass); - object_class->finalize = gst_vaapisink_finalize; - object_class->set_property = gst_vaapisink_set_property; - object_class->get_property = gst_vaapisink_get_property; + object_class->finalize = gst_vaapisink_finalize; + object_class->set_property = gst_vaapisink_set_property; + object_class->get_property = gst_vaapisink_get_property; - basesink_class->start = gst_vaapisink_start; - basesink_class->stop = gst_vaapisink_stop; - basesink_class->set_caps = gst_vaapisink_set_caps; - basesink_class->preroll = gst_vaapisink_show_frame; - basesink_class->render = gst_vaapisink_show_frame; + basesink_class->start = gst_vaapisink_start; + basesink_class->stop = gst_vaapisink_stop; + basesink_class->set_caps = gst_vaapisink_set_caps; + basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; + basesink_class->preroll = gst_vaapisink_show_frame; + basesink_class->render = gst_vaapisink_show_frame; #if USE_VAAPISINK_GLX g_object_class_install_property From e7c98453748ac79cf4a93d1d024d09d84852a47e Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 22:00:37 +0000 Subject: [PATCH 0293/3781] Complete initialization of the GstVaapiVideoBuffer. Some frames start to show up. --- gst/vaapidecode/gstvaapidecode.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 9600858a3a..762e0ce65b 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -105,11 +105,20 @@ gst_vaapidecode_task_cb(gpointer data) return; buffer = NULL; - ret = gst_pad_alloc_buffer(decode->srcpad, 0, 0, GST_PAD_CAPS(decode->srcpad), &buffer); + ret = gst_pad_alloc_buffer( + decode->srcpad, + 0, 0, + GST_PAD_CAPS(decode->srcpad), + &buffer + ); if (ret != GST_FLOW_OK || !buffer) goto error_create_buffer; GST_BUFFER_TIMESTAMP(buffer) = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); + gst_vaapi_video_buffer_set_surface_proxy( + GST_VAAPI_VIDEO_BUFFER(buffer), + proxy + ); ret = gst_pad_push(decode->srcpad, buffer); if (ret != GST_FLOW_OK) From fcede672dfda98b6fe86cee9224cf24cf66d0ea2 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 29 Apr 2010 23:09:07 +0000 Subject: [PATCH 0294/3781] Fix H.264 decoding with AVC1 format bitstreams. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 77 ++++++++++++--------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 365cbde774..eae51da9fa 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -245,6 +245,7 @@ gst_vaapi_decoder_ffmpeg_close(GstVaapiDecoderFfmpeg *ffdecoder) if (priv->avctx) { av_freep(&priv->avctx->extradata); + priv->avctx->extradata_size = 0; avcodec_close(priv->avctx); } @@ -259,6 +260,7 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe { GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(ffdecoder); + GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(ffdecoder); GstVaapiCodec codec = GST_VAAPI_DECODER_CODEC(ffdecoder); enum CodecID codec_id; AVCodec *ffcodec; @@ -266,6 +268,13 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe gst_vaapi_decoder_ffmpeg_close(ffdecoder); + if (codec_data) { + const guchar *data = GST_BUFFER_DATA(codec_data); + const guint size = GST_BUFFER_SIZE(codec_data); + if (!set_codec_data(priv->avctx, data, size)) + return FALSE; + } + codec_id = get_codec_id_from_codec(codec); if (codec_id == CODEC_ID_NONE) return FALSE; @@ -274,18 +283,20 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe if (!ffcodec) return FALSE; - priv->pctx = av_parser_init(codec_id); - if (!priv->pctx) - return FALSE; - - /* XXX: av_find_stream_info() does this and some codecs really - want hard an extradata buffer for initialization (e.g. VC-1) */ - if (!priv->avctx->extradata && priv->pctx->parser->split) { - const guchar *buf = GST_BUFFER_DATA(buffer); - guint buf_size = GST_BUFFER_SIZE(buffer); - buf_size = priv->pctx->parser->split(priv->avctx, buf, buf_size); - if (buf_size > 0 && !set_codec_data(priv->avctx, buf, buf_size)) + if (codec_id != CODEC_ID_H264 || priv->avctx->extradata_size == 0) { + priv->pctx = av_parser_init(codec_id); + if (!priv->pctx) return FALSE; + + /* XXX: av_find_stream_info() does this and some codecs really + want hard an extradata buffer for initialization (e.g. VC-1) */ + if (!priv->avctx->extradata && priv->pctx->parser->split) { + const guchar *buf = GST_BUFFER_DATA(buffer); + guint buf_size = GST_BUFFER_SIZE(buffer); + buf_size = priv->pctx->parser->split(priv->avctx, buf, buf_size); + if (buf_size > 0 && !set_codec_data(priv->avctx, buf, buf_size)) + return FALSE; + } } GST_VAAPI_DISPLAY_LOCK(display); @@ -313,9 +324,7 @@ gst_vaapi_decoder_ffmpeg_destroy(GstVaapiDecoderFfmpeg *ffdecoder) static gboolean gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) { - GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(ffdecoder); GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); if (!priv->frame) { priv->frame = avcodec_alloc_frame(); @@ -329,13 +338,6 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) return FALSE; } - if (codec_data) { - const guchar *data = GST_BUFFER_DATA(codec_data); - const guint size = GST_BUFFER_SIZE(codec_data); - if (!set_codec_data(priv->avctx, data, size)) - return FALSE; - } - if (!priv->vactx) { priv->vactx = g_new(GstVaapiContextFfmpeg, 1); if (!priv->vactx) @@ -410,21 +412,28 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) inbuf_size = GST_BUFFER_SIZE(buffer); inbuf_ts = GST_BUFFER_TIMESTAMP(buffer); - do { - int parsed_size = av_parser_parse( - priv->pctx, - priv->avctx, - &outbuf, &outbuf_size, - inbuf, inbuf_size, - inbuf_ts, inbuf_ts - ); - got_frame = outbuf && outbuf_size > 0; + if (priv->pctx) { + do { + int parsed_size = av_parser_parse( + priv->pctx, + priv->avctx, + &outbuf, &outbuf_size, + inbuf, inbuf_size, + inbuf_ts, inbuf_ts + ); + got_frame = outbuf && outbuf_size > 0; - if (parsed_size > 0) { - inbuf += parsed_size; - inbuf_size -= parsed_size; - } - } while (!got_frame && inbuf_size > 0); + if (parsed_size > 0) { + inbuf += parsed_size; + inbuf_size -= parsed_size; + } + } while (!got_frame && inbuf_size > 0); + } + else { + outbuf = inbuf; + outbuf_size = inbuf_size; + got_frame = inbuf && inbuf_size > 0; + } if (!got_frame && !GST_BUFFER_IS_EOS(buffer)) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; From 800faf9ea7d85d903984b4e0abf82711a79c1b23 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 30 Apr 2010 08:18:07 +0000 Subject: [PATCH 0295/3781] Document H.264 / AVC1 format case better. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index eae51da9fa..be1bceb1d6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -264,6 +264,7 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe GstVaapiCodec codec = GST_VAAPI_DECODER_CODEC(ffdecoder); enum CodecID codec_id; AVCodec *ffcodec; + gboolean parser_is_needed; int ret; gst_vaapi_decoder_ffmpeg_close(ffdecoder); @@ -283,7 +284,18 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe if (!ffcodec) return FALSE; - if (codec_id != CODEC_ID_H264 || priv->avctx->extradata_size == 0) { + switch (codec_id) { + case CODEC_ID_H264: + /* For AVC1 formats, sequence headers are in extradata and + input encoded buffers represent the whole NAL unit */ + parser_is_needed = priv->avctx->extradata_size == 0; + break; + default: + parser_is_needed = TRUE; + break; + } + + if (parser_is_needed) { priv->pctx = av_parser_init(codec_id); if (!priv->pctx) return FALSE; From 1b76d72b9860bdab60254fd4b4b464668c8a8ead Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 30 Apr 2010 09:48:41 +0000 Subject: [PATCH 0296/3781] Add GST_VAAPI_ENTRYPOINT_SLICE_ENCODE. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 9 ++++++--- gst-libs/gst/vaapi/gstvaapiprofile.h | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 11c67ad05d..06ae214216 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -92,9 +92,12 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { /* Entry-points */ static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = { - { GST_VAAPI_ENTRYPOINT_VLD, VAEntrypointVLD }, - { GST_VAAPI_ENTRYPOINT_IDCT, VAEntrypointIDCT }, - { GST_VAAPI_ENTRYPOINT_MOCO, VAEntrypointMoComp }, + { GST_VAAPI_ENTRYPOINT_VLD, VAEntrypointVLD }, + { GST_VAAPI_ENTRYPOINT_IDCT, VAEntrypointIDCT }, + { GST_VAAPI_ENTRYPOINT_MOCO, VAEntrypointMoComp }, +#if VA_CHECK_VERSION(0,30,0) + { GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, VAEntrypointEncSlice }, +#endif { 0, } }; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 4746f69bc1..48c80cd8f3 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -112,13 +112,15 @@ enum _GstVaapiProfile { * @GST_VAAPI_ENTRYPOINT_VLD: Variable Length Decoding * @GST_VAAPI_ENTRYPOINT_IDCT: Inverse Decrete Cosine Transform * @GST_VAAPI_ENTRYPOINT_MOCO: Motion Compensation + * @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: Encode Slice * * The set of all entrypoints for #GstVaapiEntrypoint */ enum _GstVaapiEntrypoint { GST_VAAPI_ENTRYPOINT_VLD = 1, GST_VAAPI_ENTRYPOINT_IDCT, - GST_VAAPI_ENTRYPOINT_MOCO + GST_VAAPI_ENTRYPOINT_MOCO, + GST_VAAPI_ENTRYPOINT_SLICE_ENCODE }; GstVaapiProfile From ee000a357b254e22375e77c0e0dfcdfd566a85ba Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 30 Apr 2010 09:52:29 +0000 Subject: [PATCH 0297/3781] Fix gst_vaapi_display_has_{decoder,encoder}() to check for the entrypoint too. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 91 ++++++++++++++++------------ gst-libs/gst/vaapi/gstvaapidisplay.h | 10 +-- 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index d002b53734..051848c6f5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -35,6 +35,12 @@ GST_DEBUG_CATEGORY(gst_debug_vaapi); G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT); +typedef struct _GstVaapiConfig GstVaapiConfig; +struct _GstVaapiConfig { + GstVaapiProfile profile; + GstVaapiEntrypoint entrypoint; +}; + enum { PROP_0, @@ -124,23 +130,30 @@ compare_rgb_formats(gconstpointer a, gconstpointer b) (gint)gst_vaapi_image_format_get_score(fmt2)); } -/* Check if profiles array contains profile */ +/* Check if configs array contains profile at entrypoint */ static inline gboolean -find_profile(GArray *profiles, GstVaapiProfile profile) +find_config( + GArray *configs, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint +) { + GstVaapiConfig *config; guint i; - for (i = 0; i < profiles->len; i++) - if (g_array_index(profiles, GstVaapiProfile, i) == profile) + for (i = 0; i < configs->len; i++) { + config = &g_array_index(configs, GstVaapiConfig, i); + if (config->profile == profile && config->entrypoint == entrypoint) return TRUE; + } return FALSE; } -/* Convert profiles array to GstCaps */ +/* Convert configs array to profiles as GstCaps */ static GstCaps * -get_profile_caps(GArray *profiles) +get_profile_caps(GArray *configs) { - GstVaapiProfile profile; + GstVaapiConfig *config; GstCaps *out_caps, *caps; guint i; @@ -148,11 +161,11 @@ get_profile_caps(GArray *profiles) if (!out_caps) return NULL; - for (i = 0; i < profiles->len; i++) { - profile = g_array_index(profiles, GstVaapiProfile, i); - caps = gst_vaapi_profile_get_caps(profile); + for (i = 0; i < configs->len; i++) { + config = &g_array_index(configs, GstVaapiConfig, i); + caps = gst_vaapi_profile_get_caps(config->profile); if (caps) - gst_caps_append(out_caps, caps); + gst_caps_merge(out_caps, caps); } return out_caps; } @@ -322,19 +335,18 @@ gst_vaapi_display_create(GstVaapiDisplay *display) for (i = 0; i < n; i++) GST_DEBUG(" %s", string_of_VAProfile(profiles[i])); - priv->decoders = g_array_new(FALSE, FALSE, sizeof(GstVaapiProfile)); + priv->decoders = g_array_new(FALSE, FALSE, sizeof(GstVaapiConfig)); if (!priv->decoders) goto end; - priv->encoders = g_array_new(FALSE, FALSE, sizeof(GstVaapiProfile)); + priv->encoders = g_array_new(FALSE, FALSE, sizeof(GstVaapiConfig)); if (!priv->encoders) goto end; for (i = 0; i < n; i++) { - GstVaapiProfile profile; - gboolean has_decoder = FALSE, has_encoder = FALSE; + GstVaapiConfig config; - profile = gst_vaapi_profile(profiles[i]); - if (!profile) + config.profile = gst_vaapi_profile(profiles[i]); + if (!config.profile) continue; status = vaQueryConfigEntrypoints( @@ -346,25 +358,18 @@ gst_vaapi_display_create(GstVaapiDisplay *display) goto end; for (j = 0; j < num_entrypoints; j++) { - switch (entrypoints[j]) { - case VAEntrypointVLD: - case VAEntrypointIZZ: - case VAEntrypointIDCT: - case VAEntrypointMoComp: - case VAEntrypointDeblocking: - has_decoder = TRUE; + config.entrypoint = gst_vaapi_entrypoint(entrypoints[j]); + switch (config.entrypoint) { + case GST_VAAPI_ENTRYPOINT_VLD: + case GST_VAAPI_ENTRYPOINT_IDCT: + case GST_VAAPI_ENTRYPOINT_MOCO: + g_array_append_val(priv->decoders, config); break; -#if VA_CHECK_VERSION(0,30,0) - case VAEntrypointEncSlice: - has_encoder = TRUE; + case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: + g_array_append_val(priv->encoders, config); break; -#endif } } - if (has_decoder) - g_array_append_val(priv->decoders, profile); - if (has_encoder) - g_array_append_val(priv->encoders, profile); } /* VA image formats */ @@ -780,20 +785,23 @@ gst_vaapi_display_get_decode_caps(GstVaapiDisplay *display) * gst_vaapi_display_has_decoder: * @display: a #GstVaapiDisplay * @profile: a #VAProfile + * @entrypoint: a #GstVaaiEntrypoint * - * Returns whether VA @display supports @profile for decoding. + * Returns whether VA @display supports @profile for decoding at the + * specified @entrypoint. * * Return value: %TRUE if VA @display supports @profile for decoding. */ gboolean gst_vaapi_display_has_decoder( - GstVaapiDisplay *display, - GstVaapiProfile profile + GstVaapiDisplay *display, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint ) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); - return find_profile(display->priv->decoders, profile); + return find_config(display->priv->decoders, profile, entrypoint); } /** @@ -816,20 +824,23 @@ gst_vaapi_display_get_encode_caps(GstVaapiDisplay *display) * gst_vaapi_display_has_encoder: * @display: a #GstVaapiDisplay * @profile: a #VAProfile + * @entrypoint: a #GstVaapiEntrypoint * - * Returns whether VA @display supports @profile for encoding. + * Returns whether VA @display supports @profile for encoding at the + * specified @entrypoint. * * Return value: %TRUE if VA @display supports @profile for encoding. */ gboolean gst_vaapi_display_has_encoder( - GstVaapiDisplay *display, - GstVaapiProfile profile + GstVaapiDisplay *display, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint ) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); - return find_profile(display->priv->encoders, profile); + return find_config(display->priv->encoders, profile, entrypoint); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index b66cdf89d9..e1fdae44f1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -147,8 +147,9 @@ gst_vaapi_display_get_decode_caps(GstVaapiDisplay *display); gboolean gst_vaapi_display_has_decoder( - GstVaapiDisplay *display, - GstVaapiProfile profile + GstVaapiDisplay *display, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint ); GstCaps * @@ -156,8 +157,9 @@ gst_vaapi_display_get_encode_caps(GstVaapiDisplay *display); gboolean gst_vaapi_display_has_encoder( - GstVaapiDisplay *display, - GstVaapiProfile profile + GstVaapiDisplay *display, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint ); GstCaps * From 49f8bad4784dc461f47ccf7a85ee7d717f619d43 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 30 Apr 2010 12:04:12 +0000 Subject: [PATCH 0298/3781] Move VA context reset to AVCodecContext.get_context() as the surface sizes can change. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 110 ++++++++++++++------ 1 file changed, 79 insertions(+), 31 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index be1bceb1d6..cd1cba8f8f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -47,6 +47,8 @@ G_DEFINE_TYPE(GstVaapiDecoderFfmpeg, typedef struct _GstVaapiContextFfmpeg GstVaapiContextFfmpeg; struct _GstVaapiContextFfmpeg { struct vaapi_context base; + GstVaapiProfile profile; + GstVaapiEntrypoint entrypoint; GstVaapiDecoderFfmpeg *decoder; }; @@ -74,17 +76,30 @@ get_codec_id_from_codec(GstVaapiCodec codec) return CODEC_ID_NONE; } +/** Converts PixelFormat to entrypoint */ +static GstVaapiEntrypoint +get_entrypoint(enum PixelFormat pix_fmt) +{ + switch (pix_fmt) { + case PIX_FMT_VAAPI_VLD: return GST_VAAPI_ENTRYPOINT_VLD; + case PIX_FMT_VAAPI_IDCT: return GST_VAAPI_ENTRYPOINT_IDCT; + case PIX_FMT_VAAPI_MOCO: return GST_VAAPI_ENTRYPOINT_MOCO; + default: break; + } + return 0; +} + /** Finds a suitable profile from FFmpeg context */ static GstVaapiProfile -get_profile(AVCodecContext *avctx) +get_profile(AVCodecContext *avctx, GstVaapiEntrypoint entrypoint) { GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; GstVaapiDisplay *display; - GstVaapiProfile test_profiles[4]; + GstVaapiProfile profiles[4]; guint i, n_profiles = 0; -#define ADD_PROFILE(profile) do { \ - test_profiles[n_profiles++] = GST_VAAPI_PROFILE_##profile; \ +#define ADD_PROFILE(profile) do { \ + profiles[n_profiles++] = GST_VAAPI_PROFILE_##profile; \ } while (0) switch (avctx->codec_id) { @@ -131,16 +146,54 @@ get_profile(AVCodecContext *avctx) return 0; for (i = 0; i < n_profiles; i++) - if (gst_vaapi_display_has_decoder(display, test_profiles[i])) - return test_profiles[i]; + if (gst_vaapi_display_has_decoder(display, profiles[i], entrypoint)) + return profiles[i]; return 0; } +/** Ensures VA context is correctly set up for the current FFmpeg context */ +static GstVaapiContext * +get_context(AVCodecContext *avctx) +{ + GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; + GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(vactx->decoder); + GstVaapiDisplay *display; + GstVaapiContext *context; + gboolean success; + + if (!avctx->width || !avctx->height) + return NULL; + + success = gst_vaapi_decoder_ensure_context( + decoder, + vactx->profile, + vactx->entrypoint, + avctx->width, + avctx->height + ); + if (!success) { + GST_DEBUG("failed to reset VA context:"); + GST_DEBUG(" profile 0x%08x", vactx->profile); + GST_DEBUG(" entrypoint %d", vactx->entrypoint); + GST_DEBUG(" surface size %dx%d", avctx->width, avctx->height); + return NULL; + } + display = GST_VAAPI_DECODER_DISPLAY(decoder); + context = GST_VAAPI_DECODER_CONTEXT(decoder); + vactx->base.display = GST_VAAPI_DISPLAY_VADISPLAY(display); + vactx->base.context_id = GST_VAAPI_OBJECT_ID(context); + return context; +} + /** Sets AVCodecContext.extradata with additional codec data */ static gboolean set_codec_data(AVCodecContext *avctx, const guchar *buf, guint buf_size) { av_freep(&avctx->extradata); + avctx->extradata_size = 0; + if (!buf || buf_size < 1) + return TRUE; + avctx->extradata = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!avctx->extradata) return FALSE; @@ -155,32 +208,22 @@ static enum PixelFormat gst_vaapi_decoder_ffmpeg_get_format(AVCodecContext *avctx, const enum PixelFormat *fmt) { GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; - GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(vactx->decoder); GstVaapiProfile profile; - gboolean success; + GstVaapiEntrypoint entrypoint; guint i; - profile = get_profile(avctx); - if (!profile) - return PIX_FMT_NONE; - /* XXX: only VLD entrypoint is supported at this time */ - for (i = 0; fmt[i] != PIX_FMT_NONE; i++) - if (fmt[i] == PIX_FMT_VAAPI_VLD) - break; + for (i = 0; fmt[i] != PIX_FMT_NONE; i++) { + entrypoint = get_entrypoint(fmt[i]); + if (entrypoint != GST_VAAPI_ENTRYPOINT_VLD) + continue; - success = gst_vaapi_decoder_ensure_context( - decoder, - profile, - GST_VAAPI_ENTRYPOINT_VLD, - avctx->width, avctx->height - ); - if (success) { - GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder); - GstVaapiContext * const context = GST_VAAPI_DECODER_CONTEXT(decoder); - vactx->base.display = GST_VAAPI_DISPLAY_VADISPLAY(display); - vactx->base.context_id = GST_VAAPI_OBJECT_ID(context); - return fmt[i]; + profile = get_profile(avctx, entrypoint); + if (profile) { + vactx->profile = profile; + vactx->entrypoint = entrypoint; + return fmt[i]; + } } return PIX_FMT_NONE; } @@ -189,11 +232,14 @@ gst_vaapi_decoder_ffmpeg_get_format(AVCodecContext *avctx, const enum PixelForma static int gst_vaapi_decoder_ffmpeg_get_buffer(AVCodecContext *avctx, AVFrame *pic) { - GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; - GstVaapiContext * const context = GST_VAAPI_DECODER_CONTEXT(vactx->decoder); + GstVaapiContext *context; GstVaapiSurface *surface; GstVaapiID surface_id; + context = get_context(avctx); + if (!context) + return -1; + surface = gst_vaapi_context_get_surface(context); if (!surface) { GST_DEBUG("failed to get a free VA surface"); @@ -244,9 +290,9 @@ gst_vaapi_decoder_ffmpeg_close(GstVaapiDecoderFfmpeg *ffdecoder) GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; if (priv->avctx) { + avcodec_close(priv->avctx); av_freep(&priv->avctx->extradata); priv->avctx->extradata_size = 0; - avcodec_close(priv->avctx); } if (priv->pctx) { @@ -314,7 +360,9 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe GST_VAAPI_DISPLAY_LOCK(display); ret = avcodec_open(priv->avctx, ffcodec); GST_VAAPI_DISPLAY_UNLOCK(display); - return ret == 0; + if (ret < 0) + return FALSE; + return TRUE; } static void From 4c7c0307c4f85f1bb5978b2373dcb9747fc9e34d Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 30 Apr 2010 13:13:50 +0000 Subject: [PATCH 0299/3781] 0.2.0. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index e56ded6b07..980fc72492 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) -m4_define([gst_vaapi_minor_version], [1]) -m4_define([gst_vaapi_micro_version], [3]) +m4_define([gst_vaapi_minor_version], [2]) +m4_define([gst_vaapi_micro_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From a4d201aaf93816fd23ed1eeffae6786cec883020 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 30 Apr 2010 15:37:28 +0000 Subject: [PATCH 0300/3781] Drop excessive threading that over-complicates synchronisation. MPEG-2 & H.264 videos now play but there are other problems (timestamps). --- gst-libs/gst/vaapi/gstvaapidecoder.c | 274 +++++----------------- gst-libs/gst/vaapi/gstvaapidecoder.h | 7 - gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 23 +- gst/vaapidecode/gstvaapidecode.c | 110 ++------- gst/vaapidecode/gstvaapidecode.h | 2 - tests/test-decode.c | 17 +- 6 files changed, 102 insertions(+), 331 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index a6c848ca2b..7b69475c6f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -52,45 +52,6 @@ enum { PROP_CODEC_DATA }; -/* Wait _at most_ 10 ms for encoded buffers between each decoding step */ -#define GST_VAAPI_DECODER_TIMEOUT (10000) - -static GstBuffer * -pop_buffer(GstVaapiDecoder *decoder); - -static gboolean -push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface); - -static DecodedSurface * -pop_surface(GstVaapiDecoder *decoder, GTimeVal *end_time); - -static void -decoder_task(gpointer data) -{ - GstVaapiDecoder * const decoder = GST_VAAPI_DECODER_CAST(data); - GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); - GstBuffer *buffer; - - buffer = pop_buffer(decoder); - if (!buffer) - return; - - priv->decoder_status = klass->decode(decoder, buffer); - GST_DEBUG("decode frame (status = %d)", priv->decoder_status); - - switch (priv->decoder_status) { - case GST_VAAPI_DECODER_STATUS_SUCCESS: - case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: - break; - default: - /* Send an empty surface to signal an error */ - push_surface(decoder, NULL); - gst_task_pause(priv->decoder_task); - break; - } -} - static void update_clock(GstVaapiDecoder *decoder, GstBuffer *buffer) { @@ -177,7 +138,7 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) GST_DEBUG("queue encoded data buffer %p (%d bytes)", buffer, GST_BUFFER_SIZE(buffer)); - g_async_queue_push(priv->buffers, buffer); + g_queue_push_tail(priv->buffers, buffer); return TRUE; } @@ -185,13 +146,9 @@ static GstBuffer * pop_buffer(GstVaapiDecoder *decoder) { GstVaapiDecoderPrivate * const priv = decoder->priv; - GTimeVal end_time; GstBuffer *buffer; - g_get_current_time(&end_time); - g_time_val_add(&end_time, GST_VAAPI_DECODER_TIMEOUT); - - buffer = g_async_queue_timed_pop(priv->buffers, &end_time); + buffer = g_queue_pop_head(priv->buffers); if (!buffer) return NULL; @@ -202,6 +159,28 @@ pop_buffer(GstVaapiDecoder *decoder) return buffer; } +static GstVaapiDecoderStatus +decode_step(GstVaapiDecoder *decoder) +{ + GstVaapiDecoderStatus status; + GstBuffer *buffer; + + do { + buffer = pop_buffer(decoder); + if (!buffer) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + status = GST_VAAPI_DECODER_GET_CLASS(decoder)->decode(decoder, buffer); + GST_DEBUG("decode frame (status = %d)", status); + if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + if (GST_BUFFER_IS_EOS(buffer)) + return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + } while (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA); + return status; +} + static inline DecodedSurface * create_surface(void) { @@ -224,34 +203,26 @@ push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface) if (!ds) return FALSE; - if (surface) { - GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); - ds->proxy = gst_vaapi_surface_proxy_new(priv->context, surface); - if (ds->proxy) { - ds->status = GST_VAAPI_DECODER_STATUS_SUCCESS; - gst_vaapi_surface_proxy_set_timestamp( - ds->proxy, priv->surface_timestamp); - } - else - ds->status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); + ds->proxy = gst_vaapi_surface_proxy_new(priv->context, surface); + if (ds->proxy) { + ds->status = GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_vaapi_surface_proxy_set_timestamp(ds->proxy, priv->surface_timestamp); } else - ds->status = priv->decoder_status; + ds->status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - g_async_queue_push(priv->surfaces, ds); + g_queue_push_tail(priv->surfaces, ds); return TRUE; } static inline DecodedSurface * -pop_surface(GstVaapiDecoder *decoder, GTimeVal *end_time) +pop_surface(GstVaapiDecoder *decoder) { GstVaapiDecoderPrivate * const priv = decoder->priv; - if (!gst_vaapi_decoder_start(decoder)) - return NULL; - - return g_async_queue_timed_pop(priv->surfaces, end_time); + return g_queue_pop_head(priv->surfaces); } static inline void @@ -269,12 +240,10 @@ set_codec_data(GstVaapiDecoder *decoder, GstBuffer *codec_data) } static void -clear_async_queue(GAsyncQueue *q, GDestroyNotify destroy) +clear_queue(GQueue *q, GDestroyNotify destroy) { - guint i, qlen = g_async_queue_length(q); - - for (i = 0; i < qlen; i++) - destroy(g_async_queue_pop(q)); + while (!g_queue_is_empty(q)) + destroy(g_queue_pop_head(q)); } static void @@ -283,8 +252,6 @@ gst_vaapi_decoder_finalize(GObject *object) GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object); GstVaapiDecoderPrivate * const priv = decoder->priv; - gst_vaapi_decoder_stop(decoder); - set_codec_data(decoder, NULL); if (priv->context) { @@ -293,14 +260,14 @@ gst_vaapi_decoder_finalize(GObject *object) } if (priv->buffers) { - clear_async_queue(priv->buffers, (GDestroyNotify)gst_buffer_unref); - g_async_queue_unref(priv->buffers); + clear_queue(priv->buffers, (GDestroyNotify)gst_buffer_unref); + g_queue_free(priv->buffers); priv->buffers = NULL; } if (priv->surfaces) { - clear_async_queue(priv->surfaces, (GDestroyNotify)destroy_surface); - g_async_queue_unref(priv->surfaces); + clear_queue(priv->surfaces, (GDestroyNotify)destroy_surface); + g_queue_free(priv->surfaces); priv->surfaces = NULL; } @@ -421,81 +388,8 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->fps_d = 30; priv->surface_timestamp = GST_CLOCK_TIME_NONE; priv->surface_duration = GST_CLOCK_TIME_NONE; - priv->buffers = g_async_queue_new(); - priv->surfaces = g_async_queue_new(); - priv->decoder_task = NULL; - - g_static_rec_mutex_init(&priv->decoder_task_lock); -} - -/** - * gst_vaapi_decoder_start: - * @decoder: a #GstVaapiDecoder - * - * Starts the decoder. This creates the internal decoder thread, if - * necessary. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_decoder_start(GstVaapiDecoder *decoder) -{ - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); - - if (decoder->priv->decoder_task) - return TRUE; - - decoder->priv->decoder_task = gst_task_create(decoder_task, decoder); - if (!decoder->priv->decoder_task) - return FALSE; - - gst_task_set_lock(decoder->priv->decoder_task, &decoder->priv->decoder_task_lock); - return gst_task_start(decoder->priv->decoder_task); -} - -/** - * gst_vaapi_decoder_pause: - * @decoder: a #GstVaapiDecoder - * - * Pauses the decoder. It can be made active again through - * gst_vaapi_decoder_start() or definitely stopped through - * gst_vaapi_decoder_stop(). - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_decoder_pause(GstVaapiDecoder *decoder) -{ - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); - - return gst_task_pause(decoder->priv->decoder_task); -} - -/** - * gst_vaapi_decoder_stop: - * @decoder: a #GstVaapiDecoder - * - * Stops the decoder. This destroys any decoding thread that was - * previously created by gst_vaapi_decoder_start(). Only - * gst_vaapi_decoder_get_surface() on the queued surfaces will be - * allowed at this point. - * - * Return value: %FALSE on success - */ -gboolean -gst_vaapi_decoder_stop(GstVaapiDecoder *decoder) -{ - gboolean success; - - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); - - if (!decoder->priv->decoder_task) - return FALSE; - - success = gst_task_join(decoder->priv->decoder_task); - g_object_unref(decoder->priv->decoder_task); - decoder->priv->decoder_task = NULL; - return success; + priv->buffers = g_queue_new(); + priv->surfaces = g_queue_new(); } /** @@ -625,82 +519,42 @@ gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf) * @decoder: a #GstVaapiDecoder * @pstatus: return location for the decoder status, or %NULL * - * Waits for a decoded surface to arrive. This functions blocks until - * the @decoder has a surface ready for the caller. @pstatus is - * optional but it can help to know what went wrong during the - * decoding process. + * Flushes encoded buffers to the decoder and returns a decoded + * surface, if any. * * Return value: a #GstVaapiSurfaceProxy holding the decoded surface, * or %NULL if none is available (e.g. an error). Caller owns the * returned object. g_object_unref() after usage. */ -static GstVaapiSurfaceProxy * -_gst_vaapi_decoder_get_surface( - GstVaapiDecoder *decoder, - GTimeVal *end_time, - GstVaapiDecoderStatus *pstatus -) -{ - GstVaapiDecoderStatus status; - GstVaapiSurfaceProxy *proxy; - DecodedSurface *ds; - - ds = pop_surface(decoder, end_time); - if (ds) { - proxy = ds->proxy; - status = ds->status; - destroy_surface(ds); - } - else { - proxy = NULL; - status = GST_VAAPI_DECODER_STATUS_TIMEOUT; - } - - if (pstatus) - *pstatus = status; - return proxy; -} - GstVaapiSurfaceProxy * gst_vaapi_decoder_get_surface( GstVaapiDecoder *decoder, GstVaapiDecoderStatus *pstatus ) { - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - - return _gst_vaapi_decoder_get_surface(decoder, NULL, pstatus); -} - -/** - * gst_vaapi_decoder_timed_get_surface: - * @decoder: a #GstVaapiDecoder - * @timeout: the number of microseconds to wait for the decoded surface - * @pstatus: return location for the decoder status, or %NULL - * - * Waits for a decoded surface to arrive. This function blocks for at - * least @timeout microseconds. @pstatus is optional but it can help - * to know what went wrong during the decoding process. - * - * Return value: a #GstVaapiSurfaceProxy holding the decoded surface, - * or %NULL if none is available (e.g. an error). Caller owns the - * returned object. g_object_unref() after usage. - */ -GstVaapiSurfaceProxy * -gst_vaapi_decoder_timed_get_surface( - GstVaapiDecoder *decoder, - guint32 timeout, - GstVaapiDecoderStatus *pstatus -) -{ - GTimeVal end_time; + GstVaapiSurfaceProxy *proxy = NULL; + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + DecodedSurface *ds; g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - g_get_current_time(&end_time); - g_time_val_add(&end_time, timeout); + ds = pop_surface(decoder); + if (!ds) { + do { + status = decode_step(decoder); + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); + ds = pop_surface(decoder); + } - return _gst_vaapi_decoder_get_surface(decoder, &end_time, pstatus); + if (ds) { + proxy = ds->proxy; + status = ds->status; + destroy_surface(ds); + } + + if (pstatus) + *pstatus = status; + return proxy; } gboolean diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index b3a212e26f..66373190d7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -156,13 +156,6 @@ gst_vaapi_decoder_get_surface( GstVaapiDecoderStatus *pstatus ); -GstVaapiSurfaceProxy * -gst_vaapi_decoder_timed_get_surface( - GstVaapiDecoder *decoder, - guint32 timeout, - GstVaapiDecoderStatus *pstatus -); - G_END_DECLS #endif /* GST_VAAPI_DECODER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index a27199561a..78d25791a3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -87,19 +87,16 @@ G_BEGIN_DECLS GstVaapiDecoderPrivate)) struct _GstVaapiDecoderPrivate { - GstVaapiDisplay *display; - GstVaapiContext *context; - GstVaapiCodec codec; - GstBuffer *codec_data; - guint fps_n; - guint fps_d; - GAsyncQueue *buffers; - GAsyncQueue *surfaces; - GstClockTime surface_timestamp; - GstClockTime surface_duration; - GstTask *decoder_task; - GStaticRecMutex decoder_task_lock; - GstVaapiDecoderStatus decoder_status; + GstVaapiDisplay *display; + GstVaapiContext *context; + GstVaapiCodec codec; + GstBuffer *codec_data; + guint fps_n; + guint fps_d; + GQueue *buffers; + GQueue *surfaces; + GstClockTime surface_timestamp; + GstClockTime surface_duration; }; gboolean diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 762e0ce65b..b9564f2da7 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -91,18 +91,21 @@ enum { PROP_USE_FFMPEG, }; -static void -gst_vaapidecode_task_cb(gpointer data) +static GstFlowReturn +gst_vaapidecode_step(GstVaapiDecode *decode) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(data); - GstVaapiDecoderStatus status; GstVaapiSurfaceProxy *proxy; + GstVaapiDecoderStatus status; GstBuffer *buffer; GstFlowReturn ret; - proxy = gst_vaapi_decoder_timed_get_surface(decode->decoder, 10000, &status); - if (!proxy || status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return; + proxy = gst_vaapi_decoder_get_surface(decode->decoder, &status); + if (!proxy) { + if (status != GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) + goto error_decode; + /* More data is needed */ + return GST_FLOW_OK; + } buffer = NULL; ret = gst_pad_alloc_buffer( @@ -125,9 +128,14 @@ gst_vaapidecode_task_cb(gpointer data) goto error_commit_buffer; g_object_unref(proxy); - return; + return GST_FLOW_OK; /* ERRORS */ +error_decode: + { + GST_DEBUG("decode error %d", status); + return GST_FLOW_UNEXPECTED; + } error_create_buffer: { const GstVaapiID surface_id = @@ -137,52 +145,16 @@ error_create_buffer: "surface %" GST_VAAPI_ID_FORMAT " (error %d)", GST_VAAPI_ID_ARGS(surface_id), ret); g_object_unref(proxy); - return; + return GST_FLOW_UNEXPECTED; } error_commit_buffer: { GST_DEBUG("video sink rejected the video buffer (error %d)", ret); g_object_unref(proxy); - return; + return GST_FLOW_UNEXPECTED; } } -static gboolean -gst_vaapidecode_start(GstVaapiDecode *decode) -{ - if (gst_task_get_state(decode->decoder_task) == GST_TASK_STARTED) - return TRUE; - - GST_DEBUG("start decoding threads"); - if (!gst_vaapi_decoder_start(decode->decoder)) - return FALSE; - return gst_task_start(decode->decoder_task); -} - -static gboolean -gst_vaapidecode_pause(GstVaapiDecode *decode) -{ - if (gst_task_get_state(decode->decoder_task) == GST_TASK_PAUSED) - return TRUE; - - GST_DEBUG("pause decoding threads"); - if (!gst_vaapi_decoder_pause(decode->decoder)) - return FALSE; - return gst_task_pause(decode->decoder_task); -} - -static gboolean -gst_vaapidecode_stop(GstVaapiDecode *decode) -{ - if (gst_task_get_state(decode->decoder_task) == GST_TASK_STOPPED) - return TRUE; - - GST_DEBUG("stop decoding threads"); - if (!gst_vaapi_decoder_stop(decode->decoder)) - return FALSE; - return gst_task_stop(decode->decoder_task); -} - static gboolean gst_vaapidecode_create(GstVaapiDecode *decode) { @@ -208,26 +180,12 @@ gst_vaapidecode_create(GstVaapiDecode *decode) if (decode->use_ffmpeg) decode->decoder = gst_vaapi_decoder_ffmpeg_new(display, codec, decode->codec_data); - if (!decode->decoder) - return FALSE; - - decode->decoder_task = gst_task_create(gst_vaapidecode_task_cb, decode); - if (!decode->decoder_task) - return FALSE; - - gst_task_set_lock(decode->decoder_task, &decode->decoder_task_lock); - return TRUE; + return decode->decoder != NULL; } static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { - if (decode->decoder_task) { - gst_task_join(decode->decoder_task); - g_object_unref(decode->decoder_task); - decode->decoder_task = NULL; - } - if (decode->decoder) { gst_vaapi_decoder_put_buffer(decode->decoder, NULL); g_object_unref(decode->decoder); @@ -322,8 +280,6 @@ gst_vaapidecode_change_state(GstElement *element, GstStateChange transition) case GST_STATE_CHANGE_READY_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - if (!gst_vaapidecode_start(decode)) - return GST_STATE_CHANGE_FAILURE; break; default: break; @@ -335,12 +291,8 @@ gst_vaapidecode_change_state(GstElement *element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - if (!gst_vaapidecode_pause(decode)) - return GST_STATE_CHANGE_FAILURE; break; case GST_STATE_CHANGE_PAUSED_TO_READY: - if (!gst_vaapidecode_stop(decode)) - return GST_STATE_CHANGE_FAILURE; break; default: break; @@ -424,14 +376,11 @@ gst_vaapidecode_chain(GstPad *pad, GstBuffer *buf) goto error_create_decoder; } - if (!gst_vaapidecode_start(decode)) - goto error_start_decoder; - if (!gst_vaapi_decoder_put_buffer(decode->decoder, buf)) goto error_push_buffer; gst_buffer_unref(buf); - return GST_FLOW_OK; + return gst_vaapidecode_step(decode); /* ERRORS */ error_create_decoder: @@ -440,12 +389,6 @@ error_create_decoder: gst_buffer_unref(buf); return GST_FLOW_UNEXPECTED; } -error_start_decoder: - { - GST_DEBUG("failed to start decoder"); - gst_buffer_unref(buf); - return GST_FLOW_UNEXPECTED; - } error_push_buffer: { GST_DEBUG("failed to push input buffer to decoder"); @@ -481,14 +424,11 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - decode->display = NULL; - decode->profile = 0; - decode->codec_data = NULL; - decode->decoder = NULL; - decode->decoder_task = NULL; - decode->use_ffmpeg = TRUE; - - g_static_rec_mutex_init(&decode->decoder_task_lock); + decode->display = NULL; + decode->profile = 0; + decode->codec_data = NULL; + decode->decoder = NULL; + decode->use_ffmpeg = TRUE; /* Pad through which data comes in to the element */ decode->sinkpad = gst_pad_new_from_template( diff --git a/gst/vaapidecode/gstvaapidecode.h b/gst/vaapidecode/gstvaapidecode.h index 0772c39ce1..b2b6915cd8 100644 --- a/gst/vaapidecode/gstvaapidecode.h +++ b/gst/vaapidecode/gstvaapidecode.h @@ -65,8 +65,6 @@ struct _GstVaapiDecode { GstVaapiProfile profile; GstBuffer *codec_data; GstVaapiDecoder *decoder; - GstTask *decoder_task; - GStaticRecMutex decoder_task_lock; unsigned int use_ffmpeg : 1; }; diff --git a/tests/test-decode.c b/tests/test-decode.c index 36d07afa76..f4b56b9206 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -28,10 +28,6 @@ #include "test-h264.h" #include "test-vc1.h" -/* Default timeout to wait for the first decoded frame (10 ms) */ -/* Defined to -1 if the application indefintely waits for the decoded frame */ -#define TIMEOUT -1 - typedef void (*GetVideoDataFunc)(const guchar **data, guint *size); typedef struct _CodecDefs CodecDefs; @@ -123,16 +119,9 @@ main(int argc, char *argv[]) if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) g_error("could not send EOS to the decoder"); - if (TIMEOUT < 0) { - proxy = gst_vaapi_decoder_get_surface(decoder, &status); - if (!proxy) - g_error("could not get decoded surface"); - } - else { - proxy = gst_vaapi_decoder_timed_get_surface(decoder, TIMEOUT, &status); - if (!proxy) - g_warning("Could not get decoded surface after %d us", TIMEOUT); - } + proxy = gst_vaapi_decoder_get_surface(decoder, &status); + if (!proxy) + g_error("could not get decoded surface (decoder status %d)", status); gst_vaapi_window_show(window); From a556e08e83e8834f5ad4b47cd424cf8af2bc757b Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 30 Apr 2010 15:50:19 +0000 Subject: [PATCH 0301/3781] Decode as many surfaces as possible in gst_vaapidecode_step(). --- gst/vaapidecode/gstvaapidecode.c | 58 +++++++++++++++++--------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index b9564f2da7..7261185235 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -99,35 +99,37 @@ gst_vaapidecode_step(GstVaapiDecode *decode) GstBuffer *buffer; GstFlowReturn ret; - proxy = gst_vaapi_decoder_get_surface(decode->decoder, &status); - if (!proxy) { - if (status != GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) - goto error_decode; - /* More data is needed */ - return GST_FLOW_OK; + for (;;) { + proxy = gst_vaapi_decoder_get_surface(decode->decoder, &status); + if (!proxy) { + if (status != GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) + goto error_decode; + /* More data is needed */ + break; + } + + buffer = NULL; + ret = gst_pad_alloc_buffer( + decode->srcpad, + 0, 0, + GST_PAD_CAPS(decode->srcpad), + &buffer + ); + if (ret != GST_FLOW_OK || !buffer) + goto error_create_buffer; + + GST_BUFFER_TIMESTAMP(buffer) = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); + gst_vaapi_video_buffer_set_surface_proxy( + GST_VAAPI_VIDEO_BUFFER(buffer), + proxy + ); + + ret = gst_pad_push(decode->srcpad, buffer); + if (ret != GST_FLOW_OK) + goto error_commit_buffer; + + g_object_unref(proxy); } - - buffer = NULL; - ret = gst_pad_alloc_buffer( - decode->srcpad, - 0, 0, - GST_PAD_CAPS(decode->srcpad), - &buffer - ); - if (ret != GST_FLOW_OK || !buffer) - goto error_create_buffer; - - GST_BUFFER_TIMESTAMP(buffer) = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); - gst_vaapi_video_buffer_set_surface_proxy( - GST_VAAPI_VIDEO_BUFFER(buffer), - proxy - ); - - ret = gst_pad_push(decode->srcpad, buffer); - if (ret != GST_FLOW_OK) - goto error_commit_buffer; - - g_object_unref(proxy); return GST_FLOW_OK; /* ERRORS */ From e6b3cfeacdeeb34812111d3f1f25cf675f02802c Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 06:49:19 +0000 Subject: [PATCH 0302/3781] Drop variant=itu field to help codec detection. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 06ae214216..514105d900 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -70,13 +70,13 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { }, #endif { GST_VAAPI_PROFILE_H264_BASELINE, VAProfileH264Baseline, - "video/x-h264, variant=itu", "baseline" + "video/x-h264", "baseline" }, { GST_VAAPI_PROFILE_H264_MAIN, VAProfileH264Main, - "video/x-h264, variant=itu", "main" + "video/x-h264", "main" }, { GST_VAAPI_PROFILE_H264_HIGH, VAProfileH264High, - "video/x-h264, variant=itu", "high" + "video/x-h264", "high" }, { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, "video/x-vc1", "simple" From 8d9b365a5bba083704b966fd271119a1bfc64716 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 06:49:43 +0000 Subject: [PATCH 0303/3781] Drop extraneous comma. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 514105d900..e742dc6ef5 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -59,7 +59,7 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/mpeg, mpegversion=4", "simple" }, { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, - "video/mpeg, mpegversion=4", "advanced-simple", + "video/mpeg, mpegversion=4", "advanced-simple" }, { GST_VAAPI_PROFILE_MPEG4_MAIN, VAProfileMPEG4Main, "video/mpeg, mpegversion=4", "main" From 4754317e7021e0e71aed9bc4cd46ee150115a0e3 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 07:07:27 +0000 Subject: [PATCH 0304/3781] Relicense gst-libs/ code to LGPL v2.1+. --- COPYING.LIB | 502 ++++++++++++++++++ NEWS | 1 + README | 7 +- gst-libs/gst/vaapi/gstvaapi_priv.h | 21 +- gst-libs/gst/vaapi/gstvaapicompat.h | 21 +- gst-libs/gst/vaapi/gstvaapicontext.c | 21 +- gst-libs/gst/vaapi/gstvaapicontext.h | 21 +- gst-libs/gst/vaapi/gstvaapidebug.h | 21 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 21 +- gst-libs/gst/vaapi/gstvaapidecoder.h | 21 +- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 21 +- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h | 21 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 21 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 21 +- gst-libs/gst/vaapi/gstvaapidisplay.h | 21 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 21 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 21 +- gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 21 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 21 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 21 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 21 +- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 21 +- gst-libs/gst/vaapi/gstvaapiimage.c | 21 +- gst-libs/gst/vaapi/gstvaapiimage.h | 21 +- gst-libs/gst/vaapi/gstvaapiimageformat.c | 21 +- gst-libs/gst/vaapi/gstvaapiimageformat.h | 21 +- gst-libs/gst/vaapi/gstvaapiimagepool.c | 21 +- gst-libs/gst/vaapi/gstvaapiimagepool.h | 21 +- gst-libs/gst/vaapi/gstvaapiobject.c | 21 +- gst-libs/gst/vaapi/gstvaapiobject.h | 21 +- gst-libs/gst/vaapi/gstvaapiobject_priv.h | 21 +- gst-libs/gst/vaapi/gstvaapiparamspecs.c | 21 +- gst-libs/gst/vaapi/gstvaapiparamspecs.h | 21 +- gst-libs/gst/vaapi/gstvaapiprofile.c | 21 +- gst-libs/gst/vaapi/gstvaapiprofile.h | 21 +- gst-libs/gst/vaapi/gstvaapisubpicture.h | 21 +- gst-libs/gst/vaapi/gstvaapisurface.h | 21 +- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 21 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 21 +- gst-libs/gst/vaapi/gstvaapitexture.h | 21 +- gst-libs/gst/vaapi/gstvaapitypes.h | 21 +- gst-libs/gst/vaapi/gstvaapiutils.h | 21 +- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 21 +- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 21 +- gst-libs/gst/vaapi/gstvaapivalue.h | 21 +- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 21 +- gst-libs/gst/vaapi/gstvaapivideopool.h | 21 +- gst-libs/gst/vaapi/gstvaapivideosink.h | 21 +- gst-libs/gst/vaapi/gstvaapiwindow.h | 21 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 21 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 21 +- 51 files changed, 1036 insertions(+), 482 deletions(-) create mode 100644 COPYING.LIB diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000000..4362b49151 --- /dev/null +++ b/COPYING.LIB @@ -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. + + + Copyright (C) + + 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. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/NEWS b/NEWS index e96e568e23..33df33855d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ gst-vaapi NEWS -- summary of changes. 2010-04-DD Copyright (C) 2010 Splitted-Desktop Systems Version 0.2.0 - DD.Apr.2010 +* Relicense gst-libs/ code to LGPL v2.1+ * Add FFmpeg/VAAPI decoder for the new `vaapidecode' element Version 0.1.2 - 30.Mar.2010 diff --git a/README b/README index 28431431ab..73a2b796c5 100644 --- a/README +++ b/README @@ -8,8 +8,11 @@ License ------- -gstreamer-vaapi is available under the terms of the GNU General Public -License. +gstreamer-vaapi helper libraries are available under the terms of the +GNU Lesser General Public License v2.1+. + +gstreamer-vaapi plugin elements are available under the terms of the +GNU General Public License v2+. Overview diff --git a/gst-libs/gst/vaapi/gstvaapi_priv.h b/gst-libs/gst/vaapi/gstvaapi_priv.h index fa8ce58514..cb5f9c438e 100644 --- a/gst-libs/gst/vaapi/gstvaapi_priv.h +++ b/gst-libs/gst/vaapi/gstvaapi_priv.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_PRIV_H diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 158cc78566..1ad47ef7d5 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index aeb34913dd..c0caa76569 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index f9ade817f1..71264a3152 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/gst-libs/gst/vaapi/gstvaapidebug.h b/gst-libs/gst/vaapi/gstvaapidebug.h index 9b9013ed95..8e969782e0 100644 --- a/gst-libs/gst/vaapi/gstvaapidebug.h +++ b/gst-libs/gst/vaapi/gstvaapidebug.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 7b69475c6f..2cca2e0e0c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 66373190d7..3b65fbd586 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index cd1cba8f8f..05ded90efe 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h index 487a9a66aa..015ba2fe84 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_FFMPEG_H diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 78d25791a3..9b9a7bea35 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 051848c6f5..ae1782d46c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index e1fdae44f1..91e044d81a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 14cc35b189..7e3731b327 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index 6f43368fc9..8c3ff156d1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index d6758b02f4..6e13202f1d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 308da874f3..1ab5cc6898 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index f61a8632da..9e7ca77cb9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 8a52c577cb..732057e61e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index 9ffb1aa188..eb7237c404 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 3cc2251238..b496a74971 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index a9a865187c..e17a0dd3d4 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_IMAGE_H diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 038c37d656..a34157aff5 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index c48635947a..16029b658f 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_IMAGE_FORMAT_H diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 1bdd05936d..bdc1bb80c0 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index c5c7a02900..0592910daf 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_IMAGE_POOL_H diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 368166f96d..800a29781d 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index c0a024e11f..a5313538f6 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_OBJECT_H diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 1720d62ff1..7de6721175 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_OBJECT_PRIV_H diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.c b/gst-libs/gst/vaapi/gstvaapiparamspecs.c index ef85a57f28..3545f64555 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.c +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.h b/gst-libs/gst/vaapi/gstvaapiparamspecs.h index 96cee242df..2ebdfbdc9c 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.h +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_PARAM_SPECS_H diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index e742dc6ef5..3edb14fee3 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 48c80cd8f3..718ccffef2 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_PROFILE_H diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 237aa5c6ee..bf7e22c999 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_SUBPICTURE_H diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 668af90e46..0cb27759f2 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_SURFACE_H diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 66a4654afb..2b38d11484 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_SURFACE_POOL_H diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 5e2d833fba..1ccb81592d 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_SURFACE_PROXY_H diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 5620cceccd..54d341b526 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_TEXTURE_H diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index d35216e56d..047db2db6a 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_TYPES_H diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 2ac019715f..1f345ec088 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_UTILS_H diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 4d09fdd740..ed8856c48c 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_UTILS_GLX_H diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index ab8fb5d204..a3e8ad7967 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_UTILS_X11_H diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index 0011984164..2bed3766a8 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_VALUE_H diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index 55b4633791..a885976565 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_VIDEO_BUFFER_H diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 5dce39f28f..7552ef7189 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_VIDEO_POOL_H diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.h b/gst-libs/gst/vaapi/gstvaapivideosink.h index 7254e19b25..1810a8e189 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.h +++ b/gst-libs/gst/vaapi/gstvaapivideosink.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_VIDEO_SINK_H diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 8988c1cb30..36c773d4b2 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_WINDOW_H diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index 2090640fbd..3e58552d73 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_WINDOW_GLX_H diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index 424200f861..54b4edbb63 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_WINDOW_X11_H From cf29e752de36c84714ffe74567163626e1e59f19 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 07:10:04 +0000 Subject: [PATCH 0305/3781] Ship with COPYING.LIB. --- debian.upstream/Makefile.am | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index 5dc3152621..8bb59be6d2 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -1,8 +1,9 @@ DOCS = \ - AUTHORS \ - COPYING \ - NEWS \ - README \ + AUTHORS \ + COPYING \ + COPYING.LIB \ + NEWS \ + README \ $(NULL) DEBIANFILES = \ From ecff33db037c662e9621dbbe1691e48ab5391229 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 08:32:46 +0000 Subject: [PATCH 0306/3781] Try to fix timestamps (step 1). Looks OK on H55. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 13 +++++++++---- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 7 ++++++- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 3 ++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 2cca2e0e0c..675600ed02 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -195,7 +195,11 @@ destroy_surface(DecodedSurface *ds) } static gboolean -push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface) +push_surface( + GstVaapiDecoder *decoder, + GstVaapiSurface *surface, + GstClockTime timestamp +) { GstVaapiDecoderPrivate * const priv = decoder->priv; DecodedSurface *ds; @@ -209,7 +213,7 @@ push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface) ds->proxy = gst_vaapi_surface_proxy_new(priv->context, surface); if (ds->proxy) { ds->status = GST_VAAPI_DECODER_STATUS_SUCCESS; - gst_vaapi_surface_proxy_set_timestamp(ds->proxy, priv->surface_timestamp); + gst_vaapi_surface_proxy_set_timestamp(ds->proxy, timestamp); } else ds->status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -586,8 +590,9 @@ gst_vaapi_decoder_ensure_context( gboolean gst_vaapi_decoder_push_surface( GstVaapiDecoder *decoder, - GstVaapiSurface *surface + GstVaapiSurface *surface, + GstClockTime timestamp ) { - return push_surface(decoder, surface); + return push_surface(decoder, surface, timestamp); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 05ded90efe..cbb98457c0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -54,6 +54,7 @@ struct _GstVaapiContextFfmpeg { }; struct _GstVaapiDecoderFfmpegPrivate { + GstClockTime in_timestamp; /* timestamp from the demuxer */ AVFrame *frame; AVCodecParserContext *pctx; AVCodecContext *avctx; @@ -233,6 +234,7 @@ gst_vaapi_decoder_ffmpeg_get_format(AVCodecContext *avctx, const enum PixelForma static int gst_vaapi_decoder_ffmpeg_get_buffer(AVCodecContext *avctx, AVFrame *pic) { + GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; GstVaapiContext *context; GstVaapiSurface *surface; GstVaapiID surface_id; @@ -260,6 +262,7 @@ gst_vaapi_decoder_ffmpeg_get_buffer(AVCodecContext *avctx, AVFrame *pic) pic->linesize[1] = 0; pic->linesize[2] = 0; pic->linesize[3] = 0; + pic->pts = vactx->decoder->priv->in_timestamp; return 0; } @@ -446,7 +449,7 @@ decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) if (!surface) return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; - gst_vaapi_decoder_push_surface(GST_VAAPI_DECODER_CAST(ffdecoder), surface); + gst_vaapi_decoder_push_surface(GST_VAAPI_DECODER_CAST(ffdecoder), surface, priv->frame->pts); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -489,6 +492,7 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) inbuf_size -= parsed_size; } } while (!got_frame && inbuf_size > 0); + inbuf_ts = priv->pctx->pts; } else { outbuf = inbuf; @@ -499,6 +503,7 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) if (!got_frame && !GST_BUFFER_IS_EOS(buffer)) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + priv->in_timestamp = inbuf_ts; return decode_frame(ffdecoder, outbuf, outbuf_size); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 9b9a7bea35..fae29f64d9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -112,7 +112,8 @@ gst_vaapi_decoder_ensure_context( gboolean gst_vaapi_decoder_push_surface( GstVaapiDecoder *decoder, - GstVaapiSurface *surface + GstVaapiSurface *surface, + GstClockTime timestamp ) attribute_hidden; G_END_DECLS From 26790878a17dbb12473014bb298aa8380c9848f5 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 08:33:23 +0000 Subject: [PATCH 0307/3781] Cosmetics (spelling). --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index cbb98457c0..2e120321d2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -60,7 +60,7 @@ struct _GstVaapiDecoderFfmpegPrivate { AVCodecContext *avctx; GstVaapiContextFfmpeg *vactx; guint is_constructed : 1; - guint is_open : 1; + guint is_opened : 1; }; /** Converts codec to FFmpeg codec id */ @@ -466,9 +466,9 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) g_return_val_if_fail(priv->is_constructed, GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); - if (!priv->is_open) { - priv->is_open = gst_vaapi_decoder_ffmpeg_open(ffdecoder, buffer); - if (!priv->is_open) + if (!priv->is_opened) { + priv->is_opened = gst_vaapi_decoder_ffmpeg_open(ffdecoder, buffer); + if (!priv->is_opened) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; } @@ -574,7 +574,7 @@ gst_vaapi_decoder_ffmpeg_init(GstVaapiDecoderFfmpeg *decoder) priv->avctx = NULL; priv->vactx = NULL; priv->is_constructed = FALSE; - priv->is_open = FALSE; + priv->is_opened = FALSE; } /** From 021d2ab947ca4b22b58c5b893759b36c4ee16ba7 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 08:34:57 +0000 Subject: [PATCH 0308/3781] Drop obsolete (and wrong) code. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 27 ----------------------- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 -- 2 files changed, 29 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 675600ed02..1b9bd010b0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -53,30 +53,6 @@ enum { PROP_CODEC_DATA }; -static void -update_clock(GstVaapiDecoder *decoder, GstBuffer *buffer) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - GstClockTime timestamp, duration; - - timestamp = GST_BUFFER_TIMESTAMP(buffer); - duration = GST_BUFFER_DURATION(buffer); - - if (GST_CLOCK_TIME_IS_VALID(duration)) { - if (GST_CLOCK_TIME_IS_VALID(timestamp)) - priv->surface_timestamp = timestamp; - priv->surface_duration = duration; - } - else { - /* Assumes those are user-generated buffers with no timestamp - or duration information. Try to rely on "framerate". */ - if (!GST_CLOCK_TIME_IS_VALID(priv->surface_timestamp)) - priv->surface_timestamp = 0; - priv->surface_duration = - gst_util_uint64_scale_int(GST_SECOND, priv->fps_d, priv->fps_n); - } -} - static inline void init_buffer(GstBuffer *buffer, const guchar *buf, guint buf_size) { @@ -156,7 +132,6 @@ pop_buffer(GstVaapiDecoder *decoder) GST_DEBUG("dequeue buffer %p for decoding (%d bytes)", buffer, GST_BUFFER_SIZE(buffer)); - update_clock(decoder, buffer); return buffer; } @@ -391,8 +366,6 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->codec_data = NULL; priv->fps_n = 1000; priv->fps_d = 30; - priv->surface_timestamp = GST_CLOCK_TIME_NONE; - priv->surface_duration = GST_CLOCK_TIME_NONE; priv->buffers = g_queue_new(); priv->surfaces = g_queue_new(); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index fae29f64d9..1b4a6160ab 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -96,8 +96,6 @@ struct _GstVaapiDecoderPrivate { guint fps_d; GQueue *buffers; GQueue *surfaces; - GstClockTime surface_timestamp; - GstClockTime surface_duration; }; gboolean From 34764d2c2c8125a0d5c9f82691613f7d1d1dfd77 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 08:51:28 +0000 Subject: [PATCH 0309/3781] Fix build with older gstreamer libs where gst_buffer_unref() is not a plain function. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 1b9bd010b0..326cbf8773 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -101,6 +101,12 @@ create_buffer(const guchar *buf, guint buf_size, gboolean copy) return buffer; } +static void +destroy_buffer(GstBuffer *buffer) +{ + gst_buffer_unref(buffer); +} + static gboolean push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) { @@ -240,7 +246,7 @@ gst_vaapi_decoder_finalize(GObject *object) } if (priv->buffers) { - clear_queue(priv->buffers, (GDestroyNotify)gst_buffer_unref); + clear_queue(priv->buffers, (GDestroyNotify)destroy_buffer); g_queue_free(priv->buffers); priv->buffers = NULL; } From 587b39cdd5091bf40ca57fb5a39b409d6fad693b Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 11:44:23 +0000 Subject: [PATCH 0310/3781] Fix VC-1 detection. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- gst/vaapidecode/gstvaapidecode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 3edb14fee3..155e42726e 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -86,7 +86,7 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-vc1", "main" }, { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, - "video/x-vc1", "advanced" + "video/x-wmv, wmvversion=3, fourcc=(fourcc)WVC1", "advanced" }, { 0, } }; diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 7261185235..4449b341ea 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -57,7 +57,7 @@ static const char gst_vaapidecode_sink_caps_str[] = GST_CAPS_CODEC("video/mpeg, mpegversion=4") GST_CAPS_CODEC("video/x-h263") GST_CAPS_CODEC("video/x-h264") - GST_CAPS_CODEC("video/x-vc1") + GST_CAPS_CODEC("video/x-wmv") ; static const char gst_vaapidecode_src_caps_str[] = From 2da149abc9f7a6669cdf88116c27c804f0cfa98a Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 12:25:07 +0000 Subject: [PATCH 0311/3781] Add End-of-Sequence start code. --- tests/test-vc1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-vc1.c b/tests/test-vc1.c index 2838015265..80a56fcb67 100644 --- a/tests/test-vc1.c +++ b/tests/test-vc1.c @@ -22,7 +22,7 @@ #define VC1_CLIP_WIDTH 320 #define VC1_CLIP_HEIGHT 240 -#define VC1_CLIP_DATA_SIZE 20860 +#define VC1_CLIP_DATA_SIZE 20864 /* Data dump of a 320x240 VC-1 video clip (vc1.raw), it has a single frame */ static const guchar vc1_clip[VC1_CLIP_DATA_SIZE] = { @@ -1764,7 +1764,7 @@ static const guchar vc1_clip[VC1_CLIP_DATA_SIZE] = { 0x0e, 0x12, 0x0f, 0x34, 0xb6, 0x7b, 0xe0, 0xef, 0x3b, 0xbb, 0xb6, 0x92, 0xe8, 0xfc, 0xd4, 0x1d, 0x67, 0x18, 0x8a, 0x50, 0x9a, 0x48, 0x81, 0x4f, 0x2f, 0x54, 0x12, 0xbe, 0xdb, 0xd2, 0x67, 0xae, 0x1d, 0x2a, 0x5f, 0x8d, - 0x0f, 0x55, 0xbf, 0x40 + 0x0f, 0x55, 0xbf, 0x40, 0x00, 0x00, 0x01, 0x0a }; void vc1_get_video_data(const guchar **data, guint *size) From 64479eb8f28a3cd178a4ab14a2b173ba067fea04 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 13:44:41 +0000 Subject: [PATCH 0312/3781] Fix detection of plain old WMV3 contents. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 155e42726e..10d972fe2f 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -80,10 +80,10 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h264", "high" }, { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, - "video/x-vc1", "simple" + "video/x-wmv, wmvversion=3", "simple" }, { GST_VAAPI_PROFILE_VC1_MAIN, VAProfileVC1Main, - "video/x-vc1", "main" + "video/x-wmv, wmvversion=3", "main" }, { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, "video/x-wmv, wmvversion=3, fourcc=(fourcc)WVC1", "advanced" From fa7505c0c57979d75dd748fd15b962a6c326c751 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 14:53:18 +0000 Subject: [PATCH 0313/3781] Improve WMV3 detection yet further. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 5 +++++ gst-libs/gst/vaapi/gstvaapiprofile.c | 21 ++++++++++++++++----- gst-libs/gst/vaapi/gstvaapiprofile.h | 6 ++++-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 2e120321d2..03b5533c18 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -73,6 +73,7 @@ get_codec_id_from_codec(GstVaapiCodec codec) case GST_VAAPI_CODEC_MPEG4: return CODEC_ID_MPEG4; case GST_VAAPI_CODEC_H263: return CODEC_ID_H263; case GST_VAAPI_CODEC_H264: return CODEC_ID_H264; + case GST_VAAPI_CODEC_WMV3: return CODEC_ID_WMV3; case GST_VAAPI_CODEC_VC1: return CODEC_ID_VC1; } return CODEC_ID_NONE; @@ -340,6 +341,10 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe input encoded buffers represent the whole NAL unit */ parser_is_needed = priv->avctx->extradata_size == 0; break; + case CODEC_ID_WMV3: + /* There is no WMV3 parser in FFmpeg */ + parser_is_needed = FALSE; + break; default: parser_is_needed = TRUE; break; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 10d972fe2f..a76f261d26 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -30,9 +30,6 @@ #include "gstvaapicompat.h" #include "gstvaapiprofile.h" -#define GST_VAAPI_PROFILE_CODEC(profile) \ - ((GstVaapiCodec)(((guint32)profile) & GST_MAKE_FOURCC(0xff,0xff,0xff,0))) - typedef struct _GstVaapiProfileMap GstVaapiProfileMap; typedef struct _GstVaapiEntrypointMap GstVaapiEntrypointMap; @@ -244,7 +241,7 @@ gst_vaapi_profile_from_caps(GstCaps *caps) } if (!profile) profile = gst_vaapi_profile_from_codec_data( - GST_VAAPI_PROFILE_CODEC(m->profile), + gst_vaapi_profile_get_codec(m->profile), codec_data ); gst_caps_unref(caps_test); @@ -307,7 +304,21 @@ gst_vaapi_profile_get_caps(GstVaapiProfile profile) GstVaapiCodec gst_vaapi_profile_get_codec(GstVaapiProfile profile) { - return GST_VAAPI_PROFILE_CODEC(profile); + GstVaapiCodec codec; + + switch (profile) { + case GST_VAAPI_PROFILE_VC1_SIMPLE: + case GST_VAAPI_PROFILE_VC1_MAIN: + codec = GST_VAAPI_CODEC_WMV3; + break; + case GST_VAAPI_PROFILE_VC1_ADVANCED: + codec = GST_VAAPI_CODEC_VC1; + break; + default: + codec = (guint32)profile & GST_MAKE_FOURCC(0xff,0xff,0xff,0); + break; + } + return codec; } /** diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 718ccffef2..7ab27ab8e2 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -37,7 +37,8 @@ typedef enum _GstVaapiEntrypoint GstVaapiEntrypoint; * @GST_VAAPI_CODEC_MPEG4: MPEG-4 Part 2 (ISO/IEC 14496-2) * @GST_VAAPI_CODEC_H263: H.263 * @GST_VAAPI_CODEC_H264: H.264 aka MPEG-4 Part 10 (ISO/IEC 14496-10) - * @GST_VAAPI_CODEC_VC1: VC-1 (SMPTE 421M) + * @GST_VAAPI_CODEC_WMV3: Windows Media Video 9. VC-1 Simple or Main profile (SMPTE 421M) + * @GST_VAAPI_CODEC_VC1: VC-1 Advanced profile (SMPTE 421M) * * The set of all codecs for #GstVaapiCodec. */ @@ -47,6 +48,7 @@ enum _GstVaapiCodec { GST_VAAPI_CODEC_MPEG4 = GST_MAKE_FOURCC('M','P','4',0), GST_VAAPI_CODEC_H263 = GST_MAKE_FOURCC('2','6','3',0), GST_VAAPI_CODEC_H264 = GST_MAKE_FOURCC('2','6','4',0), + GST_VAAPI_CODEC_WMV3 = GST_MAKE_FOURCC('W','M','V',0), GST_VAAPI_CODEC_VC1 = GST_MAKE_FOURCC('V','C','1',0), }; @@ -86,7 +88,7 @@ enum _GstVaapiCodec { * @GST_VAAPI_PROFILE_VC1_SIMPLE: * VC-1 simple profile * @GST_VAAPI_PROFILE_VC1_MAIN: - * VC-1 main profile (WMV3) + * VC-1 main profile * @GST_VAAPI_PROFILE_VC1_ADVANCED: * VC-1 advanced profile * From 477e3b8530dba722de198564d2edba40e679408c Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 15:11:32 +0000 Subject: [PATCH 0314/3781] Add gst_vaapi_decoder_ffmpeg_new_from_caps() helper. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 36 ++++++++++++- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 56 +++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h | 3 ++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 + gst/vaapidecode/gstvaapidecode.c | 37 +++++--------- gst/vaapidecode/gstvaapidecode.h | 3 +- 6 files changed, 110 insertions(+), 27 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 326cbf8773..9f44130ce6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -50,7 +50,9 @@ enum { PROP_DISPLAY, PROP_CODEC, - PROP_CODEC_DATA + PROP_CODEC_DATA, + PROP_WIDTH, + PROP_HEIGHT, }; static inline void @@ -285,6 +287,12 @@ gst_vaapi_decoder_set_property( case PROP_CODEC_DATA: set_codec_data(GST_VAAPI_DECODER(object), gst_value_get_buffer(value)); break; + case PROP_WIDTH: + priv->width = g_value_get_uint(value); + break; + case PROP_HEIGHT: + priv->height = g_value_get_uint(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -311,6 +319,12 @@ gst_vaapi_decoder_get_property( case PROP_CODEC_DATA: gst_value_set_buffer(value, priv->codec_data); break; + case PROP_WIDTH: + g_value_set_uint(value, priv->width); + break; + case PROP_HEIGHT: + g_value_set_uint(value, priv->height); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -359,6 +373,24 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass) "Extra codec data", GST_TYPE_BUFFER, G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_uint("width", + "Width", + "The coded width of the picture", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_uint("height", + "Height", + "The coded height of the picture", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -370,6 +402,8 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->context = NULL; priv->codec = 0; priv->codec_data = NULL; + priv->width = 0; + priv->height = 0; priv->fps_n = 1000; priv->fps_d = 30; priv->buffers = g_queue_new(); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 03b5533c18..44e99dac9d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -608,3 +608,59 @@ gst_vaapi_decoder_ffmpeg_new( "codec-data", codec_data, NULL); } + +/** + * st_vaapi_decoder_ffmpeg_new_from_caps: + * @display: a #GstVaapiDisplay + * @caps: a #GstCaps holding codec information + * + * Creates a new #GstVaapiDecoder whose codec is determined from + * @caps. The @caps can hold extra information like codec-data and + * size. + * + * Return value: the newly allocated #GstVaapiDecoder object + */ +GstVaapiDecoder * +gst_vaapi_decoder_ffmpeg_new_from_caps(GstVaapiDisplay *display, GstCaps *caps) +{ + GstStructure *structure; + GstVaapiProfile profile; + GstVaapiCodec codec; + const GValue *v_codec_data; + GstBuffer *codec_data; + gint width, height; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + structure = gst_caps_get_structure(caps, 0); + if (!structure) + return NULL; + + profile = gst_vaapi_profile_from_caps(caps); + if (!profile) + return NULL; + + codec = gst_vaapi_profile_get_codec(profile); + if (!codec) + return NULL; + + if (!gst_structure_get_int(structure, "width", &width)) + width = 0; + if (!gst_structure_get_int(structure, "height", &height)) + height = 0; + + v_codec_data = gst_structure_get_value(structure, "codec_data"); + if (v_codec_data) + codec_data = gst_value_get_buffer(v_codec_data); + else + codec_data = NULL; + + return g_object_new(GST_VAAPI_TYPE_DECODER_FFMPEG, + "display", display, + "codec", codec, + "codec-data", codec_data, + "width", width, + "height", height, + NULL); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h index 015ba2fe84..acf5bf3836 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h @@ -86,6 +86,9 @@ gst_vaapi_decoder_ffmpeg_new( GstBuffer *codec_data ); +GstVaapiDecoder * +gst_vaapi_decoder_ffmpeg_new_from_caps(GstVaapiDisplay *display, GstCaps *caps); + G_END_DECLS #endif /* GST_VAAPI_DECODER_FFMPEG_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 1b4a6160ab..183c499b93 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -92,6 +92,8 @@ struct _GstVaapiDecoderPrivate { GstVaapiContext *context; GstVaapiCodec codec; GstBuffer *codec_data; + guint width; + guint height; guint fps_n; guint fps_d; GQueue *buffers; diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 4449b341ea..ab29f4278f 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -162,7 +162,6 @@ gst_vaapidecode_create(GstVaapiDecode *decode) { GstVaapiVideoSink *sink; GstVaapiDisplay *display; - GstVaapiCodec codec; /* Look for a downstream vaapisink */ sink = gst_vaapi_video_sink_lookup(GST_ELEMENT(decode)); @@ -175,30 +174,26 @@ gst_vaapidecode_create(GstVaapiDecode *decode) decode->display = g_object_ref(display); - codec = gst_vaapi_profile_get_codec(decode->profile); - if (!codec) - return FALSE; - if (decode->use_ffmpeg) decode->decoder = - gst_vaapi_decoder_ffmpeg_new(display, codec, decode->codec_data); + gst_vaapi_decoder_ffmpeg_new_from_caps(display, decode->decoder_caps); return decode->decoder != NULL; } static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { + if (decode->decoder_caps) { + gst_caps_unref(decode->decoder_caps); + decode->decoder_caps = NULL; + } + if (decode->decoder) { gst_vaapi_decoder_put_buffer(decode->decoder, NULL); g_object_unref(decode->decoder); decode->decoder = NULL; } - if (decode->codec_data) { - gst_buffer_unref(decode->codec_data); - decode->codec_data = NULL; - } - if (decode->display) { g_object_unref(decode->display); decode->display = NULL; @@ -331,7 +326,7 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) GstPad *other_pad; GstCaps *other_caps = NULL; GstStructure *structure; - const GValue *v_width, *v_height, *v_framerate, *v_par, *v_codec_data; + const GValue *v_width, *v_height, *v_framerate, *v_par; if (pad == decode->sinkpad) { other_pad = decode->srcpad; @@ -348,14 +343,9 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) v_height = gst_structure_get_value(structure, "height"); v_framerate = gst_structure_get_value(structure, "framerate"); v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); - v_codec_data = gst_structure_get_value(structure, "codec_data"); - if (pad == decode->sinkpad) { - decode->profile = gst_vaapi_profile_from_caps(caps); - if (v_codec_data) - decode->codec_data = - gst_buffer_ref(gst_value_get_buffer(v_codec_data)); - } + if (pad == decode->sinkpad) + decode->decoder_caps = gst_caps_ref(caps); structure = gst_caps_get_structure(other_caps, 0); gst_structure_set_value(structure, "width", v_width); @@ -426,11 +416,10 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - decode->display = NULL; - decode->profile = 0; - decode->codec_data = NULL; - decode->decoder = NULL; - decode->use_ffmpeg = TRUE; + decode->display = NULL; + decode->decoder = NULL; + decode->decoder_caps = NULL; + decode->use_ffmpeg = TRUE; /* Pad through which data comes in to the element */ decode->sinkpad = gst_pad_new_from_template( diff --git a/gst/vaapidecode/gstvaapidecode.h b/gst/vaapidecode/gstvaapidecode.h index b2b6915cd8..068f198ca7 100644 --- a/gst/vaapidecode/gstvaapidecode.h +++ b/gst/vaapidecode/gstvaapidecode.h @@ -62,9 +62,8 @@ struct _GstVaapiDecode { GstPad *sinkpad; GstPad *srcpad; GstVaapiDisplay *display; - GstVaapiProfile profile; - GstBuffer *codec_data; GstVaapiDecoder *decoder; + GstCaps *decoder_caps; unsigned int use_ffmpeg : 1; }; From 4285c2cc02825b5bf401837d418665bcef684343 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 15:29:18 +0000 Subject: [PATCH 0315/3781] Use size information from the demuxer, whenever available. i.e. fix WMV3 decoding. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 4 ++++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 22 +++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 44e99dac9d..c161d095df 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -366,6 +366,10 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe } } + /* Use size information from the demuxer, whenever available */ + priv->avctx->coded_width = GST_VAAPI_DECODER_WIDTH(ffdecoder); + priv->avctx->coded_height = GST_VAAPI_DECODER_HEIGHT(ffdecoder); + GST_VAAPI_DISPLAY_LOCK(display); ret = avcodec_open(priv->avctx, ffcodec); GST_VAAPI_DISPLAY_UNLOCK(display); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 183c499b93..2b30cf3447 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -76,6 +76,28 @@ G_BEGIN_DECLS #define GST_VAAPI_DECODER_CODEC_DATA(decoder) \ GST_VAAPI_DECODER_CAST(decoder)->priv->codec_data +/** + * 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_CAST(decoder)->priv->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_CAST(decoder)->priv->height + /* End-of-Stream buffer */ #define GST_BUFFER_FLAG_EOS (GST_BUFFER_FLAG_LAST + 0) From ffb74abe0f9bf5676c214b7003c05a5e7dd81a5b Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 15:34:22 +0000 Subject: [PATCH 0316/3781] Fix VC-1 detection with older gstreamer libs (no "fourcc" field, but a "format" one). --- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index a76f261d26..9fc294b2a1 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -83,7 +83,7 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-wmv, wmvversion=3", "main" }, { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, - "video/x-wmv, wmvversion=3, fourcc=(fourcc)WVC1", "advanced" + "video/x-wmv, wmvversion=3, format=(fourcc)WVC1", "advanced" }, { 0, } }; From dbe1d622ef8ad71edcb1e9e06d71ef37dcf99cf1 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 15:35:22 +0000 Subject: [PATCH 0317/3781] Fix VC-1 decoding, it does not require any specific parser. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index c161d095df..a99ef5c245 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -345,6 +345,11 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe /* There is no WMV3 parser in FFmpeg */ parser_is_needed = FALSE; break; + case CODEC_ID_VC1: + /* For VC-1, sequence headers ae in extradata and input encoded + buffers represent the whole slice */ + parser_is_needed = FALSE; + break; default: parser_is_needed = TRUE; break; From 24d918b7a371994455470b2bd90c04c6e1ee7d24 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 16:17:51 +0000 Subject: [PATCH 0318/3781] Try to improve heuristics to use an AVCodecContextParser. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 41 +++++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index a99ef5c245..5b32e2cae9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -315,7 +315,7 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe GstVaapiCodec codec = GST_VAAPI_DECODER_CODEC(ffdecoder); enum CodecID codec_id; AVCodec *ffcodec; - gboolean parser_is_needed; + gboolean try_parser, need_parser; int ret; gst_vaapi_decoder_ffmpeg_close(ffdecoder); @@ -339,36 +339,45 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe case CODEC_ID_H264: /* For AVC1 formats, sequence headers are in extradata and input encoded buffers represent the whole NAL unit */ - parser_is_needed = priv->avctx->extradata_size == 0; + try_parser = priv->avctx->extradata_size == 0; + need_parser = try_parser; break; case CODEC_ID_WMV3: /* There is no WMV3 parser in FFmpeg */ - parser_is_needed = FALSE; + try_parser = FALSE; + need_parser = FALSE; break; case CODEC_ID_VC1: /* For VC-1, sequence headers ae in extradata and input encoded buffers represent the whole slice */ - parser_is_needed = FALSE; + try_parser = priv->avctx->extradata_size == 0; + need_parser = FALSE; break; default: - parser_is_needed = TRUE; + try_parser = TRUE; + need_parser = TRUE; break; } - if (parser_is_needed) { + if (try_parser) { priv->pctx = av_parser_init(codec_id); - if (!priv->pctx) + if (!priv->pctx && need_parser) return FALSE; + } - /* XXX: av_find_stream_info() does this and some codecs really - want hard an extradata buffer for initialization (e.g. VC-1) */ - if (!priv->avctx->extradata && priv->pctx->parser->split) { - const guchar *buf = GST_BUFFER_DATA(buffer); - guint buf_size = GST_BUFFER_SIZE(buffer); - buf_size = priv->pctx->parser->split(priv->avctx, buf, buf_size); - if (buf_size > 0 && !set_codec_data(priv->avctx, buf, buf_size)) - return FALSE; - } + /* XXX: av_find_stream_info() does this and some codecs really + want hard an extradata buffer for initialization (e.g. VC-1) */ + if (!priv->avctx->extradata && priv->pctx && priv->pctx->parser->split) { + const guchar *buf = GST_BUFFER_DATA(buffer); + guint buf_size = GST_BUFFER_SIZE(buffer); + buf_size = priv->pctx->parser->split(priv->avctx, buf, buf_size); + if (buf_size > 0 && !set_codec_data(priv->avctx, buf, buf_size)) + return FALSE; + } + + if (priv->pctx && !need_parser) { + av_parser_close(priv->pctx); + priv->pctx = NULL; } /* Use size information from the demuxer, whenever available */ From 3ed565553517954893c7062e6e199b04fe7b6e38 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 16:41:13 +0000 Subject: [PATCH 0319/3781] Simplify tests info. --- tests/test-decode.c | 23 ++++++++++++----------- tests/test-decode.h | 35 +++++++++++++++++++++++++++++++++++ tests/test-h264.c | 9 ++++++--- tests/test-h264.h | 3 ++- tests/test-mpeg2.c | 9 ++++++--- tests/test-mpeg2.h | 3 ++- tests/test-vc1.c | 11 +++++++---- tests/test-vc1.h | 3 ++- 8 files changed, 72 insertions(+), 24 deletions(-) create mode 100644 tests/test-decode.h diff --git a/tests/test-decode.c b/tests/test-decode.c index f4b56b9206..0fea7501a0 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -28,19 +28,20 @@ #include "test-h264.h" #include "test-vc1.h" -typedef void (*GetVideoDataFunc)(const guchar **data, guint *size); +typedef void (*GetVideoInfoFunc)(VideoDecodeInfo *info); typedef struct _CodecDefs CodecDefs; struct _CodecDefs { const gchar *codec_str; - GstVaapiCodec codec; - GetVideoDataFunc get_video_data; + GetVideoInfoFunc get_video_info; }; static const CodecDefs g_codec_defs[] = { - { "mpeg2", GST_VAAPI_CODEC_MPEG2, mpeg2_get_video_data }, - { "h264", GST_VAAPI_CODEC_H264, h264_get_video_data }, - { "vc1", GST_VAAPI_CODEC_VC1, vc1_get_video_data }, +#define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info } + INIT_FUNCS(mpeg2), + INIT_FUNCS(h264), + INIT_FUNCS(vc1), +#undef INIT_FUNCS { NULL, } }; @@ -77,11 +78,11 @@ main(int argc, char *argv[]) GstVaapiDisplay *display; GstVaapiWindow *window; GstVaapiDecoder *decoder; + GstCaps *decoder_caps; GstVaapiDecoderStatus status; const CodecDefs *codec; GstVaapiSurfaceProxy *proxy; - const guchar *vdata; - guint vdata_size; + VideoDecodeInfo info; static const guint win_width = 640; static const guint win_height = 480; @@ -109,12 +110,12 @@ main(int argc, char *argv[]) if (!window) g_error("could not create window"); - codec->get_video_data(&vdata, &vdata_size); - decoder = gst_vaapi_decoder_ffmpeg_new(display, codec->codec, NULL); + codec->get_video_info(&info); + decoder = gst_vaapi_decoder_ffmpeg_new(display, gst_vaapi_profile_get_codec(info.profile), NULL); if (!decoder) g_error("could not create FFmpeg decoder"); - if (!gst_vaapi_decoder_put_buffer_data(decoder, vdata, vdata_size)) + if (!gst_vaapi_decoder_put_buffer_data(decoder, info.data, info.data_size)) g_error("could not send video data to the decoder"); if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) g_error("could not send EOS to the decoder"); diff --git a/tests/test-decode.h b/tests/test-decode.h new file mode 100644 index 0000000000..0ef55cca54 --- /dev/null +++ b/tests/test-decode.h @@ -0,0 +1,35 @@ +/* + * test-decode.h - Test GstVaapiDecoder + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef TEST_DECODE_H +#define TEST_DECODE_H + +#include + +typedef struct _VideoDecodeInfo VideoDecodeInfo; +struct _VideoDecodeInfo { + GstVaapiProfile profile; + guint width; + guint height; + const guchar *data; + guint data_size; +}; + +#endif /* TEST_DECODE_H */ diff --git a/tests/test-h264.c b/tests/test-h264.c index e4c0f37ee6..c00c275fb5 100644 --- a/tests/test-h264.c +++ b/tests/test-h264.c @@ -1038,8 +1038,11 @@ static const guchar h264_clip[H264_CLIP_DATA_SIZE] = { 0x00, 0x01, 0x0a }; -void h264_get_video_data(const guchar **data, guint *size) +void h264_get_video_info(VideoDecodeInfo *info) { - *data = h264_clip; - *size = H264_CLIP_DATA_SIZE; + info->profile = GST_VAAPI_PROFILE_H264_MAIN; + info->width = H264_CLIP_WIDTH; + info->height = H264_CLIP_HEIGHT; + info->data = h264_clip; + info->data_size = H264_CLIP_DATA_SIZE; } diff --git a/tests/test-h264.h b/tests/test-h264.h index ee022985e1..ae94bcd0b8 100644 --- a/tests/test-h264.h +++ b/tests/test-h264.h @@ -22,7 +22,8 @@ #define TEST_H264_H #include +#include "test-decode.h" -void h264_get_video_data(const guchar **data, guint *size); +void h264_get_video_info(VideoDecodeInfo *info); #endif /* TEST_H264_H */ diff --git a/tests/test-mpeg2.c b/tests/test-mpeg2.c index 2817b30086..e12b25964a 100644 --- a/tests/test-mpeg2.c +++ b/tests/test-mpeg2.c @@ -1638,8 +1638,11 @@ static const guchar mpeg2_clip[MPEG2_CLIP_DATA_SIZE] = { 0x00, 0x01, 0xb7 }; -void mpeg2_get_video_data(const guchar **data, guint *size) +void mpeg2_get_video_info(VideoDecodeInfo *info) { - *data = mpeg2_clip; - *size = MPEG2_CLIP_DATA_SIZE; + info->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; + info->width = MPEG2_CLIP_WIDTH; + info->height = MPEG2_CLIP_HEIGHT; + info->data = mpeg2_clip; + info->data_size = MPEG2_CLIP_DATA_SIZE; } diff --git a/tests/test-mpeg2.h b/tests/test-mpeg2.h index 8b3e43e6de..0825155054 100644 --- a/tests/test-mpeg2.h +++ b/tests/test-mpeg2.h @@ -22,7 +22,8 @@ #define TEST_MPEG2_H #include +#include "test-decode.h" -void mpeg2_get_video_data(const guchar **data, guint *size); +void mpeg2_get_video_info(VideoDecodeInfo *info); #endif /* TEST_MPEG2_H */ diff --git a/tests/test-vc1.c b/tests/test-vc1.c index 80a56fcb67..79e2ccaa8b 100644 --- a/tests/test-vc1.c +++ b/tests/test-vc1.c @@ -20,7 +20,7 @@ #include "test-vc1.h" -#define VC1_CLIP_WIDTH 320 +#define VC1_CLIP_WIDTH 293 #define VC1_CLIP_HEIGHT 240 #define VC1_CLIP_DATA_SIZE 20864 @@ -1767,8 +1767,11 @@ static const guchar vc1_clip[VC1_CLIP_DATA_SIZE] = { 0x0f, 0x55, 0xbf, 0x40, 0x00, 0x00, 0x01, 0x0a }; -void vc1_get_video_data(const guchar **data, guint *size) +void vc1_get_video_info(VideoDecodeInfo *info) { - *data = vc1_clip; - *size = VC1_CLIP_DATA_SIZE; + info->profile = GST_VAAPI_PROFILE_VC1_ADVANCED; + info->width = VC1_CLIP_WIDTH; + info->height = VC1_CLIP_HEIGHT; + info->data = vc1_clip; + info->data_size = VC1_CLIP_DATA_SIZE; } diff --git a/tests/test-vc1.h b/tests/test-vc1.h index ac35d2b327..05927b601d 100644 --- a/tests/test-vc1.h +++ b/tests/test-vc1.h @@ -22,7 +22,8 @@ #define TEST_VC1_H #include +#include "test-decode.h" -void vc1_get_video_data(const guchar **data, guint *size); +void vc1_get_video_info(VideoDecodeInfo *info); #endif /* TEST_VC1_H */ From 585a273532261a1349a04be5f569e1e8f215d49c Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 16:54:23 +0000 Subject: [PATCH 0320/3781] Use gst_vaapi_decoder_ffmpeg_new_from_caps(). --- tests/test-decode.c | 17 ++++++++++++++++- tests/test-decode.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/test-decode.c b/tests/test-decode.c index 0fea7501a0..c5f7f91835 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -79,6 +79,7 @@ main(int argc, char *argv[]) GstVaapiWindow *window; GstVaapiDecoder *decoder; GstCaps *decoder_caps; + GstStructure *structure; GstVaapiDecoderStatus status; const CodecDefs *codec; GstVaapiSurfaceProxy *proxy; @@ -111,7 +112,20 @@ main(int argc, char *argv[]) g_error("could not create window"); codec->get_video_info(&info); - decoder = gst_vaapi_decoder_ffmpeg_new(display, gst_vaapi_profile_get_codec(info.profile), NULL); + decoder_caps = gst_vaapi_profile_get_caps(info.profile); + if (!decoder_caps) + g_error("could not create decoder caps"); + + structure = gst_caps_get_structure(decoder_caps, 0); + if (info.width > 0 && info.height > 0) + gst_structure_set( + structure, + "width", G_TYPE_INT, info.width, + "height", G_TYPE_INT, info.height, + NULL + ); + + decoder = gst_vaapi_decoder_ffmpeg_new_from_caps(display, decoder_caps); if (!decoder) g_error("could not create FFmpeg decoder"); @@ -136,6 +150,7 @@ main(int argc, char *argv[]) pause(); g_object_unref(proxy); + gst_caps_unref(decoder_caps); g_object_unref(decoder); g_object_unref(window); g_object_unref(display); diff --git a/tests/test-decode.h b/tests/test-decode.h index 0ef55cca54..6d9aa2b021 100644 --- a/tests/test-decode.h +++ b/tests/test-decode.h @@ -21,6 +21,7 @@ #ifndef TEST_DECODE_H #define TEST_DECODE_H +#include #include typedef struct _VideoDecodeInfo VideoDecodeInfo; From 1a341a1c02866fd0e7bcb9c8258b1cad36b97e93 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 17:04:00 +0000 Subject: [PATCH 0321/3781] Use avctx->coded_{width,height} info to create the VA context. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 5b32e2cae9..669022b655 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -164,15 +164,15 @@ get_context(AVCodecContext *avctx) GstVaapiContext *context; gboolean success; - if (!avctx->width || !avctx->height) + if (!avctx->coded_width || !avctx->coded_height) return NULL; success = gst_vaapi_decoder_ensure_context( decoder, vactx->profile, vactx->entrypoint, - avctx->width, - avctx->height + avctx->coded_width, + avctx->coded_height ); if (!success) { GST_DEBUG("failed to reset VA context:"); From e39709453eaf208b40eae2064aa92923e8570ec0 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 17:36:01 +0000 Subject: [PATCH 0322/3781] Add more aliases for MPEG-4 decoding. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 6 ++++++ gst/vaapidecode/gstvaapidecode.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 9fc294b2a1..f41e96ea85 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -62,6 +62,12 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_MPEG4_MAIN, VAProfileMPEG4Main, "video/mpeg, mpegversion=4", "main" }, + { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, + "video/x-divx, divxversion=5", "advanced-simple" + }, + { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, + "video/x-xvid", "advanced-simple" + }, #if VA_CHECK_VERSION(0,30,0) { GST_VAAPI_PROFILE_H263_BASELINE, VAProfileH263Baseline, "video/x-h263, variant=itu, h263version=h263", "baseline" diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index ab29f4278f..82131b36d2 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -55,6 +55,8 @@ static const GstElementDetails gst_vaapidecode_details = static const char gst_vaapidecode_sink_caps_str[] = GST_CAPS_CODEC("video/mpeg, mpegversion=2") GST_CAPS_CODEC("video/mpeg, mpegversion=4") + GST_CAPS_CODEC("video/x-divx") + GST_CAPS_CODEC("video/x-xvid") GST_CAPS_CODEC("video/x-h263") GST_CAPS_CODEC("video/x-h264") GST_CAPS_CODEC("video/x-wmv") From bcf57bb4f9bf11efd06e79c53ac6a6f0b63d904a Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 20:34:57 +0000 Subject: [PATCH 0323/3781] Drop obsolete decls. --- gst-libs/gst/vaapi/gstvaapidecoder.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 3b65fbd586..a059657fc6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -125,15 +125,6 @@ gst_vaapi_decoder_set_frame_rate( guint den ); -gboolean -gst_vaapi_decoder_start(GstVaapiDecoder *decoder); - -gboolean -gst_vaapi_decoder_pause(GstVaapiDecoder *decoder); - -gboolean -gst_vaapi_decoder_stop(GstVaapiDecoder *decoder); - gboolean gst_vaapi_decoder_put_buffer_data( GstVaapiDecoder *decoder, From 5128ed99513e7d6fe132438254e3f7f738656427 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 20:40:27 +0000 Subject: [PATCH 0324/3781] Drop obsolete defs. --- gst-libs/gst/vaapi/gstvaapidecoder.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index a059657fc6..8af5e019a5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -60,7 +60,6 @@ typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; /** * GstVaapiDecoderStatus: * @GST_VAAPI_DECODER_STATUS_SUCCESS: Success. - * @GST_VAAPI_DECODER_STATUS_TIMEOUT: Timeout. Try again later. * @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. @@ -73,7 +72,6 @@ typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; */ enum _GstVaapiDecoderStatus { GST_VAAPI_DECODER_STATUS_SUCCESS = 0, - GST_VAAPI_DECODER_STATUS_TIMEOUT, GST_VAAPI_DECODER_STATUS_END_OF_STREAM, GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED, GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED, From 73766f9466d2d1945ce3ed7d442ba9df5e852a0c Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 20:55:17 +0000 Subject: [PATCH 0325/3781] Simplify GstVaapiDecoder API. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 129 +-------------------------- gst-libs/gst/vaapi/gstvaapidecoder.h | 28 ------ tests/test-decode.c | 12 ++- 3 files changed, 11 insertions(+), 158 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 9f44130ce6..3170fdef1b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -38,7 +38,7 @@ G_DEFINE_TYPE(GstVaapiDecoder, gst_vaapi_decoder, G_TYPE_OBJECT); -/* XXX: Make it a GstVaapiDecodedSurface + propagate PTS */ +/* XXX: Make it a GstVaapiDecodedSurface? */ typedef struct _DecodedSurface DecodedSurface; struct _DecodedSurface { GstVaapiSurfaceProxy *proxy; @@ -78,31 +78,6 @@ create_eos_buffer(void) return buffer; } -static GstBuffer * -create_buffer(const guchar *buf, guint buf_size, gboolean copy) -{ - GstBuffer *buffer; - - if (!buf || !buf_size) - return NULL; - - buffer = gst_buffer_new(); - if (!buffer) - return NULL; - - if (copy) { - buffer->malloc_data = g_malloc(buf_size); - if (!buffer->malloc_data) { - gst_buffer_unref(buffer); - return NULL; - } - memcpy(buffer->malloc_data, buf, buf_size); - buf = buffer->malloc_data; - } - init_buffer(buffer, buf, buf_size); - return buffer; -} - static void destroy_buffer(GstBuffer *buffer) { @@ -410,108 +385,6 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->surfaces = g_queue_new(); } -/** - * gst_vaapi_decoder_get_frame_rate: - * @decoder: a #GstVaapiDecoder - * @num: return location for the numerator of the frame rate - * @den: return location for the denominator of the frame rate - * - * Retrieves the current frame rate as the fraction @num / @den. The - * default frame rate is 30 fps. - */ -void -gst_vaapi_decoder_get_frame_rate( - GstVaapiDecoder *decoder, - guint *num, - guint *den -) -{ - g_return_if_fail(GST_VAAPI_IS_DECODER(decoder)); - - if (num) - *num = decoder->priv->fps_n; - - if (den) - *den = decoder->priv->fps_d; -} - -/** - * gst_vaapi_decoder_set_frame_rate: - * @decoder: a #GstVaapiDecoder - * @num: the numerator of the frame rate - * @den: the denominator of the frame rate - * - * Sets the frame rate for the stream to @num / @den. By default, the - * decoder will use the frame rate encoded in the elementary stream. - * If none is available, the decoder will default to 30 fps. - */ -void -gst_vaapi_decoder_set_frame_rate( - GstVaapiDecoder *decoder, - guint num, - guint den -) -{ - g_return_if_fail(GST_VAAPI_IS_DECODER(decoder)); - - decoder->priv->fps_n = num; - decoder->priv->fps_d = den; -} - -/** - * gst_vaapi_decoder_put_buffer_data: - * @decoder: a #GstVaapiDecoder - * @buf: pointer to buffer data - * @buf_size: size of buffer data in bytes - * - * Queues @buf_size bytes from the data @buf to the HW decoder. The - * caller is responsible for making sure @buf is live beyond this - * function. So, this function is mostly useful with static data - * buffers. gst_vaapi_decoder_put_buffer_data_copy() does the same but - * copies the data. - * - * Caller can notify an End-Of-Stream with @buf set to %NULL and - * @buf_size set to zero. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_decoder_put_buffer_data( - GstVaapiDecoder *decoder, - const guchar *buf, - guint buf_size -) -{ - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); - - return push_buffer(decoder, create_buffer(buf, buf_size, FALSE)); -} - -/** - * gst_vaapi_decoder_put_buffer_data_copy: - * @decoder: a #GstVaapiDecoder - * @buf: pointer to buffer data - * @buf_size: size of buffer data in bytes - * - * Queues a copy of @buf to the HW decoder. - * - * Caller can notify an End-Of-Stream with @buf set to %NULL and - * @buf_size set to zero. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_decoder_put_buffer_data_copy( - GstVaapiDecoder *decoder, - const guchar *buf, - guint buf_size -) -{ - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); - - return push_buffer(decoder, create_buffer(buf, buf_size, TRUE)); -} - /** * gst_vaapi_decoder_put_buffer: * @decoder: a #GstVaapiDecoder diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 8af5e019a5..e7bc5ca66f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -109,34 +109,6 @@ struct _GstVaapiDecoderClass { GType gst_vaapi_decoder_get_type(void); -void -gst_vaapi_decoder_get_frame_rate( - GstVaapiDecoder *decoder, - guint *num, - guint *den -); - -void -gst_vaapi_decoder_set_frame_rate( - GstVaapiDecoder *decoder, - guint num, - guint den -); - -gboolean -gst_vaapi_decoder_put_buffer_data( - GstVaapiDecoder *decoder, - const guchar *buf, - guint buf_size -); - -gboolean -gst_vaapi_decoder_put_buffer_data_copy( - GstVaapiDecoder *decoder, - const guchar *buf, - guint buf_size -); - gboolean gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf); diff --git a/tests/test-decode.c b/tests/test-decode.c index c5f7f91835..e17c229d40 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -82,6 +82,7 @@ main(int argc, char *argv[]) GstStructure *structure; GstVaapiDecoderStatus status; const CodecDefs *codec; + GstBuffer *buffer; GstVaapiSurfaceProxy *proxy; VideoDecodeInfo info; @@ -128,9 +129,17 @@ main(int argc, char *argv[]) decoder = gst_vaapi_decoder_ffmpeg_new_from_caps(display, decoder_caps); if (!decoder) g_error("could not create FFmpeg decoder"); + gst_caps_unref(decoder_caps); - if (!gst_vaapi_decoder_put_buffer_data(decoder, info.data, info.data_size)) + buffer = gst_buffer_new(); + if (!buffer) + g_error("could not create encoded data buffer"); + gst_buffer_set_data(buffer, (guchar *)info.data, info.data_size); + + if (!gst_vaapi_decoder_put_buffer(decoder, buffer)) g_error("could not send video data to the decoder"); + gst_buffer_unref(buffer); + if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) g_error("could not send EOS to the decoder"); @@ -150,7 +159,6 @@ main(int argc, char *argv[]) pause(); g_object_unref(proxy); - gst_caps_unref(decoder_caps); g_object_unref(decoder); g_object_unref(window); g_object_unref(display); From 09552b15593e90a001273714dcc9761789e147d3 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 21:14:01 +0000 Subject: [PATCH 0326/3781] More simplifications. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 64 ++++++--------------- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 4 +- 2 files changed, 22 insertions(+), 46 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 3170fdef1b..cba83b25ab 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -38,13 +38,6 @@ G_DEFINE_TYPE(GstVaapiDecoder, gst_vaapi_decoder, G_TYPE_OBJECT); -/* XXX: Make it a GstVaapiDecodedSurface? */ -typedef struct _DecodedSurface DecodedSurface; -struct _DecodedSurface { - GstVaapiSurfaceProxy *proxy; - GstVaapiDecoderStatus status; -}; - enum { PROP_0, @@ -140,18 +133,6 @@ decode_step(GstVaapiDecoder *decoder) return status; } -static inline DecodedSurface * -create_surface(void) -{ - return g_slice_new0(DecodedSurface); -} - -static inline void -destroy_surface(DecodedSurface *ds) -{ - g_slice_free(DecodedSurface, ds); -} - static gboolean push_surface( GstVaapiDecoder *decoder, @@ -160,27 +141,21 @@ push_surface( ) { GstVaapiDecoderPrivate * const priv = decoder->priv; - DecodedSurface *ds; - - ds = create_surface(); - if (!ds) - return FALSE; + GstVaapiSurfaceProxy *proxy; GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); - ds->proxy = gst_vaapi_surface_proxy_new(priv->context, surface); - if (ds->proxy) { - ds->status = GST_VAAPI_DECODER_STATUS_SUCCESS; - gst_vaapi_surface_proxy_set_timestamp(ds->proxy, timestamp); - } - else - ds->status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - g_queue_push_tail(priv->surfaces, ds); + proxy = gst_vaapi_surface_proxy_new(priv->context, surface); + if (!proxy) + return FALSE; + + gst_vaapi_surface_proxy_set_timestamp(proxy, timestamp); + g_queue_push_tail(priv->surfaces, proxy); return TRUE; } -static inline DecodedSurface * +static inline GstVaapiSurfaceProxy * pop_surface(GstVaapiDecoder *decoder) { GstVaapiDecoderPrivate * const priv = decoder->priv; @@ -229,7 +204,7 @@ gst_vaapi_decoder_finalize(GObject *object) } if (priv->surfaces) { - clear_queue(priv->surfaces, (GDestroyNotify)destroy_surface); + clear_queue(priv->surfaces, (GDestroyNotify)g_object_unref); g_queue_free(priv->surfaces); priv->surfaces = NULL; } @@ -423,25 +398,24 @@ gst_vaapi_decoder_get_surface( GstVaapiDecoderStatus *pstatus ) { - GstVaapiSurfaceProxy *proxy = NULL; - GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - DecodedSurface *ds; + GstVaapiSurfaceProxy *proxy; + GstVaapiDecoderStatus status; + + if (pstatus) + *pstatus = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - ds = pop_surface(decoder); - if (!ds) { + proxy = pop_surface(decoder); + if (!proxy) { do { status = decode_step(decoder); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); - ds = pop_surface(decoder); + proxy = pop_surface(decoder); } - if (ds) { - proxy = ds->proxy; - status = ds->status; - destroy_surface(ds); - } + if (proxy) + status = GST_VAAPI_DECODER_STATUS_SUCCESS; if (pstatus) *pstatus = status; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 669022b655..7ca9001a45 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -472,7 +472,9 @@ decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) if (!surface) return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; - gst_vaapi_decoder_push_surface(GST_VAAPI_DECODER_CAST(ffdecoder), surface, priv->frame->pts); + if (!gst_vaapi_decoder_push_surface(GST_VAAPI_DECODER_CAST(ffdecoder), + surface, priv->frame->pts)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; return GST_VAAPI_DECODER_STATUS_SUCCESS; } From fe35801572e17ad2e79a1407b73dededf5307a96 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 21:25:26 +0000 Subject: [PATCH 0327/3781] Fix doc. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 7ca9001a45..b756a84973 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -634,9 +634,9 @@ gst_vaapi_decoder_ffmpeg_new( * @display: a #GstVaapiDisplay * @caps: a #GstCaps holding codec information * - * Creates a new #GstVaapiDecoder whose codec is determined from - * @caps. The @caps can hold extra information like codec-data and - * size. + * Creates a new #GstVaapiDecoder based on FFmpeg where the codec is + * determined from @caps. The @caps can hold extra information like + * codec-data and pictured coded size. * * Return value: the newly allocated #GstVaapiDecoder object */ From 5851086b9212f040aaa01a9e6d5e481658b3c5b7 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 21:25:46 +0000 Subject: [PATCH 0328/3781] Simplify. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index cba83b25ab..07c3b9b186 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -48,29 +48,6 @@ enum { PROP_HEIGHT, }; -static inline void -init_buffer(GstBuffer *buffer, const guchar *buf, guint buf_size) -{ - GST_BUFFER_DATA(buffer) = (guint8 *)buf; - GST_BUFFER_SIZE(buffer) = buf_size; - GST_BUFFER_TIMESTAMP(buffer) = GST_CLOCK_TIME_NONE; - GST_BUFFER_DURATION(buffer) = GST_CLOCK_TIME_NONE; -} - -static inline GstBuffer * -create_eos_buffer(void) -{ - GstBuffer *buffer; - - buffer = gst_buffer_new(); - if (!buffer) - return NULL; - - init_buffer(buffer, NULL, 0); - GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_EOS); - return buffer; -} - static void destroy_buffer(GstBuffer *buffer) { @@ -83,9 +60,10 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) GstVaapiDecoderPrivate * const priv = decoder->priv; if (!buffer) { - buffer = create_eos_buffer(); + buffer = gst_buffer_new(); if (!buffer) return FALSE; + GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_EOS); } GST_DEBUG("queue encoded data buffer %p (%d bytes)", From 2d5434cb0b3aba2cb55e642c83d20aabe7fd8f15 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 21:49:35 +0000 Subject: [PATCH 0329/3781] Move caps initialization to parent class. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 115 +++++++++----------- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 49 +++------ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 1 + 3 files changed, 68 insertions(+), 97 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 07c3b9b186..12d79dc1a5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -42,10 +42,7 @@ enum { PROP_0, PROP_DISPLAY, - PROP_CODEC, - PROP_CODEC_DATA, - PROP_WIDTH, - PROP_HEIGHT, + PROP_CAPS, }; static void @@ -155,6 +152,46 @@ set_codec_data(GstVaapiDecoder *decoder, GstBuffer *codec_data) priv->codec_data = gst_buffer_ref(codec_data); } +static void +set_caps(GstVaapiDecoder *decoder, GstCaps *caps) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstStructure *structure; + GstVaapiProfile profile; + const GValue *v_codec_data; + gint width, height; + + if (priv->caps) { + gst_caps_unref(priv->caps); + priv->caps = NULL; + } + + if (caps) { + structure = gst_caps_get_structure(caps, 0); + if (!structure) + return; + + profile = gst_vaapi_profile_from_caps(caps); + if (!profile) + return; + + priv->codec = gst_vaapi_profile_get_codec(profile); + if (!priv->codec) + return; + + if (!gst_structure_get_int(structure, "width", &width)) + width = 0; + if (!gst_structure_get_int(structure, "height", &height)) + height = 0; + priv->width = width; + priv->height = height; + + v_codec_data = gst_structure_get_value(structure, "codec_data"); + if (v_codec_data) + set_codec_data(decoder, gst_value_get_buffer(v_codec_data)); + } +} + static void clear_queue(GQueue *q, GDestroyNotify destroy) { @@ -168,13 +205,14 @@ gst_vaapi_decoder_finalize(GObject *object) GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object); GstVaapiDecoderPrivate * const priv = decoder->priv; + set_caps(decoder, NULL); set_codec_data(decoder, NULL); if (priv->context) { g_object_unref(priv->context); priv->context = NULL; } - + if (priv->buffers) { clear_queue(priv->buffers, (GDestroyNotify)destroy_buffer); g_queue_free(priv->buffers); @@ -203,23 +241,15 @@ gst_vaapi_decoder_set_property( GParamSpec *pspec ) { - GstVaapiDecoderPrivate * const priv = GST_VAAPI_DECODER(object)->priv; + GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object); + GstVaapiDecoderPrivate * const priv = decoder->priv; switch (prop_id) { case PROP_DISPLAY: priv->display = g_object_ref(g_value_get_object(value)); break; - case PROP_CODEC: - priv->codec = g_value_get_uint(value); - break; - case PROP_CODEC_DATA: - set_codec_data(GST_VAAPI_DECODER(object), gst_value_get_buffer(value)); - break; - case PROP_WIDTH: - priv->width = g_value_get_uint(value); - break; - case PROP_HEIGHT: - priv->height = g_value_get_uint(value); + case PROP_CAPS: + set_caps(decoder, g_value_get_pointer(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -241,18 +271,6 @@ gst_vaapi_decoder_get_property( case PROP_DISPLAY: g_value_set_object(value, priv->display); break; - case PROP_CODEC: - g_value_set_uint(value, priv->codec); - break; - case PROP_CODEC_DATA: - gst_value_set_buffer(value, priv->codec_data); - break; - case PROP_WIDTH: - g_value_set_uint(value, priv->width); - break; - case PROP_HEIGHT: - g_value_set_uint(value, priv->height); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -286,39 +304,11 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass) g_object_class_install_property (object_class, - PROP_CODEC, - g_param_spec_uint("codec", - "Codec", - "The codec handled by the decoder", - 0, G_MAXINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_CODEC_DATA, - gst_param_spec_mini_object("codec-data", - "Codec data", - "Extra codec data", - GST_TYPE_BUFFER, - G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_WIDTH, - g_param_spec_uint("width", - "Width", - "The coded width of the picture", - 0, G_MAXINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_HEIGHT, - g_param_spec_uint("height", - "Height", - "The coded height of the picture", - 0, G_MAXINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + PROP_CAPS, + g_param_spec_pointer("caps", + "Decoder caps", + "The decoder caps", + G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -328,6 +318,7 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) decoder->priv = priv; priv->context = NULL; + priv->caps = NULL; priv->codec = 0; priv->codec_data = NULL; priv->width = 0; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index b756a84973..17e4029c1c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -413,6 +413,9 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) { GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; + if (!GST_VAAPI_DECODER_CODEC(ffdecoder)) + return FALSE; + if (!priv->frame) { priv->frame = avcodec_alloc_frame(); if (!priv->frame) @@ -643,44 +646,20 @@ gst_vaapi_decoder_ffmpeg_new( GstVaapiDecoder * gst_vaapi_decoder_ffmpeg_new_from_caps(GstVaapiDisplay *display, GstCaps *caps) { - GstStructure *structure; - GstVaapiProfile profile; - GstVaapiCodec codec; - const GValue *v_codec_data; - GstBuffer *codec_data; - gint width, height; + GstVaapiDecoderFfmpeg *ffdecoder; g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); g_return_val_if_fail(GST_IS_CAPS(caps), NULL); - structure = gst_caps_get_structure(caps, 0); - if (!structure) + ffdecoder = g_object_new( + GST_VAAPI_TYPE_DECODER_FFMPEG, + "display", display, + "caps", caps, + NULL + ); + if (!ffdecoder->priv->is_constructed) { + g_object_unref(ffdecoder); return NULL; - - profile = gst_vaapi_profile_from_caps(caps); - if (!profile) - return NULL; - - codec = gst_vaapi_profile_get_codec(profile); - if (!codec) - return NULL; - - if (!gst_structure_get_int(structure, "width", &width)) - width = 0; - if (!gst_structure_get_int(structure, "height", &height)) - height = 0; - - v_codec_data = gst_structure_get_value(structure, "codec_data"); - if (v_codec_data) - codec_data = gst_value_get_buffer(v_codec_data); - else - codec_data = NULL; - - return g_object_new(GST_VAAPI_TYPE_DECODER_FFMPEG, - "display", display, - "codec", codec, - "codec-data", codec_data, - "width", width, - "height", height, - NULL); + } + return GST_VAAPI_DECODER_CAST(ffdecoder); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 2b30cf3447..c824188be9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -112,6 +112,7 @@ G_BEGIN_DECLS struct _GstVaapiDecoderPrivate { GstVaapiDisplay *display; GstVaapiContext *context; + GstCaps *caps; GstVaapiCodec codec; GstBuffer *codec_data; guint width; From edae9f068c54a6e65ee911e31bb2d93cb4fe58e4 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 22:02:41 +0000 Subject: [PATCH 0330/3781] Extract framerate information from caps. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 52 +++++++++-------------- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 1 - 2 files changed, 21 insertions(+), 32 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 12d79dc1a5..16feb4d3c8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -156,40 +156,32 @@ static void set_caps(GstVaapiDecoder *decoder, GstCaps *caps) { GstVaapiDecoderPrivate * const priv = decoder->priv; - GstStructure *structure; + GstStructure * const structure = gst_caps_get_structure(caps, 0); GstVaapiProfile profile; const GValue *v_codec_data; - gint width, height; + gint v1, v2; - if (priv->caps) { - gst_caps_unref(priv->caps); - priv->caps = NULL; + profile = gst_vaapi_profile_from_caps(caps); + if (!profile) + return; + + priv->codec = gst_vaapi_profile_get_codec(profile); + if (!priv->codec) + return; + + if (gst_structure_get_int(structure, "width", &v1)) + priv->width = v1; + if (gst_structure_get_int(structure, "height", &v2)) + priv->height = v2; + + if (gst_structure_get_fraction(structure, "framerate", &v1, &v2)) { + priv->fps_n = v1; + priv->fps_d = v2; } - if (caps) { - structure = gst_caps_get_structure(caps, 0); - if (!structure) - return; - - profile = gst_vaapi_profile_from_caps(caps); - if (!profile) - return; - - priv->codec = gst_vaapi_profile_get_codec(profile); - if (!priv->codec) - return; - - if (!gst_structure_get_int(structure, "width", &width)) - width = 0; - if (!gst_structure_get_int(structure, "height", &height)) - height = 0; - priv->width = width; - priv->height = height; - - v_codec_data = gst_structure_get_value(structure, "codec_data"); - if (v_codec_data) - set_codec_data(decoder, gst_value_get_buffer(v_codec_data)); - } + v_codec_data = gst_structure_get_value(structure, "codec_data"); + if (v_codec_data) + set_codec_data(decoder, gst_value_get_buffer(v_codec_data)); } static void @@ -205,7 +197,6 @@ gst_vaapi_decoder_finalize(GObject *object) GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object); GstVaapiDecoderPrivate * const priv = decoder->priv; - set_caps(decoder, NULL); set_codec_data(decoder, NULL); if (priv->context) { @@ -318,7 +309,6 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) decoder->priv = priv; priv->context = NULL; - priv->caps = NULL; priv->codec = 0; priv->codec_data = NULL; priv->width = 0; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index c824188be9..2b30cf3447 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -112,7 +112,6 @@ G_BEGIN_DECLS struct _GstVaapiDecoderPrivate { GstVaapiDisplay *display; GstVaapiContext *context; - GstCaps *caps; GstVaapiCodec codec; GstBuffer *codec_data; guint width; From f6314162e09496d07b3e6d0c7768c2c28f9e1767 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 22:28:02 +0000 Subject: [PATCH 0331/3781] Rename gst_vaapi_decoder_ffmpeg_new_from_caps() to plain gst_vaapi_decoder_ffmpeg_new(). --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 29 +-------------------- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h | 9 +------ gst/vaapidecode/gstvaapidecode.c | 2 +- tests/test-decode.c | 2 +- 4 files changed, 4 insertions(+), 38 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 17e4029c1c..a866390c05 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -608,33 +608,6 @@ gst_vaapi_decoder_ffmpeg_init(GstVaapiDecoderFfmpeg *decoder) /** * gst_vaapi_decoder_ffmpeg_new: * @display: a #GstVaapiDisplay - * @codec: a #GstVaapiCodec - * @codec_data: an optional #GstBuffer holding extra codec data, or %NULL - * - * Creates a new #GstVaapiDecoder with the specified @codec bound to - * @display. @codec_data holds extra codec data like sequence headers. - * - * Return value: the newly allocated #GstVaapiDecoder object - */ -GstVaapiDecoder * -gst_vaapi_decoder_ffmpeg_new( - GstVaapiDisplay *display, - GstVaapiCodec codec, - GstBuffer *codec_data -) -{ - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - - return g_object_new(GST_VAAPI_TYPE_DECODER_FFMPEG, - "display", display, - "codec", codec, - "codec-data", codec_data, - NULL); -} - -/** - * st_vaapi_decoder_ffmpeg_new_from_caps: - * @display: a #GstVaapiDisplay * @caps: a #GstCaps holding codec information * * Creates a new #GstVaapiDecoder based on FFmpeg where the codec is @@ -644,7 +617,7 @@ gst_vaapi_decoder_ffmpeg_new( * Return value: the newly allocated #GstVaapiDecoder object */ GstVaapiDecoder * -gst_vaapi_decoder_ffmpeg_new_from_caps(GstVaapiDisplay *display, GstCaps *caps) +gst_vaapi_decoder_ffmpeg_new(GstVaapiDisplay *display, GstCaps *caps) { GstVaapiDecoderFfmpeg *ffdecoder; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h index acf5bf3836..ef0331801d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h @@ -80,14 +80,7 @@ GType gst_vaapi_decoder_ffmpeg_get_type(void); GstVaapiDecoder * -gst_vaapi_decoder_ffmpeg_new( - GstVaapiDisplay *display, - GstVaapiCodec codec, - GstBuffer *codec_data -); - -GstVaapiDecoder * -gst_vaapi_decoder_ffmpeg_new_from_caps(GstVaapiDisplay *display, GstCaps *caps); +gst_vaapi_decoder_ffmpeg_new(GstVaapiDisplay *display, GstCaps *caps); G_END_DECLS diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 82131b36d2..811052447a 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -178,7 +178,7 @@ gst_vaapidecode_create(GstVaapiDecode *decode) if (decode->use_ffmpeg) decode->decoder = - gst_vaapi_decoder_ffmpeg_new_from_caps(display, decode->decoder_caps); + gst_vaapi_decoder_ffmpeg_new(display, decode->decoder_caps); return decode->decoder != NULL; } diff --git a/tests/test-decode.c b/tests/test-decode.c index e17c229d40..995e691c58 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -126,7 +126,7 @@ main(int argc, char *argv[]) NULL ); - decoder = gst_vaapi_decoder_ffmpeg_new_from_caps(display, decoder_caps); + decoder = gst_vaapi_decoder_ffmpeg_new(display, decoder_caps); if (!decoder) g_error("could not create FFmpeg decoder"); gst_caps_unref(decoder_caps); From 79c34f823b426bb883cbef9042b7ca0ebba20fdb Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 22:34:53 +0000 Subject: [PATCH 0332/3781] Fix doc. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index f41e96ea85..3a6b78f230 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -329,7 +329,7 @@ gst_vaapi_profile_get_codec(GstVaapiProfile profile) /** * gst_vaapi_entrypoint: - * @entryprofile: a #VAEntrypoint + * @entrypoint: a #VAEntrypoint * * Converts a VA entry-point into the corresponding #GstVaapiEntrypoint. * If the entry-point cannot be represented by #GstVaapiEntrypoint, From c2c5d792872382cbb7ae59af52ff8c00f9f92634 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 22:36:34 +0000 Subject: [PATCH 0333/3781] Add missing docs. --- docs/reference/libs/Makefile.am | 11 +++ docs/reference/libs/libs-docs.xml.in | 4 + docs/reference/libs/libs-sections.txt | 94 +++++++++++++++++++++ docs/reference/libs/libs.core.types | 4 + docs/reference/plugins/Makefile.am | 1 + docs/reference/plugins/plugins-docs.xml.in | 1 + docs/reference/plugins/plugins-sections.txt | 15 +++- docs/reference/plugins/plugins.types | 1 + 8 files changed, 130 insertions(+), 1 deletion(-) diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index e8d184077b..05f1c79584 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -59,13 +59,24 @@ CFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.c $(srcdir)/$(DOC_MODULE).types # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h IGNORE_HFILES = \ + gstvaapi_priv.h \ + gstvaapicompat.h \ gstvaapidebug.h \ + gstvaapidecoder_priv.h \ + gstvaapidisplay_priv.h \ + gstvaapidisplay_glx_priv.h \ + gstvaapidisplay_x11_priv.h \ + gstvaapimarshal.h \ + gstvaapiobject_priv.h \ + gstvaapiparamspecs.h \ gstvaapiutils.h \ gstvaapiutils_glx.h \ gstvaapiutils_x11.h \ + gstvaapivalue.h \ $(NULL) EXTRA_HFILES = \ + gstvaapimarshal.c \ $(NULL) # Images to copy into HTML directory. diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 1fc8b46b48..97e19617ce 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -28,6 +28,10 @@ + + + + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 0f2389d3f9..c5bd0a402a 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -22,6 +22,12 @@ GstVaapiVideoPoolClass gst_vaapi_video_pool_get_caps gst_vaapi_video_pool_get_object gst_vaapi_video_pool_put_object +gst_vaapi_video_pool_add_object +gst_vaapi_video_pool_add_objects +gst_vaapi_video_pool_get_capacity +gst_vaapi_video_pool_set_capacity +gst_vaapi_video_pool_get_size +gst_vaapi_video_pool_reserve GST_VAAPI_VIDEO_POOL GST_VAAPI_IS_VIDEO_POOL @@ -181,14 +187,18 @@ GST_VAAPI_IMAGE_POOL_GET_CLASS GstVaapiVideoBuffer GstVaapiVideoBuffer GstVaapiVideoBufferClass +gst_vaapi_video_buffer_new gst_vaapi_video_buffer_new_from_pool gst_vaapi_video_buffer_new_with_image gst_vaapi_video_buffer_new_with_surface +gst_vaapi_video_buffer_new_with_surface_proxy gst_vaapi_video_buffer_get_image gst_vaapi_video_buffer_set_image gst_vaapi_video_buffer_set_image_from_pool gst_vaapi_video_buffer_get_surface +gst_vaapi_video_buffer_get_surface_proxy gst_vaapi_video_buffer_set_surface +gst_vaapi_video_buffer_set_surface_proxy gst_vaapi_video_buffer_set_surface_from_pool GST_VAAPI_VIDEO_BUFFER @@ -377,11 +387,14 @@ gst_vaapi_image_format_get_score GstVaapiProfile GstVaapiCodec GstVaapiProfile +GstVaapiEntrypoint gst_vaapi_profile gst_vaapi_profile_from_caps gst_vaapi_profile_get_va_profile gst_vaapi_profile_get_caps gst_vaapi_profile_get_codec +gst_vaapi_entrypoint +gst_vaapi_entrypoint_get_va_entrypoint
@@ -407,3 +420,84 @@ GST_VAAPI_TEXTURE_CLASS GST_VAAPI_IS_TEXTURE_CLASS GST_VAAPI_TEXTURE_GET_CLASS
+ +
+gstvaapicontext +GstVaapiContext +GstVaapiContext +GstVaapiContextClass +gst_vaapi_context_new +gst_vaapi_context_reset +gst_vaapi_context_get_id +gst_vaapi_context_get_profile +gst_vaapi_context_set_profile +gst_vaapi_context_get_entrypoint +gst_vaapi_context_get_size +gst_vaapi_context_get_surface +gst_vaapi_context_put_surface +gst_vaapi_context_find_surface_by_id + +GST_VAAPI_CONTEXT +GST_VAAPI_IS_CONTEXT +GST_VAAPI_TYPE_CONTEXT +gst_vaapi_context_get_type +GST_VAAPI_CONTEXT_CLASS +GST_VAAPI_IS_CONTEXT_CLASS +GST_VAAPI_CONTEXT_GET_CLASS +
+ +
+gstvaapidecoder +GstVaapiDecoderStatus +GstVaapiDecoder +GstVaapiDecoder +GstVaapiDecoderClass +gst_vaapi_decoder_put_buffer +gst_vaapi_decoder_get_surface + +GST_VAAPI_DECODER +GST_VAAPI_IS_DECODER +GST_VAAPI_TYPE_DECODER +gst_vaapi_decoder_get_type +GST_VAAPI_DECODER_CLASS +GST_VAAPI_IS_DECODER_CLASS +GST_VAAPI_DECODER_GET_CLASS +
+ +
+gstvaapidecoder_ffmpeg +GstVaapiDecoderFfmpeg +GstVaapiDecoderFfmpeg +GstVaapiDecoderFfmpegClass +gst_vaapi_decoder_ffmpeg_new + +GST_VAAPI_DECODER_FFMPEG +GST_VAAPI_IS_DECODER_FFMPEG +GST_VAAPI_TYPE_DECODER_FFMPEG +gst_vaapi_decoder_ffmpeg_get_type +GST_VAAPI_DECODER_FFMPEG_CLASS +GST_VAAPI_IS_DECODER_FFMPEG_CLASS +GST_VAAPI_DECODER_FFMPEG_GET_CLASS +
+ +
+gstvaapisurfaceproxy +GstVaapiSurfaceProxy +GstVaapiSurfaceProxy +GstVaapiSurfaceProxyClass +gst_vaapi_surface_proxy_new +gst_vaapi_surface_proxy_get_context +gst_vaapi_surface_proxy_set_context +gst_vaapi_surface_proxy_get_surface +gst_vaapi_surface_proxy_set_surface +gst_vaapi_surface_proxy_get_timestamp +gst_vaapi_surface_proxy_set_timestamp + +GST_VAAPI_SURFACE_PROXY +GST_VAAPI_IS_SURFACE_PROXY +GST_VAAPI_TYPE_SURFACE_PROXY +gst_vaapi_surface_proxy_get_type +GST_VAAPI_SURFACE_PROXY_CLASS +GST_VAAPI_IS_SURFACE_PROXY_CLASS +GST_VAAPI_SURFACE_PROXY_GET_CLASS +
diff --git a/docs/reference/libs/libs.core.types b/docs/reference/libs/libs.core.types index a33c353370..34a8f2ffb5 100644 --- a/docs/reference/libs/libs.core.types +++ b/docs/reference/libs/libs.core.types @@ -1,3 +1,6 @@ +gst_vaapi_context_get_type +gst_vaapi_decoder_get_type +gst_vaapi_decoder_ffmpeg_get_type gst_vaapi_display_get_type gst_vaapi_image_get_type gst_vaapi_image_pool_get_type @@ -5,6 +8,7 @@ gst_vaapi_object_get_type gst_vaapi_subpicture_get_type gst_vaapi_surface_get_type gst_vaapi_surface_pool_get_type +gst_vaapi_surface_proxy_get_type gst_vaapi_video_buffer_get_type gst_vaapi_video_pool_get_type gst_vaapi_video_sink_get_type diff --git a/docs/reference/plugins/Makefile.am b/docs/reference/plugins/Makefile.am index 8f10c708b0..473ba988b8 100644 --- a/docs/reference/plugins/Makefile.am +++ b/docs/reference/plugins/Makefile.am @@ -88,6 +88,7 @@ INCLUDES = \ GTKDOC_LIBS = \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la \ + $(top_builddir)/gst/vaapidecode/libgstvaapidecode.la \ $(top_builddir)/gst/vaapiconvert/libgstvaapiconvert.la \ $(top_builddir)/gst/vaapisink/libgstvaapisink.la \ $(GLIB_LIBS) diff --git a/docs/reference/plugins/plugins-docs.xml.in b/docs/reference/plugins/plugins-docs.xml.in index fbc2cf5a8f..4777999671 100644 --- a/docs/reference/plugins/plugins-docs.xml.in +++ b/docs/reference/plugins/plugins-docs.xml.in @@ -11,6 +11,7 @@ gst-plugins-vaapi Plugins + diff --git a/docs/reference/plugins/plugins-sections.txt b/docs/reference/plugins/plugins-sections.txt index 8853004e23..a0c0a31bec 100644 --- a/docs/reference/plugins/plugins-sections.txt +++ b/docs/reference/plugins/plugins-sections.txt @@ -12,6 +12,20 @@ GST_IS_VAAPISINK_CLASS GST_VAAPISINK_GET_CLASS +
+gstvaapidecode +GstVaapiDecode +GstVaapiDecode + +GST_VAAPIDECODE +GST_IS_VAAPIDECODE +GST_TYPE_VAAPIDECODE +gst_vaapidecode_get_type +GST_VAAPIDECODE_CLASS +GST_IS_VAAPIDECODE_CLASS +GST_VAAPIDECODE_GET_CLASS +
+
gstvaapiconvert GstVaapiConvert @@ -25,4 +39,3 @@ GST_VAAPICONVERT_CLASS GST_IS_VAAPICONVERT_CLASS GST_VAAPICONVERT_GET_CLASS
- diff --git a/docs/reference/plugins/plugins.types b/docs/reference/plugins/plugins.types index fab5f67fc3..db94655ea2 100644 --- a/docs/reference/plugins/plugins.types +++ b/docs/reference/plugins/plugins.types @@ -1,2 +1,3 @@ gst_vaapisink_get_type +gst_vaapidecode_get_type gst_vaapiconvert_get_type From 197eeb848eed8d41d7baa17e58f582f8cbadc6ab Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 22:42:46 +0000 Subject: [PATCH 0334/3781] Fix make dist. --- tests/Makefile.am | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 0147c9f19a..1441704844 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -58,7 +58,12 @@ test_textures_SOURCES = test-textures.c image.c test_textures_CFLAGS = $(TEST_CFLAGS) $(TEST_GLX_CFLAGS) test_textures_LDADD = $(TEST_LIBS) $(TEST_GLX_LIBS) -EXTRA_DIST = image.h $(test_codecs_source_c) $(test_codecs_source_h) +EXTRA_DIST = \ + image.h \ + test-decode.h \ + $(test_codecs_source_c) \ + $(test_codecs_source_h) \ + $(NULL) # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in From e044e545e25bdcd6da0c996bd72990b79e97437b Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 22:43:01 +0000 Subject: [PATCH 0335/3781] 0.2.0. --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 33df33855d..924e9f0832 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ -gst-vaapi NEWS -- summary of changes. 2010-04-DD +gst-vaapi NEWS -- summary of changes. 2010-05-04 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.2.0 - DD.Apr.2010 +Version 0.2.0 - 04.May.2010 * Relicense gst-libs/ code to LGPL v2.1+ * Add FFmpeg/VAAPI decoder for the new `vaapidecode' element From 85466028ad775dd0f79c53a19a016f4d2a07fb6c Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 22:50:56 +0000 Subject: [PATCH 0336/3781] Fix build with older VA-API 0.29. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 3a6b78f230..1c9f56109e 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -161,7 +161,7 @@ static GstVaapiProfile gst_vaapi_profile_from_codec_data_h264(GstBuffer *buffer) { /* MPEG-4 Part 15: Advanced Video Coding (AVC) file format */ - uint8_t * const buf = GST_BUFFER_DATA(buffer); + guchar * const buf = GST_BUFFER_DATA(buffer); if (buf[0] != 1) /* configurationVersion = 1 */ return 0; From e226acaea5818df662e092751a2d75dfc5c4940b Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 4 May 2010 08:59:27 +0000 Subject: [PATCH 0337/3781] Improve documentation for release. --- README | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/README b/README index 73a2b796c5..cf2ea0ff15 100644 --- a/README +++ b/README @@ -21,6 +21,10 @@ Overview gstreamer-vaapi consists in a collection of VA-API based plugins for GStreamer and helper libraries. + * `vaapidecode' is used to decode MPEG-2, MPEG-4, H.264, VC-1, WMV3 + videos to video/x-vaapi-surfaces surfaces, depending on the + underlying HW capabilities. + * `vaapiconvert' is used to convert from video/x-raw-yuv pixels to video/x-vaapi-surface surfaces. @@ -33,11 +37,22 @@ Features * VA-API support from 0.29 to 0.31 * OpenGL rendering through VA/GLX or GLX texture-from-pixmap + FBO + * Support for major HW video decoding solutions on Linux (AMD, Intel, NVIDIA) Requirements ------------ -libgstreamer0.10-dev >= 0.10.0 -libgstreamer-plugins-base0.10-dev >= 0.10.0 -libva-dev >= 0.31.0-1+sds9 (VA/GLX) +Software requirements + + * libgstreamer0.10-dev >= 0.10.0 + * libgstreamer-plugins-base0.10-dev >= 0.10.0 + * libva-dev >= 0.31.0-1+sds9 (VA/GLX) + +Hardware requirements + + * AMD platforms with UVD2 (XvBA supported) + * Intel Poulsbo (US15W) + * Intel Eaglelake (G45) + * Intel Ironlake (HD Graphics) + * NVIDIA platforms with PureVideo (VDPAU supported) From e1e1c253e143e97d6a9492f7c7281aa9a47e06b6 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 4 May 2010 14:59:27 +0000 Subject: [PATCH 0338/3781] Don't build plugins with SONAME. Make them plain *.so. --- configure.ac | 12 ++++++++++++ debian.upstream/gstreamer-vaapi.install.in | 2 +- gst/vaapiconvert/Makefile.am | 1 + gst/vaapidecode/Makefile.am | 1 + gst/vaapisink/Makefile.am | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 980fc72492..2bdbe9a612 100644 --- a/configure.ac +++ b/configure.ac @@ -154,6 +154,18 @@ PKG_CHECK_MODULES([GST_VIDEO], AC_SUBST(GST_VIDEO_CFLAGS) AC_SUBST(GST_VIDEO_LIBS) +dnl GST_ALL_LDFLAGS: +dnl LDFLAGS really should only contain flags, not libs - they get added before +dnl whatevertarget_LIBS and -L flags here affect the rest of the linking +GST_ALL_LDFLAGS="-no-undefined" +AC_SUBST(GST_ALL_LDFLAGS) + +dnl GST_PLUGIN_LDFLAGS: +dnl this really should only contain flags, not libs - they get added before +dnl whatevertarget_LIBS and -L flags here affect the rest of the linking +GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^([_]*gst_plugin_desc|gst_.*_get_type)\$\$' $GST_ALL_LDFLAGS" +AC_SUBST(GST_PLUGIN_LDFLAGS) + dnl Check for the GStreamer plugins directory AC_MSG_CHECKING([for GStreamer plugins directory]) GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_MAJORMINOR --variable pluginsdir` diff --git a/debian.upstream/gstreamer-vaapi.install.in b/debian.upstream/gstreamer-vaapi.install.in index 76b63bdfa5..5af8fbb5e6 100644 --- a/debian.upstream/gstreamer-vaapi.install.in +++ b/debian.upstream/gstreamer-vaapi.install.in @@ -1 +1 @@ -debian/tmp/usr/lib/gstreamer-@GST_MAJORMINOR@/libgstvaapi*.so* +debian/tmp/usr/lib/gstreamer-@GST_MAJORMINOR@/libgstvaapi*.so diff --git a/gst/vaapiconvert/Makefile.am b/gst/vaapiconvert/Makefile.am index 74e3d37872..34a865990d 100644 --- a/gst/vaapiconvert/Makefile.am +++ b/gst/vaapiconvert/Makefile.am @@ -28,6 +28,7 @@ libgstvaapiconvert_la_LIBADD = \ $(GST_VIDEO_LIBS) \ $(GST_PLUGINS_BASE_LIBS) +libgstvaapiconvert_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvaapiconvert_la_LIBTOOLFLAGS = --tag=disable-static # Extra clean files so that maintainer-clean removes *everything* diff --git a/gst/vaapidecode/Makefile.am b/gst/vaapidecode/Makefile.am index b5a230e302..b1fd20d5e2 100644 --- a/gst/vaapidecode/Makefile.am +++ b/gst/vaapidecode/Makefile.am @@ -28,6 +28,7 @@ libgstvaapidecode_la_LIBADD = \ $(GST_VIDEO_LIBS) \ $(GST_PLUGINS_BASE_LIBS) +libgstvaapidecode_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvaapidecode_la_LIBTOOLFLAGS = --tag=disable-static # Extra clean files so that maintainer-clean removes *everything* diff --git a/gst/vaapisink/Makefile.am b/gst/vaapisink/Makefile.am index 3265f33be0..c1298b9555 100644 --- a/gst/vaapisink/Makefile.am +++ b/gst/vaapisink/Makefile.am @@ -31,6 +31,7 @@ libgstvaapisink_la_LIBADD = \ $(GST_VIDEO_LIBS) \ $(GST_PLUGINS_BASE_LIBS) +libgstvaapisink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvaapisink_la_LIBTOOLFLAGS = --tag=disable-static # Extra clean files so that maintainer-clean removes *everything* From eec67a5972ae88b361330cdf44b65d9d09b8afcc Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 4 May 2010 15:02:29 +0000 Subject: [PATCH 0339/3781] Link helper libraries with libtool -no-undefined. --- gst-libs/gst/vaapi/Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 04a4547b43..e5e2bdbff9 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -204,6 +204,10 @@ libgstvaapi_glx_@GST_MAJORMINOR@_la_LIBADD = \ libgstvaapi-x11-@GST_MAJORMINOR@.la \ $(NULL) +libgstvaapi_glx_@GST_MAJORMINOR@_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(NULL) + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in From 01af005ec253442111fa79fbaa86cfc0a20cc15f Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 4 May 2010 15:03:47 +0000 Subject: [PATCH 0340/3781] Really link all helper libraries with libtool -no-undefined. --- gst-libs/gst/vaapi/Makefile.am | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index e5e2bdbff9..bc11346f5f 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -150,6 +150,10 @@ libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ $(LIBVA_LIBS) \ $(NULL) +libgstvaapi_@GST_MAJORMINOR@_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(NULL) + libgstvaapi_x11_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_x11_source_c) \ $(libgstvaapi_x11_source_priv_h) \ @@ -177,6 +181,10 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_LIBADD = \ libgstvaapi-@GST_MAJORMINOR@.la \ $(NULL) +libgstvaapi_x11_@GST_MAJORMINOR@_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(NULL) + libgstvaapi_glx_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_glx_source_c) \ $(libgstvaapi_glx_source_priv_h) \ From 73c80aa1ed8ff27437e2fddca7f19a87e2d9429b Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 5 May 2010 06:06:02 +0000 Subject: [PATCH 0341/3781] Lower plugins rank for now since playbin2 auto-plugging is not working properly. User applications will have to create their own pipeline or with some hacks around playbin2. --- gst/vaapiconvert/gstvaapiconvert.c | 2 +- gst/vaapidecode/gstvaapidecode.c | 2 +- gst/vaapisink/gstvaapisink.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index e579eb3672..352e0e6267 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -674,7 +674,7 @@ static gboolean plugin_init(GstPlugin *plugin) return gst_element_register(plugin, GST_PLUGIN_NAME, - GST_RANK_PRIMARY, + GST_RANK_NONE, GST_TYPE_VAAPICONVERT); } diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 811052447a..38924fe16e 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -451,7 +451,7 @@ static gboolean plugin_init(GstPlugin *plugin) return gst_element_register(plugin, GST_PLUGIN_NAME, - GST_RANK_PRIMARY, + GST_RANK_NONE, GST_TYPE_VAAPIDECODE); } diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index bb56b75705..c849f18c50 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -686,7 +686,7 @@ static gboolean plugin_init(GstPlugin *plugin) return gst_element_register(plugin, GST_PLUGIN_NAME, - GST_RANK_PRIMARY, + GST_RANK_NONE, GST_TYPE_VAAPISINK); } From e739b7a289a86731d248889eed601e7ca2b0afdc Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 5 May 2010 11:44:06 +0000 Subject: [PATCH 0342/3781] Fix docs. --- docs/reference/libs/Makefile.am | 1 - docs/reference/libs/libs-sections.txt | 3 --- gst-libs/gst/vaapi/gstvaapidecoder.h | 1 - gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 2 -- 4 files changed, 7 deletions(-) diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index 05f1c79584..f3584b1038 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -72,7 +72,6 @@ IGNORE_HFILES = \ gstvaapiutils.h \ gstvaapiutils_glx.h \ gstvaapiutils_x11.h \ - gstvaapivalue.h \ $(NULL) EXTRA_HFILES = \ diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index c5bd0a402a..63a2eddb51 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -132,9 +132,6 @@ GST_VAAPI_WINDOW_GLX_GET_CLASS
gstvaapidisplay -GST_VAAPI_DISPLAY_VADISPLAY -GST_VAAPI_DISPLAY_LOCK -GST_VAAPI_DISPLAY_UNLOCK GstVaapiDisplay GstVaapiDisplay GstVaapiDisplayClass diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index e7bc5ca66f..fbffdd8e08 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -95,7 +95,6 @@ struct _GstVaapiDecoder { /** * GstVaapiDecoderClass: - * @decode: decode one frame. * * A VA decoder base class. */ diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 1ccb81592d..364244e23b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -77,8 +77,6 @@ typedef struct _GstVaapiSurfaceProxyClass GstVaapiSurfaceProxyClass; /** * GstVaapiSurfaceProxy: - * @surface: a #GstVaapiSurface - * @context: the #GstVaapiContext to which the @surface is bound * * A wrapper around a VA surface and context. */ From 52eb154b1db495a0f5a591d941a8a10fa05f5bbf Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 5 May 2010 11:48:31 +0000 Subject: [PATCH 0343/3781] Don't exclude GstVaapiParamSpecs. --- docs/reference/libs/Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index f3584b1038..e8b5369f15 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -68,7 +68,6 @@ IGNORE_HFILES = \ gstvaapidisplay_x11_priv.h \ gstvaapimarshal.h \ gstvaapiobject_priv.h \ - gstvaapiparamspecs.h \ gstvaapiutils.h \ gstvaapiutils_glx.h \ gstvaapiutils_x11.h \ From 5dc932739ff8e6b7640819378bfcc8d28bbc4baa Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 5 May 2010 12:28:59 +0000 Subject: [PATCH 0344/3781] More docs. --- README | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README b/README index cf2ea0ff15..e192cc77b9 100644 --- a/README +++ b/README @@ -48,6 +48,7 @@ Software requirements * libgstreamer0.10-dev >= 0.10.0 * libgstreamer-plugins-base0.10-dev >= 0.10.0 * libva-dev >= 0.31.0-1+sds9 (VA/GLX) + * libavcodec-dev >= 0.6 or with Hardware requirements @@ -56,3 +57,23 @@ Hardware requirements * Intel Eaglelake (G45) * Intel Ironlake (HD Graphics) * NVIDIA platforms with PureVideo (VDPAU supported) + + +Usage +----- + +The GStreamer pipeline currently has to be built manually. +i.e. neither decodebin{,2} nor playbin{,2} would select the VA-API +elements automatically. + + * Play an H.264 video with an MP4 container in fullscreen mode + $ gst-launch-0.10 -v filesrc location=/path/to/video.mp4 ! \ + qtdemux ! vaapidecode ! vaapisink fullscreen=true + + +Caveats +------- + + * No automatic integration within the default playbin2 pipeline + * No ad-hoc parser, vaapidecoder currently relies on FFmpeg + * MPEG-4 Part-2 (DivX) has decoding bugs From ad637058b3a350e6a571105352c30246e4291c16 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 5 May 2010 12:29:28 +0000 Subject: [PATCH 0345/3781] Really make it 0.2.0. --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 924e9f0832..0219c2fbea 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ -gst-vaapi NEWS -- summary of changes. 2010-05-04 +gst-vaapi NEWS -- summary of changes. 2010-05-05 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.2.0 - 04.May.2010 +Version 0.2.0 - 05.May.2010 * Relicense gst-libs/ code to LGPL v2.1+ * Add FFmpeg/VAAPI decoder for the new `vaapidecode' element From 2a4f429007020d3393d16efaad0ee5d33d83fcc9 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 5 May 2010 12:57:59 +0000 Subject: [PATCH 0346/3781] Bump version for development. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 2bdbe9a612..0a8b92ed71 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [2]) -m4_define([gst_vaapi_micro_version], [0]) +m4_define([gst_vaapi_micro_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From 4a485200b91bb9ca82c7064b136e8ff35ee5f28b Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 5 May 2010 15:36:25 +0000 Subject: [PATCH 0347/3781] Add gst_vaapidecode_ensure_display() helper for set-caps. --- gst/vaapidecode/gstvaapidecode.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 38924fe16e..dd1f2ab613 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -160,11 +160,14 @@ error_commit_buffer: } static gboolean -gst_vaapidecode_create(GstVaapiDecode *decode) +gst_vaapidecode_ensure_display(GstVaapiDecode *decode) { GstVaapiVideoSink *sink; GstVaapiDisplay *display; + if (decode->display) + return TRUE; + /* Look for a downstream vaapisink */ sink = gst_vaapi_video_sink_lookup(GST_ELEMENT(decode)); if (!sink) @@ -175,10 +178,18 @@ gst_vaapidecode_create(GstVaapiDecode *decode) return FALSE; decode->display = g_object_ref(display); + return TRUE; +} + +static gboolean +gst_vaapidecode_create(GstVaapiDecode *decode) +{ + if (!gst_vaapidecode_ensure_display(decode)) + return FALSE; if (decode->use_ffmpeg) decode->decoder = - gst_vaapi_decoder_ffmpeg_new(display, decode->decoder_caps); + gst_vaapi_decoder_ffmpeg_new(decode->display, decode->decoder_caps); return decode->decoder != NULL; } From 80e5b1ba173ee3b2f4c104049016ee272a7fbec7 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 7 May 2010 06:35:31 +0000 Subject: [PATCH 0348/3781] Factor out VA surface caps. --- gst-libs/gst/vaapi/gstvaapisurface.h | 11 +++++++++++ gst/vaapiconvert/gstvaapiconvert.c | 4 +--- gst/vaapidecode/gstvaapidecode.c | 4 +--- gst/vaapisink/gstvaapisink.c | 5 +---- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 0cb27759f2..11fc35567a 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -33,6 +33,17 @@ typedef enum _GstVaapiChromaType GstVaapiChromaType; typedef enum _GstVaapiSurfaceStatus GstVaapiSurfaceStatus; typedef enum _GstVaapiSurfaceRenderFlags GstVaapiSurfaceRenderFlags; +/** + * GST_VAAPI_SURFACE_CAPS: + * + * Generic caps for VA surfaces. + */ +#define GST_VAAPI_SURFACE_CAPS \ + "video/x-vaapi-surface, " \ + "width = (int) [ 1, MAX ]," \ + "height = (int) [ 1, MAX ]," \ + "framerate = (fraction) [ 0, MAX ]" + /** * GstVaapiChromaType: * @GST_VAAPI_CHROMA_TYPE_YUV420: 4:2:0 chroma format diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index 352e0e6267..652974e7ab 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -53,9 +53,7 @@ static const char gst_vaapiconvert_yuv_caps_str[] = "height = (int) [ 1, MAX ]; "; static const char gst_vaapiconvert_vaapi_caps_str[] = - "video/x-vaapi-surface, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; "; + GST_VAAPI_SURFACE_CAPS; static GstStaticPadTemplate gst_vaapiconvert_sink_factory = GST_STATIC_PAD_TEMPLATE( diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index dd1f2ab613..191665650e 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -63,9 +63,7 @@ static const char gst_vaapidecode_sink_caps_str[] = ; static const char gst_vaapidecode_src_caps_str[] = - "video/x-vaapi-surface, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; "; + GST_VAAPI_SURFACE_CAPS; static GstStaticPadTemplate gst_vaapidecode_sink_factory = GST_STATIC_PAD_TEMPLATE( diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index c849f18c50..25da39feb9 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -60,10 +60,7 @@ static GstStaticPadTemplate gst_vaapisink_sink_factory = "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS( - "video/x-vaapi-surface, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; ")); + GST_STATIC_CAPS(GST_VAAPI_SURFACE_CAPS)); static void gst_vaapisink_iface_init(GType type); From 608d2d071bc5083abf979bb5718027d41086d8fb Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 10 May 2010 09:32:47 +0000 Subject: [PATCH 0349/3781] Improve plugin details. --- gst/vaapiconvert/gstvaapiconvert.c | 6 +++--- gst/vaapidecode/gstvaapidecode.c | 2 +- gst/vaapisink/gstvaapisink.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index 652974e7ab..9bb52ea4fd 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -41,9 +41,9 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapiconvert); /* ElementFactory information */ static const GstElementDetails gst_vaapiconvert_details = GST_ELEMENT_DETAILS( - "Video convert", - "Convert/Video", - "A VA-API based videoconvert", + "VA-API colorspace converter", + "Filter/Converter/Video", + GST_PLUGIN_DESC, "Gwenole Beauchesne "); /* Default templates */ diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 191665650e..427b463c65 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -41,7 +41,7 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapidecode); /* ElementFactory information */ static const GstElementDetails gst_vaapidecode_details = GST_ELEMENT_DETAILS( - "Video decode", + "VA-API decoder", "Codec/Decoder/Video", GST_PLUGIN_DESC, "Gwenole Beauchesne "); diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 25da39feb9..7277d5dd25 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -49,9 +49,9 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink); /* ElementFactory information */ static const GstElementDetails gst_vaapisink_details = GST_ELEMENT_DETAILS( - "Video sink", + "VA-API sink", "Sink/Video", - "A VA-API based videosink", + GST_PLUGIN_DESC, "Gwenole Beauchesne "); /* Default template */ From bceab0254ccf2b52f3be1a610979c0eb8b38429a Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 11 May 2010 12:03:13 +0000 Subject: [PATCH 0350/3781] Stop iteration if there is no more element to examine. --- gst-libs/gst/vaapi/gstvaapivideosink.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.c b/gst-libs/gst/vaapi/gstvaapivideosink.c index ab4e4524e2..b9584fa61b 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.c +++ b/gst-libs/gst/vaapi/gstvaapivideosink.c @@ -105,12 +105,13 @@ gst_vaapi_video_sink_lookup(GstElement *element) break; element = gst_pad_get_parent_element(peer); - if (element) { - if (GST_VAAPI_IS_VIDEO_SINK(element)) - sink = GST_VAAPI_VIDEO_SINK(element); - g_object_unref(element); - } g_object_unref(peer); + if (!element) + break; + + if (GST_VAAPI_IS_VIDEO_SINK(element)) + sink = GST_VAAPI_VIDEO_SINK(element); + g_object_unref(element); } return sink; } From 6f5e593abdf8638035865b444814128cd9161e07 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 11 May 2010 12:06:59 +0000 Subject: [PATCH 0351/3781] Expose video pool display. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapivideopool.c | 19 ++++++++++++++++++- gst-libs/gst/vaapi/gstvaapivideopool.h | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 63a2eddb51..d759354382 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -19,6 +19,7 @@ GST_VAAPI_SURFACE_POOL_GET_CLASS GstVaapiVideoPool GstVaapiVideoPool GstVaapiVideoPoolClass +gst_vaapi_video_pool_get_display gst_vaapi_video_pool_get_caps gst_vaapi_video_pool_get_object gst_vaapi_video_pool_put_object diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 985742ef8a..fca27345ba 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -146,7 +146,7 @@ gst_vaapi_video_pool_get_property( switch (prop_id) { case PROP_DISPLAY: - g_value_set_object(value, pool->priv->display); + g_value_set_object(value, gst_vaapi_video_pool_get_display(pool)); break; case PROP_CAPS: g_value_set_pointer(value, gst_vaapi_video_pool_get_caps(pool)); @@ -230,6 +230,23 @@ gst_vaapi_video_pool_init(GstVaapiVideoPool *pool) g_queue_init(&priv->free_objects); } +/** + * gst_vaapi_video_pool_get_display: + * @pool: a #GstVaapiVideoPool + * + * Retrieves the #GstVaapiDisplay the @pool is bound to. The @pool + * owns the returned object and it shall not be unref'ed. + * + * Return value: the #GstVaapiDisplay the @pool is bound to + */ +GstVaapiDisplay * +gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); + + return pool->priv->display; +} + /** * gst_vaapi_video_pool_get_caps: * @pool: a #GstVaapiVideoPool diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 7552ef7189..a7b44242af 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -88,6 +88,9 @@ struct _GstVaapiVideoPoolClass { GType gst_vaapi_video_pool_get_type(void); +GstVaapiDisplay * +gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool); + GstCaps * gst_vaapi_video_pool_get_caps(GstVaapiVideoPool *pool); From 710ab89fca65a6552c99eeec4efa53e7dd0f4a6a Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 11 May 2010 16:09:49 +0000 Subject: [PATCH 0352/3781] Simplify gst_vaapidecode_set_caps() and fix memory leak. --- gst/vaapidecode/gstvaapidecode.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 427b463c65..3db683e69f 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -334,19 +334,17 @@ static gboolean gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) { GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); - GstPad *other_pad; GstCaps *other_caps = NULL; GstStructure *structure; const GValue *v_width, *v_height, *v_framerate, *v_par; + gboolean success; - if (pad == decode->sinkpad) { - other_pad = decode->srcpad; - other_caps = gst_caps_from_string(gst_vaapidecode_src_caps_str); - } - else { - other_pad = decode->sinkpad; - other_caps = gst_caps_from_string(gst_vaapidecode_sink_caps_str); - } + g_return_val_if_fail(pad == decode->sinkpad, FALSE); + decode->decoder_caps = gst_caps_ref(caps); + + other_caps = gst_caps_from_string(gst_vaapidecode_src_caps_str); + if (!other_caps) + return FALSE; /* Negotiation succeeded, so now configure ourselves */ structure = gst_caps_get_structure(caps, 0); @@ -355,9 +353,6 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) v_framerate = gst_structure_get_value(structure, "framerate"); v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); - if (pad == decode->sinkpad) - decode->decoder_caps = gst_caps_ref(caps); - structure = gst_caps_get_structure(other_caps, 0); gst_structure_set_value(structure, "width", v_width); gst_structure_set_value(structure, "height", v_height); @@ -366,7 +361,9 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) if (v_par) gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); - return gst_pad_set_caps(other_pad, other_caps); + success = gst_pad_set_caps(decode->srcpad, other_caps); + gst_caps_unref(other_caps); + return success; } static GstFlowReturn From 39dbd70c8f5dcb09a12d918af2c143dd6679e1fd Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 11 May 2010 16:19:30 +0000 Subject: [PATCH 0353/3781] Expose VA display through GstVaapiVideoBuffer. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapivideobuffer.c | 101 +++++++++++++++++++---- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 6 +- gst/vaapisink/gstvaapisink.c | 3 +- 4 files changed, 95 insertions(+), 16 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index d759354382..d7f62823cc 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -190,6 +190,7 @@ gst_vaapi_video_buffer_new_from_pool gst_vaapi_video_buffer_new_with_image gst_vaapi_video_buffer_new_with_surface gst_vaapi_video_buffer_new_with_surface_proxy +gst_vaapi_video_buffer_get_display gst_vaapi_video_buffer_get_image gst_vaapi_video_buffer_set_image gst_vaapi_video_buffer_set_image_from_pool diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 113df760ef..17fff380ef 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -25,8 +25,9 @@ #include "config.h" #include "gstvaapivideobuffer.h" -#include -#include +#include "gstvaapiimagepool.h" +#include "gstvaapisurfacepool.h" +#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -39,6 +40,7 @@ G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, GST_TYPE_BUFFER); GstVaapiVideoBufferPrivate)) struct _GstVaapiVideoBufferPrivate { + GstVaapiDisplay *display; GstVaapiVideoPool *image_pool; GstVaapiImage *image; GstVaapiVideoPool *surface_pool; @@ -46,6 +48,34 @@ struct _GstVaapiVideoBufferPrivate { GstVaapiSurfaceProxy *proxy; }; +static void +set_display(GstVaapiVideoBuffer *buffer, GstVaapiDisplay *display) +{ + GstVaapiVideoBufferPrivate * const priv = buffer->priv; + + if (priv->display) { + g_object_unref(priv->display); + priv->display = NULL; + } + + if (display) + priv->display = g_object_ref(display); +} + +static inline void +set_image(GstVaapiVideoBuffer *buffer, GstVaapiImage *image) +{ + buffer->priv->image = g_object_ref(image); + set_display(buffer, GST_VAAPI_OBJECT_DISPLAY(image)); +} + +static inline void +set_surface(GstVaapiVideoBuffer *buffer, GstVaapiSurface *surface) +{ + buffer->priv->surface = g_object_ref(surface); + set_display(buffer, GST_VAAPI_OBJECT_DISPLAY(surface)); +} + static void gst_vaapi_video_buffer_destroy_image(GstVaapiVideoBuffer *buffer) { @@ -98,6 +128,8 @@ gst_vaapi_video_buffer_finalize(GstMiniObject *object) gst_vaapi_video_buffer_destroy_image(buffer); gst_vaapi_video_buffer_destroy_surface(buffer); + set_display(buffer, NULL); + parent_class = GST_MINI_OBJECT_CLASS(gst_vaapi_video_buffer_parent_class); if (parent_class->finalize) parent_class->finalize(object); @@ -120,6 +152,7 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) priv = GST_VAAPI_VIDEO_BUFFER_GET_PRIVATE(buffer); buffer->priv = priv; + priv->display = NULL; priv->image_pool = NULL; priv->image = NULL; priv->surface_pool = NULL; @@ -129,6 +162,7 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) /** * gst_vaapi_video_buffer_new: + * @display: a #GstVaapiDisplay * * Creates an empty #GstBuffer. The caller is responsible for completing * the initialization of the buffer with the gst_vaapi_video_buffer_set_*() @@ -143,9 +177,18 @@ _gst_vaapi_video_buffer_new(void) } GstBuffer * -gst_vaapi_video_buffer_new(void) +gst_vaapi_video_buffer_new(GstVaapiDisplay *display) { - return _gst_vaapi_video_buffer_new(); + GstBuffer *buffer; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + buffer = _gst_vaapi_video_buffer_new(); + if (!buffer) + return NULL; + + set_display(GST_VAAPI_VIDEO_BUFFER(buffer), display); + return buffer; } /** @@ -179,8 +222,10 @@ gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) ((is_image_pool && gst_vaapi_video_buffer_set_image_from_pool(buffer, pool)) || (is_surface_pool && - gst_vaapi_video_buffer_set_surface_from_pool(buffer, pool)))) + gst_vaapi_video_buffer_set_surface_from_pool(buffer, pool)))) { + set_display(buffer, gst_vaapi_video_pool_get_display(pool)); return GST_BUFFER(buffer); + } gst_mini_object_unref(GST_MINI_OBJECT(buffer)); return NULL; @@ -252,6 +297,24 @@ gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) return GST_BUFFER(buffer); } +/** + * gst_vaapi_video_buffer_get_display: + * @buffer: a #GstVaapiVideoBuffer + * + * Retrieves the #GstVaapiDisplay the @buffer is bound to. The @buffer + * owns the returned #GstVaapiDisplay object so the caller is + * responsible for calling g_object_ref() when needed. + * + * Return value: the #GstVaapiDisplay the @buffer is bound to + */ +GstVaapiDisplay * +gst_vaapi_video_buffer_get_display(GstVaapiVideoBuffer *buffer) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL); + + return buffer->priv->display; +} + /** * gst_vaapi_video_buffer_get_image: * @buffer: a #GstVaapiVideoBuffer @@ -292,7 +355,7 @@ gst_vaapi_video_buffer_set_image( gst_vaapi_video_buffer_destroy_image(buffer); if (image) - buffer->priv->image = g_object_ref(image); + set_image(buffer, image); } /** @@ -312,15 +375,18 @@ gst_vaapi_video_buffer_set_image_from_pool( GstVaapiVideoPool *pool ) { + GstVaapiImage *image; + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), FALSE); g_return_val_if_fail(GST_VAAPI_IS_IMAGE_POOL(pool), FALSE); gst_vaapi_video_buffer_destroy_image(buffer); if (pool) { - buffer->priv->image = gst_vaapi_video_pool_get_object(pool); - if (!buffer->priv->image) + image = gst_vaapi_video_pool_get_object(pool); + if (!image) return FALSE; + set_image(buffer, image); buffer->priv->image_pool = g_object_ref(pool); } return TRUE; @@ -366,7 +432,7 @@ gst_vaapi_video_buffer_set_surface( gst_vaapi_video_buffer_destroy_surface(buffer); if (surface) - buffer->priv->surface = g_object_ref(surface); + set_surface(buffer, surface); } /** @@ -386,15 +452,18 @@ gst_vaapi_video_buffer_set_surface_from_pool( GstVaapiVideoPool *pool ) { + GstVaapiSurface *surface; + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), FALSE); g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), FALSE); gst_vaapi_video_buffer_destroy_surface(buffer); if (pool) { - buffer->priv->surface = gst_vaapi_video_pool_get_object(pool); - if (!buffer->priv->surface) + surface = gst_vaapi_video_pool_get_object(pool); + if (!surface) return FALSE; + set_surface(buffer, surface); buffer->priv->surface_pool = g_object_ref(pool); } return TRUE; @@ -434,14 +503,18 @@ gst_vaapi_video_buffer_set_surface_proxy( GstVaapiSurfaceProxy *proxy ) { + GstVaapiSurface *surface; + g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer)); g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); gst_vaapi_video_buffer_destroy_surface(buffer); if (proxy) { - GstVaapiVideoBufferPrivate * const priv = buffer->priv; - priv->proxy = g_object_ref(proxy); - priv->surface = g_object_ref(GST_VAAPI_SURFACE_PROXY_SURFACE(proxy)); + surface = GST_VAAPI_SURFACE_PROXY_SURFACE(proxy); + if (!surface) + return; + set_surface(buffer, surface); + buffer->priv->proxy = g_object_ref(proxy); } } diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index a885976565..572d20cf9f 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -23,6 +23,7 @@ #define GST_VAAPI_VIDEO_BUFFER_H #include +#include #include #include #include @@ -84,7 +85,7 @@ GType gst_vaapi_video_buffer_get_type(void); GstBuffer * -gst_vaapi_video_buffer_new(void); +gst_vaapi_video_buffer_new(GstVaapiDisplay *display); GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); @@ -98,6 +99,9 @@ gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface); GstBuffer * gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); +GstVaapiDisplay * +gst_vaapi_video_buffer_get_display(GstVaapiVideoBuffer *buffer); + GstVaapiImage * gst_vaapi_video_buffer_get_image(GstVaapiVideoBuffer *buffer); diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 7277d5dd25..8384153595 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -281,6 +281,7 @@ gst_vaapisink_buffer_alloc( GstBuffer **pout_buffer ) { + GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstBuffer *buffer; GstCaps *sink_caps; @@ -291,7 +292,7 @@ gst_vaapisink_buffer_alloc( if (!gst_caps_is_always_compatible(caps, sink_caps)) goto error_invalid_caps; - buffer = gst_vaapi_video_buffer_new(); + buffer = gst_vaapi_video_buffer_new(sink->display); if (!buffer) goto error_create_buffer; From af1fd4b9101367b118889d4b27d8f2001847f39d Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 11 May 2010 16:23:17 +0000 Subject: [PATCH 0354/3781] Use fixed caps on the src pad, they are not meant to change from video/x-vaapi-surface. --- gst/vaapidecode/gstvaapidecode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 3db683e69f..3d8ccc99a2 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -446,6 +446,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) "src" ); + gst_pad_use_fixed_caps(decode->srcpad); gst_pad_set_event_function(decode->srcpad, gst_vaapidecode_src_event); gst_element_add_pad(GST_ELEMENT(decode), decode->srcpad); } From 453164d0c5cda87dba3844c18b7607c37a80eb32 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 07:57:55 +0000 Subject: [PATCH 0355/3781] Add gst_vaapi_display_lookup_downstream() helper. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapiutils_gst.c | 108 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_gst.h | 31 +++++++ 3 files changed, 141 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_gst.c create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_gst.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index bc11346f5f..9759baf839 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -37,6 +37,7 @@ libgstvaapi_source_c = \ gstvaapisurfacepool.c \ gstvaapisurfaceproxy.c \ gstvaapiutils.c \ + gstvaapiutils_gst.c \ gstvaapivalue.c \ gstvaapivideobuffer.c \ gstvaapivideopool.c \ @@ -75,6 +76,7 @@ libgstvaapi_source_priv_h = \ gstvaapidisplay_priv.h \ gstvaapiobject_priv.h \ gstvaapiutils.h \ + gstvaapiutils_gst.h \ gstvaapi_priv.h \ $(libgst_vaapi_ffmpeg_source_priv_h) \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_gst.c b/gst-libs/gst/vaapi/gstvaapiutils_gst.c new file mode 100644 index 0000000000..12bd17d283 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_gst.c @@ -0,0 +1,108 @@ +/* + * gstvaapiutils_gst.c - GST utilties + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * 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 "config.h" +#include "gstvaapiutils_gst.h" +#include "gstvaapivideosink.h" +#include "gstvaapivideobuffer.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +static GstVaapiDisplay * +lookup_through_vaapisink_iface(GstElement *element) +{ + GstVaapiDisplay *display; + GstVaapiVideoSink *sink; + + GST_DEBUG("looking for a downstream vaapisink"); + + /* Look for a downstream vaapisink */ + sink = gst_vaapi_video_sink_lookup(element); + if (!sink) + return NULL; + + display = gst_vaapi_video_sink_get_display(sink); + GST_DEBUG(" found display %p", display); + return display; +} + +static GstVaapiDisplay * +lookup_through_peer_buffer(GstElement *element) +{ + GstVaapiDisplay *display; + GstPad *pad; + GstBuffer *buffer; + GstFlowReturn ret; + + GST_DEBUG("looking for a GstVaapiVideoBuffer from peer"); + + /* Lookup for a GstVaapiVideoBuffer from peer */ + pad = gst_element_get_static_pad(element, "src"); + if (!pad) + return NULL; + + buffer = NULL; + ret = gst_pad_alloc_buffer(pad, 0, 0, GST_PAD_CAPS(pad), &buffer); + g_object_unref(pad); + if (ret != GST_FLOW_OK || !buffer) + return NULL; + + display = GST_VAAPI_IS_VIDEO_BUFFER(buffer) ? + gst_vaapi_video_buffer_get_display(GST_VAAPI_VIDEO_BUFFER(buffer)) : + NULL; + gst_buffer_unref(buffer); + + GST_DEBUG(" found display %p", display); + return display; +} + +/** + * gst_vaapi_display_lookup_downstream: + * @element: a #GstElement + * + * Finds a suitable #GstVaapiDisplay downstream from @element. + * + * 1. Check whether a downstream element implements the + * #GstVaapiVideoSinkInterface interface. + * + * 2. Check whether the @element peer implements a custom + * buffer_alloc() function that allocates #GstVaapiVideoBuffer + * buffers. + * + * Return value: a downstream allocated #GstVaapiDisplay object, or + * %NULL if none was found + */ +GstVaapiDisplay * +gst_vaapi_display_lookup_downstream(GstElement *element) +{ + GstVaapiDisplay *display; + + display = lookup_through_vaapisink_iface(element); + if (display) + return display; + + display = lookup_through_peer_buffer(element); + if (display) + return display; + + return NULL; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_gst.h b/gst-libs/gst/vaapi/gstvaapiutils_gst.h new file mode 100644 index 0000000000..86eaad01a5 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_gst.h @@ -0,0 +1,31 @@ +/* + * gstvaapiutils_gst.h - GST utilties + * + * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * + * 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_UTILS_GST_H +#define GST_VAAPI_UTILS_GST_H + +#include +#include + +GstVaapiDisplay * +gst_vaapi_display_lookup_downstream(GstElement *element); + +#endif /* GST_VAAPI_UTILS_GST_H */ From 909d1f96a333a6cec7829670d2245395f956d34d Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 08:00:09 +0000 Subject: [PATCH 0356/3781] Raise VA-API plugins ranks. --- gst/vaapiconvert/gstvaapiconvert.c | 2 +- gst/vaapidecode/gstvaapidecode.c | 2 +- gst/vaapisink/gstvaapisink.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index 9bb52ea4fd..1ccfae9f15 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -672,7 +672,7 @@ static gboolean plugin_init(GstPlugin *plugin) return gst_element_register(plugin, GST_PLUGIN_NAME, - GST_RANK_NONE, + GST_RANK_SECONDARY, GST_TYPE_VAAPICONVERT); } diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 3d8ccc99a2..4fcbbe051f 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -458,7 +458,7 @@ static gboolean plugin_init(GstPlugin *plugin) return gst_element_register(plugin, GST_PLUGIN_NAME, - GST_RANK_NONE, + GST_RANK_PRIMARY, GST_TYPE_VAAPIDECODE); } diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 8384153595..7c4ecfb130 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -684,7 +684,7 @@ static gboolean plugin_init(GstPlugin *plugin) return gst_element_register(plugin, GST_PLUGIN_NAME, - GST_RANK_NONE, + GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); } From 159f42ca7fb458acda0b61008672ae4cfcb69e77 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 08:02:19 +0000 Subject: [PATCH 0357/3781] Exclude gstvaapiutils_gst.h from docs for now. --- docs/reference/libs/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index e8b5369f15..745a932415 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -70,6 +70,7 @@ IGNORE_HFILES = \ gstvaapiobject_priv.h \ gstvaapiutils.h \ gstvaapiutils_glx.h \ + gstvaapiutils_gst.h \ gstvaapiutils_x11.h \ $(NULL) From 2d90a2dd3a4713c5e49bdafbcc11c64333e00b14 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 08:02:45 +0000 Subject: [PATCH 0358/3781] Fix integration within the playbin2 pipeline. --- NEWS | 5 ++++- README | 1 - gst/vaapidecode/gstvaapidecode.c | 24 ++++++------------------ 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/NEWS b/NEWS index 0219c2fbea..07c7042078 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2010-05-05 +gst-vaapi NEWS -- summary of changes. 2010-05-DD Copyright (C) 2010 Splitted-Desktop Systems +Version 0.2.1 - DD.May.2010 +* Fix integration within the playbin2 pipeline + Version 0.2.0 - 05.May.2010 * Relicense gst-libs/ code to LGPL v2.1+ * Add FFmpeg/VAAPI decoder for the new `vaapidecode' element diff --git a/README b/README index e192cc77b9..7f18290715 100644 --- a/README +++ b/README @@ -74,6 +74,5 @@ elements automatically. Caveats ------- - * No automatic integration within the default playbin2 pipeline * No ad-hoc parser, vaapidecoder currently relies on FFmpeg * MPEG-4 Part-2 (DivX) has decoding bugs diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 4fcbbe051f..84ab40c455 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -31,6 +31,7 @@ #include #include #include +#include #define GST_PLUGIN_NAME "vaapidecode" #define GST_PLUGIN_DESC "A VA-API based video decoder" @@ -157,26 +158,13 @@ error_commit_buffer: } } -static gboolean +static inline gboolean gst_vaapidecode_ensure_display(GstVaapiDecode *decode) { - GstVaapiVideoSink *sink; - GstVaapiDisplay *display; - - if (decode->display) - return TRUE; - - /* Look for a downstream vaapisink */ - sink = gst_vaapi_video_sink_lookup(GST_ELEMENT(decode)); - if (!sink) - return FALSE; - - display = gst_vaapi_video_sink_get_display(sink); - if (!display) - return FALSE; - - decode->display = g_object_ref(display); - return TRUE; + if (!decode->display) + decode->display = + gst_vaapi_display_lookup_downstream(GST_ELEMENT(decode)); + return decode->display != NULL; } static gboolean From f53a5781ad677a378eecdd3b1c4a5a78fe55b857 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 08:32:34 +0000 Subject: [PATCH 0359/3781] Initialize decoder earlier. --- gst/vaapidecode/gstvaapidecode.c | 63 ++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 84ab40c455..61e5797323 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -168,38 +168,49 @@ gst_vaapidecode_ensure_display(GstVaapiDecode *decode) } static gboolean -gst_vaapidecode_create(GstVaapiDecode *decode) +gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) { if (!gst_vaapidecode_ensure_display(decode)) return FALSE; if (decode->use_ffmpeg) - decode->decoder = - gst_vaapi_decoder_ffmpeg_new(decode->display, decode->decoder_caps); - return decode->decoder != NULL; + decode->decoder = gst_vaapi_decoder_ffmpeg_new(decode->display, caps); + if (!decode->decoder) + return FALSE; + + decode->decoder_caps = gst_caps_ref(caps); + return TRUE; } static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { - if (decode->decoder_caps) { - gst_caps_unref(decode->decoder_caps); - decode->decoder_caps = NULL; - } - if (decode->decoder) { gst_vaapi_decoder_put_buffer(decode->decoder, NULL); g_object_unref(decode->decoder); decode->decoder = NULL; } - if (decode->display) { - g_object_unref(decode->display); - decode->display = NULL; + if (decode->decoder_caps) { + gst_caps_unref(decode->decoder_caps); + decode->decoder_caps = NULL; } } -static void gst_vaapidecode_base_init(gpointer klass) +static gboolean +gst_vaapidecode_reset(GstVaapiDecode *decode, GstCaps *caps) +{ + if (decode->decoder && + decode->decoder_caps && + gst_caps_is_always_compatible(caps, decode->decoder_caps)) + return TRUE; + + gst_vaapidecode_destroy(decode); + return gst_vaapidecode_create(decode, caps); +} + +static void +gst_vaapidecode_base_init(gpointer klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); @@ -221,7 +232,14 @@ static void gst_vaapidecode_base_init(gpointer klass) static void gst_vaapidecode_finalize(GObject *object) { - gst_vaapidecode_destroy(GST_VAAPIDECODE(object)); + GstVaapiDecode * const decode = GST_VAAPIDECODE(object); + + gst_vaapidecode_destroy(decode); + + if (decode->display) { + g_object_unref(decode->display); + decode->display = NULL; + } G_OBJECT_CLASS(parent_class)->finalize(object); } @@ -328,7 +346,6 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) gboolean success; g_return_val_if_fail(pad == decode->sinkpad, FALSE); - decode->decoder_caps = gst_caps_ref(caps); other_caps = gst_caps_from_string(gst_vaapidecode_src_caps_str); if (!other_caps) @@ -351,7 +368,10 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) success = gst_pad_set_caps(decode->srcpad, other_caps); gst_caps_unref(other_caps); - return success; + if (!success) + return FALSE; + + return gst_vaapidecode_reset(decode, caps); } static GstFlowReturn @@ -359,11 +379,6 @@ gst_vaapidecode_chain(GstPad *pad, GstBuffer *buf) { GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); - if (!decode->decoder) { - if (!gst_vaapidecode_create(decode)) - goto error_create_decoder; - } - if (!gst_vaapi_decoder_put_buffer(decode->decoder, buf)) goto error_push_buffer; @@ -371,12 +386,6 @@ gst_vaapidecode_chain(GstPad *pad, GstBuffer *buf) return gst_vaapidecode_step(decode); /* ERRORS */ -error_create_decoder: - { - GST_DEBUG("failed to create decoder"); - gst_buffer_unref(buf); - return GST_FLOW_UNEXPECTED; - } error_push_buffer: { GST_DEBUG("failed to push input buffer to decoder"); From 6258c468f94456d55fd900bcf20e3950978dfe7b Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 09:22:49 +0000 Subject: [PATCH 0360/3781] Fix vaapidecode to expose the HW supported caps only. --- NEWS | 1 + gst/vaapidecode/Makefile.am | 2 +- gst/vaapidecode/gstvaapidecode.c | 89 ++++++++++++++++++++++++++++++++ gst/vaapidecode/gstvaapidecode.h | 1 + 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 07c7042078..b0bd819706 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Copyright (C) 2010 Splitted-Desktop Systems Version 0.2.1 - DD.May.2010 * Fix integration within the playbin2 pipeline +* Fix vaapidecode to expose the HW supported caps only Version 0.2.0 - 05.May.2010 * Relicense gst-libs/ code to LGPL v2.1+ diff --git a/gst/vaapidecode/Makefile.am b/gst/vaapidecode/Makefile.am index b1fd20d5e2..f537e6e1f3 100644 --- a/gst/vaapidecode/Makefile.am +++ b/gst/vaapidecode/Makefile.am @@ -4,7 +4,7 @@ libgstvaapi_CFLAGS = \ -I$(top_srcdir)/gst-libs libgstvaapi_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la libgstvaapidecode_la_SOURCES = \ gstvaapidecode.c \ diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 61e5797323..130424a1b4 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -28,6 +28,7 @@ #include "config.h" #include "gstvaapidecode.h" +#include #include #include #include @@ -241,6 +242,11 @@ gst_vaapidecode_finalize(GObject *object) decode->display = NULL; } + if (decode->allowed_caps) { + gst_caps_unref(decode->allowed_caps); + decode->allowed_caps = NULL; + } + G_OBJECT_CLASS(parent_class)->finalize(object); } @@ -336,6 +342,87 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) G_PARAM_READWRITE)); } +static gboolean +gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) +{ + GstVaapiDisplay *display; + GstCaps *decode_caps; + guint i, n_decode_caps; + + if (decode->allowed_caps) + return TRUE; + + if (gst_vaapidecode_ensure_display(decode)) + display = g_object_ref(decode->display); + else { + display = gst_vaapi_display_x11_new(NULL); + if (!display) + goto error_no_display; + } + + decode_caps = gst_vaapi_display_get_decode_caps(display); + if (!decode_caps) + goto error_no_decode_caps; + n_decode_caps = gst_caps_get_size(decode_caps); + + decode->allowed_caps = gst_caps_new_empty(); + if (!decode->allowed_caps) + goto error_no_memory; + + for (i = 0; i < n_decode_caps; i++) { + GstStructure *structure; + structure = gst_caps_get_structure(decode_caps, i); + if (!structure) + continue; + structure = gst_structure_copy(structure); + if (!structure) + continue; + gst_structure_remove_field(structure, "profile"); + gst_structure_set( + structure, + "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, + NULL + ); + gst_caps_merge_structure(decode->allowed_caps, structure); + } + + gst_caps_unref(decode_caps); + g_object_unref(display); + return TRUE; + + /* ERRORS */ +error_no_display: + { + GST_DEBUG("failed to retrieve VA display"); + return FALSE; + } +error_no_decode_caps: + { + GST_DEBUG("failed to retrieve VA decode caps"); + g_object_unref(display); + return FALSE; + } +error_no_memory: + { + GST_DEBUG("failed to allocate allowed-caps set"); + gst_caps_unref(decode_caps); + g_object_unref(display); + return FALSE; + } +} + +static GstCaps * +gst_vaapidecode_get_caps(GstPad *pad) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); + + if (!gst_vaapidecode_ensure_allowed_caps(decode)) + return gst_caps_new_empty(); + + return gst_caps_ref(decode->allowed_caps); +} + static gboolean gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) { @@ -424,6 +511,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) decode->display = NULL; decode->decoder = NULL; decode->decoder_caps = NULL; + decode->allowed_caps = NULL; decode->use_ffmpeg = TRUE; /* Pad through which data comes in to the element */ @@ -432,6 +520,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) "sink" ); + gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps); gst_pad_set_setcaps_function(decode->sinkpad, gst_vaapidecode_set_caps); gst_pad_set_chain_function(decode->sinkpad, gst_vaapidecode_chain); gst_pad_set_event_function(decode->sinkpad, gst_vaapidecode_sink_event); diff --git a/gst/vaapidecode/gstvaapidecode.h b/gst/vaapidecode/gstvaapidecode.h index 068f198ca7..8791bd961f 100644 --- a/gst/vaapidecode/gstvaapidecode.h +++ b/gst/vaapidecode/gstvaapidecode.h @@ -64,6 +64,7 @@ struct _GstVaapiDecode { GstVaapiDisplay *display; GstVaapiDecoder *decoder; GstCaps *decoder_caps; + GstCaps *allowed_caps; unsigned int use_ffmpeg : 1; }; From 35cd2b1ffe1c78f0db24fe9e2e9d9c80ebadc7a2 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 09:34:37 +0000 Subject: [PATCH 0361/3781] Cosmetics. --- gst/vaapiconvert/gstvaapiconvert.c | 21 ++++++++++++++------- gst/vaapidecode/gstvaapidecode.c | 5 +++-- gst/vaapisink/gstvaapisink.c | 18 ++++++++++++------ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index 1ccfae9f15..f10bafdcfc 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -49,7 +49,7 @@ static const GstElementDetails gst_vaapiconvert_details = /* Default templates */ static const char gst_vaapiconvert_yuv_caps_str[] = "video/x-raw-yuv, " - "width = (int) [ 1, MAX ], " + "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]; "; static const char gst_vaapiconvert_vaapi_caps_str[] = @@ -83,8 +83,11 @@ enum { PROP_DIRECT_RENDERING, }; -static gboolean gst_vaapiconvert_start(GstBaseTransform *trans); -static gboolean gst_vaapiconvert_stop(GstBaseTransform *trans); +static gboolean +gst_vaapiconvert_start(GstBaseTransform *trans); + +static gboolean +gst_vaapiconvert_stop(GstBaseTransform *trans); static GstFlowReturn gst_vaapiconvert_transform( @@ -151,7 +154,8 @@ gst_vaapiconvert_destroy(GstVaapiConvert *convert) } } -static void gst_vaapiconvert_base_init(gpointer klass) +static void +gst_vaapiconvert_base_init(gpointer klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); @@ -291,7 +295,8 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) g_object_unref(sinkpad); } -static gboolean gst_vaapiconvert_start(GstBaseTransform *trans) +static gboolean +gst_vaapiconvert_start(GstBaseTransform *trans) { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); GstVaapiVideoSink *sink; @@ -310,7 +315,8 @@ static gboolean gst_vaapiconvert_start(GstBaseTransform *trans) return TRUE; } -static gboolean gst_vaapiconvert_stop(GstBaseTransform *trans) +static gboolean +gst_vaapiconvert_stop(GstBaseTransform *trans) { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); @@ -665,7 +671,8 @@ gst_vaapiconvert_prepare_output_buffer( return GST_FLOW_OK; } -static gboolean plugin_init(GstPlugin *plugin) +static gboolean +plugin_init(GstPlugin *plugin) { GST_DEBUG_CATEGORY_INIT(gst_debug_vaapiconvert, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 130424a1b4..5d1f2be684 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -51,7 +51,7 @@ static const GstElementDetails gst_vaapidecode_details = /* Default templates */ #define GST_CAPS_CODEC(CODEC) \ CODEC ", " \ - "width = (int) [ 1, MAX ], " \ + "width = (int) [ 1, MAX ], " \ "height = (int) [ 1, MAX ]; " static const char gst_vaapidecode_sink_caps_str[] = @@ -537,7 +537,8 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) gst_element_add_pad(GST_ELEMENT(decode), decode->srcpad); } -static gboolean plugin_init(GstPlugin *plugin) +static gboolean +plugin_init(GstPlugin *plugin) { GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 7c4ecfb130..baa2e71e03 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -90,12 +90,14 @@ gst_vaapi_video_sink_do_get_display(GstVaapiVideoSink *sink) return gst_vaapisink_get_display(GST_VAAPISINK(sink)); } -static void gst_vaapi_video_sink_iface_init(GstVaapiVideoSinkInterface *iface) +static void +gst_vaapi_video_sink_iface_init(GstVaapiVideoSinkInterface *iface) { iface->get_display = gst_vaapi_video_sink_do_get_display; } -static void gst_vaapisink_iface_init(GType type) +static void +gst_vaapisink_iface_init(GType type) { const GType g_define_type_id = type; @@ -571,7 +573,8 @@ gst_vaapisink_get_property( } } -static void gst_vaapisink_base_init(gpointer klass) +static void +gst_vaapisink_base_init(gpointer klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); @@ -583,7 +586,8 @@ static void gst_vaapisink_base_init(gpointer klass) ); } -static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) +static void +gst_vaapisink_class_init(GstVaapiSinkClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass); @@ -653,7 +657,8 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) G_PARAM_READWRITE)); } -static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) +static void +gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) { sink->display_name = NULL; sink->display = NULL; @@ -677,7 +682,8 @@ gst_vaapisink_get_display(GstVaapiSink *sink) return sink->display; } -static gboolean plugin_init(GstPlugin *plugin) +static gboolean +plugin_init(GstPlugin *plugin) { GST_DEBUG_CATEGORY_INIT(gst_debug_vaapisink, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); From 2531b21a72fb9a7052c1cd468aedb27fcecf7191 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 10:51:21 +0000 Subject: [PATCH 0362/3781] Update deps to match configure.ac versions. --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 7f18290715..7a333c9d51 100644 --- a/README +++ b/README @@ -46,7 +46,7 @@ Requirements Software requirements * libgstreamer0.10-dev >= 0.10.0 - * libgstreamer-plugins-base0.10-dev >= 0.10.0 + * libgstreamer-plugins-base0.10-dev >= 0.10.16 * libva-dev >= 0.31.0-1+sds9 (VA/GLX) * libavcodec-dev >= 0.6 or with From 601db12ccb7f4db390e350719b4df44b367c318a Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 11:43:50 +0000 Subject: [PATCH 0363/3781] Add GstXOverlay interface to vaapisink (e.g. for Totem). --- NEWS | 1 + configure.ac | 7 +++ gst/vaapisink/Makefile.am | 2 + gst/vaapisink/gstvaapisink.c | 100 +++++++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+) diff --git a/NEWS b/NEWS index b0bd819706..fbc056985d 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ Copyright (C) 2010 Splitted-Desktop Systems Version 0.2.1 - DD.May.2010 * Fix integration within the playbin2 pipeline * Fix vaapidecode to expose the HW supported caps only +* Add GstXOverlay interface to vaapisink (e.g. for Totem) Version 0.2.0 - 05.May.2010 * Relicense gst-libs/ code to LGPL v2.1+ diff --git a/configure.ac b/configure.ac index 0a8b92ed71..5dc886486c 100644 --- a/configure.ac +++ b/configure.ac @@ -154,6 +154,13 @@ PKG_CHECK_MODULES([GST_VIDEO], AC_SUBST(GST_VIDEO_CFLAGS) AC_SUBST(GST_VIDEO_LIBS) +dnl Check for GStreamer interfaces +PKG_CHECK_MODULES([GST_INTERFACES], + [gstreamer-interfaces-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED] +) +AC_SUBST(GST_INTERFACES_CFLAGS) +AC_SUBST(GST_INTERFACES_LIBS) + dnl GST_ALL_LDFLAGS: dnl LDFLAGS really should only contain flags, not libs - they get added before dnl whatevertarget_LIBS and -L flags here affect the rest of the linking diff --git a/gst/vaapisink/Makefile.am b/gst/vaapisink/Makefile.am index c1298b9555..81ed421b9c 100644 --- a/gst/vaapisink/Makefile.am +++ b/gst/vaapisink/Makefile.am @@ -23,12 +23,14 @@ libgstvaapisink_la_CFLAGS = \ $(libgstvaapi_CFLAGS) \ $(GST_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ + $(GST_INTERFACES_CFLAGS) \ $(GST_PLUGINS_BASE_CFLAGS) libgstvaapisink_la_LIBADD = \ $(libgstvaapi_LIBS) \ $(GST_LIBS) \ $(GST_VIDEO_LIBS) \ + $(GST_INTERFACES_LIBS) \ $(GST_PLUGINS_BASE_LIBS) libgstvaapisink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index baa2e71e03..91dfd9e74c 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -40,6 +40,9 @@ #endif #include "gstvaapisink.h" +/* Supported interfaces */ +#include + #define GST_PLUGIN_NAME "vaapisink" #define GST_PLUGIN_DESC "A VA-API based videosink" @@ -81,6 +84,26 @@ enum { PROP_USE_REFLECTION }; +/* GstImplementsInterface interface */ + +static gboolean +gst_vaapisink_implements_interface_supported( + GstImplementsInterface *iface, + GType type +) +{ + return (type == GST_VAAPI_TYPE_VIDEO_SINK || + type == GST_TYPE_X_OVERLAY); +} + +static void +gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface) +{ + iface->supported = gst_vaapisink_implements_interface_supported; +} + +/* GstVaapiVideoSink interface */ + static GstVaapiDisplay * gst_vaapisink_get_display(GstVaapiSink *sink); @@ -96,13 +119,75 @@ gst_vaapi_video_sink_iface_init(GstVaapiVideoSinkInterface *iface) iface->get_display = gst_vaapi_video_sink_do_get_display; } +/* GstXOverlay interface */ + +static GstFlowReturn +gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); + +static void +gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) +{ + GstVaapiSink * const sink = GST_VAAPISINK(overlay); + XWindowAttributes wattr; + + if (sink->window && + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) == xid) + return; + + gst_vaapi_display_lock(sink->display); + XGetWindowAttributes( + gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)), + xid, + &wattr + ); + gst_vaapi_display_unlock(sink->display); + sink->window_width = wattr.width; + sink->window_height = wattr.height; + + if (sink->window) { + g_object_unref(sink->window); + sink->window = NULL; + } + +#if USE_VAAPISINK_GLX + if (sink->use_glx) + sink->window = gst_vaapi_window_glx_new_with_xid(sink->display, xid); + else +#endif + sink->window = gst_vaapi_window_x11_new_with_xid(sink->display, xid); +} + +static void +gst_vaapisink_xoverlay_expose(GstXOverlay *overlay) +{ + GstBaseSink * const base_sink = GST_BASE_SINK(overlay); + GstBuffer *buffer; + + buffer = gst_base_sink_get_last_buffer(base_sink); + if (buffer) { + gst_vaapisink_show_frame(base_sink, buffer); + gst_buffer_unref(buffer); + } +} + +static void +gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface) +{ + iface->set_xwindow_id = gst_vaapisink_xoverlay_set_xid; + iface->expose = gst_vaapisink_xoverlay_expose; +} + static void gst_vaapisink_iface_init(GType type) { const GType g_define_type_id = type; + G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, + gst_vaapisink_implements_iface_init); G_IMPLEMENT_INTERFACE(GST_VAAPI_TYPE_VIDEO_SINK, gst_vaapi_video_sink_iface_init); + G_IMPLEMENT_INTERFACE(GST_TYPE_X_OVERLAY, + gst_vaapisink_xoverlay_iface_init); } static void @@ -131,6 +216,11 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) else #endif sink->window = gst_vaapi_window_x11_new(display, width, height); + if (sink->window) + gst_x_overlay_got_xwindow_id( + GST_X_OVERLAY(sink), + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) + ); } return sink->window != NULL; } @@ -246,6 +336,16 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) } GST_DEBUG("window size %ux%u", win_width, win_height); + if (!sink->window) { + gst_vaapi_display_lock(sink->display); + gst_x_overlay_prepare_xwindow_id(GST_X_OVERLAY(sink)); + gst_vaapi_display_unlock(sink->display); + if (sink->window) { + win_width = sink->window_width; + win_height = sink->window_height; + } + } + if (sink->fullscreen) { disp_rect->x = (display_width - win_width) / 2; disp_rect->y = (display_height - win_height) / 2; From 99b1adce4f8d4d63517370071c437206e2a4dacc Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 12:58:53 +0000 Subject: [PATCH 0364/3781] Fix render rect when the foreign window size changes. --- gst/vaapisink/gstvaapisink.c | 173 ++++++++++++++++++++--------------- gst/vaapisink/gstvaapisink.h | 2 + 2 files changed, 102 insertions(+), 73 deletions(-) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 91dfd9e74c..28afff00d1 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -124,16 +124,15 @@ gst_vaapi_video_sink_iface_init(GstVaapiVideoSinkInterface *iface) static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); +static gboolean +update_display_rect(GstVaapiSink *sink, guint display_width, guint display_height); + static void gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); XWindowAttributes wattr; - if (sink->window && - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) == xid) - return; - gst_vaapi_display_lock(sink->display); XGetWindowAttributes( gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)), @@ -141,8 +140,17 @@ gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) &wattr ); gst_vaapi_display_unlock(sink->display); - sink->window_width = wattr.width; - sink->window_height = wattr.height; + + if (wattr.width != sink->window_width || + wattr.height != sink->window_height) { + update_display_rect(sink, wattr.width, wattr.height); + sink->window_width = wattr.width; + sink->window_height = wattr.height; + } + + if (sink->window && + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) == xid) + return; if (sink->window) { g_object_unref(sink->window); @@ -269,17 +277,83 @@ gst_vaapisink_stop(GstBaseSink *base_sink) return TRUE; } +static gboolean +update_display_rect(GstVaapiSink *sink, guint display_width, guint display_height) +{ + GstVaapiRectangle * const display_rect = &sink->display_rect; + guint num, den, display_par_n, display_par_d; + double display_ratio; + gboolean success; + + gst_vaapi_display_get_pixel_aspect_ratio( + sink->display, + &display_par_n, &display_par_d + ); + + success = gst_video_calculate_display_ratio( + &num, &den, + sink->video_width, sink->video_height, + sink->video_par_n, sink->video_par_d, + display_par_n, display_par_d + ); + if (!success) + return FALSE; + GST_DEBUG("video size %dx%d, calculated display ratio %d/%d", + sink->video_width, sink->video_height, num, den); + + if ((sink->video_height % den) == 0) { + GST_DEBUG("keeping video height"); + display_rect->width = + gst_util_uint64_scale_int(sink->video_height, num, den); + display_rect->height = sink->video_height; + } + else if ((sink->video_width % num) == 0) { + GST_DEBUG("keeping video width"); + display_rect->width = sink->video_width; + display_rect->height = + gst_util_uint64_scale_int(sink->video_width, den, num); + } + else { + GST_DEBUG("approximating while keeping video height"); + display_rect->width = + gst_util_uint64_scale_int(sink->video_height, num, den); + display_rect->height = sink->video_height; + } + display_ratio = (gdouble)display_rect->width / display_rect->height; + GST_DEBUG("scaling to %ux%u", display_rect->width, display_rect->height); + + if (sink->fullscreen || + display_rect->width > display_width || + display_rect->height > display_height) { + if (sink->video_width > sink->video_height) { + display_rect->width = display_width; + display_rect->height = display_width / display_ratio; + } + else { + display_rect->width = display_height * display_ratio; + display_rect->height = display_height; + } + } + GST_DEBUG("display size %ux%u", display_rect->width, display_rect->height); + + if (sink->fullscreen) { + display_rect->x = (display_width - display_rect->width) / 2; + display_rect->y = (display_height - display_rect->height) / 2; + } + else { + display_rect->x = 0; + display_rect->y = 0; + } + return TRUE; +} + static gboolean gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstStructure * const structure = gst_caps_get_structure(caps, 0); - GstVaapiRectangle * const disp_rect = &sink->display_rect; - guint num, den; - guint win_width, win_height; - guint display_width, display_height, display_par_n, display_par_d; + guint display_width, display_height, win_width, win_height; gint video_width, video_height, video_par_n = 1, video_par_d = 1; - gdouble win_ratio; if (!structure) return FALSE; @@ -291,79 +365,30 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) sink->video_height = video_height; gst_video_parse_caps_pixel_aspect_ratio(caps, &video_par_n, &video_par_d); + sink->video_par_n = video_par_n; + sink->video_par_d = video_par_d; + gst_vaapi_display_get_size(sink->display, &display_width, &display_height); - gst_vaapi_display_get_pixel_aspect_ratio( - sink->display, - &display_par_n, &display_par_d - ); - - if (!gst_video_calculate_display_ratio(&num, &den, - video_width, video_height, - video_par_n, video_par_d, - display_par_n, display_par_d)) + if (!update_display_rect(sink, display_width, display_height)) return FALSE; - GST_DEBUG("video size %dx%d, calculated display ratio %d/%d", - video_width, video_height, num, den); - - if ((video_height % den) == 0) { - GST_DEBUG("keeping video height"); - win_width = gst_util_uint64_scale_int(video_height, num, den); - win_height = video_height; - } - else if ((video_width % num) == 0) { - GST_DEBUG("keeping video width"); - win_width = video_width; - win_height = gst_util_uint64_scale_int(video_width, den, num); - } - else { - GST_DEBUG("approximating while keeping video height"); - win_width = gst_util_uint64_scale_int (video_height, num, den); - win_height = video_height; - } - win_ratio = (gdouble)win_width / win_height; - GST_DEBUG("scaling to %ux%u", win_width, win_height); - - if (sink->fullscreen || - win_width > display_width || win_height > display_height) { - if (video_width > video_height) { - win_width = display_width; - win_height = display_width / win_ratio; - } - else { - win_width = display_height * win_ratio; - win_height = display_height; - } - } - GST_DEBUG("window size %ux%u", win_width, win_height); - - if (!sink->window) { - gst_vaapi_display_lock(sink->display); - gst_x_overlay_prepare_xwindow_id(GST_X_OVERLAY(sink)); - gst_vaapi_display_unlock(sink->display); - if (sink->window) { - win_width = sink->window_width; - win_height = sink->window_height; - } - } if (sink->fullscreen) { - disp_rect->x = (display_width - win_width) / 2; - disp_rect->y = (display_height - win_height) / 2; + win_width = display_width; + win_height = display_height; } else { - disp_rect->x = 0; - disp_rect->y = 0; + win_width = sink->display_rect.width; + win_height = sink->display_rect.height; } - disp_rect->width = win_width; - disp_rect->height = win_height; if (sink->window) gst_vaapi_window_set_size(sink->window, win_width, win_height); else { - if (sink->fullscreen) { - win_width = display_width; - win_height = display_height; - } + gst_vaapi_display_lock(sink->display); + gst_x_overlay_prepare_xwindow_id(GST_X_OVERLAY(sink)); + gst_vaapi_display_unlock(sink->display); + if (sink->window) + return TRUE; if (!gst_vaapisink_ensure_window(sink, win_width, win_height)) return FALSE; gst_vaapi_window_set_fullscreen(sink->window, sink->fullscreen); @@ -768,6 +793,8 @@ gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) sink->texture = NULL; sink->video_width = 0; sink->video_height = 0; + sink->video_par_n = 1; + sink->video_par_d = 1; sink->fullscreen = FALSE; sink->synchronous = FALSE; sink->use_glx = USE_VAAPISINK_GLX; diff --git a/gst/vaapisink/gstvaapisink.h b/gst/vaapisink/gstvaapisink.h index c7ceae43d9..848c148de1 100644 --- a/gst/vaapisink/gstvaapisink.h +++ b/gst/vaapisink/gstvaapisink.h @@ -74,6 +74,8 @@ struct _GstVaapiSink { GstVaapiTexture *texture; guint video_width; guint video_height; + gint video_par_n; + gint video_par_d; GstVaapiRectangle display_rect; guint fullscreen : 1; guint synchronous : 1; From 91c4c2c6b550c4f4e802e880444b1c70a26f6f14 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 14:10:38 +0000 Subject: [PATCH 0365/3781] Fix comment. --- gst-libs/gst/vaapi/gstvaapiutils_gst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_gst.c b/gst-libs/gst/vaapi/gstvaapiutils_gst.c index 12bd17d283..f0b29fb0fb 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_gst.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_gst.c @@ -55,7 +55,7 @@ lookup_through_peer_buffer(GstElement *element) GST_DEBUG("looking for a GstVaapiVideoBuffer from peer"); - /* Lookup for a GstVaapiVideoBuffer from peer */ + /* Look for a GstVaapiVideoBuffer from peer */ pad = gst_element_get_static_pad(element, "src"); if (!pad) return NULL; From 76661d73d1b16f8e9f09200d72b57a24a6541965 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 19:14:35 +0000 Subject: [PATCH 0366/3781] Fix GstVaapiDisplay refcounting in vaapidecode. --- gst/vaapidecode/gstvaapidecode.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 5d1f2be684..d20d8b57b9 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -162,10 +162,15 @@ error_commit_buffer: static inline gboolean gst_vaapidecode_ensure_display(GstVaapiDecode *decode) { - if (!decode->display) - decode->display = - gst_vaapi_display_lookup_downstream(GST_ELEMENT(decode)); - return decode->display != NULL; + GstVaapiDisplay *display; + + if (!decode->display) { + display = gst_vaapi_display_lookup_downstream(GST_ELEMENT(decode)); + if (!display) + return FALSE; + decode->display = g_object_ref(display); + } + return TRUE; } static gboolean From 1eb927ba5bd63ab3c94bf903e89041dedc4fccfe Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 19:14:59 +0000 Subject: [PATCH 0367/3781] 0.2.1. --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index fbc056985d..a995e1c610 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ -gst-vaapi NEWS -- summary of changes. 2010-05-DD +gst-vaapi NEWS -- summary of changes. 2010-05-12 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.2.1 - DD.May.2010 +Version 0.2.1 - 12.May.2010 * Fix integration within the playbin2 pipeline * Fix vaapidecode to expose the HW supported caps only * Add GstXOverlay interface to vaapisink (e.g. for Totem) From 73df3d41b9d24aa4b1521c7a7f25f7bddcecf3ca Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 19:18:04 +0000 Subject: [PATCH 0368/3781] Drop obsolete comment. --- README | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README b/README index 7a333c9d51..8da45ff4f7 100644 --- a/README +++ b/README @@ -62,10 +62,6 @@ Hardware requirements Usage ----- -The GStreamer pipeline currently has to be built manually. -i.e. neither decodebin{,2} nor playbin{,2} would select the VA-API -elements automatically. - * Play an H.264 video with an MP4 container in fullscreen mode $ gst-launch-0.10 -v filesrc location=/path/to/video.mp4 ! \ qtdemux ! vaapidecode ! vaapisink fullscreen=true From d16dda6b61c84f86d31ba84eb7719f21a0a83413 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 19:35:45 +0000 Subject: [PATCH 0369/3781] Ensure VA display is created prior to initializing the window from a specific XID. Also move code down. --- gst/vaapisink/gstvaapisink.c | 102 ++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 44 deletions(-) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 28afff00d1..04e224b8df 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -121,6 +121,9 @@ gst_vaapi_video_sink_iface_init(GstVaapiVideoSinkInterface *iface) /* GstXOverlay interface */ +static gboolean +gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, XID xid); + static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); @@ -131,38 +134,8 @@ static void gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); - XWindowAttributes wattr; - gst_vaapi_display_lock(sink->display); - XGetWindowAttributes( - gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)), - xid, - &wattr - ); - gst_vaapi_display_unlock(sink->display); - - if (wattr.width != sink->window_width || - wattr.height != sink->window_height) { - update_display_rect(sink, wattr.width, wattr.height); - sink->window_width = wattr.width; - sink->window_height = wattr.height; - } - - if (sink->window && - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) == xid) - return; - - if (sink->window) { - g_object_unref(sink->window); - sink->window = NULL; - } - -#if USE_VAAPISINK_GLX - if (sink->use_glx) - sink->window = gst_vaapi_window_glx_new_with_xid(sink->display, xid); - else -#endif - sink->window = gst_vaapi_window_x11_new_with_xid(sink->display, xid); + gst_vaapisink_ensure_window_xid(sink, xid); } static void @@ -212,6 +185,23 @@ gst_vaapisink_destroy(GstVaapiSink *sink) } } +static inline gboolean +gst_vaapisink_ensure_display(GstVaapiSink *sink) +{ + if (!sink->display) { +#if USE_VAAPISINK_GLX + if (sink->use_glx) + sink->display = gst_vaapi_display_glx_new(sink->display_name); + else +#endif + sink->display = gst_vaapi_display_x11_new(sink->display_name); + if (!sink->display || !gst_vaapi_display_get_display(sink->display)) + return FALSE; + g_object_set(sink, "synchronous", sink->synchronous, NULL); + } + return sink->display != NULL; +} + static inline gboolean gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) { @@ -233,21 +223,45 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) return sink->window != NULL; } -static inline gboolean -gst_vaapisink_ensure_display(GstVaapiSink *sink) +static gboolean +gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, XID xid) { - if (!sink->display) { -#if USE_VAAPISINK_GLX - if (sink->use_glx) - sink->display = gst_vaapi_display_glx_new(sink->display_name); - else -#endif - sink->display = gst_vaapi_display_x11_new(sink->display_name); - if (!sink->display || !gst_vaapi_display_get_display(sink->display)) - return FALSE; - g_object_set(sink, "synchronous", sink->synchronous, NULL); + XWindowAttributes wattr; + + if (!gst_vaapisink_ensure_display(sink)) + return FALSE; + + gst_vaapi_display_lock(sink->display); + XGetWindowAttributes( + gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)), + xid, + &wattr + ); + gst_vaapi_display_unlock(sink->display); + + if (wattr.width != sink->window_width || + wattr.height != sink->window_height) { + update_display_rect(sink, wattr.width, wattr.height); + sink->window_width = wattr.width; + sink->window_height = wattr.height; } - return sink->display != NULL; + + if (sink->window && + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) == xid) + return TRUE; + + if (sink->window) { + g_object_unref(sink->window); + sink->window = NULL; + } + +#if USE_VAAPISINK_GLX + if (sink->use_glx) + sink->window = gst_vaapi_window_glx_new_with_xid(sink->display, xid); + else +#endif + sink->window = gst_vaapi_window_x11_new_with_xid(sink->display, xid); + return sink->window != NULL; } static gboolean From b3dc91b1d9c47fd8ea7e48506d6e8c6b184180e3 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 12 May 2010 19:40:30 +0000 Subject: [PATCH 0370/3781] Move code around. --- gst/vaapisink/gstvaapisink.c | 147 +++++++++++++++++------------------ 1 file changed, 72 insertions(+), 75 deletions(-) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 04e224b8df..039bfa9794 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -127,9 +127,6 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, XID xid); static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); -static gboolean -update_display_rect(GstVaapiSink *sink, guint display_width, guint display_height); - static void gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) { @@ -202,6 +199,75 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink) return sink->display != NULL; } +static gboolean +gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) +{ + GstVaapiRectangle * const display_rect = &sink->display_rect; + guint num, den, display_par_n, display_par_d; + double display_ratio; + gboolean success; + + gst_vaapi_display_get_pixel_aspect_ratio( + sink->display, + &display_par_n, &display_par_d + ); + + success = gst_video_calculate_display_ratio( + &num, &den, + sink->video_width, sink->video_height, + sink->video_par_n, sink->video_par_d, + display_par_n, display_par_d + ); + if (!success) + return FALSE; + GST_DEBUG("video size %dx%d, calculated display ratio %d/%d", + sink->video_width, sink->video_height, num, den); + + if ((sink->video_height % den) == 0) { + GST_DEBUG("keeping video height"); + display_rect->width = + gst_util_uint64_scale_int(sink->video_height, num, den); + display_rect->height = sink->video_height; + } + else if ((sink->video_width % num) == 0) { + GST_DEBUG("keeping video width"); + display_rect->width = sink->video_width; + display_rect->height = + gst_util_uint64_scale_int(sink->video_width, den, num); + } + else { + GST_DEBUG("approximating while keeping video height"); + display_rect->width = + gst_util_uint64_scale_int(sink->video_height, num, den); + display_rect->height = sink->video_height; + } + display_ratio = (gdouble)display_rect->width / display_rect->height; + GST_DEBUG("scaling to %ux%u", display_rect->width, display_rect->height); + + if (sink->fullscreen || + display_rect->width > width || display_rect->height > height) { + if (sink->video_width > sink->video_height) { + display_rect->width = width; + display_rect->height = width / display_ratio; + } + else { + display_rect->width = height * display_ratio; + display_rect->height = height; + } + } + GST_DEBUG("display size %ux%u", display_rect->width, display_rect->height); + + if (sink->fullscreen) { + display_rect->x = (width - display_rect->width) / 2; + display_rect->y = (height - display_rect->height) / 2; + } + else { + display_rect->x = 0; + display_rect->y = 0; + } + return TRUE; +} + static inline gboolean gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) { @@ -241,7 +307,8 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, XID xid) if (wattr.width != sink->window_width || wattr.height != sink->window_height) { - update_display_rect(sink, wattr.width, wattr.height); + if (!gst_vaapisink_ensure_render_rect(sink, wattr.width, wattr.height)) + return FALSE; sink->window_width = wattr.width; sink->window_height = wattr.height; } @@ -291,76 +358,6 @@ gst_vaapisink_stop(GstBaseSink *base_sink) return TRUE; } -static gboolean -update_display_rect(GstVaapiSink *sink, guint display_width, guint display_height) -{ - GstVaapiRectangle * const display_rect = &sink->display_rect; - guint num, den, display_par_n, display_par_d; - double display_ratio; - gboolean success; - - gst_vaapi_display_get_pixel_aspect_ratio( - sink->display, - &display_par_n, &display_par_d - ); - - success = gst_video_calculate_display_ratio( - &num, &den, - sink->video_width, sink->video_height, - sink->video_par_n, sink->video_par_d, - display_par_n, display_par_d - ); - if (!success) - return FALSE; - GST_DEBUG("video size %dx%d, calculated display ratio %d/%d", - sink->video_width, sink->video_height, num, den); - - if ((sink->video_height % den) == 0) { - GST_DEBUG("keeping video height"); - display_rect->width = - gst_util_uint64_scale_int(sink->video_height, num, den); - display_rect->height = sink->video_height; - } - else if ((sink->video_width % num) == 0) { - GST_DEBUG("keeping video width"); - display_rect->width = sink->video_width; - display_rect->height = - gst_util_uint64_scale_int(sink->video_width, den, num); - } - else { - GST_DEBUG("approximating while keeping video height"); - display_rect->width = - gst_util_uint64_scale_int(sink->video_height, num, den); - display_rect->height = sink->video_height; - } - display_ratio = (gdouble)display_rect->width / display_rect->height; - GST_DEBUG("scaling to %ux%u", display_rect->width, display_rect->height); - - if (sink->fullscreen || - display_rect->width > display_width || - display_rect->height > display_height) { - if (sink->video_width > sink->video_height) { - display_rect->width = display_width; - display_rect->height = display_width / display_ratio; - } - else { - display_rect->width = display_height * display_ratio; - display_rect->height = display_height; - } - } - GST_DEBUG("display size %ux%u", display_rect->width, display_rect->height); - - if (sink->fullscreen) { - display_rect->x = (display_width - display_rect->width) / 2; - display_rect->y = (display_height - display_rect->height) / 2; - } - else { - display_rect->x = 0; - display_rect->y = 0; - } - return TRUE; -} - static gboolean gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { @@ -383,7 +380,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) sink->video_par_d = video_par_d; gst_vaapi_display_get_size(sink->display, &display_width, &display_height); - if (!update_display_rect(sink, display_width, display_height)) + if (!gst_vaapisink_ensure_render_rect(sink, display_width, display_height)) return FALSE; if (sink->fullscreen) { From 3a7c049829f5f8f9dd56c127463061fa804a7150 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 04:22:31 +0000 Subject: [PATCH 0371/3781] Use XGetGeometry() to retrieve the window size. --- gst/vaapisink/gstvaapisink.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 039bfa9794..4499083845 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -292,25 +292,27 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) static gboolean gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, XID xid) { - XWindowAttributes wattr; + Window rootwin; + unsigned int width, height, border_width, depth; + int x, y; if (!gst_vaapisink_ensure_display(sink)) return FALSE; gst_vaapi_display_lock(sink->display); - XGetWindowAttributes( + XGetGeometry( gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)), xid, - &wattr + &rootwin, + &x, &y, &width, &height, &border_width, &depth ); gst_vaapi_display_unlock(sink->display); - if (wattr.width != sink->window_width || - wattr.height != sink->window_height) { - if (!gst_vaapisink_ensure_render_rect(sink, wattr.width, wattr.height)) + if (width != sink->window_width || height != sink->window_height) { + if (!gst_vaapisink_ensure_render_rect(sink, width, height)) return FALSE; - sink->window_width = wattr.width; - sink->window_height = wattr.height; + sink->window_width = width; + sink->window_height = height; } if (sink->window && From 13e43aa9b6fddce1da4954fc89c867fbc1d82b21 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 04:27:44 +0000 Subject: [PATCH 0372/3781] Debug video & display PARs. --- gst/vaapisink/gstvaapisink.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 4499083845..856acbd3b2 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -211,6 +211,8 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) sink->display, &display_par_n, &display_par_d ); + GST_DEBUG("display pixel-aspect-ratio %d/%d", + display_par_n, display_par_d); success = gst_video_calculate_display_ratio( &num, &den, @@ -220,7 +222,7 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) ); if (!success) return FALSE; - GST_DEBUG("video size %dx%d, calculated display ratio %d/%d", + GST_DEBUG("video size %dx%d, calculated render ratio %d/%d", sink->video_width, sink->video_height, num, den); if ((sink->video_height % den) == 0) { @@ -380,6 +382,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) gst_video_parse_caps_pixel_aspect_ratio(caps, &video_par_n, &video_par_d); sink->video_par_n = video_par_n; sink->video_par_d = video_par_d; + GST_DEBUG("video pixel-aspect-ratio %d/%d", video_par_n, video_par_d); gst_vaapi_display_get_size(sink->display, &display_width, &display_height); if (!gst_vaapisink_ensure_render_rect(sink, display_width, display_height)) From 527e1f03e42bdad2e2366ce848901fcaeb3c5e67 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 04:40:40 +0000 Subject: [PATCH 0373/3781] Respin release. --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index a995e1c610..ce90c24c73 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ -gst-vaapi NEWS -- summary of changes. 2010-05-12 +gst-vaapi NEWS -- summary of changes. 2010-05-13 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.2.1 - 12.May.2010 +Version 0.2.1 - 13.May.2010 * Fix integration within the playbin2 pipeline * Fix vaapidecode to expose the HW supported caps only * Add GstXOverlay interface to vaapisink (e.g. for Totem) From 0e0426582e6b3be905f09bb5d890f7b156ca9c8b Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 06:11:42 +0000 Subject: [PATCH 0374/3781] Fix OpenGL texture internal format (Clutter). --- NEWS | 1 + gst-libs/gst/vaapi/gstvaapiutils_glx.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index ce90c24c73..1b5cb2c1c4 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ gst-vaapi NEWS -- summary of changes. 2010-05-13 Copyright (C) 2010 Splitted-Desktop Systems Version 0.2.1 - 13.May.2010 +* Fix OpenGL texture internal format (Clutter) * Fix integration within the playbin2 pipeline * Fix vaapidecode to expose the HW supported caps only * Add GstXOverlay interface to vaapisink (e.g. for Totem) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index d84edfb857..9d38f9e79c 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -554,10 +554,12 @@ gl_unbind_texture(GLTextureState *ts) GLuint gl_create_texture(GLenum target, GLenum format, guint width, guint height) { + GLenum internal_format; GLuint texture; GLTextureState ts; guint bytes_per_component; + internal_format = format; switch (format) { case GL_LUMINANCE: bytes_per_component = 1; @@ -567,6 +569,7 @@ gl_create_texture(GLenum target, GLenum format, guint width, guint height) break; case GL_RGBA: case GL_BGRA: + internal_format = GL_RGBA; bytes_per_component = 4; break; default: @@ -586,7 +589,7 @@ gl_create_texture(GLenum target, GLenum format, guint width, guint height) glTexImage2D( target, 0, - bytes_per_component, + internal_format, width, height, 0, format, From 10d4d32aa9e5891289cc70d334467b3b25abbe1d Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 06:12:37 +0000 Subject: [PATCH 0375/3781] Cosmetics. --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 1b5cb2c1c4..0c2b0d71f6 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,7 @@ Version 0.2.1 - 13.May.2010 * Fix OpenGL texture internal format (Clutter) * Fix integration within the playbin2 pipeline * Fix vaapidecode to expose the HW supported caps only -* Add GstXOverlay interface to vaapisink (e.g. for Totem) +* Add GstXOverlay interface to vaapisink (Totem media player) Version 0.2.0 - 05.May.2010 * Relicense gst-libs/ code to LGPL v2.1+ From 30b813dcd6b1c3ccf16e60f85a7004ecbf018a33 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 07:19:21 +0000 Subject: [PATCH 0376/3781] Fix packaging deps. --- debian.upstream/control.in | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/debian.upstream/control.in b/debian.upstream/control.in index e463f37cc0..fed84263a2 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -67,7 +67,10 @@ Description: GStreamer libraries from the "vaapi" set Package: libgstvaapi-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, ${misc:Depends} +Depends: ${shlibs:Depends}, ${misc:Depends}, + libgstvaapi@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), + libgstvaapi-x11-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), + libgstvaapi-glx-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}) Description: GStreamer development files for libraries from the "vaapi" set GStreamer/VA-API development files. . From cf3edf434059a31c68466894eab2886ebecb585b Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 07:19:46 +0000 Subject: [PATCH 0377/3781] Nuke older build dir. --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 578a41bd8e..7b35b5828c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,6 +16,7 @@ deb: deb.upstream: dist -mkdir -p $(DEB_BUILDDIR) cd $(DEB_BUILDDIR) && \ + rm -rf $(PACKAGE)-$(VERSION) && \ tar zxvf ../$(PACKAGE)-$(VERSION).tar.gz && \ cd $(PACKAGE)-$(VERSION) && \ $(LN_S) debian.upstream debian && \ From 7f44c87a95d5e1468d77b648cec58a95c2cc1a25 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 09:38:47 +0000 Subject: [PATCH 0378/3781] Add debug info for _show_frame(). --- gst/vaapisink/gstvaapisink.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 856acbd3b2..4d15c1c0fa 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -601,6 +601,9 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) if (!surface) return GST_FLOW_UNEXPECTED; + GST_DEBUG("render surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); + flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; #if USE_VAAPISINK_GLX From c7847dccaf582c9e0db2cb86caa4e96c43b3e55a Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 09:40:52 +0000 Subject: [PATCH 0379/3781] Bump version for development. --- NEWS | 8 ++++++-- configure.ac | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 0c2b0d71f6..9be5f4c6ae 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,12 @@ -gst-vaapi NEWS -- summary of changes. 2010-05-13 +gst-vaapi NEWS -- summary of changes. 2010-05-DD Copyright (C) 2010 Splitted-Desktop Systems -Version 0.2.1 - 13.May.2010 +Version 0.2.2 - DD.May.2010 +* Fix packaging dependencies * Fix OpenGL texture internal format (Clutter) +* Fix foreign window size for embedding (Totem) + +Version 0.2.1 - 12.May.2010 * Fix integration within the playbin2 pipeline * Fix vaapidecode to expose the HW supported caps only * Add GstXOverlay interface to vaapisink (Totem media player) diff --git a/configure.ac b/configure.ac index 5dc886486c..605ba0a21e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [2]) -m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_micro_version], [2]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From 748aac0fc56ab0dfe7245934bcdfb4f6a6ef4364 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 16:41:55 +0000 Subject: [PATCH 0380/3781] Sort platforms by name. --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 8da45ff4f7..3c4fed13a5 100644 --- a/README +++ b/README @@ -53,9 +53,9 @@ Software requirements Hardware requirements * AMD platforms with UVD2 (XvBA supported) - * Intel Poulsbo (US15W) * Intel Eaglelake (G45) * Intel Ironlake (HD Graphics) + * Intel Poulsbo (US15W) * NVIDIA platforms with PureVideo (VDPAU supported) From d5df97625ed849f711c1dbbdeb0570cd24076d01 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 21:27:43 +0000 Subject: [PATCH 0381/3781] Fix a crash in the FFmpeg decoder on close. --- NEWS | 1 + gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 9be5f4c6ae..fe04ed9775 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Copyright (C) 2010 Splitted-Desktop Systems Version 0.2.2 - DD.May.2010 * Fix packaging dependencies +* Fix a crash in the FFmpeg decoder on close * Fix OpenGL texture internal format (Clutter) * Fix foreign window size for embedding (Totem) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index a866390c05..d7ec1aee38 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -295,7 +295,8 @@ gst_vaapi_decoder_ffmpeg_close(GstVaapiDecoderFfmpeg *ffdecoder) GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; if (priv->avctx) { - avcodec_close(priv->avctx); + if (priv->is_opened) + avcodec_close(priv->avctx); av_freep(&priv->avctx->extradata); priv->avctx->extradata_size = 0; } From 0fb0c49dbb9da3447219bbe2013d8f1788b15d6f Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 21:39:58 +0000 Subject: [PATCH 0382/3781] Improve previous fix. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index d7ec1aee38..79fa94fbc5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -295,8 +295,10 @@ gst_vaapi_decoder_ffmpeg_close(GstVaapiDecoderFfmpeg *ffdecoder) GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; if (priv->avctx) { - if (priv->is_opened) + if (priv->is_opened) { avcodec_close(priv->avctx); + priv->is_opened = FALSE; + } av_freep(&priv->avctx->extradata); priv->avctx->extradata_size = 0; } From d24ee09860213333b67c544a70b2cc0f94d64166 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 13 May 2010 21:52:22 +0000 Subject: [PATCH 0383/3781] 0.2.2. --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index fe04ed9775..f8942afdd6 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ -gst-vaapi NEWS -- summary of changes. 2010-05-DD +gst-vaapi NEWS -- summary of changes. 2010-05-14 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.2.2 - DD.May.2010 +Version 0.2.2 - 14.May.2010 * Fix packaging dependencies * Fix a crash in the FFmpeg decoder on close * Fix OpenGL texture internal format (Clutter) From 681c07f541cc1284be30c9e192a1b68931435268 Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 14 May 2010 05:02:05 +0000 Subject: [PATCH 0384/3781] Bump version for development. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 605ba0a21e..bcb95710d2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [2]) -m4_define([gst_vaapi_micro_version], [2]) +m4_define([gst_vaapi_micro_version], [3]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From acadb2f995cecfd03cc936952d7106c2ee73dcdd Mon Sep 17 00:00:00 2001 From: gb Date: Sat, 15 May 2010 04:25:32 +0000 Subject: [PATCH 0385/3781] Improve debug info for gst_vaapisink_ensure_render_rect(). --- gst/vaapisink/gstvaapisink.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 4d15c1c0fa..1dcb4f4c96 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -207,6 +207,8 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) double display_ratio; gboolean success; + GST_DEBUG("ensure render rect within %ux%u bounds", width, height); + gst_vaapi_display_get_pixel_aspect_ratio( sink->display, &display_par_n, &display_par_d @@ -222,7 +224,7 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) ); if (!success) return FALSE; - GST_DEBUG("video size %dx%d, calculated render ratio %d/%d", + GST_DEBUG("video size %dx%d, calculated ratio %d/%d", sink->video_width, sink->video_height, num, den); if ((sink->video_height % den) == 0) { @@ -257,7 +259,6 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) display_rect->height = height; } } - GST_DEBUG("display size %ux%u", display_rect->width, display_rect->height); if (sink->fullscreen) { display_rect->x = (width - display_rect->width) / 2; @@ -267,6 +268,10 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) display_rect->x = 0; display_rect->y = 0; } + + GST_DEBUG("render rect (%d,%d):%ux%u", + display_rect->x, display_rect->y, + display_rect->width, display_rect->height); return TRUE; } From 0047bb1553c296495e22a94ea357e4f67b11b47e Mon Sep 17 00:00:00 2001 From: gb Date: Sat, 15 May 2010 04:35:00 +0000 Subject: [PATCH 0386/3781] Change GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN value to something more generic (-1). --- gst-libs/gst/vaapi/gstvaapidecoder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index fbffdd8e08..3dbfbc58c9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -78,7 +78,7 @@ enum _GstVaapiDecoderStatus { GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC, GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE, - GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN + GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN = -1 }; /** From 5e8e268e269619128d4bde2b51b44c990bb84e7d Mon Sep 17 00:00:00 2001 From: gb Date: Sat, 15 May 2010 05:36:15 +0000 Subject: [PATCH 0387/3781] Check for out-of-free-surfaces condition. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapicontext.c | 16 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapicontext.h | 3 +++ gst-libs/gst/vaapi/gstvaapidecoder.c | 6 ++++++ gst-libs/gst/vaapi/gstvaapidecoder.h | 2 ++ 5 files changed, 28 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index d7f62823cc..3db23a75a8 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -433,6 +433,7 @@ gst_vaapi_context_set_profile gst_vaapi_context_get_entrypoint gst_vaapi_context_get_size gst_vaapi_context_get_surface +gst_vaapi_context_get_surface_count gst_vaapi_context_put_surface gst_vaapi_context_find_surface_by_id diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index c0caa76569..e40fe0b7f3 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -616,6 +616,22 @@ gst_vaapi_context_get_surface(GstVaapiContext *context) return gst_vaapi_video_pool_get_object(context->priv->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(GST_VAAPI_IS_CONTEXT(context), 0); + + return gst_vaapi_video_pool_get_size(context->priv->surfaces_pool); +} + /** * gst_vaapi_context_put_surface: * @context: a #GstVaapiContext diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 71264a3152..e83a991681 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -122,6 +122,9 @@ gst_vaapi_context_get_size( GstVaapiSurface * gst_vaapi_context_get_surface(GstVaapiContext *context); +guint +gst_vaapi_context_get_surface_count(GstVaapiContext *context); + void gst_vaapi_context_put_surface(GstVaapiContext *context, GstVaapiSurface *surface); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 16feb4d3c8..15094633ea 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -89,9 +89,15 @@ pop_buffer(GstVaapiDecoder *decoder) static GstVaapiDecoderStatus decode_step(GstVaapiDecoder *decoder) { + GstVaapiDecoderPrivate * const priv = decoder->priv; GstVaapiDecoderStatus status; GstBuffer *buffer; + /* Decoding will fail if there is no surface left */ + if (priv->context && + gst_vaapi_context_get_surface_count(priv->context) == 0) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE; + do { buffer = pop_buffer(decoder); if (!buffer) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 3dbfbc58c9..53a54d3a51 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -65,6 +65,7 @@ typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; * @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_UNKNOWN: Unknown error. * @@ -77,6 +78,7 @@ enum _GstVaapiDecoderStatus { 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_UNKNOWN = -1 }; From 9a3b4a7844f9cca2376117a1236dc3d04a7afb7e Mon Sep 17 00:00:00 2001 From: gb Date: Sat, 15 May 2010 06:59:54 +0000 Subject: [PATCH 0388/3781] Fix memory leak of encoded buffers. --- NEWS | 5 ++++- gst-libs/gst/vaapi/gstvaapidecoder.c | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f8942afdd6..52d49e8363 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2010-05-14 +gst-vaapi NEWS -- summary of changes. 2010-05-DD Copyright (C) 2010 Splitted-Desktop Systems +Version 0.2.3 - DD.May.2010 +* Fix memory leak of encoded buffers + Version 0.2.2 - 14.May.2010 * Fix packaging dependencies * Fix a crash in the FFmpeg decoder on close diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 15094633ea..0bdf05eb85 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -105,6 +105,7 @@ decode_step(GstVaapiDecoder *decoder) status = GST_VAAPI_DECODER_GET_CLASS(decoder)->decode(decoder, buffer); GST_DEBUG("decode frame (status = %d)", status); + gst_buffer_unref(buffer); if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) return status; From a777a98f2f135469478f9cdf3ea9551bc853f142 Mon Sep 17 00:00:00 2001 From: gb Date: Sat, 15 May 2010 09:43:28 +0000 Subject: [PATCH 0389/3781] Add mechanism to reinsert buffer leftovers into the queue. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 29 +++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 21 ++++++++++----- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 8 ++++++ 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 0bdf05eb85..7fb4e86b73 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -70,6 +70,17 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) return TRUE; } +static void +push_back_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + GST_DEBUG("requeue encoded data buffer %p (%d bytes)", + buffer, GST_BUFFER_SIZE(buffer)); + + g_queue_push_head(priv->buffers, buffer); +} + static GstBuffer * pop_buffer(GstVaapiDecoder *decoder) { @@ -413,6 +424,24 @@ gst_vaapi_decoder_ensure_context( return priv->context != NULL; } +gboolean +gst_vaapi_decoder_push_buffer_sub( + GstVaapiDecoder *decoder, + GstBuffer *buffer, + guint offset, + guint size +) +{ + GstBuffer *subbuffer; + + subbuffer = gst_buffer_create_sub(buffer, offset, size); + if (!subbuffer) + return FALSE; + + push_back_buffer(decoder, subbuffer); + return TRUE; +} + gboolean gst_vaapi_decoder_push_surface( GstVaapiDecoder *decoder, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 79fa94fbc5..5537ea30f9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -490,8 +490,8 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) GstVaapiDecoderFfmpeg * const ffdecoder = GST_VAAPI_DECODER_FFMPEG(decoder); GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; GstClockTime inbuf_ts; - guchar *inbuf, *outbuf; - gint inbuf_size, outbuf_size; + guchar *outbuf; + gint inbuf_ofs, inbuf_size, outbuf_size; gboolean got_frame; g_return_val_if_fail(priv->is_constructed, @@ -503,7 +503,7 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; } - inbuf = GST_BUFFER_DATA(buffer); + inbuf_ofs = 0; inbuf_size = GST_BUFFER_SIZE(buffer); inbuf_ts = GST_BUFFER_TIMESTAMP(buffer); @@ -513,24 +513,31 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) priv->pctx, priv->avctx, &outbuf, &outbuf_size, - inbuf, inbuf_size, + GST_BUFFER_DATA(buffer) + inbuf_ofs, inbuf_size, inbuf_ts, inbuf_ts ); got_frame = outbuf && outbuf_size > 0; if (parsed_size > 0) { - inbuf += parsed_size; + inbuf_ofs += parsed_size; inbuf_size -= parsed_size; } } while (!got_frame && inbuf_size > 0); inbuf_ts = priv->pctx->pts; } else { - outbuf = inbuf; + outbuf = GST_BUFFER_DATA(buffer); outbuf_size = inbuf_size; - got_frame = inbuf && inbuf_size > 0; + got_frame = outbuf && outbuf_size > 0; + inbuf_ofs = inbuf_size; + inbuf_size = 0; } + if (inbuf_size > 0 && + !gst_vaapi_decoder_push_buffer_sub(decoder, buffer, + inbuf_ofs, inbuf_size)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + if (!got_frame && !GST_BUFFER_IS_EOS(buffer)) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 2b30cf3447..2dd028508c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -131,6 +131,14 @@ gst_vaapi_decoder_ensure_context( guint height ) attribute_hidden; +gboolean +gst_vaapi_decoder_push_buffer_sub( + GstVaapiDecoder *decoder, + GstBuffer *buffer, + guint offset, + guint size +) attribute_hidden; + gboolean gst_vaapi_decoder_push_surface( GstVaapiDecoder *decoder, From 86d0b2ade936da1891448449543e64daa27fe520 Mon Sep 17 00:00:00 2001 From: gb Date: Sat, 15 May 2010 15:33:20 +0000 Subject: [PATCH 0390/3781] Regularly update and expose decoder caps. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapidecoder.c | 119 +++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidecoder.h | 3 + gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 12 ++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 25 +++- 5 files changed, 156 insertions(+), 4 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 3db23a75a8..a37b4579e2 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -452,6 +452,7 @@ GstVaapiDecoderStatus GstVaapiDecoder GstVaapiDecoder GstVaapiDecoderClass +gst_vaapi_decoder_get_caps gst_vaapi_decoder_put_buffer gst_vaapi_decoder_get_surface diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 7fb4e86b73..4fe84cbe7c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -183,6 +183,8 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps) if (!profile) return; + priv->caps = gst_caps_copy(caps); + priv->codec = gst_vaapi_profile_get_codec(profile); if (!priv->codec) return; @@ -197,6 +199,11 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps) priv->fps_d = v2; } + if (gst_structure_get_fraction(structure, "pixel-aspect-ratio", &v1, &v2)) { + priv->par_n = v1; + priv->par_d = v2; + } + v_codec_data = gst_structure_get_value(structure, "codec_data"); if (v_codec_data) set_codec_data(decoder, gst_value_get_buffer(v_codec_data)); @@ -217,6 +224,11 @@ gst_vaapi_decoder_finalize(GObject *object) set_codec_data(decoder, NULL); + if (priv->caps) { + gst_caps_unref(priv->caps); + priv->caps = NULL; + } + if (priv->context) { g_object_unref(priv->context); priv->context = NULL; @@ -280,6 +292,9 @@ gst_vaapi_decoder_get_property( case PROP_DISPLAY: g_value_set_object(value, priv->display); break; + case PROP_CAPS: + gst_value_set_caps(value, priv->caps); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -317,7 +332,7 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass) g_param_spec_pointer("caps", "Decoder caps", "The decoder caps", - G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -327,16 +342,34 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) decoder->priv = priv; priv->context = NULL; + priv->caps = NULL; priv->codec = 0; priv->codec_data = NULL; priv->width = 0; priv->height = 0; - priv->fps_n = 1000; - priv->fps_d = 30; + priv->fps_n = 0; + priv->fps_d = 0; + priv->par_n = 0; + priv->par_d = 0; priv->buffers = g_queue_new(); priv->surfaces = g_queue_new(); } +/** + * gst_vaapi_decoder_get_caps: + * @decoder: a #GstVaapiDecoder + * + * Retrieves the @decoder caps. The deocder owns the returned caps, so + * use gst_caps_ref() whenever necessary. + * + * Return value: the @decoder caps + */ +GstCaps * +gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder) +{ + return decoder->priv->caps; +} + /** * gst_vaapi_decoder_put_buffer: * @decoder: a #GstVaapiDecoder @@ -399,6 +432,84 @@ gst_vaapi_decoder_get_surface( return proxy; } +void +gst_vaapi_decoder_set_picture_size( + GstVaapiDecoder *decoder, + guint width, + guint height +) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + g_object_freeze_notify(G_OBJECT(decoder)); + + if (priv->width != width) { + GST_DEBUG("picture width changed to %d", width); + priv->width = width; + gst_caps_set_simple(priv->caps, "width", G_TYPE_INT, width, NULL); + g_object_notify(G_OBJECT(decoder), "caps"); + } + + if (priv->height != height) { + GST_DEBUG("picture height changed to %d", height); + priv->height = height; + gst_caps_set_simple(priv->caps, "height", G_TYPE_INT, height, NULL); + g_object_notify(G_OBJECT(decoder), "caps"); + } + + g_object_thaw_notify(G_OBJECT(decoder)); +} + +void +gst_vaapi_decoder_set_framerate( + GstVaapiDecoder *decoder, + guint fps_n, + guint fps_d +) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (!fps_n || !fps_d) + return; + + if (priv->fps_n != fps_n || priv->fps_d != fps_d) { + GST_DEBUG("framerate changed to %u/%u", fps_n, fps_d); + priv->fps_n = fps_n; + priv->fps_d = fps_d; + gst_caps_set_simple( + priv->caps, + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, + NULL + ); + g_object_notify(G_OBJECT(decoder), "caps"); + } +} + +void +gst_vaapi_decoder_set_pixel_aspect_ratio( + GstVaapiDecoder *decoder, + guint par_n, + guint par_d +) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (!par_n || !par_d) + return; + + if (priv->par_n != par_n || priv->par_d != par_d) { + GST_DEBUG("pixel-aspect-ratio changed to %u/%u", par_n, par_d); + priv->par_n = par_n; + priv->par_d = par_d; + gst_caps_set_simple( + priv->caps, + "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, + NULL + ); + g_object_notify(G_OBJECT(decoder), "caps"); + } +} + gboolean gst_vaapi_decoder_ensure_context( GstVaapiDecoder *decoder, @@ -410,6 +521,8 @@ gst_vaapi_decoder_ensure_context( { GstVaapiDecoderPrivate * const priv = decoder->priv; + gst_vaapi_decoder_set_picture_size(decoder, width, height); + if (priv->context) return gst_vaapi_context_reset(priv->context, profile, entrypoint, width, height); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 53a54d3a51..f7210d3311 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -110,6 +110,9 @@ struct _GstVaapiDecoderClass { GType gst_vaapi_decoder_get_type(void); +GstCaps * +gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder); + gboolean gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 5537ea30f9..b94a02a86d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -167,6 +167,18 @@ get_context(AVCodecContext *avctx) if (!avctx->coded_width || !avctx->coded_height) return NULL; + gst_vaapi_decoder_set_framerate( + decoder, + avctx->time_base.den / avctx->ticks_per_frame, + avctx->time_base.num + ); + + gst_vaapi_decoder_set_pixel_aspect_ratio( + decoder, + avctx->sample_aspect_ratio.num, + avctx->sample_aspect_ratio.den + ); + success = gst_vaapi_decoder_ensure_context( decoder, vactx->profile, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 2dd028508c..546d93b8e6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -112,16 +112,40 @@ G_BEGIN_DECLS struct _GstVaapiDecoderPrivate { GstVaapiDisplay *display; GstVaapiContext *context; + GstCaps *caps; GstVaapiCodec codec; GstBuffer *codec_data; guint width; guint height; guint fps_n; guint fps_d; + guint par_n; + guint par_d; GQueue *buffers; GQueue *surfaces; }; +void +gst_vaapi_decoder_set_picture_size( + GstVaapiDecoder *decoder, + guint width, + guint height +) attribute_hidden; + +void +gst_vaapi_decoder_set_framerate( + GstVaapiDecoder *decoder, + guint fps_n, + guint fps_d +) attribute_hidden; + +void +gst_vaapi_decoder_set_pixel_aspect_ratio( + GstVaapiDecoder *decoder, + guint par_n, + guint par_d +) attribute_hidden; + gboolean gst_vaapi_decoder_ensure_context( GstVaapiDecoder *decoder, @@ -149,4 +173,3 @@ gst_vaapi_decoder_push_surface( G_END_DECLS #endif /* GST_VAAPI_DECODER_PRIV_H */ - From adfed50a90ff59958335e0fca2c6ca35f915e563 Mon Sep 17 00:00:00 2001 From: gb Date: Sun, 16 May 2010 21:04:32 +0000 Subject: [PATCH 0391/3781] Fix VC-1 decoding through the playbin2 pipeline. --- NEWS | 1 + gst/vaapidecode/gstvaapidecode.c | 59 +++++++++++++++++++++++++++++--- gst/vaapidecode/gstvaapidecode.h | 2 ++ 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 52d49e8363..43e67459c4 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Copyright (C) 2010 Splitted-Desktop Systems Version 0.2.3 - DD.May.2010 * Fix memory leak of encoded buffers +* Fix VC-1 decoding through the playbin2 pipeline Version 0.2.2 - 14.May.2010 * Fix packaging dependencies diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index d20d8b57b9..992178db79 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -93,6 +93,14 @@ enum { PROP_USE_FFMPEG, }; +static void +gst_vaapidecode_release(GstVaapiDecode *decode, GObject *dead_object) +{ + g_mutex_lock(decode->decoder_mutex); + g_cond_signal(decode->decoder_ready); + g_mutex_unlock(decode->decoder_mutex); +} + static GstFlowReturn gst_vaapidecode_step(GstVaapiDecode *decode) { @@ -104,12 +112,32 @@ gst_vaapidecode_step(GstVaapiDecode *decode) for (;;) { proxy = gst_vaapi_decoder_get_surface(decode->decoder, &status); if (!proxy) { + if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { + /* Wait for a VA surface to be displayed and free'd */ + GTimeVal timeout; + g_get_current_time(&timeout); + g_time_val_add(&timeout, 100); + g_mutex_lock(decode->decoder_mutex); + g_cond_timed_wait( + decode->decoder_ready, + decode->decoder_mutex, + &timeout + ); + g_mutex_unlock(decode->decoder_mutex); + continue; + } if (status != GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) goto error_decode; /* More data is needed */ break; } + g_object_weak_ref( + G_OBJECT(proxy), + (GWeakNotify)gst_vaapidecode_release, + decode + ); + buffer = NULL; ret = gst_pad_alloc_buffer( decode->srcpad, @@ -179,6 +207,14 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) if (!gst_vaapidecode_ensure_display(decode)) return FALSE; + decode->decoder_mutex = g_mutex_new(); + if (!decode->decoder_mutex) + return FALSE; + + decode->decoder_ready = g_cond_new(); + if (!decode->decoder_ready) + return FALSE; + if (decode->use_ffmpeg) decode->decoder = gst_vaapi_decoder_ffmpeg_new(decode->display, caps); if (!decode->decoder) @@ -191,6 +227,17 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { + if (decode->decoder_ready) { + gst_vaapidecode_release(decode, NULL); + g_cond_free(decode->decoder_ready); + decode->decoder_ready = NULL; + } + + if (decode->decoder_mutex) { + g_mutex_free(decode->decoder_mutex); + decode->decoder_mutex = NULL; + } + if (decode->decoder) { gst_vaapi_decoder_put_buffer(decode->decoder, NULL); g_object_unref(decode->decoder); @@ -513,11 +560,13 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - decode->display = NULL; - decode->decoder = NULL; - decode->decoder_caps = NULL; - decode->allowed_caps = NULL; - decode->use_ffmpeg = TRUE; + decode->display = NULL; + decode->decoder = NULL; + decode->decoder_mutex = NULL; + decode->decoder_ready = NULL; + decode->decoder_caps = NULL; + decode->allowed_caps = NULL; + decode->use_ffmpeg = TRUE; /* Pad through which data comes in to the element */ decode->sinkpad = gst_pad_new_from_template( diff --git a/gst/vaapidecode/gstvaapidecode.h b/gst/vaapidecode/gstvaapidecode.h index 8791bd961f..6d07bc5b63 100644 --- a/gst/vaapidecode/gstvaapidecode.h +++ b/gst/vaapidecode/gstvaapidecode.h @@ -63,6 +63,8 @@ struct _GstVaapiDecode { GstPad *srcpad; GstVaapiDisplay *display; GstVaapiDecoder *decoder; + GMutex *decoder_mutex; + GCond *decoder_ready; GstCaps *decoder_caps; GstCaps *allowed_caps; unsigned int use_ffmpeg : 1; From fa6385cd397e698d2fa7b5e08bd522c8b336e1eb Mon Sep 17 00:00:00 2001 From: gb Date: Sun, 16 May 2010 21:17:49 +0000 Subject: [PATCH 0392/3781] Fix decoder caps to report codec aliases. --- NEWS | 1 + README | 1 - gst-libs/gst/vaapi/gstvaapiprofile.c | 27 ++++++++++++++++++--------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index 43e67459c4..e6ece4b943 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Copyright (C) 2010 Splitted-Desktop Systems Version 0.2.3 - DD.May.2010 * Fix memory leak of encoded buffers +* Fix decoder caps to report codec aliases * Fix VC-1 decoding through the playbin2 pipeline Version 0.2.2 - 14.May.2010 diff --git a/README b/README index 3c4fed13a5..9a28115eeb 100644 --- a/README +++ b/README @@ -71,4 +71,3 @@ Caveats ------- * No ad-hoc parser, vaapidecoder currently relies on FFmpeg - * MPEG-4 Part-2 (DivX) has decoding bugs diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 1c9f56109e..40c9760af0 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -285,18 +285,27 @@ gst_vaapi_profile_get_va_profile(GstVaapiProfile profile) GstCaps * gst_vaapi_profile_get_caps(GstVaapiProfile profile) { - const GstVaapiProfileMap * const m = get_profiles_map(profile); - GstCaps *caps; + const GstVaapiProfileMap *m; + GstCaps *out_caps, *caps; - if (!m) + out_caps = gst_caps_new_empty(); + if (!out_caps) return NULL; - caps = gst_caps_from_string(m->caps_str); - if (!caps) - return NULL; - - gst_caps_set_simple(caps, "profile", G_TYPE_STRING, m->profile_str, NULL); - return caps; + for (m = gst_vaapi_profiles; m->profile; m++) { + if (m->profile != profile) + continue; + caps = gst_caps_from_string(m->caps_str); + if (!caps) + continue; + gst_caps_set_simple( + caps, + "profile", G_TYPE_STRING, m->profile_str, + NULL + ); + gst_caps_merge(out_caps, caps); + } + return out_caps; } /** From 689888d43db3ff5df84506f005fc16d9d29c79b0 Mon Sep 17 00:00:00 2001 From: gb Date: Sun, 16 May 2010 21:18:37 +0000 Subject: [PATCH 0393/3781] Build-Requires: gstreamer0.10 >= 0.10.10 for gst_caps_merge(). --- README | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index 9a28115eeb..9e76d2a268 100644 --- a/README +++ b/README @@ -45,7 +45,7 @@ Requirements Software requirements - * libgstreamer0.10-dev >= 0.10.0 + * libgstreamer0.10-dev >= 0.10.10 * libgstreamer-plugins-base0.10-dev >= 0.10.16 * libva-dev >= 0.31.0-1+sds9 (VA/GLX) * libavcodec-dev >= 0.6 or with diff --git a/configure.ac b/configure.ac index bcb95710d2..5f73343696 100644 --- a/configure.ac +++ b/configure.ac @@ -8,7 +8,7 @@ m4_define([gst_vaapi_version], # gst version number m4_define([gst_major_version], [0]) m4_define([gst_minor_version], [10]) -m4_define([gst_micro_version], [0]) +m4_define([gst_micro_version], [10]) m4_define([gst_major_minor_version], [gst_major_version.gst_minor_version]) m4_define([gst_version], From f2b8dc69ac555fb49fcf2a4eaf5b2feb3f2ec3ed Mon Sep 17 00:00:00 2001 From: gb Date: Sun, 16 May 2010 21:35:14 +0000 Subject: [PATCH 0394/3781] Wait for at most one second for a VA surface to become available. --- gst/vaapidecode/gstvaapidecode.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 992178db79..f9f7a336ee 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -108,15 +108,20 @@ gst_vaapidecode_step(GstVaapiDecode *decode) GstVaapiDecoderStatus status; GstBuffer *buffer; GstFlowReturn ret; + guint tries; for (;;) { + tries = 0; + again: proxy = gst_vaapi_decoder_get_surface(decode->decoder, &status); if (!proxy) { if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { /* Wait for a VA surface to be displayed and free'd */ + if (++tries > 100) + goto error_decode_timeout; GTimeVal timeout; g_get_current_time(&timeout); - g_time_val_add(&timeout, 100); + g_time_val_add(&timeout, 10000); /* 10 ms each step */ g_mutex_lock(decode->decoder_mutex); g_cond_timed_wait( decode->decoder_ready, @@ -124,7 +129,7 @@ gst_vaapidecode_step(GstVaapiDecode *decode) &timeout ); g_mutex_unlock(decode->decoder_mutex); - continue; + goto again; } if (status != GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) goto error_decode; @@ -163,6 +168,12 @@ gst_vaapidecode_step(GstVaapiDecode *decode) return GST_FLOW_OK; /* ERRORS */ +error_decode_timeout: + { + GST_DEBUG("decode timeout. Decoder required a VA surface but none " + "got available within one second"); + return GST_FLOW_UNEXPECTED; + } error_decode: { GST_DEBUG("decode error %d", status); From ca25e903ace43b99fe53f65aba614a9765eabc51 Mon Sep 17 00:00:00 2001 From: gb Date: Sun, 16 May 2010 21:44:17 +0000 Subject: [PATCH 0395/3781] 0.2.3. --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index e6ece4b943..167c5a390d 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ -gst-vaapi NEWS -- summary of changes. 2010-05-DD +gst-vaapi NEWS -- summary of changes. 2010-05-16 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.2.3 - DD.May.2010 +Version 0.2.3 - 16.May.2010 * Fix memory leak of encoded buffers * Fix decoder caps to report codec aliases * Fix VC-1 decoding through the playbin2 pipeline From 48ef9eef613068e85e64c2fac57ff2fc70830d08 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 17 May 2010 07:32:10 +0000 Subject: [PATCH 0396/3781] Bump version for development. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 5f73343696..83cb20207e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [2]) -m4_define([gst_vaapi_micro_version], [3]) +m4_define([gst_vaapi_micro_version], [4]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From 9cfa0058879992c395fcd9497f801b7d11731c88 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 17 May 2010 08:24:42 +0000 Subject: [PATCH 0397/3781] Simplify GLX rendering code. --- gst/vaapisink/gstvaapisink.c | 111 ++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 46 deletions(-) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 1dcb4f4c96..602bc782ba 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -555,15 +555,30 @@ render_reflection(GstVaapiSink *sink) } static gboolean -gst_vaapisink_show_frame_glx(GstVaapiSink *sink) +gst_vaapisink_show_frame_glx( + GstVaapiSink *sink, + GstVaapiSurface *surface, + guint flags +) { GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window); GLenum target; GLuint texture; - if (!sink->use_reflection) - return gst_vaapi_window_glx_put_texture(window, sink->texture, - NULL, &sink->display_rect); + gst_vaapi_window_glx_make_current(window); + if (!sink->texture) { + sink->texture = gst_vaapi_texture_new( + sink->display, + GL_TEXTURE_2D, + GL_BGRA, + sink->video_width, + sink->video_height + ); + if (!sink->texture) + goto error_create_texture; + } + if (!gst_vaapi_texture_put_surface(sink->texture, surface, flags)) + goto error_transfer_surface; target = gst_vaapi_texture_get_target(sink->texture); texture = gst_vaapi_texture_get_id(sink->texture); @@ -575,22 +590,54 @@ gst_vaapisink_show_frame_glx(GstVaapiSink *sink) glEnable(target); glBindTexture(target, texture); { - glPushMatrix(); - glRotatef(20.0f, 0.0f, 1.0f, 0.0f); - glTranslatef(50.0f, 0.0f, 0.0f); + if (sink->use_reflection) { + glPushMatrix(); + glRotatef(20.0f, 0.0f, 1.0f, 0.0f); + glTranslatef(50.0f, 0.0f, 0.0f); + } render_frame(sink); - glPushMatrix(); - glTranslatef(0.0, (GLfloat)sink->display_rect.height + 5.0f, 0.0f); - render_reflection(sink); - glPopMatrix(); - glPopMatrix(); + if (sink->use_reflection) { + glPushMatrix(); + glTranslatef(0.0, (GLfloat)sink->display_rect.height + 5.0f, 0.0f); + render_reflection(sink); + glPopMatrix(); + glPopMatrix(); + } } glBindTexture(target, 0); glDisable(target); + gst_vaapi_window_glx_swap_buffers(window); return TRUE; + + /* ERRORS */ +error_create_texture: + { + GST_DEBUG("could not create VA/GLX texture"); + return FALSE; + } +error_transfer_surface: + { + GST_DEBUG("could not transfer VA surface to texture"); + return FALSE; + } } #endif +static inline gboolean +gst_vaapisink_show_frame_x11( + GstVaapiSink *sink, + GstVaapiSurface *surface, + guint flags +) +{ + if (!gst_vaapi_window_put_surface(sink->window, surface, + NULL, &sink->display_rect, flags)) { + GST_DEBUG("could not render VA surface"); + return FALSE; + } + return TRUE; +} + static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) { @@ -598,6 +645,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); GstVaapiSurface *surface; guint flags; + gboolean success; if (!sink->window) return GST_FLOW_UNEXPECTED; @@ -612,41 +660,12 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; #if USE_VAAPISINK_GLX - if (sink->use_glx) { - GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window); - gst_vaapi_window_glx_make_current(window); - if (!sink->texture) { - sink->texture = gst_vaapi_texture_new( - sink->display, - GL_TEXTURE_2D, - GL_BGRA, - sink->video_width, - sink->video_height - ); - if (!sink->texture) { - GST_DEBUG("could not create VA/GLX texture"); - return GST_FLOW_UNEXPECTED; - } - } - if (!gst_vaapi_texture_put_surface(sink->texture, surface, flags)) { - GST_DEBUG("could not transfer VA surface to texture"); - return GST_FLOW_UNEXPECTED; - } - if (!gst_vaapisink_show_frame_glx(sink)) { - GST_DEBUG("could not render VA/GLX texture"); - return GST_FLOW_UNEXPECTED; - } - gst_vaapi_window_glx_swap_buffers(window); - return GST_FLOW_OK; - } + if (sink->use_glx) + success = gst_vaapisink_show_frame_glx(sink, surface, flags); + else #endif - - if (!gst_vaapi_window_put_surface(sink->window, surface, - NULL, &sink->display_rect, flags)) { - GST_DEBUG("could not render VA surface"); - return GST_FLOW_UNEXPECTED; - } - return GST_FLOW_OK; + success = gst_vaapisink_show_frame_x11(sink, surface, flags); + return success ? GST_FLOW_OK : GST_FLOW_UNEXPECTED; } static void From 643d08ef23a589935e7938fe787c958af326a756 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 17 May 2010 08:28:28 +0000 Subject: [PATCH 0398/3781] Disable GLX rendering when vaapisink uses a foreign X window. --- NEWS | 5 ++++- gst/vaapisink/gstvaapisink.c | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 167c5a390d..c211c4f136 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2010-05-16 +gst-vaapi NEWS -- summary of changes. 2010-05-DD Copyright (C) 2010 Splitted-Desktop Systems +Version 0.2.4 - DD.May.2010 +* Disable GLX rendering when vaapisink uses a foreign X window + Version 0.2.3 - 16.May.2010 * Fix memory leak of encoded buffers * Fix decoder caps to report codec aliases diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 602bc782ba..79e0dc7a90 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -132,6 +132,10 @@ gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); + /* Disable GLX rendering when vaapisink is using a foreign X + window. It's pretty much useless */ + sink->use_glx = FALSE; + gst_vaapisink_ensure_window_xid(sink, xid); } From 28f85a916d20667af008275f5e9ed2aa7595c551 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 17 May 2010 08:55:51 +0000 Subject: [PATCH 0399/3781] Fix video rendering rect within an embedder window (Totem). --- NEWS | 1 + gst/vaapisink/gstvaapisink.c | 54 +++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index c211c4f136..05faa50c3d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ gst-vaapi NEWS -- summary of changes. 2010-05-DD Copyright (C) 2010 Splitted-Desktop Systems Version 0.2.4 - DD.May.2010 +* Fix video rendering rect within an embedder window (Totem) * Disable GLX rendering when vaapisink uses a foreign X window Version 0.2.3 - 16.May.2010 diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 79e0dc7a90..bed2df6b6e 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -186,6 +186,57 @@ gst_vaapisink_destroy(GstVaapiSink *sink) } } +/* Checks whether a ConfigureNotify event is in the queue */ +typedef struct _ConfigureNotifyEventPendingArgs ConfigureNotifyEventPendingArgs; +struct _ConfigureNotifyEventPendingArgs { + Window window; + guint width; + guint height; + gboolean match; +}; + +static Bool +configure_notify_event_pending_cb(Display *dpy, XEvent *xev, XPointer arg) +{ + ConfigureNotifyEventPendingArgs * const args = + (ConfigureNotifyEventPendingArgs *)arg; + + if (xev->type == ConfigureNotify && + xev->xconfigure.window == args->window && + xev->xconfigure.width == args->width && + xev->xconfigure.height == args->height) + args->match = TRUE; + + /* XXX: this is a hack to traverse the whole queue because we + can't use XPeekIfEvent() since it could block */ + return False; +} + +static gboolean +configure_notify_event_pending( + GstVaapiSink *sink, + Window window, + guint width, + guint height +) +{ + ConfigureNotifyEventPendingArgs args; + XEvent xev; + + args.window = window; + args.width = width; + args.height = height; + args.match = FALSE; + + /* XXX: don't use XPeekIfEvent() because it might block */ + XCheckIfEvent( + gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)), + &xev, + configure_notify_event_pending_cb, (XPointer)&args + ); + return args.match; +} + static inline gboolean gst_vaapisink_ensure_display(GstVaapiSink *sink) { @@ -319,7 +370,8 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, XID xid) ); gst_vaapi_display_unlock(sink->display); - if (width != sink->window_width || height != sink->window_height) { + if ((width != sink->window_width || height != sink->window_height) && + !configure_notify_event_pending(sink, xid, width, height)) { if (!gst_vaapisink_ensure_render_rect(sink, width, height)) return FALSE; sink->window_width = width; From 6b8f76b2ce67a9ab30e3a85ecabdf2a65bd5d3c4 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 17 May 2010 12:32:34 +0000 Subject: [PATCH 0400/3781] Soft validate caps since we only care about video/x-vaapi-surface as input. _setcaps() will check for other fields. --- gst/vaapisink/gstvaapisink.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index bed2df6b6e..b944ee6e09 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -486,14 +486,11 @@ gst_vaapisink_buffer_alloc( ) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + GstStructure *structure; GstBuffer *buffer; - GstCaps *sink_caps; - sink_caps = gst_static_pad_template_get_caps(&gst_vaapisink_sink_factory); - if (!sink_caps) - goto error_no_sink_caps; - - if (!gst_caps_is_always_compatible(caps, sink_caps)) + structure = gst_caps_get_structure(caps, 0); + if (!gst_structure_has_name(structure, "video/x-vaapi-surface")) goto error_invalid_caps; buffer = gst_vaapi_video_buffer_new(sink->display); @@ -501,26 +498,18 @@ gst_vaapisink_buffer_alloc( goto error_create_buffer; gst_buffer_set_caps(buffer, caps); - gst_caps_unref(sink_caps); *pout_buffer = buffer; return GST_FLOW_OK; /* ERRORS */ -error_no_sink_caps: - { - GST_DEBUG("failed to get static sink caps"); - return GST_FLOW_UNEXPECTED; - } error_invalid_caps: { GST_DEBUG("failed to validate input caps"); - gst_caps_unref(sink_caps); return GST_FLOW_UNEXPECTED; } error_create_buffer: { GST_DEBUG("failed to create video buffer"); - gst_caps_unref(sink_caps); return GST_FLOW_UNEXPECTED; } } From 643d35e87a67376af9cd89cd868666368b105ac3 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 18 May 2010 11:22:54 +0000 Subject: [PATCH 0401/3781] Fix upscaling in foreign window (Totem). --- gst/vaapisink/gstvaapisink.c | 4 +++- gst/vaapisink/gstvaapisink.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index b944ee6e09..088999a13b 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -136,6 +136,7 @@ gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) window. It's pretty much useless */ sink->use_glx = FALSE; + sink->foreign_window = TRUE; gst_vaapisink_ensure_window_xid(sink, xid); } @@ -303,7 +304,7 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) display_ratio = (gdouble)display_rect->width / display_rect->height; GST_DEBUG("scaling to %ux%u", display_rect->width, display_rect->height); - if (sink->fullscreen || + if (sink->fullscreen || sink->foreign_window || display_rect->width > width || display_rect->height > height) { if (sink->video_width > sink->video_height) { display_rect->width = width; @@ -883,6 +884,7 @@ gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) sink->video_height = 0; sink->video_par_n = 1; sink->video_par_d = 1; + sink->foreign_window = FALSE; sink->fullscreen = FALSE; sink->synchronous = FALSE; sink->use_glx = USE_VAAPISINK_GLX; diff --git a/gst/vaapisink/gstvaapisink.h b/gst/vaapisink/gstvaapisink.h index 848c148de1..1a9014b6a9 100644 --- a/gst/vaapisink/gstvaapisink.h +++ b/gst/vaapisink/gstvaapisink.h @@ -77,6 +77,7 @@ struct _GstVaapiSink { gint video_par_n; gint video_par_d; GstVaapiRectangle display_rect; + guint foreign_window : 1; guint fullscreen : 1; guint synchronous : 1; guint use_glx : 1; From ade43e801668c1b0f9f80c1ea9f12f6fdc86a7f9 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 14 Jun 2010 09:20:37 +0000 Subject: [PATCH 0402/3781] Fix build with older VA-API 0.29-sds. --- gst-libs/gst/vaapi/gstvaapicompat.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 1ad47ef7d5..e17684fbd1 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -27,6 +27,9 @@ # include #else # include +# if !VA_CHECK_VERSION(0,30,4) +# include +# endif #endif #if USE_VAAPI_GLX From dfa5bafa5c55110a619cfe2ab101730ee304d7a9 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 14 Jun 2010 12:58:22 +0000 Subject: [PATCH 0403/3781] Update changelog. --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 05faa50c3d..18299ca8ed 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ gst-vaapi NEWS -- summary of changes. 2010-05-DD Copyright (C) 2010 Splitted-Desktop Systems Version 0.2.4 - DD.May.2010 +* Fix build with older VA-API 0.29-sds * Fix video rendering rect within an embedder window (Totem) * Disable GLX rendering when vaapisink uses a foreign X window From 6735dc6b68cc208fbf27cf995bc026f9154026a9 Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 14 Jun 2010 14:14:42 +0000 Subject: [PATCH 0404/3781] Fix decoding of some H.264 streams. e.g. Ice Age 2 trailer. --- NEWS | 1 + gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 18299ca8ed..6af3779bd1 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Copyright (C) 2010 Splitted-Desktop Systems Version 0.2.4 - DD.May.2010 * Fix build with older VA-API 0.29-sds +* Fix decoding of some H.264 streams. e.g. Ice Age 2 trailer * Fix video rendering rect within an embedder window (Totem) * Disable GLX rendering when vaapisink uses a foreign X window diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index b94a02a86d..d6fe7e2406 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -478,10 +478,10 @@ decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) buf, buf_size ); GST_VAAPI_DISPLAY_UNLOCK(display); - if (bytes_read < 0) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; if (!got_picture) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + if (bytes_read < 0) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; surface = gst_vaapi_context_find_surface_by_id( GST_VAAPI_DECODER_CONTEXT(ffdecoder), From e384639747b5c3cf128fe4d09e693fba793ceb9a Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 14 Jun 2010 14:46:41 +0000 Subject: [PATCH 0405/3781] Bump version for development. --- NEWS | 6 ++++-- configure.ac | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 6af3779bd1..d259339b8a 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,11 @@ -gst-vaapi NEWS -- summary of changes. 2010-05-DD +gst-vaapi NEWS -- summary of changes. 2010-06-DD Copyright (C) 2010 Splitted-Desktop Systems -Version 0.2.4 - DD.May.2010 +Version 0.2.5 - DD.Jun.2010 * Fix build with older VA-API 0.29-sds * Fix decoding of some H.264 streams. e.g. Ice Age 2 trailer + +Version 0.2.4 - 18.May.2010 * Fix video rendering rect within an embedder window (Totem) * Disable GLX rendering when vaapisink uses a foreign X window diff --git a/configure.ac b/configure.ac index 83cb20207e..89dca33d77 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [2]) -m4_define([gst_vaapi_micro_version], [4]) +m4_define([gst_vaapi_micro_version], [5]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From d1332bc2e1d05da8eb031ba2cec27dc929882d20 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 15 Jun 2010 12:36:16 +0000 Subject: [PATCH 0406/3781] Fix GLX version check. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 9d38f9e79c..899b657550 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -853,7 +853,7 @@ gl_create_pixmap_object(Display *dpy, guint width, guint height) return NULL; if (!glXQueryVersion(dpy, &glx_major, &glx_minor)) return NULL; - if (glx_major < 0 || (glx_major == 1 && glx_minor < 3)) /* 1.3 */ + if (glx_major < 1 || (glx_major == 1 && glx_minor < 3)) /* 1.3 */ return NULL; gl_vtable->has_texture_from_pixmap = TRUE; } From ca3005055cf6b851408b26fcdb63dc86c5badade Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 22 Jun 2010 12:57:06 +0000 Subject: [PATCH 0407/3781] Add GstBaseVideoDecoder from gst-plugins-bad git. --- gst-libs/gst/video/Makefile.am | 43 + gst-libs/gst/video/gstbasevideocodec.c | 575 +++++++++ gst-libs/gst/video/gstbasevideocodec.h | 150 +++ gst-libs/gst/video/gstbasevideodecoder.c | 1495 ++++++++++++++++++++++ gst-libs/gst/video/gstbasevideodecoder.h | 177 +++ gst-libs/gst/video/gstbasevideoutils.c | 137 ++ gst-libs/gst/video/gstbasevideoutils.h | 100 ++ 7 files changed, 2677 insertions(+) create mode 100644 gst-libs/gst/video/Makefile.am create mode 100644 gst-libs/gst/video/gstbasevideocodec.c create mode 100644 gst-libs/gst/video/gstbasevideocodec.h create mode 100644 gst-libs/gst/video/gstbasevideodecoder.c create mode 100644 gst-libs/gst/video/gstbasevideodecoder.h create mode 100644 gst-libs/gst/video/gstbasevideoutils.c create mode 100644 gst-libs/gst/video/gstbasevideoutils.h diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am new file mode 100644 index 0000000000..4a2dc1d6f0 --- /dev/null +++ b/gst-libs/gst/video/Makefile.am @@ -0,0 +1,43 @@ +noinst_LTLIBRARIES = libgstbasevideo-@GST_MAJORMINOR@.la + +libgstbasevideo_source_c = \ + gstbasevideocodec.c \ + gstbasevideodecoder.c \ + gstbasevideoutils.c \ + $(NULL) + +libgstbasevideo_source_h = \ + gstbasevideocodec.h \ + gstbasevideodecoder.h \ + gstbasevideoutils.h \ + $(NULL) + +libgstbasevideo_@GST_MAJORMINOR@includedir = \ + $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/video + +libgstbasevideo_@GST_MAJORMINOR@_la_SOURCES = \ + $(libgstbasevideo_source_c) + +noinst_HEADERS = \ + $(libgstbasevideo_source_h) + +libgstbasevideo_@GST_MAJORMINOR@_la_CFLAGS = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + $(GST_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(GST_PLUGINS_BASE_CFLAGS) \ + $(NULL) + +libgstbasevideo_@GST_MAJORMINOR@_la_LIBADD = \ + $(GST_LIBS) \ + $(GST_BASE_LIBS) \ + $(GST_PLUGINS_BASE_LIBS) \ + $(NULL) + +libgstbasevideo_@GST_MAJORMINOR@_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(NULL) + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/gst-libs/gst/video/gstbasevideocodec.c b/gst-libs/gst/video/gstbasevideocodec.c new file mode 100644 index 0000000000..a6931c96cb --- /dev/null +++ b/gst-libs/gst/video/gstbasevideocodec.c @@ -0,0 +1,575 @@ +/* Schrodinger + * Copyright (C) 2006 David Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstbasevideocodec.h" + +#include +#include + +GST_DEBUG_CATEGORY (basevideocodec_debug); +#define GST_CAT_DEFAULT basevideocodec_debug + +/* GstBaseVideoCodec signals and args */ +enum +{ + LAST_SIGNAL +}; + +enum +{ + ARG_0 +}; + +static void gst_base_video_codec_finalize (GObject * object); + +//static const GstQueryType *gst_base_video_codec_get_query_types (GstPad *pad); +//static gboolean gst_base_video_codec_src_query (GstPad *pad, GstQuery *query); +//static gboolean gst_base_video_codec_sink_query (GstPad *pad, GstQuery *query); +//static gboolean gst_base_video_codec_src_event (GstPad *pad, GstEvent *event); +//static gboolean gst_base_video_codec_sink_event (GstPad *pad, GstEvent *event); +static GstStateChangeReturn gst_base_video_codec_change_state (GstElement * + element, GstStateChange transition); +//static GstFlowReturn gst_base_video_codec_push_all (GstBaseVideoCodec *base_video_codec, +// gboolean at_eos); + + +GST_BOILERPLATE (GstBaseVideoCodec, gst_base_video_codec, GstElement, + GST_TYPE_ELEMENT); + +static void +gst_base_video_codec_base_init (gpointer g_class) +{ + GST_DEBUG_CATEGORY_INIT (basevideocodec_debug, "basevideocodec", 0, + "Base Video Codec"); + +} + +static void +gst_base_video_codec_class_init (GstBaseVideoCodecClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *element_class; + + gobject_class = G_OBJECT_CLASS (klass); + element_class = GST_ELEMENT_CLASS (klass); + + gobject_class->finalize = gst_base_video_codec_finalize; + + element_class->change_state = gst_base_video_codec_change_state; +} + +static void +gst_base_video_codec_init (GstBaseVideoCodec * base_video_codec, + GstBaseVideoCodecClass * klass) +{ + GstPadTemplate *pad_template; + + GST_DEBUG ("gst_base_video_codec_init"); + + pad_template = + gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink"); + g_return_if_fail (pad_template != NULL); + + base_video_codec->sinkpad = gst_pad_new_from_template (pad_template, "sink"); + //gst_pad_set_query_function (base_video_codec->sinkpad, + // gst_base_video_codec_sink_query); + gst_element_add_pad (GST_ELEMENT (base_video_codec), + base_video_codec->sinkpad); + + pad_template = + gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src"); + g_return_if_fail (pad_template != NULL); + + base_video_codec->srcpad = gst_pad_new_from_template (pad_template, "src"); + gst_element_add_pad (GST_ELEMENT (base_video_codec), + base_video_codec->srcpad); + + base_video_codec->input_adapter = gst_adapter_new (); + base_video_codec->output_adapter = gst_adapter_new (); + +} + +static void +gst_base_video_codec_reset (GstBaseVideoCodec * base_video_codec) +{ + GST_DEBUG ("reset"); + + base_video_codec->system_frame_number = 0; + + //gst_segment_init (&base_video_codec->state.segment, GST_FORMAT_TIME); + gst_adapter_clear (base_video_codec->input_adapter); + gst_adapter_clear (base_video_codec->output_adapter); + +} + +static void +gst_base_video_codec_finalize (GObject * object) +{ + GstBaseVideoCodec *base_video_codec; + + g_return_if_fail (GST_IS_BASE_VIDEO_CODEC (object)); + base_video_codec = GST_BASE_VIDEO_CODEC (object); + + if (base_video_codec->input_adapter) { + g_object_unref (base_video_codec->input_adapter); + } + if (base_video_codec->output_adapter) { + g_object_unref (base_video_codec->output_adapter); + } + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +#ifdef unused +static const GstQueryType * +gst_base_video_codec_get_query_types (GstPad * pad) +{ + static const GstQueryType query_types[] = { + GST_QUERY_POSITION, + GST_QUERY_DURATION, + GST_QUERY_CONVERT, + 0 + }; + + return query_types; +} +#endif + +#if 0 +static gboolean +gst_base_video_codec_src_convert (GstPad * pad, + GstFormat src_format, gint64 src_value, + GstFormat * dest_format, gint64 * dest_value) +{ + gboolean res; + GstBaseVideoCodec *dec; + + if (src_format == *dest_format) { + *dest_value = src_value; + return TRUE; + } + + dec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); + + if (src_format == GST_FORMAT_DEFAULT && *dest_format == GST_FORMAT_TIME) { + if (dec->fps_d != 0) { + *dest_value = gst_util_uint64_scale (granulepos_to_frame (src_value), + dec->fps_d * GST_SECOND, dec->fps_n); + res = TRUE; + } else { + res = FALSE; + } + } else { + GST_WARNING ("unhandled conversion from %d to %d", src_format, + *dest_format); + res = FALSE; + } + + gst_object_unref (dec); + + return res; +} + +static gboolean +gst_base_video_codec_sink_convert (GstPad * pad, + GstFormat src_format, gint64 src_value, + GstFormat * dest_format, gint64 * dest_value) +{ + gboolean res = TRUE; + GstBaseVideoCodec *dec; + + if (src_format == *dest_format) { + *dest_value = src_value; + return TRUE; + } + + dec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); + + /* FIXME: check if we are in a decoding state */ + + switch (src_format) { + case GST_FORMAT_DEFAULT: + switch (*dest_format) { + case GST_FORMAT_TIME: + *dest_value = gst_util_uint64_scale (src_value, + dec->fps_d * GST_SECOND, dec->fps_n); + break; + default: + res = FALSE; + } + break; + case GST_FORMAT_TIME: + switch (*dest_format) { + case GST_FORMAT_DEFAULT: + { + *dest_value = gst_util_uint64_scale (src_value, + dec->fps_n, dec->fps_d * GST_SECOND); + break; + } + default: + res = FALSE; + break; + } + break; + default: + res = FALSE; + break; + } + + gst_object_unref (dec); + + return res; +} +#endif + +#ifdef unused +static gboolean +gst_base_video_codec_src_query (GstPad * pad, GstQuery * query) +{ + GstBaseVideoCodec *base_codec; + gboolean res = FALSE; + + base_codec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_POSITION: + { + GstFormat format; + gint64 time; + gint64 value; + + gst_query_parse_position (query, &format, NULL); + + time = gst_util_uint64_scale (base_codec->system_frame_number, + base_codec->state.fps_n, base_codec->state.fps_d); + time += base_codec->state.segment.time; + GST_DEBUG ("query position %" GST_TIME_FORMAT, GST_TIME_ARGS (time)); + res = gst_base_video_encoded_video_convert (&base_codec->state, + GST_FORMAT_TIME, time, &format, &value); + if (!res) + goto error; + + gst_query_set_position (query, format, value); + break; + } + case GST_QUERY_DURATION: + res = gst_pad_query (GST_PAD_PEER (base_codec->sinkpad), query); + if (!res) + goto error; + break; + case GST_QUERY_CONVERT: + { + GstFormat src_fmt, dest_fmt; + gint64 src_val, dest_val; + + GST_DEBUG ("query convert"); + + gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); + res = gst_base_video_encoded_video_convert (&base_codec->state, + src_fmt, src_val, &dest_fmt, &dest_val); + if (!res) + goto error; + gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); + break; + } + default: + res = gst_pad_query_default (pad, query); + break; + } +done: + gst_object_unref (base_codec); + + return res; +error: + GST_DEBUG_OBJECT (base_codec, "query failed"); + goto done; +} +#endif + +#ifdef unused +static gboolean +gst_base_video_codec_sink_query (GstPad * pad, GstQuery * query) +{ + GstBaseVideoCodec *base_video_codec; + gboolean res = FALSE; + + base_video_codec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CONVERT: + { + GstFormat src_fmt, dest_fmt; + gint64 src_val, dest_val; + + gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); + res = gst_base_video_encoded_video_convert (&base_video_codec->state, + src_fmt, src_val, &dest_fmt, &dest_val); + if (!res) + goto error; + gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); + break; + } + default: + res = gst_pad_query_default (pad, query); + break; + } +done: + gst_object_unref (base_video_codec); + + return res; +error: + GST_DEBUG_OBJECT (base_video_codec, "query failed"); + goto done; +} +#endif + +#ifdef unused +static gboolean +gst_base_video_codec_src_event (GstPad * pad, GstEvent * event) +{ + GstBaseVideoCodec *base_video_codec; + gboolean res = FALSE; + + base_video_codec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_SEEK: + { + GstFormat format, tformat; + gdouble rate; + GstEvent *real_seek; + GstSeekFlags flags; + GstSeekType cur_type, stop_type; + gint64 cur, stop; + gint64 tcur, tstop; + + gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, + &cur, &stop_type, &stop); + gst_event_unref (event); + + tformat = GST_FORMAT_TIME; + res = gst_base_video_encoded_video_convert (&base_video_codec->state, + format, cur, &tformat, &tcur); + if (!res) + goto convert_error; + res = gst_base_video_encoded_video_convert (&base_video_codec->state, + format, stop, &tformat, &tstop); + if (!res) + goto convert_error; + + real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME, + flags, cur_type, tcur, stop_type, tstop); + + res = gst_pad_push_event (base_video_codec->sinkpad, real_seek); + + break; + } +#if 0 + case GST_EVENT_QOS: + { + gdouble proportion; + GstClockTimeDiff diff; + GstClockTime timestamp; + + gst_event_parse_qos (event, &proportion, &diff, ×tamp); + + GST_OBJECT_LOCK (base_video_codec); + base_video_codec->proportion = proportion; + base_video_codec->earliest_time = timestamp + diff; + GST_OBJECT_UNLOCK (base_video_codec); + + GST_DEBUG_OBJECT (base_video_codec, + "got QoS %" GST_TIME_FORMAT ", %" G_GINT64_FORMAT, + GST_TIME_ARGS (timestamp), diff); + + res = gst_pad_push_event (base_video_codec->sinkpad, event); + break; + } +#endif + default: + res = gst_pad_push_event (base_video_codec->sinkpad, event); + break; + } +done: + gst_object_unref (base_video_codec); + return res; + +convert_error: + GST_DEBUG_OBJECT (base_video_codec, "could not convert format"); + goto done; +} +#endif + +#ifdef unused +static gboolean +gst_base_video_codec_sink_event (GstPad * pad, GstEvent * event) +{ + GstBaseVideoCodec *base_video_codec; + gboolean ret = FALSE; + + base_video_codec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_START: + ret = gst_pad_push_event (base_video_codec->srcpad, event); + break; + case GST_EVENT_FLUSH_STOP: + gst_base_video_codec_reset (base_video_codec); + ret = gst_pad_push_event (base_video_codec->srcpad, event); + break; + case GST_EVENT_EOS: + if (gst_base_video_codec_push_all (base_video_codec, + FALSE) == GST_FLOW_ERROR) { + gst_event_unref (event); + return FALSE; + } + + ret = gst_pad_push_event (base_video_codec->srcpad, event); + break; + case GST_EVENT_NEWSEGMENT: + { + gboolean update; + GstFormat format; + gdouble rate; + gint64 start, stop, time; + + gst_event_parse_new_segment (event, &update, &rate, &format, &start, + &stop, &time); + + if (format != GST_FORMAT_TIME) + goto newseg_wrong_format; + + if (rate <= 0.0) + goto newseg_wrong_rate; + + GST_DEBUG ("newsegment %" GST_TIME_FORMAT " %" GST_TIME_FORMAT, + GST_TIME_ARGS (start), GST_TIME_ARGS (time)); + gst_segment_set_newsegment (&base_video_codec->state.segment, update, + rate, format, start, stop, time); + + ret = gst_pad_push_event (base_video_codec->srcpad, event); + break; + } + default: + ret = gst_pad_push_event (base_video_codec->srcpad, event); + break; + } +done: + gst_object_unref (base_video_codec); + return ret; + +newseg_wrong_format: + GST_DEBUG_OBJECT (base_video_codec, "received non TIME newsegment"); + gst_event_unref (event); + goto done; + +newseg_wrong_rate: + GST_DEBUG_OBJECT (base_video_codec, "negative rates not supported"); + gst_event_unref (event); + goto done; +} +#endif + + +static GstStateChangeReturn +gst_base_video_codec_change_state (GstElement * element, + GstStateChange transition) +{ + GstBaseVideoCodec *base_video_codec = GST_BASE_VIDEO_CODEC (element); + GstStateChangeReturn ret; + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + gst_base_video_codec_reset (base_video_codec); + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + break; + default: + break; + } + + ret = parent_class->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_base_video_codec_reset (base_video_codec); + break; + case GST_STATE_CHANGE_READY_TO_NULL: + break; + default: + break; + } + + return ret; +} + +#if 0 +guint64 +gst_base_video_codec_get_timestamp (GstBaseVideoCodec * base_video_codec, + int picture_number) +{ + if (picture_number < 0) { + return base_video_codec->timestamp_offset - + (gint64) gst_util_uint64_scale (-picture_number, + base_video_codec->state.fps_d * GST_SECOND, + base_video_codec->state.fps_n); + } else { + return base_video_codec->timestamp_offset + + gst_util_uint64_scale (picture_number, + base_video_codec->state.fps_d * GST_SECOND, + base_video_codec->state.fps_n); + } +} +#endif + +GstVideoFrame * +gst_base_video_codec_new_frame (GstBaseVideoCodec * base_video_codec) +{ + GstVideoFrame *frame; + + frame = g_malloc0 (sizeof (GstVideoFrame)); + + frame->system_frame_number = base_video_codec->system_frame_number; + base_video_codec->system_frame_number++; + + return frame; +} + +void +gst_base_video_codec_free_frame (GstVideoFrame * frame) +{ + if (frame->sink_buffer) { + gst_buffer_unref (frame->sink_buffer); + } +#if 0 + if (frame->src_buffer) { + gst_buffer_unref (frame->src_buffer); + } +#endif + + g_free (frame); +} diff --git a/gst-libs/gst/video/gstbasevideocodec.h b/gst-libs/gst/video/gstbasevideocodec.h new file mode 100644 index 0000000000..b6acf62ee6 --- /dev/null +++ b/gst-libs/gst/video/gstbasevideocodec.h @@ -0,0 +1,150 @@ +/* GStreamer + * Copyright (C) 2008 David Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_BASE_VIDEO_CODEC_H_ +#define _GST_BASE_VIDEO_CODEC_H_ + +#ifndef GST_USE_UNSTABLE_API +#warning "GstBaseVideoCodec is unstable API and may change in future." +#warning "You can define GST_USE_UNSTABLE_API to avoid this warning." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_BASE_VIDEO_CODEC \ + (gst_base_video_codec_get_type()) +#define GST_BASE_VIDEO_CODEC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BASE_VIDEO_CODEC,GstBaseVideoCodec)) +#define GST_BASE_VIDEO_CODEC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BASE_VIDEO_CODEC,GstBaseVideoCodecClass)) +#define GST_BASE_VIDEO_CODEC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_BASE_VIDEO_CODEC,GstBaseVideoCodecClass)) +#define GST_IS_BASE_VIDEO_CODEC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BASE_VIDEO_CODEC)) +#define GST_IS_BASE_VIDEO_CODEC_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_VIDEO_CODEC)) + +/** + * GST_BASE_VIDEO_CODEC_SINK_NAME: + * + * The name of the templates for the sink pad. + */ +#define GST_BASE_VIDEO_CODEC_SINK_NAME "sink" +/** + * GST_BASE_VIDEO_CODEC_SRC_NAME: + * + * The name of the templates for the source pad. + */ +#define GST_BASE_VIDEO_CODEC_SRC_NAME "src" + +/** + * GST_BASE_VIDEO_CODEC_SRC_PAD: + * @obj: base video codec instance + * + * Gives the pointer to the source #GstPad object of the element. + */ +#define GST_BASE_VIDEO_CODEC_SRC_PAD(obj) (((GstBaseVideoCodec *) (obj))->srcpad) + +/** + * GST_BASE_VIDEO_CODEC_SINK_PAD: + * @obj: base video codec instance + * + * Gives the pointer to the sink #GstPad object of the element. + */ +#define GST_BASE_VIDEO_CODEC_SINK_PAD(obj) (((GstBaseVideoCodec *) (obj))->sinkpad) + +/** + * GST_BASE_VIDEO_CODEC_FLOW_NEED_DATA: + * + */ +#define GST_BASE_VIDEO_CODEC_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS + +typedef struct _GstBaseVideoCodec GstBaseVideoCodec; +typedef struct _GstBaseVideoCodecClass GstBaseVideoCodecClass; + +struct _GstBaseVideoCodec +{ + GstElement element; + + /*< private >*/ + GstPad *sinkpad; + GstPad *srcpad; + GstAdapter *input_adapter; + GstAdapter *output_adapter; + +#if 0 + /* FIXME need to move from subclasses */ + GstVideoState state; +#endif + + //int reorder_depth; + + //gboolean have_sync; + //gboolean discont; + //gboolean started; + + //GstVideoFrame *current_frame; + //int distance_from_sync; + + //gboolean sink_clipping; + + //guint64 presentation_frame_number; + guint64 system_frame_number; + + //GstCaps *caps; + //gboolean set_output_caps; + + //GstClockTime buffer_timestamp; + + GstClockTime timestamp_offset; +}; + +struct _GstBaseVideoCodecClass +{ + GstElementClass element_class; + + gboolean (*start) (GstBaseVideoCodec *codec); + gboolean (*stop) (GstBaseVideoCodec *codec); + gboolean (*reset) (GstBaseVideoCodec *codec); + GstFlowReturn (*parse_data) (GstBaseVideoCodec *codec, gboolean at_eos); + int (*scan_for_sync) (GstAdapter *adapter, gboolean at_eos, + int offset, int n); + GstFlowReturn (*shape_output) (GstBaseVideoCodec *codec, GstVideoFrame *frame); + GstCaps *(*get_caps) (GstBaseVideoCodec *codec); + +}; + +GType gst_base_video_codec_get_type (void); + +#if 0 +guint64 gst_base_video_codec_get_timestamp (GstBaseVideoCodec *codec, + int picture_number); +#endif + +GstVideoFrame * gst_base_video_codec_new_frame (GstBaseVideoCodec *base_video_codec); +void gst_base_video_codec_free_frame (GstVideoFrame *frame); + + +G_END_DECLS + +#endif + diff --git a/gst-libs/gst/video/gstbasevideodecoder.c b/gst-libs/gst/video/gstbasevideodecoder.c new file mode 100644 index 0000000000..b1a97eb432 --- /dev/null +++ b/gst-libs/gst/video/gstbasevideodecoder.c @@ -0,0 +1,1495 @@ +/* GStreamer + * Copyright (C) 2008 David Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstbasevideodecoder.h" + +#include + +GST_DEBUG_CATEGORY (basevideodecoder_debug); +#define GST_CAT_DEFAULT basevideodecoder_debug + +static void gst_base_video_decoder_finalize (GObject * object); + +static gboolean gst_base_video_decoder_sink_setcaps (GstPad * pad, + GstCaps * caps); +static gboolean gst_base_video_decoder_sink_event (GstPad * pad, + GstEvent * event); +static gboolean gst_base_video_decoder_src_event (GstPad * pad, + GstEvent * event); +static GstFlowReturn gst_base_video_decoder_chain (GstPad * pad, + GstBuffer * buf); +static gboolean gst_base_video_decoder_sink_query (GstPad * pad, + GstQuery * query); +//static GstFlowReturn gst_base_video_decoder_process (GstBaseVideoDecoder *base_video_decoder); +static GstStateChangeReturn gst_base_video_decoder_change_state (GstElement * + element, GstStateChange transition); +static const GstQueryType *gst_base_video_decoder_get_query_types (GstPad * + pad); +static gboolean gst_base_video_decoder_src_query (GstPad * pad, + GstQuery * query); +static gboolean gst_base_video_decoder_src_convert (GstPad * pad, + GstFormat src_format, gint64 src_value, GstFormat * dest_format, + gint64 * dest_value); +static void gst_base_video_decoder_reset (GstBaseVideoDecoder * + base_video_decoder); + +static GstFlowReturn +gst_base_video_decoder_have_frame_2 (GstBaseVideoDecoder * base_video_decoder); + +static guint64 +gst_base_video_decoder_get_timestamp (GstBaseVideoDecoder * base_video_decoder, + int picture_number); +static guint64 +gst_base_video_decoder_get_field_timestamp (GstBaseVideoDecoder * + base_video_decoder, int field_offset); +static guint64 gst_base_video_decoder_get_field_duration (GstBaseVideoDecoder * + base_video_decoder, int n_fields); +static GstVideoFrame *gst_base_video_decoder_new_frame (GstBaseVideoDecoder * + base_video_decoder); +static void gst_base_video_decoder_free_frame (GstVideoFrame * frame); + +GST_BOILERPLATE (GstBaseVideoDecoder, gst_base_video_decoder, + GstBaseVideoCodec, GST_TYPE_BASE_VIDEO_CODEC); + +static void +gst_base_video_decoder_base_init (gpointer g_class) +{ + GST_DEBUG_CATEGORY_INIT (basevideodecoder_debug, "basevideodecoder", 0, + "Base Video Decoder"); + +} + +static void +gst_base_video_decoder_class_init (GstBaseVideoDecoderClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = G_OBJECT_CLASS (klass); + gstelement_class = GST_ELEMENT_CLASS (klass); + + gobject_class->finalize = gst_base_video_decoder_finalize; + + gstelement_class->change_state = gst_base_video_decoder_change_state; + + parent_class = g_type_class_peek_parent (klass); +} + +static void +gst_base_video_decoder_init (GstBaseVideoDecoder * base_video_decoder, + GstBaseVideoDecoderClass * klass) +{ + GstPad *pad; + + GST_DEBUG ("gst_base_video_decoder_init"); + + pad = GST_BASE_VIDEO_CODEC_SINK_PAD (base_video_decoder); + + gst_pad_set_chain_function (pad, gst_base_video_decoder_chain); + gst_pad_set_event_function (pad, gst_base_video_decoder_sink_event); + gst_pad_set_setcaps_function (pad, gst_base_video_decoder_sink_setcaps); + gst_pad_set_query_function (pad, gst_base_video_decoder_sink_query); + + pad = GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder); + + gst_pad_set_event_function (pad, gst_base_video_decoder_src_event); + gst_pad_set_query_type_function (pad, gst_base_video_decoder_get_query_types); + gst_pad_set_query_function (pad, gst_base_video_decoder_src_query); + gst_pad_use_fixed_caps (pad); + + base_video_decoder->input_adapter = gst_adapter_new (); + base_video_decoder->output_adapter = gst_adapter_new (); + + gst_segment_init (&base_video_decoder->segment, GST_FORMAT_TIME); + gst_base_video_decoder_reset (base_video_decoder); + + base_video_decoder->current_frame = + gst_base_video_decoder_new_frame (base_video_decoder); + + base_video_decoder->sink_clipping = TRUE; +} + +static gboolean +gst_base_video_decoder_sink_setcaps (GstPad * pad, GstCaps * caps) +{ + GstBaseVideoDecoder *base_video_decoder; + GstBaseVideoDecoderClass *base_video_decoder_class; + GstStructure *structure; + const GValue *codec_data; + GstVideoState *state; + gboolean ret = TRUE; + + base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); + base_video_decoder_class = + GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); + + GST_DEBUG ("setcaps %" GST_PTR_FORMAT, caps); + + state = &base_video_decoder->state; + + if (state->codec_data) { + gst_buffer_unref (state->codec_data); + } + memset (state, 0, sizeof (GstVideoState)); + + structure = gst_caps_get_structure (caps, 0); + + gst_video_format_parse_caps (caps, NULL, &state->width, &state->height); + gst_video_parse_caps_framerate (caps, &state->fps_n, &state->fps_d); + gst_video_parse_caps_pixel_aspect_ratio (caps, &state->par_n, &state->par_d); + +#if 0 + /* requires 0.10.23 */ + state->have_interlaced = + gst_video_format_parse_caps_interlaced (caps, &state->interlaced); +#else + state->have_interlaced = gst_structure_get_boolean (structure, + "interlaced", &state->interlaced); +#endif + + codec_data = gst_structure_get_value (structure, "codec_data"); + if (codec_data && G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) { + state->codec_data = gst_value_get_buffer (codec_data); + } + + if (base_video_decoder_class->start) { + ret = base_video_decoder_class->start (base_video_decoder); + } + + g_object_unref (base_video_decoder); + + return ret; +} + +static void +gst_base_video_decoder_finalize (GObject * object) +{ + GstBaseVideoDecoder *base_video_decoder; + GstBaseVideoDecoderClass *base_video_decoder_class; + + g_return_if_fail (GST_IS_BASE_VIDEO_DECODER (object)); + base_video_decoder = GST_BASE_VIDEO_DECODER (object); + base_video_decoder_class = GST_BASE_VIDEO_DECODER_GET_CLASS (object); + + gst_base_video_decoder_reset (base_video_decoder); + + if (base_video_decoder->input_adapter) { + g_object_unref (base_video_decoder->input_adapter); + base_video_decoder->input_adapter = NULL; + } + if (base_video_decoder->output_adapter) { + g_object_unref (base_video_decoder->output_adapter); + base_video_decoder->output_adapter = NULL; + } + + GST_DEBUG_OBJECT (object, "finalize"); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static gboolean +gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event) +{ + GstBaseVideoDecoder *base_video_decoder; + GstBaseVideoDecoderClass *base_video_decoder_class; + gboolean ret = FALSE; + + base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); + base_video_decoder_class = + GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_EOS: + { + if (!base_video_decoder->packetized) { + GstFlowReturn flow_ret; + + do { + flow_ret = + base_video_decoder_class->parse_data (base_video_decoder, TRUE); + } while (flow_ret == GST_FLOW_OK); + } + + if (base_video_decoder_class->finish) { + base_video_decoder_class->finish (base_video_decoder); + } + + ret = + gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), + event); + } + break; + case GST_EVENT_NEWSEGMENT: + { + gboolean update; + double rate; + double applied_rate; + GstFormat format; + gint64 start; + gint64 stop; + gint64 position; + GstSegment *segment = &base_video_decoder->segment; + + gst_event_parse_new_segment_full (event, &update, &rate, + &applied_rate, &format, &start, &stop, &position); + + if (format != GST_FORMAT_TIME) + goto newseg_wrong_format; + + if (!update) { + gst_base_video_decoder_reset (base_video_decoder); + } + + base_video_decoder->timestamp_offset = start; + + gst_segment_set_newsegment_full (segment, + update, rate, applied_rate, format, start, stop, position); + base_video_decoder->have_segment = TRUE; + + GST_DEBUG_OBJECT (base_video_decoder, + "new segment: format %d rate %g start %" GST_TIME_FORMAT + " stop %" GST_TIME_FORMAT + " position %" GST_TIME_FORMAT + " update %d", + format, rate, + GST_TIME_ARGS (segment->start), + GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time), update); + + ret = + gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), + event); + } + break; + case GST_EVENT_FLUSH_STOP:{ + GST_OBJECT_LOCK (base_video_decoder); + base_video_decoder->earliest_time = GST_CLOCK_TIME_NONE; + base_video_decoder->proportion = 0.5; + GST_OBJECT_UNLOCK (base_video_decoder); + } + default: + /* FIXME this changes the order of events */ + ret = + gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), + event); + break; + } + +done: + gst_object_unref (base_video_decoder); + return ret; + +newseg_wrong_format: + { + GST_DEBUG_OBJECT (base_video_decoder, "received non TIME newsegment"); + gst_event_unref (event); + goto done; + } +} + +static gboolean +gst_base_video_decoder_src_event (GstPad * pad, GstEvent * event) +{ + GstBaseVideoDecoder *base_video_decoder; + gboolean res = FALSE; + + base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_SEEK: + { + GstFormat format, tformat; + gdouble rate; + GstEvent *real_seek; + GstSeekFlags flags; + GstSeekType cur_type, stop_type; + gint64 cur, stop; + gint64 tcur, tstop; + + GST_DEBUG ("seek event"); + + gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, + &cur, &stop_type, &stop); + gst_event_unref (event); + + tformat = GST_FORMAT_TIME; + res = + gst_base_video_decoder_src_convert (pad, format, cur, &tformat, + &tcur); + if (!res) + goto convert_error; + res = + gst_base_video_decoder_src_convert (pad, format, stop, &tformat, + &tstop); + if (!res) + goto convert_error; + + real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME, + flags, cur_type, tcur, stop_type, tstop); + + res = + gst_pad_push_event (GST_BASE_VIDEO_CODEC_SINK_PAD + (base_video_decoder), real_seek); + + break; + } + case GST_EVENT_QOS: + { + gdouble proportion; + GstClockTimeDiff diff; + GstClockTime timestamp; + GstClockTime duration; + + gst_event_parse_qos (event, &proportion, &diff, ×tamp); + + GST_OBJECT_LOCK (base_video_decoder); + base_video_decoder->proportion = proportion; + if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) { + if (G_UNLIKELY (diff > 0)) { + if (base_video_decoder->state.fps_n > 0) + duration = + gst_util_uint64_scale (GST_SECOND, + base_video_decoder->state.fps_d, + base_video_decoder->state.fps_n); + else + duration = 0; + base_video_decoder->earliest_time = timestamp + 2 * diff + duration; + } else { + base_video_decoder->earliest_time = timestamp + diff; + } + } else { + base_video_decoder->earliest_time = GST_CLOCK_TIME_NONE; + } + GST_OBJECT_UNLOCK (base_video_decoder); + + GST_DEBUG_OBJECT (base_video_decoder, + "got QoS %" GST_TIME_FORMAT ", %" G_GINT64_FORMAT ", %g", + GST_TIME_ARGS (timestamp), diff, proportion); + + res = + gst_pad_push_event (GST_BASE_VIDEO_CODEC_SINK_PAD + (base_video_decoder), event); + break; + } + default: + res = + gst_pad_push_event (GST_BASE_VIDEO_CODEC_SINK_PAD + (base_video_decoder), event); + break; + } +done: + gst_object_unref (base_video_decoder); + return res; + +convert_error: + GST_DEBUG_OBJECT (base_video_decoder, "could not convert format"); + goto done; +} + + +#if 0 +static gboolean +gst_base_video_decoder_sink_convert (GstPad * pad, + GstFormat src_format, gint64 src_value, + GstFormat * dest_format, gint64 * dest_value) +{ + gboolean res = TRUE; + GstBaseVideoDecoder *enc; + + if (src_format == *dest_format) { + *dest_value = src_value; + return TRUE; + } + + enc = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); + + /* FIXME: check if we are in a decoding state */ + + switch (src_format) { + case GST_FORMAT_BYTES: + switch (*dest_format) { +#if 0 + case GST_FORMAT_DEFAULT: + *dest_value = gst_util_uint64_scale_int (src_value, 1, + enc->bytes_per_picture); + break; +#endif + case GST_FORMAT_TIME: + /* seems like a rather silly conversion, implement me if you like */ + default: + res = FALSE; + } + break; + case GST_FORMAT_DEFAULT: + switch (*dest_format) { + case GST_FORMAT_TIME: + *dest_value = gst_util_uint64_scale (src_value, + GST_SECOND * enc->fps_d, enc->fps_n); + break; +#if 0 + case GST_FORMAT_BYTES: + *dest_value = gst_util_uint64_scale_int (src_value, + enc->bytes_per_picture, 1); + break; +#endif + default: + res = FALSE; + } + break; + default: + res = FALSE; + break; + } +} +#endif + +static gboolean +gst_base_video_decoder_src_convert (GstPad * pad, + GstFormat src_format, gint64 src_value, + GstFormat * dest_format, gint64 * dest_value) +{ + gboolean res = TRUE; + GstBaseVideoDecoder *enc; + + if (src_format == *dest_format) { + *dest_value = src_value; + return TRUE; + } + + enc = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); + + /* FIXME: check if we are in a encoding state */ + + GST_DEBUG ("src convert"); + switch (src_format) { +#if 0 + case GST_FORMAT_DEFAULT: + switch (*dest_format) { + case GST_FORMAT_TIME: + *dest_value = gst_util_uint64_scale (granulepos_to_frame (src_value), + enc->fps_d * GST_SECOND, enc->fps_n); + break; + default: + res = FALSE; + } + break; + case GST_FORMAT_TIME: + switch (*dest_format) { + case GST_FORMAT_DEFAULT: + { + *dest_value = gst_util_uint64_scale (src_value, + enc->fps_n, enc->fps_d * GST_SECOND); + break; + } + default: + res = FALSE; + break; + } + break; +#endif + default: + res = FALSE; + break; + } + + gst_object_unref (enc); + + return res; +} + +static const GstQueryType * +gst_base_video_decoder_get_query_types (GstPad * pad) +{ + static const GstQueryType query_types[] = { + GST_QUERY_POSITION, + GST_QUERY_DURATION, + GST_QUERY_CONVERT, + 0 + }; + + return query_types; +} + +static gboolean +gst_base_video_decoder_src_query (GstPad * pad, GstQuery * query) +{ + GstBaseVideoDecoder *enc; + gboolean res = TRUE; + + enc = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); + + switch GST_QUERY_TYPE + (query) { + case GST_QUERY_POSITION: + { + GstFormat format; + gint64 time; + + gst_query_parse_position (query, &format, NULL); + GST_DEBUG ("query in format %d", format); + + if (format != GST_FORMAT_TIME) { + goto error; + } + + time = enc->last_timestamp; + time = gst_segment_to_stream_time (&enc->segment, GST_FORMAT_TIME, time); + + gst_query_set_position (query, format, time); + + res = TRUE; + + break; + } + case GST_QUERY_DURATION: + { + res = gst_pad_peer_query (enc->base_video_codec.sinkpad, query); + break; + } + case GST_QUERY_CONVERT: + { + GstFormat src_fmt, dest_fmt; + gint64 src_val, dest_val; + + GST_DEBUG ("convert query"); + + gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); + res = + gst_base_video_decoder_src_convert (pad, src_fmt, src_val, &dest_fmt, + &dest_val); + if (!res) + goto error; + gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); + break; + } + default: + res = gst_pad_query_default (pad, query); + } + gst_object_unref (enc); + return res; + +error: + GST_ERROR_OBJECT (enc, "query failed"); + gst_object_unref (enc); + return res; +} + +static gboolean +gst_base_video_decoder_sink_query (GstPad * pad, GstQuery * query) +{ + GstBaseVideoDecoder *base_video_decoder; + gboolean res = FALSE; + + base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); + + GST_DEBUG_OBJECT (base_video_decoder, "sink query fps=%d/%d", + base_video_decoder->state.fps_n, base_video_decoder->state.fps_d); + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CONVERT: + { + GstFormat src_fmt, dest_fmt; + gint64 src_val, dest_val; + + gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); + res = gst_base_video_rawvideo_convert (&base_video_decoder->state, + src_fmt, src_val, &dest_fmt, &dest_val); + if (!res) + goto error; + gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); + break; + } + default: + res = gst_pad_query_default (pad, query); + break; + } +done: + gst_object_unref (base_video_decoder); + + return res; +error: + GST_DEBUG_OBJECT (base_video_decoder, "query failed"); + goto done; +} + + +#if 0 +static gboolean +gst_pad_is_negotiated (GstPad * pad) +{ + GstCaps *caps; + + g_return_val_if_fail (pad != NULL, FALSE); + + caps = gst_pad_get_negotiated_caps (pad); + if (caps) { + gst_caps_unref (caps); + return TRUE; + } + + return FALSE; +} +#endif + +typedef struct _Timestamp Timestamp; +struct _Timestamp +{ + guint64 offset; + GstClockTime timestamp; + GstClockTime duration; +}; + +static void +gst_base_video_decoder_add_timestamp (GstBaseVideoDecoder * base_video_decoder, + GstBuffer * buffer) +{ + Timestamp *ts; + + ts = g_malloc (sizeof (Timestamp)); + + GST_DEBUG ("adding timestamp %" GST_TIME_FORMAT " %" GST_TIME_FORMAT, + GST_TIME_ARGS (base_video_decoder->input_offset), + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); + + ts->offset = base_video_decoder->input_offset; + ts->timestamp = GST_BUFFER_TIMESTAMP (buffer); + ts->duration = GST_BUFFER_DURATION (buffer); + + base_video_decoder->timestamps = + g_list_append (base_video_decoder->timestamps, ts); +} + +static void +gst_base_video_decoder_get_timestamp_at_offset (GstBaseVideoDecoder * + base_video_decoder, guint64 offset, GstClockTime * timestamp, + GstClockTime * duration) +{ + Timestamp *ts; + GList *g; + + *timestamp = GST_CLOCK_TIME_NONE; + *duration = GST_CLOCK_TIME_NONE; + + g = base_video_decoder->timestamps; + while (g) { + ts = g->data; + if (ts->offset <= offset) { + *timestamp = ts->timestamp; + *duration = ts->duration; + g_free (ts); + g = g_list_next (g); + base_video_decoder->timestamps = + g_list_remove (base_video_decoder->timestamps, ts); + } else { + break; + } + } + + GST_DEBUG ("got timestamp %" GST_TIME_FORMAT " %" GST_TIME_FORMAT, + GST_TIME_ARGS (offset), GST_TIME_ARGS (*timestamp)); +} + +static void +gst_base_video_decoder_reset (GstBaseVideoDecoder * base_video_decoder) +{ + GstBaseVideoDecoderClass *base_video_decoder_class; + GList *g; + + base_video_decoder_class = + GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); + + GST_DEBUG ("reset"); + + base_video_decoder->started = FALSE; + + base_video_decoder->discont = TRUE; + base_video_decoder->have_sync = FALSE; + + base_video_decoder->timestamp_offset = GST_CLOCK_TIME_NONE; + base_video_decoder->system_frame_number = 0; + base_video_decoder->presentation_frame_number = 0; + base_video_decoder->base_picture_number = 0; + base_video_decoder->last_timestamp = GST_CLOCK_TIME_NONE; + + base_video_decoder->input_offset = 0; + base_video_decoder->frame_offset = 0; + + /* This function could be called from finalize() */ + if (base_video_decoder->input_adapter) { + gst_adapter_clear (base_video_decoder->input_adapter); + } + if (base_video_decoder->output_adapter) { + gst_adapter_clear (base_video_decoder->output_adapter); + } + + if (base_video_decoder->caps) { + gst_caps_unref (base_video_decoder->caps); + base_video_decoder->caps = NULL; + } + //gst_segment_init (&base_video_decoder->segment, GST_FORMAT_TIME); + + if (base_video_decoder->current_frame) { + gst_base_video_decoder_free_frame (base_video_decoder->current_frame); + base_video_decoder->current_frame = NULL; + } + + base_video_decoder->have_src_caps = FALSE; + + for (g = g_list_first (base_video_decoder->frames); g; g = g_list_next (g)) { + GstVideoFrame *frame = g->data; + gst_base_video_decoder_free_frame (frame); + } + g_list_free (base_video_decoder->frames); + base_video_decoder->frames = NULL; + + GST_OBJECT_LOCK (base_video_decoder); + base_video_decoder->earliest_time = GST_CLOCK_TIME_NONE; + base_video_decoder->proportion = 0.5; + GST_OBJECT_UNLOCK (base_video_decoder); + + if (base_video_decoder_class->reset) { + base_video_decoder_class->reset (base_video_decoder); + } +} + +static GstFlowReturn +gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf) +{ + GstBaseVideoDecoder *base_video_decoder; + GstBaseVideoDecoderClass *klass; + GstFlowReturn ret; + + GST_DEBUG ("chain %" GST_TIME_FORMAT " duration %" GST_TIME_FORMAT, + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), + GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); + +#if 0 + /* requiring the pad to be negotiated makes it impossible to use + * oggdemux or filesrc ! decoder */ + if (!gst_pad_is_negotiated (pad)) { + GST_DEBUG ("not negotiated"); + return GST_FLOW_NOT_NEGOTIATED; + } +#endif + + base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); + klass = GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); + + GST_DEBUG_OBJECT (base_video_decoder, "chain"); + + if (!base_video_decoder->have_segment) { + GstEvent *event; + GstFlowReturn ret; + + GST_WARNING + ("Received buffer without a new-segment. Assuming timestamps start from 0."); + + gst_segment_set_newsegment_full (&base_video_decoder->segment, + FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0, GST_CLOCK_TIME_NONE, 0); + base_video_decoder->have_segment = TRUE; + + event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, + GST_CLOCK_TIME_NONE, 0); + + ret = + gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), + event); + if (!ret) { + GST_ERROR ("new segment event ret=%d", ret); + return GST_FLOW_ERROR; + } + } + + if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) { + GST_DEBUG_OBJECT (base_video_decoder, "received DISCONT buffer"); + gst_base_video_decoder_reset (base_video_decoder); + } + + if (!base_video_decoder->started) { + klass->start (base_video_decoder); + base_video_decoder->started = TRUE; + } + + if (base_video_decoder->current_frame == NULL) { + base_video_decoder->current_frame = + gst_base_video_decoder_new_frame (base_video_decoder); + } + + if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { + gst_base_video_decoder_add_timestamp (base_video_decoder, buf); + } + base_video_decoder->input_offset += GST_BUFFER_SIZE (buf); + +#if 0 + if (base_video_decoder->timestamp_offset == GST_CLOCK_TIME_NONE && + GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE) { + GST_DEBUG ("got new offset %" GST_TIME_FORMAT, + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); + base_video_decoder->timestamp_offset = GST_BUFFER_TIMESTAMP (buf); + } +#endif + + if (base_video_decoder->packetized) { + base_video_decoder->current_frame->sink_buffer = buf; + + ret = gst_base_video_decoder_have_frame_2 (base_video_decoder); + } else { + + gst_adapter_push (base_video_decoder->input_adapter, buf); + + if (!base_video_decoder->have_sync) { + int n, m; + + GST_DEBUG ("no sync, scanning"); + + n = gst_adapter_available (base_video_decoder->input_adapter); + m = klass->scan_for_sync (base_video_decoder, FALSE, 0, n); + if (m == -1) { + gst_object_unref (base_video_decoder); + return GST_FLOW_OK; + } + + if (m < 0) { + g_warning ("subclass returned negative scan %d", m); + } + + if (m >= n) { + GST_ERROR ("subclass scanned past end %d >= %d", m, n); + } + + gst_adapter_flush (base_video_decoder->input_adapter, m); + + if (m < n) { + GST_DEBUG ("found possible sync after %d bytes (of %d)", m, n); + + /* this is only "maybe" sync */ + base_video_decoder->have_sync = TRUE; + } + + if (!base_video_decoder->have_sync) { + gst_object_unref (base_video_decoder); + return GST_FLOW_OK; + } + } + + do { + ret = klass->parse_data (base_video_decoder, FALSE); + } while (ret == GST_FLOW_OK); + + if (ret == GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA) { + gst_object_unref (base_video_decoder); + return GST_FLOW_OK; + } + } + + gst_object_unref (base_video_decoder); + return ret; +} + +static GstStateChangeReturn +gst_base_video_decoder_change_state (GstElement * element, + GstStateChange transition) +{ + GstBaseVideoDecoder *base_video_decoder; + GstBaseVideoDecoderClass *base_video_decoder_class; + GstStateChangeReturn ret; + + base_video_decoder = GST_BASE_VIDEO_DECODER (element); + base_video_decoder_class = GST_BASE_VIDEO_DECODER_GET_CLASS (element); + + switch (transition) { + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + if (base_video_decoder_class->stop) { + base_video_decoder_class->stop (base_video_decoder); + } + break; + default: + break; + } + + return ret; +} + +static void +gst_base_video_decoder_free_frame (GstVideoFrame * frame) +{ + g_return_if_fail (frame != NULL); + + if (frame->sink_buffer) { + gst_buffer_unref (frame->sink_buffer); + } + if (frame->src_buffer) { + gst_buffer_unref (frame->src_buffer); + } + + g_free (frame); +} + +static GstVideoFrame * +gst_base_video_decoder_new_frame (GstBaseVideoDecoder * base_video_decoder) +{ + GstVideoFrame *frame; + + frame = g_malloc0 (sizeof (GstVideoFrame)); + + frame->system_frame_number = base_video_decoder->system_frame_number; + base_video_decoder->system_frame_number++; + + frame->decode_frame_number = frame->system_frame_number - + base_video_decoder->reorder_depth; + + frame->decode_timestamp = GST_CLOCK_TIME_NONE; + frame->presentation_timestamp = GST_CLOCK_TIME_NONE; + frame->presentation_duration = GST_CLOCK_TIME_NONE; + frame->n_fields = 2; + + return frame; +} + +GstFlowReturn +gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder, + GstVideoFrame * frame) +{ + GstBaseVideoDecoderClass *base_video_decoder_class; + GstBuffer *src_buffer; + + GST_DEBUG ("finish frame"); + + base_video_decoder_class = + GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); + + GST_DEBUG ("finish frame sync=%d pts=%" GST_TIME_FORMAT, frame->is_sync_point, + GST_TIME_ARGS (frame->presentation_timestamp)); + + if (GST_CLOCK_TIME_IS_VALID (frame->presentation_timestamp)) { + if (frame->presentation_timestamp != base_video_decoder->timestamp_offset) { + GST_DEBUG ("sync timestamp %" GST_TIME_FORMAT " diff %" GST_TIME_FORMAT, + GST_TIME_ARGS (frame->presentation_timestamp), + GST_TIME_ARGS (frame->presentation_timestamp - + base_video_decoder->segment.start)); + base_video_decoder->timestamp_offset = frame->presentation_timestamp; + base_video_decoder->field_index = 0; + } else { + /* This case is for one initial timestamp and no others, e.g., + * filesrc ! decoder ! xvimagesink */ + GST_WARNING ("sync timestamp didn't change, ignoring"); + frame->presentation_timestamp = GST_CLOCK_TIME_NONE; + } + } else { + if (frame->is_sync_point) { + GST_WARNING ("sync point doesn't have timestamp"); + if (!GST_CLOCK_TIME_IS_VALID (base_video_decoder->timestamp_offset)) { + GST_WARNING + ("No base timestamp. Assuming frames start at segment start"); + base_video_decoder->timestamp_offset = + base_video_decoder->segment.start; + base_video_decoder->field_index = 0; + } + } + } + frame->field_index = base_video_decoder->field_index; + base_video_decoder->field_index += frame->n_fields; + + if (frame->presentation_timestamp == GST_CLOCK_TIME_NONE) { + frame->presentation_timestamp = + gst_base_video_decoder_get_field_timestamp (base_video_decoder, + frame->field_index); + frame->presentation_duration = GST_CLOCK_TIME_NONE; + frame->decode_timestamp = + gst_base_video_decoder_get_timestamp (base_video_decoder, + frame->decode_frame_number); + } + if (frame->presentation_duration == GST_CLOCK_TIME_NONE) { + frame->presentation_duration = + gst_base_video_decoder_get_field_duration (base_video_decoder, + frame->n_fields); + } + + if (GST_CLOCK_TIME_IS_VALID (base_video_decoder->last_timestamp)) { + if (frame->presentation_timestamp < base_video_decoder->last_timestamp) { + GST_WARNING ("decreasing timestamp (%" GST_TIME_FORMAT " < %" + GST_TIME_FORMAT ")", GST_TIME_ARGS (frame->presentation_timestamp), + GST_TIME_ARGS (base_video_decoder->last_timestamp)); + } + } + base_video_decoder->last_timestamp = frame->presentation_timestamp; + + GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_BUFFER_FLAG_DELTA_UNIT); + if (base_video_decoder->state.interlaced) { +#ifndef GST_VIDEO_BUFFER_TFF +#define GST_VIDEO_BUFFER_TFF (GST_MINI_OBJECT_FLAG_LAST << 5) +#endif +#ifndef GST_VIDEO_BUFFER_RFF +#define GST_VIDEO_BUFFER_RFF (GST_MINI_OBJECT_FLAG_LAST << 6) +#endif +#ifndef GST_VIDEO_BUFFER_ONEFIELD +#define GST_VIDEO_BUFFER_ONEFIELD (GST_MINI_OBJECT_FLAG_LAST << 7) +#endif + int tff = base_video_decoder->state.top_field_first; + + if (frame->field_index & 1) { + tff ^= 1; + } + if (tff) { + GST_BUFFER_FLAG_SET (frame->src_buffer, GST_VIDEO_BUFFER_TFF); + } else { + GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_VIDEO_BUFFER_TFF); + } + GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_VIDEO_BUFFER_RFF); + GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_VIDEO_BUFFER_ONEFIELD); + if (frame->n_fields == 3) { + GST_BUFFER_FLAG_SET (frame->src_buffer, GST_VIDEO_BUFFER_RFF); + } else if (frame->n_fields == 1) { + GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_VIDEO_BUFFER_ONEFIELD); + } + } + if (base_video_decoder->discont) { + GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_BUFFER_FLAG_DISCONT); + base_video_decoder->discont = FALSE; + } + + GST_BUFFER_TIMESTAMP (frame->src_buffer) = frame->presentation_timestamp; + GST_BUFFER_DURATION (frame->src_buffer) = frame->presentation_duration; + GST_BUFFER_OFFSET (frame->src_buffer) = GST_BUFFER_OFFSET_NONE; + GST_BUFFER_OFFSET_END (frame->src_buffer) = GST_BUFFER_OFFSET_NONE; + + GST_DEBUG ("pushing frame %" GST_TIME_FORMAT, + GST_TIME_ARGS (frame->presentation_timestamp)); + + base_video_decoder->frames = + g_list_remove (base_video_decoder->frames, frame); + + gst_base_video_decoder_set_src_caps (base_video_decoder); + + src_buffer = frame->src_buffer; + frame->src_buffer = NULL; + + gst_base_video_decoder_free_frame (frame); + + if (base_video_decoder->sink_clipping) { + gint64 start = GST_BUFFER_TIMESTAMP (src_buffer); + gint64 stop = GST_BUFFER_TIMESTAMP (src_buffer) + + GST_BUFFER_DURATION (src_buffer); + + if (gst_segment_clip (&base_video_decoder->segment, GST_FORMAT_TIME, + start, stop, &start, &stop)) { + GST_BUFFER_TIMESTAMP (src_buffer) = start; + GST_BUFFER_DURATION (src_buffer) = stop - start; + GST_DEBUG ("accepting buffer inside segment: %" GST_TIME_FORMAT + " %" GST_TIME_FORMAT + " seg %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT + " time %" GST_TIME_FORMAT, + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer)), + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer) + + GST_BUFFER_DURATION (src_buffer)), + GST_TIME_ARGS (base_video_decoder->segment.start), + GST_TIME_ARGS (base_video_decoder->segment.stop), + GST_TIME_ARGS (base_video_decoder->segment.time)); + } else { + GST_DEBUG ("dropping buffer outside segment: %" GST_TIME_FORMAT + " %" GST_TIME_FORMAT + " seg %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT + " time %" GST_TIME_FORMAT, + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer)), + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer) + + GST_BUFFER_DURATION (src_buffer)), + GST_TIME_ARGS (base_video_decoder->segment.start), + GST_TIME_ARGS (base_video_decoder->segment.stop), + GST_TIME_ARGS (base_video_decoder->segment.time)); + gst_buffer_unref (src_buffer); + return GST_FLOW_OK; + } + } + + return gst_pad_push (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), + src_buffer); +} + +GstFlowReturn +gst_base_video_decoder_skip_frame (GstBaseVideoDecoder * base_video_decoder, + GstVideoFrame * frame) +{ + GstBaseVideoDecoderClass *base_video_decoder_class; + + GST_DEBUG ("finish frame"); + + base_video_decoder_class = + GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); + + GST_DEBUG ("finish frame sync=%d pts=%" GST_TIME_FORMAT, frame->is_sync_point, + GST_TIME_ARGS (frame->presentation_timestamp)); + + if (GST_CLOCK_TIME_IS_VALID (frame->presentation_timestamp)) { + if (frame->presentation_timestamp != base_video_decoder->timestamp_offset) { + GST_DEBUG ("sync timestamp %" GST_TIME_FORMAT " diff %" GST_TIME_FORMAT, + GST_TIME_ARGS (frame->presentation_timestamp), + GST_TIME_ARGS (frame->presentation_timestamp - + base_video_decoder->segment.start)); + base_video_decoder->timestamp_offset = frame->presentation_timestamp; + base_video_decoder->field_index = 0; + } else { + /* This case is for one initial timestamp and no others, e.g., + * filesrc ! decoder ! xvimagesink */ + GST_WARNING ("sync timestamp didn't change, ignoring"); + frame->presentation_timestamp = GST_CLOCK_TIME_NONE; + } + } else { + if (frame->is_sync_point) { + GST_WARNING ("sync point doesn't have timestamp"); + if (GST_CLOCK_TIME_IS_VALID (base_video_decoder->timestamp_offset)) { + GST_WARNING + ("No base timestamp. Assuming frames start at segment start"); + base_video_decoder->timestamp_offset = + base_video_decoder->segment.start; + base_video_decoder->field_index = 0; + } + } + } + frame->field_index = base_video_decoder->field_index; + base_video_decoder->field_index += frame->n_fields; + + if (frame->presentation_timestamp == GST_CLOCK_TIME_NONE) { + frame->presentation_timestamp = + gst_base_video_decoder_get_field_timestamp (base_video_decoder, + frame->field_index); + frame->presentation_duration = GST_CLOCK_TIME_NONE; + frame->decode_timestamp = + gst_base_video_decoder_get_timestamp (base_video_decoder, + frame->decode_frame_number); + } + if (frame->presentation_duration == GST_CLOCK_TIME_NONE) { + frame->presentation_duration = + gst_base_video_decoder_get_field_duration (base_video_decoder, + frame->n_fields); + } + + base_video_decoder->last_timestamp = frame->presentation_timestamp; + + GST_DEBUG ("skipping frame %" GST_TIME_FORMAT, + GST_TIME_ARGS (frame->presentation_timestamp)); + + base_video_decoder->frames = + g_list_remove (base_video_decoder->frames, frame); + + gst_base_video_decoder_free_frame (frame); + + return GST_FLOW_OK; +} + +int +gst_base_video_decoder_get_height (GstBaseVideoDecoder * base_video_decoder) +{ + return base_video_decoder->state.height; +} + +int +gst_base_video_decoder_get_width (GstBaseVideoDecoder * base_video_decoder) +{ + return base_video_decoder->state.width; +} + +GstFlowReturn +gst_base_video_decoder_end_of_stream (GstBaseVideoDecoder * base_video_decoder, + GstBuffer * buffer) +{ + + if (base_video_decoder->frames) { + GST_DEBUG ("EOS with frames left over"); + } + + return gst_pad_push (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), + buffer); +} + +void +gst_base_video_decoder_add_to_frame (GstBaseVideoDecoder * base_video_decoder, + int n_bytes) +{ + GstBuffer *buf; + + GST_DEBUG ("add to frame"); + + if (n_bytes == 0) + return; + + if (gst_adapter_available (base_video_decoder->output_adapter) == 0) { + base_video_decoder->frame_offset = base_video_decoder->input_offset - + gst_adapter_available (base_video_decoder->input_adapter); + } + buf = gst_adapter_take_buffer (base_video_decoder->input_adapter, n_bytes); + + gst_adapter_push (base_video_decoder->output_adapter, buf); +} + +static guint64 +gst_base_video_decoder_get_timestamp (GstBaseVideoDecoder * base_video_decoder, + int picture_number) +{ + if (base_video_decoder->state.fps_d == 0) { + return -1; + } + if (picture_number < base_video_decoder->base_picture_number) { + return base_video_decoder->timestamp_offset - + (gint64) gst_util_uint64_scale (base_video_decoder->base_picture_number + - picture_number, base_video_decoder->state.fps_d * GST_SECOND, + base_video_decoder->state.fps_n); + } else { + return base_video_decoder->timestamp_offset + + gst_util_uint64_scale (picture_number - + base_video_decoder->base_picture_number, + base_video_decoder->state.fps_d * GST_SECOND, + base_video_decoder->state.fps_n); + } +} + +static guint64 +gst_base_video_decoder_get_field_timestamp (GstBaseVideoDecoder * + base_video_decoder, int field_offset) +{ + if (base_video_decoder->state.fps_d == 0) { + return GST_CLOCK_TIME_NONE; + } + if (field_offset < 0) { + GST_WARNING ("field offset < 0"); + return GST_CLOCK_TIME_NONE; + } + return base_video_decoder->timestamp_offset + + gst_util_uint64_scale (field_offset, + base_video_decoder->state.fps_d * GST_SECOND, + base_video_decoder->state.fps_n * 2); +} + +static guint64 +gst_base_video_decoder_get_field_duration (GstBaseVideoDecoder * + base_video_decoder, int n_fields) +{ + if (base_video_decoder->state.fps_d == 0) { + return GST_CLOCK_TIME_NONE; + } + if (n_fields < 0) { + GST_WARNING ("n_fields < 0"); + return GST_CLOCK_TIME_NONE; + } + return gst_util_uint64_scale (n_fields, + base_video_decoder->state.fps_d * GST_SECOND, + base_video_decoder->state.fps_n * 2); +} + + +GstFlowReturn +gst_base_video_decoder_have_frame (GstBaseVideoDecoder * base_video_decoder) +{ + GstBuffer *buffer; + int n_available; + GstClockTime timestamp; + GstClockTime duration; + + GST_DEBUG ("have_frame"); + + n_available = gst_adapter_available (base_video_decoder->output_adapter); + if (n_available) { + buffer = gst_adapter_take_buffer (base_video_decoder->output_adapter, + n_available); + } else { + buffer = gst_buffer_new_and_alloc (0); + } + + base_video_decoder->current_frame->sink_buffer = buffer; + + gst_base_video_decoder_get_timestamp_at_offset (base_video_decoder, + base_video_decoder->frame_offset, ×tamp, &duration); + + GST_BUFFER_TIMESTAMP (buffer) = timestamp; + GST_BUFFER_DURATION (buffer) = duration; + + return gst_base_video_decoder_have_frame_2 (base_video_decoder); +} + +static GstFlowReturn +gst_base_video_decoder_have_frame_2 (GstBaseVideoDecoder * base_video_decoder) +{ + GstVideoFrame *frame = base_video_decoder->current_frame; + GstBaseVideoDecoderClass *base_video_decoder_class; + GstFlowReturn ret = GST_FLOW_OK; + GstClockTime running_time; + GstClockTimeDiff deadline; + + base_video_decoder_class = + GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); + + frame->distance_from_sync = base_video_decoder->distance_from_sync; + base_video_decoder->distance_from_sync++; + + frame->presentation_timestamp = GST_BUFFER_TIMESTAMP (frame->sink_buffer); + frame->presentation_duration = GST_BUFFER_DURATION (frame->sink_buffer); + + GST_DEBUG ("pts %" GST_TIME_FORMAT, + GST_TIME_ARGS (frame->presentation_timestamp)); + GST_DEBUG ("dts %" GST_TIME_FORMAT, GST_TIME_ARGS (frame->decode_timestamp)); + GST_DEBUG ("dist %d", frame->distance_from_sync); + + base_video_decoder->frames = g_list_append (base_video_decoder->frames, + frame); + + running_time = gst_segment_to_running_time (&base_video_decoder->segment, + GST_FORMAT_TIME, frame->presentation_timestamp); + + if (GST_CLOCK_TIME_IS_VALID (base_video_decoder->earliest_time)) + deadline = GST_CLOCK_DIFF (base_video_decoder->earliest_time, running_time); + else + deadline = G_MAXINT64; + + /* do something with frame */ + ret = base_video_decoder_class->handle_frame (base_video_decoder, frame, + deadline); + if (!GST_FLOW_IS_SUCCESS (ret)) { + GST_DEBUG ("flow error!"); + } + + /* create new frame */ + base_video_decoder->current_frame = + gst_base_video_decoder_new_frame (base_video_decoder); + + return ret; +} + +GstVideoState * +gst_base_video_decoder_get_state (GstBaseVideoDecoder * base_video_decoder) +{ + return &base_video_decoder->state; + +} + +void +gst_base_video_decoder_set_state (GstBaseVideoDecoder * base_video_decoder, + GstVideoState * state) +{ + memcpy (&base_video_decoder->state, state, sizeof (*state)); + +} + +void +gst_base_video_decoder_lost_sync (GstBaseVideoDecoder * base_video_decoder) +{ + g_return_if_fail (GST_IS_BASE_VIDEO_DECODER (base_video_decoder)); + + GST_DEBUG ("lost_sync"); + + if (gst_adapter_available (base_video_decoder->input_adapter) >= 1) { + gst_adapter_flush (base_video_decoder->input_adapter, 1); + } + + base_video_decoder->have_sync = FALSE; +} + +void +gst_base_video_decoder_set_sync_point (GstBaseVideoDecoder * base_video_decoder) +{ + GST_DEBUG ("set_sync_point"); + + base_video_decoder->current_frame->is_sync_point = TRUE; + base_video_decoder->distance_from_sync = 0; +} + +GstVideoFrame * +gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder * + base_video_decoder) +{ + GList *g; + + g = g_list_first (base_video_decoder->frames); + + if (g == NULL) + return NULL; + return (GstVideoFrame *) (g->data); +} + +GstVideoFrame * +gst_base_video_decoder_get_frame (GstBaseVideoDecoder * base_video_decoder, + int frame_number) +{ + GList *g; + + for (g = g_list_first (base_video_decoder->frames); g; g = g_list_next (g)) { + GstVideoFrame *frame = g->data; + + if (frame->system_frame_number == frame_number) { + return frame; + } + } + + return NULL; +} + +void +gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder) +{ + GstCaps *caps; + GstVideoState *state = &base_video_decoder->state; + + if (base_video_decoder->have_src_caps) + return; + + caps = gst_video_format_new_caps (state->format, + state->width, state->height, + state->fps_n, state->fps_d, state->par_n, state->par_d); + gst_caps_set_simple (caps, "interlaced", + G_TYPE_BOOLEAN, state->interlaced, NULL); + + GST_DEBUG ("setting caps %" GST_PTR_FORMAT, caps); + + gst_pad_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), caps); + + base_video_decoder->have_src_caps = TRUE; + + gst_caps_unref (caps); +} + +GstFlowReturn +gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder * + base_video_decoder, GstVideoFrame * frame) +{ + GstFlowReturn flow_ret; + int num_bytes; + + gst_base_video_decoder_set_src_caps (base_video_decoder); + + num_bytes = gst_video_format_get_size (base_video_decoder->state.format, + base_video_decoder->state.width, base_video_decoder->state.height); + flow_ret = + gst_pad_alloc_buffer_and_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD + (base_video_decoder), GST_BUFFER_OFFSET_NONE, num_bytes, + GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)), + &frame->src_buffer); + + if (flow_ret != GST_FLOW_OK) { + GST_WARNING ("failed to get buffer"); + } + + return flow_ret; +} diff --git a/gst-libs/gst/video/gstbasevideodecoder.h b/gst-libs/gst/video/gstbasevideodecoder.h new file mode 100644 index 0000000000..02f1fd3a7f --- /dev/null +++ b/gst-libs/gst/video/gstbasevideodecoder.h @@ -0,0 +1,177 @@ +/* GStreamer + * Copyright (C) 2008 David Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_BASE_VIDEO_DECODER_H_ +#define _GST_BASE_VIDEO_DECODER_H_ + +#ifndef GST_USE_UNSTABLE_API +#warning "GstBaseVideoDecoder is unstable API and may change in future." +#warning "You can define GST_USE_UNSTABLE_API to avoid this warning." +#endif + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_BASE_VIDEO_DECODER \ + (gst_base_video_decoder_get_type()) +#define GST_BASE_VIDEO_DECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BASE_VIDEO_DECODER,GstBaseVideoDecoder)) +#define GST_BASE_VIDEO_DECODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BASE_VIDEO_DECODER,GstBaseVideoDecoderClass)) +#define GST_BASE_VIDEO_DECODER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_BASE_VIDEO_DECODER,GstBaseVideoDecoderClass)) +#define GST_IS_BASE_VIDEO_DECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BASE_VIDEO_DECODER)) +#define GST_IS_BASE_VIDEO_DECODER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_VIDEO_DECODER)) + +/** + * GST_BASE_VIDEO_DECODER_SINK_NAME: + * + * The name of the templates for the sink pad. + */ +#define GST_BASE_VIDEO_DECODER_SINK_NAME "sink" +/** + * GST_BASE_VIDEO_DECODER_SRC_NAME: + * + * The name of the templates for the source pad. + */ +#define GST_BASE_VIDEO_DECODER_SRC_NAME "src" + +/** + * * GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA: + * * + * */ +#define GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS + + +typedef struct _GstBaseVideoDecoder GstBaseVideoDecoder; +typedef struct _GstBaseVideoDecoderClass GstBaseVideoDecoderClass; + +struct _GstBaseVideoDecoder +{ + GstBaseVideoCodec base_video_codec; + + /*< private >*/ + GstAdapter *input_adapter; + GstAdapter *output_adapter; + + GList *frames; + + gboolean have_sync; + gboolean discont; + gboolean started; + + GstVideoState state; + GstSegment segment; + + gboolean sink_clipping; + + guint64 presentation_frame_number; + guint64 system_frame_number; + + GstCaps *caps; + gboolean have_src_caps; + + GstVideoFrame *current_frame; + + int distance_from_sync; + int reorder_depth; + + GstClockTime buffer_timestamp; + + GstClockTime timestamp_offset; + + gdouble proportion; + GstClockTime earliest_time; + + //GstBuffer *codec_data; + + guint64 input_offset; + guint64 frame_offset; + GstClockTime last_timestamp; + + guint64 base_picture_number; + + int field_index; + + gboolean is_delta_unit; + gboolean packetized; + + GList *timestamps; + gboolean have_segment; +}; + +struct _GstBaseVideoDecoderClass +{ + GstBaseVideoCodecClass base_video_codec_class; + + gboolean (*set_format) (GstBaseVideoDecoder *coder, GstVideoFormat, + int width, int height, int fps_n, int fps_d, + int par_n, int par_d); + gboolean (*start) (GstBaseVideoDecoder *coder); + gboolean (*stop) (GstBaseVideoDecoder *coder); + gboolean (*reset) (GstBaseVideoDecoder *coder); + int (*scan_for_sync) (GstBaseVideoDecoder *decoder, gboolean at_eos, + int offset, int n); + GstFlowReturn (*parse_data) (GstBaseVideoDecoder *decoder, gboolean at_eos); + GstFlowReturn (*finish) (GstBaseVideoDecoder *coder); + GstFlowReturn (*handle_frame) (GstBaseVideoDecoder *coder, GstVideoFrame *frame, + GstClockTimeDiff deadline); + GstFlowReturn (*shape_output) (GstBaseVideoDecoder *coder, GstVideoFrame *frame); + GstCaps *(*get_caps) (GstBaseVideoDecoder *coder); + +}; + +GType gst_base_video_decoder_get_type (void); + +int gst_base_video_decoder_get_width (GstBaseVideoDecoder *coder); +int gst_base_video_decoder_get_height (GstBaseVideoDecoder *coder); + +guint64 gst_base_video_decoder_get_timestamp_offset (GstBaseVideoDecoder *coder); + +GstVideoFrame *gst_base_video_decoder_get_frame (GstBaseVideoDecoder *coder, + int frame_number); +GstVideoFrame *gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder *coder); +void gst_base_video_decoder_add_to_frame (GstBaseVideoDecoder *base_video_decoder, + int n_bytes); +GstFlowReturn gst_base_video_decoder_finish_frame (GstBaseVideoDecoder *base_video_decoder, + GstVideoFrame *frame); +GstFlowReturn gst_base_video_decoder_skip_frame (GstBaseVideoDecoder * base_video_decoder, + GstVideoFrame * frame); +GstFlowReturn gst_base_video_decoder_end_of_stream (GstBaseVideoDecoder *base_video_decoder, + GstBuffer *buffer); +GstFlowReturn +gst_base_video_decoder_have_frame (GstBaseVideoDecoder *base_video_decoder); +GstVideoState * gst_base_video_decoder_get_state (GstBaseVideoDecoder *base_video_decoder); +void gst_base_video_decoder_set_state (GstBaseVideoDecoder *base_video_decoder, + GstVideoState *state); +void gst_base_video_decoder_lost_sync (GstBaseVideoDecoder *base_video_decoder); +void gst_base_video_decoder_set_sync_point (GstBaseVideoDecoder *base_video_decoder); + +void gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder *base_video_decoder); + +GstFlowReturn gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder *base_video_decoder, + GstVideoFrame *frame); + +G_END_DECLS + +#endif + diff --git a/gst-libs/gst/video/gstbasevideoutils.c b/gst-libs/gst/video/gstbasevideoutils.c new file mode 100644 index 0000000000..4ccdd58c5e --- /dev/null +++ b/gst-libs/gst/video/gstbasevideoutils.c @@ -0,0 +1,137 @@ +/* GStreamer + * Copyright (C) 2008 David Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstbasevideoutils.h" + +#include + +GST_DEBUG_CATEGORY_EXTERN (basevideocodec_debug); +#define GST_CAT_DEFAULT basevideocodec_debug + + +#if 0 +guint64 +gst_base_video_convert_bytes_to_frames (GstVideoState * state, guint64 bytes) +{ + return gst_util_uint64_scale_int (bytes, 1, state->bytes_per_picture); +} + +guint64 +gst_base_video_convert_frames_to_bytes (GstVideoState * state, guint64 frames) +{ + return frames * state->bytes_per_picture; +} +#endif + + +gboolean +gst_base_video_rawvideo_convert (GstVideoState * state, + GstFormat src_format, gint64 src_value, + GstFormat * dest_format, gint64 * dest_value) +{ + gboolean res = FALSE; + + if (src_format == *dest_format) { + *dest_value = src_value; + return TRUE; + } + + if (src_format == GST_FORMAT_BYTES && + *dest_format == GST_FORMAT_DEFAULT && state->bytes_per_picture != 0) { + /* convert bytes to frames */ + *dest_value = gst_util_uint64_scale_int (src_value, 1, + state->bytes_per_picture); + res = TRUE; + } else if (src_format == GST_FORMAT_DEFAULT && + *dest_format == GST_FORMAT_BYTES && state->bytes_per_picture != 0) { + /* convert bytes to frames */ + *dest_value = src_value * state->bytes_per_picture; + res = TRUE; + } else if (src_format == GST_FORMAT_DEFAULT && + *dest_format == GST_FORMAT_TIME && state->fps_n != 0) { + /* convert frames to time */ + /* FIXME add segment time? */ + *dest_value = gst_util_uint64_scale (src_value, + GST_SECOND * state->fps_d, state->fps_n); + res = TRUE; + } else if (src_format == GST_FORMAT_TIME && + *dest_format == GST_FORMAT_DEFAULT && state->fps_d != 0) { + /* convert time to frames */ + /* FIXME subtract segment time? */ + *dest_value = gst_util_uint64_scale (src_value, state->fps_n, + GST_SECOND * state->fps_d); + res = TRUE; + } + + /* FIXME add bytes <--> time */ + + return res; +} + +gboolean +gst_base_video_encoded_video_convert (GstVideoState * state, + GstFormat src_format, gint64 src_value, + GstFormat * dest_format, gint64 * dest_value) +{ + gboolean res = FALSE; + + if (src_format == *dest_format) { + *dest_value = src_value; + return TRUE; + } + + GST_DEBUG ("src convert"); + +#if 0 + if (src_format == GST_FORMAT_DEFAULT && *dest_format == GST_FORMAT_TIME) { + if (dec->fps_d != 0) { + *dest_value = gst_util_uint64_scale (granulepos_to_frame (src_value), + dec->fps_d * GST_SECOND, dec->fps_n); + res = TRUE; + } else { + res = FALSE; + } + } else { + GST_WARNING ("unhandled conversion from %d to %d", src_format, + *dest_format); + res = FALSE; + } +#endif + + return res; +} + +GstClockTime +gst_video_state_get_timestamp (const GstVideoState * state, + GstSegment * segment, int frame_number) +{ + if (frame_number < 0) { + return segment->start - + (gint64) gst_util_uint64_scale (-frame_number, + state->fps_d * GST_SECOND, state->fps_n); + } else { + return segment->start + + gst_util_uint64_scale (frame_number, + state->fps_d * GST_SECOND, state->fps_n); + } +} diff --git a/gst-libs/gst/video/gstbasevideoutils.h b/gst-libs/gst/video/gstbasevideoutils.h new file mode 100644 index 0000000000..f644218c32 --- /dev/null +++ b/gst-libs/gst/video/gstbasevideoutils.h @@ -0,0 +1,100 @@ +/* GStreamer + * Copyright (C) 2008 David Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_BASE_VIDEO_UTILS_H_ +#define _GST_BASE_VIDEO_UTILS_H_ + +#ifndef GST_USE_UNSTABLE_API +#warning "The base video utils API is unstable and may change in future." +#warning "You can define GST_USE_UNSTABLE_API to avoid this warning." +#endif + +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _GstVideoState GstVideoState; +typedef struct _GstVideoFrame GstVideoFrame; + +struct _GstVideoState +{ + GstVideoFormat format; + int width, height; + int fps_n, fps_d; + int par_n, par_d; + + gboolean have_interlaced; + gboolean interlaced; + gboolean top_field_first; + + int clean_width, clean_height; + int clean_offset_left, clean_offset_top; + + int bytes_per_picture; + + //GstSegment segment; + + int picture_number; + GstBuffer *codec_data; + +}; + +struct _GstVideoFrame +{ + GstClockTime decode_timestamp; + GstClockTime presentation_timestamp; + GstClockTime presentation_duration; + + gint system_frame_number; + gint decode_frame_number; + gint presentation_frame_number; + + int distance_from_sync; + gboolean is_sync_point; + gboolean is_eos; + + GstBuffer *sink_buffer; + GstBuffer *src_buffer; + + int field_index; + int n_fields; + + void *coder_hook; +}; + +gboolean gst_base_video_rawvideo_convert (GstVideoState *state, + GstFormat src_format, gint64 src_value, + GstFormat * dest_format, gint64 *dest_value); +gboolean gst_base_video_encoded_video_convert (GstVideoState *state, + GstFormat src_format, gint64 src_value, + GstFormat * dest_format, gint64 *dest_value); + +GstClockTime gst_video_state_get_timestamp (const GstVideoState *state, + GstSegment *segment, int frame_number); + +int gst_adapter_masked_scan_uint32_compat (GstAdapter *adapter, + guint32 pattern, guint32 mask, guint offset, guint n); +GstBuffer *gst_adapter_get_buffer (GstAdapter *adapter); + +G_END_DECLS + +#endif + From 7bd568f29397c6b8ac3a9c6d166bab1b616eefec Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 22 Jun 2010 13:48:30 +0000 Subject: [PATCH 0408/3781] Further drop dependency on libgstvideo. --- gst-libs/gst/video/gstbasevideodecoder.c | 34 +++++++++++++++++------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/video/gstbasevideodecoder.c b/gst-libs/gst/video/gstbasevideodecoder.c index b1a97eb432..54a91288c9 100644 --- a/gst-libs/gst/video/gstbasevideodecoder.c +++ b/gst-libs/gst/video/gstbasevideodecoder.c @@ -1455,11 +1455,20 @@ gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder) if (base_video_decoder->have_src_caps) return; - caps = gst_video_format_new_caps (state->format, - state->width, state->height, - state->fps_n, state->fps_d, state->par_n, state->par_d); - gst_caps_set_simple (caps, "interlaced", - G_TYPE_BOOLEAN, state->interlaced, NULL); + caps = gst_pad_get_allowed_caps + (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)); + if (!caps) + goto null_caps; + if (gst_caps_is_empty (caps)) + goto empty_caps; + + gst_caps_set_simple (caps, + "width", G_TYPE_INT, state->width, + "height", G_TYPE_INT, state->height, + "framerate", GST_TYPE_FRACTION, state->fps_n, state->fps_d, + "pixel-aspect-ratio", GST_TYPE_FRACTION, state->par_n, state->par_d, + "interlaced", G_TYPE_BOOLEAN, state->interlaced, NULL); + gst_pad_fixate_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), caps); GST_DEBUG ("setting caps %" GST_PTR_FORMAT, caps); @@ -1468,6 +1477,16 @@ gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder) base_video_decoder->have_src_caps = TRUE; gst_caps_unref (caps); + return; + +null_caps: + GST_WARNING ("Got null caps from get_allowed_caps"); + return; + +empty_caps: + GST_WARNING ("Got empty caps from get_allowed_caps"); + gst_caps_unref (caps); + return; } GstFlowReturn @@ -1475,15 +1494,12 @@ gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder * base_video_decoder, GstVideoFrame * frame) { GstFlowReturn flow_ret; - int num_bytes; gst_base_video_decoder_set_src_caps (base_video_decoder); - num_bytes = gst_video_format_get_size (base_video_decoder->state.format, - base_video_decoder->state.width, base_video_decoder->state.height); flow_ret = gst_pad_alloc_buffer_and_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD - (base_video_decoder), GST_BUFFER_OFFSET_NONE, num_bytes, + (base_video_decoder), GST_BUFFER_OFFSET_NONE, 0, GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)), &frame->src_buffer); From b5b650c6ee599b38a7d1e984d726ebbe7984c6e0 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 22 Jun 2010 13:57:33 +0000 Subject: [PATCH 0409/3781] Really drop any dependency on libgstvideo. i.e. inline the helpers. --- gst-libs/gst/video/gstbasevideodecoder.c | 28 ++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/video/gstbasevideodecoder.c b/gst-libs/gst/video/gstbasevideodecoder.c index 54a91288c9..7804cb1ce4 100644 --- a/gst-libs/gst/video/gstbasevideodecoder.c +++ b/gst-libs/gst/video/gstbasevideodecoder.c @@ -147,25 +147,31 @@ gst_base_video_decoder_sink_setcaps (GstPad * pad, GstCaps * caps) state = &base_video_decoder->state; - if (state->codec_data) { + if (state->codec_data) gst_buffer_unref (state->codec_data); - } memset (state, 0, sizeof (GstVideoState)); structure = gst_caps_get_structure (caps, 0); - gst_video_format_parse_caps (caps, NULL, &state->width, &state->height); - gst_video_parse_caps_framerate (caps, &state->fps_n, &state->fps_d); - gst_video_parse_caps_pixel_aspect_ratio (caps, &state->par_n, &state->par_d); + gst_structure_get_int (structure, "width", &state->width); + gst_structure_get_int (structure, "height", &state->height); + + /* framerate default: 25 fps */ + if (!gst_structure_get_fraction (structure, "framerate", + &state->fps_n, &state->fps_d)) { + state->fps_n = 25; + state->fps_d = 1; + } + + /* pixel-aspect-ratio default: 1/1 */ + if (!gst_structure_get_fraction (structure, "pixel-aspect-ratio", + &state->par_n, &state->par_d)) { + state->par_n = 1; + state->par_d = 1; + } -#if 0 - /* requires 0.10.23 */ - state->have_interlaced = - gst_video_format_parse_caps_interlaced (caps, &state->interlaced); -#else state->have_interlaced = gst_structure_get_boolean (structure, "interlaced", &state->interlaced); -#endif codec_data = gst_structure_get_value (structure, "codec_data"); if (codec_data && G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) { From e708f89b6707971e486768217a18045aa2d51623 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 22 Jun 2010 14:06:25 +0000 Subject: [PATCH 0410/3781] Drop superfluous functions. --- gst-libs/gst/video/gstbasevideodecoder.c | 13 ---- gst-libs/gst/video/gstbasevideoutils.c | 92 ------------------------ gst-libs/gst/video/gstbasevideoutils.h | 12 ---- 3 files changed, 117 deletions(-) diff --git a/gst-libs/gst/video/gstbasevideodecoder.c b/gst-libs/gst/video/gstbasevideodecoder.c index 7804cb1ce4..b5c79f6b01 100644 --- a/gst-libs/gst/video/gstbasevideodecoder.c +++ b/gst-libs/gst/video/gstbasevideodecoder.c @@ -610,19 +610,6 @@ gst_base_video_decoder_sink_query (GstPad * pad, GstQuery * query) GST_DEBUG_OBJECT (base_video_decoder, "sink query fps=%d/%d", base_video_decoder->state.fps_n, base_video_decoder->state.fps_d); switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_CONVERT: - { - GstFormat src_fmt, dest_fmt; - gint64 src_val, dest_val; - - gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); - res = gst_base_video_rawvideo_convert (&base_video_decoder->state, - src_fmt, src_val, &dest_fmt, &dest_val); - if (!res) - goto error; - gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); - break; - } default: res = gst_pad_query_default (pad, query); break; diff --git a/gst-libs/gst/video/gstbasevideoutils.c b/gst-libs/gst/video/gstbasevideoutils.c index 4ccdd58c5e..44f7dc0b70 100644 --- a/gst-libs/gst/video/gstbasevideoutils.c +++ b/gst-libs/gst/video/gstbasevideoutils.c @@ -29,98 +29,6 @@ GST_DEBUG_CATEGORY_EXTERN (basevideocodec_debug); #define GST_CAT_DEFAULT basevideocodec_debug -#if 0 -guint64 -gst_base_video_convert_bytes_to_frames (GstVideoState * state, guint64 bytes) -{ - return gst_util_uint64_scale_int (bytes, 1, state->bytes_per_picture); -} - -guint64 -gst_base_video_convert_frames_to_bytes (GstVideoState * state, guint64 frames) -{ - return frames * state->bytes_per_picture; -} -#endif - - -gboolean -gst_base_video_rawvideo_convert (GstVideoState * state, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - gboolean res = FALSE; - - if (src_format == *dest_format) { - *dest_value = src_value; - return TRUE; - } - - if (src_format == GST_FORMAT_BYTES && - *dest_format == GST_FORMAT_DEFAULT && state->bytes_per_picture != 0) { - /* convert bytes to frames */ - *dest_value = gst_util_uint64_scale_int (src_value, 1, - state->bytes_per_picture); - res = TRUE; - } else if (src_format == GST_FORMAT_DEFAULT && - *dest_format == GST_FORMAT_BYTES && state->bytes_per_picture != 0) { - /* convert bytes to frames */ - *dest_value = src_value * state->bytes_per_picture; - res = TRUE; - } else if (src_format == GST_FORMAT_DEFAULT && - *dest_format == GST_FORMAT_TIME && state->fps_n != 0) { - /* convert frames to time */ - /* FIXME add segment time? */ - *dest_value = gst_util_uint64_scale (src_value, - GST_SECOND * state->fps_d, state->fps_n); - res = TRUE; - } else if (src_format == GST_FORMAT_TIME && - *dest_format == GST_FORMAT_DEFAULT && state->fps_d != 0) { - /* convert time to frames */ - /* FIXME subtract segment time? */ - *dest_value = gst_util_uint64_scale (src_value, state->fps_n, - GST_SECOND * state->fps_d); - res = TRUE; - } - - /* FIXME add bytes <--> time */ - - return res; -} - -gboolean -gst_base_video_encoded_video_convert (GstVideoState * state, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - gboolean res = FALSE; - - if (src_format == *dest_format) { - *dest_value = src_value; - return TRUE; - } - - GST_DEBUG ("src convert"); - -#if 0 - if (src_format == GST_FORMAT_DEFAULT && *dest_format == GST_FORMAT_TIME) { - if (dec->fps_d != 0) { - *dest_value = gst_util_uint64_scale (granulepos_to_frame (src_value), - dec->fps_d * GST_SECOND, dec->fps_n); - res = TRUE; - } else { - res = FALSE; - } - } else { - GST_WARNING ("unhandled conversion from %d to %d", src_format, - *dest_format); - res = FALSE; - } -#endif - - return res; -} - GstClockTime gst_video_state_get_timestamp (const GstVideoState * state, GstSegment * segment, int frame_number) diff --git a/gst-libs/gst/video/gstbasevideoutils.h b/gst-libs/gst/video/gstbasevideoutils.h index f644218c32..047be71368 100644 --- a/gst-libs/gst/video/gstbasevideoutils.h +++ b/gst-libs/gst/video/gstbasevideoutils.h @@ -36,7 +36,6 @@ typedef struct _GstVideoFrame GstVideoFrame; struct _GstVideoState { - GstVideoFormat format; int width, height; int fps_n, fps_d; int par_n, par_d; @@ -80,20 +79,9 @@ struct _GstVideoFrame void *coder_hook; }; -gboolean gst_base_video_rawvideo_convert (GstVideoState *state, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 *dest_value); -gboolean gst_base_video_encoded_video_convert (GstVideoState *state, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 *dest_value); - GstClockTime gst_video_state_get_timestamp (const GstVideoState *state, GstSegment *segment, int frame_number); -int gst_adapter_masked_scan_uint32_compat (GstAdapter *adapter, - guint32 pattern, guint32 mask, guint offset, guint n); -GstBuffer *gst_adapter_get_buffer (GstAdapter *adapter); - G_END_DECLS #endif From 781a7edd5784c466a2cf294317692309e4f4ea08 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 22 Jun 2010 15:15:46 +0000 Subject: [PATCH 0411/3781] Add gst_base_video_decoder_update_src_caps(). Don't forcibly set "interlaced" field if upstream elements did not have any. --- gst-libs/gst/video/gstbasevideodecoder.c | 30 +++++++++++++++++++----- gst-libs/gst/video/gstbasevideodecoder.h | 1 + 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/video/gstbasevideodecoder.c b/gst-libs/gst/video/gstbasevideodecoder.c index b5c79f6b01..a66446fb0f 100644 --- a/gst-libs/gst/video/gstbasevideodecoder.c +++ b/gst-libs/gst/video/gstbasevideodecoder.c @@ -1448,18 +1448,26 @@ gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder) if (base_video_decoder->have_src_caps) return; - caps = gst_pad_get_allowed_caps - (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)); - if (!caps) - goto null_caps; - if (gst_caps_is_empty (caps)) - goto empty_caps; + caps = GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)); + if (caps) + caps = gst_caps_copy (caps); + else { + caps = gst_pad_get_allowed_caps + (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)); + if (!caps) + goto null_caps; + if (gst_caps_is_empty (caps)) + goto empty_caps; + } gst_caps_set_simple (caps, "width", G_TYPE_INT, state->width, "height", G_TYPE_INT, state->height, "framerate", GST_TYPE_FRACTION, state->fps_n, state->fps_d, "pixel-aspect-ratio", GST_TYPE_FRACTION, state->par_n, state->par_d, + NULL); + if (state->have_interlaced) + gst_caps_set_simple (caps, "interlaced", G_TYPE_BOOLEAN, state->interlaced, NULL); gst_pad_fixate_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), caps); @@ -1482,6 +1490,16 @@ empty_caps: return; } +void +gst_base_video_decoder_update_src_caps (GstBaseVideoDecoder * + base_video_decoder) +{ + g_return_if_fail (GST_IS_BASE_VIDEO_DECODER (base_video_decoder)); + + base_video_decoder->have_src_caps = FALSE; + gst_base_video_decoder_set_src_caps (base_video_decoder); +} + GstFlowReturn gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder * base_video_decoder, GstVideoFrame * frame) diff --git a/gst-libs/gst/video/gstbasevideodecoder.h b/gst-libs/gst/video/gstbasevideodecoder.h index 02f1fd3a7f..656eb40a6e 100644 --- a/gst-libs/gst/video/gstbasevideodecoder.h +++ b/gst-libs/gst/video/gstbasevideodecoder.h @@ -167,6 +167,7 @@ void gst_base_video_decoder_lost_sync (GstBaseVideoDecoder *base_video_decoder); void gst_base_video_decoder_set_sync_point (GstBaseVideoDecoder *base_video_decoder); void gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder *base_video_decoder); +void gst_base_video_decoder_update_src_caps (GstBaseVideoDecoder *base_video_decoder); GstFlowReturn gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder *base_video_decoder, GstVideoFrame *frame); From fcb65d60f5aebae322c88a19bef558c3d7504ba6 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 1 Jul 2010 11:11:18 +0000 Subject: [PATCH 0412/3781] Drop dependency on libavformat. --- NEWS | 1 + configure.ac | 7 ++----- gst-libs/gst/vaapi/Makefile.am | 2 -- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 17 +++++++++++++---- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index d259339b8a..ddae573c89 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ gst-vaapi NEWS -- summary of changes. 2010-06-DD Copyright (C) 2010 Splitted-Desktop Systems Version 0.2.5 - DD.Jun.2010 +* Drop dependency on libavformat * Fix build with older VA-API 0.29-sds * Fix decoding of some H.264 streams. e.g. Ice Age 2 trailer diff --git a/configure.ac b/configure.ac index 89dca33d77..403f8bc7a8 100644 --- a/configure.ac +++ b/configure.ac @@ -272,12 +272,9 @@ else fi dnl Check for FFmpeg -PKG_CHECK_MODULES(LIBAVFORMAT, [libavformat]) -AC_CHECK_HEADERS([libavformat/avformat.h]) - PKG_CHECK_MODULES(LIBAVCODEC, [libavcodec]) -AC_CHECK_HEADERS([libavcodec/avcodec.h]) -AC_CHECK_HEADERS([libavcodec/vaapi.h], [], +AC_CHECK_HEADERS([libavcodec/avcodec.h ffmpeg/avcodec.h]) +AC_CHECK_HEADERS([libavcodec/vaapi.h ffmpeg/vaapi.h], [break], AC_MSG_ERROR([The system FFmpeg headers do not support VA-API])) AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 9759baf839..c488897974 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -140,7 +140,6 @@ libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ $(GST_BASE_CFLAGS) \ $(GST_CFLAGS) \ $(LIBAVCODEC_CFLAGS) \ - $(LIBAVFORMAT_CFLAGS) \ $(LIBVA_CFLAGS) \ $(NULL) @@ -148,7 +147,6 @@ libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ $(GST_BASE_LIBS) \ $(GST_LIBS) \ $(LIBAVCODEC_LIBS) \ - $(LIBAVFORMAT_LIBS) \ $(LIBVA_LIBS) \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index d6fe7e2406..e8fc98121f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -25,9 +25,18 @@ */ #include "config.h" -#include -#include -#include +#ifdef HAVE_LIBAVCODEC_AVCODEC_H +# include +#endif +#ifdef HAVE_FFMPEG_AVCODEC_H +# include +#endif +#ifdef HAVE_LIBAVCODEC_VAAPI_H +# include +#endif +#ifdef HAVE_FFMPEG_VAAPI_H +# include +#endif #include "gstvaapidecoder_ffmpeg.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" @@ -598,7 +607,7 @@ gst_vaapi_decoder_ffmpeg_class_init(GstVaapiDecoderFfmpegClass *klass) static gpointer gst_vaapi_decoder_ffmpeg_init_once_cb(gpointer user_data) { - av_register_all(); + avcodec_register_all(); return NULL; } From 982a06b1c786779852abe5abf3ff57a54095e26d Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 1 Jul 2010 11:38:28 +0000 Subject: [PATCH 0413/3781] Call the GLX/Pixmap related functions through the vtable. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 19 +++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 9 +++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 899b657550..dff878050d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -664,6 +664,14 @@ gl_init_vtable(void) gboolean has_extension; /* GLX_EXT_texture_from_pixmap */ + gl_vtable->glx_create_pixmap = (PFNGLXCREATEPIXMAPPROC) + get_proc_address("glXCreatePixmap"); + if (!gl_vtable->glx_create_pixmap) + return NULL; + gl_vtable->glx_destroy_pixmap = (PFNGLXDESTROYPIXMAPPROC) + get_proc_address("glXDestroyPixmap"); + if (!gl_vtable->glx_destroy_pixmap) + return NULL; gl_vtable->glx_bind_tex_image = (PFNGLXBINDTEXIMAGEEXTPROC) get_proc_address("glXBindTexImageEXT"); if (!gl_vtable->glx_bind_tex_image) @@ -906,7 +914,12 @@ gl_create_pixmap_object(Display *dpy, guint width, guint height) *attr++ = GL_NONE; x11_trap_errors(); - pixo->glx_pixmap = glXCreatePixmap(dpy, fbconfig[0], pixo->pixmap, pixmap_attrs); + pixo->glx_pixmap = gl_vtable->glx_create_pixmap( + dpy, + fbconfig[0], + pixo->pixmap, + pixmap_attrs + ); free(fbconfig); if (x11_untrap_errors() != 0) goto error; @@ -934,6 +947,8 @@ error: void gl_destroy_pixmap_object(GLPixmapObject *pixo) { + GLVTable * const gl_vtable = gl_get_vtable(); + if (!pixo) return; @@ -945,7 +960,7 @@ gl_destroy_pixmap_object(GLPixmapObject *pixo) } if (pixo->glx_pixmap) { - glXDestroyPixmap(pixo->dpy, pixo->glx_pixmap); + gl_vtable->glx_destroy_pixmap(pixo->dpy, pixo->glx_pixmap); pixo->glx_pixmap = None; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index ed8856c48c..5309b7a14c 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -34,6 +34,13 @@ typedef void (*PFNGLXBINDTEXIMAGEEXTPROC)(Display *, GLXDrawable, int, const int typedef void (*PFNGLXRELEASETEXIMAGEEXTPROC)(Display *, GLXDrawable, int); #endif +#if GLX_GLXEXT_VERSION < 27 +/* XXX: this is not exactly that version but this is the only means to + make sure we have the correct with those signatures */ +typedef GLXPixmap (*PFNGLXCREATEPIXMAPPROC)(Display *, GLXFBConfig, Pixmap, const int *); +typedef void (*PFNGLXDESTROYPIXMAPPROC)(Display *, GLXPixmap); +#endif + #ifndef GL_FRAMEBUFFER_BINDING #define GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_EXT #endif @@ -117,6 +124,8 @@ gl_create_texture(GLenum target, GLenum format, guint width, guint height) typedef struct _GLVTable GLVTable; struct _GLVTable { + PFNGLXCREATEPIXMAPPROC glx_create_pixmap; + PFNGLXDESTROYPIXMAPPROC glx_destroy_pixmap; PFNGLXBINDTEXIMAGEEXTPROC glx_bind_tex_image; PFNGLXRELEASETEXIMAGEEXTPROC glx_release_tex_image; PFNGLGENFRAMEBUFFERSEXTPROC gl_gen_framebuffers; From 8ee1ffa8578bb93383d2037aedde527a0af7a9a7 Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 1 Jul 2010 11:41:23 +0000 Subject: [PATCH 0414/3781] Drop the GLX 1.3 requirement. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index dff878050d..b1d8dcf0dd 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -852,17 +852,11 @@ gl_create_pixmap_object(Display *dpy, guint width, guint height) /* XXX: this won't work for different displays */ if (!gl_vtable->has_texture_from_pixmap) { - const char *glx_extensions; - int glx_major, glx_minor; - glx_extensions = glXQueryExtensionsString(dpy, screen); + const char *glx_extensions = glXQueryExtensionsString(dpy, screen); if (!glx_extensions) return NULL; if (!find_string("GLX_EXT_texture_from_pixmap", glx_extensions, " ")) return NULL; - if (!glXQueryVersion(dpy, &glx_major, &glx_minor)) - return NULL; - if (glx_major < 1 || (glx_major == 1 && glx_minor < 3)) /* 1.3 */ - return NULL; gl_vtable->has_texture_from_pixmap = TRUE; } From 7dfec25d5c946c4f09098e1ee747d990d84d80dd Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 1 Jul 2010 11:43:22 +0000 Subject: [PATCH 0415/3781] Updates. --- NEWS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index ddae573c89..b1164f2093 100644 --- a/NEWS +++ b/NEWS @@ -1,10 +1,10 @@ -gst-vaapi NEWS -- summary of changes. 2010-06-DD +gst-vaapi NEWS -- summary of changes. 2010-07-01 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.2.5 - DD.Jun.2010 -* Drop dependency on libavformat +Version 0.2.5 - 01.Jul.2010 * Fix build with older VA-API 0.29-sds * Fix decoding of some H.264 streams. e.g. Ice Age 2 trailer +* Fix VA/GLX support with texture-from-pixmap and GLX version < 1.3 Version 0.2.4 - 18.May.2010 * Fix video rendering rect within an embedder window (Totem) From 028ed08f8cc7ccfb93938b65a85ee11f021443df Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 1 Jul 2010 13:19:29 +0000 Subject: [PATCH 0416/3781] Render pretty background only in use-reflection=true mode. --- gst/vaapisink/gstvaapisink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 088999a13b..fc86ec0a13 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -631,7 +631,8 @@ gst_vaapisink_show_frame_glx( if (target != GL_TEXTURE_2D || !texture) return FALSE; - render_background(sink); + if (sink->use_reflection) + render_background(sink); glEnable(target); glBindTexture(target, texture); From 616f4ca4b3a02fc3021803225af8bd94046a5897 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 20 Jul 2010 11:21:37 +0000 Subject: [PATCH 0417/3781] Fix license terms... --- debian.upstream/copyright | 71 +++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/debian.upstream/copyright b/debian.upstream/copyright index 94da1e1218..a7b3a141ed 100644 --- a/debian.upstream/copyright +++ b/debian.upstream/copyright @@ -1,34 +1,55 @@ This package is maintained by: Gwenole Beauchesne +Copyright: + + gstreamer-vaapi helper libraries + gst-libs/gst/vaapi/*.[ch]: LGPL (v2.1 or later) + + gstreamer-vaapi plugin elements + gst/vaapi{convert,decode,sink}: GPL (v2 or later) License: - Copyright (C) 2009, Splitted-Desktop Systems. - All rights reserved. + Copyright (C) 2010, Splitted-Desktop Systems. - Redistribution. Redistribution and use in binary form, without - modification, are permitted provided that the following conditions are - met: + gstreamer-vaapi helper libraries are available under the terms of + the GNU Lesser General Public License v2.1+. - * Redistributions must reproduce the above copyright notice and the - following disclaimer in the documentation and/or other materials - provided with the distribution. - * Neither the name of Splitted-Desktop Systems nor the names of its - suppliers may be used to endorse or promote products derived from - this software without specific prior written permission. - * No reverse engineering, decompilation, or disassembly of this software - is permitted. + 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. - DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. + This library is distributed in the hope that 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 + +On Debian GNU/Linux systems, the complete text of the GNU Lesser General +Public License can be found in `/usr/share/common-licenses/LGPL-2.1'. + + gstreamer-vaapi plugin elements are available under the terms of + the GNU General Public License v2+. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +On Debian GNU/Linux systems, the complete text of the GNU General Public +License can be found in `/usr/share/common-licenses/GPL-2'. From 1321fa9a82f038648197f5e8f6bcf82e11804e04 Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 20 Jul 2010 11:23:16 +0000 Subject: [PATCH 0418/3781] 0.2.5. --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index b1164f2093..5bc3b3951b 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ -gst-vaapi NEWS -- summary of changes. 2010-07-01 +gst-vaapi NEWS -- summary of changes. 2010-07-20 Copyright (C) 2010 Splitted-Desktop Systems -Version 0.2.5 - 01.Jul.2010 +Version 0.2.5 - 20.Jul.2010 * Fix build with older VA-API 0.29-sds * Fix decoding of some H.264 streams. e.g. Ice Age 2 trailer * Fix VA/GLX support with texture-from-pixmap and GLX version < 1.3 From b614ec9c9b11bbf5c4d0ca9d0154763d50a422b1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 14 Jun 2011 13:51:41 +0200 Subject: [PATCH 0419/3781] Fix licensing terms. --- NEWS | 5 ++++- gst-libs/gst/vaapi/gstvaapisubpicture.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapisurface.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapitexture.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapiutils.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapivalue.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapivideopool.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapivideosink.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapiwindow.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 21 +++++++++++---------- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 21 +++++++++++---------- 16 files changed, 169 insertions(+), 151 deletions(-) diff --git a/NEWS b/NEWS index 5bc3b3951b..ea6ed84963 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2010-07-20 +gst-vaapi NEWS -- summary of changes. 2011-06-14 Copyright (C) 2010 Splitted-Desktop Systems +Version 0.2.6 - 14.Jun.2011 +* Fix licensing terms (LGPL v2.1) + Version 0.2.5 - 20.Jul.2010 * Fix build with older VA-API 0.29-sds * Fix decoding of some H.264 streams. e.g. Ice Age 2 trailer diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index ae79b7842b..2164a19120 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 08269a8040..941f397142 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index a151b0fd90..221bc33ffb 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 22737aaa74..8f7c673ad5 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 083f0346a7..48a7c0496c 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 53c405d645..a855bf3f37 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index b1d8dcf0dd..bd3b07042f 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ #define _GNU_SOURCE 1 /* RTLD_DEFAULT */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index dc161e1b23..50532283cb 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 "config.h" diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 1ba30deb09..a52c6e2805 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 17fff380ef..9f6ac63a41 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index fca27345ba..891a6a8575 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.c b/gst-libs/gst/vaapi/gstvaapivideosink.c index b9584fa61b..7cceaa5260 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.c +++ b/gst-libs/gst/vaapi/gstvaapivideosink.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 8e5e58b654..4aab5d42a3 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 1dcf4a5d12..6613aa6146 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index b46f08ae9f..dc2c5fd145 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** From 1701ce3107cf4edbb628f61e148c69d92c9a722b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 14 Jun 2011 13:52:56 +0200 Subject: [PATCH 0420/3781] Update copyright notice. --- gst-libs/gst/vaapi/gstvaapi_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapicompat.h | 2 +- gst-libs/gst/vaapi/gstvaapicontext.c | 2 +- gst-libs/gst/vaapi/gstvaapicontext.h | 2 +- gst-libs/gst/vaapi/gstvaapidebug.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.h | 2 +- gst-libs/gst/vaapi/gstvaapiimageformat.c | 2 +- gst-libs/gst/vaapi/gstvaapiimageformat.h | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.c | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.h | 2 +- gst-libs/gst/vaapi/gstvaapiobject.c | 2 +- gst-libs/gst/vaapi/gstvaapiobject.h | 2 +- gst-libs/gst/vaapi/gstvaapiobject_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiparamspecs.c | 2 +- gst-libs/gst/vaapi/gstvaapiparamspecs.h | 2 +- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- gst-libs/gst/vaapi/gstvaapiprofile.h | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.h | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 2 +- gst-libs/gst/vaapi/gstvaapitexture.c | 2 +- gst-libs/gst/vaapi/gstvaapitexture.h | 2 +- gst-libs/gst/vaapi/gstvaapitypes.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_gst.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_gst.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapivalue.c | 2 +- gst-libs/gst/vaapi/gstvaapivalue.h | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.h | 2 +- gst-libs/gst/vaapi/gstvaapivideosink.c | 2 +- gst-libs/gst/vaapi/gstvaapivideosink.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 2 +- gst/vaapiconvert/gstvaapiconvert.c | 2 +- gst/vaapiconvert/gstvaapiconvert.h | 2 +- gst/vaapidecode/gstvaapidecode.c | 2 +- gst/vaapidecode/gstvaapidecode.h | 2 +- gst/vaapisink/gstvaapisink.c | 2 +- gst/vaapisink/gstvaapisink.h | 2 +- tests/image.c | 2 +- tests/image.h | 2 +- tests/test-decode.c | 2 +- tests/test-decode.h | 2 +- tests/test-display.c | 2 +- tests/test-h264.c | 2 +- tests/test-h264.h | 2 +- tests/test-mpeg2.c | 2 +- tests/test-mpeg2.h | 2 +- tests/test-surfaces.c | 2 +- tests/test-textures.c | 2 +- tests/test-vc1.c | 2 +- tests/test-vc1.h | 2 +- tests/test-windows.c | 2 +- 85 files changed, 85 insertions(+), 85 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapi_priv.h b/gst-libs/gst/vaapi/gstvaapi_priv.h index cb5f9c438e..99d09b901b 100644 --- a/gst-libs/gst/vaapi/gstvaapi_priv.h +++ b/gst-libs/gst/vaapi/gstvaapi_priv.h @@ -1,7 +1,7 @@ /* * gstvaapi_priv.h - Helper to include all private headers * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index e17684fbd1..bf4385d36e 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -1,7 +1,7 @@ /* * gstvapicompat.h - VA-API compatibility glue * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index e40fe0b7f3..b5c409240e 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -1,7 +1,7 @@ /* * gstvaapicontext.c - VA context abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index e83a991681..d1b12608dd 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -1,7 +1,7 @@ /* * gstvaapicontext.h - VA context abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidebug.h b/gst-libs/gst/vaapi/gstvaapidebug.h index 8e969782e0..f0359cf726 100644 --- a/gst-libs/gst/vaapi/gstvaapidebug.h +++ b/gst-libs/gst/vaapi/gstvaapidebug.h @@ -1,7 +1,7 @@ /* * gstvaapidebug.h - VA-API debugging utilities * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 4fe84cbe7c..006e17bbed 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder.c - VA decoder abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index f7210d3311..73db5fd7a7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder.h - VA decoder abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index e8fc98121f..8124a3c6a1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_ffmpeg.c - FFmpeg-based decoder * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h index ef0331801d..68c61ee7d0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_ffmpeg.h - FFmpeg-based decoder * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 546d93b8e6..76f287901d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_priv.h - VA decoder abstraction (private definitions) * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index ae1782d46c..d03cfa758b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1,7 +1,7 @@ /* * gstvaapidisplay.c - VA display abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 91e044d81a..075c1f617f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay.h - VA display abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 7e3731b327..660d757627 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -1,7 +1,7 @@ /* * gstvaapidisplay_glx.c - VA/GLX display abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index 8c3ff156d1..abb9d1bf6a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_glx.h - VA/GLX display abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index 6e13202f1d..48b4bac5fb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_glx_priv.h - Internal VA/GLX interface * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 1ab5cc6898..5f2ff14122 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_priv.h - Base VA display (private definitions) * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 9e7ca77cb9..de98a005b6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -1,7 +1,7 @@ /* * gstvaapidisplay_x11.c - VA/X11 display abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 732057e61e..71c8a8ded8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_x11.h - VA/X11 display abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index eb7237c404..b717d2f129 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_x11_priv.h - Internal VA/X11 interface * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index b496a74971..f0186c3e8d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -1,7 +1,7 @@ /* * gstvaapiimage.c - VA image abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index e17a0dd3d4..f93bfa87d7 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -1,7 +1,7 @@ /* * gstvaapiimage.h - VA image abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index a34157aff5..9218c68776 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -1,7 +1,7 @@ /* * gstvaapiimageformat.c - VA image format abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index 16029b658f..f83e3bacbc 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -1,7 +1,7 @@ /* * gstvaapiimageformat.h - VA image format abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index bdc1bb80c0..e5738cea21 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -1,7 +1,7 @@ /* * gstvaapiimagepool.c - Gst VA image pool * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index 0592910daf..70f8a6b393 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -1,7 +1,7 @@ /* * gstvaapiimagepool.h - Gst VA image pool * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 800a29781d..66cbb3024e 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -1,7 +1,7 @@ /* * gstvaapiobject.c - Base VA object * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index a5313538f6..066b0865e3 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -1,7 +1,7 @@ /* * gstvaapiobject.h - Base VA object * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 7de6721175..825b21cb77 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -1,7 +1,7 @@ /* * gstvaapiobject_priv.h - Base VA object (private definitions) * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.c b/gst-libs/gst/vaapi/gstvaapiparamspecs.c index 3545f64555..41d5fe6ca2 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.c +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.c @@ -1,7 +1,7 @@ /* * gstvaapiparamspecs.c - GParamSpecs for some of our types * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.h b/gst-libs/gst/vaapi/gstvaapiparamspecs.h index 2ebdfbdc9c..6bfb28996e 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.h +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.h @@ -1,7 +1,7 @@ /* * gstvaapiparamspecs.h - GParamSpecs for some of our types * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 40c9760af0..67a3f57cce 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -1,7 +1,7 @@ /* * gstvaapiprofile.c - VA profile abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 7ab27ab8e2..1da138165f 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -1,7 +1,7 @@ /* * gstvaapiprofile.h - VA profile abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 2164a19120..046aa68aca 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -1,7 +1,7 @@ /* * gstvaapisubpicture.c - VA subpicture abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index bf7e22c999..4cdbc7c081 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -1,7 +1,7 @@ /* * gstvaapisubpicture.h - VA subpicture abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 941f397142..4d9c5b0f1f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -1,7 +1,7 @@ /* * gstvaapisurface.c - VA surface abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 11fc35567a..840e029004 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -1,7 +1,7 @@ /* * gstvaapisurface.h - VA surface abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 221bc33ffb..a68be6410e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -1,7 +1,7 @@ /* * gstvaapisurfacepool.c - Gst VA surface pool * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 2b38d11484..dfcef4d763 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -1,7 +1,7 @@ /* * gstvaapisurfacepool.h - Gst VA surface pool * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 8f7c673ad5..f1a9206c50 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -1,7 +1,7 @@ /* * gstvaapisurfaceproxy.c - VA surface proxy * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 364244e23b..b24caf5e61 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -1,7 +1,7 @@ /* * gstvaapisurfaceproxy.h - VA surface proxy * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 48a7c0496c..f9a84f50ab 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -1,7 +1,7 @@ /* * gstvaapitexture.c - VA texture abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 54d341b526..a92c01529e 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -1,7 +1,7 @@ /* * gstvaapitexture.h - VA texture abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 047db2db6a..c0b555a5b9 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -1,7 +1,7 @@ /* * gstvaapitypes.h - Basic types * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index a855bf3f37..1530c9ea99 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -1,7 +1,7 @@ /* * gstvaapiutils.c - VA-API utilities * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 1f345ec088..50149073ae 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -1,7 +1,7 @@ /* * gstvaapiutils.h - VA-API utilities * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index bd3b07042f..b904ecc533 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -1,7 +1,7 @@ /* * gstvaapiutils_glx.c - GLX utilties * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 5309b7a14c..357b0fd333 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -1,7 +1,7 @@ /* * gstvaapiutils_glx.h - GLX utilties * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_gst.c b/gst-libs/gst/vaapi/gstvaapiutils_gst.c index f0b29fb0fb..7a0e7dae44 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_gst.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_gst.c @@ -1,7 +1,7 @@ /* * gstvaapiutils_gst.c - GST utilties * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_gst.h b/gst-libs/gst/vaapi/gstvaapiutils_gst.h index 86eaad01a5..350f20a3e5 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_gst.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_gst.h @@ -1,7 +1,7 @@ /* * gstvaapiutils_gst.h - GST utilties * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 50532283cb..7024b670f7 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -1,7 +1,7 @@ /* * gstvaapiutils_x11.c - X11 utilties * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index a3e8ad7967..df43f5bf41 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -1,7 +1,7 @@ /* * gstvaapiutils_x11.h - X11 utilties * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index a52c6e2805..44db35aec4 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -1,7 +1,7 @@ /* * gstvaapivalue.c - GValue implementations specific to VA-API * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index 2bed3766a8..8ba1985235 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -1,7 +1,7 @@ /* * gstvaapivalue.h - GValue implementations specific to VA-API * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 9f6ac63a41..912a4cdcc4 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -1,7 +1,7 @@ /* * gstvaapivideobuffer.c - Gst VA video buffer * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index 572d20cf9f..b0705e6c05 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -1,7 +1,7 @@ /* * gstvaapivideobuffer.h - Gstreamer/VA video buffer * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 891a6a8575..47a039f97e 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -1,7 +1,7 @@ /* * gstvaapivideopool.c - Video object pool abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index a7b44242af..21fe1a7b37 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -1,7 +1,7 @@ /* * gstvaapivideopool.h - Video object pool abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.c b/gst-libs/gst/vaapi/gstvaapivideosink.c index 7cceaa5260..7ba672039a 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.c +++ b/gst-libs/gst/vaapi/gstvaapivideosink.c @@ -1,7 +1,7 @@ /* * gstvaapivideosink.c - VA sink interface * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.h b/gst-libs/gst/vaapi/gstvaapivideosink.h index 1810a8e189..01bf01ba04 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.h +++ b/gst-libs/gst/vaapi/gstvaapivideosink.h @@ -1,7 +1,7 @@ /* * gstvaapivideosink.h - VA sink interface * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 4aab5d42a3..db262cfec9 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -1,7 +1,7 @@ /* * gstvaapiwindow.c - VA window abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 36c773d4b2..7743d615da 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -1,7 +1,7 @@ /* * gstvaapiwindow.h - VA window abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 6613aa6146..cb132ca0a3 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -1,7 +1,7 @@ /* * gstvaapiwindow_glx.c - VA/GLX window abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index 3e58552d73..fb896a72b6 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -1,7 +1,7 @@ /* * gstvaapiwindow_glx.h - VA/GLX window abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index dc2c5fd145..f41e3aa83a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -1,7 +1,7 @@ /* * gstvaapiwindow_x11.c - VA/X11 window abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index 54b4edbb63..b720a8ecc4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -1,7 +1,7 @@ /* * gstvaapiwindow_x11.h - VA/X11 window abstraction * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index f10bafdcfc..4b52101f7c 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -1,7 +1,7 @@ /* * gstvaapiconvert.c - VA-API video converter * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gst/vaapiconvert/gstvaapiconvert.h b/gst/vaapiconvert/gstvaapiconvert.h index d5a6bbc62c..81e3e68984 100644 --- a/gst/vaapiconvert/gstvaapiconvert.h +++ b/gst/vaapiconvert/gstvaapiconvert.h @@ -1,7 +1,7 @@ /* * gstvaapiconvert.h - VA-API video converter * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index f9f7a336ee..224fed7c54 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -1,7 +1,7 @@ /* * gstvaapidecode.c - VA-API video decoder * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gst/vaapidecode/gstvaapidecode.h b/gst/vaapidecode/gstvaapidecode.h index 6d07bc5b63..ce39f0e0b1 100644 --- a/gst/vaapidecode/gstvaapidecode.h +++ b/gst/vaapidecode/gstvaapidecode.h @@ -1,7 +1,7 @@ /* * gstvaapidecode.h - VA-API video decoder * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index fc86ec0a13..396c6cf46e 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -1,7 +1,7 @@ /* * gstvaapisink.c - VA-API video sink * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gst/vaapisink/gstvaapisink.h b/gst/vaapisink/gstvaapisink.h index 1a9014b6a9..a2543fe729 100644 --- a/gst/vaapisink/gstvaapisink.h +++ b/gst/vaapisink/gstvaapisink.h @@ -1,7 +1,7 @@ /* * gstvaapisink.h - VA-API video sink * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/image.c b/tests/image.c index be628c3d05..809adc3bee 100644 --- a/tests/image.c +++ b/tests/image.c @@ -1,7 +1,7 @@ /* * image.c - Image utilities for the tests * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/image.h b/tests/image.h index c0558a681d..d748544656 100644 --- a/tests/image.h +++ b/tests/image.h @@ -1,7 +1,7 @@ /* * image.h - Image utilities for the tests * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-decode.c b/tests/test-decode.c index 995e691c58..7e63bef406 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -1,7 +1,7 @@ /* * test-decode.c - Test GstVaapiDecoder * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-decode.h b/tests/test-decode.h index 6d9aa2b021..2ac862e65b 100644 --- a/tests/test-decode.h +++ b/tests/test-decode.h @@ -1,7 +1,7 @@ /* * test-decode.h - Test GstVaapiDecoder * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-display.c b/tests/test-display.c index 57972e7db8..59e03b258f 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -1,7 +1,7 @@ /* * test-display.c - Test GstVaapiDisplayX11 * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-h264.c b/tests/test-h264.c index c00c275fb5..bdb0274dbf 100644 --- a/tests/test-h264.c +++ b/tests/test-h264.c @@ -1,7 +1,7 @@ /* * test-h264.c - H.264 test data * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-h264.h b/tests/test-h264.h index ae94bcd0b8..7f24514451 100644 --- a/tests/test-h264.h +++ b/tests/test-h264.h @@ -1,7 +1,7 @@ /* * test-h264.h - H.264 test data * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-mpeg2.c b/tests/test-mpeg2.c index e12b25964a..8ee4c34571 100644 --- a/tests/test-mpeg2.c +++ b/tests/test-mpeg2.c @@ -1,7 +1,7 @@ /* * test-mpeg2.c - MPEG-2 test data * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-mpeg2.h b/tests/test-mpeg2.h index 0825155054..54c43b6a80 100644 --- a/tests/test-mpeg2.h +++ b/tests/test-mpeg2.h @@ -1,7 +1,7 @@ /* * test-mpeg2.h - MPEG-2 test data * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index 933239163c..f3b5c3becb 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -1,7 +1,7 @@ /* * test-surfaces.c - Test GstVaapiSurface and GstVaapiSurfacePool * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-textures.c b/tests/test-textures.c index 2d7f1addab..865dd62074 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -1,7 +1,7 @@ /* * test-textures.c - Test GstVaapiTexture * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-vc1.c b/tests/test-vc1.c index 79e2ccaa8b..8b7c2dcb8e 100644 --- a/tests/test-vc1.c +++ b/tests/test-vc1.c @@ -1,7 +1,7 @@ /* * test-vc1.c - VC-1 test data * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-vc1.h b/tests/test-vc1.h index 05927b601d..c57a5d6509 100644 --- a/tests/test-vc1.h +++ b/tests/test-vc1.h @@ -1,7 +1,7 @@ /* * test-vc1.h - VC-1 test data * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tests/test-windows.c b/tests/test-windows.c index f6ea9d811b..74ac01fdef 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -1,7 +1,7 @@ /* * test-windows.c - Test GstVaapiWindow * - * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From d97bbd0f44d9d72e191d4101de1caabaa1595078 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 14 Jun 2011 15:59:08 +0200 Subject: [PATCH 0421/3781] 0.2.6. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 403f8bc7a8..c747f280ca 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [2]) -m4_define([gst_vaapi_micro_version], [5]) +m4_define([gst_vaapi_micro_version], [6]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From 41e3e88c3a1e1874f1f60998a3ceb85b19d71fb2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 15 Jul 2011 16:08:08 +0200 Subject: [PATCH 0422/3781] Fix build with libva headers not in a standard include dir. --- gst/vaapiconvert/Makefile.am | 1 + gst/vaapidecode/Makefile.am | 1 + gst/vaapisink/Makefile.am | 1 + tests/Makefile.am | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapiconvert/Makefile.am b/gst/vaapiconvert/Makefile.am index 34a865990d..545e4cbed7 100644 --- a/gst/vaapiconvert/Makefile.am +++ b/gst/vaapiconvert/Makefile.am @@ -1,6 +1,7 @@ plugin_LTLIBRARIES = libgstvaapiconvert.la libgstvaapi_CFLAGS = \ + $(LIBVA_CFLAGS) \ -I$(top_srcdir)/gst-libs libgstvaapi_LIBS = \ diff --git a/gst/vaapidecode/Makefile.am b/gst/vaapidecode/Makefile.am index f537e6e1f3..17bf0c988a 100644 --- a/gst/vaapidecode/Makefile.am +++ b/gst/vaapidecode/Makefile.am @@ -1,6 +1,7 @@ plugin_LTLIBRARIES = libgstvaapidecode.la libgstvaapi_CFLAGS = \ + $(LIBVA_CFLAGS) \ -I$(top_srcdir)/gst-libs libgstvaapi_LIBS = \ diff --git a/gst/vaapisink/Makefile.am b/gst/vaapisink/Makefile.am index 81ed421b9c..a11b1b59ec 100644 --- a/gst/vaapisink/Makefile.am +++ b/gst/vaapisink/Makefile.am @@ -1,6 +1,7 @@ plugin_LTLIBRARIES = libgstvaapisink.la libgstvaapi_CFLAGS = \ + $(LIBVA_CFLAGS) \ -I$(top_srcdir)/gst-libs if USE_VAAPISINK_GLX diff --git a/tests/Makefile.am b/tests/Makefile.am index 1441704844..40f28e3e17 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -11,7 +11,7 @@ noinst_PROGRAMS += \ $(NULL) endif -TEST_CFLAGS = -I$(top_srcdir)/gst-libs $(GST_CFLAGS) +TEST_CFLAGS = $(LIBVA_CFLAGS) -I$(top_srcdir)/gst-libs $(GST_CFLAGS) TEST_X11_CFLAGS = -DUSE_X11 $(X11_CFLAGS) TEST_GLX_CFLAGS = -DUSE_GLX $(GLX_CFLAGS) TEST_MIX_CFLAGS = $(TEST_X11_CFLAGS) From f0b9cbd8995aabdeae0997281e62719dfa98cc5d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 19 Jul 2011 17:38:40 +0200 Subject: [PATCH 0423/3781] Use pretty build output with automake >= 1.11. --- configure.ac | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configure.ac b/configure.ac index c747f280ca..faec8df827 100644 --- a/configure.ac +++ b/configure.ac @@ -65,6 +65,12 @@ AC_SUBST(GST_MAJORMINOR) AC_SUBST(GST_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) +dnl Use pretty build output with automake >= 1.11 +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [ + AM_DEFAULT_VERBOSITY=1 + AC_SUBST(AM_DEFAULT_VERBOSITY) +]) + dnl Check for tools AC_PROG_CC AM_PROG_CC_C_O From 7711aa1325d183bae5f0de59041825523600ce80 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Jul 2011 15:42:16 +0200 Subject: [PATCH 0424/3781] Bump version for development. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index faec8df827..76a684a91a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [2]) -m4_define([gst_vaapi_micro_version], [6]) +m4_define([gst_vaapi_micro_version], [7]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From ab6efa04cae5750e32c75e3245ae654d68d6ca47 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Jul 2011 15:33:13 +0200 Subject: [PATCH 0425/3781] Add canonical form (type name) of VA surface caps. --- gst-libs/gst/vaapi/gstvaapisurface.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 840e029004..15fe78d170 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -33,13 +33,21 @@ typedef enum _GstVaapiChromaType GstVaapiChromaType; typedef enum _GstVaapiSurfaceStatus GstVaapiSurfaceStatus; typedef enum _GstVaapiSurfaceRenderFlags GstVaapiSurfaceRenderFlags; +/** + * GST_VAAPI_SURFACE_CAPS_NAME: + * + * Generic caps type for VA surfaces. + */ +#define GST_VAAPI_SURFACE_CAPS_NAME \ + "video/x-vaapi-surface" + /** * GST_VAAPI_SURFACE_CAPS: * * Generic caps for VA surfaces. */ #define GST_VAAPI_SURFACE_CAPS \ - "video/x-vaapi-surface, " \ + GST_VAAPI_SURFACE_CAPS_NAME ", " \ "width = (int) [ 1, MAX ]," \ "height = (int) [ 1, MAX ]," \ "framerate = (fraction) [ 0, MAX ]" From 2f91c9e8c199cebd45288574d9b8889b49932a0c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Jul 2011 15:34:48 +0200 Subject: [PATCH 0426/3781] Report caps update only once per video resolution change. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 006e17bbed..58242ba7e6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -440,24 +440,24 @@ gst_vaapi_decoder_set_picture_size( ) { GstVaapiDecoderPrivate * const priv = decoder->priv; - - g_object_freeze_notify(G_OBJECT(decoder)); + gboolean size_changed = FALSE; if (priv->width != width) { GST_DEBUG("picture width changed to %d", width); priv->width = width; gst_caps_set_simple(priv->caps, "width", G_TYPE_INT, width, NULL); - g_object_notify(G_OBJECT(decoder), "caps"); + size_changed = TRUE; } if (priv->height != height) { GST_DEBUG("picture height changed to %d", height); priv->height = height; gst_caps_set_simple(priv->caps, "height", G_TYPE_INT, height, NULL); - g_object_notify(G_OBJECT(decoder), "caps"); + size_changed = TRUE; } - g_object_thaw_notify(G_OBJECT(decoder)); + if (size_changed) + g_object_notify(G_OBJECT(decoder), "caps"); } void From f2906b7ad0efe0553f1d7cba6168f7b28a10a931 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Jul 2011 15:39:51 +0200 Subject: [PATCH 0427/3781] Fix decoding of MPEG-2 TS files. --- gst/vaapidecode/gstvaapidecode.c | 109 +++++++++++++++++++++++-------- gst/vaapidecode/gstvaapidecode.h | 2 + 2 files changed, 84 insertions(+), 27 deletions(-) diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 224fed7c54..363cc9d412 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -93,6 +93,66 @@ enum { PROP_USE_FFMPEG, }; +static gboolean +gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps); + +static void +gst_vaapi_decoder_notify_caps(GObject *obj, GParamSpec *pspec, void *user_data) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data); + GstCaps *caps; + + g_assert(decode->decoder == GST_VAAPI_DECODER(obj)); + + caps = gst_vaapi_decoder_get_caps(decode->decoder); + gst_vaapidecode_update_src_caps(decode, caps); +} + +static inline gboolean +gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps) +{ + if (decode->sinkpad_caps) + gst_caps_unref(decode->sinkpad_caps); + decode->sinkpad_caps = gst_caps_ref(caps); + return TRUE; +} + +static gboolean +gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) +{ + GstCaps *other_caps; + GstStructure *structure; + const GValue *v_width, *v_height, *v_framerate, *v_par; + gboolean success; + + if (!decode->srcpad_caps) { + decode->srcpad_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); + if (!decode->srcpad_caps) + return FALSE; + } + + structure = gst_caps_get_structure(caps, 0); + v_width = gst_structure_get_value(structure, "width"); + v_height = gst_structure_get_value(structure, "height"); + v_framerate = gst_structure_get_value(structure, "framerate"); + v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); + + structure = gst_caps_get_structure(decode->srcpad_caps, 0); + if (v_width && v_height) { + gst_structure_set_value(structure, "width", v_width); + gst_structure_set_value(structure, "height", v_height); + } + if (v_framerate) + gst_structure_set_value(structure, "framerate", v_framerate); + if (v_par) + gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); + + other_caps = gst_caps_copy(decode->srcpad_caps); + success = gst_pad_set_caps(decode->srcpad, other_caps); + gst_caps_unref(other_caps); + return success; +} + static void gst_vaapidecode_release(GstVaapiDecode *decode, GObject *dead_object) { @@ -231,6 +291,13 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) if (!decode->decoder) return FALSE; + g_signal_connect( + G_OBJECT(decode->decoder), + "notify::caps", + G_CALLBACK(gst_vaapi_decoder_notify_caps), + decode + ); + decode->decoder_caps = gst_caps_ref(caps); return TRUE; } @@ -300,6 +367,16 @@ gst_vaapidecode_finalize(GObject *object) gst_vaapidecode_destroy(decode); + if (decode->sinkpad_caps) { + gst_caps_unref(decode->sinkpad_caps); + decode->sinkpad_caps = NULL; + } + + if (decode->srcpad_caps) { + gst_caps_unref(decode->srcpad_caps); + decode->srcpad_caps = NULL; + } + if (decode->display) { g_object_unref(decode->display); decode->display = NULL; @@ -490,38 +567,14 @@ static gboolean gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) { GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); - GstCaps *other_caps = NULL; - GstStructure *structure; - const GValue *v_width, *v_height, *v_framerate, *v_par; - gboolean success; g_return_val_if_fail(pad == decode->sinkpad, FALSE); - other_caps = gst_caps_from_string(gst_vaapidecode_src_caps_str); - if (!other_caps) + if (!gst_vaapidecode_update_sink_caps(decode, caps)) return FALSE; - - /* Negotiation succeeded, so now configure ourselves */ - structure = gst_caps_get_structure(caps, 0); - v_width = gst_structure_get_value(structure, "width"); - v_height = gst_structure_get_value(structure, "height"); - v_framerate = gst_structure_get_value(structure, "framerate"); - v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); - - structure = gst_caps_get_structure(other_caps, 0); - gst_structure_set_value(structure, "width", v_width); - gst_structure_set_value(structure, "height", v_height); - if (v_framerate) - gst_structure_set_value(structure, "framerate", v_framerate); - if (v_par) - gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); - - success = gst_pad_set_caps(decode->srcpad, other_caps); - gst_caps_unref(other_caps); - if (!success) + if (!gst_vaapidecode_update_src_caps(decode, caps)) return FALSE; - - return gst_vaapidecode_reset(decode, caps); + return gst_vaapidecode_reset(decode, decode->sinkpad_caps); } static GstFlowReturn @@ -584,6 +637,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) gst_element_class_get_pad_template(element_class, "sink"), "sink" ); + decode->sinkpad_caps = NULL; gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps); gst_pad_set_setcaps_function(decode->sinkpad, gst_vaapidecode_set_caps); @@ -596,6 +650,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) gst_element_class_get_pad_template(element_class, "src"), "src" ); + decode->srcpad_caps = NULL; gst_pad_use_fixed_caps(decode->srcpad); gst_pad_set_event_function(decode->srcpad, gst_vaapidecode_src_event); diff --git a/gst/vaapidecode/gstvaapidecode.h b/gst/vaapidecode/gstvaapidecode.h index ce39f0e0b1..3ab509e505 100644 --- a/gst/vaapidecode/gstvaapidecode.h +++ b/gst/vaapidecode/gstvaapidecode.h @@ -60,7 +60,9 @@ struct _GstVaapiDecode { GstElement parent_instance; GstPad *sinkpad; + GstCaps *sinkpad_caps; GstPad *srcpad; + GstCaps *srcpad_caps; GstVaapiDisplay *display; GstVaapiDecoder *decoder; GMutex *decoder_mutex; From a9a9d72e96700aa2af0a1fbd4da0ef00fc5f7fbb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Jul 2011 15:55:47 +0200 Subject: [PATCH 0428/3781] Fix build with newer FFmpeg versions. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 8124a3c6a1..c3c259a9df 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -478,13 +478,18 @@ decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(ffdecoder); GstVaapiSurface *surface; int bytes_read, got_picture = 0; + AVPacket pkt; + + av_init_packet(&pkt); + pkt.data = buf; + pkt.size = buf_size; GST_VAAPI_DISPLAY_LOCK(display); - bytes_read = avcodec_decode_video( + bytes_read = avcodec_decode_video2( priv->avctx, priv->frame, &got_picture, - buf, buf_size + &pkt ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!got_picture) @@ -530,12 +535,14 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) if (priv->pctx) { do { - int parsed_size = av_parser_parse( + int parsed_size; + parsed_size = av_parser_parse2( priv->pctx, priv->avctx, &outbuf, &outbuf_size, GST_BUFFER_DATA(buffer) + inbuf_ofs, inbuf_size, - inbuf_ts, inbuf_ts + inbuf_ts, inbuf_ts, + AV_NOPTS_VALUE ); got_frame = outbuf && outbuf_size > 0; From f94bd448169a4753dbdc4921bb3bba964cc8d83a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Jul 2011 15:59:00 +0200 Subject: [PATCH 0429/3781] Updates. --- NEWS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index ea6ed84963..ce036d1130 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,10 @@ -gst-vaapi NEWS -- summary of changes. 2011-06-14 +gst-vaapi NEWS -- summary of changes. 2011-07-DD Copyright (C) 2010 Splitted-Desktop Systems +Version 0.2.7 - DD.Jul.2011 +* Fix MPEG-2 TS decoding +* Fix build with newer versions of FFmpeg + Version 0.2.6 - 14.Jun.2011 * Fix licensing terms (LGPL v2.1) From 00bb1ca6b42fdd1deb917debc9c4debfe6d78769 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 1 Aug 2011 14:15:39 +0200 Subject: [PATCH 0430/3781] Add Intel copyright information. --- NEWS | 3 ++- README | 3 ++- debian.upstream/copyright | 3 ++- gst-libs/gst/vaapi/gstvaapidecoder.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 1 + gst-libs/gst/vaapi/gstvaapisurface.h | 1 + gst/vaapidecode/gstvaapidecode.c | 1 + gst/vaapidecode/gstvaapidecode.h | 1 + 8 files changed, 11 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index ce036d1130..a0ae679c31 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ gst-vaapi NEWS -- summary of changes. 2011-07-DD -Copyright (C) 2010 Splitted-Desktop Systems +Copyright (C) 2010-2011 Splitted-Desktop Systems +Copyright (C) 2011 Intel Corporation Version 0.2.7 - DD.Jul.2011 * Fix MPEG-2 TS decoding diff --git a/README b/README index 9e76d2a268..95987fa753 100644 --- a/README +++ b/README @@ -2,7 +2,8 @@ gstreamer-vaapi VA-API support to GStreamer - Copyright (C) 2010 Splitted-Desktop Systems + Copyright (C) 2010-2011 Splitted-Desktop Systems + Copyright (C) 2011 Intel Corporation License diff --git a/debian.upstream/copyright b/debian.upstream/copyright index a7b3a141ed..a78f4e1fbd 100644 --- a/debian.upstream/copyright +++ b/debian.upstream/copyright @@ -11,7 +11,8 @@ Copyright: License: - Copyright (C) 2010, Splitted-Desktop Systems. + Copyright (C) 2010-2011, Splitted-Desktop Systems. + Copyright (C) 2011, Intel Corporation. gstreamer-vaapi helper libraries are available under the terms of the GNU Lesser General Public License v2.1+. diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 58242ba7e6..2f0274b96a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -2,6 +2,7 @@ * gstvaapidecoder.c - VA decoder abstraction * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index c3c259a9df..e12f95785f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -2,6 +2,7 @@ * gstvaapidecoder_ffmpeg.c - FFmpeg-based decoder * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 15fe78d170..bc513f7da7 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -2,6 +2,7 @@ * gstvaapisurface.h - VA surface abstraction * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 363cc9d412..266309c7ec 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -2,6 +2,7 @@ * gstvaapidecode.c - VA-API video decoder * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gst/vaapidecode/gstvaapidecode.h b/gst/vaapidecode/gstvaapidecode.h index 3ab509e505..9c7759f53d 100644 --- a/gst/vaapidecode/gstvaapidecode.h +++ b/gst/vaapidecode/gstvaapidecode.h @@ -2,6 +2,7 @@ * gstvaapidecode.h - VA-API video decoder * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From dcf44d0809672c76f9653500a78a850930e1c019 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 5 Sep 2011 16:18:14 +0200 Subject: [PATCH 0431/3781] vaapiconvert: use gst_vaapi_display_lookup_downstream() helper to get a VA display. --- gst/vaapiconvert/gstvaapiconvert.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index 4b52101f7c..b4625919b5 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include "gstvaapiconvert.h" #define GST_PLUGIN_NAME "vaapiconvert" @@ -299,15 +301,10 @@ static gboolean gst_vaapiconvert_start(GstBaseTransform *trans) { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); - GstVaapiVideoSink *sink; GstVaapiDisplay *display; - /* Look for a downstream vaapisink */ - sink = gst_vaapi_video_sink_lookup(GST_ELEMENT(trans)); - if (!sink) - return FALSE; - - display = gst_vaapi_video_sink_get_display(sink); + /* Look for a downstream display */ + display = gst_vaapi_display_lookup_downstream(GST_ELEMENT(trans)); if (!display) return FALSE; From f601d133ccfbaacfc6910e5d00c7c76be5231d70 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 5 Sep 2011 17:23:05 +0200 Subject: [PATCH 0432/3781] vaapiconvert: protect access to direct_rendering. --- gst/vaapiconvert/gstvaapiconvert.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index b4625919b5..c258a2abba 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -197,7 +197,9 @@ gst_vaapiconvert_set_property( switch (prop_id) { case PROP_DIRECT_RENDERING: + GST_OBJECT_LOCK(convert); convert->direct_rendering = g_value_get_uint(value); + GST_OBJECT_UNLOCK(convert); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); From e00ec1f57618a9ae177548ce0f57483000567a0b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 6 Sep 2011 16:49:43 +0200 Subject: [PATCH 0433/3781] Add gst_vaapi_video_buffer_new_from_buffer(). Add helper function to bind a foreign buffer into a GstVaapiVideoBuffer. Any image, surface or surface proxy will be inherited from the source buffer if it is a GstVaapiVideoBuffer. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapivideobuffer.c | 43 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivideobuffer.h | 3 ++ 3 files changed, 47 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index a37b4579e2..722d6b4b4c 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -187,6 +187,7 @@ GstVaapiVideoBuffer GstVaapiVideoBufferClass gst_vaapi_video_buffer_new gst_vaapi_video_buffer_new_from_pool +gst_vaapi_video_buffer_new_from_buffer gst_vaapi_video_buffer_new_with_image gst_vaapi_video_buffer_new_with_surface gst_vaapi_video_buffer_new_with_surface_proxy diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 912a4cdcc4..ee7ff66247 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -47,6 +47,7 @@ struct _GstVaapiVideoBufferPrivate { GstVaapiVideoPool *surface_pool; GstVaapiSurface *surface; GstVaapiSurfaceProxy *proxy; + GstBuffer *buffer; }; static void @@ -118,6 +119,11 @@ gst_vaapi_video_buffer_destroy_surface(GstVaapiVideoBuffer *buffer) g_object_unref(priv->surface_pool); priv->surface_pool = NULL; } + + if (priv->buffer) { + gst_buffer_unref(priv->buffer); + priv->buffer = NULL; + } } static void @@ -159,6 +165,7 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) priv->surface_pool = NULL; priv->surface = NULL; priv->proxy = NULL; + priv->buffer = NULL; } /** @@ -232,6 +239,42 @@ gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) return NULL; } +/** + * gst_vaapi_video_buffer_new_from_buffer: + * @buffer: a #GstBuffer + * + * Creates a #GstBuffer with video objects bound to @buffer video + * objects, if any. + * + * Return value: the newly allocated #GstBuffer, or %NULL on error + */ +GstBuffer * +gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) +{ + GstVaapiVideoBuffer *inbuf, *outbuf; + + if (!GST_VAAPI_IS_VIDEO_BUFFER(buffer)) { + if (!buffer->parent || !GST_VAAPI_IS_VIDEO_BUFFER(buffer->parent)) + return NULL; + buffer = buffer->parent; + } + inbuf = GST_VAAPI_VIDEO_BUFFER(buffer); + + outbuf = _gst_vaapi_video_buffer_new(); + if (!outbuf) + return NULL; + + if (inbuf->priv->image) + gst_vaapi_video_buffer_set_image(outbuf, inbuf->priv->image); + if (inbuf->priv->surface) + gst_vaapi_video_buffer_set_surface(outbuf, inbuf->priv->surface); + if (inbuf->priv->proxy) + gst_vaapi_video_buffer_set_surface_proxy(outbuf, inbuf->priv->proxy); + + outbuf->priv->buffer = gst_buffer_ref(buffer); + return GST_BUFFER(outbuf); +} + /** * gst_vaapi_video_buffer_new_with_image: * @image: a #GstVaapiImage diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index b0705e6c05..a00df2a510 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -90,6 +90,9 @@ gst_vaapi_video_buffer_new(GstVaapiDisplay *display); GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); +GstBuffer * +gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer); + GstBuffer * gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image); From 8589e8279c363523780664827539531fc953c160 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 5 Sep 2011 16:20:20 +0200 Subject: [PATCH 0434/3781] vaapiconvert: fix direct-rendering mode. --- NEWS | 1 + gst/vaapiconvert/gstvaapiconvert.c | 61 ++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/NEWS b/NEWS index a0ae679c31..3d86cfd98c 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Copyright (C) 2011 Intel Corporation Version 0.2.7 - DD.Jul.2011 * Fix MPEG-2 TS decoding * Fix build with newer versions of FFmpeg +* Fix vaapiconvert direct-rendering modes Version 0.2.6 - 14.Jun.2011 * Fix licensing terms (LGPL v2.1) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index c258a2abba..0b9deaba73 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -77,6 +77,12 @@ GST_BOILERPLATE( GstBaseTransform, GST_TYPE_BASE_TRANSFORM); +/* + * Direct rendering levels (direct-rendering) + * 0: upstream allocated YUV pixels + * 1: vaapiconvert allocated YUV pixels (mapped from VA image) + * 2: vaapiconvert allocated YUV pixels (mapped from VA surface) + */ #define DIRECT_RENDERING_DEFAULT 2 enum { @@ -334,10 +340,11 @@ gst_vaapiconvert_transform( ) { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); - GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(outbuf); + GstVaapiVideoBuffer *vbuffer; GstVaapiSurface *surface; GstVaapiImage *image; + vbuffer = GST_VAAPI_VIDEO_BUFFER(outbuf); surface = gst_vaapi_video_buffer_get_surface(vbuffer); if (!surface) return GST_FLOW_UNEXPECTED; @@ -347,12 +354,9 @@ gst_vaapiconvert_transform( GST_DEBUG("GstVaapiVideoBuffer was expected"); return GST_FLOW_UNEXPECTED; } - if (inbuf != outbuf) { - GST_DEBUG("same GstVaapiVideoBuffer was expected on both pads"); - return GST_FLOW_UNEXPECTED; - } - image = gst_vaapi_video_buffer_get_image(vbuffer); + vbuffer = GST_VAAPI_VIDEO_BUFFER(inbuf); + image = gst_vaapi_video_buffer_get_image(vbuffer); if (!image) return GST_FLOW_UNEXPECTED; if (!gst_vaapi_image_unmap(image)) @@ -571,6 +575,8 @@ gst_vaapiconvert_buffer_alloc( GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); GstBuffer *buffer = NULL; GstVaapiImage *image = NULL; + GstVaapiSurface *surface = NULL; + GstVaapiVideoBuffer *vbuffer; /* Check if we can use direct-rendering */ if (!gst_vaapiconvert_negotiate_buffers(convert, caps, caps)) @@ -578,26 +584,32 @@ gst_vaapiconvert_buffer_alloc( if (!convert->direct_rendering) return GST_FLOW_OK; - buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); - if (!buffer) - goto error; - - GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); - GstVaapiSurface *surface; switch (convert->direct_rendering) { case 2: + buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); + if (!buffer) + goto error; + vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); + surface = gst_vaapi_video_buffer_get_surface(vbuffer); image = gst_vaapi_surface_derive_image(surface); if (image) { gst_vaapi_video_buffer_set_image(vbuffer, image); break; } + /* We can't use the derive-image optimization. Disable it. */ convert->direct_rendering = 1; + gst_buffer_unref(buffer); + buffer = NULL; + case 1: - if (!gst_vaapi_video_buffer_set_image_from_pool(vbuffer, convert->images)) + buffer = gst_vaapi_video_buffer_new_from_pool(convert->images); + if (!buffer) goto error; - image = gst_vaapi_video_buffer_get_image(vbuffer); + vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); + + image = gst_vaapi_video_buffer_get_image(vbuffer); break; } g_assert(image); @@ -614,6 +626,7 @@ gst_vaapiconvert_buffer_alloc( error: /* We can't use the inout-buffers optimization. Disable it. */ + GST_DEBUG("disable in/out buffer optimization"); if (buffer) gst_buffer_unref(buffer); convert->direct_rendering = 0; @@ -651,15 +664,21 @@ gst_vaapiconvert_prepare_output_buffer( ) { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); - GstBuffer *buffer; + GstBuffer *buffer = NULL; + GstFlowReturn ret; - if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) - buffer = gst_buffer_ref(inbuf); - else { - if (convert->direct_rendering) { - GST_DEBUG("upstream element destroyed our inout buffer"); - convert->direct_rendering = 0; + if (convert->direct_rendering == 2) { + if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) { + buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf); + GST_BUFFER_SIZE(buffer) = size; } + else { + GST_DEBUG("upstream element destroyed our in/out buffer"); + convert->direct_rendering = 1; + } + } + + if (!buffer) { buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); if (!buffer) return GST_FLOW_UNEXPECTED; From 0a07620f37f3b6da0962b47494c744f82603cb27 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 6 Sep 2011 17:47:10 +0200 Subject: [PATCH 0435/3781] vaapiconvert: fix memory leak (VA surface image). --- gst/vaapiconvert/gstvaapiconvert.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index 0b9deaba73..bdbb6f9cc1 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -595,6 +595,7 @@ gst_vaapiconvert_buffer_alloc( image = gst_vaapi_surface_derive_image(surface); if (image) { gst_vaapi_video_buffer_set_image(vbuffer, image); + gst_object_unref(image); /* video buffer owns an extra reference */ break; } From dd879638cafc89000cf1d97cc768fb417e150301 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 6 Sep 2011 18:34:33 +0200 Subject: [PATCH 0436/3781] vaapiconvert: fix autodetection for vaDeriveImage() support. --- gst/vaapiconvert/gstvaapiconvert.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index bdbb6f9cc1..faf8b033cc 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -493,7 +493,8 @@ gst_vaapiconvert_ensure_surface_pool(GstVaapiConvert *convert, GstCaps *caps) image = gst_vaapi_surface_derive_image(surface); if (image) { if (gst_vaapi_image_map(image)) { - if (convert->direct_rendering_caps == 1) + if (convert->direct_rendering_caps == 1 && + gst_vaapi_image_is_linear(image)) convert->direct_rendering_caps = 2; gst_vaapi_image_unmap(image); } @@ -593,7 +594,7 @@ gst_vaapiconvert_buffer_alloc( surface = gst_vaapi_video_buffer_get_surface(vbuffer); image = gst_vaapi_surface_derive_image(surface); - if (image) { + if (image && gst_vaapi_image_get_data_size(image) == size) { gst_vaapi_video_buffer_set_image(vbuffer, image); gst_object_unref(image); /* video buffer owns an extra reference */ break; From 6e9a816c480d4aa9d646fd28ef0f93944ba3c776 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 8 Sep 2011 13:09:17 +0200 Subject: [PATCH 0437/3781] vaapiconvert: warn when surface failed to be updated with image. --- gst/vaapiconvert/gstvaapiconvert.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index faf8b033cc..77661ebf08 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -343,6 +343,7 @@ gst_vaapiconvert_transform( GstVaapiVideoBuffer *vbuffer; GstVaapiSurface *surface; GstVaapiImage *image; + gboolean success; vbuffer = GST_VAAPI_VIDEO_BUFFER(outbuf); surface = gst_vaapi_video_buffer_get_surface(vbuffer); @@ -362,8 +363,10 @@ gst_vaapiconvert_transform( if (!gst_vaapi_image_unmap(image)) return GST_FLOW_UNEXPECTED; - if (convert->direct_rendering < 2) - gst_vaapi_surface_put_image(surface, image); + if (convert->direct_rendering < 2) { + if (!gst_vaapi_surface_put_image(surface, image)) + goto error_put_image; + } return GST_FLOW_OK; } @@ -372,9 +375,20 @@ gst_vaapiconvert_transform( return GST_FLOW_UNEXPECTED; gst_vaapi_image_update_from_buffer(image, inbuf); - gst_vaapi_surface_put_image(surface, image); + success = gst_vaapi_surface_put_image(surface, image); gst_vaapi_video_pool_put_object(convert->images, image); + if (!success) + goto error_put_image; return GST_FLOW_OK; + +error_put_image: + { + GST_WARNING("failed to upload %" GST_FOURCC_FORMAT " image " + "to surface 0x%08x", + GST_FOURCC_ARGS(gst_vaapi_image_get_format(image)), + gst_vaapi_surface_get_id(surface)); + return GST_FLOW_OK; + } } static GstCaps * From 857a024c6280e41995bf84ffbe4d71661c3b4c03 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 8 Sep 2011 14:40:08 +0200 Subject: [PATCH 0438/3781] Fix gst_vaapi_image_new_with_image(). --- gst-libs/gst/vaapi/gstvaapiimage.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index f0186c3e8d..c9096035ac 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -279,13 +279,16 @@ gst_vaapi_image_set_property( break; } case PROP_FORMAT: - priv->format = g_value_get_uint(value); + if (priv->create_image) + priv->format = g_value_get_uint(value); break; case PROP_WIDTH: - priv->width = g_value_get_uint(value); + if (priv->create_image) + priv->width = g_value_get_uint(value); break; case PROP_HEIGHT: - priv->height = g_value_get_uint(value); + if (priv->create_image) + priv->height = g_value_get_uint(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); From 64defe961529f2a431fab8b89c110718c87152d5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 8 Sep 2011 14:50:24 +0200 Subject: [PATCH 0439/3781] vaapiconvert: fix direct-rendering caps detection. --- gst/vaapiconvert/gstvaapiconvert.c | 122 +++++++++++++++++++++-------- gst/vaapiconvert/gstvaapiconvert.h | 2 + 2 files changed, 93 insertions(+), 31 deletions(-) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index 77661ebf08..a37d3941d6 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -288,9 +288,11 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) convert->display = NULL; convert->images = NULL; + convert->images_reset = FALSE; convert->image_width = 0; convert->image_height = 0; convert->surfaces = NULL; + convert->surfaces_reset = FALSE; convert->surface_width = 0; convert->surface_height = 0; convert->direct_rendering_caps = 0; @@ -449,8 +451,6 @@ static gboolean gst_vaapiconvert_ensure_image_pool(GstVaapiConvert *convert, GstCaps *caps) { GstStructure * const structure = gst_caps_get_structure(caps, 0); - GstVideoFormat vformat; - GstVaapiImage *image; gint width, height; gst_structure_get_int(structure, "width", &width); @@ -464,19 +464,7 @@ gst_vaapiconvert_ensure_image_pool(GstVaapiConvert *convert, GstCaps *caps) convert->images = gst_vaapi_image_pool_new(convert->display, caps); if (!convert->images) return FALSE; - - /* Check if we can alias sink & output buffers (same data_size) */ - if (gst_video_format_parse_caps(caps, &vformat, NULL, NULL)) { - image = gst_vaapi_video_pool_get_object(convert->images); - if (image) { - if (convert->direct_rendering_caps == 0 && - (gst_vaapi_image_is_linear(image) && - (gst_vaapi_image_get_data_size(image) == - gst_video_format_get_size(vformat, width, height)))) - convert->direct_rendering_caps = 1; - gst_vaapi_video_pool_put_object(convert->images, image); - } - } + convert->images_reset = TRUE; } return TRUE; } @@ -500,26 +488,97 @@ gst_vaapiconvert_ensure_surface_pool(GstVaapiConvert *convert, GstCaps *caps) convert->surfaces = gst_vaapi_surface_pool_new(convert->display, caps); if (!convert->surfaces) return FALSE; - - /* Check if we can access to the surface pixels directly */ - surface = gst_vaapi_video_pool_get_object(convert->surfaces); - if (surface) { - image = gst_vaapi_surface_derive_image(surface); - if (image) { - if (gst_vaapi_image_map(image)) { - if (convert->direct_rendering_caps == 1 && - gst_vaapi_image_is_linear(image)) - convert->direct_rendering_caps = 2; - gst_vaapi_image_unmap(image); - } - g_object_unref(image); - } - gst_vaapi_video_pool_put_object(convert->surfaces, surface); - } + convert->surfaces_reset = TRUE; } return TRUE; } +static GstVaapiImageFormat +gst_video_format_to_vaapi_image_format(GstVideoFormat vformat) +{ + GstVaapiImageFormat vaformat; + + switch (vformat) { + case GST_VIDEO_FORMAT_NV12: vaformat = GST_VAAPI_IMAGE_NV12; break; + case GST_VIDEO_FORMAT_YV12: vaformat = GST_VAAPI_IMAGE_YV12; break; + case GST_VIDEO_FORMAT_I420: vaformat = GST_VAAPI_IMAGE_I420; break; + case GST_VIDEO_FORMAT_AYUV: vaformat = GST_VAAPI_IMAGE_AYUV; break; + case GST_VIDEO_FORMAT_ARGB: vaformat = GST_VAAPI_IMAGE_ARGB; break; + case GST_VIDEO_FORMAT_RGBA: vaformat = GST_VAAPI_IMAGE_RGBA; break; + case GST_VIDEO_FORMAT_ABGR: vaformat = GST_VAAPI_IMAGE_ABGR; break; + case GST_VIDEO_FORMAT_BGRA: vaformat = GST_VAAPI_IMAGE_BGRA; break; + default: vaformat = (GstVaapiImageFormat)0; break; + } + return vaformat; +} + +static void +gst_vaapiconvert_ensure_direct_rendering_caps( + GstVaapiConvert *convert, + GstCaps *caps +) +{ + GstVaapiSurface *surface; + GstVaapiImage *image; + GstVaapiImageFormat vaformat; + GstVideoFormat vformat; + GstStructure *structure; + gint width, height; + + if (!convert->images_reset && !convert->surfaces_reset) + return; + + convert->images_reset = FALSE; + convert->surfaces_reset = FALSE; + convert->direct_rendering_caps = 0; + + structure = gst_caps_get_structure(caps, 0); + if (!structure) + return; + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + + /* Translate from Gst video format to VA image format */ + if (!gst_video_format_parse_caps(caps, &vformat, NULL, NULL)) + return; + if (!gst_video_format_is_yuv(vformat)) + return; + vaformat = gst_video_format_to_vaapi_image_format(vformat); + if (!vaformat) + return; + + /* Check if we can alias sink & output buffers (same data_size) */ + image = gst_vaapi_video_pool_get_object(convert->images); + if (image) { + if (convert->direct_rendering_caps == 0 && + (gst_vaapi_image_get_format(image) == vaformat && + gst_vaapi_image_is_linear(image) && + (gst_vaapi_image_get_data_size(image) == + gst_video_format_get_size(vformat, width, height)))) + convert->direct_rendering_caps = 1; + gst_vaapi_video_pool_put_object(convert->images, image); + } + + /* Check if we can access to the surface pixels directly */ + surface = gst_vaapi_video_pool_get_object(convert->surfaces); + if (surface) { + image = gst_vaapi_surface_derive_image(surface); + if (image) { + if (gst_vaapi_image_map(image)) { + if (convert->direct_rendering_caps == 1 && + (gst_vaapi_image_get_format(image) == vaformat && + gst_vaapi_image_is_linear(image) && + (gst_vaapi_image_get_data_size(image) == + gst_video_format_get_size(vformat, width, height)))) + convert->direct_rendering_caps = 2; + gst_vaapi_image_unmap(image); + } + g_object_unref(image); + } + gst_vaapi_video_pool_put_object(convert->surfaces, surface); + } +} + static gboolean gst_vaapiconvert_negotiate_buffers( GstVaapiConvert *convert, @@ -535,6 +594,7 @@ gst_vaapiconvert_negotiate_buffers( if (!gst_vaapiconvert_ensure_surface_pool(convert, outcaps)) return FALSE; + gst_vaapiconvert_ensure_direct_rendering_caps(convert, incaps); dr = MIN(convert->direct_rendering, convert->direct_rendering_caps); if (convert->direct_rendering != dr) { convert->direct_rendering = dr; diff --git a/gst/vaapiconvert/gstvaapiconvert.h b/gst/vaapiconvert/gstvaapiconvert.h index 81e3e68984..41f37ac3a4 100644 --- a/gst/vaapiconvert/gstvaapiconvert.h +++ b/gst/vaapiconvert/gstvaapiconvert.h @@ -73,6 +73,8 @@ struct _GstVaapiConvert { guint surface_height; guint direct_rendering_caps; guint direct_rendering; + unsigned int images_reset : 1; + unsigned int surfaces_reset : 1; }; struct _GstVaapiConvertClass { From bd74adeffa49d8d4ecfb52255471f51962e37ef9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Sep 2011 13:00:04 +0200 Subject: [PATCH 0440/3781] Cosmetics (sort source files). --- gst-libs/gst/vaapi/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index c488897974..1feca33835 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -70,6 +70,7 @@ libgstvaapi_source_h = \ $(NULL) libgstvaapi_source_priv_h = \ + gstvaapi_priv.h \ gstvaapicompat.h \ gstvaapidebug.h \ gstvaapidecoder_priv.h \ @@ -77,7 +78,6 @@ libgstvaapi_source_priv_h = \ gstvaapiobject_priv.h \ gstvaapiutils.h \ gstvaapiutils_gst.h \ - gstvaapi_priv.h \ $(libgst_vaapi_ffmpeg_source_priv_h) \ $(NULL) From c94dde647ce84502fe1eb7b5f0691d6db1e64443 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Sep 2011 11:34:05 +0200 Subject: [PATCH 0441/3781] vaapidecode: fix decoding of MPEG-2 PS files. --- NEWS | 2 +- gst/vaapidecode/gstvaapidecode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 3d86cfd98c..416f02e1a4 100644 --- a/NEWS +++ b/NEWS @@ -3,7 +3,7 @@ Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011 Intel Corporation Version 0.2.7 - DD.Jul.2011 -* Fix MPEG-2 TS decoding +* Fix MPEG-2 decoding from TS & PS streams * Fix build with newer versions of FFmpeg * Fix vaapiconvert direct-rendering modes diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 266309c7ec..4282a4232a 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -56,7 +56,7 @@ static const GstElementDetails gst_vaapidecode_details = "height = (int) [ 1, MAX ]; " static const char gst_vaapidecode_sink_caps_str[] = - GST_CAPS_CODEC("video/mpeg, mpegversion=2") + GST_CAPS_CODEC("video/mpeg, mpegversion=2, systemstream=(boolean)false") GST_CAPS_CODEC("video/mpeg, mpegversion=4") GST_CAPS_CODEC("video/x-divx") GST_CAPS_CODEC("video/x-xvid") From 6b1107cef728d86800ec47f62ecb6110d742ba9b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Sep 2011 13:07:18 +0200 Subject: [PATCH 0442/3781] vaapidecode: fix sink caps to not expose size information. This fixes this particular issue: GStreamer-WARNING **: pad vaapidecode0:sink returned caps which are not a real subset of its template caps --- gst/vaapidecode/gstvaapidecode.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 4282a4232a..13dad07ed1 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -50,10 +50,7 @@ static const GstElementDetails gst_vaapidecode_details = "Gwenole Beauchesne "); /* Default templates */ -#define GST_CAPS_CODEC(CODEC) \ - CODEC ", " \ - "width = (int) [ 1, MAX ], " \ - "height = (int) [ 1, MAX ]; " +#define GST_CAPS_CODEC(CODEC) CODEC "; " static const char gst_vaapidecode_sink_caps_str[] = GST_CAPS_CODEC("video/mpeg, mpegversion=2, systemstream=(boolean)false") From 08e8f3e671f86f2191609bc6485e2dd75a1eff8b Mon Sep 17 00:00:00 2001 From: warly Date: Tue, 18 Oct 2011 09:06:52 +0200 Subject: [PATCH 0443/3781] move plugins to LGPL v2.1+ --- COPYING | 339 ----------------------------- README | 8 +- debian.upstream/copyright | 28 +-- gst/vaapiconvert/gstvaapiconvert.c | 21 +- gst/vaapiconvert/gstvaapiconvert.h | 21 +- gst/vaapidecode/gstvaapidecode.c | 23 +- gst/vaapidecode/gstvaapidecode.h | 21 +- gst/vaapisink/gstvaapisink.c | 21 +- gst/vaapisink/gstvaapisink.h | 23 +- 9 files changed, 73 insertions(+), 432 deletions(-) delete mode 100644 COPYING diff --git a/COPYING b/COPYING deleted file mode 100644 index d511905c16..0000000000 --- a/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 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. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/README b/README index 95987fa753..a9243e395f 100644 --- a/README +++ b/README @@ -9,12 +9,8 @@ License ------- -gstreamer-vaapi helper libraries are available under the terms of the -GNU Lesser General Public License v2.1+. - -gstreamer-vaapi plugin elements are available under the terms of the -GNU General Public License v2+. - +gstreamer-vaapi helper libraries and plugin elements are available under the terms of the +GNU Lesser General Public License v2.1+ Overview -------- diff --git a/debian.upstream/copyright b/debian.upstream/copyright index a78f4e1fbd..4a568de59d 100644 --- a/debian.upstream/copyright +++ b/debian.upstream/copyright @@ -4,18 +4,15 @@ Gwenole Beauchesne Copyright: gstreamer-vaapi helper libraries - gst-libs/gst/vaapi/*.[ch]: LGPL (v2.1 or later) - - gstreamer-vaapi plugin elements - gst/vaapi{convert,decode,sink}: GPL (v2 or later) + and plugins elements: LGPL (v2.1 or later) License: Copyright (C) 2010-2011, Splitted-Desktop Systems. Copyright (C) 2011, Intel Corporation. - gstreamer-vaapi helper libraries are available under the terms of - the GNU Lesser General Public License v2.1+. + gstreamer-vaapi helper libraries and plugins elements are available under + the terms of the GNU Lesser General Public License v2.1+. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License @@ -35,22 +32,3 @@ License: On Debian GNU/Linux systems, the complete text of the GNU Lesser General Public License can be found in `/usr/share/common-licenses/LGPL-2.1'. - gstreamer-vaapi plugin elements are available under the terms of - the GNU General Public License v2+. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - -On Debian GNU/Linux systems, the complete text of the GNU General Public -License can be found in `/usr/share/common-licenses/GPL-2'. diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index a37d3941d6..1d2fef2b18 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst/vaapiconvert/gstvaapiconvert.h b/gst/vaapiconvert/gstvaapiconvert.h index 41f37ac3a4..7c29c6cd41 100644 --- a/gst/vaapiconvert/gstvaapiconvert.h +++ b/gst/vaapiconvert/gstvaapiconvert.h @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is 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 program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA +*/ #ifndef GST_VAAPICONVERT_H #define GST_VAAPICONVERT_H diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 13dad07ed1..41a404852e 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -4,20 +4,21 @@ * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011 Intel Corporation * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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:gstvaapidecode diff --git a/gst/vaapidecode/gstvaapidecode.h b/gst/vaapidecode/gstvaapidecode.h index 9c7759f53d..e2788a54de 100644 --- a/gst/vaapidecode/gstvaapidecode.h +++ b/gst/vaapidecode/gstvaapidecode.h @@ -4,19 +4,20 @@ * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011 Intel Corporation * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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_VAAPIDECODE_H diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 396c6cf46e..8bd8092f43 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 */ /** diff --git a/gst/vaapisink/gstvaapisink.h b/gst/vaapisink/gstvaapisink.h index a2543fe729..d30692d64d 100644 --- a/gst/vaapisink/gstvaapisink.h +++ b/gst/vaapisink/gstvaapisink.h @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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_VAAPISINK_H #define GST_VAAPISINK_H From 39be5a433b0290b78c274441cfb4b606fea0f55a Mon Sep 17 00:00:00 2001 From: warly Date: Tue, 18 Oct 2011 09:18:20 +0200 Subject: [PATCH 0444/3781] switch tests licence to LGPL v2.1+ --- tests/image.c | 23 ++++++++++++----------- tests/image.h | 23 ++++++++++++----------- tests/test-decode.c | 23 ++++++++++++----------- tests/test-decode.h | 21 +++++++++++---------- tests/test-display.c | 23 ++++++++++++----------- tests/test-h264.c | 23 ++++++++++++----------- tests/test-h264.h | 23 ++++++++++++----------- tests/test-mpeg2.c | 23 ++++++++++++----------- tests/test-mpeg2.h | 23 ++++++++++++----------- tests/test-surfaces.c | 21 +++++++++++---------- tests/test-textures.c | 23 ++++++++++++----------- tests/test-vc1.c | 23 ++++++++++++----------- tests/test-vc1.h | 23 ++++++++++++----------- tests/test-windows.c | 23 ++++++++++++----------- 14 files changed, 166 insertions(+), 152 deletions(-) diff --git a/tests/image.c b/tests/image.c index 809adc3bee..20f1c02017 100644 --- a/tests/image.c +++ b/tests/image.c @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 "image.h" diff --git a/tests/image.h b/tests/image.h index d748544656..a837d9754b 100644 --- a/tests/image.h +++ b/tests/image.h @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 IMAGE_H #define IMAGE_H diff --git a/tests/test-decode.c b/tests/test-decode.c index 7e63bef406..b913e08fc6 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 #include diff --git a/tests/test-decode.h b/tests/test-decode.h index 2ac862e65b..59a02116c4 100644 --- a/tests/test-decode.h +++ b/tests/test-decode.h @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 TEST_DECODE_H diff --git a/tests/test-display.c b/tests/test-display.c index 59e03b258f..b3b734bb43 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 #ifdef USE_X11 diff --git a/tests/test-h264.c b/tests/test-h264.c index bdb0274dbf..a0a361b64a 100644 --- a/tests/test-h264.c +++ b/tests/test-h264.c @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 "test-h264.h" diff --git a/tests/test-h264.h b/tests/test-h264.h index 7f24514451..9bc0a9aca2 100644 --- a/tests/test-h264.h +++ b/tests/test-h264.h @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 TEST_H264_H #define TEST_H264_H diff --git a/tests/test-mpeg2.c b/tests/test-mpeg2.c index 8ee4c34571..2f5d17c46c 100644 --- a/tests/test-mpeg2.c +++ b/tests/test-mpeg2.c @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 "test-mpeg2.h" diff --git a/tests/test-mpeg2.h b/tests/test-mpeg2.h index 54c43b6a80..b81adf093e 100644 --- a/tests/test-mpeg2.h +++ b/tests/test-mpeg2.h @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 TEST_MPEG2_H #define TEST_MPEG2_H diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index f3b5c3becb..9cd23e334d 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -3,19 +3,20 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 diff --git a/tests/test-textures.c b/tests/test-textures.c index 865dd62074..27497b1d7c 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 #include diff --git a/tests/test-vc1.c b/tests/test-vc1.c index 8b7c2dcb8e..4feb0ba046 100644 --- a/tests/test-vc1.c +++ b/tests/test-vc1.c @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 "test-vc1.h" diff --git a/tests/test-vc1.h b/tests/test-vc1.h index c57a5d6509..e659c486fa 100644 --- a/tests/test-vc1.h +++ b/tests/test-vc1.h @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 TEST_VC1_H #define TEST_VC1_H diff --git a/tests/test-windows.c b/tests/test-windows.c index 74ac01fdef..6862d1290b 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -3,20 +3,21 @@ * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This 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 program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ + * 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 #include From 89a244ede4539200116643d020b18d55a7e85083 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 19 Oct 2011 14:39:21 +0200 Subject: [PATCH 0445/3781] Splitted-Desktop systems relicensed plugins and tests to LGPL v2.1+. --- NEWS | 1 + README | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 416f02e1a4..2997fe77df 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011 Intel Corporation Version 0.2.7 - DD.Jul.2011 +* Relicense plugins and tests to LGPL v2.1 (SDS) * Fix MPEG-2 decoding from TS & PS streams * Fix build with newer versions of FFmpeg * Fix vaapiconvert direct-rendering modes diff --git a/README b/README index a9243e395f..129c4687ef 100644 --- a/README +++ b/README @@ -9,8 +9,8 @@ License ------- -gstreamer-vaapi helper libraries and plugin elements are available under the terms of the -GNU Lesser General Public License v2.1+ +gstreamer-vaapi helper libraries and plugin elements are available +under the terms of the GNU Lesser General Public License v2.1+ Overview -------- From fcaad720fb8892017e33e4ca0eb0175727473fc9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 19 Oct 2011 14:43:56 +0200 Subject: [PATCH 0446/3781] Update with my current e-mail address. --- configure.ac | 2 +- debian.upstream/changelog.in | 2 +- debian.upstream/control.in | 2 +- debian.upstream/copyright | 2 +- gst/vaapiconvert/gstvaapiconvert.c | 2 +- gst/vaapidecode/gstvaapidecode.c | 2 +- gst/vaapisink/gstvaapisink.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 76a684a91a..3e995b50bf 100644 --- a/configure.ac +++ b/configure.ac @@ -41,7 +41,7 @@ m4_define([gtkdoc_version], [gtkdoc_major_version.gtkdoc_minor_version]) AC_PREREQ([2.57]) AC_INIT([gst_vaapi], [gst_vaapi_version], - [gbeauchesne@splitted-desktop.com], + [gwenole.beauchesne@intel.com], [gstreamer-vaapi]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CANONICAL_TARGET diff --git a/debian.upstream/changelog.in b/debian.upstream/changelog.in index 4ecfad0e9c..92f9d3dea3 100644 --- a/debian.upstream/changelog.in +++ b/debian.upstream/changelog.in @@ -2,4 +2,4 @@ gstreamer@GST_MAJORMINOR@-vaapi (@PACKAGE_VERSION@-1) unstable; urgency=low * Autogenerated package, see NEWS file for ChangeLog. - -- Gwenole Beauchesne @TODAY@ + -- Gwenole Beauchesne @TODAY@ diff --git a/debian.upstream/control.in b/debian.upstream/control.in index fed84263a2..0e1c8e5f27 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -1,7 +1,7 @@ Source: gstreamer@GST_MAJORMINOR@-vaapi Section: libs Priority: optional -Maintainer: Gwenole Beauchesne +Maintainer: Gwenole Beauchesne Build-Depends: debhelper (>= 5), cdbs, libglib2.0-dev, diff --git a/debian.upstream/copyright b/debian.upstream/copyright index 4a568de59d..04c86b50c7 100644 --- a/debian.upstream/copyright +++ b/debian.upstream/copyright @@ -1,5 +1,5 @@ This package is maintained by: -Gwenole Beauchesne +Gwenole Beauchesne Copyright: diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index 1d2fef2b18..acd2667dc6 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -47,7 +47,7 @@ static const GstElementDetails gst_vaapiconvert_details = "VA-API colorspace converter", "Filter/Converter/Video", GST_PLUGIN_DESC, - "Gwenole Beauchesne "); + "Gwenole Beauchesne "); /* Default templates */ static const char gst_vaapiconvert_yuv_caps_str[] = diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 41a404852e..90eeb1cc94 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -48,7 +48,7 @@ static const GstElementDetails gst_vaapidecode_details = "VA-API decoder", "Codec/Decoder/Video", GST_PLUGIN_DESC, - "Gwenole Beauchesne "); + "Gwenole Beauchesne "); /* Default templates */ #define GST_CAPS_CODEC(CODEC) CODEC "; " diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 8bd8092f43..43794ab2db 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -56,7 +56,7 @@ static const GstElementDetails gst_vaapisink_details = "VA-API sink", "Sink/Video", GST_PLUGIN_DESC, - "Gwenole Beauchesne "); + "Gwenole Beauchesne "); /* Default template */ static GstStaticPadTemplate gst_vaapisink_sink_factory = From 51fd6f1f5058c3adfac43007188f433450f2e3a3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 19 Oct 2011 14:47:31 +0200 Subject: [PATCH 0447/3781] vaapiconvert: fix some warnings. --- gst/vaapiconvert/gstvaapiconvert.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index acd2667dc6..829dcdfbcb 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -474,8 +474,6 @@ static gboolean gst_vaapiconvert_ensure_surface_pool(GstVaapiConvert *convert, GstCaps *caps) { GstStructure * const structure = gst_caps_get_structure(caps, 0); - GstVaapiSurface *surface; - GstVaapiImage *image; gint width, height; gst_structure_get_int(structure, "width", &width); @@ -742,7 +740,6 @@ gst_vaapiconvert_prepare_output_buffer( { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); GstBuffer *buffer = NULL; - GstFlowReturn ret; if (convert->direct_rendering == 2) { if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) { From 3b9a165037b2cef868087d6cd963886072241d52 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 12 Oct 2011 14:00:50 +0200 Subject: [PATCH 0448/3781] decoder: fix use of invalid data at the end-of-stream. --- NEWS | 1 + gst-libs/gst/vaapi/gstvaapidecoder.c | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 2997fe77df..871f5097a0 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ Version 0.2.7 - DD.Jul.2011 * Fix MPEG-2 decoding from TS & PS streams * Fix build with newer versions of FFmpeg * Fix vaapiconvert direct-rendering modes +* Fix use of invalid data at the end-of-stream Version 0.2.6 - 14.Jun.2011 * Fix licensing terms (LGPL v2.1) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 2f0274b96a..c6282b7f77 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -117,12 +117,9 @@ decode_step(GstVaapiDecoder *decoder) status = GST_VAAPI_DECODER_GET_CLASS(decoder)->decode(decoder, buffer); GST_DEBUG("decode frame (status = %d)", status); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS && GST_BUFFER_IS_EOS(buffer)) + status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM; gst_buffer_unref(buffer); - if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - - if (GST_BUFFER_IS_EOS(buffer)) - return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; } while (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA); return status; } From 394c57454c717981011063ce14f74cb90a903189 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Mon, 24 Oct 2011 16:18:16 -0400 Subject: [PATCH 0449/3781] Update license in plugin definition Signed-off-by: Gwenole Beauchesne --- gst/vaapiconvert/gstvaapiconvert.c | 2 +- gst/vaapidecode/gstvaapidecode.c | 2 +- gst/vaapisink/gstvaapisink.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapiconvert/gstvaapiconvert.c index 829dcdfbcb..9b3b0b4e37 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapiconvert/gstvaapiconvert.c @@ -781,6 +781,6 @@ GST_PLUGIN_DEFINE( GST_PLUGIN_DESC, plugin_init, PACKAGE_VERSION, - "GPL", + "LGPL", PACKAGE, PACKAGE_BUGREPORT); diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 90eeb1cc94..a31877636e 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -674,6 +674,6 @@ GST_PLUGIN_DEFINE( GST_PLUGIN_DESC, plugin_init, PACKAGE_VERSION, - "GPL", + "LGPL", PACKAGE, PACKAGE_BUGREPORT); diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapisink/gstvaapisink.c index 43794ab2db..10f791b364 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapisink/gstvaapisink.c @@ -919,6 +919,6 @@ GST_PLUGIN_DEFINE( GST_PLUGIN_DESC, plugin_init, PACKAGE_VERSION, - "GPL", + "LGPL", PACKAGE, PACKAGE_BUGREPORT); From f5c1bc67f5f373186f359ecbc3492eb6c473ecac Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Mon, 12 Sep 2011 16:20:16 -0400 Subject: [PATCH 0450/3781] Adding ignore file Signed-off-by: Gwenole Beauchesne --- .gitignore | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..f94a58024e --- /dev/null +++ b/.gitignore @@ -0,0 +1,59 @@ +aclocal.m4 +autom4te.cache +config.h* +config.log +config.status +config.guess +config.sub +config.rpath +configure +libtool +stamp-h +stamp-h.in +stamp-h1 +gst-element-check-*.m4 +ltmain.sh +missing +mkinstalldirs +compile +install-sh +depcomp +autoregen.sh +ABOUT-NLS +_stdint.h + +/m4 + +.deps +.libs +*.lo +*.la +*.o +Makefile.in +Makefile +*~ +*.swp + +debian.upstream/changelog +debian.upstream/control +debian.upstream/gstreamer0.10-vaapi-doc.install +debian.upstream/gstreamer0.10-vaapi.install +debian.upstream/libgstvaapi-dev.install +debian.upstream/libgstvaapi-glx-0.install +debian.upstream/libgstvaapi-x11-0.install +debian.upstream/libgstvaapi0.install +docs/reference/libs/libs-docs.xml +docs/reference/plugins/plugins-docs.xml +gst-libs/gst/vaapi/gstvaapimarshal.c +gst-libs/gst/vaapi/gstvaapimarshal.h +gst-libs/gst/vaapi/stamp-marshal +gtk-doc.make +pkgconfig/gstreamer-vaapi-0.10.pc +pkgconfig/gstreamer-vaapi-glx-0.10.pc +pkgconfig/gstreamer-vaapi-x11-0.10.pc +tests/test-decode +tests/test-display +tests/test-surfaces +tests/test-textures +tests/test-windows + From fbc97f186fea083b6bcb021dbde4aa4a74f0c0f2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 7 Dec 2011 13:14:28 +0100 Subject: [PATCH 0451/3781] 0.2.7. --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 871f5097a0..5ff94446aa 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,8 @@ -gst-vaapi NEWS -- summary of changes. 2011-07-DD +gst-vaapi NEWS -- summary of changes. 2011-12-07 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011 Intel Corporation -Version 0.2.7 - DD.Jul.2011 +Version 0.2.7 - 07.Dec.2011 * Relicense plugins and tests to LGPL v2.1 (SDS) * Fix MPEG-2 decoding from TS & PS streams * Fix build with newer versions of FFmpeg From 78810665f8ff86289d6a0cd093f8b6656a6d475d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 7 Dec 2011 13:52:17 +0100 Subject: [PATCH 0452/3781] Fix build on Ubuntu 11.10 (Oneric). --- docs/reference/libs/Makefile.am | 2 ++ docs/reference/plugins/Makefile.am | 8 ++++++-- tests/Makefile.am | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index 745a932415..f8eafeb2c8 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -102,12 +102,14 @@ expand_content_files = \ INCLUDES = \ $(GLIB_CFLAGS) \ + $(GST_CFLAGS) \ -I$(top_srcdir) \ -I$(top_srcdir)/gst-libs \ -I$(top_srcdir)/gst-libs/gst/vaapi GTKDOC_LIBS = \ $(GLIB_LIBS) \ + $(GST_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la GTKDOC_LIBS += \ diff --git a/docs/reference/plugins/Makefile.am b/docs/reference/plugins/Makefile.am index 473ba988b8..457dfd13ab 100644 --- a/docs/reference/plugins/Makefile.am +++ b/docs/reference/plugins/Makefile.am @@ -83,7 +83,9 @@ INCLUDES = \ -I$(top_srcdir) \ -I$(top_srcdir)/gst-libs \ -I$(top_srcdir)/gst-libs/gst/vaapi \ - $(GLIB_CFLAGS) + $(GLIB_CFLAGS) \ + $(GST_CFLAGS) \ + $(NULL) GTKDOC_LIBS = \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la \ @@ -91,7 +93,9 @@ GTKDOC_LIBS = \ $(top_builddir)/gst/vaapidecode/libgstvaapidecode.la \ $(top_builddir)/gst/vaapiconvert/libgstvaapiconvert.la \ $(top_builddir)/gst/vaapisink/libgstvaapisink.la \ - $(GLIB_LIBS) + $(GLIB_LIBS) \ + $(GST_LIBS) \ + $(NULL) # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make diff --git a/tests/Makefile.am b/tests/Makefile.am index 40f28e3e17..ba6490ab38 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -20,14 +20,19 @@ TEST_MIX_CFLAGS += $(TEST_GLX_CFLAGS) endif TEST_LIBS = \ + $(GST_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-@GST_MAJORMINOR@.la TEST_X11_LIBS = \ $(X11_LIBS) \ + $(GST_LIBS) \ + $(LIBVA_X11_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la TEST_GLX_LIBS = \ $(GLX_LIBS) \ + $(GST_LIBS) \ + $(LIBVA_GLX_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-@GST_MAJORMINOR@.la TEST_MIX_LIBS = $(TEST_X11_LIBS) From cadc5cdd7661b2295a8c1e32c3edbc1ecd2ceab1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 7 Dec 2011 14:17:32 +0100 Subject: [PATCH 0453/3781] debian: build against upstream libva packages. --- configure.ac | 25 ++++++++----------------- debian.upstream/control.in | 2 +- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/configure.ac b/configure.ac index 3e995b50bf..7a81504fe3 100644 --- a/configure.ac +++ b/configure.ac @@ -21,17 +21,13 @@ m4_define([gst_plugins_base_micro_version], [16]) m4_define([gst_plugins_base_version], [gst_plugins_base_major_version.gst_plugins_base_minor_version.gst_plugins_base_micro_version]) +# VA-API minimum version number +m4_define([va_api_x11_version], [0.31.0]) +m4_define([va_api_glx_version], [0.32.0]) + # libva package version number -m4_define([libva_sds_version_0_29], [8]) -m4_define([libva_sds_package_version_0_29], [0.29-2+sds11]) -m4_define([libva_sds_version_0_30], [1]) -m4_define([libva_sds_package_version_0_30], [0.30-1+sds1]) -m4_define([libva_glx_sds_version_0_30], [5]) -m4_define([libva_glx_sds_package_version_0_30], [0.30.4-1+sds6]) -m4_define([libva_glx_sds_version_0_31], [1]) -m4_define([libva_glx_sds_package_version_0_31], [0.31.0-1+sds1]) -m4_define([libva_sds_version], [libva_glx_sds_version_0_31]) -m4_define([libva_sds_package_version], [libva_glx_sds_package_version_0_31]) +m4_define([libva_x11_package_version], [1.0.3]) +m4_define([libva_glx_package_version], [1.0.9]) # gtk-doc version number # XXX: introspection annotations require gtk-doc >= 1.12 @@ -54,8 +50,8 @@ AC_SUBST(TODAY) GST_VAAPI_MAJOR_VERSION=gst_vaapi_major_version AC_SUBST(GST_VAAPI_MAJOR_VERSION) -LIBVA_SDS_PACKAGE_VERSION=libva_sds_package_version -AC_SUBST(LIBVA_SDS_PACKAGE_VERSION) +LIBVA_PACKAGE_VERSION=libva_x11_package_version +AC_SUBST(LIBVA_PACKAGE_VERSION) dnl Versions for GStreamer and plugins-base GST_MAJORMINOR=gst_major_minor_version @@ -299,12 +295,7 @@ VA_VERSION=`$PKG_CONFIG --modversion libva` VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1` VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2` VA_MICRO_VERSION=`echo "$VA_VERSION" | cut -d'.' -f3` -VA_SDS_VERSION=`$PKG_CONFIG libva --variable sdsversion` - VA_VERSION_STR="$VA_VERSION" -if test -n "$VA_SDS_VERSION"; then - VA_VERSION_STR="$VA_VERSION_STR-sds$VA_SDS_VERSION" -fi pkgconfigdir=${libdir}/pkgconfig AC_SUBST(pkgconfigdir) diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 0e1c8e5f27..579d8496d1 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -7,7 +7,7 @@ Build-Depends: debhelper (>= 5), libglib2.0-dev, libgstreamer@GST_MAJORMINOR@-dev (>= @GST_VERSION_REQUIRED@), libgstreamer-plugins-base@GST_MAJORMINOR@-dev (>= @GST_PLUGINS_BASE_VERSION_REQUIRED@), - libva-dev (>= @LIBVA_SDS_PACKAGE_VERSION@) + libva-dev (>= @LIBVA_PACKAGE_VERSION@) Build-Depends-Indep: gtk-doc-tools (>= @GTKDOC_VERSION@) Standards-Version: 3.7.2 From 0b54e451c238cce231d4b20675313bed35afb336 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Jul 2011 14:31:30 +0200 Subject: [PATCH 0454/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 7a81504fe3..e6e9842849 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) -m4_define([gst_vaapi_minor_version], [2]) -m4_define([gst_vaapi_micro_version], [7]) +m4_define([gst_vaapi_minor_version], [3]) +m4_define([gst_vaapi_micro_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From 48b3d02143bffc038abbe6acd5c18230f998ee24 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 14 Sep 2011 15:12:41 -0400 Subject: [PATCH 0455/3781] Group all plugins into the same bundle Signed-off-by: Gwenole Beauchesne --- configure.ac | 4 +- docs/reference/plugins/Makefile.am | 4 +- gst/Makefile.am | 2 +- gst/{vaapisink => vaapi}/Makefile.am | 19 +++++-- gst/vaapi/gstvaapi.c | 57 +++++++++++++++++++ gst/{vaapiconvert => vaapi}/gstvaapiconvert.c | 25 +------- gst/{vaapiconvert => vaapi}/gstvaapiconvert.h | 0 gst/{vaapidecode => vaapi}/gstvaapidecode.c | 25 +------- gst/{vaapidecode => vaapi}/gstvaapidecode.h | 0 gst/{vaapisink => vaapi}/gstvaapisink.c | 25 +------- gst/{vaapisink => vaapi}/gstvaapisink.h | 0 gst/vaapiconvert/Makefile.am | 36 ------------ gst/vaapidecode/Makefile.am | 36 ------------ 13 files changed, 82 insertions(+), 151 deletions(-) rename gst/{vaapisink => vaapi}/Makefile.am (66%) create mode 100644 gst/vaapi/gstvaapi.c rename gst/{vaapiconvert => vaapi}/gstvaapiconvert.c (98%) rename gst/{vaapiconvert => vaapi}/gstvaapiconvert.h (100%) rename gst/{vaapidecode => vaapi}/gstvaapidecode.c (97%) rename gst/{vaapidecode => vaapi}/gstvaapidecode.h (100%) rename gst/{vaapisink => vaapi}/gstvaapisink.c (98%) rename gst/{vaapisink => vaapi}/gstvaapisink.h (100%) delete mode 100644 gst/vaapiconvert/Makefile.am delete mode 100644 gst/vaapidecode/Makefile.am diff --git a/configure.ac b/configure.ac index e6e9842849..0b9af9b012 100644 --- a/configure.ac +++ b/configure.ac @@ -333,9 +333,7 @@ pkgconfig/gstreamer-vaapi-glx.pc.in pkgconfig/gstreamer-vaapi-x11-$GST_MAJORMINOR.pc:\ pkgconfig/gstreamer-vaapi-x11.pc.in gst/Makefile - gst/vaapiconvert/Makefile - gst/vaapidecode/Makefile - gst/vaapisink/Makefile + gst/vaapi/Makefile tests/Makefile ]) diff --git a/docs/reference/plugins/Makefile.am b/docs/reference/plugins/Makefile.am index 457dfd13ab..0bb388cb96 100644 --- a/docs/reference/plugins/Makefile.am +++ b/docs/reference/plugins/Makefile.am @@ -90,9 +90,7 @@ INCLUDES = \ GTKDOC_LIBS = \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la \ - $(top_builddir)/gst/vaapidecode/libgstvaapidecode.la \ - $(top_builddir)/gst/vaapiconvert/libgstvaapiconvert.la \ - $(top_builddir)/gst/vaapisink/libgstvaapisink.la \ + $(top_builddir)/gst/vaapi/libgstvaapi.la \ $(GLIB_LIBS) \ $(GST_LIBS) \ $(NULL) diff --git a/gst/Makefile.am b/gst/Makefile.am index 195d0e9dd2..37d365da29 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = vaapiconvert vaapidecode vaapisink +SUBDIRS = vaapi # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/gst/vaapisink/Makefile.am b/gst/vaapi/Makefile.am similarity index 66% rename from gst/vaapisink/Makefile.am rename to gst/vaapi/Makefile.am index a11b1b59ec..19bd410ba2 100644 --- a/gst/vaapisink/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -1,4 +1,4 @@ -plugin_LTLIBRARIES = libgstvaapisink.la +plugin_LTLIBRARIES = libgstvaapi.la libgstvaapi_CFLAGS = \ $(LIBVA_CFLAGS) \ @@ -12,30 +12,37 @@ libgstvaapi_LIBS = \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la endif -libgstvaapisink_la_SOURCES = \ +libgstvaapi_la_SOURCES = \ + gstvaapi.c \ + gstvaapiconvert.c \ + gstvaapidecode.c \ gstvaapisink.c \ $(NULL) noinst_HEADERS = \ + gstvaapiconvert.h \ + gstvaapidecode.h \ gstvaapisink.h \ $(NULL) -libgstvaapisink_la_CFLAGS = \ +libgstvaapi_la_CFLAGS = \ $(libgstvaapi_CFLAGS) \ $(GST_CFLAGS) \ + $(GST_BASE_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ $(GST_INTERFACES_CFLAGS) \ $(GST_PLUGINS_BASE_CFLAGS) -libgstvaapisink_la_LIBADD = \ +libgstvaapi_la_LIBADD = \ $(libgstvaapi_LIBS) \ $(GST_LIBS) \ + $(GST_BASE_LIBS) \ $(GST_VIDEO_LIBS) \ $(GST_INTERFACES_LIBS) \ $(GST_PLUGINS_BASE_LIBS) -libgstvaapisink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstvaapisink_la_LIBTOOLFLAGS = --tag=disable-static +libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstvaapi_la_LIBTOOLFLAGS = --tag=disable-static # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c new file mode 100644 index 0000000000..1675a2a7c6 --- /dev/null +++ b/gst/vaapi/gstvaapi.c @@ -0,0 +1,57 @@ +/* + * gstvaapi.c - VA-API element registration + * + * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011 Collabora Ltd. + * Author: Nicolas Dufresne + * + * 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 + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "gstvaapiconvert.h" +#include "gstvaapidecode.h" +#include "gstvaapisink.h" + +static gboolean +plugin_init (GstPlugin *plugin) +{ + gst_element_register(plugin, "vaapiconvert", + GST_RANK_PRIMARY, + GST_TYPE_VAAPICONVERT); + gst_element_register(plugin, "vaapidecode", + GST_RANK_PRIMARY, + GST_TYPE_VAAPIDECODE); + gst_element_register(plugin, "vaapisink", + GST_RANK_PRIMARY, + GST_TYPE_VAAPISINK); + return TRUE; +} + +GST_PLUGIN_DEFINE( + GST_VERSION_MAJOR, GST_VERSION_MINOR, + "vaapi", + "VA-API based elements", + plugin_init, + PACKAGE_VERSION, + "LGPL", + PACKAGE, + PACKAGE_BUGREPORT); diff --git a/gst/vaapiconvert/gstvaapiconvert.c b/gst/vaapi/gstvaapiconvert.c similarity index 98% rename from gst/vaapiconvert/gstvaapiconvert.c rename to gst/vaapi/gstvaapiconvert.c index 9b3b0b4e37..769176ac31 100644 --- a/gst/vaapiconvert/gstvaapiconvert.c +++ b/gst/vaapi/gstvaapiconvert.c @@ -240,6 +240,9 @@ gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapiconvert, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + object_class->finalize = gst_vaapiconvert_finalize; object_class->set_property = gst_vaapiconvert_set_property; object_class->get_property = gst_vaapiconvert_get_property; @@ -762,25 +765,3 @@ gst_vaapiconvert_prepare_output_buffer( *poutbuf = buffer; return GST_FLOW_OK; } - -static gboolean -plugin_init(GstPlugin *plugin) -{ - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapiconvert, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - - return gst_element_register(plugin, - GST_PLUGIN_NAME, - GST_RANK_SECONDARY, - GST_TYPE_VAAPICONVERT); -} - -GST_PLUGIN_DEFINE( - GST_VERSION_MAJOR, GST_VERSION_MINOR, - GST_PLUGIN_NAME, - GST_PLUGIN_DESC, - plugin_init, - PACKAGE_VERSION, - "LGPL", - PACKAGE, - PACKAGE_BUGREPORT); diff --git a/gst/vaapiconvert/gstvaapiconvert.h b/gst/vaapi/gstvaapiconvert.h similarity index 100% rename from gst/vaapiconvert/gstvaapiconvert.h rename to gst/vaapi/gstvaapiconvert.h diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c similarity index 97% rename from gst/vaapidecode/gstvaapidecode.c rename to gst/vaapi/gstvaapidecode.c index a31877636e..19f0e91780 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -465,6 +465,9 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + object_class->finalize = gst_vaapidecode_finalize; object_class->set_property = gst_vaapidecode_set_property; object_class->get_property = gst_vaapidecode_get_property; @@ -655,25 +658,3 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) gst_pad_set_event_function(decode->srcpad, gst_vaapidecode_src_event); gst_element_add_pad(GST_ELEMENT(decode), decode->srcpad); } - -static gboolean -plugin_init(GstPlugin *plugin) -{ - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - - return gst_element_register(plugin, - GST_PLUGIN_NAME, - GST_RANK_PRIMARY, - GST_TYPE_VAAPIDECODE); -} - -GST_PLUGIN_DEFINE( - GST_VERSION_MAJOR, GST_VERSION_MINOR, - GST_PLUGIN_NAME, - GST_PLUGIN_DESC, - plugin_init, - PACKAGE_VERSION, - "LGPL", - PACKAGE, - PACKAGE_BUGREPORT); diff --git a/gst/vaapidecode/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h similarity index 100% rename from gst/vaapidecode/gstvaapidecode.h rename to gst/vaapi/gstvaapidecode.h diff --git a/gst/vaapisink/gstvaapisink.c b/gst/vaapi/gstvaapisink.c similarity index 98% rename from gst/vaapisink/gstvaapisink.c rename to gst/vaapi/gstvaapisink.c index 10f791b364..b59f738d2f 100644 --- a/gst/vaapisink/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -808,6 +808,9 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass); + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapisink, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + object_class->finalize = gst_vaapisink_finalize; object_class->set_property = gst_vaapisink_set_property; object_class->get_property = gst_vaapisink_get_property; @@ -900,25 +903,3 @@ gst_vaapisink_get_display(GstVaapiSink *sink) return NULL; return sink->display; } - -static gboolean -plugin_init(GstPlugin *plugin) -{ - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapisink, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - - return gst_element_register(plugin, - GST_PLUGIN_NAME, - GST_RANK_PRIMARY, - GST_TYPE_VAAPISINK); -} - -GST_PLUGIN_DEFINE( - GST_VERSION_MAJOR, GST_VERSION_MINOR, - GST_PLUGIN_NAME, - GST_PLUGIN_DESC, - plugin_init, - PACKAGE_VERSION, - "LGPL", - PACKAGE, - PACKAGE_BUGREPORT); diff --git a/gst/vaapisink/gstvaapisink.h b/gst/vaapi/gstvaapisink.h similarity index 100% rename from gst/vaapisink/gstvaapisink.h rename to gst/vaapi/gstvaapisink.h diff --git a/gst/vaapiconvert/Makefile.am b/gst/vaapiconvert/Makefile.am deleted file mode 100644 index 545e4cbed7..0000000000 --- a/gst/vaapiconvert/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -plugin_LTLIBRARIES = libgstvaapiconvert.la - -libgstvaapi_CFLAGS = \ - $(LIBVA_CFLAGS) \ - -I$(top_srcdir)/gst-libs - -libgstvaapi_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la - -libgstvaapiconvert_la_SOURCES = \ - gstvaapiconvert.c \ - $(NULL) - -noinst_HEADERS = \ - gstvaapiconvert.h \ - $(NULL) - -libgstvaapiconvert_la_CFLAGS = \ - $(libgstvaapi_CFLAGS) \ - $(GST_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) - -libgstvaapiconvert_la_LIBADD = \ - $(libgstvaapi_LIBS) \ - $(GST_LIBS) \ - $(GST_BASE_LIBS) \ - $(GST_VIDEO_LIBS) \ - $(GST_PLUGINS_BASE_LIBS) - -libgstvaapiconvert_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstvaapiconvert_la_LIBTOOLFLAGS = --tag=disable-static - -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in diff --git a/gst/vaapidecode/Makefile.am b/gst/vaapidecode/Makefile.am deleted file mode 100644 index 17bf0c988a..0000000000 --- a/gst/vaapidecode/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -plugin_LTLIBRARIES = libgstvaapidecode.la - -libgstvaapi_CFLAGS = \ - $(LIBVA_CFLAGS) \ - -I$(top_srcdir)/gst-libs - -libgstvaapi_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la - -libgstvaapidecode_la_SOURCES = \ - gstvaapidecode.c \ - $(NULL) - -noinst_HEADERS = \ - gstvaapidecode.h \ - $(NULL) - -libgstvaapidecode_la_CFLAGS = \ - $(libgstvaapi_CFLAGS) \ - $(GST_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) - -libgstvaapidecode_la_LIBADD = \ - $(libgstvaapi_LIBS) \ - $(GST_LIBS) \ - $(GST_BASE_LIBS) \ - $(GST_VIDEO_LIBS) \ - $(GST_PLUGINS_BASE_LIBS) - -libgstvaapidecode_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstvaapidecode_la_LIBTOOLFLAGS = --tag=disable-static - -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in From 01bcd440906e962849eea5e1ff5ff5d7d3f814af Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 7 Dec 2011 14:40:20 +0100 Subject: [PATCH 0456/3781] .gitignore: refine for generated docs. --- .gitignore | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index f94a58024e..be3a80e1a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,27 @@ +ABOUT-NLS +_stdint.h aclocal.m4 autom4te.cache +autoregen.sh +compile +config.guess config.h* config.log -config.status -config.guess -config.sub config.rpath +config.status +config.sub configure -libtool -stamp-h -stamp-h.in -stamp-h1 +depcomp gst-element-check-*.m4 +gstreamer-vaapi-*.tar.gz +install-sh +libtool ltmain.sh missing mkinstalldirs -compile -install-sh -depcomp -autoregen.sh -ABOUT-NLS -_stdint.h +stamp-h +stamp-h.in +stamp-h1 /m4 @@ -34,6 +35,7 @@ Makefile *~ *.swp +debian.build/ debian.upstream/changelog debian.upstream/control debian.upstream/gstreamer0.10-vaapi-doc.install @@ -42,8 +44,16 @@ debian.upstream/libgstvaapi-dev.install debian.upstream/libgstvaapi-glx-0.install debian.upstream/libgstvaapi-x11-0.install debian.upstream/libgstvaapi0.install +docs/reference/libs/html* docs/reference/libs/libs-docs.xml +docs/reference/libs/tmpl* +docs/reference/libs/xml* +docs/reference/libs/*.stamp +docs/reference/plugins/html* docs/reference/plugins/plugins-docs.xml +docs/reference/plugins/tmpl* +docs/reference/plugins/xml* +docs/reference/plugins/*.stamp gst-libs/gst/vaapi/gstvaapimarshal.c gst-libs/gst/vaapi/gstvaapimarshal.h gst-libs/gst/vaapi/stamp-marshal @@ -56,4 +66,3 @@ tests/test-display tests/test-surfaces tests/test-textures tests/test-windows - From feaa38e22b3fb9d990b3a578c67986331da2dccc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 7 Dec 2011 14:42:14 +0100 Subject: [PATCH 0457/3781] doc: mention Collabora copyrights. --- README | 1 + debian.upstream/copyright | 1 + 2 files changed, 2 insertions(+) diff --git a/README b/README index 129c4687ef..6d20e15095 100644 --- a/README +++ b/README @@ -4,6 +4,7 @@ Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011 Intel Corporation + Copyright (C) 2011 Collabora Ltd. License diff --git a/debian.upstream/copyright b/debian.upstream/copyright index 04c86b50c7..7e8e8c8f8c 100644 --- a/debian.upstream/copyright +++ b/debian.upstream/copyright @@ -10,6 +10,7 @@ License: Copyright (C) 2010-2011, Splitted-Desktop Systems. Copyright (C) 2011, Intel Corporation. + Copyright (C) 2011, Collabora Ltd. gstreamer-vaapi helper libraries and plugins elements are available under the terms of the GNU Lesser General Public License v2.1+. From 8a1dc4978f9b96f2361d6717cffe3304d7c9335d Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 13 Oct 2011 17:07:35 -0400 Subject: [PATCH 0458/3781] display: don't crash when config is empty. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidisplay.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index d03cfa758b..fe2bc30472 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -142,6 +142,9 @@ find_config( GstVaapiConfig *config; guint i; + if (!configs) + return FALSE; + for (i = 0; i < configs->len; i++) { config = &g_array_index(configs, GstVaapiConfig, i); if (config->profile == profile && config->entrypoint == entrypoint) @@ -158,6 +161,9 @@ get_profile_caps(GArray *configs) GstCaps *out_caps, *caps; guint i; + if (!configs) + return NULL; + out_caps = gst_caps_new_empty(); if (!out_caps) return NULL; From e5abbe0440784a38c856f7b311fdb3869763a409 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 13 Oct 2011 17:08:13 -0400 Subject: [PATCH 0459/3781] display: destroy display on creation failure. This allows element to detect that the display creation has actually failed. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidisplay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index fe2bc30472..ea0780d3ff 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -503,7 +503,8 @@ gst_vaapi_display_constructed(GObject *object) GObjectClass *parent_class; display->priv->create_display = display->priv->display == NULL; - gst_vaapi_display_create(display); + if (!gst_vaapi_display_create(display)) + gst_vaapi_display_destroy(display); parent_class = G_OBJECT_CLASS(gst_vaapi_display_parent_class); if (parent_class->constructed) From 6e7ac7c28e0fdbc5f87be73f25108955150742d0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 7 Dec 2011 17:31:09 +0100 Subject: [PATCH 0460/3781] configure: allow for pre-releases. --- configure.ac | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure.ac b/configure.ac index 0b9af9b012..808fa632f8 100644 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,12 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) m4_define([gst_vaapi_micro_version], [0]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) +m4_if(gst_vaapi_pre_version, [0], [], [ +m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) +]) # gst version number m4_define([gst_major_version], [0]) From 820c52f9533b57fc7ceac74b26bb1bdc4a0d4cc4 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 28 Jul 2011 11:14:49 +0300 Subject: [PATCH 0461/3781] vaapisink: replace the deprecated xoverlay API with the new one. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index b59f738d2f..759b4e3358 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -123,13 +123,13 @@ gst_vaapi_video_sink_iface_init(GstVaapiVideoSinkInterface *iface) /* GstXOverlay interface */ static gboolean -gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, XID xid); +gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id); static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); static void -gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) +gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window_id) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); @@ -138,7 +138,7 @@ gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) sink->use_glx = FALSE; sink->foreign_window = TRUE; - gst_vaapisink_ensure_window_xid(sink, xid); + gst_vaapisink_ensure_window_xid(sink, window_id); } static void @@ -157,8 +157,8 @@ gst_vaapisink_xoverlay_expose(GstXOverlay *overlay) static void gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface) { - iface->set_xwindow_id = gst_vaapisink_xoverlay_set_xid; - iface->expose = gst_vaapisink_xoverlay_expose; + iface->set_window_handle = gst_vaapisink_xoverlay_set_window_handle; + iface->expose = gst_vaapisink_xoverlay_expose; } static void @@ -354,11 +354,12 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) } static gboolean -gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, XID xid) +gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) { Window rootwin; unsigned int width, height, border_width, depth; int x, y; + XID xid = window_id; if (!gst_vaapisink_ensure_display(sink)) return FALSE; From f35a7f8fb0e3862028e5467791bfb17d47e96182 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 7 Dec 2011 18:40:35 +0100 Subject: [PATCH 0462/3781] Add new GStreamer version check utilities. --- .gitignore | 1 + configure.ac | 9 +++++ gst-libs/gst/Makefile.am | 6 ++- gst-libs/gst/gstutils_version.h.in | 61 ++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 gst-libs/gst/gstutils_version.h.in diff --git a/.gitignore b/.gitignore index be3a80e1a2..26ec42c0c9 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,7 @@ docs/reference/plugins/plugins-docs.xml docs/reference/plugins/tmpl* docs/reference/plugins/xml* docs/reference/plugins/*.stamp +gst-libs/gst/gstutils_version.h gst-libs/gst/vaapi/gstvaapimarshal.c gst-libs/gst/vaapi/gstvaapimarshal.h gst-libs/gst/vaapi/stamp-marshal diff --git a/configure.ac b/configure.ac index 808fa632f8..9baa50c56d 100644 --- a/configure.ac +++ b/configure.ac @@ -146,6 +146,14 @@ PKG_CHECK_MODULES([GST_PLUGINS_BASE], AC_SUBST(GST_PLUGINS_BASE_CFLAGS) AC_SUBST(GST_PLUGINS_BASE_LIBS) +V=`$PKG_CONFIG --modversion gstreamer-plugins-base-$GST_MAJORMINOR` +GST_PLUGINS_BASE_MAJOR_VERSION=`echo "$V" | cut -d'.' -f1` +GST_PLUGINS_BASE_MINOR_VERSION=`echo "$V" | cut -d'.' -f2` +GST_PLUGINS_BASE_MICRO_VERSION=`echo "$V" | cut -d'.' -f3` +AC_SUBST(GST_PLUGINS_BASE_MAJOR_VERSION) +AC_SUBST(GST_PLUGINS_BASE_MINOR_VERSION) +AC_SUBST(GST_PLUGINS_BASE_MICRO_VERSION) + dnl Check for GStreamer base PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED] @@ -328,6 +336,7 @@ debian.upstream/libgstvaapi-glx.install.in docs/reference/plugins/plugins-docs.xml gst-libs/Makefile gst-libs/gst/Makefile + gst-libs/gst/gstutils_version.h gst-libs/gst/vaapi/Makefile pkgconfig/Makefile pkgconfig/gstreamer-vaapi-$GST_MAJORMINOR.pc:\ diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 37d365da29..494170c42b 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -1,4 +1,8 @@ SUBDIRS = vaapi +gen_headers = gstutils_version.h +noinst_HEADERS = $(gen_headers) +EXTRA_DIST = gstutils_version.h.in + # Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +MAINTAINERCLEANFILES = Makefile.in $(gen_headers) diff --git a/gst-libs/gst/gstutils_version.h.in b/gst-libs/gst/gstutils_version.h.in new file mode 100644 index 0000000000..cc177b752f --- /dev/null +++ b/gst-libs/gst/gstutils_version.h.in @@ -0,0 +1,61 @@ +/* + * gstutils_version.h - GStreamer version utilities + * + * Copyright (C) 2011 Intel Corporation + * + * 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_UTILS_VERSION_H +#define GST_UTILS_VERSION_H + +/* gst-plugins-base version */ +#define GST_PLUGINS_BASE_MAJOR_VERSION @GST_PLUGINS_BASE_MAJOR_VERSION@ +#define GST_PLUGINS_BASE_MINOR_VERSION @GST_PLUGINS_BASE_MINOR_VERSION@ +#define GST_PLUGINS_BASE_MICRO_VERSION @GST_PLUGINS_BASE_MICRO_VERSION@ + +/** + * GST_UTILS_CHECK_VERSION: + * @major: major version, like 1 in 1.2.3 + * @minor: minor version, like 2 in 1.2.3 + * @micro: micro version, like 3 in 1.2.3 + * + * Evaluates to %TRUE if the version of gst-plugins-base is equal or + * greater than @major, @minor and @micro + */ +#define GST_UTILS_CHECK_VERSION(major,minor,micro, rmajor,rminor,rmicro) \ + ((rmajor) > (major) || \ + ((rmajor) == (major) && (rminor) > (minor)) || \ + ((rmajor) == (major) && (rminor) == (minor) && (rmicro) >= (micro))) + +/** + * GST_PLUGINS_BASE_CHECK_VERSION: + * @major: major version, like 1 in 1.2.3 + * @minor: minor version, like 2 in 1.2.3 + * @micro: micro version, like 3 in 1.2.3 + * + * Evaluates to %TRUE if the version of gst-plugins-base is greater + * than @major, @minor and @micro + */ +#ifndef GST_PLUGINS_BASE_CHECK_VERSION +#define GST_PLUGINS_BASE_CHECK_VERSION(major,minor,micro) \ + GST_UTILS_CHECK_VERSION(major,minor,micro, \ + GST_PLUGINS_BASE_MAJOR_VERSION, \ + GST_PLUGINS_BASE_MINOR_VERSION, \ + GST_PLUGINS_BASE_MICRO_VERSION) +#endif + +#endif /* GST_UTILS_VERSION_H */ From 513b9c700b984c5c7aad9aa5afda093d9078fa0c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 7 Dec 2011 19:04:09 +0100 Subject: [PATCH 0463/3781] vaapisink: allow compatibility with gst-plugins-base < 0.10.31. --- gst/vaapi/gstvaapisink.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 759b4e3358..b40cde333b 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -31,6 +31,7 @@ #include "config.h" #include #include +#include #include #include #include @@ -44,6 +45,9 @@ /* Supported interfaces */ #include +#define HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE \ + GST_PLUGINS_BASE_CHECK_VERSION(0,10,31) + #define GST_PLUGIN_NAME "vaapisink" #define GST_PLUGIN_DESC "A VA-API based videosink" @@ -128,8 +132,8 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id); static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); -static void -gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window_id) +static inline void +_gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, guintptr window_id) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); @@ -141,6 +145,20 @@ gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window_i gst_vaapisink_ensure_window_xid(sink, window_id); } +#if HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE +static void +gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window_id) +{ + _gst_vaapisink_xoverlay_set_xid(overlay, window_id); +} +#else +static void +gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) +{ + _gst_vaapisink_xoverlay_set_xid(overlay, xid); +} +#endif + static void gst_vaapisink_xoverlay_expose(GstXOverlay *overlay) { @@ -157,7 +175,11 @@ gst_vaapisink_xoverlay_expose(GstXOverlay *overlay) static void gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface) { +#if HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE iface->set_window_handle = gst_vaapisink_xoverlay_set_window_handle; +#else + iface->set_xwindow_id = gst_vaapisink_xoverlay_set_xid; +#endif iface->expose = gst_vaapisink_xoverlay_expose; } From 04d4c9f225337ea6b310f9ab8e68755b1f529561 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 7 Dec 2011 19:09:55 +0100 Subject: [PATCH 0464/3781] Add Intel copyright information. --- gst/vaapi/gstvaapiconvert.c | 1 + gst/vaapi/gstvaapisink.c | 1 + 2 files changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapiconvert.c b/gst/vaapi/gstvaapiconvert.c index 769176ac31..8c2896c0d9 100644 --- a/gst/vaapi/gstvaapiconvert.c +++ b/gst/vaapi/gstvaapiconvert.c @@ -2,6 +2,7 @@ * gstvaapiconvert.c - VA-API video converter * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index b40cde333b..5c93daae9b 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -2,6 +2,7 @@ * gstvaapisink.c - VA-API video sink * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License From f3d89f8bc00d19a6598a9a3cc16576fccb73c508 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 8 Dec 2011 13:30:51 +0100 Subject: [PATCH 0465/3781] vaapiplugin: link against VA/GLX when enabled. --- gst/vaapi/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 19bd410ba2..3e842dcb34 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -4,7 +4,7 @@ libgstvaapi_CFLAGS = \ $(LIBVA_CFLAGS) \ -I$(top_srcdir)/gst-libs -if USE_VAAPISINK_GLX +if USE_VAAPI_GLX libgstvaapi_LIBS = \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la else From 2df43791d4a22e0df9b73d27cadbf38dda37cd67 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 8 Dec 2011 14:57:36 +0100 Subject: [PATCH 0466/3781] vaapisink: use GST_ERROR to print error messages. --- gst/vaapi/gstvaapisink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 5c93daae9b..35c2af3cba 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -530,12 +530,12 @@ gst_vaapisink_buffer_alloc( /* ERRORS */ error_invalid_caps: { - GST_DEBUG("failed to validate input caps"); + GST_ERROR("failed to validate input caps"); return GST_FLOW_UNEXPECTED; } error_create_buffer: { - GST_DEBUG("failed to create video buffer"); + GST_ERROR("failed to create video buffer"); return GST_FLOW_UNEXPECTED; } } From 99c5d18f412a6f42d6bbf9b931675b8597a1539f Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 4 Nov 2011 16:50:15 -0400 Subject: [PATCH 0467/3781] Port to GstVideoContext interface. This new interface allows for upstream and downstream display sharing that works in both static and dynamic pipelines. Signed-off-by: Gwenole Beauchesne --- configure.ac | 15 ++ gst-libs/gst/vaapi/Makefile.am | 2 - gst-libs/gst/vaapi/gstvaapiutils_gst.c | 108 ------------ gst/vaapi/Makefile.am | 5 + gst/vaapi/gstvaapiconvert.c | 70 +++++++- gst/vaapi/gstvaapidecode.c | 86 ++++++---- gst/vaapi/gstvaapipluginutil.c | 162 ++++++++++++++++++ .../vaapi/gstvaapipluginutil.h | 17 +- gst/vaapi/gstvaapisink.c | 106 +++++------- gst/vaapi/gstvaapisink.h | 1 - 10 files changed, 348 insertions(+), 224 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapiutils_gst.c create mode 100644 gst/vaapi/gstvaapipluginutil.c rename gst-libs/gst/vaapi/gstvaapiutils_gst.h => gst/vaapi/gstvaapipluginutil.h (62%) diff --git a/configure.ac b/configure.ac index 9baa50c56d..4334d75395 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,13 @@ m4_define([gst_plugins_base_version], m4_define([va_api_x11_version], [0.31.0]) m4_define([va_api_glx_version], [0.32.0]) +# gst plugins-bad version number +m4_define([gst_plugins_bad_major_version], [0]) +m4_define([gst_plugins_bad_minor_version], [10]) +m4_define([gst_plugins_bad_micro_version], [22]) +m4_define([gst_plugins_bad_version], + [gst_plugins_bad_major_version.gst_plugins_bad_minor_version.gst_plugins_bad_micro_version]) + # libva package version number m4_define([libva_x11_package_version], [1.0.3]) m4_define([libva_glx_package_version], [1.0.9]) @@ -61,6 +68,7 @@ dnl Versions for GStreamer and plugins-base GST_MAJORMINOR=gst_major_minor_version GST_VERSION_REQUIRED=gst_version GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version +GST_PLUGINS_BAD_VERSION_REQUIRED=gst_plugins_bad_version AC_SUBST(GST_MAJORMINOR) AC_SUBST(GST_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) @@ -168,6 +176,13 @@ PKG_CHECK_MODULES([GST_VIDEO], AC_SUBST(GST_VIDEO_CFLAGS) AC_SUBST(GST_VIDEO_LIBS) +dnl Check for GStreamer basevideo +PKG_CHECK_MODULES([GST_BASEVIDEO], + [gstreamer-basevideo-$GST_MAJORMINOR >= $GST_PLUGINS_BAD_VERSION_REQUIRED] +) +AC_SUBST(GST_BASEVIDEO_CFLAGS) +AC_SUBST(GST_BASEVIDEO_LIBS) + dnl Check for GStreamer interfaces PKG_CHECK_MODULES([GST_INTERFACES], [gstreamer-interfaces-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED] diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 1feca33835..17ead8b308 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -37,7 +37,6 @@ libgstvaapi_source_c = \ gstvaapisurfacepool.c \ gstvaapisurfaceproxy.c \ gstvaapiutils.c \ - gstvaapiutils_gst.c \ gstvaapivalue.c \ gstvaapivideobuffer.c \ gstvaapivideopool.c \ @@ -77,7 +76,6 @@ libgstvaapi_source_priv_h = \ gstvaapidisplay_priv.h \ gstvaapiobject_priv.h \ gstvaapiutils.h \ - gstvaapiutils_gst.h \ $(libgst_vaapi_ffmpeg_source_priv_h) \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_gst.c b/gst-libs/gst/vaapi/gstvaapiutils_gst.c deleted file mode 100644 index 7a0e7dae44..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiutils_gst.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * gstvaapiutils_gst.c - GST utilties - * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems - * - * 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 "config.h" -#include "gstvaapiutils_gst.h" -#include "gstvaapivideosink.h" -#include "gstvaapivideobuffer.h" - -#define DEBUG 1 -#include "gstvaapidebug.h" - -static GstVaapiDisplay * -lookup_through_vaapisink_iface(GstElement *element) -{ - GstVaapiDisplay *display; - GstVaapiVideoSink *sink; - - GST_DEBUG("looking for a downstream vaapisink"); - - /* Look for a downstream vaapisink */ - sink = gst_vaapi_video_sink_lookup(element); - if (!sink) - return NULL; - - display = gst_vaapi_video_sink_get_display(sink); - GST_DEBUG(" found display %p", display); - return display; -} - -static GstVaapiDisplay * -lookup_through_peer_buffer(GstElement *element) -{ - GstVaapiDisplay *display; - GstPad *pad; - GstBuffer *buffer; - GstFlowReturn ret; - - GST_DEBUG("looking for a GstVaapiVideoBuffer from peer"); - - /* Look for a GstVaapiVideoBuffer from peer */ - pad = gst_element_get_static_pad(element, "src"); - if (!pad) - return NULL; - - buffer = NULL; - ret = gst_pad_alloc_buffer(pad, 0, 0, GST_PAD_CAPS(pad), &buffer); - g_object_unref(pad); - if (ret != GST_FLOW_OK || !buffer) - return NULL; - - display = GST_VAAPI_IS_VIDEO_BUFFER(buffer) ? - gst_vaapi_video_buffer_get_display(GST_VAAPI_VIDEO_BUFFER(buffer)) : - NULL; - gst_buffer_unref(buffer); - - GST_DEBUG(" found display %p", display); - return display; -} - -/** - * gst_vaapi_display_lookup_downstream: - * @element: a #GstElement - * - * Finds a suitable #GstVaapiDisplay downstream from @element. - * - * 1. Check whether a downstream element implements the - * #GstVaapiVideoSinkInterface interface. - * - * 2. Check whether the @element peer implements a custom - * buffer_alloc() function that allocates #GstVaapiVideoBuffer - * buffers. - * - * Return value: a downstream allocated #GstVaapiDisplay object, or - * %NULL if none was found - */ -GstVaapiDisplay * -gst_vaapi_display_lookup_downstream(GstElement *element) -{ - GstVaapiDisplay *display; - - display = lookup_through_vaapisink_iface(element); - if (display) - return display; - - display = lookup_through_peer_buffer(element); - if (display) - return display; - - return NULL; -} diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 3e842dcb34..0b18d08f11 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -2,6 +2,7 @@ plugin_LTLIBRARIES = libgstvaapi.la libgstvaapi_CFLAGS = \ $(LIBVA_CFLAGS) \ + -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs if USE_VAAPI_GLX @@ -16,12 +17,14 @@ libgstvaapi_la_SOURCES = \ gstvaapi.c \ gstvaapiconvert.c \ gstvaapidecode.c \ + gstvaapipluginutil.c \ gstvaapisink.c \ $(NULL) noinst_HEADERS = \ gstvaapiconvert.h \ gstvaapidecode.h \ + gstvaapipluginutil.h \ gstvaapisink.h \ $(NULL) @@ -31,6 +34,7 @@ libgstvaapi_la_CFLAGS = \ $(GST_BASE_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ $(GST_INTERFACES_CFLAGS) \ + $(GST_BASEVIDEO_CFLAGS) \ $(GST_PLUGINS_BASE_CFLAGS) libgstvaapi_la_LIBADD = \ @@ -39,6 +43,7 @@ libgstvaapi_la_LIBADD = \ $(GST_BASE_LIBS) \ $(GST_VIDEO_LIBS) \ $(GST_INTERFACES_LIBS) \ + $(GST_BASEVIDEO_LIBS) \ $(GST_PLUGINS_BASE_LIBS) libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/gst/vaapi/gstvaapiconvert.c b/gst/vaapi/gstvaapiconvert.c index 8c2896c0d9..f8719403bc 100644 --- a/gst/vaapi/gstvaapiconvert.c +++ b/gst/vaapi/gstvaapiconvert.c @@ -29,11 +29,14 @@ */ #include "config.h" + #include #include +#include #include #include -#include + +#include "gstvaapipluginutil.h" #include "gstvaapiconvert.h" #define GST_PLUGIN_NAME "vaapiconvert" @@ -73,11 +76,15 @@ static GstStaticPadTemplate gst_vaapiconvert_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapiconvert_vaapi_caps_str)); -GST_BOILERPLATE( +#define GstVideoContextClass GstVideoContextInterface +GST_BOILERPLATE_WITH_INTERFACE( GstVaapiConvert, gst_vaapiconvert, GstBaseTransform, - GST_TYPE_BASE_TRANSFORM); + GST_TYPE_BASE_TRANSFORM, + GstVideoContext, + GST_TYPE_VIDEO_CONTEXT, + gst_video_context); /* * Direct rendering levels (direct-rendering) @@ -145,6 +152,34 @@ gst_vaapiconvert_prepare_output_buffer( GstBuffer **poutbuf ); +static gboolean +gst_vaapiconvert_query( + GstPad *pad, + GstQuery *query +); + +/* GstVideoContext interface */ + +static void +gst_vaapiconvert_set_video_context(GstVideoContext *context, const gchar *type, + const GValue *value) +{ + GstVaapiConvert *convert = GST_VAAPICONVERT (context); + gst_vaapi_set_display (type, value, &convert->display); +} + +static gboolean +gst_video_context_supported (GstVaapiConvert *convert, GType iface_type) +{ + return (iface_type == GST_TYPE_VIDEO_CONTEXT); +} + +static void +gst_video_context_interface_init(GstVideoContextInterface *iface) +{ + iface->set_context = gst_vaapiconvert_set_video_context; +} + static void gst_vaapiconvert_destroy(GstVaapiConvert *convert) { @@ -289,7 +324,7 @@ gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) static void gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) { - GstPad *sinkpad; + GstPad *sinkpad, *srcpad; convert->display = NULL; convert->images = NULL; @@ -310,20 +345,20 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) gst_vaapiconvert_sinkpad_buffer_alloc ); g_object_unref(sinkpad); + + /* Override query on src pad */ + srcpad = gst_element_get_static_pad(GST_ELEMENT(convert), "src"); + gst_pad_set_query_function(srcpad, gst_vaapiconvert_query); } static gboolean gst_vaapiconvert_start(GstBaseTransform *trans) { GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); - GstVaapiDisplay *display; - /* Look for a downstream display */ - display = gst_vaapi_display_lookup_downstream(GST_ELEMENT(trans)); - if (!display) + if (!gst_vaapi_ensure_display(convert, &convert->display)) return FALSE; - convert->display = g_object_ref(display); return TRUE; } @@ -766,3 +801,20 @@ gst_vaapiconvert_prepare_output_buffer( *poutbuf = buffer; return GST_FLOW_OK; } + +static gboolean +gst_vaapiconvert_query(GstPad *pad, GstQuery *query) +{ + GstVaapiConvert *convert = GST_VAAPICONVERT (gst_pad_get_parent_element (pad)); + gboolean res; + + GST_DEBUG ("sharing display %p", convert->display); + + if (gst_vaapi_reply_to_query (query, convert->display)) + res = TRUE; + else + res = gst_pad_query_default (pad, query); + + g_object_unref (convert); + return res; +} diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 19f0e91780..716c3525a4 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -29,12 +29,15 @@ */ #include "config.h" -#include "gstvaapidecode.h" -#include + +#include #include #include #include -#include +#include + +#include "gstvaapidecode.h" +#include "gstvaapipluginutil.h" #define GST_PLUGIN_NAME "vaapidecode" #define GST_PLUGIN_DESC "A VA-API based video decoder" @@ -80,11 +83,15 @@ static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapidecode_src_caps_str)); -GST_BOILERPLATE( +#define GstVideoContextClass GstVideoContextInterface +GST_BOILERPLATE_WITH_INTERFACE( GstVaapiDecode, gst_vaapidecode, GstElement, - GST_TYPE_ELEMENT); + GST_TYPE_ELEMENT, + GstVideoContext, + GST_TYPE_VIDEO_CONTEXT, + gst_video_context); enum { PROP_0, @@ -257,24 +264,10 @@ error_commit_buffer: } } -static inline gboolean -gst_vaapidecode_ensure_display(GstVaapiDecode *decode) -{ - GstVaapiDisplay *display; - - if (!decode->display) { - display = gst_vaapi_display_lookup_downstream(GST_ELEMENT(decode)); - if (!display) - return FALSE; - decode->display = g_object_ref(display); - } - return TRUE; -} - static gboolean gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) { - if (!gst_vaapidecode_ensure_display(decode)) + if (!gst_vaapi_ensure_display(decode, &decode->display)) return FALSE; decode->decoder_mutex = g_mutex_new(); @@ -339,6 +332,28 @@ gst_vaapidecode_reset(GstVaapiDecode *decode, GstCaps *caps) return gst_vaapidecode_create(decode, caps); } +/* GstVideoContext interface */ + +static void +gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type, + const GValue *value) +{ + GstVaapiDecode *decode = GST_VAAPIDECODE (context); + gst_vaapi_set_display (type, value, &decode->display); +} + +static gboolean +gst_video_context_supported (GstVaapiDecode *decode, GType iface_type) +{ + return (iface_type == GST_TYPE_VIDEO_CONTEXT); +} + +static void +gst_video_context_interface_init(GstVideoContextInterface *iface) +{ + iface->set_context = gst_vaapidecode_set_video_context; +} + static void gst_vaapidecode_base_init(gpointer klass) { @@ -494,15 +509,10 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) if (decode->allowed_caps) return TRUE; - if (gst_vaapidecode_ensure_display(decode)) - display = g_object_ref(decode->display); - else { - display = gst_vaapi_display_x11_new(NULL); - if (!display) - goto error_no_display; - } + if (!gst_vaapi_ensure_display(decode, &decode->display)) + goto error_no_display; - decode_caps = gst_vaapi_display_get_decode_caps(display); + decode_caps = gst_vaapi_display_get_decode_caps(decode->display); if (!decode_caps) goto error_no_decode_caps; n_decode_caps = gst_caps_get_size(decode_caps); @@ -530,7 +540,6 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) } gst_caps_unref(decode_caps); - g_object_unref(display); return TRUE; /* ERRORS */ @@ -542,14 +551,12 @@ error_no_display: error_no_decode_caps: { GST_DEBUG("failed to retrieve VA decode caps"); - g_object_unref(display); return FALSE; } error_no_memory: { GST_DEBUG("failed to allocate allowed-caps set"); gst_caps_unref(decode_caps); - g_object_unref(display); return FALSE; } } @@ -621,6 +628,22 @@ gst_vaapidecode_src_event(GstPad *pad, GstEvent *event) return gst_pad_push_event(decode->sinkpad, event); } +static gboolean +gst_vaapidecode_query (GstPad *pad, GstQuery *query) { + GstVaapiDecode *decode = GST_VAAPIDECODE (gst_pad_get_parent_element (pad)); + gboolean res; + + GST_DEBUG ("sharing display %p", decode->display); + + if (gst_vaapi_reply_to_query (query, decode->display)) + res = TRUE; + else + res = gst_pad_query_default (pad, query); + + g_object_unref (decode); + return res; +} + static void gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) { @@ -656,5 +679,6 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) gst_pad_use_fixed_caps(decode->srcpad); gst_pad_set_event_function(decode->srcpad, gst_vaapidecode_src_event); + gst_pad_set_query_function(decode->srcpad, gst_vaapidecode_query); gst_element_add_pad(GST_ELEMENT(decode), decode->srcpad); } diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c new file mode 100644 index 0000000000..a95fb8c66b --- /dev/null +++ b/gst/vaapi/gstvaapipluginutil.c @@ -0,0 +1,162 @@ +/* + * gstvaapipluginutil.h - VA-API plugin helpers + * + * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011 Collabora + * Author: Nicolas Dufresne + * + * 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 + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gstvaapipluginutil.h" + +#include + +#ifdef USE_VAAPI_GLX +#include +#else +#include +#endif + +/* Preferred first */ +static const char *display_types[] = { + "gst-vaapi-display", + "vaapi-display", + "x11-display", + "x11-display-name", + NULL +}; + +gboolean +gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display) +{ + GstVideoContext *context; + + g_return_val_if_fail (GST_IS_VIDEO_CONTEXT (element), FALSE); + g_return_val_if_fail (display != NULL, FALSE); + + /* Already exist ? */ + if (*display) + return TRUE; + + context = GST_VIDEO_CONTEXT (element); + gst_video_context_prepare (context, display_types); + + /* If no neighboor, or application not interested, use system default */ + if (!*display) +#if USE_VAAPI_GLX + *display = gst_vaapi_display_glx_new (""); +#else + *display = gst_vaapi_display_x11_new (""); +#endif + + /* FIXME allocator should return NULL in case of failure */ + if (*display && !gst_vaapi_display_get_display(*display)) { + g_object_unref (*display); + *display = NULL; + } + + return (*display != NULL); +} + +void +gst_vaapi_set_display (const gchar *type, + const GValue *value, + GstVaapiDisplay **display) +{ + GstVaapiDisplay *dpy = NULL; + + if (!strcmp (type, "x11-display-name")) { + g_return_if_fail (G_VALUE_HOLDS_STRING (value)); +#if USE_VAAPI_GLX + dpy = gst_vaapi_display_glx_new (g_value_get_string (value)); +#else + dpy = gst_vaapi_display_x11_new (g_value_get_string (value)); +#endif + } else if (!strcmp (type, "x11-display")) { + g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); +#if USE_VAAPI_GLX + dpy = gst_vaapi_display_glx_new_with_display (g_value_get_pointer (value)); +#else + dpy = gst_vaapi_display_x11_new_with_display (g_value_get_pointer (value)); +#endif + } else if (!strcmp (type, "vaapi-display")) { + g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); + dpy = gst_vaapi_display_new_with_display (g_value_get_pointer (value)); + } else if (!strcmp (type, "gst-vaapi-display")) { + g_return_if_fail (G_VALUE_HOLDS_OBJECT (value)); + dpy = g_value_dup_object (value); + } + + if (dpy) { + if (*display) + g_object_unref (*display); + *display = dpy; + } +} + +gboolean +gst_vaapi_reply_to_query (GstQuery *query, GstVaapiDisplay *display) +{ + const gchar **types; + const gchar *type; + gint i; + gboolean res = FALSE; + + if (!display) + return FALSE; + + types = gst_video_context_query_get_supported_types (query); + + if (!types) + return FALSE; + + for (i = 0; types[i]; i++) { + type = types[i]; + + if (!strcmp (type, "gst-vaapi-display")) { + gst_video_context_query_set_object (query, type, G_OBJECT (display)); + + } else if (!strcmp (type, "vaapi-display")) { + VADisplay vadpy = gst_vaapi_display_get_display(display); + gst_video_context_query_set_pointer (query, type, vadpy); + + } else if (!strcmp (type, "x11-display") && + GST_VAAPI_IS_DISPLAY_X11(display)) { + GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11 (display); + Display *x11dpy = gst_vaapi_display_x11_get_display (xvadpy); + gst_video_context_query_set_pointer (query, type, x11dpy); + + } else if (!strcmp (type, "x11-display-name") && + GST_VAAPI_IS_DISPLAY_X11(display)) { + GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11 (display); + Display *x11dpy = gst_vaapi_display_x11_get_display (xvadpy); + gst_video_context_query_set_string (query, type, DisplayString(x11dpy)); + + } else { + continue; + } + + res = TRUE; + break; + } + + return res; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_gst.h b/gst/vaapi/gstvaapipluginutil.h similarity index 62% rename from gst-libs/gst/vaapi/gstvaapiutils_gst.h rename to gst/vaapi/gstvaapipluginutil.h index 350f20a3e5..3d31938a5a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_gst.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -1,7 +1,9 @@ /* - * gstvaapiutils_gst.h - GST utilties + * gstvaapipluginutil.h - VA-API plugins private helper * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011 Collabora + * Author: Nicolas Dufresne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -19,13 +21,10 @@ * Boston, MA 02110-1301 USA */ -#ifndef GST_VAAPI_UTILS_GST_H -#define GST_VAAPI_UTILS_GST_H - #include +#include #include -GstVaapiDisplay * -gst_vaapi_display_lookup_downstream(GstElement *element); - -#endif /* GST_VAAPI_UTILS_GST_H */ +gboolean gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display); +void gst_vaapi_set_display (const gchar *type, const GValue *value, GstVaapiDisplay **display); +gboolean gst_vaapi_reply_to_query (GstQuery *query, GstVaapiDisplay *display); diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 35c2af3cba..b2477c3e87 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -31,8 +31,9 @@ #include "config.h" #include -#include #include +#include +#include #include #include #include @@ -41,11 +42,13 @@ #include #include #endif -#include "gstvaapisink.h" /* Supported interfaces */ #include +#include "gstvaapisink.h" +#include "gstvaapipluginutil.h" + #define HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE \ GST_PLUGINS_BASE_CHECK_VERSION(0,10,31) @@ -84,7 +87,6 @@ enum { PROP_0, PROP_USE_GLX, - PROP_DISPLAY, PROP_FULLSCREEN, PROP_SYNCHRONOUS, PROP_USE_REFLECTION @@ -98,7 +100,7 @@ gst_vaapisink_implements_interface_supported( GType type ) { - return (type == GST_VAAPI_TYPE_VIDEO_SINK || + return (type == GST_TYPE_VIDEO_CONTEXT || type == GST_TYPE_X_OVERLAY); } @@ -110,19 +112,18 @@ gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface) /* GstVaapiVideoSink interface */ -static GstVaapiDisplay * -gst_vaapisink_get_display(GstVaapiSink *sink); - -static GstVaapiDisplay * -gst_vaapi_video_sink_do_get_display(GstVaapiVideoSink *sink) +static void +gst_vaapisink_set_video_context(GstVideoContext *context, const gchar *type, + const GValue *value) { - return gst_vaapisink_get_display(GST_VAAPISINK(sink)); + GstVaapiSink *sink = GST_VAAPISINK (context); + gst_vaapi_set_display (type, value, &sink->display); } static void -gst_vaapi_video_sink_iface_init(GstVaapiVideoSinkInterface *iface) +gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface) { - iface->get_display = gst_vaapi_video_sink_do_get_display; + iface->set_context = gst_vaapisink_set_video_context; } /* GstXOverlay interface */ @@ -191,8 +192,8 @@ gst_vaapisink_iface_init(GType type) G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapisink_implements_iface_init); - G_IMPLEMENT_INTERFACE(GST_VAAPI_TYPE_VIDEO_SINK, - gst_vaapi_video_sink_iface_init); + G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, + gst_vaapisink_video_context_iface_init); G_IMPLEMENT_INTERFACE(GST_TYPE_X_OVERLAY, gst_vaapisink_xoverlay_iface_init); } @@ -204,11 +205,6 @@ gst_vaapisink_destroy(GstVaapiSink *sink) g_object_unref(sink->display); sink->display = NULL; } - - if (sink->display_name) { - g_free(sink->display_name); - sink->display_name = NULL; - } } /* Checks whether a ConfigureNotify event is in the queue */ @@ -262,23 +258,6 @@ configure_notify_event_pending( return args.match; } -static inline gboolean -gst_vaapisink_ensure_display(GstVaapiSink *sink) -{ - if (!sink->display) { -#if USE_VAAPISINK_GLX - if (sink->use_glx) - sink->display = gst_vaapi_display_glx_new(sink->display_name); - else -#endif - sink->display = gst_vaapi_display_x11_new(sink->display_name); - if (!sink->display || !gst_vaapi_display_get_display(sink->display)) - return FALSE; - g_object_set(sink, "synchronous", sink->synchronous, NULL); - } - return sink->display != NULL; -} - static gboolean gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) { @@ -384,7 +363,7 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) int x, y; XID xid = window_id; - if (!gst_vaapisink_ensure_display(sink)) + if (!gst_vaapi_ensure_display(sink, &sink->display)) return FALSE; gst_vaapi_display_lock(sink->display); @@ -427,8 +406,6 @@ gst_vaapisink_start(GstBaseSink *base_sink) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - if (!gst_vaapisink_ensure_display(sink)) - return FALSE; return TRUE; } @@ -471,6 +448,9 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) sink->video_par_d = video_par_d; GST_DEBUG("video pixel-aspect-ratio %d/%d", video_par_n, video_par_d); + if (!gst_vaapi_ensure_display(sink, &sink->display)) + return FALSE; + gst_vaapi_display_get_size(sink->display, &display_width, &display_height); if (!gst_vaapisink_ensure_render_rect(sink, display_width, display_height)) return FALSE; @@ -515,6 +495,9 @@ gst_vaapisink_buffer_alloc( GstStructure *structure; GstBuffer *buffer; + if (!gst_vaapi_ensure_display(sink, &sink->display)) + goto error_ensure_display; + structure = gst_caps_get_structure(caps, 0); if (!gst_structure_has_name(structure, "video/x-vaapi-surface")) goto error_invalid_caps; @@ -528,6 +511,11 @@ gst_vaapisink_buffer_alloc( return GST_FLOW_OK; /* ERRORS */ +error_ensure_display: + { + GST_ERROR("failed to ensure display"); + return GST_FLOW_UNEXPECTED; + } error_invalid_caps: { GST_ERROR("failed to validate input caps"); @@ -719,6 +707,12 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) guint flags; gboolean success; + if (sink->display != gst_vaapi_video_buffer_get_display (vbuffer)) { + if (sink->display) + g_object_unref (sink->display); + sink->display = g_object_ref (gst_vaapi_video_buffer_get_display (vbuffer)); + } + if (!sink->window) return GST_FLOW_UNEXPECTED; @@ -740,6 +734,14 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) return success ? GST_FLOW_OK : GST_FLOW_UNEXPECTED; } +static gboolean +gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query) +{ + GstVaapiSink *sink = GST_VAAPISINK(base_sink); + GST_DEBUG ("sharing display %p", sink->display); + return gst_vaapi_reply_to_query (query, sink->display); +} + static void gst_vaapisink_finalize(GObject *object) { @@ -762,10 +764,6 @@ gst_vaapisink_set_property( case PROP_USE_GLX: sink->use_glx = g_value_get_boolean(value); break; - case PROP_DISPLAY: - g_free(sink->display_name); - sink->display_name = g_strdup(g_value_get_string(value)); - break; case PROP_FULLSCREEN: sink->fullscreen = g_value_get_boolean(value); break; @@ -795,9 +793,6 @@ gst_vaapisink_get_property( case PROP_USE_GLX: g_value_set_boolean(value, sink->use_glx); break; - case PROP_DISPLAY: - g_value_set_string(value, sink->display_name); - break; case PROP_FULLSCREEN: g_value_set_boolean(value, sink->fullscreen); break; @@ -845,6 +840,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; basesink_class->preroll = gst_vaapisink_show_frame; basesink_class->render = gst_vaapisink_show_frame; + basesink_class->query = gst_vaapisink_query; #if USE_VAAPISINK_GLX g_object_class_install_property @@ -866,15 +862,6 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) G_PARAM_READWRITE)); #endif - g_object_class_install_property - (object_class, - PROP_DISPLAY, - g_param_spec_string("display", - "X11 display name", - "X11 display name", - "", - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, PROP_FULLSCREEN, @@ -903,7 +890,6 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) { - sink->display_name = NULL; sink->display = NULL; sink->window = NULL; sink->window_width = 0; @@ -919,11 +905,3 @@ gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) sink->use_glx = USE_VAAPISINK_GLX; sink->use_reflection = FALSE; } - -GstVaapiDisplay * -gst_vaapisink_get_display(GstVaapiSink *sink) -{ - if (!gst_vaapisink_ensure_display(sink)) - return NULL; - return sink->display; -} diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index d30692d64d..221e452f77 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -67,7 +67,6 @@ struct _GstVaapiSink { /*< private >*/ GstVideoSink parent_instance; - gchar *display_name; GstVaapiDisplay *display; GstVaapiWindow *window; guint window_width; From 075374cda3a9b08bb77babb4aaef43402921527d Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 4 Nov 2011 17:16:23 -0400 Subject: [PATCH 0468/3781] Change caps to use new video/x-surface generic type. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/Makefile.am | 3 +++ gst-libs/gst/vaapi/gstvaapicontext.c | 3 ++- gst-libs/gst/vaapi/gstvaapisurface.h | 14 ++++++++------ gst/vaapi/gstvaapiconvert.c | 4 ++-- gst/vaapi/gstvaapisink.c | 2 +- tests/Makefile.am | 2 +- tests/test-surfaces.c | 3 ++- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 17ead8b308..a68e04561d 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -134,6 +134,7 @@ libgstvaapi_@GST_MAJORMINOR@includedir = \ $(libgstvaapi_includedir) libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ + -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GST_BASE_CFLAGS) \ $(GST_CFLAGS) \ @@ -165,6 +166,7 @@ libgstvaapi_x11_@GST_MAJORMINOR@includedir = \ $(libgstvaapi_includedir) libgstvaapi_x11_@GST_MAJORMINOR@_la_CFLAGS = \ + -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ @@ -196,6 +198,7 @@ libgstvaapi_glx_@GST_MAJORMINOR@includedir = \ $(libgstvaapi_includedir) libgstvaapi_glx_@GST_MAJORMINOR@_la_CFLAGS = \ + -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index b5c409240e..2ab62bb953 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -143,7 +143,8 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context) if (!priv->surfaces_pool) { caps = gst_caps_new_simple( - "video/x-vaapi-surface", + GST_VAAPI_SURFACE_CAPS_NAME, + "type", G_TYPE_STRING, "vaapi", "width", G_TYPE_INT, priv->width, "height", G_TYPE_INT, priv->height, NULL diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index bc513f7da7..05dffcfdce 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -27,6 +27,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -39,18 +40,19 @@ typedef enum _GstVaapiSurfaceRenderFlags GstVaapiSurfaceRenderFlags; * * Generic caps type for VA surfaces. */ -#define GST_VAAPI_SURFACE_CAPS_NAME \ - "video/x-vaapi-surface" +#define GST_VAAPI_SURFACE_CAPS_NAME GST_VIDEO_CAPS_SURFACE /** * GST_VAAPI_SURFACE_CAPS: * * Generic caps for VA surfaces. */ -#define GST_VAAPI_SURFACE_CAPS \ - GST_VAAPI_SURFACE_CAPS_NAME ", " \ - "width = (int) [ 1, MAX ]," \ - "height = (int) [ 1, MAX ]," \ +#define GST_VAAPI_SURFACE_CAPS \ + GST_VAAPI_SURFACE_CAPS_NAME ", " \ + "type = vaapi, " \ + "opengl = (boolean) { true, false }, " \ + "width = (int) [ 1, MAX ], " \ + "height = (int) [ 1, MAX ], " \ "framerate = (fraction) [ 0, MAX ]" /** diff --git a/gst/vaapi/gstvaapiconvert.c b/gst/vaapi/gstvaapiconvert.c index f8719403bc..1574de78fe 100644 --- a/gst/vaapi/gstvaapiconvert.c +++ b/gst/vaapi/gstvaapiconvert.c @@ -462,7 +462,7 @@ gst_vaapiconvert_transform_caps( out_caps = gst_caps_from_string(gst_vaapiconvert_vaapi_caps_str); } else { - if (!gst_structure_has_name(structure, "video/x-vaapi-surface")) + if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) return NULL; out_caps = gst_caps_from_string(gst_vaapiconvert_yuv_caps_str); if (convert->display) { @@ -667,7 +667,7 @@ gst_vaapiconvert_get_unit_size( GstVideoFormat format; gint width, height; - if (gst_structure_has_name(structure, "video/x-vaapi-surface")) + if (gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) *size = 0; else { if (!gst_video_format_parse_caps(caps, &format, &width, &height)) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index b2477c3e87..067e2f0ec6 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -499,7 +499,7 @@ gst_vaapisink_buffer_alloc( goto error_ensure_display; structure = gst_caps_get_structure(caps, 0); - if (!gst_structure_has_name(structure, "video/x-vaapi-surface")) + if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) goto error_invalid_caps; buffer = gst_vaapi_video_buffer_new(sink->display); diff --git a/tests/Makefile.am b/tests/Makefile.am index ba6490ab38..8a27305557 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -11,7 +11,7 @@ noinst_PROGRAMS += \ $(NULL) endif -TEST_CFLAGS = $(LIBVA_CFLAGS) -I$(top_srcdir)/gst-libs $(GST_CFLAGS) +TEST_CFLAGS = $(LIBVA_CFLAGS) -I$(top_srcdir)/gst-libs $(GST_CFLAGS) -DGST_USE_UNSTABLE_API TEST_X11_CFLAGS = -DUSE_X11 $(X11_CFLAGS) TEST_GLX_CFLAGS = -DUSE_GLX $(GLX_CFLAGS) TEST_MIX_CFLAGS = $(TEST_X11_CFLAGS) diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index 9cd23e334d..17e97516c5 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -66,7 +66,8 @@ main(int argc, char *argv[]) g_object_unref(surface); caps = gst_caps_new_simple( - "video/x-vaapi-surface", + GST_VAAPI_SURFACE_CAPS_NAME, + "type", G_TYPE_STRING, "vaapi", "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL From b170d1a9827d4a944142c266798d2e5266489362 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 6 Oct 2011 16:04:37 -0400 Subject: [PATCH 0469/3781] Don't use downstream buffer allocation. With the new video/x-surface abstraction, we can't rely on having a VA specific sink downstream. Also, there was no particular reason to do that. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 11 +++------ gst/vaapi/gstvaapisink.c | 47 -------------------------------------- 2 files changed, 3 insertions(+), 55 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 716c3525a4..f267d0ff48 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -209,17 +209,12 @@ gst_vaapidecode_step(GstVaapiDecode *decode) decode ); - buffer = NULL; - ret = gst_pad_alloc_buffer( - decode->srcpad, - 0, 0, - GST_PAD_CAPS(decode->srcpad), - &buffer - ); - if (ret != GST_FLOW_OK || !buffer) + buffer = gst_vaapi_video_buffer_new(decode->display); + if (!buffer) goto error_create_buffer; GST_BUFFER_TIMESTAMP(buffer) = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); + gst_buffer_set_caps(buffer, GST_PAD_CAPS(decode->srcpad)); gst_vaapi_video_buffer_set_surface_proxy( GST_VAAPI_VIDEO_BUFFER(buffer), proxy diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 067e2f0ec6..c68a3ae63b 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -482,52 +482,6 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return TRUE; } -static GstFlowReturn -gst_vaapisink_buffer_alloc( - GstBaseSink *base_sink, - guint64 offset, - guint size, - GstCaps *caps, - GstBuffer **pout_buffer -) -{ - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstStructure *structure; - GstBuffer *buffer; - - if (!gst_vaapi_ensure_display(sink, &sink->display)) - goto error_ensure_display; - - structure = gst_caps_get_structure(caps, 0); - if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) - goto error_invalid_caps; - - buffer = gst_vaapi_video_buffer_new(sink->display); - if (!buffer) - goto error_create_buffer; - - gst_buffer_set_caps(buffer, caps); - *pout_buffer = buffer; - return GST_FLOW_OK; - - /* ERRORS */ -error_ensure_display: - { - GST_ERROR("failed to ensure display"); - return GST_FLOW_UNEXPECTED; - } -error_invalid_caps: - { - GST_ERROR("failed to validate input caps"); - return GST_FLOW_UNEXPECTED; - } -error_create_buffer: - { - GST_ERROR("failed to create video buffer"); - return GST_FLOW_UNEXPECTED; - } -} - #if USE_VAAPISINK_GLX static void render_background(GstVaapiSink *sink) @@ -837,7 +791,6 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->start = gst_vaapisink_start; basesink_class->stop = gst_vaapisink_stop; basesink_class->set_caps = gst_vaapisink_set_caps; - basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; basesink_class->preroll = gst_vaapisink_show_frame; basesink_class->render = gst_vaapisink_show_frame; basesink_class->query = gst_vaapisink_query; From a6717334f9a3030ddde8f890726a4b2926c20878 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 6 Oct 2011 16:06:15 -0400 Subject: [PATCH 0470/3781] Port to GstSurfaceBuffer interface. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/Makefile.am | 2 ++ gst-libs/gst/vaapi/gstvaapivideobuffer.c | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index a68e04561d..957e3abbf9 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -137,6 +137,7 @@ libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GST_BASE_CFLAGS) \ + $(GST_BASEVIDEO_CFLAGS) \ $(GST_CFLAGS) \ $(LIBAVCODEC_CFLAGS) \ $(LIBVA_CFLAGS) \ @@ -144,6 +145,7 @@ libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ $(GST_BASE_LIBS) \ + $(GST_BASEVIDEO_LIBS) \ $(GST_LIBS) \ $(LIBAVCODEC_LIBS) \ $(LIBVA_LIBS) \ diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index ee7ff66247..40b7b5ebd8 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -33,7 +33,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, GST_TYPE_BUFFER); +G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, GST_TYPE_SURFACE_BUFFER); #define GST_VAAPI_VIDEO_BUFFER_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index a00df2a510..1ea745bbd3 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -22,7 +22,7 @@ #ifndef GST_VAAPI_VIDEO_BUFFER_H #define GST_VAAPI_VIDEO_BUFFER_H -#include +#include #include #include #include @@ -66,7 +66,7 @@ typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass; */ struct _GstVaapiVideoBuffer { /*< private >*/ - GstBuffer parent_instance; + GstSurfaceBuffer parent_instance; GstVaapiVideoBufferPrivate *priv; }; @@ -78,7 +78,7 @@ struct _GstVaapiVideoBuffer { */ struct _GstVaapiVideoBufferClass { /*< private >*/ - GstBufferClass parent_class; + GstSurfaceBufferClass parent_class; }; GType From c5b18c27d53f3adaf5c81d829a180ef2a9451a0b Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 4 Nov 2011 19:47:09 -0400 Subject: [PATCH 0471/3781] videobuffer: add GLX buffer support. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/Makefile.am | 5 + gst-libs/gst/vaapi/gstvaapivideobuffer.c | 34 ++++ gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c | 170 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h | 88 +++++++++ gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h | 45 +++++ .../gst/vaapi/gstvaapivideoconverter_glx.c | 139 ++++++++++++++ .../gst/vaapi/gstvaapivideoconverter_glx.h | 75 ++++++++ 7 files changed, 556 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c create mode 100644 gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h create mode 100644 gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h create mode 100644 gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c create mode 100644 gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 957e3abbf9..94995ec8e3 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -76,6 +76,7 @@ libgstvaapi_source_priv_h = \ gstvaapidisplay_priv.h \ gstvaapiobject_priv.h \ gstvaapiutils.h \ + gstvaapivideobuffer_priv.h \ $(libgst_vaapi_ffmpeg_source_priv_h) \ $(NULL) @@ -104,12 +105,16 @@ libgstvaapi_glx_source_c = \ gstvaapiutils.c \ gstvaapiutils_glx.c \ gstvaapiutils_x11.c \ + gstvaapivideobuffer_glx.c \ + gstvaapivideoconverter_glx.c \ gstvaapiwindow_glx.c \ $(NULL) libgstvaapi_glx_source_h = \ gstvaapidisplay_glx.h \ gstvaapitexture.h \ + gstvaapivideobuffer_glx.h \ + gstvaapivideoconverter_glx.h \ gstvaapiwindow_glx.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 40b7b5ebd8..6814663e15 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -26,6 +26,7 @@ #include "config.h" #include "gstvaapivideobuffer.h" +#include "gstvaapivideobuffer_priv.h" #include "gstvaapiimagepool.h" #include "gstvaapisurfacepool.h" #include "gstvaapiobject_priv.h" @@ -562,3 +563,36 @@ gst_vaapi_video_buffer_set_surface_proxy( buffer->priv->proxy = g_object_ref(proxy); } } + +/** + * gst_vaapi_video_buffer_set_display: + * @buffer: a #GstVaapiVideoBuffer + * @display a #GstVaapiDisplay + * + * For subclass only, don't use. + */ +void +gst_vaapi_video_buffer_set_display( + GstVaapiVideoBuffer *buffer, + GstVaapiDisplay *display +) +{ + set_display(buffer, display); +} + +/** + * gst_vaapi_video_buffer_set_display: + * @buffer: a #GstVaapiVideoBuffer + * @other_buffer: a #GstBuffer + * + * For subclass only, don't use. + */ +void +gst_vaapi_video_buffer_set_buffer( + GstVaapiVideoBuffer *buffer, + GstBuffer *other_buffer +) +{ + g_return_if_fail (buffer->priv->buffer == NULL); + buffer->priv->buffer = gst_buffer_ref (other_buffer); +} diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c new file mode 100644 index 0000000000..e71da181a7 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c @@ -0,0 +1,170 @@ +/* + * gstvaapivideobuffer_glx.c - Gst VA video buffer + * + * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011 Collabora Ltd. + * Author: Nicolas Dufresne + * + * 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:gstvaapivideobufferglx + * @short_description: VA video buffer for GStreamer with GLX support + */ + +#include "config.h" +#include "gstvaapivideobuffer_glx.h" +#include "gstvaapivideobuffer_priv.h" +#include "gstvaapivideoconverter_glx.h" +#include "gstvaapiobject_priv.h" +#include "gstvaapiimagepool.h" +#include "gstvaapisurfacepool.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE (GstVaapiVideoBufferGLX, gst_vaapi_video_buffer_glx, + GST_VAAPI_TYPE_VIDEO_BUFFER); + +static void +gst_vaapi_video_buffer_glx_class_init(GstVaapiVideoBufferGLXClass * klass) +{ + GstSurfaceBufferClass * const surface_class = GST_SURFACE_BUFFER_CLASS (klass); + surface_class->create_converter = gst_vaapi_video_converter_glx_new; +} + +static void +gst_vaapi_video_buffer_glx_init (GstVaapiVideoBufferGLX * buffer) +{ +} + +static inline gpointer +_gst_vaapi_video_buffer_glx_new (void) +{ + return gst_mini_object_new (GST_VAAPI_TYPE_VIDEO_BUFFER_GLX); +} + +/** + * gst_vaapi_video_buffer_glx_new: + * @display: a #GstVaapiDisplayGLX + * + * Creates an empty #GstBuffer. The caller is responsible for completing + * the initialization of the buffer with the gst_vaapi_video_buffer_set_*() + * functions. + * + * Return value: the newly allocated #GstBuffer, or %NULL or error + */ +GstBuffer * +gst_vaapi_video_buffer_glx_new(GstVaapiDisplayGLX * display) +{ + GstBuffer *buffer; + + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); + + buffer = _gst_vaapi_video_buffer_glx_new (); + if (!buffer) + return NULL; + + gst_vaapi_video_buffer_set_display (GST_VAAPI_VIDEO_BUFFER (buffer), + GST_VAAPI_DISPLAY (display)); + return buffer; +} + +/** + * gst_vaapi_video_buffer_glx_new_from_pool: + * @pool: a #GstVaapiVideoPool + * + * Creates a #GstBuffer with a video object allocated from a @pool. + * Only #GstVaapiSurfacePool and #GstVaapiImagePool pools are supported. + * + * The buffer is destroyed through the last call to gst_buffer_unref() + * and the video objects are pushed back to their respective pools. + * + * Return value: the newly allocated #GstBuffer, or %NULL on error + */ +GstBuffer * +gst_vaapi_video_buffer_glx_new_from_pool (GstVaapiVideoPool * pool) +{ + GstVaapiVideoBuffer *buffer; + gboolean is_image_pool, is_surface_pool; + + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_POOL (pool), NULL); + + is_image_pool = GST_VAAPI_IS_IMAGE_POOL (pool); + is_surface_pool = GST_VAAPI_IS_SURFACE_POOL (pool); + + if (!is_image_pool && !is_surface_pool) + return NULL; + + buffer = _gst_vaapi_video_buffer_glx_new (); + if (buffer && + ((is_image_pool && + gst_vaapi_video_buffer_set_image_from_pool (buffer, pool)) || + (is_surface_pool && + gst_vaapi_video_buffer_set_surface_from_pool (buffer, pool)))) { + gst_vaapi_video_buffer_set_display (buffer, + gst_vaapi_video_pool_get_display (pool)); + return GST_BUFFER (buffer); + } + + gst_mini_object_unref (GST_MINI_OBJECT(buffer)); + return NULL; +} + +/** + * gst_vaapi_video_buffer_glx_new_from_buffer: + * @buffer: a #GstBuffer + * + * Creates a #GstBuffer with video objects bound to @buffer video + * objects, if any. + * + * Return value: the newly allocated #GstBuffer, or %NULL on error + */ +GstBuffer * +gst_vaapi_video_buffer_glx_new_from_buffer (GstBuffer * buffer) +{ + GstVaapiVideoBuffer *inbuf, *outbuf; + GstVaapiImage *image; + GstVaapiSurface *surface; + GstVaapiSurfaceProxy *proxy; + + if (!GST_VAAPI_IS_VIDEO_BUFFER_GLX (buffer)) { + if (!buffer->parent || !GST_VAAPI_IS_VIDEO_BUFFER_GLX (buffer->parent)) + return NULL; + buffer = buffer->parent; + } + inbuf = GST_VAAPI_VIDEO_BUFFER (buffer); + + outbuf = _gst_vaapi_video_buffer_glx_new (); + if (!outbuf) + return NULL; + + image = gst_vaapi_video_buffer_get_image (inbuf); + surface = gst_vaapi_video_buffer_get_surface (inbuf); + proxy = + gst_vaapi_video_buffer_get_surface_proxy (inbuf); + + if (image) + gst_vaapi_video_buffer_set_image (outbuf, image); + if (surface) + gst_vaapi_video_buffer_set_surface (outbuf, surface); + if (proxy) + gst_vaapi_video_buffer_set_surface_proxy (outbuf, proxy); + + gst_vaapi_video_buffer_set_buffer (outbuf, buffer); + return GST_BUFFER (outbuf); +} diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h new file mode 100644 index 0000000000..48bf084173 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h @@ -0,0 +1,88 @@ +/* + * gstvaapivideobuffer_glx.h - Gstreamer/VA video buffer + * + * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011 Collabora Ltd. + * Author: Nicolas Dufresne + * + * 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_VIDEO_BUFFER_GLX_H +#define GST_VAAPI_VIDEO_BUFFER_GLX_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_VIDEO_BUFFER_GLX \ + (gst_vaapi_video_buffer_glx_get_type()) + +#define GST_VAAPI_VIDEO_BUFFER_GLX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, \ + GstVaapiVideoBufferGLX)) + +#define GST_VAAPI_VIDEO_BUFFER_GLX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, \ + GstVaapiVideoBufferGLXClass)) + +#define GST_VAAPI_IS_VIDEO_BUFFER_GLX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_BUFFER_GLX)) + +#define GST_VAAPI_IS_VIDEO_BUFFER_GLX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_BUFFER_GLX)) + +#define GST_VAAPI_VIDEO_BUFFER_GLX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, \ + GstVaapiVideoBufferGLXClass)) + +typedef struct _GstVaapiVideoBufferGLX GstVaapiVideoBufferGLX; +typedef struct _GstVaapiVideoBufferGLXClass GstVaapiVideoBufferGLXClass; + +/** + * GstVaapiVideoBufferGLX: + * + * A #GstBuffer holding video objects (#GstVaapiSurface and #GstVaapiImage). + */ +struct _GstVaapiVideoBufferGLX { + /*< private >*/ + GstVaapiVideoBuffer parent_instance; +}; + +/** + * GstVaapiVideoBufferGLXClass: + * + * A #GstBuffer holding video objects + */ +struct _GstVaapiVideoBufferGLXClass { + /*< private >*/ + GstVaapiVideoBufferClass parent_class; +}; + +GType gst_vaapi_video_buffer_glx_get_type (void); +GstBuffer *gst_vaapi_video_buffer_glx_new (GstVaapiDisplayGLX * display); +GstBuffer *gst_vaapi_video_buffer_glx_new_from_pool (GstVaapiVideoPool * pool); +GstBuffer *gst_vaapi_video_buffer_glx_new_from_buffer (GstBuffer * buffer); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_BUFFER_GLX_H */ diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h b/gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h new file mode 100644 index 0000000000..d72ab63fac --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h @@ -0,0 +1,45 @@ +/* + * gstvaapivideobuffer_priv.h - Gstreamer/VA video buffer (private interface) + * + * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011 Collabora Ltd. + * Author: Nicolas Dufresne + * + * 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_VIDEO_BUFFER_PRIV_H +#define GST_VAAPI_VIDEO_BUFFER_PRIV_H + +#include + +G_BEGIN_DECLS + +void +gst_vaapi_video_buffer_set_display( + GstVaapiVideoBuffer *buffer, + GstVaapiDisplay *display +); + +void +gst_vaapi_video_buffer_set_buffer( + GstVaapiVideoBuffer *buffer, + GstBuffer *other_buffer +); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_BUFFER_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c new file mode 100644 index 0000000000..515d57ea61 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -0,0 +1,139 @@ +/* + * gstvaapivideoconverter_glx.c - Gst VA video converter + * + * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011 Collabora Ltd. + * Author: Nicolas Dufresne + * + * 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 "config.h" +#include +#include "gstvaapivideoconverter_glx.h" +#include "gstvaapivideobuffer.h" +#include "gstvaapitexture.h" + +static void gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoConverterGLX, gst_vaapi_video_converter_glx, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GST_TYPE_SURFACE_CONVERTER, + gst_vaapi_video_converter_glx_iface_init)); + +struct _GstVaapiVideoConverterGLXPrivate { + GstVaapiTexture *texture; +}; + +static void +gst_vaapi_video_converter_glx_dispose(GObject *object) +{ + GstVaapiVideoConverterGLXPrivate *priv = + GST_VAAPI_VIDEO_CONVERTER_GLX (object)->priv; + + if (priv->texture) + g_object_unref (priv->texture); + + priv->texture = NULL; + + G_OBJECT_CLASS (gst_vaapi_video_converter_glx_parent_class)->dispose (object); +} + +static void +gst_vaapi_video_converter_glx_class_init(GstVaapiVideoConverterGLXClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (klass, sizeof (GstVaapiVideoConverterGLXPrivate)); + object_class->dispose = gst_vaapi_video_converter_glx_dispose; +} + +static void +gst_vaapi_video_converter_glx_init(GstVaapiVideoConverterGLX *buffer) +{ + buffer->priv = G_TYPE_INSTANCE_GET_PRIVATE(buffer, + GST_VAAPI_TYPE_VIDEO_CONVERTER, + GstVaapiVideoConverterGLXPrivate); +} + +static void +gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface *iface) { + iface->upload = gst_vaapi_video_converter_glx_upload; +} + +/** + * gst_vaapi_video_converter_glx_new: + * @ + * + * Creates an empty #GstBuffer. The caller is responsible for completing + * the initialization of the buffer with the gst_vaapi_video_converter_glx_set_*() + * functions. + * + * Return value: the newly allocated #GstBuffer, or %NULL or error + */ +GstSurfaceConverter * +gst_vaapi_video_converter_glx_new(GstSurfaceBuffer *surface, const gchar *type, + GValue *dest) +{ + GstVaapiVideoBuffer *buffer = GST_VAAPI_VIDEO_BUFFER (surface); + GstVaapiDisplay *display = gst_vaapi_video_buffer_get_display (buffer); + GstVaapiTexture *texture; + GstVaapiVideoConverterGLX *converter = NULL; + + /* We only support Open GL texture conversion */ + if (strcmp(type, "opengl") || !G_VALUE_HOLDS_UINT (dest)) + return NULL; + + /* FIXME Should we assume target and format ? */ + texture = gst_vaapi_texture_new_with_texture (display, + g_value_get_uint (dest), + GL_TEXTURE_2D, + GL_BGRA); + + if (texture) { + converter = g_object_new (GST_VAAPI_TYPE_VIDEO_CONVERTER, NULL); + converter->priv->texture = texture; + } + + return GST_SURFACE_CONVERTER (converter); +} + +gboolean +gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *converter, + GstSurfaceBuffer *buffer) +{ + GstVaapiVideoConverterGLXPrivate *priv = + GST_VAAPI_VIDEO_CONVERTER_GLX (converter)->priv; + GstVaapiSurface *surface = gst_vaapi_video_buffer_get_surface ( + GST_VAAPI_VIDEO_BUFFER (buffer)); + GstVaapiDisplay *new_dpy, *old_dpy; + + new_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); + old_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (priv->texture)); + + if (old_dpy != new_dpy) { + guint texture = gst_vaapi_texture_get_id (priv->texture); + g_object_unref (priv->texture); + priv->texture = gst_vaapi_texture_new_with_texture (new_dpy, + texture, + GL_TEXTURE_2D, + GL_BGRA); + } + + return gst_vaapi_texture_put_surface (priv->texture, surface, + GST_VAAPI_PICTURE_STRUCTURE_FRAME); +} diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h new file mode 100644 index 0000000000..012bb13761 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h @@ -0,0 +1,75 @@ +/* + * gstvaapivideoconverter_glx.h - Gstreamer/VA video converter + * + * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011 Collabora Ltd. + * Author: Nicolas Dufresne + * + * 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_VIDEO_CONVERTER_GLX_H +#define GST_VAAPI_VIDEO_CONVERTER_GLX_H + +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_VIDEO_CONVERTER (gst_vaapi_video_converter_glx_get_type ()) +#define GST_VAAPI_VIDEO_CONVERTER_GLX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER, GstVaapiVideoConverterGLX)) +#define GST_VAAPI_VIDEO_CONVERTER_GLX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER, GstVaapiVideoConverterGLXClass)) +#define GST_VAAPI_IS_VIDEO_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER)) +#define GST_VAAPI_IS_VIDEO_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER)) +#define GST_VAAPI_VIDEO_CONVERTER_GLX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER, GstVaapiVideoConverterGLXClass)) + +typedef struct _GstVaapiVideoConverterGLX GstVaapiVideoConverterGLX; +typedef struct _GstVaapiVideoConverterGLXPrivate GstVaapiVideoConverterGLXPrivate; +typedef struct _GstVaapiVideoConverterGLXClass GstVaapiVideoConverterGLXClass; + +/** + * GstVaapiVideoConverterGLX: + * + * Converter to transform VA buffers into GL textures. + */ +struct _GstVaapiVideoConverterGLX { + /*< private >*/ + GObject parent_instance; + + GstVaapiVideoConverterGLXPrivate *priv; +}; + +/** + * GstVaapiVideoConverterGLXClass: + * + * Converter to transform VA buffers into GL textures. + */ +struct _GstVaapiVideoConverterGLXClass { + /*< private >*/ + GObjectClass parent_class; +}; + +GType gst_vaapi_video_converter_glx_get_type (void); + +GstSurfaceConverter *gst_vaapi_video_converter_glx_new (GstSurfaceBuffer *buffer, + const gchar *type, + GValue *dest); + +gboolean gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *self, + GstSurfaceBuffer *buffer); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_CONVERTER_GLX_H */ From bb22317e3939a78e7d2de3d716f2d6954fe22137 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 4 Nov 2011 20:07:52 -0400 Subject: [PATCH 0472/3781] vaapiplugin: allocate GLX buffers when supported. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapiconvert.c | 8 ++++++++ gst/vaapi/gstvaapidecode.c | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/gst/vaapi/gstvaapiconvert.c b/gst/vaapi/gstvaapiconvert.c index 1574de78fe..043a6ba782 100644 --- a/gst/vaapi/gstvaapiconvert.c +++ b/gst/vaapi/gstvaapiconvert.c @@ -36,6 +36,14 @@ #include #include +#if USE_VAAPI_GLX +#include +#define gst_vaapi_video_buffer_new_from_pool(pool) \ + gst_vaapi_video_buffer_glx_new_from_pool(pool) +#define gst_vaapi_video_buffer_new_from_buffer(buffer) \ + gst_vaapi_video_buffer_glx_new_from_buffer(buffer) +#endif + #include "gstvaapipluginutil.h" #include "gstvaapiconvert.h" diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f267d0ff48..dff200bd7a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -36,6 +36,12 @@ #include #include +#if USE_VAAPI_GLX +#include +#define gst_vaapi_video_buffer_new(display) \ + gst_vaapi_video_buffer_glx_new(GST_VAAPI_DISPLAY_GLX(display)) +#endif + #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" From 36e0f582a8c7d28e5617aa47ad6f092e67e1ee71 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 4 Nov 2011 19:47:25 -0400 Subject: [PATCH 0473/3781] vaapiplugin: properly set opengl support in caps. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapiconvert.c | 1 + gst/vaapi/gstvaapidecode.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapiconvert.c b/gst/vaapi/gstvaapiconvert.c index 043a6ba782..229060c191 100644 --- a/gst/vaapi/gstvaapiconvert.c +++ b/gst/vaapi/gstvaapiconvert.c @@ -488,6 +488,7 @@ gst_vaapiconvert_transform_caps( structure = gst_caps_get_structure(out_caps, 0); gst_structure_set_value(structure, "width", v_width); gst_structure_set_value(structure, "height", v_height); + gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, NULL); if (v_framerate) gst_structure_set_value(structure, "framerate", v_framerate); if (v_par) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index dff200bd7a..f0170f8892 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -159,6 +159,8 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) if (v_par) gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); + gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, NULL); + other_caps = gst_caps_copy(decode->srcpad_caps); success = gst_pad_set_caps(decode->srcpad, other_caps); gst_caps_unref(other_caps); From e3c6a78da69f008d94b0f6cce95136e94648ce69 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 8 Dec 2011 15:16:14 +0100 Subject: [PATCH 0474/3781] decoder: drop unused headers. --- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 76f287901d..52ddc22b62 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -23,7 +23,6 @@ #define GST_VAAPI_DECODER_PRIV_H #include -#include #include #include From dc08d1eae08c7bfa3ab6c4b3a7770387d6058e0b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 8 Dec 2011 15:44:09 +0100 Subject: [PATCH 0475/3781] vaapiplugin: properly set surface type to "vaapi" in caps. --- gst/vaapi/gstvaapiconvert.c | 1 + gst/vaapi/gstvaapidecode.c | 1 + 2 files changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapiconvert.c b/gst/vaapi/gstvaapiconvert.c index 229060c191..39f1c48d10 100644 --- a/gst/vaapi/gstvaapiconvert.c +++ b/gst/vaapi/gstvaapiconvert.c @@ -488,6 +488,7 @@ gst_vaapiconvert_transform_caps( structure = gst_caps_get_structure(out_caps, 0); gst_structure_set_value(structure, "width", v_width); gst_structure_set_value(structure, "height", v_height); + gst_structure_set(structure, "type", G_TYPE_STRING, "vaapi", NULL); gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, NULL); if (v_framerate) gst_structure_set_value(structure, "framerate", v_framerate); diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f0170f8892..63f29fc0aa 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -159,6 +159,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) if (v_par) gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); + gst_structure_set(structure, "type", G_TYPE_STRING, "vaapi", NULL); gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, NULL); other_caps = gst_caps_copy(decode->srcpad_caps); From 809e087cca77d5a233a622e92b3905c93728ca42 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 8 Dec 2011 11:54:59 +0100 Subject: [PATCH 0476/3781] vaapidecode: return sink caps template if decoder is in NULL state. Otherwise, the decoder would always create its own X display instead of probing it from the downstream element, which is not reliable. e.g. DISPLAY is not :0 or when running on Wayland. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 15 +++++++++++++++ gst/vaapi/gstvaapidecode.h | 1 + 2 files changed, 16 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 63f29fc0aa..ffba8fb5aa 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -455,6 +455,9 @@ gst_vaapidecode_change_state(GstElement *element, GstStateChange transition) GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + decode->is_ready = TRUE; + break; case GST_STATE_CHANGE_READY_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: @@ -472,6 +475,14 @@ gst_vaapidecode_change_state(GstElement *element, GstStateChange transition) break; case GST_STATE_CHANGE_PAUSED_TO_READY: break; + case GST_STATE_CHANGE_READY_TO_NULL: + gst_vaapidecode_destroy(decode); + if (decode->display) { + g_object_unref(decode->display); + decode->display = NULL; + } + decode->is_ready = FALSE; + break; default: break; } @@ -570,6 +581,9 @@ gst_vaapidecode_get_caps(GstPad *pad) { GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); + if (!decode->is_ready) + return gst_static_pad_template_get_caps(&gst_vaapidecode_sink_factory); + if (!gst_vaapidecode_ensure_allowed_caps(decode)) return gst_caps_new_empty(); @@ -660,6 +674,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) decode->decoder_caps = NULL; decode->allowed_caps = NULL; decode->use_ffmpeg = TRUE; + decode->is_ready = FALSE; /* Pad through which data comes in to the element */ decode->sinkpad = gst_pad_new_from_template( diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index e2788a54de..f288583feb 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -72,6 +72,7 @@ struct _GstVaapiDecode { GstCaps *decoder_caps; GstCaps *allowed_caps; unsigned int use_ffmpeg : 1; + unsigned int is_ready : 1; }; struct _GstVaapiDecodeClass { From 5f85b67b1828e6fe12b928f7eb6d8608bd00de9c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 9 Dec 2011 10:44:52 +0100 Subject: [PATCH 0477/3781] autogen: don't configure if NO_CONFIGURE variable is set. --- autogen.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 284547f02b..9e15ad9ae9 100755 --- a/autogen.sh +++ b/autogen.sh @@ -36,4 +36,6 @@ else ACLOCAL="${ACLOCAL-aclocal} $ACLOCAL_FLAGS" autoreconf -v --install || exit $? fi -./configure "$@" && echo "Now type 'make' to compile $PROJECT." +if test -z "$NO_CONFIGURE"; then + ./configure "$@" && echo "Now type 'make' to compile $PROJECT." +fi From 0df67b5e89c684a0a583770dd1450ef4249f1d77 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 9 Dec 2011 10:45:20 +0100 Subject: [PATCH 0478/3781] vaapiplugin: include local build dir to CFLAGS for generated files. --- gst/vaapi/Makefile.am | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 0b18d08f11..8b1bbf8549 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -1,9 +1,11 @@ plugin_LTLIBRARIES = libgstvaapi.la libgstvaapi_CFLAGS = \ - $(LIBVA_CFLAGS) \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs + $(LIBVA_CFLAGS) \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + -I$(top_builddir)/gst-libs \ + $(NULL) if USE_VAAPI_GLX libgstvaapi_LIBS = \ From 89fcb023c8aee45a81ffee88dc71b95cf38a9f84 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 9 Dec 2011 11:20:04 +0100 Subject: [PATCH 0479/3781] configure: check for GstBaseSink 'query' vfunc. --- configure.ac | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/configure.ac b/configure.ac index 4334d75395..7f27bb948f 100644 --- a/configure.ac +++ b/configure.ac @@ -147,6 +147,24 @@ PKG_CHECK_MODULES([GST], AC_SUBST(GST_CFLAGS) AC_SUBST(GST_LIBS) +AC_CACHE_CHECK([for GstBaseSink::query hook], ac_cv_have_gst_base_sink_query, [ + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $GST_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $GST_LIBS" + AC_TRY_COMPILE( + [#include ], + [GstBaseSinkClass klass; klass.query = NULL;], + [ac_cv_have_gst_base_sink_query="yes"], + [ac_cv_have_gst_base_sink_query="no"] + ) + CFLAGS="$saved_CFLAGS" + LIBS="$saved_LIBS" +]) +if test "$ac_cv_have_gst_base_sink_query" != "yes"; then + AC_MSG_ERROR([GstBaseSink does not contain the 'query' vfunc]) +fi + dnl Check for GStreamer plugins-base PKG_CHECK_MODULES([GST_PLUGINS_BASE], [gstreamer-plugins-base-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED] From 64296cbd43f9fe2ed18a43d1227c1ed4f29d3815 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 9 Dec 2011 11:38:34 +0100 Subject: [PATCH 0480/3781] NEWS: updates. --- NEWS | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 5ff94446aa..b6d9b396ed 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,15 @@ -gst-vaapi NEWS -- summary of changes. 2011-12-07 +gst-vaapi NEWS -- summary of changes. 2011-12-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011 Intel Corporation +Version 0.3.0 - DD.Dec.2011 +* Group all plugins into the same bundle +* Use new XOverlay API (Sreerenj Balachandran) +* Use new GstVideoContext and GstSurfaceBuffer API (Nicolas Dufresne) +* Fix vaapidecode sink caps if decoder is in NULL state (Sreerenj Balachandran) +* Fix auto-plugging and downstream buffer allocation (Nicolas Dufresne) +* Fix crash in VA display init if no VA configs were found (Nicolas Dufresne) + Version 0.2.7 - 07.Dec.2011 * Relicense plugins and tests to LGPL v2.1 (SDS) * Fix MPEG-2 decoding from TS & PS streams From 82f390f6b20d17a0fcfe1a821761994d7532c6f6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 9 Dec 2011 11:38:43 +0100 Subject: [PATCH 0481/3781] README: update dependencies. --- README | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README b/README index 6d20e15095..a4d94be285 100644 --- a/README +++ b/README @@ -43,10 +43,14 @@ Requirements Software requirements - * libgstreamer0.10-dev >= 0.10.10 - * libgstreamer-plugins-base0.10-dev >= 0.10.16 - * libva-dev >= 0.31.0-1+sds9 (VA/GLX) - * libavcodec-dev >= 0.6 or with + * libgstreamer0.10-dev >= 0.10.35.1 + or with GstBaseSink::query() + * libgstreamer-plugins-base0.10-dev >= 0.10.35 + * libgstreamer-plugins-bad0.10-dev >= 0.10.22.1 + or with GstVideoContext, GstSurfaceBuffer + * libva-dev >= 1.0.3 (VA/GLX) + * libavcodec-dev >= 0.6 + or with Hardware requirements From ed6e968e39401cf4203dd33d02077983d8cacfa1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 9 Dec 2011 11:46:45 +0100 Subject: [PATCH 0482/3781] 0.3.0. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index b6d9b396ed..b974ba7a7c 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,8 @@ -gst-vaapi NEWS -- summary of changes. 2011-12-DD +gst-vaapi NEWS -- summary of changes. 2011-12-09 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011 Intel Corporation -Version 0.3.0 - DD.Dec.2011 +Version 0.3.0 - 09.Dec.2011 * Group all plugins into the same bundle * Use new XOverlay API (Sreerenj Balachandran) * Use new GstVideoContext and GstSurfaceBuffer API (Nicolas Dufresne) diff --git a/configure.ac b/configure.ac index 7f27bb948f..26f989f763 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From e0fc705de37d3f54734a242d0ecff4092e221d88 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Dec 2011 10:04:32 +0100 Subject: [PATCH 0483/3781] Drop unused copy of GstBaseVideoDecoder. --- gst-libs/gst/video/Makefile.am | 43 - gst-libs/gst/video/gstbasevideocodec.c | 575 -------- gst-libs/gst/video/gstbasevideocodec.h | 150 --- gst-libs/gst/video/gstbasevideodecoder.c | 1522 ---------------------- gst-libs/gst/video/gstbasevideodecoder.h | 178 --- gst-libs/gst/video/gstbasevideoutils.c | 45 - gst-libs/gst/video/gstbasevideoutils.h | 88 -- 7 files changed, 2601 deletions(-) delete mode 100644 gst-libs/gst/video/Makefile.am delete mode 100644 gst-libs/gst/video/gstbasevideocodec.c delete mode 100644 gst-libs/gst/video/gstbasevideocodec.h delete mode 100644 gst-libs/gst/video/gstbasevideodecoder.c delete mode 100644 gst-libs/gst/video/gstbasevideodecoder.h delete mode 100644 gst-libs/gst/video/gstbasevideoutils.c delete mode 100644 gst-libs/gst/video/gstbasevideoutils.h diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am deleted file mode 100644 index 4a2dc1d6f0..0000000000 --- a/gst-libs/gst/video/Makefile.am +++ /dev/null @@ -1,43 +0,0 @@ -noinst_LTLIBRARIES = libgstbasevideo-@GST_MAJORMINOR@.la - -libgstbasevideo_source_c = \ - gstbasevideocodec.c \ - gstbasevideodecoder.c \ - gstbasevideoutils.c \ - $(NULL) - -libgstbasevideo_source_h = \ - gstbasevideocodec.h \ - gstbasevideodecoder.h \ - gstbasevideoutils.h \ - $(NULL) - -libgstbasevideo_@GST_MAJORMINOR@includedir = \ - $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/video - -libgstbasevideo_@GST_MAJORMINOR@_la_SOURCES = \ - $(libgstbasevideo_source_c) - -noinst_HEADERS = \ - $(libgstbasevideo_source_h) - -libgstbasevideo_@GST_MAJORMINOR@_la_CFLAGS = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - $(GST_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) \ - $(NULL) - -libgstbasevideo_@GST_MAJORMINOR@_la_LIBADD = \ - $(GST_LIBS) \ - $(GST_BASE_LIBS) \ - $(GST_PLUGINS_BASE_LIBS) \ - $(NULL) - -libgstbasevideo_@GST_MAJORMINOR@_la_LDFLAGS = \ - $(GST_ALL_LDFLAGS) \ - $(NULL) - -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in diff --git a/gst-libs/gst/video/gstbasevideocodec.c b/gst-libs/gst/video/gstbasevideocodec.c deleted file mode 100644 index a6931c96cb..0000000000 --- a/gst-libs/gst/video/gstbasevideocodec.c +++ /dev/null @@ -1,575 +0,0 @@ -/* Schrodinger - * Copyright (C) 2006 David Schleef - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstbasevideocodec.h" - -#include -#include - -GST_DEBUG_CATEGORY (basevideocodec_debug); -#define GST_CAT_DEFAULT basevideocodec_debug - -/* GstBaseVideoCodec signals and args */ -enum -{ - LAST_SIGNAL -}; - -enum -{ - ARG_0 -}; - -static void gst_base_video_codec_finalize (GObject * object); - -//static const GstQueryType *gst_base_video_codec_get_query_types (GstPad *pad); -//static gboolean gst_base_video_codec_src_query (GstPad *pad, GstQuery *query); -//static gboolean gst_base_video_codec_sink_query (GstPad *pad, GstQuery *query); -//static gboolean gst_base_video_codec_src_event (GstPad *pad, GstEvent *event); -//static gboolean gst_base_video_codec_sink_event (GstPad *pad, GstEvent *event); -static GstStateChangeReturn gst_base_video_codec_change_state (GstElement * - element, GstStateChange transition); -//static GstFlowReturn gst_base_video_codec_push_all (GstBaseVideoCodec *base_video_codec, -// gboolean at_eos); - - -GST_BOILERPLATE (GstBaseVideoCodec, gst_base_video_codec, GstElement, - GST_TYPE_ELEMENT); - -static void -gst_base_video_codec_base_init (gpointer g_class) -{ - GST_DEBUG_CATEGORY_INIT (basevideocodec_debug, "basevideocodec", 0, - "Base Video Codec"); - -} - -static void -gst_base_video_codec_class_init (GstBaseVideoCodecClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *element_class; - - gobject_class = G_OBJECT_CLASS (klass); - element_class = GST_ELEMENT_CLASS (klass); - - gobject_class->finalize = gst_base_video_codec_finalize; - - element_class->change_state = gst_base_video_codec_change_state; -} - -static void -gst_base_video_codec_init (GstBaseVideoCodec * base_video_codec, - GstBaseVideoCodecClass * klass) -{ - GstPadTemplate *pad_template; - - GST_DEBUG ("gst_base_video_codec_init"); - - pad_template = - gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink"); - g_return_if_fail (pad_template != NULL); - - base_video_codec->sinkpad = gst_pad_new_from_template (pad_template, "sink"); - //gst_pad_set_query_function (base_video_codec->sinkpad, - // gst_base_video_codec_sink_query); - gst_element_add_pad (GST_ELEMENT (base_video_codec), - base_video_codec->sinkpad); - - pad_template = - gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src"); - g_return_if_fail (pad_template != NULL); - - base_video_codec->srcpad = gst_pad_new_from_template (pad_template, "src"); - gst_element_add_pad (GST_ELEMENT (base_video_codec), - base_video_codec->srcpad); - - base_video_codec->input_adapter = gst_adapter_new (); - base_video_codec->output_adapter = gst_adapter_new (); - -} - -static void -gst_base_video_codec_reset (GstBaseVideoCodec * base_video_codec) -{ - GST_DEBUG ("reset"); - - base_video_codec->system_frame_number = 0; - - //gst_segment_init (&base_video_codec->state.segment, GST_FORMAT_TIME); - gst_adapter_clear (base_video_codec->input_adapter); - gst_adapter_clear (base_video_codec->output_adapter); - -} - -static void -gst_base_video_codec_finalize (GObject * object) -{ - GstBaseVideoCodec *base_video_codec; - - g_return_if_fail (GST_IS_BASE_VIDEO_CODEC (object)); - base_video_codec = GST_BASE_VIDEO_CODEC (object); - - if (base_video_codec->input_adapter) { - g_object_unref (base_video_codec->input_adapter); - } - if (base_video_codec->output_adapter) { - g_object_unref (base_video_codec->output_adapter); - } - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -#ifdef unused -static const GstQueryType * -gst_base_video_codec_get_query_types (GstPad * pad) -{ - static const GstQueryType query_types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - GST_QUERY_CONVERT, - 0 - }; - - return query_types; -} -#endif - -#if 0 -static gboolean -gst_base_video_codec_src_convert (GstPad * pad, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - gboolean res; - GstBaseVideoCodec *dec; - - if (src_format == *dest_format) { - *dest_value = src_value; - return TRUE; - } - - dec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); - - if (src_format == GST_FORMAT_DEFAULT && *dest_format == GST_FORMAT_TIME) { - if (dec->fps_d != 0) { - *dest_value = gst_util_uint64_scale (granulepos_to_frame (src_value), - dec->fps_d * GST_SECOND, dec->fps_n); - res = TRUE; - } else { - res = FALSE; - } - } else { - GST_WARNING ("unhandled conversion from %d to %d", src_format, - *dest_format); - res = FALSE; - } - - gst_object_unref (dec); - - return res; -} - -static gboolean -gst_base_video_codec_sink_convert (GstPad * pad, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - gboolean res = TRUE; - GstBaseVideoCodec *dec; - - if (src_format == *dest_format) { - *dest_value = src_value; - return TRUE; - } - - dec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); - - /* FIXME: check if we are in a decoding state */ - - switch (src_format) { - case GST_FORMAT_DEFAULT: - switch (*dest_format) { - case GST_FORMAT_TIME: - *dest_value = gst_util_uint64_scale (src_value, - dec->fps_d * GST_SECOND, dec->fps_n); - break; - default: - res = FALSE; - } - break; - case GST_FORMAT_TIME: - switch (*dest_format) { - case GST_FORMAT_DEFAULT: - { - *dest_value = gst_util_uint64_scale (src_value, - dec->fps_n, dec->fps_d * GST_SECOND); - break; - } - default: - res = FALSE; - break; - } - break; - default: - res = FALSE; - break; - } - - gst_object_unref (dec); - - return res; -} -#endif - -#ifdef unused -static gboolean -gst_base_video_codec_src_query (GstPad * pad, GstQuery * query) -{ - GstBaseVideoCodec *base_codec; - gboolean res = FALSE; - - base_codec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_POSITION: - { - GstFormat format; - gint64 time; - gint64 value; - - gst_query_parse_position (query, &format, NULL); - - time = gst_util_uint64_scale (base_codec->system_frame_number, - base_codec->state.fps_n, base_codec->state.fps_d); - time += base_codec->state.segment.time; - GST_DEBUG ("query position %" GST_TIME_FORMAT, GST_TIME_ARGS (time)); - res = gst_base_video_encoded_video_convert (&base_codec->state, - GST_FORMAT_TIME, time, &format, &value); - if (!res) - goto error; - - gst_query_set_position (query, format, value); - break; - } - case GST_QUERY_DURATION: - res = gst_pad_query (GST_PAD_PEER (base_codec->sinkpad), query); - if (!res) - goto error; - break; - case GST_QUERY_CONVERT: - { - GstFormat src_fmt, dest_fmt; - gint64 src_val, dest_val; - - GST_DEBUG ("query convert"); - - gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); - res = gst_base_video_encoded_video_convert (&base_codec->state, - src_fmt, src_val, &dest_fmt, &dest_val); - if (!res) - goto error; - gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); - break; - } - default: - res = gst_pad_query_default (pad, query); - break; - } -done: - gst_object_unref (base_codec); - - return res; -error: - GST_DEBUG_OBJECT (base_codec, "query failed"); - goto done; -} -#endif - -#ifdef unused -static gboolean -gst_base_video_codec_sink_query (GstPad * pad, GstQuery * query) -{ - GstBaseVideoCodec *base_video_codec; - gboolean res = FALSE; - - base_video_codec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_CONVERT: - { - GstFormat src_fmt, dest_fmt; - gint64 src_val, dest_val; - - gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); - res = gst_base_video_encoded_video_convert (&base_video_codec->state, - src_fmt, src_val, &dest_fmt, &dest_val); - if (!res) - goto error; - gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); - break; - } - default: - res = gst_pad_query_default (pad, query); - break; - } -done: - gst_object_unref (base_video_codec); - - return res; -error: - GST_DEBUG_OBJECT (base_video_codec, "query failed"); - goto done; -} -#endif - -#ifdef unused -static gboolean -gst_base_video_codec_src_event (GstPad * pad, GstEvent * event) -{ - GstBaseVideoCodec *base_video_codec; - gboolean res = FALSE; - - base_video_codec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - { - GstFormat format, tformat; - gdouble rate; - GstEvent *real_seek; - GstSeekFlags flags; - GstSeekType cur_type, stop_type; - gint64 cur, stop; - gint64 tcur, tstop; - - gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, - &cur, &stop_type, &stop); - gst_event_unref (event); - - tformat = GST_FORMAT_TIME; - res = gst_base_video_encoded_video_convert (&base_video_codec->state, - format, cur, &tformat, &tcur); - if (!res) - goto convert_error; - res = gst_base_video_encoded_video_convert (&base_video_codec->state, - format, stop, &tformat, &tstop); - if (!res) - goto convert_error; - - real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME, - flags, cur_type, tcur, stop_type, tstop); - - res = gst_pad_push_event (base_video_codec->sinkpad, real_seek); - - break; - } -#if 0 - case GST_EVENT_QOS: - { - gdouble proportion; - GstClockTimeDiff diff; - GstClockTime timestamp; - - gst_event_parse_qos (event, &proportion, &diff, ×tamp); - - GST_OBJECT_LOCK (base_video_codec); - base_video_codec->proportion = proportion; - base_video_codec->earliest_time = timestamp + diff; - GST_OBJECT_UNLOCK (base_video_codec); - - GST_DEBUG_OBJECT (base_video_codec, - "got QoS %" GST_TIME_FORMAT ", %" G_GINT64_FORMAT, - GST_TIME_ARGS (timestamp), diff); - - res = gst_pad_push_event (base_video_codec->sinkpad, event); - break; - } -#endif - default: - res = gst_pad_push_event (base_video_codec->sinkpad, event); - break; - } -done: - gst_object_unref (base_video_codec); - return res; - -convert_error: - GST_DEBUG_OBJECT (base_video_codec, "could not convert format"); - goto done; -} -#endif - -#ifdef unused -static gboolean -gst_base_video_codec_sink_event (GstPad * pad, GstEvent * event) -{ - GstBaseVideoCodec *base_video_codec; - gboolean ret = FALSE; - - base_video_codec = GST_BASE_VIDEO_CODEC (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_START: - ret = gst_pad_push_event (base_video_codec->srcpad, event); - break; - case GST_EVENT_FLUSH_STOP: - gst_base_video_codec_reset (base_video_codec); - ret = gst_pad_push_event (base_video_codec->srcpad, event); - break; - case GST_EVENT_EOS: - if (gst_base_video_codec_push_all (base_video_codec, - FALSE) == GST_FLOW_ERROR) { - gst_event_unref (event); - return FALSE; - } - - ret = gst_pad_push_event (base_video_codec->srcpad, event); - break; - case GST_EVENT_NEWSEGMENT: - { - gboolean update; - GstFormat format; - gdouble rate; - gint64 start, stop, time; - - gst_event_parse_new_segment (event, &update, &rate, &format, &start, - &stop, &time); - - if (format != GST_FORMAT_TIME) - goto newseg_wrong_format; - - if (rate <= 0.0) - goto newseg_wrong_rate; - - GST_DEBUG ("newsegment %" GST_TIME_FORMAT " %" GST_TIME_FORMAT, - GST_TIME_ARGS (start), GST_TIME_ARGS (time)); - gst_segment_set_newsegment (&base_video_codec->state.segment, update, - rate, format, start, stop, time); - - ret = gst_pad_push_event (base_video_codec->srcpad, event); - break; - } - default: - ret = gst_pad_push_event (base_video_codec->srcpad, event); - break; - } -done: - gst_object_unref (base_video_codec); - return ret; - -newseg_wrong_format: - GST_DEBUG_OBJECT (base_video_codec, "received non TIME newsegment"); - gst_event_unref (event); - goto done; - -newseg_wrong_rate: - GST_DEBUG_OBJECT (base_video_codec, "negative rates not supported"); - gst_event_unref (event); - goto done; -} -#endif - - -static GstStateChangeReturn -gst_base_video_codec_change_state (GstElement * element, - GstStateChange transition) -{ - GstBaseVideoCodec *base_video_codec = GST_BASE_VIDEO_CODEC (element); - GstStateChangeReturn ret; - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - gst_base_video_codec_reset (base_video_codec); - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - break; - default: - break; - } - - ret = parent_class->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_base_video_codec_reset (base_video_codec); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - - return ret; -} - -#if 0 -guint64 -gst_base_video_codec_get_timestamp (GstBaseVideoCodec * base_video_codec, - int picture_number) -{ - if (picture_number < 0) { - return base_video_codec->timestamp_offset - - (gint64) gst_util_uint64_scale (-picture_number, - base_video_codec->state.fps_d * GST_SECOND, - base_video_codec->state.fps_n); - } else { - return base_video_codec->timestamp_offset + - gst_util_uint64_scale (picture_number, - base_video_codec->state.fps_d * GST_SECOND, - base_video_codec->state.fps_n); - } -} -#endif - -GstVideoFrame * -gst_base_video_codec_new_frame (GstBaseVideoCodec * base_video_codec) -{ - GstVideoFrame *frame; - - frame = g_malloc0 (sizeof (GstVideoFrame)); - - frame->system_frame_number = base_video_codec->system_frame_number; - base_video_codec->system_frame_number++; - - return frame; -} - -void -gst_base_video_codec_free_frame (GstVideoFrame * frame) -{ - if (frame->sink_buffer) { - gst_buffer_unref (frame->sink_buffer); - } -#if 0 - if (frame->src_buffer) { - gst_buffer_unref (frame->src_buffer); - } -#endif - - g_free (frame); -} diff --git a/gst-libs/gst/video/gstbasevideocodec.h b/gst-libs/gst/video/gstbasevideocodec.h deleted file mode 100644 index b6acf62ee6..0000000000 --- a/gst-libs/gst/video/gstbasevideocodec.h +++ /dev/null @@ -1,150 +0,0 @@ -/* GStreamer - * Copyright (C) 2008 David Schleef - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _GST_BASE_VIDEO_CODEC_H_ -#define _GST_BASE_VIDEO_CODEC_H_ - -#ifndef GST_USE_UNSTABLE_API -#warning "GstBaseVideoCodec is unstable API and may change in future." -#warning "You can define GST_USE_UNSTABLE_API to avoid this warning." -#endif - -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_BASE_VIDEO_CODEC \ - (gst_base_video_codec_get_type()) -#define GST_BASE_VIDEO_CODEC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BASE_VIDEO_CODEC,GstBaseVideoCodec)) -#define GST_BASE_VIDEO_CODEC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BASE_VIDEO_CODEC,GstBaseVideoCodecClass)) -#define GST_BASE_VIDEO_CODEC_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_BASE_VIDEO_CODEC,GstBaseVideoCodecClass)) -#define GST_IS_BASE_VIDEO_CODEC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BASE_VIDEO_CODEC)) -#define GST_IS_BASE_VIDEO_CODEC_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_VIDEO_CODEC)) - -/** - * GST_BASE_VIDEO_CODEC_SINK_NAME: - * - * The name of the templates for the sink pad. - */ -#define GST_BASE_VIDEO_CODEC_SINK_NAME "sink" -/** - * GST_BASE_VIDEO_CODEC_SRC_NAME: - * - * The name of the templates for the source pad. - */ -#define GST_BASE_VIDEO_CODEC_SRC_NAME "src" - -/** - * GST_BASE_VIDEO_CODEC_SRC_PAD: - * @obj: base video codec instance - * - * Gives the pointer to the source #GstPad object of the element. - */ -#define GST_BASE_VIDEO_CODEC_SRC_PAD(obj) (((GstBaseVideoCodec *) (obj))->srcpad) - -/** - * GST_BASE_VIDEO_CODEC_SINK_PAD: - * @obj: base video codec instance - * - * Gives the pointer to the sink #GstPad object of the element. - */ -#define GST_BASE_VIDEO_CODEC_SINK_PAD(obj) (((GstBaseVideoCodec *) (obj))->sinkpad) - -/** - * GST_BASE_VIDEO_CODEC_FLOW_NEED_DATA: - * - */ -#define GST_BASE_VIDEO_CODEC_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS - -typedef struct _GstBaseVideoCodec GstBaseVideoCodec; -typedef struct _GstBaseVideoCodecClass GstBaseVideoCodecClass; - -struct _GstBaseVideoCodec -{ - GstElement element; - - /*< private >*/ - GstPad *sinkpad; - GstPad *srcpad; - GstAdapter *input_adapter; - GstAdapter *output_adapter; - -#if 0 - /* FIXME need to move from subclasses */ - GstVideoState state; -#endif - - //int reorder_depth; - - //gboolean have_sync; - //gboolean discont; - //gboolean started; - - //GstVideoFrame *current_frame; - //int distance_from_sync; - - //gboolean sink_clipping; - - //guint64 presentation_frame_number; - guint64 system_frame_number; - - //GstCaps *caps; - //gboolean set_output_caps; - - //GstClockTime buffer_timestamp; - - GstClockTime timestamp_offset; -}; - -struct _GstBaseVideoCodecClass -{ - GstElementClass element_class; - - gboolean (*start) (GstBaseVideoCodec *codec); - gboolean (*stop) (GstBaseVideoCodec *codec); - gboolean (*reset) (GstBaseVideoCodec *codec); - GstFlowReturn (*parse_data) (GstBaseVideoCodec *codec, gboolean at_eos); - int (*scan_for_sync) (GstAdapter *adapter, gboolean at_eos, - int offset, int n); - GstFlowReturn (*shape_output) (GstBaseVideoCodec *codec, GstVideoFrame *frame); - GstCaps *(*get_caps) (GstBaseVideoCodec *codec); - -}; - -GType gst_base_video_codec_get_type (void); - -#if 0 -guint64 gst_base_video_codec_get_timestamp (GstBaseVideoCodec *codec, - int picture_number); -#endif - -GstVideoFrame * gst_base_video_codec_new_frame (GstBaseVideoCodec *base_video_codec); -void gst_base_video_codec_free_frame (GstVideoFrame *frame); - - -G_END_DECLS - -#endif - diff --git a/gst-libs/gst/video/gstbasevideodecoder.c b/gst-libs/gst/video/gstbasevideodecoder.c deleted file mode 100644 index a66446fb0f..0000000000 --- a/gst-libs/gst/video/gstbasevideodecoder.c +++ /dev/null @@ -1,1522 +0,0 @@ -/* GStreamer - * Copyright (C) 2008 David Schleef - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstbasevideodecoder.h" - -#include - -GST_DEBUG_CATEGORY (basevideodecoder_debug); -#define GST_CAT_DEFAULT basevideodecoder_debug - -static void gst_base_video_decoder_finalize (GObject * object); - -static gboolean gst_base_video_decoder_sink_setcaps (GstPad * pad, - GstCaps * caps); -static gboolean gst_base_video_decoder_sink_event (GstPad * pad, - GstEvent * event); -static gboolean gst_base_video_decoder_src_event (GstPad * pad, - GstEvent * event); -static GstFlowReturn gst_base_video_decoder_chain (GstPad * pad, - GstBuffer * buf); -static gboolean gst_base_video_decoder_sink_query (GstPad * pad, - GstQuery * query); -//static GstFlowReturn gst_base_video_decoder_process (GstBaseVideoDecoder *base_video_decoder); -static GstStateChangeReturn gst_base_video_decoder_change_state (GstElement * - element, GstStateChange transition); -static const GstQueryType *gst_base_video_decoder_get_query_types (GstPad * - pad); -static gboolean gst_base_video_decoder_src_query (GstPad * pad, - GstQuery * query); -static gboolean gst_base_video_decoder_src_convert (GstPad * pad, - GstFormat src_format, gint64 src_value, GstFormat * dest_format, - gint64 * dest_value); -static void gst_base_video_decoder_reset (GstBaseVideoDecoder * - base_video_decoder); - -static GstFlowReturn -gst_base_video_decoder_have_frame_2 (GstBaseVideoDecoder * base_video_decoder); - -static guint64 -gst_base_video_decoder_get_timestamp (GstBaseVideoDecoder * base_video_decoder, - int picture_number); -static guint64 -gst_base_video_decoder_get_field_timestamp (GstBaseVideoDecoder * - base_video_decoder, int field_offset); -static guint64 gst_base_video_decoder_get_field_duration (GstBaseVideoDecoder * - base_video_decoder, int n_fields); -static GstVideoFrame *gst_base_video_decoder_new_frame (GstBaseVideoDecoder * - base_video_decoder); -static void gst_base_video_decoder_free_frame (GstVideoFrame * frame); - -GST_BOILERPLATE (GstBaseVideoDecoder, gst_base_video_decoder, - GstBaseVideoCodec, GST_TYPE_BASE_VIDEO_CODEC); - -static void -gst_base_video_decoder_base_init (gpointer g_class) -{ - GST_DEBUG_CATEGORY_INIT (basevideodecoder_debug, "basevideodecoder", 0, - "Base Video Decoder"); - -} - -static void -gst_base_video_decoder_class_init (GstBaseVideoDecoderClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = G_OBJECT_CLASS (klass); - gstelement_class = GST_ELEMENT_CLASS (klass); - - gobject_class->finalize = gst_base_video_decoder_finalize; - - gstelement_class->change_state = gst_base_video_decoder_change_state; - - parent_class = g_type_class_peek_parent (klass); -} - -static void -gst_base_video_decoder_init (GstBaseVideoDecoder * base_video_decoder, - GstBaseVideoDecoderClass * klass) -{ - GstPad *pad; - - GST_DEBUG ("gst_base_video_decoder_init"); - - pad = GST_BASE_VIDEO_CODEC_SINK_PAD (base_video_decoder); - - gst_pad_set_chain_function (pad, gst_base_video_decoder_chain); - gst_pad_set_event_function (pad, gst_base_video_decoder_sink_event); - gst_pad_set_setcaps_function (pad, gst_base_video_decoder_sink_setcaps); - gst_pad_set_query_function (pad, gst_base_video_decoder_sink_query); - - pad = GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder); - - gst_pad_set_event_function (pad, gst_base_video_decoder_src_event); - gst_pad_set_query_type_function (pad, gst_base_video_decoder_get_query_types); - gst_pad_set_query_function (pad, gst_base_video_decoder_src_query); - gst_pad_use_fixed_caps (pad); - - base_video_decoder->input_adapter = gst_adapter_new (); - base_video_decoder->output_adapter = gst_adapter_new (); - - gst_segment_init (&base_video_decoder->segment, GST_FORMAT_TIME); - gst_base_video_decoder_reset (base_video_decoder); - - base_video_decoder->current_frame = - gst_base_video_decoder_new_frame (base_video_decoder); - - base_video_decoder->sink_clipping = TRUE; -} - -static gboolean -gst_base_video_decoder_sink_setcaps (GstPad * pad, GstCaps * caps) -{ - GstBaseVideoDecoder *base_video_decoder; - GstBaseVideoDecoderClass *base_video_decoder_class; - GstStructure *structure; - const GValue *codec_data; - GstVideoState *state; - gboolean ret = TRUE; - - base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - GST_DEBUG ("setcaps %" GST_PTR_FORMAT, caps); - - state = &base_video_decoder->state; - - if (state->codec_data) - gst_buffer_unref (state->codec_data); - memset (state, 0, sizeof (GstVideoState)); - - structure = gst_caps_get_structure (caps, 0); - - gst_structure_get_int (structure, "width", &state->width); - gst_structure_get_int (structure, "height", &state->height); - - /* framerate default: 25 fps */ - if (!gst_structure_get_fraction (structure, "framerate", - &state->fps_n, &state->fps_d)) { - state->fps_n = 25; - state->fps_d = 1; - } - - /* pixel-aspect-ratio default: 1/1 */ - if (!gst_structure_get_fraction (structure, "pixel-aspect-ratio", - &state->par_n, &state->par_d)) { - state->par_n = 1; - state->par_d = 1; - } - - state->have_interlaced = gst_structure_get_boolean (structure, - "interlaced", &state->interlaced); - - codec_data = gst_structure_get_value (structure, "codec_data"); - if (codec_data && G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) { - state->codec_data = gst_value_get_buffer (codec_data); - } - - if (base_video_decoder_class->start) { - ret = base_video_decoder_class->start (base_video_decoder); - } - - g_object_unref (base_video_decoder); - - return ret; -} - -static void -gst_base_video_decoder_finalize (GObject * object) -{ - GstBaseVideoDecoder *base_video_decoder; - GstBaseVideoDecoderClass *base_video_decoder_class; - - g_return_if_fail (GST_IS_BASE_VIDEO_DECODER (object)); - base_video_decoder = GST_BASE_VIDEO_DECODER (object); - base_video_decoder_class = GST_BASE_VIDEO_DECODER_GET_CLASS (object); - - gst_base_video_decoder_reset (base_video_decoder); - - if (base_video_decoder->input_adapter) { - g_object_unref (base_video_decoder->input_adapter); - base_video_decoder->input_adapter = NULL; - } - if (base_video_decoder->output_adapter) { - g_object_unref (base_video_decoder->output_adapter); - base_video_decoder->output_adapter = NULL; - } - - GST_DEBUG_OBJECT (object, "finalize"); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static gboolean -gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event) -{ - GstBaseVideoDecoder *base_video_decoder; - GstBaseVideoDecoderClass *base_video_decoder_class; - gboolean ret = FALSE; - - base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - { - if (!base_video_decoder->packetized) { - GstFlowReturn flow_ret; - - do { - flow_ret = - base_video_decoder_class->parse_data (base_video_decoder, TRUE); - } while (flow_ret == GST_FLOW_OK); - } - - if (base_video_decoder_class->finish) { - base_video_decoder_class->finish (base_video_decoder); - } - - ret = - gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), - event); - } - break; - case GST_EVENT_NEWSEGMENT: - { - gboolean update; - double rate; - double applied_rate; - GstFormat format; - gint64 start; - gint64 stop; - gint64 position; - GstSegment *segment = &base_video_decoder->segment; - - gst_event_parse_new_segment_full (event, &update, &rate, - &applied_rate, &format, &start, &stop, &position); - - if (format != GST_FORMAT_TIME) - goto newseg_wrong_format; - - if (!update) { - gst_base_video_decoder_reset (base_video_decoder); - } - - base_video_decoder->timestamp_offset = start; - - gst_segment_set_newsegment_full (segment, - update, rate, applied_rate, format, start, stop, position); - base_video_decoder->have_segment = TRUE; - - GST_DEBUG_OBJECT (base_video_decoder, - "new segment: format %d rate %g start %" GST_TIME_FORMAT - " stop %" GST_TIME_FORMAT - " position %" GST_TIME_FORMAT - " update %d", - format, rate, - GST_TIME_ARGS (segment->start), - GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time), update); - - ret = - gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), - event); - } - break; - case GST_EVENT_FLUSH_STOP:{ - GST_OBJECT_LOCK (base_video_decoder); - base_video_decoder->earliest_time = GST_CLOCK_TIME_NONE; - base_video_decoder->proportion = 0.5; - GST_OBJECT_UNLOCK (base_video_decoder); - } - default: - /* FIXME this changes the order of events */ - ret = - gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), - event); - break; - } - -done: - gst_object_unref (base_video_decoder); - return ret; - -newseg_wrong_format: - { - GST_DEBUG_OBJECT (base_video_decoder, "received non TIME newsegment"); - gst_event_unref (event); - goto done; - } -} - -static gboolean -gst_base_video_decoder_src_event (GstPad * pad, GstEvent * event) -{ - GstBaseVideoDecoder *base_video_decoder; - gboolean res = FALSE; - - base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - { - GstFormat format, tformat; - gdouble rate; - GstEvent *real_seek; - GstSeekFlags flags; - GstSeekType cur_type, stop_type; - gint64 cur, stop; - gint64 tcur, tstop; - - GST_DEBUG ("seek event"); - - gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, - &cur, &stop_type, &stop); - gst_event_unref (event); - - tformat = GST_FORMAT_TIME; - res = - gst_base_video_decoder_src_convert (pad, format, cur, &tformat, - &tcur); - if (!res) - goto convert_error; - res = - gst_base_video_decoder_src_convert (pad, format, stop, &tformat, - &tstop); - if (!res) - goto convert_error; - - real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME, - flags, cur_type, tcur, stop_type, tstop); - - res = - gst_pad_push_event (GST_BASE_VIDEO_CODEC_SINK_PAD - (base_video_decoder), real_seek); - - break; - } - case GST_EVENT_QOS: - { - gdouble proportion; - GstClockTimeDiff diff; - GstClockTime timestamp; - GstClockTime duration; - - gst_event_parse_qos (event, &proportion, &diff, ×tamp); - - GST_OBJECT_LOCK (base_video_decoder); - base_video_decoder->proportion = proportion; - if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) { - if (G_UNLIKELY (diff > 0)) { - if (base_video_decoder->state.fps_n > 0) - duration = - gst_util_uint64_scale (GST_SECOND, - base_video_decoder->state.fps_d, - base_video_decoder->state.fps_n); - else - duration = 0; - base_video_decoder->earliest_time = timestamp + 2 * diff + duration; - } else { - base_video_decoder->earliest_time = timestamp + diff; - } - } else { - base_video_decoder->earliest_time = GST_CLOCK_TIME_NONE; - } - GST_OBJECT_UNLOCK (base_video_decoder); - - GST_DEBUG_OBJECT (base_video_decoder, - "got QoS %" GST_TIME_FORMAT ", %" G_GINT64_FORMAT ", %g", - GST_TIME_ARGS (timestamp), diff, proportion); - - res = - gst_pad_push_event (GST_BASE_VIDEO_CODEC_SINK_PAD - (base_video_decoder), event); - break; - } - default: - res = - gst_pad_push_event (GST_BASE_VIDEO_CODEC_SINK_PAD - (base_video_decoder), event); - break; - } -done: - gst_object_unref (base_video_decoder); - return res; - -convert_error: - GST_DEBUG_OBJECT (base_video_decoder, "could not convert format"); - goto done; -} - - -#if 0 -static gboolean -gst_base_video_decoder_sink_convert (GstPad * pad, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - gboolean res = TRUE; - GstBaseVideoDecoder *enc; - - if (src_format == *dest_format) { - *dest_value = src_value; - return TRUE; - } - - enc = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - - /* FIXME: check if we are in a decoding state */ - - switch (src_format) { - case GST_FORMAT_BYTES: - switch (*dest_format) { -#if 0 - case GST_FORMAT_DEFAULT: - *dest_value = gst_util_uint64_scale_int (src_value, 1, - enc->bytes_per_picture); - break; -#endif - case GST_FORMAT_TIME: - /* seems like a rather silly conversion, implement me if you like */ - default: - res = FALSE; - } - break; - case GST_FORMAT_DEFAULT: - switch (*dest_format) { - case GST_FORMAT_TIME: - *dest_value = gst_util_uint64_scale (src_value, - GST_SECOND * enc->fps_d, enc->fps_n); - break; -#if 0 - case GST_FORMAT_BYTES: - *dest_value = gst_util_uint64_scale_int (src_value, - enc->bytes_per_picture, 1); - break; -#endif - default: - res = FALSE; - } - break; - default: - res = FALSE; - break; - } -} -#endif - -static gboolean -gst_base_video_decoder_src_convert (GstPad * pad, - GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - gboolean res = TRUE; - GstBaseVideoDecoder *enc; - - if (src_format == *dest_format) { - *dest_value = src_value; - return TRUE; - } - - enc = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - - /* FIXME: check if we are in a encoding state */ - - GST_DEBUG ("src convert"); - switch (src_format) { -#if 0 - case GST_FORMAT_DEFAULT: - switch (*dest_format) { - case GST_FORMAT_TIME: - *dest_value = gst_util_uint64_scale (granulepos_to_frame (src_value), - enc->fps_d * GST_SECOND, enc->fps_n); - break; - default: - res = FALSE; - } - break; - case GST_FORMAT_TIME: - switch (*dest_format) { - case GST_FORMAT_DEFAULT: - { - *dest_value = gst_util_uint64_scale (src_value, - enc->fps_n, enc->fps_d * GST_SECOND); - break; - } - default: - res = FALSE; - break; - } - break; -#endif - default: - res = FALSE; - break; - } - - gst_object_unref (enc); - - return res; -} - -static const GstQueryType * -gst_base_video_decoder_get_query_types (GstPad * pad) -{ - static const GstQueryType query_types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - GST_QUERY_CONVERT, - 0 - }; - - return query_types; -} - -static gboolean -gst_base_video_decoder_src_query (GstPad * pad, GstQuery * query) -{ - GstBaseVideoDecoder *enc; - gboolean res = TRUE; - - enc = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - - switch GST_QUERY_TYPE - (query) { - case GST_QUERY_POSITION: - { - GstFormat format; - gint64 time; - - gst_query_parse_position (query, &format, NULL); - GST_DEBUG ("query in format %d", format); - - if (format != GST_FORMAT_TIME) { - goto error; - } - - time = enc->last_timestamp; - time = gst_segment_to_stream_time (&enc->segment, GST_FORMAT_TIME, time); - - gst_query_set_position (query, format, time); - - res = TRUE; - - break; - } - case GST_QUERY_DURATION: - { - res = gst_pad_peer_query (enc->base_video_codec.sinkpad, query); - break; - } - case GST_QUERY_CONVERT: - { - GstFormat src_fmt, dest_fmt; - gint64 src_val, dest_val; - - GST_DEBUG ("convert query"); - - gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); - res = - gst_base_video_decoder_src_convert (pad, src_fmt, src_val, &dest_fmt, - &dest_val); - if (!res) - goto error; - gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); - break; - } - default: - res = gst_pad_query_default (pad, query); - } - gst_object_unref (enc); - return res; - -error: - GST_ERROR_OBJECT (enc, "query failed"); - gst_object_unref (enc); - return res; -} - -static gboolean -gst_base_video_decoder_sink_query (GstPad * pad, GstQuery * query) -{ - GstBaseVideoDecoder *base_video_decoder; - gboolean res = FALSE; - - base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (base_video_decoder, "sink query fps=%d/%d", - base_video_decoder->state.fps_n, base_video_decoder->state.fps_d); - switch (GST_QUERY_TYPE (query)) { - default: - res = gst_pad_query_default (pad, query); - break; - } -done: - gst_object_unref (base_video_decoder); - - return res; -error: - GST_DEBUG_OBJECT (base_video_decoder, "query failed"); - goto done; -} - - -#if 0 -static gboolean -gst_pad_is_negotiated (GstPad * pad) -{ - GstCaps *caps; - - g_return_val_if_fail (pad != NULL, FALSE); - - caps = gst_pad_get_negotiated_caps (pad); - if (caps) { - gst_caps_unref (caps); - return TRUE; - } - - return FALSE; -} -#endif - -typedef struct _Timestamp Timestamp; -struct _Timestamp -{ - guint64 offset; - GstClockTime timestamp; - GstClockTime duration; -}; - -static void -gst_base_video_decoder_add_timestamp (GstBaseVideoDecoder * base_video_decoder, - GstBuffer * buffer) -{ - Timestamp *ts; - - ts = g_malloc (sizeof (Timestamp)); - - GST_DEBUG ("adding timestamp %" GST_TIME_FORMAT " %" GST_TIME_FORMAT, - GST_TIME_ARGS (base_video_decoder->input_offset), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); - - ts->offset = base_video_decoder->input_offset; - ts->timestamp = GST_BUFFER_TIMESTAMP (buffer); - ts->duration = GST_BUFFER_DURATION (buffer); - - base_video_decoder->timestamps = - g_list_append (base_video_decoder->timestamps, ts); -} - -static void -gst_base_video_decoder_get_timestamp_at_offset (GstBaseVideoDecoder * - base_video_decoder, guint64 offset, GstClockTime * timestamp, - GstClockTime * duration) -{ - Timestamp *ts; - GList *g; - - *timestamp = GST_CLOCK_TIME_NONE; - *duration = GST_CLOCK_TIME_NONE; - - g = base_video_decoder->timestamps; - while (g) { - ts = g->data; - if (ts->offset <= offset) { - *timestamp = ts->timestamp; - *duration = ts->duration; - g_free (ts); - g = g_list_next (g); - base_video_decoder->timestamps = - g_list_remove (base_video_decoder->timestamps, ts); - } else { - break; - } - } - - GST_DEBUG ("got timestamp %" GST_TIME_FORMAT " %" GST_TIME_FORMAT, - GST_TIME_ARGS (offset), GST_TIME_ARGS (*timestamp)); -} - -static void -gst_base_video_decoder_reset (GstBaseVideoDecoder * base_video_decoder) -{ - GstBaseVideoDecoderClass *base_video_decoder_class; - GList *g; - - base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - GST_DEBUG ("reset"); - - base_video_decoder->started = FALSE; - - base_video_decoder->discont = TRUE; - base_video_decoder->have_sync = FALSE; - - base_video_decoder->timestamp_offset = GST_CLOCK_TIME_NONE; - base_video_decoder->system_frame_number = 0; - base_video_decoder->presentation_frame_number = 0; - base_video_decoder->base_picture_number = 0; - base_video_decoder->last_timestamp = GST_CLOCK_TIME_NONE; - - base_video_decoder->input_offset = 0; - base_video_decoder->frame_offset = 0; - - /* This function could be called from finalize() */ - if (base_video_decoder->input_adapter) { - gst_adapter_clear (base_video_decoder->input_adapter); - } - if (base_video_decoder->output_adapter) { - gst_adapter_clear (base_video_decoder->output_adapter); - } - - if (base_video_decoder->caps) { - gst_caps_unref (base_video_decoder->caps); - base_video_decoder->caps = NULL; - } - //gst_segment_init (&base_video_decoder->segment, GST_FORMAT_TIME); - - if (base_video_decoder->current_frame) { - gst_base_video_decoder_free_frame (base_video_decoder->current_frame); - base_video_decoder->current_frame = NULL; - } - - base_video_decoder->have_src_caps = FALSE; - - for (g = g_list_first (base_video_decoder->frames); g; g = g_list_next (g)) { - GstVideoFrame *frame = g->data; - gst_base_video_decoder_free_frame (frame); - } - g_list_free (base_video_decoder->frames); - base_video_decoder->frames = NULL; - - GST_OBJECT_LOCK (base_video_decoder); - base_video_decoder->earliest_time = GST_CLOCK_TIME_NONE; - base_video_decoder->proportion = 0.5; - GST_OBJECT_UNLOCK (base_video_decoder); - - if (base_video_decoder_class->reset) { - base_video_decoder_class->reset (base_video_decoder); - } -} - -static GstFlowReturn -gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf) -{ - GstBaseVideoDecoder *base_video_decoder; - GstBaseVideoDecoderClass *klass; - GstFlowReturn ret; - - GST_DEBUG ("chain %" GST_TIME_FORMAT " duration %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), - GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); - -#if 0 - /* requiring the pad to be negotiated makes it impossible to use - * oggdemux or filesrc ! decoder */ - if (!gst_pad_is_negotiated (pad)) { - GST_DEBUG ("not negotiated"); - return GST_FLOW_NOT_NEGOTIATED; - } -#endif - - base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - klass = GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - GST_DEBUG_OBJECT (base_video_decoder, "chain"); - - if (!base_video_decoder->have_segment) { - GstEvent *event; - GstFlowReturn ret; - - GST_WARNING - ("Received buffer without a new-segment. Assuming timestamps start from 0."); - - gst_segment_set_newsegment_full (&base_video_decoder->segment, - FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0, GST_CLOCK_TIME_NONE, 0); - base_video_decoder->have_segment = TRUE; - - event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, - GST_CLOCK_TIME_NONE, 0); - - ret = - gst_pad_push_event (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), - event); - if (!ret) { - GST_ERROR ("new segment event ret=%d", ret); - return GST_FLOW_ERROR; - } - } - - if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) { - GST_DEBUG_OBJECT (base_video_decoder, "received DISCONT buffer"); - gst_base_video_decoder_reset (base_video_decoder); - } - - if (!base_video_decoder->started) { - klass->start (base_video_decoder); - base_video_decoder->started = TRUE; - } - - if (base_video_decoder->current_frame == NULL) { - base_video_decoder->current_frame = - gst_base_video_decoder_new_frame (base_video_decoder); - } - - if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { - gst_base_video_decoder_add_timestamp (base_video_decoder, buf); - } - base_video_decoder->input_offset += GST_BUFFER_SIZE (buf); - -#if 0 - if (base_video_decoder->timestamp_offset == GST_CLOCK_TIME_NONE && - GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE) { - GST_DEBUG ("got new offset %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); - base_video_decoder->timestamp_offset = GST_BUFFER_TIMESTAMP (buf); - } -#endif - - if (base_video_decoder->packetized) { - base_video_decoder->current_frame->sink_buffer = buf; - - ret = gst_base_video_decoder_have_frame_2 (base_video_decoder); - } else { - - gst_adapter_push (base_video_decoder->input_adapter, buf); - - if (!base_video_decoder->have_sync) { - int n, m; - - GST_DEBUG ("no sync, scanning"); - - n = gst_adapter_available (base_video_decoder->input_adapter); - m = klass->scan_for_sync (base_video_decoder, FALSE, 0, n); - if (m == -1) { - gst_object_unref (base_video_decoder); - return GST_FLOW_OK; - } - - if (m < 0) { - g_warning ("subclass returned negative scan %d", m); - } - - if (m >= n) { - GST_ERROR ("subclass scanned past end %d >= %d", m, n); - } - - gst_adapter_flush (base_video_decoder->input_adapter, m); - - if (m < n) { - GST_DEBUG ("found possible sync after %d bytes (of %d)", m, n); - - /* this is only "maybe" sync */ - base_video_decoder->have_sync = TRUE; - } - - if (!base_video_decoder->have_sync) { - gst_object_unref (base_video_decoder); - return GST_FLOW_OK; - } - } - - do { - ret = klass->parse_data (base_video_decoder, FALSE); - } while (ret == GST_FLOW_OK); - - if (ret == GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA) { - gst_object_unref (base_video_decoder); - return GST_FLOW_OK; - } - } - - gst_object_unref (base_video_decoder); - return ret; -} - -static GstStateChangeReturn -gst_base_video_decoder_change_state (GstElement * element, - GstStateChange transition) -{ - GstBaseVideoDecoder *base_video_decoder; - GstBaseVideoDecoderClass *base_video_decoder_class; - GstStateChangeReturn ret; - - base_video_decoder = GST_BASE_VIDEO_DECODER (element); - base_video_decoder_class = GST_BASE_VIDEO_DECODER_GET_CLASS (element); - - switch (transition) { - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - if (base_video_decoder_class->stop) { - base_video_decoder_class->stop (base_video_decoder); - } - break; - default: - break; - } - - return ret; -} - -static void -gst_base_video_decoder_free_frame (GstVideoFrame * frame) -{ - g_return_if_fail (frame != NULL); - - if (frame->sink_buffer) { - gst_buffer_unref (frame->sink_buffer); - } - if (frame->src_buffer) { - gst_buffer_unref (frame->src_buffer); - } - - g_free (frame); -} - -static GstVideoFrame * -gst_base_video_decoder_new_frame (GstBaseVideoDecoder * base_video_decoder) -{ - GstVideoFrame *frame; - - frame = g_malloc0 (sizeof (GstVideoFrame)); - - frame->system_frame_number = base_video_decoder->system_frame_number; - base_video_decoder->system_frame_number++; - - frame->decode_frame_number = frame->system_frame_number - - base_video_decoder->reorder_depth; - - frame->decode_timestamp = GST_CLOCK_TIME_NONE; - frame->presentation_timestamp = GST_CLOCK_TIME_NONE; - frame->presentation_duration = GST_CLOCK_TIME_NONE; - frame->n_fields = 2; - - return frame; -} - -GstFlowReturn -gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder, - GstVideoFrame * frame) -{ - GstBaseVideoDecoderClass *base_video_decoder_class; - GstBuffer *src_buffer; - - GST_DEBUG ("finish frame"); - - base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - GST_DEBUG ("finish frame sync=%d pts=%" GST_TIME_FORMAT, frame->is_sync_point, - GST_TIME_ARGS (frame->presentation_timestamp)); - - if (GST_CLOCK_TIME_IS_VALID (frame->presentation_timestamp)) { - if (frame->presentation_timestamp != base_video_decoder->timestamp_offset) { - GST_DEBUG ("sync timestamp %" GST_TIME_FORMAT " diff %" GST_TIME_FORMAT, - GST_TIME_ARGS (frame->presentation_timestamp), - GST_TIME_ARGS (frame->presentation_timestamp - - base_video_decoder->segment.start)); - base_video_decoder->timestamp_offset = frame->presentation_timestamp; - base_video_decoder->field_index = 0; - } else { - /* This case is for one initial timestamp and no others, e.g., - * filesrc ! decoder ! xvimagesink */ - GST_WARNING ("sync timestamp didn't change, ignoring"); - frame->presentation_timestamp = GST_CLOCK_TIME_NONE; - } - } else { - if (frame->is_sync_point) { - GST_WARNING ("sync point doesn't have timestamp"); - if (!GST_CLOCK_TIME_IS_VALID (base_video_decoder->timestamp_offset)) { - GST_WARNING - ("No base timestamp. Assuming frames start at segment start"); - base_video_decoder->timestamp_offset = - base_video_decoder->segment.start; - base_video_decoder->field_index = 0; - } - } - } - frame->field_index = base_video_decoder->field_index; - base_video_decoder->field_index += frame->n_fields; - - if (frame->presentation_timestamp == GST_CLOCK_TIME_NONE) { - frame->presentation_timestamp = - gst_base_video_decoder_get_field_timestamp (base_video_decoder, - frame->field_index); - frame->presentation_duration = GST_CLOCK_TIME_NONE; - frame->decode_timestamp = - gst_base_video_decoder_get_timestamp (base_video_decoder, - frame->decode_frame_number); - } - if (frame->presentation_duration == GST_CLOCK_TIME_NONE) { - frame->presentation_duration = - gst_base_video_decoder_get_field_duration (base_video_decoder, - frame->n_fields); - } - - if (GST_CLOCK_TIME_IS_VALID (base_video_decoder->last_timestamp)) { - if (frame->presentation_timestamp < base_video_decoder->last_timestamp) { - GST_WARNING ("decreasing timestamp (%" GST_TIME_FORMAT " < %" - GST_TIME_FORMAT ")", GST_TIME_ARGS (frame->presentation_timestamp), - GST_TIME_ARGS (base_video_decoder->last_timestamp)); - } - } - base_video_decoder->last_timestamp = frame->presentation_timestamp; - - GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_BUFFER_FLAG_DELTA_UNIT); - if (base_video_decoder->state.interlaced) { -#ifndef GST_VIDEO_BUFFER_TFF -#define GST_VIDEO_BUFFER_TFF (GST_MINI_OBJECT_FLAG_LAST << 5) -#endif -#ifndef GST_VIDEO_BUFFER_RFF -#define GST_VIDEO_BUFFER_RFF (GST_MINI_OBJECT_FLAG_LAST << 6) -#endif -#ifndef GST_VIDEO_BUFFER_ONEFIELD -#define GST_VIDEO_BUFFER_ONEFIELD (GST_MINI_OBJECT_FLAG_LAST << 7) -#endif - int tff = base_video_decoder->state.top_field_first; - - if (frame->field_index & 1) { - tff ^= 1; - } - if (tff) { - GST_BUFFER_FLAG_SET (frame->src_buffer, GST_VIDEO_BUFFER_TFF); - } else { - GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_VIDEO_BUFFER_TFF); - } - GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_VIDEO_BUFFER_RFF); - GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_VIDEO_BUFFER_ONEFIELD); - if (frame->n_fields == 3) { - GST_BUFFER_FLAG_SET (frame->src_buffer, GST_VIDEO_BUFFER_RFF); - } else if (frame->n_fields == 1) { - GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_VIDEO_BUFFER_ONEFIELD); - } - } - if (base_video_decoder->discont) { - GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_BUFFER_FLAG_DISCONT); - base_video_decoder->discont = FALSE; - } - - GST_BUFFER_TIMESTAMP (frame->src_buffer) = frame->presentation_timestamp; - GST_BUFFER_DURATION (frame->src_buffer) = frame->presentation_duration; - GST_BUFFER_OFFSET (frame->src_buffer) = GST_BUFFER_OFFSET_NONE; - GST_BUFFER_OFFSET_END (frame->src_buffer) = GST_BUFFER_OFFSET_NONE; - - GST_DEBUG ("pushing frame %" GST_TIME_FORMAT, - GST_TIME_ARGS (frame->presentation_timestamp)); - - base_video_decoder->frames = - g_list_remove (base_video_decoder->frames, frame); - - gst_base_video_decoder_set_src_caps (base_video_decoder); - - src_buffer = frame->src_buffer; - frame->src_buffer = NULL; - - gst_base_video_decoder_free_frame (frame); - - if (base_video_decoder->sink_clipping) { - gint64 start = GST_BUFFER_TIMESTAMP (src_buffer); - gint64 stop = GST_BUFFER_TIMESTAMP (src_buffer) + - GST_BUFFER_DURATION (src_buffer); - - if (gst_segment_clip (&base_video_decoder->segment, GST_FORMAT_TIME, - start, stop, &start, &stop)) { - GST_BUFFER_TIMESTAMP (src_buffer) = start; - GST_BUFFER_DURATION (src_buffer) = stop - start; - GST_DEBUG ("accepting buffer inside segment: %" GST_TIME_FORMAT - " %" GST_TIME_FORMAT - " seg %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT - " time %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer)), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer) + - GST_BUFFER_DURATION (src_buffer)), - GST_TIME_ARGS (base_video_decoder->segment.start), - GST_TIME_ARGS (base_video_decoder->segment.stop), - GST_TIME_ARGS (base_video_decoder->segment.time)); - } else { - GST_DEBUG ("dropping buffer outside segment: %" GST_TIME_FORMAT - " %" GST_TIME_FORMAT - " seg %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT - " time %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer)), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer) + - GST_BUFFER_DURATION (src_buffer)), - GST_TIME_ARGS (base_video_decoder->segment.start), - GST_TIME_ARGS (base_video_decoder->segment.stop), - GST_TIME_ARGS (base_video_decoder->segment.time)); - gst_buffer_unref (src_buffer); - return GST_FLOW_OK; - } - } - - return gst_pad_push (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), - src_buffer); -} - -GstFlowReturn -gst_base_video_decoder_skip_frame (GstBaseVideoDecoder * base_video_decoder, - GstVideoFrame * frame) -{ - GstBaseVideoDecoderClass *base_video_decoder_class; - - GST_DEBUG ("finish frame"); - - base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - GST_DEBUG ("finish frame sync=%d pts=%" GST_TIME_FORMAT, frame->is_sync_point, - GST_TIME_ARGS (frame->presentation_timestamp)); - - if (GST_CLOCK_TIME_IS_VALID (frame->presentation_timestamp)) { - if (frame->presentation_timestamp != base_video_decoder->timestamp_offset) { - GST_DEBUG ("sync timestamp %" GST_TIME_FORMAT " diff %" GST_TIME_FORMAT, - GST_TIME_ARGS (frame->presentation_timestamp), - GST_TIME_ARGS (frame->presentation_timestamp - - base_video_decoder->segment.start)); - base_video_decoder->timestamp_offset = frame->presentation_timestamp; - base_video_decoder->field_index = 0; - } else { - /* This case is for one initial timestamp and no others, e.g., - * filesrc ! decoder ! xvimagesink */ - GST_WARNING ("sync timestamp didn't change, ignoring"); - frame->presentation_timestamp = GST_CLOCK_TIME_NONE; - } - } else { - if (frame->is_sync_point) { - GST_WARNING ("sync point doesn't have timestamp"); - if (GST_CLOCK_TIME_IS_VALID (base_video_decoder->timestamp_offset)) { - GST_WARNING - ("No base timestamp. Assuming frames start at segment start"); - base_video_decoder->timestamp_offset = - base_video_decoder->segment.start; - base_video_decoder->field_index = 0; - } - } - } - frame->field_index = base_video_decoder->field_index; - base_video_decoder->field_index += frame->n_fields; - - if (frame->presentation_timestamp == GST_CLOCK_TIME_NONE) { - frame->presentation_timestamp = - gst_base_video_decoder_get_field_timestamp (base_video_decoder, - frame->field_index); - frame->presentation_duration = GST_CLOCK_TIME_NONE; - frame->decode_timestamp = - gst_base_video_decoder_get_timestamp (base_video_decoder, - frame->decode_frame_number); - } - if (frame->presentation_duration == GST_CLOCK_TIME_NONE) { - frame->presentation_duration = - gst_base_video_decoder_get_field_duration (base_video_decoder, - frame->n_fields); - } - - base_video_decoder->last_timestamp = frame->presentation_timestamp; - - GST_DEBUG ("skipping frame %" GST_TIME_FORMAT, - GST_TIME_ARGS (frame->presentation_timestamp)); - - base_video_decoder->frames = - g_list_remove (base_video_decoder->frames, frame); - - gst_base_video_decoder_free_frame (frame); - - return GST_FLOW_OK; -} - -int -gst_base_video_decoder_get_height (GstBaseVideoDecoder * base_video_decoder) -{ - return base_video_decoder->state.height; -} - -int -gst_base_video_decoder_get_width (GstBaseVideoDecoder * base_video_decoder) -{ - return base_video_decoder->state.width; -} - -GstFlowReturn -gst_base_video_decoder_end_of_stream (GstBaseVideoDecoder * base_video_decoder, - GstBuffer * buffer) -{ - - if (base_video_decoder->frames) { - GST_DEBUG ("EOS with frames left over"); - } - - return gst_pad_push (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), - buffer); -} - -void -gst_base_video_decoder_add_to_frame (GstBaseVideoDecoder * base_video_decoder, - int n_bytes) -{ - GstBuffer *buf; - - GST_DEBUG ("add to frame"); - - if (n_bytes == 0) - return; - - if (gst_adapter_available (base_video_decoder->output_adapter) == 0) { - base_video_decoder->frame_offset = base_video_decoder->input_offset - - gst_adapter_available (base_video_decoder->input_adapter); - } - buf = gst_adapter_take_buffer (base_video_decoder->input_adapter, n_bytes); - - gst_adapter_push (base_video_decoder->output_adapter, buf); -} - -static guint64 -gst_base_video_decoder_get_timestamp (GstBaseVideoDecoder * base_video_decoder, - int picture_number) -{ - if (base_video_decoder->state.fps_d == 0) { - return -1; - } - if (picture_number < base_video_decoder->base_picture_number) { - return base_video_decoder->timestamp_offset - - (gint64) gst_util_uint64_scale (base_video_decoder->base_picture_number - - picture_number, base_video_decoder->state.fps_d * GST_SECOND, - base_video_decoder->state.fps_n); - } else { - return base_video_decoder->timestamp_offset + - gst_util_uint64_scale (picture_number - - base_video_decoder->base_picture_number, - base_video_decoder->state.fps_d * GST_SECOND, - base_video_decoder->state.fps_n); - } -} - -static guint64 -gst_base_video_decoder_get_field_timestamp (GstBaseVideoDecoder * - base_video_decoder, int field_offset) -{ - if (base_video_decoder->state.fps_d == 0) { - return GST_CLOCK_TIME_NONE; - } - if (field_offset < 0) { - GST_WARNING ("field offset < 0"); - return GST_CLOCK_TIME_NONE; - } - return base_video_decoder->timestamp_offset + - gst_util_uint64_scale (field_offset, - base_video_decoder->state.fps_d * GST_SECOND, - base_video_decoder->state.fps_n * 2); -} - -static guint64 -gst_base_video_decoder_get_field_duration (GstBaseVideoDecoder * - base_video_decoder, int n_fields) -{ - if (base_video_decoder->state.fps_d == 0) { - return GST_CLOCK_TIME_NONE; - } - if (n_fields < 0) { - GST_WARNING ("n_fields < 0"); - return GST_CLOCK_TIME_NONE; - } - return gst_util_uint64_scale (n_fields, - base_video_decoder->state.fps_d * GST_SECOND, - base_video_decoder->state.fps_n * 2); -} - - -GstFlowReturn -gst_base_video_decoder_have_frame (GstBaseVideoDecoder * base_video_decoder) -{ - GstBuffer *buffer; - int n_available; - GstClockTime timestamp; - GstClockTime duration; - - GST_DEBUG ("have_frame"); - - n_available = gst_adapter_available (base_video_decoder->output_adapter); - if (n_available) { - buffer = gst_adapter_take_buffer (base_video_decoder->output_adapter, - n_available); - } else { - buffer = gst_buffer_new_and_alloc (0); - } - - base_video_decoder->current_frame->sink_buffer = buffer; - - gst_base_video_decoder_get_timestamp_at_offset (base_video_decoder, - base_video_decoder->frame_offset, ×tamp, &duration); - - GST_BUFFER_TIMESTAMP (buffer) = timestamp; - GST_BUFFER_DURATION (buffer) = duration; - - return gst_base_video_decoder_have_frame_2 (base_video_decoder); -} - -static GstFlowReturn -gst_base_video_decoder_have_frame_2 (GstBaseVideoDecoder * base_video_decoder) -{ - GstVideoFrame *frame = base_video_decoder->current_frame; - GstBaseVideoDecoderClass *base_video_decoder_class; - GstFlowReturn ret = GST_FLOW_OK; - GstClockTime running_time; - GstClockTimeDiff deadline; - - base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - frame->distance_from_sync = base_video_decoder->distance_from_sync; - base_video_decoder->distance_from_sync++; - - frame->presentation_timestamp = GST_BUFFER_TIMESTAMP (frame->sink_buffer); - frame->presentation_duration = GST_BUFFER_DURATION (frame->sink_buffer); - - GST_DEBUG ("pts %" GST_TIME_FORMAT, - GST_TIME_ARGS (frame->presentation_timestamp)); - GST_DEBUG ("dts %" GST_TIME_FORMAT, GST_TIME_ARGS (frame->decode_timestamp)); - GST_DEBUG ("dist %d", frame->distance_from_sync); - - base_video_decoder->frames = g_list_append (base_video_decoder->frames, - frame); - - running_time = gst_segment_to_running_time (&base_video_decoder->segment, - GST_FORMAT_TIME, frame->presentation_timestamp); - - if (GST_CLOCK_TIME_IS_VALID (base_video_decoder->earliest_time)) - deadline = GST_CLOCK_DIFF (base_video_decoder->earliest_time, running_time); - else - deadline = G_MAXINT64; - - /* do something with frame */ - ret = base_video_decoder_class->handle_frame (base_video_decoder, frame, - deadline); - if (!GST_FLOW_IS_SUCCESS (ret)) { - GST_DEBUG ("flow error!"); - } - - /* create new frame */ - base_video_decoder->current_frame = - gst_base_video_decoder_new_frame (base_video_decoder); - - return ret; -} - -GstVideoState * -gst_base_video_decoder_get_state (GstBaseVideoDecoder * base_video_decoder) -{ - return &base_video_decoder->state; - -} - -void -gst_base_video_decoder_set_state (GstBaseVideoDecoder * base_video_decoder, - GstVideoState * state) -{ - memcpy (&base_video_decoder->state, state, sizeof (*state)); - -} - -void -gst_base_video_decoder_lost_sync (GstBaseVideoDecoder * base_video_decoder) -{ - g_return_if_fail (GST_IS_BASE_VIDEO_DECODER (base_video_decoder)); - - GST_DEBUG ("lost_sync"); - - if (gst_adapter_available (base_video_decoder->input_adapter) >= 1) { - gst_adapter_flush (base_video_decoder->input_adapter, 1); - } - - base_video_decoder->have_sync = FALSE; -} - -void -gst_base_video_decoder_set_sync_point (GstBaseVideoDecoder * base_video_decoder) -{ - GST_DEBUG ("set_sync_point"); - - base_video_decoder->current_frame->is_sync_point = TRUE; - base_video_decoder->distance_from_sync = 0; -} - -GstVideoFrame * -gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder * - base_video_decoder) -{ - GList *g; - - g = g_list_first (base_video_decoder->frames); - - if (g == NULL) - return NULL; - return (GstVideoFrame *) (g->data); -} - -GstVideoFrame * -gst_base_video_decoder_get_frame (GstBaseVideoDecoder * base_video_decoder, - int frame_number) -{ - GList *g; - - for (g = g_list_first (base_video_decoder->frames); g; g = g_list_next (g)) { - GstVideoFrame *frame = g->data; - - if (frame->system_frame_number == frame_number) { - return frame; - } - } - - return NULL; -} - -void -gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder) -{ - GstCaps *caps; - GstVideoState *state = &base_video_decoder->state; - - if (base_video_decoder->have_src_caps) - return; - - caps = GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)); - if (caps) - caps = gst_caps_copy (caps); - else { - caps = gst_pad_get_allowed_caps - (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)); - if (!caps) - goto null_caps; - if (gst_caps_is_empty (caps)) - goto empty_caps; - } - - gst_caps_set_simple (caps, - "width", G_TYPE_INT, state->width, - "height", G_TYPE_INT, state->height, - "framerate", GST_TYPE_FRACTION, state->fps_n, state->fps_d, - "pixel-aspect-ratio", GST_TYPE_FRACTION, state->par_n, state->par_d, - NULL); - if (state->have_interlaced) - gst_caps_set_simple (caps, - "interlaced", G_TYPE_BOOLEAN, state->interlaced, NULL); - gst_pad_fixate_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), caps); - - GST_DEBUG ("setting caps %" GST_PTR_FORMAT, caps); - - gst_pad_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder), caps); - - base_video_decoder->have_src_caps = TRUE; - - gst_caps_unref (caps); - return; - -null_caps: - GST_WARNING ("Got null caps from get_allowed_caps"); - return; - -empty_caps: - GST_WARNING ("Got empty caps from get_allowed_caps"); - gst_caps_unref (caps); - return; -} - -void -gst_base_video_decoder_update_src_caps (GstBaseVideoDecoder * - base_video_decoder) -{ - g_return_if_fail (GST_IS_BASE_VIDEO_DECODER (base_video_decoder)); - - base_video_decoder->have_src_caps = FALSE; - gst_base_video_decoder_set_src_caps (base_video_decoder); -} - -GstFlowReturn -gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder * - base_video_decoder, GstVideoFrame * frame) -{ - GstFlowReturn flow_ret; - - gst_base_video_decoder_set_src_caps (base_video_decoder); - - flow_ret = - gst_pad_alloc_buffer_and_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD - (base_video_decoder), GST_BUFFER_OFFSET_NONE, 0, - GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_decoder)), - &frame->src_buffer); - - if (flow_ret != GST_FLOW_OK) { - GST_WARNING ("failed to get buffer"); - } - - return flow_ret; -} diff --git a/gst-libs/gst/video/gstbasevideodecoder.h b/gst-libs/gst/video/gstbasevideodecoder.h deleted file mode 100644 index 656eb40a6e..0000000000 --- a/gst-libs/gst/video/gstbasevideodecoder.h +++ /dev/null @@ -1,178 +0,0 @@ -/* GStreamer - * Copyright (C) 2008 David Schleef - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _GST_BASE_VIDEO_DECODER_H_ -#define _GST_BASE_VIDEO_DECODER_H_ - -#ifndef GST_USE_UNSTABLE_API -#warning "GstBaseVideoDecoder is unstable API and may change in future." -#warning "You can define GST_USE_UNSTABLE_API to avoid this warning." -#endif - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_BASE_VIDEO_DECODER \ - (gst_base_video_decoder_get_type()) -#define GST_BASE_VIDEO_DECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BASE_VIDEO_DECODER,GstBaseVideoDecoder)) -#define GST_BASE_VIDEO_DECODER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BASE_VIDEO_DECODER,GstBaseVideoDecoderClass)) -#define GST_BASE_VIDEO_DECODER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_BASE_VIDEO_DECODER,GstBaseVideoDecoderClass)) -#define GST_IS_BASE_VIDEO_DECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BASE_VIDEO_DECODER)) -#define GST_IS_BASE_VIDEO_DECODER_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_VIDEO_DECODER)) - -/** - * GST_BASE_VIDEO_DECODER_SINK_NAME: - * - * The name of the templates for the sink pad. - */ -#define GST_BASE_VIDEO_DECODER_SINK_NAME "sink" -/** - * GST_BASE_VIDEO_DECODER_SRC_NAME: - * - * The name of the templates for the source pad. - */ -#define GST_BASE_VIDEO_DECODER_SRC_NAME "src" - -/** - * * GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA: - * * - * */ -#define GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS - - -typedef struct _GstBaseVideoDecoder GstBaseVideoDecoder; -typedef struct _GstBaseVideoDecoderClass GstBaseVideoDecoderClass; - -struct _GstBaseVideoDecoder -{ - GstBaseVideoCodec base_video_codec; - - /*< private >*/ - GstAdapter *input_adapter; - GstAdapter *output_adapter; - - GList *frames; - - gboolean have_sync; - gboolean discont; - gboolean started; - - GstVideoState state; - GstSegment segment; - - gboolean sink_clipping; - - guint64 presentation_frame_number; - guint64 system_frame_number; - - GstCaps *caps; - gboolean have_src_caps; - - GstVideoFrame *current_frame; - - int distance_from_sync; - int reorder_depth; - - GstClockTime buffer_timestamp; - - GstClockTime timestamp_offset; - - gdouble proportion; - GstClockTime earliest_time; - - //GstBuffer *codec_data; - - guint64 input_offset; - guint64 frame_offset; - GstClockTime last_timestamp; - - guint64 base_picture_number; - - int field_index; - - gboolean is_delta_unit; - gboolean packetized; - - GList *timestamps; - gboolean have_segment; -}; - -struct _GstBaseVideoDecoderClass -{ - GstBaseVideoCodecClass base_video_codec_class; - - gboolean (*set_format) (GstBaseVideoDecoder *coder, GstVideoFormat, - int width, int height, int fps_n, int fps_d, - int par_n, int par_d); - gboolean (*start) (GstBaseVideoDecoder *coder); - gboolean (*stop) (GstBaseVideoDecoder *coder); - gboolean (*reset) (GstBaseVideoDecoder *coder); - int (*scan_for_sync) (GstBaseVideoDecoder *decoder, gboolean at_eos, - int offset, int n); - GstFlowReturn (*parse_data) (GstBaseVideoDecoder *decoder, gboolean at_eos); - GstFlowReturn (*finish) (GstBaseVideoDecoder *coder); - GstFlowReturn (*handle_frame) (GstBaseVideoDecoder *coder, GstVideoFrame *frame, - GstClockTimeDiff deadline); - GstFlowReturn (*shape_output) (GstBaseVideoDecoder *coder, GstVideoFrame *frame); - GstCaps *(*get_caps) (GstBaseVideoDecoder *coder); - -}; - -GType gst_base_video_decoder_get_type (void); - -int gst_base_video_decoder_get_width (GstBaseVideoDecoder *coder); -int gst_base_video_decoder_get_height (GstBaseVideoDecoder *coder); - -guint64 gst_base_video_decoder_get_timestamp_offset (GstBaseVideoDecoder *coder); - -GstVideoFrame *gst_base_video_decoder_get_frame (GstBaseVideoDecoder *coder, - int frame_number); -GstVideoFrame *gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder *coder); -void gst_base_video_decoder_add_to_frame (GstBaseVideoDecoder *base_video_decoder, - int n_bytes); -GstFlowReturn gst_base_video_decoder_finish_frame (GstBaseVideoDecoder *base_video_decoder, - GstVideoFrame *frame); -GstFlowReturn gst_base_video_decoder_skip_frame (GstBaseVideoDecoder * base_video_decoder, - GstVideoFrame * frame); -GstFlowReturn gst_base_video_decoder_end_of_stream (GstBaseVideoDecoder *base_video_decoder, - GstBuffer *buffer); -GstFlowReturn -gst_base_video_decoder_have_frame (GstBaseVideoDecoder *base_video_decoder); -GstVideoState * gst_base_video_decoder_get_state (GstBaseVideoDecoder *base_video_decoder); -void gst_base_video_decoder_set_state (GstBaseVideoDecoder *base_video_decoder, - GstVideoState *state); -void gst_base_video_decoder_lost_sync (GstBaseVideoDecoder *base_video_decoder); -void gst_base_video_decoder_set_sync_point (GstBaseVideoDecoder *base_video_decoder); - -void gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder *base_video_decoder); -void gst_base_video_decoder_update_src_caps (GstBaseVideoDecoder *base_video_decoder); - -GstFlowReturn gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder *base_video_decoder, - GstVideoFrame *frame); - -G_END_DECLS - -#endif - diff --git a/gst-libs/gst/video/gstbasevideoutils.c b/gst-libs/gst/video/gstbasevideoutils.c deleted file mode 100644 index 44f7dc0b70..0000000000 --- a/gst-libs/gst/video/gstbasevideoutils.c +++ /dev/null @@ -1,45 +0,0 @@ -/* GStreamer - * Copyright (C) 2008 David Schleef - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstbasevideoutils.h" - -#include - -GST_DEBUG_CATEGORY_EXTERN (basevideocodec_debug); -#define GST_CAT_DEFAULT basevideocodec_debug - - -GstClockTime -gst_video_state_get_timestamp (const GstVideoState * state, - GstSegment * segment, int frame_number) -{ - if (frame_number < 0) { - return segment->start - - (gint64) gst_util_uint64_scale (-frame_number, - state->fps_d * GST_SECOND, state->fps_n); - } else { - return segment->start + - gst_util_uint64_scale (frame_number, - state->fps_d * GST_SECOND, state->fps_n); - } -} diff --git a/gst-libs/gst/video/gstbasevideoutils.h b/gst-libs/gst/video/gstbasevideoutils.h deleted file mode 100644 index 047be71368..0000000000 --- a/gst-libs/gst/video/gstbasevideoutils.h +++ /dev/null @@ -1,88 +0,0 @@ -/* GStreamer - * Copyright (C) 2008 David Schleef - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _GST_BASE_VIDEO_UTILS_H_ -#define _GST_BASE_VIDEO_UTILS_H_ - -#ifndef GST_USE_UNSTABLE_API -#warning "The base video utils API is unstable and may change in future." -#warning "You can define GST_USE_UNSTABLE_API to avoid this warning." -#endif - -#include -#include -#include - -G_BEGIN_DECLS - -typedef struct _GstVideoState GstVideoState; -typedef struct _GstVideoFrame GstVideoFrame; - -struct _GstVideoState -{ - int width, height; - int fps_n, fps_d; - int par_n, par_d; - - gboolean have_interlaced; - gboolean interlaced; - gboolean top_field_first; - - int clean_width, clean_height; - int clean_offset_left, clean_offset_top; - - int bytes_per_picture; - - //GstSegment segment; - - int picture_number; - GstBuffer *codec_data; - -}; - -struct _GstVideoFrame -{ - GstClockTime decode_timestamp; - GstClockTime presentation_timestamp; - GstClockTime presentation_duration; - - gint system_frame_number; - gint decode_frame_number; - gint presentation_frame_number; - - int distance_from_sync; - gboolean is_sync_point; - gboolean is_eos; - - GstBuffer *sink_buffer; - GstBuffer *src_buffer; - - int field_index; - int n_fields; - - void *coder_hook; -}; - -GstClockTime gst_video_state_get_timestamp (const GstVideoState *state, - GstSegment *segment, int frame_number); - -G_END_DECLS - -#endif - From 2c5f034c66b2431b6180b4ff880e3a4f5fac8290 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Dec 2011 13:22:07 +0100 Subject: [PATCH 0484/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 26f989f763..a3047f11fc 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) -m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From cbf81d7d51db8acb7d788263578fa58906d9ac92 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 25 Nov 2011 12:28:04 -0500 Subject: [PATCH 0485/3781] Add missing video context queries. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapiconvert.c | 1 + gst/vaapi/gstvaapidecode.c | 1 + 2 files changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapiconvert.c b/gst/vaapi/gstvaapiconvert.c index 39f1c48d10..f692b50f15 100644 --- a/gst/vaapi/gstvaapiconvert.c +++ b/gst/vaapi/gstvaapiconvert.c @@ -352,6 +352,7 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) sinkpad, gst_vaapiconvert_sinkpad_buffer_alloc ); + gst_pad_set_query_function(sinkpad, gst_vaapiconvert_query); g_object_unref(sinkpad); /* Override query on src pad */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ffba8fb5aa..17c6320574 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -687,6 +687,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) gst_pad_set_setcaps_function(decode->sinkpad, gst_vaapidecode_set_caps); gst_pad_set_chain_function(decode->sinkpad, gst_vaapidecode_chain); gst_pad_set_event_function(decode->sinkpad, gst_vaapidecode_sink_event); + gst_pad_set_query_function(decode->sinkpad, gst_vaapidecode_query); gst_element_add_pad(GST_ELEMENT(decode), decode->sinkpad); /* Pad through which data goes out of the element */ From bb72c5555586ef0cf148cb353936f2f28024fd40 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Fri, 14 Oct 2011 13:00:12 -0300 Subject: [PATCH 0486/3781] tests: add test for subpictures. Signed-off-by: Gwenole Beauchesne --- tests/Makefile.am | 5 + tests/test-subpicture-data.c | 1430 ++++++++++++++++++++++++++++++++++ tests/test-subpicture-data.h | 40 + tests/test-subpicture.c | 207 +++++ 4 files changed, 1682 insertions(+) create mode 100644 tests/test-subpicture-data.c create mode 100644 tests/test-subpicture-data.h create mode 100644 tests/test-subpicture.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 8a27305557..d1c7d45804 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -3,6 +3,7 @@ noinst_PROGRAMS = \ test-display \ test-surfaces \ test-windows \ + test-subpicture \ $(NULL) if USE_GLX @@ -55,6 +56,10 @@ test_surfaces_SOURCES = test-surfaces.c test_surfaces_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) test_surfaces_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) +test_subpicture_SOURCES = test-subpicture.c test-h264.c test-subpicture-data.c +test_subpicture_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) +test_subpicture_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) + test_windows_SOURCES = test-windows.c image.c test_windows_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) test_windows_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) diff --git a/tests/test-subpicture-data.c b/tests/test-subpicture-data.c new file mode 100644 index 0000000000..02f21888dc --- /dev/null +++ b/tests/test-subpicture-data.c @@ -0,0 +1,1430 @@ +/* + * test-subpicture-data.c - subpicture data + * + * Copyright (C) <2011> Intel Corporation + * Copyright (C) <2011> Collabora Ltd. + * Copyright (C) <2011> Thibault Saunier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "test-subpicture-data.h" + +#define SUBPICTURE_WIDTH 184 +#define SUBPICTURE_HEIGHT 38 +#define SUBPICTURE_DATA_SIZE 27968 + +/* Raw RGBA data */ +static const guint32 text[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x09000000, 0x63000000, 0x08000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x44000000, 0x88000000, 0x88000000, 0x88000000, 0x88000000, + 0x88000000, 0x88000000, 0x88000000, 0x88000000, 0x88000000, + 0x44000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x44000000, 0x88000000, 0x44000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x44000000, 0x88000000, + 0x44000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x69000000, 0xff0000b4, 0x65000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0x80000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0x80000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0x80000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x6a000000, + 0xff0000b6, 0x9c000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x3c000000, 0xbb000000, + 0xff0000ff, 0xdd000000, 0xbb000000, 0xbb000000, 0xbb000000, + 0xbb000000, 0xdd000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x08000000, 0x61000000, + 0x60000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x00000000, 0x1f000000, 0x5c000000, 0x78000000, 0x60000000, + 0x27000000, 0x00000000, 0x00000000, 0x44000000, 0xc4000000, + 0xff0000ff, 0xe2000000, 0x88000000, 0x88000000, 0x88000000, + 0x0f000000, 0x00000000, 0x00000000, 0x42000000, 0x78000000, + 0x78000000, 0x41000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x1f000000, 0x5c000000, 0x78000000, + 0x60000000, 0x27000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x1f000000, 0x5c000000, 0x78000000, 0x60000000, + 0x27000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x42000000, 0x78000000, 0x78000000, 0x41000000, + 0x00000000, 0x00000000, 0x00000000, 0x44000000, 0x88000000, + 0x88000000, 0x45000000, 0x3d000000, 0x73000000, 0x6c000000, + 0x37000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x44000000, + 0xc4000000, 0xff0000ff, 0xe2000000, 0x88000000, 0x88000000, + 0x88000000, 0x53000000, 0x88000000, 0x88000000, 0x44000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x41000000, + 0x78000000, 0x78000000, 0x46000000, 0x01000000, 0x00000000, + 0x00000000, 0x44000000, 0x88000000, 0x88000000, 0x49000000, + 0x55000000, 0x78000000, 0x4a000000, 0x02000000, 0x02000000, + 0x4f000000, 0x78000000, 0x4d000000, 0x01000000, 0x00000000, + 0x00000000, 0x44000000, 0x88000000, 0x88000000, 0x45000000, + 0x3e000000, 0x77000000, 0x78000000, 0x43000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x42000000, 0x78000000, 0x78000000, 0x41000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1f000000, + 0x5c000000, 0x78000000, 0x60000000, 0x27000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x44000000, 0x88000000, 0x80000000, + 0x77000000, 0x9e000000, 0x00000000, 0x00000000, 0x9000000a, + 0xfd000076, 0xff0000b6, 0xff0000ef, 0xfe0000dc, 0xf50000a0, + 0xc8000036, 0x35000000, 0x80000000, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff00009c, 0x1c000000, + 0x10000000, 0xc900001f, 0xff0000ad, 0xff0000e7, 0xff0000e7, + 0xff0000ad, 0xc900001f, 0x13000000, 0x00000000, 0x00000000, + 0x9000000a, 0xfd000076, 0xff0000b6, 0xff0000ef, 0xfe0000dc, + 0xf50000a0, 0xc8000036, 0x35000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x9000000a, + 0xfd000076, 0xff0000b6, 0xff0000ef, 0xfe0000dc, 0xf50000a0, + 0xc8000036, 0x35000000, 0x00000000, 0x10000000, 0xc900001f, + 0xff0000ad, 0xff0000e7, 0xff0000e7, 0xff0000ad, 0xc900001f, + 0x13000000, 0x00000000, 0x80000000, 0xff0000ff, 0xff0000ff, + 0xee000011, 0xff0000a3, 0xff0000e5, 0xff0000ca, 0xfc000072, + 0x94000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff00009c, + 0x9b000000, 0xff0000ff, 0xff0000ff, 0x80000000, 0x00000000, + 0x00000000, 0x10000000, 0xc900001f, 0xff0000ad, 0xfe0000e7, + 0xff0000e7, 0xff0000af, 0xc600001f, 0x11000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xff0000ff, 0xf700001f, 0xff0000b6, + 0xff0000eb, 0xf80000ac, 0xbb00001a, 0xc8000022, 0xff0000b3, + 0xff0000e6, 0xf900008a, 0xad000017, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xff0000ff, 0xf300001b, 0xff0000ad, + 0xfe0000e3, 0xff0000e9, 0xff0000ad, 0xc100001d, 0x0f000000, + 0x00000000, 0x00000000, 0x10000000, 0xc900001f, 0xff0000ad, + 0xff0000e7, 0xff0000e7, 0xff0000ad, 0xc900001f, 0x13000000, + 0x00000000, 0x00000000, 0x9000000a, 0xfd000076, 0xff0000b6, + 0xff0000ef, 0xfe0000dc, 0xf50000a0, 0xc8000036, 0x35000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xe2000000, 0x88000000, + 0x88000000, 0xc4000000, 0xff0000ff, 0x80000000, 0x00000000, + 0x00000000, 0x00000000, 0x43000000, 0xff000078, 0xf8000096, + 0xbe00002c, 0xb9000011, 0xe5000051, 0xfa0000cf, 0xff0000ff, + 0x8d000000, 0x3c000000, 0xbb000000, 0xff0000ff, 0xdd000000, + 0xbb000000, 0xbb000000, 0xbb000000, 0x57000000, 0xbc00001a, + 0xff0000e4, 0xf5000098, 0xc8000033, 0xd1000033, 0xf900009a, + 0xff0000e4, 0xbe00001a, 0x00000000, 0x43000000, 0xff000078, + 0xf8000096, 0xbe00002c, 0xb9000011, 0xe5000051, 0xfa0000cf, + 0xff0000ff, 0x8d000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x43000000, 0xff000078, 0xf8000096, + 0xbe00002c, 0xb9000011, 0xe5000051, 0xfa0000cf, 0xff0000ff, + 0x8d000000, 0x00000000, 0xbc00001a, 0xff0000e4, 0xf5000098, + 0xc8000033, 0xd1000033, 0xf900009a, 0xff0000e4, 0xbe00001a, + 0x00000000, 0x3c000000, 0xbb000000, 0xff0000ff, 0xff0000b1, + 0xea000077, 0xbd00001d, 0xda000042, 0xfd0000bc, 0xfa000074, + 0x36000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x3c000000, 0xbb000000, 0xff0000ff, + 0xdd000000, 0xbb000000, 0xbb000000, 0xbb000000, 0x81000000, + 0xbb000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0xb700001a, 0xff0000e6, 0xf500008e, 0xc9000031, 0xd000002c, + 0xf8000087, 0xff0000dd, 0xb1000014, 0x00000000, 0x3c000000, + 0xbb000000, 0xff0000ff, 0xff0000a9, 0xd4000054, 0xc5000024, + 0xfc0000a8, 0xfa0000b4, 0xff0000a7, 0xd5000054, 0xc4000024, + 0xfc0000aa, 0xfc000088, 0x3e000000, 0x00000000, 0x3c000000, + 0xbb000000, 0xff0000ff, 0xff0000cf, 0xf2000087, 0xc600002d, + 0xd1000033, 0xf900009a, 0xff0000e1, 0xb6000017, 0x00000000, + 0x00000000, 0xbc00001a, 0xff0000e4, 0xf5000098, 0xc8000033, + 0xd1000033, 0xf900009a, 0xff0000e4, 0xbe00001a, 0x00000000, + 0x43000000, 0xff000078, 0xf8000096, 0xbe00002c, 0xb9000011, + 0xe5000051, 0xfa0000cf, 0xff0000ff, 0x8d000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x00000000, 0x75000000, 0xfe0000e4, 0xc5000025, 0x4c000000, + 0x16000000, 0x09000000, 0xcd000040, 0xff0000ff, 0xc0000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x2e000000, 0xff00009c, 0xf8000092, + 0x7e000000, 0x4c000000, 0x1a000000, 0x30000000, 0xfa000096, + 0xff00009b, 0x37000000, 0x75000000, 0xfe0000e4, 0xc5000025, + 0x4c000000, 0x16000000, 0x09000000, 0xcd000040, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x75000000, 0xfe0000e4, 0xc5000025, 0x4c000000, + 0x16000000, 0x09000000, 0xcd000040, 0xff0000ff, 0xc0000000, + 0x2e000000, 0xff00009c, 0xf8000092, 0x7e000000, 0x4c000000, + 0x1a000000, 0x30000000, 0xfa000096, 0xff00009b, 0x37000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xf5000078, 0x5e000000, + 0x3c000000, 0x0f000000, 0xcd00004b, 0xfe0000c1, 0x89000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xc0000000, 0x00000000, 0x2e000000, 0xff00009b, + 0xf900009e, 0x82000000, 0x47000000, 0x19000000, 0x25000000, + 0xf700008e, 0xfe000086, 0x25000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xee000060, 0x56000000, 0x2a000000, 0xb9000036, + 0xff0000ff, 0xe9000060, 0x55000000, 0x2a000000, 0xba000038, + 0xff0000ca, 0x91000000, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xf7000084, 0x70000000, 0x44000000, 0x17000000, + 0x30000000, 0xfb000096, 0xff000098, 0x32000000, 0x2e000000, + 0xff00009c, 0xf8000092, 0x7e000000, 0x4c000000, 0x1a000000, + 0x30000000, 0xfa000096, 0xff00009b, 0x37000000, 0x75000000, + 0xfe0000e4, 0xc5000025, 0x4c000000, 0x16000000, 0x09000000, + 0xcd000040, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xdd000000, 0xbb000000, 0xbb000000, 0xdd000000, + 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, 0x00000000, + 0x49000000, 0xf70000a8, 0xfb0000cb, 0xea000055, 0x82000005, + 0x48000000, 0x44000000, 0x88000000, 0x9e000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x00000000, 0x5d000000, 0xff0000da, 0xd0000049, 0x49000000, + 0x00000000, 0x00000000, 0x00000000, 0xbe00004b, 0xfe0000d9, + 0x96000000, 0x49000000, 0xf70000a8, 0xfb0000cb, 0xea000055, + 0x82000005, 0x48000000, 0x44000000, 0x88000000, 0x9e000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x49000000, 0xf70000a8, 0xfb0000cb, 0xea000055, 0x82000005, + 0x48000000, 0x44000000, 0x88000000, 0x9e000000, 0x5d000000, + 0xff0000da, 0xd0000049, 0x49000000, 0x00000000, 0x00000000, + 0x00000000, 0xbe00004b, 0xfe0000d9, 0x96000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xd1000028, 0x3c000000, 0x00000000, + 0x00000000, 0x90000011, 0xff0000fc, 0xaf000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x5d000000, 0xff0000da, 0xeb000034, + 0xad000000, 0x88000000, 0x88000000, 0x88000000, 0xde00002f, + 0xff0000cb, 0x7b000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xcd000020, 0x30000000, 0x00000000, 0x84000005, 0xff0000ff, + 0xcd000020, 0x30000000, 0x00000000, 0x85000006, 0xff0000fc, + 0xb1000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xd300002c, 0x42000000, 0x00000000, 0x00000000, 0x00000000, + 0xbe00004b, 0xfe0000d8, 0x95000000, 0x5d000000, 0xff0000da, + 0xd0000049, 0x49000000, 0x00000000, 0x00000000, 0x00000000, + 0xbe00004b, 0xfe0000d9, 0x96000000, 0x49000000, 0xf70000a8, + 0xfb0000cb, 0xea000055, 0x82000005, 0x48000000, 0x44000000, + 0x88000000, 0x9e000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x3c000000, 0x77000000, + 0x9e000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x8f000007, 0xf900007e, 0xfc0000dd, 0xff0000f2, 0xfb0000c2, + 0xf200005c, 0x72000001, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, 0x00000000, + 0x78000000, 0xff0000f6, 0xc0000012, 0x25000000, 0x00000000, + 0x00000000, 0x00000000, 0x92000013, 0xff0000f6, 0xb4000000, + 0x00000000, 0x8f000007, 0xf900007e, 0xfc0000dd, 0xff0000f2, + 0xfb0000c2, 0xf200005c, 0x72000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x8f000007, 0xf900007e, 0xfc0000dd, 0xff0000f2, 0xfb0000c2, + 0xf200005c, 0x72000001, 0x00000000, 0x78000000, 0xff0000f6, + 0xc0000012, 0x25000000, 0x00000000, 0x00000000, 0x00000000, + 0x92000013, 0xff0000f6, 0xb4000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xc0000000, 0x14000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xbf000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x7a000000, 0xff0000f6, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ee, + 0xa8000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x10000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x10000000, 0x00000000, 0x80000000, 0xff0000ff, 0xbf000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x16000000, 0x00000000, 0x00000000, 0x00000000, 0x92000013, + 0xff0000f6, 0xb3000000, 0x78000000, 0xff0000f6, 0xc0000012, + 0x25000000, 0x00000000, 0x00000000, 0x00000000, 0x92000013, + 0xff0000f6, 0xb4000000, 0x00000000, 0x8f000007, 0xf900007e, + 0xfc0000dd, 0xff0000f2, 0xfb0000c2, 0xf200005c, 0x72000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x44000000, + 0x88000000, 0x44000000, 0x00000000, 0x44000000, 0x88000000, + 0x65000000, 0x84000000, 0xc8000014, 0xf4000059, 0xfc0000cc, + 0xfb000098, 0x40000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x00000000, 0x5d000000, + 0xff0000da, 0xdc00004a, 0x09000000, 0x00000000, 0x00000000, + 0x00000000, 0xbe00004b, 0xfe0000d9, 0xb1000000, 0x44000000, + 0x88000000, 0x65000000, 0x84000000, 0xc8000014, 0xf4000059, + 0xfc0000cc, 0xfb000098, 0x40000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x44000000, 0x88000000, + 0x65000000, 0x84000000, 0xc8000014, 0xf4000059, 0xfc0000cc, + 0xfb000098, 0x40000000, 0x5d000000, 0xff0000da, 0xdc00004a, + 0x09000000, 0x00000000, 0x00000000, 0x00000000, 0xbe00004b, + 0xfe0000d9, 0xb1000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x69000000, 0xff0000d9, 0xe8000028, 0xbb000000, 0xbb000000, + 0xbb000000, 0xbb000000, 0xda000000, 0xff000000, 0xc1000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xd6000036, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xbe00004b, 0xfe0000d8, + 0xb1000000, 0x5d000000, 0xff0000da, 0xdc00004a, 0x09000000, + 0x00000000, 0x00000000, 0x00000000, 0xbe00004b, 0xfe0000d9, + 0xb1000000, 0x44000000, 0x88000000, 0x65000000, 0x84000000, + 0xc8000014, 0xf4000059, 0xfc0000cc, 0xfb000098, 0x40000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0x80000000, 0x00000000, 0x80000000, 0xff0000ff, 0xba00003a, + 0x00000000, 0x00000000, 0x0b000000, 0xc1000027, 0xff0000e2, + 0x9d000000, 0x00000000, 0x7f000000, 0xff0000fd, 0xc0000002, + 0x00000000, 0x43000000, 0x88000000, 0x71000000, 0xff00009b, + 0xfb000095, 0x39000000, 0x00000000, 0x00000000, 0x18000000, + 0xf9000096, 0xff00009b, 0x85000000, 0x80000000, 0xff0000ff, + 0xba00003a, 0x00000000, 0x00000000, 0x0b000000, 0xc1000027, + 0xff0000e2, 0x9d000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xba00003a, + 0x00000000, 0x00000000, 0x0b000000, 0xc1000027, 0xff0000e2, + 0x9d000000, 0x2b000000, 0xff00009b, 0xfb000095, 0x39000000, + 0x00000000, 0x00000000, 0x18000000, 0xf9000096, 0xff00009b, + 0x85000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x7f000000, 0xff0000fd, + 0xc0000002, 0x00000000, 0x43000000, 0x88000000, 0x46000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x2b000000, + 0xff000097, 0xf4000080, 0x1b000000, 0x00000000, 0x00000000, + 0x08000000, 0xe0000059, 0xff0000b5, 0x55000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xf9000089, 0x28000000, 0x00000000, + 0x00000000, 0x18000000, 0xf9000096, 0xff000097, 0x83000000, + 0x2b000000, 0xff00009b, 0xfb000095, 0x39000000, 0x00000000, + 0x00000000, 0x18000000, 0xf9000096, 0xff00009b, 0x85000000, + 0x80000000, 0xff0000ff, 0xba00003a, 0x00000000, 0x00000000, + 0x0b000000, 0xc1000027, 0xff0000e2, 0x9d000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x44000000, + 0xc4000000, 0xff0000ff, 0xe2000000, 0x88000000, 0x88000000, + 0x88000000, 0x88000000, 0xc4000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xfc0000c5, 0xcf00004a, + 0x91000010, 0xab00002c, 0xfa00009d, 0xff000074, 0x95000000, + 0x00000000, 0x66000000, 0xff0000c1, 0xee000050, 0x8e00000d, + 0xe400005a, 0xfe0000c7, 0x66000000, 0xb800001a, 0xff0000e4, + 0xf8000099, 0xac000033, 0xac000033, 0xf5000099, 0xff0000e4, + 0xcc00001a, 0x4e000000, 0x80000000, 0xff0000ff, 0xfc0000c5, + 0xcf00004a, 0x91000010, 0xab00002c, 0xfa00009d, 0xff000074, + 0x95000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xfc0000c5, 0xcf00004a, + 0x91000010, 0xab00002c, 0xfa00009d, 0xff000074, 0x95000000, + 0x00000000, 0xb800001a, 0xff0000e4, 0xf8000099, 0xac000033, + 0xac000033, 0xf5000099, 0xff0000e4, 0xcc00001a, 0x4e000000, + 0x44000000, 0xc4000000, 0xff0000ff, 0xe2000000, 0x44000000, + 0x00000000, 0x44000000, 0xc4000000, 0xff0000ff, 0xe2000000, + 0x44000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x66000000, 0xff0000c1, 0xee000050, + 0x8e00000d, 0xe400005a, 0xfe0000c7, 0xaa000000, 0xc4000000, + 0xff0000ff, 0xe2000000, 0x44000000, 0x00000000, 0xad000015, + 0xff0000d3, 0xf200007f, 0xaa00002d, 0x9d00001d, 0xe6000061, + 0xff0000e9, 0xe9000025, 0x60000000, 0x44000000, 0xc4000000, + 0xff0000ff, 0xe2000000, 0x44000000, 0x44000000, 0xc4000000, + 0xff0000ff, 0xe2000000, 0x44000000, 0x44000000, 0xc4000000, + 0xff0000ff, 0xe2000000, 0x44000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xff0000bc, 0xf5000088, 0xa900002d, 0xac000033, + 0xf5000099, 0xff0000e1, 0xc9000017, 0x4c000000, 0x00000000, + 0xb800001a, 0xff0000e4, 0xf8000099, 0xac000033, 0xac000033, + 0xf5000099, 0xff0000e4, 0xcc00001a, 0x4e000000, 0x80000000, + 0xff0000ff, 0xfc0000c5, 0xcf00004a, 0x91000010, 0xab00002c, + 0xfa00009d, 0xff000074, 0x95000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xc0000000, 0x00000000, + 0x36000000, 0xd300003b, 0xfb0000aa, 0xff0000e1, 0xff0000f0, + 0xff0000b6, 0xfc000076, 0xae000008, 0x3a000000, 0x00000000, + 0x15000000, 0xee000046, 0xff0000bd, 0xff0000ef, 0xfd0000be, + 0xeb00003f, 0x6f000000, 0x13000000, 0xcd00001f, 0xff0000ae, + 0xff0000e8, 0xff0000e8, 0xff0000ae, 0xd900001f, 0x7d000000, + 0x0d000000, 0x36000000, 0xd300003b, 0xfb0000aa, 0xff0000e1, + 0xff0000f0, 0xff0000b6, 0xfc000076, 0xae000008, 0x3a000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x36000000, 0xd300003b, 0xfb0000aa, 0xff0000e1, 0xff0000f0, + 0xff0000b6, 0xfc000076, 0xae000008, 0x3a000000, 0x00000000, + 0x13000000, 0xcd00001f, 0xff0000ae, 0xff0000e8, 0xff0000e8, + 0xff0000ae, 0xd900001f, 0x7d000000, 0x0d000000, 0x80000000, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0x80000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0x80000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x15000000, 0xee000046, 0xff0000bd, 0xff0000ef, + 0xfd0000be, 0xeb00003f, 0xbc000000, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0x80000000, 0x00000000, 0x0e000000, 0xc0000018, + 0xff0000a4, 0xff0000e1, 0xff0000e5, 0xfc00009b, 0xec000042, + 0x8d000000, 0x13000000, 0x80000000, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0x80000000, 0x80000000, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0x80000000, 0x80000000, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0x80000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xf8000012, 0xff0000a6, 0xff0000e2, 0xff0000e9, 0xff0000ad, + 0xd100001d, 0x78000000, 0x0c000000, 0x00000000, 0x13000000, + 0xcd00001f, 0xff0000ae, 0xff0000e8, 0xff0000e8, 0xff0000ae, + 0xd900001f, 0x7d000000, 0x0d000000, 0x36000000, 0xd300003b, + 0xfb0000aa, 0xff0000e1, 0xff0000f0, 0xff0000b6, 0xfc000076, + 0xae000008, 0x3a000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x3c000000, 0x77000000, 0xbb000000, + 0xbb000000, 0xbb000000, 0xbb000000, 0xbb000000, 0xbb000000, + 0xbb000000, 0xbb000000, 0x9e000000, 0x00000000, 0x00000000, + 0x00000000, 0x4a000000, 0x96000000, 0xb2000000, 0xa8000000, + 0x6e000000, 0x3b000000, 0x04000000, 0x00000000, 0x00000000, + 0x0f000000, 0x78000000, 0xaa000000, 0xaa000000, 0x68000000, + 0x20000000, 0x00000000, 0x00000000, 0x47000000, 0xa5000000, + 0xb4000000, 0x94000000, 0x57000000, 0x10000000, 0x00000000, + 0x00000000, 0x00000000, 0x4a000000, 0x96000000, 0xb2000000, + 0xa8000000, 0x6e000000, 0x3b000000, 0x04000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x4a000000, 0x96000000, 0xb2000000, 0xa8000000, + 0x6e000000, 0x3b000000, 0x04000000, 0x00000000, 0x00000000, + 0x00000000, 0x47000000, 0xa5000000, 0xb4000000, 0x94000000, + 0x57000000, 0x10000000, 0x00000000, 0x3c000000, 0x77000000, + 0xbb000000, 0xbb000000, 0x9e000000, 0x00000000, 0x3c000000, + 0x77000000, 0xbb000000, 0xbb000000, 0x9e000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x0f000000, 0x78000000, 0xaa000000, 0xaa000000, + 0x68000000, 0x54000000, 0x77000000, 0xbb000000, 0xbb000000, + 0x9e000000, 0x00000000, 0x00000000, 0x00000000, 0x3b000000, + 0x9f000000, 0xb0000000, 0x9e000000, 0x51000000, 0x21000000, + 0x00000000, 0x3c000000, 0x77000000, 0xbb000000, 0xbb000000, + 0x9e000000, 0x3c000000, 0x77000000, 0xbb000000, 0xbb000000, + 0x9e000000, 0x3c000000, 0x77000000, 0xbb000000, 0xbb000000, + 0x9e000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x43000000, 0x9d000000, 0xb3000000, 0x95000000, 0x57000000, + 0x0f000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x47000000, 0xa5000000, 0xb4000000, 0x94000000, 0x57000000, + 0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x4a000000, + 0x96000000, 0xb2000000, 0xa8000000, 0x6e000000, 0x3b000000, + 0x04000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x44000000, 0xc4000000, 0xff0000ff, 0xe2000000, 0x44000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0x80000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x3c000000, 0x77000000, + 0xbb000000, 0xbb000000, 0x9e000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x09000000, 0x63000000, 0x08000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x44000000, 0x88000000, 0x44000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x44000000, + 0x88000000, 0x88000000, 0x44000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x69000000, 0xff0000b4, 0x65000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x44000000, 0x88000000, 0x88000000, + 0x44000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x44000000, + 0x88000000, 0x88000000, 0x44000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0x80000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xff0000ff, 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x6a000000, 0xff0000b6, 0x9c000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xff0000ff, 0x80000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xff0000ff, 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x3c000000, 0xbb000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08000000, + 0x61000000, 0x60000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x3c000000, 0xbb000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x3c000000, 0xbb000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x44000000, 0xc4000000, + 0xff0000ff, 0xe2000000, 0x88000000, 0x88000000, 0x88000000, + 0x0f000000, 0x00000000, 0x00000000, 0x41000000, 0x78000000, + 0x78000000, 0x46000000, 0x01000000, 0x00000000, 0x00000000, + 0x44000000, 0x88000000, 0x88000000, 0x45000000, 0x3d000000, + 0x73000000, 0x6c000000, 0x37000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x41000000, + 0x78000000, 0x78000000, 0x46000000, 0x01000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x38000000, 0x6e000000, 0x79000000, 0x43000000, 0x00000000, + 0x00000000, 0x00000000, 0x44000000, 0x88000000, 0x88000000, + 0x44000000, 0x38000000, 0x75000000, 0x86000000, 0x88000000, + 0x44000000, 0x00000000, 0x00000000, 0x42000000, 0x78000000, + 0x78000000, 0x41000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x1f000000, 0x5c000000, 0x78000000, + 0x60000000, 0x27000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x42000000, 0x78000000, 0x78000000, + 0x41000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x1f000000, 0x5c000000, 0x78000000, 0x60000000, + 0x27000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x1f000000, 0x5c000000, 0x78000000, 0x60000000, 0x27000000, + 0x00000000, 0x00000000, 0x44000000, 0x88000000, 0x88000000, + 0x44000000, 0x00000000, 0x44000000, 0x88000000, 0x88000000, + 0x45000000, 0x3d000000, 0x73000000, 0x6c000000, 0x37000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x43000000, 0x79000000, 0x6f000000, 0x38000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x44000000, + 0x88000000, 0x88000000, 0x44000000, 0x00000000, 0x00000000, + 0x44000000, 0x88000000, 0x88000000, 0x44000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x43000000, 0x79000000, + 0x6f000000, 0x38000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000, 0x02000000, 0x46000000, + 0x76000000, 0x65000000, 0x27000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff00009c, 0x1c000000, + 0x10000000, 0xc900001f, 0xff0000ad, 0xfe0000e7, 0xff0000e7, + 0xff0000af, 0xc600001f, 0x11000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xff0000ff, 0xee000011, 0xff0000a3, 0xff0000e5, + 0xff0000ca, 0xfc000072, 0x94000010, 0x00000000, 0x00000000, + 0x00000000, 0x10000000, 0xc900001f, 0xff0000ad, 0xfe0000e7, + 0xff0000e7, 0xff0000af, 0xc600001f, 0x11000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xf7000011, 0xff0000a2, + 0xfe0000e0, 0xff0000e9, 0xff0000ad, 0xc100001d, 0x0f000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xff0000ff, 0xef000014, + 0xff0000a3, 0xff0000dd, 0xff0000ff, 0xff0000ff, 0x80000000, + 0x10000000, 0xc900001f, 0xff0000ad, 0xff0000e7, 0xff0000e7, + 0xff0000ad, 0xc900001f, 0x13000000, 0x00000000, 0x00000000, + 0x9000000a, 0xfd000076, 0xff0000b6, 0xff0000ef, 0xfe0000dc, + 0xf50000a0, 0xc8000036, 0x35000000, 0x00000000, 0x10000000, + 0xc900001f, 0xff0000ad, 0xff0000e7, 0xff0000e7, 0xff0000ad, + 0xc900001f, 0x13000000, 0x00000000, 0x00000000, 0x9000000a, + 0xfd000076, 0xff0000b6, 0xff0000ef, 0xfe0000dc, 0xf50000a0, + 0xc8000036, 0x35000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x9000000a, 0xfd000076, + 0xff0000b6, 0xff0000ef, 0xfe0000dc, 0xf50000a0, 0xc8000036, + 0x35000000, 0x80000000, 0xff0000ff, 0xff0000ff, 0x80000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xff0000ff, 0xee000011, + 0xff0000a3, 0xff0000e5, 0xff0000ca, 0xfc000072, 0x94000010, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x10000000, 0xc900001e, + 0xff0000ad, 0xff0000e9, 0xfe0000e0, 0xff0000a2, 0xed000011, + 0xff0000ff, 0xc0000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xff0000ff, 0x80000000, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xff0000ff, 0x80000000, 0x00000000, 0x00000000, + 0x10000000, 0xc900001e, 0xff0000ad, 0xff0000e9, 0xfe0000e0, + 0xff0000a2, 0xed000011, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x36000000, 0xdd000045, 0xff0000bf, 0xff0000ef, + 0xff0000b9, 0xfc000063, 0x7e00000b, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x3c000000, 0xbb000000, 0xff0000ff, 0xdd000000, + 0xbb000000, 0xbb000000, 0xbb000000, 0x57000000, 0xb700001a, + 0xff0000e6, 0xf500008e, 0xc9000031, 0xd000002c, 0xf8000087, + 0xff0000dd, 0xb1000014, 0x00000000, 0x3c000000, 0xbb000000, + 0xff0000ff, 0xff0000b1, 0xea000077, 0xbd00001d, 0xda000042, + 0xfd0000bc, 0xfa000074, 0x36000000, 0x00000000, 0x00000000, + 0xb700001a, 0xff0000e6, 0xf500008e, 0xc9000031, 0xd000002c, + 0xf8000087, 0xff0000dd, 0xb1000014, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xff0000bd, 0xf200008c, 0xc500002f, + 0xd1000033, 0xf900009a, 0xff0000e1, 0xb6000017, 0x00000000, + 0x3c000000, 0xbb000000, 0xff0000ff, 0xff0000b8, 0xe0000067, + 0xb8000015, 0xf000005c, 0xff0000ff, 0xc0000000, 0xbc00001a, + 0xff0000e4, 0xf5000098, 0xc8000033, 0xd1000033, 0xf900009a, + 0xff0000e4, 0xbe00001a, 0x00000000, 0x43000000, 0xff000078, + 0xf8000096, 0xbe00002c, 0xb9000011, 0xe5000051, 0xfa0000cf, + 0xff0000ff, 0x8d000000, 0x00000000, 0xbc00001a, 0xff0000e4, + 0xf5000098, 0xc8000033, 0xd1000033, 0xf900009a, 0xff0000e4, + 0xbe00001a, 0x00000000, 0x43000000, 0xff000078, 0xf8000096, + 0xbe00002c, 0xb9000011, 0xe5000051, 0xfa0000cf, 0xff0000ff, + 0x8d000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x43000000, 0xff000078, 0xf8000096, 0xbe00002c, + 0xb9000011, 0xe5000051, 0xfa0000cf, 0xff0000ff, 0x8d000000, + 0x3c000000, 0xbb000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x3c000000, 0xbb000000, 0xff0000ff, 0xff0000b1, 0xea000077, + 0xbd00001d, 0xda000042, 0xfd0000bc, 0xfa000074, 0x36000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xb7000019, 0xff0000e2, 0xf5000098, + 0xc8000033, 0xd100002f, 0xf800008c, 0xff0000bc, 0xff0000ff, + 0xc0000000, 0x00000000, 0x3c000000, 0xbb000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x3c000000, 0xbb000000, + 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, 0xb7000019, + 0xff0000e2, 0xf5000098, 0xc8000033, 0xd100002f, 0xf800008c, + 0xff0000bc, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xf2000076, 0xbe000014, 0xd7000031, + 0xfe0000b1, 0xff00008e, 0x33000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x2e000000, 0xff00009b, 0xf900009e, + 0x82000000, 0x47000000, 0x19000000, 0x25000000, 0xf700008e, + 0xfe000086, 0x25000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xf5000078, 0x5e000000, 0x3c000000, 0x0f000000, 0xcd00004b, + 0xfe0000c1, 0x89000000, 0x00000000, 0x2e000000, 0xff00009b, + 0xf900009e, 0x82000000, 0x47000000, 0x19000000, 0x25000000, + 0xf700008e, 0xfe000086, 0x25000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xf900008a, 0x68000000, 0x46000000, 0x18000000, + 0x30000000, 0xfb000096, 0xff000098, 0x32000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xf0000068, 0x5d000000, 0x34000000, + 0x42000000, 0x90000000, 0xb4000000, 0xff00009c, 0xf8000092, + 0x7e000000, 0x4c000000, 0x1a000000, 0x30000000, 0xfa000096, + 0xff00009b, 0x37000000, 0x75000000, 0xfe0000e4, 0xc5000025, + 0x4c000000, 0x16000000, 0x09000000, 0xcd000040, 0xff0000ff, + 0xc0000000, 0x2e000000, 0xff00009c, 0xf8000092, 0x7e000000, + 0x4c000000, 0x1a000000, 0x30000000, 0xfa000096, 0xff00009b, + 0x37000000, 0x75000000, 0xfe0000e4, 0xc5000025, 0x4c000000, + 0x16000000, 0x09000000, 0xcd000040, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x75000000, 0xfe0000e4, 0xc5000025, 0x4c000000, 0x16000000, + 0x09000000, 0xcd000040, 0xff0000ff, 0xc0000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xf5000078, 0x5e000000, 0x3c000000, + 0x0f000000, 0xcd00004b, 0xfe0000c1, 0x89000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x2a000000, 0xff00009a, 0xf9000092, 0x7d000000, 0x4c000000, + 0x1a000000, 0x26000000, 0xf600008b, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x2a000000, 0xff00009a, 0xf9000092, + 0x7d000000, 0x4c000000, 0x1a000000, 0x26000000, 0xf600008b, + 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, 0x3c000000, + 0x77000000, 0x9b000000, 0x3b000000, 0x0a000000, 0xaf000027, + 0xff0000e4, 0x8f000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x00000000, 0x5d000000, 0xff0000da, 0xeb000034, 0xad000000, + 0x88000000, 0x88000000, 0x88000000, 0xde00002f, 0xff0000cb, + 0x7b000000, 0x00000000, 0x80000000, 0xff0000ff, 0xd1000028, + 0x3c000000, 0x00000000, 0x00000000, 0x90000011, 0xff0000fc, + 0xaf000000, 0x00000000, 0x5d000000, 0xff0000da, 0xeb000034, + 0xad000000, 0x88000000, 0x88000000, 0x88000000, 0xde00002f, + 0xff0000cb, 0x7b000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xd7000036, 0x45000000, 0x00000000, 0x00000000, 0x00000000, + 0xbe00004b, 0xfe0000d8, 0x95000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xcb000019, 0x34000000, 0x00000000, 0x00000000, + 0x00000000, 0x5d000000, 0xff0000da, 0xd0000049, 0x49000000, + 0x00000000, 0x00000000, 0x00000000, 0xbe00004b, 0xfe0000d9, + 0x96000000, 0x49000000, 0xf70000a8, 0xfb0000cb, 0xea000055, + 0x82000005, 0x48000000, 0x44000000, 0x88000000, 0x9e000000, + 0x5d000000, 0xff0000da, 0xd0000049, 0x49000000, 0x00000000, + 0x00000000, 0x00000000, 0xbe00004b, 0xfe0000d9, 0x96000000, + 0x49000000, 0xf70000a8, 0xfb0000cb, 0xea000055, 0x82000005, + 0x48000000, 0x44000000, 0x88000000, 0x9e000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x49000000, + 0xf70000a8, 0xfb0000cb, 0xea000055, 0x82000005, 0x48000000, + 0x44000000, 0x88000000, 0x9e000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xd1000028, 0x3c000000, 0x00000000, 0x00000000, + 0x90000011, 0xff0000fc, 0xaf000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x5b000000, + 0xff0000da, 0xd0000049, 0x49000000, 0x00000000, 0x00000000, + 0x00000000, 0xb0000037, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x5b000000, 0xff0000da, 0xd0000049, 0x49000000, + 0x00000000, 0x00000000, 0x00000000, 0xb0000037, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x00000000, 0x2d000000, + 0x60000000, 0x81000000, 0x88000000, 0xc4000000, 0xff0000f6, + 0xb3000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, 0x00000000, + 0x7a000000, 0xff0000f6, 0xff0000ff, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ee, 0xa8000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x14000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xbf000000, + 0x00000000, 0x7a000000, 0xff0000f6, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ee, + 0xa8000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000001, + 0x1b000000, 0x00000000, 0x00000000, 0x00000000, 0x92000013, + 0xff0000f6, 0xb3000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x0d000000, 0x00000000, 0x00000000, 0x00000000, + 0x78000000, 0xff0000f6, 0xc0000012, 0x25000000, 0x00000000, + 0x00000000, 0x00000000, 0x92000013, 0xff0000f6, 0xb4000000, + 0x00000000, 0x8f000007, 0xf900007e, 0xfc0000dd, 0xff0000f2, + 0xfb0000c2, 0xf200005c, 0x72000001, 0x00000000, 0x78000000, + 0xff0000f6, 0xc0000012, 0x25000000, 0x00000000, 0x00000000, + 0x00000000, 0x92000013, 0xff0000f6, 0xb4000000, 0x00000000, + 0x8f000007, 0xf900007e, 0xfc0000dd, 0xff0000f2, 0xfb0000c2, + 0xf200005c, 0x72000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8f000007, + 0xf900007e, 0xfc0000dd, 0xff0000f2, 0xfb0000c2, 0xf200005c, + 0x72000001, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x14000000, 0x00000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xbf000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x78000000, 0xff0000f6, + 0xc0000012, 0x25000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000001, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x78000000, 0xff0000f6, 0xc0000012, 0x25000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000001, 0xff0000ff, 0xc0000000, + 0x00000000, 0x01000000, 0xa1000010, 0xfe00007f, 0xfe0000c1, + 0xff0000f9, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xbd000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x00000000, 0x69000000, + 0xff0000d9, 0xe8000028, 0xbb000000, 0xbb000000, 0xbb000000, + 0xbb000000, 0xda000000, 0xff000000, 0xc1000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x69000000, 0xff0000d9, 0xe8000028, 0xbb000000, 0xbb000000, + 0xbb000000, 0xbb000000, 0xda000000, 0xff000000, 0xc1000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xd300002b, 0x01000000, + 0x00000000, 0x00000000, 0x00000000, 0xbe00004b, 0xfe0000d8, + 0xb1000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x5d000000, + 0xff0000da, 0xdc00004a, 0x09000000, 0x00000000, 0x00000000, + 0x00000000, 0xbe00004b, 0xfe0000d9, 0xb1000000, 0x44000000, + 0x88000000, 0x65000000, 0x84000000, 0xc8000014, 0xf4000059, + 0xfc0000cc, 0xfb000098, 0x40000000, 0x5d000000, 0xff0000da, + 0xdc00004a, 0x09000000, 0x00000000, 0x00000000, 0x00000000, + 0xbe00004b, 0xfe0000d9, 0xb1000000, 0x44000000, 0x88000000, + 0x65000000, 0x84000000, 0xc8000014, 0xf4000059, 0xfc0000cc, + 0xfb000098, 0x40000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x44000000, 0x88000000, 0x65000000, + 0x84000000, 0xc8000014, 0xf4000059, 0xfc0000cc, 0xfb000098, + 0x40000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x5b000000, 0xff0000da, 0xdc000049, + 0x09000000, 0x00000000, 0x00000000, 0x00000000, 0xa700002c, + 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, 0x7e000000, + 0xff0000fc, 0xc7000011, 0x00000000, 0x00000000, 0x00000000, + 0xa500002a, 0xff0000ff, 0xc0000000, 0x00000000, 0x5b000000, + 0xff0000da, 0xdc000049, 0x09000000, 0x00000000, 0x00000000, + 0x00000000, 0xa700002c, 0xff0000ff, 0xc0000000, 0x00000000, + 0x48000000, 0xff000083, 0xfb0000a8, 0xc7000038, 0xb500000a, + 0xba000000, 0xdd000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x7f000000, 0xff0000fd, 0xc0000002, + 0x00000000, 0x43000000, 0x88000000, 0x71000000, 0xff000097, + 0xf4000080, 0x1b000000, 0x00000000, 0x00000000, 0x08000000, + 0xe0000059, 0xff0000b5, 0x55000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, 0x2b000000, + 0xff000097, 0xf4000080, 0x1b000000, 0x00000000, 0x00000000, + 0x08000000, 0xe0000059, 0xff0000b5, 0x55000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xf7000083, 0x1f000000, 0x00000000, + 0x00000000, 0x18000000, 0xf9000096, 0xff000097, 0x83000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x2b000000, 0xff00009b, + 0xfb000095, 0x39000000, 0x00000000, 0x00000000, 0x18000000, + 0xf9000096, 0xff00009b, 0x85000000, 0x80000000, 0xff0000ff, + 0xba00003a, 0x00000000, 0x00000000, 0x0b000000, 0xc1000027, + 0xff0000e2, 0x9d000000, 0x2b000000, 0xff00009b, 0xfb000095, + 0x39000000, 0x00000000, 0x00000000, 0x18000000, 0xf9000096, + 0xff00009b, 0x85000000, 0x80000000, 0xff0000ff, 0xba00003a, + 0x00000000, 0x00000000, 0x0b000000, 0xc1000027, 0xff0000e2, + 0x9d000000, 0x00000000, 0x44000000, 0x88000000, 0x45000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xba00003a, 0x00000000, + 0x00000000, 0x0b000000, 0xc1000027, 0xff0000e2, 0x9d000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000000, 0xff0000ff, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x2a000000, 0xff000099, 0xfb000092, 0x38000000, + 0x00000000, 0x00000000, 0x0b000000, 0xf0000084, 0xff0000ff, + 0xc0000000, 0x00000000, 0x00000000, 0x67000000, 0xfe0000c2, + 0xdf000048, 0x09000000, 0x00000000, 0x07000000, 0xec00007a, + 0xff0000ff, 0xc0000000, 0x00000000, 0x2a000000, 0xff000099, + 0xfb000092, 0x38000000, 0x00000000, 0x00000000, 0x0b000000, + 0xf0000084, 0xff0000ff, 0xc0000000, 0x00000000, 0x76000000, + 0xff0000e1, 0xbd000026, 0x54000000, 0x1c000000, 0x05000000, + 0x98000015, 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, + 0x44000000, 0x88000000, 0x88000000, 0x44000000, 0x00000000, + 0x00000000, 0x66000000, 0xff0000c1, 0xee000050, 0x8e00000d, + 0xe400005a, 0xfe0000c7, 0x66000000, 0xad000015, 0xff0000d3, + 0xf200007f, 0xaa00002d, 0x9d00001d, 0xe6000061, 0xff0000e9, + 0xe9000025, 0x60000000, 0x44000000, 0xc4000000, 0xff0000ff, + 0xe2000000, 0x44000000, 0x00000000, 0x44000000, 0xc4000000, + 0xff0000ff, 0xe2000000, 0x44000000, 0x00000000, 0xad000015, + 0xff0000d3, 0xf200007f, 0xaa00002d, 0x9d00001d, 0xe6000061, + 0xff0000e9, 0xe9000025, 0x60000000, 0x44000000, 0xc4000000, + 0xff0000ff, 0xff0000cc, 0xf3000083, 0xa900002b, 0xac000033, + 0xf5000099, 0xff0000e1, 0xc9000017, 0x4c000000, 0x44000000, + 0xc4000000, 0xff0000ff, 0xe2000000, 0x88000000, 0x44000000, + 0x00000000, 0x00000000, 0x00000000, 0xb800001a, 0xff0000e4, + 0xf8000099, 0xac000033, 0xac000033, 0xf5000099, 0xff0000e4, + 0xcc00001a, 0x4e000000, 0x80000000, 0xff0000ff, 0xfc0000c5, + 0xcf00004a, 0x91000010, 0xab00002c, 0xfa00009d, 0xff000074, + 0x95000000, 0x00000000, 0xb800001a, 0xff0000e4, 0xf8000099, + 0xac000033, 0xac000033, 0xf5000099, 0xff0000e4, 0xcc00001a, + 0x4e000000, 0x80000000, 0xff0000ff, 0xfc0000c5, 0xcf00004a, + 0x91000010, 0xab00002c, 0xfa00009d, 0xff000074, 0x95000000, + 0x00000000, 0x8e000009, 0xff0000e8, 0x72000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0xff0000ff, 0xfc0000c5, 0xcf00004a, 0x91000010, + 0xab00002c, 0xfa00009d, 0xff000074, 0x95000000, 0x44000000, + 0xc4000000, 0xff0000ff, 0xe2000000, 0x44000000, 0x44000000, + 0xc4000000, 0xff0000ff, 0xe2000000, 0x44000000, 0x00000000, + 0x44000000, 0xc4000000, 0xff0000ff, 0xe2000000, 0x44000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xb8000019, 0xff0000e2, 0xf7000097, 0xab000032, + 0xa900002b, 0xef000083, 0xff0000cc, 0xff0000ff, 0xe2000000, + 0x44000000, 0x00000000, 0x30000000, 0xf9000076, 0xfd0000ba, + 0xc4000041, 0x9c00001c, 0xe9000076, 0xff0000b0, 0xff0000ff, + 0xe2000000, 0x44000000, 0x00000000, 0xb8000019, 0xff0000e2, + 0xf7000097, 0xab000032, 0xa900002b, 0xef000083, 0xff0000cc, + 0xff0000ff, 0xe2000000, 0x44000000, 0x47000000, 0xfd000086, + 0xfd0000af, 0xbd000038, 0x8f00000e, 0xc000003c, 0xfe0000b5, + 0xff0000ff, 0xe2000000, 0x44000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xff0000ff, 0x80000000, 0x00000000, 0x00000000, + 0x15000000, 0xee000046, 0xff0000bd, 0xff0000ef, 0xfd0000be, + 0xeb00003f, 0x6f000000, 0x0e000000, 0xc0000018, 0xff0000a4, + 0xff0000e1, 0xff0000e5, 0xfc00009b, 0xec000042, 0x8d000000, + 0x13000000, 0x80000000, 0xff0000ff, 0xff0000ff, 0xff0000ff, + 0x80000000, 0x00000000, 0x80000000, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0x80000000, 0x00000000, 0x0e000000, 0xc0000018, + 0xff0000a4, 0xff0000e1, 0xff0000e5, 0xfc00009b, 0xec000042, + 0x8d000000, 0x13000000, 0x80000000, 0xff0000ff, 0xff0000ff, + 0xfa00001a, 0xff0000ad, 0xff0000e4, 0xff0000e9, 0xff0000ad, + 0xd100001d, 0x78000000, 0x0c000000, 0x80000000, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0x80000000, 0x00000000, + 0x00000000, 0x00000000, 0x13000000, 0xcd00001f, 0xff0000ae, + 0xff0000e8, 0xff0000e8, 0xff0000ae, 0xd900001f, 0x7d000000, + 0x0d000000, 0x36000000, 0xd300003b, 0xfb0000aa, 0xff0000e1, + 0xff0000f0, 0xff0000b6, 0xfc000076, 0xae000008, 0x3a000000, + 0x00000000, 0x13000000, 0xcd00001f, 0xff0000ae, 0xff0000e8, + 0xff0000e8, 0xff0000ae, 0xd900001f, 0x7d000000, 0x0d000000, + 0x36000000, 0xd300003b, 0xfb0000aa, 0xff0000e1, 0xff0000f0, + 0xff0000b6, 0xfc000076, 0xae000008, 0x3a000000, 0x00000000, + 0xba00002b, 0xff0000ba, 0x9f000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x36000000, + 0xd300003b, 0xfb0000aa, 0xff0000e1, 0xff0000f0, 0xff0000b6, + 0xfc000076, 0xae000008, 0x3a000000, 0x80000000, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0x80000000, 0x80000000, 0xff0000ff, + 0xff0000ff, 0xff0000ff, 0x80000000, 0x00000000, 0x80000000, + 0xff0000ff, 0xff0000ff, 0xff0000ff, 0x80000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x0f000000, 0xc300001e, 0xff0000ae, 0xff0000e9, 0xfe0000e5, + 0xff0000ae, 0xf600001a, 0xff0000ff, 0xff0000ff, 0x80000000, + 0x00000000, 0x00000000, 0x96000011, 0xfd000075, 0xff0000cc, + 0xff0000e6, 0xff0000a4, 0xf2000011, 0xff0000ff, 0xff0000ff, + 0x80000000, 0x00000000, 0x0f000000, 0xc300001e, 0xff0000ae, + 0xff0000e9, 0xfe0000e5, 0xff0000ae, 0xf600001a, 0xff0000ff, + 0xff0000ff, 0x80000000, 0x00000000, 0x9b000011, 0xfc000082, + 0xff0000cb, 0xff0000f2, 0xff0000ca, 0xfe000048, 0xff0000ff, + 0xff0000ff, 0x80000000, 0x00000000, 0x80000000, 0xff0000ff, + 0xff0000ff, 0xc0000000, 0x00000000, 0x00000000, 0x00000000, + 0x0f000000, 0x78000000, 0xaa000000, 0xaa000000, 0x68000000, + 0x20000000, 0x00000000, 0x00000000, 0x3b000000, 0x9f000000, + 0xb0000000, 0x9e000000, 0x51000000, 0x21000000, 0x00000000, + 0x3c000000, 0x77000000, 0xbb000000, 0xbb000000, 0x9e000000, + 0x00000000, 0x3c000000, 0x77000000, 0xbb000000, 0xbb000000, + 0x9e000000, 0x00000000, 0x00000000, 0x00000000, 0x3b000000, + 0x9f000000, 0xb0000000, 0x9e000000, 0x51000000, 0x21000000, + 0x00000000, 0x3c000000, 0x77000000, 0xbb000000, 0x9e000000, + 0x47000000, 0xa5000000, 0xb3000000, 0x95000000, 0x57000000, + 0x0f000000, 0x00000000, 0x3c000000, 0x77000000, 0xbb000000, + 0xbb000000, 0xbb000000, 0x9e000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x47000000, 0xa5000000, + 0xb4000000, 0x94000000, 0x57000000, 0x10000000, 0x00000000, + 0x00000000, 0x00000000, 0x4a000000, 0x96000000, 0xb2000000, + 0xa8000000, 0x6e000000, 0x3b000000, 0x04000000, 0x00000000, + 0x00000000, 0x00000000, 0x47000000, 0xa5000000, 0xb4000000, + 0x94000000, 0x57000000, 0x10000000, 0x00000000, 0x00000000, + 0x00000000, 0x4a000000, 0x96000000, 0xb2000000, 0xa8000000, + 0x6e000000, 0x3b000000, 0x04000000, 0x13000000, 0xf600007d, + 0xf900006e, 0x66000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x4a000000, 0x96000000, 0xb2000000, 0xa8000000, 0x6e000000, + 0x3b000000, 0x04000000, 0x3c000000, 0x77000000, 0xbb000000, + 0xbb000000, 0x9e000000, 0x3c000000, 0x77000000, 0xbb000000, + 0xbb000000, 0x9e000000, 0x00000000, 0x3c000000, 0x77000000, + 0xbb000000, 0xbb000000, 0x9e000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x47000000, 0xa5000000, 0xb5000000, 0x94000000, + 0x7f000000, 0x7e000000, 0xbb000000, 0x9e000000, 0x00000000, + 0x00000000, 0x00000000, 0x3d000000, 0x8d000000, 0xaa000000, + 0x93000000, 0x7b000000, 0x7c000000, 0xbb000000, 0x9e000000, + 0x00000000, 0x00000000, 0x00000000, 0x47000000, 0xa5000000, + 0xb5000000, 0x94000000, 0x7f000000, 0x7e000000, 0xbb000000, + 0x9e000000, 0x00000000, 0x00000000, 0x35000000, 0x8d000000, + 0xaa000000, 0xa1000000, 0x8e000000, 0x8a000000, 0xbb000000, + 0x9e000000, 0x00000000, 0x3c000000, 0x77000000, 0xbb000000, + 0x9e000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x6d000000, 0xff000097, 0x9c000002, + 0x37000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x06000000, 0x79000000, 0x4d000000, 0x01000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +void subpicture_get_info(VideoSubpictureInfo *info) +{ + info->width = SUBPICTURE_WIDTH; + info->height = SUBPICTURE_HEIGHT; + info->data = text; + info->data_size = SUBPICTURE_DATA_SIZE; +} diff --git a/tests/test-subpicture-data.h b/tests/test-subpicture-data.h new file mode 100644 index 0000000000..cc37988aa5 --- /dev/null +++ b/tests/test-subpicture-data.h @@ -0,0 +1,40 @@ +/* + * test-subpicture-data.h - subpicture data + * + * Copyright (C) <2011> Intel Corporation + * Copyright (C) <2011> Collabora Ltd. + * Copyright (C) <2011> Thibault Saunier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef TEST_SUBPICTURE_DATA +#define TEST_SUBPICTURE_DATA + +#include +#include "test-decode.h" + +typedef struct _VideoSubpictureInfo VideoSubpictureInfo; + +struct _VideoSubpictureInfo { + guint width; + guint height; + const guint32 *data; + guint data_size; +}; + +void subpicture_get_info(VideoSubpictureInfo *info); + +#endif /* TEST_SUBPICTURE_DATA*/ diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c new file mode 100644 index 0000000000..ee01709c09 --- /dev/null +++ b/tests/test-subpicture.c @@ -0,0 +1,207 @@ +/* + * test-subpicture.c - Test GstVaapiSubpicture + * + * Copyright (C) <2011> Intel Corporation + * Copyright (C) <2011> Collabora Ltd. + * Copyright (C) <2011> Thibault Saunier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include +#include "test-h264.h" +#include "test-subpicture-data.h" + +typedef void (*GetVideoInfoFunc)(VideoDecodeInfo *info); + +typedef struct _CodecDefs CodecDefs; +struct _CodecDefs { + const gchar *codec_str; + GetVideoInfoFunc get_video_info; +}; + +static const CodecDefs g_codec_defs[] = { +#define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info } + INIT_FUNCS(h264), +#undef INIT_FUNCS + { NULL, } +}; + +static const CodecDefs * +get_codec_defs(const gchar *codec_str) +{ + const CodecDefs *c; + for (c = g_codec_defs; c->codec_str; c++) + if (strcmp(codec_str, c->codec_str) == 0) + return c; + return NULL; +} + +static inline void pause(void) +{ + g_print("Press any key to continue...\n"); + getchar(); +} + +static gchar *g_codec_str; + +static GOptionEntry g_options[] = { + { "codec", 'c', + 0, + G_OPTION_ARG_STRING, &g_codec_str, + "codec to test", NULL }, + { NULL, } +}; + +int +main(int argc, char *argv[]) +{ + GOptionContext *options; + GstVaapiDisplay *display; + GstVaapiWindow *window; + GstVaapiDecoder *decoder; + GstCaps *decoder_caps; + GstStructure *structure; + GstVaapiDecoderStatus status; + const CodecDefs *codec; + GstBuffer *buffer; + GstVaapiSurfaceProxy *proxy; + VideoDecodeInfo info; + VideoSubpictureInfo subinfo; + GstVaapiImage *subtitle_image; + GstVaapiSubpicture *subpicture; + GstCaps *argbcaps; + GstVaapiRectangle sub_rect; + + static const guint win_width = 640; + static const guint win_height = 480; + + gst_init(&argc, &argv); + + options = g_option_context_new(" - test-decode options"); + g_option_context_add_main_entries(options, g_options, NULL); + g_option_context_parse(options, &argc, &argv, NULL); + g_option_context_free(options); + + if (!g_codec_str) + g_codec_str = g_strdup("h264"); + + g_print("Test %s decode\n", g_codec_str); + codec = get_codec_defs(g_codec_str); + if (!codec) + g_error("no %s codec data found", g_codec_str); + + display = gst_vaapi_display_x11_new(NULL); + if (!display) + g_error("could not create VA display"); + + window = gst_vaapi_window_x11_new(display, win_width, win_height); + if (!window) + g_error("could not create window"); + + codec->get_video_info(&info); + decoder_caps = gst_vaapi_profile_get_caps(info.profile); + if (!decoder_caps) + g_error("could not create decoder caps"); + + structure = gst_caps_get_structure(decoder_caps, 0); + if (info.width > 0 && info.height > 0) + gst_structure_set( + structure, + "width", G_TYPE_INT, info.width, + "height", G_TYPE_INT, info.height, + NULL + ); + + decoder = gst_vaapi_decoder_ffmpeg_new(display, decoder_caps); + if (!decoder) + g_error("could not create FFmpeg decoder"); + gst_caps_unref(decoder_caps); + + buffer = gst_buffer_new(); + if (!buffer) + g_error("could not create encoded data buffer"); + gst_buffer_set_data(buffer, (guchar *)info.data, info.data_size); + + if (!gst_vaapi_decoder_put_buffer(decoder, buffer)) + g_error("could not send video data to the decoder"); + gst_buffer_unref(buffer); + + if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) + g_error("could not send EOS to the decoder"); + + proxy = gst_vaapi_decoder_get_surface(decoder, &status); + if (!proxy) + g_error("could not get decoded surface (decoder status %d)", status); + + subpicture_get_info (&subinfo); + + /* Adding subpicture */ + argbcaps = gst_caps_new_simple ("video/x-raw-rgb", + "endianness", G_TYPE_INT, 1, + "bpp", G_TYPE_INT, 32, + "width", G_TYPE_INT, subinfo.width, + "height", G_TYPE_INT, subinfo.height, + NULL); + + buffer = gst_buffer_new (); + gst_buffer_set_data(buffer, (guchar *)subinfo.data, subinfo.data_size); + gst_buffer_set_caps (buffer, argbcaps); + + subtitle_image = gst_vaapi_image_new (display, + GST_VAAPI_IMAGE_RGBA, subinfo.width, subinfo.height); + + gst_vaapi_image_update_from_buffer (subtitle_image, buffer); + + subpicture = gst_vaapi_subpicture_new (subtitle_image); + + /* We position it as a subtitle, centered at the bottom. */ + sub_rect.x = (win_width - subinfo.width) / 2; + sub_rect.y = win_height - subinfo.height - 10; + sub_rect.height = subinfo.height; + sub_rect.width = subinfo.height; + + if (!gst_vaapi_surface_associate_subpicture ( + GST_VAAPI_SURFACE_PROXY_SURFACE(proxy), + subpicture, + NULL, + &sub_rect)) + g_error("could not associate subpicture"); + + gst_vaapi_window_show(window); + + if (!gst_vaapi_window_put_surface(window, + GST_VAAPI_SURFACE_PROXY_SURFACE(proxy), + NULL, + NULL, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + g_error("could not render surface"); + + pause(); + + gst_buffer_unref(buffer); + g_object_unref(proxy); + g_object_unref(decoder); + g_object_unref(window); + g_object_unref(display); + g_free(g_codec_str); + gst_deinit(); + return 0; +} From b4ca838fb070daaf5b01e97c7723684db1db3395 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 17 Oct 2011 18:43:15 +0200 Subject: [PATCH 0487/3781] tests: fix subpicture test. --- tests/test-subpicture.c | 47 ++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index ee01709c09..86f0ad1baf 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -70,6 +70,19 @@ static GOptionEntry g_options[] = { { NULL, } }; +static void +upload_image (guint8 *dst, const guint32 *src, guint size) +{ + guint i; + + for (i = 0; i < size; i += 4) { + dst[i ] = *src >> 24; + dst[i + 1] = *src >> 16; + dst[i + 2] = *src >> 8; + dst[i + 3] = *src++; + } +} + int main(int argc, char *argv[]) { @@ -83,12 +96,14 @@ main(int argc, char *argv[]) const CodecDefs *codec; GstBuffer *buffer; GstVaapiSurfaceProxy *proxy; + GstVaapiSurface *surface; VideoDecodeInfo info; VideoSubpictureInfo subinfo; GstVaapiImage *subtitle_image; GstVaapiSubpicture *subpicture; - GstCaps *argbcaps; - GstVaapiRectangle sub_rect; + GstCaps *argbcaps; + GstVaapiRectangle sub_rect; + guint surf_width, surf_height; static const guint win_width = 640; static const guint win_height = 480; @@ -151,35 +166,47 @@ main(int argc, char *argv[]) if (!proxy) g_error("could not get decoded surface (decoder status %d)", status); + surface = gst_vaapi_surface_proxy_get_surface(proxy); + if (!surface) + g_error("could not get underlying surface"); + + gst_vaapi_surface_get_size(surface, &surf_width, &surf_height); + printf("surface size %dx%d\n", surf_width, surf_height); + subpicture_get_info (&subinfo); /* Adding subpicture */ argbcaps = gst_caps_new_simple ("video/x-raw-rgb", - "endianness", G_TYPE_INT, 1, + "endianness", G_TYPE_INT, G_BIG_ENDIAN, "bpp", G_TYPE_INT, 32, + "red_mask", G_TYPE_INT, 0xff000000, + "green_mask", G_TYPE_INT, 0x00ff0000, + "blue_mask", G_TYPE_INT, 0x0000ff00, + "alpha_mask", G_TYPE_INT, 0x000000ff, "width", G_TYPE_INT, subinfo.width, "height", G_TYPE_INT, subinfo.height, NULL); - buffer = gst_buffer_new (); - gst_buffer_set_data(buffer, (guchar *)subinfo.data, subinfo.data_size); + buffer = gst_buffer_new_and_alloc (subinfo.data_size); + upload_image (GST_BUFFER_DATA (buffer), subinfo.data, subinfo.data_size); gst_buffer_set_caps (buffer, argbcaps); subtitle_image = gst_vaapi_image_new (display, GST_VAAPI_IMAGE_RGBA, subinfo.width, subinfo.height); - gst_vaapi_image_update_from_buffer (subtitle_image, buffer); + if (!gst_vaapi_image_update_from_buffer (subtitle_image, buffer)) + g_error ("could not update VA image with subtitle data"); subpicture = gst_vaapi_subpicture_new (subtitle_image); /* We position it as a subtitle, centered at the bottom. */ - sub_rect.x = (win_width - subinfo.width) / 2; - sub_rect.y = win_height - subinfo.height - 10; + sub_rect.x = (surf_width - subinfo.width) / 2; + sub_rect.y = surf_height - subinfo.height - 10; sub_rect.height = subinfo.height; - sub_rect.width = subinfo.height; + sub_rect.width = subinfo.width; if (!gst_vaapi_surface_associate_subpicture ( - GST_VAAPI_SURFACE_PROXY_SURFACE(proxy), + surface, subpicture, NULL, &sub_rect)) From 697b96c30c451ce43b4cdbb90142f77faaff8f9b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Dec 2011 13:39:20 +0100 Subject: [PATCH 0488/3781] display: fix has_image_format() to check against subpicture formats. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index ea0780d3ff..b4da1624b6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -893,7 +893,14 @@ gst_vaapi_display_has_image_format( g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); g_return_val_if_fail(format, FALSE); - return find_format(display->priv->image_formats, format); + if (find_format(display->priv->image_formats, format)) + return TRUE; + + /* XXX: try subpicture formats since some drivers could report a + * set of VA image formats that is not a superset of the set of VA + * subpicture formats + */ + return find_format(display->priv->subpicture_formats, format); } /** From 6352c7d5fa830975562e221dce8fdb0a8a4239d3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Dec 2011 15:31:52 +0100 Subject: [PATCH 0489/3781] subpicture: fix doc for gst_vaapi_subpicture_set_image(). --- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 046aa68aca..1f3f4b7248 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -256,7 +256,7 @@ gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture) * @image: a #GstVaapiImage * * Binds a new #GstVaapiImage to the @subpicture. The reference to the - * previous image is released a new one acquired on @image. + * previous image is released and a new one is acquired on @image. */ void gst_vaapi_subpicture_set_image( From 9337fb9a74a700026a139f622156ea676bacc138 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Dec 2011 14:34:03 +0100 Subject: [PATCH 0490/3781] image: allow partial updates. --- gst-libs/gst/vaapi/gstvaapiimage.c | 298 ++++++++++++++++++++++------- gst-libs/gst/vaapi/gstvaapiimage.h | 22 ++- gst/vaapi/gstvaapiconvert.c | 2 +- tests/test-subpicture.c | 2 +- 4 files changed, 252 insertions(+), 72 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index c9096035ac..584d4157e4 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -70,7 +70,7 @@ enum { } while (0) static gboolean -_gst_vaapi_image_map(GstVaapiImage *image); +_gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image); static gboolean _gst_vaapi_image_unmap(GstVaapiImage *image); @@ -744,15 +744,17 @@ gst_vaapi_image_map(GstVaapiImage *image) g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); g_return_val_if_fail(image->priv->is_constructed, FALSE); - return _gst_vaapi_image_map(image); + return _gst_vaapi_image_map(image, NULL); } gboolean -_gst_vaapi_image_map(GstVaapiImage *image) +_gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image) { + GstVaapiImagePrivate * const priv = image->priv; GstVaapiDisplay *display; void *image_data; VAStatus status; + guint i; if (_gst_vaapi_image_is_mapped(image)) return TRUE; @@ -772,6 +774,18 @@ _gst_vaapi_image_map(GstVaapiImage *image) return FALSE; image->priv->image_data = image_data; + + if (raw_image) { + const VAImage * const va_image = &priv->image; + raw_image->format = priv->format; + raw_image->width = va_image->width; + raw_image->height = va_image->height; + raw_image->num_planes = va_image->num_planes; + for (i = 0; i < raw_image->num_planes; i++) { + raw_image->pixels[i] = image_data + va_image->offsets[i]; + raw_image->stride[i] = va_image->pitches[i]; + } + } return TRUE; } @@ -899,10 +913,159 @@ gst_vaapi_image_get_data_size(GstVaapiImage *image) return image->priv->image.data_size; } +/* Copy N lines of an image */ +static inline void +memcpy_pic( + guchar *dst, + guint dst_stride, + const guchar *src, + guint src_stride, + guint len, + guint height +) +{ + guint i; + + for (i = 0; i < height; i++) { + memcpy(dst, src, len); + dst += dst_stride; + src += dst_stride; + } +} + +/* Copy NV12 images */ +static void +copy_image_NV12( + GstVaapiImageRaw *dst_image, + GstVaapiImageRaw *src_image, + const GstVaapiRectangle *rect +) +{ + guchar *dst, *src; + guint dst_stride, src_stride; + + /* Y plane */ + dst_stride = dst_image->stride[0]; + dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x; + src_stride = src_image->stride[0]; + src = src_image->pixels[0] + rect->y * src_stride + rect->x; + memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height); + + /* UV plane */ + dst_stride = dst_image->stride[1]; + dst = dst_image->pixels[1] + (rect->y / 2) * dst_stride + (rect->x & -2); + src_stride = src_image->stride[1]; + src = src_image->pixels[1] + (rect->y / 2) * src_stride + (rect->x & -2); + memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height / 2); +} + +/* Copy YV12 images */ +static void +copy_image_YV12( + GstVaapiImageRaw *dst_image, + GstVaapiImageRaw *src_image, + const GstVaapiRectangle *rect +) +{ + guchar *dst, *src; + guint dst_stride, src_stride; + guint i, x, y, w, h; + + /* Y plane */ + dst_stride = dst_image->stride[0]; + dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x; + src_stride = src_image->stride[0]; + src = src_image->pixels[0] + rect->y * src_stride + rect->x; + memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height); + + /* U/V planes */ + x = rect->x / 2; + y = rect->y / 2; + w = rect->width / 2; + h = rect->height / 2; + for (i = 1; i < dst_image->num_planes; i++) { + dst_stride = dst_image->stride[i]; + dst = dst_image->pixels[i] + y * dst_stride + x; + src_stride = src_image->stride[i]; + src = src_image->pixels[i] + y * src_stride + x; + memcpy_pic(dst, dst_stride, src, src_stride, w, h); + } +} + +/* Copy RGBA images */ +static void +copy_image_RGBA( + GstVaapiImageRaw *dst_image, + GstVaapiImageRaw *src_image, + const GstVaapiRectangle *rect +) +{ + guchar *dst, *src; + guint dst_stride, src_stride; + + dst_stride = dst_image->stride[0]; + dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x; + src_stride = src_image->stride[0]; + src = src_image->pixels[0] + rect->y * src_stride + rect->x; + memcpy_pic(dst, dst_stride, src, src_stride, 4 * rect->width, rect->height); +} + +static gboolean +copy_image( + GstVaapiImageRaw *dst_image, + GstVaapiImageRaw *src_image, + const GstVaapiRectangle *rect +) +{ + GstVaapiRectangle default_rect; + + if (dst_image->format != src_image->format || + dst_image->width != src_image->width || + dst_image->height != src_image->height) + return FALSE; + + if (rect) { + if (rect->x >= src_image->width || + rect->x + src_image->width > src_image->width || + rect->y >= src_image->height || + rect->y + src_image->height > src_image->height) + return FALSE; + } + else { + default_rect.x = 0; + default_rect.y = 0; + default_rect.width = src_image->width; + default_rect.height = src_image->height; + rect = &default_rect; + } + + switch (dst_image->format) { + case GST_VAAPI_IMAGE_NV12: + copy_image_NV12(dst_image, src_image, rect); + break; + case GST_VAAPI_IMAGE_YV12: + case GST_VAAPI_IMAGE_I420: + copy_image_YV12(dst_image, src_image, rect); + break; + case GST_VAAPI_IMAGE_ARGB: + case GST_VAAPI_IMAGE_RGBA: + case GST_VAAPI_IMAGE_ABGR: + case GST_VAAPI_IMAGE_BGRA: + copy_image_RGBA(dst_image, src_image, rect); + break; + default: + GST_ERROR("unsupported image format for copy"); + return FALSE; + } + return TRUE; +} + /** * gst_vaapi_image_update_from_buffer: * @image: a #GstVaapiImage * @buffer: a #GstBuffer + * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the + * whole image * * Transfers pixels data contained in the #GstBuffer into the * @image. Both image structures shall have the same format. @@ -910,17 +1073,22 @@ gst_vaapi_image_get_data_size(GstVaapiImage *image) * Return value: %TRUE on success */ gboolean -gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) +gst_vaapi_image_update_from_buffer( + GstVaapiImage *image, + GstBuffer *buffer, + GstVaapiRectangle *rect +) { GstVaapiImagePrivate *priv; GstStructure *structure; GstCaps *caps; GstVaapiImageFormat format; + GstVaapiImageRaw dst_image, src_image; + guint width2, height2, size2; gint width, height; - guint offsets[3], pitches[3], widths[3], heights[3]; - guint i, j; guchar *data; guint32 data_size; + gboolean success; g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); g_return_val_if_fail(image->priv->is_constructed, FALSE); @@ -944,74 +1112,66 @@ gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer) if (width != priv->width || height != priv->height) return FALSE; - if (!gst_vaapi_image_map(image)) + if (!_gst_vaapi_image_map(image, &dst_image)) return FALSE; - if (priv->is_linear && data_size == priv->image.data_size) - memcpy(priv->image_data, data, data_size); - else { - /* XXX: copied from gst_video_format_get_row_stride() -- no NV12? */ - const guint width2 = (width + 1) / 2; - const guint height2 = (height + 1) / 2; - guint size2; - switch (format) { - case GST_VAAPI_IMAGE_NV12: - offsets[0] = 0; - pitches[0] = GST_ROUND_UP_4(width); - widths [0] = width; - heights[0] = height; - offsets[1] = offsets[0] + height * pitches[0]; - pitches[1] = pitches[0]; - widths [1] = width2 * 2; - heights[1] = height2; - size2 = offsets[1] + height2 * pitches[1]; - break; - case GST_VAAPI_IMAGE_YV12: - case GST_VAAPI_IMAGE_I420: - offsets[0] = 0; - pitches[0] = GST_ROUND_UP_4(width); - widths [0] = width; - heights[0] = height; - offsets[1] = offsets[0] + height * pitches[0]; - pitches[1] = GST_ROUND_UP_4(GST_ROUND_UP_2(width) / 2); - widths [1] = width2; - heights[1] = height2; - offsets[2] = offsets[1] + height2 * pitches[1]; - pitches[2] = pitches[1]; - widths [2] = width2; - heights[2] = height2; - size2 = offsets[2] + height2 * pitches[2]; - break; - case GST_VAAPI_IMAGE_ARGB: - case GST_VAAPI_IMAGE_RGBA: - case GST_VAAPI_IMAGE_ABGR: - case GST_VAAPI_IMAGE_BGRA: - offsets[0] = 0; - pitches[0] = width * 4; - widths [0] = width * 4; - heights[0] = height; - size2 = offsets[0] + height * pitches[0]; - break; - default: - g_error("could not compute row-stride for %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS(format)); - break; - } - if (size2 != data_size) - g_error("data_size mismatch %d / %u", size2, data_size); - for (i = 0; i < priv->image.num_planes; i++) { - guchar *src = data + offsets[i]; - guchar *dst = priv->image_data + priv->image.offsets[i]; - for (j = 0; j < heights[i]; j++) { - memcpy(dst, src, widths[i]); - src += pitches[i]; - dst += priv->image.pitches[i]; - } + /* XXX: copied from gst_video_format_get_row_stride() -- no NV12? */ + src_image.format = priv->format; + src_image.width = width; + src_image.height = height; + width2 = (width + 1) / 2; + height2 = (height + 1) / 2; + size2 = 0; + switch (format) { + case GST_VAAPI_IMAGE_NV12: + src_image.num_planes = 2; + src_image.pixels[0] = data; + src_image.stride[0] = GST_ROUND_UP_4(width); + size2 += height * src_image.stride[0]; + src_image.pixels[1] = data + size2; + src_image.stride[1] = src_image.stride[1]; + size2 += height2 * src_image.stride[1]; + break; + case GST_VAAPI_IMAGE_YV12: + case GST_VAAPI_IMAGE_I420: + src_image.num_planes = 3; + src_image.pixels[0] = data; + src_image.stride[0] = GST_ROUND_UP_4(width); + size2 += height * src_image.stride[0]; + src_image.pixels[1] = data + size2; + src_image.stride[1] = GST_ROUND_UP_4(width2); + size2 += height2 * src_image.stride[1]; + src_image.pixels[2] = data + size2; + src_image.stride[2] = src_image.stride[1]; + size2 += height2 * src_image.stride[2]; + break; + case GST_VAAPI_IMAGE_ARGB: + case GST_VAAPI_IMAGE_RGBA: + case GST_VAAPI_IMAGE_ABGR: + case GST_VAAPI_IMAGE_BGRA: + src_image.num_planes = 1; + src_image.pixels[0] = data; + src_image.stride[0] = width * 4; + size2 += height * src_image.stride[0]; + break; + default: + g_error("could not compute row-stride for %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS(format)); + break; + } + + if (size2 != data_size) { + g_error("data_size mismatch %d / %u", size2, data_size); + if (size2 > data_size) { + _gst_vaapi_image_unmap(image); + return FALSE; } } - if (!gst_vaapi_image_unmap(image)) + success = copy_image(&dst_image, &src_image, rect); + + if (!_gst_vaapi_image_unmap(image)) return FALSE; - return TRUE; + return success; } diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index f93bfa87d7..5710077a9e 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -80,6 +80,7 @@ G_BEGIN_DECLS typedef struct _GstVaapiImage GstVaapiImage; typedef struct _GstVaapiImagePrivate GstVaapiImagePrivate; typedef struct _GstVaapiImageClass GstVaapiImageClass; +typedef struct _GstVaapiImageRaw GstVaapiImageRaw; /** * GstVaapiImage: @@ -103,6 +104,21 @@ struct _GstVaapiImageClass { GstVaapiObjectClass parent_class; }; +/** + * GstVaapiImageRaw: + * + * A raw image wrapper. The caller is responsible for initializing all + * the fields with sensible values. + */ +struct _GstVaapiImageRaw { + GstVaapiImageFormat format; + guint width; + guint height; + guint num_planes; + guchar *pixels[3]; + guint stride[3]; +}; + GType gst_vaapi_image_get_type(void); @@ -160,7 +176,11 @@ guint gst_vaapi_image_get_data_size(GstVaapiImage *image); gboolean -gst_vaapi_image_update_from_buffer(GstVaapiImage *image, GstBuffer *buffer); +gst_vaapi_image_update_from_buffer( + GstVaapiImage *image, + GstBuffer *buffer, + GstVaapiRectangle *rect +); G_END_DECLS diff --git a/gst/vaapi/gstvaapiconvert.c b/gst/vaapi/gstvaapiconvert.c index f692b50f15..919eaba2ae 100644 --- a/gst/vaapi/gstvaapiconvert.c +++ b/gst/vaapi/gstvaapiconvert.c @@ -425,7 +425,7 @@ gst_vaapiconvert_transform( if (!image) return GST_FLOW_UNEXPECTED; - gst_vaapi_image_update_from_buffer(image, inbuf); + gst_vaapi_image_update_from_buffer(image, inbuf, NULL); success = gst_vaapi_surface_put_image(surface, image); gst_vaapi_video_pool_put_object(convert->images, image); if (!success) diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 86f0ad1baf..e273e919b2 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -194,7 +194,7 @@ main(int argc, char *argv[]) subtitle_image = gst_vaapi_image_new (display, GST_VAAPI_IMAGE_RGBA, subinfo.width, subinfo.height); - if (!gst_vaapi_image_update_from_buffer (subtitle_image, buffer)) + if (!gst_vaapi_image_update_from_buffer (subtitle_image, buffer, NULL)) g_error ("could not update VA image with subtitle data"); subpicture = gst_vaapi_subpicture_new (subtitle_image); From efcdec08fb26dd772b5c53a6c4370508c55425ff Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Dec 2011 16:34:07 +0100 Subject: [PATCH 0491/3781] image: allow updates from GstVaapiImageRaw. --- gst-libs/gst/vaapi/gstvaapiimage.c | 37 ++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiimage.h | 7 ++++++ 2 files changed, 44 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 584d4157e4..4b503cf9b1 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -1175,3 +1175,40 @@ gst_vaapi_image_update_from_buffer( return success; } + +/** + * gst_vaapi_image_update_from_raw: + * @image: a #GstVaapiImage + * @src_image: a #GstVaapiImageRaw + * @buffer: a #GstBuffer + * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the + * whole image + * + * Transfers pixels data contained in the #GstVaapiImageRaw into the + * @image. Both image structures shall have the same format. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_image_update_from_raw( + GstVaapiImage *image, + GstVaapiImageRaw *src_image, + GstVaapiRectangle *rect +) +{ + GstVaapiImageRaw dst_image; + gboolean success; + + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image->priv->is_constructed, FALSE); + + if (!_gst_vaapi_image_map(image, &dst_image)) + return FALSE; + + success = copy_image(&dst_image, src_image, rect); + + if (!_gst_vaapi_image_unmap(image)) + return FALSE; + + return success; +} diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 5710077a9e..5b6557f361 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -182,6 +182,13 @@ gst_vaapi_image_update_from_buffer( GstVaapiRectangle *rect ); +gboolean +gst_vaapi_image_update_from_raw( + GstVaapiImage *image, + GstVaapiImageRaw *src_image, + GstVaapiRectangle *rect +); + G_END_DECLS #endif /* GST_VAAPI_IMAGE_H */ From 55738da35b684b3ebffa3f3510e347cc654b1cd9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Dec 2011 18:13:19 +0100 Subject: [PATCH 0492/3781] image: add gst_vaapi_image_format_from_video() helper. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapiimageformat.c | 29 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiimageformat.h | 4 ++++ gst/vaapi/gstvaapiconvert.c | 21 +---------------- 5 files changed, 36 insertions(+), 20 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 722d6b4b4c..d271a26e32 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -377,6 +377,7 @@ gst_vaapi_image_format_is_yuv gst_vaapi_image_format gst_vaapi_image_format_from_caps gst_vaapi_image_format_from_fourcc +gst_vaapi_image_format_from_video gst_vaapi_image_format_get_va_format gst_vaapi_image_format_get_caps gst_vaapi_image_format_get_score diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 94995ec8e3..76771741ba 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -143,6 +143,7 @@ libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ -I$(top_srcdir)/gst-libs \ $(GST_BASE_CFLAGS) \ $(GST_BASEVIDEO_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ $(GST_CFLAGS) \ $(LIBAVCODEC_CFLAGS) \ $(LIBVA_CFLAGS) \ diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 9218c68776..cac410afd3 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -233,6 +233,35 @@ gst_vaapi_image_format_from_fourcc(guint32 fourcc) return (GstVaapiImageFormat)fourcc; } +/** + * gst_vaapi_image_format_from_video: + * @format: a #GstVideoFormat + * + * Converts a #GstVideoFormat into the corresponding + * #GstVaapiImageFormat. If the image format cannot be represented by + * #GstVaapiImageFormat, then zero is returned. + * + * Return value: the #GstVaapiImageFormat describing the video format + */ +GstVaapiImageFormat +gst_vaapi_image_format_from_video(GstVideoFormat format) +{ + GstVaapiImageFormat va_format; + + switch (format) { + case GST_VIDEO_FORMAT_NV12: va_format = GST_VAAPI_IMAGE_NV12; break; + case GST_VIDEO_FORMAT_YV12: va_format = GST_VAAPI_IMAGE_YV12; break; + case GST_VIDEO_FORMAT_I420: va_format = GST_VAAPI_IMAGE_I420; break; + case GST_VIDEO_FORMAT_AYUV: va_format = GST_VAAPI_IMAGE_AYUV; break; + case GST_VIDEO_FORMAT_ARGB: va_format = GST_VAAPI_IMAGE_ARGB; break; + case GST_VIDEO_FORMAT_RGBA: va_format = GST_VAAPI_IMAGE_RGBA; break; + case GST_VIDEO_FORMAT_ABGR: va_format = GST_VAAPI_IMAGE_ABGR; break; + case GST_VIDEO_FORMAT_BGRA: va_format = GST_VAAPI_IMAGE_BGRA; break; + default: va_format = (GstVaapiImageFormat)0; break; + } + return va_format; +} + /** * gst_vaapi_image_format_get_va_format: * @format: a #GstVaapiImageFormat diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index f83e3bacbc..da45341b63 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -23,6 +23,7 @@ #define GST_VAAPI_IMAGE_FORMAT_H #include +#include G_BEGIN_DECLS @@ -75,6 +76,9 @@ gst_vaapi_image_format_from_caps(GstCaps *caps); GstVaapiImageFormat gst_vaapi_image_format_from_fourcc(guint32 fourcc); +GstVaapiImageFormat +gst_vaapi_image_format_from_video(GstVideoFormat format); + const VAImageFormat * gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format); diff --git a/gst/vaapi/gstvaapiconvert.c b/gst/vaapi/gstvaapiconvert.c index 919eaba2ae..a0db024d40 100644 --- a/gst/vaapi/gstvaapiconvert.c +++ b/gst/vaapi/gstvaapiconvert.c @@ -542,25 +542,6 @@ gst_vaapiconvert_ensure_surface_pool(GstVaapiConvert *convert, GstCaps *caps) return TRUE; } -static GstVaapiImageFormat -gst_video_format_to_vaapi_image_format(GstVideoFormat vformat) -{ - GstVaapiImageFormat vaformat; - - switch (vformat) { - case GST_VIDEO_FORMAT_NV12: vaformat = GST_VAAPI_IMAGE_NV12; break; - case GST_VIDEO_FORMAT_YV12: vaformat = GST_VAAPI_IMAGE_YV12; break; - case GST_VIDEO_FORMAT_I420: vaformat = GST_VAAPI_IMAGE_I420; break; - case GST_VIDEO_FORMAT_AYUV: vaformat = GST_VAAPI_IMAGE_AYUV; break; - case GST_VIDEO_FORMAT_ARGB: vaformat = GST_VAAPI_IMAGE_ARGB; break; - case GST_VIDEO_FORMAT_RGBA: vaformat = GST_VAAPI_IMAGE_RGBA; break; - case GST_VIDEO_FORMAT_ABGR: vaformat = GST_VAAPI_IMAGE_ABGR; break; - case GST_VIDEO_FORMAT_BGRA: vaformat = GST_VAAPI_IMAGE_BGRA; break; - default: vaformat = (GstVaapiImageFormat)0; break; - } - return vaformat; -} - static void gst_vaapiconvert_ensure_direct_rendering_caps( GstVaapiConvert *convert, @@ -592,7 +573,7 @@ gst_vaapiconvert_ensure_direct_rendering_caps( return; if (!gst_video_format_is_yuv(vformat)) return; - vaformat = gst_video_format_to_vaapi_image_format(vformat); + vaformat = gst_vaapi_image_format_from_video(vformat); if (!vaformat) return; From c997607c6f34143af86d7a7a240a02aff3a60255 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 25 Nov 2011 14:59:56 -0500 Subject: [PATCH 0493/3781] surface: add helper to handle GstVideoOverlayComposition. This helper resets the subpictures to reflect the current composition layers provided with the buffers. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapisurface.c | 95 ++++++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapisurface.h | 7 ++ 2 files changed, 95 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 4d9c5b0f1f..f7e4b8c535 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -78,22 +78,29 @@ destroy_subpicture_cb(gpointer subpicture, gpointer surface) } static void -gst_vaapi_surface_destroy(GstVaapiSurface *surface) +gst_vaapi_surface_destroy_subpictures(GstVaapiSurface *surface) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface); GstVaapiSurfacePrivate * const priv = surface->priv; - VASurfaceID surface_id; - VAStatus status; - - surface_id = GST_VAAPI_OBJECT_ID(surface); - GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); if (priv->subpictures) { g_ptr_array_foreach(priv->subpictures, destroy_subpicture_cb, surface); g_ptr_array_free(priv->subpictures, TRUE); priv->subpictures = NULL; } +} +static void +gst_vaapi_surface_destroy(GstVaapiSurface *surface) +{ + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface); + VASurfaceID surface_id; + VAStatus status; + + surface_id = GST_VAAPI_OBJECT_ID(surface); + GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); + + gst_vaapi_surface_destroy_subpictures(surface); + if (surface_id != VA_INVALID_SURFACE) { GST_VAAPI_DISPLAY_LOCK(display); status = vaDestroySurfaces( @@ -790,3 +797,77 @@ gst_vaapi_surface_query_status( *pstatus = to_GstVaapiSurfaceStatus(surface_status); return TRUE; } + +/** + * gst_vaapi_surface_update_composition: + * @surface: a #GstVaapiSurface + * @compostion: a #GstVideoOverlayCompositon + * + * Helper to update the subpictures from #GstVideoOverlayCompositon. Sending + * a NULL composition will clear all the current subpictures. Note that this + * method will clear existing subpictures. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_surface_update_composition( + GstVaapiSurface *surface, + GstVideoOverlayComposition *composition +) +{ + GstVaapiDisplay *display; + guint n, nb_rectangles; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + + display = GST_VAAPI_OBJECT_DISPLAY(surface); + if (!display) + return FALSE; + + /* Clear current subpictures */ + gst_vaapi_surface_destroy_subpictures(surface); + + if (!composition) + return TRUE; + + nb_rectangles = gst_video_overlay_composition_n_rectangles (composition); + + /* Overlay all the rectangles cantained in the overlay composition */ + for (n = 0; n < nb_rectangles; ++n) { + GstBuffer *buf; + GstVideoOverlayRectangle *rect; + guint stride; + GstVaapiImage *subtitle_image; + GstVaapiRectangle sub_rect; + GstVaapiSubpicture *subpicture; + + rect = gst_video_overlay_composition_get_rectangle (composition, n); + buf = gst_video_overlay_rectangle_get_pixels_argb (rect, + &stride, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + + gst_video_overlay_rectangle_get_render_rectangle (rect, + (gint *)&sub_rect.x, (gint *)&sub_rect.y, + &sub_rect.width, &sub_rect.height); + subtitle_image = gst_vaapi_image_new (display, + GST_VAAPI_IMAGE_RGBA, sub_rect.width, sub_rect.height); + + if (!gst_vaapi_image_update_from_buffer (subtitle_image, buf, &sub_rect)) { + GST_WARNING ("could not update VA image with subtitle data"); + return FALSE; + } + + subpicture = gst_vaapi_subpicture_new (subtitle_image); + g_object_unref (subtitle_image); + + if (!gst_vaapi_surface_associate_subpicture (surface, subpicture, + NULL, &sub_rect)) { + GST_WARNING ("could not render overlay rectangle %p", rect); + g_object_unref (subpicture); + return FALSE; + } + + g_object_unref (subpicture); + } + + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 05dffcfdce..8a2b70b086 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -28,6 +28,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -228,6 +229,12 @@ gst_vaapi_surface_query_status( GstVaapiSurfaceStatus *pstatus ); +gboolean +gst_vaapi_surface_update_composition( + GstVaapiSurface *surface, + GstVideoOverlayComposition *composition +); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_H */ From 010f94b85d79e95dfc867e1a617eedf5650928d7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Dec 2011 18:37:13 +0100 Subject: [PATCH 0494/3781] surface: fix VA image leak when an error occurred. --- gst-libs/gst/vaapi/gstvaapisurface.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index f7e4b8c535..54bc432e08 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -853,6 +853,7 @@ gst_vaapi_surface_update_composition( if (!gst_vaapi_image_update_from_buffer (subtitle_image, buf, &sub_rect)) { GST_WARNING ("could not update VA image with subtitle data"); + g_object_unref (subtitle_image); return FALSE; } From b014567502f789d9f466d677bdc87f44db4ea3e8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Dec 2011 18:27:14 +0100 Subject: [PATCH 0495/3781] surface: use unscaled overlay rectangle for blending. --- gst-libs/gst/vaapi/gstvaapisurface.c | 38 ++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 54bc432e08..e07f71afef 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -836,26 +836,42 @@ gst_vaapi_surface_update_composition( for (n = 0; n < nb_rectangles; ++n) { GstBuffer *buf; GstVideoOverlayRectangle *rect; - guint stride; + guint width, height, stride; + GstVaapiImageFormat format; GstVaapiImage *subtitle_image; GstVaapiRectangle sub_rect; GstVaapiSubpicture *subpicture; + GstVaapiImageRaw raw_image; rect = gst_video_overlay_composition_get_rectangle (composition, n); - buf = gst_video_overlay_rectangle_get_pixels_argb (rect, - &stride, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + buf = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rect, + &width, &height, &stride, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + + /* XXX: use gst_vaapi_image_format_from_video() */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + format = GST_VAAPI_IMAGE_BGRA; +#else + format = GST_VAAPI_IMAGE_ARGB; +#endif + subtitle_image = gst_vaapi_image_new (display, format, width, height); + if (!subtitle_image) + return FALSE; + + raw_image.format = format; + raw_image.width = width; + raw_image.height = height; + raw_image.num_planes = 1; + raw_image.pixels[0] = GST_BUFFER_DATA(buf); + raw_image.stride[0] = stride; + if (!gst_vaapi_image_update_from_raw (subtitle_image, &raw_image, NULL)) { + GST_WARNING ("could not update VA image with subtitle data"); + g_object_unref (subtitle_image); + return FALSE; + } gst_video_overlay_rectangle_get_render_rectangle (rect, (gint *)&sub_rect.x, (gint *)&sub_rect.y, &sub_rect.width, &sub_rect.height); - subtitle_image = gst_vaapi_image_new (display, - GST_VAAPI_IMAGE_RGBA, sub_rect.width, sub_rect.height); - - if (!gst_vaapi_image_update_from_buffer (subtitle_image, buf, &sub_rect)) { - GST_WARNING ("could not update VA image with subtitle data"); - g_object_unref (subtitle_image); - return FALSE; - } subpicture = gst_vaapi_subpicture_new (subtitle_image); g_object_unref (subtitle_image); From e4d7e9056804796283905d71f95d2539f377024b Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 23 Nov 2011 16:45:46 -0300 Subject: [PATCH 0496/3781] vaapisink: handle GstVideoOverlayComposition planes. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index c68a3ae63b..d028358b83 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -645,7 +645,7 @@ gst_vaapisink_show_frame_x11( ) { if (!gst_vaapi_window_put_surface(sink->window, surface, - NULL, &sink->display_rect, flags)) { + NULL, &sink->display_rect, flags)) { GST_DEBUG("could not render VA surface"); return FALSE; } @@ -660,6 +660,8 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) GstVaapiSurface *surface; guint flags; gboolean success; + GstVideoOverlayComposition * const composition = + gst_video_buffer_get_overlay_composition(buffer); if (sink->display != gst_vaapi_video_buffer_get_display (vbuffer)) { if (sink->display) @@ -679,6 +681,9 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + if (!gst_vaapi_surface_update_composition(surface, composition)) + GST_WARNING("could not update subtitles"); + #if USE_VAAPISINK_GLX if (sink->use_glx) success = gst_vaapisink_show_frame_glx(sink, surface, flags); From f6fb26790367a7b4c22694c09d18ed679fc7a97c Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 25 Nov 2011 15:00:25 -0500 Subject: [PATCH 0497/3781] converter: add support for GstVideoOverlayComposition planes. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index 515d57ea61..5e3b87bc50 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -121,6 +121,8 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *converter, GstVaapiSurface *surface = gst_vaapi_video_buffer_get_surface ( GST_VAAPI_VIDEO_BUFFER (buffer)); GstVaapiDisplay *new_dpy, *old_dpy; + GstVideoOverlayComposition * const composition = + gst_video_buffer_get_overlay_composition (GST_BUFFER (buffer)); new_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); old_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (priv->texture)); @@ -134,6 +136,9 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *converter, GL_BGRA); } + if (!gst_vaapi_surface_update_composition (surface, composition)) + GST_WARNING ("could not update subtitles"); + return gst_vaapi_texture_put_surface (priv->texture, surface, GST_VAAPI_PICTURE_STRUCTURE_FRAME); } From 3fd3620f7ff455073459963292b3d7641970fa4e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Dec 2011 18:42:44 +0100 Subject: [PATCH 0498/3781] NEWS: updates. --- NEWS | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index b974ba7a7c..a3aca3ad15 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,12 @@ -gst-vaapi NEWS -- summary of changes. 2011-12-09 +gst-vaapi NEWS -- summary of changes. 2011-12-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011 Intel Corporation +Version 0.3.1 - DD.Dec.2011 +* Fix check for supported VA images +* Add support for new subtitle/overlay infrastructure (Thibault Saunier) +* Add missing video context queries in vaapisink/vaapiconvert (Nicolas Dufresne) + Version 0.3.0 - 09.Dec.2011 * Group all plugins into the same bundle * Use new XOverlay API (Sreerenj Balachandran) From cbfd2aebccec53c66de2acc8b963e2b34ba1f401 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 13 Dec 2011 13:40:55 +0100 Subject: [PATCH 0499/3781] configure: check for GstVideoOverlayComposition. --- configure.ac | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/configure.ac b/configure.ac index a3047f11fc..8f064cdbdf 100644 --- a/configure.ac +++ b/configure.ac @@ -194,6 +194,25 @@ PKG_CHECK_MODULES([GST_VIDEO], AC_SUBST(GST_VIDEO_CFLAGS) AC_SUBST(GST_VIDEO_LIBS) +AC_CACHE_CHECK([for GstVideoOverlayComposition], + ac_cv_have_gst_video_overlay_composition, [ + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $GST_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $GST_LIBS" + AC_TRY_COMPILE( + [#include ], + [GstVideoOverlayComposition *c = gst_video_overlay_composition_new(0);], + [ac_cv_have_gst_video_overlay_composition="yes"], + [ac_cv_have_gst_video_overlay_composition="no"] + ) + CFLAGS="$saved_CFLAGS" + LIBS="$saved_LIBS" +]) +if test "$ac_cv_have_gst_video_overlay_composition" != "yes"; then + AC_MSG_ERROR([GstVideoOverlayComposition is not available]) +fi + dnl Check for GStreamer basevideo PKG_CHECK_MODULES([GST_BASEVIDEO], [gstreamer-basevideo-$GST_MAJORMINOR >= $GST_PLUGINS_BAD_VERSION_REQUIRED] From a4244820af355eea883e5e67b9246ea1ee71b34c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 13 Dec 2011 15:51:58 +0100 Subject: [PATCH 0500/3781] Rename gst_vaapi_surface_update_composition() to gst_vaapi_surface_set_subpictures_from_composition(). --- gst-libs/gst/vaapi/gstvaapisurface.c | 4 ++-- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c | 2 +- gst/vaapi/gstvaapisink.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index e07f71afef..50215e8311 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -799,7 +799,7 @@ gst_vaapi_surface_query_status( } /** - * gst_vaapi_surface_update_composition: + * gst_vaapi_surface_set_subpictures_from_composition: * @surface: a #GstVaapiSurface * @compostion: a #GstVideoOverlayCompositon * @@ -810,7 +810,7 @@ gst_vaapi_surface_query_status( * Return value: %TRUE on success */ gboolean -gst_vaapi_surface_update_composition( +gst_vaapi_surface_set_subpictures_from_composition( GstVaapiSurface *surface, GstVideoOverlayComposition *composition ) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 8a2b70b086..c80c065800 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -230,7 +230,7 @@ gst_vaapi_surface_query_status( ); gboolean -gst_vaapi_surface_update_composition( +gst_vaapi_surface_set_subpictures_from_composition( GstVaapiSurface *surface, GstVideoOverlayComposition *composition ); diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index 5e3b87bc50..ee22b15ddd 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -136,7 +136,7 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *converter, GL_BGRA); } - if (!gst_vaapi_surface_update_composition (surface, composition)) + if (!gst_vaapi_surface_set_subpictures_from_composition (surface, composition)) GST_WARNING ("could not update subtitles"); return gst_vaapi_texture_put_surface (priv->texture, surface, diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index d028358b83..175549894f 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -681,7 +681,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - if (!gst_vaapi_surface_update_composition(surface, composition)) + if (!gst_vaapi_surface_set_subpictures_from_composition(surface, composition)) GST_WARNING("could not update subtitles"); #if USE_VAAPISINK_GLX From 9c8c33857fc4ca6ee188613d081515ce28d9655b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 13 Dec 2011 15:59:02 +0100 Subject: [PATCH 0501/3781] Fix warnings. --- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 3 +-- gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c | 1 - gst/vaapi/gstvaapidecode.c | 1 - gst/vaapi/gstvaapisink.c | 2 -- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 7024b670f7..9c0852dfc5 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -79,12 +79,11 @@ x11_create_window(Display *dpy, guint w, guint h, Visual *vis, Colormap cmap) XSetWindowAttributes xswa; unsigned long xswa_mask; XWindowAttributes wattr; - unsigned long black_pixel, white_pixel; + unsigned long black_pixel; screen = DefaultScreen(dpy); rootwin = RootWindow(dpy, screen); black_pixel = BlackPixel(dpy, screen); - white_pixel = WhitePixel(dpy, screen); if (!vis) vis = DefaultVisual(dpy, screen); diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index ee22b15ddd..a4d3562800 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -56,7 +56,6 @@ static void gst_vaapi_video_converter_glx_class_init(GstVaapiVideoConverterGLXClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; g_type_class_add_private (klass, sizeof (GstVaapiVideoConverterGLXPrivate)); object_class->dispose = gst_vaapi_video_converter_glx_dispose; diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 17c6320574..81d08a9e21 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -517,7 +517,6 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) static gboolean gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) { - GstVaapiDisplay *display; GstCaps *decode_caps; guint i, n_decode_caps; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 175549894f..c1749248d8 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -404,8 +404,6 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) static gboolean gst_vaapisink_start(GstBaseSink *base_sink) { - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - return TRUE; } From 317c4e639ee6c972255360e102101862a56d7e57 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 13 Dec 2011 16:53:15 +0100 Subject: [PATCH 0502/3781] surface: record parent context. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapicontext.c | 8 ++- gst-libs/gst/vaapi/gstvaapisurface.c | 81 +++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapisurface.h | 4 ++ gst-libs/gst/vaapi/gstvaapisurface_priv.h | 33 +++++++++ 6 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapisurface_priv.h diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index d271a26e32..48a928eb87 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -332,6 +332,7 @@ gst_vaapi_surface_get_chroma_type gst_vaapi_surface_get_width gst_vaapi_surface_get_height gst_vaapi_surface_get_size +gst_vaapi_surface_get_parent_context gst_vaapi_surface_derive_image gst_vaapi_surface_get_image gst_vaapi_surface_put_image diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 76771741ba..6361cc14a4 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -75,6 +75,7 @@ libgstvaapi_source_priv_h = \ gstvaapidecoder_priv.h \ gstvaapidisplay_priv.h \ gstvaapiobject_priv.h \ + gstvaapisurface_priv.h \ gstvaapiutils.h \ gstvaapivideobuffer_priv.h \ $(libgst_vaapi_ffmpeg_source_priv_h) \ diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 2ab62bb953..63a8c74c0b 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -28,6 +28,8 @@ #include #include "gstvaapicompat.h" #include "gstvaapicontext.h" +#include "gstvaapisurface.h" +#include "gstvaapisurface_priv.h" #include "gstvaapisurfacepool.h" #include "gstvaapiutils.h" #include "gstvaapi_priv.h" @@ -66,7 +68,10 @@ enum { static void unref_surface_cb(gpointer data, gpointer user_data) { - g_object_unref(GST_VAAPI_SURFACE(data)); + GstVaapiSurface * const surface = GST_VAAPI_SURFACE(data); + + gst_vaapi_surface_set_parent_context(surface, NULL); + g_object_unref(surface); } static void @@ -178,6 +183,7 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context) g_ptr_array_add(priv->surfaces, surface); if (!gst_vaapi_video_pool_add_object(priv->surfaces_pool, surface)) return FALSE; + gst_vaapi_surface_set_parent_context(surface, context); } return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 50215e8311..c6dcf787ca 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -28,6 +28,8 @@ #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapisurface.h" +#include "gstvaapisurface_priv.h" +#include "gstvaapicontext.h" #include "gstvaapiimage.h" #include "gstvaapi_priv.h" @@ -46,6 +48,7 @@ struct _GstVaapiSurfacePrivate { guint height; GstVaapiChromaType chroma_type; GPtrArray *subpictures; + GstVaapiContext *parent_context; }; enum { @@ -53,7 +56,8 @@ enum { PROP_WIDTH, PROP_HEIGHT, - PROP_CHROMA_TYPE + PROP_CHROMA_TYPE, + PROP_PARENT_CONTEXT }; static gboolean @@ -100,6 +104,7 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface) GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); gst_vaapi_surface_destroy_subpictures(surface); + gst_vaapi_surface_set_parent_context(surface, NULL); if (surface_id != VA_INVALID_SURFACE) { GST_VAAPI_DISPLAY_LOCK(display); @@ -185,6 +190,9 @@ gst_vaapi_surface_set_property( case PROP_CHROMA_TYPE: priv->chroma_type = g_value_get_uint(value); break; + case PROP_PARENT_CONTEXT: + gst_vaapi_surface_set_parent_context(surface, g_value_get_object(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -211,6 +219,9 @@ gst_vaapi_surface_get_property( case PROP_CHROMA_TYPE: g_value_set_uint(value, gst_vaapi_surface_get_chroma_type(surface)); break; + case PROP_PARENT_CONTEXT: + g_value_set_object(value, gst_vaapi_surface_get_parent_context(surface)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -268,6 +279,15 @@ gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass) "The chroma type of the surface", 0, G_MAXUINT32, 0, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_PARENT_CONTEXT, + g_param_spec_object("parent-context", + "Parent Context", + "The parent context, if any", + GST_VAAPI_TYPE_CONTEXT, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -275,11 +295,12 @@ gst_vaapi_surface_init(GstVaapiSurface *surface) { GstVaapiSurfacePrivate *priv = GST_VAAPI_SURFACE_GET_PRIVATE(surface); - surface->priv = priv; - priv->width = 0; - priv->height = 0; - priv->chroma_type = 0; - priv->subpictures = NULL; + surface->priv = priv; + priv->width = 0; + priv->height = 0; + priv->chroma_type = 0; + priv->subpictures = NULL; + priv->parent_context = NULL; } /** @@ -401,6 +422,54 @@ gst_vaapi_surface_get_size( *pheight = gst_vaapi_surface_get_height(surface); } +/** + * gst_vaapi_surface_set_parent_context: + * @surface: a #GstVaapiSurface + * @context: a #GstVaapiContext + * + * Sets new parent context, or clears any parent context if @context + * is %NULL. This function owns an extra reference to the context, + * which will be released when the surface is destroyed. + */ +void +gst_vaapi_surface_set_parent_context( + GstVaapiSurface *surface, + GstVaapiContext *context +) +{ + GstVaapiSurfacePrivate *priv; + + g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); + + priv = surface->priv; + + if (priv->parent_context) { + g_object_unref(priv->parent_context); + priv->parent_context = NULL; + } + + if (context) + priv->parent_context = g_object_ref(context); +} + +/** + * gst_vaapi_surface_get_parent_context: + * @surface: a #GstVaapiSurface + * + * Retrieves the parent #GstVaapiContext, or %NULL if there is + * none. The surface shall still own a reference to the context. + * i.e. the caller shall not unreference the returned context object. + * + * Return value: the parent context, if any. + */ +GstVaapiContext * +gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); + + return surface->priv->parent_context; +} + /** * gst_vaapi_surface_derive_image: * @surface: a #GstVaapiSurface diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index c80c065800..0741878101 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -35,6 +35,7 @@ G_BEGIN_DECLS typedef enum _GstVaapiChromaType GstVaapiChromaType; typedef enum _GstVaapiSurfaceStatus GstVaapiSurfaceStatus; typedef enum _GstVaapiSurfaceRenderFlags GstVaapiSurfaceRenderFlags; +typedef struct _GstVaapiContext GstVaapiContext; /** * GST_VAAPI_SURFACE_CAPS_NAME: @@ -197,6 +198,9 @@ gst_vaapi_surface_get_size( guint *pheight ); +GstVaapiContext * +gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface); + GstVaapiImage * gst_vaapi_surface_derive_image(GstVaapiSurface *surface); diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h new file mode 100644 index 0000000000..7c99c69ae7 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -0,0 +1,33 @@ +/* + * gstvaapisurface_priv.h - VA surface abstraction (private data) + * + * Copyright (C) 2011 Intel Corporation + * + * 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_SURFACE_PRIV_H +#define GST_VAAPI_SURFACE_PRIV_H + +#include + +void +gst_vaapi_surface_set_parent_context( + GstVaapiSurface *surface, + GstVaapiContext *context +) attribute_hidden; + +#endif /* GST_VAAPI_SURFACE_PRIV_H */ From 32271684874d5c33bc3eb51f293fc013d6d3705c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Dec 2011 13:16:21 +0100 Subject: [PATCH 0503/3781] subpicture: add helper to create subpicture from GstVideoOverlayRectangle. --- gst-libs/gst/vaapi/gstvaapisubpicture.c | 62 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisubpicture.h | 7 +++ gst-libs/gst/vaapi/gstvaapisurface.c | 36 +------------- 3 files changed, 71 insertions(+), 34 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 1f3f4b7248..2776b7230a 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -218,6 +218,68 @@ gst_vaapi_subpicture_new(GstVaapiImage *image) NULL); } +/** + * gst_vaapi_subpicture_new_from_overlay_rectangle: + * @display: a #GstVaapiDisplay + * @rect: a #GstVideoOverlayRectangle + * + * Helper function that creates a new #GstVaapiSubpicture from a + * #GstVideoOverlayRectangle. A new #GstVaapiImage is also created + * along the way and attached to the resulting subpicture. The + * subpicture holds a unique reference to the underlying image. + * + * Return value: the newly allocated #GstVaapiSubpicture object + */ +GstVaapiSubpicture * +gst_vaapi_subpicture_new_from_overlay_rectangle( + GstVaapiDisplay *display, + GstVideoOverlayRectangle *rect +) +{ + GstVaapiSubpicture *subpicture; + GstVaapiImageFormat format; + GstVaapiImage *image; + GstVaapiImageRaw raw_image; + GstBuffer *buffer; + guint width, height, stride; + + g_return_val_if_fail(GST_IS_VIDEO_OVERLAY_RECTANGLE(rect), NULL); + + buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb( + rect, + &width, &height, &stride, + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE + ); + if (!buffer) + return NULL; + + /* XXX: use gst_vaapi_image_format_from_video() */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + format = GST_VAAPI_IMAGE_BGRA; +#else + format = GST_VAAPI_IMAGE_ARGB; +#endif + image = gst_vaapi_image_new(display, format, width, height); + if (!image) + return NULL; + + raw_image.format = format; + raw_image.width = width; + raw_image.height = height; + raw_image.num_planes = 1; + raw_image.pixels[0] = GST_BUFFER_DATA(buffer); + raw_image.stride[0] = stride; + if (!gst_vaapi_image_update_from_raw(image, &raw_image, NULL)) { + GST_WARNING("could not update VA image with subtitle data"); + g_object_unref(image); + return NULL; + } + + subpicture = gst_vaapi_subpicture_new(image); + g_object_unref(image); + return subpicture; +} + /** * gst_vaapi_subpicture_get_id: * @subpicture: a #GstVaapiSubpicture diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 4cdbc7c081..afbd2507c2 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -25,6 +25,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -84,6 +85,12 @@ gst_vaapi_subpicture_get_type(void); GstVaapiSubpicture * gst_vaapi_subpicture_new(GstVaapiImage *image); +GstVaapiSubpicture * +gst_vaapi_subpicture_new_from_overlay_rectangle( + GstVaapiDisplay *display, + GstVideoOverlayRectangle *rect +); + GstVaapiID gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index c6dcf787ca..d8347bbb0b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -903,57 +903,25 @@ gst_vaapi_surface_set_subpictures_from_composition( /* Overlay all the rectangles cantained in the overlay composition */ for (n = 0; n < nb_rectangles; ++n) { - GstBuffer *buf; GstVideoOverlayRectangle *rect; - guint width, height, stride; - GstVaapiImageFormat format; - GstVaapiImage *subtitle_image; GstVaapiRectangle sub_rect; GstVaapiSubpicture *subpicture; - GstVaapiImageRaw raw_image; rect = gst_video_overlay_composition_get_rectangle (composition, n); - buf = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rect, - &width, &height, &stride, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); - - /* XXX: use gst_vaapi_image_format_from_video() */ -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - format = GST_VAAPI_IMAGE_BGRA; -#else - format = GST_VAAPI_IMAGE_ARGB; -#endif - subtitle_image = gst_vaapi_image_new (display, format, width, height); - if (!subtitle_image) - return FALSE; - - raw_image.format = format; - raw_image.width = width; - raw_image.height = height; - raw_image.num_planes = 1; - raw_image.pixels[0] = GST_BUFFER_DATA(buf); - raw_image.stride[0] = stride; - if (!gst_vaapi_image_update_from_raw (subtitle_image, &raw_image, NULL)) { - GST_WARNING ("could not update VA image with subtitle data"); - g_object_unref (subtitle_image); - return FALSE; - } + subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle (display, + rect); gst_video_overlay_rectangle_get_render_rectangle (rect, (gint *)&sub_rect.x, (gint *)&sub_rect.y, &sub_rect.width, &sub_rect.height); - subpicture = gst_vaapi_subpicture_new (subtitle_image); - g_object_unref (subtitle_image); - if (!gst_vaapi_surface_associate_subpicture (surface, subpicture, NULL, &sub_rect)) { GST_WARNING ("could not render overlay rectangle %p", rect); g_object_unref (subpicture); return FALSE; } - g_object_unref (subpicture); } - return TRUE; } From bf63fe671f3b7f8ecd5ad832323cccfda8be9d2a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Dec 2011 13:46:26 +0100 Subject: [PATCH 0504/3781] surface: fix typo in debug message. --- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index d8347bbb0b..18fd414a35 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -755,7 +755,7 @@ gst_vaapi_surface_deassociate_subpicture( /* First, check subpicture was really associated with this surface */ if (!g_ptr_array_remove_fast(surface->priv->subpictures, subpicture)) { - GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT "was not bound to " + GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT " was not bound to " "surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(subpicture)), GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); From 0634dc768de6e6e9109f2e782253061ba41a807e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Dec 2011 14:13:58 +0100 Subject: [PATCH 0505/3781] surface: fix associate subpicture to not report deassociation errors. --- gst-libs/gst/vaapi/gstvaapisurface.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 18fd414a35..57eab42f8b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -648,15 +648,19 @@ gst_vaapi_surface_associate_subpicture( g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); - if (!gst_vaapi_surface_deassociate_subpicture(surface, subpicture)) - return FALSE; - if (!surface->priv->subpictures) { surface->priv->subpictures = g_ptr_array_new(); if (!surface->priv->subpictures) return FALSE; } + if (g_ptr_array_remove_fast(surface->priv->subpictures, subpicture)) { + success = _gst_vaapi_surface_deassociate_subpicture(surface, subpicture); + g_object_unref(subpicture); + if (!success) + return FALSE; + } + success = _gst_vaapi_surface_associate_subpicture( surface, subpicture, From 17538a340e2e72e1770d40b563d6a0d89421b1f8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Dec 2011 14:35:13 +0100 Subject: [PATCH 0506/3781] context: make it possible to apply composition globally. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapicontext.c | 206 ++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapicontext.h | 7 + 3 files changed, 214 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 48a928eb87..751ba64121 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -439,6 +439,7 @@ gst_vaapi_context_get_surface gst_vaapi_context_get_surface_count gst_vaapi_context_put_surface gst_vaapi_context_find_surface_by_id +gst_vaapi_context_apply_composition GST_VAAPI_CONTEXT GST_VAAPI_IS_CONTEXT diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 63a8c74c0b..29654cd3a5 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -31,6 +31,8 @@ #include "gstvaapisurface.h" #include "gstvaapisurface_priv.h" #include "gstvaapisurfacepool.h" +#include "gstvaapiimage.h" +#include "gstvaapisubpicture.h" #include "gstvaapiutils.h" #include "gstvaapi_priv.h" @@ -44,11 +46,20 @@ G_DEFINE_TYPE(GstVaapiContext, gst_vaapi_context, GST_VAAPI_TYPE_OBJECT); GST_VAAPI_TYPE_CONTEXT, \ GstVaapiContextPrivate)) +typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle; +struct _GstVaapiOverlayRectangle { + GstVaapiContext *context; + GstVaapiSubpicture *subpicture; + GstVaapiRectangle rect; + guint seq_num; +}; + /* XXX: optimize for the effective number of reference frames */ struct _GstVaapiContextPrivate { VAConfigID config_id; GPtrArray *surfaces; GstVaapiVideoPool *surfaces_pool; + GPtrArray *overlay; GstVaapiProfile profile; GstVaapiEntrypoint entrypoint; guint width; @@ -65,6 +76,65 @@ enum { PROP_HEIGHT }; +static GstVaapiOverlayRectangle * +overlay_rectangle_new(GstVaapiContext *context) +{ + GstVaapiOverlayRectangle *overlay; + + overlay = g_slice_new0(GstVaapiOverlayRectangle); + if (!overlay) + return NULL; + + overlay->context = context; + return overlay; +} + +static void +overlay_rectangle_destroy(GstVaapiOverlayRectangle *overlay) +{ + GstVaapiContextPrivate *priv; + guint i; + + if (!overlay) + return; + priv = overlay->context->priv; + + if (overlay->subpicture) { + if (priv->surfaces) { + GstVaapiSubpicture * const subpicture = overlay->subpicture; + for (i = 0; i < priv->surfaces->len; i++) { + GstVaapiSurface * const surface = + g_ptr_array_index(priv->surfaces, i); + gst_vaapi_surface_deassociate_subpicture(surface, subpicture); + } + } + g_object_unref(overlay->subpicture); + overlay->subpicture = NULL; + } + g_slice_free(GstVaapiOverlayRectangle, overlay); +} + +static void +destroy_overlay_cb(gpointer data, gpointer user_data) +{ + GstVaapiOverlayRectangle * const overlay = data; + + overlay_rectangle_destroy(overlay); +} + +static void +gst_vaapi_context_destroy_overlay(GstVaapiContext *context) +{ + GstVaapiContextPrivate * const priv = context->priv; + + if (!priv->overlay) + return; + + g_ptr_array_foreach(priv->overlay, destroy_overlay_cb, priv); + g_ptr_array_free(priv->overlay, TRUE); + priv->overlay = NULL; +} + static void unref_surface_cb(gpointer data, gpointer user_data) { @@ -79,6 +149,8 @@ gst_vaapi_context_destroy_surfaces(GstVaapiContext *context) { GstVaapiContextPrivate * const priv = context->priv; + gst_vaapi_context_destroy_overlay(context); + if (priv->surfaces) { g_ptr_array_foreach(priv->surfaces, unref_surface_cb, NULL); g_ptr_array_free(priv->surfaces, TRUE); @@ -129,6 +201,19 @@ gst_vaapi_context_destroy(GstVaapiContext *context) } } +static gboolean +gst_vaapi_context_create_overlay(GstVaapiContext *context) +{ + GstVaapiContextPrivate * const priv = context->priv; + + if (!priv->overlay) { + priv->overlay = g_ptr_array_new(); + if (!priv->overlay) + return FALSE; + } + return TRUE; +} + static gboolean gst_vaapi_context_create_surfaces(GstVaapiContext *context) { @@ -140,6 +225,9 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context) /* Number of scratch surfaces beyond those used as reference */ const guint SCRATCH_SURFACES_COUNT = 4; + if (!gst_vaapi_context_create_overlay(context)) + return FALSE; + if (!priv->surfaces) { priv->surfaces = g_ptr_array_new(); if (!priv->surfaces) @@ -405,6 +493,7 @@ gst_vaapi_context_init(GstVaapiContext *context) priv->config_id = VA_INVALID_ID; priv->surfaces = NULL; priv->surfaces_pool = NULL; + priv->overlay = NULL; priv->profile = 0; priv->entrypoint = 0; priv->width = 0; @@ -684,3 +773,120 @@ gst_vaapi_context_find_surface_by_id(GstVaapiContext *context, GstVaapiID id) } return NULL; } + +/* Check if composition changed */ +static gboolean +gst_vaapi_context_composition_changed( + GstVaapiContext *context, + GstVideoOverlayComposition *composition +) +{ + GstVaapiContextPrivate * const priv = context->priv; + GstVaapiOverlayRectangle *overlay; + GstVideoOverlayRectangle *rect; + guint i, n_rectangles; + + if (!priv->overlay || !composition) + return TRUE; + + n_rectangles = gst_video_overlay_composition_n_rectangles(composition); + if (priv->overlay->len != n_rectangles) + return TRUE; + + for (i = 0; i < n_rectangles; i++) { + rect = gst_video_overlay_composition_get_rectangle(composition, i); + g_return_val_if_fail(rect, TRUE); + overlay = g_ptr_array_index(priv->overlay, i); + g_return_val_if_fail(overlay, TRUE); + if (overlay->seq_num != gst_video_overlay_rectangle_get_seqnum(rect)) + return TRUE; + } + return FALSE; +} + +/** + * gst_vaapi_context_apply_composition: + * @context: a #GstVaapiContext + * @composition: a #GstVideoOverlayComposition + * + * Applies video composition planes to all surfaces bound to @context. + * This helper function resets any additional subpictures the user may + * have associated himself. A %NULL @composition will also clear all + * the existing subpictures. + * + * Return value: %TRUE if all composition planes could be applied, + * %FALSE otherwise + */ +gboolean +gst_vaapi_context_apply_composition( + GstVaapiContext *context, + GstVideoOverlayComposition *composition +) +{ + GstVaapiContextPrivate *priv; + GstVideoOverlayRectangle *rect; + GstVaapiOverlayRectangle *overlay = NULL; + GstVaapiDisplay *display; + guint i, j, n_rectangles; + + g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE); + + priv = context->priv; + if (!priv->surfaces) + return FALSE; + + display = GST_VAAPI_OBJECT_DISPLAY(context); + if (!display) + return FALSE; + + if (!gst_vaapi_context_composition_changed(context, composition)) + return TRUE; + gst_vaapi_context_destroy_overlay(context); + + if (!composition) + return TRUE; + if (!gst_vaapi_context_create_overlay(context)) + return FALSE; + + n_rectangles = gst_video_overlay_composition_n_rectangles(composition); + for (i = 0; i < n_rectangles; i++) { + rect = gst_video_overlay_composition_get_rectangle(composition, i); + + overlay = overlay_rectangle_new(context); + if (!overlay) { + GST_WARNING("could not create VA overlay rectangle"); + return FALSE; + } + overlay->seq_num = gst_video_overlay_rectangle_get_seqnum(rect); + + overlay->subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle( + display, + rect + ); + if (!overlay->subpicture) { + overlay_rectangle_destroy(overlay); + return FALSE; + } + + gst_video_overlay_rectangle_get_render_rectangle( + rect, + (gint *)&overlay->rect.x, + (gint *)&overlay->rect.y, + &overlay->rect.width, + &overlay->rect.height + ); + + for (j = 0; j < priv->surfaces->len; j++) { + GstVaapiSurface * const surface = + g_ptr_array_index(priv->surfaces, j); + if (!gst_vaapi_surface_associate_subpicture(surface, + overlay->subpicture, NULL, &overlay->rect)) { + GST_WARNING("could not render overlay rectangle %p", rect); + overlay_rectangle_destroy(overlay); + return FALSE; + } + } + g_ptr_array_add(priv->overlay, overlay); + } + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index d1b12608dd..457570c054 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -26,6 +26,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -131,6 +132,12 @@ gst_vaapi_context_put_surface(GstVaapiContext *context, GstVaapiSurface *surface GstVaapiSurface * gst_vaapi_context_find_surface_by_id(GstVaapiContext *context, GstVaapiID id); +gboolean +gst_vaapi_context_apply_composition( + GstVaapiContext *context, + GstVideoOverlayComposition *composition +); + G_END_DECLS #endif /* GST_VAAPI_CONTEXT_H */ From ac7c4cfe785e134319b3e232389056e4d9bd99e5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Dec 2011 14:40:37 +0100 Subject: [PATCH 0507/3781] surface: apply composition to the parent context, if requested. --- gst-libs/gst/vaapi/gstvaapisurface.c | 13 +++++++++++-- gst-libs/gst/vaapi/gstvaapisurface.h | 5 +++-- gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c | 3 ++- gst/vaapi/gstvaapisink.c | 3 ++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 57eab42f8b..c29b1ba13e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -875,6 +875,8 @@ gst_vaapi_surface_query_status( * gst_vaapi_surface_set_subpictures_from_composition: * @surface: a #GstVaapiSurface * @compostion: a #GstVideoOverlayCompositon + * @propagate_context: a flag specifying whether to apply composition + * to the parent context, if any * * Helper to update the subpictures from #GstVideoOverlayCompositon. Sending * a NULL composition will clear all the current subpictures. Note that this @@ -884,8 +886,9 @@ gst_vaapi_surface_query_status( */ gboolean gst_vaapi_surface_set_subpictures_from_composition( - GstVaapiSurface *surface, - GstVideoOverlayComposition *composition + GstVaapiSurface *surface, + GstVideoOverlayComposition *composition, + gboolean propagate_context ) { GstVaapiDisplay *display; @@ -893,6 +896,12 @@ gst_vaapi_surface_set_subpictures_from_composition( g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + if (propagate_context) { + GstVaapiContext * const context = surface->priv->parent_context; + if (context) + return gst_vaapi_context_apply_composition(context, composition); + } + display = GST_VAAPI_OBJECT_DISPLAY(surface); if (!display) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 0741878101..ce9bd9e8d2 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -235,8 +235,9 @@ gst_vaapi_surface_query_status( gboolean gst_vaapi_surface_set_subpictures_from_composition( - GstVaapiSurface *surface, - GstVideoOverlayComposition *composition + GstVaapiSurface *surface, + GstVideoOverlayComposition *composition, + gboolean propagate_context ); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index a4d3562800..fdeb817e8f 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -135,7 +135,8 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *converter, GL_BGRA); } - if (!gst_vaapi_surface_set_subpictures_from_composition (surface, composition)) + if (!gst_vaapi_surface_set_subpictures_from_composition (surface, + composition, TRUE)) GST_WARNING ("could not update subtitles"); return gst_vaapi_texture_put_surface (priv->texture, surface, diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index c1749248d8..7dab2710cd 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -679,7 +679,8 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - if (!gst_vaapi_surface_set_subpictures_from_composition(surface, composition)) + if (!gst_vaapi_surface_set_subpictures_from_composition(surface, + composition, TRUE)) GST_WARNING("could not update subtitles"); #if USE_VAAPISINK_GLX From 8a5a1bf38cbd98d3306c74cc185b1bbcf4a0bdb5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Dec 2011 15:22:24 +0100 Subject: [PATCH 0508/3781] NEWS: updates. --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index a3aca3ad15..d2d22f4b06 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ Copyright (C) 2011 Intel Corporation Version 0.3.1 - DD.Dec.2011 * Fix check for supported VA images +* Add support for partial VA image updates * Add support for new subtitle/overlay infrastructure (Thibault Saunier) * Add missing video context queries in vaapisink/vaapiconvert (Nicolas Dufresne) From e13efd71b752f4f30754bc387e6ce48a158f96ec Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 3 Jan 2012 13:42:12 +0100 Subject: [PATCH 0509/3781] 0.3.1. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index d2d22f4b06..a303d0ec4e 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,8 @@ -gst-vaapi NEWS -- summary of changes. 2011-12-DD +gst-vaapi NEWS -- summary of changes. 2011-12-16 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011 Intel Corporation -Version 0.3.1 - DD.Dec.2011 +Version 0.3.1 - 16.Dec.2011 * Fix check for supported VA images * Add support for partial VA image updates * Add support for new subtitle/overlay infrastructure (Thibault Saunier) diff --git a/configure.ac b/configure.ac index 8f064cdbdf..1d70c92ed1 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 9b33d003159feef98521bb73fa9009fb77444c60 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 3 Jan 2012 13:54:03 +0100 Subject: [PATCH 0510/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 1d70c92ed1..7005a7afa7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) -m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [2]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 42fa974391bb7f2e13615815cceda8e1a7f7b1b7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 3 Jan 2012 14:34:09 +0100 Subject: [PATCH 0511/3781] Rename vaapiconvert element to vaapiupload. --- NEWS | 5 +- README | 2 +- debian.upstream/control.in | 2 +- docs/reference/plugins/plugins-docs.xml.in | 2 +- docs/reference/plugins/plugins-sections.txt | 20 +- docs/reference/plugins/plugins.types | 2 +- gst/vaapi/Makefile.am | 4 +- gst/vaapi/gstvaapi.c | 6 +- .../{gstvaapiconvert.c => gstvaapiupload.c} | 348 +++++++++--------- .../{gstvaapiconvert.h => gstvaapiupload.h} | 50 +-- 10 files changed, 222 insertions(+), 219 deletions(-) rename gst/vaapi/{gstvaapiconvert.c => gstvaapiupload.c} (62%) rename gst/vaapi/{gstvaapiconvert.h => gstvaapiupload.h} (61%) diff --git a/NEWS b/NEWS index a303d0ec4e..670f571690 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,10 @@ -gst-vaapi NEWS -- summary of changes. 2011-12-16 +gst-vaapi NEWS -- summary of changes. 2012-01-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011 Intel Corporation +Version 0.3.2 - DD.Jan.2012 +* Rename vaapiconvert element to vaapiupload + Version 0.3.1 - 16.Dec.2011 * Fix check for supported VA images * Add support for partial VA image updates diff --git a/README b/README index a4d94be285..3aa80aa2dc 100644 --- a/README +++ b/README @@ -23,7 +23,7 @@ GStreamer and helper libraries. videos to video/x-vaapi-surfaces surfaces, depending on the underlying HW capabilities. - * `vaapiconvert' is used to convert from video/x-raw-yuv pixels to + * `vaapiupload' is used to convert from video/x-raw-yuv pixels to video/x-vaapi-surface surfaces. * `vaapisink' is used to display video/x-vaapi-surface surfaces to diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 579d8496d1..98bbdfac6d 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -18,7 +18,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends} Suggests: gstreamer@GST_MAJORMINOR@-vaapi-doc Description: VA-API plugins for GStreamer This package contains GStreamer plugins for VA-API support: - - `vaapiconvert': converts from YUV pixels to VA surfaces + - `vaapiupload': converts from YUV pixels to VA surfaces - `vaapisink': a VA-API based video sink Package: gstreamer@GST_MAJORMINOR@-vaapi-doc diff --git a/docs/reference/plugins/plugins-docs.xml.in b/docs/reference/plugins/plugins-docs.xml.in index 4777999671..b02060fd15 100644 --- a/docs/reference/plugins/plugins-docs.xml.in +++ b/docs/reference/plugins/plugins-docs.xml.in @@ -12,7 +12,7 @@ gst-plugins-vaapi Plugins - + diff --git a/docs/reference/plugins/plugins-sections.txt b/docs/reference/plugins/plugins-sections.txt index a0c0a31bec..9db963afdb 100644 --- a/docs/reference/plugins/plugins-sections.txt +++ b/docs/reference/plugins/plugins-sections.txt @@ -27,15 +27,15 @@ GST_VAAPIDECODE_GET_CLASS
-gstvaapiconvert -GstVaapiConvert -GstVaapiConvert +gstvaapiupload +GstVaapiUpload +GstVaapiUpload -GST_VAAPICONVERT -GST_IS_VAAPICONVERT -GST_TYPE_VAAPICONVERT -gst_vaapiconvert_get_type -GST_VAAPICONVERT_CLASS -GST_IS_VAAPICONVERT_CLASS -GST_VAAPICONVERT_GET_CLASS +GST_VAAPIUPLOAD +GST_IS_VAAPIUPLOAD +GST_TYPE_VAAPIUPLOAD +gst_vaapiupload_get_type +GST_VAAPIUPLOAD_CLASS +GST_IS_VAAPIUPLOAD_CLASS +GST_VAAPIUPLOAD_GET_CLASS
diff --git a/docs/reference/plugins/plugins.types b/docs/reference/plugins/plugins.types index db94655ea2..a6b5ab9c02 100644 --- a/docs/reference/plugins/plugins.types +++ b/docs/reference/plugins/plugins.types @@ -1,3 +1,3 @@ gst_vaapisink_get_type gst_vaapidecode_get_type -gst_vaapiconvert_get_type +gst_vaapiupload_get_type diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 8b1bbf8549..3ff3b4ac47 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -17,17 +17,17 @@ endif libgstvaapi_la_SOURCES = \ gstvaapi.c \ - gstvaapiconvert.c \ gstvaapidecode.c \ gstvaapipluginutil.c \ gstvaapisink.c \ + gstvaapiupload.c \ $(NULL) noinst_HEADERS = \ - gstvaapiconvert.h \ gstvaapidecode.h \ gstvaapipluginutil.h \ gstvaapisink.h \ + gstvaapiupload.h \ $(NULL) libgstvaapi_la_CFLAGS = \ diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 1675a2a7c6..44fb2e898c 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -27,16 +27,16 @@ #include -#include "gstvaapiconvert.h" +#include "gstvaapiupload.h" #include "gstvaapidecode.h" #include "gstvaapisink.h" static gboolean plugin_init (GstPlugin *plugin) { - gst_element_register(plugin, "vaapiconvert", + gst_element_register(plugin, "vaapiupload", GST_RANK_PRIMARY, - GST_TYPE_VAAPICONVERT); + GST_TYPE_VAAPIUPLOAD); gst_element_register(plugin, "vaapidecode", GST_RANK_PRIMARY, GST_TYPE_VAAPIDECODE); diff --git a/gst/vaapi/gstvaapiconvert.c b/gst/vaapi/gstvaapiupload.c similarity index 62% rename from gst/vaapi/gstvaapiconvert.c rename to gst/vaapi/gstvaapiupload.c index a0db024d40..803b907231 100644 --- a/gst/vaapi/gstvaapiconvert.c +++ b/gst/vaapi/gstvaapiupload.c @@ -1,5 +1,5 @@ /* - * gstvaapiconvert.c - VA-API video converter + * gstvaapiupload.c - VA-API video uploader * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011 Intel Corporation @@ -21,11 +21,11 @@ */ /** - * SECTION:gstvaapiconvert - * @short_description: A VA-API based video pixels format converter + * SECTION:gstvaapiupload + * @short_description: A video to VA flow filter * - * vaapiconvert converts from raw YUV pixels to surfaces suitable for - * the vaapisink element. + * vaapiupload converts from raw YUV pixels to VA surfaces suitable + * for the vaapisink element, for example. */ #include "config.h" @@ -45,16 +45,16 @@ #endif #include "gstvaapipluginutil.h" -#include "gstvaapiconvert.h" +#include "gstvaapiupload.h" -#define GST_PLUGIN_NAME "vaapiconvert" -#define GST_PLUGIN_DESC "A VA-API based video pixels format converter" +#define GST_PLUGIN_NAME "vaapiupload" +#define GST_PLUGIN_DESC "A video to VA flow filter" -GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapiconvert); -#define GST_CAT_DEFAULT gst_debug_vaapiconvert +GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapiupload); +#define GST_CAT_DEFAULT gst_debug_vaapiupload /* ElementFactory information */ -static const GstElementDetails gst_vaapiconvert_details = +static const GstElementDetails gst_vaapiupload_details = GST_ELEMENT_DETAILS( "VA-API colorspace converter", "Filter/Converter/Video", @@ -62,32 +62,32 @@ static const GstElementDetails gst_vaapiconvert_details = "Gwenole Beauchesne "); /* Default templates */ -static const char gst_vaapiconvert_yuv_caps_str[] = +static const char gst_vaapiupload_yuv_caps_str[] = "video/x-raw-yuv, " "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]; "; -static const char gst_vaapiconvert_vaapi_caps_str[] = +static const char gst_vaapiupload_vaapi_caps_str[] = GST_VAAPI_SURFACE_CAPS; -static GstStaticPadTemplate gst_vaapiconvert_sink_factory = +static GstStaticPadTemplate gst_vaapiupload_sink_factory = GST_STATIC_PAD_TEMPLATE( "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS(gst_vaapiconvert_yuv_caps_str)); + GST_STATIC_CAPS(gst_vaapiupload_yuv_caps_str)); -static GstStaticPadTemplate gst_vaapiconvert_src_factory = +static GstStaticPadTemplate gst_vaapiupload_src_factory = GST_STATIC_PAD_TEMPLATE( "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS(gst_vaapiconvert_vaapi_caps_str)); + GST_STATIC_CAPS(gst_vaapiupload_vaapi_caps_str)); #define GstVideoContextClass GstVideoContextInterface GST_BOILERPLATE_WITH_INTERFACE( - GstVaapiConvert, - gst_vaapiconvert, + GstVaapiUpload, + gst_vaapiupload, GstBaseTransform, GST_TYPE_BASE_TRANSFORM, GstVideoContext, @@ -97,8 +97,8 @@ GST_BOILERPLATE_WITH_INTERFACE( /* * Direct rendering levels (direct-rendering) * 0: upstream allocated YUV pixels - * 1: vaapiconvert allocated YUV pixels (mapped from VA image) - * 2: vaapiconvert allocated YUV pixels (mapped from VA surface) + * 1: vaapiupload allocated YUV pixels (mapped from VA image) + * 2: vaapiupload allocated YUV pixels (mapped from VA surface) */ #define DIRECT_RENDERING_DEFAULT 2 @@ -109,41 +109,41 @@ enum { }; static gboolean -gst_vaapiconvert_start(GstBaseTransform *trans); +gst_vaapiupload_start(GstBaseTransform *trans); static gboolean -gst_vaapiconvert_stop(GstBaseTransform *trans); +gst_vaapiupload_stop(GstBaseTransform *trans); static GstFlowReturn -gst_vaapiconvert_transform( +gst_vaapiupload_transform( GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf ); static GstCaps * -gst_vaapiconvert_transform_caps( +gst_vaapiupload_transform_caps( GstBaseTransform *trans, GstPadDirection direction, GstCaps *caps ); static gboolean -gst_vaapiconvert_set_caps( +gst_vaapiupload_set_caps( GstBaseTransform *trans, GstCaps *incaps, GstCaps *outcaps ); static gboolean -gst_vaapiconvert_get_unit_size( +gst_vaapiupload_get_unit_size( GstBaseTransform *trans, GstCaps *caps, guint *size ); static GstFlowReturn -gst_vaapiconvert_sinkpad_buffer_alloc( +gst_vaapiupload_sinkpad_buffer_alloc( GstPad *pad, guint64 offset, guint size, @@ -152,7 +152,7 @@ gst_vaapiconvert_sinkpad_buffer_alloc( ); static GstFlowReturn -gst_vaapiconvert_prepare_output_buffer( +gst_vaapiupload_prepare_output_buffer( GstBaseTransform *trans, GstBuffer *inbuf, gint size, @@ -161,7 +161,7 @@ gst_vaapiconvert_prepare_output_buffer( ); static gboolean -gst_vaapiconvert_query( +gst_vaapiupload_query( GstPad *pad, GstQuery *query ); @@ -169,15 +169,15 @@ gst_vaapiconvert_query( /* GstVideoContext interface */ static void -gst_vaapiconvert_set_video_context(GstVideoContext *context, const gchar *type, +gst_vaapiupload_set_video_context(GstVideoContext *context, const gchar *type, const GValue *value) { - GstVaapiConvert *convert = GST_VAAPICONVERT (context); - gst_vaapi_set_display (type, value, &convert->display); + GstVaapiUpload *upload = GST_VAAPIUPLOAD (context); + gst_vaapi_set_display (type, value, &upload->display); } static gboolean -gst_video_context_supported (GstVaapiConvert *convert, GType iface_type) +gst_video_context_supported (GstVaapiUpload *upload, GType iface_type) { return (iface_type == GST_TYPE_VIDEO_CONTEXT); } @@ -185,72 +185,72 @@ gst_video_context_supported (GstVaapiConvert *convert, GType iface_type) static void gst_video_context_interface_init(GstVideoContextInterface *iface) { - iface->set_context = gst_vaapiconvert_set_video_context; + iface->set_context = gst_vaapiupload_set_video_context; } static void -gst_vaapiconvert_destroy(GstVaapiConvert *convert) +gst_vaapiupload_destroy(GstVaapiUpload *upload) { - if (convert->images) { - g_object_unref(convert->images); - convert->images = NULL; + if (upload->images) { + g_object_unref(upload->images); + upload->images = NULL; } - if (convert->surfaces) { - g_object_unref(convert->surfaces); - convert->surfaces = NULL; + if (upload->surfaces) { + g_object_unref(upload->surfaces); + upload->surfaces = NULL; } - if (convert->display) { - g_object_unref(convert->display); - convert->display = NULL; + if (upload->display) { + g_object_unref(upload->display); + upload->display = NULL; } } static void -gst_vaapiconvert_base_init(gpointer klass) +gst_vaapiupload_base_init(gpointer klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - gst_element_class_set_details(element_class, &gst_vaapiconvert_details); + gst_element_class_set_details(element_class, &gst_vaapiupload_details); /* sink pad */ gst_element_class_add_pad_template( element_class, - gst_static_pad_template_get(&gst_vaapiconvert_sink_factory) + gst_static_pad_template_get(&gst_vaapiupload_sink_factory) ); /* src pad */ gst_element_class_add_pad_template( element_class, - gst_static_pad_template_get(&gst_vaapiconvert_src_factory) + gst_static_pad_template_get(&gst_vaapiupload_src_factory) ); } static void -gst_vaapiconvert_finalize(GObject *object) +gst_vaapiupload_finalize(GObject *object) { - gst_vaapiconvert_destroy(GST_VAAPICONVERT(object)); + gst_vaapiupload_destroy(GST_VAAPIUPLOAD(object)); G_OBJECT_CLASS(parent_class)->finalize(object); } static void -gst_vaapiconvert_set_property( +gst_vaapiupload_set_property( GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec ) { - GstVaapiConvert * const convert = GST_VAAPICONVERT(object); + GstVaapiUpload * const upload = GST_VAAPIUPLOAD(object); switch (prop_id) { case PROP_DIRECT_RENDERING: - GST_OBJECT_LOCK(convert); - convert->direct_rendering = g_value_get_uint(value); - GST_OBJECT_UNLOCK(convert); + GST_OBJECT_LOCK(upload); + upload->direct_rendering = g_value_get_uint(value); + GST_OBJECT_UNLOCK(upload); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -259,18 +259,18 @@ gst_vaapiconvert_set_property( } static void -gst_vaapiconvert_get_property( +gst_vaapiupload_get_property( GObject *object, guint prop_id, GValue *value, GParamSpec *pspec ) { - GstVaapiConvert * const convert = GST_VAAPICONVERT(object); + GstVaapiUpload * const upload = GST_VAAPIUPLOAD(object); switch (prop_id) { case PROP_DIRECT_RENDERING: - g_value_set_uint(value, convert->direct_rendering); + g_value_set_uint(value, upload->direct_rendering); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -279,28 +279,28 @@ gst_vaapiconvert_get_property( } static void -gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) +gst_vaapiupload_class_init(GstVaapiUploadClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapiconvert, + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapiupload, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - object_class->finalize = gst_vaapiconvert_finalize; - object_class->set_property = gst_vaapiconvert_set_property; - object_class->get_property = gst_vaapiconvert_get_property; + object_class->finalize = gst_vaapiupload_finalize; + object_class->set_property = gst_vaapiupload_set_property; + object_class->get_property = gst_vaapiupload_get_property; - trans_class->start = gst_vaapiconvert_start; - trans_class->stop = gst_vaapiconvert_stop; - trans_class->transform = gst_vaapiconvert_transform; - trans_class->transform_caps = gst_vaapiconvert_transform_caps; - trans_class->set_caps = gst_vaapiconvert_set_caps; - trans_class->get_unit_size = gst_vaapiconvert_get_unit_size; - trans_class->prepare_output_buffer = gst_vaapiconvert_prepare_output_buffer; + trans_class->start = gst_vaapiupload_start; + trans_class->stop = gst_vaapiupload_stop; + trans_class->transform = gst_vaapiupload_transform; + trans_class->transform_caps = gst_vaapiupload_transform_caps; + trans_class->set_caps = gst_vaapiupload_set_caps; + trans_class->get_unit_size = gst_vaapiupload_get_unit_size; + trans_class->prepare_output_buffer = gst_vaapiupload_prepare_output_buffer; /** - * GstVaapiConvert:direct-rendering: + * GstVaapiUpload:direct-rendering: * * Selects the direct rendering level. * @@ -330,67 +330,67 @@ gst_vaapiconvert_class_init(GstVaapiConvertClass *klass) } static void -gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass) +gst_vaapiupload_init(GstVaapiUpload *upload, GstVaapiUploadClass *klass) { GstPad *sinkpad, *srcpad; - convert->display = NULL; - convert->images = NULL; - convert->images_reset = FALSE; - convert->image_width = 0; - convert->image_height = 0; - convert->surfaces = NULL; - convert->surfaces_reset = FALSE; - convert->surface_width = 0; - convert->surface_height = 0; - convert->direct_rendering_caps = 0; - convert->direct_rendering = G_MAXUINT32; + upload->display = NULL; + upload->images = NULL; + upload->images_reset = FALSE; + upload->image_width = 0; + upload->image_height = 0; + upload->surfaces = NULL; + upload->surfaces_reset = FALSE; + upload->surface_width = 0; + upload->surface_height = 0; + upload->direct_rendering_caps = 0; + upload->direct_rendering = G_MAXUINT32; /* Override buffer allocator on sink pad */ - sinkpad = gst_element_get_static_pad(GST_ELEMENT(convert), "sink"); + sinkpad = gst_element_get_static_pad(GST_ELEMENT(upload), "sink"); gst_pad_set_bufferalloc_function( sinkpad, - gst_vaapiconvert_sinkpad_buffer_alloc + gst_vaapiupload_sinkpad_buffer_alloc ); - gst_pad_set_query_function(sinkpad, gst_vaapiconvert_query); + gst_pad_set_query_function(sinkpad, gst_vaapiupload_query); g_object_unref(sinkpad); /* Override query on src pad */ - srcpad = gst_element_get_static_pad(GST_ELEMENT(convert), "src"); - gst_pad_set_query_function(srcpad, gst_vaapiconvert_query); + srcpad = gst_element_get_static_pad(GST_ELEMENT(upload), "src"); + gst_pad_set_query_function(srcpad, gst_vaapiupload_query); } static gboolean -gst_vaapiconvert_start(GstBaseTransform *trans) +gst_vaapiupload_start(GstBaseTransform *trans) { - GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - if (!gst_vaapi_ensure_display(convert, &convert->display)) + if (!gst_vaapi_ensure_display(upload, &upload->display)) return FALSE; return TRUE; } static gboolean -gst_vaapiconvert_stop(GstBaseTransform *trans) +gst_vaapiupload_stop(GstBaseTransform *trans) { - GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - if (convert->display) { - g_object_unref(convert->display); - convert->display = NULL; + if (upload->display) { + g_object_unref(upload->display); + upload->display = NULL; } return TRUE; } static GstFlowReturn -gst_vaapiconvert_transform( +gst_vaapiupload_transform( GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf ) { - GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); GstVaapiVideoBuffer *vbuffer; GstVaapiSurface *surface; GstVaapiImage *image; @@ -401,7 +401,7 @@ gst_vaapiconvert_transform( if (!surface) return GST_FLOW_UNEXPECTED; - if (convert->direct_rendering) { + if (upload->direct_rendering) { if (!GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) { GST_DEBUG("GstVaapiVideoBuffer was expected"); return GST_FLOW_UNEXPECTED; @@ -414,20 +414,20 @@ gst_vaapiconvert_transform( if (!gst_vaapi_image_unmap(image)) return GST_FLOW_UNEXPECTED; - if (convert->direct_rendering < 2) { + if (upload->direct_rendering < 2) { if (!gst_vaapi_surface_put_image(surface, image)) goto error_put_image; } return GST_FLOW_OK; } - image = gst_vaapi_video_pool_get_object(convert->images); + image = gst_vaapi_video_pool_get_object(upload->images); if (!image) return GST_FLOW_UNEXPECTED; gst_vaapi_image_update_from_buffer(image, inbuf, NULL); success = gst_vaapi_surface_put_image(surface, image); - gst_vaapi_video_pool_put_object(convert->images, image); + gst_vaapi_video_pool_put_object(upload->images, image); if (!success) goto error_put_image; return GST_FLOW_OK; @@ -443,13 +443,13 @@ error_put_image: } static GstCaps * -gst_vaapiconvert_transform_caps( +gst_vaapiupload_transform_caps( GstBaseTransform *trans, GstPadDirection direction, GstCaps *caps ) { - GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); GstCaps *out_caps = NULL; GstStructure *structure; const GValue *v_width, *v_height, *v_framerate, *v_par; @@ -468,15 +468,15 @@ gst_vaapiconvert_transform_caps( if (direction == GST_PAD_SINK) { if (!gst_structure_has_name(structure, "video/x-raw-yuv")) return NULL; - out_caps = gst_caps_from_string(gst_vaapiconvert_vaapi_caps_str); + out_caps = gst_caps_from_string(gst_vaapiupload_vaapi_caps_str); } else { if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) return NULL; - out_caps = gst_caps_from_string(gst_vaapiconvert_yuv_caps_str); - if (convert->display) { + out_caps = gst_caps_from_string(gst_vaapiupload_yuv_caps_str); + if (upload->display) { GstCaps *allowed_caps, *inter_caps; - allowed_caps = gst_vaapi_display_get_image_caps(convert->display); + allowed_caps = gst_vaapi_display_get_image_caps(upload->display); if (!allowed_caps) return NULL; inter_caps = gst_caps_intersect(out_caps, allowed_caps); @@ -499,7 +499,7 @@ gst_vaapiconvert_transform_caps( } static gboolean -gst_vaapiconvert_ensure_image_pool(GstVaapiConvert *convert, GstCaps *caps) +gst_vaapiupload_ensure_image_pool(GstVaapiUpload *upload, GstCaps *caps) { GstStructure * const structure = gst_caps_get_structure(caps, 0); gint width, height; @@ -507,21 +507,21 @@ gst_vaapiconvert_ensure_image_pool(GstVaapiConvert *convert, GstCaps *caps) gst_structure_get_int(structure, "width", &width); gst_structure_get_int(structure, "height", &height); - if (width != convert->image_width || height != convert->image_height) { - convert->image_width = width; - convert->image_height = height; - if (convert->images) - g_object_unref(convert->images); - convert->images = gst_vaapi_image_pool_new(convert->display, caps); - if (!convert->images) + if (width != upload->image_width || height != upload->image_height) { + upload->image_width = width; + upload->image_height = height; + if (upload->images) + g_object_unref(upload->images); + upload->images = gst_vaapi_image_pool_new(upload->display, caps); + if (!upload->images) return FALSE; - convert->images_reset = TRUE; + upload->images_reset = TRUE; } return TRUE; } static gboolean -gst_vaapiconvert_ensure_surface_pool(GstVaapiConvert *convert, GstCaps *caps) +gst_vaapiupload_ensure_surface_pool(GstVaapiUpload *upload, GstCaps *caps) { GstStructure * const structure = gst_caps_get_structure(caps, 0); gint width, height; @@ -529,22 +529,22 @@ gst_vaapiconvert_ensure_surface_pool(GstVaapiConvert *convert, GstCaps *caps) gst_structure_get_int(structure, "width", &width); gst_structure_get_int(structure, "height", &height); - if (width != convert->surface_width || height != convert->surface_height) { - convert->surface_width = width; - convert->surface_height = height; - if (convert->surfaces) - g_object_unref(convert->surfaces); - convert->surfaces = gst_vaapi_surface_pool_new(convert->display, caps); - if (!convert->surfaces) + if (width != upload->surface_width || height != upload->surface_height) { + upload->surface_width = width; + upload->surface_height = height; + if (upload->surfaces) + g_object_unref(upload->surfaces); + upload->surfaces = gst_vaapi_surface_pool_new(upload->display, caps); + if (!upload->surfaces) return FALSE; - convert->surfaces_reset = TRUE; + upload->surfaces_reset = TRUE; } return TRUE; } static void -gst_vaapiconvert_ensure_direct_rendering_caps( - GstVaapiConvert *convert, +gst_vaapiupload_ensure_direct_rendering_caps( + GstVaapiUpload *upload, GstCaps *caps ) { @@ -555,12 +555,12 @@ gst_vaapiconvert_ensure_direct_rendering_caps( GstStructure *structure; gint width, height; - if (!convert->images_reset && !convert->surfaces_reset) + if (!upload->images_reset && !upload->surfaces_reset) return; - convert->images_reset = FALSE; - convert->surfaces_reset = FALSE; - convert->direct_rendering_caps = 0; + upload->images_reset = FALSE; + upload->surfaces_reset = FALSE; + upload->direct_rendering_caps = 0; structure = gst_caps_get_structure(caps, 0); if (!structure) @@ -578,78 +578,78 @@ gst_vaapiconvert_ensure_direct_rendering_caps( return; /* Check if we can alias sink & output buffers (same data_size) */ - image = gst_vaapi_video_pool_get_object(convert->images); + image = gst_vaapi_video_pool_get_object(upload->images); if (image) { - if (convert->direct_rendering_caps == 0 && + if (upload->direct_rendering_caps == 0 && (gst_vaapi_image_get_format(image) == vaformat && gst_vaapi_image_is_linear(image) && (gst_vaapi_image_get_data_size(image) == gst_video_format_get_size(vformat, width, height)))) - convert->direct_rendering_caps = 1; - gst_vaapi_video_pool_put_object(convert->images, image); + upload->direct_rendering_caps = 1; + gst_vaapi_video_pool_put_object(upload->images, image); } /* Check if we can access to the surface pixels directly */ - surface = gst_vaapi_video_pool_get_object(convert->surfaces); + surface = gst_vaapi_video_pool_get_object(upload->surfaces); if (surface) { image = gst_vaapi_surface_derive_image(surface); if (image) { if (gst_vaapi_image_map(image)) { - if (convert->direct_rendering_caps == 1 && + if (upload->direct_rendering_caps == 1 && (gst_vaapi_image_get_format(image) == vaformat && gst_vaapi_image_is_linear(image) && (gst_vaapi_image_get_data_size(image) == gst_video_format_get_size(vformat, width, height)))) - convert->direct_rendering_caps = 2; + upload->direct_rendering_caps = 2; gst_vaapi_image_unmap(image); } g_object_unref(image); } - gst_vaapi_video_pool_put_object(convert->surfaces, surface); + gst_vaapi_video_pool_put_object(upload->surfaces, surface); } } static gboolean -gst_vaapiconvert_negotiate_buffers( - GstVaapiConvert *convert, +gst_vaapiupload_negotiate_buffers( + GstVaapiUpload *upload, GstCaps *incaps, GstCaps *outcaps ) { guint dr; - if (!gst_vaapiconvert_ensure_image_pool(convert, incaps)) + if (!gst_vaapiupload_ensure_image_pool(upload, incaps)) return FALSE; - if (!gst_vaapiconvert_ensure_surface_pool(convert, outcaps)) + if (!gst_vaapiupload_ensure_surface_pool(upload, outcaps)) return FALSE; - gst_vaapiconvert_ensure_direct_rendering_caps(convert, incaps); - dr = MIN(convert->direct_rendering, convert->direct_rendering_caps); - if (convert->direct_rendering != dr) { - convert->direct_rendering = dr; + gst_vaapiupload_ensure_direct_rendering_caps(upload, incaps); + dr = MIN(upload->direct_rendering, upload->direct_rendering_caps); + if (upload->direct_rendering != dr) { + upload->direct_rendering = dr; GST_DEBUG("direct-rendering level: %d", dr); } return TRUE; } static gboolean -gst_vaapiconvert_set_caps( +gst_vaapiupload_set_caps( GstBaseTransform *trans, GstCaps *incaps, GstCaps *outcaps ) { - GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - if (!gst_vaapiconvert_negotiate_buffers(convert, incaps, outcaps)) + if (!gst_vaapiupload_negotiate_buffers(upload, incaps, outcaps)) return FALSE; return TRUE; } static gboolean -gst_vaapiconvert_get_unit_size( +gst_vaapiupload_get_unit_size( GstBaseTransform *trans, GstCaps *caps, guint *size @@ -670,28 +670,28 @@ gst_vaapiconvert_get_unit_size( } static GstFlowReturn -gst_vaapiconvert_buffer_alloc( +gst_vaapiupload_buffer_alloc( GstBaseTransform *trans, guint size, GstCaps *caps, GstBuffer **pbuf ) { - GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); GstBuffer *buffer = NULL; GstVaapiImage *image = NULL; GstVaapiSurface *surface = NULL; GstVaapiVideoBuffer *vbuffer; /* Check if we can use direct-rendering */ - if (!gst_vaapiconvert_negotiate_buffers(convert, caps, caps)) + if (!gst_vaapiupload_negotiate_buffers(upload, caps, caps)) goto error; - if (!convert->direct_rendering) + if (!upload->direct_rendering) return GST_FLOW_OK; - switch (convert->direct_rendering) { + switch (upload->direct_rendering) { case 2: - buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); + buffer = gst_vaapi_video_buffer_new_from_pool(upload->surfaces); if (!buffer) goto error; vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); @@ -705,12 +705,12 @@ gst_vaapiconvert_buffer_alloc( } /* We can't use the derive-image optimization. Disable it. */ - convert->direct_rendering = 1; + upload->direct_rendering = 1; gst_buffer_unref(buffer); buffer = NULL; case 1: - buffer = gst_vaapi_video_buffer_new_from_pool(convert->images); + buffer = gst_vaapi_video_buffer_new_from_pool(upload->images); if (!buffer) goto error; vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); @@ -735,12 +735,12 @@ error: GST_DEBUG("disable in/out buffer optimization"); if (buffer) gst_buffer_unref(buffer); - convert->direct_rendering = 0; + upload->direct_rendering = 0; return GST_FLOW_OK; } static GstFlowReturn -gst_vaapiconvert_sinkpad_buffer_alloc( +gst_vaapiupload_sinkpad_buffer_alloc( GstPad *pad, guint64 offset, guint size, @@ -755,13 +755,13 @@ gst_vaapiconvert_sinkpad_buffer_alloc( if (!trans) return GST_FLOW_UNEXPECTED; - ret = gst_vaapiconvert_buffer_alloc(trans, size, caps, pbuf); + ret = gst_vaapiupload_buffer_alloc(trans, size, caps, pbuf); g_object_unref(trans); return ret; } static GstFlowReturn -gst_vaapiconvert_prepare_output_buffer( +gst_vaapiupload_prepare_output_buffer( GstBaseTransform *trans, GstBuffer *inbuf, gint size, @@ -769,22 +769,22 @@ gst_vaapiconvert_prepare_output_buffer( GstBuffer **poutbuf ) { - GstVaapiConvert * const convert = GST_VAAPICONVERT(trans); + GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); GstBuffer *buffer = NULL; - if (convert->direct_rendering == 2) { + if (upload->direct_rendering == 2) { if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) { buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf); GST_BUFFER_SIZE(buffer) = size; } else { GST_DEBUG("upstream element destroyed our in/out buffer"); - convert->direct_rendering = 1; + upload->direct_rendering = 1; } } if (!buffer) { - buffer = gst_vaapi_video_buffer_new_from_pool(convert->surfaces); + buffer = gst_vaapi_video_buffer_new_from_pool(upload->surfaces); if (!buffer) return GST_FLOW_UNEXPECTED; } @@ -795,18 +795,18 @@ gst_vaapiconvert_prepare_output_buffer( } static gboolean -gst_vaapiconvert_query(GstPad *pad, GstQuery *query) +gst_vaapiupload_query(GstPad *pad, GstQuery *query) { - GstVaapiConvert *convert = GST_VAAPICONVERT (gst_pad_get_parent_element (pad)); + GstVaapiUpload *upload = GST_VAAPIUPLOAD (gst_pad_get_parent_element (pad)); gboolean res; - GST_DEBUG ("sharing display %p", convert->display); + GST_DEBUG ("sharing display %p", upload->display); - if (gst_vaapi_reply_to_query (query, convert->display)) + if (gst_vaapi_reply_to_query (query, upload->display)) res = TRUE; else res = gst_pad_query_default (pad, query); - g_object_unref (convert); + g_object_unref (upload); return res; } diff --git a/gst/vaapi/gstvaapiconvert.h b/gst/vaapi/gstvaapiupload.h similarity index 61% rename from gst/vaapi/gstvaapiconvert.h rename to gst/vaapi/gstvaapiupload.h index 7c29c6cd41..07e57717a7 100644 --- a/gst/vaapi/gstvaapiconvert.h +++ b/gst/vaapi/gstvaapiupload.h @@ -1,5 +1,5 @@ /* - * gstvaapiconvert.h - VA-API video converter + * gstvaapiupload.h - VA-API video uploader * * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems * @@ -19,8 +19,8 @@ * Boston, MA 02110-1301 USA */ -#ifndef GST_VAAPICONVERT_H -#define GST_VAAPICONVERT_H +#ifndef GST_VAAPIUPLOAD_H +#define GST_VAAPIUPLOAD_H #include #include @@ -31,37 +31,37 @@ G_BEGIN_DECLS -#define GST_TYPE_VAAPICONVERT \ - (gst_vaapiconvert_get_type()) +#define GST_TYPE_VAAPIUPLOAD \ + (gst_vaapiupload_get_type()) -#define GST_VAAPICONVERT(obj) \ +#define GST_VAAPIUPLOAD(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_TYPE_VAAPICONVERT, \ - GstVaapiConvert)) + GST_TYPE_VAAPIUPLOAD, \ + GstVaapiUpload)) -#define GST_VAAPICONVERT_CLASS(klass) \ +#define GST_VAAPIUPLOAD_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_TYPE_VAAPICONVERT, \ - GstVaapiConvertClass)) + GST_TYPE_VAAPIUPLOAD, \ + GstVaapiUploadClass)) -#define GST_IS_VAAPICONVERT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPICONVERT)) +#define GST_IS_VAAPIUPLOAD(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPIUPLOAD)) -#define GST_IS_VAAPICONVERT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPICONVERT)) +#define GST_IS_VAAPIUPLOAD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPIUPLOAD)) -#define GST_VAAPICONVERT_GET_CLASS(obj) \ +#define GST_VAAPIUPLOAD_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_TYPE_VAAPICONVERT, \ - GstVaapiConvertClass)) + GST_TYPE_VAAPIUPLOAD, \ + GstVaapiUploadClass)) -typedef struct _GstVaapiConvert GstVaapiConvert; -typedef struct _GstVaapiConvertClass GstVaapiConvertClass; +typedef struct _GstVaapiUpload GstVaapiUpload; +typedef struct _GstVaapiUploadClass GstVaapiUploadClass; /* Max output surfaces */ -#define GST_VAAPICONVERT_MAX_SURFACES 2 +#define GST_VAAPIUPLOAD_MAX_SURFACES 2 -struct _GstVaapiConvert { +struct _GstVaapiUpload { /*< private >*/ GstBaseTransform parent_instance; @@ -78,14 +78,14 @@ struct _GstVaapiConvert { unsigned int surfaces_reset : 1; }; -struct _GstVaapiConvertClass { +struct _GstVaapiUploadClass { /*< private >*/ GstBaseTransformClass parent_class; }; GType -gst_vaapiconvert_get_type(void); +gst_vaapiupload_get_type(void); G_END_DECLS -#endif /* GST_VAAPICONVERT_H */ +#endif /* GST_VAAPIUPLOAD_H */ From 12c85f69ff98ebf50dc12629ac5e4d0611bb0c0e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 3 Jan 2012 18:16:35 +0100 Subject: [PATCH 0512/3781] vaapiupload: fix memory leak in _init() function. --- gst/vaapi/gstvaapiupload.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 803b907231..410d62a7b6 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -358,6 +358,7 @@ gst_vaapiupload_init(GstVaapiUpload *upload, GstVaapiUploadClass *klass) /* Override query on src pad */ srcpad = gst_element_get_static_pad(GST_ELEMENT(upload), "src"); gst_pad_set_query_function(srcpad, gst_vaapiupload_query); + g_object_unref(srcpad); } static gboolean From ad390f3569402e7a0b86b177fffd96616ecb3406 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 4 Jan 2012 11:29:11 +0100 Subject: [PATCH 0513/3781] image: fix update from NV12 buffers. --- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 4b503cf9b1..9bb00d04a3 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -1129,7 +1129,7 @@ gst_vaapi_image_update_from_buffer( src_image.stride[0] = GST_ROUND_UP_4(width); size2 += height * src_image.stride[0]; src_image.pixels[1] = data + size2; - src_image.stride[1] = src_image.stride[1]; + src_image.stride[1] = src_image.stride[0]; size2 += height2 * src_image.stride[1]; break; case GST_VAAPI_IMAGE_YV12: From 13f00c67e61a4c72d1566fa88b7ba7ef32fe09cb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 4 Jan 2012 11:34:34 +0100 Subject: [PATCH 0514/3781] image: simplify initialization of raw images from video buffers. --- gst-libs/gst/vaapi/gstvaapiimage.c | 154 +++++++++++++++-------------- 1 file changed, 81 insertions(+), 73 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 9bb00d04a3..f0aa730d1a 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -913,6 +913,83 @@ gst_vaapi_image_get_data_size(GstVaapiImage *image) return image->priv->image.data_size; } +static gboolean +init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) +{ + GstStructure *structure; + GstCaps *caps; + GstVaapiImageFormat format; + guint width2, height2, size2; + gint width, height; + guchar *data; + guint32 data_size; + + data = GST_BUFFER_DATA(buffer); + data_size = GST_BUFFER_SIZE(buffer); + caps = GST_BUFFER_CAPS(buffer); + + if (!caps) + return FALSE; + + format = gst_vaapi_image_format_from_caps(caps); + + structure = gst_caps_get_structure(caps, 0); + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + + /* XXX: copied from gst_video_format_get_row_stride() -- no NV12? */ + raw_image->format = format; + raw_image->width = width; + raw_image->height = height; + width2 = (width + 1) / 2; + height2 = (height + 1) / 2; + size2 = 0; + switch (format) { + case GST_VAAPI_IMAGE_NV12: + raw_image->num_planes = 2; + raw_image->pixels[0] = data; + raw_image->stride[0] = GST_ROUND_UP_4(width); + size2 += height * raw_image->stride[0]; + raw_image->pixels[1] = data + size2; + raw_image->stride[1] = raw_image->stride[0]; + size2 += height2 * raw_image->stride[1]; + break; + case GST_VAAPI_IMAGE_YV12: + case GST_VAAPI_IMAGE_I420: + raw_image->num_planes = 3; + raw_image->pixels[0] = data; + raw_image->stride[0] = GST_ROUND_UP_4(width); + size2 += height * raw_image->stride[0]; + raw_image->pixels[1] = data + size2; + raw_image->stride[1] = GST_ROUND_UP_4(width2); + size2 += height2 * raw_image->stride[1]; + raw_image->pixels[2] = data + size2; + raw_image->stride[2] = raw_image->stride[1]; + size2 += height2 * raw_image->stride[2]; + break; + case GST_VAAPI_IMAGE_ARGB: + case GST_VAAPI_IMAGE_RGBA: + case GST_VAAPI_IMAGE_ABGR: + case GST_VAAPI_IMAGE_BGRA: + raw_image->num_planes = 1; + raw_image->pixels[0] = data; + raw_image->stride[0] = width * 4; + size2 += height * raw_image->stride[0]; + break; + default: + g_error("could not compute row-stride for %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS(format)); + return FALSE; + } + + if (size2 != data_size) { + g_error("data_size mismatch %d / %u", size2, data_size); + if (size2 > data_size) + return FALSE; + } + return TRUE; +} + /* Copy N lines of an image */ static inline void memcpy_pic( @@ -1080,94 +1157,25 @@ gst_vaapi_image_update_from_buffer( ) { GstVaapiImagePrivate *priv; - GstStructure *structure; - GstCaps *caps; - GstVaapiImageFormat format; GstVaapiImageRaw dst_image, src_image; - guint width2, height2, size2; - gint width, height; - guchar *data; - guint32 data_size; gboolean success; g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); g_return_val_if_fail(image->priv->is_constructed, FALSE); g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE); - priv = image->priv; - data = GST_BUFFER_DATA(buffer); - data_size = GST_BUFFER_SIZE(buffer); - caps = GST_BUFFER_CAPS(buffer); + priv = image->priv; - if (!caps) + if (!init_image_from_buffer(&src_image, buffer)) return FALSE; - - format = gst_vaapi_image_format_from_caps(caps); - if (format != priv->format) + if (src_image.format != priv->format) return FALSE; - - structure = gst_caps_get_structure(caps, 0); - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); - if (width != priv->width || height != priv->height) + if (src_image.width != priv->width || src_image.height != priv->height) return FALSE; if (!_gst_vaapi_image_map(image, &dst_image)) return FALSE; - /* XXX: copied from gst_video_format_get_row_stride() -- no NV12? */ - src_image.format = priv->format; - src_image.width = width; - src_image.height = height; - width2 = (width + 1) / 2; - height2 = (height + 1) / 2; - size2 = 0; - switch (format) { - case GST_VAAPI_IMAGE_NV12: - src_image.num_planes = 2; - src_image.pixels[0] = data; - src_image.stride[0] = GST_ROUND_UP_4(width); - size2 += height * src_image.stride[0]; - src_image.pixels[1] = data + size2; - src_image.stride[1] = src_image.stride[0]; - size2 += height2 * src_image.stride[1]; - break; - case GST_VAAPI_IMAGE_YV12: - case GST_VAAPI_IMAGE_I420: - src_image.num_planes = 3; - src_image.pixels[0] = data; - src_image.stride[0] = GST_ROUND_UP_4(width); - size2 += height * src_image.stride[0]; - src_image.pixels[1] = data + size2; - src_image.stride[1] = GST_ROUND_UP_4(width2); - size2 += height2 * src_image.stride[1]; - src_image.pixels[2] = data + size2; - src_image.stride[2] = src_image.stride[1]; - size2 += height2 * src_image.stride[2]; - break; - case GST_VAAPI_IMAGE_ARGB: - case GST_VAAPI_IMAGE_RGBA: - case GST_VAAPI_IMAGE_ABGR: - case GST_VAAPI_IMAGE_BGRA: - src_image.num_planes = 1; - src_image.pixels[0] = data; - src_image.stride[0] = width * 4; - size2 += height * src_image.stride[0]; - break; - default: - g_error("could not compute row-stride for %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS(format)); - break; - } - - if (size2 != data_size) { - g_error("data_size mismatch %d / %u", size2, data_size); - if (size2 > data_size) { - _gst_vaapi_image_unmap(image); - return FALSE; - } - } - success = copy_image(&dst_image, &src_image, rect); if (!_gst_vaapi_image_unmap(image)) From 7f8eaa6cbfec856c2364835b9fa3c669aebd7a9d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 10:29:48 +0100 Subject: [PATCH 0515/3781] image: add helpers to extract pixels to user buffers. --- docs/reference/libs/libs-sections.txt | 2 + gst-libs/gst/vaapi/gstvaapiimage.c | 84 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiimage.h | 14 +++++ 3 files changed, 100 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 751ba64121..cfd3189c1f 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -307,6 +307,8 @@ gst_vaapi_image_get_plane_count gst_vaapi_image_get_plane gst_vaapi_image_get_pitch gst_vaapi_image_get_data_size +gst_vaapi_image_get_buffer +gst_vaapi_image_get_raw gst_vaapi_image_update_from_buffer GST_VAAPI_IMAGE diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index f0aa730d1a..49a19e5be2 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -1137,6 +1137,90 @@ copy_image( return TRUE; } +/** + * gst_vaapi_image_get_buffer: + * @image: a #GstVaapiImage + * @buffer: a #GstBuffer + * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the + * whole image + * + * Transfers pixels data contained in the @image into the #GstBuffer. + * Both image structures shall have the same format. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_image_get_buffer( + GstVaapiImage *image, + GstBuffer *buffer, + GstVaapiRectangle *rect +) +{ + GstVaapiImagePrivate *priv; + GstVaapiImageRaw dst_image, src_image; + gboolean success; + + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image->priv->is_constructed, FALSE); + g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE); + + priv = image->priv; + + if (!init_image_from_buffer(&dst_image, buffer)) + return FALSE; + if (dst_image.format != priv->format) + return FALSE; + if (dst_image.width != priv->width || dst_image.height != priv->height) + return FALSE; + + if (!_gst_vaapi_image_map(image, &src_image)) + return FALSE; + + success = copy_image(&dst_image, &src_image, rect); + + if (!_gst_vaapi_image_unmap(image)) + return FALSE; + + return success; +} + +/** + * gst_vaapi_image_get_raw: + * @image: a #GstVaapiImage + * @dst_image: a #GstVaapiImageRaw + * @buffer: a #GstBuffer + * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the + * whole image + * + * Transfers pixels data contained in the @image into the #GstVaapiImageRaw. + * Both image structures shall have the same format. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_image_get_raw( + GstVaapiImage *image, + GstVaapiImageRaw *dst_image, + GstVaapiRectangle *rect +) +{ + GstVaapiImageRaw src_image; + gboolean success; + + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image->priv->is_constructed, FALSE); + + if (!_gst_vaapi_image_map(image, &src_image)) + return FALSE; + + success = copy_image(dst_image, &src_image, rect); + + if (!_gst_vaapi_image_unmap(image)) + return FALSE; + + return success; +} + /** * gst_vaapi_image_update_from_buffer: * @image: a #GstVaapiImage diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 5b6557f361..a2b5ba2c87 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -175,6 +175,20 @@ gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane); guint gst_vaapi_image_get_data_size(GstVaapiImage *image); +gboolean +gst_vaapi_image_get_buffer( + GstVaapiImage *image, + GstBuffer *buffer, + GstVaapiRectangle *rect +); + +gboolean +gst_vaapi_image_get_raw( + GstVaapiImage *image, + GstVaapiImageRaw *dst_image, + GstVaapiRectangle *rect +); + gboolean gst_vaapi_image_update_from_buffer( GstVaapiImage *image, From 872694fda58a725890fc8ff9f0a3f5bf9aabc88d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 11:00:39 +0100 Subject: [PATCH 0516/3781] vaapipluingutils: add helper to append surface caps to YUV caps. --- gst/vaapi/gstvaapipluginutil.c | 28 ++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 3 +++ 2 files changed, 31 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index a95fb8c66b..84e89d59b2 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -160,3 +160,31 @@ gst_vaapi_reply_to_query (GstQuery *query, GstVaapiDisplay *display) return res; } + +gboolean +gst_vaapi_append_surface_caps (GstCaps *out_caps, GstCaps *in_caps) +{ + GstStructure *structure; + const GValue *v_width, *v_height, *v_framerate, *v_par; + guint i, n_structures; + + structure = gst_caps_get_structure (in_caps, 0); + v_width = gst_structure_get_value (structure, "width"); + v_height = gst_structure_get_value (structure, "height"); + v_framerate = gst_structure_get_value (structure, "framerate"); + v_par = gst_structure_get_value (structure, "pixel-aspect-ratio"); + if (!v_width || !v_height) + return FALSE; + + n_structures = gst_caps_get_size (out_caps); + for (i = 0; i < n_structures; i++) { + structure = gst_caps_get_structure (out_caps, i); + gst_structure_set_value (structure, "width", v_width); + gst_structure_set_value (structure, "height", v_height); + if (v_framerate) + gst_structure_set_value (structure, "framerate", v_framerate); + if (v_par) + gst_structure_set_value (structure, "pixel-aspect-ratio", v_par); + } + return TRUE; +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 3d31938a5a..704ed370f7 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -28,3 +28,6 @@ gboolean gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display); void gst_vaapi_set_display (const gchar *type, const GValue *value, GstVaapiDisplay **display); gboolean gst_vaapi_reply_to_query (GstQuery *query, GstVaapiDisplay *display); + +gboolean +gst_vaapi_append_surface_caps (GstCaps *out_caps, GstCaps *in_caps); From 6ca190b4c5143f9218eb078a61cb21cd0cb8e863 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 10:50:59 +0100 Subject: [PATCH 0517/3781] vaapidownload: add new plugin to download pixels from VA surfaces. --- README | 3 + docs/reference/plugins/plugins-docs.xml.in | 1 + docs/reference/plugins/plugins-sections.txt | 14 + docs/reference/plugins/plugins.types | 1 + gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapi.c | 4 + gst/vaapi/gstvaapidownload.c | 614 ++++++++++++++++++++ gst/vaapi/gstvaapidownload.h | 66 +++ 8 files changed, 705 insertions(+) create mode 100644 gst/vaapi/gstvaapidownload.c create mode 100644 gst/vaapi/gstvaapidownload.h diff --git a/README b/README index 3aa80aa2dc..6c10464554 100644 --- a/README +++ b/README @@ -26,6 +26,9 @@ GStreamer and helper libraries. * `vaapiupload' is used to convert from video/x-raw-yuv pixels to video/x-vaapi-surface surfaces. + * `vaapidownload' is used to convert from video-x-vaapi-surface + surfaces to video/x-raw-yuv pixels. + * `vaapisink' is used to display video/x-vaapi-surface surfaces to screen. diff --git a/docs/reference/plugins/plugins-docs.xml.in b/docs/reference/plugins/plugins-docs.xml.in index b02060fd15..550355ec3c 100644 --- a/docs/reference/plugins/plugins-docs.xml.in +++ b/docs/reference/plugins/plugins-docs.xml.in @@ -12,6 +12,7 @@ gst-plugins-vaapi Plugins + diff --git a/docs/reference/plugins/plugins-sections.txt b/docs/reference/plugins/plugins-sections.txt index 9db963afdb..48cd444543 100644 --- a/docs/reference/plugins/plugins-sections.txt +++ b/docs/reference/plugins/plugins-sections.txt @@ -39,3 +39,17 @@ GST_VAAPIUPLOAD_CLASS GST_IS_VAAPIUPLOAD_CLASS GST_VAAPIUPLOAD_GET_CLASS + +
+gstvaapidownload +GstVaapiDownload +GstVaapiDownload + +GST_VAAPIDOWNLOAD +GST_IS_VAAPIDOWNLOAD +GST_TYPE_VAAPIDOWNLOAD +gst_vaapidownload_get_type +GST_VAAPIDOWNLOAD_CLASS +GST_IS_VAAPIDOWNLOAD_CLASS +GST_VAAPIDOWNLOAD_GET_CLASS +
diff --git a/docs/reference/plugins/plugins.types b/docs/reference/plugins/plugins.types index a6b5ab9c02..72cb6a404d 100644 --- a/docs/reference/plugins/plugins.types +++ b/docs/reference/plugins/plugins.types @@ -1,3 +1,4 @@ gst_vaapisink_get_type gst_vaapidecode_get_type +gst_vaapidownload_get_type gst_vaapiupload_get_type diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 3ff3b4ac47..5be00766a2 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -18,6 +18,7 @@ endif libgstvaapi_la_SOURCES = \ gstvaapi.c \ gstvaapidecode.c \ + gstvaapidownload.c \ gstvaapipluginutil.c \ gstvaapisink.c \ gstvaapiupload.c \ @@ -25,6 +26,7 @@ libgstvaapi_la_SOURCES = \ noinst_HEADERS = \ gstvaapidecode.h \ + gstvaapidownload.h \ gstvaapipluginutil.h \ gstvaapisink.h \ gstvaapiupload.h \ diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 44fb2e898c..89db5e764b 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -27,6 +27,7 @@ #include +#include "gstvaapidownload.h" #include "gstvaapiupload.h" #include "gstvaapidecode.h" #include "gstvaapisink.h" @@ -34,6 +35,9 @@ static gboolean plugin_init (GstPlugin *plugin) { + gst_element_register(plugin, "vaapidownload", + GST_RANK_SECONDARY, + GST_TYPE_VAAPIDOWNLOAD); gst_element_register(plugin, "vaapiupload", GST_RANK_PRIMARY, GST_TYPE_VAAPIUPLOAD); diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c new file mode 100644 index 0000000000..2c02535572 --- /dev/null +++ b/gst/vaapi/gstvaapidownload.c @@ -0,0 +1,614 @@ +/* + * gstvaapidownload.c - VA-API video downloader + * + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation + * + * 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:gstvaapidownload + * @short_description: A VA to video flow filter + * + * vaapidownload converts from VA surfaces to raw YUV pixels. + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#if USE_VAAPI_GLX +#include +#define gst_vaapi_video_buffer_new_from_pool(pool) \ + gst_vaapi_video_buffer_glx_new_from_pool(pool) +#define gst_vaapi_video_buffer_new_from_buffer(buffer) \ + gst_vaapi_video_buffer_glx_new_from_buffer(buffer) +#endif + +#include "gstvaapipluginutil.h" +#include "gstvaapidownload.h" + +#define GST_PLUGIN_NAME "vaapidownload" +#define GST_PLUGIN_DESC "A VA to video flow filter" + +GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapidownload); +#define GST_CAT_DEFAULT gst_debug_vaapidownload + +/* ElementFactory information */ +static const GstElementDetails gst_vaapidownload_details = + GST_ELEMENT_DETAILS( + "VA-API colorspace converter", + "Filter/Converter/Video", + GST_PLUGIN_DESC, + "Gwenole Beauchesne "); + +/* Default templates */ +static const char gst_vaapidownload_yuv_caps_str[] = + "video/x-raw-yuv, " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]; "; + +static const char gst_vaapidownload_vaapi_caps_str[] = + GST_VAAPI_SURFACE_CAPS; + +static GstStaticPadTemplate gst_vaapidownload_sink_factory = + GST_STATIC_PAD_TEMPLATE( + "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS(gst_vaapidownload_vaapi_caps_str)); + +static GstStaticPadTemplate gst_vaapidownload_src_factory = + GST_STATIC_PAD_TEMPLATE( + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS(gst_vaapidownload_yuv_caps_str)); + +typedef struct _TransformSizeCache TransformSizeCache; +struct _TransformSizeCache { + GstCaps *caps; + guint size; +}; + +struct _GstVaapiDownload { + /*< private >*/ + GstBaseTransform parent_instance; + + GstVaapiDisplay *display; + GstCaps *allowed_caps; + TransformSizeCache transform_size_cache[2]; + GstVaapiVideoPool *images; + GstVaapiImageFormat image_format; + guint image_width; + guint image_height; + unsigned int images_reset : 1; +}; + +struct _GstVaapiDownloadClass { + /*< private >*/ + GstBaseTransformClass parent_class; +}; + +#define GstVideoContextClass GstVideoContextInterface +GST_BOILERPLATE_WITH_INTERFACE( + GstVaapiDownload, + gst_vaapidownload, + GstBaseTransform, + GST_TYPE_BASE_TRANSFORM, + GstVideoContext, + GST_TYPE_VIDEO_CONTEXT, + gst_video_context); + +static gboolean +gst_vaapidownload_start(GstBaseTransform *trans); + +static gboolean +gst_vaapidownload_stop(GstBaseTransform *trans); + +static void +gst_vaapidownload_before_transform(GstBaseTransform *trans, GstBuffer *buffer); + +static GstFlowReturn +gst_vaapidownload_transform( + GstBaseTransform *trans, + GstBuffer *inbuf, + GstBuffer *outbuf +); + +static GstCaps * +gst_vaapidownload_transform_caps( + GstBaseTransform *trans, + GstPadDirection direction, + GstCaps *caps +); + +static gboolean +gst_vaapidownload_transform_size( + GstBaseTransform *trans, + GstPadDirection direction, + GstCaps *caps, + guint size, + GstCaps *othercaps, + guint *othersize +); + +static gboolean +gst_vaapidownload_set_caps( + GstBaseTransform *trans, + GstCaps *incaps, + GstCaps *outcaps +); + +static gboolean +gst_vaapidownload_query( + GstPad *pad, + GstQuery *query +); + +/* GstVideoContext interface */ + +static void +gst_vaapidownload_set_video_context(GstVideoContext *context, const gchar *type, + const GValue *value) +{ + GstVaapiDownload *download = GST_VAAPIDOWNLOAD (context); + gst_vaapi_set_display (type, value, &download->display); +} + +static gboolean +gst_video_context_supported (GstVaapiDownload *download, GType iface_type) +{ + return (iface_type == GST_TYPE_VIDEO_CONTEXT); +} + +static void +gst_video_context_interface_init(GstVideoContextInterface *iface) +{ + iface->set_context = gst_vaapidownload_set_video_context; +} + +static void +gst_vaapidownload_destroy(GstVaapiDownload *download) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS(download->transform_size_cache); i++) { + TransformSizeCache * const tsc = &download->transform_size_cache[i]; + if (tsc->caps) { + gst_caps_unref(tsc->caps); + tsc->caps = NULL; + tsc->size = 0; + } + } + + if (download->allowed_caps) { + gst_caps_unref(download->allowed_caps); + download->allowed_caps = NULL; + } + + if (download->images) { + g_object_unref(download->images); + download->images = NULL; + } + + if (download->display) { + g_object_unref(download->display); + download->display = NULL; + } +} + +static void +gst_vaapidownload_base_init(gpointer klass) +{ + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + + gst_element_class_set_details(element_class, &gst_vaapidownload_details); + + /* sink pad */ + gst_element_class_add_pad_template( + element_class, + gst_static_pad_template_get(&gst_vaapidownload_sink_factory) + ); + + /* src pad */ + gst_element_class_add_pad_template( + element_class, + gst_static_pad_template_get(&gst_vaapidownload_src_factory) + ); +} + +static void +gst_vaapidownload_finalize(GObject *object) +{ + gst_vaapidownload_destroy(GST_VAAPIDOWNLOAD(object)); + + G_OBJECT_CLASS(parent_class)->finalize(object); +} + +static void +gst_vaapidownload_class_init(GstVaapiDownloadClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); + + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidownload, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + object_class->finalize = gst_vaapidownload_finalize; + trans_class->start = gst_vaapidownload_start; + trans_class->stop = gst_vaapidownload_stop; + trans_class->before_transform = gst_vaapidownload_before_transform; + trans_class->transform = gst_vaapidownload_transform; + trans_class->transform_caps = gst_vaapidownload_transform_caps; + trans_class->transform_size = gst_vaapidownload_transform_size; + trans_class->set_caps = gst_vaapidownload_set_caps; +} + +static void +gst_vaapidownload_init(GstVaapiDownload *download, GstVaapiDownloadClass *klass) +{ + GstPad *sinkpad, *srcpad; + + download->display = NULL; + download->allowed_caps = NULL; + download->images = NULL; + download->images_reset = FALSE; + download->image_format = (GstVaapiImageFormat)0; + download->image_width = 0; + download->image_height = 0; + + /* Override buffer allocator on sink pad */ + sinkpad = gst_element_get_static_pad(GST_ELEMENT(download), "sink"); + gst_pad_set_query_function(sinkpad, gst_vaapidownload_query); + gst_object_unref(sinkpad); + + /* Override query on src pad */ + srcpad = gst_element_get_static_pad(GST_ELEMENT(download), "src"); + gst_pad_set_query_function(srcpad, gst_vaapidownload_query); + gst_object_unref(srcpad); +} + +static gboolean +gst_vaapidownload_start(GstBaseTransform *trans) +{ + GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); + + if (!gst_vaapi_ensure_display(download, &download->display)) + return FALSE; + return TRUE; +} + +static gboolean +gst_vaapidownload_stop(GstBaseTransform *trans) +{ + GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); + + if (download->display) { + g_object_unref(download->display); + download->display = NULL; + } + return TRUE; +} + +static GstVaapiImageFormat +get_surface_format(GstVaapiSurface *surface) +{ + GstVaapiImage *image; + GstVaapiImageFormat format = GST_VAAPI_IMAGE_NV12; + + /* XXX: NV12 is assumed by default */ + image = gst_vaapi_surface_derive_image(surface); + if (image) { + format = gst_vaapi_image_get_format(image); + g_object_unref(image); + } + return format; +} + +static gboolean +gst_vaapidownload_update_src_caps(GstVaapiDownload *download, GstBuffer *buffer) +{ + GstVaapiVideoBuffer *vbuffer; + GstVaapiSurface *surface; + GstVaapiImageFormat format; + GstPad *srcpad; + GstCaps *in_caps, *out_caps; + + vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); + surface = gst_vaapi_video_buffer_get_surface(vbuffer); + if (!surface) { + GST_WARNING("failed to retrieve VA surface from buffer"); + return FALSE; + } + + format = get_surface_format(surface); + if (format == download->image_format) + return TRUE; + + in_caps = GST_BUFFER_CAPS(buffer); + if (!in_caps) { + GST_WARNING("failed to retrieve caps from buffer"); + return FALSE; + } + + out_caps = gst_vaapi_image_format_get_caps(format); + if (!out_caps) { + GST_WARNING("failed to create caps from format %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS(format)); + return FALSE; + } + + if (!gst_vaapi_append_surface_caps(out_caps, in_caps)) { + gst_caps_unref(out_caps); + return FALSE; + } + + /* Try to renegotiate downstream caps */ + srcpad = gst_element_get_static_pad(GST_ELEMENT(download), "src"); + gst_pad_set_caps(srcpad, out_caps); + gst_object_unref(srcpad); + + gst_vaapidownload_set_caps(GST_BASE_TRANSFORM(download), in_caps, out_caps); + gst_caps_replace(&download->allowed_caps, out_caps); + gst_caps_unref(out_caps); + return TRUE; +} + +static void +gst_vaapidownload_before_transform(GstBaseTransform *trans, GstBuffer *buffer) +{ + GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); + + gst_vaapidownload_update_src_caps(download, buffer); +} + +static GstFlowReturn +gst_vaapidownload_transform( + GstBaseTransform *trans, + GstBuffer *inbuf, + GstBuffer *outbuf +) +{ + GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); + GstVaapiVideoBuffer *vbuffer; + GstVaapiSurface *surface; + GstVaapiImage *image = NULL; + gboolean success; + + vbuffer = GST_VAAPI_VIDEO_BUFFER(inbuf); + surface = gst_vaapi_video_buffer_get_surface(vbuffer); + if (!surface) + return GST_FLOW_UNEXPECTED; + + image = gst_vaapi_video_pool_get_object(download->images); + if (!image) + return GST_FLOW_UNEXPECTED; + if (!gst_vaapi_surface_get_image(surface, image)) + goto error_get_image; + + success = gst_vaapi_image_get_buffer(image, outbuf, NULL); + gst_vaapi_video_pool_put_object(download->images, image); + if (!success) + goto error_get_buffer; + return GST_FLOW_OK; + +error_get_image: + { + GST_WARNING("failed to download %" GST_FOURCC_FORMAT " image " + "from surface 0x%08x", + GST_FOURCC_ARGS(gst_vaapi_image_get_format(image)), + gst_vaapi_surface_get_id(surface)); + gst_vaapi_video_pool_put_object(download->images, image); + return GST_FLOW_UNEXPECTED; + } + +error_get_buffer: + { + GST_WARNING("failed to transfer image to output video buffer"); + return GST_FLOW_UNEXPECTED; + } +} + +static GstCaps * +gst_vaapidownload_transform_caps( + GstBaseTransform *trans, + GstPadDirection direction, + GstCaps *caps +) +{ + GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); + GstPad *srcpad; + GstCaps *allowed_caps, *inter_caps, *out_caps = NULL; + GstStructure *structure; + + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + structure = gst_caps_get_structure(caps, 0); + + if (direction == GST_PAD_SINK) { + if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) + return NULL; + if (!gst_vaapi_ensure_display(download, &download->display)) + return NULL; + out_caps = gst_caps_from_string(gst_vaapidownload_yuv_caps_str); + + /* Build up allowed caps */ + /* XXX: we don't know the decoded surface format yet so we + expose whatever VA images we support */ + if (download->allowed_caps) + allowed_caps = gst_caps_ref(download->allowed_caps); + else { + allowed_caps = gst_vaapi_display_get_image_caps(download->display); + if (!allowed_caps) + return NULL; + } + inter_caps = gst_caps_intersect(out_caps, allowed_caps); + gst_caps_unref(allowed_caps); + gst_caps_unref(out_caps); + out_caps = inter_caps; + + /* Intersect with allowed caps from the peer, if any */ + srcpad = gst_element_get_static_pad(GST_ELEMENT(download), "src"); + allowed_caps = gst_pad_peer_get_caps(srcpad); + if (allowed_caps) { + inter_caps = gst_caps_intersect(out_caps, allowed_caps); + gst_caps_unref(allowed_caps); + gst_caps_unref(out_caps); + out_caps = inter_caps; + } + } + else { + if (!gst_structure_has_name(structure, "video/x-raw-yuv")) + return NULL; + out_caps = gst_caps_from_string(gst_vaapidownload_vaapi_caps_str); + + structure = gst_caps_get_structure(out_caps, 0); + gst_structure_set( + structure, + "type", G_TYPE_STRING, "vaapi", + "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, + NULL + ); + } + + if (!gst_vaapi_append_surface_caps(out_caps, caps)) { + gst_caps_unref(out_caps); + return NULL; + } + return out_caps; +} + +static gboolean +gst_vaapidownload_ensure_image_pool(GstVaapiDownload *download, GstCaps *caps) +{ + GstStructure * const structure = gst_caps_get_structure(caps, 0); + GstVaapiImageFormat format; + gint width, height; + + format = gst_vaapi_image_format_from_caps(caps); + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + + if (format != download->image_format || + width != download->image_width || + height != download->image_height) { + download->image_format = format; + download->image_width = width; + download->image_height = height; + if (download->images) + g_object_unref(download->images); + download->images = gst_vaapi_image_pool_new(download->display, caps); + if (!download->images) + return FALSE; + download->images_reset = TRUE; + } + return TRUE; +} + +static inline gboolean +gst_vaapidownload_negotiate_buffers( + GstVaapiDownload *download, + GstCaps *incaps, + GstCaps *outcaps +) +{ + if (!gst_vaapidownload_ensure_image_pool(download, outcaps)) + return FALSE; + return TRUE; +} + +static gboolean +gst_vaapidownload_set_caps( + GstBaseTransform *trans, + GstCaps *incaps, + GstCaps *outcaps +) +{ + GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); + + if (!gst_vaapidownload_negotiate_buffers(download, incaps, outcaps)) + return FALSE; + return TRUE; +} + +static gboolean +gst_vaapidownload_transform_size( + GstBaseTransform *trans, + GstPadDirection direction, + GstCaps *caps, + guint size, + GstCaps *othercaps, + guint *othersize +) +{ + GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); + GstStructure * const structure = gst_caps_get_structure(othercaps, 0); + GstVideoFormat format; + gint width, height; + guint i; + + /* Lookup in cache */ + for (i = 0; i < G_N_ELEMENTS(download->transform_size_cache); i++) { + TransformSizeCache * const tsc = &download->transform_size_cache[i]; + if (tsc->caps && tsc->caps == othercaps) { + *othersize = tsc->size; + return TRUE; + } + } + + /* Compute requested buffer size */ + if (gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) + *othersize = 0; + else { + if (!gst_video_format_parse_caps(othercaps, &format, &width, &height)) + return FALSE; + *othersize = gst_video_format_get_size(format, width, height); + } + + /* Update cache */ + for (i = 0; i < G_N_ELEMENTS(download->transform_size_cache); i++) { + TransformSizeCache * const tsc = &download->transform_size_cache[i]; + if (!tsc->caps) { + gst_caps_replace(&tsc->caps, othercaps); + tsc->size = *othersize; + } + } + return TRUE; +} + +static gboolean +gst_vaapidownload_query(GstPad *pad, GstQuery *query) +{ + GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(gst_pad_get_parent_element(pad)); + gboolean res; + + GST_DEBUG("sharing display %p", download->display); + + if (gst_vaapi_reply_to_query(query, download->display)) + res = TRUE; + else + res = gst_pad_query_default(pad, query); + + g_object_unref(download); + return res; + +} diff --git a/gst/vaapi/gstvaapidownload.h b/gst/vaapi/gstvaapidownload.h new file mode 100644 index 0000000000..b15235aa91 --- /dev/null +++ b/gst/vaapi/gstvaapidownload.h @@ -0,0 +1,66 @@ +/* + * gstvaapidownload.h - VA-API video downloader + * + * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA +*/ + +#ifndef GST_VAAPIDOWNLOAD_H +#define GST_VAAPIDOWNLOAD_H + +#include +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIDOWNLOAD \ + (gst_vaapidownload_get_type()) + +#define GST_VAAPIDOWNLOAD(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_TYPE_VAAPIDOWNLOAD, \ + GstVaapiDownload)) + +#define GST_VAAPIDOWNLOAD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_TYPE_VAAPIDOWNLOAD, \ + GstVaapiDownloadClass)) + +#define GST_IS_VAAPIDOWNLOAD(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPIDOWNLOAD)) + +#define GST_IS_VAAPIDOWNLOAD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPIDOWNLOAD)) + +#define GST_VAAPIDOWNLOAD_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_TYPE_VAAPIDOWNLOAD, \ + GstVaapiDownloadClass)) + +typedef struct _GstVaapiDownload GstVaapiDownload; +typedef struct _GstVaapiDownloadClass GstVaapiDownloadClass; + +GType +gst_vaapidownload_get_type(void); + +G_END_DECLS + +#endif /* GST_VAAPIDOWNLOAD_H */ From 0de8b8cce1751d3685c5363663080b79098436d5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 10:55:34 +0100 Subject: [PATCH 0518/3781] vaapiupload: fix sink (YUV) caps to not report type and opengl fields. --- gst/vaapi/gstvaapiupload.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 410d62a7b6..0f6a76fcba 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -470,6 +470,14 @@ gst_vaapiupload_transform_caps( if (!gst_structure_has_name(structure, "video/x-raw-yuv")) return NULL; out_caps = gst_caps_from_string(gst_vaapiupload_vaapi_caps_str); + + structure = gst_caps_get_structure(out_caps, 0); + gst_structure_set( + structure, + "type", G_TYPE_STRING, "vaapi", + "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, + NULL + ); } else { if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) @@ -490,8 +498,6 @@ gst_vaapiupload_transform_caps( structure = gst_caps_get_structure(out_caps, 0); gst_structure_set_value(structure, "width", v_width); gst_structure_set_value(structure, "height", v_height); - gst_structure_set(structure, "type", G_TYPE_STRING, "vaapi", NULL); - gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, NULL); if (v_framerate) gst_structure_set_value(structure, "framerate", v_framerate); if (v_par) From f0486c5716e055656f0836c34738e647e4fd9031 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 11:01:56 +0100 Subject: [PATCH 0519/3781] vaapiupload: use new gst_vaapi_append_surface_caps() helper. This also fixes extra structures, beyond the one at index 0, to hold the right additional values. --- gst/vaapi/gstvaapiupload.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 0f6a76fcba..282bb09269 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -453,18 +453,10 @@ gst_vaapiupload_transform_caps( GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); GstCaps *out_caps = NULL; GstStructure *structure; - const GValue *v_width, *v_height, *v_framerate, *v_par; g_return_val_if_fail(GST_IS_CAPS(caps), NULL); - structure = gst_caps_get_structure(caps, 0); - v_width = gst_structure_get_value(structure, "width"); - v_height = gst_structure_get_value(structure, "height"); - v_framerate = gst_structure_get_value(structure, "framerate"); - v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); - - if (!v_width || !v_height) - return NULL; + structure = gst_caps_get_structure(caps, 0); if (direction == GST_PAD_SINK) { if (!gst_structure_has_name(structure, "video/x-raw-yuv")) @@ -495,13 +487,10 @@ gst_vaapiupload_transform_caps( } } - structure = gst_caps_get_structure(out_caps, 0); - gst_structure_set_value(structure, "width", v_width); - gst_structure_set_value(structure, "height", v_height); - if (v_framerate) - gst_structure_set_value(structure, "framerate", v_framerate); - if (v_par) - gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); + if (!gst_vaapi_append_surface_caps(out_caps, caps)) { + gst_caps_unref(out_caps); + return NULL; + } return out_caps; } From 119402d5b93cf9a25b09bff1bdf975f3a356e7da Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 11:23:01 +0100 Subject: [PATCH 0520/3781] debian: update control.in description for new plugins. --- debian.upstream/control.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 98bbdfac6d..1cf3477d6f 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -18,7 +18,9 @@ Depends: ${shlibs:Depends}, ${misc:Depends} Suggests: gstreamer@GST_MAJORMINOR@-vaapi-doc Description: VA-API plugins for GStreamer This package contains GStreamer plugins for VA-API support: + - `vaapidecode': decode bitstreams using VA-API - `vaapiupload': converts from YUV pixels to VA surfaces + - `vaapidownload': convert from VA surfaces to YUV pixels - `vaapisink': a VA-API based video sink Package: gstreamer@GST_MAJORMINOR@-vaapi-doc From 0afd2e5c425eb1538b5c470c514306194acc19cc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 14:50:26 +0100 Subject: [PATCH 0521/3781] context: avoid self reference loops with surfaces. --- gst-libs/gst/vaapi/gstvaapicontext.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 29654cd3a5..f982fe02dc 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -271,7 +271,6 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context) g_ptr_array_add(priv->surfaces, surface); if (!gst_vaapi_video_pool_add_object(priv->surfaces_pool, surface)) return FALSE; - gst_vaapi_surface_set_parent_context(surface, context); } return TRUE; } @@ -707,9 +706,16 @@ gst_vaapi_context_get_size( GstVaapiSurface * gst_vaapi_context_get_surface(GstVaapiContext *context) { + GstVaapiSurface *surface; + g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); - return gst_vaapi_video_pool_get_object(context->priv->surfaces_pool); + surface = gst_vaapi_video_pool_get_object(context->priv->surfaces_pool); + if (!surface) + return NULL; + + gst_vaapi_surface_set_parent_context(surface, context); + return surface; } /** @@ -741,6 +747,7 @@ gst_vaapi_context_put_surface(GstVaapiContext *context, GstVaapiSurface *surface g_return_if_fail(GST_VAAPI_IS_CONTEXT(context)); g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); + gst_vaapi_surface_set_parent_context(surface, NULL); gst_vaapi_video_pool_put_object(context->priv->surfaces_pool, surface); } From 48cefaf9ce81225b59d0e4b7d320bb229a6e9301 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 16:26:49 +0100 Subject: [PATCH 0522/3781] vaapidecode: fix deinitialization order. --- gst/vaapi/gstvaapidecode.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 81d08a9e21..a5f0b0c5d3 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -301,17 +301,6 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { - if (decode->decoder_ready) { - gst_vaapidecode_release(decode, NULL); - g_cond_free(decode->decoder_ready); - decode->decoder_ready = NULL; - } - - if (decode->decoder_mutex) { - g_mutex_free(decode->decoder_mutex); - decode->decoder_mutex = NULL; - } - if (decode->decoder) { gst_vaapi_decoder_put_buffer(decode->decoder, NULL); g_object_unref(decode->decoder); @@ -322,6 +311,17 @@ gst_vaapidecode_destroy(GstVaapiDecode *decode) gst_caps_unref(decode->decoder_caps); decode->decoder_caps = NULL; } + + if (decode->decoder_ready) { + gst_vaapidecode_release(decode, NULL); + g_cond_free(decode->decoder_ready); + decode->decoder_ready = NULL; + } + + if (decode->decoder_mutex) { + g_mutex_free(decode->decoder_mutex); + decode->decoder_mutex = NULL; + } } static gboolean From 40f44ab60eeceb0416858afd205bdfa9e6276d58 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 16:44:44 +0100 Subject: [PATCH 0523/3781] surfaceproxy: simplify destruction. Also make sure to always make sure to release the surface back to the pool of surfaces in the associated VA context, if any. --- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 46 +++++++++++------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index f1a9206c50..80201c5fd4 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -55,19 +55,9 @@ static void gst_vaapi_surface_proxy_finalize(GObject *object) { GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(object); - GstVaapiSurfaceProxyPrivate * const priv = proxy->priv; - if (priv->surface) { - if (priv->context) - gst_vaapi_context_put_surface(priv->context, priv->surface); - g_object_unref(priv->surface); - priv->surface = NULL; - } - - if (priv->context) { - g_object_unref(priv->context); - priv->context = NULL; - } + gst_vaapi_surface_proxy_set_surface(proxy, NULL); + gst_vaapi_surface_proxy_set_context(proxy, NULL); G_OBJECT_CLASS(gst_vaapi_surface_proxy_parent_class)->finalize(object); } @@ -226,16 +216,19 @@ gst_vaapi_surface_proxy_set_context( GstVaapiContext *context ) { - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - g_return_if_fail(GST_VAAPI_IS_CONTEXT(context)); + GstVaapiSurfaceProxyPrivate *priv; - if (proxy->priv->context) { - g_object_unref(proxy->priv->context); - proxy->priv->context = NULL; + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + + priv = proxy->priv; + + if (priv->context) { + g_object_unref(priv->context); + priv->context = NULL; } if (context) - proxy->priv->context = g_object_ref(context); + priv->context = g_object_ref(context); } /** @@ -269,16 +262,21 @@ gst_vaapi_surface_proxy_set_surface( GstVaapiSurface *surface ) { - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); + GstVaapiSurfaceProxyPrivate *priv; - if (proxy->priv->surface) { - g_object_unref(proxy->priv->surface); - proxy->priv->surface = NULL; + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + + priv = proxy->priv; + + if (priv->surface) { + if (priv->context) + gst_vaapi_context_put_surface(priv->context, priv->surface); + g_object_unref(priv->surface); + priv->surface = NULL; } if (surface) - proxy->priv->surface = g_object_ref(surface); + priv->surface = g_object_ref(surface); } /** From 4e72aa587c883a859a3b0ed6ecd13b8063f8d9e9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 16:59:57 +0100 Subject: [PATCH 0524/3781] surfaceproxy: add helper to retrieve the VA surface ID. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 18 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 3 +++ 3 files changed, 22 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index cfd3189c1f..46da57a15f 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -496,6 +496,7 @@ gst_vaapi_surface_proxy_new gst_vaapi_surface_proxy_get_context gst_vaapi_surface_proxy_set_context gst_vaapi_surface_proxy_get_surface +gst_vaapi_surface_proxy_get_surface_id gst_vaapi_surface_proxy_set_surface gst_vaapi_surface_proxy_get_timestamp gst_vaapi_surface_proxy_set_timestamp diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 80201c5fd4..fc21208228 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -26,6 +26,7 @@ #include "config.h" #include "gstvaapisurfaceproxy.h" +#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -247,6 +248,23 @@ gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy) return proxy->priv->surface; } +/** + * gst_vaapi_surface_proxy_get_surface_id: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the VA surface ID stored in the @proxy. + * + * Return value: the #GstVaapiID + */ +GstVaapiID +gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), GST_VAAPI_ID_NONE); + g_return_val_if_fail(proxy->priv->surface != NULL, GST_VAAPI_ID_NONE); + + return GST_VAAPI_OBJECT_ID(proxy->priv->surface); +} + /** * gst_vaapi_surface_proxy_set_surface: * @proxy: a #GstVaapiSurfaceProxy diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index b24caf5e61..8eab401bd6 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -115,6 +115,9 @@ gst_vaapi_surface_proxy_set_context( GstVaapiSurface * gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy); +GstVaapiID +gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy); + void gst_vaapi_surface_proxy_set_surface( GstVaapiSurfaceProxy *proxy, From 3e1d235c1ac49ad07afc1da4cb68a06ab64784e5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 17:09:35 +0100 Subject: [PATCH 0525/3781] decoder: fix possible leak of VA surfaces. Under some circumstances, we could have leaked a surface, thus not releasing it to the pool of available surfaces in the VA context. The strategy is now to use a proxy earlier and automatically ref/unref whenever necessary. In particular, during the lifetime needed for FFmpeg. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 31 ++++++++++++++------- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 26 +++++++++++------ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 7 +++++ 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index c6282b7f77..fead8f0f05 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -126,20 +126,15 @@ decode_step(GstVaapiDecoder *decoder) static gboolean push_surface( - GstVaapiDecoder *decoder, - GstVaapiSurface *surface, - GstClockTime timestamp + GstVaapiDecoder *decoder, + GstVaapiSurfaceProxy *proxy, + GstClockTime timestamp ) { GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVaapiSurfaceProxy *proxy; GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); - - proxy = gst_vaapi_surface_proxy_new(priv->context, surface); - if (!proxy) - return FALSE; + GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id(proxy))); gst_vaapi_surface_proxy_set_timestamp(proxy, timestamp); g_queue_push_tail(priv->surfaces, proxy); @@ -560,5 +555,21 @@ gst_vaapi_decoder_push_surface( GstClockTime timestamp ) { - return push_surface(decoder, surface, timestamp); + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiSurfaceProxy *proxy; + + proxy = gst_vaapi_surface_proxy_new(priv->context, surface); + if (!proxy) + return FALSE; + return push_surface(decoder, proxy, timestamp); +} + +gboolean +gst_vaapi_decoder_push_surface_proxy( + GstVaapiDecoder *decoder, + GstVaapiSurfaceProxy *proxy, + GstClockTime timestamp +) +{ + return push_surface(decoder, g_object_ref(proxy), timestamp); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index e12f95785f..7224bcd3fb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -260,6 +260,7 @@ gst_vaapi_decoder_ffmpeg_get_buffer(AVCodecContext *avctx, AVFrame *pic) GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; GstVaapiContext *context; GstVaapiSurface *surface; + GstVaapiSurfaceProxy *proxy; GstVaapiID surface_id; context = get_context(avctx); @@ -272,12 +273,19 @@ gst_vaapi_decoder_ffmpeg_get_buffer(AVCodecContext *avctx, AVFrame *pic) return -1; } + proxy = gst_vaapi_surface_proxy_new(context, surface); + if (!proxy) { + GST_DEBUG("failed to create proxy surface"); + gst_vaapi_context_put_surface(context, surface); + return -1; + } + surface_id = GST_VAAPI_OBJECT_ID(surface); GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); pic->type = FF_BUFFER_TYPE_USER; pic->age = 1; - pic->data[0] = (uint8_t *)surface; + pic->data[0] = (uint8_t *)proxy; pic->data[1] = NULL; pic->data[2] = NULL; pic->data[3] = (uint8_t *)(uintptr_t)surface_id; @@ -301,10 +309,13 @@ gst_vaapi_decoder_ffmpeg_reget_buffer(AVCodecContext *avctx, AVFrame *pic) static void gst_vaapi_decoder_ffmpeg_release_buffer(AVCodecContext *avctx, AVFrame *pic) { + GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(pic->data[0]); GstVaapiID surface_id = GST_VAAPI_ID(GPOINTER_TO_UINT(pic->data[3])); GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); + g_object_unref(proxy); + pic->data[0] = NULL; pic->data[1] = NULL; pic->data[2] = NULL; @@ -477,7 +488,7 @@ decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) { GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(ffdecoder); - GstVaapiSurface *surface; + GstVaapiSurfaceProxy *proxy; int bytes_read, got_picture = 0; AVPacket pkt; @@ -498,15 +509,12 @@ decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) if (bytes_read < 0) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - surface = gst_vaapi_context_find_surface_by_id( - GST_VAAPI_DECODER_CONTEXT(ffdecoder), - GPOINTER_TO_UINT(priv->frame->data[3]) - ); - if (!surface) + proxy = GST_VAAPI_SURFACE_PROXY(priv->frame->data[0]); + if (!proxy) return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; - if (!gst_vaapi_decoder_push_surface(GST_VAAPI_DECODER_CAST(ffdecoder), - surface, priv->frame->pts)) + if (!gst_vaapi_decoder_push_surface_proxy(GST_VAAPI_DECODER_CAST(ffdecoder), + proxy, priv->frame->pts)) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; return GST_VAAPI_DECODER_STATUS_SUCCESS; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 52ddc22b62..d6e696fb47 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -169,6 +169,13 @@ gst_vaapi_decoder_push_surface( GstClockTime timestamp ) attribute_hidden; +gboolean +gst_vaapi_decoder_push_surface_proxy( + GstVaapiDecoder *decoder, + GstVaapiSurfaceProxy *proxy, + GstClockTime timestamp +) attribute_hidden; + G_END_DECLS #endif /* GST_VAAPI_DECODER_PRIV_H */ From 1b191126c0cf50a1571810d177380694335ffb3c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Jan 2012 17:35:12 +0100 Subject: [PATCH 0526/3781] NEWS: updates. --- NEWS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS b/NEWS index 670f571690..036d3bb593 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,11 @@ Copyright (C) 2011 Intel Corporation Version 0.3.2 - DD.Jan.2012 * Rename vaapiconvert element to vaapiupload +* Fix vaapiupload from NV12 buffers +* Fix possible leaks of VA surfaces in FFmpeg decoder +* Fix memory leak in vaapiupload initialization function +* Fix possible crash in vaapidecode deinitialization code +* Add vaapidownload element to convert from VA surfaces to YUV pixels Version 0.3.1 - 16.Dec.2011 * Fix check for supported VA images From 3181dca9f26b1c0fbfa23d2a7a82bcbe7e22993e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 6 Jan 2012 11:18:55 +0100 Subject: [PATCH 0527/3781] tests: fix make dist (ship with test-subpicture-data.h). --- tests/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Makefile.am b/tests/Makefile.am index d1c7d45804..2f54941549 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -71,6 +71,7 @@ test_textures_LDADD = $(TEST_LIBS) $(TEST_GLX_LIBS) EXTRA_DIST = \ image.h \ test-decode.h \ + test-subpicture-data.h \ $(test_codecs_source_c) \ $(test_codecs_source_h) \ $(NULL) From fed57fb14e4f251087cd6c3c23c46992b154e2d5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 6 Jan 2012 11:20:48 +0100 Subject: [PATCH 0528/3781] 0.3.2. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 036d3bb593..2ab7d04841 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,8 @@ -gst-vaapi NEWS -- summary of changes. 2012-01-DD +gst-vaapi NEWS -- summary of changes. 2012-01-06 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011 Intel Corporation -Version 0.3.2 - DD.Jan.2012 +Version 0.3.2 - 06.Jan.2012 * Rename vaapiconvert element to vaapiupload * Fix vaapiupload from NV12 buffers * Fix possible leaks of VA surfaces in FFmpeg decoder diff --git a/configure.ac b/configure.ac index 7005a7afa7..f6475e8ed0 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) m4_define([gst_vaapi_micro_version], [2]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 93ba0f858afc358aadfc56b8f5a177866a26d451 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 6 Jan 2012 11:23:21 +0100 Subject: [PATCH 0529/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index f6475e8ed0..5ea1c20aef 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) -m4_define([gst_vaapi_micro_version], [2]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [3]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 1980a719a23be5ffc2175c3ea82082daac34a57c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 6 Jan 2012 16:48:15 +0100 Subject: [PATCH 0530/3781] .gitignore: add test-subpicture. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 26ec42c0c9..93fb38efcf 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,7 @@ pkgconfig/gstreamer-vaapi-glx-0.10.pc pkgconfig/gstreamer-vaapi-x11-0.10.pc tests/test-decode tests/test-display +tests/test-subpicture tests/test-surfaces tests/test-textures tests/test-windows From c40c05e5a4e8acdfd7acd15c518bcfab1b8b7d28 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Fri, 6 Jan 2012 17:51:59 +0100 Subject: [PATCH 0531/3781] Add missing profiles from VA-API 0.32.0. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiutils.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 1530c9ea99..a99d7e8254 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -66,6 +66,11 @@ const char *string_of_VAProfile(VAProfile profile) PROFILE(MPEG4Simple); PROFILE(MPEG4AdvancedSimple); PROFILE(MPEG4Main); +#if VA_CHECK_VERSION(0,32,0) + PROFILE(JPEGBaseline); + PROFILE(H263Baseline); + PROFILE(H264ConstrainedBaseline); +#endif PROFILE(H264Baseline); PROFILE(H264Main); PROFILE(H264High); From 420402d5930dc9c9c387a1be624b33b8458e1905 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 9 Jan 2012 11:04:21 +0100 Subject: [PATCH 0532/3781] window: always check geometry when the window is mapped. --- gst-libs/gst/vaapi/gstvaapiwindow.c | 31 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index db262cfec9..58a9841381 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -41,9 +41,11 @@ G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, GST_VAAPI_TYPE_OBJECT); struct _GstVaapiWindowPrivate { guint width; guint height; + guint display_width; + guint display_height; gboolean is_constructed : 1; guint is_fullscreen : 1; - guint is_fullscreen_changed : 1; + guint check_geometry : 1; }; enum { @@ -59,22 +61,16 @@ gst_vaapi_window_ensure_size(GstVaapiWindow *window) { GstVaapiWindowPrivate * const priv = window->priv; GstVaapiWindowClass * const klass = GST_VAAPI_WINDOW_GET_CLASS(window); - guint display_width, display_height; - if (!priv->is_fullscreen_changed) + if (!priv->check_geometry) return; if (klass->get_geometry) klass->get_geometry(window, NULL, NULL, &priv->width, &priv->height); - gst_vaapi_display_get_size( - GST_VAAPI_OBJECT_DISPLAY(window), - &display_width, - &display_height - ); - priv->is_fullscreen_changed = FALSE; - priv->is_fullscreen = (priv->width == display_width && - priv->height == display_height); + priv->check_geometry = FALSE; + priv->is_fullscreen = (priv->width == priv->display_width && + priv->height == priv->display_height); } static void @@ -92,6 +88,12 @@ gst_vaapi_window_create(GstVaapiWindow *window) width = priv->width; height = priv->height; + gst_vaapi_display_get_size( + GST_VAAPI_OBJECT_DISPLAY(window), + &priv->display_width, + &priv->display_height + ); + if (!GST_VAAPI_WINDOW_GET_CLASS(window)->create(window, &width, &height)) return FALSE; @@ -226,7 +228,7 @@ gst_vaapi_window_init(GstVaapiWindow *window) priv->height = 1; priv->is_constructed = FALSE; priv->is_fullscreen = FALSE; - priv->is_fullscreen_changed = FALSE; + priv->check_geometry = FALSE; } /** @@ -259,6 +261,7 @@ gst_vaapi_window_show(GstVaapiWindow *window) g_return_if_fail(window->priv->is_constructed); GST_VAAPI_WINDOW_GET_CLASS(window)->show(window); + window->priv->check_geometry = TRUE; } /** @@ -313,8 +316,8 @@ gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) if (window->priv->is_fullscreen != fullscreen && klass->set_fullscreen && klass->set_fullscreen(window, fullscreen)) { - window->priv->is_fullscreen = fullscreen; - window->priv->is_fullscreen_changed = TRUE; + window->priv->is_fullscreen = fullscreen; + window->priv->check_geometry = TRUE; } } From 3ca1d0820ca898c08960692c19f6bf6389a4e6b8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 9 Jan 2012 10:37:30 +0100 Subject: [PATCH 0533/3781] vaapisink: implement GstXOverlay::set_render_rectangle(). --- gst/vaapi/gstvaapisink.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 7dab2710cd..52e07d1b9f 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -52,6 +52,9 @@ #define HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE \ GST_PLUGINS_BASE_CHECK_VERSION(0,10,31) +#define HAVE_GST_XOVERLAY_SET_RENDER_RECTANGLE \ + GST_PLUGINS_BASE_CHECK_VERSION(0,10,29) + #define GST_PLUGIN_NAME "vaapisink" #define GST_PLUGIN_DESC "A VA-API based videosink" @@ -161,6 +164,30 @@ gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) } #endif +#if HAVE_GST_XOVERLAY_SET_RENDER_RECTANGLE +static void +gst_vaapisink_xoverlay_set_render_rectangle( + GstXOverlay *overlay, + gint x, + gint y, + gint width, + gint height +) +{ + GstVaapiSink * const sink = GST_VAAPISINK(overlay); + GstVaapiRectangle * const display_rect = &sink->display_rect; + + display_rect->x = x; + display_rect->y = y; + display_rect->width = width; + display_rect->height = height; + + GST_DEBUG("render rect (%d,%d):%ux%u", + display_rect->x, display_rect->y, + display_rect->width, display_rect->height); +} +#endif + static void gst_vaapisink_xoverlay_expose(GstXOverlay *overlay) { @@ -178,11 +205,14 @@ static void gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface) { #if HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE - iface->set_window_handle = gst_vaapisink_xoverlay_set_window_handle; + iface->set_window_handle = gst_vaapisink_xoverlay_set_window_handle; #else - iface->set_xwindow_id = gst_vaapisink_xoverlay_set_xid; + iface->set_xwindow_id = gst_vaapisink_xoverlay_set_xid; #endif - iface->expose = gst_vaapisink_xoverlay_expose; +#if HAVE_GST_XOVERLAY_SET_RENDER_RECTANGLE + iface->set_render_rectangle = gst_vaapisink_xoverlay_set_render_rectangle; +#endif + iface->expose = gst_vaapisink_xoverlay_expose; } static void From b1aee91aa087536e6a43ddd8c4e8bc0ab56d9e5f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 9 Jan 2012 11:23:39 +0100 Subject: [PATCH 0534/3781] vaapisink: automatically fit video to window. --- gst/vaapi/gstvaapisink.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 52e07d1b9f..6b82cfacc3 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -459,7 +459,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstStructure * const structure = gst_caps_get_structure(caps, 0); - guint display_width, display_height, win_width, win_height; + guint win_width, win_height; gint video_width, video_height, video_par_n = 1, video_par_d = 1; if (!structure) @@ -479,17 +479,11 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) if (!gst_vaapi_ensure_display(sink, &sink->display)) return FALSE; - gst_vaapi_display_get_size(sink->display, &display_width, &display_height); - if (!gst_vaapisink_ensure_render_rect(sink, display_width, display_height)) - return FALSE; - - if (sink->fullscreen) { - win_width = display_width; - win_height = display_height; - } + if (sink->fullscreen) + gst_vaapi_display_get_size(sink->display, &win_width, &win_height); else { - win_width = sink->display_rect.width; - win_height = sink->display_rect.height; + win_width = video_width; + win_height = video_height; } if (sink->window) @@ -504,10 +498,13 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return FALSE; gst_vaapi_window_set_fullscreen(sink->window, sink->fullscreen); gst_vaapi_window_show(sink->window); + gst_vaapi_window_get_size(sink->window, &win_width, &win_height); } sink->window_width = win_width; sink->window_height = win_height; - return TRUE; + GST_DEBUG("window size %ux%u", win_width, win_height); + + return gst_vaapisink_ensure_render_rect(sink, win_width, win_height); } #if USE_VAAPISINK_GLX From 8866a7c2231a4c3ff656f929177fe4e739cef49f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 9 Jan 2012 16:51:35 +0100 Subject: [PATCH 0535/3781] vaapisink: fix calculation of render region. --- gst/vaapi/gstvaapisink.c | 50 +++++++++++----------------------------- 1 file changed, 13 insertions(+), 37 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 6b82cfacc3..252d5f28b3 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -293,7 +293,6 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) { GstVaapiRectangle * const display_rect = &sink->display_rect; guint num, den, display_par_n, display_par_d; - double display_ratio; gboolean success; GST_DEBUG("ensure render rect within %ux%u bounds", width, height); @@ -316,47 +315,24 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) GST_DEBUG("video size %dx%d, calculated ratio %d/%d", sink->video_width, sink->video_height, num, den); - if ((sink->video_height % den) == 0) { - GST_DEBUG("keeping video height"); - display_rect->width = - gst_util_uint64_scale_int(sink->video_height, num, den); - display_rect->height = sink->video_height; + display_rect->width = gst_util_uint64_scale_int(height, num, den); + if (display_rect->width <= width) { + GST_DEBUG("keeping window height"); + display_rect->height = height; } - else if ((sink->video_width % num) == 0) { - GST_DEBUG("keeping video width"); - display_rect->width = sink->video_width; + else { + GST_DEBUG("keeping window width"); + display_rect->width = width; display_rect->height = - gst_util_uint64_scale_int(sink->video_width, den, num); + gst_util_uint64_scale_int(width, den, num); } - else { - GST_DEBUG("approximating while keeping video height"); - display_rect->width = - gst_util_uint64_scale_int(sink->video_height, num, den); - display_rect->height = sink->video_height; - } - display_ratio = (gdouble)display_rect->width / display_rect->height; - GST_DEBUG("scaling to %ux%u", display_rect->width, display_rect->height); + GST_DEBUG("scaling video to %ux%u", display_rect->width, display_rect->height); - if (sink->fullscreen || sink->foreign_window || - display_rect->width > width || display_rect->height > height) { - if (sink->video_width > sink->video_height) { - display_rect->width = width; - display_rect->height = width / display_ratio; - } - else { - display_rect->width = height * display_ratio; - display_rect->height = height; - } - } + g_assert(display_rect->width <= width); + g_assert(display_rect->height <= height); - if (sink->fullscreen) { - display_rect->x = (width - display_rect->width) / 2; - display_rect->y = (height - display_rect->height) / 2; - } - else { - display_rect->x = 0; - display_rect->y = 0; - } + display_rect->x = (width - display_rect->width) / 2; + display_rect->y = (height - display_rect->height) / 2; GST_DEBUG("render rect (%d,%d):%ux%u", display_rect->x, display_rect->y, From c432e82e441a6e39a29bd94a9a1998aa4eb0a438 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 26 Aug 2011 15:44:46 -0400 Subject: [PATCH 0536/3781] vaapisink: don't leak GL texture. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 252d5f28b3..c2ba3ab20d 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -231,6 +231,11 @@ gst_vaapisink_iface_init(GType type) static void gst_vaapisink_destroy(GstVaapiSink *sink) { + if (sink->texture) { + g_object_unref(sink->texture); + sink->texture = NULL; + } + if (sink->display) { g_object_unref(sink->display); sink->display = NULL; From 0385750fa7bd5345d8d82e92c44a9f58a25e3426 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 11 Jan 2012 14:11:30 +0100 Subject: [PATCH 0537/3781] vaapisink: ensure VA display in GstBaseSink::start() hook. This ensures a VA display is ready by the time upstream elements request for it. --- gst/vaapi/gstvaapisink.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index c2ba3ab20d..9000fedcd2 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -415,7 +415,9 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) static gboolean gst_vaapisink_start(GstBaseSink *base_sink) { - return TRUE; + GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + + return gst_vaapi_ensure_display(sink, &sink->display); } static gboolean From b7e5a48e5e4bf14f4a24ee30ecdd889855fe92ae Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 26 Aug 2011 15:44:25 -0400 Subject: [PATCH 0538/3781] vaapiupload: only set caps on newly created buffers. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapiupload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 282bb09269..7a47b2fbbe 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -783,9 +783,9 @@ gst_vaapiupload_prepare_output_buffer( buffer = gst_vaapi_video_buffer_new_from_pool(upload->surfaces); if (!buffer) return GST_FLOW_UNEXPECTED; + gst_buffer_set_caps(buffer, caps); } - gst_buffer_set_caps(buffer, caps); *poutbuf = buffer; return GST_FLOW_OK; } From 6b03d30162205f27b4158e44b0b9f98baa95ab99 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 11 Jan 2012 14:13:06 +0100 Subject: [PATCH 0539/3781] vaapiplugin: fix gst_vaapi_ensure_display() to use system defaults. This ensures the display name provided to gst_vaapi_display_*_new() maps to the system defaults, instead of forcing "" that could be different from the current DISPLAY name. --- gst/vaapi/gstvaapipluginutil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 84e89d59b2..0db0908169 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -62,9 +62,9 @@ gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display) /* If no neighboor, or application not interested, use system default */ if (!*display) #if USE_VAAPI_GLX - *display = gst_vaapi_display_glx_new (""); + *display = gst_vaapi_display_glx_new (NULL); #else - *display = gst_vaapi_display_x11_new (""); + *display = gst_vaapi_display_x11_new (NULL); #endif /* FIXME allocator should return NULL in case of failure */ From 773272475f54de0ee5b2f3f85bcf6ae614d8bcf7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 12 Jan 2012 12:46:34 +0100 Subject: [PATCH 0540/3781] display: implement a VA display cache. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidisplay.h | 13 + gst-libs/gst/vaapi/gstvaapidisplaycache.c | 378 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplaycache.h | 76 +++++ 4 files changed, 469 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapidisplaycache.c create mode 100644 gst-libs/gst/vaapi/gstvaapidisplaycache.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 6361cc14a4..5485b5f3e5 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -25,6 +25,7 @@ libgstvaapi_source_c = \ gstvaapicontext.c \ gstvaapidecoder.c \ gstvaapidisplay.c \ + gstvaapidisplaycache.c \ gstvaapiimage.c \ gstvaapiimageformat.c \ gstvaapiimagepool.c \ @@ -49,6 +50,7 @@ libgstvaapi_source_h = \ gstvaapicontext.h \ gstvaapidecoder.h \ gstvaapidisplay.h \ + gstvaapidisplaycache.h \ gstvaapiimage.h \ gstvaapiimageformat.h \ gstvaapiimagepool.h \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 075c1f617f..0517e42626 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -58,10 +58,23 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DISPLAY, \ GstVaapiDisplayClass)) +typedef struct _GstVaapiDisplayInfo GstVaapiDisplayInfo; typedef struct _GstVaapiDisplay GstVaapiDisplay; typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; +/** + * GstVaapiDisplayInfo: + * + * Generic class to retrieve VA display info + */ +struct _GstVaapiDisplayInfo { + GstVaapiDisplay *display; + gchar *display_name; + VADisplay va_display; + gpointer native_display; +}; + /** * GstVaapiDisplay: * diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c new file mode 100644 index 0000000000..a6bb39d08e --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -0,0 +1,378 @@ +/* + * gstvaapidisplaycache.c - VA display cache + * + * Copyright (C) 2012 Intel Corporation + * + * 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 "config.h" +#include +#include +#include "gstvaapidisplaycache.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +typedef struct _CacheEntry CacheEntry; +struct _CacheEntry { + GstVaapiDisplayInfo info; +}; + +struct _GstVaapiDisplayCache { + GStaticMutex mutex; + GList *list; +}; + +static void +cache_entry_free(CacheEntry *entry) +{ + GstVaapiDisplayInfo *info; + + if (!entry) + return; + + info = &entry->info; + + if (info->display_name) { + g_free(info->display_name); + info->display_name = NULL; + } + g_slice_free(CacheEntry, entry); +} + +static CacheEntry * +cache_entry_new(const GstVaapiDisplayInfo *di) +{ + GstVaapiDisplayInfo *info; + CacheEntry *entry; + + entry = g_slice_new(CacheEntry); + if (!entry) + return NULL; + + info = &entry->info; + info->display = di->display; + info->va_display = di->va_display; + info->native_display = di->native_display; + info->display_name = NULL; + + if (di->display_name) { + info->display_name = g_strdup(di->display_name); + if (!info->display_name) + goto error; + } + return entry; + +error: + cache_entry_free(entry); + return NULL; +} + +#define CACHE_LOOKUP(cache, res, prop, comp_func, comp_data, user_data) do { \ + GList *l; \ + \ + g_static_mutex_lock(&(cache)->mutex); \ + for (l = (cache)->list; l != NULL; l = l->next) { \ + GstVaapiDisplayInfo * const info = \ + &((CacheEntry *)l->data)->info; \ + if (comp_func(info->prop, comp_data, user_data)) \ + break; \ + } \ + g_static_mutex_unlock(&(cache)->mutex); \ + res = l; \ + } while (0) + +#define compare_equal(a, b, user_data) \ + ((a) == (b)) + +#define compare_string(a, b, user_data) \ + ((a) == (b) || ((a) && (b) && strcmp(a, b) == 0)) + +static GList * +cache_lookup_display(GstVaapiDisplayCache *cache, GstVaapiDisplay *display) +{ + GList *m; + + CACHE_LOOKUP(cache, m, display, compare_equal, display, NULL); + return m; +} + +static GList * +cache_lookup_va_display(GstVaapiDisplayCache *cache, VADisplay va_display) +{ + GList *m; + + CACHE_LOOKUP(cache, m, va_display, compare_equal, va_display, NULL); + return m; +} + +static GList * +cache_lookup_native_display(GstVaapiDisplayCache *cache, gpointer native_display) +{ + GList *m; + + CACHE_LOOKUP(cache, m, native_display, compare_equal, native_display, NULL); + return m; +} + +/** + * gst_vaapi_display_cache_new: + * + * Creates a new VA display cache. + * + * Return value: the newly created #GstVaapiDisplayCache object + */ +GstVaapiDisplayCache * +gst_vaapi_display_cache_new(void) +{ + GstVaapiDisplayCache *cache; + + cache = g_slice_new0(GstVaapiDisplayCache); + if (!cache) + return NULL; + + g_static_mutex_init(&cache->mutex); + return cache; +} + +/** + * gst_vaapi_display_cache_new: + * @cache: the #GstVaapiDisplayCache to destroy + * + * Destroys a VA display cache. + */ +void +gst_vaapi_display_cache_free(GstVaapiDisplayCache *cache) +{ + GList *l; + + if (!cache) + return; + + if (cache->list) { + for (l = cache->list; l != NULL; l = l->next) + cache_entry_free(l->data); + g_list_free(cache->list); + cache->list = NULL; + } + g_slice_free(GstVaapiDisplayCache, cache); +} + +/** + * gst_vaapi_display_cache_get_size: + * @cache: the #GstVaapiDisplayCache + * + * Gets the size of the display cache @cache. + * + * Return value: the size of the display cache + */ +guint +gst_vaapi_display_cache_get_size(GstVaapiDisplayCache *cache) +{ + guint size; + + g_return_val_if_fail(cache != NULL, 0); + + g_static_mutex_lock(&cache->mutex); + size = g_list_length(cache->list); + g_static_mutex_unlock(&cache->mutex); + return size; +} + +/** + * gst_vaapi_display_cache_add: + * @cache: the #GstVaapiDisplayCache + * @info: the display cache info to add + * + * Adds a new entry with data from @info. The display @info data is + * copied into the newly created cache entry. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_display_cache_add( + GstVaapiDisplayCache *cache, + GstVaapiDisplayInfo *info +) +{ + CacheEntry *entry; + + g_return_val_if_fail(cache != NULL, FALSE); + g_return_val_if_fail(info != NULL, FALSE); + + entry = cache_entry_new(info); + if (!entry) + return FALSE; + + g_static_mutex_lock(&cache->mutex); + cache->list = g_list_prepend(cache->list, entry); + g_static_mutex_unlock(&cache->mutex); + return TRUE; +} + +/** + * gst_vaapi_display_cache_remove: + * @cache: the #GstVaapiDisplayCache + * @display: the display to remove from cache + * + * Removes any cache entry that matches the specified #GstVaapiDisplay. + */ +void +gst_vaapi_display_cache_remove( + GstVaapiDisplayCache *cache, + GstVaapiDisplay *display +) +{ + GList *m; + + m = cache_lookup_display(cache, display); + if (!m) + return; + + cache_entry_free(m->data); + g_static_mutex_lock(&cache->mutex); + cache->list = g_list_delete_link(cache->list, m); + g_static_mutex_unlock(&cache->mutex); +} + +/** + * gst_vaapi_display_cache_lookup: + * @cache: the #GstVaapiDisplayCache + * @display: the display to find + * + * Looks up the display cache for the specified #GstVaapiDisplay. + * + * Return value: a #GstVaapiDisplayInfo matching @display, or %NULL if + * none was found + */ +const GstVaapiDisplayInfo * +gst_vaapi_display_cache_lookup( + GstVaapiDisplayCache *cache, + GstVaapiDisplay *display +) +{ + CacheEntry *entry; + GList *m; + + g_return_val_if_fail(cache != NULL, NULL); + g_return_val_if_fail(display != NULL, NULL); + + m = cache_lookup_display(cache, display); + if (!m) + return NULL; + + entry = m->data; + return &entry->info; +} + +/** + * gst_vaapi_display_cache_lookup_by_va_display: + * @cache: the #GstVaapiDisplayCache + * @va_display: the VA display to find + * + * Looks up the display cache for the specified VA display. + * + * Return value: a #GstVaapiDisplayInfo matching @va_display, or %NULL + * if none was found + */ +const GstVaapiDisplayInfo * +gst_vaapi_display_cache_lookup_by_va_display( + GstVaapiDisplayCache *cache, + VADisplay va_display +) +{ + CacheEntry *entry; + GList *m; + + g_return_val_if_fail(cache != NULL, NULL); + g_return_val_if_fail(va_display != NULL, NULL); + + m = cache_lookup_va_display(cache, va_display); + if (!m) + return NULL; + + entry = m->data; + return &entry->info; +} + +/** + * gst_vaapi_display_cache_lookup_by_native_display: + * @cache: the #GstVaapiDisplayCache + * @native_display: the native display to find + * + * Looks up the display cache for the specified native display. + * + * Return value: a #GstVaapiDisplayInfo matching @native_display, or + * %NULL if none was found + */ +const GstVaapiDisplayInfo * +gst_vaapi_display_cache_lookup_by_native_display( + GstVaapiDisplayCache *cache, + gpointer native_display +) +{ + CacheEntry *entry; + GList *m; + + g_return_val_if_fail(cache != NULL, NULL); + g_return_val_if_fail(native_display != NULL, NULL); + + m = cache_lookup_native_display(cache, native_display); + if (!m) + return NULL; + + entry = m->data; + return &entry->info; +} + +/** + * gst_vaapi_display_cache_lookup_by_name: + * @cache: the #GstVaapiDisplayCache + * @display_name: the display name to match + * @compare_func: an optional string comparison function + * @user_data: any relevant data pointer to the comparison function + * + * Looks up the display cache for the specified display name. A + * specific comparison function can be provided to avoid a plain + * strcmp(). + * + * Return value: a #GstVaapiDisplayInfo matching @display_name, or + * %NULL if none was found + */ +const GstVaapiDisplayInfo * +gst_vaapi_display_cache_lookup_by_name( + GstVaapiDisplayCache *cache, + const gchar *display_name, + GCompareDataFunc compare_func, + gpointer user_data +) +{ + CacheEntry *entry; + GList *m; + + g_return_val_if_fail(cache != NULL, NULL); + + if (compare_func) + CACHE_LOOKUP(cache, m, display_name, compare_func, display_name, user_data); + else + CACHE_LOOKUP(cache, m, display_name, compare_string, display_name, NULL); + if (!m) + return NULL; + + entry = m->data; + return &entry->info; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h new file mode 100644 index 0000000000..12c29531d3 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.h @@ -0,0 +1,76 @@ +/* + * gstvaapidisplaycache.h - VA display cache + * + * Copyright (C) 2012 Intel Corporation + * + * 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 GSTVAAPIDISPLAYCACHE_H +#define GSTVAAPIDISPLAYCACHE_H + +#include + +typedef struct _GstVaapiDisplayCache GstVaapiDisplayCache; + +GstVaapiDisplayCache * +gst_vaapi_display_cache_new(void); + +void +gst_vaapi_display_cache_free(GstVaapiDisplayCache *cache); + +guint +gst_vaapi_display_cache_get_size(GstVaapiDisplayCache *cache); + +gboolean +gst_vaapi_display_cache_add( + GstVaapiDisplayCache *cache, + GstVaapiDisplayInfo *info +); + +void +gst_vaapi_display_cache_remove( + GstVaapiDisplayCache *cache, + GstVaapiDisplay *display +); + +const GstVaapiDisplayInfo * +gst_vaapi_display_cache_lookup( + GstVaapiDisplayCache *cache, + GstVaapiDisplay *display +); + +const GstVaapiDisplayInfo * +gst_vaapi_display_cache_lookup_by_va_display( + GstVaapiDisplayCache *cache, + VADisplay va_display +); + +const GstVaapiDisplayInfo * +gst_vaapi_display_cache_lookup_by_native_display( + GstVaapiDisplayCache *cache, + gpointer native_display +); + +const GstVaapiDisplayInfo * +gst_vaapi_display_cache_lookup_by_name( + GstVaapiDisplayCache *cache, + const gchar *display_name, + GCompareDataFunc compare_func, + gpointer user_data +); + +#endif /* GSTVAAPIDISPLAYCACHE_H */ From 9516f00f8eda9f9ef8fd4c49246b8f6de1f7d32f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 12 Jan 2012 15:03:04 +0100 Subject: [PATCH 0541/3781] display: use VA display cache for X11 and GLX winsys. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 96 ++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapidisplay.h | 5 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 17 +++- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 5 ++ gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 92 ++++++++++++++++++++-- 5 files changed, 188 insertions(+), 27 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index b4da1624b6..0d2cff05a2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -25,6 +25,7 @@ */ #include "config.h" +#include #include "gstvaapiutils.h" #include "gstvaapidisplay.h" #include "gstvaapidisplay_priv.h" @@ -50,6 +51,22 @@ enum { PROP_HEIGHT }; +static inline GstVaapiDisplayCache * +get_display_cache(void) +{ + static GstVaapiDisplayCache *g_display_cache = NULL; + + if (!g_display_cache) + g_display_cache = gst_vaapi_display_cache_new(); + return g_display_cache; +} + +GstVaapiDisplayCache * +gst_vaapi_display_get_cache(void) +{ + return get_display_cache(); +} + /* Append GstVaapiImageFormat to formats array */ static inline void append_format(GArray *formats, GstVaapiImageFormat format) @@ -281,7 +298,8 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) } if (priv->display) { - vaTerminate(priv->display); + if (!priv->parent) + vaTerminate(priv->display); priv->display = NULL; } @@ -290,12 +308,20 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) if (klass->close_display) klass->close_display(display); } + + if (priv->parent) { + g_object_unref(priv->parent); + priv->parent = NULL; + } + + gst_vaapi_display_cache_remove(get_display_cache(), display); } static gboolean gst_vaapi_display_create(GstVaapiDisplay *display) { GstVaapiDisplayPrivate * const priv = display->priv; + GstVaapiDisplayCache *cache; gboolean has_errors = TRUE; VAProfile *profiles = NULL; VAEntrypoint *entrypoints = NULL; @@ -303,16 +329,21 @@ gst_vaapi_display_create(GstVaapiDisplay *display) unsigned int *flags = NULL; gint i, j, n, num_entrypoints, major_version, minor_version; VAStatus status; + GstVaapiDisplayInfo info; + const GstVaapiDisplayInfo *cached_info = NULL; - if (!priv->display && priv->create_display) { + memset(&info, 0, sizeof(info)); + info.display = display; + + if (priv->display) + info.va_display = priv->display; + else if (priv->create_display) { GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); if (klass->open_display && !klass->open_display(display)) return FALSE; - if (klass->get_display) { - priv->display = klass->get_display(display); - if (!priv->display) - return FALSE; - } + if (!klass->get_display || !klass->get_display(display, &info)) + return FALSE; + priv->display = info.va_display; if (klass->get_size) klass->get_size(display, &priv->width, &priv->height); if (klass->get_size_mm) @@ -322,10 +353,25 @@ gst_vaapi_display_create(GstVaapiDisplay *display) if (!priv->display) return FALSE; - status = vaInitialize(priv->display, &major_version, &minor_version); - if (!vaapi_check_status(status, "vaInitialize()")) - goto end; - GST_DEBUG("VA-API version %d.%d", major_version, minor_version); + cache = get_display_cache(); + if (!cache) + return FALSE; + cached_info = gst_vaapi_display_cache_lookup_by_va_display( + cache, + info.va_display + ); + if (cached_info) { + if (priv->parent) + g_object_unref(priv->parent); + priv->parent = g_object_ref(cached_info->display); + } + + if (!priv->parent) { + status = vaInitialize(priv->display, &major_version, &minor_version); + if (!vaapi_check_status(status, "vaInitialize()")) + goto end; + GST_DEBUG("VA-API version %d.%d", major_version, minor_version); + } /* VA profiles */ profiles = g_new(VAProfile, vaMaxNumProfiles(priv->display)); @@ -419,6 +465,11 @@ gst_vaapi_display_create(GstVaapiDisplay *display) append_formats(priv->subpicture_formats, formats, n); g_array_sort(priv->subpicture_formats, compare_rgb_formats); + if (!cached_info) { + if (!gst_vaapi_display_cache_add(cache, &info)) + goto end; + } + has_errors = FALSE; end: g_free(profiles); @@ -431,13 +482,21 @@ end: static void gst_vaapi_display_lock_default(GstVaapiDisplay *display) { - g_static_rec_mutex_lock(&display->priv->mutex); + GstVaapiDisplayPrivate *priv = display->priv; + + if (priv->parent) + priv = priv->parent->priv; + g_static_rec_mutex_lock(&priv->mutex); } static void gst_vaapi_display_unlock_default(GstVaapiDisplay *display) { - g_static_rec_mutex_unlock(&display->priv->mutex); + GstVaapiDisplayPrivate *priv = display->priv; + + if (priv->parent) + priv = priv->parent->priv; + g_static_rec_mutex_unlock(&priv->mutex); } static void @@ -562,6 +621,7 @@ gst_vaapi_display_init(GstVaapiDisplay *display) GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); display->priv = priv; + priv->parent = NULL; priv->display = NULL; priv->width = 0; priv->height = 0; @@ -590,6 +650,16 @@ gst_vaapi_display_init(GstVaapiDisplay *display) GstVaapiDisplay * gst_vaapi_display_new_with_display(VADisplay va_display) { + GstVaapiDisplayCache * const cache = get_display_cache(); + const GstVaapiDisplayInfo *info; + + g_return_val_if_fail(va_display != NULL, NULL); + g_return_val_if_fail(cache != NULL, NULL); + + info = gst_vaapi_display_cache_lookup_by_va_display(cache, va_display); + if (info) + return g_object_ref(info->display); + return g_object_new(GST_VAAPI_TYPE_DISPLAY, "display", va_display, NULL); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 0517e42626..616f74349d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -95,7 +95,7 @@ struct _GstVaapiDisplay { * @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 #VADisplay + * @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 * @@ -112,7 +112,8 @@ struct _GstVaapiDisplayClass { void (*unlock) (GstVaapiDisplay *display); void (*sync) (GstVaapiDisplay *display); void (*flush) (GstVaapiDisplay *display); - VADisplay (*get_display) (GstVaapiDisplay *display); + gboolean (*get_display) (GstVaapiDisplay *display, + GstVaapiDisplayInfo *info); void (*get_size) (GstVaapiDisplay *display, guint *pwidth, guint *pheight); void (*get_size_mm) (GstVaapiDisplay *display, diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 660d757627..cd74789a38 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -46,10 +46,19 @@ gst_vaapi_display_glx_finalize(GObject *object) G_OBJECT_CLASS(gst_vaapi_display_glx_parent_class)->finalize(object); } -static VADisplay -gst_vaapi_display_glx_get_va_display(GstVaapiDisplay *display) +static gboolean +gst_vaapi_display_glx_get_display_info( + GstVaapiDisplay *display, + GstVaapiDisplayInfo *info +) { - return vaGetDisplayGLX(GST_VAAPI_DISPLAY_XDISPLAY(display)); + GstVaapiDisplayClass * const dpy_class = + GST_VAAPI_DISPLAY_CLASS(gst_vaapi_display_glx_parent_class); + + info->va_display = vaGetDisplayGLX(GST_VAAPI_DISPLAY_XDISPLAY(display)); + if (!info->va_display) + return FALSE; + return dpy_class->get_display(display, info); } static void @@ -59,7 +68,7 @@ gst_vaapi_display_glx_class_init(GstVaapiDisplayGLXClass *klass) GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); object_class->finalize = gst_vaapi_display_glx_finalize; - dpy_class->get_display = gst_vaapi_display_glx_get_va_display; + dpy_class->get_display = gst_vaapi_display_glx_get_display_info; } static void diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 5f2ff14122..76b58a7568 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -23,6 +23,7 @@ #define GST_VAAPI_DISPLAY_PRIV_H #include +#include G_BEGIN_DECLS @@ -70,6 +71,7 @@ G_BEGIN_DECLS * Base class for VA displays. */ struct _GstVaapiDisplayPrivate { + GstVaapiDisplay *parent; GStaticRecMutex mutex; VADisplay display; guint width; @@ -85,6 +87,9 @@ struct _GstVaapiDisplayPrivate { guint create_display : 1; }; +GstVaapiDisplayCache * +gst_vaapi_display_get_cache(void); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index de98a005b6..36b0a99f41 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -25,6 +25,7 @@ */ #include "config.h" +#include #include "gstvaapiutils.h" #include "gstvaapidisplay_priv.h" #include "gstvaapidisplay_x11.h" @@ -46,6 +47,40 @@ enum { PROP_X11_SCREEN }; +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; +} + +static gboolean +compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const gchar *display_name; + + /* XXX: handle screen number? */ + if (a && b) + return strcmp(a, b) == 0; + + /* Match "" or default display name */ + if (a) + display_name = a; + else if (b) + display_name = b; + else + return TRUE; + + if (*display_name == '\0') + return TRUE; + if (strcmp(display_name, get_default_display_name()) == 0) + return TRUE; + return FALSE; +} + static void gst_vaapi_display_x11_finalize(GObject *object) { @@ -139,13 +174,29 @@ static void gst_vaapi_display_x11_constructed(GObject *object) { GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); + GstVaapiDisplayX11Private * const priv = display->priv; + GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache(); + const GstVaapiDisplayInfo *info; GObjectClass *parent_class; - display->priv->create_display = display->priv->x11_display == NULL; + priv->create_display = priv->x11_display == NULL; + + /* Don't create X11 display if there is one in the cache already */ + if (priv->create_display) { + info = gst_vaapi_display_cache_lookup_by_name( + cache, + priv->display_name, + compare_display_name, NULL + ); + if (info) { + priv->x11_display = info->native_display; + priv->create_display = FALSE; + } + } /* Reset display-name if the user provided his own X11 display */ - if (!display->priv->create_display) - set_display_name(display, XDisplayString(display->priv->x11_display)); + if (!priv->create_display) + set_display_name(display, XDisplayString(priv->x11_display)); parent_class = G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class); if (parent_class->constructed) @@ -158,7 +209,6 @@ gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) GstVaapiDisplayX11Private * const priv = GST_VAAPI_DISPLAY_X11(display)->priv; - /* XXX: maintain an X11 display cache */ if (priv->create_display) { priv->x11_display = XOpenDisplay(priv->display_name); if (!priv->x11_display) @@ -217,10 +267,36 @@ gst_vaapi_display_x11_flush(GstVaapiDisplay *display) } } -static VADisplay -gst_vaapi_display_x11_get_va_display(GstVaapiDisplay *display) +static gboolean +gst_vaapi_display_x11_get_display_info( + GstVaapiDisplay *display, + GstVaapiDisplayInfo *info +) { - return vaGetDisplay(GST_VAAPI_DISPLAY_XDISPLAY(display)); + GstVaapiDisplayX11Private * const priv = + GST_VAAPI_DISPLAY_X11(display)->priv; + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *cached_info; + + /* Return any cached info even if child has its own VA display */ + cache = gst_vaapi_display_get_cache(); + if (!cache) + return FALSE; + cached_info = gst_vaapi_display_cache_lookup_by_native_display(cache, priv->x11_display); + if (cached_info) { + *info = *cached_info; + return TRUE; + } + + /* Otherwise, create VA display if there is none already */ + 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 @@ -280,7 +356,7 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) 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_va_display; + 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; From 674ea91faa342bdd2311d78dd71a713297163ffd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 12 Jan 2012 15:30:04 +0100 Subject: [PATCH 0542/3781] display: always free VA display cache if it is empty. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 0d2cff05a2..f7bc0deb2e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -51,11 +51,11 @@ enum { PROP_HEIGHT }; +static GstVaapiDisplayCache *g_display_cache = NULL; + static inline GstVaapiDisplayCache * get_display_cache(void) { - static GstVaapiDisplayCache *g_display_cache = NULL; - if (!g_display_cache) g_display_cache = gst_vaapi_display_cache_new(); return g_display_cache; @@ -67,6 +67,17 @@ gst_vaapi_display_get_cache(void) return get_display_cache(); } +static void +free_display_cache(void) +{ + if (!g_display_cache) + return; + if (gst_vaapi_display_cache_get_size(g_display_cache) > 0) + return; + gst_vaapi_display_cache_free(g_display_cache); + g_display_cache = NULL; +} + /* Append GstVaapiImageFormat to formats array */ static inline void append_format(GArray *formats, GstVaapiImageFormat format) @@ -314,7 +325,10 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) priv->parent = NULL; } - gst_vaapi_display_cache_remove(get_display_cache(), display); + if (g_display_cache) { + gst_vaapi_display_cache_remove(get_display_cache(), display); + free_display_cache(); + } } static gboolean From 58e5534c5650d95531b34a67c41481e1516f75ca Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 12 Jan 2012 15:34:59 +0100 Subject: [PATCH 0543/3781] tests: check for shared VA displays (display cache). --- tests/test-decode.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/test-decode.c b/tests/test-decode.c index b913e08fc6..0aece9428a 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -29,6 +29,9 @@ #include "test-h264.h" #include "test-vc1.h" +/* Set to 1 to check display cache works (shared VA display) */ +#define CHECK_DISPLAY_CACHE 1 + typedef void (*GetVideoInfoFunc)(VideoDecodeInfo *info); typedef struct _CodecDefs CodecDefs; @@ -76,7 +79,7 @@ int main(int argc, char *argv[]) { GOptionContext *options; - GstVaapiDisplay *display; + GstVaapiDisplay *display, *display2; GstVaapiWindow *window; GstVaapiDecoder *decoder; GstCaps *decoder_caps; @@ -109,6 +112,13 @@ main(int argc, char *argv[]) if (!display) g_error("could not create VA display"); + if (CHECK_DISPLAY_CACHE) + display2 = gst_vaapi_display_x11_new(NULL); + else + display2 = g_object_ref(display); + if (!display2) + g_error("could not create second VA display"); + window = gst_vaapi_window_x11_new(display, win_width, win_height); if (!window) g_error("could not create window"); @@ -163,6 +173,7 @@ main(int argc, char *argv[]) g_object_unref(decoder); g_object_unref(window); g_object_unref(display); + g_object_unref(display2); g_free(g_codec_str); gst_deinit(); return 0; From 44d8bac31438a8d935e8244bf809653cdb98402d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 12 Jan 2012 17:18:47 +0100 Subject: [PATCH 0544/3781] NEWS: updates. --- NEWS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NEWS b/NEWS index 2ab7d04841..33f7c856dc 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,14 @@ gst-vaapi NEWS -- summary of changes. 2012-01-06 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011 Intel Corporation +Version 0.3.3 - DD.Jan.2012 +* Add MPEG-2, MPEG-4 and VC-1 decoders (based on codecparsers) +* Add support for GstXOverlay::set_render_rectangle() in vaapisink +* Fix memory leak of GL texture (Nicolas Dufresne) +* Fix vaapisink to automatically fit video to window +* Fix vaapiupload to only set caps on newly created buffers (Nicolas Dufresne) +* Fix gst_vaapi_ensure_display() to honour DISPLAY environment variable + Version 0.3.2 - 06.Jan.2012 * Rename vaapiconvert element to vaapiupload * Fix vaapiupload from NV12 buffers From 43403729963bb43c905b2b09cbd295b35efae543 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Jan 2012 11:46:55 +0100 Subject: [PATCH 0545/3781] utils: drop string_of_FOURCC() in favor of standard GST_FOURCC_* helpers. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiutils.c | 15 --------------- gst-libs/gst/vaapi/gstvaapiutils.h | 4 ---- 3 files changed, 2 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index f7bc0deb2e..4790810fbd 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -449,7 +449,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) GST_DEBUG("%d image formats", n); for (i = 0; i < n; i++) - GST_DEBUG(" %s", string_of_FOURCC(formats[i].fourcc)); + GST_DEBUG(" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc)); priv->image_formats = g_array_new(FALSE, FALSE, sizeof(GstVaapiImageFormat)); @@ -470,7 +470,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) GST_DEBUG("%d subpicture formats", n); for (i = 0; i < n; i++) - GST_DEBUG(" %s", string_of_FOURCC(formats[i].fourcc)); + GST_DEBUG(" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc)); priv->subpicture_formats = g_array_new(FALSE, FALSE, sizeof(GstVaapiImageFormat)); diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index a99d7e8254..e6f9bbfc9f 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -40,21 +40,6 @@ vaapi_check_status(VAStatus status, const char *msg) return TRUE; } -/* Return a string representation of a FOURCC */ -const char *string_of_FOURCC(guint32 fourcc) -{ - static int buf; - static char str[2][5]; // XXX: 2 buffers should be enough for most purposes - - buf ^= 1; - str[buf][0] = fourcc; - str[buf][1] = fourcc >> 8; - str[buf][2] = fourcc >> 16; - str[buf][3] = fourcc >> 24; - str[buf][4] = '\0'; - return str[buf]; -} - /* Return a string representation of a VAProfile */ const char *string_of_VAProfile(VAProfile profile) { diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 50149073ae..7d45d3ed23 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -36,10 +36,6 @@ gboolean vaapi_check_status(VAStatus status, const char *msg) attribute_hidden; -/** Return a string representation of a FOURCC */ -const char *string_of_FOURCC(guint32 fourcc) - attribute_hidden; - /** Return a string representation of a VAProfile */ const char *string_of_VAProfile(VAProfile profile) attribute_hidden; From ba810c2ed670628de486a7ae2e11a003e2d3849f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Jan 2012 12:09:07 +0100 Subject: [PATCH 0546/3781] utils: simplify string of VAProfile/VAEntrypoint. --- gst-libs/gst/vaapi/gstvaapiutils.c | 57 +++++++++++++++++------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index e6f9bbfc9f..bdc2b125d0 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -29,6 +29,13 @@ #define DEBUG 1 #include "gstvaapidebug.h" +#define CONCAT(a, b) CONCAT_(a, b) +#define CONCAT_(a, b) a##b +#define STRINGIFY(x) STRINGIFY_(x) +#define STRINGIFY_(x) #x +#define STRCASEP(p, x) STRCASE(CONCAT(p, x)) +#define STRCASE(x) case x: return STRINGIFY(x) + /* Check VA status for success or print out an error */ gboolean vaapi_check_status(VAStatus status, const char *msg) @@ -44,25 +51,25 @@ vaapi_check_status(VAStatus status, const char *msg) const char *string_of_VAProfile(VAProfile profile) { switch (profile) { -#define PROFILE(profile) \ - case VAProfile##profile: return "VAProfile" #profile - PROFILE(MPEG2Simple); - PROFILE(MPEG2Main); - PROFILE(MPEG4Simple); - PROFILE(MPEG4AdvancedSimple); - PROFILE(MPEG4Main); +#define MAP(profile) \ + STRCASEP(VAProfile, profile) + MAP(MPEG2Simple); + MAP(MPEG2Main); + MAP(MPEG4Simple); + MAP(MPEG4AdvancedSimple); + MAP(MPEG4Main); #if VA_CHECK_VERSION(0,32,0) - PROFILE(JPEGBaseline); - PROFILE(H263Baseline); - PROFILE(H264ConstrainedBaseline); + MAP(JPEGBaseline); + MAP(H263Baseline); + MAP(H264ConstrainedBaseline); #endif - PROFILE(H264Baseline); - PROFILE(H264Main); - PROFILE(H264High); - PROFILE(VC1Simple); - PROFILE(VC1Main); - PROFILE(VC1Advanced); -#undef PROFILE + MAP(H264Baseline); + MAP(H264Main); + MAP(H264High); + MAP(VC1Simple); + MAP(VC1Main); + MAP(VC1Advanced); +#undef MAP default: break; } return ""; @@ -72,14 +79,14 @@ const char *string_of_VAProfile(VAProfile profile) const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) { switch (entrypoint) { -#define ENTRYPOINT(entrypoint) \ - case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint - ENTRYPOINT(VLD); - ENTRYPOINT(IZZ); - ENTRYPOINT(IDCT); - ENTRYPOINT(MoComp); - ENTRYPOINT(Deblocking); -#undef ENTRYPOINT +#define MAP(entrypoint) \ + STRCASEP(VAEntrypoint, entrypoint) + MAP(VLD); + MAP(IZZ); + MAP(IDCT); + MAP(MoComp); + MAP(Deblocking); +#undef MAP default: break; } return ""; From a3c9365f156036f526bb6956b7333c296777bc99 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Jan 2012 14:03:29 +0100 Subject: [PATCH 0547/3781] utils: rewrite gl_perspective() as per OpenGL FAQ 9.085. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 43 ++++++-------------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index b904ecc533..f30b6dc71d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -205,42 +205,17 @@ gl_set_bgcolor(guint32 color) * basically is the Mesa implementation of gluPerspective(). */ static void -frustum(GLdouble left, GLdouble right, - GLdouble bottom, GLdouble top, - GLdouble nearval, GLdouble farval) +gl_perspective(GLdouble fovy, GLdouble aspect, GLdouble near_val, GLdouble far_val) { - GLdouble x, y, a, b, c, d; - GLdouble m[16]; + GLdouble left, right, top, bottom; - x = (2.0 * nearval) / (right - left); - y = (2.0 * nearval) / (top - bottom); - a = (right + left) / (right - left); - b = (top + bottom) / (top - bottom); - c = -(farval + nearval) / ( farval - nearval); - d = -(2.0 * farval * nearval) / (farval - nearval); - -#define M(row,col) m[col*4+row] - M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F; - M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F; - M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d; - M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F; -#undef M - - glMultMatrixd(m); -} - -static void -gl_perspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) -{ - GLdouble xmin, xmax, ymin, ymax; - - ymax = zNear * tan(fovy * M_PI / 360.0); - ymin = -ymax; - xmin = ymin * aspect; - xmax = ymax * aspect; - - /* Don't call glFrustum() because of error semantics (covglu) */ - frustum(xmin, xmax, ymin, ymax, zNear, zFar); + /* Source (Q 9.085): + */ + top = tan(fovy * M_PI / 360.0) * near_val; + bottom = -top; + left = aspect * bottom; + right = aspect * top; + glFrustum(left, right, bottom, top, near_val, far_val); } /** From 30ef6802d60352e280285b1bb932fa39f95c4d38 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Jan 2012 14:13:55 +0100 Subject: [PATCH 0548/3781] utils: pretty-print output of gl_get_error_string(). --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 36 +++++++++++--------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index f30b6dc71d..71308db24a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -62,30 +62,24 @@ find_string(const char *name, const char *ext, const char *sep) const char * gl_get_error_string(GLenum error) { - static const struct { - GLenum val; - const char *str; - } - gl_errors[] = { - { GL_NO_ERROR, "no error" }, - { GL_INVALID_ENUM, "invalid enumerant" }, - { GL_INVALID_VALUE, "invalid value" }, - { GL_INVALID_OPERATION, "invalid operation" }, - { GL_STACK_OVERFLOW, "stack overflow" }, - { GL_STACK_UNDERFLOW, "stack underflow" }, - { GL_OUT_OF_MEMORY, "out of memory" }, + switch (error) { +#define MAP(id, str) \ + case id: return str " (" #id ")" + MAP(GL_NO_ERROR, "no error"); + MAP(GL_INVALID_ENUM, "invalid enumerant"); + MAP(GL_INVALID_VALUE, "invalid value"); + MAP(GL_INVALID_OPERATION, "invalid operation"); + MAP(GL_STACK_OVERFLOW, "stack overflow"); + MAP(GL_STACK_UNDERFLOW, "stack underflow"); + MAP(GL_OUT_OF_MEMORY, "out of memory"); #ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT - { GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "invalid framebuffer operation" }, + MAP(GL_INVALID_FRAMEBUFFER_OPERATION_EXT, + "invalid framebuffer operation"); #endif - { ~0, NULL } +#undef MAP + default: break; }; - - guint i; - for (i = 0; gl_errors[i].str; i++) { - if (gl_errors[i].val == error) - return gl_errors[i].str; - } - return "unknown"; + return ""; } /** From 9b9c049a6758522eeec7f68ad683ee38368cab79 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Jan 2012 15:03:38 +0100 Subject: [PATCH 0549/3781] utils: slight improvements to gl_bind_texture(). --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 87 ++++++++++++++++---------- 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 71308db24a..23ea8b7100 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -166,6 +166,39 @@ gl_get_texture_param(GLenum target, GLenum param, guint *pval) return TRUE; } +/** + * gl_get_texture_binding: + * @target: a texture target + * + * Determines the texture binding type for the specified target. + * + * Return value: texture binding type for @target + */ +static GLenum +gl_get_texture_binding(GLenum target) +{ + GLenum binding; + + switch (target) { + case GL_TEXTURE_1D: + binding = GL_TEXTURE_BINDING_1D; + break; + case GL_TEXTURE_2D: + binding = GL_TEXTURE_BINDING_2D; + break; + case GL_TEXTURE_3D: + binding = GL_TEXTURE_BINDING_3D; + break; + case GL_TEXTURE_RECTANGLE_ARB: + binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; + break; + default: + binding = 0; + break; + } + return binding; +} + /** * gl_set_bgcolor: * @color: the requested RGB color @@ -455,42 +488,32 @@ gl_swap_buffers(GLContextState *cs) gboolean gl_bind_texture(GLTextureState *ts, GLenum target, GLuint texture) { - ts->target = target; - ts->old_texture = 0; - ts->was_bound = 0; - ts->was_enabled = glIsEnabled(target); - if (!ts->was_enabled) - glEnable(target); + GLenum binding; - GLenum texture_binding; - switch (target) { - case GL_TEXTURE_1D: - texture_binding = GL_TEXTURE_BINDING_1D; - break; - case GL_TEXTURE_2D: - texture_binding = GL_TEXTURE_BINDING_2D; - break; - case GL_TEXTURE_3D: - texture_binding = GL_TEXTURE_BINDING_3D; - break; - case GL_TEXTURE_RECTANGLE_ARB: - texture_binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; - break; - default: - g_assert(!texture); - return FALSE; - } + ts->target = target; - if (!gl_get_param(texture_binding, &ts->old_texture)) - return FALSE; - - ts->was_bound = texture == ts->old_texture; - if (!ts->was_bound) { - gl_purge_errors(); - glBindTexture(target, texture); - if (gl_check_error()) + if (glIsEnabled(target)) { + binding = gl_get_texture_binding(target); + if (!binding) return FALSE; + if (!gl_get_param(binding, &ts->old_texture)) + return FALSE; + ts->was_enabled = TRUE; + ts->was_bound = texture == ts->old_texture; + if (ts->was_bound) + return TRUE; } + else { + glEnable(target); + ts->old_texture = 0; + ts->was_enabled = FALSE; + ts->was_bound = FALSE; + } + + gl_purge_errors(); + glBindTexture(target, texture); + if (gl_check_error()) + return FALSE; return TRUE; } From e0913aaf0e953bd2bbdabf03ebaee02e3bfb0651 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 4 Aug 2011 17:29:41 +0200 Subject: [PATCH 0550/3781] Add VA buffer helpers. --- gst-libs/gst/vaapi/gstvaapiutils.c | 68 ++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 25 +++++++++++ 2 files changed, 93 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index bdc2b125d0..5e6eb6ef6e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -47,6 +47,74 @@ vaapi_check_status(VAStatus status, const char *msg) return TRUE; } +/* Maps VA buffer */ +void * +vaapi_map_buffer(VADisplay dpy, VABufferID buf_id) +{ + VAStatus status; + void *data = NULL; + + status = vaMapBuffer(dpy, buf_id, &data); + if (!vaapi_check_status(status, "vaMapBuffer()")) + return NULL; + return data; +} + +/* Unmaps VA buffer */ +void +vaapi_unmap_buffer(VADisplay dpy, VABufferID buf_id, void **pbuf) +{ + VAStatus status; + + if (pbuf) + *pbuf = NULL; + + status = vaUnmapBuffer(dpy, buf_id); + if (!vaapi_check_status(status, "vaUnmapBuffer()")) + return; +} + +/* Creates and maps VA buffer */ +void * +vaapi_create_buffer( + VADisplay dpy, + VAContextID ctx, + int type, + unsigned int size, + VABufferID *buf_id_ptr +) +{ + VABufferID buf_id; + VAStatus status; + void *data; + + status = vaCreateBuffer(dpy, ctx, type, size, 1, NULL, &buf_id); + if (!vaapi_check_status(status, "vaCreateBuffer()")) + return NULL; + + data = vaapi_map_buffer(dpy, buf_id); + if (!data) + goto error; + + *buf_id_ptr = buf_id; + return data; + +error: + vaapi_destroy_buffer(dpy, &buf_id); + return NULL; +} + +/* Destroy VA buffer */ +void +vaapi_destroy_buffer(VADisplay dpy, VABufferID *buf_id_ptr) +{ + if (!buf_id_ptr || *buf_id_ptr == VA_INVALID_ID) + return; + + vaDestroyBuffer(dpy, *buf_id_ptr); + *buf_id_ptr = VA_INVALID_ID; +} + /* Return a string representation of a VAProfile */ const char *string_of_VAProfile(VAProfile profile) { diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 7d45d3ed23..c626429745 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -36,6 +36,31 @@ gboolean vaapi_check_status(VAStatus status, const char *msg) attribute_hidden; +/** Maps VA buffer */ +void * +vaapi_map_buffer(VADisplay dpy, VABufferID buf_id) + attribute_hidden; + +/** Unmaps VA buffer */ +void +vaapi_unmap_buffer(VADisplay dpy, VABufferID buf_id, void **pbuf) + attribute_hidden; + +/** Creates and maps VA buffer */ +void * +vaapi_create_buffer( + VADisplay dpy, + VAContextID ctx, + int type, + unsigned int size, + VABufferID *buf_id +) attribute_hidden; + +/** Destroy VA buffer */ +void +vaapi_destroy_buffer(VADisplay dpy, VABufferID *buf_id) + attribute_hidden; + /** Return a string representation of a VAProfile */ const char *string_of_VAProfile(VAProfile profile) attribute_hidden; From 9764e35acb6740c30cac236e1e927bf72c249781 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Sep 2011 13:00:59 +0200 Subject: [PATCH 0551/3781] Add timestamp buffer store helper utils. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapiutils_tsb.c | 237 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_tsb.h | 58 ++++++ 3 files changed, 297 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_tsb.c create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_tsb.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 5485b5f3e5..5a69da6839 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -38,6 +38,7 @@ libgstvaapi_source_c = \ gstvaapisurfacepool.c \ gstvaapisurfaceproxy.c \ gstvaapiutils.c \ + gstvaapiutils_tsb.c \ gstvaapivalue.c \ gstvaapivideobuffer.c \ gstvaapivideopool.c \ @@ -79,6 +80,7 @@ libgstvaapi_source_priv_h = \ gstvaapiobject_priv.h \ gstvaapisurface_priv.h \ gstvaapiutils.h \ + gstvaapiutils_tsb.h \ gstvaapivideobuffer_priv.h \ $(libgst_vaapi_ffmpeg_source_priv_h) \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_tsb.c b/gst-libs/gst/vaapi/gstvaapiutils_tsb.c new file mode 100644 index 0000000000..67ef2f2c23 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_tsb.c @@ -0,0 +1,237 @@ +/* + * gstvaapiutils_tsb.c - Timestamp buffer store + * + * Copyright (C) 2011 Intel Corporation + * + * 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 "gstvaapiutils_tsb.h" +#include + +typedef struct _GstVaapiTSBEntry GstVaapiTSBEntry; + +struct _GstVaapiTSB { + GList *list; +}; + +struct _GstVaapiTSBEntry { + GstBuffer *buffer; + guint32 buffer_size; + guint32 offset; +}; + +static GstVaapiTSBEntry * +gst_vaapi_tsb_entry_new(GstBuffer *buffer) +{ + GstVaapiTSBEntry *e; + + e = g_slice_new(GstVaapiTSBEntry); + if (!e) + return NULL; + + e->buffer = gst_buffer_ref(buffer); + e->buffer_size = GST_BUFFER_SIZE(buffer); + e->offset = 0; + return e; +} + +static void +gst_vaapi_tsb_entry_destroy(GstVaapiTSBEntry *e) +{ + if (!e) + return; + + if (e->buffer) { + gst_buffer_unref(e->buffer); + e->buffer = NULL; + } + g_slice_free(GstVaapiTSBEntry, e); +} + +/** + * gst_vaapi_tsb_new: + * + * Creates a new #GstVaapiTSB. + * + * Return value: a new #GstVaapiTSB + */ +GstVaapiTSB * +gst_vaapi_tsb_new() +{ + GstVaapiTSB *tsb; + + tsb = g_new(GstVaapiTSB, 1); + if (!tsb) + return NULL; + + tsb->list = NULL; + return tsb; +} + +/** + * gst_vaapi_tsb_destroy: + * @tsb: a #GstVaapiTSB + * + * Destroys the #GstVaapiTSB. All buffers are unreferenced. + */ +void +gst_vaapi_tsb_destroy(GstVaapiTSB *tsb) +{ + if (!tsb) + return; + + if (tsb->list) { + g_list_foreach(tsb->list, (GFunc)gst_vaapi_tsb_entry_destroy, NULL); + g_list_free(tsb->list); + tsb->list = NULL; + } + g_free(tsb); +} + +/** + * gst_vaapi_tsb_push: + * @tsb: a #GstVaapiTSB + * @buffer: a #GstBuffer + * + * Pushes @buffer to the timestamp buffer store. The TSB owns and + * maintains an extra reference to the buffer. + * + * Return value: %TRUE if success, %FALSE otherwise + */ +gboolean +gst_vaapi_tsb_push(GstVaapiTSB *tsb, GstBuffer *buffer) +{ + GList *l; + GstVaapiTSBEntry *e; + + if (!tsb) + return FALSE; + + e = gst_vaapi_tsb_entry_new(buffer); + if (!e) + return FALSE; + + l = g_list_append(tsb->list, e); + if (!l) + return FALSE; + + tsb->list = l; + return TRUE; +} + +/** + * gst_vaapi_tsb_pop: + * @tsb: a #GstVaapiTSB + * @size: number of bytes to remove from the TSB + * + * Removes @size bytes from the @tsb. + */ +void +gst_vaapi_tsb_pop(GstVaapiTSB *tsb, gsize size) +{ + GList *l; + GstVaapiTSBEntry *e; + guint32 n; + + if (!tsb || !tsb->list) + return; + + l = tsb->list; + e = l->data; + while (size > 0) { + n = MIN(e->buffer_size - e->offset, size); + e->offset += n; + size -= n; + if (e->offset == e->buffer_size) { + gst_vaapi_tsb_entry_destroy(e); + l = l->next; + g_list_free_1(tsb->list); + tsb->list = l; + if (!l) + return; + e = l->data; + } + } +} + +/** + * gst_vaapi_tsb_peek: + * @tsb: a #GstVaapiTSB + * + * Returns the current #GstBuffer. + * + * Return value: current #GstBuffer, or %NULL if none was found + */ +GstBuffer * +gst_vaapi_tsb_peek(GstVaapiTSB *tsb) +{ + GstVaapiTSBEntry *e; + + if (!tsb || !tsb->list) + return NULL; + + e = tsb->list->data; + if (!e) + return NULL; + + return e->buffer; +} + +/** + * gst_vaapi_tsb_get_timestamp: + * @tsb: a #GstVaapiTSB + * + * Returns the timestamp for the current #GstBuffer. + * + * Return value: current #GstBuffer timestamp, or %GST_CLOCK_TIME_NONE if none was found + */ +GstClockTime +gst_vaapi_tsb_get_timestamp(GstVaapiTSB *tsb) +{ + GstBuffer *buffer; + + buffer = gst_vaapi_tsb_peek(tsb); + if (!buffer) + return GST_CLOCK_TIME_NONE; + + return GST_BUFFER_TIMESTAMP(buffer); +} + +/** + * gst_vaapi_tsb_get_size: + * @tsb: a #GstVaapiTSB + * + * Returns the size of the #GstVaapiTSB. + * + * Return value: how many bytes left to consume from @tsb + */ +gsize +gst_vaapi_tsb_get_size(GstVaapiTSB *tsb) +{ + GList *l; + GstVaapiTSBEntry *e; + guint32 size = 0; + + if (!tsb || !tsb->list) + return 0; + + for (l = tsb->list; l != NULL; l = l->next) { + e = l->data; + size += e->buffer_size - e->offset; + } + return size; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_tsb.h b/gst-libs/gst/vaapi/gstvaapiutils_tsb.h new file mode 100644 index 0000000000..4070571974 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_tsb.h @@ -0,0 +1,58 @@ +/* + * gstvaapiutils_tsb.h - Timestamp buffer store + * + * Copyright (C) 2011 Intel Corporation + * + * 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_UTILS_TSB_H +#define GST_VAAPI_UTILS_TSB_H + +#include "config.h" +#include + +typedef struct _GstVaapiTSB GstVaapiTSB; + +GstVaapiTSB * +gst_vaapi_tsb_new() + attribute_hidden; + +void +gst_vaapi_tsb_destroy(GstVaapiTSB *tsb) + attribute_hidden; + +gboolean +gst_vaapi_tsb_push(GstVaapiTSB *tsb, GstBuffer *buffer) + attribute_hidden; + +void +gst_vaapi_tsb_pop(GstVaapiTSB *tsb, gsize size) + attribute_hidden; + +GstBuffer * +gst_vaapi_tsb_peek(GstVaapiTSB *tsb) + attribute_hidden; + +GstClockTime +gst_vaapi_tsb_get_timestamp(GstVaapiTSB *tsb) + attribute_hidden; + +gsize +gst_vaapi_tsb_get_size(GstVaapiTSB *tsb) + attribute_hidden; + +#endif /* GST_VAAPI_UTILS_TSB_H */ From a93c1c076b81a71771e7debf2fcec0caffeaa369 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 5 Aug 2011 11:52:43 +0200 Subject: [PATCH 0552/3781] decoder: add new error codes. GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: for unsupported profile GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: for unsupported chroma format --- gst-libs/gst/vaapi/gstvaapidecoder.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 73db5fd7a7..02ce20330d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -67,6 +67,9 @@ typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; * @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_UNKNOWN: Unknown error. * * Decoder status for gst_vaapi_decoder_get_surface(). @@ -80,6 +83,9 @@ enum _GstVaapiDecoderStatus { 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_UNKNOWN = -1 }; From 3360f7f3e369bc28c4c39c153b052c9ff8d2305d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 5 Aug 2011 11:53:50 +0200 Subject: [PATCH 0553/3781] Add VA decoder helpers. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 320 +++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 88 ++++++ 2 files changed, 406 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index fead8f0f05..e1b45dfbed 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -26,7 +26,6 @@ */ #include "config.h" -#include #include #include "gstvaapicompat.h" #include "gstvaapidecoder.h" @@ -44,6 +43,7 @@ enum { PROP_DISPLAY, PROP_CAPS, + PROP_CODEC_INFO, }; static void @@ -202,6 +202,20 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps) set_codec_data(decoder, gst_value_get_buffer(v_codec_data)); } +static inline void +set_codec_info(GstVaapiDecoder *decoder, GstVaapiCodecInfo *codec_info) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (codec_info) { + priv->codec_info = *codec_info; + if (!priv->codec_info.pic_size) + priv->codec_info.pic_size = sizeof(GstVaapiPicture); + if (!priv->codec_info.slice_size) + priv->codec_info.slice_size = sizeof(GstVaapiSlice); + } +} + static void clear_queue(GQueue *q, GDestroyNotify destroy) { @@ -225,6 +239,7 @@ gst_vaapi_decoder_finalize(GObject *object) if (priv->context) { g_object_unref(priv->context); priv->context = NULL; + priv->va_context = VA_INVALID_ID; } if (priv->buffers) { @@ -242,6 +257,7 @@ gst_vaapi_decoder_finalize(GObject *object) if (priv->display) { g_object_unref(priv->display); priv->display = NULL; + priv->va_display = NULL; } G_OBJECT_CLASS(gst_vaapi_decoder_parent_class)->finalize(object); @@ -261,10 +277,17 @@ gst_vaapi_decoder_set_property( switch (prop_id) { case PROP_DISPLAY: priv->display = g_object_ref(g_value_get_object(value)); + if (priv->display) + priv->va_display = gst_vaapi_display_get_display(priv->display); + else + priv->va_display = NULL; break; case PROP_CAPS: set_caps(decoder, g_value_get_pointer(value)); break; + case PROP_CODEC_INFO: + set_codec_info(decoder, g_value_get_pointer(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -326,6 +349,14 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass) "Decoder caps", "The decoder caps", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_CODEC_INFO, + g_param_spec_pointer("codec-info", + "Codec info", + "The codec info", + G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -334,7 +365,10 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) GstVaapiDecoderPrivate *priv = GST_VAAPI_DECODER_GET_PRIVATE(decoder); decoder->priv = priv; + priv->display = NULL; + priv->va_display = NULL; priv->context = NULL; + priv->va_context = VA_INVALID_ID; priv->caps = NULL; priv->codec = 0; priv->codec_data = NULL; @@ -527,7 +561,11 @@ gst_vaapi_decoder_ensure_context( width, height ); - return priv->context != NULL; + if (!priv->context) + return FALSE; + + priv->va_context = gst_vaapi_context_get_id(priv->context); + return TRUE; } gboolean @@ -573,3 +611,281 @@ gst_vaapi_decoder_push_surface_proxy( { return push_surface(decoder, g_object_ref(proxy), timestamp); } + +static void +destroy_iq_matrix(GstVaapiDecoder *decoder, GstVaapiIqMatrix *iq_matrix); + +static void +destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice); + +static void +destroy_slice_cb(gpointer data, gpointer user_data) +{ + GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(user_data); + GstVaapiSlice * const slice = data; + + destroy_slice(decoder, slice); +} + +static void +destroy_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (picture->slices) { + g_ptr_array_foreach(picture->slices, destroy_slice_cb, decoder); + g_ptr_array_free(picture->slices, TRUE); + picture->slices = NULL; + } + + if (picture->iq_matrix) { + destroy_iq_matrix(decoder, picture->iq_matrix); + picture->iq_matrix = NULL; + } + + picture->surface = NULL; + picture->surface_id = VA_INVALID_ID; + + vaapi_destroy_buffer(priv->va_display, &picture->param_id); + picture->param = NULL; + g_slice_free1(priv->codec_info.pic_size, picture); +} + +static GstVaapiPicture * +create_picture(GstVaapiDecoder *decoder) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiPicture *picture; + + picture = g_slice_alloc(priv->codec_info.pic_size); + if (!picture) + return NULL; + + picture->type = GST_VAAPI_PICTURE_TYPE_NONE; + picture->flags = 0; + picture->surface_id = VA_INVALID_ID; + picture->surface = NULL; + picture->param_id = VA_INVALID_ID; + picture->param = NULL; + picture->slices = NULL; + picture->iq_matrix = NULL; + picture->pts = GST_CLOCK_TIME_NONE; + + picture->surface = gst_vaapi_context_get_surface(priv->context); + if (!picture->surface) + goto error; + picture->surface_id = gst_vaapi_surface_get_id(picture->surface); + + picture->param = vaapi_create_buffer( + priv->va_display, + priv->va_context, + VAPictureParameterBufferType, + priv->codec_info.pic_param_size, + &picture->param_id + ); + if (!picture->param) + goto error; + + picture->slices = g_ptr_array_new(); + if (!picture->slices) + goto error; + return picture; + +error: + destroy_picture(priv->va_display, picture); + return NULL; +} + +GstVaapiPicture * +gst_vaapi_decoder_new_picture(GstVaapiDecoder *decoder) +{ + return create_picture(decoder); +} + +void +gst_vaapi_decoder_free_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) +{ + destroy_picture(decoder, picture); +} + +static void +destroy_iq_matrix(GstVaapiDecoder *decoder, GstVaapiIqMatrix *iq_matrix) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + vaapi_destroy_buffer(priv->va_display, &iq_matrix->param_id); + iq_matrix->param = NULL; + g_slice_free(GstVaapiIqMatrix, iq_matrix); +} + +static GstVaapiIqMatrix * +create_iq_matrix(GstVaapiDecoder *decoder) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiIqMatrix *iq_matrix; + + iq_matrix = g_slice_new(GstVaapiIqMatrix); + if (!iq_matrix) + return NULL; + + iq_matrix->param_id = VA_INVALID_ID; + + iq_matrix->param = vaapi_create_buffer( + priv->va_display, + priv->va_context, + VAIQMatrixBufferType, + priv->codec_info.iq_matrix_size, + &iq_matrix->param_id + ); + if (!iq_matrix->param) + goto error; + return iq_matrix; + +error: + destroy_iq_matrix(decoder, iq_matrix); + return NULL; +} + +GstVaapiIqMatrix * +gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder) +{ + return create_iq_matrix(decoder); +} + +static void +destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + vaapi_destroy_buffer(priv->va_display, &slice->data_id); + vaapi_destroy_buffer(priv->va_display, &slice->param_id); + slice->param = NULL; + g_slice_free1(priv->codec_info.slice_size, slice); +} + +static GstVaapiSlice * +create_slice(GstVaapiDecoder *decoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiSlice *slice; + VASliceParameterBufferBase *slice_param; + guchar *data; + + slice = g_slice_alloc(priv->codec_info.slice_size); + if (!slice) + return NULL; + + slice->data_id = VA_INVALID_ID; + slice->param_id = VA_INVALID_ID; + + data = vaapi_create_buffer( + priv->va_display, + priv->va_context, + VASliceDataBufferType, + buf_size, + &slice->data_id + ); + if (!data) + goto error; + memcpy(data, buf, buf_size); + vaapi_unmap_buffer(priv->va_display, slice->data_id, NULL); + + slice->param = vaapi_create_buffer( + priv->va_display, + priv->va_context, + VASliceParameterBufferType, + priv->codec_info.slice_param_size, + &slice->param_id + ); + if (!slice->param) + goto error; + + slice_param = slice->param; + slice_param->slice_data_size = buf_size; + slice_param->slice_data_offset = 0; + slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL; + return slice; + +error: + destroy_slice(decoder, slice); + return NULL; +} + +GstVaapiSlice * +gst_vaapi_decoder_new_slice( + GstVaapiDecoder *decoder, + GstVaapiPicture *picture, + guchar *buf, + guint buf_size +) +{ + GstVaapiSlice *slice; + + slice = create_slice(decoder, buf, buf_size); + if (!slice) + return NULL; + g_ptr_array_add(picture->slices, slice); + return slice; +} + +gboolean +gst_vaapi_decoder_decode_picture( + GstVaapiDecoder *decoder, + GstVaapiPicture *picture +) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiIqMatrix * const iq_matrix = picture->iq_matrix; + GstVaapiSlice *slice; + VABufferID va_buffers[3]; + guint i, n_va_buffers = 0; + VAStatus status; + + GST_DEBUG("decode picture 0x%08x", gst_vaapi_surface_get_id(picture->surface)); + + vaapi_unmap_buffer(priv->va_display, picture->param_id, &picture->param); + va_buffers[n_va_buffers++] = picture->param_id; + + if (iq_matrix) { + vaapi_unmap_buffer(priv->va_display, iq_matrix->param_id, &iq_matrix->param); + va_buffers[n_va_buffers++] = iq_matrix->param_id; + } + + status = vaBeginPicture( + priv->va_display, + priv->va_context, + picture->surface_id + ); + if (!vaapi_check_status(status, "vaBeginPicture()")) + return FALSE; + + status = vaRenderPicture( + priv->va_display, + priv->va_context, + va_buffers, n_va_buffers + ); + if (!vaapi_check_status(status, "vaRenderPicture()")) + return FALSE; + + for (i = 0; i < picture->slices->len; i++) { + slice = g_ptr_array_index(picture->slices, i); + + vaapi_unmap_buffer(priv->va_display, slice->param_id, NULL); + va_buffers[0] = slice->param_id; + va_buffers[1] = slice->data_id; + n_va_buffers = 2; + + status = vaRenderPicture( + priv->va_display, + priv->va_context, + va_buffers, n_va_buffers + ); + if (!vaapi_check_status(status, "vaRenderPicture()")) + return FALSE; + } + + status = vaEndPicture(priv->va_display, priv->va_context); + if (!vaapi_check_status(status, "vaEndPicture()")) + return FALSE; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index d6e696fb47..d4cb9bbc19 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -108,12 +108,74 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DECODER, \ GstVaapiDecoderPrivate)) +typedef enum _GstVaapiPictureType GstVaapiPictureType; +typedef struct _GstVaapiCodecInfo GstVaapiCodecInfo; +typedef struct _GstVaapiPicture GstVaapiPicture; +typedef struct _GstVaapiSlice GstVaapiSlice; +typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix; + +enum _GstVaapiPictureType { + 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) +}; + +enum { + GST_VAAPI_PICTURE_SKIPPED = 1 << 0, // Skipped frame + GST_VAAPI_PICTURE_REFERENCE = 1 << 1, // Reference frame +}; + +#define GST_VAAPI_PICTURE(picture) \ + ((GstVaapiPicture *)(picture)) + +#define GST_VAAPI_PICTURE_IS_REFERENCE(picture) \ + ((GST_VAAPI_PICTURE(picture)->flags & GST_VAAPI_PICTURE_REFERENCE) != 0) + +struct _GstVaapiCodecInfo { + guint pic_size; // GstVaapiPicture size + guint slice_size; // GstVaapiSlice size + guint pic_param_size; // VAPictureParameterBuffer size + guint slice_param_size; // VASliceParameterBuffer size + guint iq_matrix_size; // VAIQMatrixBuffer size +}; + +struct _GstVaapiPicture { + GstVaapiPictureType type; + guint flags; + VASurfaceID surface_id; + GstVaapiSurface *surface; + VABufferID param_id; + void *param; + GPtrArray *slices; + GstVaapiIqMatrix *iq_matrix; + GstClockTime pts; +}; + +struct _GstVaapiSlice { + VABufferID param_id; + void *param; + VABufferID data_id; +}; + +struct _GstVaapiIqMatrix { + VABufferID param_id; + void *param; +}; + struct _GstVaapiDecoderPrivate { GstVaapiDisplay *display; + VADisplay va_display; GstVaapiContext *context; + VAContextID va_context; GstCaps *caps; GstVaapiCodec codec; GstBuffer *codec_data; + GstVaapiCodecInfo codec_info; guint width; guint height; guint fps_n; @@ -176,6 +238,32 @@ gst_vaapi_decoder_push_surface_proxy( GstClockTime timestamp ) attribute_hidden; +GstVaapiPicture * +gst_vaapi_decoder_new_picture(GstVaapiDecoder *decoder) + attribute_hidden; + +void +gst_vaapi_decoder_free_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) + attribute_hidden; + +GstVaapiIqMatrix * +gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder) + attribute_hidden; + +GstVaapiSlice * +gst_vaapi_decoder_new_slice( + GstVaapiDecoder *decoder, + GstVaapiPicture *picture, + guchar *buf, + guint buf_size +) attribute_hidden; + +gboolean +gst_vaapi_decoder_decode_picture( + GstVaapiDecoder *decoder, + GstVaapiPicture *picture +) attribute_hidden; + G_END_DECLS #endif /* GST_VAAPI_DECODER_PRIV_H */ From 8f0eda896440812820b8e206edaf999e1c92e8f2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 12 Aug 2011 10:21:19 +0200 Subject: [PATCH 0554/3781] Allow conditional build of GStreamer/FFmpeg bitstream parsers. --- configure.ac | 50 ++++++++++++++++++++++++++++++-- gst-libs/gst/vaapi/Makefile.am | 53 ++++++++++++++++++++-------------- gst/vaapi/gstvaapidecode.c | 34 +++++++++++++++++++--- tests/test-decode.c | 34 ++++++++++++++++++++-- 4 files changed, 139 insertions(+), 32 deletions(-) diff --git a/configure.ac b/configure.ac index 5ea1c20aef..78b5b9ea52 100644 --- a/configure.ac +++ b/configure.ac @@ -99,6 +99,16 @@ AC_ARG_ENABLE(vaapisink-glx, [enable OpenGL/X11 to vaapisink @<:@default=yes@:>@]), [], [enable_vaapisink_glx="no"]) +AC_ARG_ENABLE(ffmpeg, + AC_HELP_STRING([--enable-ffmpeg], + [enable bitstream parsing from FFmpeg @<:@default=yes@:>@]), + [], [enable_ffmpeg="yes"]) + +AC_ARG_ENABLE(codecparsers, + AC_HELP_STRING([--enable-codecparsers], + [enable adhoc bitstream parsers from GStreamer @<:@default=yes@:>@]), + [], [enable_codecparsers="yes"]) + dnl Check for __attribute__((visibility())) AC_CACHE_CHECK([whether __attribute__((visibility())) is supported], vaapi_cv_visibility_attribute, @@ -220,6 +230,20 @@ PKG_CHECK_MODULES([GST_BASEVIDEO], AC_SUBST(GST_BASEVIDEO_CFLAGS) AC_SUBST(GST_BASEVIDEO_LIBS) +dnl Check for GStreamer codec parsers +USE_CODEC_PARSERS=0 +if test "$enable_codecparsers" = "yes"; then +PKG_CHECK_MODULES([GST_CODEC_PARSERS], + [gstreamer-codecparsers-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED], + [enable_codecparsers="yes" USE_CODEC_PARSERS=1], + [enable_codecparsers="no" USE_CODEC_PARSERS=0] +) +fi + +AC_DEFINE_UNQUOTED(USE_CODEC_PARSERS, $USE_CODEC_PARSERS, + [Defined to 1 if GStreamer codec parsers are used]) +AM_CONDITIONAL(USE_CODEC_PARSERS, test $USE_CODEC_PARSERS -eq 1) + dnl Check for GStreamer interfaces PKG_CHECK_MODULES([GST_INTERFACES], [gstreamer-interfaces-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED] @@ -338,10 +362,28 @@ else fi dnl Check for FFmpeg -PKG_CHECK_MODULES(LIBAVCODEC, [libavcodec]) +USE_FFMPEG=0 +if test "$enable_ffmpeg" = "yes"; then +PKG_CHECK_MODULES(LIBAVCODEC, [libavcodec], + [enable_ffmpeg="yes" USE_FFMPEG=1], + [enable_ffmpeg="no" USE_FFMPEG=0] +) +fi +if test "$enable_ffmpeg" = "yes"; then AC_CHECK_HEADERS([libavcodec/avcodec.h ffmpeg/avcodec.h]) -AC_CHECK_HEADERS([libavcodec/vaapi.h ffmpeg/vaapi.h], [break], - AC_MSG_ERROR([The system FFmpeg headers do not support VA-API])) +AC_CHECK_HEADERS([libavcodec/vaapi.h ffmpeg/vaapi.h], + [break], + [enable_ffmpeg="no" USE_FFMPEG=0] +) +fi + +if test "$enable_ffmpeg:$enable_codecparsers" = "no:no"; then + AC_MSG_ERROR([Found neither suitable FFmpeg with VA-API support nor GStreamer bitstream parsers]) +fi + +AC_DEFINE_UNQUOTED(USE_FFMPEG, $USE_FFMPEG, + [Defined to 1 if FFmpeg is used]) +AM_CONDITIONAL(USE_FFMPEG, test $USE_FFMPEG -eq 1) AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) @@ -414,4 +456,6 @@ echo VA-API version ................... : $VA_VERSION_STR echo GLX support ...................... : $(yesno $USE_GLX) echo VA/GLX support ................... : $(yesno $USE_VAAPI_GLX) echo VaapiSink/GL ..................... : $(yesno $USE_VAAPISINK_GLX) +echo FFmpeg bitstream parsers ......... : $(yesno $USE_FFMPEG) +echo GStreamer bitstream parsers ...... : $(yesno $USE_CODEC_PARSERS) echo diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 5a69da6839..4333aa356b 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -10,15 +10,21 @@ endif libgstvaapi_includedir = \ $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi -libgstvaapi_ffmpeg_source_c = \ - gstvaapidecoder_ffmpeg.c \ +libgstvaapi_cflags = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + $(GST_BASE_CFLAGS) \ + $(GST_BASEVIDEO_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ + $(GST_CFLAGS) \ + $(LIBVA_CFLAGS) \ $(NULL) -libgstvaapi_ffmpeg_source_h = \ - gstvaapidecoder_ffmpeg.h \ - $(NULL) - -libgstvaapi_ffmpeg_source_priv_h = \ +libgstvaapi_libs = \ + $(GST_BASE_LIBS) \ + $(GST_BASEVIDEO_LIBS) \ + $(GST_LIBS) \ + $(LIBVA_LIBS) \ $(NULL) libgstvaapi_source_c = \ @@ -44,7 +50,6 @@ libgstvaapi_source_c = \ gstvaapivideopool.c \ gstvaapivideosink.c \ gstvaapiwindow.c \ - $(libgstvaapi_ffmpeg_source_c) \ $(NULL) libgstvaapi_source_h = \ @@ -68,7 +73,6 @@ libgstvaapi_source_h = \ gstvaapivideopool.h \ gstvaapivideosink.h \ gstvaapiwindow.h \ - $(libgstvaapi_ffmpeg_source_h) \ $(NULL) libgstvaapi_source_priv_h = \ @@ -131,6 +135,22 @@ libgstvaapi_glx_source_priv_h = \ gstvaapiutils_x11.h \ $(NULL) +if USE_FFMPEG +libgstvaapi_source_c += gstvaapidecoder_ffmpeg.c +libgstvaapi_source_h += gstvaapidecoder_ffmpeg.h +libgstvaapi_cflags += $(LIBAVCODEC_CFLAGS) +libgstvaapi_libs += $(LIBAVCODEC_LIBS) +endif + +if USE_CODEC_PARSERS +libgstvaapi_source_c += \ + $(NULL) +libgstvaapi_source_h += \ + $(NULL) +libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS) +libgstvaapi_libs += $(GST_CODEC_PARSERS_LIBS) +endif + libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_source_c) \ $(libgstvaapi_source_priv_h) \ @@ -144,22 +164,11 @@ libgstvaapi_@GST_MAJORMINOR@includedir = \ $(libgstvaapi_includedir) libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - $(GST_BASE_CFLAGS) \ - $(GST_BASEVIDEO_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(GST_CFLAGS) \ - $(LIBAVCODEC_CFLAGS) \ - $(LIBVA_CFLAGS) \ + $(libgstvaapi_cflags) \ $(NULL) libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ - $(GST_BASE_LIBS) \ - $(GST_BASEVIDEO_LIBS) \ - $(GST_LIBS) \ - $(LIBAVCODEC_LIBS) \ - $(LIBVA_LIBS) \ + $(libgstvaapi_libs) \ $(NULL) libgstvaapi_@GST_MAJORMINOR@_la_LDFLAGS = \ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a5f0b0c5d3..d4eb118eff 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -45,6 +45,16 @@ #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" +#if USE_FFMPEG +# include +#endif +#if USE_CODEC_PARSERS +#endif + +/* Favor codecparsers-based decoders for 0.3.x series */ +#define USE_FFMPEG_DEFAULT \ + (USE_FFMPEG && !USE_CODEC_PARSERS) + #define GST_PLUGIN_NAME "vaapidecode" #define GST_PLUGIN_DESC "A VA-API based video decoder" @@ -271,6 +281,9 @@ error_commit_buffer: static gboolean gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) { + VADisplay dpy; + GstStructure *structure; + if (!gst_vaapi_ensure_display(decode, &decode->display)) return FALSE; @@ -282,8 +295,19 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) if (!decode->decoder_ready) return FALSE; - if (decode->use_ffmpeg) - decode->decoder = gst_vaapi_decoder_ffmpeg_new(decode->display, caps); + dpy = decode->display; + if (decode->use_ffmpeg) { +#if USE_FFMPEG + decode->decoder = gst_vaapi_decoder_ffmpeg_new(dpy, caps); +#endif + } + else { +#if USE_CODEC_PARSERS + structure = gst_caps_get_structure(caps, 0); + if (!structure) + return FALSE; +#endif + } if (!decode->decoder) return FALSE; @@ -504,14 +528,16 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) element_class->change_state = gst_vaapidecode_change_state; +#if USE_FFMPEG g_object_class_install_property (object_class, PROP_USE_FFMPEG, g_param_spec_boolean("use-ffmpeg", "Use FFmpeg/VAAPI for decoding", "Uses FFmpeg/VAAPI for decoding", - TRUE, + USE_FFMPEG_DEFAULT, G_PARAM_READWRITE)); +#endif } static gboolean @@ -672,7 +698,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) decode->decoder_ready = NULL; decode->decoder_caps = NULL; decode->allowed_caps = NULL; - decode->use_ffmpeg = TRUE; + decode->use_ffmpeg = USE_FFMPEG_DEFAULT; decode->is_ready = FALSE; /* Pad through which data comes in to the element */ diff --git a/tests/test-decode.c b/tests/test-decode.c index 0aece9428a..67b00db9b0 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -19,16 +19,22 @@ * Boston, MA 02110-1301 USA */ +#include "config.h" #include #include #include #include -#include #include #include "test-mpeg2.h" #include "test-h264.h" #include "test-vc1.h" +#if USE_FFMPEG +# include +#endif +#if USE_CODEC_PARSERS +#endif + /* Set to 1 to check display cache works (shared VA display) */ #define CHECK_DISPLAY_CACHE 1 @@ -66,12 +72,21 @@ static inline void pause(void) } static gchar *g_codec_str; +static gboolean g_use_ffmpeg = FALSE; static GOptionEntry g_options[] = { { "codec", 'c', 0, G_OPTION_ARG_STRING, &g_codec_str, "codec to test", NULL }, + { "ffmpeg", 0, + 0, + G_OPTION_ARG_NONE, &g_use_ffmpeg, + "use ffmpeg", NULL }, + { "codecparsers", 0, + G_OPTION_FLAG_REVERSE, + G_OPTION_ARG_NONE, &g_use_ffmpeg, + "use codec parsers", NULL }, { NULL, } }; @@ -137,9 +152,22 @@ main(int argc, char *argv[]) NULL ); - decoder = gst_vaapi_decoder_ffmpeg_new(display, decoder_caps); + if (g_use_ffmpeg) { +#if USE_FFMPEG + decoder = gst_vaapi_decoder_ffmpeg_new(display, decoder_caps); +#endif + } + else { +#if USE_CODEC_PARSERS + switch (gst_vaapi_profile_get_codec(info.profile)) { + default: + decoder = NULL; + break; + } +#endif + } if (!decoder) - g_error("could not create FFmpeg decoder"); + g_error("could not create decoder"); gst_caps_unref(decoder_caps); buffer = gst_buffer_new(); From 49b4702fb696df18168343e12d99801585981da8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 5 Aug 2011 11:55:11 +0200 Subject: [PATCH 0555/3781] Add initial MPEG-2 decoder. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 942 +++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h | 87 ++ gst/vaapi/gstvaapidecode.c | 9 + tests/test-decode.c | 4 + 5 files changed, 1044 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 4333aa356b..802394436a 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -144,8 +144,10 @@ endif if USE_CODEC_PARSERS libgstvaapi_source_c += \ + gstvaapidecoder_mpeg2.c \ $(NULL) libgstvaapi_source_h += \ + gstvaapidecoder_mpeg2.h \ $(NULL) libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS) libgstvaapi_libs += $(GST_CODEC_PARSERS_LIBS) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c new file mode 100644 index 0000000000..5a5d376e71 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -0,0 +1,942 @@ +/* + * gstvaapidecoder_mpeg2.c - MPEG-2 decoder + * + * Copyright (C) 2011 Intel Corporation + * + * 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_mpeg2 + * @short_description: MPEG-2 decoder + */ + +#include "config.h" +#include +#include +#include +#include "gstvaapidecoder_mpeg2.h" +#include "gstvaapidecoder_priv.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapiobject_priv.h" +#include "gstvaapiutils_tsb.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiDecoderMpeg2, + gst_vaapi_decoder_mpeg2, + GST_VAAPI_TYPE_DECODER); + +#define GST_VAAPI_DECODER_MPEG2_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DECODER_MPEG2, \ + GstVaapiDecoderMpeg2Private)) + +#define READ_UINT8(br, val, nbits) G_STMT_START { \ + if (!gst_bit_reader_get_bits_uint8 (br, &val, nbits)) { \ + GST_WARNING ("failed to read uint8, nbits: %d", nbits); \ + goto failed; \ + } \ +} G_STMT_END + +struct _GstVaapiDecoderMpeg2Private { + GstVaapiProfile profile; + guint width; + guint height; + guint fps_n; + guint fps_d; + GstMpegVideoSequenceHdr seq_hdr; + GstMpegVideoSequenceExt seq_ext; + GstMpegVideoPictureHdr pic_hdr; + GstMpegVideoPictureExt pic_ext; + GstMpegVideoQuantMatrixExt quant_matrix_ext; + GstVaapiPicture *current_picture; + GstVaapiPicture *next_picture; + GstVaapiPicture *prev_picture; + GstVaapiTSB *tsb; + GstBuffer *sub_buffer; + guint mb_y; + guint mb_height; + GstClockTime seq_pts; + GstClockTime gop_pts; + GstClockTime pts_diff; + guint is_constructed : 1; + guint is_opened : 1; + guint is_first_field : 1; + guint has_seq_ext : 1; + guint has_seq_scalable_ext : 1; + guint has_pic_ext : 1; + guint has_quant_matrix_ext : 1; + guint size_changed : 1; + guint profile_changed : 1; + guint quant_matrix_changed : 1; + guint progressive_sequence : 1; +}; + +static void +gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + + if (priv->current_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->current_picture); + priv->current_picture = NULL; + } + + if (priv->next_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->next_picture); + priv->next_picture = NULL; + } + + if (priv->prev_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); + priv->prev_picture = NULL; + } + + if (priv->sub_buffer) { + gst_buffer_unref(priv->sub_buffer); + priv->sub_buffer = NULL; + } + + if (priv->tsb) { + gst_vaapi_tsb_destroy(priv->tsb); + priv->tsb = NULL; + } +} + +static gboolean +gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + + gst_vaapi_decoder_mpeg2_close(decoder); + + priv->tsb = gst_vaapi_tsb_new(); + if (!priv->tsb) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_decoder_mpeg2_destroy(GstVaapiDecoderMpeg2 *decoder) +{ + gst_vaapi_decoder_mpeg2_close(decoder); +} + +static gboolean +gst_vaapi_decoder_mpeg2_create(GstVaapiDecoderMpeg2 *decoder) +{ + if (!GST_VAAPI_DECODER_CODEC(decoder)) + return FALSE; + return TRUE; +} + +static inline void +copy_quant_matrix(guint8 dst[64], const guint8 src[64]) +{ + memcpy(dst, src, 64); +} + +static GstVaapiDecoderStatus +ensure_context(GstVaapiDecoderMpeg2 *decoder) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + 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_MPEG2_SIMPLE) + profiles[n_profiles++] = GST_VAAPI_PROFILE_MPEG2_MAIN; + + 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 (priv->progressive_sequence) + priv->mb_height = (priv->height + 15) / 16; + else + priv->mb_height = (priv->height + 31) / 32 * 2; + } + + if (reset_context) { + reset_context = gst_vaapi_decoder_ensure_context( + GST_VAAPI_DECODER(decoder), + priv->profile, + entrypoint, + priv->width, priv->height + ); + if (!reset_context) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + VAIQMatrixBufferMPEG2 *iq_matrix; + guint8 *intra_quant_matrix = NULL; + guint8 *non_intra_quant_matrix = NULL; + guint8 *chroma_intra_quant_matrix = NULL; + guint8 *chroma_non_intra_quant_matrix = NULL; + + if (!priv->quant_matrix_changed) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + priv->quant_matrix_changed = FALSE; + + picture->iq_matrix = gst_vaapi_decoder_new_iq_matrix(GST_VAAPI_DECODER(decoder)); + if (!picture->iq_matrix) { + GST_DEBUG("failed to allocate IQ matrix"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + iq_matrix = picture->iq_matrix->param; + + intra_quant_matrix = priv->seq_hdr.intra_quantizer_matrix; + non_intra_quant_matrix = priv->seq_hdr.non_intra_quantizer_matrix; + if (priv->has_quant_matrix_ext) { + if (priv->quant_matrix_ext.load_intra_quantiser_matrix) + intra_quant_matrix = priv->quant_matrix_ext.intra_quantiser_matrix; + if (priv->quant_matrix_ext.load_non_intra_quantiser_matrix) + non_intra_quant_matrix = priv->quant_matrix_ext.non_intra_quantiser_matrix; + if (priv->quant_matrix_ext.load_chroma_intra_quantiser_matrix) + chroma_intra_quant_matrix = priv->quant_matrix_ext.chroma_intra_quantiser_matrix; + if (priv->quant_matrix_ext.load_chroma_non_intra_quantiser_matrix) + chroma_non_intra_quant_matrix = priv->quant_matrix_ext.chroma_non_intra_quantiser_matrix; + } + + iq_matrix->load_intra_quantiser_matrix = intra_quant_matrix != NULL; + if (intra_quant_matrix) { + iq_matrix->load_intra_quantiser_matrix = 1; + copy_quant_matrix(iq_matrix->intra_quantiser_matrix, + intra_quant_matrix); + } + + iq_matrix->load_intra_quantiser_matrix = 1; + copy_quant_matrix(iq_matrix->intra_quantiser_matrix, + priv->seq_hdr.intra_quantizer_matrix); + + iq_matrix->load_non_intra_quantiser_matrix = 1; + copy_quant_matrix(iq_matrix->non_intra_quantiser_matrix, + priv->seq_hdr.non_intra_quantizer_matrix); + + iq_matrix->load_chroma_intra_quantiser_matrix = 0; + iq_matrix->load_chroma_non_intra_quantiser_matrix = 0; + if (priv->has_quant_matrix_ext) { + if (priv->quant_matrix_ext.load_intra_quantiser_matrix) + copy_quant_matrix(iq_matrix->intra_quantiser_matrix, + priv->quant_matrix_ext.intra_quantiser_matrix); + + if (priv->quant_matrix_ext.load_non_intra_quantiser_matrix) + copy_quant_matrix(iq_matrix->non_intra_quantiser_matrix, + priv->quant_matrix_ext.non_intra_quantiser_matrix); + + if (priv->quant_matrix_ext.load_chroma_intra_quantiser_matrix) { + iq_matrix->load_chroma_intra_quantiser_matrix = 1; + copy_quant_matrix(iq_matrix->chroma_intra_quantiser_matrix, + priv->quant_matrix_ext.chroma_intra_quantiser_matrix); + } + + if (priv->quant_matrix_ext.load_chroma_non_intra_quantiser_matrix) { + iq_matrix->load_chroma_non_intra_quantiser_matrix = 1; + copy_quant_matrix(iq_matrix->chroma_non_intra_quantiser_matrix, + priv->quant_matrix_ext.chroma_non_intra_quantiser_matrix); + } + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static inline GstVaapiDecoderStatus +render_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + + if (!gst_vaapi_decoder_push_surface(base_decoder, + picture->surface, + picture->pts)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_current_picture(GstVaapiDecoderMpeg2 *decoder) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiPicture * const picture = priv->current_picture; + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (picture) { + if (!gst_vaapi_decoder_decode_picture(base_decoder, picture)) + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { + if (priv->prev_picture && priv->next_picture) + status = render_picture(decoder, picture); + gst_vaapi_decoder_free_picture(base_decoder, picture); + } + priv->current_picture = NULL; + } + return status; +} + +static GstVaapiDecoderStatus +decode_sequence(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr; + + if (!gst_mpeg_video_parse_sequence_header(seq_hdr, buf, buf_size, 0)) { + GST_DEBUG("failed to parse sequence header"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + priv->fps_n = seq_hdr->fps_n; + priv->fps_d = seq_hdr->fps_d; + gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); + + priv->seq_pts = gst_vaapi_tsb_get_timestamp(priv->tsb); + + priv->width = seq_hdr->width; + priv->height = seq_hdr->height; + priv->has_seq_ext = FALSE; + priv->size_changed = TRUE; + priv->quant_matrix_changed = TRUE; + priv->progressive_sequence = TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoSequenceExt * const seq_ext = &priv->seq_ext; + GstVaapiProfile profile; + guint width, height; + + if (!gst_mpeg_video_parse_sequence_extension(seq_ext, buf, buf_size, 0)) { + GST_DEBUG("failed to parse sequence-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + priv->has_seq_ext = TRUE; + priv->progressive_sequence = seq_ext->progressive; + + width = (priv->width & 0xffff) | ((guint32)seq_ext->horiz_size_ext << 16); + height = (priv->height & 0xffff) | ((guint32)seq_ext->vert_size_ext << 16); + GST_DEBUG("video resolution %ux%u", width, height); + + if (seq_ext->fps_n_ext && seq_ext->fps_d_ext) { + priv->fps_n *= seq_ext->fps_n_ext + 1; + priv->fps_d *= seq_ext->fps_d_ext + 1; + gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); + } + + if (priv->width != width) { + priv->width = width; + priv->size_changed = TRUE; + } + + if (priv->height != height) { + priv->height = height; + priv->size_changed = TRUE; + } + + switch (seq_ext->profile) { + case GST_MPEG_VIDEO_PROFILE_SIMPLE: + profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; + break; + case GST_MPEG_VIDEO_PROFILE_MAIN: + profile = GST_VAAPI_PROFILE_MPEG2_MAIN; + break; + default: + GST_DEBUG("unsupported profile %d", seq_ext->profile); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + if (priv->profile != profile) { + priv->profile = profile; + priv->profile_changed = TRUE; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + + if (priv->current_picture) { + status = decode_current_picture(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + status = render_picture(decoder, priv->current_picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + + if (priv->next_picture) { + status = render_picture(decoder, priv->next_picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; +} + +static GstVaapiDecoderStatus +decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoQuantMatrixExt * const quant_matrix_ext = &priv->quant_matrix_ext; + + if (!gst_mpeg_video_parse_quant_matrix_extension(quant_matrix_ext, buf, buf_size, 0)) { + GST_DEBUG("failed to parse quant-matrix-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + priv->has_quant_matrix_ext = TRUE; + priv->quant_matrix_changed = TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoGop gop; + GstClockTime pts; + + if (!gst_mpeg_video_parse_gop(&gop, buf, buf_size, 0)) { + GST_DEBUG("failed to parse GOP"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + GST_DEBUG("GOP %02u:%02u:%02u:%02u", + gop.hour, gop.minute, gop.second, gop.frame); + + pts = GST_SECOND * (gop.hour * 3600 + gop.minute * 60 + gop.second); + pts += gst_util_uint64_scale(gop.frame, GST_SECOND * priv->fps_d, priv->fps_n); + priv->gop_pts = pts; + if (!priv->pts_diff) + priv->pts_diff = priv->seq_pts - priv->gop_pts; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr; + GstVaapiPicture *picture; + GstVaapiDecoderStatus status; + GstClockTime pts; + + status = ensure_context(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_DEBUG("failed to reset context"); + return status; + } + + if (priv->current_picture) { + status = decode_current_picture(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + + priv->current_picture = gst_vaapi_decoder_new_picture(base_decoder); + if (!priv->current_picture) { + GST_DEBUG("failed to allocate picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + picture = priv->current_picture; + + status = ensure_quant_matrix(decoder, picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_DEBUG("failed to reset quantizer matrix"); + return status; + } + + if (!gst_mpeg_video_parse_picture_header(pic_hdr, buf, buf_size, 0)) { + GST_DEBUG("failed to parse picture header"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + priv->has_pic_ext = FALSE; + + switch (pic_hdr->pic_type) { + case GST_MPEG_VIDEO_PICTURE_TYPE_I: + picture->type = GST_VAAPI_PICTURE_TYPE_I; + break; + case GST_MPEG_VIDEO_PICTURE_TYPE_P: + picture->type = GST_VAAPI_PICTURE_TYPE_P; + break; + case GST_MPEG_VIDEO_PICTURE_TYPE_B: + picture->type = GST_VAAPI_PICTURE_TYPE_B; + break; + default: + GST_DEBUG("unsupported picture type %d", pic_hdr->pic_type); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + priv->mb_y = 0; + if (pic_hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_I) + priv->is_first_field = TRUE; + else + priv->is_first_field ^= 1; + + /* Update presentation time */ + pts = priv->gop_pts; + pts += gst_util_uint64_scale(pic_hdr->tsn, GST_SECOND * priv->fps_d, priv->fps_n); + picture->pts = pts + priv->pts_diff; + + /* Update reference pictures */ + if (pic_hdr->pic_type != GST_MPEG_VIDEO_PICTURE_TYPE_B) { + picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + if (priv->prev_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); + priv->prev_picture = NULL; + } + if (priv->next_picture) { + priv->prev_picture = priv->next_picture; + priv->next_picture = NULL; + status = render_picture(decoder, priv->prev_picture); + } + priv->next_picture = picture; + } + return status; +} + +static GstVaapiDecoderStatus +decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext; + + if (!gst_mpeg_video_parse_picture_extension(pic_ext, buf, buf_size, 0)) { + GST_DEBUG("failed to parse picture-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + priv->has_pic_ext = TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static inline guint32 +pack_f_code(guint8 f_code[2][2]) +{ + return (((guint32)f_code[0][0] << 12) | + ((guint32)f_code[0][1] << 8) | + ((guint32)f_code[1][0] << 4) | + ( f_code[1][1] )); +} + +static gboolean +fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + VAPictureParameterBufferMPEG2 * const pic_param = picture->param; + GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr; + GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext; + + if (!priv->has_pic_ext) + return FALSE; + + /* Fill in VAPictureParameterBufferMPEG2 */ + pic_param->horizontal_size = priv->width; + pic_param->vertical_size = priv->height; + pic_param->forward_reference_picture = VA_INVALID_ID; + pic_param->backward_reference_picture = VA_INVALID_ID; + pic_param->picture_coding_type = pic_hdr->pic_type; + pic_param->f_code = pack_f_code(pic_ext->f_code); + +#define COPY_FIELD(a, b, f) \ + pic_param->a.b.f = pic_ext->f + pic_param->picture_coding_extension.value = 0; + pic_param->picture_coding_extension.bits.is_first_field = priv->is_first_field; + COPY_FIELD(picture_coding_extension, bits, intra_dc_precision); + COPY_FIELD(picture_coding_extension, bits, picture_structure); + COPY_FIELD(picture_coding_extension, bits, top_field_first); + COPY_FIELD(picture_coding_extension, bits, frame_pred_frame_dct); + COPY_FIELD(picture_coding_extension, bits, concealment_motion_vectors); + COPY_FIELD(picture_coding_extension, bits, q_scale_type); + COPY_FIELD(picture_coding_extension, bits, intra_vlc_format); + COPY_FIELD(picture_coding_extension, bits, alternate_scan); + COPY_FIELD(picture_coding_extension, bits, repeat_first_field); + COPY_FIELD(picture_coding_extension, bits, progressive_frame); + + switch (pic_hdr->pic_type) { + case GST_MPEG_VIDEO_PICTURE_TYPE_B: + if (priv->next_picture) + pic_param->backward_reference_picture = priv->next_picture->surface_id; + // fall-through + case GST_MPEG_VIDEO_PICTURE_TYPE_P: + if (priv->prev_picture) + pic_param->forward_reference_picture = priv->prev_picture->surface_id; + break; + } + return TRUE; +} + +static GstVaapiDecoderStatus +decode_slice( + GstVaapiDecoderMpeg2 *decoder, + int slice_no, + guchar *buf, + guint buf_size +) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiPicture * const picture = priv->current_picture; + GstVaapiSlice *slice; + VASliceParameterBufferMPEG2 *slice_param; + GstVaapiDecoderStatus status; + GstBitReader br; + guint8 slice_vertical_position_extension; + guint8 quantiser_scale_code; + guint8 intra_slice_flag, intra_slice = 0; + guint8 extra_bit_slice, junk8; + + GST_DEBUG("slice %d @ %p, %u bytes)", slice_no, buf, buf_size); + + if (picture->slices->len == 0 && !fill_picture(decoder, picture)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + priv->mb_y = slice_no; + + slice = gst_vaapi_decoder_new_slice( + GST_VAAPI_DECODER(decoder), + picture, + buf, buf_size + ); + if (!slice) { + GST_DEBUG("failed to allocate slice"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + /* Parse slice */ + gst_bit_reader_init(&br, buf, buf_size); + if (priv->height > 2800) + READ_UINT8(&br, slice_vertical_position_extension, 3); + if (priv->has_seq_scalable_ext) { + GST_DEBUG("failed to parse slice %d. Unsupported sequence_scalable_extension()", slice_no); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + READ_UINT8(&br, quantiser_scale_code, 5); + READ_UINT8(&br, extra_bit_slice, 1); + if (extra_bit_slice == 1) { + READ_UINT8(&br, intra_slice_flag, 1); + if (intra_slice_flag) { + READ_UINT8(&br, intra_slice, 1); + READ_UINT8(&br, junk8, 7); + } + READ_UINT8(&br, extra_bit_slice, 1); + while (extra_bit_slice == 1) { + READ_UINT8(&br, junk8, 8); + READ_UINT8(&br, extra_bit_slice, 1); + } + } + + /* Fill in VASliceParameterBufferMPEG2 */ + slice_param = slice->param; + slice_param->macroblock_offset = gst_bit_reader_get_pos(&br); + slice_param->slice_horizontal_position = 0; + slice_param->slice_vertical_position = priv->mb_y; + slice_param->quantiser_scale_code = quantiser_scale_code; + slice_param->intra_slice_flag = intra_slice; + + /* Commit picture for decoding if we reached the last slice */ + if (++priv->mb_y >= priv->mb_height) { + status = decode_current_picture(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + GST_DEBUG("done"); + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; + +failed: + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; +} + +static GstVaapiDecoderStatus +decode_chunks(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer, GList *chunks) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoTypeOffsetSize *tos; + GstVaapiDecoderStatus status; + guchar * const buf = GST_BUFFER_DATA(buffer); + guchar *data; + guint data_size, ofs, pos = 0; + GList *l; + + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + for (l = chunks; l; l = g_list_next(l)) { + tos = l->data; + data = buf + tos->offset; + data_size = tos->size; + if (tos->size < 0) { + if (tos->offset < 4) + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + priv->sub_buffer = gst_buffer_create_sub( + buffer, + tos->offset - 4, + GST_BUFFER_SIZE(buffer) - (tos->offset - 4) + ); + break; + } + + ofs = tos->offset - pos + tos->size; + gst_vaapi_tsb_pop(priv->tsb, ofs); + pos += ofs; + + switch (tos->type) { + case GST_MPEG_VIDEO_PACKET_PICTURE: + status = decode_picture(decoder, data, data_size); + break; + case GST_MPEG_VIDEO_PACKET_SEQUENCE: + status = decode_sequence(decoder, data, data_size); + break; + case GST_MPEG_VIDEO_PACKET_EXTENSION: { + const guchar id = data[0] >> 4; + switch (id) { + case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: + status = decode_sequence_ext(decoder, data, data_size); + break; + case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: + status = decode_quant_matrix_ext(decoder, data, data_size); + break; + case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: + status = decode_picture_ext(decoder, data, data_size); + break; + default: + // Ignore unknown extensions + GST_DEBUG("unsupported start-code extension (0x%02x)", id); + break; + } + break; + } + case GST_MPEG_VIDEO_PACKET_SEQUENCE_END: + status = decode_sequence_end(decoder); + break; + case GST_MPEG_VIDEO_PACKET_GOP: + status = decode_gop(decoder, data, data_size); + break; + case GST_MPEG_VIDEO_PACKET_USER_DATA: + // Ignore user-data packets + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + default: + if (tos->type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + tos->type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { + status = decode_slice( + decoder, + tos->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN, + data, data_size + ); + break; + } + GST_DEBUG("unsupported start code (0x%02x)", tos->type); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + break; + } + return status; +} + +static GstVaapiDecoderStatus +decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + guchar *buf; + guint buf_size; + GList *chunks; + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + if (!buf && buf_size == 0) + return decode_sequence_end(decoder); + + gst_vaapi_tsb_push(priv->tsb, buffer); + + if (priv->sub_buffer) { + buffer = gst_buffer_merge(priv->sub_buffer, buffer); + if (!buffer) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + gst_buffer_unref(priv->sub_buffer); + priv->sub_buffer = NULL; + } + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + chunks = gst_mpeg_video_parse(buf, buf_size, 0); + if (!chunks) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + status = decode_chunks(decoder, buffer, chunks); + g_list_free_full(chunks, (GDestroyNotify)g_free); + return status; +} + +GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base, GstBuffer *buffer) +{ + GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2(base); + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + + g_return_val_if_fail(priv->is_constructed, + GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); + + if (!priv->is_opened) { + priv->is_opened = gst_vaapi_decoder_mpeg2_open(decoder, buffer); + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + } + return decode_buffer(decoder, buffer); +} + +static void +gst_vaapi_decoder_mpeg2_finalize(GObject *object) +{ + GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2(object); + + gst_vaapi_decoder_mpeg2_destroy(decoder); + + G_OBJECT_CLASS(gst_vaapi_decoder_mpeg2_parent_class)->finalize(object); +} + +static void +gst_vaapi_decoder_mpeg2_constructed(GObject *object) +{ + GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2(object); + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GObjectClass *parent_class; + + parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_mpeg2_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); + + priv->is_constructed = gst_vaapi_decoder_mpeg2_create(decoder); +} + +static void +gst_vaapi_decoder_mpeg2_class_init(GstVaapiDecoderMpeg2Class *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiDecoderMpeg2Private)); + + object_class->finalize = gst_vaapi_decoder_mpeg2_finalize; + object_class->constructed = gst_vaapi_decoder_mpeg2_constructed; + + decoder_class->decode = gst_vaapi_decoder_mpeg2_decode; +} + +static void +gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) +{ + GstVaapiDecoderMpeg2Private *priv; + + priv = GST_VAAPI_DECODER_MPEG2_GET_PRIVATE(decoder); + decoder->priv = priv; + priv->width = 0; + priv->height = 0; + priv->fps_n = 0; + priv->fps_d = 0; + priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; + priv->current_picture = NULL; + priv->next_picture = NULL; + priv->prev_picture = NULL; + priv->tsb = NULL; + priv->sub_buffer = NULL; + priv->mb_y = 0; + priv->mb_height = 0; + priv->seq_pts = GST_CLOCK_TIME_NONE; + priv->gop_pts = GST_CLOCK_TIME_NONE; + priv->pts_diff = 0; + priv->is_constructed = FALSE; + priv->is_opened = FALSE; + priv->is_first_field = FALSE; + priv->has_seq_ext = FALSE; + priv->has_seq_scalable_ext = FALSE; + priv->has_pic_ext = FALSE; + priv->has_quant_matrix_ext = FALSE; + priv->size_changed = FALSE; + priv->profile_changed = FALSE; + priv->quant_matrix_changed = FALSE; + priv->progressive_sequence = FALSE; +} + +/** + * gst_vaapi_decoder_mpeg2_new: + * @display: a #GstVaapiDisplay + * @caps: a #GstCaps holding codec information + * + * Creates a new #GstVaapiDecoder for MPEG-2 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_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps) +{ + GstVaapiDecoderMpeg2 *decoder; + + static const GstVaapiCodecInfo codec_info = { + .pic_size = sizeof(GstVaapiPicture), + .slice_size = sizeof(GstVaapiSlice), + .pic_param_size = sizeof(VAPictureParameterBufferMPEG2), + .slice_param_size = sizeof(VASliceParameterBufferMPEG2), + .iq_matrix_size = sizeof(VAIQMatrixBufferMPEG2), + }; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + decoder = g_object_new( + GST_VAAPI_TYPE_DECODER_MPEG2, + "display", display, + "caps", caps, + "codec-info", &codec_info, + NULL + ); + if (!decoder->priv->is_constructed) { + g_object_unref(decoder); + return NULL; + } + return GST_VAAPI_DECODER_CAST(decoder); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h new file mode 100644 index 0000000000..84a9a189e0 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h @@ -0,0 +1,87 @@ +/* + * gstvaapidecoder_mpeg2.h - MPEG-2 decoder + * + * Copyright (C) 2011 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DECODER_MPEG2 \ + (gst_vaapi_decoder_mpeg2_get_type()) + +#define GST_VAAPI_DECODER_MPEG2(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DECODER_MPEG2, \ + GstVaapiDecoderMpeg2)) + +#define GST_VAAPI_DECODER_MPEG2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DECODER_MPEG2, \ + GstVaapiDecoderMpeg2Class)) + +#define GST_VAAPI_IS_DECODER_MPEG2(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_MPEG2)) + +#define GST_VAAPI_IS_DECODER_MPEG2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_MPEG2)) + +#define GST_VAAPI_DECODER_MPEG2_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DECODER_MPEG2, \ + GstVaapiDecoderMpeg2Class)) + +typedef struct _GstVaapiDecoderMpeg2 GstVaapiDecoderMpeg2; +typedef struct _GstVaapiDecoderMpeg2Private GstVaapiDecoderMpeg2Private; +typedef struct _GstVaapiDecoderMpeg2Class GstVaapiDecoderMpeg2Class; + +/** + * GstVaapiDecoderMpeg2: + * + * A decoder based on Mpeg2. + */ +struct _GstVaapiDecoderMpeg2 { + /*< private >*/ + GstVaapiDecoder parent_instance; + + GstVaapiDecoderMpeg2Private *priv; +}; + +/** + * GstVaapiDecoderMpeg2Class: + * + * A decoder class based on Mpeg2. + */ +struct _GstVaapiDecoderMpeg2Class { + /*< private >*/ + GstVaapiDecoderClass parent_class; +}; + +GType +gst_vaapi_decoder_mpeg2_get_type(void); + +GstVaapiDecoder * +gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps); + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_MPEG2_H */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d4eb118eff..607750290c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -31,6 +31,7 @@ #include "config.h" #include +#include #include #include #include @@ -49,6 +50,7 @@ # include #endif #if USE_CODEC_PARSERS +# include #endif /* Favor codecparsers-based decoders for 0.3.x series */ @@ -283,6 +285,7 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) { VADisplay dpy; GstStructure *structure; + int version; if (!gst_vaapi_ensure_display(decode, &decode->display)) return FALSE; @@ -306,6 +309,12 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) structure = gst_caps_get_structure(caps, 0); if (!structure) return FALSE; + if (gst_structure_has_name(structure, "video/mpeg")) { + if (!gst_structure_get_int(structure, "mpegversion", &version)) + return FALSE; + if (version == 2) + decode->decoder = gst_vaapi_decoder_mpeg2_new(dpy, caps); + } #endif } if (!decode->decoder) diff --git a/tests/test-decode.c b/tests/test-decode.c index 67b00db9b0..0f37286f2c 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -33,6 +33,7 @@ # include #endif #if USE_CODEC_PARSERS +# include #endif /* Set to 1 to check display cache works (shared VA display) */ @@ -160,6 +161,9 @@ main(int argc, char *argv[]) else { #if USE_CODEC_PARSERS switch (gst_vaapi_profile_get_codec(info.profile)) { + case GST_VAAPI_CODEC_MPEG2: + decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); + break; default: decoder = NULL; break; From c5902b7a8478dc6f7869782b97881a40badd9149 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Sep 2011 18:02:53 +0200 Subject: [PATCH 0556/3781] mpeg2: handle closed_gop. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 5a5d376e71..423c41f796 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -85,6 +85,8 @@ struct _GstVaapiDecoderMpeg2Private { guint profile_changed : 1; guint quant_matrix_changed : 1; guint progressive_sequence : 1; + guint closed_gop : 1; + guint broken_link : 1; }; static void @@ -304,7 +306,8 @@ decode_current_picture(GstVaapiDecoderMpeg2 *decoder) if (!gst_vaapi_decoder_decode_picture(base_decoder, picture)) status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { - if (priv->prev_picture && priv->next_picture) + if ((priv->prev_picture && priv->next_picture) || + (priv->closed_gop && priv->next_picture)) status = render_picture(decoder, picture); gst_vaapi_decoder_free_picture(base_decoder, picture); } @@ -444,8 +447,12 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } - GST_DEBUG("GOP %02u:%02u:%02u:%02u", - gop.hour, gop.minute, gop.second, gop.frame); + priv->closed_gop = gop.closed_gop; + priv->broken_link = gop.broken_link; + + GST_DEBUG("GOP %02u:%02u:%02u:%02u (closed_gop %d, broken_link %d)", + gop.hour, gop.minute, gop.second, gop.frame, + priv->closed_gop, priv->broken_link); pts = GST_SECOND * (gop.hour * 3600 + gop.minute * 60 + gop.second); pts += gst_util_uint64_scale(gop.frame, GST_SECOND * priv->fps_d, priv->fps_n); @@ -899,6 +906,8 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv->profile_changed = FALSE; priv->quant_matrix_changed = FALSE; priv->progressive_sequence = FALSE; + priv->closed_gop = FALSE; + priv->broken_link = FALSE; } /** From ce413eb83d15e6fe10bf3d1448e57d2014333223 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 Sep 2011 18:20:00 +0200 Subject: [PATCH 0557/3781] mpeg2: ignore system start codes (PES headers). --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 423c41f796..e078697702 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -773,6 +773,11 @@ decode_chunks(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer, GList *chunks) ); break; } + else if (tos->type >= 0xb9 && tos->type <= 0xff) { + // Ignore system start codes (PES headers) + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } GST_DEBUG("unsupported start code (0x%02x)", tos->type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; From ab8f602957deb4e1f967c6142864d1431bc1b01a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Sep 2011 18:11:57 +0200 Subject: [PATCH 0558/3781] mpeg2: fix packets spanning over two buffers. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index e078697702..91807db086 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -703,6 +703,7 @@ decode_chunks(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer, GList *chunks) GstMpegVideoTypeOffsetSize *tos; GstVaapiDecoderStatus status; guchar * const buf = GST_BUFFER_DATA(buffer); + const guint buf_size = GST_BUFFER_SIZE(buffer); guchar *data; guint data_size, ofs, pos = 0; GList *l; @@ -712,16 +713,8 @@ decode_chunks(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer, GList *chunks) tos = l->data; data = buf + tos->offset; data_size = tos->size; - if (tos->size < 0) { - if (tos->offset < 4) - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - priv->sub_buffer = gst_buffer_create_sub( - buffer, - tos->offset - 4, - GST_BUFFER_SIZE(buffer) - (tos->offset - 4) - ); + if (tos->size < 0) break; - } ofs = tos->offset - pos + tos->size; gst_vaapi_tsb_pop(priv->tsb, ofs); @@ -785,6 +778,9 @@ decode_chunks(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer, GList *chunks) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) break; } + + if (status == GST_VAAPI_DECODER_STATUS_SUCCESS && pos < buf_size) + priv->sub_buffer = gst_buffer_create_sub(buffer, pos, buf_size - pos); return status; } From 697a2804e129380f7c3f4132b7be2f3c67068258 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 18 Nov 2011 15:06:07 +0200 Subject: [PATCH 0559/3781] mpeg2: replace GstVaapiTSB API with GstAdapter (gst-plugins-base >= 0.10.24). Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 27 +++++++++++----------- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h | 1 + 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 91807db086..580ad9e71d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -32,7 +32,6 @@ #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" -#include "gstvaapiutils_tsb.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -67,7 +66,7 @@ struct _GstVaapiDecoderMpeg2Private { GstVaapiPicture *current_picture; GstVaapiPicture *next_picture; GstVaapiPicture *prev_picture; - GstVaapiTSB *tsb; + GstAdapter *adapter; GstBuffer *sub_buffer; guint mb_y; guint mb_height; @@ -115,9 +114,10 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) priv->sub_buffer = NULL; } - if (priv->tsb) { - gst_vaapi_tsb_destroy(priv->tsb); - priv->tsb = NULL; + if (priv->adapter) { + gst_adapter_clear(priv->adapter); + g_object_unref(priv->adapter); + priv->adapter = NULL; } } @@ -128,9 +128,9 @@ gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) gst_vaapi_decoder_mpeg2_close(decoder); - priv->tsb = gst_vaapi_tsb_new(); - if (!priv->tsb) - return FALSE; + priv->adapter = gst_adapter_new(); + if (!priv->adapter) + return FALSE; return TRUE; } @@ -332,7 +332,7 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) priv->fps_d = seq_hdr->fps_d; gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); - priv->seq_pts = gst_vaapi_tsb_get_timestamp(priv->tsb); + priv->seq_pts = gst_adapter_prev_timestamp(priv->adapter, NULL); priv->width = seq_hdr->width; priv->height = seq_hdr->height; @@ -717,7 +717,8 @@ decode_chunks(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer, GList *chunks) break; ofs = tos->offset - pos + tos->size; - gst_vaapi_tsb_pop(priv->tsb, ofs); + if (gst_adapter_available(priv->adapter) >= ofs) + gst_adapter_flush(priv->adapter, ofs); pos += ofs; switch (tos->type) { @@ -798,8 +799,8 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) if (!buf && buf_size == 0) return decode_sequence_end(decoder); - gst_vaapi_tsb_push(priv->tsb, buffer); - + gst_buffer_ref(buffer); + gst_adapter_push(priv->adapter, buffer); if (priv->sub_buffer) { buffer = gst_buffer_merge(priv->sub_buffer, buffer); if (!buffer) @@ -889,7 +890,7 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv->current_picture = NULL; priv->next_picture = NULL; priv->prev_picture = NULL; - priv->tsb = NULL; + priv->adapter = NULL; priv->sub_buffer = NULL; priv->mb_y = 0; priv->mb_height = 0; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h index 84a9a189e0..98368331e0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h @@ -23,6 +23,7 @@ #define GST_VAAPI_DECODER_MPEG2_H #include +#include G_BEGIN_DECLS From a591dc3b7245457916ee0e83f4ca842b871bc96f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 6 Jan 2012 16:44:09 +0100 Subject: [PATCH 0560/3781] mpeg2: fix quantisation matrix construction. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 45 +++++++--------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 580ad9e71d..d2963b9579 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -242,43 +242,24 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) } iq_matrix->load_intra_quantiser_matrix = intra_quant_matrix != NULL; - if (intra_quant_matrix) { - iq_matrix->load_intra_quantiser_matrix = 1; + if (intra_quant_matrix) copy_quant_matrix(iq_matrix->intra_quantiser_matrix, intra_quant_matrix); - } - iq_matrix->load_intra_quantiser_matrix = 1; - copy_quant_matrix(iq_matrix->intra_quantiser_matrix, - priv->seq_hdr.intra_quantizer_matrix); + iq_matrix->load_non_intra_quantiser_matrix = non_intra_quant_matrix != NULL; + if (non_intra_quant_matrix) + copy_quant_matrix(iq_matrix->non_intra_quantiser_matrix, + non_intra_quant_matrix); - iq_matrix->load_non_intra_quantiser_matrix = 1; - copy_quant_matrix(iq_matrix->non_intra_quantiser_matrix, - priv->seq_hdr.non_intra_quantizer_matrix); + iq_matrix->load_chroma_intra_quantiser_matrix = chroma_intra_quant_matrix != NULL; + if (chroma_intra_quant_matrix) + copy_quant_matrix(iq_matrix->chroma_intra_quantiser_matrix, + chroma_intra_quant_matrix); - iq_matrix->load_chroma_intra_quantiser_matrix = 0; - iq_matrix->load_chroma_non_intra_quantiser_matrix = 0; - if (priv->has_quant_matrix_ext) { - if (priv->quant_matrix_ext.load_intra_quantiser_matrix) - copy_quant_matrix(iq_matrix->intra_quantiser_matrix, - priv->quant_matrix_ext.intra_quantiser_matrix); - - if (priv->quant_matrix_ext.load_non_intra_quantiser_matrix) - copy_quant_matrix(iq_matrix->non_intra_quantiser_matrix, - priv->quant_matrix_ext.non_intra_quantiser_matrix); - - if (priv->quant_matrix_ext.load_chroma_intra_quantiser_matrix) { - iq_matrix->load_chroma_intra_quantiser_matrix = 1; - copy_quant_matrix(iq_matrix->chroma_intra_quantiser_matrix, - priv->quant_matrix_ext.chroma_intra_quantiser_matrix); - } - - if (priv->quant_matrix_ext.load_chroma_non_intra_quantiser_matrix) { - iq_matrix->load_chroma_non_intra_quantiser_matrix = 1; - copy_quant_matrix(iq_matrix->chroma_non_intra_quantiser_matrix, - priv->quant_matrix_ext.chroma_non_intra_quantiser_matrix); - } - } + iq_matrix->load_chroma_non_intra_quantiser_matrix = chroma_non_intra_quant_matrix != NULL; + if (chroma_non_intra_quant_matrix) + copy_quant_matrix(iq_matrix->chroma_non_intra_quantiser_matrix, + chroma_non_intra_quant_matrix); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 27fa5903efe2e1951cd90c37a5e13191ae418c4f Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Mon, 9 Jan 2012 17:37:34 +0100 Subject: [PATCH 0561/3781] mpeg2: fix first field detection. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index d2963b9579..e70c6357a0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -440,6 +440,8 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) priv->gop_pts = pts; if (!priv->pts_diff) priv->pts_diff = priv->seq_pts - priv->gop_pts; + + priv->is_first_field = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -500,10 +502,6 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) } priv->mb_y = 0; - if (pic_hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_I) - priv->is_first_field = TRUE; - else - priv->is_first_field ^= 1; /* Update presentation time */ pts = priv->gop_pts; @@ -618,8 +616,13 @@ decode_slice( GST_DEBUG("slice %d @ %p, %u bytes)", slice_no, buf, buf_size); - if (picture->slices->len == 0 && !fill_picture(decoder, picture)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + if (picture->slices->len == 0) { + if (!fill_picture(decoder, picture)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + if (!priv->pic_ext.progressive_frame) + priv->is_first_field ^= 1; + } priv->mb_y = slice_no; From b865d4a740f7a0def4a6e2cad519b8a41ac79f46 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 30 Sep 2011 13:40:11 +0200 Subject: [PATCH 0562/3781] Add initial VC-1 decoder. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 947 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_vc1.h | 87 +++ gst/vaapi/gstvaapidecode.c | 3 + tests/test-decode.c | 4 + 5 files changed, 1043 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_vc1.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_vc1.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 802394436a..50ca49aa26 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -145,9 +145,11 @@ endif if USE_CODEC_PARSERS libgstvaapi_source_c += \ gstvaapidecoder_mpeg2.c \ + gstvaapidecoder_vc1.c \ $(NULL) libgstvaapi_source_h += \ gstvaapidecoder_mpeg2.h \ + gstvaapidecoder_vc1.h \ $(NULL) libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS) libgstvaapi_libs += $(GST_CODEC_PARSERS_LIBS) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c new file mode 100644 index 0000000000..ad1e956453 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -0,0 +1,947 @@ +/* + * gstvaapidecoder_vc1.c - VC-1 decoder + * + * Copyright (C) 2011 Intel Corporation + * + * 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_vc1 + * @short_description: VC-1 decoder + */ + +#include "config.h" +#include +#include +#include "gstvaapidecoder_vc1.h" +#include "gstvaapidecoder_priv.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapiobject_priv.h" +#include "gstvaapiutils_tsb.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiDecoderVC1, + gst_vaapi_decoder_vc1, + GST_VAAPI_TYPE_DECODER); + +#define GST_VAAPI_DECODER_VC1_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DECODER_VC1, \ + GstVaapiDecoderVC1Private)) + +struct _GstVaapiDecoderVC1Private { + GstVaapiProfile profile; + guint width; + guint height; + guint fps_n; + guint fps_d; + GstVC1SeqHdr seq_hdr; + GstVC1EntryPointHdr entrypoint_hdr; + GstVC1FrameHdr frame_hdr; + GstVaapiPicture *current_picture; + GstVaapiPicture *next_picture; + GstVaapiPicture *prev_picture; + GstVaapiTSB *tsb; + GstBuffer *sub_buffer; + guint is_constructed : 1; + guint is_opened : 1; + guint is_first_field : 1; + guint has_entrypoint : 1; + guint size_changed : 1; + guint profile_changed : 1; + guint closed_entry : 1; + guint broken_link : 1; +}; + +static GstVaapiDecoderStatus +get_status(GstVC1ParserResult result) +{ + GstVaapiDecoderStatus status; + + switch (result) { + case GST_VC1_PARSER_OK: + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + case GST_VC1_PARSER_NO_BDU_END: + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + break; + case GST_VC1_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_vc1_close(GstVaapiDecoderVC1 *decoder) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderVC1Private * const priv = decoder->priv; + + if (priv->current_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->current_picture); + priv->current_picture = NULL; + } + + if (priv->next_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->next_picture); + priv->next_picture = NULL; + } + + if (priv->prev_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); + priv->prev_picture = NULL; + } + + if (priv->sub_buffer) { + gst_buffer_unref(priv->sub_buffer); + priv->sub_buffer = NULL; + } + + if (priv->tsb) { + gst_vaapi_tsb_destroy(priv->tsb); + priv->tsb = NULL; + } +} + +static gboolean +gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + + gst_vaapi_decoder_vc1_close(decoder); + + priv->tsb = gst_vaapi_tsb_new(); + if (!priv->tsb) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_decoder_vc1_destroy(GstVaapiDecoderVC1 *decoder) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + + gst_vaapi_decoder_vc1_close(decoder); +} + +static gboolean +gst_vaapi_decoder_vc1_create(GstVaapiDecoderVC1 *decoder) +{ + if (!GST_VAAPI_DECODER_CODEC(decoder)) + return FALSE; + return TRUE; +} + +static GstVaapiDecoderStatus +ensure_context(GstVaapiDecoderVC1 *decoder) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + 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_VC1_SIMPLE) + profiles[n_profiles++] = GST_VAAPI_PROFILE_VC1_MAIN; + + 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) { + reset_context = gst_vaapi_decoder_ensure_context( + GST_VAAPI_DECODER(decoder), + priv->profile, + entrypoint, + priv->width, priv->height + ); + if (!reset_context) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static inline GstVaapiDecoderStatus +render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + + if (!gst_vaapi_decoder_push_surface(base_decoder, + picture->surface, + picture->pts)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_current_picture(GstVaapiDecoderVC1 *decoder) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiPicture * const picture = priv->current_picture; + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (picture) { + if (!gst_vaapi_decoder_decode_picture(base_decoder, picture)) + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { + if (priv->prev_picture && priv->next_picture) + status = render_picture(decoder, picture); + gst_vaapi_decoder_free_picture(base_decoder, picture); + } + priv->current_picture = NULL; + } + return status; +} + +static GstVaapiDecoderStatus +decode_sequence(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; + GstVC1ParserResult result; + GstVaapiProfile profile; + guint width, height; + + result = gst_vc1_parse_sequence_header(buf, buf_size, seq_hdr); + if (result != GST_VC1_PARSER_OK) { + GST_DEBUG("failed to parse sequence layer"); + return get_status(result); + } + + priv->has_entrypoint = FALSE; + + /* Validate profile */ + switch (seq_hdr->profile) { + case GST_VC1_PROFILE_SIMPLE: + case GST_VC1_PROFILE_MAIN: + case GST_VC1_PROFILE_ADVANCED: + break; + default: + GST_DEBUG("unsupported profile %d", seq_hdr->profile); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + +#if 0 + priv->fps_n = seq_hdr->fps_n; + priv->fps_d = seq_hdr->fps_d; + gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); +#endif + + switch (seq_hdr->profile) { + case GST_VC1_PROFILE_SIMPLE: + case GST_VC1_PROFILE_MAIN: + width = seq_hdr->struct_c.coded_width; + height = seq_hdr->struct_c.coded_height; + break; + case GST_VC1_PROFILE_ADVANCED: + width = seq_hdr->advanced.max_coded_width; + height = seq_hdr->advanced.max_coded_height; + break; + default: + g_assert(0 && "XXX: we already validated the profile above"); + break; + } + + if (priv->width != width) { + priv->width = width; + priv->size_changed = TRUE; + } + + if (priv->height != height) { + priv->height = height; + priv->size_changed = TRUE; + } + + switch (seq_hdr->profile) { + case GST_VC1_PROFILE_SIMPLE: + profile = GST_VAAPI_PROFILE_VC1_SIMPLE; + break; + case GST_VC1_PROFILE_MAIN: + profile = GST_VAAPI_PROFILE_VC1_MAIN; + break; + case GST_VC1_PROFILE_ADVANCED: + profile = GST_VAAPI_PROFILE_VC1_ADVANCED; + break; + default: + g_assert(0 && "XXX: we already validated the profile above"); + break; + } + if (priv->profile != profile) { + priv->profile = profile; + priv->profile_changed = TRUE; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence_end(GstVaapiDecoderVC1 *decoder) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + + if (priv->current_picture) { + status = decode_current_picture(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + status = render_picture(decoder, priv->current_picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + + if (priv->next_picture) { + status = render_picture(decoder, priv->next_picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; +} + +static GstVaapiDecoderStatus +decode_entry_point(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; + GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr; + GstVC1ParserResult result; + + result = gst_vc1_parse_entry_point_header( + buf, buf_size, + entrypoint_hdr, + seq_hdr + ); + if (result != GST_VC1_PARSER_OK) { + GST_DEBUG("failed to parse entrypoint layer"); + return get_status(result); + } + + if (entrypoint_hdr->coded_size_flag) { + priv->width = entrypoint_hdr->coded_width; + priv->height = entrypoint_hdr->coded_height; + priv->size_changed = TRUE; + } + + priv->has_entrypoint = TRUE; + priv->closed_entry = entrypoint_hdr->closed_entry; + priv->broken_link = entrypoint_hdr->broken_link; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static guint +get_PTYPE(GstVC1FrameHdr *frame_hdr) +{ + switch (frame_hdr->ptype) { + case GST_VC1_PICTURE_TYPE_I: return 0; + case GST_VC1_PICTURE_TYPE_P: return 1; + case GST_VC1_PICTURE_TYPE_B: return 2; + case GST_VC1_PICTURE_TYPE_BI: return 3; + } + return 4; /* skipped P-frame */ +} + +static inline int +has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; + GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + guint mvmode, mvmode2; + + if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { + GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; + if (pic->mvtypemb) + return 0; + mvmode = pic->mvmode; + mvmode2 = pic->mvmode2; + } + else { + GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple; + if (pic->mvtypemb) + return 0; + mvmode = pic->mvmode; + mvmode2 = pic->mvmode2; + } + return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P && + (mvmode == GST_VC1_MVMODE_MIXED_MV || + (mvmode == GST_VC1_MVMODE_INTENSITY_COMP && + mvmode2 == GST_VC1_MVMODE_MIXED_MV))); +} + +static inline int +has_SKIPMB_bitplane(GstVaapiDecoderVC1 *decoder) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; + GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + + if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { + GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; + if (pic->skipmb) + return 0; + } + else { + GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple; + if (pic->skipmb) + return 0; + } + return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P || + frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B); +} + +static inline int +has_DIRECTMB_bitplane(GstVaapiDecoderVC1 *decoder) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; + GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + + if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { + GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; + if (pic->directmb) + return 0; + } + else { + GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple; + if (pic->directmb) + return 0; + } + return frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B; +} + +static inline int +has_ACPRED_bitplane(GstVaapiDecoderVC1 *decoder) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; + GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; + + if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED) + return 0; + if (pic->acpred) + return 0; + return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I || + frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI); +} + +static inline int +has_OVERFLAGS_bitplane(GstVaapiDecoderVC1 *decoder) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; + GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr; + GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; + + if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED) + return 0; + if (pic->overflags) + return 0; + return ((frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I || + frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) && + (entrypoint_hdr->overlap && frame_hdr->pquant <= 8) && + pic->condover == GST_VC1_CONDOVER_SELECT); +} + +static gboolean +fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + VAPictureParameterBufferVC1 * const pic_param = picture->param; + GstVC1SeqStructC * const structc = &priv->seq_hdr.struct_c; + GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple; + + /* Fill in VAPictureParameterBufferVC1 (simple/main profile bits) */ + pic_param->sequence_fields.bits.finterpflag = structc->finterpflag; + pic_param->sequence_fields.bits.multires = structc->multires; + pic_param->sequence_fields.bits.overlap = structc->overlap; + pic_param->sequence_fields.bits.syncmarker = structc->syncmarker; + pic_param->sequence_fields.bits.rangered = structc->rangered; + pic_param->sequence_fields.bits.max_b_frames = structc->maxbframes; + pic_param->conditional_overlap_flag = 0; /* advanced profile only */ + pic_param->fast_uvmc_flag = structc->fastuvmc; + pic_param->b_picture_fraction = pic->bfraction; + pic_param->cbp_table = pic->cbptab; + pic_param->mb_mode_table = 0; /* XXX: interlaced frame */ + pic_param->range_reduction_frame = pic->rangeredfrm; + pic_param->rounding_control = 0; /* advanced profile only */ + pic_param->post_processing = 0; /* advanced profile only */ + pic_param->picture_resolution_index = pic->respic; + pic_param->luma_scale = pic->lumscale; + pic_param->luma_shift = pic->lumshift; + pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb; + pic_param->raw_coding.flags.direct_mb = pic->directmb; + pic_param->raw_coding.flags.skip_mb = pic->skipmb; + pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder); + pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder); + pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder); + pic_param->mv_fields.bits.mv_mode = pic->mvmode; + pic_param->mv_fields.bits.mv_mode2 = pic->mvmode2; + pic_param->mv_fields.bits.mv_table = pic->mvtab; + pic_param->mv_fields.bits.extended_mv_flag = structc->extended_mv; + pic_param->mv_fields.bits.extended_mv_range = pic->mvrange; + pic_param->transform_fields.bits.variable_sized_transform_flag = structc->vstransform; + pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf; + pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm; + pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2; + return TRUE; +} + +static gboolean +fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + VAPictureParameterBufferVC1 * const pic_param = picture->param; + GstVC1AdvancedSeqHdr * const adv_hdr = &priv->seq_hdr.advanced; + GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr; + GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; + + if (!priv->has_entrypoint) + return FALSE; + + /* Fill in VAPictureParameterBufferVC1 (advanced profile bits) */ + pic_param->sequence_fields.bits.pulldown = adv_hdr->pulldown; + pic_param->sequence_fields.bits.interlace = adv_hdr->interlace; + pic_param->sequence_fields.bits.tfcntrflag = adv_hdr->tfcntrflag; + pic_param->sequence_fields.bits.finterpflag = adv_hdr->finterpflag; + pic_param->sequence_fields.bits.psf = adv_hdr->psf; + pic_param->sequence_fields.bits.overlap = entrypoint_hdr->overlap; + pic_param->entrypoint_fields.bits.broken_link = entrypoint_hdr->broken_link; + pic_param->entrypoint_fields.bits.closed_entry = entrypoint_hdr->closed_entry; + pic_param->entrypoint_fields.bits.panscan_flag = entrypoint_hdr->panscan_flag; + pic_param->entrypoint_fields.bits.loopfilter = entrypoint_hdr->loopfilter; + pic_param->conditional_overlap_flag = pic->condover; + pic_param->fast_uvmc_flag = entrypoint_hdr->fastuvmc; + pic_param->range_mapping_fields.bits.luma_flag = entrypoint_hdr->range_mapy_flag; + pic_param->range_mapping_fields.bits.luma = entrypoint_hdr->range_mapy; + pic_param->range_mapping_fields.bits.chroma_flag = entrypoint_hdr->range_mapuv_flag; + pic_param->range_mapping_fields.bits.chroma = entrypoint_hdr->range_mapuv; + pic_param->b_picture_fraction = pic->bfraction; + pic_param->cbp_table = pic->cbptab; + pic_param->mb_mode_table = 0; /* XXX: interlaced frame */ + pic_param->range_reduction_frame = 0; /* simple/main profile only */ + pic_param->rounding_control = pic->rndctrl; + pic_param->post_processing = pic->postproc; + pic_param->picture_resolution_index = 0; /* simple/main profile only */ + pic_param->luma_scale = pic->lumscale; + pic_param->luma_shift = pic->lumshift; + pic_param->picture_fields.bits.frame_coding_mode = pic->fcm; + pic_param->picture_fields.bits.top_field_first = pic->tff; + pic_param->picture_fields.bits.is_first_field = pic->fcm == 0; /* XXX: interlaced frame */ + pic_param->picture_fields.bits.intensity_compensation = pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP; + pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb; + pic_param->raw_coding.flags.direct_mb = pic->directmb; + pic_param->raw_coding.flags.skip_mb = pic->skipmb; + pic_param->raw_coding.flags.ac_pred = pic->acpred; + pic_param->raw_coding.flags.overflags = pic->overflags; + pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder); + pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder); + pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder); + pic_param->bitplane_present.flags.bp_ac_pred = has_ACPRED_bitplane(decoder); + pic_param->bitplane_present.flags.bp_overflags = has_OVERFLAGS_bitplane(decoder); + pic_param->reference_fields.bits.reference_distance_flag = entrypoint_hdr->refdist_flag; + pic_param->mv_fields.bits.mv_mode = pic->mvmode; + pic_param->mv_fields.bits.mv_mode2 = pic->mvmode2; + pic_param->mv_fields.bits.mv_table = pic->mvtab; + pic_param->mv_fields.bits.extended_mv_flag = entrypoint_hdr->extended_mv; + pic_param->mv_fields.bits.extended_mv_range = pic->mvrange; + pic_param->mv_fields.bits.extended_dmv_flag = entrypoint_hdr->extended_dmv; + pic_param->pic_quantizer_fields.bits.dquant = entrypoint_hdr->dquant; + pic_param->pic_quantizer_fields.bits.quantizer = entrypoint_hdr->quantizer; + pic_param->transform_fields.bits.variable_sized_transform_flag = entrypoint_hdr->vstransform; + pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf; + pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm; + pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2; + return TRUE; +} + +static gboolean +fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + VAPictureParameterBufferVC1 * const pic_param = picture->param; + GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; + GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + + /* Fill in VAPictureParameterBufferVC1 (common fields) */ + pic_param->forward_reference_picture = VA_INVALID_ID; + pic_param->backward_reference_picture = VA_INVALID_ID; + pic_param->inloop_decoded_picture = VA_INVALID_ID; + pic_param->sequence_fields.value = 0; +#if VA_CHECK_VERSION(0,32,0) + pic_param->sequence_fields.bits.profile = seq_hdr->profile; +#endif + pic_param->coded_width = priv->width; + pic_param->coded_height = priv->height; + pic_param->entrypoint_fields.value = 0; + pic_param->range_mapping_fields.value = 0; + pic_param->picture_fields.value = 0; + pic_param->picture_fields.bits.picture_type = get_PTYPE(frame_hdr); + pic_param->raw_coding.value = 0; + pic_param->bitplane_present.value = 0; + pic_param->reference_fields.value = 0; + pic_param->mv_fields.value = 0; + pic_param->pic_quantizer_fields.value = 0; + pic_param->pic_quantizer_fields.bits.half_qp = frame_hdr->halfqp; + pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = frame_hdr->pquant; + pic_param->pic_quantizer_fields.bits.pic_quantizer_type = frame_hdr->pquantizer; + pic_param->pic_quantizer_fields.bits.dq_frame = frame_hdr->vopdquant.dquantfrm; + pic_param->pic_quantizer_fields.bits.dq_profile = frame_hdr->vopdquant.dqprofile; + pic_param->pic_quantizer_fields.bits.dq_sb_edge = frame_hdr->vopdquant.dqsbedge; + pic_param->pic_quantizer_fields.bits.dq_db_edge = frame_hdr->vopdquant.dqsbedge; + pic_param->pic_quantizer_fields.bits.dq_binary_level = frame_hdr->vopdquant.dqbilevel; + pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = frame_hdr->vopdquant.altpquant; + pic_param->transform_fields.value = 0; + pic_param->transform_fields.bits.transform_ac_codingset_idx1 = frame_hdr->transacfrm; + pic_param->transform_fields.bits.intra_transform_dc_table = frame_hdr->transdctab; + + if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { + if (!fill_picture_advanced(decoder, picture)) + return FALSE; + } + else { + if (!fill_picture_structc(decoder, picture)) + return FALSE; + } + + switch (picture->type) { + case GST_VAAPI_PICTURE_TYPE_B: + if (priv->next_picture) + pic_param->backward_reference_picture = priv->next_picture->surface_id; + // fall-through + case GST_VAAPI_PICTURE_TYPE_P: + if (priv->prev_picture) + pic_param->forward_reference_picture = priv->prev_picture->surface_id; + break; + default: + break; + } + return TRUE; +} + +static GstVaapiDecoderStatus +decode_frame(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; + GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + GstVC1ParserResult result; + GstVaapiPicture *picture; + GstVaapiSlice *slice; + GstVaapiDecoderStatus status; + VASliceParameterBufferVC1 *slice_param; + + status = ensure_context(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_DEBUG("failed to reset context"); + return status; + } + + if (priv->current_picture) { + status = decode_current_picture(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + + priv->current_picture = gst_vaapi_decoder_new_picture(base_decoder); + if (!priv->current_picture) { + GST_DEBUG("failed to allocate picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + picture = priv->current_picture; + + memset(frame_hdr, 0, sizeof(*frame_hdr)); + result = gst_vc1_parse_frame_header(buf, buf_size, frame_hdr, seq_hdr, NULL); + if (result != GST_VC1_PARSER_OK) { + GST_DEBUG("failed to parse frame layer"); + return get_status(result); + } + + switch (frame_hdr->ptype) { + case GST_VC1_PICTURE_TYPE_I: + picture->type = GST_VAAPI_PICTURE_TYPE_I; + picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + break; + case GST_VC1_PICTURE_TYPE_SKIPPED: + picture->flags |= GST_VAAPI_PICTURE_SKIPPED; + // fall-through + case GST_VC1_PICTURE_TYPE_P: + picture->type = GST_VAAPI_PICTURE_TYPE_P; + picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + break; + case GST_VC1_PICTURE_TYPE_B: + picture->type = GST_VAAPI_PICTURE_TYPE_B; + break; + case GST_VC1_PICTURE_TYPE_BI: + picture->type = GST_VAAPI_PICTURE_TYPE_BI; + break; + default: + GST_DEBUG("unsupported picture type %d", frame_hdr->ptype); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + /* Update reference pictures */ + if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { + if (priv->prev_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); + priv->prev_picture = NULL; + } + if (priv->next_picture) { + priv->prev_picture = priv->next_picture; + priv->next_picture = NULL; + status = render_picture(decoder, priv->prev_picture); + } + priv->next_picture = picture; + } + + if (!fill_picture(decoder, picture)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + slice = gst_vaapi_decoder_new_slice(base_decoder, picture, buf, buf_size); + if (!slice) { + GST_DEBUG("failed to allocate slice"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + /* Fill in VASliceParameterBufferVC1 */ + slice_param = slice->param; + slice_param->macroblock_offset = frame_hdr->header_size; + slice_param->slice_vertical_position = 0; + + /* Decode picture right away, we got the full frame */ + return decode_current_picture(decoder); +} + +static GstVaapiDecoderStatus +decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + GstVC1ParserResult result; + GstVC1BDU bdu; + guchar *buf; + guint buf_size, bdu_size, ofs; + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + if (!buf && buf_size == 0) + return decode_sequence_end(decoder); + + gst_vaapi_tsb_push(priv->tsb, buffer); + + if (priv->sub_buffer) { + buffer = gst_buffer_merge(priv->sub_buffer, buffer); + if (!buffer) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + gst_buffer_unref(priv->sub_buffer); + priv->sub_buffer = NULL; + } + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + ofs = 0; + do { + result = gst_vc1_identify_next_bdu( + buf + ofs, + buf_size - ofs, + &bdu + ); + status = get_status(result); + + if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) { + priv->sub_buffer = gst_buffer_create_sub(buffer, ofs, buf_size - ofs); + break; + } + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + break; + + ofs += bdu.offset; + switch (bdu.type) { + case GST_VC1_SEQUENCE: + status = decode_sequence(decoder, buf + ofs, bdu.size); + break; + case GST_VC1_ENTRYPOINT: + status = decode_entry_point(decoder, buf + ofs, bdu.size); + break; + case GST_VC1_FRAME: + status = decode_frame(decoder, buf + ofs, bdu.size); + break; + case GST_VC1_SLICE: + GST_DEBUG("decode slice"); + break; + case GST_VC1_END_OF_SEQ: + status = decode_sequence_end(decoder); + break; + default: + GST_DEBUG("unsupported BDU type %d", bdu.type); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + ofs += bdu.size; + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); + return status; +} + +GstVaapiDecoderStatus +gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base, GstBuffer *buffer) +{ + GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base); + GstVaapiDecoderVC1Private * const priv = decoder->priv; + + g_return_val_if_fail(priv->is_constructed, + GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); + + if (!priv->is_opened) { + priv->is_opened = gst_vaapi_decoder_vc1_open(decoder, buffer); + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + } + return decode_buffer(decoder, buffer); +} + +static void +gst_vaapi_decoder_vc1_finalize(GObject *object) +{ + GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object); + + gst_vaapi_decoder_vc1_destroy(decoder); + + G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class)->finalize(object); +} + +static void +gst_vaapi_decoder_vc1_constructed(GObject *object) +{ + GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object); + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GObjectClass *parent_class; + + parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); + + priv->is_constructed = gst_vaapi_decoder_vc1_create(decoder); +} + +static void +gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiDecoderVC1Private)); + + object_class->finalize = gst_vaapi_decoder_vc1_finalize; + object_class->constructed = gst_vaapi_decoder_vc1_constructed; + + decoder_class->decode = gst_vaapi_decoder_vc1_decode; +} + +static void +gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder) +{ + GstVaapiDecoderVC1Private *priv; + + priv = GST_VAAPI_DECODER_VC1_GET_PRIVATE(decoder); + decoder->priv = priv; + priv->width = 0; + priv->height = 0; + priv->fps_n = 0; + priv->fps_d = 0; + priv->profile = (GstVaapiProfile)0; + priv->current_picture = NULL; + priv->next_picture = NULL; + priv->prev_picture = NULL; + priv->tsb = NULL; + priv->sub_buffer = NULL; + priv->is_constructed = FALSE; + priv->is_opened = FALSE; + priv->is_first_field = FALSE; + priv->has_entrypoint = FALSE; + priv->size_changed = FALSE; + priv->profile_changed = FALSE; + priv->closed_entry = FALSE; + priv->broken_link = FALSE; +} + +/** + * gst_vaapi_decoder_vc1_new: + * @display: a #GstVaapiDisplay + * @caps: a #GstCaps holding codec information + * + * Creates a new #GstVaapiDecoder for VC-1 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_vc1_new(GstVaapiDisplay *display, GstCaps *caps) +{ + GstVaapiDecoderVC1 *decoder; + + static const GstVaapiCodecInfo codec_info = { + .pic_size = sizeof(GstVaapiPicture), + .slice_size = sizeof(GstVaapiSlice), + .pic_param_size = sizeof(VAPictureParameterBufferVC1), + .slice_param_size = sizeof(VASliceParameterBufferVC1), + .iq_matrix_size = 0, + }; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + decoder = g_object_new( + GST_VAAPI_TYPE_DECODER_VC1, + "display", display, + "caps", caps, + "codec-info", &codec_info, + NULL + ); + if (!decoder->priv->is_constructed) { + g_object_unref(decoder); + return NULL; + } + return GST_VAAPI_DECODER_CAST(decoder); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h new file mode 100644 index 0000000000..b877227283 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h @@ -0,0 +1,87 @@ +/* + * gstvaapidecoder_vc1.h - VC-1 decoder + * + * Copyright (C) 2011 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DECODER_VC1 \ + (gst_vaapi_decoder_vc1_get_type()) + +#define GST_VAAPI_DECODER_VC1(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DECODER_VC1, \ + GstVaapiDecoderVC1)) + +#define GST_VAAPI_DECODER_VC1_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DECODER_VC1, \ + GstVaapiDecoderVC1Class)) + +#define GST_VAAPI_IS_DECODER_VC1(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_VC1)) + +#define GST_VAAPI_IS_DECODER_VC1_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_VC1)) + +#define GST_VAAPI_DECODER_VC1_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DECODER_VC1, \ + GstVaapiDecoderVC1Class)) + +typedef struct _GstVaapiDecoderVC1 GstVaapiDecoderVC1; +typedef struct _GstVaapiDecoderVC1Private GstVaapiDecoderVC1Private; +typedef struct _GstVaapiDecoderVC1Class GstVaapiDecoderVC1Class; + +/** + * GstVaapiDecoderVC1: + * + * A decoder based on VC1. + */ +struct _GstVaapiDecoderVC1 { + /*< private >*/ + GstVaapiDecoder parent_instance; + + GstVaapiDecoderVC1Private *priv; +}; + +/** + * GstVaapiDecoderVC1Class: + * + * A decoder class based on VC1. + */ +struct _GstVaapiDecoderVC1Class { + /*< private >*/ + GstVaapiDecoderClass parent_class; +}; + +GType +gst_vaapi_decoder_vc1_get_type(void); + +GstVaapiDecoder * +gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps); + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_VC1_H */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 607750290c..49fa80eacc 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -51,6 +51,7 @@ #endif #if USE_CODEC_PARSERS # include +# include #endif /* Favor codecparsers-based decoders for 0.3.x series */ @@ -315,6 +316,8 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) if (version == 2) decode->decoder = gst_vaapi_decoder_mpeg2_new(dpy, caps); } + else if (gst_structure_has_name(structure, "video/x-wmv")) + decode->decoder = gst_vaapi_decoder_vc1_new(dpy, caps); #endif } if (!decode->decoder) diff --git a/tests/test-decode.c b/tests/test-decode.c index 0f37286f2c..835400be99 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -34,6 +34,7 @@ #endif #if USE_CODEC_PARSERS # include +# include #endif /* Set to 1 to check display cache works (shared VA display) */ @@ -164,6 +165,9 @@ main(int argc, char *argv[]) case GST_VAAPI_CODEC_MPEG2: decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); break; + case GST_VAAPI_CODEC_VC1: + decoder = gst_vaapi_decoder_vc1_new(display, decoder_caps); + break; default: decoder = NULL; break; From a6a1653d922cf0d841998331e02159790f32a0ed Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 30 Sep 2011 17:16:23 +0200 Subject: [PATCH 0563/3781] vc1: fix framerate calculation. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 67 +++++++++++++++++++++--- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index ad1e956453..b6fe1a0d27 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -238,9 +238,11 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; + GstVC1AdvancedSeqHdr * const adv_hdr = &seq_hdr->advanced; + GstVC1SeqStructC * const structc = &seq_hdr->struct_c; GstVC1ParserResult result; GstVaapiProfile profile; - guint width, height; + guint width, height, fps_n, fps_d; result = gst_vc1_parse_sequence_header(buf, buf_size, seq_hdr); if (result != GST_VC1_PARSER_OK) { @@ -261,11 +263,64 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } -#if 0 - priv->fps_n = seq_hdr->fps_n; - priv->fps_d = seq_hdr->fps_d; - gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); -#endif + fps_n = 0; + fps_d = 0; + switch (seq_hdr->profile) { + case GST_VC1_PROFILE_SIMPLE: + case GST_VC1_PROFILE_MAIN: + if (structc->wmvp) { + fps_n = structc->framerate; + fps_d = 1; + } + break; + case GST_VC1_PROFILE_ADVANCED: + if (adv_hdr->display_ext && adv_hdr->framerate_flag) { + if (adv_hdr->framerateind) { + // 6.1.14.4.4 - Frame Rate Explicit + fps_n = adv_hdr->framerateexp + 1; + fps_d = 32; + } + else { + // 6.1.14.4.2 - Frame Rate Numerator + static const guint frameratenr_table[] = { + [1] = 24000, + [2] = 25000, + [3] = 30000, + [4] = 50000, + [5] = 60000, + [6] = 48000, + [7] = 72000 + }; + + // 6.1.14.4.3 - Frame Rate Denominator + static const guint frameratedr_table[] = { + [1] = 1000, + [2] = 1001 + }; + + if (adv_hdr->frameratenr < 1 || adv_hdr->frameratenr > 7) { + GST_DEBUG("unsupported FRAMERATENR value"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + fps_n = frameratenr_table[adv_hdr->frameratenr]; + + if (adv_hdr->frameratedr < 1 || adv_hdr->frameratedr > 2) { + GST_DEBUG("unsupported FRAMERATEDR value"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + fps_d = frameratedr_table[adv_hdr->frameratedr]; + } + } + break; + default: + g_assert(0 && "XXX: we already validated the profile above"); + break; + } + if (fps_n && fps_d) { + priv->fps_n = fps_n; + priv->fps_d = fps_d; + gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); + } switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: From e686c440c7e5a9e72500b0e379fc1d6246be2087 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 4 Oct 2011 14:15:55 +0200 Subject: [PATCH 0564/3781] vc1: fix BFRACTION reconstruction. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 57 +++++++++++++++++++++--- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index b6fe1a0d27..a96251d9db 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -421,10 +421,11 @@ decode_entry_point(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +/* Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */ static guint -get_PTYPE(GstVC1FrameHdr *frame_hdr) +get_PTYPE(guint ptype) { - switch (frame_hdr->ptype) { + switch (ptype) { case GST_VC1_PICTURE_TYPE_I: return 0; case GST_VC1_PICTURE_TYPE_P: return 1; case GST_VC1_PICTURE_TYPE_B: return 2; @@ -433,6 +434,52 @@ get_PTYPE(GstVC1FrameHdr *frame_hdr) return 4; /* skipped P-frame */ } +/* Reconstruct bitstream BFRACTION (7.1.1.14, index into Table-40) */ +static guint +get_BFRACTION(guint bfraction) +{ + guint i; + + static const struct { + guint16 index; + guint16 value; + } + bfraction_map[] = { + { 0, GST_VC1_BFRACTION_BASIS / 2 }, + { 1, GST_VC1_BFRACTION_BASIS / 3 }, + { 2, (GST_VC1_BFRACTION_BASIS * 2) / 3 }, + { 3, GST_VC1_BFRACTION_BASIS / 4 }, + { 4, (GST_VC1_BFRACTION_BASIS * 3) / 4 }, + { 5, GST_VC1_BFRACTION_BASIS / 5 }, + { 6, (GST_VC1_BFRACTION_BASIS * 2) / 5 }, + { 7, (GST_VC1_BFRACTION_BASIS * 3) / 5 }, + { 8, (GST_VC1_BFRACTION_BASIS * 4) / 5 }, + { 9, GST_VC1_BFRACTION_BASIS / 6 }, + { 10, (GST_VC1_BFRACTION_BASIS * 5) / 6 }, + { 11, GST_VC1_BFRACTION_BASIS / 7 }, + { 12, (GST_VC1_BFRACTION_BASIS * 2) / 7 }, + { 13, (GST_VC1_BFRACTION_BASIS * 3) / 7 }, + { 14, (GST_VC1_BFRACTION_BASIS * 4) / 7 }, + { 15, (GST_VC1_BFRACTION_BASIS * 5) / 7 }, + { 16, (GST_VC1_BFRACTION_BASIS * 6) / 7 }, + { 17, GST_VC1_BFRACTION_BASIS / 8 }, + { 18, (GST_VC1_BFRACTION_BASIS * 3) / 8 }, + { 19, (GST_VC1_BFRACTION_BASIS * 5) / 8 }, + { 20, (GST_VC1_BFRACTION_BASIS * 7) / 8 }, + { 21, GST_VC1_BFRACTION_RESERVED }, + { 22, GST_VC1_BFRACTION_PTYPE_BI } + }; + + if (!bfraction) + return 0; + + for (i = 0; i < G_N_ELEMENTS(bfraction_map); i++) { + if (bfraction_map[i].value == bfraction) + return bfraction_map[i].index; + } + return 21; /* RESERVED */ +} + static inline int has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder) { @@ -555,7 +602,7 @@ fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) pic_param->sequence_fields.bits.max_b_frames = structc->maxbframes; pic_param->conditional_overlap_flag = 0; /* advanced profile only */ pic_param->fast_uvmc_flag = structc->fastuvmc; - pic_param->b_picture_fraction = pic->bfraction; + pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction); pic_param->cbp_table = pic->cbptab; pic_param->mb_mode_table = 0; /* XXX: interlaced frame */ pic_param->range_reduction_frame = pic->rangeredfrm; @@ -612,7 +659,7 @@ fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) pic_param->range_mapping_fields.bits.luma = entrypoint_hdr->range_mapy; pic_param->range_mapping_fields.bits.chroma_flag = entrypoint_hdr->range_mapuv_flag; pic_param->range_mapping_fields.bits.chroma = entrypoint_hdr->range_mapuv; - pic_param->b_picture_fraction = pic->bfraction; + pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction); pic_param->cbp_table = pic->cbptab; pic_param->mb_mode_table = 0; /* XXX: interlaced frame */ pic_param->range_reduction_frame = 0; /* simple/main profile only */ @@ -672,7 +719,7 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) pic_param->entrypoint_fields.value = 0; pic_param->range_mapping_fields.value = 0; pic_param->picture_fields.value = 0; - pic_param->picture_fields.bits.picture_type = get_PTYPE(frame_hdr); + pic_param->picture_fields.bits.picture_type = get_PTYPE(frame_hdr->ptype); pic_param->raw_coding.value = 0; pic_param->bitplane_present.value = 0; pic_param->reference_fields.value = 0; From 5aea02a66f9d174d7d57635b85cf809704cc0ae9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 4 Oct 2011 17:51:51 +0200 Subject: [PATCH 0565/3781] vc1: fix bitplanes decoding. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 59 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 11 +++ gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 82 ++++++++++++++++++++++- 3 files changed, 151 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index e1b45dfbed..adb1b1871e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -615,6 +615,9 @@ gst_vaapi_decoder_push_surface_proxy( static void destroy_iq_matrix(GstVaapiDecoder *decoder, GstVaapiIqMatrix *iq_matrix); +static void +destroy_bitplane(GstVaapiDecoder *decoder, GstVaapiBitPlane *bitplane); + static void destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice); @@ -643,6 +646,11 @@ destroy_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) picture->iq_matrix = NULL; } + if (picture->bitplane) { + destroy_bitplane(decoder, picture->bitplane); + picture->bitplane = NULL; + } + picture->surface = NULL; picture->surface_id = VA_INVALID_ID; @@ -669,6 +677,7 @@ create_picture(GstVaapiDecoder *decoder) picture->param = NULL; picture->slices = NULL; picture->iq_matrix = NULL; + picture->bitplane = NULL; picture->pts = GST_CLOCK_TIME_NONE; picture->surface = gst_vaapi_context_get_surface(priv->context); @@ -752,6 +761,50 @@ gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder) return create_iq_matrix(decoder); } +static void +destroy_bitplane(GstVaapiDecoder *decoder, GstVaapiBitPlane *bitplane) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + vaapi_destroy_buffer(priv->va_display, &bitplane->data_id); + bitplane->data = NULL; + g_slice_free(GstVaapiBitPlane, bitplane); +} + +static GstVaapiBitPlane * +create_bitplane(GstVaapiDecoder *decoder, guint size) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiBitPlane *bitplane; + + bitplane = g_slice_new(GstVaapiBitPlane); + if (!bitplane) + return NULL; + + bitplane->data_id = VA_INVALID_ID; + + bitplane->data = vaapi_create_buffer( + priv->va_display, + priv->va_context, + VABitPlaneBufferType, + size, + &bitplane->data_id + ); + if (!bitplane->data) + goto error; + return bitplane; + +error: + destroy_bitplane(decoder, bitplane); + return NULL; +} + +GstVaapiBitPlane * +gst_vaapi_decoder_new_bitplane(GstVaapiDecoder *decoder, guint size) +{ + return create_bitplane(decoder, size); +} + static void destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice) { @@ -836,6 +889,7 @@ gst_vaapi_decoder_decode_picture( { GstVaapiDecoderPrivate * const priv = decoder->priv; GstVaapiIqMatrix * const iq_matrix = picture->iq_matrix; + GstVaapiBitPlane * const bitplane = picture->bitplane; GstVaapiSlice *slice; VABufferID va_buffers[3]; guint i, n_va_buffers = 0; @@ -851,6 +905,11 @@ gst_vaapi_decoder_decode_picture( va_buffers[n_va_buffers++] = iq_matrix->param_id; } + if (bitplane) { + vaapi_unmap_buffer(priv->va_display, bitplane->data_id, (void **)&bitplane->data); + va_buffers[n_va_buffers++] = bitplane->data_id; + } + status = vaBeginPicture( priv->va_display, priv->va_context, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index d4cb9bbc19..478daa86b7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -113,6 +113,7 @@ typedef struct _GstVaapiCodecInfo GstVaapiCodecInfo; typedef struct _GstVaapiPicture GstVaapiPicture; typedef struct _GstVaapiSlice GstVaapiSlice; typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix; +typedef struct _GstVaapiBitPlane GstVaapiBitPlane; enum _GstVaapiPictureType { GST_VAAPI_PICTURE_TYPE_NONE = 0, // Undefined @@ -153,6 +154,7 @@ struct _GstVaapiPicture { void *param; GPtrArray *slices; GstVaapiIqMatrix *iq_matrix; + GstVaapiBitPlane *bitplane; GstClockTime pts; }; @@ -167,6 +169,11 @@ struct _GstVaapiIqMatrix { void *param; }; +struct _GstVaapiBitPlane { + VABufferID data_id; + guint8 *data; +}; + struct _GstVaapiDecoderPrivate { GstVaapiDisplay *display; VADisplay va_display; @@ -250,6 +257,10 @@ GstVaapiIqMatrix * gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder) attribute_hidden; +GstVaapiBitPlane * +gst_vaapi_decoder_new_bitplane(GstVaapiDecoder *decoder, guint size) + attribute_hidden; + GstVaapiSlice * gst_vaapi_decoder_new_slice( GstVaapiDecoder *decoder, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index a96251d9db..a344610021 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -54,6 +54,7 @@ struct _GstVaapiDecoderVC1Private { GstVC1SeqHdr seq_hdr; GstVC1EntryPointHdr entrypoint_hdr; GstVC1FrameHdr frame_hdr; + GstVC1BitPlanes *bitplanes; GstVaapiPicture *current_picture; GstVaapiPicture *next_picture; GstVaapiPicture *prev_picture; @@ -117,6 +118,11 @@ gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder) priv->sub_buffer = NULL; } + if (priv->bitplanes) { + gst_vc1_bitplanes_free(priv->bitplanes); + priv->bitplanes = NULL; + } + if (priv->tsb) { gst_vaapi_tsb_destroy(priv->tsb); priv->tsb = NULL; @@ -133,6 +139,10 @@ gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) priv->tsb = gst_vaapi_tsb_new(); if (!priv->tsb) return FALSE; + + priv->bitplanes = gst_vc1_bitplanes_new(); + if (!priv->bitplanes) + return FALSE; return TRUE; } @@ -584,6 +594,22 @@ has_OVERFLAGS_bitplane(GstVaapiDecoderVC1 *decoder) pic->condover == GST_VC1_CONDOVER_SELECT); } +static inline void +pack_bitplanes(GstVaapiBitPlane *bitplane, guint n, const guint8 *bitplanes[3], guint x, guint y, guint stride) +{ + const guint dst_index = n / 2; + const guint src_index = y * stride + x; + guint8 v = 0; + + if (bitplanes[0]) + v |= bitplanes[0][src_index]; + if (bitplanes[1]) + v |= bitplanes[1][src_index] << 1; + if (bitplanes[2]) + v |= bitplanes[2][src_index] << 2; + bitplane->data[dst_index] = (bitplane->data[dst_index] << 4) | v; +} + static gboolean fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) { @@ -701,6 +727,7 @@ fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) static gboolean fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) { + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderVC1Private * const priv = decoder->priv; VAPictureParameterBufferVC1 * const pic_param = picture->param; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; @@ -759,6 +786,49 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) default: break; } + + if (pic_param->bitplane_present.value) { + const guint8 *bitplanes[3]; + guint x, y, n; + + switch (picture->type) { + case GST_VAAPI_PICTURE_TYPE_P: + bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL; + bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL; + bitplanes[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ? priv->bitplanes->mvtypemb : NULL; + break; + case GST_VAAPI_PICTURE_TYPE_B: + bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL; + bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL; + bitplanes[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */ + break; + case GST_VAAPI_PICTURE_TYPE_BI: + case GST_VAAPI_PICTURE_TYPE_I: + bitplanes[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */ + bitplanes[1] = pic_param->bitplane_present.flags.bp_ac_pred ? priv->bitplanes->acpred : NULL; + bitplanes[2] = pic_param->bitplane_present.flags.bp_overflags ? priv->bitplanes->overflags : NULL; + break; + default: + bitplanes[0] = NULL; + bitplanes[1] = NULL; + bitplanes[2] = NULL; + break; + } + + picture->bitplane = gst_vaapi_decoder_new_bitplane( + base_decoder, + (seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2 + ); + if (!picture->bitplane) + return FALSE; + + n = 0; + for (y = 0; y < seq_hdr->mb_height; y++) + for (x = 0; x < seq_hdr->mb_width; x++, n++) + pack_bitplanes(picture->bitplane, n, bitplanes, x, y, seq_hdr->mb_stride); + if (n & 1) /* move last nibble to the high order */ + picture->bitplane->data[n/2] <<= 4; + } return TRUE; } @@ -794,8 +864,18 @@ decode_frame(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) } picture = priv->current_picture; + if (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, seq_hdr)) { + GST_DEBUG("failed to allocate bitplanes"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + memset(frame_hdr, 0, sizeof(*frame_hdr)); - result = gst_vc1_parse_frame_header(buf, buf_size, frame_hdr, seq_hdr, NULL); + result = gst_vc1_parse_frame_header( + buf, buf_size, + frame_hdr, + seq_hdr, + priv->bitplanes + ); if (result != GST_VC1_PARSER_OK) { GST_DEBUG("failed to parse frame layer"); return get_status(result); From 032486912f37446ab2b367f56c362e537295a509 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 5 Oct 2011 15:56:36 +0200 Subject: [PATCH 0566/3781] vc1: handle encapsulated bitstreams. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 153 ++++++++++++++++++----- 1 file changed, 119 insertions(+), 34 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index a344610021..dd7a0e9b5e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -60,6 +60,8 @@ struct _GstVaapiDecoderVC1Private { GstVaapiPicture *prev_picture; GstVaapiTSB *tsb; GstBuffer *sub_buffer; + guint8 *rbdu_buffer; + guint rbdu_buffer_size; guint is_constructed : 1; guint is_opened : 1; guint is_first_field : 1; @@ -152,6 +154,12 @@ gst_vaapi_decoder_vc1_destroy(GstVaapiDecoderVC1 *decoder) GstVaapiDecoderVC1Private * const priv = decoder->priv; gst_vaapi_decoder_vc1_close(decoder); + + if (priv->rbdu_buffer) { + g_free(priv->rbdu_buffer); + priv->rbdu_buffer = NULL; + priv->rbdu_buffer_size = 0; + } } static gboolean @@ -243,7 +251,7 @@ decode_current_picture(GstVaapiDecoderVC1 *decoder) } static GstVaapiDecoderStatus -decode_sequence(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) +decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderVC1Private * const priv = decoder->priv; @@ -254,7 +262,11 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) GstVaapiProfile profile; guint width, height, fps_n, fps_d; - result = gst_vc1_parse_sequence_header(buf, buf_size, seq_hdr); + result = gst_vc1_parse_sequence_header( + rbdu->data + rbdu->offset, + rbdu->size, + seq_hdr + ); if (result != GST_VC1_PARSER_OK) { GST_DEBUG("failed to parse sequence layer"); return get_status(result); @@ -402,7 +414,7 @@ decode_sequence_end(GstVaapiDecoderVC1 *decoder) } static GstVaapiDecoderStatus -decode_entry_point(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) +decode_entry_point(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; @@ -410,7 +422,8 @@ decode_entry_point(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) GstVC1ParserResult result; result = gst_vc1_parse_entry_point_header( - buf, buf_size, + rbdu->data + rbdu->offset, + rbdu->size, entrypoint_hdr, seq_hdr ); @@ -833,7 +846,7 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) } static GstVaapiDecoderStatus -decode_frame(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) +decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderVC1Private * const priv = decoder->priv; @@ -871,7 +884,8 @@ decode_frame(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) memset(frame_hdr, 0, sizeof(*frame_hdr)); result = gst_vc1_parse_frame_header( - buf, buf_size, + rbdu->data + rbdu->offset, + rbdu->size, frame_hdr, seq_hdr, priv->bitplanes @@ -921,7 +935,12 @@ decode_frame(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) if (!fill_picture(decoder, picture)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - slice = gst_vaapi_decoder_new_slice(base_decoder, picture, buf, buf_size); + slice = gst_vaapi_decoder_new_slice( + base_decoder, + picture, + ebdu->data + ebdu->sc_offset, + ebdu->size + ebdu->offset - ebdu->sc_offset + ); if (!slice) { GST_DEBUG("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -929,22 +948,107 @@ decode_frame(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) /* Fill in VASliceParameterBufferVC1 */ slice_param = slice->param; - slice_param->macroblock_offset = frame_hdr->header_size; + slice_param->macroblock_offset = 8 * (ebdu->offset - ebdu->sc_offset) + frame_hdr->header_size; slice_param->slice_vertical_position = 0; /* Decode picture right away, we got the full frame */ return decode_current_picture(decoder); } +static gboolean +decode_rbdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + guint8 *rbdu_buffer; + guint i, j, rbdu_buffer_size; + + /* BDU are encapsulated in advanced profile mode only */ + if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) { + memcpy(rbdu, ebdu, sizeof(*rbdu)); + return TRUE; + } + + /* Reallocate unescaped bitstream buffer */ + rbdu_buffer = priv->rbdu_buffer; + if (!rbdu_buffer || ebdu->size > priv->rbdu_buffer_size) { + rbdu_buffer = g_realloc(priv->rbdu_buffer, ebdu->size); + if (!rbdu_buffer) + return FALSE; + priv->rbdu_buffer = rbdu_buffer; + priv->rbdu_buffer_size = ebdu->size; + } + + /* Unescape bitstream buffer */ + if (ebdu->size < 4) { + memcpy(rbdu_buffer, ebdu->data + ebdu->offset, ebdu->size); + rbdu_buffer_size = ebdu->size; + } + else { + guint8 * const bdu_buffer = ebdu->data + ebdu->offset; + for (i = 0, j = 0; i < ebdu->size; i++) { + if (i >= 2 && i < ebdu->size - 1 && + bdu_buffer[i - 1] == 0x00 && + bdu_buffer[i - 2] == 0x00 && + bdu_buffer[i ] == 0x03 && + bdu_buffer[i + 1] <= 0x03) + i++; + rbdu_buffer[j++] = bdu_buffer[i]; + } + rbdu_buffer_size = j; + } + + /* Reconstruct RBDU */ + rbdu->type = ebdu->type; + rbdu->size = rbdu_buffer_size; + rbdu->sc_offset = 0; + rbdu->offset = 0; + rbdu->data = rbdu_buffer; + return TRUE; +} + +static GstVaapiDecoderStatus +decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu) +{ + GstVaapiDecoderStatus status; + GstVC1BDU rbdu; + + if (!decode_rbdu(decoder, &rbdu, ebdu)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + switch (ebdu->type) { + case GST_VC1_SEQUENCE: + status = decode_sequence(decoder, &rbdu, ebdu); + break; + case GST_VC1_ENTRYPOINT: + status = decode_entry_point(decoder, &rbdu, ebdu); + break; + case GST_VC1_FRAME: + status = decode_frame(decoder, &rbdu, ebdu); + break; + case GST_VC1_SLICE: + GST_DEBUG("decode slice"); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + case GST_VC1_END_OF_SEQ: + status = decode_sequence_end(decoder); + break; + default: + GST_DEBUG("unsupported BDU type %d", ebdu->type); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + return status; +} + static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) { GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVaapiDecoderStatus status; GstVC1ParserResult result; - GstVC1BDU bdu; + GstVC1BDU ebdu; guchar *buf; - guint buf_size, bdu_size, ofs; + guint buf_size, ofs; buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); @@ -968,7 +1072,7 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) result = gst_vc1_identify_next_bdu( buf + ofs, buf_size - ofs, - &bdu + &ebdu ); status = get_status(result); @@ -979,29 +1083,8 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) break; - ofs += bdu.offset; - switch (bdu.type) { - case GST_VC1_SEQUENCE: - status = decode_sequence(decoder, buf + ofs, bdu.size); - break; - case GST_VC1_ENTRYPOINT: - status = decode_entry_point(decoder, buf + ofs, bdu.size); - break; - case GST_VC1_FRAME: - status = decode_frame(decoder, buf + ofs, bdu.size); - break; - case GST_VC1_SLICE: - GST_DEBUG("decode slice"); - break; - case GST_VC1_END_OF_SEQ: - status = decode_sequence_end(decoder); - break; - default: - GST_DEBUG("unsupported BDU type %d", bdu.type); - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - break; - } - ofs += bdu.size; + ofs += ebdu.offset + ebdu.size; + status = decode_ebdu(decoder, &ebdu); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); return status; } @@ -1078,6 +1161,8 @@ gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder) priv->prev_picture = NULL; priv->tsb = NULL; priv->sub_buffer = NULL; + priv->rbdu_buffer = NULL; + priv->rbdu_buffer_size = 0; priv->is_constructed = FALSE; priv->is_opened = FALSE; priv->is_first_field = FALSE; From a7ccbde2afb41e3251d2ba2406ef3042f56d9fe7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 5 Oct 2011 16:41:57 +0200 Subject: [PATCH 0567/3781] vc1: handle codec-data. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 60 ++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index dd7a0e9b5e..0050cfb9db 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1047,6 +1047,7 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) GstVaapiDecoderStatus status; GstVC1ParserResult result; GstVC1BDU ebdu; + GstBuffer *codec_data; guchar *buf; guint buf_size, ofs; @@ -1055,6 +1056,17 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) if (!buf && buf_size == 0) return decode_sequence_end(decoder); + /* Assume demuxer sends out plain frames if codec-data */ + codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); + if (codec_data && codec_data != buffer) { + ebdu.type = GST_VC1_FRAME; + ebdu.size = buf_size; + ebdu.sc_offset = 0; + ebdu.offset = 0; + ebdu.data = buf; + return decode_ebdu(decoder, &ebdu); + } + gst_vaapi_tsb_push(priv->tsb, buffer); if (priv->sub_buffer) { @@ -1089,11 +1101,52 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) return status; } +static GstVaapiDecoderStatus +decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderStatus status; + GstVC1ParserResult result; + GstVC1BDU ebdu; + guchar *buf; + guint buf_size, ofs; + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + if (!buf || buf_size == 0) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + ofs = 0; + do { + result = gst_vc1_identify_next_bdu( + buf + ofs, + buf_size - ofs, + &ebdu + ); + + switch (result) { + case GST_VC1_PARSER_NO_BDU_END: + /* Assume the EBDU is complete within codec-data bounds */ + ebdu.size = buf_size - ofs - (ebdu.offset - ebdu.sc_offset); + // fall-through + case GST_VC1_PARSER_OK: + status = decode_ebdu(decoder, &ebdu); + ofs += ebdu.offset + ebdu.size; + break; + default: + status = get_status(result); + break; + } + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size); + return status; +} + GstVaapiDecoderStatus gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base, GstBuffer *buffer) { GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base); GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + GstBuffer *codec_data; g_return_val_if_fail(priv->is_constructed, GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); @@ -1102,6 +1155,13 @@ gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base, GstBuffer *buffer) priv->is_opened = gst_vaapi_decoder_vc1_open(decoder, buffer); if (!priv->is_opened) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + + codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); + if (codec_data) { + status = decode_codec_data(decoder, codec_data); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } } return decode_buffer(decoder, buffer); } From b5ab2e56a9afbaffa6350c83f284874a68acd45c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 6 Oct 2011 15:59:22 +0200 Subject: [PATCH 0568/3781] vc1: fix MV mode packing. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 58 ++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 0050cfb9db..829f5dfaa4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -503,6 +503,58 @@ get_BFRACTION(guint bfraction) return 21; /* RESERVED */ } +/* Translate GStreamer MV modes to VA-API */ +static guint +get_VAMvModeVC1(guint mvmode) +{ + switch (mvmode) { + case GST_VC1_MVMODE_1MV_HPEL_BILINEAR: return VAMvMode1MvHalfPelBilinear; + case GST_VC1_MVMODE_1MV: return VAMvMode1Mv; + case GST_VC1_MVMODE_1MV_HPEL: return VAMvMode1MvHalfPel; + case GST_VC1_MVMODE_MIXED_MV: return VAMvModeMixedMv; + case GST_VC1_MVMODE_INTENSITY_COMP: return VAMvModeIntensityCompensation; + } + return 0; +} + +/* Reconstruct bitstream MVMODE (7.1.1.32) */ +static guint +get_MVMODE(GstVC1FrameHdr *frame_hdr) +{ + guint mvmode; + + if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) + mvmode = frame_hdr->pic.advanced.mvmode; + else + mvmode = frame_hdr->pic.simple.mvmode; + + if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P || + frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B) + return get_VAMvModeVC1(mvmode); + return 0; +} + +/* Reconstruct bitstream MVMODE2 (7.1.1.33) */ +static guint +get_MVMODE2(GstVC1FrameHdr *frame_hdr) +{ + guint mvmode, mvmode2; + + if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) { + mvmode = frame_hdr->pic.advanced.mvmode; + mvmode2 = frame_hdr->pic.advanced.mvmode2; + } + else { + mvmode = frame_hdr->pic.simple.mvmode; + mvmode2 = frame_hdr->pic.simple.mvmode2; + } + + if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P && + mvmode == GST_VC1_MVMODE_INTENSITY_COMP) + return get_VAMvModeVC1(mvmode2); + return 0; +} + static inline int has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder) { @@ -656,8 +708,6 @@ fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder); pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder); pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder); - pic_param->mv_fields.bits.mv_mode = pic->mvmode; - pic_param->mv_fields.bits.mv_mode2 = pic->mvmode2; pic_param->mv_fields.bits.mv_table = pic->mvtab; pic_param->mv_fields.bits.extended_mv_flag = structc->extended_mv; pic_param->mv_fields.bits.extended_mv_range = pic->mvrange; @@ -722,8 +772,6 @@ fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) pic_param->bitplane_present.flags.bp_ac_pred = has_ACPRED_bitplane(decoder); pic_param->bitplane_present.flags.bp_overflags = has_OVERFLAGS_bitplane(decoder); pic_param->reference_fields.bits.reference_distance_flag = entrypoint_hdr->refdist_flag; - pic_param->mv_fields.bits.mv_mode = pic->mvmode; - pic_param->mv_fields.bits.mv_mode2 = pic->mvmode2; pic_param->mv_fields.bits.mv_table = pic->mvtab; pic_param->mv_fields.bits.extended_mv_flag = entrypoint_hdr->extended_mv; pic_param->mv_fields.bits.extended_mv_range = pic->mvrange; @@ -764,6 +812,8 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) pic_param->bitplane_present.value = 0; pic_param->reference_fields.value = 0; pic_param->mv_fields.value = 0; + pic_param->mv_fields.bits.mv_mode = get_MVMODE(frame_hdr); + pic_param->mv_fields.bits.mv_mode2 = get_MVMODE2(frame_hdr); pic_param->pic_quantizer_fields.value = 0; pic_param->pic_quantizer_fields.bits.half_qp = frame_hdr->halfqp; pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = frame_hdr->pquant; From 7b1d7841977bdf416567f1e4ba934407ed11aa67 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Oct 2011 11:12:33 +0200 Subject: [PATCH 0569/3781] vc1: fix presentation timestamps. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 829f5dfaa4..35fc75b4ed 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -907,6 +907,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) GstVaapiSlice *slice; GstVaapiDecoderStatus status; VASliceParameterBufferVC1 *slice_param; + GstClockTime pts; status = ensure_context(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { @@ -968,6 +969,10 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } + /* Update presentation time */ + pts = gst_vaapi_tsb_get_timestamp(priv->tsb); + picture->pts = pts; + /* Update reference pictures */ if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { if (priv->prev_picture) { @@ -1106,6 +1111,8 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) if (!buf && buf_size == 0) return decode_sequence_end(decoder); + gst_vaapi_tsb_push(priv->tsb, buffer); + /* Assume demuxer sends out plain frames if codec-data */ codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); if (codec_data && codec_data != buffer) { @@ -1114,11 +1121,11 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) ebdu.sc_offset = 0; ebdu.offset = 0; ebdu.data = buf; - return decode_ebdu(decoder, &ebdu); + status = decode_ebdu(decoder, &ebdu); + gst_vaapi_tsb_pop(priv->tsb, buf_size); + return status; } - gst_vaapi_tsb_push(priv->tsb, buffer); - if (priv->sub_buffer) { buffer = gst_buffer_merge(priv->sub_buffer, buffer); if (!buffer) @@ -1146,7 +1153,9 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) break; ofs += ebdu.offset + ebdu.size; + gst_vaapi_tsb_pop(priv->tsb, ebdu.offset); status = decode_ebdu(decoder, &ebdu); + gst_vaapi_tsb_pop(priv->tsb, ebdu.size); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); return status; } From 6ae97634cf8d8c5f0978a52202e29a5cbdd5c062 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Oct 2011 11:50:20 +0200 Subject: [PATCH 0570/3781] vc1: fix codec-data decoding for WMV3 format. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 38 ++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 35fc75b4ed..55d0f0b853 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1163,17 +1163,55 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) static GstVaapiDecoderStatus decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) { + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVaapiDecoderStatus status; GstVC1ParserResult result; GstVC1BDU ebdu; + GstCaps *caps; + GstStructure *structure; guchar *buf; guint buf_size, ofs; + gint width, height; + guint32 format; buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); if (!buf || buf_size == 0) return GST_VAAPI_DECODER_STATUS_SUCCESS; + caps = GST_VAAPI_DECODER_CAST(decoder)->priv->caps; + structure = gst_caps_get_structure(caps, 0); + + if (!gst_structure_get_int(structure, "width", &width) || + !gst_structure_get_int(structure, "height", &height)) { + GST_DEBUG("failed to parse size from codec-data"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!gst_structure_get_fourcc(structure, "format", &format)) { + GST_DEBUG("failed to parse profile from codec-data"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + } + + /* WMV3 -- expecting sequence header */ + if (format == GST_MAKE_FOURCC('W','M','V','3')) { + seq_hdr->struct_c.coded_width = width; + seq_hdr->struct_c.coded_height = height; + ebdu.type = GST_VC1_SEQUENCE; + ebdu.size = buf_size; + ebdu.sc_offset = 0; + ebdu.offset = 0; + ebdu.data = buf; + return decode_ebdu(decoder, &ebdu); + } + + /* WVC1 -- expecting bitstream data units */ + if (format != GST_MAKE_FOURCC('W','V','C','1')) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + seq_hdr->advanced.max_coded_width = width; + seq_hdr->advanced.max_coded_height = height; + ofs = 0; do { result = gst_vc1_identify_next_bdu( From c3455e341e6b441e5468ecd9356f7625cb685dce Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 18 Nov 2011 15:41:40 +0200 Subject: [PATCH 0571/3781] vc1: replace GstVaapiTSB with GstAdapter (gst-plugins-base >= 0.10.24). Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 32 ++++++++++++++---------- gst-libs/gst/vaapi/gstvaapidecoder_vc1.h | 1 + 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 55d0f0b853..0bf52371fe 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -31,7 +31,6 @@ #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" -#include "gstvaapiutils_tsb.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -58,7 +57,7 @@ struct _GstVaapiDecoderVC1Private { GstVaapiPicture *current_picture; GstVaapiPicture *next_picture; GstVaapiPicture *prev_picture; - GstVaapiTSB *tsb; + GstAdapter *adapter; GstBuffer *sub_buffer; guint8 *rbdu_buffer; guint rbdu_buffer_size; @@ -125,9 +124,10 @@ gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder) priv->bitplanes = NULL; } - if (priv->tsb) { - gst_vaapi_tsb_destroy(priv->tsb); - priv->tsb = NULL; + if (priv->adapter) { + gst_adapter_clear(priv->adapter); + g_object_unref(priv->adapter); + priv->adapter = NULL; } } @@ -138,8 +138,8 @@ gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) gst_vaapi_decoder_vc1_close(decoder); - priv->tsb = gst_vaapi_tsb_new(); - if (!priv->tsb) + priv->adapter = gst_adapter_new(); + if (!priv->adapter) return FALSE; priv->bitplanes = gst_vc1_bitplanes_new(); @@ -970,7 +970,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) } /* Update presentation time */ - pts = gst_vaapi_tsb_get_timestamp(priv->tsb); + pts = gst_adapter_prev_timestamp(priv->adapter, NULL); picture->pts = pts; /* Update reference pictures */ @@ -1111,7 +1111,8 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) if (!buf && buf_size == 0) return decode_sequence_end(decoder); - gst_vaapi_tsb_push(priv->tsb, buffer); + gst_buffer_ref(buffer); + gst_adapter_push(priv->adapter, buffer); /* Assume demuxer sends out plain frames if codec-data */ codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); @@ -1122,7 +1123,9 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) ebdu.offset = 0; ebdu.data = buf; status = decode_ebdu(decoder, &ebdu); - gst_vaapi_tsb_pop(priv->tsb, buf_size); + + if (gst_adapter_available(priv->adapter) >= buf_size) + gst_adapter_flush(priv->adapter, buf_size); return status; } @@ -1153,9 +1156,12 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) break; ofs += ebdu.offset + ebdu.size; - gst_vaapi_tsb_pop(priv->tsb, ebdu.offset); + if (gst_adapter_available(priv->adapter) >= ebdu.offset) + gst_adapter_flush(priv->adapter, ebdu.offset); + status = decode_ebdu(decoder, &ebdu); - gst_vaapi_tsb_pop(priv->tsb, ebdu.size); + if (gst_adapter_available(priv->adapter) >= ebdu.size) + gst_adapter_flush(priv->adapter, ebdu.size); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); return status; } @@ -1316,7 +1322,7 @@ gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder) priv->current_picture = NULL; priv->next_picture = NULL; priv->prev_picture = NULL; - priv->tsb = NULL; + priv->adapter = NULL; priv->sub_buffer = NULL; priv->rbdu_buffer = NULL; priv->rbdu_buffer_size = 0; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h index b877227283..f443a4997f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h @@ -23,6 +23,7 @@ #define GST_VAAPI_DECODER_VC1_H #include +#include G_BEGIN_DECLS From 650278347450731be998823d0ecdaf2df7015b5e Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Fri, 9 Dec 2011 16:28:11 +0800 Subject: [PATCH 0572/3781] Add initial MPEG-4 decoder. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 1108 ++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h | 87 ++ gst/vaapi/gstvaapidecode.c | 7 + 4 files changed, 1204 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 50ca49aa26..8623b5fe44 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -145,10 +145,12 @@ endif if USE_CODEC_PARSERS libgstvaapi_source_c += \ gstvaapidecoder_mpeg2.c \ + gstvaapidecoder_mpeg4.c \ gstvaapidecoder_vc1.c \ $(NULL) libgstvaapi_source_h += \ gstvaapidecoder_mpeg2.h \ + gstvaapidecoder_mpeg4.h \ gstvaapidecoder_vc1.h \ $(NULL) libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c new file mode 100644 index 0000000000..0da00266f8 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -0,0 +1,1108 @@ +/* + * gstvaapidecoder_mpeg4.c - MPEG-4 decoder + * + * Copyright (C) 2011 Intel Corporation + * + * 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_mpeg4 + * @short_description: MPEG-4 decoder, include h263/divx/xvid support + */ + +#include "config.h" +#include +#include +#include +#include "gstvaapidecoder_mpeg4.h" +#include "gstvaapidecoder_priv.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapiobject_priv.h" +#include "gstvaapiutils_tsb.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiDecoderMpeg4, + gst_vaapi_decoder_mpeg4, + GST_VAAPI_TYPE_DECODER); + +#define GST_VAAPI_DECODER_MPEG4_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DECODER_MPEG4, \ + GstVaapiDecoderMpeg4Private)) + +struct _GstVaapiDecoderMpeg4Private { + GstVaapiProfile profile; + guint level; + guint width; + guint height; + guint fps_n; + guint fps_d; + guint coding_type; + GstMpeg4VisualObjectSequence vos_hdr; + GstMpeg4VisualObject vo_hdr; + GstMpeg4VideoSignalType signal_type; + GstMpeg4VideoObjectLayer vol_hdr; + GstMpeg4VideoObjectPlane vop_hdr; + GstMpeg4VideoPlaneShortHdr svh_hdr; + GstMpeg4VideoPacketHdr packet_hdr; + GstMpeg4SpriteTrajectory sprite_trajectory; + VAIQMatrixBufferMPEG4 iq_matrix; + GstVaapiPicture *curr_picture; + // forward reference pic + GstVaapiPicture *next_picture; + // backward reference pic + GstVaapiPicture *prev_picture; + GstVaapiTSB *tsb; + GstBuffer *sub_buffer; + GstClockTime seq_pts; + GstClockTime gop_pts; + GstClockTime pts_diff; + // anchor sync time base for any picture type, + // it is time base of backward reference frame + GstClockTime last_sync_time; + // time base for recent I/P/S frame, + // it is time base of forward reference frame for B frame + GstClockTime sync_time; + // temporal_reference of previous frame of svh + guint8 prev_t_ref; + guint is_constructed : 1; + guint is_opened : 1; + guint is_first_field : 1; + guint size_changed : 1; + guint profile_changed : 1; + guint progressive_sequence : 1; + guint closed_gop : 1; + guint broken_link : 1; + guint calculate_pts_diff : 1; + guint is_svh : 1; +}; + +static void +gst_vaapi_decoder_mpeg4_close(GstVaapiDecoderMpeg4 *decoder) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + + if (priv->curr_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->curr_picture); + priv->curr_picture = NULL; + } + + if (priv->next_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->next_picture); + priv->next_picture = NULL; + } + + if (priv->prev_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); + priv->prev_picture = NULL; + } + + if (priv->sub_buffer) { + gst_buffer_unref(priv->sub_buffer); + priv->sub_buffer = NULL; + } + + if (priv->tsb) { + gst_vaapi_tsb_destroy(priv->tsb); + priv->tsb = NULL; + } +} + +static gboolean +gst_vaapi_decoder_mpeg4_open(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) +{ + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstCaps *caps = NULL; + GstStructure *structure = NULL; + + gst_vaapi_decoder_mpeg4_close(decoder); + + priv->tsb = gst_vaapi_tsb_new(); + if (!priv->tsb) + return FALSE; + + priv->is_svh = 0; + caps = gst_vaapi_decoder_get_caps(base_decoder); + if (caps) { + structure = gst_caps_get_structure(caps, 0); + if (structure) { + if (gst_structure_has_name(structure, "video/x-h263")) { + priv->is_svh = 1; + priv->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; + priv->prev_t_ref = -1; + } + } + } + return TRUE; +} + +static void +gst_vaapi_decoder_mpeg4_destroy(GstVaapiDecoderMpeg4 *decoder) +{ + gst_vaapi_decoder_mpeg4_close(decoder); +} + +static gboolean +gst_vaapi_decoder_mpeg4_create(GstVaapiDecoderMpeg4 *decoder) +{ + if (!GST_VAAPI_DECODER_CODEC(decoder)) + return FALSE; + return TRUE; +} + +static inline void +copy_quant_matrix(guint8 dst[64], const guint8 src[64]) +{ + memcpy(dst, src, 64); +} + +static GstVaapiDecoderStatus +ensure_context(GstVaapiDecoderMpeg4 *decoder) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + 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_MPEG4_SIMPLE) + profiles[n_profiles++] = GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE; + + 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) { + reset_context = gst_vaapi_decoder_ensure_context( + GST_VAAPI_DECODER(decoder), + priv->profile, + entrypoint, + priv->width, priv->height + ); + if (!reset_context) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +ensure_quant_matrix(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + VAIQMatrixBufferMPEG4 *iq_matrix; + + if (!priv->vol_hdr.load_intra_quant_mat && !priv->vol_hdr.load_non_intra_quant_mat) { + return GST_VAAPI_DECODER_STATUS_SUCCESS; + } + + picture->iq_matrix = gst_vaapi_decoder_new_iq_matrix(GST_VAAPI_DECODER(decoder)); + if (!picture->iq_matrix) { + GST_DEBUG("failed to allocate IQ matrix"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + iq_matrix = picture->iq_matrix->param; + + if (priv->vol_hdr.load_intra_quant_mat) { + iq_matrix->load_intra_quant_mat = 1; + copy_quant_matrix(iq_matrix->intra_quant_mat, + priv->vol_hdr.intra_quant_mat); + } + else + iq_matrix->load_intra_quant_mat = 0; + + if (priv->vol_hdr.load_non_intra_quant_mat) { + iq_matrix->load_non_intra_quant_mat = 1; + copy_quant_matrix(iq_matrix->non_intra_quant_mat, + priv->vol_hdr.non_intra_quant_mat); + } + else + iq_matrix->load_non_intra_quant_mat = 0; + + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static inline GstVaapiDecoderStatus +render_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + + if (!gst_vaapi_decoder_push_surface(base_decoder, + picture->surface, + picture->pts)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +/* decode_picture() start to decode a frame/picture + * decode_current_picture() finishe decoding a frame/picture + * (commit buffer to driver for decoding) + */ +static GstVaapiDecoderStatus +decode_current_picture(GstVaapiDecoderMpeg4 *decoder) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiPicture * const picture = priv->curr_picture; + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (picture) { + if (!gst_vaapi_decoder_decode_picture(base_decoder, picture)) + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { + if ((priv->prev_picture && priv->next_picture) || + (priv->closed_gop && priv->next_picture)) + status = render_picture(decoder, picture); + gst_vaapi_decoder_free_picture(base_decoder, picture); + } + priv->curr_picture = NULL; + } + return status; +} + +static GstVaapiDecoderStatus +decode_sequence(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstMpeg4VisualObjectSequence * const vos_hdr = &priv->vos_hdr; + GstVaapiProfile profile; + + if (gst_mpeg4_parse_visual_object_sequence(vos_hdr, buf, buf_size) != GST_MPEG4_PARSER_OK) { + GST_DEBUG("failed to parse sequence header"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + priv->level = vos_hdr->level; + switch (vos_hdr->profile) { + case GST_MPEG4_PROFILE_SIMPLE: + profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; + break; + case GST_MPEG4_PROFILE_ADVANCED_SIMPLE: + profile = GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE; + break; + default: + GST_DEBUG("unsupported profile %d", profile); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + if (priv->profile != profile) { + priv->profile = profile; + priv->profile_changed = TRUE; + } + priv->seq_pts = gst_vaapi_tsb_get_timestamp(priv->tsb); + priv->calculate_pts_diff = TRUE; + + priv->size_changed = TRUE; + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence_end(GstVaapiDecoderMpeg4 *decoder) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + + if (priv->curr_picture) { + status = decode_current_picture(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + status = render_picture(decoder, priv->curr_picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + + if (priv->next_picture) { + status = render_picture(decoder, priv->next_picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; +} + +static GstVaapiDecoderStatus +decode_visual_object(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstMpeg4VisualObject * vo_hdr = &priv->vo_hdr; + GstMpeg4VideoSignalType * signal_type = &priv->signal_type; + + if (gst_mpeg4_parse_visual_object (vo_hdr, signal_type, buf, buf_size) != GST_MPEG4_PARSER_OK) { + GST_DEBUG("failed to parse visual object"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + /* XXX: video_signal_type isn't used for decoding */ + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_video_object_layer(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstMpeg4VisualObject * vo_hdr = &priv->vo_hdr; + GstMpeg4VideoObjectLayer * vol_hdr = &priv->vol_hdr; + + if (gst_mpeg4_parse_video_object_layer (vol_hdr, vo_hdr, buf, buf_size) != GST_MPEG4_PARSER_OK) { + GST_DEBUG("failed to parse video object layer"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + priv->width = vol_hdr->width; + priv->height = vol_hdr->height; + + priv->progressive_sequence = !vol_hdr->interlaced; + + if (vol_hdr->fixed_vop_rate) { + priv->fps_n = vol_hdr->vop_time_increment_resolution; + priv->fps_d = vol_hdr->fixed_vop_time_increment; + gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); + } + + gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, priv->vol_hdr.par_width, priv->vol_hdr.par_height); + gst_vaapi_decoder_set_picture_size(base_decoder, priv->width, priv->height); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_gop(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstMpeg4GroupOfVOP gop; + GstClockTime pts; + + if (buf_size >4) { + if (gst_mpeg4_parse_group_of_vop(&gop, buf, buf_size) != GST_MPEG4_PARSER_OK) { + GST_DEBUG("failed to parse GOP"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + } + else { + gop.closed = 1; + gop.broken_link = 0; + gop.hours = 0; + gop.minutes = 0; + gop.seconds = 0; + } + + priv->closed_gop = gop.closed; + priv->broken_link = gop.broken_link; + + GST_DEBUG("GOP %02u:%02u:%02u (closed_gop %d, broken_link %d)", + gop.hours, gop.minutes, gop.seconds, + priv->closed_gop, priv->broken_link); + + pts = GST_SECOND * (gop.hours * 3600 + gop.minutes * 60 + gop.seconds); + priv->gop_pts = pts; + priv->last_sync_time = priv->gop_pts; + priv->sync_time= priv->gop_pts; + + if (priv->calculate_pts_diff) { + priv->pts_diff = priv->seq_pts - priv->gop_pts; + priv->calculate_pts_diff = FALSE; + } + + priv->is_first_field = TRUE; + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) +{ + GstMpeg4ParseResult parser_result = GST_MPEG4_PARSER_OK; + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr; + GstMpeg4VideoObjectLayer * const vol_hdr = &priv->vol_hdr; + GstMpeg4SpriteTrajectory * const sprite_trajectory = &priv->sprite_trajectory; + GstVaapiPicture *picture; + GstVaapiDecoderStatus status; + GstClockTime pts; + + // context depends on priv->width and priv->height, so we move parse_vop a little earlier + if (priv->is_svh) { + parser_result = gst_mpeg4_parse_video_plane_short_header(&priv->svh_hdr, buf, buf_size); + + } + else { + parser_result = gst_mpeg4_parse_video_object_plane(vop_hdr, sprite_trajectory, vol_hdr, buf, buf_size); + } + + if (parser_result != GST_MPEG4_PARSER_OK) { + GST_DEBUG("failed to parse picture header"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + if (priv->is_svh) { + priv->width = priv->svh_hdr.vop_width; + priv->height = priv->svh_hdr.vop_height; + } + else { + if (!vop_hdr->width && !vop_hdr->height) { + vop_hdr->width = vol_hdr->width; + vop_hdr->height = vol_hdr->height; + } + priv->width = vop_hdr->width; + priv->height = vop_hdr->height; + } + + status = ensure_context(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_DEBUG("failed to reset context"); + return status; + } + + if (priv->curr_picture) { + status = decode_current_picture(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + + priv->curr_picture = gst_vaapi_decoder_new_picture(base_decoder); + if (!priv->curr_picture) { + GST_DEBUG("failed to allocate picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + picture = priv->curr_picture; + + status = ensure_quant_matrix(decoder, picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_DEBUG("failed to reset quantizer matrix"); + return status; + } + + /* 7.6.7 Temporal prediction structure + * forward reference frame B B B B B B backward reference frame + * | | + * nearest I/P/S in the past with vop_coded ==1 | + * nearest I/P/S in the future with any vop_coded + * fixme, it said that B frame shouldn't use backward reference frame + * when backward reference frame coded is 0 + */ + if (priv->is_svh) { + priv->coding_type = priv->svh_hdr.picture_coding_type; + } + else { + priv->coding_type = priv->vop_hdr.coding_type; + } + switch (priv->coding_type) { + case GST_MPEG4_I_VOP: + picture->type = GST_VAAPI_PICTURE_TYPE_I; + if (priv->is_svh || vop_hdr->coded) + picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + break; + case GST_MPEG4_P_VOP: + picture->type = GST_VAAPI_PICTURE_TYPE_P; + if (priv->is_svh || vop_hdr->coded) + picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + break; + case GST_MPEG4_B_VOP: + picture->type = GST_VAAPI_PICTURE_TYPE_B; + break; + case GST_MPEG4_S_VOP: + picture->type = GST_VAAPI_PICTURE_TYPE_S; + // see 3.175 reference VOP + if (vop_hdr->coded) + picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + break; + default: + GST_DEBUG("unsupported picture type %d", priv->coding_type); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!priv->is_svh && !vop_hdr->coded) { + status = render_picture(decoder, priv->prev_picture); + return status; + } + + if (priv->is_svh) { + guint temp_ref = priv->svh_hdr.temporal_reference; + if (temp_ref < priv->prev_t_ref) { + temp_ref += 256; + } + guint delta_ref = temp_ref - priv->prev_t_ref; + + pts = priv->sync_time; + // see temporal_reference definition in spec, 30000/1001Hz + pts += gst_util_uint64_scale(delta_ref, GST_SECOND*1001, 30000); + priv->sync_time = pts; + priv->prev_t_ref = priv->svh_hdr.temporal_reference; + } + else { + /* Update presentation time, 6.3.5 */ + if(vop_hdr->coding_type != GST_MPEG4_B_VOP) { + // increment basing on decoding order + priv->last_sync_time = priv->sync_time; + priv->sync_time = priv->last_sync_time + vop_hdr->modulo_time_base; + pts = priv->sync_time * GST_SECOND; + pts += gst_util_uint64_scale(vop_hdr->time_increment, GST_SECOND, vol_hdr->vop_time_increment_resolution); + } + else { + // increment basing on display oder + pts = (priv->last_sync_time + vop_hdr->modulo_time_base)* GST_SECOND; + pts += gst_util_uint64_scale(vop_hdr->time_increment, GST_SECOND, vol_hdr->vop_time_increment_resolution); + } + } + picture->pts = pts + priv->pts_diff; + + /* Update reference pictures */ + /* XXX: consider priv->vol_hdr.low_delay, consider packed video frames for DivX/XviD */ + if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { + picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + if (priv->prev_picture) { + gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); + priv->prev_picture = NULL; + } + if (priv->next_picture) { + priv->prev_picture = priv->next_picture; + priv->next_picture = NULL; + status = render_picture(decoder, priv->prev_picture); + } + priv->next_picture = picture; + } + return status; +} + +static gboolean +fill_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + VAPictureParameterBufferMPEG4 * const pic_param = picture->param; + GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr; + + /* Fill in VAPictureParameterBufferMPEG4 */ + pic_param->forward_reference_picture = VA_INVALID_ID; + pic_param->backward_reference_picture = VA_INVALID_ID; + + pic_param->vol_fields.value = 0; + pic_param->vop_fields.value = 0; + if(priv->is_svh) { + // vol_hdr Parameters + pic_param->vol_fields.bits.short_video_header = 1; + // does the following vol_hdr parameters matter for short video header? + pic_param->vol_fields.bits.chroma_format = 1; // I420, see table 6-15. + pic_param->vol_fields.bits.interlaced = 0; + pic_param->vol_fields.bits.obmc_disable = 1; + pic_param->vol_fields.bits.sprite_enable = 0; + pic_param->vol_fields.bits.sprite_warping_accuracy = 0; + pic_param->vol_fields.bits.quant_type = 0; //method 1; $7.4.4 + pic_param->vol_fields.bits.quarter_sample = 0; + pic_param->vol_fields.bits.data_partitioned = 0; + pic_param->vol_fields.bits.reversible_vlc = 0; + pic_param->vol_fields.bits.resync_marker_disable = 1; + pic_param->no_of_sprite_warping_points = 0; + pic_param->quant_precision = 5; + // VOP parameters + pic_param->vop_width = priv->svh_hdr.vop_width; + pic_param->vop_height = priv->svh_hdr.vop_height; + pic_param->vop_fields.bits.vop_coding_type = priv->svh_hdr.picture_coding_type; + pic_param->vop_time_increment_resolution = priv->vol_hdr.vop_time_increment_resolution; + + pic_param->num_gobs_in_vop = priv->svh_hdr.num_gobs_in_vop; + pic_param->num_macroblocks_in_gob = priv->svh_hdr.num_macroblocks_in_gob; + } + else { + // VOL parameters + pic_param->vol_fields.bits.short_video_header = 0; + pic_param->vol_fields.bits.chroma_format = priv->vol_hdr.chroma_format; + pic_param->vol_fields.bits.interlaced = priv->vol_hdr.interlaced; + pic_param->vol_fields.bits.obmc_disable = priv->vol_hdr.obmc_disable; + pic_param->vol_fields.bits.sprite_enable = priv->vol_hdr.sprite_enable; + pic_param->vol_fields.bits.sprite_warping_accuracy = priv->vol_hdr.sprite_warping_accuracy; + pic_param->vol_fields.bits.quant_type = priv->vol_hdr.quant_type; + pic_param->vol_fields.bits.quarter_sample = priv->vol_hdr.quarter_sample; + pic_param->vol_fields.bits.data_partitioned = priv->vol_hdr.data_partitioned; + pic_param->vol_fields.bits.reversible_vlc = priv->vol_hdr.reversible_vlc; + pic_param->vol_fields.bits.resync_marker_disable = priv->vol_hdr.resync_marker_disable; + pic_param->no_of_sprite_warping_points = priv->vol_hdr.no_of_sprite_warping_points; + int i =0; + for (i=0; i<3 && ivol_hdr.no_of_sprite_warping_points ; i++) { + pic_param->sprite_trajectory_du[i] = priv->sprite_trajectory.vop_ref_points[i]; + pic_param->sprite_trajectory_dv[i] = priv->sprite_trajectory.sprite_ref_points[i]; + } + pic_param->quant_precision = priv->vol_hdr.quant_precision; + + // VOP parameters + pic_param->vop_width = vop_hdr->width; + pic_param->vop_height = vop_hdr->height; + pic_param->vop_fields.bits.vop_coding_type = vop_hdr->coding_type; + pic_param->vop_fields.bits.vop_rounding_type = vop_hdr->rounding_type; + pic_param->vop_fields.bits.intra_dc_vlc_thr = vop_hdr->intra_dc_vlc_thr; + pic_param->vop_fields.bits.top_field_first = vop_hdr->top_field_first; + pic_param->vop_fields.bits.alternate_vertical_scan_flag = vop_hdr->alternate_vertical_scan_flag; + + pic_param->vop_fcode_forward = vop_hdr->fcode_forward; + pic_param->vop_fcode_backward = vop_hdr->fcode_backward; + pic_param->vop_time_increment_resolution = priv->vol_hdr.vop_time_increment_resolution; + } + + switch (priv->coding_type) { + case GST_MPEG4_B_VOP: + pic_param->TRB = priv->curr_picture->pts - priv->prev_picture->pts; + pic_param->TRD = priv->next_picture->pts - priv->prev_picture->pts; + pic_param->backward_reference_picture = priv->next_picture->surface_id; + pic_param->vop_fields.bits.backward_reference_vop_coding_type = priv->prev_picture->type; + // fall-through + case GST_MPEG4_P_VOP: + if (priv->prev_picture) + pic_param->forward_reference_picture = priv->prev_picture->surface_id; + break; + } + + if (priv->vol_hdr.interlaced) { + priv->is_first_field ^= 1; + } + return TRUE; +} + +static GstVaapiDecoderStatus +decode_slice( + GstVaapiDecoderMpeg4 *decoder, + const guint8 *buf, + guint buf_size, + gboolean has_packet_header +) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiPicture * const picture = priv->curr_picture; + GstVaapiSlice *slice; + VASliceParameterBufferMPEG4 *slice_param; + + GST_DEBUG("decoder silce: %p, %u bytes)", buf, buf_size); + + // has_packet_header is ture for the 2+ slice + if (!has_packet_header && !fill_picture(decoder, picture)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + slice = gst_vaapi_decoder_new_slice( + GST_VAAPI_DECODER(decoder), + picture, + (guchar*)buf, buf_size + ); + if (!slice) { + GST_DEBUG("failed to allocate slice"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + /* Fill in VASliceParameterBufferMPEG4 */ + slice_param = slice->param; + if (priv->is_svh) { + slice_param->macroblock_offset = (priv->svh_hdr.size)%8; + slice_param->macroblock_number = 0; + // the header of first gob_layer is empty (gob_header_empty=1), use vop_quant + slice_param->quant_scale = priv->svh_hdr.vop_quant; + } + else { + if (has_packet_header) { + slice_param->macroblock_offset = priv->packet_hdr.size % 8; + slice_param->macroblock_number = priv->packet_hdr.macroblock_number; + slice_param->quant_scale = priv->packet_hdr.quant_scale; + } + else { + slice_param->macroblock_offset = priv->vop_hdr.size % 8; + slice_param->macroblock_number = 0; + slice_param->quant_scale = priv->vop_hdr.quant; + } + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstMpeg4Packet *tos = &packet; + GstVaapiDecoderStatus status; + + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + if (tos->size < 0) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + // packet.size is the size from current marker to the next. + if (tos->type == GST_MPEG4_VISUAL_OBJ_SEQ_START) { + status = decode_sequence(decoder, packet.data + packet.offset, packet.size); + } + else if (tos->type == GST_MPEG4_VISUAL_OBJ_SEQ_END) { + status = decode_sequence_end(decoder); + } + else if (tos->type == GST_MPEG4_VISUAL_OBJ) { + status = decode_visual_object(decoder, packet.data + packet.offset, packet.size); + } + else if (tos->type >= GST_MPEG4_VIDEO_OBJ_FIRST && tos->type <= GST_MPEG4_VIDEO_OBJ_LAST) { + GST_WARNING("unexpected marker: (GST_MPEG4_VIDEO_OBJ_FIRST, GST_MPEG4_VIDEO_OBJ_LAST)"); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + } + else if (tos->type >= GST_MPEG4_VIDEO_LAYER_FIRST && tos->type <= GST_MPEG4_VIDEO_LAYER_LAST) { + status = decode_video_object_layer(decoder, packet.data + packet.offset, packet.size); + } + else if (tos->type == GST_MPEG4_GROUP_OF_VOP) { + status = decode_gop(decoder, packet.data + packet.offset, packet.size); + } + else if (tos->type == GST_MPEG4_VIDEO_OBJ_PLANE) { + status = decode_picture(decoder, packet.data + packet.offset, packet.size); + + /* decode slice + * A resync marker shall only be located immediately before a macroblock + * (or video packet header if exists) and aligned with a byte + * either start_code or resync_marker are scaned/measured by byte, + * while the header itself are parsed/measured in bit + * it means: resync_marker(video_packet_header) start from byte boundary, + * while MB doesn't start from byte boundary -- it is what 'macroblock_offset' + * in slice refer to + */ + const guint8 *_data = packet.data + packet.offset + priv->vop_hdr.size/8; + gint _data_size = packet.size - (priv->vop_hdr.size/8); + GstMpeg4Packet video_packet; + + if (priv->vol_hdr.resync_marker_disable) { + status = decode_slice(decoder, _data, _data_size, FALSE); + } + else { + // next start_code is required to determine the end of last slice + _data_size += 4; + GstMpeg4ParseResult ret = GST_MPEG4_PARSER_OK; + + gboolean first_slice = TRUE; + while (_data_size > 0) { + // we can skip user data here + ret = gst_mpeg4_parse(&video_packet, TRUE, &priv->vop_hdr, _data, 0, _data_size); + if(ret != GST_MPEG4_PARSER_OK) { + break; + } + + if (first_slice) { + status = decode_slice(decoder, _data, video_packet.size, FALSE); + first_slice = FALSE; + } + else { + _data += video_packet.offset; + _data_size -= video_packet.offset; + + ret = gst_mpeg4_parse_video_packet_header (&priv->packet_hdr, &priv->vol_hdr, &priv->vop_hdr, &priv->sprite_trajectory, _data, _data_size); + status = decode_slice(decoder,_data + priv->packet_hdr.size/8, video_packet.size - priv->packet_hdr.size/8, TRUE); + } + + _data += video_packet.size; + _data_size -= video_packet.size; + } + } + status = decode_current_picture(decoder); + } + else if (tos->type == GST_MPEG4_USER_DATA + || tos->type == GST_MPEG4_VIDEO_SESSION_ERR + || tos->type == GST_MPEG4_FBA + || tos->type == GST_MPEG4_FBA_PLAN + || tos->type == GST_MPEG4_MESH + || tos->type == GST_MPEG4_MESH_PLAN + || tos->type == GST_MPEG4_STILL_TEXTURE_OBJ + || tos->type == GST_MPEG4_TEXTURE_SPATIAL + || tos->type == GST_MPEG4_TEXTURE_SNR_LAYER + || tos->type == GST_MPEG4_TEXTURE_TILE + || tos->type == GST_MPEG4_SHAPE_LAYER + || tos->type == GST_MPEG4_STUFFING + || tos->type == GST_MPEG4_SYSTEM_FIRST + || tos->type == GST_MPEG4_SYSTEM_LAST) { + GST_WARNING("Ignore marker: %x\n", tos->type); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + } + + return status; +} + +static GstVaapiDecoderStatus +decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + guchar *buf; + guint pos, buf_size; + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + + // visual object sequence end + if (!buf && buf_size == 0) + return decode_sequence_end(decoder); + + gst_vaapi_tsb_push(priv->tsb, buffer); + + if (priv->sub_buffer) { + buffer = gst_buffer_merge(priv->sub_buffer, buffer); + if (!buffer) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + gst_buffer_unref(priv->sub_buffer); + priv->sub_buffer = NULL; + } + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + pos = 0; + + GstMpeg4Packet packet; + GstMpeg4ParseResult result = GST_MPEG4_PARSER_OK; + guint consumed_size = 0; + + if (priv->is_svh) { + while (result == GST_MPEG4_PARSER_OK && pos < buf_size) { + result = gst_h263_parse (&packet,buf, pos, buf_size); + if (result != GST_MPEG4_PARSER_OK) { + break; + } + status = decode_picture(decoder, packet.data+packet.offset, packet.size); + if (GST_VAAPI_DECODER_STATUS_SUCCESS == status) { + // MBs are not byte aligned, so we set the start address with byte aligned + // and mb offset with (priv->svh_hdr.size)%8 + status = decode_slice(decoder, packet.data+packet.offset+(priv->svh_hdr.size)/8, + packet.size - (priv->svh_hdr.size)/8, FALSE); + status = decode_current_picture(decoder); + + consumed_size = packet.offset + packet.size; + pos += consumed_size; + gst_vaapi_tsb_pop(priv->tsb, consumed_size); + } + else { + GST_WARNING("decode h263 packet failed\n"); + break; + } + } + } + else { + while (pos < buf_size) { + // don't skip user data, we need the size to pop tsb buffer + result = gst_mpeg4_parse(&packet, FALSE, NULL, buf, pos, buf_size); + if (result != GST_MPEG4_PARSER_OK) { + break; + } + status = decode_packet(decoder, packet); + if (GST_VAAPI_DECODER_STATUS_SUCCESS == status) { + consumed_size = packet.offset + packet.size - pos; + pos = packet.offset + packet.size; + gst_vaapi_tsb_pop(priv->tsb, consumed_size); + } + else { + GST_WARNING("decode mp4 packet failed\n"); + break; + } + } + } + + if ((result == GST_MPEG4_PARSER_NO_PACKET || result == GST_MPEG4_PARSER_NO_PACKET_END) && pos < buf_size) { + priv->sub_buffer = gst_buffer_create_sub(buffer, pos, buf_size-pos); + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } + return status; +} + +static GstVaapiDecoderStatus +decode_codec_data(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + guchar *buf, *_buf; + guint pos, buf_size, _buf_size; + + _buf = GST_BUFFER_DATA(buffer); + _buf_size = GST_BUFFER_SIZE(buffer); + // add additional 0x000001b2 to enclose the last header + buf_size = _buf_size + 4; + buf = malloc(buf_size); + memcpy(buf, _buf, buf_size); + buf[buf_size-4] = 0; + buf[buf_size-3] = 0; + buf[buf_size-2] = 1; + buf[buf_size-1] = 0xb2; + + pos = 0; + GstMpeg4Packet packet; + GstMpeg4ParseResult result = GST_MPEG4_PARSER_OK; + + while (result == GST_MPEG4_PARSER_OK && pos < buf_size) { + result = gst_mpeg4_parse(&packet, FALSE, NULL, buf, pos, buf_size); + if (result != GST_MPEG4_PARSER_OK) { + break; + } + status = decode_packet(decoder, packet); + if (GST_VAAPI_DECODER_STATUS_SUCCESS == status) { + pos = packet.offset + packet.size; + } + else { + GST_WARNING("decode mp4 packet failed when decoding codec data\n"); + break; + } + } + free(buf); + return status; +} + +GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base, GstBuffer *buffer) +{ + GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4(base); + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstBuffer *codec_data = NULL; + GstVaapiDecoderStatus status; + + g_return_val_if_fail(priv->is_constructed, + GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); + + if (!priv->is_opened) { + priv->is_opened = gst_vaapi_decoder_mpeg4_open(decoder, buffer); + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + + codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); + if (codec_data) { + status = decode_codec_data(decoder, codec_data); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + } + return decode_buffer(decoder, buffer); +} + +static void +gst_vaapi_decoder_mpeg4_finalize(GObject *object) +{ + GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4(object); + + gst_vaapi_decoder_mpeg4_destroy(decoder); + + G_OBJECT_CLASS(gst_vaapi_decoder_mpeg4_parent_class)->finalize(object); +} + +static void +gst_vaapi_decoder_mpeg4_constructed(GObject *object) +{ + GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4(object); + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GObjectClass *parent_class; + + parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_mpeg4_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); + + priv->is_constructed = gst_vaapi_decoder_mpeg4_create(decoder); +} + +static void +gst_vaapi_decoder_mpeg4_class_init(GstVaapiDecoderMpeg4Class *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiDecoderMpeg4Private)); + + object_class->finalize = gst_vaapi_decoder_mpeg4_finalize; + object_class->constructed = gst_vaapi_decoder_mpeg4_constructed; + + decoder_class->decode = gst_vaapi_decoder_mpeg4_decode; +} + +static void +gst_vaapi_decoder_mpeg4_init(GstVaapiDecoderMpeg4 *decoder) +{ + GstVaapiDecoderMpeg4Private *priv; + + priv = GST_VAAPI_DECODER_MPEG4_GET_PRIVATE(decoder); + decoder->priv = priv; + priv->width = 0; + priv->height = 0; + priv->fps_n = 0; + priv->fps_d = 0; + priv->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; + priv->curr_picture = NULL; + priv->next_picture = NULL; + priv->prev_picture = NULL; + priv->tsb = NULL; + priv->sub_buffer = NULL; + priv->seq_pts = GST_CLOCK_TIME_NONE; + priv->gop_pts = GST_CLOCK_TIME_NONE; + priv->pts_diff = 0; + priv->calculate_pts_diff = TRUE; + priv->is_constructed = FALSE; + priv->is_opened = FALSE; + priv->is_first_field = FALSE; + priv->size_changed = TRUE; + priv->profile_changed = TRUE; + priv->progressive_sequence = FALSE; + priv->closed_gop = FALSE; + priv->broken_link = FALSE; +} + +/** + * gst_vaapi_decoder_mpeg4_new: + * @display: a #GstVaapiDisplay + * @caps: a #GstCaps holding codec information + * + * Creates a new #GstVaapiDecoder for MPEG-2 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_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps) +{ + GstVaapiDecoderMpeg4 *decoder; + + static const GstVaapiCodecInfo codec_info = { + .pic_size = sizeof(GstVaapiPicture), + .slice_size = sizeof(GstVaapiSlice), + .pic_param_size = sizeof(VAPictureParameterBufferMPEG4), + .slice_param_size = sizeof(VASliceParameterBufferMPEG4), + .iq_matrix_size = sizeof(VAIQMatrixBufferMPEG4), + }; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + decoder = g_object_new( + GST_VAAPI_TYPE_DECODER_MPEG4, + "display", display, + "caps", caps, + "codec-info", &codec_info, + NULL + ); + if (!decoder->priv->is_constructed) { + g_object_unref(decoder); + return NULL; + } + return GST_VAAPI_DECODER_CAST(decoder); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h new file mode 100644 index 0000000000..717994d098 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h @@ -0,0 +1,87 @@ +/* + * gstvaapidecoder_mpeg4.h - MPEG-4 decoder + * + * Copyright (C) 2011 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DECODER_MPEG4 \ + (gst_vaapi_decoder_mpeg4_get_type()) + +#define GST_VAAPI_DECODER_MPEG4(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DECODER_MPEG4, \ + GstVaapiDecoderMpeg4)) + +#define GST_VAAPI_DECODER_MPEG4_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DECODER_MPEG4, \ + GstVaapiDecoderMpeg4Class)) + +#define GST_VAAPI_IS_DECODER_MPEG4(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_MPEG4)) + +#define GST_VAAPI_IS_DECODER_MPEG4_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_MPEG4)) + +#define GST_VAAPI_DECODER_MPEG4_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DECODER_MPEG4, \ + GstVaapiDecoderMpeg4Class)) + +typedef struct _GstVaapiDecoderMpeg4 GstVaapiDecoderMpeg4; +typedef struct _GstVaapiDecoderMpeg4Private GstVaapiDecoderMpeg4Private; +typedef struct _GstVaapiDecoderMpeg4Class GstVaapiDecoderMpeg4Class; + +/** + * GstVaapiDecoderMpeg4: + * + * A decoder based on Mpeg4. + */ +struct _GstVaapiDecoderMpeg4 { + /*< private >*/ + GstVaapiDecoder parent_instance; + + GstVaapiDecoderMpeg4Private *priv; +}; + +/** + * GstVaapiDecoderMpeg4Class: + * + * A decoder class based on Mpeg4. + */ +struct _GstVaapiDecoderMpeg4Class { + /*< private >*/ + GstVaapiDecoderClass parent_class; +}; + +GType +gst_vaapi_decoder_mpeg4_get_type(void); + +GstVaapiDecoder * +gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps); + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_MPEG4_H */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 49fa80eacc..43b434951d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -51,6 +51,7 @@ #endif #if USE_CODEC_PARSERS # include +# include # include #endif @@ -315,9 +316,15 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) return FALSE; if (version == 2) decode->decoder = gst_vaapi_decoder_mpeg2_new(dpy, caps); + else if (version == 4) + decode->decoder = gst_vaapi_decoder_mpeg4_new(dpy, caps); } else if (gst_structure_has_name(structure, "video/x-wmv")) decode->decoder = gst_vaapi_decoder_vc1_new(dpy, caps); + else if (gst_structure_has_name(structure, "video/x-h263") || + gst_structure_has_name(structure, "video/x-divx") || + gst_structure_has_name(structure, "video/x-xvid")) + decode->decoder = gst_vaapi_decoder_mpeg4_new(dpy, caps); #endif } if (!decode->decoder) From c0d8f2fb1fafb04fe1fb9906a8fc83b26c513963 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Fri, 9 Dec 2011 16:44:03 +0800 Subject: [PATCH 0573/3781] mpeg4: replace GstVaapiTSB with GstAdapter (gst-plugins-base >= 0.10.24). Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 27 ++++++++++++---------- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h | 1 + 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 0da00266f8..0c4d969fde 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -32,7 +32,6 @@ #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" -#include "gstvaapiutils_tsb.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -68,7 +67,7 @@ struct _GstVaapiDecoderMpeg4Private { GstVaapiPicture *next_picture; // backward reference pic GstVaapiPicture *prev_picture; - GstVaapiTSB *tsb; + GstAdapter *adapter; GstBuffer *sub_buffer; GstClockTime seq_pts; GstClockTime gop_pts; @@ -119,9 +118,10 @@ gst_vaapi_decoder_mpeg4_close(GstVaapiDecoderMpeg4 *decoder) priv->sub_buffer = NULL; } - if (priv->tsb) { - gst_vaapi_tsb_destroy(priv->tsb); - priv->tsb = NULL; + if (priv->adapter) { + gst_adapter_clear(priv->adapter); + g_object_unref(priv->adapter); + priv->adapter = NULL; } } @@ -135,8 +135,8 @@ gst_vaapi_decoder_mpeg4_open(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) gst_vaapi_decoder_mpeg4_close(decoder); - priv->tsb = gst_vaapi_tsb_new(); - if (!priv->tsb) + priv->adapter = gst_adapter_new(); + if (!priv->adapter) return FALSE; priv->is_svh = 0; @@ -324,7 +324,7 @@ decode_sequence(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size priv->profile = profile; priv->profile_changed = TRUE; } - priv->seq_pts = gst_vaapi_tsb_get_timestamp(priv->tsb); + priv->seq_pts = gst_adapter_prev_timestamp(priv->adapter, NULL); priv->calculate_pts_diff = TRUE; priv->size_changed = TRUE; @@ -862,7 +862,8 @@ decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) if (!buf && buf_size == 0) return decode_sequence_end(decoder); - gst_vaapi_tsb_push(priv->tsb, buffer); + gst_buffer_ref(buffer); + gst_adapter_push(priv->adapter, buffer); if (priv->sub_buffer) { buffer = gst_buffer_merge(priv->sub_buffer, buffer); @@ -896,7 +897,8 @@ decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) consumed_size = packet.offset + packet.size; pos += consumed_size; - gst_vaapi_tsb_pop(priv->tsb, consumed_size); + if (gst_adapter_available(priv->adapter) >= pos) + gst_adapter_flush(priv->adapter, pos); } else { GST_WARNING("decode h263 packet failed\n"); @@ -915,7 +917,8 @@ decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) if (GST_VAAPI_DECODER_STATUS_SUCCESS == status) { consumed_size = packet.offset + packet.size - pos; pos = packet.offset + packet.size; - gst_vaapi_tsb_pop(priv->tsb, consumed_size); + if (gst_adapter_available(priv->adapter) >= pos) + gst_adapter_flush(priv->adapter, pos); } else { GST_WARNING("decode mp4 packet failed\n"); @@ -1051,7 +1054,7 @@ gst_vaapi_decoder_mpeg4_init(GstVaapiDecoderMpeg4 *decoder) priv->curr_picture = NULL; priv->next_picture = NULL; priv->prev_picture = NULL; - priv->tsb = NULL; + priv->adapter = NULL; priv->sub_buffer = NULL; priv->seq_pts = GST_CLOCK_TIME_NONE; priv->gop_pts = GST_CLOCK_TIME_NONE; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h index 717994d098..753c60d377 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h @@ -23,6 +23,7 @@ #define GST_VAAPI_DECODER_MPEG4_H #include +#include G_BEGIN_DECLS From 14cc1cf061127564de84f1b1478bd55d36333ed7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 16 Jan 2012 10:41:10 +0100 Subject: [PATCH 0574/3781] legal: fix copyright notices to include "Copyright" term. --- gst-libs/gst/vaapi/gstvaapi_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapicompat.h | 2 +- gst-libs/gst/vaapi/gstvaapicontext.c | 2 +- gst-libs/gst/vaapi/gstvaapicontext.h | 2 +- gst-libs/gst/vaapi/gstvaapidebug.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.h | 2 +- gst-libs/gst/vaapi/gstvaapiimageformat.c | 2 +- gst-libs/gst/vaapi/gstvaapiimageformat.h | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.c | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.h | 2 +- gst-libs/gst/vaapi/gstvaapiobject.c | 2 +- gst-libs/gst/vaapi/gstvaapiobject.h | 2 +- gst-libs/gst/vaapi/gstvaapiobject_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiparamspecs.c | 2 +- gst-libs/gst/vaapi/gstvaapiparamspecs.h | 2 +- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- gst-libs/gst/vaapi/gstvaapiprofile.h | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.h | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 2 +- gst-libs/gst/vaapi/gstvaapitexture.c | 2 +- gst-libs/gst/vaapi/gstvaapitexture.h | 2 +- gst-libs/gst/vaapi/gstvaapitypes.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapivalue.c | 2 +- gst-libs/gst/vaapi/gstvaapivalue.h | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.h | 2 +- gst-libs/gst/vaapi/gstvaapivideosink.c | 2 +- gst-libs/gst/vaapi/gstvaapivideosink.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 2 +- gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapidecode.h | 2 +- gst/vaapi/gstvaapidownload.c | 2 +- gst/vaapi/gstvaapidownload.h | 2 +- gst/vaapi/gstvaapisink.c | 2 +- gst/vaapi/gstvaapisink.h | 2 +- gst/vaapi/gstvaapiupload.c | 2 +- gst/vaapi/gstvaapiupload.h | 2 +- tests/image.c | 2 +- tests/image.h | 2 +- tests/test-decode.c | 2 +- tests/test-decode.h | 2 +- tests/test-display.c | 2 +- tests/test-h264.c | 2 +- tests/test-h264.h | 2 +- tests/test-mpeg2.c | 2 +- tests/test-mpeg2.h | 2 +- tests/test-surfaces.c | 2 +- tests/test-textures.c | 2 +- tests/test-vc1.c | 2 +- tests/test-vc1.h | 2 +- tests/test-windows.c | 2 +- 85 files changed, 85 insertions(+), 85 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapi_priv.h b/gst-libs/gst/vaapi/gstvaapi_priv.h index 99d09b901b..8416b83386 100644 --- a/gst-libs/gst/vaapi/gstvaapi_priv.h +++ b/gst-libs/gst/vaapi/gstvaapi_priv.h @@ -1,7 +1,7 @@ /* * gstvaapi_priv.h - Helper to include all private headers * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index bf4385d36e..756474aab3 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -1,7 +1,7 @@ /* * gstvapicompat.h - VA-API compatibility glue * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index f982fe02dc..d26cea2f8c 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -1,7 +1,7 @@ /* * gstvaapicontext.c - VA context abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 457570c054..6168def176 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -1,7 +1,7 @@ /* * gstvaapicontext.h - VA context abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidebug.h b/gst-libs/gst/vaapi/gstvaapidebug.h index f0359cf726..d743c741fc 100644 --- a/gst-libs/gst/vaapi/gstvaapidebug.h +++ b/gst-libs/gst/vaapi/gstvaapidebug.h @@ -1,7 +1,7 @@ /* * gstvaapidebug.h - VA-API debugging utilities * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index adb1b1871e..bec3e62b29 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder.c - VA decoder abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 02ce20330d..0306689be9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder.h - VA decoder abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 7224bcd3fb..c1dc70b7e3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_ffmpeg.c - FFmpeg-based decoder * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h index 68c61ee7d0..746d16d1e0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_ffmpeg.h - FFmpeg-based decoder * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 478daa86b7..4cf0b18e9a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_priv.h - VA decoder abstraction (private definitions) * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 4790810fbd..5b43e435de 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1,7 +1,7 @@ /* * gstvaapidisplay.c - VA display abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 616f74349d..375ce443bc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay.h - VA display abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index cd74789a38..da86625d51 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -1,7 +1,7 @@ /* * gstvaapidisplay_glx.c - VA/GLX display abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index abb9d1bf6a..b7135a6800 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_glx.h - VA/GLX display abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index 48b4bac5fb..a843b38407 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_glx_priv.h - Internal VA/GLX interface * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 76b58a7568..2892f0d3b0 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_priv.h - Base VA display (private definitions) * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 36b0a99f41..a8a21f84f4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -1,7 +1,7 @@ /* * gstvaapidisplay_x11.c - VA/X11 display abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 71c8a8ded8..ab6d0ec4c4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_x11.h - VA/X11 display abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index b717d2f129..a1b9213e95 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_x11_priv.h - Internal VA/X11 interface * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 49a19e5be2..00dfd03fcb 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -1,7 +1,7 @@ /* * gstvaapiimage.c - VA image abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index a2b5ba2c87..2fa6ee42e8 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -1,7 +1,7 @@ /* * gstvaapiimage.h - VA image abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index cac410afd3..763bbe1a7f 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -1,7 +1,7 @@ /* * gstvaapiimageformat.c - VA image format abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index da45341b63..25305d1960 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -1,7 +1,7 @@ /* * gstvaapiimageformat.h - VA image format abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index e5738cea21..3332931d91 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -1,7 +1,7 @@ /* * gstvaapiimagepool.c - Gst VA image pool * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index 70f8a6b393..139a8505e2 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -1,7 +1,7 @@ /* * gstvaapiimagepool.h - Gst VA image pool * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 66cbb3024e..f2106eb3d7 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -1,7 +1,7 @@ /* * gstvaapiobject.c - Base VA object * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index 066b0865e3..fbb4aef76e 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -1,7 +1,7 @@ /* * gstvaapiobject.h - Base VA object * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 825b21cb77..d84b7b0d68 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -1,7 +1,7 @@ /* * gstvaapiobject_priv.h - Base VA object (private definitions) * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.c b/gst-libs/gst/vaapi/gstvaapiparamspecs.c index 41d5fe6ca2..cac4027d43 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.c +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.c @@ -1,7 +1,7 @@ /* * gstvaapiparamspecs.c - GParamSpecs for some of our types * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.h b/gst-libs/gst/vaapi/gstvaapiparamspecs.h index 6bfb28996e..b22416e9d0 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.h +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.h @@ -1,7 +1,7 @@ /* * gstvaapiparamspecs.h - GParamSpecs for some of our types * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 67a3f57cce..1c95bbb670 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -1,7 +1,7 @@ /* * gstvaapiprofile.c - VA profile abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 1da138165f..c144a915b2 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -1,7 +1,7 @@ /* * gstvaapiprofile.h - VA profile abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 2776b7230a..58221c4a17 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -1,7 +1,7 @@ /* * gstvaapisubpicture.c - VA subpicture abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index afbd2507c2..c199684dca 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -1,7 +1,7 @@ /* * gstvaapisubpicture.h - VA subpicture abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index c29b1ba13e..350c5294ba 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -1,7 +1,7 @@ /* * gstvaapisurface.c - VA surface abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index ce9bd9e8d2..0bd8139936 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -1,7 +1,7 @@ /* * gstvaapisurface.h - VA surface abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index a68be6410e..8fe9d5d9da 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -1,7 +1,7 @@ /* * gstvaapisurfacepool.c - Gst VA surface pool * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index dfcef4d763..1a7c30a535 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -1,7 +1,7 @@ /* * gstvaapisurfacepool.h - Gst VA surface pool * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index fc21208228..c67e8cbe94 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -1,7 +1,7 @@ /* * gstvaapisurfaceproxy.c - VA surface proxy * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 8eab401bd6..cf8f5b2d9f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -1,7 +1,7 @@ /* * gstvaapisurfaceproxy.h - VA surface proxy * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index f9a84f50ab..0b7092943b 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -1,7 +1,7 @@ /* * gstvaapitexture.c - VA texture abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index a92c01529e..1b67a5b1b5 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -1,7 +1,7 @@ /* * gstvaapitexture.h - VA texture abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index c0b555a5b9..a6312b1f85 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -1,7 +1,7 @@ /* * gstvaapitypes.h - Basic types * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 5e6eb6ef6e..ca9b3c6ce8 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -1,7 +1,7 @@ /* * gstvaapiutils.c - VA-API utilities * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index c626429745..3c05d1c476 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -1,7 +1,7 @@ /* * gstvaapiutils.h - VA-API utilities * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 23ea8b7100..3ebb568031 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -1,7 +1,7 @@ /* * gstvaapiutils_glx.c - GLX utilties * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 357b0fd333..c5c7a0c0e2 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -1,7 +1,7 @@ /* * gstvaapiutils_glx.h - GLX utilties * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 9c0852dfc5..fb64295349 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -1,7 +1,7 @@ /* * gstvaapiutils_x11.c - X11 utilties * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index df43f5bf41..a031168e99 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -1,7 +1,7 @@ /* * gstvaapiutils_x11.h - X11 utilties * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 44db35aec4..1b3da64d84 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -1,7 +1,7 @@ /* * gstvaapivalue.c - GValue implementations specific to VA-API * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index 8ba1985235..a3834d2d98 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -1,7 +1,7 @@ /* * gstvaapivalue.h - GValue implementations specific to VA-API * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 6814663e15..9baf2aef08 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -1,7 +1,7 @@ /* * gstvaapivideobuffer.c - Gst VA video buffer * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index 1ea745bbd3..965aca18bc 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -1,7 +1,7 @@ /* * gstvaapivideobuffer.h - Gstreamer/VA video buffer * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 47a039f97e..ec70be992a 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -1,7 +1,7 @@ /* * gstvaapivideopool.c - Video object pool abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 21fe1a7b37..12266178ec 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -1,7 +1,7 @@ /* * gstvaapivideopool.h - Video object pool abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.c b/gst-libs/gst/vaapi/gstvaapivideosink.c index 7ba672039a..8f511d4ee1 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.c +++ b/gst-libs/gst/vaapi/gstvaapivideosink.c @@ -1,7 +1,7 @@ /* * gstvaapivideosink.c - VA sink interface * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.h b/gst-libs/gst/vaapi/gstvaapivideosink.h index 01bf01ba04..e9a17b4e9c 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.h +++ b/gst-libs/gst/vaapi/gstvaapivideosink.h @@ -1,7 +1,7 @@ /* * gstvaapivideosink.h - VA sink interface * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 58a9841381..35e10451f6 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -1,7 +1,7 @@ /* * gstvaapiwindow.c - VA window abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 7743d615da..f5b6ee0ea6 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -1,7 +1,7 @@ /* * gstvaapiwindow.h - VA window abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index cb132ca0a3..447318ed10 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -1,7 +1,7 @@ /* * gstvaapiwindow_glx.c - VA/GLX window abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index fb896a72b6..96b7f4e6b4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -1,7 +1,7 @@ /* * gstvaapiwindow_glx.h - VA/GLX window abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index f41e3aa83a..d1f7d5ac09 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -1,7 +1,7 @@ /* * gstvaapiwindow_x11.c - VA/X11 window abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index b720a8ecc4..9488703eef 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -1,7 +1,7 @@ /* * gstvaapiwindow_x11.h - VA/X11 window abstraction * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 43b434951d..80c74e8544 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1,7 +1,7 @@ /* * gstvaapidecode.c - VA-API video decoder * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index f288583feb..6725bcbf57 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -1,7 +1,7 @@ /* * gstvaapidecode.h - VA-API video decoder * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 2c02535572..fdf4f22e95 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -1,7 +1,7 @@ /* * gstvaapidownload.c - VA-API video downloader * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapidownload.h b/gst/vaapi/gstvaapidownload.h index b15235aa91..4f800b1419 100644 --- a/gst/vaapi/gstvaapidownload.h +++ b/gst/vaapi/gstvaapidownload.h @@ -1,7 +1,7 @@ /* * gstvaapidownload.h - VA-API video downloader * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 9000fedcd2..d0e0ca6bbf 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1,7 +1,7 @@ /* * gstvaapisink.c - VA-API video sink * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 221e452f77..06479d1344 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -1,7 +1,7 @@ /* * gstvaapisink.h - VA-API video sink * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 7a47b2fbbe..e4fbd5d69b 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -1,7 +1,7 @@ /* * gstvaapiupload.c - VA-API video uploader * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapiupload.h b/gst/vaapi/gstvaapiupload.h index 07e57717a7..776a638f38 100644 --- a/gst/vaapi/gstvaapiupload.h +++ b/gst/vaapi/gstvaapiupload.h @@ -1,7 +1,7 @@ /* * gstvaapiupload.h - VA-API video uploader * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/image.c b/tests/image.c index 20f1c02017..39a8ac5e7e 100644 --- a/tests/image.c +++ b/tests/image.c @@ -1,7 +1,7 @@ /* * image.c - Image utilities for the tests * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/image.h b/tests/image.h index a837d9754b..f9580650ed 100644 --- a/tests/image.h +++ b/tests/image.h @@ -1,7 +1,7 @@ /* * image.h - Image utilities for the tests * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-decode.c b/tests/test-decode.c index 835400be99..9b39734b3f 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -1,7 +1,7 @@ /* * test-decode.c - Test GstVaapiDecoder * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-decode.h b/tests/test-decode.h index 59a02116c4..147f51c9d9 100644 --- a/tests/test-decode.h +++ b/tests/test-decode.h @@ -1,7 +1,7 @@ /* * test-decode.h - Test GstVaapiDecoder * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-display.c b/tests/test-display.c index b3b734bb43..302fc31675 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -1,7 +1,7 @@ /* * test-display.c - Test GstVaapiDisplayX11 * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-h264.c b/tests/test-h264.c index a0a361b64a..e25c3927be 100644 --- a/tests/test-h264.c +++ b/tests/test-h264.c @@ -1,7 +1,7 @@ /* * test-h264.c - H.264 test data * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-h264.h b/tests/test-h264.h index 9bc0a9aca2..93b79cabe0 100644 --- a/tests/test-h264.h +++ b/tests/test-h264.h @@ -1,7 +1,7 @@ /* * test-h264.h - H.264 test data * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-mpeg2.c b/tests/test-mpeg2.c index 2f5d17c46c..3e75143a9e 100644 --- a/tests/test-mpeg2.c +++ b/tests/test-mpeg2.c @@ -1,7 +1,7 @@ /* * test-mpeg2.c - MPEG-2 test data * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-mpeg2.h b/tests/test-mpeg2.h index b81adf093e..c43154dbc7 100644 --- a/tests/test-mpeg2.h +++ b/tests/test-mpeg2.h @@ -1,7 +1,7 @@ /* * test-mpeg2.h - MPEG-2 test data * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index 17e97516c5..a6edb348bd 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -1,7 +1,7 @@ /* * test-surfaces.c - Test GstVaapiSurface and GstVaapiSurfacePool * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-textures.c b/tests/test-textures.c index 27497b1d7c..7bf40fd3a8 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -1,7 +1,7 @@ /* * test-textures.c - Test GstVaapiTexture * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-vc1.c b/tests/test-vc1.c index 4feb0ba046..60170f1628 100644 --- a/tests/test-vc1.c +++ b/tests/test-vc1.c @@ -1,7 +1,7 @@ /* * test-vc1.c - VC-1 test data * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-vc1.h b/tests/test-vc1.h index e659c486fa..1d785043c5 100644 --- a/tests/test-vc1.h +++ b/tests/test-vc1.h @@ -1,7 +1,7 @@ /* * test-vc1.h - VC-1 test data * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-windows.c b/tests/test-windows.c index 6862d1290b..56c316883a 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -1,7 +1,7 @@ /* * test-windows.c - Test GstVaapiWindow * - * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2010-2011 Splitted-Desktop Systems * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License From 1594d99d5589784107d6b306213b6e7a2cfa4038 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 16 Jan 2012 10:42:55 +0100 Subject: [PATCH 0575/3781] legal: add Intel copyright on modified files. --- gst-libs/gst/vaapi/gstvaapicontext.c | 1 + gst-libs/gst/vaapi/gstvaapicontext.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 1 + gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay.h | 1 + gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 1 + gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 1 + gst-libs/gst/vaapi/gstvaapiimage.c | 1 + gst-libs/gst/vaapi/gstvaapiimage.h | 1 + gst-libs/gst/vaapi/gstvaapiimageformat.c | 1 + gst-libs/gst/vaapi/gstvaapiimageformat.h | 1 + gst-libs/gst/vaapi/gstvaapisubpicture.c | 1 + gst-libs/gst/vaapi/gstvaapisubpicture.h | 1 + gst-libs/gst/vaapi/gstvaapisurface.c | 1 + gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 1 + gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 1 + gst-libs/gst/vaapi/gstvaapiutils.c | 1 + gst-libs/gst/vaapi/gstvaapiutils.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_glx.c | 1 + gst-libs/gst/vaapi/gstvaapiutils_x11.c | 1 + gst-libs/gst/vaapi/gstvaapivideobuffer.c | 1 + gst-libs/gst/vaapi/gstvaapivideobuffer.h | 1 + gst-libs/gst/vaapi/gstvaapiwindow.c | 1 + gst/vaapi/gstvaapidownload.h | 1 + gst/vaapi/gstvaapisink.h | 1 + gst/vaapi/gstvaapiupload.h | 1 + tests/test-decode.c | 1 + 29 files changed, 29 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index d26cea2f8c..1a262ec540 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -2,6 +2,7 @@ * gstvaapicontext.c - VA context abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 6168def176..78f9b28289 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -2,6 +2,7 @@ * gstvaapicontext.h - VA context abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 0306689be9..910dfc5fb1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -2,6 +2,7 @@ * gstvaapidecoder.h - VA decoder abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 4cf0b18e9a..07c740bca7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -2,6 +2,7 @@ * gstvaapidecoder_priv.h - VA decoder abstraction (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 5b43e435de..f670a68915 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -2,6 +2,7 @@ * gstvaapidisplay.c - VA display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 375ce443bc..eb6bf2651b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -2,6 +2,7 @@ * gstvaapidisplay.h - VA display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index da86625d51..94e9dfc7e4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -2,6 +2,7 @@ * gstvaapidisplay_glx.c - VA/GLX display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 2892f0d3b0..ab0c1d5698 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -2,6 +2,7 @@ * gstvaapidisplay_priv.h - Base VA display (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index a8a21f84f4..68ddf347da 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -2,6 +2,7 @@ * gstvaapidisplay_x11.c - VA/X11 display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 00dfd03fcb..f063b540f0 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -2,6 +2,7 @@ * gstvaapiimage.c - VA image abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 2fa6ee42e8..b4642c9239 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -2,6 +2,7 @@ * gstvaapiimage.h - VA image abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 763bbe1a7f..a910b03c58 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -2,6 +2,7 @@ * gstvaapiimageformat.c - VA image format abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index 25305d1960..56af2a4e0c 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -2,6 +2,7 @@ * gstvaapiimageformat.h - VA image format abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 58221c4a17..000ab27bde 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -2,6 +2,7 @@ * gstvaapisubpicture.c - VA subpicture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index c199684dca..7a0dd96a84 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -2,6 +2,7 @@ * gstvaapisubpicture.h - VA subpicture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 350c5294ba..e0b614ea09 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -2,6 +2,7 @@ * gstvaapisurface.c - VA surface abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index c67e8cbe94..65d58db0bb 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -2,6 +2,7 @@ * gstvaapisurfaceproxy.c - VA surface proxy * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index cf8f5b2d9f..b1b6ff5254 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -2,6 +2,7 @@ * gstvaapisurfaceproxy.h - VA surface proxy * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index ca9b3c6ce8..e2ad756e1b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -2,6 +2,7 @@ * gstvaapiutils.c - VA-API utilities * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 3c05d1c476..ded19b368b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -2,6 +2,7 @@ * gstvaapiutils.h - VA-API utilities * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 3ebb568031..9080868c85 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -2,6 +2,7 @@ * gstvaapiutils_glx.c - GLX utilties * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index fb64295349..76dd78813a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -2,6 +2,7 @@ * gstvaapiutils_x11.c - X11 utilties * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 9baf2aef08..3b6c98db6b 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -2,6 +2,7 @@ * gstvaapivideobuffer.c - Gst VA video buffer * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index 965aca18bc..d076b43cc8 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -2,6 +2,7 @@ * gstvaapivideobuffer.h - Gstreamer/VA video buffer * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 35e10451f6..efd4952229 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -2,6 +2,7 @@ * gstvaapiwindow.c - VA window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapidownload.h b/gst/vaapi/gstvaapidownload.h index 4f800b1419..56923db4df 100644 --- a/gst/vaapi/gstvaapidownload.h +++ b/gst/vaapi/gstvaapidownload.h @@ -2,6 +2,7 @@ * gstvaapidownload.h - VA-API video downloader * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 06479d1344..368a2d2b73 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -2,6 +2,7 @@ * gstvaapisink.h - VA-API video sink * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiupload.h b/gst/vaapi/gstvaapiupload.h index 776a638f38..b3371e7aaf 100644 --- a/gst/vaapi/gstvaapiupload.h +++ b/gst/vaapi/gstvaapiupload.h @@ -2,6 +2,7 @@ * gstvaapiupload.h - VA-API video uploader * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-decode.c b/tests/test-decode.c index 9b39734b3f..8d52cc3d66 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -2,6 +2,7 @@ * test-decode.c - Test GstVaapiDecoder * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License From 92f11799d1e3498814790754d2ed720e9bc87a66 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 16 Jan 2012 11:03:51 +0100 Subject: [PATCH 0576/3781] legal: fix year for some copyright notices. --- README | 2 +- debian.upstream/copyright | 2 +- gst-libs/gst/vaapi/gstvaapicontext.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.c | 2 +- gst/vaapi/gstvaapi.c | 2 +- gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapidownload.c | 2 +- gst/vaapi/gstvaapidownload.h | 2 +- gst/vaapi/gstvaapipluginutil.c | 2 +- gst/vaapi/gstvaapipluginutil.h | 2 +- gst/vaapi/gstvaapisink.c | 2 +- gst/vaapi/gstvaapiupload.c | 2 +- gst/vaapi/gstvaapiupload.h | 2 +- tests/test-decode.c | 2 +- 29 files changed, 29 insertions(+), 29 deletions(-) diff --git a/README b/README index 6c10464554..2b96af450c 100644 --- a/README +++ b/README @@ -3,7 +3,7 @@ VA-API support to GStreamer Copyright (C) 2010-2011 Splitted-Desktop Systems - Copyright (C) 2011 Intel Corporation + Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora Ltd. diff --git a/debian.upstream/copyright b/debian.upstream/copyright index 7e8e8c8f8c..bb733ae5a7 100644 --- a/debian.upstream/copyright +++ b/debian.upstream/copyright @@ -9,7 +9,7 @@ Copyright: License: Copyright (C) 2010-2011, Splitted-Desktop Systems. - Copyright (C) 2011, Intel Corporation. + Copyright (C) 2011-2012, Intel Corporation. Copyright (C) 2011, Collabora Ltd. gstreamer-vaapi helper libraries and plugins elements are available under diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 1a262ec540..af57feb9a5 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -2,7 +2,7 @@ * gstvaapicontext.c - VA context abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index bec3e62b29..4442f1015c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -2,7 +2,7 @@ * gstvaapidecoder.c - VA decoder abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index c1dc70b7e3..8fb9099d8e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -2,7 +2,7 @@ * gstvaapidecoder_ffmpeg.c - FFmpeg-based decoder * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 07c740bca7..3a6cda171c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -2,7 +2,7 @@ * gstvaapidecoder_priv.h - VA decoder abstraction (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index f670a68915..94c6e67c5f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -2,7 +2,7 @@ * gstvaapidisplay.c - VA display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index eb6bf2651b..33d7a234e6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -2,7 +2,7 @@ * gstvaapidisplay.h - VA display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 94e9dfc7e4..29950e8858 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -2,7 +2,7 @@ * gstvaapidisplay_glx.c - VA/GLX display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index ab0c1d5698..80ec99a287 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -2,7 +2,7 @@ * gstvaapidisplay_priv.h - Base VA display (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 68ddf347da..f4bd52c6e5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -2,7 +2,7 @@ * gstvaapidisplay_x11.c - VA/X11 display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index f063b540f0..9cd2639989 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -2,7 +2,7 @@ * gstvaapiimage.c - VA image abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index b4642c9239..3178b68ba4 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -2,7 +2,7 @@ * gstvaapiimage.h - VA image abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 65d58db0bb..747d00f284 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -2,7 +2,7 @@ * gstvaapisurfaceproxy.c - VA surface proxy * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index b1b6ff5254..6cc4dea9ed 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -2,7 +2,7 @@ * gstvaapisurfaceproxy.h - VA surface proxy * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index e2ad756e1b..97518cf274 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -2,7 +2,7 @@ * gstvaapiutils.c - VA-API utilities * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index ded19b368b..ac6a38f270 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -2,7 +2,7 @@ * gstvaapiutils.h - VA-API utilities * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 9080868c85..527c07cb2d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -2,7 +2,7 @@ * gstvaapiutils_glx.c - GLX utilties * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index efd4952229..749b88d307 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -2,7 +2,7 @@ * gstvaapiwindow.c - VA window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 89db5e764b..2ca04c5f20 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -1,7 +1,7 @@ /* * gstvaapi.c - VA-API element registration * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * Copyright (C) 2011 Collabora Ltd. * Author: Nicolas Dufresne * diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 80c74e8544..7193b2c916 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -2,7 +2,7 @@ * gstvaapidecode.c - VA-API video decoder * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index fdf4f22e95..3a5df38e46 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -2,7 +2,7 @@ * gstvaapidownload.c - VA-API video downloader * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapidownload.h b/gst/vaapi/gstvaapidownload.h index 56923db4df..70df9b9a9d 100644 --- a/gst/vaapi/gstvaapidownload.h +++ b/gst/vaapi/gstvaapidownload.h @@ -2,7 +2,7 @@ * gstvaapidownload.h - VA-API video downloader * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 0db0908169..782304bf82 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1,7 +1,7 @@ /* * gstvaapipluginutil.h - VA-API plugin helpers * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * Copyright (C) 2011 Collabora * Author: Nicolas Dufresne * diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 704ed370f7..e879cd470a 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -1,7 +1,7 @@ /* * gstvaapipluginutil.h - VA-API plugins private helper * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * Copyright (C) 2011 Collabora * Author: Nicolas Dufresne * diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index d0e0ca6bbf..cc78a96d45 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -2,7 +2,7 @@ * gstvaapisink.c - VA-API video sink * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index e4fbd5d69b..9ba73666b8 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -2,7 +2,7 @@ * gstvaapiupload.c - VA-API video uploader * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiupload.h b/gst/vaapi/gstvaapiupload.h index b3371e7aaf..425054ec08 100644 --- a/gst/vaapi/gstvaapiupload.h +++ b/gst/vaapi/gstvaapiupload.h @@ -2,7 +2,7 @@ * gstvaapiupload.h - VA-API video uploader * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-decode.c b/tests/test-decode.c index 8d52cc3d66..e0b461d607 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -2,7 +2,7 @@ * test-decode.c - Test GstVaapiDecoder * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License From fbb5215c6a62b63db85c59994c07f54befb6a2be Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 16 Jan 2012 11:05:31 +0100 Subject: [PATCH 0577/3781] 0.3.3. --- NEWS | 7 ++++--- configure.ac | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 33f7c856dc..49c4dfa865 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2012-01-06 +gst-vaapi NEWS -- summary of changes. 2012-01-16 Copyright (C) 2010-2011 Splitted-Desktop Systems -Copyright (C) 2011 Intel Corporation +Copyright (C) 2011-2012 Intel Corporation +Copyright (C) 2011 Collabora -Version 0.3.3 - DD.Jan.2012 +Version 0.3.3 - 16.Jan.2012 * Add MPEG-2, MPEG-4 and VC-1 decoders (based on codecparsers) * Add support for GstXOverlay::set_render_rectangle() in vaapisink * Fix memory leak of GL texture (Nicolas Dufresne) diff --git a/configure.ac b/configure.ac index 78b5b9ea52..d061ba759b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) m4_define([gst_vaapi_micro_version], [3]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 35d33b13f653e08b24666b1dd0b448c1c122c2de Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 16 Jan 2012 14:09:57 +0100 Subject: [PATCH 0578/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index d061ba759b..9a5ff8401f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) -m4_define([gst_vaapi_micro_version], [3]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [4]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 9f5c48759394056515bd1a077a9e6040ef7c9051 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 16 Jan 2012 14:19:00 +0100 Subject: [PATCH 0579/3781] tests: fix build without FFmpeg. --- tests/Makefile.am | 2 +- tests/test-subpicture.c | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 2f54941549..d01a6de54c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -56,7 +56,7 @@ test_surfaces_SOURCES = test-surfaces.c test_surfaces_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) test_surfaces_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) -test_subpicture_SOURCES = test-subpicture.c test-h264.c test-subpicture-data.c +test_subpicture_SOURCES = test-subpicture.c test-mpeg2.c test-subpicture-data.c test_subpicture_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) test_subpicture_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index e273e919b2..f9f0052e41 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -20,15 +20,22 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" #include #include #include #include -#include #include -#include "test-h264.h" +#include "test-mpeg2.h" #include "test-subpicture-data.h" +#if USE_FFMPEG +# include +#endif +#if USE_CODEC_PARSERS +# include +#endif + typedef void (*GetVideoInfoFunc)(VideoDecodeInfo *info); typedef struct _CodecDefs CodecDefs; @@ -39,7 +46,7 @@ struct _CodecDefs { static const CodecDefs g_codec_defs[] = { #define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info } - INIT_FUNCS(h264), + INIT_FUNCS(mpeg2), #undef INIT_FUNCS { NULL, } }; @@ -89,7 +96,7 @@ main(int argc, char *argv[]) GOptionContext *options; GstVaapiDisplay *display; GstVaapiWindow *window; - GstVaapiDecoder *decoder; + GstVaapiDecoder *decoder = NULL; GstCaps *decoder_caps; GstStructure *structure; GstVaapiDecoderStatus status; @@ -116,7 +123,7 @@ main(int argc, char *argv[]) g_option_context_free(options); if (!g_codec_str) - g_codec_str = g_strdup("h264"); + g_codec_str = g_strdup("mpeg2"); g_print("Test %s decode\n", g_codec_str); codec = get_codec_defs(g_codec_str); @@ -145,9 +152,15 @@ main(int argc, char *argv[]) NULL ); - decoder = gst_vaapi_decoder_ffmpeg_new(display, decoder_caps); +#if USE_CODEC_PARSERS + decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); +#endif +#if USE_FFMPEG if (!decoder) - g_error("could not create FFmpeg decoder"); + decoder = gst_vaapi_decoder_ffmpeg_new(display, decoder_caps); +#endif + if (!decoder) + g_error("could not create video decoder"); gst_caps_unref(decoder_caps); buffer = gst_buffer_new(); From 0f511e1e0b3e4c8e0d05682ec3c98838ec97e66d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 18 Jan 2012 10:42:38 +0100 Subject: [PATCH 0580/3781] surface: don't expose gst_vaapi_surface_get_parent_context(). gst_vaapi_surface_get_parent_context() was not meant to be exposed globally. It's just an internal helper function. However, it's still possible to get the parent context through the "parent-context" property. --- docs/reference/libs/libs-sections.txt | 1 - gst-libs/gst/vaapi/gstvaapisurface.h | 4 ---- gst-libs/gst/vaapi/gstvaapisurface_priv.h | 5 +++++ 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 46da57a15f..b4fd5130d7 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -334,7 +334,6 @@ gst_vaapi_surface_get_chroma_type gst_vaapi_surface_get_width gst_vaapi_surface_get_height gst_vaapi_surface_get_size -gst_vaapi_surface_get_parent_context gst_vaapi_surface_derive_image gst_vaapi_surface_get_image gst_vaapi_surface_put_image diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 0bd8139936..9057290b49 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -35,7 +35,6 @@ G_BEGIN_DECLS typedef enum _GstVaapiChromaType GstVaapiChromaType; typedef enum _GstVaapiSurfaceStatus GstVaapiSurfaceStatus; typedef enum _GstVaapiSurfaceRenderFlags GstVaapiSurfaceRenderFlags; -typedef struct _GstVaapiContext GstVaapiContext; /** * GST_VAAPI_SURFACE_CAPS_NAME: @@ -198,9 +197,6 @@ gst_vaapi_surface_get_size( guint *pheight ); -GstVaapiContext * -gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface); - GstVaapiImage * gst_vaapi_surface_derive_image(GstVaapiSurface *surface); diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index 7c99c69ae7..a7eeda91d1 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -22,6 +22,7 @@ #ifndef GST_VAAPI_SURFACE_PRIV_H #define GST_VAAPI_SURFACE_PRIV_H +#include #include void @@ -30,4 +31,8 @@ gst_vaapi_surface_set_parent_context( GstVaapiContext *context ) attribute_hidden; +GstVaapiContext * +gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface) + attribute_hidden; + #endif /* GST_VAAPI_SURFACE_PRIV_H */ From a9f79c9251994e382688ca44e34dfaa91ae41152 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 18 Jan 2012 10:47:56 +0100 Subject: [PATCH 0581/3781] tests: error out if FFmpeg|codecparsers are not supported. --- tests/test-decode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test-decode.c b/tests/test-decode.c index e0b461d607..3758137244 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -158,6 +158,8 @@ main(int argc, char *argv[]) if (g_use_ffmpeg) { #if USE_FFMPEG decoder = gst_vaapi_decoder_ffmpeg_new(display, decoder_caps); +#else + g_error("FFmpeg-based decoders are not supported"); #endif } else { @@ -173,6 +175,8 @@ main(int argc, char *argv[]) decoder = NULL; break; } +#else + g_error("codecparsers-based decoders are not supported"); #endif } if (!decoder) From 29623239b9a0eda74a102e603c4375d8961a9fc2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jan 2012 10:06:37 +0100 Subject: [PATCH 0582/3781] Add template for workarounds. --- gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapiworkarounds.h | 29 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiworkarounds.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 8623b5fe44..68c76dbcf9 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -86,6 +86,7 @@ libgstvaapi_source_priv_h = \ gstvaapiutils.h \ gstvaapiutils_tsb.h \ gstvaapivideobuffer_priv.h \ + gstvaapiworkarounds.h \ $(libgst_vaapi_ffmpeg_source_priv_h) \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapiworkarounds.h b/gst-libs/gst/vaapi/gstvaapiworkarounds.h new file mode 100644 index 0000000000..a0cbde77fc --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiworkarounds.h @@ -0,0 +1,29 @@ +/* + * gstvaapiworkaround.h - GStreamer/VA workarounds + * + * Copyright (C) 2011-2012 Intel Corporation + * + * 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_WORKAROUNDS_H +#define GST_VAAPI_WORKAROUNDS_H + +G_BEGIN_DECLS + +G_END_DECLS + +#endif /* GST_VAAPI_WORKAROUNDS_H */ From c42ba571a8acac44a18625b17c446e0d76a00ffc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 18 Jan 2012 10:22:58 +0100 Subject: [PATCH 0583/3781] display: report H.263 Baseline profile. HACK: expose GST_VAAPI_PROFILE_H263_BASELINE for decoding if MPEG-4:2 Simple profile (VAProfileMPEG4Simple) is supported. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 32 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiworkarounds.h | 6 +++++ 2 files changed, 38 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 94c6e67c5f..e975c638d6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -30,6 +30,7 @@ #include "gstvaapiutils.h" #include "gstvaapidisplay.h" #include "gstvaapidisplay_priv.h" +#include "gstvaapiworkarounds.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -182,6 +183,36 @@ find_config( return FALSE; } +/* HACK: append H.263 Baseline profile if MPEG-4:2 Simple profile is supported */ +static void +append_h263_config(GArray *configs) +{ + GstVaapiConfig *config, tmp_config; + GstVaapiConfig *mpeg4_simple_config = NULL; + GstVaapiConfig *h263_baseline_config = NULL; + guint i; + + if (!WORKAROUND_H263_BASELINE_DECODE_PROFILE) + return; + + if (!configs) + return; + + for (i = 0; i < configs->len; i++) { + config = &g_array_index(configs, GstVaapiConfig, i); + if (config->profile == GST_VAAPI_PROFILE_MPEG4_SIMPLE) + mpeg4_simple_config = config; + else if (config->profile == GST_VAAPI_PROFILE_H263_BASELINE) + h263_baseline_config = config; + } + + if (mpeg4_simple_config && !h263_baseline_config) { + tmp_config = *mpeg4_simple_config; + tmp_config.profile = GST_VAAPI_PROFILE_H263_BASELINE; + g_array_append_val(configs, tmp_config); + } +} + /* Convert configs array to profiles as GstCaps */ static GstCaps * get_profile_caps(GArray *configs) @@ -439,6 +470,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) } } } + append_h263_config(priv->decoders); /* VA image formats */ formats = g_new(VAImageFormat, vaMaxNumImageFormats(priv->display)); diff --git a/gst-libs/gst/vaapi/gstvaapiworkarounds.h b/gst-libs/gst/vaapi/gstvaapiworkarounds.h index a0cbde77fc..b060b13cc9 100644 --- a/gst-libs/gst/vaapi/gstvaapiworkarounds.h +++ b/gst-libs/gst/vaapi/gstvaapiworkarounds.h @@ -24,6 +24,12 @@ G_BEGIN_DECLS +/* + * Workaround to expose H.263 Baseline decode profile for drivers that + * support MPEG-4:2 Simple profile decoding. + */ +#define WORKAROUND_H263_BASELINE_DECODE_PROFILE (1) + G_END_DECLS #endif /* GST_VAAPI_WORKAROUNDS_H */ From b963ccb92992de3941bce9c6cfc3ed70b651f1e6 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Wed, 18 Jan 2012 10:23:41 +0100 Subject: [PATCH 0584/3781] profile: match video/x-h263 as H.263 Baseline profile. HACK: qtdemux does not report profiles for H.263. So, assume plain "video/x-h263" is H.263 Baseline profile. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiprofile.c | 10 +++++++++- gst-libs/gst/vaapi/gstvaapiworkarounds.h | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 1c95bbb670..e3cddd33c6 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -29,6 +29,7 @@ #include #include "gstvaapicompat.h" #include "gstvaapiprofile.h" +#include "gstvaapiworkarounds.h" typedef struct _GstVaapiProfileMap GstVaapiProfileMap; typedef struct _GstVaapiEntrypointMap GstVaapiEntrypointMap; @@ -245,11 +246,18 @@ gst_vaapi_profile_from_caps(GstCaps *caps) strcmp(profile_str, m->profile_str) == 0) profile = best_profile; } - if (!profile) + if (!profile) { profile = gst_vaapi_profile_from_codec_data( gst_vaapi_profile_get_codec(m->profile), codec_data ); + if (!profile && + WORKAROUND_QTDEMUX_NO_H263_PROFILES && + strncmp(name, "video/x-h263", namelen) == 0) { + /* HACK: qtdemux does not report profiles for h263 */ + profile = m->profile; + } + } gst_caps_unref(caps_test); } return profile ? profile : best_profile; diff --git a/gst-libs/gst/vaapi/gstvaapiworkarounds.h b/gst-libs/gst/vaapi/gstvaapiworkarounds.h index b060b13cc9..a7276f4a37 100644 --- a/gst-libs/gst/vaapi/gstvaapiworkarounds.h +++ b/gst-libs/gst/vaapi/gstvaapiworkarounds.h @@ -30,6 +30,12 @@ G_BEGIN_DECLS */ #define WORKAROUND_H263_BASELINE_DECODE_PROFILE (1) +/* + * Workaround for qtdemux that does not report profiles for + * video/x-h263. Assume H.263 Baseline profile in this case. + */ +#define WORKAROUND_QTDEMUX_NO_H263_PROFILES (1) + G_END_DECLS #endif /* GST_VAAPI_WORKAROUNDS_H */ From 990fe81fe23b4129fe35bbd4ac197b1f85077d74 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jan 2012 11:48:42 +0100 Subject: [PATCH 0585/3781] vaapisink: cap window size to the maximum display size. --- gst/vaapi/gstvaapisink.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index cc78a96d45..5fdf2d6b6c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -442,7 +442,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstStructure * const structure = gst_caps_get_structure(caps, 0); - guint win_width, win_height; + guint win_width, win_height, display_width, display_height; gint video_width, video_height, video_par_n = 1, video_par_d = 1; if (!structure) @@ -462,8 +462,12 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) if (!gst_vaapi_ensure_display(sink, &sink->display)) return FALSE; - if (sink->fullscreen) - gst_vaapi_display_get_size(sink->display, &win_width, &win_height); + gst_vaapi_display_get_size(sink->display, &display_width, &display_height); + if (sink->fullscreen || + video_width > display_width || video_height > display_height) { + win_width = display_width; + win_height = display_height; + } else { win_width = video_width; win_height = video_height; From 74d36803811dc382d6b11c40222cdf7a98dde27a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 21 Nov 2011 18:39:49 +0100 Subject: [PATCH 0586/3781] decoder: add ref_count to GstVaapiPicture. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 4442f1015c..da738efc23 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -671,6 +671,7 @@ create_picture(GstVaapiDecoder *decoder) picture->type = GST_VAAPI_PICTURE_TYPE_NONE; picture->flags = 0; + picture->ref_count = 1; picture->surface_id = VA_INVALID_ID; picture->surface = NULL; picture->param_id = VA_INVALID_ID; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 3a6cda171c..402348f869 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -149,6 +149,7 @@ struct _GstVaapiCodecInfo { struct _GstVaapiPicture { GstVaapiPictureType type; guint flags; + guint ref_count; VASurfaceID surface_id; GstVaapiSurface *surface; VABufferID param_id; @@ -254,6 +255,20 @@ void gst_vaapi_decoder_free_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) attribute_hidden; +static inline GstVaapiPicture * +gst_vaapi_decoder_ref_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) +{ + ++picture->ref_count; + return picture; +} + +static inline void +gst_vaapi_decoder_unref_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) +{ + if (--picture->ref_count == 0) + gst_vaapi_decoder_free_picture(decoder, picture); +} + GstVaapiIqMatrix * gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder) attribute_hidden; From dbba1f6107daaf716f15675e26bfd20ce8e91122 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jan 2012 10:21:45 +0100 Subject: [PATCH 0587/3781] decoder: allow slices to be attached to pictures later. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 10 +++++++++- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index da738efc23..b896847dc1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -878,10 +878,18 @@ gst_vaapi_decoder_new_slice( slice = create_slice(decoder, buf, buf_size); if (!slice) return NULL; - g_ptr_array_add(picture->slices, slice); + + if (picture) + g_ptr_array_add(picture->slices, slice); return slice; } +void +gst_vaapi_decoder_free_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice) +{ + destroy_slice(decoder, slice); +} + gboolean gst_vaapi_decoder_decode_picture( GstVaapiDecoder *decoder, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 402348f869..2d6d55d6a5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -285,6 +285,10 @@ gst_vaapi_decoder_new_slice( guint buf_size ) attribute_hidden; +void +gst_vaapi_decoder_free_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice) + attribute_hidden; + gboolean gst_vaapi_decoder_decode_picture( GstVaapiDecoder *decoder, From e5d12e885315fc2a5db806ec5a8d92f9ab3ea809 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jan 2012 09:48:11 +0100 Subject: [PATCH 0588/3781] decoder: rework the internal VA objects API. The new API simplifies a lot reference counting and makes it more flexible for future additions/changes. The GstVaapiCodecInfo is also gone. Rather, new helper macros are provided to allocate picture, slice and quantization matrix parameter buffers. --- gst-libs/gst/vaapi/Makefile.am | 6 + gst-libs/gst/vaapi/gstvaapicodec_objects.c | 250 +++++++++++++ gst-libs/gst/vaapi/gstvaapicodec_objects.h | 323 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder.c | 373 ------------------- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 55 +-- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 60 +-- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 326 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 253 +++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 116 ------ gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 62 +-- 10 files changed, 1204 insertions(+), 620 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapicodec_objects.c create mode 100644 gst-libs/gst/vaapi/gstvaapicodec_objects.h create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_objects.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_objects.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 68c76dbcf9..b2cd2ccc6b 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -145,8 +145,10 @@ endif if USE_CODEC_PARSERS libgstvaapi_source_c += \ + gstvaapicodec_objects.c \ gstvaapidecoder_mpeg2.c \ gstvaapidecoder_mpeg4.c \ + gstvaapidecoder_objects.c \ gstvaapidecoder_vc1.c \ $(NULL) libgstvaapi_source_h += \ @@ -154,6 +156,10 @@ libgstvaapi_source_h += \ gstvaapidecoder_mpeg4.h \ gstvaapidecoder_vc1.h \ $(NULL) +libgstvaapi_source_priv_h += \ + gstvaapicodec_objects.h \ + gstvaapidecoder_objects.h \ + $(NULL) libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS) libgstvaapi_libs += $(GST_CODEC_PARSERS_LIBS) endif diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c new file mode 100644 index 0000000000..7af2dd9579 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -0,0 +1,250 @@ +/* + * gstvaapicodec_objects.c - VA codec objects abstraction + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2012 Intel Corporation + * + * 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 "config.h" +#include +#include +#include "gstvaapicodec_objects.h" +#include "gstvaapidecoder_priv.h" +#include "gstvaapicompat.h" +#include "gstvaapiutils.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +/* ------------------------------------------------------------------------- */ +/* --- Base Codec Object --- */ +/* ------------------------------------------------------------------------- */ + +G_DEFINE_TYPE(GstVaapiCodecObject, gst_vaapi_codec_object, GST_TYPE_MINI_OBJECT) + +static void +gst_vaapi_codec_object_finalize(GstMiniObject *object) +{ + GstVaapiCodecObject * const obj = GST_VAAPI_CODEC_OBJECT(object); + + obj->codec = NULL; +} + +static void +gst_vaapi_codec_object_init(GstVaapiCodecObject *obj) +{ + obj->codec = NULL; +} + +static gboolean +gst_vaapi_codec_object_create( + GstVaapiCodecObject *obj, + const GstVaapiCodecObjectConstructorArgs *args +) +{ + obj->codec = args->codec; + return TRUE; +} + +static void +gst_vaapi_codec_object_class_init(GstVaapiCodecObjectClass *klass) +{ + GstMiniObjectClass * const object_class = GST_MINI_OBJECT_CLASS(klass); + + object_class->finalize = gst_vaapi_codec_object_finalize; + klass->construct = gst_vaapi_codec_object_create; +} + +GstVaapiCodecObject * +gst_vaapi_codec_object_new( + GType type, + GstVaapiCodecBase *codec, + gconstpointer param, + guint param_size, + gconstpointer data, + guint data_size +) +{ + GstMiniObject *obj; + GstVaapiCodecObject *va_obj; + GstVaapiCodecObjectConstructorArgs args; + + obj = gst_mini_object_new(type); + if (!obj) + return NULL; + + va_obj = GST_VAAPI_CODEC_OBJECT(obj); + args.codec = codec; + args.param = param; + args.param_size = param_size; + args.data = data; + args.data_size = data_size; + if (gst_vaapi_codec_object_construct(va_obj, &args)) + return va_obj; + + gst_mini_object_unref(obj); + return NULL; +} + +gboolean +gst_vaapi_codec_object_construct( + GstVaapiCodecObject *obj, + const GstVaapiCodecObjectConstructorArgs *args +) +{ + GstVaapiCodecObjectClass *klass; + + g_return_val_if_fail(GST_VAAPI_CODEC_OBJECT(obj), FALSE); + g_return_val_if_fail(args->codec != NULL, FALSE); + g_return_val_if_fail(args->param_size > 0, FALSE); + + if (GST_MINI_OBJECT_FLAG_IS_SET(obj, GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED)) + return TRUE; + + klass = GST_VAAPI_CODEC_OBJECT_GET_CLASS(obj); + if (!klass || !klass->construct || !klass->construct(obj, args)) + return FALSE; + + GST_MINI_OBJECT_FLAG_SET(obj, GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED); + return TRUE; +} + +#define GET_DECODER(obj) GST_VAAPI_DECODER_CAST((obj)->parent_instance.codec) +#define GET_CONTEXT(obj) GET_DECODER(obj)->priv->context +#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->priv->va_display +#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->priv->va_context + +/* ------------------------------------------------------------------------- */ +/* --- Inverse Quantization Matrices --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiIqMatrix, + gst_vaapi_iq_matrix, + GST_VAAPI_TYPE_CODEC_OBJECT) + +static 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; +} + +static gboolean +gst_vaapi_iq_matrix_create( + GstVaapiIqMatrix *iq_matrix, + const GstVaapiCodecObjectConstructorArgs *args +) +{ + iq_matrix->param = vaapi_create_buffer( + GET_VA_DISPLAY(iq_matrix), + GET_VA_CONTEXT(iq_matrix), + VAIQMatrixBufferType, + args->param_size, + &iq_matrix->param_id + ); + if (!iq_matrix->param) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_iq_matrix_init(GstVaapiIqMatrix *iq_matrix) +{ + iq_matrix->param = NULL; + iq_matrix->param_id = VA_INVALID_ID; +} + +GstVaapiIqMatrix * +gst_vaapi_iq_matrix_new( + GstVaapiDecoder *decoder, + gconstpointer param, + guint param_size +) +{ + GstVaapiCodecObject *object; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + object = gst_vaapi_codec_object_new( + GST_VAAPI_TYPE_IQ_MATRIX, + GST_VAAPI_CODEC_BASE(decoder), + param, param_size, + NULL, 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, + GST_VAAPI_TYPE_CODEC_OBJECT) + +static void +gst_vaapi_bitplane_destroy(GstVaapiBitPlane *bitplane) +{ + vaapi_destroy_buffer(GET_VA_DISPLAY(bitplane), &bitplane->data_id); + bitplane->data = NULL; +} + +static gboolean +gst_vaapi_bitplane_create( + GstVaapiBitPlane *bitplane, + const GstVaapiCodecObjectConstructorArgs *args +) +{ + bitplane->data = vaapi_create_buffer( + GET_VA_DISPLAY(bitplane), + GET_VA_CONTEXT(bitplane), + VABitPlaneBufferType, + args->param_size, + &bitplane->data_id + ); + if (!bitplane->data) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_bitplane_init(GstVaapiBitPlane *bitplane) +{ + bitplane->data = NULL; + bitplane->data_id = VA_INVALID_ID; +} + +GstVaapiBitPlane * +gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size) +{ + GstVaapiCodecObject *object; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + object = gst_vaapi_codec_object_new( + GST_VAAPI_TYPE_BITPLANE, + GST_VAAPI_CODEC_BASE(decoder), + data, data_size, + NULL, 0 + ); + if (!object) + return NULL; + return GST_VAAPI_BITPLANE_CAST(object); +} diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h new file mode 100644 index 0000000000..7577ba6ac7 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -0,0 +1,323 @@ +/* + * gstvaapicodec_objects.h - VA codec objects abstraction + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2012 Intel Corporation + * + * 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 +#include + +G_BEGIN_DECLS + +typedef gpointer GstVaapiCodecBase; +typedef struct _GstVaapiCodecObject GstVaapiCodecObject; +typedef struct _GstVaapiCodecObjectClass GstVaapiCodecObjectClass; +typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix; +typedef struct _GstVaapiIqMatrixClass GstVaapiIqMatrixClass; +typedef struct _GstVaapiBitPlane GstVaapiBitPlane; +typedef struct _GstVaapiBitPlaneClass GstVaapiBitPlaneClass; + +/* ------------------------------------------------------------------------- */ +/* --- 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_TYPE_CODEC_OBJECT \ + (gst_vaapi_codec_object_get_type()) + +#define GST_VAAPI_CODEC_OBJECT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_CODEC_OBJECT, \ + GstVaapiCodecObject)) + +#define GST_VAAPI_CODEC_OBJECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_CODEC_OBJECT, \ + GstVaapiCodecObjectClass)) + +#define GST_VAAPI_IS_CODEC_OBJECT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_CODEC_OBJECT)) + +#define GST_VAAPI_IS_CODEC_OBJECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_CODEC_OBJECT)) + +#define GST_VAAPI_CODEC_OBJECT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_CODEC_OBJECT, \ + GstVaapiCodecObjectClass)) + +enum { + GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED = (GST_MINI_OBJECT_FLAG_LAST << 0), + GST_VAAPI_CODEC_OBJECT_FLAG_LAST = (GST_MINI_OBJECT_FLAG_LAST << 1) +}; + +typedef struct { + GstVaapiCodecObject *obj; + GstVaapiCodecBase *codec; + gconstpointer param; + guint param_size; + gconstpointer data; + guint data_size; +} GstVaapiCodecObjectConstructorArgs; + +/** + * GstVaapiCodecObject: + * + * A #GstMiniObject holding the base codec object data + */ +struct _GstVaapiCodecObject { + /*< private >*/ + GstMiniObject parent_instance; + GstVaapiCodecBase *codec; +}; + +/** + * GstVaapiCodecObjectClass: + * + * The #GstVaapiCodecObject base class. + */ +struct _GstVaapiCodecObjectClass { + /*< private >*/ + GstMiniObjectClass parent_class; + + gboolean (*construct) (GstVaapiCodecObject *obj, + const GstVaapiCodecObjectConstructorArgs *args); +}; + +GType +gst_vaapi_codec_object_get_type(void) + attribute_hidden; + +GstVaapiCodecObject * +gst_vaapi_codec_object_new( + GType type, + GstVaapiCodecBase *codec, + gconstpointer param, + guint param_size, + gconstpointer data, + guint data_size +) attribute_hidden; + +gboolean +gst_vaapi_codec_object_construct( + GstVaapiCodecObject *obj, + const GstVaapiCodecObjectConstructorArgs *args +) attribute_hidden; + +/* ------------------------------------------------------------------------- */ +/* --- Inverse Quantization Matrices --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_TYPE_IQ_MATRIX \ + (gst_vaapi_iq_matrix_get_type()) + +#define GST_VAAPI_IQ_MATRIX_CAST(obj) \ + ((GstVaapiIqMatrix *)(obj)) + +#define GST_VAAPI_IQ_MATRIX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_IQ_MATRIX, \ + GstVaapiIqMatrix)) + +#define GST_VAAPI_IQ_MATRIX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_IQ_MATRIX, \ + GstVaapiIqMatrixClass)) + +#define GST_VAAPI_IS_IQ_MATRIX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_IQ_MATRIX)) + +#define GST_VAAPI_IS_IQ_MATRIX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_IQ_MATRIX)) + +#define GST_VAAPI_IQ_MATRIX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_IQ_MATRIX, \ + GstVaapiIqMatrixClass)) + +/** + * GstVaapiIqMatrix: + * + * A #GstVaapiCodecObject holding an inverse quantization matrix parameter. + */ +struct _GstVaapiIqMatrix { + /*< private >*/ + GstVaapiCodecObject parent_instance; + VABufferID param_id; + + /*< public >*/ + gpointer param; +}; + +/** + * GstVaapiIqMatrixClass: + * + * The #GstVaapiIqMatrix base class. + */ +struct _GstVaapiIqMatrixClass { + /*< private >*/ + GstVaapiCodecObjectClass parent_class; +}; + +GType +gst_vaapi_iq_matrix_get_type(void) + attribute_hidden; + +GstVaapiIqMatrix * +gst_vaapi_iq_matrix_new( + GstVaapiDecoder *decoder, + gconstpointer param, + guint param_size +) attribute_hidden; + +/* ------------------------------------------------------------------------- */ +/* --- VC-1 Bit Planes --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_TYPE_BITPLANE \ + (gst_vaapi_bitplane_get_type()) + +#define GST_VAAPI_BITPLANE_CAST(obj) \ + ((GstVaapiBitPlane *)(obj)) + +#define GST_VAAPI_BITPLANE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_BITPLANE, \ + GstVaapiBitPlane)) + +#define GST_VAAPI_BITPLANE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_BITPLANE, \ + GstVaapiBitPlaneClass)) + +#define GST_VAAPI_IS_BITPLANE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_BITPLANE)) + +#define GST_VAAPI_IS_BITPLANE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_BITPLANE)) + +#define GST_VAAPI_BITPLANE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_BITPLANE, \ + GstVaapiBitPlaneClass)) + +/** + * GstVaapiBitPlane: + * + * A #GstVaapiCodecObject holding a VC-1 bit plane parameter. + */ +struct _GstVaapiBitPlane { + /*< private >*/ + GstVaapiCodecObject parent_instance; + VABufferID data_id; + + /*< public >*/ + guint8 *data; +}; + +/** + * GstVaapiBitPlaneClass: + * + * The #GstVaapiBitPlane base class. + */ +struct _GstVaapiBitPlaneClass { + /*< private >*/ + GstVaapiCodecObjectClass parent_class; +}; + +GType +gst_vaapi_bitplane_get_type(void) + attribute_hidden; + +GstVaapiBitPlane * +gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size) + attribute_hidden; + +/* ------------------------------------------------------------------------- */ +/* --- Helpers to create codec-dependent objects --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_CODEC_DEFINE_TYPE(type, prefix, base_type) \ +G_DEFINE_TYPE(type, prefix, base_type) \ + \ +static void \ +prefix##_destroy(type *); \ + \ +static gboolean \ +prefix##_create( \ + type *, \ + const GstVaapiCodecObjectConstructorArgs *args \ +); \ + \ +static void \ +prefix##_finalize(GstMiniObject *object) \ +{ \ + GstMiniObjectClass *parent_class; \ + \ + prefix##_destroy((type *)object); \ + \ + parent_class = GST_MINI_OBJECT_CLASS(prefix##_parent_class); \ + if (parent_class->finalize) \ + parent_class->finalize(object); \ +} \ + \ +static gboolean \ +prefix##_construct( \ + GstVaapiCodecObject *object, \ + const GstVaapiCodecObjectConstructorArgs *args \ +) \ +{ \ + GstVaapiCodecObjectClass *parent_class; \ + \ + parent_class = GST_VAAPI_CODEC_OBJECT_CLASS(prefix##_parent_class); \ + if (parent_class->construct) { \ + if (!parent_class->construct(object, args)) \ + return FALSE; \ + } \ + return prefix##_create((type *)object, args); \ +} \ + \ +static void \ +prefix##_class_init(type##Class *klass) \ +{ \ + GstMiniObjectClass * const object_class = \ + GST_MINI_OBJECT_CLASS(klass); \ + GstVaapiCodecObjectClass * const codec_class = \ + GST_VAAPI_CODEC_OBJECT_CLASS(klass); \ + \ + object_class->finalize = prefix##_finalize; \ + codec_class->construct = prefix##_construct; \ +} + +#define GST_VAAPI_IQ_MATRIX_NEW(codec, decoder) \ + gst_vaapi_iq_matrix_new(GST_VAAPI_DECODER_CAST(decoder), \ + NULL, sizeof(VAIQMatrixBuffer##codec)) + +#define GST_VAAPI_BITPLANE_NEW(decoder, size) \ + gst_vaapi_bitplane_new(GST_VAAPI_DECODER_CAST(decoder), NULL, size) + +G_END_DECLS + +#endif /* GST_VAAPI_CODEC_OBJECTS_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index b896847dc1..e0d1b7b209 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -26,7 +26,6 @@ */ #include "config.h" -#include #include "gstvaapicompat.h" #include "gstvaapidecoder.h" #include "gstvaapidecoder_priv.h" @@ -43,7 +42,6 @@ enum { PROP_DISPLAY, PROP_CAPS, - PROP_CODEC_INFO, }; static void @@ -202,20 +200,6 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps) set_codec_data(decoder, gst_value_get_buffer(v_codec_data)); } -static inline void -set_codec_info(GstVaapiDecoder *decoder, GstVaapiCodecInfo *codec_info) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - - if (codec_info) { - priv->codec_info = *codec_info; - if (!priv->codec_info.pic_size) - priv->codec_info.pic_size = sizeof(GstVaapiPicture); - if (!priv->codec_info.slice_size) - priv->codec_info.slice_size = sizeof(GstVaapiSlice); - } -} - static void clear_queue(GQueue *q, GDestroyNotify destroy) { @@ -285,9 +269,6 @@ gst_vaapi_decoder_set_property( case PROP_CAPS: set_caps(decoder, g_value_get_pointer(value)); break; - case PROP_CODEC_INFO: - set_codec_info(decoder, g_value_get_pointer(value)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -349,14 +330,6 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass) "Decoder caps", "The decoder caps", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_CODEC_INFO, - g_param_spec_pointer("codec-info", - "Codec info", - "The codec info", - G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -611,349 +584,3 @@ gst_vaapi_decoder_push_surface_proxy( { return push_surface(decoder, g_object_ref(proxy), timestamp); } - -static void -destroy_iq_matrix(GstVaapiDecoder *decoder, GstVaapiIqMatrix *iq_matrix); - -static void -destroy_bitplane(GstVaapiDecoder *decoder, GstVaapiBitPlane *bitplane); - -static void -destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice); - -static void -destroy_slice_cb(gpointer data, gpointer user_data) -{ - GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(user_data); - GstVaapiSlice * const slice = data; - - destroy_slice(decoder, slice); -} - -static void -destroy_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - - if (picture->slices) { - g_ptr_array_foreach(picture->slices, destroy_slice_cb, decoder); - g_ptr_array_free(picture->slices, TRUE); - picture->slices = NULL; - } - - if (picture->iq_matrix) { - destroy_iq_matrix(decoder, picture->iq_matrix); - picture->iq_matrix = NULL; - } - - if (picture->bitplane) { - destroy_bitplane(decoder, picture->bitplane); - picture->bitplane = NULL; - } - - picture->surface = NULL; - picture->surface_id = VA_INVALID_ID; - - vaapi_destroy_buffer(priv->va_display, &picture->param_id); - picture->param = NULL; - g_slice_free1(priv->codec_info.pic_size, picture); -} - -static GstVaapiPicture * -create_picture(GstVaapiDecoder *decoder) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVaapiPicture *picture; - - picture = g_slice_alloc(priv->codec_info.pic_size); - if (!picture) - return NULL; - - picture->type = GST_VAAPI_PICTURE_TYPE_NONE; - picture->flags = 0; - picture->ref_count = 1; - picture->surface_id = VA_INVALID_ID; - picture->surface = NULL; - picture->param_id = VA_INVALID_ID; - picture->param = NULL; - picture->slices = NULL; - picture->iq_matrix = NULL; - picture->bitplane = NULL; - picture->pts = GST_CLOCK_TIME_NONE; - - picture->surface = gst_vaapi_context_get_surface(priv->context); - if (!picture->surface) - goto error; - picture->surface_id = gst_vaapi_surface_get_id(picture->surface); - - picture->param = vaapi_create_buffer( - priv->va_display, - priv->va_context, - VAPictureParameterBufferType, - priv->codec_info.pic_param_size, - &picture->param_id - ); - if (!picture->param) - goto error; - - picture->slices = g_ptr_array_new(); - if (!picture->slices) - goto error; - return picture; - -error: - destroy_picture(priv->va_display, picture); - return NULL; -} - -GstVaapiPicture * -gst_vaapi_decoder_new_picture(GstVaapiDecoder *decoder) -{ - return create_picture(decoder); -} - -void -gst_vaapi_decoder_free_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) -{ - destroy_picture(decoder, picture); -} - -static void -destroy_iq_matrix(GstVaapiDecoder *decoder, GstVaapiIqMatrix *iq_matrix) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - - vaapi_destroy_buffer(priv->va_display, &iq_matrix->param_id); - iq_matrix->param = NULL; - g_slice_free(GstVaapiIqMatrix, iq_matrix); -} - -static GstVaapiIqMatrix * -create_iq_matrix(GstVaapiDecoder *decoder) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVaapiIqMatrix *iq_matrix; - - iq_matrix = g_slice_new(GstVaapiIqMatrix); - if (!iq_matrix) - return NULL; - - iq_matrix->param_id = VA_INVALID_ID; - - iq_matrix->param = vaapi_create_buffer( - priv->va_display, - priv->va_context, - VAIQMatrixBufferType, - priv->codec_info.iq_matrix_size, - &iq_matrix->param_id - ); - if (!iq_matrix->param) - goto error; - return iq_matrix; - -error: - destroy_iq_matrix(decoder, iq_matrix); - return NULL; -} - -GstVaapiIqMatrix * -gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder) -{ - return create_iq_matrix(decoder); -} - -static void -destroy_bitplane(GstVaapiDecoder *decoder, GstVaapiBitPlane *bitplane) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - - vaapi_destroy_buffer(priv->va_display, &bitplane->data_id); - bitplane->data = NULL; - g_slice_free(GstVaapiBitPlane, bitplane); -} - -static GstVaapiBitPlane * -create_bitplane(GstVaapiDecoder *decoder, guint size) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVaapiBitPlane *bitplane; - - bitplane = g_slice_new(GstVaapiBitPlane); - if (!bitplane) - return NULL; - - bitplane->data_id = VA_INVALID_ID; - - bitplane->data = vaapi_create_buffer( - priv->va_display, - priv->va_context, - VABitPlaneBufferType, - size, - &bitplane->data_id - ); - if (!bitplane->data) - goto error; - return bitplane; - -error: - destroy_bitplane(decoder, bitplane); - return NULL; -} - -GstVaapiBitPlane * -gst_vaapi_decoder_new_bitplane(GstVaapiDecoder *decoder, guint size) -{ - return create_bitplane(decoder, size); -} - -static void -destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - - vaapi_destroy_buffer(priv->va_display, &slice->data_id); - vaapi_destroy_buffer(priv->va_display, &slice->param_id); - slice->param = NULL; - g_slice_free1(priv->codec_info.slice_size, slice); -} - -static GstVaapiSlice * -create_slice(GstVaapiDecoder *decoder, guchar *buf, guint buf_size) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVaapiSlice *slice; - VASliceParameterBufferBase *slice_param; - guchar *data; - - slice = g_slice_alloc(priv->codec_info.slice_size); - if (!slice) - return NULL; - - slice->data_id = VA_INVALID_ID; - slice->param_id = VA_INVALID_ID; - - data = vaapi_create_buffer( - priv->va_display, - priv->va_context, - VASliceDataBufferType, - buf_size, - &slice->data_id - ); - if (!data) - goto error; - memcpy(data, buf, buf_size); - vaapi_unmap_buffer(priv->va_display, slice->data_id, NULL); - - slice->param = vaapi_create_buffer( - priv->va_display, - priv->va_context, - VASliceParameterBufferType, - priv->codec_info.slice_param_size, - &slice->param_id - ); - if (!slice->param) - goto error; - - slice_param = slice->param; - slice_param->slice_data_size = buf_size; - slice_param->slice_data_offset = 0; - slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL; - return slice; - -error: - destroy_slice(decoder, slice); - return NULL; -} - -GstVaapiSlice * -gst_vaapi_decoder_new_slice( - GstVaapiDecoder *decoder, - GstVaapiPicture *picture, - guchar *buf, - guint buf_size -) -{ - GstVaapiSlice *slice; - - slice = create_slice(decoder, buf, buf_size); - if (!slice) - return NULL; - - if (picture) - g_ptr_array_add(picture->slices, slice); - return slice; -} - -void -gst_vaapi_decoder_free_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice) -{ - destroy_slice(decoder, slice); -} - -gboolean -gst_vaapi_decoder_decode_picture( - GstVaapiDecoder *decoder, - GstVaapiPicture *picture -) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVaapiIqMatrix * const iq_matrix = picture->iq_matrix; - GstVaapiBitPlane * const bitplane = picture->bitplane; - GstVaapiSlice *slice; - VABufferID va_buffers[3]; - guint i, n_va_buffers = 0; - VAStatus status; - - GST_DEBUG("decode picture 0x%08x", gst_vaapi_surface_get_id(picture->surface)); - - vaapi_unmap_buffer(priv->va_display, picture->param_id, &picture->param); - va_buffers[n_va_buffers++] = picture->param_id; - - if (iq_matrix) { - vaapi_unmap_buffer(priv->va_display, iq_matrix->param_id, &iq_matrix->param); - va_buffers[n_va_buffers++] = iq_matrix->param_id; - } - - if (bitplane) { - vaapi_unmap_buffer(priv->va_display, bitplane->data_id, (void **)&bitplane->data); - va_buffers[n_va_buffers++] = bitplane->data_id; - } - - status = vaBeginPicture( - priv->va_display, - priv->va_context, - picture->surface_id - ); - if (!vaapi_check_status(status, "vaBeginPicture()")) - return FALSE; - - status = vaRenderPicture( - priv->va_display, - priv->va_context, - va_buffers, n_va_buffers - ); - if (!vaapi_check_status(status, "vaRenderPicture()")) - return FALSE; - - for (i = 0; i < picture->slices->len; i++) { - slice = g_ptr_array_index(picture->slices, i); - - vaapi_unmap_buffer(priv->va_display, slice->param_id, NULL); - va_buffers[0] = slice->param_id; - va_buffers[1] = slice->data_id; - n_va_buffers = 2; - - status = vaRenderPicture( - priv->va_display, - priv->va_context, - va_buffers, n_va_buffers - ); - if (!vaapi_check_status(status, "vaRenderPicture()")) - return FALSE; - } - - status = vaEndPicture(priv->va_display, priv->va_context); - if (!vaapi_check_status(status, "vaEndPicture()")) - return FALSE; - return TRUE; -} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index e70c6357a0..33edc0f3de 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -29,6 +29,7 @@ #include #include #include "gstvaapidecoder_mpeg2.h" +#include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" @@ -91,23 +92,11 @@ struct _GstVaapiDecoderMpeg2Private { static void gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - if (priv->current_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->current_picture); - priv->current_picture = NULL; - } - - if (priv->next_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->next_picture); - priv->next_picture = NULL; - } - - if (priv->prev_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); - priv->prev_picture = NULL; - } + gst_vaapi_picture_replace(&priv->current_picture, NULL); + gst_vaapi_picture_replace(&priv->next_picture, NULL); + gst_vaapi_picture_replace(&priv->prev_picture, NULL); if (priv->sub_buffer) { gst_buffer_unref(priv->sub_buffer); @@ -221,7 +210,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) priv->quant_matrix_changed = FALSE; - picture->iq_matrix = gst_vaapi_decoder_new_iq_matrix(GST_VAAPI_DECODER(decoder)); + picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(MPEG2, decoder); if (!picture->iq_matrix) { GST_DEBUG("failed to allocate IQ matrix"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -266,11 +255,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) static inline GstVaapiDecoderStatus render_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); - - if (!gst_vaapi_decoder_push_surface(base_decoder, - picture->surface, - picture->pts)) + if (!gst_vaapi_picture_output(picture)) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -278,19 +263,18 @@ render_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderMpeg2 *decoder) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstVaapiPicture * const picture = priv->current_picture; GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; if (picture) { - if (!gst_vaapi_decoder_decode_picture(base_decoder, picture)) + if (!gst_vaapi_picture_decode(picture)) status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { if ((priv->prev_picture && priv->next_picture) || (priv->closed_gop && priv->next_picture)) status = render_picture(decoder, picture); - gst_vaapi_decoder_free_picture(base_decoder, picture); + gst_vaapi_picture_unref(picture); } priv->current_picture = NULL; } @@ -448,7 +432,6 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr; GstVaapiPicture *picture; @@ -467,7 +450,7 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) return status; } - priv->current_picture = gst_vaapi_decoder_new_picture(base_decoder); + priv->current_picture = GST_VAAPI_PICTURE_NEW(MPEG2, decoder); if (!priv->current_picture) { GST_DEBUG("failed to allocate picture"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -510,9 +493,9 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) /* Update reference pictures */ if (pic_hdr->pic_type != GST_MPEG_VIDEO_PICTURE_TYPE_B) { - picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); if (priv->prev_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); + gst_vaapi_picture_unref(priv->prev_picture); priv->prev_picture = NULL; } if (priv->next_picture) { @@ -626,15 +609,12 @@ decode_slice( priv->mb_y = slice_no; - slice = gst_vaapi_decoder_new_slice( - GST_VAAPI_DECODER(decoder), - picture, - buf, buf_size - ); + slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, buf, buf_size); if (!slice) { GST_DEBUG("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } + gst_vaapi_picture_add_slice(picture, slice); /* Parse slice */ gst_bit_reader_init(&br, buf, buf_size); @@ -911,14 +891,6 @@ gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps) { GstVaapiDecoderMpeg2 *decoder; - static const GstVaapiCodecInfo codec_info = { - .pic_size = sizeof(GstVaapiPicture), - .slice_size = sizeof(GstVaapiSlice), - .pic_param_size = sizeof(VAPictureParameterBufferMPEG2), - .slice_param_size = sizeof(VASliceParameterBufferMPEG2), - .iq_matrix_size = sizeof(VAIQMatrixBufferMPEG2), - }; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); g_return_val_if_fail(GST_IS_CAPS(caps), NULL); @@ -926,7 +898,6 @@ gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps) GST_VAAPI_TYPE_DECODER_MPEG2, "display", display, "caps", caps, - "codec-info", &codec_info, NULL ); if (!decoder->priv->is_constructed) { diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 0c4d969fde..a81f19b790 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -29,6 +29,7 @@ #include #include #include "gstvaapidecoder_mpeg4.h" +#include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" @@ -95,23 +96,11 @@ struct _GstVaapiDecoderMpeg4Private { static void gst_vaapi_decoder_mpeg4_close(GstVaapiDecoderMpeg4 *decoder) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg4Private * const priv = decoder->priv; - if (priv->curr_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->curr_picture); - priv->curr_picture = NULL; - } - - if (priv->next_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->next_picture); - priv->next_picture = NULL; - } - - if (priv->prev_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); - priv->prev_picture = NULL; - } + gst_vaapi_picture_replace(&priv->curr_picture, NULL); + gst_vaapi_picture_replace(&priv->next_picture, NULL); + gst_vaapi_picture_replace(&priv->prev_picture, NULL); if (priv->sub_buffer) { gst_buffer_unref(priv->sub_buffer); @@ -231,7 +220,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; } - picture->iq_matrix = gst_vaapi_decoder_new_iq_matrix(GST_VAAPI_DECODER(decoder)); + picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(MPEG4, decoder); if (!picture->iq_matrix) { GST_DEBUG("failed to allocate IQ matrix"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -261,11 +250,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) static inline GstVaapiDecoderStatus render_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); - - if (!gst_vaapi_decoder_push_surface(base_decoder, - picture->surface, - picture->pts)) + if (!gst_vaapi_picture_output(picture)) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -277,19 +262,18 @@ render_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderMpeg4 *decoder) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg4Private * const priv = decoder->priv; GstVaapiPicture * const picture = priv->curr_picture; GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; if (picture) { - if (!gst_vaapi_decoder_decode_picture(base_decoder, picture)) + if (!gst_vaapi_picture_decode(picture)) status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { if ((priv->prev_picture && priv->next_picture) || (priv->closed_gop && priv->next_picture)) status = render_picture(decoder, picture); - gst_vaapi_decoder_free_picture(base_decoder, picture); + gst_vaapi_picture_unref(picture); } priv->curr_picture = NULL; } @@ -448,7 +432,6 @@ static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) { GstMpeg4ParseResult parser_result = GST_MPEG4_PARSER_OK; - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg4Private * const priv = decoder->priv; GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr; GstMpeg4VideoObjectLayer * const vol_hdr = &priv->vol_hdr; @@ -496,7 +479,7 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) return status; } - priv->curr_picture = gst_vaapi_decoder_new_picture(base_decoder); + priv->curr_picture = GST_VAAPI_PICTURE_NEW(MPEG4, decoder); if (!priv->curr_picture) { GST_DEBUG("failed to allocate picture"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -527,12 +510,12 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) case GST_MPEG4_I_VOP: picture->type = GST_VAAPI_PICTURE_TYPE_I; if (priv->is_svh || vop_hdr->coded) - picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); break; case GST_MPEG4_P_VOP: picture->type = GST_VAAPI_PICTURE_TYPE_P; if (priv->is_svh || vop_hdr->coded) - picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); break; case GST_MPEG4_B_VOP: picture->type = GST_VAAPI_PICTURE_TYPE_B; @@ -541,7 +524,7 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) picture->type = GST_VAAPI_PICTURE_TYPE_S; // see 3.175 reference VOP if (vop_hdr->coded) - picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); break; default: GST_DEBUG("unsupported picture type %d", priv->coding_type); @@ -586,9 +569,8 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) /* Update reference pictures */ /* XXX: consider priv->vol_hdr.low_delay, consider packed video frames for DivX/XviD */ if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { - picture->flags |= GST_VAAPI_PICTURE_REFERENCE; if (priv->prev_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); + gst_vaapi_picture_unref(priv->prev_picture); priv->prev_picture = NULL; } if (priv->next_picture) { @@ -712,15 +694,12 @@ decode_slice( if (!has_packet_header && !fill_picture(decoder, picture)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - slice = gst_vaapi_decoder_new_slice( - GST_VAAPI_DECODER(decoder), - picture, - (guchar*)buf, buf_size - ); + slice = GST_VAAPI_SLICE_NEW(MPEG4, decoder, buf, buf_size); if (!slice) { GST_DEBUG("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } + gst_vaapi_picture_add_slice(picture, slice); /* Fill in VASliceParameterBufferMPEG4 */ slice_param = slice->param; @@ -1085,14 +1064,6 @@ gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps) { GstVaapiDecoderMpeg4 *decoder; - static const GstVaapiCodecInfo codec_info = { - .pic_size = sizeof(GstVaapiPicture), - .slice_size = sizeof(GstVaapiSlice), - .pic_param_size = sizeof(VAPictureParameterBufferMPEG4), - .slice_param_size = sizeof(VASliceParameterBufferMPEG4), - .iq_matrix_size = sizeof(VAIQMatrixBufferMPEG4), - }; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); g_return_val_if_fail(GST_IS_CAPS(caps), NULL); @@ -1100,7 +1071,6 @@ gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps) GST_VAAPI_TYPE_DECODER_MPEG4, "display", display, "caps", caps, - "codec-info", &codec_info, NULL ); if (!decoder->priv->is_constructed) { diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c new file mode 100644 index 0000000000..61ff4e6b19 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -0,0 +1,326 @@ +/* + * gstvaapidecoder_objects.c - VA decoder objects helpers + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2012 Intel Corporation + * + * 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 "config.h" +#include +#include +#include "gstvaapidecoder_objects.h" +#include "gstvaapidecoder_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)->priv->context +#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->priv->va_display +#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->priv->va_context + +/* ------------------------------------------------------------------------- */ +/* --- Pictures --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPicture, + gst_vaapi_picture, + GST_VAAPI_TYPE_CODEC_OBJECT) + +static void +destroy_slice_cb(gpointer data, gpointer user_data) +{ + GstMiniObject * const object = data; + + gst_mini_object_unref(object); +} + +static void +gst_vaapi_picture_destroy(GstVaapiPicture *picture) +{ + if (picture->slices) { + g_ptr_array_foreach(picture->slices, destroy_slice_cb, NULL); + g_ptr_array_free(picture->slices, TRUE); + picture->slices = NULL; + } + + if (picture->iq_matrix) { + gst_mini_object_unref(GST_MINI_OBJECT(picture->iq_matrix)); + picture->iq_matrix = NULL; + } + + if (picture->bitplane) { + gst_mini_object_unref(GST_MINI_OBJECT(picture->bitplane)); + picture->bitplane = NULL; + } + + picture->surface_id = VA_INVALID_ID; + picture->surface = NULL; + + vaapi_destroy_buffer(GET_VA_DISPLAY(picture), &picture->param_id); + picture->param = NULL; +} + +static gboolean +gst_vaapi_picture_create( + GstVaapiPicture *picture, + const GstVaapiCodecObjectConstructorArgs *args +) +{ + picture->surface = gst_vaapi_context_get_surface(GET_CONTEXT(picture)); + if (!picture->surface) + return FALSE; + picture->surface_id = gst_vaapi_surface_get_id(picture->surface); + + picture->param = vaapi_create_buffer( + GET_VA_DISPLAY(picture), + GET_VA_CONTEXT(picture), + VAPictureParameterBufferType, + args->param_size, + &picture->param_id + ); + if (!picture->param) + return FALSE; + + picture->slices = g_ptr_array_new(); + if (!picture->slices) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_picture_init(GstVaapiPicture *picture) +{ + picture->type = GST_VAAPI_PICTURE_TYPE_NONE; + picture->surface = NULL; + picture->surface_id = VA_INVALID_ID; + picture->param = NULL; + picture->param_id = VA_INVALID_ID; + picture->slices = NULL; + picture->iq_matrix = NULL; + picture->bitplane = NULL; + picture->pts = GST_CLOCK_TIME_NONE; +} + +GstVaapiPicture * +gst_vaapi_picture_new( + GstVaapiDecoder *decoder, + gconstpointer param, + guint param_size +) +{ + GstVaapiCodecObject *object; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + object = gst_vaapi_codec_object_new( + GST_VAAPI_TYPE_PICTURE, + GST_VAAPI_CODEC_BASE(decoder), + param, param_size, + NULL, 0 + ); + 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); +} + +gboolean +gst_vaapi_picture_decode(GstVaapiPicture *picture) +{ + GstVaapiIqMatrix *iq_matrix; + GstVaapiBitPlane *bitplane; + VADisplay va_display; + VAContextID va_context; + VABufferID va_buffers[3]; + guint i, n_va_buffers = 0; + VAStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE); + + va_display = GET_VA_DISPLAY(picture); + va_context = GET_VA_CONTEXT(picture); + + GST_DEBUG("decode picture 0x%08x", picture->surface_id); + + vaapi_unmap_buffer(va_display, picture->param_id, &picture->param); + va_buffers[n_va_buffers++] = picture->param_id; + + iq_matrix = picture->iq_matrix; + if (iq_matrix) { + vaapi_unmap_buffer( + va_display, + iq_matrix->param_id, &iq_matrix->param + ); + va_buffers[n_va_buffers++] = iq_matrix->param_id; + } + + bitplane = picture->bitplane; + if (bitplane) { + vaapi_unmap_buffer( + va_display, + bitplane->data_id, (void **)&bitplane->data + ); + va_buffers[n_va_buffers++] = bitplane->data_id; + } + + status = vaBeginPicture(va_display, va_context, picture->surface_id); + if (!vaapi_check_status(status, "vaBeginPicture()")) + return FALSE; + + status = vaRenderPicture(va_display, va_context, va_buffers, n_va_buffers); + if (!vaapi_check_status(status, "vaRenderPicture()")) + return FALSE; + + for (i = 0; i < picture->slices->len; i++) { + GstVaapiSlice * const slice = g_ptr_array_index(picture->slices, i); + + vaapi_unmap_buffer(va_display, slice->param_id, NULL); + va_buffers[0] = slice->param_id; + va_buffers[1] = slice->data_id; + n_va_buffers = 2; + + status = vaRenderPicture( + va_display, + va_context, + va_buffers, n_va_buffers + ); + if (!vaapi_check_status(status, "vaRenderPicture()")) + return FALSE; + } + + status = vaEndPicture(va_display, va_context); + if (!vaapi_check_status(status, "vaEndPicture()")) + return FALSE; + return TRUE; +} + +gboolean +gst_vaapi_picture_output(GstVaapiPicture *picture) +{ + GstVaapiSurfaceProxy *proxy; + gboolean success; + + g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE); + + proxy = gst_vaapi_surface_proxy_new(GET_CONTEXT(picture), picture->surface); + if (!proxy) + return FALSE; + success = gst_vaapi_decoder_push_surface_proxy( + GET_DECODER(picture), + proxy, picture->pts + ); + g_object_unref(proxy); // ref'ed in gst_vaapi_decoder_push_surface_proxy() + return success; +} + +/* ------------------------------------------------------------------------- */ +/* --- Slices --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSlice, + gst_vaapi_slice, + GST_VAAPI_TYPE_CODEC_OBJECT) + +static void +gst_vaapi_slice_destroy(GstVaapiSlice *slice) +{ + VADisplay const va_display = GET_VA_DISPLAY(slice); + + vaapi_destroy_buffer(va_display, &slice->data_id); + vaapi_destroy_buffer(va_display, &slice->param_id); + slice->param = NULL; +} + +static gboolean +gst_vaapi_slice_create( + GstVaapiSlice *slice, + const GstVaapiCodecObjectConstructorArgs *args +) +{ + VASliceParameterBufferBase *slice_param; + guint8 *data; + + data = vaapi_create_buffer( + GET_VA_DISPLAY(slice), + GET_VA_CONTEXT(slice), + VASliceDataBufferType, + args->data_size, + &slice->data_id + ); + if (!data) + return FALSE; + memcpy(data, args->data, args->data_size); + vaapi_unmap_buffer(GET_VA_DISPLAY(slice), slice->data_id, NULL); + + slice->param = vaapi_create_buffer( + GET_VA_DISPLAY(slice), + GET_VA_CONTEXT(slice), + VASliceParameterBufferType, + args->param_size, + &slice->param_id + ); + if (!slice->param) + 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; +} + +static void +gst_vaapi_slice_init(GstVaapiSlice *slice) +{ + slice->param = NULL; + slice->param_id = VA_INVALID_ID; + slice->data_id = VA_INVALID_ID; +} + +GstVaapiSlice * +gst_vaapi_slice_new( + GstVaapiDecoder *decoder, + gconstpointer param, + guint param_size, + const guchar *data, + guint data_size +) +{ + GstVaapiCodecObject *object; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + object = gst_vaapi_codec_object_new( + GST_VAAPI_TYPE_SLICE, + GST_VAAPI_CODEC_BASE(decoder), + param, param_size, + data, data_size + ); + return GST_VAAPI_SLICE_CAST(object); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h new file mode 100644 index 0000000000..2bd1ea9879 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -0,0 +1,253 @@ +/* + * gstvaapidecoder_objects.h - VA decoder objects + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2012 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +typedef enum _GstVaapiPictureType GstVaapiPictureType; +typedef struct _GstVaapiPicture GstVaapiPicture; +typedef struct _GstVaapiPictureClass GstVaapiPictureClass; +typedef struct _GstVaapiSlice GstVaapiSlice; +typedef struct _GstVaapiSliceClass GstVaapiSliceClass; + +/* ------------------------------------------------------------------------- */ +/* --- Pictures --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_TYPE_PICTURE \ + (gst_vaapi_picture_get_type()) + +#define GST_VAAPI_PICTURE_CAST(obj) \ + ((GstVaapiPicture *)(obj)) + +#define GST_VAAPI_PICTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_PICTURE, \ + GstVaapiPicture)) + +#define GST_VAAPI_PICTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_PICTURE, \ + GstVaapiPictureClass)) + +#define GST_VAAPI_IS_PICTURE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_PICTURE)) + +#define GST_VAAPI_IS_PICTURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_PICTURE)) + +#define GST_VAAPI_PICTURE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_PICTURE, \ + GstVaapiPictureClass)) + +enum _GstVaapiPictureType { + 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) +}; + +/** + * Picture flags: + * @GST_VAAPI_PICTURE_FLAG_SKIPPED: skipped frame + * @GST_VAAPI_PICTURE_FLAG_REFERENCE: reference frame + * @GST_VAAPI_PICTURE_FLAG_LAST: first flag that can be used by subclasses + * + * Enum values used for #GstVaapiPicture flags. + */ +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_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 2), +}; + +#define GST_VAAPI_PICTURE_FLAG_IS_SET GST_MINI_OBJECT_FLAG_IS_SET +#define GST_VAAPI_PICTURE_FLAG_SET GST_MINI_OBJECT_FLAG_SET +#define GST_VAAPI_PICTURE_FLAG_UNSET GST_MINI_OBJECT_FLAG_UNSET + +#define GST_VAAPI_PICTURE_IS_REFERENCE(picture) \ + GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE) + +/** + * GstVaapiPicture: + * + * A #GstVaapiCodecObject holding a picture parameter. + */ +struct _GstVaapiPicture { + /*< private >*/ + GstVaapiCodecObject parent_instance; + GstVaapiSurface *surface; + VABufferID param_id; + + /*< public >*/ + GstVaapiPictureType type; + VASurfaceID surface_id; + gpointer param; + GPtrArray *slices; + GstVaapiIqMatrix *iq_matrix; + GstVaapiBitPlane *bitplane; + GstClockTime pts; +}; + +/** + * GstVaapiPictureClass: + * + * The #GstVaapiPicture base class. + */ +struct _GstVaapiPictureClass { + /*< private >*/ + GstVaapiCodecObjectClass parent_class; +}; + +GType +gst_vaapi_picture_get_type(void) + attribute_hidden; + +GstVaapiPicture * +gst_vaapi_picture_new( + GstVaapiDecoder *decoder, + gconstpointer param, + guint param_size +) attribute_hidden; + +void +gst_vaapi_picture_add_slice(GstVaapiPicture *picture, GstVaapiSlice *slice) + attribute_hidden; + +gboolean +gst_vaapi_picture_decode(GstVaapiPicture *picture) + attribute_hidden; + +gboolean +gst_vaapi_picture_output(GstVaapiPicture *picture) + attribute_hidden; + +static inline gpointer +gst_vaapi_picture_ref(gpointer ptr) +{ + return gst_mini_object_ref(GST_MINI_OBJECT(ptr)); +} + +static inline void +gst_vaapi_picture_unref(gpointer ptr) +{ + gst_mini_object_unref(GST_MINI_OBJECT(ptr)); +} + +#define gst_vaapi_picture_replace(old_picture_p, new_picture) \ + gst_mini_object_replace((GstMiniObject **)(old_picture_p), \ + (GstMiniObject *)(new_picture)) + +/* ------------------------------------------------------------------------- */ +/* --- Slices --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_TYPE_SLICE \ + (gst_vaapi_slice_get_type()) + +#define GST_VAAPI_SLICE_CAST(obj) \ + ((GstVaapiSlice *)(obj)) + +#define GST_VAAPI_SLICE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_SLICE, \ + GstVaapiSlice)) + +#define GST_VAAPI_SLICE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_SLICE, \ + GstVaapiSliceClass)) + +#define GST_VAAPI_IS_SLICE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SLICE)) + +#define GST_VAAPI_IS_SLICE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SLICE)) + +#define GST_VAAPI_SLICE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_SLICE, \ + GstVaapiSliceClass)) + +/** + * GstVaapiSlice: + * + * A #GstVaapiCodecObject holding a slice parameter. + */ +struct _GstVaapiSlice { + /*< private >*/ + GstVaapiCodecObject parent_instance; + + /*< public >*/ + VABufferID param_id; + VABufferID data_id; + gpointer param; +}; + +/** + * GstVaapiSliceClass: + * + * The #GstVaapiSlice base class. + */ +struct _GstVaapiSliceClass { + /*< private >*/ + GstVaapiCodecObjectClass parent_class; +}; + +GType +gst_vaapi_slice_get_type(void) + attribute_hidden; + +GstVaapiSlice * +gst_vaapi_slice_new( + GstVaapiDecoder *decoder, + gconstpointer param, + guint param_size, + const guchar *data, + guint data_size +) attribute_hidden; + +/* ------------------------------------------------------------------------- */ +/* --- Helpers to create codec-dependent objects --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_PICTURE_NEW(codec, decoder) \ + gst_vaapi_picture_new(GST_VAAPI_DECODER_CAST(decoder), \ + NULL, sizeof(VAPictureParameterBuffer##codec)) + +#define GST_VAAPI_SLICE_NEW(codec, decoder, buf, buf_size) \ + gst_vaapi_slice_new(GST_VAAPI_DECODER_CAST(decoder), \ + NULL, sizeof(VASliceParameterBuffer##codec), \ + buf, buf_size) + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_OBJECTS_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 2d6d55d6a5..27efee1144 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -109,73 +109,6 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DECODER, \ GstVaapiDecoderPrivate)) -typedef enum _GstVaapiPictureType GstVaapiPictureType; -typedef struct _GstVaapiCodecInfo GstVaapiCodecInfo; -typedef struct _GstVaapiPicture GstVaapiPicture; -typedef struct _GstVaapiSlice GstVaapiSlice; -typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix; -typedef struct _GstVaapiBitPlane GstVaapiBitPlane; - -enum _GstVaapiPictureType { - 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) -}; - -enum { - GST_VAAPI_PICTURE_SKIPPED = 1 << 0, // Skipped frame - GST_VAAPI_PICTURE_REFERENCE = 1 << 1, // Reference frame -}; - -#define GST_VAAPI_PICTURE(picture) \ - ((GstVaapiPicture *)(picture)) - -#define GST_VAAPI_PICTURE_IS_REFERENCE(picture) \ - ((GST_VAAPI_PICTURE(picture)->flags & GST_VAAPI_PICTURE_REFERENCE) != 0) - -struct _GstVaapiCodecInfo { - guint pic_size; // GstVaapiPicture size - guint slice_size; // GstVaapiSlice size - guint pic_param_size; // VAPictureParameterBuffer size - guint slice_param_size; // VASliceParameterBuffer size - guint iq_matrix_size; // VAIQMatrixBuffer size -}; - -struct _GstVaapiPicture { - GstVaapiPictureType type; - guint flags; - guint ref_count; - VASurfaceID surface_id; - GstVaapiSurface *surface; - VABufferID param_id; - void *param; - GPtrArray *slices; - GstVaapiIqMatrix *iq_matrix; - GstVaapiBitPlane *bitplane; - GstClockTime pts; -}; - -struct _GstVaapiSlice { - VABufferID param_id; - void *param; - VABufferID data_id; -}; - -struct _GstVaapiIqMatrix { - VABufferID param_id; - void *param; -}; - -struct _GstVaapiBitPlane { - VABufferID data_id; - guint8 *data; -}; - struct _GstVaapiDecoderPrivate { GstVaapiDisplay *display; VADisplay va_display; @@ -184,7 +117,6 @@ struct _GstVaapiDecoderPrivate { GstCaps *caps; GstVaapiCodec codec; GstBuffer *codec_data; - GstVaapiCodecInfo codec_info; guint width; guint height; guint fps_n; @@ -247,54 +179,6 @@ gst_vaapi_decoder_push_surface_proxy( GstClockTime timestamp ) attribute_hidden; -GstVaapiPicture * -gst_vaapi_decoder_new_picture(GstVaapiDecoder *decoder) - attribute_hidden; - -void -gst_vaapi_decoder_free_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) - attribute_hidden; - -static inline GstVaapiPicture * -gst_vaapi_decoder_ref_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) -{ - ++picture->ref_count; - return picture; -} - -static inline void -gst_vaapi_decoder_unref_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture) -{ - if (--picture->ref_count == 0) - gst_vaapi_decoder_free_picture(decoder, picture); -} - -GstVaapiIqMatrix * -gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder) - attribute_hidden; - -GstVaapiBitPlane * -gst_vaapi_decoder_new_bitplane(GstVaapiDecoder *decoder, guint size) - attribute_hidden; - -GstVaapiSlice * -gst_vaapi_decoder_new_slice( - GstVaapiDecoder *decoder, - GstVaapiPicture *picture, - guchar *buf, - guint buf_size -) attribute_hidden; - -void -gst_vaapi_decoder_free_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice) - attribute_hidden; - -gboolean -gst_vaapi_decoder_decode_picture( - GstVaapiDecoder *decoder, - GstVaapiPicture *picture -) attribute_hidden; - G_END_DECLS #endif /* GST_VAAPI_DECODER_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 0bf52371fe..9f4e6c9e87 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -28,6 +28,7 @@ #include #include #include "gstvaapidecoder_vc1.h" +#include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" @@ -96,23 +97,11 @@ get_status(GstVC1ParserResult result) static void gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderVC1Private * const priv = decoder->priv; - if (priv->current_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->current_picture); - priv->current_picture = NULL; - } - - if (priv->next_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->next_picture); - priv->next_picture = NULL; - } - - if (priv->prev_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); - priv->prev_picture = NULL; - } + gst_vaapi_picture_replace(&priv->current_picture, NULL); + gst_vaapi_picture_replace(&priv->next_picture, NULL); + gst_vaapi_picture_replace(&priv->prev_picture, NULL); if (priv->sub_buffer) { gst_buffer_unref(priv->sub_buffer); @@ -220,11 +209,7 @@ ensure_context(GstVaapiDecoderVC1 *decoder) static inline GstVaapiDecoderStatus render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); - - if (!gst_vaapi_decoder_push_surface(base_decoder, - picture->surface, - picture->pts)) + if (!gst_vaapi_picture_output(picture)) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -232,18 +217,17 @@ render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVaapiPicture * const picture = priv->current_picture; GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; if (picture) { - if (!gst_vaapi_decoder_decode_picture(base_decoder, picture)) + if (!gst_vaapi_picture_decode(picture)) status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { if (priv->prev_picture && priv->next_picture) status = render_picture(decoder, picture); - gst_vaapi_decoder_free_picture(base_decoder, picture); + gst_vaapi_picture_unref(picture); } priv->current_picture = NULL; } @@ -788,7 +772,6 @@ fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) static gboolean fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderVC1Private * const priv = decoder->priv; VAPictureParameterBufferVC1 * const pic_param = picture->param; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; @@ -878,8 +861,8 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) break; } - picture->bitplane = gst_vaapi_decoder_new_bitplane( - base_decoder, + picture->bitplane = GST_VAAPI_BITPLANE_NEW( + decoder, (seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2 ); if (!picture->bitplane) @@ -898,7 +881,6 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) static GstVaapiDecoderStatus decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; @@ -921,7 +903,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) return status; } - priv->current_picture = gst_vaapi_decoder_new_picture(base_decoder); + priv->current_picture = GST_VAAPI_PICTURE_NEW(VC1, decoder); if (!priv->current_picture) { GST_DEBUG("failed to allocate picture"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -949,14 +931,14 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) switch (frame_hdr->ptype) { case GST_VC1_PICTURE_TYPE_I: picture->type = GST_VAAPI_PICTURE_TYPE_I; - picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); break; case GST_VC1_PICTURE_TYPE_SKIPPED: - picture->flags |= GST_VAAPI_PICTURE_SKIPPED; + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_SKIPPED); // fall-through case GST_VC1_PICTURE_TYPE_P: picture->type = GST_VAAPI_PICTURE_TYPE_P; - picture->flags |= GST_VAAPI_PICTURE_REFERENCE; + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); break; case GST_VC1_PICTURE_TYPE_B: picture->type = GST_VAAPI_PICTURE_TYPE_B; @@ -976,7 +958,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) /* Update reference pictures */ if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { if (priv->prev_picture) { - gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture); + gst_vaapi_picture_unref(priv->prev_picture); priv->prev_picture = NULL; } if (priv->next_picture) { @@ -990,9 +972,9 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) if (!fill_picture(decoder, picture)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - slice = gst_vaapi_decoder_new_slice( - base_decoder, - picture, + slice = GST_VAAPI_SLICE_NEW( + VC1, + decoder, ebdu->data + ebdu->sc_offset, ebdu->size + ebdu->offset - ebdu->sc_offset ); @@ -1000,6 +982,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) GST_DEBUG("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } + gst_vaapi_picture_add_slice(picture, slice); /* Fill in VASliceParameterBufferVC1 */ slice_param = slice->param; @@ -1351,14 +1334,6 @@ gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps) { GstVaapiDecoderVC1 *decoder; - static const GstVaapiCodecInfo codec_info = { - .pic_size = sizeof(GstVaapiPicture), - .slice_size = sizeof(GstVaapiSlice), - .pic_param_size = sizeof(VAPictureParameterBufferVC1), - .slice_param_size = sizeof(VASliceParameterBufferVC1), - .iq_matrix_size = 0, - }; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); g_return_val_if_fail(GST_IS_CAPS(caps), NULL); @@ -1366,7 +1341,6 @@ gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps) GST_VAAPI_TYPE_DECODER_VC1, "display", display, "caps", caps, - "codec-info", &codec_info, NULL ); if (!decoder->priv->is_constructed) { From 7b19745141d3d653e84e3512b7235292e7c1e17a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jan 2012 14:54:31 +0100 Subject: [PATCH 0589/3781] decoder: simplify output of decoded frames. Drop obsolete gst_vaapi_decoder_push_surface() that was no longer used. Change gst_vaapi_decoder_push_surface_proxy() semantics to assume PTS is already set correctly and reference count increased, if necessary. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 33 +++----------------- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 25 +++++++++------ gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 11 +++---- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 12 ++----- 4 files changed, 27 insertions(+), 54 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index e0d1b7b209..2f54e7a43d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -122,21 +122,15 @@ decode_step(GstVaapiDecoder *decoder) return status; } -static gboolean -push_surface( - GstVaapiDecoder *decoder, - GstVaapiSurfaceProxy *proxy, - GstClockTime timestamp -) +static inline void +push_surface(GstVaapiDecoder *decoder, GstVaapiSurfaceProxy *proxy) { GstVaapiDecoderPrivate * const priv = decoder->priv; GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id(proxy))); - gst_vaapi_surface_proxy_set_timestamp(proxy, timestamp); g_queue_push_tail(priv->surfaces, proxy); - return TRUE; } static inline GstVaapiSurfaceProxy * @@ -559,28 +553,11 @@ gst_vaapi_decoder_push_buffer_sub( return TRUE; } -gboolean -gst_vaapi_decoder_push_surface( - GstVaapiDecoder *decoder, - GstVaapiSurface *surface, - GstClockTime timestamp -) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVaapiSurfaceProxy *proxy; - - proxy = gst_vaapi_surface_proxy_new(priv->context, surface); - if (!proxy) - return FALSE; - return push_surface(decoder, proxy, timestamp); -} - -gboolean +void gst_vaapi_decoder_push_surface_proxy( GstVaapiDecoder *decoder, - GstVaapiSurfaceProxy *proxy, - GstClockTime timestamp + GstVaapiSurfaceProxy *proxy ) { - return push_surface(decoder, g_object_ref(proxy), timestamp); + return push_surface(decoder, proxy); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 8fb9099d8e..21425ac884 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -483,12 +483,26 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) return TRUE; } +static GstVaapiDecoderStatus +render_frame(GstVaapiDecoderFfmpeg *decoder, AVFrame *frame) +{ + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiSurfaceProxy *proxy; + + proxy = GST_VAAPI_SURFACE_PROXY(frame->data[0]); + if (!proxy) + return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; + + gst_vaapi_surface_proxy_set_timestamp(proxy, frame->pts); + gst_vaapi_decoder_push_surface_proxy(base_decoder, g_object_ref(proxy)); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) { GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(ffdecoder); - GstVaapiSurfaceProxy *proxy; int bytes_read, got_picture = 0; AVPacket pkt; @@ -509,14 +523,7 @@ decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) if (bytes_read < 0) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - proxy = GST_VAAPI_SURFACE_PROXY(priv->frame->data[0]); - if (!proxy) - return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; - - if (!gst_vaapi_decoder_push_surface_proxy(GST_VAAPI_DECODER_CAST(ffdecoder), - proxy, priv->frame->pts)) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + return render_frame(ffdecoder, priv->frame); } GstVaapiDecoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 61ff4e6b19..c25e86cfea 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -224,19 +224,16 @@ gboolean gst_vaapi_picture_output(GstVaapiPicture *picture) { GstVaapiSurfaceProxy *proxy; - gboolean success; g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE); proxy = gst_vaapi_surface_proxy_new(GET_CONTEXT(picture), picture->surface); if (!proxy) return FALSE; - success = gst_vaapi_decoder_push_surface_proxy( - GET_DECODER(picture), - proxy, picture->pts - ); - g_object_unref(proxy); // ref'ed in gst_vaapi_decoder_push_surface_proxy() - return success; + + gst_vaapi_surface_proxy_set_timestamp(proxy, picture->pts); + gst_vaapi_decoder_push_surface_proxy(GET_DECODER(picture), proxy); + return TRUE; } /* ------------------------------------------------------------------------- */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 27efee1144..87ce200b21 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -165,18 +165,10 @@ gst_vaapi_decoder_push_buffer_sub( guint size ) attribute_hidden; -gboolean -gst_vaapi_decoder_push_surface( - GstVaapiDecoder *decoder, - GstVaapiSurface *surface, - GstClockTime timestamp -) attribute_hidden; - -gboolean +void gst_vaapi_decoder_push_surface_proxy( GstVaapiDecoder *decoder, - GstVaapiSurfaceProxy *proxy, - GstClockTime timestamp + GstVaapiSurfaceProxy *proxy ) attribute_hidden; G_END_DECLS From 2897618b852c0f8e25df40f8980e1c2c5c59653e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jan 2012 15:19:14 +0100 Subject: [PATCH 0590/3781] decoder: properly reference count pictures. This fixes cases where a GstVaapiPicture would be destroyed whereas there is still a valid instance of it in either prev, current or next picture. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 17 +++++------------ gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 17 +++++------------ gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 17 +++++------------ 3 files changed, 15 insertions(+), 36 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 33edc0f3de..e888426264 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -274,9 +274,8 @@ decode_current_picture(GstVaapiDecoderMpeg2 *decoder) if ((priv->prev_picture && priv->next_picture) || (priv->closed_gop && priv->next_picture)) status = render_picture(decoder, picture); - gst_vaapi_picture_unref(picture); } - priv->current_picture = NULL; + gst_vaapi_picture_replace(&priv->current_picture, NULL); } return status; } @@ -494,16 +493,10 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) /* Update reference pictures */ if (pic_hdr->pic_type != GST_MPEG_VIDEO_PICTURE_TYPE_B) { GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - if (priv->prev_picture) { - gst_vaapi_picture_unref(priv->prev_picture); - priv->prev_picture = NULL; - } - if (priv->next_picture) { - priv->prev_picture = priv->next_picture; - priv->next_picture = NULL; - status = render_picture(decoder, priv->prev_picture); - } - priv->next_picture = picture; + if (priv->next_picture) + status = render_picture(decoder, priv->next_picture); + gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture); + gst_vaapi_picture_replace(&priv->next_picture, picture); } return status; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index a81f19b790..24a675712c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -273,9 +273,8 @@ decode_current_picture(GstVaapiDecoderMpeg4 *decoder) if ((priv->prev_picture && priv->next_picture) || (priv->closed_gop && priv->next_picture)) status = render_picture(decoder, picture); - gst_vaapi_picture_unref(picture); } - priv->curr_picture = NULL; + gst_vaapi_picture_replace(&priv->curr_picture, NULL); } return status; } @@ -569,16 +568,10 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) /* Update reference pictures */ /* XXX: consider priv->vol_hdr.low_delay, consider packed video frames for DivX/XviD */ if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { - if (priv->prev_picture) { - gst_vaapi_picture_unref(priv->prev_picture); - priv->prev_picture = NULL; - } - if (priv->next_picture) { - priv->prev_picture = priv->next_picture; - priv->next_picture = NULL; - status = render_picture(decoder, priv->prev_picture); - } - priv->next_picture = picture; + if (priv->next_picture) + status = render_picture(decoder, priv->next_picture); + gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture); + gst_vaapi_picture_replace(&priv->next_picture, picture); } return status; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 9f4e6c9e87..b305b28b8d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -227,9 +227,8 @@ decode_current_picture(GstVaapiDecoderVC1 *decoder) if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { if (priv->prev_picture && priv->next_picture) status = render_picture(decoder, picture); - gst_vaapi_picture_unref(picture); } - priv->current_picture = NULL; + gst_vaapi_picture_replace(&priv->current_picture, NULL); } return status; } @@ -957,16 +956,10 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) /* Update reference pictures */ if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { - if (priv->prev_picture) { - gst_vaapi_picture_unref(priv->prev_picture); - priv->prev_picture = NULL; - } - if (priv->next_picture) { - priv->prev_picture = priv->next_picture; - priv->next_picture = NULL; - status = render_picture(decoder, priv->prev_picture); - } - priv->next_picture = picture; + if (priv->next_picture) + status = render_picture(decoder, priv->next_picture); + gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture); + gst_vaapi_picture_replace(&priv->next_picture, picture); } if (!fill_picture(decoder, picture)) From 4a46b5d6c4a54fcb50828ee2b590d46b5f409906 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jan 2012 15:28:42 +0100 Subject: [PATCH 0591/3781] decoder: retain proxy surface until the GstVaapiPicture is destroyed. Keep a valid reference to the proxy in GstVaapiPicture so that frames marked as "used for reference" could be kept during the lifetime of the picture. i.e. don't release them too soon as they could be re-used right away. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 21 ++++++++++++++++---- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 1 + 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index c25e86cfea..ed5f3c7803 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -71,6 +71,11 @@ gst_vaapi_picture_destroy(GstVaapiPicture *picture) picture->bitplane = NULL; } + if (picture->proxy) { + g_object_unref(picture->proxy); + picture->proxy = NULL; + } + picture->surface_id = VA_INVALID_ID; picture->surface = NULL; @@ -110,6 +115,7 @@ gst_vaapi_picture_init(GstVaapiPicture *picture) { picture->type = GST_VAAPI_PICTURE_TYPE_NONE; picture->surface = NULL; + picture->proxy = NULL; picture->surface_id = VA_INVALID_ID; picture->param = NULL; picture->param_id = VA_INVALID_ID; @@ -227,12 +233,19 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE); - proxy = gst_vaapi_surface_proxy_new(GET_CONTEXT(picture), picture->surface); - if (!proxy) - return FALSE; + proxy = picture->proxy; + if (!proxy) { + proxy = gst_vaapi_surface_proxy_new( + GET_CONTEXT(picture), + picture->surface + ); + if (!proxy) + return FALSE; + picture->proxy = proxy; + } gst_vaapi_surface_proxy_set_timestamp(proxy, picture->pts); - gst_vaapi_decoder_push_surface_proxy(GET_DECODER(picture), proxy); + gst_vaapi_decoder_push_surface_proxy(GET_DECODER(picture), g_object_ref(proxy)); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 2bd1ea9879..6bdfe2cb5c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -105,6 +105,7 @@ struct _GstVaapiPicture { /*< private >*/ GstVaapiCodecObject parent_instance; GstVaapiSurface *surface; + GstVaapiSurfaceProxy *proxy; VABufferID param_id; /*< public >*/ From c071f80f405a5bcb7aad69a4b89c337bbe625d83 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 12 Aug 2011 17:43:55 +0200 Subject: [PATCH 0592/3781] Add initial H.264 decoder. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1942 +++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 87 + gst/vaapi/gstvaapidecode.c | 5 +- tests/test-decode.c | 4 + 5 files changed, 2039 insertions(+), 1 deletion(-) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_h264.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_h264.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index b2cd2ccc6b..8e0b104ac4 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -146,12 +146,14 @@ endif if USE_CODEC_PARSERS libgstvaapi_source_c += \ gstvaapicodec_objects.c \ + gstvaapidecoder_h264.c \ gstvaapidecoder_mpeg2.c \ gstvaapidecoder_mpeg4.c \ gstvaapidecoder_objects.c \ gstvaapidecoder_vc1.c \ $(NULL) libgstvaapi_source_h += \ + gstvaapidecoder_h264.h \ gstvaapidecoder_mpeg2.h \ gstvaapidecoder_mpeg4.h \ gstvaapidecoder_vc1.h \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c new file mode 100644 index 0000000000..80f4153233 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -0,0 +1,1942 @@ +/* + * gstvaapidecoder_h264.c - H.264 decoder + * + * Copyright (C) 2011-2012 Intel Corporation + * + * 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_h264 + * @short_description: H.264 decoder + */ + +#include "config.h" +#include +#include +#include "gstvaapidecoder_h264.h" +#include "gstvaapidecoder_objects.h" +#include "gstvaapidecoder_priv.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapiobject_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; +typedef struct _GstVaapiPictureH264Class GstVaapiPictureH264Class; +typedef struct _GstVaapiSliceH264 GstVaapiSliceH264; +typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class; + +/* ------------------------------------------------------------------------- */ +/* --- H.264 Pictures --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_TYPE_PICTURE_H264 \ + (gst_vaapi_picture_h264_get_type()) + +#define GST_VAAPI_PICTURE_H264_CAST(obj) \ + ((GstVaapiPictureH264 *)(obj)) + +#define GST_VAAPI_PICTURE_H264(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_PICTURE_H264, \ + GstVaapiPictureH264)) + +#define GST_VAAPI_PICTURE_H264_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_PICTURE_H264, \ + GstVaapiPictureH264Class)) + +#define GST_VAAPI_IS_PICTURE_H264(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_PICTURE_H264)) + +#define GST_VAAPI_IS_PICTURE_H264_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_PICTURE_H264)) + +#define GST_VAAPI_PICTURE_H264_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_PICTURE_H264, \ + GstVaapiPictureH264Class)) + +struct _GstVaapiPictureH264 { + GstVaapiPicture base; + VAPictureH264 info; + gint32 poc; + gint32 frame_num; // Original frame_num from slice_header() + gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap + gint32 pic_num; // Temporary for ref pic marking: PicNum + gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum + guint is_idr : 1; + guint is_long_term : 1; + guint field_pic_flag : 1; + guint bottom_field_flag : 1; + guint has_mmco_5 : 1; +}; + +struct _GstVaapiPictureH264Class { + /*< private >*/ + GstVaapiPictureClass parent_class; +}; + +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264, + gst_vaapi_picture_h264, + GST_VAAPI_TYPE_PICTURE) + +static void +gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *decoder) +{ +} + +static gboolean +gst_vaapi_picture_h264_create( + GstVaapiPictureH264 *picture, + const GstVaapiCodecObjectConstructorArgs *args +) +{ + return TRUE; +} + +static void +gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture) +{ + VAPictureH264 *va_pic; + + va_pic = &picture->info; + va_pic->flags = 0; + va_pic->TopFieldOrderCnt = 0; + va_pic->BottomFieldOrderCnt = 0; + + picture->poc = 0; + picture->is_long_term = FALSE; + picture->is_idr = FALSE; + picture->has_mmco_5 = FALSE; +} + +static inline GstVaapiPictureH264 * +gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder) +{ + GstVaapiCodecObject *object; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + object = gst_vaapi_codec_object_new( + GST_VAAPI_TYPE_PICTURE_H264, + GST_VAAPI_CODEC_BASE(decoder), + NULL, sizeof(VAPictureParameterBufferH264), + NULL, 0 + ); + if (!object) + return NULL; + return GST_VAAPI_PICTURE_H264_CAST(object); +} + +/* ------------------------------------------------------------------------- */ +/* --- Slices --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_TYPE_SLICE_H264 \ + (gst_vaapi_slice_h264_get_type()) + +#define GST_VAAPI_SLICE_H264_CAST(obj) \ + ((GstVaapiSliceH264 *)(obj)) + +#define GST_VAAPI_SLICE_H264(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_SLICE_H264, \ + GstVaapiSliceH264)) + +#define GST_VAAPI_SLICE_H264_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_SLICE_H264, \ + GstVaapiSliceH264Class)) + +#define GST_VAAPI_IS_SLICE_H264(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SLICE_H264)) + +#define GST_VAAPI_IS_SLICE_H264_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SLICE_H264)) + +#define GST_VAAPI_SLICE_H264_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_SLICE_H264, \ + GstVaapiSliceH264Class)) + +struct _GstVaapiSliceH264 { + GstVaapiSlice base; + GstH264SliceHdr slice_hdr; // parsed slice_header() +}; + +struct _GstVaapiSliceH264Class { + /*< private >*/ + GstVaapiSliceClass parent_class; +}; + +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSliceH264, + gst_vaapi_slice_h264, + GST_VAAPI_TYPE_SLICE) + +static void +gst_vaapi_slice_h264_destroy(GstVaapiSliceH264 *slice) +{ +} + +static gboolean +gst_vaapi_slice_h264_create( + GstVaapiSliceH264 *slice, + const GstVaapiCodecObjectConstructorArgs *args +) +{ + return TRUE; +} + +static void +gst_vaapi_slice_h264_init(GstVaapiSliceH264 *slice) +{ +} + +static inline GstVaapiSliceH264 * +gst_vaapi_slice_h264_new( + GstVaapiDecoderH264 *decoder, + const guint8 *data, + guint data_size +) +{ + GstVaapiCodecObject *object; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + object = gst_vaapi_codec_object_new( + GST_VAAPI_TYPE_SLICE_H264, + GST_VAAPI_CODEC_BASE(decoder), + NULL, sizeof(VASliceParameterBufferH264), + data, data_size + ); + if (!object) + return NULL; + return GST_VAAPI_SLICE_H264_CAST(object); +} + +/* ------------------------------------------------------------------------- */ +/* --- H.264 Decoder --- */ +/* ------------------------------------------------------------------------- */ + +G_DEFINE_TYPE(GstVaapiDecoderH264, + gst_vaapi_decoder_h264, + GST_VAAPI_TYPE_DECODER); + +#define GST_VAAPI_DECODER_H264_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DECODER_H264, \ + GstVaapiDecoderH264Private)) + +// Used for field_poc[] +#define TOP_FIELD 0 +#define BOTTOM_FIELD 1 + +struct _GstVaapiDecoderH264Private { + GstBuffer *sub_buffer; + GstH264NalParser *parser; + GstH264SPS *sps; + GstH264PPS *pps; + GstVaapiPictureH264 *current_picture; + GstVaapiPictureH264 *dpb[16]; + guint dpb_count; + GstVaapiProfile profile; + GstVaapiPictureH264 *short_ref[32]; + guint short_ref_count; + GstVaapiPictureH264 *long_ref[32]; + guint long_ref_count; + guint list_count; + GstVaapiPictureH264 *RefPicList0[32]; + guint RefPicList0_count; + GstVaapiPictureH264 *RefPicList1[32]; + guint RefPicList1_count; + guint width; + guint height; + guint mb_x; + guint mb_y; + guint mb_width; + guint mb_height; + guint8 scaling_list_4x4[6][16]; + guint8 scaling_list_8x8[6][64]; + gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt + gint32 poc_msb; // PicOrderCntMsb + gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header()) + gint32 prev_poc_msb; // prevPicOrderCntMsb + gint32 prev_poc_lsb; // prevPicOrderCntLsb + gint32 frame_num_offset; // FrameNumOffset + gint32 prev_frame_num_offset; // prevFrameNumOffset + gint32 frame_num; // frame_num (from slice_header()) + gint32 prev_frame_num; // prevFrameNum + guint is_constructed : 1; + guint is_opened : 1; +}; + +static gboolean +decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture); + +static void +clear_references( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 **pictures, + guint *picture_count +); + +static GstVaapiDecoderStatus +get_status(GstH264ParserResult result) +{ + GstVaapiDecoderStatus status; + + switch (result) { + case GST_H264_PARSER_OK: + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + case GST_H264_PARSER_NO_NAL_END: + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + break; + case GST_H264_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_h264_close(GstVaapiDecoderH264 *decoder) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + guint i; + + gst_vaapi_picture_replace(&priv->current_picture, NULL); + clear_references(decoder, priv->short_ref, &priv->short_ref_count); + clear_references(decoder, priv->long_ref, &priv->long_ref_count ); + + if (priv->sub_buffer) { + gst_buffer_unref(priv->sub_buffer); + priv->sub_buffer = NULL; + } + + if (priv->parser) { + gst_h264_nal_parser_free(priv->parser); + priv->parser = NULL; + } + + if (priv->dpb_count > 0) { + for (i = 0; i < priv->dpb_count; i++) + priv->dpb[i] = NULL; + priv->dpb_count = 0; + } +} + +static gboolean +gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + + gst_vaapi_decoder_h264_close(decoder); + + priv->parser = gst_h264_nal_parser_new(); + if (!priv->parser) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_decoder_h264_destroy(GstVaapiDecoderH264 *decoder) +{ + gst_vaapi_decoder_h264_close(decoder); +} + +static gboolean +gst_vaapi_decoder_h264_create(GstVaapiDecoderH264 *decoder) +{ + if (!GST_VAAPI_DECODER_CODEC(decoder)) + return FALSE; + return TRUE; +} + +static GstVaapiDecoderStatus +ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiProfile profiles[2]; + GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; + guint i, n_profiles = 0; + gboolean success, reset_context = FALSE; + + if (priv->sps != sps || priv->sps->profile_idc != sps->profile_idc) { + GST_DEBUG("profile changed"); + reset_context = TRUE; + + switch (sps->profile_idc) { + case 66: + profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE; + break; + case 77: + profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_MAIN; + // fall-through + case 100: + profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; + break; + default: + GST_DEBUG("unsupported profile %d", sps->profile_idc); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + + for (i = 0; i < n_profiles; i++) { + success = gst_vaapi_display_has_decoder( + GST_VAAPI_DECODER_DISPLAY(decoder), + profiles[i], + entrypoint + ); + if (success) + break; + } + if (i == n_profiles) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + priv->profile = profiles[i]; + } + + if (priv->sps != sps || priv->sps->chroma_format_idc != sps->chroma_format_idc) { + GST_DEBUG("chroma format changed"); + reset_context = TRUE; + + /* XXX: theoritically, we could handle 4:2:2 format */ + if (sps->chroma_format_idc != 1) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; + } + + if (priv->sps != sps || + priv->sps->width != sps->width || + priv->sps->height != sps->height) { + GST_DEBUG("size changed"); + reset_context = TRUE; + + priv->width = sps->width; + priv->height = sps->height; + priv->mb_width = sps->pic_width_in_mbs_minus1 + 1; + priv->mb_height = sps->pic_height_in_map_units_minus1 + 1; + priv->mb_height *= 2 - sps->frame_mbs_only_flag; + } + + if (reset_context) { + success = gst_vaapi_decoder_ensure_context( + GST_VAAPI_DECODER(decoder), + priv->profile, + entrypoint, + priv->width, priv->height + ); + if (!success) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstH264PPS *pps) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + + if (priv->pps != pps) { + memcpy(priv->scaling_list_4x4, pps->scaling_lists_4x4, + sizeof(priv->scaling_list_4x4)); + memcpy(priv->scaling_list_8x8, pps->scaling_lists_8x8, + sizeof(priv->scaling_list_8x8)); + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static gboolean +decode_current_picture(GstVaapiDecoderH264 *decoder) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiPictureH264 * const picture = priv->current_picture; + gboolean success = FALSE; + + if (!picture) + return TRUE; + + if (!decode_picture_end(decoder, picture)) + goto end; + if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture))) + goto end; + if (!gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture))) + goto end; + success = TRUE; +end: + gst_vaapi_picture_replace(&priv->current_picture, NULL); + return success; +} + +static GstVaapiDecoderStatus +decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264SPS sps; + GstH264ParserResult result; + + GST_DEBUG("decode SPS"); + + memset(&sps, 0, sizeof(sps)); + result = gst_h264_parser_parse_sps(priv->parser, nalu, &sps, TRUE); + if (result != GST_H264_PARSER_OK) + return get_status(result); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264PPS pps; + GstH264ParserResult result; + + GST_DEBUG("decode PPS"); + + memset(&pps, 0, sizeof(pps)); + result = gst_h264_parser_parse_pps(priv->parser, nalu, &pps); + if (result != GST_H264_PARSER_OK) + return get_status(result); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sei(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264SEIMessage sei; + GstH264ParserResult result; + + GST_DEBUG("decode SEI"); + + memset(&sei, 0, sizeof(sei)); + result = gst_h264_parser_parse_sei(priv->parser, nalu, &sei); + if (result != GST_H264_PARSER_OK) + return get_status(result); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence_end(GstVaapiDecoderH264 *decoder) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + + GST_DEBUG("decode sequence-end"); + + if (priv->current_picture && !decode_current_picture(decoder)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; +} + +/* 8.2.1.1 - Decoding process for picture order count type 0 */ +static void +init_picture_poc_0( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264PPS * const pps = slice_hdr->pps; + GstH264SPS * const sps = pps->sequence; + const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); + + GST_DEBUG("decode picture order count type 0"); + + // (8-3) + priv->poc_lsb = slice_hdr->pic_order_cnt_lsb; + if (priv->poc_lsb < priv->prev_poc_lsb && + (priv->prev_poc_lsb - priv->poc_lsb) >= (MaxPicOrderCntLsb / 2)) + priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb; + else if (priv->poc_lsb > priv->prev_poc_lsb && + (priv->poc_lsb - priv->prev_poc_lsb) > (MaxPicOrderCntLsb / 2)) + priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb; + else + priv->poc_msb = priv->prev_poc_msb; + + // (8-4) + if (!slice_hdr->field_pic_flag || !slice_hdr->bottom_field_flag) + priv->field_poc[TOP_FIELD] = priv->poc_msb + priv->poc_lsb; + + // (8-5) + if (!slice_hdr->field_pic_flag) + priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] + + slice_hdr->delta_pic_order_cnt_bottom; + else if (slice_hdr->bottom_field_flag) + priv->field_poc[BOTTOM_FIELD] = priv->poc_msb + priv->poc_lsb; +} + +/* 8.2.1.2 - Decoding process for picture order count type 1 */ +static void +init_picture_poc_1( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264PPS * const pps = slice_hdr->pps; + GstH264SPS * const sps = pps->sequence; + const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); + gint32 abs_frame_num, expected_poc; + guint i; + + GST_DEBUG("decode picture order count type 1"); + + // (8-6) + if (picture->is_idr) + priv->frame_num_offset = 0; + else if (priv->prev_frame_num > priv->frame_num) + priv->frame_num_offset = priv->prev_frame_num_offset + MaxFrameNum; + else + priv->frame_num_offset = priv->prev_frame_num_offset; + + // (8-7) + if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0) + abs_frame_num = priv->frame_num_offset + priv->frame_num; + else + abs_frame_num = 0; + if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture) && abs_frame_num > 0) + abs_frame_num = abs_frame_num - 1; + + if (abs_frame_num > 0) { + gint32 expected_delta_per_poc_cycle; + gint32 poc_cycle_cnt, frame_num_in_poc_cycle; + + expected_delta_per_poc_cycle = 0; + for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++) + expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i]; + + // (8-8) + poc_cycle_cnt = (abs_frame_num - 1) / + sps->num_ref_frames_in_pic_order_cnt_cycle; + frame_num_in_poc_cycle = (abs_frame_num - 1) % + sps->num_ref_frames_in_pic_order_cnt_cycle; + + // (8-9) + expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle; + for (i = 0; i <= frame_num_in_poc_cycle; i++) + expected_poc += sps->offset_for_ref_frame[i]; + } + else + expected_poc = 0; + if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) + expected_poc += sps->offset_for_non_ref_pic; + + // (8-10) + if (!slice_hdr->field_pic_flag) { + priv->field_poc[TOP_FIELD] = expected_poc + + slice_hdr->delta_pic_order_cnt[0]; + priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] + + sps->offset_for_top_to_bottom_field + + slice_hdr->delta_pic_order_cnt[1]; + } + else if (!slice_hdr->bottom_field_flag) + priv->field_poc[TOP_FIELD] = expected_poc + + slice_hdr->delta_pic_order_cnt[0]; + else + priv->field_poc[BOTTOM_FIELD] = expected_poc + + sps->offset_for_top_to_bottom_field + slice_hdr->delta_pic_order_cnt[0]; +} + +/* 8.2.1.3 - Decoding process for picture order count type 2 */ +static void +init_picture_poc_2( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264PPS * const pps = slice_hdr->pps; + GstH264SPS * const sps = pps->sequence; + const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); + guint temp_poc; + + GST_DEBUG("decode picture order count type 2"); + + // (8-11) + if (picture->is_idr) + priv->frame_num_offset = 0; + else if (priv->prev_frame_num > priv->frame_num) + priv->frame_num_offset = priv->prev_frame_num_offset + MaxFrameNum; + else + priv->frame_num_offset = priv->prev_frame_num_offset; + + // (8-12) + if (picture->is_idr) + temp_poc = 0; + else if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) + temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1; + else + temp_poc = 2 * (priv->frame_num_offset + priv->frame_num); + + // (8-13) + if (!slice_hdr->field_pic_flag) { + priv->field_poc[TOP_FIELD] = temp_poc; + priv->field_poc[BOTTOM_FIELD] = temp_poc; + } + else if (slice_hdr->bottom_field_flag) + priv->field_poc[BOTTOM_FIELD] = temp_poc; + else + priv->field_poc[TOP_FIELD] = temp_poc; +} + +/* 8.2.1 - Decoding process for picture order count */ +static void +init_picture_poc( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + VAPictureH264 * const pic = &picture->info; + GstH264PPS * const pps = slice_hdr->pps; + GstH264SPS * const sps = pps->sequence; + + switch (sps->pic_order_cnt_type) { + case 0: + init_picture_poc_0(decoder, picture, slice_hdr); + break; + case 1: + init_picture_poc_1(decoder, picture, slice_hdr); + break; + case 2: + init_picture_poc_2(decoder, picture, slice_hdr); + break; + } + + if (!(pic->flags & VA_PICTURE_H264_BOTTOM_FIELD)) + pic->TopFieldOrderCnt = priv->field_poc[TOP_FIELD]; + if (!(pic->flags & VA_PICTURE_H264_TOP_FIELD)) + pic->BottomFieldOrderCnt = priv->field_poc[BOTTOM_FIELD]; + picture->poc = MIN(pic->TopFieldOrderCnt, pic->BottomFieldOrderCnt); +} + +static int +compare_picture_pic_num_dec(const void *a, const void *b) +{ + const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; + const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + + return picB->pic_num - picA->pic_num; +} + +static int +compare_picture_long_term_pic_num_inc(const void *a, const void *b) +{ + const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; + const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + + return picA->long_term_pic_num - picB->long_term_pic_num; +} + +static int +compare_picture_poc_dec(const void *a, const void *b) +{ + const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; + const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + + return picB->poc - picA->poc; +} + +static int +compare_picture_poc_inc(const void *a, const void *b) +{ + const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; + const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + + return picA->poc - picB->poc; +} + +static int +compare_picture_frame_num_wrap_dec(const void *a, const void *b) +{ + const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; + const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + + return picB->frame_num_wrap - picA->frame_num_wrap; +} + +static int +compare_picture_long_term_frame_idx_inc(const void *a, const void *b) +{ + const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; + const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + + return picA->info.frame_idx - picB->info.frame_idx; +} + +/* 8.2.4.1 - Decoding process for picture numbers */ +static void +init_picture_refs_pic_num( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264PPS * const pps = slice_hdr->pps; + GstH264SPS * const sps = pps->sequence; + const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); + const guint field_flags = VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD; + guint i; + + GST_DEBUG("decode picture numbers"); + + for (i = 0; i < priv->short_ref_count; i++) { + GstVaapiPictureH264 * const pic = priv->short_ref[i]; + + // (8-27) + if (pic->frame_num > priv->frame_num) + pic->frame_num_wrap = pic->frame_num - MaxFrameNum; + else + pic->frame_num_wrap = pic->frame_num; + + // (8-28, 8-30, 8-31) + if (!pic->field_pic_flag) + pic->pic_num = pic->frame_num_wrap; + else { + if (((picture->info.flags ^ pic->info.flags) & field_flags) == 0) + pic->pic_num = 2 * pic->frame_num_wrap + 1; + else + pic->pic_num = 2 * pic->frame_num_wrap; + } + } + + for (i = 0; i < priv->long_ref_count; i++) { + GstVaapiPictureH264 * const pic = priv->long_ref[i]; + + // (8-29, 8-32, 8-33) + if (!pic->field_pic_flag) + pic->long_term_pic_num = pic->info.frame_idx; + else { + if (((picture->info.flags ^ pic->info.flags) & field_flags) == 0) + pic->long_term_pic_num = 2 * pic->info.frame_idx + 1; + else + pic->long_term_pic_num = 2 * pic->info.frame_idx; + } + } +} + +#define SORT_REF_LIST(list, n, compare_func) \ + qsort(list, n, sizeof(*(list)), compare_picture_##compare_func) + +static void +init_picture_refs_p_slice( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiPictureH264 **ref_list; + guint i; + + GST_DEBUG("decode reference picture list for P and SP slices"); + + if (!picture->field_pic_flag) { + /* 8.2.4.2.1 - P and SP slices in frames */ + if (priv->short_ref_count > 0) { + ref_list = priv->RefPicList0; + for (i = 0; i < priv->short_ref_count; i++) + ref_list[i] = priv->short_ref[i]; + SORT_REF_LIST(ref_list, i, pic_num_dec); + priv->RefPicList0_count += i; + } + + if (priv->long_ref_count > 0) { + ref_list = &priv->RefPicList0[priv->RefPicList0_count]; + for (i = 0; i < priv->long_ref_count; i++) + ref_list[i] = priv->long_ref[i]; + SORT_REF_LIST(ref_list, i, long_term_pic_num_inc); + priv->RefPicList0_count += i; + } + } + else { + /* 8.2.4.2.2 - P and SP slices in fields */ + GstVaapiPictureH264 *short_ref[32]; + guint short_ref_count = 0; + GstVaapiPictureH264 *long_ref[32]; + guint long_ref_count = 0; + + // XXX: handle second field if current field is marked as + // "used for short-term reference" + if (priv->short_ref_count > 0) { + for (i = 0; i < priv->short_ref_count; i++) + short_ref[i] = priv->short_ref[i]; + SORT_REF_LIST(short_ref, i, frame_num_wrap_dec); + short_ref_count = i; + } + + // XXX: handle second field if current field is marked as + // "used for long-term reference" + if (priv->long_ref_count > 0) { + for (i = 0; i < priv->long_ref_count; i++) + long_ref[i] = priv->long_ref[i]; + SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc); + long_ref_count = i; + } + + // XXX: handle 8.2.4.2.5 + } +} + +static void +init_picture_refs_b_slice( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiPictureH264 **ref_list; + guint i, n; + + GST_DEBUG("decode reference picture list for B slices"); + + if (!picture->field_pic_flag) { + /* 8.2.4.2.3 - B slices in frames */ + + /* RefPicList0 */ + if (priv->short_ref_count > 0) { + // 1. Short-term references + ref_list = priv->RefPicList0; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->poc < picture->poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST(ref_list, n, poc_dec); + priv->RefPicList0_count += n; + + ref_list = &priv->RefPicList0[priv->RefPicList0_count]; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->poc >= picture->poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST(ref_list, n, poc_inc); + priv->RefPicList0_count += n; + } + + if (priv->long_ref_count > 0) { + // 2. Long-term references + ref_list = &priv->RefPicList0[priv->RefPicList0_count]; + for (n = 0, i = 0; i < priv->long_ref_count; i++) + ref_list[n++] = priv->long_ref[i]; + SORT_REF_LIST(ref_list, n, long_term_pic_num_inc); + priv->RefPicList0_count += n; + } + + /* RefPicList1 */ + if (priv->short_ref_count > 0) { + // 1. Short-term references + ref_list = priv->RefPicList1; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->poc > picture->poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST(ref_list, n, poc_inc); + priv->RefPicList1_count += n; + + ref_list = &priv->RefPicList1[priv->RefPicList1_count]; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->poc <= picture->poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST(ref_list, n, poc_dec); + priv->RefPicList1_count += n; + } + + if (priv->long_ref_count > 0) { + // 2. Long-term references + ref_list = &priv->RefPicList1[priv->RefPicList1_count]; + for (n = 0, i = 0; i < priv->long_ref_count; i++) + ref_list[n++] = priv->long_ref[i]; + SORT_REF_LIST(ref_list, n, long_term_pic_num_inc); + priv->RefPicList1_count += n; + } + } + else { + /* 8.2.4.2.4 - B slices in fields */ + GstVaapiPictureH264 *short_ref0[32]; + guint short_ref0_count = 0; + GstVaapiPictureH264 *short_ref1[32]; + guint short_ref1_count = 0; + GstVaapiPictureH264 *long_ref[32]; + guint long_ref_count = 0; + + /* refFrameList0ShortTerm */ + if (priv->short_ref_count > 0) { + ref_list = short_ref0; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->poc <= picture->poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST(ref_list, n, poc_dec); + short_ref0_count += n; + + ref_list = &short_ref0[short_ref0_count]; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->poc > picture->poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST(ref_list, n, poc_inc); + short_ref0_count += n; + } + + /* refFrameList1ShortTerm */ + if (priv->short_ref_count > 0) { + ref_list = short_ref1; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->poc > picture->poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST(ref_list, n, poc_inc); + short_ref1_count += n; + + ref_list = &short_ref1[short_ref1_count]; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->poc <= picture->poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST(ref_list, n, poc_dec); + short_ref1_count += n; + } + + /* refFrameListLongTerm */ + if (priv->long_ref_count > 0) { + for (i = 0; i < priv->long_ref_count; i++) + long_ref[i] = priv->long_ref[i]; + SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc); + long_ref_count = i; + } + + // XXX: handle 8.2.4.2.5 + } + + /* Check whether RefPicList1 is identical to RefPicList0, then + swap if necessary */ + if (priv->RefPicList1_count > 1 && + priv->RefPicList1_count == priv->RefPicList0_count && + memcmp(priv->RefPicList0, priv->RefPicList1, + priv->RefPicList0_count * sizeof(priv->RefPicList0[0])) == 0) { + GstVaapiPictureH264 * const tmp = priv->RefPicList1[0]; + priv->RefPicList1[0] = priv->RefPicList1[1]; + priv->RefPicList1[1] = tmp; + } +} + +#undef SORT_REF_LIST + +static void +clear_references( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 **pictures, + guint *picture_count +) +{ + const guint num_pictures = *picture_count; + guint i; + + for (i = 0; i < num_pictures; i++) + gst_vaapi_picture_replace(&pictures[i], NULL); + *picture_count = 0; +} + +static gint +find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + guint i; + + for (i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->pic_num == pic_num) + return i; + } + GST_ERROR("found no short-term reference picture with PicNum = %d", + pic_num); + return -1; +} + +static gint +find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + guint i; + + for (i = 0; i < priv->long_ref_count; i++) { + if (priv->long_ref[i]->long_term_pic_num == long_term_pic_num) + return i; + } + GST_ERROR("found no long-term reference picture with LongTermPicNum = %d", + long_term_pic_num); + return -1; +} + +static void +exec_picture_refs_modification_1( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr, + guint list +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264PPS * const pps = slice_hdr->pps; + GstH264SPS * const sps = pps->sequence; + GstH264RefPicListModification *ref_pic_list_modification; + guint num_ref_pic_list_modifications; + GstVaapiPictureH264 **ref_list; + guint *ref_list_count_ptr, ref_list_count, ref_list_idx = 0; + guint i, j, n, num_refs; + gint found_ref_idx; + gint32 MaxPicNum, CurrPicNum, picNumPred; + + GST_DEBUG("modification process of reference picture list %u", list); + + if (list == 0) { + ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l0; + num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0; + ref_list = priv->RefPicList0; + ref_list_count_ptr = &priv->RefPicList0_count; + num_refs = slice_hdr->num_ref_idx_l0_active_minus1 + 1; + } + else { + ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l1; + num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1; + ref_list = priv->RefPicList1; + ref_list_count_ptr = &priv->RefPicList1_count; + num_refs = slice_hdr->num_ref_idx_l1_active_minus1 + 1; + } + ref_list_count = *ref_list_count_ptr; + + if (picture->field_pic_flag) { + MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum + CurrPicNum = 2 * slice_hdr->frame_num + 1; // 2 * frame_num + 1 + } + else { + MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 4); // MaxFrameNum + CurrPicNum = slice_hdr->frame_num; // frame_num + } + + picNumPred = CurrPicNum; + + for (i = 0; i < num_ref_pic_list_modifications; i++) { + GstH264RefPicListModification * const l = &ref_pic_list_modification[i]; + if (l->modification_of_pic_nums_idc == 3) + break; + + /* 8.2.4.3.1 - Short-term reference pictures */ + if (l->modification_of_pic_nums_idc == 0 || l->modification_of_pic_nums_idc == 1) { + gint32 abs_diff_pic_num = l->value.abs_diff_pic_num_minus1 + 1; + gint32 picNum, picNumNoWrap; + + // (8-34) + if (l->modification_of_pic_nums_idc == 0) { + picNumNoWrap = picNumPred - abs_diff_pic_num; + if (picNumNoWrap < 0) + picNumNoWrap += MaxPicNum; + } + + // (8-35) + else { + picNumNoWrap = picNumPred + abs_diff_pic_num; + if (picNumNoWrap >= MaxPicNum) + picNumNoWrap -= MaxPicNum; + } + picNumPred = picNumNoWrap; + + // (8-36) + picNum = picNumNoWrap; + if (picNum > CurrPicNum) + picNum -= MaxPicNum; + + for (j = num_refs; j > ref_list_idx; j--) + ref_list[j] = ref_list[j - 1]; + found_ref_idx = find_short_term_reference(decoder, picNum); + ref_list[ref_list_idx++] = + found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL; + n = ref_list_idx; + for (j = ref_list_idx; j < num_refs; j++) { + const gint32 PicNumF = ref_list[j]->is_long_term ? + MaxPicNum : ref_list[j]->pic_num; + if (PicNumF != picNum) + ref_list[n++] = ref_list[j]; + } + } + + /* 8.2.4.3.2 - Long-term reference pictures */ + else { + + for (j = num_refs; j > ref_list_idx; j--) + ref_list[j] = ref_list[j - 1]; + found_ref_idx = + find_long_term_reference(decoder, l->value.long_term_pic_num); + ref_list[ref_list_idx++] = + found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL; + n = ref_list_idx; + for (j = ref_list_idx; j < num_refs; j++) { + const gint32 LongTermPicNumF = ref_list[j]->is_long_term ? + ref_list[j]->long_term_pic_num : INT_MAX; + if (LongTermPicNumF != l->value.long_term_pic_num) + ref_list[n++] = ref_list[j]; + } + } + } + +#if DEBUG + for (i = 0; i < num_refs; i++) + if (!ref_list[i]) + GST_ERROR("list %u entry %u is empty", list, i); +#endif + *ref_list_count_ptr = num_refs; +} + +/* 8.2.4.3 - Modification process for reference picture lists */ +static void +exec_picture_refs_modification( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr +) +{ + GST_DEBUG("execute ref_pic_list_modification()"); + + /* RefPicList0 */ + if (!GST_H264_IS_I_SLICE(slice_hdr) && !GST_H264_IS_SI_SLICE(slice_hdr) && + slice_hdr->ref_pic_list_modification_flag_l0) + exec_picture_refs_modification_1(decoder, picture, slice_hdr, 0); + + /* RefPicList1 */ + if (GST_H264_IS_B_SLICE(slice_hdr) && + slice_hdr->ref_pic_list_modification_flag_l1) + exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1); +} + +static gboolean +init_picture_refs( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiPicture * const base_picture = &picture->base; + guint i, num_refs; + + init_picture_refs_pic_num(decoder, picture, slice_hdr); + + priv->RefPicList0_count = 0; + priv->RefPicList1_count = 0; + + switch (base_picture->type) { + case GST_VAAPI_PICTURE_TYPE_P: + case GST_VAAPI_PICTURE_TYPE_SP: + init_picture_refs_p_slice(decoder, picture, slice_hdr); + break; + case GST_VAAPI_PICTURE_TYPE_B: + init_picture_refs_b_slice(decoder, picture, slice_hdr); + break; + default: + break; + } + + exec_picture_refs_modification(decoder, picture, slice_hdr); + + switch (base_picture->type) { + case GST_VAAPI_PICTURE_TYPE_B: + num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1; + for (i = priv->RefPicList1_count; i < num_refs; i++) + priv->RefPicList1[i] = NULL; + priv->RefPicList1_count = num_refs; + + // fall-through + case GST_VAAPI_PICTURE_TYPE_P: + case GST_VAAPI_PICTURE_TYPE_SP: + num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1; + for (i = priv->RefPicList0_count; i < num_refs; i++) + priv->RefPicList0[i] = NULL; + priv->RefPicList0_count = num_refs; + break; + default: + break; + } + return TRUE; +} + +static gboolean +init_picture( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr, + GstH264NalUnit *nalu +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiPicture * const base_picture = &picture->base; + VAPictureH264 *pic; + guint i; + + priv->frame_num = slice_hdr->frame_num; + picture->frame_num = priv->frame_num; + picture->is_idr = nalu->type == GST_H264_NAL_SLICE_IDR; + picture->field_pic_flag = slice_hdr->field_pic_flag; + picture->bottom_field_flag = slice_hdr->bottom_field_flag; + + /* Reset decoder state for IDR pictures */ + if (picture->is_idr) { + GST_DEBUG(""); + clear_references(decoder, priv->short_ref, &priv->short_ref_count); + clear_references(decoder, priv->long_ref, &priv->long_ref_count ); + priv->prev_poc_msb = 0; + priv->prev_poc_lsb = 0; + } + + /* Initialize VA picture info */ + pic = &picture->info; + pic->picture_id = picture->base.surface_id; + pic->frame_idx = priv->frame_num; + if (picture->field_pic_flag) { + if (picture->bottom_field_flag) + pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD; + else + pic->flags |= VA_PICTURE_H264_TOP_FIELD; + } + + /* Initialize base picture */ + switch (slice_hdr->type % 5) { + case GST_H264_P_SLICE: + base_picture->type = GST_VAAPI_PICTURE_TYPE_P; + break; + case GST_H264_B_SLICE: + base_picture->type = GST_VAAPI_PICTURE_TYPE_B; + break; + case GST_H264_I_SLICE: + base_picture->type = GST_VAAPI_PICTURE_TYPE_I; + break; + case GST_H264_SP_SLICE: + base_picture->type = GST_VAAPI_PICTURE_TYPE_SP; + break; + case GST_H264_SI_SLICE: + base_picture->type = GST_VAAPI_PICTURE_TYPE_SI; + break; + } + + if (nalu->ref_idc) { + GstH264DecRefPicMarking * const dec_ref_pic_marking = + &slice_hdr->dec_ref_pic_marking; + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + if (picture->is_idr) { + if (dec_ref_pic_marking->long_term_reference_flag) + picture->is_long_term = TRUE; + } + else if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) { + for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) { + GstH264RefPicMarking * const ref_pic_marking = + &dec_ref_pic_marking->ref_pic_marking[i]; + switch (ref_pic_marking->memory_management_control_operation) { + case 3: + case 6: + picture->is_long_term = TRUE; + pic->frame_idx = ref_pic_marking->long_term_frame_idx; + break; + case 5: + picture->has_mmco_5 = TRUE; + break; + } + } + } + if (picture->is_long_term) + pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE; + else + pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE; + } + + init_picture_poc(decoder, picture, slice_hdr); + if (!init_picture_refs(decoder, picture, slice_hdr)) { + GST_DEBUG("failed to initialize references"); + return FALSE; + } + return TRUE; +} + +/* Update picture order count */ +static void +exit_picture_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264SPS * const sps = priv->sps; + + switch (sps->pic_order_cnt_type) { + case 0: + if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) + break; + if (picture->has_mmco_5) { + priv->prev_poc_msb = 0; + if (!picture->field_pic_flag || !picture->bottom_field_flag) + priv->prev_poc_lsb = picture->info.TopFieldOrderCnt; + else + priv->prev_poc_lsb = 0; + } + else { + priv->prev_poc_msb = priv->poc_msb; + priv->prev_poc_lsb = priv->poc_lsb; + } + break; + case 1: + case 2: + priv->prev_frame_num = priv->frame_num; + if (picture->has_mmco_5) + priv->prev_frame_num_offset = 0; + else + priv->prev_frame_num_offset = priv->frame_num_offset; + break; + } +} + +static inline gboolean +exit_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiPictureH264 **picture_ptr; + + /* Update picture order count */ + exit_picture_poc(decoder, picture); + + /* Decoded reference picture marking process */ + if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) + return TRUE; + if (picture->is_long_term) { + g_assert(priv->long_ref_count < G_N_ELEMENTS(priv->long_ref)); + picture_ptr = &priv->long_ref[priv->long_ref_count++]; + } + else { + g_assert(priv->short_ref_count < G_N_ELEMENTS(priv->short_ref)); + picture_ptr = &priv->short_ref[priv->short_ref_count++]; + } + gst_vaapi_picture_replace(picture_ptr, picture); + return TRUE; +} + +static void +vaapi_init_picture(VAPictureH264 *pic) +{ + pic->picture_id = VA_INVALID_ID; + pic->frame_idx = 0; + pic->flags = VA_PICTURE_H264_INVALID; + pic->TopFieldOrderCnt = 0; + pic->BottomFieldOrderCnt = 0; +} + +static gboolean +fill_picture( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr, + GstH264NalUnit *nalu +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiPicture * const base_picture = &picture->base; + GstH264SPS * const sps = priv->sps; + GstH264PPS * const pps = priv->pps; + VAPictureParameterBufferH264 * const pic_param = base_picture->param; + guint i, n; + + /* Fill in VAPictureParameterBufferH264 */ + pic_param->CurrPic = picture->info; + for (i = 0, n = 0; i < priv->short_ref_count; i++) + pic_param->ReferenceFrames[n++] = priv->short_ref[i]->info; + for (i = 0; i < priv->long_ref_count; i++) + pic_param->ReferenceFrames[n++] = priv->long_ref[i]->info; + for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++) + vaapi_init_picture(&pic_param->ReferenceFrames[n]); + +#define COPY_FIELD(s, f) \ + pic_param->f = (s)->f + +#define COPY_BFM(a, s, f) \ + pic_param->a.bits.f = (s)->f + + pic_param->picture_width_in_mbs_minus1 = priv->mb_width - 1; + pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1; + pic_param->frame_num = priv->frame_num; + + COPY_FIELD(sps, bit_depth_luma_minus8); + COPY_FIELD(sps, bit_depth_chroma_minus8); + COPY_FIELD(sps, num_ref_frames); + COPY_FIELD(pps, num_slice_groups_minus1); + COPY_FIELD(pps, slice_group_map_type); + COPY_FIELD(pps, slice_group_change_rate_minus1); + COPY_FIELD(pps, pic_init_qp_minus26); + COPY_FIELD(pps, pic_init_qs_minus26); + COPY_FIELD(pps, chroma_qp_index_offset); + COPY_FIELD(pps, second_chroma_qp_index_offset); + + pic_param->seq_fields.value = 0; /* reset all bits */ + pic_param->seq_fields.bits.residual_colour_transform_flag = sps->separate_colour_plane_flag; + pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */ + + COPY_BFM(seq_fields, sps, chroma_format_idc); + COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag); + COPY_BFM(seq_fields, sps, frame_mbs_only_flag); + COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag); + COPY_BFM(seq_fields, sps, direct_8x8_inference_flag); + COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4); + COPY_BFM(seq_fields, sps, pic_order_cnt_type); + COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4); + COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag); + + pic_param->pic_fields.value = 0; /* reset all bits */ + pic_param->pic_fields.bits.field_pic_flag = slice_hdr->field_pic_flag; + pic_param->pic_fields.bits.reference_pic_flag = GST_VAAPI_PICTURE_IS_REFERENCE(picture); + + COPY_BFM(pic_fields, pps, entropy_coding_mode_flag); + COPY_BFM(pic_fields, pps, weighted_pred_flag); + COPY_BFM(pic_fields, pps, weighted_bipred_idc); + COPY_BFM(pic_fields, pps, transform_8x8_mode_flag); + COPY_BFM(pic_fields, pps, constrained_intra_pred_flag); + COPY_BFM(pic_fields, pps, pic_order_present_flag); + COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag); + COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag); + return TRUE; +} + +static gboolean +fill_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + VAIQMatrixBufferH264 * const iq_matrix = picture->base.iq_matrix->param; + + /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[] + is not large enough to hold lists for 4:4:4 */ + if (priv->sps->chroma_format_idc == 3 && + sizeof(iq_matrix->ScalingList8x8) != sizeof(priv->scaling_list_8x8)) + return FALSE; + + /* Fill in VAIQMatrixBufferH264 */ + memcpy(iq_matrix->ScalingList4x4, priv->scaling_list_4x4, + sizeof(iq_matrix->ScalingList4x4)); + memcpy(iq_matrix->ScalingList8x8, priv->scaling_list_8x8, + sizeof(iq_matrix->ScalingList8x8)); + return TRUE; +} + +static GstVaapiDecoderStatus +decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceHdr *slice_hdr) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiPictureH264 *picture; + GstVaapiDecoderStatus status; + GstH264PPS * const pps = slice_hdr->pps; + GstH264SPS * const sps = pps->sequence; + + status = ensure_context(decoder, sps); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_DEBUG("failed to reset context"); + return status; + } + + if (priv->current_picture && !decode_current_picture(decoder)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + picture = gst_vaapi_picture_h264_new(decoder); + if (!picture) { + GST_DEBUG("failed to allocate picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + priv->current_picture = picture; + + picture->base.iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder); + if (!picture->base.iq_matrix) { + GST_DEBUG("failed to allocate IQ matrix"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + status = ensure_quant_matrix(decoder, pps); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_DEBUG("failed to reset quantizer matrix"); + return status; + } + + priv->sps = sps; + priv->pps = pps; + + if (!init_picture(decoder, picture, slice_hdr, nalu)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + if (!fill_picture(decoder, picture, slice_hdr, nalu)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static gboolean +decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +{ + if (!fill_quant_matrix(decoder, picture)) + return FALSE; + exit_picture(decoder, picture); + return TRUE; +} + +static gboolean +fill_slice(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264SliceHdr * const slice_hdr = &slice->slice_hdr; + GstH264PPS * const pps = slice_hdr->pps; + GstH264SPS * const sps = pps->sequence; + GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table; + VASliceParameterBufferH264 * const slice_param = slice->base.param; + gint i, j; + + /* Fill in VASliceParameterBufferH264 */ + slice_param->slice_data_bit_offset = 8 /* nal_unit_type */ + slice_hdr->header_size; + slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice; + slice_param->slice_type = slice_hdr->type % 5; + slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag; + slice_param->num_ref_idx_l0_active_minus1 = priv->list_count > 0 ? slice_hdr->num_ref_idx_l0_active_minus1 : 0; + slice_param->num_ref_idx_l1_active_minus1 = priv->list_count > 1 ? slice_hdr->num_ref_idx_l1_active_minus1 : 0; + slice_param->cabac_init_idc = slice_hdr->cabac_init_idc; + slice_param->slice_qp_delta = slice_hdr->slice_qp_delta; + slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc; + slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2; + slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2; + slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom; + slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom; + + for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++) + slice_param->RefPicList0[i] = priv->RefPicList0[i]->info; + for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++) + vaapi_init_picture(&slice_param->RefPicList0[i]); + + for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++) + slice_param->RefPicList1[i] = priv->RefPicList1[i]->info; + for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++) + vaapi_init_picture(&slice_param->RefPicList1[i]); + + slice_param->luma_weight_l0_flag = priv->list_count > 0; + if (slice_param->luma_weight_l0_flag) { + for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { + slice_param->luma_weight_l0[i] = w->luma_weight_l0[i]; + slice_param->luma_offset_l0[i] = w->luma_offset_l0[i]; + } + } + + slice_param->chroma_weight_l0_flag = priv->list_count > 0 && sps->chroma_array_type != 0; + if (slice_param->chroma_weight_l0_flag) { + for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { + for (j = 0; j < 2; j++) { + slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j]; + slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j]; + } + } + } + + slice_param->luma_weight_l1_flag = priv->list_count > 1; + if (slice_param->luma_weight_l1_flag) { + for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { + slice_param->luma_weight_l1[i] = w->luma_weight_l1[i]; + slice_param->luma_offset_l1[i] = w->luma_offset_l1[i]; + } + } + + slice_param->chroma_weight_l1_flag = priv->list_count > 1 && sps->chroma_array_type != 0; + if (slice_param->chroma_weight_l1_flag) { + for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { + for (j = 0; j < 2; j++) { + slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j]; + slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j]; + } + } + } + return TRUE; +} + +static GstVaapiDecoderStatus +decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + GstVaapiPictureH264 *picture; + GstVaapiSliceH264 *slice = NULL; + GstH264SliceHdr *slice_hdr; + GstH264ParserResult result; + + GST_DEBUG("slice (%u bytes)", nalu->size); + + slice = gst_vaapi_slice_h264_new( + decoder, + nalu->data + nalu->offset, + nalu->size + ); + if (!slice) { + GST_DEBUG("failed to allocate slice"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + slice_hdr = &slice->slice_hdr; + memset(slice_hdr, 0, sizeof(*slice_hdr)); + result = gst_h264_parser_parse_slice_hdr(priv->parser, nalu, slice_hdr, TRUE, TRUE); + if (result != GST_H264_PARSER_OK) { + status = get_status(result); + goto error; + } + + if (slice_hdr->first_mb_in_slice == 0) { + status = decode_picture(decoder, nalu, slice_hdr); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto error; + } + picture = priv->current_picture; + + priv->list_count = (GST_H264_IS_B_SLICE(slice_hdr) ? 2 : + (GST_H264_IS_I_SLICE(slice_hdr) ? 0 : 1)); + + priv->mb_x = slice_hdr->first_mb_in_slice % priv->mb_width; + priv->mb_y = slice_hdr->first_mb_in_slice / priv->mb_width; // FIXME: MBAFF or field + + if (!fill_slice(decoder, slice)) { + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + goto error; + } + gst_vaapi_picture_add_slice( + GST_VAAPI_PICTURE_CAST(picture), + GST_VAAPI_SLICE_CAST(slice) + ); + + /* Commit picture for decoding if we reached the last slice */ + if (++priv->mb_y >= priv->mb_height) { + if (!decode_current_picture(decoder)) { + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + goto error; + } + GST_DEBUG("done"); + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; + +error: + if (slice) + gst_mini_object_unref(GST_MINI_OBJECT(slice)); + return status; +} + +static GstVaapiDecoderStatus +decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + GstH264ParserResult result; + GstH264NalUnit nalu; + guchar *buf; + guint buf_size, ofs; + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + if (!buf && buf_size == 0) + return decode_sequence_end(decoder); + + if (priv->sub_buffer) { + buffer = gst_buffer_merge(priv->sub_buffer, buffer); + if (!buffer) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + gst_buffer_unref(priv->sub_buffer); + priv->sub_buffer = NULL; + } + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + ofs = 0; + do { + result = gst_h264_parser_identify_nalu( + priv->parser, + buf, ofs, buf_size, + &nalu + ); + status = get_status(result); + + if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) { + priv->sub_buffer = gst_buffer_create_sub(buffer, ofs, buf_size - ofs); + break; + } + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + break; + + ofs = nalu.offset + nalu.size; + switch (nalu.type) { + case GST_H264_NAL_SLICE_IDR: + /* fall-through. IDR specifics are handled in init_picture() */ + case GST_H264_NAL_SLICE: + status = decode_slice(decoder, &nalu); + break; + case GST_H264_NAL_SPS: + status = decode_sps(decoder, &nalu); + break; + case GST_H264_NAL_PPS: + status = decode_pps(decoder, &nalu); + break; + case GST_H264_NAL_SEI: + status = decode_sei(decoder, &nalu); + break; + case GST_H264_NAL_SEQ_END: + status = decode_sequence_end(decoder); + break; + default: + GST_DEBUG("unsupported NAL unit type %d", nalu.type); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); + return status; +} + +GstVaapiDecoderStatus +gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base, GstBuffer *buffer) +{ + GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base); + GstVaapiDecoderH264Private * const priv = decoder->priv; + + g_return_val_if_fail(priv->is_constructed, + GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); + + if (!priv->is_opened) { + priv->is_opened = gst_vaapi_decoder_h264_open(decoder, buffer); + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + } + return decode_buffer(decoder, buffer); +} + +static void +gst_vaapi_decoder_h264_finalize(GObject *object) +{ + GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object); + + gst_vaapi_decoder_h264_destroy(decoder); + + G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class)->finalize(object); +} + +static void +gst_vaapi_decoder_h264_constructed(GObject *object) +{ + GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object); + GstVaapiDecoderH264Private * const priv = decoder->priv; + GObjectClass *parent_class; + + parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); + + priv->is_constructed = gst_vaapi_decoder_h264_create(decoder); +} + +static void +gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiDecoderH264Private)); + + object_class->finalize = gst_vaapi_decoder_h264_finalize; + object_class->constructed = gst_vaapi_decoder_h264_constructed; + + decoder_class->decode = gst_vaapi_decoder_h264_decode; +} + +static void +gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) +{ + GstVaapiDecoderH264Private *priv; + + priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder); + decoder->priv = priv; + priv->parser = NULL; + priv->sps = NULL; + priv->pps = NULL; + priv->current_picture = NULL; + priv->dpb_count = 0; + priv->profile = GST_VAAPI_PROFILE_H264_HIGH; + priv->short_ref_count = 0; + priv->long_ref_count = 0; + priv->list_count = 0; + priv->RefPicList0_count = 0; + priv->RefPicList1_count = 0; + priv->width = 0; + priv->height = 0; + priv->mb_x = 0; + priv->mb_y = 0; + priv->mb_width = 0; + priv->mb_height = 0; + priv->sub_buffer = NULL; + priv->field_poc[0] = 0; + priv->field_poc[1] = 0; + priv->poc_msb = 0; + priv->poc_lsb = 0; + priv->prev_poc_msb = 0; + priv->prev_poc_lsb = 0; + priv->frame_num_offset = 0; + priv->prev_frame_num_offset = 0; + priv->frame_num = 0; + priv->prev_frame_num = 0; + priv->is_constructed = FALSE; + priv->is_opened = FALSE; + + memset(priv->dpb, 0, sizeof(priv->dpb)); + memset(priv->short_ref, 0, sizeof(priv->short_ref)); + memset(priv->long_ref, 0, sizeof(priv->long_ref)); + memset(priv->RefPicList0, 0, sizeof(priv->RefPicList0)); + memset(priv->RefPicList1, 0, sizeof(priv->RefPicList1)); +} + +/** + * gst_vaapi_decoder_h264_new: + * @display: a #GstVaapiDisplay + * @caps: a #GstCaps holding codec information + * + * Creates a new #GstVaapiDecoder for MPEG-2 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_h264_new(GstVaapiDisplay *display, GstCaps *caps) +{ + GstVaapiDecoderH264 *decoder; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + decoder = g_object_new( + GST_VAAPI_TYPE_DECODER_H264, + "display", display, + "caps", caps, + NULL + ); + if (!decoder->priv->is_constructed) { + g_object_unref(decoder); + return NULL; + } + return GST_VAAPI_DECODER_CAST(decoder); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h new file mode 100644 index 0000000000..5ba47763d4 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -0,0 +1,87 @@ +/* + * gstvaapidecoder_h264.h - H.264 decoder + * + * Copyright (C) 2011-2012 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DECODER_H264 \ + (gst_vaapi_decoder_h264_get_type()) + +#define GST_VAAPI_DECODER_H264(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DECODER_H264, \ + GstVaapiDecoderH264)) + +#define GST_VAAPI_DECODER_H264_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DECODER_H264, \ + GstVaapiDecoderH264Class)) + +#define GST_VAAPI_IS_DECODER_H264(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_H264)) + +#define GST_VAAPI_IS_DECODER_H264_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_H264)) + +#define GST_VAAPI_DECODER_H264_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DECODER_H264, \ + GstVaapiDecoderH264Class)) + +typedef struct _GstVaapiDecoderH264 GstVaapiDecoderH264; +typedef struct _GstVaapiDecoderH264Private GstVaapiDecoderH264Private; +typedef struct _GstVaapiDecoderH264Class GstVaapiDecoderH264Class; + +/** + * GstVaapiDecoderH264: + * + * A decoder based on H264. + */ +struct _GstVaapiDecoderH264 { + /*< private >*/ + GstVaapiDecoder parent_instance; + + GstVaapiDecoderH264Private *priv; +}; + +/** + * GstVaapiDecoderH264Class: + * + * A decoder class based on H264. + */ +struct _GstVaapiDecoderH264Class { + /*< private >*/ + GstVaapiDecoderClass parent_class; +}; + +GType +gst_vaapi_decoder_h264_get_type(void); + +GstVaapiDecoder * +gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps); + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_H264_H */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 7193b2c916..c95bd98393 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -50,6 +50,7 @@ # include #endif #if USE_CODEC_PARSERS +# include # include # include # include @@ -311,7 +312,9 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) structure = gst_caps_get_structure(caps, 0); if (!structure) return FALSE; - if (gst_structure_has_name(structure, "video/mpeg")) { + if (gst_structure_has_name(structure, "video/x-h264")) + decode->decoder = gst_vaapi_decoder_h264_new(dpy, caps); + else if (gst_structure_has_name(structure, "video/mpeg")) { if (!gst_structure_get_int(structure, "mpegversion", &version)) return FALSE; if (version == 2) diff --git a/tests/test-decode.c b/tests/test-decode.c index 3758137244..895c862371 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -34,6 +34,7 @@ # include #endif #if USE_CODEC_PARSERS +# include # include # include #endif @@ -165,6 +166,9 @@ main(int argc, char *argv[]) else { #if USE_CODEC_PARSERS switch (gst_vaapi_profile_get_codec(info.profile)) { + case GST_VAAPI_CODEC_H264: + decoder = gst_vaapi_decoder_h264_new(display, decoder_caps); + break; case GST_VAAPI_CODEC_MPEG2: decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); break; From 6d61965531dc99d482676991e6fc07e212a4925a Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 25 Nov 2011 14:37:00 +0200 Subject: [PATCH 0593/3781] h264: handle codec-data. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 79 ++++++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 80f4153233..dd38108e34 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -265,6 +265,7 @@ struct _GstVaapiDecoderH264Private { guint RefPicList0_count; GstVaapiPictureH264 *RefPicList1[32]; guint RefPicList1_count; + guint nal_length_size; guint width; guint height; guint mb_x; @@ -1810,11 +1811,77 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) return status; } +static GstVaapiDecoderStatus +decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + GstH264NalUnit nalu; + GstH264ParserResult result; + guchar *buf; + guint buf_size; + guint i, ofs, num_sps, num_pps; + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + if (!buf || buf_size == 0) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (buf_size < 8) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + if (buf[0] != 1) { + GST_DEBUG("failed to decode codec-data, not in avcC format"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + priv->nal_length_size = (buf[4] & 0x03) + 1; + + num_sps = buf[5] & 0x1f; + ofs = 6; + + for (i = 0; i < num_sps; i++) { + result = gst_h264_parser_identify_nalu_avc( + priv->parser, + buf, ofs, buf_size, 2, + &nalu + ); + if (result != GST_H264_PARSER_OK) + return get_status(result); + + status = decode_sps(decoder, &nalu); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + ofs = nalu.offset + nalu.size; + } + + num_pps = buf[ofs]; + ofs++; + + for (i = 0; i < num_pps; i++) { + result = gst_h264_parser_identify_nalu_avc( + priv->parser, + buf, ofs, buf_size, 2, + &nalu + ); + if (result != GST_H264_PARSER_OK) + return get_status(result); + + status = decode_pps(decoder, &nalu); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + ofs = nalu.offset + nalu.size; + } + return status; +} + GstVaapiDecoderStatus gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base, GstBuffer *buffer) { GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base); GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + GstBuffer *codec_data; g_return_val_if_fail(priv->is_constructed, GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); @@ -1823,8 +1890,15 @@ gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base, GstBuffer *buffer) priv->is_opened = gst_vaapi_decoder_h264_open(decoder, buffer); if (!priv->is_opened) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; - } - return decode_buffer(decoder, buffer); + + codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); + if (codec_data) { + status = decode_codec_data(decoder, codec_data); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + } + return decode_buffer(decoder, buffer); } static void @@ -1883,6 +1957,7 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->list_count = 0; priv->RefPicList0_count = 0; priv->RefPicList1_count = 0; + priv->nal_length_size = 0; priv->width = 0; priv->height = 0; priv->mb_x = 0; From 5a795b439c5009cb660d69191f9a1522f1618052 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 17 Jan 2012 10:42:49 +0100 Subject: [PATCH 0594/3781] h264: handle avcC format for decoding buffers. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 25 +++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index dd38108e34..835c66077f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -285,6 +285,7 @@ struct _GstVaapiDecoderH264Private { gint32 prev_frame_num; // prevFrameNum guint is_constructed : 1; guint is_opened : 1; + guint is_avc : 1; }; static gboolean @@ -1769,11 +1770,20 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) buf_size = GST_BUFFER_SIZE(buffer); ofs = 0; do { - result = gst_h264_parser_identify_nalu( - priv->parser, - buf, ofs, buf_size, - &nalu - ); + if (priv->is_avc) { + result = gst_h264_parser_identify_nalu_avc( + priv->parser, + buf, ofs, buf_size, priv->nal_length_size, + &nalu + ); + } + else { + result = gst_h264_parser_identify_nalu( + priv->parser, + buf, ofs, buf_size, + &nalu + ); + } status = get_status(result); if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) { @@ -1807,7 +1817,7 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } - } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size); return status; } @@ -1872,6 +1882,8 @@ decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) return status; ofs = nalu.offset + nalu.size; } + + priv->is_avc = TRUE; return status; } @@ -1977,6 +1989,7 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->prev_frame_num = 0; priv->is_constructed = FALSE; priv->is_opened = FALSE; + priv->is_avc = FALSE; memset(priv->dpb, 0, sizeof(priv->dpb)); memset(priv->short_ref, 0, sizeof(priv->short_ref)); From 16ccf82363909e5e66c02319f1589c96ff69ec12 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 18 Jan 2012 13:38:34 +0100 Subject: [PATCH 0595/3781] h264: execute reference picture marking process (sliding window). --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 128 +++++++++++++++++++--- 1 file changed, 114 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 835c66077f..78ca386341 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -320,6 +320,16 @@ get_status(GstH264ParserResult result) return status; } +static inline GstH264DecRefPicMarking * +get_dec_ref_pic_marking(GstVaapiPictureH264 *picture_h264) +{ + GstVaapiPicture * const picture = GST_VAAPI_PICTURE_CAST(picture_h264); + GstVaapiSliceH264 *slice; + + slice = g_ptr_array_index(picture->slices, picture->slices->len - 1); + return &slice->slice_hdr.dec_ref_pic_marking; +} + static void gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) { @@ -1066,6 +1076,25 @@ clear_references( *picture_count = 0; } +static gboolean +remove_reference_at( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 **pictures, + guint *picture_count, + guint index +) +{ + guint num_pictures = *picture_count; + + g_return_val_if_fail(index < num_pictures, FALSE); + + if (index != --num_pictures) + gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]); + gst_vaapi_picture_replace(&pictures[num_pictures], NULL); + *picture_count = num_pictures; + return TRUE; +} + static gint find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num) { @@ -1302,6 +1331,7 @@ init_picture( priv->frame_num = slice_hdr->frame_num; picture->frame_num = priv->frame_num; + picture->frame_num_wrap = priv->frame_num; picture->is_idr = nalu->type == GST_H264_NAL_SLICE_IDR; picture->field_pic_flag = slice_hdr->field_pic_flag; picture->bottom_field_flag = slice_hdr->bottom_field_flag; @@ -1383,6 +1413,88 @@ init_picture( return TRUE; } +/* 8.2.5.3 - Sliding window decoded reference picture marking process */ +static gboolean +exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264SPS * const sps = priv->sps; + guint i, max_num_ref_frames, lowest_frame_num_index; + gint32 lowest_frame_num; + + GST_DEBUG("reference picture marking process (sliding window)"); + + max_num_ref_frames = sps->num_ref_frames; + if (max_num_ref_frames == 0) + max_num_ref_frames = 1; + + if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames) + return TRUE; + if (priv->short_ref_count < 1) + return FALSE; + + lowest_frame_num = priv->short_ref[0]->frame_num_wrap; + lowest_frame_num_index = 0; + for (i = 1; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->frame_num_wrap < lowest_frame_num) { + lowest_frame_num = priv->short_ref[i]->frame_num_wrap; + lowest_frame_num_index = i; + } + } + + remove_reference_at( + decoder, + priv->short_ref, &priv->short_ref_count, + lowest_frame_num_index + ); + return TRUE; +} + +/* 8.2.5.4 - Adaptive memory control decoded reference picture marking process */ +static gboolean +exec_ref_pic_marking_adaptive( + GstVaapiDecoderH264 *decoder, + GstH264DecRefPicMarking *dec_ref_pic_marking +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + + GST_DEBUG("reference picture marking process (adaptive memory control)"); + + return TRUE; +} + +/* 8.2.5 - Execute reference picture marking process */ +static gboolean +exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiPictureH264 **picture_ptr; + + if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) + return TRUE; + + if (!picture->is_idr) { + GstH264DecRefPicMarking * const dec_ref_pic_marking = + get_dec_ref_pic_marking(picture); + if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) { + if (!exec_ref_pic_marking_adaptive(decoder, dec_ref_pic_marking)) + return FALSE; + } + else { + if (!exec_ref_pic_marking_sliding_window(decoder)) + return FALSE; + } + } + + if (picture->is_long_term) + picture_ptr = &priv->long_ref[priv->long_ref_count++]; + else + picture_ptr = &priv->short_ref[priv->short_ref_count++]; + gst_vaapi_picture_replace(picture_ptr, picture); + return TRUE; +} + /* Update picture order count */ static void exit_picture_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) @@ -1420,24 +1532,12 @@ exit_picture_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) static inline gboolean exit_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { - GstVaapiDecoderH264Private * const priv = decoder->priv; - GstVaapiPictureH264 **picture_ptr; - /* Update picture order count */ exit_picture_poc(decoder, picture); /* Decoded reference picture marking process */ - if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) - return TRUE; - if (picture->is_long_term) { - g_assert(priv->long_ref_count < G_N_ELEMENTS(priv->long_ref)); - picture_ptr = &priv->long_ref[priv->long_ref_count++]; - } - else { - g_assert(priv->short_ref_count < G_N_ELEMENTS(priv->short_ref)); - picture_ptr = &priv->short_ref[priv->short_ref_count++]; - } - gst_vaapi_picture_replace(picture_ptr, picture); + if (!exec_ref_pic_marking(decoder, picture)) + return FALSE; return TRUE; } From 61753fd55a4c2cf4ddd4b21da80ec1796678169d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jan 2012 15:20:51 +0100 Subject: [PATCH 0596/3781] h264: fix presentation timestamps. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 26 ++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 78ca386341..6cf2733621 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -26,6 +26,7 @@ #include "config.h" #include +#include #include #include "gstvaapidecoder_h264.h" #include "gstvaapidecoder_objects.h" @@ -248,6 +249,7 @@ G_DEFINE_TYPE(GstVaapiDecoderH264, #define BOTTOM_FIELD 1 struct _GstVaapiDecoderH264Private { + GstAdapter *adapter; GstBuffer *sub_buffer; GstH264NalParser *parser; GstH264SPS *sps; @@ -355,6 +357,12 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) priv->dpb[i] = NULL; priv->dpb_count = 0; } + + if (priv->adapter) { + gst_adapter_clear(priv->adapter); + g_object_unref(priv->adapter); + priv->adapter = NULL; + } } static gboolean @@ -364,6 +372,10 @@ gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) gst_vaapi_decoder_h264_close(decoder); + priv->adapter = gst_adapter_new(); + if (!priv->adapter) + return FALSE; + priv->parser = gst_h264_nal_parser_new(); if (!priv->parser) return FALSE; @@ -1335,6 +1347,7 @@ init_picture( picture->is_idr = nalu->type == GST_H264_NAL_SLICE_IDR; picture->field_pic_flag = slice_hdr->field_pic_flag; picture->bottom_field_flag = slice_hdr->bottom_field_flag; + base_picture->pts = gst_adapter_prev_timestamp(priv->adapter, NULL); /* Reset decoder state for IDR pictures */ if (picture->is_idr) { @@ -1858,6 +1871,9 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) if (!buf && buf_size == 0) return decode_sequence_end(decoder); + gst_buffer_ref(buffer); + gst_adapter_push(priv->adapter, buffer); + if (priv->sub_buffer) { buffer = gst_buffer_merge(priv->sub_buffer, buffer); if (!buffer) @@ -1893,7 +1909,10 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) break; - ofs = nalu.offset + nalu.size; + ofs = nalu.offset - ofs; + if (gst_adapter_available(priv->adapter) >= ofs) + gst_adapter_flush(priv->adapter, ofs); + switch (nalu.type) { case GST_H264_NAL_SLICE_IDR: /* fall-through. IDR specifics are handled in init_picture() */ @@ -1917,6 +1936,10 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } + + if (gst_adapter_available(priv->adapter) >= nalu.size) + gst_adapter_flush(priv->adapter, nalu.size); + ofs = nalu.offset + nalu.size; } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size); return status; } @@ -2076,6 +2099,7 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->mb_y = 0; priv->mb_width = 0; priv->mb_height = 0; + priv->adapter = NULL; priv->sub_buffer = NULL; priv->field_poc[0] = 0; priv->field_poc[1] = 0; From 8c37221fa558429d561f322164be3b0585c22ffb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jan 2012 15:03:07 +0100 Subject: [PATCH 0597/3781] h264: execute reference picture marking process (MMCO). --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 61 ++++++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 6cf2733621..c3846eae21 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1463,17 +1463,74 @@ exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) return TRUE; } -/* 8.2.5.4 - Adaptive memory control decoded reference picture marking process */ +/* 8.2.5.4. Adaptive memory control decoded reference picture marking process */ static gboolean exec_ref_pic_marking_adaptive( GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, GstH264DecRefPicMarking *dec_ref_pic_marking ) { GstVaapiDecoderH264Private * const priv = decoder->priv; + gint32 pic_num, ref_idx; + guint i; GST_DEBUG("reference picture marking process (adaptive memory control)"); + for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) { + GstH264RefPicMarking * const ref_pic_marking = + &dec_ref_pic_marking->ref_pic_marking[i]; + + switch (ref_pic_marking->memory_management_control_operation) { + case 1: + // Mark short-term reference picture as "unused for reference" + if (!picture->field_pic_flag) + pic_num = picture->frame_num_wrap; + else + pic_num = 2 * picture->frame_num_wrap + 1; + pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1; + ref_idx = find_short_term_reference(decoder, pic_num); + if (ref_idx < 0) + break; + remove_reference_at( + decoder, + priv->short_ref, &priv->short_ref_count, + ref_idx + ); + break; + case 2: + // Mark long-term reference picture as "unused for reference" + pic_num = picture->long_term_pic_num; + ref_idx = find_long_term_reference(decoder, pic_num); + if (ref_idx < 0) + break; + remove_reference_at( + decoder, + priv->long_ref, &priv->long_ref_count, + ref_idx + ); + break; + case 3: + // Assign LongTermFrameIdx to a short-term reference picture + if (!picture->field_pic_flag) + pic_num = picture->frame_num_wrap; + else + pic_num = 2 * picture->frame_num_wrap + 1; + pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1; + ref_idx = find_short_term_reference(decoder, pic_num); + if (ref_idx < 0) + break; + break; + case 5: + // Mark all reference pictures as "unused for reference" + clear_references(decoder, priv->short_ref, &priv->short_ref_count); + clear_references(decoder, priv->long_ref, &priv->long_ref_count ); + break; + default: + g_assert(0 && "unhandled MMCO"); + break; + } + } return TRUE; } @@ -1491,7 +1548,7 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) GstH264DecRefPicMarking * const dec_ref_pic_marking = get_dec_ref_pic_marking(picture); if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) { - if (!exec_ref_pic_marking_adaptive(decoder, dec_ref_pic_marking)) + if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking)) return FALSE; } else { From 425060a7a8db761b2ce0244981e9ea597b1ac96d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jan 2012 09:20:25 +0100 Subject: [PATCH 0598/3781] h264: fix pred_weight_table() reconstruction. Only the explicit pred_weight_table(), possibly with the inferred default values, shall be required. e.g. don't fill in the table if weighted_pred_flag is not set for P/SP slices. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 106 ++++++++++++++-------- 1 file changed, 67 insertions(+), 39 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index c3846eae21..f849db4849 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1772,16 +1772,79 @@ decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) } static gboolean -fill_slice(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) +fill_pred_weight_table(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) { - GstVaapiDecoderH264Private * const priv = decoder->priv; GstH264SliceHdr * const slice_hdr = &slice->slice_hdr; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table; VASliceParameterBufferH264 * const slice_param = slice->base.param; + guint num_weight_tables = 0; gint i, j; + if (pps->weighted_pred_flag && + (GST_H264_IS_P_SLICE(slice_hdr) || GST_H264_IS_SP_SLICE(slice_hdr))) + num_weight_tables = 1; + else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE(slice_hdr)) + num_weight_tables = 2; + else + num_weight_tables = 0; + + slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom; + slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom; + slice_param->luma_weight_l0_flag = 0; + slice_param->chroma_weight_l0_flag = 0; + slice_param->luma_weight_l1_flag = 0; + slice_param->chroma_weight_l1_flag = 0; + + if (num_weight_tables < 1) + return TRUE; + + slice_param->luma_weight_l0_flag = 1; + for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { + slice_param->luma_weight_l0[i] = w->luma_weight_l0[i]; + slice_param->luma_offset_l0[i] = w->luma_offset_l0[i]; + } + + slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0; + if (slice_param->chroma_weight_l0_flag) { + for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { + for (j = 0; j < 2; j++) { + slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j]; + slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j]; + } + } + } + + if (num_weight_tables < 2) + return TRUE; + + slice_param->luma_weight_l1_flag = 1; + for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { + slice_param->luma_weight_l1[i] = w->luma_weight_l1[i]; + slice_param->luma_offset_l1[i] = w->luma_offset_l1[i]; + } + + slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0; + if (slice_param->chroma_weight_l1_flag) { + for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { + for (j = 0; j < 2; j++) { + slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j]; + slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j]; + } + } + } + return TRUE; +} + +static gboolean +fill_slice(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264SliceHdr * const slice_hdr = &slice->slice_hdr; + VASliceParameterBufferH264 * const slice_param = slice->base.param; + gint i; + /* Fill in VASliceParameterBufferH264 */ slice_param->slice_data_bit_offset = 8 /* nal_unit_type */ + slice_hdr->header_size; slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice; @@ -1794,8 +1857,6 @@ fill_slice(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc; slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2; slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2; - slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom; - slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom; for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++) slice_param->RefPicList0[i] = priv->RefPicList0[i]->info; @@ -1807,41 +1868,8 @@ fill_slice(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++) vaapi_init_picture(&slice_param->RefPicList1[i]); - slice_param->luma_weight_l0_flag = priv->list_count > 0; - if (slice_param->luma_weight_l0_flag) { - for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { - slice_param->luma_weight_l0[i] = w->luma_weight_l0[i]; - slice_param->luma_offset_l0[i] = w->luma_offset_l0[i]; - } - } - - slice_param->chroma_weight_l0_flag = priv->list_count > 0 && sps->chroma_array_type != 0; - if (slice_param->chroma_weight_l0_flag) { - for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { - for (j = 0; j < 2; j++) { - slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j]; - slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j]; - } - } - } - - slice_param->luma_weight_l1_flag = priv->list_count > 1; - if (slice_param->luma_weight_l1_flag) { - for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { - slice_param->luma_weight_l1[i] = w->luma_weight_l1[i]; - slice_param->luma_offset_l1[i] = w->luma_offset_l1[i]; - } - } - - slice_param->chroma_weight_l1_flag = priv->list_count > 1 && sps->chroma_array_type != 0; - if (slice_param->chroma_weight_l1_flag) { - for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { - for (j = 0; j < 2; j++) { - slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j]; - slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j]; - } - } - } + if (!fill_pred_weight_table(decoder, slice)) + return FALSE; return TRUE; } From e52ca4a2c8ab976b477e2d8bec8b6a21e4afe691 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jan 2012 15:38:14 +0100 Subject: [PATCH 0599/3781] h264: handle Decoded Picture Buffer (DPB). --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 195 ++++++++++++++++++++-- 1 file changed, 185 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index f849db4849..58bd612c3e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -86,6 +86,8 @@ struct _GstVaapiPictureH264 { guint field_pic_flag : 1; guint bottom_field_flag : 1; guint has_mmco_5 : 1; + guint output_flag : 1; + guint output_needed : 1; }; struct _GstVaapiPictureH264Class { @@ -125,6 +127,7 @@ gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture) picture->is_long_term = FALSE; picture->is_idr = FALSE; picture->has_mmco_5 = FALSE; + picture->output_needed = FALSE; } static inline GstVaapiPictureH264 * @@ -257,6 +260,7 @@ struct _GstVaapiDecoderH264Private { GstVaapiPictureH264 *current_picture; GstVaapiPictureH264 *dpb[16]; guint dpb_count; + guint dpb_size; GstVaapiProfile profile; GstVaapiPictureH264 *short_ref[32]; guint short_ref_count; @@ -300,6 +304,176 @@ clear_references( guint *picture_count ); +static void +dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + guint num_pictures = --priv->dpb_count; + + if (index != num_pictures) + gst_vaapi_picture_replace(&priv->dpb[index], priv->dpb[num_pictures]); + gst_vaapi_picture_replace(&priv->dpb[num_pictures], NULL); +} + +static inline gboolean +dpb_output(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +{ + /* XXX: update cropping rectangle */ + picture->output_needed = FALSE; + return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture)); +} + +static gboolean +dpb_bump(GstVaapiDecoderH264 *decoder) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + guint i, lowest_poc_index; + gboolean success; + + for (i = 0; i < priv->dpb_count; i++) { + if (priv->dpb[i]->output_needed) + break; + } + if (i == priv->dpb_count) + return FALSE; + + lowest_poc_index = i++; + for (; i < priv->dpb_count; i++) { + GstVaapiPictureH264 * const picture = priv->dpb[i]; + if (picture->output_needed && picture->poc < priv->dpb[lowest_poc_index]->poc) + lowest_poc_index = i; + } + + success = dpb_output(decoder, priv->dpb[lowest_poc_index]); + if (!GST_VAAPI_PICTURE_IS_REFERENCE(priv->dpb[lowest_poc_index])) + dpb_remove_index(decoder, lowest_poc_index); + return success; +} + +static void +dpb_flush(GstVaapiDecoderH264 *decoder) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + + while (dpb_bump(decoder)) + ; + clear_references(decoder, priv->dpb, &priv->dpb_count); +} + +static gboolean +dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + guint i; + + // Remove all unused pictures + if (picture->is_idr) + dpb_flush(decoder); + else { + i = 0; + while (i < priv->dpb_count) { + GstVaapiPictureH264 * const picture = priv->dpb[i]; + if (!picture->output_needed && + !GST_VAAPI_PICTURE_IS_REFERENCE(picture)) + dpb_remove_index(decoder, i); + else + i++; + } + } + + // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB + if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { + while (priv->dpb_count == priv->dpb_size) { + if (!dpb_bump(decoder)) + return FALSE; + } + gst_vaapi_picture_replace(&priv->dpb[priv->dpb_count++], picture); + if (picture->output_flag) + picture->output_needed = TRUE; + } + + // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB + else { + if (!picture->output_flag) + return TRUE; + while (priv->dpb_count == priv->dpb_size) { + for (i = 0; i < priv->dpb_count; i++) { + if (priv->dpb[i]->output_needed && + priv->dpb[i]->poc < picture->poc) + break; + } + if (i == priv->dpb_count) + return dpb_output(decoder, picture); + if (!dpb_bump(decoder)) + return FALSE; + } + gst_vaapi_picture_replace(&priv->dpb[priv->dpb_count++], picture); + picture->output_needed = TRUE; + } + return TRUE; +} + +static void +dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs; + + /* Table A-1 - Level limits */ + switch (sps->level_idc) { + case 10: MaxDpbMbs = 396; break; + case 11: MaxDpbMbs = 900; break; + case 12: MaxDpbMbs = 2376; break; + case 13: MaxDpbMbs = 2376; break; + case 20: MaxDpbMbs = 2376; break; + case 21: MaxDpbMbs = 4752; break; + case 22: MaxDpbMbs = 8100; break; + case 30: MaxDpbMbs = 8100; break; + case 31: MaxDpbMbs = 18000; break; + case 32: MaxDpbMbs = 20480; break; + case 40: MaxDpbMbs = 32768; break; + case 41: MaxDpbMbs = 32768; break; + case 42: MaxDpbMbs = 34816; break; + case 50: MaxDpbMbs = 110400; break; + case 51: MaxDpbMbs = 184320; break; + default: + g_assert(0 && "unhandled level"); + break; + } + + PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) * + (sps->pic_height_in_map_units_minus1 + 1) * + (sps->frame_mbs_only_flag ? 1 : 2)); + max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs; + + /* VUI parameters */ + if (sps->vui_parameters_present_flag) { + GstH264VUIParams * const vui_params = &sps->vui_parameters; + if (vui_params->bitstream_restriction_flag) + max_dec_frame_buffering = vui_params->max_dec_frame_buffering; + else { + switch (sps->profile_idc) { + case 44: // CAVLC 4:4:4 Intra profile + case 86: // Scalable High profile + case 100: // High profile + case 110: // High 10 profile + case 122: // High 4:2:2 profile + case 244: // High 4:4:4 Predictive profile + if (sps->constraint_set3_flag) + max_dec_frame_buffering = 0; + break; + } + } + } + + if (max_dec_frame_buffering > 16) + max_dec_frame_buffering = 16; + else if (max_dec_frame_buffering < sps->num_ref_frames) + max_dec_frame_buffering = sps->num_ref_frames; + priv->dpb_size = MAX(1, max_dec_frame_buffering); + GST_DEBUG("DPB size %u", priv->dpb_size); +} + static GstVaapiDecoderStatus get_status(GstH264ParserResult result) { @@ -336,11 +510,11 @@ static void gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = decoder->priv; - guint i; gst_vaapi_picture_replace(&priv->current_picture, NULL); clear_references(decoder, priv->short_ref, &priv->short_ref_count); clear_references(decoder, priv->long_ref, &priv->long_ref_count ); + clear_references(decoder, priv->dpb, &priv->dpb_count ); if (priv->sub_buffer) { gst_buffer_unref(priv->sub_buffer); @@ -352,12 +526,6 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) priv->parser = NULL; } - if (priv->dpb_count > 0) { - for (i = 0; i < priv->dpb_count; i++) - priv->dpb[i] = NULL; - priv->dpb_count = 0; - } - if (priv->adapter) { gst_adapter_clear(priv->adapter); g_object_unref(priv->adapter); @@ -469,6 +637,9 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) ); if (!success) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + /* Reset DPB */ + dpb_reset(decoder, sps); } return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -501,8 +672,6 @@ decode_current_picture(GstVaapiDecoderH264 *decoder) goto end; if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture))) goto end; - if (!gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture))) - goto end; success = TRUE; end: gst_vaapi_picture_replace(&priv->current_picture, NULL); @@ -1100,6 +1269,7 @@ remove_reference_at( g_return_val_if_fail(index < num_pictures, FALSE); + GST_VAAPI_PICTURE_FLAG_UNSET(pictures[index], GST_VAAPI_PICTURE_FLAG_REFERENCE); if (index != --num_pictures) gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]); gst_vaapi_picture_replace(&pictures[num_pictures], NULL); @@ -1347,6 +1517,7 @@ init_picture( picture->is_idr = nalu->type == GST_H264_NAL_SLICE_IDR; picture->field_pic_flag = slice_hdr->field_pic_flag; picture->bottom_field_flag = slice_hdr->bottom_field_flag; + picture->output_flag = TRUE; /* XXX: conformant to Annex A only */ base_picture->pts = gst_adapter_prev_timestamp(priv->adapter, NULL); /* Reset decoder state for IDR pictures */ @@ -1767,7 +1938,10 @@ decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { if (!fill_quant_matrix(decoder, picture)) return FALSE; - exit_picture(decoder, picture); + if (!exit_picture(decoder, picture)) + return FALSE; + if (!dpb_add(decoder, picture)) + return FALSE; return TRUE; } @@ -2171,6 +2345,7 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->pps = NULL; priv->current_picture = NULL; priv->dpb_count = 0; + priv->dpb_size = 0; priv->profile = GST_VAAPI_PROFILE_H264_HIGH; priv->short_ref_count = 0; priv->long_ref_count = 0; From d656b958a3e15361161574dff87a8bfc047b8d59 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 27 Jan 2012 16:08:03 +0100 Subject: [PATCH 0600/3781] h264: flush DPB when the end of the sequence is reached. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 58bd612c3e..df0007d2b8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -738,6 +738,7 @@ decode_sequence_end(GstVaapiDecoderH264 *decoder) if (priv->current_picture && !decode_current_picture(decoder)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + dpb_flush(decoder); return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; } From 5cd0242bbb74370835b306c05afdd99065765f83 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 27 Jan 2012 17:28:50 +0100 Subject: [PATCH 0601/3781] h264: simplify RefPicList reconstruction. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 63 ++++++++++++++++------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index df0007d2b8..247488dfc9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -266,7 +266,6 @@ struct _GstVaapiDecoderH264Private { guint short_ref_count; GstVaapiPictureH264 *long_ref[32]; guint long_ref_count; - guint list_count; GstVaapiPictureH264 *RefPicList0[32]; guint RefPicList0_count; GstVaapiPictureH264 *RefPicList1[32]; @@ -2013,36 +2012,66 @@ fill_pred_weight_table(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) } static gboolean -fill_slice(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) +fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstH264SliceHdr * const slice_hdr = &slice->slice_hdr; VASliceParameterBufferH264 * const slice_param = slice->base.param; - gint i; + guint i, num_ref_lists = 0; - /* Fill in VASliceParameterBufferH264 */ - slice_param->slice_data_bit_offset = 8 /* nal_unit_type */ + slice_hdr->header_size; - slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice; - slice_param->slice_type = slice_hdr->type % 5; - slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag; - slice_param->num_ref_idx_l0_active_minus1 = priv->list_count > 0 ? slice_hdr->num_ref_idx_l0_active_minus1 : 0; - slice_param->num_ref_idx_l1_active_minus1 = priv->list_count > 1 ? slice_hdr->num_ref_idx_l1_active_minus1 : 0; - slice_param->cabac_init_idc = slice_hdr->cabac_init_idc; - slice_param->slice_qp_delta = slice_hdr->slice_qp_delta; - slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc; - slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2; - slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2; + slice_param->num_ref_idx_l0_active_minus1 = 0; + slice_param->num_ref_idx_l1_active_minus1 = 0; + + if (GST_H264_IS_B_SLICE(slice_hdr)) + num_ref_lists = 2; + else if (GST_H264_IS_I_SLICE(slice_hdr)) + num_ref_lists = 0; + else + num_ref_lists = 1; + + if (num_ref_lists < 1) + return TRUE; + + slice_param->num_ref_idx_l0_active_minus1 = + slice_hdr->num_ref_idx_l0_active_minus1; for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++) slice_param->RefPicList0[i] = priv->RefPicList0[i]->info; for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++) vaapi_init_picture(&slice_param->RefPicList0[i]); + if (num_ref_lists < 2) + return TRUE; + + slice_param->num_ref_idx_l1_active_minus1 = + slice_hdr->num_ref_idx_l1_active_minus1; + for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++) slice_param->RefPicList1[i] = priv->RefPicList1[i]->info; for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++) vaapi_init_picture(&slice_param->RefPicList1[i]); + return TRUE; +} +static gboolean +fill_slice(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) +{ + GstH264SliceHdr * const slice_hdr = &slice->slice_hdr; + VASliceParameterBufferH264 * const slice_param = slice->base.param; + + /* Fill in VASliceParameterBufferH264 */ + slice_param->slice_data_bit_offset = 8 /* nal_unit_type */ + slice_hdr->header_size; + slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice; + slice_param->slice_type = slice_hdr->type % 5; + slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag; + slice_param->cabac_init_idc = slice_hdr->cabac_init_idc; + slice_param->slice_qp_delta = slice_hdr->slice_qp_delta; + slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc; + slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2; + slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2; + + if (!fill_RefPicList(decoder, slice)) + return FALSE; if (!fill_pred_weight_table(decoder, slice)) return FALSE; return TRUE; @@ -2085,9 +2114,6 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) } picture = priv->current_picture; - priv->list_count = (GST_H264_IS_B_SLICE(slice_hdr) ? 2 : - (GST_H264_IS_I_SLICE(slice_hdr) ? 0 : 1)); - priv->mb_x = slice_hdr->first_mb_in_slice % priv->mb_width; priv->mb_y = slice_hdr->first_mb_in_slice / priv->mb_width; // FIXME: MBAFF or field @@ -2350,7 +2376,6 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->profile = GST_VAAPI_PROFILE_H264_HIGH; priv->short_ref_count = 0; priv->long_ref_count = 0; - priv->list_count = 0; priv->RefPicList0_count = 0; priv->RefPicList1_count = 0; priv->nal_length_size = 0; From a79c7f9fa6e8d7eb5f62d682df7d9418e5b6241b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 30 Jan 2012 10:15:32 +0100 Subject: [PATCH 0602/3781] decoder: optimize slice data buffers initialization. VA drivers may have a faster means to transfer user buffers to GPU buffers than using memcpy(). In particular, on Intel Gen graphics, we can use pwrite(). This provides for faster upload of bitstream and can help higher bitrates. vaapi_create_buffer() helper function was also updated to allow for un-mapped buffers and pre-initialized data for buffers. --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 34 ++++++++------------ gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 30 ++++++++++------- gst-libs/gst/vaapi/gstvaapiutils.c | 33 +++++++++++-------- gst-libs/gst/vaapi/gstvaapiutils.h | 14 ++++---- 4 files changed, 59 insertions(+), 52 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 7af2dd9579..9a244bc9ea 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -150,16 +150,13 @@ gst_vaapi_iq_matrix_create( const GstVaapiCodecObjectConstructorArgs *args ) { - iq_matrix->param = vaapi_create_buffer( - GET_VA_DISPLAY(iq_matrix), - GET_VA_CONTEXT(iq_matrix), - VAIQMatrixBufferType, - args->param_size, - &iq_matrix->param_id - ); - if (!iq_matrix->param) - return FALSE; - return TRUE; + 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); } static void @@ -212,16 +209,13 @@ gst_vaapi_bitplane_create( const GstVaapiCodecObjectConstructorArgs *args ) { - bitplane->data = vaapi_create_buffer( - GET_VA_DISPLAY(bitplane), - GET_VA_CONTEXT(bitplane), - VABitPlaneBufferType, - args->param_size, - &bitplane->data_id - ); - if (!bitplane->data) - return FALSE; - return TRUE; + return vaapi_create_buffer(GET_VA_DISPLAY(bitplane), + GET_VA_CONTEXT(bitplane), + VABitPlaneBufferType, + args->param_size, + args->param, + &bitplane->data_id, + &bitplane->data); } static void diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index ed5f3c7803..aa1d7481fa 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -89,19 +89,23 @@ gst_vaapi_picture_create( const GstVaapiCodecObjectConstructorArgs *args ) { + gboolean success; + picture->surface = gst_vaapi_context_get_surface(GET_CONTEXT(picture)); if (!picture->surface) return FALSE; picture->surface_id = gst_vaapi_surface_get_id(picture->surface); - picture->param = vaapi_create_buffer( + success = vaapi_create_buffer( GET_VA_DISPLAY(picture), GET_VA_CONTEXT(picture), VAPictureParameterBufferType, args->param_size, - &picture->param_id + args->param, + &picture->param_id, + &picture->param ); - if (!picture->param) + if (!success) return FALSE; picture->slices = g_ptr_array_new(); @@ -274,28 +278,30 @@ gst_vaapi_slice_create( ) { VASliceParameterBufferBase *slice_param; - guint8 *data; + gboolean success; - data = vaapi_create_buffer( + success = vaapi_create_buffer( GET_VA_DISPLAY(slice), GET_VA_CONTEXT(slice), VASliceDataBufferType, args->data_size, - &slice->data_id + args->data, + &slice->data_id, + NULL ); - if (!data) + if (!success) return FALSE; - memcpy(data, args->data, args->data_size); - vaapi_unmap_buffer(GET_VA_DISPLAY(slice), slice->data_id, NULL); - slice->param = vaapi_create_buffer( + success = vaapi_create_buffer( GET_VA_DISPLAY(slice), GET_VA_CONTEXT(slice), VASliceParameterBufferType, args->param_size, - &slice->param_id + args->param, + &slice->param_id, + &slice->param ); - if (!slice->param) + if (!success) return FALSE; slice_param = slice->param; diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 97518cf274..2b8f17bd25 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -76,33 +76,38 @@ vaapi_unmap_buffer(VADisplay dpy, VABufferID buf_id, void **pbuf) } /* Creates and maps VA buffer */ -void * +gboolean vaapi_create_buffer( - VADisplay dpy, - VAContextID ctx, - int type, - unsigned int size, - VABufferID *buf_id_ptr + VADisplay dpy, + VAContextID ctx, + int type, + unsigned int size, + gconstpointer buf, + VABufferID *buf_id_ptr, + gpointer *mapped_data ) { VABufferID buf_id; VAStatus status; - void *data; + gpointer data = (gpointer)buf; - status = vaCreateBuffer(dpy, ctx, type, size, 1, NULL, &buf_id); + status = vaCreateBuffer(dpy, ctx, type, size, 1, data, &buf_id); if (!vaapi_check_status(status, "vaCreateBuffer()")) - return NULL; + return FALSE; - data = vaapi_map_buffer(dpy, buf_id); - if (!data) - goto error; + if (mapped_data) { + data = vaapi_map_buffer(dpy, buf_id); + if (!data) + goto error; + *mapped_data = data; + } *buf_id_ptr = buf_id; - return data; + return TRUE; error: vaapi_destroy_buffer(dpy, &buf_id); - return NULL; + return FALSE; } /* Destroy VA buffer */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index ac6a38f270..b8a42bc785 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -48,13 +48,15 @@ vaapi_unmap_buffer(VADisplay dpy, VABufferID buf_id, void **pbuf) attribute_hidden; /** Creates and maps VA buffer */ -void * +gboolean vaapi_create_buffer( - VADisplay dpy, - VAContextID ctx, - int type, - unsigned int size, - VABufferID *buf_id + VADisplay dpy, + VAContextID ctx, + int type, + unsigned int size, + gconstpointer data, + VABufferID *buf_id, + gpointer *mapped_data ) attribute_hidden; /** Destroy VA buffer */ From 0fb1147d9c254cf529199b87b4dc9892545da2dd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 30 Jan 2012 18:12:59 +0100 Subject: [PATCH 0603/3781] Add header for system-dependent definitions. --- gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapicodec_objects.c | 2 +- gst-libs/gst/vaapi/gstvaapicontext.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplaycache.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapiimageformat.c | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.c | 2 +- gst-libs/gst/vaapi/gstvaapiobject.c | 2 +- gst-libs/gst/vaapi/gstvaapiparamspecs.c | 2 +- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 2 +- gst-libs/gst/vaapi/gstvaapitexture.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapivalue.c | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c | 2 +- .../gst/vaapi/gstvaapivideoconverter_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 2 +- gst-libs/gst/vaapi/gstvaapivideosink.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- gst-libs/gst/vaapi/sysdeps.h | 29 +++++++++++++++++++ 38 files changed, 66 insertions(+), 36 deletions(-) create mode 100644 gst-libs/gst/vaapi/sysdeps.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 8e0b104ac4..4314d3a8ff 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -87,6 +87,7 @@ libgstvaapi_source_priv_h = \ gstvaapiutils_tsb.h \ gstvaapivideobuffer_priv.h \ gstvaapiworkarounds.h \ + sysdeps.h \ $(libgst_vaapi_ffmpeg_source_priv_h) \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 9a244bc9ea..7b5958d86b 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "sysdeps.h" #include #include #include "gstvaapicodec_objects.h" diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index af57feb9a5..9b1bf1ad39 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -25,7 +25,7 @@ * @short_description: VA context abstraction */ -#include "config.h" +#include "sysdeps.h" #include #include "gstvaapicompat.h" #include "gstvaapicontext.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 2f54e7a43d..a83004e16c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -25,7 +25,7 @@ * @short_description: VA decoder abstraction */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapicompat.h" #include "gstvaapidecoder.h" #include "gstvaapidecoder_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 21425ac884..f6439c0085 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -25,7 +25,7 @@ * @short_description: FFmpeg-based decoder */ -#include "config.h" +#include "sysdeps.h" #ifdef HAVE_LIBAVCODEC_AVCODEC_H # include #endif diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 247488dfc9..96398849c8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -24,7 +24,7 @@ * @short_description: H.264 decoder */ -#include "config.h" +#include "sysdeps.h" #include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index e888426264..12c2690b4f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -24,7 +24,7 @@ * @short_description: MPEG-2 decoder */ -#include "config.h" +#include "sysdeps.h" #include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 24a675712c..5ef2d22d4a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -24,7 +24,7 @@ * @short_description: MPEG-4 decoder, include h263/divx/xvid support */ -#include "config.h" +#include "sysdeps.h" #include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index aa1d7481fa..968f86bf29 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "sysdeps.h" #include #include #include "gstvaapidecoder_objects.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index b305b28b8d..d7d68121c2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -24,7 +24,7 @@ * @short_description: VC-1 decoder */ -#include "config.h" +#include "sysdeps.h" #include #include #include "gstvaapidecoder_vc1.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index e975c638d6..097713c7d0 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -25,7 +25,7 @@ * @short_description: VA display abstraction */ -#include "config.h" +#include "sysdeps.h" #include #include "gstvaapiutils.h" #include "gstvaapidisplay.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 29950e8858..ccf126afa8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -25,7 +25,7 @@ * @short_description: VA/GLX display abstraction */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapiutils_glx.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index f4bd52c6e5..0f5f7ba6b3 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -25,7 +25,7 @@ * @short_description: VA/X11 display abstraction */ -#include "config.h" +#include "sysdeps.h" #include #include "gstvaapiutils.h" #include "gstvaapidisplay_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index a6bb39d08e..54f349cc50 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -19,7 +19,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "sysdeps.h" #include #include #include "gstvaapidisplaycache.h" diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 9cd2639989..200da86f37 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -25,7 +25,7 @@ * @short_description: VA image abstraction */ -#include "config.h" +#include "sysdeps.h" #include #include "gstvaapicompat.h" #include "gstvaapiutils.h" diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index a910b03c58..dd031577a9 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -25,7 +25,7 @@ * @short_description: VA image format abstraction */ -#include "config.h" +#include "sysdeps.h" #include #include "gstvaapicompat.h" #include "gstvaapiimageformat.h" diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 3332931d91..159cb308ea 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -24,7 +24,7 @@ * @short_description: VA image pool */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapiimagepool.h" #define DEBUG 1 diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index f2106eb3d7..52529c0f77 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -24,7 +24,7 @@ * @short_description: Base VA object */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapiobject.h" #include "gstvaapi_priv.h" #include "gstvaapiparamspecs.h" diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.c b/gst-libs/gst/vaapi/gstvaapiparamspecs.c index cac4027d43..8905af4d21 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.c +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.c @@ -24,7 +24,7 @@ * @short_description: GParamSpecs for some of our types */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapiparamspecs.h" #include "gstvaapivalue.h" diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index e3cddd33c6..54b7abac84 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -24,7 +24,7 @@ * @short_description: VA profile abstraction */ -#include "config.h" +#include "sysdeps.h" #include #include #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 000ab27bde..11a94f101d 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -25,7 +25,7 @@ * @short_description: VA subpicture abstraction */ -#include "config.h" +#include "sysdeps.h" #include #include "gstvaapicompat.h" #include "gstvaapiutils.h" diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index e0b614ea09..65c4b28eed 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -25,7 +25,7 @@ * @short_description: VA surface abstraction */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapisurface.h" diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 8fe9d5d9da..b3e95380ae 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -24,7 +24,7 @@ * @short_description: VA surface pool */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapisurfacepool.h" #define DEBUG 1 diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 747d00f284..404583c34a 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -25,7 +25,7 @@ * @short_description: VA surface proxy */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapisurfaceproxy.h" #include "gstvaapiobject_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 0b7092943b..97025f2601 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -24,7 +24,7 @@ * @short_description: VA/GLX texture abstraction */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapitexture.h" #include "gstvaapicompat.h" #include "gstvaapiutils.h" diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 2b8f17bd25..8d5aeccfef 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapisurface.h" diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 527c07cb2d..bf7c3580d0 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -21,7 +21,7 @@ */ #define _GNU_SOURCE 1 /* RTLD_DEFAULT */ -#include "config.h" +#include "sysdeps.h" #include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 76dd78813a..abc58b8e73 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "sysdeps.h" #include #include #include "gstvaapiutils_x11.h" diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 1b3da64d84..112d1b4abd 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -24,7 +24,7 @@ * @short_description: GValue implementations specific to VA-API */ -#include "config.h" +#include "sysdeps.h" #include #include "gstvaapivalue.h" diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 3b6c98db6b..a225981adb 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -25,7 +25,7 @@ * @short_description: VA video buffer for GStreamer */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapivideobuffer.h" #include "gstvaapivideobuffer_priv.h" #include "gstvaapiimagepool.h" diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c index e71da181a7..da49a0d81c 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c @@ -26,7 +26,7 @@ * @short_description: VA video buffer for GStreamer with GLX support */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapivideobuffer_glx.h" #include "gstvaapivideobuffer_priv.h" #include "gstvaapivideoconverter_glx.h" diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index fdeb817e8f..a9ba30d7f2 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -21,7 +21,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "sysdeps.h" #include #include "gstvaapivideoconverter_glx.h" #include "gstvaapivideobuffer.h" diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index ec70be992a..e10648354f 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -24,7 +24,7 @@ * @short_description: Video object pool abstraction */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapivideopool.h" #define DEBUG 1 diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.c b/gst-libs/gst/vaapi/gstvaapivideosink.c index 8f511d4ee1..cde38dd81a 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.c +++ b/gst-libs/gst/vaapi/gstvaapivideosink.c @@ -24,7 +24,7 @@ * @short_description: An interface for implementing VA-API sink elements */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapivideosink.h" static void diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 749b88d307..56ef8ed08c 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -25,7 +25,7 @@ * @short_description: VA window abstraction */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapiwindow.h" #include "gstvaapi_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 447318ed10..45c040d700 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -24,7 +24,7 @@ * @short_description: VA/GLX window abstraction */ -#include "config.h" +#include "sysdeps.h" #include "gstvaapiwindow_glx.h" #include "gstvaapidisplay_x11.h" #include "gstvaapidisplay_x11_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index d1f7d5ac09..51de0615bc 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -24,7 +24,7 @@ * @short_description: VA/X11 window abstraction */ -#include "config.h" +#include "sysdeps.h" #include #include #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/sysdeps.h b/gst-libs/gst/vaapi/sysdeps.h new file mode 100644 index 0000000000..b4a8878d16 --- /dev/null +++ b/gst-libs/gst/vaapi/sysdeps.h @@ -0,0 +1,29 @@ +/* + * sysdeps.h - System-dependent definitions + * + * Copyright (C) 2012 Intel Corporation + * + * 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 SYSDEPS_H +#define SYSDEPS_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#endif /* SYSDEPS_H */ From b54bf3175c0dde840902f47bbbc63422fe136fe7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 30 Jan 2012 18:25:03 +0100 Subject: [PATCH 0604/3781] Add glib compatibility glue for older versions. --- configure.ac | 3 +++ gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/glibcompat.h | 36 +++++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/sysdeps.h | 2 ++ 4 files changed, 42 insertions(+) create mode 100644 gst-libs/gst/vaapi/glibcompat.h diff --git a/configure.ac b/configure.ac index 9a5ff8401f..1d4e343f2e 100644 --- a/configure.ac +++ b/configure.ac @@ -147,6 +147,9 @@ AC_SUBST(GTKDOC_VERSION) dnl Check for GLib AC_PATH_PROG([GLIB_GENMARSHAL], [glib-genmarshal]) PKG_CHECK_MODULES([GLIB], [glib-2.0]) +AC_CHECK_LIB([glib-2.0], [g_list_free_full], [ + AC_DEFINE([HAVE_G_LIST_FREE_FULL], [1], + [Define to 1 if g_list_free_full() is available.])]) AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LIBS) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 4314d3a8ff..d35c23d5de 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -76,6 +76,7 @@ libgstvaapi_source_h = \ $(NULL) libgstvaapi_source_priv_h = \ + glibcompat.h \ gstvaapi_priv.h \ gstvaapicompat.h \ gstvaapidebug.h \ diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h new file mode 100644 index 0000000000..7df3ddfe67 --- /dev/null +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -0,0 +1,36 @@ +/* + * glibcompat.h - System-dependent definitions + * + * Copyright (C) 2012 Intel Corporation + * + * 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 GLIB_COMPAT_H +#define GLIB_COMPAT_H + +#include + +#ifndef HAVE_G_LIST_FREE_FULL +static inline void +g_list_free_full(GList *list, GDestroyNotify free_func) +{ + g_list_foreach(list, (GFunc)free_func, NULL); + g_list_free(list); +} +#endif + +#endif /* GLIB_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/sysdeps.h b/gst-libs/gst/vaapi/sysdeps.h index b4a8878d16..c8be89076c 100644 --- a/gst-libs/gst/vaapi/sysdeps.h +++ b/gst-libs/gst/vaapi/sysdeps.h @@ -26,4 +26,6 @@ # include "config.h" #endif +#include "glibcompat.h" + #endif /* SYSDEPS_H */ From 11d09495ea084ee2af740db61e4445ef5128d9af Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 31 Jan 2012 10:47:36 +0100 Subject: [PATCH 0605/3781] mpeg2: use GstAdapter to track input sequence. This fixes possible memory leaks and improves performance by removing some extra copies. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 138 +++++++++------------ 1 file changed, 59 insertions(+), 79 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 12c2690b4f..3e6c5aa128 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -68,7 +68,6 @@ struct _GstVaapiDecoderMpeg2Private { GstVaapiPicture *next_picture; GstVaapiPicture *prev_picture; GstAdapter *adapter; - GstBuffer *sub_buffer; guint mb_y; guint mb_height; GstClockTime seq_pts; @@ -98,11 +97,6 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) gst_vaapi_picture_replace(&priv->next_picture, NULL); gst_vaapi_picture_replace(&priv->prev_picture, NULL); - if (priv->sub_buffer) { - gst_buffer_unref(priv->sub_buffer); - priv->sub_buffer = NULL; - } - if (priv->adapter) { gst_adapter_clear(priv->adapter); g_object_unref(priv->adapter); @@ -653,49 +647,75 @@ failed: return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } +static inline gint +scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) +{ + return (gint)gst_adapter_masked_scan_uint32_peek(adapter, + 0xffffff00, 0x00000100, + ofs, size, + scp); +} + static GstVaapiDecoderStatus -decode_chunks(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer, GList *chunks) +decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoTypeOffsetSize *tos; GstVaapiDecoderStatus status; - guchar * const buf = GST_BUFFER_DATA(buffer); - const guint buf_size = GST_BUFFER_SIZE(buffer); - guchar *data; - guint data_size, ofs, pos = 0; - GList *l; + guchar *buf; + guint buf_size, size; + guint32 start_code; + guint8 type; + gint ofs; - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - for (l = chunks; l; l = g_list_next(l)) { - tos = l->data; - data = buf + tos->offset; - data_size = tos->size; - if (tos->size < 0) + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + if (!buf && buf_size == 0) + return decode_sequence_end(decoder); + + gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); + + size = gst_adapter_available(priv->adapter); + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + do { + if (size < 8) break; + ofs = scan_for_start_code(priv->adapter, 0, size, &start_code); + if (ofs < 0) + break; + gst_adapter_flush(priv->adapter, ofs); + size -= ofs; - ofs = tos->offset - pos + tos->size; - if (gst_adapter_available(priv->adapter) >= ofs) - gst_adapter_flush(priv->adapter, ofs); - pos += ofs; + if (size < 8) + break; + ofs = scan_for_start_code(priv->adapter, 4, size - 4, NULL); + if (ofs < 0) + break; + gst_adapter_flush(priv->adapter, 4); + size -= ofs; - switch (tos->type) { + buffer = gst_adapter_take_buffer(priv->adapter, ofs - 4); + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + + type = start_code & 0xff; + switch (type) { case GST_MPEG_VIDEO_PACKET_PICTURE: - status = decode_picture(decoder, data, data_size); + status = decode_picture(decoder, buf, buf_size); break; case GST_MPEG_VIDEO_PACKET_SEQUENCE: - status = decode_sequence(decoder, data, data_size); + status = decode_sequence(decoder, buf, buf_size); break; case GST_MPEG_VIDEO_PACKET_EXTENSION: { - const guchar id = data[0] >> 4; + const guchar id = buf[0] >> 4; switch (id) { case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: - status = decode_sequence_ext(decoder, data, data_size); + status = decode_sequence_ext(decoder, buf, buf_size); break; case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: - status = decode_quant_matrix_ext(decoder, data, data_size); + status = decode_quant_matrix_ext(decoder, buf, buf_size); break; case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: - status = decode_picture_ext(decoder, data, data_size); + status = decode_picture_ext(decoder, buf, buf_size); break; default: // Ignore unknown extensions @@ -708,72 +728,33 @@ decode_chunks(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer, GList *chunks) status = decode_sequence_end(decoder); break; case GST_MPEG_VIDEO_PACKET_GOP: - status = decode_gop(decoder, data, data_size); + status = decode_gop(decoder, buf, buf_size); break; case GST_MPEG_VIDEO_PACKET_USER_DATA: // Ignore user-data packets status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; default: - if (tos->type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && - tos->type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { + if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { status = decode_slice( decoder, - tos->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN, - data, data_size + type - GST_MPEG_VIDEO_PACKET_SLICE_MIN, + buf, buf_size ); break; } - else if (tos->type >= 0xb9 && tos->type <= 0xff) { + else if (type >= 0xb9 && type <= 0xff) { // Ignore system start codes (PES headers) status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; } - GST_DEBUG("unsupported start code (0x%02x)", tos->type); + GST_DEBUG("unsupported start code (0x%02x)", type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - break; - } - - if (status == GST_VAAPI_DECODER_STATUS_SUCCESS && pos < buf_size) - priv->sub_buffer = gst_buffer_create_sub(buffer, pos, buf_size - pos); - return status; -} - -static GstVaapiDecoderStatus -decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) -{ - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstVaapiDecoderStatus status; - guchar *buf; - guint buf_size; - GList *chunks; - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - if (!buf && buf_size == 0) - return decode_sequence_end(decoder); - - gst_buffer_ref(buffer); - gst_adapter_push(priv->adapter, buffer); - if (priv->sub_buffer) { - buffer = gst_buffer_merge(priv->sub_buffer, buffer); - if (!buffer) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - gst_buffer_unref(priv->sub_buffer); - priv->sub_buffer = NULL; - } - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - chunks = gst_mpeg_video_parse(buf, buf_size, 0); - if (!chunks) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - - status = decode_chunks(decoder, buffer, chunks); - g_list_free_full(chunks, (GDestroyNotify)g_free); + gst_buffer_unref(buffer); + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); return status; } @@ -848,7 +829,6 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv->next_picture = NULL; priv->prev_picture = NULL; priv->adapter = NULL; - priv->sub_buffer = NULL; priv->mb_y = 0; priv->mb_height = 0; priv->seq_pts = GST_CLOCK_TIME_NONE; From 399875ee86ac7fa2c581e94d154d5ba2b9a7e2d5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 31 Jan 2012 11:26:37 +0100 Subject: [PATCH 0606/3781] decoder: fix memory leak of VA objects on exit. On sequence end, if the last decoded picture is not output for rendering, then the proxy surface is not created. In this case, the original surface must be released explicitly to the context. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 968f86bf29..bc5a4e30eb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -75,7 +75,10 @@ gst_vaapi_picture_destroy(GstVaapiPicture *picture) g_object_unref(picture->proxy); picture->proxy = NULL; } - + else if (picture->surface) { + /* Explicitly release any surface that was not bound to a proxy */ + gst_vaapi_context_put_surface(GET_CONTEXT(picture), picture->surface); + } picture->surface_id = VA_INVALID_ID; picture->surface = NULL; From fe791efc28586b9ac89b7ac27dcd1342a66c05ac Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 31 Jan 2012 11:34:17 +0100 Subject: [PATCH 0607/3781] decoder: allocate proxy surface earlier. This simplifies gst_vaapi_picture_output() to only update the presentation timestamp and submit the proxy to the decoder for output. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index bc5a4e30eb..77ee0b9fb6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -99,6 +99,11 @@ gst_vaapi_picture_create( return FALSE; picture->surface_id = gst_vaapi_surface_get_id(picture->surface); + picture->proxy = + gst_vaapi_surface_proxy_new(GET_CONTEXT(picture), picture->surface); + if (!picture->proxy) + return FALSE; + success = vaapi_create_buffer( GET_VA_DISPLAY(picture), GET_VA_CONTEXT(picture), @@ -240,19 +245,12 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE); - proxy = picture->proxy; - if (!proxy) { - proxy = gst_vaapi_surface_proxy_new( - GET_CONTEXT(picture), - picture->surface - ); - if (!proxy) - return FALSE; - picture->proxy = proxy; - } + if (!picture->proxy) + return FALSE; + proxy = g_object_ref(picture->proxy); gst_vaapi_surface_proxy_set_timestamp(proxy, picture->pts); - gst_vaapi_decoder_push_surface_proxy(GET_DECODER(picture), g_object_ref(proxy)); + gst_vaapi_decoder_push_surface_proxy(GET_DECODER(picture), proxy); return TRUE; } From dc0b24dcacc2f2034a2b6d6d8efd8a8cbab9743a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 1 Feb 2012 23:28:23 +0100 Subject: [PATCH 0608/3781] NEWS: updates. --- NEWS | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 49c4dfa865..4307dbac07 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,17 @@ -gst-vaapi NEWS -- summary of changes. 2012-01-16 +gst-vaapi NEWS -- summary of changes. 2012-02-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora +Version 0.3.4 - DD.Feb.2012 +* Add H.264 decoder (based on codecparsers) +* Add workaround for qtdemux not exposing H.263 profiles (Halley Zhao) +* Alias H.263 Baseline profile to MPEG-4:2 Simple profile (Halley Zhao) +* Use optimized path to submit slice data buffers +* Fix possible memory leak in MPEG-2 decoder +* Fix vaapisink to cap window size to the maximum display size +* Fix MPEG-2, MPEG-4 and VC-1 decoders to refcount reference surfaces properly + Version 0.3.3 - 16.Jan.2012 * Add MPEG-2, MPEG-4 and VC-1 decoders (based on codecparsers) * Add support for GstXOverlay::set_render_rectangle() in vaapisink From 41f83d0bab419fa32c571f0f01f6b99fdd137153 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 1 Feb 2012 23:32:47 +0100 Subject: [PATCH 0609/3781] README: updates. Mention codecparsers-based decoders, FFmpeg is now optional. Update list of support HW. --- README | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README b/README index 2b96af450c..682d904bdc 100644 --- a/README +++ b/README @@ -36,7 +36,8 @@ GStreamer and helper libraries. Features -------- - * VA-API support from 0.29 to 0.31 + * VA-API support from 0.29 to 0.32 + * MPEG-2, MPEG-4, H.264 and VC-1 ad-hoc decoders * OpenGL rendering through VA/GLX or GLX texture-from-pixmap + FBO * Support for major HW video decoding solutions on Linux (AMD, Intel, NVIDIA) @@ -46,12 +47,15 @@ Requirements Software requirements + * libva-dev >= 1.0.3 (VA/GLX) * libgstreamer0.10-dev >= 0.10.35.1 or with GstBaseSink::query() * libgstreamer-plugins-base0.10-dev >= 0.10.35 * libgstreamer-plugins-bad0.10-dev >= 0.10.22.1 - or with GstVideoContext, GstSurfaceBuffer - * libva-dev >= 1.0.3 (VA/GLX) + or with GstVideoContext, GstSurfaceBuffer, codecparsers + + If codecparsers-based decoders are not used: + * libavcodec-dev >= 0.6 or with @@ -59,8 +63,9 @@ Hardware requirements * AMD platforms with UVD2 (XvBA supported) * Intel Eaglelake (G45) - * Intel Ironlake (HD Graphics) + * Intel Ironlake, Sandy Bridge and Ivy Bridge (HD Graphics) * Intel Poulsbo (US15W) + * Intel Medfield or Cedar Trail * NVIDIA platforms with PureVideo (VDPAU supported) @@ -70,9 +75,3 @@ Usage * Play an H.264 video with an MP4 container in fullscreen mode $ gst-launch-0.10 -v filesrc location=/path/to/video.mp4 ! \ qtdemux ! vaapidecode ! vaapisink fullscreen=true - - -Caveats -------- - - * No ad-hoc parser, vaapidecoder currently relies on FFmpeg From 2d47a06090d4093f720cd505c758ce8876e93da9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 1 Feb 2012 23:34:09 +0100 Subject: [PATCH 0610/3781] 0.3.4. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 4307dbac07..60eba1e68e 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2012-02-DD +gst-vaapi NEWS -- summary of changes. 2012-02-01 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora -Version 0.3.4 - DD.Feb.2012 +Version 0.3.4 - 01.Feb.2012 * Add H.264 decoder (based on codecparsers) * Add workaround for qtdemux not exposing H.263 profiles (Halley Zhao) * Alias H.263 Baseline profile to MPEG-4:2 Simple profile (Halley Zhao) diff --git a/configure.ac b/configure.ac index 1d4e343f2e..8f0bb261f7 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) m4_define([gst_vaapi_micro_version], [4]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From fc596d1ea9a37133f47f938fe78f561628f57727 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 2 Feb 2012 09:23:15 +0100 Subject: [PATCH 0611/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 8f0bb261f7..f0184dfec5 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) -m4_define([gst_vaapi_micro_version], [4]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [5]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From f64bafea59676b52b0f27ad02d5131e78a0ff11c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sun, 5 Feb 2012 18:24:08 +0100 Subject: [PATCH 0612/3781] plugins: fix pad template ref leaks. --- gst/vaapi/gstvaapidecode.c | 15 +++++++-------- gst/vaapi/gstvaapidownload.c | 15 +++++++-------- gst/vaapi/gstvaapisink.c | 8 ++++---- gst/vaapi/gstvaapiupload.c | 15 +++++++-------- 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index c95bd98393..ea6a0ef130 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -408,20 +408,19 @@ static void gst_vaapidecode_base_init(gpointer klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstPadTemplate *pad_template; gst_element_class_set_details(element_class, &gst_vaapidecode_details); /* sink pad */ - gst_element_class_add_pad_template( - element_class, - gst_static_pad_template_get(&gst_vaapidecode_sink_factory) - ); + pad_template = gst_static_pad_template_get(&gst_vaapidecode_sink_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); /* src pad */ - gst_element_class_add_pad_template( - element_class, - gst_static_pad_template_get(&gst_vaapidecode_src_factory) - ); + pad_template = gst_static_pad_template_get(&gst_vaapidecode_src_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); } static void diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 3a5df38e46..a2af0a51b5 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -220,20 +220,19 @@ static void gst_vaapidownload_base_init(gpointer klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstPadTemplate *pad_template; gst_element_class_set_details(element_class, &gst_vaapidownload_details); /* sink pad */ - gst_element_class_add_pad_template( - element_class, - gst_static_pad_template_get(&gst_vaapidownload_sink_factory) - ); + pad_template = gst_static_pad_template_get(&gst_vaapidownload_sink_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); /* src pad */ - gst_element_class_add_pad_template( - element_class, - gst_static_pad_template_get(&gst_vaapidownload_src_factory) - ); + pad_template = gst_static_pad_template_get(&gst_vaapidownload_src_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); } static void diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 5fdf2d6b6c..59587547f4 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -784,13 +784,13 @@ static void gst_vaapisink_base_init(gpointer klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstPadTemplate *pad_template; gst_element_class_set_details(element_class, &gst_vaapisink_details); - gst_element_class_add_pad_template( - element_class, - gst_static_pad_template_get(&gst_vaapisink_sink_factory) - ); + pad_template = gst_static_pad_template_get(&gst_vaapisink_sink_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); } static void diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 9ba73666b8..e76856663b 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -211,20 +211,19 @@ static void gst_vaapiupload_base_init(gpointer klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstPadTemplate *pad_template; gst_element_class_set_details(element_class, &gst_vaapiupload_details); /* sink pad */ - gst_element_class_add_pad_template( - element_class, - gst_static_pad_template_get(&gst_vaapiupload_sink_factory) - ); + pad_template = gst_static_pad_template_get(&gst_vaapiupload_sink_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); /* src pad */ - gst_element_class_add_pad_template( - element_class, - gst_static_pad_template_get(&gst_vaapiupload_src_factory) - ); + pad_template = gst_static_pad_template_get(&gst_vaapiupload_src_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); } static void From 843f528f95b64debfba2d2416def35a030cf5008 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sun, 5 Feb 2012 18:28:51 +0100 Subject: [PATCH 0613/3781] vaapiupload: use g_object_unref() for GstVaapiImage. --- gst/vaapi/gstvaapiupload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index e76856663b..9bd383fc96 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -695,7 +695,7 @@ gst_vaapiupload_buffer_alloc( image = gst_vaapi_surface_derive_image(surface); if (image && gst_vaapi_image_get_data_size(image) == size) { gst_vaapi_video_buffer_set_image(vbuffer, image); - gst_object_unref(image); /* video buffer owns an extra reference */ + g_object_unref(image); /* video buffer owns an extra reference */ break; } From d46e8d9961b9dbc12d77b087af80d3fba733b4f9 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Tue, 31 Jan 2012 16:38:58 +0800 Subject: [PATCH 0614/3781] display: skip profiles which have no entrypoints. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 097713c7d0..1a286945ad 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -454,7 +454,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) entrypoints, &num_entrypoints ); if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()")) - goto end; + continue; for (j = 0; j < num_entrypoints; j++) { config.entrypoint = gst_vaapi_entrypoint(entrypoints[j]); From d75d70d395d48eb02ef31b5656131b85c8221a97 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 6 Feb 2012 15:54:09 +0100 Subject: [PATCH 0615/3781] mpeg2: fix crash when there is no free surface to decode into. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 17 +++++++++++++---- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 4 ++++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 4 ++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index a83004e16c..b316a8a58e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -99,14 +99,13 @@ pop_buffer(GstVaapiDecoder *decoder) static GstVaapiDecoderStatus decode_step(GstVaapiDecoder *decoder) { - GstVaapiDecoderPrivate * const priv = decoder->priv; GstVaapiDecoderStatus status; GstBuffer *buffer; /* Decoding will fail if there is no surface left */ - if (priv->context && - gst_vaapi_context_get_surface_count(priv->context) == 0) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE; + status = gst_vaapi_decoder_check_status(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; do { buffer = pop_buffer(decoder); @@ -561,3 +560,13 @@ gst_vaapi_decoder_push_surface_proxy( { return push_surface(decoder, proxy); } + +GstVaapiDecoderStatus +gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (priv->context && gst_vaapi_context_get_surface_count(priv->context) < 1) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 3e6c5aa128..a702b96f71 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -685,6 +685,10 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) gst_adapter_flush(priv->adapter, ofs); size -= ofs; + status = gst_vaapi_decoder_check_status(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + break; + if (size < 8) break; ofs = scan_for_start_code(priv->adapter, 4, size - 4, NULL); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 87ce200b21..45478d47e7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -171,6 +171,10 @@ gst_vaapi_decoder_push_surface_proxy( GstVaapiSurfaceProxy *proxy ) attribute_hidden; +GstVaapiDecoderStatus +gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder) + attribute_hidden; + G_END_DECLS #endif /* GST_VAAPI_DECODER_PRIV_H */ From 2f127d6af473afd647a2c88f75faafd1cd718437 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 6 Feb 2012 16:11:38 +0100 Subject: [PATCH 0616/3781] vaapidecode: fix another pad template ref leak. --- gst/vaapi/gstvaapidecode.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ea6a0ef130..eaa79a26c6 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -712,6 +712,7 @@ static void gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstPadTemplate *pad_template; decode->display = NULL; decode->decoder = NULL; @@ -723,10 +724,9 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) decode->is_ready = FALSE; /* Pad through which data comes in to the element */ - decode->sinkpad = gst_pad_new_from_template( - gst_element_class_get_pad_template(element_class, "sink"), - "sink" - ); + pad_template = gst_element_class_get_pad_template(element_class, "sink"); + decode->sinkpad = gst_pad_new_from_template(pad_template, "sink"); + gst_object_unref(pad_template); decode->sinkpad_caps = NULL; gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps); @@ -737,10 +737,9 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) gst_element_add_pad(GST_ELEMENT(decode), decode->sinkpad); /* Pad through which data goes out of the element */ - decode->srcpad = gst_pad_new_from_template( - gst_element_class_get_pad_template(element_class, "src"), - "src" - ); + pad_template = gst_element_class_get_pad_template(element_class, "src"); + decode->srcpad = gst_pad_new_from_template(pad_template, "src"); + gst_object_unref(pad_template); decode->srcpad_caps = NULL; gst_pad_use_fixed_caps(decode->srcpad); From 5cc357f88abb732341e35f1dda236b4fd824c6f5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 7 Feb 2012 10:05:53 +0100 Subject: [PATCH 0617/3781] cosmetics: fix warnings (drop unused variables). --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 1 - gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 7b5958d86b..223069aab8 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -215,7 +215,7 @@ gst_vaapi_bitplane_create( args->param_size, args->param, &bitplane->data_id, - &bitplane->data); + (void **)&bitplane->data); } static void diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index a702b96f71..7b57c12415 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -685,7 +685,7 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) gst_adapter_flush(priv->adapter, ofs); size -= ofs; - status = gst_vaapi_decoder_check_status(decoder); + status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder)); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) break; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 5ef2d22d4a..e2cbc4e418 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -909,7 +909,6 @@ decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) static GstVaapiDecoderStatus decode_codec_data(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; GstVaapiDecoderStatus status; guchar *buf, *_buf; guint pos, buf_size, _buf_size; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 1a286945ad..cd7c0e223a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -497,7 +497,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) flags = g_new(guint, n); if (!formats || !flags) goto end; - status = vaQuerySubpictureFormats(priv->display, formats, flags, &n); + status = vaQuerySubpictureFormats(priv->display, formats, flags, (guint *)&n); if (!vaapi_check_status(status, "vaQuerySubpictureFormats()")) goto end; From a698766a8b155b9c282ee1d53c39a833c826616d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 7 Feb 2012 10:01:01 +0100 Subject: [PATCH 0618/3781] glib: fix includes. --- gst-libs/gst/vaapi/gstvaapiutils.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index b8a42bc785..cf5fcc32a9 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -24,7 +24,7 @@ #define GST_VAAPI_UTILS_H #include "config.h" -#include +#include #ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 # include diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index c5c7a0c0e2..80e76f1d08 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #if GLX_GLXEXT_VERSION < 18 typedef void (*PFNGLXBINDTEXIMAGEEXTPROC)(Display *, GLXDrawable, int, const int *); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index a031168e99..f9250878a8 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -24,7 +24,7 @@ #include "config.h" #include -#include +#include void x11_trap_errors(void) attribute_hidden; From 830efb3fbda060626569f48c45c508c9237e074c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 7 Feb 2012 11:07:15 +0100 Subject: [PATCH 0619/3781] glib: map deprecated API to glib >= 2.32 equivalents. GStaticMutex and GStaticRecMutex are now replaced with GMutex and GRecMutex, which no longer require any prior call to g_thread_init(). --- gst-libs/gst/vaapi/glibcompat.h | 22 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + gst-libs/gst/vaapi/gstvaapidisplaycache.c | 1 + 3 files changed, 24 insertions(+) diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 7df3ddfe67..7ccd645911 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -33,4 +33,26 @@ g_list_free_full(GList *list, GDestroyNotify free_func) } #endif +#if GLIB_CHECK_VERSION(2,31,2) +#define GStaticMutex GMutex +#undef g_static_mutex_init +#define g_static_mutex_init(mutex) g_mutex_init(mutex) +#undef g_static_mutex_free +#define g_static_mutex_free(mutex) g_mutex_clear(mutex) +#undef g_static_mutex_lock +#define g_static_mutex_lock(mutex) g_mutex_lock(mutex) +#undef g_static_mutex_unlock +#define g_static_mutex_unlock(mutex) g_mutex_unlock(mutex) + +#define GStaticRecMutex GRecMutex +#undef g_static_rec_mutex_init +#define g_static_rec_mutex_init(mutex) g_rec_mutex_init(mutex) +#undef g_static_rec_mutex_free +#define g_static_rec_mutex_free(mutex) g_rec_mutex_clear(mutex) +#undef g_static_rec_mutex_lock +#define g_static_rec_mutex_lock(mutex) g_rec_mutex_lock(mutex) +#undef g_static_rec_mutex_unlock +#define g_static_rec_mutex_unlock(m) g_rec_mutex_unlock(m) +#endif + #endif /* GLIB_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index cd7c0e223a..01e19fcd3d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -361,6 +361,7 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) gst_vaapi_display_cache_remove(get_display_cache(), display); free_display_cache(); } + g_static_rec_mutex_free(&priv->mutex); } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index 54f349cc50..93178f4633 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -169,6 +169,7 @@ gst_vaapi_display_cache_free(GstVaapiDisplayCache *cache) g_list_free(cache->list); cache->list = NULL; } + g_static_mutex_free(&cache->mutex); g_slice_free(GstVaapiDisplayCache, cache); } From 26c105a6ca7d07cb6b13d82fc6d738bd211182af Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 8 Feb 2012 17:57:29 +0100 Subject: [PATCH 0620/3781] h264: don't allocate too big data structures on stack. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 96398849c8..0ff2f8e949 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -256,7 +256,9 @@ struct _GstVaapiDecoderH264Private { GstBuffer *sub_buffer; GstH264NalParser *parser; GstH264SPS *sps; + GstH264SPS last_sps; GstH264PPS *pps; + GstH264PPS last_pps; GstVaapiPictureH264 *current_picture; GstVaapiPictureH264 *dpb[16]; guint dpb_count; @@ -681,13 +683,13 @@ static GstVaapiDecoderStatus decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264SPS sps; + GstH264SPS * const sps = &priv->last_sps; GstH264ParserResult result; GST_DEBUG("decode SPS"); - memset(&sps, 0, sizeof(sps)); - result = gst_h264_parser_parse_sps(priv->parser, nalu, &sps, TRUE); + memset(sps, 0, sizeof(*sps)); + result = gst_h264_parser_parse_sps(priv->parser, nalu, sps, TRUE); if (result != GST_H264_PARSER_OK) return get_status(result); @@ -698,13 +700,13 @@ static GstVaapiDecoderStatus decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264PPS pps; + GstH264PPS * const pps = &priv->last_pps; GstH264ParserResult result; GST_DEBUG("decode PPS"); - memset(&pps, 0, sizeof(pps)); - result = gst_h264_parser_parse_pps(priv->parser, nalu, &pps); + memset(pps, 0, sizeof(*pps)); + result = gst_h264_parser_parse_pps(priv->parser, nalu, pps); if (result != GST_H264_PARSER_OK) return get_status(result); From 6c5054e84077a2e1353671f81fa13bb66b6d2465 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 8 Feb 2012 18:07:14 +0100 Subject: [PATCH 0621/3781] h264: create VA context earlier when SPS is parsed. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 0ff2f8e949..5083740678 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -293,6 +293,7 @@ struct _GstVaapiDecoderH264Private { guint is_constructed : 1; guint is_opened : 1; guint is_avc : 1; + guint has_context : 1; }; static gboolean @@ -574,7 +575,7 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) guint i, n_profiles = 0; gboolean success, reset_context = FALSE; - if (priv->sps != sps || priv->sps->profile_idc != sps->profile_idc) { + if (!priv->has_context || priv->sps->profile_idc != sps->profile_idc) { GST_DEBUG("profile changed"); reset_context = TRUE; @@ -607,7 +608,8 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) priv->profile = profiles[i]; } - if (priv->sps != sps || priv->sps->chroma_format_idc != sps->chroma_format_idc) { + if (!priv->has_context || + priv->sps->chroma_format_idc != sps->chroma_format_idc) { GST_DEBUG("chroma format changed"); reset_context = TRUE; @@ -616,7 +618,7 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; } - if (priv->sps != sps || + if (!priv->has_context || priv->sps->width != sps->width || priv->sps->height != sps->height) { GST_DEBUG("size changed"); @@ -638,6 +640,7 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) ); if (!success) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + priv->has_context = TRUE; /* Reset DPB */ dpb_reset(decoder, sps); @@ -693,7 +696,7 @@ decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) if (result != GST_H264_PARSER_OK) return get_status(result); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + return ensure_context(decoder, sps); } static GstVaapiDecoderStatus @@ -2370,8 +2373,8 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder); decoder->priv = priv; priv->parser = NULL; - priv->sps = NULL; - priv->pps = NULL; + priv->sps = &priv->last_sps; + priv->pps = &priv->last_pps; priv->current_picture = NULL; priv->dpb_count = 0; priv->dpb_size = 0; @@ -2402,6 +2405,7 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->is_constructed = FALSE; priv->is_opened = FALSE; priv->is_avc = FALSE; + priv->has_context = FALSE; memset(priv->dpb, 0, sizeof(priv->dpb)); memset(priv->short_ref, 0, sizeof(priv->short_ref)); From 82dbd6f5be41206a7159e71bbb879e79b6d9bc8e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 8 Feb 2012 18:08:49 +0100 Subject: [PATCH 0622/3781] h264: complete any current picture decoder before SPS / PPS change. This ensures the VA context is clear when the encoded resolution changes. i.e. make sure older picture is decoded with the older VA context before it changes. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 5083740678..0746c28e01 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -691,6 +691,9 @@ decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) GST_DEBUG("decode SPS"); + if (priv->current_picture && !decode_current_picture(decoder)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + memset(sps, 0, sizeof(*sps)); result = gst_h264_parser_parse_sps(priv->parser, nalu, sps, TRUE); if (result != GST_H264_PARSER_OK) @@ -708,6 +711,9 @@ decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) GST_DEBUG("decode PPS"); + if (priv->current_picture && !decode_current_picture(decoder)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + memset(pps, 0, sizeof(*pps)); result = gst_h264_parser_parse_pps(priv->parser, nalu, pps); if (result != GST_H264_PARSER_OK) From ab94048ea0be0311453aaeedb174d01b09c682d9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 13 Feb 2012 10:10:35 +0100 Subject: [PATCH 0623/3781] decoder: fix double buffer free with some VA drivers. vaRenderPicture() implicitly disposes VA buffers. Some VA drivers would push the VA buffer object into a list of free buffers to be re-used. However, reference pictures (and data) that was kept would explicitly release the VA buffer object later on, thus possibly destroying a valid (re-used) object. Besides, some other VA drivers don't support correctly the vaRenderPicture() semantics for VA buffers disposal and would leak memory if there is no explicit vaDestroyBuffer(). The temporary workaround is to explcitily destroy VA buffers right after vaRenderPicture(). All VA drivers need to be aligned. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 64 ++++++++++---------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 77ee0b9fb6..f089aa2ff8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -168,6 +168,22 @@ gst_vaapi_picture_add_slice(GstVaapiPicture *picture, GstVaapiSlice *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(GstVaapiPicture *picture) { @@ -175,9 +191,8 @@ gst_vaapi_picture_decode(GstVaapiPicture *picture) GstVaapiBitPlane *bitplane; VADisplay va_display; VAContextID va_context; - VABufferID va_buffers[3]; - guint i, n_va_buffers = 0; VAStatus status; + guint i; g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE); @@ -186,50 +201,37 @@ gst_vaapi_picture_decode(GstVaapiPicture *picture) GST_DEBUG("decode picture 0x%08x", picture->surface_id); - vaapi_unmap_buffer(va_display, picture->param_id, &picture->param); - va_buffers[n_va_buffers++] = picture->param_id; - - iq_matrix = picture->iq_matrix; - if (iq_matrix) { - vaapi_unmap_buffer( - va_display, - iq_matrix->param_id, &iq_matrix->param - ); - va_buffers[n_va_buffers++] = iq_matrix->param_id; - } - - bitplane = picture->bitplane; - if (bitplane) { - vaapi_unmap_buffer( - va_display, - bitplane->data_id, (void **)&bitplane->data - ); - va_buffers[n_va_buffers++] = bitplane->data_id; - } - status = vaBeginPicture(va_display, va_context, picture->surface_id); if (!vaapi_check_status(status, "vaBeginPicture()")) return FALSE; - status = vaRenderPicture(va_display, va_context, va_buffers, n_va_buffers); - if (!vaapi_check_status(status, "vaRenderPicture()")) + 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; for (i = 0; i < picture->slices->len; i++) { GstVaapiSlice * const slice = g_ptr_array_index(picture->slices, i); + VABufferID va_buffers[2]; vaapi_unmap_buffer(va_display, slice->param_id, NULL); va_buffers[0] = slice->param_id; va_buffers[1] = slice->data_id; - n_va_buffers = 2; - status = vaRenderPicture( - va_display, - va_context, - va_buffers, n_va_buffers - ); + status = vaRenderPicture(va_display, va_context, va_buffers, 2); if (!vaapi_check_status(status, "vaRenderPicture()")) return FALSE; + + vaapi_destroy_buffer(va_display, &slice->param_id); + vaapi_destroy_buffer(va_display, &slice->data_id); } status = vaEndPicture(va_display, va_context); From de7432f712f9ae2f5f0b4919eee137533e60afbc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 15 Feb 2012 14:08:44 +0100 Subject: [PATCH 0624/3781] image: fix source stride in picture copy. --- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 200da86f37..8348b2c8fa 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -1007,7 +1007,7 @@ memcpy_pic( for (i = 0; i < height; i++) { memcpy(dst, src, len); dst += dst_stride; - src += dst_stride; + src += src_stride; } } From d47031b8cebd126d6d5f0c0f9653557430429fd3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Feb 2012 11:19:48 +0100 Subject: [PATCH 0625/3781] mpeg2: fix decoding of multiple slices with same slice_vertical_position. 6.3.15 says that "some slices may have the same slice_vertical_position, since slices may start and finish anywhere". So, we can't submit the current picture to the HW right away since subsequent slices would be missing. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 7b57c12415..e782577017 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -577,7 +577,6 @@ decode_slice( GstVaapiPicture * const picture = priv->current_picture; GstVaapiSlice *slice; VASliceParameterBufferMPEG2 *slice_param; - GstVaapiDecoderStatus status; GstBitReader br; guint8 slice_vertical_position_extension; guint8 quantiser_scale_code; @@ -633,14 +632,6 @@ decode_slice( slice_param->slice_vertical_position = priv->mb_y; slice_param->quantiser_scale_code = quantiser_scale_code; slice_param->intra_slice_flag = intra_slice; - - /* Commit picture for decoding if we reached the last slice */ - if (++priv->mb_y >= priv->mb_height) { - status = decode_current_picture(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - GST_DEBUG("done"); - } return GST_VAAPI_DECODER_STATUS_SUCCESS; failed: From b36d2c810ee753ef0141f795f1f409dc95609632 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Feb 2012 16:14:02 +0100 Subject: [PATCH 0626/3781] mpeg2: drop useless mb_y and mb_height members. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index e782577017..2039a1fe5c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -68,8 +68,6 @@ struct _GstVaapiDecoderMpeg2Private { GstVaapiPicture *next_picture; GstVaapiPicture *prev_picture; GstAdapter *adapter; - guint mb_y; - guint mb_height; GstClockTime seq_pts; GstClockTime gop_pts; GstClockTime pts_diff; @@ -169,11 +167,6 @@ ensure_context(GstVaapiDecoderMpeg2 *decoder) GST_DEBUG("size changed"); priv->size_changed = FALSE; reset_context = TRUE; - - if (priv->progressive_sequence) - priv->mb_height = (priv->height + 15) / 16; - else - priv->mb_height = (priv->height + 31) / 32 * 2; } if (reset_context) { @@ -477,8 +470,6 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } - priv->mb_y = 0; - /* Update presentation time */ pts = priv->gop_pts; pts += gst_util_uint64_scale(pic_hdr->tsn, GST_SECOND * priv->fps_d, priv->fps_n); @@ -593,8 +584,6 @@ decode_slice( priv->is_first_field ^= 1; } - priv->mb_y = slice_no; - slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, buf, buf_size); if (!slice) { GST_DEBUG("failed to allocate slice"); @@ -629,7 +618,7 @@ decode_slice( slice_param = slice->param; slice_param->macroblock_offset = gst_bit_reader_get_pos(&br); slice_param->slice_horizontal_position = 0; - slice_param->slice_vertical_position = priv->mb_y; + slice_param->slice_vertical_position = slice_no; slice_param->quantiser_scale_code = quantiser_scale_code; slice_param->intra_slice_flag = intra_slice; return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -824,8 +813,6 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv->next_picture = NULL; priv->prev_picture = NULL; priv->adapter = NULL; - priv->mb_y = 0; - priv->mb_height = 0; priv->seq_pts = GST_CLOCK_TIME_NONE; priv->gop_pts = GST_CLOCK_TIME_NONE; priv->pts_diff = 0; From 60e515e0b7c4cc50a59fe28a12fdc7a6f01e6c5a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Feb 2012 14:17:34 +0100 Subject: [PATCH 0627/3781] mpeg2: fix slice_horizontal_position calculation. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 106 ++++++++++++++++++++- 1 file changed, 103 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 2039a1fe5c..7f2d5b5f77 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -53,6 +53,13 @@ G_DEFINE_TYPE(GstVaapiDecoderMpeg2, } \ } G_STMT_END +#define SKIP(reader, nbits) G_STMT_START { \ + if (!gst_bit_reader_skip (reader, nbits)) { \ + GST_WARNING ("failed to skip nbits: %d", nbits); \ + goto failed; \ + } \ +} G_STMT_END + struct _GstVaapiDecoderMpeg2Private { GstVaapiProfile profile; guint width; @@ -86,6 +93,85 @@ struct _GstVaapiDecoderMpeg2Private { guint broken_link : 1; }; +/* VLC decoder from gst-plugins-bad */ +typedef struct _VLCTable VLCTable; +struct _VLCTable { + gint value; + guint cword; + guint cbits; +}; + +static gboolean +decode_vlc(GstBitReader *br, gint *res, const VLCTable *table, guint length) +{ + guint8 i; + guint cbits = 0; + guint32 value = 0; + + for (i = 0; i < length; i++) { + if (cbits != table[i].cbits) { + cbits = table[i].cbits; + if (!gst_bit_reader_peek_bits_uint32(br, &value, cbits)) { + goto failed; + } + } + + if (value == table[i].cword) { + SKIP(br, cbits); + if (res) + *res = table[i].value; + return TRUE; + } + } + GST_DEBUG("failed to find VLC code"); + +failed: + GST_WARNING("failed to decode VLC, returning"); + return FALSE; +} + +enum { + GST_MPEG_VIDEO_MACROBLOCK_ESCAPE = -1, +}; + +/* Table B-1: Variable length codes for macroblock_address_increment */ +static const VLCTable mpeg2_mbaddr_vlc_table[] = { + { 1, 0x01, 1 }, + { 2, 0x03, 3 }, + { 3, 0x02, 3 }, + { 4, 0x03, 4 }, + { 5, 0x02, 4 }, + { 6, 0x03, 5 }, + { 7, 0x02, 5 }, + { 8, 0x07, 7 }, + { 9, 0x06, 7 }, + { 10, 0x0b, 8 }, + { 11, 0x0a, 8 }, + { 12, 0x09, 8 }, + { 13, 0x08, 8 }, + { 14, 0x07, 8 }, + { 15, 0x06, 8 }, + { 16, 0x17, 10 }, + { 17, 0x16, 10 }, + { 18, 0x15, 10 }, + { 19, 0x14, 10 }, + { 20, 0x13, 10 }, + { 21, 0x12, 10 }, + { 22, 0x23, 11 }, + { 23, 0x22, 11 }, + { 24, 0x21, 11 }, + { 25, 0x20, 11 }, + { 26, 0x1f, 11 }, + { 27, 0x1e, 11 }, + { 28, 0x1d, 11 }, + { 29, 0x1c, 11 }, + { 30, 0x1b, 11 }, + { 31, 0x1a, 11 }, + { 32, 0x19, 11 }, + { 33, 0x18, 11 }, + { GST_MPEG_VIDEO_MACROBLOCK_ESCAPE, 0x08, 11 } +}; + static void gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) { @@ -569,6 +655,8 @@ decode_slice( GstVaapiSlice *slice; VASliceParameterBufferMPEG2 *slice_param; GstBitReader br; + gint mb_x, mb_y, mb_inc; + guint macroblock_offset; guint8 slice_vertical_position_extension; guint8 quantiser_scale_code; guint8 intra_slice_flag, intra_slice = 0; @@ -613,12 +701,24 @@ decode_slice( READ_UINT8(&br, extra_bit_slice, 1); } } + macroblock_offset = gst_bit_reader_get_pos(&br); + + mb_y = slice_no; + mb_x = -1; + do { + if (!decode_vlc(&br, &mb_inc, mpeg2_mbaddr_vlc_table, + G_N_ELEMENTS(mpeg2_mbaddr_vlc_table))) { + GST_WARNING("failed to decode first macroblock_address_increment"); + goto failed; + } + mb_x += mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE ? 33 : mb_inc; + } while (mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE); /* Fill in VASliceParameterBufferMPEG2 */ slice_param = slice->param; - slice_param->macroblock_offset = gst_bit_reader_get_pos(&br); - slice_param->slice_horizontal_position = 0; - slice_param->slice_vertical_position = slice_no; + slice_param->macroblock_offset = macroblock_offset; + slice_param->slice_horizontal_position = mb_x; + slice_param->slice_vertical_position = mb_y; slice_param->quantiser_scale_code = quantiser_scale_code; slice_param->intra_slice_flag = intra_slice; return GST_VAAPI_DECODER_STATUS_SUCCESS; From 3bc68b5b327fa56c157d627835f9143a29ad09fe Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Feb 2012 14:42:38 +0100 Subject: [PATCH 0628/3781] mpeg2: fix decoding at end-of-sequence. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 7f2d5b5f77..305a2dcc10 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -444,9 +444,6 @@ decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) status = decode_current_picture(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - status = render_picture(decoder, priv->current_picture); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; } if (priv->next_picture) { From 124cd8a3d39c8a597f19a57cdf0a98cb82811214 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Feb 2012 16:23:27 +0100 Subject: [PATCH 0629/3781] decoder: add picture structure flags. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 6bdfe2cb5c..6566fec047 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -79,6 +79,8 @@ enum _GstVaapiPictureType { * Picture flags: * @GST_VAAPI_PICTURE_FLAG_SKIPPED: skipped frame * @GST_VAAPI_PICTURE_FLAG_REFERENCE: reference frame + * @GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD: bottom field + * @GST_VAAPI_PICTURE_FLAG_TOP_FIELD: top field * @GST_VAAPI_PICTURE_FLAG_LAST: first flag that can be used by subclasses * * Enum values used for #GstVaapiPicture flags. @@ -86,9 +88,15 @@ enum _GstVaapiPictureType { 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_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 2), + GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 2), + GST_VAAPI_PICTURE_FLAG_TOP_FIELD = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 3), + GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 4), + + GST_VAAPI_PICTURE_MASK_STRUCTURE = (GST_VAAPI_PICTURE_FLAG_TOP_FIELD | + GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD) }; +#define GST_VAAPI_PICTURE_FLAGS GST_MINI_OBJECT_FLAGS #define GST_VAAPI_PICTURE_FLAG_IS_SET GST_MINI_OBJECT_FLAG_IS_SET #define GST_VAAPI_PICTURE_FLAG_SET GST_MINI_OBJECT_FLAG_SET #define GST_VAAPI_PICTURE_FLAG_UNSET GST_MINI_OBJECT_FLAG_UNSET @@ -96,6 +104,15 @@ enum { #define GST_VAAPI_PICTURE_IS_REFERENCE(picture) \ GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE) +#define GST_VAAPI_PICTURE_IS_TOP_FIELD(picture) \ + GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_TOP_FIELD) + +#define GST_VAAPI_PICTURE_IS_BOTTOM_FIELD(picture) \ + GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD) + +#define GST_VAAPI_PICTURE_IS_FRAME(picture) \ + ((GST_VAAPI_PICTURE_FLAGS(picture) & GST_VAAPI_PICTURE_MASK_STRUCTURE) == 0) + /** * GstVaapiPicture: * From f1883b4a4e9a88d5f55947813dea456f2c66957c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Feb 2012 16:39:14 +0100 Subject: [PATCH 0630/3781] mpeg2: fix slice_vertical_position calculation. Make sure to adjust slice_vertical_position if picture structure is a top or bottom field. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 305a2dcc10..b2579b3b54 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -574,12 +574,22 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext; + GstVaapiPicture * const picture = priv->current_picture; if (!gst_mpeg_video_parse_picture_extension(pic_ext, buf, buf_size, 0)) { GST_DEBUG("failed to parse picture-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } priv->has_pic_ext = TRUE; + + switch (pic_ext->picture_structure) { + case GST_MPEG_VIDEO_PICTURE_STRUCTURE_TOP_FIELD: + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TOP_FIELD); + break; + case GST_MPEG_VIDEO_PICTURE_STRUCTURE_BOTTOM_FIELD: + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD); + break; + } return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -700,7 +710,10 @@ decode_slice( } macroblock_offset = gst_bit_reader_get_pos(&br); - mb_y = slice_no; + mb_y = slice_no << !GST_VAAPI_PICTURE_IS_FRAME(picture); + if (GST_VAAPI_PICTURE_IS_BOTTOM_FIELD(picture)) + mb_y++; + mb_x = -1; do { if (!decode_vlc(&br, &mb_inc, mpeg2_mbaddr_vlc_table, From 033a675bcce62e00ecb0d8d53f00386873070975 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Sun, 12 Feb 2012 11:21:52 +0200 Subject: [PATCH 0631/3781] mpeg2: fix size calculation from sequence_extension(). Original values from sequence_header() are 12-bit and the remaining 2 most significant bits are coming from sequence_extension(). Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index b2579b3b54..e98a3f4a09 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -396,8 +396,8 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) priv->has_seq_ext = TRUE; priv->progressive_sequence = seq_ext->progressive; - width = (priv->width & 0xffff) | ((guint32)seq_ext->horiz_size_ext << 16); - height = (priv->height & 0xffff) | ((guint32)seq_ext->vert_size_ext << 16); + width = (priv->width & 0x0fff) | ((guint32)seq_ext->horiz_size_ext << 12); + height = (priv->height & 0x0fff) | ((guint32)seq_ext->vert_size_ext << 12); GST_DEBUG("video resolution %ux%u", width, height); if (seq_ext->fps_n_ext && seq_ext->fps_d_ext) { From 6b56c84c9b69b9ca4c2cd2534f0c850e56f5e06e Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Wed, 29 Feb 2012 03:08:46 -0500 Subject: [PATCH 0632/3781] h264: fix modification process of reference picture lists. Construction of RefPicList0/1 could be off by one element. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 0746c28e01..a8a4bc0d77 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1396,14 +1396,18 @@ exec_picture_refs_modification_1( if (picNum > CurrPicNum) picNum -= MaxPicNum; + // (8-37) for (j = num_refs; j > ref_list_idx; j--) ref_list[j] = ref_list[j - 1]; found_ref_idx = find_short_term_reference(decoder, picNum); ref_list[ref_list_idx++] = found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL; n = ref_list_idx; - for (j = ref_list_idx; j < num_refs; j++) { - const gint32 PicNumF = ref_list[j]->is_long_term ? + for (j = ref_list_idx; j <= num_refs; j++) { + gint32 PicNumF; + if (!ref_list[j]) + continue; + PicNumF = ref_list[j]->is_long_term ? MaxPicNum : ref_list[j]->pic_num; if (PicNumF != picNum) ref_list[n++] = ref_list[j]; @@ -1420,8 +1424,11 @@ exec_picture_refs_modification_1( ref_list[ref_list_idx++] = found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL; n = ref_list_idx; - for (j = ref_list_idx; j < num_refs; j++) { - const gint32 LongTermPicNumF = ref_list[j]->is_long_term ? + for (j = ref_list_idx; j <= num_refs; j++) { + gint32 LongTermPicNumF; + if (!ref_list[j]) + continue; + LongTermPicNumF = ref_list[j]->is_long_term ? ref_list[j]->long_term_pic_num : INT_MAX; if (LongTermPicNumF != l->value.long_term_pic_num) ref_list[n++] = ref_list[j]; From c979d51da6a52ab9f67dfe91ed8b2dfbbbe38c15 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 21 Feb 2012 02:11:20 -0500 Subject: [PATCH 0633/3781] h264: skip all Access Unit (AU) NALs. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index a8a4bc0d77..e19fa424ea 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -733,8 +733,10 @@ decode_sei(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) memset(&sei, 0, sizeof(sei)); result = gst_h264_parser_parse_sei(priv->parser, nalu, &sei); - if (result != GST_H264_PARSER_OK) + if (result != GST_H264_PARSER_OK) { + GST_WARNING("failed to decode SEI, payload type:%d", sei.payloadType); return get_status(result); + } return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2235,6 +2237,10 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) case GST_H264_NAL_SEQ_END: status = decode_sequence_end(decoder); break; + case GST_H264_NAL_AU_DELIMITER: + /* skip all Access Unit NALs */ + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; default: GST_DEBUG("unsupported NAL unit type %d", nalu.type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; From 63e29adbf57bdc2b6f72eddd9690c2dc4c6e0b52 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 2 Mar 2012 13:41:16 +0100 Subject: [PATCH 0634/3781] h264: fix slice_data_bit_offset calculation. Unlike what VA-API documentation defines, the slice_data_bit_offset represents the offset to the first macroblock in the slice data, minus any emulation prevention bytes in the slice_header(). This fix copes with binary-only VA drivers that won't be fixed any time soon. Besides, this aligns with the current FFmpeg behaviour that was based on those proprietary drivers implementing the API incorrectly. --- configure.ac | 24 +++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 44 +++++++++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index f0184dfec5..81583c5fc6 100644 --- a/configure.ac +++ b/configure.ac @@ -247,6 +247,30 @@ AC_DEFINE_UNQUOTED(USE_CODEC_PARSERS, $USE_CODEC_PARSERS, [Defined to 1 if GStreamer codec parsers are used]) AM_CONDITIONAL(USE_CODEC_PARSERS, test $USE_CODEC_PARSERS -eq 1) +if test "$enable_codecparsers" = "yes"; then +AC_CACHE_CHECK([for GstH264SliceHdr::n_emulation_prevention_bytes], + ac_cv_have_gst_h264_slice_hdr_epb_count, [ + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" + AC_TRY_COMPILE( + [#include ], + [GstH264SliceHdr slice_hdr; + slice_hdr.n_emulation_prevention_bytes = 0;], + [ac_cv_have_gst_h264_slice_hdr_epb_count="yes"], + [ac_cv_have_gst_h264_slice_hdr_epb_count="no"] + ) + CFLAGS="$saved_CFLAGS" + LIBS="$saved_LIBS" +]) +fi + +if test "$ac_cv_have_gst_h264_slice_hdr_epb_count" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_GST_H264_SLICE_HDR_EPB_COUNT, 1, + [Defined to 1 if GstH264SliceHdr::n_emulation_prevention_bytes exists.]) +fi + dnl Check for GStreamer interfaces PKG_CHECK_MODULES([GST_INTERFACES], [gstreamer-interfaces-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED] diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index e19fa424ea..9ee3809ac9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1965,6 +1965,40 @@ decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return TRUE; } +#ifndef HAVE_GST_H264_SLICE_HDR_EPB_COUNT +static guint +get_epb_count(const guint8 *buf, guint buf_size, guint header_size) +{ + guint i, n = 0; + + if (buf_size > header_size) + buf_size = header_size; + + for (i = 2; i < buf_size; i++) { + if (!buf[i - 2] && !buf[i - 1] && buf[i] == 0x03) + i += 2, n++; + } + return n; +} +#endif + +static inline guint +get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, GstH264NalUnit *nalu) +{ + guint epb_count; + +#ifdef HAVE_GST_H264_SLICE_HDR_EPB_COUNT + epb_count = slice_hdr->n_emulation_prevention_bytes; +#else + epb_count = get_epb_count( + nalu->data + nalu->offset, + nalu->size, + slice_hdr->header_size / 8 + ); +#endif + return 8 /* nal_unit_type */ + slice_hdr->header_size - epb_count * 8; +} + static gboolean fill_pred_weight_table(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) { @@ -2074,13 +2108,17 @@ fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) } static gboolean -fill_slice(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) +fill_slice( + GstVaapiDecoderH264 *decoder, + GstVaapiSliceH264 *slice, + GstH264NalUnit *nalu +) { GstH264SliceHdr * const slice_hdr = &slice->slice_hdr; VASliceParameterBufferH264 * const slice_param = slice->base.param; /* Fill in VASliceParameterBufferH264 */ - slice_param->slice_data_bit_offset = 8 /* nal_unit_type */ + slice_hdr->header_size; + slice_param->slice_data_bit_offset = get_slice_data_bit_offset(slice_hdr, nalu); slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice; slice_param->slice_type = slice_hdr->type % 5; slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag; @@ -2137,7 +2175,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) priv->mb_x = slice_hdr->first_mb_in_slice % priv->mb_width; priv->mb_y = slice_hdr->first_mb_in_slice / priv->mb_width; // FIXME: MBAFF or field - if (!fill_slice(decoder, slice)) { + if (!fill_slice(decoder, slice, nalu)) { status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; goto error; } From 6c8b052bd3c3c1e5e419045632dbc7e63ce0e775 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 2 Mar 2012 15:03:57 +0100 Subject: [PATCH 0635/3781] Revert "vaapidecode: fix another pad template ref leak" (Holger Kaelberer) This reverts commit 2f127d6af473afd647a2c88f75faafd1cd718437. For gst_element_class_get_pad_template(), no unreferencing is necessary according to the GStreamer documentation. --- gst/vaapi/gstvaapidecode.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index eaa79a26c6..ea6a0ef130 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -712,7 +712,6 @@ static void gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - GstPadTemplate *pad_template; decode->display = NULL; decode->decoder = NULL; @@ -724,9 +723,10 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) decode->is_ready = FALSE; /* Pad through which data comes in to the element */ - pad_template = gst_element_class_get_pad_template(element_class, "sink"); - decode->sinkpad = gst_pad_new_from_template(pad_template, "sink"); - gst_object_unref(pad_template); + decode->sinkpad = gst_pad_new_from_template( + gst_element_class_get_pad_template(element_class, "sink"), + "sink" + ); decode->sinkpad_caps = NULL; gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps); @@ -737,9 +737,10 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) gst_element_add_pad(GST_ELEMENT(decode), decode->sinkpad); /* Pad through which data goes out of the element */ - pad_template = gst_element_class_get_pad_template(element_class, "src"); - decode->srcpad = gst_pad_new_from_template(pad_template, "src"); - gst_object_unref(pad_template); + decode->srcpad = gst_pad_new_from_template( + gst_element_class_get_pad_template(element_class, "src"), + "src" + ); decode->srcpad_caps = NULL; gst_pad_use_fixed_caps(decode->srcpad); From 8bbe22f831182e77d417788bb44e4aeaf2a07b0e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 24 Feb 2012 12:53:30 +0100 Subject: [PATCH 0636/3781] mpeg2: fix slice_vertical_position calculation (again). VA-API expects slice_vertical_position as the initial position from the bitstream. i.e. the direct slice() information. VA drivers will be fixed accordingly. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index e98a3f4a09..11bbe93258 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -710,10 +710,7 @@ decode_slice( } macroblock_offset = gst_bit_reader_get_pos(&br); - mb_y = slice_no << !GST_VAAPI_PICTURE_IS_FRAME(picture); - if (GST_VAAPI_PICTURE_IS_BOTTOM_FIELD(picture)) - mb_y++; - + mb_y = slice_no; mb_x = -1; do { if (!decode_vlc(&br, &mb_inc, mpeg2_mbaddr_vlc_table, From 10dfc67ccabde8d36602fa740b8dafc9676195da Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 24 Feb 2012 12:56:48 +0100 Subject: [PATCH 0637/3781] mpeg2: catch incorrect picture_structure from bitstreams. Assume "frame" picture structure if the syntax element was zero or if progressive_frame is set. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 11bbe93258..b523fb9a00 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -582,6 +582,14 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) } priv->has_pic_ext = TRUE; + if (pic_ext->picture_structure == 0 || + (pic_ext->progressive_frame && + pic_ext->picture_structure != GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME)) { + GST_WARNING("invalid picture_structure %d, replacing with \"frame\"", + pic_ext->picture_structure); + pic_ext->picture_structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME; + } + switch (pic_ext->picture_structure) { case GST_MPEG_VIDEO_PICTURE_STRUCTURE_TOP_FIELD: GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TOP_FIELD); From d6ab5e121000ac0941da86c74a446fb2512c1fd6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 28 Feb 2012 11:58:21 +0100 Subject: [PATCH 0638/3781] mpeg2: fix is_first_field calculation. Reset is_first_field for frame pictures. Factor out locations where the flag is updated. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index b523fb9a00..7feacff2a2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -494,7 +494,7 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) if (!priv->pts_diff) priv->pts_diff = priv->seq_pts - priv->gop_pts; - priv->is_first_field = TRUE; + priv->is_first_field = FALSE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -590,6 +590,7 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) pic_ext->picture_structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME; } + priv->is_first_field ^= 1; switch (pic_ext->picture_structure) { case GST_MPEG_VIDEO_PICTURE_STRUCTURE_TOP_FIELD: GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TOP_FIELD); @@ -597,6 +598,9 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) case GST_MPEG_VIDEO_PICTURE_STRUCTURE_BOTTOM_FIELD: GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD); break; + case GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME: + priv->is_first_field = TRUE; + break; } return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -679,13 +683,8 @@ decode_slice( GST_DEBUG("slice %d @ %p, %u bytes)", slice_no, buf, buf_size); - if (picture->slices->len == 0) { - if (!fill_picture(decoder, picture)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - - if (!priv->pic_ext.progressive_frame) - priv->is_first_field ^= 1; - } + if (picture->slices->len == 0 && !fill_picture(decoder, picture)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, buf, buf_size); if (!slice) { From c94390be710c5ab5dd8ed4348450777f88278dfb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 16 Mar 2012 14:21:36 +0100 Subject: [PATCH 0639/3781] AUTHORS: update to match current authors. --- AUTHORS | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 455858155c..96d5fc7955 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,14 @@ -Gwenole Beauchesne - Primary author +Maintainers: + +Gwenole Beauchesne - Lead developer +Halley Zhao - MPEG-4:2 decoder + +This project is maintained by Intel Corporation. + +Contributors (sorted by first name): + +Feng Yuan +Holger Kaelberer +Nicolas Dufresne +Sreerenj Balachandran +Thibault Saunier From 8593fb619c970143ddcacc798f4b5a5384c569db Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Tue, 7 Feb 2012 15:54:15 +0100 Subject: [PATCH 0640/3781] surfaceproxy: add TFF property. Add TFF (top-field-first) property to GstVaapiSurfaceProxy. Signed-off-by: Gwenole Beauchesne --- docs/reference/libs/libs-sections.txt | 2 + gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 51 ++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 15 +++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index b4fd5130d7..29fa8c050c 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -499,6 +499,8 @@ gst_vaapi_surface_proxy_get_surface_id gst_vaapi_surface_proxy_set_surface gst_vaapi_surface_proxy_get_timestamp gst_vaapi_surface_proxy_set_timestamp +gst_vaapi_surface_proxy_get_tff +gst_vaapi_surface_proxy_set_tff GST_VAAPI_SURFACE_PROXY GST_VAAPI_IS_SURFACE_PROXY diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 404583c34a..9b01ac34d6 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -43,6 +43,7 @@ struct _GstVaapiSurfaceProxyPrivate { GstVaapiContext *context; GstVaapiSurface *surface; GstClockTime timestamp; + gboolean tff; }; enum { @@ -50,7 +51,8 @@ enum { PROP_CONTEXT, PROP_SURFACE, - PROP_TIMESTAMP + PROP_TIMESTAMP, + PROP_TFF }; static void @@ -84,6 +86,9 @@ gst_vaapi_surface_proxy_set_property( case PROP_TIMESTAMP: gst_vaapi_surface_proxy_set_timestamp(proxy, g_value_get_uint64(value)); break; + case PROP_TFF: + gst_vaapi_surface_proxy_set_tff(proxy, g_value_get_boolean(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -110,6 +115,9 @@ gst_vaapi_surface_proxy_get_property( case PROP_TIMESTAMP: g_value_set_uint64(value, gst_vaapi_surface_proxy_get_timestamp(proxy)); break; + case PROP_TFF: + g_value_set_boolean(value, gst_vaapi_surface_proxy_get_tff(proxy)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -151,6 +159,15 @@ gst_vaapi_surface_proxy_class_init(GstVaapiSurfaceProxyClass *klass) "The presentation time of the surface", 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, + PROP_TFF, + g_param_spec_boolean("tff", + "Top-Field-First", + "Flag indicating for interlaced surfaces whether Top Field is First", + FALSE, + G_PARAM_READWRITE)); } static void @@ -163,6 +180,7 @@ gst_vaapi_surface_proxy_init(GstVaapiSurfaceProxy *proxy) priv->context = NULL; priv->surface = NULL; priv->timestamp = GST_CLOCK_TIME_NONE; + priv->tff = FALSE; } /** @@ -332,3 +350,34 @@ gst_vaapi_surface_proxy_set_timestamp( proxy->priv->timestamp = timestamp; } + +/** + * gst_vaapi_surface_proxy_get_tff: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the TFF flag of the #GstVaapiSurface held by @proxy. + * + * Return value: the TFF flag of the surface + */ +gboolean +gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE); + + return proxy->priv->tff; +} + +/** + * gst_vaapi_surface_proxy_set_tff: + * @proxy: a #GstVaapiSurfaceProxy + * @tff: the new value of the TFF flag + * + * Sets the TFF flag of the @proxy surface to @tff. + */ +void +gst_vaapi_surface_proxy_set_tff(GstVaapiSurfaceProxy *proxy, gboolean tff) +{ + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + + proxy->priv->tff = tff; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 6cc4dea9ed..a6d963081f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -72,6 +72,15 @@ G_BEGIN_DECLS #define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(surface) \ gst_vaapi_surface_proxy_get_timestamp(surface) +/** + * GST_VAAPI_SURFACE_PROXY_TFF: + * @surface: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the tff flag of the @surface + */ +#define GST_VAAPI_SURFACE_PROXY_TFF(surface) \ + gst_vaapi_surface_proxy_get_tff(surface) + typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; typedef struct _GstVaapiSurfaceProxyPrivate GstVaapiSurfaceProxyPrivate; typedef struct _GstVaapiSurfaceProxyClass GstVaapiSurfaceProxyClass; @@ -134,6 +143,12 @@ gst_vaapi_surface_proxy_set_timestamp( GstClockTime timestamp ); +gboolean +gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy); + +void +gst_vaapi_surface_proxy_set_tff(GstVaapiSurfaceProxy *proxy, gboolean tff); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_PROXY_H */ From 82f11ffb3088b8f5e6905a462a4990526767857b Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Tue, 7 Feb 2012 15:54:15 +0100 Subject: [PATCH 0641/3781] decoder: maintain caps for interlaced streams. Extend GstVaapiDecoder base object to maintain caps with "interlaced" property. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder.c | 22 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 5 +++++ 2 files changed, 27 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index b316a8a58e..d47bea6a63 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -162,6 +162,7 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps) GstVaapiProfile profile; const GValue *v_codec_data; gint v1, v2; + gboolean b; profile = gst_vaapi_profile_from_caps(caps); if (!profile) @@ -188,6 +189,9 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps) priv->par_d = v2; } + if (gst_structure_get_boolean(structure, "interlaced", &b)) + priv->is_interlaced = b; + v_codec_data = gst_structure_get_value(structure, "codec_data"); if (v_codec_data) set_codec_data(decoder, gst_value_get_buffer(v_codec_data)); @@ -346,6 +350,7 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->par_d = 0; priv->buffers = g_queue_new(); priv->surfaces = g_queue_new(); + priv->is_interlaced = FALSE; } /** @@ -503,6 +508,23 @@ gst_vaapi_decoder_set_pixel_aspect_ratio( } } +void +gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + if (priv->is_interlaced != interlaced) { + GST_DEBUG("interlaced changed to %s", interlaced ? "true" : "false"); + priv->is_interlaced = interlaced; + gst_caps_set_simple( + priv->caps, + "interlaced", G_TYPE_BOOLEAN, interlaced, + NULL + ); + g_object_notify(G_OBJECT(decoder), "caps"); + } +} + gboolean gst_vaapi_decoder_ensure_context( GstVaapiDecoder *decoder, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 45478d47e7..6e153e594b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -125,6 +125,7 @@ struct _GstVaapiDecoderPrivate { guint par_d; GQueue *buffers; GQueue *surfaces; + guint is_interlaced : 1; }; void @@ -148,6 +149,10 @@ gst_vaapi_decoder_set_pixel_aspect_ratio( guint par_d ) attribute_hidden; +void +gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced) + attribute_hidden; + gboolean gst_vaapi_decoder_ensure_context( GstVaapiDecoder *decoder, From 0d0cff695fc0841e0d749690d3062e9eb8c789b6 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Tue, 7 Feb 2012 15:54:15 +0100 Subject: [PATCH 0642/3781] vaapidecode: propagate interlaced and TFF properties downstream. Propagate "interlaced" caps downstream and set "tff" buffer flag appropriately to output buffers for interlaced pictures. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ea6a0ef130..862b478493 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -149,7 +149,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) { GstCaps *other_caps; GstStructure *structure; - const GValue *v_width, *v_height, *v_framerate, *v_par; + const GValue *v_width, *v_height, *v_framerate, *v_par, *v_interlaced; gboolean success; if (!decode->srcpad_caps) { @@ -163,6 +163,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) v_height = gst_structure_get_value(structure, "height"); v_framerate = gst_structure_get_value(structure, "framerate"); v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); + v_interlaced = gst_structure_get_value(structure, "interlaced"); structure = gst_caps_get_structure(decode->srcpad_caps, 0); if (v_width && v_height) { @@ -173,6 +174,8 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) gst_structure_set_value(structure, "framerate", v_framerate); if (v_par) gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); + if (v_interlaced) + gst_structure_set_value(structure, "interlaced", v_interlaced); gst_structure_set(structure, "type", G_TYPE_STRING, "vaapi", NULL); gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, NULL); @@ -239,6 +242,10 @@ gst_vaapidecode_step(GstVaapiDecode *decode) GST_BUFFER_TIMESTAMP(buffer) = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); gst_buffer_set_caps(buffer, GST_PAD_CAPS(decode->srcpad)); + + if (GST_VAAPI_SURFACE_PROXY_TFF(proxy)) + GST_BUFFER_FLAG_SET(buffer, GST_VIDEO_BUFFER_TFF); + gst_vaapi_video_buffer_set_surface_proxy( GST_VAAPI_VIDEO_BUFFER(buffer), proxy From 2ebfa66ade3c7d277688a0159adba44e089d463e Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Tue, 7 Feb 2012 15:57:14 +0100 Subject: [PATCH 0643/3781] ffmpeg: add support for interlaced streams. Evaluate interlaced stream properties. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index f6439c0085..6309ed8d18 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -166,7 +166,7 @@ get_profile(AVCodecContext *avctx, GstVaapiEntrypoint entrypoint) /** Ensures VA context is correctly set up for the current FFmpeg context */ static GstVaapiContext * -get_context(AVCodecContext *avctx) +get_context(AVCodecContext *avctx, AVFrame *pic) { GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(vactx->decoder); @@ -189,6 +189,8 @@ get_context(AVCodecContext *avctx) avctx->sample_aspect_ratio.den ); + gst_vaapi_decoder_set_interlaced(decoder, !!pic->interlaced_frame); + success = gst_vaapi_decoder_ensure_context( decoder, vactx->profile, @@ -263,7 +265,7 @@ gst_vaapi_decoder_ffmpeg_get_buffer(AVCodecContext *avctx, AVFrame *pic) GstVaapiSurfaceProxy *proxy; GstVaapiID surface_id; - context = get_context(avctx); + context = get_context(avctx, pic); if (!context) return -1; @@ -494,6 +496,8 @@ render_frame(GstVaapiDecoderFfmpeg *decoder, AVFrame *frame) return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; gst_vaapi_surface_proxy_set_timestamp(proxy, frame->pts); + if (frame->interlaced_frame) + gst_vaapi_surface_proxy_set_tff(proxy, frame->top_field_first); gst_vaapi_decoder_push_surface_proxy(base_decoder, g_object_ref(proxy)); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From fc3edde05cb18b8e0c5c8bbe2deabf93be457814 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 13 Mar 2012 02:03:31 -0400 Subject: [PATCH 0644/3781] mpeg2: don't decode anything before the first sequence_header(). Skip all pictures prior to the first sequence_header(). Besides, skip all picture_data() if there was no prior picture_header(). Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 7feacff2a2..db2950faa9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -798,6 +798,8 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) type = start_code & 0xff; switch (type) { case GST_MPEG_VIDEO_PACKET_PICTURE: + if (!priv->width || !priv->height) + break; status = decode_picture(decoder, buf, buf_size); break; case GST_MPEG_VIDEO_PACKET_SEQUENCE: @@ -813,6 +815,8 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) status = decode_quant_matrix_ext(decoder, buf, buf_size); break; case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: + if (!priv->width || !priv->height) + break; status = decode_picture_ext(decoder, buf, buf_size); break; default: @@ -835,6 +839,8 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) default: if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { + if (!priv->current_picture) + break; status = decode_slice( decoder, type - GST_MPEG_VIDEO_PACKET_SLICE_MIN, From baa80d97530abc92e451c90da8bbd2e366ec338b Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 13 Mar 2012 20:33:41 -0400 Subject: [PATCH 0645/3781] mpeg2: fix GOP timestamps when incorrect data is received. Some streams have incorrect GOP timestamps, or nothing set at all. i.e. GOP time is 00:00:00 for all GOPs. Try to recover in this case from demuxer timestamps, which are monotonic. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index db2950faa9..abd0e06dd8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -490,6 +490,12 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) pts = GST_SECOND * (gop.hour * 3600 + gop.minute * 60 + gop.second); pts += gst_util_uint64_scale(gop.frame, GST_SECOND * priv->fps_d, priv->fps_n); + if (priv->gop_pts != GST_CLOCK_TIME_NONE && pts <= priv->gop_pts) { + /* Try to fix GOP timestamps, based on demux timestamps */ + pts = gst_adapter_prev_timestamp(priv->adapter, NULL); + if (pts != GST_CLOCK_TIME_NONE) + pts -= priv->pts_diff; + } priv->gop_pts = pts; if (!priv->pts_diff) priv->pts_diff = priv->seq_pts - priv->gop_pts; From d43f3dc50abb976b08dbbbb074f6897cc1abfeff Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Thu, 15 Mar 2012 04:58:04 -0400 Subject: [PATCH 0646/3781] decode: delay NEWSEGMENT event if vaapidecode element was not linked. Rationale: playbin2 links all elements at run-time. Once vaapidecode is created and a NEWSEGMENT event arrives, downstream element may not be ready yet. So, delay this event until next element is chained in, otherwise basesink could output "Received buffer without a new-segment. Assuming timestamps start from 0". Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 31 ++++++++++++++++++++++++++++++- gst/vaapi/gstvaapidecode.h | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 862b478493..5035fcd164 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -457,6 +457,11 @@ gst_vaapidecode_finalize(GObject *object) decode->allowed_caps = NULL; } + if (decode->delayed_new_seg) { + gst_event_unref(decode->delayed_new_seg); + decode->delayed_new_seg = NULL; + } + G_OBJECT_CLASS(parent_class)->finalize(object); } @@ -654,7 +659,16 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) return FALSE; if (!gst_vaapidecode_update_src_caps(decode, caps)) return FALSE; - return gst_vaapidecode_reset(decode, decode->sinkpad_caps); + if (!gst_vaapidecode_reset(decode, decode->sinkpad_caps)) + return FALSE; + + /* Propagate NEWSEGMENT event downstream, now that pads are linked */ + if (decode->delayed_new_seg) { + if (gst_pad_push_event(decode->srcpad, decode->delayed_new_seg)) + gst_event_unref(decode->delayed_new_seg); + decode->delayed_new_seg = NULL; + } + return TRUE; } static GstFlowReturn @@ -685,6 +699,20 @@ gst_vaapidecode_sink_event(GstPad *pad, GstEvent *event) GST_DEBUG("handle sink event '%s'", GST_EVENT_TYPE_NAME(event)); /* Propagate event downstream */ + switch (GST_EVENT_TYPE(event)) { + case GST_EVENT_NEWSEGMENT: + if (decode->delayed_new_seg) { + gst_event_unref(decode->delayed_new_seg); + decode->delayed_new_seg = NULL; + } + if (!GST_PAD_PEER(decode->srcpad)) { + decode->delayed_new_seg = gst_event_ref(event); + return TRUE; + } + break; + default: + break; + } return gst_pad_push_event(decode->srcpad, event); } @@ -726,6 +754,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) decode->decoder_ready = NULL; decode->decoder_caps = NULL; decode->allowed_caps = NULL; + decode->delayed_new_seg = NULL; decode->use_ffmpeg = USE_FFMPEG_DEFAULT; decode->is_ready = FALSE; diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 6725bcbf57..6a5792dff1 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -71,6 +71,7 @@ struct _GstVaapiDecode { GCond *decoder_ready; GstCaps *decoder_caps; GstCaps *allowed_caps; + GstEvent *delayed_new_seg; unsigned int use_ffmpeg : 1; unsigned int is_ready : 1; }; From 81ab8dad37add791311c6c9a18017b332d812a26 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Thu, 22 Mar 2012 03:28:22 -0400 Subject: [PATCH 0647/3781] mpeg4: check for decoder status prior to decoding packet. Make sure there is a VA surface free prior to decoding the current frame. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index e2cbc4e418..8f6af3495a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -724,10 +724,13 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) GstMpeg4Packet *tos = &packet; GstVaapiDecoderStatus status; - status = GST_VAAPI_DECODER_STATUS_SUCCESS; if (tos->size < 0) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder)); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + // packet.size is the size from current marker to the next. if (tos->type == GST_MPEG4_VISUAL_OBJ_SEQ_START) { status = decode_sequence(decoder, packet.data + packet.offset, packet.size); @@ -823,7 +826,7 @@ static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) { GstVaapiDecoderMpeg4Private * const priv = decoder->priv; - GstVaapiDecoderStatus status; + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; guchar *buf; guint pos, buf_size; @@ -899,7 +902,10 @@ decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) } } - if ((result == GST_MPEG4_PARSER_NO_PACKET || result == GST_MPEG4_PARSER_NO_PACKET_END) && pos < buf_size) { + if ((result == GST_MPEG4_PARSER_NO_PACKET || + result == GST_MPEG4_PARSER_NO_PACKET_END || + status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) && + pos < buf_size) { priv->sub_buffer = gst_buffer_create_sub(buffer, pos, buf_size-pos); status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; } From 7277f0e220a8d8223c2c324b24d9010caa6907bf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 23 Mar 2012 17:11:18 +0100 Subject: [PATCH 0648/3781] h264: skip all Filler Data NALs. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 9ee3809ac9..89fef9117b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2279,6 +2279,10 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) /* skip all Access Unit NALs */ status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; + case GST_H264_NAL_FILLER_DATA: + /* skip all Filler Data NALs */ + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; default: GST_DEBUG("unsupported NAL unit type %d", nalu.type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; From 3b67533d3df2ab831b6ff82f356e9c58ac452357 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 23 Mar 2012 17:13:58 +0100 Subject: [PATCH 0649/3781] compat: add compatibility glue with VA-API 0.34+ (WIP). --- gst-libs/gst/vaapi/gstvaapicompat.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 756474aab3..9b4da516b8 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -91,4 +91,9 @@ typedef struct _VASliceParameterBufferBase { #define vaAssociateSubpicture vaAssociateSubpicture2 #endif +/* Compatibility glue with VA-API 0.34 */ +#if VA_CHECK_VERSION(0,34,0) +# include +#endif + #endif /* GST_VAAPI_COMPAT_H */ From a5144358d1eb613fa2d5bfbf4f8e097e85d935e6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 26 Mar 2012 12:01:36 +0200 Subject: [PATCH 0650/3781] videobuffer: add surface render flags. Allow rendering flags, as a combination of GstVaapiSurfaceRenderFlags, to be set to the video buffer. In particular, this is mostly useful for basic deinterlacing. --- docs/reference/libs/libs-sections.txt | 2 ++ gst-libs/gst/vaapi/gstvaapivideobuffer.c | 35 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivideobuffer.h | 6 ++++ .../gst/vaapi/gstvaapivideoconverter_glx.c | 6 ++-- gst/vaapi/gstvaapisink.c | 2 +- 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 29fa8c050c..d60213ac9e 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -200,6 +200,8 @@ gst_vaapi_video_buffer_get_surface_proxy gst_vaapi_video_buffer_set_surface gst_vaapi_video_buffer_set_surface_proxy gst_vaapi_video_buffer_set_surface_from_pool +gst_vaapi_video_buffer_get_render_flags +gst_vaapi_video_buffer_set_render_flags GST_VAAPI_VIDEO_BUFFER GST_VAAPI_IS_VIDEO_BUFFER diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index a225981adb..81176ffb4e 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -50,6 +50,7 @@ struct _GstVaapiVideoBufferPrivate { GstVaapiSurface *surface; GstVaapiSurfaceProxy *proxy; GstBuffer *buffer; + guint render_flags; }; static void @@ -168,6 +169,7 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) priv->surface = NULL; priv->proxy = NULL; priv->buffer = NULL; + priv->render_flags = 0; } /** @@ -597,3 +599,36 @@ gst_vaapi_video_buffer_set_buffer( g_return_if_fail (buffer->priv->buffer == NULL); buffer->priv->buffer = gst_buffer_ref (other_buffer); } + +/** + * gst_vaapi_video_buffer_get_render_flags: + * @buffer: a #GstVaapiVideoBuffer + * + * Retrieves the surface render flags bound to the @buffer. + * + * Return value: a combination for #GstVaapiSurfaceRenderFlags + */ +guint +gst_vaapi_video_buffer_get_render_flags(GstVaapiVideoBuffer *buffer) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), 0); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(buffer->priv->surface), 0); + + return buffer->priv->render_flags; +} + +/** + * gst_vaapi_video_buffer_set_render_flags: + * @buffer: a #GstVaapiVideoBuffer + * @flags: a set of surface render flags + * + * Sets #GstVaapiSurfaceRenderFlags to the @buffer. + */ +void +gst_vaapi_video_buffer_set_render_flags(GstVaapiVideoBuffer *buffer, guint flags) +{ + g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer)); + g_return_if_fail(GST_VAAPI_IS_SURFACE(buffer->priv->surface)); + + buffer->priv->render_flags = flags; +} diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index d076b43cc8..520191c4d7 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -145,6 +145,12 @@ gst_vaapi_video_buffer_set_surface_proxy( GstVaapiSurfaceProxy *proxy ); +guint +gst_vaapi_video_buffer_get_render_flags(GstVaapiVideoBuffer *buffer); + +void +gst_vaapi_video_buffer_set_render_flags(GstVaapiVideoBuffer *buffer, guint flags); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_BUFFER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index a9ba30d7f2..646a82fe81 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -117,8 +117,8 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *converter, { GstVaapiVideoConverterGLXPrivate *priv = GST_VAAPI_VIDEO_CONVERTER_GLX (converter)->priv; - GstVaapiSurface *surface = gst_vaapi_video_buffer_get_surface ( - GST_VAAPI_VIDEO_BUFFER (buffer)); + GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER (buffer); + GstVaapiSurface *surface = gst_vaapi_video_buffer_get_surface (vbuffer); GstVaapiDisplay *new_dpy, *old_dpy; GstVideoOverlayComposition * const composition = gst_video_buffer_get_overlay_composition (GST_BUFFER (buffer)); @@ -140,5 +140,5 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *converter, GST_WARNING ("could not update subtitles"); return gst_vaapi_texture_put_surface (priv->texture, surface, - GST_VAAPI_PICTURE_STRUCTURE_FRAME); + gst_vaapi_video_buffer_get_render_flags (vbuffer)); } diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 59587547f4..6769be2629 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -691,7 +691,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) GST_DEBUG("render surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); - flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + flags = gst_vaapi_video_buffer_get_render_flags(vbuffer); if (!gst_vaapi_surface_set_subpictures_from_composition(surface, composition, TRUE)) From 894d65b81a457cb3cbdfc470848a97bf90a8f09c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 26 Mar 2012 14:37:24 +0200 Subject: [PATCH 0651/3781] vaapipostproc: add new element for video postprocessing. Add vaapipostproc element for video postprocessing. So far, only basic bob deinterlacing is implemented. Interlaced mode is automatically detected based on sink caps ("interlaced" field). --- README | 5 +- debian.upstream/control.in | 1 + gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapi.c | 4 + gst/vaapi/gstvaapipostproc.c | 714 +++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipostproc.h | 123 ++++++ 6 files changed, 848 insertions(+), 1 deletion(-) create mode 100644 gst/vaapi/gstvaapipostproc.c create mode 100644 gst/vaapi/gstvaapipostproc.h diff --git a/README b/README index 682d904bdc..ce09558c6c 100644 --- a/README +++ b/README @@ -26,9 +26,12 @@ GStreamer and helper libraries. * `vaapiupload' is used to convert from video/x-raw-yuv pixels to video/x-vaapi-surface surfaces. - * `vaapidownload' is used to convert from video-x-vaapi-surface + * `vaapidownload' is used to convert from video/x-vaapi-surface surfaces to video/x-raw-yuv pixels. + * `vaapipostproc' is used to postprocess video/x-vaapi-surface + surfaces, for e.g. deinterlacing. + * `vaapisink' is used to display video/x-vaapi-surface surfaces to screen. diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 1cf3477d6f..9ef5de6290 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -21,6 +21,7 @@ Description: VA-API plugins for GStreamer - `vaapidecode': decode bitstreams using VA-API - `vaapiupload': converts from YUV pixels to VA surfaces - `vaapidownload': convert from VA surfaces to YUV pixels + - `vaapipostproc': postprocess VA surfaces, e.g. deinterlacing - `vaapisink': a VA-API based video sink Package: gstreamer@GST_MAJORMINOR@-vaapi-doc diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 5be00766a2..3879fb626a 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -20,6 +20,7 @@ libgstvaapi_la_SOURCES = \ gstvaapidecode.c \ gstvaapidownload.c \ gstvaapipluginutil.c \ + gstvaapipostproc.c \ gstvaapisink.c \ gstvaapiupload.c \ $(NULL) @@ -28,6 +29,7 @@ noinst_HEADERS = \ gstvaapidecode.h \ gstvaapidownload.h \ gstvaapipluginutil.h \ + gstvaapipostproc.h \ gstvaapisink.h \ gstvaapiupload.h \ $(NULL) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 2ca04c5f20..23be2b3832 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -30,6 +30,7 @@ #include "gstvaapidownload.h" #include "gstvaapiupload.h" #include "gstvaapidecode.h" +#include "gstvaapipostproc.h" #include "gstvaapisink.h" static gboolean @@ -44,6 +45,9 @@ plugin_init (GstPlugin *plugin) gst_element_register(plugin, "vaapidecode", GST_RANK_PRIMARY, GST_TYPE_VAAPIDECODE); + gst_element_register(plugin, "vaapipostproc", + GST_RANK_PRIMARY, + GST_TYPE_VAAPIPOSTPROC); gst_element_register(plugin, "vaapisink", GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c new file mode 100644 index 0000000000..e0f9f67914 --- /dev/null +++ b/gst/vaapi/gstvaapipostproc.c @@ -0,0 +1,714 @@ +/* + * gstvaapipostproc.c - VA-API video postprocessing + * + * Copyright (C) 2012 Intel Corporation + * + * 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:gstvaapipostproc + * @short_description: A video postprocessing filter + * + * vaapipostproc consists in various postprocessing algorithms to be + * applied to VA surfaces. So far, only basic bob deinterlacing is + * implemented. + */ + +#include "config.h" +#include +#include +#include +#include + +#include "gstvaapipluginutil.h" +#include "gstvaapipostproc.h" + +#define GST_PLUGIN_NAME "vaapipostproc" +#define GST_PLUGIN_DESC "A video postprocessing filter" + +GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapipostproc); +#define GST_CAT_DEFAULT gst_debug_vaapipostproc + +/* ElementFactory information */ +static const GstElementDetails gst_vaapipostproc_details = + GST_ELEMENT_DETAILS( + "VA-API video postprocessing", + "Filter/Converter/Video", + GST_PLUGIN_DESC, + "Gwenole Beauchesne "); + +/* Default templates */ +static const char gst_vaapipostproc_sink_caps_str[] = + GST_VAAPI_SURFACE_CAPS ", " + "interlaced = (boolean) { true, false }"; + +static const char gst_vaapipostproc_src_caps_str[] = + GST_VAAPI_SURFACE_CAPS ", " + "interlaced = (boolean) false"; + +static GstStaticPadTemplate gst_vaapipostproc_sink_factory = + GST_STATIC_PAD_TEMPLATE( + "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS(gst_vaapipostproc_sink_caps_str)); + +static GstStaticPadTemplate gst_vaapipostproc_src_factory = + GST_STATIC_PAD_TEMPLATE( + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS(gst_vaapipostproc_src_caps_str)); + +#define GstVideoContextClass GstVideoContextInterface +GST_BOILERPLATE_WITH_INTERFACE( + GstVaapiPostproc, + gst_vaapipostproc, + GstElement, + GST_TYPE_ELEMENT, + GstVideoContext, + GST_TYPE_VIDEO_CONTEXT, + gst_video_context); + +enum { + PROP_0, + + PROP_DEINTERLACE_MODE, + PROP_DEINTERLACE_METHOD, +}; + +#define DEFAULT_DEINTERLACE_MODE GST_VAAPI_DEINTERLACE_MODE_AUTO +#define DEFAULT_DEINTERLACE_METHOD GST_VAAPI_DEINTERLACE_METHOD_BOB + +#define GST_TYPE_VAAPI_DEINTERLACE_MODES \ + gst_vaapi_deinterlace_modes_get_type() + +static GType +gst_vaapi_deinterlace_modes_get_type(void) +{ + static GType deinterlace_modes_type = 0; + + static const GEnumValue modes_types[] = { + { GST_VAAPI_DEINTERLACE_MODE_AUTO, + "Auto detection", "auto" }, + { GST_VAAPI_DEINTERLACE_MODE_INTERLACED, + "Force deinterlacing", "interlaced" }, + { GST_VAAPI_DEINTERLACE_MODE_DISABLED, + "Never deinterlace", "disabled" }, + { 0, NULL, NULL }, + }; + + if (!deinterlace_modes_type) { + deinterlace_modes_type = + g_enum_register_static("GstVaapiDeinterlaceModes", modes_types); + } + return deinterlace_modes_type; +} + +#define GST_TYPE_VAAPI_DEINTERLACE_METHODS \ + gst_vaapi_deinterlace_methods_get_type() + +static GType +gst_vaapi_deinterlace_methods_get_type(void) +{ + static GType deinterlace_methods_type = 0; + + static const GEnumValue methods_types[] = { + { GST_VAAPI_DEINTERLACE_METHOD_BOB, + "Bob deinterlacing", "bob" }, +#if 0 + /* VA/VPP */ + { GST_VAAPI_DEINTERLACE_METHOD_WEAVE, + "Weave deinterlacing", "weave" }, + { GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE, + "Motion adaptive deinterlacing", "motion-adaptive" }, + { GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED, + "Motion compensated deinterlacing", "motion-compensated" }, +#endif + { 0, NULL, NULL }, + }; + + if (!deinterlace_methods_type) { + deinterlace_methods_type = + g_enum_register_static("GstVaapiDeinterlaceMethods", methods_types); + } + return deinterlace_methods_type; +} + +static inline GstVaapiPostproc * +get_vaapipostproc_from_pad(GstPad *pad) +{ + return GST_VAAPIPOSTPROC(gst_pad_get_parent_element(pad)); +} + +/* GstVideoContext interface */ + +static void +gst_vaapipostproc_set_video_context( + GstVideoContext *context, + const gchar *type, + const GValue *value +) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(context); + + gst_vaapi_set_display(type, value, &postproc->display); +} + +static gboolean +gst_video_context_supported(GstVaapiPostproc *postproc, GType iface_type) +{ + return (iface_type == GST_TYPE_VIDEO_CONTEXT); +} + +static void +gst_video_context_interface_init(GstVideoContextInterface *iface) +{ + iface->set_context = gst_vaapipostproc_set_video_context; +} + +static gboolean +gst_vaapipostproc_create(GstVaapiPostproc *postproc, GstCaps *caps) +{ + if (!gst_vaapi_ensure_display(postproc, &postproc->display)) + return FALSE; + + gst_caps_replace(&postproc->postproc_caps, caps); + return TRUE; +} + +static void +gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) +{ + gst_caps_replace(&postproc->postproc_caps, NULL); + + if (postproc->display) { + g_object_unref(postproc->display); + postproc->display = NULL; + } +} + +static gboolean +gst_vaapipostproc_reset(GstVaapiPostproc *postproc, GstCaps *caps) +{ + if (postproc->postproc_caps && + gst_caps_is_always_compatible(caps, postproc->postproc_caps)) + return TRUE; + + gst_vaapipostproc_destroy(postproc); + return gst_vaapipostproc_create(postproc, caps); +} + +static gboolean +gst_vaapipostproc_start(GstVaapiPostproc *postproc) +{ + if (!gst_vaapi_ensure_display(postproc, &postproc->display)) + return FALSE; + return TRUE; +} + +static gboolean +gst_vaapipostproc_stop(GstVaapiPostproc *postproc) +{ + if (postproc->display) { + g_object_unref(postproc->display); + postproc->display = NULL; + } + return TRUE; +} + +static GstFlowReturn +gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) +{ + GstVaapiVideoBuffer *vbuf = GST_VAAPI_VIDEO_BUFFER(buf); + GstVaapiSurfaceProxy *proxy; + GstClockTime timestamp; + GstFlowReturn ret; + GstBuffer *outbuf = NULL; + guint outbuf_flags, flags = 0; + gboolean tff; + + /* Deinterlacing disabled, push frame */ + if (!postproc->deinterlace) { + gst_vaapi_video_buffer_set_render_flags(vbuf, flags); + ret = gst_pad_push(postproc->srcpad, buf); + if (ret != GST_FLOW_OK) + goto error_push_buffer; + return GST_FLOW_OK; + } + + timestamp = GST_BUFFER_TIMESTAMP(buf); + proxy = gst_vaapi_video_buffer_get_surface_proxy(vbuf); + tff = gst_vaapi_surface_proxy_get_tff(proxy); + + /* First field */ + outbuf = gst_vaapi_video_buffer_new_with_surface_proxy(proxy); + if (!outbuf) + goto error_create_buffer; + + vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf); + outbuf_flags = flags; + outbuf_flags |= tff ? + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + gst_vaapi_video_buffer_set_render_flags(vbuf, outbuf_flags); + + GST_BUFFER_TIMESTAMP(outbuf) = timestamp; + GST_BUFFER_DURATION(outbuf) = postproc->field_duration; + gst_buffer_set_caps(outbuf, postproc->srcpad_caps); + ret = gst_pad_push(postproc->srcpad, outbuf); + if (ret != GST_FLOW_OK) + goto error_push_buffer; + + /* Second field */ + outbuf = gst_vaapi_video_buffer_new_with_surface_proxy(proxy); + if (!outbuf) + goto error_create_buffer; + + vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf); + outbuf_flags = flags; + outbuf_flags |= tff ? + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD : + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + gst_vaapi_video_buffer_set_render_flags(vbuf, outbuf_flags); + + GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration; + GST_BUFFER_DURATION(outbuf) = postproc->field_duration; + gst_buffer_set_caps(outbuf, postproc->srcpad_caps); + ret = gst_pad_push(postproc->srcpad, outbuf); + if (ret != GST_FLOW_OK) + goto error_push_buffer; + + gst_buffer_unref(buf); + return GST_FLOW_OK; + + /* ERRORS */ +error_create_buffer: + { + GST_ERROR("failed to create output buffer"); + gst_buffer_unref(buf); + return GST_FLOW_UNEXPECTED; + } +error_push_buffer: + { + if (ret != GST_FLOW_WRONG_STATE) + GST_ERROR("failed to push output buffer to video sink"); + gst_buffer_unref(buf); + return GST_FLOW_UNEXPECTED; + } +} + +static gboolean +gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps) +{ + gint fps_n, fps_d; + gboolean interlaced; + + if (!gst_video_parse_caps_framerate(caps, &fps_n, &fps_d)) + return FALSE; + postproc->fps_n = fps_n; + postproc->fps_d = fps_d; + + switch (postproc->deinterlace_mode) { + case GST_VAAPI_DEINTERLACE_MODE_AUTO: + if (!gst_video_format_parse_caps_interlaced(caps, &interlaced)) + return FALSE; + postproc->deinterlace = interlaced; + break; + case GST_VAAPI_DEINTERLACE_MODE_INTERLACED: + postproc->deinterlace = TRUE; + break; + case GST_VAAPI_DEINTERLACE_MODE_DISABLED: + postproc->deinterlace = FALSE; + break; + } + + postproc->field_duration = gst_util_uint64_scale( + GST_SECOND, + postproc->fps_d, + (1 + postproc->deinterlace) * postproc->fps_n + ); + + gst_caps_replace(&postproc->sinkpad_caps, caps); + return TRUE; +} + +static gboolean +gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps) +{ + GstCaps *src_caps; + GstStructure *structure; + const GValue *v_width, *v_height, *v_par; + gint fps_n, fps_d; + + if (postproc->srcpad_caps) + src_caps = gst_caps_make_writable(postproc->srcpad_caps); + else + src_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); + if (!src_caps) + return FALSE; + postproc->srcpad_caps = src_caps; + + structure = gst_caps_get_structure(caps, 0); + v_width = gst_structure_get_value(structure, "width"); + v_height = gst_structure_get_value(structure, "height"); + v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); + + structure = gst_caps_get_structure(src_caps, 0); + if (v_width && v_height) { + gst_structure_set_value(structure, "width", v_width); + gst_structure_set_value(structure, "height", v_height); + } + if (v_par) + gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); + + gst_structure_set(structure, "type", G_TYPE_STRING, "vaapi", NULL); + gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, NULL); + + if (!postproc->deinterlace) + gst_structure_remove_field(structure, "interlaced"); + else { + /* Set double framerate in interlaced mode */ + if (!gst_util_fraction_multiply(postproc->fps_n, postproc->fps_d, + 2, 1, + &fps_n, &fps_d)) + return FALSE; + + gst_structure_set( + structure, + "interlaced", G_TYPE_BOOLEAN, FALSE, + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, + NULL + ); + } + return gst_pad_set_caps(postproc->srcpad, src_caps); +} + +static gboolean +gst_vaapipostproc_ensure_allowed_caps(GstVaapiPostproc *postproc) +{ + if (postproc->allowed_caps) + return TRUE; + + postproc->allowed_caps = + gst_caps_from_string(gst_vaapipostproc_sink_caps_str); + if (!postproc->allowed_caps) + return FALSE; + + /* XXX: append VA/VPP filters */ + return TRUE; +} + +static GstCaps * +gst_vaapipostproc_get_caps(GstPad *pad) +{ + GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); + GstCaps *out_caps; + + if (gst_vaapipostproc_ensure_allowed_caps(postproc)) + out_caps = gst_caps_ref(postproc->allowed_caps); + else + out_caps = gst_caps_new_empty(); + + gst_object_unref(postproc); + return out_caps; +} + +static gboolean +gst_vaapipostproc_set_caps(GstPad *pad, GstCaps *caps) +{ + GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); + gboolean success = FALSE; + + g_return_val_if_fail(pad == postproc->sinkpad, FALSE); + + do { + if (!gst_vaapipostproc_update_sink_caps(postproc, caps)) + break; + if (!gst_vaapipostproc_update_src_caps(postproc, caps)) + break; + if (!gst_vaapipostproc_reset(postproc, postproc->sinkpad_caps)) + break; + success = TRUE; + } while (0); + gst_object_unref(postproc); + return success; +} + +static GstFlowReturn +gst_vaapipostproc_chain(GstPad *pad, GstBuffer *buf) +{ + GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); + GstFlowReturn ret; + + ret = gst_vaapipostproc_process(postproc, buf); + gst_object_unref(postproc); + return ret; +} + +static gboolean +gst_vaapipostproc_sink_event(GstPad *pad, GstEvent *event) +{ + GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); + gboolean success; + + GST_DEBUG("handle sink event '%s'", GST_EVENT_TYPE_NAME(event)); + + /* Propagate event downstream */ + success = gst_pad_push_event(postproc->srcpad, event); + gst_object_unref(postproc); + return success; +} + +static gboolean +gst_vaapipostproc_src_event(GstPad *pad, GstEvent *event) +{ + GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); + gboolean success; + + GST_DEBUG("handle src event '%s'", GST_EVENT_TYPE_NAME(event)); + + /* Propagate event upstream */ + success = gst_pad_push_event(postproc->sinkpad, event); + gst_object_unref(postproc); + return success; +} + +static gboolean +gst_vaapipostproc_query(GstPad *pad, GstQuery *query) +{ + GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); + gboolean success; + + GST_DEBUG("sharing display %p", postproc->display); + + if (gst_vaapi_reply_to_query(query, postproc->display)) + success = TRUE; + else + success = gst_pad_query_default(pad, query); + + gst_object_unref(postproc); + return success; +} + +static void +gst_vaapipostproc_finalize(GObject *object) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(object); + + gst_vaapipostproc_destroy(postproc); + + gst_caps_replace(&postproc->sinkpad_caps, NULL); + gst_caps_replace(&postproc->srcpad_caps, NULL); + gst_caps_replace(&postproc->allowed_caps, NULL); + + G_OBJECT_CLASS(parent_class)->finalize(object); +} + +static void +gst_vaapipostproc_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(object); + + switch (prop_id) { + case PROP_DEINTERLACE_MODE: + postproc->deinterlace_mode = g_value_get_enum(value); + break; + case PROP_DEINTERLACE_METHOD: + postproc->deinterlace_method = g_value_get_enum(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapipostproc_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(object); + + switch (prop_id) { + case PROP_DEINTERLACE_MODE: + g_value_set_enum(value, postproc->deinterlace_mode); + break; + case PROP_DEINTERLACE_METHOD: + g_value_set_enum(value, postproc->deinterlace_method); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static GstStateChangeReturn +gst_vaapipostproc_change_state(GstElement *element, GstStateChange transition) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(element); + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + if (!gst_vaapipostproc_start(postproc)) + return GST_STATE_CHANGE_FAILURE; + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition); + if (ret != GST_STATE_CHANGE_SUCCESS) + return ret; + + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + break; + case GST_STATE_CHANGE_READY_TO_NULL: + if (!gst_vaapipostproc_stop(postproc)) + return GST_STATE_CHANGE_FAILURE; + break; + default: + break; + } + return GST_STATE_CHANGE_SUCCESS; +} + +static void +gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapipostproc, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + object_class->finalize = gst_vaapipostproc_finalize; + object_class->set_property = gst_vaapipostproc_set_property; + object_class->get_property = gst_vaapipostproc_get_property; + + element_class->change_state = gst_vaapipostproc_change_state; + + /** + * GstVaapiSink:deinterlace-mode: + * + * This selects whether the deinterlacing should always be applied or if + * they should only be applied on content that has the "interlaced" flag + * on the caps. + */ + g_object_class_install_property + (object_class, + PROP_DEINTERLACE_MODE, + g_param_spec_enum("deinterlace", + "Deinterlace", + "Deinterlace mode to use", + GST_TYPE_VAAPI_DEINTERLACE_MODES, + DEFAULT_DEINTERLACE_MODE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiSink:deinterlace-method: + * + * This selects the deinterlacing method to apply. + */ + g_object_class_install_property + (object_class, + PROP_DEINTERLACE_METHOD, + g_param_spec_enum("deinterlace-method", + "Deinterlace method", + "Deinterlace method to use", + GST_TYPE_VAAPI_DEINTERLACE_METHODS, + DEFAULT_DEINTERLACE_METHOD, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static void +gst_vaapipostproc_base_init(gpointer klass) +{ + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstPadTemplate *pad_template; + + gst_element_class_set_details(element_class, &gst_vaapipostproc_details); + + /* sink pad */ + pad_template = gst_static_pad_template_get(&gst_vaapipostproc_sink_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); + + /* src pad */ + pad_template = gst_static_pad_template_get(&gst_vaapipostproc_src_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); +} + +static void +gst_vaapipostproc_init(GstVaapiPostproc *postproc, GstVaapiPostprocClass *klass) +{ + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + + postproc->allowed_caps = NULL; + postproc->postproc_caps = NULL; + postproc->display = NULL; + postproc->surface_width = 0; + postproc->surface_height = 0; + postproc->deinterlace = FALSE; + postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE; + postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; + postproc->field_duration = GST_CLOCK_TIME_NONE; + postproc->fps_n = 0; + postproc->fps_d = 0; + + /* Pad through which data comes in to the element */ + postproc->sinkpad = gst_pad_new_from_template( + gst_element_class_get_pad_template(element_class, "sink"), + "sink" + ); + postproc->sinkpad_caps = NULL; + + gst_pad_set_getcaps_function(postproc->sinkpad, gst_vaapipostproc_get_caps); + gst_pad_set_setcaps_function(postproc->sinkpad, gst_vaapipostproc_set_caps); + gst_pad_set_chain_function(postproc->sinkpad, gst_vaapipostproc_chain); + gst_pad_set_event_function(postproc->sinkpad, gst_vaapipostproc_sink_event); + gst_pad_set_query_function(postproc->sinkpad, gst_vaapipostproc_query); + gst_element_add_pad(GST_ELEMENT(postproc), postproc->sinkpad); + + /* Pad through which data goes out of the element */ + postproc->srcpad = gst_pad_new_from_template( + gst_element_class_get_pad_template(element_class, "src"), + "src" + ); + postproc->srcpad_caps = NULL; + + gst_pad_set_event_function(postproc->srcpad, gst_vaapipostproc_src_event); + gst_pad_set_query_function(postproc->srcpad, gst_vaapipostproc_query); + gst_element_add_pad(GST_ELEMENT(postproc), postproc->srcpad); +} diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h new file mode 100644 index 0000000000..281d2863a8 --- /dev/null +++ b/gst/vaapi/gstvaapipostproc.h @@ -0,0 +1,123 @@ +/* + * gstvaapipostproc.h - VA-API video post processing + * + * Copyright (C) 2012 Intel Corporation + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA +*/ + +#ifndef GST_VAAPIPOSTPROC_H +#define GST_VAAPIPOSTPROC_H + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIPOSTPROC \ + (gst_vaapipostproc_get_type()) + +#define GST_VAAPIPOSTPROC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_TYPE_VAAPIPOSTPROC, \ + GstVaapiPostproc)) + +#define GST_VAAPIPOSTPROC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_TYPE_VAAPIPOSTPROC, \ + GstVaapiPostprocClass)) + +#define GST_IS_VAAPIPOSTPROC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPIPOSTPROC)) + +#define GST_IS_VAAPIPOSTPROC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPIPOSTPROC)) + +#define GST_VAAPIPOSTPROC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_TYPE_VAAPIPOSTPROC, \ + GstVaapiPostprocClass)) + +typedef struct _GstVaapiPostproc GstVaapiPostproc; +typedef struct _GstVaapiPostprocClass GstVaapiPostprocClass; + +typedef enum _GstVaapiDeinterlaceMode GstVaapiDeinterlaceMode; +typedef enum _GstVaapiDeinterlaceMethod GstVaapiDeinterlaceMethod; + +/** + * GstVaapiDeinterlaceMode: + * @GST_VAAPI_DEINTERLACE_MODE_AUTO: Auto detect needs for deinterlacing. + * @GST_VAAPI_DEINTERLACE_MODE_INTERLACED: Force deinterlacing. + * @GST_VAAPI_DEINTERLACE_MODE_DISABLED: Never perform deinterlacing. + */ +enum _GstVaapiDeinterlaceMode { + GST_VAAPI_DEINTERLACE_MODE_AUTO = 0, + GST_VAAPI_DEINTERLACE_MODE_INTERLACED, + GST_VAAPI_DEINTERLACE_MODE_DISABLED, +}; + +/** + * GstVaapiDeinterlaceMethod: + * @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. + */ +enum _GstVaapiDeinterlaceMethod { + GST_VAAPI_DEINTERLACE_METHOD_BOB = 1, + GST_VAAPI_DEINTERLACE_METHOD_WEAVE, + GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE, + GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED, +}; + +struct _GstVaapiPostproc { + /*< private >*/ + GstElement parent_instance; + + GstPad *sinkpad; + GstCaps *sinkpad_caps; + GstPad *srcpad; + GstCaps *srcpad_caps; + GstCaps *allowed_caps; + GstCaps *postproc_caps; + + GstVaapiDisplay *display; + guint surface_width; + guint surface_height; + + /* Deinterlacing */ + gboolean deinterlace; + GstVaapiDeinterlaceMode deinterlace_mode; + GstVaapiDeinterlaceMethod deinterlace_method; + GstClockTime field_duration; + gint fps_n; + gint fps_d; +}; + +struct _GstVaapiPostprocClass { + /*< private >*/ + GstElementClass parent_class; +}; + +GType +gst_vaapipostproc_get_type(void); + +G_END_DECLS + +#endif /* GST_VAAPIPOSTPROC_H */ From b98d334dce30746df20787dfc8d0d7c4324ccaea Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 28 Mar 2012 15:16:17 +0200 Subject: [PATCH 0652/3781] vaapipostproc: get "interlaced" attribute from surface proxy. Add new "interlaced" attribute to GstVaapiSurfaceProxy. Use this in vaapipostproc so that to handles cases where bitstream is interlaced but almost only frame pictures are generated. In this case, we should not be alternating between top/bottom fields. --- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 4 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 55 ++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 15 ++++++ gst/vaapi/gstvaapipostproc.c | 28 +++++++---- 4 files changed, 89 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 6309ed8d18..2d4d55017a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -496,8 +496,8 @@ render_frame(GstVaapiDecoderFfmpeg *decoder, AVFrame *frame) return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; gst_vaapi_surface_proxy_set_timestamp(proxy, frame->pts); - if (frame->interlaced_frame) - gst_vaapi_surface_proxy_set_tff(proxy, frame->top_field_first); + gst_vaapi_surface_proxy_set_interlaced(proxy, !!frame->interlaced_frame); + gst_vaapi_surface_proxy_set_tff(proxy, frame->top_field_first); gst_vaapi_decoder_push_surface_proxy(base_decoder, g_object_ref(proxy)); return GST_VAAPI_DECODER_STATUS_SUCCESS; } diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 9b01ac34d6..3c2f2299ce 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -43,7 +43,8 @@ struct _GstVaapiSurfaceProxyPrivate { GstVaapiContext *context; GstVaapiSurface *surface; GstClockTime timestamp; - gboolean tff; + guint is_interlaced : 1; + guint tff : 1; }; enum { @@ -52,6 +53,7 @@ enum { PROP_CONTEXT, PROP_SURFACE, PROP_TIMESTAMP, + PROP_INTERLACED, PROP_TFF }; @@ -86,6 +88,9 @@ gst_vaapi_surface_proxy_set_property( case PROP_TIMESTAMP: gst_vaapi_surface_proxy_set_timestamp(proxy, g_value_get_uint64(value)); break; + case PROP_INTERLACED: + gst_vaapi_surface_proxy_set_interlaced(proxy, g_value_get_boolean(value)); + break; case PROP_TFF: gst_vaapi_surface_proxy_set_tff(proxy, g_value_get_boolean(value)); break; @@ -115,6 +120,9 @@ gst_vaapi_surface_proxy_get_property( case PROP_TIMESTAMP: g_value_set_uint64(value, gst_vaapi_surface_proxy_get_timestamp(proxy)); break; + case PROP_INTERLACED: + g_value_set_boolean(value, gst_vaapi_surface_proxy_get_interlaced(proxy)); + break; case PROP_TFF: g_value_set_boolean(value, gst_vaapi_surface_proxy_get_tff(proxy)); break; @@ -160,6 +168,15 @@ gst_vaapi_surface_proxy_class_init(GstVaapiSurfaceProxyClass *klass) 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, G_PARAM_READWRITE)); + g_object_class_install_property + (object_class, + PROP_INTERLACED, + g_param_spec_boolean("interlaced", + "Interlaced", + "Flag indicating whether surface is interlaced", + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_TFF, @@ -180,6 +197,7 @@ gst_vaapi_surface_proxy_init(GstVaapiSurfaceProxy *proxy) priv->context = NULL; priv->surface = NULL; priv->timestamp = GST_CLOCK_TIME_NONE; + priv->is_interlaced = FALSE; priv->tff = FALSE; } @@ -351,6 +369,39 @@ gst_vaapi_surface_proxy_set_timestamp( proxy->priv->timestamp = timestamp; } +/** + * gst_vaapi_surface_proxy_get_interlaced: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns whether the @proxy holds an interlaced #GstVaapiSurface or not. + * + * Return value: %TRUE if the underlying surface is interlaced, %FALSE + * otherwise. + */ +gboolean +gst_vaapi_surface_proxy_get_interlaced(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE); + + return proxy->priv->is_interlaced; +} + +/** + * gst_vaapi_surface_proxy_set_interlaced: + * @proxy: a #GstVaapiSurfaceProxy + * @b: a boolean value + * + * Sets whether the underlying #GstVaapiSurface for @proxy is interlaced + * or not. + */ +void +gst_vaapi_surface_proxy_set_interlaced(GstVaapiSurfaceProxy *proxy, gboolean b) +{ + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + + proxy->priv->is_interlaced = b; +} + /** * gst_vaapi_surface_proxy_get_tff: * @proxy: a #GstVaapiSurfaceProxy @@ -364,7 +415,7 @@ gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE); - return proxy->priv->tff; + return proxy->priv->is_interlaced && proxy->priv->tff; } /** diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index a6d963081f..b32458c76b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -72,6 +72,15 @@ G_BEGIN_DECLS #define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(surface) \ gst_vaapi_surface_proxy_get_timestamp(surface) +/** + * GST_VAAPI_SURFACE_PROXY_INTERLACED: + * @surface: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to %TRUE if the @surface is interlaced. + */ +#define GST_VAAPI_SURFACE_PROXY_INTERLACED(surface) \ + gst_vaapi_surface_proxy_get_interlaced(surface) + /** * GST_VAAPI_SURFACE_PROXY_TFF: * @surface: a #GstVaapiSurfaceProxy @@ -143,6 +152,12 @@ gst_vaapi_surface_proxy_set_timestamp( GstClockTime timestamp ); +gboolean +gst_vaapi_surface_proxy_get_interlaced(GstVaapiSurfaceProxy *proxy); + +void +gst_vaapi_surface_proxy_set_interlaced(GstVaapiSurfaceProxy *proxy, gboolean b); + gboolean gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index e0f9f67914..31a46e250c 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -239,8 +239,10 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) GstClockTime timestamp; GstFlowReturn ret; GstBuffer *outbuf = NULL; - guint outbuf_flags, flags = 0; - gboolean tff; + guint outbuf_flags, flags; + gboolean interlaced, tff; + + flags = gst_vaapi_video_buffer_get_render_flags(vbuf); /* Deinterlacing disabled, push frame */ if (!postproc->deinterlace) { @@ -251,9 +253,13 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) return GST_FLOW_OK; } - timestamp = GST_BUFFER_TIMESTAMP(buf); - proxy = gst_vaapi_video_buffer_get_surface_proxy(vbuf); - tff = gst_vaapi_surface_proxy_get_tff(proxy); + timestamp = GST_BUFFER_TIMESTAMP(buf); + proxy = gst_vaapi_video_buffer_get_surface_proxy(vbuf); + interlaced = gst_vaapi_surface_proxy_get_interlaced(proxy); + tff = gst_vaapi_surface_proxy_get_tff(proxy); + + flags &= ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); /* First field */ outbuf = gst_vaapi_video_buffer_new_with_surface_proxy(proxy); @@ -262,9 +268,11 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf); outbuf_flags = flags; - outbuf_flags |= tff ? + outbuf_flags |= interlaced ? ( + tff ? GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) : + GST_VAAPI_PICTURE_STRUCTURE_FRAME; gst_vaapi_video_buffer_set_render_flags(vbuf, outbuf_flags); GST_BUFFER_TIMESTAMP(outbuf) = timestamp; @@ -281,9 +289,11 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf); outbuf_flags = flags; - outbuf_flags |= tff ? + outbuf_flags |= interlaced ? ( + tff ? GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD : - GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) : + GST_VAAPI_PICTURE_STRUCTURE_FRAME; gst_vaapi_video_buffer_set_render_flags(vbuf, outbuf_flags); GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration; From a7ec623279b6f63633df8f6f54581d85fc5deb35 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 28 Mar 2012 14:24:40 +0200 Subject: [PATCH 0653/3781] decoder: fix semantics of SKIPPED pictures. If GstVaapiPicture has flag SKIPPED set, this means gst_vaapi_picture_output() will not push the underlying surface for rendering. Besides, VC-1 skipped P-frame has nothing to do with rendering. This only means that the currently decoded picture is just a copy of its reference picture. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 8 +++++--- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 3 +++ gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 2 -- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index f089aa2ff8..adad9c6abe 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -250,9 +250,11 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) if (!picture->proxy) return FALSE; - proxy = g_object_ref(picture->proxy); - gst_vaapi_surface_proxy_set_timestamp(proxy, picture->pts); - gst_vaapi_decoder_push_surface_proxy(GET_DECODER(picture), proxy); + if (!GST_VAAPI_PICTURE_IS_SKIPPED(picture)) { + proxy = g_object_ref(picture->proxy); + gst_vaapi_surface_proxy_set_timestamp(proxy, picture->pts); + gst_vaapi_decoder_push_surface_proxy(GET_DECODER(picture), proxy); + } return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 6566fec047..c53492dfa4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -101,6 +101,9 @@ enum { #define GST_VAAPI_PICTURE_FLAG_SET GST_MINI_OBJECT_FLAG_SET #define GST_VAAPI_PICTURE_FLAG_UNSET GST_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) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index d7d68121c2..63fbc7307b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -933,8 +933,6 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); break; case GST_VC1_PICTURE_TYPE_SKIPPED: - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_SKIPPED); - // fall-through case GST_VC1_PICTURE_TYPE_P: picture->type = GST_VAAPI_PICTURE_TYPE_P; GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); From e8756ae4270d5fdc476bdd75d505371deb995ee8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 28 Mar 2012 14:28:26 +0200 Subject: [PATCH 0654/3781] decoder: add OUTPUT flag to pictures. Allow pictures to be marked as output gst_vaapi_picture_output(). --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index adad9c6abe..79f8a1646d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -255,6 +255,7 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) gst_vaapi_surface_proxy_set_timestamp(proxy, picture->pts); gst_vaapi_decoder_push_surface_proxy(GET_DECODER(picture), proxy); } + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_OUTPUT); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index c53492dfa4..cb64611e91 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -81,6 +81,7 @@ enum _GstVaapiPictureType { * @GST_VAAPI_PICTURE_FLAG_REFERENCE: reference frame * @GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD: bottom field * @GST_VAAPI_PICTURE_FLAG_TOP_FIELD: top field + * @GST_VAAPI_PICTURE_FLAG_OUTPUT: frame was output * @GST_VAAPI_PICTURE_FLAG_LAST: first flag that can be used by subclasses * * Enum values used for #GstVaapiPicture flags. @@ -90,7 +91,8 @@ enum { GST_VAAPI_PICTURE_FLAG_REFERENCE = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 1), GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 2), GST_VAAPI_PICTURE_FLAG_TOP_FIELD = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 3), - GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 4), + GST_VAAPI_PICTURE_FLAG_OUTPUT = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 4), + GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 5), GST_VAAPI_PICTURE_MASK_STRUCTURE = (GST_VAAPI_PICTURE_FLAG_TOP_FIELD | GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD) @@ -107,6 +109,9 @@ enum { #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_TOP_FIELD(picture) \ GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_TOP_FIELD) From c27385aa8d74ffb33bc9a2bfe10103a2b80d25ba Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 28 Mar 2012 16:07:44 +0200 Subject: [PATCH 0655/3781] decoder: rework picture field flags. Add top-field-first (TFF) and interlaced flags to GstVaapiPicture so they could be propagated to the surface proxy when it is pushed for rendering. Besides, top and bottom fields are now expressed with picture structure flags from GstVaapiSurfaceRenderFlags. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 5 ++-- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 5 ++++ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 31 ++++++++------------ 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index abd0e06dd8..5a77b7deb0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -599,12 +599,13 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) priv->is_first_field ^= 1; switch (pic_ext->picture_structure) { case GST_MPEG_VIDEO_PICTURE_STRUCTURE_TOP_FIELD: - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TOP_FIELD); + picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; break; case GST_MPEG_VIDEO_PICTURE_STRUCTURE_BOTTOM_FIELD: - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD); + picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; break; case GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME: + picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; priv->is_first_field = TRUE; break; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 79f8a1646d..29832dd0f1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -98,6 +98,7 @@ gst_vaapi_picture_create( if (!picture->surface) return FALSE; picture->surface_id = gst_vaapi_surface_get_id(picture->surface); + picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; picture->proxy = gst_vaapi_surface_proxy_new(GET_CONTEXT(picture), picture->surface); @@ -253,6 +254,10 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) if (!GST_VAAPI_PICTURE_IS_SKIPPED(picture)) { proxy = g_object_ref(picture->proxy); gst_vaapi_surface_proxy_set_timestamp(proxy, picture->pts); + if (GST_VAAPI_PICTURE_IS_INTERLACED(picture)) + gst_vaapi_surface_proxy_set_interlaced(proxy, TRUE); + if (GST_VAAPI_PICTURE_IS_TFF(picture)) + gst_vaapi_surface_proxy_set_tff(proxy, TRUE); gst_vaapi_decoder_push_surface_proxy(GET_DECODER(picture), proxy); } GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_OUTPUT); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index cb64611e91..90009c777a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -79,23 +79,20 @@ enum _GstVaapiPictureType { * Picture flags: * @GST_VAAPI_PICTURE_FLAG_SKIPPED: skipped frame * @GST_VAAPI_PICTURE_FLAG_REFERENCE: reference frame - * @GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD: bottom field - * @GST_VAAPI_PICTURE_FLAG_TOP_FIELD: top field * @GST_VAAPI_PICTURE_FLAG_OUTPUT: frame was output + * @GST_VAAPI_PICTURE_FLAG_INTERLACED: interlaced frame + * @GST_VAAPI_PICTURE_FLAG_TFF: top-field-first * @GST_VAAPI_PICTURE_FLAG_LAST: first flag that can be used by subclasses * * Enum values used for #GstVaapiPicture flags. */ 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_BOTTOM_FIELD = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 2), - GST_VAAPI_PICTURE_FLAG_TOP_FIELD = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 3), - GST_VAAPI_PICTURE_FLAG_OUTPUT = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 4), - GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 5), - - GST_VAAPI_PICTURE_MASK_STRUCTURE = (GST_VAAPI_PICTURE_FLAG_TOP_FIELD | - GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD) + 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_TFF = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 5), + GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 6), }; #define GST_VAAPI_PICTURE_FLAGS GST_MINI_OBJECT_FLAGS @@ -112,14 +109,11 @@ enum { #define GST_VAAPI_PICTURE_IS_OUTPUT(picture) \ GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_OUTPUT) -#define GST_VAAPI_PICTURE_IS_TOP_FIELD(picture) \ - GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_TOP_FIELD) +#define GST_VAAPI_PICTURE_IS_INTERLACED(picture) \ + GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED) -#define GST_VAAPI_PICTURE_IS_BOTTOM_FIELD(picture) \ - GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_BOTTOM_FIELD) - -#define GST_VAAPI_PICTURE_IS_FRAME(picture) \ - ((GST_VAAPI_PICTURE_FLAGS(picture) & GST_VAAPI_PICTURE_MASK_STRUCTURE) == 0) +#define GST_VAAPI_PICTURE_IS_TFF(picture) \ + GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF) /** * GstVaapiPicture: @@ -141,6 +135,7 @@ struct _GstVaapiPicture { GstVaapiIqMatrix *iq_matrix; GstVaapiBitPlane *bitplane; GstClockTime pts; + guint structure; }; /** From 195a61fa022b4d828d50c545ee4ac6f936ecbaf9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 28 Mar 2012 16:05:58 +0200 Subject: [PATCH 0656/3781] decoder: allow pictures to be cloned for field decoding. Add gst_vaapi_picture_new_field() function that clones a picture, while preserving the parent picture surface. i.e. the surface proxy reference count is increased and other fields copied as is. Besides, the picture is reset into a "non-output" mode. --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 1 + gst-libs/gst/vaapi/gstvaapicodec_objects.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 87 ++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 5 ++ 4 files changed, 85 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 223069aab8..fd4822da58 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -94,6 +94,7 @@ gst_vaapi_codec_object_new( args.param_size = param_size; args.data = data; args.data_size = data_size; + args.flags = 0; if (gst_vaapi_codec_object_construct(va_obj, &args)) return va_obj; diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index 7577ba6ac7..f379f02608 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -80,6 +80,7 @@ typedef struct { guint param_size; gconstpointer data; guint data_size; + guint flags; } GstVaapiCodecObjectConstructorArgs; /** diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 29832dd0f1..38ab760e29 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -44,6 +44,11 @@ GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPicture, gst_vaapi_picture, GST_VAAPI_TYPE_CODEC_OBJECT) +enum { + GST_VAAPI_CREATE_PICTURE_FLAG_CLONE = 1 << 0, + GST_VAAPI_CREATE_PICTURE_FLAG_FIELD = 1 << 1, +}; + static void destroy_slice_cb(gpointer data, gpointer user_data) { @@ -94,16 +99,50 @@ gst_vaapi_picture_create( { gboolean success; - picture->surface = gst_vaapi_context_get_surface(GET_CONTEXT(picture)); - if (!picture->surface) - return FALSE; - picture->surface_id = gst_vaapi_surface_get_id(picture->surface); - picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + if (args->flags & GST_VAAPI_CREATE_PICTURE_FLAG_CLONE) { + GstVaapiPicture * const parent_picture = GST_VAAPI_PICTURE(args->data); - picture->proxy = - gst_vaapi_surface_proxy_new(GET_CONTEXT(picture), picture->surface); - if (!picture->proxy) - return FALSE; + picture->proxy = g_object_ref(parent_picture->proxy); + picture->surface = gst_vaapi_surface_proxy_get_surface(picture->proxy); + picture->type = parent_picture->type; + picture->pts = parent_picture->pts; + + // 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_TFF) + ); + + 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; + } + } + } + else { + picture->surface = gst_vaapi_context_get_surface(GET_CONTEXT(picture)); + if (!picture->surface) + return FALSE; + + picture->proxy = + gst_vaapi_surface_proxy_new(GET_CONTEXT(picture), picture->surface); + if (!picture->proxy) + return FALSE; + + picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + } + picture->surface_id = gst_vaapi_surface_get_id(picture->surface); success = vaapi_create_buffer( GET_VA_DISPLAY(picture), @@ -116,6 +155,7 @@ gst_vaapi_picture_create( ); if (!success) return FALSE; + picture->param_size = args->param_size; picture->slices = g_ptr_array_new(); if (!picture->slices) @@ -132,6 +172,7 @@ gst_vaapi_picture_init(GstVaapiPicture *picture) picture->surface_id = VA_INVALID_ID; picture->param = NULL; picture->param_id = VA_INVALID_ID; + picture->param_size = 0; picture->slices = NULL; picture->iq_matrix = NULL; picture->bitplane = NULL; @@ -160,6 +201,34 @@ gst_vaapi_picture_new( return GST_VAAPI_PICTURE_CAST(object); } +GstVaapiPicture * +gst_vaapi_picture_new_field(GstVaapiPicture *picture) +{ + GstMiniObject *obj; + GstVaapiCodecObject *va_obj; + GstVaapiCodecObjectConstructorArgs args; + + g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), NULL); + + obj = gst_mini_object_new(GST_VAAPI_TYPE_PICTURE); + if (!obj) + return NULL; + + va_obj = GST_VAAPI_CODEC_OBJECT(obj); + args.codec = GST_VAAPI_CODEC_BASE(GET_DECODER(picture)); + args.param = NULL; + args.param_size = picture->param_size; + args.data = picture; + args.data_size = 0; + args.flags = (GST_VAAPI_CREATE_PICTURE_FLAG_CLONE| + GST_VAAPI_CREATE_PICTURE_FLAG_FIELD); + if (gst_vaapi_codec_object_construct(va_obj, &args)) + return GST_VAAPI_PICTURE_CAST(va_obj); + + gst_mini_object_unref(obj); + return NULL; +} + void gst_vaapi_picture_add_slice(GstVaapiPicture *picture, GstVaapiSlice *slice) { diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 90009c777a..71708f38a5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -126,6 +126,7 @@ struct _GstVaapiPicture { GstVaapiSurface *surface; GstVaapiSurfaceProxy *proxy; VABufferID param_id; + guint param_size; /*< public >*/ GstVaapiPictureType type; @@ -159,6 +160,10 @@ gst_vaapi_picture_new( guint param_size ) attribute_hidden; +GstVaapiPicture * +gst_vaapi_picture_new_field(GstVaapiPicture *picture) + attribute_hidden; + void gst_vaapi_picture_add_slice(GstVaapiPicture *picture, GstVaapiSlice *slice) attribute_hidden; From b56ac162244765b036f283802642cecc2003cd11 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 28 Mar 2012 17:50:28 +0200 Subject: [PATCH 0657/3781] decoder: add first-field flag to picture. Add first-field (FF) flag to GstVaapiPicture, thus not requiring is_first_field member in each decoder. Rather, when a GstVaapiPicture is created, it is considered as the first field. Any subsequent allocated field will become the second field. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 8 +------- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 3 +++ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 5 +++++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 5a77b7deb0..4d5c3c324c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -80,7 +80,6 @@ struct _GstVaapiDecoderMpeg2Private { GstClockTime pts_diff; guint is_constructed : 1; guint is_opened : 1; - guint is_first_field : 1; guint has_seq_ext : 1; guint has_seq_scalable_ext : 1; guint has_pic_ext : 1; @@ -499,8 +498,6 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) priv->gop_pts = pts; if (!priv->pts_diff) priv->pts_diff = priv->seq_pts - priv->gop_pts; - - priv->is_first_field = FALSE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -596,7 +593,6 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) pic_ext->picture_structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME; } - priv->is_first_field ^= 1; switch (pic_ext->picture_structure) { case GST_MPEG_VIDEO_PICTURE_STRUCTURE_TOP_FIELD: picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; @@ -606,7 +602,6 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) break; case GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME: picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - priv->is_first_field = TRUE; break; } return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -643,7 +638,7 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) #define COPY_FIELD(a, b, f) \ pic_param->a.b.f = pic_ext->f pic_param->picture_coding_extension.value = 0; - pic_param->picture_coding_extension.bits.is_first_field = priv->is_first_field; + pic_param->picture_coding_extension.bits.is_first_field = GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture); COPY_FIELD(picture_coding_extension, bits, intra_dc_precision); COPY_FIELD(picture_coding_extension, bits, picture_structure); COPY_FIELD(picture_coding_extension, bits, top_field_first); @@ -945,7 +940,6 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv->pts_diff = 0; priv->is_constructed = FALSE; priv->is_opened = FALSE; - priv->is_first_field = FALSE; priv->has_seq_ext = FALSE; priv->has_seq_scalable_ext = FALSE; priv->has_pic_ext = FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 38ab760e29..ce0de82272 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -114,6 +114,7 @@ gst_vaapi_picture_create( (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) ); @@ -128,6 +129,7 @@ gst_vaapi_picture_create( picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; break; } + GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAG_FF); } } else { @@ -141,6 +143,7 @@ gst_vaapi_picture_create( return FALSE; picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_FF); } picture->surface_id = gst_vaapi_surface_get_id(picture->surface); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 71708f38a5..7858a2f56d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -81,6 +81,7 @@ enum _GstVaapiPictureType { * @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_LAST: first flag that can be used by subclasses * @@ -91,6 +92,7 @@ enum { 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_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 6), }; @@ -112,6 +114,9 @@ enum { #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) From ac4fc0d36ca26e8e35946a4224c8a1cad78b3456 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 28 Mar 2012 14:36:30 +0200 Subject: [PATCH 0658/3781] mpeg2: add new decoded picture buffer infrastructure. Decoded pictures are now maintained into DPB, similarly to H.264. The same mechanism could be re-used for VC-1 and MPEG-4:2 codecs. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 328 +++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_dpb.h | 187 ++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 93 +++--- 4 files changed, 557 insertions(+), 53 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_dpb.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_dpb.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index d35c23d5de..e965214ded 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -148,6 +148,7 @@ endif if USE_CODEC_PARSERS libgstvaapi_source_c += \ gstvaapicodec_objects.c \ + gstvaapidecoder_dpb.c \ gstvaapidecoder_h264.c \ gstvaapidecoder_mpeg2.c \ gstvaapidecoder_mpeg4.c \ @@ -162,6 +163,7 @@ libgstvaapi_source_h += \ $(NULL) libgstvaapi_source_priv_h += \ gstvaapicodec_objects.h \ + gstvaapidecoder_dpb.h \ gstvaapidecoder_objects.h \ $(NULL) libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c new file mode 100644 index 0000000000..4bdd7eb232 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -0,0 +1,328 @@ +/* + * gstvaapidecoder_dpb.c - Decoded Picture Buffer + * + * Copyright (C) 2012 Intel Corporation + * + * 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" + +/* ------------------------------------------------------------------------- */ +/* --- Common Decoded Picture Buffer utilities --- */ +/* ------------------------------------------------------------------------- */ + +static GstVaapiDpb * +dpb_new(GType type, guint max_pictures) +{ + GstMiniObject *obj; + GstVaapiDpb *dpb; + + g_return_val_if_fail(max_pictures > 0, NULL); + + obj = gst_mini_object_new(type); + if (!obj) + return NULL; + + dpb = GST_VAAPI_DPB_CAST(obj); + dpb->pictures = g_new0(GstVaapiPicture *, max_pictures); + if (!dpb->pictures) + goto error; + dpb->max_pictures = max_pictures; + return dpb; + +error: + gst_mini_object_unref(obj); + 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->pts < dpb->pictures[lowest_pts_index]->pts) + 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; +} + +/* ------------------------------------------------------------------------- */ +/* --- Base Decoded Picture Buffer --- */ +/* ------------------------------------------------------------------------- */ + +G_DEFINE_TYPE(GstVaapiDpb, gst_vaapi_dpb, GST_TYPE_MINI_OBJECT) + +static void +gst_vaapi_dpb_base_flush(GstVaapiDpb *dpb) +{ + while (dpb_bump(dpb)) + ; + dpb_clear(dpb); +} + +static gboolean +gst_vaapi_dpb_base_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]->pts < picture->pts) + 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 +gst_vaapi_dpb_finalize(GstMiniObject *object) +{ + GstVaapiDpb * const dpb = GST_VAAPI_DPB_CAST(object); + GstMiniObjectClass *parent_class; + + if (dpb->pictures) { + dpb_clear(dpb); + g_free(dpb->pictures); + } + + parent_class = GST_MINI_OBJECT_CLASS(gst_vaapi_dpb_parent_class); + if (parent_class->finalize) + parent_class->finalize(object); +} + +static void +gst_vaapi_dpb_init(GstVaapiDpb *dpb) +{ + dpb->pictures = NULL; + dpb->num_pictures = 0; + dpb->max_pictures = 0; +} + +static void +gst_vaapi_dpb_class_init(GstVaapiDpbClass *klass) +{ + GstMiniObjectClass * const object_class = GST_MINI_OBJECT_CLASS(klass); + + object_class->finalize = gst_vaapi_dpb_finalize; + klass->flush = gst_vaapi_dpb_base_flush; + klass->add = gst_vaapi_dpb_base_add; +} + +void +gst_vaapi_dpb_flush(GstVaapiDpb *dpb) +{ + 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) +{ + 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); +} + +/* ------------------------------------------------------------------------- */ +/* --- MPEG-2 Decoded Picture Buffer --- */ +/* ------------------------------------------------------------------------- */ + +G_DEFINE_TYPE(GstVaapiDpbMpeg2, gst_vaapi_dpb_mpeg2, GST_VAAPI_TYPE_DPB) + +static gboolean +gst_vaapi_dpb_mpeg2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) +{ + GstVaapiPicture *ref_picture; + gint index = -1; + + g_return_val_if_fail(GST_VAAPI_IS_DPB_MPEG2(dpb), 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]->pts > dpb->pictures[1]->pts); + 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 +gst_vaapi_dpb_mpeg2_init(GstVaapiDpbMpeg2 *dpb) +{ +} + +static void +gst_vaapi_dpb_mpeg2_class_init(GstVaapiDpbMpeg2Class *klass) +{ + GstVaapiDpbClass * const dpb_class = GST_VAAPI_DPB_CLASS(klass); + + dpb_class->add = gst_vaapi_dpb_mpeg2_add; +} + +GstVaapiDpb * +gst_vaapi_dpb_mpeg2_new(void) +{ + return dpb_new(GST_VAAPI_TYPE_DPB_MPEG2, 2); +} + +void +gst_vaapi_dpb_mpeg2_get_references( + GstVaapiDpb *dpb, + GstVaapiPicture *picture, + GstVaapiPicture **prev_picture_ptr, + GstVaapiPicture **next_picture_ptr +) +{ + GstVaapiPicture **picture_ptr, *ref_picture, *ref_pictures[2]; + guint i, index; + + g_return_if_fail(GST_VAAPI_IS_DPB_MPEG2(dpb)); + 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->pts > picture->pts; + picture_ptr = &ref_pictures[index]; + if (!*picture_ptr || ((*picture_ptr)->pts > ref_picture->pts) == 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]; +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h new file mode 100644 index 0000000000..198ad19521 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h @@ -0,0 +1,187 @@ +/* + * gstvaapidecoder_dpb.h - Decoded Picture Buffer + * + * Copyright (C) 2012 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +typedef struct _GstVaapiDpb GstVaapiDpb; +typedef struct _GstVaapiDpbClass GstVaapiDpbClass; +typedef struct _GstVaapiDpbMpeg2 GstVaapiDpbMpeg2; +typedef struct _GstVaapiDpbMpeg2Class GstVaapiDpbMpeg2Class; + +/* ------------------------------------------------------------------------- */ +/* --- Base Decoded Picture Buffer --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_TYPE_DPB \ + (gst_vaapi_dpb_get_type()) + +#define GST_VAAPI_DPB_CAST(obj) \ + ((GstVaapiDpb *)(obj)) + +#define GST_VAAPI_DPB(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DPB, \ + GstVaapiDpb)) + +#define GST_VAAPI_DPB_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DPB, \ + GstVaapiDpbClass)) + +#define GST_VAAPI_IS_DPB(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DPB)) + +#define GST_VAAPI_IS_DPB_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DPB)) + +#define GST_VAAPI_DPB_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DPB, \ + GstVaapiDpbClass)) + +/** + * GstVaapiDpb: + * + * A decoded picture buffer (DPB) object. + */ +struct _GstVaapiDpb { + /*< private >*/ + GstMiniObject parent_instance; + + /*< protected >*/ + GstVaapiPicture **pictures; + guint num_pictures; + guint max_pictures; +}; + +/** + * GstVaapiDpbClass: + * + * The #GstVaapiDpb base class. + */ +struct _GstVaapiDpbClass { + /*< private >*/ + GstMiniObjectClass parent_class; + + /*< protected >*/ + void (*flush) (GstVaapiDpb *dpb); + gboolean (*add) (GstVaapiDpb *dpb, GstVaapiPicture *picture); +}; + +GType +gst_vaapi_dpb_get_type(void) + attribute_hidden; + +void +gst_vaapi_dpb_flush(GstVaapiDpb *dpb) + attribute_hidden; + +gboolean +gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) + attribute_hidden; + +static inline gpointer +gst_vaapi_dpb_ref(gpointer ptr) +{ + return gst_mini_object_ref(GST_MINI_OBJECT(ptr)); +} + +static inline void +gst_vaapi_dpb_unref(gpointer ptr) +{ + gst_mini_object_unref(GST_MINI_OBJECT(ptr)); +} + +/* ------------------------------------------------------------------------- */ +/* --- MPEG-2 Decoded Picture Buffer --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_TYPE_DPB_MPEG2 \ + (gst_vaapi_dpb_mpeg2_get_type()) + +#define GST_VAAPI_DPB_MPEG2_CAST(obj) \ + ((GstVaapiDpbMpeg2 *)(obj)) + +#define GST_VAAPI_DPB_MPEG2(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DPB_MPEG2, \ + GstVaapiDpbMpeg2)) + +#define GST_VAAPI_DPB_MPEG2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DPB_MPEG2, \ + GstVaapiDpbMpeg2Class)) + +#define GST_VAAPI_IS_DPB_MPEG2(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DPB_MPEG2)) + +#define GST_VAAPI_IS_DPB_MPEG2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DPB_MPEG2)) + +#define GST_VAAPI_DPB_MPEG2_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DPB_MPEG2, \ + GstVaapiDpbMpeg2Class)) + +/** + * GstVaapiDpbMpeg2: + * + * A decoded picture buffer (DPB_MPEG2) object. + */ +struct _GstVaapiDpbMpeg2 { + /*< private >*/ + GstVaapiDpb parent_instance; +}; + +/** + * GstVaapiDpbMpeg2Class: + * + * The #GstVaapiDpbMpeg2 base class. + */ +struct _GstVaapiDpbMpeg2Class { + /*< private >*/ + GstVaapiDpbClass parent_class; +}; + +GType +gst_vaapi_dpb_mpeg2_get_type(void) + attribute_hidden; + +GstVaapiDpb * +gst_vaapi_dpb_mpeg2_new(void) + attribute_hidden; + +void +gst_vaapi_dpb_mpeg2_get_references( + GstVaapiDpb *dpb, + GstVaapiPicture *picture, + GstVaapiPicture **prev_picture_ptr, + GstVaapiPicture **next_picture_ptr +) attribute_hidden; + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_DPB */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 4d5c3c324c..65d7fc6baf 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -30,6 +30,7 @@ #include #include "gstvaapidecoder_mpeg2.h" #include "gstvaapidecoder_objects.h" +#include "gstvaapidecoder_dpb.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" @@ -72,8 +73,7 @@ struct _GstVaapiDecoderMpeg2Private { GstMpegVideoPictureExt pic_ext; GstMpegVideoQuantMatrixExt quant_matrix_ext; GstVaapiPicture *current_picture; - GstVaapiPicture *next_picture; - GstVaapiPicture *prev_picture; + GstVaapiDpb *dpb; GstAdapter *adapter; GstClockTime seq_pts; GstClockTime gop_pts; @@ -177,8 +177,11 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) GstVaapiDecoderMpeg2Private * const priv = decoder->priv; gst_vaapi_picture_replace(&priv->current_picture, NULL); - gst_vaapi_picture_replace(&priv->next_picture, NULL); - gst_vaapi_picture_replace(&priv->prev_picture, NULL); + + if (priv->dpb) { + gst_vaapi_dpb_unref(priv->dpb); + priv->dpb = NULL; + } if (priv->adapter) { gst_adapter_clear(priv->adapter); @@ -197,6 +200,10 @@ gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) priv->adapter = gst_adapter_new(); if (!priv->adapter) return FALSE; + + priv->dpb = gst_vaapi_dpb_mpeg2_new(); + if (!priv->dpb) + return FALSE; return TRUE; } @@ -324,32 +331,20 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static inline GstVaapiDecoderStatus -render_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) -{ - if (!gst_vaapi_picture_output(picture)) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus +static gboolean decode_current_picture(GstVaapiDecoderMpeg2 *decoder) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstVaapiPicture * const picture = priv->current_picture; - GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; if (picture) { if (!gst_vaapi_picture_decode(picture)) - status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { - if ((priv->prev_picture && priv->next_picture) || - (priv->closed_gop && priv->next_picture)) - status = render_picture(decoder, picture); - } + return FALSE; + if (!gst_vaapi_dpb_add(priv->dpb, picture)) + return FALSE; gst_vaapi_picture_replace(&priv->current_picture, NULL); } - return status; + return TRUE; } static GstVaapiDecoderStatus @@ -437,19 +432,11 @@ static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstVaapiDecoderStatus status; - if (priv->current_picture) { - status = decode_current_picture(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } + if (priv->current_picture && !decode_current_picture(decoder)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - if (priv->next_picture) { - status = render_picture(decoder, priv->next_picture); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } + gst_vaapi_dpb_flush(priv->dpb); return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; } @@ -516,11 +503,8 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) return status; } - if (priv->current_picture) { - status = decode_current_picture(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } + if (priv->current_picture && !decode_current_picture(decoder)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; priv->current_picture = GST_VAAPI_PICTURE_NEW(MPEG2, decoder); if (!priv->current_picture) { @@ -543,9 +527,11 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) switch (pic_hdr->pic_type) { case GST_MPEG_VIDEO_PICTURE_TYPE_I: + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); picture->type = GST_VAAPI_PICTURE_TYPE_I; break; case GST_MPEG_VIDEO_PICTURE_TYPE_P: + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); picture->type = GST_VAAPI_PICTURE_TYPE_P; break; case GST_MPEG_VIDEO_PICTURE_TYPE_B: @@ -560,15 +546,6 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) pts = priv->gop_pts; pts += gst_util_uint64_scale(pic_hdr->tsn, GST_SECOND * priv->fps_d, priv->fps_n); picture->pts = pts + priv->pts_diff; - - /* Update reference pictures */ - if (pic_hdr->pic_type != GST_MPEG_VIDEO_PICTURE_TYPE_B) { - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - if (priv->next_picture) - status = render_picture(decoder, priv->next_picture); - gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture); - gst_vaapi_picture_replace(&priv->next_picture, picture); - } return status; } @@ -623,6 +600,7 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) VAPictureParameterBufferMPEG2 * const pic_param = picture->param; GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr; GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext; + GstVaapiPicture *prev_picture, *next_picture; if (!priv->has_pic_ext) return FALSE; @@ -650,14 +628,25 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) COPY_FIELD(picture_coding_extension, bits, repeat_first_field); COPY_FIELD(picture_coding_extension, bits, progressive_frame); + gst_vaapi_dpb_mpeg2_get_references( + priv->dpb, + picture, + &prev_picture, + &next_picture + ); + switch (pic_hdr->pic_type) { case GST_MPEG_VIDEO_PICTURE_TYPE_B: - if (priv->next_picture) - pic_param->backward_reference_picture = priv->next_picture->surface_id; - // fall-through + if (next_picture) + pic_param->backward_reference_picture = next_picture->surface_id; + if (prev_picture) + pic_param->forward_reference_picture = prev_picture->surface_id; + else if (!priv->closed_gop) + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_SKIPPED); + break; case GST_MPEG_VIDEO_PICTURE_TYPE_P: - if (priv->prev_picture) - pic_param->forward_reference_picture = priv->prev_picture->surface_id; + if (prev_picture) + pic_param->forward_reference_picture = prev_picture->surface_id; break; } return TRUE; @@ -932,8 +921,6 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv->fps_d = 0; priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; priv->current_picture = NULL; - priv->next_picture = NULL; - priv->prev_picture = NULL; priv->adapter = NULL; priv->seq_pts = GST_CLOCK_TIME_NONE; priv->gop_pts = GST_CLOCK_TIME_NONE; From 7a9410f826c852377a5214dc21203dc07d250d08 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 28 Mar 2012 16:08:29 +0200 Subject: [PATCH 0659/3781] mpeg2: add support for interlaced streams. Pictures are submitted to the HW for rendering only when both fields are decoded or current picture is a full frame. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 37 +++++++++++++++----- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 7 ++++ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 65d7fc6baf..b2a6367d2c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -340,9 +340,11 @@ decode_current_picture(GstVaapiDecoderMpeg2 *decoder) if (picture) { if (!gst_vaapi_picture_decode(picture)) return FALSE; - if (!gst_vaapi_dpb_add(priv->dpb, picture)) - return FALSE; - gst_vaapi_picture_replace(&priv->current_picture, NULL); + if (GST_VAAPI_PICTURE_IS_COMPLETE(picture)) { + if (!gst_vaapi_dpb_add(priv->dpb, picture)) + return FALSE; + gst_vaapi_picture_replace(&priv->current_picture, NULL); + } } return TRUE; } @@ -389,6 +391,7 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) } priv->has_seq_ext = TRUE; priv->progressive_sequence = seq_ext->progressive; + gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence); width = (priv->width & 0x0fff) | ((guint32)seq_ext->horiz_size_ext << 12); height = (priv->height & 0x0fff) | ((guint32)seq_ext->vert_size_ext << 12); @@ -506,12 +509,24 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) if (priv->current_picture && !decode_current_picture(decoder)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - priv->current_picture = GST_VAAPI_PICTURE_NEW(MPEG2, decoder); - if (!priv->current_picture) { - GST_DEBUG("failed to allocate picture"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + if (priv->current_picture) { + /* Re-use current picture where the first field was decoded */ + picture = gst_vaapi_picture_new_field(priv->current_picture); + if (!picture) { + GST_ERROR("failed to allocate field picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } } - picture = priv->current_picture; + else { + /* Create new picture */ + picture = GST_VAAPI_PICTURE_NEW(MPEG2, 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) { @@ -570,6 +585,12 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) pic_ext->picture_structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME; } + if (!priv->progressive_sequence && !pic_ext->progressive_frame) { + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED); + if (pic_ext->top_field_first) + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF); + } + switch (pic_ext->picture_structure) { case GST_MPEG_VIDEO_PICTURE_STRUCTURE_TOP_FIELD: picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 7858a2f56d..fe8d62c420 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -120,6 +120,13 @@ enum { #define GST_VAAPI_PICTURE_IS_TFF(picture) \ GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF) +#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_FIRST_FIELD(picture)) + /** * GstVaapiPicture: * From b003a2bab28a156032e9c888d8d5a48eb833d980 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 28 Mar 2012 19:15:47 +0200 Subject: [PATCH 0660/3781] mpeg2: fix invalid interlaced frame in progressive sequence. Some streams, badly constructed, could have signaled an interlaced frame while the sequence was meant to be progressive. Warn and force frame to be progressive in this case. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index b2a6367d2c..dbf66dd3e4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -577,6 +577,11 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) } priv->has_pic_ext = TRUE; + if (priv->progressive_sequence && !pic_ext->progressive_frame) { + GST_WARNING("invalid interlaced frame in progressive sequence, fixing"); + pic_ext->progressive_frame = 1; + } + if (pic_ext->picture_structure == 0 || (pic_ext->progressive_frame && pic_ext->picture_structure != GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME)) { From 7af40475d54c9d713a01cda4a78446981a7d90bd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 29 Mar 2012 11:13:20 +0200 Subject: [PATCH 0661/3781] mpeg2: review and report errors accordingly. Use GST_ERROR() to report real errors instead of hiding them into GST_DEBUG(). --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index dbf66dd3e4..6cb1ac1f42 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -291,7 +291,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(MPEG2, decoder); if (!picture->iq_matrix) { - GST_DEBUG("failed to allocate IQ matrix"); + GST_ERROR("failed to allocate IQ matrix"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } iq_matrix = picture->iq_matrix->param; @@ -357,7 +357,7 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr; if (!gst_mpeg_video_parse_sequence_header(seq_hdr, buf, buf_size, 0)) { - GST_DEBUG("failed to parse sequence header"); + GST_ERROR("failed to parse sequence header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -386,7 +386,7 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) guint width, height; if (!gst_mpeg_video_parse_sequence_extension(seq_ext, buf, buf_size, 0)) { - GST_DEBUG("failed to parse sequence-extension"); + GST_ERROR("failed to parse sequence-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } priv->has_seq_ext = TRUE; @@ -421,7 +421,7 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) profile = GST_VAAPI_PROFILE_MPEG2_MAIN; break; default: - GST_DEBUG("unsupported profile %d", seq_ext->profile); + GST_ERROR("unsupported profile %d", seq_ext->profile); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } if (priv->profile != profile) { @@ -450,7 +450,7 @@ decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_si GstMpegVideoQuantMatrixExt * const quant_matrix_ext = &priv->quant_matrix_ext; if (!gst_mpeg_video_parse_quant_matrix_extension(quant_matrix_ext, buf, buf_size, 0)) { - GST_DEBUG("failed to parse quant-matrix-extension"); + GST_ERROR("failed to parse quant-matrix-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } priv->has_quant_matrix_ext = TRUE; @@ -466,7 +466,7 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) GstClockTime pts; if (!gst_mpeg_video_parse_gop(&gop, buf, buf_size, 0)) { - GST_DEBUG("failed to parse GOP"); + GST_ERROR("failed to parse GOP"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -502,7 +502,7 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) status = ensure_context(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_DEBUG("failed to reset context"); + GST_ERROR("failed to reset context"); return status; } @@ -530,12 +530,12 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) status = ensure_quant_matrix(decoder, picture); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_DEBUG("failed to reset quantizer matrix"); + GST_ERROR("failed to reset quantizer matrix"); return status; } if (!gst_mpeg_video_parse_picture_header(pic_hdr, buf, buf_size, 0)) { - GST_DEBUG("failed to parse picture header"); + GST_ERROR("failed to parse picture header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } priv->has_pic_ext = FALSE; @@ -553,7 +553,7 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) picture->type = GST_VAAPI_PICTURE_TYPE_B; break; default: - GST_DEBUG("unsupported picture type %d", pic_hdr->pic_type); + GST_ERROR("unsupported picture type %d", pic_hdr->pic_type); return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } @@ -572,7 +572,7 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) GstVaapiPicture * const picture = priv->current_picture; if (!gst_mpeg_video_parse_picture_extension(pic_ext, buf, buf_size, 0)) { - GST_DEBUG("failed to parse picture-extension"); + GST_ERROR("failed to parse picture-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } priv->has_pic_ext = TRUE; @@ -705,7 +705,7 @@ decode_slice( slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, buf, buf_size); if (!slice) { - GST_DEBUG("failed to allocate slice"); + GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } gst_vaapi_picture_add_slice(picture, slice); @@ -715,7 +715,7 @@ decode_slice( if (priv->height > 2800) READ_UINT8(&br, slice_vertical_position_extension, 3); if (priv->has_seq_scalable_ext) { - GST_DEBUG("failed to parse slice %d. Unsupported sequence_scalable_extension()", slice_no); + GST_ERROR("failed to parse slice %d. Unsupported sequence_scalable_extension()", slice_no); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } READ_UINT8(&br, quantiser_scale_code, 5); @@ -838,7 +838,7 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) break; default: // Ignore unknown extensions - GST_DEBUG("unsupported start-code extension (0x%02x)", id); + GST_WARNING("unsupported start-code extension (0x%02x)", id); break; } break; @@ -870,7 +870,7 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; } - GST_DEBUG("unsupported start code (0x%02x)", type); + GST_WARNING("unsupported start code (0x%02x)", type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } From 6eeb20a95316342c76dc501f8d78ea30f11bb2ca Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 30 Mar 2012 17:07:39 +0200 Subject: [PATCH 0662/3781] mpeg2: ignore empty user-data packets. Fix tcela-8.bits conformance test. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 6cb1ac1f42..515f1c44dd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -808,6 +808,15 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) gst_adapter_flush(priv->adapter, 4); size -= ofs; + if (ofs == 4) { + // Ignore empty user-data packets + if ((start_code & 0xff) == GST_MPEG_VIDEO_PACKET_USER_DATA) + continue; + GST_ERROR("failed to get a valid packet (SC: 0x%08x)", start_code); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + buffer = gst_adapter_take_buffer(priv->adapter, ofs - 4); buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); From d51bb8748211f1ad90fcf49a87cbd7e930bfe5d9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 30 Mar 2012 16:23:33 +0200 Subject: [PATCH 0663/3781] mpeg2: rework generation of presentation timestamps. Always prefer PTS from the demuxer layer for GOP times. If this is invalid, i.e. demuxer could not determine the PTS or the generated PTS is lower than max PTS from past pictures, then try to fix it up based on the duration of a frame. For picture PTS, simply use the GOP PTS formerly computed then use TSN to reconstruct a current time. Also now handle wrapped TSN correctly. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 127 +++++++++++++++++---- 1 file changed, 105 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 515f1c44dd..e4e0e957c7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -61,6 +61,102 @@ G_DEFINE_TYPE(GstVaapiDecoderMpeg2, } \ } G_STMT_END +/* PTS Generator */ +typedef struct _PTSGenerator PTSGenerator; +struct _PTSGenerator { + GstClockTime gop_pts; // Current GOP PTS + GstClockTime max_pts; // Max picture PTS + guint gop_tsn; // Absolute GOP TSN + guint max_tsn; // Max picture TSN, relative to last GOP TSN + guint ovl_tsn; // How many times TSN overflowed since GOP + guint lst_tsn; // Last picture TSN + guint fps_n; + guint fps_d; +}; + +static void +pts_init(PTSGenerator *tsg) +{ + tsg->gop_pts = GST_CLOCK_TIME_NONE; + tsg->max_pts = GST_CLOCK_TIME_NONE; + tsg->gop_tsn = 0; + tsg->max_tsn = 0; + tsg->ovl_tsn = 0; + tsg->lst_tsn = 0; + tsg->fps_n = 0; + tsg->fps_d = 0; +} + +static inline GstClockTime +pts_get_duration(PTSGenerator *tsg, guint num_frames) +{ + return gst_util_uint64_scale(num_frames, + GST_SECOND * tsg->fps_d, tsg->fps_n); +} + +static void +pts_set_framerate(PTSGenerator *tsg, guint fps_n, guint fps_d) +{ + tsg->fps_n = fps_n; + tsg->fps_d = fps_d; +} + +static void +pts_sync(PTSGenerator *tsg, GstClockTime gop_pts) +{ + guint gop_tsn; + + if (!GST_CLOCK_TIME_IS_VALID(gop_pts) || + (GST_CLOCK_TIME_IS_VALID(tsg->max_pts) && tsg->max_pts >= gop_pts)) { + /* Invalid GOP PTS, interpolate from the last known picture PTS */ + if (GST_CLOCK_TIME_IS_VALID(tsg->max_pts)) { + gop_pts = tsg->max_pts + pts_get_duration(tsg, 1); + gop_tsn = tsg->gop_tsn + tsg->ovl_tsn * 1024 + tsg->max_tsn + 1; + } + else { + gop_pts = 0; + gop_tsn = 0; + } + } + else { + /* Interpolate GOP TSN from this valid PTS */ + if (GST_CLOCK_TIME_IS_VALID(tsg->gop_pts)) + gop_tsn = tsg->gop_tsn + gst_util_uint64_scale( + gop_pts - tsg->gop_pts, tsg->fps_n, GST_SECOND * tsg->fps_d); + else + gop_tsn = 0; + } + + tsg->gop_pts = gop_pts; + tsg->gop_tsn = gop_tsn; + tsg->max_tsn = 0; + tsg->ovl_tsn = 0; + tsg->lst_tsn = 0; +} + +static GstClockTime +pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn) +{ + GstClockTime pts; + + if (!GST_CLOCK_TIME_IS_VALID(tsg->gop_pts)) + tsg->gop_pts = 0; + + pts = tsg->gop_pts + pts_get_duration(tsg, tsg->ovl_tsn * 1024 + pic_tsn); + + if (!GST_CLOCK_TIME_IS_VALID(tsg->max_pts) || tsg->max_pts < pts) + tsg->max_pts = pts; + + if (tsg->max_tsn < pic_tsn) + tsg->max_tsn = pic_tsn; + else if (tsg->max_tsn == 1023 && pic_tsn < tsg->lst_tsn) { /* TSN wrapped */ + tsg->max_tsn = pic_tsn; + tsg->ovl_tsn++; + } + tsg->lst_tsn = pic_tsn; + return pts; +} + struct _GstVaapiDecoderMpeg2Private { GstVaapiProfile profile; guint width; @@ -75,9 +171,7 @@ struct _GstVaapiDecoderMpeg2Private { GstVaapiPicture *current_picture; GstVaapiDpb *dpb; GstAdapter *adapter; - GstClockTime seq_pts; - GstClockTime gop_pts; - GstClockTime pts_diff; + PTSGenerator tsg; guint is_constructed : 1; guint is_opened : 1; guint has_seq_ext : 1; @@ -204,6 +298,8 @@ gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) priv->dpb = gst_vaapi_dpb_mpeg2_new(); if (!priv->dpb) return FALSE; + + pts_init(&priv->tsg); return TRUE; } @@ -363,10 +459,9 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) priv->fps_n = seq_hdr->fps_n; priv->fps_d = seq_hdr->fps_d; + pts_set_framerate(&priv->tsg, priv->fps_n, priv->fps_d); gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); - priv->seq_pts = gst_adapter_prev_timestamp(priv->adapter, NULL); - priv->width = seq_hdr->width; priv->height = seq_hdr->height; priv->has_seq_ext = FALSE; @@ -400,6 +495,7 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) if (seq_ext->fps_n_ext && seq_ext->fps_d_ext) { priv->fps_n *= seq_ext->fps_n_ext + 1; priv->fps_d *= seq_ext->fps_d_ext + 1; + pts_set_framerate(&priv->tsg, priv->fps_n, priv->fps_d); gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); } @@ -477,17 +573,8 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) gop.hour, gop.minute, gop.second, gop.frame, priv->closed_gop, priv->broken_link); - pts = GST_SECOND * (gop.hour * 3600 + gop.minute * 60 + gop.second); - pts += gst_util_uint64_scale(gop.frame, GST_SECOND * priv->fps_d, priv->fps_n); - if (priv->gop_pts != GST_CLOCK_TIME_NONE && pts <= priv->gop_pts) { - /* Try to fix GOP timestamps, based on demux timestamps */ - pts = gst_adapter_prev_timestamp(priv->adapter, NULL); - if (pts != GST_CLOCK_TIME_NONE) - pts -= priv->pts_diff; - } - priv->gop_pts = pts; - if (!priv->pts_diff) - priv->pts_diff = priv->seq_pts - priv->gop_pts; + pts = gst_adapter_prev_timestamp(priv->adapter, NULL); + pts_sync(&priv->tsg, pts); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -558,9 +645,8 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) } /* Update presentation time */ - pts = priv->gop_pts; - pts += gst_util_uint64_scale(pic_hdr->tsn, GST_SECOND * priv->fps_d, priv->fps_n); - picture->pts = pts + priv->pts_diff; + pts = gst_adapter_prev_timestamp(priv->adapter, NULL); + picture->pts = pts_eval(&priv->tsg, pts, pic_hdr->tsn); return status; } @@ -957,9 +1043,6 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; priv->current_picture = NULL; priv->adapter = NULL; - priv->seq_pts = GST_CLOCK_TIME_NONE; - priv->gop_pts = GST_CLOCK_TIME_NONE; - priv->pts_diff = 0; priv->is_constructed = FALSE; priv->is_opened = FALSE; priv->has_seq_ext = FALSE; From 75538bbc9bf116113248e39511ad261e7d651774 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 30 Mar 2012 17:03:28 +0200 Subject: [PATCH 0664/3781] decoder: use POC to maintain the DPB. Introduce a POC field in GstVaapiPicture so that to store simpler sequential numbers. A signed 32-bit integer should be enough for 1 year of continuous video streaming at 60 Hz. Use this new POC value to maintain the DPB, instead of 64-bit timestamps. This also aligns with H.264 that will be migrated to GstVaapiDpb infrastructure. --- gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 10 +++++----- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 7 +++++++ gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 1 + 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index 4bdd7eb232..6ba5834631 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -70,7 +70,7 @@ dpb_get_oldest(GstVaapiDpb *dpb, gboolean output) GstVaapiPicture * const picture = dpb->pictures[i]; if ((GST_VAAPI_PICTURE_IS_OUTPUT(picture) ^ output) != 0) continue; - if (picture->pts < dpb->pictures[lowest_pts_index]->pts) + if (picture->poc < dpb->pictures[lowest_pts_index]->poc) lowest_pts_index = i; } return lowest_pts_index; @@ -164,7 +164,7 @@ gst_vaapi_dpb_base_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) 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]->pts < picture->pts) + dpb->pictures[i]->poc < picture->poc) break; } if (i == dpb->num_pictures) @@ -261,7 +261,7 @@ gst_vaapi_dpb_mpeg2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) * - the oldest reference picture is replaced with the new reference picture */ if (G_LIKELY(dpb->num_pictures == 2)) { - index = (dpb->pictures[0]->pts > dpb->pictures[1]->pts); + 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)) @@ -315,9 +315,9 @@ gst_vaapi_dpb_mpeg2_get_references( ref_pictures[1] = NULL; for (i = 0; i < dpb->num_pictures; i++) { ref_picture = dpb->pictures[i]; - index = ref_picture->pts > picture->pts; + index = ref_picture->poc > picture->poc; picture_ptr = &ref_pictures[index]; - if (!*picture_ptr || ((*picture_ptr)->pts > ref_picture->pts) == index) + if (!*picture_ptr || ((*picture_ptr)->poc > ref_picture->poc) == index) *picture_ptr = ref_picture; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index e4e0e957c7..815d058f13 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -94,6 +94,12 @@ pts_get_duration(PTSGenerator *tsg, guint num_frames) GST_SECOND * tsg->fps_d, tsg->fps_n); } +static inline guint +pts_get_poc(PTSGenerator *tsg) +{ + return tsg->gop_tsn + tsg->ovl_tsn * 1024 + tsg->lst_tsn; +} + static void pts_set_framerate(PTSGenerator *tsg, guint fps_n, guint fps_d) { @@ -647,6 +653,7 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) /* Update presentation time */ pts = gst_adapter_prev_timestamp(priv->adapter, NULL); picture->pts = pts_eval(&priv->tsg, pts, pic_hdr->tsn); + picture->poc = pts_get_poc(&priv->tsg); return status; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index ce0de82272..4725fac853 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -106,6 +106,7 @@ gst_vaapi_picture_create( picture->surface = gst_vaapi_surface_proxy_get_surface(picture->proxy); picture->type = parent_picture->type; picture->pts = parent_picture->pts; + picture->poc = parent_picture->poc; // Copy all picture flags but "output" GST_VAAPI_PICTURE_FLAG_SET( @@ -180,6 +181,7 @@ gst_vaapi_picture_init(GstVaapiPicture *picture) picture->iq_matrix = NULL; picture->bitplane = NULL; picture->pts = GST_CLOCK_TIME_NONE; + picture->poc = 0; } GstVaapiPicture * diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index fe8d62c420..93d8ce27e4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -148,6 +148,7 @@ struct _GstVaapiPicture { GstVaapiIqMatrix *iq_matrix; GstVaapiBitPlane *bitplane; GstClockTime pts; + gint32 poc; guint structure; }; From b33dd6930081c7ab8d0f1ceee48bc89b21105cdd Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 30 Mar 2012 03:04:40 -0400 Subject: [PATCH 0665/3781] mpeg4: improve error checking while decoding packets. decode_picture() could return an error when an MPEG-4 profile is not supported for example. In this case, the underlying VA context is not allocated and no other proper action can be taken. Likewise on exit from decode_slice(). Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 8f6af3495a..ca31ebd084 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -753,6 +753,8 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) } else if (tos->type == GST_MPEG4_VIDEO_OBJ_PLANE) { status = decode_picture(decoder, packet.data + packet.offset, packet.size); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; /* decode slice * A resync marker shall only be located immediately before a macroblock @@ -769,6 +771,8 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) if (priv->vol_hdr.resync_marker_disable) { status = decode_slice(decoder, _data, _data_size, FALSE); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; } else { // next start_code is required to determine the end of last slice From 99932049e45d4e4bbd229926f4fa31b56dbf6f43 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Apr 2012 10:43:30 +0200 Subject: [PATCH 0666/3781] mpeg2: fix simple to main profile fallback. Allow fallback from simple to main profile when the HW decoder does not support the former profile and that no sequence_header_extension() is available to point out this. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 815d058f13..0e97d2e13d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1057,7 +1057,7 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv->has_pic_ext = FALSE; priv->has_quant_matrix_ext = FALSE; priv->size_changed = FALSE; - priv->profile_changed = FALSE; + priv->profile_changed = TRUE; /* Allow fallbacks to work */ priv->quant_matrix_changed = FALSE; priv->progressive_sequence = FALSE; priv->closed_gop = FALSE; From 5975def8ab076e52919c9249c8f47ac3d6300ae4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Apr 2012 11:29:53 +0200 Subject: [PATCH 0667/3781] mpeg2: allocate dummy picture for first field based I-frame. In P-pictures, prediction shall be made from the two most recently decoded reference fields. However, when the first I-frame is a field, the next field of the current picture could be a P-picture but only a single field was decoded so far. In this case, create a dummy picture with POC = -1 that will be used as reference. Some VA drivers would error out if P-pictures don't have a forward reference picture. This is true in general but not in this very specific initial case. --- gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 8 ++++++ gst-libs/gst/vaapi/gstvaapidecoder_dpb.h | 4 +++ gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 33 ++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index 6ba5834631..da520c48cc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -238,6 +238,14 @@ gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) 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; +} + /* ------------------------------------------------------------------------- */ /* --- MPEG-2 Decoded Picture Buffer --- */ /* ------------------------------------------------------------------------- */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h index 198ad19521..1a199b8949 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h @@ -103,6 +103,10 @@ gboolean gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) attribute_hidden; +guint +gst_vaapi_dpb_size(GstVaapiDpb *dpb) + attribute_hidden; + static inline gpointer gst_vaapi_dpb_ref(gpointer ptr) { diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 0e97d2e13d..3477573134 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -700,6 +700,39 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; break; } + + /* Allocate dummy picture for first field based I-frame */ + if (picture->type == GST_VAAPI_PICTURE_TYPE_I && + !GST_VAAPI_PICTURE_IS_FRAME(picture) && + gst_vaapi_dpb_size(priv->dpb) == 0) { + GstVaapiPicture *dummy_picture; + gboolean success; + + dummy_picture = GST_VAAPI_PICTURE_NEW(MPEG2, decoder); + if (!dummy_picture) { + GST_ERROR("failed to allocate dummy picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + dummy_picture->type = GST_VAAPI_PICTURE_TYPE_I; + dummy_picture->pts = GST_CLOCK_TIME_NONE; + dummy_picture->poc = -1; + dummy_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + + GST_VAAPI_PICTURE_FLAG_SET( + dummy_picture, + (GST_VAAPI_PICTURE_FLAG_SKIPPED | + GST_VAAPI_PICTURE_FLAG_REFERENCE) + ); + + success = gst_vaapi_dpb_add(priv->dpb, dummy_picture); + gst_vaapi_picture_unref(dummy_picture); + if (!success) { + GST_ERROR("failed to add dummy picture into DPB"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + GST_INFO("allocated dummy picture for first field based I-frame"); + } return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 7490c3500d41e0c96fe4d37492bba75776050ad5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Apr 2012 10:05:57 +0200 Subject: [PATCH 0668/3781] Update introduction and changelog. --- NEWS | 24 +++++++++++++++++++++++- README | 8 ++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 60eba1e68e..608ba1c7dd 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,30 @@ -gst-vaapi NEWS -- summary of changes. 2012-02-01 +gst-vaapi NEWS -- summary of changes. 2012-04-02 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora +Version 0.3.6 - 02.Apr.2012 +* Add support for decoding MPEG-2 interlaced streams +* Add support for interlaced streams with FFmpeg decoders (Holger Kaelberer) +* Add vaapipostproc element for video postprocessing (e.g. deinterlacing) +* Skip all H.264 Filler Data NALs +* Fix crashes in MPEG-4 decoder (Feng Yuan) +* Fix fallback from MPEG-2 Simple to Main profile +* Improve decoding of misformed MPEG-2 streams (+Feng Yuan) +* Avoid a hang in playbin2 for some MPEG-2 TS streams (Feng Yuan) + +Version 0.3.5 - 02.Mar.2012 +* Fix H.264 decoding when emulation prevention bytes are detected +* Skip all H.264 Access Unit (AU) NALs (Feng Yuan) +* Fix modification process of H.264 reference picture lists (Feng Yuan) +* Fix MPEG-2 stream size calculation (Sreerenj Balachandran) +* Fix MPEG-2 decoding on Intel Gen with multiple slices per MB line +* Fix crash when downloading/uploading VA images on PowerVR (Cedar Trail) +* Fix double buffer free issues with some VA drivers +* Fix crash when there is no free surface available for decoding +* Skip profiles which have no entrypoints (Halley Zhao) +* Fix minor memory leaks in plug-in elements + Version 0.3.4 - 01.Feb.2012 * Add H.264 decoder (based on codecparsers) * Add workaround for qtdemux not exposing H.263 profiles (Halley Zhao) diff --git a/README b/README index ce09558c6c..3c1e07873f 100644 --- a/README +++ b/README @@ -75,6 +75,14 @@ Hardware requirements Usage ----- + VA elements are automatically plugged into GStreamer pipelines. So, + using playbin2 should work as is. However, here are a few alternate + pipelines constructed manually. + * Play an H.264 video with an MP4 container in fullscreen mode $ gst-launch-0.10 -v filesrc location=/path/to/video.mp4 ! \ qtdemux ! vaapidecode ! vaapisink fullscreen=true + + * Play a raw MPEG-2 interlaced stream + $ gst-launch-0.10 -v filesrc location=/path/to/mpeg2.bits ! \ + mpegvideoparse ! vaapidecode ! vaapipostproc ! vaapisink From d9c57a236de30b415130fc91d8508e8b3c8bb36d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Apr 2012 12:52:54 +0200 Subject: [PATCH 0669/3781] Fix a few documentation issues. --- docs/reference/libs/libs-docs.xml.in | 4 ++ docs/reference/libs/libs-sections.txt | 66 +++++++++++++++++++ docs/reference/plugins/plugins-docs.xml.in | 1 + docs/reference/plugins/plugins-sections.txt | 14 ++++ docs/reference/plugins/plugins.types | 3 +- gst-libs/gst/vaapi/gstvaapiimage.c | 1 - .../gst/vaapi/gstvaapivideoconverter_glx.c | 12 ++-- gst/vaapi/gstvaapipostproc.c | 4 +- 8 files changed, 96 insertions(+), 9 deletions(-) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 97e19617ce..e4329662ba 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -30,6 +30,10 @@ + + + + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index d60213ac9e..afcb793837 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -488,6 +488,70 @@ GST_VAAPI_IS_DECODER_FFMPEG_CLASS GST_VAAPI_DECODER_FFMPEG_GET_CLASS +
+gstvaapidecoder_mpeg2 +GstVaapiDecoderMpeg2 +GstVaapiDecoderMpeg2 +GstVaapiDecoderMpeg2Class +gst_vaapi_decoder_mpeg2_new + +GST_VAAPI_DECODER_MPEG2 +GST_VAAPI_IS_DECODER_MPEG2 +GST_VAAPI_TYPE_DECODER_MPEG2 +gst_vaapi_decoder_mpeg2_get_type +GST_VAAPI_DECODER_MPEG2_CLASS +GST_VAAPI_IS_DECODER_MPEG2_CLASS +GST_VAAPI_DECODER_MPEG2_GET_CLASS +
+ +
+gstvaapidecoder_mpeg4 +GstVaapiDecoderMpeg4 +GstVaapiDecoderMpeg4 +GstVaapiDecoderMpeg4Class +gst_vaapi_decoder_mpeg4_new + +GST_VAAPI_DECODER_MPEG4 +GST_VAAPI_IS_DECODER_MPEG4 +GST_VAAPI_TYPE_DECODER_MPEG4 +gst_vaapi_decoder_mpeg4_get_type +GST_VAAPI_DECODER_MPEG4_CLASS +GST_VAAPI_IS_DECODER_MPEG4_CLASS +GST_VAAPI_DECODER_MPEG4_GET_CLASS +
+ +
+gstvaapidecoder_h264 +GstVaapiDecoderH264 +GstVaapiDecoderH264 +GstVaapiDecoderH264Class +gst_vaapi_decoder_h264_new + +GST_VAAPI_DECODER_H264 +GST_VAAPI_IS_DECODER_H264 +GST_VAAPI_TYPE_DECODER_H264 +gst_vaapi_decoder_h264_get_type +GST_VAAPI_DECODER_H264_CLASS +GST_VAAPI_IS_DECODER_H264_CLASS +GST_VAAPI_DECODER_H264_GET_CLASS +
+ +
+gstvaapidecoder_vc1 +GstVaapiDecoderVC1 +GstVaapiDecoderVC1 +GstVaapiDecoderVC1Class +gst_vaapi_decoder_vc1_new + +GST_VAAPI_DECODER_VC1 +GST_VAAPI_IS_DECODER_VC1 +GST_VAAPI_TYPE_DECODER_VC1 +gst_vaapi_decoder_vc1_get_type +GST_VAAPI_DECODER_VC1_CLASS +GST_VAAPI_IS_DECODER_VC1_CLASS +GST_VAAPI_DECODER_VC1_GET_CLASS +
+
gstvaapisurfaceproxy GstVaapiSurfaceProxy @@ -501,6 +565,8 @@ gst_vaapi_surface_proxy_get_surface_id gst_vaapi_surface_proxy_set_surface gst_vaapi_surface_proxy_get_timestamp gst_vaapi_surface_proxy_set_timestamp +gst_vaapi_surface_proxy_get_interlaced +gst_vaapi_surface_proxy_set_interlaced gst_vaapi_surface_proxy_get_tff gst_vaapi_surface_proxy_set_tff diff --git a/docs/reference/plugins/plugins-docs.xml.in b/docs/reference/plugins/plugins-docs.xml.in index 550355ec3c..3532a551b7 100644 --- a/docs/reference/plugins/plugins-docs.xml.in +++ b/docs/reference/plugins/plugins-docs.xml.in @@ -12,6 +12,7 @@ gst-plugins-vaapi Plugins + diff --git a/docs/reference/plugins/plugins-sections.txt b/docs/reference/plugins/plugins-sections.txt index 48cd444543..58f3fe8107 100644 --- a/docs/reference/plugins/plugins-sections.txt +++ b/docs/reference/plugins/plugins-sections.txt @@ -26,6 +26,20 @@ GST_IS_VAAPIDECODE_CLASS GST_VAAPIDECODE_GET_CLASS
+
+gstvaapipostproc +GstVaapiPostproc +GstVaapiPostproc + +GST_VAAPIPOSTPROC +GST_IS_VAAPIPOSTPROC +GST_TYPE_VAAPIPOSTPROC +gst_vaapipostproc_get_type +GST_VAAPIPOSTPROC_CLASS +GST_IS_VAAPIPOSTPROC_CLASS +GST_VAAPIPOSTPROC_GET_CLASS +
+
gstvaapiupload GstVaapiUpload diff --git a/docs/reference/plugins/plugins.types b/docs/reference/plugins/plugins.types index 72cb6a404d..41175802af 100644 --- a/docs/reference/plugins/plugins.types +++ b/docs/reference/plugins/plugins.types @@ -1,4 +1,5 @@ -gst_vaapisink_get_type gst_vaapidecode_get_type gst_vaapidownload_get_type +gst_vaapipostproc_get_type +gst_vaapisink_get_type gst_vaapiupload_get_type diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 8348b2c8fa..717d95256d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -1189,7 +1189,6 @@ gst_vaapi_image_get_buffer( * gst_vaapi_image_get_raw: * @image: a #GstVaapiImage * @dst_image: a #GstVaapiImageRaw - * @buffer: a #GstBuffer * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the * whole image * diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index 646a82fe81..106b8ea893 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -76,13 +76,15 @@ gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface *iface) { /** * gst_vaapi_video_converter_glx_new: - * @ + * @surface: the #GstSurfaceBuffer + * @type: type of the target buffer (must be "opengl") + * @dest: target of the conversion (must be GL texture id) * - * Creates an empty #GstBuffer. The caller is responsible for completing - * the initialization of the buffer with the gst_vaapi_video_converter_glx_set_*() - * functions. + * Creates an empty #GstBuffer. The caller is responsible for + * completing the initialization of the buffer with the + * gst_vaapi_video_converter_glx_set_*() functions. * - * Return value: the newly allocated #GstBuffer, or %NULL or error + * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstSurfaceConverter * gst_vaapi_video_converter_glx_new(GstSurfaceBuffer *surface, const gchar *type, diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 31a46e250c..ca9400ad4c 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -629,7 +629,7 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) element_class->change_state = gst_vaapipostproc_change_state; /** - * GstVaapiSink:deinterlace-mode: + * GstVaapiPostproc:deinterlace-mode: * * This selects whether the deinterlacing should always be applied or if * they should only be applied on content that has the "interlaced" flag @@ -646,7 +646,7 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** - * GstVaapiSink:deinterlace-method: + * GstVaapiPostproc:deinterlace-method: * * This selects the deinterlacing method to apply. */ From b819c890e7569f68aadc86250c7e8a2abba7db49 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Apr 2012 10:07:33 +0200 Subject: [PATCH 0670/3781] 0.3.6. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 81583c5fc6..1cfb9baba0 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) -m4_define([gst_vaapi_micro_version], [5]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_micro_version], [6]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From c28eef0cb2356c301b90efd7882a9e3e2829fccb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Apr 2012 13:07:34 +0200 Subject: [PATCH 0671/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 1cfb9baba0..0d0335c4a2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) -m4_define([gst_vaapi_micro_version], [6]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [7]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From c37c9ca6cfa85e249209924e6a2b405dbd9db54d Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Tue, 7 Feb 2012 15:21:05 +0100 Subject: [PATCH 0672/3781] vaapisink: recalculate render rect only if caps are negotiated. Fix gst_vaapisink_xoverlay_set_window_handle() when it is called before caps got negotiated. Besides, when a foreign window is provided by the user, so should the render rect. Signed-off-by: Gwenole Beauchesne --- NEWS | 5 ++++- gst/vaapi/gstvaapisink.c | 9 +++++++++ gst/vaapi/gstvaapisink.h | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 608ba1c7dd..292a1b73ea 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,11 @@ -gst-vaapi NEWS -- summary of changes. 2012-04-02 +gst-vaapi NEWS -- summary of changes. 2012-04-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora +Version 0.3.7 - DD.Apr.2012 +* Recalculate render rect only if caps are negotiated (Holger Kaelberer) + Version 0.3.6 - 02.Apr.2012 * Add support for decoding MPEG-2 interlaced streams * Add support for interlaced streams with FFmpeg decoders (Holger Kaelberer) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 6769be2629..6ae5f2a17d 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -240,6 +240,8 @@ gst_vaapisink_destroy(GstVaapiSink *sink) g_object_unref(sink->display); sink->display = NULL; } + + gst_caps_replace(&sink->caps, NULL); } /* Checks whether a ConfigureNotify event is in the queue */ @@ -300,6 +302,10 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) guint num, den, display_par_n, display_par_d; gboolean success; + /* Return success if caps are not set yet */ + if (!sink->caps) + return TRUE; + GST_DEBUG("ensure render rect within %ux%u bounds", width, height); gst_vaapi_display_get_pixel_aspect_ratio( @@ -459,6 +465,8 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) sink->video_par_d = video_par_d; GST_DEBUG("video pixel-aspect-ratio %d/%d", video_par_n, video_par_d); + gst_caps_replace(&sink->caps, caps); + if (!gst_vaapi_ensure_display(sink, &sink->display)) return FALSE; @@ -861,6 +869,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) { + sink->caps = NULL; sink->display = NULL; sink->window = NULL; sink->window_width = 0; diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 368a2d2b73..b7c06d8091 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -68,6 +68,7 @@ struct _GstVaapiSink { /*< private >*/ GstVideoSink parent_instance; + GstCaps *caps; GstVaapiDisplay *display; GstVaapiWindow *window; guint window_width; From bd08610e0774b223888574f41f24a1315199dc53 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Tue, 7 Feb 2012 15:23:22 +0100 Subject: [PATCH 0673/3781] vaapisink: don't resize a 'foreign' X-window. Don't forcibly resize foreign X windows. The user is responsible for their size and vaapisink shall not change this. Signed-off-by: Gwenole Beauchesne --- NEWS | 1 + gst/vaapi/gstvaapisink.c | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 292a1b73ea..a3f4ee6f5c 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora Version 0.3.7 - DD.Apr.2012 +* Don't forcibly resize user provided X windows (Holger Kaelberer) * Recalculate render rect only if caps are negotiated (Holger Kaelberer) Version 0.3.6 - 02.Apr.2012 diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 6ae5f2a17d..027fcb2446 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -471,8 +471,12 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return FALSE; gst_vaapi_display_get_size(sink->display, &display_width, &display_height); - if (sink->fullscreen || - video_width > display_width || video_height > display_height) { + if (sink->foreign_window) { + win_width = sink->window_width; + win_height = sink->window_height; + } + else if (sink->fullscreen || + video_width > display_width || video_height > display_height) { win_width = display_width; win_height = display_height; } @@ -481,8 +485,10 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) win_height = video_height; } - if (sink->window) - gst_vaapi_window_set_size(sink->window, win_width, win_height); + if (sink->window) { + if (!sink->foreign_window || sink->fullscreen) + gst_vaapi_window_set_size(sink->window, win_width, win_height); + } else { gst_vaapi_display_lock(sink->display); gst_x_overlay_prepare_xwindow_id(GST_X_OVERLAY(sink)); From 84b5fc5e5874c4c2e97f07dd1260f29a94bbf7de Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Apr 2012 14:51:06 +0200 Subject: [PATCH 0674/3781] vaapidecode: report unsupported codec profiles. Try to gracefully abort when the HW does not support the requested profile. There is no fallback unless profiles are correctly parsed and matched through caps beforehand. --- NEWS | 1 + gst/vaapi/gstvaapidecode.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index a3f4ee6f5c..f3ac4ebbfa 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora Version 0.3.7 - DD.Apr.2012 +* Fix vaapidecode to report unsupported codec profiles * Don't forcibly resize user provided X windows (Holger Kaelberer) * Recalculate render rect only if caps are negotiated (Holger Kaelberer) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 5035fcd164..6e73d3a505 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -269,7 +269,17 @@ error_decode_timeout: error_decode: { GST_DEBUG("decode error %d", status); - return GST_FLOW_UNEXPECTED; + switch (status) { + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: + ret = GST_FLOW_NOT_SUPPORTED; + break; + default: + ret = GST_FLOW_UNEXPECTED; + break; + } + return ret; } error_create_buffer: { From 9c8b85b3c7b3d2e00c876be7d8e5aca2e025b229 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Apr 2012 16:07:58 +0200 Subject: [PATCH 0675/3781] mpeg2: fix decoding of high profile streams. Allow MPEG-2 High profile streams only if the HW supports that profile or no High profile specific bits are used, and thus Main profile could be used instead. i.e. chroma_format is 4:2:0, intra_dc_precision is not set to 11 and no sequence_scalable_extension() was parsed. --- NEWS | 1 + gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 77 ++++++++++++++++++---- gst-libs/gst/vaapi/gstvaapiprofile.h | 6 ++ 3 files changed, 70 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index f3ac4ebbfa..17867ef96a 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Copyright (C) 2011 Collabora Version 0.3.7 - DD.Apr.2012 * Fix vaapidecode to report unsupported codec profiles +* Fix decoding of MPEG-2 High profile streams compatible with Main profile * Don't forcibly resize user provided X windows (Holger Kaelberer) * Recalculate render rect only if caps are negotiated (Holger Kaelberer) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 3477573134..6642b56b11 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -165,6 +165,7 @@ pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn) struct _GstVaapiDecoderMpeg2Private { GstVaapiProfile profile; + GstVaapiProfile hw_profile; guint width; guint height; guint fps_n; @@ -329,13 +330,66 @@ copy_quant_matrix(guint8 dst[64], const guint8 src[64]) memcpy(dst, src, 64); } +static const char * +get_profile_str(GstVaapiProfile profile) +{ + char *str; + + switch (profile) { + case GST_VAAPI_PROFILE_MPEG2_SIMPLE: str = "simple"; break; + case GST_VAAPI_PROFILE_MPEG2_MAIN: str = "main"; break; + case GST_VAAPI_PROFILE_MPEG2_HIGH: str = "high"; break; + default: str = ""; break; + } + return str; +} + +static GstVaapiProfile +get_profile(GstVaapiDecoderMpeg2 *decoder, GstVaapiEntrypoint entrypoint) +{ + GstVaapiDisplay * const va_display = GST_VAAPI_DECODER_DISPLAY(decoder); + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiProfile profile = priv->profile; + + do { + /* Return immediately if the exact same profile was found */ + if (gst_vaapi_display_has_decoder(va_display, profile, entrypoint)) + break; + + /* Otherwise, try to map to a higher profile */ + switch (profile) { + case GST_VAAPI_PROFILE_MPEG2_SIMPLE: + profile = GST_VAAPI_PROFILE_MPEG2_MAIN; + break; + case GST_VAAPI_PROFILE_MPEG2_MAIN: + profile = GST_VAAPI_PROFILE_MPEG2_HIGH; + break; + case GST_VAAPI_PROFILE_MPEG2_HIGH: + // Try to map to main profile if no high profile specific bits used + if (priv->profile == profile && + !priv->has_seq_scalable_ext && + (priv->has_seq_ext && priv->seq_ext.chroma_format == 1)) { + profile = GST_VAAPI_PROFILE_MPEG2_MAIN; + break; + } + // fall-through + default: + profile = GST_VAAPI_PROFILE_UNKNOWN; + break; + } + } while (profile != GST_VAAPI_PROFILE_UNKNOWN); + + if (profile != priv->profile) + GST_INFO("forced %s profile to %s profile", + get_profile_str(priv->profile), get_profile_str(profile)); + return profile; +} + static GstVaapiDecoderStatus ensure_context(GstVaapiDecoderMpeg2 *decoder) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstVaapiProfile profiles[2]; GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; - guint i, n_profiles = 0; gboolean reset_context = FALSE; if (priv->profile_changed) { @@ -343,18 +397,9 @@ ensure_context(GstVaapiDecoderMpeg2 *decoder) priv->profile_changed = FALSE; reset_context = TRUE; - profiles[n_profiles++] = priv->profile; - if (priv->profile == GST_VAAPI_PROFILE_MPEG2_SIMPLE) - profiles[n_profiles++] = GST_VAAPI_PROFILE_MPEG2_MAIN; - - 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) + priv->hw_profile = get_profile(decoder, entrypoint); + if (priv->hw_profile == GST_VAAPI_PROFILE_UNKNOWN) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - priv->profile = profiles[i]; } if (priv->size_changed) { @@ -366,7 +411,7 @@ ensure_context(GstVaapiDecoderMpeg2 *decoder) if (reset_context) { reset_context = gst_vaapi_decoder_ensure_context( GST_VAAPI_DECODER(decoder), - priv->profile, + priv->hw_profile, entrypoint, priv->width, priv->height ); @@ -522,6 +567,9 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) case GST_MPEG_VIDEO_PROFILE_MAIN: profile = GST_VAAPI_PROFILE_MPEG2_MAIN; break; + case GST_MPEG_VIDEO_PROFILE_HIGH: + profile = GST_VAAPI_PROFILE_MPEG2_HIGH; + break; default: GST_ERROR("unsupported profile %d", seq_ext->profile); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; @@ -1080,6 +1128,7 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv->height = 0; priv->fps_n = 0; priv->fps_d = 0; + priv->hw_profile = GST_VAAPI_PROFILE_UNKNOWN; priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; priv->current_picture = NULL; priv->adapter = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index c144a915b2..e16bff959a 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -65,12 +65,16 @@ enum _GstVaapiCodec { /** * GstVaapiProfile: + * @GST_VAAPI_PROFILE_UNKNOWN: + * Unknown profile, used for initializers * @GST_VAAPI_PROFILE_MPEG1: * MPEG-1 * @GST_VAAPI_PROFILE_MPEG2_SIMPLE: * MPEG-2 simple profile * @GST_VAAPI_PROFILE_MPEG2_MAIN: * MPEG-2 main profile + * @GST_VAAPI_PROFILE_MPEG2_HIGH: + * MPEG-2 high profile * @GST_VAAPI_PROFILE_MPEG4_SIMPLE: * MPEG-4 Part-2 simple profile * @GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE: @@ -95,9 +99,11 @@ enum _GstVaapiCodec { * The set of all profiles for #GstVaapiProfile. */ enum _GstVaapiProfile { + GST_VAAPI_PROFILE_UNKNOWN = 0, GST_VAAPI_PROFILE_MPEG1 = GST_VAAPI_MAKE_PROFILE(MPEG1,1), GST_VAAPI_PROFILE_MPEG2_SIMPLE = GST_VAAPI_MAKE_PROFILE(MPEG2,1), GST_VAAPI_PROFILE_MPEG2_MAIN = GST_VAAPI_MAKE_PROFILE(MPEG2,2), + GST_VAAPI_PROFILE_MPEG2_HIGH = GST_VAAPI_MAKE_PROFILE(MPEG2,3), GST_VAAPI_PROFILE_MPEG4_SIMPLE = GST_VAAPI_MAKE_PROFILE(MPEG4,1), GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE = GST_VAAPI_MAKE_PROFILE(MPEG4,2), GST_VAAPI_PROFILE_MPEG4_MAIN = GST_VAAPI_MAKE_PROFILE(MPEG4,3), From 2d36f6199ecadcf91112a8672944d493e154e1a6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Apr 2012 18:09:21 +0200 Subject: [PATCH 0676/3781] mpeg2: fix interpolation of GOP TSN from new PTS. New GOP TSN base could be mis-calculated. In particular, this fixes decoding of uruseiyatsura.vob from . --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 6642b56b11..3333c2e2ca 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -128,7 +128,8 @@ pts_sync(PTSGenerator *tsg, GstClockTime gop_pts) /* Interpolate GOP TSN from this valid PTS */ if (GST_CLOCK_TIME_IS_VALID(tsg->gop_pts)) gop_tsn = tsg->gop_tsn + gst_util_uint64_scale( - gop_pts - tsg->gop_pts, tsg->fps_n, GST_SECOND * tsg->fps_d); + gop_pts - tsg->gop_pts + pts_get_duration(tsg, 1) - 1, + tsg->fps_n, GST_SECOND * tsg->fps_d); else gop_tsn = 0; } From 49b1dca2d37f42e105ab735be5615cdaa8c35243 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Apr 2012 18:42:12 +0200 Subject: [PATCH 0677/3781] mpeg2: fix calculation of macroblock_offset. Fix decoding of streams with extra slice() information before the first macroblock(). e.g. this fixes sony-ct3.bs from conformance test. --- NEWS | 3 ++- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 9 +++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 17867ef96a..05c54caf33 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,8 @@ Copyright (C) 2011 Collabora Version 0.3.7 - DD.Apr.2012 * Fix vaapidecode to report unsupported codec profiles -* Fix decoding of MPEG-2 High profile streams compatible with Main profile +* Fix MPEG-2 decoding of streams with extra slice() information +* Fix MPEG-2 decoding of High profile streams compatible with Main profile * Don't forcibly resize user provided X windows (Holger Kaelberer) * Recalculate render rect only if caps are negotiated (Holger Kaelberer) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 3333c2e2ca..38ecb33277 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -870,7 +870,7 @@ decode_slice( guint macroblock_offset; guint8 slice_vertical_position_extension; guint8 quantiser_scale_code; - guint8 intra_slice_flag, intra_slice = 0; + guint8 intra_slice = 0; guint8 extra_bit_slice, junk8; GST_DEBUG("slice %d @ %p, %u bytes)", slice_no, buf, buf_size); @@ -896,11 +896,8 @@ decode_slice( READ_UINT8(&br, quantiser_scale_code, 5); READ_UINT8(&br, extra_bit_slice, 1); if (extra_bit_slice == 1) { - READ_UINT8(&br, intra_slice_flag, 1); - if (intra_slice_flag) { - READ_UINT8(&br, intra_slice, 1); - READ_UINT8(&br, junk8, 7); - } + READ_UINT8(&br, intra_slice, 1); + READ_UINT8(&br, junk8, 7); READ_UINT8(&br, extra_bit_slice, 1); while (extra_bit_slice == 1) { READ_UINT8(&br, junk8, 8); From 68d1b7e52512e20d1185a10ed88caae9db7cbac9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 10 Apr 2012 14:28:31 +0200 Subject: [PATCH 0678/3781] vaapidecode: fix includes when compiling for a single API. --- gst/vaapi/gstvaapidecode.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6e73d3a505..206ef2f73d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -31,10 +31,8 @@ #include "config.h" #include -#include #include #include -#include #include #if USE_VAAPI_GLX From 5d75cc4c6f95abe4b298cc2a2e59b4b0b1b6c91c Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 10 Apr 2012 13:29:10 +0200 Subject: [PATCH 0679/3781] vaapidecode: fix VA display type. Fix typo whereby plain VADisplay type was used instead of the GstVaapiDisplay wrapper. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 206ef2f73d..638a15741d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -301,7 +301,7 @@ error_commit_buffer: static gboolean gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) { - VADisplay dpy; + GstVaapiDisplay *dpy; GstStructure *structure; int version; From c350a0809d3ecb2f47f7fe6c43b319f12d1d5bdd Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 10 Feb 2012 00:21:04 +0800 Subject: [PATCH 0680/3781] codecparsers: add JPEG parser. Signed-off-by: Gwenole Beauchesne --- configure.ac | 24 + gst-libs/gst/Makefile.am | 2 +- gst-libs/gst/codecparsers/Makefile.am | 46 ++ gst-libs/gst/codecparsers/gstjpegparser.c | 625 ++++++++++++++++++++++ gst-libs/gst/codecparsers/gstjpegparser.h | 120 +++++ gst-libs/gst/vaapi/Makefile.am | 5 + 6 files changed, 821 insertions(+), 1 deletion(-) create mode 100644 gst-libs/gst/codecparsers/Makefile.am create mode 100644 gst-libs/gst/codecparsers/gstjpegparser.c create mode 100644 gst-libs/gst/codecparsers/gstjpegparser.h diff --git a/configure.ac b/configure.ac index 0d0335c4a2..d8d45636a4 100644 --- a/configure.ac +++ b/configure.ac @@ -247,6 +247,7 @@ AC_DEFINE_UNQUOTED(USE_CODEC_PARSERS, $USE_CODEC_PARSERS, [Defined to 1 if GStreamer codec parsers are used]) AM_CONDITIONAL(USE_CODEC_PARSERS, test $USE_CODEC_PARSERS -eq 1) +USE_LOCAL_CODEC_PARSERS=0 if test "$enable_codecparsers" = "yes"; then AC_CACHE_CHECK([for GstH264SliceHdr::n_emulation_prevention_bytes], ac_cv_have_gst_h264_slice_hdr_epb_count, [ @@ -264,6 +265,22 @@ AC_CACHE_CHECK([for GstH264SliceHdr::n_emulation_prevention_bytes], CFLAGS="$saved_CFLAGS" LIBS="$saved_LIBS" ]) + +AC_CACHE_CHECK([for JPEG parser], + ac_cv_have_gst_jpeg_parser, [ + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" + AC_TRY_COMPILE( + [#include ], + [GstJpegImage jpeg_image;], + [ac_cv_have_gst_jpeg_parser="yes"], + [ac_cv_have_gst_jpeg_parser="no" USE_LOCAL_CODEC_PARSERS=1] + ) + CFLAGS="$saved_CFLAGS" + LIBS="$saved_LIBS" +]) fi if test "$ac_cv_have_gst_h264_slice_hdr_epb_count" = "yes"; then @@ -271,6 +288,12 @@ if test "$ac_cv_have_gst_h264_slice_hdr_epb_count" = "yes"; then [Defined to 1 if GstH264SliceHdr::n_emulation_prevention_bytes exists.]) fi +if test "$ac_cv_have_gst_jpeg_parser" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_GST_JPEG_PARSER, 1, + [Defined to 1 if JPEG parser exists.]) +fi +AM_CONDITIONAL(USE_LOCAL_CODEC_PARSERS, test $USE_LOCAL_CODEC_PARSERS -eq 1) + dnl Check for GStreamer interfaces PKG_CHECK_MODULES([GST_INTERFACES], [gstreamer-interfaces-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED] @@ -458,6 +481,7 @@ debian.upstream/libgstvaapi-glx.install.in gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/gstutils_version.h + gst-libs/gst/codecparsers/Makefile gst-libs/gst/vaapi/Makefile pkgconfig/Makefile pkgconfig/gstreamer-vaapi-$GST_MAJORMINOR.pc:\ diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 494170c42b..68753be9ad 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = vaapi +SUBDIRS = codecparsers vaapi gen_headers = gstutils_version.h noinst_HEADERS = $(gen_headers) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am new file mode 100644 index 0000000000..f6a49a31ce --- /dev/null +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -0,0 +1,46 @@ +noinst_LTLIBRARIES = \ + libgstvaapi-codecparsers.la \ + $(NULL) + +libgstvaapi_codecparsers_cflags = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + $(GST_BASE_CFLAGS) \ + $(GST_CFLAGS) \ + $(NULL) + +libgstvaapi_codecparsers_libs = \ + $(GST_BASE_LIBS) \ + $(GST_LIBS) \ + $(NULL) + +libgstvaapi_codecparsers_source_c = \ + gstjpegparser.c \ + $(NULL) + +libgstvaapi_codecparsers_source_h = \ + gstjpegparser.h \ + $(NULL) + +libgstvaapi_codecparsers_source_priv_h = \ + $(NULL) + +libgstvaapi_codecparsers_la_SOURCES = \ + $(libgstvaapi_codecparsers_source_c) \ + $(libgstvaapi_codecparsers_source_priv_h) \ + $(NULL) + +libgstvaapi_codecparsers_la_CFLAGS = \ + $(libgstvaapi_codecparsers_cflags) \ + $(NULL) + +libgstvaapi_codecparsers_la_LIBADD = \ + $(libgstvaapi_codecparsers_libs) \ + $(NULL) + +libgstvaapi_codecparsers_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(NULL) + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c new file mode 100644 index 0000000000..2eefc8991d --- /dev/null +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -0,0 +1,625 @@ +/* + * gstjpegparser.c - JPEG parser for baseline + * + * Copyright (C) 2011 Intel Corporation + * + * 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 "gstjpegparser.h" + +#include +#include + +#ifndef GST_DISABLE_GST_DEBUG + +#define GST_CAT_DEFAULT ensure_debug_category() + +static GstDebugCategory * +ensure_debug_category (void) +{ + static gsize cat_gonce = 0; + + if (g_once_init_enter (&cat_gonce)) { + gsize cat_done; + + cat_done = (gsize) _gst_debug_category_new ("codecparsers_jpeg", 0, + "GstJpegCodecParser"); + + g_once_init_leave (&cat_gonce, cat_done); + } + + return (GstDebugCategory *) cat_gonce; +} +#else + +#define ensure_debug_category() /* NOOP */ + +#endif /* GST_DISABLE_GST_DEBUG */ + +#define DEBUG_PRINT_COMMENT 0 + +#define CHECK_FAILED(exp, ret) G_STMT_START { \ + if (!(exp)) { \ + result = ret; \ + goto wrong_state; \ + } \ + } G_STMT_END + +#define JPEG_RESULT_CHECK(result) G_STMT_START { \ + if ((result) != GST_JPEG_PARSER_OK) { \ + goto wrong_state; \ + } \ + } G_STMT_END + +#define READ_UINT8(reader, val) G_STMT_START { \ + if (!gst_byte_reader_get_uint8 ((reader), &val)) { \ + GST_WARNING ("failed to read uint8"); \ + goto failed; \ + } \ + } G_STMT_END + +#define READ_UINT16(reader, val) G_STMT_START { \ + if (!gst_byte_reader_get_uint16_be ((reader), &val)) { \ + GST_WARNING ("failed to read uint16"); \ + goto failed; \ + } \ + } G_STMT_END + +#define READ_BYTES(reader, buf, length) G_STMT_START { \ + const guint8 *vals; \ + if (!gst_byte_reader_get_data(reader, length, &vals)) { \ + GST_WARNING("failed to read bytes, size:%d", length); \ + goto failed; \ + } \ + memcpy(buf, vals, length); \ + } G_STMT_END + +/* Table B.1: marker code assignments */ +enum JPEG_MARKER +{ + GST_JPEG_SOF0 = 0xC0, /* Frame Profile, Baseline */ + GST_JPEG_SOFF = 0xCF, + GST_JPEG_DHT = 0xC4, /* Define Huffman Table */ + GST_JPEG_DAC = 0xCC, /* Define Arithmetic Coding conditioning */ + GST_JPEG_RST0 = 0xD0, /* Restart with modulo 8 */ + GST_JPEG_RST7 = 0xD7, + GST_JPEG_SOI = 0xD8, /* Start Of Image */ + GST_JPEG_EOI = 0xD9, /* End Of Image */ + GST_JPEG_SOS = 0xDA, /* Start Of Scan */ + GST_JPEG_DQT = 0xDB, /* Define Quantization Table */ + GST_JPEG_DNL = 0xDC, /* Define Num of Lines */ + GST_JPEG_DRI = 0xDD, /* Define Restart Interval */ + GST_JPEG_APP0 = 0xE0, /* Application segments */ + GST_JPEG_APPF = 0xEF, + GST_JPEG_COM = 0xFE, /* Comments */ +}; +static gboolean jpeg_parse_to_next_marker (GstByteReader * reader, + guint8 * marker); + +/* CCITT T.81, Annex K.1 Quantization tables for luminance and chrominance components */ +/* only for 8-bit per sample image*/ +static const guint8 default_quant_luma_zigzag[64] = { + 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, + 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, + 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, + 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, + 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, + 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, + 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, + 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, +}; + +static const guint8 default_quant_chroma_zigzag[64] = { + 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 +}; + +/* Table K.3: typical Huffman tables for 8-bit precision luminance and chrominance */ +static const guint8 default_dc_luma_bits[16] = { + 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 +}; + +static const guint8 default_dc_luma_vals[16] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 +}; + +static const guint8 default_dc_chroma_bits[16] = { + 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 +}; + +static const guint8 default_dc_chroma_vals[16] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 +}; + +static const guint8 default_ac_luma_bits[16] = { + 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125 +}; + +static const guint8 default_ac_luma_vals[256] = { + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa +}; + +static const guint8 default_ac_chroma_bits[16] = { + 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119 +}; + +static const guint8 default_ac_chroma_vals[256] = { + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa +}; + +static gboolean +jpeg_parse_to_next_marker (GstByteReader * reader, guint8 * marker) +{ + guint8 value; + + while (gst_byte_reader_get_uint8 (reader, &value)) { + if (value != 0xFF) + continue; + while (value == 0xFF) { + READ_UINT8 (reader, value); + } + if (value == 0x00) + continue; + *marker = value; + return TRUE; + } + +failed: + return FALSE; +} + +static GstJpegParserResult +jpeg_parse_frame (GstJpegImage * image, const guint8 * buf, guint32 length) +{ + GstByteReader bytes_reader = GST_BYTE_READER_INIT (buf, length); + GstJpegParserResult result = GST_JPEG_PARSER_OK; + guint8 val; + u_int i; + + g_assert (image && buf && length); + READ_UINT8 (&bytes_reader, image->sample_precision); + READ_UINT16 (&bytes_reader, image->height); + READ_UINT16 (&bytes_reader, image->width); + READ_UINT8 (&bytes_reader, image->num_components); + CHECK_FAILED (image->num_components <= GST_JPEG_MAX_COMPONENTS, + GST_JPEG_PARSER_FRAME_ERROR); + for (i = 0; i < image->num_components; i++) { + READ_UINT8 (&bytes_reader, image->components[i].identifier); + READ_UINT8 (&bytes_reader, val); + image->components[i].horizontal_factor = (val >> 4) & 0x0F; + image->components[i].vertical_factor = (val & 0x0F); + READ_UINT8 (&bytes_reader, image->components[i].quant_table_selector); + CHECK_FAILED ((image->components[i].horizontal_factor <= 4 && + image->components[i].vertical_factor <= 4 && + image->components[i].quant_table_selector < 4), + GST_JPEG_PARSER_FRAME_ERROR); + } + return GST_JPEG_PARSER_OK; + +failed: + return GST_JPEG_PARSER_FRAME_ERROR; + +wrong_state: + return result; +} + +static GstJpegParserResult +jpeg_parse_scan (GstJpegImage * image, const guint8 * buf, guint32 length) +{ + GstByteReader bytes_reader = GST_BYTE_READER_INIT (buf, length); + GstJpegParserResult result = GST_JPEG_PARSER_OK; + guint8 val; + u_int i; + + g_assert (image && buf && length); + READ_UINT8 (&bytes_reader, image->current_scan.num_components); + CHECK_FAILED (image->current_scan.num_components <= GST_JPEG_MAX_COMPONENTS, + GST_JPEG_PARSER_SCAN_ERROR); + for (i = 0; i < image->current_scan.num_components; i++) { + READ_UINT8 (&bytes_reader, + image->current_scan.components[i].component_selector); + READ_UINT8 (&bytes_reader, val); + image->current_scan.components[i].dc_selector = (val >> 4) & 0x0F; + image->current_scan.components[i].ac_selector = val & 0x0F; + g_assert (image->current_scan.components[i].dc_selector < 4 && + image->current_scan.components[i].ac_selector < 4); + CHECK_FAILED ((image->current_scan.components[i].dc_selector < 4 && + image->current_scan.components[i].ac_selector < 4), + GST_JPEG_PARSER_SCAN_ERROR); + } + return GST_JPEG_PARSER_OK; + +failed: + return GST_JPEG_PARSER_SCAN_ERROR; + +wrong_state: + return result; +} + +static GstJpegParserResult +jpeg_parse_huffman_tables (GstJpegImage * image, const guint8 * buf, + guint32 length) +{ + GstByteReader bytes_reader = GST_BYTE_READER_INIT (buf, length); + GstJpegParserResult result = GST_JPEG_PARSER_OK; + GstJpegHuffmanTable *huf_table; + guint8 tmp_val; + gboolean is_dc; + guint8 table_index; + guint32 value_count; + u_int i; + + g_assert (image && buf && length); + while (gst_byte_reader_get_remaining (&bytes_reader)) { + READ_UINT8 (&bytes_reader, tmp_val); + is_dc = !((tmp_val >> 4) & 0x0F); + table_index = (tmp_val & 0x0F); + CHECK_FAILED (table_index < GST_JPEG_MAX_COMPONENTS, + GST_JPEG_PARSER_HUFFMAN_ERROR); + if (is_dc) { + huf_table = &image->dc_huf_tables[table_index]; + } else { + huf_table = &image->ac_huf_tables[table_index]; + } + READ_BYTES (&bytes_reader, huf_table->huf_bits, 16); + value_count = 0; + for (i = 0; i < 16; i++) + value_count += huf_table->huf_bits[i]; + READ_BYTES (&bytes_reader, huf_table->huf_values, value_count); + } + return GST_JPEG_PARSER_OK; + +failed: + return GST_JPEG_PARSER_HUFFMAN_ERROR; + +wrong_state: + return result; +} + +static GstJpegParserResult +jpeg_parse_quantization_table (GstJpegImage * image, const guint8 * buf, + guint32 length) +{ + GstByteReader bytes_reader = GST_BYTE_READER_INIT (buf, length); + GstJpegParserResult result = GST_JPEG_PARSER_OK; + GstJpegQuantTable *quant_table; + guint8 val; + guint8 table_index; + + g_assert (image && buf && length); + while (gst_byte_reader_get_remaining (&bytes_reader)) { + READ_UINT8 (&bytes_reader, val); + table_index = (val & 0x0f); + CHECK_FAILED (table_index < GST_JPEG_MAX_COMPONENTS, + GST_JPEG_PARSER_QUANT_ERROR); + quant_table = &(image->quant_tables[table_index]); + quant_table->quant_precision = ((val >> 4) & 0x0f); + if (!quant_table->quant_precision) { /* 8-bit values */ + READ_BYTES (&bytes_reader, quant_table->quant_table, 64); + } else { /* 16-bit values */ + READ_BYTES (&bytes_reader, quant_table->quant_table, 128); + } + } + return GST_JPEG_PARSER_OK; + +failed: + return GST_JPEG_PARSER_QUANT_ERROR; + +wrong_state: + return result; +} + +static GstJpegParserResult +jpeg_parse_restart_interval (GstJpegImage * image, const guint8 * buf, + guint32 length) +{ + GstByteReader bytes_reader = GST_BYTE_READER_INIT (buf, length); + guint16 interval; + + g_assert (image && buf && length); + READ_UINT16 (&bytes_reader, interval); + image->restart_interval = interval; + return GST_JPEG_PARSER_OK; + +failed: + return GST_JPEG_PARSER_QUANT_ERROR; +} + +static GstJpegParserResult +jpeg_parse_comments (GstJpegImage * image, const guint8 * buf, guint32 length) +{ + g_assert (image); +#if DEBUG_PRINT_COMMENT + char *comments = (char *) g_malloc0 (length + 1); + memcpy (comments, buf, length); + comments[length] = '\0'; + GST_DEBUG ("jpeg comments:%s\n", comments); + g_free (comments); +#endif + return GST_JPEG_PARSER_OK; +} + +static void +jpeg_set_default_huffman_tables (GstJpegImage * image) +{ + /* luma */ + memcpy (image->dc_huf_tables[0].huf_bits, default_dc_luma_bits, 16); + memcpy (image->dc_huf_tables[0].huf_values, default_dc_luma_vals, 16); + memcpy (image->ac_huf_tables[0].huf_bits, default_ac_luma_bits, 16); + memcpy (image->ac_huf_tables[0].huf_values, default_ac_luma_vals, 256); + + /* chroma */ + memcpy (image->dc_huf_tables[1].huf_bits, default_dc_chroma_bits, 16); + memcpy (image->dc_huf_tables[1].huf_values, default_dc_chroma_vals, 16); + memcpy (image->ac_huf_tables[1].huf_bits, default_ac_chroma_bits, 16); + memcpy (image->ac_huf_tables[1].huf_values, default_ac_chroma_vals, 256); +} + +static void +jpeg_set_default_quantization_tables (GstJpegImage * image) +{ + /* luma */ + image->quant_tables[0].quant_precision = 0; + memcpy (image->quant_tables[0].quant_table, default_quant_luma_zigzag, 64); + + /* chroma */ + image->quant_tables[1].quant_precision = 0; + memcpy (image->quant_tables[1].quant_table, default_quant_chroma_zigzag, 64); +} + +GstJpegParserResult +gst_jpeg_parse_image (GstJpegImage * image, const guint8 * buf, guint32 size) +{ + GstByteReader bytes_reader; + GstJpegParserResult result = GST_JPEG_PARSER_OK; + guint8 marker; + guint16 header_length; + const guint8 *header_buf; + gboolean first_scan_reached = FALSE; + gboolean has_huffman_tables = FALSE, has_quant_tables = FALSE; + + g_assert (image && buf && size); + memset (image, 0, sizeof (GstJpegImage)); + gst_byte_reader_init (&bytes_reader, buf, size); + + /* read SOI */ + CHECK_FAILED (jpeg_parse_to_next_marker (&bytes_reader, &marker) + && GST_JPEG_SOI == marker, GST_JPEG_PARSER_NOT_JPEG); + image->jpeg_begin = buf + gst_byte_reader_get_pos (&bytes_reader) - 2; + image->jpeg_end = buf + size; + + while (jpeg_parse_to_next_marker (&bytes_reader, &marker)) { + if (marker >= GST_JPEG_SOF0 && marker <= GST_JPEG_SOFF + && marker != GST_JPEG_DHT && marker != GST_JPEG_DAC) { + g_assert (marker == GST_JPEG_SOF0); + if (marker > GST_JPEG_SOF0) { + GST_WARNING ("codecparser_jpeg cannot support this image type:%02x", + marker); + result = GST_JPEG_PARSER_UNSUPPORTED_PROFILE; + goto wrong_state; + } + image->frame_type = marker; + marker = GST_JPEG_SOF0; + } + if (marker == GST_JPEG_EOI) { + image->jpeg_end = buf + gst_byte_reader_get_pos (&bytes_reader); + break; + } else { + READ_UINT16 (&bytes_reader, header_length); + CHECK_FAILED ((header_length >= 2 && + gst_byte_reader_get_remaining (&bytes_reader) + 2 >= + header_length), GST_JPEG_PARSER_BROKEN_DATA); + header_length -= 2; + header_buf = buf + gst_byte_reader_get_pos (&bytes_reader); + } + + switch (marker) { + case GST_JPEG_SOF0: + JPEG_RESULT_CHECK (result = + jpeg_parse_frame (image, header_buf, header_length)); + break; + case GST_JPEG_DHT: + JPEG_RESULT_CHECK (result = + jpeg_parse_huffman_tables (image, header_buf, header_length)); + has_huffman_tables = TRUE; + break; + case GST_JPEG_SOS: + JPEG_RESULT_CHECK (result = + jpeg_parse_scan (image, header_buf, header_length)); + first_scan_reached = TRUE; /* read to first scan stop */ + break; + case GST_JPEG_DQT: + JPEG_RESULT_CHECK (result = + jpeg_parse_quantization_table (image, header_buf, header_length)); + has_quant_tables = TRUE; + break; + case GST_JPEG_DRI: + JPEG_RESULT_CHECK (result = + jpeg_parse_restart_interval (image, header_buf, header_length)); + break; + case GST_JPEG_COM: + JPEG_RESULT_CHECK (result = + jpeg_parse_comments (image, header_buf, header_length)); + break; + case GST_JPEG_DAC: + case GST_JPEG_DNL: + default: + /* Unsupported markers, skip them */ + break; + } + gst_byte_reader_skip (&bytes_reader, header_length); + if (first_scan_reached) + break; + } + + image->jpeg_pos = buf + gst_byte_reader_get_pos (&bytes_reader); + if (!first_scan_reached) { + GST_WARNING ("jpeg no scan was found\n"); + return GST_JPEG_PARSER_NO_SCAN_FOUND; + } + if (!has_huffman_tables) + jpeg_set_default_huffman_tables (image); + if (!has_quant_tables) + jpeg_set_default_quantization_tables (image); + + return GST_JPEG_PARSER_OK; + +failed: + GST_WARNING ("jpeg parsing read broken data"); + return GST_JPEG_PARSER_BROKEN_DATA; + +wrong_state: + return result; + +} + +GstJpegParserResult +gst_jpeg_parse_next_scan (GstJpegImage * image) +{ + GstByteReader bytes_reader; + GstJpegParserResult result = GST_JPEG_PARSER_OK; + guint8 marker; + guint16 header_length; + const guint8 *header_buf; + gboolean scan_found = FALSE; + + g_assert (image->jpeg_begin && image->jpeg_end && image->jpeg_pos); + if (!image->jpeg_begin || !image->jpeg_end || !image->jpeg_pos + || image->jpeg_pos >= image->jpeg_end) + return GST_JPEG_PARSER_NO_SCAN_FOUND; + gst_byte_reader_init (&bytes_reader, image->jpeg_pos, + image->jpeg_end - image->jpeg_pos); + + while (jpeg_parse_to_next_marker (&bytes_reader, &marker)) { + if (marker == GST_JPEG_EOI) { + image->jpeg_end = + image->jpeg_pos + gst_byte_reader_get_pos (&bytes_reader); + break; + } + if (marker != GST_JPEG_SOS) + continue; + READ_UINT16 (&bytes_reader, header_length); + CHECK_FAILED ((header_length >= 2 && + gst_byte_reader_get_remaining (&bytes_reader) + 2 >= header_length), + GST_JPEG_PARSER_SCAN_ERROR); + header_length -= 2; + header_buf = image->jpeg_pos + gst_byte_reader_get_pos (&bytes_reader); + JPEG_RESULT_CHECK (result = + jpeg_parse_scan (image, header_buf, header_length)); + scan_found = TRUE; + break; + } + image->jpeg_pos += gst_byte_reader_get_pos (&bytes_reader); + if (!scan_found) + return GST_JPEG_PARSER_NO_SCAN_FOUND; + + return GST_JPEG_PARSER_OK; +failed: + GST_WARNING ("jpeg parsing read broken data"); + return GST_JPEG_PARSER_BROKEN_DATA; + +wrong_state: + return result; +} + +guint32 +gst_jpeg_skip_to_scan_end (GstJpegImage * image) +{ + GstByteReader bytes_reader; + guint8 marker; + guint32 skip_bytes = 0; + gboolean next_marker_found = FALSE; + + g_assert (image->jpeg_begin && image->jpeg_end && image->jpeg_pos); + if (!image->jpeg_begin || !image->jpeg_end || !image->jpeg_pos + || image->jpeg_pos >= image->jpeg_end) + return 0; + gst_byte_reader_init (&bytes_reader, image->jpeg_pos, + image->jpeg_end - image->jpeg_pos); + while (jpeg_parse_to_next_marker (&bytes_reader, &marker)) { + if (marker >= GST_JPEG_RST0 && marker <= GST_JPEG_RST7) + continue; + next_marker_found = TRUE; + break; + } + if (next_marker_found) + skip_bytes = gst_byte_reader_get_pos (&bytes_reader) - 2; + else + skip_bytes = gst_byte_reader_get_pos (&bytes_reader); + image->jpeg_pos += skip_bytes; + return skip_bytes; +} + +const guint8 * +gst_jpeg_get_position (GstJpegImage * image) +{ + return image->jpeg_pos; +} + +guint32 +gst_jpeg_get_left_size (GstJpegImage * image) +{ + if (image->jpeg_end > image->jpeg_pos) + return image->jpeg_end - image->jpeg_pos; + return 0; +} diff --git a/gst-libs/gst/codecparsers/gstjpegparser.h b/gst-libs/gst/codecparsers/gstjpegparser.h new file mode 100644 index 0000000000..43bedb155a --- /dev/null +++ b/gst-libs/gst/codecparsers/gstjpegparser.h @@ -0,0 +1,120 @@ +/* + * gstjpegparser.h - JPEG parser for baseline + * + * Copyright (C) 2011 Intel Corporation + * + * 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_JPEG_PARSER_H +#define GST_JPEG_PARSER_H + +#ifndef GST_USE_UNSTABLE_API +# warning "The JPEG parsing library is unstable API and may change in future." +# warning "You can define GST_USE_UNSTABLE_API to avoid this warning." +#endif + +#include + +G_BEGIN_DECLS + +#define GST_JPEG_MAX_COMPONENTS 4 +#define GST_JPEG_QUANT_ELEMENTS_SIZE 64 + +typedef struct _GstJpegQuantTable GstJpegQuantTable; +typedef struct _GstJpegHuffmanTable GstJpegHuffmanTable; +typedef struct _GstJpegScan GstJpegScan; +typedef struct _GstJpegImage GstJpegImage; + +typedef enum +{ + GST_JPEG_PARSER_OK, + GST_JPEG_PARSER_UNSUPPORTED_PROFILE, + GST_JPEG_PARSER_NOT_JPEG, + GST_JPEG_PARSER_BROKEN_DATA, + GST_JPEG_PARSER_NO_SCAN_FOUND, + GST_JPEG_PARSER_FRAME_ERROR, + GST_JPEG_PARSER_SCAN_ERROR, + GST_JPEG_PARSER_HUFFMAN_ERROR, + GST_JPEG_PARSER_QUANT_ERROR, + GST_JPEG_PARSER_DRI_ERROR, +} GstJpegParserResult; + +struct _GstJpegQuantTable +{ + guint8 quant_precision; /* 4 bits; Value 0 indicates 8bit Q values; value 1 indicates 16bit Q values */ + guint8 quant_table[GST_JPEG_QUANT_ELEMENTS_SIZE * 2]; /* 64*8(or 64*16) bits, zigzag mode */ +}; + +struct _GstJpegHuffmanTable +{ + guint8 huf_bits[16]; + guint8 huf_values[256]; +}; + +struct _GstJpegScan +{ + guint8 num_components; /* 8 bits */ + struct + { + guint8 component_selector; /* 8 bits */ + guint8 dc_selector; /* 4 bits */ + guint8 ac_selector; /* 4 bits */ + } components[GST_JPEG_MAX_COMPONENTS]; +}; + +struct _GstJpegImage +{ + guint32 frame_type; + guint8 sample_precision; /* 8 bits */ + guint16 height; /* 16 bits */ + guint16 width; /* 16 bits */ + guint8 num_components; /* 8 bits */ + struct + { + guint8 identifier; /* 8 bits */ + guint8 horizontal_factor; /* 4 bits */ + guint8 vertical_factor; /* 4 bits */ + guint8 quant_table_selector; /* 8 bits */ + } components[GST_JPEG_MAX_COMPONENTS]; + + GstJpegQuantTable quant_tables[GST_JPEG_MAX_COMPONENTS]; + GstJpegHuffmanTable dc_huf_tables[GST_JPEG_MAX_COMPONENTS]; + GstJpegHuffmanTable ac_huf_tables[GST_JPEG_MAX_COMPONENTS]; + guint32 restart_interval; /* DRI */ + + GstJpegScan current_scan; + + const guint8 *jpeg_pos; + const guint8 *jpeg_begin; + const guint8 *jpeg_end; +}; + +/* parse to first scan and stop there */ +GstJpegParserResult gst_jpeg_parse_image (GstJpegImage * image, + const guint8 * buf, + guint32 size); + +GstJpegParserResult gst_jpeg_parse_next_scan (GstJpegImage * image); + +/* return skip bytes length */ +guint32 gst_jpeg_skip_to_scan_end (GstJpegImage * image); +const guint8 * gst_jpeg_get_position (GstJpegImage * image); +guint32 gst_jpeg_get_left_size (GstJpegImage * image); + +G_END_DECLS + +#endif /* GST_JPEG_PARSER_H */ diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index e965214ded..d4e3397b30 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -170,6 +170,11 @@ libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS) libgstvaapi_libs += $(GST_CODEC_PARSERS_LIBS) endif +if USE_LOCAL_CODEC_PARSERS +libgstvaapi_libs += \ + $(top_builddir)/gst-libs/gst/codecparsers/libgstvaapi-codecparsers.la +endif + libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_source_c) \ $(libgstvaapi_source_priv_h) \ From 75e8a7d6f84e24275eaba168fb61ada0dc98c844 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 10 Feb 2012 00:21:04 +0800 Subject: [PATCH 0681/3781] Add initial JPEG decoder. Signed-off-by: Gwenole Beauchesne --- configure.ac | 26 + gst-libs/gst/vaapi/Makefile.am | 5 + gst-libs/gst/vaapi/gstvaapicodec_objects.c | 59 +++ gst-libs/gst/vaapi/gstvaapicodec_objects.h | 72 +++ gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 531 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h | 88 +++ gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 13 + gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 1 + gst-libs/gst/vaapi/gstvaapiprofile.c | 6 + gst-libs/gst/vaapi/gstvaapiprofile.h | 2 + gst/vaapi/gstvaapidecode.c | 6 + 11 files changed, 809 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h diff --git a/configure.ac b/configure.ac index d8d45636a4..4d17ab7ea7 100644 --- a/configure.ac +++ b/configure.ac @@ -404,6 +404,32 @@ AC_SUBST(LIBVA_GLX_PKGNAME) AC_SUBST(LIBVA_EXTRA_CFLAGS) AC_SUBST(LIBVA_EXTRA_LIBS) +dnl Check for JPEG decoding API (0.33+) +USE_JPEG_DECODER=0 +if test "$enable_codecparsers" = "yes"; then +AC_CACHE_CHECK([for JPEG decoding API], + ac_cv_have_jpeg_decoding_api, [ + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$CFLAGS $LIBVA_LIBS" + AC_TRY_COMPILE( + [#include ], + [VAPictureParameterBufferJPEG pic_param; + VASliceParameterBufferJPEG slice_param; + VAIQMatrixBufferJPEG iq_matrix;], + [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=1], + [ac_cv_have_jpeg_decoding_api="no"] + ) + CFLAGS="$saved_CFLAGS" + LIBS="$saved_LIBS" +]) +fi + +AC_DEFINE_UNQUOTED(USE_JPEG_DECODER, $USE_JPEG_DECODER, + [Defined to 1 if JPEG decoder is used]) +AM_CONDITIONAL(USE_JPEG_DECODER, test $USE_JPEG_DECODER -eq 1) + dnl Check for OpenGL support to vaapisink if test "$enable_vaapisink_glx:$USE_GLX" = "yes:1"; then USE_VAAPISINK_GLX=1 diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index d4e3397b30..394e52a772 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -168,6 +168,11 @@ libgstvaapi_source_priv_h += \ $(NULL) libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS) libgstvaapi_libs += $(GST_CODEC_PARSERS_LIBS) + +if USE_JPEG_DECODER +libgstvaapi_source_c += gstvaapidecoder_jpeg.c +libgstvaapi_source_h += gstvaapidecoder_jpeg.h +endif endif if USE_LOCAL_CODEC_PARSERS diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index fd4822da58..63ba30ef86 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -243,3 +243,62 @@ gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size) return NULL; return GST_VAAPI_BITPLANE_CAST(object); } + +/* ------------------------------------------------------------------------- */ +/* --- JPEG Huffman Tables --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiHuffmanTable, + gst_vaapi_huffman_table, + GST_VAAPI_TYPE_CODEC_OBJECT) + +static 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; +} + +static gboolean +gst_vaapi_huffman_table_create( + GstVaapiHuffmanTable *huf_table, + const GstVaapiCodecObjectConstructorArgs *args +) +{ + 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); +} + +static void +gst_vaapi_huffman_table_init(GstVaapiHuffmanTable *huf_table) +{ + huf_table->param = NULL; + huf_table->param_id = VA_INVALID_ID; +} + +GstVaapiHuffmanTable * +gst_vaapi_huffman_table_new( + GstVaapiDecoder *decoder, + guint8 *data, + guint data_size +) +{ + GstVaapiCodecObject *object; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + object = gst_vaapi_codec_object_new( + GST_VAAPI_TYPE_HUFFMAN_TABLE, + GST_VAAPI_CODEC_BASE(decoder), + data, data_size, + NULL, 0 + ); + if (!object) + return NULL; + return GST_VAAPI_HUFFMAN_TABLE_CAST(object); +} diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index f379f02608..8fb0c15ccb 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -35,6 +35,8 @@ typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix; typedef struct _GstVaapiIqMatrixClass GstVaapiIqMatrixClass; typedef struct _GstVaapiBitPlane GstVaapiBitPlane; typedef struct _GstVaapiBitPlaneClass GstVaapiBitPlaneClass; +typedef struct _GstVaapiHuffmanTable GstVaapiHuffmanTable; +typedef struct _GstVaapiHuffmanTableClass GstVaapiHuffmanTableClass; /* ------------------------------------------------------------------------- */ /* --- Base Codec Object --- */ @@ -256,6 +258,72 @@ GstVaapiBitPlane * gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size) attribute_hidden; +/* ------------------------------------------------------------------------- */ +/* --- JPEG Huffman Tables --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_TYPE_HUFFMAN_TABLE \ + (gst_vaapi_huffman_table_get_type()) + +#define GST_VAAPI_HUFFMAN_TABLE_CAST(obj) \ + ((GstVaapiHuffmanTable *)(obj)) + +#define GST_VAAPI_HUFFMAN_TABLE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_HUFFMAN_TABLE, \ + GstVaapiHuffmanTable)) + +#define GST_VAAPI_HUFFMAN_TABLE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_HUFFMAN_TABLE, \ + GstVaapiHuffmanTableClass)) + +#define GST_VAAPI_IS_HUFFMAN_TABLE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_HUFFMAN_TABLE)) + +#define GST_VAAPI_IS_HUFFMAN_TABLE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_HUFFMAN_TABLE)) + +#define GST_VAAPI_HUFFMAN_TABLE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_HUFFMAN_TABLE, \ + GstVaapiHuffmanTableClass)) + +/** + * GstVaapiHuffmanTable: + * + * A #GstVaapiCodecObject holding huffman table. + */ +struct _GstVaapiHuffmanTable { + /*< private >*/ + GstVaapiCodecObject parent_instance; + VABufferID param_id; + + /*< public >*/ + gpointer param; +}; + +/** + * GstVaapiHuffmanTableClass: + * + * The #GstVaapiHuffmanTable base class. + */ +struct _GstVaapiHuffmanTableClass { + /*< private >*/ + GstVaapiCodecObjectClass parent_class; +}; + +GType +gst_vaapi_huffman_table_get_type(void) + attribute_hidden; + +GstVaapiHuffmanTable * +gst_vaapi_huffman_table_new( + GstVaapiDecoder *decoder, + guint8 *data, + guint data_size +) attribute_hidden; + /* ------------------------------------------------------------------------- */ /* --- Helpers to create codec-dependent objects --- */ /* ------------------------------------------------------------------------- */ @@ -318,6 +386,10 @@ prefix##_class_init(type##Class *klass) \ #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(VAHuffmanTableBuffer##codec)) G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c new file mode 100644 index 0000000000..91c4255e1c --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -0,0 +1,531 @@ +/* + * gstvaapidecoder_jpeg.c - JPEG decoder + * + * Copyright (C) 2011-2012 Intel Corporation + * + * 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 +#include +#include "gstvaapidecoder_jpeg.h" +#include "gstvaapidecoder_objects.h" +#include "gstvaapidecoder_priv.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapiobject_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiDecoderJpeg, + gst_vaapi_decoder_jpeg, + GST_VAAPI_TYPE_DECODER); + +#define GST_VAAPI_DECODER_JPEG_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DECODER_JPEG, \ + GstVaapiDecoderJpegPrivate)) + +struct _GstVaapiDecoderJpegPrivate { + GstVaapiProfile profile; + guint width; + guint height; + GstVaapiPicture *current_picture; + guint is_opened : 1; + guint profile_changed : 1; + guint is_constructed : 1; +}; + + +static GstVaapiDecoderStatus +get_status(GstJpegParserResult result) +{ + GstVaapiDecoderStatus status; + + switch (result) { + case GST_JPEG_PARSER_OK: + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + case GST_JPEG_PARSER_FRAME_ERROR: + case GST_JPEG_PARSER_SCAN_ERROR: + case GST_JPEG_PARSER_HUFFMAN_ERROR: + case GST_JPEG_PARSER_QUANT_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_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->is_constructed = FALSE; +} + +static gboolean +gst_vaapi_decoder_jpeg_open(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) +{ + gst_vaapi_decoder_jpeg_close(decoder); + + return TRUE; +} + +static void +gst_vaapi_decoder_jpeg_destroy(GstVaapiDecoderJpeg *decoder) +{ + gst_vaapi_decoder_jpeg_close(decoder); +} + +static gboolean +gst_vaapi_decoder_jpeg_create(GstVaapiDecoderJpeg *decoder) +{ + if (!GST_VAAPI_DECODER_CODEC(decoder)) + return FALSE; + return TRUE; +} + +static GstVaapiDecoderStatus +ensure_context(GstVaapiDecoderJpeg *decoder) +{ + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + 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 (reset_context) { + reset_context = gst_vaapi_decoder_ensure_context( + GST_VAAPI_DECODER(decoder), + priv->profile, + entrypoint, + priv->width, priv->height + ); + if (!reset_context) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static inline GstVaapiDecoderStatus +decode_current_picture(GstVaapiDecoderJpeg *decoder) +{ + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiPicture * const picture = priv->current_picture; + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (picture) { + if (!gst_vaapi_picture_decode(picture)) + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + else if (!gst_vaapi_picture_output(picture)) + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + gst_vaapi_picture_replace(&priv->current_picture, NULL); + } + return status; +} + +static gboolean +fill_picture( + GstVaapiDecoderJpeg *decoder, + GstVaapiPicture *picture, + GstJpegImage *jpeg_image +) +{ + VAPictureParameterBufferJPEG *pic_param = picture->param; + guint i; + + g_assert(pic_param); + + memset(pic_param, 0, sizeof(VAPictureParameterBufferJPEG)); + pic_param->type = jpeg_image->frame_type; + pic_param->sample_precision = jpeg_image->sample_precision; + pic_param->image_width = jpeg_image->width; + pic_param->image_height = jpeg_image->height; + + /* XXX: ROI + rotation */ + + pic_param->num_components = jpeg_image->num_components; + for (i = 0; i < pic_param->num_components; i++) { + pic_param->components[i].component_id = + jpeg_image->components[i].identifier; + pic_param->components[i].h_sampling_factor = + jpeg_image->components[i].horizontal_factor; + pic_param->components[i].v_sampling_factor = + jpeg_image->components[i].vertical_factor; + pic_param->components[i].quantiser_table_selector = + jpeg_image->components[i].quant_table_selector; + } + return TRUE; +} + +static gboolean +fill_quantization_table( + GstVaapiDecoderJpeg *decoder, + GstVaapiPicture *picture, + GstJpegImage *jpeg_image +) +{ + VAIQMatrixBufferJPEG *iq_matrix; + int i = 0; + + picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(JPEG, decoder); + g_assert(picture->iq_matrix); + iq_matrix = picture->iq_matrix->param; + memset(iq_matrix, 0, sizeof(VAIQMatrixBufferJPEG)); + for (i = 0; i < GST_JPEG_MAX_COMPONENTS; i++) { + iq_matrix->precision[i] = jpeg_image->quant_tables[i].quant_precision; + if (iq_matrix->precision[i] == 0) /* 8-bit values*/ + memcpy(iq_matrix->quantiser_matrix[i], jpeg_image->quant_tables[i].quant_table, 64); + else + memcpy(iq_matrix->quantiser_matrix[i], jpeg_image->quant_tables[i].quant_table, 128); + } + return TRUE; +} + +static gboolean +fill_huffman_table( + GstVaapiDecoderJpeg *decoder, + GstVaapiPicture *picture, + GstJpegImage *jpeg_image +) +{ + VAHuffmanTableBufferJPEG *huffman_table; + int i; + + picture->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW(JPEG, decoder); + g_assert(picture->huf_table); + huffman_table = picture->huf_table->param; + memset(huffman_table, 0, sizeof(VAHuffmanTableBufferJPEG)); + for (i = 0; i < GST_JPEG_MAX_COMPONENTS; i++) { + memcpy(huffman_table->huffman_table[i].dc_bits, + jpeg_image->dc_huf_tables[i].huf_bits, + 16); + memcpy(huffman_table->huffman_table[i].dc_huffval, + jpeg_image->dc_huf_tables[i].huf_values, + 16); + memcpy(huffman_table->huffman_table[i].ac_bits, + jpeg_image->ac_huf_tables[i].huf_bits, + 16); + memcpy(huffman_table->huffman_table[i].ac_huffval, + jpeg_image->ac_huf_tables[i].huf_values, + 256); + } + return TRUE; +} + +static guint +get_max_horizontal_samples(GstJpegImage *jpeg) +{ + guint i, max_factor = 0; + + for (i = 0; i < jpeg->num_components; i++) { + if (jpeg->components[i].horizontal_factor > max_factor) + max_factor = jpeg->components[i].horizontal_factor; + } + return max_factor; +} + +static guint +get_max_vertical_samples(GstJpegImage *jpeg) +{ + guint i, max_factor = 0; + + for (i = 0; i < jpeg->num_components; i++) { + if (jpeg->components[i].vertical_factor > max_factor) + max_factor = jpeg->components[i].vertical_factor; + } + return max_factor; +} + +static gboolean +fill_slices( + GstVaapiDecoderJpeg *decoder, + GstVaapiPicture *picture, + GstJpegImage *jpeg_image +) +{ + VASliceParameterBufferJPEG *slice_param; + GstVaapiSlice *gst_slice; + int i; + const guint8 *sos_src; + guint32 sos_length; + guint total_h_samples, total_v_samples; + + while (gst_jpeg_get_left_size(jpeg_image)) { + sos_src = gst_jpeg_get_position(jpeg_image); + sos_length = gst_jpeg_skip_to_scan_end(jpeg_image); + if (!sos_length) + break; + gst_slice = GST_VAAPI_SLICE_NEW(JPEG, decoder, sos_src, sos_length); + slice_param = gst_slice->param; + slice_param->num_components = jpeg_image->current_scan.num_components; + for (i = 0; i < slice_param->num_components; i++) { + slice_param->components[i].component_id = jpeg_image->current_scan.components[i].component_selector; + slice_param->components[i].dc_selector = jpeg_image->current_scan.components[i].dc_selector; + slice_param->components[i].ac_selector = jpeg_image->current_scan.components[i].ac_selector; + } + slice_param->restart_interval = jpeg_image->restart_interval; + + if (jpeg_image->current_scan.num_components == 1) { /*non-interleaved*/ + slice_param->slice_horizontal_position = 0; + slice_param->slice_vertical_position = 0; + /* Y mcu numbers*/ + if (slice_param->components[0].component_id == jpeg_image->components[0].identifier) { + slice_param->num_mcus = (jpeg_image->width/8)*(jpeg_image->height/8); + } else { /*Cr, Cb mcu numbers*/ + slice_param->num_mcus = (jpeg_image->width/16)*(jpeg_image->height/16); + } + } else { /* interleaved */ + slice_param->slice_horizontal_position = 0; + slice_param->slice_vertical_position = 0; + total_v_samples = get_max_vertical_samples(jpeg_image); + total_h_samples = get_max_horizontal_samples(jpeg_image); + slice_param->num_mcus = ((jpeg_image->width + total_h_samples*8 - 1)/(total_h_samples*8)) * + ((jpeg_image->height + total_v_samples*8 -1)/(total_v_samples*8)); + } + + gst_vaapi_picture_add_slice(picture, gst_slice); + if (!gst_jpeg_parse_next_scan(jpeg_image)) { + break; + } + } + + if (picture->slices && picture->slices->len) + return TRUE; + return FALSE; +} + +static GstVaapiDecoderStatus +decode_picture( + GstVaapiDecoderJpeg *decoder, + guchar *buf, + guint buf_size, + GstClockTime pts +) +{ + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiPicture *picture = NULL; + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; + GstJpegImage jpeg_image; + GstJpegParserResult result; + + /* parse jpeg */ + memset(&jpeg_image, 0, sizeof(jpeg_image)); + result = gst_jpeg_parse_image(&jpeg_image, buf, buf_size); + if (result != GST_JPEG_PARSER_OK) { + GST_ERROR("failed to parse image"); + return get_status(result); + } + + /* set info to va parameters in current picture*/ + priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; + priv->height = jpeg_image.height; + priv->width = jpeg_image.width; + + status = ensure_context(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_ERROR("failed to reset context"); + return status; + } + + picture = GST_VAAPI_PICTURE_NEW(JPEG, 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, &jpeg_image)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + if (!fill_quantization_table(decoder, picture, &jpeg_image)) { + GST_ERROR("failed to fill in quantization table"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!fill_huffman_table(decoder, picture, &jpeg_image)) { + GST_ERROR("failed to fill in huffman table"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!fill_slices(decoder, picture, &jpeg_image)) { + GST_ERROR("failed to fill in all scans"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + /* Update presentation time */ + picture->pts = pts; + return status; +} + +static GstVaapiDecoderStatus +decode_buffer(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) +{ + GstVaapiDecoderStatus status; + GstClockTime pts; + guchar *buf; + guint buf_size; + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + if (!buf && buf_size == 0) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + pts = GST_BUFFER_TIMESTAMP(buffer); + g_assert(GST_CLOCK_TIME_IS_VALID(pts)); + + status = decode_picture(decoder, buf, buf_size, pts); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + return decode_current_picture(decoder); +} + +GstVaapiDecoderStatus +gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base, GstBuffer *buffer) +{ + GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(base); + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + + if (!priv->is_opened) { + priv->is_opened = gst_vaapi_decoder_jpeg_open(decoder, buffer); + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + } + return decode_buffer(decoder, buffer); +} + +static void +gst_vaapi_decoder_jpeg_finalize(GObject *object) +{ + GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(object); + + gst_vaapi_decoder_jpeg_destroy(decoder); + + G_OBJECT_CLASS(gst_vaapi_decoder_jpeg_parent_class)->finalize(object); +} + +static void +gst_vaapi_decoder_jpeg_constructed(GObject *object) +{ + GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(object); + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GObjectClass *parent_class; + + parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_jpeg_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); + + priv->is_constructed = gst_vaapi_decoder_jpeg_create(decoder); +} + +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); + + g_type_class_add_private(klass, sizeof(GstVaapiDecoderJpegPrivate)); + + object_class->finalize = gst_vaapi_decoder_jpeg_finalize; + object_class->constructed = gst_vaapi_decoder_jpeg_constructed; + + decoder_class->decode = gst_vaapi_decoder_jpeg_decode; +} + +static void +gst_vaapi_decoder_jpeg_init(GstVaapiDecoderJpeg *decoder) +{ + GstVaapiDecoderJpegPrivate *priv; + + priv = GST_VAAPI_DECODER_JPEG_GET_PRIVATE(decoder); + decoder->priv = priv; + priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; + priv->width = 0; + priv->height = 0; + priv->current_picture = NULL; + priv->is_opened = FALSE; + priv->profile_changed = TRUE; + priv->is_constructed = FALSE; +} + +/** + * 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) +{ + GstVaapiDecoderJpeg *decoder; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + decoder = g_object_new( + GST_VAAPI_TYPE_DECODER_JPEG, + "display", display, + "caps", caps, + NULL + ); + if (!decoder->priv->is_constructed) { + g_object_unref(decoder); + return NULL; + } + return GST_VAAPI_DECODER_CAST(decoder); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h new file mode 100644 index 0000000000..68dab506fa --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h @@ -0,0 +1,88 @@ +/* + * gstvaapidecoder_jpeg.h - JPEG decoder + * + * Copyright (C) 2011-2012 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DECODER_JPEG \ + (gst_vaapi_decoder_jpeg_get_type()) + +#define GST_VAAPI_DECODER_JPEG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DECODER_JPEG, \ + GstVaapiDecoderJpeg)) + +#define GST_VAAPI_DECODER_JPEG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DECODER_JPEG, \ + GstVaapiDecoderJpegClass)) + +#define GST_VAAPI_IS_DECODER_JPEG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_JPEG)) + +#define GST_VAAPI_IS_DECODER_JPEG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_JPEG)) + +#define GST_VAAPI_DECODER_JPEG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DECODER_JPEG, \ + GstVaapiDecoderJpegClass)) + +typedef struct _GstVaapiDecoderJpeg GstVaapiDecoderJpeg; +typedef struct _GstVaapiDecoderJpegPrivate GstVaapiDecoderJpegPrivate; +typedef struct _GstVaapiDecoderJpegClass GstVaapiDecoderJpegClass; + +/** + * 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; +}; + +GType +gst_vaapi_decoder_jpeg_get_type(void); + +GstVaapiDecoder * +gst_vaapi_decoder_jpeg_new(GstVaapiDisplay *display, GstCaps *caps); + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_JPEG_H */ + diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 4725fac853..5f90fb0268 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -71,6 +71,11 @@ gst_vaapi_picture_destroy(GstVaapiPicture *picture) picture->iq_matrix = NULL; } + if (picture->huf_table) { + gst_mini_object_unref(GST_MINI_OBJECT(picture->huf_table)); + picture->huf_table = NULL; + } + if (picture->bitplane) { gst_mini_object_unref(GST_MINI_OBJECT(picture->bitplane)); picture->bitplane = NULL; @@ -179,6 +184,7 @@ gst_vaapi_picture_init(GstVaapiPicture *picture) picture->param_size = 0; picture->slices = NULL; picture->iq_matrix = NULL; + picture->huf_table = NULL; picture->bitplane = NULL; picture->pts = GST_CLOCK_TIME_NONE; picture->poc = 0; @@ -264,6 +270,7 @@ gst_vaapi_picture_decode(GstVaapiPicture *picture) { GstVaapiIqMatrix *iq_matrix; GstVaapiBitPlane *bitplane; + GstVaapiHuffmanTable *huf_table; VADisplay va_display; VAContextID va_context; VAStatus status; @@ -293,6 +300,12 @@ gst_vaapi_picture_decode(GstVaapiPicture *picture) &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; + for (i = 0; i < picture->slices->len; i++) { GstVaapiSlice * const slice = g_ptr_array_index(picture->slices, i); VABufferID va_buffers[2]; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 93d8ce27e4..56a6fde37a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -146,6 +146,7 @@ struct _GstVaapiPicture { gpointer param; GPtrArray *slices; GstVaapiIqMatrix *iq_matrix; + GstVaapiHuffmanTable *huf_table; GstVaapiBitPlane *bitplane; GstClockTime pts; gint32 poc; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 54b7abac84..f93e628a23 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -92,6 +92,9 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, "video/x-wmv, wmvversion=3, format=(fourcc)WVC1", "advanced" }, + { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline, + "image/jpeg", "baseline" + }, { 0, } }; @@ -337,6 +340,9 @@ gst_vaapi_profile_get_codec(GstVaapiProfile profile) case GST_VAAPI_PROFILE_VC1_ADVANCED: codec = GST_VAAPI_CODEC_VC1; break; + case GST_VAAPI_PROFILE_JPEG_BASELINE: + codec = GST_VAAPI_CODEC_JPEG; + break; default: codec = (guint32)profile & GST_MAKE_FOURCC(0xff,0xff,0xff,0); break; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index e16bff959a..986c9a26b4 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -50,6 +50,7 @@ enum _GstVaapiCodec { GST_VAAPI_CODEC_H264 = GST_MAKE_FOURCC('2','6','4',0), GST_VAAPI_CODEC_WMV3 = GST_MAKE_FOURCC('W','M','V',0), GST_VAAPI_CODEC_VC1 = GST_MAKE_FOURCC('V','C','1',0), + GST_VAAPI_CODEC_JPEG = GST_MAKE_FOURCC('J','P','G',0), }; /** @@ -114,6 +115,7 @@ enum _GstVaapiProfile { GST_VAAPI_PROFILE_VC1_SIMPLE = GST_VAAPI_MAKE_PROFILE(VC1,1), GST_VAAPI_PROFILE_VC1_MAIN = GST_VAAPI_MAKE_PROFILE(VC1,2), GST_VAAPI_PROFILE_VC1_ADVANCED = GST_VAAPI_MAKE_PROFILE(VC1,3), + GST_VAAPI_PROFILE_JPEG_BASELINE = GST_VAAPI_MAKE_PROFILE(JPEG,1), }; /** diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 638a15741d..751c158132 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -49,6 +49,7 @@ #endif #if USE_CODEC_PARSERS # include +# include # include # include # include @@ -83,6 +84,7 @@ static const char gst_vaapidecode_sink_caps_str[] = GST_CAPS_CODEC("video/x-h263") GST_CAPS_CODEC("video/x-h264") GST_CAPS_CODEC("video/x-wmv") + GST_CAPS_CODEC("image/jpeg") ; static const char gst_vaapidecode_src_caps_str[] = @@ -343,6 +345,10 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) gst_structure_has_name(structure, "video/x-divx") || gst_structure_has_name(structure, "video/x-xvid")) decode->decoder = gst_vaapi_decoder_mpeg4_new(dpy, caps); +#if USE_JPEG_DECODER + else if (gst_structure_has_name(structure, "image/jpeg")) + decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps); +#endif #endif } if (!decode->decoder) From 687b4828954086997f011904ef1eafde51345b12 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 12 Apr 2012 11:00:22 +0200 Subject: [PATCH 0682/3781] dpb: mpeg2: cosmetics. Define MAX_MPEG2_REFERENCES to 2 and avoid magic numbers all around. --- gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index da520c48cc..c5a5a76864 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -250,6 +250,9 @@ gst_vaapi_dpb_size(GstVaapiDpb *dpb) /* --- MPEG-2 Decoded Picture Buffer --- */ /* ------------------------------------------------------------------------- */ +/* At most two reference pictures for MPEG-2 */ +#define MAX_MPEG2_REFERENCES 2 + G_DEFINE_TYPE(GstVaapiDpbMpeg2, gst_vaapi_dpb_mpeg2, GST_VAAPI_TYPE_DPB) static gboolean @@ -268,7 +271,7 @@ gst_vaapi_dpb_mpeg2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) * - ... 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)) { + if (G_LIKELY(dpb->num_pictures == MAX_MPEG2_REFERENCES)) { index = (dpb->pictures[0]->poc > dpb->pictures[1]->poc); ref_picture = dpb->pictures[index]; if (!GST_VAAPI_PICTURE_IS_OUTPUT(ref_picture)) { @@ -302,7 +305,7 @@ gst_vaapi_dpb_mpeg2_class_init(GstVaapiDpbMpeg2Class *klass) GstVaapiDpb * gst_vaapi_dpb_mpeg2_new(void) { - return dpb_new(GST_VAAPI_TYPE_DPB_MPEG2, 2); + return dpb_new(GST_VAAPI_TYPE_DPB_MPEG2, MAX_MPEG2_REFERENCES); } void @@ -313,7 +316,8 @@ gst_vaapi_dpb_mpeg2_get_references( GstVaapiPicture **next_picture_ptr ) { - GstVaapiPicture **picture_ptr, *ref_picture, *ref_pictures[2]; + GstVaapiPicture *ref_picture, *ref_pictures[MAX_MPEG2_REFERENCES]; + GstVaapiPicture **picture_ptr; guint i, index; g_return_if_fail(GST_VAAPI_IS_DPB_MPEG2(dpb)); From 60b5c2da97b7fd33fe9227fde6b2c8b2b91e1104 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Wed, 11 Apr 2012 23:02:45 -0400 Subject: [PATCH 0683/3781] mpeg4: fix handling of temporal reference distances. TRD and TRB fields are not large enough to hold the difference of PTS expressed with nanosecond resolution. So, compute them from the original VOP info. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 33 ++++++++++++++++------ 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index ca31ebd084..bd089e2430 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -79,6 +79,12 @@ struct _GstVaapiDecoderMpeg4Private { // time base for recent I/P/S frame, // it is time base of forward reference frame for B frame GstClockTime sync_time; + + /* last non-b-frame time by resolution */ + GstClockTime last_non_b_scale_time; + GstClockTime non_b_scale_time; + GstClockTime trb; + GstClockTime trd; // temporal_reference of previous frame of svh guint8 prev_t_ref; guint is_constructed : 1; @@ -389,7 +395,7 @@ decode_gop(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) { GstVaapiDecoderMpeg4Private * const priv = decoder->priv; GstMpeg4GroupOfVOP gop; - GstClockTime pts; + GstClockTime gop_time; if (buf_size >4) { if (gst_mpeg4_parse_group_of_vop(&gop, buf, buf_size) != GST_MPEG4_PARSER_OK) { @@ -412,10 +418,10 @@ decode_gop(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) gop.hours, gop.minutes, gop.seconds, priv->closed_gop, priv->broken_link); - pts = GST_SECOND * (gop.hours * 3600 + gop.minutes * 60 + gop.seconds); - priv->gop_pts = pts; - priv->last_sync_time = priv->gop_pts; - priv->sync_time= priv->gop_pts; + gop_time = gop.hours * 3600 + gop.minutes * 60 + gop.seconds; + priv->gop_pts = gop_time * GST_SECOND; + priv->last_sync_time = gop_time; + priv->sync_time = gop_time; if (priv->calculate_pts_diff) { priv->pts_diff = priv->seq_pts - priv->gop_pts; @@ -556,11 +562,16 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) priv->sync_time = priv->last_sync_time + vop_hdr->modulo_time_base; pts = priv->sync_time * GST_SECOND; pts += gst_util_uint64_scale(vop_hdr->time_increment, GST_SECOND, vol_hdr->vop_time_increment_resolution); + priv->last_non_b_scale_time = priv->non_b_scale_time; + priv->non_b_scale_time = priv->sync_time * vol_hdr->vop_time_increment_resolution + vop_hdr->time_increment; + priv->trd = priv->non_b_scale_time - priv->last_non_b_scale_time; } else { // increment basing on display oder - pts = (priv->last_sync_time + vop_hdr->modulo_time_base)* GST_SECOND; + pts = (priv->last_sync_time + vop_hdr->modulo_time_base) * GST_SECOND; pts += gst_util_uint64_scale(vop_hdr->time_increment, GST_SECOND, vol_hdr->vop_time_increment_resolution); + priv->trb = (priv->last_sync_time + vop_hdr->modulo_time_base) * vol_hdr->vop_time_increment_resolution + + vop_hdr->time_increment - priv->last_non_b_scale_time; } } picture->pts = pts + priv->pts_diff; @@ -649,14 +660,16 @@ fill_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) pic_param->vop_time_increment_resolution = priv->vol_hdr.vop_time_increment_resolution; } + pic_param->TRB = 0; + pic_param->TRD = 0; switch (priv->coding_type) { case GST_MPEG4_B_VOP: - pic_param->TRB = priv->curr_picture->pts - priv->prev_picture->pts; - pic_param->TRD = priv->next_picture->pts - priv->prev_picture->pts; + pic_param->TRB = priv->trb; pic_param->backward_reference_picture = priv->next_picture->surface_id; pic_param->vop_fields.bits.backward_reference_vop_coding_type = priv->prev_picture->type; // fall-through case GST_MPEG4_P_VOP: + pic_param->TRD = priv->trd; if (priv->prev_picture) pic_param->forward_reference_picture = priv->prev_picture->surface_id; break; @@ -1049,6 +1062,10 @@ gst_vaapi_decoder_mpeg4_init(GstVaapiDecoderMpeg4 *decoder) priv->progressive_sequence = FALSE; priv->closed_gop = FALSE; priv->broken_link = FALSE; + priv->last_non_b_scale_time = 0; + priv->non_b_scale_time = 0; + priv->trb = 0; + priv->trd = 0; } /** From bf9f77b1afb0829b97e2d502057aec973c5fd7f5 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Thu, 12 Apr 2012 11:48:24 +0200 Subject: [PATCH 0684/3781] mpeg4: fix VOP coding type of backward reference pictures. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index bd089e2430..9909db5566 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -587,6 +587,12 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) return status; } +static inline guint +get_vop_coding_type(GstVaapiPicture *picture) +{ + return picture->type - GST_VAAPI_PICTURE_TYPE_I; +} + static gboolean fill_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) { @@ -666,7 +672,7 @@ fill_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) case GST_MPEG4_B_VOP: pic_param->TRB = priv->trb; pic_param->backward_reference_picture = priv->next_picture->surface_id; - pic_param->vop_fields.bits.backward_reference_vop_coding_type = priv->prev_picture->type; + pic_param->vop_fields.bits.backward_reference_vop_coding_type = get_vop_coding_type(priv->prev_picture); // fall-through case GST_MPEG4_P_VOP: pic_param->TRD = priv->trd; From 449606efc57bfe416cc754d9da72b00c0c744981 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 16 Apr 2012 10:02:29 +0200 Subject: [PATCH 0685/3781] Fix build without JPEG decoder. --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 63ba30ef86..e79341d001 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -248,6 +248,7 @@ gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size) /* --- JPEG Huffman Tables --- */ /* ------------------------------------------------------------------------- */ +#if USE_JPEG_DECODER GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiHuffmanTable, gst_vaapi_huffman_table, GST_VAAPI_TYPE_CODEC_OBJECT) @@ -302,3 +303,4 @@ gst_vaapi_huffman_table_new( return NULL; return GST_VAAPI_HUFFMAN_TABLE_CAST(object); } +#endif From 1632b409824bee961fe66ae53cd279a99448f647 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Thu, 26 Apr 2012 04:00:41 -0400 Subject: [PATCH 0686/3781] mpeg4: fix timestamp issues on too fast playback. Improve generation of presentation timestamps to be less sensitive to input stream errors. In practise, GOP is also a synchronization point for PTS calculation. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 69 +++++++++++++++++++--- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 9909db5566..15ec95a70c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -73,6 +73,7 @@ struct _GstVaapiDecoderMpeg4Private { GstClockTime seq_pts; GstClockTime gop_pts; GstClockTime pts_diff; + GstClockTime max_pts; // anchor sync time base for any picture type, // it is time base of backward reference frame GstClockTime last_sync_time; @@ -314,8 +315,6 @@ decode_sequence(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size priv->profile_changed = TRUE; } priv->seq_pts = gst_adapter_prev_timestamp(priv->adapter, NULL); - priv->calculate_pts_diff = TRUE; - priv->size_changed = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -419,19 +418,64 @@ decode_gop(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) priv->closed_gop, priv->broken_link); gop_time = gop.hours * 3600 + gop.minutes * 60 + gop.seconds; - priv->gop_pts = gop_time * GST_SECOND; priv->last_sync_time = gop_time; priv->sync_time = gop_time; - if (priv->calculate_pts_diff) { - priv->pts_diff = priv->seq_pts - priv->gop_pts; - priv->calculate_pts_diff = FALSE; - } - + if (priv->gop_pts != GST_CLOCK_TIME_NONE) + priv->pts_diff += gop_time * GST_SECOND - priv->gop_pts; + priv->gop_pts = gop_time * GST_SECOND; + priv->calculate_pts_diff = TRUE; priv->is_first_field = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } + +void +calculate_pts_diff(GstVaapiDecoderMpeg4 *decoder, + GstMpeg4VideoObjectLayer *vol_hdr, + GstMpeg4VideoObjectPlane *vop_hdr) +{ + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstClockTime frame_timestamp; + + frame_timestamp = gst_adapter_prev_timestamp(priv->adapter, NULL); + if (frame_timestamp && frame_timestamp != GST_CLOCK_TIME_NONE) { + /* Buffer with timestamp */ + if (priv->max_pts != GST_CLOCK_TIME_NONE && + frame_timestamp < priv->max_pts) { + frame_timestamp = priv->max_pts + + gst_util_uint64_scale((vol_hdr->fixed_vop_rate ? + vol_hdr->fixed_vop_time_increment : 1), + GST_SECOND, + vol_hdr->vop_time_increment_resolution); + } + } else { + /* Buffer without timestamp set */ + if (priv->max_pts == GST_CLOCK_TIME_NONE) /* first buffer */ + frame_timestamp = 0; + else { + GstClockTime tmp_pts; + tmp_pts = priv->pts_diff + priv->gop_pts + + vop_hdr->modulo_time_base * GST_SECOND + + gst_util_uint64_scale(vop_hdr->time_increment, + GST_SECOND, + vol_hdr->vop_time_increment_resolution); + if (tmp_pts > priv->max_pts) + frame_timestamp = tmp_pts; + else + frame_timestamp = priv->max_pts + + gst_util_uint64_scale((vol_hdr->fixed_vop_rate ? + vol_hdr->fixed_vop_time_increment : 1), + GST_SECOND, + vol_hdr->vop_time_increment_resolution); + } + } + + priv->pts_diff = frame_timestamp - + (priv->gop_pts + vop_hdr->modulo_time_base * GST_SECOND + + gst_util_uint64_scale(vop_hdr->time_increment, GST_SECOND, + vol_hdr->vop_time_increment_resolution)); +} static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) @@ -555,6 +599,12 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) priv->prev_t_ref = priv->svh_hdr.temporal_reference; } else { + /* Update priv->pts_diff */ + if (priv->calculate_pts_diff) { + calculate_pts_diff(decoder, vol_hdr, vop_hdr); + priv->calculate_pts_diff = FALSE; + } + /* Update presentation time, 6.3.5 */ if(vop_hdr->coding_type != GST_MPEG4_B_VOP) { // increment basing on decoding order @@ -575,6 +625,8 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) } } picture->pts = pts + priv->pts_diff; + if (priv->max_pts == GST_CLOCK_TIME_NONE || priv->max_pts < picture->pts) + priv->max_pts = picture->pts; /* Update reference pictures */ /* XXX: consider priv->vol_hdr.low_delay, consider packed video frames for DivX/XviD */ @@ -1058,6 +1110,7 @@ gst_vaapi_decoder_mpeg4_init(GstVaapiDecoderMpeg4 *decoder) priv->sub_buffer = NULL; priv->seq_pts = GST_CLOCK_TIME_NONE; priv->gop_pts = GST_CLOCK_TIME_NONE; + priv->max_pts = GST_CLOCK_TIME_NONE; priv->pts_diff = 0; priv->calculate_pts_diff = TRUE; priv->is_constructed = FALSE; From 96437a7a1691067a5e7975f548623bc6a6b8e799 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 27 Apr 2012 04:10:17 -0400 Subject: [PATCH 0687/3781] mpeg4: handle skipped frames (vop_hdr->coded = 0). Gracefully skip non VOP coded frames. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 15ec95a70c..9f07a8a617 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -496,6 +496,9 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) } else { parser_result = gst_mpeg4_parse_video_object_plane(vop_hdr, sprite_trajectory, vol_hdr, buf, buf_size); + /* Need to skip this frame if VOP was not coded */ + if (GST_MPEG4_PARSER_OK == parser_result && !vop_hdr->coded) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; } if (parser_result != GST_MPEG4_PARSER_OK) { @@ -964,7 +967,8 @@ decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) break; } status = decode_packet(decoder, packet); - if (GST_VAAPI_DECODER_STATUS_SUCCESS == status) { + if (GST_VAAPI_DECODER_STATUS_SUCCESS == status || + GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA == status) { consumed_size = packet.offset + packet.size - pos; pos = packet.offset + packet.size; if (gst_adapter_available(priv->adapter) >= pos) From c40c05dc45fe187c43d15e23e9d47efec9a129c2 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 27 Apr 2012 04:13:00 -0400 Subject: [PATCH 0688/3781] mpeg4: map Simple_Scalable profile to Advanced_Simple profile. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 9f07a8a617..52f461f173 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -304,6 +304,7 @@ decode_sequence(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; break; case GST_MPEG4_PROFILE_ADVANCED_SIMPLE: + case GST_MPEG4_PROFILE_SIMPLE_SCALABLE: /* shared profile with ADVANCED_SIMPLE */ profile = GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE; break; default: From 0fe727ba77e1b7ea8e2a915ab5ac56c1851877b3 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Wed, 18 Apr 2012 22:30:45 -0400 Subject: [PATCH 0689/3781] mpeg: fix picture used to determine backward_reference_vop_coding_type. Complete fix brought by bf9f77b1afb0829b97e2d502057aec973c5fd7f5 but Gwenole did not apply all the bits. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 52f461f173..acf9d0d1ce 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -728,7 +728,7 @@ fill_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) case GST_MPEG4_B_VOP: pic_param->TRB = priv->trb; pic_param->backward_reference_picture = priv->next_picture->surface_id; - pic_param->vop_fields.bits.backward_reference_vop_coding_type = get_vop_coding_type(priv->prev_picture); + pic_param->vop_fields.bits.backward_reference_vop_coding_type = get_vop_coding_type(priv->next_picture); // fall-through case GST_MPEG4_P_VOP: pic_param->TRD = priv->trd; From 0cf06cdbcb5332cd17c7175b2e19af1682146e64 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Apr 2012 01:58:39 -0400 Subject: [PATCH 0690/3781] jpeg: simplify and optimize parser API. --- gst-libs/gst/codecparsers/gstjpegparser.h | 347 ++++++++++++++++++---- 1 file changed, 292 insertions(+), 55 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstjpegparser.h b/gst-libs/gst/codecparsers/gstjpegparser.h index 43bedb155a..c6b8fc08c2 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.h +++ b/gst-libs/gst/codecparsers/gstjpegparser.h @@ -1,5 +1,5 @@ /* - * gstjpegparser.h - JPEG parser for baseline + * gstjpegparser.h - JPEG parser * * Copyright (C) 2011 Intel Corporation * @@ -31,89 +31,326 @@ G_BEGIN_DECLS -#define GST_JPEG_MAX_COMPONENTS 4 -#define GST_JPEG_QUANT_ELEMENTS_SIZE 64 +/** + * GST_JPEG_MAX_FRAME_COMPONENTS: + * + * Maximum number of image components in a frame (Nf). + */ +#define GST_JPEG_MAX_FRAME_COMPONENTS 256 + +/** + * GST_JPEG_MAX_SCAN_COMPONENTS: + * + * Maximum number of image components in a scan (Ns). + */ +#define GST_JPEG_MAX_SCAN_COMPONENTS 4 + +/** + * GST_JPEG_MAX_QUANT_ELEMENTS: + * + * Number of elements in the quantization table. + */ +#define GST_JPEG_MAX_QUANT_ELEMENTS 64 typedef struct _GstJpegQuantTable GstJpegQuantTable; typedef struct _GstJpegHuffmanTable GstJpegHuffmanTable; -typedef struct _GstJpegScan GstJpegScan; -typedef struct _GstJpegImage GstJpegImage; +typedef struct _GstJpegScanComponent GstJpegScanComponent; +typedef struct _GstJpegScanHdr GstJpegScanHdr; +typedef struct _GstJpegFrameComponent GstJpegFrameComponent; +typedef struct _GstJpegFrameHdr GstJpegFrameHdr; +typedef struct _GstJpegTypeOffsetSize GstJpegTypeOffsetSize; +/** + * GstJpegParserResult: + * @GST_JPEG_PARSER_OK: The parsing succeeded + * @GST_JPEG_PARSER_BROKEN_DATA: The data to parse is broken + * @GST_JPEG_PARSER_NO_SCAN_FOUND: No scan found during the parsing + * @GST_JPEG_PARSER_ERROR: An error occured while parsing + * + * The result of parsing JPEG data. + */ typedef enum { GST_JPEG_PARSER_OK, - GST_JPEG_PARSER_UNSUPPORTED_PROFILE, - GST_JPEG_PARSER_NOT_JPEG, GST_JPEG_PARSER_BROKEN_DATA, GST_JPEG_PARSER_NO_SCAN_FOUND, - GST_JPEG_PARSER_FRAME_ERROR, - GST_JPEG_PARSER_SCAN_ERROR, - GST_JPEG_PARSER_HUFFMAN_ERROR, - GST_JPEG_PARSER_QUANT_ERROR, - GST_JPEG_PARSER_DRI_ERROR, + GST_JPEG_PARSER_ERROR, } GstJpegParserResult; +/** + * GstJpegMarkerCode: + * @GST_JPEG_MARKER_SOF_MIN: Start of frame min marker code + * @GST_JPEG_MARKER_SOF_MAX: Start of frame max marker code + * @GST_JPEG_MARKER_DHT: Huffman tabler marker code + * @GST_JPEG_MARKER_DAC: Arithmetic coding marker code + * @GST_JPEG_MARKER_RST_MIN: Restart interval min marker code + * @GST_JPEG_MARKER_RST_MAX: Restart interval max marker code + * @GST_JPEG_MARKER_SOI: Start of image marker code + * @GST_JPEG_MARKER_EOI: End of image marker code + * @GST_JPEG_MARKER_SOS: Start of scan marker code + * @GST_JPEG_MARKER_DQT: Define quantization table marker code + * @GST_JPEG_MARKER_DNL: Define number of lines marker code + * @GST_JPEG_MARKER_DRI: Define restart interval marker code + * @GST_JPEG_MARKER_APP_MIN: Application segment min marker code + * @GST_JPEG_MARKER_APP_MAX: Application segment max marker code + * @GST_JPEG_MARKER_COM: Comment marker code + * + * Indicates the type of JPEG segment. + */ +typedef enum { + GST_JPEG_MARKER_SOF_MIN = 0xC0, + GST_JPEG_MARKER_SOF_MAX = 0xCF, + GST_JPEG_MARKER_DHT = 0xC4, + GST_JPEG_MARKER_DAC = 0xCC, + GST_JPEG_MARKER_RST_MIN = 0xD0, + GST_JPEG_MARKER_RST_MAX = 0xD7, + GST_JPEG_MARKER_SOI = 0xD8, + GST_JPEG_MARKER_EOI = 0xD9, + GST_JPEG_MARKER_SOS = 0xDA, + GST_JPEG_MARKER_DQT = 0xDB, + GST_JPEG_MARKER_DNL = 0xDC, + GST_JPEG_MARKER_DRI = 0xDD, + GST_JPEG_MARKER_APP_MIN = 0xE0, + GST_JPEG_MARKER_APP_MAX = 0xEF, + GST_JPEG_MARKER_COM = 0xFE, +} GstJpegMarkerCode; + +/** + * GstJpegProfile: + * @GST_JPEG_PROFILE_BASELINE: Baseline DCT + * @GST_JPEG_PROFILE_EXTENDED: Extended sequential DCT + * @GST_JPEG_PROFILE_PROGRESSIVE: Progressive DCT + * @GST_JPEG_PROFILE_LOSSLESS: Lossless (sequential) + * @GST_JPEG_PROFILE_ARITHMETIC: Flag for arithmetic coding + * + * JPEG encoding processes. + */ +typedef enum { + GST_JPEG_PROFILE_BASELINE = 0x00, + GST_JPEG_PROFILE_EXTENDED = 0x01, + GST_JPEG_PROFILE_PROGRESSIVE = 0x02, + GST_JPEG_PROFILE_LOSSLESS = 0x03, + GST_JPEG_PROFILE_ARITHMETIC = 0x80 +} GstJpegProfile; + +/** + * GstJpegQuantTable: + * @quant_precision: Quantization table element precision (Pq) + * @quant_table: Quantization table elements (Qk) + * + * Quantization table. + */ struct _GstJpegQuantTable { - guint8 quant_precision; /* 4 bits; Value 0 indicates 8bit Q values; value 1 indicates 16bit Q values */ - guint8 quant_table[GST_JPEG_QUANT_ELEMENTS_SIZE * 2]; /* 64*8(or 64*16) bits, zigzag mode */ + guint8 quant_precision; + guint16 quant_table[GST_JPEG_MAX_QUANT_ELEMENTS]; }; +/** + * GstJpegHuffmanTable: + * @huf_bits: Number of Huffman codes of length i + 1 (Li) + * @huf_vales: Value associated with each Huffman code (Vij) + * + * Huffman table. + */ struct _GstJpegHuffmanTable { guint8 huf_bits[16]; guint8 huf_values[256]; }; -struct _GstJpegScan +/** + * GstJpegScanComponent: + * @component_selector: Scan component selector (Csj) + * @dc_selector: DC entropy coding table destination selector (Tdj) + * @ac_selector: AC entropy coding table destination selector (Taj) + + * Component-specification parameters. + */ +struct _GstJpegScanComponent { - guint8 num_components; /* 8 bits */ - struct - { - guint8 component_selector; /* 8 bits */ - guint8 dc_selector; /* 4 bits */ - guint8 ac_selector; /* 4 bits */ - } components[GST_JPEG_MAX_COMPONENTS]; + guint8 component_selector; /* 0 .. 255 */ + guint8 dc_selector; /* 0 .. 3 */ + guint8 ac_selector; /* 0 .. 3 */ }; -struct _GstJpegImage +/** + * GstJpegScanHdr: + * @num_components: Number of image components in scan (Ns) + * @components: Image components + * + * Scan header. + */ +struct _GstJpegScanHdr { - guint32 frame_type; - guint8 sample_precision; /* 8 bits */ - guint16 height; /* 16 bits */ - guint16 width; /* 16 bits */ - guint8 num_components; /* 8 bits */ - struct - { - guint8 identifier; /* 8 bits */ - guint8 horizontal_factor; /* 4 bits */ - guint8 vertical_factor; /* 4 bits */ - guint8 quant_table_selector; /* 8 bits */ - } components[GST_JPEG_MAX_COMPONENTS]; - - GstJpegQuantTable quant_tables[GST_JPEG_MAX_COMPONENTS]; - GstJpegHuffmanTable dc_huf_tables[GST_JPEG_MAX_COMPONENTS]; - GstJpegHuffmanTable ac_huf_tables[GST_JPEG_MAX_COMPONENTS]; - guint32 restart_interval; /* DRI */ - - GstJpegScan current_scan; - - const guint8 *jpeg_pos; - const guint8 *jpeg_begin; - const guint8 *jpeg_end; + guint8 num_components; /* 1 .. 4 */ + GstJpegScanComponent components[GST_JPEG_MAX_SCAN_COMPONENTS]; }; -/* parse to first scan and stop there */ -GstJpegParserResult gst_jpeg_parse_image (GstJpegImage * image, - const guint8 * buf, - guint32 size); +/** + * GstJpegFrameComponent: + * @identifier: Component identifier (Ci) + * @horizontal_factor: Horizontal sampling factor (Hi) + * @vertical_factor: Vertical sampling factor (Vi) + * @quant_table_selector: Quantization table destination selector (Tqi) + * + * Component-specification parameters. + */ +struct _GstJpegFrameComponent +{ + guint8 identifier; /* 0 .. 255 */ + guint8 horizontal_factor; /* 1 .. 4 */ + guint8 vertical_factor; /* 1 .. 4 */ + guint8 quant_table_selector; /* 0 .. 3 */ +}; -GstJpegParserResult gst_jpeg_parse_next_scan (GstJpegImage * image); +/** + * GstJpegFrameHdr: + * @profile: JPEG encoding process (see #GstJpegProfile) + * @sample_precision: Sample precision (P) + * @height: Number of lines (Y) + * @width: Number of samples per line (X) + * @num_components: Number of image components in frame (Nf) + * @components: Image components + * @restart_interval: Number of MCU in the restart interval (Ri) + * + * Frame header. + */ +struct _GstJpegFrameHdr +{ + guint8 profile; + guint8 sample_precision; /* 2 .. 16 */ + guint16 width; /* 1 .. 65535 */ + guint16 height; /* 0 .. 65535 */ + guint8 num_components; /* 1 .. 255 */ + GstJpegFrameComponent components[GST_JPEG_MAX_FRAME_COMPONENTS]; +}; -/* return skip bytes length */ -guint32 gst_jpeg_skip_to_scan_end (GstJpegImage * image); -const guint8 * gst_jpeg_get_position (GstJpegImage * image); -guint32 gst_jpeg_get_left_size (GstJpegImage * image); +/** + * GstJpegTypeOffsetSize: + * @type: The type of the segment that starts at @offset + * @offset: The offset to the segment start in bytes + * @size: The size in bytes of the segment, or -1 if the end was not found + * + * A structure that contains the type of a segment, its offset and its size. + */ +struct _GstJpegTypeOffsetSize +{ + guint8 type; + guint offset; + gint size; +}; + +/** + * gst_jpeg_parse: + * @data: The data to parse + * @size: The size of @data + * @offset: The offset from which to start parsing + * + * Parses the JPEG bitstream contained in @data, and returns the detected + * segments as a newly-allocated list of #GstJpegTypeOffsetSize elements. + * The caller is responsible for destroying the list when no longer needed. + * + * Returns: a #GList of #GstJpegTypeOffsetSize. + */ +GList *gst_jpeg_parse (const guint8 * data, + gsize size, + guint offset); + +/** + * gst_jpeg_parse_frame_hdr: + * @hdr: (out): The #GstJpegFrameHdr structure to fill in + * @data: The data from which to parse the frame header + * @size: The size of @data + * @offset: The offset in bytes from which to start parsing @data + * + * Parses the @hdr JPEG frame header structure members from @data. + * + * Returns: a #GstJpegParserResult + */ +GstJpegParserResult gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * hdr, + const guint8 * data, + gsize size, + guint offset); + +/** + * gst_jpeg_parse_scan_hdr: + * @hdr: (out): The #GstJpegScanHdr structure to fill in + * @data: The data from which to parse the scan header + * @size: The size of @data + * @offset: The offset in bytes from which to start parsing @data + * + * Parses the @hdr JPEG scan header structure members from @data. + * + * Returns: a #GstJpegParserResult + */ +GstJpegParserResult gst_jpeg_parse_scan_hdr (GstJpegScanHdr * hdr, + const guint8 * data, + gsize size, + guint offset); + +/** + * gst_jpeg_parse_quantization_table: + * @quant_tables: (out): The #GstJpegQuantizationTable structure to fill in + * @num_quant_tables: The number of allocated quantization tables in @quant_tables + * @data: The data from which to parse the quantization table + * @size: The size of @data + * @offset: The offset in bytes from which to start parsing @data + * + * Parses the JPEG quantization table structure members from @data. + * + * Note: @quant_tables represents the user-allocated quantization + * tables based on the number of scan components. That is, the parser + * writes the output quantization table at the index specified by the + * quantization table destination identifier (Tq). So, the array of + * quantization tables shall be large enough to hold the table for the + * last component. + * + * Returns: a #GstJpegParserResult + */ +GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTable *quant_tables, + guint num_quant_tables, + const guint8 * data, + gsize size, + guint offset); + +/** + * gst_jpeg_parse_huffman_table: + * @huf_tables: (out): The #GstJpegHuffmanTable structure to fill in + * @num_huf_tables: The number of allocated Huffman tables in @huf_tables + * @data: The data from which to parse the Huffman table + * @size: The size of @data + * @offset: The offset in bytes from which to start parsing @data + * + * Parses the JPEG Huffman table structure members from @data. + * + * Note: @huf_tables represents the user-allocated Huffman tables + * based on the number of scan components. That is, the parser writes + * the output Huffman table at the index specified by the Huffman + * table destination identifier (Th). So, the array of Huffman tables + * shall be large enough to hold the table for the last component. + * + * Returns: a #GstJpegParserResult + */ +GstJpegParserResult gst_jpeg_parse_huffman_table (GstJpegHuffmanTable *huf_tables, + guint num_huf_tables, + const guint8 * data, + gsize size, + guint offset); + +/** + * gst_jpeg_parse_restart_interval: + * @interval: (out): The parsed restart interval value + * @data: The data from which to parse the restart interval specification + * @size: The size of @data + * @offset: The offset in bytes from which to start parsing @data + * + * Returns: a #GstJpegParserResult + */ +GstJpegParserResult gst_jpeg_parse_restart_interval (guint * interval, + const guint8 * data, + gsize size, + guint offset); G_END_DECLS From 53cbdcc1e6df3f71a4c43c25d3e5bf0b8d9cae7d Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Thu, 19 Apr 2012 23:50:14 +0800 Subject: [PATCH 0691/3781] jpeg: update to match latest parser API. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/codecparsers/gstjpegparser.c | 668 +++++++++------------- gst-libs/gst/codecparsers/gstjpegparser.h | 33 +- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 458 +++++++++++---- 3 files changed, 629 insertions(+), 530 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c index 2eefc8991d..a56c3df1c5 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -65,15 +65,15 @@ ensure_debug_category (void) } \ } G_STMT_END -#define READ_UINT8(reader, val) G_STMT_START { \ - if (!gst_byte_reader_get_uint8 ((reader), &val)) { \ - GST_WARNING ("failed to read uint8"); \ - goto failed; \ - } \ +#define READ_UINT8(reader, val) G_STMT_START { \ + if (!gst_byte_reader_get_uint8 ((reader), &(val))) { \ + GST_WARNING ("failed to read uint8"); \ + goto failed; \ + } \ } G_STMT_END #define READ_UINT16(reader, val) G_STMT_START { \ - if (!gst_byte_reader_get_uint16_be ((reader), &val)) { \ + if (!gst_byte_reader_get_uint16_be ((reader), &(val))) { \ GST_WARNING ("failed to read uint16"); \ goto failed; \ } \ @@ -88,123 +88,149 @@ ensure_debug_category (void) memcpy(buf, vals, length); \ } G_STMT_END -/* Table B.1: marker code assignments */ -enum JPEG_MARKER -{ - GST_JPEG_SOF0 = 0xC0, /* Frame Profile, Baseline */ - GST_JPEG_SOFF = 0xCF, - GST_JPEG_DHT = 0xC4, /* Define Huffman Table */ - GST_JPEG_DAC = 0xCC, /* Define Arithmetic Coding conditioning */ - GST_JPEG_RST0 = 0xD0, /* Restart with modulo 8 */ - GST_JPEG_RST7 = 0xD7, - GST_JPEG_SOI = 0xD8, /* Start Of Image */ - GST_JPEG_EOI = 0xD9, /* End Of Image */ - GST_JPEG_SOS = 0xDA, /* Start Of Scan */ - GST_JPEG_DQT = 0xDB, /* Define Quantization Table */ - GST_JPEG_DNL = 0xDC, /* Define Num of Lines */ - GST_JPEG_DRI = 0xDD, /* Define Restart Interval */ - GST_JPEG_APP0 = 0xE0, /* Application segments */ - GST_JPEG_APPF = 0xEF, - GST_JPEG_COM = 0xFE, /* Comments */ -}; static gboolean jpeg_parse_to_next_marker (GstByteReader * reader, guint8 * marker); /* CCITT T.81, Annex K.1 Quantization tables for luminance and chrominance components */ /* only for 8-bit per sample image*/ -static const guint8 default_quant_luma_zigzag[64] = { - 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, - 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, - 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, - 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, - 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, - 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, - 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, - 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, -}; - -static const guint8 default_quant_chroma_zigzag[64] = { - 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 +static const GstJpegQuantTable +default_quant_tables_zigzag[GST_JPEG_MAX_SCAN_COMPONENTS] = { + /* luma */ + {0, { 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, + 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, + 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, + 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, + 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, + 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, + 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, + 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63 } }, + /* chroma */ + {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 } }, + /* chroma */ + {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 } }, + {0, } }; /* Table K.3: typical Huffman tables for 8-bit precision luminance and chrominance */ -static const guint8 default_dc_luma_bits[16] = { - 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 -}; - -static const guint8 default_dc_luma_vals[16] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 -}; - -static const guint8 default_dc_chroma_bits[16] = { - 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 -}; - -static const guint8 default_dc_chroma_vals[16] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 -}; - -static const guint8 default_ac_luma_bits[16] = { - 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125 -}; - -static const guint8 default_ac_luma_vals[256] = { - 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa -}; - -static const guint8 default_ac_chroma_bits[16] = { - 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119 -}; - -static const guint8 default_ac_chroma_vals[256] = { - 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa +/* +0..GST_JPEG_MAX_SCAN_COMPONENTS -1, DC huffman tables +GST_JPEG_MAX_SCAN_COMPONENTS...GST_JPEG_MAX_SCAN_COMPONENTS*2-1, AC huffman tables +*/ +static const +GstJpegHuffmanTable default_huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2] = { + /* DC luma */ + { { 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b } + }, + /* DC chroma */ + { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b } + }, + /* DC chroma */ + { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b } + }, + { { 0 }, + { 0 } + }, + /* AC luma */ + { { 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, + 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d }, + { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa} + }, + /* AC chroma */ + { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77 }, + { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa } + }, + /* AC chroma */ + { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77 }, + { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa } + }, + { { 0 }, + { 0 } + } }; static gboolean @@ -228,98 +254,101 @@ failed: return FALSE; } -static GstJpegParserResult -jpeg_parse_frame (GstJpegImage * image, const guint8 * buf, guint32 length) +GstJpegParserResult +gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * frame_hdr, + const guint8 * data, gsize size, guint offset) { - GstByteReader bytes_reader = GST_BYTE_READER_INIT (buf, length); + GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); GstJpegParserResult result = GST_JPEG_PARSER_OK; guint8 val; u_int i; - g_assert (image && buf && length); - READ_UINT8 (&bytes_reader, image->sample_precision); - READ_UINT16 (&bytes_reader, image->height); - READ_UINT16 (&bytes_reader, image->width); - READ_UINT8 (&bytes_reader, image->num_components); - CHECK_FAILED (image->num_components <= GST_JPEG_MAX_COMPONENTS, - GST_JPEG_PARSER_FRAME_ERROR); - for (i = 0; i < image->num_components; i++) { - READ_UINT8 (&bytes_reader, image->components[i].identifier); + g_assert (frame_hdr && data && size); + READ_UINT8 (&bytes_reader, frame_hdr->sample_precision); + READ_UINT16 (&bytes_reader, frame_hdr->height); + READ_UINT16 (&bytes_reader, frame_hdr->width); + READ_UINT8 (&bytes_reader, frame_hdr->num_components); + CHECK_FAILED (frame_hdr->num_components <= GST_JPEG_MAX_SCAN_COMPONENTS, + GST_JPEG_PARSER_ERROR); + for (i = 0; i < frame_hdr->num_components; i++) { + READ_UINT8 (&bytes_reader, frame_hdr->components[i].identifier); READ_UINT8 (&bytes_reader, val); - image->components[i].horizontal_factor = (val >> 4) & 0x0F; - image->components[i].vertical_factor = (val & 0x0F); - READ_UINT8 (&bytes_reader, image->components[i].quant_table_selector); - CHECK_FAILED ((image->components[i].horizontal_factor <= 4 && - image->components[i].vertical_factor <= 4 && - image->components[i].quant_table_selector < 4), - GST_JPEG_PARSER_FRAME_ERROR); + frame_hdr->components[i].horizontal_factor = (val >> 4) & 0x0F; + frame_hdr->components[i].vertical_factor = (val & 0x0F); + READ_UINT8 (&bytes_reader, frame_hdr->components[i].quant_table_selector); + CHECK_FAILED ((frame_hdr->components[i].horizontal_factor <= 4 && + frame_hdr->components[i].vertical_factor <= 4 && + frame_hdr->components[i].quant_table_selector < 4), + GST_JPEG_PARSER_ERROR); } return GST_JPEG_PARSER_OK; failed: - return GST_JPEG_PARSER_FRAME_ERROR; + return GST_JPEG_PARSER_ERROR; wrong_state: return result; } -static GstJpegParserResult -jpeg_parse_scan (GstJpegImage * image, const guint8 * buf, guint32 length) +GstJpegParserResult +gst_jpeg_parse_scan_hdr (GstJpegScanHdr * scan_hdr, + const guint8 * data, gsize size, guint offset) { - GstByteReader bytes_reader = GST_BYTE_READER_INIT (buf, length); + GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); GstJpegParserResult result = GST_JPEG_PARSER_OK; guint8 val; u_int i; - g_assert (image && buf && length); - READ_UINT8 (&bytes_reader, image->current_scan.num_components); - CHECK_FAILED (image->current_scan.num_components <= GST_JPEG_MAX_COMPONENTS, - GST_JPEG_PARSER_SCAN_ERROR); - for (i = 0; i < image->current_scan.num_components; i++) { + g_assert (scan_hdr && data && size); + READ_UINT8 (&bytes_reader, scan_hdr->num_components); + CHECK_FAILED (scan_hdr->num_components <= GST_JPEG_MAX_SCAN_COMPONENTS, + GST_JPEG_PARSER_BROKEN_DATA); + for (i = 0; i < scan_hdr->num_components; i++) { READ_UINT8 (&bytes_reader, - image->current_scan.components[i].component_selector); + scan_hdr->components[i].component_selector); READ_UINT8 (&bytes_reader, val); - image->current_scan.components[i].dc_selector = (val >> 4) & 0x0F; - image->current_scan.components[i].ac_selector = val & 0x0F; - g_assert (image->current_scan.components[i].dc_selector < 4 && - image->current_scan.components[i].ac_selector < 4); - CHECK_FAILED ((image->current_scan.components[i].dc_selector < 4 && - image->current_scan.components[i].ac_selector < 4), - GST_JPEG_PARSER_SCAN_ERROR); + scan_hdr->components[i].dc_selector = (val >> 4) & 0x0F; + scan_hdr->components[i].ac_selector = val & 0x0F; + g_assert (scan_hdr->components[i].dc_selector < 4 && + scan_hdr->components[i].ac_selector < 4); + CHECK_FAILED ((scan_hdr->components[i].dc_selector < 4 && + scan_hdr->components[i].ac_selector < 4), + GST_JPEG_PARSER_BROKEN_DATA); } return GST_JPEG_PARSER_OK; failed: - return GST_JPEG_PARSER_SCAN_ERROR; + return GST_JPEG_PARSER_ERROR; wrong_state: return result; } -static GstJpegParserResult -jpeg_parse_huffman_tables (GstJpegImage * image, const guint8 * buf, - guint32 length) +GstJpegParserResult +gst_jpeg_parse_huffman_table ( + GstJpegHuffmanTable huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2], + const guint8 * data, gsize size, guint offset) { - GstByteReader bytes_reader = GST_BYTE_READER_INIT (buf, length); + GstByteReader bytes_reader = GST_BYTE_READER_INIT (data+offset, size-offset); GstJpegParserResult result = GST_JPEG_PARSER_OK; - GstJpegHuffmanTable *huf_table; + GstJpegHuffmanTable * huf_table; guint8 tmp_val; gboolean is_dc; guint8 table_index; guint32 value_count; u_int i; - g_assert (image && buf && length); + g_assert (huf_tables && data && size); while (gst_byte_reader_get_remaining (&bytes_reader)) { READ_UINT8 (&bytes_reader, tmp_val); is_dc = !((tmp_val >> 4) & 0x0F); table_index = (tmp_val & 0x0F); - CHECK_FAILED (table_index < GST_JPEG_MAX_COMPONENTS, - GST_JPEG_PARSER_HUFFMAN_ERROR); + CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, + GST_JPEG_PARSER_BROKEN_DATA); if (is_dc) { - huf_table = &image->dc_huf_tables[table_index]; + huf_table = &huf_tables[table_index]; } else { - huf_table = &image->ac_huf_tables[table_index]; + huf_table = &huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS + table_index]; } READ_BYTES (&bytes_reader, huf_table->huf_bits, 16); value_count = 0; @@ -330,296 +359,133 @@ jpeg_parse_huffman_tables (GstJpegImage * image, const guint8 * buf, return GST_JPEG_PARSER_OK; failed: - return GST_JPEG_PARSER_HUFFMAN_ERROR; + return GST_JPEG_PARSER_ERROR; wrong_state: return result; } -static GstJpegParserResult -jpeg_parse_quantization_table (GstJpegImage * image, const guint8 * buf, - guint32 length) +GstJpegParserResult +gst_jpeg_parse_quant_table ( + GstJpegQuantTable *quant_tables, guint num_quant_tables, + const guint8 * data, gsize size, guint offset) { - GstByteReader bytes_reader = GST_BYTE_READER_INIT (buf, length); + GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); GstJpegParserResult result = GST_JPEG_PARSER_OK; GstJpegQuantTable *quant_table; guint8 val; guint8 table_index; + guint i; - g_assert (image && buf && length); + g_assert (quant_tables && num_quant_tables && data && size); while (gst_byte_reader_get_remaining (&bytes_reader)) { READ_UINT8 (&bytes_reader, val); table_index = (val & 0x0f); - CHECK_FAILED (table_index < GST_JPEG_MAX_COMPONENTS, - GST_JPEG_PARSER_QUANT_ERROR); - quant_table = &(image->quant_tables[table_index]); + CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS && table_index < num_quant_tables, + GST_JPEG_PARSER_BROKEN_DATA); + quant_table = &quant_tables[table_index]; quant_table->quant_precision = ((val >> 4) & 0x0f); - if (!quant_table->quant_precision) { /* 8-bit values */ - READ_BYTES (&bytes_reader, quant_table->quant_table, 64); - } else { /* 16-bit values */ - READ_BYTES (&bytes_reader, quant_table->quant_table, 128); + for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) { + if (!quant_table->quant_precision) { /* 8-bit values */ + READ_UINT8(&bytes_reader, val); + quant_table->quant_table[i] = val; + } else { /* 16-bit values */ + READ_UINT16(&bytes_reader, quant_table->quant_table[i]); + } } } return GST_JPEG_PARSER_OK; failed: - return GST_JPEG_PARSER_QUANT_ERROR; + return GST_JPEG_PARSER_ERROR; wrong_state: return result; } -static GstJpegParserResult -jpeg_parse_restart_interval (GstJpegImage * image, const guint8 * buf, - guint32 length) +GstJpegParserResult +gst_jpeg_parse_restart_interval (guint * interval, + const guint8 * data, gsize size, guint offset) { - GstByteReader bytes_reader = GST_BYTE_READER_INIT (buf, length); - guint16 interval; + GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); + guint16 tmp; - g_assert (image && buf && length); - READ_UINT16 (&bytes_reader, interval); - image->restart_interval = interval; + g_assert (interval && data && size); + READ_UINT16 (&bytes_reader, tmp); + *interval = tmp; return GST_JPEG_PARSER_OK; failed: - return GST_JPEG_PARSER_QUANT_ERROR; + return GST_JPEG_PARSER_BROKEN_DATA; } -static GstJpegParserResult -jpeg_parse_comments (GstJpegImage * image, const guint8 * buf, guint32 length) +void +gst_jpeg_get_default_huffman_table (GstJpegHuffmanTable huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2]) { - g_assert (image); -#if DEBUG_PRINT_COMMENT - char *comments = (char *) g_malloc0 (length + 1); - memcpy (comments, buf, length); - comments[length] = '\0'; - GST_DEBUG ("jpeg comments:%s\n", comments); - g_free (comments); -#endif - return GST_JPEG_PARSER_OK; + memcpy(huf_tables, + default_huf_tables, + sizeof(GstJpegHuffmanTable)*GST_JPEG_MAX_SCAN_COMPONENTS*2); } -static void -jpeg_set_default_huffman_tables (GstJpegImage * image) +void +gst_jpeg_get_default_quantization_table (GstJpegQuantTable *quant_tables, guint num_quant_tables) { - /* luma */ - memcpy (image->dc_huf_tables[0].huf_bits, default_dc_luma_bits, 16); - memcpy (image->dc_huf_tables[0].huf_values, default_dc_luma_vals, 16); - memcpy (image->ac_huf_tables[0].huf_bits, default_ac_luma_bits, 16); - memcpy (image->ac_huf_tables[0].huf_values, default_ac_luma_vals, 256); - - /* chroma */ - memcpy (image->dc_huf_tables[1].huf_bits, default_dc_chroma_bits, 16); - memcpy (image->dc_huf_tables[1].huf_values, default_dc_chroma_vals, 16); - memcpy (image->ac_huf_tables[1].huf_bits, default_ac_chroma_bits, 16); - memcpy (image->ac_huf_tables[1].huf_values, default_ac_chroma_vals, 256); + int i = 1; + g_assert(quant_tables && num_quant_tables); + for (i = 0; i < num_quant_tables && i < GST_JPEG_MAX_SCAN_COMPONENTS; i++) + memcpy(&quant_tables[i], + &default_quant_tables_zigzag[i], + sizeof(GstJpegQuantTable)); } -static void -jpeg_set_default_quantization_tables (GstJpegImage * image) -{ - /* luma */ - image->quant_tables[0].quant_precision = 0; - memcpy (image->quant_tables[0].quant_table, default_quant_luma_zigzag, 64); - - /* chroma */ - image->quant_tables[1].quant_precision = 0; - memcpy (image->quant_tables[1].quant_table, default_quant_chroma_zigzag, 64); -} - -GstJpegParserResult -gst_jpeg_parse_image (GstJpegImage * image, const guint8 * buf, guint32 size) +GList * +gst_jpeg_parse(const guint8 * data, gsize size, guint offset) { GstByteReader bytes_reader; - GstJpegParserResult result = GST_JPEG_PARSER_OK; guint8 marker; guint16 header_length; - const guint8 *header_buf; - gboolean first_scan_reached = FALSE; - gboolean has_huffman_tables = FALSE, has_quant_tables = FALSE; + GList *segments = NULL; + GstJpegTypeOffsetSize *seg; - g_assert (image && buf && size); - memset (image, 0, sizeof (GstJpegImage)); - gst_byte_reader_init (&bytes_reader, buf, size); + size -= offset; + + if ((gssize)size <= 0) { + GST_DEBUG ("Can't parse from offset %d, buffer is too small", offset); + return NULL; + } + + gst_byte_reader_init (&bytes_reader, &data[offset], size); /* read SOI */ - CHECK_FAILED (jpeg_parse_to_next_marker (&bytes_reader, &marker) - && GST_JPEG_SOI == marker, GST_JPEG_PARSER_NOT_JPEG); - image->jpeg_begin = buf + gst_byte_reader_get_pos (&bytes_reader) - 2; - image->jpeg_end = buf + size; + if (!jpeg_parse_to_next_marker (&bytes_reader, &marker) || + marker != GST_JPEG_MARKER_SOI) + goto failed; while (jpeg_parse_to_next_marker (&bytes_reader, &marker)) { - if (marker >= GST_JPEG_SOF0 && marker <= GST_JPEG_SOFF - && marker != GST_JPEG_DHT && marker != GST_JPEG_DAC) { - g_assert (marker == GST_JPEG_SOF0); - if (marker > GST_JPEG_SOF0) { - GST_WARNING ("codecparser_jpeg cannot support this image type:%02x", - marker); - result = GST_JPEG_PARSER_UNSUPPORTED_PROFILE; - goto wrong_state; - } - image->frame_type = marker; - marker = GST_JPEG_SOF0; - } - if (marker == GST_JPEG_EOI) { - image->jpeg_end = buf + gst_byte_reader_get_pos (&bytes_reader); + if (marker == GST_JPEG_MARKER_EOI) break; - } else { - READ_UINT16 (&bytes_reader, header_length); - CHECK_FAILED ((header_length >= 2 && - gst_byte_reader_get_remaining (&bytes_reader) + 2 >= - header_length), GST_JPEG_PARSER_BROKEN_DATA); - header_length -= 2; - header_buf = buf + gst_byte_reader_get_pos (&bytes_reader); - } - switch (marker) { - case GST_JPEG_SOF0: - JPEG_RESULT_CHECK (result = - jpeg_parse_frame (image, header_buf, header_length)); - break; - case GST_JPEG_DHT: - JPEG_RESULT_CHECK (result = - jpeg_parse_huffman_tables (image, header_buf, header_length)); - has_huffman_tables = TRUE; - break; - case GST_JPEG_SOS: - JPEG_RESULT_CHECK (result = - jpeg_parse_scan (image, header_buf, header_length)); - first_scan_reached = TRUE; /* read to first scan stop */ - break; - case GST_JPEG_DQT: - JPEG_RESULT_CHECK (result = - jpeg_parse_quantization_table (image, header_buf, header_length)); - has_quant_tables = TRUE; - break; - case GST_JPEG_DRI: - JPEG_RESULT_CHECK (result = - jpeg_parse_restart_interval (image, header_buf, header_length)); - break; - case GST_JPEG_COM: - JPEG_RESULT_CHECK (result = - jpeg_parse_comments (image, header_buf, header_length)); - break; - case GST_JPEG_DAC: - case GST_JPEG_DNL: - default: - /* Unsupported markers, skip them */ - break; - } - gst_byte_reader_skip (&bytes_reader, header_length); - if (first_scan_reached) - break; - } - - image->jpeg_pos = buf + gst_byte_reader_get_pos (&bytes_reader); - if (!first_scan_reached) { - GST_WARNING ("jpeg no scan was found\n"); - return GST_JPEG_PARSER_NO_SCAN_FOUND; - } - if (!has_huffman_tables) - jpeg_set_default_huffman_tables (image); - if (!has_quant_tables) - jpeg_set_default_quantization_tables (image); - - return GST_JPEG_PARSER_OK; - -failed: - GST_WARNING ("jpeg parsing read broken data"); - return GST_JPEG_PARSER_BROKEN_DATA; - -wrong_state: - return result; - -} - -GstJpegParserResult -gst_jpeg_parse_next_scan (GstJpegImage * image) -{ - GstByteReader bytes_reader; - GstJpegParserResult result = GST_JPEG_PARSER_OK; - guint8 marker; - guint16 header_length; - const guint8 *header_buf; - gboolean scan_found = FALSE; - - g_assert (image->jpeg_begin && image->jpeg_end && image->jpeg_pos); - if (!image->jpeg_begin || !image->jpeg_end || !image->jpeg_pos - || image->jpeg_pos >= image->jpeg_end) - return GST_JPEG_PARSER_NO_SCAN_FOUND; - gst_byte_reader_init (&bytes_reader, image->jpeg_pos, - image->jpeg_end - image->jpeg_pos); - - while (jpeg_parse_to_next_marker (&bytes_reader, &marker)) { - if (marker == GST_JPEG_EOI) { - image->jpeg_end = - image->jpeg_pos + gst_byte_reader_get_pos (&bytes_reader); - break; - } - if (marker != GST_JPEG_SOS) - continue; READ_UINT16 (&bytes_reader, header_length); - CHECK_FAILED ((header_length >= 2 && - gst_byte_reader_get_remaining (&bytes_reader) + 2 >= header_length), - GST_JPEG_PARSER_SCAN_ERROR); - header_length -= 2; - header_buf = image->jpeg_pos + gst_byte_reader_get_pos (&bytes_reader); - JPEG_RESULT_CHECK (result = - jpeg_parse_scan (image, header_buf, header_length)); - scan_found = TRUE; - break; - } - image->jpeg_pos += gst_byte_reader_get_pos (&bytes_reader); - if (!scan_found) - return GST_JPEG_PARSER_NO_SCAN_FOUND; + if (header_length < 2 || + gst_byte_reader_get_remaining (&bytes_reader) < header_length - 2) + goto failed; + + seg = g_malloc (sizeof (GstJpegTypeOffsetSize)); + seg->type = marker; + seg->offset = gst_byte_reader_get_pos(&bytes_reader) + offset; + seg->size = header_length - 2; + segments = g_list_prepend(segments, seg); + gst_byte_reader_skip (&bytes_reader, header_length - 2); + + /* parser should stop at first scan */ + if (seg->type == GST_JPEG_MARKER_SOS) + break; + } + return g_list_reverse (segments); - return GST_JPEG_PARSER_OK; failed: - GST_WARNING ("jpeg parsing read broken data"); - return GST_JPEG_PARSER_BROKEN_DATA; - -wrong_state: - return result; -} - -guint32 -gst_jpeg_skip_to_scan_end (GstJpegImage * image) -{ - GstByteReader bytes_reader; - guint8 marker; - guint32 skip_bytes = 0; - gboolean next_marker_found = FALSE; - - g_assert (image->jpeg_begin && image->jpeg_end && image->jpeg_pos); - if (!image->jpeg_begin || !image->jpeg_end || !image->jpeg_pos - || image->jpeg_pos >= image->jpeg_end) - return 0; - gst_byte_reader_init (&bytes_reader, image->jpeg_pos, - image->jpeg_end - image->jpeg_pos); - while (jpeg_parse_to_next_marker (&bytes_reader, &marker)) { - if (marker >= GST_JPEG_RST0 && marker <= GST_JPEG_RST7) - continue; - next_marker_found = TRUE; - break; + { + GST_WARNING ("Failed to parse"); + return g_list_reverse (segments); } - if (next_marker_found) - skip_bytes = gst_byte_reader_get_pos (&bytes_reader) - 2; - else - skip_bytes = gst_byte_reader_get_pos (&bytes_reader); - image->jpeg_pos += skip_bytes; - return skip_bytes; -} - -const guint8 * -gst_jpeg_get_position (GstJpegImage * image) -{ - return image->jpeg_pos; -} - -guint32 -gst_jpeg_get_left_size (GstJpegImage * image) -{ - if (image->jpeg_end > image->jpeg_pos) - return image->jpeg_end - image->jpeg_pos; - return 0; } diff --git a/gst-libs/gst/codecparsers/gstjpegparser.h b/gst-libs/gst/codecparsers/gstjpegparser.h index c6b8fc08c2..34a33a2dae 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.h +++ b/gst-libs/gst/codecparsers/gstjpegparser.h @@ -317,7 +317,6 @@ GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTable *quan /** * gst_jpeg_parse_huffman_table: * @huf_tables: (out): The #GstJpegHuffmanTable structure to fill in - * @num_huf_tables: The number of allocated Huffman tables in @huf_tables * @data: The data from which to parse the Huffman table * @size: The size of @data * @offset: The offset in bytes from which to start parsing @data @@ -327,13 +326,14 @@ GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTable *quan * Note: @huf_tables represents the user-allocated Huffman tables * based on the number of scan components. That is, the parser writes * the output Huffman table at the index specified by the Huffman - * table destination identifier (Th). So, the array of Huffman tables - * shall be large enough to hold the table for the last component. + * table destination identifier (Th). The first array of + * Huffman tables are related + * to dc tables; The second array of + * of Huffman tables are related to ac tables. * * Returns: a #GstJpegParserResult */ -GstJpegParserResult gst_jpeg_parse_huffman_table (GstJpegHuffmanTable *huf_tables, - guint num_huf_tables, +GstJpegParserResult gst_jpeg_parse_huffman_table (GstJpegHuffmanTable huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2], const guint8 * data, gsize size, guint offset); @@ -352,6 +352,29 @@ GstJpegParserResult gst_jpeg_parse_restart_interval (guint * interval, gsize size, guint offset); +/** + * gst_jpeg_get_default_huffman_table: + * @huf_tables: (out): The default dc/ac hufman tables to fill in + * + * DC huffman tables fill in the first 4 arrays. + * AC huffman tables fill in the last 4 arrays. + * + * Returns: void + */ +void gst_jpeg_get_default_huffman_table ( + GstJpegHuffmanTable huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2]); + +/** + * gst_jpeg_get_default_quantization_table: + * @quant_tables: (out): The default luma/chroma quant-tables in zigzag mode + * @num_quant_tables: The number of allocated quantization tables in @quant_tables + * + * Fills in @quant_tables with the default quantization tables, as + * specified by the JPEG standard. + */ +void gst_jpeg_get_default_quantization_table (GstJpegQuantTable *quant_tables, + guint num_quant_tables); + G_END_DECLS #endif /* GST_JPEG_PARSER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 91c4255e1c..cb083b325b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -50,6 +50,12 @@ struct _GstVaapiDecoderJpegPrivate { guint width; guint height; GstVaapiPicture *current_picture; + GstJpegFrameHdr frame_hdr; + GstJpegHuffmanTable huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2]; + GstJpegQuantTable quant_tables[GST_JPEG_MAX_SCAN_COMPONENTS]; + gboolean has_huf_table; + gboolean has_quant_table; + guint mcu_restart; guint is_opened : 1; guint profile_changed : 1; guint is_constructed : 1; @@ -65,10 +71,8 @@ get_status(GstJpegParserResult result) case GST_JPEG_PARSER_OK: status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; - case GST_JPEG_PARSER_FRAME_ERROR: - case GST_JPEG_PARSER_SCAN_ERROR: - case GST_JPEG_PARSER_HUFFMAN_ERROR: - case GST_JPEG_PARSER_QUANT_ERROR: + case GST_JPEG_PARSER_BROKEN_DATA: + case GST_JPEG_PARSER_NO_SCAN_FOUND: status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; default: @@ -178,7 +182,7 @@ static gboolean fill_picture( GstVaapiDecoderJpeg *decoder, GstVaapiPicture *picture, - GstJpegImage *jpeg_image + GstJpegFrameHdr *jpeg_frame_hdr ) { VAPictureParameterBufferJPEG *pic_param = picture->param; @@ -187,23 +191,25 @@ fill_picture( g_assert(pic_param); memset(pic_param, 0, sizeof(VAPictureParameterBufferJPEG)); - pic_param->type = jpeg_image->frame_type; - pic_param->sample_precision = jpeg_image->sample_precision; - pic_param->image_width = jpeg_image->width; - pic_param->image_height = jpeg_image->height; + pic_param->type = jpeg_frame_hdr->profile; + pic_param->sample_precision = jpeg_frame_hdr->sample_precision; + pic_param->image_width = jpeg_frame_hdr->width; + pic_param->image_height = jpeg_frame_hdr->height; /* XXX: ROI + rotation */ - pic_param->num_components = jpeg_image->num_components; + pic_param->num_components = jpeg_frame_hdr->num_components; + if (jpeg_frame_hdr->num_components > 4) + return FALSE; for (i = 0; i < pic_param->num_components; i++) { pic_param->components[i].component_id = - jpeg_image->components[i].identifier; + jpeg_frame_hdr->components[i].identifier; pic_param->components[i].h_sampling_factor = - jpeg_image->components[i].horizontal_factor; + jpeg_frame_hdr->components[i].horizontal_factor; pic_param->components[i].v_sampling_factor = - jpeg_image->components[i].vertical_factor; + jpeg_frame_hdr->components[i].vertical_factor; pic_param->components[i].quantiser_table_selector = - jpeg_image->components[i].quant_table_selector; + jpeg_frame_hdr->components[i].quant_table_selector; } return TRUE; } @@ -211,23 +217,31 @@ fill_picture( static gboolean fill_quantization_table( GstVaapiDecoderJpeg *decoder, - GstVaapiPicture *picture, - GstJpegImage *jpeg_image + GstVaapiPicture *picture ) { + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; VAIQMatrixBufferJPEG *iq_matrix; - int i = 0; + guint i, j; + + if (!priv->has_quant_table) + gst_jpeg_get_default_quantization_table(priv->quant_tables, GST_JPEG_MAX_SCAN_COMPONENTS); picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(JPEG, decoder); g_assert(picture->iq_matrix); iq_matrix = picture->iq_matrix->param; memset(iq_matrix, 0, sizeof(VAIQMatrixBufferJPEG)); - for (i = 0; i < GST_JPEG_MAX_COMPONENTS; i++) { - iq_matrix->precision[i] = jpeg_image->quant_tables[i].quant_precision; - if (iq_matrix->precision[i] == 0) /* 8-bit values*/ - memcpy(iq_matrix->quantiser_matrix[i], jpeg_image->quant_tables[i].quant_table, 64); + for (i = 0; i < GST_JPEG_MAX_SCAN_COMPONENTS; i++) { + iq_matrix->precision[i] = priv->quant_tables[i].quant_precision; + if (iq_matrix->precision[i] == 0) /* 8-bit values */ + for (j = 0; j < GST_JPEG_MAX_QUANT_ELEMENTS; j++) { + iq_matrix->quantiser_matrix[i][j] = + priv->quant_tables[i].quant_table[j]; + } else - memcpy(iq_matrix->quantiser_matrix[i], jpeg_image->quant_tables[i].quant_table, 128); + memcpy(iq_matrix->quantiser_matrix[i], + priv->quant_tables[i].quant_table, + 128); } return TRUE; } @@ -235,119 +249,65 @@ fill_quantization_table( static gboolean fill_huffman_table( GstVaapiDecoderJpeg *decoder, - GstVaapiPicture *picture, - GstJpegImage *jpeg_image + GstVaapiPicture *picture ) { + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; VAHuffmanTableBufferJPEG *huffman_table; - int i; + guint i; + + if (!priv->has_huf_table) + gst_jpeg_get_default_huffman_table(priv->huf_tables); picture->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW(JPEG, decoder); g_assert(picture->huf_table); huffman_table = picture->huf_table->param; memset(huffman_table, 0, sizeof(VAHuffmanTableBufferJPEG)); - for (i = 0; i < GST_JPEG_MAX_COMPONENTS; i++) { + for (i = 0; i < GST_JPEG_MAX_SCAN_COMPONENTS; i++) { memcpy(huffman_table->huffman_table[i].dc_bits, - jpeg_image->dc_huf_tables[i].huf_bits, + priv->huf_tables[i].huf_bits, 16); memcpy(huffman_table->huffman_table[i].dc_huffval, - jpeg_image->dc_huf_tables[i].huf_values, + priv->huf_tables[i].huf_values, 16); memcpy(huffman_table->huffman_table[i].ac_bits, - jpeg_image->ac_huf_tables[i].huf_bits, + priv->huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS + i].huf_bits, 16); memcpy(huffman_table->huffman_table[i].ac_huffval, - jpeg_image->ac_huf_tables[i].huf_values, + priv->huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS + i].huf_values, 256); } return TRUE; } static guint -get_max_horizontal_samples(GstJpegImage *jpeg) +get_max_horizontal_samples(GstJpegFrameHdr *frame_hdr) { guint i, max_factor = 0; - for (i = 0; i < jpeg->num_components; i++) { - if (jpeg->components[i].horizontal_factor > max_factor) - max_factor = jpeg->components[i].horizontal_factor; + for (i = 0; i < frame_hdr->num_components; i++) { + if (frame_hdr->components[i].horizontal_factor > max_factor) + max_factor = frame_hdr->components[i].horizontal_factor; } return max_factor; } static guint -get_max_vertical_samples(GstJpegImage *jpeg) +get_max_vertical_samples(GstJpegFrameHdr *frame_hdr) { guint i, max_factor = 0; - for (i = 0; i < jpeg->num_components; i++) { - if (jpeg->components[i].vertical_factor > max_factor) - max_factor = jpeg->components[i].vertical_factor; + for (i = 0; i < frame_hdr->num_components; i++) { + if (frame_hdr->components[i].vertical_factor > max_factor) + max_factor = frame_hdr->components[i].vertical_factor; } return max_factor; } -static gboolean -fill_slices( - GstVaapiDecoderJpeg *decoder, - GstVaapiPicture *picture, - GstJpegImage *jpeg_image -) -{ - VASliceParameterBufferJPEG *slice_param; - GstVaapiSlice *gst_slice; - int i; - const guint8 *sos_src; - guint32 sos_length; - guint total_h_samples, total_v_samples; - - while (gst_jpeg_get_left_size(jpeg_image)) { - sos_src = gst_jpeg_get_position(jpeg_image); - sos_length = gst_jpeg_skip_to_scan_end(jpeg_image); - if (!sos_length) - break; - gst_slice = GST_VAAPI_SLICE_NEW(JPEG, decoder, sos_src, sos_length); - slice_param = gst_slice->param; - slice_param->num_components = jpeg_image->current_scan.num_components; - for (i = 0; i < slice_param->num_components; i++) { - slice_param->components[i].component_id = jpeg_image->current_scan.components[i].component_selector; - slice_param->components[i].dc_selector = jpeg_image->current_scan.components[i].dc_selector; - slice_param->components[i].ac_selector = jpeg_image->current_scan.components[i].ac_selector; - } - slice_param->restart_interval = jpeg_image->restart_interval; - - if (jpeg_image->current_scan.num_components == 1) { /*non-interleaved*/ - slice_param->slice_horizontal_position = 0; - slice_param->slice_vertical_position = 0; - /* Y mcu numbers*/ - if (slice_param->components[0].component_id == jpeg_image->components[0].identifier) { - slice_param->num_mcus = (jpeg_image->width/8)*(jpeg_image->height/8); - } else { /*Cr, Cb mcu numbers*/ - slice_param->num_mcus = (jpeg_image->width/16)*(jpeg_image->height/16); - } - } else { /* interleaved */ - slice_param->slice_horizontal_position = 0; - slice_param->slice_vertical_position = 0; - total_v_samples = get_max_vertical_samples(jpeg_image); - total_h_samples = get_max_horizontal_samples(jpeg_image); - slice_param->num_mcus = ((jpeg_image->width + total_h_samples*8 - 1)/(total_h_samples*8)) * - ((jpeg_image->height + total_v_samples*8 -1)/(total_v_samples*8)); - } - - gst_vaapi_picture_add_slice(picture, gst_slice); - if (!gst_jpeg_parse_next_scan(jpeg_image)) { - break; - } - } - - if (picture->slices && picture->slices->len) - return TRUE; - return FALSE; -} - static GstVaapiDecoderStatus decode_picture( GstVaapiDecoderJpeg *decoder, + guint8 profile, guchar *buf, guint buf_size, GstClockTime pts @@ -355,29 +315,42 @@ decode_picture( { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstVaapiPicture *picture = NULL; + GstJpegFrameHdr *jpeg_frame_hdr = &priv->frame_hdr; GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; - GstJpegImage jpeg_image; GstJpegParserResult result; /* parse jpeg */ - memset(&jpeg_image, 0, sizeof(jpeg_image)); - result = gst_jpeg_parse_image(&jpeg_image, buf, buf_size); + memset(jpeg_frame_hdr, 0, sizeof(GstJpegFrameHdr)); + switch (profile) { + case GST_JPEG_MARKER_SOF_MIN: + jpeg_frame_hdr->profile = GST_JPEG_MARKER_SOF_MIN; + priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; + break; + default: + GST_WARNING("Jpeg profile was not supported."); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + + result = gst_jpeg_parse_frame_hdr(jpeg_frame_hdr, buf, buf_size, 0); if (result != GST_JPEG_PARSER_OK) { GST_ERROR("failed to parse image"); return get_status(result); } /* set info to va parameters in current picture*/ - priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; - priv->height = jpeg_image.height; - priv->width = jpeg_image.width; - + priv->height = jpeg_frame_hdr->height; + priv->width = jpeg_frame_hdr->width; + status = ensure_context(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { GST_ERROR("failed to reset context"); return status; } + if (priv->current_picture && + (status = decode_current_picture(decoder)) != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + picture = GST_VAAPI_PICTURE_NEW(JPEG, decoder); if (!picture) { GST_ERROR("failed to allocate picture"); @@ -386,36 +359,224 @@ decode_picture( gst_vaapi_picture_replace(&priv->current_picture, picture); gst_vaapi_picture_unref(picture); - if (!fill_picture(decoder, picture, &jpeg_image)) + if (!fill_picture(decoder, picture, jpeg_frame_hdr)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - if (!fill_quantization_table(decoder, picture, &jpeg_image)) { - GST_ERROR("failed to fill in quantization table"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - - if (!fill_huffman_table(decoder, picture, &jpeg_image)) { - GST_ERROR("failed to fill in huffman table"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - - if (!fill_slices(decoder, picture, &jpeg_image)) { - GST_ERROR("failed to fill in all scans"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - /* Update presentation time */ picture->pts = pts; return status; } +static GstVaapiDecoderStatus +decode_huffman_table( + GstVaapiDecoderJpeg *decoder, + guchar *buf, + guint buf_size +) +{ + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstJpegParserResult result; + + result = gst_jpeg_parse_huffman_table( + priv->huf_tables, + buf, buf_size, 0 + ); + if (result != GST_JPEG_PARSER_OK) { + GST_DEBUG("failed to parse Huffman table"); + return get_status(result); + } + priv->has_huf_table = TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_quant_table( + GstVaapiDecoderJpeg *decoder, + guchar *buf, + guint buf_size +) +{ + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstJpegParserResult result; + + result = gst_jpeg_parse_quant_table( + priv->quant_tables, + GST_JPEG_MAX_SCAN_COMPONENTS, + buf, buf_size, 0 + ); + if (result != GST_JPEG_PARSER_OK) { + GST_DEBUG("failed to parse quantization table"); + return get_status(result); + } + priv->has_quant_table = TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_restart_interval( + GstVaapiDecoderJpeg *decoder, + guchar *buf, + guint buf_size +) +{ + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstJpegParserResult result; + + result = gst_jpeg_parse_restart_interval( + &priv->mcu_restart, + buf, buf_size, 0 + ); + if (result != GST_JPEG_PARSER_OK) { + GST_DEBUG("failed to parse restart interval"); + return get_status(result); + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static gint32 +scan_to_end(const guint8 *start, guint32 size) +{ + const guint8 *pos = start, *end = start + size; + + for (; pos < end; ++pos) { + if (*pos != 0xFF) + continue; + while (*pos == 0xFF && pos + 1 < end) + ++pos; + if (*pos == 0x00 || *pos == 0xFF || + (*pos >= GST_JPEG_MARKER_RST_MIN && *pos <= GST_JPEG_MARKER_RST_MAX)) + continue; + break; + } + if (pos >= end) + return size; + return pos - start - 1; +} + +static gboolean +scan_to_next_scan(guint8 *data, guint32 size, + guint8 **scan, guint32 *scan_header_size, guint32 *scan_left_size) +{ + GList *seg_list = NULL; + gboolean ret = FALSE; + + if (!data || !size) + return FALSE; + + seg_list = gst_jpeg_parse(data, size, 0); + for (; seg_list; seg_list = seg_list->next) { + GstJpegTypeOffsetSize * const seg = seg_list->data; + if (seg->type != GST_JPEG_MARKER_SOS) + continue; + *scan = seg->offset + data; + *scan_header_size = seg->size; + *scan_left_size = size - seg->offset - seg->size; + ret = TRUE; + break; + } + g_list_free_full(seg_list, g_free); + return ret; +} + +static GstVaapiDecoderStatus +decode_scan( + GstVaapiDecoderJpeg *decoder, + guchar *scan, + guint scan_header_size, + guint scan_left_size) +{ + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiPicture *picture = priv->current_picture; + GstJpegParserResult result = GST_JPEG_PARSER_OK; + VASliceParameterBufferJPEG *slice_param; + GstVaapiSlice *gst_slice; + guint8 *mcu_start, *next_mark; + guint8 *buf_end = scan + scan_header_size + scan_left_size; + guint mcu_size; + guint total_h_samples, total_v_samples; + GstJpegScanHdr scan_hdr; + guint i; + + if (!picture) { + GST_ERROR ("There is no VAPicture before decoding scan."); + return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; + } + + if (!fill_quantization_table(decoder, picture)) { + GST_ERROR("Failed to fill in quantization table"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!fill_huffman_table(decoder, picture)) { + GST_ERROR("Failed to fill in huffman table"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + mcu_size = scan_left_size; + while (scan_left_size) { + memset(&scan_hdr, 0, sizeof(scan_hdr)); + result = gst_jpeg_parse_scan_hdr(&scan_hdr, scan, scan_header_size, 0); + if (result != GST_JPEG_PARSER_OK) { + GST_DEBUG("Jpeg parsed scan failed."); + return get_status(result); + } + mcu_start = scan + scan_header_size; + mcu_size = scan_to_end(mcu_start, scan_left_size); + + gst_slice = GST_VAAPI_SLICE_NEW(JPEG, decoder, mcu_start, mcu_size); + gst_vaapi_picture_add_slice(picture, gst_slice); + + slice_param = gst_slice->param; + slice_param->num_components = scan_hdr.num_components; + for (i = 0; i < scan_hdr.num_components; i++) { + slice_param->components[i].component_id = scan_hdr.components[i].component_selector; + slice_param->components[i].dc_selector = scan_hdr.components[i].dc_selector; + slice_param->components[i].ac_selector = scan_hdr.components[i].ac_selector; + } + slice_param->restart_interval = priv->mcu_restart; + if (scan_hdr.num_components == 1) { /*non-interleaved*/ + slice_param->slice_horizontal_position = 0; + slice_param->slice_vertical_position = 0; + /* Y mcu numbers*/ + if (slice_param->components[0].component_id == priv->frame_hdr.components[0].identifier) { + slice_param->num_mcus = (priv->frame_hdr.width/8)*(priv->frame_hdr.height/8); + } else { /*Cr, Cb mcu numbers*/ + slice_param->num_mcus = (priv->frame_hdr.width/16)*(priv->frame_hdr.height/16); + } + } else { /* interleaved */ + slice_param->slice_horizontal_position = 0; + slice_param->slice_vertical_position = 0; + total_v_samples = get_max_vertical_samples(&priv->frame_hdr); + total_h_samples = get_max_horizontal_samples(&priv->frame_hdr); + slice_param->num_mcus = ((priv->frame_hdr.width + total_h_samples*8 - 1)/(total_h_samples*8)) * + ((priv->frame_hdr.height + total_v_samples*8 -1)/(total_v_samples*8)); + } + + next_mark = mcu_start + mcu_size; + scan_left_size = buf_end - next_mark; + if (scan_left_size < 4) /* Mark_code(2-bytes) + header_length(2-bytes)*/ + break; + + if (!scan_to_next_scan(next_mark, scan_left_size, &scan, &scan_header_size, &scan_left_size)) + break; + } + + if (picture->slices && picture->slices->len) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; +} + static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) { - GstVaapiDecoderStatus status; + GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; GstClockTime pts; guchar *buf; guint buf_size; + GList *seg_list = NULL; + gboolean scan_found = FALSE; + GstJpegTypeOffsetSize *seg; buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); @@ -425,10 +586,53 @@ decode_buffer(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) pts = GST_BUFFER_TIMESTAMP(buffer); g_assert(GST_CLOCK_TIME_IS_VALID(pts)); - status = decode_picture(decoder, buf, buf_size, pts); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - return decode_current_picture(decoder); + priv->has_quant_table = FALSE; + priv->has_huf_table = FALSE; + priv->mcu_restart = 0; + + seg_list = gst_jpeg_parse(buf, buf_size, 0); + for (; seg_list && !scan_found; seg_list = seg_list->next) { + seg = seg_list->data; + g_assert(seg); + switch (seg->type) { + case GST_JPEG_MARKER_DHT: + status = decode_huffman_table(decoder, buf + seg->offset, seg->size); + break; + case GST_JPEG_MARKER_DAC: + GST_ERROR("unsupported arithmetic decoding"); + status = GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + break; + case GST_JPEG_MARKER_DQT: + status = decode_quant_table(decoder, buf + seg->offset, seg->size); + break; + case GST_JPEG_MARKER_DRI: + status = decode_restart_interval(decoder, buf + seg->offset, seg->size); + break; + case GST_JPEG_MARKER_SOS: + status = decode_scan(decoder, buf + seg->offset, seg->size, buf_size - seg->offset - seg->size); + scan_found = TRUE; + break; + default: + if (seg->type >= GST_JPEG_MARKER_SOF_MIN && + seg->type <= GST_JPEG_MARKER_SOF_MAX) + status = decode_picture(decoder, seg->type, buf + seg->offset, seg->size, pts); + else { + GST_WARNING("unsupported marker (0x%02x)", seg->type); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + break; + } + } + + /* clean seg_list */ + g_list_free_full(seg_list, g_free); + + if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) { + if (scan_found) + return decode_current_picture(decoder); + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } + return status; } GstVaapiDecoderStatus @@ -494,9 +698,15 @@ gst_vaapi_decoder_jpeg_init(GstVaapiDecoderJpeg *decoder) priv->width = 0; priv->height = 0; priv->current_picture = NULL; + priv->has_huf_table = FALSE; + priv->has_quant_table = FALSE; + priv->mcu_restart = 0; priv->is_opened = FALSE; priv->profile_changed = TRUE; priv->is_constructed = FALSE; + memset(&priv->frame_hdr, 0, sizeof(priv->frame_hdr)); + memset(priv->huf_tables, 0, sizeof(priv->huf_tables)); + memset(priv->quant_tables, 0, sizeof(priv->quant_tables)); } /** From 4c5cc7eff9137e9f0a4421f53e1bf4f02f42aebc Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Mon, 4 Jun 2012 15:52:19 +0800 Subject: [PATCH 0692/3781] jpeg: make gst_jpeg_parse() support multiple scans. gst_jpeg_parse() now gathers all scans available in the supplied buffer. A scan comprises of the scan header and any entropy-coded segments or restart marker following it. The size and offset to the associated data (ECS + RST segments) are append to a new GstJpegScanOffsetSize structure. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/codecparsers/gstjpegparser.c | 59 +++++++-- gst-libs/gst/codecparsers/gstjpegparser.h | 20 +++ gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 141 +++++++--------------- 3 files changed, 115 insertions(+), 105 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c index a56c3df1c5..ff7989c7ca 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -438,6 +438,41 @@ gst_jpeg_get_default_quantization_table (GstJpegQuantTable *quant_tables, guint sizeof(GstJpegQuantTable)); } +static gint32 +jpeg_scan_to_end (const guint8 *start, guint32 size) +{ + const guint8 *pos = start, *end = start + size; + + for (; pos < end; ++pos) { + if (*pos != 0xFF) + continue; + while (*pos == 0xFF && pos + 1 < end) + ++pos; + if (*pos == 0x00 || *pos == 0xFF || + (*pos >= GST_JPEG_MARKER_RST_MIN && *pos <= GST_JPEG_MARKER_RST_MAX)) + continue; + break; + } + if (pos >= end) + return size; + return pos - start - 1; +} + +static GstJpegTypeOffsetSize * +gst_jpeg_segment_new (guint8 marker, guint offset, gint size) +{ + GstJpegTypeOffsetSize *seg; + + if (GST_JPEG_MARKER_SOS == marker) + seg = g_malloc0 (sizeof (GstJpegScanOffsetSize)); + else + seg = g_malloc0 (sizeof (GstJpegTypeOffsetSize)); + seg->type = marker; + seg->offset = offset; + seg->size = size; + return seg; +} + GList * gst_jpeg_parse(const guint8 * data, gsize size, guint offset) { @@ -446,6 +481,8 @@ gst_jpeg_parse(const guint8 * data, gsize size, guint offset) guint16 header_length; GList *segments = NULL; GstJpegTypeOffsetSize *seg; + const guint8 *scan_start; + gint scan_size = 0; size -= offset; @@ -470,16 +507,24 @@ gst_jpeg_parse(const guint8 * data, gsize size, guint offset) gst_byte_reader_get_remaining (&bytes_reader) < header_length - 2) goto failed; - seg = g_malloc (sizeof (GstJpegTypeOffsetSize)); - seg->type = marker; - seg->offset = gst_byte_reader_get_pos(&bytes_reader) + offset; - seg->size = header_length - 2; + seg = gst_jpeg_segment_new (marker, + gst_byte_reader_get_pos(&bytes_reader) + offset, + header_length - 2); segments = g_list_prepend(segments, seg); gst_byte_reader_skip (&bytes_reader, header_length - 2); - /* parser should stop at first scan */ - if (seg->type == GST_JPEG_MARKER_SOS) - break; + if (seg->type == GST_JPEG_MARKER_SOS) { + GstJpegScanOffsetSize * const scan_seg = (GstJpegScanOffsetSize *)seg; + scan_start = gst_byte_reader_peek_data_unchecked (&bytes_reader); + scan_size = jpeg_scan_to_end (scan_start, + gst_byte_reader_get_remaining (&bytes_reader)); + if (scan_size <= 0) + break; + + scan_seg->data_offset = gst_byte_reader_get_pos (&bytes_reader) + offset; + scan_seg->data_size = scan_size; + gst_byte_reader_skip (&bytes_reader, scan_size); + } } return g_list_reverse (segments); diff --git a/gst-libs/gst/codecparsers/gstjpegparser.h b/gst-libs/gst/codecparsers/gstjpegparser.h index 34a33a2dae..c18be6cb12 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.h +++ b/gst-libs/gst/codecparsers/gstjpegparser.h @@ -59,6 +59,7 @@ typedef struct _GstJpegScanHdr GstJpegScanHdr; typedef struct _GstJpegFrameComponent GstJpegFrameComponent; typedef struct _GstJpegFrameHdr GstJpegFrameHdr; typedef struct _GstJpegTypeOffsetSize GstJpegTypeOffsetSize; +typedef struct _GstJpegScanOffsetSize GstJpegScanOffsetSize; /** * GstJpegParserResult: @@ -241,6 +242,25 @@ struct _GstJpegTypeOffsetSize gint size; }; +/** + * GstJpegScanOffsetSize: + * @header: The header info associated to the scan + * @data_offset: The offset to the first entropy-coded segment in bytes + * @data_size: The size in bytes of the scan data, including all ECS + * and RST segments, or -1 if the end was not found + * + * A structure that contains information on a scan. A scan comprises of the + * scan @header, and all entropy-coded segment (ECS) and restart marker (RST) + * associated to it. The header type MUST be set to @GST_JPEG_MARKER_SOS. + */ +struct _GstJpegScanOffsetSize +{ + GstJpegTypeOffsetSize header; + guint data_offset; + gint data_size; +}; + + /** * gst_jpeg_parse: * @data: The data to parse diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index cb083b325b..c1456edc9c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -433,66 +433,19 @@ decode_restart_interval( return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static gint32 -scan_to_end(const guint8 *start, guint32 size) -{ - const guint8 *pos = start, *end = start + size; - - for (; pos < end; ++pos) { - if (*pos != 0xFF) - continue; - while (*pos == 0xFF && pos + 1 < end) - ++pos; - if (*pos == 0x00 || *pos == 0xFF || - (*pos >= GST_JPEG_MARKER_RST_MIN && *pos <= GST_JPEG_MARKER_RST_MAX)) - continue; - break; - } - if (pos >= end) - return size; - return pos - start - 1; -} - -static gboolean -scan_to_next_scan(guint8 *data, guint32 size, - guint8 **scan, guint32 *scan_header_size, guint32 *scan_left_size) -{ - GList *seg_list = NULL; - gboolean ret = FALSE; - - if (!data || !size) - return FALSE; - - seg_list = gst_jpeg_parse(data, size, 0); - for (; seg_list; seg_list = seg_list->next) { - GstJpegTypeOffsetSize * const seg = seg_list->data; - if (seg->type != GST_JPEG_MARKER_SOS) - continue; - *scan = seg->offset + data; - *scan_header_size = seg->size; - *scan_left_size = size - seg->offset - seg->size; - ret = TRUE; - break; - } - g_list_free_full(seg_list, g_free); - return ret; -} - static GstVaapiDecoderStatus decode_scan( GstVaapiDecoderJpeg *decoder, - guchar *scan, + guchar *scan_header, guint scan_header_size, - guint scan_left_size) + guchar *scan_data, + guint scan_data_size) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstVaapiPicture *picture = priv->current_picture; GstJpegParserResult result = GST_JPEG_PARSER_OK; VASliceParameterBufferJPEG *slice_param; GstVaapiSlice *gst_slice; - guint8 *mcu_start, *next_mark; - guint8 *buf_end = scan + scan_header_size + scan_left_size; - guint mcu_size; guint total_h_samples, total_v_samples; GstJpegScanHdr scan_hdr; guint i; @@ -512,53 +465,40 @@ decode_scan( return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } - mcu_size = scan_left_size; - while (scan_left_size) { - memset(&scan_hdr, 0, sizeof(scan_hdr)); - result = gst_jpeg_parse_scan_hdr(&scan_hdr, scan, scan_header_size, 0); - if (result != GST_JPEG_PARSER_OK) { - GST_DEBUG("Jpeg parsed scan failed."); - return get_status(result); + memset(&scan_hdr, 0, sizeof(scan_hdr)); + result = gst_jpeg_parse_scan_hdr(&scan_hdr, scan_header, scan_header_size, 0); + if (result != GST_JPEG_PARSER_OK) { + GST_DEBUG("Jpeg parsed scan failed."); + return get_status(result); + } + + gst_slice = GST_VAAPI_SLICE_NEW(JPEG, decoder, scan_data, scan_data_size); + gst_vaapi_picture_add_slice(picture, gst_slice); + + slice_param = gst_slice->param; + slice_param->num_components = scan_hdr.num_components; + for (i = 0; i < scan_hdr.num_components; i++) { + slice_param->components[i].component_id = scan_hdr.components[i].component_selector; + slice_param->components[i].dc_selector = scan_hdr.components[i].dc_selector; + slice_param->components[i].ac_selector = scan_hdr.components[i].ac_selector; + } + slice_param->restart_interval = priv->mcu_restart; + if (scan_hdr.num_components == 1) { /*non-interleaved*/ + slice_param->slice_horizontal_position = 0; + slice_param->slice_vertical_position = 0; + /* Y mcu numbers*/ + if (slice_param->components[0].component_id == priv->frame_hdr.components[0].identifier) { + slice_param->num_mcus = (priv->frame_hdr.width/8)*(priv->frame_hdr.height/8); + } else { /*Cr, Cb mcu numbers*/ + slice_param->num_mcus = (priv->frame_hdr.width/16)*(priv->frame_hdr.height/16); } - mcu_start = scan + scan_header_size; - mcu_size = scan_to_end(mcu_start, scan_left_size); - - gst_slice = GST_VAAPI_SLICE_NEW(JPEG, decoder, mcu_start, mcu_size); - gst_vaapi_picture_add_slice(picture, gst_slice); - - slice_param = gst_slice->param; - slice_param->num_components = scan_hdr.num_components; - for (i = 0; i < scan_hdr.num_components; i++) { - slice_param->components[i].component_id = scan_hdr.components[i].component_selector; - slice_param->components[i].dc_selector = scan_hdr.components[i].dc_selector; - slice_param->components[i].ac_selector = scan_hdr.components[i].ac_selector; - } - slice_param->restart_interval = priv->mcu_restart; - if (scan_hdr.num_components == 1) { /*non-interleaved*/ - slice_param->slice_horizontal_position = 0; - slice_param->slice_vertical_position = 0; - /* Y mcu numbers*/ - if (slice_param->components[0].component_id == priv->frame_hdr.components[0].identifier) { - slice_param->num_mcus = (priv->frame_hdr.width/8)*(priv->frame_hdr.height/8); - } else { /*Cr, Cb mcu numbers*/ - slice_param->num_mcus = (priv->frame_hdr.width/16)*(priv->frame_hdr.height/16); - } - } else { /* interleaved */ - slice_param->slice_horizontal_position = 0; - slice_param->slice_vertical_position = 0; - total_v_samples = get_max_vertical_samples(&priv->frame_hdr); - total_h_samples = get_max_horizontal_samples(&priv->frame_hdr); - slice_param->num_mcus = ((priv->frame_hdr.width + total_h_samples*8 - 1)/(total_h_samples*8)) * - ((priv->frame_hdr.height + total_v_samples*8 -1)/(total_v_samples*8)); - } - - next_mark = mcu_start + mcu_size; - scan_left_size = buf_end - next_mark; - if (scan_left_size < 4) /* Mark_code(2-bytes) + header_length(2-bytes)*/ - break; - - if (!scan_to_next_scan(next_mark, scan_left_size, &scan, &scan_header_size, &scan_left_size)) - break; + } else { /* interleaved */ + slice_param->slice_horizontal_position = 0; + slice_param->slice_vertical_position = 0; + total_v_samples = get_max_vertical_samples(&priv->frame_hdr); + total_h_samples = get_max_horizontal_samples(&priv->frame_hdr); + slice_param->num_mcus = ((priv->frame_hdr.width + total_h_samples*8 - 1)/(total_h_samples*8)) * + ((priv->frame_hdr.height + total_v_samples*8 -1)/(total_v_samples*8)); } if (picture->slices && picture->slices->len) @@ -608,10 +548,15 @@ decode_buffer(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) case GST_JPEG_MARKER_DRI: status = decode_restart_interval(decoder, buf + seg->offset, seg->size); break; - case GST_JPEG_MARKER_SOS: - status = decode_scan(decoder, buf + seg->offset, seg->size, buf_size - seg->offset - seg->size); + case GST_JPEG_MARKER_SOS: { + GstJpegScanOffsetSize * const scan = (GstJpegScanOffsetSize *)seg; + status = decode_scan( + decoder, buf + scan->header.offset, scan->header.size, + buf + scan->data_offset, scan->data_size + ); scan_found = TRUE; break; + } default: if (seg->type >= GST_JPEG_MARKER_SOF_MIN && seg->type <= GST_JPEG_MARKER_SOF_MAX) From 90e6532fd35a526bd6242384b8f294f916942abf Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Mon, 4 Jun 2012 16:20:13 +0800 Subject: [PATCH 0693/3781] jpeg: add new GstJpegHuffmanTables structure. Add new GstJpegHuffmanTables helper structure to hold all possible AC/DC Huffman tables available to all components. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/codecparsers/gstjpegparser.c | 213 +++++++++++----------- gst-libs/gst/codecparsers/gstjpegparser.h | 32 ++-- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 16 +- 3 files changed, 137 insertions(+), 124 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c index ff7989c7ca..1febbed04e 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -131,105 +131,109 @@ default_quant_tables_zigzag[GST_JPEG_MAX_SCAN_COMPONENTS] = { GST_JPEG_MAX_SCAN_COMPONENTS...GST_JPEG_MAX_SCAN_COMPONENTS*2-1, AC huffman tables */ static const -GstJpegHuffmanTable default_huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2] = { - /* DC luma */ - { { 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b } +GstJpegHuffmanTables default_huf_tables = { + { + /* DC luma */ + { { 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b } + }, + /* DC chroma */ + { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b } + }, + /* DC chroma */ + { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b } + }, + { { 0x0 }, + { 0x0 } + } }, - /* DC chroma */ - { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b } - }, - /* DC chroma */ - { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b } - }, - { { 0 }, - { 0 } - }, - /* AC luma */ - { { 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, - 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d }, - { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa} - }, - /* AC chroma */ - { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77 }, - { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa } - }, - /* AC chroma */ - { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77 }, - { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa } - }, - { { 0 }, - { 0 } + { + /* AC luma */ + { { 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, + 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d }, + { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa} + }, + /* AC chroma */ + { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77 }, + { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa } + }, + /* AC chroma */ + { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77 }, + { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa } + }, + { { 0x00 }, + { 0x00 } + } } }; @@ -326,7 +330,7 @@ wrong_state: GstJpegParserResult gst_jpeg_parse_huffman_table ( - GstJpegHuffmanTable huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2], + GstJpegHuffmanTables *huf_tables, const guint8 * data, gsize size, guint offset) { GstByteReader bytes_reader = GST_BYTE_READER_INIT (data+offset, size-offset); @@ -346,9 +350,9 @@ gst_jpeg_parse_huffman_table ( CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, GST_JPEG_PARSER_BROKEN_DATA); if (is_dc) { - huf_table = &huf_tables[table_index]; + huf_table = &huf_tables->dc_tables[table_index]; } else { - huf_table = &huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS + table_index]; + huf_table = &huf_tables->ac_tables[table_index]; } READ_BYTES (&bytes_reader, huf_table->huf_bits, 16); value_count = 0; @@ -420,11 +424,12 @@ failed: } void -gst_jpeg_get_default_huffman_table (GstJpegHuffmanTable huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2]) +gst_jpeg_get_default_huffman_table (GstJpegHuffmanTables *huf_tables) { + g_assert(huf_tables); memcpy(huf_tables, - default_huf_tables, - sizeof(GstJpegHuffmanTable)*GST_JPEG_MAX_SCAN_COMPONENTS*2); + &default_huf_tables, + sizeof(GstJpegHuffmanTables)); } void diff --git a/gst-libs/gst/codecparsers/gstjpegparser.h b/gst-libs/gst/codecparsers/gstjpegparser.h index c18be6cb12..38523f23c3 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.h +++ b/gst-libs/gst/codecparsers/gstjpegparser.h @@ -54,6 +54,7 @@ G_BEGIN_DECLS typedef struct _GstJpegQuantTable GstJpegQuantTable; typedef struct _GstJpegHuffmanTable GstJpegHuffmanTable; +typedef struct _GstJpegHuffmanTables GstJpegHuffmanTables; typedef struct _GstJpegScanComponent GstJpegScanComponent; typedef struct _GstJpegScanHdr GstJpegScanHdr; typedef struct _GstJpegFrameComponent GstJpegFrameComponent; @@ -160,6 +161,20 @@ struct _GstJpegHuffmanTable guint8 huf_values[256]; }; +/** + * GstJpegHuffmanTables: + * @dc_tables: DC Huffman tables + * @ac_tables: AC Huffman tables + * + * Helper data structure that holds all AC/DC Huffman tables used to + * decode an image. + */ +struct _GstJpegHuffmanTables +{ + GstJpegHuffmanTable dc_tables[GST_JPEG_MAX_SCAN_COMPONENTS]; + GstJpegHuffmanTable ac_tables[GST_JPEG_MAX_SCAN_COMPONENTS]; +}; + /** * GstJpegScanComponent: * @component_selector: Scan component selector (Csj) @@ -343,17 +358,13 @@ GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTable *quan * * Parses the JPEG Huffman table structure members from @data. * - * Note: @huf_tables represents the user-allocated Huffman tables - * based on the number of scan components. That is, the parser writes - * the output Huffman table at the index specified by the Huffman - * table destination identifier (Th). The first array of - * Huffman tables are related - * to dc tables; The second array of - * of Huffman tables are related to ac tables. + * Note: @huf_tables represents the complete set of possible Huffman + * tables. However, the parser will only write to the Huffman table + * specified by the table destination identifier (Th). * * Returns: a #GstJpegParserResult */ -GstJpegParserResult gst_jpeg_parse_huffman_table (GstJpegHuffmanTable huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2], +GstJpegParserResult gst_jpeg_parse_huffman_table (GstJpegHuffmanTables *huf_tables, const guint8 * data, gsize size, guint offset); @@ -376,13 +387,10 @@ GstJpegParserResult gst_jpeg_parse_restart_interval (guint * interval, * gst_jpeg_get_default_huffman_table: * @huf_tables: (out): The default dc/ac hufman tables to fill in * - * DC huffman tables fill in the first 4 arrays. - * AC huffman tables fill in the last 4 arrays. - * * Returns: void */ void gst_jpeg_get_default_huffman_table ( - GstJpegHuffmanTable huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2]); + GstJpegHuffmanTables *huf_tables); /** * gst_jpeg_get_default_quantization_table: diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index c1456edc9c..fd03748ad5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -51,7 +51,7 @@ struct _GstVaapiDecoderJpegPrivate { guint height; GstVaapiPicture *current_picture; GstJpegFrameHdr frame_hdr; - GstJpegHuffmanTable huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS*2]; + GstJpegHuffmanTables huf_tables; GstJpegQuantTable quant_tables[GST_JPEG_MAX_SCAN_COMPONENTS]; gboolean has_huf_table; gboolean has_quant_table; @@ -257,7 +257,7 @@ fill_huffman_table( guint i; if (!priv->has_huf_table) - gst_jpeg_get_default_huffman_table(priv->huf_tables); + gst_jpeg_get_default_huffman_table(&priv->huf_tables); picture->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW(JPEG, decoder); g_assert(picture->huf_table); @@ -265,16 +265,16 @@ fill_huffman_table( memset(huffman_table, 0, sizeof(VAHuffmanTableBufferJPEG)); for (i = 0; i < GST_JPEG_MAX_SCAN_COMPONENTS; i++) { memcpy(huffman_table->huffman_table[i].dc_bits, - priv->huf_tables[i].huf_bits, + priv->huf_tables.dc_tables[i].huf_bits, 16); memcpy(huffman_table->huffman_table[i].dc_huffval, - priv->huf_tables[i].huf_values, + priv->huf_tables.dc_tables[i].huf_values, 16); memcpy(huffman_table->huffman_table[i].ac_bits, - priv->huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS + i].huf_bits, + priv->huf_tables.ac_tables[i].huf_bits, 16); memcpy(huffman_table->huffman_table[i].ac_huffval, - priv->huf_tables[GST_JPEG_MAX_SCAN_COMPONENTS + i].huf_values, + priv->huf_tables.ac_tables[i].huf_values, 256); } return TRUE; @@ -378,7 +378,7 @@ decode_huffman_table( GstJpegParserResult result; result = gst_jpeg_parse_huffman_table( - priv->huf_tables, + &priv->huf_tables, buf, buf_size, 0 ); if (result != GST_JPEG_PARSER_OK) { @@ -650,7 +650,7 @@ gst_vaapi_decoder_jpeg_init(GstVaapiDecoderJpeg *decoder) priv->profile_changed = TRUE; priv->is_constructed = FALSE; memset(&priv->frame_hdr, 0, sizeof(priv->frame_hdr)); - memset(priv->huf_tables, 0, sizeof(priv->huf_tables)); + memset(&priv->huf_tables, 0, sizeof(priv->huf_tables)); memset(priv->quant_tables, 0, sizeof(priv->quant_tables)); } From e61f4c444524b99958df5a68f3f40e230cb5d927 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 5 Jun 2012 10:10:22 +0800 Subject: [PATCH 0694/3781] codecparsers: jpeg: use U_READ_UINT*() wherever possible. Use GstByteReader *_unchecked() variants as much as possible. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/codecparsers/gstjpegparser.c | 52 ++++++++++++++--------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c index 1febbed04e..f7a7c32e6f 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -88,6 +88,15 @@ ensure_debug_category (void) memcpy(buf, vals, length); \ } G_STMT_END +#define U_READ_UINT8(reader, val) G_STMT_START { \ + (val) = gst_byte_reader_get_uint8_unchecked(reader); \ + } G_STMT_END + +#define U_READ_UINT16(reader, val) G_STMT_START { \ + (val) = gst_byte_reader_get_uint16_be_unchecked(reader); \ + } G_STMT_END + + static gboolean jpeg_parse_to_next_marker (GstByteReader * reader, guint8 * marker); @@ -268,18 +277,23 @@ gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * frame_hdr, u_int i; g_assert (frame_hdr && data && size); - READ_UINT8 (&bytes_reader, frame_hdr->sample_precision); - READ_UINT16 (&bytes_reader, frame_hdr->height); - READ_UINT16 (&bytes_reader, frame_hdr->width); - READ_UINT8 (&bytes_reader, frame_hdr->num_components); + + CHECK_FAILED (gst_byte_reader_get_remaining (&bytes_reader) >= 6, GST_JPEG_PARSER_ERROR); + U_READ_UINT8 (&bytes_reader, frame_hdr->sample_precision); + U_READ_UINT16 (&bytes_reader, frame_hdr->height); + U_READ_UINT16 (&bytes_reader, frame_hdr->width); + U_READ_UINT8 (&bytes_reader, frame_hdr->num_components); CHECK_FAILED (frame_hdr->num_components <= GST_JPEG_MAX_SCAN_COMPONENTS, GST_JPEG_PARSER_ERROR); + + CHECK_FAILED (gst_byte_reader_get_remaining(&bytes_reader) >= 3*frame_hdr->num_components, + GST_JPEG_PARSER_ERROR); for (i = 0; i < frame_hdr->num_components; i++) { - READ_UINT8 (&bytes_reader, frame_hdr->components[i].identifier); - READ_UINT8 (&bytes_reader, val); + U_READ_UINT8 (&bytes_reader, frame_hdr->components[i].identifier); + U_READ_UINT8 (&bytes_reader, val); frame_hdr->components[i].horizontal_factor = (val >> 4) & 0x0F; frame_hdr->components[i].vertical_factor = (val & 0x0F); - READ_UINT8 (&bytes_reader, frame_hdr->components[i].quant_table_selector); + U_READ_UINT8 (&bytes_reader, frame_hdr->components[i].quant_table_selector); CHECK_FAILED ((frame_hdr->components[i].horizontal_factor <= 4 && frame_hdr->components[i].vertical_factor <= 4 && frame_hdr->components[i].quant_table_selector < 4), @@ -287,9 +301,6 @@ gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * frame_hdr, } return GST_JPEG_PARSER_OK; -failed: - return GST_JPEG_PARSER_ERROR; - wrong_state: return result; } @@ -307,10 +318,13 @@ gst_jpeg_parse_scan_hdr (GstJpegScanHdr * scan_hdr, READ_UINT8 (&bytes_reader, scan_hdr->num_components); CHECK_FAILED (scan_hdr->num_components <= GST_JPEG_MAX_SCAN_COMPONENTS, GST_JPEG_PARSER_BROKEN_DATA); + + CHECK_FAILED (gst_byte_reader_get_remaining (&bytes_reader) >= 2*scan_hdr->num_components, + GST_JPEG_PARSER_ERROR); for (i = 0; i < scan_hdr->num_components; i++) { - READ_UINT8 (&bytes_reader, + U_READ_UINT8 (&bytes_reader, scan_hdr->components[i].component_selector); - READ_UINT8 (&bytes_reader, val); + U_READ_UINT8 (&bytes_reader, val); scan_hdr->components[i].dc_selector = (val >> 4) & 0x0F; scan_hdr->components[i].ac_selector = val & 0x0F; g_assert (scan_hdr->components[i].dc_selector < 4 && @@ -344,7 +358,7 @@ gst_jpeg_parse_huffman_table ( g_assert (huf_tables && data && size); while (gst_byte_reader_get_remaining (&bytes_reader)) { - READ_UINT8 (&bytes_reader, tmp_val); + U_READ_UINT8 (&bytes_reader, tmp_val); is_dc = !((tmp_val >> 4) & 0x0F); table_index = (tmp_val & 0x0F); CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, @@ -383,26 +397,26 @@ gst_jpeg_parse_quant_table ( g_assert (quant_tables && num_quant_tables && data && size); while (gst_byte_reader_get_remaining (&bytes_reader)) { - READ_UINT8 (&bytes_reader, val); + U_READ_UINT8 (&bytes_reader, val); table_index = (val & 0x0f); CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS && table_index < num_quant_tables, GST_JPEG_PARSER_BROKEN_DATA); quant_table = &quant_tables[table_index]; quant_table->quant_precision = ((val >> 4) & 0x0f); + + CHECK_FAILED (gst_byte_reader_get_remaining(&bytes_reader) >= GST_JPEG_MAX_QUANT_ELEMENTS * (1 + !!quant_table->quant_precision), + GST_JPEG_PARSER_BROKEN_DATA); for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) { if (!quant_table->quant_precision) { /* 8-bit values */ - READ_UINT8(&bytes_reader, val); + U_READ_UINT8 (&bytes_reader, val); quant_table->quant_table[i] = val; } else { /* 16-bit values */ - READ_UINT16(&bytes_reader, quant_table->quant_table[i]); + U_READ_UINT16 (&bytes_reader, quant_table->quant_table[i]); } } } return GST_JPEG_PARSER_OK; -failed: - return GST_JPEG_PARSER_ERROR; - wrong_state: return result; } From 326a229636a3444d08a933e523683d9fcb368bcb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Jun 2012 16:06:47 +0200 Subject: [PATCH 0695/3781] codecparsers: jpeg: track valid quantization and Huffman tables. Add valid flag to GstJpegQuantTable and GstJpegHuffmanTable so that to determine whether a table actually changed since the last user synchronization point. That way, this makes it possible for some hardware accelerated decoding solution to upload only those tables that changed. --- gst-libs/gst/codecparsers/gstjpegparser.c | 115 +++++++++++----------- gst-libs/gst/codecparsers/gstjpegparser.h | 50 +++++++--- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 22 ++--- 3 files changed, 104 insertions(+), 83 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c index f7a7c32e6f..35187c4101 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -101,37 +101,39 @@ static gboolean jpeg_parse_to_next_marker (GstByteReader * reader, guint8 * marker); /* CCITT T.81, Annex K.1 Quantization tables for luminance and chrominance components */ -/* only for 8-bit per sample image*/ -static const GstJpegQuantTable -default_quant_tables_zigzag[GST_JPEG_MAX_SCAN_COMPONENTS] = { - /* luma */ - {0, { 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, - 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, - 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, - 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, - 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, - 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, - 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, - 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63 } }, - /* chroma */ - {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 } }, - /* chroma */ - {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 } }, - {0, } +/* only for 8-bit per sample image */ +static const GstJpegQuantTables +default_quant_tables_zigzag = { + .quant_tables = { + /* luma */ + {0, { 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, + 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, + 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, + 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, + 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, + 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, + 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, + 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63 }, TRUE }, + /* chroma */ + {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 }, TRUE }, + /* chroma */ + {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 }, TRUE }, + {0, } + } }; /* Table K.3: typical Huffman tables for 8-bit precision luminance and chrominance */ @@ -141,30 +143,33 @@ GST_JPEG_MAX_SCAN_COMPONENTS...GST_JPEG_MAX_SCAN_COMPONENTS*2-1, AC huffman tabl */ static const GstJpegHuffmanTables default_huf_tables = { - { + .dc_tables = { /* DC luma */ { { 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b } + 0x08, 0x09, 0x0a, 0x0b }, + TRUE }, /* DC chroma */ { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b } + 0x08, 0x09, 0x0a, 0x0b }, + TRUE }, /* DC chroma */ { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b } + 0x08, 0x09, 0x0a, 0x0b }, + TRUE }, { { 0x0 }, { 0x0 } } }, - { + .ac_tables = { /* AC luma */ { { 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d }, @@ -188,7 +193,8 @@ GstJpegHuffmanTables default_huf_tables = { 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa} + 0xf9, 0xfa}, + TRUE }, /* AC chroma */ { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, @@ -213,7 +219,8 @@ GstJpegHuffmanTables default_huf_tables = { 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa } + 0xf9, 0xfa }, + TRUE }, /* AC chroma */ { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, @@ -238,7 +245,8 @@ GstJpegHuffmanTables default_huf_tables = { 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa } + 0xf9, 0xfa }, + TRUE }, { { 0x00 }, { 0x00 } @@ -373,6 +381,7 @@ gst_jpeg_parse_huffman_table ( for (i = 0; i < 16; i++) value_count += huf_table->huf_bits[i]; READ_BYTES (&bytes_reader, huf_table->huf_values, value_count); + huf_table->valid = TRUE; } return GST_JPEG_PARSER_OK; @@ -385,7 +394,7 @@ wrong_state: GstJpegParserResult gst_jpeg_parse_quant_table ( - GstJpegQuantTable *quant_tables, guint num_quant_tables, + GstJpegQuantTables *quant_tables, const guint8 * data, gsize size, guint offset) { GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); @@ -395,13 +404,13 @@ gst_jpeg_parse_quant_table ( guint8 table_index; guint i; - g_assert (quant_tables && num_quant_tables && data && size); + g_assert (quant_tables && data && size); while (gst_byte_reader_get_remaining (&bytes_reader)) { U_READ_UINT8 (&bytes_reader, val); table_index = (val & 0x0f); - CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS && table_index < num_quant_tables, + CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, GST_JPEG_PARSER_BROKEN_DATA); - quant_table = &quant_tables[table_index]; + quant_table = &quant_tables->quant_tables[table_index]; quant_table->quant_precision = ((val >> 4) & 0x0f); CHECK_FAILED (gst_byte_reader_get_remaining(&bytes_reader) >= GST_JPEG_MAX_QUANT_ELEMENTS * (1 + !!quant_table->quant_precision), @@ -414,6 +423,7 @@ gst_jpeg_parse_quant_table ( U_READ_UINT16 (&bytes_reader, quant_table->quant_table[i]); } } + quant_table->valid = TRUE; } return GST_JPEG_PARSER_OK; @@ -438,23 +448,18 @@ failed: } void -gst_jpeg_get_default_huffman_table (GstJpegHuffmanTables *huf_tables) +gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables *huf_tables) { - g_assert(huf_tables); - memcpy(huf_tables, - &default_huf_tables, - sizeof(GstJpegHuffmanTables)); + g_assert (huf_tables); + + memcpy (huf_tables, &default_huf_tables, sizeof (GstJpegHuffmanTables)); } void -gst_jpeg_get_default_quantization_table (GstJpegQuantTable *quant_tables, guint num_quant_tables) +gst_jpeg_get_default_quantization_tables (GstJpegQuantTables *quant_tables) { - int i = 1; - g_assert(quant_tables && num_quant_tables); - for (i = 0; i < num_quant_tables && i < GST_JPEG_MAX_SCAN_COMPONENTS; i++) - memcpy(&quant_tables[i], - &default_quant_tables_zigzag[i], - sizeof(GstJpegQuantTable)); + g_assert (quant_tables); + memcpy (quant_tables, &default_quant_tables_zigzag, sizeof (GstJpegQuantTables)); } static gint32 diff --git a/gst-libs/gst/codecparsers/gstjpegparser.h b/gst-libs/gst/codecparsers/gstjpegparser.h index 38523f23c3..a3f2b858f3 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.h +++ b/gst-libs/gst/codecparsers/gstjpegparser.h @@ -53,6 +53,7 @@ G_BEGIN_DECLS #define GST_JPEG_MAX_QUANT_ELEMENTS 64 typedef struct _GstJpegQuantTable GstJpegQuantTable; +typedef struct _GstJpegQuantTables GstJpegQuantTables; typedef struct _GstJpegHuffmanTable GstJpegHuffmanTable; typedef struct _GstJpegHuffmanTables GstJpegHuffmanTables; typedef struct _GstJpegScanComponent GstJpegScanComponent; @@ -139,6 +140,8 @@ typedef enum { * GstJpegQuantTable: * @quant_precision: Quantization table element precision (Pq) * @quant_table: Quantization table elements (Qk) + * @valid: If the quantization table is valid, which means it has + * already been parsed * * Quantization table. */ @@ -146,12 +149,27 @@ struct _GstJpegQuantTable { guint8 quant_precision; guint16 quant_table[GST_JPEG_MAX_QUANT_ELEMENTS]; + gboolean valid; +}; + +/** + * GstJpegQuantTables: + * @quant_tables: All quantization tables + * + * Helper data structure that holds all quantization tables used to + * decode an image. + */ +struct _GstJpegQuantTables +{ + GstJpegQuantTable quant_tables[GST_JPEG_MAX_SCAN_COMPONENTS]; }; /** * GstJpegHuffmanTable: * @huf_bits: Number of Huffman codes of length i + 1 (Li) * @huf_vales: Value associated with each Huffman code (Vij) + * @valid: If the Huffman table is valid, which means it has already + * been parsed * * Huffman table. */ @@ -159,6 +177,7 @@ struct _GstJpegHuffmanTable { guint8 huf_bits[16]; guint8 huf_values[256]; + gboolean valid; }; /** @@ -334,17 +353,15 @@ GstJpegParserResult gst_jpeg_parse_scan_hdr (GstJpegScanHdr * hdr, * * Parses the JPEG quantization table structure members from @data. * - * Note: @quant_tables represents the user-allocated quantization - * tables based on the number of scan components. That is, the parser - * writes the output quantization table at the index specified by the - * quantization table destination identifier (Tq). So, the array of - * quantization tables shall be large enough to hold the table for the - * last component. + * Note: @quant_tables represents the complete set of possible + * quantization tables. However, the parser will only write to the + * quantization table specified by the table destination identifier + * (Tq). While doing so, the @valid flag of the specified quantization + * table will also be set to %TRUE. * * Returns: a #GstJpegParserResult */ -GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTable *quant_tables, - guint num_quant_tables, +GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTables *quant_tables, const guint8 * data, gsize size, guint offset); @@ -360,7 +377,9 @@ GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTable *quan * * Note: @huf_tables represents the complete set of possible Huffman * tables. However, the parser will only write to the Huffman table - * specified by the table destination identifier (Th). + * specified by the table destination identifier (Th). While doing so, + * the @valid flag of the specified Huffman table will also be set to + * %TRUE; * * Returns: a #GstJpegParserResult */ @@ -384,24 +403,23 @@ GstJpegParserResult gst_jpeg_parse_restart_interval (guint * interval, guint offset); /** - * gst_jpeg_get_default_huffman_table: - * @huf_tables: (out): The default dc/ac hufman tables to fill in + * gst_jpeg_get_default_huffman_tables: + * @huf_tables: (out): The default DC/AC Huffman tables to fill in * - * Returns: void + * Fills in @huf_tables with the default AC/DC Huffman tables, as + * specified by the JPEG standard. */ -void gst_jpeg_get_default_huffman_table ( +void gst_jpeg_get_default_huffman_tables ( GstJpegHuffmanTables *huf_tables); /** * gst_jpeg_get_default_quantization_table: * @quant_tables: (out): The default luma/chroma quant-tables in zigzag mode - * @num_quant_tables: The number of allocated quantization tables in @quant_tables * * Fills in @quant_tables with the default quantization tables, as * specified by the JPEG standard. */ -void gst_jpeg_get_default_quantization_table (GstJpegQuantTable *quant_tables, - guint num_quant_tables); +void gst_jpeg_get_default_quantization_tables (GstJpegQuantTables *quant_tables); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index fd03748ad5..a47791189c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -52,7 +52,7 @@ struct _GstVaapiDecoderJpegPrivate { GstVaapiPicture *current_picture; GstJpegFrameHdr frame_hdr; GstJpegHuffmanTables huf_tables; - GstJpegQuantTable quant_tables[GST_JPEG_MAX_SCAN_COMPONENTS]; + GstJpegQuantTables quant_tables; gboolean has_huf_table; gboolean has_quant_table; guint mcu_restart; @@ -225,22 +225,24 @@ fill_quantization_table( guint i, j; if (!priv->has_quant_table) - gst_jpeg_get_default_quantization_table(priv->quant_tables, GST_JPEG_MAX_SCAN_COMPONENTS); + gst_jpeg_get_default_quantization_tables(&priv->quant_tables); picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(JPEG, decoder); g_assert(picture->iq_matrix); iq_matrix = picture->iq_matrix->param; memset(iq_matrix, 0, sizeof(VAIQMatrixBufferJPEG)); for (i = 0; i < GST_JPEG_MAX_SCAN_COMPONENTS; i++) { - iq_matrix->precision[i] = priv->quant_tables[i].quant_precision; + GstJpegQuantTable * const quant_table = + &priv->quant_tables.quant_tables[i]; + iq_matrix->precision[i] = quant_table->quant_precision; if (iq_matrix->precision[i] == 0) /* 8-bit values */ for (j = 0; j < GST_JPEG_MAX_QUANT_ELEMENTS; j++) { iq_matrix->quantiser_matrix[i][j] = - priv->quant_tables[i].quant_table[j]; + quant_table->quant_table[j]; } else memcpy(iq_matrix->quantiser_matrix[i], - priv->quant_tables[i].quant_table, + quant_table->quant_table, 128); } return TRUE; @@ -257,7 +259,7 @@ fill_huffman_table( guint i; if (!priv->has_huf_table) - gst_jpeg_get_default_huffman_table(&priv->huf_tables); + gst_jpeg_get_default_huffman_tables(&priv->huf_tables); picture->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW(JPEG, decoder); g_assert(picture->huf_table); @@ -399,11 +401,7 @@ decode_quant_table( GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstJpegParserResult result; - result = gst_jpeg_parse_quant_table( - priv->quant_tables, - GST_JPEG_MAX_SCAN_COMPONENTS, - buf, buf_size, 0 - ); + result = gst_jpeg_parse_quant_table(&priv->quant_tables, buf, buf_size, 0); if (result != GST_JPEG_PARSER_OK) { GST_DEBUG("failed to parse quantization table"); return get_status(result); @@ -651,7 +649,7 @@ gst_vaapi_decoder_jpeg_init(GstVaapiDecoderJpeg *decoder) priv->is_constructed = FALSE; memset(&priv->frame_hdr, 0, sizeof(priv->frame_hdr)); memset(&priv->huf_tables, 0, sizeof(priv->huf_tables)); - memset(priv->quant_tables, 0, sizeof(priv->quant_tables)); + memset(&priv->quant_tables, 0, sizeof(priv->quant_tables)); } /** From 4e1a3543404c60e0f1cfc48d2284720cd3bea67a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 25 Jun 2012 17:10:49 +0200 Subject: [PATCH 0696/3781] jpeg: update to current VA/JPEG decoding API. --- configure.ac | 4 +- gst-libs/gst/vaapi/gstvaapicompat.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 86 +++++++++++++---------- 3 files changed, 54 insertions(+), 37 deletions(-) diff --git a/configure.ac b/configure.ac index 4d17ab7ea7..7efaaa0fb4 100644 --- a/configure.ac +++ b/configure.ac @@ -414,9 +414,11 @@ AC_CACHE_CHECK([for JPEG decoding API], saved_LIBS="$LIBS" LIBS="$CFLAGS $LIBVA_LIBS" AC_TRY_COMPILE( - [#include ], + [#include + #include ] [VAPictureParameterBufferJPEG pic_param; VASliceParameterBufferJPEG slice_param; + VAHuffmanTableBufferJPEG huffman_table; VAIQMatrixBufferJPEG iq_matrix;], [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=1], [ac_cv_have_jpeg_decoding_api="no"] diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 9b4da516b8..9ff4f3bca0 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -94,6 +94,7 @@ typedef struct _VASliceParameterBufferBase { /* Compatibility glue with VA-API 0.34 */ #if VA_CHECK_VERSION(0,34,0) # include +# include #endif #endif /* GST_VAAPI_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index a47791189c..d798f0d0a0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -27,6 +27,7 @@ #include "sysdeps.h" #include #include +#include "gstvaapicompat.h" #include "gstvaapidecoder_jpeg.h" #include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" @@ -95,7 +96,6 @@ gst_vaapi_decoder_jpeg_close(GstVaapiDecoderJpeg *decoder) priv->height = 0; priv->is_opened = FALSE; priv->profile_changed = TRUE; - priv->is_constructed = FALSE; } static gboolean @@ -191,10 +191,9 @@ fill_picture( g_assert(pic_param); memset(pic_param, 0, sizeof(VAPictureParameterBufferJPEG)); - pic_param->type = jpeg_frame_hdr->profile; pic_param->sample_precision = jpeg_frame_hdr->sample_precision; - pic_param->image_width = jpeg_frame_hdr->width; - pic_param->image_height = jpeg_frame_hdr->height; + pic_param->picture_width = jpeg_frame_hdr->width; + pic_param->picture_height = jpeg_frame_hdr->height; /* XXX: ROI + rotation */ @@ -222,7 +221,7 @@ fill_quantization_table( { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; VAIQMatrixBufferJPEG *iq_matrix; - guint i, j; + guint i, j, num_tables; if (!priv->has_quant_table) gst_jpeg_get_default_quantization_tables(&priv->quant_tables); @@ -230,20 +229,23 @@ fill_quantization_table( picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(JPEG, decoder); g_assert(picture->iq_matrix); iq_matrix = picture->iq_matrix->param; - memset(iq_matrix, 0, sizeof(VAIQMatrixBufferJPEG)); - for (i = 0; i < GST_JPEG_MAX_SCAN_COMPONENTS; i++) { + + 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->precision[i] = quant_table->quant_precision; - if (iq_matrix->precision[i] == 0) /* 8-bit values */ - for (j = 0; j < GST_JPEG_MAX_QUANT_ELEMENTS; j++) { - iq_matrix->quantiser_matrix[i][j] = - quant_table->quant_table[j]; - } - else - memcpy(iq_matrix->quantiser_matrix[i], - quant_table->quant_table, - 128); + + iq_matrix->load_quantiser_table[i] = quant_table->valid; + if (!iq_matrix->load_quantiser_table[i]) + continue; + + g_assert(quant_table->quant_precision == 0); + 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 TRUE; } @@ -255,8 +257,9 @@ fill_huffman_table( ) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstJpegHuffmanTables * const huf_tables = &priv->huf_tables; VAHuffmanTableBufferJPEG *huffman_table; - guint i; + guint i, num_tables; if (!priv->has_huf_table) gst_jpeg_get_default_huffman_tables(&priv->huf_tables); @@ -264,20 +267,28 @@ fill_huffman_table( picture->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW(JPEG, decoder); g_assert(picture->huf_table); huffman_table = picture->huf_table->param; - memset(huffman_table, 0, sizeof(VAHuffmanTableBufferJPEG)); - for (i = 0; i < GST_JPEG_MAX_SCAN_COMPONENTS; i++) { - memcpy(huffman_table->huffman_table[i].dc_bits, - priv->huf_tables.dc_tables[i].huf_bits, - 16); - memcpy(huffman_table->huffman_table[i].dc_huffval, - priv->huf_tables.dc_tables[i].huf_values, - 16); - memcpy(huffman_table->huffman_table[i].ac_bits, - priv->huf_tables.ac_tables[i].huf_bits, - 16); - memcpy(huffman_table->huffman_table[i].ac_huffval, - priv->huf_tables.ac_tables[i].huf_values, - 256); + + 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)); } return TRUE; } @@ -476,16 +487,19 @@ decode_scan( slice_param = gst_slice->param; slice_param->num_components = scan_hdr.num_components; for (i = 0; i < scan_hdr.num_components; i++) { - slice_param->components[i].component_id = scan_hdr.components[i].component_selector; - slice_param->components[i].dc_selector = scan_hdr.components[i].dc_selector; - slice_param->components[i].ac_selector = scan_hdr.components[i].ac_selector; + 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; if (scan_hdr.num_components == 1) { /*non-interleaved*/ slice_param->slice_horizontal_position = 0; slice_param->slice_vertical_position = 0; /* Y mcu numbers*/ - if (slice_param->components[0].component_id == priv->frame_hdr.components[0].identifier) { + if (slice_param->components[0].component_selector == priv->frame_hdr.components[0].identifier) { slice_param->num_mcus = (priv->frame_hdr.width/8)*(priv->frame_hdr.height/8); } else { /*Cr, Cb mcu numbers*/ slice_param->num_mcus = (priv->frame_hdr.width/16)*(priv->frame_hdr.height/16); From a9bd8400db3b786376c18321ee1e41895c3e7753 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 25 Jun 2012 17:25:44 +0200 Subject: [PATCH 0697/3781] Fix build with recent GStreamer stack. --- gst-libs/gst/vaapi/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 394e52a772..b269193d04 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -24,6 +24,7 @@ libgstvaapi_libs = \ $(GST_BASE_LIBS) \ $(GST_BASEVIDEO_LIBS) \ $(GST_LIBS) \ + $(GST_VIDEO_LIBS) \ $(LIBVA_LIBS) \ $(NULL) From 86b02639ee50cf3691b20aed4bddd50b681b4495 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Jun 2012 11:03:25 +0200 Subject: [PATCH 0698/3781] configure: disable FFmpeg-based decoders. FFmpeg decoders are still available through the --enable-ffmpeg option but are no longer maintained. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 7efaaa0fb4..db933ab536 100644 --- a/configure.ac +++ b/configure.ac @@ -101,8 +101,8 @@ AC_ARG_ENABLE(vaapisink-glx, AC_ARG_ENABLE(ffmpeg, AC_HELP_STRING([--enable-ffmpeg], - [enable bitstream parsing from FFmpeg @<:@default=yes@:>@]), - [], [enable_ffmpeg="yes"]) + [enable bitstream parsing from FFmpeg @<:@default=no@:>@]), + [], [enable_ffmpeg="no"]) AC_ARG_ENABLE(codecparsers, AC_HELP_STRING([--enable-codecparsers], From e0fac751f67c82a4f74cb8e2198136f4ca6f5f7c Mon Sep 17 00:00:00 2001 From: Yan Yin Date: Mon, 25 Jun 2012 16:07:55 +0800 Subject: [PATCH 0699/3781] vaapiplugin: fix build when compiling without GLX. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipluginutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 782304bf82..168ae1ffe9 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -29,7 +29,7 @@ #include -#ifdef USE_VAAPI_GLX +#if USE_VAAPI_GLX #include #else #include From c5d56a019f8d55be8d76c02086236c28050d9ca1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Jun 2012 13:34:39 +0200 Subject: [PATCH 0700/3781] NEWS: updates. --- NEWS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 05c54caf33..f7e305e6b6 100644 --- a/NEWS +++ b/NEWS @@ -6,7 +6,9 @@ Copyright (C) 2011 Collabora Version 0.3.7 - DD.Apr.2012 * Fix vaapidecode to report unsupported codec profiles * Fix MPEG-2 decoding of streams with extra slice() information -* Fix MPEG-2 decoding of High profile streams compatible with Main profile +* Map MPEG-2 compatible High profile streams to Main profile +* Map MPEG-4 Simple Scalable profile streams to Advanced Simple (Feng Yuan) +* Fix various MPEG-4 decoding bugs (timestamps, reference frames) (Feng Yuan) * Don't forcibly resize user provided X windows (Holger Kaelberer) * Recalculate render rect only if caps are negotiated (Holger Kaelberer) From a13941ca1898ebe80224d9521d425f9ac4b26437 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Jun 2012 14:46:40 +0200 Subject: [PATCH 0701/3781] 0.3.7. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index f7e305e6b6..558c85c731 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2012-04-DD +gst-vaapi NEWS -- summary of changes. 2012-06-26 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora -Version 0.3.7 - DD.Apr.2012 +Version 0.3.7 - 26.Jun.2012 * Fix vaapidecode to report unsupported codec profiles * Fix MPEG-2 decoding of streams with extra slice() information * Map MPEG-2 compatible High profile streams to Main profile diff --git a/configure.ac b/configure.ac index db933ab536..8b47a2155a 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) m4_define([gst_vaapi_micro_version], [7]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 23c4f9616d50325efc68a412f9cc77047a77d0e8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Jun 2012 15:02:44 +0200 Subject: [PATCH 0702/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 8b47a2155a..4bfd64f1bf 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [3]) -m4_define([gst_vaapi_micro_version], [7]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [8]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 251d53fac63f0a79ebe2639046fa7c3ad3cce1c0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Jun 2012 15:04:58 +0200 Subject: [PATCH 0703/3781] NEWS: updates. --- NEWS | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 558c85c731..6f0bb8859a 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,11 @@ -gst-vaapi NEWS -- summary of changes. 2012-06-26 +gst-vaapi NEWS -- summary of changes. 2012-07-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora +Version 0.3.8 - DD.Jul.2012 +* Disable FFmpeg-based decoders by default + Version 0.3.7 - 26.Jun.2012 * Fix vaapidecode to report unsupported codec profiles * Fix MPEG-2 decoding of streams with extra slice() information From 06be1afea60533400a390c228292bcab28885b43 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Jun 2012 15:18:53 +0200 Subject: [PATCH 0704/3781] jpeg: fix build with VA-API < 0.32.0. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index f93e628a23..7536c446ed 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -92,9 +92,11 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, "video/x-wmv, wmvversion=3, format=(fourcc)WVC1", "advanced" }, +#if VA_CHECK_VERSION(0,32,0) { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline, "image/jpeg", "baseline" }, +#endif { 0, } }; From c7587e87dd26294b0e02fb936db4e24bb977f98d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 16 Jul 2012 16:24:04 +0200 Subject: [PATCH 0705/3781] jpeg: fix configure check for VA/JPEG decoding API. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4bfd64f1bf..134171aa65 100644 --- a/configure.ac +++ b/configure.ac @@ -415,7 +415,7 @@ AC_CACHE_CHECK([for JPEG decoding API], LIBS="$CFLAGS $LIBVA_LIBS" AC_TRY_COMPILE( [#include - #include ] + #include ], [VAPictureParameterBufferJPEG pic_param; VASliceParameterBufferJPEG slice_param; VAHuffmanTableBufferJPEG huffman_table; From 8f93bbc93786a5964d4d36fe5053334af597a593 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 16 Jul 2012 17:35:19 +0200 Subject: [PATCH 0706/3781] codecparsers: jpeg: tweak parser API. ... to allow for more consistent parsing API among various codec parsers. In particular, drop use of GList. --- gst-libs/gst/codecparsers/gstjpegparser.c | 809 +++++++++++----------- gst-libs/gst/codecparsers/gstjpegparser.h | 146 ++-- 2 files changed, 469 insertions(+), 486 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c index 35187c4101..49f80742f6 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -1,7 +1,7 @@ /* - * gstjpegparser.c - JPEG parser for baseline + * gstjpegparser.c - JPEG parser * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -19,10 +19,9 @@ * Boston, MA 02110-1301 USA */ -#include "gstjpegparser.h" - #include #include +#include "gstjpegparser.h" #ifndef GST_DISABLE_GST_DEBUG @@ -52,28 +51,15 @@ ensure_debug_category (void) #define DEBUG_PRINT_COMMENT 0 -#define CHECK_FAILED(exp, ret) G_STMT_START { \ - if (!(exp)) { \ - result = ret; \ - goto wrong_state; \ - } \ - } G_STMT_END - -#define JPEG_RESULT_CHECK(result) G_STMT_START { \ - if ((result) != GST_JPEG_PARSER_OK) { \ - goto wrong_state; \ - } \ - } G_STMT_END - #define READ_UINT8(reader, val) G_STMT_START { \ - if (!gst_byte_reader_get_uint8 ((reader), &(val))) { \ + if (!gst_byte_reader_get_uint8 ((reader), &(val))) { \ GST_WARNING ("failed to read uint8"); \ goto failed; \ } \ } G_STMT_END #define READ_UINT16(reader, val) G_STMT_START { \ - if (!gst_byte_reader_get_uint16_be ((reader), &(val))) { \ + if (!gst_byte_reader_get_uint16_be ((reader), &(val))) { \ GST_WARNING ("failed to read uint16"); \ goto failed; \ } \ @@ -81,11 +67,11 @@ ensure_debug_category (void) #define READ_BYTES(reader, buf, length) G_STMT_START { \ const guint8 *vals; \ - if (!gst_byte_reader_get_data(reader, length, &vals)) { \ - GST_WARNING("failed to read bytes, size:%d", length); \ + if (!gst_byte_reader_get_data (reader, length, &vals)) { \ + GST_WARNING ("failed to read bytes, size:%d", length); \ goto failed; \ } \ - memcpy(buf, vals, length); \ + memcpy (buf, vals, length); \ } G_STMT_END #define U_READ_UINT8(reader, val) G_STMT_START { \ @@ -97,464 +83,473 @@ ensure_debug_category (void) } G_STMT_END -static gboolean jpeg_parse_to_next_marker (GstByteReader * reader, - guint8 * marker); - /* CCITT T.81, Annex K.1 Quantization tables for luminance and chrominance components */ /* only for 8-bit per sample image */ -static const GstJpegQuantTables -default_quant_tables_zigzag = { +/* *INDENT-OFF* */ +static const GstJpegQuantTables default_quant_tables_zigzag = { .quant_tables = { /* luma */ - {0, { 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, - 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, - 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, - 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, - 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, - 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, - 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, - 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63 }, TRUE }, + {0, {0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, + 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, + 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, + 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, + 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, + 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, + 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, + 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63}, TRUE}, /* chroma */ - {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 }, TRUE }, + {0, {0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63}, TRUE}, /* chroma */ - {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 }, TRUE }, - {0, } + {0, {0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63}, TRUE}, + {0,} } }; +/* *INDENT-ON* */ /* Table K.3: typical Huffman tables for 8-bit precision luminance and chrominance */ -/* -0..GST_JPEG_MAX_SCAN_COMPONENTS -1, DC huffman tables -GST_JPEG_MAX_SCAN_COMPONENTS...GST_JPEG_MAX_SCAN_COMPONENTS*2-1, AC huffman tables -*/ -static const -GstJpegHuffmanTables default_huf_tables = { +/* *INDENT-OFF* */ +static const GstJpegHuffmanTables default_huf_tables = { .dc_tables = { - /* DC luma */ - { { 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b }, - TRUE - }, - /* DC chroma */ - { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b }, - TRUE - }, - /* DC chroma */ - { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b }, - TRUE - }, - { { 0x0 }, - { 0x0 } - } + /* DC luma */ + {{0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b}, + TRUE}, + /* DC chroma */ + {{0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b}, + TRUE}, + /* DC chroma */ + {{0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b}, + TRUE}, + {{0x0,}, + {0x0,} + } }, .ac_tables = { - /* AC luma */ - { { 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, - 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d }, - { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa}, - TRUE - }, - /* AC chroma */ - { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77 }, - { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa }, - TRUE - }, - /* AC chroma */ - { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77 }, - { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa }, - TRUE - }, - { { 0x00 }, - { 0x00 } - } + /* AC luma */ + {{0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, + 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d}, + {0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa}, + TRUE}, + /* AC chroma */ + {{0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77}, + {0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa}, + TRUE}, + /* AC chroma */ + {{0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77}, + {0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa}, + TRUE}, + {{0x00,}, + {0x00,} + } } }; +/* *INDENT-ON* */ -static gboolean -jpeg_parse_to_next_marker (GstByteReader * reader, guint8 * marker) +static inline gboolean +jpeg_parse_to_next_marker (GstByteReader * br, guint8 * marker) { - guint8 value; + gint ofs; - while (gst_byte_reader_get_uint8 (reader, &value)) { - if (value != 0xFF) - continue; - while (value == 0xFF) { - READ_UINT8 (reader, value); + ofs = gst_jpeg_scan_for_marker_code (br->data, br->size, br->byte); + if (ofs < 0) + return FALSE; + + if (marker) + *marker = br->data[ofs + 1]; + gst_byte_reader_skip (br, ofs - br->byte + 2); + return TRUE; +} + +gint +gst_jpeg_scan_for_marker_code (const guint8 * data, gsize size, guint offset) +{ + guint i; + + g_return_val_if_fail (data != NULL, -1); + g_return_val_if_fail (size > offset, -1); + + for (i = offset; i < size - 1;) { + if (data[i] != 0xff) + i++; + else { + const guint8 v = data[i + 1]; + if (v >= 0xc0 && v <= 0xfe) + return i; + i += 2; } - if (value == 0x00) - continue; - *marker = value; - return TRUE; } + return -1; +} + +gboolean +gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * frame_hdr, + const guint8 * data, gsize size, guint offset) +{ + GstByteReader br; + guint16 length; + guint8 val; + guint i; + + g_return_val_if_fail (frame_hdr != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (size > offset, FALSE); + + size -= offset; + gst_byte_reader_init (&br, &data[offset], size); + g_return_val_if_fail (size >= 8, FALSE); + + U_READ_UINT16 (&br, length); /* Lf */ + g_return_val_if_fail (size >= length, FALSE); + + U_READ_UINT8 (&br, frame_hdr->sample_precision); + U_READ_UINT16 (&br, frame_hdr->height); + U_READ_UINT16 (&br, frame_hdr->width); + U_READ_UINT8 (&br, frame_hdr->num_components); + g_return_val_if_fail (frame_hdr->num_components <= + GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); + + length -= 8; + g_return_val_if_fail (length >= 3 * frame_hdr->num_components, FALSE); + for (i = 0; i < frame_hdr->num_components; i++) { + U_READ_UINT8 (&br, frame_hdr->components[i].identifier); + U_READ_UINT8 (&br, val); + frame_hdr->components[i].horizontal_factor = (val >> 4) & 0x0F; + frame_hdr->components[i].vertical_factor = (val & 0x0F); + U_READ_UINT8 (&br, frame_hdr->components[i].quant_table_selector); + g_return_val_if_fail ((frame_hdr->components[i].horizontal_factor <= 4 && + frame_hdr->components[i].vertical_factor <= 4 && + frame_hdr->components[i].quant_table_selector < 4), FALSE); + length -= 3; + } + + g_assert (length == 0); + return TRUE; +} + +gboolean +gst_jpeg_parse_scan_hdr (GstJpegScanHdr * scan_hdr, + const guint8 * data, gsize size, guint offset) +{ + GstByteReader br; + guint16 length; + guint8 val; + guint i; + + g_return_val_if_fail (scan_hdr != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (size > offset, FALSE); + + size -= offset; + gst_byte_reader_init (&br, &data[offset], size); + g_return_val_if_fail (size >= 3, FALSE); + + U_READ_UINT16 (&br, length); /* Ls */ + g_return_val_if_fail (size >= length, FALSE); + + U_READ_UINT8 (&br, scan_hdr->num_components); + g_return_val_if_fail (scan_hdr->num_components <= + GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); + + length -= 3; + g_return_val_if_fail (length >= 2 * scan_hdr->num_components, FALSE); + for (i = 0; i < scan_hdr->num_components; i++) { + U_READ_UINT8 (&br, scan_hdr->components[i].component_selector); + U_READ_UINT8 (&br, val); + scan_hdr->components[i].dc_selector = (val >> 4) & 0x0F; + scan_hdr->components[i].ac_selector = val & 0x0F; + g_return_val_if_fail ((scan_hdr->components[i].dc_selector < 4 && + scan_hdr->components[i].ac_selector < 4), FALSE); + length -= 2; + } + + /* FIXME: Ss, Se, Ah, Al */ + g_assert (length == 3); + return TRUE; +} + +gboolean +gst_jpeg_parse_huffman_table (GstJpegHuffmanTables * huf_tables, + const guint8 * data, gsize size, guint offset) +{ + GstByteReader br; + GstJpegHuffmanTable *huf_table; + guint16 length; + guint8 val, table_class, table_index; + guint32 value_count; + guint i; + + g_return_val_if_fail (huf_tables != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (size > offset, FALSE); + + size -= offset; + gst_byte_reader_init (&br, &data[offset], size); + g_return_val_if_fail (size >= 2, FALSE); + + U_READ_UINT16 (&br, length); /* Lh */ + g_return_val_if_fail (size >= length, FALSE); + + while (gst_byte_reader_get_remaining (&br)) { + U_READ_UINT8 (&br, val); + table_class = ((val >> 4) & 0x0F); + table_index = (val & 0x0F); + g_return_val_if_fail (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); + if (table_class == 0) { + huf_table = &huf_tables->dc_tables[table_index]; + } else { + huf_table = &huf_tables->ac_tables[table_index]; + } + READ_BYTES (&br, huf_table->huf_bits, 16); + value_count = 0; + for (i = 0; i < 16; i++) + value_count += huf_table->huf_bits[i]; + READ_BYTES (&br, huf_table->huf_values, value_count); + huf_table->valid = TRUE; + } + return TRUE; failed: return FALSE; } -GstJpegParserResult -gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * frame_hdr, +gboolean +gst_jpeg_parse_quant_table (GstJpegQuantTables * quant_tables, const guint8 * data, gsize size, guint offset) { - GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); - GstJpegParserResult result = GST_JPEG_PARSER_OK; - guint8 val; - u_int i; - - g_assert (frame_hdr && data && size); - - CHECK_FAILED (gst_byte_reader_get_remaining (&bytes_reader) >= 6, GST_JPEG_PARSER_ERROR); - U_READ_UINT8 (&bytes_reader, frame_hdr->sample_precision); - U_READ_UINT16 (&bytes_reader, frame_hdr->height); - U_READ_UINT16 (&bytes_reader, frame_hdr->width); - U_READ_UINT8 (&bytes_reader, frame_hdr->num_components); - CHECK_FAILED (frame_hdr->num_components <= GST_JPEG_MAX_SCAN_COMPONENTS, - GST_JPEG_PARSER_ERROR); - - CHECK_FAILED (gst_byte_reader_get_remaining(&bytes_reader) >= 3*frame_hdr->num_components, - GST_JPEG_PARSER_ERROR); - for (i = 0; i < frame_hdr->num_components; i++) { - U_READ_UINT8 (&bytes_reader, frame_hdr->components[i].identifier); - U_READ_UINT8 (&bytes_reader, val); - frame_hdr->components[i].horizontal_factor = (val >> 4) & 0x0F; - frame_hdr->components[i].vertical_factor = (val & 0x0F); - U_READ_UINT8 (&bytes_reader, frame_hdr->components[i].quant_table_selector); - CHECK_FAILED ((frame_hdr->components[i].horizontal_factor <= 4 && - frame_hdr->components[i].vertical_factor <= 4 && - frame_hdr->components[i].quant_table_selector < 4), - GST_JPEG_PARSER_ERROR); - } - return GST_JPEG_PARSER_OK; - -wrong_state: - return result; -} - -GstJpegParserResult -gst_jpeg_parse_scan_hdr (GstJpegScanHdr * scan_hdr, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); - GstJpegParserResult result = GST_JPEG_PARSER_OK; - guint8 val; - u_int i; - - g_assert (scan_hdr && data && size); - READ_UINT8 (&bytes_reader, scan_hdr->num_components); - CHECK_FAILED (scan_hdr->num_components <= GST_JPEG_MAX_SCAN_COMPONENTS, - GST_JPEG_PARSER_BROKEN_DATA); - - CHECK_FAILED (gst_byte_reader_get_remaining (&bytes_reader) >= 2*scan_hdr->num_components, - GST_JPEG_PARSER_ERROR); - for (i = 0; i < scan_hdr->num_components; i++) { - U_READ_UINT8 (&bytes_reader, - scan_hdr->components[i].component_selector); - U_READ_UINT8 (&bytes_reader, val); - scan_hdr->components[i].dc_selector = (val >> 4) & 0x0F; - scan_hdr->components[i].ac_selector = val & 0x0F; - g_assert (scan_hdr->components[i].dc_selector < 4 && - scan_hdr->components[i].ac_selector < 4); - CHECK_FAILED ((scan_hdr->components[i].dc_selector < 4 && - scan_hdr->components[i].ac_selector < 4), - GST_JPEG_PARSER_BROKEN_DATA); - } - return GST_JPEG_PARSER_OK; - -failed: - return GST_JPEG_PARSER_ERROR; - -wrong_state: - return result; -} - -GstJpegParserResult -gst_jpeg_parse_huffman_table ( - GstJpegHuffmanTables *huf_tables, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader bytes_reader = GST_BYTE_READER_INIT (data+offset, size-offset); - GstJpegParserResult result = GST_JPEG_PARSER_OK; - GstJpegHuffmanTable * huf_table; - guint8 tmp_val; - gboolean is_dc; - guint8 table_index; - guint32 value_count; - u_int i; - - g_assert (huf_tables && data && size); - while (gst_byte_reader_get_remaining (&bytes_reader)) { - U_READ_UINT8 (&bytes_reader, tmp_val); - is_dc = !((tmp_val >> 4) & 0x0F); - table_index = (tmp_val & 0x0F); - CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, - GST_JPEG_PARSER_BROKEN_DATA); - if (is_dc) { - huf_table = &huf_tables->dc_tables[table_index]; - } else { - huf_table = &huf_tables->ac_tables[table_index]; - } - READ_BYTES (&bytes_reader, huf_table->huf_bits, 16); - value_count = 0; - for (i = 0; i < 16; i++) - value_count += huf_table->huf_bits[i]; - READ_BYTES (&bytes_reader, huf_table->huf_values, value_count); - huf_table->valid = TRUE; - } - return GST_JPEG_PARSER_OK; - -failed: - return GST_JPEG_PARSER_ERROR; - -wrong_state: - return result; -} - -GstJpegParserResult -gst_jpeg_parse_quant_table ( - GstJpegQuantTables *quant_tables, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); - GstJpegParserResult result = GST_JPEG_PARSER_OK; + GstByteReader br; GstJpegQuantTable *quant_table; - guint8 val; - guint8 table_index; + guint16 length; + guint8 val, table_index; guint i; - g_assert (quant_tables && data && size); - while (gst_byte_reader_get_remaining (&bytes_reader)) { - U_READ_UINT8 (&bytes_reader, val); + g_return_val_if_fail (quant_tables != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (size > offset, FALSE); + + size -= offset; + gst_byte_reader_init (&br, &data[offset], size); + g_return_val_if_fail (size >= 2, FALSE); + + U_READ_UINT16 (&br, length); /* Lq */ + g_return_val_if_fail (size >= length, FALSE); + + while (gst_byte_reader_get_remaining (&br)) { + U_READ_UINT8 (&br, val); table_index = (val & 0x0f); - CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, - GST_JPEG_PARSER_BROKEN_DATA); + g_return_val_if_fail (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); quant_table = &quant_tables->quant_tables[table_index]; quant_table->quant_precision = ((val >> 4) & 0x0f); - CHECK_FAILED (gst_byte_reader_get_remaining(&bytes_reader) >= GST_JPEG_MAX_QUANT_ELEMENTS * (1 + !!quant_table->quant_precision), - GST_JPEG_PARSER_BROKEN_DATA); + g_return_val_if_fail (gst_byte_reader_get_remaining (&br) >= + GST_JPEG_MAX_QUANT_ELEMENTS * (1 + ! !quant_table->quant_precision), + FALSE); for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) { - if (!quant_table->quant_precision) { /* 8-bit values */ - U_READ_UINT8 (&bytes_reader, val); - quant_table->quant_table[i] = val; - } else { /* 16-bit values */ - U_READ_UINT16 (&bytes_reader, quant_table->quant_table[i]); - } + if (!quant_table->quant_precision) { /* 8-bit values */ + U_READ_UINT8 (&br, val); + quant_table->quant_table[i] = val; + } else { /* 16-bit values */ + U_READ_UINT16 (&br, quant_table->quant_table[i]); + } } quant_table->valid = TRUE; } - return GST_JPEG_PARSER_OK; - -wrong_state: - return result; + return TRUE; } -GstJpegParserResult +gboolean gst_jpeg_parse_restart_interval (guint * interval, const guint8 * data, gsize size, guint offset) { - GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); - guint16 tmp; + GstByteReader br; + guint16 length, val; - g_assert (interval && data && size); - READ_UINT16 (&bytes_reader, tmp); - *interval = tmp; - return GST_JPEG_PARSER_OK; + g_return_val_if_fail (interval != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (size > offset, FALSE); -failed: - return GST_JPEG_PARSER_BROKEN_DATA; + size -= offset; + gst_byte_reader_init (&br, &data[offset], size); + g_return_val_if_fail (size >= 4, FALSE); + + U_READ_UINT16 (&br, length); /* Lr */ + g_return_val_if_fail (size >= length, FALSE); + + U_READ_UINT16 (&br, val); + *interval = val; + return TRUE; } void -gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables *huf_tables) +gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables * huf_tables) { g_assert (huf_tables); - memcpy (huf_tables, &default_huf_tables, sizeof (GstJpegHuffmanTables)); + memcpy (huf_tables, &default_huf_tables, sizeof (*huf_tables)); } void -gst_jpeg_get_default_quantization_tables (GstJpegQuantTables *quant_tables) +gst_jpeg_get_default_quantization_tables (GstJpegQuantTables * quant_tables) { g_assert (quant_tables); - memcpy (quant_tables, &default_quant_tables_zigzag, sizeof (GstJpegQuantTables)); + + memcpy (quant_tables, &default_quant_tables_zigzag, sizeof (*quant_tables)); } -static gint32 -jpeg_scan_to_end (const guint8 *start, guint32 size) +gboolean +gst_jpeg_parse (GstJpegMarkerSegment * seg, + const guint8 * data, gsize size, guint offset) { - const guint8 *pos = start, *end = start + size; + GstByteReader br; + guint16 length; - for (; pos < end; ++pos) { - if (*pos != 0xFF) - continue; - while (*pos == 0xFF && pos + 1 < end) - ++pos; - if (*pos == 0x00 || *pos == 0xFF || - (*pos >= GST_JPEG_MARKER_RST_MIN && *pos <= GST_JPEG_MARKER_RST_MAX)) - continue; - break; + g_return_val_if_fail (seg != NULL, FALSE); + + if (size <= offset) { + GST_DEBUG ("failed to parse from offset %u, buffer is too small", offset); + return FALSE; } - if (pos >= end) - return size; - return pos - start - 1; -} - -static GstJpegTypeOffsetSize * -gst_jpeg_segment_new (guint8 marker, guint offset, gint size) -{ - GstJpegTypeOffsetSize *seg; - - if (GST_JPEG_MARKER_SOS == marker) - seg = g_malloc0 (sizeof (GstJpegScanOffsetSize)); - else - seg = g_malloc0 (sizeof (GstJpegTypeOffsetSize)); - seg->type = marker; - seg->offset = offset; - seg->size = size; - return seg; -} - -GList * -gst_jpeg_parse(const guint8 * data, gsize size, guint offset) -{ - GstByteReader bytes_reader; - guint8 marker; - guint16 header_length; - GList *segments = NULL; - GstJpegTypeOffsetSize *seg; - const guint8 *scan_start; - gint scan_size = 0; size -= offset; + gst_byte_reader_init (&br, &data[offset], size); - if ((gssize)size <= 0) { - GST_DEBUG ("Can't parse from offset %d, buffer is too small", offset); - return NULL; + if (!jpeg_parse_to_next_marker (&br, &seg->marker)) { + GST_DEBUG ("failed to find marker code"); + return FALSE; } - gst_byte_reader_init (&bytes_reader, &data[offset], size); + seg->offset = offset + gst_byte_reader_get_pos (&br); + seg->size = -1; - /* read SOI */ - if (!jpeg_parse_to_next_marker (&bytes_reader, &marker) || - marker != GST_JPEG_MARKER_SOI) - goto failed; - - while (jpeg_parse_to_next_marker (&bytes_reader, &marker)) { - if (marker == GST_JPEG_MARKER_EOI) + /* Try to find end of segment */ + switch (seg->marker) { + case GST_JPEG_MARKER_SOI: + case GST_JPEG_MARKER_EOI: + fixed_size_segment: + seg->size = 2; break; - READ_UINT16 (&bytes_reader, header_length); - if (header_length < 2 || - gst_byte_reader_get_remaining (&bytes_reader) < header_length - 2) - goto failed; + case (GST_JPEG_MARKER_SOF_MIN + 0): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 1): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 2): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 3): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 9): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 10): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 11): /* Lf */ + case GST_JPEG_MARKER_SOS: /* Ls */ + case GST_JPEG_MARKER_DQT: /* Lq */ + case GST_JPEG_MARKER_DHT: /* Lh */ + case GST_JPEG_MARKER_DAC: /* La */ + case GST_JPEG_MARKER_DRI: /* Lr */ + case GST_JPEG_MARKER_COM: /* Lc */ + case GST_JPEG_MARKER_DNL: /* Ld */ + variable_size_segment: + READ_UINT16 (&br, length); + seg->size = length; + break; - seg = gst_jpeg_segment_new (marker, - gst_byte_reader_get_pos(&bytes_reader) + offset, - header_length - 2); - segments = g_list_prepend(segments, seg); - gst_byte_reader_skip (&bytes_reader, header_length - 2); + default: + /* Application data segment length (Lp) */ + if (seg->marker >= GST_JPEG_MARKER_APP_MIN && + seg->marker <= GST_JPEG_MARKER_APP_MAX) + goto variable_size_segment; - if (seg->type == GST_JPEG_MARKER_SOS) { - GstJpegScanOffsetSize * const scan_seg = (GstJpegScanOffsetSize *)seg; - scan_start = gst_byte_reader_peek_data_unchecked (&bytes_reader); - scan_size = jpeg_scan_to_end (scan_start, - gst_byte_reader_get_remaining (&bytes_reader)); - if (scan_size <= 0) - break; + /* Restart markers (fixed size, two bytes only) */ + if (seg->marker >= GST_JPEG_MARKER_RST_MIN && + seg->marker <= GST_JPEG_MARKER_RST_MAX) + goto fixed_size_segment; - scan_seg->data_offset = gst_byte_reader_get_pos (&bytes_reader) + offset; - scan_seg->data_size = scan_size; - gst_byte_reader_skip (&bytes_reader, scan_size); - } + /* Fallback: scan for next marker */ + if (!jpeg_parse_to_next_marker (&br, NULL)) + goto failed; + seg->size = gst_byte_reader_get_pos (&br) - seg->offset; + break; } - return g_list_reverse (segments); + return TRUE; failed: - { - GST_WARNING ("Failed to parse"); - return g_list_reverse (segments); - } + return FALSE; } diff --git a/gst-libs/gst/codecparsers/gstjpegparser.h b/gst-libs/gst/codecparsers/gstjpegparser.h index a3f2b858f3..7237584e25 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.h +++ b/gst-libs/gst/codecparsers/gstjpegparser.h @@ -1,7 +1,7 @@ /* * gstjpegparser.h - JPEG parser * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -60,25 +60,7 @@ typedef struct _GstJpegScanComponent GstJpegScanComponent; typedef struct _GstJpegScanHdr GstJpegScanHdr; typedef struct _GstJpegFrameComponent GstJpegFrameComponent; typedef struct _GstJpegFrameHdr GstJpegFrameHdr; -typedef struct _GstJpegTypeOffsetSize GstJpegTypeOffsetSize; -typedef struct _GstJpegScanOffsetSize GstJpegScanOffsetSize; - -/** - * GstJpegParserResult: - * @GST_JPEG_PARSER_OK: The parsing succeeded - * @GST_JPEG_PARSER_BROKEN_DATA: The data to parse is broken - * @GST_JPEG_PARSER_NO_SCAN_FOUND: No scan found during the parsing - * @GST_JPEG_PARSER_ERROR: An error occured while parsing - * - * The result of parsing JPEG data. - */ -typedef enum -{ - GST_JPEG_PARSER_OK, - GST_JPEG_PARSER_BROKEN_DATA, - GST_JPEG_PARSER_NO_SCAN_FOUND, - GST_JPEG_PARSER_ERROR, -} GstJpegParserResult; +typedef struct _GstJpegMarkerSegment GstJpegMarkerSegment; /** * GstJpegMarkerCode: @@ -124,7 +106,6 @@ typedef enum { * @GST_JPEG_PROFILE_EXTENDED: Extended sequential DCT * @GST_JPEG_PROFILE_PROGRESSIVE: Progressive DCT * @GST_JPEG_PROFILE_LOSSLESS: Lossless (sequential) - * @GST_JPEG_PROFILE_ARITHMETIC: Flag for arithmetic coding * * JPEG encoding processes. */ @@ -133,9 +114,20 @@ typedef enum { GST_JPEG_PROFILE_EXTENDED = 0x01, GST_JPEG_PROFILE_PROGRESSIVE = 0x02, GST_JPEG_PROFILE_LOSSLESS = 0x03, - GST_JPEG_PROFILE_ARITHMETIC = 0x80 } GstJpegProfile; +/** + * GstJpegEntropyCodingMode: + * @GST_JPEG_ENTROPY_CODING_HUFFMAN: Huffman coding + * @GST_JPEG_ENTROPY_CODING_ARITHMETIC: arithmetic coding + * + * JPEG entropy coding mode. + */ +typedef enum { + GST_JPEG_ENTROPY_CODING_HUFFMAN = 0x00, + GST_JPEG_ENTROPY_CODING_ARITHMETIC = 0x08 +} GstJpegEntropyCodingMode; + /** * GstJpegQuantTable: * @quant_precision: Quantization table element precision (Pq) @@ -241,7 +233,6 @@ struct _GstJpegFrameComponent /** * GstJpegFrameHdr: - * @profile: JPEG encoding process (see #GstJpegProfile) * @sample_precision: Sample precision (P) * @height: Number of lines (Y) * @width: Number of samples per line (X) @@ -253,7 +244,6 @@ struct _GstJpegFrameComponent */ struct _GstJpegFrameHdr { - guint8 profile; guint8 sample_precision; /* 2 .. 16 */ guint16 width; /* 1 .. 65535 */ guint16 height; /* 0 .. 65535 */ @@ -262,38 +252,37 @@ struct _GstJpegFrameHdr }; /** - * GstJpegTypeOffsetSize: + * GstJpegMarkerSegment: * @type: The type of the segment that starts at @offset - * @offset: The offset to the segment start in bytes - * @size: The size in bytes of the segment, or -1 if the end was not found + * @offset: The offset to the segment start in bytes. This is the + * exact start of the segment, no marker code included + * @size: The size in bytes of the segment, or -1 if the end was not + * found. It is the exact size of the segment, no marker code included * * A structure that contains the type of a segment, its offset and its size. */ -struct _GstJpegTypeOffsetSize +struct _GstJpegMarkerSegment { - guint8 type; + guint8 marker; guint offset; gint size; }; /** - * GstJpegScanOffsetSize: - * @header: The header info associated to the scan - * @data_offset: The offset to the first entropy-coded segment in bytes - * @data_size: The size in bytes of the scan data, including all ECS - * and RST segments, or -1 if the end was not found + * gst_jpeg_scan_for_marker_code: + * @data: The data to parse + * @size: The size of @data + * @offset: The offset from which to start parsing * - * A structure that contains information on a scan. A scan comprises of the - * scan @header, and all entropy-coded segment (ECS) and restart marker (RST) - * associated to it. The header type MUST be set to @GST_JPEG_MARKER_SOS. + * Scans the JPEG bitstream contained in @data for the next marker + * code. If found, the function returns an offset to the marker code, + * including the 0xff prefix code but excluding any extra fill bytes. + * + * Returns: offset to the marker code if found, or -1 if not found. */ -struct _GstJpegScanOffsetSize -{ - GstJpegTypeOffsetSize header; - guint data_offset; - gint data_size; -}; - +gint gst_jpeg_scan_for_marker_code (const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse: @@ -301,15 +290,15 @@ struct _GstJpegScanOffsetSize * @size: The size of @data * @offset: The offset from which to start parsing * - * Parses the JPEG bitstream contained in @data, and returns the detected - * segments as a newly-allocated list of #GstJpegTypeOffsetSize elements. - * The caller is responsible for destroying the list when no longer needed. + * Parses the JPEG bitstream contained in @data, and returns the + * detected segment as a #GstJpegMarkerSegment. * - * Returns: a #GList of #GstJpegTypeOffsetSize. + * Returns: TRUE if a packet start code was found. */ -GList *gst_jpeg_parse (const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse (GstJpegMarkerSegment * seg, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse_frame_hdr: @@ -320,12 +309,12 @@ GList *gst_jpeg_parse (const guint8 * data, * * Parses the @hdr JPEG frame header structure members from @data. * - * Returns: a #GstJpegParserResult + * Returns: TRUE if the frame header was correctly parsed. */ -GstJpegParserResult gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * hdr, - const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * hdr, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse_scan_hdr: @@ -336,12 +325,12 @@ GstJpegParserResult gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * hdr, * * Parses the @hdr JPEG scan header structure members from @data. * - * Returns: a #GstJpegParserResult + * Returns: TRUE if the scan header was correctly parsed */ -GstJpegParserResult gst_jpeg_parse_scan_hdr (GstJpegScanHdr * hdr, - const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse_scan_hdr (GstJpegScanHdr * hdr, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse_quantization_table: @@ -359,12 +348,12 @@ GstJpegParserResult gst_jpeg_parse_scan_hdr (GstJpegScanHdr * hdr, * (Tq). While doing so, the @valid flag of the specified quantization * table will also be set to %TRUE. * - * Returns: a #GstJpegParserResult + * Returns: TRUE if the quantization table was correctly parsed. */ -GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTables *quant_tables, - const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse_quant_table (GstJpegQuantTables *quant_tables, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse_huffman_table: @@ -381,12 +370,12 @@ GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTables *qua * the @valid flag of the specified Huffman table will also be set to * %TRUE; * - * Returns: a #GstJpegParserResult + * Returns: TRUE if the Huffman table was correctly parsed. */ -GstJpegParserResult gst_jpeg_parse_huffman_table (GstJpegHuffmanTables *huf_tables, - const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse_huffman_table (GstJpegHuffmanTables *huf_tables, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse_restart_interval: @@ -395,12 +384,12 @@ GstJpegParserResult gst_jpeg_parse_huffman_table (GstJpegHuffmanTables *h * @size: The size of @data * @offset: The offset in bytes from which to start parsing @data * - * Returns: a #GstJpegParserResult + * Returns: TRUE if the restart interval value was correctly parsed. */ -GstJpegParserResult gst_jpeg_parse_restart_interval (guint * interval, - const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse_restart_interval (guint * interval, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_get_default_huffman_tables: @@ -409,8 +398,7 @@ GstJpegParserResult gst_jpeg_parse_restart_interval (guint * interval, * Fills in @huf_tables with the default AC/DC Huffman tables, as * specified by the JPEG standard. */ -void gst_jpeg_get_default_huffman_tables ( - GstJpegHuffmanTables *huf_tables); +void gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables *huf_tables); /** * gst_jpeg_get_default_quantization_table: @@ -419,7 +407,7 @@ void gst_jpeg_get_default_huffman_tables ( * Fills in @quant_tables with the default quantization tables, as * specified by the JPEG standard. */ -void gst_jpeg_get_default_quantization_tables (GstJpegQuantTables *quant_tables); +void gst_jpeg_get_default_quantization_tables (GstJpegQuantTables *quant_tables); G_END_DECLS From 1139908487b3f24792d5e912d3156164e8f665aa Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 17 Jul 2012 13:43:32 +0200 Subject: [PATCH 0707/3781] jpeg: update to match latest parser API. --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 244 ++++++++++++---------- 1 file changed, 128 insertions(+), 116 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index d798f0d0a0..ac19b3df5f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -62,26 +62,14 @@ struct _GstVaapiDecoderJpegPrivate { guint is_constructed : 1; }; - -static GstVaapiDecoderStatus -get_status(GstJpegParserResult result) -{ - GstVaapiDecoderStatus status; - - switch (result) { - case GST_JPEG_PARSER_OK: - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - case GST_JPEG_PARSER_BROKEN_DATA: - case GST_JPEG_PARSER_NO_SCAN_FOUND: - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - break; - default: - status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - break; - } - return status; -} +typedef struct _GstJpegScanSegment GstJpegScanSegment; +struct _GstJpegScanSegment { + guint header_offset; + guint header_size; + guint data_offset; + guint data_size; + guint is_valid : 1; +}; static void gst_vaapi_decoder_jpeg_close(GstVaapiDecoderJpeg *decoder) @@ -161,21 +149,21 @@ ensure_context(GstVaapiDecoderJpeg *decoder) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static inline GstVaapiDecoderStatus +static gboolean decode_current_picture(GstVaapiDecoderJpeg *decoder) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstVaapiPicture * const picture = priv->current_picture; - GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; + gboolean success = TRUE; if (picture) { if (!gst_vaapi_picture_decode(picture)) - status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + success = FALSE; else if (!gst_vaapi_picture_output(picture)) - status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + success = FALSE; gst_vaapi_picture_replace(&priv->current_picture, NULL); } - return status; + return success; } static gboolean @@ -327,32 +315,26 @@ decode_picture( ) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; - GstVaapiPicture *picture = NULL; - GstJpegFrameHdr *jpeg_frame_hdr = &priv->frame_hdr; - GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; - GstJpegParserResult result; + GstJpegFrameHdr * const frame_hdr = &priv->frame_hdr; + GstVaapiPicture *picture; + GstVaapiDecoderStatus status; - /* parse jpeg */ - memset(jpeg_frame_hdr, 0, sizeof(GstJpegFrameHdr)); switch (profile) { - case GST_JPEG_MARKER_SOF_MIN: - jpeg_frame_hdr->profile = GST_JPEG_MARKER_SOF_MIN; - priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; - break; - default: - GST_WARNING("Jpeg profile was not supported."); - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + case GST_JPEG_MARKER_SOF_MIN: + priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; + break; + default: + GST_ERROR("unsupported profile %d", profile); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } - result = gst_jpeg_parse_frame_hdr(jpeg_frame_hdr, buf, buf_size, 0); - if (result != GST_JPEG_PARSER_OK) { + memset(frame_hdr, 0, sizeof(*frame_hdr)); + if (!gst_jpeg_parse_frame_hdr(frame_hdr, buf, buf_size, 0)) { GST_ERROR("failed to parse image"); - return get_status(result); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } - - /* set info to va parameters in current picture*/ - priv->height = jpeg_frame_hdr->height; - priv->width = jpeg_frame_hdr->width; + priv->height = frame_hdr->height; + priv->width = frame_hdr->width; status = ensure_context(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { @@ -360,9 +342,8 @@ decode_picture( return status; } - if (priv->current_picture && - (status = decode_current_picture(decoder)) != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; + if (priv->current_picture && !decode_current_picture(decoder)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; picture = GST_VAAPI_PICTURE_NEW(JPEG, decoder); if (!picture) { @@ -372,12 +353,12 @@ decode_picture( gst_vaapi_picture_replace(&priv->current_picture, picture); gst_vaapi_picture_unref(picture); - if (!fill_picture(decoder, picture, jpeg_frame_hdr)) + if (!fill_picture(decoder, picture, frame_hdr)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; /* Update presentation time */ picture->pts = pts; - return status; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus @@ -388,15 +369,10 @@ decode_huffman_table( ) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; - GstJpegParserResult result; - result = gst_jpeg_parse_huffman_table( - &priv->huf_tables, - buf, buf_size, 0 - ); - if (result != GST_JPEG_PARSER_OK) { + if (!gst_jpeg_parse_huffman_table(&priv->huf_tables, buf, buf_size, 0)) { GST_DEBUG("failed to parse Huffman table"); - return get_status(result); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } priv->has_huf_table = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -410,12 +386,10 @@ decode_quant_table( ) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; - GstJpegParserResult result; - result = gst_jpeg_parse_quant_table(&priv->quant_tables, buf, buf_size, 0); - if (result != GST_JPEG_PARSER_OK) { + if (!gst_jpeg_parse_quant_table(&priv->quant_tables, buf, buf_size, 0)) { GST_DEBUG("failed to parse quantization table"); - return get_status(result); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } priv->has_quant_table = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -429,15 +403,10 @@ decode_restart_interval( ) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; - GstJpegParserResult result; - result = gst_jpeg_parse_restart_interval( - &priv->mcu_restart, - buf, buf_size, 0 - ); - if (result != GST_JPEG_PARSER_OK) { + if (!gst_jpeg_parse_restart_interval(&priv->mcu_restart, buf, buf_size, 0)) { GST_DEBUG("failed to parse restart interval"); - return get_status(result); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -452,7 +421,6 @@ decode_scan( { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstVaapiPicture *picture = priv->current_picture; - GstJpegParserResult result = GST_JPEG_PARSER_OK; VASliceParameterBufferJPEG *slice_param; GstVaapiSlice *gst_slice; guint total_h_samples, total_v_samples; @@ -460,25 +428,24 @@ decode_scan( guint i; if (!picture) { - GST_ERROR ("There is no VAPicture before decoding scan."); + GST_ERROR("There is no VAPicture before decoding scan."); return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; } if (!fill_quantization_table(decoder, picture)) { - GST_ERROR("Failed to fill in quantization table"); + GST_ERROR("failed to fill in quantization table"); return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } if (!fill_huffman_table(decoder, picture)) { - GST_ERROR("Failed to fill in huffman table"); + GST_ERROR("failed to fill in huffman table"); return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } memset(&scan_hdr, 0, sizeof(scan_hdr)); - result = gst_jpeg_parse_scan_hdr(&scan_hdr, scan_header, scan_header_size, 0); - if (result != GST_JPEG_PARSER_OK) { + if (!gst_jpeg_parse_scan_hdr(&scan_hdr, scan_header, scan_header_size, 0)) { GST_DEBUG("Jpeg parsed scan failed."); - return get_status(result); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } gst_slice = GST_VAAPI_SLICE_NEW(JPEG, decoder, scan_data, scan_data_size); @@ -523,71 +490,116 @@ decode_buffer(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + GstJpegMarkerSegment seg; + GstJpegScanSegment scan_seg; GstClockTime pts; guchar *buf; - guint buf_size; - GList *seg_list = NULL; - gboolean scan_found = FALSE; - GstJpegTypeOffsetSize *seg; + guint buf_size, ofs; + gboolean append_ecs; buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); if (!buf && buf_size == 0) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + memset(&scan_seg, 0, sizeof(scan_seg)); + pts = GST_BUFFER_TIMESTAMP(buffer); - g_assert(GST_CLOCK_TIME_IS_VALID(pts)); + ofs = 0; + while (gst_jpeg_parse(&seg, buf, buf_size, ofs)) { + if (seg.size < 0) { + GST_DEBUG("buffer to short for parsing"); + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } + ofs += seg.size; - priv->has_quant_table = FALSE; - priv->has_huf_table = FALSE; - priv->mcu_restart = 0; + /* Decode scan, if complete */ + if (seg.marker == GST_JPEG_MARKER_EOI && scan_seg.header_size > 0) { + scan_seg.data_size = seg.offset - scan_seg.data_offset; + scan_seg.is_valid = TRUE; + } + if (scan_seg.is_valid) { + status = decode_scan( + decoder, + buf + scan_seg.header_offset, + scan_seg.header_size, + buf + scan_seg.data_offset, + scan_seg.data_size + ); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + break; + memset(&scan_seg, 0, sizeof(scan_seg)); + } - seg_list = gst_jpeg_parse(buf, buf_size, 0); - for (; seg_list && !scan_found; seg_list = seg_list->next) { - seg = seg_list->data; - g_assert(seg); - switch (seg->type) { - case GST_JPEG_MARKER_DHT: - status = decode_huffman_table(decoder, buf + seg->offset, seg->size); + append_ecs = TRUE; + switch (seg.marker) { + case GST_JPEG_MARKER_SOI: + priv->has_quant_table = FALSE; + priv->has_huf_table = FALSE; + priv->mcu_restart = 0; + status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; - case GST_JPEG_MARKER_DAC: - GST_ERROR("unsupported arithmetic decoding"); - status = GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + case GST_JPEG_MARKER_EOI: + status = decode_current_picture(decoder); + break; + case GST_JPEG_MARKER_DHT: + status = decode_huffman_table(decoder, buf + seg.offset, seg.size); break; case GST_JPEG_MARKER_DQT: - status = decode_quant_table(decoder, buf + seg->offset, seg->size); + status = decode_quant_table(decoder, buf + seg.offset, seg.size); break; case GST_JPEG_MARKER_DRI: - status = decode_restart_interval(decoder, buf + seg->offset, seg->size); + status = decode_restart_interval(decoder, buf + seg.offset, seg.size); break; - case GST_JPEG_MARKER_SOS: { - GstJpegScanOffsetSize * const scan = (GstJpegScanOffsetSize *)seg; - status = decode_scan( - decoder, buf + scan->header.offset, scan->header.size, - buf + scan->data_offset, scan->data_size - ); - scan_found = TRUE; + case GST_JPEG_MARKER_DAC: + GST_ERROR("unsupported arithmetic coding mode"); + status = GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + break; + case GST_JPEG_MARKER_SOS: + scan_seg.header_offset = seg.offset; + scan_seg.header_size = seg.size; + scan_seg.data_offset = seg.offset + seg.size; + scan_seg.data_size = 0; + append_ecs = FALSE; break; - } default: - if (seg->type >= GST_JPEG_MARKER_SOF_MIN && - seg->type <= GST_JPEG_MARKER_SOF_MAX) - status = decode_picture(decoder, seg->type, buf + seg->offset, seg->size, pts); - else { - GST_WARNING("unsupported marker (0x%02x)", seg->type); - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + /* Restart marker */ + if (seg.marker >= GST_JPEG_MARKER_RST_MIN && + seg.marker <= GST_JPEG_MARKER_RST_MAX) { + append_ecs = FALSE; + break; } + + /* Frame header */ + if (seg.marker >= GST_JPEG_MARKER_SOF_MIN && + seg.marker <= GST_JPEG_MARKER_SOF_MAX) { + status = decode_picture( + decoder, + seg.marker, + buf + seg.offset, seg.size, + pts + ); + break; + } + + /* Application segments */ + if (seg.marker >= GST_JPEG_MARKER_APP_MIN && + seg.marker <= GST_JPEG_MARKER_APP_MAX) { + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + + GST_WARNING("unsupported marker (0x%02x)", seg.marker); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } - } - /* clean seg_list */ - g_list_free_full(seg_list, g_free); + /* Append entropy coded segments */ + if (append_ecs) + scan_seg.data_size = seg.offset - scan_seg.data_offset; - if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) { - if (scan_found) - return decode_current_picture(decoder); - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + break; } return status; } From 776d120b7fed1d52f472f2f8f4a5f19464a9f22e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 17 Jul 2012 13:44:45 +0200 Subject: [PATCH 0708/3781] tests: add test for JPEG decoding. --- tests/Makefile.am | 2 +- tests/test-decode.c | 6 + tests/test-jpeg.c | 2080 +++++++++++++++++++++++++++++++++++++++++++ tests/test-jpeg.h | 30 + 4 files changed, 2117 insertions(+), 1 deletion(-) create mode 100644 tests/test-jpeg.c create mode 100644 tests/test-jpeg.h diff --git a/tests/Makefile.am b/tests/Makefile.am index d01a6de54c..e45b72f3de 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -41,7 +41,7 @@ if USE_GLX TEST_MIX_LIBS += $(TEST_GLX_LIBS) endif -test_codecs_source_c = test-mpeg2.c test-h264.c test-vc1.c +test_codecs_source_c = test-mpeg2.c test-h264.c test-vc1.c test-jpeg.c test_codecs_source_h = $(test_codecs_source_c:%.c=%.h) test_decode_SOURCES = test-decode.c $(test_codecs_source_c) diff --git a/tests/test-decode.c b/tests/test-decode.c index 895c862371..021d087c5a 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -26,6 +26,7 @@ #include #include #include +#include "test-jpeg.h" #include "test-mpeg2.h" #include "test-h264.h" #include "test-vc1.h" @@ -35,6 +36,7 @@ #endif #if USE_CODEC_PARSERS # include +# include # include # include #endif @@ -52,6 +54,7 @@ struct _CodecDefs { static const CodecDefs g_codec_defs[] = { #define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info } + INIT_FUNCS(jpeg), INIT_FUNCS(mpeg2), INIT_FUNCS(h264), INIT_FUNCS(vc1), @@ -169,6 +172,9 @@ main(int argc, char *argv[]) case GST_VAAPI_CODEC_H264: decoder = gst_vaapi_decoder_h264_new(display, decoder_caps); break; + case GST_VAAPI_CODEC_JPEG: + decoder = gst_vaapi_decoder_jpeg_new(display, decoder_caps); + break; case GST_VAAPI_CODEC_MPEG2: decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); break; diff --git a/tests/test-jpeg.c b/tests/test-jpeg.c new file mode 100644 index 0000000000..ab7aff0b0f --- /dev/null +++ b/tests/test-jpeg.c @@ -0,0 +1,2080 @@ +/* + * test-jpeg.c - JPEG test data + * + * Copyright (C) 2012 Intel Corporation + * + * 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 "test-jpeg.h" + +#define JPEG_CLIP_WIDTH 320 +#define JPEG_CLIP_HEIGHT 240 +#define JPEG_CLIP_DATA_SIZE 24481 + +/* Data dump of a 320x240 VC-1 video clip (jpeg.raw), it has a single frame */ +static const guchar jpeg_clip[JPEG_CLIP_DATA_SIZE] = { + 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, + 0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, + 0x00, 0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04, 0x04, 0x05, + 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08, 0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, + 0x0b, 0x09, 0x0c, 0x11, 0x0f, 0x12, 0x12, 0x11, 0x0f, 0x11, 0x11, 0x13, + 0x16, 0x1c, 0x17, 0x13, 0x14, 0x1a, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, + 0x1a, 0x1d, 0x1d, 0x1f, 0x1f, 0x1f, 0x13, 0x17, 0x22, 0x24, 0x22, 0x1e, + 0x24, 0x1c, 0x1e, 0x1f, 0x1e, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x05, 0x05, + 0x05, 0x07, 0x06, 0x07, 0x0e, 0x08, 0x08, 0x0e, 0x1e, 0x14, 0x11, 0x14, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0xf0, 0x01, 0x40, 0x03, + 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, + 0x1d, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x03, 0x06, 0x07, 0x02, + 0x08, 0x01, 0x00, 0x09, 0xff, 0xc4, 0x00, 0x43, 0x10, 0x00, 0x02, 0x01, + 0x03, 0x02, 0x04, 0x04, 0x05, 0x02, 0x04, 0x03, 0x07, 0x03, 0x04, 0x03, + 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x00, 0x21, 0x06, 0x12, 0x31, + 0x41, 0x13, 0x22, 0x51, 0x61, 0x07, 0x14, 0x32, 0x71, 0x81, 0x91, 0xa1, + 0x15, 0x23, 0x42, 0xb1, 0x52, 0xc1, 0xd1, 0x08, 0x24, 0x33, 0x62, 0xe1, + 0xf0, 0xf1, 0x16, 0x43, 0x72, 0x25, 0x26, 0x34, 0x82, 0x17, 0x53, 0x83, + 0x93, 0xff, 0xc4, 0x00, 0x19, 0x01, 0x00, 0x02, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, + 0x00, 0x01, 0x04, 0x05, 0xff, 0xc4, 0x00, 0x2b, 0x11, 0x00, 0x02, 0x02, + 0x01, 0x04, 0x02, 0x02, 0x02, 0x01, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x11, 0x03, 0x04, 0x12, 0x21, 0x31, 0x22, 0x41, + 0x13, 0x32, 0x05, 0x51, 0x14, 0x23, 0x42, 0x61, 0x33, 0x52, 0x91, 0xb1, + 0xc1, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, + 0x00, 0x3f, 0x00, 0xcc, 0xb8, 0xce, 0xf5, 0x70, 0x83, 0x8b, 0x2f, 0x40, + 0x79, 0xe2, 0x4b, 0x8c, 0xe8, 0x17, 0xd8, 0x48, 0xdf, 0xe9, 0xa8, 0x2d, + 0xbc, 0x52, 0xa1, 0xb3, 0x2d, 0x34, 0xa8, 0x00, 0xc1, 0xc2, 0x67, 0x6f, + 0x5f, 0xdb, 0x53, 0xf1, 0x9d, 0x08, 0x97, 0x8b, 0xef, 0x72, 0x0d, 0xc7, + 0xcf, 0xcf, 0xb7, 0x4f, 0xfd, 0xc3, 0xa4, 0x33, 0x47, 0x15, 0x0d, 0x1c, + 0xac, 0x55, 0x89, 0x70, 0x42, 0xb7, 0x4c, 0x1c, 0xf4, 0xd6, 0x13, 0x97, + 0x3f, 0xb3, 0x2d, 0x74, 0xfc, 0x6f, 0xc3, 0xe1, 0xc2, 0xbd, 0x4c, 0x8a, + 0x71, 0x82, 0x5a, 0x3c, 0x63, 0x56, 0x4b, 0x1f, 0x10, 0xf0, 0xfd, 0x7b, + 0xaa, 0x0b, 0xa5, 0x2a, 0xf3, 0x79, 0x40, 0x69, 0x00, 0x39, 0xfc, 0xeb, + 0x13, 0xf0, 0x62, 0x7e, 0x5e, 0x65, 0x00, 0xb6, 0xdb, 0x6b, 0xa1, 0x48, + 0x88, 0x4a, 0x82, 0x36, 0xf6, 0xd4, 0xb7, 0xec, 0x1d, 0x87, 0xa5, 0xae, + 0x57, 0x24, 0x8b, 0x84, 0x2a, 0x28, 0x28, 0xcd, 0x34, 0x8a, 0xb3, 0x2b, + 0x19, 0xe3, 0x91, 0x5c, 0x91, 0x83, 0xb6, 0xdd, 0x35, 0x41, 0xba, 0xd7, + 0x25, 0x35, 0xbe, 0x69, 0xb0, 0x43, 0x46, 0xa4, 0xe7, 0x3e, 0xc7, 0x59, + 0xcf, 0x0d, 0x41, 0x39, 0xba, 0x2c, 0x71, 0xd4, 0xcb, 0x1c, 0x64, 0x67, + 0x0a, 0xdb, 0x67, 0x3e, 0x9a, 0x7f, 0x7c, 0xba, 0x25, 0x45, 0x9a, 0xb2, + 0xdf, 0x24, 0x85, 0x6a, 0xb2, 0x10, 0x77, 0xe7, 0x5c, 0xf5, 0x3e, 0x9d, + 0x34, 0x8d, 0x9f, 0x17, 0x3f, 0xb2, 0x64, 0x85, 0xd3, 0x33, 0xfa, 0xd9, + 0xcd, 0x5d, 0x4b, 0xd4, 0x33, 0x12, 0xd2, 0x31, 0x6e, 0xbe, 0xa7, 0x3a, + 0x6b, 0xc3, 0x7c, 0x9f, 0xf0, 0xd9, 0xca, 0x9e, 0x6c, 0xfd, 0xf4, 0x0b, + 0xdb, 0xe6, 0x4f, 0x30, 0x4d, 0xb3, 0xd3, 0x4d, 0xf8, 0x76, 0x13, 0x1c, + 0xab, 0x24, 0x83, 0x03, 0x9f, 0x97, 0xec, 0x74, 0x68, 0x7a, 0xe8, 0xbc, + 0xd8, 0x69, 0xa9, 0xa3, 0x9c, 0x9d, 0x98, 0x95, 0x07, 0x61, 0x81, 0xbe, + 0xfd, 0x34, 0xf2, 0xa9, 0x20, 0x82, 0x21, 0x24, 0xd8, 0x8c, 0x75, 0x43, + 0x8c, 0xef, 0xdb, 0x48, 0xa8, 0x9d, 0x92, 0xea, 0xaa, 0x47, 0x2a, 0x34, + 0x60, 0x07, 0xf5, 0x20, 0x7a, 0x6a, 0xc5, 0x27, 0x87, 0x24, 0x2f, 0x05, + 0x41, 0xcc, 0x6c, 0x31, 0xd3, 0x4e, 0x42, 0x19, 0x58, 0xbe, 0xc5, 0x35, + 0x5c, 0x6b, 0x24, 0xbc, 0xde, 0x2c, 0x24, 0xb2, 0x8c, 0x90, 0x0f, 0xb6, + 0xda, 0x87, 0x83, 0x2e, 0xa2, 0x5b, 0x8c, 0x94, 0xd2, 0xc9, 0xbb, 0x6d, + 0x8c, 0x6c, 0xac, 0x31, 0xb0, 0xd3, 0xca, 0xea, 0x4e, 0x68, 0x1f, 0xc2, + 0x66, 0x78, 0xd4, 0x1f, 0x38, 0x19, 0x03, 0xd8, 0xea, 0x92, 0xb4, 0xb2, + 0xd3, 0x5f, 0x84, 0xb1, 0x1e, 0x53, 0xf5, 0x67, 0xdc, 0x77, 0xd5, 0x9a, + 0xb1, 0x3d, 0xd1, 0xda, 0x5d, 0x38, 0xc4, 0xc1, 0x1d, 0x8a, 0xa4, 0xd4, + 0xc5, 0xe2, 0xa0, 0x1d, 0x39, 0x72, 0x47, 0xb8, 0xf7, 0xd5, 0x52, 0x86, + 0xd7, 0x6e, 0x8e, 0x18, 0xea, 0xa0, 0xb9, 0x20, 0x9a, 0x51, 0x85, 0xa7, + 0x64, 0x6e, 0x6f, 0x5d, 0xfd, 0x35, 0x77, 0x85, 0xc5, 0x5d, 0x2a, 0x3b, + 0x90, 0x4b, 0x27, 0xf3, 0x36, 0xf6, 0xd6, 0x69, 0x55, 0x55, 0x24, 0xb7, + 0x29, 0x62, 0x81, 0x3f, 0x9b, 0x03, 0x98, 0x99, 0xf9, 0x80, 0x07, 0x07, + 0x18, 0xfb, 0x9c, 0x6a, 0x07, 0x81, 0x26, 0x9c, 0x18, 0xc9, 0x6a, 0x39, + 0xeb, 0xa3, 0x82, 0x86, 0x6f, 0x1a, 0x76, 0x7e, 0x54, 0x0a, 0xb8, 0xdf, + 0xed, 0xab, 0x5d, 0x3d, 0x38, 0xa1, 0x52, 0xe6, 0xa6, 0x29, 0x2e, 0x52, + 0x0c, 0x73, 0xf2, 0x73, 0x01, 0x26, 0x73, 0x80, 0x7d, 0x14, 0x6f, 0xf8, + 0xd7, 0x1c, 0x23, 0x6d, 0x82, 0x0a, 0x46, 0xa8, 0xa7, 0xa7, 0xcd, 0x5c, + 0x91, 0xff, 0x00, 0x31, 0x07, 0xd4, 0x89, 0xb6, 0xd9, 0xec, 0x31, 0xd4, + 0xf7, 0xd4, 0xf4, 0xd5, 0x4d, 0x15, 0x73, 0xd4, 0x49, 0x1a, 0xd5, 0x33, + 0x29, 0x8d, 0x40, 0x5c, 0x0f, 0xfe, 0x2a, 0xbb, 0xe3, 0xef, 0xdf, 0x03, + 0x52, 0x97, 0xa1, 0xeb, 0x0c, 0x62, 0x2b, 0x96, 0x2a, 0x98, 0xea, 0x2a, + 0x4c, 0x93, 0x4b, 0x3b, 0x2a, 0x33, 0x4c, 0x4b, 0x60, 0x06, 0x3f, 0x4f, + 0x31, 0xf5, 0x39, 0xce, 0x3b, 0x69, 0x61, 0x3e, 0x74, 0xa8, 0x8f, 0x0c, + 0x8a, 0x70, 0x37, 0xc7, 0x37, 0xdb, 0xdb, 0x53, 0xde, 0xc4, 0xbc, 0xe5, + 0xa4, 0x51, 0x0c, 0x21, 0xcf, 0x88, 0x13, 0xe9, 0x5c, 0x12, 0x06, 0x74, + 0x38, 0x65, 0x91, 0x55, 0xa2, 0x45, 0x58, 0x97, 0x60, 0x1b, 0xea, 0xfb, + 0x0f, 0x6c, 0xff, 0x00, 0xa6, 0xa0, 0xcd, 0xa0, 0xb5, 0x28, 0xd3, 0x32, + 0xac, 0x3c, 0xa5, 0xe4, 0x7c, 0x28, 0x0b, 0xe6, 0xc9, 0xd7, 0x70, 0xc6, + 0x60, 0x79, 0x21, 0x90, 0xf3, 0xf8, 0x7f, 0x4b, 0x0e, 0x80, 0xff, 0x00, + 0xde, 0xfa, 0xea, 0xb4, 0x55, 0x53, 0xd7, 0x37, 0x38, 0x0a, 0xe1, 0x41, + 0x1c, 0xbe, 0x50, 0xb9, 0xdf, 0x61, 0xa8, 0x22, 0xcc, 0x91, 0xba, 0x9d, + 0x98, 0xb9, 0x63, 0xef, 0xbe, 0xa1, 0x36, 0x8e, 0xf8, 0x5a, 0x08, 0xaa, + 0xee, 0x71, 0xa5, 0x6c, 0xf2, 0x45, 0x4e, 0x5c, 0xb4, 0x92, 0x20, 0x04, + 0xa8, 0x03, 0x3b, 0x0f, 0xbe, 0x34, 0xce, 0xb5, 0x6c, 0x86, 0xa9, 0x84, + 0x92, 0x48, 0xa8, 0xe3, 0x9c, 0x4a, 0xa3, 0x94, 0x31, 0xef, 0xb7, 0xf9, + 0xe9, 0x47, 0x0b, 0xc6, 0x2a, 0x0d, 0x42, 0x24, 0xca, 0xb2, 0x02, 0x07, + 0x23, 0x6d, 0x90, 0x3b, 0xe7, 0x4e, 0xe7, 0xa2, 0xf0, 0xe8, 0x5a, 0xa2, + 0xa4, 0x0e, 0x48, 0xce, 0xc0, 0xf5, 0x3f, 0x6d, 0x26, 0x53, 0x51, 0x97, + 0x26, 0x1c, 0xb1, 0x79, 0x1f, 0x04, 0x7c, 0x35, 0x4d, 0x40, 0x2f, 0x52, + 0x34, 0x51, 0xc8, 0xcb, 0xe1, 0x16, 0x46, 0x77, 0xc8, 0x27, 0x9b, 0x6d, + 0xbf, 0x1a, 0xb0, 0x52, 0xda, 0xcd, 0x69, 0x92, 0xae, 0xb7, 0x3e, 0x00, + 0x25, 0x82, 0xe3, 0xf7, 0xd5, 0x52, 0xdb, 0x71, 0x88, 0xcc, 0x4c, 0x50, + 0xb4, 0x2a, 0xad, 0xb4, 0x85, 0xb7, 0x1e, 0xf8, 0xd5, 0x8e, 0xa6, 0xf3, + 0x5e, 0xd6, 0x7a, 0x81, 0x4a, 0x91, 0xc8, 0xdc, 0xbc, 0x85, 0x97, 0xfa, + 0x57, 0xa1, 0x3a, 0xc1, 0x9b, 0x0e, 0x4c, 0xb2, 0xdd, 0x01, 0x19, 0x31, + 0xc9, 0x3a, 0xa1, 0x35, 0xc6, 0xf9, 0x68, 0xfe, 0x16, 0xca, 0xb4, 0xfe, + 0x13, 0xb4, 0x8d, 0xc9, 0x18, 0x39, 0x63, 0xd8, 0x12, 0x7b, 0x0c, 0x01, + 0xaa, 0x25, 0x7d, 0x52, 0xb5, 0x67, 0x8e, 0xb1, 0x85, 0x93, 0x94, 0x28, + 0x20, 0xe4, 0x80, 0x3a, 0x81, 0xa3, 0x2a, 0xa3, 0xa7, 0x2c, 0xdc, 0xa4, + 0xb7, 0x2e, 0xd9, 0xf4, 0xf6, 0xd2, 0xba, 0x88, 0xcb, 0xca, 0xbc, 0x83, + 0x7c, 0xe3, 0x5b, 0x63, 0x8f, 0x64, 0x52, 0xb0, 0x94, 0x47, 0x91, 0x99, + 0xa8, 0x7c, 0x09, 0xa1, 0xa8, 0x61, 0x04, 0xe8, 0x32, 0xbf, 0xe1, 0xce, + 0x08, 0x03, 0xdb, 0x56, 0x9a, 0x6a, 0x51, 0x53, 0x4a, 0x23, 0xa7, 0x5f, + 0xe7, 0x8f, 0xe6, 0x28, 0x27, 0x0a, 0x70, 0x37, 0xcf, 0xbe, 0x33, 0xa0, + 0xac, 0xd4, 0xf1, 0xf8, 0x54, 0xa9, 0x38, 0x60, 0xa2, 0x24, 0x0d, 0xca, + 0x33, 0xd4, 0x01, 0x9d, 0x59, 0xb8, 0xd2, 0xd3, 0x45, 0xc3, 0x95, 0x74, + 0xb0, 0xd0, 0xd7, 0x23, 0x89, 0x69, 0x23, 0x95, 0xd9, 0x58, 0x33, 0x07, + 0x61, 0xb8, 0xdb, 0xfe, 0x9d, 0x74, 0xc2, 0xf7, 0x15, 0xc6, 0xc7, 0x55, + 0x18, 0x53, 0xb8, 0x1e, 0x9e, 0xda, 0x1e, 0x3a, 0x5a, 0x58, 0xe6, 0x92, + 0x72, 0xaa, 0xae, 0xf9, 0xe6, 0x62, 0x7a, 0x92, 0x73, 0xa9, 0xa3, 0xff, + 0x00, 0x84, 0x06, 0x73, 0xe8, 0x71, 0xa1, 0xee, 0x0e, 0xb1, 0xdb, 0x65, + 0x24, 0x02, 0x4b, 0x80, 0x06, 0xa7, 0x6e, 0x80, 0xa3, 0xae, 0x5c, 0x9f, + 0x2e, 0x08, 0xf5, 0x07, 0x5f, 0x79, 0x0e, 0x71, 0xa5, 0xb4, 0x15, 0x92, + 0x52, 0x55, 0x29, 0x18, 0xe4, 0x66, 0xc3, 0x7e, 0x74, 0xff, 0x00, 0xc1, + 0x1e, 0x28, 0x65, 0x3d, 0x57, 0xa9, 0xef, 0xa7, 0x55, 0x3a, 0x0a, 0x82, + 0x28, 0x61, 0x0f, 0x42, 0xfb, 0xf3, 0x1c, 0x15, 0x0b, 0xf8, 0xd2, 0xbf, + 0xe1, 0x61, 0x79, 0x39, 0x0a, 0x1c, 0x80, 0x5c, 0xfa, 0x67, 0xb6, 0x9f, + 0xdb, 0x14, 0xa5, 0x34, 0x9c, 0x87, 0x07, 0x7d, 0x72, 0x88, 0x42, 0xfb, + 0xe9, 0x30, 0x7e, 0x4c, 0x18, 0xbe, 0x40, 0xa8, 0x69, 0x4a, 0x44, 0x63, + 0x8d, 0x41, 0x39, 0x27, 0xf1, 0xa6, 0x56, 0xda, 0x39, 0x1a, 0x60, 0x3b, + 0x91, 0x80, 0x35, 0x6d, 0xf8, 0x4d, 0x69, 0xb1, 0x5c, 0x78, 0xba, 0x2a, + 0x6e, 0x21, 0x93, 0x92, 0x8e, 0x48, 0x5f, 0xff, 0x00, 0x73, 0xc3, 0x1c, + 0xfb, 0x10, 0x0b, 0x7a, 0x75, 0xd6, 0x87, 0x3f, 0xc2, 0xca, 0xb8, 0xde, + 0x6a, 0xeb, 0x40, 0x59, 0xa0, 0x8a, 0x46, 0x11, 0x46, 0xc7, 0xcc, 0xca, + 0x0e, 0xc5, 0x4f, 0x7d, 0xb4, 0x53, 0x77, 0xe3, 0xfb, 0x2b, 0x63, 0x7d, + 0x06, 0xfc, 0x2a, 0x5e, 0x1e, 0x6b, 0x3c, 0x34, 0x17, 0xaa, 0x01, 0xe2, + 0x46, 0x00, 0xf9, 0x82, 0x4f, 0x2f, 0x41, 0xb1, 0xdf, 0x6d, 0x58, 0xef, + 0x50, 0x7c, 0x36, 0x9a, 0x9a, 0x5a, 0x19, 0xe9, 0x12, 0x71, 0xbe, 0xf1, + 0x46, 0xc5, 0x94, 0xf4, 0xc8, 0x27, 0xd3, 0xf3, 0xa5, 0x1c, 0x2d, 0x62, + 0xa4, 0x7a, 0x29, 0x4d, 0xc6, 0xbe, 0x3b, 0x7f, 0x82, 0x71, 0x22, 0x49, + 0x80, 0xd9, 0xea, 0x73, 0x9f, 0xce, 0x9e, 0xd2, 0xdd, 0x38, 0x0e, 0xd4, + 0x04, 0x00, 0xa5, 0x5b, 0x05, 0xc3, 0x49, 0xe1, 0x19, 0x33, 0xf9, 0xc6, + 0x3f, 0x4d, 0x66, 0xd3, 0xe3, 0xcd, 0x1b, 0x5b, 0x52, 0xff, 0x00, 0x23, + 0x31, 0x6e, 0x4a, 0x9a, 0x46, 0x79, 0x71, 0xf8, 0x67, 0xc3, 0x55, 0xb0, + 0x3d, 0x45, 0x97, 0x89, 0x54, 0xd4, 0xf5, 0x5a, 0x6a, 0xa5, 0x0a, 0x48, + 0xf4, 0xc8, 0xef, 0xd3, 0x48, 0x2d, 0xdc, 0x05, 0x56, 0xd5, 0xb4, 0xf6, + 0xea, 0x9a, 0x39, 0x56, 0x6a, 0x99, 0x00, 0x47, 0xe4, 0x21, 0x4a, 0xe7, + 0xb1, 0xef, 0xb6, 0xb7, 0xbb, 0x47, 0x14, 0xf0, 0x9d, 0x64, 0x89, 0x47, + 0x4d, 0x24, 0x30, 0x92, 0xdc, 0xa8, 0x92, 0x40, 0x10, 0x13, 0xe8, 0x36, + 0xc6, 0x75, 0x64, 0x9c, 0x42, 0x90, 0x88, 0xcb, 0x47, 0x12, 0x9d, 0xb7, + 0x20, 0x01, 0xae, 0x87, 0xc7, 0xb9, 0x72, 0x37, 0xe1, 0xbf, 0x67, 0xf3, + 0x9f, 0x8a, 0x2a, 0x64, 0x8f, 0x8c, 0xb8, 0x82, 0x30, 0xfc, 0xa9, 0xfc, + 0x4a, 0xa4, 0xed, 0xdc, 0xf8, 0xad, 0xa4, 0x97, 0x3a, 0xc7, 0x89, 0x92, + 0x27, 0x84, 0x32, 0x32, 0x73, 0x37, 0x9b, 0x1b, 0x9e, 0x87, 0x56, 0xdb, + 0xf5, 0xad, 0x62, 0xe2, 0xeb, 0xe5, 0x55, 0x44, 0x8c, 0xfe, 0x25, 0xc6, + 0xa5, 0x95, 0x7b, 0x00, 0x64, 0x63, 0xaa, 0x1d, 0xd6, 0x56, 0x9e, 0xbe, + 0x57, 0x41, 0xcc, 0x39, 0x88, 0x51, 0xe8, 0x35, 0x9c, 0xcd, 0x3f, 0xb3, + 0x24, 0xa3, 0x2f, 0x35, 0x6a, 0x4b, 0x08, 0x29, 0xcb, 0xdf, 0xae, 0xfa, + 0x26, 0xe0, 0xd1, 0x73, 0xaa, 0x02, 0x39, 0xb3, 0x83, 0x83, 0xfe, 0x5a, + 0x5d, 0x12, 0x4a, 0x57, 0x94, 0x61, 0x79, 0x8f, 0x73, 0xa2, 0x23, 0x49, + 0x04, 0xa2, 0x05, 0xf3, 0x3e, 0x36, 0x3f, 0xf5, 0xd4, 0x08, 0xb0, 0xf0, + 0xcc, 0x4b, 0x4c, 0x79, 0xd8, 0x6d, 0x30, 0xc0, 0x3e, 0xfa, 0x87, 0x89, + 0x68, 0xbc, 0x1b, 0x87, 0x88, 0xd1, 0xb0, 0xf1, 0x94, 0x30, 0x24, 0x75, + 0xd4, 0x31, 0x5c, 0x66, 0xf1, 0xe1, 0xa1, 0x47, 0xc4, 0x68, 0x06, 0x40, + 0x1d, 0x70, 0x37, 0xfd, 0x74, 0xc2, 0xfb, 0x4e, 0xe6, 0x18, 0xdf, 0x9d, + 0x98, 0xc5, 0x91, 0xbf, 0xf8, 0x4e, 0x08, 0x1a, 0x0c, 0x9c, 0x2a, 0x2e, + 0x5d, 0x08, 0xe0, 0x85, 0xe5, 0x90, 0xc2, 0xbb, 0x93, 0xd0, 0x68, 0x8a, + 0x75, 0x64, 0xa6, 0x32, 0x28, 0xf3, 0x83, 0x8d, 0xba, 0x1f, 0x43, 0xa1, + 0xe9, 0x25, 0x10, 0xdc, 0x12, 0x5c, 0xe0, 0x86, 0xf2, 0x9f, 0x7d, 0x3d, + 0xa6, 0xa4, 0x92, 0x76, 0x03, 0x99, 0x10, 0xb6, 0xe4, 0x1f, 0x7d, 0x54, + 0x45, 0xa0, 0x1a, 0x2a, 0x8a, 0x85, 0x98, 0x4c, 0x67, 0x22, 0x44, 0x3c, + 0xc4, 0x9d, 0xf5, 0x75, 0xa3, 0xaf, 0x59, 0xa2, 0x8d, 0xe1, 0x95, 0x24, + 0x57, 0x50, 0x7d, 0xc1, 0xf4, 0xc6, 0xab, 0xb2, 0x70, 0xed, 0xc3, 0xc4, + 0x63, 0x17, 0x86, 0xc9, 0xca, 0x49, 0x3c, 0xdd, 0xb5, 0xf6, 0xcb, 0x47, + 0x35, 0x34, 0xe9, 0x1a, 0x48, 0x4a, 0x44, 0xaf, 0xe2, 0xc6, 0xaf, 0x8d, + 0xce, 0x0e, 0x7e, 0xda, 0x6f, 0xd4, 0xd0, 0xb1, 0x6f, 0xa4, 0x59, 0x12, + 0xf7, 0x14, 0x15, 0x5e, 0x11, 0x3c, 0xc3, 0x18, 0x75, 0xec, 0x74, 0x6d, + 0x96, 0x0a, 0x58, 0xee, 0xa6, 0x48, 0x54, 0x2c, 0x75, 0x28, 0x59, 0x73, + 0xb8, 0xcf, 0x70, 0x74, 0x92, 0x8a, 0x4a, 0x0a, 0x8a, 0x59, 0x96, 0x7f, + 0x0e, 0x9e, 0xad, 0xd8, 0xb4, 0x0f, 0xfe, 0x21, 0xfe, 0x1f, 0xef, 0xfa, + 0x68, 0xae, 0x1a, 0x92, 0x49, 0xa8, 0xe5, 0x12, 0x48, 0xce, 0x12, 0x5f, + 0x26, 0xfd, 0x0f, 0xa8, 0xd2, 0x66, 0xf7, 0x0b, 0x71, 0xae, 0x03, 0x78, + 0x86, 0x9a, 0xa2, 0x9a, 0x17, 0xa5, 0xb5, 0x43, 0xfc, 0xc6, 0x89, 0xb9, + 0x14, 0x1e, 0xe7, 0x7d, 0xbf, 0xd3, 0x59, 0xc5, 0x9a, 0x92, 0x15, 0xa7, + 0x8e, 0x26, 0x86, 0x46, 0xac, 0xf1, 0x49, 0x98, 0xb6, 0xd8, 0x39, 0xdf, + 0x27, 0xb6, 0x0f, 0x6d, 0x6c, 0x54, 0x6a, 0x95, 0x02, 0x29, 0x65, 0x24, + 0xca, 0x23, 0xfa, 0x86, 0xc7, 0x39, 0xdf, 0xfb, 0x7e, 0xfa, 0xab, 0x71, + 0x8d, 0x25, 0x35, 0x3d, 0xd1, 0xe7, 0x76, 0x31, 0xc1, 0x30, 0xf1, 0x58, + 0x29, 0xfa, 0xe4, 0x1b, 0x15, 0xfc, 0xee, 0x7f, 0x1a, 0xac, 0x19, 0x29, + 0xb1, 0xd8, 0x1f, 0x20, 0xaf, 0x5c, 0x69, 0x21, 0x45, 0x3e, 0x49, 0x1c, + 0x0f, 0x0c, 0x46, 0xdb, 0x10, 0x47, 0x5c, 0x0c, 0x02, 0xc7, 0xae, 0x4f, + 0x4d, 0x75, 0x44, 0xf1, 0x07, 0x0e, 0xc0, 0xa3, 0xa3, 0x06, 0x96, 0x51, + 0x21, 0x27, 0x1f, 0xe0, 0x5f, 0xb9, 0xfe, 0xda, 0x46, 0x6a, 0x67, 0x92, + 0x59, 0x26, 0xa7, 0x79, 0x23, 0x55, 0xd8, 0x21, 0xfa, 0x98, 0x74, 0xeb, + 0x8d, 0x1d, 0x0d, 0x4c, 0x8a, 0x64, 0x91, 0x89, 0x42, 0x1b, 0x99, 0x54, + 0x11, 0xb9, 0xfc, 0x7d, 0xf5, 0xa4, 0xdf, 0x10, 0x5b, 0xcc, 0x6a, 0x79, + 0x1d, 0x97, 0x9a, 0x10, 0xac, 0x47, 0xaa, 0xef, 0xa5, 0xb4, 0xcc, 0xd2, + 0x4a, 0x22, 0x2c, 0xa8, 0xe7, 0xb4, 0x87, 0x1b, 0x7a, 0xe7, 0x4d, 0x4c, + 0xae, 0xf5, 0x45, 0x98, 0x02, 0x5c, 0x73, 0x1f, 0x4d, 0xf7, 0xd7, 0xeb, + 0x7c, 0xd1, 0x2c, 0x35, 0x08, 0xd4, 0xc7, 0x92, 0x6c, 0x2b, 0x33, 0x0e, + 0x60, 0xbb, 0xef, 0xbf, 0x6e, 0xdf, 0xa6, 0xa1, 0x05, 0xb2, 0x24, 0xb8, + 0x25, 0xc9, 0x25, 0x8f, 0x36, 0xfa, 0x82, 0xae, 0xa5, 0x29, 0x60, 0x0c, + 0x06, 0xe3, 0x1f, 0xae, 0x8d, 0xb8, 0x47, 0x1c, 0x55, 0x07, 0xc2, 0xa9, + 0x2c, 0x87, 0x3c, 0xa7, 0xaa, 0x8f, 0x63, 0xe9, 0xa4, 0xb7, 0xa6, 0x32, + 0x4e, 0x90, 0x73, 0x0c, 0x28, 0xe6, 0x38, 0xf5, 0xd4, 0x02, 0x7e, 0x28, + 0xf9, 0x4b, 0x70, 0x9a, 0x9a, 0xbd, 0xaa, 0x11, 0xbc, 0x8d, 0x91, 0x8e, + 0xc7, 0xef, 0xab, 0x62, 0x55, 0x25, 0xca, 0x89, 0x57, 0xc5, 0x63, 0x4e, + 0x76, 0x92, 0x32, 0x7a, 0x7a, 0x7e, 0x87, 0x1a, 0xa4, 0x26, 0x54, 0x95, + 0xd5, 0x9b, 0x85, 0xff, 0x00, 0xfc, 0x57, 0x1e, 0xa7, 0x4a, 0x66, 0x7c, + 0x55, 0xbd, 0x26, 0x7e, 0xa9, 0x53, 0x4f, 0x51, 0x1c, 0x4a, 0xcc, 0x6a, + 0x89, 0xdc, 0x93, 0x84, 0xe5, 0xf7, 0xd3, 0x2a, 0x74, 0x96, 0x4a, 0x69, + 0x97, 0xc4, 0x09, 0x19, 0x19, 0x24, 0xf4, 0xeb, 0xa5, 0x15, 0x33, 0x78, + 0x26, 0xbd, 0xa6, 0xe6, 0x66, 0x7c, 0x2a, 0x38, 0xfe, 0x91, 0xe9, 0xa6, + 0x7e, 0x1b, 0x25, 0xa6, 0x09, 0x26, 0x24, 0x73, 0xa0, 0x0c, 0x73, 0xd7, + 0x1f, 0xf8, 0xd1, 0x35, 0xd3, 0x1f, 0xac, 0xc7, 0xfd, 0x35, 0x21, 0x64, + 0xe9, 0x0a, 0x8c, 0x46, 0x79, 0xc0, 0xdb, 0x9b, 0xdf, 0x51, 0x59, 0xe9, + 0x7e, 0x66, 0xf5, 0x0a, 0x15, 0xca, 0x2b, 0x73, 0xb6, 0xfd, 0x86, 0x88, + 0x48, 0x8c, 0xaa, 0x4c, 0x43, 0x2b, 0xbe, 0xda, 0x71, 0xc3, 0x76, 0xe9, + 0x21, 0xfe, 0x7b, 0xaf, 0x99, 0xdb, 0x39, 0xf6, 0xd1, 0x98, 0x10, 0xe2, + 0xa5, 0x39, 0xa5, 0x2c, 0xa7, 0xa0, 0x03, 0x41, 0xd5, 0x40, 0x85, 0x9e, + 0x37, 0xce, 0x64, 0xe5, 0xc1, 0x27, 0xa1, 0x3a, 0x32, 0x5c, 0x78, 0x87, + 0x1d, 0x73, 0xa8, 0xfe, 0x5c, 0xcd, 0x59, 0xe1, 0xc8, 0xab, 0x24, 0x52, + 0x27, 0x9c, 0x1f, 0x4c, 0x63, 0x1f, 0xdb, 0x41, 0x3a, 0xf6, 0x00, 0x3d, + 0x45, 0x24, 0x94, 0xf2, 0x98, 0x88, 0xc1, 0xf5, 0xd4, 0xd3, 0xda, 0xfc, + 0x68, 0x52, 0x96, 0x45, 0x67, 0x86, 0x68, 0xc4, 0xa1, 0xb3, 0x83, 0xcd, + 0xdc, 0x7d, 0x86, 0xa6, 0xb9, 0xd3, 0xc9, 0xcf, 0x12, 0xc0, 0xbe, 0x45, + 0xc0, 0x03, 0xd1, 0x40, 0xe9, 0xa6, 0x75, 0x17, 0xa9, 0x85, 0x9e, 0x92, + 0x8d, 0x59, 0x55, 0x0b, 0xb6, 0x58, 0x0d, 0x94, 0xf4, 0x0a, 0x4f, 0xed, + 0xa4, 0x2c, 0x91, 0x95, 0x32, 0x14, 0xca, 0x5b, 0x44, 0x95, 0xf5, 0x1c, + 0xbc, 0x8e, 0xa2, 0x36, 0xc1, 0x77, 0x1d, 0x48, 0xd5, 0xba, 0x9a, 0xdb, + 0x24, 0x86, 0x2a, 0x68, 0x91, 0x9d, 0xdb, 0x08, 0x8b, 0xcb, 0xb9, 0x3e, + 0x9a, 0x8e, 0x3a, 0xe9, 0xe1, 0x26, 0x07, 0x44, 0x56, 0x2d, 0x8c, 0x95, + 0xdf, 0x4c, 0xa8, 0x3c, 0x29, 0x1a, 0x28, 0xea, 0x64, 0x78, 0xd9, 0x66, + 0x59, 0x04, 0x88, 0x3a, 0x01, 0xdb, 0xef, 0xd3, 0xf4, 0xd3, 0x3e, 0x47, + 0x77, 0x22, 0x16, 0x9b, 0x27, 0x04, 0x45, 0x2d, 0xbd, 0xda, 0x69, 0x2b, + 0xe9, 0xeb, 0x60, 0x89, 0xd9, 0xa9, 0xa3, 0xa5, 0x32, 0xe4, 0x8c, 0xee, + 0x4e, 0x40, 0x51, 0xb6, 0xa9, 0x74, 0xf4, 0xed, 0xcc, 0x55, 0xb1, 0xe5, + 0xd6, 0xf3, 0x5b, 0x61, 0x9a, 0xff, 0x00, 0x60, 0xf9, 0xee, 0x1c, 0xe3, + 0x79, 0x6a, 0x65, 0x31, 0x05, 0x96, 0x92, 0x47, 0x11, 0x07, 0x00, 0x64, + 0xae, 0x07, 0x43, 0xee, 0x73, 0x9c, 0x1d, 0xf5, 0x4b, 0xe0, 0x4b, 0x7d, + 0x96, 0x3b, 0xe4, 0x53, 0xf1, 0x0d, 0x34, 0x86, 0x28, 0x58, 0x23, 0x44, + 0x98, 0x0a, 0xc4, 0x11, 0xe6, 0x3e, 0xa3, 0xed, 0xff, 0x00, 0x4d, 0x0f, + 0xd2, 0x7e, 0x5e, 0xca, 0xa6, 0x9a, 0xbf, 0x62, 0xab, 0x4f, 0x0f, 0x57, + 0xc1, 0x43, 0x4b, 0x75, 0xaa, 0xa6, 0x78, 0xa9, 0xaa, 0x8f, 0x2d, 0x3c, + 0xa4, 0xec, 0xe0, 0x75, 0xfd, 0xf5, 0xe8, 0xcf, 0x86, 0xb7, 0x29, 0x2b, + 0xb8, 0x6e, 0x18, 0xa6, 0x6c, 0xcd, 0x4c, 0x04, 0x6d, 0xee, 0xb8, 0xf2, + 0x9f, 0xd3, 0x4c, 0xab, 0xed, 0x96, 0xdb, 0xcd, 0x84, 0x51, 0xa2, 0x45, + 0xf2, 0x92, 0xc4, 0xa6, 0x06, 0x88, 0x00, 0x14, 0x63, 0x2a, 0x57, 0x1d, + 0x34, 0x2f, 0x06, 0xd9, 0xaa, 0x2c, 0xf4, 0xf3, 0x47, 0x55, 0x22, 0x49, + 0x24, 0x8c, 0x30, 0xcb, 0xdd, 0x54, 0x60, 0x67, 0xdf, 0x1a, 0xd7, 0x8e, + 0x1b, 0x65, 0xb8, 0xd7, 0x0c, 0x7b, 0x58, 0x48, 0xe1, 0xfb, 0x79, 0xbc, + 0xcd, 0x72, 0x7a, 0x68, 0x24, 0x69, 0x54, 0x64, 0x32, 0x03, 0xca, 0xc3, + 0xb8, 0xcf, 0xaf, 0xf9, 0x68, 0xf8, 0x68, 0x69, 0x61, 0x04, 0x45, 0x4d, + 0x02, 0x02, 0x72, 0x71, 0x18, 0x19, 0x3a, 0x23, 0x7d, 0x55, 0x38, 0xeb, + 0x8b, 0xa0, 0xe1, 0xe8, 0x8c, 0x08, 0x04, 0x95, 0xae, 0xb9, 0x44, 0xcf, + 0xd2, 0x3d, 0x4e, 0x9d, 0x63, 0x5d, 0x25, 0x6c, 0x0f, 0x8e, 0x78, 0x6e, + 0xeb, 0x53, 0x23, 0xd7, 0x58, 0xaa, 0x42, 0x54, 0x4a, 0x04, 0x6f, 0x0b, + 0x72, 0x85, 0x2a, 0x06, 0xc5, 0x72, 0x30, 0x0e, 0x7b, 0xfb, 0xeb, 0x14, + 0xe3, 0x19, 0x78, 0x8a, 0x9e, 0xe5, 0xf2, 0xf7, 0xa7, 0xaa, 0x15, 0x51, + 0x6c, 0x04, 0xec, 0x58, 0x72, 0xf6, 0x03, 0x7c, 0x6a, 0xfd, 0x6e, 0xe2, + 0x7f, 0x88, 0x57, 0x27, 0x15, 0x16, 0xda, 0x69, 0x6a, 0x62, 0x0f, 0xbf, + 0xf2, 0x70, 0x9f, 0xf8, 0xd7, 0x5c, 0x6b, 0x6a, 0xe3, 0xae, 0x2e, 0xa4, + 0xa3, 0x82, 0xb6, 0xcb, 0x49, 0x4f, 0xf2, 0xef, 0xce, 0x24, 0x59, 0x57, + 0x3b, 0x8c, 0x1c, 0x8e, 0x62, 0x7d, 0xfa, 0x6a, 0xb7, 0x19, 0x9a, 0x8e, + 0x4e, 0x8f, 0x34, 0x71, 0x50, 0xf1, 0x38, 0x92, 0xec, 0xb9, 0xc0, 0x35, + 0x53, 0x2f, 0xea, 0xe7, 0x59, 0x84, 0x71, 0x73, 0x49, 0x22, 0xe7, 0x04, + 0x31, 0xdf, 0x5a, 0x5f, 0x15, 0x48, 0xe9, 0xc4, 0xd7, 0x99, 0x1a, 0x36, + 0x58, 0x23, 0xab, 0x97, 0x2c, 0x47, 0x52, 0x64, 0x3d, 0x35, 0x9f, 0x53, + 0x52, 0xd4, 0x2d, 0x1b, 0xd6, 0x3a, 0xaa, 0xc5, 0x25, 0x43, 0x04, 0xf3, + 0x79, 0xba, 0x9e, 0xda, 0xc9, 0x36, 0xab, 0x83, 0x3c, 0xfe, 0xcc, 0x85, + 0x56, 0x35, 0x04, 0x18, 0xcb, 0x39, 0xdb, 0x39, 0xfd, 0xf5, 0x24, 0x23, + 0xc3, 0x8d, 0x99, 0x8e, 0xfd, 0x0f, 0xbe, 0x88, 0x86, 0x9f, 0xc4, 0x26, + 0x42, 0x3c, 0xa8, 0x32, 0x75, 0xc3, 0x46, 0x67, 0x94, 0x3b, 0x82, 0x91, + 0x2f, 0x4d, 0xb3, 0xb6, 0x84, 0xa3, 0x9a, 0x05, 0x06, 0xba, 0x29, 0x58, + 0x75, 0x70, 0x18, 0xfd, 0xce, 0xa7, 0xbf, 0x57, 0xbc, 0xd7, 0x45, 0x46, + 0x93, 0x09, 0x0c, 0x62, 0x12, 0x40, 0xd8, 0x90, 0x49, 0xce, 0x84, 0xab, + 0x7c, 0x05, 0xf0, 0xf6, 0x03, 0x6d, 0x07, 0x2e, 0x49, 0xcf, 0xeb, 0xa5, + 0x86, 0xb8, 0x54, 0x4b, 0x3c, 0xb1, 0x4e, 0x08, 0x40, 0x4e, 0x07, 0x36, + 0x74, 0xe7, 0x87, 0xa6, 0x9a, 0xa6, 0x9d, 0x8c, 0x7b, 0xc9, 0x4e, 0x07, + 0x36, 0xfd, 0x06, 0x90, 0x40, 0xb8, 0x32, 0x30, 0xe8, 0x50, 0xff, 0x00, + 0x96, 0xaf, 0x1c, 0x07, 0x4e, 0x23, 0xb4, 0xbc, 0xb2, 0x79, 0x44, 0x8d, + 0x91, 0xb7, 0x5d, 0x1c, 0x08, 0x13, 0x41, 0x73, 0xe5, 0x0b, 0xce, 0xd8, + 0xf3, 0x6c, 0x74, 0x25, 0x45, 0xc6, 0x9d, 0x24, 0xb8, 0xcf, 0x1c, 0x73, + 0xc8, 0xd1, 0x48, 0xac, 0x44, 0x5d, 0x48, 0xd9, 0x48, 0xc7, 0xa0, 0x38, + 0xd2, 0xcb, 0x95, 0x3c, 0xd4, 0xb7, 0x59, 0x24, 0x15, 0x29, 0x35, 0x20, + 0x93, 0x9c, 0x28, 0x18, 0x3e, 0xbc, 0xb9, 0xec, 0x75, 0xfa, 0xd5, 0x5f, + 0x25, 0x0c, 0x73, 0xac, 0x30, 0xa8, 0x59, 0xf7, 0x04, 0xef, 0x91, 0xe9, + 0xa6, 0x3e, 0x43, 0x53, 0xa7, 0x63, 0x08, 0x2e, 0x10, 0x57, 0x94, 0x9a, + 0x5a, 0x42, 0x7f, 0x9b, 0xc8, 0x5f, 0xc3, 0xce, 0xfe, 0xa7, 0xfd, 0x75, + 0x6a, 0xb4, 0x52, 0xcf, 0x35, 0x72, 0x3a, 0x55, 0xf8, 0x74, 0xb1, 0x27, + 0x99, 0x00, 0xc7, 0x30, 0xed, 0x8d, 0xf6, 0xd5, 0x0a, 0x20, 0x83, 0x3c, + 0x9e, 0x54, 0x24, 0x92, 0x80, 0xec, 0x09, 0x39, 0x3a, 0xb8, 0x70, 0xf5, + 0x47, 0x3d, 0x02, 0xc5, 0xcf, 0xba, 0x80, 0x31, 0xed, 0xdb, 0x48, 0x71, + 0xe6, 0x8b, 0x94, 0xf7, 0x16, 0xd8, 0x04, 0xe0, 0xbb, 0xc2, 0x79, 0xe3, + 0x62, 0x40, 0xef, 0x81, 0xe8, 0x75, 0xf1, 0xa9, 0x1e, 0x48, 0x8c, 0x35, + 0x51, 0x2b, 0x21, 0x1f, 0x4b, 0x0c, 0x82, 0x34, 0x9a, 0xe6, 0x2e, 0x12, + 0xd9, 0x8c, 0x56, 0xfa, 0xa6, 0x86, 0x74, 0xf3, 0x01, 0xda, 0x4f, 0xf9, + 0x4f, 0xb7, 0x6d, 0x7d, 0xb1, 0x5c, 0xea, 0x2a, 0xad, 0xbe, 0x2c, 0x0e, + 0x60, 0xa8, 0x21, 0x83, 0x20, 0x3d, 0x18, 0x1c, 0x11, 0xfa, 0xea, 0x2c, + 0x39, 0x12, 0xab, 0x12, 0xa1, 0x6a, 0xc1, 0xae, 0xbc, 0x22, 0x99, 0xf1, + 0x6d, 0x93, 0x78, 0x0c, 0x09, 0x26, 0x36, 0x3e, 0x56, 0x07, 0xa8, 0x1a, + 0xac, 0xbc, 0x33, 0x51, 0xce, 0x52, 0x60, 0xd0, 0xbf, 0x39, 0x5f, 0x04, + 0x8c, 0x96, 0x00, 0xf4, 0xfb, 0x1f, 0x5d, 0x5c, 0xe8, 0xb8, 0x88, 0x21, + 0xf9, 0x6b, 0xcb, 0x2a, 0xcc, 0x84, 0xf8, 0xa0, 0x0c, 0xba, 0x8e, 0xcd, + 0x8f, 0xea, 0x07, 0xae, 0xbe, 0x71, 0x9d, 0x95, 0x6f, 0xf6, 0xea, 0x5a, + 0x9a, 0x09, 0xd7, 0xc7, 0x8b, 0x78, 0xa4, 0x4e, 0x92, 0x0f, 0x42, 0x7b, + 0x68, 0xa3, 0x36, 0xbe, 0xcc, 0xd3, 0xa7, 0xc9, 0x2c, 0x7c, 0x48, 0xa2, + 0xd6, 0xca, 0x5e, 0x4e, 0x45, 0x26, 0x08, 0x49, 0xca, 0xef, 0x9e, 0xfd, + 0x34, 0x4d, 0xe7, 0xc3, 0xa7, 0xa5, 0x58, 0x39, 0xd5, 0xe4, 0x75, 0xc9, + 0x03, 0x62, 0xbf, 0x8d, 0x09, 0x52, 0xe4, 0x43, 0x25, 0x1d, 0x50, 0x6f, + 0x1a, 0x17, 0xc4, 0x6a, 0xe3, 0x0d, 0x11, 0x07, 0x7c, 0xff, 0x00, 0xae, + 0xa0, 0xb9, 0x97, 0x79, 0x12, 0x69, 0x25, 0x67, 0x79, 0x06, 0x58, 0x9e, + 0xb9, 0xd3, 0xce, 0x92, 0xe5, 0x59, 0x02, 0xb3, 0x3c, 0x8a, 0x07, 0xd3, + 0xf4, 0x9c, 0xe8, 0x2a, 0xf4, 0x31, 0xb4, 0x8d, 0x9c, 0xef, 0x80, 0x71, + 0xe9, 0xdb, 0x47, 0x40, 0xb9, 0x46, 0x61, 0xf5, 0x76, 0xd1, 0xf6, 0xdb, + 0x1c, 0x97, 0xc9, 0x79, 0x96, 0x64, 0xa7, 0x8e, 0x22, 0x64, 0x9e, 0x46, + 0xec, 0xa0, 0xe3, 0xf5, 0x3a, 0x19, 0xc9, 0x46, 0x2e, 0x4c, 0xc9, 0xa8, + 0xe9, 0x15, 0xda, 0x0a, 0x67, 0xaa, 0x91, 0x55, 0x06, 0xed, 0xb9, 0x3e, + 0x9a, 0xb9, 0x51, 0xdb, 0x65, 0x86, 0xdc, 0xa9, 0x19, 0x08, 0xc7, 0xbe, + 0x3a, 0xe8, 0x8b, 0x6d, 0x3d, 0xb2, 0x28, 0xe6, 0x36, 0xb2, 0x1c, 0x09, + 0x44, 0x63, 0xcd, 0x92, 0xd9, 0xd5, 0xda, 0xa6, 0xca, 0xd4, 0xfc, 0x25, + 0x4a, 0xf2, 0x14, 0xf1, 0x9a, 0x56, 0xf2, 0xe7, 0x7c, 0xb6, 0xe3, 0x6f, + 0xd7, 0x59, 0x33, 0x6a, 0x16, 0x2a, 0xbf, 0x62, 0x31, 0x64, 0x58, 0xe6, + 0x9b, 0x33, 0x35, 0xa4, 0x96, 0x66, 0x82, 0x8d, 0x90, 0xb9, 0x33, 0x90, + 0x40, 0xf4, 0xcf, 0xae, 0xae, 0x37, 0xdb, 0x34, 0xaf, 0x6a, 0xf9, 0x11, + 0x16, 0x39, 0x23, 0x00, 0x7d, 0xc6, 0x35, 0x3a, 0x58, 0xea, 0x63, 0xf0, + 0x2b, 0x17, 0xfe, 0x32, 0xb8, 0x21, 0x40, 0xdc, 0x6c, 0x7b, 0xfa, 0xfb, + 0x6b, 0xb9, 0x78, 0x90, 0xd2, 0x31, 0xa7, 0xaf, 0xa7, 0x2f, 0x0c, 0x47, + 0x1e, 0x2c, 0x6b, 0xe6, 0x66, 0x1e, 0xda, 0x44, 0xf3, 0x4b, 0x23, 0x4f, + 0x13, 0xe8, 0x7f, 0xe4, 0x33, 0x47, 0x22, 0xac, 0x6e, 0xd0, 0x8e, 0x9e, + 0xc9, 0xf2, 0x74, 0x86, 0x77, 0x41, 0x95, 0x19, 0x6d, 0xb7, 0xc7, 0xae, + 0x8c, 0xa1, 0x96, 0x2f, 0x94, 0x59, 0x0b, 0x79, 0x1b, 0xa1, 0xc6, 0x98, + 0x55, 0x5f, 0x53, 0xc2, 0x47, 0x36, 0xc9, 0x96, 0x49, 0x90, 0x98, 0xd2, + 0x43, 0xca, 0x59, 0x7d, 0x4e, 0xda, 0x22, 0xc7, 0x60, 0xab, 0x9e, 0xde, + 0x93, 0x25, 0x20, 0x82, 0x09, 0x14, 0x4a, 0xbc, 0xfe, 0x52, 0xca, 0x73, + 0x83, 0x8e, 0xac, 0x36, 0x38, 0x3e, 0xc7, 0x5b, 0x74, 0xd3, 0x9c, 0xbe, + 0xc6, 0x0c, 0x49, 0xfb, 0x2a, 0x95, 0xb7, 0xba, 0x6f, 0x9c, 0x6a, 0x3a, + 0x5e, 0x71, 0x3f, 0xd2, 0x24, 0x65, 0xc2, 0x83, 0xdf, 0xef, 0xa6, 0x7c, + 0x3c, 0x87, 0xe5, 0x5e, 0x49, 0x01, 0xf1, 0x41, 0xf3, 0x16, 0x18, 0x3c, + 0xbd, 0x8e, 0x35, 0xdf, 0x11, 0xda, 0x61, 0xc1, 0x8a, 0x78, 0x44, 0xad, + 0xcf, 0x91, 0x85, 0xc1, 0x23, 0xd3, 0x3a, 0xfa, 0x9e, 0x05, 0x02, 0x88, + 0x69, 0xe5, 0xa9, 0x91, 0x7c, 0x24, 0x88, 0x09, 0x76, 0xe5, 0xee, 0x47, + 0xe0, 0xe4, 0x68, 0xb5, 0x18, 0x9d, 0xd2, 0x18, 0xe2, 0xab, 0x83, 0xa9, + 0xa6, 0x91, 0xe4, 0x25, 0x5f, 0xe9, 0xd9, 0x7d, 0xf1, 0xa6, 0x91, 0xd0, + 0xd1, 0x85, 0x5a, 0x84, 0x60, 0x8b, 0x3e, 0x25, 0x0b, 0x9c, 0x05, 0x63, + 0x8e, 0x6c, 0x67, 0xbe, 0x46, 0x92, 0x48, 0x09, 0xf2, 0x29, 0xc1, 0x03, + 0x3a, 0x7d, 0x5f, 0x6b, 0xf0, 0x69, 0xe9, 0x92, 0xbe, 0x12, 0x95, 0x31, + 0xc6, 0xac, 0x87, 0x39, 0xc0, 0x2a, 0x08, 0x3f, 0xbe, 0xb3, 0x4d, 0x52, + 0xab, 0xa1, 0x32, 0x74, 0x45, 0xc4, 0x10, 0xd3, 0xb3, 0xc3, 0x55, 0x4d, + 0x23, 0x4b, 0xcd, 0xb3, 0xf3, 0x30, 0x24, 0x37, 0x7c, 0xfe, 0x83, 0xf4, + 0xd7, 0x74, 0x12, 0x52, 0xca, 0x82, 0x29, 0x1c, 0x09, 0x06, 0x06, 0xfd, + 0x34, 0x2c, 0xce, 0xca, 0xe1, 0x0e, 0x32, 0x57, 0x25, 0xc0, 0xdd, 0xbd, + 0x33, 0xa1, 0x95, 0x17, 0xc4, 0x75, 0x63, 0xb9, 0x39, 0x07, 0x53, 0x6e, + 0xf8, 0x51, 0x1f, 0x45, 0xda, 0xc9, 0x6e, 0xa8, 0xa8, 0x12, 0xad, 0x2c, + 0x4e, 0x59, 0x50, 0x15, 0x58, 0x50, 0xb9, 0x63, 0xef, 0x8e, 0x9d, 0x33, + 0xa7, 0xb6, 0xae, 0x1f, 0xe2, 0x53, 0x22, 0x1a, 0x7b, 0x65, 0x53, 0x97, + 0xc1, 0x52, 0xd1, 0x15, 0x18, 0xf7, 0x27, 0x4f, 0x7e, 0x0f, 0x71, 0x1c, + 0x56, 0x9e, 0x12, 0xa8, 0xad, 0x8e, 0x8d, 0xdd, 0x68, 0xd9, 0x52, 0xb3, + 0xc2, 0x4e, 0x63, 0xbe, 0x79, 0x5c, 0xfe, 0x32, 0x33, 0xdb, 0xf3, 0xab, + 0xec, 0xdc, 0x61, 0x59, 0x3d, 0x96, 0x7a, 0xaa, 0x2a, 0x38, 0x9f, 0x9d, + 0x39, 0xa0, 0x2d, 0x9c, 0x0d, 0xf0, 0x79, 0x94, 0xfe, 0x4e, 0x85, 0x69, + 0xe3, 0x35, 0xcc, 0xa9, 0x95, 0xf1, 0xc2, 0xae, 0x4c, 0x17, 0x80, 0x38, + 0xaa, 0x7a, 0x4b, 0x55, 0x35, 0x0d, 0xca, 0x95, 0x95, 0x10, 0x94, 0x12, + 0x73, 0x67, 0x90, 0x0e, 0xc7, 0x6d, 0x68, 0xf0, 0xcb, 0x1c, 0xd1, 0x2c, + 0xb1, 0x38, 0x74, 0x61, 0x95, 0x20, 0xec, 0x75, 0x90, 0xd0, 0xf1, 0x7d, + 0xa9, 0x69, 0x4d, 0x15, 0x55, 0x15, 0x0b, 0xd4, 0x16, 0x69, 0x48, 0x4d, + 0x83, 0x39, 0xea, 0x48, 0xc7, 0xa9, 0xd0, 0x75, 0x9c, 0x57, 0x79, 0x85, + 0xfc, 0x6a, 0x6a, 0xd5, 0xa5, 0x45, 0x3b, 0x45, 0x1a, 0x0f, 0x0c, 0x7e, + 0x3b, 0xf6, 0xd0, 0xad, 0x7c, 0x34, 0xbe, 0x32, 0x96, 0xe4, 0x37, 0x16, + 0xad, 0x41, 0x53, 0x76, 0x6b, 0x37, 0x5b, 0xcd, 0xb6, 0x86, 0x51, 0x0d, + 0x5c, 0xfe, 0x1b, 0x1d, 0xfe, 0x82, 0xd8, 0xfd, 0x3a, 0x69, 0x1d, 0xca, + 0x8f, 0x82, 0x2b, 0xa9, 0xde, 0xef, 0x5c, 0xd4, 0x92, 0x2c, 0x6e, 0x26, + 0x7a, 0x89, 0x1f, 0xcd, 0xb7, 0x62, 0x4e, 0xe4, 0x7f, 0xcb, 0xfb, 0x6a, + 0x8b, 0x4f, 0x37, 0x13, 0xdd, 0x2a, 0x24, 0x28, 0x68, 0x9c, 0xcc, 0x7f, + 0x99, 0x2b, 0xf3, 0x2f, 0x20, 0xc6, 0xf9, 0x1f, 0xa7, 0x7d, 0x2c, 0xb9, + 0x5b, 0x28, 0x64, 0x95, 0xbf, 0x8f, 0xf1, 0x3d, 0x24, 0x4b, 0x8c, 0x98, + 0xe9, 0x50, 0xcb, 0x8f, 0xf4, 0xd1, 0x43, 0xf2, 0x73, 0xc9, 0xcc, 0x63, + 0xc0, 0x6f, 0x52, 0xdf, 0xa0, 0x8e, 0x30, 0xf8, 0x8d, 0x51, 0x24, 0x92, + 0xd2, 0xda, 0xa5, 0x11, 0x52, 0xae, 0x52, 0x24, 0x89, 0x79, 0x7c, 0x9d, + 0xbe, 0xdd, 0xb6, 0xd4, 0x7c, 0x03, 0x7d, 0xe2, 0xeb, 0xed, 0x44, 0x76, + 0x5b, 0x4d, 0x5c, 0x54, 0x28, 0x01, 0x92, 0x59, 0x79, 0x01, 0x60, 0x32, + 0x32, 0xc7, 0x3d, 0x7a, 0x8f, 0x4d, 0x65, 0x9c, 0x45, 0x76, 0xa2, 0xa4, + 0xaa, 0x96, 0x2b, 0x7b, 0x3b, 0x53, 0x87, 0x22, 0x27, 0x91, 0x40, 0x76, + 0x1d, 0xbe, 0xd9, 0xd1, 0xdc, 0x1f, 0xc5, 0xf7, 0xa5, 0x34, 0xb6, 0x4b, + 0x2d, 0x33, 0x47, 0x3c, 0xf3, 0x79, 0x8d, 0x39, 0xc4, 0xb2, 0x92, 0x73, + 0xe6, 0x6c, 0x74, 0x03, 0xdc, 0x0e, 0xa7, 0x4d, 0xc2, 0xf2, 0x39, 0xdb, + 0x17, 0x8d, 0xc9, 0xca, 0xdb, 0x28, 0x1c, 0x62, 0x3c, 0x4b, 0xb5, 0xd9, + 0x47, 0xd0, 0x2e, 0x13, 0x78, 0x8b, 0xdc, 0x8e, 0x73, 0xbe, 0x94, 0x5c, + 0x62, 0xa1, 0xa3, 0x31, 0x3c, 0x71, 0x7f, 0xbb, 0xc8, 0xbf, 0xe2, 0xe8, + 0x74, 0xc7, 0x89, 0xa1, 0xa9, 0x6e, 0x2a, 0xba, 0xf3, 0x30, 0x78, 0xcd, + 0x74, 0xe7, 0x04, 0x63, 0x6e, 0x76, 0xdb, 0xf1, 0xa5, 0x35, 0x54, 0x72, + 0x4c, 0xa2, 0x9c, 0x4a, 0xa4, 0x7d, 0x5c, 0xad, 0xb7, 0x4e, 0xc0, 0xe9, + 0xf4, 0xfd, 0x03, 0x3f, 0xb3, 0x01, 0xe4, 0xf9, 0xa2, 0xb1, 0x44, 0x79, + 0x63, 0xea, 0x7f, 0xe6, 0x3a, 0x31, 0x6d, 0x63, 0x90, 0xbc, 0x84, 0x72, + 0x85, 0xc7, 0x36, 0x0e, 0xc3, 0xf1, 0xaf, 0x94, 0xf5, 0x46, 0x89, 0x92, + 0x13, 0x44, 0xf1, 0xb1, 0x50, 0x57, 0xc4, 0xdb, 0x27, 0x44, 0x45, 0x77, + 0xa2, 0x69, 0x58, 0xd4, 0x48, 0xef, 0x57, 0x1b, 0x7f, 0xc2, 0x44, 0xf2, + 0xae, 0xff, 0x00, 0xf7, 0xbe, 0xaf, 0xc2, 0xae, 0x4c, 0x15, 0xd5, 0x95, + 0xda, 0xdb, 0x5d, 0x5c, 0x6f, 0x98, 0xe2, 0x95, 0xd3, 0x19, 0x07, 0xc3, + 0xc6, 0x47, 0xae, 0x35, 0x0d, 0x25, 0xb2, 0xba, 0xae, 0x46, 0x8a, 0x2a, + 0x66, 0x2c, 0xa4, 0x73, 0x0c, 0x7d, 0x20, 0xf4, 0x27, 0x57, 0x19, 0x2b, + 0x94, 0x4c, 0x2a, 0x15, 0x0c, 0x4e, 0xbb, 0x60, 0xff, 0x00, 0xa6, 0x99, + 0x70, 0xa5, 0x31, 0x4a, 0x0a, 0xa9, 0xd4, 0x78, 0x93, 0xcd, 0x29, 0x76, + 0xed, 0xb1, 0xd6, 0x5e, 0xdf, 0x03, 0x0a, 0xb4, 0x1c, 0x33, 0x24, 0x7c, + 0xb4, 0x2b, 0x2a, 0x3d, 0x44, 0xaa, 0x64, 0x73, 0xd0, 0x2a, 0x82, 0x32, + 0x3d, 0xfa, 0xeb, 0xbb, 0xb5, 0x49, 0xa5, 0x46, 0xa3, 0xa6, 0x99, 0xbc, + 0x15, 0xc2, 0xe0, 0x1d, 0x89, 0x03, 0x1f, 0xa6, 0xac, 0x75, 0xee, 0xf4, + 0xd5, 0xd2, 0xc9, 0x51, 0x1b, 0x20, 0x92, 0x97, 0x11, 0xb6, 0x36, 0xfa, + 0xba, 0x67, 0xf1, 0xaa, 0x95, 0x73, 0x47, 0x33, 0x15, 0x41, 0xd3, 0xbf, + 0xae, 0xb6, 0x6d, 0xa4, 0x40, 0x15, 0x12, 0x54, 0xcd, 0x1d, 0x3a, 0xe0, + 0x07, 0x38, 0xc0, 0xe8, 0x34, 0xc5, 0xe0, 0x64, 0x41, 0x1b, 0x6c, 0x54, + 0x6c, 0x3d, 0x34, 0xbe, 0xdd, 0xe2, 0x45, 0x71, 0x0e, 0x9f, 0x50, 0xdc, + 0x1d, 0x3e, 0xf0, 0xe7, 0xa8, 0x4c, 0xcc, 0xc0, 0xef, 0xbe, 0xaa, 0x3d, + 0x94, 0x28, 0x65, 0xc3, 0x6e, 0x37, 0xd3, 0x0b, 0x65, 0x63, 0xd2, 0xb2, + 0xbc, 0x6f, 0xb8, 0x6c, 0x91, 0xed, 0xaf, 0xd2, 0xd0, 0xcb, 0xe1, 0xb1, + 0x5c, 0x72, 0xaf, 0x56, 0x63, 0x80, 0x34, 0xbe, 0x17, 0x4e, 0x40, 0x7b, + 0x8c, 0xfe, 0xfa, 0x94, 0x59, 0xa6, 0x50, 0xc8, 0x92, 0xa2, 0xcc, 0x87, + 0xf9, 0x6e, 0x9c, 0xde, 0xb8, 0xd0, 0xf4, 0x94, 0xe9, 0x05, 0x75, 0x50, + 0x0a, 0x02, 0xca, 0xc2, 0x55, 0xfb, 0x91, 0x83, 0xfd, 0xbf, 0x7d, 0x07, + 0xc2, 0x12, 0x78, 0xb6, 0x7c, 0xe3, 0xfe, 0x1b, 0x60, 0x0f, 0x63, 0xa3, + 0x2b, 0x65, 0x29, 0x71, 0xa7, 0x32, 0x48, 0xb1, 0xc4, 0x62, 0x39, 0x76, + 0x3b, 0x64, 0x11, 0x81, 0xa9, 0x40, 0x47, 0xb1, 0x17, 0x18, 0x43, 0x3f, + 0xf1, 0x9a, 0x0a, 0xda, 0x2a, 0x66, 0x91, 0xd5, 0x5c, 0x4e, 0x14, 0xee, + 0xc1, 0x46, 0x41, 0xfd, 0xf5, 0x15, 0x92, 0xeb, 0x5d, 0x68, 0xa5, 0xf9, + 0xb6, 0x71, 0x2b, 0x99, 0x83, 0xcb, 0x4e, 0xe7, 0x39, 0xce, 0x70, 0x40, + 0xec, 0x71, 0xdf, 0x5f, 0xae, 0x55, 0x15, 0x17, 0xdb, 0x89, 0x96, 0xd9, + 0x28, 0x86, 0x9e, 0x89, 0x49, 0x91, 0xe4, 0x7f, 0x0c, 0xc9, 0xb6, 0x4f, + 0x2e, 0x77, 0xea, 0x31, 0xf8, 0xd0, 0x6f, 0x1a, 0xca, 0x6a, 0x24, 0x97, + 0x2e, 0xae, 0xc1, 0x06, 0x5b, 0x3c, 0xc4, 0x75, 0x27, 0xd7, 0x52, 0x93, + 0x54, 0xce, 0x8e, 0x2a, 0x9c, 0x29, 0xa3, 0x43, 0xab, 0xb3, 0x5a, 0x38, + 0xae, 0x85, 0x2b, 0x56, 0x23, 0x1c, 0xc1, 0x7c, 0xb2, 0xa7, 0xd6, 0x87, + 0xd0, 0xfa, 0x8d, 0x51, 0x78, 0xa3, 0x86, 0x2e, 0x16, 0xb8, 0xfc, 0x59, + 0x23, 0x33, 0xc4, 0x36, 0x33, 0x46, 0x3f, 0x72, 0x3b, 0x6a, 0xcd, 0xc0, + 0xb7, 0xe8, 0xa9, 0x7f, 0xfa, 0x7c, 0xbf, 0xcb, 0x5e, 0x63, 0xe1, 0x9c, + 0xec, 0x3d, 0xb5, 0x7f, 0x0c, 0x93, 0x47, 0xb8, 0x0c, 0xa7, 0xa8, 0xd2, + 0x37, 0x38, 0x3a, 0x7c, 0x99, 0xa7, 0x97, 0x26, 0x9d, 0xd7, 0xa3, 0xcf, + 0xf6, 0xe0, 0xaf, 0x1c, 0xc3, 0x38, 0xe8, 0x41, 0xfb, 0x6d, 0xa6, 0xd6, + 0x8a, 0x3a, 0x99, 0xec, 0xb5, 0x66, 0x2a, 0x81, 0x4e, 0xbb, 0x82, 0x4a, + 0x92, 0x09, 0x2d, 0xd3, 0x6f, 0xb6, 0x8e, 0xf8, 0xad, 0x45, 0x4f, 0x6f, + 0xe2, 0xaa, 0x24, 0xa3, 0x8c, 0x43, 0x1d, 0x54, 0x1c, 0xcd, 0x1a, 0x0c, + 0x2f, 0x30, 0x27, 0xcd, 0xf7, 0xd7, 0x74, 0x73, 0x46, 0x6c, 0xc9, 0x47, + 0x17, 0xf2, 0xf0, 0xdc, 0xcd, 0x8d, 0xf7, 0x3d, 0x75, 0x32, 0x4e, 0xe9, + 0x0c, 0xcd, 0x3d, 0xf0, 0x8b, 0x06, 0xb1, 0xd3, 0xc9, 0x41, 0x6f, 0xf1, + 0x50, 0xa8, 0x74, 0x97, 0x99, 0x64, 0xcf, 0x5d, 0xf3, 0xfa, 0xeb, 0x5e, + 0xe1, 0xa5, 0x3c, 0x79, 0xf1, 0x16, 0x8a, 0x9a, 0xd1, 0x0d, 0x55, 0xae, + 0x8d, 0x60, 0xe4, 0x90, 0xcd, 0x27, 0x3b, 0x04, 0x2b, 0xfc, 0xc2, 0x01, + 0xff, 0x00, 0x10, 0x3f, 0xbe, 0xb3, 0x6b, 0x5f, 0x83, 0x15, 0x39, 0x12, + 0x29, 0x2e, 0x58, 0x88, 0x80, 0xe8, 0x0f, 0xa9, 0x1a, 0x63, 0xc3, 0xb7, + 0x4e, 0x29, 0xb4, 0xde, 0x3e, 0x6a, 0x82, 0xb1, 0xe2, 0x98, 0x73, 0x24, + 0x6d, 0x1a, 0xe7, 0x00, 0xec, 0x40, 0xfc, 0x77, 0xd2, 0xf2, 0xe4, 0x86, + 0xeb, 0x92, 0xe8, 0xcb, 0x29, 0xf2, 0x8b, 0xdd, 0xd1, 0x28, 0xed, 0xb7, + 0xaa, 0x9b, 0x75, 0x2d, 0x4c, 0x6f, 0x0c, 0x32, 0xbc, 0x4a, 0x92, 0x1f, + 0x3e, 0x15, 0xb1, 0xe6, 0x1e, 0xbb, 0x68, 0xde, 0x0b, 0xe0, 0xbe, 0x17, + 0xe2, 0x0b, 0xdd, 0x7b, 0x5c, 0xe5, 0xa8, 0x89, 0xe3, 0x8b, 0xe6, 0xa1, + 0x2b, 0x22, 0x88, 0x9b, 0x0a, 0x32, 0x47, 0xe7, 0x72, 0x35, 0x44, 0xe2, + 0x5a, 0x49, 0xe4, 0xba, 0xc7, 0x70, 0x84, 0x08, 0xe6, 0x91, 0x33, 0x50, + 0x06, 0xc0, 0x38, 0xeb, 0xb7, 0xbe, 0x73, 0xf7, 0xce, 0x9e, 0xf0, 0x7c, + 0x52, 0xbd, 0xa1, 0x1e, 0x4d, 0xbc, 0x09, 0x48, 0x76, 0x0f, 0xe6, 0xf3, + 0x6f, 0x9c, 0x7a, 0x7f, 0xd3, 0x5c, 0xb8, 0xe5, 0x58, 0x5b, 0xcb, 0x1e, + 0x53, 0x33, 0xef, 0xa7, 0x67, 0xce, 0x0f, 0xf8, 0x75, 0x5d, 0xc5, 0x57, + 0xab, 0x8d, 0x5b, 0xa1, 0x78, 0x69, 0xb9, 0x9d, 0xd8, 0x37, 0xd6, 0xd9, + 0xf2, 0xa0, 0xf6, 0xc1, 0x3a, 0x9b, 0x8a, 0x6a, 0x20, 0xe1, 0xf4, 0x92, + 0x89, 0xd4, 0xad, 0x74, 0x51, 0x08, 0x84, 0x6c, 0x30, 0xf1, 0xa0, 0xfa, + 0x57, 0x1d, 0x80, 0xdf, 0x57, 0xee, 0x1b, 0xe2, 0xfa, 0x8a, 0x3b, 0x74, + 0x96, 0xfa, 0x0a, 0x95, 0xa6, 0x09, 0x2f, 0x95, 0xd9, 0x72, 0x5d, 0xb1, + 0xbe, 0x07, 0xa6, 0x4e, 0xaa, 0x3c, 0x6d, 0xc5, 0x7c, 0x41, 0x57, 0x53, + 0x2a, 0x57, 0xdb, 0xed, 0x13, 0xa0, 0xc8, 0x69, 0x85, 0x0a, 0x17, 0x91, + 0x7a, 0x0c, 0xb9, 0x05, 0x81, 0xe8, 0x76, 0x23, 0x5b, 0xf4, 0xb9, 0xf1, + 0xea, 0x9d, 0xc1, 0xb5, 0x43, 0xa1, 0x35, 0x2e, 0x8c, 0xb5, 0x65, 0xa9, + 0xaf, 0x97, 0xc4, 0xaa, 0x9d, 0xdc, 0x86, 0xca, 0xa3, 0x1c, 0x80, 0x3d, + 0x46, 0x88, 0x58, 0x23, 0x07, 0x38, 0x27, 0xee, 0x74, 0xc6, 0xe3, 0x70, + 0x8a, 0xa0, 0x08, 0x7e, 0x4a, 0x3a, 0x52, 0x3f, 0x98, 0x0a, 0x1e, 0xa3, + 0xbe, 0x83, 0xe1, 0x4b, 0x8d, 0x9e, 0xe7, 0xc4, 0xb3, 0x59, 0xa7, 0x95, + 0x48, 0x10, 0x12, 0x18, 0xb7, 0x2a, 0xb3, 0x02, 0x36, 0xfd, 0x37, 0xd6, + 0xa6, 0xdd, 0xf2, 0xc2, 0xb3, 0xf2, 0x4f, 0x43, 0x44, 0x5a, 0xb2, 0xb2, + 0x39, 0x5d, 0x62, 0x52, 0xd1, 0xac, 0x6a, 0x0f, 0xf3, 0x3f, 0xa7, 0x39, + 0xfe, 0x9f, 0x5f, 0xd3, 0xbe, 0xad, 0x22, 0xf8, 0xfc, 0x4b, 0x6c, 0xa2, + 0xb8, 0xcf, 0x6d, 0x7a, 0x3a, 0xaf, 0x07, 0xc2, 0x92, 0x45, 0x1f, 0xcb, + 0x94, 0xaf, 0x42, 0x3d, 0x0e, 0x3b, 0x63, 0xfa, 0x75, 0x35, 0x87, 0x84, + 0xc5, 0xf3, 0x88, 0x63, 0xb1, 0x59, 0x68, 0xe3, 0xa9, 0x9a, 0x37, 0x06, + 0xb8, 0x01, 0x88, 0x69, 0xc7, 0xac, 0x87, 0xb1, 0x3e, 0x9d, 0x75, 0xe8, + 0x7e, 0x1e, 0xf8, 0x79, 0x62, 0xb6, 0xf0, 0xf1, 0xb4, 0xc9, 0x09, 0x96, + 0x39, 0x7c, 0xd2, 0xa8, 0x1c, 0xab, 0xcc, 0x7a, 0xf2, 0x81, 0xd3, 0xf5, + 0xd1, 0x3d, 0x3a, 0xca, 0xa9, 0x85, 0x1c, 0x7f, 0x22, 0xb3, 0xcb, 0xf5, + 0x34, 0xfc, 0xe3, 0x07, 0x63, 0xeb, 0xa1, 0x16, 0x90, 0xac, 0x98, 0x63, + 0xbf, 0x5c, 0xe3, 0x5e, 0xac, 0x8f, 0xe1, 0x7f, 0x05, 0x2c, 0x85, 0xcd, + 0xa8, 0xb0, 0x23, 0xe9, 0x69, 0xdc, 0x81, 0xf6, 0xdf, 0x5c, 0x5d, 0x7e, + 0x16, 0x70, 0x75, 0x6d, 0x32, 0xc5, 0x15, 0xb8, 0xd1, 0xba, 0x7d, 0x32, + 0xc0, 0xe4, 0x37, 0xe7, 0x3d, 0x46, 0x97, 0x0d, 0x16, 0x48, 0xaa, 0x6e, + 0xcb, 0x8e, 0x96, 0x48, 0xc9, 0xfe, 0x09, 0xd8, 0xae, 0x37, 0x1a, 0x7b, + 0xe8, 0xa2, 0xad, 0x6a, 0x4e, 0x7a, 0x5f, 0x08, 0x4a, 0x14, 0x15, 0x67, + 0x24, 0x10, 0x18, 0x1e, 0xd8, 0x07, 0xa6, 0x94, 0xd1, 0x5c, 0xae, 0xf6, + 0x5b, 0xe5, 0x6f, 0x0b, 0x5d, 0x29, 0x62, 0x47, 0x99, 0x4c, 0x4c, 0x40, + 0xc0, 0x52, 0x08, 0xc3, 0x7b, 0x83, 0x8d, 0x7a, 0x0b, 0x82, 0xb8, 0x6a, + 0x9b, 0x84, 0xec, 0xa6, 0x86, 0x12, 0x66, 0x2f, 0x33, 0x3b, 0x38, 0x5d, + 0xdb, 0x24, 0xe3, 0x3f, 0x8c, 0x0d, 0x65, 0x9f, 0xed, 0x01, 0x62, 0x9a, + 0xae, 0xb0, 0x5f, 0xe8, 0x23, 0xfe, 0x65, 0x2a, 0xac, 0x53, 0x28, 0x19, + 0x66, 0xe6, 0x3b, 0x6d, 0xfa, 0x7e, 0xba, 0xbc, 0x9a, 0x5f, 0x15, 0x7d, + 0x93, 0x26, 0x0e, 0x0a, 0x79, 0xb3, 0xc8, 0x6a, 0xd6, 0x38, 0xdc, 0x44, + 0xec, 0xdf, 0x50, 0x1e, 0x51, 0x93, 0xad, 0x1f, 0x86, 0xb8, 0x56, 0x86, + 0x8e, 0x96, 0x5a, 0x8b, 0xad, 0x6c, 0x75, 0xf7, 0x06, 0x24, 0x53, 0x25, + 0x31, 0xe6, 0x55, 0x51, 0xd1, 0xbd, 0xf3, 0xfb, 0x67, 0x59, 0x9d, 0x82, + 0xc9, 0x5f, 0x50, 0xcd, 0x4b, 0x77, 0xb9, 0xc9, 0x46, 0x01, 0xf3, 0x43, + 0x19, 0x2c, 0xfd, 0x7e, 0x9d, 0xb6, 0x1e, 0xfd, 0x71, 0xe9, 0xad, 0x83, + 0x82, 0xeb, 0xec, 0x7c, 0x2b, 0x42, 0x20, 0xac, 0x95, 0x90, 0x22, 0x05, + 0xf1, 0xa5, 0x39, 0xe5, 0x03, 0xa0, 0x19, 0xdf, 0x03, 0x5c, 0xfd, 0x2e, + 0x9a, 0x0a, 0x4d, 0x4d, 0x70, 0x2b, 0x0e, 0x15, 0x16, 0xdb, 0x14, 0xd4, + 0xb5, 0x65, 0x65, 0x9a, 0xa2, 0x96, 0x24, 0x11, 0xc4, 0x1c, 0xe1, 0x10, + 0x05, 0xe6, 0x8c, 0x1d, 0x83, 0x0c, 0xe7, 0x27, 0x62, 0x75, 0x50, 0xbc, + 0x3c, 0x31, 0x40, 0x1a, 0xa9, 0xe3, 0x86, 0x28, 0xb2, 0xbb, 0x26, 0x02, + 0xe4, 0xee, 0x4e, 0x37, 0x3b, 0xea, 0xdd, 0xc4, 0xfc, 0x5f, 0xc3, 0xb3, + 0x55, 0xca, 0xd4, 0xa6, 0x59, 0x63, 0xa9, 0x1c, 0xa5, 0xd6, 0x12, 0xbc, + 0x8c, 0x77, 0x27, 0x27, 0xec, 0x75, 0x97, 0xfc, 0x4c, 0xbd, 0xd2, 0x57, + 0xc9, 0x45, 0x6b, 0xb5, 0xac, 0x92, 0xa1, 0x72, 0xd3, 0xc8, 0xfd, 0x5d, + 0xb3, 0x85, 0xfc, 0x60, 0xe8, 0x73, 0x60, 0x59, 0x73, 0xa8, 0x63, 0x92, + 0xa5, 0xd8, 0x39, 0x60, 0xb7, 0x70, 0xc4, 0x5c, 0x4d, 0x6b, 0xa2, 0x9e, + 0xba, 0x13, 0x41, 0x72, 0x86, 0xe1, 0x55, 0x2b, 0xe3, 0xc2, 0x81, 0x58, + 0xf8, 0x64, 0x9c, 0x2a, 0xef, 0x8d, 0xce, 0x75, 0xbd, 0x7c, 0x19, 0xf8, + 0x6f, 0x6e, 0xe1, 0xbb, 0x5b, 0x54, 0xdd, 0x12, 0x9e, 0xaa, 0xf1, 0x3a, + 0x7f, 0x3b, 0x1b, 0xf8, 0x00, 0xff, 0x00, 0x42, 0xff, 0x00, 0x99, 0xfb, + 0x6a, 0x9b, 0xf0, 0xaf, 0x86, 0xe8, 0xa8, 0xab, 0x1e, 0xbe, 0xbd, 0x44, + 0xd5, 0x2a, 0x02, 0xd3, 0x29, 0xc0, 0x45, 0x73, 0xd4, 0xe4, 0xfe, 0x9f, + 0x9d, 0x69, 0xca, 0x12, 0x95, 0xa4, 0x96, 0xa6, 0x59, 0x10, 0xca, 0x87, + 0xf9, 0x3c, 0xbb, 0x02, 0x3a, 0x01, 0xeb, 0xae, 0x9e, 0x1c, 0xf1, 0xde, + 0xe1, 0x1e, 0x90, 0xec, 0x4e, 0x8f, 0x1f, 0x71, 0x08, 0xab, 0xa8, 0xe2, + 0x6b, 0xba, 0x48, 0x42, 0xc2, 0x2b, 0xa6, 0x0b, 0xca, 0x30, 0x48, 0xe7, + 0x6e, 0xfa, 0x56, 0x68, 0xd5, 0x7c, 0xb3, 0x4e, 0x52, 0x2e, 0x6c, 0x2a, + 0x06, 0xc9, 0xfb, 0xea, 0xc1, 0xc4, 0x66, 0x25, 0xe2, 0x1b, 0x97, 0x8a, + 0x55, 0x54, 0xd6, 0x4b, 0x82, 0x4f, 0x7e, 0x73, 0xa5, 0xcd, 0x5b, 0x68, + 0x84, 0x34, 0x6f, 0x39, 0x72, 0x06, 0xea, 0x91, 0x13, 0xbf, 0xa6, 0x4e, + 0x9e, 0x80, 0xdc, 0xb7, 0xbb, 0x42, 0xd9, 0x28, 0xa4, 0x69, 0x0c, 0x18, + 0x0f, 0x01, 0xf3, 0x73, 0xc8, 0x7d, 0xfb, 0x77, 0xfd, 0x3f, 0x5d, 0x10, + 0x94, 0x74, 0xb1, 0xc7, 0x35, 0x74, 0xd4, 0x08, 0xc8, 0x8f, 0xc8, 0x85, + 0x48, 0xe6, 0x66, 0x3d, 0xcf, 0x36, 0x36, 0xf7, 0xc9, 0xd3, 0x4a, 0x29, + 0x20, 0x92, 0x9d, 0x9c, 0x7c, 0xda, 0xc5, 0xc9, 0xe5, 0x0c, 0xa3, 0xcb, + 0xb6, 0xc7, 0x19, 0xce, 0x34, 0x65, 0x0a, 0x2a, 0x70, 0x65, 0x5d, 0xa5, + 0xed, 0xf4, 0x37, 0x25, 0xad, 0x71, 0x22, 0xcd, 0x3c, 0x38, 0x92, 0x26, + 0x52, 0x30, 0x50, 0x9c, 0x15, 0x23, 0xef, 0x8c, 0x9d, 0x66, 0xcc, 0xd5, + 0xd3, 0x1a, 0x8a, 0xbb, 0xc2, 0x22, 0x75, 0x3f, 0xfb, 0x7d, 0x31, 0xe8, + 0x3f, 0xb6, 0xad, 0xd6, 0x3a, 0x8a, 0x51, 0x4d, 0x2b, 0x23, 0x72, 0xa2, + 0x2a, 0xf3, 0x85, 0x3b, 0x92, 0x37, 0xd5, 0x6a, 0x4a, 0x79, 0x67, 0xaf, + 0x58, 0x99, 0x8e, 0xc0, 0x02, 0x71, 0x8f, 0xce, 0xa1, 0xbd, 0x17, 0xb7, + 0x57, 0xab, 0xd3, 0x33, 0x47, 0x95, 0x1e, 0x6c, 0xec, 0x40, 0x18, 0xdc, + 0x69, 0x69, 0x50, 0x89, 0x21, 0xcf, 0x16, 0xd4, 0x51, 0x57, 0x33, 0x54, + 0x5a, 0xe3, 0x96, 0x9a, 0x90, 0xb7, 0x86, 0x91, 0xbb, 0xf3, 0x90, 0x40, + 0x01, 0x8e, 0x70, 0x3b, 0xe7, 0x1e, 0x9a, 0xa5, 0x5c, 0x33, 0x1a, 0x1f, + 0x50, 0x71, 0x9f, 0x6d, 0x34, 0x8e, 0xea, 0x6a, 0x03, 0x25, 0x53, 0x20, + 0x55, 0xc9, 0x18, 0x1f, 0x56, 0x7a, 0x69, 0x5d, 0x5f, 0x33, 0xc8, 0x59, + 0x17, 0x2b, 0x9e, 0x50, 0xa7, 0xbe, 0x4e, 0xb7, 0x3a, 0xa5, 0x43, 0x10, + 0x45, 0x86, 0xde, 0x64, 0x8b, 0xe6, 0x0a, 0x9e, 0x57, 0x3b, 0x9f, 0x5e, + 0xe7, 0x47, 0x5c, 0x2e, 0x73, 0xd1, 0x8f, 0x06, 0x9e, 0x34, 0x03, 0xa2, + 0x67, 0xaa, 0xfb, 0xfb, 0xe9, 0xc5, 0x24, 0x42, 0x1b, 0x4c, 0x54, 0xa5, + 0x70, 0xc1, 0x41, 0x03, 0x3d, 0xf1, 0xbe, 0xab, 0xf7, 0x57, 0x57, 0x06, + 0x1e, 0x5c, 0x31, 0x38, 0x07, 0x3d, 0x3b, 0x1d, 0x13, 0xe1, 0x10, 0x29, + 0x6e, 0x8a, 0x38, 0x42, 0xa2, 0x9e, 0x62, 0x7e, 0x7e, 0x69, 0x79, 0x5d, + 0xf1, 0xf5, 0xab, 0x0c, 0xfe, 0x31, 0xb6, 0xab, 0xa1, 0x82, 0x46, 0x00, + 0x19, 0xc6, 0xda, 0x7b, 0xc4, 0xd5, 0x14, 0x4c, 0x29, 0x61, 0xa3, 0x62, + 0xea, 0xb1, 0x00, 0x77, 0xd8, 0x10, 0x31, 0xa4, 0x72, 0xe0, 0x81, 0xeb, + 0xd7, 0x48, 0x28, 0x69, 0xc3, 0x17, 0x7a, 0xa8, 0xae, 0x94, 0x74, 0x11, + 0x95, 0x58, 0x4c, 0x86, 0x46, 0x23, 0xea, 0x27, 0x38, 0xc6, 0x7d, 0x37, + 0xd3, 0x7f, 0x88, 0x52, 0x98, 0xea, 0xad, 0x92, 0x54, 0x42, 0x66, 0xa5, + 0xf1, 0x5c, 0x4b, 0xca, 0x3a, 0x74, 0xc7, 0xe9, 0xa4, 0x1c, 0x3f, 0x02, + 0xa7, 0x10, 0x51, 0xd5, 0xce, 0x00, 0x8c, 0x2f, 0x2c, 0x67, 0xd5, 0xb2, + 0x3f, 0xeb, 0xa6, 0xff, 0x00, 0x11, 0x24, 0x35, 0x37, 0x33, 0x42, 0x8c, + 0x24, 0x8e, 0x0a, 0x6f, 0x17, 0x38, 0xc6, 0x0f, 0x36, 0xff, 0x00, 0xd8, + 0x69, 0xa9, 0x9a, 0xa2, 0x9d, 0xc6, 0x8e, 0xed, 0xd1, 0xd2, 0x55, 0xdc, + 0xeb, 0xa1, 0xf9, 0x8a, 0x9a, 0x87, 0x34, 0xab, 0x94, 0xc6, 0x59, 0x90, + 0x6f, 0x93, 0xbf, 0xb8, 0x3b, 0x76, 0x07, 0x3a, 0x86, 0xbe, 0x99, 0x60, + 0xa2, 0x8a, 0x51, 0x3a, 0x48, 0x5d, 0x1b, 0x1c, 0x9b, 0x80, 0x01, 0xd8, + 0x7e, 0x9a, 0x67, 0xf0, 0xfe, 0xe5, 0x4e, 0xb5, 0xe2, 0x09, 0x56, 0x34, + 0x9a, 0xa9, 0x42, 0x2b, 0x9f, 0xeb, 0x5c, 0x12, 0xc8, 0x7d, 0x71, 0xb6, + 0x89, 0xbe, 0x51, 0xd3, 0x43, 0xc3, 0x6f, 0x14, 0x14, 0xfe, 0x1c, 0xb5, + 0x35, 0xd2, 0x95, 0x2b, 0xf4, 0x80, 0x0f, 0xfd, 0x3f, 0x7d, 0x18, 0x70, + 0x96, 0xdc, 0x8e, 0x25, 0x66, 0xdf, 0x50, 0x94, 0xce, 0xd8, 0x3c, 0x8c, + 0xe8, 0xbc, 0xad, 0xff, 0x00, 0x31, 0x1a, 0xd2, 0xf8, 0x2a, 0xfa, 0x95, + 0x51, 0x0a, 0x3a, 0x89, 0x57, 0xc7, 0x85, 0x54, 0x33, 0x67, 0xeb, 0xf7, + 0xc6, 0xb3, 0x14, 0x12, 0x47, 0x2a, 0x4b, 0x9e, 0x56, 0x55, 0xc7, 0x4f, + 0xdf, 0x47, 0xdb, 0xe9, 0xdc, 0x89, 0x24, 0x8e, 0x69, 0x3c, 0x58, 0xc0, + 0x20, 0xe7, 0x7d, 0x23, 0x24, 0x2c, 0x76, 0xa3, 0x12, 0xcb, 0x1a, 0x63, + 0x5f, 0x8b, 0x8d, 0x2c, 0x7c, 0x65, 0x6b, 0x95, 0xc7, 0x3c, 0x26, 0x9b, + 0xc9, 0xf6, 0xe6, 0x20, 0xe9, 0xcf, 0x0e, 0xdb, 0x79, 0x28, 0xe9, 0xeb, + 0x4c, 0x69, 0x53, 0x12, 0x02, 0x15, 0x17, 0x62, 0x8d, 0xd8, 0xe4, 0x63, + 0x3d, 0x08, 0xdf, 0x3d, 0x75, 0x56, 0xe2, 0x4a, 0xa9, 0xae, 0x94, 0xb6, + 0xea, 0xa9, 0x9d, 0x9a, 0x5a, 0x34, 0x31, 0xb0, 0x27, 0x24, 0x8d, 0x59, + 0xb8, 0x3e, 0xfb, 0x4d, 0x05, 0xa4, 0xc7, 0xe2, 0x10, 0x00, 0xcf, 0xeb, + 0xac, 0xba, 0xcd, 0xff, 0x00, 0x12, 0x94, 0x7f, 0x66, 0x5c, 0xf8, 0x9c, + 0x31, 0xa4, 0xbd, 0x0b, 0xae, 0x94, 0xf5, 0x35, 0x57, 0x24, 0x9c, 0x2a, + 0xd2, 0x4a, 0xbb, 0xa2, 0xc6, 0xb8, 0x52, 0x77, 0xd8, 0x8f, 0x5e, 0xbb, + 0xea, 0xe7, 0xc0, 0x33, 0x4b, 0x5e, 0xcd, 0x6f, 0xa6, 0xa0, 0x98, 0x56, + 0x49, 0x11, 0x90, 0x2f, 0x3a, 0x9e, 0x60, 0x33, 0xcd, 0xbf, 0xdc, 0x77, + 0xd2, 0x9a, 0xea, 0xda, 0x4b, 0x8d, 0xb8, 0xd5, 0xd3, 0xef, 0x24, 0x4d, + 0xfc, 0xc0, 0x3b, 0x80, 0x0e, 0xfa, 0xe3, 0xfd, 0x9f, 0xa6, 0xa9, 0x8f, + 0x8d, 0xe3, 0x7a, 0x58, 0x64, 0x92, 0x94, 0xb3, 0x78, 0xf2, 0xe3, 0xca, + 0x85, 0x81, 0x3f, 0xe5, 0xfb, 0xe9, 0x2b, 0x4d, 0x1d, 0x42, 0x70, 0x97, + 0x4c, 0xcb, 0x8b, 0x1a, 0xcb, 0x3d, 0xac, 0x86, 0xff, 0x00, 0x59, 0x70, + 0x8e, 0xb8, 0xc9, 0xc8, 0xb1, 0x78, 0x2c, 0x47, 0x29, 0x52, 0x1e, 0x33, + 0xbe, 0xcf, 0x9e, 0xfa, 0xfb, 0xc3, 0x3c, 0x45, 0xf2, 0x97, 0x07, 0xaa, + 0xaa, 0xa7, 0x6a, 0x88, 0x79, 0x1a, 0x29, 0x23, 0x56, 0xe5, 0x3b, 0xff, + 0x00, 0x50, 0x3e, 0xda, 0xf4, 0x9d, 0xc7, 0xe1, 0x87, 0x09, 0x71, 0xc5, + 0x44, 0x57, 0x1b, 0xe5, 0xba, 0x4f, 0x1a, 0x35, 0x18, 0x96, 0x39, 0x0c, + 0x52, 0x3f, 0xff, 0x00, 0x2c, 0x75, 0x03, 0xb6, 0x7a, 0x6a, 0x7a, 0xcf, + 0x84, 0x1c, 0x0b, 0x47, 0x69, 0x31, 0x52, 0xd9, 0xe4, 0xfe, 0x5e, 0x09, + 0x26, 0xa5, 0xcf, 0x3e, 0x3f, 0xc5, 0x93, 0xbe, 0xb5, 0xc7, 0xf1, 0xca, + 0x0a, 0xa0, 0xcd, 0x0f, 0x48, 0xa3, 0xd3, 0x3c, 0xf1, 0x76, 0xe2, 0x2b, + 0xd4, 0x42, 0xa2, 0xec, 0xb6, 0xf8, 0x3f, 0x85, 0x48, 0xe9, 0x4f, 0x13, + 0xc9, 0x4f, 0xcf, 0x18, 0x20, 0x79, 0x4a, 0xbe, 0xc7, 0x9b, 0x6c, 0xed, + 0x8d, 0xf4, 0xca, 0xdf, 0x52, 0xf7, 0x38, 0x17, 0x99, 0x05, 0x4f, 0x24, + 0x79, 0x76, 0x07, 0x00, 0x1f, 0x5d, 0x6b, 0x7c, 0x75, 0xc1, 0x75, 0x1c, + 0x69, 0xc3, 0x27, 0x86, 0xed, 0x2b, 0x4b, 0x4b, 0x0c, 0x72, 0x46, 0xf9, + 0x71, 0xca, 0xaa, 0x17, 0xd9, 0x47, 0xbe, 0xa4, 0xb6, 0xfc, 0x19, 0x16, + 0xfb, 0x04, 0x74, 0x34, 0xf7, 0x58, 0xc4, 0xf8, 0xe5, 0x92, 0x4f, 0x00, + 0xe1, 0x86, 0x37, 0xfe, 0xad, 0x36, 0x1a, 0x79, 0x63, 0xfa, 0x93, 0x26, + 0x99, 0xc1, 0xd2, 0xe4, 0xf2, 0xa7, 0x19, 0x54, 0xc8, 0x95, 0x55, 0x12, + 0x42, 0x39, 0x49, 0x52, 0x83, 0x7e, 0x8b, 0xd3, 0x1a, 0x6f, 0xf0, 0x5b, + 0xe1, 0x07, 0x11, 0xf1, 0xb5, 0xca, 0x1a, 0xc3, 0x1c, 0xf6, 0xdb, 0x42, + 0x38, 0xf1, 0x2b, 0xdc, 0x63, 0x98, 0x67, 0xa4, 0x7f, 0xe2, 0x6f, 0xed, + 0xaf, 0x57, 0xf0, 0x2f, 0xc2, 0x2e, 0x18, 0xe1, 0xe0, 0x2a, 0xeb, 0x28, + 0xa9, 0xee, 0x97, 0x2e, 0x6e, 0x6f, 0x98, 0xa8, 0x8f, 0x98, 0x27, 0xb2, + 0xa9, 0xd8, 0x7d, 0xfa, 0xea, 0xf4, 0xf8, 0xa7, 0x41, 0x1c, 0x68, 0xa8, + 0x8b, 0xb0, 0x54, 0x18, 0x03, 0xf1, 0xad, 0x31, 0x80, 0xd5, 0x8b, 0x81, + 0x67, 0x06, 0x70, 0xb5, 0x9f, 0x84, 0xac, 0xd1, 0xda, 0xec, 0xb4, 0xa2, + 0x18, 0x86, 0xf2, 0x3b, 0x79, 0xa4, 0x99, 0xfb, 0xbb, 0xb7, 0x56, 0x27, + 0x4f, 0x34, 0x2a, 0x4a, 0x09, 0xeb, 0x83, 0xa9, 0x1a, 0x42, 0xcb, 0x82, + 0x34, 0xc4, 0x86, 0x25, 0x47, 0x53, 0x49, 0xc8, 0xa4, 0x8e, 0xb8, 0xce, + 0xa0, 0xa0, 0xac, 0x4a, 0x99, 0x5c, 0x67, 0x74, 0x38, 0x23, 0x5c, 0xd5, + 0x49, 0x88, 0xcf, 0xdb, 0x1a, 0x4d, 0x6b, 0x99, 0xe3, 0xba, 0x4a, 0xc4, + 0xe1, 0x1d, 0xb1, 0xfa, 0x77, 0xd5, 0xd1, 0x76, 0x3c, 0xbe, 0xb4, 0xd1, + 0xda, 0x2a, 0xa4, 0xa6, 0xe6, 0xf1, 0x92, 0x26, 0x64, 0x55, 0xea, 0xc4, + 0x02, 0x70, 0x3d, 0xcf, 0xe7, 0x59, 0x27, 0x0d, 0xdc, 0xe9, 0xaf, 0xfc, + 0x3f, 0x70, 0x14, 0x37, 0xea, 0x5b, 0x6c, 0xaf, 0x2f, 0x8d, 0x53, 0x1c, + 0xc9, 0x99, 0xe3, 0x20, 0x8c, 0x0f, 0x36, 0x01, 0xf7, 0x6d, 0xfa, 0x0d, + 0x6c, 0xaa, 0x43, 0x2e, 0x7a, 0x8d, 0x79, 0x63, 0xe3, 0x1c, 0x6f, 0x07, + 0xc4, 0xab, 0xbc, 0x64, 0x15, 0xcb, 0xab, 0xa6, 0xfb, 0x10, 0xca, 0x0f, + 0xfd, 0xfd, 0xf5, 0x8f, 0x59, 0xe3, 0x14, 0xc4, 0x67, 0x7c, 0x07, 0x3d, + 0x86, 0xae, 0xa6, 0xf1, 0xf2, 0xc6, 0x76, 0xf1, 0x5c, 0xb3, 0x25, 0x64, + 0x47, 0x21, 0x80, 0x04, 0xe7, 0x23, 0x6d, 0xfd, 0x06, 0xa6, 0x58, 0x6e, + 0xb6, 0x8b, 0x85, 0x3f, 0xf1, 0xa8, 0x12, 0xbe, 0x87, 0xc4, 0x1b, 0xcd, + 0x1f, 0x37, 0x32, 0xfb, 0x6f, 0xb6, 0x46, 0xaa, 0xdc, 0x1d, 0x7a, 0xac, + 0xb3, 0x5e, 0xa9, 0xe5, 0x49, 0x0f, 0x82, 0xf2, 0x72, 0xcc, 0xa4, 0xed, + 0xca, 0x7a, 0x9c, 0x7e, 0x9a, 0xd9, 0xb8, 0x9a, 0x4b, 0x5c, 0xf6, 0xb8, + 0xd2, 0x3a, 0x87, 0xa8, 0xe6, 0x41, 0x18, 0x43, 0x16, 0x39, 0x97, 0xa8, + 0xdf, 0x3d, 0x80, 0xd7, 0x2b, 0x0e, 0x24, 0xed, 0x27, 0xc9, 0x96, 0x00, + 0x97, 0x3e, 0x1b, 0xe1, 0x3b, 0x85, 0xbd, 0x6a, 0xa8, 0x2d, 0xa1, 0x15, + 0x9d, 0x9d, 0x0d, 0x3b, 0x91, 0x90, 0x47, 0x42, 0x0e, 0x40, 0x3e, 0xda, + 0xce, 0xab, 0xb8, 0x52, 0x25, 0xbf, 0x41, 0x55, 0x43, 0x89, 0xd2, 0x22, + 0xee, 0x61, 0x99, 0x72, 0xcb, 0xb1, 0x23, 0x3e, 0xa0, 0x6a, 0xdf, 0x6b, + 0x35, 0x34, 0xa1, 0xe9, 0xe9, 0x29, 0x66, 0x78, 0x26, 0x3c, 0xd0, 0xb4, + 0x9f, 0x48, 0x1d, 0xf7, 0xef, 0xbe, 0x35, 0xfa, 0x0a, 0x86, 0xc4, 0x93, + 0xff, 0x00, 0x0a, 0x32, 0xd6, 0x73, 0xf8, 0x11, 0xc9, 0x10, 0xc1, 0x1b, + 0xf4, 0xc7, 0x7e, 0x9a, 0xd9, 0x87, 0x0b, 0x4b, 0x73, 0x8d, 0x30, 0xc9, + 0x78, 0x2a, 0xba, 0xae, 0x59, 0x05, 0xbe, 0xaa, 0x99, 0x24, 0xab, 0x8d, + 0x1b, 0xc3, 0x90, 0x30, 0x5f, 0x10, 0x0f, 0xe9, 0xdf, 0x62, 0x71, 0xd3, + 0xed, 0xae, 0xb8, 0x8b, 0x88, 0xa9, 0x25, 0xa6, 0xf9, 0x95, 0x72, 0xf0, + 0x42, 0x07, 0x8d, 0x86, 0xc4, 0x91, 0x63, 0xa8, 0xc1, 0xed, 0x9d, 0xb4, + 0x9b, 0x88, 0xaa, 0xaf, 0x74, 0x9c, 0xa2, 0xae, 0x90, 0x46, 0x86, 0x40, + 0x1d, 0x8a, 0x6e, 0x7a, 0xec, 0x7d, 0xf6, 0xd6, 0x7b, 0xc7, 0x46, 0x94, + 0x5e, 0xb1, 0x49, 0x17, 0x20, 0x68, 0xd5, 0xa4, 0x6c, 0xec, 0xcd, 0xf6, + 0xfc, 0xe8, 0x31, 0xe9, 0xa3, 0x82, 0x4f, 0x22, 0xec, 0xb9, 0x45, 0x41, + 0x5a, 0x33, 0xfe, 0x32, 0x88, 0x0e, 0x29, 0xbb, 0xbb, 0x10, 0x8a, 0x2b, + 0x67, 0x39, 0x27, 0xa9, 0xf1, 0x0e, 0x97, 0x50, 0xbc, 0x3c, 0xe1, 0xde, + 0x15, 0x9f, 0x1b, 0x85, 0x27, 0x6d, 0x1b, 0xc5, 0x4b, 0x2d, 0x47, 0x17, + 0xde, 0x7c, 0x4f, 0xf8, 0x6b, 0x5f, 0x38, 0x07, 0xff, 0x00, 0xf4, 0x3b, + 0x6b, 0xf5, 0x05, 0x0b, 0x4a, 0xc0, 0x47, 0xf4, 0xf5, 0x63, 0x8f, 0xdb, + 0x4c, 0x7d, 0x99, 0xe7, 0xf6, 0x67, 0x75, 0x35, 0xb3, 0x4c, 0xea, 0xef, + 0x4e, 0xab, 0x10, 0xc7, 0x94, 0x36, 0xe7, 0xf3, 0x8d, 0x47, 0x25, 0xc2, + 0xae, 0xaa, 0x9b, 0x7c, 0xc4, 0x80, 0x91, 0x84, 0x63, 0x8d, 0xf4, 0x5d, + 0x72, 0x43, 0x0c, 0x4d, 0x1b, 0x46, 0xdb, 0x0c, 0x82, 0x47, 0x7d, 0x2c, + 0x89, 0x83, 0x92, 0x80, 0xf2, 0xe3, 0xaf, 0xbe, 0x95, 0x96, 0xe5, 0xd8, + 0x1b, 0xda, 0x54, 0x86, 0x9c, 0x39, 0x17, 0xf3, 0x86, 0xd8, 0xdc, 0xef, + 0xa2, 0xae, 0xeb, 0x43, 0x25, 0xd6, 0x1a, 0x6a, 0xe0, 0x48, 0x68, 0x18, + 0xa9, 0x53, 0x82, 0xa7, 0x98, 0x60, 0xff, 0x00, 0x7d, 0x15, 0xc2, 0x54, + 0xdf, 0x54, 0x84, 0x63, 0xcb, 0xb1, 0xf5, 0xd5, 0x4e, 0xfd, 0x5f, 0x3b, + 0xf1, 0x7b, 0xbb, 0xb6, 0x4c, 0x4e, 0x23, 0x5f, 0x60, 0x32, 0x31, 0xa7, + 0x41, 0xf2, 0x83, 0x8b, 0x0b, 0xbc, 0x59, 0x1a, 0x98, 0x37, 0xcb, 0xc8, + 0x25, 0x55, 0x19, 0x23, 0x9b, 0x24, 0x7e, 0x7b, 0xe8, 0x1b, 0x4a, 0xab, + 0xd5, 0xc4, 0x65, 0x1c, 0xcc, 0x18, 0x60, 0x74, 0xdb, 0x1a, 0xb5, 0xc1, + 0x50, 0x95, 0x36, 0xf8, 0xa7, 0x45, 0x1e, 0x2c, 0x43, 0x1b, 0x9e, 0xa4, + 0x6c, 0x47, 0xe7, 0x55, 0x4a, 0x80, 0x61, 0xb9, 0x4b, 0x2a, 0x46, 0xd1, + 0xa3, 0x13, 0xca, 0x06, 0xe4, 0x12, 0x7a, 0x69, 0xcb, 0xc3, 0x25, 0x16, + 0x5a, 0x89, 0x12, 0x47, 0x91, 0xf5, 0x0d, 0xf5, 0x55, 0xe2, 0x66, 0x4a, + 0x69, 0x0d, 0x44, 0x67, 0xcf, 0x9f, 0xd0, 0xe9, 0x9b, 0xd4, 0x4c, 0x82, + 0x92, 0x26, 0x86, 0x68, 0xda, 0xa1, 0x80, 0x42, 0xd1, 0xf6, 0xe8, 0x71, + 0xbf, 0x5d, 0x53, 0x78, 0xb6, 0xa1, 0xa3, 0xe2, 0x1a, 0x8a, 0x0c, 0x3a, + 0xc3, 0x4f, 0x21, 0x8c, 0xc6, 0xdd, 0x43, 0x03, 0xe6, 0xcf, 0xbe, 0x46, + 0xaf, 0x3e, 0x54, 0xfc, 0x50, 0x49, 0x86, 0x96, 0x79, 0x5b, 0xc4, 0x73, + 0x92, 0x7a, 0xeb, 0x87, 0xcf, 0x36, 0x74, 0x4b, 0x18, 0xe5, 0xa7, 0x8e, + 0x48, 0x54, 0x05, 0x2b, 0xa2, 0xf8, 0x7e, 0xdf, 0x51, 0x57, 0x5c, 0xb2, + 0x47, 0x1a, 0x48, 0x91, 0x9e, 0x66, 0x0f, 0x9c, 0x1c, 0x1e, 0x87, 0x1a, + 0x5a, 0xe8, 0xb3, 0xba, 0x41, 0xfc, 0x3e, 0x38, 0x6b, 0xe4, 0x6c, 0x3c, + 0x11, 0x16, 0x89, 0x39, 0x72, 0x09, 0x6d, 0xc1, 0x3f, 0x63, 0x83, 0xa8, + 0x6d, 0xa9, 0x1d, 0x4b, 0x9a, 0xaa, 0x89, 0x32, 0x5c, 0x31, 0xa8, 0x90, + 0x8e, 0x63, 0xd3, 0xaf, 0xf6, 0xc6, 0xac, 0x17, 0xb1, 0x59, 0x32, 0xcc, + 0x95, 0x0b, 0x0a, 0xf9, 0x08, 0x41, 0x1a, 0x72, 0xa8, 0xff, 0x00, 0x97, + 0x19, 0xd2, 0x9b, 0x3c, 0xd1, 0xc0, 0x94, 0x91, 0x14, 0x42, 0xf2, 0xc0, + 0xf0, 0x37, 0x30, 0xcf, 0x29, 0x23, 0x63, 0xa6, 0x23, 0x7e, 0x9f, 0x95, + 0x60, 0xdc, 0x2d, 0x22, 0xcb, 0x0c, 0x88, 0xcf, 0x29, 0xa9, 0x86, 0x63, + 0x24, 0x4c, 0xa4, 0xe5, 0x81, 0x1d, 0xf1, 0xf6, 0xd5, 0xba, 0x3a, 0xb8, + 0xab, 0xf8, 0x6e, 0x38, 0x48, 0x65, 0x9e, 0x4f, 0x17, 0x92, 0x10, 0x3e, + 0x97, 0x56, 0xff, 0x00, 0x3c, 0xe3, 0x3e, 0xda, 0x43, 0xc3, 0x4d, 0x10, + 0xb9, 0x1f, 0x91, 0x4c, 0xcb, 0x4e, 0x18, 0xbc, 0x8c, 0x00, 0x51, 0xb7, + 0x98, 0x31, 0x3d, 0xbb, 0x0f, 0x4d, 0xb5, 0xf2, 0x9f, 0xf9, 0xbc, 0x49, + 0x0c, 0x85, 0x84, 0x8b, 0x34, 0x26, 0xa2, 0x6c, 0x9c, 0x98, 0xf2, 0x32, + 0xc0, 0x1e, 0xfb, 0xe3, 0xf4, 0xd1, 0xa6, 0x5a, 0x85, 0x4a, 0xc8, 0x61, + 0x91, 0x7c, 0xa9, 0x22, 0x81, 0x20, 0x1f, 0x4b, 0x0e, 0x87, 0xd3, 0xef, + 0xa2, 0x62, 0x63, 0x4d, 0x2a, 0x54, 0x14, 0xe5, 0x0c, 0x4a, 0xb2, 0xe7, + 0xb6, 0x86, 0x42, 0xf2, 0x09, 0x9d, 0xfe, 0xb2, 0xdc, 0xf9, 0xf7, 0x27, + 0x4c, 0xae, 0x54, 0xc1, 0x6d, 0xf4, 0xd5, 0x87, 0xac, 0xab, 0xca, 0xdf, + 0x71, 0xd3, 0x43, 0x66, 0xcb, 0x21, 0x30, 0x14, 0xb9, 0xff, 0x00, 0x31, + 0x1e, 0x28, 0x66, 0x5c, 0x83, 0x8d, 0x98, 0x7d, 0xf4, 0x1d, 0xd1, 0x15, + 0x2c, 0xd5, 0x6a, 0xb1, 0xf3, 0x34, 0x28, 0xd2, 0x28, 0x0c, 0x40, 0x20, + 0x03, 0xb1, 0xc7, 0x51, 0xa7, 0xd1, 0x47, 0xf3, 0x02, 0xcc, 0x5d, 0xb9, + 0xd4, 0xc6, 0xeb, 0x9f, 0x42, 0x08, 0x1a, 0x89, 0x21, 0x8d, 0x2e, 0x8f, + 0x04, 0xcb, 0x98, 0xca, 0xb0, 0xfb, 0x8d, 0x4b, 0x24, 0xe3, 0xc1, 0x4b, + 0xb2, 0x99, 0x3c, 0x08, 0xe4, 0x32, 0x25, 0x24, 0x72, 0xec, 0xdc, 0xf2, + 0x16, 0xc8, 0xef, 0xb6, 0x33, 0x8d, 0x6b, 0x3f, 0x09, 0x67, 0xa2, 0xb4, + 0xf1, 0xc5, 0x80, 0xc1, 0x75, 0x49, 0x12, 0xa2, 0xa1, 0x44, 0xa8, 0xb1, + 0x91, 0xb6, 0x3a, 0x80, 0x7b, 0x7f, 0xae, 0xa9, 0x13, 0x9b, 0x5d, 0xb1, + 0x27, 0xa2, 0xaf, 0x94, 0xc0, 0xc8, 0xc7, 0xc1, 0x65, 0x21, 0x81, 0x5c, + 0xe0, 0x65, 0x7e, 0xda, 0x55, 0x45, 0x55, 0x15, 0x1d, 0xca, 0x39, 0x29, + 0xe4, 0x2b, 0x89, 0x39, 0xe1, 0x60, 0x70, 0xcb, 0x83, 0xdb, 0xdb, 0x52, + 0x16, 0x9f, 0x28, 0xe7, 0x38, 0xf2, 0x7b, 0xea, 0x4b, 0xcd, 0x6d, 0xbe, + 0xef, 0x4d, 0x45, 0x0d, 0xb6, 0x69, 0xe8, 0x66, 0x1b, 0xce, 0xb9, 0x21, + 0x0f, 0xf9, 0x68, 0x8b, 0xdf, 0x11, 0x4f, 0x47, 0x75, 0xa3, 0xa0, 0xa6, + 0xb4, 0xcd, 0x58, 0x95, 0x07, 0x0c, 0xe8, 0xdb, 0x2f, 0xa9, 0x3b, 0x1d, + 0x65, 0x3f, 0x07, 0x3e, 0x2c, 0x45, 0x7e, 0xa7, 0x92, 0xd3, 0x5c, 0x39, + 0x6e, 0x09, 0x1f, 0x2a, 0x11, 0xd2, 0x53, 0x8e, 0xb8, 0xed, 0xd3, 0x5a, + 0x65, 0x96, 0xed, 0x53, 0x25, 0xa9, 0x5a, 0xb5, 0x39, 0x6b, 0x5c, 0x9e, + 0x6c, 0x2e, 0x00, 0x1a, 0xd3, 0x43, 0x93, 0x2c, 0xf4, 0x2b, 0x04, 0x61, + 0x96, 0x24, 0xe5, 0x27, 0x73, 0xeb, 0xed, 0xa2, 0x5d, 0xd5, 0x17, 0x2d, + 0xf6, 0xd2, 0x9b, 0x5c, 0xc5, 0x61, 0x52, 0xdb, 0x93, 0xbe, 0x74, 0x75, + 0x44, 0x88, 0xf0, 0x1d, 0x1d, 0x96, 0xd9, 0x29, 0x94, 0x75, 0x07, 0x6c, + 0x68, 0x2a, 0xc9, 0xb6, 0x03, 0x27, 0x73, 0x8d, 0x41, 0x2c, 0x98, 0x5c, + 0x73, 0x76, 0xd0, 0xd3, 0x4b, 0x90, 0xbe, 0x6e, 0x9b, 0xea, 0x14, 0x1d, + 0x03, 0x79, 0x80, 0x3b, 0xfb, 0xe8, 0x95, 0x21, 0x77, 0x63, 0x8d, 0x2e, + 0xa5, 0x94, 0x39, 0x07, 0x47, 0x9f, 0x32, 0x11, 0xea, 0x35, 0x08, 0x2c, + 0xbb, 0xd4, 0x72, 0x82, 0x01, 0xfb, 0x68, 0x2a, 0x75, 0x21, 0x10, 0x8f, + 0xa8, 0xef, 0xae, 0x6e, 0x44, 0x9a, 0xd1, 0x1b, 0x74, 0xd1, 0x74, 0x91, + 0x86, 0x95, 0x41, 0xc0, 0x5e, 0xe4, 0x9c, 0x76, 0xd0, 0xc8, 0xbf, 0x56, + 0x35, 0xa2, 0xa8, 0xcc, 0x18, 0x3b, 0x91, 0xac, 0xd7, 0xe3, 0x77, 0x06, + 0xd5, 0x5f, 0x0c, 0x17, 0xdb, 0x72, 0xc6, 0x65, 0x82, 0x13, 0x1c, 0xca, + 0xcc, 0x17, 0x2a, 0x0e, 0x41, 0xcf, 0x73, 0xbf, 0x4d, 0x5a, 0x6c, 0xf7, + 0x8a, 0x09, 0xa4, 0x6a, 0x68, 0x2a, 0x01, 0x62, 0xc7, 0xcb, 0xe8, 0x7d, + 0x34, 0xf2, 0x0a, 0x98, 0xd9, 0x4c, 0x13, 0xae, 0x53, 0x3b, 0xfa, 0x1f, + 0xbe, 0xb3, 0xc5, 0xc3, 0x53, 0x8d, 0xa1, 0x52, 0x71, 0xc8, 0xb6, 0xa6, + 0x79, 0x49, 0xa9, 0xe5, 0x8d, 0xf9, 0x1e, 0x32, 0x0e, 0x31, 0x9e, 0xda, + 0xbd, 0x58, 0xab, 0x26, 0x7b, 0x4c, 0x34, 0x4a, 0x04, 0xd5, 0x0a, 0xa3, + 0x94, 0xbf, 0x51, 0xe8, 0x3e, 0xda, 0xd4, 0xef, 0x5c, 0x07, 0xc3, 0x37, + 0x69, 0x3c, 0x6f, 0x0e, 0x4a, 0x67, 0x0d, 0x9c, 0xc0, 0xc0, 0x64, 0xfd, + 0x88, 0x3a, 0x92, 0xd1, 0xc2, 0xdc, 0x37, 0x60, 0xcc, 0xf1, 0xc6, 0xd3, + 0x54, 0x0f, 0x31, 0x79, 0xbc, 0xc7, 0xf4, 0xe9, 0xac, 0x7a, 0x5d, 0x04, + 0xb1, 0xcd, 0xb6, 0xf8, 0x11, 0x0d, 0x3b, 0x83, 0xe4, 0x49, 0xc2, 0xfc, + 0x39, 0x72, 0xac, 0x8a, 0x37, 0xbb, 0xc5, 0x4c, 0xb4, 0x44, 0x15, 0x6a, + 0x67, 0x4c, 0xb3, 0x83, 0x82, 0x18, 0x10, 0x46, 0x3a, 0x68, 0x3e, 0x36, + 0xb1, 0x35, 0x92, 0xa6, 0x3a, 0xfa, 0x31, 0x31, 0xa5, 0x3b, 0x2a, 0x46, + 0x76, 0x88, 0xf4, 0xdf, 0x3f, 0x7e, 0xba, 0xb0, 0x71, 0x0d, 0xfe, 0x0a, + 0x78, 0xcc, 0xb3, 0x55, 0x88, 0x3c, 0xb9, 0x89, 0x72, 0x00, 0x3e, 0x99, + 0xc9, 0x03, 0x1f, 0xe9, 0xaa, 0x5c, 0x7f, 0x16, 0x2d, 0x36, 0x62, 0xd4, + 0xf5, 0xd7, 0x1f, 0xe2, 0x21, 0x9f, 0x99, 0x97, 0x93, 0x9d, 0x87, 0xa8, + 0xe6, 0x1e, 0x50, 0x07, 0xa0, 0x27, 0x5b, 0xd4, 0x03, 0xd8, 0x9f, 0x42, + 0xfa, 0x4e, 0x17, 0xae, 0x37, 0x75, 0xbc, 0xd7, 0xd5, 0x8a, 0xce, 0x64, + 0x23, 0xc0, 0x66, 0xce, 0x33, 0xbe, 0x73, 0xed, 0xd3, 0x54, 0x1f, 0x8a, + 0x94, 0x33, 0xc1, 0xc4, 0x9e, 0x38, 0xa4, 0x30, 0xc1, 0x34, 0x4a, 0x50, + 0x21, 0xe6, 0x24, 0x8c, 0x0d, 0xbf, 0xd3, 0x57, 0x4b, 0xc7, 0xc5, 0x4e, + 0x1b, 0xbc, 0x56, 0xc9, 0x0d, 0xb2, 0xd7, 0x74, 0xab, 0x90, 0x27, 0x24, + 0x2b, 0x4d, 0xf4, 0xc4, 0xc3, 0x6c, 0x9c, 0xed, 0x81, 0xef, 0x81, 0xaa, + 0xb9, 0x5b, 0x9d, 0x7c, 0x82, 0xbe, 0xf1, 0x0c, 0xa2, 0x9f, 0x18, 0x8e, + 0x57, 0xab, 0x40, 0x99, 0xea, 0x72, 0xc0, 0x04, 0x03, 0xdb, 0x9b, 0xf5, + 0x3a, 0xcb, 0x2c, 0x79, 0x25, 0x26, 0x9a, 0x2f, 0xf8, 0xae, 0x5d, 0x99, + 0xbf, 0x10, 0xd1, 0x49, 0x51, 0xc4, 0xf7, 0x18, 0x60, 0x4f, 0x11, 0x9e, + 0xb6, 0x5c, 0x8e, 0x9d, 0x5c, 0xef, 0xaf, 0xd7, 0x27, 0xa6, 0xb5, 0xdb, + 0x7f, 0x87, 0xc5, 0x2b, 0x7c, 0xcb, 0x6e, 0xee, 0x9d, 0xbd, 0x8e, 0xae, + 0x8b, 0x69, 0xaa, 0x9a, 0xff, 0x00, 0x51, 0x41, 0x6c, 0xa6, 0xf1, 0xee, + 0x97, 0x4a, 0xa9, 0x92, 0x05, 0xce, 0xc0, 0x73, 0x12, 0x58, 0x9f, 0xe9, + 0x03, 0x1a, 0x33, 0x8c, 0x3e, 0x03, 0xf1, 0x3d, 0x05, 0x8e, 0xba, 0xf1, + 0xf3, 0xf4, 0xf5, 0xa6, 0x91, 0x11, 0xd2, 0x08, 0x54, 0x97, 0x75, 0xc6, + 0x64, 0x3f, 0xfe, 0xbe, 0x9b, 0xe7, 0xdb, 0x57, 0x91, 0x78, 0xd9, 0x96, + 0x78, 0x9b, 0x6d, 0xa3, 0x19, 0xab, 0xa9, 0x96, 0x56, 0x26, 0x49, 0x1e, + 0x42, 0x06, 0x01, 0x63, 0x9d, 0x4b, 0x6a, 0x89, 0x5d, 0x59, 0x83, 0x79, + 0xbd, 0x31, 0xa8, 0xe7, 0xa6, 0x90, 0x30, 0x52, 0xaf, 0xcf, 0x9d, 0xd7, + 0x97, 0x7d, 0x3c, 0xb6, 0x5b, 0xda, 0x9a, 0x8f, 0xc7, 0x64, 0x09, 0x2c, + 0xa5, 0x17, 0x04, 0x67, 0x0a, 0x71, 0x81, 0xf7, 0xff, 0x00, 0xc6, 0xb1, + 0xa7, 0xb8, 0xcc, 0xe0, 0x19, 0x67, 0xb8, 0x47, 0x6d, 0x82, 0x59, 0x67, + 0x93, 0x96, 0x30, 0xa4, 0x6b, 0x3c, 0xb8, 0x39, 0x9e, 0xe9, 0x51, 0x3a, + 0x93, 0x99, 0x27, 0x66, 0x5c, 0xf6, 0x19, 0x3a, 0xd3, 0x69, 0x68, 0xd3, + 0xe6, 0x5a, 0xa2, 0xa6, 0x30, 0xe3, 0x9b, 0x11, 0xa9, 0x18, 0xc0, 0xf5, + 0xfb, 0xeb, 0x39, 0xbb, 0xd2, 0x9a, 0x6b, 0xbd, 0x44, 0x1c, 0xc4, 0xf2, + 0xc8, 0x70, 0x71, 0xef, 0xa7, 0xec, 0xa4, 0x83, 0x8a, 0xa2, 0xc1, 0xc3, + 0xb5, 0x8d, 0x08, 0x62, 0x42, 0xb8, 0x65, 0x1e, 0x56, 0x19, 0x04, 0xea, + 0xc5, 0xc2, 0xd4, 0xf0, 0xdc, 0x38, 0x80, 0x07, 0x89, 0xe9, 0xbc, 0xa7, + 0x2c, 0x06, 0x42, 0x9c, 0x8f, 0xb6, 0xda, 0xa7, 0xd2, 0x18, 0xd6, 0x8c, + 0xc6, 0xc0, 0x99, 0x41, 0x05, 0x5b, 0xdb, 0x5a, 0x0f, 0x00, 0xa5, 0x6a, + 0x8a, 0x79, 0x62, 0x85, 0xd9, 0x2a, 0x33, 0x0b, 0xbe, 0x3c, 0xb8, 0xe5, + 0xce, 0x33, 0xeb, 0xb8, 0x3a, 0x73, 0x9d, 0x2b, 0xfd, 0x06, 0x32, 0xe2, + 0xee, 0x1c, 0xb0, 0xd8, 0xfe, 0x21, 0xd0, 0x0a, 0xab, 0xbd, 0x45, 0x55, + 0x35, 0x34, 0x70, 0x4c, 0x44, 0x6a, 0x3e, 0xb2, 0xbc, 0xc5, 0x48, 0x1e, + 0xf8, 0xeb, 0xd3, 0x3a, 0xcd, 0x38, 0xa6, 0xcf, 0x4b, 0x5d, 0xc6, 0xb7, + 0xab, 0xa4, 0xf5, 0x11, 0x52, 0xc5, 0x2c, 0x8e, 0xeb, 0x19, 0x04, 0x99, + 0x25, 0x7d, 0xf9, 0x17, 0x19, 0xe9, 0x83, 0xbf, 0xdb, 0xd7, 0x56, 0xab, + 0xdd, 0xd6, 0x3b, 0xab, 0x19, 0xa2, 0x6e, 0x49, 0xa1, 0x25, 0x1c, 0x31, + 0xfa, 0x58, 0x10, 0x33, 0xf6, 0xdb, 0x55, 0x8f, 0x88, 0x15, 0xd4, 0xa6, + 0x3b, 0x5c, 0x14, 0x30, 0x39, 0xae, 0x87, 0x9d, 0xab, 0x66, 0x32, 0x65, + 0x67, 0x91, 0xfb, 0xa6, 0xdb, 0x00, 0x30, 0x3f, 0x1a, 0xcc, 0xa5, 0xf2, + 0x64, 0xe3, 0xa2, 0xd1, 0x52, 0x2f, 0xfc, 0x3e, 0x8a, 0x65, 0x48, 0xc4, + 0xb2, 0x87, 0x0a, 0xa5, 0x86, 0x00, 0x04, 0x1c, 0x6d, 0xed, 0x8d, 0x4d, + 0x69, 0xe2, 0xbb, 0xc5, 0x34, 0x4b, 0x1c, 0x12, 0xc5, 0x1a, 0xa8, 0x21, + 0x93, 0xc3, 0x18, 0x66, 0xf5, 0x3d, 0xce, 0x87, 0xe2, 0x58, 0xd9, 0x2b, + 0xa3, 0xb6, 0x42, 0xe1, 0xc5, 0x10, 0xc0, 0x23, 0x6c, 0xb9, 0xc1, 0x63, + 0xf8, 0x27, 0x1a, 0x0c, 0x4b, 0x19, 0x5e, 0x42, 0xac, 0x58, 0x7f, 0xc4, + 0x38, 0xfa, 0x4e, 0xb5, 0xf4, 0x39, 0x16, 0x7b, 0x15, 0xc6, 0xe7, 0x73, + 0xae, 0x35, 0xb5, 0x0c, 0x25, 0x00, 0x9e, 0x71, 0xd1, 0x11, 0x7d, 0x00, + 0xec, 0x75, 0x2d, 0x4c, 0x40, 0x1a, 0x98, 0xa9, 0xd5, 0xb1, 0x16, 0x64, + 0x4d, 0xf3, 0xe5, 0x27, 0xae, 0x74, 0x82, 0xd1, 0x72, 0xa9, 0xb7, 0x64, + 0x42, 0xd9, 0x89, 0x98, 0x97, 0x18, 0xea, 0x0e, 0xad, 0x36, 0xf9, 0xc5, + 0x6c, 0x2c, 0x88, 0x03, 0x10, 0x79, 0xe2, 0x5f, 0x62, 0x3a, 0x7e, 0xfa, + 0xb4, 0x6c, 0xd3, 0x83, 0x50, 0xc0, 0xb3, 0xd4, 0xc5, 0x5b, 0x01, 0xf0, + 0x96, 0x58, 0xb9, 0x26, 0xe6, 0x53, 0x82, 0xc3, 0x6e, 0xde, 0xa7, 0x18, + 0xd3, 0x7b, 0x2c, 0x71, 0x52, 0xdf, 0xed, 0xf5, 0xf1, 0x0c, 0x53, 0x73, + 0x9a, 0x1a, 0x96, 0x1f, 0xff, 0x00, 0x66, 0x3f, 0xb6, 0x30, 0x7f, 0x3a, + 0x5d, 0x65, 0x45, 0x8a, 0xa5, 0xa1, 0x9d, 0xfc, 0x0d, 0xd8, 0xb6, 0xdc, + 0xc0, 0x95, 0xdf, 0x18, 0xfb, 0x8e, 0xba, 0xea, 0xcf, 0x3a, 0xcb, 0x69, + 0xbc, 0xa5, 0x53, 0xb1, 0x95, 0x58, 0xbb, 0x39, 0x3d, 0xf9, 0x87, 0x2e, + 0x3e, 0xc7, 0x23, 0xf1, 0xa2, 0x43, 0x3d, 0x93, 0x49, 0x11, 0xa7, 0x9a, + 0x78, 0x60, 0x3e, 0x54, 0x6f, 0x5c, 0xe0, 0x69, 0x84, 0x15, 0x08, 0xd6, + 0x41, 0x4f, 0x50, 0x39, 0x8b, 0x49, 0x98, 0x37, 0xdd, 0x98, 0x03, 0xd3, + 0xf7, 0xd0, 0x15, 0x14, 0xb5, 0x0e, 0x94, 0xf7, 0x17, 0x85, 0x9a, 0x39, + 0x23, 0x0b, 0x20, 0x88, 0xe4, 0x82, 0x36, 0x39, 0xd7, 0x0e, 0xc6, 0x98, + 0x2c, 0x94, 0x75, 0x0d, 0xe4, 0x60, 0x40, 0xce, 0xe1, 0xbd, 0xff, 0x00, + 0x7d, 0x50, 0xf4, 0x7e, 0x6a, 0xa9, 0xff, 0x00, 0x85, 0x53, 0x49, 0x48, + 0x18, 0x4b, 0x04, 0xce, 0x84, 0x77, 0xc6, 0x73, 0x9f, 0xdb, 0x45, 0xb2, + 0x4b, 0x2d, 0xe2, 0x63, 0xcc, 0x59, 0xbc, 0x2e, 0x60, 0x01, 0xc6, 0x0e, + 0x3d, 0x75, 0xc9, 0x84, 0x5d, 0xe9, 0x25, 0xa8, 0x5c, 0x53, 0x55, 0x27, + 0xf5, 0x46, 0x70, 0x8c, 0xc7, 0x3e, 0x56, 0x1d, 0x8e, 0x74, 0x4d, 0x9a, + 0x41, 0x58, 0xd4, 0x8d, 0x2e, 0x56, 0xaa, 0x37, 0x30, 0xb8, 0x23, 0xa8, + 0x39, 0xe5, 0x38, 0xfd, 0xb5, 0x54, 0x49, 0x15, 0xae, 0x28, 0xa3, 0x2f, + 0xc4, 0xd3, 0x54, 0x48, 0xac, 0xf0, 0x48, 0x82, 0x52, 0x71, 0xb1, 0x63, + 0x8d, 0x89, 0xf5, 0xeb, 0xa5, 0xdc, 0xb8, 0x6f, 0x11, 0x5b, 0x0f, 0x1e, + 0x42, 0xae, 0x3a, 0x2f, 0xae, 0xad, 0x9c, 0x49, 0x56, 0xf4, 0xf6, 0xfa, + 0x3b, 0x8d, 0x1c, 0x41, 0xd3, 0xc3, 0xe4, 0x92, 0x22, 0xde, 0x5d, 0xb2, + 0x37, 0xfd, 0x35, 0x4b, 0x37, 0xba, 0xda, 0x89, 0x8a, 0x9a, 0x6a, 0x78, + 0x81, 0x18, 0xe9, 0x80, 0x07, 0xaf, 0xbf, 0x6d, 0x15, 0x18, 0x72, 0x7d, + 0xd9, 0x75, 0xf8, 0x4f, 0x7c, 0xa5, 0xb3, 0xf1, 0xc5, 0xb2, 0xbe, 0xa9, + 0x4a, 0x94, 0x94, 0x02, 0xfc, 0xd8, 0x18, 0xf7, 0xd7, 0xb7, 0xa8, 0xea, + 0xe9, 0xea, 0x29, 0xa3, 0x9a, 0x98, 0xa3, 0x41, 0x22, 0x86, 0x46, 0x43, + 0x90, 0x41, 0xe8, 0x75, 0xe0, 0x2b, 0x7c, 0x15, 0x0b, 0x02, 0x4d, 0x3d, + 0x3a, 0x87, 0xce, 0x41, 0xe5, 0xc1, 0x03, 0x5e, 0x90, 0xff, 0x00, 0x67, + 0x6e, 0x2a, 0x6b, 0x85, 0xa4, 0xd8, 0x2b, 0x80, 0x13, 0x52, 0xe5, 0xa9, + 0xb2, 0x73, 0x94, 0xcf, 0x4d, 0x32, 0x2c, 0xa8, 0x48, 0xdd, 0xe0, 0x99, + 0x55, 0xf1, 0xeb, 0xdf, 0x45, 0xbc, 0xbc, 0x89, 0x91, 0xbe, 0xfa, 0x4b, + 0x4a, 0xdc, 0xca, 0x07, 0x71, 0xa2, 0x26, 0x9f, 0x92, 0x22, 0x19, 0xbb, + 0x69, 0xa8, 0x68, 0x45, 0x44, 0xfe, 0x5e, 0xb8, 0xd2, 0xca, 0xa9, 0xfa, + 0xf9, 0xbb, 0xe9, 0x7c, 0xb5, 0x8a, 0xb2, 0x31, 0x2c, 0xaa, 0xbe, 0xa5, + 0x80, 0xc0, 0xd2, 0xea, 0xdb, 0xac, 0x14, 0xea, 0xd3, 0xb3, 0x3b, 0xc0, + 0x33, 0xe7, 0x8d, 0x4b, 0xef, 0xd7, 0xb6, 0xac, 0x83, 0xbb, 0x75, 0x63, + 0xa5, 0x49, 0x8d, 0x8f, 0x95, 0x89, 0x20, 0xea, 0xd1, 0x4a, 0xcc, 0x62, + 0x04, 0xee, 0x35, 0xe7, 0xeb, 0xd7, 0x12, 0x5c, 0xab, 0x49, 0xa9, 0x49, + 0x24, 0xa3, 0x89, 0x1f, 0xc2, 0x86, 0x15, 0xf3, 0x4b, 0x29, 0x39, 0x39, + 0xed, 0xca, 0x36, 0x1b, 0x9f, 0x5e, 0x9a, 0xdb, 0x12, 0xbd, 0xa8, 0xf8, + 0x7e, 0x0a, 0xaa, 0x85, 0x31, 0x4e, 0xd0, 0x2b, 0x14, 0x3d, 0x41, 0x2a, + 0x09, 0xce, 0x91, 0x8b, 0x3a, 0xc9, 0x26, 0x97, 0xa0, 0x20, 0xd4, 0x9d, + 0x20, 0x6b, 0xcb, 0x78, 0x77, 0x50, 0x3a, 0xe4, 0x67, 0x46, 0x51, 0x1f, + 0x19, 0x25, 0x88, 0x0c, 0x17, 0x52, 0x07, 0xdf, 0x1a, 0xa5, 0x35, 0xf2, + 0xbe, 0xe3, 0xc4, 0x51, 0x43, 0x48, 0x61, 0x9e, 0x30, 0xa7, 0xc6, 0x04, + 0x79, 0x90, 0x9d, 0xfa, 0xfd, 0xb5, 0x64, 0xa4, 0xb8, 0x2d, 0x3b, 0xc5, + 0x29, 0x39, 0x05, 0x82, 0xe7, 0xd7, 0x3a, 0xa8, 0xe5, 0x8e, 0x44, 0xf6, + 0xbe, 0x86, 0x5a, 0x92, 0x69, 0x3e, 0x80, 0xa3, 0xe1, 0x1b, 0x65, 0x4c, + 0x4b, 0x2d, 0x7f, 0x96, 0x44, 0x5e, 0x42, 0xb1, 0xca, 0x76, 0x23, 0xb8, + 0xc6, 0x30, 0x74, 0x8a, 0xe4, 0x38, 0x96, 0xc7, 0x7b, 0xa7, 0xb7, 0x5b, + 0x64, 0x96, 0xe7, 0x4b, 0x3a, 0x99, 0x14, 0x48, 0x33, 0x22, 0x28, 0x38, + 0xe5, 0x2d, 0xd8, 0x6e, 0x34, 0xcb, 0x8e, 0xea, 0x64, 0xb4, 0x66, 0x7a, + 0xdb, 0xd5, 0xb2, 0xdf, 0x04, 0x8e, 0x79, 0x92, 0x49, 0xf9, 0x5c, 0x8c, + 0xfd, 0x41, 0x71, 0x92, 0x7d, 0xbb, 0xea, 0x9b, 0x37, 0xc5, 0xce, 0x1b, + 0xa5, 0xb4, 0x34, 0x34, 0x13, 0xd6, 0xd6, 0x4c, 0xb1, 0xf2, 0xc2, 0x44, + 0x44, 0x79, 0xb1, 0xf5, 0x1e, 0xbe, 0x53, 0xe9, 0xae, 0x16, 0x3c, 0x9a, + 0x95, 0x36, 0xa1, 0x0a, 0xff, 0x00, 0x3e, 0x8c, 0xdf, 0x14, 0xa5, 0xe8, + 0xb8, 0xcd, 0xc4, 0x73, 0x50, 0x31, 0xa6, 0xb8, 0xd3, 0xc9, 0x4c, 0xdc, + 0x9c, 0xfb, 0xb6, 0x46, 0x3e, 0xfa, 0xad, 0xdf, 0xbe, 0x23, 0x59, 0xe8, + 0x22, 0x59, 0x85, 0x55, 0x2c, 0x93, 0xf3, 0xf2, 0xad, 0x3b, 0x31, 0x63, + 0x8c, 0xe3, 0x99, 0xb1, 0xd0, 0x7e, 0x7b, 0xeb, 0x22, 0x96, 0xb2, 0xf9, + 0xc6, 0x55, 0xf3, 0x09, 0x1a, 0x69, 0x51, 0x5c, 0xb9, 0x54, 0x41, 0x15, + 0x3c, 0x64, 0xf4, 0xe6, 0xc6, 0xe4, 0x9d, 0xc6, 0x0e, 0x4f, 0x6d, 0x29, + 0x96, 0x2e, 0x1c, 0xa4, 0xac, 0xe6, 0xbe, 0x5c, 0x64, 0x75, 0x89, 0x5d, + 0x65, 0xa7, 0xa3, 0x42, 0x5d, 0x88, 0x38, 0xc1, 0x6f, 0xe9, 0xff, 0x00, + 0xa7, 0x4d, 0x76, 0x71, 0xbc, 0x95, 0x52, 0xec, 0xd4, 0xb0, 0x3f, 0x6c, + 0xb6, 0x71, 0xad, 0xde, 0xcf, 0xc4, 0xb7, 0x65, 0xaa, 0xb9, 0xf1, 0x15, + 0xb6, 0x8a, 0x8a, 0x37, 0xc8, 0x86, 0x29, 0x5e, 0x50, 0xa4, 0xfd, 0x44, + 0xe4, 0x6e, 0x7a, 0x0c, 0x69, 0x7c, 0xf7, 0xbe, 0x04, 0xb4, 0xc4, 0x63, + 0xa2, 0xa9, 0x6a, 0xf9, 0x1b, 0x67, 0x10, 0xc2, 0x79, 0xa5, 0xfc, 0x9c, + 0x05, 0xfd, 0xfa, 0xea, 0xab, 0x57, 0x37, 0x0e, 0x04, 0x0d, 0x64, 0xe1, + 0xaa, 0x8a, 0x97, 0x00, 0x7f, 0x32, 0xb6, 0x76, 0x92, 0x34, 0xce, 0xd9, + 0xe5, 0x18, 0xe6, 0x39, 0x23, 0xfd, 0x34, 0xef, 0x87, 0xb8, 0x16, 0x77, + 0xa4, 0xf9, 0xaa, 0xc7, 0x8a, 0xd9, 0xce, 0xbe, 0x21, 0x62, 0x8a, 0x18, + 0x67, 0xb8, 0xe7, 0xfa, 0x74, 0xdb, 0x1d, 0x08, 0xb5, 0xd1, 0x61, 0x86, + 0xe5, 0x77, 0x7b, 0x64, 0xa2, 0x38, 0xad, 0xbc, 0x27, 0x6a, 0x68, 0xf1, + 0xcd, 0x33, 0x8f, 0x98, 0xe5, 0x3d, 0x08, 0x41, 0xfd, 0x47, 0xfe, 0x6f, + 0x53, 0xaa, 0xcd, 0xde, 0xf1, 0xc2, 0x23, 0x99, 0x5c, 0x5d, 0x2f, 0x72, + 0xa1, 0xc2, 0xd5, 0x56, 0xce, 0x4c, 0x63, 0xd9, 0x46, 0x7a, 0x7a, 0x0c, + 0x0d, 0xb4, 0xba, 0xae, 0xc1, 0x49, 0x3d, 0xda, 0x4a, 0x5a, 0x2a, 0xe1, + 0x58, 0x15, 0xb9, 0x66, 0xa9, 0x79, 0x76, 0x62, 0x33, 0xe5, 0x1d, 0xc9, + 0x1b, 0xe7, 0x1b, 0x68, 0xb8, 0xe2, 0xe1, 0x7a, 0x08, 0x42, 0xd4, 0xd5, + 0xc4, 0xd2, 0x01, 0x90, 0x24, 0xc9, 0x1c, 0xd8, 0xe9, 0x8f, 0x4f, 0x4d, + 0x1b, 0x65, 0xb4, 0x4c, 0xb7, 0xba, 0xfb, 0x4f, 0x1d, 0x56, 0xdc, 0x69, + 0x2b, 0x65, 0xa3, 0xaa, 0xa7, 0xa9, 0x99, 0x20, 0x70, 0x7c, 0xc4, 0x19, + 0x1b, 0x3f, 0x8e, 0xda, 0xd3, 0xf8, 0x67, 0xe3, 0x45, 0xd6, 0x39, 0x61, + 0x8a, 0xfb, 0x8a, 0x88, 0x73, 0xca, 0xd2, 0x20, 0x0a, 0xe4, 0x7b, 0x8e, + 0x87, 0xfb, 0xeb, 0x23, 0xbe, 0xc6, 0x0f, 0x13, 0xdc, 0x9a, 0x60, 0xc5, + 0x8d, 0x54, 0x9c, 0x80, 0x0c, 0xec, 0x1c, 0xe8, 0xfa, 0x63, 0x1b, 0xc6, + 0x09, 0x5c, 0x82, 0x30, 0x41, 0xd2, 0x6e, 0xa3, 0xb4, 0xe3, 0xe4, 0xf1, + 0x67, 0xde, 0x31, 0xa0, 0xa3, 0x8f, 0x8a, 0x6b, 0xaa, 0xed, 0xc9, 0x10, + 0xb7, 0x4c, 0xcd, 0x3d, 0x17, 0x21, 0xdb, 0x0c, 0xd9, 0xc9, 0x1d, 0xb0, + 0x0e, 0x31, 0xdb, 0x43, 0x54, 0x02, 0xd4, 0x54, 0xca, 0x18, 0x85, 0xe6, + 0x8c, 0xe3, 0xf2, 0x34, 0xc6, 0x44, 0x89, 0xa9, 0x8d, 0x3c, 0x69, 0x1b, + 0x33, 0x1f, 0x21, 0x2b, 0xba, 0x3f, 0x62, 0x3e, 0xe7, 0x63, 0xf7, 0xd0, + 0x56, 0x5a, 0x0f, 0xe2, 0x17, 0xcb, 0x75, 0xa2, 0x6a, 0xc4, 0xa7, 0x8e, + 0x79, 0x04, 0x52, 0x36, 0x39, 0xb9, 0x3c, 0xd9, 0x07, 0x1e, 0xb9, 0xc6, + 0xb3, 0x28, 0xed, 0x95, 0x02, 0x9d, 0xc4, 0xb0, 0xf0, 0x55, 0x82, 0x6b, + 0xfd, 0xfa, 0x9e, 0x85, 0x00, 0x31, 0x31, 0x1e, 0x33, 0x90, 0x71, 0x1c, + 0x7d, 0xcf, 0xf6, 0x1f, 0x9d, 0x50, 0xfe, 0x32, 0x5a, 0xa9, 0x6d, 0x5f, + 0x10, 0xaf, 0x94, 0xd4, 0x34, 0xc1, 0x29, 0x29, 0xeb, 0x4a, 0x46, 0x46, + 0xf8, 0x05, 0x43, 0x72, 0x93, 0xeb, 0xb9, 0xd7, 0xaa, 0xed, 0x16, 0x5a, + 0x5e, 0x13, 0x85, 0xe8, 0x28, 0xd8, 0x62, 0x48, 0xd9, 0xaa, 0x4f, 0xf5, + 0xc8, 0x01, 0x1e, 0x6d, 0xba, 0x36, 0x3f, 0x1a, 0xf3, 0x97, 0x19, 0xdd, + 0x29, 0xeb, 0x6d, 0x7c, 0x55, 0x0d, 0x25, 0x12, 0xb0, 0xae, 0xba, 0x1a, + 0xb8, 0xea, 0xa4, 0x39, 0x91, 0x52, 0x2e, 0x60, 0xa9, 0xf6, 0x20, 0x92, + 0x4f, 0xe3, 0x4d, 0xc9, 0xe5, 0x51, 0x06, 0x8c, 0xe2, 0x09, 0xd0, 0x37, + 0x32, 0x8d, 0xba, 0x11, 0x9d, 0x6e, 0x3c, 0x2b, 0x55, 0x40, 0x7e, 0x16, + 0xd1, 0x5b, 0xe5, 0xa3, 0x9e, 0x3a, 0xd4, 0x91, 0xea, 0x22, 0xa9, 0x59, + 0x30, 0x00, 0x6c, 0x13, 0xe5, 0xfb, 0x05, 0xdf, 0xdb, 0x59, 0x07, 0x04, + 0x59, 0xc5, 0xfb, 0x89, 0xe8, 0x6d, 0x23, 0x64, 0xa8, 0x90, 0xf3, 0x9f, + 0x45, 0x00, 0xb1, 0xfe, 0xdf, 0xdb, 0x5e, 0x9c, 0x8b, 0xe1, 0xfc, 0xf1, + 0xd1, 0x22, 0x55, 0xc9, 0x4d, 0x6f, 0xa5, 0x5a, 0x7c, 0x86, 0x73, 0x9e, + 0x45, 0x1b, 0x00, 0x07, 0xae, 0xb8, 0xda, 0xdc, 0xfa, 0x88, 0xc9, 0x43, + 0x12, 0xbf, 0xd8, 0x13, 0x52, 0xfe, 0xd3, 0x05, 0xae, 0xe1, 0xda, 0x81, + 0x0c, 0xdc, 0xd3, 0x89, 0x91, 0xdc, 0xb4, 0x8d, 0xcb, 0xe6, 0x6d, 0xf2, + 0x73, 0xf9, 0xd2, 0xdb, 0x9d, 0x0d, 0xb1, 0xa9, 0x84, 0x1e, 0x19, 0x04, + 0xe0, 0xb3, 0x03, 0xe6, 0xce, 0x3f, 0xb6, 0xac, 0x9c, 0x4b, 0x5a, 0x69, + 0x0c, 0xf0, 0xa4, 0x81, 0xe3, 0xe6, 0x60, 0xa5, 0x98, 0x2f, 0x32, 0xee, + 0x01, 0xdf, 0xf1, 0xac, 0xd2, 0x82, 0x99, 0xea, 0xeb, 0x64, 0xa3, 0xa7, + 0xac, 0x20, 0x80, 0x59, 0xf1, 0xd0, 0x0c, 0xe0, 0x8c, 0xfd, 0xce, 0x9d, + 0xa5, 0xb9, 0xa4, 0xdf, 0x65, 0x20, 0x49, 0x2d, 0x46, 0xdd, 0x5b, 0x3b, + 0x02, 0x5e, 0x19, 0xd4, 0x90, 0xc7, 0xae, 0x73, 0xd0, 0xeb, 0x93, 0x1c, + 0x7f, 0x26, 0xf4, 0x7e, 0x1a, 0x04, 0x76, 0x0f, 0xcd, 0x8f, 0x36, 0x40, + 0x23, 0xaf, 0xa6, 0xfa, 0x7d, 0xf2, 0x49, 0x6e, 0x81, 0xe3, 0x3e, 0x6e, + 0x6e, 0xad, 0xeb, 0xed, 0x9d, 0x71, 0x4f, 0x46, 0x95, 0xd0, 0xb3, 0xd3, + 0x00, 0x42, 0xec, 0xc0, 0x9e, 0x87, 0x5b, 0x5c, 0x87, 0x29, 0x95, 0x65, + 0xa4, 0x44, 0x8a, 0x58, 0x02, 0x61, 0x8f, 0x98, 0x1f, 0x5c, 0x76, 0xd3, + 0xfe, 0x1e, 0x30, 0xac, 0x54, 0xb5, 0x04, 0x12, 0x23, 0x1e, 0x1c, 0xdb, + 0xe0, 0x80, 0x7b, 0xff, 0x00, 0x6d, 0x7c, 0xb8, 0x50, 0x48, 0xb0, 0x1f, + 0x05, 0x59, 0x59, 0x71, 0xcc, 0xfd, 0x40, 0xc7, 0x5c, 0xe8, 0x5a, 0x39, + 0xdd, 0x64, 0x68, 0xe4, 0x05, 0x56, 0x4c, 0x07, 0x1d, 0x41, 0xdf, 0xd7, + 0x4d, 0xc5, 0x3b, 0x56, 0x6a, 0xd2, 0xcf, 0x91, 0x85, 0x7a, 0xad, 0x05, + 0xc3, 0xc3, 0x0c, 0x4a, 0x33, 0x07, 0xe7, 0x53, 0xb3, 0x6f, 0x9f, 0xdc, + 0x68, 0x9a, 0x98, 0x20, 0xb8, 0x55, 0x5d, 0x24, 0x85, 0x4d, 0x27, 0xcc, + 0xc7, 0x12, 0x53, 0xc6, 0x83, 0x79, 0x31, 0x8e, 0x62, 0x7f, 0xd7, 0xd8, + 0xe8, 0x6f, 0x97, 0x82, 0x96, 0x7a, 0xa4, 0xa8, 0x54, 0x94, 0xbc, 0x79, + 0x8b, 0x7c, 0xf2, 0x80, 0x71, 0x91, 0xe8, 0x74, 0x55, 0xa2, 0x17, 0x7a, + 0xba, 0x66, 0xa5, 0x1e, 0x2c, 0x49, 0x19, 0x8f, 0x9a, 0x56, 0x3e, 0x47, + 0x61, 0xb9, 0xc8, 0xec, 0x0e, 0x9b, 0x66, 0xd7, 0xc9, 0x1d, 0x96, 0xb2, + 0xa5, 0x65, 0x31, 0x46, 0xdc, 0xf1, 0x16, 0xdf, 0x27, 0x66, 0x1a, 0x6f, + 0x14, 0x74, 0xa9, 0x4c, 0xce, 0x39, 0xb9, 0xea, 0x25, 0x74, 0xf0, 0x94, + 0x67, 0x93, 0x7d, 0x8e, 0x4e, 0xf8, 0xd4, 0x14, 0xd4, 0xd3, 0x5b, 0x78, + 0x82, 0xa6, 0x9a, 0xb6, 0x9d, 0x23, 0xe6, 0x50, 0x33, 0x17, 0xd0, 0xa0, + 0xee, 0x37, 0xf7, 0xce, 0xbe, 0x56, 0xd2, 0x9b, 0x4d, 0xc9, 0x6b, 0x23, + 0x8c, 0xcb, 0x09, 0x7f, 0xa4, 0x37, 0x4e, 0xf8, 0x3e, 0x9b, 0x6a, 0x30, + 0xa2, 0x88, 0x69, 0xcc, 0x94, 0x57, 0x52, 0x7c, 0xc6, 0x35, 0x2a, 0x1d, + 0x47, 0x7e, 0xbb, 0xe9, 0x90, 0x53, 0x4f, 0x78, 0x92, 0xa2, 0x17, 0x02, + 0x0a, 0xef, 0x2c, 0x52, 0x2e, 0xde, 0x14, 0x9d, 0x41, 0xfd, 0x8e, 0xba, + 0xe2, 0x2a, 0x64, 0xf9, 0x68, 0xaf, 0x14, 0x39, 0x28, 0xdc, 0xae, 0xd9, + 0x39, 0xc0, 0x3d, 0x0f, 0xe3, 0xa6, 0x34, 0x05, 0x75, 0x4d, 0x2d, 0x4f, + 0x0e, 0x35, 0x62, 0x00, 0x67, 0x49, 0x42, 0xbb, 0x2f, 0x73, 0xeb, 0xf7, + 0xef, 0xaa, 0x0d, 0x87, 0x08, 0x45, 0x4d, 0x75, 0x4d, 0x02, 0xc6, 0x40, + 0x59, 0x85, 0x42, 0x46, 0xeb, 0x80, 0x41, 0x18, 0x7f, 0xc7, 0x43, 0xaa, + 0x4d, 0xd6, 0xa6, 0x1b, 0x87, 0x10, 0x22, 0x50, 0xa2, 0xc5, 0x12, 0xc9, + 0x9d, 0x97, 0xea, 0xc6, 0x7a, 0x6a, 0xf1, 0x72, 0x0f, 0x47, 0x53, 0x41, + 0x75, 0x2e, 0xb2, 0xbc, 0x54, 0xd1, 0x34, 0x8a, 0x06, 0xcf, 0x19, 0x18, + 0x20, 0xfd, 0x8e, 0x35, 0x47, 0xe2, 0x8a, 0x38, 0x2d, 0x97, 0xea, 0x82, + 0x8b, 0xcb, 0x4f, 0x54, 0x9e, 0x3d, 0x39, 0xce, 0x70, 0x1b, 0x7f, 0xdb, + 0xa6, 0xad, 0x19, 0x73, 0xae, 0x0b, 0x50, 0xa6, 0x6a, 0x1b, 0x5b, 0xd7, + 0xdc, 0x5f, 0xcc, 0xe7, 0x96, 0x3c, 0x8c, 0xfd, 0x8f, 0xed, 0xa7, 0x1f, + 0x04, 0xaf, 0xcf, 0x6b, 0xe3, 0xfb, 0x7a, 0x00, 0x43, 0xd6, 0x54, 0xaa, + 0x6c, 0x70, 0x00, 0x3d, 0x7f, 0xf1, 0xac, 0xb3, 0xe7, 0x95, 0x6d, 0xed, + 0x14, 0xb2, 0xb4, 0xd2, 0x48, 0xc7, 0xc4, 0x24, 0xe7, 0xec, 0x33, 0xab, + 0xef, 0xc0, 0x0a, 0x09, 0x27, 0xf8, 0x89, 0x63, 0x25, 0x39, 0xb1, 0x52, + 0xa4, 0x7b, 0x0e, 0xa7, 0xf6, 0xd1, 0xc4, 0x44, 0x4f, 0x6e, 0xb1, 0x5e, + 0x75, 0x2a, 0xa1, 0x01, 0x1b, 0x01, 0xe9, 0xeb, 0xa4, 0x7c, 0x57, 0x74, + 0xa7, 0xb5, 0xda, 0xea, 0xeb, 0x6a, 0xe6, 0x11, 0x41, 0x04, 0x4c, 0xf2, + 0x31, 0xec, 0x00, 0xd3, 0xa9, 0x4a, 0x99, 0x32, 0xbf, 0x4a, 0x2e, 0xb0, + 0x7f, 0xf6, 0xa7, 0xe2, 0x94, 0xa5, 0xb0, 0xc3, 0x60, 0x81, 0xc8, 0x9e, + 0xe0, 0xe7, 0xc4, 0x55, 0x3d, 0x23, 0x53, 0xd4, 0xfd, 0xcf, 0xf6, 0x3a, + 0x63, 0x63, 0x51, 0x94, 0x5f, 0xf8, 0xf6, 0xff, 0x00, 0xc4, 0x77, 0x4a, + 0xd6, 0x35, 0xf5, 0x30, 0xd0, 0x34, 0xdc, 0xa9, 0x0a, 0x30, 0x1c, 0xb1, + 0x6f, 0x80, 0x76, 0xdf, 0x6d, 0xb5, 0xdc, 0xbc, 0x47, 0x53, 0xf3, 0xf5, + 0x74, 0x56, 0xda, 0xc9, 0x29, 0xa8, 0x0b, 0x83, 0x1c, 0x68, 0x4a, 0xb3, + 0x63, 0x6c, 0x92, 0x31, 0x9d, 0x56, 0x6d, 0x74, 0x5e, 0x2c, 0x1e, 0x29, + 0xa8, 0x58, 0xff, 0x00, 0xa5, 0x55, 0xd4, 0x8f, 0x13, 0x1e, 0x9a, 0xfd, + 0x4b, 0x14, 0x82, 0xf9, 0x0b, 0xb4, 0x4e, 0xb0, 0x44, 0xc0, 0x49, 0x21, + 0x5e, 0xdf, 0x6d, 0x62, 0x72, 0x94, 0xd3, 0x89, 0x9d, 0xdb, 0xb4, 0x8d, + 0xe7, 0xe0, 0x15, 0x8e, 0xe5, 0xc4, 0x17, 0xef, 0x98, 0xb9, 0x09, 0x1a, + 0xd3, 0x42, 0x7c, 0x4e, 0x79, 0x06, 0x79, 0xdc, 0x74, 0x50, 0x7b, 0xff, + 0x00, 0xd3, 0x5a, 0x77, 0xc5, 0x1e, 0x2b, 0xa5, 0xa2, 0x43, 0x11, 0x9c, + 0x21, 0x07, 0x94, 0x31, 0xd8, 0x2e, 0x3a, 0x93, 0xe8, 0x06, 0xa8, 0x77, + 0xef, 0x8a, 0x74, 0x74, 0x56, 0x18, 0x6d, 0x3c, 0x27, 0x47, 0xe1, 0xd2, + 0xc3, 0x12, 0xc6, 0x27, 0x90, 0x00, 0x84, 0x8e, 0xbb, 0x77, 0xc7, 0xdf, + 0x59, 0xf5, 0x4d, 0xee, 0xbe, 0xf6, 0xe6, 0x79, 0x99, 0x6e, 0x55, 0x59, + 0x38, 0x12, 0x36, 0x51, 0x47, 0xd8, 0x6c, 0x07, 0xdf, 0x27, 0x4c, 0x86, + 0x3f, 0x8f, 0x15, 0x47, 0xb3, 0x44, 0x31, 0x54, 0x69, 0x70, 0x5f, 0x69, + 0xbe, 0x21, 0xf0, 0xd5, 0xaa, 0x1f, 0xfe, 0x9f, 0x2c, 0xd5, 0x55, 0x72, + 0x00, 0x6a, 0x3c, 0x38, 0x39, 0x8c, 0x8c, 0x47, 0x9b, 0x7e, 0xc0, 0xe4, + 0xea, 0xb1, 0xc4, 0x5c, 0x6f, 0x7c, 0xba, 0xd5, 0x43, 0x50, 0x95, 0x37, + 0x0b, 0x65, 0x3c, 0x3f, 0x42, 0xc3, 0x10, 0x0e, 0xc7, 0xb1, 0x1b, 0xfe, + 0xfa, 0x54, 0xd7, 0xfe, 0x21, 0xb3, 0x42, 0x89, 0x4d, 0x6d, 0xb5, 0xd3, + 0xc1, 0x1f, 0x2f, 0x3c, 0x49, 0x16, 0x5d, 0x8e, 0x06, 0xe7, 0xbb, 0x7a, + 0xfa, 0x7b, 0x68, 0x6a, 0xee, 0x2e, 0xbe, 0xd5, 0xce, 0xe5, 0xea, 0x68, + 0xbc, 0x73, 0x9f, 0x0d, 0xd2, 0x21, 0xcc, 0x83, 0x3f, 0xd2, 0x3a, 0x03, + 0xd3, 0x7c, 0x67, 0x43, 0x87, 0x14, 0x71, 0x7d, 0x46, 0x43, 0x02, 0xc6, + 0xb8, 0x19, 0x7c, 0xe3, 0xb5, 0x48, 0xaa, 0x97, 0x87, 0x12, 0xe1, 0x70, + 0x9f, 0xfe, 0x1d, 0x55, 0xca, 0xa5, 0xe7, 0x76, 0x63, 0xbe, 0x79, 0x00, + 0xc1, 0xf5, 0xc6, 0xfd, 0xf4, 0x2c, 0xb7, 0xba, 0x1a, 0x1b, 0xa3, 0xcd, + 0x3d, 0xaf, 0xf8, 0xbd, 0x48, 0x51, 0xe7, 0xa8, 0xfe, 0x45, 0x30, 0xf6, + 0x48, 0xb1, 0xb8, 0x1b, 0xee, 0x71, 0xf9, 0xd5, 0x7e, 0xe5, 0x76, 0xb8, + 0xd7, 0xb9, 0x5b, 0xd5, 0x55, 0x55, 0x7b, 0xf2, 0xff, 0x00, 0x2d, 0x60, + 0xf2, 0x85, 0xf7, 0x3e, 0xfa, 0xf9, 0x4d, 0x14, 0x41, 0x61, 0x47, 0x81, + 0x56, 0x49, 0x59, 0x7c, 0x3f, 0x12, 0x41, 0x9d, 0xf6, 0xc1, 0xf4, 0x1d, + 0xf1, 0xa6, 0x58, 0xed, 0xa5, 0x8a, 0xa7, 0x89, 0x6a, 0x6b, 0xe3, 0x96, + 0x28, 0xea, 0x69, 0x6c, 0x74, 0xb8, 0xc9, 0x4a, 0x38, 0xda, 0x49, 0x71, + 0xf7, 0x18, 0x03, 0xa9, 0xd8, 0x63, 0x43, 0x50, 0xd5, 0x70, 0x8d, 0xb1, + 0xa1, 0x06, 0xd5, 0x55, 0x57, 0x50, 0xc0, 0x06, 0x32, 0xaf, 0x29, 0x95, + 0x8f, 0x42, 0xc4, 0xef, 0xf8, 0x18, 0xeb, 0xed, 0xa0, 0x8c, 0x36, 0xca, + 0x59, 0x1e, 0x4a, 0xdb, 0x8d, 0xbd, 0x21, 0x58, 0x8b, 0x49, 0x1d, 0x34, + 0xad, 0x27, 0x33, 0xf4, 0xe5, 0xcf, 0x63, 0x9d, 0xf1, 0xf7, 0xd2, 0xfb, + 0x6d, 0x7d, 0x20, 0x68, 0xca, 0x51, 0x97, 0x8d, 0x18, 0x16, 0xe7, 0x8f, + 0x24, 0x8e, 0xd9, 0x3d, 0x8e, 0xa5, 0x93, 0x69, 0x6c, 0xad, 0xe3, 0x28, + 0xe8, 0xa5, 0x14, 0xbc, 0x3d, 0xc2, 0xd4, 0xd4, 0x55, 0x2d, 0xb4, 0xad, + 0x2c, 0x61, 0xcf, 0x3f, 0xa8, 0x07, 0xd3, 0x1a, 0x45, 0x57, 0x3d, 0xd6, + 0xe3, 0xe2, 0xd6, 0x5d, 0xee, 0x0f, 0x2e, 0x58, 0xf3, 0x2e, 0xfb, 0x7d, + 0x87, 0x7f, 0xb6, 0xa0, 0x9e, 0xe5, 0x33, 0xdc, 0x26, 0x9e, 0x7a, 0x76, + 0x48, 0x99, 0x88, 0x48, 0xd1, 0xbc, 0xc8, 0x99, 0xeb, 0x9e, 0xf8, 0x1f, + 0x6d, 0x17, 0x15, 0xd1, 0x45, 0x33, 0x47, 0x6b, 0xa5, 0x8e, 0x05, 0x5e, + 0xb2, 0x48, 0xb9, 0x73, 0xf6, 0xf4, 0xed, 0xeb, 0xa9, 0x64, 0xda, 0x21, + 0x99, 0xa9, 0x1e, 0xa4, 0x2d, 0x3c, 0x6f, 0x22, 0x2a, 0xe1, 0x7c, 0x98, + 0x24, 0xe7, 0x73, 0xd7, 0x5c, 0x0a, 0x7a, 0x86, 0x6c, 0x78, 0x01, 0x54, + 0x37, 0xd2, 0xdb, 0x9d, 0x37, 0x82, 0x8a, 0xb1, 0xaa, 0xda, 0xa6, 0xab, + 0xce, 0xf5, 0x21, 0x71, 0xcc, 0xdb, 0x8d, 0xb6, 0x27, 0xd3, 0x6d, 0x17, + 0x5b, 0x6f, 0x4a, 0x1a, 0x7f, 0x13, 0xe7, 0x04, 0x72, 0xe3, 0x3c, 0xaa, + 0x3a, 0x9f, 0x4c, 0xea, 0x59, 0x36, 0x9d, 0x5d, 0xe4, 0x4f, 0xfd, 0x47, + 0x72, 0xdc, 0x9c, 0x55, 0x4a, 0x08, 0xff, 0x00, 0xf7, 0x3a, 0xee, 0x38, + 0x7c, 0x53, 0xfc, 0xb7, 0xc2, 0x1d, 0xf5, 0x45, 0xe3, 0x59, 0x6b, 0x2d, + 0x9c, 0x75, 0x77, 0x31, 0x48, 0xd1, 0x78, 0xb5, 0xb2, 0xca, 0x31, 0xdf, + 0xf9, 0x87, 0xae, 0xb4, 0x1f, 0x86, 0x73, 0x58, 0xef, 0xb4, 0xb1, 0xc1, + 0x57, 0xc4, 0x0b, 0x41, 0x76, 0x79, 0x02, 0x88, 0x27, 0x4f, 0xe5, 0x48, + 0x4f, 0x75, 0x61, 0xd3, 0xdc, 0x69, 0x0e, 0x67, 0x2a, 0x5f, 0x66, 0x7e, + 0x14, 0x73, 0x0a, 0x59, 0x98, 0x48, 0x39, 0x55, 0x49, 0xe9, 0xe9, 0xa9, + 0xb8, 0xae, 0x68, 0x9e, 0xa6, 0xc9, 0xc6, 0x74, 0xd1, 0x85, 0x51, 0xe1, + 0xc7, 0x5d, 0x1a, 0x9f, 0xa6, 0x74, 0xc7, 0x98, 0xff, 0x00, 0xf2, 0x5c, + 0x1f, 0xbe, 0x75, 0x71, 0xe2, 0x2b, 0x35, 0xae, 0xc9, 0x4a, 0xe9, 0x7d, + 0xbe, 0x5b, 0xbc, 0xc4, 0x72, 0x42, 0x92, 0x12, 0xf2, 0x02, 0x73, 0xba, + 0xf6, 0x00, 0x6f, 0xa6, 0x93, 0xd0, 0xda, 0x78, 0x87, 0x83, 0xe4, 0x82, + 0xd6, 0x21, 0xac, 0xa7, 0x8a, 0x23, 0xe1, 0x98, 0xc4, 0x71, 0x22, 0xb8, + 0x1f, 0x54, 0x80, 0x2e, 0x49, 0xc6, 0x76, 0x2c, 0x7a, 0xe9, 0x39, 0x73, + 0x01, 0x1c, 0x65, 0xb7, 0xc7, 0xff, 0x00, 0xd4, 0xd6, 0xc9, 0x22, 0xa7, + 0xac, 0x68, 0x7e, 0x66, 0x00, 0x66, 0xaa, 0x40, 0x1b, 0xc1, 0x8c, 0xa8, + 0xdb, 0xdd, 0x88, 0x38, 0xc7, 0x6c, 0xeb, 0x0a, 0xab, 0x8e, 0xcb, 0x6b, + 0xac, 0x5a, 0x6a, 0xd7, 0x94, 0x5b, 0xbc, 0x72, 0x82, 0x32, 0x33, 0x23, + 0xc5, 0x92, 0x09, 0xfb, 0xe3, 0xf5, 0xd6, 0xd9, 0xf0, 0x92, 0xf1, 0x41, + 0x07, 0x06, 0x51, 0x5b, 0xae, 0x6b, 0x19, 0x58, 0xd5, 0xd6, 0x39, 0x81, + 0x00, 0x45, 0xe6, 0xda, 0x26, 0xdf, 0x63, 0xd3, 0xf6, 0xd7, 0x9c, 0x38, + 0xe2, 0x29, 0x1f, 0x8a, 0xab, 0x40, 0x93, 0x31, 0x53, 0xca, 0x51, 0x30, + 0x32, 0x00, 0xc9, 0xc7, 0xeb, 0xa9, 0x0c, 0x89, 0x26, 0x56, 0x55, 0x49, + 0x17, 0x4f, 0xf6, 0x76, 0xa9, 0xe1, 0x2b, 0x37, 0x10, 0x5c, 0xd2, 0xed, + 0x3b, 0xc1, 0x25, 0x50, 0x11, 0x5b, 0xeb, 0x25, 0x8f, 0x1c, 0x89, 0xcc, + 0x4f, 0x9b, 0xfc, 0x3c, 0xde, 0x5f, 0xd3, 0x5b, 0x7f, 0xc5, 0xea, 0x0b, + 0xc5, 0x75, 0xa2, 0x8d, 0xa1, 0x9a, 0x23, 0x43, 0x1c, 0x5c, 0xd3, 0x32, + 0xb6, 0x39, 0x98, 0xf7, 0xc0, 0xeb, 0xdb, 0xf5, 0x3a, 0xf2, 0xb5, 0xba, + 0x9d, 0x8b, 0x2b, 0x73, 0x64, 0x03, 0xe9, 0xad, 0xc3, 0xe1, 0x2f, 0x17, + 0xf3, 0x52, 0x0e, 0x12, 0xe2, 0x33, 0x2c, 0x96, 0xc9, 0xd7, 0x92, 0x9e, + 0x51, 0xd6, 0x1f, 0x40, 0x4f, 0x65, 0xfe, 0xda, 0x4e, 0x45, 0xf2, 0xc1, + 0xc2, 0xe9, 0xb0, 0x23, 0x2d, 0xde, 0x26, 0x43, 0xf1, 0x67, 0x87, 0x6e, + 0xf6, 0x8a, 0x5a, 0x4b, 0xbb, 0x40, 0xcd, 0x47, 0x55, 0xcc, 0x91, 0xcc, + 0x01, 0x00, 0x15, 0xeb, 0xf8, 0x3d, 0x8f, 0xb6, 0xb2, 0xca, 0x6a, 0xaa, + 0xba, 0x5a, 0xd4, 0x96, 0x98, 0x81, 0x39, 0x6e, 0x50, 0x18, 0x64, 0x6f, + 0xd8, 0xeb, 0xd8, 0x9f, 0x18, 0x78, 0xae, 0xd5, 0x61, 0xe1, 0x8a, 0xae, + 0x10, 0xb4, 0x53, 0xbd, 0xc9, 0xaa, 0x23, 0x30, 0xca, 0x66, 0x97, 0xc4, + 0x8a, 0x9d, 0x71, 0xdb, 0x3d, 0x4f, 0xdb, 0xa6, 0xbc, 0xad, 0x5d, 0x6f, + 0x14, 0x37, 0x6a, 0x7a, 0xb4, 0x84, 0xb4, 0x62, 0x45, 0xfa, 0x17, 0x70, + 0x33, 0xbe, 0x33, 0xd3, 0x6d, 0xb3, 0xab, 0xc1, 0x1f, 0x86, 0x3b, 0x3b, + 0x18, 0xa9, 0x70, 0x99, 0x15, 0x4a, 0xdc, 0xeb, 0xe3, 0x3f, 0x35, 0x31, + 0x65, 0x8f, 0x01, 0xe3, 0x4d, 0x82, 0x92, 0x36, 0xc8, 0x1b, 0x1f, 0xbe, + 0xa3, 0xb1, 0xdc, 0x2a, 0xec, 0xb5, 0x6e, 0x20, 0x45, 0x31, 0x33, 0xf2, + 0xba, 0x30, 0xce, 0x47, 0xb7, 0xa1, 0xd5, 0xbe, 0xed, 0x34, 0x4d, 0x0c, + 0xc2, 0xc8, 0x8f, 0x15, 0x1d, 0x75, 0x51, 0x73, 0x14, 0x92, 0x66, 0x4c, + 0x2e, 0x71, 0xcd, 0x8e, 0xb8, 0xc9, 0xfd, 0x74, 0x04, 0x96, 0x3f, 0x98, + 0x77, 0xa9, 0xf0, 0x01, 0x25, 0x4e, 0xd9, 0xc6, 0x0f, 0x63, 0xf8, 0xd1, + 0x42, 0x7b, 0xc0, 0x0e, 0xb9, 0xc1, 0x69, 0xaf, 0xb2, 0x81, 0x1d, 0x44, + 0xf2, 0xd4, 0x56, 0xb8, 0x58, 0xa9, 0x23, 0x3b, 0xbb, 0x06, 0x53, 0xe7, + 0x19, 0xfa, 0x71, 0x90, 0x3b, 0x93, 0xa4, 0x2b, 0x43, 0x27, 0x81, 0x2b, + 0x0a, 0x69, 0x72, 0xaf, 0xca, 0x06, 0x31, 0xca, 0x07, 0xb6, 0x87, 0xb8, + 0x97, 0xb7, 0x54, 0xc2, 0x82, 0x36, 0x47, 0x4c, 0x32, 0x48, 0x1b, 0xa7, + 0xb6, 0x86, 0x86, 0xf3, 0x51, 0x51, 0xf3, 0x11, 0xbd, 0x43, 0x72, 0x8d, + 0x95, 0xc0, 0xdd, 0x40, 0x3d, 0x3f, 0x52, 0x4e, 0x99, 0x6d, 0x34, 0xd0, + 0xf4, 0x1f, 0x0d, 0x10, 0x5a, 0xca, 0x66, 0x58, 0xe5, 0x91, 0xe6, 0x19, + 0x20, 0x8c, 0x12, 0xdf, 0xe1, 0xd3, 0x26, 0x06, 0x82, 0x14, 0x05, 0xea, + 0x21, 0x46, 0x56, 0x95, 0x49, 0x18, 0x0c, 0x79, 0xba, 0x63, 0xd4, 0x74, + 0xce, 0xb9, 0x17, 0x28, 0xe3, 0x6b, 0x05, 0x7c, 0x2b, 0x22, 0x8a, 0x79, + 0xd0, 0x33, 0x81, 0x9c, 0x90, 0x77, 0xc0, 0xfd, 0xf5, 0xcd, 0xd6, 0x6a, + 0xba, 0xde, 0x23, 0x9e, 0x59, 0x9e, 0x59, 0x92, 0x56, 0x56, 0x0c, 0x5b, + 0x97, 0x62, 0x7b, 0x0e, 0xcb, 0xd7, 0x6d, 0xf5, 0xad, 0x1b, 0xd7, 0x41, + 0x46, 0xe3, 0x3d, 0xc5, 0x2a, 0x6a, 0xe0, 0x5e, 0x77, 0x1c, 0xb2, 0xca, + 0x59, 0x32, 0x4e, 0x36, 0xce, 0x74, 0x44, 0xd7, 0x2a, 0x4a, 0xea, 0x54, + 0x47, 0x46, 0x8d, 0xda, 0x50, 0xae, 0x0f, 0x63, 0x82, 0x03, 0x67, 0xdb, + 0xa7, 0xe7, 0x42, 0x4d, 0x44, 0xf6, 0x8b, 0xdd, 0x54, 0x0a, 0xf9, 0x8b, + 0x67, 0x60, 0x1b, 0x2c, 0xc0, 0x8c, 0x93, 0xf6, 0xce, 0x8d, 0xad, 0xa6, + 0x48, 0xec, 0xc2, 0xe3, 0x84, 0x53, 0x59, 0xe1, 0x99, 0x90, 0x27, 0x51, + 0xb9, 0x04, 0x1f, 0x7e, 0xbf, 0xa6, 0xad, 0x8d, 0x88, 0x1c, 0x7f, 0x3d, + 0x6f, 0x86, 0x52, 0xcb, 0xe2, 0x50, 0xc3, 0x28, 0x8c, 0xf7, 0x00, 0xee, + 0x0e, 0x3d, 0xb4, 0x59, 0xb3, 0xd1, 0x54, 0x5b, 0xeb, 0x83, 0x9f, 0x0a, + 0x47, 0x0d, 0x35, 0x39, 0x4e, 0x85, 0x15, 0x73, 0xfb, 0xe4, 0x6d, 0xdb, + 0x50, 0x99, 0x69, 0xc7, 0x0b, 0xc9, 0x42, 0x81, 0x85, 0x43, 0x4c, 0x5d, + 0x49, 0x5c, 0x2b, 0x63, 0x27, 0x19, 0xfc, 0x68, 0x6a, 0x99, 0x5a, 0x0b, + 0x13, 0xb8, 0x95, 0xa3, 0x2e, 0xc5, 0x02, 0x11, 0xb9, 0xce, 0xfb, 0xfb, + 0x74, 0xd5, 0x14, 0xc0, 0xe3, 0xb9, 0xd5, 0xc5, 0x6e, 0x4b, 0x6d, 0x42, + 0xab, 0xa3, 0x60, 0x29, 0xe6, 0xdd, 0x37, 0xc6, 0x3e, 0xda, 0x8f, 0x8c, + 0x56, 0x3b, 0x8f, 0xc9, 0xdb, 0xa0, 0x58, 0xd6, 0x4a, 0x28, 0x39, 0x07, + 0x20, 0xd8, 0x9e, 0x62, 0x4f, 0xf7, 0xd4, 0x34, 0xf4, 0x6f, 0x2d, 0x39, + 0x33, 0xcb, 0x1e, 0x14, 0xf5, 0xcf, 0x51, 0xe9, 0xa6, 0x86, 0x9e, 0x81, + 0x29, 0x21, 0x34, 0xec, 0xef, 0x50, 0xc4, 0xbc, 0xac, 0x63, 0xc0, 0x51, + 0xdb, 0x07, 0xf3, 0xf9, 0xeb, 0xa8, 0x51, 0x4b, 0xa4, 0xb5, 0x4a, 0x6b, + 0x42, 0x54, 0xc6, 0x42, 0xab, 0x63, 0xa6, 0xdf, 0x73, 0xad, 0xcf, 0xfd, + 0x9c, 0x78, 0x5e, 0xe2, 0x9c, 0x71, 0x15, 0xf6, 0x68, 0xa4, 0xa5, 0xb4, + 0xd2, 0x42, 0xd2, 0x0a, 0x99, 0x94, 0xac, 0x4e, 0xdf, 0x48, 0x0a, 0xdd, + 0x3b, 0xea, 0x8c, 0x23, 0xa7, 0x0a, 0x24, 0xa7, 0x9b, 0x2f, 0xc9, 0x86, + 0x2d, 0xd3, 0x71, 0xd3, 0x1d, 0xf5, 0x74, 0xa1, 0xe2, 0xba, 0xcb, 0x85, + 0xa2, 0x92, 0xd1, 0x79, 0xb8, 0x56, 0xad, 0x14, 0x51, 0x24, 0x74, 0xd4, + 0x54, 0x31, 0x15, 0x32, 0x80, 0x4e, 0x32, 0x07, 0xdb, 0x54, 0x9d, 0x3b, + 0x15, 0x2c, 0x3c, 0xa7, 0x66, 0xf5, 0x5d, 0xf1, 0x17, 0x84, 0x23, 0x8e, + 0x68, 0x92, 0xff, 0x00, 0x4b, 0x2c, 0xe1, 0x8a, 0xb3, 0xae, 0x48, 0x03, + 0xa7, 0x5c, 0x6b, 0xcd, 0x5f, 0x10, 0x6b, 0xc7, 0x17, 0x71, 0x8d, 0x4d, + 0xe6, 0xb6, 0xae, 0xa7, 0xe4, 0xd4, 0xf8, 0x54, 0xb0, 0xa4, 0x79, 0x61, + 0x1a, 0xf4, 0x3c, 0xc7, 0xa6, 0x7a, 0x9d, 0xba, 0x9d, 0x1a, 0xd5, 0x09, + 0x6e, 0x4a, 0x8a, 0x5a, 0x6b, 0x4d, 0x22, 0x38, 0x25, 0xdc, 0xcf, 0x2f, + 0x8b, 0x3f, 0x2e, 0x46, 0x32, 0x01, 0x21, 0x49, 0x24, 0x6d, 0xd7, 0x42, + 0xd6, 0x53, 0x5e, 0x26, 0xa5, 0x7a, 0xca, 0xdb, 0x7c, 0xb1, 0x53, 0xe3, + 0x0c, 0x4c, 0x61, 0x47, 0xdc, 0x6f, 0x8c, 0x7b, 0xef, 0xa6, 0xfc, 0x96, + 0x5e, 0xd5, 0xec, 0x57, 0x15, 0x1c, 0x6e, 0x23, 0x5a, 0x48, 0x59, 0x56, + 0x32, 0x70, 0xe5, 0xcb, 0x36, 0xe7, 0x39, 0xcf, 0x41, 0xfa, 0x69, 0x84, + 0x9e, 0x1d, 0x08, 0x8e, 0x55, 0x81, 0x2a, 0xaa, 0x58, 0x79, 0xbc, 0x61, + 0xcc, 0x07, 0xb8, 0xf5, 0x3a, 0x12, 0x2a, 0x84, 0x83, 0x95, 0x22, 0x2e, + 0xc3, 0x2a, 0x63, 0x50, 0xd9, 0x18, 0xf7, 0x3d, 0xfe, 0xda, 0x6a, 0xb5, + 0x55, 0xb7, 0x26, 0x94, 0xc7, 0x4b, 0x09, 0x90, 0x10, 0xa1, 0xd9, 0xb9, + 0x79, 0x33, 0xd7, 0x1b, 0x7b, 0x01, 0xbe, 0x97, 0x63, 0x94, 0x52, 0x5c, + 0x10, 0xd4, 0xf1, 0x15, 0x74, 0xb4, 0x9f, 0x2f, 0x23, 0xc1, 0x2b, 0x10, + 0x10, 0x46, 0xb4, 0xa8, 0x7c, 0x31, 0xe8, 0xa4, 0xf4, 0x23, 0xd8, 0x7e, + 0x75, 0x02, 0xd5, 0x5c, 0x82, 0xab, 0x43, 0x4a, 0x54, 0x85, 0x11, 0x86, + 0x38, 0xe7, 0xc6, 0xfb, 0x91, 0xd0, 0x69, 0xa9, 0xb4, 0xdd, 0xa6, 0x3c, + 0x83, 0xe5, 0xa0, 0xdf, 0xeb, 0x50, 0x0b, 0x63, 0xee, 0x37, 0xfe, 0xda, + 0x51, 0x71, 0xa4, 0xab, 0xb7, 0xd4, 0x34, 0x2d, 0x56, 0x80, 0x48, 0x0e, + 0xc4, 0xe1, 0x8e, 0x0e, 0x33, 0xef, 0xa9, 0xb8, 0xbd, 0xa7, 0xc8, 0x94, + 0x3d, 0x68, 0x92, 0xbd, 0x3c, 0x55, 0x1f, 0x53, 0x09, 0x80, 0xfc, 0x68, + 0xf4, 0x64, 0xaf, 0xa9, 0x86, 0x8a, 0x3b, 0x7a, 0x7c, 0x9c, 0x32, 0x9f, + 0xe6, 0xbb, 0xf9, 0x00, 0xf5, 0x3b, 0x6f, 0xa5, 0x96, 0xe9, 0x2d, 0xd4, + 0x71, 0xbd, 0x40, 0xff, 0x00, 0x7b, 0xb8, 0x33, 0x93, 0xc9, 0x92, 0xa1, + 0x17, 0xa7, 0x5f, 0x7e, 0xa7, 0x5d, 0xd4, 0xd5, 0x5d, 0xa6, 0x6f, 0x91, + 0x79, 0x82, 0xc1, 0x27, 0xd0, 0x22, 0xd9, 0x70, 0x7a, 0x0f, 0x7e, 0xd8, + 0xd5, 0xa6, 0x53, 0x1b, 0xcd, 0x6f, 0xa1, 0x7a, 0xf6, 0x89, 0x78, 0x86, + 0x08, 0x5a, 0x43, 0xcb, 0x1c, 0x14, 0xf1, 0xb0, 0x0e, 0x07, 0x60, 0xc7, + 0x63, 0xf7, 0xd3, 0x9f, 0xfe, 0xdb, 0xa4, 0xa3, 0x4a, 0x6a, 0x88, 0xa9, + 0x58, 0x46, 0x08, 0x9a, 0x77, 0x4f, 0x1a, 0x5e, 0x7c, 0x6d, 0xd3, 0x03, + 0x3d, 0x4f, 0xa6, 0xab, 0xed, 0xc3, 0x91, 0xc3, 0x68, 0x89, 0x9a, 0xf4, + 0xb1, 0xcc, 0xe4, 0xad, 0x44, 0x0f, 0x10, 0x0f, 0x18, 0x1d, 0x40, 0x6c, + 0xe7, 0xa8, 0x1b, 0x69, 0x6a, 0xc7, 0x13, 0xd6, 0xc4, 0x94, 0x95, 0x2d, + 0x38, 0x62, 0x39, 0xde, 0x52, 0x70, 0x49, 0xdb, 0x97, 0xdf, 0xae, 0x7f, + 0x1a, 0x8c, 0x0d, 0xca, 0x5c, 0x23, 0xf5, 0x7a, 0xdb, 0xa4, 0x99, 0x12, + 0xc5, 0x43, 0x54, 0x22, 0x4d, 0xe4, 0x92, 0xa0, 0x87, 0x27, 0xdc, 0x0e, + 0xdf, 0xae, 0xbe, 0x8a, 0x17, 0x99, 0x15, 0x8b, 0xc8, 0x0e, 0x76, 0x04, + 0xe3, 0x95, 0x7e, 0xda, 0xb3, 0xf1, 0x4d, 0xae, 0xa6, 0x82, 0x9a, 0x2a, + 0xba, 0xca, 0xec, 0xf3, 0x80, 0x84, 0x41, 0x1e, 0x31, 0xb6, 0xc0, 0x00, + 0x71, 0x9c, 0x7f, 0xe7, 0x55, 0xa1, 0x08, 0x5a, 0x49, 0xa6, 0xa9, 0x96, + 0x72, 0xae, 0xdc, 0xaa, 0x07, 0x5d, 0x4a, 0x19, 0x1a, 0x6a, 0xd3, 0x23, + 0x32, 0xa5, 0x14, 0x73, 0x27, 0x2b, 0xb8, 0xc9, 0xc3, 0x02, 0x00, 0xce, + 0x7d, 0x3a, 0xeb, 0xbb, 0x3d, 0xda, 0x92, 0x9d, 0xd6, 0x69, 0x29, 0x9e, + 0x49, 0x54, 0xe4, 0x3e, 0x3c, 0xa4, 0xff, 0x00, 0x96, 0xa2, 0xb6, 0xa2, + 0xf8, 0xc9, 0xe3, 0xc7, 0x2f, 0x80, 0xc7, 0xc3, 0xe7, 0xe5, 0xcf, 0xeb, + 0xef, 0x8c, 0x68, 0xda, 0xa8, 0xa8, 0xad, 0x95, 0x58, 0xc0, 0x9e, 0x9d, + 0x9b, 0x20, 0x78, 0x7e, 0x61, 0xe9, 0x9d, 0xf6, 0x07, 0x54, 0x59, 0x35, + 0x5d, 0xee, 0x79, 0x99, 0xdd, 0x22, 0x8e, 0x25, 0x29, 0x85, 0x63, 0xb1, + 0xfc, 0x7e, 0x34, 0xbd, 0xb3, 0x57, 0x34, 0x6c, 0xae, 0x65, 0x6c, 0x81, + 0x1a, 0x83, 0x90, 0x0f, 0xb9, 0xd1, 0x97, 0x1a, 0xb7, 0xac, 0x40, 0xb1, + 0x43, 0xf2, 0x94, 0xea, 0x02, 0xf2, 0x2e, 0x09, 0x62, 0x3b, 0xe9, 0x32, + 0x99, 0x21, 0x12, 0x34, 0x52, 0x14, 0x05, 0xb1, 0x19, 0x23, 0x72, 0xde, + 0xc3, 0x50, 0x84, 0x7f, 0x10, 0xb8, 0x6b, 0x88, 0xc5, 0xfa, 0xe3, 0x79, + 0x9e, 0xd9, 0x33, 0x50, 0xcb, 0x57, 0x37, 0x85, 0x2a, 0xee, 0x39, 0x3c, + 0x56, 0x03, 0x3e, 0x9d, 0x07, 0xeb, 0xa1, 0x28, 0xac, 0xf3, 0xd2, 0xd2, + 0xbd, 0x6d, 0x43, 0x72, 0x3c, 0x60, 0x15, 0x41, 0xd5, 0x75, 0x78, 0xe3, + 0x7e, 0x27, 0xa5, 0x96, 0xef, 0x3d, 0xb7, 0xe6, 0x5c, 0xc7, 0x4b, 0x33, + 0xaf, 0x86, 0x7f, 0xc6, 0x18, 0xe4, 0x9e, 0xdd, 0x49, 0xc7, 0xb6, 0xaa, + 0x35, 0x57, 0x17, 0xaa, 0x2d, 0x00, 0x3c, 0xa8, 0x73, 0xef, 0x9d, 0xf5, + 0x9b, 0x04, 0x25, 0xb5, 0xca, 0x7d, 0xff, 0x00, 0xe1, 0xc5, 0x97, 0xd9, + 0x84, 0x47, 0x55, 0x25, 0x6d, 0x74, 0x75, 0x15, 0xb3, 0xbc, 0xc4, 0xb6, + 0x4b, 0x39, 0xe6, 0x00, 0xfa, 0x9c, 0x9d, 0xc6, 0xfa, 0xb5, 0x9e, 0x24, + 0xa7, 0xa5, 0xb3, 0xd3, 0xd9, 0xa9, 0xee, 0x0c, 0x20, 0x4c, 0xf3, 0x00, + 0xa5, 0x4b, 0x39, 0xdc, 0x9f, 0x5c, 0x7f, 0xdf, 0xde, 0x91, 0x12, 0x08, + 0x21, 0x67, 0x5f, 0xab, 0x1b, 0x6b, 0xed, 0x0a, 0x78, 0x93, 0x89, 0x64, + 0xcb, 0x04, 0x39, 0xfc, 0xe8, 0x26, 0xf9, 0x48, 0x56, 0xf2, 0xfb, 0x6f, + 0xba, 0x34, 0x96, 0xba, 0xab, 0x74, 0x52, 0x7f, 0xba, 0xcb, 0xcb, 0xe2, + 0x12, 0x30, 0x3a, 0x74, 0xc6, 0xab, 0xb7, 0x68, 0xe3, 0xa7, 0xa9, 0x54, + 0x8c, 0x89, 0x09, 0x1e, 0x66, 0x1b, 0x83, 0xed, 0x9d, 0x29, 0xaf, 0xaf, + 0xa9, 0xa6, 0x63, 0x0d, 0x31, 0x68, 0xfc, 0x4e, 0x56, 0x66, 0x56, 0xec, + 0x07, 0x4f, 0xdf, 0x52, 0x5a, 0xe7, 0x79, 0xa2, 0x78, 0x66, 0x60, 0xce, + 0x4f, 0x30, 0x63, 0xd7, 0x55, 0x54, 0x54, 0xa7, 0xb8, 0xd4, 0xfe, 0x11, + 0x58, 0x7e, 0x1f, 0xde, 0xea, 0x61, 0xa1, 0xbd, 0x5e, 0xea, 0xa9, 0xeb, + 0xa5, 0xd9, 0x69, 0x5c, 0x08, 0xe3, 0x90, 0xfa, 0x09, 0x0e, 0x72, 0x7a, + 0xed, 0xb6, 0xb7, 0xe8, 0x61, 0xe1, 0x1e, 0x07, 0xa2, 0x4a, 0x5a, 0x5a, + 0x40, 0x8e, 0xc9, 0xff, 0x00, 0x06, 0x18, 0x8c, 0x92, 0x32, 0xe3, 0xa9, + 0xf6, 0xdb, 0xae, 0xc3, 0x5e, 0x53, 0xe1, 0xb8, 0x6d, 0xf5, 0x93, 0x1a, + 0x5a, 0xe8, 0x99, 0x9e, 0x48, 0xf9, 0x29, 0x9c, 0x3f, 0x2f, 0x85, 0x36, + 0x57, 0x95, 0x89, 0xf4, 0xeb, 0xfa, 0xea, 0xdd, 0x74, 0xbc, 0xf1, 0x6f, + 0x0d, 0xd3, 0x1b, 0x55, 0xce, 0xb2, 0x3b, 0x8d, 0x1b, 0x1e, 0x69, 0x8a, + 0x8c, 0xcf, 0x32, 0x67, 0xe9, 0x62, 0x7c, 0xc5, 0x7b, 0x63, 0xa6, 0xda, + 0x09, 0x6a, 0x31, 0xc7, 0xc2, 0xbc, 0xbd, 0x0d, 0xc7, 0x38, 0xae, 0x97, + 0x27, 0xcf, 0x88, 0xb7, 0x3b, 0x75, 0xf6, 0xf7, 0x57, 0x58, 0x69, 0x44, + 0x6a, 0x1d, 0xbc, 0x1f, 0x02, 0x35, 0x50, 0x17, 0x3b, 0x1d, 0xba, 0x93, + 0xea, 0x73, 0xac, 0xca, 0xba, 0x81, 0x64, 0xad, 0x32, 0x46, 0x8c, 0xa3, + 0xb3, 0x36, 0x0b, 0x63, 0xf4, 0xd5, 0xba, 0xf4, 0xa5, 0x78, 0x4a, 0xb3, + 0x8a, 0x6d, 0x55, 0x54, 0xd1, 0x50, 0xd1, 0xf2, 0xc2, 0x20, 0x95, 0xb9, + 0x5a, 0x49, 0x5b, 0xfe, 0x5e, 0xe7, 0x19, 0x39, 0xed, 0xac, 0xee, 0xd5, + 0x7e, 0x45, 0x41, 0x1d, 0x67, 0x36, 0x32, 0xcd, 0xe2, 0x01, 0x96, 0xc9, + 0xdf, 0x41, 0x8d, 0x39, 0x2b, 0x6a, 0x85, 0xbb, 0xbe, 0x06, 0x41, 0x15, + 0x67, 0xf9, 0x79, 0x23, 0x0a, 0x08, 0xf2, 0x30, 0x3e, 0x9d, 0x06, 0x34, + 0x44, 0xf1, 0xd5, 0xd2, 0x53, 0xac, 0xeb, 0x87, 0x8f, 0x62, 0x79, 0x86, + 0x70, 0x34, 0x9f, 0x88, 0xea, 0x64, 0xa8, 0xb3, 0xd1, 0x55, 0x40, 0xad, + 0x03, 0x34, 0x87, 0xae, 0xe4, 0xe3, 0x38, 0x3a, 0x0e, 0xa7, 0x88, 0x2e, + 0x15, 0x36, 0x7a, 0x9a, 0x17, 0x3e, 0x27, 0x88, 0x98, 0x04, 0x1c, 0x15, + 0xdc, 0x69, 0x98, 0xbe, 0xa0, 0x9c, 0xf1, 0x0d, 0x6c, 0xf5, 0xfc, 0xa2, + 0x6a, 0x78, 0x51, 0xe2, 0x61, 0x1a, 0xf2, 0xb7, 0x98, 0x83, 0xed, 0x8e, + 0x83, 0x5d, 0x0b, 0x39, 0xb7, 0x52, 0x0a, 0xcb, 0x8c, 0x4b, 0xe0, 0xcb, + 0x1f, 0x89, 0x4e, 0x76, 0xfe, 0x68, 0xe6, 0x23, 0xd7, 0x6d, 0xd7, 0x40, + 0xd8, 0xa9, 0xda, 0xa8, 0xb3, 0xcf, 0x0c, 0xb2, 0x78, 0x23, 0x9c, 0x0e, + 0xc0, 0x02, 0x3a, 0xfa, 0x8d, 0x38, 0xbd, 0xdf, 0xe9, 0xae, 0xf5, 0x15, + 0x8f, 0x53, 0x48, 0xb1, 0xca, 0x89, 0x1a, 0x52, 0xa4, 0x28, 0x23, 0x48, + 0x54, 0x64, 0x9d, 0x80, 0xef, 0x9d, 0x0b, 0x1b, 0x16, 0x70, 0xe5, 0xea, + 0xa8, 0xe3, 0x01, 0x7f, 0x9a, 0xaf, 0xcc, 0xb1, 0xa0, 0xf2, 0xa2, 0x67, + 0x6f, 0xce, 0x8a, 0xbd, 0xcf, 0x34, 0xa9, 0x29, 0x41, 0xe6, 0x88, 0x22, + 0xb1, 0x07, 0x21, 0x98, 0x64, 0x93, 0x9f, 0x5d, 0xfa, 0x68, 0x5e, 0x1f, + 0xaa, 0x92, 0x92, 0xb6, 0x1a, 0x93, 0x1a, 0xb7, 0x33, 0x96, 0x90, 0x11, + 0x9f, 0x21, 0xdb, 0xfe, 0xbf, 0x8d, 0x17, 0xcf, 0x51, 0x6f, 0xaf, 0xad, + 0xa5, 0x0d, 0x84, 0x9c, 0x73, 0x00, 0x06, 0xc4, 0x7a, 0x6b, 0x5e, 0x17, + 0xc5, 0x1d, 0x0c, 0x0f, 0xc4, 0x0e, 0xa6, 0x71, 0x55, 0x08, 0xb8, 0x4c, + 0xed, 0x14, 0xed, 0x20, 0x56, 0x3d, 0x79, 0x90, 0x83, 0xab, 0x2f, 0x11, + 0xc1, 0x3b, 0xdb, 0x66, 0x96, 0x01, 0x27, 0x82, 0xaa, 0xa5, 0x14, 0x8d, + 0x89, 0x39, 0x00, 0x0f, 0xb0, 0x1f, 0xf7, 0x9d, 0x27, 0xe1, 0xca, 0x58, + 0xee, 0x54, 0xb2, 0x41, 0x24, 0x2a, 0x0f, 0x3e, 0xd2, 0x16, 0xc9, 0x4f, + 0xc6, 0x37, 0x18, 0xed, 0xab, 0x2c, 0x17, 0x1f, 0xfe, 0xcf, 0xa5, 0xb5, + 0x55, 0x4f, 0x2d, 0x3c, 0xd2, 0x86, 0x85, 0x5e, 0x55, 0x3c, 0xb8, 0x2e, + 0x00, 0xc7, 0x63, 0x91, 0x9e, 0xfd, 0x34, 0xfb, 0x34, 0xd8, 0x05, 0x1c, + 0x36, 0xf8, 0xf8, 0x6e, 0x9a, 0xe3, 0x53, 0x0b, 0xa4, 0x10, 0xa3, 0x23, + 0xc6, 0xad, 0xe6, 0x79, 0x5b, 0xa3, 0x7d, 0x8e, 0x3f, 0x1a, 0xab, 0x57, + 0x61, 0xa0, 0xa7, 0x91, 0x69, 0x5a, 0x28, 0x08, 0x28, 0x27, 0xee, 0xec, + 0x7f, 0xc4, 0x3f, 0x1a, 0x3e, 0xe8, 0x93, 0x50, 0x73, 0x5a, 0x56, 0xa1, + 0xa5, 0x32, 0xb1, 0xf0, 0xd4, 0x21, 0xfa, 0x81, 0x20, 0x6a, 0x4a, 0x09, + 0x29, 0xa5, 0xa5, 0x4a, 0x4a, 0x98, 0x2a, 0x24, 0xa9, 0x84, 0x37, 0xf2, + 0x08, 0xf2, 0x87, 0x3b, 0x02, 0x7e, 0xc7, 0x54, 0x53, 0x64, 0x34, 0x86, + 0x96, 0x8a, 0x92, 0x25, 0x8e, 0x15, 0x96, 0xac, 0x64, 0x3f, 0x8a, 0xbc, + 0xd1, 0xae, 0xe3, 0x18, 0x19, 0xd3, 0x99, 0xa9, 0x1a, 0xa6, 0x64, 0xe7, + 0x67, 0x92, 0x56, 0x40, 0x5c, 0x2a, 0xe0, 0x2e, 0x71, 0xb8, 0x00, 0xe3, + 0x1e, 0xda, 0x16, 0x8a, 0xd1, 0x5b, 0x82, 0x23, 0xa6, 0x25, 0x64, 0xf2, + 0x80, 0x1f, 0x20, 0x37, 0x5d, 0xce, 0x3a, 0xf4, 0xd8, 0xfa, 0x8d, 0x39, + 0xa1, 0x57, 0xb7, 0xd4, 0xcf, 0x6f, 0xb8, 0x49, 0x1c, 0x50, 0x48, 0x8a, + 0xf2, 0x2a, 0x37, 0x3c, 0xc7, 0xa7, 0xd2, 0xc3, 0xf7, 0x1a, 0x84, 0x21, + 0xf0, 0xe8, 0x28, 0x5a, 0x28, 0xe1, 0x57, 0xab, 0xa9, 0x23, 0x99, 0x93, + 0xa9, 0x18, 0xf5, 0x5e, 0xc3, 0xdb, 0xf4, 0xd4, 0xc6, 0xba, 0xfc, 0x94, + 0xd3, 0x2b, 0x62, 0x86, 0x0a, 0x8c, 0x16, 0x64, 0x02, 0x36, 0xe5, 0xec, + 0x32, 0x4e, 0xc3, 0xa6, 0xa1, 0xae, 0xac, 0xa5, 0x9f, 0xc2, 0x86, 0xd3, + 0x6e, 0x65, 0x98, 0xcc, 0x79, 0xa6, 0x7e, 0xac, 0x4e, 0x7c, 0xbf, 0x60, + 0x75, 0xc3, 0xfc, 0xb0, 0x0f, 0x05, 0x64, 0x4e, 0xd2, 0xb1, 0xda, 0x79, + 0xc9, 0xc0, 0x1d, 0x49, 0x41, 0x8d, 0x87, 0xbe, 0xff, 0x00, 0x6d, 0x42, + 0x06, 0x43, 0x7d, 0x96, 0x1b, 0x7c, 0x34, 0x56, 0x89, 0x33, 0x51, 0x51, + 0xe7, 0xa8, 0x91, 0xa3, 0x0c, 0xfc, 0xc7, 0x6e, 0x6c, 0x9e, 0xfe, 0xfa, + 0xee, 0x9a, 0xcb, 0x78, 0xa9, 0x55, 0x96, 0xae, 0x59, 0xa5, 0x8a, 0x12, + 0x58, 0x78, 0x8d, 0xce, 0x71, 0xdf, 0xca, 0x3a, 0x01, 0xd3, 0x3f, 0xf6, + 0x07, 0x96, 0x4a, 0x68, 0x22, 0x89, 0x6d, 0xe8, 0xaa, 0xe8, 0x7c, 0x4f, + 0x1b, 0x9b, 0x97, 0x94, 0xf5, 0xdc, 0xe3, 0xd3, 0x42, 0x52, 0x56, 0x56, + 0x55, 0x21, 0xa7, 0x8e, 0xad, 0x99, 0x64, 0x62, 0xcf, 0x32, 0x13, 0xcc, + 0xfb, 0xf4, 0x3a, 0x84, 0x0c, 0xb8, 0x5c, 0xa8, 0x29, 0xa3, 0xf9, 0x6b, + 0x4c, 0x4a, 0x24, 0x66, 0x21, 0xe4, 0x45, 0x05, 0xc7, 0xb0, 0x6f, 0x5f, + 0x7f, 0xf5, 0xd7, 0x16, 0x64, 0xba, 0xb2, 0xd4, 0xd4, 0xd2, 0x52, 0xc7, + 0x14, 0x4a, 0xc3, 0x9e, 0x57, 0x39, 0x20, 0xe3, 0xbf, 0xa9, 0xd7, 0x5f, + 0x25, 0x49, 0x41, 0x28, 0x2c, 0x7c, 0x59, 0x0a, 0x61, 0x41, 0x18, 0x20, + 0xed, 0xdf, 0x46, 0x56, 0xd5, 0xc5, 0xf2, 0x06, 0x0e, 0x52, 0xaf, 0x26, + 0x19, 0xa2, 0x41, 0x85, 0x51, 0x8e, 0xff, 0x00, 0xe2, 0x3a, 0x11, 0x88, + 0xe9, 0x2e, 0xd5, 0xe9, 0x13, 0x52, 0xc7, 0x13, 0x47, 0x33, 0xc9, 0xca, + 0xae, 0xd8, 0x5e, 0x61, 0xdf, 0x18, 0x1f, 0x4e, 0x81, 0xab, 0xa4, 0xa3, + 0x42, 0xc6, 0xa2, 0xbd, 0xa5, 0x99, 0x62, 0xe7, 0x96, 0x45, 0xcb, 0x1e, + 0x6f, 0xf0, 0x80, 0x3b, 0x60, 0xe7, 0x5c, 0x56, 0xbd, 0x24, 0x94, 0xca, + 0xa7, 0x94, 0x33, 0x1c, 0xe0, 0x1f, 0x30, 0xcf, 0xb6, 0x8c, 0xb3, 0xdd, + 0xa1, 0xa4, 0x33, 0x53, 0x45, 0x4b, 0x1c, 0x6d, 0x24, 0x65, 0x10, 0xc9, + 0x0a, 0xb3, 0x1e, 0x98, 0xcb, 0x7d, 0x86, 0xa0, 0x14, 0xe3, 0xd0, 0xb6, + 0xc7, 0x1c, 0x32, 0xe5, 0xa3, 0xa7, 0x32, 0x7f, 0x49, 0x69, 0x54, 0xe4, + 0x82, 0x3d, 0xff, 0x00, 0xb6, 0x98, 0x57, 0xd1, 0x59, 0xa3, 0xaa, 0x5a, + 0x8a, 0xda, 0xb9, 0xe4, 0x99, 0xf7, 0xf0, 0x55, 0x42, 0x82, 0x70, 0x70, + 0x07, 0xa0, 0x1a, 0x81, 0x6b, 0x40, 0xcb, 0xab, 0xc6, 0xc0, 0xae, 0x15, + 0x91, 0x76, 0x07, 0xbf, 0xe9, 0xa5, 0xeb, 0x53, 0x11, 0xaa, 0x0b, 0x31, + 0x90, 0xb6, 0x7a, 0x7f, 0x4b, 0x1f, 0x5c, 0xff, 0x00, 0x96, 0xad, 0x12, + 0xac, 0xb4, 0x70, 0xf5, 0xb2, 0x8e, 0xf5, 0x6a, 0x9e, 0x05, 0x34, 0x94, + 0x45, 0x50, 0xc9, 0x3c, 0x93, 0xe5, 0xe4, 0x75, 0x04, 0x74, 0x03, 0xd0, + 0x67, 0xef, 0x8d, 0x09, 0x53, 0x6a, 0xa3, 0xa5, 0x74, 0x9e, 0x82, 0xe6, + 0x67, 0x90, 0x02, 0xdc, 0xc0, 0x05, 0x0b, 0xbf, 0xeb, 0x9f, 0x6e, 0xdb, + 0xf5, 0xd2, 0xf9, 0xa5, 0x2d, 0x4d, 0x24, 0x91, 0x88, 0x96, 0x25, 0x6c, + 0x66, 0x3f, 0xbe, 0x8b, 0x8a, 0xe0, 0xfe, 0x04, 0x94, 0xb4, 0x8b, 0xcf, + 0xcd, 0x8c, 0x86, 0x18, 0xe5, 0x03, 0x55, 0x61, 0xc3, 0x1a, 0x5d, 0x9f, + 0x6b, 0x24, 0x9a, 0xb2, 0xa4, 0x4d, 0x59, 0x53, 0xe3, 0x15, 0x1e, 0x69, + 0x65, 0x7e, 0x8b, 0xec, 0x7d, 0x75, 0xc5, 0xe2, 0x48, 0xab, 0x63, 0xa7, + 0xa4, 0xa3, 0xa7, 0x59, 0x20, 0xa7, 0x53, 0x23, 0xca, 0xab, 0x8f, 0x10, + 0x12, 0x0e, 0xe7, 0xbf, 0x6d, 0x45, 0x77, 0x45, 0xab, 0x8c, 0x2c, 0xf2, + 0xa1, 0x91, 0xf0, 0x15, 0x00, 0xfa, 0x71, 0xa9, 0xe8, 0x84, 0x66, 0x86, + 0x48, 0x9a, 0x75, 0x8d, 0xce, 0xc5, 0xdb, 0x7e, 0x6d, 0x52, 0x65, 0xed, + 0xae, 0x85, 0x57, 0x9a, 0xfa, 0xb8, 0x5e, 0x08, 0xe2, 0x05, 0xa3, 0x93, + 0x0f, 0xca, 0xaa, 0x70, 0xa7, 0xfc, 0xfd, 0x35, 0x35, 0x4c, 0xf4, 0xb1, + 0xa7, 0xcc, 0xd4, 0x54, 0xcc, 0x95, 0x12, 0x2e, 0x70, 0xbf, 0xe2, 0xff, + 0x00, 0x2f, 0x4d, 0x0b, 0x5f, 0x3c, 0x4a, 0xea, 0x8e, 0x24, 0x6f, 0x0d, + 0xb0, 0x08, 0x07, 0x71, 0xed, 0xbf, 0xdb, 0x5c, 0x4b, 0x72, 0xa1, 0x33, + 0x47, 0x1b, 0x53, 0xaa, 0xca, 0xa0, 0x2a, 0x87, 0x1e, 0x60, 0x75, 0x2c, + 0x94, 0x49, 0xe3, 0xcd, 0x3d, 0x31, 0xf0, 0xe0, 0x54, 0x56, 0x1b, 0xb6, + 0x31, 0x9f, 0x7d, 0x09, 0x4a, 0x88, 0x19, 0x96, 0x59, 0x0c, 0x93, 0xc5, + 0xe6, 0x2c, 0xdd, 0x17, 0xd3, 0x5d, 0xcf, 0x0d, 0x74, 0xc7, 0x9a, 0x7a, + 0x94, 0xa7, 0x84, 0x9c, 0x80, 0xbf, 0x57, 0xe3, 0x40, 0x56, 0xb5, 0x32, + 0x7f, 0x22, 0x08, 0x9a, 0x56, 0xfe, 0xa9, 0x1f, 0xb9, 0xf4, 0xd5, 0xd9, + 0x03, 0x38, 0x96, 0x10, 0x9c, 0x51, 0x79, 0xce, 0x0f, 0x3d, 0xc2, 0x76, + 0x3f, 0xff, 0x00, 0xd1, 0xb4, 0x3c, 0x30, 0xab, 0xb4, 0x71, 0x80, 0x00, + 0xc8, 0x3a, 0xfd, 0xc5, 0xcc, 0xff, 0x00, 0xfa, 0xbe, 0xee, 0xb1, 0x80, + 0x49, 0xaf, 0x9c, 0x1f, 0x6f, 0xe6, 0x36, 0x8e, 0xb3, 0x52, 0xb1, 0x2b, + 0x9c, 0x9c, 0x0c, 0x13, 0xe9, 0x8e, 0xfa, 0x16, 0x70, 0x72, 0x76, 0xce, + 0xde, 0x15, 0x05, 0x52, 0x31, 0xcd, 0x81, 0x86, 0x3a, 0xfc, 0xc1, 0x29, + 0xe9, 0xf0, 0x48, 0x01, 0x77, 0x27, 0x46, 0x38, 0x5c, 0x19, 0x30, 0x79, + 0x15, 0x79, 0x8b, 0x7b, 0x7a, 0xe9, 0x69, 0x9e, 0x49, 0xa6, 0x25, 0x55, + 0x58, 0x8e, 0xfd, 0xa3, 0xfb, 0x7b, 0xfb, 0xe9, 0x51, 0x8d, 0xb1, 0x62, + 0xda, 0xe6, 0x92, 0x4f, 0xf7, 0x96, 0x6e, 0x50, 0xf8, 0x48, 0xd4, 0x8d, + 0xd8, 0x6e, 0x73, 0xa6, 0x16, 0xa6, 0x2b, 0x1a, 0x13, 0xb8, 0xf5, 0xd2, + 0xfb, 0xb3, 0x7f, 0x35, 0x23, 0xe7, 0x69, 0x02, 0x8e, 0x76, 0x63, 0xd4, + 0x93, 0xb7, 0xf6, 0x1a, 0x71, 0x41, 0x4f, 0x23, 0xd2, 0x24, 0xf1, 0xc6, + 0x4c, 0x60, 0x0e, 0x9f, 0x6d, 0x04, 0xf8, 0x74, 0x08, 0xd2, 0x9c, 0x3f, + 0x97, 0x93, 0x6c, 0x60, 0xe7, 0x4c, 0xae, 0xdc, 0x61, 0x72, 0xa4, 0xe2, + 0xda, 0x5a, 0xf5, 0x68, 0xb1, 0x35, 0xb8, 0x51, 0xb4, 0x64, 0x86, 0x19, + 0x0b, 0x80, 0xec, 0x08, 0xf5, 0xdf, 0x42, 0xd9, 0x69, 0xa5, 0x9c, 0x16, + 0x2d, 0x1c, 0x51, 0x03, 0x86, 0x79, 0x1b, 0x00, 0x1f, 0x4f, 0xbe, 0xac, + 0x77, 0x2e, 0x1f, 0xb0, 0xd2, 0x59, 0x29, 0x2f, 0x55, 0xf3, 0xc7, 0xf3, + 0x8a, 0x59, 0x0a, 0x15, 0xd9, 0xa3, 0x3e, 0x56, 0x38, 0xeb, 0xce, 0x33, + 0xb1, 0x1d, 0x0f, 0xae, 0xb9, 0xf9, 0xfe, 0x36, 0xed, 0x87, 0x08, 0xd1, + 0x4b, 0xa9, 0x5a, 0x4a, 0x9a, 0x34, 0x72, 0x64, 0x12, 0x39, 0x08, 0x55, + 0x50, 0x90, 0xcc, 0x46, 0x72, 0x31, 0xdc, 0xe4, 0xfd, 0xb7, 0xd5, 0x6e, + 0xe9, 0x6a, 0x8a, 0x86, 0x71, 0x3d, 0x43, 0xc6, 0x50, 0xe7, 0x28, 0xad, + 0xe6, 0x18, 0x3b, 0xe4, 0x76, 0xd5, 0x9a, 0xe9, 0xc5, 0xd5, 0xfc, 0x25, + 0x7b, 0xaa, 0xa4, 0xb1, 0x50, 0xd1, 0x8a, 0x6a, 0x92, 0xbe, 0x0c, 0xf3, + 0xd3, 0x7f, 0x35, 0x53, 0x1b, 0x18, 0xcb, 0x6e, 0x0e, 0xe7, 0x7d, 0x57, + 0xef, 0xcd, 0x47, 0x2a, 0xc2, 0xeb, 0x70, 0x4a, 0x8a, 0xc9, 0xc0, 0x73, + 0x18, 0x88, 0x83, 0x1b, 0x13, 0xb8, 0x66, 0x27, 0x05, 0xba, 0xe7, 0x1b, + 0x7b, 0xeb, 0x55, 0x49, 0xc5, 0x49, 0x8e, 0x64, 0x53, 0x9f, 0xe2, 0x14, + 0xa0, 0xa2, 0x08, 0xa9, 0xcb, 0x1f, 0x96, 0x42, 0x77, 0x7d, 0x03, 0x1c, + 0x46, 0x13, 0xba, 0x05, 0xe5, 0x38, 0x6f, 0x63, 0xa8, 0x2f, 0xb5, 0x75, + 0x35, 0x12, 0xc5, 0x4d, 0x24, 0xb9, 0x8a, 0x8d, 0x4c, 0x70, 0x28, 0x18, + 0xe5, 0x19, 0xcb, 0x1f, 0xbe, 0x75, 0xf6, 0xcb, 0x53, 0x4f, 0x9a, 0x95, + 0xaf, 0x8d, 0xa7, 0xfe, 0x51, 0xf0, 0xdb, 0x9b, 0x74, 0x3b, 0x60, 0xfe, + 0x3a, 0x7e, 0x75, 0x70, 0x8b, 0x5d, 0x80, 0xd0, 0x5d, 0xc2, 0xf3, 0x58, + 0xf2, 0x54, 0x3c, 0x54, 0x94, 0xf0, 0x42, 0xe4, 0x23, 0x34, 0x29, 0xcb, + 0x80, 0x31, 0xb7, 0xea, 0x33, 0x9f, 0x53, 0xa3, 0x38, 0x32, 0xde, 0xd7, + 0xab, 0xb9, 0xa5, 0x32, 0xc3, 0x02, 0x4a, 0x59, 0xa4, 0xa8, 0x99, 0xb9, + 0x42, 0x80, 0x32, 0x49, 0x6e, 0xc0, 0x01, 0x9d, 0x22, 0x9b, 0x9a, 0x03, + 0x2c, 0x7c, 0xbe, 0x2c, 0x64, 0x61, 0xb2, 0x71, 0xae, 0xed, 0xeb, 0x22, + 0x51, 0x38, 0x35, 0x02, 0x2a, 0x76, 0x50, 0x65, 0xc1, 0xce, 0x7b, 0xe0, + 0xe9, 0xff, 0x00, 0x1a, 0xf4, 0x35, 0x44, 0x6f, 0x71, 0xb9, 0x41, 0x6a, + 0x81, 0x8d, 0x21, 0x47, 0x4f, 0x10, 0xac, 0x52, 0x63, 0x3e, 0x22, 0x8e, + 0xfb, 0xef, 0xff, 0x00, 0x9d, 0x75, 0x55, 0x2f, 0xce, 0xd3, 0xdb, 0x6f, + 0x10, 0x9f, 0xe7, 0x4c, 0xc2, 0x19, 0x71, 0xdb, 0x6d, 0x57, 0xef, 0x01, + 0x2b, 0x44, 0x2b, 0x02, 0x88, 0xd1, 0x00, 0x00, 0x67, 0x60, 0x31, 0xab, + 0x7d, 0xb6, 0xc1, 0x33, 0xf0, 0x55, 0x35, 0x54, 0x15, 0x10, 0x34, 0x09, + 0x2b, 0x2e, 0x43, 0x79, 0xa3, 0x97, 0x63, 0xb8, 0xed, 0x9c, 0x9c, 0x6a, + 0xf1, 0xc5, 0x46, 0x5c, 0x7b, 0x1d, 0xa7, 0x95, 0x4a, 0x8e, 0xf8, 0x46, + 0x68, 0xad, 0xd7, 0x7a, 0xba, 0x29, 0xc1, 0x8a, 0x69, 0x64, 0x0a, 0xac, + 0x47, 0x94, 0x6f, 0xbe, 0x47, 0xa6, 0x33, 0xa6, 0x5c, 0x46, 0x69, 0xa4, + 0xe1, 0x44, 0x34, 0xd3, 0x2c, 0x81, 0x18, 0xf8, 0x43, 0x3b, 0xa3, 0x07, + 0x38, 0x20, 0xf7, 0xdb, 0x51, 0x5a, 0xad, 0x54, 0x55, 0xf7, 0xca, 0x05, + 0x59, 0x98, 0x45, 0x71, 0x82, 0x58, 0xe5, 0x27, 0xcd, 0xcb, 0x2a, 0x0f, + 0x37, 0xa6, 0xc4, 0xe8, 0x8e, 0x17, 0x84, 0x53, 0xd4, 0x49, 0x62, 0xbb, + 0x27, 0xf3, 0x28, 0x5d, 0xbc, 0x0c, 0x9d, 0x9f, 0x27, 0x61, 0x8f, 0x40, + 0x0e, 0x7f, 0x3a, 0xd2, 0x6e, 0x14, 0xdf, 0x28, 0xe6, 0x17, 0xf1, 0x0c, + 0xb5, 0xb0, 0xb7, 0x2c, 0x48, 0xe7, 0xae, 0x09, 0x6c, 0x74, 0x3d, 0x36, + 0xcf, 0x5d, 0x4d, 0x6e, 0x9e, 0xa2, 0x19, 0x62, 0x7a, 0x57, 0xa7, 0x12, + 0xab, 0x32, 0x13, 0x2e, 0xea, 0x33, 0xb8, 0x23, 0xd4, 0xed, 0xfa, 0x6a, + 0x5b, 0x85, 0x12, 0x10, 0xd5, 0x10, 0x85, 0x2f, 0x22, 0x91, 0xb7, 0xd0, + 0x33, 0x90, 0x32, 0x7d, 0xb1, 0xd3, 0x40, 0x5c, 0xe6, 0x5b, 0x6d, 0xbd, + 0xcc, 0xcc, 0x5d, 0x8a, 0x8e, 0xa3, 0x04, 0xb3, 0x0e, 0x9d, 0xff, 0x00, + 0xec, 0x1d, 0x42, 0x9a, 0x38, 0x5b, 0xcd, 0x64, 0xcd, 0x53, 0x45, 0x3d, + 0x5d, 0x05, 0x2b, 0x2b, 0x9e, 0x79, 0x9a, 0x52, 0xc4, 0x80, 0x77, 0xf0, + 0xd4, 0xec, 0x09, 0xf4, 0xd1, 0x34, 0x86, 0x2a, 0xb9, 0x44, 0x76, 0xf9, + 0x1a, 0xa0, 0xf4, 0x79, 0x64, 0x3c, 0xa4, 0xfa, 0x8e, 0xfa, 0xa2, 0xba, + 0xc0, 0x55, 0xe5, 0x91, 0xd9, 0xe5, 0x46, 0xc2, 0xa9, 0x3b, 0x0f, 0xfc, + 0x6a, 0xff, 0x00, 0xf0, 0xd6, 0x84, 0xdd, 0xd5, 0x56, 0x3a, 0xa2, 0xaf, + 0x21, 0x28, 0x60, 0x43, 0x86, 0x60, 0xa0, 0x16, 0x6c, 0xfa, 0x6a, 0x15, + 0xb9, 0x2e, 0xce, 0xe5, 0x33, 0xd1, 0xd6, 0x24, 0x63, 0xc3, 0x25, 0x18, + 0x1e, 0x45, 0xf6, 0xd3, 0xca, 0x9a, 0xab, 0x65, 0x4c, 0x82, 0xb2, 0xad, + 0xa1, 0x33, 0x3e, 0x09, 0x76, 0x18, 0x03, 0x6e, 0xde, 0x9a, 0x1a, 0xba, + 0xc6, 0xf6, 0xab, 0x84, 0x8f, 0x24, 0x0d, 0x0b, 0x83, 0x82, 0xa7, 0x32, + 0x72, 0x13, 0xd0, 0x64, 0x7a, 0xe8, 0x1a, 0x8a, 0x55, 0xaa, 0xb8, 0xf2, + 0xbd, 0x4c, 0x06, 0x38, 0xcf, 0x21, 0x91, 0xdb, 0x93, 0x1b, 0x03, 0xf4, + 0x9e, 0xdd, 0xb5, 0x06, 0x45, 0x46, 0x43, 0xca, 0xba, 0x3b, 0x65, 0x4d, + 0x2c, 0x75, 0x10, 0x49, 0x2b, 0x52, 0xf2, 0x66, 0x47, 0x91, 0x79, 0x15, + 0xcf, 0xa0, 0xfb, 0x7a, 0xe9, 0x1c, 0x72, 0x5a, 0xab, 0xae, 0x93, 0xba, + 0x54, 0xcb, 0x41, 0x16, 0x15, 0x12, 0x3c, 0x1e, 0x46, 0x41, 0xeb, 0x8f, + 0x5d, 0x73, 0x0d, 0x28, 0xab, 0xaf, 0x11, 0x52, 0xd4, 0x07, 0xa5, 0x89, + 0x72, 0xf2, 0x67, 0xcb, 0xdb, 0x23, 0xdb, 0xed, 0xa9, 0xab, 0x22, 0xa4, + 0x15, 0x5f, 0xee, 0x6f, 0xe2, 0xc6, 0x83, 0x99, 0xa4, 0xe4, 0xcf, 0x39, + 0xe9, 0xb6, 0xfd, 0x34, 0x05, 0xec, 0x3f, 0x55, 0xc0, 0x22, 0x96, 0x49, + 0xf3, 0x13, 0x72, 0xb9, 0xe5, 0x4f, 0x10, 0x6c, 0xb9, 0xe9, 0x9c, 0x64, + 0xe3, 0x5f, 0x09, 0xa0, 0x69, 0xd7, 0xc4, 0x12, 0x3c, 0x6d, 0xbb, 0x3f, + 0x26, 0x06, 0x75, 0xd5, 0x0c, 0x2a, 0xb0, 0x99, 0x0a, 0x2e, 0x7a, 0xf3, + 0xb8, 0xc9, 0x1e, 0x9a, 0x1e, 0xa6, 0xad, 0x01, 0x6c, 0xc8, 0xc4, 0x11, + 0x82, 0x54, 0x72, 0x92, 0x7d, 0xb5, 0x2c, 0x24, 0x88, 0xee, 0x09, 0x4d, + 0x15, 0x63, 0x44, 0x2a, 0x92, 0x6a, 0x79, 0x14, 0x81, 0xcb, 0xb0, 0x55, + 0x3d, 0x06, 0x7a, 0x9c, 0x6a, 0x4a, 0x6b, 0x62, 0xcc, 0xac, 0xf3, 0x7c, + 0xa1, 0x87, 0x62, 0x25, 0x73, 0xbe, 0xdd, 0x40, 0xd2, 0x72, 0x61, 0x59, + 0x39, 0xa4, 0x2c, 0xa8, 0x0e, 0x48, 0x51, 0x9d, 0x33, 0xa2, 0x96, 0x81, + 0xdb, 0xe6, 0xe0, 0x89, 0x88, 0x56, 0xe5, 0xfa, 0x82, 0x9f, 0xbe, 0xfa, + 0x96, 0x48, 0x47, 0x90, 0xca, 0xa0, 0x5e, 0x1c, 0xc3, 0x22, 0x98, 0x90, + 0xe5, 0x42, 0x0f, 0x20, 0x1f, 0xf2, 0xfe, 0xa7, 0xf5, 0xd4, 0x10, 0xab, + 0x46, 0x85, 0xd8, 0x0f, 0x31, 0xd8, 0x93, 0xa6, 0x72, 0xd5, 0x17, 0x89, + 0x56, 0x33, 0x85, 0x23, 0x38, 0x6d, 0xf1, 0x9d, 0x05, 0x51, 0x19, 0x78, + 0xb9, 0x24, 0x95, 0x37, 0x39, 0xc8, 0x19, 0x00, 0x7a, 0x7d, 0xf4, 0x36, + 0x32, 0x8e, 0x23, 0xe4, 0x2f, 0x97, 0x78, 0xbc, 0x6c, 0xf9, 0x15, 0xba, + 0x0f, 0x7f, 0xfa, 0xe8, 0x5a, 0x95, 0x8d, 0xe7, 0x0d, 0x53, 0x52, 0xc9, + 0x17, 0x49, 0x18, 0x30, 0x23, 0x3e, 0xc3, 0xbe, 0x8e, 0x8e, 0xaa, 0x8a, + 0x9c, 0x32, 0x1c, 0x29, 0xc7, 0x95, 0x89, 0xce, 0x80, 0xaa, 0xf0, 0x1a, + 0x21, 0x15, 0x35, 0x32, 0x7f, 0x88, 0x1e, 0x5c, 0x67, 0xdf, 0x3a, 0x89, + 0x83, 0x41, 0x31, 0x44, 0x21, 0x85, 0xa4, 0x86, 0x6c, 0x43, 0x8f, 0x2b, + 0x14, 0xc3, 0x63, 0xfc, 0xb5, 0x09, 0xab, 0xa4, 0x40, 0xaf, 0x83, 0x2c, + 0xa0, 0x7d, 0x4c, 0x37, 0xd0, 0x71, 0x53, 0x4d, 0x22, 0xa4, 0x50, 0xc1, + 0x34, 0xf3, 0x31, 0xc6, 0x22, 0x56, 0x60, 0xb8, 0xfc, 0x6f, 0xab, 0x5f, + 0x0b, 0xfc, 0x32, 0xe3, 0x2e, 0x24, 0x9a, 0x37, 0x86, 0xc1, 0x58, 0x60, + 0xe5, 0x00, 0xcb, 0x51, 0x88, 0x50, 0x6e, 0x33, 0xf5, 0x60, 0x9c, 0x0f, + 0x4c, 0xea, 0xec, 0x85, 0x62, 0x6b, 0xc4, 0xb2, 0x6c, 0x94, 0xa4, 0xb2, + 0x9c, 0x00, 0xfd, 0x0e, 0x3d, 0x35, 0xf2, 0xa2, 0xae, 0xaa, 0xb9, 0x07, + 0x8a, 0x90, 0xaf, 0x37, 0xd3, 0x91, 0xb6, 0x75, 0xb3, 0x56, 0x7c, 0x06, + 0x96, 0xcf, 0x2c, 0xd5, 0x95, 0xd7, 0x75, 0x34, 0x71, 0x6e, 0x9e, 0x04, + 0x21, 0x5a, 0x4f, 0xc9, 0x27, 0x97, 0xf7, 0xd5, 0x83, 0x83, 0x57, 0x86, + 0x78, 0x76, 0xa5, 0x0f, 0xf0, 0x2a, 0x22, 0x09, 0x21, 0xe6, 0x91, 0x3c, + 0x49, 0x37, 0xea, 0x43, 0x36, 0x71, 0xf6, 0xd6, 0x0c, 0xdf, 0x90, 0xc5, + 0x87, 0x26, 0xc9, 0xf0, 0x64, 0xcb, 0xac, 0xc7, 0x89, 0xd4, 0x8c, 0x9b, + 0xe1, 0xf7, 0xc2, 0x4e, 0x30, 0xe2, 0xdc, 0x55, 0x4d, 0x1c, 0x94, 0x16, + 0xdf, 0xe9, 0xa9, 0xa8, 0x04, 0x07, 0x1f, 0xf2, 0xa9, 0xc1, 0x23, 0x7e, + 0xba, 0xde, 0xf8, 0x1f, 0xe1, 0x0f, 0x06, 0x70, 0xd5, 0x10, 0x7a, 0x8a, + 0x75, 0xbb, 0x5c, 0x39, 0x73, 0x24, 0xd5, 0x03, 0x2a, 0x0e, 0x07, 0xd2, + 0x9d, 0x06, 0xfe, 0xb9, 0x3e, 0xfa, 0xb7, 0xdc, 0x78, 0xc2, 0x8e, 0x9e, + 0x8e, 0x19, 0x62, 0x41, 0x3f, 0x38, 0xda, 0x3e, 0x81, 0x75, 0xd5, 0x97, + 0x88, 0xa3, 0xba, 0xb8, 0x8e, 0x4a, 0x55, 0x87, 0x23, 0x20, 0x0d, 0xc7, + 0xeb, 0xeb, 0xab, 0x7a, 0xcd, 0x33, 0x96, 0xc8, 0xcd, 0x36, 0xcc, 0xdf, + 0xca, 0xc7, 0x3e, 0x99, 0xe7, 0x2f, 0xff, 0x00, 0x88, 0x6b, 0xab, 0x6e, + 0xf5, 0x17, 0xbb, 0xd5, 0xc2, 0x9a, 0xd3, 0x6e, 0xad, 0xac, 0x92, 0x58, + 0x9b, 0x9c, 0x3c, 0x92, 0xa1, 0x72, 0xc4, 0x85, 0xe8, 0x36, 0x23, 0xaf, + 0xae, 0x99, 0x70, 0xef, 0x03, 0xc1, 0x59, 0x5d, 0xc5, 0x31, 0x59, 0xe9, + 0x95, 0xe9, 0xe0, 0x81, 0xe9, 0xe9, 0xcc, 0xad, 0xb9, 0xc9, 0x05, 0x7e, + 0xec, 0x40, 0xeb, 0x9d, 0x69, 0x1c, 0x5b, 0x15, 0xba, 0x4a, 0xae, 0x1d, + 0x92, 0xe7, 0x33, 0x24, 0x51, 0x5b, 0x61, 0xe4, 0xe5, 0x6c, 0xb0, 0x24, + 0x1f, 0xe9, 0xf4, 0x3b, 0x6f, 0xa6, 0x1c, 0x1d, 0x4b, 0x5b, 0x6f, 0xa5, + 0xb9, 0xcf, 0x1c, 0x50, 0x47, 0x4a, 0x19, 0xa6, 0x46, 0x55, 0xda, 0x47, + 0xe5, 0x3c, 0xa7, 0x3d, 0xc0, 0xc6, 0x7e, 0xf8, 0xd3, 0xe7, 0xe1, 0x22, + 0x64, 0xc6, 0x94, 0xa9, 0x1e, 0x53, 0xbd, 0xb3, 0xc2, 0xe6, 0x85, 0xd5, + 0xe3, 0x90, 0x31, 0xf1, 0x50, 0x8f, 0x30, 0xc6, 0xdc, 0xa7, 0xdf, 0x39, + 0xfd, 0x34, 0x34, 0x4b, 0x31, 0x89, 0x62, 0x08, 0xb1, 0x21, 0x20, 0x10, + 0x06, 0xe7, 0xef, 0xa2, 0xae, 0xd3, 0x34, 0xb7, 0x09, 0x6a, 0x27, 0x72, + 0xf2, 0xca, 0xd9, 0x77, 0x3d, 0xcf, 0x7d, 0x45, 0x16, 0x19, 0x58, 0x91, + 0xb6, 0x36, 0xd1, 0xc5, 0xd1, 0x81, 0xf6, 0x03, 0x5f, 0x01, 0x77, 0x66, + 0x55, 0xc1, 0x52, 0x47, 0xdf, 0x56, 0x9e, 0x1f, 0x88, 0xa5, 0x8e, 0x33, + 0x08, 0x01, 0xca, 0xe4, 0xae, 0x92, 0x34, 0x6a, 0xd1, 0xb6, 0x7e, 0xc3, + 0x5a, 0x25, 0xa2, 0xd9, 0x1c, 0x74, 0x34, 0x50, 0xca, 0xeb, 0x1a, 0xb6, + 0x09, 0x94, 0x9c, 0x05, 0x07, 0xa9, 0xfd, 0x33, 0xaa, 0x84, 0xb9, 0x6c, + 0xa0, 0xeb, 0x35, 0xda, 0xe9, 0x07, 0x04, 0x09, 0x23, 0xb7, 0xc3, 0x1c, + 0x36, 0xe5, 0x92, 0x45, 0x9f, 0x00, 0x18, 0xe6, 0x66, 0xc2, 0xc9, 0xbf, + 0xd4, 0xdd, 0x40, 0x03, 0xa0, 0xce, 0xdd, 0xf5, 0x47, 0xaa, 0x7b, 0x95, + 0x65, 0xc9, 0xaa, 0x6b, 0x6a, 0x1a, 0x67, 0x93, 0x76, 0x9b, 0x3b, 0x9d, + 0xf3, 0xd7, 0xae, 0x72, 0x35, 0x0d, 0xd2, 0x6a, 0xba, 0x9a, 0x99, 0x16, + 0x33, 0x53, 0x1d, 0x03, 0x4a, 0x3e, 0x5e, 0x9e, 0x59, 0x08, 0xe6, 0x03, + 0xa3, 0x15, 0xf5, 0xc6, 0xbe, 0x73, 0x4d, 0x44, 0xfc, 0xa8, 0x43, 0xc4, + 0x40, 0x62, 0x31, 0xea, 0x33, 0xae, 0x7d, 0xb9, 0xab, 0x7d, 0x92, 0xdf, + 0xb1, 0xef, 0xfe, 0xab, 0xe1, 0xdb, 0x35, 0x1c, 0xd5, 0xf7, 0xdb, 0x3c, + 0x97, 0xab, 0xc8, 0x46, 0x58, 0x04, 0xa5, 0x4c, 0x4c, 0x36, 0xf3, 0x3e, + 0x73, 0xb8, 0xf4, 0x00, 0x1d, 0xf5, 0x93, 0x5d, 0x6a, 0x7f, 0x8a, 0xdc, + 0x26, 0xae, 0x11, 0x47, 0x4d, 0x23, 0x31, 0x2b, 0x14, 0x43, 0x0a, 0x83, + 0x39, 0xc0, 0xd3, 0x5e, 0x2c, 0x91, 0x66, 0xaa, 0x05, 0x0e, 0xeb, 0x93, + 0x8f, 0x63, 0xa4, 0x44, 0xaa, 0xc7, 0x14, 0x7c, 0xc0, 0x78, 0xe7, 0x90, + 0xb1, 0xe8, 0x0f, 0xa1, 0xd7, 0x46, 0x2d, 0xec, 0x49, 0x8f, 0x8c, 0x9b, + 0xec, 0xec, 0x1f, 0x15, 0x73, 0x27, 0x99, 0xb3, 0xe6, 0xcf, 0xae, 0xa2, + 0xaf, 0x44, 0x82, 0x08, 0xc8, 0x60, 0xbc, 0xc7, 0x66, 0xf7, 0xd3, 0x7a, + 0x2b, 0x44, 0xf1, 0xe0, 0xa0, 0x0b, 0x8d, 0xb0, 0x76, 0x24, 0x6b, 0x8b, + 0xe4, 0x3e, 0x15, 0x19, 0xf1, 0xd2, 0x2d, 0xfe, 0xa0, 0x17, 0xbf, 0xae, + 0xab, 0x22, 0xb4, 0x8a, 0x8f, 0x62, 0x4a, 0x47, 0x69, 0x27, 0x45, 0x69, + 0x39, 0x57, 0x1b, 0x9e, 0xde, 0xff, 0x00, 0xdb, 0x47, 0xdc, 0x2a, 0x69, + 0xa3, 0x50, 0xd4, 0xf0, 0xc6, 0x25, 0xe8, 0xdb, 0x6d, 0x9f, 0x4c, 0x69, + 0x13, 0x2b, 0xae, 0x02, 0xbb, 0x04, 0xd8, 0x92, 0x36, 0xfc, 0x68, 0xe6, + 0x81, 0x10, 0x23, 0x40, 0xc4, 0xae, 0x03, 0x12, 0xdd, 0x73, 0xdf, 0xf1, + 0xa5, 0xa4, 0x12, 0x64, 0x31, 0xc9, 0x14, 0x93, 0xe1, 0x93, 0x90, 0x92, + 0x7a, 0x74, 0xfd, 0x35, 0xe8, 0xfa, 0x0e, 0x0d, 0xb3, 0x5b, 0x3e, 0x09, + 0x48, 0x68, 0x96, 0x79, 0xeb, 0xaa, 0x04, 0x15, 0xf5, 0x12, 0x33, 0x79, + 0x49, 0x5d, 0xc8, 0x51, 0x9d, 0x80, 0x42, 0xda, 0xf3, 0xfa, 0xc2, 0x12, + 0x56, 0x2e, 0x42, 0xb8, 0x00, 0xa9, 0x03, 0xa8, 0x3b, 0xeb, 0xd0, 0xdc, + 0x0f, 0xf1, 0x04, 0x55, 0xf0, 0x5d, 0xbe, 0xd0, 0x91, 0xc4, 0xd3, 0x52, + 0xd3, 0x0a, 0x69, 0x55, 0x86, 0x4e, 0x00, 0xc0, 0x3f, 0x91, 0xa5, 0x67, + 0xda, 0xaa, 0x52, 0x74, 0x90, 0x37, 0xcd, 0x99, 0xa8, 0x13, 0xc5, 0x43, + 0x25, 0xc5, 0x1f, 0x96, 0x7a, 0x3a, 0x91, 0x32, 0xa9, 0x18, 0xf1, 0x14, + 0x9e, 0x57, 0xc0, 0xef, 0xe6, 0x03, 0xf5, 0x1a, 0x6d, 0x7f, 0x78, 0xe4, + 0xbd, 0x5a, 0xaa, 0xea, 0x52, 0x58, 0x52, 0x5a, 0x57, 0xdc, 0x1f, 0x36, + 0x7a, 0x8c, 0x8f, 0x61, 0x8d, 0x7e, 0xa5, 0xa3, 0x86, 0xa0, 0x5e, 0xad, + 0x0d, 0x21, 0x5a, 0xa8, 0x49, 0x11, 0x87, 0xd8, 0x3c, 0x6c, 0x83, 0x60, + 0x3b, 0x79, 0x94, 0x7e, 0xba, 0xe6, 0xae, 0x2a, 0x9b, 0x9d, 0x8f, 0x87, + 0x1c, 0x6f, 0x50, 0xb2, 0xc7, 0x18, 0x3f, 0xf2, 0x82, 0x57, 0xfb, 0x0d, + 0x74, 0x62, 0xd4, 0x95, 0xa3, 0xac, 0xb9, 0x42, 0xca, 0x8a, 0xb1, 0x00, + 0x96, 0x9e, 0x59, 0xe1, 0x67, 0x8e, 0x55, 0x87, 0x9b, 0x18, 0x56, 0x52, + 0x09, 0xe6, 0x23, 0xb9, 0xc9, 0xc9, 0xf5, 0xfc, 0x69, 0x1d, 0xcd, 0xa2, + 0x91, 0xe3, 0x50, 0xa2, 0x79, 0x64, 0x03, 0x2f, 0xfd, 0x38, 0xec, 0x71, + 0xdb, 0xed, 0xa7, 0xbc, 0x45, 0x22, 0x7f, 0x15, 0x91, 0x04, 0x3c, 0xe9, + 0x2c, 0x2a, 0x55, 0x13, 0x62, 0x58, 0x33, 0x63, 0x3a, 0x4d, 0x67, 0xa7, + 0x96, 0x47, 0x96, 0xb2, 0xa6, 0x3c, 0xb2, 0x36, 0xc9, 0xd3, 0x18, 0xd8, + 0xea, 0xc6, 0x51, 0x2d, 0xaa, 0xd5, 0x6d, 0xa4, 0xa9, 0xac, 0x32, 0xc5, + 0x0c, 0xf2, 0x54, 0x29, 0x4f, 0x3a, 0x6d, 0x19, 0xc7, 0x51, 0xff, 0x00, + 0x7d, 0xf4, 0xf3, 0x83, 0xea, 0xa5, 0xb0, 0x42, 0x25, 0xa4, 0x8a, 0x9a, + 0x82, 0x49, 0xa6, 0x65, 0x4a, 0x95, 0x8c, 0x39, 0x8e, 0x23, 0xec, 0x48, + 0xdc, 0x91, 0xb7, 0xb6, 0x96, 0x4c, 0x4c, 0x15, 0x12, 0x7c, 0xc3, 0x6f, + 0x29, 0x57, 0xe5, 0x4d, 0xd8, 0x92, 0x3b, 0x0d, 0x77, 0x71, 0xa9, 0x69, + 0x53, 0xe4, 0x60, 0xa6, 0x8e, 0x06, 0x95, 0x46, 0x65, 0x78, 0xc6, 0xeb, + 0xd3, 0x3e, 0xd8, 0x07, 0x19, 0xf5, 0x3a, 0x00, 0x66, 0x83, 0xab, 0x6a, + 0xea, 0xe6, 0x49, 0xab, 0x2e, 0x17, 0x96, 0xf0, 0x6a, 0x7c, 0xd1, 0x45, + 0x1b, 0x79, 0x80, 0x3b, 0x82, 0xde, 0xff, 0x00, 0x6d, 0x2d, 0x86, 0x4a, + 0x68, 0x22, 0x96, 0x78, 0xe1, 0x79, 0xcb, 0x00, 0xaa, 0xd2, 0x80, 0x47, + 0x36, 0x3b, 0x69, 0xa5, 0x45, 0xbe, 0x8a, 0x92, 0xdc, 0xf5, 0x4c, 0xaf, + 0x20, 0x50, 0xab, 0x17, 0x3a, 0xed, 0x81, 0xdc, 0x8f, 0x43, 0xdb, 0x50, + 0x53, 0x1f, 0x98, 0xa8, 0x35, 0x95, 0xe2, 0x38, 0x29, 0x97, 0xc8, 0x39, + 0x13, 0x00, 0x11, 0xd8, 0x0f, 0xc6, 0xa0, 0x6a, 0x07, 0x34, 0x90, 0x23, + 0x50, 0xc3, 0x0b, 0xf2, 0xa3, 0xc8, 0x39, 0x9f, 0x19, 0x00, 0x8f, 0x4f, + 0xfb, 0xf4, 0xd1, 0x31, 0x40, 0xb0, 0xc8, 0x20, 0xf1, 0x02, 0x43, 0x93, + 0xcc, 0x54, 0xee, 0xc3, 0x4b, 0x6b, 0xeb, 0x5a, 0x79, 0x84, 0x31, 0x07, + 0x48, 0xf9, 0x89, 0x0b, 0xcc, 0x73, 0x8f, 0xf2, 0xd4, 0xad, 0x1c, 0xd1, + 0x22, 0x91, 0x84, 0xc9, 0xca, 0x03, 0x92, 0x70, 0x46, 0x7a, 0xe7, 0x50, + 0x60, 0x65, 0x53, 0xc7, 0x0a, 0x88, 0xd2, 0x00, 0x0f, 0x31, 0x06, 0x59, + 0x18, 0x1e, 0x6f, 0x4c, 0x7a, 0x68, 0x1a, 0xaa, 0xd6, 0xe5, 0x68, 0x95, + 0x23, 0x04, 0x0c, 0x73, 0x05, 0xc8, 0xd7, 0x35, 0xd2, 0xb3, 0xc7, 0x12, + 0x31, 0xf3, 0x31, 0x00, 0x9e, 0x60, 0x77, 0xc7, 0xf7, 0xd0, 0x29, 0x04, + 0x22, 0xb2, 0x40, 0xc2, 0x52, 0x63, 0xe8, 0x5b, 0x61, 0x9d, 0x2c, 0x84, + 0x90, 0x55, 0x2a, 0x23, 0x09, 0xa7, 0x63, 0xd8, 0xaa, 0x46, 0x30, 0x75, + 0x0c, 0x73, 0xc5, 0x1c, 0x92, 0xba, 0x29, 0x54, 0x39, 0x61, 0x9f, 0x5d, + 0x14, 0x65, 0xa5, 0xa6, 0x4e, 0x6a, 0x94, 0x66, 0x69, 0x73, 0xc9, 0xe5, + 0xc6, 0x4f, 0xa0, 0xd4, 0x74, 0x34, 0x93, 0x5c, 0xaa, 0x9e, 0x38, 0x41, + 0x41, 0x18, 0x0c, 0xf1, 0xb0, 0xc1, 0x00, 0xf6, 0xd5, 0x49, 0xa4, 0xad, + 0x82, 0xe7, 0x1c, 0x6a, 0xe4, 0xcf, 0xd1, 0xd5, 0x49, 0x55, 0x12, 0x32, + 0xe5, 0xb3, 0x91, 0x8e, 0x83, 0x6d, 0x3b, 0xe1, 0xde, 0x1c, 0xbc, 0x5c, + 0xe0, 0x6a, 0xb5, 0x10, 0xd2, 0x53, 0x09, 0x39, 0x3c, 0x6a, 0x89, 0x02, + 0x26, 0x7d, 0x89, 0xdd, 0xbe, 0xc0, 0x1d, 0x3d, 0xb0, 0x70, 0xd5, 0xca, + 0xd2, 0xf4, 0xb7, 0xb6, 0xb3, 0x25, 0x4d, 0x1c, 0x45, 0x64, 0xe5, 0x91, + 0x03, 0xa4, 0x9e, 0xc4, 0x67, 0x45, 0xdf, 0xae, 0x54, 0x1c, 0x45, 0xc6, + 0x12, 0xd5, 0xc4, 0xb0, 0x5a, 0xa9, 0x9c, 0x89, 0x24, 0x49, 0x5f, 0x96, + 0x35, 0x7c, 0x00, 0xd8, 0x18, 0xeb, 0xfe, 0x9a, 0xcd, 0x93, 0x54, 0xaa, + 0xa1, 0xd9, 0xcf, 0xcb, 0xac, 0x57, 0x50, 0xe4, 0x9a, 0x5f, 0x86, 0x16, + 0xf3, 0xe1, 0x4d, 0x72, 0xba, 0x99, 0xd1, 0x94, 0xb0, 0x92, 0x05, 0xf2, + 0x6d, 0xd4, 0x02, 0x7a, 0x77, 0xed, 0xa6, 0x74, 0x1f, 0x0d, 0x78, 0x7d, + 0xee, 0x34, 0xd5, 0x74, 0xf7, 0x4b, 0x8d, 0x55, 0x34, 0x88, 0x3f, 0x92, + 0xfb, 0x3b, 0x82, 0x32, 0x14, 0x1c, 0xec, 0x0e, 0xdb, 0xe3, 0x56, 0xfe, + 0x16, 0xbf, 0x70, 0xb5, 0x25, 0xa5, 0xe9, 0x2b, 0x6a, 0xad, 0xd3, 0xc3, + 0x12, 0x2a, 0x8f, 0x02, 0x42, 0x43, 0x9e, 0xcd, 0x82, 0x3e, 0xbd, 0xce, + 0xfe, 0xc3, 0x57, 0xbb, 0x05, 0x77, 0x0a, 0x47, 0x6d, 0x94, 0xda, 0xea, + 0xe9, 0xa0, 0xf0, 0x51, 0x25, 0xa9, 0x91, 0x9b, 0x1e, 0x18, 0x60, 0x70, + 0x0b, 0x7e, 0x0e, 0xda, 0xe6, 0xfc, 0x3a, 0xb9, 0xbb, 0x79, 0x69, 0x19, + 0xbe, 0x7c, 0x8f, 0xfb, 0xcc, 0xf6, 0x86, 0xeb, 0x5d, 0xc1, 0x96, 0xd6, + 0xb2, 0xd1, 0x5a, 0x85, 0xa2, 0x16, 0x91, 0x8b, 0x18, 0xe2, 0xcb, 0x36, + 0x7f, 0xab, 0x9f, 0xd7, 0x6d, 0x36, 0xb4, 0x71, 0xdc, 0xb4, 0xb6, 0xf5, + 0x86, 0xae, 0xe3, 0x1a, 0x73, 0x1c, 0xc1, 0x2b, 0xb7, 0x9a, 0x45, 0x3d, + 0x9b, 0xdc, 0x7f, 0x96, 0x9d, 0xdf, 0x6f, 0x56, 0x2b, 0xa5, 0xba, 0xa2, + 0x95, 0x6a, 0xad, 0xd3, 0xa7, 0x86, 0x79, 0xa5, 0x9a, 0x50, 0x30, 0x7d, + 0x37, 0x1f, 0xbe, 0xb1, 0x7b, 0x8d, 0xb2, 0xed, 0x2c, 0x32, 0x7c, 0x9c, + 0x74, 0xf7, 0x5a, 0x26, 0xcb, 0x2c, 0x51, 0x37, 0x34, 0x91, 0x2e, 0x3a, + 0xff, 0x00, 0xd7, 0x57, 0x9b, 0x0e, 0x5d, 0xb4, 0xa7, 0x7f, 0xf6, 0x23, + 0x24, 0xa7, 0xea, 0x56, 0x6b, 0xd7, 0x3e, 0x2d, 0x9e, 0xa2, 0xdf, 0xe0, + 0x0a, 0xc8, 0xda, 0x26, 0x05, 0x64, 0xca, 0x87, 0x2f, 0xfa, 0xf4, 0xd5, + 0x2a, 0xed, 0x0c, 0x33, 0x54, 0x43, 0x83, 0xf2, 0xf0, 0x31, 0x1e, 0x33, + 0x67, 0x65, 0x4e, 0xbf, 0xae, 0x91, 0x70, 0xec, 0xb1, 0x41, 0xc2, 0x38, + 0x86, 0x36, 0x9e, 0x56, 0x25, 0xe3, 0x32, 0x3f, 0xd0, 0x17, 0x66, 0x5c, + 0xe3, 0x1d, 0xc6, 0xdd, 0x76, 0xd2, 0xda, 0xaa, 0x9a, 0x8b, 0xbd, 0x05, + 0x44, 0xe6, 0xb2, 0x8a, 0x0a, 0x78, 0x17, 0x95, 0x95, 0xe7, 0x0a, 0x5b, + 0xff, 0x00, 0x88, 0xfd, 0xb5, 0xcc, 0x78, 0x35, 0x19, 0x66, 0xb7, 0xc9, + 0xb4, 0x26, 0xa6, 0xfb, 0x1b, 0xde, 0x78, 0xe2, 0x82, 0x0b, 0xc8, 0x86, + 0x82, 0x88, 0x55, 0x51, 0x53, 0xa2, 0xa6, 0x0c, 0xe4, 0x07, 0x20, 0x63, + 0x9b, 0x38, 0xce, 0xfa, 0xd1, 0x3e, 0x1c, 0x71, 0xfd, 0x8a, 0xf0, 0x82, + 0xdb, 0x4d, 0x4b, 0xfc, 0x3e, 0xbf, 0x97, 0x22, 0x26, 0x3c, 0xdc, 0xe4, + 0x76, 0x56, 0xdb, 0x3a, 0xc7, 0xed, 0x2d, 0xc2, 0xd4, 0x09, 0x29, 0x96, + 0xd8, 0xd7, 0x9a, 0x9c, 0x8d, 0x84, 0xf8, 0xa7, 0x55, 0xc7, 0xa8, 0x1b, + 0x9d, 0xff, 0x00, 0xbe, 0xb4, 0xbe, 0x09, 0x3c, 0x33, 0x74, 0x86, 0x2a, + 0x9a, 0x6b, 0x5d, 0x1d, 0x2d, 0x64, 0x78, 0x25, 0x15, 0x07, 0x3a, 0x9f, + 0x5c, 0xeb, 0xa7, 0x87, 0x0c, 0x31, 0x4a, 0xe3, 0x15, 0x63, 0x21, 0x2d, + 0xa2, 0x7e, 0x28, 0x8e, 0xe5, 0xc5, 0x1c, 0x5f, 0x6e, 0xa6, 0xb5, 0xd3, + 0x93, 0x53, 0x6d, 0xb7, 0xc4, 0x31, 0x33, 0x72, 0xc6, 0x11, 0x54, 0x67, + 0x27, 0x7d, 0x89, 0x23, 0x57, 0x2e, 0x20, 0xe2, 0x0b, 0x77, 0x0f, 0x70, + 0xfd, 0x3d, 0x0c, 0xf5, 0x46, 0x09, 0x2a, 0x19, 0x11, 0xe4, 0x84, 0x11, + 0xcb, 0xd8, 0xe0, 0x7a, 0x76, 0xfb, 0x0d, 0x0d, 0x5d, 0x2d, 0x55, 0x15, + 0xae, 0x29, 0x2d, 0xf0, 0x4e, 0x9e, 0x2c, 0x71, 0x89, 0x66, 0xa7, 0x5e, + 0x69, 0x47, 0x97, 0xb0, 0xd5, 0x16, 0xe1, 0x79, 0xe1, 0x0b, 0x4d, 0xfa, + 0x14, 0xe2, 0x7b, 0xb4, 0xb5, 0xb2, 0x73, 0xf3, 0xd4, 0x52, 0xcf, 0x91, + 0x27, 0x7c, 0x0f, 0x2f, 0xbf, 0x6f, 0xdb, 0x5d, 0x79, 0x79, 0xb3, 0xa7, + 0x2f, 0x25, 0x66, 0x3d, 0x78, 0x8e, 0x4a, 0x5e, 0x21, 0xae, 0x81, 0xd5, + 0xd7, 0xc3, 0x99, 0x94, 0x12, 0x36, 0x23, 0x27, 0x1f, 0xb0, 0xd7, 0x70, + 0x03, 0xcb, 0x93, 0xdf, 0xb6, 0xb5, 0xcf, 0x8b, 0x5c, 0x05, 0x1d, 0xea, + 0x55, 0xe2, 0xce, 0x0f, 0x6a, 0x6a, 0x9a, 0x49, 0x23, 0x5f, 0x16, 0x92, + 0x39, 0x4f, 0x88, 0x08, 0x00, 0x64, 0x29, 0xea, 0x71, 0x81, 0x81, 0xbe, + 0xda, 0xad, 0xf0, 0xd7, 0xc2, 0xbe, 0x2d, 0xbc, 0xf8, 0x73, 0x4d, 0x6e, + 0x9a, 0xdb, 0x42, 0xcc, 0xb9, 0x9a, 0xa5, 0x08, 0x23, 0x7d, 0xf0, 0xbd, + 0x4e, 0xde, 0xb8, 0x1a, 0x4a, 0x95, 0xba, 0x39, 0xd2, 0xc5, 0x26, 0xf8, + 0x14, 0x70, 0x05, 0x82, 0xe1, 0xc4, 0x5c, 0x45, 0x1d, 0x2d, 0x15, 0x0c, + 0xd5, 0x29, 0x09, 0x12, 0x4d, 0xc8, 0x36, 0x54, 0xf5, 0x3f, 0x73, 0xad, + 0xd6, 0x9e, 0xd8, 0x96, 0x79, 0xde, 0xe5, 0x55, 0x49, 0x1c, 0xb2, 0x52, + 0xa7, 0x96, 0x09, 0xd7, 0x99, 0x79, 0x8f, 0x42, 0x46, 0x7e, 0xfa, 0xbb, + 0x70, 0x57, 0x08, 0xd9, 0x78, 0x2e, 0xcb, 0x15, 0x1d, 0xba, 0x27, 0x79, + 0x1c, 0x8f, 0x1a, 0xa9, 0x90, 0x19, 0x25, 0x6f, 0x56, 0xf6, 0xf6, 0xed, + 0xaa, 0xef, 0x1f, 0xde, 0x2d, 0xe2, 0xad, 0xa9, 0xe0, 0x90, 0x97, 0x4d, + 0xa5, 0x0a, 0x36, 0x2c, 0x3a, 0xfe, 0xfa, 0x1c, 0xf3, 0x96, 0x3c, 0x6e, + 0x9d, 0x36, 0x1c, 0xf1, 0xa8, 0x46, 0xd9, 0x99, 0x71, 0x6d, 0x25, 0xba, + 0xe5, 0x57, 0x25, 0x7d, 0xca, 0x95, 0x00, 0x5c, 0xb3, 0x38, 0x24, 0x01, + 0xeb, 0xb0, 0xd6, 0x7f, 0x76, 0x97, 0x87, 0xaa, 0xea, 0x45, 0x1d, 0x9e, + 0x92, 0x6e, 0x42, 0x30, 0xf3, 0x4a, 0xc5, 0x53, 0xdc, 0x81, 0xe9, 0xad, + 0x1f, 0x8c, 0x2d, 0xb3, 0xdd, 0x2c, 0x2e, 0xd4, 0xde, 0x43, 0x34, 0x80, + 0x04, 0xc1, 0x62, 0xc3, 0x7c, 0xf4, 0xe9, 0xf9, 0xd6, 0x37, 0xc4, 0x2e, + 0x96, 0xfb, 0x83, 0xdb, 0x23, 0xe4, 0x11, 0xc6, 0xc1, 0x26, 0x90, 0x36, + 0x72, 0xdd, 0xf1, 0xfa, 0x63, 0xef, 0x9d, 0x63, 0xd2, 0xc3, 0x2c, 0xe1, + 0xbf, 0x23, 0x62, 0x60, 0x7c, 0xb9, 0xd9, 0x28, 0x00, 0xf0, 0x9a, 0xa6, + 0x6e, 0x40, 0x0a, 0x99, 0xd1, 0x0a, 0xa9, 0x1e, 0xed, 0x9d, 0x05, 0x1f, + 0x0d, 0xd3, 0x47, 0x08, 0x8e, 0x98, 0xb4, 0x91, 0x1c, 0xee, 0xe7, 0x25, + 0x94, 0xee, 0x0e, 0x75, 0x71, 0x86, 0x5a, 0x3a, 0x7b, 0x4b, 0x45, 0x30, + 0x24, 0x39, 0x00, 0xc7, 0x8e, 0xa3, 0x1a, 0xa3, 0x52, 0xde, 0xa4, 0xa7, + 0xbb, 0x56, 0x52, 0xc4, 0x85, 0x69, 0x62, 0x97, 0x08, 0x8c, 0x73, 0x81, + 0xed, 0xae, 0x94, 0x61, 0x51, 0xa1, 0x84, 0xc6, 0x2a, 0xdb, 0x74, 0x52, + 0x34, 0x55, 0x06, 0x58, 0x93, 0x2a, 0xb1, 0x3f, 0x55, 0x3e, 0xc7, 0x55, + 0xcb, 0x8d, 0xce, 0xa2, 0x49, 0xd6, 0x26, 0x91, 0xd4, 0xc9, 0x83, 0x82, + 0x7d, 0x75, 0x76, 0x8c, 0xd0, 0x5c, 0x84, 0x80, 0xb7, 0x84, 0x1c, 0x61, + 0xb0, 0x39, 0x89, 0x3f, 0x6d, 0x4b, 0x6c, 0xf8, 0x71, 0x6b, 0xae, 0xf8, + 0x8d, 0x4f, 0xc2, 0xf4, 0x57, 0x89, 0xbc, 0x27, 0x1e, 0x2c, 0xd5, 0x95, + 0x09, 0x83, 0x12, 0x84, 0x2e, 0xe3, 0x04, 0xf5, 0x18, 0xc6, 0x33, 0xd7, + 0xbe, 0x8d, 0x85, 0x13, 0x3e, 0x93, 0x0a, 0x0f, 0x88, 0x76, 0x03, 0xbf, + 0x7d, 0x4f, 0x02, 0x2b, 0xc0, 0xac, 0x98, 0xc1, 0x03, 0x5c, 0xdd, 0xed, + 0xd3, 0xd4, 0x5c, 0xea, 0x29, 0x52, 0x4f, 0xf7, 0x78, 0xa6, 0x60, 0x24, + 0x3b, 0xe4, 0x02, 0x40, 0xfb, 0xed, 0xa9, 0xa1, 0x85, 0x29, 0x63, 0x31, + 0xa9, 0x2e, 0xa0, 0xec, 0x71, 0x8d, 0x0d, 0x12, 0x71, 0x0a, 0x4a, 0x41, + 0x25, 0x30, 0x63, 0x2c, 0x6c, 0xe8, 0xbb, 0x28, 0x3d, 0x73, 0xd0, 0x7d, + 0xf4, 0xce, 0xdf, 0x5d, 0x4f, 0x68, 0x00, 0x13, 0x3c, 0x15, 0x41, 0xbc, + 0xcc, 0x4e, 0xc0, 0xe0, 0xe3, 0x3e, 0xde, 0xda, 0x06, 0xd9, 0x70, 0xf0, + 0x23, 0x92, 0x15, 0xa7, 0x89, 0xe2, 0x95, 0xd7, 0xc4, 0x56, 0x1b, 0x9e, + 0x52, 0x0e, 0x41, 0xed, 0xd3, 0x4d, 0x2f, 0x37, 0x1a, 0x4b, 0x8f, 0x2b, + 0x55, 0xc4, 0xa5, 0xd1, 0x3c, 0x35, 0x7c, 0x79, 0xf9, 0x47, 0x40, 0x4f, + 0x7c, 0x0d, 0x25, 0xc7, 0xfd, 0xcb, 0x82, 0x51, 0x6d, 0xb5, 0xd6, 0x9b, + 0xb7, 0x10, 0xdb, 0x2e, 0xd0, 0xc4, 0xaf, 0x52, 0x41, 0x8a, 0xa0, 0x83, + 0xb3, 0xe1, 0x00, 0xc9, 0x1e, 0x9d, 0x0e, 0xa0, 0x98, 0xbd, 0x0d, 0xa6, + 0xe9, 0x49, 0x09, 0x65, 0x9e, 0xdf, 0x5a, 0x8f, 0x4e, 0x73, 0x95, 0x72, + 0xe7, 0x2a, 0x07, 0xa6, 0xdd, 0x74, 0xb7, 0x83, 0xee, 0x1e, 0x35, 0x3c, + 0xdf, 0x22, 0x16, 0x39, 0xed, 0xa8, 0x65, 0x0a, 0xc3, 0x66, 0x0a, 0x30, + 0x0f, 0xef, 0xa3, 0x2e, 0xf2, 0xc7, 0x4f, 0x75, 0xaf, 0x28, 0xea, 0x62, + 0x8e, 0x5a, 0x5a, 0xa6, 0x03, 0xe9, 0x72, 0x46, 0x3f, 0x38, 0xc8, 0xc1, + 0xd7, 0x47, 0x0f, 0xd0, 0xeb, 0x61, 0xfa, 0x20, 0x5a, 0xf5, 0x32, 0xf1, + 0x2d, 0xae, 0xac, 0x4c, 0x4b, 0xc8, 0x65, 0x89, 0x8c, 0x87, 0x02, 0x26, + 0x0c, 0x7f, 0x4c, 0xf6, 0xd7, 0xeb, 0x51, 0x92, 0x3b, 0xad, 0x7d, 0x2c, + 0xb4, 0xc0, 0x4b, 0x1f, 0x33, 0xa2, 0x73, 0x64, 0xb1, 0x27, 0xaf, 0xe3, + 0x44, 0x5c, 0x26, 0xb6, 0x8b, 0x64, 0x74, 0xef, 0x1c, 0x32, 0x4b, 0x0c, + 0xb2, 0x31, 0x95, 0x81, 0x39, 0x2e, 0x49, 0x05, 0xbe, 0xe3, 0x03, 0xbe, + 0x87, 0xbc, 0xcf, 0x53, 0x55, 0x73, 0xb5, 0x5c, 0xa8, 0xd3, 0xc2, 0xae, + 0xa8, 0x85, 0x4c, 0xa1, 0x4e, 0x39, 0x59, 0x47, 0x9b, 0x56, 0x37, 0x78, + 0x3a, 0x49, 0x4c, 0xd5, 0x69, 0x55, 0x31, 0x12, 0xf9, 0xc2, 0xb8, 0x71, + 0xf4, 0x8f, 0x61, 0xe9, 0xef, 0xdf, 0x44, 0x5e, 0xd6, 0x1b, 0x55, 0xfe, + 0x3a, 0xb1, 0x00, 0x9a, 0x9e, 0x78, 0x73, 0x4e, 0x84, 0xf9, 0x47, 0x62, + 0x71, 0xae, 0x78, 0xba, 0x2a, 0x2a, 0xc8, 0xed, 0xd5, 0xc9, 0x34, 0x69, + 0x55, 0x53, 0x2f, 0x2c, 0xab, 0xd0, 0x64, 0x1f, 0xaf, 0x1e, 0x9b, 0x6f, + 0xf7, 0xd0, 0xf7, 0x46, 0x79, 0xe5, 0x89, 0x6a, 0x66, 0x1c, 0xf4, 0x8a, + 0xc8, 0x54, 0x0d, 0x86, 0x48, 0x23, 0x07, 0xdf, 0xae, 0x80, 0xb4, 0x75, + 0x4b, 0xce, 0xed, 0x8a, 0xfa, 0xc9, 0x8b, 0xb6, 0x5a, 0x34, 0xce, 0x54, + 0x2f, 0x6d, 0xb5, 0x30, 0x64, 0xab, 0xb7, 0x24, 0x40, 0x78, 0x8c, 0x93, + 0x34, 0x9b, 0x0f, 0xa7, 0xae, 0x73, 0xfa, 0xea, 0x0a, 0x68, 0x96, 0x48, + 0x92, 0x44, 0x99, 0x54, 0x3f, 0xfc, 0x42, 0xc7, 0x04, 0x2e, 0x40, 0xdb, + 0xdb, 0x5f, 0x60, 0xad, 0x6a, 0x39, 0xe4, 0xf9, 0x44, 0x0f, 0x02, 0xc5, + 0xcc, 0x18, 0xaf, 0x28, 0xf3, 0x13, 0xe6, 0x03, 0xbf, 0x7d, 0x40, 0x8f, + 0xb1, 0x4a, 0xa6, 0x65, 0x54, 0x81, 0x23, 0x89, 0x37, 0x77, 0xc7, 0x99, + 0xbd, 0x4e, 0xbe, 0x32, 0x40, 0x0c, 0x8c, 0xbc, 0xc5, 0x7e, 0xac, 0x0e, + 0xa7, 0x3d, 0xc9, 0xed, 0xa1, 0x67, 0x50, 0x70, 0xb1, 0x33, 0x3c, 0x60, + 0x82, 0x09, 0xed, 0xae, 0xe2, 0x6c, 0x4e, 0x59, 0xc0, 0x0f, 0xb6, 0x0f, + 0x6c, 0xfa, 0xe8, 0x4b, 0x25, 0x74, 0x75, 0x91, 0x11, 0x5b, 0x9d, 0xd7, + 0x0c, 0xac, 0xdd, 0x7d, 0xb1, 0xa8, 0xf3, 0x5f, 0x5d, 0x70, 0x5a, 0x58, + 0x55, 0xe5, 0xab, 0x76, 0x21, 0x63, 0x5d, 0xce, 0x74, 0x3d, 0x65, 0x4b, + 0x53, 0xd5, 0xf8, 0xce, 0xa6, 0x47, 0xe5, 0xd8, 0x83, 0xb6, 0x7d, 0xf5, + 0xf7, 0x86, 0xae, 0x95, 0x14, 0xd7, 0x46, 0x9d, 0x27, 0x6a, 0x4a, 0xb7, + 0x23, 0xe5, 0xe4, 0x0e, 0x31, 0xcd, 0x9d, 0xc6, 0x71, 0xb1, 0x3a, 0x10, + 0x33, 0xe7, 0x8c, 0x29, 0x7b, 0x2f, 0x7c, 0x39, 0xc0, 0x4c, 0x1a, 0xdb, + 0xc4, 0x86, 0xe5, 0x4d, 0x70, 0x73, 0x3a, 0xac, 0x90, 0x8d, 0xfc, 0x3e, + 0xdb, 0x83, 0xd0, 0xab, 0x63, 0xf4, 0xd2, 0xa4, 0x8e, 0x6a, 0xaf, 0x88, + 0x57, 0x08, 0x3a, 0xcb, 0x55, 0x2b, 0x73, 0x12, 0x37, 0xc8, 0x03, 0x1a, + 0xe2, 0x5b, 0xa5, 0x55, 0x35, 0x5d, 0x75, 0xc3, 0x15, 0x14, 0xb7, 0x29, + 0x4f, 0x37, 0x82, 0xbb, 0x01, 0x9d, 0xd8, 0xfa, 0x0d, 0xfb, 0x63, 0x5f, + 0x78, 0x3f, 0x88, 0x3e, 0x43, 0x88, 0x23, 0xe2, 0x23, 0x49, 0x1d, 0x5c, + 0xa0, 0xb1, 0x71, 0x2f, 0x46, 0xe6, 0x03, 0x39, 0x03, 0xa1, 0xdb, 0x3a, + 0x46, 0x59, 0x5b, 0x38, 0xd9, 0x72, 0xca, 0x6f, 0x93, 0x42, 0xac, 0x92, + 0xba, 0xcd, 0x65, 0x9e, 0xd6, 0x64, 0x91, 0x59, 0xa0, 0x1e, 0x33, 0x74, + 0xcf, 0x72, 0x3d, 0xfa, 0x6b, 0x2c, 0xb9, 0x55, 0x86, 0xa8, 0xf1, 0xa2, + 0x8d, 0xa3, 0x47, 0xc3, 0x60, 0x9c, 0x63, 0x3d, 0x75, 0xa9, 0xf1, 0x6f, + 0x19, 0xd9, 0xea, 0xed, 0x50, 0xd4, 0xd9, 0x96, 0xad, 0x6b, 0x6a, 0x0e, + 0x25, 0x8e, 0xa1, 0xb9, 0xd6, 0x9f, 0xae, 0x79, 0x4e, 0x37, 0x27, 0xb1, + 0xd6, 0x43, 0x7f, 0xa8, 0xa5, 0x15, 0x8a, 0xa3, 0x69, 0x79, 0xb0, 0xd8, + 0x1b, 0x03, 0xdb, 0x3f, 0x7f, 0x5d, 0x2a, 0x9d, 0xee, 0x62, 0xb6, 0x96, + 0xba, 0xbb, 0x6b, 0x52, 0xaa, 0x2b, 0xc7, 0x24, 0x53, 0x90, 0x09, 0x46, + 0xe8, 0x41, 0x00, 0x86, 0xcf, 0x7c, 0xe7, 0x57, 0x7a, 0x4e, 0x1f, 0xb9, + 0x57, 0xf0, 0x4d, 0x24, 0x56, 0xc0, 0x90, 0xab, 0xb2, 0xb4, 0xb0, 0xf4, + 0x69, 0x64, 0xc9, 0xc3, 0x13, 0xfd, 0x5b, 0x74, 0xf4, 0x1a, 0x4b, 0xc4, + 0x75, 0x90, 0x49, 0x6e, 0xb7, 0x45, 0xf2, 0x75, 0x91, 0x5c, 0x69, 0xd7, + 0x13, 0x89, 0x36, 0x55, 0x42, 0xbe, 0x51, 0xef, 0xb6, 0x0f, 0xd8, 0x8d, + 0x1f, 0x65, 0xe2, 0x2a, 0xd9, 0x6a, 0x22, 0xad, 0x7a, 0xd6, 0x2b, 0x00, + 0x08, 0xc8, 0x48, 0x20, 0xa0, 0xec, 0x06, 0xda, 0xe6, 0xad, 0xc9, 0xbb, + 0x42, 0xd2, 0x57, 0xc8, 0xa9, 0xad, 0x97, 0x84, 0xbb, 0xc1, 0x6e, 0xf9, + 0x59, 0x3e, 0x6a, 0xa1, 0x7f, 0x92, 0x24, 0x1c, 0xbc, 0xde, 0xfa, 0x60, + 0x9c, 0x15, 0xc6, 0xd4, 0xb5, 0x22, 0xba, 0x8e, 0x23, 0x0c, 0xd1, 0xe5, + 0x87, 0xcb, 0x4c, 0x39, 0x87, 0xb6, 0x36, 0xdb, 0x45, 0x7c, 0x53, 0xb8, + 0x51, 0x56, 0xd3, 0x43, 0x74, 0xb7, 0xd5, 0xab, 0xba, 0x1e, 0x5e, 0x50, + 0x71, 0x2a, 0x12, 0xa3, 0xbf, 0xa6, 0x47, 0xe3, 0xf7, 0xd4, 0xfc, 0x01, + 0xf1, 0x17, 0xf8, 0x75, 0x9a, 0x9e, 0xdf, 0x7a, 0x54, 0x92, 0x30, 0x4b, + 0x19, 0x17, 0xeb, 0x52, 0x77, 0xdf, 0xd7, 0x3a, 0x67, 0xd5, 0x59, 0x36, + 0xc7, 0xf4, 0x0b, 0xc7, 0x75, 0x33, 0x7f, 0xe8, 0x1b, 0x7c, 0x0b, 0x48, + 0xb6, 0xea, 0x88, 0x1b, 0x9e, 0xb6, 0x34, 0x3b, 0x9c, 0x82, 0x01, 0xc7, + 0xf7, 0xfb, 0x8d, 0x67, 0x96, 0x88, 0x8b, 0xba, 0x21, 0x84, 0x4a, 0x59, + 0xb1, 0x82, 0x76, 0x24, 0xed, 0xad, 0x42, 0xb6, 0xb6, 0xd3, 0xc5, 0x6d, + 0x55, 0x47, 0x14, 0xae, 0x6a, 0x6b, 0x26, 0x39, 0x2a, 0x0b, 0x10, 0xa3, + 0xa0, 0xfc, 0x0c, 0x0d, 0x41, 0x27, 0x0a, 0xd3, 0x5a, 0x28, 0x8d, 0x1d, + 0x24, 0x86, 0x3a, 0x92, 0xb9, 0xf1, 0x25, 0x05, 0x5b, 0x20, 0x74, 0xdf, + 0xa0, 0xed, 0xa4, 0xe4, 0xd5, 0x42, 0x0d, 0x2f, 0x61, 0x49, 0xf0, 0x33, + 0x36, 0xeb, 0x3a, 0xdb, 0x95, 0xad, 0x51, 0x0a, 0x0a, 0xe9, 0x11, 0x01, + 0xf1, 0x10, 0x18, 0xf3, 0x8d, 0xf6, 0x18, 0xc8, 0x27, 0xd7, 0x54, 0xcb, + 0x5d, 0xee, 0xe5, 0x1f, 0x15, 0xa8, 0x48, 0x29, 0x62, 0x11, 0x31, 0x59, + 0x84, 0x3e, 0x50, 0x18, 0x67, 0x24, 0x2f, 0xa6, 0xd8, 0xeb, 0xdf, 0x42, + 0x53, 0xf1, 0x15, 0x42, 0xdc, 0xe9, 0x6d, 0xd7, 0x98, 0xde, 0xa2, 0x88, + 0xcb, 0xe1, 0x1e, 0x71, 0xba, 0x12, 0x71, 0xb1, 0xd1, 0x9c, 0x55, 0xc2, + 0x15, 0x10, 0xc5, 0x51, 0x78, 0x86, 0xa1, 0x63, 0x59, 0x6a, 0x3c, 0x2a, + 0x68, 0xc3, 0x79, 0xe4, 0x52, 0x7a, 0xff, 0x00, 0x6f, 0xd3, 0x4f, 0x96, + 0x6d, 0xd2, 0xda, 0xd5, 0x58, 0x26, 0xa4, 0xb7, 0x1a, 0x99, 0xa9, 0x4d, + 0xb1, 0xdc, 0xa8, 0x68, 0xc7, 0x20, 0x04, 0x0c, 0x8d, 0x86, 0xdf, 0x8d, + 0x53, 0xf8, 0xcb, 0xe1, 0x95, 0x0d, 0xe0, 0x1a, 0xd9, 0xaa, 0x62, 0x82, + 0x45, 0x89, 0x9e, 0x01, 0xcb, 0xcc, 0xe1, 0x80, 0x52, 0x03, 0xb0, 0xce, + 0x17, 0xd7, 0xb0, 0x3a, 0xb2, 0xf0, 0x35, 0xb1, 0xae, 0xb7, 0x8a, 0xfa, + 0x5a, 0xfb, 0x83, 0x47, 0x4f, 0xcc, 0x7e, 0x5d, 0x42, 0x85, 0x20, 0xe7, + 0xfe, 0x63, 0xbf, 0xe3, 0x56, 0x1a, 0xab, 0x5d, 0x65, 0xbe, 0xad, 0x05, + 0x6d, 0x23, 0x4f, 0x40, 0xaa, 0x73, 0x32, 0xb0, 0xe4, 0x60, 0x08, 0xc0, + 0x65, 0x1d, 0x88, 0xdf, 0x1e, 0xda, 0xdd, 0x2c, 0x92, 0x8b, 0xb8, 0xfa, + 0x1f, 0x14, 0xe2, 0xdb, 0x64, 0x1f, 0x02, 0x6d, 0xf5, 0x94, 0xb6, 0x39, + 0xe2, 0x92, 0x9a, 0x96, 0x8a, 0xa6, 0x96, 0x51, 0x0b, 0x2c, 0x1b, 0xc1, + 0x56, 0xa1, 0x47, 0xf3, 0x8b, 0xff, 0x00, 0x5b, 0x13, 0x91, 0xb6, 0x02, + 0xf4, 0xc1, 0xd6, 0x93, 0x1f, 0x2c, 0xf3, 0x2c, 0x09, 0x51, 0x0a, 0xc9, + 0x0e, 0x0c, 0x91, 0x23, 0x73, 0x11, 0x9d, 0xc1, 0x3d, 0x3a, 0xe9, 0x2d, + 0x3a, 0x45, 0x05, 0xbe, 0x3a, 0xaa, 0x78, 0x21, 0x8e, 0x49, 0x10, 0x78, + 0x66, 0x30, 0x04, 0x7e, 0x1e, 0x41, 0xd8, 0x7f, 0x49, 0xff, 0x00, 0x4d, + 0x35, 0x88, 0x40, 0x8c, 0x95, 0x2a, 0x86, 0x42, 0x00, 0x0e, 0xfc, 0xb8, + 0x61, 0x8e, 0x85, 0xbd, 0x86, 0xff, 0x00, 0xae, 0xab, 0x16, 0x69, 0x4a, + 0x5e, 0x46, 0xb5, 0x2e, 0x06, 0x53, 0xc9, 0xe1, 0xc6, 0x0b, 0xc6, 0xce, + 0x73, 0x8e, 0x55, 0x19, 0x24, 0x74, 0xce, 0xab, 0x75, 0xfc, 0x15, 0x6e, + 0xa9, 0xa9, 0x96, 0x7a, 0x87, 0x91, 0xfc, 0x46, 0x27, 0x94, 0x01, 0xdf, + 0xaf, 0x6d, 0x58, 0x62, 0x95, 0x5e, 0x36, 0xa8, 0xf1, 0xd5, 0xd4, 0x8f, + 0x21, 0x1b, 0x00, 0x3e, 0xfa, 0x1f, 0x9a, 0x69, 0xf2, 0x2a, 0x13, 0x95, + 0x41, 0xdc, 0xab, 0xe4, 0x1f, 0x6e, 0x9f, 0xbf, 0xb6, 0xb4, 0x67, 0xc3, + 0x8b, 0x2a, 0x4a, 0x6a, 0xca, 0xc8, 0x93, 0x5c, 0x95, 0x39, 0xf8, 0x3e, + 0x3a, 0x4b, 0x6d, 0xc9, 0xa0, 0x91, 0x9e, 0xa4, 0xd3, 0xca, 0xb6, 0xf5, + 0x6d, 0x96, 0x1f, 0x29, 0x23, 0x1f, 0xf3, 0x6d, 0x9c, 0xeb, 0xc7, 0xdc, + 0x43, 0x62, 0xab, 0xe7, 0xa8, 0x84, 0x41, 0x21, 0x97, 0x99, 0x94, 0xaf, + 0x2e, 0xfc, 0xc3, 0xb7, 0xed, 0xaf, 0x77, 0xca, 0x95, 0x02, 0xa9, 0xa7, + 0x82, 0x68, 0xc4, 0x0c, 0x9e, 0x60, 0xc3, 0x3e, 0x60, 0x46, 0xff, 0x00, + 0xa6, 0x75, 0x87, 0xfc, 0x49, 0xe3, 0xa8, 0x24, 0xbb, 0x56, 0xc7, 0x45, + 0x47, 0x4d, 0x1c, 0x48, 0x8e, 0xa2, 0x52, 0x3c, 0xf2, 0x49, 0xd3, 0x9b, + 0x1e, 0xdd, 0x89, 0xd6, 0x6d, 0x54, 0xfe, 0x24, 0x9c, 0x7f, 0xe0, 0xcd, + 0x9f, 0x6a, 0x4a, 0xcf, 0x2f, 0x5b, 0xae, 0x97, 0x3a, 0x54, 0xf9, 0x67, + 0x93, 0x23, 0x3c, 0xbc, 0x8e, 0x33, 0xbf, 0xa6, 0xb8, 0xa5, 0xa5, 0x34, + 0xb3, 0xbc, 0x8a, 0x9f, 0xcd, 0x99, 0xc8, 0x63, 0x9f, 0xa0, 0x13, 0xd7, + 0xfe, 0x9a, 0xb8, 0x52, 0x59, 0xd2, 0xb6, 0xbc, 0xd7, 0x54, 0xc2, 0x4c, + 0x4b, 0xbc, 0xac, 0xc7, 0xeb, 0x7e, 0xd8, 0x1f, 0xae, 0x84, 0xe2, 0x16, + 0x4a, 0x6a, 0xb4, 0x0b, 0x4c, 0x73, 0xca, 0x0f, 0x9b, 0xa3, 0x7b, 0xea, + 0xe1, 0x97, 0x7c, 0xb6, 0xc4, 0x5c, 0x64, 0x7c, 0x9e, 0xd6, 0x28, 0xea, + 0xed, 0x95, 0x14, 0x22, 0x49, 0x69, 0x84, 0x45, 0xdc, 0x63, 0x3c, 0xc5, + 0x4f, 0x31, 0x20, 0x7e, 0x40, 0xfc, 0xeb, 0xef, 0x1b, 0x5e, 0x45, 0xf7, + 0x88, 0xab, 0x6f, 0x53, 0x40, 0xb4, 0xf3, 0xd5, 0xc6, 0xbc, 0xc0, 0x28, + 0x5e, 0x76, 0x00, 0x02, 0xc5, 0x47, 0x4c, 0xe0, 0x6d, 0xed, 0xab, 0x67, + 0xc2, 0xeb, 0xa4, 0x94, 0xa6, 0xe7, 0xc4, 0x35, 0x53, 0x28, 0x92, 0x9a, + 0x94, 0xd3, 0xd3, 0xd3, 0x2c, 0x63, 0x05, 0x1b, 0x63, 0xe6, 0x3b, 0x2f, + 0xb7, 0xb9, 0xce, 0xb3, 0xc7, 0xb5, 0xde, 0xe4, 0xab, 0x68, 0x24, 0xa8, + 0xf1, 0xa9, 0x0c, 0xd9, 0x4e, 0x67, 0x1f, 0x56, 0xfe, 0xbe, 0x99, 0x23, + 0x4e, 0x8c, 0xd3, 0x93, 0x8b, 0xf4, 0x35, 0x31, 0xaf, 0xc9, 0x5d, 0x29, + 0x78, 0x3f, 0xe6, 0x40, 0xa4, 0x92, 0x8a, 0x49, 0x15, 0x32, 0x79, 0x0b, + 0xc6, 0xcc, 0x33, 0x90, 0x33, 0xcc, 0x3f, 0xb6, 0xab, 0xd5, 0xd0, 0x3c, + 0x10, 0x09, 0x26, 0x60, 0x99, 0x19, 0x03, 0xae, 0xfa, 0x79, 0x6a, 0x92, + 0xa2, 0xd7, 0x72, 0x6a, 0x1a, 0xc5, 0x3c, 0x92, 0x31, 0xe5, 0xcf, 0x4c, + 0xeb, 0xe7, 0x19, 0xa0, 0xae, 0x14, 0xb4, 0xf4, 0xa8, 0x8a, 0xc6, 0x4e, + 0x56, 0x23, 0xaf, 0xa6, 0x95, 0x1c, 0x8f, 0xe4, 0x49, 0xf4, 0x0c, 0xa6, + 0x55, 0x69, 0x26, 0x67, 0x5e, 0x63, 0xf4, 0xab, 0x6d, 0xf6, 0xd3, 0xfa, + 0x51, 0x1a, 0x2f, 0x89, 0x50, 0x39, 0xc3, 0x79, 0x95, 0x71, 0xd4, 0x1d, + 0x7e, 0xaa, 0xe1, 0x69, 0x6d, 0xf4, 0x80, 0xcb, 0x22, 0x78, 0xc1, 0xfc, + 0xb8, 0x18, 0xcf, 0x5d, 0x08, 0xbe, 0x24, 0x8e, 0x90, 0xbc, 0x6c, 0xb2, + 0x0d, 0x97, 0x1d, 0x3f, 0x5d, 0x33, 0xe4, 0x53, 0x57, 0x12, 0xdf, 0x28, + 0xb4, 0xf0, 0xf4, 0x94, 0x13, 0x19, 0x3c, 0x68, 0xca, 0x96, 0x25, 0x51, + 0x14, 0xec, 0x17, 0x07, 0xaf, 0xae, 0x74, 0x75, 0x6d, 0x03, 0x57, 0x45, + 0x5b, 0x54, 0x58, 0xe2, 0xa6, 0x89, 0x5c, 0x05, 0x5e, 0x9c, 0x88, 0x39, + 0xb3, 0xe9, 0xb9, 0x1a, 0x4b, 0x65, 0x49, 0x61, 0xaa, 0xa3, 0x6e, 0x61, + 0xcf, 0x14, 0xca, 0x18, 0x0e, 0x99, 0x27, 0xd7, 0x57, 0x35, 0xc4, 0x13, + 0x5d, 0x28, 0xe7, 0x40, 0x3c, 0x0a, 0x79, 0xd4, 0x64, 0xe3, 0x98, 0x92, + 0xb8, 0xfb, 0x75, 0x3a, 0x76, 0x9f, 0xa6, 0x6d, 0xd1, 0xcf, 0x72, 0x6b, + 0xf4, 0x53, 0x78, 0x96, 0x70, 0xb6, 0x1a, 0x48, 0x51, 0xb9, 0x52, 0xa9, + 0xe3, 0x9c, 0xc6, 0x06, 0xd9, 0x20, 0xab, 0x7e, 0xe3, 0x4c, 0xa8, 0xf0, + 0xb5, 0x16, 0xe7, 0xa6, 0x01, 0x3c, 0x02, 0x32, 0xec, 0x70, 0x3a, 0x64, + 0x8f, 0xdb, 0x4b, 0x67, 0x0c, 0x28, 0x78, 0x6e, 0x29, 0xd5, 0xe4, 0x09, + 0x3d, 0x44, 0xc5, 0x33, 0xb2, 0xa0, 0x61, 0x8c, 0x1f, 0xc6, 0x3b, 0x68, + 0xc9, 0xe6, 0x49, 0x29, 0x93, 0xe5, 0x61, 0x68, 0x64, 0x9e, 0x62, 0xdc, + 0x85, 0x89, 0xc6, 0x4e, 0x4e, 0xfd, 0xc6, 0x35, 0xa0, 0xd7, 0x0e, 0xc1, + 0x69, 0x61, 0x96, 0xe5, 0x7b, 0x86, 0x9a, 0x47, 0x1f, 0x2e, 0xb2, 0x12, + 0xa4, 0x0d, 0x94, 0x13, 0x9d, 0xb4, 0x5f, 0x11, 0xd2, 0x53, 0xc5, 0x7d, + 0x16, 0xda, 0x66, 0x73, 0x1f, 0x22, 0xb4, 0x92, 0x36, 0xf8, 0xdb, 0x6f, + 0xfc, 0x6a, 0x5b, 0x4d, 0x5a, 0xd0, 0x71, 0x07, 0x8a, 0xcd, 0x94, 0x73, + 0xe4, 0x21, 0x76, 0x39, 0xdc, 0x0c, 0x6a, 0x6b, 0xd2, 0x54, 0x41, 0x5a, + 0x2a, 0x4c, 0x7c, 0xa6, 0xb0, 0x99, 0x39, 0xc3, 0x67, 0x94, 0xff, 0x00, + 0xe3, 0x3b, 0x68, 0x46, 0x24, 0x2c, 0x8a, 0x8e, 0x59, 0x88, 0x39, 0x64, + 0xe4, 0x63, 0xc8, 0xca, 0x7e, 0x9c, 0x76, 0xd7, 0x10, 0x3a, 0xa8, 0x9a, + 0x22, 0x87, 0x2c, 0xc0, 0x47, 0x83, 0xb0, 0xc6, 0x76, 0xf7, 0x1d, 0x74, + 0x6b, 0xf8, 0x2d, 0x0a, 0xd1, 0xcb, 0x2a, 0x81, 0x36, 0x4a, 0xc8, 0xc3, + 0x02, 0x3f, 0x71, 0xe8, 0x4e, 0x82, 0xf9, 0x79, 0x10, 0xc9, 0x07, 0x3a, + 0x48, 0xc8, 0xde, 0x46, 0x56, 0xce, 0xdd, 0xb5, 0x44, 0x44, 0x82, 0x28, + 0xd5, 0x9d, 0x64, 0x8f, 0xcf, 0x9c, 0x82, 0x3a, 0x69, 0x6d, 0x73, 0xc9, + 0x33, 0x98, 0xd5, 0xb0, 0xca, 0x4e, 0xfe, 0x9b, 0xed, 0xfb, 0x68, 0xdb, + 0xa8, 0x9e, 0x9c, 0xe2, 0x56, 0x1c, 0xdd, 0x48, 0xce, 0x96, 0x54, 0x4a, + 0x42, 0xc4, 0x85, 0x0f, 0x34, 0xad, 0x93, 0x9d, 0x86, 0x35, 0x0b, 0x25, + 0x96, 0x70, 0x5d, 0x28, 0x9a, 0x97, 0xc3, 0x66, 0x65, 0x65, 0x98, 0x92, + 0x72, 0x3e, 0xda, 0x02, 0xa6, 0x08, 0xed, 0xf5, 0xb2, 0x4b, 0x5c, 0xa8, + 0xc0, 0xf9, 0x57, 0x0b, 0x80, 0x17, 0xfe, 0x5f, 0x4d, 0x18, 0x55, 0x16, + 0x55, 0x45, 0x05, 0x50, 0xae, 0x0e, 0x0e, 0xea, 0x73, 0xd7, 0x45, 0x9b, + 0x19, 0xbb, 0x55, 0xa4, 0xd3, 0xcb, 0x27, 0xf0, 0xda, 0x75, 0xe6, 0xcb, + 0xff, 0x00, 0xee, 0x11, 0xd8, 0x69, 0x51, 0x9b, 0x94, 0xdc, 0x59, 0xc8, + 0xc9, 0xfe, 0xa3, 0x62, 0xf1, 0x25, 0x7d, 0x7d, 0x4c, 0x13, 0xd1, 0xc9, + 0x57, 0x94, 0x01, 0x15, 0x49, 0xe7, 0x3c, 0xaa, 0x31, 0x81, 0xd3, 0x6d, + 0xb1, 0xab, 0xbd, 0x8a, 0xd9, 0x67, 0xb8, 0x45, 0x14, 0x0b, 0x77, 0x36, + 0xea, 0xc7, 0x20, 0x3d, 0x25, 0x64, 0x4c, 0xa4, 0xb9, 0xea, 0x73, 0xd3, + 0x1a, 0xad, 0xcb, 0x73, 0x92, 0x9d, 0xdc, 0xdb, 0xff, 0x00, 0xdd, 0x83, + 0x80, 0x14, 0xa8, 0xf3, 0x22, 0x0e, 0x8a, 0x0f, 0x6e, 0xbf, 0x9d, 0x7e, + 0xa7, 0x79, 0x2b, 0x2b, 0x60, 0x85, 0xe6, 0xe7, 0xfe, 0x50, 0x2c, 0xcc, + 0x77, 0x2e, 0xcc, 0xa3, 0x7f, 0x5f, 0xdb, 0xa6, 0xb3, 0xe4, 0xed, 0xc8, + 0x43, 0x34, 0x6e, 0x20, 0xe0, 0x9b, 0xcd, 0x92, 0x9a, 0x8e, 0x68, 0x0d, + 0x3d, 0x5c, 0x53, 0xb3, 0x2a, 0x3a, 0x36, 0xcb, 0x82, 0x37, 0x39, 0xe8, + 0x7d, 0xbd, 0x06, 0x97, 0xd1, 0x59, 0xb8, 0x21, 0xaa, 0xa3, 0xfe, 0x2d, + 0x78, 0xaa, 0x17, 0x29, 0x58, 0x44, 0xf2, 0xd3, 0xd3, 0x8f, 0x06, 0x39, + 0x0b, 0x64, 0x9c, 0x9e, 0xa0, 0x0f, 0x4d, 0xbb, 0xe7, 0x7d, 0x36, 0xe3, + 0x98, 0x6d, 0x16, 0x1e, 0x0f, 0xb4, 0xc3, 0x6e, 0xbc, 0x9a, 0x9b, 0x88, + 0xcb, 0xd4, 0x88, 0x2b, 0x4c, 0x91, 0xc6, 0x40, 0xc3, 0x02, 0x9b, 0x80, + 0x49, 0x23, 0x70, 0x7d, 0x46, 0xfa, 0xa5, 0xd0, 0xcb, 0x35, 0x1f, 0x0a, + 0xd5, 0xf1, 0x19, 0xa6, 0xa5, 0x25, 0x26, 0x14, 0x50, 0x16, 0x07, 0x31, + 0xc8, 0xe0, 0xb7, 0x30, 0x19, 0xdc, 0x80, 0xac, 0x37, 0xdb, 0x71, 0xa1, + 0x4e, 0xda, 0x41, 0x17, 0x9a, 0x9b, 0x1f, 0x10, 0xf0, 0xf5, 0x75, 0x5d, + 0x3b, 0xdc, 0x29, 0x65, 0xa2, 0x58, 0x0c, 0xef, 0x24, 0xd3, 0xa9, 0x32, + 0x8c, 0x80, 0x15, 0x41, 0xdf, 0x9b, 0x71, 0xb0, 0xed, 0x9d, 0x01, 0x0d, + 0x86, 0xdd, 0x7c, 0x09, 0x4f, 0x6f, 0xba, 0xc1, 0x43, 0x79, 0x6f, 0x39, + 0xa7, 0xa8, 0xa8, 0x01, 0x1f, 0x62, 0x72, 0x18, 0xec, 0x35, 0x8e, 0x54, + 0xdc, 0x6a, 0x65, 0xac, 0x53, 0x56, 0xcf, 0x50, 0x39, 0xc1, 0x2a, 0x64, + 0x6c, 0xbf, 0xa0, 0xce, 0x75, 0xa0, 0xf0, 0xa5, 0xc7, 0x87, 0x63, 0xe2, + 0x2a, 0x1b, 0x3d, 0xda, 0x2a, 0xc8, 0x9a, 0x66, 0x22, 0xa2, 0xa1, 0x9f, + 0x9c, 0xc5, 0xe5, 0x25, 0x79, 0x32, 0x3e, 0x9c, 0x80, 0x33, 0xef, 0xa3, + 0x7a, 0x7e, 0x77, 0x5f, 0xa0, 0x06, 0x75, 0xf3, 0x9f, 0xe1, 0xe2, 0x9d, + 0x92, 0x9e, 0x27, 0xa3, 0x8b, 0x96, 0x49, 0xd4, 0x61, 0x64, 0x3d, 0x4e, + 0x4f, 0xf5, 0x1f, 0x4f, 0xb6, 0xa1, 0xa8, 0xe1, 0x4b, 0xe9, 0x34, 0x72, + 0x4d, 0x4b, 0x3c, 0x26, 0xa9, 0x99, 0x51, 0x66, 0x1c, 0xac, 0x40, 0xc7, + 0x9b, 0x97, 0xa8, 0x19, 0x23, 0x7f, 0xbe, 0x99, 0xf0, 0x2f, 0x0f, 0x1e, + 0x26, 0xe3, 0x43, 0x40, 0x2a, 0x9e, 0x9e, 0x3a, 0x58, 0x9e, 0xa3, 0xc6, + 0x76, 0x0d, 0xba, 0x83, 0xca, 0x77, 0xdb, 0x39, 0xc7, 0x5e, 0xc4, 0xe9, + 0x25, 0xff, 0x00, 0x8c, 0x38, 0x8a, 0xe5, 0x75, 0x79, 0x2b, 0xef, 0x73, + 0xd4, 0x54, 0xc1, 0x21, 0x11, 0xb2, 0xbe, 0x02, 0x80, 0x71, 0xb6, 0x3f, + 0xcb, 0x58, 0x96, 0x18, 0xf3, 0x40, 0x51, 0xa1, 0xda, 0xb8, 0x66, 0xdd, + 0xc3, 0xd6, 0x88, 0xea, 0x6b, 0x0b, 0xc9, 0x73, 0x38, 0x6e, 0x68, 0xd8, + 0xe2, 0x36, 0xc6, 0xd8, 0x00, 0x8d, 0xf7, 0xd0, 0x95, 0x97, 0x5a, 0xfa, + 0xee, 0x78, 0xc5, 0xda, 0x49, 0x5d, 0x5b, 0x1e, 0x15, 0x46, 0xdc, 0xd8, + 0xf4, 0x3a, 0x93, 0xe1, 0x2f, 0xc4, 0x1a, 0x48, 0xee, 0xf4, 0xf4, 0x7c, + 0x5d, 0x04, 0x55, 0x49, 0x2b, 0x11, 0x15, 0x7c, 0x99, 0x2f, 0x19, 0x6e, + 0xcf, 0x9c, 0xf3, 0x2f, 0xbf, 0x6d, 0x5d, 0xea, 0xbe, 0x1e, 0x56, 0x9b, + 0xb2, 0x5f, 0x38, 0x76, 0xa2, 0x95, 0xff, 0x00, 0xdf, 0xa4, 0x22, 0x19, + 0x10, 0x05, 0xe5, 0x0c, 0x70, 0x41, 0x07, 0x07, 0xa7, 0x4c, 0x74, 0x3e, + 0xda, 0x46, 0x5d, 0x23, 0x6e, 0xd1, 0x7f, 0x13, 0x7d, 0x18, 0xe2, 0xdb, + 0xa7, 0xaa, 0xe2, 0x78, 0x3c, 0x59, 0x4c, 0x30, 0x49, 0x2f, 0x34, 0xaa, + 0xbe, 0xa3, 0x39, 0x1f, 0xae, 0xae, 0x15, 0x74, 0xf4, 0x44, 0x81, 0x2b, + 0xca, 0xd0, 0xe0, 0x8e, 0x5e, 0x6e, 0xa5, 0xba, 0x9f, 0xbe, 0xb4, 0xb4, + 0xf8, 0x71, 0x47, 0x53, 0x09, 0x17, 0x49, 0x07, 0xce, 0xb3, 0x16, 0x9a, + 0xaa, 0x12, 0x54, 0x6e, 0x09, 0x01, 0x50, 0x92, 0x01, 0x1b, 0x7d, 0xc6, + 0x75, 0x8c, 0xdf, 0x66, 0xfe, 0x1f, 0x7a, 0xaa, 0xb3, 0xf8, 0xce, 0xe6, + 0x09, 0x0a, 0xf3, 0xba, 0x72, 0xe4, 0x82, 0x46, 0xc3, 0x27, 0x6d, 0x6b, + 0xc3, 0x8a, 0x4b, 0xec, 0xca, 0x78, 0xe8, 0xd9, 0xf8, 0x53, 0x86, 0xe8, + 0xff, 0x00, 0x88, 0x53, 0xf1, 0x03, 0xd7, 0xc8, 0xa5, 0x11, 0x79, 0x60, + 0x31, 0x82, 0x55, 0xb9, 0x40, 0x2c, 0x09, 0x27, 0xfb, 0x6a, 0xd9, 0x56, + 0x22, 0x92, 0x05, 0x85, 0x2b, 0x0a, 0xcd, 0xe5, 0x7f, 0x13, 0x3e, 0x63, + 0x83, 0xf4, 0x91, 0xd3, 0xee, 0x74, 0x8e, 0x9a, 0xa2, 0xa6, 0x9e, 0xc5, + 0x48, 0xf4, 0xc3, 0xc7, 0x0d, 0x4e, 0xbc, 0xf2, 0x0c, 0x01, 0x18, 0x00, + 0x0e, 0x53, 0x9e, 0x9d, 0xc6, 0xdd, 0x71, 0xa0, 0x66, 0xad, 0x09, 0x4d, + 0x05, 0x5d, 0x12, 0x24, 0x22, 0x49, 0x3c, 0x09, 0xd2, 0x38, 0x4f, 0x21, + 0xc6, 0xfd, 0xce, 0x4f, 0x4f, 0x6d, 0x56, 0x4c, 0x8a, 0x32, 0x69, 0x9b, + 0x1f, 0x6e, 0x8b, 0x4d, 0x3d, 0x42, 0xc1, 0x4d, 0x3c, 0x35, 0x46, 0x26, + 0x75, 0x5c, 0xa8, 0x24, 0x30, 0x39, 0xe8, 0xb8, 0x1f, 0xb6, 0xab, 0x17, + 0xbe, 0x20, 0x7b, 0x45, 0x4a, 0xf3, 0xd1, 0x54, 0x07, 0x48, 0x8b, 0x98, + 0xc9, 0x18, 0xf0, 0xc9, 0xdc, 0x92, 0x76, 0xfc, 0x13, 0xaa, 0x97, 0x12, + 0x71, 0x7c, 0x54, 0x97, 0xda, 0x85, 0x9a, 0xb5, 0x60, 0xa6, 0x8c, 0x73, + 0x49, 0x84, 0xc0, 0x5d, 0x8e, 0x10, 0x2f, 0xa9, 0xdb, 0x7f, 0x6d, 0x71, + 0x6a, 0xe2, 0x2a, 0xdb, 0xdf, 0x0c, 0xca, 0x05, 0xae, 0x25, 0x5d, 0xf0, + 0x6b, 0x1b, 0x06, 0x55, 0x3d, 0x0a, 0x9d, 0xb9, 0x57, 0x1d, 0x4f, 0xf7, + 0xd2, 0xe3, 0x39, 0x49, 0x5a, 0x66, 0x57, 0x94, 0xbc, 0xf0, 0xb7, 0x13, + 0x47, 0x74, 0x82, 0xa2, 0x6b, 0x64, 0x6f, 0xf2, 0x71, 0xc4, 0x64, 0xe5, + 0x09, 0x80, 0xa4, 0xe0, 0xf4, 0x27, 0x7e, 0xfd, 0x3a, 0xeb, 0xb3, 0x72, + 0xfe, 0x35, 0x04, 0x75, 0x14, 0x2b, 0x35, 0x25, 0x50, 0x3b, 0xcb, 0x2f, + 0x91, 0xa6, 0x0b, 0xb6, 0x15, 0x8f, 0x4c, 0xee, 0x7a, 0x74, 0xd2, 0x0f, + 0x87, 0x0f, 0x05, 0x3d, 0x9a, 0x68, 0x26, 0xa3, 0x99, 0xe5, 0xa7, 0x8d, + 0xc7, 0x89, 0x1b, 0x64, 0x54, 0x31, 0xe9, 0xe1, 0xa6, 0xc4, 0xf4, 0x03, + 0x27, 0x6d, 0x58, 0xe8, 0x6d, 0x51, 0xcd, 0x47, 0x47, 0x1d, 0x78, 0xf9, + 0xa9, 0xa5, 0x0d, 0x24, 0xe2, 0x70, 0x57, 0x95, 0x1b, 0x7f, 0x32, 0x13, + 0xb1, 0x04, 0x74, 0x1b, 0x6d, 0xab, 0x87, 0xc9, 0xe9, 0xd8, 0x71, 0x7b, + 0xe3, 0x64, 0x7c, 0x6f, 0x73, 0xbc, 0x43, 0xc0, 0xd5, 0x32, 0xc5, 0x32, + 0x41, 0x5b, 0x28, 0xe5, 0x89, 0x63, 0x42, 0x79, 0x54, 0x92, 0x33, 0x91, + 0xed, 0xaf, 0x3d, 0xd6, 0xda, 0x2b, 0x11, 0xd8, 0xcf, 0x32, 0x2a, 0x91, + 0x92, 0x73, 0xb8, 0xc9, 0xf4, 0xd7, 0xa2, 0xe8, 0xed, 0xa6, 0xe5, 0x43, + 0x72, 0xb6, 0x4d, 0x54, 0xbe, 0x0e, 0x4a, 0x53, 0xf8, 0x52, 0xf3, 0xaa, + 0x2f, 0x63, 0x8f, 0xf2, 0xdf, 0xa8, 0xd6, 0x5f, 0xf1, 0x13, 0x83, 0xef, + 0x5c, 0x3f, 0x6c, 0x8e, 0xe5, 0x03, 0x53, 0xdc, 0x8f, 0x89, 0xc8, 0xc8, + 0x33, 0x94, 0x63, 0xd0, 0x9c, 0xf5, 0xd0, 0x64, 0x59, 0x67, 0x97, 0x73, + 0xe9, 0x01, 0x97, 0x1b, 0x6e, 0xd1, 0x4b, 0xbc, 0xda, 0xd7, 0x87, 0xed, + 0x8b, 0x2c, 0xf2, 0xd3, 0xf3, 0xd4, 0x43, 0xce, 0xac, 0x47, 0x98, 0x03, + 0xd0, 0x6a, 0x99, 0x62, 0xb4, 0x52, 0xdd, 0xab, 0xe6, 0xae, 0xb8, 0xd6, + 0x47, 0x49, 0x6d, 0x80, 0x9f, 0x1a, 0x79, 0xb3, 0x86, 0x38, 0xd9, 0x54, + 0x0d, 0xd8, 0x9d, 0x69, 0x09, 0xf0, 0xe6, 0xf1, 0x74, 0x64, 0xbd, 0x71, + 0x75, 0xc5, 0x69, 0xa8, 0xe3, 0x52, 0x1d, 0x61, 0x1c, 0xe6, 0x35, 0x09, + 0x95, 0xce, 0xf8, 0xc1, 0xd8, 0x63, 0xae, 0xb3, 0x0b, 0xf0, 0x47, 0xbc, + 0x7c, 0x85, 0x28, 0x8d, 0xa9, 0xa9, 0xd8, 0x08, 0x80, 0x5f, 0x2f, 0xdf, + 0x5a, 0xa3, 0x92, 0x2f, 0xe8, 0x02, 0x8d, 0x1f, 0x62, 0x95, 0x22, 0xb7, + 0x4f, 0x0d, 0x37, 0x34, 0x71, 0x19, 0x0e, 0x41, 0x4e, 0x5f, 0x10, 0x03, + 0xe5, 0x38, 0xfb, 0x68, 0x27, 0x2b, 0x5f, 0x6b, 0x92, 0x02, 0xd9, 0x31, + 0x39, 0x6c, 0x7a, 0x64, 0x6c, 0x7f, 0xef, 0xd7, 0x5a, 0x65, 0xb6, 0x81, + 0x38, 0x9a, 0xd3, 0xf3, 0x30, 0x2c, 0x86, 0xb6, 0xdb, 0x96, 0xac, 0x61, + 0x1f, 0xf2, 0xcc, 0x1c, 0xbb, 0x60, 0x8c, 0xe0, 0xae, 0x0e, 0xd8, 0xdf, + 0x39, 0xed, 0xac, 0xf6, 0x4a, 0x58, 0xa8, 0xaf, 0x95, 0x34, 0xb2, 0x11, + 0x14, 0x55, 0x00, 0xf2, 0x73, 0x7a, 0xe7, 0xa7, 0xf7, 0xd3, 0x78, 0x9b, + 0xb4, 0x86, 0x45, 0x96, 0xbf, 0x83, 0x97, 0x2b, 0x6d, 0x65, 0xc1, 0x2d, + 0x97, 0xbb, 0x2d, 0x3d, 0xca, 0xaa, 0x1c, 0xad, 0x1b, 0xcb, 0x8f, 0x2a, + 0xf4, 0x2b, 0xfe, 0x7a, 0xb8, 0xfc, 0x45, 0xe1, 0x7b, 0x14, 0xfc, 0x49, + 0x4d, 0xc4, 0x36, 0xa8, 0xe2, 0x5f, 0x05, 0x0a, 0x49, 0x4f, 0x08, 0xc4, + 0x71, 0x48, 0x36, 0xc8, 0xf5, 0xef, 0xac, 0xd3, 0xe1, 0xbc, 0x17, 0x48, + 0x3e, 0x23, 0x5a, 0x45, 0xa5, 0x11, 0xaa, 0xfc, 0x7c, 0x44, 0x59, 0xb0, + 0xbd, 0x08, 0xc9, 0x3e, 0x98, 0xdf, 0x5e, 0x8d, 0xa0, 0xb1, 0xd2, 0xc5, + 0x05, 0x7c, 0x8f, 0xe0, 0xcb, 0xcf, 0x1c, 0xaf, 0x56, 0xd3, 0xb9, 0x52, + 0xd2, 0x16, 0x2c, 0x70, 0xbd, 0x87, 0x5d, 0x61, 0xd5, 0x62, 0x6a, 0x54, + 0x9f, 0x62, 0xe7, 0xc9, 0x91, 0x5f, 0xf8, 0x5b, 0x9f, 0xe1, 0xdd, 0x67, + 0x10, 0xc9, 0xce, 0xcd, 0x1d, 0x42, 0x45, 0x14, 0x7b, 0x80, 0xa3, 0xa1, + 0x63, 0xef, 0x9c, 0xe3, 0x1a, 0xca, 0xeb, 0xa5, 0x14, 0xf9, 0x96, 0x1d, + 0xa4, 0x3e, 0x54, 0x3e, 0x9e, 0xfa, 0xf4, 0xdf, 0xc4, 0x2b, 0xd5, 0x8e, + 0x4b, 0x6d, 0x07, 0x0f, 0xbd, 0x3d, 0x14, 0xb6, 0xf9, 0x62, 0xf1, 0x43, + 0x42, 0x85, 0x63, 0x84, 0x93, 0x85, 0xc0, 0x19, 0x24, 0xe1, 0xb5, 0xe7, + 0x2b, 0xe5, 0xa4, 0x43, 0x57, 0x5f, 0x2b, 0x11, 0x24, 0x14, 0x93, 0x18, + 0xd0, 0xaf, 0x4d, 0xf2, 0x41, 0x07, 0xec, 0x3a, 0x69, 0xda, 0x75, 0xb3, + 0xc4, 0x28, 0xb2, 0xb6, 0x6a, 0x6a, 0x14, 0xb1, 0x8a, 0x46, 0x0b, 0x19, + 0x04, 0x0c, 0xff, 0x00, 0x56, 0x7a, 0xeb, 0x40, 0x59, 0xa5, 0x7b, 0x24, + 0x95, 0x0f, 0xcc, 0xdc, 0xd4, 0x3e, 0x21, 0x23, 0x66, 0x2c, 0x48, 0xe6, + 0xfc, 0x6a, 0x91, 0x80, 0xf1, 0x24, 0x81, 0x64, 0xf0, 0xd9, 0x8b, 0x06, + 0x2b, 0x80, 0xd8, 0xeb, 0x8f, 0x5d, 0x5e, 0x29, 0xea, 0x05, 0x57, 0x0e, + 0xc9, 0x3b, 0x05, 0x52, 0x68, 0x9e, 0x9d, 0x49, 0x6e, 0xfc, 0xe1, 0x87, + 0xfd, 0xfb, 0x6b, 0xad, 0x86, 0x06, 0xfd, 0x23, 0x05, 0xb5, 0x54, 0xc9, + 0x43, 0x71, 0xb4, 0x37, 0xca, 0xfc, 0xc2, 0xc1, 0x40, 0xf3, 0x00, 0x4e, + 0xec, 0xae, 0x58, 0x30, 0x23, 0xed, 0xcc, 0x73, 0xed, 0xa5, 0xf4, 0x54, + 0xeb, 0x27, 0x0b, 0xd4, 0x5c, 0xd2, 0x4f, 0xf7, 0xea, 0x7a, 0xc0, 0x4a, + 0x2f, 0x55, 0x89, 0x80, 0x2b, 0xfd, 0xb4, 0x55, 0xb6, 0x79, 0x57, 0x88, + 0xe2, 0xb6, 0x1e, 0x46, 0x67, 0xa1, 0x8e, 0x9a, 0x07, 0xe7, 0xdd, 0x1f, + 0xc3, 0xe6, 0x0c, 0x3d, 0xb7, 0x6e, 0xfd, 0xf5, 0x37, 0x09, 0x23, 0x35, + 0xaa, 0xfd, 0x6d, 0x9a, 0x37, 0x87, 0x34, 0xc9, 0x32, 0xf3, 0x8d, 0xa5, + 0x74, 0x7c, 0x10, 0x0f, 0x7c, 0xe7, 0x44, 0xfb, 0x35, 0x3e, 0xc0, 0x6b, + 0x8f, 0x35, 0xc2, 0x2a, 0xb0, 0xfc, 0xc6, 0x67, 0xe7, 0x56, 0xfe, 0xfb, + 0x7e, 0x75, 0x63, 0xb9, 0x24, 0x4f, 0x05, 0x14, 0x53, 0x2e, 0x11, 0x23, + 0xf1, 0x15, 0xd8, 0xe4, 0x85, 0xc1, 0x1b, 0x0f, 0x4e, 0x9a, 0xaf, 0xcd, + 0x49, 0x32, 0x43, 0x4b, 0x05, 0x45, 0x30, 0xa7, 0x78, 0xdf, 0x9c, 0x96, + 0xf2, 0xb1, 0x0d, 0x92, 0x3f, 0x1a, 0x71, 0x73, 0x0c, 0x6d, 0x74, 0x41, + 0xb1, 0x20, 0x8d, 0x08, 0x2e, 0xa7, 0xb7, 0x61, 0xa1, 0x34, 0x44, 0x55, + 0x58, 0x11, 0x62, 0x80, 0x2a, 0x00, 0xbc, 0xb9, 0xc9, 0xf5, 0xf5, 0xc7, + 0xa6, 0xa2, 0xa7, 0x56, 0x69, 0x53, 0x1b, 0x76, 0x27, 0x53, 0x73, 0x24, + 0xb4, 0x6a, 0xaf, 0x1a, 0x18, 0x8a, 0xf2, 0x63, 0x97, 0x24, 0x10, 0x71, + 0x9d, 0x7e, 0x82, 0x1a, 0x98, 0x26, 0x6a, 0x49, 0x31, 0x21, 0xe4, 0x2c, + 0x92, 0x8f, 0xa5, 0xd4, 0x77, 0x1a, 0xa2, 0x88, 0x2e, 0x93, 0x3f, 0x8e, + 0xf1, 0xab, 0x73, 0x78, 0x60, 0x17, 0xdb, 0x76, 0x27, 0xb6, 0x96, 0xcd, + 0x11, 0x59, 0x7c, 0x39, 0x06, 0x46, 0x39, 0xc1, 0xf4, 0x3e, 0xda, 0x77, + 0x08, 0x58, 0xae, 0x2e, 0x93, 0xd3, 0x99, 0xa3, 0xc2, 0xbb, 0x0e, 0x6c, + 0x13, 0xb6, 0x7a, 0xe9, 0x05, 0xd8, 0xf3, 0x54, 0x89, 0xa3, 0xe6, 0x08, + 0xa4, 0x31, 0x07, 0xaf, 0x2e, 0x48, 0xc6, 0xa1, 0x66, 0x87, 0xf0, 0xb3, + 0xe1, 0xed, 0x57, 0x1d, 0x5c, 0x18, 0xd2, 0xd5, 0x2d, 0x34, 0x74, 0x50, + 0xc6, 0xd3, 0x4a, 0xc0, 0x9c, 0xf3, 0xb1, 0xd8, 0x7b, 0xe3, 0x27, 0xf1, + 0xad, 0x6b, 0xfd, 0xa3, 0x2c, 0x14, 0x16, 0x5f, 0x87, 0xb6, 0x4a, 0x7a, + 0x0a, 0x54, 0x8a, 0x2a, 0x49, 0x45, 0x3a, 0x30, 0xfa, 0xb0, 0x63, 0x27, + 0x7f, 0x5c, 0xf2, 0xe7, 0x56, 0x1f, 0xf6, 0x75, 0xb5, 0x7f, 0x0c, 0xe0, + 0x9a, 0x5a, 0xca, 0x6e, 0x59, 0x69, 0xeb, 0xe1, 0x13, 0xbb, 0xa9, 0xc9, + 0x2f, 0xb8, 0x0a, 0x7e, 0xc0, 0x63, 0xf3, 0xa5, 0x3c, 0x65, 0xc0, 0x3c, + 0x61, 0xc7, 0x7c, 0x41, 0x5b, 0x70, 0xbd, 0x56, 0x43, 0x41, 0x6c, 0x81, + 0x5d, 0x2d, 0xb4, 0x60, 0x97, 0x7c, 0xff, 0x00, 0x4b, 0x30, 0x1b, 0x2e, + 0x4f, 0x53, 0x92, 0x7d, 0xb4, 0xa8, 0xc7, 0x6c, 0x5c, 0xbd, 0xb3, 0x9b, + 0x38, 0x2e, 0x68, 0xc0, 0xf8, 0x4f, 0x83, 0xae, 0xdc, 0x61, 0x70, 0x6a, + 0x2b, 0x3d, 0x3a, 0x4b, 0x2a, 0xc6, 0xd2, 0x3b, 0x33, 0xf2, 0xaa, 0x28, + 0xc0, 0x3c, 0xc7, 0xb1, 0xc9, 0x18, 0xfb, 0xea, 0x1b, 0xcf, 0x0e, 0xdc, + 0x78, 0x7a, 0x7f, 0x91, 0xbb, 0xd1, 0xd4, 0x51, 0xd4, 0x15, 0x0c, 0x12, + 0x45, 0xc7, 0x32, 0xee, 0x32, 0x3d, 0xb6, 0x3a, 0xf6, 0x17, 0xc3, 0xde, + 0x18, 0xa4, 0xe1, 0x4e, 0x16, 0x86, 0xd3, 0x4d, 0x1a, 0x34, 0xe2, 0x3c, + 0xcd, 0x37, 0x42, 0xed, 0xd7, 0xf4, 0xdf, 0x03, 0x59, 0x17, 0xfb, 0x4c, + 0xd9, 0x2a, 0x9a, 0xef, 0x6f, 0xbe, 0x63, 0xfd, 0xdd, 0xe9, 0xc5, 0x3b, + 0x80, 0x33, 0xc8, 0xe0, 0x92, 0x37, 0xf7, 0xe6, 0xfd, 0xb4, 0x9c, 0xb0, + 0xdb, 0x14, 0xcc, 0xf9, 0x31, 0xd2, 0x30, 0x6a, 0x88, 0xfc, 0x4e, 0x58, + 0x23, 0xfa, 0x9b, 0x73, 0xf6, 0xd3, 0x1b, 0xfd, 0xc2, 0x08, 0xbe, 0x16, + 0x4b, 0x60, 0x68, 0xa4, 0x79, 0x0d, 0xcc, 0x56, 0x2b, 0x96, 0xd8, 0x2f, + 0x86, 0x50, 0x29, 0xf7, 0xd6, 0x91, 0xc1, 0xdc, 0x22, 0xf7, 0xdf, 0x87, + 0x15, 0xf1, 0x5b, 0xad, 0x1f, 0x3d, 0x75, 0xa9, 0xae, 0x44, 0x86, 0x53, + 0x85, 0x58, 0x15, 0x14, 0x64, 0xb3, 0x1e, 0x80, 0x86, 0xe8, 0x3e, 0xf8, + 0xdb, 0x55, 0xcb, 0x47, 0xc3, 0xeb, 0x97, 0x12, 0xde, 0xeb, 0x78, 0x66, + 0x26, 0x8a, 0x29, 0xe0, 0x49, 0x8c, 0x85, 0xf7, 0x55, 0xe4, 0x38, 0x03, + 0x3e, 0xe7, 0x03, 0x3e, 0xfa, 0x4e, 0x37, 0xe5, 0x60, 0x24, 0x62, 0xf6, + 0xfc, 0xcf, 0x72, 0x46, 0xe5, 0x3c, 0xb0, 0x9c, 0xf5, 0xfc, 0x69, 0xb5, + 0xa1, 0x26, 0x6e, 0x28, 0x49, 0x23, 0x38, 0xf0, 0xc6, 0x7f, 0x04, 0x63, + 0xfc, 0xc6, 0xa3, 0xae, 0xb3, 0xd4, 0xf0, 0xed, 0xda, 0xb6, 0xd1, 0x72, + 0xa7, 0x68, 0x6a, 0xe9, 0xe4, 0x2a, 0xc0, 0x8d, 0x9b, 0x7e, 0xa0, 0xfa, + 0x77, 0x1a, 0xd0, 0x7e, 0x18, 0xfc, 0x3e, 0xba, 0xf1, 0x05, 0xc1, 0x27, + 0x86, 0x9c, 0xac, 0x4e, 0x57, 0xce, 0x0e, 0x47, 0x2e, 0xdb, 0x93, 0xdb, + 0xd7, 0x1a, 0xd1, 0x9b, 0x22, 0x8c, 0x2d, 0x91, 0xa2, 0xdb, 0xf0, 0xe9, + 0x6a, 0x65, 0xa1, 0xe2, 0x69, 0x12, 0x37, 0x4a, 0xb7, 0xb7, 0x83, 0x1b, + 0x03, 0x96, 0x74, 0x0c, 0x32, 0xa0, 0x6d, 0xd8, 0x75, 0xd6, 0x7d, 0x4b, + 0xc3, 0x57, 0x66, 0xb5, 0xcd, 0x75, 0x4b, 0x75, 0x4c, 0x74, 0x71, 0xbf, + 0xfc, 0x5f, 0x05, 0x82, 0x05, 0xed, 0xb9, 0x1e, 0xfa, 0xd6, 0xef, 0xe6, + 0xdd, 0xc1, 0xd7, 0x81, 0x65, 0xb4, 0xb1, 0x92, 0xe2, 0x22, 0x06, 0x5a, + 0x85, 0xcf, 0x90, 0x64, 0x6d, 0xef, 0x9c, 0x74, 0xd7, 0x1c, 0x4f, 0x54, + 0x78, 0xae, 0xd8, 0x54, 0x54, 0x57, 0xc3, 0x3d, 0x1c, 0x3f, 0xfe, 0x3a, + 0x4b, 0xfc, 0x83, 0x1a, 0x8f, 0xf0, 0x6c, 0x33, 0x9c, 0x6f, 0xae, 0x3e, + 0x3d, 0x46, 0xce, 0x7a, 0xb6, 0x2a, 0x8c, 0x9e, 0xa5, 0xa7, 0xf0, 0xa9, + 0xe2, 0x2f, 0xb5, 0x3e, 0x54, 0x0c, 0x0c, 0x82, 0x4e, 0xfb, 0xeb, 0xd2, + 0x56, 0xbb, 0x85, 0xf3, 0xff, 0x00, 0x4f, 0x58, 0x55, 0xea, 0x26, 0x8e, + 0x96, 0x6a, 0x28, 0x52, 0x61, 0x1a, 0x8f, 0x11, 0xb2, 0xa3, 0x05, 0x7e, + 0xfa, 0xf3, 0x7a, 0xe6, 0x40, 0x91, 0x92, 0x10, 0xf8, 0xb9, 0x3e, 0xc3, + 0x04, 0x1d, 0x7a, 0x37, 0xe1, 0xe7, 0x11, 0x40, 0x96, 0x98, 0xa2, 0xa6, + 0x11, 0x2b, 0x2c, 0x31, 0xaa, 0x34, 0xa7, 0x03, 0xc3, 0x5d, 0xca, 0xfd, + 0xfb, 0xea, 0x6b, 0x1c, 0x54, 0xa2, 0x9b, 0xa2, 0xf1, 0xe4, 0x49, 0xf2, + 0x5a, 0x2a, 0xe9, 0x2a, 0xad, 0xf4, 0x4e, 0x63, 0x9a, 0x69, 0xa4, 0x46, + 0xfe, 0x4b, 0x4a, 0xd9, 0x0a, 0x3f, 0xab, 0x9b, 0x03, 0x73, 0xdf, 0x18, + 0xce, 0x47, 0x5d, 0x79, 0xeb, 0x8e, 0xef, 0xd5, 0xfc, 0x59, 0xc5, 0x4e, + 0x22, 0xa7, 0x65, 0x8a, 0x91, 0x1a, 0x00, 0xef, 0x19, 0x8d, 0xf6, 0x62, + 0x72, 0xc0, 0xf4, 0x27, 0xd3, 0xb6, 0xb6, 0x4e, 0x3c, 0xa2, 0xbe, 0x7f, + 0xe9, 0xa8, 0xae, 0xb4, 0x33, 0x3f, 0x38, 0x98, 0x4c, 0xbe, 0x0e, 0x23, + 0xe4, 0x42, 0x7a, 0xb2, 0x0c, 0xf3, 0x11, 0x91, 0xdf, 0x4c, 0x78, 0x22, + 0xc1, 0x41, 0x15, 0x6d, 0x35, 0x6c, 0xa2, 0x3a, 0xeb, 0x93, 0xc2, 0x64, + 0x9a, 0xa7, 0x1e, 0x45, 0x7c, 0x82, 0x0e, 0x0e, 0xe4, 0xef, 0xb1, 0xf4, + 0x1a, 0x76, 0x15, 0x2c, 0x72, 0xb6, 0xbb, 0x34, 0xed, 0xba, 0x47, 0xff, + 0xd9 +}; + +void jpeg_get_video_info(VideoDecodeInfo *info) +{ + info->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; + info->width = JPEG_CLIP_WIDTH; + info->height = JPEG_CLIP_HEIGHT; + info->data = jpeg_clip; + info->data_size = JPEG_CLIP_DATA_SIZE; +} diff --git a/tests/test-jpeg.h b/tests/test-jpeg.h new file mode 100644 index 0000000000..8fdbcfe3ca --- /dev/null +++ b/tests/test-jpeg.h @@ -0,0 +1,30 @@ +/* + * test-jpeg.h - JPEG test data + * + * Copyright (C) 2012 Intel Corporation + * + * 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 TEST_JPEG_H +#define TEST_JPEG_H + +#include +#include "test-decode.h" + +void jpeg_get_video_info(VideoDecodeInfo *info); + +#endif /* TEST_JPEG_H */ From ffb13f966048e5c9004be1dc4725eff8b2a97d5b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jul 2012 10:54:33 +0200 Subject: [PATCH 0709/3781] tests: fix build without JPEG decoder support. --- tests/test-decode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test-decode.c b/tests/test-decode.c index 021d087c5a..2f496beae8 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -172,9 +172,11 @@ main(int argc, char *argv[]) case GST_VAAPI_CODEC_H264: decoder = gst_vaapi_decoder_h264_new(display, decoder_caps); break; +#if USE_JPEG_DECODER case GST_VAAPI_CODEC_JPEG: decoder = gst_vaapi_decoder_jpeg_new(display, decoder_caps); break; +#endif case GST_VAAPI_CODEC_MPEG2: decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); break; From 90d82ab7e167e73ecbd5c6b8c50393db22e5b27d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Sun, 1 Jul 2012 03:57:13 +0900 Subject: [PATCH 0710/3781] plugins: do not use deprecated core GStreamer symbols. Bump GStreamer required version to 0.10.14, needed for gst_element_class_set_details_simple(). Signed-off-by: Gwenole Beauchesne --- configure.ac | 2 +- gst/vaapi/gstvaapidecode.c | 8 +++++++- gst/vaapi/gstvaapidownload.c | 8 +++++++- gst/vaapi/gstvaapipostproc.c | 8 +++++++- gst/vaapi/gstvaapisink.c | 8 +++++++- gst/vaapi/gstvaapiupload.c | 8 +++++++- 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 134171aa65..96d7a2c30f 100644 --- a/configure.ac +++ b/configure.ac @@ -12,7 +12,7 @@ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) # gst version number m4_define([gst_major_version], [0]) m4_define([gst_minor_version], [10]) -m4_define([gst_micro_version], [10]) +m4_define([gst_micro_version], [14]) m4_define([gst_major_minor_version], [gst_major_version.gst_minor_version]) m4_define([gst_version], diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 751c158132..6595566c72 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -431,7 +431,13 @@ gst_vaapidecode_base_init(gpointer klass) GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstPadTemplate *pad_template; - gst_element_class_set_details(element_class, &gst_vaapidecode_details); + gst_element_class_set_details_simple( + element_class, + gst_vaapidecode_details.longname, + gst_vaapidecode_details.klass, + gst_vaapidecode_details.description, + gst_vaapidecode_details.author + ); /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapidecode_sink_factory); diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index a2af0a51b5..31e7eeaa90 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -222,7 +222,13 @@ gst_vaapidownload_base_init(gpointer klass) GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstPadTemplate *pad_template; - gst_element_class_set_details(element_class, &gst_vaapidownload_details); + gst_element_class_set_details_simple( + element_class, + gst_vaapidownload_details.longname, + gst_vaapidownload_details.klass, + gst_vaapidownload_details.description, + gst_vaapidownload_details.author + ); /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapidownload_sink_factory); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index ca9400ad4c..476ce19a28 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -667,7 +667,13 @@ gst_vaapipostproc_base_init(gpointer klass) GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstPadTemplate *pad_template; - gst_element_class_set_details(element_class, &gst_vaapipostproc_details); + gst_element_class_set_details_simple( + element_class, + gst_vaapipostproc_details.longname, + gst_vaapipostproc_details.klass, + gst_vaapipostproc_details.description, + gst_vaapipostproc_details.author + ); /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapipostproc_sink_factory); diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 027fcb2446..e6080ea96c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -800,7 +800,13 @@ gst_vaapisink_base_init(gpointer klass) GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstPadTemplate *pad_template; - gst_element_class_set_details(element_class, &gst_vaapisink_details); + gst_element_class_set_details_simple( + element_class, + gst_vaapisink_details.longname, + gst_vaapisink_details.klass, + gst_vaapisink_details.description, + gst_vaapisink_details.author + ); pad_template = gst_static_pad_template_get(&gst_vaapisink_sink_factory); gst_element_class_add_pad_template(element_class, pad_template); diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 9bd383fc96..923a6f6f71 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -213,7 +213,13 @@ gst_vaapiupload_base_init(gpointer klass) GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstPadTemplate *pad_template; - gst_element_class_set_details(element_class, &gst_vaapiupload_details); + gst_element_class_set_details_simple( + element_class, + gst_vaapiupload_details.longname, + gst_vaapiupload_details.klass, + gst_vaapiupload_details.description, + gst_vaapiupload_details.author + ); /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapiupload_sink_factory); From 187c5038702b2e1aa89680e92fb1210366a19707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Sun, 1 Jul 2012 03:57:13 +0900 Subject: [PATCH 0711/3781] plugins: do not use deprecated GStreamer -base symbols. Bump GStreamer plugins -base required version to 0.10.31, needed for gst_x_overlay_got_window_handle(). Signed-off-by: Gwenole Beauchesne --- configure.ac | 2 +- gst/vaapi/gstvaapisink.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 96d7a2c30f..ffe158bc1e 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ m4_define([gst_version], # gst plugins-base version number m4_define([gst_plugins_base_major_version], [0]) m4_define([gst_plugins_base_minor_version], [10]) -m4_define([gst_plugins_base_micro_version], [16]) +m4_define([gst_plugins_base_micro_version], [31]) m4_define([gst_plugins_base_version], [gst_plugins_base_major_version.gst_plugins_base_minor_version.gst_plugins_base_micro_version]) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index e6080ea96c..8c84d33483 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -364,7 +364,7 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) #endif sink->window = gst_vaapi_window_x11_new(display, width, height); if (sink->window) - gst_x_overlay_got_xwindow_id( + gst_x_overlay_got_window_handle( GST_X_OVERLAY(sink), gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) ); From 2594aadb0eee5113569874667febec3c9d762d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Sun, 1 Jul 2012 02:58:36 +0900 Subject: [PATCH 0712/3781] plugins: use G_DEFINE_TYPE_* instead of deprecated GST_BOILERPLATE_*. Signed-off-by: Gwenole Beauchesne --- configure.ac | 11 +++++- gst/vaapi/gstvaapidecode.c | 62 +++++++++++++++----------------- gst/vaapi/gstvaapidownload.c | 64 ++++++++++++++++----------------- gst/vaapi/gstvaapipostproc.c | 62 +++++++++++++++----------------- gst/vaapi/gstvaapisink.c | 69 ++++++++++++++++-------------------- gst/vaapi/gstvaapiupload.c | 60 +++++++++++++++---------------- 6 files changed, 157 insertions(+), 171 deletions(-) diff --git a/configure.ac b/configure.ac index ffe158bc1e..6201f3d14a 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,15 @@ m4_if(gst_vaapi_pre_version, [0], [], [ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) ]) +# glib version number +m4_define([glib_major_version], [2]) +m4_define([glib_minor_version], [4]) +m4_define([glib_micro_version], [0]) +m4_define([glib_major_minor_version], + [glib_major_version.glib_minor_version]) +m4_define([glib_version], + [glib_major_version.glib_minor_version.glib_micro_version]) + # gst version number m4_define([gst_major_version], [0]) m4_define([gst_minor_version], [10]) @@ -146,7 +155,7 @@ AC_SUBST(GTKDOC_VERSION) dnl Check for GLib AC_PATH_PROG([GLIB_GENMARSHAL], [glib-genmarshal]) -PKG_CHECK_MODULES([GLIB], [glib-2.0]) +PKG_CHECK_MODULES([GLIB], [glib-2.0 >= glib_version]) AC_CHECK_LIB([glib-2.0], [g_list_free_full], [ AC_DEFINE([HAVE_G_LIST_FREE_FULL], [1], [Define to 1 if g_list_free_full() is available.])]) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6595566c72..ea34345213 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -104,15 +104,16 @@ static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapidecode_src_caps_str)); +static void +gst_video_context_interface_init(GstVideoContextInterface *iface); + #define GstVideoContextClass GstVideoContextInterface -GST_BOILERPLATE_WITH_INTERFACE( +G_DEFINE_TYPE_WITH_CODE( GstVaapiDecode, gst_vaapidecode, - GstElement, GST_TYPE_ELEMENT, - GstVideoContext, - GST_TYPE_VIDEO_CONTEXT, - gst_video_context); + G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, + gst_video_context_interface_init)); enum { PROP_0, @@ -425,31 +426,6 @@ gst_video_context_interface_init(GstVideoContextInterface *iface) iface->set_context = gst_vaapidecode_set_video_context; } -static void -gst_vaapidecode_base_init(gpointer klass) -{ - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - GstPadTemplate *pad_template; - - gst_element_class_set_details_simple( - element_class, - gst_vaapidecode_details.longname, - gst_vaapidecode_details.klass, - gst_vaapidecode_details.description, - gst_vaapidecode_details.author - ); - - /* sink pad */ - pad_template = gst_static_pad_template_get(&gst_vaapidecode_sink_factory); - gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); - - /* src pad */ - pad_template = gst_static_pad_template_get(&gst_vaapidecode_src_factory); - gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); -} - static void gst_vaapidecode_finalize(GObject *object) { @@ -482,7 +458,7 @@ gst_vaapidecode_finalize(GObject *object) decode->delayed_new_seg = NULL; } - G_OBJECT_CLASS(parent_class)->finalize(object); + G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object); } static void @@ -543,7 +519,7 @@ gst_vaapidecode_change_state(GstElement *element, GstStateChange transition) break; } - ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition); + ret = GST_ELEMENT_CLASS(gst_vaapidecode_parent_class)->change_state(element, transition); if (ret != GST_STATE_CHANGE_SUCCESS) return ret; @@ -571,6 +547,7 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstPadTemplate *pad_template; GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); @@ -581,6 +558,24 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) element_class->change_state = gst_vaapidecode_change_state; + gst_element_class_set_details_simple( + element_class, + gst_vaapidecode_details.longname, + gst_vaapidecode_details.klass, + gst_vaapidecode_details.description, + gst_vaapidecode_details.author + ); + + /* sink pad */ + pad_template = gst_static_pad_template_get(&gst_vaapidecode_sink_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); + + /* src pad */ + pad_template = gst_static_pad_template_get(&gst_vaapidecode_src_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); + #if USE_FFMPEG g_object_class_install_property (object_class, @@ -764,8 +759,9 @@ gst_vaapidecode_query (GstPad *pad, GstQuery *query) { } static void -gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) +gst_vaapidecode_init(GstVaapiDecode *decode) { + GstVaapiDecodeClass *klass = GST_VAAPIDECODE_GET_CLASS(decode); GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); decode->display = NULL; diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 31e7eeaa90..eb0c7c5085 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -108,15 +108,16 @@ struct _GstVaapiDownloadClass { GstBaseTransformClass parent_class; }; +static void +gst_video_context_interface_init(GstVideoContextInterface *iface); + #define GstVideoContextClass GstVideoContextInterface -GST_BOILERPLATE_WITH_INTERFACE( +G_DEFINE_TYPE_WITH_CODE( GstVaapiDownload, gst_vaapidownload, - GstBaseTransform, GST_TYPE_BASE_TRANSFORM, - GstVideoContext, - GST_TYPE_VIDEO_CONTEXT, - gst_video_context); + G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, + gst_video_context_interface_init)); static gboolean gst_vaapidownload_start(GstBaseTransform *trans); @@ -217,11 +218,33 @@ gst_vaapidownload_destroy(GstVaapiDownload *download) } static void -gst_vaapidownload_base_init(gpointer klass) +gst_vaapidownload_finalize(GObject *object) { + gst_vaapidownload_destroy(GST_VAAPIDOWNLOAD(object)); + + G_OBJECT_CLASS(gst_vaapidownload_parent_class)->finalize(object); +} + +static void +gst_vaapidownload_class_init(GstVaapiDownloadClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstPadTemplate *pad_template; + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidownload, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + object_class->finalize = gst_vaapidownload_finalize; + trans_class->start = gst_vaapidownload_start; + trans_class->stop = gst_vaapidownload_stop; + trans_class->before_transform = gst_vaapidownload_before_transform; + trans_class->transform = gst_vaapidownload_transform; + trans_class->transform_caps = gst_vaapidownload_transform_caps; + trans_class->transform_size = gst_vaapidownload_transform_size; + trans_class->set_caps = gst_vaapidownload_set_caps; + gst_element_class_set_details_simple( element_class, gst_vaapidownload_details.longname, @@ -242,34 +265,7 @@ gst_vaapidownload_base_init(gpointer klass) } static void -gst_vaapidownload_finalize(GObject *object) -{ - gst_vaapidownload_destroy(GST_VAAPIDOWNLOAD(object)); - - G_OBJECT_CLASS(parent_class)->finalize(object); -} - -static void -gst_vaapidownload_class_init(GstVaapiDownloadClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); - - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidownload, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - - object_class->finalize = gst_vaapidownload_finalize; - trans_class->start = gst_vaapidownload_start; - trans_class->stop = gst_vaapidownload_stop; - trans_class->before_transform = gst_vaapidownload_before_transform; - trans_class->transform = gst_vaapidownload_transform; - trans_class->transform_caps = gst_vaapidownload_transform_caps; - trans_class->transform_size = gst_vaapidownload_transform_size; - trans_class->set_caps = gst_vaapidownload_set_caps; -} - -static void -gst_vaapidownload_init(GstVaapiDownload *download, GstVaapiDownloadClass *klass) +gst_vaapidownload_init(GstVaapiDownload *download) { GstPad *sinkpad, *srcpad; diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 476ce19a28..8d38a35b12 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -74,15 +74,16 @@ static GstStaticPadTemplate gst_vaapipostproc_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapipostproc_src_caps_str)); +static void +gst_video_context_interface_init(GstVideoContextInterface *iface); + #define GstVideoContextClass GstVideoContextInterface -GST_BOILERPLATE_WITH_INTERFACE( +G_DEFINE_TYPE_WITH_CODE( GstVaapiPostproc, gst_vaapipostproc, - GstElement, GST_TYPE_ELEMENT, - GstVideoContext, - GST_TYPE_VIDEO_CONTEXT, - gst_video_context); + G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, + gst_video_context_interface_init)); enum { PROP_0, @@ -526,7 +527,7 @@ gst_vaapipostproc_finalize(GObject *object) gst_caps_replace(&postproc->srcpad_caps, NULL); gst_caps_replace(&postproc->allowed_caps, NULL); - G_OBJECT_CLASS(parent_class)->finalize(object); + G_OBJECT_CLASS(gst_vaapipostproc_parent_class)->finalize(object); } static void @@ -594,7 +595,7 @@ gst_vaapipostproc_change_state(GstElement *element, GstStateChange transition) break; } - ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition); + ret = GST_ELEMENT_CLASS(gst_vaapipostproc_parent_class)->change_state(element, transition); if (ret != GST_STATE_CHANGE_SUCCESS) return ret; @@ -618,6 +619,7 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstPadTemplate *pad_template; GST_DEBUG_CATEGORY_INIT(gst_debug_vaapipostproc, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); @@ -628,6 +630,24 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) element_class->change_state = gst_vaapipostproc_change_state; + gst_element_class_set_details_simple( + element_class, + gst_vaapipostproc_details.longname, + gst_vaapipostproc_details.klass, + gst_vaapipostproc_details.description, + gst_vaapipostproc_details.author + ); + + /* sink pad */ + pad_template = gst_static_pad_template_get(&gst_vaapipostproc_sink_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); + + /* src pad */ + pad_template = gst_static_pad_template_get(&gst_vaapipostproc_src_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); + /** * GstVaapiPostproc:deinterlace-mode: * @@ -662,33 +682,9 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) } static void -gst_vaapipostproc_base_init(gpointer klass) -{ - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - GstPadTemplate *pad_template; - - gst_element_class_set_details_simple( - element_class, - gst_vaapipostproc_details.longname, - gst_vaapipostproc_details.klass, - gst_vaapipostproc_details.description, - gst_vaapipostproc_details.author - ); - - /* sink pad */ - pad_template = gst_static_pad_template_get(&gst_vaapipostproc_sink_factory); - gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); - - /* src pad */ - pad_template = gst_static_pad_template_get(&gst_vaapipostproc_src_factory); - gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); -} - -static void -gst_vaapipostproc_init(GstVaapiPostproc *postproc, GstVaapiPostprocClass *klass) +gst_vaapipostproc_init(GstVaapiPostproc *postproc) { + GstVaapiPostprocClass *klass = GST_VAAPIPOSTPROC_GET_CLASS(postproc); GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); postproc->allowed_caps = NULL; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 8c84d33483..2c7f268586 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -77,14 +77,25 @@ static GstStaticPadTemplate gst_vaapisink_sink_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(GST_VAAPI_SURFACE_CAPS)); -static void gst_vaapisink_iface_init(GType type); +static void +gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface); -GST_BOILERPLATE_FULL( +static void +gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface); + +static void +gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface); + +G_DEFINE_TYPE_WITH_CODE( GstVaapiSink, gst_vaapisink, - GstVideoSink, GST_TYPE_VIDEO_SINK, - gst_vaapisink_iface_init); + G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, + gst_vaapisink_implements_iface_init); + G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, + gst_vaapisink_video_context_iface_init); + G_IMPLEMENT_INTERFACE(GST_TYPE_X_OVERLAY, + gst_vaapisink_xoverlay_iface_init)); enum { PROP_0, @@ -215,19 +226,6 @@ gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface) iface->expose = gst_vaapisink_xoverlay_expose; } -static void -gst_vaapisink_iface_init(GType type) -{ - const GType g_define_type_id = type; - - G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, - gst_vaapisink_implements_iface_init); - G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_vaapisink_video_context_iface_init); - G_IMPLEMENT_INTERFACE(GST_TYPE_X_OVERLAY, - gst_vaapisink_xoverlay_iface_init); -} - static void gst_vaapisink_destroy(GstVaapiSink *sink) { @@ -733,7 +731,7 @@ gst_vaapisink_finalize(GObject *object) { gst_vaapisink_destroy(GST_VAAPISINK(object)); - G_OBJECT_CLASS(parent_class)->finalize(object); + G_OBJECT_CLASS(gst_vaapisink_parent_class)->finalize(object); } static void @@ -794,30 +792,13 @@ gst_vaapisink_get_property( } } -static void -gst_vaapisink_base_init(gpointer klass) -{ - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - GstPadTemplate *pad_template; - - gst_element_class_set_details_simple( - element_class, - gst_vaapisink_details.longname, - gst_vaapisink_details.klass, - gst_vaapisink_details.description, - gst_vaapisink_details.author - ); - - pad_template = gst_static_pad_template_get(&gst_vaapisink_sink_factory); - gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); -} - static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass); + GstPadTemplate *pad_template; GST_DEBUG_CATEGORY_INIT(gst_debug_vaapisink, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); @@ -833,6 +814,18 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->render = gst_vaapisink_show_frame; basesink_class->query = gst_vaapisink_query; + gst_element_class_set_details_simple( + element_class, + gst_vaapisink_details.longname, + gst_vaapisink_details.klass, + gst_vaapisink_details.description, + gst_vaapisink_details.author + ); + + pad_template = gst_static_pad_template_get(&gst_vaapisink_sink_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); + #if USE_VAAPISINK_GLX g_object_class_install_property (object_class, @@ -879,7 +872,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) } static void -gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass) +gst_vaapisink_init(GstVaapiSink *sink) { sink->caps = NULL; sink->display = NULL; diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 923a6f6f71..d96f3663bf 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -84,15 +84,16 @@ static GstStaticPadTemplate gst_vaapiupload_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapiupload_vaapi_caps_str)); +static void +gst_video_context_interface_init(GstVideoContextInterface *iface); + #define GstVideoContextClass GstVideoContextInterface -GST_BOILERPLATE_WITH_INTERFACE( +G_DEFINE_TYPE_WITH_CODE( GstVaapiUpload, gst_vaapiupload, - GstBaseTransform, GST_TYPE_BASE_TRANSFORM, - GstVideoContext, - GST_TYPE_VIDEO_CONTEXT, - gst_video_context); + G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, + gst_video_context_interface_init)); /* * Direct rendering levels (direct-rendering) @@ -207,37 +208,12 @@ gst_vaapiupload_destroy(GstVaapiUpload *upload) } } -static void -gst_vaapiupload_base_init(gpointer klass) -{ - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - GstPadTemplate *pad_template; - - gst_element_class_set_details_simple( - element_class, - gst_vaapiupload_details.longname, - gst_vaapiupload_details.klass, - gst_vaapiupload_details.description, - gst_vaapiupload_details.author - ); - - /* sink pad */ - pad_template = gst_static_pad_template_get(&gst_vaapiupload_sink_factory); - gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); - - /* src pad */ - pad_template = gst_static_pad_template_get(&gst_vaapiupload_src_factory); - gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); -} - static void gst_vaapiupload_finalize(GObject *object) { gst_vaapiupload_destroy(GST_VAAPIUPLOAD(object)); - G_OBJECT_CLASS(parent_class)->finalize(object); + G_OBJECT_CLASS(gst_vaapiupload_parent_class)->finalize(object); } @@ -287,7 +263,9 @@ static void gst_vaapiupload_class_init(GstVaapiUploadClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); + GstPadTemplate *pad_template; GST_DEBUG_CATEGORY_INIT(gst_debug_vaapiupload, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); @@ -304,6 +282,24 @@ gst_vaapiupload_class_init(GstVaapiUploadClass *klass) trans_class->get_unit_size = gst_vaapiupload_get_unit_size; trans_class->prepare_output_buffer = gst_vaapiupload_prepare_output_buffer; + gst_element_class_set_details_simple( + element_class, + gst_vaapiupload_details.longname, + gst_vaapiupload_details.klass, + gst_vaapiupload_details.description, + gst_vaapiupload_details.author + ); + + /* sink pad */ + pad_template = gst_static_pad_template_get(&gst_vaapiupload_sink_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); + + /* src pad */ + pad_template = gst_static_pad_template_get(&gst_vaapiupload_src_factory); + gst_element_class_add_pad_template(element_class, pad_template); + gst_object_unref(pad_template); + /** * GstVaapiUpload:direct-rendering: * @@ -335,7 +331,7 @@ gst_vaapiupload_class_init(GstVaapiUploadClass *klass) } static void -gst_vaapiupload_init(GstVaapiUpload *upload, GstVaapiUploadClass *klass) +gst_vaapiupload_init(GstVaapiUpload *upload) { GstPad *sinkpad, *srcpad; From 50e40a4c8752d97d828d0dea1cc28709b84bb57f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jul 2012 11:43:03 +0200 Subject: [PATCH 0713/3781] plugins: add support for GstImplementsInterface. --- gst/vaapi/gstvaapidecode.c | 28 ++++++++++++++++++++++------ gst/vaapi/gstvaapidownload.c | 28 ++++++++++++++++++++++------ gst/vaapi/gstvaapipostproc.c | 28 ++++++++++++++++++++++------ gst/vaapi/gstvaapiupload.c | 28 ++++++++++++++++++++++------ 4 files changed, 88 insertions(+), 24 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ea34345213..540d15f6e3 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -104,6 +104,9 @@ static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapidecode_src_caps_str)); +static void +gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface); + static void gst_video_context_interface_init(GstVideoContextInterface *iface); @@ -112,6 +115,8 @@ G_DEFINE_TYPE_WITH_CODE( GstVaapiDecode, gst_vaapidecode, GST_TYPE_ELEMENT, + G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, + gst_vaapidecode_implements_iface_init); G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init)); @@ -404,6 +409,23 @@ gst_vaapidecode_reset(GstVaapiDecode *decode, GstCaps *caps) return gst_vaapidecode_create(decode, caps); } +/* GstImplementsInterface interface */ + +static gboolean +gst_vaapidecode_implements_interface_supported( + GstImplementsInterface *iface, + GType type +) +{ + return (type == GST_TYPE_VIDEO_CONTEXT); +} + +static void +gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface) +{ + iface->supported = gst_vaapidecode_implements_interface_supported; +} + /* GstVideoContext interface */ static void @@ -414,12 +436,6 @@ gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type, gst_vaapi_set_display (type, value, &decode->display); } -static gboolean -gst_video_context_supported (GstVaapiDecode *decode, GType iface_type) -{ - return (iface_type == GST_TYPE_VIDEO_CONTEXT); -} - static void gst_video_context_interface_init(GstVideoContextInterface *iface) { diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index eb0c7c5085..63f2afee8a 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -108,6 +108,9 @@ struct _GstVaapiDownloadClass { GstBaseTransformClass parent_class; }; +static void +gst_vaapidownload_implements_iface_init(GstImplementsInterfaceClass *iface); + static void gst_video_context_interface_init(GstVideoContextInterface *iface); @@ -116,6 +119,8 @@ G_DEFINE_TYPE_WITH_CODE( GstVaapiDownload, gst_vaapidownload, GST_TYPE_BASE_TRANSFORM, + G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, + gst_vaapidownload_implements_iface_init); G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init)); @@ -165,6 +170,23 @@ gst_vaapidownload_query( GstQuery *query ); +/* GstImplementsInterface interface */ + +static gboolean +gst_vaapidownload_implements_interface_supported( + GstImplementsInterface *iface, + GType type +) +{ + return (type == GST_TYPE_VIDEO_CONTEXT); +} + +static void +gst_vaapidownload_implements_iface_init(GstImplementsInterfaceClass *iface) +{ + iface->supported = gst_vaapidownload_implements_interface_supported; +} + /* GstVideoContext interface */ static void @@ -175,12 +197,6 @@ gst_vaapidownload_set_video_context(GstVideoContext *context, const gchar *type, gst_vaapi_set_display (type, value, &download->display); } -static gboolean -gst_video_context_supported (GstVaapiDownload *download, GType iface_type) -{ - return (iface_type == GST_TYPE_VIDEO_CONTEXT); -} - static void gst_video_context_interface_init(GstVideoContextInterface *iface) { diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 8d38a35b12..feb5558966 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -74,6 +74,9 @@ static GstStaticPadTemplate gst_vaapipostproc_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapipostproc_src_caps_str)); +static void +gst_vaapipostproc_implements_iface_init(GstImplementsInterfaceClass *iface); + static void gst_video_context_interface_init(GstVideoContextInterface *iface); @@ -82,6 +85,8 @@ G_DEFINE_TYPE_WITH_CODE( GstVaapiPostproc, gst_vaapipostproc, GST_TYPE_ELEMENT, + G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, + gst_vaapipostproc_implements_iface_init); G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init)); @@ -156,6 +161,23 @@ get_vaapipostproc_from_pad(GstPad *pad) return GST_VAAPIPOSTPROC(gst_pad_get_parent_element(pad)); } +/* GstImplementsInterface interface */ + +static gboolean +gst_vaapipostproc_implements_interface_supported( + GstImplementsInterface *iface, + GType type +) +{ + return (type == GST_TYPE_VIDEO_CONTEXT); +} + +static void +gst_vaapipostproc_implements_iface_init(GstImplementsInterfaceClass *iface) +{ + iface->supported = gst_vaapipostproc_implements_interface_supported; +} + /* GstVideoContext interface */ static void @@ -170,12 +192,6 @@ gst_vaapipostproc_set_video_context( gst_vaapi_set_display(type, value, &postproc->display); } -static gboolean -gst_video_context_supported(GstVaapiPostproc *postproc, GType iface_type) -{ - return (iface_type == GST_TYPE_VIDEO_CONTEXT); -} - static void gst_video_context_interface_init(GstVideoContextInterface *iface) { diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index d96f3663bf..0762279352 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -84,6 +84,9 @@ static GstStaticPadTemplate gst_vaapiupload_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapiupload_vaapi_caps_str)); +static void +gst_vaapiupload_implements_iface_init(GstImplementsInterfaceClass *iface); + static void gst_video_context_interface_init(GstVideoContextInterface *iface); @@ -92,6 +95,8 @@ G_DEFINE_TYPE_WITH_CODE( GstVaapiUpload, gst_vaapiupload, GST_TYPE_BASE_TRANSFORM, + G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, + gst_vaapiupload_implements_iface_init); G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init)); @@ -167,6 +172,23 @@ gst_vaapiupload_query( GstQuery *query ); +/* GstImplementsInterface interface */ + +static gboolean +gst_vaapiupload_implements_interface_supported( + GstImplementsInterface *iface, + GType type +) +{ + return (type == GST_TYPE_VIDEO_CONTEXT); +} + +static void +gst_vaapiupload_implements_iface_init(GstImplementsInterfaceClass *iface) +{ + iface->supported = gst_vaapiupload_implements_interface_supported; +} + /* GstVideoContext interface */ static void @@ -177,12 +199,6 @@ gst_vaapiupload_set_video_context(GstVideoContext *context, const gchar *type, gst_vaapi_set_display (type, value, &upload->display); } -static gboolean -gst_video_context_supported (GstVaapiUpload *upload, GType iface_type) -{ - return (iface_type == GST_TYPE_VIDEO_CONTEXT); -} - static void gst_video_context_interface_init(GstVideoContextInterface *iface) { From 44794661e5098a47bcdfa2b21375a6b0964f9225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Thu, 28 Jun 2012 00:04:19 +0900 Subject: [PATCH 0714/3781] configure: don't use AC_SUBST for some variables. PKG_CHECK_MODULES already does this for us. Signed-off-by: Gwenole Beauchesne --- configure.ac | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/configure.ac b/configure.ac index 6201f3d14a..d69959bf30 100644 --- a/configure.ac +++ b/configure.ac @@ -159,15 +159,11 @@ PKG_CHECK_MODULES([GLIB], [glib-2.0 >= glib_version]) AC_CHECK_LIB([glib-2.0], [g_list_free_full], [ AC_DEFINE([HAVE_G_LIST_FREE_FULL], [1], [Define to 1 if g_list_free_full() is available.])]) -AC_SUBST(GLIB_CFLAGS) -AC_SUBST(GLIB_LIBS) dnl Check for GStreamer PKG_CHECK_MODULES([GST], [gstreamer-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED] ) -AC_SUBST(GST_CFLAGS) -AC_SUBST(GST_LIBS) AC_CACHE_CHECK([for GstBaseSink::query hook], ac_cv_have_gst_base_sink_query, [ saved_CFLAGS="$CFLAGS" @@ -191,8 +187,6 @@ dnl Check for GStreamer plugins-base PKG_CHECK_MODULES([GST_PLUGINS_BASE], [gstreamer-plugins-base-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED] ) -AC_SUBST(GST_PLUGINS_BASE_CFLAGS) -AC_SUBST(GST_PLUGINS_BASE_LIBS) V=`$PKG_CONFIG --modversion gstreamer-plugins-base-$GST_MAJORMINOR` GST_PLUGINS_BASE_MAJOR_VERSION=`echo "$V" | cut -d'.' -f1` @@ -206,15 +200,11 @@ dnl Check for GStreamer base PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED] ) -AC_SUBST(GST_BASE_CFLAGS) -AC_SUBST(GST_BASE_LIBS) dnl Check for GStreamer video PKG_CHECK_MODULES([GST_VIDEO], [gstreamer-video-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED] ) -AC_SUBST(GST_VIDEO_CFLAGS) -AC_SUBST(GST_VIDEO_LIBS) AC_CACHE_CHECK([for GstVideoOverlayComposition], ac_cv_have_gst_video_overlay_composition, [ @@ -239,8 +229,6 @@ dnl Check for GStreamer basevideo PKG_CHECK_MODULES([GST_BASEVIDEO], [gstreamer-basevideo-$GST_MAJORMINOR >= $GST_PLUGINS_BAD_VERSION_REQUIRED] ) -AC_SUBST(GST_BASEVIDEO_CFLAGS) -AC_SUBST(GST_BASEVIDEO_LIBS) dnl Check for GStreamer codec parsers USE_CODEC_PARSERS=0 @@ -307,8 +295,6 @@ dnl Check for GStreamer interfaces PKG_CHECK_MODULES([GST_INTERFACES], [gstreamer-interfaces-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED] ) -AC_SUBST(GST_INTERFACES_CFLAGS) -AC_SUBST(GST_INTERFACES_LIBS) dnl GST_ALL_LDFLAGS: dnl LDFLAGS really should only contain flags, not libs - they get added before From 27246f04abd678507f0b56c12635915fec0aeea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Thu, 28 Jun 2012 00:20:12 +0900 Subject: [PATCH 0715/3781] configure: drop deprecated autoconf macros. Bump autoconf required version to 2.58, needed for AS_HELP_STRING macro. Signed-off-by: Gwenole Beauchesne --- configure.ac | 74 +++++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/configure.ac b/configure.ac index d69959bf30..e221e4faee 100644 --- a/configure.ac +++ b/configure.ac @@ -55,14 +55,14 @@ m4_define([gtkdoc_major_version], [1]) m4_define([gtkdoc_minor_version], [9]) m4_define([gtkdoc_version], [gtkdoc_major_version.gtkdoc_minor_version]) -AC_PREREQ([2.57]) +AC_PREREQ([2.58]) AC_INIT([gst_vaapi], [gst_vaapi_version], [gwenole.beauchesne@intel.com], [gstreamer-vaapi]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE -AM_CONFIG_HEADER([config.h]) +AC_CONFIG_HEADERS([config.h]) TODAY="`LC_ALL=C date +'%a, %d %b %Y %X %z'`" AC_SUBST(TODAY) @@ -94,27 +94,27 @@ AM_PROG_CC_C_O AC_PROG_LIBTOOL AC_ARG_ENABLE(glx, - AC_HELP_STRING([--enable-glx], + AS_HELP_STRING([--enable-glx], [enable OpenGL/X11 @<:@default=yes@:>@]), [], [enable_glx="yes"]) AC_ARG_ENABLE(vaapi-glx, - AC_HELP_STRING([--enable-vaapi-glx], + AS_HELP_STRING([--enable-vaapi-glx], [enable VA/GLX extensions @<:@default=yes@:>@]), [], [enable_vaapi_glx="yes"]) AC_ARG_ENABLE(vaapisink-glx, - AC_HELP_STRING([--enable-vaapisink-glx], + AS_HELP_STRING([--enable-vaapisink-glx], [enable OpenGL/X11 to vaapisink @<:@default=yes@:>@]), [], [enable_vaapisink_glx="no"]) AC_ARG_ENABLE(ffmpeg, - AC_HELP_STRING([--enable-ffmpeg], + AS_HELP_STRING([--enable-ffmpeg], [enable bitstream parsing from FFmpeg @<:@default=no@:>@]), [], [enable_ffmpeg="no"]) AC_ARG_ENABLE(codecparsers, - AC_HELP_STRING([--enable-codecparsers], + AS_HELP_STRING([--enable-codecparsers], [enable adhoc bitstream parsers from GStreamer @<:@default=yes@:>@]), [], [enable_codecparsers="yes"]) @@ -170,9 +170,10 @@ AC_CACHE_CHECK([for GstBaseSink::query hook], ac_cv_have_gst_base_sink_query, [ CFLAGS="$CFLAGS $GST_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $GST_LIBS" - AC_TRY_COMPILE( - [#include ], - [GstBaseSinkClass klass; klass.query = NULL;], + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[GstBaseSinkClass klass; klass.query = NULL;]])], [ac_cv_have_gst_base_sink_query="yes"], [ac_cv_have_gst_base_sink_query="no"] ) @@ -212,9 +213,10 @@ AC_CACHE_CHECK([for GstVideoOverlayComposition], CFLAGS="$CFLAGS $GST_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $GST_LIBS" - AC_TRY_COMPILE( - [#include ], - [GstVideoOverlayComposition *c = gst_video_overlay_composition_new(0);], + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[GstVideoOverlayComposition *c = gst_video_overlay_composition_new(0);]])], [ac_cv_have_gst_video_overlay_composition="yes"], [ac_cv_have_gst_video_overlay_composition="no"] ) @@ -252,10 +254,11 @@ AC_CACHE_CHECK([for GstH264SliceHdr::n_emulation_prevention_bytes], CFLAGS="$CFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" - AC_TRY_COMPILE( - [#include ], - [GstH264SliceHdr slice_hdr; - slice_hdr.n_emulation_prevention_bytes = 0;], + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[GstH264SliceHdr slice_hdr; + slice_hdr.n_emulation_prevention_bytes = 0;]])], [ac_cv_have_gst_h264_slice_hdr_epb_count="yes"], [ac_cv_have_gst_h264_slice_hdr_epb_count="no"] ) @@ -269,9 +272,10 @@ AC_CACHE_CHECK([for JPEG parser], CFLAGS="$CFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" - AC_TRY_COMPILE( - [#include ], - [GstJpegImage jpeg_image;], + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[GstJpegImage jpeg_image;]])], [ac_cv_have_gst_jpeg_parser="yes"], [ac_cv_have_gst_jpeg_parser="no" USE_LOCAL_CODEC_PARSERS=1] ) @@ -350,11 +354,13 @@ AC_CACHE_CHECK([for old VA-API 0.29], CFLAGS="$CFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $LIBVA_LIBS" - AC_TRY_LINK( - [#include ], - [vaGetDisplay(NULL)], - [ac_cv_have_vaapi_old="yes"], - [ac_cv_have_vaapi_old="no"]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[vaGetDisplay(NULL)]])], + [ac_cv_have_vaapi_old="yes"], + [ac_cv_have_vaapi_old="no"] + ) CFLAGS="$saved_CFLAGS" LIBS="$saved_LIBS" ]) @@ -408,13 +414,14 @@ AC_CACHE_CHECK([for JPEG decoding API], CFLAGS="$CFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" LIBS="$CFLAGS $LIBVA_LIBS" - AC_TRY_COMPILE( - [#include - #include ], - [VAPictureParameterBufferJPEG pic_param; - VASliceParameterBufferJPEG slice_param; - VAHuffmanTableBufferJPEG huffman_table; - VAIQMatrixBufferJPEG iq_matrix;], + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include ]], + [[VAPictureParameterBufferJPEG pic_param; + VASliceParameterBufferJPEG slice_param; + VAHuffmanTableBufferJPEG huffman_table; + VAIQMatrixBufferJPEG iq_matrix;]])], [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=1], [ac_cv_have_jpeg_decoding_api="no"] ) @@ -479,7 +486,7 @@ VA_VERSION_STR="$VA_VERSION" pkgconfigdir=${libdir}/pkgconfig AC_SUBST(pkgconfigdir) -AC_OUTPUT([ +AC_CONFIG_FILES([ Makefile debian.upstream/Makefile debian.upstream/changelog @@ -517,6 +524,7 @@ pkgconfig/gstreamer-vaapi-x11.pc.in gst/vaapi/Makefile tests/Makefile ]) +AC_OUTPUT dnl Print summary yesno() { From 7eef852bdb92c805ec5efb45886a7c03f3bdc015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Thu, 28 Jun 2012 00:27:31 +0900 Subject: [PATCH 0716/3781] configure: put m4 macros and autogenerated files into m4/ directory. Signed-off-by: Gwenole Beauchesne --- Makefile.am | 2 ++ autogen.sh | 4 +++- configure.ac | 11 ++++++++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index 7b35b5828c..a20451466f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,5 @@ +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} + AUTOMAKE_OPTIONS = foreign SUBDIRS = debian.upstream gst-libs gst pkgconfig tests docs diff --git a/autogen.sh b/autogen.sh index 9e15ad9ae9..7f9a198ddb 100755 --- a/autogen.sh +++ b/autogen.sh @@ -12,6 +12,8 @@ test $TEST_TYPE $FILE || { exit 1 } +mkdir -p m4 + GTKDOCIZE=`which gtkdocize` if test -z $GTKDOCIZE; then echo "*** No gtk-doc support ***" @@ -33,7 +35,7 @@ if test -z $AUTORECONF; then echo "*** No autoreconf found ***" exit 1 else - ACLOCAL="${ACLOCAL-aclocal} $ACLOCAL_FLAGS" autoreconf -v --install || exit $? + autoreconf -v --install || exit $? fi if test -z "$NO_CONFIGURE"; then diff --git a/configure.ac b/configure.ac index e221e4faee..9a6c89aba9 100644 --- a/configure.ac +++ b/configure.ac @@ -59,10 +59,15 @@ AC_PREREQ([2.58]) AC_INIT([gst_vaapi], [gst_vaapi_version], [gwenole.beauchesne@intel.com], [gstreamer-vaapi]) -AC_CONFIG_SRCDIR([Makefile.am]) -AC_CANONICAL_TARGET -AM_INIT_AUTOMAKE + AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_SRCDIR([Makefile.am]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_AUX_DIR([build-aux]) + +AC_CANONICAL_TARGET + +AM_INIT_AUTOMAKE TODAY="`LC_ALL=C date +'%a, %d %b %Y %X %z'`" AC_SUBST(TODAY) From cdd33a433ecf089f38dc113dab9387dea5e5676e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Thu, 28 Jun 2012 00:39:10 +0900 Subject: [PATCH 0717/3781] configure: fix build without gtk-doc support. Also do not generate tamplate files as all the documentation is inline. Drop un-needed code in autogen.sh as well. Signed-off-by: Gwenole Beauchesne --- autogen.sh | 8 -------- configure.ac | 6 ++++-- docs/Makefile.am | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/autogen.sh b/autogen.sh index 7f9a198ddb..3032585dc2 100755 --- a/autogen.sh +++ b/autogen.sh @@ -20,14 +20,6 @@ if test -z $GTKDOCIZE; then echo "EXTRA_DIST =" > gtk-doc.make else gtkdocize || exit $? - # we need to patch gtk-doc.make to support pretty output with - # libtool 1.x. Should be fixed in the next version of gtk-doc. - # To be more resilient with the various versions of gtk-doc one - # can find, just sed gkt-doc.make rather than patch it. - sed -e 's#) --mode=compile#) --tag=CC --mode=compile#' gtk-doc.make > gtk-doc.temp \ - && mv gtk-doc.temp gtk-doc.make - sed -e 's#) --mode=link#) --tag=CC --mode=link#' gtk-doc.make > gtk-doc.temp \ - && mv gtk-doc.temp gtk-doc.make fi AUTORECONF=`which autoreconf` diff --git a/configure.ac b/configure.ac index 9a6c89aba9..eaeebf8231 100644 --- a/configure.ac +++ b/configure.ac @@ -154,8 +154,10 @@ AC_CHECK_LIB(m, tan) dnl Check for Gtk doc GTKDOC_VERSION=gtkdoc_version -GTK_DOC_CHECK([$GTKDOC_VERSION]) -AM_CONDITIONAL([BUILD_GTK_DOC], [test "x$enable_gtk_doc" = "xyes"]) +# gtkdocize greps for '^GTK_DOC_CHECK', so it needs to be on its own line +m4_ifdef([GTK_DOC_CHECK], [ +GTK_DOC_CHECK([$GTKDOC_VERSION], [--flavour no-tmpl])], [ +AM_CONDITIONAL([ENABLE_GTK_DOC], [false])]) AC_SUBST(GTKDOC_VERSION) dnl Check for GLib diff --git a/docs/Makefile.am b/docs/Makefile.am index 516af70036..58bb28723e 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -1,6 +1,6 @@ SUBDIRS = -if BUILD_GTK_DOC +if ENABLE_GTK_DOC SUBDIRS += reference endif From fbb9a5e1c0f3179dc07d9f970b67d3586be28ed2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jul 2012 13:57:05 +0200 Subject: [PATCH 0718/3781] jpeg: fix make dist. --- gst-libs/gst/codecparsers/Makefile.am | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index f6a49a31ce..aa10113b48 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -22,12 +22,9 @@ libgstvaapi_codecparsers_source_h = \ gstjpegparser.h \ $(NULL) -libgstvaapi_codecparsers_source_priv_h = \ - $(NULL) - libgstvaapi_codecparsers_la_SOURCES = \ $(libgstvaapi_codecparsers_source_c) \ - $(libgstvaapi_codecparsers_source_priv_h) \ + $(libgstvaapi_codecparsers_source_h) \ $(NULL) libgstvaapi_codecparsers_la_CFLAGS = \ From 1150f50ed052e93bff98eee54f3d21a062d03827 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jul 2012 13:58:31 +0200 Subject: [PATCH 0719/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index eaeebf8231..f9e617ea24 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) -m4_define([gst_vaapi_minor_version], [3]) -m4_define([gst_vaapi_micro_version], [8]) +m4_define([gst_vaapi_minor_version], [4]) +m4_define([gst_vaapi_micro_version], [0]) m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) From 27c8269b43490d61200c57cb34bb2b6f59832929 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jul 2012 14:29:33 +0200 Subject: [PATCH 0720/3781] glibcompat: drop explicit check for g_list_free_full(). --- configure.ac | 3 --- gst-libs/gst/vaapi/glibcompat.h | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index f9e617ea24..d1b2244d40 100644 --- a/configure.ac +++ b/configure.ac @@ -163,9 +163,6 @@ AC_SUBST(GTKDOC_VERSION) dnl Check for GLib AC_PATH_PROG([GLIB_GENMARSHAL], [glib-genmarshal]) PKG_CHECK_MODULES([GLIB], [glib-2.0 >= glib_version]) -AC_CHECK_LIB([glib-2.0], [g_list_free_full], [ - AC_DEFINE([HAVE_G_LIST_FREE_FULL], [1], - [Define to 1 if g_list_free_full() is available.])]) dnl Check for GStreamer PKG_CHECK_MODULES([GST], diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 7ccd645911..93a3903c2e 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -24,7 +24,7 @@ #include -#ifndef HAVE_G_LIST_FREE_FULL +#if !GLIB_CHECK_VERSION(2,27,2) static inline void g_list_free_full(GList *list, GDestroyNotify free_func) { From c415868f269745c5c87c025681f5ee19feaba278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Sun, 1 Jul 2012 06:02:22 +0900 Subject: [PATCH 0721/3781] libs: use generic g_cclosure_marshal_VOID__VOID(). Signed-off-by: Gwenole Beauchesne --- .gitignore | 3 --- configure.ac | 1 - docs/reference/libs/Makefile.am | 2 -- gst-libs/gst/vaapi/Makefile.am | 34 ------------------------- gst-libs/gst/vaapi/gstvaapimarshal.list | 1 - gst-libs/gst/vaapi/gstvaapiobject.c | 3 +-- 6 files changed, 1 insertion(+), 43 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapimarshal.list diff --git a/.gitignore b/.gitignore index 93fb38efcf..2cd25a5bf6 100644 --- a/.gitignore +++ b/.gitignore @@ -55,9 +55,6 @@ docs/reference/plugins/tmpl* docs/reference/plugins/xml* docs/reference/plugins/*.stamp gst-libs/gst/gstutils_version.h -gst-libs/gst/vaapi/gstvaapimarshal.c -gst-libs/gst/vaapi/gstvaapimarshal.h -gst-libs/gst/vaapi/stamp-marshal gtk-doc.make pkgconfig/gstreamer-vaapi-0.10.pc pkgconfig/gstreamer-vaapi-glx-0.10.pc diff --git a/configure.ac b/configure.ac index d1b2244d40..4bef5b32be 100644 --- a/configure.ac +++ b/configure.ac @@ -161,7 +161,6 @@ AM_CONDITIONAL([ENABLE_GTK_DOC], [false])]) AC_SUBST(GTKDOC_VERSION) dnl Check for GLib -AC_PATH_PROG([GLIB_GENMARSHAL], [glib-genmarshal]) PKG_CHECK_MODULES([GLIB], [glib-2.0 >= glib_version]) dnl Check for GStreamer diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index f8eafeb2c8..d4747b3281 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -66,7 +66,6 @@ IGNORE_HFILES = \ gstvaapidisplay_priv.h \ gstvaapidisplay_glx_priv.h \ gstvaapidisplay_x11_priv.h \ - gstvaapimarshal.h \ gstvaapiobject_priv.h \ gstvaapiutils.h \ gstvaapiutils_glx.h \ @@ -75,7 +74,6 @@ IGNORE_HFILES = \ $(NULL) EXTRA_HFILES = \ - gstvaapimarshal.c \ $(NULL) # Images to copy into HTML directory. diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index b269193d04..9c6f846d8a 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -36,7 +36,6 @@ libgstvaapi_source_c = \ gstvaapiimage.c \ gstvaapiimageformat.c \ gstvaapiimagepool.c \ - gstvaapimarshal.c \ gstvaapiobject.c \ gstvaapiparamspecs.c \ gstvaapiprofile.c \ @@ -271,36 +270,3 @@ libgstvaapi_glx_@GST_MAJORMINOR@_la_LDFLAGS = \ # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in - -# glib-genmarshal rules -glib_marshal_list = gstvaapimarshal.list -glib_marshal_prefix = gst_vaapi_marshal - -marshal_h = $(glib_marshal_list:.list=.h) -marshal_c = $(glib_marshal_list:.list=.c) - -CLEANFILES = stamp-marshal -DISTCLEANFILES = $(marshal_h) $(marshal_c) -BUILT_SOURCES = $(marshal_h) $(marshal_c) -EXTRA_DIST = $(srcdir)/$(glib_marshal_list) - -stamp-marshal: $(glib_marshal_list) - $(GLIB_GENMARSHAL) \ - --prefix=$(glib_marshal_prefix) \ - --header \ - $(srcdir)/$(glib_marshal_list) > xgen-mh \ - && (cmp -s xgen-mh $(marshal_h) || cp -f xgen-mh $(marshal_h)) \ - && rm -f xgen-mh \ - && echo timestamp > $(@F) - -$(marshal_h): stamp-marshal - @true - -$(marshal_c): $(marshal_h) - (echo "#include \"$(marshal_h)\"" ; \ - $(GLIB_GENMARSHAL) \ - --prefix=$(glib_marshal_prefix) \ - --body \ - $(srcdir)/$(glib_marshal_list)) > xgen-mc \ - && cp xgen-mc $(marshal_c) \ - && rm -f xgen-mc diff --git a/gst-libs/gst/vaapi/gstvaapimarshal.list b/gst-libs/gst/vaapi/gstvaapimarshal.list deleted file mode 100644 index 5b76282c96..0000000000 --- a/gst-libs/gst/vaapi/gstvaapimarshal.list +++ /dev/null @@ -1 +0,0 @@ -VOID:VOID diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 52529c0f77..ec8286e7ed 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -29,7 +29,6 @@ #include "gstvaapi_priv.h" #include "gstvaapiparamspecs.h" #include "gstvaapivalue.h" -#include "gstvaapimarshal.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -179,7 +178,7 @@ gst_vaapi_object_class_init(GstVaapiObjectClass *klass) G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET(GstVaapiObjectClass, destroy), NULL, NULL, - gst_vaapi_marshal_VOID__VOID, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 ); } From 30024b3f8e2de95c0ba31fc4989f45249bd9d070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Sun, 1 Jul 2012 05:34:15 +0900 Subject: [PATCH 0722/3781] libs: use g_clear_object() wherever applicable. This is a preferred thread-safe version. Also add an inline version of g_clear_object() if compiling with glib < 2.28. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/glibcompat.h | 19 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapicontext.c | 5 +---- gst-libs/gst/vaapi/gstvaapidisplay.c | 8 ++------ gst-libs/gst/vaapi/gstvaapiobject.c | 5 +---- gst-libs/gst/vaapi/gstvaapisubpicture.c | 5 +---- gst-libs/gst/vaapi/gstvaapisurface.c | 5 +---- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 5 +---- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 20 ++++--------------- .../gst/vaapi/gstvaapivideoconverter_glx.c | 5 +---- gst-libs/gst/vaapi/gstvaapivideopool.c | 5 +---- 10 files changed, 32 insertions(+), 50 deletions(-) diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 93a3903c2e..30a8563f17 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -23,6 +23,7 @@ #define GLIB_COMPAT_H #include +#include #if !GLIB_CHECK_VERSION(2,27,2) static inline void @@ -33,6 +34,24 @@ g_list_free_full(GList *list, GDestroyNotify free_func) } #endif +#if !GLIB_CHECK_VERSION(2,28,0) +static inline void +g_clear_object_inline(volatile GObject **object_ptr) +{ + gpointer * const ptr = (gpointer)object_ptr; + gpointer old; + + do { + old = g_atomic_pointer_get(ptr); + } while G_UNLIKELY(!g_atomic_pointer_compare_and_exchange(ptr, old, NULL)); + + if (old) + g_object_unref(old); +} +#undef g_clear_object +#define g_clear_object(obj) g_clear_object_inline((volatile GObject **)(obj)) +#endif + #if GLIB_CHECK_VERSION(2,31,2) #define GStaticMutex GMutex #undef g_static_mutex_init diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 9b1bf1ad39..52e81e4020 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -158,10 +158,7 @@ gst_vaapi_context_destroy_surfaces(GstVaapiContext *context) priv->surfaces = NULL; } - if (priv->surfaces_pool) { - g_object_unref(priv->surfaces_pool); - priv->surfaces_pool = NULL; - } + g_clear_object(&priv->surfaces_pool); } static void diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 01e19fcd3d..e113f71e75 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -352,10 +352,7 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) klass->close_display(display); } - if (priv->parent) { - g_object_unref(priv->parent); - priv->parent = NULL; - } + g_clear_object(&priv->parent); if (g_display_cache) { gst_vaapi_display_cache_remove(get_display_cache(), display); @@ -408,8 +405,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) info.va_display ); if (cached_info) { - if (priv->parent) - g_object_unref(priv->parent); + g_clear_object(&priv->parent); priv->parent = g_object_ref(cached_info->display); } diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index ec8286e7ed..ad3d139b09 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -71,10 +71,7 @@ gst_vaapi_object_finalize(GObject *object) priv->id = GST_VAAPI_ID_NONE; - if (priv->display) { - g_object_unref(priv->display); - priv->display = NULL; - } + g_clear_object(&priv->display); G_OBJECT_CLASS(gst_vaapi_object_parent_class)->finalize(object); } diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 11a94f101d..cfd7fd3a38 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -79,10 +79,7 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) GST_VAAPI_OBJECT_ID(subpicture) = VA_INVALID_ID; } - if (priv->image) { - g_object_unref(priv->image); - priv->image = NULL; - } + g_clear_object(&priv->image); } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 65c4b28eed..b471de7d42 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -444,10 +444,7 @@ gst_vaapi_surface_set_parent_context( priv = surface->priv; - if (priv->parent_context) { - g_object_unref(priv->parent_context); - priv->parent_context = NULL; - } + g_clear_object(&priv->parent_context); if (context) priv->parent_context = g_object_ref(context); diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 3c2f2299ce..aa4103e068 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -260,10 +260,7 @@ gst_vaapi_surface_proxy_set_context( priv = proxy->priv; - if (priv->context) { - g_object_unref(priv->context); - priv->context = NULL; - } + g_clear_object(&priv->context); if (context) priv->context = g_object_ref(context); diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 81176ffb4e..7d80e5010c 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -58,10 +58,7 @@ set_display(GstVaapiVideoBuffer *buffer, GstVaapiDisplay *display) { GstVaapiVideoBufferPrivate * const priv = buffer->priv; - if (priv->display) { - g_object_unref(priv->display); - priv->display = NULL; - } + g_clear_object(&priv->display); if (display) priv->display = g_object_ref(display); @@ -94,10 +91,7 @@ gst_vaapi_video_buffer_destroy_image(GstVaapiVideoBuffer *buffer) priv->image = NULL; } - if (priv->image_pool) { - g_object_unref(priv->image_pool); - priv->image_pool = NULL; - } + g_clear_object(&priv->image_pool); } static void @@ -105,10 +99,7 @@ gst_vaapi_video_buffer_destroy_surface(GstVaapiVideoBuffer *buffer) { GstVaapiVideoBufferPrivate * const priv = buffer->priv; - if (priv->proxy) { - g_object_unref(priv->proxy); - priv->proxy = NULL; - } + g_clear_object(&priv->proxy); if (priv->surface) { if (priv->surface_pool) @@ -118,10 +109,7 @@ gst_vaapi_video_buffer_destroy_surface(GstVaapiVideoBuffer *buffer) priv->surface = NULL; } - if (priv->surface_pool) { - g_object_unref(priv->surface_pool); - priv->surface_pool = NULL; - } + g_clear_object(&priv->surface_pool); if (priv->buffer) { gst_buffer_unref(priv->buffer); diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index 106b8ea893..0ea968fb87 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -44,10 +44,7 @@ gst_vaapi_video_converter_glx_dispose(GObject *object) GstVaapiVideoConverterGLXPrivate *priv = GST_VAAPI_VIDEO_CONVERTER_GLX (object)->priv; - if (priv->texture) - g_object_unref (priv->texture); - - priv->texture = NULL; + g_clear_object(&priv->texture); G_OBJECT_CLASS (gst_vaapi_video_converter_glx_parent_class)->dispose (object); } diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index e10648354f..ea24befd90 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -95,10 +95,7 @@ gst_vaapi_video_pool_destroy(GstVaapiVideoPool *pool) priv->caps = NULL; } - if (priv->display) { - g_object_unref(priv->display); - priv->display = NULL; - } + g_clear_object(&priv->display); } static void From dba174906a856f47cf86c8594f56780b6550b6ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Fri, 29 Jun 2012 15:19:51 +0900 Subject: [PATCH 0723/3781] libs: declare _get_type() functions as const. Declaring a function as const enables better optimization of calls to the function. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapicodec_objects.h | 8 ++++---- gst-libs/gst/vaapi/gstvaapicontext.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_dpb.h | 4 ++-- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 4 ++-- gst-libs/gst/vaapi/gstvaapidecoder_vc1.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapiimage.h | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.h | 2 +- gst-libs/gst/vaapi/gstvaapiobject.h | 2 +- gst-libs/gst/vaapi/gstvaapiparamspecs.h | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.h | 2 +- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 2 +- gst-libs/gst/vaapi/gstvaapitexture.h | 2 +- gst-libs/gst/vaapi/gstvaapivalue.h | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.h | 2 +- gst-libs/gst/vaapi/gstvaapivideosink.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 2 +- 32 files changed, 37 insertions(+), 37 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index 8fb0c15ccb..f1e846d0f0 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -110,7 +110,7 @@ struct _GstVaapiCodecObjectClass { }; GType -gst_vaapi_codec_object_get_type(void) +gst_vaapi_codec_object_get_type(void) G_GNUC_CONST attribute_hidden; GstVaapiCodecObject * @@ -185,7 +185,7 @@ struct _GstVaapiIqMatrixClass { }; GType -gst_vaapi_iq_matrix_get_type(void) +gst_vaapi_iq_matrix_get_type(void) G_GNUC_CONST attribute_hidden; GstVaapiIqMatrix * @@ -251,7 +251,7 @@ struct _GstVaapiBitPlaneClass { }; GType -gst_vaapi_bitplane_get_type(void) +gst_vaapi_bitplane_get_type(void) G_GNUC_CONST attribute_hidden; GstVaapiBitPlane * @@ -314,7 +314,7 @@ struct _GstVaapiHuffmanTableClass { }; GType -gst_vaapi_huffman_table_get_type(void) +gst_vaapi_huffman_table_get_type(void) G_GNUC_CONST attribute_hidden; GstVaapiHuffmanTable * diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 78f9b28289..1187c400d1 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -82,7 +82,7 @@ struct _GstVaapiContextClass { }; GType -gst_vaapi_context_get_type(void); +gst_vaapi_context_get_type(void) G_GNUC_CONST; GstVaapiContext * gst_vaapi_context_new( diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 910dfc5fb1..f365b931a8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -115,7 +115,7 @@ struct _GstVaapiDecoderClass { }; GType -gst_vaapi_decoder_get_type(void); +gst_vaapi_decoder_get_type(void) G_GNUC_CONST; GstCaps * gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h index 1a199b8949..db43811e20 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h @@ -92,7 +92,7 @@ struct _GstVaapiDpbClass { }; GType -gst_vaapi_dpb_get_type(void) +gst_vaapi_dpb_get_type(void) G_GNUC_CONST attribute_hidden; void @@ -171,7 +171,7 @@ struct _GstVaapiDpbMpeg2Class { }; GType -gst_vaapi_dpb_mpeg2_get_type(void) +gst_vaapi_dpb_mpeg2_get_type(void) G_GNUC_CONST attribute_hidden; GstVaapiDpb * diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h index 746d16d1e0..01e667f394 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h @@ -77,7 +77,7 @@ struct _GstVaapiDecoderFfmpegClass { }; GType -gst_vaapi_decoder_ffmpeg_get_type(void); +gst_vaapi_decoder_ffmpeg_get_type(void) G_GNUC_CONST; GstVaapiDecoder * gst_vaapi_decoder_ffmpeg_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h index 5ba47763d4..79a08f174a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -77,7 +77,7 @@ struct _GstVaapiDecoderH264Class { }; GType -gst_vaapi_decoder_h264_get_type(void); +gst_vaapi_decoder_h264_get_type(void) G_GNUC_CONST; GstVaapiDecoder * gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h index 68dab506fa..cd3b975d67 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h @@ -77,7 +77,7 @@ struct _GstVaapiDecoderJpegClass { }; GType -gst_vaapi_decoder_jpeg_get_type(void); +gst_vaapi_decoder_jpeg_get_type(void) G_GNUC_CONST; GstVaapiDecoder * gst_vaapi_decoder_jpeg_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h index 98368331e0..e438c39654 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h @@ -78,7 +78,7 @@ struct _GstVaapiDecoderMpeg2Class { }; GType -gst_vaapi_decoder_mpeg2_get_type(void); +gst_vaapi_decoder_mpeg2_get_type(void) G_GNUC_CONST; GstVaapiDecoder * gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h index 753c60d377..4c877bbae8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h @@ -78,7 +78,7 @@ struct _GstVaapiDecoderMpeg4Class { }; GType -gst_vaapi_decoder_mpeg4_get_type(void); +gst_vaapi_decoder_mpeg4_get_type(void) G_GNUC_CONST; GstVaapiDecoder * gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 56a6fde37a..0e33f07624 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -164,7 +164,7 @@ struct _GstVaapiPictureClass { }; GType -gst_vaapi_picture_get_type(void) +gst_vaapi_picture_get_type(void) G_GNUC_CONST attribute_hidden; GstVaapiPicture * @@ -263,7 +263,7 @@ struct _GstVaapiSliceClass { }; GType -gst_vaapi_slice_get_type(void) +gst_vaapi_slice_get_type(void) G_GNUC_CONST attribute_hidden; GstVaapiSlice * diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h index f443a4997f..1bed6067c9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h @@ -78,7 +78,7 @@ struct _GstVaapiDecoderVC1Class { }; GType -gst_vaapi_decoder_vc1_get_type(void); +gst_vaapi_decoder_vc1_get_type(void) G_GNUC_CONST; GstVaapiDecoder * gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 33d7a234e6..7be56cae43 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -122,7 +122,7 @@ struct _GstVaapiDisplayClass { }; GType -gst_vaapi_display_get_type(void); +gst_vaapi_display_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_display_new_with_display(VADisplay va_display); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index b7135a6800..6f115e5096 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -77,7 +77,7 @@ struct _GstVaapiDisplayGLXClass { }; GType -gst_vaapi_display_glx_get_type(void); +gst_vaapi_display_glx_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_display_glx_new(const gchar *display_name); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index ab6d0ec4c4..a651dd6705 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -84,7 +84,7 @@ struct _GstVaapiDisplayX11Class { }; GType -gst_vaapi_display_x11_get_type(void); +gst_vaapi_display_x11_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_display_x11_new(const gchar *display_name); diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 3178b68ba4..d0c3cf3053 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -121,7 +121,7 @@ struct _GstVaapiImageRaw { }; GType -gst_vaapi_image_get_type(void); +gst_vaapi_image_get_type(void) G_GNUC_CONST; GstVaapiImage * gst_vaapi_image_new( diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index 139a8505e2..2478c470b4 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -78,7 +78,7 @@ struct _GstVaapiImagePoolClass { }; GType -gst_vaapi_image_pool_get_type(void); +gst_vaapi_image_pool_get_type(void) G_GNUC_CONST; GstVaapiVideoPool * gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index fbb4aef76e..913cac8690 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -82,7 +82,7 @@ struct _GstVaapiObjectClass { }; GType -gst_vaapi_object_get_type(void); +gst_vaapi_object_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_object_get_display(GstVaapiObject *object); diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.h b/gst-libs/gst/vaapi/gstvaapiparamspecs.h index b22416e9d0..5b201496ff 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.h +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.h @@ -55,7 +55,7 @@ struct _GstVaapiParamSpecID { GstVaapiParamSpecID)) GType -gst_vaapi_param_spec_id_get_type(void); +gst_vaapi_param_spec_id_get_type(void) G_GNUC_CONST; GParamSpec * gst_vaapi_param_spec_id( diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 7a0dd96a84..e7a6dbfdca 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -81,7 +81,7 @@ struct _GstVaapiSubpictureClass { }; GType -gst_vaapi_subpicture_get_type(void); +gst_vaapi_subpicture_get_type(void) G_GNUC_CONST; GstVaapiSubpicture * gst_vaapi_subpicture_new(GstVaapiImage *image); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 9057290b49..9f51caa3fa 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -168,7 +168,7 @@ struct _GstVaapiSurfaceClass { }; GType -gst_vaapi_surface_get_type(void); +gst_vaapi_surface_get_type(void) G_GNUC_CONST; GstVaapiSurface * gst_vaapi_surface_new( diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 1a7c30a535..2bb661c884 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -78,7 +78,7 @@ struct _GstVaapiSurfacePoolClass { }; GType -gst_vaapi_surface_pool_get_type(void); +gst_vaapi_surface_pool_get_type(void) G_GNUC_CONST; GstVaapiVideoPool * gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index b32458c76b..35e38f7c0b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -117,7 +117,7 @@ struct _GstVaapiSurfaceProxyClass { }; GType -gst_vaapi_surface_proxy_get_type(void); +gst_vaapi_surface_proxy_get_type(void) G_GNUC_CONST; GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface); diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 1b67a5b1b5..4f8f3ce379 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -81,7 +81,7 @@ struct _GstVaapiTextureClass { }; GType -gst_vaapi_texture_get_type(void); +gst_vaapi_texture_get_type(void) G_GNUC_CONST; GstVaapiTexture * gst_vaapi_texture_new( diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index a3834d2d98..a5a52bec28 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -45,7 +45,7 @@ G_BEGIN_DECLS #define GST_VAAPI_VALUE_HOLDS_ID(x) (G_VALUE_HOLDS((x), GST_VAAPI_TYPE_ID)) GType -gst_vaapi_id_get_type(void); +gst_vaapi_id_get_type(void) G_GNUC_CONST; GstVaapiID gst_vaapi_value_get_id(const GValue *value); diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index 520191c4d7..04c5ba4f5f 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -83,7 +83,7 @@ struct _GstVaapiVideoBufferClass { }; GType -gst_vaapi_video_buffer_get_type(void); +gst_vaapi_video_buffer_get_type(void) G_GNUC_CONST; GstBuffer * gst_vaapi_video_buffer_new(GstVaapiDisplay *display); diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h index 48bf084173..af0a05c000 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h @@ -78,7 +78,7 @@ struct _GstVaapiVideoBufferGLXClass { GstVaapiVideoBufferClass parent_class; }; -GType gst_vaapi_video_buffer_glx_get_type (void); +GType gst_vaapi_video_buffer_glx_get_type (void) G_GNUC_CONST; GstBuffer *gst_vaapi_video_buffer_glx_new (GstVaapiDisplayGLX * display); GstBuffer *gst_vaapi_video_buffer_glx_new_from_pool (GstVaapiVideoPool * pool); GstBuffer *gst_vaapi_video_buffer_glx_new_from_buffer (GstBuffer * buffer); diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h index 012bb13761..0215444d49 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h @@ -61,7 +61,7 @@ struct _GstVaapiVideoConverterGLXClass { GObjectClass parent_class; }; -GType gst_vaapi_video_converter_glx_get_type (void); +GType gst_vaapi_video_converter_glx_get_type (void) G_GNUC_CONST; GstSurfaceConverter *gst_vaapi_video_converter_glx_new (GstSurfaceBuffer *buffer, const gchar *type, diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 12266178ec..f2fdb5e5cd 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -86,7 +86,7 @@ struct _GstVaapiVideoPoolClass { }; GType -gst_vaapi_video_pool_get_type(void); +gst_vaapi_video_pool_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool); diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.h b/gst-libs/gst/vaapi/gstvaapivideosink.h index e9a17b4e9c..f33ba49717 100644 --- a/gst-libs/gst/vaapi/gstvaapivideosink.h +++ b/gst-libs/gst/vaapi/gstvaapivideosink.h @@ -61,7 +61,7 @@ struct _GstVaapiVideoSinkInterface { }; GType -gst_vaapi_video_sink_get_type(void); +gst_vaapi_video_sink_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_video_sink_get_display(GstVaapiVideoSink *sink); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index f5b6ee0ea6..5fdaf812f6 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -104,7 +104,7 @@ struct _GstVaapiWindowClass { }; GType -gst_vaapi_window_get_type(void); +gst_vaapi_window_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_window_get_display(GstVaapiWindow *window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index 96b7f4e6b4..55473557c9 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -80,7 +80,7 @@ struct _GstVaapiWindowGLXClass { }; GType -gst_vaapi_window_glx_get_type(void); +gst_vaapi_window_glx_get_type(void) G_GNUC_CONST; GstVaapiWindow * gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index 9488703eef..f1f22d4780 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -95,7 +95,7 @@ struct _GstVaapiWindowX11Class { }; GType -gst_vaapi_window_x11_get_type(void); +gst_vaapi_window_x11_get_type(void) G_GNUC_CONST; GstVaapiWindow * gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height); From 5ff0837b32173ab7981c254bc25889e913a5b837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Sun, 1 Jul 2012 05:50:17 +0900 Subject: [PATCH 0724/3781] plugins: use g_clear_object() wherever applicable. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 10 ++-------- gst/vaapi/gstvaapidownload.c | 20 +++++--------------- gst/vaapi/gstvaapipostproc.c | 5 +---- gst/vaapi/gstvaapisink.c | 29 ++++++----------------------- gst/vaapi/gstvaapiupload.c | 29 +++++++---------------------- 5 files changed, 21 insertions(+), 72 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 540d15f6e3..72691331a2 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -459,10 +459,7 @@ gst_vaapidecode_finalize(GObject *object) decode->srcpad_caps = NULL; } - if (decode->display) { - g_object_unref(decode->display); - decode->display = NULL; - } + g_clear_object(&decode->display); if (decode->allowed_caps) { gst_caps_unref(decode->allowed_caps); @@ -546,10 +543,7 @@ gst_vaapidecode_change_state(GstElement *element, GstStateChange transition) break; case GST_STATE_CHANGE_READY_TO_NULL: gst_vaapidecode_destroy(decode); - if (decode->display) { - g_object_unref(decode->display); - decode->display = NULL; - } + g_clear_object(&decode->display); decode->is_ready = FALSE; break; default: diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 63f2afee8a..2358b41f01 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -222,15 +222,8 @@ gst_vaapidownload_destroy(GstVaapiDownload *download) download->allowed_caps = NULL; } - if (download->images) { - g_object_unref(download->images); - download->images = NULL; - } - - if (download->display) { - g_object_unref(download->display); - download->display = NULL; - } + g_clear_object(&download->images); + g_clear_object(&download->display); } static void @@ -319,10 +312,8 @@ gst_vaapidownload_stop(GstBaseTransform *trans) { GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - if (download->display) { - g_object_unref(download->display); - download->display = NULL; - } + g_clear_object(&download->display); + return TRUE; } @@ -531,8 +522,7 @@ gst_vaapidownload_ensure_image_pool(GstVaapiDownload *download, GstCaps *caps) download->image_format = format; download->image_width = width; download->image_height = height; - if (download->images) - g_object_unref(download->images); + g_clear_object(&download->images); download->images = gst_vaapi_image_pool_new(download->display, caps); if (!download->images) return FALSE; diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index feb5558966..0f8ebf59c3 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -213,10 +213,7 @@ gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) { gst_caps_replace(&postproc->postproc_caps, NULL); - if (postproc->display) { - g_object_unref(postproc->display); - postproc->display = NULL; - } + g_clear_object(&postproc->display); } static gboolean diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 2c7f268586..b3c8e04adf 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -229,15 +229,8 @@ gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface) static void gst_vaapisink_destroy(GstVaapiSink *sink) { - if (sink->texture) { - g_object_unref(sink->texture); - sink->texture = NULL; - } - - if (sink->display) { - g_object_unref(sink->display); - sink->display = NULL; - } + g_clear_object(&sink->texture); + g_clear_object(&sink->display); gst_caps_replace(&sink->caps, NULL); } @@ -402,10 +395,7 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) == xid) return TRUE; - if (sink->window) { - g_object_unref(sink->window); - sink->window = NULL; - } + g_clear_object(&sink->window); #if USE_VAAPISINK_GLX if (sink->use_glx) @@ -429,15 +419,9 @@ gst_vaapisink_stop(GstBaseSink *base_sink) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - if (sink->window) { - g_object_unref(sink->window); - sink->window = NULL; - } + g_clear_object(&sink->window); + g_clear_object(&sink->display); - if (sink->display) { - g_object_unref(sink->display); - sink->display = NULL; - } return TRUE; } @@ -688,8 +672,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) gst_video_buffer_get_overlay_composition(buffer); if (sink->display != gst_vaapi_video_buffer_get_display (vbuffer)) { - if (sink->display) - g_object_unref (sink->display); + g_clear_object(&sink->display); sink->display = g_object_ref (gst_vaapi_video_buffer_get_display (vbuffer)); } diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 0762279352..645756282f 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -208,20 +208,9 @@ gst_video_context_interface_init(GstVideoContextInterface *iface) static void gst_vaapiupload_destroy(GstVaapiUpload *upload) { - if (upload->images) { - g_object_unref(upload->images); - upload->images = NULL; - } - - if (upload->surfaces) { - g_object_unref(upload->surfaces); - upload->surfaces = NULL; - } - - if (upload->display) { - g_object_unref(upload->display); - upload->display = NULL; - } + g_clear_object(&upload->images); + g_clear_object(&upload->surfaces); + g_clear_object(&upload->display); } static void @@ -394,10 +383,8 @@ gst_vaapiupload_stop(GstBaseTransform *trans) { GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - if (upload->display) { - g_object_unref(upload->display); - upload->display = NULL; - } + g_clear_object(&upload->display); + return TRUE; } @@ -523,8 +510,7 @@ gst_vaapiupload_ensure_image_pool(GstVaapiUpload *upload, GstCaps *caps) if (width != upload->image_width || height != upload->image_height) { upload->image_width = width; upload->image_height = height; - if (upload->images) - g_object_unref(upload->images); + g_clear_object(&upload->images); upload->images = gst_vaapi_image_pool_new(upload->display, caps); if (!upload->images) return FALSE; @@ -545,8 +531,7 @@ gst_vaapiupload_ensure_surface_pool(GstVaapiUpload *upload, GstCaps *caps) if (width != upload->surface_width || height != upload->surface_height) { upload->surface_width = width; upload->surface_height = height; - if (upload->surfaces) - g_object_unref(upload->surfaces); + g_clear_object(&upload->surfaces); upload->surfaces = gst_vaapi_surface_pool_new(upload->display, caps); if (!upload->surfaces) return FALSE; From ba3ae6061333d63fe3454d7e9d4e92e493cbb237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Fri, 29 Jun 2012 08:45:47 +0900 Subject: [PATCH 0725/3781] plugins: declare _get_type() functions as const. Declaring a function as const enables better optimization of calls to the function. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.h | 2 +- gst/vaapi/gstvaapidownload.h | 2 +- gst/vaapi/gstvaapipostproc.h | 2 +- gst/vaapi/gstvaapisink.h | 2 +- gst/vaapi/gstvaapiupload.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 6a5792dff1..60b2515524 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -82,7 +82,7 @@ struct _GstVaapiDecodeClass { }; GType -gst_vaapidecode_get_type(void); +gst_vaapidecode_get_type(void) G_GNUC_CONST; G_END_DECLS diff --git a/gst/vaapi/gstvaapidownload.h b/gst/vaapi/gstvaapidownload.h index 70df9b9a9d..7a594c4d85 100644 --- a/gst/vaapi/gstvaapidownload.h +++ b/gst/vaapi/gstvaapidownload.h @@ -60,7 +60,7 @@ typedef struct _GstVaapiDownload GstVaapiDownload; typedef struct _GstVaapiDownloadClass GstVaapiDownloadClass; GType -gst_vaapidownload_get_type(void); +gst_vaapidownload_get_type(void) G_GNUC_CONST; G_END_DECLS diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 281d2863a8..6ec56d1c5f 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -116,7 +116,7 @@ struct _GstVaapiPostprocClass { }; GType -gst_vaapipostproc_get_type(void); +gst_vaapipostproc_get_type(void) G_GNUC_CONST; G_END_DECLS diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index b7c06d8091..b22a8d39ee 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -92,7 +92,7 @@ struct _GstVaapiSinkClass { }; GType -gst_vaapisink_get_type(void); +gst_vaapisink_get_type(void) G_GNUC_CONST; G_END_DECLS diff --git a/gst/vaapi/gstvaapiupload.h b/gst/vaapi/gstvaapiupload.h index 425054ec08..386a62c3c2 100644 --- a/gst/vaapi/gstvaapiupload.h +++ b/gst/vaapi/gstvaapiupload.h @@ -85,7 +85,7 @@ struct _GstVaapiUploadClass { }; GType -gst_vaapiupload_get_type(void); +gst_vaapiupload_get_type(void) G_GNUC_CONST; G_END_DECLS From 768956901609122030a96dada77eb9757042e3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Sun, 1 Jul 2012 05:55:05 +0900 Subject: [PATCH 0726/3781] configure: bump glib required version to 2.28. Signed-off-by: Gwenole Beauchesne --- configure.ac | 6 ++++-- debian.upstream/control.in | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 4bef5b32be..5aac8c52f6 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) # glib version number m4_define([glib_major_version], [2]) -m4_define([glib_minor_version], [4]) +m4_define([glib_minor_version], [28]) m4_define([glib_micro_version], [0]) m4_define([glib_major_minor_version], [glib_major_version.glib_minor_version]) @@ -161,7 +161,9 @@ AM_CONDITIONAL([ENABLE_GTK_DOC], [false])]) AC_SUBST(GTKDOC_VERSION) dnl Check for GLib -PKG_CHECK_MODULES([GLIB], [glib-2.0 >= glib_version]) +GLIB_VERSION_REQUIRED=glib_version +PKG_CHECK_MODULES([GLIB], [glib-2.0 >= $GLIB_VERSION_REQUIRED]) +AC_SUBST(GLIB_VERSION_REQUIRED) dnl Check for GStreamer PKG_CHECK_MODULES([GST], diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 9ef5de6290..5f23160ce1 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -4,7 +4,7 @@ Priority: optional Maintainer: Gwenole Beauchesne Build-Depends: debhelper (>= 5), cdbs, - libglib2.0-dev, + libglib2.0-dev (>= @GLIB_VERSION_REQUIRED@), libgstreamer@GST_MAJORMINOR@-dev (>= @GST_VERSION_REQUIRED@), libgstreamer-plugins-base@GST_MAJORMINOR@-dev (>= @GST_PLUGINS_BASE_VERSION_REQUIRED@), libva-dev (>= @LIBVA_PACKAGE_VERSION@) From 7f47ac3bea8e703f0d998d318e58606bf1a14560 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jul 2012 17:00:36 +0200 Subject: [PATCH 0727/3781] Drop FFmpeg-based decoders. GStreamer codecparsers-based decoders are the only supported decoders now. Though, FFmpeg decoders are still available in gstreamer-vaapi 0.3.x series. --- NEWS | 6 +- configure.ac | 30 +- docs/reference/libs/libs-sections.txt | 16 - docs/reference/libs/libs.core.types | 1 - gst-libs/gst/vaapi/Makefile.am | 8 - gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 696 -------------------- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h | 87 --- gst/vaapi/gstvaapidecode.c | 74 --- gst/vaapi/gstvaapidecode.h | 1 - tests/test-decode.c | 23 - tests/test-subpicture.c | 7 - 11 files changed, 5 insertions(+), 944 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c delete mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h diff --git a/NEWS b/NEWS index 6f0bb8859a..118610ae40 100644 --- a/NEWS +++ b/NEWS @@ -1,10 +1,10 @@ -gst-vaapi NEWS -- summary of changes. 2012-07-DD +gst-vaapi NEWS -- summary of changes. 2012-08-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora -Version 0.3.8 - DD.Jul.2012 -* Disable FFmpeg-based decoders by default +Version 0.4.0 - DD.Aug.2012 +* Drop FFmpeg-based decoders Version 0.3.7 - 26.Jun.2012 * Fix vaapidecode to report unsupported codec profiles diff --git a/configure.ac b/configure.ac index 5aac8c52f6..9fc8a51361 100644 --- a/configure.ac +++ b/configure.ac @@ -113,11 +113,6 @@ AC_ARG_ENABLE(vaapisink-glx, [enable OpenGL/X11 to vaapisink @<:@default=yes@:>@]), [], [enable_vaapisink_glx="no"]) -AC_ARG_ENABLE(ffmpeg, - AS_HELP_STRING([--enable-ffmpeg], - [enable bitstream parsing from FFmpeg @<:@default=no@:>@]), - [], [enable_ffmpeg="no"]) - AC_ARG_ENABLE(codecparsers, AS_HELP_STRING([--enable-codecparsers], [enable adhoc bitstream parsers from GStreamer @<:@default=yes@:>@]), @@ -446,29 +441,9 @@ else USE_VAAPISINK_GLX=0 fi -dnl Check for FFmpeg -USE_FFMPEG=0 -if test "$enable_ffmpeg" = "yes"; then -PKG_CHECK_MODULES(LIBAVCODEC, [libavcodec], - [enable_ffmpeg="yes" USE_FFMPEG=1], - [enable_ffmpeg="no" USE_FFMPEG=0] -) +if test "$enable_codecparsers" = "no"; then + AC_MSG_ERROR([Found no suitable GStreamer bitstream parsers]) fi -if test "$enable_ffmpeg" = "yes"; then -AC_CHECK_HEADERS([libavcodec/avcodec.h ffmpeg/avcodec.h]) -AC_CHECK_HEADERS([libavcodec/vaapi.h ffmpeg/vaapi.h], - [break], - [enable_ffmpeg="no" USE_FFMPEG=0] -) -fi - -if test "$enable_ffmpeg:$enable_codecparsers" = "no:no"; then - AC_MSG_ERROR([Found neither suitable FFmpeg with VA-API support nor GStreamer bitstream parsers]) -fi - -AC_DEFINE_UNQUOTED(USE_FFMPEG, $USE_FFMPEG, - [Defined to 1 if FFmpeg is used]) -AM_CONDITIONAL(USE_FFMPEG, test $USE_FFMPEG -eq 1) AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) @@ -543,6 +518,5 @@ echo VA-API version ................... : $VA_VERSION_STR echo GLX support ...................... : $(yesno $USE_GLX) echo VA/GLX support ................... : $(yesno $USE_VAAPI_GLX) echo VaapiSink/GL ..................... : $(yesno $USE_VAAPISINK_GLX) -echo FFmpeg bitstream parsers ......... : $(yesno $USE_FFMPEG) echo GStreamer bitstream parsers ...... : $(yesno $USE_CODEC_PARSERS) echo diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index afcb793837..cfe63a4347 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -472,22 +472,6 @@ GST_VAAPI_IS_DECODER_CLASS GST_VAAPI_DECODER_GET_CLASS
-
-gstvaapidecoder_ffmpeg -GstVaapiDecoderFfmpeg -GstVaapiDecoderFfmpeg -GstVaapiDecoderFfmpegClass -gst_vaapi_decoder_ffmpeg_new - -GST_VAAPI_DECODER_FFMPEG -GST_VAAPI_IS_DECODER_FFMPEG -GST_VAAPI_TYPE_DECODER_FFMPEG -gst_vaapi_decoder_ffmpeg_get_type -GST_VAAPI_DECODER_FFMPEG_CLASS -GST_VAAPI_IS_DECODER_FFMPEG_CLASS -GST_VAAPI_DECODER_FFMPEG_GET_CLASS -
-
gstvaapidecoder_mpeg2 GstVaapiDecoderMpeg2 diff --git a/docs/reference/libs/libs.core.types b/docs/reference/libs/libs.core.types index 34a8f2ffb5..b779fd6359 100644 --- a/docs/reference/libs/libs.core.types +++ b/docs/reference/libs/libs.core.types @@ -1,6 +1,5 @@ gst_vaapi_context_get_type gst_vaapi_decoder_get_type -gst_vaapi_decoder_ffmpeg_get_type gst_vaapi_display_get_type gst_vaapi_image_get_type gst_vaapi_image_pool_get_type diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 9c6f846d8a..acced92ee8 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -89,7 +89,6 @@ libgstvaapi_source_priv_h = \ gstvaapivideobuffer_priv.h \ gstvaapiworkarounds.h \ sysdeps.h \ - $(libgst_vaapi_ffmpeg_source_priv_h) \ $(NULL) libgstvaapi_x11_source_c = \ @@ -138,13 +137,6 @@ libgstvaapi_glx_source_priv_h = \ gstvaapiutils_x11.h \ $(NULL) -if USE_FFMPEG -libgstvaapi_source_c += gstvaapidecoder_ffmpeg.c -libgstvaapi_source_h += gstvaapidecoder_ffmpeg.h -libgstvaapi_cflags += $(LIBAVCODEC_CFLAGS) -libgstvaapi_libs += $(LIBAVCODEC_LIBS) -endif - if USE_CODEC_PARSERS libgstvaapi_source_c += \ gstvaapicodec_objects.c \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c deleted file mode 100644 index 2d4d55017a..0000000000 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * gstvaapidecoder_ffmpeg.c - FFmpeg-based decoder - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation - * - * 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_ffmpeg - * @short_description: FFmpeg-based decoder - */ - -#include "sysdeps.h" -#ifdef HAVE_LIBAVCODEC_AVCODEC_H -# include -#endif -#ifdef HAVE_FFMPEG_AVCODEC_H -# include -#endif -#ifdef HAVE_LIBAVCODEC_VAAPI_H -# include -#endif -#ifdef HAVE_FFMPEG_VAAPI_H -# include -#endif -#include "gstvaapidecoder_ffmpeg.h" -#include "gstvaapidecoder_priv.h" -#include "gstvaapidisplay_priv.h" -#include "gstvaapiobject_priv.h" - -#define DEBUG 1 -#include "gstvaapidebug.h" - -G_DEFINE_TYPE(GstVaapiDecoderFfmpeg, - gst_vaapi_decoder_ffmpeg, - GST_VAAPI_TYPE_DECODER); - -#define GST_VAAPI_DECODER_FFMPEG_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DECODER_FFMPEG, \ - GstVaapiDecoderFfmpegPrivate)) - -typedef struct _GstVaapiContextFfmpeg GstVaapiContextFfmpeg; -struct _GstVaapiContextFfmpeg { - struct vaapi_context base; - GstVaapiProfile profile; - GstVaapiEntrypoint entrypoint; - GstVaapiDecoderFfmpeg *decoder; -}; - -struct _GstVaapiDecoderFfmpegPrivate { - GstClockTime in_timestamp; /* timestamp from the demuxer */ - AVFrame *frame; - AVCodecParserContext *pctx; - AVCodecContext *avctx; - GstVaapiContextFfmpeg *vactx; - guint is_constructed : 1; - guint is_opened : 1; -}; - -/** Converts codec to FFmpeg codec id */ -static enum CodecID -get_codec_id_from_codec(GstVaapiCodec codec) -{ - switch (codec) { - case GST_VAAPI_CODEC_MPEG1: return CODEC_ID_MPEG1VIDEO; - case GST_VAAPI_CODEC_MPEG2: return CODEC_ID_MPEG2VIDEO; - case GST_VAAPI_CODEC_MPEG4: return CODEC_ID_MPEG4; - case GST_VAAPI_CODEC_H263: return CODEC_ID_H263; - case GST_VAAPI_CODEC_H264: return CODEC_ID_H264; - case GST_VAAPI_CODEC_WMV3: return CODEC_ID_WMV3; - case GST_VAAPI_CODEC_VC1: return CODEC_ID_VC1; - } - return CODEC_ID_NONE; -} - -/** Converts PixelFormat to entrypoint */ -static GstVaapiEntrypoint -get_entrypoint(enum PixelFormat pix_fmt) -{ - switch (pix_fmt) { - case PIX_FMT_VAAPI_VLD: return GST_VAAPI_ENTRYPOINT_VLD; - case PIX_FMT_VAAPI_IDCT: return GST_VAAPI_ENTRYPOINT_IDCT; - case PIX_FMT_VAAPI_MOCO: return GST_VAAPI_ENTRYPOINT_MOCO; - default: break; - } - return 0; -} - -/** Finds a suitable profile from FFmpeg context */ -static GstVaapiProfile -get_profile(AVCodecContext *avctx, GstVaapiEntrypoint entrypoint) -{ - GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; - GstVaapiDisplay *display; - GstVaapiProfile profiles[4]; - guint i, n_profiles = 0; - -#define ADD_PROFILE(profile) do { \ - profiles[n_profiles++] = GST_VAAPI_PROFILE_##profile; \ - } while (0) - - switch (avctx->codec_id) { - case CODEC_ID_MPEG1VIDEO: - ADD_PROFILE(MPEG1); - break; - case CODEC_ID_MPEG2VIDEO: - ADD_PROFILE(MPEG2_MAIN); - ADD_PROFILE(MPEG2_SIMPLE); - break; - case CODEC_ID_H263: - ADD_PROFILE(H263_BASELINE); - /* fall-through */ - case CODEC_ID_MPEG4: - ADD_PROFILE(MPEG4_MAIN); - ADD_PROFILE(MPEG4_ADVANCED_SIMPLE); - ADD_PROFILE(MPEG4_SIMPLE); - break; - case CODEC_ID_H264: - if (avctx->profile == 66) /* baseline */ - ADD_PROFILE(H264_BASELINE); - else { - if (avctx->profile == 77) /* main */ - ADD_PROFILE(H264_MAIN); - ADD_PROFILE(H264_HIGH); - } - break; - case CODEC_ID_WMV3: - if (avctx->profile == 0) /* simple */ - ADD_PROFILE(VC1_SIMPLE); - ADD_PROFILE(VC1_MAIN); - break; - case CODEC_ID_VC1: - ADD_PROFILE(VC1_ADVANCED); - break; - default: - break; - } - -#undef ADD_PROFILE - - display = GST_VAAPI_DECODER_DISPLAY(vactx->decoder); - if (!display) - return 0; - - for (i = 0; i < n_profiles; i++) - if (gst_vaapi_display_has_decoder(display, profiles[i], entrypoint)) - return profiles[i]; - return 0; -} - -/** Ensures VA context is correctly set up for the current FFmpeg context */ -static GstVaapiContext * -get_context(AVCodecContext *avctx, AVFrame *pic) -{ - GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; - GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(vactx->decoder); - GstVaapiDisplay *display; - GstVaapiContext *context; - gboolean success; - - if (!avctx->coded_width || !avctx->coded_height) - return NULL; - - gst_vaapi_decoder_set_framerate( - decoder, - avctx->time_base.den / avctx->ticks_per_frame, - avctx->time_base.num - ); - - gst_vaapi_decoder_set_pixel_aspect_ratio( - decoder, - avctx->sample_aspect_ratio.num, - avctx->sample_aspect_ratio.den - ); - - gst_vaapi_decoder_set_interlaced(decoder, !!pic->interlaced_frame); - - success = gst_vaapi_decoder_ensure_context( - decoder, - vactx->profile, - vactx->entrypoint, - avctx->coded_width, - avctx->coded_height - ); - if (!success) { - GST_DEBUG("failed to reset VA context:"); - GST_DEBUG(" profile 0x%08x", vactx->profile); - GST_DEBUG(" entrypoint %d", vactx->entrypoint); - GST_DEBUG(" surface size %dx%d", avctx->width, avctx->height); - return NULL; - } - display = GST_VAAPI_DECODER_DISPLAY(decoder); - context = GST_VAAPI_DECODER_CONTEXT(decoder); - vactx->base.display = GST_VAAPI_DISPLAY_VADISPLAY(display); - vactx->base.context_id = GST_VAAPI_OBJECT_ID(context); - return context; -} - -/** Sets AVCodecContext.extradata with additional codec data */ -static gboolean -set_codec_data(AVCodecContext *avctx, const guchar *buf, guint buf_size) -{ - av_freep(&avctx->extradata); - avctx->extradata_size = 0; - if (!buf || buf_size < 1) - return TRUE; - - avctx->extradata = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!avctx->extradata) - return FALSE; - avctx->extradata_size = buf_size; - memcpy(avctx->extradata, buf, buf_size); - memset(avctx->extradata + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - return TRUE; -} - -/** AVCodecContext.get_format() implementation */ -static enum PixelFormat -gst_vaapi_decoder_ffmpeg_get_format(AVCodecContext *avctx, const enum PixelFormat *fmt) -{ - GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; - GstVaapiProfile profile; - GstVaapiEntrypoint entrypoint; - guint i; - - /* XXX: only VLD entrypoint is supported at this time */ - for (i = 0; fmt[i] != PIX_FMT_NONE; i++) { - entrypoint = get_entrypoint(fmt[i]); - if (entrypoint != GST_VAAPI_ENTRYPOINT_VLD) - continue; - - profile = get_profile(avctx, entrypoint); - if (profile) { - vactx->profile = profile; - vactx->entrypoint = entrypoint; - return fmt[i]; - } - } - return PIX_FMT_NONE; -} - -/** AVCodecContext.get_buffer() implementation */ -static int -gst_vaapi_decoder_ffmpeg_get_buffer(AVCodecContext *avctx, AVFrame *pic) -{ - GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; - GstVaapiContext *context; - GstVaapiSurface *surface; - GstVaapiSurfaceProxy *proxy; - GstVaapiID surface_id; - - context = get_context(avctx, pic); - if (!context) - return -1; - - surface = gst_vaapi_context_get_surface(context); - if (!surface) { - GST_DEBUG("failed to get a free VA surface"); - return -1; - } - - proxy = gst_vaapi_surface_proxy_new(context, surface); - if (!proxy) { - GST_DEBUG("failed to create proxy surface"); - gst_vaapi_context_put_surface(context, surface); - return -1; - } - - surface_id = GST_VAAPI_OBJECT_ID(surface); - GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); - - pic->type = FF_BUFFER_TYPE_USER; - pic->age = 1; - pic->data[0] = (uint8_t *)proxy; - pic->data[1] = NULL; - pic->data[2] = NULL; - pic->data[3] = (uint8_t *)(uintptr_t)surface_id; - pic->linesize[0] = 0; - pic->linesize[1] = 0; - pic->linesize[2] = 0; - pic->linesize[3] = 0; - pic->pts = vactx->decoder->priv->in_timestamp; - return 0; -} - -/** AVCodecContext.reget_buffer() implementation */ -static int -gst_vaapi_decoder_ffmpeg_reget_buffer(AVCodecContext *avctx, AVFrame *pic) -{ - GST_DEBUG("UNIMPLEMENTED"); - return -1; -} - -/** AVCodecContext.release_buffer() implementation */ -static void -gst_vaapi_decoder_ffmpeg_release_buffer(AVCodecContext *avctx, AVFrame *pic) -{ - GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(pic->data[0]); - GstVaapiID surface_id = GST_VAAPI_ID(GPOINTER_TO_UINT(pic->data[3])); - - GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); - - g_object_unref(proxy); - - pic->data[0] = NULL; - pic->data[1] = NULL; - pic->data[2] = NULL; - pic->data[3] = NULL; -} - -static void -gst_vaapi_decoder_ffmpeg_close(GstVaapiDecoderFfmpeg *ffdecoder) -{ - GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - - if (priv->avctx) { - if (priv->is_opened) { - avcodec_close(priv->avctx); - priv->is_opened = FALSE; - } - av_freep(&priv->avctx->extradata); - priv->avctx->extradata_size = 0; - } - - if (priv->pctx) { - av_parser_close(priv->pctx); - priv->pctx = NULL; - } -} - -static gboolean -gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffer) -{ - GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(ffdecoder); - GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(ffdecoder); - GstVaapiCodec codec = GST_VAAPI_DECODER_CODEC(ffdecoder); - enum CodecID codec_id; - AVCodec *ffcodec; - gboolean try_parser, need_parser; - int ret; - - gst_vaapi_decoder_ffmpeg_close(ffdecoder); - - if (codec_data) { - const guchar *data = GST_BUFFER_DATA(codec_data); - const guint size = GST_BUFFER_SIZE(codec_data); - if (!set_codec_data(priv->avctx, data, size)) - return FALSE; - } - - codec_id = get_codec_id_from_codec(codec); - if (codec_id == CODEC_ID_NONE) - return FALSE; - - ffcodec = avcodec_find_decoder(codec_id); - if (!ffcodec) - return FALSE; - - switch (codec_id) { - case CODEC_ID_H264: - /* For AVC1 formats, sequence headers are in extradata and - input encoded buffers represent the whole NAL unit */ - try_parser = priv->avctx->extradata_size == 0; - need_parser = try_parser; - break; - case CODEC_ID_WMV3: - /* There is no WMV3 parser in FFmpeg */ - try_parser = FALSE; - need_parser = FALSE; - break; - case CODEC_ID_VC1: - /* For VC-1, sequence headers ae in extradata and input encoded - buffers represent the whole slice */ - try_parser = priv->avctx->extradata_size == 0; - need_parser = FALSE; - break; - default: - try_parser = TRUE; - need_parser = TRUE; - break; - } - - if (try_parser) { - priv->pctx = av_parser_init(codec_id); - if (!priv->pctx && need_parser) - return FALSE; - } - - /* XXX: av_find_stream_info() does this and some codecs really - want hard an extradata buffer for initialization (e.g. VC-1) */ - if (!priv->avctx->extradata && priv->pctx && priv->pctx->parser->split) { - const guchar *buf = GST_BUFFER_DATA(buffer); - guint buf_size = GST_BUFFER_SIZE(buffer); - buf_size = priv->pctx->parser->split(priv->avctx, buf, buf_size); - if (buf_size > 0 && !set_codec_data(priv->avctx, buf, buf_size)) - return FALSE; - } - - if (priv->pctx && !need_parser) { - av_parser_close(priv->pctx); - priv->pctx = NULL; - } - - /* Use size information from the demuxer, whenever available */ - priv->avctx->coded_width = GST_VAAPI_DECODER_WIDTH(ffdecoder); - priv->avctx->coded_height = GST_VAAPI_DECODER_HEIGHT(ffdecoder); - - GST_VAAPI_DISPLAY_LOCK(display); - ret = avcodec_open(priv->avctx, ffcodec); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (ret < 0) - return FALSE; - return TRUE; -} - -static void -gst_vaapi_decoder_ffmpeg_destroy(GstVaapiDecoderFfmpeg *ffdecoder) -{ - GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - - gst_vaapi_decoder_ffmpeg_close(ffdecoder); - - if (priv->vactx) { - g_free(priv->vactx); - priv->vactx = NULL; - } - - av_freep(&priv->avctx); - av_freep(&priv->frame); -} - -static gboolean -gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) -{ - GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - - if (!GST_VAAPI_DECODER_CODEC(ffdecoder)) - return FALSE; - - if (!priv->frame) { - priv->frame = avcodec_alloc_frame(); - if (!priv->frame) - return FALSE; - } - - if (!priv->avctx) { - priv->avctx = avcodec_alloc_context(); - if (!priv->avctx) - return FALSE; - } - - if (!priv->vactx) { - priv->vactx = g_new(GstVaapiContextFfmpeg, 1); - if (!priv->vactx) - return FALSE; - } - memset(&priv->vactx->base, 0, sizeof(priv->vactx->base)); - priv->vactx->decoder = ffdecoder; - - priv->avctx->hwaccel_context = priv->vactx; - priv->avctx->get_format = gst_vaapi_decoder_ffmpeg_get_format; - priv->avctx->get_buffer = gst_vaapi_decoder_ffmpeg_get_buffer; - priv->avctx->reget_buffer = gst_vaapi_decoder_ffmpeg_reget_buffer; - priv->avctx->release_buffer = gst_vaapi_decoder_ffmpeg_release_buffer; - priv->avctx->thread_count = 1; - priv->avctx->draw_horiz_band = NULL; - priv->avctx->slice_flags = SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; - return TRUE; -} - -static GstVaapiDecoderStatus -render_frame(GstVaapiDecoderFfmpeg *decoder, AVFrame *frame) -{ - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); - GstVaapiSurfaceProxy *proxy; - - proxy = GST_VAAPI_SURFACE_PROXY(frame->data[0]); - if (!proxy) - return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; - - gst_vaapi_surface_proxy_set_timestamp(proxy, frame->pts); - gst_vaapi_surface_proxy_set_interlaced(proxy, !!frame->interlaced_frame); - gst_vaapi_surface_proxy_set_tff(proxy, frame->top_field_first); - gst_vaapi_decoder_push_surface_proxy(base_decoder, g_object_ref(proxy)); - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -decode_frame(GstVaapiDecoderFfmpeg *ffdecoder, guchar *buf, guint buf_size) -{ - GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(ffdecoder); - int bytes_read, got_picture = 0; - AVPacket pkt; - - av_init_packet(&pkt); - pkt.data = buf; - pkt.size = buf_size; - - GST_VAAPI_DISPLAY_LOCK(display); - bytes_read = avcodec_decode_video2( - priv->avctx, - priv->frame, - &got_picture, - &pkt - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!got_picture) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - if (bytes_read < 0) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - - return render_frame(ffdecoder, priv->frame); -} - -GstVaapiDecoderStatus -gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer) -{ - GstVaapiDecoderFfmpeg * const ffdecoder = GST_VAAPI_DECODER_FFMPEG(decoder); - GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - GstClockTime inbuf_ts; - guchar *outbuf; - gint inbuf_ofs, inbuf_size, outbuf_size; - gboolean got_frame; - - g_return_val_if_fail(priv->is_constructed, - GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); - - if (!priv->is_opened) { - priv->is_opened = gst_vaapi_decoder_ffmpeg_open(ffdecoder, buffer); - if (!priv->is_opened) - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; - } - - inbuf_ofs = 0; - inbuf_size = GST_BUFFER_SIZE(buffer); - inbuf_ts = GST_BUFFER_TIMESTAMP(buffer); - - if (priv->pctx) { - do { - int parsed_size; - parsed_size = av_parser_parse2( - priv->pctx, - priv->avctx, - &outbuf, &outbuf_size, - GST_BUFFER_DATA(buffer) + inbuf_ofs, inbuf_size, - inbuf_ts, inbuf_ts, - AV_NOPTS_VALUE - ); - got_frame = outbuf && outbuf_size > 0; - - if (parsed_size > 0) { - inbuf_ofs += parsed_size; - inbuf_size -= parsed_size; - } - } while (!got_frame && inbuf_size > 0); - inbuf_ts = priv->pctx->pts; - } - else { - outbuf = GST_BUFFER_DATA(buffer); - outbuf_size = inbuf_size; - got_frame = outbuf && outbuf_size > 0; - inbuf_ofs = inbuf_size; - inbuf_size = 0; - } - - if (inbuf_size > 0 && - !gst_vaapi_decoder_push_buffer_sub(decoder, buffer, - inbuf_ofs, inbuf_size)) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - - if (!got_frame && !GST_BUFFER_IS_EOS(buffer)) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - - priv->in_timestamp = inbuf_ts; - return decode_frame(ffdecoder, outbuf, outbuf_size); -} - -static void -gst_vaapi_decoder_ffmpeg_finalize(GObject *object) -{ - GstVaapiDecoderFfmpeg * const ffdecoder = GST_VAAPI_DECODER_FFMPEG(object); - - gst_vaapi_decoder_ffmpeg_destroy(ffdecoder); - - G_OBJECT_CLASS(gst_vaapi_decoder_ffmpeg_parent_class)->finalize(object); -} - -static void -gst_vaapi_decoder_ffmpeg_constructed(GObject *object) -{ - GstVaapiDecoderFfmpeg * const ffdecoder = GST_VAAPI_DECODER_FFMPEG(object); - GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; - GObjectClass *parent_class; - - parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_ffmpeg_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); - - priv->is_constructed = gst_vaapi_decoder_ffmpeg_create(ffdecoder); -} - -static void -gst_vaapi_decoder_ffmpeg_class_init(GstVaapiDecoderFfmpegClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiDecoderFfmpegPrivate)); - - object_class->finalize = gst_vaapi_decoder_ffmpeg_finalize; - object_class->constructed = gst_vaapi_decoder_ffmpeg_constructed; - - decoder_class->decode = gst_vaapi_decoder_ffmpeg_decode; -} - -static gpointer -gst_vaapi_decoder_ffmpeg_init_once_cb(gpointer user_data) -{ - avcodec_register_all(); - return NULL; -} - -static inline void -gst_vaapi_decoder_ffmpeg_init_once(void) -{ - static GOnce once = G_ONCE_INIT; - - g_once(&once, gst_vaapi_decoder_ffmpeg_init_once_cb, NULL); -} - -static void -gst_vaapi_decoder_ffmpeg_init(GstVaapiDecoderFfmpeg *decoder) -{ - GstVaapiDecoderFfmpegPrivate *priv; - - gst_vaapi_decoder_ffmpeg_init_once(); - - priv = GST_VAAPI_DECODER_FFMPEG_GET_PRIVATE(decoder); - decoder->priv = priv; - priv->frame = NULL; - priv->pctx = NULL; - priv->avctx = NULL; - priv->vactx = NULL; - priv->is_constructed = FALSE; - priv->is_opened = FALSE; -} - -/** - * gst_vaapi_decoder_ffmpeg_new: - * @display: a #GstVaapiDisplay - * @caps: a #GstCaps holding codec information - * - * Creates a new #GstVaapiDecoder based on FFmpeg where the codec is - * determined from @caps. The @caps can hold extra information like - * codec-data and pictured coded size. - * - * Return value: the newly allocated #GstVaapiDecoder object - */ -GstVaapiDecoder * -gst_vaapi_decoder_ffmpeg_new(GstVaapiDisplay *display, GstCaps *caps) -{ - GstVaapiDecoderFfmpeg *ffdecoder; - - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); - - ffdecoder = g_object_new( - GST_VAAPI_TYPE_DECODER_FFMPEG, - "display", display, - "caps", caps, - NULL - ); - if (!ffdecoder->priv->is_constructed) { - g_object_unref(ffdecoder); - return NULL; - } - return GST_VAAPI_DECODER_CAST(ffdecoder); -} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h deleted file mode 100644 index 01e667f394..0000000000 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * gstvaapidecoder_ffmpeg.h - FFmpeg-based decoder - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * - * 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_FFMPEG_H -#define GST_VAAPI_DECODER_FFMPEG_H - -#include - -G_BEGIN_DECLS - -#define GST_VAAPI_TYPE_DECODER_FFMPEG \ - (gst_vaapi_decoder_ffmpeg_get_type()) - -#define GST_VAAPI_DECODER_FFMPEG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DECODER_FFMPEG, \ - GstVaapiDecoderFfmpeg)) - -#define GST_VAAPI_DECODER_FFMPEG_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DECODER_FFMPEG, \ - GstVaapiDecoderFfmpegClass)) - -#define GST_VAAPI_IS_DECODER_FFMPEG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_FFMPEG)) - -#define GST_VAAPI_IS_DECODER_FFMPEG_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_FFMPEG)) - -#define GST_VAAPI_DECODER_FFMPEG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DECODER_FFMPEG, \ - GstVaapiDecoderFfmpegClass)) - -typedef struct _GstVaapiDecoderFfmpeg GstVaapiDecoderFfmpeg; -typedef struct _GstVaapiDecoderFfmpegPrivate GstVaapiDecoderFfmpegPrivate; -typedef struct _GstVaapiDecoderFfmpegClass GstVaapiDecoderFfmpegClass; - -/** - * GstVaapiDecoderFfmpeg: - * - * A decoder based on FFmpeg. - */ -struct _GstVaapiDecoderFfmpeg { - /*< private >*/ - GstVaapiDecoder parent_instance; - - GstVaapiDecoderFfmpegPrivate *priv; -}; - -/** - * GstVaapiDecoderFfmpegClass: - * - * A decoder class based on FFmpeg. - */ -struct _GstVaapiDecoderFfmpegClass { - /*< private >*/ - GstVaapiDecoderClass parent_class; -}; - -GType -gst_vaapi_decoder_ffmpeg_get_type(void) G_GNUC_CONST; - -GstVaapiDecoder * -gst_vaapi_decoder_ffmpeg_new(GstVaapiDisplay *display, GstCaps *caps); - -G_END_DECLS - -#endif /* GST_VAAPI_DECODER_FFMPEG_H */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 72691331a2..9572f23f06 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -44,9 +44,6 @@ #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" -#if USE_FFMPEG -# include -#endif #if USE_CODEC_PARSERS # include # include @@ -55,10 +52,6 @@ # include #endif -/* Favor codecparsers-based decoders for 0.3.x series */ -#define USE_FFMPEG_DEFAULT \ - (USE_FFMPEG && !USE_CODEC_PARSERS) - #define GST_PLUGIN_NAME "vaapidecode" #define GST_PLUGIN_DESC "A VA-API based video decoder" @@ -120,12 +113,6 @@ G_DEFINE_TYPE_WITH_CODE( G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init)); -enum { - PROP_0, - - PROP_USE_FFMPEG, -}; - static gboolean gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps); @@ -325,12 +312,6 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) return FALSE; dpy = decode->display; - if (decode->use_ffmpeg) { -#if USE_FFMPEG - decode->decoder = gst_vaapi_decoder_ffmpeg_new(dpy, caps); -#endif - } - else { #if USE_CODEC_PARSERS structure = gst_caps_get_structure(caps, 0); if (!structure) @@ -356,7 +337,6 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps); #endif #endif - } if (!decode->decoder) return FALSE; @@ -474,46 +454,6 @@ gst_vaapidecode_finalize(GObject *object) G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object); } -static void -gst_vaapidecode_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDecode * const decode = GST_VAAPIDECODE(object); - - switch (prop_id) { - case PROP_USE_FFMPEG: - decode->use_ffmpeg = g_value_get_boolean(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapidecode_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDecode * const decode = GST_VAAPIDECODE(object); - - switch (prop_id) { - case PROP_USE_FFMPEG: - g_value_set_boolean(value, decode->use_ffmpeg); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - static GstStateChangeReturn gst_vaapidecode_change_state(GstElement *element, GstStateChange transition) { @@ -563,8 +503,6 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapidecode_finalize; - object_class->set_property = gst_vaapidecode_set_property; - object_class->get_property = gst_vaapidecode_get_property; element_class->change_state = gst_vaapidecode_change_state; @@ -585,17 +523,6 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) pad_template = gst_static_pad_template_get(&gst_vaapidecode_src_factory); gst_element_class_add_pad_template(element_class, pad_template); gst_object_unref(pad_template); - -#if USE_FFMPEG - g_object_class_install_property - (object_class, - PROP_USE_FFMPEG, - g_param_spec_boolean("use-ffmpeg", - "Use FFmpeg/VAAPI for decoding", - "Uses FFmpeg/VAAPI for decoding", - USE_FFMPEG_DEFAULT, - G_PARAM_READWRITE)); -#endif } static gboolean @@ -781,7 +708,6 @@ gst_vaapidecode_init(GstVaapiDecode *decode) decode->decoder_caps = NULL; decode->allowed_caps = NULL; decode->delayed_new_seg = NULL; - decode->use_ffmpeg = USE_FFMPEG_DEFAULT; decode->is_ready = FALSE; /* Pad through which data comes in to the element */ diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 60b2515524..408ee08c1a 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -72,7 +72,6 @@ struct _GstVaapiDecode { GstCaps *decoder_caps; GstCaps *allowed_caps; GstEvent *delayed_new_seg; - unsigned int use_ffmpeg : 1; unsigned int is_ready : 1; }; diff --git a/tests/test-decode.c b/tests/test-decode.c index 2f496beae8..561162d32a 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -31,9 +31,6 @@ #include "test-h264.h" #include "test-vc1.h" -#if USE_FFMPEG -# include -#endif #if USE_CODEC_PARSERS # include # include @@ -79,21 +76,12 @@ static inline void pause(void) } static gchar *g_codec_str; -static gboolean g_use_ffmpeg = FALSE; static GOptionEntry g_options[] = { { "codec", 'c', 0, G_OPTION_ARG_STRING, &g_codec_str, "codec to test", NULL }, - { "ffmpeg", 0, - 0, - G_OPTION_ARG_NONE, &g_use_ffmpeg, - "use ffmpeg", NULL }, - { "codecparsers", 0, - G_OPTION_FLAG_REVERSE, - G_OPTION_ARG_NONE, &g_use_ffmpeg, - "use codec parsers", NULL }, { NULL, } }; @@ -159,14 +147,6 @@ main(int argc, char *argv[]) NULL ); - if (g_use_ffmpeg) { -#if USE_FFMPEG - decoder = gst_vaapi_decoder_ffmpeg_new(display, decoder_caps); -#else - g_error("FFmpeg-based decoders are not supported"); -#endif - } - else { #if USE_CODEC_PARSERS switch (gst_vaapi_profile_get_codec(info.profile)) { case GST_VAAPI_CODEC_H264: @@ -187,10 +167,7 @@ main(int argc, char *argv[]) decoder = NULL; break; } -#else - g_error("codecparsers-based decoders are not supported"); #endif - } if (!decoder) g_error("could not create decoder"); gst_caps_unref(decoder_caps); diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index f9f0052e41..a0e1b6fb50 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -29,9 +29,6 @@ #include "test-mpeg2.h" #include "test-subpicture-data.h" -#if USE_FFMPEG -# include -#endif #if USE_CODEC_PARSERS # include #endif @@ -154,10 +151,6 @@ main(int argc, char *argv[]) #if USE_CODEC_PARSERS decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); -#endif -#if USE_FFMPEG - if (!decoder) - decoder = gst_vaapi_decoder_ffmpeg_new(display, decoder_caps); #endif if (!decoder) g_error("could not create video decoder"); From 9d440fafb3146b0090e75a9ad03f1795e12443db Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jul 2012 17:16:28 +0200 Subject: [PATCH 0728/3781] Drop all references to USE_CODEC_PARSERS. --- configure.ac | 51 ++++++++++--------------------- gst-libs/gst/vaapi/Makefile.am | 41 ++++++++++--------------- gst/vaapi/gstvaapidecode.c | 55 ++++++++++++++++------------------ tests/test-decode.c | 47 +++++++++++++---------------- tests/test-subpicture.c | 7 +---- 5 files changed, 79 insertions(+), 122 deletions(-) diff --git a/configure.ac b/configure.ac index 9fc8a51361..ccca88c63f 100644 --- a/configure.ac +++ b/configure.ac @@ -34,10 +34,6 @@ m4_define([gst_plugins_base_micro_version], [31]) m4_define([gst_plugins_base_version], [gst_plugins_base_major_version.gst_plugins_base_minor_version.gst_plugins_base_micro_version]) -# VA-API minimum version number -m4_define([va_api_x11_version], [0.31.0]) -m4_define([va_api_glx_version], [0.32.0]) - # gst plugins-bad version number m4_define([gst_plugins_bad_major_version], [0]) m4_define([gst_plugins_bad_minor_version], [10]) @@ -45,6 +41,10 @@ m4_define([gst_plugins_bad_micro_version], [22]) m4_define([gst_plugins_bad_version], [gst_plugins_bad_major_version.gst_plugins_bad_minor_version.gst_plugins_bad_micro_version]) +# VA-API minimum version number +m4_define([va_api_x11_version], [0.31.0]) +m4_define([va_api_glx_version], [0.32.0]) + # libva package version number m4_define([libva_x11_package_version], [1.0.3]) m4_define([libva_glx_package_version], [1.0.9]) @@ -113,11 +113,6 @@ AC_ARG_ENABLE(vaapisink-glx, [enable OpenGL/X11 to vaapisink @<:@default=yes@:>@]), [], [enable_vaapisink_glx="no"]) -AC_ARG_ENABLE(codecparsers, - AS_HELP_STRING([--enable-codecparsers], - [enable adhoc bitstream parsers from GStreamer @<:@default=yes@:>@]), - [], [enable_codecparsers="yes"]) - dnl Check for __attribute__((visibility())) AC_CACHE_CHECK([whether __attribute__((visibility())) is supported], vaapi_cv_visibility_attribute, @@ -233,21 +228,13 @@ PKG_CHECK_MODULES([GST_BASEVIDEO], ) dnl Check for GStreamer codec parsers -USE_CODEC_PARSERS=0 -if test "$enable_codecparsers" = "yes"; then -PKG_CHECK_MODULES([GST_CODEC_PARSERS], - [gstreamer-codecparsers-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED], - [enable_codecparsers="yes" USE_CODEC_PARSERS=1], - [enable_codecparsers="no" USE_CODEC_PARSERS=0] -) -fi - -AC_DEFINE_UNQUOTED(USE_CODEC_PARSERS, $USE_CODEC_PARSERS, - [Defined to 1 if GStreamer codec parsers are used]) -AM_CONDITIONAL(USE_CODEC_PARSERS, test $USE_CODEC_PARSERS -eq 1) - +USE_CODEC_PARSERS=1 USE_LOCAL_CODEC_PARSERS=0 -if test "$enable_codecparsers" = "yes"; then + +PKG_CHECK_MODULES([GST_CODEC_PARSERS], + [gstreamer-codecparsers-$GST_MAJORMINOR >= $GST_PLUGINS_BAD_VERSION_REQUIRED] +) + AC_CACHE_CHECK([for GstH264SliceHdr::n_emulation_prevention_bytes], ac_cv_have_gst_h264_slice_hdr_epb_count, [ saved_CFLAGS="$CFLAGS" @@ -266,6 +253,11 @@ AC_CACHE_CHECK([for GstH264SliceHdr::n_emulation_prevention_bytes], LIBS="$saved_LIBS" ]) +if test "$ac_cv_have_gst_h264_slice_hdr_epb_count" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_GST_H264_SLICE_HDR_EPB_COUNT, 1, + [Defined to 1 if GstH264SliceHdr::n_emulation_prevention_bytes exists.]) +fi + AC_CACHE_CHECK([for JPEG parser], ac_cv_have_gst_jpeg_parser, [ saved_CFLAGS="$CFLAGS" @@ -282,12 +274,6 @@ AC_CACHE_CHECK([for JPEG parser], CFLAGS="$saved_CFLAGS" LIBS="$saved_LIBS" ]) -fi - -if test "$ac_cv_have_gst_h264_slice_hdr_epb_count" = "yes"; then - AC_DEFINE_UNQUOTED(HAVE_GST_H264_SLICE_HDR_EPB_COUNT, 1, - [Defined to 1 if GstH264SliceHdr::n_emulation_prevention_bytes exists.]) -fi if test "$ac_cv_have_gst_jpeg_parser" = "yes"; then AC_DEFINE_UNQUOTED(HAVE_GST_JPEG_PARSER, 1, @@ -407,7 +393,6 @@ AC_SUBST(LIBVA_EXTRA_LIBS) dnl Check for JPEG decoding API (0.33+) USE_JPEG_DECODER=0 -if test "$enable_codecparsers" = "yes"; then AC_CACHE_CHECK([for JPEG decoding API], ac_cv_have_jpeg_decoding_api, [ saved_CFLAGS="$CFLAGS" @@ -428,7 +413,6 @@ AC_CACHE_CHECK([for JPEG decoding API], CFLAGS="$saved_CFLAGS" LIBS="$saved_LIBS" ]) -fi AC_DEFINE_UNQUOTED(USE_JPEG_DECODER, $USE_JPEG_DECODER, [Defined to 1 if JPEG decoder is used]) @@ -441,10 +425,6 @@ else USE_VAAPISINK_GLX=0 fi -if test "$enable_codecparsers" = "no"; then - AC_MSG_ERROR([Found no suitable GStreamer bitstream parsers]) -fi - AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) @@ -518,5 +498,4 @@ echo VA-API version ................... : $VA_VERSION_STR echo GLX support ...................... : $(yesno $USE_GLX) echo VA/GLX support ................... : $(yesno $USE_VAAPI_GLX) echo VaapiSink/GL ..................... : $(yesno $USE_VAAPISINK_GLX) -echo GStreamer bitstream parsers ...... : $(yesno $USE_CODEC_PARSERS) echo diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index acced92ee8..27145b0ff8 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -17,6 +17,7 @@ libgstvaapi_cflags = \ $(GST_BASEVIDEO_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ $(GST_CFLAGS) \ + $(GST_CODEC_PARSERS_CFLAGS) \ $(LIBVA_CFLAGS) \ $(NULL) @@ -25,12 +26,20 @@ libgstvaapi_libs = \ $(GST_BASEVIDEO_LIBS) \ $(GST_LIBS) \ $(GST_VIDEO_LIBS) \ + $(GST_CODEC_PARSERS_LIBS) \ $(LIBVA_LIBS) \ $(NULL) libgstvaapi_source_c = \ + gstvaapicodec_objects.c \ gstvaapicontext.c \ gstvaapidecoder.c \ + gstvaapidecoder_dpb.c \ + gstvaapidecoder_h264.c \ + gstvaapidecoder_mpeg2.c \ + gstvaapidecoder_mpeg4.c \ + gstvaapidecoder_objects.c \ + gstvaapidecoder_vc1.c \ gstvaapidisplay.c \ gstvaapidisplaycache.c \ gstvaapiimage.c \ @@ -55,6 +64,10 @@ libgstvaapi_source_c = \ libgstvaapi_source_h = \ gstvaapicontext.h \ gstvaapidecoder.h \ + gstvaapidecoder_h264.h \ + gstvaapidecoder_mpeg2.h \ + gstvaapidecoder_mpeg4.h \ + gstvaapidecoder_vc1.h \ gstvaapidisplay.h \ gstvaapidisplaycache.h \ gstvaapiimage.h \ @@ -78,8 +91,11 @@ libgstvaapi_source_h = \ libgstvaapi_source_priv_h = \ glibcompat.h \ gstvaapi_priv.h \ + gstvaapicodec_objects.h \ gstvaapicompat.h \ gstvaapidebug.h \ + gstvaapidecoder_dpb.h \ + gstvaapidecoder_objects.h \ gstvaapidecoder_priv.h \ gstvaapidisplay_priv.h \ gstvaapiobject_priv.h \ @@ -137,35 +153,10 @@ libgstvaapi_glx_source_priv_h = \ gstvaapiutils_x11.h \ $(NULL) -if USE_CODEC_PARSERS -libgstvaapi_source_c += \ - gstvaapicodec_objects.c \ - gstvaapidecoder_dpb.c \ - gstvaapidecoder_h264.c \ - gstvaapidecoder_mpeg2.c \ - gstvaapidecoder_mpeg4.c \ - gstvaapidecoder_objects.c \ - gstvaapidecoder_vc1.c \ - $(NULL) -libgstvaapi_source_h += \ - gstvaapidecoder_h264.h \ - gstvaapidecoder_mpeg2.h \ - gstvaapidecoder_mpeg4.h \ - gstvaapidecoder_vc1.h \ - $(NULL) -libgstvaapi_source_priv_h += \ - gstvaapicodec_objects.h \ - gstvaapidecoder_dpb.h \ - gstvaapidecoder_objects.h \ - $(NULL) -libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS) -libgstvaapi_libs += $(GST_CODEC_PARSERS_LIBS) - if USE_JPEG_DECODER libgstvaapi_source_c += gstvaapidecoder_jpeg.c libgstvaapi_source_h += gstvaapidecoder_jpeg.h endif -endif if USE_LOCAL_CODEC_PARSERS libgstvaapi_libs += \ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9572f23f06..adafed1251 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -44,13 +44,11 @@ #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" -#if USE_CODEC_PARSERS -# include -# include -# include -# include -# include -#endif +#include +#include +#include +#include +#include #define GST_PLUGIN_NAME "vaapidecode" #define GST_PLUGIN_DESC "A VA-API based video decoder" @@ -302,6 +300,7 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) if (!gst_vaapi_ensure_display(decode, &decode->display)) return FALSE; + dpy = decode->display; decode->decoder_mutex = g_mutex_new(); if (!decode->decoder_mutex) @@ -311,31 +310,29 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) if (!decode->decoder_ready) return FALSE; - dpy = decode->display; -#if USE_CODEC_PARSERS - structure = gst_caps_get_structure(caps, 0); - if (!structure) + structure = gst_caps_get_structure(caps, 0); + if (!structure) + return FALSE; + + if (gst_structure_has_name(structure, "video/x-h264")) + decode->decoder = gst_vaapi_decoder_h264_new(dpy, caps); + else if (gst_structure_has_name(structure, "video/mpeg")) { + if (!gst_structure_get_int(structure, "mpegversion", &version)) return FALSE; - if (gst_structure_has_name(structure, "video/x-h264")) - decode->decoder = gst_vaapi_decoder_h264_new(dpy, caps); - else if (gst_structure_has_name(structure, "video/mpeg")) { - if (!gst_structure_get_int(structure, "mpegversion", &version)) - return FALSE; - if (version == 2) - decode->decoder = gst_vaapi_decoder_mpeg2_new(dpy, caps); - else if (version == 4) - decode->decoder = gst_vaapi_decoder_mpeg4_new(dpy, caps); - } - else if (gst_structure_has_name(structure, "video/x-wmv")) - decode->decoder = gst_vaapi_decoder_vc1_new(dpy, caps); - else if (gst_structure_has_name(structure, "video/x-h263") || - gst_structure_has_name(structure, "video/x-divx") || - gst_structure_has_name(structure, "video/x-xvid")) + if (version == 2) + decode->decoder = gst_vaapi_decoder_mpeg2_new(dpy, caps); + else if (version == 4) decode->decoder = gst_vaapi_decoder_mpeg4_new(dpy, caps); + } + else if (gst_structure_has_name(structure, "video/x-wmv")) + decode->decoder = gst_vaapi_decoder_vc1_new(dpy, caps); + else if (gst_structure_has_name(structure, "video/x-h263") || + gst_structure_has_name(structure, "video/x-divx") || + gst_structure_has_name(structure, "video/x-xvid")) + decode->decoder = gst_vaapi_decoder_mpeg4_new(dpy, caps); #if USE_JPEG_DECODER - else if (gst_structure_has_name(structure, "image/jpeg")) - decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps); -#endif + else if (gst_structure_has_name(structure, "image/jpeg")) + decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps); #endif if (!decode->decoder) return FALSE; diff --git a/tests/test-decode.c b/tests/test-decode.c index 561162d32a..ef1f36efa4 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -26,18 +26,15 @@ #include #include #include +#include +#include +#include +#include #include "test-jpeg.h" #include "test-mpeg2.h" #include "test-h264.h" #include "test-vc1.h" -#if USE_CODEC_PARSERS -# include -# include -# include -# include -#endif - /* Set to 1 to check display cache works (shared VA display) */ #define CHECK_DISPLAY_CACHE 1 @@ -147,27 +144,25 @@ main(int argc, char *argv[]) NULL ); -#if USE_CODEC_PARSERS - switch (gst_vaapi_profile_get_codec(info.profile)) { - case GST_VAAPI_CODEC_H264: - decoder = gst_vaapi_decoder_h264_new(display, decoder_caps); - break; + switch (gst_vaapi_profile_get_codec(info.profile)) { + case GST_VAAPI_CODEC_H264: + decoder = gst_vaapi_decoder_h264_new(display, decoder_caps); + break; #if USE_JPEG_DECODER - case GST_VAAPI_CODEC_JPEG: - decoder = gst_vaapi_decoder_jpeg_new(display, decoder_caps); - break; -#endif - case GST_VAAPI_CODEC_MPEG2: - decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); - break; - case GST_VAAPI_CODEC_VC1: - decoder = gst_vaapi_decoder_vc1_new(display, decoder_caps); - break; - default: - decoder = NULL; - break; - } + case GST_VAAPI_CODEC_JPEG: + decoder = gst_vaapi_decoder_jpeg_new(display, decoder_caps); + break; #endif + case GST_VAAPI_CODEC_MPEG2: + decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); + break; + case GST_VAAPI_CODEC_VC1: + decoder = gst_vaapi_decoder_vc1_new(display, decoder_caps); + break; + default: + decoder = NULL; + break; + } if (!decoder) g_error("could not create decoder"); gst_caps_unref(decoder_caps); diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index a0e1b6fb50..b3d7c65f7a 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -25,14 +25,11 @@ #include #include #include +#include #include #include "test-mpeg2.h" #include "test-subpicture-data.h" -#if USE_CODEC_PARSERS -# include -#endif - typedef void (*GetVideoInfoFunc)(VideoDecodeInfo *info); typedef struct _CodecDefs CodecDefs; @@ -149,9 +146,7 @@ main(int argc, char *argv[]) NULL ); -#if USE_CODEC_PARSERS decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); -#endif if (!decoder) g_error("could not create video decoder"); gst_caps_unref(decoder_caps); From 4f95b622463c39166624de17fdd1c866d6888224 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jul 2012 17:27:06 +0200 Subject: [PATCH 0729/3781] docs: add missing entries for the JPEG decoder. --- docs/reference/libs/libs-sections.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index cfe63a4347..8da7246f63 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -472,6 +472,22 @@ GST_VAAPI_IS_DECODER_CLASS GST_VAAPI_DECODER_GET_CLASS
+
+gstvaapidecoder_jpeg +GstVaapiDecoderJpeg +GstVaapiDecoderJpeg +GstVaapiDecoderJpegClass +gst_vaapi_decoder_jpeg_new + +GST_VAAPI_DECODER_JPEG +GST_VAAPI_IS_DECODER_JPEG +GST_VAAPI_TYPE_DECODER_JPEG +gst_vaapi_decoder_jpeg_get_type +GST_VAAPI_DECODER_JPEG_CLASS +GST_VAAPI_IS_DECODER_JPEG_CLASS +GST_VAAPI_DECODER_JPEG_GET_CLASS +
+
gstvaapidecoder_mpeg2 GstVaapiDecoderMpeg2 From 562d98ec56d28956a618d3ef06c46ffc7ceecc96 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jul 2012 17:41:25 +0200 Subject: [PATCH 0730/3781] Drop obsolete GstVaapiTSB. It has been replaced with a GstAdapter and gst_adapter_prev_pts(). --- gst-libs/gst/vaapi/Makefile.am | 2 - gst-libs/gst/vaapi/gstvaapiutils_tsb.c | 237 ------------------------- gst-libs/gst/vaapi/gstvaapiutils_tsb.h | 58 ------ 3 files changed, 297 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapiutils_tsb.c delete mode 100644 gst-libs/gst/vaapi/gstvaapiutils_tsb.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 27145b0ff8..49f95c5d94 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -53,7 +53,6 @@ libgstvaapi_source_c = \ gstvaapisurfacepool.c \ gstvaapisurfaceproxy.c \ gstvaapiutils.c \ - gstvaapiutils_tsb.c \ gstvaapivalue.c \ gstvaapivideobuffer.c \ gstvaapivideopool.c \ @@ -101,7 +100,6 @@ libgstvaapi_source_priv_h = \ gstvaapiobject_priv.h \ gstvaapisurface_priv.h \ gstvaapiutils.h \ - gstvaapiutils_tsb.h \ gstvaapivideobuffer_priv.h \ gstvaapiworkarounds.h \ sysdeps.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_tsb.c b/gst-libs/gst/vaapi/gstvaapiutils_tsb.c deleted file mode 100644 index 67ef2f2c23..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiutils_tsb.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * gstvaapiutils_tsb.c - Timestamp buffer store - * - * Copyright (C) 2011 Intel Corporation - * - * 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 "gstvaapiutils_tsb.h" -#include - -typedef struct _GstVaapiTSBEntry GstVaapiTSBEntry; - -struct _GstVaapiTSB { - GList *list; -}; - -struct _GstVaapiTSBEntry { - GstBuffer *buffer; - guint32 buffer_size; - guint32 offset; -}; - -static GstVaapiTSBEntry * -gst_vaapi_tsb_entry_new(GstBuffer *buffer) -{ - GstVaapiTSBEntry *e; - - e = g_slice_new(GstVaapiTSBEntry); - if (!e) - return NULL; - - e->buffer = gst_buffer_ref(buffer); - e->buffer_size = GST_BUFFER_SIZE(buffer); - e->offset = 0; - return e; -} - -static void -gst_vaapi_tsb_entry_destroy(GstVaapiTSBEntry *e) -{ - if (!e) - return; - - if (e->buffer) { - gst_buffer_unref(e->buffer); - e->buffer = NULL; - } - g_slice_free(GstVaapiTSBEntry, e); -} - -/** - * gst_vaapi_tsb_new: - * - * Creates a new #GstVaapiTSB. - * - * Return value: a new #GstVaapiTSB - */ -GstVaapiTSB * -gst_vaapi_tsb_new() -{ - GstVaapiTSB *tsb; - - tsb = g_new(GstVaapiTSB, 1); - if (!tsb) - return NULL; - - tsb->list = NULL; - return tsb; -} - -/** - * gst_vaapi_tsb_destroy: - * @tsb: a #GstVaapiTSB - * - * Destroys the #GstVaapiTSB. All buffers are unreferenced. - */ -void -gst_vaapi_tsb_destroy(GstVaapiTSB *tsb) -{ - if (!tsb) - return; - - if (tsb->list) { - g_list_foreach(tsb->list, (GFunc)gst_vaapi_tsb_entry_destroy, NULL); - g_list_free(tsb->list); - tsb->list = NULL; - } - g_free(tsb); -} - -/** - * gst_vaapi_tsb_push: - * @tsb: a #GstVaapiTSB - * @buffer: a #GstBuffer - * - * Pushes @buffer to the timestamp buffer store. The TSB owns and - * maintains an extra reference to the buffer. - * - * Return value: %TRUE if success, %FALSE otherwise - */ -gboolean -gst_vaapi_tsb_push(GstVaapiTSB *tsb, GstBuffer *buffer) -{ - GList *l; - GstVaapiTSBEntry *e; - - if (!tsb) - return FALSE; - - e = gst_vaapi_tsb_entry_new(buffer); - if (!e) - return FALSE; - - l = g_list_append(tsb->list, e); - if (!l) - return FALSE; - - tsb->list = l; - return TRUE; -} - -/** - * gst_vaapi_tsb_pop: - * @tsb: a #GstVaapiTSB - * @size: number of bytes to remove from the TSB - * - * Removes @size bytes from the @tsb. - */ -void -gst_vaapi_tsb_pop(GstVaapiTSB *tsb, gsize size) -{ - GList *l; - GstVaapiTSBEntry *e; - guint32 n; - - if (!tsb || !tsb->list) - return; - - l = tsb->list; - e = l->data; - while (size > 0) { - n = MIN(e->buffer_size - e->offset, size); - e->offset += n; - size -= n; - if (e->offset == e->buffer_size) { - gst_vaapi_tsb_entry_destroy(e); - l = l->next; - g_list_free_1(tsb->list); - tsb->list = l; - if (!l) - return; - e = l->data; - } - } -} - -/** - * gst_vaapi_tsb_peek: - * @tsb: a #GstVaapiTSB - * - * Returns the current #GstBuffer. - * - * Return value: current #GstBuffer, or %NULL if none was found - */ -GstBuffer * -gst_vaapi_tsb_peek(GstVaapiTSB *tsb) -{ - GstVaapiTSBEntry *e; - - if (!tsb || !tsb->list) - return NULL; - - e = tsb->list->data; - if (!e) - return NULL; - - return e->buffer; -} - -/** - * gst_vaapi_tsb_get_timestamp: - * @tsb: a #GstVaapiTSB - * - * Returns the timestamp for the current #GstBuffer. - * - * Return value: current #GstBuffer timestamp, or %GST_CLOCK_TIME_NONE if none was found - */ -GstClockTime -gst_vaapi_tsb_get_timestamp(GstVaapiTSB *tsb) -{ - GstBuffer *buffer; - - buffer = gst_vaapi_tsb_peek(tsb); - if (!buffer) - return GST_CLOCK_TIME_NONE; - - return GST_BUFFER_TIMESTAMP(buffer); -} - -/** - * gst_vaapi_tsb_get_size: - * @tsb: a #GstVaapiTSB - * - * Returns the size of the #GstVaapiTSB. - * - * Return value: how many bytes left to consume from @tsb - */ -gsize -gst_vaapi_tsb_get_size(GstVaapiTSB *tsb) -{ - GList *l; - GstVaapiTSBEntry *e; - guint32 size = 0; - - if (!tsb || !tsb->list) - return 0; - - for (l = tsb->list; l != NULL; l = l->next) { - e = l->data; - size += e->buffer_size - e->offset; - } - return size; -} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_tsb.h b/gst-libs/gst/vaapi/gstvaapiutils_tsb.h deleted file mode 100644 index 4070571974..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiutils_tsb.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * gstvaapiutils_tsb.h - Timestamp buffer store - * - * Copyright (C) 2011 Intel Corporation - * - * 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_UTILS_TSB_H -#define GST_VAAPI_UTILS_TSB_H - -#include "config.h" -#include - -typedef struct _GstVaapiTSB GstVaapiTSB; - -GstVaapiTSB * -gst_vaapi_tsb_new() - attribute_hidden; - -void -gst_vaapi_tsb_destroy(GstVaapiTSB *tsb) - attribute_hidden; - -gboolean -gst_vaapi_tsb_push(GstVaapiTSB *tsb, GstBuffer *buffer) - attribute_hidden; - -void -gst_vaapi_tsb_pop(GstVaapiTSB *tsb, gsize size) - attribute_hidden; - -GstBuffer * -gst_vaapi_tsb_peek(GstVaapiTSB *tsb) - attribute_hidden; - -GstClockTime -gst_vaapi_tsb_get_timestamp(GstVaapiTSB *tsb) - attribute_hidden; - -gsize -gst_vaapi_tsb_get_size(GstVaapiTSB *tsb) - attribute_hidden; - -#endif /* GST_VAAPI_UTILS_TSB_H */ From d8b0c8ec383dd33a109644670b0e7da06a96c7af Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jul 2012 17:55:00 +0200 Subject: [PATCH 0731/3781] Use standard G_GNUC_INTERNAL keyword instead of attribute_hidden. --- configure.ac | 26 ------ gst-libs/gst/vaapi/gstvaapicodec_objects.h | 32 ++++--- gst-libs/gst/vaapi/gstvaapidecoder_dpb.h | 27 +++--- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 30 ++++--- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 26 +++--- gst-libs/gst/vaapi/gstvaapisurface_priv.h | 7 +- gst-libs/gst/vaapi/gstvaapiutils.h | 35 ++++---- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 95 ++++++++++---------- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 17 ++-- 9 files changed, 144 insertions(+), 151 deletions(-) diff --git a/configure.ac b/configure.ac index ccca88c63f..a4c3e2cf78 100644 --- a/configure.ac +++ b/configure.ac @@ -113,32 +113,6 @@ AC_ARG_ENABLE(vaapisink-glx, [enable OpenGL/X11 to vaapisink @<:@default=yes@:>@]), [], [enable_vaapisink_glx="no"]) -dnl Check for __attribute__((visibility())) -AC_CACHE_CHECK([whether __attribute__((visibility())) is supported], - vaapi_cv_visibility_attribute, - [cat > conftest.c </dev/null 2>&1; then - if grep '\.hidden.*foo' conftest.s >/dev/null; then - if grep '\.protected.*bar' conftest.s >/dev/null; then - vaapi_cv_visibility_attribute=yes - fi - fi - fi - rm -f conftest.[cs] -]) -if test $vaapi_cv_visibility_attribute = yes; then - vaapi_cv_visibility_attribute_hidden="__attribute__((visibility(\"hidden\")))" -else - vaapi_cv_visibility_attribute_hidden="" -fi -AC_DEFINE_UNQUOTED([attribute_hidden], - [$vaapi_cv_visibility_attribute_hidden], - [Define the "hidden" visibility attribute]) - dnl Check for basic libraries AC_CHECK_LIB(m, tan) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index f1e846d0f0..c70f34f3c9 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -109,10 +109,11 @@ struct _GstVaapiCodecObjectClass { const GstVaapiCodecObjectConstructorArgs *args); }; +G_GNUC_INTERNAL GType -gst_vaapi_codec_object_get_type(void) G_GNUC_CONST - attribute_hidden; +gst_vaapi_codec_object_get_type(void) G_GNUC_CONST; +G_GNUC_INTERNAL GstVaapiCodecObject * gst_vaapi_codec_object_new( GType type, @@ -121,13 +122,14 @@ gst_vaapi_codec_object_new( guint param_size, gconstpointer data, guint data_size -) attribute_hidden; +); +G_GNUC_INTERNAL gboolean gst_vaapi_codec_object_construct( GstVaapiCodecObject *obj, const GstVaapiCodecObjectConstructorArgs *args -) attribute_hidden; +); /* ------------------------------------------------------------------------- */ /* --- Inverse Quantization Matrices --- */ @@ -184,16 +186,17 @@ struct _GstVaapiIqMatrixClass { GstVaapiCodecObjectClass parent_class; }; +G_GNUC_INTERNAL GType -gst_vaapi_iq_matrix_get_type(void) G_GNUC_CONST - attribute_hidden; +gst_vaapi_iq_matrix_get_type(void) G_GNUC_CONST; +G_GNUC_INTERNAL GstVaapiIqMatrix * gst_vaapi_iq_matrix_new( GstVaapiDecoder *decoder, gconstpointer param, guint param_size -) attribute_hidden; +); /* ------------------------------------------------------------------------- */ /* --- VC-1 Bit Planes --- */ @@ -250,13 +253,13 @@ struct _GstVaapiBitPlaneClass { GstVaapiCodecObjectClass parent_class; }; +G_GNUC_INTERNAL GType -gst_vaapi_bitplane_get_type(void) G_GNUC_CONST - attribute_hidden; +gst_vaapi_bitplane_get_type(void) G_GNUC_CONST; +G_GNUC_INTERNAL GstVaapiBitPlane * -gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size) - attribute_hidden; +gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size); /* ------------------------------------------------------------------------- */ /* --- JPEG Huffman Tables --- */ @@ -313,16 +316,17 @@ struct _GstVaapiHuffmanTableClass { GstVaapiCodecObjectClass parent_class; }; +G_GNUC_INTERNAL GType -gst_vaapi_huffman_table_get_type(void) G_GNUC_CONST - attribute_hidden; +gst_vaapi_huffman_table_get_type(void) G_GNUC_CONST; +G_GNUC_INTERNAL GstVaapiHuffmanTable * gst_vaapi_huffman_table_new( GstVaapiDecoder *decoder, guint8 *data, guint data_size -) attribute_hidden; +); /* ------------------------------------------------------------------------- */ /* --- Helpers to create codec-dependent objects --- */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h index db43811e20..3cbaa48e84 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h @@ -91,21 +91,21 @@ struct _GstVaapiDpbClass { gboolean (*add) (GstVaapiDpb *dpb, GstVaapiPicture *picture); }; +G_GNUC_INTERNAL GType -gst_vaapi_dpb_get_type(void) G_GNUC_CONST - attribute_hidden; +gst_vaapi_dpb_get_type(void) G_GNUC_CONST; +G_GNUC_INTERNAL void -gst_vaapi_dpb_flush(GstVaapiDpb *dpb) - attribute_hidden; +gst_vaapi_dpb_flush(GstVaapiDpb *dpb); +G_GNUC_INTERNAL gboolean -gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) - attribute_hidden; +gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture); +G_GNUC_INTERNAL guint -gst_vaapi_dpb_size(GstVaapiDpb *dpb) - attribute_hidden; +gst_vaapi_dpb_size(GstVaapiDpb *dpb); static inline gpointer gst_vaapi_dpb_ref(gpointer ptr) @@ -170,21 +170,22 @@ struct _GstVaapiDpbMpeg2Class { GstVaapiDpbClass parent_class; }; +G_GNUC_INTERNAL GType -gst_vaapi_dpb_mpeg2_get_type(void) G_GNUC_CONST - attribute_hidden; +gst_vaapi_dpb_mpeg2_get_type(void) G_GNUC_CONST; +G_GNUC_INTERNAL GstVaapiDpb * -gst_vaapi_dpb_mpeg2_new(void) - attribute_hidden; +gst_vaapi_dpb_mpeg2_new(void); +G_GNUC_INTERNAL void gst_vaapi_dpb_mpeg2_get_references( GstVaapiDpb *dpb, GstVaapiPicture *picture, GstVaapiPicture **prev_picture_ptr, GstVaapiPicture **next_picture_ptr -) attribute_hidden; +); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 0e33f07624..f7a7ea6930 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -163,32 +163,33 @@ struct _GstVaapiPictureClass { GstVaapiCodecObjectClass parent_class; }; +G_GNUC_INTERNAL GType -gst_vaapi_picture_get_type(void) G_GNUC_CONST - attribute_hidden; +gst_vaapi_picture_get_type(void) G_GNUC_CONST; +G_GNUC_INTERNAL GstVaapiPicture * gst_vaapi_picture_new( GstVaapiDecoder *decoder, gconstpointer param, guint param_size -) attribute_hidden; +); +G_GNUC_INTERNAL GstVaapiPicture * -gst_vaapi_picture_new_field(GstVaapiPicture *picture) - attribute_hidden; +gst_vaapi_picture_new_field(GstVaapiPicture *picture); +G_GNUC_INTERNAL void -gst_vaapi_picture_add_slice(GstVaapiPicture *picture, GstVaapiSlice *slice) - attribute_hidden; +gst_vaapi_picture_add_slice(GstVaapiPicture *picture, GstVaapiSlice *slice); +G_GNUC_INTERNAL gboolean -gst_vaapi_picture_decode(GstVaapiPicture *picture) - attribute_hidden; +gst_vaapi_picture_decode(GstVaapiPicture *picture); +G_GNUC_INTERNAL gboolean -gst_vaapi_picture_output(GstVaapiPicture *picture) - attribute_hidden; +gst_vaapi_picture_output(GstVaapiPicture *picture); static inline gpointer gst_vaapi_picture_ref(gpointer ptr) @@ -262,10 +263,11 @@ struct _GstVaapiSliceClass { GstVaapiCodecObjectClass parent_class; }; +G_GNUC_INTERNAL GType -gst_vaapi_slice_get_type(void) G_GNUC_CONST - attribute_hidden; +gst_vaapi_slice_get_type(void) G_GNUC_CONST; +G_GNUC_INTERNAL GstVaapiSlice * gst_vaapi_slice_new( GstVaapiDecoder *decoder, @@ -273,7 +275,7 @@ gst_vaapi_slice_new( guint param_size, const guchar *data, guint data_size -) attribute_hidden; +); /* ------------------------------------------------------------------------- */ /* --- Helpers to create codec-dependent objects --- */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 6e153e594b..66646d3d9c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -128,31 +128,35 @@ struct _GstVaapiDecoderPrivate { guint is_interlaced : 1; }; +G_GNUC_INTERNAL void gst_vaapi_decoder_set_picture_size( GstVaapiDecoder *decoder, guint width, guint height -) attribute_hidden; +); +G_GNUC_INTERNAL void gst_vaapi_decoder_set_framerate( GstVaapiDecoder *decoder, guint fps_n, guint fps_d -) attribute_hidden; +); +G_GNUC_INTERNAL void gst_vaapi_decoder_set_pixel_aspect_ratio( GstVaapiDecoder *decoder, guint par_n, guint par_d -) attribute_hidden; +); +G_GNUC_INTERNAL void -gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced) - attribute_hidden; +gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced); +G_GNUC_INTERNAL gboolean gst_vaapi_decoder_ensure_context( GstVaapiDecoder *decoder, @@ -160,25 +164,27 @@ gst_vaapi_decoder_ensure_context( GstVaapiEntrypoint entrypoint, guint width, guint height -) attribute_hidden; +); +G_GNUC_INTERNAL gboolean gst_vaapi_decoder_push_buffer_sub( GstVaapiDecoder *decoder, GstBuffer *buffer, guint offset, guint size -) attribute_hidden; +); +G_GNUC_INTERNAL void gst_vaapi_decoder_push_surface_proxy( GstVaapiDecoder *decoder, GstVaapiSurfaceProxy *proxy -) attribute_hidden; +); +G_GNUC_INTERNAL GstVaapiDecoderStatus -gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder) - attribute_hidden; +gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index a7eeda91d1..0817b2911c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -25,14 +25,15 @@ #include #include +G_GNUC_INTERNAL void gst_vaapi_surface_set_parent_context( GstVaapiSurface *surface, GstVaapiContext *context -) attribute_hidden; +); +G_GNUC_INTERNAL GstVaapiContext * -gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface) - attribute_hidden; +gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface); #endif /* GST_VAAPI_SURFACE_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index cf5fcc32a9..5c75c8d743 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -33,21 +33,22 @@ #endif /** Check VA status for success or print out an error */ +G_GNUC_INTERNAL gboolean -vaapi_check_status(VAStatus status, const char *msg) - attribute_hidden; +vaapi_check_status(VAStatus status, const char *msg); /** Maps VA buffer */ +G_GNUC_INTERNAL void * -vaapi_map_buffer(VADisplay dpy, VABufferID buf_id) - attribute_hidden; +vaapi_map_buffer(VADisplay dpy, VABufferID buf_id); /** Unmaps VA buffer */ +G_GNUC_INTERNAL void -vaapi_unmap_buffer(VADisplay dpy, VABufferID buf_id, void **pbuf) - attribute_hidden; +vaapi_unmap_buffer(VADisplay dpy, VABufferID buf_id, void **pbuf); /** Creates and maps VA buffer */ +G_GNUC_INTERNAL gboolean vaapi_create_buffer( VADisplay dpy, @@ -57,27 +58,27 @@ vaapi_create_buffer( gconstpointer data, VABufferID *buf_id, gpointer *mapped_data -) attribute_hidden; +); /** Destroy VA buffer */ +G_GNUC_INTERNAL void -vaapi_destroy_buffer(VADisplay dpy, VABufferID *buf_id) - attribute_hidden; +vaapi_destroy_buffer(VADisplay dpy, VABufferID *buf_id); /** Return a string representation of a VAProfile */ -const char *string_of_VAProfile(VAProfile profile) - attribute_hidden; +G_GNUC_INTERNAL +const char *string_of_VAProfile(VAProfile profile); /** Return a string representation of a VAEntrypoint */ -const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) - attribute_hidden; +G_GNUC_INTERNAL +const char *string_of_VAEntrypoint(VAEntrypoint entrypoint); +G_GNUC_INTERNAL guint -from_GstVaapiSurfaceRenderFlags(guint flags) - attribute_hidden; +from_GstVaapiSurfaceRenderFlags(guint flags); +G_GNUC_INTERNAL guint -to_GstVaapiSurfaceStatus(guint va_flags) - attribute_hidden; +to_GstVaapiSurfaceStatus(guint va_flags); #endif /* GST_VAAPI_UTILS_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 80e76f1d08..c9a4983336 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -45,33 +45,33 @@ typedef void (*PFNGLXDESTROYPIXMAPPROC)(Display *, GLXPixmap); #define GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_EXT #endif +G_GNUC_INTERNAL const char * -gl_get_error_string(GLenum error) - attribute_hidden; +gl_get_error_string(GLenum error); +G_GNUC_INTERNAL void -gl_purge_errors(void) - attribute_hidden; +gl_purge_errors(void); +G_GNUC_INTERNAL gboolean -gl_check_error(void) - attribute_hidden; +gl_check_error(void); +G_GNUC_INTERNAL gboolean -gl_get_param(GLenum param, guint *pval) - attribute_hidden; +gl_get_param(GLenum param, guint *pval); +G_GNUC_INTERNAL gboolean -gl_get_texture_param(GLenum target, GLenum param, guint *pval) - attribute_hidden; +gl_get_texture_param(GLenum target, GLenum param, guint *pval); +G_GNUC_INTERNAL void -gl_set_bgcolor(guint32 color) - attribute_hidden; +gl_set_bgcolor(guint32 color); +G_GNUC_INTERNAL void -gl_resize(guint width, guint height) - attribute_hidden; +gl_resize(guint width, guint height); typedef struct _GLContextState GLContextState; struct _GLContextState { @@ -82,25 +82,25 @@ struct _GLContextState { guint swapped_buffers : 1; }; +G_GNUC_INTERNAL GLContextState * -gl_create_context(Display *dpy, int screen, GLContextState *parent) - attribute_hidden; +gl_create_context(Display *dpy, int screen, GLContextState *parent); +G_GNUC_INTERNAL void -gl_destroy_context(GLContextState *cs) - attribute_hidden; +gl_destroy_context(GLContextState *cs); +G_GNUC_INTERNAL void -gl_get_current_context(GLContextState *cs) - attribute_hidden; +gl_get_current_context(GLContextState *cs); +G_GNUC_INTERNAL gboolean -gl_set_current_context(GLContextState *new_cs, GLContextState *old_cs) - attribute_hidden; +gl_set_current_context(GLContextState *new_cs, GLContextState *old_cs); +G_GNUC_INTERNAL void -gl_swap_buffers(GLContextState *cs) - attribute_hidden; +gl_swap_buffers(GLContextState *cs); typedef struct _GLTextureState GLTextureState; struct _GLTextureState { @@ -110,17 +110,17 @@ struct _GLTextureState { guint was_bound : 1; }; +G_GNUC_INTERNAL gboolean -gl_bind_texture(GLTextureState *ts, GLenum target, GLuint texture) - attribute_hidden; +gl_bind_texture(GLTextureState *ts, GLenum target, GLuint texture); +G_GNUC_INTERNAL void -gl_unbind_texture(GLTextureState *ts) - attribute_hidden; +gl_unbind_texture(GLTextureState *ts); +G_GNUC_INTERNAL GLuint -gl_create_texture(GLenum target, GLenum format, guint width, guint height) - attribute_hidden; +gl_create_texture(GLenum target, GLenum format, guint width, guint height); typedef struct _GLVTable GLVTable; struct _GLVTable { @@ -152,9 +152,9 @@ struct _GLVTable { guint has_multitexture : 1; }; +G_GNUC_INTERNAL GLVTable * -gl_get_vtable(void) - attribute_hidden; +gl_get_vtable(void); typedef struct _GLPixmapObject GLPixmapObject; struct _GLPixmapObject { @@ -169,21 +169,21 @@ struct _GLPixmapObject { guint is_bound : 1; }; +G_GNUC_INTERNAL GLPixmapObject * -gl_create_pixmap_object(Display *dpy, guint width, guint height) - attribute_hidden; +gl_create_pixmap_object(Display *dpy, guint width, guint height); +G_GNUC_INTERNAL void -gl_destroy_pixmap_object(GLPixmapObject *pixo) - attribute_hidden; +gl_destroy_pixmap_object(GLPixmapObject *pixo); +G_GNUC_INTERNAL gboolean -gl_bind_pixmap_object(GLPixmapObject *pixo) - attribute_hidden; +gl_bind_pixmap_object(GLPixmapObject *pixo); +G_GNUC_INTERNAL gboolean -gl_unbind_pixmap_object(GLPixmapObject *pixo) - attribute_hidden; +gl_unbind_pixmap_object(GLPixmapObject *pixo); typedef struct _GLFramebufferObject GLFramebufferObject; struct _GLFramebufferObject { @@ -194,24 +194,25 @@ struct _GLFramebufferObject { guint is_bound : 1; }; +G_GNUC_INTERNAL GLFramebufferObject * gl_create_framebuffer_object( GLenum target, GLuint texture, guint width, guint height -) attribute_hidden; +); +G_GNUC_INTERNAL void -gl_destroy_framebuffer_object(GLFramebufferObject *fbo) - attribute_hidden; +gl_destroy_framebuffer_object(GLFramebufferObject *fbo); +G_GNUC_INTERNAL gboolean -gl_bind_framebuffer_object(GLFramebufferObject *fbo) - attribute_hidden; +gl_bind_framebuffer_object(GLFramebufferObject *fbo); +G_GNUC_INTERNAL gboolean -gl_unbind_framebuffer_object(GLFramebufferObject *fbo) - attribute_hidden; +gl_unbind_framebuffer_object(GLFramebufferObject *fbo); #endif /* GST_VAAPI_UTILS_GLX_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index f9250878a8..090b403718 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -26,16 +26,19 @@ #include #include -void x11_trap_errors(void) - attribute_hidden; +G_GNUC_INTERNAL +void +x11_trap_errors(void); -int x11_untrap_errors(void) - attribute_hidden; +G_GNUC_INTERNAL +int +x11_untrap_errors(void); +G_GNUC_INTERNAL Window -x11_create_window(Display *dpy, guint w, guint h, Visual *vis, Colormap cmap) - attribute_hidden; +x11_create_window(Display *dpy, guint w, guint h, Visual *vis, Colormap cmap); +G_GNUC_INTERNAL gboolean x11_get_geometry( Display *dpy, @@ -44,6 +47,6 @@ x11_get_geometry( gint *py, guint *pwidth, guint *pheight -) attribute_hidden; +); #endif /* GST_VAAPI_UTILS_X11_H */ From edefbb109671688019e15a91036a59ce0a543e1f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Jul 2012 14:05:23 +0200 Subject: [PATCH 0732/3781] configure: cosmetics and some minor changes. - Better grouping of feature checks - Sort list of config files to generate --- configure.ac | 85 ++++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/configure.ac b/configure.ac index a4c3e2cf78..b6074ba977 100644 --- a/configure.ac +++ b/configure.ac @@ -86,6 +86,7 @@ GST_PLUGINS_BAD_VERSION_REQUIRED=gst_plugins_bad_version AC_SUBST(GST_MAJORMINOR) AC_SUBST(GST_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) +AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED) dnl Use pretty build output with automake >= 1.11 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [ @@ -129,16 +130,19 @@ GLIB_VERSION_REQUIRED=glib_version PKG_CHECK_MODULES([GLIB], [glib-2.0 >= $GLIB_VERSION_REQUIRED]) AC_SUBST(GLIB_VERSION_REQUIRED) -dnl Check for GStreamer -PKG_CHECK_MODULES([GST], - [gstreamer-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED] -) +dnl --------------------------------------------------------------------------- +dnl -- GStreamer -- +dnl --------------------------------------------------------------------------- + +dnl GStreamer Core +PKG_CHECK_MODULES([GST], [gstreamer-$GST_MAJORMINOR >= gst_version]) +PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-$GST_MAJORMINOR >= gst_version]) AC_CACHE_CHECK([for GstBaseSink::query hook], ac_cv_have_gst_base_sink_query, [ saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $GST_CFLAGS" + CFLAGS="$CFLAGS $GST_BASE_CFLAGS" saved_LIBS="$LIBS" - LIBS="$LIBS $GST_LIBS" + LIBS="$LIBS $GST_BASE_LIBS" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], @@ -153,11 +157,13 @@ if test "$ac_cv_have_gst_base_sink_query" != "yes"; then AC_MSG_ERROR([GstBaseSink does not contain the 'query' vfunc]) fi -dnl Check for GStreamer plugins-base +dnl GStreamer -base plugins PKG_CHECK_MODULES([GST_PLUGINS_BASE], - [gstreamer-plugins-base-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED] -) + [gstreamer-plugins-base-$GST_MAJORMINOR >= gst_plugins_base_version]) +PKG_CHECK_MODULES([GST_INTERFACES], + [gstreamer-interfaces-$GST_MAJORMINOR >= gst_plugins_base_version]) +dnl ... GST_PLUGINS_BASE_CHECK_VERSION() implementation V=`$PKG_CONFIG --modversion gstreamer-plugins-base-$GST_MAJORMINOR` GST_PLUGINS_BASE_MAJOR_VERSION=`echo "$V" | cut -d'.' -f1` GST_PLUGINS_BASE_MINOR_VERSION=`echo "$V" | cut -d'.' -f2` @@ -166,15 +172,9 @@ AC_SUBST(GST_PLUGINS_BASE_MAJOR_VERSION) AC_SUBST(GST_PLUGINS_BASE_MINOR_VERSION) AC_SUBST(GST_PLUGINS_BASE_MICRO_VERSION) -dnl Check for GStreamer base -PKG_CHECK_MODULES([GST_BASE], - [gstreamer-base-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED] -) - -dnl Check for GStreamer video +dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], - [gstreamer-video-$GST_MAJORMINOR >= $GST_VERSION_REQUIRED] -) + [gstreamer-video-$GST_MAJORMINOR >= gst_plugins_base_version]) AC_CACHE_CHECK([for GstVideoOverlayComposition], ac_cv_have_gst_video_overlay_composition, [ @@ -196,19 +196,18 @@ if test "$ac_cv_have_gst_video_overlay_composition" != "yes"; then AC_MSG_ERROR([GstVideoOverlayComposition is not available]) fi -dnl Check for GStreamer basevideo +dnl GStreamer -bad plugins PKG_CHECK_MODULES([GST_BASEVIDEO], - [gstreamer-basevideo-$GST_MAJORMINOR >= $GST_PLUGINS_BAD_VERSION_REQUIRED] -) + [gstreamer-basevideo-$GST_MAJORMINOR >= gst_plugins_bad_version]) -dnl Check for GStreamer codec parsers +dnl ... bitstream parsers USE_CODEC_PARSERS=1 USE_LOCAL_CODEC_PARSERS=0 PKG_CHECK_MODULES([GST_CODEC_PARSERS], - [gstreamer-codecparsers-$GST_MAJORMINOR >= $GST_PLUGINS_BAD_VERSION_REQUIRED] -) + [gstreamer-codecparsers-$GST_MAJORMINOR >= gst_plugins_bad_version]) +dnl ... 0.10.23 addition, could be implemented otherwise AC_CACHE_CHECK([for GstH264SliceHdr::n_emulation_prevention_bytes], ac_cv_have_gst_h264_slice_hdr_epb_count, [ saved_CFLAGS="$CFLAGS" @@ -232,6 +231,7 @@ if test "$ac_cv_have_gst_h264_slice_hdr_epb_count" = "yes"; then [Defined to 1 if GstH264SliceHdr::n_emulation_prevention_bytes exists.]) fi +dnl ... JPEG parser, not upstream yet AC_CACHE_CHECK([for JPEG parser], ac_cv_have_gst_jpeg_parser, [ saved_CFLAGS="$CFLAGS" @@ -255,11 +255,6 @@ if test "$ac_cv_have_gst_jpeg_parser" = "yes"; then fi AM_CONDITIONAL(USE_LOCAL_CODEC_PARSERS, test $USE_LOCAL_CODEC_PARSERS -eq 1) -dnl Check for GStreamer interfaces -PKG_CHECK_MODULES([GST_INTERFACES], - [gstreamer-interfaces-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED] -) - dnl GST_ALL_LDFLAGS: dnl LDFLAGS really should only contain flags, not libs - they get added before dnl whatevertarget_LIBS and -L flags here affect the rest of the linking @@ -283,6 +278,10 @@ AC_MSG_RESULT([$GST_PLUGINS_DIR]) plugindir="$GST_PLUGINS_DIR" AC_SUBST(plugindir) +dnl --------------------------------------------------------------------------- +dnl -- Renderers -- +dnl --------------------------------------------------------------------------- + dnl Check for X11 PKG_CHECK_MODULES(X11, [x11]) @@ -302,6 +301,10 @@ AC_CHECK_LIB(GL, glXCreateContext, [GLX_LIBS="-lGL"], [USE_GLX=0]) AC_SUBST(GLX_CFLAGS) AC_SUBST(GLX_LIBS) +dnl --------------------------------------------------------------------------- +dnl -- VA-API -- +dnl --------------------------------------------------------------------------- + dnl Check for VA-API LIBVA_PKGNAME="libva" PKG_CHECK_MODULES(LIBVA, [$LIBVA_PKGNAME]) @@ -388,10 +391,6 @@ AC_CACHE_CHECK([for JPEG decoding API], LIBS="$saved_LIBS" ]) -AC_DEFINE_UNQUOTED(USE_JPEG_DECODER, $USE_JPEG_DECODER, - [Defined to 1 if JPEG decoder is used]) -AM_CONDITIONAL(USE_JPEG_DECODER, test $USE_JPEG_DECODER -eq 1) - dnl Check for OpenGL support to vaapisink if test "$enable_vaapisink_glx:$USE_GLX" = "yes:1"; then USE_VAAPISINK_GLX=1 @@ -399,6 +398,14 @@ else USE_VAAPISINK_GLX=0 fi +dnl --------------------------------------------------------------------------- +dnl -- Generate files and summary -- +dnl --------------------------------------------------------------------------- + +AC_DEFINE_UNQUOTED(USE_JPEG_DECODER, $USE_JPEG_DECODER, + [Defined to 1 if JPEG decoder is used]) +AM_CONDITIONAL(USE_JPEG_DECODER, test $USE_JPEG_DECODER -eq 1) + AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) @@ -425,17 +432,17 @@ AC_CONFIG_FILES([ debian.upstream/Makefile debian.upstream/changelog debian.upstream/control - debian.upstream/gstreamer$GST_MAJORMINOR-vaapi.install:\ -debian.upstream/gstreamer-vaapi.install.in debian.upstream/gstreamer$GST_MAJORMINOR-vaapi-doc.install:\ debian.upstream/gstreamer-vaapi-doc.install.in + debian.upstream/gstreamer$GST_MAJORMINOR-vaapi.install:\ +debian.upstream/gstreamer-vaapi.install.in debian.upstream/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi.install.in debian.upstream/libgstvaapi-dev.install - debian.upstream/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:\ -debian.upstream/libgstvaapi-x11.install.in debian.upstream/libgstvaapi-glx-$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi-glx.install.in + debian.upstream/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:\ +debian.upstream/libgstvaapi-x11.install.in docs/Makefile docs/reference/Makefile docs/reference/libs/Makefile @@ -444,9 +451,11 @@ debian.upstream/libgstvaapi-glx.install.in docs/reference/plugins/plugins-docs.xml gst-libs/Makefile gst-libs/gst/Makefile - gst-libs/gst/gstutils_version.h gst-libs/gst/codecparsers/Makefile + gst-libs/gst/gstutils_version.h gst-libs/gst/vaapi/Makefile + gst/Makefile + gst/vaapi/Makefile pkgconfig/Makefile pkgconfig/gstreamer-vaapi-$GST_MAJORMINOR.pc:\ pkgconfig/gstreamer-vaapi.pc.in @@ -454,8 +463,6 @@ pkgconfig/gstreamer-vaapi.pc.in pkgconfig/gstreamer-vaapi-glx.pc.in pkgconfig/gstreamer-vaapi-x11-$GST_MAJORMINOR.pc:\ pkgconfig/gstreamer-vaapi-x11.pc.in - gst/Makefile - gst/vaapi/Makefile tests/Makefile ]) AC_OUTPUT From bcae632c32dc97e5169689a37afde67994dfa4a3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Jul 2012 11:16:27 +0200 Subject: [PATCH 0733/3781] vaapisink: drop checks for new APIs used by default. GStreamer -base plugins >= 0.10.31 are now required, so the checks for new APIs like GstXOverlay::set_window_handle() and ::set_render_rectangle() are no longer necessary. --- configure.ac | 10 ----- gst-libs/gst/Makefile.am | 4 -- gst-libs/gst/gstutils_version.h.in | 61 ------------------------------ gst/vaapi/gstvaapisink.c | 35 ++--------------- 4 files changed, 3 insertions(+), 107 deletions(-) delete mode 100644 gst-libs/gst/gstutils_version.h.in diff --git a/configure.ac b/configure.ac index b6074ba977..09c0185000 100644 --- a/configure.ac +++ b/configure.ac @@ -163,15 +163,6 @@ PKG_CHECK_MODULES([GST_PLUGINS_BASE], PKG_CHECK_MODULES([GST_INTERFACES], [gstreamer-interfaces-$GST_MAJORMINOR >= gst_plugins_base_version]) -dnl ... GST_PLUGINS_BASE_CHECK_VERSION() implementation -V=`$PKG_CONFIG --modversion gstreamer-plugins-base-$GST_MAJORMINOR` -GST_PLUGINS_BASE_MAJOR_VERSION=`echo "$V" | cut -d'.' -f1` -GST_PLUGINS_BASE_MINOR_VERSION=`echo "$V" | cut -d'.' -f2` -GST_PLUGINS_BASE_MICRO_VERSION=`echo "$V" | cut -d'.' -f3` -AC_SUBST(GST_PLUGINS_BASE_MAJOR_VERSION) -AC_SUBST(GST_PLUGINS_BASE_MINOR_VERSION) -AC_SUBST(GST_PLUGINS_BASE_MICRO_VERSION) - dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], [gstreamer-video-$GST_MAJORMINOR >= gst_plugins_base_version]) @@ -452,7 +443,6 @@ debian.upstream/libgstvaapi-x11.install.in gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/codecparsers/Makefile - gst-libs/gst/gstutils_version.h gst-libs/gst/vaapi/Makefile gst/Makefile gst/vaapi/Makefile diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 68753be9ad..06d14db0df 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -1,8 +1,4 @@ SUBDIRS = codecparsers vaapi -gen_headers = gstutils_version.h -noinst_HEADERS = $(gen_headers) -EXTRA_DIST = gstutils_version.h.in - # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in $(gen_headers) diff --git a/gst-libs/gst/gstutils_version.h.in b/gst-libs/gst/gstutils_version.h.in deleted file mode 100644 index cc177b752f..0000000000 --- a/gst-libs/gst/gstutils_version.h.in +++ /dev/null @@ -1,61 +0,0 @@ -/* - * gstutils_version.h - GStreamer version utilities - * - * Copyright (C) 2011 Intel Corporation - * - * 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_UTILS_VERSION_H -#define GST_UTILS_VERSION_H - -/* gst-plugins-base version */ -#define GST_PLUGINS_BASE_MAJOR_VERSION @GST_PLUGINS_BASE_MAJOR_VERSION@ -#define GST_PLUGINS_BASE_MINOR_VERSION @GST_PLUGINS_BASE_MINOR_VERSION@ -#define GST_PLUGINS_BASE_MICRO_VERSION @GST_PLUGINS_BASE_MICRO_VERSION@ - -/** - * GST_UTILS_CHECK_VERSION: - * @major: major version, like 1 in 1.2.3 - * @minor: minor version, like 2 in 1.2.3 - * @micro: micro version, like 3 in 1.2.3 - * - * Evaluates to %TRUE if the version of gst-plugins-base is equal or - * greater than @major, @minor and @micro - */ -#define GST_UTILS_CHECK_VERSION(major,minor,micro, rmajor,rminor,rmicro) \ - ((rmajor) > (major) || \ - ((rmajor) == (major) && (rminor) > (minor)) || \ - ((rmajor) == (major) && (rminor) == (minor) && (rmicro) >= (micro))) - -/** - * GST_PLUGINS_BASE_CHECK_VERSION: - * @major: major version, like 1 in 1.2.3 - * @minor: minor version, like 2 in 1.2.3 - * @micro: micro version, like 3 in 1.2.3 - * - * Evaluates to %TRUE if the version of gst-plugins-base is greater - * than @major, @minor and @micro - */ -#ifndef GST_PLUGINS_BASE_CHECK_VERSION -#define GST_PLUGINS_BASE_CHECK_VERSION(major,minor,micro) \ - GST_UTILS_CHECK_VERSION(major,minor,micro, \ - GST_PLUGINS_BASE_MAJOR_VERSION, \ - GST_PLUGINS_BASE_MINOR_VERSION, \ - GST_PLUGINS_BASE_MICRO_VERSION) -#endif - -#endif /* GST_UTILS_VERSION_H */ diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index b3c8e04adf..2165038cd7 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -31,7 +31,6 @@ #include "config.h" #include -#include #include #include #include @@ -49,12 +48,6 @@ #include "gstvaapisink.h" #include "gstvaapipluginutil.h" -#define HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE \ - GST_PLUGINS_BASE_CHECK_VERSION(0,10,31) - -#define HAVE_GST_XOVERLAY_SET_RENDER_RECTANGLE \ - GST_PLUGINS_BASE_CHECK_VERSION(0,10,29) - #define GST_PLUGIN_NAME "vaapisink" #define GST_PLUGIN_DESC "A VA-API based videosink" @@ -148,8 +141,8 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id); static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); -static inline void -_gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, guintptr window_id) +static void +gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); @@ -158,24 +151,9 @@ _gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, guintptr window_id) sink->use_glx = FALSE; sink->foreign_window = TRUE; - gst_vaapisink_ensure_window_xid(sink, window_id); + gst_vaapisink_ensure_window_xid(sink, window); } -#if HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE -static void -gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window_id) -{ - _gst_vaapisink_xoverlay_set_xid(overlay, window_id); -} -#else -static void -gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid) -{ - _gst_vaapisink_xoverlay_set_xid(overlay, xid); -} -#endif - -#if HAVE_GST_XOVERLAY_SET_RENDER_RECTANGLE static void gst_vaapisink_xoverlay_set_render_rectangle( GstXOverlay *overlay, @@ -197,7 +175,6 @@ gst_vaapisink_xoverlay_set_render_rectangle( display_rect->x, display_rect->y, display_rect->width, display_rect->height); } -#endif static void gst_vaapisink_xoverlay_expose(GstXOverlay *overlay) @@ -215,14 +192,8 @@ gst_vaapisink_xoverlay_expose(GstXOverlay *overlay) static void gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface) { -#if HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE iface->set_window_handle = gst_vaapisink_xoverlay_set_window_handle; -#else - iface->set_xwindow_id = gst_vaapisink_xoverlay_set_xid; -#endif -#if HAVE_GST_XOVERLAY_SET_RENDER_RECTANGLE iface->set_render_rectangle = gst_vaapisink_xoverlay_set_render_rectangle; -#endif iface->expose = gst_vaapisink_xoverlay_expose; } From 9491a35731cc4c287287347c2c4628febddcc0e6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Jul 2012 11:45:15 +0200 Subject: [PATCH 0734/3781] Drop support for obsolete VA-API versions < 0.30.4. --- configure.ac | 77 ++++++------------------ gst-libs/gst/vaapi/gstvaapicompat.h | 53 +--------------- gst-libs/gst/vaapi/gstvaapidisplay.h | 7 +-- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 7 +-- gst-libs/gst/vaapi/gstvaapiutils.h | 7 +-- 5 files changed, 23 insertions(+), 128 deletions(-) diff --git a/configure.ac b/configure.ac index 09c0185000..d0209fc379 100644 --- a/configure.ac +++ b/configure.ac @@ -42,6 +42,7 @@ m4_define([gst_plugins_bad_version], [gst_plugins_bad_major_version.gst_plugins_bad_minor_version.gst_plugins_bad_micro_version]) # VA-API minimum version number +m4_define([va_api_version], [0.30.4]) m4_define([va_api_x11_version], [0.31.0]) m4_define([va_api_glx_version], [0.32.0]) @@ -296,69 +297,35 @@ dnl --------------------------------------------------------------------------- dnl -- VA-API -- dnl --------------------------------------------------------------------------- -dnl Check for VA-API +dnl Core API LIBVA_PKGNAME="libva" -PKG_CHECK_MODULES(LIBVA, [$LIBVA_PKGNAME]) +PKG_CHECK_MODULES(LIBVA, [$LIBVA_PKGNAME >= va_api_version]) AC_SUBST(LIBVA_PKGNAME) -dnl ... original VA-API 0.29 -AC_CACHE_CHECK([for old VA-API 0.29], - ac_cv_have_vaapi_old, [ - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $LIBVA_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[vaGetDisplay(NULL)]])], - [ac_cv_have_vaapi_old="yes"], - [ac_cv_have_vaapi_old="no"] - ) - CFLAGS="$saved_CFLAGS" - LIBS="$saved_LIBS" -]) -if test "$ac_cv_have_vaapi_old" = "yes"; then - LIBVA_EXTRA_CFLAGS="$LIBVA_CFLAGS -DGST_VAAPI_USE_OLD_VAAPI_0_29" -fi +VA_VERSION=`$PKG_CONFIG --modversion libva` +VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1` +VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2` +VA_MICRO_VERSION=`echo "$VA_VERSION" | cut -d'.' -f3` +VA_VERSION_STR="$VA_VERSION" -dnl ... VA-API >= 0.31 or -sds +dnl VA/X11 API LIBVA_X11_PKGNAME="libva-x11" -PKG_CHECK_MODULES(LIBVA_X11, [$LIBVA_X11_PKGNAME], - [ac_cv_have_vaapi_x11="yes"], - [ac_cv_have_vaapi_x11="no"] -) -if test "$ac_cv_have_vaapi_x11" = "no"; then - if test "$ac_cv_have_vaapi_old" = "yes"; then - LIBVA_X11_PKGNAME="libva" - CFLAGS="$CFLAGS $LIBVA_EXTRA_CFLAGS" - LIBS="$LIBS $LIBVA_EXTRA_LIBS" - else - AC_MSG_ERROR([could not find VA-API]) - fi -fi +PKG_CHECK_MODULES(LIBVA_X11, [$LIBVA_X11_PKGNAME >= va_api_x11_version]) AC_SUBST(LIBVA_X11_PKGNAME) -dnl ... VA-API >= 0.31 or -sds (VA/GLX extensions) -USE_VAAPI_GLX=0 +dnl VA/GLX API +HAVE_VA_GLX=0 +LIBVA_GLX_PKGNAME="libva-glx" if test $USE_GLX -eq 1; then - if test "$enable_vaapi_glx" = "yes"; then - LIBVA_GLX_PKGNAME="libva-glx" - PKG_CHECK_MODULES(LIBVA_GLX, [$LIBVA_GLX_PKGNAME], - [ac_cv_have_vaapi_glx="yes" USE_VAAPI_GLX=1], - [ac_cv_have_vaapi_glx="no"] - ) - fi - if test $USE_VAAPI_GLX -eq 0; then + PKG_CHECK_MODULES(LIBVA_GLX, [$LIBVA_GLX_PKGNAME >= va_api_glx_version], + [HAVE_VA_GLX=1]) + if test "$enable_vaapi_glx" = "yes" -a $HAVE_VA_GLX -eq 0; then AC_MSG_WARN([VA/GLX not found or disabled. Fallbacking to TFP+FBO]) LIBVA_GLX_PKGNAME="$LIBVA_X11_PKGNAME" fi fi AC_SUBST(LIBVA_GLX_PKGNAME) -AC_SUBST(LIBVA_EXTRA_CFLAGS) -AC_SUBST(LIBVA_EXTRA_LIBS) - dnl Check for JPEG decoding API (0.33+) USE_JPEG_DECODER=0 AC_CACHE_CHECK([for JPEG decoding API], @@ -401,20 +368,14 @@ AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) -AC_DEFINE_UNQUOTED(USE_VAAPI_GLX, $USE_VAAPI_GLX, +AC_DEFINE_UNQUOTED([USE_VAAPI_GLX], [$HAVE_VA_GLX], [Defined to 1 if VA/GLX is enabled]) -AM_CONDITIONAL(USE_VAAPI_GLX, test $USE_VAAPI_GLX -eq 1) +AM_CONDITIONAL([USE_VAAPI_GLX], [test $HAVE_VA_GLX -eq 1]) AC_DEFINE_UNQUOTED(USE_VAAPISINK_GLX, $USE_VAAPISINK_GLX, [Defined to 1 to enable GLX support to vaapisink]) AM_CONDITIONAL(USE_VAAPISINK_GLX, test $USE_VAAPISINK_GLX -eq 1) -VA_VERSION=`$PKG_CONFIG --modversion libva` -VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1` -VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2` -VA_MICRO_VERSION=`echo "$VA_VERSION" | cut -d'.' -f3` -VA_VERSION_STR="$VA_VERSION" - pkgconfigdir=${libdir}/pkgconfig AC_SUBST(pkgconfigdir) @@ -467,6 +428,6 @@ echo $PACKAGE configuration summary: echo echo VA-API version ................... : $VA_VERSION_STR echo GLX support ...................... : $(yesno $USE_GLX) -echo VA/GLX support ................... : $(yesno $USE_VAAPI_GLX) +echo VA/GLX support ................... : $(yesno $HAVE_VA_GLX) echo VaapiSink/GL ..................... : $(yesno $USE_VAAPISINK_GLX) echo diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 9ff4f3bca0..766bbe60ac 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -22,15 +22,7 @@ #ifndef GST_VAAPI_COMPAT_H #define GST_VAAPI_COMPAT_H -#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 -# include -# include -#else -# include -# if !VA_CHECK_VERSION(0,30,4) -# include -# endif -#endif +#include #if USE_VAAPI_GLX # include @@ -38,49 +30,6 @@ # define vaGetDisplayGLX(dpy) vaGetDisplay(dpy) #endif -/* Check for VA version */ -#ifndef VA_CHECK_VERSION -#define VA_MAJOR_VERSION 0 -#define VA_MINOR_VERSION 29 -#define VA_MICRO_VERSION 0 -#define VA_SDS_VERSION 0 -#define VA_CHECK_VERSION(major,minor,micro) \ - (VA_MAJOR_VERSION > (major) || \ - (VA_MAJOR_VERSION == (major) && VA_MINOR_VERSION > (minor)) || \ - (VA_MAJOR_VERSION == (major) && VA_MINOR_VERSION == (minor) && VA_MICRO_VERSION >= (micro))) -#endif - -/* Check for VA/SDS version */ -#ifndef VA_CHECK_VERSION_SDS -#define VA_CHECK_VERSION_SDS(major, minor, micro, sds) \ - (VA_CHECK_VERSION(major, minor, (micro)+1) || \ - (VA_CHECK_VERSION(major, minor, micro) && VA_SDS_VERSION >= (sds))) -#endif - -/* Compatibility glue with original VA-API 0.29 */ -#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 -typedef struct _VASliceParameterBufferBase { - unsigned int slice_data_size; - unsigned int slice_data_offset; - unsigned int slice_data_flag; -} VASliceParameterBufferBase; -#endif - -#ifndef VA_FOURCC -#define VA_FOURCC(ch0, ch1, ch2, ch3) \ - ((guint32)(guint8)(ch0) | \ - ((guint32)(guint8)(ch1) << 8) | \ - ((guint32)(guint8)(ch2) << 16) | \ - ((guint32)(guint8)(ch3) << 24 )) -#endif - -#ifndef VA_INVALID_ID -#define VA_INVALID_ID 0xffffffff -#endif -#ifndef VA_INVALID_SURFACE -#define VA_INVALID_SURFACE VA_INVALID_ID -#endif - /* Compatibility glue with VA-API < 0.31 */ #if !VA_CHECK_VERSION(0,31,0) #undef vaSyncSurface diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 7be56cae43..e68e9c3f54 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -23,12 +23,7 @@ #ifndef GST_VAAPI_DISPLAY_H #define GST_VAAPI_DISPLAY_H -#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 -# include -#else -# include -#endif - +#include #include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index a651dd6705..358f59f8a8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -22,12 +22,7 @@ #ifndef GST_VAAPI_DISPLAY_X11_H #define GST_VAAPI_DISPLAY_X11_H -#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 -# include -#else -# include -#endif - +#include #include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 5c75c8d743..9ee74f1947 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -25,12 +25,7 @@ #include "config.h" #include - -#ifdef GST_VAAPI_USE_OLD_VAAPI_0_29 -# include -#else -# include -#endif +#include /** Check VA status for success or print out an error */ G_GNUC_INTERNAL From b6c97e31ee5a306cf4b11dcce8619e441686072a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Jul 2012 14:44:27 +0200 Subject: [PATCH 0735/3781] configure: improve checks for GLX. --- configure.ac | 44 +++++++++++++++++++++++++--------- gst-libs/gst/vaapi/Makefile.am | 4 ++-- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index d0209fc379..a8f6e009b4 100644 --- a/configure.ac +++ b/configure.ac @@ -277,21 +277,43 @@ dnl --------------------------------------------------------------------------- dnl Check for X11 PKG_CHECK_MODULES(X11, [x11]) -dnl Check for OpenGL -USE_GLX=1 -if test "$enable_glx" != "yes"; then - USE_GLX=0 +dnl OpenGL +enable_opengl="no" +if test "$enable_glx" = "yes"; then + enable_opengl="yes" fi -GLX_CFLAGS="" -GLX_LIBS="" -AC_CHECK_HEADERS([GL/gl.h GL/glext.h GL/glx.h], [], [USE_GLX=0], [ + +HAVE_GL=0 +if test "$enable_opengl" = "yes"; then + HAVE_GL=1 + PKG_CHECK_MODULES([GL], [gl], [:], [HAVE_GL=0]) + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GL_CFLAGS" + AC_CHECK_HEADERS([GL/gl.h GL/glext.h], [:], [HAVE_GL=0], [ #ifdef HAVE_GL_GL_H # include #endif -]) -AC_CHECK_LIB(GL, glXCreateContext, [GLX_LIBS="-lGL"], [USE_GLX=0]) -AC_SUBST(GLX_CFLAGS) -AC_SUBST(GLX_LIBS) + ]) + CPPFLAGS="$saved_CPPFLAGS" +fi + +dnl ... GLX +USE_GLX=0 +if test "$enable_glx" = "yes" -a $HAVE_GL -eq 1; then + USE_GLX=1 + saved_CPPFLAGS="$CPPFLAGS" + saved_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $GL_CFLAGS" + LIBS="$LIBS $GL_LIBS" + AC_CHECK_HEADERS([GL/glx.h], [:], [USE_GLX=0], [ +#ifdef HAVE_GL_GL_H +# include +#endif + ]) + AC_CHECK_LIB([GL], [glXCreateContext], [:], [USE_GLX=0]) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +fi dnl --------------------------------------------------------------------------- dnl -- VA-API -- diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 49f95c5d94..1ddf17fdf8 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -234,13 +234,13 @@ libgstvaapi_glx_@GST_MAJORMINOR@_la_CFLAGS = \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ - $(GLX_CFLAGS) \ + $(GL_CFLAGS) \ $(LIBVA_GLX_CFLAGS) \ $(NULL) libgstvaapi_glx_@GST_MAJORMINOR@_la_LIBADD = \ $(GLIB_LIBS) \ - $(GLX_LIBS) \ + $(GL_LIBS) \ $(LIBVA_GLX_LIBS) \ libgstvaapi-x11-@GST_MAJORMINOR@.la \ $(NULL) From 67fad5a27e10029bff85c206b8659be7b52ea063 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Jul 2012 15:57:26 +0200 Subject: [PATCH 0736/3781] configure: fix previous commit for GLX deps. --- tests/Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index e45b72f3de..ff1e09c79a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -14,7 +14,7 @@ endif TEST_CFLAGS = $(LIBVA_CFLAGS) -I$(top_srcdir)/gst-libs $(GST_CFLAGS) -DGST_USE_UNSTABLE_API TEST_X11_CFLAGS = -DUSE_X11 $(X11_CFLAGS) -TEST_GLX_CFLAGS = -DUSE_GLX $(GLX_CFLAGS) +TEST_GLX_CFLAGS = -DUSE_GLX $(X11_CFLAGS) $(GL_CFLAGS) TEST_MIX_CFLAGS = $(TEST_X11_CFLAGS) if USE_GLX TEST_MIX_CFLAGS += $(TEST_GLX_CFLAGS) @@ -31,7 +31,8 @@ TEST_X11_LIBS = \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la TEST_GLX_LIBS = \ - $(GLX_LIBS) \ + $(X11_LIBS) \ + $(GL_LIBS) \ $(GST_LIBS) \ $(LIBVA_GLX_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-@GST_MAJORMINOR@.la From 98f860f433a59798817000cbe7b81e2c2cb73af4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jul 2012 13:28:42 +0200 Subject: [PATCH 0737/3781] configure: improve checks for X11. --- configure.ac | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index a8f6e009b4..f78919c656 100644 --- a/configure.ac +++ b/configure.ac @@ -100,6 +100,11 @@ AC_PROG_CC AM_PROG_CC_C_O AC_PROG_LIBTOOL +AC_ARG_ENABLE(x11, + AS_HELP_STRING([--enable-x11], + [enable X11 output @<:@default=yes@:>@]), + [], [enable_x11="yes"]) + AC_ARG_ENABLE(glx, AS_HELP_STRING([--enable-glx], [enable OpenGL/X11 @<:@default=yes@:>@]), @@ -275,7 +280,16 @@ dnl -- Renderers -- dnl --------------------------------------------------------------------------- dnl Check for X11 -PKG_CHECK_MODULES(X11, [x11]) +USE_X11=0 +if test "$enable_x11" = "yes"; then + PKG_CHECK_MODULES(X11, [x11], [USE_X11=1], [USE_X11=0]) + if test $USE_X11 -eq 1; then + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $WAYLAND_CFLAGS" + AC_CHECK_HEADERS([X11/Xlib.h X11/Xutil.h X11/Xatom.h], [:], [USE_X11=0]) + CPPFLAGS="$saved_CPPFLAGS" + fi +fi dnl OpenGL enable_opengl="no" @@ -299,7 +313,7 @@ fi dnl ... GLX USE_GLX=0 -if test "$enable_glx" = "yes" -a $HAVE_GL -eq 1; then +if test "$enable_glx" = "yes" -a $HAVE_GL -eq 1 -a $USE_X11 -eq 1; then USE_GLX=1 saved_CPPFLAGS="$CPPFLAGS" saved_LIBS="$LIBS" @@ -331,8 +345,12 @@ VA_MICRO_VERSION=`echo "$VA_VERSION" | cut -d'.' -f3` VA_VERSION_STR="$VA_VERSION" dnl VA/X11 API +HAVE_VA_X11=0 LIBVA_X11_PKGNAME="libva-x11" -PKG_CHECK_MODULES(LIBVA_X11, [$LIBVA_X11_PKGNAME >= va_api_x11_version]) +if test $USE_X11 -eq 1; then + PKG_CHECK_MODULES(LIBVA_X11, [$LIBVA_X11_PKGNAME >= va_api_x11_version], + [HAVE_VA_X11=1], [USE_X11=0]) +fi AC_SUBST(LIBVA_X11_PKGNAME) dnl VA/GLX API @@ -382,10 +400,22 @@ dnl --------------------------------------------------------------------------- dnl -- Generate files and summary -- dnl --------------------------------------------------------------------------- +case ":$USE_X11:$USE_GLX:" in +*:1:*) + ;; +*) + AC_MSG_ERROR([No renderer is enabled]) + ;; +esac + AC_DEFINE_UNQUOTED(USE_JPEG_DECODER, $USE_JPEG_DECODER, [Defined to 1 if JPEG decoder is used]) AM_CONDITIONAL(USE_JPEG_DECODER, test $USE_JPEG_DECODER -eq 1) +AC_DEFINE_UNQUOTED(USE_X11, $USE_X11, + [Defined to 1 if X11 is enabled]) +AM_CONDITIONAL(USE_X11, test $USE_X11 -eq 1) + AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) @@ -450,6 +480,7 @@ echo $PACKAGE configuration summary: echo echo VA-API version ................... : $VA_VERSION_STR echo GLX support ...................... : $(yesno $USE_GLX) +echo VA/X11 support ................... : $(yesno $USE_X11) echo VA/GLX support ................... : $(yesno $HAVE_VA_GLX) echo VaapiSink/GL ..................... : $(yesno $USE_VAAPISINK_GLX) echo From 37bf5a669e3624eeffe755bd11855c822a497336 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Jul 2012 16:37:01 +0200 Subject: [PATCH 0738/3781] tests: simplify build with various display options. --- tests/Makefile.am | 81 ++++++++++++++++++++++---------------------- tests/test-display.c | 9 ++--- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index ff1e09c79a..c3d4666dd1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,73 +1,72 @@ -noinst_PROGRAMS = \ - test-decode \ - test-display \ - test-surfaces \ - test-windows \ - test-subpicture \ +noinst_PROGRAMS = \ + test-decode \ + test-display \ + test-surfaces \ + test-windows \ + test-subpicture \ $(NULL) if USE_GLX -noinst_PROGRAMS += \ - test-textures \ +noinst_PROGRAMS += \ + test-textures \ $(NULL) endif -TEST_CFLAGS = $(LIBVA_CFLAGS) -I$(top_srcdir)/gst-libs $(GST_CFLAGS) -DGST_USE_UNSTABLE_API -TEST_X11_CFLAGS = -DUSE_X11 $(X11_CFLAGS) -TEST_GLX_CFLAGS = -DUSE_GLX $(X11_CFLAGS) $(GL_CFLAGS) -TEST_MIX_CFLAGS = $(TEST_X11_CFLAGS) -if USE_GLX -TEST_MIX_CFLAGS += $(TEST_GLX_CFLAGS) -endif +TEST_CFLAGS = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + $(LIBVA_CFLAGS) \ + $(GST_CFLAGS) \ + $(NULL) TEST_LIBS = \ - $(GST_LIBS) \ + $(LIBVA_LIBS) \ + $(GST_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-@GST_MAJORMINOR@.la -TEST_X11_LIBS = \ - $(X11_LIBS) \ - $(GST_LIBS) \ - $(LIBVA_X11_LIBS) \ +if USE_X11 +TEST_CFLAGS += $(X11_CFLAGS) +TEST_LIBS += \ + $(LIBVA_X11_LIBS) \ + $(X11_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la +endif -TEST_GLX_LIBS = \ - $(X11_LIBS) \ - $(GL_LIBS) \ - $(GST_LIBS) \ - $(LIBVA_GLX_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-@GST_MAJORMINOR@.la - -TEST_MIX_LIBS = $(TEST_X11_LIBS) if USE_GLX -TEST_MIX_LIBS += $(TEST_GLX_LIBS) +TEST_CFLAGS += $(X11_CFLAGS) $(GL_CFLAGS) +TEST_LIBS += \ + $(LIBVA_GLX_LIBS) \ + $(X11_LIBS) \ + $(GL_LIBS) \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-@GST_MAJORMINOR@.la endif test_codecs_source_c = test-mpeg2.c test-h264.c test-vc1.c test-jpeg.c test_codecs_source_h = $(test_codecs_source_c:%.c=%.h) test_decode_SOURCES = test-decode.c $(test_codecs_source_c) -test_decode_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) -test_decode_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) +test_decode_CFLAGS = $(TEST_CFLAGS) +test_decode_LDADD = $(TEST_LIBS) test_display_SOURCES = test-display.c -test_display_CFLAGS = $(TEST_CFLAGS) $(TEST_MIX_CFLAGS) -test_display_LDADD = $(TEST_LIBS) $(TEST_MIX_LIBS) +test_display_CFLAGS = $(TEST_CFLAGS) +test_display_LDADD = $(TEST_LIBS) test_surfaces_SOURCES = test-surfaces.c -test_surfaces_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) -test_surfaces_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) +test_surfaces_CFLAGS = $(TEST_CFLAGS) +test_surfaces_LDADD = $(TEST_LIBS) test_subpicture_SOURCES = test-subpicture.c test-mpeg2.c test-subpicture-data.c -test_subpicture_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) -test_subpicture_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) +test_subpicture_CFLAGS = $(TEST_CFLAGS) +test_subpicture_LDADD = $(TEST_LIBS) test_windows_SOURCES = test-windows.c image.c -test_windows_CFLAGS = $(TEST_CFLAGS) $(TEST_X11_CFLAGS) -test_windows_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS) +test_windows_CFLAGS = $(TEST_CFLAGS) +test_windows_LDADD = $(TEST_LIBS) test_textures_SOURCES = test-textures.c image.c -test_textures_CFLAGS = $(TEST_CFLAGS) $(TEST_GLX_CFLAGS) -test_textures_LDADD = $(TEST_LIBS) $(TEST_GLX_LIBS) +test_textures_CFLAGS = $(TEST_CFLAGS) +test_textures_LDADD = $(TEST_LIBS) EXTRA_DIST = \ image.h \ diff --git a/tests/test-display.c b/tests/test-display.c index 302fc31675..12f7520522 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -19,11 +19,12 @@ * Boston, MA 02110-1301 USA */ +#include "config.h" #include -#ifdef USE_X11 +#if USE_X11 #include #endif -#ifdef USE_GLX +#if USE_GLX #include #endif @@ -155,7 +156,7 @@ main(int argc, char *argv[]) gst_init(&argc, &argv); -#ifdef USE_X11 +#if USE_X11 g_print("#\n"); g_print("# Create display with gst_vaapi_display_x11_new()\n"); g_print("#\n"); @@ -216,7 +217,7 @@ main(int argc, char *argv[]) g_print("\n"); #endif -#ifdef USE_GLX +#if USE_GLX g_print("#\n"); g_print("# Create display with gst_vaapi_display_glx_new()\n"); g_print("#\n"); From e58737db6e5e1a63e4077c4bd0385942c9f28e83 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jul 2012 14:11:16 +0200 Subject: [PATCH 0739/3781] tests: build convenience library for common utilities. --- tests/Makefile.am | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index c3d4666dd1..c6f73178f8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -44,34 +44,41 @@ endif test_codecs_source_c = test-mpeg2.c test-h264.c test-vc1.c test-jpeg.c test_codecs_source_h = $(test_codecs_source_c:%.c=%.h) +test_utils_source_c = image.c +test_utils_source_h = image.h + +noinst_LTLIBRARIES = libutils.la +libutils_la_SOURCES = $(test_utils_source_c) +libutils_la_CFLAGS = $(TEST_CFLAGS) + test_decode_SOURCES = test-decode.c $(test_codecs_source_c) test_decode_CFLAGS = $(TEST_CFLAGS) -test_decode_LDADD = $(TEST_LIBS) +test_decode_LDADD = libutils.la $(TEST_LIBS) test_display_SOURCES = test-display.c test_display_CFLAGS = $(TEST_CFLAGS) -test_display_LDADD = $(TEST_LIBS) +test_display_LDADD = libutils.la $(TEST_LIBS) test_surfaces_SOURCES = test-surfaces.c test_surfaces_CFLAGS = $(TEST_CFLAGS) -test_surfaces_LDADD = $(TEST_LIBS) +test_surfaces_LDADD = libutils.la $(TEST_LIBS) test_subpicture_SOURCES = test-subpicture.c test-mpeg2.c test-subpicture-data.c test_subpicture_CFLAGS = $(TEST_CFLAGS) -test_subpicture_LDADD = $(TEST_LIBS) +test_subpicture_LDADD = libutils.la $(TEST_LIBS) -test_windows_SOURCES = test-windows.c image.c +test_windows_SOURCES = test-windows.c test_windows_CFLAGS = $(TEST_CFLAGS) -test_windows_LDADD = $(TEST_LIBS) +test_windows_LDADD = libutils.la $(TEST_LIBS) -test_textures_SOURCES = test-textures.c image.c +test_textures_SOURCES = test-textures.c test_textures_CFLAGS = $(TEST_CFLAGS) -test_textures_LDADD = $(TEST_LIBS) +test_textures_LDADD = libutils.la $(TEST_LIBS) EXTRA_DIST = \ - image.h \ test-decode.h \ test-subpicture-data.h \ + $(test_utils_source_h) \ $(test_codecs_source_c) \ $(test_codecs_source_h) \ $(NULL) From 0c8dc604cb3e0e803f83e16a3d30e943cb24ebe9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jul 2012 14:15:42 +0200 Subject: [PATCH 0740/3781] tests: move encoded bitstreams to libutils.la. --- tests/Makefile.am | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index c6f73178f8..a2820b6af7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -42,10 +42,10 @@ TEST_LIBS += \ endif test_codecs_source_c = test-mpeg2.c test-h264.c test-vc1.c test-jpeg.c -test_codecs_source_h = $(test_codecs_source_c:%.c=%.h) +test_codecs_source_h = $(test_codecs_source_c:%.c=%.h) test-decode.h -test_utils_source_c = image.c -test_utils_source_h = image.h +test_utils_source_c = image.c $(test_codecs_source_c) +test_utils_source_h = image.h $(test_codecs_source_h) noinst_LTLIBRARIES = libutils.la libutils_la_SOURCES = $(test_utils_source_c) @@ -63,7 +63,7 @@ test_surfaces_SOURCES = test-surfaces.c test_surfaces_CFLAGS = $(TEST_CFLAGS) test_surfaces_LDADD = libutils.la $(TEST_LIBS) -test_subpicture_SOURCES = test-subpicture.c test-mpeg2.c test-subpicture-data.c +test_subpicture_SOURCES = test-subpicture.c test-subpicture-data.c test_subpicture_CFLAGS = $(TEST_CFLAGS) test_subpicture_LDADD = libutils.la $(TEST_LIBS) @@ -76,11 +76,8 @@ test_textures_CFLAGS = $(TEST_CFLAGS) test_textures_LDADD = libutils.la $(TEST_LIBS) EXTRA_DIST = \ - test-decode.h \ test-subpicture-data.h \ $(test_utils_source_h) \ - $(test_codecs_source_c) \ - $(test_codecs_source_h) \ $(NULL) # Extra clean files so that maintainer-clean removes *everything* From 9e0c97a3d3318322c9f1cd54c1a6af9468bf8b0f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jul 2012 15:17:03 +0200 Subject: [PATCH 0741/3781] tests: use common display and window creation routines. Add new --output option to select the renderer. Use --list-outputs to print a list of supported renderers. --- tests/Makefile.am | 4 +- tests/output.c | 157 ++++++++++++++++++++++++++++++++++++++++ tests/output.h | 55 ++++++++++++++ tests/test-decode.c | 20 ++--- tests/test-subpicture.c | 18 ++--- tests/test-surfaces.c | 9 ++- 6 files changed, 232 insertions(+), 31 deletions(-) create mode 100644 tests/output.c create mode 100644 tests/output.h diff --git a/tests/Makefile.am b/tests/Makefile.am index a2820b6af7..71c5531004 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -44,8 +44,8 @@ endif test_codecs_source_c = test-mpeg2.c test-h264.c test-vc1.c test-jpeg.c test_codecs_source_h = $(test_codecs_source_c:%.c=%.h) test-decode.h -test_utils_source_c = image.c $(test_codecs_source_c) -test_utils_source_h = image.h $(test_codecs_source_h) +test_utils_source_c = image.c output.c $(test_codecs_source_c) +test_utils_source_h = image.h output.h $(test_codecs_source_h) noinst_LTLIBRARIES = libutils.la libutils_la_SOURCES = $(test_utils_source_c) diff --git a/tests/output.c b/tests/output.c new file mode 100644 index 0000000000..dd76bc7391 --- /dev/null +++ b/tests/output.c @@ -0,0 +1,157 @@ +/* + * output.c - Video output helpers + * + * Copyright (C) 2012 Intel Corporation + * + * 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 "config.h" +#include +#include +#if USE_X11 +# include +# include +#endif +#include "output.h" + +static const VideoOutputInfo *g_video_output; +static const VideoOutputInfo g_video_outputs[] = { + /* Video outputs are sorted in test order for automatic characterisation */ +#if USE_X11 + { "x11", + gst_vaapi_display_x11_new, + gst_vaapi_window_x11_new + }, +#endif + { NULL, } +}; + +static gchar *g_output_name; +static gboolean g_list_outputs = FALSE; + +static GOptionEntry g_options[] = { + { "list-outputs", 0, + 0, + G_OPTION_ARG_NONE, &g_list_outputs, + "list video outputs", NULL }, + { "output", 'o', + 0, + G_OPTION_ARG_STRING, &g_output_name, + "video output name", NULL }, + { NULL, } +}; + +static void +list_outputs(void) +{ + const VideoOutputInfo *o; + + g_print("Video outputs:"); + for (o = g_video_outputs; o->name != NULL; o++) + g_print(" %s", o->name); + g_print("\n"); +} + +gboolean +video_output_init(int *argc, char *argv[], GOptionEntry *options) +{ + GOptionContext *ctx; + gboolean success; + +#if !GLIB_CHECK_VERSION(2,31,0) + if (!g_thread_supported()) + g_thread_init(NULL); +#endif + + ctx = g_option_context_new("- test options"); + if (!ctx) + return FALSE; + + g_option_context_add_group(ctx, gst_init_get_option_group()); + g_option_context_add_main_entries(ctx, g_options, NULL); + if (options) + g_option_context_add_main_entries(ctx, options, NULL); + success = g_option_context_parse(ctx, argc, &argv, NULL); + g_option_context_free(ctx); + + if (g_list_outputs) { + list_outputs(); + exit(0); + } + return success; +} + +void +video_output_exit(void) +{ + g_free(g_output_name); + gst_deinit(); +} + +const VideoOutputInfo * +video_output_lookup(const gchar *output_name) +{ + const VideoOutputInfo *o; + + if (!output_name) + return NULL; + + for (o = g_video_outputs; o->name != NULL; o++) { + if (g_ascii_strcasecmp(o->name, output_name) == 0) + return o; + } + return NULL; +} + +GstVaapiDisplay * +video_output_create_display(const gchar *display_name) +{ + const VideoOutputInfo *o = g_video_output; + GstVaapiDisplay *display = NULL; + + if (!o) { + if (g_output_name) + o = video_output_lookup(g_output_name); + else { + for (o = g_video_outputs; o->name != NULL; o++) { + display = o->create_display(display_name); + if (display) { + if (gst_vaapi_display_get_display(display)) + break; + g_object_unref(display); + display = NULL; + } + } + } + if (!o || !o->name) + return NULL; + g_print("Using %s video output\n", o->name); + g_video_output = o; + } + + if (!display) + display = o->create_display(display_name); + return display; +} + +GstVaapiWindow * +video_output_create_window(GstVaapiDisplay *display, guint width, guint height) +{ + if (!g_video_output) + return NULL; + return g_video_output->create_window(display, width, height); +} diff --git a/tests/output.h b/tests/output.h new file mode 100644 index 0000000000..3377915491 --- /dev/null +++ b/tests/output.h @@ -0,0 +1,55 @@ +/* + * output.h - Video output helpers + * + * Copyright (C) 2012 Intel Corporation + * + * 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 OUTPUT_H +#define OUTPUT_H + +#include +#include +#include + +typedef GstVaapiDisplay *(*CreateDisplayFunc)(const gchar *display_name); +typedef GstVaapiWindow *(*CreateWindowFunc)(GstVaapiDisplay *display, + guint width, guint height); + +typedef struct _VideoOutputInfo VideoOutputInfo; +struct _VideoOutputInfo { + const gchar *name; + CreateDisplayFunc create_display; + CreateWindowFunc create_window; +}; + +gboolean +video_output_init(int *argc, char *argv[], GOptionEntry *options); + +void +video_output_exit(void); + +const VideoOutputInfo * +video_output_lookup(const gchar *output_name); + +GstVaapiDisplay * +video_output_create_display(const gchar *display_name); + +GstVaapiWindow * +video_output_create_window(GstVaapiDisplay *display, guint width, guint height); + +#endif /* OUTPUT_H */ diff --git a/tests/test-decode.c b/tests/test-decode.c index ef1f36efa4..a425f822a0 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -22,8 +22,6 @@ #include "config.h" #include -#include -#include #include #include #include @@ -34,6 +32,7 @@ #include "test-mpeg2.h" #include "test-h264.h" #include "test-vc1.h" +#include "output.h" /* Set to 1 to check display cache works (shared VA display) */ #define CHECK_DISPLAY_CACHE 1 @@ -85,7 +84,6 @@ static GOptionEntry g_options[] = { int main(int argc, char *argv[]) { - GOptionContext *options; GstVaapiDisplay *display, *display2; GstVaapiWindow *window; GstVaapiDecoder *decoder; @@ -100,12 +98,8 @@ main(int argc, char *argv[]) static const guint win_width = 640; static const guint win_height = 480; - gst_init(&argc, &argv); - - options = g_option_context_new(" - test-decode options"); - g_option_context_add_main_entries(options, g_options, NULL); - g_option_context_parse(options, &argc, &argv, NULL); - g_option_context_free(options); + if (!video_output_init(&argc, argv, g_options)) + g_error("failed to initialize video output subsystem"); if (!g_codec_str) g_codec_str = g_strdup("h264"); @@ -115,18 +109,18 @@ main(int argc, char *argv[]) if (!codec) g_error("no %s codec data found", g_codec_str); - display = gst_vaapi_display_x11_new(NULL); + display = video_output_create_display(NULL); if (!display) g_error("could not create VA display"); if (CHECK_DISPLAY_CACHE) - display2 = gst_vaapi_display_x11_new(NULL); + display2 = video_output_create_display(NULL); else display2 = g_object_ref(display); if (!display2) g_error("could not create second VA display"); - window = gst_vaapi_window_x11_new(display, win_width, win_height); + window = video_output_create_window(display, win_width, win_height); if (!window) g_error("could not create window"); @@ -200,6 +194,6 @@ main(int argc, char *argv[]) g_object_unref(display); g_object_unref(display2); g_free(g_codec_str); - gst_deinit(); + video_output_exit(); return 0; } diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index b3d7c65f7a..7a65fe34c7 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -22,11 +22,10 @@ #include "config.h" #include -#include -#include #include #include #include +#include "output.h" #include "test-mpeg2.h" #include "test-subpicture-data.h" @@ -87,7 +86,6 @@ upload_image (guint8 *dst, const guint32 *src, guint size) int main(int argc, char *argv[]) { - GOptionContext *options; GstVaapiDisplay *display; GstVaapiWindow *window; GstVaapiDecoder *decoder = NULL; @@ -109,12 +107,8 @@ main(int argc, char *argv[]) static const guint win_width = 640; static const guint win_height = 480; - gst_init(&argc, &argv); - - options = g_option_context_new(" - test-decode options"); - g_option_context_add_main_entries(options, g_options, NULL); - g_option_context_parse(options, &argc, &argv, NULL); - g_option_context_free(options); + if (!video_output_init(&argc, argv, g_options)) + g_error("failed to initialize video output subsystem"); if (!g_codec_str) g_codec_str = g_strdup("mpeg2"); @@ -124,11 +118,11 @@ main(int argc, char *argv[]) if (!codec) g_error("no %s codec data found", g_codec_str); - display = gst_vaapi_display_x11_new(NULL); + display = video_output_create_display(NULL); if (!display) g_error("could not create VA display"); - window = gst_vaapi_window_x11_new(display, win_width, win_height); + window = video_output_create_window(display, win_width, win_height); if (!window) g_error("could not create window"); @@ -230,6 +224,6 @@ main(int argc, char *argv[]) g_object_unref(window); g_object_unref(display); g_free(g_codec_str); - gst_deinit(); + video_output_exit(); return 0; } diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index a6edb348bd..c236e5ee16 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -21,7 +21,7 @@ #include #include -#include +#include "output.h" #define MAX_SURFACES 4 @@ -46,9 +46,10 @@ main(int argc, char *argv[]) static const guint width = 320; static const guint height = 240; - gst_init(&argc, &argv); + if (!video_output_init(&argc, argv, NULL)) + g_error("failed to initialize video output subsystem"); - display = gst_vaapi_display_x11_new(NULL); + display = video_output_create_display(NULL); if (!display) g_error("could not create Gst/VA display"); @@ -126,6 +127,6 @@ main(int argc, char *argv[]) g_object_unref(pool); g_print("unref surface\n"); g_object_unref(surface); - gst_deinit(); + video_output_exit(); return 0; } From e9112cd3f40166e1913fce2c68da41f3f11cf8ce Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jul 2012 15:20:23 +0200 Subject: [PATCH 0742/3781] tests: allow GLX output, if available and selected. --- tests/output.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/output.c b/tests/output.c index dd76bc7391..583347c8af 100644 --- a/tests/output.c +++ b/tests/output.c @@ -26,6 +26,10 @@ # include # include #endif +#if USE_GLX +# include +# include +#endif #include "output.h" static const VideoOutputInfo *g_video_output; @@ -36,6 +40,12 @@ static const VideoOutputInfo g_video_outputs[] = { gst_vaapi_display_x11_new, gst_vaapi_window_x11_new }, +#endif +#if USE_GLX + { "glx", + gst_vaapi_display_glx_new, + gst_vaapi_window_glx_new + }, #endif { NULL, } }; From 7a0382130f0e7747753909f059fb1a664ecab529 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jul 2012 16:15:38 +0200 Subject: [PATCH 0743/3781] configure: drop check for --enable-vaapi-glx. This flag is obsolete. It was meant to explicitly enable/disable VA/GLX API support, or fallback to TFP+FBO if this API is not found. Now, we check for the VA/GLX API by default if --enable-glx is set. If this API is not found, we now default to use TFP+FBO. Note: TFP+FBO, i.e. using vaPutSurface() is now also a deprecated usage and will be removed in the future. If GLX rendering is requested, then the VA/GLX API shall be used as it covers most usages. e.g. AMD driver can't render to an X pixmap yet. --- configure.ac | 22 +++++++------------ gst-libs/gst/vaapi/gstvaapicompat.h | 6 ++++++ gst/vaapi/Makefile.am | 14 +++++++----- gst/vaapi/gstvaapidecode.c | 4 ++-- gst/vaapi/gstvaapidownload.c | 4 ++-- gst/vaapi/gstvaapipluginutil.c | 33 +++++++++++++++-------------- gst/vaapi/gstvaapipostproc.c | 2 +- gst/vaapi/gstvaapiupload.c | 4 ++-- tests/test-display.c | 6 +++--- 9 files changed, 50 insertions(+), 45 deletions(-) diff --git a/configure.ac b/configure.ac index f78919c656..7aca8b5467 100644 --- a/configure.ac +++ b/configure.ac @@ -107,14 +107,9 @@ AC_ARG_ENABLE(x11, AC_ARG_ENABLE(glx, AS_HELP_STRING([--enable-glx], - [enable OpenGL/X11 @<:@default=yes@:>@]), + [enable OpenGL/X11 output @<:@default=yes@:>@]), [], [enable_glx="yes"]) -AC_ARG_ENABLE(vaapi-glx, - AS_HELP_STRING([--enable-vaapi-glx], - [enable VA/GLX extensions @<:@default=yes@:>@]), - [], [enable_vaapi_glx="yes"]) - AC_ARG_ENABLE(vaapisink-glx, AS_HELP_STRING([--enable-vaapisink-glx], [enable OpenGL/X11 to vaapisink @<:@default=yes@:>@]), @@ -358,10 +353,13 @@ HAVE_VA_GLX=0 LIBVA_GLX_PKGNAME="libva-glx" if test $USE_GLX -eq 1; then PKG_CHECK_MODULES(LIBVA_GLX, [$LIBVA_GLX_PKGNAME >= va_api_glx_version], - [HAVE_VA_GLX=1]) - if test "$enable_vaapi_glx" = "yes" -a $HAVE_VA_GLX -eq 0; then - AC_MSG_WARN([VA/GLX not found or disabled. Fallbacking to TFP+FBO]) - LIBVA_GLX_PKGNAME="$LIBVA_X11_PKGNAME" + [HAVE_VA_GLX=1], [LIBVA_GLX_PKGNAME="$LIBVA_X11_PKGNAME"]) + + if test $HAVE_VA_GLX -eq 1; then + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$LIBVA_GLX_CPPFLAGS" + AC_CHECK_HEADERS([va/va_glx.h], [:], [HAVE_VA_GLX=0]) + CPPFLAGS="$saved_CPPFLAGS" fi fi AC_SUBST(LIBVA_GLX_PKGNAME) @@ -420,10 +418,6 @@ AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) -AC_DEFINE_UNQUOTED([USE_VAAPI_GLX], [$HAVE_VA_GLX], - [Defined to 1 if VA/GLX is enabled]) -AM_CONDITIONAL([USE_VAAPI_GLX], [test $HAVE_VA_GLX -eq 1]) - AC_DEFINE_UNQUOTED(USE_VAAPISINK_GLX, $USE_VAAPISINK_GLX, [Defined to 1 to enable GLX support to vaapisink]) AM_CONDITIONAL(USE_VAAPISINK_GLX, test $USE_VAAPISINK_GLX -eq 1) diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 766bbe60ac..47cd7a3b6e 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -24,6 +24,12 @@ #include +#ifdef HAVE_VA_VA_GLX_H +# define USE_VAAPI_GLX 1 +#else +# define USE_VAAPI_GLX 0 +#endif + #if USE_VAAPI_GLX # include #else diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 3879fb626a..6a4175adc6 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -7,14 +7,18 @@ libgstvaapi_CFLAGS = \ -I$(top_builddir)/gst-libs \ $(NULL) -if USE_VAAPI_GLX -libgstvaapi_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la -else -libgstvaapi_LIBS = \ +libgstvaapi_LIBS = + +if USE_X11 +libgstvaapi_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la endif +if USE_GLX +libgstvaapi_LIBS += \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la +endif + libgstvaapi_la_SOURCES = \ gstvaapi.c \ gstvaapidecode.c \ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index adafed1251..1680b007f2 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -35,7 +35,7 @@ #include #include -#if USE_VAAPI_GLX +#if USE_GLX #include #define gst_vaapi_video_buffer_new(display) \ gst_vaapi_video_buffer_glx_new(GST_VAAPI_DISPLAY_GLX(display)) @@ -169,7 +169,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) gst_structure_set_value(structure, "interlaced", v_interlaced); gst_structure_set(structure, "type", G_TYPE_STRING, "vaapi", NULL); - gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, NULL); + gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_GLX, NULL); other_caps = gst_caps_copy(decode->srcpad_caps); success = gst_pad_set_caps(decode->srcpad, other_caps); diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 2358b41f01..7fdcbe628d 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -35,7 +35,7 @@ #include #include -#if USE_VAAPI_GLX +#if USE_GLX #include #define gst_vaapi_video_buffer_new_from_pool(pool) \ gst_vaapi_video_buffer_glx_new_from_pool(pool) @@ -493,7 +493,7 @@ gst_vaapidownload_transform_caps( gst_structure_set( structure, "type", G_TYPE_STRING, "vaapi", - "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, + "opengl", G_TYPE_BOOLEAN, USE_GLX, NULL ); } diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 168ae1ffe9..e026fa0665 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -22,19 +22,20 @@ */ #ifdef HAVE_CONFIG_H -#include +# include "config.h" +#endif +#include +#if USE_X11 +# include +#endif +#if USE_GLX +# include #endif #include "gstvaapipluginutil.h" #include -#if USE_VAAPI_GLX -#include -#else -#include -#endif - /* Preferred first */ static const char *display_types[] = { "gst-vaapi-display", @@ -60,12 +61,12 @@ gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display) gst_video_context_prepare (context, display_types); /* If no neighboor, or application not interested, use system default */ +#if USE_GLX if (!*display) -#if USE_VAAPI_GLX *display = gst_vaapi_display_glx_new (NULL); -#else - *display = gst_vaapi_display_x11_new (NULL); #endif + if (!*display) + *display = gst_vaapi_display_x11_new (NULL); /* FIXME allocator should return NULL in case of failure */ if (*display && !gst_vaapi_display_get_display(*display)) { @@ -85,18 +86,18 @@ gst_vaapi_set_display (const gchar *type, if (!strcmp (type, "x11-display-name")) { g_return_if_fail (G_VALUE_HOLDS_STRING (value)); -#if USE_VAAPI_GLX +#if USE_GLX dpy = gst_vaapi_display_glx_new (g_value_get_string (value)); -#else - dpy = gst_vaapi_display_x11_new (g_value_get_string (value)); #endif + if (!dpy) + dpy = gst_vaapi_display_x11_new (g_value_get_string (value)); } else if (!strcmp (type, "x11-display")) { g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); -#if USE_VAAPI_GLX +#if USE_GLX dpy = gst_vaapi_display_glx_new_with_display (g_value_get_pointer (value)); -#else - dpy = gst_vaapi_display_x11_new_with_display (g_value_get_pointer (value)); #endif + if (!dpy) + dpy = gst_vaapi_display_x11_new_with_display (g_value_get_pointer (value)); } else if (!strcmp (type, "vaapi-display")) { g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); dpy = gst_vaapi_display_new_with_display (g_value_get_pointer (value)); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 0f8ebf59c3..3b81830da6 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -401,7 +401,7 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps) gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); gst_structure_set(structure, "type", G_TYPE_STRING, "vaapi", NULL); - gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, NULL); + gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_GLX, NULL); if (!postproc->deinterlace) gst_structure_remove_field(structure, "interlaced"); diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 645756282f..9e5d513dcf 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -36,7 +36,7 @@ #include #include -#if USE_VAAPI_GLX +#if USE_GLX #include #define gst_vaapi_video_buffer_new_from_pool(pool) \ gst_vaapi_video_buffer_glx_new_from_pool(pool) @@ -471,7 +471,7 @@ gst_vaapiupload_transform_caps( gst_structure_set( structure, "type", G_TYPE_STRING, "vaapi", - "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX, + "opengl", G_TYPE_BOOLEAN, USE_GLX, NULL ); } diff --git a/tests/test-display.c b/tests/test-display.c index 12f7520522..47caa3d455 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -28,10 +28,8 @@ #include #endif -#if USE_VAAPI_GLX +#ifdef HAVE_VA_VA_GLX_H # include -#else -# define vaGetDisplayGLX(dpy) vaGetDisplay(dpy) #endif static void @@ -255,6 +253,7 @@ main(int argc, char *argv[]) } g_print("\n"); +#ifdef HAVE_VA_VA_GLX_H g_print("#\n"); g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayGLX()]\n"); g_print("#\n"); @@ -276,6 +275,7 @@ main(int argc, char *argv[]) XCloseDisplay(x11_display); } g_print("\n"); +#endif #endif gst_deinit(); From 8f132b79363d5bf9a1d00753bdb61fe504372cda Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jul 2012 17:49:08 +0200 Subject: [PATCH 0744/3781] configure: drop check for --enable-vaapisink-glx. vaapisink is now built with support for multiple display types, whenever they are enabled. The new "display" attribute is used to select a particular renderer. --- configure.ac | 17 ------- gst/vaapi/gstvaapipluginutil.c | 22 ++++++++ gst/vaapi/gstvaapipluginutil.h | 24 +++++++++ gst/vaapi/gstvaapisink.c | 92 +++++++++++++++++++++++----------- gst/vaapi/gstvaapisink.h | 9 ++-- 5 files changed, 111 insertions(+), 53 deletions(-) diff --git a/configure.ac b/configure.ac index 7aca8b5467..b3a26ef7de 100644 --- a/configure.ac +++ b/configure.ac @@ -110,11 +110,6 @@ AC_ARG_ENABLE(glx, [enable OpenGL/X11 output @<:@default=yes@:>@]), [], [enable_glx="yes"]) -AC_ARG_ENABLE(vaapisink-glx, - AS_HELP_STRING([--enable-vaapisink-glx], - [enable OpenGL/X11 to vaapisink @<:@default=yes@:>@]), - [], [enable_vaapisink_glx="no"]) - dnl Check for basic libraries AC_CHECK_LIB(m, tan) @@ -387,13 +382,6 @@ AC_CACHE_CHECK([for JPEG decoding API], LIBS="$saved_LIBS" ]) -dnl Check for OpenGL support to vaapisink -if test "$enable_vaapisink_glx:$USE_GLX" = "yes:1"; then - USE_VAAPISINK_GLX=1 -else - USE_VAAPISINK_GLX=0 -fi - dnl --------------------------------------------------------------------------- dnl -- Generate files and summary -- dnl --------------------------------------------------------------------------- @@ -418,10 +406,6 @@ AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) -AC_DEFINE_UNQUOTED(USE_VAAPISINK_GLX, $USE_VAAPISINK_GLX, - [Defined to 1 to enable GLX support to vaapisink]) -AM_CONDITIONAL(USE_VAAPISINK_GLX, test $USE_VAAPISINK_GLX -eq 1) - pkgconfigdir=${libdir}/pkgconfig AC_SUBST(pkgconfigdir) @@ -476,5 +460,4 @@ echo VA-API version ................... : $VA_VERSION_STR echo GLX support ...................... : $(yesno $USE_GLX) echo VA/X11 support ................... : $(yesno $USE_X11) echo VA/GLX support ................... : $(yesno $HAVE_VA_GLX) -echo VaapiSink/GL ..................... : $(yesno $USE_VAAPISINK_GLX) echo diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index e026fa0665..e500e5c5b0 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -189,3 +189,25 @@ gst_vaapi_append_surface_caps (GstCaps *out_caps, GstCaps *in_caps) } return TRUE; } + +GType +gst_vaapi_display_type_get_type(void) +{ + static GType g_type = 0; + + static const GEnumValue display_types[] = { + { GST_VAAPI_DISPLAY_TYPE_AUTO, + "Auto detection", "auto" }, + { GST_VAAPI_DISPLAY_TYPE_X11, + "VA/X11 display", "x11" }, +#if USE_GLX + { GST_VAAPI_DISPLAY_TYPE_GLX, + "VA/GLX display", "glx" }, +#endif + { 0, NULL, NULL }, + }; + + if (!g_type) + g_type = g_enum_register_static("GstVaapiDisplayType", display_types); + return g_type; +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index e879cd470a..8d684b0d98 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -21,13 +21,37 @@ * Boston, MA 02110-1301 USA */ +#ifndef GST_VAAPI_PLUGIN_UTIL_H +#define GST_VAAPI_PLUGIN_UTIL_H + #include #include #include +/** + * GstVaapiDisplayType: + * @GST_VAAPI_DISPLAY_TYPE_AUTO: Automatic detection of the display type. + * @GST_VAAPI_DISPLAY_TYPE_X11: VA/X11 display. + * @GST_VAAPI_DISPLAY_TYPE_GLX: VA/GLX display. + */ +typedef enum _GstVaapiDisplayType GstVaapiDisplayType; +enum _GstVaapiDisplayType { + GST_VAAPI_DISPLAY_TYPE_AUTO = 0, + GST_VAAPI_DISPLAY_TYPE_X11, + GST_VAAPI_DISPLAY_TYPE_GLX, +}; + +#define GST_VAAPI_TYPE_DISPLAY_TYPE \ + gst_vaapi_display_type_get_type() + +GType +gst_vaapi_display_type_get_type(void) G_GNUC_CONST; + gboolean gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display); void gst_vaapi_set_display (const gchar *type, const GValue *value, GstVaapiDisplay **display); gboolean gst_vaapi_reply_to_query (GstQuery *query, GstVaapiDisplay *display); gboolean gst_vaapi_append_surface_caps (GstCaps *out_caps, GstCaps *in_caps); + +#endif /* GST_VAAPI_PLUGIN_UTIL_H */ diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 2165038cd7..7fcf3724df 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -37,9 +37,9 @@ #include #include #include -#if USE_VAAPISINK_GLX -#include -#include +#if USE_GLX +# include +# include #endif /* Supported interfaces */ @@ -93,12 +93,14 @@ G_DEFINE_TYPE_WITH_CODE( enum { PROP_0, - PROP_USE_GLX, + PROP_DISPLAY_TYPE, PROP_FULLSCREEN, PROP_SYNCHRONOUS, PROP_USE_REFLECTION }; +#define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_X11 + /* GstImplementsInterface interface */ static gboolean @@ -148,7 +150,8 @@ gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window) /* Disable GLX rendering when vaapisink is using a foreign X window. It's pretty much useless */ - sink->use_glx = FALSE; + if (sink->display_type == GST_VAAPI_DISPLAY_TYPE_GLX) + sink->display_type = GST_VAAPI_DISPLAY_TYPE_X11; sink->foreign_window = TRUE; gst_vaapisink_ensure_window_xid(sink, window); @@ -257,6 +260,12 @@ configure_notify_event_pending( return args.match; } +static inline gboolean +gst_vaapisink_ensure_display(GstVaapiSink *sink) +{ + return gst_vaapi_ensure_display(sink, &sink->display); +} + static gboolean gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) { @@ -319,12 +328,19 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) GstVaapiDisplay * const display = sink->display; if (!sink->window) { -#if USE_VAAPISINK_GLX - if (sink->use_glx) + switch (sink->display_type) { +#if USE_GLX + case GST_VAAPI_DISPLAY_TYPE_GLX: sink->window = gst_vaapi_window_glx_new(display, width, height); - else + break; #endif + case GST_VAAPI_DISPLAY_TYPE_X11: sink->window = gst_vaapi_window_x11_new(display, width, height); + break; + default: + GST_ERROR("unsupported display type %d", sink->display_type); + return FALSE; + } if (sink->window) gst_x_overlay_got_window_handle( GST_X_OVERLAY(sink), @@ -342,7 +358,7 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) int x, y; XID xid = window_id; - if (!gst_vaapi_ensure_display(sink, &sink->display)) + if (!gst_vaapisink_ensure_display(sink)) return FALSE; gst_vaapi_display_lock(sink->display); @@ -368,12 +384,19 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) g_clear_object(&sink->window); -#if USE_VAAPISINK_GLX - if (sink->use_glx) + switch (sink->display_type) { +#if USE_GLX + case GST_VAAPI_DISPLAY_TYPE_GLX: sink->window = gst_vaapi_window_glx_new_with_xid(sink->display, xid); - else + break; #endif + case GST_VAAPI_DISPLAY_TYPE_X11: sink->window = gst_vaapi_window_x11_new_with_xid(sink->display, xid); + break; + default: + GST_ERROR("unsupported display type %d", sink->display_type); + return FALSE; + } return sink->window != NULL; } @@ -382,7 +405,7 @@ gst_vaapisink_start(GstBaseSink *base_sink) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - return gst_vaapi_ensure_display(sink, &sink->display); + return gst_vaapisink_ensure_display(sink); } static gboolean @@ -420,7 +443,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) gst_caps_replace(&sink->caps, caps); - if (!gst_vaapi_ensure_display(sink, &sink->display)) + if (!gst_vaapisink_ensure_display(sink)) return FALSE; gst_vaapi_display_get_size(sink->display, &display_width, &display_height); @@ -461,7 +484,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return gst_vaapisink_ensure_render_rect(sink, win_width, win_height); } -#if USE_VAAPISINK_GLX +#if USE_GLX static void render_background(GstVaapiSink *sink) { @@ -663,12 +686,20 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) composition, TRUE)) GST_WARNING("could not update subtitles"); -#if USE_VAAPISINK_GLX - if (sink->use_glx) + switch (sink->display_type) { +#if USE_GLX + case GST_VAAPI_DISPLAY_TYPE_GLX: success = gst_vaapisink_show_frame_glx(sink, surface, flags); - else + break; #endif + case GST_VAAPI_DISPLAY_TYPE_X11: success = gst_vaapisink_show_frame_x11(sink, surface, flags); + break; + default: + GST_ERROR("unsupported display type %d", sink->display_type); + success = FALSE; + break; + } return success ? GST_FLOW_OK : GST_FLOW_UNEXPECTED; } @@ -699,8 +730,8 @@ gst_vaapisink_set_property( GstVaapiSink * const sink = GST_VAAPISINK(object); switch (prop_id) { - case PROP_USE_GLX: - sink->use_glx = g_value_get_boolean(value); + case PROP_DISPLAY_TYPE: + sink->display_type = g_value_get_enum(value); break; case PROP_FULLSCREEN: sink->fullscreen = g_value_get_boolean(value); @@ -728,8 +759,8 @@ gst_vaapisink_get_property( GstVaapiSink * const sink = GST_VAAPISINK(object); switch (prop_id) { - case PROP_USE_GLX: - g_value_set_boolean(value, sink->use_glx); + case PROP_DISPLAY_TYPE: + g_value_set_enum(value, sink->display_type); break; case PROP_FULLSCREEN: g_value_set_boolean(value, sink->fullscreen); @@ -780,16 +811,17 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) gst_element_class_add_pad_template(element_class, pad_template); gst_object_unref(pad_template); -#if USE_VAAPISINK_GLX g_object_class_install_property (object_class, - PROP_USE_GLX, - g_param_spec_boolean("use-glx", - "GLX rendering", - "Enables GLX rendering", - TRUE, - G_PARAM_READWRITE)); + PROP_DISPLAY_TYPE, + g_param_spec_enum("display", + "display type", + "display type to use", + GST_VAAPI_TYPE_DISPLAY_TYPE, + GST_VAAPI_DISPLAY_TYPE_AUTO, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#if USE_GLX g_object_class_install_property (object_class, PROP_USE_REFLECTION, @@ -841,6 +873,6 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->foreign_window = FALSE; sink->fullscreen = FALSE; sink->synchronous = FALSE; - sink->use_glx = USE_VAAPISINK_GLX; + sink->display_type = DEFAULT_DISPLAY_TYPE; sink->use_reflection = FALSE; } diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index b22a8d39ee..c5883b3c52 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -26,10 +26,10 @@ #include #include #include -#if USE_VAAPISINK_GLX +#if USE_GLX #include #endif -#include +#include "gstvaapipluginutil.h" G_BEGIN_DECLS @@ -59,10 +59,7 @@ G_BEGIN_DECLS typedef struct _GstVaapiSink GstVaapiSink; typedef struct _GstVaapiSinkClass GstVaapiSinkClass; - -#if !USE_VAAPISINK_GLX typedef struct _GstVaapiTexture GstVaapiTexture; -#endif struct _GstVaapiSink { /*< private >*/ @@ -70,6 +67,7 @@ struct _GstVaapiSink { GstCaps *caps; GstVaapiDisplay *display; + GstVaapiDisplayType display_type; GstVaapiWindow *window; guint window_width; guint window_height; @@ -82,7 +80,6 @@ struct _GstVaapiSink { guint foreign_window : 1; guint fullscreen : 1; guint synchronous : 1; - guint use_glx : 1; guint use_reflection : 1; }; From 96040a0fa2f96eb473b84f16309dac90e0f2bd84 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jul 2012 17:54:58 +0200 Subject: [PATCH 0745/3781] configure: simplify video outputs summary. --- configure.ac | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index b3a26ef7de..7ef92f3423 100644 --- a/configure.ac +++ b/configure.ac @@ -453,11 +453,13 @@ yesno() { test $1 -eq 1 && echo yes || echo no } +VIDEO_OUTPUTS="" +AS_IF([test $USE_X11 -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS x11"]) +AS_IF([test $USE_GLX -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS glx"]) + echo echo $PACKAGE configuration summary: echo echo VA-API version ................... : $VA_VERSION_STR -echo GLX support ...................... : $(yesno $USE_GLX) -echo VA/X11 support ................... : $(yesno $USE_X11) -echo VA/GLX support ................... : $(yesno $HAVE_VA_GLX) +echo Video outputs .................... : $VIDEO_OUTPUTS echo From aa64ce0bede54466bfab34cdcdd9f10de101784a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jul 2012 18:01:26 +0200 Subject: [PATCH 0746/3781] pluginutils: cosmetics (indentation fixes). --- gst/vaapi/gstvaapipluginutil.c | 252 +++++++++++++++++---------------- gst/vaapi/gstvaapipluginutil.h | 17 ++- 2 files changed, 139 insertions(+), 130 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index e500e5c5b0..ce16a43741 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -25,169 +25,171 @@ # include "config.h" #endif #include +#include #if USE_X11 # include #endif #if USE_GLX # include #endif - #include "gstvaapipluginutil.h" -#include - /* Preferred first */ static const char *display_types[] = { - "gst-vaapi-display", - "vaapi-display", - "x11-display", - "x11-display-name", - NULL + "gst-vaapi-display", + "vaapi-display", + "x11-display", + "x11-display-name", + NULL }; gboolean -gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display) +gst_vaapi_ensure_display(gpointer element, GstVaapiDisplay **display) { - GstVideoContext *context; + GstVideoContext *context; - g_return_val_if_fail (GST_IS_VIDEO_CONTEXT (element), FALSE); - g_return_val_if_fail (display != NULL, FALSE); + g_return_val_if_fail(GST_IS_VIDEO_CONTEXT(element), FALSE); + g_return_val_if_fail(display != NULL, FALSE); - /* Already exist ? */ - if (*display) - return TRUE; + /* Already exist ? */ + if (*display) + return TRUE; - context = GST_VIDEO_CONTEXT (element); - gst_video_context_prepare (context, display_types); + context = GST_VIDEO_CONTEXT(element); + gst_video_context_prepare(context, display_types); - /* If no neighboor, or application not interested, use system default */ + /* If no neighboor, or application not interested, use system default */ #if USE_GLX - if (!*display) - *display = gst_vaapi_display_glx_new (NULL); + if (!*display) + *display = gst_vaapi_display_glx_new(NULL); #endif - if (!*display) - *display = gst_vaapi_display_x11_new (NULL); + if (!*display) + *display = gst_vaapi_display_x11_new(NULL); - /* FIXME allocator should return NULL in case of failure */ - if (*display && !gst_vaapi_display_get_display(*display)) { - g_object_unref (*display); - *display = NULL; - } - - return (*display != NULL); + /* FIXME allocator should return NULL in case of failure */ + if (*display && !gst_vaapi_display_get_display(*display)) { + g_object_unref(*display); + *display = NULL; + } + return (*display != NULL); } void -gst_vaapi_set_display (const gchar *type, - const GValue *value, - GstVaapiDisplay **display) +gst_vaapi_set_display( + const gchar *type, + const GValue *value, + GstVaapiDisplay **display +) { - GstVaapiDisplay *dpy = NULL; + GstVaapiDisplay *dpy = NULL; - if (!strcmp (type, "x11-display-name")) { - g_return_if_fail (G_VALUE_HOLDS_STRING (value)); + if (!strcmp(type, "x11-display-name")) { + g_return_if_fail(G_VALUE_HOLDS_STRING(value)); #if USE_GLX - dpy = gst_vaapi_display_glx_new (g_value_get_string (value)); + dpy = gst_vaapi_display_glx_new(g_value_get_string(value)); #endif - if (!dpy) - dpy = gst_vaapi_display_x11_new (g_value_get_string (value)); - } else if (!strcmp (type, "x11-display")) { - g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); + if (!dpy) + dpy = gst_vaapi_display_x11_new(g_value_get_string(value)); + } + else if (!strcmp(type, "x11-display")) { + g_return_if_fail(G_VALUE_HOLDS_POINTER(value)); #if USE_GLX - dpy = gst_vaapi_display_glx_new_with_display (g_value_get_pointer (value)); + dpy = gst_vaapi_display_glx_new_with_display(g_value_get_pointer(value)); #endif - if (!dpy) - dpy = gst_vaapi_display_x11_new_with_display (g_value_get_pointer (value)); - } else if (!strcmp (type, "vaapi-display")) { - g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); - dpy = gst_vaapi_display_new_with_display (g_value_get_pointer (value)); - } else if (!strcmp (type, "gst-vaapi-display")) { - g_return_if_fail (G_VALUE_HOLDS_OBJECT (value)); - dpy = g_value_dup_object (value); - } - - if (dpy) { - if (*display) - g_object_unref (*display); - *display = dpy; - } -} - -gboolean -gst_vaapi_reply_to_query (GstQuery *query, GstVaapiDisplay *display) -{ - const gchar **types; - const gchar *type; - gint i; - gboolean res = FALSE; - - if (!display) - return FALSE; - - types = gst_video_context_query_get_supported_types (query); - - if (!types) - return FALSE; - - for (i = 0; types[i]; i++) { - type = types[i]; - - if (!strcmp (type, "gst-vaapi-display")) { - gst_video_context_query_set_object (query, type, G_OBJECT (display)); - - } else if (!strcmp (type, "vaapi-display")) { - VADisplay vadpy = gst_vaapi_display_get_display(display); - gst_video_context_query_set_pointer (query, type, vadpy); - - } else if (!strcmp (type, "x11-display") && - GST_VAAPI_IS_DISPLAY_X11(display)) { - GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11 (display); - Display *x11dpy = gst_vaapi_display_x11_get_display (xvadpy); - gst_video_context_query_set_pointer (query, type, x11dpy); - - } else if (!strcmp (type, "x11-display-name") && - GST_VAAPI_IS_DISPLAY_X11(display)) { - GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11 (display); - Display *x11dpy = gst_vaapi_display_x11_get_display (xvadpy); - gst_video_context_query_set_string (query, type, DisplayString(x11dpy)); - - } else { - continue; + if (!dpy) + dpy = gst_vaapi_display_x11_new_with_display(g_value_get_pointer(value)); + } + else if (!strcmp(type, "vaapi-display")) { + g_return_if_fail(G_VALUE_HOLDS_POINTER(value)); + dpy = gst_vaapi_display_new_with_display(g_value_get_pointer(value)); + } + else if (!strcmp(type, "gst-vaapi-display")) { + g_return_if_fail(G_VALUE_HOLDS_OBJECT(value)); + dpy = g_value_dup_object(value); } - res = TRUE; - break; - } - - return res; + if (dpy) { + if (*display) + g_object_unref(*display); + *display = dpy; + } } gboolean -gst_vaapi_append_surface_caps (GstCaps *out_caps, GstCaps *in_caps) +gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) { - GstStructure *structure; - const GValue *v_width, *v_height, *v_framerate, *v_par; - guint i, n_structures; + const gchar **types; + const gchar *type; + gint i; + gboolean res = FALSE; - structure = gst_caps_get_structure (in_caps, 0); - v_width = gst_structure_get_value (structure, "width"); - v_height = gst_structure_get_value (structure, "height"); - v_framerate = gst_structure_get_value (structure, "framerate"); - v_par = gst_structure_get_value (structure, "pixel-aspect-ratio"); - if (!v_width || !v_height) - return FALSE; + if (!display) + return FALSE; - n_structures = gst_caps_get_size (out_caps); - for (i = 0; i < n_structures; i++) { - structure = gst_caps_get_structure (out_caps, i); - gst_structure_set_value (structure, "width", v_width); - gst_structure_set_value (structure, "height", v_height); - if (v_framerate) - gst_structure_set_value (structure, "framerate", v_framerate); - if (v_par) - gst_structure_set_value (structure, "pixel-aspect-ratio", v_par); - } - return TRUE; + types = gst_video_context_query_get_supported_types(query); + + if (!types) + return FALSE; + + for (i = 0; types[i]; i++) { + type = types[i]; + + if (!strcmp(type, "gst-vaapi-display")) { + gst_video_context_query_set_object(query, type, G_OBJECT(display)); + } + else if (!strcmp(type, "vaapi-display")) { + VADisplay vadpy = gst_vaapi_display_get_display(display); + gst_video_context_query_set_pointer(query, type, vadpy); + } + else if (!strcmp(type, "x11-display") && + GST_VAAPI_IS_DISPLAY_X11(display)) { + GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11(display); + Display *x11dpy = gst_vaapi_display_x11_get_display(xvadpy); + gst_video_context_query_set_pointer(query, type, x11dpy); + + } + else if (!strcmp(type, "x11-display-name") && + GST_VAAPI_IS_DISPLAY_X11(display)) { + GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11(display); + Display *x11dpy = gst_vaapi_display_x11_get_display(xvadpy); + gst_video_context_query_set_string(query, type, DisplayString(x11dpy)); + } + else { + continue; + } + + res = TRUE; + break; + } + return res; +} + +gboolean +gst_vaapi_append_surface_caps(GstCaps *out_caps, GstCaps *in_caps) +{ + GstStructure *structure; + const GValue *v_width, *v_height, *v_framerate, *v_par; + guint i, n_structures; + + structure = gst_caps_get_structure(in_caps, 0); + v_width = gst_structure_get_value(structure, "width"); + v_height = gst_structure_get_value(structure, "height"); + v_framerate = gst_structure_get_value(structure, "framerate"); + v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); + if (!v_width || !v_height) + return FALSE; + + n_structures = gst_caps_get_size(out_caps); + for (i = 0; i < n_structures; i++) { + structure = gst_caps_get_structure(out_caps, i); + gst_structure_set_value(structure, "width", v_width); + gst_structure_set_value(structure, "height", v_height); + if (v_framerate) + gst_structure_set_value(structure, "framerate", v_framerate); + if (v_par) + gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); + } + return TRUE; } GType diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 8d684b0d98..9c3812f7b4 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -24,8 +24,6 @@ #ifndef GST_VAAPI_PLUGIN_UTIL_H #define GST_VAAPI_PLUGIN_UTIL_H -#include -#include #include /** @@ -47,9 +45,18 @@ enum _GstVaapiDisplayType { GType gst_vaapi_display_type_get_type(void) G_GNUC_CONST; -gboolean gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display); -void gst_vaapi_set_display (const gchar *type, const GValue *value, GstVaapiDisplay **display); -gboolean gst_vaapi_reply_to_query (GstQuery *query, GstVaapiDisplay *display); +gboolean +gst_vaapi_ensure_display(gpointer element, GstVaapiDisplay **display); + +void +gst_vaapi_set_display( + const gchar *type, + const GValue *value, + GstVaapiDisplay **display +); + +gboolean +gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display); gboolean gst_vaapi_append_surface_caps (GstCaps *out_caps, GstCaps *in_caps); From 753a56e9a15964df7b4658bba8ad041a7f1fac76 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jul 2012 18:37:38 +0200 Subject: [PATCH 0747/3781] pluginutils: improve automatic display type selection. --- gst/vaapi/gstvaapidecode.c | 4 +- gst/vaapi/gstvaapidownload.c | 4 +- gst/vaapi/gstvaapipluginutil.c | 69 +++++++++++++++++++++++++++------- gst/vaapi/gstvaapipluginutil.h | 6 ++- gst/vaapi/gstvaapipostproc.c | 4 +- gst/vaapi/gstvaapisink.c | 4 +- gst/vaapi/gstvaapiupload.c | 2 +- 7 files changed, 69 insertions(+), 24 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1680b007f2..b2f31135ce 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -298,7 +298,7 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) GstStructure *structure; int version; - if (!gst_vaapi_ensure_display(decode, &decode->display)) + if (!gst_vaapi_ensure_display(decode, &decode->display, NULL)) return FALSE; dpy = decode->display; @@ -531,7 +531,7 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) if (decode->allowed_caps) return TRUE; - if (!gst_vaapi_ensure_display(decode, &decode->display)) + if (!gst_vaapi_ensure_display(decode, &decode->display, NULL)) goto error_no_display; decode_caps = gst_vaapi_display_get_decode_caps(decode->display); diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 7fdcbe628d..4908e52fbf 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -302,7 +302,7 @@ gst_vaapidownload_start(GstBaseTransform *trans) { GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - if (!gst_vaapi_ensure_display(download, &download->display)) + if (!gst_vaapi_ensure_display(download, &download->display, NULL)) return FALSE; return TRUE; } @@ -455,7 +455,7 @@ gst_vaapidownload_transform_caps( if (direction == GST_PAD_SINK) { if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) return NULL; - if (!gst_vaapi_ensure_display(download, &download->display)) + if (!gst_vaapi_ensure_display(download, &download->display, NULL)) return NULL; out_caps = gst_caps_from_string(gst_vaapidownload_yuv_caps_str); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ce16a43741..a0921343e4 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -43,35 +43,76 @@ static const char *display_types[] = { NULL }; +typedef struct { + const gchar *type_str; + GstVaapiDisplayType type; + GstVaapiDisplay * (*create_display)(const gchar *); +} DisplayMap; + +static const DisplayMap g_display_map[] = { +#if USE_GLX + { "glx", + GST_VAAPI_DISPLAY_TYPE_GLX, + gst_vaapi_display_glx_new }, +#endif +#if USE_X11 + { "x11", + GST_VAAPI_DISPLAY_TYPE_X11, + gst_vaapi_display_x11_new }, +#endif + { NULL, } +}; + gboolean -gst_vaapi_ensure_display(gpointer element, GstVaapiDisplay **display) +gst_vaapi_ensure_display( + gpointer element, + GstVaapiDisplay **display_ptr, + GstVaapiDisplayType *display_type_ptr +) { + GstVaapiDisplayType display_type = + display_type_ptr ? *display_type_ptr : GST_VAAPI_DISPLAY_TYPE_AUTO; + GstVaapiDisplay *display; GstVideoContext *context; + const DisplayMap *m; g_return_val_if_fail(GST_IS_VIDEO_CONTEXT(element), FALSE); - g_return_val_if_fail(display != NULL, FALSE); + g_return_val_if_fail(display_ptr != NULL, FALSE); /* Already exist ? */ - if (*display) + display = *display_ptr; + if (display) return TRUE; context = GST_VIDEO_CONTEXT(element); gst_video_context_prepare(context, display_types); /* If no neighboor, or application not interested, use system default */ -#if USE_GLX - if (!*display) - *display = gst_vaapi_display_glx_new(NULL); -#endif - if (!*display) - *display = gst_vaapi_display_x11_new(NULL); + for (m = g_display_map; m->type_str != NULL; m++) { + if (display_type != GST_VAAPI_DISPLAY_TYPE_AUTO && + display_type != m->type) + continue; - /* FIXME allocator should return NULL in case of failure */ - if (*display && !gst_vaapi_display_get_display(*display)) { - g_object_unref(*display); - *display = NULL; + display = m->create_display(NULL); + if (display) { + /* FIXME: allocator should return NULL if an error occurred */ + if (gst_vaapi_display_get_display(display)) { + display_type = m->type; + break; + } + g_object_unref(display); + display = NULL; + } + + if (display_type != GST_VAAPI_DISPLAY_TYPE_AUTO) + break; } - return (*display != NULL); + + if (display_ptr) + *display_ptr = display; + if (display_type_ptr) + *display_type_ptr = display_type; + return display != NULL; } void diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 9c3812f7b4..ac2487332a 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -46,7 +46,11 @@ GType gst_vaapi_display_type_get_type(void) G_GNUC_CONST; gboolean -gst_vaapi_ensure_display(gpointer element, GstVaapiDisplay **display); +gst_vaapi_ensure_display( + gpointer element, + GstVaapiDisplay **display, + GstVaapiDisplayType *display_type_ptr +); void gst_vaapi_set_display( diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 3b81830da6..bfd18c0e09 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -201,7 +201,7 @@ gst_video_context_interface_init(GstVideoContextInterface *iface) static gboolean gst_vaapipostproc_create(GstVaapiPostproc *postproc, GstCaps *caps) { - if (!gst_vaapi_ensure_display(postproc, &postproc->display)) + if (!gst_vaapi_ensure_display(postproc, &postproc->display, NULL)) return FALSE; gst_caps_replace(&postproc->postproc_caps, caps); @@ -230,7 +230,7 @@ gst_vaapipostproc_reset(GstVaapiPostproc *postproc, GstCaps *caps) static gboolean gst_vaapipostproc_start(GstVaapiPostproc *postproc) { - if (!gst_vaapi_ensure_display(postproc, &postproc->display)) + if (!gst_vaapi_ensure_display(postproc, &postproc->display, NULL)) return FALSE; return TRUE; } diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 7fcf3724df..7a992193af 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -99,7 +99,7 @@ enum { PROP_USE_REFLECTION }; -#define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_X11 +#define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_AUTO /* GstImplementsInterface interface */ @@ -263,7 +263,7 @@ configure_notify_event_pending( static inline gboolean gst_vaapisink_ensure_display(GstVaapiSink *sink) { - return gst_vaapi_ensure_display(sink, &sink->display); + return gst_vaapi_ensure_display(sink, &sink->display, &sink->display_type); } static gboolean diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 9e5d513dcf..fac9a7dddf 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -372,7 +372,7 @@ gst_vaapiupload_start(GstBaseTransform *trans) { GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - if (!gst_vaapi_ensure_display(upload, &upload->display)) + if (!gst_vaapi_ensure_display(upload, &upload->display, NULL)) return FALSE; return TRUE; From e52def47371f3934ee57a98717e3d13237accb4b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jul 2012 10:58:32 +0200 Subject: [PATCH 0748/3781] utils: fix gl_create_context() with parent context set. If GLX window was created from a foreign Display, then that same Display shall be used for subsequent glXMakeCurrent(). This means that gl_create_context() will now use the same Display that the parent, if available. This fixes cluttersink with the Intel GenX VA driver. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index bf7c3580d0..3821181394 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -309,8 +309,15 @@ gl_create_context(Display *dpy, int screen, GLContextState *parent) if (!cs) goto error; - cs->display = dpy; - cs->window = parent ? parent->window : None; + if (parent) { + cs->display = parent->display; + cs->window = parent->window; + screen = DefaultScreen(parent->display); + } + else { + cs->display = dpy; + cs->window = None; + } cs->visual = NULL; cs->context = NULL; cs->swapped_buffers = FALSE; @@ -327,14 +334,14 @@ gl_create_context(Display *dpy, int screen, GLContextState *parent) if (fbconfig_id == GLX_DONT_CARE) goto choose_fbconfig; - fbconfigs = glXGetFBConfigs(dpy, screen, &n_fbconfigs); + fbconfigs = glXGetFBConfigs(parent->display, screen, &n_fbconfigs); if (!fbconfigs) goto error; /* Find out a GLXFBConfig compatible with the parent context */ for (n = 0; n < n_fbconfigs; n++) { status = glXGetFBConfigAttrib( - dpy, + parent->display, fbconfigs[n], GLX_FBCONFIG_ID, &val ); @@ -347,7 +354,7 @@ gl_create_context(Display *dpy, int screen, GLContextState *parent) else { choose_fbconfig: fbconfigs = glXChooseFBConfig( - dpy, + cs->display, screen, fbconfig_attrs, &n_fbconfigs ); @@ -358,9 +365,9 @@ gl_create_context(Display *dpy, int screen, GLContextState *parent) n = 0; } - cs->visual = glXGetVisualFromFBConfig(dpy, fbconfigs[n]); + cs->visual = glXGetVisualFromFBConfig(cs->display, fbconfigs[n]); cs->context = glXCreateNewContext( - dpy, + cs->display, fbconfigs[n], GLX_RGBA_TYPE, parent ? parent->context : NULL, From e12ef8e6a24c75d4c4f70e9afd3457cbde5735b2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jul 2012 13:52:06 +0200 Subject: [PATCH 0749/3781] videobuffer: factor out base and GLX implementations. Introduce new typed constructors internal to gstreamer-vaapi plugin elements. This avoids duplication of code, and makes it possible to further implement generic video buffer creation routines that automatically map to base or GLX variants. --- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 130 +++++++++++------- gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c | 105 +++----------- gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h | 30 ++-- 3 files changed, 121 insertions(+), 144 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 7d80e5010c..ef4f2350da 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -160,6 +160,20 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) priv->render_flags = 0; } +static inline gboolean +gst_vaapi_video_buffer_is_a(GstBuffer *buffer, GType type) +{ + return G_TYPE_CHECK_INSTANCE_TYPE(buffer, type); +} + +static inline gpointer +_gst_vaapi_video_buffer_typed_new(GType type) +{ + g_return_val_if_fail(g_type_is_a(type, GST_VAAPI_TYPE_VIDEO_BUFFER), NULL); + + return gst_mini_object_new(type); +} + /** * gst_vaapi_video_buffer_new: * @display: a #GstVaapiDisplay @@ -170,20 +184,14 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) * * Return value: the newly allocated #GstBuffer, or %NULL or error */ -static inline gpointer -_gst_vaapi_video_buffer_new(void) -{ - return gst_mini_object_new(GST_VAAPI_TYPE_VIDEO_BUFFER); -} - GstBuffer * -gst_vaapi_video_buffer_new(GstVaapiDisplay *display) +gst_vaapi_video_buffer_typed_new(GType type, GstVaapiDisplay *display) { GstBuffer *buffer; g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - buffer = _gst_vaapi_video_buffer_new(); + buffer = _gst_vaapi_video_buffer_typed_new(type); if (!buffer) return NULL; @@ -191,6 +199,13 @@ gst_vaapi_video_buffer_new(GstVaapiDisplay *display) return buffer; } +GstBuffer * +gst_vaapi_video_buffer_new(GstVaapiDisplay *display) +{ + return gst_vaapi_video_buffer_typed_new( + GST_VAAPI_TYPE_VIDEO_BUFFER, display); +} + /** * gst_vaapi_video_buffer_new_from_pool: * @pool: a #GstVaapiVideoPool @@ -204,7 +219,7 @@ gst_vaapi_video_buffer_new(GstVaapiDisplay *display) * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstBuffer * -gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) +gst_vaapi_video_buffer_typed_new_from_pool(GType type, GstVaapiVideoPool *pool) { GstVaapiVideoBuffer *buffer; gboolean is_image_pool, is_surface_pool; @@ -217,7 +232,7 @@ gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) if (!is_image_pool && !is_surface_pool) return NULL; - buffer = _gst_vaapi_video_buffer_new(); + buffer = _gst_vaapi_video_buffer_typed_new(type); if (buffer && ((is_image_pool && gst_vaapi_video_buffer_set_image_from_pool(buffer, pool)) || @@ -231,6 +246,13 @@ gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) return NULL; } +GstBuffer * +gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) +{ + return gst_vaapi_video_buffer_typed_new_from_pool( + GST_VAAPI_TYPE_VIDEO_BUFFER, pool); +} + /** * gst_vaapi_video_buffer_new_from_buffer: * @buffer: a #GstBuffer @@ -241,18 +263,19 @@ gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstBuffer * -gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) +gst_vaapi_video_buffer_typed_new_from_buffer(GType type, GstBuffer *buffer) { GstVaapiVideoBuffer *inbuf, *outbuf; - if (!GST_VAAPI_IS_VIDEO_BUFFER(buffer)) { - if (!buffer->parent || !GST_VAAPI_IS_VIDEO_BUFFER(buffer->parent)) + if (!gst_vaapi_video_buffer_is_a(buffer, type)) { + if (!buffer->parent || + !gst_vaapi_video_buffer_is_a(buffer->parent, type)) return NULL; buffer = buffer->parent; } inbuf = GST_VAAPI_VIDEO_BUFFER(buffer); - outbuf = _gst_vaapi_video_buffer_new(); + outbuf = _gst_vaapi_video_buffer_typed_new(type); if (!outbuf) return NULL; @@ -267,6 +290,13 @@ gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) return GST_BUFFER(outbuf); } +GstBuffer * +gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) +{ + return gst_vaapi_video_buffer_typed_new_from_buffer( + GST_VAAPI_TYPE_VIDEO_BUFFER, buffer); +} + /** * gst_vaapi_video_buffer_new_with_image: * @image: a #GstVaapiImage @@ -277,18 +307,25 @@ gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstBuffer * -gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) +gst_vaapi_video_buffer_typed_new_with_image(GType type, GstVaapiImage *image) { GstVaapiVideoBuffer *buffer; g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); - buffer = _gst_vaapi_video_buffer_new(); + buffer = _gst_vaapi_video_buffer_typed_new(type); if (buffer) gst_vaapi_video_buffer_set_image(buffer, image); return GST_BUFFER(buffer); } +GstBuffer * +gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) +{ + return gst_vaapi_video_buffer_typed_new_with_image( + GST_VAAPI_TYPE_VIDEO_BUFFER, image); +} + /** * gst_vaapi_video_buffer_new_with_surface: * @surface: a #GstVaapiSurface @@ -299,18 +336,28 @@ gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstBuffer * -gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) +gst_vaapi_video_buffer_typed_new_with_surface( + GType type, + GstVaapiSurface *surface +) { GstVaapiVideoBuffer *buffer; g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - buffer = _gst_vaapi_video_buffer_new(); + buffer = _gst_vaapi_video_buffer_typed_new(type); if (buffer) gst_vaapi_video_buffer_set_surface(buffer, surface); return GST_BUFFER(buffer); } +GstBuffer * +gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) +{ + return gst_vaapi_video_buffer_typed_new_with_surface( + GST_VAAPI_TYPE_VIDEO_BUFFER, surface); +} + /** * gst_vaapi_video_buffer_new_with_surface_proxy: * @proxy: a #GstVaapiSurfaceProxy @@ -321,18 +368,28 @@ gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstBuffer * -gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) +gst_vaapi_video_buffer_typed_new_with_surface_proxy( + GType type, + GstVaapiSurfaceProxy *proxy +) { GstVaapiVideoBuffer *buffer; g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); - buffer = _gst_vaapi_video_buffer_new(); + buffer = _gst_vaapi_video_buffer_typed_new(type); if (buffer) gst_vaapi_video_buffer_set_surface_proxy(buffer, proxy); return GST_BUFFER(buffer); } +GstBuffer * +gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) +{ + return gst_vaapi_video_buffer_typed_new_with_surface_proxy( + GST_VAAPI_TYPE_VIDEO_BUFFER, proxy); +} + /** * gst_vaapi_video_buffer_get_display: * @buffer: a #GstVaapiVideoBuffer @@ -555,39 +612,6 @@ gst_vaapi_video_buffer_set_surface_proxy( } } -/** - * gst_vaapi_video_buffer_set_display: - * @buffer: a #GstVaapiVideoBuffer - * @display a #GstVaapiDisplay - * - * For subclass only, don't use. - */ -void -gst_vaapi_video_buffer_set_display( - GstVaapiVideoBuffer *buffer, - GstVaapiDisplay *display -) -{ - set_display(buffer, display); -} - -/** - * gst_vaapi_video_buffer_set_display: - * @buffer: a #GstVaapiVideoBuffer - * @other_buffer: a #GstBuffer - * - * For subclass only, don't use. - */ -void -gst_vaapi_video_buffer_set_buffer( - GstVaapiVideoBuffer *buffer, - GstBuffer *other_buffer -) -{ - g_return_if_fail (buffer->priv->buffer == NULL); - buffer->priv->buffer = gst_buffer_ref (other_buffer); -} - /** * gst_vaapi_video_buffer_get_render_flags: * @buffer: a #GstVaapiVideoBuffer diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c index da49a0d81c..4f3ef43531 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c @@ -28,36 +28,32 @@ #include "sysdeps.h" #include "gstvaapivideobuffer_glx.h" -#include "gstvaapivideobuffer_priv.h" #include "gstvaapivideoconverter_glx.h" -#include "gstvaapiobject_priv.h" -#include "gstvaapiimagepool.h" -#include "gstvaapisurfacepool.h" +#include "gstvaapivideopool.h" +#include "gstvaapivideobuffer_priv.h" +#include "gstvaapidisplay_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE (GstVaapiVideoBufferGLX, gst_vaapi_video_buffer_glx, - GST_VAAPI_TYPE_VIDEO_BUFFER); +G_DEFINE_TYPE(GstVaapiVideoBufferGLX, + gst_vaapi_video_buffer_glx, + GST_VAAPI_TYPE_VIDEO_BUFFER); static void -gst_vaapi_video_buffer_glx_class_init(GstVaapiVideoBufferGLXClass * klass) +gst_vaapi_video_buffer_glx_class_init(GstVaapiVideoBufferGLXClass *klass) { - GstSurfaceBufferClass * const surface_class = GST_SURFACE_BUFFER_CLASS (klass); - surface_class->create_converter = gst_vaapi_video_converter_glx_new; + GstSurfaceBufferClass * const surface_class = + GST_SURFACE_BUFFER_CLASS(klass); + + surface_class->create_converter = gst_vaapi_video_converter_glx_new; } static void -gst_vaapi_video_buffer_glx_init (GstVaapiVideoBufferGLX * buffer) +gst_vaapi_video_buffer_glx_init(GstVaapiVideoBufferGLX *buffer) { } -static inline gpointer -_gst_vaapi_video_buffer_glx_new (void) -{ - return gst_mini_object_new (GST_VAAPI_TYPE_VIDEO_BUFFER_GLX); -} - /** * gst_vaapi_video_buffer_glx_new: * @display: a #GstVaapiDisplayGLX @@ -69,19 +65,12 @@ _gst_vaapi_video_buffer_glx_new (void) * Return value: the newly allocated #GstBuffer, or %NULL or error */ GstBuffer * -gst_vaapi_video_buffer_glx_new(GstVaapiDisplayGLX * display) +gst_vaapi_video_buffer_glx_new(GstVaapiDisplayGLX *display) { - GstBuffer *buffer; + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); - g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); - - buffer = _gst_vaapi_video_buffer_glx_new (); - if (!buffer) - return NULL; - - gst_vaapi_video_buffer_set_display (GST_VAAPI_VIDEO_BUFFER (buffer), - GST_VAAPI_DISPLAY (display)); - return buffer; + return gst_vaapi_video_buffer_typed_new( + GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, GST_VAAPI_DISPLAY_CAST(display)); } /** @@ -97,32 +86,10 @@ gst_vaapi_video_buffer_glx_new(GstVaapiDisplayGLX * display) * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstBuffer * -gst_vaapi_video_buffer_glx_new_from_pool (GstVaapiVideoPool * pool) +gst_vaapi_video_buffer_glx_new_from_pool(GstVaapiVideoPool *pool) { - GstVaapiVideoBuffer *buffer; - gboolean is_image_pool, is_surface_pool; - - g_return_val_if_fail (GST_VAAPI_IS_VIDEO_POOL (pool), NULL); - - is_image_pool = GST_VAAPI_IS_IMAGE_POOL (pool); - is_surface_pool = GST_VAAPI_IS_SURFACE_POOL (pool); - - if (!is_image_pool && !is_surface_pool) - return NULL; - - buffer = _gst_vaapi_video_buffer_glx_new (); - if (buffer && - ((is_image_pool && - gst_vaapi_video_buffer_set_image_from_pool (buffer, pool)) || - (is_surface_pool && - gst_vaapi_video_buffer_set_surface_from_pool (buffer, pool)))) { - gst_vaapi_video_buffer_set_display (buffer, - gst_vaapi_video_pool_get_display (pool)); - return GST_BUFFER (buffer); - } - - gst_mini_object_unref (GST_MINI_OBJECT(buffer)); - return NULL; + return gst_vaapi_video_buffer_typed_new_from_pool( + GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, pool); } /** @@ -135,36 +102,8 @@ gst_vaapi_video_buffer_glx_new_from_pool (GstVaapiVideoPool * pool) * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstBuffer * -gst_vaapi_video_buffer_glx_new_from_buffer (GstBuffer * buffer) +gst_vaapi_video_buffer_glx_new_from_buffer(GstBuffer *buffer) { - GstVaapiVideoBuffer *inbuf, *outbuf; - GstVaapiImage *image; - GstVaapiSurface *surface; - GstVaapiSurfaceProxy *proxy; - - if (!GST_VAAPI_IS_VIDEO_BUFFER_GLX (buffer)) { - if (!buffer->parent || !GST_VAAPI_IS_VIDEO_BUFFER_GLX (buffer->parent)) - return NULL; - buffer = buffer->parent; - } - inbuf = GST_VAAPI_VIDEO_BUFFER (buffer); - - outbuf = _gst_vaapi_video_buffer_glx_new (); - if (!outbuf) - return NULL; - - image = gst_vaapi_video_buffer_get_image (inbuf); - surface = gst_vaapi_video_buffer_get_surface (inbuf); - proxy = - gst_vaapi_video_buffer_get_surface_proxy (inbuf); - - if (image) - gst_vaapi_video_buffer_set_image (outbuf, image); - if (surface) - gst_vaapi_video_buffer_set_surface (outbuf, surface); - if (proxy) - gst_vaapi_video_buffer_set_surface_proxy (outbuf, proxy); - - gst_vaapi_video_buffer_set_buffer (outbuf, buffer); - return GST_BUFFER (outbuf); + return gst_vaapi_video_buffer_typed_new_from_buffer( + GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, buffer); } diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h b/gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h index d72ab63fac..a08edbd8bf 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h @@ -28,16 +28,30 @@ G_BEGIN_DECLS -void -gst_vaapi_video_buffer_set_display( - GstVaapiVideoBuffer *buffer, - GstVaapiDisplay *display +/* Private API for gstreamer-vaapi plugin elements only */ + +GstBuffer * +gst_vaapi_video_buffer_typed_new(GType type, GstVaapiDisplay *display); + +GstBuffer * +gst_vaapi_video_buffer_typed_new_from_pool(GType type, GstVaapiVideoPool *pool); + +GstBuffer * +gst_vaapi_video_buffer_typed_new_from_buffer(GType type, GstBuffer *buffer); + +GstBuffer * +gst_vaapi_video_buffer_typed_new_with_image(GType type, GstVaapiImage *image); + +GstBuffer * +gst_vaapi_video_buffer_typed_new_with_surface( + GType type, + GstVaapiSurface *surface ); -void -gst_vaapi_video_buffer_set_buffer( - GstVaapiVideoBuffer *buffer, - GstBuffer *other_buffer +GstBuffer * +gst_vaapi_video_buffer_typed_new_with_surface_proxy( + GType type, + GstVaapiSurfaceProxy *proxy ); G_END_DECLS From 809a85433d73fb1fbb0f452c85b7d2ec369c81ab Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jul 2012 14:09:09 +0200 Subject: [PATCH 0750/3781] videobuffer: mark video buffer creation routines as deprecated. The vdeo buffer creation routines shall actually be internal to gstreamer-vaapi plugin elements. So deprecate any explicit creation routines that are not the new *_typed_new*() variants. --- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 11 +++++++++++ gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index 04c5ba4f5f..118ea35e7c 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -85,24 +85,35 @@ struct _GstVaapiVideoBufferClass { GType gst_vaapi_video_buffer_get_type(void) G_GNUC_CONST; +/* Deprecated API. Client applications shall not use the following functions */ +#ifndef GST_VAAPI_DISABLE_DEPRECATED + +G_GNUC_DEPRECATED GstBuffer * gst_vaapi_video_buffer_new(GstVaapiDisplay *display); +G_GNUC_DEPRECATED GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); +G_GNUC_DEPRECATED GstBuffer * gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer); +G_GNUC_DEPRECATED GstBuffer * gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image); +G_GNUC_DEPRECATED GstBuffer * gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface); +G_GNUC_DEPRECATED GstBuffer * gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); +#endif /* GST_VAAPI_DISABLE_DEPRECATED */ + GstVaapiDisplay * gst_vaapi_video_buffer_get_display(GstVaapiVideoBuffer *buffer); diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h index af0a05c000..fe5e0c31fc 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h @@ -79,10 +79,21 @@ struct _GstVaapiVideoBufferGLXClass { }; GType gst_vaapi_video_buffer_glx_get_type (void) G_GNUC_CONST; + +/* Deprecated API. Client applications shall not use the following functions */ +#ifndef GST_VAAPI_DISABLE_DEPRECATED + +G_GNUC_DEPRECATED GstBuffer *gst_vaapi_video_buffer_glx_new (GstVaapiDisplayGLX * display); + +G_GNUC_DEPRECATED GstBuffer *gst_vaapi_video_buffer_glx_new_from_pool (GstVaapiVideoPool * pool); + +G_GNUC_DEPRECATED GstBuffer *gst_vaapi_video_buffer_glx_new_from_buffer (GstBuffer * buffer); +#endif /* GST_VAAPI_DISABLE_DEPRECATED */ + G_END_DECLS #endif /* GST_VAAPI_VIDEO_BUFFER_GLX_H */ From 8ef490a3dec18c8dbc770a0d25e4f80563bc613d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jul 2012 14:31:25 +0200 Subject: [PATCH 0751/3781] videobuffer: drop deprecated functions. Move video buffer creation routines to plugin elements. That exclusively uses *_typed_new*() variants. --- docs/reference/libs/libs-sections.txt | 12 +- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 69 ++++------- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 29 ----- gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c | 54 -------- gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h | 14 --- gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapidecode.c | 7 +- gst/vaapi/gstvaapidownload.c | 11 +- gst/vaapi/gstvaapipluginbuffer.c | 124 +++++++++++++++++++ gst/vaapi/gstvaapipluginbuffer.h | 49 ++++++++ gst/vaapi/gstvaapipostproc.c | 3 +- gst/vaapi/gstvaapiupload.c | 11 +- 12 files changed, 209 insertions(+), 176 deletions(-) create mode 100644 gst/vaapi/gstvaapipluginbuffer.c create mode 100644 gst/vaapi/gstvaapipluginbuffer.h diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 8da7246f63..435f6e82a0 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -185,12 +185,12 @@ GST_VAAPI_IMAGE_POOL_GET_CLASS GstVaapiVideoBuffer GstVaapiVideoBuffer GstVaapiVideoBufferClass -gst_vaapi_video_buffer_new -gst_vaapi_video_buffer_new_from_pool -gst_vaapi_video_buffer_new_from_buffer -gst_vaapi_video_buffer_new_with_image -gst_vaapi_video_buffer_new_with_surface -gst_vaapi_video_buffer_new_with_surface_proxy +gst_vaapi_video_buffer_typed_new +gst_vaapi_video_buffer_typed_new_from_pool +gst_vaapi_video_buffer_typed_new_from_buffer +gst_vaapi_video_buffer_typed_new_with_image +gst_vaapi_video_buffer_typed_new_with_surface +gst_vaapi_video_buffer_typed_new_with_surface_proxy gst_vaapi_video_buffer_get_display gst_vaapi_video_buffer_get_image gst_vaapi_video_buffer_set_image diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index ef4f2350da..18b58ef972 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -175,13 +175,16 @@ _gst_vaapi_video_buffer_typed_new(GType type) } /** - * gst_vaapi_video_buffer_new: + * gst_vaapi_video_buffer_typed_new: * @display: a #GstVaapiDisplay * * Creates an empty #GstBuffer. The caller is responsible for completing * the initialization of the buffer with the gst_vaapi_video_buffer_set_*() * functions. * + * This function shall only be called from within gstreamer-vaapi + * plugin elements. + * * Return value: the newly allocated #GstBuffer, or %NULL or error */ GstBuffer * @@ -199,15 +202,8 @@ gst_vaapi_video_buffer_typed_new(GType type, GstVaapiDisplay *display) return buffer; } -GstBuffer * -gst_vaapi_video_buffer_new(GstVaapiDisplay *display) -{ - return gst_vaapi_video_buffer_typed_new( - GST_VAAPI_TYPE_VIDEO_BUFFER, display); -} - /** - * gst_vaapi_video_buffer_new_from_pool: + * gst_vaapi_video_buffer_typed_new_from_pool: * @pool: a #GstVaapiVideoPool * * Creates a #GstBuffer with a video object allocated from a @pool. @@ -246,20 +242,16 @@ gst_vaapi_video_buffer_typed_new_from_pool(GType type, GstVaapiVideoPool *pool) return NULL; } -GstBuffer * -gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) -{ - return gst_vaapi_video_buffer_typed_new_from_pool( - GST_VAAPI_TYPE_VIDEO_BUFFER, pool); -} - /** - * gst_vaapi_video_buffer_new_from_buffer: + * gst_vaapi_video_buffer_typed_new_from_buffer: * @buffer: a #GstBuffer * * Creates a #GstBuffer with video objects bound to @buffer video * objects, if any. * + * This function shall only be called from within gstreamer-vaapi + * plugin elements. + * * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstBuffer * @@ -290,20 +282,16 @@ gst_vaapi_video_buffer_typed_new_from_buffer(GType type, GstBuffer *buffer) return GST_BUFFER(outbuf); } -GstBuffer * -gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) -{ - return gst_vaapi_video_buffer_typed_new_from_buffer( - GST_VAAPI_TYPE_VIDEO_BUFFER, buffer); -} - /** - * gst_vaapi_video_buffer_new_with_image: + * gst_vaapi_video_buffer_typed_new_with_image: * @image: a #GstVaapiImage * * Creates a #GstBuffer with the specified @image. The resulting * buffer holds an additional reference to the @image. * + * This function shall only be called from within gstreamer-vaapi + * plugin elements. + * * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstBuffer * @@ -319,20 +307,16 @@ gst_vaapi_video_buffer_typed_new_with_image(GType type, GstVaapiImage *image) return GST_BUFFER(buffer); } -GstBuffer * -gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) -{ - return gst_vaapi_video_buffer_typed_new_with_image( - GST_VAAPI_TYPE_VIDEO_BUFFER, image); -} - /** - * gst_vaapi_video_buffer_new_with_surface: + * gst_vaapi_video_buffer_typed_new_with_surface: * @surface: a #GstVaapiSurface * * Creates a #GstBuffer with the specified @surface. The resulting * buffer holds an additional reference to the @surface. * + * This function shall only be called from within gstreamer-vaapi + * plugin elements. + * * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstBuffer * @@ -351,20 +335,16 @@ gst_vaapi_video_buffer_typed_new_with_surface( return GST_BUFFER(buffer); } -GstBuffer * -gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) -{ - return gst_vaapi_video_buffer_typed_new_with_surface( - GST_VAAPI_TYPE_VIDEO_BUFFER, surface); -} - /** - * gst_vaapi_video_buffer_new_with_surface_proxy: + * gst_vaapi_video_buffer_typed_new_with_surface_proxy: * @proxy: a #GstVaapiSurfaceProxy * * Creates a #GstBuffer with the specified surface @proxy. The * resulting buffer holds an additional reference to the @proxy. * + * This function shall only be called from within gstreamer-vaapi + * plugin elements. + * * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstBuffer * @@ -383,13 +363,6 @@ gst_vaapi_video_buffer_typed_new_with_surface_proxy( return GST_BUFFER(buffer); } -GstBuffer * -gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) -{ - return gst_vaapi_video_buffer_typed_new_with_surface_proxy( - GST_VAAPI_TYPE_VIDEO_BUFFER, proxy); -} - /** * gst_vaapi_video_buffer_get_display: * @buffer: a #GstVaapiVideoBuffer diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index 118ea35e7c..5d479b241f 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -85,35 +85,6 @@ struct _GstVaapiVideoBufferClass { GType gst_vaapi_video_buffer_get_type(void) G_GNUC_CONST; -/* Deprecated API. Client applications shall not use the following functions */ -#ifndef GST_VAAPI_DISABLE_DEPRECATED - -G_GNUC_DEPRECATED -GstBuffer * -gst_vaapi_video_buffer_new(GstVaapiDisplay *display); - -G_GNUC_DEPRECATED -GstBuffer * -gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); - -G_GNUC_DEPRECATED -GstBuffer * -gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer); - -G_GNUC_DEPRECATED -GstBuffer * -gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image); - -G_GNUC_DEPRECATED -GstBuffer * -gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface); - -G_GNUC_DEPRECATED -GstBuffer * -gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); - -#endif /* GST_VAAPI_DISABLE_DEPRECATED */ - GstVaapiDisplay * gst_vaapi_video_buffer_get_display(GstVaapiVideoBuffer *buffer); diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c index 4f3ef43531..c531f79359 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c @@ -53,57 +53,3 @@ static void gst_vaapi_video_buffer_glx_init(GstVaapiVideoBufferGLX *buffer) { } - -/** - * gst_vaapi_video_buffer_glx_new: - * @display: a #GstVaapiDisplayGLX - * - * Creates an empty #GstBuffer. The caller is responsible for completing - * the initialization of the buffer with the gst_vaapi_video_buffer_set_*() - * functions. - * - * Return value: the newly allocated #GstBuffer, or %NULL or error - */ -GstBuffer * -gst_vaapi_video_buffer_glx_new(GstVaapiDisplayGLX *display) -{ - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); - - return gst_vaapi_video_buffer_typed_new( - GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, GST_VAAPI_DISPLAY_CAST(display)); -} - -/** - * gst_vaapi_video_buffer_glx_new_from_pool: - * @pool: a #GstVaapiVideoPool - * - * Creates a #GstBuffer with a video object allocated from a @pool. - * Only #GstVaapiSurfacePool and #GstVaapiImagePool pools are supported. - * - * The buffer is destroyed through the last call to gst_buffer_unref() - * and the video objects are pushed back to their respective pools. - * - * Return value: the newly allocated #GstBuffer, or %NULL on error - */ -GstBuffer * -gst_vaapi_video_buffer_glx_new_from_pool(GstVaapiVideoPool *pool) -{ - return gst_vaapi_video_buffer_typed_new_from_pool( - GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, pool); -} - -/** - * gst_vaapi_video_buffer_glx_new_from_buffer: - * @buffer: a #GstBuffer - * - * Creates a #GstBuffer with video objects bound to @buffer video - * objects, if any. - * - * Return value: the newly allocated #GstBuffer, or %NULL on error - */ -GstBuffer * -gst_vaapi_video_buffer_glx_new_from_buffer(GstBuffer *buffer) -{ - return gst_vaapi_video_buffer_typed_new_from_buffer( - GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, buffer); -} diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h index fe5e0c31fc..0dbe065c09 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h @@ -80,20 +80,6 @@ struct _GstVaapiVideoBufferGLXClass { GType gst_vaapi_video_buffer_glx_get_type (void) G_GNUC_CONST; -/* Deprecated API. Client applications shall not use the following functions */ -#ifndef GST_VAAPI_DISABLE_DEPRECATED - -G_GNUC_DEPRECATED -GstBuffer *gst_vaapi_video_buffer_glx_new (GstVaapiDisplayGLX * display); - -G_GNUC_DEPRECATED -GstBuffer *gst_vaapi_video_buffer_glx_new_from_pool (GstVaapiVideoPool * pool); - -G_GNUC_DEPRECATED -GstBuffer *gst_vaapi_video_buffer_glx_new_from_buffer (GstBuffer * buffer); - -#endif /* GST_VAAPI_DISABLE_DEPRECATED */ - G_END_DECLS #endif /* GST_VAAPI_VIDEO_BUFFER_GLX_H */ diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 6a4175adc6..e3c3ddb62d 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -23,6 +23,7 @@ libgstvaapi_la_SOURCES = \ gstvaapi.c \ gstvaapidecode.c \ gstvaapidownload.c \ + gstvaapipluginbuffer.c \ gstvaapipluginutil.c \ gstvaapipostproc.c \ gstvaapisink.c \ @@ -32,6 +33,7 @@ libgstvaapi_la_SOURCES = \ noinst_HEADERS = \ gstvaapidecode.h \ gstvaapidownload.h \ + gstvaapipluginbuffer.h \ gstvaapipluginutil.h \ gstvaapipostproc.h \ gstvaapisink.h \ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b2f31135ce..6c303f9f1d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -35,14 +35,9 @@ #include #include -#if USE_GLX -#include -#define gst_vaapi_video_buffer_new(display) \ - gst_vaapi_video_buffer_glx_new(GST_VAAPI_DISPLAY_GLX(display)) -#endif - #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" +#include "gstvaapipluginbuffer.h" #include #include diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 4908e52fbf..f3e9caa4b6 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -35,16 +35,9 @@ #include #include -#if USE_GLX -#include -#define gst_vaapi_video_buffer_new_from_pool(pool) \ - gst_vaapi_video_buffer_glx_new_from_pool(pool) -#define gst_vaapi_video_buffer_new_from_buffer(buffer) \ - gst_vaapi_video_buffer_glx_new_from_buffer(buffer) -#endif - -#include "gstvaapipluginutil.h" #include "gstvaapidownload.h" +#include "gstvaapipluginutil.h" +#include "gstvaapipluginbuffer.h" #define GST_PLUGIN_NAME "vaapidownload" #define GST_PLUGIN_DESC "A VA to video flow filter" diff --git a/gst/vaapi/gstvaapipluginbuffer.c b/gst/vaapi/gstvaapipluginbuffer.c new file mode 100644 index 0000000000..225318e16a --- /dev/null +++ b/gst/vaapi/gstvaapipluginbuffer.c @@ -0,0 +1,124 @@ +/* + * gstvaapipluginbuffer.c - Private GStreamer/VA video buffers + * + * Copyright (C) 2012 Intel Corporation + * + * 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 + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#if USE_GLX +# include +#endif +#include "gstvaapipluginbuffer.h" + +static inline GType +get_type(GstVaapiDisplay *display) +{ +#if USE_GLX + if (GST_VAAPI_IS_DISPLAY_GLX(display)) + return GST_VAAPI_TYPE_VIDEO_BUFFER_GLX; +#endif + return GST_VAAPI_TYPE_VIDEO_BUFFER; +} + +GstBuffer * +gst_vaapi_video_buffer_new(GstVaapiDisplay *display) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + return gst_vaapi_video_buffer_typed_new(get_type(display), display); +} + +GstBuffer * +gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) +{ + GstVaapiDisplay *display; + + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); + + display = gst_vaapi_video_pool_get_display(pool); + if (!display) + return NULL; + return gst_vaapi_video_buffer_typed_new_from_pool(get_type(display), pool); +} + +GstBuffer * +gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) +{ + GstVaapiVideoBuffer *vbuffer; + GstVaapiDisplay *display; + + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL); + + vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); + display = gst_vaapi_video_buffer_get_display(vbuffer); + if (!display) + return NULL; + + return gst_vaapi_video_buffer_typed_new_from_buffer( + get_type(display), buffer); +} + +GstBuffer * +gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) +{ + GstVaapiDisplay *display; + + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); + + display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(image)); + if (!display) + return NULL; + + return gst_vaapi_video_buffer_typed_new_with_image( + get_type(display), image); +} + +GstBuffer * +gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) +{ + GstVaapiDisplay *display; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); + + display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); + if (!display) + return NULL; + + return gst_vaapi_video_buffer_typed_new_with_surface( + get_type(display), surface); +} + +GstBuffer * +gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) +{ + GstVaapiDisplay *display; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); + + display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(proxy)); + if (!display) + return NULL; + + return gst_vaapi_video_buffer_typed_new_with_surface_proxy( + get_type(display), proxy); +} diff --git a/gst/vaapi/gstvaapipluginbuffer.h b/gst/vaapi/gstvaapipluginbuffer.h new file mode 100644 index 0000000000..d6798d5d9d --- /dev/null +++ b/gst/vaapi/gstvaapipluginbuffer.h @@ -0,0 +1,49 @@ +/* + * gstvaapipluginbuffer.h - Private GStreamer/VA video buffers + * + * Copyright (C) 2012 Intel Corporation + * + * 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_PLUGIN_BUFFER_H +#define GST_VAAPI_PLUGIN_BUFFER_H + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new(GstVaapiDisplay *display); + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer); + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image); + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface); + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); + +#endif /* GST_VAAPI_PLUGIN_BUFFER_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index bfd18c0e09..59bd1b3de5 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -34,8 +34,9 @@ #include #include -#include "gstvaapipluginutil.h" #include "gstvaapipostproc.h" +#include "gstvaapipluginutil.h" +#include "gstvaapipluginbuffer.h" #define GST_PLUGIN_NAME "vaapipostproc" #define GST_PLUGIN_DESC "A video postprocessing filter" diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index fac9a7dddf..d66b21d596 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -36,16 +36,9 @@ #include #include -#if USE_GLX -#include -#define gst_vaapi_video_buffer_new_from_pool(pool) \ - gst_vaapi_video_buffer_glx_new_from_pool(pool) -#define gst_vaapi_video_buffer_new_from_buffer(buffer) \ - gst_vaapi_video_buffer_glx_new_from_buffer(buffer) -#endif - -#include "gstvaapipluginutil.h" #include "gstvaapiupload.h" +#include "gstvaapipluginutil.h" +#include "gstvaapipluginbuffer.h" #define GST_PLUGIN_NAME "vaapiupload" #define GST_PLUGIN_DESC "A video to VA flow filter" From 6b4ff307b34bca89e1c239b3f2d08a196f7a1a9a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jul 2012 16:14:51 +0200 Subject: [PATCH 0752/3781] plugins: declare helper functions as internal. --- gst/vaapi/gstvaapipluginutil.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index ac2487332a..fd535201e3 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -45,6 +45,7 @@ enum _GstVaapiDisplayType { GType gst_vaapi_display_type_get_type(void) G_GNUC_CONST; +G_GNUC_INTERNAL gboolean gst_vaapi_ensure_display( gpointer element, @@ -52,6 +53,7 @@ gst_vaapi_ensure_display( GstVaapiDisplayType *display_type_ptr ); +G_GNUC_INTERNAL void gst_vaapi_set_display( const gchar *type, @@ -59,9 +61,11 @@ gst_vaapi_set_display( GstVaapiDisplay **display ); +G_GNUC_INTERNAL gboolean gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display); +G_GNUC_INTERNAL gboolean gst_vaapi_append_surface_caps (GstCaps *out_caps, GstCaps *in_caps); From 411b970f8a35fd92f3196a7f12feeb45e7a887c1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jul 2012 19:43:40 +0200 Subject: [PATCH 0753/3781] display: use prefixed display names for cache lookups. This improves display name comparisons by always allocating a valid display name. This also helps to disambiguate lookups by name in the global display cache, should a new backend be implemented. --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 93 ++++++++++++++++++------ 1 file changed, 69 insertions(+), 24 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 0f5f7ba6b3..6ad5ed1dba 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -48,6 +48,15 @@ enum { PROP_X11_SCREEN }; +#define NAME_PREFIX "X11:" +#define NAME_PREFIX_LENGTH 4 + +static inline gboolean +is_display_name(const gchar *display_name) +{ + return strncmp(display_name, NAME_PREFIX, NAME_PREFIX_LENGTH) == 0; +} + static inline const gchar * get_default_display_name(void) { @@ -61,25 +70,35 @@ get_default_display_name(void) static gboolean compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data) { - const gchar *display_name; + const gchar *cached_name = a, *cached_name_end; + const gchar *tested_name = b, *tested_name_end; + guint cached_name_length, tested_name_length; + + if (!cached_name || !is_display_name(cached_name)) + return FALSE; + g_return_val_if_fail(tested_name && is_display_name(tested_name), FALSE); + + cached_name += NAME_PREFIX_LENGTH; + cached_name_end = strchr(cached_name, ':'); + if (cached_name_end) + cached_name_length = cached_name_end - cached_name; + else + cached_name_length = strlen(cached_name); + + tested_name += NAME_PREFIX_LENGTH; + tested_name_end = strchr(tested_name, ':'); + if (tested_name_end) + tested_name_length = tested_name_end - tested_name; + else + tested_name_length = strlen(tested_name); + + if (cached_name_length != tested_name_length) + return FALSE; + if (strncmp(cached_name, tested_name, cached_name_length) != 0) + return FALSE; /* XXX: handle screen number? */ - if (a && b) - return strcmp(a, b) == 0; - - /* Match "" or default display name */ - if (a) - display_name = a; - else if (b) - display_name = b; - else - return TRUE; - - if (*display_name == '\0') - return TRUE; - if (strcmp(display_name, get_default_display_name()) == 0) - return TRUE; - return FALSE; + return TRUE; } static void @@ -88,6 +107,29 @@ gst_vaapi_display_x11_finalize(GObject *object) G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class)->finalize(object); } +/* Reconstruct a display name without our prefix */ +static const gchar * +get_display_name(gpointer ptr) +{ + GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(ptr); + const gchar *display_name = display->priv->display_name; + + if (!display_name) + return NULL; + + if (is_display_name(display_name)) { + display_name += NAME_PREFIX_LENGTH; + if (*display_name == '\0') + return NULL; + return display_name; + } + + /* XXX: this should not happen */ + g_assert(0 && "display name without prefix"); + return display_name; +} + +/* Mangle display name with our prefix */ static void set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name) { @@ -95,10 +137,12 @@ set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name) g_free(priv->display_name); - if (display_name) - priv->display_name = g_strdup(display_name); - else - priv->display_name = NULL; + if (!display_name) { + display_name = get_default_display_name(); + if (!display_name) + display_name = ""; + } + priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, display_name); } static void @@ -157,7 +201,7 @@ gst_vaapi_display_x11_get_property( g_value_set_boolean(value, display->priv->synchronous); break; case PROP_DISPLAY_NAME: - g_value_set_string(value, display->priv->display_name); + g_value_set_string(value, get_display_name(display)); break; case PROP_X11_DISPLAY: g_value_set_pointer(value, gst_vaapi_display_x11_get_display(display)); @@ -211,7 +255,7 @@ gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) GST_VAAPI_DISPLAY_X11(display)->priv; if (priv->create_display) { - priv->x11_display = XOpenDisplay(priv->display_name); + priv->x11_display = XOpenDisplay(get_display_name(display)); if (!priv->x11_display) return FALSE; priv->x11_screen = DefaultScreen(priv->x11_display); @@ -283,7 +327,8 @@ gst_vaapi_display_x11_get_display_info( cache = gst_vaapi_display_get_cache(); if (!cache) return FALSE; - cached_info = gst_vaapi_display_cache_lookup_by_native_display(cache, priv->x11_display); + cached_info = gst_vaapi_display_cache_lookup_by_native_display( + cache, priv->x11_display); if (cached_info) { *info = *cached_info; return TRUE; From 437bc925f66b4f6bede4078203a6f8b72449e973 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 25 Jul 2012 09:16:02 +0200 Subject: [PATCH 0754/3781] display: add display types. Move display types from gstvaapipluginutil.* to gstvaapidisplay.* so that we could simplify characterization of a GstVaapiDisplay. Also rename "auto" type to "any", and add a "display-type" attribute. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 61 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 23 +++++++++ gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 1 + gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 1 + gst-libs/gst/vaapi/gstvaapidisplaycache.c | 1 + gst/vaapi/gstvaapipluginutil.c | 28 ++--------- gst/vaapi/gstvaapipluginutil.h | 19 ------- gst/vaapi/gstvaapisink.c | 4 +- 9 files changed, 93 insertions(+), 46 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index e113f71e75..f4352bd103 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -49,6 +49,7 @@ enum { PROP_0, PROP_DISPLAY, + PROP_DISPLAY_TYPE, PROP_WIDTH, PROP_HEIGHT }; @@ -80,6 +81,29 @@ free_display_cache(void) g_display_cache = NULL; } +/* GstVaapiDisplayType enumerations */ +GType +gst_vaapi_display_type_get_type(void) +{ + static GType g_type = 0; + + static const GEnumValue display_types[] = { + { GST_VAAPI_DISPLAY_TYPE_ANY, + "Auto detection", "any" }, + { GST_VAAPI_DISPLAY_TYPE_X11, + "VA/X11 display", "x11" }, +#if USE_GLX + { GST_VAAPI_DISPLAY_TYPE_GLX, + "VA/GLX display", "glx" }, +#endif + { 0, NULL, NULL }, + }; + + if (!g_type) + g_type = g_enum_register_static("GstVaapiDisplayType", display_types); + return g_type; +} + /* Append GstVaapiImageFormat to formats array */ static inline void append_format(GArray *formats, GstVaapiImageFormat format) @@ -378,6 +402,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) memset(&info, 0, sizeof(info)); info.display = display; + info.display_type = priv->display_type; if (priv->display) info.va_display = priv->display; @@ -388,6 +413,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) if (!klass->get_display || !klass->get_display(display, &info)) return FALSE; priv->display = info.va_display; + priv->display_type = info.display_type; if (klass->get_size) klass->get_size(display, &priv->width, &priv->height); if (klass->get_size_mm) @@ -407,6 +433,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) if (cached_info) { g_clear_object(&priv->parent); priv->parent = g_object_ref(cached_info->display); + priv->display_type = cached_info->display_type; } if (!priv->parent) { @@ -567,6 +594,9 @@ gst_vaapi_display_set_property( case PROP_DISPLAY: display->priv->display = g_value_get_pointer(value); break; + case PROP_DISPLAY_TYPE: + display->priv->display_type = g_value_get_enum(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -587,6 +617,9 @@ gst_vaapi_display_get_property( case PROP_DISPLAY: g_value_set_pointer(value, gst_vaapi_display_get_display(display)); break; + case PROP_DISPLAY_TYPE: + g_value_set_enum(value, gst_vaapi_display_get_display_type(display)); + break; case PROP_WIDTH: g_value_set_uint(value, gst_vaapi_display_get_width(display)); break; @@ -640,6 +673,16 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) "VA display", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property + (object_class, + PROP_DISPLAY_TYPE, + g_param_spec_enum("display-type", + "VA display type", + "VA display type", + GST_VAAPI_TYPE_DISPLAY_TYPE, + GST_VAAPI_DISPLAY_TYPE_ANY, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_WIDTH, @@ -666,6 +709,7 @@ gst_vaapi_display_init(GstVaapiDisplay *display) display->priv = priv; priv->parent = NULL; + priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; priv->display = NULL; priv->width = 0; priv->height = 0; @@ -795,6 +839,23 @@ gst_vaapi_display_flush(GstVaapiDisplay *display) klass->flush(display); } +/** + * gst_vaapi_display_get_display: + * @display: a #GstVaapiDisplay + * + * Returns the #GstVaapiDisplayType bound to @display. + * + * Return value: the #GstVaapiDisplayType + */ +GstVaapiDisplayType +gst_vaapi_display_get_display_type(GstVaapiDisplay *display) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), + GST_VAAPI_DISPLAY_TYPE_ANY); + + return display->priv->display_type; +} + /** * gst_vaapi_display_get_display: * @display: a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index e68e9c3f54..81410ec677 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -54,11 +54,30 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DISPLAY, \ GstVaapiDisplayClass)) +typedef enum _GstVaapiDisplayType GstVaapiDisplayType; typedef struct _GstVaapiDisplayInfo GstVaapiDisplayInfo; typedef struct _GstVaapiDisplay GstVaapiDisplay; typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; +/** + * 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. + */ +enum _GstVaapiDisplayType { + GST_VAAPI_DISPLAY_TYPE_ANY = 0, + GST_VAAPI_DISPLAY_TYPE_X11, + GST_VAAPI_DISPLAY_TYPE_GLX, +}; + +#define GST_VAAPI_TYPE_DISPLAY_TYPE \ + (gst_vaapi_display_type_get_type()) + +GType +gst_vaapi_display_type_get_type(void) G_GNUC_CONST; + /** * GstVaapiDisplayInfo: * @@ -66,6 +85,7 @@ typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; */ struct _GstVaapiDisplayInfo { GstVaapiDisplay *display; + GstVaapiDisplayType display_type; gchar *display_name; VADisplay va_display; gpointer native_display; @@ -134,6 +154,9 @@ gst_vaapi_display_sync(GstVaapiDisplay *display); void gst_vaapi_display_flush(GstVaapiDisplay *display); +GstVaapiDisplayType +gst_vaapi_display_get_display_type(GstVaapiDisplay *display); + VADisplay gst_vaapi_display_get_display(GstVaapiDisplay *display); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index ccf126afa8..87ac84a83d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -59,6 +59,7 @@ gst_vaapi_display_glx_get_display_info( info->va_display = vaGetDisplayGLX(GST_VAAPI_DISPLAY_XDISPLAY(display)); if (!info->va_display) return FALSE; + info->display_type = GST_VAAPI_DISPLAY_TYPE_GLX; return dpy_class->get_display(display, info); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 80ec99a287..d48cc60fd8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -74,6 +74,7 @@ G_BEGIN_DECLS struct _GstVaapiDisplayPrivate { GstVaapiDisplay *parent; GStaticRecMutex mutex; + GstVaapiDisplayType display_type; VADisplay display; guint width; guint height; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 6ad5ed1dba..1c89d1577b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -341,6 +341,7 @@ gst_vaapi_display_x11_get_display_info( info->va_display = vaGetDisplay(priv->x11_display); if (!info->va_display) return FALSE; + info->display_type = GST_VAAPI_DISPLAY_TYPE_X11; } return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index 93178f4633..0e6ef36c62 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -68,6 +68,7 @@ cache_entry_new(const GstVaapiDisplayInfo *di) info->display = di->display; info->va_display = di->va_display; info->native_display = di->native_display; + info->display_type = di->display_type; info->display_name = NULL; if (di->display_name) { diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index a0921343e4..ad8ce88ce1 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -71,7 +71,7 @@ gst_vaapi_ensure_display( ) { GstVaapiDisplayType display_type = - display_type_ptr ? *display_type_ptr : GST_VAAPI_DISPLAY_TYPE_AUTO; + display_type_ptr ? *display_type_ptr : GST_VAAPI_DISPLAY_TYPE_ANY; GstVaapiDisplay *display; GstVideoContext *context; const DisplayMap *m; @@ -89,7 +89,7 @@ gst_vaapi_ensure_display( /* If no neighboor, or application not interested, use system default */ for (m = g_display_map; m->type_str != NULL; m++) { - if (display_type != GST_VAAPI_DISPLAY_TYPE_AUTO && + if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY && display_type != m->type) continue; @@ -104,7 +104,7 @@ gst_vaapi_ensure_display( display = NULL; } - if (display_type != GST_VAAPI_DISPLAY_TYPE_AUTO) + if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY) break; } @@ -232,25 +232,3 @@ gst_vaapi_append_surface_caps(GstCaps *out_caps, GstCaps *in_caps) } return TRUE; } - -GType -gst_vaapi_display_type_get_type(void) -{ - static GType g_type = 0; - - static const GEnumValue display_types[] = { - { GST_VAAPI_DISPLAY_TYPE_AUTO, - "Auto detection", "auto" }, - { GST_VAAPI_DISPLAY_TYPE_X11, - "VA/X11 display", "x11" }, -#if USE_GLX - { GST_VAAPI_DISPLAY_TYPE_GLX, - "VA/GLX display", "glx" }, -#endif - { 0, NULL, NULL }, - }; - - if (!g_type) - g_type = g_enum_register_static("GstVaapiDisplayType", display_types); - return g_type; -} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index fd535201e3..64aa8e9ee8 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -26,25 +26,6 @@ #include -/** - * GstVaapiDisplayType: - * @GST_VAAPI_DISPLAY_TYPE_AUTO: Automatic detection of the display type. - * @GST_VAAPI_DISPLAY_TYPE_X11: VA/X11 display. - * @GST_VAAPI_DISPLAY_TYPE_GLX: VA/GLX display. - */ -typedef enum _GstVaapiDisplayType GstVaapiDisplayType; -enum _GstVaapiDisplayType { - GST_VAAPI_DISPLAY_TYPE_AUTO = 0, - GST_VAAPI_DISPLAY_TYPE_X11, - GST_VAAPI_DISPLAY_TYPE_GLX, -}; - -#define GST_VAAPI_TYPE_DISPLAY_TYPE \ - gst_vaapi_display_type_get_type() - -GType -gst_vaapi_display_type_get_type(void) G_GNUC_CONST; - G_GNUC_INTERNAL gboolean gst_vaapi_ensure_display( diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 7a992193af..ff43a0658e 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -99,7 +99,7 @@ enum { PROP_USE_REFLECTION }; -#define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_AUTO +#define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY /* GstImplementsInterface interface */ @@ -818,7 +818,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) "display type", "display type to use", GST_VAAPI_TYPE_DISPLAY_TYPE, - GST_VAAPI_DISPLAY_TYPE_AUTO, + GST_VAAPI_DISPLAY_TYPE_ANY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); #if USE_GLX From 4e53b5fe4e4789caaac644a380522ba742376168 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 25 Jul 2012 11:37:26 +0200 Subject: [PATCH 0755/3781] display: fix destruction of mutex. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index f4352bd103..7972003a30 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -382,7 +382,6 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) gst_vaapi_display_cache_remove(get_display_cache(), display); free_display_cache(); } - g_static_rec_mutex_free(&priv->mutex); } static gboolean @@ -577,6 +576,8 @@ gst_vaapi_display_finalize(GObject *object) gst_vaapi_display_destroy(display); + g_static_rec_mutex_free(&display->priv->mutex); + G_OBJECT_CLASS(gst_vaapi_display_parent_class)->finalize(object); } From cff117b54dbfbd58a8bf483dd710a85989b057e2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 25 Jul 2012 10:02:29 +0200 Subject: [PATCH 0756/3781] plugins: fix display type selection and propagation. If vaapisink is in the GStreamer pipeline, then we shall allocate a unique GstVaapiDisplay and propagate it upstream. i.e. subsequent queries from vaapidecode shall get a valid answer from vaapisink. --- gst/vaapi/gstvaapidecode.c | 11 +++++++++-- gst/vaapi/gstvaapidownload.c | 11 +++++++++-- gst/vaapi/gstvaapipluginutil.c | 14 ++++++++------ gst/vaapi/gstvaapipluginutil.h | 4 ++-- gst/vaapi/gstvaapipostproc.c | 11 +++++++++-- gst/vaapi/gstvaapisink.c | 24 +++++++++++++++++++++++- gst/vaapi/gstvaapiupload.c | 10 ++++++++-- 7 files changed, 68 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6c303f9f1d..253874ca27 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -286,6 +286,13 @@ error_commit_buffer: } } +static inline gboolean +gst_vaapidecode_ensure_display(GstVaapiDecode *decode) +{ + return gst_vaapi_ensure_display(decode, GST_VAAPI_DISPLAY_TYPE_ANY, + &decode->display); +} + static gboolean gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) { @@ -293,7 +300,7 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) GstStructure *structure; int version; - if (!gst_vaapi_ensure_display(decode, &decode->display, NULL)) + if (!gst_vaapidecode_ensure_display(decode)) return FALSE; dpy = decode->display; @@ -526,7 +533,7 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) if (decode->allowed_caps) return TRUE; - if (!gst_vaapi_ensure_display(decode, &decode->display, NULL)) + if (!gst_vaapidecode_ensure_display(decode)) goto error_no_display; decode_caps = gst_vaapi_display_get_decode_caps(decode->display); diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index f3e9caa4b6..69ce5d193f 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -290,12 +290,19 @@ gst_vaapidownload_init(GstVaapiDownload *download) gst_object_unref(srcpad); } +static inline gboolean +gst_vaapidownload_ensure_display(GstVaapiDownload *download) +{ + return gst_vaapi_ensure_display(download, GST_VAAPI_DISPLAY_TYPE_ANY, + &download->display); +} + static gboolean gst_vaapidownload_start(GstBaseTransform *trans) { GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - if (!gst_vaapi_ensure_display(download, &download->display, NULL)) + if (!gst_vaapidownload_ensure_display(download)) return FALSE; return TRUE; } @@ -448,7 +455,7 @@ gst_vaapidownload_transform_caps( if (direction == GST_PAD_SINK) { if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) return NULL; - if (!gst_vaapi_ensure_display(download, &download->display, NULL)) + if (!gst_vaapidownload_ensure_display(download)) return NULL; out_caps = gst_caps_from_string(gst_vaapidownload_yuv_caps_str); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ad8ce88ce1..6c731a698a 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -66,12 +66,10 @@ static const DisplayMap g_display_map[] = { gboolean gst_vaapi_ensure_display( gpointer element, - GstVaapiDisplay **display_ptr, - GstVaapiDisplayType *display_type_ptr + GstVaapiDisplayType display_type, + GstVaapiDisplay **display_ptr ) { - GstVaapiDisplayType display_type = - display_type_ptr ? *display_type_ptr : GST_VAAPI_DISPLAY_TYPE_ANY; GstVaapiDisplay *display; GstVideoContext *context; const DisplayMap *m; @@ -85,8 +83,14 @@ gst_vaapi_ensure_display( return TRUE; context = GST_VIDEO_CONTEXT(element); + g_return_val_if_fail(context != NULL, FALSE); + gst_video_context_prepare(context, display_types); + /* Neighbour found and it updated the display */ + if (*display_ptr) + return TRUE; + /* If no neighboor, or application not interested, use system default */ for (m = g_display_map; m->type_str != NULL; m++) { if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY && @@ -110,8 +114,6 @@ gst_vaapi_ensure_display( if (display_ptr) *display_ptr = display; - if (display_type_ptr) - *display_type_ptr = display_type; return display != NULL; } diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 64aa8e9ee8..b55374bec7 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -30,8 +30,8 @@ G_GNUC_INTERNAL gboolean gst_vaapi_ensure_display( gpointer element, - GstVaapiDisplay **display, - GstVaapiDisplayType *display_type_ptr + GstVaapiDisplayType display_type, + GstVaapiDisplay **display ); G_GNUC_INTERNAL diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 59bd1b3de5..8565a5e4d1 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -199,10 +199,17 @@ gst_video_context_interface_init(GstVideoContextInterface *iface) iface->set_context = gst_vaapipostproc_set_video_context; } +static inline gboolean +gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc) +{ + return gst_vaapi_ensure_display(postproc, GST_VAAPI_DISPLAY_TYPE_ANY, + &postproc->display); +} + static gboolean gst_vaapipostproc_create(GstVaapiPostproc *postproc, GstCaps *caps) { - if (!gst_vaapi_ensure_display(postproc, &postproc->display, NULL)) + if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; gst_caps_replace(&postproc->postproc_caps, caps); @@ -231,7 +238,7 @@ gst_vaapipostproc_reset(GstVaapiPostproc *postproc, GstCaps *caps) static gboolean gst_vaapipostproc_start(GstVaapiPostproc *postproc) { - if (!gst_vaapi_ensure_display(postproc, &postproc->display, NULL)) + if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; return TRUE; } diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index ff43a0658e..f43b27fd1c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -260,10 +260,32 @@ configure_notify_event_pending( return args.match; } +static const gchar * +get_display_type_name(GstVaapiDisplayType display_type) +{ + gpointer const klass = g_type_class_peek(GST_VAAPI_TYPE_DISPLAY_TYPE); + GEnumValue * const e = g_enum_get_value(klass, display_type); + + if (e) + return e->value_name; + return ""; +} + static inline gboolean gst_vaapisink_ensure_display(GstVaapiSink *sink) { - return gst_vaapi_ensure_display(sink, &sink->display, &sink->display_type); + GstVaapiDisplayType display_type; + + if (!gst_vaapi_ensure_display(sink, sink->display_type, &sink->display)) + return FALSE; + + display_type = gst_vaapi_display_get_display_type(sink->display); + if (display_type != sink->display_type) { + GST_INFO("created %s %p", get_display_type_name(display_type), + sink->display); + sink->display_type = display_type; + } + return TRUE; } static gboolean diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index d66b21d596..b4bc9fde9b 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -360,14 +360,20 @@ gst_vaapiupload_init(GstVaapiUpload *upload) g_object_unref(srcpad); } +static inline gboolean +gst_vaapiupload_ensure_display(GstVaapiUpload *upload) +{ + return gst_vaapi_ensure_display(upload, GST_VAAPI_DISPLAY_TYPE_ANY, + &upload->display); +} + static gboolean gst_vaapiupload_start(GstBaseTransform *trans) { GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - if (!gst_vaapi_ensure_display(upload, &upload->display, NULL)) + if (!gst_vaapiupload_ensure_display(upload)) return FALSE; - return TRUE; } From efe623c25335bdbed3cc21601cc7a47aae0de82b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 25 Jul 2012 14:51:28 +0200 Subject: [PATCH 0757/3781] plugins: use new display types more. In particular, simplify gst_vaapi_reply_to_query() with display types. Likewise for creating new video buffers. --- gst/vaapi/gstvaapipluginbuffer.c | 16 +++++++++--- gst/vaapi/gstvaapipluginutil.c | 44 +++++++++++++++++++------------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbuffer.c b/gst/vaapi/gstvaapipluginbuffer.c index 225318e16a..7005a2b83a 100644 --- a/gst/vaapi/gstvaapipluginbuffer.c +++ b/gst/vaapi/gstvaapipluginbuffer.c @@ -30,14 +30,22 @@ #endif #include "gstvaapipluginbuffer.h" -static inline GType +static GType get_type(GstVaapiDisplay *display) { + GType type; + + switch (gst_vaapi_display_get_display_type(display)) { #if USE_GLX - if (GST_VAAPI_IS_DISPLAY_GLX(display)) - return GST_VAAPI_TYPE_VIDEO_BUFFER_GLX; + case GST_VAAPI_DISPLAY_TYPE_GLX: + type = GST_VAAPI_TYPE_VIDEO_BUFFER_GLX; + break; #endif - return GST_VAAPI_TYPE_VIDEO_BUFFER; + default: + type = GST_VAAPI_TYPE_VIDEO_BUFFER; + break; + } + return type; } GstBuffer * diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 6c731a698a..3ae3d23597 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -161,6 +161,7 @@ gst_vaapi_set_display( gboolean gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) { + GstVaapiDisplayType display_type; const gchar **types; const gchar *type; gint i; @@ -174,9 +175,11 @@ gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) if (!types) return FALSE; - for (i = 0; types[i]; i++) { + display_type = gst_vaapi_display_get_display_type(display); + for (i = 0; types[i] && !res; i++) { type = types[i]; + res = TRUE; if (!strcmp(type, "gst-vaapi-display")) { gst_video_context_query_set_object(query, type, G_OBJECT(display)); } @@ -184,25 +187,30 @@ gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) VADisplay vadpy = gst_vaapi_display_get_display(display); gst_video_context_query_set_pointer(query, type, vadpy); } - else if (!strcmp(type, "x11-display") && - GST_VAAPI_IS_DISPLAY_X11(display)) { - GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11(display); - Display *x11dpy = gst_vaapi_display_x11_get_display(xvadpy); - gst_video_context_query_set_pointer(query, type, x11dpy); - - } - else if (!strcmp(type, "x11-display-name") && - GST_VAAPI_IS_DISPLAY_X11(display)) { - GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11(display); - Display *x11dpy = gst_vaapi_display_x11_get_display(xvadpy); - gst_video_context_query_set_string(query, type, DisplayString(x11dpy)); - } else { - continue; + switch (display_type) { +#if USE_GLX + case GST_VAAPI_DISPLAY_TYPE_GLX: +#endif + case GST_VAAPI_DISPLAY_TYPE_X11: { + GstVaapiDisplayX11 * const xvadpy = + GST_VAAPI_DISPLAY_X11(display); + Display * const x11dpy = + gst_vaapi_display_x11_get_display(xvadpy); + if (!strcmp(type, "x11-display")) + gst_video_context_query_set_pointer(query, type, x11dpy); + else if (!strcmp(type, "x11-display-name")) + gst_video_context_query_set_string(query, type, + DisplayString(x11dpy)); + else + res = FALSE; + break; + } + default: + res = FALSE; + break; + } } - - res = TRUE; - break; } return res; } From 5a1293a27e714d0a417d4e32291f80a9d36b29ae Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 25 Jul 2012 15:11:51 +0200 Subject: [PATCH 0758/3781] plugins: fix creation of video buffer from surface proxy. Fix a regression introduced with commit 8ef490a. --- gst/vaapi/gstvaapipluginbuffer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbuffer.c b/gst/vaapi/gstvaapipluginbuffer.c index 7005a2b83a..33cb9176c3 100644 --- a/gst/vaapi/gstvaapipluginbuffer.c +++ b/gst/vaapi/gstvaapipluginbuffer.c @@ -120,10 +120,15 @@ GstBuffer * gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) { GstVaapiDisplay *display; + GstVaapiSurface *surface; g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); - display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(proxy)); + surface = gst_vaapi_surface_proxy_get_surface(proxy); + if (!surface) + return NULL; + + display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); if (!display) return NULL; From 621bb12be6ba82db701f505c38a0ebc25a3941c8 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 19 Jul 2012 10:27:23 +0200 Subject: [PATCH 0759/3781] Add initial support for VA/Wayland. Signed-off-by: Gwenole Beauchesne --- NEWS | 1 + configure.ac | 34 +- gst-libs/gst/vaapi/Makefile.am | 53 +++ gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 414 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay_wayland.h | 94 ++++ .../gst/vaapi/gstvaapidisplay_wayland_priv.h | 60 +++ gst-libs/gst/vaapi/gstvaapiobject_priv.h | 22 + gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 302 +++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow_wayland.h | 89 ++++ 9 files changed, 1068 insertions(+), 1 deletion(-) create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_wayland.c create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_wayland.h create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_wayland.c create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_wayland.h diff --git a/NEWS b/NEWS index 118610ae40..39e6572862 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora Version 0.4.0 - DD.Aug.2012 +* Add support for Wayland * Drop FFmpeg-based decoders Version 0.3.7 - 26.Jun.2012 diff --git a/configure.ac b/configure.ac index 7ef92f3423..86c4f7b515 100644 --- a/configure.ac +++ b/configure.ac @@ -45,10 +45,12 @@ m4_define([gst_plugins_bad_version], m4_define([va_api_version], [0.30.4]) m4_define([va_api_x11_version], [0.31.0]) m4_define([va_api_glx_version], [0.32.0]) +m4_define([va_api_wld_version], [0.34.0]) # libva package version number m4_define([libva_x11_package_version], [1.0.3]) m4_define([libva_glx_package_version], [1.0.9]) +m4_define([libva_wld_package_version], [1.2.0]) # gtk-doc version number # XXX: introspection annotations require gtk-doc >= 1.12 @@ -110,6 +112,11 @@ AC_ARG_ENABLE(glx, [enable OpenGL/X11 output @<:@default=yes@:>@]), [], [enable_glx="yes"]) +AC_ARG_ENABLE(wayland, + AC_HELP_STRING([--enable-wayland], + [enable Wayland output @<:@default=yes@:>@]), + [], [enable_wayland="yes"]) + dnl Check for basic libraries AC_CHECK_LIB(m, tan) @@ -319,6 +326,20 @@ if test "$enable_glx" = "yes" -a $HAVE_GL -eq 1 -a $USE_X11 -eq 1; then LIBS="$saved_LIBS" fi +dnl Check for Wayland +USE_WAYLAND=0 +if test "$enable_wayland" = "yes"; then + PKG_CHECK_MODULES(WAYLAND, [wayland-client], + [USE_WAYLAND=1], [USE_WAYLAND=0]) + + if test $USE_WAYLAND -eq 1; then + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $WAYLAND_CFLAGS" + AC_CHECK_HEADERS([wayland-client.h], [:], [USE_WAYLAND=0]) + CPPFLAGS="$saved_CPPFLAGS" + fi +fi + dnl --------------------------------------------------------------------------- dnl -- VA-API -- dnl --------------------------------------------------------------------------- @@ -382,11 +403,17 @@ AC_CACHE_CHECK([for JPEG decoding API], LIBS="$saved_LIBS" ]) +dnl VA/Wayland API +if test "$enable_wayland" = "yes"; then + PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= va_api_wld_version], + [:], [USE_WAYLAND=0]) +fi + dnl --------------------------------------------------------------------------- dnl -- Generate files and summary -- dnl --------------------------------------------------------------------------- -case ":$USE_X11:$USE_GLX:" in +case ":$USE_X11:$USE_GLX:$USE_WAYLAND:" in *:1:*) ;; *) @@ -406,6 +433,10 @@ AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) +AC_DEFINE_UNQUOTED(USE_WAYLAND, $USE_WAYLAND, + [Defined to 1 if WAYLAND is enabled]) +AM_CONDITIONAL(USE_WAYLAND, test $USE_WAYLAND -eq 1) + pkgconfigdir=${libdir}/pkgconfig AC_SUBST(pkgconfigdir) @@ -456,6 +487,7 @@ yesno() { VIDEO_OUTPUTS="" AS_IF([test $USE_X11 -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS x11"]) AS_IF([test $USE_GLX -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS glx"]) +AS_IF([test $USE_WAYLAND -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS wayland"]) echo echo $PACKAGE configuration summary: diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 1ddf17fdf8..fc84e49645 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -3,6 +3,10 @@ lib_LTLIBRARIES = \ libgstvaapi-x11-@GST_MAJORMINOR@.la \ $(NULL) +if USE_WAYLAND +lib_LTLIBRARIES += libgstvaapi-wayland-@GST_MAJORMINOR@.la +endif + if USE_GLX lib_LTLIBRARIES += libgstvaapi-glx-@GST_MAJORMINOR@.la endif @@ -124,6 +128,23 @@ libgstvaapi_x11_source_priv_h = \ gstvaapiutils_x11.h \ $(NULL) +libgstvaapi_wayland_source_c = \ + gstvaapidisplay_wayland.c \ + gstvaapiutils.c \ + gstvaapiwindow_wayland.c \ + $(NULL) + +libgstvaapi_wayland_source_h = \ + gstvaapidisplay_wayland.h \ + gstvaapiwindow_wayland.h \ + $(NULL) + +libgstvaapi_wayland_source_priv_h = \ + gstvaapicompat.h \ + gstvaapidisplay_wayland_priv.h \ + gstvaapiutils.h \ + $(NULL) + libgstvaapi_glx_source_c = \ gstvaapidisplay_glx.c \ gstvaapitexture.c \ @@ -217,6 +238,38 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) +libgstvaapi_wayland_@GST_MAJORMINOR@_la_SOURCES = \ + $(libgstvaapi_wayland_source_c) \ + $(libgstvaapi_wayland_source_priv_h) \ + $(NULL) + +libgstvaapi_wayland_@GST_MAJORMINOR@include_HEADERS = \ + $(libgstvaapi_wayland_source_h) \ + $(NULL) + +libgstvaapi_wayland_@GST_MAJORMINOR@includedir = \ + $(libgstvaapi_includedir) + +libgstvaapi_wayland_@GST_MAJORMINOR@_la_CFLAGS = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + $(GLIB_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(WAYLAND_CFLAGS) \ + $(LIBVA_WAYLAND_CFLAGS) \ + $(NULL) + +libgstvaapi_wayland_@GST_MAJORMINOR@_la_LIBADD = \ + $(GLIB_LIBS) \ + $(WAYLAND_LIBS) \ + $(LIBVA_WAYLAND_LIBS) \ + libgstvaapi-@GST_MAJORMINOR@.la \ + $(NULL) + +libgstvaapi_wayland_@GST_MAJORMINOR@_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(NULL) + libgstvaapi_glx_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_glx_source_c) \ $(libgstvaapi_glx_source_priv_h) \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c new file mode 100644 index 0000000000..0407c96cb5 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -0,0 +1,414 @@ +/* + * gstvaapidisplay_wayland.c - VA/Wayland display abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * 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 +#include "gstvaapidisplay_priv.h" +#include "gstvaapidisplay_wayland.h" +#include "gstvaapidisplay_wayland_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiDisplayWayland, + gst_vaapi_display_wayland, + GST_VAAPI_TYPE_DISPLAY); + +enum { + PROP_0, + + PROP_DISPLAY_NAME, + PROP_WL_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; +} + +static gboolean +compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const gchar *display_name; + + /* XXX: handle screen number? */ + if (a && b) + return strcmp(a, b) == 0; + + /* Match "" or default display name */ + if (a) + display_name = a; + else if (b) + display_name = b; + else + return TRUE; + + if (*display_name == '\0') + return TRUE; + if (strcmp(display_name, get_default_display_name()) == 0) + return TRUE; + return FALSE; +} + +static void +gst_vaapi_display_wayland_finalize(GObject *object) +{ + G_OBJECT_CLASS(gst_vaapi_display_wayland_parent_class)->finalize(object); +} + +static void +set_display_name(GstVaapiDisplayWayland *display, const gchar *display_name) +{ + GstVaapiDisplayWaylandPrivate * const priv = display->priv; + + g_free(priv->display_name); + + if (display_name) + priv->display_name = g_strdup(display_name); + else + priv->display_name = NULL; +} + +static void +gst_vaapi_display_wayland_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(object); + + switch (prop_id) { + case PROP_DISPLAY_NAME: + set_display_name(display, g_value_get_string(value)); + break; + case PROP_WL_DISPLAY: + display->priv->wl_display = g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} +static void +gst_vaapi_display_wayland_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(object); + + switch (prop_id) { + case PROP_DISPLAY_NAME: + g_value_set_string(value, display->priv->display_name); + break; + case PROP_WL_DISPLAY: + g_value_set_pointer(value, gst_vaapi_display_wayland_get_display(display)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_display_wayland_constructed(GObject *object) +{ + GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(object); + GstVaapiDisplayWaylandPrivate * const priv = display->priv; + GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache(); + const GstVaapiDisplayInfo *info; + GObjectClass *parent_class; + const gchar *display_name; + + priv->create_display = priv->wl_display == NULL; + + /* Don't create Wayland display if there is one in the cache already */ + if (priv->create_display) { + info = gst_vaapi_display_cache_lookup_by_name( + cache, + priv->display_name, + compare_display_name, NULL + ); + if (info) { + priv->wl_display = info->native_display; + priv->create_display = FALSE; + } + } + + /* Reset display-name if the user provided his own Wayland display */ + if (!priv->create_display) { + /* XXX: get socket name */ + GST_WARNING("wayland: get display name"); + display_name = NULL; + set_display_name(display, display_name); + } + + parent_class = G_OBJECT_CLASS(gst_vaapi_display_wayland_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + +static void +display_handle_global( + struct wl_display *display, + uint32_t id, + const char *interface, + uint32_t version, + void *data +) +{ + GstVaapiDisplayWaylandPrivate * const priv = data; + + if (strcmp(interface, "wl_compositor") == 0) + priv->compositor = wl_display_bind(display, id, &wl_compositor_interface); + else if (strcmp(interface, "wl_shell") == 0) + priv->shell = wl_display_bind(display, id, &wl_shell_interface); +} + +static int +event_mask_update(uint32_t mask, void *data) +{ + GstVaapiDisplayWaylandPrivate * const priv = data; + + priv->event_mask = mask; + return 0; +} + +static gboolean +gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display) +{ + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND(display)->priv; + + if (!priv->create_display) + return priv->wl_display != NULL; + + priv->wl_display = wl_display_connect(priv->display_name); + if (!priv->wl_display) + return FALSE; + + wl_display_set_user_data(priv->wl_display, priv); + wl_display_add_global_listener(priv->wl_display, display_handle_global, priv); + priv->event_fd = wl_display_get_fd(priv->wl_display, event_mask_update, priv); + wl_display_iterate(priv->wl_display, priv->event_mask); + wl_display_roundtrip(priv->wl_display); + + if (!priv->compositor) { + GST_ERROR("failed to bind compositor interface"); + return FALSE; + } + + if (!priv->shell) { + GST_ERROR("failed to bind shell interface"); + return FALSE; + } + return TRUE; +} + +static void +gst_vaapi_display_wayland_close_display(GstVaapiDisplay * display) +{ + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND(display)->priv; + + if (priv->compositor) { + wl_compositor_destroy(priv->compositor); + priv->compositor = NULL; + } + + if (priv->wl_display) { + wl_display_disconnect(priv->wl_display); + priv->wl_display = NULL; + } + + if (priv->display_name) { + g_free(priv->display_name); + priv->display_name = NULL; + } +} + +static gboolean +gst_vaapi_display_wayland_get_display_info( + GstVaapiDisplay *display, + GstVaapiDisplayInfo *info +) +{ + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND(display)->priv; + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *cached_info; + + /* Return any cached info even if child has its own VA display */ + cache = gst_vaapi_display_get_cache(); + if (!cache) + return FALSE; + cached_info = + gst_vaapi_display_cache_lookup_by_native_display(cache, priv->wl_display); + if (cached_info) { + *info = *cached_info; + return TRUE; + } + + /* Otherwise, create VA display if there is none already */ + 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; + info->display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; + } + return TRUE; +} + +static void +gst_vaapi_display_wayland_class_init(GstVaapiDisplayWaylandClass * klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiDisplayWaylandPrivate)); + + object_class->finalize = gst_vaapi_display_wayland_finalize; + object_class->set_property = gst_vaapi_display_wayland_set_property; + object_class->get_property = gst_vaapi_display_wayland_get_property; + object_class->constructed = gst_vaapi_display_wayland_constructed; + + 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; + + /** + * GstVaapiDisplayWayland:wayland-display: + * + * The Wayland #wl_display that was created by + * gst_vaapi_display_wayland_new() or that was bound from + * gst_vaapi_display_wayland_new_with_display(). + */ + g_object_class_install_property + (object_class, + PROP_WL_DISPLAY, + g_param_spec_pointer("wl-display", + "Wayland display", + "Wayland display", + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + /** + * GstVaapiDisplayWayland:display-name: + * + * The Wayland display name. + */ + g_object_class_install_property + (object_class, + PROP_DISPLAY_NAME, + g_param_spec_string("display-name", + "Wayland display name", + "Wayland display name", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_display_wayland_init(GstVaapiDisplayWayland *display) +{ + GstVaapiDisplayWaylandPrivate *priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + + display->priv = priv; + priv->create_display = TRUE; + priv->display_name = NULL; + priv->wl_display = NULL; + priv->compositor = NULL; + priv->shell = NULL; + priv->event_fd = -1; + priv->event_mask = 0; +} + +/** + * 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) +{ + return g_object_new(GST_VAAPI_TYPE_DISPLAY_WAYLAND, + "display-name", display_name, + NULL); +} + +/** + * 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) +{ + g_return_val_if_fail(wl_display, NULL); + + return g_object_new(GST_VAAPI_TYPE_DISPLAY_WAYLAND, + "wl-display", wl_display, + NULL); +} + +/** + * 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 display->priv->wl_display; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h new file mode 100644 index 0000000000..c5fc0f635c --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h @@ -0,0 +1,94 @@ +/* + * gstvaapidisplay_wayland.h - VA/Wayland display abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * 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 +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DISPLAY_WAYLAND \ + (gst_vaapi_display_wayland_get_type()) + +#define GST_VAAPI_DISPLAY_WAYLAND(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ + GstVaapiDisplayWayland)) + +#define GST_VAAPI_DISPLAY_WAYLAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ + GstVaapiDisplayWaylandClass)) + +#define GST_VAAPI_IS_DISPLAY_WAYLAND(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_WAYLAND)) + +#define GST_VAAPI_IS_DISPLAY_WAYLAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_WAYLAND)) + +#define GST_VAAPI_DISPLAY_WAYLAND_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ + GstVaapiDisplayWaylandClass)) + +typedef struct _GstVaapiDisplayWayland GstVaapiDisplayWayland; +typedef struct _GstVaapiDisplayWaylandPrivate GstVaapiDisplayWaylandPrivate; +typedef struct _GstVaapiDisplayWaylandClass GstVaapiDisplayWaylandClass; + +/** + * 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; +}; + +GType +gst_vaapi_display_wayland_get_type(void) G_GNUC_CONST; + +GstVaapiDisplay * +gst_vaapi_display_wayland_new(const gchar *display_name); + +GstVaapiDisplay * +gst_vaapi_display_wayland_new_with_display(struct wl_display *wl_display); + +struct wl_display * +gst_vaapi_display_wayland_get_display(GstVaapiDisplayWayland *display); + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_WAYLAND_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h new file mode 100644 index 0000000000..04a72db611 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -0,0 +1,60 @@ +/* + * gstvaapidisplay_wayland_priv.h - Internal VA/Wayland interface + * + * Copyright (C) 2012 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ + GstVaapiDisplayWaylandPrivate)) + +#define GST_VAAPI_DISPLAY_WAYLAND_CAST(display) \ + ((GstVaapiDisplayWayland *)(display)) + +/** + * 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_CAST(display)->priv->wl_display + +struct _GstVaapiDisplayWaylandPrivate { + gchar *display_name; + struct wl_display *wl_display; + struct wl_compositor *compositor; + struct wl_shell *shell; + gint event_fd; + guint32 event_mask; + guint create_display : 1; +}; + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_WAYLAND_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index d84b7b0d68..aa1b110943 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -75,6 +75,17 @@ G_BEGIN_DECLS #define GST_VAAPI_OBJECT_DISPLAY_GLX(object) \ GST_VAAPI_DISPLAY_GLX_CAST(GST_VAAPI_OBJECT_DISPLAY(object)) +/** + * GST_VAAPI_OBJECT_DISPLAY_WAYLAND: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the #GstVaapiDisplayWayland the @object is + * bound to. This is an internal macro that does not do any run-time + * type check and requires #include "gstvaapidisplay_wayland_priv.h" + */ +#define GST_VAAPI_OBJECT_DISPLAY_WAYLAND(object) \ + GST_VAAPI_DISPLAY_WAYLAND_CAST(GST_VAAPI_OBJECT_DISPLAY(object)) + /** * GST_VAAPI_OBJECT_VADISPLAY: * @object: a #GstVaapiObject @@ -108,6 +119,17 @@ G_BEGIN_DECLS #define GST_VAAPI_OBJECT_XSCREEN(object) \ GST_VAAPI_DISPLAY_XSCREEN(GST_VAAPI_OBJECT_DISPLAY(object)) +/** + * GST_VAAPI_OBJECT_WL_DISPLAY: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the underlying #wl_display of @display. + * This is an internal macro that does not do any run-time type check + * and requires #include "gstvaapidisplay_wayland_priv.h". + */ +#define GST_VAAPI_OBJECT_WL_DISPLAY(object) \ + GST_VAAPI_DISPLAY_WL_DISPLAY(GST_VAAPI_OBJECT_DISPLAY(object)) + /** * GST_VAAPI_OBJECT_LOCK_DISPLAY: * @object: a #GstVaapiObject diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c new file mode 100644 index 0000000000..6963414651 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -0,0 +1,302 @@ +/* + * gstvaapiwindow_wayland.c - VA/Wayland window abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * 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:gstvaapiwindow_wayland + * @short_description: VA/Wayland window abstraction + */ + +#include "sysdeps.h" +#include +#include "gstvaapicompat.h" +#include "gstvaapiwindow_wayland.h" +#include "gstvaapidisplay_wayland.h" +#include "gstvaapidisplay_wayland_priv.h" +#include "gstvaapiutils.h" +#include "gstvaapi_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiWindowWayland, + gst_vaapi_window_wayland, + GST_VAAPI_TYPE_WINDOW); + +#define GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_WINDOW_WAYLAND, \ + GstVaapiWindowWaylandPrivate)) + +struct _GstVaapiWindowWaylandPrivate { + struct wl_shell_surface *shell_surface; + struct wl_surface *surface; + struct wl_buffer *buffer; + guint redraw_pending : 1; +}; + +static gboolean +gst_vaapi_window_wayland_show(GstVaapiWindow *window) +{ + GST_WARNING("unimplemented GstVaapiWindowWayland::show()"); + + return TRUE; +} + +static gboolean +gst_vaapi_window_wayland_hide(GstVaapiWindow *window) +{ + GST_WARNING("unimplemented GstVaapiWindowWayland::hide()"); + + return TRUE; +} + +static gboolean +gst_vaapi_window_wayland_create( + GstVaapiWindow *window, + guint *width, + guint *height +) +{ + GstVaapiWindowWaylandPrivate * const priv = + GST_VAAPI_WINDOW_WAYLAND(window)->priv; + GstVaapiDisplayWaylandPrivate * const priv_display = + GST_VAAPI_OBJECT_DISPLAY_WAYLAND(window)->priv; + + GST_DEBUG("create window, size %ux%u", *width, *height); + + g_return_val_if_fail(priv_display->compositor != NULL, FALSE); + g_return_val_if_fail(priv_display->shell != NULL, FALSE); + + priv->surface = wl_compositor_create_surface(priv_display->compositor); + if (!priv->surface) + return FALSE; + + priv->shell_surface = + wl_shell_get_shell_surface(priv_display->shell, priv->surface); + if (!priv->shell_surface) + return FALSE; + + wl_shell_surface_set_toplevel(priv->shell_surface); + wl_shell_surface_set_fullscreen( + priv->shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, + 0, + NULL + ); + + priv->redraw_pending = FALSE; + return TRUE; +} + +static void +gst_vaapi_window_wayland_destroy(GstVaapiWindow * window) +{ + GstVaapiWindowWaylandPrivate * const priv = + GST_VAAPI_WINDOW_WAYLAND(window)->priv; + + if (priv->shell_surface) { + wl_shell_surface_destroy(priv->shell_surface); + priv->shell_surface = NULL; + } + + if (priv->surface) { + wl_surface_destroy(priv->surface); + priv->surface = NULL; + } + + if (priv->buffer) { + wl_buffer_destroy(priv->buffer); + priv->buffer = NULL; + } +} + +static gboolean +gst_vaapi_window_wayland_resize( + GstVaapiWindow * window, + guint width, + guint height +) +{ + GST_DEBUG("resize window, new size %ux%u", width, height); + return TRUE; +} + +static void +frame_redraw_callback(void *data, struct wl_callback *callback, uint32_t time) +{ + GstVaapiWindowWaylandPrivate * const priv = data; + + priv->redraw_pending = FALSE; + wl_buffer_destroy(priv->buffer); + priv->buffer = NULL; + wl_callback_destroy(callback); +} + +static const struct wl_callback_listener frame_callback_listener = { + frame_redraw_callback +}; + +static gboolean +gst_vaapi_window_wayland_render( + GstVaapiWindow *window, + GstVaapiSurface *surface, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect, + guint flags +) +{ + GstVaapiWindowWaylandPrivate * const priv = + GST_VAAPI_WINDOW_WAYLAND(window)->priv; + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(window); + struct wl_display * const wl_display = GST_VAAPI_OBJECT_WL_DISPLAY(window); + struct wl_buffer *buffer; + struct wl_callback *callback; + guint width, height; + VASurfaceID surface_id; + VAStatus status; + + /* XXX: use VPP to support unusual source and destination rectangles */ + gst_vaapi_surface_get_size(surface, &width, &height); + if (src_rect->x != 0 || + src_rect->y != 0 || + src_rect->width != width || + src_rect->height != height) { + GST_ERROR("unsupported source rectangle for rendering"); + return FALSE; + } + + if (0 && (dst_rect->width != width || dst_rect->height != height)) { + GST_ERROR("unsupported target rectangle for rendering"); + return FALSE; + } + + surface_id = GST_VAAPI_OBJECT_ID(surface); + if (surface_id == VA_INVALID_ID) + return FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + + /* Wait for the previous frame to complete redraw */ + if (priv->redraw_pending) + wl_display_iterate(wl_display, WL_DISPLAY_READABLE); + + status = vaGetSurfaceBufferWl( + GST_VAAPI_DISPLAY_VADISPLAY(display), + surface_id, + &buffer + ); + if (!vaapi_check_status(status, "vaGetSurfaceBufferWl()")) + return FALSE; + + /* XXX: attach to the specified target rectangle */ + wl_surface_attach(priv->surface, buffer, 0, 0); + wl_surface_damage(priv->surface, 0, 0, width, height); + + wl_display_iterate(wl_display, WL_DISPLAY_WRITABLE); + priv->redraw_pending = TRUE; + priv->buffer = buffer; + + callback = wl_surface_frame(priv->surface); + wl_callback_add_listener(callback, &frame_callback_listener, priv); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + return TRUE; +} + +static void +gst_vaapi_window_wayland_finalize(GObject *object) +{ + G_OBJECT_CLASS(gst_vaapi_window_wayland_parent_class)->finalize(object); +} + +static void +gst_vaapi_window_wayland_constructed(GObject *object) +{ + GObjectClass *parent_class; + + parent_class = G_OBJECT_CLASS(gst_vaapi_window_wayland_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + +static void +gst_vaapi_window_wayland_class_init(GstVaapiWindowWaylandClass * klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiWindowClass * const window_class = GST_VAAPI_WINDOW_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiWindowWaylandPrivate)); + + object_class->finalize = gst_vaapi_window_wayland_finalize; + object_class->constructed = gst_vaapi_window_wayland_constructed; + + window_class->create = gst_vaapi_window_wayland_create; + window_class->destroy = gst_vaapi_window_wayland_destroy; + window_class->show = gst_vaapi_window_wayland_show; + window_class->hide = gst_vaapi_window_wayland_hide; + window_class->render = gst_vaapi_window_wayland_render; + window_class->resize = gst_vaapi_window_wayland_resize; +} + +static void +gst_vaapi_window_wayland_init(GstVaapiWindowWayland * window) +{ + GstVaapiWindowWaylandPrivate *priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); + + window->priv = priv; + priv->shell_surface = NULL; + priv->surface = NULL; + priv->buffer = NULL; + priv->redraw_pending = FALSE; +} + +/** + * gst_vaapi_window_wayland_new: + * @display: a #GstVaapiDisplay + * @width: the requested window width, in pixels + * @height: the requested windo height, in pixels + * + * Creates a window with the specified @width and @height. The window + * will be attached to the @display and remains invisible to the user + * until gst_vaapi_window_show() is called. + * + * Return value: the newly allocated #GstVaapiWindow object + */ +GstVaapiWindow * +gst_vaapi_window_wayland_new( + GstVaapiDisplay *display, + guint width, + guint height +) +{ + GST_DEBUG("new window, size %ux%u", width, height); + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(height > 0, NULL); + + return g_object_new(GST_VAAPI_TYPE_WINDOW_WAYLAND, + "display", display, + "id", GST_VAAPI_ID(0), + "width", width, + "height", height, + NULL); +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h new file mode 100644 index 0000000000..d711fb776b --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h @@ -0,0 +1,89 @@ +/* + * gstvaapiwindow_wayland.h - VA/Wayland window abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * 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_WINDOW_WAYLAND_H +#define GST_VAAPI_WINDOW_WAYLAND_H + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_WINDOW_WAYLAND \ + (gst_vaapi_window_wayland_get_type()) + +#define GST_VAAPI_WINDOW_WAYLAND(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_WINDOW_WAYLAND, \ + GstVaapiWindowWayland)) + +#define GST_VAAPI_WINDOW_WAYLAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_WINDOW_WAYLAND, \ + GstVaapiWindowWaylandClass)) + +#define GST_VAAPI_IS_WINDOW_WAYLAND(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW_WAYLAND)) + +#define GST_VAAPI_IS_WINDOW_WAYLAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW_WAYLAND)) + +#define GST_VAAPI_WINDOW_WAYLAND_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_WINDOW_WAYLAND, \ + GstVaapiWindowWaylandClass)) + +typedef struct _GstVaapiWindowWayland GstVaapiWindowWayland; +typedef struct _GstVaapiWindowWaylandPrivate GstVaapiWindowWaylandPrivate; +typedef struct _GstVaapiWindowWaylandClass GstVaapiWindowWaylandClass; + +/** + * GstVaapiWindowWayland: + * + * A Wayland window abstraction. + */ +struct _GstVaapiWindowWayland { + /*< private >*/ + GstVaapiWindow parent_instance; + + GstVaapiWindowWaylandPrivate *priv; +}; + +/** + * GstVaapiWindowWaylandClass: + * + * An Wayland #Window wrapper class. + */ +struct _GstVaapiWindowWaylandClass { + /*< private >*/ + GstVaapiWindowClass parent_class; +}; + +GType +gst_vaapi_window_wayland_get_type(void) G_GNUC_CONST; + +GstVaapiWindow * +gst_vaapi_window_wayland_new(GstVaapiDisplay *display, guint width, guint height); + +G_END_DECLS + +#endif /* GST_VAAPI_WINDOW_WAYLAND_H */ From 5e356922bf33d7bb6a8a036957d4adc3bb4e5ea1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Jul 2012 12:56:33 +0200 Subject: [PATCH 0760/3781] tests: add support for Wayland. --- tests/Makefile.am | 8 ++++ tests/output.c | 10 ++++ tests/test-display.c | 40 ++++++++++++++-- tests/test-windows.c | 108 ++++++++++++++++++++++++++++++++----------- 4 files changed, 134 insertions(+), 32 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 71c5531004..1aacdc99d3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -41,6 +41,14 @@ TEST_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-@GST_MAJORMINOR@.la endif +if USE_WAYLAND +TEST_CFLAGS += $(WAYLAND_CFLAGS) +TEST_LIBS += \ + $(LIBVA_WAYLAND_LIBS) \ + $(WAYLAND_LIBS) \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-@GST_MAJORMINOR@.la +endif + test_codecs_source_c = test-mpeg2.c test-h264.c test-vc1.c test-jpeg.c test_codecs_source_h = $(test_codecs_source_c:%.c=%.h) test-decode.h diff --git a/tests/output.c b/tests/output.c index 583347c8af..d47af7d536 100644 --- a/tests/output.c +++ b/tests/output.c @@ -30,11 +30,21 @@ # include # include #endif +#if USE_WAYLAND +# include +# include +#endif #include "output.h" static const VideoOutputInfo *g_video_output; static const VideoOutputInfo g_video_outputs[] = { /* Video outputs are sorted in test order for automatic characterisation */ +#if USE_WAYLAND + { "wayland", + gst_vaapi_display_wayland_new, + gst_vaapi_window_wayland_new + }, +#endif #if USE_X11 { "x11", gst_vaapi_display_x11_new, diff --git a/tests/test-display.c b/tests/test-display.c index 47caa3d455..2ebbed0463 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -22,10 +22,13 @@ #include "config.h" #include #if USE_X11 -#include +# include #endif #if USE_GLX -#include +# include +#endif +#if USE_WAYLAND +# include #endif #ifdef HAVE_VA_VA_GLX_H @@ -147,8 +150,6 @@ dump_caps(GstVaapiDisplay *display) int main(int argc, char *argv[]) { - Display *x11_display; - VADisplay va_display; GstVaapiDisplay *display; guint width, height, par_n, par_d; @@ -178,6 +179,8 @@ main(int argc, char *argv[]) g_print("# Create display with gst_vaapi_display_x11_new_with_display()\n"); g_print("#\n"); { + Display *x11_display; + x11_display = XOpenDisplay(NULL); if (!x11_display) g_error("could not create X11 display"); @@ -196,6 +199,9 @@ main(int argc, char *argv[]) g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplay()]\n"); g_print("#\n"); { + Display *x11_display; + VADisplay va_display; + x11_display = XOpenDisplay(NULL); if (!x11_display) g_error("could not create X11 display"); @@ -239,6 +245,8 @@ main(int argc, char *argv[]) g_print("# Create display with gst_vaapi_display_glx_new_with_display()\n"); g_print("#\n"); { + Display *x11_display; + x11_display = XOpenDisplay(NULL); if (!x11_display) g_error("could not create X11 display"); @@ -258,6 +266,9 @@ main(int argc, char *argv[]) g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayGLX()]\n"); g_print("#\n"); { + Display *x11_display; + VADisplay va_display; + x11_display = XOpenDisplay(NULL); if (!x11_display) g_error("could not create X11 display"); @@ -278,6 +289,27 @@ main(int argc, char *argv[]) #endif #endif +#if USE_WAYLAND + g_print("#\n"); + g_print("# Create display with gst_vaapi_display_wayland_new()\n"); + g_print("#\n"); + { + display = gst_vaapi_display_wayland_new(NULL); + if (!display) + g_error("could not create Gst/VA display"); + + gst_vaapi_display_get_size(display, &width, &height); + g_print("Display size: %ux%u\n", width, height); + + gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d); + g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); + + dump_caps(display); + g_object_unref(display); + } + g_print("\n"); +#endif + gst_deinit(); return 0; } diff --git a/tests/test-windows.c b/tests/test-windows.c index 56c316883a..ec6c3d9b2c 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -19,28 +19,34 @@ * Boston, MA 02110-1301 USA */ -#include -#include +#include "config.h" #include #include +#if USE_X11 +# include +# include +#endif +#if USE_WAYLAND +# include +# include +#endif #include "image.h" -static inline void pause(void) +static inline void +pause(void) { g_print("Press any key to continue...\n"); getchar(); } -int -main(int argc, char *argv[]) +static GstVaapiSurface * +create_test_surface(GstVaapiDisplay *display, guint width, guint height) { - GstVaapiDisplay *display; - GstVaapiWindow *window; - GstVaapiSurface *surface; - GstVaapiImage *image = NULL; - guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + GstVaapiImage *image = NULL; + GstVaapiSurface *surface; guint i; + static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; static const GstVaapiImageFormat image_formats[] = { GST_VAAPI_IMAGE_NV12, GST_VAAPI_IMAGE_YV12, @@ -53,18 +59,6 @@ main(int argc, char *argv[]) 0 }; - static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - static const guint width = 320; - static const guint height = 240; - static const guint win_width = 640; - static const guint win_height = 480; - - gst_init(&argc, &argv); - - display = gst_vaapi_display_x11_new(NULL); - if (!display) - g_error("could not create Gst/VA display"); - surface = gst_vaapi_surface_new(display, chroma_type, width, height); if (!surface) g_error("could not create Gst/VA surface"); @@ -73,11 +67,10 @@ main(int argc, char *argv[]) const GstVaapiImageFormat format = image_formats[i]; image = image_generate(display, format, width, height); - if (image) { - if (image_upload(image, surface)) - break; - g_object_unref(image); - } + if (!image) + break; + if (image_upload(image, surface)) + break; } if (!image) g_error("could not create Gst/VA image"); @@ -85,6 +78,34 @@ main(int argc, char *argv[]) if (!gst_vaapi_surface_sync(surface)) g_error("could not complete image upload"); + g_object_unref(image); + return surface; +} + +int +main(int argc, char *argv[]) +{ + GstVaapiDisplay *display; + GstVaapiWindow *window; + GstVaapiSurface *surface; + guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + + static const guint width = 320; + static const guint height = 240; + static const guint win_width = 640; + static const guint win_height = 480; + + gst_init(&argc, &argv); + +#if USE_X11 + display = gst_vaapi_display_x11_new(NULL); + if (!display) + g_error("could not create Gst/VA display"); + + surface = create_test_surface(display, width, height); + if (!surface) + g_error("could not create Gst/VA surface"); + g_print("#\n"); g_print("# Create window with gst_vaapi_window_x11_new()\n"); g_print("#\n"); @@ -141,9 +162,40 @@ main(int argc, char *argv[]) XDestroyWindow(dpy, win); } - g_object_unref(image); g_object_unref(surface); g_object_unref(display); +#endif + +#if USE_WAYLAND + display = gst_vaapi_display_wayland_new(NULL); + if (!display) + g_error("could not create Gst/VA (Wayland) display"); + + surface = create_test_surface(display, width, height); + if (!surface) + g_error("could not create Gst/VA surface"); + + g_print("#\n"); + g_print("# Create window with gst_vaapi_window_wayland_new()\n"); + g_print("#\n"); + { + window = gst_vaapi_window_wayland_new(display, win_width, win_height); + if (!window) + g_error("could not create window"); + + gst_vaapi_window_show(window); + + if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) + g_error("could not render surface"); + + pause(); + g_object_unref(window); + } + + g_object_unref(surface); + g_object_unref(display); +#endif + gst_deinit(); return 0; } From 9e00c87367df27dc4ba450fd87d251859d9ec3d2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jul 2012 09:45:25 +0200 Subject: [PATCH 0761/3781] plugins: add support for Wayland. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 4 +++ gst-libs/gst/vaapi/gstvaapidisplay.h | 2 ++ gst/vaapi/Makefile.am | 5 +++ gst/vaapi/gstvaapipluginutil.c | 51 ++++++++++++++++++++++++---- gst/vaapi/gstvaapisink.c | 44 +++++++++++++++++++----- 5 files changed, 91 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 7972003a30..226efdc6ee 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -95,6 +95,10 @@ gst_vaapi_display_type_get_type(void) #if USE_GLX { GST_VAAPI_DISPLAY_TYPE_GLX, "VA/GLX display", "glx" }, +#endif +#if USE_WAYLAND + { GST_VAAPI_DISPLAY_TYPE_WAYLAND, + "VA/Wayland display", "wayland" }, #endif { 0, NULL, NULL }, }; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 81410ec677..d8fa9a38e4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -65,11 +65,13 @@ typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; * @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. */ enum _GstVaapiDisplayType { GST_VAAPI_DISPLAY_TYPE_ANY = 0, GST_VAAPI_DISPLAY_TYPE_X11, GST_VAAPI_DISPLAY_TYPE_GLX, + GST_VAAPI_DISPLAY_TYPE_WAYLAND, }; #define GST_VAAPI_TYPE_DISPLAY_TYPE \ diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index e3c3ddb62d..c8940c5f3a 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -19,6 +19,11 @@ libgstvaapi_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la endif +if USE_WAYLAND +libgstvaapi_LIBS += \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-$(GST_MAJORMINOR).la +endif + libgstvaapi_la_SOURCES = \ gstvaapi.c \ gstvaapidecode.c \ diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 3ae3d23597..08ca36ab79 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -32,12 +32,19 @@ #if USE_GLX # include #endif +#if USE_WAYLAND +# include +#endif #include "gstvaapipluginutil.h" /* Preferred first */ static const char *display_types[] = { "gst-vaapi-display", "vaapi-display", +#if USE_WAYLAND + "wl-display", + "wl-display-name", +#endif "x11-display", "x11-display-name", NULL @@ -50,6 +57,11 @@ typedef struct { } DisplayMap; static const DisplayMap g_display_map[] = { +#if USE_WAYLAND + { "wayland", + GST_VAAPI_DISPLAY_TYPE_WAYLAND, + gst_vaapi_display_wayland_new }, +#endif #if USE_GLX { "glx", GST_VAAPI_DISPLAY_TYPE_GLX, @@ -126,7 +138,15 @@ gst_vaapi_set_display( { GstVaapiDisplay *dpy = NULL; - if (!strcmp(type, "x11-display-name")) { + if (!strcmp(type, "vaapi-display")) { + g_return_if_fail(G_VALUE_HOLDS_POINTER(value)); + dpy = gst_vaapi_display_new_with_display(g_value_get_pointer(value)); + } + else if (!strcmp(type, "gst-vaapi-display")) { + g_return_if_fail(G_VALUE_HOLDS_OBJECT(value)); + dpy = g_value_dup_object(value); + } + else if (!strcmp(type, "x11-display-name")) { g_return_if_fail(G_VALUE_HOLDS_STRING(value)); #if USE_GLX dpy = gst_vaapi_display_glx_new(g_value_get_string(value)); @@ -142,14 +162,20 @@ gst_vaapi_set_display( if (!dpy) dpy = gst_vaapi_display_x11_new_with_display(g_value_get_pointer(value)); } - else if (!strcmp(type, "vaapi-display")) { +#if USE_WAYLAND + else if (!strcmp(type, "wl-display")) { + struct wl_display *wl_display; g_return_if_fail(G_VALUE_HOLDS_POINTER(value)); - dpy = gst_vaapi_display_new_with_display(g_value_get_pointer(value)); + wl_display = g_value_get_pointer(value); + dpy = gst_vaapi_display_wayland_new_with_display(wl_display); } - else if (!strcmp(type, "gst-vaapi-display")) { - g_return_if_fail(G_VALUE_HOLDS_OBJECT(value)); - dpy = g_value_dup_object(value); + else if (!strcmp(type, "wl-display-name")) { + const gchar *display_name; + g_return_if_fail(G_VALUE_HOLDS_STRING(value)); + display_name = g_value_get_string(value); + dpy = gst_vaapi_display_wayland_new(display_name); } +#endif if (dpy) { if (*display) @@ -206,6 +232,19 @@ gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) res = FALSE; break; } +#if USE_WAYLAND + case GST_VAAPI_DISPLAY_TYPE_WAYLAND: { + GstVaapiDisplayWayland * const wlvadpy = + GST_VAAPI_DISPLAY_WAYLAND(display); + struct wl_display * const wldpy = + gst_vaapi_display_wayland_get_display(wlvadpy); + if (!strcmp(type, "wl-display")) + gst_video_context_query_set_pointer(query, type, wldpy); + else + res = FALSE; + break; + } +#endif default: res = FALSE; break; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index f43b27fd1c..e5441a7bc5 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -41,6 +41,10 @@ # include # include #endif +#if USE_WAYLAND +# include +# include +#endif /* Supported interfaces */ #include @@ -354,20 +358,27 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) #if USE_GLX case GST_VAAPI_DISPLAY_TYPE_GLX: sink->window = gst_vaapi_window_glx_new(display, width, height); - break; + goto notify_xoverlay_interface; #endif case GST_VAAPI_DISPLAY_TYPE_X11: sink->window = gst_vaapi_window_x11_new(display, width, height); - break; - default: - GST_ERROR("unsupported display type %d", sink->display_type); - return FALSE; - } - if (sink->window) + notify_xoverlay_interface: + if (!sink->window) + break; gst_x_overlay_got_window_handle( GST_X_OVERLAY(sink), gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) ); + break; +#if USE_WAYLAND + case GST_VAAPI_DISPLAY_TYPE_WAYLAND: + sink->window = gst_vaapi_window_wayland_new(display, width, height); + break; +#endif + default: + GST_ERROR("unsupported display type %d", sink->display_type); + return FALSE; + } } return sink->window != NULL; } @@ -458,6 +469,16 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) sink->video_width = video_width; sink->video_height = video_height; +#if USE_WAYLAND + /* XXX: fix GstVaapiDisplayWayland::get_size() */ + if (sink->display_type == GST_VAAPI_DISPLAY_TYPE_WAYLAND) { + sink->window_width = video_width; + sink->window_height = video_height; + return gst_vaapisink_ensure_window(sink, + sink->window_width, sink->window_height); + } +#endif + gst_video_parse_caps_pixel_aspect_ratio(caps, &video_par_n, &video_par_d); sink->video_par_n = video_par_n; sink->video_par_d = video_par_d; @@ -662,7 +683,7 @@ error_transfer_surface: #endif static inline gboolean -gst_vaapisink_show_frame_x11( +gst_vaapisink_put_surface( GstVaapiSink *sink, GstVaapiSurface *surface, guint flags @@ -715,8 +736,13 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) break; #endif case GST_VAAPI_DISPLAY_TYPE_X11: - success = gst_vaapisink_show_frame_x11(sink, surface, flags); + success = gst_vaapisink_put_surface(sink, surface, flags); break; +#if USE_WAYLAND + case GST_VAAPI_DISPLAY_TYPE_WAYLAND: + success = gst_vaapisink_put_surface(sink, surface, flags); + break; +#endif default: GST_ERROR("unsupported display type %d", sink->display_type); success = FALSE; From 0bf1e761f963a11c476d5d87a141b9c27cad5892 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jul 2012 15:07:48 +0200 Subject: [PATCH 0762/3781] Fix build without X11. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 ++ gst/vaapi/gstvaapipluginutil.c | 6 ++++++ gst/vaapi/gstvaapisink.c | 27 ++++++++++++++++++++++++--- pkgconfig/Makefile.am | 2 ++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 226efdc6ee..7238518fc2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -90,8 +90,10 @@ gst_vaapi_display_type_get_type(void) static const GEnumValue display_types[] = { { GST_VAAPI_DISPLAY_TYPE_ANY, "Auto detection", "any" }, +#if USE_X11 { GST_VAAPI_DISPLAY_TYPE_X11, "VA/X11 display", "x11" }, +#endif #if USE_GLX { GST_VAAPI_DISPLAY_TYPE_GLX, "VA/GLX display", "glx" }, diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 08ca36ab79..ac7efebb39 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -45,8 +45,10 @@ static const char *display_types[] = { "wl-display", "wl-display-name", #endif +#if USE_X11 "x11-display", "x11-display-name", +#endif NULL }; @@ -146,6 +148,7 @@ gst_vaapi_set_display( g_return_if_fail(G_VALUE_HOLDS_OBJECT(value)); dpy = g_value_dup_object(value); } +#if USE_X11 else if (!strcmp(type, "x11-display-name")) { g_return_if_fail(G_VALUE_HOLDS_STRING(value)); #if USE_GLX @@ -162,6 +165,7 @@ gst_vaapi_set_display( if (!dpy) dpy = gst_vaapi_display_x11_new_with_display(g_value_get_pointer(value)); } +#endif #if USE_WAYLAND else if (!strcmp(type, "wl-display")) { struct wl_display *wl_display; @@ -215,6 +219,7 @@ gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) } else { switch (display_type) { +#if USE_X11 #if USE_GLX case GST_VAAPI_DISPLAY_TYPE_GLX: #endif @@ -232,6 +237,7 @@ gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) res = FALSE; break; } +#endif #if USE_WAYLAND case GST_VAAPI_DISPLAY_TYPE_WAYLAND: { GstVaapiDisplayWayland * const wlvadpy = diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index e5441a7bc5..4c6fd80141 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -35,8 +35,10 @@ #include #include #include -#include -#include +#if USE_X11 +# include +# include +#endif #if USE_GLX # include # include @@ -141,8 +143,10 @@ gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface) /* GstXOverlay interface */ +#if USE_X11 static gboolean gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id); +#endif static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); @@ -158,7 +162,16 @@ gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window) sink->display_type = GST_VAAPI_DISPLAY_TYPE_X11; sink->foreign_window = TRUE; - gst_vaapisink_ensure_window_xid(sink, window); + + switch (sink->display_type) { +#if USE_X11 + case GST_VAAPI_DISPLAY_TYPE_X11: + gst_vaapisink_ensure_window_xid(sink, window); + break; +#endif + default: + break; + } } static void @@ -213,6 +226,7 @@ gst_vaapisink_destroy(GstVaapiSink *sink) gst_caps_replace(&sink->caps, NULL); } +#if USE_X11 /* Checks whether a ConfigureNotify event is in the queue */ typedef struct _ConfigureNotifyEventPendingArgs ConfigureNotifyEventPendingArgs; struct _ConfigureNotifyEventPendingArgs { @@ -263,6 +277,7 @@ configure_notify_event_pending( ); return args.match; } +#endif static const gchar * get_display_type_name(GstVaapiDisplayType display_type) @@ -360,6 +375,7 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) sink->window = gst_vaapi_window_glx_new(display, width, height); goto notify_xoverlay_interface; #endif +#if USE_X11 case GST_VAAPI_DISPLAY_TYPE_X11: sink->window = gst_vaapi_window_x11_new(display, width, height); notify_xoverlay_interface: @@ -370,6 +386,7 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) ); break; +#endif #if USE_WAYLAND case GST_VAAPI_DISPLAY_TYPE_WAYLAND: sink->window = gst_vaapi_window_wayland_new(display, width, height); @@ -383,6 +400,7 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) return sink->window != NULL; } +#if USE_X11 static gboolean gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) { @@ -432,6 +450,7 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) } return sink->window != NULL; } +#endif static gboolean gst_vaapisink_start(GstBaseSink *base_sink) @@ -735,9 +754,11 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) success = gst_vaapisink_show_frame_glx(sink, surface, flags); break; #endif +#if USE_X11 case GST_VAAPI_DISPLAY_TYPE_X11: success = gst_vaapisink_put_surface(sink, surface, flags); break; +#endif #if USE_WAYLAND case GST_VAAPI_DISPLAY_TYPE_WAYLAND: success = gst_vaapisink_put_surface(sink, surface, flags); diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index 22628bdd50..dd1012a22b 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -1,5 +1,7 @@ pcfiles_in = gstreamer-vaapi.pc.in +if USE_X11 pcfiles_in += gstreamer-vaapi-x11.pc.in +endif if USE_GLX pcfiles_in += gstreamer-vaapi-glx.pc.in endif From 95b7d5a6e66602f0672db1ee2eb188cfa35dd938 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jul 2012 15:43:44 +0200 Subject: [PATCH 0763/3781] wayland: add packaging files. --- configure.ac | 4 ++++ debian.upstream/Makefile.am | 3 +++ debian.upstream/control.in | 9 +++++++++ debian.upstream/libgstvaapi-wayland.install.in | 1 + pkgconfig/Makefile.am | 10 +++++----- pkgconfig/gstreamer-vaapi-wayland.pc.in | 12 ++++++++++++ 6 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 debian.upstream/libgstvaapi-wayland.install.in create mode 100644 pkgconfig/gstreamer-vaapi-wayland.pc.in diff --git a/configure.ac b/configure.ac index 86c4f7b515..f6b07d52ff 100644 --- a/configure.ac +++ b/configure.ac @@ -454,6 +454,8 @@ debian.upstream/libgstvaapi.install.in debian.upstream/libgstvaapi-dev.install debian.upstream/libgstvaapi-glx-$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi-glx.install.in + debian.upstream/libgstvaapi-wayland-$GST_VAAPI_MAJOR_VERSION.install:\ +debian.upstream/libgstvaapi-wayland.install.in debian.upstream/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi-x11.install.in docs/Makefile @@ -473,6 +475,8 @@ debian.upstream/libgstvaapi-x11.install.in pkgconfig/gstreamer-vaapi.pc.in pkgconfig/gstreamer-vaapi-glx-$GST_MAJORMINOR.pc:\ pkgconfig/gstreamer-vaapi-glx.pc.in + pkgconfig/gstreamer-vaapi-wayland-$GST_MAJORMINOR.pc:\ +pkgconfig/gstreamer-vaapi-wayland.pc.in pkgconfig/gstreamer-vaapi-x11-$GST_MAJORMINOR.pc:\ pkgconfig/gstreamer-vaapi-x11.pc.in tests/Makefile diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index 8bb59be6d2..cf3bc3ef67 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -25,6 +25,8 @@ DEBIANFILES = \ libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-glx.install.in \ libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ + libgstvaapi-wayland.install.in \ + libgstvaapi-wayland-$(GST_VAAPI_MAJOR_VERSION).install \ rules \ $(NULL) @@ -37,6 +39,7 @@ DEBIANGENFILES = \ libgstvaapi-dev.install \ libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ + libgstvaapi-wayland-$(GST_VAAPI_MAJOR_VERSION).install \ $(NULL) EXTRA_DIST = \ diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 5f23160ce1..bd812abeed 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -67,6 +67,15 @@ Description: GStreamer libraries from the "vaapi" set . This package contains glx libraries for the "vaapi" set. +Package: libgstvaapi-wayland-@GST_VAAPI_MAJOR_VERSION@ +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: GStreamer libraries from the "vaapi" set + VA-API support libraries for GStreamer. + . + This package contains Wayland libraries for the "vaapi" set. + Package: libgstvaapi-dev Architecture: any Section: libdevel diff --git a/debian.upstream/libgstvaapi-wayland.install.in b/debian.upstream/libgstvaapi-wayland.install.in new file mode 100644 index 0000000000..e1740b5c92 --- /dev/null +++ b/debian.upstream/libgstvaapi-wayland.install.in @@ -0,0 +1 @@ +debian/tmp/usr/lib/libgstvaapi-wayland-@GST_MAJORMINOR@.so.* diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index dd1012a22b..7d6741379e 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -5,23 +5,23 @@ endif if USE_GLX pcfiles_in += gstreamer-vaapi-glx.pc.in endif +if USE_WAYLAND +pcfiles_in += gstreamer-vaapi-wayland.pc.in +endif pcfiles = $(pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc) all_pcfiles_in = gstreamer-vaapi.pc.in all_pcfiles_in += gstreamer-vaapi-x11.pc.in all_pcfiles_in += gstreamer-vaapi-glx.pc.in +all_pcfiles_in += gstreamer-vaapi-wayland.pc.in all_pcfiles = $(all_pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc) pkgconfigdir = @pkgconfigdir@ pkgconfig_DATA = $(pcfiles) -EXTRA_DIST = \ - gstreamer-vaapi.pc.in \ - gstreamer-vaapi-glx.pc.in \ - gstreamer-vaapi-x11.pc.in \ - $(NULL) +EXTRA_DIST = $(all_pcfiles_in) DISTCLEANFILES = $(all_pcfiles) diff --git a/pkgconfig/gstreamer-vaapi-wayland.pc.in b/pkgconfig/gstreamer-vaapi-wayland.pc.in new file mode 100644 index 0000000000..07f1da0145 --- /dev/null +++ b/pkgconfig/gstreamer-vaapi-wayland.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ + +Name: GStreamer VA-API (Wayland) Plugins Libraries +Description: Streaming media framework, VA-API (Wayland) plugins libraries +Requires: gstreamer-vaapi-@GST_MAJORMINOR@ libva-wayland +Version: @VERSION@ +Libs: -L${libdir} -lgstvaapi-wayland-@GST_MAJORMINOR@ +Cflags: -I${includedir} From 5be6de20cbcfc95bc5f2addae8e17782260d6496 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jul 2012 19:58:55 +0200 Subject: [PATCH 0764/3781] wayland: mangle display name for cache lookups. --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 95 ++++++++++++++------ 1 file changed, 69 insertions(+), 26 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 0407c96cb5..ec59180507 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -44,6 +44,15 @@ enum { PROP_WL_DISPLAY }; +#define NAME_PREFIX "WLD:" +#define NAME_PREFIX_LENGTH 4 + +static inline gboolean +is_display_name(const gchar *display_name) +{ + return strncmp(display_name, NAME_PREFIX, NAME_PREFIX_LENGTH) == 0; +} + static inline const gchar * get_default_display_name(void) { @@ -54,28 +63,39 @@ get_default_display_name(void) return g_display_name; } +static inline guint +get_display_name_length(const gchar *display_name) +{ + const gchar *str; + + str = strchr(display_name, '-'); + if (str) + return str - display_name; + return strlen(display_name); +} + static gboolean compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data) { - const gchar *display_name; + const gchar *cached_name = a; + const gchar *tested_name = b; + guint cached_name_length, tested_name_length; - /* XXX: handle screen number? */ - if (a && b) - return strcmp(a, b) == 0; + if (!cached_name || !is_display_name(cached_name)) + return FALSE; + cached_name += NAME_PREFIX_LENGTH; + cached_name_length = get_display_name_length(cached_name); - /* Match "" or default display name */ - if (a) - display_name = a; - else if (b) - display_name = b; - else - return TRUE; + g_return_val_if_fail(tested_name && is_display_name(tested_name), FALSE); + tested_name += NAME_PREFIX_LENGTH; + tested_name_length = get_display_name_length(tested_name); - if (*display_name == '\0') - return TRUE; - if (strcmp(display_name, get_default_display_name()) == 0) - return TRUE; - return FALSE; + /* XXX: handle screen number and default WAYLAND_DISPLAY name */ + if (cached_name_length != tested_name_length) + return FALSE; + if (strncmp(cached_name, tested_name, cached_name_length) != 0) + return FALSE; + return TRUE; } static void @@ -84,6 +104,29 @@ gst_vaapi_display_wayland_finalize(GObject *object) G_OBJECT_CLASS(gst_vaapi_display_wayland_parent_class)->finalize(object); } +/* Reconstruct a display name without our prefix */ +static const gchar * +get_display_name(gpointer ptr) +{ + GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(ptr); + const gchar *display_name = display->priv->display_name; + + if (!display_name) + return NULL; + + if (is_display_name(display_name)) { + display_name += NAME_PREFIX_LENGTH; + if (*display_name == '\0') + return NULL; + return display_name; + } + + /* XXX: this should not happen */ + g_assert(0 && "display name without prefix"); + return display_name; +} + +/* Mangle display name with our prefix */ static void set_display_name(GstVaapiDisplayWayland *display, const gchar *display_name) { @@ -91,10 +134,12 @@ set_display_name(GstVaapiDisplayWayland *display, const gchar *display_name) g_free(priv->display_name); - if (display_name) - priv->display_name = g_strdup(display_name); - else - priv->display_name = NULL; + if (!display_name) { + display_name = get_default_display_name(); + if (!display_name) + display_name = ""; + } + priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, display_name); } static void @@ -131,7 +176,7 @@ gst_vaapi_display_wayland_get_property( switch (prop_id) { case PROP_DISPLAY_NAME: - g_value_set_string(value, display->priv->display_name); + g_value_set_string(value, get_display_name(display)); break; case PROP_WL_DISPLAY: g_value_set_pointer(value, gst_vaapi_display_wayland_get_display(display)); @@ -150,7 +195,6 @@ gst_vaapi_display_wayland_constructed(GObject *object) GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache(); const GstVaapiDisplayInfo *info; GObjectClass *parent_class; - const gchar *display_name; priv->create_display = priv->wl_display == NULL; @@ -169,10 +213,9 @@ gst_vaapi_display_wayland_constructed(GObject *object) /* Reset display-name if the user provided his own Wayland display */ if (!priv->create_display) { - /* XXX: get socket name */ + /* XXX: how to get socket/display name? */ GST_WARNING("wayland: get display name"); - display_name = NULL; - set_display_name(display, display_name); + set_display_name(display, NULL); } parent_class = G_OBJECT_CLASS(gst_vaapi_display_wayland_parent_class); @@ -215,7 +258,7 @@ gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display) if (!priv->create_display) return priv->wl_display != NULL; - priv->wl_display = wl_display_connect(priv->display_name); + priv->wl_display = wl_display_connect(get_display_name(display)); if (!priv->wl_display) return FALSE; From af3b6dc2b86fef102329fcef3bb0db8a51841195 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 25 Jul 2012 10:39:04 +0200 Subject: [PATCH 0765/3781] wayland: fix double disconnect of display. --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index ec59180507..56487d5033 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -292,7 +292,8 @@ gst_vaapi_display_wayland_close_display(GstVaapiDisplay * display) } if (priv->wl_display) { - wl_display_disconnect(priv->wl_display); + if (priv->create_display) + wl_display_disconnect(priv->wl_display); priv->wl_display = NULL; } From 44d6f7631ba8db5537d3c4d0aecb7b778cd51290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 26 Jul 2012 09:27:47 -0400 Subject: [PATCH 0766/3781] wayland: respond to ping/pong protocol so we're not deemed unresponsive. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 26 +++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 6963414651..81e658a911 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -68,6 +68,30 @@ gst_vaapi_window_wayland_hide(GstVaapiWindow *window) return TRUE; } +static void +handle_ping(void *data, struct wl_shell_surface *shell_surface, + uint32_t serial) +{ + wl_shell_surface_pong(shell_surface, serial); +} + +static void +handle_configure(void *data, struct wl_shell_surface *shell_surface, + uint32_t edges, int32_t width, int32_t height) +{ +} + +static void +handle_popup_done(void *data, struct wl_shell_surface *shell_surface) +{ +} + +static const struct wl_shell_surface_listener shell_surface_listener = { + handle_ping, + handle_configure, + handle_popup_done +}; + static gboolean gst_vaapi_window_wayland_create( GstVaapiWindow *window, @@ -94,6 +118,8 @@ gst_vaapi_window_wayland_create( if (!priv->shell_surface) return FALSE; + wl_shell_surface_add_listener(priv->shell_surface, + &shell_surface_listener, priv); wl_shell_surface_set_toplevel(priv->shell_surface); wl_shell_surface_set_fullscreen( priv->shell_surface, From 22b2c2cb4fb29d566abab57c557391ea1cf8e32a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 26 Jul 2012 09:28:51 -0400 Subject: [PATCH 0767/3781] wayland: use scale fullscreen method. This makes the compositor scale the surface to fit and preserves aspect ratio. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 81e658a911..867c37cc80 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -123,7 +123,7 @@ gst_vaapi_window_wayland_create( wl_shell_surface_set_toplevel(priv->shell_surface); wl_shell_surface_set_fullscreen( priv->shell_surface, - WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL ); From 511cc95a448ca5c7843307a89c2a9cb02ccfba4f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 27 Jul 2012 10:45:41 +0200 Subject: [PATCH 0768/3781] plugins: prefer X11 rendering over GLX. Prefer X11 display over GLX so that "vaapisink" uses X11, i.e. vaPutSurface(), for rendering instead of texturing. --- gst/vaapi/gstvaapipluginutil.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ac7efebb39..504d53a8cd 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -64,15 +64,15 @@ static const DisplayMap g_display_map[] = { GST_VAAPI_DISPLAY_TYPE_WAYLAND, gst_vaapi_display_wayland_new }, #endif -#if USE_GLX - { "glx", - GST_VAAPI_DISPLAY_TYPE_GLX, - gst_vaapi_display_glx_new }, -#endif #if USE_X11 { "x11", GST_VAAPI_DISPLAY_TYPE_X11, gst_vaapi_display_x11_new }, +#endif +#if USE_GLX + { "glx", + GST_VAAPI_DISPLAY_TYPE_GLX, + gst_vaapi_display_glx_new }, #endif { NULL, } }; From 4401ada22ac29642b037db832e1ee1c740d8372d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 27 Jul 2012 14:27:05 +0200 Subject: [PATCH 0769/3781] wayland: implement display ::get_size*() hooks. --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 82 ++++++++++++++++++- .../gst/vaapi/gstvaapidisplay_wayland_priv.h | 5 ++ gst/vaapi/gstvaapisink.c | 10 --- 3 files changed, 86 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 56487d5033..6ebf9da76a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -223,6 +223,35 @@ gst_vaapi_display_wayland_constructed(GObject *object) parent_class->constructed(object); } +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 display_handle_global( struct wl_display *display, @@ -238,6 +267,10 @@ display_handle_global( priv->compositor = wl_display_bind(display, id, &wl_compositor_interface); else if (strcmp(interface, "wl_shell") == 0) priv->shell = wl_display_bind(display, id, &wl_shell_interface); + else if (strcmp(interface, "wl_output") == 0) { + priv->output = wl_display_bind(display, id, &wl_output_interface); + wl_output_add_listener(priv->output, &output_listener, priv); + } } static int @@ -337,6 +370,46 @@ gst_vaapi_display_wayland_get_display_info( return TRUE; } +static void +gst_vaapi_display_wayland_get_size( + GstVaapiDisplay *display, + guint *pwidth, + guint *pheight +) +{ + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND(display)->priv; + + 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(display)->priv; + + if (!priv->output) + return; + + if (pwidth) + *pwidth = priv->phys_width; + + if (pheight) + *pheight = priv->phys_height; +} + static void gst_vaapi_display_wayland_class_init(GstVaapiDisplayWaylandClass * klass) { @@ -353,6 +426,8 @@ gst_vaapi_display_wayland_class_init(GstVaapiDisplayWaylandClass * klass) 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; /** * GstVaapiDisplayWayland:wayland-display: @@ -387,7 +462,7 @@ gst_vaapi_display_wayland_class_init(GstVaapiDisplayWaylandClass * klass) static void gst_vaapi_display_wayland_init(GstVaapiDisplayWayland *display) { - GstVaapiDisplayWaylandPrivate *priv = + GstVaapiDisplayWaylandPrivate * const priv = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); display->priv = priv; @@ -396,6 +471,11 @@ gst_vaapi_display_wayland_init(GstVaapiDisplayWayland *display) priv->wl_display = NULL; priv->compositor = NULL; priv->shell = NULL; + priv->output = NULL; + priv->width = 0; + priv->height = 0; + priv->phys_width = 0; + priv->phys_height = 0; priv->event_fd = -1; priv->event_mask = 0; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index 04a72db611..b98303e24e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -50,6 +50,11 @@ struct _GstVaapiDisplayWaylandPrivate { struct wl_display *wl_display; struct wl_compositor *compositor; struct wl_shell *shell; + struct wl_output *output; + guint width; + guint height; + guint phys_width; + guint phys_height; gint event_fd; guint32 event_mask; guint create_display : 1; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 4c6fd80141..7f1850652b 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -488,16 +488,6 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) sink->video_width = video_width; sink->video_height = video_height; -#if USE_WAYLAND - /* XXX: fix GstVaapiDisplayWayland::get_size() */ - if (sink->display_type == GST_VAAPI_DISPLAY_TYPE_WAYLAND) { - sink->window_width = video_width; - sink->window_height = video_height; - return gst_vaapisink_ensure_window(sink, - sink->window_width, sink->window_height); - } -#endif - gst_video_parse_caps_pixel_aspect_ratio(caps, &video_par_n, &video_par_d); sink->video_par_n = video_par_n; sink->video_par_d = video_par_d; From 7c1b9b48e46f893b2c0c1848a65729840bda5281 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 31 Jul 2012 11:51:57 +0200 Subject: [PATCH 0770/3781] jpeg: update to the latest VA-API changes (0.32.1+). --- configure.ac | 13 ++++++------ gst-libs/gst/vaapi/gstvaapicodec_objects.h | 6 +++--- gst-libs/gst/vaapi/gstvaapicompat.h | 1 - gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 24 +++++++++++----------- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/configure.ac b/configure.ac index f6b07d52ff..ebcf69bd72 100644 --- a/configure.ac +++ b/configure.ac @@ -380,7 +380,7 @@ if test $USE_GLX -eq 1; then fi AC_SUBST(LIBVA_GLX_PKGNAME) -dnl Check for JPEG decoding API (0.33+) +dnl Check for JPEG decoding API (0.32.1+) USE_JPEG_DECODER=0 AC_CACHE_CHECK([for JPEG decoding API], ac_cv_have_jpeg_decoding_api, [ @@ -390,12 +390,11 @@ AC_CACHE_CHECK([for JPEG decoding API], LIBS="$CFLAGS $LIBVA_LIBS" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - [[#include - #include ]], - [[VAPictureParameterBufferJPEG pic_param; - VASliceParameterBufferJPEG slice_param; - VAHuffmanTableBufferJPEG huffman_table; - VAIQMatrixBufferJPEG iq_matrix;]])], + [[#include ]], + [[VAPictureParameterBufferJPEGBaseline pic_param; + VASliceParameterBufferJPEGBaseline slice_param; + VAHuffmanTableBufferJPEGBaseline huffman_table; + VAIQMatrixBufferJPEGBaseline iq_matrix;]])], [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=1], [ac_cv_have_jpeg_decoding_api="no"] ) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index c70f34f3c9..a064c1595a 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -390,9 +390,9 @@ prefix##_class_init(type##Class *klass) \ #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), \ + +#define GST_VAAPI_HUFFMAN_TABLE_NEW(codec, decoder) \ + gst_vaapi_huffman_table_new(GST_VAAPI_DECODER_CAST(decoder), \ NULL, sizeof(VAHuffmanTableBuffer##codec)) G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 47cd7a3b6e..4a1f93d8d7 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -49,7 +49,6 @@ /* Compatibility glue with VA-API 0.34 */ #if VA_CHECK_VERSION(0,34,0) # include -# include #endif #endif /* GST_VAAPI_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index ac19b3df5f..5cfbe4d634 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -173,18 +173,15 @@ fill_picture( GstJpegFrameHdr *jpeg_frame_hdr ) { - VAPictureParameterBufferJPEG *pic_param = picture->param; + VAPictureParameterBufferJPEGBaseline *pic_param = picture->param; guint i; g_assert(pic_param); - memset(pic_param, 0, sizeof(VAPictureParameterBufferJPEG)); - pic_param->sample_precision = jpeg_frame_hdr->sample_precision; + memset(pic_param, 0, sizeof(VAPictureParameterBufferJPEGBaseline)); pic_param->picture_width = jpeg_frame_hdr->width; pic_param->picture_height = jpeg_frame_hdr->height; - /* XXX: ROI + rotation */ - pic_param->num_components = jpeg_frame_hdr->num_components; if (jpeg_frame_hdr->num_components > 4) return FALSE; @@ -208,13 +205,13 @@ fill_quantization_table( ) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; - VAIQMatrixBufferJPEG *iq_matrix; + VAIQMatrixBufferJPEGBaseline *iq_matrix; guint i, j, num_tables; if (!priv->has_quant_table) gst_jpeg_get_default_quantization_tables(&priv->quant_tables); - picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(JPEG, decoder); + picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(JPEGBaseline, decoder); g_assert(picture->iq_matrix); iq_matrix = picture->iq_matrix->param; @@ -246,13 +243,13 @@ fill_huffman_table( { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstJpegHuffmanTables * const huf_tables = &priv->huf_tables; - VAHuffmanTableBufferJPEG *huffman_table; + VAHuffmanTableBufferJPEGBaseline *huffman_table; guint i, num_tables; if (!priv->has_huf_table) gst_jpeg_get_default_huffman_tables(&priv->huf_tables); - picture->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW(JPEG, decoder); + picture->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW(JPEGBaseline, decoder); g_assert(picture->huf_table); huffman_table = picture->huf_table->param; @@ -277,6 +274,9 @@ fill_huffman_table( 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)); } return TRUE; } @@ -345,7 +345,7 @@ decode_picture( if (priv->current_picture && !decode_current_picture(decoder)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - picture = GST_VAAPI_PICTURE_NEW(JPEG, decoder); + picture = GST_VAAPI_PICTURE_NEW(JPEGBaseline, decoder); if (!picture) { GST_ERROR("failed to allocate picture"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -421,7 +421,7 @@ decode_scan( { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstVaapiPicture *picture = priv->current_picture; - VASliceParameterBufferJPEG *slice_param; + VASliceParameterBufferJPEGBaseline *slice_param; GstVaapiSlice *gst_slice; guint total_h_samples, total_v_samples; GstJpegScanHdr scan_hdr; @@ -448,7 +448,7 @@ decode_scan( return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } - gst_slice = GST_VAAPI_SLICE_NEW(JPEG, decoder, scan_data, scan_data_size); + gst_slice = GST_VAAPI_SLICE_NEW(JPEGBaseline, decoder, scan_data, scan_data_size); gst_vaapi_picture_add_slice(picture, gst_slice); slice_param = gst_slice->param; From 7070961202ea7026fb5acdc8dbfa1f1764261d56 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 31 Jul 2012 17:58:43 +0200 Subject: [PATCH 0771/3781] Fix build without X11 (again). Don't try to build libgstvaapi-x11.so.* if X11 was disabled. Also shuffle files list wrt. x11, glx and wayland backends. --- configure.ac | 2 +- gst-libs/gst/vaapi/Makefile.am | 119 +++++++++++++++++---------------- 2 files changed, 61 insertions(+), 60 deletions(-) diff --git a/configure.ac b/configure.ac index ebcf69bd72..0f696ddf52 100644 --- a/configure.ac +++ b/configure.ac @@ -282,7 +282,7 @@ if test "$enable_x11" = "yes"; then PKG_CHECK_MODULES(X11, [x11], [USE_X11=1], [USE_X11=0]) if test $USE_X11 -eq 1; then saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $WAYLAND_CFLAGS" + CPPFLAGS="$CPPFLAGS $X11_CFLAGS" AC_CHECK_HEADERS([X11/Xlib.h X11/Xutil.h X11/Xatom.h], [:], [USE_X11=0]) CPPFLAGS="$saved_CPPFLAGS" fi diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index fc84e49645..b9fc07debe 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -1,16 +1,17 @@ -lib_LTLIBRARIES = \ - libgstvaapi-@GST_MAJORMINOR@.la \ - libgstvaapi-x11-@GST_MAJORMINOR@.la \ - $(NULL) +lib_LTLIBRARIES = libgstvaapi-@GST_MAJORMINOR@.la -if USE_WAYLAND -lib_LTLIBRARIES += libgstvaapi-wayland-@GST_MAJORMINOR@.la +if USE_X11 +lib_LTLIBRARIES += libgstvaapi-x11-@GST_MAJORMINOR@.la endif if USE_GLX lib_LTLIBRARIES += libgstvaapi-glx-@GST_MAJORMINOR@.la endif +if USE_WAYLAND +lib_LTLIBRARIES += libgstvaapi-wayland-@GST_MAJORMINOR@.la +endif + libgstvaapi_includedir = \ $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi @@ -109,6 +110,11 @@ libgstvaapi_source_priv_h = \ sysdeps.h \ $(NULL) +if USE_JPEG_DECODER +libgstvaapi_source_c += gstvaapidecoder_jpeg.c +libgstvaapi_source_h += gstvaapidecoder_jpeg.h +endif + libgstvaapi_x11_source_c = \ gstvaapidisplay_x11.c \ gstvaapiutils.c \ @@ -128,23 +134,6 @@ libgstvaapi_x11_source_priv_h = \ gstvaapiutils_x11.h \ $(NULL) -libgstvaapi_wayland_source_c = \ - gstvaapidisplay_wayland.c \ - gstvaapiutils.c \ - gstvaapiwindow_wayland.c \ - $(NULL) - -libgstvaapi_wayland_source_h = \ - gstvaapidisplay_wayland.h \ - gstvaapiwindow_wayland.h \ - $(NULL) - -libgstvaapi_wayland_source_priv_h = \ - gstvaapicompat.h \ - gstvaapidisplay_wayland_priv.h \ - gstvaapiutils.h \ - $(NULL) - libgstvaapi_glx_source_c = \ gstvaapidisplay_glx.c \ gstvaapitexture.c \ @@ -172,10 +161,22 @@ libgstvaapi_glx_source_priv_h = \ gstvaapiutils_x11.h \ $(NULL) -if USE_JPEG_DECODER -libgstvaapi_source_c += gstvaapidecoder_jpeg.c -libgstvaapi_source_h += gstvaapidecoder_jpeg.h -endif +libgstvaapi_wayland_source_c = \ + gstvaapidisplay_wayland.c \ + gstvaapiutils.c \ + gstvaapiwindow_wayland.c \ + $(NULL) + +libgstvaapi_wayland_source_h = \ + gstvaapidisplay_wayland.h \ + gstvaapiwindow_wayland.h \ + $(NULL) + +libgstvaapi_wayland_source_priv_h = \ + gstvaapicompat.h \ + gstvaapidisplay_wayland_priv.h \ + gstvaapiutils.h \ + $(NULL) if USE_LOCAL_CODEC_PARSERS libgstvaapi_libs += \ @@ -238,38 +239,6 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) -libgstvaapi_wayland_@GST_MAJORMINOR@_la_SOURCES = \ - $(libgstvaapi_wayland_source_c) \ - $(libgstvaapi_wayland_source_priv_h) \ - $(NULL) - -libgstvaapi_wayland_@GST_MAJORMINOR@include_HEADERS = \ - $(libgstvaapi_wayland_source_h) \ - $(NULL) - -libgstvaapi_wayland_@GST_MAJORMINOR@includedir = \ - $(libgstvaapi_includedir) - -libgstvaapi_wayland_@GST_MAJORMINOR@_la_CFLAGS = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - $(GLIB_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(WAYLAND_CFLAGS) \ - $(LIBVA_WAYLAND_CFLAGS) \ - $(NULL) - -libgstvaapi_wayland_@GST_MAJORMINOR@_la_LIBADD = \ - $(GLIB_LIBS) \ - $(WAYLAND_LIBS) \ - $(LIBVA_WAYLAND_LIBS) \ - libgstvaapi-@GST_MAJORMINOR@.la \ - $(NULL) - -libgstvaapi_wayland_@GST_MAJORMINOR@_la_LDFLAGS = \ - $(GST_ALL_LDFLAGS) \ - $(NULL) - libgstvaapi_glx_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_glx_source_c) \ $(libgstvaapi_glx_source_priv_h) \ @@ -302,5 +271,37 @@ libgstvaapi_glx_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) +libgstvaapi_wayland_@GST_MAJORMINOR@_la_SOURCES = \ + $(libgstvaapi_wayland_source_c) \ + $(libgstvaapi_wayland_source_priv_h) \ + $(NULL) + +libgstvaapi_wayland_@GST_MAJORMINOR@include_HEADERS = \ + $(libgstvaapi_wayland_source_h) \ + $(NULL) + +libgstvaapi_wayland_@GST_MAJORMINOR@includedir = \ + $(libgstvaapi_includedir) + +libgstvaapi_wayland_@GST_MAJORMINOR@_la_CFLAGS = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + $(GLIB_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(WAYLAND_CFLAGS) \ + $(LIBVA_WAYLAND_CFLAGS) \ + $(NULL) + +libgstvaapi_wayland_@GST_MAJORMINOR@_la_LIBADD = \ + $(GLIB_LIBS) \ + $(WAYLAND_LIBS) \ + $(LIBVA_WAYLAND_LIBS) \ + libgstvaapi-@GST_MAJORMINOR@.la \ + $(NULL) + +libgstvaapi_wayland_@GST_MAJORMINOR@_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(NULL) + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in From 657f0a4a6f76e121043d022c0f8be1cfdb4834d9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 1 Aug 2012 15:44:02 +0200 Subject: [PATCH 0772/3781] Add initial support for VA/DRM. --- NEWS | 1 + configure.ac | 38 +- debian.upstream/Makefile.am | 3 + debian.upstream/control.in | 9 + debian.upstream/libgstvaapi-drm.install.in | 1 + gst-libs/gst/vaapi/Makefile.am | 55 ++ gst-libs/gst/vaapi/gstvaapidisplay.c | 4 + gst-libs/gst/vaapi/gstvaapidisplay.h | 2 + gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 532 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay_drm.h | 97 ++++ gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h | 55 ++ gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 161 ++++++ gst-libs/gst/vaapi/gstvaapiwindow_drm.h | 85 +++ pkgconfig/Makefile.am | 4 + pkgconfig/gstreamer-vaapi-drm.pc.in | 12 + 15 files changed, 1058 insertions(+), 1 deletion(-) create mode 100644 debian.upstream/libgstvaapi-drm.install.in create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_drm.c create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_drm.h create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_drm.c create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_drm.h create mode 100644 pkgconfig/gstreamer-vaapi-drm.pc.in diff --git a/NEWS b/NEWS index 39e6572862..2ad1dbe6c0 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Copyright (C) 2011 Collabora Version 0.4.0 - DD.Aug.2012 * Add support for Wayland +* Add support for headless pipelines (VA/DRM API) * Drop FFmpeg-based decoders Version 0.3.7 - 26.Jun.2012 diff --git a/configure.ac b/configure.ac index 0f696ddf52..8138ccc312 100644 --- a/configure.ac +++ b/configure.ac @@ -43,11 +43,13 @@ m4_define([gst_plugins_bad_version], # VA-API minimum version number m4_define([va_api_version], [0.30.4]) +m4_define([va_api_drm_version], [0.34.0]) m4_define([va_api_x11_version], [0.31.0]) m4_define([va_api_glx_version], [0.32.0]) m4_define([va_api_wld_version], [0.34.0]) # libva package version number +m4_define([libva_drm_package_version], [1.2.0]) m4_define([libva_x11_package_version], [1.0.3]) m4_define([libva_glx_package_version], [1.0.9]) m4_define([libva_wld_package_version], [1.2.0]) @@ -102,6 +104,11 @@ AC_PROG_CC AM_PROG_CC_C_O AC_PROG_LIBTOOL +AC_ARG_ENABLE(drm, + AS_HELP_STRING([--enable-drm], + [enable DRM backend @<:@default=yes@:>@]), + [], [enable_drm="yes"]) + AC_ARG_ENABLE(x11, AS_HELP_STRING([--enable-x11], [enable X11 output @<:@default=yes@:>@]), @@ -276,6 +283,20 @@ dnl --------------------------------------------------------------------------- dnl -- Renderers -- dnl --------------------------------------------------------------------------- +dnl Check for DRM/libudev +USE_DRM=0 +if test "$enable_drm" = "yes"; then + PKG_CHECK_MODULES(DRM, [libdrm], [USE_DRM=1], [USE_DRM=0]) + PKG_CHECK_MODULES(UDEV, [libudev], [:], [USE_DRM=0]) + + if test $USE_DRM -eq 1; then + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $DRM_CFLAGS" + AC_CHECK_HEADERS([drm_fourcc.h], [:], [USE_DRM=0]) + CPPFLAGS="$saved_CPPFLAGS" + fi +fi + dnl Check for X11 USE_X11=0 if test "$enable_x11" = "yes"; then @@ -355,6 +376,12 @@ VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2` VA_MICRO_VERSION=`echo "$VA_VERSION" | cut -d'.' -f3` VA_VERSION_STR="$VA_VERSION" +dnl VA/DRM API +if test "$enable_drm" = "yes"; then + PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= va_api_drm_version], + [:], [USE_DRM=0]) +fi + dnl VA/X11 API HAVE_VA_X11=0 LIBVA_X11_PKGNAME="libva-x11" @@ -412,7 +439,7 @@ dnl --------------------------------------------------------------------------- dnl -- Generate files and summary -- dnl --------------------------------------------------------------------------- -case ":$USE_X11:$USE_GLX:$USE_WAYLAND:" in +case ":$USE_X11:$USE_GLX:$USE_WAYLAND:$USE_DRM:" in *:1:*) ;; *) @@ -424,6 +451,10 @@ AC_DEFINE_UNQUOTED(USE_JPEG_DECODER, $USE_JPEG_DECODER, [Defined to 1 if JPEG decoder is used]) AM_CONDITIONAL(USE_JPEG_DECODER, test $USE_JPEG_DECODER -eq 1) +AC_DEFINE_UNQUOTED(USE_DRM, $USE_DRM, + [Defined to 1 if DRM is enabled]) +AM_CONDITIONAL(USE_DRM, test $USE_DRM -eq 1) + AC_DEFINE_UNQUOTED(USE_X11, $USE_X11, [Defined to 1 if X11 is enabled]) AM_CONDITIONAL(USE_X11, test $USE_X11 -eq 1) @@ -451,6 +482,8 @@ debian.upstream/gstreamer-vaapi.install.in debian.upstream/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi.install.in debian.upstream/libgstvaapi-dev.install + debian.upstream/libgstvaapi-drm-$GST_VAAPI_MAJOR_VERSION.install:\ +debian.upstream/libgstvaapi-drm.install.in debian.upstream/libgstvaapi-glx-$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi-glx.install.in debian.upstream/libgstvaapi-wayland-$GST_VAAPI_MAJOR_VERSION.install:\ @@ -472,6 +505,8 @@ debian.upstream/libgstvaapi-x11.install.in pkgconfig/Makefile pkgconfig/gstreamer-vaapi-$GST_MAJORMINOR.pc:\ pkgconfig/gstreamer-vaapi.pc.in + pkgconfig/gstreamer-vaapi-drm-$GST_MAJORMINOR.pc:\ +pkgconfig/gstreamer-vaapi-drm.pc.in pkgconfig/gstreamer-vaapi-glx-$GST_MAJORMINOR.pc:\ pkgconfig/gstreamer-vaapi-glx.pc.in pkgconfig/gstreamer-vaapi-wayland-$GST_MAJORMINOR.pc:\ @@ -488,6 +523,7 @@ yesno() { } VIDEO_OUTPUTS="" +AS_IF([test $USE_DRM -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS drm"]) AS_IF([test $USE_X11 -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS x11"]) AS_IF([test $USE_GLX -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS glx"]) AS_IF([test $USE_WAYLAND -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS wayland"]) diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index cf3bc3ef67..cacc5192b2 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -21,6 +21,8 @@ DEBIANFILES = \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-dev.install.in \ libgstvaapi-dev.install \ + libgstvaapi-drm.install.in \ + libgstvaapi-drm-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-x11.install.in \ libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-glx.install.in \ @@ -37,6 +39,7 @@ DEBIANGENFILES = \ gstreamer$(GST_MAJORMINOR)-vaapi-doc.install \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-dev.install \ + libgstvaapi-drm-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-wayland-$(GST_VAAPI_MAJOR_VERSION).install \ diff --git a/debian.upstream/control.in b/debian.upstream/control.in index bd812abeed..960f72ebb7 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -49,6 +49,15 @@ Description: GStreamer libraries from the "vaapi" set . This package contains common libraries for the "vaapi" set. +Package: libgstvaapi-drm-@GST_VAAPI_MAJOR_VERSION@ +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: GStreamer libraries from the "vaapi" set + VA-API support libraries for GStreamer. + . + This package contains headless libraries for the "vaapi" set. + Package: libgstvaapi-x11-@GST_VAAPI_MAJOR_VERSION@ Section: libs Architecture: any diff --git a/debian.upstream/libgstvaapi-drm.install.in b/debian.upstream/libgstvaapi-drm.install.in new file mode 100644 index 0000000000..de8b898c1b --- /dev/null +++ b/debian.upstream/libgstvaapi-drm.install.in @@ -0,0 +1 @@ +debian/tmp/usr/lib/libgstvaapi-drm-@GST_MAJORMINOR@.so.* diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index b9fc07debe..5719222f25 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -1,5 +1,9 @@ lib_LTLIBRARIES = libgstvaapi-@GST_MAJORMINOR@.la +if USE_DRM +lib_LTLIBRARIES += libgstvaapi-drm-@GST_MAJORMINOR@.la +endif + if USE_X11 lib_LTLIBRARIES += libgstvaapi-x11-@GST_MAJORMINOR@.la endif @@ -115,6 +119,23 @@ libgstvaapi_source_c += gstvaapidecoder_jpeg.c libgstvaapi_source_h += gstvaapidecoder_jpeg.h endif +libgstvaapi_drm_source_c = \ + gstvaapidisplay_drm.c \ + gstvaapiwindow_drm.c \ + gstvaapiutils.c \ + $(NULL) + +libgstvaapi_drm_source_h = \ + gstvaapidisplay_drm.h \ + gstvaapiwindow_drm.h \ + $(NULL) + +libgstvaapi_drm_source_priv_h = \ + gstvaapicompat.h \ + gstvaapidisplay_drm_priv.h \ + gstvaapiutils.h \ + $(NULL) + libgstvaapi_x11_source_c = \ gstvaapidisplay_x11.c \ gstvaapiutils.c \ @@ -207,6 +228,40 @@ libgstvaapi_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) +libgstvaapi_drm_@GST_MAJORMINOR@_la_SOURCES = \ + $(libgstvaapi_drm_source_c) \ + $(libgstvaapi_drm_source_priv_h) \ + $(NULL) + +libgstvaapi_drm_@GST_MAJORMINOR@include_HEADERS = \ + $(libgstvaapi_drm_source_h) \ + $(NULL) + +libgstvaapi_drm_@GST_MAJORMINOR@includedir = \ + $(libgstvaapi_includedir) + +libgstvaapi_drm_@GST_MAJORMINOR@_la_CFLAGS = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + $(GLIB_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(UDEV_CFLAGS) \ + $(DRM_CFLAGS) \ + $(LIBVA_DRM_CFLAGS) \ + $(NULL) + +libgstvaapi_drm_@GST_MAJORMINOR@_la_LIBADD = \ + $(GLIB_LIBS) \ + $(UDEV_LIBS) \ + $(DRM_LIBS) \ + $(LIBVA_DRM_LIBS) \ + libgstvaapi-@GST_MAJORMINOR@.la \ + $(NULL) + +libgstvaapi_drm_@GST_MAJORMINOR@_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(NULL) + libgstvaapi_x11_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_x11_source_c) \ $(libgstvaapi_x11_source_priv_h) \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 7238518fc2..6f9c75f428 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -101,6 +101,10 @@ gst_vaapi_display_type_get_type(void) #if USE_WAYLAND { GST_VAAPI_DISPLAY_TYPE_WAYLAND, "VA/Wayland display", "wayland" }, +#endif +#if USE_DRM + { GST_VAAPI_DISPLAY_TYPE_DRM, + "VA/DRM display", "drm" }, #endif { 0, NULL, NULL }, }; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index d8fa9a38e4..2b826665b0 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -66,12 +66,14 @@ typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; * @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. */ enum _GstVaapiDisplayType { 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, }; #define GST_VAAPI_TYPE_DISPLAY_TYPE \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c new file mode 100644 index 0000000000..6a1d148272 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -0,0 +1,532 @@ +/* + * gstvaapidisplay_drm.c - VA/DRM display abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * 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 + */ + +#include "sysdeps.h" +#include +#include +#include +#include +#include +#include +#include "gstvaapiutils.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapidisplay_drm.h" +#include "gstvaapidisplay_drm_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiDisplayDRM, + gst_vaapi_display_drm, + GST_VAAPI_TYPE_DISPLAY); + +enum { + PROP_0, + + PROP_DEVICE_PATH, + PROP_DRM_DEVICE +}; + +#define NAME_PREFIX "DRM:" +#define NAME_PREFIX_LENGTH 4 + +static inline gboolean +is_device_path(const gchar *device_path) +{ + return strncmp(device_path, NAME_PREFIX, NAME_PREFIX_LENGTH) == 0; +} + +static gboolean +compare_device_path(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const gchar *cached_name = a; + const gchar *tested_name = b; + + if (!cached_name || !is_device_path(cached_name)) + return FALSE; + g_return_val_if_fail(tested_name && is_device_path(tested_name), FALSE); + + cached_name += NAME_PREFIX_LENGTH; + tested_name += NAME_PREFIX_LENGTH; + return strcmp(cached_name, tested_name) == 0; +} + +static void +gst_vaapi_display_drm_finalize(GObject *object) +{ + G_OBJECT_CLASS(gst_vaapi_display_drm_parent_class)->finalize(object); +} + +/* Get default device path. Actually, the first match in the DRM subsystem */ +static const gchar * +get_default_device_path(gpointer ptr) +{ + GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(ptr); + GstVaapiDisplayDRMPrivate * const priv = display->priv; + const gchar *syspath, *devpath; + struct udev *udev = NULL; + struct udev_device *device, *parent; + struct udev_enumerate *e = NULL; + struct udev_list_entry *l; + 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"); + 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); + if (strcmp(udev_device_get_subsystem(parent), "pci") != 0) { + 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; + } + + priv->device_path_default = g_strdup(devpath); + close(fd); + udev_device_unref(device); + 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(gpointer ptr) +{ + GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(ptr); + const gchar *device_path = display->priv->device_path; + + if (!device_path) + return NULL; + + g_return_val_if_fail(is_device_path(device_path), NULL); + + device_path += NAME_PREFIX_LENGTH; + if (*device_path == '\0') + return NULL; + return device_path; +} + +/* Mangle device path with our prefix */ +static void +set_device_path(GstVaapiDisplayDRM *display, const gchar *device_path) +{ + GstVaapiDisplayDRMPrivate * const priv = display->priv; + + g_free(priv->device_path); + priv->device_path = NULL; + + if (!device_path) { + device_path = get_default_device_path(display); + if (!device_path) + return; + } + priv->device_path = g_strdup_printf("%s%s", NAME_PREFIX, device_path); +} + +/* Set device path from file descriptor */ +static void +set_device_path_from_fd(GstVaapiDisplayDRM *display, gint drm_device) +{ + GstVaapiDisplayDRMPrivate * const priv = display->priv; + const gchar *busid, *path, *str; + gsize busid_length, path_length; + struct udev *udev = NULL; + struct udev_device *device; + struct udev_enumerate *e = NULL; + struct udev_list_entry *l; + + g_free(priv->device_path); + priv->device_path = NULL; + + if (drm_device < 0) + return; + + busid = drmGetBusid(drm_device); + if (!busid) + return; + if (strncmp(busid, "pci:", 4) != 0) + return; + busid += 4; + busid_length = strlen(busid); + + udev = udev_new(); + if (!udev) + goto end; + + e = udev_enumerate_new(udev); + if (!e) + goto end; + + udev_enumerate_add_match_subsystem(e, "drm"); + udev_enumerate_scan_devices(e); + udev_list_entry_foreach(l, udev_enumerate_get_list_entry(e)) { + path = udev_list_entry_get_name(l); + str = strstr(path, busid); + if (!str || str <= path || str[-1] != '/') + continue; + + path_length = strlen(path); + if (str + busid_length >= path + path_length) + continue; + if (strncmp(&str[busid_length], "/drm/card", 9) != 0) + continue; + + device = udev_device_new_from_syspath(udev, path); + if (!device) + continue; + + path = udev_device_get_devnode(device); + priv->device_path = g_strdup_printf("%s%s", NAME_PREFIX, path); + udev_device_unref(device); + break; + } + +end: + if (e) + udev_enumerate_unref(e); + if (udev) + udev_unref(udev); +} + +static void +gst_vaapi_display_drm_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); + + switch (prop_id) { + case PROP_DEVICE_PATH: + set_device_path(display, g_value_get_string(value)); + break; + case PROP_DRM_DEVICE: + display->priv->drm_device = g_value_get_int(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_display_drm_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); + + switch (prop_id) { + case PROP_DEVICE_PATH: + g_value_set_string(value, get_device_path(display)); + break; + case PROP_DRM_DEVICE: + g_value_set_int(value, display->priv->drm_device); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_display_drm_constructed(GObject *object) +{ + GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); + GstVaapiDisplayDRMPrivate * const priv = display->priv; + GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache(); + const GstVaapiDisplayInfo *info; + GObjectClass *parent_class; + + priv->create_display = priv->drm_device < 0; + + /* Don't create DRM display if there is one in the cache already */ + if (priv->create_display) { + info = gst_vaapi_display_cache_lookup_by_name( + cache, + priv->device_path, + compare_device_path, NULL + ); + if (info) { + priv->drm_device = GPOINTER_TO_INT(info->native_display); + priv->create_display = FALSE; + } + } + + /* Reset device-path if the user provided his own DRM display */ + if (!priv->create_display) + set_device_path_from_fd(display, priv->drm_device); + + parent_class = G_OBJECT_CLASS(gst_vaapi_display_drm_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + +static gboolean +gst_vaapi_display_drm_open_display(GstVaapiDisplay *display) +{ + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM(display)->priv; + + if (priv->create_display) { + const gchar *device_path = get_device_path(display); + if (!device_path) + return FALSE; + priv->drm_device = open(device_path, O_RDWR|O_CLOEXEC); + if (priv->drm_device < 0) + return FALSE; + } + if (priv->drm_device < 0) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_display_drm_close_display(GstVaapiDisplay *display) +{ + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM(display)->priv; + + if (priv->drm_device >= 0) { + if (priv->create_display) + close(priv->drm_device); + priv->drm_device = -1; + } + + if (priv->device_path) { + g_free(priv->device_path); + priv->device_path = NULL; + } + + if (priv->device_path_default) { + g_free(priv->device_path_default); + priv->device_path_default = NULL; + } +} + +static gboolean +gst_vaapi_display_drm_get_display_info( + GstVaapiDisplay *display, + GstVaapiDisplayInfo *info +) +{ + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM(display)->priv; + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *cached_info; + + /* Return any cached info even if child has its own VA display */ + cache = gst_vaapi_display_get_cache(); + if (!cache) + return FALSE; + cached_info = gst_vaapi_display_cache_lookup_by_native_display( + cache, GINT_TO_POINTER(priv->drm_device)); + if (cached_info) { + *info = *cached_info; + return TRUE; + } + + /* Otherwise, create VA display if there is none already */ + 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; + info->display_type = GST_VAAPI_DISPLAY_TYPE_DRM; + } + return TRUE; +} + +static void +gst_vaapi_display_drm_class_init(GstVaapiDisplayDRMClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiDisplayDRMPrivate)); + + object_class->finalize = gst_vaapi_display_drm_finalize; + object_class->set_property = gst_vaapi_display_drm_set_property; + object_class->get_property = gst_vaapi_display_drm_get_property; + object_class->constructed = gst_vaapi_display_drm_constructed; + + 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; + + /** + * GstVaapiDisplayDRM:drm-device: + * + * The DRM device (file descriptor). + */ + g_object_class_install_property + (object_class, + PROP_DRM_DEVICE, + g_param_spec_int("drm-device", + "DRM device", + "DRM device", + -1, G_MAXINT32, -1, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + /** + * GstVaapiDisplayDRM:device-path: + * + * The DRM device path. + */ + g_object_class_install_property + (object_class, + PROP_DEVICE_PATH, + g_param_spec_string("device-path", + "DRM device path", + "DRM device path", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_display_drm_init(GstVaapiDisplayDRM *display) +{ + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_GET_PRIVATE(display); + + display->priv = priv; + priv->device_path_default = NULL; + priv->device_path = NULL; + priv->drm_device = -1; + priv->create_display = TRUE; +} + +/** + * 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) +{ + return g_object_new(GST_VAAPI_TYPE_DISPLAY_DRM, + "device-path", device_path, + NULL); +} + +/** + * 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) +{ + g_return_val_if_fail(device >= 0, NULL); + + return g_object_new(GST_VAAPI_TYPE_DISPLAY_DRM, + "drm-device", device, + NULL); +} + +/** + * 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 display->priv->drm_device; +} + +/** + * 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 display->priv->device_path; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h new file mode 100644 index 0000000000..fad0d530c1 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h @@ -0,0 +1,97 @@ +/* + * gstvaapidisplay_drm.h - VA/DRM display abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DISPLAY_DRM \ + (gst_vaapi_display_drm_get_type()) + +#define GST_VAAPI_DISPLAY_DRM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DISPLAY_DRM, \ + GstVaapiDisplayDRM)) + +#define GST_VAAPI_DISPLAY_DRM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DISPLAY_DRM, \ + GstVaapiDisplayDRMClass)) + +#define GST_VAAPI_IS_DISPLAY_DRM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_DRM)) + +#define GST_VAAPI_IS_DISPLAY_DRM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_DRM)) + +#define GST_VAAPI_DISPLAY_DRM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DISPLAY_DRM, \ + GstVaapiDisplayDRMClass)) + +typedef struct _GstVaapiDisplayDRM GstVaapiDisplayDRM; +typedef struct _GstVaapiDisplayDRMPrivate GstVaapiDisplayDRMPrivate; +typedef struct _GstVaapiDisplayDRMClass GstVaapiDisplayDRMClass; + +/** + * 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; +}; + +GType +gst_vaapi_display_drm_get_type(void) G_GNUC_CONST; + +GstVaapiDisplay * +gst_vaapi_display_drm_new(const gchar *device_path); + +GstVaapiDisplay * +gst_vaapi_display_drm_new_with_device(gint device); + +gint +gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display); + +const gchar * +gst_vaapi_display_drm_get_device_path(GstVaapiDisplayDRM *display); + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_DRM_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h new file mode 100644 index 0000000000..f6211a73ad --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h @@ -0,0 +1,55 @@ +/* + * gstvaapidisplay_drm_priv.h - Internal VA/DRM interface + * + * Copyright (C) 2012 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_DISPLAY_DRM_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DISPLAY_DRM, \ + GstVaapiDisplayDRMPrivate)) + +#define GST_VAAPI_DISPLAY_DRM_CAST(display) ((GstVaapiDisplayDRM *)(display)) + +/** + * 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_CAST(display)->priv->drm_device + +struct _GstVaapiDisplayDRMPrivate { + gchar *device_path_default; + gchar *device_path; + gint drm_device; + guint create_display : 1; +}; + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_DRM_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c new file mode 100644 index 0000000000..6303480e65 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -0,0 +1,161 @@ +/* + * gstvaapiwindow_drm.c - VA/DRM window abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * 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:gstvaapiwindow_drm + * @short_description: VA/DRM dummy window abstraction + */ + +#include "sysdeps.h" +#include "gstvaapiwindow_drm.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiWindowDRM, + gst_vaapi_window_drm, + GST_VAAPI_TYPE_WINDOW); + +static gboolean +gst_vaapi_window_drm_show(GstVaapiWindow *window) +{ + return TRUE; +} + +static gboolean +gst_vaapi_window_drm_hide(GstVaapiWindow *window) +{ + return TRUE; +} + +static gboolean +gst_vaapi_window_drm_create( + GstVaapiWindow *window, + guint *width, + guint *height +) +{ + return TRUE; +} + +static void +gst_vaapi_window_drm_destroy(GstVaapiWindow * window) +{ +} + +static gboolean +gst_vaapi_window_drm_resize( + GstVaapiWindow * window, + guint width, + guint height +) +{ + return TRUE; +} + +static gboolean +gst_vaapi_window_drm_render( + GstVaapiWindow *window, + GstVaapiSurface *surface, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect, + guint flags +) +{ + return TRUE; +} + +static void +gst_vaapi_window_drm_finalize(GObject *object) +{ + G_OBJECT_CLASS(gst_vaapi_window_drm_parent_class)->finalize(object); +} + +static void +gst_vaapi_window_drm_constructed(GObject *object) +{ + GObjectClass *parent_class; + + parent_class = G_OBJECT_CLASS(gst_vaapi_window_drm_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + +static void +gst_vaapi_window_drm_class_init(GstVaapiWindowDRMClass * klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiWindowClass * const window_class = GST_VAAPI_WINDOW_CLASS(klass); + + object_class->finalize = gst_vaapi_window_drm_finalize; + object_class->constructed = gst_vaapi_window_drm_constructed; + + window_class->create = gst_vaapi_window_drm_create; + window_class->destroy = gst_vaapi_window_drm_destroy; + window_class->show = gst_vaapi_window_drm_show; + window_class->hide = gst_vaapi_window_drm_hide; + window_class->render = gst_vaapi_window_drm_render; + window_class->resize = gst_vaapi_window_drm_resize; +} + +static void +gst_vaapi_window_drm_init(GstVaapiWindowDRM * window) +{ +} + +/** + * gst_vaapi_window_drm_new: + * @display: a #GstVaapiDisplay + * @width: the requested window width, in pixels (unused) + * @height: the requested windo height, in pixels (unused) + * + * Creates a dummy window. The window will be attached to the @display. + * All rendering functions will return success since VA/DRM is a + * renderless API. + * + * Note: this dummy window object is only necessary to fulfill cases + * where the client application wants to automatically determine the + * best display to use for the current system. As such, it provides + * utility functions with the same API (function arguments) to help + * implement uniform function tables. + * + * Return value: the newly allocated #GstVaapiWindow object + */ +GstVaapiWindow * +gst_vaapi_window_drm_new( + GstVaapiDisplay *display, + guint width, + guint height +) +{ + GST_DEBUG("new window, size %ux%u", width, height); + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(height > 0, NULL); + + return g_object_new(GST_VAAPI_TYPE_WINDOW_DRM, + "display", display, + "id", GST_VAAPI_ID(0), + "width", width, + "height", height, + NULL); +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h new file mode 100644 index 0000000000..47e053a31f --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h @@ -0,0 +1,85 @@ +/* + * gstvaapiwindow_drm.h - VA/DRM window abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * 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_WINDOW_DRM_H +#define GST_VAAPI_WINDOW_DRM_H + +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_WINDOW_DRM \ + (gst_vaapi_window_drm_get_type()) + +#define GST_VAAPI_WINDOW_DRM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_WINDOW_DRM, \ + GstVaapiWindowDRM)) + +#define GST_VAAPI_WINDOW_DRM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_WINDOW_DRM, \ + GstVaapiWindowDRMClass)) + +#define GST_VAAPI_IS_WINDOW_DRM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW_DRM)) + +#define GST_VAAPI_IS_WINDOW_DRM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW_DRM)) + +#define GST_VAAPI_WINDOW_DRM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_WINDOW_DRM, \ + GstVaapiWindowDRMClass)) + +typedef struct _GstVaapiWindowDRM GstVaapiWindowDRM; +typedef struct _GstVaapiWindowDRMClass GstVaapiWindowDRMClass; + +/** + * GstVaapiWindowDRM: + * + * A dummy DRM window abstraction. + */ +struct _GstVaapiWindowDRM { + /*< private >*/ + GstVaapiWindow parent_instance; +}; + +/** + * GstVaapiWindowDRMClass: + * + * A DRM window class. + */ +struct _GstVaapiWindowDRMClass { + /*< private >*/ + GstVaapiWindowClass parent_class; +}; + +GType +gst_vaapi_window_drm_get_type(void) G_GNUC_CONST; + +GstVaapiWindow * +gst_vaapi_window_drm_new(GstVaapiDisplay *display, guint width, guint height); + +G_END_DECLS + +#endif /* GST_VAAPI_WINDOW_DRM_H */ diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index 7d6741379e..04537d1776 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -1,4 +1,7 @@ pcfiles_in = gstreamer-vaapi.pc.in +if USE_DRM +pcfiles_in += gstreamer-vaapi-drm.pc.in +endif if USE_X11 pcfiles_in += gstreamer-vaapi-x11.pc.in endif @@ -12,6 +15,7 @@ endif pcfiles = $(pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc) all_pcfiles_in = gstreamer-vaapi.pc.in +all_pcfiles_in += gstreamer-vaapi-drm.pc.in all_pcfiles_in += gstreamer-vaapi-x11.pc.in all_pcfiles_in += gstreamer-vaapi-glx.pc.in all_pcfiles_in += gstreamer-vaapi-wayland.pc.in diff --git a/pkgconfig/gstreamer-vaapi-drm.pc.in b/pkgconfig/gstreamer-vaapi-drm.pc.in new file mode 100644 index 0000000000..3ebfadfc87 --- /dev/null +++ b/pkgconfig/gstreamer-vaapi-drm.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ + +Name: GStreamer VA-API (DRM) Plugins Libraries +Description: Streaming media framework, VA-API (DRM) plugins libraries +Requires: gstreamer-vaapi-@GST_MAJORMINOR@ libva-drm +Version: @VERSION@ +Libs: -L${libdir} -lgstvaapi-drm-@GST_MAJORMINOR@ +Cflags: -I${includedir} From 34a2b33c1ab9643cf81209ada648c64cd1e02b0f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 1 Aug 2012 15:44:49 +0200 Subject: [PATCH 0773/3781] tests: add support for headless decoding. --- tests/Makefile.am | 7 +++++ tests/output.c | 10 +++++++ tests/test-display.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ tests/test-windows.c | 34 ++++++++++++++++++++++ 4 files changed, 120 insertions(+) diff --git a/tests/Makefile.am b/tests/Makefile.am index 1aacdc99d3..4c8edbbc8a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -24,6 +24,13 @@ TEST_LIBS = \ $(GST_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-@GST_MAJORMINOR@.la +if USE_DRM +TEST_CFLAGS += $(LIBVA_DRM_CFLAGS) +TEST_LIBS += \ + $(LIBVA_DRM_LIBS) \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm-@GST_MAJORMINOR@.la +endif + if USE_X11 TEST_CFLAGS += $(X11_CFLAGS) TEST_LIBS += \ diff --git a/tests/output.c b/tests/output.c index d47af7d536..438c04c0d3 100644 --- a/tests/output.c +++ b/tests/output.c @@ -22,6 +22,10 @@ #include "config.h" #include #include +#if USE_DRM +# include +# include +#endif #if USE_X11 # include # include @@ -56,6 +60,12 @@ static const VideoOutputInfo g_video_outputs[] = { gst_vaapi_display_glx_new, gst_vaapi_window_glx_new }, +#endif +#if USE_DRM + { "drm", + gst_vaapi_display_drm_new, + gst_vaapi_window_drm_new + }, #endif { NULL, } }; diff --git a/tests/test-display.c b/tests/test-display.c index 2ebbed0463..f86ebb87c7 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -21,6 +21,15 @@ #include "config.h" #include +#if USE_DRM +# include +# include +# include +# include +# ifndef DRM_DEVICE_PATH +# define DRM_DEVICE_PATH "/dev/dri/card0" +# endif +#endif #if USE_X11 # include #endif @@ -155,6 +164,66 @@ main(int argc, char *argv[]) gst_init(&argc, &argv); +#if USE_DRM + g_print("#\n"); + g_print("# Create display with gst_vaapi_display_drm_new()\n"); + g_print("#\n"); + { + display = gst_vaapi_display_drm_new(NULL); + if (!display) + g_error("could not create Gst/VA display"); + + dump_caps(display); + g_object_unref(display); + } + g_print("\n"); + + g_print("#\n"); + g_print("# Create display with gst_vaapi_display_drm_new_with_device()\n"); + g_print("#\n"); + { + int drm_device; + + drm_device = open(DRM_DEVICE_PATH, O_RDWR|O_CLOEXEC); + if (drm_device < 0) + g_error("could not open DRM device"); + + display = gst_vaapi_display_drm_new_with_device(drm_device); + if (!display) + g_error("could not create Gst/VA display"); + + dump_caps(display); + g_object_unref(display); + close(drm_device); + } + g_print("\n"); + + g_print("#\n"); + g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayDRM()]\n"); + g_print("#\n"); + { + int drm_device; + VADisplay va_display; + + drm_device = open(DRM_DEVICE_PATH, O_RDWR|O_CLOEXEC); + if (drm_device < 0) + g_error("could not open DRM device"); + + va_display = vaGetDisplayDRM(drm_device); + if (!va_display) + g_error("could not create VA display"); + + display = gst_vaapi_display_new_with_display(va_display); + if (!display) + g_error("could not create Gst/VA display"); + + dump_caps(display); + g_object_unref(display); + close(drm_device); + } + g_print("\n"); +#endif + #if USE_X11 g_print("#\n"); g_print("# Create display with gst_vaapi_display_x11_new()\n"); diff --git a/tests/test-windows.c b/tests/test-windows.c index ec6c3d9b2c..8abc7842a0 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -22,6 +22,10 @@ #include "config.h" #include #include +#if USE_DRM +# include +# include +#endif #if USE_X11 # include # include @@ -97,6 +101,36 @@ main(int argc, char *argv[]) gst_init(&argc, &argv); +#if USE_DRM + display = gst_vaapi_display_drm_new(NULL); + if (!display) + g_error("could not create Gst/VA (DRM) display"); + + surface = create_test_surface(display, width, height); + if (!surface) + g_error("could not create Gst/VA surface"); + + g_print("#\n"); + g_print("# Create window with gst_vaapi_window_drm_new()\n"); + g_print("#\n"); + { + window = gst_vaapi_window_drm_new(display, win_width, win_height); + if (!window) + g_error("could not create dummy window"); + + gst_vaapi_window_show(window); + + if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) + g_error("could not render surface"); + + pause(); + g_object_unref(window); + } + + g_object_unref(surface); + g_object_unref(display); +#endif + #if USE_X11 display = gst_vaapi_display_x11_new(NULL); if (!display) From 6118e76b62e3a89144d5152ddcd31bf5f8f8ac96 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 1 Aug 2012 15:46:19 +0200 Subject: [PATCH 0774/3781] plugins: add support for headless pipelines. --- gst/vaapi/Makefile.am | 5 ++++ gst/vaapi/gstvaapipluginutil.c | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index c8940c5f3a..0c1097ca31 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -9,6 +9,11 @@ libgstvaapi_CFLAGS = \ libgstvaapi_LIBS = +if USE_DRM +libgstvaapi_LIBS += \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm-$(GST_MAJORMINOR).la +endif + if USE_X11 libgstvaapi_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 504d53a8cd..0a56893a0c 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -26,6 +26,9 @@ #endif #include #include +#if USE_DRM +# include +#endif #if USE_X11 # include #endif @@ -48,6 +51,10 @@ static const char *display_types[] = { #if USE_X11 "x11-display", "x11-display-name", +#endif +#if USE_DRM + "drm-device", + "drm-device-path", #endif NULL }; @@ -73,6 +80,11 @@ static const DisplayMap g_display_map[] = { { "glx", GST_VAAPI_DISPLAY_TYPE_GLX, gst_vaapi_display_glx_new }, +#endif +#if USE_DRM + { "drm", + GST_VAAPI_DISPLAY_TYPE_DRM, + gst_vaapi_display_drm_new }, #endif { NULL, } }; @@ -148,6 +160,20 @@ gst_vaapi_set_display( g_return_if_fail(G_VALUE_HOLDS_OBJECT(value)); dpy = g_value_dup_object(value); } +#if USE_DRM + else if (!strcmp(type, "drm-device")) { + gint device; + g_return_if_fail(G_VALUE_HOLDS_INT(value)); + device = g_value_get_int(value); + dpy = gst_vaapi_display_drm_new_with_device(device); + } + else if (!strcmp(type, "drm-device-path")) { + const gchar *device_path; + g_return_if_fail(G_VALUE_HOLDS_STRING(value)); + device_path = g_value_get_string(value); + dpy = gst_vaapi_display_drm_new(device_path); + } +#endif #if USE_X11 else if (!strcmp(type, "x11-display-name")) { g_return_if_fail(G_VALUE_HOLDS_STRING(value)); @@ -219,6 +245,24 @@ gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) } else { switch (display_type) { +#if USE_DRM + case GST_VAAPI_DISPLAY_TYPE_DRM: { + GstVaapiDisplayDRM * const drm_dpy = + GST_VAAPI_DISPLAY_DRM(display); + if (!strcmp(type, "drm-device-path")) + gst_video_context_query_set_string(query, type, + gst_vaapi_display_drm_get_device_path(drm_dpy)); +#if 0 + /* XXX: gst_video_context_query_set_int() does not exist yet */ + else if (!strcmp(type, "drm-device")) + gst_video_context_query_set_int(query, type, + gst_vaapi_display_drm_get_device(drm_dpy)); +#endif + else + res = FALSE; + break; + } +#endif #if USE_X11 #if USE_GLX case GST_VAAPI_DISPLAY_TYPE_GLX: From dfff02689c895bda679ad035e62b8bb04abf2a69 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 1 Aug 2012 15:46:35 +0200 Subject: [PATCH 0775/3781] vaapisink: handle VA/DRM API. This is not useful in practice but for raw performance evaluation when the sink is invoked with display=drm sync=false. fakesink could also be used though. --- gst/vaapi/gstvaapisink.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 7f1850652b..4611974f9d 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -35,6 +35,9 @@ #include #include #include +#if USE_DRM +# include +#endif #if USE_X11 # include # include @@ -479,6 +482,11 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) guint win_width, win_height, display_width, display_height; gint video_width, video_height, video_par_n = 1, video_par_d = 1; +#if USE_DRM + if (sink->display_type == GST_VAAPI_DISPLAY_TYPE_DRM) + return TRUE; +#endif + if (!structure) return FALSE; if (!gst_structure_get_int(structure, "width", &video_width)) @@ -744,6 +752,11 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) success = gst_vaapisink_show_frame_glx(sink, surface, flags); break; #endif +#if USE_DRM + case GST_VAAPI_DISPLAY_TYPE_DRM: + success = TRUE; + break; +#endif #if USE_X11 case GST_VAAPI_DISPLAY_TYPE_X11: success = gst_vaapisink_put_surface(sink, surface, flags); From a72d10ca0ed086f8812af8aa83a1dbe087c8789c Mon Sep 17 00:00:00 2001 From: Yan Yin Date: Tue, 31 Jul 2012 18:22:48 +0800 Subject: [PATCH 0776/3781] utils: add string_of_VADisplayAttributeType() helper. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiutils.c | 36 ++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 5 +++++ 2 files changed, 41 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 8d5aeccfef..41682a9870 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -166,6 +166,42 @@ const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) return ""; } +/* Return a string representation of a VADisplayAttributeType */ +const char * +string_of_VADisplayAttributeType(VADisplayAttribType attribute_type) +{ + switch (attribute_type) { +#define MAP(attribute_type) \ + STRCASEP(VADisplayAttrib, attribute_type) + MAP(Brightness); + MAP(Contrast); + MAP(Hue); + MAP(Saturation); + MAP(BackgroundColor); +#if !VA_CHECK_VERSION(0,34,0) + MAP(DirectSurface); +#endif + MAP(Rotation); + MAP(OutofLoopDeblock); +#if VA_CHECK_VERSION(0,31,1) && !VA_CHECK_VERSION(0,34,0) + MAP(BLEBlackMode); + MAP(BLEWhiteMode); + MAP(BlueStretch); + MAP(SkinColorCorrection); +#endif + MAP(CSCMatrix); + MAP(BlendColor); + MAP(OverlayAutoPaintColorKey); + MAP(OverlayColorKey); + MAP(RenderMode); + MAP(RenderDevice); + MAP(RenderRect); +#undef MAP + default: break; + } + return ""; +} + /** * from_GstVaapiSurfaceRenderFlags: * @flags: the #GstVaapiSurfaceRenderFlags diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 9ee74f1947..644fd584fc 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -68,6 +68,11 @@ const char *string_of_VAProfile(VAProfile profile); G_GNUC_INTERNAL const char *string_of_VAEntrypoint(VAEntrypoint entrypoint); +/* Return a string representation of a VADisplayAttributeType */ +G_GNUC_INTERNAL +const char * +string_of_VADisplayAttributeType(VADisplayAttribType attribute_type); + G_GNUC_INTERNAL guint from_GstVaapiSurfaceRenderFlags(guint flags); From 8bd3070c51b3cee9900668c38282184e71b41ed1 Mon Sep 17 00:00:00 2001 From: Yan Yin Date: Tue, 31 Jul 2012 18:24:14 +0800 Subject: [PATCH 0777/3781] display: query for supported display attributes. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidisplay.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 6f9c75f428..90d695e68f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -400,6 +400,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) GstVaapiDisplayPrivate * const priv = display->priv; GstVaapiDisplayCache *cache; gboolean has_errors = TRUE; + VADisplayAttribute *display_attrs = NULL; VAProfile *profiles = NULL; VAEntrypoint *entrypoints = NULL; VAImageFormat *formats = NULL; @@ -505,6 +506,21 @@ gst_vaapi_display_create(GstVaapiDisplay *display) } append_h263_config(priv->decoders); + /* VA display attributes */ + display_attrs = + g_new(VADisplayAttribute, vaMaxNumDisplayAttributes(priv->display)); + if (!display_attrs) + goto end; + + n = 0; /* XXX: workaround old GMA500 bug */ + status = vaQueryDisplayAttributes(priv->display, display_attrs, &n); + if (!vaapi_check_status(status, "vaQueryDisplayAttributes()")) + goto end; + + GST_DEBUG("%d display attributes", n); + for (i = 0; i < n; i++) + GST_DEBUG(" %s", string_of_VADisplayAttributeType(display_attrs[i].type)); + /* VA image formats */ formats = g_new(VAImageFormat, vaMaxNumImageFormats(priv->display)); if (!formats) @@ -552,6 +568,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) has_errors = FALSE; end: + g_free(display_attrs); g_free(profiles); g_free(entrypoints); g_free(formats); From 71e4936e5e1d1417f2df1afeac955d35063fd372 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 1 Aug 2012 18:30:27 +0200 Subject: [PATCH 0778/3781] display: drop VAProfileNone entries from debug messages. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 90d695e68f..1f82f33ebf 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -465,8 +465,14 @@ gst_vaapi_display_create(GstVaapiDisplay *display) goto end; GST_DEBUG("%d profiles", n); - for (i = 0; i < n; i++) + for (i = 0; i < n; i++) { +#if VA_CHECK_VERSION(0,34,0) + /* Introduced in VA/VPP API */ + if (profiles[i] == VAProfileNone) + continue; +#endif GST_DEBUG(" %s", string_of_VAProfile(profiles[i])); + } priv->decoders = g_array_new(FALSE, FALSE, sizeof(GstVaapiConfig)); if (!priv->decoders) From f88323857d6539cee1aa88794ddd17153048f441 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 2 Aug 2012 15:17:57 +0200 Subject: [PATCH 0779/3781] jpeg: compute default Huffman tables. ... instead of having them pre-calculated. This saves around 1.5 KB of data in the DSO but requires gst_jpeg_get_default_huffman_tables() to do more work. Though, the client application may have to call that function at most once, only. --- gst-libs/gst/codecparsers/gstjpegparser.c | 246 ++++++++++++---------- 1 file changed, 140 insertions(+), 106 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c index 49f80742f6..d4a0d19f93 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -120,112 +120,88 @@ static const GstJpegQuantTables default_quant_tables_zigzag = { }; /* *INDENT-ON* */ -/* Table K.3: typical Huffman tables for 8-bit precision luminance and chrominance */ +typedef struct _GstJpegHuffmanTableEntry GstJpegHuffmanTableEntry; +struct _GstJpegHuffmanTableEntry +{ + guint8 value; /* category */ + guint8 length; /* code length in bits */ +}; + +/* Table K.3 - Table for luminance DC coefficient differences */ +static const GstJpegHuffmanTableEntry default_luminance_dc_table[] = { + {0x00, 2}, {0x01, 3}, {0x02, 3}, {0x03, 3}, {0x04, 3}, {0x05, 3}, + {0x06, 4}, {0x07, 5}, {0x08, 6}, {0x09, 7}, {0x0a, 8}, {0x0b, 9} +}; + +/* Table K.4 - Table for chrominance DC coefficient differences */ +static const GstJpegHuffmanTableEntry default_chrominance_dc_table[] = { + {0x00, 2}, {0x01, 2}, {0x02, 2}, {0x03, 3}, {0x04, 4}, {0x05, 5}, + {0x06, 6}, {0x07, 7}, {0x08, 8}, {0x09, 9}, {0x0a, 10}, {0x0b, 11} +}; + +/* Table K.5 - Table for luminance AC coefficients */ /* *INDENT-OFF* */ -static const GstJpegHuffmanTables default_huf_tables = { - .dc_tables = { - /* DC luma */ - {{0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b}, - TRUE}, - /* DC chroma */ - {{0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b}, - TRUE}, - /* DC chroma */ - {{0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b}, - TRUE}, - {{0x0,}, - {0x0,} - } - }, - .ac_tables = { - /* AC luma */ - {{0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, - 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d}, - {0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa}, - TRUE}, - /* AC chroma */ - {{0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77}, - {0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa}, - TRUE}, - /* AC chroma */ - {{0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77}, - {0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa}, - TRUE}, - {{0x00,}, - {0x00,} - } - } +static const GstJpegHuffmanTableEntry default_luminance_ac_table[] = { + {0x00, 4}, {0x01, 2}, {0x02, 2}, {0x03, 3}, {0x04, 4}, {0x05, 5}, + {0x06, 7}, {0x07, 8}, {0x08, 10}, {0x09, 16}, {0x0a, 16}, {0x11, 4}, + {0x12, 5}, {0x13, 7}, {0x14, 9}, {0x15, 11}, {0x16, 16}, {0x17, 16}, + {0x18, 16}, {0x19, 16}, {0x1a, 16}, {0x21, 5}, {0x22, 8}, {0x23, 10}, + {0x24, 12}, {0x25, 16}, {0x26, 16}, {0x27, 16}, {0x28, 16}, {0x29, 16}, + {0x2a, 16}, {0x31, 6}, {0x32, 9}, {0x33, 12}, {0x34, 16}, {0x35, 16}, + {0x36, 16}, {0x37, 16}, {0x38, 16}, {0x39, 16}, {0x3a, 16}, {0x41, 6}, + {0x42, 10}, {0x43, 16}, {0x44, 16}, {0x45, 16}, {0x46, 16}, {0x47, 16}, + {0x48, 16}, {0x49, 16}, {0x4a, 16}, {0x51, 7}, {0x52, 11}, {0x53, 16}, + {0x54, 16}, {0x55, 16}, {0x56, 16}, {0x57, 16}, {0x58, 16}, {0x59, 16}, + {0x5a, 16}, {0x61, 7}, {0x62, 12}, {0x63, 16}, {0x64, 16}, {0x65, 16}, + {0x66, 16}, {0x67, 16}, {0x68, 16}, {0x69, 16}, {0x6a, 16}, {0x71, 8}, + {0x72, 12}, {0x73, 16}, {0x74, 16}, {0x75, 16}, {0x76, 16}, {0x77, 16}, + {0x78, 16}, {0x79, 16}, {0x7a, 16}, {0x81, 9}, {0x82, 15}, {0x83, 16}, + {0x84, 16}, {0x85, 16}, {0x86, 16}, {0x87, 16}, {0x88, 16}, {0x89, 16}, + {0x8a, 16}, {0x91, 9}, {0x92, 16}, {0x93, 16}, {0x94, 16}, {0x95, 16}, + {0x96, 16}, {0x97, 16}, {0x98, 16}, {0x99, 16}, {0x9a, 16}, {0xa1, 9}, + {0xa2, 16}, {0xa3, 16}, {0xa4, 16}, {0xa5, 16}, {0xa6, 16}, {0xa7, 16}, + {0xa8, 16}, {0xa9, 16}, {0xaa, 16}, {0xb1, 10}, {0xb2, 16}, {0xb3, 16}, + {0xb4, 16}, {0xb5, 16}, {0xb6, 16}, {0xb7, 16}, {0xb8, 16}, {0xb9, 16}, + {0xba, 16}, {0xc1, 10}, {0xc2, 16}, {0xc3, 16}, {0xc4, 16}, {0xc5, 16}, + {0xc6, 16}, {0xc7, 16}, {0xc8, 16}, {0xc9, 16}, {0xca, 16}, {0xd1, 11}, + {0xd2, 16}, {0xd3, 16}, {0xd4, 16}, {0xd5, 16}, {0xd6, 16}, {0xd7, 16}, + {0xd8, 16}, {0xd9, 16}, {0xda, 16}, {0xe1, 16}, {0xe2, 16}, {0xe3, 16}, + {0xe4, 16}, {0xe5, 16}, {0xe6, 16}, {0xe7, 16}, {0xe8, 16}, {0xe9, 16}, + {0xea, 16}, {0xf0, 11}, {0xf1, 16}, {0xf2, 16}, {0xf3, 16}, {0xf4, 16}, + {0xf5, 16}, {0xf6, 16}, {0xf7, 16}, {0xf8, 16}, {0xf9, 16}, {0xfa, 16} +}; +/* *INDENT-ON* */ + +/* Table K.6 - Table for chrominance AC coefficients */ +/* *INDENT-OFF* */ +static const GstJpegHuffmanTableEntry default_chrominance_ac_table[] = { + {0x00, 2}, {0x01, 2}, {0x02, 3}, {0x03, 4}, {0x04, 5}, {0x05, 5}, + {0x06, 6}, {0x07, 7}, {0x08, 9}, {0x09, 10}, {0x0a, 12}, {0x11, 4}, + {0x12, 6}, {0x13, 8}, {0x14, 9}, {0x15, 11}, {0x16, 12}, {0x17, 16}, + {0x18, 16}, {0x19, 16}, {0x1a, 16}, {0x21, 5}, {0x22, 8}, {0x23, 10}, + {0x24, 12}, {0x25, 15}, {0x26, 16}, {0x27, 16}, {0x28, 16}, {0x29, 16}, + {0x2a, 16}, {0x31, 5}, {0x32, 8}, {0x33, 10}, {0x34, 12}, {0x35, 16}, + {0x36, 16}, {0x37, 16}, {0x38, 16}, {0x39, 16}, {0x3a, 16}, {0x41, 6}, + {0x42, 9}, {0x43, 16}, {0x44, 16}, {0x45, 16}, {0x46, 16}, {0x47, 16}, + {0x48, 16}, {0x49, 16}, {0x4a, 16}, {0x51, 6}, {0x52, 10}, {0x53, 16}, + {0x54, 16}, {0x55, 16}, {0x56, 16}, {0x57, 16}, {0x58, 16}, {0x59, 16}, + {0x5a, 16}, {0x61, 7}, {0x62, 11}, {0x63, 16}, {0x64, 16}, {0x65, 16}, + {0x66, 16}, {0x67, 16}, {0x68, 16}, {0x69, 16}, {0x6a, 16}, {0x71, 7}, + {0x72, 11}, {0x73, 16}, {0x74, 16}, {0x75, 16}, {0x76, 16}, {0x77, 16}, + {0x78, 16}, {0x79, 16}, {0x7a, 16}, {0x81, 8}, {0x82, 16}, {0x83, 16}, + {0x84, 16}, {0x85, 16}, {0x86, 16}, {0x87, 16}, {0x88, 16}, {0x89, 16}, + {0x8a, 16}, {0x91, 9}, {0x92, 16}, {0x93, 16}, {0x94, 16}, {0x95, 16}, + {0x96, 16}, {0x97, 16}, {0x98, 16}, {0x99, 16}, {0x9a, 16}, {0xa1, 9}, + {0xa2, 16}, {0xa3, 16}, {0xa4, 16}, {0xa5, 16}, {0xa6, 16}, {0xa7, 16}, + {0xa8, 16}, {0xa9, 16}, {0xaa, 16}, {0xb1, 9}, {0xb2, 16}, {0xb3, 16}, + {0xb4, 16}, {0xb5, 16}, {0xb6, 16}, {0xb7, 16}, {0xb8, 16}, {0xb9, 16}, + {0xba, 16}, {0xc1, 9}, {0xc2, 16}, {0xc3, 16}, {0xc4, 16}, {0xc5, 16}, + {0xc6, 16}, {0xc7, 16}, {0xc8, 16}, {0xc9, 16}, {0xca, 16}, {0xd1, 11}, + {0xd2, 16}, {0xd3, 16}, {0xd4, 16}, {0xd5, 16}, {0xd6, 16}, {0xd7, 16}, + {0xd8, 16}, {0xd9, 16}, {0xda, 16}, {0xe1, 14}, {0xe2, 16}, {0xe3, 16}, + {0xe4, 16}, {0xe5, 16}, {0xe6, 16}, {0xe7, 16}, {0xe8, 16}, {0xe9, 16}, + {0xea, 16}, {0xf0, 10}, {0xf1, 15}, {0xf2, 16}, {0xf3, 16}, {0xf4, 16}, + {0xf5, 16}, {0xf6, 16}, {0xf7, 16}, {0xf8, 16}, {0xf9, 16}, {0xfa, 16} }; /* *INDENT-ON* */ @@ -463,12 +439,70 @@ gst_jpeg_parse_restart_interval (guint * interval, return TRUE; } +static int +compare_huffman_table_entry (const void *a, const void *b) +{ + const GstJpegHuffmanTableEntry *const e1 = *(GstJpegHuffmanTableEntry **) a; + const GstJpegHuffmanTableEntry *const e2 = *(GstJpegHuffmanTableEntry **) b; + + if (e1->length == e2->length) + return (gint) e1->value - (gint) e2->value; + return (gint) e1->length - (gint) e2->length; +} + +static void +build_huffman_table (GstJpegHuffmanTable * huf_table, + const GstJpegHuffmanTableEntry * entries, guint num_entries) +{ + const GstJpegHuffmanTableEntry *sorted_entries[256]; + guint i, j, n; + + g_assert (num_entries <= G_N_ELEMENTS (sorted_entries)); + + for (i = 0; i < num_entries; i++) + sorted_entries[i] = &entries[i]; + qsort (sorted_entries, num_entries, sizeof (sorted_entries[0]), + compare_huffman_table_entry); + + for (i = 0, j = 1, n = 0; i < num_entries; i++) { + const GstJpegHuffmanTableEntry *const e = sorted_entries[i]; + if (e->length != j) { + huf_table->huf_bits[j++ - 1] = n; + for (; j < e->length; j++) + huf_table->huf_bits[j - 1] = 0; + n = 0; + } + huf_table->huf_values[i] = e->value; + n++; + } + + for (; j < G_N_ELEMENTS (huf_table->huf_bits); j++) + huf_table->huf_bits[j] = 0; + for (; i < G_N_ELEMENTS (huf_table->huf_values); i++) + huf_table->huf_values[i] = 0; + huf_table->valid = TRUE; +} + void gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables * huf_tables) { g_assert (huf_tables); - memcpy (huf_tables, &default_huf_tables, sizeof (*huf_tables)); + /* Build DC tables */ + build_huffman_table (&huf_tables->dc_tables[0], default_luminance_dc_table, + G_N_ELEMENTS (default_luminance_dc_table)); + build_huffman_table (&huf_tables->dc_tables[1], default_chrominance_dc_table, + G_N_ELEMENTS (default_chrominance_dc_table)); + memcpy (&huf_tables->dc_tables[2], &huf_tables->dc_tables[1], + sizeof (huf_tables->dc_tables[2])); + + /* Build AC tables */ + build_huffman_table (&huf_tables->ac_tables[0], default_luminance_ac_table, + G_N_ELEMENTS (default_luminance_ac_table)); + build_huffman_table (&huf_tables->ac_tables[1], default_chrominance_ac_table, + G_N_ELEMENTS (default_chrominance_ac_table)); + memcpy (&huf_tables->ac_tables[2], &huf_tables->ac_tables[1], + sizeof (huf_tables->ac_tables[2])); } void From 0b3d75f14b4a275d13eefadc81ff7e1734d2fd0f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 2 Aug 2012 18:27:48 +0200 Subject: [PATCH 0780/3781] jpeg: fix default quantization tables. Two elements in the luminance quantization table were wrong. So, gst_jpeg_get_default_quantization_tables() now reconstructs tables in zig-zag order from the standard ones (Tables K.1 and K.2). --- gst-libs/gst/codecparsers/gstjpegparser.c | 89 ++++++++++++++--------- 1 file changed, 55 insertions(+), 34 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c index d4a0d19f93..ca597ad6cb 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -83,40 +83,45 @@ ensure_debug_category (void) } G_STMT_END -/* CCITT T.81, Annex K.1 Quantization tables for luminance and chrominance components */ -/* only for 8-bit per sample image */ +/* Table used to address an 8x8 matrix in zig-zag order */ /* *INDENT-OFF* */ -static const GstJpegQuantTables default_quant_tables_zigzag = { - .quant_tables = { - /* luma */ - {0, {0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, - 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, - 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, - 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, - 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, - 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, - 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, - 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63}, TRUE}, - /* chroma */ - {0, {0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63}, TRUE}, - /* chroma */ - {0, {0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63}, TRUE}, - {0,} - } +static const guint8 zigzag_index[64] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; +/* *INDENT-ON* */ + +/* Table K.1 - Luminance quantization table */ +/* *INDENT-OFF* */ +static const guint8 default_luminance_quant_table[64] = { + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99 +}; +/* *INDENT-ON* */ + +/* Table K.2 - Chrominance quantization table */ +/* *INDENT-OFF* */ +static const guint8 default_chrominance_quant_table[64] = { + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 }; /* *INDENT-ON* */ @@ -505,12 +510,28 @@ gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables * huf_tables) sizeof (huf_tables->ac_tables[2])); } +static void +build_quant_table (GstJpegQuantTable * quant_table, const guint8 values[64]) +{ + guint i; + + for (i = 0; i < 64; i++) + quant_table->quant_table[i] = values[zigzag_index[i]]; + quant_table->quant_precision = 0; /* Pq = 0 (8-bit precision) */ + quant_table->valid = TRUE; +} + void gst_jpeg_get_default_quantization_tables (GstJpegQuantTables * quant_tables) { g_assert (quant_tables); - memcpy (quant_tables, &default_quant_tables_zigzag, sizeof (*quant_tables)); + build_quant_table (&quant_tables->quant_tables[0], + default_luminance_quant_table); + build_quant_table (&quant_tables->quant_tables[1], + default_chrominance_quant_table); + build_quant_table (&quant_tables->quant_tables[2], + default_chrominance_quant_table); } gboolean From a10ee527c7dd0988f81a7878dfd55520899fbd09 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 6 Aug 2012 19:21:03 +0200 Subject: [PATCH 0781/3781] wayland: handle de-interlacing flags. VA/Wayland API was updated to allow flags for bob deinterlacing. More elaborated filters will require a complete VA/VPP pipeline. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 867c37cc80..5925fe4f1b 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -195,7 +195,7 @@ gst_vaapi_window_wayland_render( struct wl_display * const wl_display = GST_VAAPI_OBJECT_WL_DISPLAY(window); struct wl_buffer *buffer; struct wl_callback *callback; - guint width, height; + guint width, height, va_flags; VASurfaceID surface_id; VAStatus status; @@ -224,11 +224,23 @@ gst_vaapi_window_wayland_render( if (priv->redraw_pending) wl_display_iterate(wl_display, WL_DISPLAY_READABLE); + /* XXX: use VA/VPP for other filters */ + va_flags = from_GstVaapiSurfaceRenderFlags(flags); status = vaGetSurfaceBufferWl( GST_VAAPI_DISPLAY_VADISPLAY(display), surface_id, + va_flags & (VA_TOP_FIELD|VA_BOTTOM_FIELD), &buffer ); + if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED) { + /* XXX: de-interlacing flags not supported, try with VPP? */ + status = vaGetSurfaceBufferWl( + GST_VAAPI_DISPLAY_VADISPLAY(display), + surface_id, + VA_FRAME_PICTURE, + &buffer + ); + } if (!vaapi_check_status(status, "vaGetSurfaceBufferWl()")) return FALSE; From 5157a019427a73bc592cd1a155bb4adfbbecef8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Wed, 8 Aug 2012 12:50:41 +0900 Subject: [PATCH 0782/3781] decoder: use g_object_notify_by_pspec(). Use g_object_notify_by_pspec() instead of g_object_notify() so that to avoid a property name lookup. i.e. this makes notifications faster to the `vaapidecode' element. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index d47bea6a63..a1af8304f9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -42,8 +42,12 @@ enum { PROP_DISPLAY, PROP_CAPS, + + N_PROPERTIES }; +static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; + static void destroy_buffer(GstBuffer *buffer) { @@ -311,22 +315,20 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass) * * The #GstVaapiDisplay this decoder is bound to. */ - g_object_class_install_property - (object_class, - PROP_DISPLAY, + g_properties[PROP_DISPLAY] = g_param_spec_object("display", "Display", "The GstVaapiDisplay this decoder is bound to", GST_VAAPI_TYPE_DISPLAY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property - (object_class, - PROP_CAPS, + g_properties[PROP_CAPS] = g_param_spec_pointer("caps", "Decoder caps", "The decoder caps", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties(object_class, N_PROPERTIES, g_properties); } static void @@ -455,7 +457,7 @@ gst_vaapi_decoder_set_picture_size( } if (size_changed) - g_object_notify(G_OBJECT(decoder), "caps"); + g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); } void @@ -479,7 +481,7 @@ gst_vaapi_decoder_set_framerate( "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL ); - g_object_notify(G_OBJECT(decoder), "caps"); + g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); } } @@ -504,7 +506,7 @@ gst_vaapi_decoder_set_pixel_aspect_ratio( "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL ); - g_object_notify(G_OBJECT(decoder), "caps"); + g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); } } @@ -521,7 +523,7 @@ gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced) "interlaced", G_TYPE_BOOLEAN, interlaced, NULL ); - g_object_notify(G_OBJECT(decoder), "caps"); + g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); } } From 749fab61b91a2a90ec2369684b2976eea3d44fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Thu, 28 Jun 2012 00:22:03 +0900 Subject: [PATCH 0783/3781] configure: use new libtool syntax. This now requires libtool >= 2.2 to regenerate the configure script. Signed-off-by: Gwenole Beauchesne --- configure.ac | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 8138ccc312..1f98001292 100644 --- a/configure.ac +++ b/configure.ac @@ -102,7 +102,10 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [ dnl Check for tools AC_PROG_CC AM_PROG_CC_C_O -AC_PROG_LIBTOOL + +dnl Initialize libtool +LT_PREREQ([2.2]) +LT_INIT AC_ARG_ENABLE(drm, AS_HELP_STRING([--enable-drm], From a8636b4310c9ea8c72b7a5efbc04c43df606b937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Thu, 28 Jun 2012 01:08:03 +0900 Subject: [PATCH 0784/3781] autogen: fix configure script generation when srcdir != builddir. This patch allows for regenerating the configure script from a build directory that is not the actual source directory. Signed-off-by: Gwenole Beauchesne --- autogen.sh | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/autogen.sh b/autogen.sh index 3032585dc2..920e77e963 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,16 +1,17 @@ #!/bin/sh -srcdir=`dirname $0` -test -z "$srcdir" && srcdir=. +PROJECT="gstreamer-vaapi" -PROJECT=gstreamer-vaapi -TEST_TYPE=-d -FILE=gst-libs +test -n "$srcdir" || srcdir="`dirname \"$0\"`" +test -n "$srcdir" || srcdir=. -test $TEST_TYPE $FILE || { - echo "You must run this script in the top-level $PROJECT directory" +if ! test -f "$srcdir/configure.ac"; then + echo "Failed to find the top-level $PROJECT directory" exit 1 -} +fi + +olddir="`pwd`" +cd "$srcdir" mkdir -p m4 @@ -30,6 +31,8 @@ else autoreconf -v --install || exit $? fi +cd "$olddir" + if test -z "$NO_CONFIGURE"; then - ./configure "$@" && echo "Now type 'make' to compile $PROJECT." + $srcdir/configure "$@" && echo "Now type 'make' to compile $PROJECT." fi From 1fb8f4791f7d3e734f80b8144353ea0db220a557 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 24 Aug 2012 18:41:47 +0200 Subject: [PATCH 0785/3781] mpeg2: include start code into VA slice data buffer. Integrate the start code prefix in the slice data buffer that is submitted to the hardware. VA-API specifies that slice_data_offset is the offset to the first byte of slice data. And, for MPEG-2, slice() data begins with the slice_start_code. Some VA driver implementations (EMGD) expect this. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 38ecb33277..cabf379a49 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -504,7 +504,7 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr; - if (!gst_mpeg_video_parse_sequence_header(seq_hdr, buf, buf_size, 0)) { + if (!gst_mpeg_video_parse_sequence_header(seq_hdr, buf, buf_size, 4)) { GST_ERROR("failed to parse sequence header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -532,7 +532,7 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) GstVaapiProfile profile; guint width, height; - if (!gst_mpeg_video_parse_sequence_extension(seq_ext, buf, buf_size, 0)) { + if (!gst_mpeg_video_parse_sequence_extension(seq_ext, buf, buf_size, 4)) { GST_ERROR("failed to parse sequence-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -600,7 +600,7 @@ decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_si GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoQuantMatrixExt * const quant_matrix_ext = &priv->quant_matrix_ext; - if (!gst_mpeg_video_parse_quant_matrix_extension(quant_matrix_ext, buf, buf_size, 0)) { + if (!gst_mpeg_video_parse_quant_matrix_extension(quant_matrix_ext, buf, buf_size, 4)) { GST_ERROR("failed to parse quant-matrix-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -616,7 +616,7 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) GstMpegVideoGop gop; GstClockTime pts; - if (!gst_mpeg_video_parse_gop(&gop, buf, buf_size, 0)) { + if (!gst_mpeg_video_parse_gop(&gop, buf, buf_size, 4)) { GST_ERROR("failed to parse GOP"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -676,7 +676,7 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) return status; } - if (!gst_mpeg_video_parse_picture_header(pic_hdr, buf, buf_size, 0)) { + if (!gst_mpeg_video_parse_picture_header(pic_hdr, buf, buf_size, 4)) { GST_ERROR("failed to parse picture header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -713,7 +713,7 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext; GstVaapiPicture * const picture = priv->current_picture; - if (!gst_mpeg_video_parse_picture_extension(pic_ext, buf, buf_size, 0)) { + if (!gst_mpeg_video_parse_picture_extension(pic_ext, buf, buf_size, 4)) { GST_ERROR("failed to parse picture-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -887,6 +887,7 @@ decode_slice( /* Parse slice */ gst_bit_reader_init(&br, buf, buf_size); + SKIP(&br, 32); /* slice_start_code */ if (priv->height > 2800) READ_UINT8(&br, slice_vertical_position_extension, 3); if (priv->has_seq_scalable_ext) { @@ -977,7 +978,7 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) ofs = scan_for_start_code(priv->adapter, 4, size - 4, NULL); if (ofs < 0) break; - gst_adapter_flush(priv->adapter, 4); + buffer = gst_adapter_take_buffer(priv->adapter, ofs); size -= ofs; if (ofs == 4) { @@ -989,7 +990,6 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) break; } - buffer = gst_adapter_take_buffer(priv->adapter, ofs - 4); buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); @@ -1004,7 +1004,7 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) status = decode_sequence(decoder, buf, buf_size); break; case GST_MPEG_VIDEO_PACKET_EXTENSION: { - const guchar id = buf[0] >> 4; + const guchar id = buf[4] >> 4; switch (id) { case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: status = decode_sequence_ext(decoder, buf, buf_size); From f2741a88cc77cfbb3a0989a930fb69d3d497cbcb Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 24 Aug 2012 11:36:16 +0300 Subject: [PATCH 0786/3781] jpeg: fix end-of-image (EOI) handler. decode_current_picture() was converted to return a gboolean instead of a GstVaapiDecoderStatus, so we were not getting out of the decode loop as expected, or could cause an error instead. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 5cfbe4d634..3200397245 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -540,7 +540,12 @@ decode_buffer(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; case GST_JPEG_MARKER_EOI: - status = decode_current_picture(decoder); + if (decode_current_picture(decoder)) { + /* Get out of the loop, trailing data is not needed */ + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + goto end; + } + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; break; case GST_JPEG_MARKER_DHT: status = decode_huffman_table(decoder, buf + seg.offset, seg.size); @@ -601,6 +606,7 @@ decode_buffer(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) break; } +end: return status; } From a503aaf9b9bddb4b381a500a7dff31a3fa9dd593 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 27 Aug 2012 17:02:49 +0300 Subject: [PATCH 0787/3781] display: add initial support for display attributes. The VA display attributes are mapped to properties so that to maintain the GStreamer terminology. Properties are to be identified by name, but internal functions are available to lookup the property by the actual VA display attribute type. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 88 ++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidisplay.h | 3 + gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 1 + 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 1f82f33ebf..7dc06016af 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -45,6 +45,12 @@ struct _GstVaapiConfig { GstVaapiEntrypoint entrypoint; }; +typedef struct _GstVaapiProperty GstVaapiProperty; +struct _GstVaapiProperty { + const gchar *name; + VADisplayAttribute attribute; +}; + enum { PROP_0, @@ -304,6 +310,40 @@ get_format_caps(GArray *formats) return out_caps; } +/* Find display attribute */ +static const GstVaapiProperty * +find_property(GArray *properties, const gchar *name) +{ + GstVaapiProperty *prop; + guint i; + + if (!name) + return NULL; + + for (i = 0; i < properties->len; i++) { + prop = &g_array_index(properties, GstVaapiProperty, i); + if (strcmp(prop->name, name) == 0) + return prop; + } + return NULL; +} + +#if 0 +static const GstVaapiProperty * +find_property_by_type(GArray *properties, VADisplayAttribType type) +{ + GstVaapiProperty *prop; + guint i; + + for (i = 0; i < properties->len; i++) { + prop = &g_array_index(properties, GstVaapiProperty, i); + if (prop->attribute.type == type) + return prop; + } + return NULL; +} +#endif + static void gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display) { @@ -374,6 +414,11 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) priv->subpicture_formats = NULL; } + if (priv->properties) { + g_array_free(priv->properties, TRUE); + priv->properties = NULL; + } + if (priv->display) { if (!priv->parent) vaTerminate(priv->display); @@ -523,9 +568,26 @@ gst_vaapi_display_create(GstVaapiDisplay *display) if (!vaapi_check_status(status, "vaQueryDisplayAttributes()")) goto end; + priv->properties = g_array_new(FALSE, FALSE, sizeof(GstVaapiProperty)); + if (!priv->properties) + goto end; + GST_DEBUG("%d display attributes", n); - for (i = 0; i < n; i++) - GST_DEBUG(" %s", string_of_VADisplayAttributeType(display_attrs[i].type)); + for (i = 0; i < n; i++) { + VADisplayAttribute * const attr = &display_attrs[i]; + GstVaapiProperty prop; + + GST_DEBUG(" %s", string_of_VADisplayAttributeType(attr->type)); + + switch (attr->type) { + default: + prop.attribute.flags = 0; + break; + } + if (!prop.attribute.flags) + continue; + g_array_append_val(priv->properties, prop); + } /* VA image formats */ formats = g_new(VAImageFormat, vaMaxNumImageFormats(priv->display)); @@ -755,6 +817,7 @@ gst_vaapi_display_init(GstVaapiDisplay *display) priv->encoders = NULL; priv->image_formats = NULL; priv->subpicture_formats = NULL; + priv->properties = NULL; priv->create_display = TRUE; g_static_rec_mutex_init(&priv->mutex); @@ -1153,3 +1216,24 @@ gst_vaapi_display_has_subpicture_format( return find_format(display->priv->subpicture_formats, format); } + +/** + * gst_vaapi_display_has_property: + * @display: a #GstVaapiDisplay + * @name: the property name to check + * + * Returns whether VA @display supports the requested property. The + * check is performed against the property @name. So, the client + * application may perform this check only once and cache this + * information. + * + * Return value: %TRUE if VA @display supports property @name + */ +gboolean +gst_vaapi_display_has_property(GstVaapiDisplay *display, const gchar *name) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(name, FALSE); + + return find_property(display->priv->properties, name) != NULL; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 2b826665b0..1b0ade65c8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -218,6 +218,9 @@ gst_vaapi_display_has_subpicture_format( GstVaapiImageFormat format ); +gboolean +gst_vaapi_display_has_property(GstVaapiDisplay *display, const gchar *name); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index d48cc60fd8..ac0555e3d6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -86,6 +86,7 @@ struct _GstVaapiDisplayPrivate { GArray *encoders; GArray *image_formats; GArray *subpicture_formats; + GArray *properties; guint create_display : 1; }; From a192f40ed9dceba9434823877aa04ca33865ce3a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 27 Aug 2012 18:11:37 +0300 Subject: [PATCH 0788/3781] display: add support for rendering modes. A rendering mode can be "overlay" or "texture"'ed blit. The former mode implies that a VA surface used for rendering can't be re-used right away for decoding, so the sink shall make provisions to retain the associated surface proxy until the next surface is to be displayed. The latter mode implies that the VA surface is implicitly copied to an intermediate backing store, or back buffer of a frame buffer, so the associated surface proxy can be disposed right away. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 178 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 13 ++ gst-libs/gst/vaapi/gstvaapitypes.h | 19 +++ gst-libs/gst/vaapi/gstvaapivalue.c | 22 ++++ gst-libs/gst/vaapi/gstvaapivalue.h | 13 ++ 5 files changed, 245 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 7dc06016af..8eed95d6ad 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1237,3 +1237,181 @@ gst_vaapi_display_has_property(GstVaapiDisplay *display, const gchar *name) return find_property(display->priv->properties, name) != NULL; } + +static gboolean +get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value) +{ + VADisplayAttribute attr; + VAStatus status; + + attr.type = type; + attr.flags = VA_DISPLAY_ATTRIB_GETTABLE; + status = vaGetDisplayAttributes(display->priv->display, &attr, 1); + if (!vaapi_check_status(status, "vaGetDisplayAttributes()")) + return FALSE; + *value = attr.value; + return TRUE; +} + +static gboolean +set_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint value) +{ + VADisplayAttribute attr; + VAStatus status; + + attr.type = type; + attr.value = value; + attr.flags = VA_DISPLAY_ATTRIB_SETTABLE; + status = vaSetDisplayAttributes(display->priv->display, &attr, 1); + if (!vaapi_check_status(status, "vaSetDisplayAttributes()")) + return FALSE; + return TRUE; +} + +static gboolean +get_render_mode_VADisplayAttribRenderMode( + GstVaapiDisplay *display, + GstVaapiRenderMode *pmode +) +{ + gint modes, devices; + + if (!get_attribute(display, VADisplayAttribRenderDevice, &devices)) + return FALSE; + if (!devices) + return FALSE; + if (!get_attribute(display, VADisplayAttribRenderMode, &modes)) + return FALSE; + + /* Favor "overlay" mode since it is the most restrictive one */ + if (modes & (VA_RENDER_MODE_LOCAL_OVERLAY|VA_RENDER_MODE_EXTERNAL_OVERLAY)) + *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; + else + *pmode = GST_VAAPI_RENDER_MODE_TEXTURE; + return TRUE; +} + +static gboolean +get_render_mode_VADisplayAttribDirectSurface( + GstVaapiDisplay *display, + GstVaapiRenderMode *pmode +) +{ +#if VA_CHECK_VERSION(0,34,0) + /* VADisplayAttribDirectsurface was removed in VA-API >= 0.34.0 */ + return FALSE; +#else + gint direct_surface; + + if (!get_attribute(display, VADisplayAttribDirectSurface, &direct_surface)) + return FALSE; + if (direct_surface) + *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; + else + *pmode = GST_VAAPI_RENDER_MODE_TEXTURE; + return TRUE; +#endif +} + +static gboolean +get_render_mode_default( + GstVaapiDisplay *display, + GstVaapiRenderMode *pmode +) +{ + switch (display->priv->display_type) { +#if USE_WAYLAND + case GST_VAAPI_DISPLAY_TYPE_WAYLAND: + /* wl_buffer mapped from VA surface through vaGetSurfaceBufferWl() */ + *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; + break; +#endif +#if USE_DRM + case GST_VAAPI_DISPLAY_TYPE_DRM: + /* vaGetSurfaceBufferDRM() returns the underlying DRM buffer handle */ + *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; + break; +#endif + default: + /* This includes VA/X11 and VA/GLX modes */ + *pmode = GST_VAAPI_RENDER_MODE_TEXTURE; + break; + } + return TRUE; +} + +/** + * gst_vaapi_display_get_render_mode: + * @display: a #GstVaapiDisplay + * @pmode: return location for the VA @display rendering mode + * + * Returns the current VA @display rendering mode. + * + * Return value: %TRUE if VA @display rendering mode could be determined + */ +gboolean +gst_vaapi_display_get_render_mode( + GstVaapiDisplay *display, + GstVaapiRenderMode *pmode +) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + + /* Try with render-mode attribute */ + if (get_render_mode_VADisplayAttribRenderMode(display, pmode)) + return TRUE; + + /* Try with direct-surface attribute */ + if (get_render_mode_VADisplayAttribDirectSurface(display, pmode)) + return TRUE; + + /* Default: determine from the display type */ + return get_render_mode_default(display, pmode); +} + +/** + * gst_vaapi_display_set_render_mode: + * @display: a #GstVaapiDisplay + * @mode: the #GstVaapiRenderMode to set + * + * Sets the VA @display rendering mode to the supplied @mode. This + * function returns %FALSE if the rendering mode could not be set, + * e.g. run-time switching rendering mode is not supported. + * + * Return value: %TRUE if VA @display rendering @mode could be changed + * to the requested value + */ +gboolean +gst_vaapi_display_set_render_mode( + GstVaapiDisplay *display, + GstVaapiRenderMode mode +) +{ + gint modes, devices; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + + if (!get_attribute(display, VADisplayAttribRenderDevice, &devices)) + return FALSE; + + modes = 0; + switch (mode) { + case GST_VAAPI_RENDER_MODE_OVERLAY: + if (devices & VA_RENDER_DEVICE_LOCAL) + modes |= VA_RENDER_MODE_LOCAL_OVERLAY; + if (devices & VA_RENDER_DEVICE_EXTERNAL) + modes |= VA_RENDER_MODE_EXTERNAL_OVERLAY; + break; + case GST_VAAPI_RENDER_MODE_TEXTURE: + if (devices & VA_RENDER_DEVICE_LOCAL) + modes |= VA_RENDER_MODE_LOCAL_GPU; + if (devices & VA_RENDER_DEVICE_EXTERNAL) + modes |= VA_RENDER_MODE_EXTERNAL_GPU; + break; + } + if (!modes) + return FALSE; + if (!set_attribute(display, VADisplayAttribRenderMode, modes)) + return FALSE; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 1b0ade65c8..6240e513f8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -221,6 +222,18 @@ gst_vaapi_display_has_subpicture_format( 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 +); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index a6312b1f85..241051f8c2 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -116,6 +116,25 @@ struct _GstVaapiRectangle { guint32 height; }; +/** + * GstVaapiRenderMode: + * @GST_VAAPI_RENDER_MODE_OVERLAY: in this mode, the VA display + * backend renders surfaces with an overlay engine. This means that + * the surface that is currently displayed shall not be re-used + * right away for decoding. i.e. it needs to be retained further, + * until the next surface is to be displayed. + * @GST_VAAPI_RENDER_MODE_TEXTURE: in this modem the VA display + * backend renders surfaces with a textured blit (GPU/3D engine). + * This means that the surface is copied to some intermediate + * backing store, or back buffer of a frame buffer, and is free to + * be re-used right away for decoding. + */ +typedef enum _GstVaapiRenderMode GstVaapiRenderMode; +enum _GstVaapiRenderMode { + GST_VAAPI_RENDER_MODE_OVERLAY = 1, + GST_VAAPI_RENDER_MODE_TEXTURE +}; + G_END_DECLS #endif /* GST_VAAPI_TYPES_H */ diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 112d1b4abd..703fca9cf7 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -163,3 +163,25 @@ gst_vaapi_value_set_id(GValue *value, GstVaapiID id) GST_VAAPI_VALUE_ID(value) = id; } + +/* --- GstVaapiRenderMode --- */ + +GType +gst_vaapi_render_mode_get_type(void) +{ + static GType render_mode_type = 0; + + static const GEnumValue render_modes[] = { + { GST_VAAPI_RENDER_MODE_OVERLAY, + "Overlay render mode", "overlay" }, + { GST_VAAPI_RENDER_MODE_TEXTURE, + "Textured-blit render mode", "texture" }, + { 0, NULL, NULL } + }; + + if (!render_mode_type) { + render_mode_type = + g_enum_register_static("GstVaapiRenderMode", render_modes); + } + return render_mode_type; +} diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index a5a52bec28..0c2c719ec8 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -44,6 +44,16 @@ G_BEGIN_DECLS */ #define GST_VAAPI_VALUE_HOLDS_ID(x) (G_VALUE_HOLDS((x), GST_VAAPI_TYPE_ID)) +/** + * GST_VAAPI_TYPE_RENDER_MODE: + * + * A #GstVaapiRenderMode type that represents the VA display backend + * rendering mode: overlay (2D engine) or textured-blit (3D engine). + * + * Return value: the #GType of GstVaapiRenderMode + */ +#define GST_VAAPI_TYPE_RENDER_MODE gst_vaapi_render_mode_get_type() + GType gst_vaapi_id_get_type(void) G_GNUC_CONST; @@ -53,6 +63,9 @@ gst_vaapi_value_get_id(const GValue *value); void gst_vaapi_value_set_id(GValue *value, GstVaapiID id); +GType +gst_vaapi_render_mode_get_type(void) G_GNUC_CONST; + G_END_DECLS #endif /* GST_VAAPI_VALUE_H */ From c899947e17b250a70d26332210314f31934823a3 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Wed, 22 Aug 2012 02:18:11 -0400 Subject: [PATCH 0789/3781] display: add support for rotation modes. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidisplay.c | 51 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 9 +++++ gst-libs/gst/vaapi/gstvaapitypes.h | 15 ++++++++ gst-libs/gst/vaapi/gstvaapiutils.c | 28 +++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 8 +++++ gst-libs/gst/vaapi/gstvaapivalue.c | 23 +++++++++++++ gst-libs/gst/vaapi/gstvaapivalue.h | 12 +++++++ 7 files changed, 146 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 8eed95d6ad..a212a1060b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1415,3 +1415,54 @@ gst_vaapi_display_set_render_mode( return FALSE; return TRUE; } + +/** + * gst_vaapi_display_get_rotation: + * @display: a #GstVaapiDisplay + * + * Returns the current VA @display rotation angle. If the VA driver + * does not support "rotation" display attribute, then the display is + * assumed to be un-rotated. + * + * Return value: the current #GstVaapiRotation value + */ +GstVaapiRotation +gst_vaapi_display_get_rotation(GstVaapiDisplay *display) +{ + gint value; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), GST_VAAPI_ROTATION_0); + + if (!get_attribute(display, VADisplayAttribRotation, &value)) + value = VA_ROTATION_NONE; + return to_GstVaapiRotation(value); +} + +/** + * gst_vaapi_display_set_rotation: + * @display: a #GstVaapiDisplay + * @rotation: the #GstVaapiRotation value to set + * + * Sets the VA @display rotation angle to the supplied @rotation + * value. This function returns %FALSE if the rotation angle could not + * be set, e.g. the VA driver does not allow to change the display + * rotation angle. + * + * Return value: %TRUE if VA @display rotation angle could be changed + * to the requested value + */ +gboolean +gst_vaapi_display_set_rotation( + GstVaapiDisplay *display, + GstVaapiRotation rotation +) +{ + guint value; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + + value = from_GstVaapiRotation(rotation); + if (!set_attribute(display, VADisplayAttribRotation, value)) + return FALSE; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 6240e513f8..6dac4c5f84 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -234,6 +234,15 @@ gst_vaapi_display_set_render_mode( GstVaapiRenderMode mode ); +GstVaapiRotation +gst_vaapi_display_get_rotation(GstVaapiDisplay *display); + +gboolean +gst_vaapi_display_set_rotation( + GstVaapiDisplay *display, + GstVaapiRotation rotation +); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 241051f8c2..ff5f9eb9e4 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -135,6 +135,21 @@ enum _GstVaapiRenderMode { GST_VAAPI_RENDER_MODE_TEXTURE }; +/** + * GstVaapiRotation: + * @GST_VAAPI_ROTATION_0: the VA display is not rotated. + * @GST_VAAPI_ROTATION_90: the VA display is rotated by 90°, clockwise. + * @GST_VAAPI_ROTATION_180: the VA display is rotated by 180°, clockwise. + * @GST_VAAPI_ROTATION_270: the VA display is rotated by 270°, clockwise. + */ +typedef enum _GstVaapiRotation GstVaapiRotation; +enum _GstVaapiRotation { + GST_VAAPI_ROTATION_0 = 0, + GST_VAAPI_ROTATION_90 = 90, + GST_VAAPI_ROTATION_180 = 180, + GST_VAAPI_ROTATION_270 = 270, +}; + G_END_DECLS #endif /* GST_VAAPI_TYPES_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 41682a9870..996e328cc6 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -273,3 +273,31 @@ to_GstVaapiSurfaceStatus(guint va_flags) #endif return flags; } + +/* Translate GstVaapiRotation value to VA-API rotation value */ +guint +from_GstVaapiRotation(guint value) +{ + switch (value) { + case GST_VAAPI_ROTATION_0: return VA_ROTATION_NONE; + case GST_VAAPI_ROTATION_90: return VA_ROTATION_90; + case GST_VAAPI_ROTATION_180: return VA_ROTATION_180; + case GST_VAAPI_ROTATION_270: return VA_ROTATION_270; + } + GST_ERROR("unsupported GstVaapiRotation value %d", value); + return VA_ROTATION_NONE; +} + +/* Translate VA-API rotation value to GstVaapiRotation value */ +guint +to_GstVaapiRotation(guint value) +{ + switch (value) { + case VA_ROTATION_NONE: return GST_VAAPI_ROTATION_0; + case VA_ROTATION_90: return GST_VAAPI_ROTATION_90; + case VA_ROTATION_180: return GST_VAAPI_ROTATION_180; + case VA_ROTATION_270: return GST_VAAPI_ROTATION_270; + } + GST_ERROR("unsupported VA-API rotation value %d", value); + return GST_VAAPI_ROTATION_0; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 644fd584fc..98d91e37e9 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -81,4 +81,12 @@ G_GNUC_INTERNAL guint to_GstVaapiSurfaceStatus(guint va_flags); +G_GNUC_INTERNAL +guint +from_GstVaapiRotation(guint value); + +G_GNUC_INTERNAL +guint +to_GstVaapiRotation(guint value); + #endif /* GST_VAAPI_UTILS_H */ diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 703fca9cf7..8461c09e95 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -185,3 +185,26 @@ gst_vaapi_render_mode_get_type(void) } return render_mode_type; } + +/* --- GstVaapiRotation --- */ + +GType +gst_vaapi_rotation_get_type(void) +{ + static GType g_type = 0; + + static const GEnumValue rotation_values[] = { + { GST_VAAPI_ROTATION_0, + "Unrotated mode", "0" }, + { GST_VAAPI_ROTATION_90, + "Rotated by 90°, clockwise", "90" }, + { GST_VAAPI_ROTATION_180, + "Rotated by 180°, clockwise", "180" }, + { GST_VAAPI_ROTATION_270, + "Rotated by 270°, clockwise", "270" }, + }; + + if (!g_type) + g_type = g_enum_register_static("GstVaapiRotation", rotation_values); + return g_type; +} diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index 0c2c719ec8..ec99f8e57e 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -54,6 +54,15 @@ G_BEGIN_DECLS */ #define GST_VAAPI_TYPE_RENDER_MODE gst_vaapi_render_mode_get_type() +/** + * GST_VAAPI_TYPE_ROTATION: + * + * A type that represents the VA display rotation. + * + * Return value: the #GType of GstVaapiRotation + */ +#define GST_VAAPI_TYPE_ROTATION gst_vaapi_rotation_get_type() + GType gst_vaapi_id_get_type(void) G_GNUC_CONST; @@ -66,6 +75,9 @@ gst_vaapi_value_set_id(GValue *value, GstVaapiID id); GType gst_vaapi_render_mode_get_type(void) G_GNUC_CONST; +GType +gst_vaapi_rotation_get_type(void) G_GNUC_CONST; + G_END_DECLS #endif /* GST_VAAPI_VALUE_H */ From 1069ce433fa37bdc80e284c21010b48e4122f6f9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 27 Aug 2012 19:00:37 +0200 Subject: [PATCH 0790/3781] display: fix gst_vaapi_display_has_property(). Append the "render-mode" and "rotation" properties, should they be supported by the underlying VA driver. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index a212a1060b..6ef4ae9b3e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -51,6 +51,10 @@ struct _GstVaapiProperty { VADisplayAttribute attribute; }; +/* XXX: export property names when the API is stable enough */ +#define GST_VAAPI_DISPLAY_PROP_RENDER_MODE "render-mode" +#define GST_VAAPI_DISPLAY_PROP_ROTATION "rotation" + enum { PROP_0, @@ -580,12 +584,24 @@ gst_vaapi_display_create(GstVaapiDisplay *display) GST_DEBUG(" %s", string_of_VADisplayAttributeType(attr->type)); switch (attr->type) { +#if !VA_CHECK_VERSION(0,34,0) + case VADisplayAttribDirectSurface: + prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; + break; +#endif + case VADisplayAttribRenderMode: + prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; + break; + case VADisplayAttribRotation: + prop.name = GST_VAAPI_DISPLAY_PROP_ROTATION; + break; default: - prop.attribute.flags = 0; + prop.name = NULL; break; } - if (!prop.attribute.flags) + if (!prop.name) continue; + prop.attribute = *attr; g_array_append_val(priv->properties, prop); } From fe4ad408dce29cfbbec20d9871b8f71cced1d5c3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 28 Aug 2012 16:24:15 +0200 Subject: [PATCH 0791/3781] display: install properties in batch. Use g_object_class_install_properties() to install GstVaapiDisplay properties. It is useful to maintain properties as GParamSpec so that to be able to raise "notify" signals by id instead of by name in the future. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 64 ++++++++++++++-------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 6ef4ae9b3e..ae52b867e1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -61,11 +61,15 @@ enum { PROP_DISPLAY, PROP_DISPLAY_TYPE, PROP_WIDTH, - PROP_HEIGHT + PROP_HEIGHT, + + N_PROPERTIES }; static GstVaapiDisplayCache *g_display_cache = NULL; +static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; + static inline GstVaapiDisplayCache * get_display_cache(void) { @@ -777,41 +781,35 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) dpy_class->lock = gst_vaapi_display_lock_default; dpy_class->unlock = gst_vaapi_display_unlock_default; - g_object_class_install_property - (object_class, - PROP_DISPLAY, - g_param_spec_pointer("display", - "VA display", - "VA display", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_properties[PROP_DISPLAY] = + g_param_spec_pointer("display", + "VA display", + "VA display", + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property - (object_class, - PROP_DISPLAY_TYPE, - g_param_spec_enum("display-type", - "VA display type", - "VA display type", - GST_VAAPI_TYPE_DISPLAY_TYPE, - GST_VAAPI_DISPLAY_TYPE_ANY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_properties[PROP_DISPLAY_TYPE] = + g_param_spec_enum("display-type", + "VA display type", + "VA display type", + GST_VAAPI_TYPE_DISPLAY_TYPE, + GST_VAAPI_DISPLAY_TYPE_ANY, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property - (object_class, - PROP_WIDTH, - g_param_spec_uint("width", - "Width", - "The display width", - 1, G_MAXUINT32, 1, - G_PARAM_READABLE)); + g_properties[PROP_WIDTH] = + g_param_spec_uint("width", + "Width", + "The display width", + 1, G_MAXUINT32, 1, + G_PARAM_READABLE); - g_object_class_install_property - (object_class, - PROP_HEIGHT, - g_param_spec_uint("height", - "height", - "The display height", - 1, G_MAXUINT32, 1, - G_PARAM_READABLE)); + g_properties[PROP_HEIGHT] = + g_param_spec_uint("height", + "height", + "The display height", + 1, G_MAXUINT32, 1, + G_PARAM_READABLE); + + g_object_class_install_properties(object_class, N_PROPERTIES, g_properties); } static void From 9c714cf7a0fdec91d79090a7e7b83073228a43c1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 28 Aug 2012 10:55:59 +0200 Subject: [PATCH 0792/3781] display: expose display attributes as GObject properties. Expose VA display "render-mode" and "rotation" attributes as standard GObject properties. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 54 +++++++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapidisplay.h | 8 +++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index ae52b867e1..7abda6d195 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -28,6 +28,7 @@ #include "sysdeps.h" #include #include "gstvaapiutils.h" +#include "gstvaapivalue.h" #include "gstvaapidisplay.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiworkarounds.h" @@ -51,9 +52,8 @@ struct _GstVaapiProperty { VADisplayAttribute attribute; }; -/* XXX: export property names when the API is stable enough */ -#define GST_VAAPI_DISPLAY_PROP_RENDER_MODE "render-mode" -#define GST_VAAPI_DISPLAY_PROP_ROTATION "rotation" +#define DEFAULT_RENDER_MODE GST_VAAPI_RENDER_MODE_TEXTURE +#define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 enum { PROP_0, @@ -62,6 +62,8 @@ enum { PROP_DISPLAY_TYPE, PROP_WIDTH, PROP_HEIGHT, + PROP_RENDER_MODE, + PROP_ROTATION, N_PROPERTIES }; @@ -713,6 +715,12 @@ gst_vaapi_display_set_property( case PROP_DISPLAY_TYPE: display->priv->display_type = g_value_get_enum(value); break; + case PROP_RENDER_MODE: + gst_vaapi_display_set_render_mode(display, g_value_get_enum(value)); + break; + case PROP_ROTATION: + gst_vaapi_display_set_rotation(display, g_value_get_enum(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -742,6 +750,16 @@ gst_vaapi_display_get_property( case PROP_HEIGHT: g_value_set_uint(value, gst_vaapi_display_get_height(display)); break; + case PROP_RENDER_MODE: { + GstVaapiRenderMode mode; + if (!gst_vaapi_display_get_render_mode(display, &mode)) + mode = DEFAULT_RENDER_MODE; + g_value_set_enum(value, mode); + break; + } + case PROP_ROTATION: + g_value_set_enum(value, gst_vaapi_display_get_rotation(display)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -809,6 +827,32 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) 1, G_MAXUINT32, 1, G_PARAM_READABLE); + /** + * GstVaapiDisplay:render-mode: + * + * The VA display rendering mode, expressed as a #GstVaapiRenderMode. + */ + g_properties[PROP_RENDER_MODE] = + g_param_spec_enum(GST_VAAPI_DISPLAY_PROP_RENDER_MODE, + "render mode", + "The display rendering mode", + GST_VAAPI_TYPE_RENDER_MODE, + DEFAULT_RENDER_MODE, + G_PARAM_READWRITE); + + /** + * GstVaapiDisplay:rotation: + * + * The VA display rotation mode, expressed as a #GstVaapiRotation. + */ + g_properties[PROP_ROTATION] = + g_param_spec_enum(GST_VAAPI_DISPLAY_PROP_ROTATION, + "rotation", + "The display rotation mode", + GST_VAAPI_TYPE_ROTATION, + DEFAULT_ROTATION, + G_PARAM_READWRITE); + g_object_class_install_properties(object_class, N_PROPERTIES, g_properties); } @@ -1348,7 +1392,7 @@ get_render_mode_default( #endif default: /* This includes VA/X11 and VA/GLX modes */ - *pmode = GST_VAAPI_RENDER_MODE_TEXTURE; + *pmode = DEFAULT_RENDER_MODE; break; } return TRUE; @@ -1445,7 +1489,7 @@ gst_vaapi_display_get_rotation(GstVaapiDisplay *display) { gint value; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), GST_VAAPI_ROTATION_0); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), DEFAULT_ROTATION); if (!get_attribute(display, VADisplayAttribRotation, &value)) value = VA_ROTATION_NONE; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 6dac4c5f84..a855aee514 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -96,6 +96,14 @@ struct _GstVaapiDisplayInfo { gpointer native_display; }; +/** + * GstVaapiDisplayProperties: + * @GST_VAAPI_DISPLAY_PROP_RENDER_MODE: rendering mode (#GstVaapiRenderMode). + * @GST_VAAPI_DISPLAY_PROP_ROTATION: rotation angle (#GstVaapiRotation). + */ +#define GST_VAAPI_DISPLAY_PROP_RENDER_MODE "render-mode" +#define GST_VAAPI_DISPLAY_PROP_ROTATION "rotation" + /** * GstVaapiDisplay: * From 112e2b1fe7ed90dd4b7cf24e20c345ccfb97698e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 28 Aug 2012 11:09:56 +0200 Subject: [PATCH 0793/3781] display: raise "notify" for property changes. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 7abda6d195..d2fa1872ea 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1471,6 +1471,8 @@ gst_vaapi_display_set_render_mode( return FALSE; if (!set_attribute(display, VADisplayAttribRenderMode, modes)) return FALSE; + + g_object_notify_by_pspec(G_OBJECT(display), g_properties[PROP_RENDER_MODE]); return TRUE; } @@ -1522,5 +1524,7 @@ gst_vaapi_display_set_rotation( value = from_GstVaapiRotation(rotation); if (!set_attribute(display, VADisplayAttribRotation, value)) return FALSE; + + g_object_notify_by_pspec(G_OBJECT(display), g_properties[PROP_ROTATION]); return TRUE; } From 4dad571526fa1bfdc39f2f91dadca81ffae94e02 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 28 Aug 2012 14:05:16 +0200 Subject: [PATCH 0794/3781] display: initialize default attribute values. Ensure the display attribute is actually supported by trying to retrieve its current value during GstVaapiDisplay creation. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index d2fa1872ea..5ae39d763d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -50,6 +50,7 @@ typedef struct _GstVaapiProperty GstVaapiProperty; struct _GstVaapiProperty { const gchar *name; VADisplayAttribute attribute; + gint old_value; }; #define DEFAULT_RENDER_MODE GST_VAAPI_RENDER_MODE_TEXTURE @@ -72,6 +73,12 @@ static GstVaapiDisplayCache *g_display_cache = NULL; static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; +static gboolean +get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value); + +static gboolean +set_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint value); + static inline GstVaapiDisplayCache * get_display_cache(void) { @@ -607,8 +614,12 @@ gst_vaapi_display_create(GstVaapiDisplay *display) } if (!prop.name) continue; + + /* Assume the attribute is really supported if we can get the + * actual and current value */ prop.attribute = *attr; - g_array_append_val(priv->properties, prop); + if (get_attribute(display, attr->type, &prop.old_value)) + g_array_append_val(priv->properties, prop); } /* VA image formats */ From fafcf0e13ce75c0e0d12e935e5aac520687a0195 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 28 Aug 2012 13:59:50 +0200 Subject: [PATCH 0795/3781] display: add color balance properties. Add support for hue, saturation, brightness and contrast attributes. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 165 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 8 ++ 2 files changed, 173 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 5ae39d763d..985c2811a9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -65,6 +65,10 @@ enum { PROP_HEIGHT, PROP_RENDER_MODE, PROP_ROTATION, + PROP_HUE, + PROP_SATURATION, + PROP_BRIGHTNESS, + PROP_CONTRAST, N_PROPERTIES }; @@ -79,6 +83,12 @@ get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value); static gboolean set_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint value); +static gboolean +get_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat *v); + +static gboolean +set_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat v); + static inline GstVaapiDisplayCache * get_display_cache(void) { @@ -361,6 +371,12 @@ find_property_by_type(GArray *properties, VADisplayAttribType type) } #endif +static inline const GstVaapiProperty * +find_property_by_pspec(GstVaapiDisplay *display, GParamSpec *pspec) +{ + return find_property(display->priv->properties, pspec->name); +} + static void gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display) { @@ -608,6 +624,18 @@ gst_vaapi_display_create(GstVaapiDisplay *display) case VADisplayAttribRotation: prop.name = GST_VAAPI_DISPLAY_PROP_ROTATION; break; + case VADisplayAttribHue: + prop.name = GST_VAAPI_DISPLAY_PROP_HUE; + break; + case VADisplayAttribSaturation: + prop.name = GST_VAAPI_DISPLAY_PROP_SATURATION; + break; + case VADisplayAttribBrightness: + prop.name = GST_VAAPI_DISPLAY_PROP_BRIGHTNESS; + break; + case VADisplayAttribContrast: + prop.name = GST_VAAPI_DISPLAY_PROP_CONTRAST; + break; default: prop.name = NULL; break; @@ -732,6 +760,12 @@ gst_vaapi_display_set_property( case PROP_ROTATION: gst_vaapi_display_set_rotation(display, g_value_get_enum(value)); break; + case PROP_HUE: + case PROP_SATURATION: + case PROP_BRIGHTNESS: + case PROP_CONTRAST: + set_color_balance(display, prop_id, g_value_get_float(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -771,6 +805,16 @@ gst_vaapi_display_get_property( case PROP_ROTATION: g_value_set_enum(value, gst_vaapi_display_get_rotation(display)); break; + case PROP_HUE: + case PROP_SATURATION: + case PROP_BRIGHTNESS: + case PROP_CONTRAST: { + gfloat v; + if (!get_color_balance(display, prop_id, &v)) + v = G_PARAM_SPEC_FLOAT(pspec)->default_value; + g_value_set_float(value, v); + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -864,6 +908,58 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) DEFAULT_ROTATION, G_PARAM_READWRITE); + /** + * GstVaapiDisplay:hue: + * + * The VA display hue, expressed as a float value. Range is -180.0 + * to 180.0. Default value is 0.0 and represents no modification. + */ + g_properties[PROP_HUE] = + g_param_spec_float(GST_VAAPI_DISPLAY_PROP_HUE, + "hue", + "The display hue value", + -180.0, 180.0, 0.0, + G_PARAM_READWRITE); + + /** + * GstVaapiDisplay:saturation: + * + * The VA display saturation, expressed as a float value. Range is + * 0.0 to 2.0. Default value is 1.0 and represents no modification. + */ + g_properties[PROP_SATURATION] = + g_param_spec_float(GST_VAAPI_DISPLAY_PROP_SATURATION, + "saturation", + "The display saturation value", + 0.0, 2.0, 1.0, + G_PARAM_READWRITE); + + /** + * GstVaapiDisplay:brightness: + * + * The VA display brightness, expressed as a float value. Range is + * -1.0 to 1.0. Default value is 0.0 and represents no modification. + */ + g_properties[PROP_BRIGHTNESS] = + g_param_spec_float(GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, + "brightness", + "The display brightness value", + -1.0, 1.0, 0.0, + G_PARAM_READWRITE); + + /** + * GstVaapiDisplay:contrast: + * + * The VA display contrast, expressed as a float value. Range is + * 0.0 to 2.0. Default value is 1.0 and represents no modification. + */ + g_properties[PROP_CONTRAST] = + g_param_spec_float(GST_VAAPI_DISPLAY_PROP_CONTRAST, + "contrast", + "The display contrast value", + 0.0, 2.0, 1.0, + G_PARAM_READWRITE); + g_object_class_install_properties(object_class, N_PROPERTIES, g_properties); } @@ -1539,3 +1635,72 @@ gst_vaapi_display_set_rotation( g_object_notify_by_pspec(G_OBJECT(display), g_properties[PROP_ROTATION]); return TRUE; } + +/* Get color balance attributes */ +static gboolean +get_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat *v) +{ + GParamSpecFloat * const pspec = G_PARAM_SPEC_FLOAT(g_properties[prop_id]); + const GstVaapiProperty *prop; + const VADisplayAttribute *attr; + gfloat out_value; + gint value; + + if (!pspec) + return FALSE; + + prop = find_property_by_pspec(display, &pspec->parent_instance); + if (!prop) + return FALSE; + attr = &prop->attribute; + + if (!get_attribute(display, attr->type, &value)) + return FALSE; + + /* Scale wrt. the medium ("default") value */ + out_value = pspec->default_value; + if (value > attr->value) + out_value += ((gfloat)(value - attr->value) / + (attr->max_value - attr->value) * + (pspec->maximum - pspec->default_value)); + else if (value < attr->value) + out_value -= ((gfloat)(attr->value - value) / + (attr->value - attr->min_value) * + (pspec->default_value - pspec->minimum)); + *v = out_value; + return TRUE; +} + +/* Set color balance attribute */ +static gboolean +set_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat v) +{ + GParamSpecFloat * const pspec = G_PARAM_SPEC_FLOAT(g_properties[prop_id]); + const GstVaapiProperty *prop; + const VADisplayAttribute *attr; + gint value; + + if (!pspec) + return FALSE; + + prop = find_property_by_pspec(display, &pspec->parent_instance); + if (!prop) + return FALSE; + attr = &prop->attribute; + + /* Scale wrt. the medium ("default") value */ + value = attr->value; + if (v > pspec->default_value) + value += ((v - pspec->default_value) / + (pspec->maximum - pspec->default_value) * + (attr->max_value - attr->value)); + else if (v < pspec->default_value) + value -= ((pspec->default_value - v) / + (pspec->default_value - pspec->minimum) * + (attr->value - attr->min_value)); + if (!set_attribute(display, attr->type, value)) + return FALSE; + + g_object_notify_by_pspec(G_OBJECT(display), g_properties[prop_id]); + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index a855aee514..56ca042db5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -100,9 +100,17 @@ struct _GstVaapiDisplayInfo { * 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: From 8ebe4d63d5d6a5db8b70573ca2286cac3c13ce7e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 28 Aug 2012 18:11:32 +0300 Subject: [PATCH 0796/3781] display: fix validation process of properties during discovery. Some VA drivers (e.g. EMGD) can have completely random values for initial display attributes. So, try to improve the discovery process to check the initial display attribute values actually fall within valid bounds. If not, try to reset those to some sensible values like the default value reported through vaQueryDisplayAttributes(). --- gst-libs/gst/vaapi/gstvaapidisplay.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 985c2811a9..96a72094f8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -609,6 +609,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) for (i = 0; i < n; i++) { VADisplayAttribute * const attr = &display_attrs[i]; GstVaapiProperty prop; + gint value; GST_DEBUG(" %s", string_of_VADisplayAttributeType(attr->type)); @@ -645,9 +646,24 @@ gst_vaapi_display_create(GstVaapiDisplay *display) /* Assume the attribute is really supported if we can get the * actual and current value */ + if (!get_attribute(display, attr->type, &value)) + continue; + + /* Some drivers (e.g. EMGD) have completely random initial + * values. So try to reset sensible ones */ + if (value < attr->min_value || value > attr->max_value) { + gint v; + if (!(attr->flags & VA_DISPLAY_ATTRIB_SETTABLE)) + continue; + if (!set_attribute(display, attr->type, attr->value)) + continue; + if (!get_attribute(display, attr->type, &v) || v != value) + continue; + } + prop.attribute = *attr; - if (get_attribute(display, attr->type, &prop.old_value)) - g_array_append_val(priv->properties, prop); + prop.old_value = value; + g_array_append_val(priv->properties, prop); } /* VA image formats */ From 38c7fea241f831d0ba29afc794e9af30f53a76bb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 28 Aug 2012 16:08:34 +0200 Subject: [PATCH 0797/3781] tests: dump VA display properties. --- tests/test-display.c | 137 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 126 insertions(+), 11 deletions(-) diff --git a/tests/test-display.c b/tests/test-display.c index f86ebb87c7..fa381cdd83 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -44,6 +44,18 @@ # include #endif +static void +print_value(const GValue *value, const gchar *name) +{ + gchar *value_string; + + value_string = g_strdup_value_contents(value); + if (!value_string) + return; + g_print(" %s: %s\n", name, value_string); + g_free(value_string); +} + static void print_profile_caps(GstCaps *caps, const gchar *name) { @@ -122,8 +134,109 @@ print_format_caps(GstCaps *caps, const gchar *name) } } +typedef struct _GstVaapiDisplayProperty GstVaapiDisplayProperty; +struct _GstVaapiDisplayProperty { + const gchar *name; + GValue value; +}; + static void -dump_caps(GstVaapiDisplay *display) +gst_vaapi_display_property_free(GstVaapiDisplayProperty *prop) +{ + if (!prop) + return; + g_value_unset(&prop->value); + g_slice_free(GstVaapiDisplayProperty, prop); +} + +static GstVaapiDisplayProperty * +gst_vaapi_display_property_new(const gchar *name) +{ + GstVaapiDisplayProperty *prop; + + prop = g_slice_new0(GstVaapiDisplayProperty); + if (!prop) + return NULL; + prop->name = name; + return prop; +} + +static void +free_property_cb(gpointer data, gpointer user_data) +{ + gst_vaapi_display_property_free(data); +} + +static inline GParamSpec * +get_display_property(GstVaapiDisplay *display, const gchar *name) +{ + GObjectClass *klass; + + klass = G_OBJECT_CLASS(GST_VAAPI_DISPLAY_GET_CLASS(display)); + if (!klass) + return NULL; + return g_object_class_find_property(klass, name); +} + +static void +dump_properties(GstVaapiDisplay *display) +{ + GstVaapiDisplayProperty *prop; + GPtrArray *properties; + guint i; + + static const gchar *g_properties[] = { + GST_VAAPI_DISPLAY_PROP_RENDER_MODE, + GST_VAAPI_DISPLAY_PROP_ROTATION, + GST_VAAPI_DISPLAY_PROP_HUE, + GST_VAAPI_DISPLAY_PROP_SATURATION, + GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, + GST_VAAPI_DISPLAY_PROP_CONTRAST, + NULL + }; + + properties = g_ptr_array_new(); + if (!properties) + return; + + for (i = 0; g_properties[i] != NULL; i++) { + GParamSpec *pspec = get_display_property(display, g_properties[i]); + + if (!pspec) { + GST_ERROR("failed to find GstVaapiDisplay property '%s'", + g_properties[i]); + goto end; + } + + if (!gst_vaapi_display_has_property(display, pspec->name)) + continue; + + prop = gst_vaapi_display_property_new(pspec->name); + if (!prop) { + GST_ERROR("failed to allocate GstVaapiDisplayProperty"); + goto end; + } + + g_value_init(&prop->value, pspec->value_type); + g_object_get_property(G_OBJECT(display), pspec->name, &prop->value); + g_ptr_array_add(properties, prop); + } + + g_print("%u properties\n", properties->len); + for (i = 0; i < properties->len; i++) { + prop = g_ptr_array_index(properties, i); + print_value(&prop->value, prop->name); + } + +end: + if (properties) { + g_ptr_array_foreach(properties, free_property_cb, NULL); + g_ptr_array_free(properties, TRUE); + } +} + +static void +dump_info(GstVaapiDisplay *display) { GstCaps *caps; @@ -154,6 +267,8 @@ dump_caps(GstVaapiDisplay *display) print_format_caps(caps, "subpicture"); gst_caps_unref(caps); + + dump_properties(display); } int @@ -173,7 +288,7 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); - dump_caps(display); + dump_info(display); g_object_unref(display); } g_print("\n"); @@ -192,7 +307,7 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); - dump_caps(display); + dump_info(display); g_object_unref(display); close(drm_device); } @@ -217,7 +332,7 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); - dump_caps(display); + dump_info(display); g_object_unref(display); close(drm_device); } @@ -239,7 +354,7 @@ main(int argc, char *argv[]) gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d); g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); - dump_caps(display); + dump_info(display); g_object_unref(display); } g_print("\n"); @@ -258,7 +373,7 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); - dump_caps(display); + dump_info(display); g_object_unref(display); XCloseDisplay(x11_display); } @@ -283,7 +398,7 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); - dump_caps(display); + dump_info(display); g_object_unref(display); XCloseDisplay(x11_display); } @@ -305,7 +420,7 @@ main(int argc, char *argv[]) gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d); g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); - dump_caps(display); + dump_info(display); g_object_unref(display); } g_print("\n"); @@ -324,7 +439,7 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); - dump_caps(display); + dump_info(display); g_object_unref(display); XCloseDisplay(x11_display); } @@ -350,7 +465,7 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); - dump_caps(display); + dump_info(display); g_object_unref(display); XCloseDisplay(x11_display); } @@ -373,7 +488,7 @@ main(int argc, char *argv[]) gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d); g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); - dump_caps(display); + dump_info(display); g_object_unref(display); } g_print("\n"); From 9b11f069c95e105d42b3ae1150845b02ee851df6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 29 Aug 2012 10:13:58 +0200 Subject: [PATCH 0798/3781] display: partially revert 8ebe4d6. Don't try to fix up the initial values, this could make things worse. Simply assume the driver does not support the capability in this case. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 96a72094f8..a52339d4ff 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -650,16 +650,9 @@ gst_vaapi_display_create(GstVaapiDisplay *display) continue; /* Some drivers (e.g. EMGD) have completely random initial - * values. So try to reset sensible ones */ - if (value < attr->min_value || value > attr->max_value) { - gint v; - if (!(attr->flags & VA_DISPLAY_ATTRIB_SETTABLE)) - continue; - if (!set_attribute(display, attr->type, attr->value)) - continue; - if (!get_attribute(display, attr->type, &v) || v != value) - continue; - } + * values */ + if (value < attr->min_value || value > attr->max_value) + continue; prop.attribute = *attr; prop.old_value = value; From ab8b0359e16107d59d3f216688e4e86a4aeb6eea Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 24 Aug 2012 14:54:16 +0300 Subject: [PATCH 0799/3781] vaapisink: fix build with older toolchains. Don't re-declare GstVaapiTexture if USE_GLX mode is set. --- gst/vaapi/gstvaapisink.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index c5883b3c52..54930463f0 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -59,7 +59,9 @@ G_BEGIN_DECLS typedef struct _GstVaapiSink GstVaapiSink; typedef struct _GstVaapiSinkClass GstVaapiSinkClass; +#if !USE_GLX typedef struct _GstVaapiTexture GstVaapiTexture; +#endif struct _GstVaapiSink { /*< private >*/ From e36fb69ef907333fce851ff6bb644ea3b5b0b165 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 24 Aug 2012 16:30:33 +0300 Subject: [PATCH 0800/3781] vaapisink: retain VA surface until another one is displayed. Keep VA surface proxy associated with the surface that is currently being displayed. This makes sure that surface is not released back to the pool of surfaces free to use for decoding. This is necessary with VA driver implementations that support rendering to an overlay pipe. Otherwise, there could be cases where we are decoding into a surface that is being displayed, hence some flickering. --- gst/vaapi/gstvaapisink.c | 10 +++++++++- gst/vaapi/gstvaapisink.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 4611974f9d..cacf087b56 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -223,6 +223,7 @@ gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface) static void gst_vaapisink_destroy(GstVaapiSink *sink) { + gst_buffer_replace(&sink->video_buffer, NULL); g_clear_object(&sink->texture); g_clear_object(&sink->display); @@ -468,6 +469,7 @@ gst_vaapisink_stop(GstBaseSink *base_sink) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + gst_buffer_replace(&sink->video_buffer, NULL); g_clear_object(&sink->window); g_clear_object(&sink->display); @@ -772,7 +774,12 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) success = FALSE; break; } - return success ? GST_FLOW_OK : GST_FLOW_UNEXPECTED; + if (!success) + return GST_FLOW_UNEXPECTED; + + /* Retain VA surface until the next one is displayed */ + gst_buffer_replace(&sink->video_buffer, buffer); + return GST_FLOW_OK; } static gboolean @@ -938,6 +945,7 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->window_width = 0; sink->window_height = 0; sink->texture = NULL; + sink->video_buffer = NULL; sink->video_width = 0; sink->video_height = 0; sink->video_par_n = 1; diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 54930463f0..0e8709f321 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -74,6 +74,7 @@ struct _GstVaapiSink { guint window_width; guint window_height; GstVaapiTexture *texture; + GstBuffer *video_buffer; guint video_width; guint video_height; gint video_par_n; From 0ef393c6aff7c4dab6409e9680a84e875d63213a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 27 Aug 2012 18:34:27 +0300 Subject: [PATCH 0801/3781] vaapisink: automatically detect overlay rendering mode. Retain the VA surface until another surface is to be displayed only if VA display rendering mode is determined to be "overlay" mode. --- gst/vaapi/gstvaapisink.c | 10 +++++++++- gst/vaapi/gstvaapisink.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index cacf087b56..45d8155778 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -298,6 +298,7 @@ static inline gboolean gst_vaapisink_ensure_display(GstVaapiSink *sink) { GstVaapiDisplayType display_type; + GstVaapiRenderMode render_mode; if (!gst_vaapi_ensure_display(sink, sink->display_type, &sink->display)) return FALSE; @@ -307,6 +308,11 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink) GST_INFO("created %s %p", get_display_type_name(display_type), sink->display); sink->display_type = display_type; + + sink->use_overlay = + gst_vaapi_display_get_render_mode(sink->display, &render_mode) && + render_mode == GST_VAAPI_RENDER_MODE_OVERLAY; + GST_DEBUG("use %s rendering mode", sink->use_overlay ? "overlay" : "texture"); } return TRUE; } @@ -778,7 +784,8 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) return GST_FLOW_UNEXPECTED; /* Retain VA surface until the next one is displayed */ - gst_buffer_replace(&sink->video_buffer, buffer); + if (sink->use_overlay) + gst_buffer_replace(&sink->video_buffer, buffer); return GST_FLOW_OK; } @@ -955,4 +962,5 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->synchronous = FALSE; sink->display_type = DEFAULT_DISPLAY_TYPE; sink->use_reflection = FALSE; + sink->use_overlay = FALSE; } diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 0e8709f321..eae1665bde 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -84,6 +84,7 @@ struct _GstVaapiSink { guint fullscreen : 1; guint synchronous : 1; guint use_reflection : 1; + guint use_overlay : 1; }; struct _GstVaapiSinkClass { From 4a1127dd7c4086c97b0651a9f653fe3f43f11235 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 29 Aug 2012 13:18:05 +0200 Subject: [PATCH 0802/3781] vaapisink: drop obsolete GstVaapiVideoSink interface. This interface was deprecated since 0.3.x series when the GstVideoContext interface was added to the main GStreamer APIs. --- docs/reference/libs/libs-docs.xml.in | 1 - docs/reference/libs/libs-sections.txt | 14 --- gst-libs/gst/vaapi/Makefile.am | 2 - gst-libs/gst/vaapi/gstvaapivideosink.c | 118 ------------------------- gst-libs/gst/vaapi/gstvaapivideosink.h | 74 ---------------- gst/vaapi/gstvaapidecode.c | 1 - gst/vaapi/gstvaapidownload.c | 1 - gst/vaapi/gstvaapipostproc.c | 1 - gst/vaapi/gstvaapisink.c | 3 +- gst/vaapi/gstvaapiupload.c | 1 - 10 files changed, 1 insertion(+), 215 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapivideosink.c delete mode 100644 gst-libs/gst/vaapi/gstvaapivideosink.h diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index e4329662ba..34b16658c1 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -36,7 +36,6 @@ - diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 435f6e82a0..1d9869a19b 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -39,20 +39,6 @@ GST_VAAPI_IS_VIDEO_POOL_CLASS GST_VAAPI_VIDEO_POOL_GET_CLASS
-
-gstvaapivideosink -GstVaapiVideoSink -GST_VAAPI_VIDEO_SINK_GET_INTERFACE -GstVaapiVideoSinkInterface -gst_vaapi_video_sink_get_display -gst_vaapi_video_sink_lookup - -GST_VAAPI_VIDEO_SINK -GST_VAAPI_IS_VIDEO_SINK -GST_VAAPI_TYPE_VIDEO_SINK -gst_vaapi_video_sink_get_type -
-
gstvaapidisplay_x11 GstVaapiDisplayX11 diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 5719222f25..b93d9c3fe6 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -65,7 +65,6 @@ libgstvaapi_source_c = \ gstvaapivalue.c \ gstvaapivideobuffer.c \ gstvaapivideopool.c \ - gstvaapivideosink.c \ gstvaapiwindow.c \ $(NULL) @@ -92,7 +91,6 @@ libgstvaapi_source_h = \ gstvaapivalue.h \ gstvaapivideobuffer.h \ gstvaapivideopool.h \ - gstvaapivideosink.h \ gstvaapiwindow.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.c b/gst-libs/gst/vaapi/gstvaapivideosink.c deleted file mode 100644 index cde38dd81a..0000000000 --- a/gst-libs/gst/vaapi/gstvaapivideosink.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * gstvaapivideosink.c - VA sink interface - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * - * 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:gstvaapivideosink - * @short_description: An interface for implementing VA-API sink elements - */ - -#include "sysdeps.h" -#include "gstvaapivideosink.h" - -static void -gst_vaapi_video_sink_base_init(gpointer g_class) -{ - static gboolean is_initialized = FALSE; - - if (!is_initialized) { - is_initialized = TRUE; - } -} - -GType -gst_vaapi_video_sink_get_type(void) -{ - static GType iface_type = 0; - - if (G_UNLIKELY(!iface_type)) { - static const GTypeInfo info = { - sizeof(GstVaapiVideoSinkInterface), - gst_vaapi_video_sink_base_init, /* base_init */ - NULL, /* base_finalize */ - }; - - iface_type = g_type_register_static( - G_TYPE_INTERFACE, - "GstVaapiVideoSink", - &info, - 0 - ); - } - return iface_type; -} - -/** - * gst_vaapi_video_sink_get_display: - * @sink: a #GstElement - * - * Returns the #GstVaapiDisplay created by the VA-API @sink element. - * - * Return value: the #GstVaapiDisplay created by the @sink element - */ -GstVaapiDisplay * -gst_vaapi_video_sink_get_display(GstVaapiVideoSink *sink) -{ - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_SINK(sink), NULL); - - return GST_VAAPI_VIDEO_SINK_GET_INTERFACE(sink)->get_display(sink); -} - -/** - * gst_vaapi_video_sink_lookup: - * @element: a #GstElement - * - * Traverses the whole downstream elements chain and finds a suitable - * #GstVaapiDisplay. This is a helper function for intermediate VA-API - * elements that don't create a #GstVaapiDisplay but require one. - * e.g. the `vaapiconvert' element. - * - * Return value: the #GstVaapiDisplay created by a downstream sink - * element, or %NULL if none was found - */ -GstVaapiVideoSink * -gst_vaapi_video_sink_lookup(GstElement *element) -{ - GstVaapiVideoSink *sink = NULL; - GstPad *pad, *peer; - - g_return_val_if_fail(GST_IS_ELEMENT(element), NULL); - - while (!sink) { - pad = gst_element_get_static_pad(element, "src"); - if (!pad) - break; - - peer = gst_pad_get_peer(pad); - g_object_unref(pad); - if (!peer) - break; - - element = gst_pad_get_parent_element(peer); - g_object_unref(peer); - if (!element) - break; - - if (GST_VAAPI_IS_VIDEO_SINK(element)) - sink = GST_VAAPI_VIDEO_SINK(element); - g_object_unref(element); - } - return sink; -} diff --git a/gst-libs/gst/vaapi/gstvaapivideosink.h b/gst-libs/gst/vaapi/gstvaapivideosink.h deleted file mode 100644 index f33ba49717..0000000000 --- a/gst-libs/gst/vaapi/gstvaapivideosink.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * gstvaapivideosink.h - VA sink interface - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * - * 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_VIDEO_SINK_H -#define GST_VAAPI_VIDEO_SINK_H - -#include -#include - -G_BEGIN_DECLS - -#define GST_VAAPI_TYPE_VIDEO_SINK \ - (gst_vaapi_video_sink_get_type()) - -#define GST_VAAPI_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_VIDEO_SINK, \ - GstVaapiVideoSink)) - -#define GST_VAAPI_IS_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_SINK)) - -#define GST_VAAPI_VIDEO_SINK_GET_INTERFACE(obj) \ - (G_TYPE_INSTANCE_GET_INTERFACE((obj), \ - GST_VAAPI_TYPE_VIDEO_SINK, \ - GstVaapiVideoSinkInterface)) - -typedef struct _GstVaapiVideoSink GstVaapiVideoSink; /* dummy */ -typedef struct _GstVaapiVideoSinkInterface GstVaapiVideoSinkInterface; - -/** - * GstVaapiVideoSinkInterface: - * @get_display: virtual function for retrieving the #GstVaapiDisplay created - * by the downstream sink element. The implementation of that virtual - * function is required for all Gstreamer/VAAPI sink elements. - */ -struct _GstVaapiVideoSinkInterface { - /*< private >*/ - GTypeInterface g_iface; - - /*< public >*/ - GstVaapiDisplay *(*get_display)(GstVaapiVideoSink *sink); -}; - -GType -gst_vaapi_video_sink_get_type(void) G_GNUC_CONST; - -GstVaapiDisplay * -gst_vaapi_video_sink_get_display(GstVaapiVideoSink *sink); - -GstVaapiVideoSink * -gst_vaapi_video_sink_lookup(GstElement *element); - -G_END_DECLS - -#endif /* GST_VAAPI_VIDEO_SINK_H */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 253874ca27..6980d47d26 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -31,7 +31,6 @@ #include "config.h" #include -#include #include #include diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 69ce5d193f..56ae902dce 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include "gstvaapidownload.h" diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 8565a5e4d1..6f6a818518 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -31,7 +31,6 @@ #include "config.h" #include #include -#include #include #include "gstvaapipostproc.h" diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 45d8155778..fea9e56e6b 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -34,7 +34,6 @@ #include #include #include -#include #if USE_DRM # include #endif @@ -128,7 +127,7 @@ gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface) iface->supported = gst_vaapisink_implements_interface_supported; } -/* GstVaapiVideoSink interface */ +/* GstVideoContext interface */ static void gst_vaapisink_set_video_context(GstVideoContext *context, const gchar *type, diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index b4bc9fde9b..d0eb20fcab 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include "gstvaapiupload.h" From 2a7cefab1a366ae27a65179cef72f1c6dce2f230 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 30 Aug 2012 16:27:56 +0200 Subject: [PATCH 0803/3781] display: fix GstVaapiRotation enumeration of values. --- gst-libs/gst/vaapi/gstvaapivalue.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 8461c09e95..19d95a7169 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -202,6 +202,7 @@ gst_vaapi_rotation_get_type(void) "Rotated by 180°, clockwise", "180" }, { GST_VAAPI_ROTATION_270, "Rotated by 270°, clockwise", "270" }, + { 0, NULL, NULL }, }; if (!g_type) From 30a8c566b7cfccc60ea4e8b4781c4176bb54f8b3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 6 Sep 2012 11:50:21 +0200 Subject: [PATCH 0804/3781] display: fix physical display size when display is rotated. --- configure.ac | 17 ++++++ gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 54 ++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 1 + 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 1f98001292..227aa64026 100644 --- a/configure.ac +++ b/configure.ac @@ -312,6 +312,23 @@ if test "$enable_x11" = "yes"; then fi fi +dnl Check for XRandR +HAVE_XRANDR=0 +if test $USE_X11 -eq 1; then + HAVE_XRANDR=1 + PKG_CHECK_MODULES([XRANDR], [xrandr], [:], [HAVE_XRANDR=0]) + if test $HAVE_XRANDR -eq 1; then + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $XRANDR_CFLAGS" + AC_CHECK_HEADERS([X11/extensions/Xrandr.h], [:], [HAVE_XRANDR=0]) + CPPFLAGS="$saved_CPPFLAGS" + fi +fi +if test $HAVE_XRANDR -eq 1; then + AC_DEFINE_UNQUOTED(HAVE_XRANDR, 1, + [Defined to 1 if the XRandR extension exists.]) +fi + dnl OpenGL enable_opengl="no" if test "$enable_glx" = "yes"; then diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index b93d9c3fe6..7f645c8d32 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -278,12 +278,14 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_CFLAGS = \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ $(X11_CFLAGS) \ + $(XRANDR_CFLAGS) \ $(LIBVA_X11_CFLAGS) \ $(NULL) libgstvaapi_x11_@GST_MAJORMINOR@_la_LIBADD = \ $(GLIB_LIBS) \ $(X11_LIBS) \ + $(XRANDR_LIBS) \ $(LIBVA_X11_LIBS) \ libgstvaapi-@GST_MAJORMINOR@.la \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 1c89d1577b..f00b5af910 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -32,6 +32,10 @@ #include "gstvaapidisplay_x11.h" #include "gstvaapidisplay_x11_priv.h" +#ifdef HAVE_XRANDR +# include +#endif + #define DEBUG 1 #include "gstvaapidebug.h" @@ -265,6 +269,14 @@ gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) if (priv->synchronous) XSynchronize(priv->x11_display, True); + +#ifdef HAVE_XRANDR + { + int evt_base, err_base; + priv->use_xrandr = XRRQueryExtension( + priv->x11_display, &evt_base, &err_base); + } +#endif return TRUE; } @@ -375,15 +387,52 @@ gst_vaapi_display_x11_get_size_mm( { GstVaapiDisplayX11Private * const priv = GST_VAAPI_DISPLAY_X11(display)->priv; + 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); + +#ifdef 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 = DisplayWidthMM(priv->x11_display, priv->x11_screen); + *pwidth = width_mm; if (pheight) - *pheight = DisplayHeightMM(priv->x11_display, priv->x11_screen); + *pheight = height_mm; } static void @@ -476,6 +525,7 @@ gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) priv->x11_display = NULL; priv->x11_screen = 0; priv->display_name = NULL; + priv->use_xrandr = FALSE; } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index a1b9213e95..bc04ecbea2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -60,6 +60,7 @@ struct _GstVaapiDisplayX11Private { int x11_screen; guint create_display : 1; guint synchronous : 1; + guint use_xrandr : 1; }; G_END_DECLS From 09724e12defa3c2f78fafebe3316d8173086a4a2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 6 Sep 2012 11:51:41 +0200 Subject: [PATCH 0805/3781] display: fix display aspect ratio when display is rotated. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index a52339d4ff..887664374e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -382,7 +382,7 @@ gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display) { GstVaapiDisplayPrivate * const priv = display->priv; gdouble ratio, delta; - gint i, index; + gint i, j, index, windex; static const gint par[][2] = { {1, 1}, /* regular screen */ @@ -405,21 +405,25 @@ gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display) GST_DEBUG("calculated pixel aspect ratio: %f", ratio); /* Now, find the one from par[][2] with the lowest delta to the real one */ -#define DELTA(idx) (ABS(ratio - ((gdouble)par[idx][0] / par[idx][1]))) - delta = DELTA(0); - index = 0; +#define DELTA(idx, w) (ABS(ratio - ((gdouble)par[idx][w] / par[idx][!(w)]))) + delta = DELTA(0, 0); + index = 0; + windex = 0; for (i = 1; i < G_N_ELEMENTS(par); i++) { - const gdouble this_delta = DELTA(i); - if (this_delta < delta) { - index = i; - delta = this_delta; + for (j = 0; j < 2; j++) { + const gdouble this_delta = DELTA(i, j); + if (this_delta < delta) { + index = i; + windex = j; + delta = this_delta; + } } } #undef DELTA - priv->par_n = par[index][0]; - priv->par_d = par[index][1]; + priv->par_n = par[index][windex]; + priv->par_d = par[index][windex ^ 1]; } static void From bd397a536bba813fda9865bc39bddd02eef60b5a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 6 Sep 2012 11:47:40 +0200 Subject: [PATCH 0806/3781] pluginutils: add G_PRIMITIVE_SWAP() helper macro. This macro helps swapping variables while maintaining the correct underlying and primitive type. --- gst/vaapi/gstvaapipluginutil.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index b55374bec7..78f274f5c6 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -50,4 +50,10 @@ G_GNUC_INTERNAL gboolean gst_vaapi_append_surface_caps (GstCaps *out_caps, GstCaps *in_caps); +#ifndef G_PRIMITIVE_SWAP +#define G_PRIMITIVE_SWAP(type, a, b) do { \ + const type t = a; a = b; b = t; \ + } while (0) +#endif + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ From c8f2358479c89106e5ec25c1fed7c633d1a594d4 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 28 Aug 2012 02:45:22 -0400 Subject: [PATCH 0807/3781] vaapisink: add video rotation support. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 75 +++++++++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapisink.h | 3 ++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index fea9e56e6b..c4b6260b3d 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #if USE_DRM # include @@ -104,10 +105,12 @@ enum { PROP_DISPLAY_TYPE, PROP_FULLSCREEN, PROP_SYNCHRONOUS, - PROP_USE_REFLECTION + PROP_USE_REFLECTION, + PROP_ROTATION, }; #define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY +#define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 /* GstImplementsInterface interface */ @@ -312,6 +315,9 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink) gst_vaapi_display_get_render_mode(sink->display, &render_mode) && render_mode == GST_VAAPI_RENDER_MODE_OVERLAY; GST_DEBUG("use %s rendering mode", sink->use_overlay ? "overlay" : "texture"); + + sink->use_rotation = gst_vaapi_display_has_property( + sink->display, GST_VAAPI_DISPLAY_PROP_ROTATION); } return TRUE; } @@ -461,6 +467,45 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) } #endif +static gboolean +gst_vaapisink_ensure_rotation(GstVaapiSink *sink, gboolean recalc_display_rect) +{ + gboolean success = FALSE; + + g_return_val_if_fail(sink->display, FALSE); + + if (sink->rotation == sink->rotation_req) + return TRUE; + + if (!sink->use_rotation) { + GST_WARNING("VA display does not support rotation"); + goto end; + } + + gst_vaapi_display_lock(sink->display); + success = gst_vaapi_display_set_rotation(sink->display, sink->rotation_req); + gst_vaapi_display_unlock(sink->display); + if (!success) { + GST_ERROR("failed to change VA display rotation mode"); + goto end; + } + + if (((sink->rotation + sink->rotation_req) % 180) == 90) { + /* Orientation changed */ + G_PRIMITIVE_SWAP(guint, sink->video_width, sink->video_height); + G_PRIMITIVE_SWAP(gint, sink->video_par_n, sink->video_par_d); + } + + if (recalc_display_rect && !sink->foreign_window) + gst_vaapisink_ensure_render_rect(sink, sink->window_width, + sink->window_height); + success = TRUE; + +end: + sink->rotation = sink->rotation_req; + return success; +} + static gboolean gst_vaapisink_start(GstBaseSink *base_sink) { @@ -513,6 +558,8 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) if (!gst_vaapisink_ensure_display(sink)) return FALSE; + gst_vaapisink_ensure_rotation(sink, FALSE); + gst_vaapi_display_get_size(sink->display, &display_width, &display_height); if (sink->foreign_window) { win_width = sink->window_width; @@ -740,6 +787,8 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) if (!sink->window) return GST_FLOW_UNEXPECTED; + gst_vaapisink_ensure_rotation(sink, TRUE); + surface = gst_vaapi_video_buffer_get_surface(vbuffer); if (!surface) return GST_FLOW_UNEXPECTED; @@ -827,6 +876,9 @@ gst_vaapisink_set_property( case PROP_USE_REFLECTION: sink->use_reflection = g_value_get_boolean(value); break; + case PROP_ROTATION: + sink->rotation_req = g_value_get_enum(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -856,6 +908,9 @@ gst_vaapisink_get_property( case PROP_USE_REFLECTION: g_value_set_boolean(value, sink->use_reflection); break; + case PROP_ROTATION: + g_value_set_enum(value, sink->rotation); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -940,6 +995,21 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) "Toggles X display synchronous mode", FALSE, G_PARAM_READWRITE)); + + /** + * GstVaapiSink:rotation: + * + * The VA display rotation mode, expressed as a #GstVaapiRotation. + */ + g_object_class_install_property + (object_class, + PROP_ROTATION, + g_param_spec_enum(GST_VAAPI_DISPLAY_PROP_ROTATION, + "rotation", + "The display rotation mode", + GST_VAAPI_TYPE_ROTATION, + DEFAULT_ROTATION, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void @@ -960,6 +1030,9 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->fullscreen = FALSE; sink->synchronous = FALSE; sink->display_type = DEFAULT_DISPLAY_TYPE; + sink->rotation = DEFAULT_ROTATION; + sink->rotation_req = DEFAULT_ROTATION; sink->use_reflection = FALSE; sink->use_overlay = FALSE; + sink->use_rotation = FALSE; } diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index eae1665bde..a2e8bff66d 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -80,11 +80,14 @@ struct _GstVaapiSink { gint video_par_n; gint video_par_d; GstVaapiRectangle display_rect; + GstVaapiRotation rotation; + GstVaapiRotation rotation_req; guint foreign_window : 1; guint fullscreen : 1; guint synchronous : 1; guint use_reflection : 1; guint use_overlay : 1; + guint use_rotation : 1; }; struct _GstVaapiSinkClass { From de2a18012dca67d9e581219e94616a63866db821 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 4 Sep 2012 11:53:18 +0200 Subject: [PATCH 0808/3781] vaapisink: fix calculation of window size. If either dimension is out-of-bounds, then scale window to fit the display size, even if the output is to be rotated. Use the standard gst_video_sink_center_rect() function to center and scale the window wrt. the outer (display) bounds. --- gst/vaapi/gstvaapisink.c | 68 ++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index c4b6260b3d..3c0d5009fd 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -378,6 +378,56 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) return TRUE; } +static void +gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheight) +{ + GstVideoRectangle src_rect, dst_rect, out_rect; + guint num, den, display_width, display_height, display_par_n, display_par_d; + gboolean success, scale; + + if (sink->foreign_window) { + *pwidth = sink->window_width; + *pheight = sink->window_height; + return; + } + + gst_vaapi_display_get_size(sink->display, &display_width, &display_height); + if (sink->fullscreen) { + *pwidth = display_width; + *pheight = display_height; + return; + } + + gst_vaapi_display_get_pixel_aspect_ratio( + sink->display, + &display_par_n, &display_par_d + ); + + success = gst_video_calculate_display_ratio( + &num, &den, + sink->video_width, sink->video_height, + sink->video_par_n, sink->video_par_d, + display_par_n, display_par_d + ); + if (!success) { + num = sink->video_par_n; + den = sink->video_par_d; + } + + src_rect.x = 0; + src_rect.y = 0; + src_rect.w = gst_util_uint64_scale_int(sink->video_height, num, den); + src_rect.h = sink->video_height; + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.w = display_width; + dst_rect.h = display_height; + scale = (src_rect.w > dst_rect.w || src_rect.h > dst_rect.h); + gst_video_sink_center_rect(src_rect, dst_rect, &out_rect, scale); + *pwidth = out_rect.w; + *pheight = out_rect.h; +} + static inline gboolean gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) { @@ -531,7 +581,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstStructure * const structure = gst_caps_get_structure(caps, 0); - guint win_width, win_height, display_width, display_height; + guint win_width, win_height; gint video_width, video_height, video_par_n = 1, video_par_d = 1; #if USE_DRM @@ -560,21 +610,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) gst_vaapisink_ensure_rotation(sink, FALSE); - gst_vaapi_display_get_size(sink->display, &display_width, &display_height); - if (sink->foreign_window) { - win_width = sink->window_width; - win_height = sink->window_height; - } - else if (sink->fullscreen || - video_width > display_width || video_height > display_height) { - win_width = display_width; - win_height = display_height; - } - else { - win_width = video_width; - win_height = video_height; - } - + gst_vaapisink_ensure_window_size(sink, &win_width, &win_height); if (sink->window) { if (!sink->foreign_window || sink->fullscreen) gst_vaapi_window_set_size(sink->window, win_width, win_height); From eb73aa3061d42144564ad29d92b161174583859b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Sep 2012 11:44:44 +0200 Subject: [PATCH 0809/3781] configure: fix check for VA/DRM API. --- configure.ac | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 227aa64026..c598efa33c 100644 --- a/configure.ac +++ b/configure.ac @@ -397,9 +397,17 @@ VA_MICRO_VERSION=`echo "$VA_VERSION" | cut -d'.' -f3` VA_VERSION_STR="$VA_VERSION" dnl VA/DRM API -if test "$enable_drm" = "yes"; then +HAVE_VA_DRM=0 +if test $USE_DRM -eq 1; then PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= va_api_drm_version], - [:], [USE_DRM=0]) + [HAVE_VA_DRM=1], [USE_DRM=0]) + + if test $HAVE_VA_DRM -eq 1; then + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$LIBVA_DRM_CPPFLAGS" + AC_CHECK_HEADERS([va/va_drm.h], [:], [HAVE_VA_DRM=0 USE_DRM=0]) + CPPFLAGS="$saved_CPPFLAGS" + fi fi dnl VA/X11 API From 79b45a43d1f8fe1da67fbe20368a2772fe0e06fd Mon Sep 17 00:00:00 2001 From: Philip Lorenz Date: Tue, 4 Sep 2012 13:40:04 +0200 Subject: [PATCH 0810/3781] Do not forward declare enums. Forward declaring enums is not allowed by the C standard and aborts compilation if the header file is included in a C++ project. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder.h | 5 ++--- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 5 ++--- gst-libs/gst/vaapi/gstvaapidisplay.h | 5 ++--- gst-libs/gst/vaapi/gstvaapiimageformat.c | 5 ++--- gst-libs/gst/vaapi/gstvaapiimageformat.h | 6 ++---- gst-libs/gst/vaapi/gstvaapiprofile.h | 16 ++++++---------- gst-libs/gst/vaapi/gstvaapisurface.h | 16 ++++++---------- gst-libs/gst/vaapi/gstvaapitypes.h | 10 ++++------ gst/vaapi/gstvaapipostproc.h | 11 ++++------- 9 files changed, 30 insertions(+), 49 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index f365b931a8..deeb692672 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -53,7 +53,6 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DECODER, \ GstVaapiDecoderClass)) -typedef enum _GstVaapiDecoderStatus GstVaapiDecoderStatus; typedef struct _GstVaapiDecoder GstVaapiDecoder; typedef struct _GstVaapiDecoderPrivate GstVaapiDecoderPrivate; typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; @@ -75,7 +74,7 @@ typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; * * Decoder status for gst_vaapi_decoder_get_surface(). */ -enum _GstVaapiDecoderStatus { +typedef enum { GST_VAAPI_DECODER_STATUS_SUCCESS = 0, GST_VAAPI_DECODER_STATUS_END_OF_STREAM, GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED, @@ -88,7 +87,7 @@ enum _GstVaapiDecoderStatus { GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE, GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN = -1 -}; +} GstVaapiDecoderStatus; /** * GstVaapiDecoder: diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index f7a7ea6930..b95f4e00ef 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -27,7 +27,6 @@ G_BEGIN_DECLS -typedef enum _GstVaapiPictureType GstVaapiPictureType; typedef struct _GstVaapiPicture GstVaapiPicture; typedef struct _GstVaapiPictureClass GstVaapiPictureClass; typedef struct _GstVaapiSlice GstVaapiSlice; @@ -64,7 +63,7 @@ typedef struct _GstVaapiSliceClass GstVaapiSliceClass; GST_VAAPI_TYPE_PICTURE, \ GstVaapiPictureClass)) -enum _GstVaapiPictureType { +typedef enum { GST_VAAPI_PICTURE_TYPE_NONE = 0, // Undefined GST_VAAPI_PICTURE_TYPE_I, // Intra GST_VAAPI_PICTURE_TYPE_P, // Predicted @@ -73,7 +72,7 @@ enum _GstVaapiPictureType { GST_VAAPI_PICTURE_TYPE_SI, // Switching Intra GST_VAAPI_PICTURE_TYPE_SP, // Switching Predicted GST_VAAPI_PICTURE_TYPE_BI, // BI type (VC-1) -}; +} GstVaapiPictureType; /** * Picture flags: diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 56ca042db5..d23b0ad94c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -55,7 +55,6 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DISPLAY, \ GstVaapiDisplayClass)) -typedef enum _GstVaapiDisplayType GstVaapiDisplayType; typedef struct _GstVaapiDisplayInfo GstVaapiDisplayInfo; typedef struct _GstVaapiDisplay GstVaapiDisplay; typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; @@ -69,13 +68,13 @@ typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; * @GST_VAAPI_DISPLAY_TYPE_WAYLAND: VA/Wayland display. * @GST_VAAPI_DISPLAY_TYPE_DRM: VA/DRM display. */ -enum _GstVaapiDisplayType { +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, -}; +} GstVaapiDisplayType; #define GST_VAAPI_TYPE_DISPLAY_TYPE \ (gst_vaapi_display_type_get_type()) diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index dd031577a9..d29ef6c286 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -30,14 +30,13 @@ #include "gstvaapicompat.h" #include "gstvaapiimageformat.h" -typedef enum _GstVaapiImageFormatType GstVaapiImageFormatType; typedef struct _GstVaapiImageFormatMap GstVaapiImageFormatMap; -enum _GstVaapiImageFormatType { +typedef enum { GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR = 1, /* YUV */ GST_VAAPI_IMAGE_FORMAT_TYPE_RGB, /* RGB */ GST_VAAPI_IMAGE_FORMAT_TYPE_INDEXED /* paletted */ -}; +} GstVaapiImageFormatType; struct _GstVaapiImageFormatMap { GstVaapiImageFormatType type; diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index 56af2a4e0c..9e1e66274d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -28,8 +28,6 @@ G_BEGIN_DECLS -typedef enum _GstVaapiImageFormat GstVaapiImageFormat; - /** * GstVaapiImageFormat: * @GST_VAAPI_IMAGE_NV12: @@ -51,7 +49,7 @@ typedef enum _GstVaapiImageFormat GstVaapiImageFormat; * * The set of all image formats for #GstVaapiImage. */ -enum _GstVaapiImageFormat { +typedef enum { GST_VAAPI_IMAGE_NV12 = GST_MAKE_FOURCC('N','V','1','2'), GST_VAAPI_IMAGE_YV12 = GST_MAKE_FOURCC('Y','V','1','2'), GST_VAAPI_IMAGE_I420 = GST_MAKE_FOURCC('I','4','2','0'), @@ -60,7 +58,7 @@ enum _GstVaapiImageFormat { GST_VAAPI_IMAGE_RGBA = GST_MAKE_FOURCC('R','G','B','A'), GST_VAAPI_IMAGE_ABGR = GST_MAKE_FOURCC('A','B','G','R'), GST_VAAPI_IMAGE_BGRA = GST_MAKE_FOURCC('B','G','R','A'), -}; +} GstVaapiImageFormat; gboolean gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format); diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 986c9a26b4..f742e134a7 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -26,10 +26,6 @@ G_BEGIN_DECLS -typedef enum _GstVaapiCodec GstVaapiCodec; -typedef enum _GstVaapiProfile GstVaapiProfile; -typedef enum _GstVaapiEntrypoint GstVaapiEntrypoint; - /** * GstVaapiCodec: * @GST_VAAPI_CODEC_MPEG1: MPEG-1 (ISO/IEC 11172) @@ -42,7 +38,7 @@ typedef enum _GstVaapiEntrypoint GstVaapiEntrypoint; * * The set of all codecs for #GstVaapiCodec. */ -enum _GstVaapiCodec { +typedef enum { GST_VAAPI_CODEC_MPEG1 = GST_MAKE_FOURCC('M','P','1',0), GST_VAAPI_CODEC_MPEG2 = GST_MAKE_FOURCC('M','P','2',0), GST_VAAPI_CODEC_MPEG4 = GST_MAKE_FOURCC('M','P','4',0), @@ -51,7 +47,7 @@ enum _GstVaapiCodec { GST_VAAPI_CODEC_WMV3 = GST_MAKE_FOURCC('W','M','V',0), GST_VAAPI_CODEC_VC1 = GST_MAKE_FOURCC('V','C','1',0), GST_VAAPI_CODEC_JPEG = GST_MAKE_FOURCC('J','P','G',0), -}; +} GstVaapiCodec; /** * GST_VAAPI_MAKE_PROFILE: @@ -99,7 +95,7 @@ enum _GstVaapiCodec { * * The set of all profiles for #GstVaapiProfile. */ -enum _GstVaapiProfile { +typedef enum { GST_VAAPI_PROFILE_UNKNOWN = 0, GST_VAAPI_PROFILE_MPEG1 = GST_VAAPI_MAKE_PROFILE(MPEG1,1), GST_VAAPI_PROFILE_MPEG2_SIMPLE = GST_VAAPI_MAKE_PROFILE(MPEG2,1), @@ -116,7 +112,7 @@ enum _GstVaapiProfile { GST_VAAPI_PROFILE_VC1_MAIN = GST_VAAPI_MAKE_PROFILE(VC1,2), GST_VAAPI_PROFILE_VC1_ADVANCED = GST_VAAPI_MAKE_PROFILE(VC1,3), GST_VAAPI_PROFILE_JPEG_BASELINE = GST_VAAPI_MAKE_PROFILE(JPEG,1), -}; +} GstVaapiProfile; /** * GstVaapiEntrypoint: @@ -127,12 +123,12 @@ enum _GstVaapiProfile { * * The set of all entrypoints for #GstVaapiEntrypoint */ -enum _GstVaapiEntrypoint { +typedef enum { GST_VAAPI_ENTRYPOINT_VLD = 1, GST_VAAPI_ENTRYPOINT_IDCT, GST_VAAPI_ENTRYPOINT_MOCO, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE -}; +} GstVaapiEntrypoint; GstVaapiProfile gst_vaapi_profile(VAProfile profile); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 9f51caa3fa..4b8aaeac50 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -32,10 +32,6 @@ G_BEGIN_DECLS -typedef enum _GstVaapiChromaType GstVaapiChromaType; -typedef enum _GstVaapiSurfaceStatus GstVaapiSurfaceStatus; -typedef enum _GstVaapiSurfaceRenderFlags GstVaapiSurfaceRenderFlags; - /** * GST_VAAPI_SURFACE_CAPS_NAME: * @@ -64,11 +60,11 @@ typedef enum _GstVaapiSurfaceRenderFlags GstVaapiSurfaceRenderFlags; * * The set of all chroma types for #GstVaapiSurface. */ -enum _GstVaapiChromaType { +typedef enum { GST_VAAPI_CHROMA_TYPE_YUV420 = 1, GST_VAAPI_CHROMA_TYPE_YUV422, GST_VAAPI_CHROMA_TYPE_YUV444 -}; +} GstVaapiChromaType; /** * GstVaapiSurfaceStatus: @@ -83,12 +79,12 @@ enum _GstVaapiChromaType { * * The set of all surface status for #GstVaapiSurface. */ -enum _GstVaapiSurfaceStatus { +typedef enum { GST_VAAPI_SURFACE_STATUS_IDLE = 1 << 0, GST_VAAPI_SURFACE_STATUS_RENDERING = 1 << 1, GST_VAAPI_SURFACE_STATUS_DISPLAYING = 1 << 2, GST_VAAPI_SURFACE_STATUS_SKIPPED = 1 << 3 -}; +} GstVaapiSurfaceStatus; /** * GstVaapiSurfaceRenderFlags @@ -105,7 +101,7 @@ enum _GstVaapiSurfaceStatus { * * The set of all render flags for gst_vaapi_window_put_surface(). */ -enum _GstVaapiSurfaceRenderFlags { +typedef enum { GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD = 1 << 0, GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD = 1 << 1, GST_VAAPI_PICTURE_STRUCTURE_FRAME = @@ -115,7 +111,7 @@ enum _GstVaapiSurfaceRenderFlags { ), GST_VAAPI_COLOR_STANDARD_ITUR_BT_601 = 1 << 2, GST_VAAPI_COLOR_STANDARD_ITUR_BT_709 = 1 << 3, -}; +} GstVaapiSurfaceRenderFlags; #define GST_VAAPI_TYPE_SURFACE \ (gst_vaapi_surface_get_type()) diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index ff5f9eb9e4..1ca4dd7238 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -129,11 +129,10 @@ struct _GstVaapiRectangle { * backing store, or back buffer of a frame buffer, and is free to * be re-used right away for decoding. */ -typedef enum _GstVaapiRenderMode GstVaapiRenderMode; -enum _GstVaapiRenderMode { +typedef enum { GST_VAAPI_RENDER_MODE_OVERLAY = 1, GST_VAAPI_RENDER_MODE_TEXTURE -}; +} GstVaapiRenderMode; /** * GstVaapiRotation: @@ -142,13 +141,12 @@ enum _GstVaapiRenderMode { * @GST_VAAPI_ROTATION_180: the VA display is rotated by 180°, clockwise. * @GST_VAAPI_ROTATION_270: the VA display is rotated by 270°, clockwise. */ -typedef enum _GstVaapiRotation GstVaapiRotation; -enum _GstVaapiRotation { +typedef enum { GST_VAAPI_ROTATION_0 = 0, GST_VAAPI_ROTATION_90 = 90, GST_VAAPI_ROTATION_180 = 180, GST_VAAPI_ROTATION_270 = 270, -}; +} GstVaapiRotation; G_END_DECLS diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 6ec56d1c5f..4ad4f705f8 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -57,20 +57,17 @@ G_BEGIN_DECLS typedef struct _GstVaapiPostproc GstVaapiPostproc; typedef struct _GstVaapiPostprocClass GstVaapiPostprocClass; -typedef enum _GstVaapiDeinterlaceMode GstVaapiDeinterlaceMode; -typedef enum _GstVaapiDeinterlaceMethod GstVaapiDeinterlaceMethod; - /** * GstVaapiDeinterlaceMode: * @GST_VAAPI_DEINTERLACE_MODE_AUTO: Auto detect needs for deinterlacing. * @GST_VAAPI_DEINTERLACE_MODE_INTERLACED: Force deinterlacing. * @GST_VAAPI_DEINTERLACE_MODE_DISABLED: Never perform deinterlacing. */ -enum _GstVaapiDeinterlaceMode { +typedef enum { GST_VAAPI_DEINTERLACE_MODE_AUTO = 0, GST_VAAPI_DEINTERLACE_MODE_INTERLACED, GST_VAAPI_DEINTERLACE_MODE_DISABLED, -}; +} GstVaapiDeinterlaceMode; /** * GstVaapiDeinterlaceMethod: @@ -79,12 +76,12 @@ enum _GstVaapiDeinterlaceMode { * @GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE: Motion adaptive deinterlacing algorithm. * @GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED: Motion compensated deinterlacing algorithm. */ -enum _GstVaapiDeinterlaceMethod { +typedef enum { GST_VAAPI_DEINTERLACE_METHOD_BOB = 1, GST_VAAPI_DEINTERLACE_METHOD_WEAVE, GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE, GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED, -}; +} GstVaapiDeinterlaceMethod; struct _GstVaapiPostproc { /*< private >*/ From c6d64527b552d21b79472adbed83a39146252120 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Sep 2012 11:57:59 +0200 Subject: [PATCH 0811/3781] image: don't use (void *) pointer arithmetic. --- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 717d95256d..fb2b947cc7 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -783,7 +783,7 @@ _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image) raw_image->height = va_image->height; raw_image->num_planes = va_image->num_planes; for (i = 0; i < raw_image->num_planes; i++) { - raw_image->pixels[i] = image_data + va_image->offsets[i]; + raw_image->pixels[i] = (guchar *)image_data + va_image->offsets[i]; raw_image->stride[i] = va_image->pitches[i]; } } From cdc63291821ff286c76e12dead74b5021f170ea9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Sep 2012 11:58:53 +0200 Subject: [PATCH 0812/3781] decoder: drop extraneous return for void function. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index a1af8304f9..6892dd606d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -582,7 +582,7 @@ gst_vaapi_decoder_push_surface_proxy( GstVaapiSurfaceProxy *proxy ) { - return push_surface(decoder, proxy); + push_surface(decoder, proxy); } GstVaapiDecoderStatus From 8bcfeb5a1c2d9adf323ce25b0dbff1c825eb96dd Mon Sep 17 00:00:00 2001 From: Philip Lorenz Date: Tue, 4 Sep 2012 13:54:19 +0200 Subject: [PATCH 0813/3781] vaapidecode: acquire lock only if the mutex exists. When playback stops the GstVaapiDecode object is reset into a clean state. However, surfaces may still be referenced by library users and unreferencing them after the reset triggers an access to an unset mutex. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6980d47d26..cd2d7f6f8c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -174,6 +174,9 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) static void gst_vaapidecode_release(GstVaapiDecode *decode, GObject *dead_object) { + if (!decode->decoder_mutex || !decode->decoder_ready) + return; + g_mutex_lock(decode->decoder_mutex); g_cond_signal(decode->decoder_ready); g_mutex_unlock(decode->decoder_mutex); From 6b70bf3139dc21c58578098cd3c11d8ae69b8ac7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Sep 2012 15:31:09 +0200 Subject: [PATCH 0814/3781] pkgconfig: fix dependencies and slightly improve description. Drop @LIBVA_EXTRA_{CFLAGS,LIBS}@ substitutions and slightly improve descriptions with clearer renderer names. --- pkgconfig/gstreamer-vaapi-glx.pc.in | 8 ++++---- pkgconfig/gstreamer-vaapi-x11.pc.in | 8 ++++---- pkgconfig/gstreamer-vaapi.pc.in | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pkgconfig/gstreamer-vaapi-glx.pc.in b/pkgconfig/gstreamer-vaapi-glx.pc.in index 73b4c1bd7a..86dad312d4 100644 --- a/pkgconfig/gstreamer-vaapi-glx.pc.in +++ b/pkgconfig/gstreamer-vaapi-glx.pc.in @@ -4,9 +4,9 @@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ -Name: GStreamer VA-API (glx) Plugins Libraries -Description: Streaming media framework, VA-API (glx) plugins libraries +Name: GStreamer VA-API (GLX) Plugins Libraries +Description: Streaming media framework, VA-API (GLX) plugins libraries Requires: gstreamer-vaapi-@GST_MAJORMINOR@ @LIBVA_GLX_PKGNAME@ Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-glx-@GST_MAJORMINOR@ @LIBVA_EXTRA_LIBS@ -Cflags: -I${includedir} @LIBVA_EXTRA_CFLAGS@ +Libs: -L${libdir} -lgstvaapi-glx-@GST_MAJORMINOR@ +Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi-x11.pc.in b/pkgconfig/gstreamer-vaapi-x11.pc.in index 1f258dec59..fc52ffcee3 100644 --- a/pkgconfig/gstreamer-vaapi-x11.pc.in +++ b/pkgconfig/gstreamer-vaapi-x11.pc.in @@ -4,9 +4,9 @@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ -Name: GStreamer VA-API (x11) Plugins Libraries -Description: Streaming media framework, VA-API (x11) plugins libraries +Name: GStreamer VA-API (X11) Plugins Libraries +Description: Streaming media framework, VA-API (X11) plugins libraries Requires: gstreamer-vaapi-@GST_MAJORMINOR@ @LIBVA_X11_PKGNAME@ Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-x11-@GST_MAJORMINOR@ @LIBVA_EXTRA_LIBS@ -Cflags: -I${includedir} @LIBVA_EXTRA_CFLAGS@ +Libs: -L${libdir} -lgstvaapi-x11-@GST_MAJORMINOR@ +Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi.pc.in b/pkgconfig/gstreamer-vaapi.pc.in index 281dee02c1..004affab5e 100644 --- a/pkgconfig/gstreamer-vaapi.pc.in +++ b/pkgconfig/gstreamer-vaapi.pc.in @@ -8,5 +8,5 @@ Name: GStreamer VA-API Plugins Libraries Description: Streaming media framework, VA-API plugins libraries Requires: gstreamer-@GST_MAJORMINOR@ gstreamer-base-@GST_MAJORMINOR@ @LIBVA_PKGNAME@ Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-@GST_MAJORMINOR@ @LIBVA_EXTRA_LIBS@ -Cflags: -I${includedir} @LIBVA_EXTRA_CFLAGS@ +Libs: -L${libdir} -lgstvaapi-@GST_MAJORMINOR@ +Cflags: -I${includedir} From a8624d6a79b227a47805fab1546769601927d77a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Sep 2012 16:11:12 +0200 Subject: [PATCH 0815/3781] plugins: fix build in strict ISO C mode. --- gst/vaapi/gstvaapi.c | 2 +- gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapidownload.c | 2 +- gst/vaapi/gstvaapipostproc.c | 2 +- gst/vaapi/gstvaapisink.c | 2 +- gst/vaapi/gstvaapiupload.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 23be2b3832..5e115c4799 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -62,4 +62,4 @@ GST_PLUGIN_DEFINE( PACKAGE_VERSION, "LGPL", PACKAGE, - PACKAGE_BUGREPORT); + PACKAGE_BUGREPORT) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index cd2d7f6f8c..7b85636877 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -103,7 +103,7 @@ G_DEFINE_TYPE_WITH_CODE( G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapidecode_implements_iface_init); G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init)); + gst_video_context_interface_init)) static gboolean gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps); diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 56ae902dce..cb914645e5 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -114,7 +114,7 @@ G_DEFINE_TYPE_WITH_CODE( G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapidownload_implements_iface_init); G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init)); + gst_video_context_interface_init)) static gboolean gst_vaapidownload_start(GstBaseTransform *trans); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6f6a818518..06923f680b 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -88,7 +88,7 @@ G_DEFINE_TYPE_WITH_CODE( G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapipostproc_implements_iface_init); G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init)); + gst_video_context_interface_init)) enum { PROP_0, diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 3c0d5009fd..469708275e 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -97,7 +97,7 @@ G_DEFINE_TYPE_WITH_CODE( G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_vaapisink_video_context_iface_init); G_IMPLEMENT_INTERFACE(GST_TYPE_X_OVERLAY, - gst_vaapisink_xoverlay_iface_init)); + gst_vaapisink_xoverlay_iface_init)) enum { PROP_0, diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index d0eb20fcab..5e2ce1ba05 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -90,7 +90,7 @@ G_DEFINE_TYPE_WITH_CODE( G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapiupload_implements_iface_init); G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init)); + gst_video_context_interface_init)) /* * Direct rendering levels (direct-rendering) From 61cc02f54b573d3daeb678102cc00a4ac54b77ca Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Sep 2012 16:14:11 +0200 Subject: [PATCH 0816/3781] libs: fix build in strict ISO C mode. --- gst-libs/gst/vaapi/gstvaapicontext.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.c | 2 +- gst-libs/gst/vaapi/gstvaapiobject.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 2 +- gst-libs/gst/vaapi/gstvaapitexture.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 6 ++---- gst-libs/gst/vaapi/gstvaapivalue.c | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- 31 files changed, 32 insertions(+), 34 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 52e81e4020..5030a5299a 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -40,7 +40,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiContext, gst_vaapi_context, GST_VAAPI_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiContext, gst_vaapi_context, GST_VAAPI_TYPE_OBJECT) #define GST_VAAPI_CONTEXT_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 6892dd606d..0865dba19e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -35,7 +35,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDecoder, gst_vaapi_decoder, G_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiDecoder, gst_vaapi_decoder, G_TYPE_OBJECT) enum { PROP_0, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 89fef9117b..05bd927bb3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -240,7 +240,7 @@ gst_vaapi_slice_h264_new( G_DEFINE_TYPE(GstVaapiDecoderH264, gst_vaapi_decoder_h264, - GST_VAAPI_TYPE_DECODER); + GST_VAAPI_TYPE_DECODER) #define GST_VAAPI_DECODER_H264_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 3200397245..540b0e3e90 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -39,7 +39,7 @@ G_DEFINE_TYPE(GstVaapiDecoderJpeg, gst_vaapi_decoder_jpeg, - GST_VAAPI_TYPE_DECODER); + GST_VAAPI_TYPE_DECODER) #define GST_VAAPI_DECODER_JPEG_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index cabf379a49..5e2c39297c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -40,7 +40,7 @@ G_DEFINE_TYPE(GstVaapiDecoderMpeg2, gst_vaapi_decoder_mpeg2, - GST_VAAPI_TYPE_DECODER); + GST_VAAPI_TYPE_DECODER) #define GST_VAAPI_DECODER_MPEG2_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index acf9d0d1ce..af2945f777 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -39,7 +39,7 @@ G_DEFINE_TYPE(GstVaapiDecoderMpeg4, gst_vaapi_decoder_mpeg4, - GST_VAAPI_TYPE_DECODER); + GST_VAAPI_TYPE_DECODER) #define GST_VAAPI_DECODER_MPEG4_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 63fbc7307b..7ee0594d84 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -38,7 +38,7 @@ G_DEFINE_TYPE(GstVaapiDecoderVC1, gst_vaapi_decoder_vc1, - GST_VAAPI_TYPE_DECODER); + GST_VAAPI_TYPE_DECODER) #define GST_VAAPI_DECODER_VC1_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 887664374e..40ac5a65cf 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -38,7 +38,7 @@ GST_DEBUG_CATEGORY(gst_debug_vaapi); -G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT) typedef struct _GstVaapiConfig GstVaapiConfig; struct _GstVaapiConfig { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 6a1d148272..8178c2c2fb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -41,7 +41,7 @@ G_DEFINE_TYPE(GstVaapiDisplayDRM, gst_vaapi_display_drm, - GST_VAAPI_TYPE_DISPLAY); + GST_VAAPI_TYPE_DISPLAY) enum { PROP_0, diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 87ac84a83d..10077ee1ce 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -39,7 +39,7 @@ G_DEFINE_TYPE(GstVaapiDisplayGLX, gst_vaapi_display_glx, - GST_VAAPI_TYPE_DISPLAY_X11); + GST_VAAPI_TYPE_DISPLAY_X11) static void gst_vaapi_display_glx_finalize(GObject *object) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 6ebf9da76a..1ebeb3d308 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -35,7 +35,7 @@ G_DEFINE_TYPE(GstVaapiDisplayWayland, gst_vaapi_display_wayland, - GST_VAAPI_TYPE_DISPLAY); + GST_VAAPI_TYPE_DISPLAY) enum { PROP_0, diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index f00b5af910..d632e48711 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -41,7 +41,7 @@ G_DEFINE_TYPE(GstVaapiDisplayX11, gst_vaapi_display_x11, - GST_VAAPI_TYPE_DISPLAY); + GST_VAAPI_TYPE_DISPLAY) enum { PROP_0, diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index fb2b947cc7..0961234bf4 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -35,7 +35,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, GST_VAAPI_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, GST_VAAPI_TYPE_OBJECT) #define GST_VAAPI_IMAGE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 159cb308ea..26462d3b2f 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -33,7 +33,7 @@ G_DEFINE_TYPE( GstVaapiImagePool, gst_vaapi_image_pool, - GST_VAAPI_TYPE_VIDEO_POOL); + GST_VAAPI_TYPE_VIDEO_POOL) #define GST_VAAPI_IMAGE_POOL_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index ad3d139b09..7e7b1913e8 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -33,7 +33,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiObject, gst_vaapi_object, G_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiObject, gst_vaapi_object, G_TYPE_OBJECT) enum { PROP_0, diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index cfd7fd3a38..a09f246333 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -35,7 +35,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, GST_VAAPI_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, GST_VAAPI_TYPE_OBJECT) #define GST_VAAPI_SUBPICTURE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index b471de7d42..745495d47e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -37,7 +37,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiSurface, gst_vaapi_surface, GST_VAAPI_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiSurface, gst_vaapi_surface, GST_VAAPI_TYPE_OBJECT) #define GST_VAAPI_SURFACE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index b3e95380ae..528d6f4d52 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -33,7 +33,7 @@ G_DEFINE_TYPE( GstVaapiSurfacePool, gst_vaapi_surface_pool, - GST_VAAPI_TYPE_VIDEO_POOL); + GST_VAAPI_TYPE_VIDEO_POOL) #define GST_VAAPI_SURFACE_POOL_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index aa4103e068..1e3a5b70e7 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -32,7 +32,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiSurfaceProxy, gst_vaapi_surface_proxy, G_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiSurfaceProxy, gst_vaapi_surface_proxy, G_TYPE_OBJECT) #define GST_VAAPI_SURFACE_PROXY_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 97025f2601..1b38ef330a 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -36,7 +36,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiTexture, gst_vaapi_texture, GST_VAAPI_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiTexture, gst_vaapi_texture, GST_VAAPI_TYPE_OBJECT) #define GST_VAAPI_TEXTURE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 3821181394..4dbf834e2e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -625,13 +625,11 @@ get_proc_address_func(void) GLXGetProcAddressProc get_proc_func; dlerror(); - get_proc_func = (GLXGetProcAddressProc) - dlsym(RTLD_DEFAULT, "glXGetProcAddress"); + *(void **)(&get_proc_func) = dlsym(RTLD_DEFAULT, "glXGetProcAddress"); if (!dlerror()) return get_proc_func; - get_proc_func = (GLXGetProcAddressProc) - dlsym(RTLD_DEFAULT, "glXGetProcAddressARB"); + *(void **)(&get_proc_func) = dlsym(RTLD_DEFAULT, "glXGetProcAddressARB"); if (!dlerror()) return get_proc_func; diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 19d95a7169..401770e759 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -131,7 +131,7 @@ static const GTypeValueTable gst_vaapi_id_value_table = { gst_vaapi_value_id_lcopy }; -GST_VAAPI_TYPE_DEFINE(id, "GstVaapiID"); +GST_VAAPI_TYPE_DEFINE(id, "GstVaapiID") /** * gst_vaapi_value_get_id: diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 18b58ef972..0a108535f9 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -35,7 +35,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, GST_TYPE_SURFACE_BUFFER); +G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, GST_TYPE_SURFACE_BUFFER) #define GST_VAAPI_VIDEO_BUFFER_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c index c531f79359..7ab4b51e1c 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c @@ -38,7 +38,7 @@ G_DEFINE_TYPE(GstVaapiVideoBufferGLX, gst_vaapi_video_buffer_glx, - GST_VAAPI_TYPE_VIDEO_BUFFER); + GST_VAAPI_TYPE_VIDEO_BUFFER) static void gst_vaapi_video_buffer_glx_class_init(GstVaapiVideoBufferGLXClass *klass) diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index 0ea968fb87..26de76803f 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -32,7 +32,7 @@ static void gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterfa G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoConverterGLX, gst_vaapi_video_converter_glx, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (GST_TYPE_SURFACE_CONVERTER, - gst_vaapi_video_converter_glx_iface_init)); + gst_vaapi_video_converter_glx_iface_init)) struct _GstVaapiVideoConverterGLXPrivate { GstVaapiTexture *texture; diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index ea24befd90..774305ee1c 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -30,7 +30,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiVideoPool, gst_vaapi_video_pool, G_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiVideoPool, gst_vaapi_video_pool, G_TYPE_OBJECT) #define GST_VAAPI_VIDEO_POOL_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 56ef8ed08c..9fb41489cc 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -32,7 +32,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, GST_VAAPI_TYPE_OBJECT); +G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, GST_VAAPI_TYPE_OBJECT) #define GST_VAAPI_WINDOW_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c index 6303480e65..812bf51258 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -32,7 +32,7 @@ G_DEFINE_TYPE(GstVaapiWindowDRM, gst_vaapi_window_drm, - GST_VAAPI_TYPE_WINDOW); + GST_VAAPI_TYPE_WINDOW) static gboolean gst_vaapi_window_drm_show(GstVaapiWindow *window) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 45c040d700..9266bbbc06 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -37,7 +37,7 @@ G_DEFINE_TYPE(GstVaapiWindowGLX, gst_vaapi_window_glx, - GST_VAAPI_TYPE_WINDOW_X11); + GST_VAAPI_TYPE_WINDOW_X11) #define GST_VAAPI_WINDOW_GLX_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 5925fe4f1b..ac2882e681 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -38,7 +38,7 @@ G_DEFINE_TYPE(GstVaapiWindowWayland, gst_vaapi_window_wayland, - GST_VAAPI_TYPE_WINDOW); + GST_VAAPI_TYPE_WINDOW) #define GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 51de0615bc..9a5db7943a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -38,7 +38,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiWindowX11, gst_vaapi_window_x11, GST_VAAPI_TYPE_WINDOW); +G_DEFINE_TYPE(GstVaapiWindowX11, gst_vaapi_window_x11, GST_VAAPI_TYPE_WINDOW) #define GST_VAAPI_WINDOW_X11_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ From cf75d048a174a8349c84cffbad7ba4151718d817 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Sep 2012 16:15:40 +0200 Subject: [PATCH 0817/3781] mpeg4: fix debug info for unsupported profile. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index af2945f777..84e20203d4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -308,7 +308,7 @@ decode_sequence(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size profile = GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE; break; default: - GST_DEBUG("unsupported profile %d", profile); + GST_DEBUG("unsupported profile %d", vos_hdr->profile); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } if (priv->profile != profile) { From d895e17db88d7d2e7886fe0eee51753fbfee2901 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Sep 2012 16:41:16 +0200 Subject: [PATCH 0818/3781] vaapipostproc: fix deinterlace-{mode,method} types definition. --- gst/vaapi/gstvaapipostproc.c | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 06923f680b..a528131f63 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -100,15 +100,15 @@ enum { #define DEFAULT_DEINTERLACE_MODE GST_VAAPI_DEINTERLACE_MODE_AUTO #define DEFAULT_DEINTERLACE_METHOD GST_VAAPI_DEINTERLACE_METHOD_BOB -#define GST_TYPE_VAAPI_DEINTERLACE_MODES \ - gst_vaapi_deinterlace_modes_get_type() +#define GST_VAAPI_TYPE_DEINTERLACE_MODE \ + gst_vaapi_deinterlace_mode_get_type() static GType -gst_vaapi_deinterlace_modes_get_type(void) +gst_vaapi_deinterlace_mode_get_type(void) { - static GType deinterlace_modes_type = 0; + static GType deinterlace_mode_type = 0; - static const GEnumValue modes_types[] = { + static const GEnumValue mode_types[] = { { GST_VAAPI_DEINTERLACE_MODE_AUTO, "Auto detection", "auto" }, { GST_VAAPI_DEINTERLACE_MODE_INTERLACED, @@ -118,22 +118,22 @@ gst_vaapi_deinterlace_modes_get_type(void) { 0, NULL, NULL }, }; - if (!deinterlace_modes_type) { - deinterlace_modes_type = - g_enum_register_static("GstVaapiDeinterlaceModes", modes_types); + if (!deinterlace_mode_type) { + deinterlace_mode_type = + g_enum_register_static("GstVaapiDeinterlaceMode", mode_types); } - return deinterlace_modes_type; + return deinterlace_mode_type; } -#define GST_TYPE_VAAPI_DEINTERLACE_METHODS \ - gst_vaapi_deinterlace_methods_get_type() +#define GST_VAAPI_TYPE_DEINTERLACE_METHOD \ + gst_vaapi_deinterlace_method_get_type() static GType -gst_vaapi_deinterlace_methods_get_type(void) +gst_vaapi_deinterlace_method_get_type(void) { - static GType deinterlace_methods_type = 0; + static GType deinterlace_method_type = 0; - static const GEnumValue methods_types[] = { + static const GEnumValue method_types[] = { { GST_VAAPI_DEINTERLACE_METHOD_BOB, "Bob deinterlacing", "bob" }, #if 0 @@ -148,11 +148,11 @@ gst_vaapi_deinterlace_methods_get_type(void) { 0, NULL, NULL }, }; - if (!deinterlace_methods_type) { - deinterlace_methods_type = - g_enum_register_static("GstVaapiDeinterlaceMethods", methods_types); + if (!deinterlace_method_type) { + deinterlace_method_type = + g_enum_register_static("GstVaapiDeinterlaceMethod", method_types); } - return deinterlace_methods_type; + return deinterlace_method_type; } static inline GstVaapiPostproc * @@ -681,7 +681,7 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) g_param_spec_enum("deinterlace", "Deinterlace", "Deinterlace mode to use", - GST_TYPE_VAAPI_DEINTERLACE_MODES, + GST_VAAPI_TYPE_DEINTERLACE_MODE, DEFAULT_DEINTERLACE_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); @@ -696,7 +696,7 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) g_param_spec_enum("deinterlace-method", "Deinterlace method", "Deinterlace method to use", - GST_TYPE_VAAPI_DEINTERLACE_METHODS, + GST_VAAPI_TYPE_DEINTERLACE_METHOD, DEFAULT_DEINTERLACE_METHOD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } From 4ca1f3f47c44db2347adf5606f058250179f38c7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 10 Sep 2012 18:15:02 +0200 Subject: [PATCH 0819/3781] context: allow number of reference frames to be set. Make it possible to specify the maximum number of references to use within a single VA context. This helps reducing GPU memory allocations to the useful number of references to be used. --- gst-libs/gst/vaapi/gstvaapicontext.c | 123 ++++++++++++++++++++++----- gst-libs/gst/vaapi/gstvaapicontext.h | 26 +++++- 2 files changed, 124 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 5030a5299a..1862e38080 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -65,6 +65,7 @@ struct _GstVaapiContextPrivate { GstVaapiEntrypoint entrypoint; guint width; guint height; + guint ref_frames; guint is_constructed : 1; }; @@ -74,9 +75,22 @@ enum { PROP_PROFILE, PROP_ENTRYPOINT, PROP_WIDTH, - PROP_HEIGHT + PROP_HEIGHT, + PROP_REF_FRAMES }; +static guint +get_max_ref_frames(GstVaapiProfile profile) +{ + guint ref_frames; + + switch (gst_vaapi_profile_get_codec(profile)) { + case GST_VAAPI_CODEC_H264: ref_frames = 16; break; + default: ref_frames = 2; break; + } + return ref_frames; +} + static GstVaapiOverlayRectangle * overlay_rectangle_new(GstVaapiContext *context) { @@ -218,7 +232,7 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context) GstVaapiContextPrivate * const priv = context->priv; GstCaps *caps; GstVaapiSurface *surface; - guint i, num_ref_frames, num_surfaces; + guint i, num_surfaces; /* Number of scratch surfaces beyond those used as reference */ const guint SCRATCH_SURFACES_COUNT = 4; @@ -251,11 +265,7 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context) return FALSE; } - num_ref_frames = 2; - if (gst_vaapi_profile_get_codec(priv->profile) == GST_VAAPI_CODEC_H264) - num_ref_frames = 16; - num_surfaces = num_ref_frames + SCRATCH_SURFACES_COUNT; - + num_surfaces = priv->ref_frames + SCRATCH_SURFACES_COUNT; gst_vaapi_video_pool_set_capacity(priv->surfaces_pool, num_surfaces); for (i = priv->surfaces->len; i < num_surfaces; i++) { @@ -397,6 +407,9 @@ gst_vaapi_context_set_property( case PROP_HEIGHT: priv->height = g_value_get_uint(value); break; + case PROP_REF_FRAMES: + priv->ref_frames = g_value_get_uint(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -427,6 +440,9 @@ gst_vaapi_context_get_property( case PROP_HEIGHT: g_value_set_uint(value, priv->height); break; + case PROP_REF_FRAMES: + g_value_set_uint(value, priv->ref_frames); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -479,6 +495,15 @@ gst_vaapi_context_class_init(GstVaapiContextClass *klass) "The height of the decoded surfaces", 0, G_MAXINT32, 0, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_REF_FRAMES, + g_param_spec_uint("ref-frames", + "Reference Frames", + "The number of reference frames", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -495,6 +520,7 @@ gst_vaapi_context_init(GstVaapiContext *context) priv->entrypoint = 0; priv->width = 0; priv->height = 0; + priv->ref_frames = 0; } /** @@ -515,26 +541,51 @@ gst_vaapi_context_new( GstVaapiDisplay *display, GstVaapiProfile profile, GstVaapiEntrypoint entrypoint, - unsigned int width, - unsigned int height + guint width, + guint height ) +{ + GstVaapiContextInfo info; + + info.profile = profile; + info.entrypoint = entrypoint; + info.width = width; + info.height = height; + info.ref_frames = get_max_ref_frames(profile); + return gst_vaapi_context_new_full(display, &info); +} + +/** + * gst_vaapi_context_new_full: + * @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_full(GstVaapiDisplay *display, GstVaapiContextInfo *cip) { GstVaapiContext *context; g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(profile, NULL); - g_return_val_if_fail(entrypoint, NULL); - g_return_val_if_fail(width > 0, NULL); - g_return_val_if_fail(height > 0, NULL); + g_return_val_if_fail(cip->profile, NULL); + g_return_val_if_fail(cip->entrypoint, NULL); + g_return_val_if_fail(cip->width > 0, NULL); + g_return_val_if_fail(cip->height > 0, NULL); context = g_object_new( GST_VAAPI_TYPE_CONTEXT, "display", display, "id", GST_VAAPI_ID(VA_INVALID_ID), - "profile", profile, - "entrypoint", entrypoint, - "width", width, - "height", height, + "profile", cip->profile, + "entrypoint", cip->entrypoint, + "width", cip->width, + "height", cip->height, + "ref-frames", cip->ref_frames, NULL ); if (!context->priv->is_constructed) { @@ -565,22 +616,48 @@ gst_vaapi_context_reset( unsigned int width, unsigned int height ) +{ + GstVaapiContextPrivate * const priv = context->priv; + GstVaapiContextInfo info; + + info.profile = profile; + info.entrypoint = entrypoint; + info.width = width; + info.height = height; + info.ref_frames = priv->ref_frames; + + return gst_vaapi_context_reset_full(context, &info); +} + +/** + * gst_vaapi_context_reset_full: + * @context: a #GstVaapiContext + * @cip: a pointer to the new #GstVaapiContextInfo details + * + * Resets @context to the configuration specified by @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_full(GstVaapiContext *context, GstVaapiContextInfo *cip) { GstVaapiContextPrivate * const priv = context->priv; gboolean size_changed, codec_changed; - size_changed = priv->width != width || priv->height != height; + size_changed = priv->width != cip->width || priv->height != cip->height; if (size_changed) { gst_vaapi_context_destroy_surfaces(context); - priv->width = width; - priv->height = height; + priv->width = cip->width; + priv->height = cip->height; } - codec_changed = priv->profile != profile || priv->entrypoint != entrypoint; + codec_changed = priv->profile != cip->profile || priv->entrypoint != cip->entrypoint; if (codec_changed) { gst_vaapi_context_destroy(context); - priv->profile = profile; - priv->entrypoint = entrypoint; + priv->profile = cip->profile; + priv->entrypoint = cip->entrypoint; } if (size_changed && !gst_vaapi_context_create_surfaces(context)) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 1187c400d1..cffbd7ebb0 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -56,9 +56,25 @@ G_BEGIN_DECLS GstVaapiContextClass)) typedef struct _GstVaapiContext GstVaapiContext; +typedef struct _GstVaapiContextInfo GstVaapiContextInfo; typedef struct _GstVaapiContextPrivate GstVaapiContextPrivate; typedef struct _GstVaapiContextClass GstVaapiContextClass; +/** + * 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 { + GstVaapiProfile profile; + GstVaapiEntrypoint entrypoint; + guint width; + guint height; + guint ref_frames; +}; + /** * GstVaapiContext: * @@ -93,15 +109,21 @@ gst_vaapi_context_new( guint height ); +GstVaapiContext * +gst_vaapi_context_new_full(GstVaapiDisplay *display, GstVaapiContextInfo *cip); + gboolean gst_vaapi_context_reset( GstVaapiContext *context, GstVaapiProfile profile, GstVaapiEntrypoint entrypoint, - unsigned int width, - unsigned int height + guint width, + guint height ); +gboolean +gst_vaapi_context_reset_full(GstVaapiContext *context, GstVaapiContextInfo *cip); + GstVaapiID gst_vaapi_context_get_id(GstVaapiContext *context); From 893e45ecb507376566d0edaa1f6bfa6a2907d42f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 10 Sep 2012 18:17:10 +0200 Subject: [PATCH 0820/3781] context: JPEG codec does not need any reference frame. --- gst-libs/gst/vaapi/gstvaapicontext.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 1862e38080..fe15bdc914 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -86,6 +86,7 @@ get_max_ref_frames(GstVaapiProfile profile) switch (gst_vaapi_profile_get_codec(profile)) { case GST_VAAPI_CODEC_H264: ref_frames = 16; break; + case GST_VAAPI_CODEC_JPEG: ref_frames = 0; break; default: ref_frames = 2; break; } return ref_frames; From a10b3d30326bb1a8141c8a9c604d4e4c41c73f25 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 10 Sep 2012 18:26:51 +0200 Subject: [PATCH 0821/3781] decoder: cope with new GstVaapiContextInfo based API. Update decoders to report the maximum number of reference frames to use. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 32 ++--- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 132 +++++++++++---------- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 13 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 13 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 13 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 7 +- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 13 +- 7 files changed, 121 insertions(+), 102 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 0865dba19e..148a6a23cc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -529,31 +529,23 @@ gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced) gboolean gst_vaapi_decoder_ensure_context( - GstVaapiDecoder *decoder, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, - guint width, - guint height + GstVaapiDecoder *decoder, + GstVaapiContextInfo *cip ) { GstVaapiDecoderPrivate * const priv = decoder->priv; - gst_vaapi_decoder_set_picture_size(decoder, width, height); - - if (priv->context) - return gst_vaapi_context_reset(priv->context, - profile, entrypoint, width, height); - - priv->context = gst_vaapi_context_new( - priv->display, - profile, - entrypoint, - width, - height - ); - if (!priv->context) - return FALSE; + gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height); + if (priv->context) { + if (!gst_vaapi_context_reset_full(priv->context, cip)) + return FALSE; + } + else { + priv->context = gst_vaapi_context_new_full(priv->display, cip); + if (!priv->context) + return FALSE; + } priv->va_context = gst_vaapi_context_get_id(priv->context); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 05bd927bb3..d0e24326c3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -306,6 +306,66 @@ clear_references( guint *picture_count ); +/* Get number of reference frames to use */ +static guint +get_max_dec_frame_buffering(GstH264SPS *sps) +{ + guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs; + + /* Table A-1 - Level limits */ + switch (sps->level_idc) { + case 10: MaxDpbMbs = 396; break; + case 11: MaxDpbMbs = 900; break; + case 12: MaxDpbMbs = 2376; break; + case 13: MaxDpbMbs = 2376; break; + case 20: MaxDpbMbs = 2376; break; + case 21: MaxDpbMbs = 4752; break; + case 22: MaxDpbMbs = 8100; break; + case 30: MaxDpbMbs = 8100; break; + case 31: MaxDpbMbs = 18000; break; + case 32: MaxDpbMbs = 20480; break; + case 40: MaxDpbMbs = 32768; break; + case 41: MaxDpbMbs = 32768; break; + case 42: MaxDpbMbs = 34816; break; + case 50: MaxDpbMbs = 110400; break; + case 51: MaxDpbMbs = 184320; break; + default: + g_assert(0 && "unhandled level"); + break; + } + + PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) * + (sps->pic_height_in_map_units_minus1 + 1) * + (sps->frame_mbs_only_flag ? 1 : 2)); + max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs; + + /* VUI parameters */ + if (sps->vui_parameters_present_flag) { + GstH264VUIParams * const vui_params = &sps->vui_parameters; + if (vui_params->bitstream_restriction_flag) + max_dec_frame_buffering = vui_params->max_dec_frame_buffering; + else { + switch (sps->profile_idc) { + case 44: // CAVLC 4:4:4 Intra profile + case 86: // Scalable High profile + case 100: // High profile + case 110: // High 10 profile + case 122: // High 4:2:2 profile + case 244: // High 4:4:4 Predictive profile + if (sps->constraint_set3_flag) + max_dec_frame_buffering = 0; + break; + } + } + } + + if (max_dec_frame_buffering > 16) + max_dec_frame_buffering = 16; + else if (max_dec_frame_buffering < sps->num_ref_frames) + max_dec_frame_buffering = sps->num_ref_frames; + return MAX(1, max_dec_frame_buffering); +} + static void dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index) { @@ -415,64 +475,12 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return TRUE; } -static void +static inline void dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) { GstVaapiDecoderH264Private * const priv = decoder->priv; - guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs; - /* Table A-1 - Level limits */ - switch (sps->level_idc) { - case 10: MaxDpbMbs = 396; break; - case 11: MaxDpbMbs = 900; break; - case 12: MaxDpbMbs = 2376; break; - case 13: MaxDpbMbs = 2376; break; - case 20: MaxDpbMbs = 2376; break; - case 21: MaxDpbMbs = 4752; break; - case 22: MaxDpbMbs = 8100; break; - case 30: MaxDpbMbs = 8100; break; - case 31: MaxDpbMbs = 18000; break; - case 32: MaxDpbMbs = 20480; break; - case 40: MaxDpbMbs = 32768; break; - case 41: MaxDpbMbs = 32768; break; - case 42: MaxDpbMbs = 34816; break; - case 50: MaxDpbMbs = 110400; break; - case 51: MaxDpbMbs = 184320; break; - default: - g_assert(0 && "unhandled level"); - break; - } - - PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) * - (sps->pic_height_in_map_units_minus1 + 1) * - (sps->frame_mbs_only_flag ? 1 : 2)); - max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs; - - /* VUI parameters */ - if (sps->vui_parameters_present_flag) { - GstH264VUIParams * const vui_params = &sps->vui_parameters; - if (vui_params->bitstream_restriction_flag) - max_dec_frame_buffering = vui_params->max_dec_frame_buffering; - else { - switch (sps->profile_idc) { - case 44: // CAVLC 4:4:4 Intra profile - case 86: // Scalable High profile - case 100: // High profile - case 110: // High 10 profile - case 122: // High 4:2:2 profile - case 244: // High 4:4:4 Predictive profile - if (sps->constraint_set3_flag) - max_dec_frame_buffering = 0; - break; - } - } - } - - if (max_dec_frame_buffering > 16) - max_dec_frame_buffering = 16; - else if (max_dec_frame_buffering < sps->num_ref_frames) - max_dec_frame_buffering = sps->num_ref_frames; - priv->dpb_size = MAX(1, max_dec_frame_buffering); + priv->dpb_size = get_max_dec_frame_buffering(sps); GST_DEBUG("DPB size %u", priv->dpb_size); } @@ -632,13 +640,15 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) } if (reset_context) { - success = gst_vaapi_decoder_ensure_context( - GST_VAAPI_DECODER(decoder), - priv->profile, - entrypoint, - priv->width, priv->height - ); - if (!success) + GstVaapiContextInfo info; + + info.profile = priv->profile; + info.entrypoint = entrypoint; + info.width = priv->width; + info.height = priv->height; + info.ref_frames = get_max_dec_frame_buffering(sps); + + if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; priv->has_context = TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 540b0e3e90..ddeb24dacc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -137,11 +137,16 @@ ensure_context(GstVaapiDecoderJpeg *decoder) } if (reset_context) { - reset_context = gst_vaapi_decoder_ensure_context( + GstVaapiContextInfo info; + + info.profile = priv->profile; + info.entrypoint = entrypoint; + info.width = priv->width; + info.height = priv->height; + info.ref_frames = 2; + reset_context = gst_vaapi_decoder_ensure_context( GST_VAAPI_DECODER(decoder), - priv->profile, - entrypoint, - priv->width, priv->height + &info ); if (!reset_context) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 5e2c39297c..21bbee6dc3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -410,11 +410,16 @@ ensure_context(GstVaapiDecoderMpeg2 *decoder) } if (reset_context) { - reset_context = gst_vaapi_decoder_ensure_context( + GstVaapiContextInfo info; + + info.profile = priv->hw_profile; + info.entrypoint = entrypoint; + info.width = priv->width; + info.height = priv->height; + info.ref_frames = 2; + reset_context = gst_vaapi_decoder_ensure_context( GST_VAAPI_DECODER(decoder), - priv->hw_profile, - entrypoint, - priv->width, priv->height + &info ); if (!reset_context) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 84e20203d4..f408cd634c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -205,11 +205,16 @@ ensure_context(GstVaapiDecoderMpeg4 *decoder) } if (reset_context) { - reset_context = gst_vaapi_decoder_ensure_context( + GstVaapiContextInfo info; + + info.profile = priv->profile; + info.entrypoint = entrypoint; + info.width = priv->width; + info.height = priv->height; + info.ref_frames = 2; + reset_context = gst_vaapi_decoder_ensure_context( GST_VAAPI_DECODER(decoder), - priv->profile, - entrypoint, - priv->width, priv->height + &info ); if (!reset_context) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 66646d3d9c..c753c27fd6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -159,11 +159,8 @@ gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced); G_GNUC_INTERNAL gboolean gst_vaapi_decoder_ensure_context( - GstVaapiDecoder *decoder, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, - guint width, - guint height + GstVaapiDecoder *decoder, + GstVaapiContextInfo *cip ); G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 7ee0594d84..d54a18ae92 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -194,11 +194,16 @@ ensure_context(GstVaapiDecoderVC1 *decoder) } if (reset_context) { - reset_context = gst_vaapi_decoder_ensure_context( + GstVaapiContextInfo info; + + info.profile = priv->profile; + info.entrypoint = entrypoint; + info.width = priv->width; + info.height = priv->height; + info.ref_frames = 2; + reset_context = gst_vaapi_decoder_ensure_context( GST_VAAPI_DECODER(decoder), - priv->profile, - entrypoint, - priv->width, priv->height + &info ); if (!reset_context) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; From e4d27fba6b9f6accadb7a428bf8423a41c5392f7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 11 Sep 2012 10:59:10 +0200 Subject: [PATCH 0822/3781] surfaceproxy: add "duration" property. --- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 54 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 19 ++++++++ 2 files changed, 73 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 1e3a5b70e7..dc5d52ff1c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -43,6 +43,7 @@ struct _GstVaapiSurfaceProxyPrivate { GstVaapiContext *context; GstVaapiSurface *surface; GstClockTime timestamp; + GstClockTime duration; guint is_interlaced : 1; guint tff : 1; }; @@ -53,6 +54,7 @@ enum { PROP_CONTEXT, PROP_SURFACE, PROP_TIMESTAMP, + PROP_DURATION, PROP_INTERLACED, PROP_TFF }; @@ -88,6 +90,9 @@ gst_vaapi_surface_proxy_set_property( case PROP_TIMESTAMP: gst_vaapi_surface_proxy_set_timestamp(proxy, g_value_get_uint64(value)); break; + case PROP_DURATION: + gst_vaapi_surface_proxy_set_duration(proxy, g_value_get_uint64(value)); + break; case PROP_INTERLACED: gst_vaapi_surface_proxy_set_interlaced(proxy, g_value_get_boolean(value)); break; @@ -120,6 +125,9 @@ gst_vaapi_surface_proxy_get_property( case PROP_TIMESTAMP: g_value_set_uint64(value, gst_vaapi_surface_proxy_get_timestamp(proxy)); break; + case PROP_DURATION: + g_value_set_uint64(value, gst_vaapi_surface_proxy_get_duration(proxy)); + break; case PROP_INTERLACED: g_value_set_boolean(value, gst_vaapi_surface_proxy_get_interlaced(proxy)); break; @@ -168,6 +176,15 @@ gst_vaapi_surface_proxy_class_init(GstVaapiSurfaceProxyClass *klass) 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, G_PARAM_READWRITE)); + g_object_class_install_property + (object_class, + PROP_DURATION, + g_param_spec_uint64("duration", + "Duration", + "The amount of time the surface is to be presented", + 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_INTERLACED, @@ -197,6 +214,7 @@ gst_vaapi_surface_proxy_init(GstVaapiSurfaceProxy *proxy) priv->context = NULL; priv->surface = NULL; priv->timestamp = GST_CLOCK_TIME_NONE; + priv->duration = GST_CLOCK_TIME_NONE; priv->is_interlaced = FALSE; priv->tff = FALSE; } @@ -366,6 +384,42 @@ gst_vaapi_surface_proxy_set_timestamp( proxy->priv->timestamp = timestamp; } +/** + * gst_vaapi_surface_proxy_get_duration: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the presentation duration of the #GstVaapiSurface held by @proxy. + * + * Return value: the presentation duration of the surface, or + * %GST_CLOCK_TIME_NONE is none was set + */ +GstClockTime +gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), + GST_CLOCK_TIME_NONE); + + return proxy->priv->duration; +} + +/** + * gst_vaapi_surface_proxy_set_duration: + * @proxy: a #GstVaapiSurfaceProxy + * @duration: the presentation duration of this surface as a #GstClockTime + * + * Sets the presentation duration of the @proxy surface to @duration. + */ +void +gst_vaapi_surface_proxy_set_duration( + GstVaapiSurfaceProxy *proxy, + GstClockTime duration +) +{ + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + + proxy->priv->duration = duration; +} + /** * gst_vaapi_surface_proxy_get_interlaced: * @proxy: a #GstVaapiSurfaceProxy diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 35e38f7c0b..ef333ba394 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -72,6 +72,16 @@ G_BEGIN_DECLS #define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(surface) \ gst_vaapi_surface_proxy_get_timestamp(surface) +/** + * GST_VAAPI_SURFACE_PROXY_DURATION: + * @surface: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the amount of time the @surface should be + * displayed, or %GST_CLOCK_TIME_NONE if none was set. + */ +#define GST_VAAPI_SURFACE_PROXY_DURATION(surface) \ + gst_vaapi_surface_proxy_get_duration(surface) + /** * GST_VAAPI_SURFACE_PROXY_INTERLACED: * @surface: a #GstVaapiSurfaceProxy @@ -152,6 +162,15 @@ gst_vaapi_surface_proxy_set_timestamp( GstClockTime timestamp ); +GstClockTime +gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy); + +void +gst_vaapi_surface_proxy_set_duration( + GstVaapiSurfaceProxy *proxy, + GstClockTime duration +); + gboolean gst_vaapi_surface_proxy_get_interlaced(GstVaapiSurfaceProxy *proxy); From 6c19849cd2d273fdc67b6e8f6befd17e1fbb68fc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 11 Sep 2012 10:59:33 +0200 Subject: [PATCH 0823/3781] decoder: propagate buffer duration downstream. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 6 ++++++ gst/vaapi/gstvaapidecode.c | 1 + 2 files changed, 7 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 148a6a23cc..c63bb1496e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -129,10 +129,16 @@ static inline void push_surface(GstVaapiDecoder *decoder, GstVaapiSurfaceProxy *proxy) { GstVaapiDecoderPrivate * const priv = decoder->priv; + GstClockTime duration; GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id(proxy))); + if (priv->fps_n && priv->fps_d) { + /* Actual field duration is computed in vaapipostproc */ + duration = gst_util_uint64_scale(GST_SECOND, priv->fps_d, priv->fps_n); + gst_vaapi_surface_proxy_set_duration(proxy, duration); + } g_queue_push_tail(priv->surfaces, proxy); } diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 7b85636877..0b9643fa35 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -229,6 +229,7 @@ gst_vaapidecode_step(GstVaapiDecode *decode) goto error_create_buffer; GST_BUFFER_TIMESTAMP(buffer) = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); + GST_BUFFER_DURATION(buffer) = GST_VAAPI_SURFACE_PROXY_DURATION(proxy); gst_buffer_set_caps(buffer, GST_PAD_CAPS(decode->srcpad)); if (GST_VAAPI_SURFACE_PROXY_TFF(proxy)) From 9afe700005ff47a6368734814fd58bbfaed62f04 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 11 Sep 2012 15:54:20 +0200 Subject: [PATCH 0824/3781] vaapidecode: improve "no free surface" conditions. Previously, vaapidecode would wait up to one second until a free surface is available, or it aborts decoding. Now, vaapidecode waits until the last decoded surface was to be presented, plus one second. Besides, end times are now expressed relative to the monotonic clock. --- gst/vaapi/gstvaapidecode.c | 35 ++++++++++++++++++++++------------- gst/vaapi/gstvaapidecode.h | 2 ++ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 0b9643fa35..4a4f4e74e3 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -189,28 +189,30 @@ gst_vaapidecode_step(GstVaapiDecode *decode) GstVaapiDecoderStatus status; GstBuffer *buffer; GstFlowReturn ret; - guint tries; + GstClockTime timestamp; + gint64 end_time; for (;;) { - tries = 0; - again: + end_time = decode->render_time_base; + if (!end_time) + end_time = g_get_monotonic_time(); + end_time += GST_TIME_AS_USECONDS(decode->last_buffer_time); + end_time += G_TIME_SPAN_SECOND; + proxy = gst_vaapi_decoder_get_surface(decode->decoder, &status); if (!proxy) { if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { - /* Wait for a VA surface to be displayed and free'd */ - if (++tries > 100) - goto error_decode_timeout; - GTimeVal timeout; - g_get_current_time(&timeout); - g_time_val_add(&timeout, 10000); /* 10 ms each step */ + gboolean was_signalled; g_mutex_lock(decode->decoder_mutex); - g_cond_timed_wait( + was_signalled = g_cond_wait_until( decode->decoder_ready, decode->decoder_mutex, - &timeout + end_time ); g_mutex_unlock(decode->decoder_mutex); - goto again; + if (was_signalled) + continue; + goto error_decode_timeout; } if (status != GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) goto error_decode; @@ -228,7 +230,12 @@ gst_vaapidecode_step(GstVaapiDecode *decode) if (!buffer) goto error_create_buffer; - GST_BUFFER_TIMESTAMP(buffer) = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); + timestamp = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); + if (!decode->render_time_base) + decode->render_time_base = g_get_monotonic_time(); + decode->last_buffer_time = timestamp; + + GST_BUFFER_TIMESTAMP(buffer) = timestamp; GST_BUFFER_DURATION(buffer) = GST_VAAPI_SURFACE_PROXY_DURATION(proxy); gst_buffer_set_caps(buffer, GST_PAD_CAPS(decode->srcpad)); @@ -710,6 +717,8 @@ gst_vaapidecode_init(GstVaapiDecode *decode) decode->decoder_caps = NULL; decode->allowed_caps = NULL; decode->delayed_new_seg = NULL; + decode->render_time_base = 0; + decode->last_buffer_time = 0; decode->is_ready = FALSE; /* Pad through which data comes in to the element */ diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 408ee08c1a..68799df52e 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -72,6 +72,8 @@ struct _GstVaapiDecode { GstCaps *decoder_caps; GstCaps *allowed_caps; GstEvent *delayed_new_seg; + gint64 render_time_base; + GstClockTime last_buffer_time; unsigned int is_ready : 1; }; From 2b71db30598634dc17c3d45689a0f63528b3767c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 11 Sep 2012 16:41:32 +0200 Subject: [PATCH 0825/3781] vaapidecode: simplify codec lookup from caps. Add new gst_vaapi_codec_from_caps() helper to determine codec type from the specified caps. Don't globally expose this function since this is really trivial and only used in the vaapidecode element. --- gst/vaapi/gstvaapidecode.c | 48 +++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4a4f4e74e3..d79eaa1c95 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -303,12 +303,16 @@ gst_vaapidecode_ensure_display(GstVaapiDecode *decode) &decode->display); } +static inline guint +gst_vaapi_codec_from_caps(GstCaps *caps) +{ + return gst_vaapi_profile_get_codec(gst_vaapi_profile_from_caps(caps)); +} + static gboolean gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) { GstVaapiDisplay *dpy; - GstStructure *structure; - int version; if (!gst_vaapidecode_ensure_display(decode)) return FALSE; @@ -322,30 +326,30 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) if (!decode->decoder_ready) return FALSE; - structure = gst_caps_get_structure(caps, 0); - if (!structure) - return FALSE; - - if (gst_structure_has_name(structure, "video/x-h264")) - decode->decoder = gst_vaapi_decoder_h264_new(dpy, caps); - else if (gst_structure_has_name(structure, "video/mpeg")) { - if (!gst_structure_get_int(structure, "mpegversion", &version)) - return FALSE; - if (version == 2) - decode->decoder = gst_vaapi_decoder_mpeg2_new(dpy, caps); - else if (version == 4) - decode->decoder = gst_vaapi_decoder_mpeg4_new(dpy, caps); - } - else if (gst_structure_has_name(structure, "video/x-wmv")) - decode->decoder = gst_vaapi_decoder_vc1_new(dpy, caps); - else if (gst_structure_has_name(structure, "video/x-h263") || - gst_structure_has_name(structure, "video/x-divx") || - gst_structure_has_name(structure, "video/x-xvid")) + switch (gst_vaapi_codec_from_caps(caps)) { + case GST_VAAPI_CODEC_MPEG2: + decode->decoder = gst_vaapi_decoder_mpeg2_new(dpy, caps); + break; + case GST_VAAPI_CODEC_MPEG4: + case GST_VAAPI_CODEC_H263: decode->decoder = gst_vaapi_decoder_mpeg4_new(dpy, caps); + break; + case GST_VAAPI_CODEC_H264: + decode->decoder = gst_vaapi_decoder_h264_new(dpy, caps); + break; + case GST_VAAPI_CODEC_WMV3: + case GST_VAAPI_CODEC_VC1: + decode->decoder = gst_vaapi_decoder_vc1_new(dpy, caps); + break; #if USE_JPEG_DECODER - else if (gst_structure_has_name(structure, "image/jpeg")) + case GST_VAAPI_CODEC_JPEG: decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps); + break; #endif + default: + decode->decoder = NULL; + break; + } if (!decode->decoder) return FALSE; From 5549dbc3c058e7072a480db6d4efb17c595c8580 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 11 Sep 2012 17:03:33 +0200 Subject: [PATCH 0826/3781] vaapidecode: don't reset decoder if codec type is the same. Reset, i.e. destroy then create, the decoder in _setcaps() handler only if the underlying codec type actually changed. This makes it possible to be more tolerant with certain MPEG-2 streams that get parsed to form caps that are compatible with the previous state but minor changes to "codec-data". --- gst-libs/gst/vaapi/gstvaapidecoder.c | 16 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder.h | 3 +++ gst/vaapi/gstvaapidecode.c | 14 ++++++++++---- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index c63bb1496e..d2ee86cb5f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -361,6 +361,22 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->is_interlaced = FALSE; } +/** + * gst_vaapi_decoder_get_codec: + * @decoder: a #GstVaapiDecoder + * + * Retrieves the @decoder codec type. + * + * Return value: the #GstVaapiCodec type for @decoder + */ +GstVaapiCodec +gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder) +{ + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), (GstVaapiCodec)0); + + return decoder->priv->codec; +} + /** * gst_vaapi_decoder_get_caps: * @decoder: a #GstVaapiDecoder diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index deeb692672..b5a397bd2e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -116,6 +116,9 @@ struct _GstVaapiDecoderClass { GType gst_vaapi_decoder_get_type(void) G_GNUC_CONST; +GstVaapiCodec +gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder); + GstCaps * gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder); diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d79eaa1c95..1cc94c7720 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -393,10 +393,16 @@ gst_vaapidecode_destroy(GstVaapiDecode *decode) static gboolean gst_vaapidecode_reset(GstVaapiDecode *decode, GstCaps *caps) { - if (decode->decoder && - decode->decoder_caps && - gst_caps_is_always_compatible(caps, decode->decoder_caps)) - return TRUE; + GstVaapiCodec codec; + + /* Only reset decoder if codec type changed */ + if (decode->decoder && decode->decoder_caps) { + if (gst_caps_is_always_compatible(caps, decode->decoder_caps)) + return TRUE; + codec = gst_vaapi_codec_from_caps(caps); + if (codec == gst_vaapi_decoder_get_codec(decode->decoder)) + return TRUE; + } gst_vaapidecode_destroy(decode); return gst_vaapidecode_create(decode, caps); From c4ccc0a74b183a57db01748b52421b21fcd1d93a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 12 Sep 2012 10:40:06 +0200 Subject: [PATCH 0827/3781] codecparsers: jpeg: add missing includes. --- gst-libs/gst/codecparsers/gstjpegparser.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c index ca597ad6cb..80de3fff0d 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -20,6 +20,7 @@ */ #include +#include #include #include "gstjpegparser.h" From e6047734b3168af1eb8c1501e02e2f5213f6462e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 12 Sep 2012 13:41:47 +0200 Subject: [PATCH 0828/3781] plugins: include "sysdeps.h" instead of "config.h". --- gst/vaapi/gstvaapidecode.c | 3 +-- gst/vaapi/gstvaapidownload.c | 3 +-- gst/vaapi/gstvaapipostproc.c | 2 +- gst/vaapi/gstvaapisink.c | 2 +- gst/vaapi/gstvaapiupload.c | 3 +-- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1cc94c7720..100ca52869 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -28,8 +28,7 @@ * the vaapisink element. */ -#include "config.h" - +#include "gst/vaapi/sysdeps.h" #include #include #include diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index cb914645e5..2f1271131c 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -27,8 +27,7 @@ * vaapidownload converts from VA surfaces to raw YUV pixels. */ -#include "config.h" - +#include "gst/vaapi/sysdeps.h" #include #include #include diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index a528131f63..bcd25228dd 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -28,7 +28,7 @@ * implemented. */ -#include "config.h" +#include "gst/vaapi/sysdeps.h" #include #include #include diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 469708275e..72513981b8 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -29,7 +29,7 @@ * create its own internal window and render into it. */ -#include "config.h" +#include "gst/vaapi/sysdeps.h" #include #include #include diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 5e2ce1ba05..88b43a5ce1 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -28,8 +28,7 @@ * for the vaapisink element, for example. */ -#include "config.h" - +#include "gst/vaapi/sysdeps.h" #include #include #include From f65a413500d61834a479bb5e53d4c37c9335823a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 12 Sep 2012 13:42:49 +0200 Subject: [PATCH 0829/3781] glibcompat: add replacement for g_cond_wait_until(). --- gst-libs/gst/vaapi/glibcompat.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 30a8563f17..0a6115c913 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -74,4 +74,18 @@ g_clear_object_inline(volatile GObject **object_ptr) #define g_static_rec_mutex_unlock(m) g_rec_mutex_unlock(m) #endif +#if !GLIB_CHECK_VERSION(2,31,2) +static inline gboolean +g_cond_wait_until(GCond *cond, GMutex *mutex, gint64 end_time) +{ + gint64 diff_time; + GTimeVal timeout; + + diff_time = end_time - g_get_monotonic_time(); + g_get_current_time(&timeout); + g_time_val_add(&timeout, diff_time > 0 ? diff_time : 0); + return g_cond_timed_wait(cond, mutex, &timeout); +} +#endif + #endif /* GLIB_COMPAT_H */ From 5c89b66dae6e496868fbd381afb45ec2264a3158 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 14 Sep 2012 17:30:19 +0200 Subject: [PATCH 0830/3781] configure: fix check for libva-glx and libva-drm. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index c598efa33c..7291eb275e 100644 --- a/configure.ac +++ b/configure.ac @@ -404,7 +404,7 @@ if test $USE_DRM -eq 1; then if test $HAVE_VA_DRM -eq 1; then saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$LIBVA_DRM_CPPFLAGS" + CPPFLAGS="$LIBVA_DRM_CFLAGS" AC_CHECK_HEADERS([va/va_drm.h], [:], [HAVE_VA_DRM=0 USE_DRM=0]) CPPFLAGS="$saved_CPPFLAGS" fi @@ -428,7 +428,7 @@ if test $USE_GLX -eq 1; then if test $HAVE_VA_GLX -eq 1; then saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$LIBVA_GLX_CPPFLAGS" + CPPFLAGS="$LIBVA_GLX_CFLAGS" AC_CHECK_HEADERS([va/va_glx.h], [:], [HAVE_VA_GLX=0]) CPPFLAGS="$saved_CPPFLAGS" fi From 38ed8008b126ed0ff5e06da67c9c2a19bcb3eedd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 14 Sep 2012 10:30:35 -0400 Subject: [PATCH 0831/3781] wayland: set opaque region for YUV surface. This allows the compositor to optimize redraws and cull away changes obscured by the video surface. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index ac2882e681..2607c64393 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -49,6 +49,7 @@ struct _GstVaapiWindowWaylandPrivate { struct wl_shell_surface *shell_surface; struct wl_surface *surface; struct wl_buffer *buffer; + struct wl_region *opaque_region; guint redraw_pending : 1; }; @@ -161,7 +162,18 @@ gst_vaapi_window_wayland_resize( guint height ) { + GstVaapiWindowWaylandPrivate * const priv = + GST_VAAPI_WINDOW_WAYLAND(window)->priv; + GstVaapiDisplayWaylandPrivate * const priv_display = + GST_VAAPI_OBJECT_DISPLAY_WAYLAND(window)->priv; + GST_DEBUG("resize window, new size %ux%u", width, height); + + if (priv->opaque_region) + wl_region_destroy(priv->opaque_region); + priv->opaque_region = wl_compositor_create_region(priv_display->compositor); + wl_region_add(priv->opaque_region, 0, 0, width, height); + return TRUE; } @@ -248,6 +260,12 @@ gst_vaapi_window_wayland_render( wl_surface_attach(priv->surface, buffer, 0, 0); wl_surface_damage(priv->surface, 0, 0, width, height); + if (priv->opaque_region) { + wl_surface_set_opaque_region(priv->surface, priv->opaque_region); + wl_region_destroy(priv->opaque_region); + priv->opaque_region = NULL; + } + wl_display_iterate(wl_display, WL_DISPLAY_WRITABLE); priv->redraw_pending = TRUE; priv->buffer = buffer; From 84dc362c8ecfef5399cd3ed301a695b501e46c35 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 17 Sep 2012 17:55:43 +0200 Subject: [PATCH 0832/3781] docs: fix build for make dist. --- docs/reference/libs/libs-docs.xml.in | 2 +- docs/reference/libs/libs.core.types | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 34b16658c1..474a64144a 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -30,11 +30,11 @@ + - diff --git a/docs/reference/libs/libs.core.types b/docs/reference/libs/libs.core.types index b779fd6359..12710bd226 100644 --- a/docs/reference/libs/libs.core.types +++ b/docs/reference/libs/libs.core.types @@ -10,5 +10,4 @@ gst_vaapi_surface_pool_get_type gst_vaapi_surface_proxy_get_type gst_vaapi_video_buffer_get_type gst_vaapi_video_pool_get_type -gst_vaapi_video_sink_get_type gst_vaapi_window_get_type From 59770b62396087e0ebe2ba9106b216b6292e42b8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 20 Sep 2012 14:38:15 +0200 Subject: [PATCH 0833/3781] debian: fix packaging on recent Ubuntu platforms. Use explicit GStreamer plugins path. --- debian.upstream/gstreamer-vaapi.install.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian.upstream/gstreamer-vaapi.install.in b/debian.upstream/gstreamer-vaapi.install.in index 5af8fbb5e6..2417257f05 100644 --- a/debian.upstream/gstreamer-vaapi.install.in +++ b/debian.upstream/gstreamer-vaapi.install.in @@ -1 +1 @@ -debian/tmp/usr/lib/gstreamer-@GST_MAJORMINOR@/libgstvaapi*.so +debian/tmp@plugindir@/libgstvaapi*.so From 1e5296751563f1393720716ff3087c7445f002d0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 20 Sep 2012 16:02:39 +0200 Subject: [PATCH 0834/3781] NEWS: updates. --- NEWS | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 2ad1dbe6c0..9c1b6e7313 100644 --- a/NEWS +++ b/NEWS @@ -4,9 +4,22 @@ Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora Version 0.4.0 - DD.Aug.2012 -* Add support for Wayland -* Add support for headless pipelines (VA/DRM API) -* Drop FFmpeg-based decoders +* Add support for video rotation +* Add new video display APIs: Wayland and raw DRM for headless pipelines +* Drop FFmpeg-based decoders, only use codecparsers-based ones +* Only reset decoder if meaningful caps changed, e.g. size +* Allocate the minimal number of video surfaces useful for decoding +* Fix vaapisink to scale video down to fit the screen dimensions +* Fix vaapidecode crash when trying to release an inexisten lock (Philip Lorenz) + +Version 0.3.8 - 20.Sep.2012 +* Disable FFmpeg-based decoders by default +* Add JPEG decoder (based on codecparsers) +* Fix crash when destroying GstVaapiDisplay objects early +* Fix GLX rendering with FBO + texture-from-pixmap (fallback for VA/GLX) +* Fix rendering with EMGD driver when overlay mode is used +* Fix MPEG-2 decoding on Intel Atom platforms with EMGD driver +* Fix release of dangling proxy surfaces when decoder is reset (Philip Lorenz) Version 0.3.7 - 26.Jun.2012 * Fix vaapidecode to report unsupported codec profiles From 3d7e4a3a33010469ce7317b1d34082a20afb6839 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 20 Sep 2012 16:18:27 +0200 Subject: [PATCH 0835/3781] README: updates. --- README | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README b/README index 3c1e07873f..27f7c4de80 100644 --- a/README +++ b/README @@ -40,8 +40,10 @@ Features -------- * VA-API support from 0.29 to 0.32 - * MPEG-2, MPEG-4, H.264 and VC-1 ad-hoc decoders + * JPEG, MPEG-2, MPEG-4, H.264 and VC-1 ad-hoc decoders * OpenGL rendering through VA/GLX or GLX texture-from-pixmap + FBO + * 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) @@ -57,11 +59,6 @@ Software requirements * libgstreamer-plugins-bad0.10-dev >= 0.10.22.1 or with GstVideoContext, GstSurfaceBuffer, codecparsers - If codecparsers-based decoders are not used: - - * libavcodec-dev >= 0.6 - or with - Hardware requirements * AMD platforms with UVD2 (XvBA supported) From dde9232e10d21263c28ef8d4d1c18fda54b92c30 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 20 Sep 2012 17:58:21 +0200 Subject: [PATCH 0836/3781] h264: exclusively use GstAdapter, drop sub-buffer hack. Maintaining the sub-buffer is rather suboptimal especially since we were also maintaining a GstAdapter. Now, we only use the GstAdapter thus requiring minor extra parsing when receiving avcC buffers. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 102 +++++++++++++--------- 1 file changed, 63 insertions(+), 39 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index d0e24326c3..20cd597279 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -253,7 +253,6 @@ G_DEFINE_TYPE(GstVaapiDecoderH264, struct _GstVaapiDecoderH264Private { GstAdapter *adapter; - GstBuffer *sub_buffer; GstH264NalParser *parser; GstH264SPS *sps; GstH264SPS last_sps; @@ -526,11 +525,6 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) clear_references(decoder, priv->long_ref, &priv->long_ref_count ); clear_references(decoder, priv->dpb, &priv->dpb_count ); - if (priv->sub_buffer) { - gst_buffer_unref(priv->sub_buffer); - priv->sub_buffer = NULL; - } - if (priv->parser) { gst_h264_nal_parser_free(priv->parser); priv->parser = NULL; @@ -2210,6 +2204,15 @@ error: return status; } +static inline gint +scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) +{ + return (gint)gst_adapter_masked_scan_uint32_peek(adapter, + 0xffffff00, 0x00000100, + ofs, size, + scp); +} + static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) { @@ -2217,55 +2220,80 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) GstVaapiDecoderStatus status; GstH264ParserResult result; GstH264NalUnit nalu; - guchar *buf; - guint buf_size, ofs; + const guchar *buf; + guint i, buf_size, nalu_size, size; + guint32 start_code; + gint ofs; buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); if (!buf && buf_size == 0) return decode_sequence_end(decoder); - gst_buffer_ref(buffer); - gst_adapter_push(priv->adapter, buffer); + gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); - if (priv->sub_buffer) { - buffer = gst_buffer_merge(priv->sub_buffer, buffer); - if (!buffer) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - gst_buffer_unref(priv->sub_buffer); - priv->sub_buffer = NULL; - } - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - ofs = 0; + size = gst_adapter_available(priv->adapter); do { + status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder)); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + break; + + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; if (priv->is_avc) { + if (size < priv->nal_length_size) + break; + buf = gst_adapter_peek(priv->adapter, priv->nal_length_size); + + nalu_size = 0; + for (i = 0; i < priv->nal_length_size; i++) + nalu_size = (nalu_size << 8) | buf[i]; + + buf_size = priv->nal_length_size + nalu_size; + if (size < buf_size) + break; + buffer = gst_adapter_take_buffer(priv->adapter, buf_size); + size -= buf_size; + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + result = gst_h264_parser_identify_nalu_avc( priv->parser, - buf, ofs, buf_size, priv->nal_length_size, + buf, 0, buf_size, priv->nal_length_size, &nalu ); } else { - result = gst_h264_parser_identify_nalu( + if (size < 8) + break; + ofs = scan_for_start_code(priv->adapter, 0, size, &start_code); + if (ofs < 0) + break; + gst_adapter_flush(priv->adapter, ofs); + size -= ofs; + + if (size < 8) + break; + ofs = scan_for_start_code(priv->adapter, 4, size - 4, NULL); + if (ofs < 0) + break; + buffer = gst_adapter_take_buffer(priv->adapter, ofs); + size -= ofs; + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); + + result = gst_h264_parser_identify_nalu_unchecked( priv->parser, - buf, ofs, buf_size, + buf, 0, buf_size, &nalu ); } status = get_status(result); - - if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) { - priv->sub_buffer = gst_buffer_create_sub(buffer, ofs, buf_size - ofs); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + gst_buffer_unref(buffer); break; } - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - break; - - ofs = nalu.offset - ofs; - if (gst_adapter_available(priv->adapter) >= ofs) - gst_adapter_flush(priv->adapter, ofs); switch (nalu.type) { case GST_H264_NAL_SLICE_IDR: @@ -2298,11 +2326,8 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } - - if (gst_adapter_available(priv->adapter) >= nalu.size) - gst_adapter_flush(priv->adapter, nalu.size); - ofs = nalu.offset + nalu.size; - } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size); + gst_buffer_unref(buffer); + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); return status; } @@ -2462,7 +2487,6 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->mb_width = 0; priv->mb_height = 0; priv->adapter = NULL; - priv->sub_buffer = NULL; priv->field_poc[0] = 0; priv->field_poc[1] = 0; priv->poc_msb = 0; From 1c5c5ea9b870b277969d919c36ff1e6e786bf3d0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 21 Sep 2012 16:43:38 +0200 Subject: [PATCH 0837/3781] h264: review and report errors accordingly. Use GST_ERROR() to report real errors instead of hiding them into GST_DEBUG(). --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 20cd597279..7e78695350 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1615,7 +1615,7 @@ init_picture( init_picture_poc(decoder, picture, slice_hdr); if (!init_picture_refs(decoder, picture, slice_hdr)) { - GST_DEBUG("failed to initialize references"); + GST_ERROR("failed to initialize references"); return FALSE; } return TRUE; @@ -1921,7 +1921,7 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceH status = ensure_context(decoder, sps); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_DEBUG("failed to reset context"); + GST_ERROR("failed to reset context"); return status; } @@ -1930,20 +1930,20 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceH picture = gst_vaapi_picture_h264_new(decoder); if (!picture) { - GST_DEBUG("failed to allocate picture"); + GST_ERROR("failed to allocate picture"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } priv->current_picture = picture; picture->base.iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder); if (!picture->base.iq_matrix) { - GST_DEBUG("failed to allocate IQ matrix"); + GST_ERROR("failed to allocate IQ matrix"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } status = ensure_quant_matrix(decoder, pps); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_DEBUG("failed to reset quantizer matrix"); + GST_ERROR("failed to reset quantizer matrix"); return status; } @@ -2157,7 +2157,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) nalu->size ); if (!slice) { - GST_DEBUG("failed to allocate slice"); + GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } @@ -2322,7 +2322,7 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; default: - GST_DEBUG("unsupported NAL unit type %d", nalu.type); + GST_WARNING("unsupported NAL unit type %d", nalu.type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } @@ -2351,7 +2351,7 @@ decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; if (buf[0] != 1) { - GST_DEBUG("failed to decode codec-data, not in avcC format"); + GST_ERROR("failed to decode codec-data, not in avcC format"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } From 10ee14cc9c4479bf8f6244623fd096d006dc8970 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 26 Sep 2012 16:33:16 +0200 Subject: [PATCH 0838/3781] configure: update VA-API version requirements. VA/DRM and VA/Wayland API are now promoted to VA-API 0.33.0 (libva 1.1.0). --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 7291eb275e..3b77e3c431 100644 --- a/configure.ac +++ b/configure.ac @@ -43,16 +43,16 @@ m4_define([gst_plugins_bad_version], # VA-API minimum version number m4_define([va_api_version], [0.30.4]) -m4_define([va_api_drm_version], [0.34.0]) +m4_define([va_api_drm_version], [0.33.0]) m4_define([va_api_x11_version], [0.31.0]) m4_define([va_api_glx_version], [0.32.0]) -m4_define([va_api_wld_version], [0.34.0]) +m4_define([va_api_wld_version], [0.33.0]) # libva package version number -m4_define([libva_drm_package_version], [1.2.0]) +m4_define([libva_drm_package_version], [1.1.0]) m4_define([libva_x11_package_version], [1.0.3]) m4_define([libva_glx_package_version], [1.0.9]) -m4_define([libva_wld_package_version], [1.2.0]) +m4_define([libva_wld_package_version], [1.1.0]) # gtk-doc version number # XXX: introspection annotations require gtk-doc >= 1.12 From 5db2e93d3c930fd8470cfdcd26f514d1cebc59a0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 27 Sep 2012 11:04:24 +0200 Subject: [PATCH 0839/3781] utils: fix build with version >= 85. Mesa recently updated the header version to Khronos version 85. This caused the PFNGLMULTITEXCOORD2FPROC definition to be moved out of the GL_VERSION_1_3_DEPRECATED block. However, since also defines GL_VERSION_1_3 to 1, the definitions in are then not enabled, thus leaving PFNGLMULTITEXCOORD2FPROC undefined as well. Provide a PFNGLMULTITEXCOORD2FPROC replacement as an interim solution for newer versions of the header. --- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index c9a4983336..5eb5d93557 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -41,6 +41,13 @@ typedef GLXPixmap (*PFNGLXCREATEPIXMAPPROC)(Display *, GLXFBConfig, Pixmap, cons typedef void (*PFNGLXDESTROYPIXMAPPROC)(Display *, GLXPixmap); #endif +#if GL_GLEXT_VERSION >= 85 +/* XXX: PFNGLMULTITEXCOORD2FPROC got out of the GL_VERSION_1_3_DEPRECATED + block and is not defined if GL_VERSION_1_3 is defined in + Redefine the type here as an interim solution */ +typedef void (*PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +#endif + #ifndef GL_FRAMEBUFFER_BINDING #define GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_EXT #endif From a6a1ea09a35aa4874394ba36f3500b431cb8f511 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 27 Sep 2012 11:08:58 +0200 Subject: [PATCH 0840/3781] utils: drop unused GLX helpers. Remove helpers for GL_ARB_fragment_program and GL_ARB_multitexture extensions since they are not used throughout gstreamer-vaapi. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 48 -------------------------- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 17 --------- 2 files changed, 65 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 4dbf834e2e..9a742ca109 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -728,54 +728,6 @@ gl_init_vtable(void) return NULL; gl_vtable->has_framebuffer_object = TRUE; } - - /* GL_ARB_fragment_program */ - has_extension = ( - find_string("GL_ARB_fragment_program", gl_extensions, " ") - ); - if (has_extension) { - gl_vtable->gl_gen_programs = (PFNGLGENPROGRAMSARBPROC) - get_proc_address("glGenProgramsARB"); - if (!gl_vtable->gl_gen_programs) - return NULL; - gl_vtable->gl_delete_programs = (PFNGLDELETEPROGRAMSARBPROC) - get_proc_address("glDeleteProgramsARB"); - if (!gl_vtable->gl_delete_programs) - return NULL; - gl_vtable->gl_bind_program = (PFNGLBINDPROGRAMARBPROC) - get_proc_address("glBindProgramARB"); - if (!gl_vtable->gl_bind_program) - return NULL; - gl_vtable->gl_program_string = (PFNGLPROGRAMSTRINGARBPROC) - get_proc_address("glProgramStringARB"); - if (!gl_vtable->gl_program_string) - return NULL; - gl_vtable->gl_get_program_iv = (PFNGLGETPROGRAMIVARBPROC) - get_proc_address("glGetProgramivARB"); - if (!gl_vtable->gl_get_program_iv) - return NULL; - gl_vtable->gl_program_local_parameter_4fv = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) - get_proc_address("glProgramLocalParameter4fvARB"); - if (!gl_vtable->gl_program_local_parameter_4fv) - return NULL; - gl_vtable->has_fragment_program = TRUE; - } - - /* GL_ARB_multitexture */ - has_extension = ( - find_string("GL_ARB_multitexture", gl_extensions, " ") - ); - if (has_extension) { - gl_vtable->gl_active_texture = (PFNGLACTIVETEXTUREPROC) - get_proc_address("glActiveTextureARB"); - if (!gl_vtable->gl_active_texture) - return NULL; - gl_vtable->gl_multi_tex_coord_2f = (PFNGLMULTITEXCOORD2FPROC) - get_proc_address("glMultiTexCoord2fARB"); - if (!gl_vtable->gl_multi_tex_coord_2f) - return NULL; - gl_vtable->has_multitexture = TRUE; - } return gl_vtable; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 5eb5d93557..912d0723b3 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -41,13 +41,6 @@ typedef GLXPixmap (*PFNGLXCREATEPIXMAPPROC)(Display *, GLXFBConfig, Pixmap, cons typedef void (*PFNGLXDESTROYPIXMAPPROC)(Display *, GLXPixmap); #endif -#if GL_GLEXT_VERSION >= 85 -/* XXX: PFNGLMULTITEXCOORD2FPROC got out of the GL_VERSION_1_3_DEPRECATED - block and is not defined if GL_VERSION_1_3 is defined in - Redefine the type here as an interim solution */ -typedef void (*PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); -#endif - #ifndef GL_FRAMEBUFFER_BINDING #define GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_EXT #endif @@ -145,18 +138,8 @@ struct _GLVTable { PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC gl_framebuffer_renderbuffer; PFNGLFRAMEBUFFERTEXTURE2DEXTPROC gl_framebuffer_texture_2d; PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC gl_check_framebuffer_status; - PFNGLGENPROGRAMSARBPROC gl_gen_programs; - PFNGLDELETEPROGRAMSARBPROC gl_delete_programs; - PFNGLBINDPROGRAMARBPROC gl_bind_program; - PFNGLPROGRAMSTRINGARBPROC gl_program_string; - PFNGLGETPROGRAMIVARBPROC gl_get_program_iv; - PFNGLPROGRAMLOCALPARAMETER4FVARBPROC gl_program_local_parameter_4fv; - PFNGLACTIVETEXTUREPROC gl_active_texture; - PFNGLMULTITEXCOORD2FPROC gl_multi_tex_coord_2f; guint has_texture_from_pixmap : 1; guint has_framebuffer_object : 1; - guint has_fragment_program : 1; - guint has_multitexture : 1; }; G_GNUC_INTERNAL From dd915c15c83f46a9eec376ac35fd3f816477ab10 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 28 Sep 2012 17:38:17 +0200 Subject: [PATCH 0841/3781] debian: fix conditional build of packages. Make it still possible to build package even if one of the build dependencies for a specific video backend is not available. --- debian.upstream/control.in | 76 ++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 960f72ebb7..c40d5b07bc 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -7,6 +7,10 @@ Build-Depends: debhelper (>= 5), libglib2.0-dev (>= @GLIB_VERSION_REQUIRED@), libgstreamer@GST_MAJORMINOR@-dev (>= @GST_VERSION_REQUIRED@), libgstreamer-plugins-base@GST_MAJORMINOR@-dev (>= @GST_PLUGINS_BASE_VERSION_REQUIRED@), +@USE_DRM_TRUE@ libdrm-dev, libudev-dev, +@USE_X11_TRUE@ libx11-dev, libxrandr-dev, +@USE_GLX_TRUE@ libgl-dev, +@USE_WAYLAND_TRUE@ libwayland-dev, libva-dev (>= @LIBVA_PACKAGE_VERSION@) Build-Depends-Indep: gtk-doc-tools (>= @GTKDOC_VERSION@) Standards-Version: 3.7.2 @@ -49,49 +53,51 @@ Description: GStreamer libraries from the "vaapi" set . This package contains common libraries for the "vaapi" set. -Package: libgstvaapi-drm-@GST_VAAPI_MAJOR_VERSION@ -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: GStreamer libraries from the "vaapi" set - VA-API support libraries for GStreamer. - . - This package contains headless libraries for the "vaapi" set. +@USE_DRM_TRUE@Package: libgstvaapi-drm-@GST_VAAPI_MAJOR_VERSION@ +@USE_DRM_TRUE@Section: libs +@USE_DRM_TRUE@Architecture: any +@USE_DRM_TRUE@Depends: ${shlibs:Depends}, ${misc:Depends} +@USE_DRM_TRUE@Description: GStreamer libraries from the "vaapi" set +@USE_DRM_TRUE@ VA-API support libraries for GStreamer. +@USE_DRM_TRUE@ . +@USE_DRM_TRUE@ This package contains headless libraries for the "vaapi" set. -Package: libgstvaapi-x11-@GST_VAAPI_MAJOR_VERSION@ -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: GStreamer libraries from the "vaapi" set - VA-API support libraries for GStreamer. - . - This package contains x11 libraries for the "vaapi" set. +@USE_X11_TRUE@Package: libgstvaapi-x11-@GST_VAAPI_MAJOR_VERSION@ +@USE_X11_TRUE@Section: libs +@USE_X11_TRUE@Architecture: any +@USE_X11_TRUE@Depends: ${shlibs:Depends}, ${misc:Depends} +@USE_X11_TRUE@Description: GStreamer libraries from the "vaapi" set +@USE_X11_TRUE@ VA-API support libraries for GStreamer. +@USE_X11_TRUE@ . +@USE_X11_TRUE@ This package contains x11 libraries for the "vaapi" set. -Package: libgstvaapi-glx-@GST_VAAPI_MAJOR_VERSION@ -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: GStreamer libraries from the "vaapi" set - VA-API support libraries for GStreamer. - . - This package contains glx libraries for the "vaapi" set. +@USE_GLX_TRUE@Package: libgstvaapi-glx-@GST_VAAPI_MAJOR_VERSION@ +@USE_GLX_TRUE@Section: libs +@USE_GLX_TRUE@Architecture: any +@USE_GLX_TRUE@Depends: ${shlibs:Depends}, ${misc:Depends} +@USE_GLX_TRUE@Description: GStreamer libraries from the "vaapi" set +@USE_GLX_TRUE@ VA-API support libraries for GStreamer. +@USE_GLX_TRUE@ . +@USE_GLX_TRUE@ This package contains glx libraries for the "vaapi" set. -Package: libgstvaapi-wayland-@GST_VAAPI_MAJOR_VERSION@ -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: GStreamer libraries from the "vaapi" set - VA-API support libraries for GStreamer. - . - This package contains Wayland libraries for the "vaapi" set. +@USE_WAYLAND_TRUE@Package: libgstvaapi-wayland-@GST_VAAPI_MAJOR_VERSION@ +@USE_WAYLAND_TRUE@Section: libs +@USE_WAYLAND_TRUE@Architecture: any +@USE_WAYLAND_TRUE@Depends: ${shlibs:Depends}, ${misc:Depends} +@USE_WAYLAND_TRUE@Description: GStreamer libraries from the "vaapi" set +@USE_WAYLAND_TRUE@ VA-API support libraries for GStreamer. +@USE_WAYLAND_TRUE@ . +@USE_WAYLAND_TRUE@ This package contains Wayland libraries for the "vaapi" set. Package: libgstvaapi-dev Architecture: any Section: libdevel Depends: ${shlibs:Depends}, ${misc:Depends}, - libgstvaapi@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), - libgstvaapi-x11-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), - libgstvaapi-glx-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}) +@USE_DRM_TRUE@ libgstvaapi-drm-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), +@USE_X11_TRUE@ libgstvaapi-x11-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), +@USE_GLX_TRUE@ libgstvaapi-glx-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), +@USE_WAYLAND_TRUE@ libgstvaapi-wayland-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), + libgstvaapi@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}) Description: GStreamer development files for libraries from the "vaapi" set GStreamer/VA-API development files. . From 43ba2f1940005289ec7d0c26c434f0465734ce33 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 28 Sep 2012 17:39:43 +0200 Subject: [PATCH 0842/3781] debian: fix Wayland build dependencies. --- configure.ac | 8 +++++++- debian.upstream/control.in | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 3b77e3c431..7f4f8ad28f 100644 --- a/configure.ac +++ b/configure.ac @@ -41,6 +41,9 @@ m4_define([gst_plugins_bad_micro_version], [22]) m4_define([gst_plugins_bad_version], [gst_plugins_bad_major_version.gst_plugins_bad_minor_version.gst_plugins_bad_micro_version]) +# Wayland minimum version number +m4_define([wayland_api_version], [0.95.0]) + # VA-API minimum version number m4_define([va_api_version], [0.30.4]) m4_define([va_api_drm_version], [0.33.0]) @@ -83,6 +86,9 @@ AC_SUBST(GST_VAAPI_MAJOR_VERSION) LIBVA_PACKAGE_VERSION=libva_x11_package_version AC_SUBST(LIBVA_PACKAGE_VERSION) +WAYLAND_API_VERSION=wayland_api_version +AC_SUBST(WAYLAND_API_VERSION) + dnl Versions for GStreamer and plugins-base GST_MAJORMINOR=gst_major_minor_version GST_VERSION_REQUIRED=gst_version @@ -370,7 +376,7 @@ fi dnl Check for Wayland USE_WAYLAND=0 if test "$enable_wayland" = "yes"; then - PKG_CHECK_MODULES(WAYLAND, [wayland-client], + PKG_CHECK_MODULES(WAYLAND, [wayland-client >= wayland_api_version], [USE_WAYLAND=1], [USE_WAYLAND=0]) if test $USE_WAYLAND -eq 1; then diff --git a/debian.upstream/control.in b/debian.upstream/control.in index c40d5b07bc..661856c1a3 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -10,7 +10,7 @@ Build-Depends: debhelper (>= 5), @USE_DRM_TRUE@ libdrm-dev, libudev-dev, @USE_X11_TRUE@ libx11-dev, libxrandr-dev, @USE_GLX_TRUE@ libgl-dev, -@USE_WAYLAND_TRUE@ libwayland-dev, +@USE_WAYLAND_TRUE@ libwayland-dev (>= @WAYLAND_API_VERSION@), libva-dev (>= @LIBVA_PACKAGE_VERSION@) Build-Depends-Indep: gtk-doc-tools (>= @GTKDOC_VERSION@) Standards-Version: 3.7.2 From b65f2bb3d1578930b504aed7f67bff18c30dc02b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 28 Sep 2012 17:41:42 +0200 Subject: [PATCH 0843/3781] debian: fix GStreamer build dependencies. --- debian.upstream/control.in | 1 + 1 file changed, 1 insertion(+) diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 661856c1a3..e89a657a16 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -7,6 +7,7 @@ Build-Depends: debhelper (>= 5), libglib2.0-dev (>= @GLIB_VERSION_REQUIRED@), libgstreamer@GST_MAJORMINOR@-dev (>= @GST_VERSION_REQUIRED@), libgstreamer-plugins-base@GST_MAJORMINOR@-dev (>= @GST_PLUGINS_BASE_VERSION_REQUIRED@), + libgstreamer-plugins-bad@GST_MAJORMINOR@-dev (>= @GST_PLUGINS_BAD_VERSION_REQUIRED@), @USE_DRM_TRUE@ libdrm-dev, libudev-dev, @USE_X11_TRUE@ libx11-dev, libxrandr-dev, @USE_GLX_TRUE@ libgl-dev, From add4f3a298769ffbb99a0fcd1da5cb34c283cd2b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 28 Sep 2012 17:54:03 +0200 Subject: [PATCH 0844/3781] Fix and document build dependencies better. --- README | 23 +++++++++++++++-------- configure.ac | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/README b/README index 27f7c4de80..91dc10827a 100644 --- a/README +++ b/README @@ -19,8 +19,8 @@ Overview gstreamer-vaapi consists in a collection of VA-API based plugins for GStreamer and helper libraries. - * `vaapidecode' is used to decode MPEG-2, MPEG-4, H.264, VC-1, WMV3 - videos to video/x-vaapi-surfaces surfaces, depending on the + * `vaapidecode' is used to decode JPEG, MPEG-2, MPEG-4, H.264, VC-1, + WMV3 videos to video/x-vaapi-surfaces surfaces, depending on the underlying HW capabilities. * `vaapiupload' is used to convert from video/x-raw-yuv pixels to @@ -52,12 +52,19 @@ Requirements Software requirements - * libva-dev >= 1.0.3 (VA/GLX) - * libgstreamer0.10-dev >= 0.10.35.1 - or with GstBaseSink::query() - * libgstreamer-plugins-base0.10-dev >= 0.10.35 - * libgstreamer-plugins-bad0.10-dev >= 0.10.22.1 - or with GstVideoContext, GstSurfaceBuffer, codecparsers + * GStreamer 0.10.x: + libglib2.0-dev (>= 2.28) + libgstreamer0.10-dev (>= 0.10.36) + or with GstBaseSink::query() + libgstreamer-plugins-base0.10-dev (>= 0.10.36) + libgstreamer-plugins-bad0.10-dev (>= 0.10.22.1) + or with GstVideoContext, GstSurfaceBuffer, codecparsers + + * Renderers: + DRM: libva-dev (>= 1.1.0), libdrm-dev, libudev-dev + X11: libva-dev (>= 1.0.1) + GLX: libva-dev (>= 1.0.3) + Wayland: libva-dev (>= 1.1.0), libwayland-dev (>= 0.95.0) Hardware requirements diff --git a/configure.ac b/configure.ac index 7f4f8ad28f..736c31e7aa 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ m4_define([glib_version], # gst version number m4_define([gst_major_version], [0]) m4_define([gst_minor_version], [10]) -m4_define([gst_micro_version], [14]) +m4_define([gst_micro_version], [36]) m4_define([gst_major_minor_version], [gst_major_version.gst_minor_version]) m4_define([gst_version], From 07ee807f8842bbde442feed7582d90237125c6a8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 1 Oct 2012 09:21:03 +0200 Subject: [PATCH 0845/3781] Bump version for development. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 736c31e7aa..98ad4130a6 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) -m4_define([gst_vaapi_minor_version], [4]) +m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [0]) m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], From 0cde1f52893c56e284d60cdbf38ac0c46063f7a9 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Thu, 4 Oct 2012 17:39:52 +0100 Subject: [PATCH 0846/3781] wayland: add support for windowed mode. Rather than always making the surface fullscreen instead implement the set_fullscreen vfunc on GstVaapiWindow and then set the shell surface fullscreen on not depending on that. Reviewed-by: Joe Konno Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 57 +++++++++++++++------ 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 2607c64393..ac170ca37c 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -50,7 +50,9 @@ struct _GstVaapiWindowWaylandPrivate { struct wl_surface *surface; struct wl_buffer *buffer; struct wl_region *opaque_region; - guint redraw_pending : 1; + guint redraw_pending : 1; + guint is_shown : 1; + guint fullscreen_on_show : 1; }; static gboolean @@ -93,6 +95,31 @@ static const struct wl_shell_surface_listener shell_surface_listener = { handle_popup_done }; +static gboolean +gst_vaapi_window_wayland_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) +{ + GstVaapiWindowWaylandPrivate * const priv = + GST_VAAPI_WINDOW_WAYLAND(window)->priv; + + if (!priv->is_shown) { + priv->fullscreen_on_show = fullscreen; + return TRUE; + } + + if (!fullscreen) + wl_shell_surface_set_toplevel(priv->shell_surface); + else { + wl_shell_surface_set_fullscreen( + priv->shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, + 0, + NULL + ); + } + + return TRUE; +} + static gboolean gst_vaapi_window_wayland_create( GstVaapiWindow *window, @@ -122,14 +149,13 @@ gst_vaapi_window_wayland_create( wl_shell_surface_add_listener(priv->shell_surface, &shell_surface_listener, priv); wl_shell_surface_set_toplevel(priv->shell_surface); - wl_shell_surface_set_fullscreen( - priv->shell_surface, - WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, - 0, - NULL - ); + + if (priv->fullscreen_on_show) + gst_vaapi_window_wayland_set_fullscreen(window, TRUE); priv->redraw_pending = FALSE; + priv->is_shown = TRUE; + return TRUE; } @@ -300,15 +326,16 @@ gst_vaapi_window_wayland_class_init(GstVaapiWindowWaylandClass * klass) g_type_class_add_private(klass, sizeof(GstVaapiWindowWaylandPrivate)); - object_class->finalize = gst_vaapi_window_wayland_finalize; - object_class->constructed = gst_vaapi_window_wayland_constructed; + object_class->finalize = gst_vaapi_window_wayland_finalize; + object_class->constructed = gst_vaapi_window_wayland_constructed; - window_class->create = gst_vaapi_window_wayland_create; - window_class->destroy = gst_vaapi_window_wayland_destroy; - window_class->show = gst_vaapi_window_wayland_show; - window_class->hide = gst_vaapi_window_wayland_hide; - window_class->render = gst_vaapi_window_wayland_render; - window_class->resize = gst_vaapi_window_wayland_resize; + window_class->create = gst_vaapi_window_wayland_create; + window_class->destroy = gst_vaapi_window_wayland_destroy; + window_class->show = gst_vaapi_window_wayland_show; + window_class->hide = gst_vaapi_window_wayland_hide; + window_class->render = gst_vaapi_window_wayland_render; + window_class->resize = gst_vaapi_window_wayland_resize; + window_class->set_fullscreen = gst_vaapi_window_wayland_set_fullscreen; } static void From 86b70977f8f0de3a81e8eb9105b8ee0804d8d3bf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 5 Oct 2012 12:06:27 +0200 Subject: [PATCH 0847/3781] wayland: cosmetics (remove tabs). --- gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index b98303e24e..429de3682c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -28,7 +28,7 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ + GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ GstVaapiDisplayWaylandPrivate)) #define GST_VAAPI_DISPLAY_WAYLAND_CAST(display) \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index ac170ca37c..8e04f2d7f5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -166,7 +166,7 @@ gst_vaapi_window_wayland_destroy(GstVaapiWindow * window) GST_VAAPI_WINDOW_WAYLAND(window)->priv; if (priv->shell_surface) { - wl_shell_surface_destroy(priv->shell_surface); + wl_shell_surface_destroy(priv->shell_surface); priv->shell_surface = NULL; } @@ -176,7 +176,7 @@ gst_vaapi_window_wayland_destroy(GstVaapiWindow * window) } if (priv->buffer) { - wl_buffer_destroy(priv->buffer); + wl_buffer_destroy(priv->buffer); priv->buffer = NULL; } } @@ -196,7 +196,7 @@ gst_vaapi_window_wayland_resize( GST_DEBUG("resize window, new size %ux%u", width, height); if (priv->opaque_region) - wl_region_destroy(priv->opaque_region); + wl_region_destroy(priv->opaque_region); priv->opaque_region = wl_compositor_create_region(priv_display->compositor); wl_region_add(priv->opaque_region, 0, 0, width, height); @@ -260,7 +260,7 @@ gst_vaapi_window_wayland_render( /* Wait for the previous frame to complete redraw */ if (priv->redraw_pending) - wl_display_iterate(wl_display, WL_DISPLAY_READABLE); + wl_display_iterate(wl_display, WL_DISPLAY_READABLE); /* XXX: use VA/VPP for other filters */ va_flags = from_GstVaapiSurfaceRenderFlags(flags); From 84f308010fe78d1752ecb244018a0735c32e994d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 5 Oct 2012 13:36:27 +0200 Subject: [PATCH 0848/3781] debian: fix make dist for packaging. --- debian.upstream/Makefile.am | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index cacc5192b2..eba85db789 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -1,52 +1,42 @@ DOCS = \ AUTHORS \ - COPYING \ COPYING.LIB \ NEWS \ README \ $(NULL) DEBIANFILES = \ - changelog \ changelog.in \ compat \ - control \ control.in \ copyright \ - gstreamer-vaapi.install.in \ - gstreamer$(GST_MAJORMINOR)-vaapi.install \ gstreamer-vaapi-doc.install.in \ - gstreamer$(GST_MAJORMINOR)-vaapi-doc.install \ - libgstvaapi.install.in \ - libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ + gstreamer-vaapi.install.in \ libgstvaapi-dev.install.in \ - libgstvaapi-dev.install \ libgstvaapi-drm.install.in \ - libgstvaapi-drm-$(GST_VAAPI_MAJOR_VERSION).install \ - libgstvaapi-x11.install.in \ - libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-glx.install.in \ - libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-wayland.install.in \ - libgstvaapi-wayland-$(GST_VAAPI_MAJOR_VERSION).install \ + libgstvaapi-x11.install.in \ + libgstvaapi.install.in \ rules \ $(NULL) DEBIANGENFILES = \ - control \ changelog \ - gstreamer$(GST_MAJORMINOR)-vaapi.install \ + control \ gstreamer$(GST_MAJORMINOR)-vaapi-doc.install \ + gstreamer$(GST_MAJORMINOR)-vaapi.install \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-dev.install \ libgstvaapi-drm-$(GST_VAAPI_MAJOR_VERSION).install \ - libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-wayland-$(GST_VAAPI_MAJOR_VERSION).install \ + libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ $(NULL) -EXTRA_DIST = \ - $(DEBIANFILES) +EXTRA_DIST = $(DEBIANFILES) + +dist_noinst_DATA = $(DEBIANGENFILES) # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in $(DEBIANGENFILES) From da1e4e391894917577c87deabc514a4d34b52d2d Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Sun, 26 Aug 2012 22:29:04 -0400 Subject: [PATCH 0849/3781] vaapidecode: flush buffers when receiving EOS. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 100ca52869..cd11f36a87 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -407,6 +407,18 @@ gst_vaapidecode_reset(GstVaapiDecode *decode, GstCaps *caps) return gst_vaapidecode_create(decode, caps); } +static gboolean +gst_vaapidecode_flush(GstVaapiDecode *decode) +{ + g_return_val_if_fail(decode->decoder, FALSE); + + if (!gst_vaapi_decoder_put_buffer(decode->decoder, NULL)) + return FALSE; + if (gst_vaapidecode_step(decode) != GST_FLOW_OK) + return FALSE; + return TRUE; +} + /* GstImplementsInterface interface */ static gboolean @@ -680,6 +692,11 @@ gst_vaapidecode_sink_event(GstPad *pad, GstEvent *event) return TRUE; } break; + case GST_EVENT_EOS: + if (!gst_vaapidecode_flush(decode)) { + GST_WARNING("failed to flush buffers"); + } + break; default: break; } From d7fccc351a5c3055772eac62545e66518a6c95bb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Oct 2012 14:40:00 +0200 Subject: [PATCH 0850/3781] decoder: drop unused functions. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 29 ----------------------- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 9 ------- 2 files changed, 38 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index d2ee86cb5f..085b3e00a2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -73,17 +73,6 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) return TRUE; } -static void -push_back_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - - GST_DEBUG("requeue encoded data buffer %p (%d bytes)", - buffer, GST_BUFFER_SIZE(buffer)); - - g_queue_push_head(priv->buffers, buffer); -} - static GstBuffer * pop_buffer(GstVaapiDecoder *decoder) { @@ -572,24 +561,6 @@ gst_vaapi_decoder_ensure_context( return TRUE; } -gboolean -gst_vaapi_decoder_push_buffer_sub( - GstVaapiDecoder *decoder, - GstBuffer *buffer, - guint offset, - guint size -) -{ - GstBuffer *subbuffer; - - subbuffer = gst_buffer_create_sub(buffer, offset, size); - if (!subbuffer) - return FALSE; - - push_back_buffer(decoder, subbuffer); - return TRUE; -} - void gst_vaapi_decoder_push_surface_proxy( GstVaapiDecoder *decoder, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index c753c27fd6..7ab4906dbd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -163,15 +163,6 @@ gst_vaapi_decoder_ensure_context( GstVaapiContextInfo *cip ); -G_GNUC_INTERNAL -gboolean -gst_vaapi_decoder_push_buffer_sub( - GstVaapiDecoder *decoder, - GstBuffer *buffer, - guint offset, - guint size -); - G_GNUC_INTERNAL void gst_vaapi_decoder_push_surface_proxy( From 86981eea41485361a6c3f68815dc7004910942ec Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Oct 2012 14:48:00 +0200 Subject: [PATCH 0851/3781] decoder: refine semantics of gst_vaapi_decoder_put_buffer(). Improve the semantics for gst_vaapi_decoder_put_buffer() when an empty buffer is passed on. An empty buffer is a buffer with a NULL data pointer or with a size equals to zero. In this case, that buffer is simply skipped and the function returns TRUE. A NULL buffer argument still marks the end-of-stream. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 085b3e00a2..b8052d30dd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -389,7 +389,10 @@ gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder) * Queues a #GstBuffer to the HW decoder. The decoder holds a * reference to @buf. * - * Caller can notify an End-Of-Stream with @buf set to %NULL. + * Caller can notify an End-Of-Stream with @buf set to %NULL. However, + * if an empty buffer is passed, i.e. a buffer with %NULL data pointer + * or size equals to zero, then the function ignores this buffer and + * returns %TRUE. * * Return value: %TRUE on success */ @@ -398,7 +401,12 @@ gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf) { g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); - return push_buffer(decoder, buf ? gst_buffer_ref(buf) : NULL); + if (buf) { + if (!GST_BUFFER_DATA(buf) || GST_BUFFER_SIZE(buf) <= 0) + return TRUE; + buf = gst_buffer_ref(buf); + } + return push_buffer(decoder, buf); } /** From 8f7d19f010a7a8a525fb7bb2c36c75f9ca4c94b6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Oct 2012 15:01:38 +0200 Subject: [PATCH 0852/3781] mpeg2: fix return value for "no-data" conditions. Fix return value when the second scan for start code fails. This means there is not enough data to determine the full extents of the current packet and the function shall return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA in this case, instead of GST_VAAPI_DECODER_STATUS_SUCCESS. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 39 +++++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 21bbee6dc3..2b8851f438 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -963,9 +963,14 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); - size = gst_adapter_available(priv->adapter); - status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + size = gst_adapter_available(priv->adapter); do { + if (size == 0) { + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; if (size < 8) break; ofs = scan_for_start_code(priv->adapter, 0, size, &start_code); @@ -978,6 +983,7 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) break; + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; if (size < 8) break; ofs = scan_for_start_code(priv->adapter, 4, size - 4, NULL); @@ -988,8 +994,10 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) if (ofs == 4) { // Ignore empty user-data packets - if ((start_code & 0xff) == GST_MPEG_VIDEO_PACKET_USER_DATA) + if ((start_code & 0xff) == GST_MPEG_VIDEO_PACKET_USER_DATA) { + status = GST_VAAPI_DECODER_STATUS_SUCCESS; continue; + } GST_ERROR("failed to get a valid packet (SC: 0x%08x)", start_code); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; @@ -1001,9 +1009,16 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) type = start_code & 0xff; switch (type) { case GST_MPEG_VIDEO_PACKET_PICTURE: - if (!priv->width || !priv->height) + if (priv->width > 0 && priv->height > 0) { + status = decode_picture(decoder, buf, buf_size); break; - status = decode_picture(decoder, buf, buf_size); + } + + // Ignore packet while picture size is undefined + // i.e. missing sequence headers, or not parsed correctly + skip_picture_unknown_size: + GST_WARNING("failed to parse picture of unknown size"); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; case GST_MPEG_VIDEO_PACKET_SEQUENCE: status = decode_sequence(decoder, buf, buf_size); @@ -1018,13 +1033,15 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) status = decode_quant_matrix_ext(decoder, buf, buf_size); break; case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: - if (!priv->width || !priv->height) + if (priv->width > 0 && priv->height > 0) { + status = decode_picture_ext(decoder, buf, buf_size); break; - status = decode_picture_ext(decoder, buf, buf_size); - break; + } + goto skip_picture_unknown_size; default: // Ignore unknown extensions GST_WARNING("unsupported start-code extension (0x%02x)", id); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; } break; @@ -1042,8 +1059,12 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) default: if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { - if (!priv->current_picture) + if (!priv->current_picture) { + // Ignore packet while picture is undefined + // i.e. missing picture headers, or not parsed correctly + status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; + } status = decode_slice( decoder, type - GST_MPEG_VIDEO_PACKET_SLICE_MIN, From 91da4fcb18dc83e8e03caf8905a5ee09c564444b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Oct 2012 15:40:49 +0200 Subject: [PATCH 0853/3781] mpeg2: fix memory leak of empty packets. Fix memory leakage of empty packets, i.e. packets that only contain the start code prefix. In particular, free empty user-data packets. Besides, the codec parser will already fail gracefully if the packet to parse does not have the minimum required size. So, we can also completely drop the block of code that used to handle packets of size 4 (including the start code). --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 2b8851f438..92ff03287b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -971,7 +971,7 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) } status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - if (size < 8) + if (size < 4) break; ofs = scan_for_start_code(priv->adapter, 0, size, &start_code); if (ofs < 0) @@ -992,17 +992,6 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) buffer = gst_adapter_take_buffer(priv->adapter, ofs); size -= ofs; - if (ofs == 4) { - // Ignore empty user-data packets - if ((start_code & 0xff) == GST_MPEG_VIDEO_PACKET_USER_DATA) { - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - continue; - } - GST_ERROR("failed to get a valid packet (SC: 0x%08x)", start_code); - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - break; - } - buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); From dc03ca91008ef92465a2b099c976b6775f78f6f2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Oct 2012 15:34:18 +0200 Subject: [PATCH 0854/3781] mpeg2: fix end-of-stream conditions (flush). Decode pending data in the adapter prior to processing the actual code for end-of-stream. Initial code from Feng Yuan. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 92ff03287b..a4544c6a49 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -950,6 +950,7 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstVaapiDecoderStatus status; + gboolean is_eos; guchar *buf; guint buf_size, size; guint32 start_code; @@ -958,10 +959,9 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); - if (!buf && buf_size == 0) - return decode_sequence_end(decoder); - - gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); + is_eos = GST_BUFFER_IS_EOS(buffer); + if (buf && buf_size > 0) + gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); size = gst_adapter_available(priv->adapter); do { @@ -987,8 +987,12 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) if (size < 8) break; ofs = scan_for_start_code(priv->adapter, 4, size - 4, NULL); - if (ofs < 0) - break; + if (ofs < 0) { + // Assume the whole packet is present if end-of-stream + if (!is_eos) + break; + ofs = size; + } buffer = gst_adapter_take_buffer(priv->adapter, ofs); size -= ofs; @@ -1072,6 +1076,10 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) } gst_buffer_unref(buffer); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); + + if (is_eos && (status == GST_VAAPI_DECODER_STATUS_SUCCESS || + status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA)) + status = decode_sequence_end(decoder); return status; } From 388e881ba9143d27a94b812f57d41abc870b9e4e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Oct 2012 09:45:03 +0200 Subject: [PATCH 0855/3781] mpeg2: add decode_packet() helper function. Split decode_buffer() into the core infrastructure that determines the packets contained in the adapter and the actual function that decodes the packet data. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 163 +++++++++++---------- 1 file changed, 87 insertions(+), 76 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index a4544c6a49..928c64f045 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -945,6 +945,92 @@ scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) scp); } +static GstVaapiDecoderStatus +decode_packet(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + guchar type; + + /* The packet defined by buf and buf_size contains the start code */ + type = buf[3]; + switch (type) { + case GST_MPEG_VIDEO_PACKET_PICTURE: + if (!priv->width || !priv->height) + goto unknown_picture_size; + status = decode_picture(decoder, buf, buf_size); + break; + case GST_MPEG_VIDEO_PACKET_SEQUENCE: + status = decode_sequence(decoder, buf, buf_size); + break; + case GST_MPEG_VIDEO_PACKET_EXTENSION: { + const guchar id = buf[4] >> 4; + switch (id) { + case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: + status = decode_sequence_ext(decoder, buf, buf_size); + break; + case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: + status = decode_quant_matrix_ext(decoder, buf, buf_size); + break; + case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: + if (!priv->width || !priv->height) + goto unknown_picture_size; + status = decode_picture_ext(decoder, buf, buf_size); + break; + default: + // Ignore unknown start-code extensions + GST_WARNING("unsupported start code extension (0x%02x)", id); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + break; + } + case GST_MPEG_VIDEO_PACKET_SEQUENCE_END: + status = decode_sequence_end(decoder); + break; + case GST_MPEG_VIDEO_PACKET_GOP: + status = decode_gop(decoder, buf, buf_size); + break; + case GST_MPEG_VIDEO_PACKET_USER_DATA: + // Ignore user-data packets + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + default: + if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { + if (!priv->current_picture) + goto undefined_picture; + status = decode_slice( + decoder, + type - GST_MPEG_VIDEO_PACKET_SLICE_MIN, + buf, buf_size + ); + break; + } + else if (type >= 0xb9 && type <= 0xff) { + // Ignore system start codes (PES headers) + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + GST_WARNING("unsupported start code (0x%02x)", type); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + return status; + +unknown_picture_size: + // Ignore packet while picture size is undefined + // i.e. missing sequence headers, or not parsed correctly + GST_WARNING("failed to parse picture of unknown size"); + return GST_VAAPI_DECODER_STATUS_SUCCESS; + +undefined_picture: + // Ignore packet while picture is undefined + // i.e. missing picture headers, or not parsed correctly + GST_WARNING("failed to parse slice with undefined picture"); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) { @@ -954,7 +1040,6 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) guchar *buf; guint buf_size, size; guint32 start_code; - guint8 type; gint ofs; buf = GST_BUFFER_DATA(buffer); @@ -998,82 +1083,8 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); + status = decode_packet(decoder, buf, buf_size); - type = start_code & 0xff; - switch (type) { - case GST_MPEG_VIDEO_PACKET_PICTURE: - if (priv->width > 0 && priv->height > 0) { - status = decode_picture(decoder, buf, buf_size); - break; - } - - // Ignore packet while picture size is undefined - // i.e. missing sequence headers, or not parsed correctly - skip_picture_unknown_size: - GST_WARNING("failed to parse picture of unknown size"); - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - case GST_MPEG_VIDEO_PACKET_SEQUENCE: - status = decode_sequence(decoder, buf, buf_size); - break; - case GST_MPEG_VIDEO_PACKET_EXTENSION: { - const guchar id = buf[4] >> 4; - switch (id) { - case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: - status = decode_sequence_ext(decoder, buf, buf_size); - break; - case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: - status = decode_quant_matrix_ext(decoder, buf, buf_size); - break; - case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: - if (priv->width > 0 && priv->height > 0) { - status = decode_picture_ext(decoder, buf, buf_size); - break; - } - goto skip_picture_unknown_size; - default: - // Ignore unknown extensions - GST_WARNING("unsupported start-code extension (0x%02x)", id); - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } - break; - } - case GST_MPEG_VIDEO_PACKET_SEQUENCE_END: - status = decode_sequence_end(decoder); - break; - case GST_MPEG_VIDEO_PACKET_GOP: - status = decode_gop(decoder, buf, buf_size); - break; - case GST_MPEG_VIDEO_PACKET_USER_DATA: - // Ignore user-data packets - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - default: - if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && - type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { - if (!priv->current_picture) { - // Ignore packet while picture is undefined - // i.e. missing picture headers, or not parsed correctly - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } - status = decode_slice( - decoder, - type - GST_MPEG_VIDEO_PACKET_SLICE_MIN, - buf, buf_size - ); - break; - } - else if (type >= 0xb9 && type <= 0xff) { - // Ignore system start codes (PES headers) - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } - GST_WARNING("unsupported start code (0x%02x)", type); - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - break; - } gst_buffer_unref(buffer); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); From 6f2e885f11c0986cdbdbd114c37c6765c7e8bbd9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Oct 2012 10:31:39 +0200 Subject: [PATCH 0856/3781] h264: fix end-of-stream conditions (flush). Decode pending data in the adapter prior to processing the actual code for end-of-stream. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 32 ++++++++++++++++------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 7e78695350..a3af794139 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2220,6 +2220,7 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) GstVaapiDecoderStatus status; GstH264ParserResult result; GstH264NalUnit nalu; + gboolean is_eos; const guchar *buf; guint i, buf_size, nalu_size, size; guint32 start_code; @@ -2227,13 +2228,17 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); - if (!buf && buf_size == 0) - return decode_sequence_end(decoder); - - gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); + is_eos = GST_BUFFER_IS_EOS(buffer); + if (buf && buf_size > 0) + gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); size = gst_adapter_available(priv->adapter); do { + if (size == 0) { + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder)); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) break; @@ -2264,7 +2269,7 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) ); } else { - if (size < 8) + if (size < 4) break; ofs = scan_for_start_code(priv->adapter, 0, size, &start_code); if (ofs < 0) @@ -2272,11 +2277,14 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) gst_adapter_flush(priv->adapter, ofs); size -= ofs; - if (size < 8) - break; - ofs = scan_for_start_code(priv->adapter, 4, size - 4, NULL); - if (ofs < 0) - break; + ofs = G_UNLIKELY(size < 8) ? -1 : + scan_for_start_code(priv->adapter, 4, size - 4, NULL); + if (ofs < 0) { + // Assume the whole NAL unit is present if end-of-stream + if (!is_eos) + break; + ofs = size; + } buffer = gst_adapter_take_buffer(priv->adapter, ofs); size -= ofs; @@ -2328,6 +2336,10 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) } gst_buffer_unref(buffer); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); + + if (is_eos && (status == GST_VAAPI_DECODER_STATUS_SUCCESS || + status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA)) + status = decode_sequence_end(decoder); return status; } From 3f430b32a4b5415d70744295432e8a3ba0e3d6a6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Oct 2012 10:35:20 +0200 Subject: [PATCH 0857/3781] h264: add decode_nalu() helper function. Split decode_buffer() into the core infrastructure that determines the NAL units contained in the adapter and the actual function that decodes the NAL unit. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 77 ++++++++++++----------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index a3af794139..fc6cbf810f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2213,6 +2213,45 @@ scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) scp); } +static GstVaapiDecoderStatus +decode_nalu(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) +{ + GstVaapiDecoderStatus status; + + switch (nalu->type) { + case GST_H264_NAL_SLICE_IDR: + /* fall-through. IDR specifics are handled in init_picture() */ + case GST_H264_NAL_SLICE: + status = decode_slice(decoder, nalu); + break; + case GST_H264_NAL_SPS: + status = decode_sps(decoder, nalu); + break; + case GST_H264_NAL_PPS: + status = decode_pps(decoder, nalu); + break; + case GST_H264_NAL_SEI: + status = decode_sei(decoder, nalu); + break; + case GST_H264_NAL_SEQ_END: + status = decode_sequence_end(decoder); + break; + case GST_H264_NAL_AU_DELIMITER: + /* skip all Access Unit NALs */ + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + case GST_H264_NAL_FILLER_DATA: + /* skip all Filler Data NALs */ + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + default: + GST_WARNING("unsupported NAL unit type %d", nalu->type); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + return status; +} + static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) { @@ -2298,42 +2337,8 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) ); } status = get_status(result); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - gst_buffer_unref(buffer); - break; - } - - switch (nalu.type) { - case GST_H264_NAL_SLICE_IDR: - /* fall-through. IDR specifics are handled in init_picture() */ - case GST_H264_NAL_SLICE: - status = decode_slice(decoder, &nalu); - break; - case GST_H264_NAL_SPS: - status = decode_sps(decoder, &nalu); - break; - case GST_H264_NAL_PPS: - status = decode_pps(decoder, &nalu); - break; - case GST_H264_NAL_SEI: - status = decode_sei(decoder, &nalu); - break; - case GST_H264_NAL_SEQ_END: - status = decode_sequence_end(decoder); - break; - case GST_H264_NAL_AU_DELIMITER: - /* skip all Access Unit NALs */ - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - case GST_H264_NAL_FILLER_DATA: - /* skip all Filler Data NALs */ - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - default: - GST_WARNING("unsupported NAL unit type %d", nalu.type); - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - break; - } + if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) + status = decode_nalu(decoder, &nalu); gst_buffer_unref(buffer); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); From fa873969056c534a330bdb7909d6e3c32df769fd Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Thu, 27 Sep 2012 18:05:46 +0100 Subject: [PATCH 0858/3781] h264: use pixel-aspect-ratio from SPS header. Propagate pixel-aspect-ratio determined by the GStreamer codecparser from the sequence headers. Signed-off-by: Simon Farnsworth Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index fc6cbf810f..d0ff1ec868 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -689,6 +689,7 @@ end: static GstVaapiDecoderStatus decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) { + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderH264Private * const priv = decoder->priv; GstH264SPS * const sps = &priv->last_sps; GstH264ParserResult result; @@ -703,6 +704,11 @@ decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) if (result != GST_H264_PARSER_OK) return get_status(result); + gst_vaapi_decoder_set_pixel_aspect_ratio( + base_decoder, + sps->vui_parameters.par_n, + sps->vui_parameters.par_d + ); return ensure_context(decoder, sps); } From 9692201505b4e39b08ea04049903c2564a7899f6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 11 Oct 2012 13:40:37 +0200 Subject: [PATCH 0859/3781] autogen: fix check for gtkdocize and autoreconf. If gtkdocize or autoreconf programs were not found, then the autogen.sh script would fail to report that correctly because test -z was not passed any argument (empty string "" in this case). --- autogen.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autogen.sh b/autogen.sh index 920e77e963..3d7ffd8306 100755 --- a/autogen.sh +++ b/autogen.sh @@ -16,7 +16,7 @@ cd "$srcdir" mkdir -p m4 GTKDOCIZE=`which gtkdocize` -if test -z $GTKDOCIZE; then +if test -z "$GTKDOCIZE"; then echo "*** No gtk-doc support ***" echo "EXTRA_DIST =" > gtk-doc.make else @@ -24,7 +24,7 @@ else fi AUTORECONF=`which autoreconf` -if test -z $AUTORECONF; then +if test -z "$AUTORECONF"; then echo "*** No autoreconf found ***" exit 1 else From 8ddef13c071061dbf448bc7981ec3fe82bec5b2d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 11 Oct 2012 14:17:12 +0200 Subject: [PATCH 0860/3781] .gitignore: updates. --- .gitignore | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 2cd25a5bf6..00467e092c 100644 --- a/.gitignore +++ b/.gitignore @@ -41,23 +41,27 @@ debian.upstream/control debian.upstream/gstreamer0.10-vaapi-doc.install debian.upstream/gstreamer0.10-vaapi.install debian.upstream/libgstvaapi-dev.install +debian.upstream/libgstvaapi-drm-0.install debian.upstream/libgstvaapi-glx-0.install +debian.upstream/libgstvaapi-wayland-0.install debian.upstream/libgstvaapi-x11-0.install debian.upstream/libgstvaapi0.install +docs/reference/libs/*.stamp docs/reference/libs/html* docs/reference/libs/libs-docs.xml docs/reference/libs/tmpl* docs/reference/libs/xml* -docs/reference/libs/*.stamp +docs/reference/plugins/*.stamp docs/reference/plugins/html* docs/reference/plugins/plugins-docs.xml docs/reference/plugins/tmpl* docs/reference/plugins/xml* -docs/reference/plugins/*.stamp gst-libs/gst/gstutils_version.h gtk-doc.make pkgconfig/gstreamer-vaapi-0.10.pc +pkgconfig/gstreamer-vaapi-drm-0.10.pc pkgconfig/gstreamer-vaapi-glx-0.10.pc +pkgconfig/gstreamer-vaapi-wayland-0.10.pc pkgconfig/gstreamer-vaapi-x11-0.10.pc tests/test-decode tests/test-display From c3b343f3241af8328e4f43bb6431a1d12e8b0388 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 11 Oct 2012 10:03:14 +0200 Subject: [PATCH 0861/3781] Add codecparsers submodule. --- .gitmodules | 3 +++ Makefile.am | 2 +- autogen.sh | 11 +++++++++++ configure.ac | 1 + ext/Makefile.am | 29 +++++++++++++++++++++++++++++ ext/codecparsers | 1 + 6 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 .gitmodules create mode 100644 ext/Makefile.am create mode 160000 ext/codecparsers diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..e40ceed55b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ext/codecparsers"] + path = ext/codecparsers + url = git://gitorious.org/vaapi/gstreamer-codecparsers.git diff --git a/Makefile.am b/Makefile.am index a20451466f..08a5e2a883 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} AUTOMAKE_OPTIONS = foreign -SUBDIRS = debian.upstream gst-libs gst pkgconfig tests docs +SUBDIRS = debian.upstream gst-libs gst pkgconfig tests docs ext # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ diff --git a/autogen.sh b/autogen.sh index 3d7ffd8306..4314352f43 100755 --- a/autogen.sh +++ b/autogen.sh @@ -15,6 +15,17 @@ cd "$srcdir" mkdir -p m4 +GIT=`which git` +if test -z "$GIT"; then + echo "*** No git found ***" + exit 1 +else + if test ! -f ext/codecparsers/autogen.sh; then + $GIT submodule init + fi + $GIT submodule update +fi + GTKDOCIZE=`which gtkdocize` if test -z "$GTKDOCIZE"; then echo "*** No gtk-doc support ***" diff --git a/configure.ac b/configure.ac index 98ad4130a6..eb97a7a36a 100644 --- a/configure.ac +++ b/configure.ac @@ -530,6 +530,7 @@ debian.upstream/libgstvaapi-x11.install.in docs/reference/libs/libs-docs.xml docs/reference/plugins/Makefile docs/reference/plugins/plugins-docs.xml + ext/Makefile gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/codecparsers/Makefile diff --git a/ext/Makefile.am b/ext/Makefile.am new file mode 100644 index 0000000000..bad55d50e3 --- /dev/null +++ b/ext/Makefile.am @@ -0,0 +1,29 @@ +EXTRA_DIST = + +codecparsers_srcdir = \ + $(top_srcdir)/ext/codecparsers/gst-libs/gst/codecparsers + +codecparsers_source_c = \ + gsth264parser.c \ + gstjpegparser.c \ + gstmpeg4parser.c \ + gstmpegvideoparser.c \ + gstvc1parser.c \ + parserutils.c \ + $(NULL) + +EXTRA_DIST += $(codecparsers_source_c:%.c=$(codecparsers_srcdir)/%.c) + +codecparsers_source_h = \ + gsth264parser.h \ + gstjpegparser.h \ + gstmpeg4parser.h \ + gstmpegvideoparser.h \ + gstvc1parser.h \ + parserutils.h \ + $(NULL) + +EXTRA_DIST += $(codecparsers_source_h:%.h=$(codecparsers_srcdir)/%.h) + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/ext/codecparsers b/ext/codecparsers new file mode 160000 index 0000000000..70dfc67bc6 --- /dev/null +++ b/ext/codecparsers @@ -0,0 +1 @@ +Subproject commit 70dfc67bc6953363a4273bbd0381f09433cea36f From cee782a177ce857f30052a2aae53a80b9fb3e96d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 11 Oct 2012 13:23:02 +0200 Subject: [PATCH 0862/3781] codecparsers: jpeg: use submodule sources. --- .gitignore | 2 + configure.ac | 19 +- gst-libs/gst/codecparsers/Makefile.am | 37 +- gst-libs/gst/codecparsers/gstjpegparser.c | 611 ---------------------- gst-libs/gst/codecparsers/gstjpegparser.h | 414 --------------- gst-libs/gst/vaapi/Makefile.am | 8 +- 6 files changed, 39 insertions(+), 1052 deletions(-) delete mode 100644 gst-libs/gst/codecparsers/gstjpegparser.c delete mode 100644 gst-libs/gst/codecparsers/gstjpegparser.h diff --git a/.gitignore b/.gitignore index 00467e092c..0ff526c3f9 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,8 @@ docs/reference/plugins/html* docs/reference/plugins/plugins-docs.xml docs/reference/plugins/tmpl* docs/reference/plugins/xml* +gst-libs/gst/codecparsers/*.[ch] +gst-libs/gst/codecparsers/.timestamp.* gst-libs/gst/gstutils_version.h gtk-doc.make pkgconfig/gstreamer-vaapi-0.10.pc diff --git a/configure.ac b/configure.ac index eb97a7a36a..728a2c6aa5 100644 --- a/configure.ac +++ b/configure.ac @@ -211,9 +211,6 @@ PKG_CHECK_MODULES([GST_BASEVIDEO], [gstreamer-basevideo-$GST_MAJORMINOR >= gst_plugins_bad_version]) dnl ... bitstream parsers -USE_CODEC_PARSERS=1 -USE_LOCAL_CODEC_PARSERS=0 - PKG_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_MAJORMINOR >= gst_plugins_bad_version]) @@ -244,8 +241,8 @@ fi dnl ... JPEG parser, not upstream yet AC_CACHE_CHECK([for JPEG parser], ac_cv_have_gst_jpeg_parser, [ - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" AC_COMPILE_IFELSE( @@ -253,17 +250,13 @@ AC_CACHE_CHECK([for JPEG parser], [[#include ]], [[GstJpegImage jpeg_image;]])], [ac_cv_have_gst_jpeg_parser="yes"], - [ac_cv_have_gst_jpeg_parser="no" USE_LOCAL_CODEC_PARSERS=1] + [ac_cv_have_gst_jpeg_parser="no"] ) - CFLAGS="$saved_CFLAGS" + CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) - -if test "$ac_cv_have_gst_jpeg_parser" = "yes"; then - AC_DEFINE_UNQUOTED(HAVE_GST_JPEG_PARSER, 1, - [Defined to 1 if JPEG parser exists.]) -fi -AM_CONDITIONAL(USE_LOCAL_CODEC_PARSERS, test $USE_LOCAL_CODEC_PARSERS -eq 1) +AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_JPEG], + [test "$ac_cv_have_gst_jpeg_parser" != "yes"]) dnl GST_ALL_LDFLAGS: dnl LDFLAGS really should only contain flags, not libs - they get added before diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index aa10113b48..4660a7dcff 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -2,6 +2,9 @@ noinst_LTLIBRARIES = \ libgstvaapi-codecparsers.la \ $(NULL) +local_codecparsers_srcdir = \ + $(top_srcdir)/ext/codecparsers/gst-libs/gst/codecparsers + libgstvaapi_codecparsers_cflags = \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ @@ -14,17 +17,23 @@ libgstvaapi_codecparsers_libs = \ $(GST_LIBS) \ $(NULL) -libgstvaapi_codecparsers_source_c = \ - gstjpegparser.c \ +gen_source_c = +gen_source_h = + +if USE_LOCAL_CODEC_PARSERS_JPEG +gen_source_c += gstjpegparser.c +gen_source_h += gstjpegparser.h +endif + +GENFILES = \ + $(gen_source_c) \ + $(gen_source_h) \ $(NULL) -libgstvaapi_codecparsers_source_h = \ - gstjpegparser.h \ - $(NULL) +nodist_EXTRA_libgstvaapi_codecparsers_la_SOURCES = dummy.c -libgstvaapi_codecparsers_la_SOURCES = \ - $(libgstvaapi_codecparsers_source_c) \ - $(libgstvaapi_codecparsers_source_h) \ +nodist_libgstvaapi_codecparsers_la_SOURCES = \ + $(gen_source_c) \ $(NULL) libgstvaapi_codecparsers_la_CFLAGS = \ @@ -39,5 +48,17 @@ libgstvaapi_codecparsers_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) +all-local: .timestamp.symlinks + +.timestamp.symlinks: $(GENFILES) + touch $@ + +$(gen_source_c): %.c: $(local_codecparsers_srcdir)/%.c + $(LN_S) -f $< $@ +$(gen_source_h): %.h: $(local_codecparsers_srcdir)/%.h + $(LN_S) -f $< $@ + +DISTCLEANFILES = $(GENFILES) .timestamp.symlinks + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c deleted file mode 100644 index 80de3fff0d..0000000000 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ /dev/null @@ -1,611 +0,0 @@ -/* - * gstjpegparser.c - JPEG parser - * - * Copyright (C) 2011-2012 Intel Corporation - * - * 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 -#include -#include -#include "gstjpegparser.h" - -#ifndef GST_DISABLE_GST_DEBUG - -#define GST_CAT_DEFAULT ensure_debug_category() - -static GstDebugCategory * -ensure_debug_category (void) -{ - static gsize cat_gonce = 0; - - if (g_once_init_enter (&cat_gonce)) { - gsize cat_done; - - cat_done = (gsize) _gst_debug_category_new ("codecparsers_jpeg", 0, - "GstJpegCodecParser"); - - g_once_init_leave (&cat_gonce, cat_done); - } - - return (GstDebugCategory *) cat_gonce; -} -#else - -#define ensure_debug_category() /* NOOP */ - -#endif /* GST_DISABLE_GST_DEBUG */ - -#define DEBUG_PRINT_COMMENT 0 - -#define READ_UINT8(reader, val) G_STMT_START { \ - if (!gst_byte_reader_get_uint8 ((reader), &(val))) { \ - GST_WARNING ("failed to read uint8"); \ - goto failed; \ - } \ - } G_STMT_END - -#define READ_UINT16(reader, val) G_STMT_START { \ - if (!gst_byte_reader_get_uint16_be ((reader), &(val))) { \ - GST_WARNING ("failed to read uint16"); \ - goto failed; \ - } \ - } G_STMT_END - -#define READ_BYTES(reader, buf, length) G_STMT_START { \ - const guint8 *vals; \ - if (!gst_byte_reader_get_data (reader, length, &vals)) { \ - GST_WARNING ("failed to read bytes, size:%d", length); \ - goto failed; \ - } \ - memcpy (buf, vals, length); \ - } G_STMT_END - -#define U_READ_UINT8(reader, val) G_STMT_START { \ - (val) = gst_byte_reader_get_uint8_unchecked(reader); \ - } G_STMT_END - -#define U_READ_UINT16(reader, val) G_STMT_START { \ - (val) = gst_byte_reader_get_uint16_be_unchecked(reader); \ - } G_STMT_END - - -/* Table used to address an 8x8 matrix in zig-zag order */ -/* *INDENT-OFF* */ -static const guint8 zigzag_index[64] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63 -}; -/* *INDENT-ON* */ - -/* Table K.1 - Luminance quantization table */ -/* *INDENT-OFF* */ -static const guint8 default_luminance_quant_table[64] = { - 16, 11, 10, 16, 24, 40, 51, 61, - 12, 12, 14, 19, 26, 58, 60, 55, - 14, 13, 16, 24, 40, 57, 69, 56, - 14, 17, 22, 29, 51, 87, 80, 62, - 18, 22, 37, 56, 68, 109, 103, 77, - 24, 35, 55, 64, 81, 104, 113, 92, - 49, 64, 78, 87, 103, 121, 120, 101, - 72, 92, 95, 98, 112, 100, 103, 99 -}; -/* *INDENT-ON* */ - -/* Table K.2 - Chrominance quantization table */ -/* *INDENT-OFF* */ -static const guint8 default_chrominance_quant_table[64] = { - 17, 18, 24, 47, 99, 99, 99, 99, - 18, 21, 26, 66, 99, 99, 99, 99, - 24, 26, 56, 99, 99, 99, 99, 99, - 47, 66, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 -}; -/* *INDENT-ON* */ - -typedef struct _GstJpegHuffmanTableEntry GstJpegHuffmanTableEntry; -struct _GstJpegHuffmanTableEntry -{ - guint8 value; /* category */ - guint8 length; /* code length in bits */ -}; - -/* Table K.3 - Table for luminance DC coefficient differences */ -static const GstJpegHuffmanTableEntry default_luminance_dc_table[] = { - {0x00, 2}, {0x01, 3}, {0x02, 3}, {0x03, 3}, {0x04, 3}, {0x05, 3}, - {0x06, 4}, {0x07, 5}, {0x08, 6}, {0x09, 7}, {0x0a, 8}, {0x0b, 9} -}; - -/* Table K.4 - Table for chrominance DC coefficient differences */ -static const GstJpegHuffmanTableEntry default_chrominance_dc_table[] = { - {0x00, 2}, {0x01, 2}, {0x02, 2}, {0x03, 3}, {0x04, 4}, {0x05, 5}, - {0x06, 6}, {0x07, 7}, {0x08, 8}, {0x09, 9}, {0x0a, 10}, {0x0b, 11} -}; - -/* Table K.5 - Table for luminance AC coefficients */ -/* *INDENT-OFF* */ -static const GstJpegHuffmanTableEntry default_luminance_ac_table[] = { - {0x00, 4}, {0x01, 2}, {0x02, 2}, {0x03, 3}, {0x04, 4}, {0x05, 5}, - {0x06, 7}, {0x07, 8}, {0x08, 10}, {0x09, 16}, {0x0a, 16}, {0x11, 4}, - {0x12, 5}, {0x13, 7}, {0x14, 9}, {0x15, 11}, {0x16, 16}, {0x17, 16}, - {0x18, 16}, {0x19, 16}, {0x1a, 16}, {0x21, 5}, {0x22, 8}, {0x23, 10}, - {0x24, 12}, {0x25, 16}, {0x26, 16}, {0x27, 16}, {0x28, 16}, {0x29, 16}, - {0x2a, 16}, {0x31, 6}, {0x32, 9}, {0x33, 12}, {0x34, 16}, {0x35, 16}, - {0x36, 16}, {0x37, 16}, {0x38, 16}, {0x39, 16}, {0x3a, 16}, {0x41, 6}, - {0x42, 10}, {0x43, 16}, {0x44, 16}, {0x45, 16}, {0x46, 16}, {0x47, 16}, - {0x48, 16}, {0x49, 16}, {0x4a, 16}, {0x51, 7}, {0x52, 11}, {0x53, 16}, - {0x54, 16}, {0x55, 16}, {0x56, 16}, {0x57, 16}, {0x58, 16}, {0x59, 16}, - {0x5a, 16}, {0x61, 7}, {0x62, 12}, {0x63, 16}, {0x64, 16}, {0x65, 16}, - {0x66, 16}, {0x67, 16}, {0x68, 16}, {0x69, 16}, {0x6a, 16}, {0x71, 8}, - {0x72, 12}, {0x73, 16}, {0x74, 16}, {0x75, 16}, {0x76, 16}, {0x77, 16}, - {0x78, 16}, {0x79, 16}, {0x7a, 16}, {0x81, 9}, {0x82, 15}, {0x83, 16}, - {0x84, 16}, {0x85, 16}, {0x86, 16}, {0x87, 16}, {0x88, 16}, {0x89, 16}, - {0x8a, 16}, {0x91, 9}, {0x92, 16}, {0x93, 16}, {0x94, 16}, {0x95, 16}, - {0x96, 16}, {0x97, 16}, {0x98, 16}, {0x99, 16}, {0x9a, 16}, {0xa1, 9}, - {0xa2, 16}, {0xa3, 16}, {0xa4, 16}, {0xa5, 16}, {0xa6, 16}, {0xa7, 16}, - {0xa8, 16}, {0xa9, 16}, {0xaa, 16}, {0xb1, 10}, {0xb2, 16}, {0xb3, 16}, - {0xb4, 16}, {0xb5, 16}, {0xb6, 16}, {0xb7, 16}, {0xb8, 16}, {0xb9, 16}, - {0xba, 16}, {0xc1, 10}, {0xc2, 16}, {0xc3, 16}, {0xc4, 16}, {0xc5, 16}, - {0xc6, 16}, {0xc7, 16}, {0xc8, 16}, {0xc9, 16}, {0xca, 16}, {0xd1, 11}, - {0xd2, 16}, {0xd3, 16}, {0xd4, 16}, {0xd5, 16}, {0xd6, 16}, {0xd7, 16}, - {0xd8, 16}, {0xd9, 16}, {0xda, 16}, {0xe1, 16}, {0xe2, 16}, {0xe3, 16}, - {0xe4, 16}, {0xe5, 16}, {0xe6, 16}, {0xe7, 16}, {0xe8, 16}, {0xe9, 16}, - {0xea, 16}, {0xf0, 11}, {0xf1, 16}, {0xf2, 16}, {0xf3, 16}, {0xf4, 16}, - {0xf5, 16}, {0xf6, 16}, {0xf7, 16}, {0xf8, 16}, {0xf9, 16}, {0xfa, 16} -}; -/* *INDENT-ON* */ - -/* Table K.6 - Table for chrominance AC coefficients */ -/* *INDENT-OFF* */ -static const GstJpegHuffmanTableEntry default_chrominance_ac_table[] = { - {0x00, 2}, {0x01, 2}, {0x02, 3}, {0x03, 4}, {0x04, 5}, {0x05, 5}, - {0x06, 6}, {0x07, 7}, {0x08, 9}, {0x09, 10}, {0x0a, 12}, {0x11, 4}, - {0x12, 6}, {0x13, 8}, {0x14, 9}, {0x15, 11}, {0x16, 12}, {0x17, 16}, - {0x18, 16}, {0x19, 16}, {0x1a, 16}, {0x21, 5}, {0x22, 8}, {0x23, 10}, - {0x24, 12}, {0x25, 15}, {0x26, 16}, {0x27, 16}, {0x28, 16}, {0x29, 16}, - {0x2a, 16}, {0x31, 5}, {0x32, 8}, {0x33, 10}, {0x34, 12}, {0x35, 16}, - {0x36, 16}, {0x37, 16}, {0x38, 16}, {0x39, 16}, {0x3a, 16}, {0x41, 6}, - {0x42, 9}, {0x43, 16}, {0x44, 16}, {0x45, 16}, {0x46, 16}, {0x47, 16}, - {0x48, 16}, {0x49, 16}, {0x4a, 16}, {0x51, 6}, {0x52, 10}, {0x53, 16}, - {0x54, 16}, {0x55, 16}, {0x56, 16}, {0x57, 16}, {0x58, 16}, {0x59, 16}, - {0x5a, 16}, {0x61, 7}, {0x62, 11}, {0x63, 16}, {0x64, 16}, {0x65, 16}, - {0x66, 16}, {0x67, 16}, {0x68, 16}, {0x69, 16}, {0x6a, 16}, {0x71, 7}, - {0x72, 11}, {0x73, 16}, {0x74, 16}, {0x75, 16}, {0x76, 16}, {0x77, 16}, - {0x78, 16}, {0x79, 16}, {0x7a, 16}, {0x81, 8}, {0x82, 16}, {0x83, 16}, - {0x84, 16}, {0x85, 16}, {0x86, 16}, {0x87, 16}, {0x88, 16}, {0x89, 16}, - {0x8a, 16}, {0x91, 9}, {0x92, 16}, {0x93, 16}, {0x94, 16}, {0x95, 16}, - {0x96, 16}, {0x97, 16}, {0x98, 16}, {0x99, 16}, {0x9a, 16}, {0xa1, 9}, - {0xa2, 16}, {0xa3, 16}, {0xa4, 16}, {0xa5, 16}, {0xa6, 16}, {0xa7, 16}, - {0xa8, 16}, {0xa9, 16}, {0xaa, 16}, {0xb1, 9}, {0xb2, 16}, {0xb3, 16}, - {0xb4, 16}, {0xb5, 16}, {0xb6, 16}, {0xb7, 16}, {0xb8, 16}, {0xb9, 16}, - {0xba, 16}, {0xc1, 9}, {0xc2, 16}, {0xc3, 16}, {0xc4, 16}, {0xc5, 16}, - {0xc6, 16}, {0xc7, 16}, {0xc8, 16}, {0xc9, 16}, {0xca, 16}, {0xd1, 11}, - {0xd2, 16}, {0xd3, 16}, {0xd4, 16}, {0xd5, 16}, {0xd6, 16}, {0xd7, 16}, - {0xd8, 16}, {0xd9, 16}, {0xda, 16}, {0xe1, 14}, {0xe2, 16}, {0xe3, 16}, - {0xe4, 16}, {0xe5, 16}, {0xe6, 16}, {0xe7, 16}, {0xe8, 16}, {0xe9, 16}, - {0xea, 16}, {0xf0, 10}, {0xf1, 15}, {0xf2, 16}, {0xf3, 16}, {0xf4, 16}, - {0xf5, 16}, {0xf6, 16}, {0xf7, 16}, {0xf8, 16}, {0xf9, 16}, {0xfa, 16} -}; -/* *INDENT-ON* */ - -static inline gboolean -jpeg_parse_to_next_marker (GstByteReader * br, guint8 * marker) -{ - gint ofs; - - ofs = gst_jpeg_scan_for_marker_code (br->data, br->size, br->byte); - if (ofs < 0) - return FALSE; - - if (marker) - *marker = br->data[ofs + 1]; - gst_byte_reader_skip (br, ofs - br->byte + 2); - return TRUE; -} - -gint -gst_jpeg_scan_for_marker_code (const guint8 * data, gsize size, guint offset) -{ - guint i; - - g_return_val_if_fail (data != NULL, -1); - g_return_val_if_fail (size > offset, -1); - - for (i = offset; i < size - 1;) { - if (data[i] != 0xff) - i++; - else { - const guint8 v = data[i + 1]; - if (v >= 0xc0 && v <= 0xfe) - return i; - i += 2; - } - } - return -1; -} - -gboolean -gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * frame_hdr, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader br; - guint16 length; - guint8 val; - guint i; - - g_return_val_if_fail (frame_hdr != NULL, FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (size > offset, FALSE); - - size -= offset; - gst_byte_reader_init (&br, &data[offset], size); - g_return_val_if_fail (size >= 8, FALSE); - - U_READ_UINT16 (&br, length); /* Lf */ - g_return_val_if_fail (size >= length, FALSE); - - U_READ_UINT8 (&br, frame_hdr->sample_precision); - U_READ_UINT16 (&br, frame_hdr->height); - U_READ_UINT16 (&br, frame_hdr->width); - U_READ_UINT8 (&br, frame_hdr->num_components); - g_return_val_if_fail (frame_hdr->num_components <= - GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); - - length -= 8; - g_return_val_if_fail (length >= 3 * frame_hdr->num_components, FALSE); - for (i = 0; i < frame_hdr->num_components; i++) { - U_READ_UINT8 (&br, frame_hdr->components[i].identifier); - U_READ_UINT8 (&br, val); - frame_hdr->components[i].horizontal_factor = (val >> 4) & 0x0F; - frame_hdr->components[i].vertical_factor = (val & 0x0F); - U_READ_UINT8 (&br, frame_hdr->components[i].quant_table_selector); - g_return_val_if_fail ((frame_hdr->components[i].horizontal_factor <= 4 && - frame_hdr->components[i].vertical_factor <= 4 && - frame_hdr->components[i].quant_table_selector < 4), FALSE); - length -= 3; - } - - g_assert (length == 0); - return TRUE; -} - -gboolean -gst_jpeg_parse_scan_hdr (GstJpegScanHdr * scan_hdr, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader br; - guint16 length; - guint8 val; - guint i; - - g_return_val_if_fail (scan_hdr != NULL, FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (size > offset, FALSE); - - size -= offset; - gst_byte_reader_init (&br, &data[offset], size); - g_return_val_if_fail (size >= 3, FALSE); - - U_READ_UINT16 (&br, length); /* Ls */ - g_return_val_if_fail (size >= length, FALSE); - - U_READ_UINT8 (&br, scan_hdr->num_components); - g_return_val_if_fail (scan_hdr->num_components <= - GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); - - length -= 3; - g_return_val_if_fail (length >= 2 * scan_hdr->num_components, FALSE); - for (i = 0; i < scan_hdr->num_components; i++) { - U_READ_UINT8 (&br, scan_hdr->components[i].component_selector); - U_READ_UINT8 (&br, val); - scan_hdr->components[i].dc_selector = (val >> 4) & 0x0F; - scan_hdr->components[i].ac_selector = val & 0x0F; - g_return_val_if_fail ((scan_hdr->components[i].dc_selector < 4 && - scan_hdr->components[i].ac_selector < 4), FALSE); - length -= 2; - } - - /* FIXME: Ss, Se, Ah, Al */ - g_assert (length == 3); - return TRUE; -} - -gboolean -gst_jpeg_parse_huffman_table (GstJpegHuffmanTables * huf_tables, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader br; - GstJpegHuffmanTable *huf_table; - guint16 length; - guint8 val, table_class, table_index; - guint32 value_count; - guint i; - - g_return_val_if_fail (huf_tables != NULL, FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (size > offset, FALSE); - - size -= offset; - gst_byte_reader_init (&br, &data[offset], size); - g_return_val_if_fail (size >= 2, FALSE); - - U_READ_UINT16 (&br, length); /* Lh */ - g_return_val_if_fail (size >= length, FALSE); - - while (gst_byte_reader_get_remaining (&br)) { - U_READ_UINT8 (&br, val); - table_class = ((val >> 4) & 0x0F); - table_index = (val & 0x0F); - g_return_val_if_fail (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); - if (table_class == 0) { - huf_table = &huf_tables->dc_tables[table_index]; - } else { - huf_table = &huf_tables->ac_tables[table_index]; - } - READ_BYTES (&br, huf_table->huf_bits, 16); - value_count = 0; - for (i = 0; i < 16; i++) - value_count += huf_table->huf_bits[i]; - READ_BYTES (&br, huf_table->huf_values, value_count); - huf_table->valid = TRUE; - } - return TRUE; - -failed: - return FALSE; -} - -gboolean -gst_jpeg_parse_quant_table (GstJpegQuantTables * quant_tables, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader br; - GstJpegQuantTable *quant_table; - guint16 length; - guint8 val, table_index; - guint i; - - g_return_val_if_fail (quant_tables != NULL, FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (size > offset, FALSE); - - size -= offset; - gst_byte_reader_init (&br, &data[offset], size); - g_return_val_if_fail (size >= 2, FALSE); - - U_READ_UINT16 (&br, length); /* Lq */ - g_return_val_if_fail (size >= length, FALSE); - - while (gst_byte_reader_get_remaining (&br)) { - U_READ_UINT8 (&br, val); - table_index = (val & 0x0f); - g_return_val_if_fail (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); - quant_table = &quant_tables->quant_tables[table_index]; - quant_table->quant_precision = ((val >> 4) & 0x0f); - - g_return_val_if_fail (gst_byte_reader_get_remaining (&br) >= - GST_JPEG_MAX_QUANT_ELEMENTS * (1 + ! !quant_table->quant_precision), - FALSE); - for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) { - if (!quant_table->quant_precision) { /* 8-bit values */ - U_READ_UINT8 (&br, val); - quant_table->quant_table[i] = val; - } else { /* 16-bit values */ - U_READ_UINT16 (&br, quant_table->quant_table[i]); - } - } - quant_table->valid = TRUE; - } - return TRUE; -} - -gboolean -gst_jpeg_parse_restart_interval (guint * interval, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader br; - guint16 length, val; - - g_return_val_if_fail (interval != NULL, FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (size > offset, FALSE); - - size -= offset; - gst_byte_reader_init (&br, &data[offset], size); - g_return_val_if_fail (size >= 4, FALSE); - - U_READ_UINT16 (&br, length); /* Lr */ - g_return_val_if_fail (size >= length, FALSE); - - U_READ_UINT16 (&br, val); - *interval = val; - return TRUE; -} - -static int -compare_huffman_table_entry (const void *a, const void *b) -{ - const GstJpegHuffmanTableEntry *const e1 = *(GstJpegHuffmanTableEntry **) a; - const GstJpegHuffmanTableEntry *const e2 = *(GstJpegHuffmanTableEntry **) b; - - if (e1->length == e2->length) - return (gint) e1->value - (gint) e2->value; - return (gint) e1->length - (gint) e2->length; -} - -static void -build_huffman_table (GstJpegHuffmanTable * huf_table, - const GstJpegHuffmanTableEntry * entries, guint num_entries) -{ - const GstJpegHuffmanTableEntry *sorted_entries[256]; - guint i, j, n; - - g_assert (num_entries <= G_N_ELEMENTS (sorted_entries)); - - for (i = 0; i < num_entries; i++) - sorted_entries[i] = &entries[i]; - qsort (sorted_entries, num_entries, sizeof (sorted_entries[0]), - compare_huffman_table_entry); - - for (i = 0, j = 1, n = 0; i < num_entries; i++) { - const GstJpegHuffmanTableEntry *const e = sorted_entries[i]; - if (e->length != j) { - huf_table->huf_bits[j++ - 1] = n; - for (; j < e->length; j++) - huf_table->huf_bits[j - 1] = 0; - n = 0; - } - huf_table->huf_values[i] = e->value; - n++; - } - - for (; j < G_N_ELEMENTS (huf_table->huf_bits); j++) - huf_table->huf_bits[j] = 0; - for (; i < G_N_ELEMENTS (huf_table->huf_values); i++) - huf_table->huf_values[i] = 0; - huf_table->valid = TRUE; -} - -void -gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables * huf_tables) -{ - g_assert (huf_tables); - - /* Build DC tables */ - build_huffman_table (&huf_tables->dc_tables[0], default_luminance_dc_table, - G_N_ELEMENTS (default_luminance_dc_table)); - build_huffman_table (&huf_tables->dc_tables[1], default_chrominance_dc_table, - G_N_ELEMENTS (default_chrominance_dc_table)); - memcpy (&huf_tables->dc_tables[2], &huf_tables->dc_tables[1], - sizeof (huf_tables->dc_tables[2])); - - /* Build AC tables */ - build_huffman_table (&huf_tables->ac_tables[0], default_luminance_ac_table, - G_N_ELEMENTS (default_luminance_ac_table)); - build_huffman_table (&huf_tables->ac_tables[1], default_chrominance_ac_table, - G_N_ELEMENTS (default_chrominance_ac_table)); - memcpy (&huf_tables->ac_tables[2], &huf_tables->ac_tables[1], - sizeof (huf_tables->ac_tables[2])); -} - -static void -build_quant_table (GstJpegQuantTable * quant_table, const guint8 values[64]) -{ - guint i; - - for (i = 0; i < 64; i++) - quant_table->quant_table[i] = values[zigzag_index[i]]; - quant_table->quant_precision = 0; /* Pq = 0 (8-bit precision) */ - quant_table->valid = TRUE; -} - -void -gst_jpeg_get_default_quantization_tables (GstJpegQuantTables * quant_tables) -{ - g_assert (quant_tables); - - build_quant_table (&quant_tables->quant_tables[0], - default_luminance_quant_table); - build_quant_table (&quant_tables->quant_tables[1], - default_chrominance_quant_table); - build_quant_table (&quant_tables->quant_tables[2], - default_chrominance_quant_table); -} - -gboolean -gst_jpeg_parse (GstJpegMarkerSegment * seg, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader br; - guint16 length; - - g_return_val_if_fail (seg != NULL, FALSE); - - if (size <= offset) { - GST_DEBUG ("failed to parse from offset %u, buffer is too small", offset); - return FALSE; - } - - size -= offset; - gst_byte_reader_init (&br, &data[offset], size); - - if (!jpeg_parse_to_next_marker (&br, &seg->marker)) { - GST_DEBUG ("failed to find marker code"); - return FALSE; - } - - seg->offset = offset + gst_byte_reader_get_pos (&br); - seg->size = -1; - - /* Try to find end of segment */ - switch (seg->marker) { - case GST_JPEG_MARKER_SOI: - case GST_JPEG_MARKER_EOI: - fixed_size_segment: - seg->size = 2; - break; - - case (GST_JPEG_MARKER_SOF_MIN + 0): /* Lf */ - case (GST_JPEG_MARKER_SOF_MIN + 1): /* Lf */ - case (GST_JPEG_MARKER_SOF_MIN + 2): /* Lf */ - case (GST_JPEG_MARKER_SOF_MIN + 3): /* Lf */ - case (GST_JPEG_MARKER_SOF_MIN + 9): /* Lf */ - case (GST_JPEG_MARKER_SOF_MIN + 10): /* Lf */ - case (GST_JPEG_MARKER_SOF_MIN + 11): /* Lf */ - case GST_JPEG_MARKER_SOS: /* Ls */ - case GST_JPEG_MARKER_DQT: /* Lq */ - case GST_JPEG_MARKER_DHT: /* Lh */ - case GST_JPEG_MARKER_DAC: /* La */ - case GST_JPEG_MARKER_DRI: /* Lr */ - case GST_JPEG_MARKER_COM: /* Lc */ - case GST_JPEG_MARKER_DNL: /* Ld */ - variable_size_segment: - READ_UINT16 (&br, length); - seg->size = length; - break; - - default: - /* Application data segment length (Lp) */ - if (seg->marker >= GST_JPEG_MARKER_APP_MIN && - seg->marker <= GST_JPEG_MARKER_APP_MAX) - goto variable_size_segment; - - /* Restart markers (fixed size, two bytes only) */ - if (seg->marker >= GST_JPEG_MARKER_RST_MIN && - seg->marker <= GST_JPEG_MARKER_RST_MAX) - goto fixed_size_segment; - - /* Fallback: scan for next marker */ - if (!jpeg_parse_to_next_marker (&br, NULL)) - goto failed; - seg->size = gst_byte_reader_get_pos (&br) - seg->offset; - break; - } - return TRUE; - -failed: - return FALSE; -} diff --git a/gst-libs/gst/codecparsers/gstjpegparser.h b/gst-libs/gst/codecparsers/gstjpegparser.h deleted file mode 100644 index 7237584e25..0000000000 --- a/gst-libs/gst/codecparsers/gstjpegparser.h +++ /dev/null @@ -1,414 +0,0 @@ -/* - * gstjpegparser.h - JPEG parser - * - * Copyright (C) 2011-2012 Intel Corporation - * - * 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_JPEG_PARSER_H -#define GST_JPEG_PARSER_H - -#ifndef GST_USE_UNSTABLE_API -# warning "The JPEG parsing library is unstable API and may change in future." -# warning "You can define GST_USE_UNSTABLE_API to avoid this warning." -#endif - -#include - -G_BEGIN_DECLS - -/** - * GST_JPEG_MAX_FRAME_COMPONENTS: - * - * Maximum number of image components in a frame (Nf). - */ -#define GST_JPEG_MAX_FRAME_COMPONENTS 256 - -/** - * GST_JPEG_MAX_SCAN_COMPONENTS: - * - * Maximum number of image components in a scan (Ns). - */ -#define GST_JPEG_MAX_SCAN_COMPONENTS 4 - -/** - * GST_JPEG_MAX_QUANT_ELEMENTS: - * - * Number of elements in the quantization table. - */ -#define GST_JPEG_MAX_QUANT_ELEMENTS 64 - -typedef struct _GstJpegQuantTable GstJpegQuantTable; -typedef struct _GstJpegQuantTables GstJpegQuantTables; -typedef struct _GstJpegHuffmanTable GstJpegHuffmanTable; -typedef struct _GstJpegHuffmanTables GstJpegHuffmanTables; -typedef struct _GstJpegScanComponent GstJpegScanComponent; -typedef struct _GstJpegScanHdr GstJpegScanHdr; -typedef struct _GstJpegFrameComponent GstJpegFrameComponent; -typedef struct _GstJpegFrameHdr GstJpegFrameHdr; -typedef struct _GstJpegMarkerSegment GstJpegMarkerSegment; - -/** - * GstJpegMarkerCode: - * @GST_JPEG_MARKER_SOF_MIN: Start of frame min marker code - * @GST_JPEG_MARKER_SOF_MAX: Start of frame max marker code - * @GST_JPEG_MARKER_DHT: Huffman tabler marker code - * @GST_JPEG_MARKER_DAC: Arithmetic coding marker code - * @GST_JPEG_MARKER_RST_MIN: Restart interval min marker code - * @GST_JPEG_MARKER_RST_MAX: Restart interval max marker code - * @GST_JPEG_MARKER_SOI: Start of image marker code - * @GST_JPEG_MARKER_EOI: End of image marker code - * @GST_JPEG_MARKER_SOS: Start of scan marker code - * @GST_JPEG_MARKER_DQT: Define quantization table marker code - * @GST_JPEG_MARKER_DNL: Define number of lines marker code - * @GST_JPEG_MARKER_DRI: Define restart interval marker code - * @GST_JPEG_MARKER_APP_MIN: Application segment min marker code - * @GST_JPEG_MARKER_APP_MAX: Application segment max marker code - * @GST_JPEG_MARKER_COM: Comment marker code - * - * Indicates the type of JPEG segment. - */ -typedef enum { - GST_JPEG_MARKER_SOF_MIN = 0xC0, - GST_JPEG_MARKER_SOF_MAX = 0xCF, - GST_JPEG_MARKER_DHT = 0xC4, - GST_JPEG_MARKER_DAC = 0xCC, - GST_JPEG_MARKER_RST_MIN = 0xD0, - GST_JPEG_MARKER_RST_MAX = 0xD7, - GST_JPEG_MARKER_SOI = 0xD8, - GST_JPEG_MARKER_EOI = 0xD9, - GST_JPEG_MARKER_SOS = 0xDA, - GST_JPEG_MARKER_DQT = 0xDB, - GST_JPEG_MARKER_DNL = 0xDC, - GST_JPEG_MARKER_DRI = 0xDD, - GST_JPEG_MARKER_APP_MIN = 0xE0, - GST_JPEG_MARKER_APP_MAX = 0xEF, - GST_JPEG_MARKER_COM = 0xFE, -} GstJpegMarkerCode; - -/** - * GstJpegProfile: - * @GST_JPEG_PROFILE_BASELINE: Baseline DCT - * @GST_JPEG_PROFILE_EXTENDED: Extended sequential DCT - * @GST_JPEG_PROFILE_PROGRESSIVE: Progressive DCT - * @GST_JPEG_PROFILE_LOSSLESS: Lossless (sequential) - * - * JPEG encoding processes. - */ -typedef enum { - GST_JPEG_PROFILE_BASELINE = 0x00, - GST_JPEG_PROFILE_EXTENDED = 0x01, - GST_JPEG_PROFILE_PROGRESSIVE = 0x02, - GST_JPEG_PROFILE_LOSSLESS = 0x03, -} GstJpegProfile; - -/** - * GstJpegEntropyCodingMode: - * @GST_JPEG_ENTROPY_CODING_HUFFMAN: Huffman coding - * @GST_JPEG_ENTROPY_CODING_ARITHMETIC: arithmetic coding - * - * JPEG entropy coding mode. - */ -typedef enum { - GST_JPEG_ENTROPY_CODING_HUFFMAN = 0x00, - GST_JPEG_ENTROPY_CODING_ARITHMETIC = 0x08 -} GstJpegEntropyCodingMode; - -/** - * GstJpegQuantTable: - * @quant_precision: Quantization table element precision (Pq) - * @quant_table: Quantization table elements (Qk) - * @valid: If the quantization table is valid, which means it has - * already been parsed - * - * Quantization table. - */ -struct _GstJpegQuantTable -{ - guint8 quant_precision; - guint16 quant_table[GST_JPEG_MAX_QUANT_ELEMENTS]; - gboolean valid; -}; - -/** - * GstJpegQuantTables: - * @quant_tables: All quantization tables - * - * Helper data structure that holds all quantization tables used to - * decode an image. - */ -struct _GstJpegQuantTables -{ - GstJpegQuantTable quant_tables[GST_JPEG_MAX_SCAN_COMPONENTS]; -}; - -/** - * GstJpegHuffmanTable: - * @huf_bits: Number of Huffman codes of length i + 1 (Li) - * @huf_vales: Value associated with each Huffman code (Vij) - * @valid: If the Huffman table is valid, which means it has already - * been parsed - * - * Huffman table. - */ -struct _GstJpegHuffmanTable -{ - guint8 huf_bits[16]; - guint8 huf_values[256]; - gboolean valid; -}; - -/** - * GstJpegHuffmanTables: - * @dc_tables: DC Huffman tables - * @ac_tables: AC Huffman tables - * - * Helper data structure that holds all AC/DC Huffman tables used to - * decode an image. - */ -struct _GstJpegHuffmanTables -{ - GstJpegHuffmanTable dc_tables[GST_JPEG_MAX_SCAN_COMPONENTS]; - GstJpegHuffmanTable ac_tables[GST_JPEG_MAX_SCAN_COMPONENTS]; -}; - -/** - * GstJpegScanComponent: - * @component_selector: Scan component selector (Csj) - * @dc_selector: DC entropy coding table destination selector (Tdj) - * @ac_selector: AC entropy coding table destination selector (Taj) - - * Component-specification parameters. - */ -struct _GstJpegScanComponent -{ - guint8 component_selector; /* 0 .. 255 */ - guint8 dc_selector; /* 0 .. 3 */ - guint8 ac_selector; /* 0 .. 3 */ -}; - -/** - * GstJpegScanHdr: - * @num_components: Number of image components in scan (Ns) - * @components: Image components - * - * Scan header. - */ -struct _GstJpegScanHdr -{ - guint8 num_components; /* 1 .. 4 */ - GstJpegScanComponent components[GST_JPEG_MAX_SCAN_COMPONENTS]; -}; - -/** - * GstJpegFrameComponent: - * @identifier: Component identifier (Ci) - * @horizontal_factor: Horizontal sampling factor (Hi) - * @vertical_factor: Vertical sampling factor (Vi) - * @quant_table_selector: Quantization table destination selector (Tqi) - * - * Component-specification parameters. - */ -struct _GstJpegFrameComponent -{ - guint8 identifier; /* 0 .. 255 */ - guint8 horizontal_factor; /* 1 .. 4 */ - guint8 vertical_factor; /* 1 .. 4 */ - guint8 quant_table_selector; /* 0 .. 3 */ -}; - -/** - * GstJpegFrameHdr: - * @sample_precision: Sample precision (P) - * @height: Number of lines (Y) - * @width: Number of samples per line (X) - * @num_components: Number of image components in frame (Nf) - * @components: Image components - * @restart_interval: Number of MCU in the restart interval (Ri) - * - * Frame header. - */ -struct _GstJpegFrameHdr -{ - guint8 sample_precision; /* 2 .. 16 */ - guint16 width; /* 1 .. 65535 */ - guint16 height; /* 0 .. 65535 */ - guint8 num_components; /* 1 .. 255 */ - GstJpegFrameComponent components[GST_JPEG_MAX_FRAME_COMPONENTS]; -}; - -/** - * GstJpegMarkerSegment: - * @type: The type of the segment that starts at @offset - * @offset: The offset to the segment start in bytes. This is the - * exact start of the segment, no marker code included - * @size: The size in bytes of the segment, or -1 if the end was not - * found. It is the exact size of the segment, no marker code included - * - * A structure that contains the type of a segment, its offset and its size. - */ -struct _GstJpegMarkerSegment -{ - guint8 marker; - guint offset; - gint size; -}; - -/** - * gst_jpeg_scan_for_marker_code: - * @data: The data to parse - * @size: The size of @data - * @offset: The offset from which to start parsing - * - * Scans the JPEG bitstream contained in @data for the next marker - * code. If found, the function returns an offset to the marker code, - * including the 0xff prefix code but excluding any extra fill bytes. - * - * Returns: offset to the marker code if found, or -1 if not found. - */ -gint gst_jpeg_scan_for_marker_code (const guint8 * data, - gsize size, - guint offset); - -/** - * gst_jpeg_parse: - * @data: The data to parse - * @size: The size of @data - * @offset: The offset from which to start parsing - * - * Parses the JPEG bitstream contained in @data, and returns the - * detected segment as a #GstJpegMarkerSegment. - * - * Returns: TRUE if a packet start code was found. - */ -gboolean gst_jpeg_parse (GstJpegMarkerSegment * seg, - const guint8 * data, - gsize size, - guint offset); - -/** - * gst_jpeg_parse_frame_hdr: - * @hdr: (out): The #GstJpegFrameHdr structure to fill in - * @data: The data from which to parse the frame header - * @size: The size of @data - * @offset: The offset in bytes from which to start parsing @data - * - * Parses the @hdr JPEG frame header structure members from @data. - * - * Returns: TRUE if the frame header was correctly parsed. - */ -gboolean gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * hdr, - const guint8 * data, - gsize size, - guint offset); - -/** - * gst_jpeg_parse_scan_hdr: - * @hdr: (out): The #GstJpegScanHdr structure to fill in - * @data: The data from which to parse the scan header - * @size: The size of @data - * @offset: The offset in bytes from which to start parsing @data - * - * Parses the @hdr JPEG scan header structure members from @data. - * - * Returns: TRUE if the scan header was correctly parsed - */ -gboolean gst_jpeg_parse_scan_hdr (GstJpegScanHdr * hdr, - const guint8 * data, - gsize size, - guint offset); - -/** - * gst_jpeg_parse_quantization_table: - * @quant_tables: (out): The #GstJpegQuantizationTable structure to fill in - * @num_quant_tables: The number of allocated quantization tables in @quant_tables - * @data: The data from which to parse the quantization table - * @size: The size of @data - * @offset: The offset in bytes from which to start parsing @data - * - * Parses the JPEG quantization table structure members from @data. - * - * Note: @quant_tables represents the complete set of possible - * quantization tables. However, the parser will only write to the - * quantization table specified by the table destination identifier - * (Tq). While doing so, the @valid flag of the specified quantization - * table will also be set to %TRUE. - * - * Returns: TRUE if the quantization table was correctly parsed. - */ -gboolean gst_jpeg_parse_quant_table (GstJpegQuantTables *quant_tables, - const guint8 * data, - gsize size, - guint offset); - -/** - * gst_jpeg_parse_huffman_table: - * @huf_tables: (out): The #GstJpegHuffmanTable structure to fill in - * @data: The data from which to parse the Huffman table - * @size: The size of @data - * @offset: The offset in bytes from which to start parsing @data - * - * Parses the JPEG Huffman table structure members from @data. - * - * Note: @huf_tables represents the complete set of possible Huffman - * tables. However, the parser will only write to the Huffman table - * specified by the table destination identifier (Th). While doing so, - * the @valid flag of the specified Huffman table will also be set to - * %TRUE; - * - * Returns: TRUE if the Huffman table was correctly parsed. - */ -gboolean gst_jpeg_parse_huffman_table (GstJpegHuffmanTables *huf_tables, - const guint8 * data, - gsize size, - guint offset); - -/** - * gst_jpeg_parse_restart_interval: - * @interval: (out): The parsed restart interval value - * @data: The data from which to parse the restart interval specification - * @size: The size of @data - * @offset: The offset in bytes from which to start parsing @data - * - * Returns: TRUE if the restart interval value was correctly parsed. - */ -gboolean gst_jpeg_parse_restart_interval (guint * interval, - const guint8 * data, - gsize size, - guint offset); - -/** - * gst_jpeg_get_default_huffman_tables: - * @huf_tables: (out): The default DC/AC Huffman tables to fill in - * - * Fills in @huf_tables with the default AC/DC Huffman tables, as - * specified by the JPEG standard. - */ -void gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables *huf_tables); - -/** - * gst_jpeg_get_default_quantization_table: - * @quant_tables: (out): The default luma/chroma quant-tables in zigzag mode - * - * Fills in @quant_tables with the default quantization tables, as - * specified by the JPEG standard. - */ -void gst_jpeg_get_default_quantization_tables (GstJpegQuantTables *quant_tables); - -G_END_DECLS - -#endif /* GST_JPEG_PARSER_H */ diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 7f645c8d32..49b1b3b5ff 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -22,6 +22,7 @@ libgstvaapi_includedir = \ libgstvaapi_cflags = \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ + -I$(top_builddir)/gst-libs \ $(GST_BASE_CFLAGS) \ $(GST_BASEVIDEO_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ @@ -37,7 +38,7 @@ libgstvaapi_libs = \ $(GST_VIDEO_LIBS) \ $(GST_CODEC_PARSERS_LIBS) \ $(LIBVA_LIBS) \ - $(NULL) + $(top_builddir)/gst-libs/gst/codecparsers/libgstvaapi-codecparsers.la libgstvaapi_source_c = \ gstvaapicodec_objects.c \ @@ -197,11 +198,6 @@ libgstvaapi_wayland_source_priv_h = \ gstvaapiutils.h \ $(NULL) -if USE_LOCAL_CODEC_PARSERS -libgstvaapi_libs += \ - $(top_builddir)/gst-libs/gst/codecparsers/libgstvaapi-codecparsers.la -endif - libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_source_c) \ $(libgstvaapi_source_priv_h) \ From 022e99e12796a8a8f0f8dd296522aab2ec0c464e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 11 Oct 2012 13:49:14 +0200 Subject: [PATCH 0863/3781] codecparsers: h264: use submodule sources. Use newer sources from the codecparsers/ submodule for - GstH264SliceHdr.n_emulation_prevention_bytes: EPBs; - GstH264VUIParams.{par_n,par_d}: pixel-aspect-ratio. --- configure.ac | 28 +++++++++++++-------------- gst-libs/gst/codecparsers/Makefile.am | 5 +++++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index 728a2c6aa5..24ef2a4e4a 100644 --- a/configure.ac +++ b/configure.ac @@ -214,29 +214,29 @@ dnl ... bitstream parsers PKG_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_MAJORMINOR >= gst_plugins_bad_version]) -dnl ... 0.10.23 addition, could be implemented otherwise -AC_CACHE_CHECK([for GstH264SliceHdr::n_emulation_prevention_bytes], - ac_cv_have_gst_h264_slice_hdr_epb_count, [ - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" +dnl ... H.264 parser, with the required extensions +AC_CACHE_CHECK([for H.264 parser], + ac_cv_have_gst_h264_parser, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[GstH264SliceHdr slice_hdr; - slice_hdr.n_emulation_prevention_bytes = 0;]])], - [ac_cv_have_gst_h264_slice_hdr_epb_count="yes"], - [ac_cv_have_gst_h264_slice_hdr_epb_count="no"] + GstH264VUIParams vui_params; + slice_hdr.n_emulation_prevention_bytes = 0; + vui_params.par_n = 0; + vui_params.par_d = 0;]])], + [ac_cv_have_gst_h264_parser="yes"], + [ac_cv_have_gst_h264_parser="no"] ) - CFLAGS="$saved_CFLAGS" + CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) - -if test "$ac_cv_have_gst_h264_slice_hdr_epb_count" = "yes"; then - AC_DEFINE_UNQUOTED(HAVE_GST_H264_SLICE_HDR_EPB_COUNT, 1, - [Defined to 1 if GstH264SliceHdr::n_emulation_prevention_bytes exists.]) -fi +AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_H264], + [test "$ac_cv_have_gst_h264_parser" != "yes"]) dnl ... JPEG parser, not upstream yet AC_CACHE_CHECK([for JPEG parser], diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 4660a7dcff..48b93bc885 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -25,6 +25,11 @@ gen_source_c += gstjpegparser.c gen_source_h += gstjpegparser.h endif +if USE_LOCAL_CODEC_PARSERS_H264 +gen_source_c += gsth264parser.c parserutils.c +gen_source_h += gsth264parser.h parserutils.h +endif + GENFILES = \ $(gen_source_c) \ $(gen_source_h) \ From bd11baedc5b7756d7f992f90cfd11ed2176136c1 Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Thu, 27 Sep 2012 18:05:46 +0100 Subject: [PATCH 0864/3781] mpeg2: use pixel-aspec-ratio information from bitstream parser. Signed-off-by: Simon Farnsworth Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 928c64f045..7b479057fc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -519,6 +519,12 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) pts_set_framerate(&priv->tsg, priv->fps_n, priv->fps_d); gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); + gst_vaapi_decoder_set_pixel_aspect_ratio( + base_decoder, + seq_hdr->par_w, + seq_hdr->par_h + ); + priv->width = seq_hdr->width; priv->height = seq_hdr->height; priv->has_seq_ext = FALSE; From b07eb2056b953f4569450035b145e448b688519d Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Thu, 27 Sep 2012 18:05:46 +0100 Subject: [PATCH 0865/3781] vc1: use pixel-aspect-ratio from bitstream parser. Signed-off-by: Simon Farnsworth Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index d54a18ae92..96a58deb8a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -248,7 +248,7 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) GstVC1SeqStructC * const structc = &seq_hdr->struct_c; GstVC1ParserResult result; GstVaapiProfile profile; - guint width, height, fps_n, fps_d; + guint width, height, fps_n, fps_d, par_n, par_d; result = gst_vc1_parse_sequence_header( rbdu->data + rbdu->offset, @@ -275,6 +275,8 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) fps_n = 0; fps_d = 0; + par_n = 0; + par_d = 0; switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: case GST_VC1_PROFILE_MAIN: @@ -321,6 +323,8 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) fps_d = frameratedr_table[adv_hdr->frameratedr]; } } + par_n = adv_hdr->par_n; + par_d = adv_hdr->par_d; break; default: g_assert(0 && "XXX: we already validated the profile above"); @@ -332,6 +336,9 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); } + if (par_n > 0 && par_d > 0) + gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, par_n, par_d); + switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: case GST_VC1_PROFILE_MAIN: From 193b14c0f2aa00dba7d29abd5d3d4b8a92748ec5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 11 Oct 2012 15:04:12 +0200 Subject: [PATCH 0866/3781] vc1: use framerate information from bitstream parser. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 51 +++--------------------- 1 file changed, 5 insertions(+), 46 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 96a58deb8a..57ff80c3d3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -49,8 +49,6 @@ struct _GstVaapiDecoderVC1Private { GstVaapiProfile profile; guint width; guint height; - guint fps_n; - guint fps_d; GstVC1SeqHdr seq_hdr; GstVC1EntryPointHdr entrypoint_hdr; GstVC1FrameHdr frame_hdr; @@ -286,43 +284,8 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) } break; case GST_VC1_PROFILE_ADVANCED: - if (adv_hdr->display_ext && adv_hdr->framerate_flag) { - if (adv_hdr->framerateind) { - // 6.1.14.4.4 - Frame Rate Explicit - fps_n = adv_hdr->framerateexp + 1; - fps_d = 32; - } - else { - // 6.1.14.4.2 - Frame Rate Numerator - static const guint frameratenr_table[] = { - [1] = 24000, - [2] = 25000, - [3] = 30000, - [4] = 50000, - [5] = 60000, - [6] = 48000, - [7] = 72000 - }; - - // 6.1.14.4.3 - Frame Rate Denominator - static const guint frameratedr_table[] = { - [1] = 1000, - [2] = 1001 - }; - - if (adv_hdr->frameratenr < 1 || adv_hdr->frameratenr > 7) { - GST_DEBUG("unsupported FRAMERATENR value"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } - fps_n = frameratenr_table[adv_hdr->frameratenr]; - - if (adv_hdr->frameratedr < 1 || adv_hdr->frameratedr > 2) { - GST_DEBUG("unsupported FRAMERATEDR value"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } - fps_d = frameratedr_table[adv_hdr->frameratedr]; - } - } + fps_n = adv_hdr->fps_n; + fps_d = adv_hdr->fps_d; par_n = adv_hdr->par_n; par_d = adv_hdr->par_d; break; @@ -330,11 +293,9 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) g_assert(0 && "XXX: we already validated the profile above"); break; } - if (fps_n && fps_d) { - priv->fps_n = fps_n; - priv->fps_d = fps_d; - gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); - } + + if (fps_n && fps_d) + gst_vaapi_decoder_set_framerate(base_decoder, fps_n, fps_d); if (par_n > 0 && par_d > 0) gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, par_n, par_d); @@ -1302,8 +1263,6 @@ gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder) decoder->priv = priv; priv->width = 0; priv->height = 0; - priv->fps_n = 0; - priv->fps_d = 0; priv->profile = (GstVaapiProfile)0; priv->current_picture = NULL; priv->next_picture = NULL; From d42d838388459e64ae704d5a4dcf7a1a8b457c5b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 16 Oct 2012 16:43:43 +0200 Subject: [PATCH 0867/3781] codecparsers: fix generation of symlinks. Try to improve dependencies while generating symlinks to externally maintained copy of codecparsers (derived from upstream git master tree). --- gst-libs/gst/codecparsers/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 48b93bc885..4f226cbcc8 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -58,7 +58,7 @@ all-local: .timestamp.symlinks .timestamp.symlinks: $(GENFILES) touch $@ -$(gen_source_c): %.c: $(local_codecparsers_srcdir)/%.c +$(gen_source_c): %.c: $(local_codecparsers_srcdir)/%.c %.h $(LN_S) -f $< $@ $(gen_source_h): %.h: $(local_codecparsers_srcdir)/%.h $(LN_S) -f $< $@ From 26b7c46eda13a94a35a97c448f424d963a89dcbc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 16 Oct 2012 16:46:17 +0200 Subject: [PATCH 0868/3781] h264: drop extra code covered by built-in codecparsers. GstH264SliceHdr.n_emulation_prevention_bytes is bound to exist now that a newer version of codecparsers/ are used if the system provided one is now recent enough to have those required extensions. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 25 ----------------------- 1 file changed, 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index d0ff1ec868..9dfd38d5e6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1975,37 +1975,12 @@ decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return TRUE; } -#ifndef HAVE_GST_H264_SLICE_HDR_EPB_COUNT -static guint -get_epb_count(const guint8 *buf, guint buf_size, guint header_size) -{ - guint i, n = 0; - - if (buf_size > header_size) - buf_size = header_size; - - for (i = 2; i < buf_size; i++) { - if (!buf[i - 2] && !buf[i - 1] && buf[i] == 0x03) - i += 2, n++; - } - return n; -} -#endif - static inline guint get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, GstH264NalUnit *nalu) { guint epb_count; -#ifdef HAVE_GST_H264_SLICE_HDR_EPB_COUNT epb_count = slice_hdr->n_emulation_prevention_bytes; -#else - epb_count = get_epb_count( - nalu->data + nalu->offset, - nalu->size, - slice_hdr->header_size / 8 - ); -#endif return 8 /* nal_unit_type */ + slice_hdr->header_size - epb_count * 8; } From 2e8949d77b1503bcd51e4cc6a92ab204db371302 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 16 Oct 2012 16:52:04 +0200 Subject: [PATCH 0869/3781] h264: add flag to compile with strict DPB ordering mode. Allow build with strict DPB ordering mode whereby evicted entries are replaced by the next entries, in order instead of optimizing it away with the last entry in the DPB. This is only useful for debugging purpose, against a reference SW decoder for example. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 9dfd38d5e6..8785923dbf 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -37,6 +37,9 @@ #define DEBUG 1 #include "gstvaapidebug.h" +/* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */ +#define USE_STRICT_DPB_ORDERING 0 + typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; typedef struct _GstVaapiPictureH264Class GstVaapiPictureH264Class; typedef struct _GstVaapiSliceH264 GstVaapiSliceH264; @@ -369,9 +372,13 @@ static void dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index) { GstVaapiDecoderH264Private * const priv = decoder->priv; - guint num_pictures = --priv->dpb_count; + guint i, num_pictures = --priv->dpb_count; - if (index != num_pictures) + if (USE_STRICT_DPB_ORDERING) { + for (i = index; i < num_pictures; i++) + gst_vaapi_picture_replace(&priv->dpb[i], priv->dpb[i + 1]); + } + else if (index != num_pictures) gst_vaapi_picture_replace(&priv->dpb[index], priv->dpb[num_pictures]); gst_vaapi_picture_replace(&priv->dpb[num_pictures], NULL); } From 7d1b583d91db83c3f9d96ae866bca16d8dc8c914 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 17 Oct 2012 14:52:35 +0200 Subject: [PATCH 0870/3781] vaapidecode: fix compiler warnings. Don't care of the return value for gst_vaapi_decoder_put_buffer() during destruction of the element. Don't print out (uninitialised) error code when allocation of video buffer failed. --- gst/vaapi/gstvaapidecode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index cd11f36a87..4d0813573d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -282,8 +282,8 @@ error_create_buffer: gst_vaapi_surface_get_id(GST_VAAPI_SURFACE_PROXY_SURFACE(proxy)); GST_DEBUG("video sink failed to create video buffer for proxy'ed " - "surface %" GST_VAAPI_ID_FORMAT " (error %d)", - GST_VAAPI_ID_ARGS(surface_id), ret); + "surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(surface_id)); g_object_unref(proxy); return GST_FLOW_UNEXPECTED; } @@ -367,7 +367,7 @@ static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { if (decode->decoder) { - gst_vaapi_decoder_put_buffer(decode->decoder, NULL); + (void)gst_vaapi_decoder_put_buffer(decode->decoder, NULL); g_object_unref(decode->decoder); decode->decoder = NULL; } From 4bcfa3fe0a482b2d7b0609704e9683038216b5e3 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Thu, 4 Oct 2012 17:39:53 +0100 Subject: [PATCH 0871/3781] vaapidecode: adopt non-deprecrated glib locking primitive pattern. The use of heap allocated GMutex/GCond is deprecated. Instead place them inside the structure they are locking. These changes switch to use g_mutex_init/g_cond_init rather than the heap allocation functions. Because we cannot test for a NULL pointer for the GMutex/GCond we must initialise inside the GObject _init function and clear inside the _finalize which is guaranteed to only be called once and after the object is no longer in use. --- gst/vaapi/gstvaapidecode.c | 44 ++++++++++++-------------------------- gst/vaapi/gstvaapidecode.h | 4 ++-- 2 files changed, 16 insertions(+), 32 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4d0813573d..e58a31b2ce 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -173,12 +173,9 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) static void gst_vaapidecode_release(GstVaapiDecode *decode, GObject *dead_object) { - if (!decode->decoder_mutex || !decode->decoder_ready) - return; - - g_mutex_lock(decode->decoder_mutex); - g_cond_signal(decode->decoder_ready); - g_mutex_unlock(decode->decoder_mutex); + g_mutex_lock(&decode->decoder_mutex); + g_cond_signal(&decode->decoder_ready); + g_mutex_unlock(&decode->decoder_mutex); } static GstFlowReturn @@ -202,13 +199,13 @@ gst_vaapidecode_step(GstVaapiDecode *decode) if (!proxy) { if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { gboolean was_signalled; - g_mutex_lock(decode->decoder_mutex); + g_mutex_lock(&decode->decoder_mutex); was_signalled = g_cond_wait_until( - decode->decoder_ready, - decode->decoder_mutex, + &decode->decoder_ready, + &decode->decoder_mutex, end_time ); - g_mutex_unlock(decode->decoder_mutex); + g_mutex_unlock(&decode->decoder_mutex); if (was_signalled) continue; goto error_decode_timeout; @@ -317,14 +314,6 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) return FALSE; dpy = decode->display; - decode->decoder_mutex = g_mutex_new(); - if (!decode->decoder_mutex) - return FALSE; - - decode->decoder_ready = g_cond_new(); - if (!decode->decoder_ready) - return FALSE; - switch (gst_vaapi_codec_from_caps(caps)) { case GST_VAAPI_CODEC_MPEG2: decode->decoder = gst_vaapi_decoder_mpeg2_new(dpy, caps); @@ -377,16 +366,7 @@ gst_vaapidecode_destroy(GstVaapiDecode *decode) decode->decoder_caps = NULL; } - if (decode->decoder_ready) { - gst_vaapidecode_release(decode, NULL); - g_cond_free(decode->decoder_ready); - decode->decoder_ready = NULL; - } - - if (decode->decoder_mutex) { - g_mutex_free(decode->decoder_mutex); - decode->decoder_mutex = NULL; - } + gst_vaapidecode_release(decode, NULL); } static gboolean @@ -481,6 +461,9 @@ gst_vaapidecode_finalize(GObject *object) decode->delayed_new_seg = NULL; } + g_cond_clear(&decode->decoder_ready); + g_mutex_clear(&decode->decoder_mutex); + G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object); } @@ -738,8 +721,6 @@ gst_vaapidecode_init(GstVaapiDecode *decode) decode->display = NULL; decode->decoder = NULL; - decode->decoder_mutex = NULL; - decode->decoder_ready = NULL; decode->decoder_caps = NULL; decode->allowed_caps = NULL; decode->delayed_new_seg = NULL; @@ -747,6 +728,9 @@ gst_vaapidecode_init(GstVaapiDecode *decode) decode->last_buffer_time = 0; decode->is_ready = FALSE; + g_mutex_init(&decode->decoder_mutex); + g_cond_init(&decode->decoder_ready); + /* Pad through which data comes in to the element */ decode->sinkpad = gst_pad_new_from_template( gst_element_class_get_pad_template(element_class, "sink"), diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 68799df52e..87e280724a 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -67,8 +67,8 @@ struct _GstVaapiDecode { GstCaps *srcpad_caps; GstVaapiDisplay *display; GstVaapiDecoder *decoder; - GMutex *decoder_mutex; - GCond *decoder_ready; + GMutex decoder_mutex; + GCond decoder_ready; GstCaps *decoder_caps; GstCaps *allowed_caps; GstEvent *delayed_new_seg; From 40cb71f36e4f0f1e8662377cb2f13fd5a72d57ad Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 17 Oct 2012 15:38:14 +0200 Subject: [PATCH 0872/3781] configure: bump glib required version to 2.31.2. Use new Thread API. In particular, g_mutex_init() and g_cond_init() rather than g_mutex_new() and g_cond_new() respectively. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 24ef2a4e4a..9a994659a5 100644 --- a/configure.ac +++ b/configure.ac @@ -11,8 +11,8 @@ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) # glib version number m4_define([glib_major_version], [2]) -m4_define([glib_minor_version], [28]) -m4_define([glib_micro_version], [0]) +m4_define([glib_minor_version], [31]) +m4_define([glib_micro_version], [2]) m4_define([glib_major_minor_version], [glib_major_version.glib_minor_version]) m4_define([glib_version], From 1dea0ef9744a8ae35f293e24d7c190402f38b1a6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 17 Oct 2012 15:42:17 +0200 Subject: [PATCH 0873/3781] configure: generate bzip2 tarballs in ustar format by default. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 9a994659a5..f38d9f9624 100644 --- a/configure.ac +++ b/configure.ac @@ -75,7 +75,7 @@ AC_CONFIG_AUX_DIR([build-aux]) AC_CANONICAL_TARGET -AM_INIT_AUTOMAKE +AM_INIT_AUTOMAKE([1.11 tar-ustar no-dist-gzip dist-bzip2]) TODAY="`LC_ALL=C date +'%a, %d %b %Y %X %z'`" AC_SUBST(TODAY) From a39a709d2d001a19059de304c16b96fe2d2f64fe Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 17 Oct 2012 15:49:23 +0200 Subject: [PATCH 0874/3781] debian: fix make dist for packaging. bzip2 tarballs are now used, so update the deb.upstream dependencies to include dist-bzip2 instead of plain old dist, and use the correct tar extract options to handle that format. --- Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 08a5e2a883..70cb5eea90 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,11 +15,11 @@ DEB_BUILDDIR = debian.build deb: dpkg-buildpackage -rfakeroot -uc -us -deb.upstream: dist +deb.upstream: dist-bzip2 -mkdir -p $(DEB_BUILDDIR) cd $(DEB_BUILDDIR) && \ rm -rf $(PACKAGE)-$(VERSION) && \ - tar zxvf ../$(PACKAGE)-$(VERSION).tar.gz && \ + tar jxvf ../$(PACKAGE)-$(VERSION).tar.bz2 && \ cd $(PACKAGE)-$(VERSION) && \ $(LN_S) debian.upstream debian && \ $(MAKE) deb -f Makefile.am From 04bbd8cc11d38b282e833dd0dc4efa6bdb52d1b2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Oct 2012 10:50:29 +0200 Subject: [PATCH 0875/3781] h264: move MMCO handlers out of the loop (cosmetics). This change only splits each individual MMCO handler into several functions dedicated for each operation. This is needed to perform further work later on. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 149 ++++++++++++++-------- 1 file changed, 99 insertions(+), 50 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 8785923dbf..b4014054cc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1671,6 +1671,84 @@ exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) return TRUE; } +static inline gint32 +get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking) +{ + gint32 pic_num; + + if (!picture->field_pic_flag) + pic_num = picture->frame_num_wrap; + else + pic_num = 2 * picture->frame_num_wrap + 1; + pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1; + return pic_num; +} + +/* 8.2.5.4.1. Mark-term reference picture as "unused for reference" */ +static void +exec_ref_pic_marking_adaptive_mmco_1( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264RefPicMarking *ref_pic_marking +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + gint32 i, picNumX; + + picNumX = get_picNumX(picture, ref_pic_marking); + i = find_short_term_reference(decoder, picNumX); + if (i < 0) + return; + remove_reference_at(decoder, priv->short_ref, &priv->short_ref_count, i); +} + +/* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */ +static void +exec_ref_pic_marking_adaptive_mmco_2( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264RefPicMarking *ref_pic_marking +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + gint32 i; + + i = find_long_term_reference(decoder, picture->long_term_pic_num); + if (i < 0) + return; + remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i); +} + +/* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */ +static void +exec_ref_pic_marking_adaptive_mmco_3( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264RefPicMarking *ref_pic_marking +) +{ + gint32 i, picNumX; + + picNumX = get_picNumX(picture, ref_pic_marking); + i = find_short_term_reference(decoder, picNumX); + if (i < 0) + return; +} + +/* 8.2.5.4.5. Mark all reference pictures as "unused for reference" */ +static void +exec_ref_pic_marking_adaptive_mmco_5( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264RefPicMarking *ref_pic_marking +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + + clear_references(decoder, priv->short_ref, &priv->short_ref_count); + clear_references(decoder, priv->long_ref, &priv->long_ref_count ); +} + /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */ static gboolean exec_ref_pic_marking_adaptive( @@ -1679,64 +1757,35 @@ exec_ref_pic_marking_adaptive( GstH264DecRefPicMarking *dec_ref_pic_marking ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; - gint32 pic_num, ref_idx; guint i; GST_DEBUG("reference picture marking process (adaptive memory control)"); + typedef void (*exec_ref_pic_marking_adaptive_mmco_func)( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264RefPicMarking *ref_pic_marking + ); + + static const exec_ref_pic_marking_adaptive_mmco_func mmco_funcs[] = { + NULL, + exec_ref_pic_marking_adaptive_mmco_1, + exec_ref_pic_marking_adaptive_mmco_2, + exec_ref_pic_marking_adaptive_mmco_3, + NULL, + exec_ref_pic_marking_adaptive_mmco_5, + }; + for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) { GstH264RefPicMarking * const ref_pic_marking = &dec_ref_pic_marking->ref_pic_marking[i]; - switch (ref_pic_marking->memory_management_control_operation) { - case 1: - // Mark short-term reference picture as "unused for reference" - if (!picture->field_pic_flag) - pic_num = picture->frame_num_wrap; - else - pic_num = 2 * picture->frame_num_wrap + 1; - pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1; - ref_idx = find_short_term_reference(decoder, pic_num); - if (ref_idx < 0) - break; - remove_reference_at( - decoder, - priv->short_ref, &priv->short_ref_count, - ref_idx - ); - break; - case 2: - // Mark long-term reference picture as "unused for reference" - pic_num = picture->long_term_pic_num; - ref_idx = find_long_term_reference(decoder, pic_num); - if (ref_idx < 0) - break; - remove_reference_at( - decoder, - priv->long_ref, &priv->long_ref_count, - ref_idx - ); - break; - case 3: - // Assign LongTermFrameIdx to a short-term reference picture - if (!picture->field_pic_flag) - pic_num = picture->frame_num_wrap; - else - pic_num = 2 * picture->frame_num_wrap + 1; - pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1; - ref_idx = find_short_term_reference(decoder, pic_num); - if (ref_idx < 0) - break; - break; - case 5: - // Mark all reference pictures as "unused for reference" - clear_references(decoder, priv->short_ref, &priv->short_ref_count); - clear_references(decoder, priv->long_ref, &priv->long_ref_count ); - break; - default: - g_assert(0 && "unhandled MMCO"); - break; + const guint mmco = ref_pic_marking->memory_management_control_operation; + if (mmco < G_N_ELEMENTS(mmco_funcs) && mmco_funcs[mmco]) + mmco_funcs[mmco](decoder, picture, ref_pic_marking); + else { + GST_ERROR("unhandled MMCO %u", mmco); + return FALSE; } } return TRUE; From d9b5e47585ec7bf5f10f4918422cb00c126cfd4c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Oct 2012 11:52:13 +0200 Subject: [PATCH 0876/3781] h264: fix MMCO-based reference picture marking process. Fix adaptive memory control decoded reference picture marking process implementation for operations 2 to 6, thus also fixing support for long-term reference pictures. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 104 +++++++++++++++++----- 1 file changed, 83 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index b4014054cc..8e362f1bd3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1296,10 +1296,16 @@ remove_reference_at( ) { guint num_pictures = *picture_count; + GstVaapiPictureH264 *picture; g_return_val_if_fail(index < num_pictures, FALSE); - GST_VAAPI_PICTURE_FLAG_UNSET(pictures[index], GST_VAAPI_PICTURE_FLAG_REFERENCE); + picture = pictures[index]; + GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + picture->is_long_term = FALSE; + picture->info.flags &= ~(VA_PICTURE_H264_SHORT_TERM_REFERENCE | + VA_PICTURE_H264_LONG_TERM_REFERENCE); + if (index != --num_pictures) gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]); gst_vaapi_picture_replace(&pictures[num_pictures], NULL); @@ -1608,22 +1614,10 @@ init_picture( for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) { GstH264RefPicMarking * const ref_pic_marking = &dec_ref_pic_marking->ref_pic_marking[i]; - switch (ref_pic_marking->memory_management_control_operation) { - case 3: - case 6: - picture->is_long_term = TRUE; - pic->frame_idx = ref_pic_marking->long_term_frame_idx; - break; - case 5: + if (ref_pic_marking->memory_management_control_operation == 5) picture->has_mmco_5 = TRUE; - break; - } } } - if (picture->is_long_term) - pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE; - else - pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE; } init_picture_poc(decoder, picture, slice_hdr); @@ -1713,7 +1707,7 @@ exec_ref_pic_marking_adaptive_mmco_2( GstVaapiDecoderH264Private * const priv = decoder->priv; gint32 i; - i = find_long_term_reference(decoder, picture->long_term_pic_num); + i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num); if (i < 0) return; remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i); @@ -1727,12 +1721,55 @@ exec_ref_pic_marking_adaptive_mmco_3( GstH264RefPicMarking *ref_pic_marking ) { + GstVaapiDecoderH264Private * const priv = decoder->priv; + VAPictureH264 *pic; gint32 i, picNumX; + for (i = 0; i < priv->long_ref_count; i++) { + if (priv->long_ref[i]->info.frame_idx == ref_pic_marking->long_term_frame_idx) + break; + } + if (i != priv->long_ref_count) + remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i); + picNumX = get_picNumX(picture, ref_pic_marking); i = find_short_term_reference(decoder, picNumX); if (i < 0) return; + + picture = gst_vaapi_picture_ref(priv->short_ref[i]); + remove_reference_at(decoder, priv->short_ref, &priv->short_ref_count, i); + gst_vaapi_picture_replace(&priv->long_ref[priv->long_ref_count++], picture); + gst_vaapi_picture_unref(picture); + + picture->is_long_term = TRUE; + pic = &picture->info; + pic->frame_idx = ref_pic_marking->long_term_frame_idx; + pic->flags &= ~VA_PICTURE_H264_SHORT_TERM_REFERENCE; + pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE; + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); +} + +/* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx + * as "unused for reference" */ +static void +exec_ref_pic_marking_adaptive_mmco_4( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264RefPicMarking *ref_pic_marking +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + gint32 i, long_term_frame_idx; + + long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1; + + for (i = 0; i < priv->long_ref_count; i++) { + if ((gint32)priv->long_ref[i]->info.frame_idx <= long_term_frame_idx) + continue; + remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i); + i--; + } } /* 8.2.5.4.5. Mark all reference pictures as "unused for reference" */ @@ -1747,6 +1784,23 @@ exec_ref_pic_marking_adaptive_mmco_5( clear_references(decoder, priv->short_ref, &priv->short_ref_count); clear_references(decoder, priv->long_ref, &priv->long_ref_count ); + dpb_flush(decoder); + + /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */ + picture->frame_num = 0; + picture->poc = 0; +} + +/* 8.2.5.4.6. Assign a long-term frame index to the current picture */ +static void +exec_ref_pic_marking_adaptive_mmco_6( + GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, + GstH264RefPicMarking *ref_pic_marking +) +{ + picture->is_long_term = TRUE; + picture->info.frame_idx = ref_pic_marking->long_term_frame_idx; } /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */ @@ -1772,8 +1826,9 @@ exec_ref_pic_marking_adaptive( exec_ref_pic_marking_adaptive_mmco_1, exec_ref_pic_marking_adaptive_mmco_2, exec_ref_pic_marking_adaptive_mmco_3, - NULL, + exec_ref_pic_marking_adaptive_mmco_4, exec_ref_pic_marking_adaptive_mmco_5, + exec_ref_pic_marking_adaptive_mmco_6, }; for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) { @@ -1814,10 +1869,14 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) } } - if (picture->is_long_term) + if (picture->is_long_term) { picture_ptr = &priv->long_ref[priv->long_ref_count++]; - else + picture->info.flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE; + } + else { picture_ptr = &priv->short_ref[priv->short_ref_count++]; + picture->info.flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE; + } gst_vaapi_picture_replace(picture_ptr, picture); return TRUE; } @@ -1847,11 +1906,14 @@ exit_picture_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) break; case 1: case 2: - priv->prev_frame_num = priv->frame_num; - if (picture->has_mmco_5) + if (picture->has_mmco_5) { + priv->prev_frame_num = 0; priv->prev_frame_num_offset = 0; - else + } + else { + priv->prev_frame_num = priv->frame_num; priv->prev_frame_num_offset = priv->frame_num_offset; + } break; } } From 97979ee6de1ba834bc05a2a675e93dec1815a5eb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 23 Oct 2012 10:33:50 +0200 Subject: [PATCH 0877/3781] h264: simplify code when MMCO is 5. Remove exit_picture() and exit_picture_poc() since PicOrderCnt(CurrPic) is now updated accordingly to the standard. Besides, MMCO = 5 specific operations are moved up to exec_ref_pic_marking_adaptive_mmco_5(). --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 122 +++++++++------------- 1 file changed, 51 insertions(+), 71 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 8e362f1bd3..6c4adf71d7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -88,7 +88,6 @@ struct _GstVaapiPictureH264 { guint is_long_term : 1; guint field_pic_flag : 1; guint bottom_field_flag : 1; - guint has_mmco_5 : 1; guint output_flag : 1; guint output_needed : 1; }; @@ -129,7 +128,6 @@ gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture) picture->poc = 0; picture->is_long_term = FALSE; picture->is_idr = FALSE; - picture->has_mmco_5 = FALSE; picture->output_needed = FALSE; } @@ -289,9 +287,10 @@ struct _GstVaapiDecoderH264Private { gint32 prev_poc_msb; // prevPicOrderCntMsb gint32 prev_poc_lsb; // prevPicOrderCntLsb gint32 frame_num_offset; // FrameNumOffset - gint32 prev_frame_num_offset; // prevFrameNumOffset gint32 frame_num; // frame_num (from slice_header()) gint32 prev_frame_num; // prevFrameNum + gboolean prev_pic_has_mmco5; // prevMmco5Pic + gboolean prev_pic_bottom_field; // Flag: previous picture is a bottom field guint is_constructed : 1; guint is_opened : 1; guint is_avc : 1; @@ -786,6 +785,20 @@ init_picture_poc_0( GST_DEBUG("decode picture order count type 0"); + if (picture->is_idr) { + priv->prev_poc_msb = 0; + priv->prev_poc_lsb = 0; + } + else if (priv->prev_pic_has_mmco5) { + priv->prev_poc_msb = 0; + priv->prev_poc_lsb = priv->prev_pic_bottom_field ? 0 : + priv->field_poc[TOP_FIELD]; + } + else { + priv->prev_poc_msb = priv->poc_msb; + priv->prev_poc_lsb = priv->poc_lsb; + } + // (8-3) priv->poc_lsb = slice_hdr->pic_order_cnt_lsb; if (priv->poc_lsb < priv->prev_poc_lsb && @@ -821,18 +834,23 @@ init_picture_poc_1( GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); - gint32 abs_frame_num, expected_poc; + gint32 prev_frame_num_offset, abs_frame_num, expected_poc; guint i; GST_DEBUG("decode picture order count type 1"); + if (priv->prev_pic_has_mmco5) + prev_frame_num_offset = 0; + else + prev_frame_num_offset = priv->frame_num_offset; + // (8-6) if (picture->is_idr) priv->frame_num_offset = 0; else if (priv->prev_frame_num > priv->frame_num) - priv->frame_num_offset = priv->prev_frame_num_offset + MaxFrameNum; + priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum; else - priv->frame_num_offset = priv->prev_frame_num_offset; + priv->frame_num_offset = prev_frame_num_offset; // (8-7) if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0) @@ -894,17 +912,22 @@ init_picture_poc_2( GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); - guint temp_poc; + gint32 prev_frame_num_offset, temp_poc; GST_DEBUG("decode picture order count type 2"); + if (priv->prev_pic_has_mmco5) + prev_frame_num_offset = 0; + else + prev_frame_num_offset = priv->frame_num_offset; + // (8-11) if (picture->is_idr) priv->frame_num_offset = 0; else if (priv->prev_frame_num > priv->frame_num) - priv->frame_num_offset = priv->prev_frame_num_offset + MaxFrameNum; + priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum; else - priv->frame_num_offset = priv->prev_frame_num_offset; + priv->frame_num_offset = prev_frame_num_offset; // (8-12) if (picture->is_idr) @@ -1552,8 +1575,8 @@ init_picture( GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiPicture * const base_picture = &picture->base; VAPictureH264 *pic; - guint i; + priv->prev_frame_num = priv->frame_num; priv->frame_num = slice_hdr->frame_num; picture->frame_num = priv->frame_num; picture->frame_num_wrap = priv->frame_num; @@ -1568,8 +1591,6 @@ init_picture( GST_DEBUG(""); clear_references(decoder, priv->short_ref, &priv->short_ref_count); clear_references(decoder, priv->long_ref, &priv->long_ref_count ); - priv->prev_poc_msb = 0; - priv->prev_poc_lsb = 0; } /* Initialize VA picture info */ @@ -1610,14 +1631,6 @@ init_picture( if (dec_ref_pic_marking->long_term_reference_flag) picture->is_long_term = TRUE; } - else if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) { - for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) { - GstH264RefPicMarking * const ref_pic_marking = - &dec_ref_pic_marking->ref_pic_marking[i]; - if (ref_pic_marking->memory_management_control_operation == 5) - picture->has_mmco_5 = TRUE; - } - } } init_picture_poc(decoder, picture, slice_hdr); @@ -1781,13 +1794,24 @@ exec_ref_pic_marking_adaptive_mmco_5( ) { GstVaapiDecoderH264Private * const priv = decoder->priv; + VAPictureH264 * const pic = &picture->info; clear_references(decoder, priv->short_ref, &priv->short_ref_count); clear_references(decoder, priv->long_ref, &priv->long_ref_count ); dpb_flush(decoder); + priv->prev_pic_has_mmco5 = TRUE; + /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */ + priv->frame_num = 0; + priv->frame_num_offset = 0; picture->frame_num = 0; + + /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */ + if (!(pic->flags & VA_PICTURE_H264_BOTTOM_FIELD)) + pic->TopFieldOrderCnt -= picture->poc; + if (!(pic->flags & VA_PICTURE_H264_TOP_FIELD)) + pic->BottomFieldOrderCnt -= picture->poc; picture->poc = 0; } @@ -1853,6 +1877,10 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiPictureH264 **picture_ptr; + priv->prev_pic_has_mmco5 = FALSE; + priv->prev_pic_bottom_field = + picture->field_pic_flag && picture->bottom_field_flag; + if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) return TRUE; @@ -1881,55 +1909,6 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return TRUE; } -/* Update picture order count */ -static void -exit_picture_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) -{ - GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264SPS * const sps = priv->sps; - - switch (sps->pic_order_cnt_type) { - case 0: - if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) - break; - if (picture->has_mmco_5) { - priv->prev_poc_msb = 0; - if (!picture->field_pic_flag || !picture->bottom_field_flag) - priv->prev_poc_lsb = picture->info.TopFieldOrderCnt; - else - priv->prev_poc_lsb = 0; - } - else { - priv->prev_poc_msb = priv->poc_msb; - priv->prev_poc_lsb = priv->poc_lsb; - } - break; - case 1: - case 2: - if (picture->has_mmco_5) { - priv->prev_frame_num = 0; - priv->prev_frame_num_offset = 0; - } - else { - priv->prev_frame_num = priv->frame_num; - priv->prev_frame_num_offset = priv->frame_num_offset; - } - break; - } -} - -static inline gboolean -exit_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) -{ - /* Update picture order count */ - exit_picture_poc(decoder, picture); - - /* Decoded reference picture marking process */ - if (!exec_ref_pic_marking(decoder, picture)) - return FALSE; - return TRUE; -} - static void vaapi_init_picture(VAPictureH264 *pic) { @@ -2086,7 +2065,7 @@ decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { if (!fill_quant_matrix(decoder, picture)) return FALSE; - if (!exit_picture(decoder, picture)) + if (!exec_ref_pic_marking(decoder, picture)) return FALSE; if (!dpb_add(decoder, picture)) return FALSE; @@ -2610,9 +2589,10 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->prev_poc_msb = 0; priv->prev_poc_lsb = 0; priv->frame_num_offset = 0; - priv->prev_frame_num_offset = 0; priv->frame_num = 0; priv->prev_frame_num = 0; + priv->prev_pic_has_mmco5 = FALSE; + priv->prev_pic_bottom_field = FALSE; priv->is_constructed = FALSE; priv->is_opened = FALSE; priv->is_avc = FALSE; From efaab79e89e6d039a916f6fd817efa6eae4c4e61 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 23 Oct 2012 14:50:14 +0200 Subject: [PATCH 0878/3781] h264: optimize handling of scaling lists. Don't copy scaling lists twice to an intermediate state. Rather, directly use the scaling lists from GstH264PPS since they would match those provided by SPS header, if necessary. i.e. if PPS-specific scaling lists are not available in the bitstream. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 85 ++++++++++++----------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 6c4adf71d7..6f07895c4a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -279,8 +279,6 @@ struct _GstVaapiDecoderH264Private { guint mb_y; guint mb_width; guint mb_height; - guint8 scaling_list_4x4[6][16]; - guint8 scaling_list_8x8[6][64]; gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt gint32 poc_msb; // PicOrderCntMsb gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header()) @@ -659,15 +657,52 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) } static GstVaapiDecoderStatus -ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstH264PPS *pps) +ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264SPS * const sps = priv->sps; + GstH264PPS * const pps = priv->pps; + GstVaapiPicture * const base_picture = &picture->base; + VAIQMatrixBufferH264 *iq_matrix; + guint i, j, n; - if (priv->pps != pps) { - memcpy(priv->scaling_list_4x4, pps->scaling_lists_4x4, - sizeof(priv->scaling_list_4x4)); - memcpy(priv->scaling_list_8x8, pps->scaling_lists_8x8, - sizeof(priv->scaling_list_8x8)); + base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder); + if (!base_picture->iq_matrix) { + GST_ERROR("failed to allocate IQ matrix"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + iq_matrix = base_picture->iq_matrix->param; + + /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[] + is not large enough to hold lists for 4:4:4 */ + if (sps->chroma_format_idc == 3) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; + + g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16); + g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64); + + if (sizeof(iq_matrix->ScalingList4x4) == sizeof(pps->scaling_lists_4x4)) + memcpy(iq_matrix->ScalingList4x4, pps->scaling_lists_4x4, + sizeof(iq_matrix->ScalingList4x4)); + else { + n = MIN(G_N_ELEMENTS(iq_matrix->ScalingList4x4), + G_N_ELEMENTS(pps->scaling_lists_4x4)); + for (i = 0; i < n; i++) { + for (j = 0; j < 16; j++) + iq_matrix->ScalingList4x4[i][j] = pps->scaling_lists_4x4[i][j]; + } + } + + if (sizeof(iq_matrix->ScalingList8x8) == sizeof(pps->scaling_lists_8x8)) + memcpy(iq_matrix->ScalingList8x8, pps->scaling_lists_8x8, + sizeof(iq_matrix->ScalingList8x8)); + else { + n = MIN(G_N_ELEMENTS(iq_matrix->ScalingList8x8), + G_N_ELEMENTS(pps->scaling_lists_8x8)); + for (i = 0; i < n; i++) { + for (j = 0; j < 16; j++) + iq_matrix->ScalingList8x8[i][j] = pps->scaling_lists_8x8[i][j]; + } } return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1993,26 +2028,6 @@ fill_picture( return TRUE; } -static gboolean -fill_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) -{ - GstVaapiDecoderH264Private * const priv = decoder->priv; - VAIQMatrixBufferH264 * const iq_matrix = picture->base.iq_matrix->param; - - /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[] - is not large enough to hold lists for 4:4:4 */ - if (priv->sps->chroma_format_idc == 3 && - sizeof(iq_matrix->ScalingList8x8) != sizeof(priv->scaling_list_8x8)) - return FALSE; - - /* Fill in VAIQMatrixBufferH264 */ - memcpy(iq_matrix->ScalingList4x4, priv->scaling_list_4x4, - sizeof(iq_matrix->ScalingList4x4)); - memcpy(iq_matrix->ScalingList8x8, priv->scaling_list_8x8, - sizeof(iq_matrix->ScalingList8x8)); - return TRUE; -} - static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceHdr *slice_hdr) { @@ -2038,21 +2053,15 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceH } priv->current_picture = picture; - picture->base.iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder); - if (!picture->base.iq_matrix) { - GST_ERROR("failed to allocate IQ matrix"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } + priv->sps = sps; + priv->pps = pps; - status = ensure_quant_matrix(decoder, pps); + status = ensure_quant_matrix(decoder, picture); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { GST_ERROR("failed to reset quantizer matrix"); return status; } - priv->sps = sps; - priv->pps = pps; - if (!init_picture(decoder, picture, slice_hdr, nalu)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; if (!fill_picture(decoder, picture, slice_hdr, nalu)) @@ -2063,8 +2072,6 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceH static gboolean decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { - if (!fill_quant_matrix(decoder, picture)) - return FALSE; if (!exec_ref_pic_marking(decoder, picture)) return FALSE; if (!dpb_add(decoder, picture)) From 6398bc7d3c86a6b220415c497ea609cb41186da7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Oct 2012 18:23:09 +0200 Subject: [PATCH 0879/3781] h264: fix detection of picture boundaries. Strictly follow the standard (7.4.1.2.4) to detect the first VCL NAL unit of a primary coded picture. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 104 +++++++++++++++++++--- 1 file changed, 92 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 6f07895c4a..0e7f748b10 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -149,6 +149,17 @@ gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder) return GST_VAAPI_PICTURE_H264_CAST(object); } +static inline GstVaapiSliceH264 * +gst_vaapi_picture_h264_get_last_slice(GstVaapiPictureH264 *picture) +{ + g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL); + + if (G_UNLIKELY(picture->base.slices->len < 1)) + return NULL; + return g_ptr_array_index(picture->base.slices, + picture->base.slices->len - 1); +} + /* ------------------------------------------------------------------------- */ /* --- Slices --- */ /* ------------------------------------------------------------------------- */ @@ -509,16 +520,6 @@ get_status(GstH264ParserResult result) return status; } -static inline GstH264DecRefPicMarking * -get_dec_ref_pic_marking(GstVaapiPictureH264 *picture_h264) -{ - GstVaapiPicture * const picture = GST_VAAPI_PICTURE_CAST(picture_h264); - GstVaapiSliceH264 *slice; - - slice = g_ptr_array_index(picture->slices, picture->slices->len - 1); - return &slice->slice_hdr.dec_ref_pic_marking; -} - static void gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) { @@ -1920,8 +1921,10 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return TRUE; if (!picture->is_idr) { + GstVaapiSliceH264 * const slice = + gst_vaapi_picture_h264_get_last_slice(picture); GstH264DecRefPicMarking * const dec_ref_pic_marking = - get_dec_ref_pic_marking(picture); + &slice->slice_hdr.dec_ref_pic_marking; if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) { if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking)) return FALSE; @@ -2028,6 +2031,83 @@ fill_picture( return TRUE; } +/* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */ +static gboolean +is_new_picture( + GstVaapiDecoderH264 *decoder, + GstH264NalUnit *nalu, + GstH264SliceHdr *slice_hdr +) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264PPS * const pps = slice_hdr->pps; + GstH264SPS * const sps = pps->sequence; + GstVaapiSliceH264 *slice; + GstH264SliceHdr *prev_slice_hdr; + + if (!priv->current_picture) + return TRUE; + + slice = gst_vaapi_picture_h264_get_last_slice(priv->current_picture); + if (!slice) + return FALSE; + prev_slice_hdr = &slice->slice_hdr; + +#define CHECK_EXPR(expr, field_name) do { \ + if (!(expr)) { \ + GST_DEBUG(field_name " differs in value"); \ + return TRUE; \ + } \ + } while (0) + +#define CHECK_VALUE(new_slice_hdr, old_slice_hdr, field) \ + CHECK_EXPR(((new_slice_hdr)->field == (old_slice_hdr)->field), #field) + + /* frame_num differs in value, regardless of inferred values to 0 */ + CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num); + + /* pic_parameter_set_id differs in value */ + CHECK_VALUE(slice_hdr, prev_slice_hdr, pps); + + /* field_pic_flag differs in value */ + CHECK_VALUE(slice_hdr, prev_slice_hdr, field_pic_flag); + + /* bottom_field_flag is present in both and differs in value */ + if (slice_hdr->field_pic_flag && prev_slice_hdr->field_pic_flag) + CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag); + + /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */ + CHECK_EXPR(((GST_VAAPI_PICTURE_IS_REFERENCE(priv->current_picture) ^ + (nalu->ref_idc != 0)) == 0), "nal_ref_idc"); + + /* POC type is 0 for both and either pic_order_cnt_lsb differs in + value or delta_pic_order_cnt_bottom differs in value */ + if (sps->pic_order_cnt_type == 0) { + CHECK_VALUE(slice_hdr, prev_slice_hdr, pic_order_cnt_lsb); + if (pps->pic_order_present_flag && !slice_hdr->field_pic_flag) + CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt_bottom); + } + + /* POC type is 1 for both and either delta_pic_order_cnt[0] + differs in value or delta_pic_order_cnt[1] differs in value */ + else if (sps->pic_order_cnt_type == 1) { + CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[0]); + CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[1]); + } + + /* IdrPicFlag differs in value */ + CHECK_EXPR(((priv->current_picture->is_idr ^ + (nalu->type == GST_H264_NAL_SLICE_IDR)) == 0), "IdrPicFlag"); + + /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */ + if (priv->current_picture->is_idr) + CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id); + +#undef CHECK_EXPR +#undef CHECK_VALUE + return FALSE; +} + static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceHdr *slice_hdr) { @@ -2254,7 +2334,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) goto error; } - if (slice_hdr->first_mb_in_slice == 0) { + if (is_new_picture(decoder, nalu, slice_hdr)) { status = decode_picture(decoder, nalu, slice_hdr); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto error; From 015879cafe999e359881629705d2275f75d5c385 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 26 Oct 2012 13:17:43 +0200 Subject: [PATCH 0880/3781] h264: fix scaling list generation. ... aka fix regression from efaab79. In particular, ScalingList8x8[] array was partially copied to the VAIQMatrixBufferH264. While we are at it, also improve bounds checking and avoid copying 8x8 scaling lists if transform_8x8_mode_flag is set to 0. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 75 +++++++++++++++-------- 1 file changed, 49 insertions(+), 26 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 0e7f748b10..39aa988785 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -657,6 +657,53 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static void +fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps) +{ + const guint8 (* const ScalingList4x4)[6][16] = &pps->scaling_lists_4x4; + guint i, j; + + /* There are always 6 4x4 scaling lists */ + g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4) == 6); + g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16); + + if (sizeof(iq_matrix->ScalingList4x4[0][0]) == 1) + memcpy(iq_matrix->ScalingList4x4, *ScalingList4x4, + sizeof(iq_matrix->ScalingList4x4)); + else { + for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) { + for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList4x4[i]); j++) + iq_matrix->ScalingList4x4[i][j] = (*ScalingList4x4)[i][j]; + } + } +} + +static void +fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps) +{ + const guint8 (* const ScalingList8x8)[6][64] = &pps->scaling_lists_8x8; + const GstH264SPS * const sps = pps->sequence; + guint i, j, n; + + /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */ + if (!pps->transform_8x8_mode_flag) + return; + + g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8) >= 2); + g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64); + + if (sizeof(iq_matrix->ScalingList8x8[0][0]) == 1) + memcpy(iq_matrix->ScalingList8x8, *ScalingList8x8, + sizeof(iq_matrix->ScalingList8x8)); + else { + n = (sps->chroma_format_idc != 3) ? 2 : 6; + for (i = 0; i < n; i++) { + for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList8x8[i]); j++) + iq_matrix->ScalingList8x8[i][j] = (*ScalingList8x8)[i][j]; + } + } +} + static GstVaapiDecoderStatus ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { @@ -665,7 +712,6 @@ ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) GstH264PPS * const pps = priv->pps; GstVaapiPicture * const base_picture = &picture->base; VAIQMatrixBufferH264 *iq_matrix; - guint i, j, n; base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder); if (!base_picture->iq_matrix) { @@ -679,32 +725,9 @@ ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (sps->chroma_format_idc == 3) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; - g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16); - g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64); + fill_iq_matrix_4x4(iq_matrix, pps); + fill_iq_matrix_8x8(iq_matrix, pps); - if (sizeof(iq_matrix->ScalingList4x4) == sizeof(pps->scaling_lists_4x4)) - memcpy(iq_matrix->ScalingList4x4, pps->scaling_lists_4x4, - sizeof(iq_matrix->ScalingList4x4)); - else { - n = MIN(G_N_ELEMENTS(iq_matrix->ScalingList4x4), - G_N_ELEMENTS(pps->scaling_lists_4x4)); - for (i = 0; i < n; i++) { - for (j = 0; j < 16; j++) - iq_matrix->ScalingList4x4[i][j] = pps->scaling_lists_4x4[i][j]; - } - } - - if (sizeof(iq_matrix->ScalingList8x8) == sizeof(pps->scaling_lists_8x8)) - memcpy(iq_matrix->ScalingList8x8, pps->scaling_lists_8x8, - sizeof(iq_matrix->ScalingList8x8)); - else { - n = MIN(G_N_ELEMENTS(iq_matrix->ScalingList8x8), - G_N_ELEMENTS(pps->scaling_lists_8x8)); - for (i = 0; i < n; i++) { - for (j = 0; j < 16; j++) - iq_matrix->ScalingList8x8[i][j] = pps->scaling_lists_8x8[i][j]; - } - } return GST_VAAPI_DECODER_STATUS_SUCCESS; } From e30a5182673c6b21b5d8ef223afa78cfd9405cd7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 26 Oct 2012 16:12:05 +0200 Subject: [PATCH 0881/3781] h264: fix activation order of picture and sequence parameters. Delay ensure_context() until we actually need a VA context for allocating new VA surfaces, and then GstVaapiPictures, but also when a real activation of a new picture parameter set occurs, thus also implying an activation of the related sequence parameter set. The most important thing was to drop the global pps and sps pointers since they may not have matched the currently activated picture parameter or sequence parameter sets at the specified decode point. Anoter positive side-effect is that this cleans up all occurrences of decode_current_picture() to only keep those useful in decode_picture(), before a new picture is allocated, or in decode_sequence_end() when an end-of-stream or end-of-sequence condition occurred. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 290 ++++++++++++---------- 1 file changed, 161 insertions(+), 129 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 39aa988785..ef07381f39 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -79,6 +79,7 @@ typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class; struct _GstVaapiPictureH264 { GstVaapiPicture base; VAPictureH264 info; + GstH264PPS *pps; gint32 poc; gint32 frame_num; // Original frame_num from slice_header() gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap @@ -266,15 +267,19 @@ G_DEFINE_TYPE(GstVaapiDecoderH264, struct _GstVaapiDecoderH264Private { GstAdapter *adapter; GstH264NalParser *parser; - GstH264SPS *sps; + /* Last decoded SPS. May not be the last activated one. Just here because + it may not fit stack memory allocation in decode_sps() */ GstH264SPS last_sps; - GstH264PPS *pps; + /* Last decoded PPS. May not be the last activated one. Just here because + it may not fit stack memory allocation in decode_pps() */ GstH264PPS last_pps; GstVaapiPictureH264 *current_picture; GstVaapiPictureH264 *dpb[16]; guint dpb_count; guint dpb_size; GstVaapiProfile profile; + GstVaapiEntrypoint entrypoint; + GstVaapiChromaType chroma_type; GstVaapiPictureH264 *short_ref[32]; guint short_ref_count; GstVaapiPictureH264 *long_ref[32]; @@ -286,10 +291,6 @@ struct _GstVaapiDecoderH264Private { guint nal_length_size; guint width; guint height; - guint mb_x; - guint mb_y; - guint mb_width; - guint mb_height; gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt gint32 poc_msb; // PicOrderCntMsb gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header()) @@ -573,87 +574,140 @@ gst_vaapi_decoder_h264_create(GstVaapiDecoderH264 *decoder) return TRUE; } +static guint +h264_get_profile(GstH264SPS *sps) +{ + guint profile = 0; + + switch (sps->profile_idc) { + case 66: + profile = GST_VAAPI_PROFILE_H264_BASELINE; + break; + case 77: + profile = GST_VAAPI_PROFILE_H264_MAIN; + break; + case 100: + profile = GST_VAAPI_PROFILE_H264_HIGH; + break; + } + return profile; +} + +static guint +h264_get_chroma_type(GstH264SPS *sps) +{ + guint chroma_type = 0; + + switch (sps->chroma_format_idc) { + case 1: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + break; + case 2: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; + break; + case 3: + if (!sps->separate_colour_plane_flag) + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; + break; + } + return chroma_type; +} + +static GstVaapiProfile +get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder); + GstVaapiProfile profile, profiles[2]; + guint i, n_profiles = 0; + + profile = h264_get_profile(sps); + if (!profile) + return GST_VAAPI_PROFILE_UNKNOWN; + + profiles[n_profiles++] = profile; + switch (profile) { + case GST_VAAPI_PROFILE_H264_MAIN: + profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; + break; + default: + break; + } + + /* If the preferred profile (profiles[0]) matches one that we already + found, then just return it now instead of searching for it again */ + if (profiles[0] == priv->profile) + return priv->profile; + + for (i = 0; i < n_profiles; i++) { + if (gst_vaapi_display_has_decoder(display, profiles[i], priv->entrypoint)) + return profiles[i]; + } + return GST_VAAPI_PROFILE_UNKNOWN; +} + static GstVaapiDecoderStatus ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) { + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); GstVaapiDecoderH264Private * const priv = decoder->priv; - GstVaapiProfile profiles[2]; - GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; - guint i, n_profiles = 0; - gboolean success, reset_context = FALSE; + GstVaapiContextInfo info; + GstVaapiProfile profile; + GstVaapiChromaType chroma_type; + gboolean reset_context = FALSE; - if (!priv->has_context || priv->sps->profile_idc != sps->profile_idc) { + profile = get_profile(decoder, sps); + if (!profile) { + GST_ERROR("unsupported profile_idc %u", sps->profile_idc); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + + if (priv->profile != profile) { GST_DEBUG("profile changed"); reset_context = TRUE; - - switch (sps->profile_idc) { - case 66: - profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE; - break; - case 77: - profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_MAIN; - // fall-through - case 100: - profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; - break; - default: - GST_DEBUG("unsupported profile %d", sps->profile_idc); - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - } - - for (i = 0; i < n_profiles; i++) { - success = gst_vaapi_display_has_decoder( - GST_VAAPI_DECODER_DISPLAY(decoder), - profiles[i], - entrypoint - ); - if (success) - break; - } - if (i == n_profiles) - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - priv->profile = profiles[i]; + priv->profile = profile; } - if (!priv->has_context || - priv->sps->chroma_format_idc != sps->chroma_format_idc) { + chroma_type = h264_get_chroma_type(sps); + if (!chroma_type || chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) { + GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; + } + + if (priv->chroma_type != chroma_type) { GST_DEBUG("chroma format changed"); - reset_context = TRUE; - - /* XXX: theoritically, we could handle 4:2:2 format */ - if (sps->chroma_format_idc != 1) - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; + reset_context = TRUE; + priv->chroma_type = chroma_type; } - if (!priv->has_context || - priv->sps->width != sps->width || - priv->sps->height != sps->height) { + if (priv->width != sps->width || priv->height != sps->height) { GST_DEBUG("size changed"); - reset_context = TRUE; - - priv->width = sps->width; - priv->height = sps->height; - priv->mb_width = sps->pic_width_in_mbs_minus1 + 1; - priv->mb_height = sps->pic_height_in_map_units_minus1 + 1; - priv->mb_height *= 2 - sps->frame_mbs_only_flag; + reset_context = TRUE; + priv->width = sps->width; + priv->height = sps->height; } - if (reset_context) { - GstVaapiContextInfo info; + gst_vaapi_decoder_set_pixel_aspect_ratio( + base_decoder, + sps->vui_parameters.par_n, + sps->vui_parameters.par_d + ); - info.profile = priv->profile; - info.entrypoint = entrypoint; - info.width = priv->width; - info.height = priv->height; - info.ref_frames = get_max_dec_frame_buffering(sps); + if (!reset_context && priv->has_context) + return GST_VAAPI_DECODER_STATUS_SUCCESS; - if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - priv->has_context = TRUE; + info.profile = priv->profile; + info.entrypoint = priv->entrypoint; + info.width = priv->width; + info.height = priv->height; + info.ref_frames = get_max_dec_frame_buffering(sps); - /* Reset DPB */ - dpb_reset(decoder, sps); - } + if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + priv->has_context = TRUE; + + /* Reset DPB */ + dpb_reset(decoder, sps); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -707,10 +761,9 @@ fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps) static GstVaapiDecoderStatus ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { - GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264SPS * const sps = priv->sps; - GstH264PPS * const pps = priv->pps; GstVaapiPicture * const base_picture = &picture->base; + GstH264PPS * const pps = picture->pps; + GstH264SPS * const sps = pps->sequence; VAIQMatrixBufferH264 *iq_matrix; base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder); @@ -731,50 +784,47 @@ ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static gboolean +static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiPictureH264 * const picture = priv->current_picture; - gboolean success = FALSE; + GstVaapiDecoderStatus status; if (!picture) - return TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + status = ensure_context(decoder, picture->pps->sequence); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; if (!decode_picture_end(decoder, picture)) - goto end; + goto error; if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture))) - goto end; - success = TRUE; -end: + goto error; gst_vaapi_picture_replace(&priv->current_picture, NULL); - return success; + return GST_VAAPI_DECODER_STATUS_SUCCESS; + +error: + gst_vaapi_picture_replace(&priv->current_picture, NULL); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } static GstVaapiDecoderStatus decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderH264Private * const priv = decoder->priv; GstH264SPS * const sps = &priv->last_sps; GstH264ParserResult result; GST_DEBUG("decode SPS"); - if (priv->current_picture && !decode_current_picture(decoder)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - memset(sps, 0, sizeof(*sps)); result = gst_h264_parser_parse_sps(priv->parser, nalu, sps, TRUE); if (result != GST_H264_PARSER_OK) return get_status(result); - gst_vaapi_decoder_set_pixel_aspect_ratio( - base_decoder, - sps->vui_parameters.par_n, - sps->vui_parameters.par_d - ); - return ensure_context(decoder, sps); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus @@ -786,9 +836,6 @@ decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) GST_DEBUG("decode PPS"); - if (priv->current_picture && !decode_current_picture(decoder)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - memset(pps, 0, sizeof(*pps)); result = gst_h264_parser_parse_pps(priv->parser, nalu, pps); if (result != GST_H264_PARSER_OK) @@ -819,12 +866,14 @@ decode_sei(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderH264 *decoder) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; GST_DEBUG("decode sequence-end"); - if (priv->current_picture && !decode_current_picture(decoder)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + status = decode_current_picture(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + dpb_flush(decoder); return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; } @@ -1705,7 +1754,8 @@ static gboolean exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264SPS * const sps = priv->sps; + GstH264PPS * const pps = priv->current_picture->pps; + GstH264SPS * const sps = pps->sequence; guint i, max_num_ref_frames, lowest_frame_num_index; gint32 lowest_frame_num; @@ -1990,8 +2040,8 @@ fill_picture( { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiPicture * const base_picture = &picture->base; - GstH264SPS * const sps = priv->sps; - GstH264PPS * const pps = priv->pps; + GstH264PPS * const pps = picture->pps; + GstH264SPS * const sps = pps->sequence; VAPictureParameterBufferH264 * const pic_param = base_picture->param; guint i, n; @@ -2010,9 +2060,9 @@ fill_picture( #define COPY_BFM(a, s, f) \ pic_param->a.bits.f = (s)->f - pic_param->picture_width_in_mbs_minus1 = priv->mb_width - 1; - pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1; - pic_param->frame_num = priv->frame_num; + pic_param->picture_width_in_mbs_minus1 = ((priv->width + 15) >> 4) - 1; + pic_param->picture_height_in_mbs_minus1 = ((priv->height + 15) >> 4) - 1; + pic_param->frame_num = priv->frame_num; COPY_FIELD(sps, bit_depth_luma_minus8); COPY_FIELD(sps, bit_depth_chroma_minus8); @@ -2140,14 +2190,13 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceH GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; - status = ensure_context(decoder, sps); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_ERROR("failed to reset context"); + status = decode_current_picture(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - } - if (priv->current_picture && !decode_current_picture(decoder)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + status = ensure_context(decoder, sps); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; picture = gst_vaapi_picture_h264_new(decoder); if (!picture) { @@ -2156,8 +2205,7 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceH } priv->current_picture = picture; - priv->sps = sps; - priv->pps = pps; + picture->pps = pps; status = ensure_quant_matrix(decoder, picture); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { @@ -2364,9 +2412,6 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) } picture = priv->current_picture; - priv->mb_x = slice_hdr->first_mb_in_slice % priv->mb_width; - priv->mb_y = slice_hdr->first_mb_in_slice / priv->mb_width; // FIXME: MBAFF or field - if (!fill_slice(decoder, slice, nalu)) { status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; goto error; @@ -2375,15 +2420,6 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) GST_VAAPI_PICTURE_CAST(picture), GST_VAAPI_SLICE_CAST(slice) ); - - /* Commit picture for decoding if we reached the last slice */ - if (++priv->mb_y >= priv->mb_height) { - if (!decode_current_picture(decoder)) { - status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - goto error; - } - GST_DEBUG("done"); - } return GST_VAAPI_DECODER_STATUS_SUCCESS; error: @@ -2674,12 +2710,12 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder); decoder->priv = priv; priv->parser = NULL; - priv->sps = &priv->last_sps; - priv->pps = &priv->last_pps; priv->current_picture = NULL; priv->dpb_count = 0; priv->dpb_size = 0; - priv->profile = GST_VAAPI_PROFILE_H264_HIGH; + priv->profile = GST_VAAPI_PROFILE_UNKNOWN; + priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD; + priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; priv->short_ref_count = 0; priv->long_ref_count = 0; priv->RefPicList0_count = 0; @@ -2687,10 +2723,6 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->nal_length_size = 0; priv->width = 0; priv->height = 0; - priv->mb_x = 0; - priv->mb_y = 0; - priv->mb_width = 0; - priv->mb_height = 0; priv->adapter = NULL; priv->field_poc[0] = 0; priv->field_poc[1] = 0; From 49774b3c582c7583d64d798c1a81171eba054b50 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 31 Oct 2012 11:07:48 +0100 Subject: [PATCH 0882/3781] h264: add vaapi_fill_picture() helper. Add vaapi_fill_picture() helper function to convert GstVaapiPictureH264 to VAPictureH264 structure. This is preparatory work to get rid of the local VAPictureH264 member in GstVaapiPictureH264. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 51 +++++++++++++++++++---- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index ef07381f39..c2f9602186 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2030,6 +2030,43 @@ vaapi_init_picture(VAPictureH264 *pic) pic->BottomFieldOrderCnt = 0; } +static void +vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture) +{ + const guint field_flags = (VA_PICTURE_H264_TOP_FIELD | + VA_PICTURE_H264_BOTTOM_FIELD); + + pic->picture_id = picture->base.surface_id; + pic->flags = 0; + + if (picture->info.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE) { + pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE; + pic->frame_idx = picture->info.frame_idx; + } + else { + if (picture->info.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) + pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE; + pic->frame_idx = picture->frame_num; + } + + switch (picture->info.flags & field_flags) { + case 0: + pic->TopFieldOrderCnt = picture->info.TopFieldOrderCnt; + pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt; + break; + case VA_PICTURE_H264_TOP_FIELD: + pic->flags |= VA_PICTURE_H264_TOP_FIELD; + pic->TopFieldOrderCnt = picture->info.BottomFieldOrderCnt; + pic->BottomFieldOrderCnt = 0; + break; + case VA_PICTURE_H264_BOTTOM_FIELD: + pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD; + pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt; + pic->TopFieldOrderCnt = 0; + break; + } +} + static gboolean fill_picture( GstVaapiDecoderH264 *decoder, @@ -2046,11 +2083,11 @@ fill_picture( guint i, n; /* Fill in VAPictureParameterBufferH264 */ - pic_param->CurrPic = picture->info; - for (i = 0, n = 0; i < priv->short_ref_count; i++) - pic_param->ReferenceFrames[n++] = priv->short_ref[i]->info; - for (i = 0; i < priv->long_ref_count; i++) - pic_param->ReferenceFrames[n++] = priv->long_ref[i]->info; + vaapi_fill_picture(&pic_param->CurrPic, picture); + for (i = 0, n = 0; i < priv->short_ref_count; i++, n++) + vaapi_fill_picture(&pic_param->ReferenceFrames[n], priv->short_ref[i]); + for (i = 0; i < priv->long_ref_count; i++, n++) + vaapi_fill_picture(&pic_param->ReferenceFrames[n], priv->long_ref[i]); for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++) vaapi_init_picture(&pic_param->ReferenceFrames[n]); @@ -2330,7 +2367,7 @@ fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) slice_hdr->num_ref_idx_l0_active_minus1; for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++) - slice_param->RefPicList0[i] = priv->RefPicList0[i]->info; + vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i]); for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++) vaapi_init_picture(&slice_param->RefPicList0[i]); @@ -2341,7 +2378,7 @@ fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) slice_hdr->num_ref_idx_l1_active_minus1; for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++) - slice_param->RefPicList1[i] = priv->RefPicList1[i]->info; + vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i]); for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++) vaapi_init_picture(&slice_param->RefPicList1[i]); return TRUE; From b35ccab29475687a585f150e5ffb34c39fff48d1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 31 Oct 2012 10:56:15 +0100 Subject: [PATCH 0883/3781] h264: fill in GstVaapiPicture structure. ... and get rid of local VAPictureH264.flags fields in GstVaapiPictureH264. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 117 +++++++++++----------- 1 file changed, 60 insertions(+), 57 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index c2f9602186..717eb42cfb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -87,8 +87,6 @@ struct _GstVaapiPictureH264 { gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum guint is_idr : 1; guint is_long_term : 1; - guint field_pic_flag : 1; - guint bottom_field_flag : 1; guint output_flag : 1; guint output_needed : 1; }; @@ -300,7 +298,7 @@ struct _GstVaapiDecoderH264Private { gint32 frame_num; // frame_num (from slice_header()) gint32 prev_frame_num; // prevFrameNum gboolean prev_pic_has_mmco5; // prevMmco5Pic - gboolean prev_pic_bottom_field; // Flag: previous picture is a bottom field + gboolean prev_pic_structure; // previous picture structure guint is_constructed : 1; guint is_opened : 1; guint is_avc : 1; @@ -890,6 +888,7 @@ init_picture_poc_0( GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); + gint32 temp_poc; GST_DEBUG("decode picture order count type 0"); @@ -899,8 +898,9 @@ init_picture_poc_0( } else if (priv->prev_pic_has_mmco5) { priv->prev_poc_msb = 0; - priv->prev_poc_lsb = priv->prev_pic_bottom_field ? 0 : - priv->field_poc[TOP_FIELD]; + priv->prev_poc_lsb = + (priv->prev_pic_structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD ? + 0 : priv->field_poc[TOP_FIELD]); } else { priv->prev_poc_msb = priv->poc_msb; @@ -918,16 +918,23 @@ init_picture_poc_0( else priv->poc_msb = priv->prev_poc_msb; - // (8-4) - if (!slice_hdr->field_pic_flag || !slice_hdr->bottom_field_flag) - priv->field_poc[TOP_FIELD] = priv->poc_msb + priv->poc_lsb; - - // (8-5) - if (!slice_hdr->field_pic_flag) - priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] + + temp_poc = priv->poc_msb + priv->poc_lsb; + switch (picture->base.structure) { + case GST_VAAPI_PICTURE_STRUCTURE_FRAME: + // (8-4, 8-5) + priv->field_poc[TOP_FIELD] = temp_poc; + priv->field_poc[BOTTOM_FIELD] = temp_poc + slice_hdr->delta_pic_order_cnt_bottom; - else if (slice_hdr->bottom_field_flag) - priv->field_poc[BOTTOM_FIELD] = priv->poc_msb + priv->poc_lsb; + break; + case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: + // (8-4) + priv->field_poc[TOP_FIELD] = temp_poc; + break; + case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: + // (8-5) + priv->field_poc[BOTTOM_FIELD] = temp_poc; + break; + } } /* 8.2.1.2 - Decoding process for picture order count type 1 */ @@ -993,19 +1000,24 @@ init_picture_poc_1( expected_poc += sps->offset_for_non_ref_pic; // (8-10) - if (!slice_hdr->field_pic_flag) { + switch (picture->base.structure) { + case GST_VAAPI_PICTURE_STRUCTURE_FRAME: priv->field_poc[TOP_FIELD] = expected_poc + slice_hdr->delta_pic_order_cnt[0]; priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] + sps->offset_for_top_to_bottom_field + slice_hdr->delta_pic_order_cnt[1]; - } - else if (!slice_hdr->bottom_field_flag) + break; + case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: priv->field_poc[TOP_FIELD] = expected_poc + slice_hdr->delta_pic_order_cnt[0]; - else + break; + case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: priv->field_poc[BOTTOM_FIELD] = expected_poc + - sps->offset_for_top_to_bottom_field + slice_hdr->delta_pic_order_cnt[0]; + sps->offset_for_top_to_bottom_field + + slice_hdr->delta_pic_order_cnt[0]; + break; + } } /* 8.2.1.3 - Decoding process for picture order count type 2 */ @@ -1046,14 +1058,10 @@ init_picture_poc_2( temp_poc = 2 * (priv->frame_num_offset + priv->frame_num); // (8-13) - if (!slice_hdr->field_pic_flag) { + if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) priv->field_poc[TOP_FIELD] = temp_poc; + if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) priv->field_poc[BOTTOM_FIELD] = temp_poc; - } - else if (slice_hdr->bottom_field_flag) - priv->field_poc[BOTTOM_FIELD] = temp_poc; - else - priv->field_poc[TOP_FIELD] = temp_poc; } /* 8.2.1 - Decoding process for picture order count */ @@ -1081,9 +1089,9 @@ init_picture_poc( break; } - if (!(pic->flags & VA_PICTURE_H264_BOTTOM_FIELD)) + if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) pic->TopFieldOrderCnt = priv->field_poc[TOP_FIELD]; - if (!(pic->flags & VA_PICTURE_H264_TOP_FIELD)) + if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) pic->BottomFieldOrderCnt = priv->field_poc[BOTTOM_FIELD]; picture->poc = MIN(pic->TopFieldOrderCnt, pic->BottomFieldOrderCnt); } @@ -1154,7 +1162,6 @@ init_picture_refs_pic_num( GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); - const guint field_flags = VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD; guint i; GST_DEBUG("decode picture numbers"); @@ -1169,10 +1176,10 @@ init_picture_refs_pic_num( pic->frame_num_wrap = pic->frame_num; // (8-28, 8-30, 8-31) - if (!pic->field_pic_flag) + if (GST_VAAPI_PICTURE_IS_FRAME(picture)) pic->pic_num = pic->frame_num_wrap; else { - if (((picture->info.flags ^ pic->info.flags) & field_flags) == 0) + if (pic->base.structure == picture->base.structure) pic->pic_num = 2 * pic->frame_num_wrap + 1; else pic->pic_num = 2 * pic->frame_num_wrap; @@ -1183,10 +1190,10 @@ init_picture_refs_pic_num( GstVaapiPictureH264 * const pic = priv->long_ref[i]; // (8-29, 8-32, 8-33) - if (!pic->field_pic_flag) + if (GST_VAAPI_PICTURE_IS_FRAME(picture)) pic->long_term_pic_num = pic->info.frame_idx; else { - if (((picture->info.flags ^ pic->info.flags) & field_flags) == 0) + if (pic->base.structure == picture->base.structure) pic->long_term_pic_num = 2 * pic->info.frame_idx + 1; else pic->long_term_pic_num = 2 * pic->info.frame_idx; @@ -1210,7 +1217,7 @@ init_picture_refs_p_slice( GST_DEBUG("decode reference picture list for P and SP slices"); - if (!picture->field_pic_flag) { + if (GST_VAAPI_PICTURE_IS_FRAME(picture)) { /* 8.2.4.2.1 - P and SP slices in frames */ if (priv->short_ref_count > 0) { ref_list = priv->RefPicList0; @@ -1270,7 +1277,7 @@ init_picture_refs_b_slice( GST_DEBUG("decode reference picture list for B slices"); - if (!picture->field_pic_flag) { + if (GST_VAAPI_PICTURE_IS_FRAME(picture)) { /* 8.2.4.2.3 - B slices in frames */ /* RefPicList0 */ @@ -1511,7 +1518,7 @@ exec_picture_refs_modification_1( } ref_list_count = *ref_list_count_ptr; - if (picture->field_pic_flag) { + if (!GST_VAAPI_PICTURE_IS_FRAME(picture)) { MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum CurrPicNum = 2 * slice_hdr->frame_num + 1; // 2 * frame_num + 1 } @@ -1689,8 +1696,6 @@ init_picture( picture->frame_num = priv->frame_num; picture->frame_num_wrap = priv->frame_num; picture->is_idr = nalu->type == GST_H264_NAL_SLICE_IDR; - picture->field_pic_flag = slice_hdr->field_pic_flag; - picture->bottom_field_flag = slice_hdr->bottom_field_flag; picture->output_flag = TRUE; /* XXX: conformant to Annex A only */ base_picture->pts = gst_adapter_prev_timestamp(priv->adapter, NULL); @@ -1705,14 +1710,8 @@ init_picture( pic = &picture->info; pic->picture_id = picture->base.surface_id; pic->frame_idx = priv->frame_num; - if (picture->field_pic_flag) { - if (picture->bottom_field_flag) - pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD; - else - pic->flags |= VA_PICTURE_H264_TOP_FIELD; - } - /* Initialize base picture */ + /* Initialize slice type */ switch (slice_hdr->type % 5) { case GST_H264_P_SLICE: base_picture->type = GST_VAAPI_PICTURE_TYPE_P; @@ -1731,6 +1730,14 @@ init_picture( break; } + /* Initialize picture structure */ + if (!slice_hdr->field_pic_flag) + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + else if (!slice_hdr->bottom_field_flag) + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + else + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + if (nalu->ref_idc) { GstH264DecRefPicMarking * const dec_ref_pic_marking = &slice_hdr->dec_ref_pic_marking; @@ -1792,7 +1799,7 @@ get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking) { gint32 pic_num; - if (!picture->field_pic_flag) + if (GST_VAAPI_PICTURE_IS_FRAME(picture)) pic_num = picture->frame_num_wrap; else pic_num = 2 * picture->frame_num_wrap + 1; @@ -1917,9 +1924,9 @@ exec_ref_pic_marking_adaptive_mmco_5( picture->frame_num = 0; /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */ - if (!(pic->flags & VA_PICTURE_H264_BOTTOM_FIELD)) + if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) pic->TopFieldOrderCnt -= picture->poc; - if (!(pic->flags & VA_PICTURE_H264_TOP_FIELD)) + if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) pic->BottomFieldOrderCnt -= picture->poc; picture->poc = 0; } @@ -1987,8 +1994,7 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) GstVaapiPictureH264 **picture_ptr; priv->prev_pic_has_mmco5 = FALSE; - priv->prev_pic_bottom_field = - picture->field_pic_flag && picture->bottom_field_flag; + priv->prev_pic_structure = picture->base.structure; if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) return TRUE; @@ -2033,9 +2039,6 @@ vaapi_init_picture(VAPictureH264 *pic) static void vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture) { - const guint field_flags = (VA_PICTURE_H264_TOP_FIELD | - VA_PICTURE_H264_BOTTOM_FIELD); - pic->picture_id = picture->base.surface_id; pic->flags = 0; @@ -2049,17 +2052,17 @@ vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture) pic->frame_idx = picture->frame_num; } - switch (picture->info.flags & field_flags) { - case 0: + switch (picture->base.structure) { + case GST_VAAPI_PICTURE_STRUCTURE_FRAME: pic->TopFieldOrderCnt = picture->info.TopFieldOrderCnt; pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt; break; - case VA_PICTURE_H264_TOP_FIELD: + case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: pic->flags |= VA_PICTURE_H264_TOP_FIELD; pic->TopFieldOrderCnt = picture->info.BottomFieldOrderCnt; pic->BottomFieldOrderCnt = 0; break; - case VA_PICTURE_H264_BOTTOM_FIELD: + case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD; pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt; pic->TopFieldOrderCnt = 0; @@ -2771,7 +2774,7 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->frame_num = 0; priv->prev_frame_num = 0; priv->prev_pic_has_mmco5 = FALSE; - priv->prev_pic_bottom_field = FALSE; + priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; priv->is_constructed = FALSE; priv->is_opened = FALSE; priv->is_avc = FALSE; From af22813f59cd6d0203cfeb409b446447bb68564e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 31 Oct 2012 11:33:40 +0100 Subject: [PATCH 0884/3781] h264: introduce GST_VAAPI_PICTURE_FLAG_IDR flag. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 36 +++++++++++++++-------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 717eb42cfb..b03b273c0b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -76,6 +76,18 @@ typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class; GST_VAAPI_TYPE_PICTURE_H264, \ GstVaapiPictureH264Class)) +/* + * Extended picture flags: + * + * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture + */ +enum { + GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0), +}; + +#define GST_VAAPI_PICTURE_IS_IDR(picture) \ + (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR)) + struct _GstVaapiPictureH264 { GstVaapiPicture base; VAPictureH264 info; @@ -85,7 +97,6 @@ struct _GstVaapiPictureH264 { gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap gint32 pic_num; // Temporary for ref pic marking: PicNum gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum - guint is_idr : 1; guint is_long_term : 1; guint output_flag : 1; guint output_needed : 1; @@ -126,7 +137,6 @@ gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture) picture->poc = 0; picture->is_long_term = FALSE; - picture->is_idr = FALSE; picture->output_needed = FALSE; } @@ -442,7 +452,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) guint i; // Remove all unused pictures - if (picture->is_idr) + if (GST_VAAPI_PICTURE_IS_IDR(picture)) dpb_flush(decoder); else { i = 0; @@ -892,7 +902,7 @@ init_picture_poc_0( GST_DEBUG("decode picture order count type 0"); - if (picture->is_idr) { + if (GST_VAAPI_PICTURE_IS_IDR(picture)) { priv->prev_poc_msb = 0; priv->prev_poc_lsb = 0; } @@ -960,7 +970,7 @@ init_picture_poc_1( prev_frame_num_offset = priv->frame_num_offset; // (8-6) - if (picture->is_idr) + if (GST_VAAPI_PICTURE_IS_IDR(picture)) priv->frame_num_offset = 0; else if (priv->prev_frame_num > priv->frame_num) priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum; @@ -1042,7 +1052,7 @@ init_picture_poc_2( prev_frame_num_offset = priv->frame_num_offset; // (8-11) - if (picture->is_idr) + if (GST_VAAPI_PICTURE_IS_IDR(picture)) priv->frame_num_offset = 0; else if (priv->prev_frame_num > priv->frame_num) priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum; @@ -1050,7 +1060,7 @@ init_picture_poc_2( priv->frame_num_offset = prev_frame_num_offset; // (8-12) - if (picture->is_idr) + if (GST_VAAPI_PICTURE_IS_IDR(picture)) temp_poc = 0; else if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1; @@ -1695,13 +1705,13 @@ init_picture( priv->frame_num = slice_hdr->frame_num; picture->frame_num = priv->frame_num; picture->frame_num_wrap = priv->frame_num; - picture->is_idr = nalu->type == GST_H264_NAL_SLICE_IDR; picture->output_flag = TRUE; /* XXX: conformant to Annex A only */ base_picture->pts = gst_adapter_prev_timestamp(priv->adapter, NULL); /* Reset decoder state for IDR pictures */ - if (picture->is_idr) { + if (nalu->type == GST_H264_NAL_SLICE_IDR) { GST_DEBUG(""); + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR); clear_references(decoder, priv->short_ref, &priv->short_ref_count); clear_references(decoder, priv->long_ref, &priv->long_ref_count ); } @@ -1742,7 +1752,7 @@ init_picture( GstH264DecRefPicMarking * const dec_ref_pic_marking = &slice_hdr->dec_ref_pic_marking; GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - if (picture->is_idr) { + if (GST_VAAPI_PICTURE_IS_IDR(picture)) { if (dec_ref_pic_marking->long_term_reference_flag) picture->is_long_term = TRUE; } @@ -1999,7 +2009,7 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) return TRUE; - if (!picture->is_idr) { + if (!GST_VAAPI_PICTURE_IS_IDR(picture)) { GstVaapiSliceH264 * const slice = gst_vaapi_picture_h264_get_last_slice(picture); GstH264DecRefPicMarking * const dec_ref_pic_marking = @@ -2209,11 +2219,11 @@ is_new_picture( } /* IdrPicFlag differs in value */ - CHECK_EXPR(((priv->current_picture->is_idr ^ + CHECK_EXPR(((GST_VAAPI_PICTURE_IS_IDR(priv->current_picture) ^ (nalu->type == GST_H264_NAL_SLICE_IDR)) == 0), "IdrPicFlag"); /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */ - if (priv->current_picture->is_idr) + if (GST_VAAPI_PICTURE_IS_IDR(priv->current_picture)) CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id); #undef CHECK_EXPR From 3c721e112348799b25d6812cee69c8833b02f8cc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 31 Oct 2012 11:45:14 +0100 Subject: [PATCH 0885/3781] h264: introduce GST_VAAPI_PICTURE_{SHORT,LONG}_TERM_REFERENCE flags. Further get rid of GstVaapiPictureH264-local VAPictureH264.flags for reference bits, thus simplifying the reference picture marking process to only track a single set of reference flags. Also introduce a new long_term_frame_idx member. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 100 ++++++++++++---------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index b03b273c0b..6bc058208e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -80,14 +80,38 @@ typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class; * Extended picture flags: * * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture + * @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies + * "used for short-term reference" + * @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies + * "used for long-term reference" + * @GST_VAAPI_PICTURE_FLAGS_REFERENCE: mask covering any kind of + * reference picture (short-term reference or long-term reference) */ enum { GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0), + + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = ( + GST_VAAPI_PICTURE_FLAG_REFERENCE), + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = ( + GST_VAAPI_PICTURE_FLAG_REFERENCE | (GST_VAAPI_PICTURE_FLAG_LAST << 1)), + GST_VAAPI_PICTURE_FLAGS_REFERENCE = ( + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE | + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE), }; #define GST_VAAPI_PICTURE_IS_IDR(picture) \ (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR)) +#define GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture) \ + ((GST_VAAPI_PICTURE_FLAGS(picture) & \ + GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \ + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE) + +#define GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture) \ + ((GST_VAAPI_PICTURE_FLAGS(picture) & \ + GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \ + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE) + struct _GstVaapiPictureH264 { GstVaapiPicture base; VAPictureH264 info; @@ -95,9 +119,9 @@ struct _GstVaapiPictureH264 { gint32 poc; gint32 frame_num; // Original frame_num from slice_header() gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap + gint32 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx gint32 pic_num; // Temporary for ref pic marking: PicNum gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum - guint is_long_term : 1; guint output_flag : 1; guint output_needed : 1; }; @@ -136,7 +160,6 @@ gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture) va_pic->BottomFieldOrderCnt = 0; picture->poc = 0; - picture->is_long_term = FALSE; picture->output_needed = FALSE; } @@ -1157,7 +1180,7 @@ compare_picture_long_term_frame_idx_inc(const void *a, const void *b) const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; - return picA->info.frame_idx - picB->info.frame_idx; + return picA->long_term_frame_idx - picB->long_term_frame_idx; } /* 8.2.4.1 - Decoding process for picture numbers */ @@ -1201,12 +1224,12 @@ init_picture_refs_pic_num( // (8-29, 8-32, 8-33) if (GST_VAAPI_PICTURE_IS_FRAME(picture)) - pic->long_term_pic_num = pic->info.frame_idx; + pic->long_term_pic_num = pic->long_term_frame_idx; else { if (pic->base.structure == picture->base.structure) - pic->long_term_pic_num = 2 * pic->info.frame_idx + 1; + pic->long_term_pic_num = 2 * pic->long_term_frame_idx + 1; else - pic->long_term_pic_num = 2 * pic->info.frame_idx; + pic->long_term_pic_num = 2 * pic->long_term_frame_idx; } } } @@ -1449,10 +1472,7 @@ remove_reference_at( g_return_val_if_fail(index < num_pictures, FALSE); picture = pictures[index]; - GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - picture->is_long_term = FALSE; - picture->info.flags &= ~(VA_PICTURE_H264_SHORT_TERM_REFERENCE | - VA_PICTURE_H264_LONG_TERM_REFERENCE); + GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); if (index != --num_pictures) gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]); @@ -1580,8 +1600,9 @@ exec_picture_refs_modification_1( gint32 PicNumF; if (!ref_list[j]) continue; - PicNumF = ref_list[j]->is_long_term ? - MaxPicNum : ref_list[j]->pic_num; + PicNumF = + GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(ref_list[j]) ? + ref_list[j]->pic_num : MaxPicNum; if (PicNumF != picNum) ref_list[n++] = ref_list[j]; } @@ -1601,7 +1622,8 @@ exec_picture_refs_modification_1( gint32 LongTermPicNumF; if (!ref_list[j]) continue; - LongTermPicNumF = ref_list[j]->is_long_term ? + LongTermPicNumF = + GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(ref_list[j]) ? ref_list[j]->long_term_pic_num : INT_MAX; if (LongTermPicNumF != l->value.long_term_pic_num) ref_list[n++] = ref_list[j]; @@ -1699,7 +1721,6 @@ init_picture( { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiPicture * const base_picture = &picture->base; - VAPictureH264 *pic; priv->prev_frame_num = priv->frame_num; priv->frame_num = slice_hdr->frame_num; @@ -1716,11 +1737,6 @@ init_picture( clear_references(decoder, priv->long_ref, &priv->long_ref_count ); } - /* Initialize VA picture info */ - pic = &picture->info; - pic->picture_id = picture->base.surface_id; - pic->frame_idx = priv->frame_num; - /* Initialize slice type */ switch (slice_hdr->type % 5) { case GST_H264_P_SLICE: @@ -1751,11 +1767,14 @@ init_picture( if (nalu->ref_idc) { GstH264DecRefPicMarking * const dec_ref_pic_marking = &slice_hdr->dec_ref_pic_marking; - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - if (GST_VAAPI_PICTURE_IS_IDR(picture)) { - if (dec_ref_pic_marking->long_term_reference_flag) - picture->is_long_term = TRUE; - } + + if (GST_VAAPI_PICTURE_IS_IDR(picture) && + dec_ref_pic_marking->long_term_reference_flag) + GST_VAAPI_PICTURE_FLAG_SET(picture, + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); + else + GST_VAAPI_PICTURE_FLAG_SET(picture, + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE); } init_picture_poc(decoder, picture, slice_hdr); @@ -1861,11 +1880,10 @@ exec_ref_pic_marking_adaptive_mmco_3( ) { GstVaapiDecoderH264Private * const priv = decoder->priv; - VAPictureH264 *pic; gint32 i, picNumX; for (i = 0; i < priv->long_ref_count; i++) { - if (priv->long_ref[i]->info.frame_idx == ref_pic_marking->long_term_frame_idx) + if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx) break; } if (i != priv->long_ref_count) @@ -1881,12 +1899,9 @@ exec_ref_pic_marking_adaptive_mmco_3( gst_vaapi_picture_replace(&priv->long_ref[priv->long_ref_count++], picture); gst_vaapi_picture_unref(picture); - picture->is_long_term = TRUE; - pic = &picture->info; - pic->frame_idx = ref_pic_marking->long_term_frame_idx; - pic->flags &= ~VA_PICTURE_H264_SHORT_TERM_REFERENCE; - pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE; - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; + GST_VAAPI_PICTURE_FLAG_SET(picture, + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); } /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx @@ -1904,7 +1919,7 @@ exec_ref_pic_marking_adaptive_mmco_4( long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1; for (i = 0; i < priv->long_ref_count; i++) { - if ((gint32)priv->long_ref[i]->info.frame_idx <= long_term_frame_idx) + if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx) continue; remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i); i--; @@ -1949,8 +1964,9 @@ exec_ref_pic_marking_adaptive_mmco_6( GstH264RefPicMarking *ref_pic_marking ) { - picture->is_long_term = TRUE; - picture->info.frame_idx = ref_pic_marking->long_term_frame_idx; + picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; + GST_VAAPI_PICTURE_FLAG_SET(picture, + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); } /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */ @@ -2024,14 +2040,10 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) } } - if (picture->is_long_term) { + if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) picture_ptr = &priv->long_ref[priv->long_ref_count++]; - picture->info.flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE; - } - else { + else picture_ptr = &priv->short_ref[priv->short_ref_count++]; - picture->info.flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE; - } gst_vaapi_picture_replace(picture_ptr, picture); return TRUE; } @@ -2052,12 +2064,12 @@ vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture) pic->picture_id = picture->base.surface_id; pic->flags = 0; - if (picture->info.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE) { + if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) { pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE; - pic->frame_idx = picture->info.frame_idx; + pic->frame_idx = picture->long_term_frame_idx; } else { - if (picture->info.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) + if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE; pic->frame_idx = picture->frame_num; } From 3480fcc8d76f928df264e92de9d1efe4a5193390 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 31 Oct 2012 11:52:03 +0100 Subject: [PATCH 0886/3781] h264: introduce per-field POC in GstVaapiPictureH264. Use the POC member available in the GstVaapiPicture base class and get rid of the dependency on the local VAPictureH264 TopFieldOrderCnt and BottomFieldOrderCnt. Rather, use a simple field_poc[] array initialized to INT_MAX, so that to simplify picture POC calculation for non frame pictures. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 67 ++++++++++------------- 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 6bc058208e..7c5f610a6d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -45,6 +45,10 @@ typedef struct _GstVaapiPictureH264Class GstVaapiPictureH264Class; typedef struct _GstVaapiSliceH264 GstVaapiSliceH264; typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class; +// Used for field_poc[] +#define TOP_FIELD 0 +#define BOTTOM_FIELD 1 + /* ------------------------------------------------------------------------- */ /* --- H.264 Pictures --- */ /* ------------------------------------------------------------------------- */ @@ -114,9 +118,8 @@ enum { struct _GstVaapiPictureH264 { GstVaapiPicture base; - VAPictureH264 info; GstH264PPS *pps; - gint32 poc; + gint32 field_poc[2]; gint32 frame_num; // Original frame_num from slice_header() gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap gint32 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx @@ -152,14 +155,8 @@ gst_vaapi_picture_h264_create( static void gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture) { - VAPictureH264 *va_pic; - - va_pic = &picture->info; - va_pic->flags = 0; - va_pic->TopFieldOrderCnt = 0; - va_pic->BottomFieldOrderCnt = 0; - - picture->poc = 0; + picture->field_poc[0] = G_MAXINT32; + picture->field_poc[1] = G_MAXINT32; picture->output_needed = FALSE; } @@ -291,10 +288,6 @@ G_DEFINE_TYPE(GstVaapiDecoderH264, GST_VAAPI_TYPE_DECODER_H264, \ GstVaapiDecoderH264Private)) -// Used for field_poc[] -#define TOP_FIELD 0 -#define BOTTOM_FIELD 1 - struct _GstVaapiDecoderH264Private { GstAdapter *adapter; GstH264NalParser *parser; @@ -448,7 +441,7 @@ dpb_bump(GstVaapiDecoderH264 *decoder) lowest_poc_index = i++; for (; i < priv->dpb_count; i++) { GstVaapiPictureH264 * const picture = priv->dpb[i]; - if (picture->output_needed && picture->poc < priv->dpb[lowest_poc_index]->poc) + if (picture->output_needed && picture->base.poc < priv->dpb[lowest_poc_index]->base.poc) lowest_poc_index = i; } @@ -507,7 +500,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) while (priv->dpb_count == priv->dpb_size) { for (i = 0; i < priv->dpb_count; i++) { if (priv->dpb[i]->output_needed && - priv->dpb[i]->poc < picture->poc) + priv->dpb[i]->base.poc < picture->base.poc) break; } if (i == priv->dpb_count) @@ -1106,7 +1099,6 @@ init_picture_poc( ) { GstVaapiDecoderH264Private * const priv = decoder->priv; - VAPictureH264 * const pic = &picture->info; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; @@ -1123,10 +1115,10 @@ init_picture_poc( } if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) - pic->TopFieldOrderCnt = priv->field_poc[TOP_FIELD]; + picture->field_poc[TOP_FIELD] = priv->field_poc[TOP_FIELD]; if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) - pic->BottomFieldOrderCnt = priv->field_poc[BOTTOM_FIELD]; - picture->poc = MIN(pic->TopFieldOrderCnt, pic->BottomFieldOrderCnt); + picture->field_poc[BOTTOM_FIELD] = priv->field_poc[BOTTOM_FIELD]; + picture->base.poc = MIN(picture->field_poc[0], picture->field_poc[1]); } static int @@ -1153,7 +1145,7 @@ compare_picture_poc_dec(const void *a, const void *b) const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; - return picB->poc - picA->poc; + return picB->base.poc - picA->base.poc; } static int @@ -1162,7 +1154,7 @@ compare_picture_poc_inc(const void *a, const void *b) const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; - return picA->poc - picB->poc; + return picA->base.poc - picB->base.poc; } static int @@ -1318,7 +1310,7 @@ init_picture_refs_b_slice( // 1. Short-term references ref_list = priv->RefPicList0; for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->poc < picture->poc) + if (priv->short_ref[i]->base.poc < picture->base.poc) ref_list[n++] = priv->short_ref[i]; } SORT_REF_LIST(ref_list, n, poc_dec); @@ -1326,7 +1318,7 @@ init_picture_refs_b_slice( ref_list = &priv->RefPicList0[priv->RefPicList0_count]; for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->poc >= picture->poc) + if (priv->short_ref[i]->base.poc >= picture->base.poc) ref_list[n++] = priv->short_ref[i]; } SORT_REF_LIST(ref_list, n, poc_inc); @@ -1347,7 +1339,7 @@ init_picture_refs_b_slice( // 1. Short-term references ref_list = priv->RefPicList1; for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->poc > picture->poc) + if (priv->short_ref[i]->base.poc > picture->base.poc) ref_list[n++] = priv->short_ref[i]; } SORT_REF_LIST(ref_list, n, poc_inc); @@ -1355,7 +1347,7 @@ init_picture_refs_b_slice( ref_list = &priv->RefPicList1[priv->RefPicList1_count]; for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->poc <= picture->poc) + if (priv->short_ref[i]->base.poc <= picture->base.poc) ref_list[n++] = priv->short_ref[i]; } SORT_REF_LIST(ref_list, n, poc_dec); @@ -1384,7 +1376,7 @@ init_picture_refs_b_slice( if (priv->short_ref_count > 0) { ref_list = short_ref0; for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->poc <= picture->poc) + if (priv->short_ref[i]->base.poc <= picture->base.poc) ref_list[n++] = priv->short_ref[i]; } SORT_REF_LIST(ref_list, n, poc_dec); @@ -1392,7 +1384,7 @@ init_picture_refs_b_slice( ref_list = &short_ref0[short_ref0_count]; for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->poc > picture->poc) + if (priv->short_ref[i]->base.poc > picture->base.poc) ref_list[n++] = priv->short_ref[i]; } SORT_REF_LIST(ref_list, n, poc_inc); @@ -1403,7 +1395,7 @@ init_picture_refs_b_slice( if (priv->short_ref_count > 0) { ref_list = short_ref1; for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->poc > picture->poc) + if (priv->short_ref[i]->base.poc > picture->base.poc) ref_list[n++] = priv->short_ref[i]; } SORT_REF_LIST(ref_list, n, poc_inc); @@ -1411,7 +1403,7 @@ init_picture_refs_b_slice( ref_list = &short_ref1[short_ref1_count]; for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->poc <= picture->poc) + if (priv->short_ref[i]->base.poc <= picture->base.poc) ref_list[n++] = priv->short_ref[i]; } SORT_REF_LIST(ref_list, n, poc_dec); @@ -1935,7 +1927,6 @@ exec_ref_pic_marking_adaptive_mmco_5( ) { GstVaapiDecoderH264Private * const priv = decoder->priv; - VAPictureH264 * const pic = &picture->info; clear_references(decoder, priv->short_ref, &priv->short_ref_count); clear_references(decoder, priv->long_ref, &priv->long_ref_count ); @@ -1950,10 +1941,10 @@ exec_ref_pic_marking_adaptive_mmco_5( /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */ if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) - pic->TopFieldOrderCnt -= picture->poc; + picture->field_poc[TOP_FIELD] -= picture->base.poc; if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) - pic->BottomFieldOrderCnt -= picture->poc; - picture->poc = 0; + picture->field_poc[BOTTOM_FIELD] -= picture->base.poc; + picture->base.poc = 0; } /* 8.2.5.4.6. Assign a long-term frame index to the current picture */ @@ -2076,17 +2067,17 @@ vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture) switch (picture->base.structure) { case GST_VAAPI_PICTURE_STRUCTURE_FRAME: - pic->TopFieldOrderCnt = picture->info.TopFieldOrderCnt; - pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt; + pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD]; + pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD]; break; case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: pic->flags |= VA_PICTURE_H264_TOP_FIELD; - pic->TopFieldOrderCnt = picture->info.BottomFieldOrderCnt; + pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD]; pic->BottomFieldOrderCnt = 0; break; case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD; - pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt; + pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD]; pic->TopFieldOrderCnt = 0; break; } From d180a3a9f60a6205c04a61495f857f0f31692247 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 31 Oct 2012 14:24:09 +0100 Subject: [PATCH 0887/3781] h264: simplify reference picture marking process. ... to build the short_ref[] and long_ref[] lists from the DPB, instead of maintaining them separately. This avoids refs/unrefs while making it possible to generate the list based on the actual picture structure. This also ensures that the list of generated ReferenceFrames[] actually matches what reference frames are available in the DPB. i.e. short_ref[] and long_ref[] entries are implied from the DPB, so there is no risk of having "dangling" references. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 113 +++++++++++----------- 1 file changed, 55 insertions(+), 58 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 7c5f610a6d..9b63f18206 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -304,9 +304,9 @@ struct _GstVaapiDecoderH264Private { GstVaapiProfile profile; GstVaapiEntrypoint entrypoint; GstVaapiChromaType chroma_type; - GstVaapiPictureH264 *short_ref[32]; + GstVaapiPictureH264 *short_ref[16]; guint short_ref_count; - GstVaapiPictureH264 *long_ref[32]; + GstVaapiPictureH264 *long_ref[16]; guint long_ref_count; GstVaapiPictureH264 *RefPicList0[32]; guint RefPicList0_count; @@ -332,14 +332,7 @@ struct _GstVaapiDecoderH264Private { }; static gboolean -decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture); - -static void -clear_references( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 **pictures, - guint *picture_count -); +exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture); /* Get number of reference frames to use */ static guint @@ -452,13 +445,22 @@ dpb_bump(GstVaapiDecoderH264 *decoder) } static void -dpb_flush(GstVaapiDecoderH264 *decoder) +dpb_clear(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = decoder->priv; + guint i; + for (i = 0; i < priv->dpb_count; i++) + gst_vaapi_picture_replace(&priv->dpb[i], NULL); + priv->dpb_count = 0; +} + +static void +dpb_flush(GstVaapiDecoderH264 *decoder) +{ while (dpb_bump(decoder)) ; - clear_references(decoder, priv->dpb, &priv->dpb_count); + dpb_clear(decoder); } static gboolean @@ -551,9 +553,8 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) GstVaapiDecoderH264Private * const priv = decoder->priv; gst_vaapi_picture_replace(&priv->current_picture, NULL); - clear_references(decoder, priv->short_ref, &priv->short_ref_count); - clear_references(decoder, priv->long_ref, &priv->long_ref_count ); - clear_references(decoder, priv->dpb, &priv->dpb_count ); + + dpb_clear(decoder); if (priv->parser) { gst_h264_nal_parser_free(priv->parser); @@ -822,7 +823,9 @@ decode_current_picture(GstVaapiDecoderH264 *decoder) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - if (!decode_picture_end(decoder, picture)) + if (!exec_ref_pic_marking(decoder, picture)) + goto error; + if (!dpb_add(decoder, picture)) goto error; if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture))) goto error; @@ -1435,21 +1438,6 @@ init_picture_refs_b_slice( #undef SORT_REF_LIST -static void -clear_references( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 **pictures, - guint *picture_count -) -{ - const guint num_pictures = *picture_count; - guint i; - - for (i = 0; i < num_pictures; i++) - gst_vaapi_picture_replace(&pictures[i], NULL); - *picture_count = 0; -} - static gboolean remove_reference_at( GstVaapiDecoderH264 *decoder, @@ -1467,8 +1455,8 @@ remove_reference_at( GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); if (index != --num_pictures) - gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]); - gst_vaapi_picture_replace(&pictures[num_pictures], NULL); + pictures[index] = pictures[num_pictures]; + pictures[num_pictures] = NULL; *picture_count = num_pictures; return TRUE; } @@ -1652,6 +1640,32 @@ exec_picture_refs_modification( exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1); } +static void +init_picture_ref_lists(GstVaapiDecoderH264 *decoder) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + guint i, short_ref_count, long_ref_count; + + short_ref_count = 0; + long_ref_count = 0; + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiPictureH264 * const picture = priv->dpb[i]; + + if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) + priv->short_ref[short_ref_count++] = picture; + else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) + priv->long_ref[long_ref_count++] = picture; + } + + for (i = short_ref_count; i < priv->short_ref_count; i++) + priv->short_ref[i] = NULL; + priv->short_ref_count = short_ref_count; + + for (i = long_ref_count; i < priv->long_ref_count; i++) + priv->long_ref[i] = NULL; + priv->long_ref_count = long_ref_count; +} + static gboolean init_picture_refs( GstVaapiDecoderH264 *decoder, @@ -1663,6 +1677,7 @@ init_picture_refs( GstVaapiPicture * const base_picture = &picture->base; guint i, num_refs; + init_picture_ref_lists(decoder); init_picture_refs_pic_num(decoder, picture, slice_hdr); priv->RefPicList0_count = 0; @@ -1725,8 +1740,6 @@ init_picture( if (nalu->type == GST_H264_NAL_SLICE_IDR) { GST_DEBUG(""); GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR); - clear_references(decoder, priv->short_ref, &priv->short_ref_count); - clear_references(decoder, priv->long_ref, &priv->long_ref_count ); } /* Initialize slice type */ @@ -1770,6 +1783,10 @@ init_picture( } init_picture_poc(decoder, picture, slice_hdr); + + if (GST_VAAPI_PICTURE_IS_IDR(picture)) + dpb_flush(decoder); + if (!init_picture_refs(decoder, picture, slice_hdr)) { GST_ERROR("failed to initialize references"); return FALSE; @@ -1828,7 +1845,7 @@ get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking) return pic_num; } -/* 8.2.5.4.1. Mark-term reference picture as "unused for reference" */ +/* 8.2.5.4.1. Mark short-term reference picture as "unused for reference" */ static void exec_ref_pic_marking_adaptive_mmco_1( GstVaapiDecoderH264 *decoder, @@ -1886,10 +1903,9 @@ exec_ref_pic_marking_adaptive_mmco_3( if (i < 0) return; - picture = gst_vaapi_picture_ref(priv->short_ref[i]); + picture = priv->short_ref[i]; remove_reference_at(decoder, priv->short_ref, &priv->short_ref_count, i); - gst_vaapi_picture_replace(&priv->long_ref[priv->long_ref_count++], picture); - gst_vaapi_picture_unref(picture); + priv->long_ref[priv->long_ref_count++] = picture; picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; GST_VAAPI_PICTURE_FLAG_SET(picture, @@ -1928,8 +1944,6 @@ exec_ref_pic_marking_adaptive_mmco_5( { GstVaapiDecoderH264Private * const priv = decoder->priv; - clear_references(decoder, priv->short_ref, &priv->short_ref_count); - clear_references(decoder, priv->long_ref, &priv->long_ref_count ); dpb_flush(decoder); priv->prev_pic_has_mmco5 = TRUE; @@ -2008,7 +2022,6 @@ static gboolean exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstVaapiPictureH264 **picture_ptr; priv->prev_pic_has_mmco5 = FALSE; priv->prev_pic_structure = picture->base.structure; @@ -2030,12 +2043,6 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return FALSE; } } - - if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) - picture_ptr = &priv->long_ref[priv->long_ref_count++]; - else - picture_ptr = &priv->short_ref[priv->short_ref_count++]; - gst_vaapi_picture_replace(picture_ptr, picture); return TRUE; } @@ -2273,16 +2280,6 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceH return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static gboolean -decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) -{ - if (!exec_ref_pic_marking(decoder, picture)) - return FALSE; - if (!dpb_add(decoder, picture)) - return FALSE; - return TRUE; -} - static inline guint get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, GstH264NalUnit *nalu) { From afddf11e22c485a29d05e78448d8204581d77d8c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 31 Oct 2012 16:37:14 +0100 Subject: [PATCH 0888/3781] h264: minor clean-ups. Move DPB flush up if the current picture to decode is an IDR. Besides, don't bother to check for IDR pictures in dpb_add() function since an explicit DPB flush was already performed in this case. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 9b63f18206..fcc671ab94 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -470,9 +470,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) guint i; // Remove all unused pictures - if (GST_VAAPI_PICTURE_IS_IDR(picture)) - dpb_flush(decoder); - else { + if (!GST_VAAPI_PICTURE_IS_IDR(picture)) { i = 0; while (i < priv->dpb_count) { GstVaapiPictureH264 * const picture = priv->dpb[i]; @@ -1666,7 +1664,7 @@ init_picture_ref_lists(GstVaapiDecoderH264 *decoder) priv->long_ref_count = long_ref_count; } -static gboolean +static void init_picture_refs( GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, @@ -1715,7 +1713,6 @@ init_picture_refs( default: break; } - return TRUE; } static gboolean @@ -1740,6 +1737,7 @@ init_picture( if (nalu->type == GST_H264_NAL_SLICE_IDR) { GST_DEBUG(""); GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR); + dpb_flush(decoder); } /* Initialize slice type */ @@ -1769,6 +1767,7 @@ init_picture( else base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + /* Initialize reference flags */ if (nalu->ref_idc) { GstH264DecRefPicMarking * const dec_ref_pic_marking = &slice_hdr->dec_ref_pic_marking; @@ -1783,14 +1782,7 @@ init_picture( } init_picture_poc(decoder, picture, slice_hdr); - - if (GST_VAAPI_PICTURE_IS_IDR(picture)) - dpb_flush(decoder); - - if (!init_picture_refs(decoder, picture, slice_hdr)) { - GST_ERROR("failed to initialize references"); - return FALSE; - } + init_picture_refs(decoder, picture, slice_hdr); return TRUE; } From d4532978862d9733c9987b7305015cfea21dfbe4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 13 Nov 2012 10:10:31 +0100 Subject: [PATCH 0889/3781] codecparsers: update to gst-vaapi-rebased commit 73d6aab. 73d6aab h264: fix rbsp_more_data() implementation 25d04cf h264: fix error code for invalid size parsed in SPS 84798e5 fix FSF address --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 70dfc67bc6..73d6aab46c 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 70dfc67bc6953363a4273bbd0381f09433cea36f +Subproject commit 73d6aab46c14d943f2a0238e70812d775f06ffee From bbbf3741ffac4efdb2d9ffd1df4733b8838f5823 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 2 Nov 2012 15:14:58 +0100 Subject: [PATCH 0890/3781] h264: introduce new frame store structure. The frame store represents a Decoded Picture Buffer entry, which can hold up to two fields. So far, the frame store is only used to hold full frames. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 260 ++++++++++++++++++---- 1 file changed, 215 insertions(+), 45 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index fcc671ab94..34eccdf214 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -40,6 +40,8 @@ /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */ #define USE_STRICT_DPB_ORDERING 0 +typedef struct _GstVaapiFrameStore GstVaapiFrameStore; +typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; typedef struct _GstVaapiPictureH264Class GstVaapiPictureH264Class; typedef struct _GstVaapiSliceH264 GstVaapiSliceH264; @@ -275,6 +277,134 @@ gst_vaapi_slice_h264_new( return GST_VAAPI_SLICE_H264_CAST(object); } +/* ------------------------------------------------------------------------- */ +/* --- Frame Buffers (DPB) --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_TYPE_FRAME_STORE \ + (gst_vaapi_frame_store_get_type()) + +#define GST_VAAPI_FRAME_STORE_CAST(obj) \ + ((GstVaapiFrameStore *)(obj)) + +#define GST_VAAPI_FRAME_STORE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_FRAME_STORE, \ + GstVaapiFrameStore)) + +#define GST_VAAPI_FRAME_STORE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_FRAME_STORE, \ + GstVaapiFrameStoreClass)) + +#define GST_VAAPI_IS_FRAME_STORE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_FRAME_STORE)) + +#define GST_VAAPI_IS_FRAME_STORE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_FRAME_STORE)) + +#define GST_VAAPI_FRAME_STORE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_FRAME_STORE, \ + GstVaapiFrameStoreClass)) + +struct _GstVaapiFrameStore { + /*< private >*/ + GstMiniObject parent_instance; + + guint structure; + GstVaapiPictureH264 *buffers[2]; + guint num_buffers; + guint output_needed; +}; + +struct _GstVaapiFrameStoreClass { + /*< private >*/ + GstMiniObjectClass parent_class; +}; + +G_DEFINE_TYPE(GstVaapiFrameStore, gst_vaapi_frame_store, GST_TYPE_MINI_OBJECT) + +static void +gst_vaapi_frame_store_finalize(GstMiniObject *object) +{ + GstVaapiFrameStore * const fs = GST_VAAPI_FRAME_STORE_CAST(object); + GstMiniObjectClass *parent_class; + guint i; + + for (i = 0; i < fs->num_buffers; i++) + gst_vaapi_picture_replace(&fs->buffers[i], NULL); + + parent_class = GST_MINI_OBJECT_CLASS(gst_vaapi_frame_store_parent_class); + if (parent_class->finalize) + parent_class->finalize(object); +} + +static void +gst_vaapi_frame_store_init(GstVaapiFrameStore *fs) +{ +} + +static void +gst_vaapi_frame_store_class_init(GstVaapiFrameStoreClass *klass) +{ + GstMiniObjectClass * const object_class = GST_MINI_OBJECT_CLASS(klass); + + object_class->finalize = gst_vaapi_frame_store_finalize; +} + +static inline gpointer +_gst_vaapi_frame_store_new(void) +{ + return gst_mini_object_new(GST_VAAPI_TYPE_FRAME_STORE); +} + +static GstVaapiFrameStore * +gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture) +{ + GstVaapiFrameStore *fs; + + g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL); + + fs = _gst_vaapi_frame_store_new(); + if (!fs) + return NULL; + + fs->structure = picture->base.structure; + fs->buffers[0] = gst_vaapi_picture_ref(picture); + fs->num_buffers = 1; + fs->output_needed = picture->output_needed; + return fs; +} + +static inline gboolean +gst_vaapi_frame_store_has_frame(GstVaapiFrameStore *fs) +{ + return fs->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME; +} + +static inline gboolean +gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs) +{ + guint i; + + for (i = 0; i < fs->num_buffers; i++) { + if (GST_VAAPI_PICTURE_IS_REFERENCE(fs->buffers[i])) + return TRUE; + } + return FALSE; +} + +#define gst_vaapi_frame_store_ref(fs) \ + gst_mini_object_ref(GST_MINI_OBJECT(fs)) + +#define gst_vaapi_frame_store_unref(fs) \ + gst_mini_object_unref(GST_MINI_OBJECT(fs)) + +#define gst_vaapi_frame_store_replace(old_fs_p, new_fs) \ + gst_mini_object_replace((GstMiniObject **)(old_fs_p), \ + (GstMiniObject *)(new_fs)) + /* ------------------------------------------------------------------------- */ /* --- H.264 Decoder --- */ /* ------------------------------------------------------------------------- */ @@ -298,7 +428,8 @@ struct _GstVaapiDecoderH264Private { it may not fit stack memory allocation in decode_pps() */ GstH264PPS last_pps; GstVaapiPictureH264 *current_picture; - GstVaapiPictureH264 *dpb[16]; + GstVaapiFrameStore *prev_frame; + GstVaapiFrameStore *dpb[16]; guint dpb_count; guint dpb_size; GstVaapiProfile profile; @@ -398,49 +529,67 @@ static void dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index) { GstVaapiDecoderH264Private * const priv = decoder->priv; - guint i, num_pictures = --priv->dpb_count; + guint i, num_frames = --priv->dpb_count; if (USE_STRICT_DPB_ORDERING) { - for (i = index; i < num_pictures; i++) - gst_vaapi_picture_replace(&priv->dpb[i], priv->dpb[i + 1]); + for (i = index; i < num_frames; i++) + gst_vaapi_frame_store_replace(&priv->dpb[i], priv->dpb[i + 1]); } - else if (index != num_pictures) - gst_vaapi_picture_replace(&priv->dpb[index], priv->dpb[num_pictures]); - gst_vaapi_picture_replace(&priv->dpb[num_pictures], NULL); + else if (index != num_frames) + gst_vaapi_frame_store_replace(&priv->dpb[index], priv->dpb[num_frames]); + gst_vaapi_frame_store_replace(&priv->dpb[num_frames], NULL); } -static inline gboolean -dpb_output(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +static gboolean +dpb_output( + GstVaapiDecoderH264 *decoder, + GstVaapiFrameStore *fs, + GstVaapiPictureH264 *picture +) { - /* XXX: update cropping rectangle */ picture->output_needed = FALSE; + + if (fs) + fs->output_needed--; + + /* XXX: update cropping rectangle */ return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture)); } +static inline void +dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i) +{ + GstVaapiFrameStore * const fs = decoder->priv->dpb[i]; + + if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs)) + dpb_remove_index(decoder, i); +} + static gboolean dpb_bump(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = decoder->priv; - guint i, lowest_poc_index; + GstVaapiPictureH264 *found_picture = NULL; + guint i, j, found_index; gboolean success; for (i = 0; i < priv->dpb_count; i++) { - if (priv->dpb[i]->output_needed) - break; + GstVaapiFrameStore * const fs = priv->dpb[i]; + if (!fs->output_needed) + continue; + for (j = 0; j < fs->num_buffers; j++) { + GstVaapiPictureH264 * const picture = fs->buffers[j]; + if (!picture->output_needed) + continue; + if (!found_picture || found_picture->base.poc > picture->base.poc) + found_picture = picture, found_index = i; + } } - if (i == priv->dpb_count) + if (!found_picture) return FALSE; - lowest_poc_index = i++; - for (; i < priv->dpb_count; i++) { - GstVaapiPictureH264 * const picture = priv->dpb[i]; - if (picture->output_needed && picture->base.poc < priv->dpb[lowest_poc_index]->base.poc) - lowest_poc_index = i; - } - - success = dpb_output(decoder, priv->dpb[lowest_poc_index]); - if (!GST_VAAPI_PICTURE_IS_REFERENCE(priv->dpb[lowest_poc_index])) - dpb_remove_index(decoder, lowest_poc_index); + success = dpb_output(decoder, priv->dpb[found_index], found_picture); + dpb_evict(decoder, found_picture, found_index); return success; } @@ -451,8 +600,10 @@ dpb_clear(GstVaapiDecoderH264 *decoder) guint i; for (i = 0; i < priv->dpb_count; i++) - gst_vaapi_picture_replace(&priv->dpb[i], NULL); + gst_vaapi_frame_store_replace(&priv->dpb[i], NULL); priv->dpb_count = 0; + + gst_vaapi_frame_store_replace(&priv->prev_frame, NULL); } static void @@ -467,30 +618,39 @@ static gboolean dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { GstVaapiDecoderH264Private * const priv = decoder->priv; - guint i; + GstVaapiFrameStore *fs; + guint i, j; // Remove all unused pictures if (!GST_VAAPI_PICTURE_IS_IDR(picture)) { i = 0; while (i < priv->dpb_count) { - GstVaapiPictureH264 * const picture = priv->dpb[i]; - if (!picture->output_needed && - !GST_VAAPI_PICTURE_IS_REFERENCE(picture)) + GstVaapiFrameStore * const fs = priv->dpb[i]; + if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs)) dpb_remove_index(decoder, i); else i++; } } + // Create new frame store + fs = gst_vaapi_frame_store_new(picture); + if (!fs) + return FALSE; + gst_vaapi_frame_store_replace(&priv->prev_frame, fs); + gst_vaapi_frame_store_unref(fs); + // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { while (priv->dpb_count == priv->dpb_size) { if (!dpb_bump(decoder)) return FALSE; } - gst_vaapi_picture_replace(&priv->dpb[priv->dpb_count++], picture); - if (picture->output_flag) + gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs); + if (picture->output_flag) { picture->output_needed = TRUE; + fs->output_needed++; + } } // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB @@ -498,18 +658,23 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (!picture->output_flag) return TRUE; while (priv->dpb_count == priv->dpb_size) { - for (i = 0; i < priv->dpb_count; i++) { - if (priv->dpb[i]->output_needed && - priv->dpb[i]->base.poc < picture->base.poc) - break; + gboolean found_picture = FALSE; + for (i = 0; !found_picture && i < priv->dpb_count; i++) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + if (!fs->output_needed) + continue; + for (j = 0; !found_picture && j < fs->num_buffers; j++) + found_picture = fs->buffers[j]->output_needed && + fs->buffers[j]->base.poc < picture->base.poc; } - if (i == priv->dpb_count) - return dpb_output(decoder, picture); + if (!found_picture) + return dpb_output(decoder, NULL, picture); if (!dpb_bump(decoder)) return FALSE; } - gst_vaapi_picture_replace(&priv->dpb[priv->dpb_count++], picture); + gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs); picture->output_needed = TRUE; + fs->output_needed++; } return TRUE; } @@ -1646,13 +1811,18 @@ init_picture_ref_lists(GstVaapiDecoderH264 *decoder) short_ref_count = 0; long_ref_count = 0; - for (i = 0; i < priv->dpb_count; i++) { - GstVaapiPictureH264 * const picture = priv->dpb[i]; - - if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) - priv->short_ref[short_ref_count++] = picture; - else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) - priv->long_ref[long_ref_count++] = picture; + if (GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) { + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + GstVaapiPictureH264 *picture; + if (!gst_vaapi_frame_store_has_frame(fs)) + continue; + picture = fs->buffers[0]; + if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) + priv->short_ref[short_ref_count++] = picture; + else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) + priv->long_ref[long_ref_count++] = picture; + } } for (i = short_ref_count; i < priv->short_ref_count; i++) From e530c5774149e68acc8e50b4b74c83968897a34a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 13 Nov 2012 14:04:31 +0100 Subject: [PATCH 0891/3781] h264: add picture structure for reference picture marking process. Introduce new `structure' field to the H.264 specific picture structure so that to simplify the reference picture marking process. That local picture structure is derived from the original picture structure, as defined by the syntax elements field_pic_flag and bottom_field_flag. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 29 +++++++++++++---------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 34eccdf214..de9e035a5f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -121,6 +121,7 @@ enum { struct _GstVaapiPictureH264 { GstVaapiPicture base; GstH264PPS *pps; + guint structure; gint32 field_poc[2]; gint32 frame_num; // Original frame_num from slice_header() gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap @@ -370,7 +371,7 @@ gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture) if (!fs) return NULL; - fs->structure = picture->base.structure; + fs->structure = picture->structure; fs->buffers[0] = gst_vaapi_picture_ref(picture); fs->num_buffers = 1; fs->output_needed = picture->output_needed; @@ -1111,7 +1112,7 @@ init_picture_poc_0( priv->poc_msb = priv->prev_poc_msb; temp_poc = priv->poc_msb + priv->poc_lsb; - switch (picture->base.structure) { + switch (picture->structure) { case GST_VAAPI_PICTURE_STRUCTURE_FRAME: // (8-4, 8-5) priv->field_poc[TOP_FIELD] = temp_poc; @@ -1192,7 +1193,7 @@ init_picture_poc_1( expected_poc += sps->offset_for_non_ref_pic; // (8-10) - switch (picture->base.structure) { + switch (picture->structure) { case GST_VAAPI_PICTURE_STRUCTURE_FRAME: priv->field_poc[TOP_FIELD] = expected_poc + slice_hdr->delta_pic_order_cnt[0]; @@ -1250,9 +1251,9 @@ init_picture_poc_2( temp_poc = 2 * (priv->frame_num_offset + priv->frame_num); // (8-13) - if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) priv->field_poc[TOP_FIELD] = temp_poc; - if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) priv->field_poc[BOTTOM_FIELD] = temp_poc; } @@ -1280,9 +1281,9 @@ init_picture_poc( break; } - if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) picture->field_poc[TOP_FIELD] = priv->field_poc[TOP_FIELD]; - if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) picture->field_poc[BOTTOM_FIELD] = priv->field_poc[BOTTOM_FIELD]; picture->base.poc = MIN(picture->field_poc[0], picture->field_poc[1]); } @@ -1370,7 +1371,7 @@ init_picture_refs_pic_num( if (GST_VAAPI_PICTURE_IS_FRAME(picture)) pic->pic_num = pic->frame_num_wrap; else { - if (pic->base.structure == picture->base.structure) + if (pic->structure == picture->structure) pic->pic_num = 2 * pic->frame_num_wrap + 1; else pic->pic_num = 2 * pic->frame_num_wrap; @@ -1384,7 +1385,7 @@ init_picture_refs_pic_num( if (GST_VAAPI_PICTURE_IS_FRAME(picture)) pic->long_term_pic_num = pic->long_term_frame_idx; else { - if (pic->base.structure == picture->base.structure) + if (pic->structure == picture->structure) pic->long_term_pic_num = 2 * pic->long_term_frame_idx + 1; else pic->long_term_pic_num = 2 * pic->long_term_frame_idx; @@ -1822,6 +1823,7 @@ init_picture_ref_lists(GstVaapiDecoderH264 *decoder) priv->short_ref[short_ref_count++] = picture; else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) priv->long_ref[long_ref_count++] = picture; + picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; } } @@ -1936,6 +1938,7 @@ init_picture( base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; else base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + picture->structure = base_picture->structure; /* Initialize reference flags */ if (nalu->ref_idc) { @@ -2116,9 +2119,9 @@ exec_ref_pic_marking_adaptive_mmco_5( picture->frame_num = 0; /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */ - if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) picture->field_poc[TOP_FIELD] -= picture->base.poc; - if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) picture->field_poc[BOTTOM_FIELD] -= picture->base.poc; picture->base.poc = 0; } @@ -2186,7 +2189,7 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) GstVaapiDecoderH264Private * const priv = decoder->priv; priv->prev_pic_has_mmco5 = FALSE; - priv->prev_pic_structure = picture->base.structure; + priv->prev_pic_structure = picture->structure; if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) return TRUE; @@ -2234,7 +2237,7 @@ vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture) pic->frame_idx = picture->frame_num; } - switch (picture->base.structure) { + switch (picture->structure) { case GST_VAAPI_PICTURE_STRUCTURE_FRAME: pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD]; pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD]; From e11f815b0d0c5b6c77550ae016a1989e58a35b4b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 23 Oct 2012 14:04:22 +0200 Subject: [PATCH 0892/3781] decoder: fix gst_vaapi_picture_new_field() object type. Fix gst_vaapi_picture_new_field() to preserve the original picture type. e.g. gst_vaapi_picture_new_field() with a GstVaapiPictureH264 argument shall generate a GstVaapiPictureH264 object. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 5f90fb0268..06cdc9a418 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -215,13 +215,15 @@ gst_vaapi_picture_new( GstVaapiPicture * gst_vaapi_picture_new_field(GstVaapiPicture *picture) { + GType type; GstMiniObject *obj; GstVaapiCodecObject *va_obj; GstVaapiCodecObjectConstructorArgs args; g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), NULL); - obj = gst_mini_object_new(GST_VAAPI_TYPE_PICTURE); + type = G_TYPE_FROM_CLASS(GST_VAAPI_PICTURE_GET_CLASS(picture)); + obj = gst_mini_object_new(type); if (!obj) return NULL; From c59d9355058914d10acde5071e4ecbd604dba154 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 13 Nov 2012 16:35:30 +0100 Subject: [PATCH 0893/3781] h264: split remove_reference_at() into finer units. Split remove_reference_at() into a function that actually removes the specified entry from the short-term or long-term reference picture array, and a function that sets reference flags to the desired value, possibly zero. The latters marks the picture as "unused for reference". --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 128 ++++++++++++++-------- 1 file changed, 80 insertions(+), 48 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index de9e035a5f..1b3e4f3ea7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -181,6 +181,18 @@ gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder) return GST_VAAPI_PICTURE_H264_CAST(object); } +static inline void +gst_vaapi_picture_h264_set_reference( + GstVaapiPictureH264 *picture, + guint reference_flags +) +{ + g_return_if_fail(GST_VAAPI_IS_PICTURE_H264(picture)); + + GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); + GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags); +} + static inline GstVaapiSliceH264 * gst_vaapi_picture_h264_get_last_slice(GstVaapiPictureH264 *picture) { @@ -526,6 +538,46 @@ get_max_dec_frame_buffering(GstH264SPS *sps) return MAX(1, max_dec_frame_buffering); } +static void +array_remove_index_fast(void *array, guint *array_length_ptr, guint index) +{ + gpointer * const entries = array; + guint num_entries = *array_length_ptr; + + g_return_if_fail(index < num_entries); + + if (index != --num_entries) + entries[index] = entries[num_entries]; + entries[num_entries] = NULL; + *array_length_ptr = num_entries; +} + +#if 1 +static inline void +array_remove_index(void *array, guint *array_length_ptr, guint index) +{ + array_remove_index_fast(array, array_length_ptr, index); +} +#else +static void +array_remove_index(void *array, guint *array_length_ptr, guint index) +{ + gpointer * const entries = array; + const guint num_entries = *array_length_ptr - 1; + guint i; + + g_return_if_fail(index <= num_entries); + + for (i = index; i < num_entries; i++) + entries[i] = entries[i + 1]; + entries[num_entries] = NULL; + *array_length_ptr = num_entries; +} +#endif + +#define ARRAY_REMOVE_INDEX(array, index) \ + array_remove_index(array, &array##_count, index) + static void dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index) { @@ -1602,29 +1654,6 @@ init_picture_refs_b_slice( #undef SORT_REF_LIST -static gboolean -remove_reference_at( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 **pictures, - guint *picture_count, - guint index -) -{ - guint num_pictures = *picture_count; - GstVaapiPictureH264 *picture; - - g_return_val_if_fail(index < num_pictures, FALSE); - - picture = pictures[index]; - GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); - - if (index != --num_pictures) - pictures[index] = pictures[num_pictures]; - pictures[num_pictures] = NULL; - *picture_count = num_pictures; - return TRUE; -} - static gint find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num) { @@ -1966,8 +1995,8 @@ exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) GstVaapiDecoderH264Private * const priv = decoder->priv; GstH264PPS * const pps = priv->current_picture->pps; GstH264SPS * const sps = pps->sequence; - guint i, max_num_ref_frames, lowest_frame_num_index; - gint32 lowest_frame_num; + GstVaapiPictureH264 *ref_picture; + guint i, m, max_num_ref_frames; GST_DEBUG("reference picture marking process (sliding window)"); @@ -1980,20 +2009,15 @@ exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) if (priv->short_ref_count < 1) return FALSE; - lowest_frame_num = priv->short_ref[0]->frame_num_wrap; - lowest_frame_num_index = 0; - for (i = 1; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->frame_num_wrap < lowest_frame_num) { - lowest_frame_num = priv->short_ref[i]->frame_num_wrap; - lowest_frame_num_index = i; - } + for (m = 0, i = 1; i < priv->short_ref_count; i++) { + GstVaapiPictureH264 * const picture = priv->short_ref[i]; + if (picture->frame_num_wrap < priv->short_ref[m]->frame_num_wrap) + m = i; } - remove_reference_at( - decoder, - priv->short_ref, &priv->short_ref_count, - lowest_frame_num_index - ); + ref_picture = priv->short_ref[m]; + gst_vaapi_picture_h264_set_reference(ref_picture, 0); + ARRAY_REMOVE_INDEX(priv->short_ref, m); return TRUE; } @@ -2025,7 +2049,9 @@ exec_ref_pic_marking_adaptive_mmco_1( i = find_short_term_reference(decoder, picNumX); if (i < 0) return; - remove_reference_at(decoder, priv->short_ref, &priv->short_ref_count, i); + + gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0); + ARRAY_REMOVE_INDEX(priv->short_ref, i); } /* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */ @@ -2042,7 +2068,9 @@ exec_ref_pic_marking_adaptive_mmco_2( i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num); if (i < 0) return; - remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i); + + gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0); + ARRAY_REMOVE_INDEX(priv->long_ref, i); } /* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */ @@ -2054,26 +2082,29 @@ exec_ref_pic_marking_adaptive_mmco_3( ) { GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiPictureH264 *ref_picture; gint32 i, picNumX; for (i = 0; i < priv->long_ref_count; i++) { if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx) break; } - if (i != priv->long_ref_count) - remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i); + if (i != priv->long_ref_count) { + gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0); + ARRAY_REMOVE_INDEX(priv->long_ref, i); + } picNumX = get_picNumX(picture, ref_pic_marking); i = find_short_term_reference(decoder, picNumX); if (i < 0) return; - picture = priv->short_ref[i]; - remove_reference_at(decoder, priv->short_ref, &priv->short_ref_count, i); - priv->long_ref[priv->long_ref_count++] = picture; + ref_picture = priv->short_ref[i]; + ARRAY_REMOVE_INDEX(priv->short_ref, i); + priv->long_ref[priv->long_ref_count++] = ref_picture; - picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; - GST_VAAPI_PICTURE_FLAG_SET(picture, + ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; + gst_vaapi_picture_h264_set_reference(ref_picture, GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); } @@ -2094,7 +2125,8 @@ exec_ref_pic_marking_adaptive_mmco_4( for (i = 0; i < priv->long_ref_count; i++) { if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx) continue; - remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i); + gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0); + ARRAY_REMOVE_INDEX(priv->long_ref, i); i--; } } @@ -2135,7 +2167,7 @@ exec_ref_pic_marking_adaptive_mmco_6( ) { picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; - GST_VAAPI_PICTURE_FLAG_SET(picture, + gst_vaapi_picture_h264_set_reference(picture, GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); } From 2c13b17cdb794104f7c3f156f77c5f075d1df403 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 13 Nov 2012 17:14:39 +0100 Subject: [PATCH 0894/3781] h264: add initial support for interlaced streams. Decoded frames are only output when they are complete, i.e. when both fields are decoded. This also means that the "interlaced" caps is not propagated to vaapipostproc or vaapisink elements. Another limitation is that interlaced bitstreams with MMCO are unlikely to work. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 255 ++++++++++++++++++++-- 1 file changed, 232 insertions(+), 23 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 1b3e4f3ea7..ed812adacc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -128,6 +128,7 @@ struct _GstVaapiPictureH264 { gint32 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx gint32 pic_num; // Temporary for ref pic marking: PicNum gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum + GstVaapiPictureH264 *other_field; // Temporary for ref pic marking: other field in the same frame store guint output_flag : 1; guint output_needed : 1; }; @@ -193,6 +194,19 @@ gst_vaapi_picture_h264_set_reference( GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags); } +static inline GstVaapiPictureH264 * +gst_vaapi_picture_h264_new_field(GstVaapiPictureH264 *picture) +{ + GstVaapiPicture *base_picture; + + g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL); + + base_picture = gst_vaapi_picture_new_field(&picture->base); + if (!base_picture) + return NULL; + return GST_VAAPI_PICTURE_H264_CAST(base_picture); +} + static inline GstVaapiSliceH264 * gst_vaapi_picture_h264_get_last_slice(GstVaapiPictureH264 *picture) { @@ -390,6 +404,61 @@ gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture) return fs; } +static gboolean +gst_vaapi_frame_store_add(GstVaapiFrameStore *fs, GstVaapiPictureH264 *picture) +{ + guint field; + + g_return_val_if_fail(GST_VAAPI_IS_FRAME_STORE(fs), FALSE); + g_return_val_if_fail(fs->num_buffers == 1, FALSE); + g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), FALSE); + g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FRAME(picture), FALSE); + + gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], picture); + if (picture->output_flag) { + picture->output_needed = TRUE; + fs->output_needed++; + } + + fs->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + + field = picture->structure == GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD ? + TOP_FIELD : BOTTOM_FIELD; + g_return_val_if_fail(fs->buffers[0]->field_poc[field] == G_MAXINT32, FALSE); + fs->buffers[0]->field_poc[field] = picture->field_poc[field]; + g_return_val_if_fail(picture->field_poc[!field] == G_MAXINT32, FALSE); + picture->field_poc[!field] = fs->buffers[0]->field_poc[!field]; + return TRUE; +} + +static gboolean +gst_vaapi_frame_store_split_fields(GstVaapiFrameStore *fs) +{ + GstVaapiPictureH264 * const first_field = fs->buffers[0]; + GstVaapiPictureH264 *second_field; + + g_return_val_if_fail(fs->num_buffers == 1, FALSE); + + first_field->base.structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + GST_VAAPI_PICTURE_FLAG_SET(first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED); + + second_field = gst_vaapi_picture_h264_new_field(first_field); + if (!second_field) + return FALSE; + gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], second_field); + gst_vaapi_picture_unref(second_field); + + second_field->frame_num = first_field->frame_num; + second_field->field_poc[0] = first_field->field_poc[0]; + second_field->field_poc[1] = first_field->field_poc[1]; + second_field->output_flag = first_field->output_flag; + if (second_field->output_flag) { + second_field->output_needed = TRUE; + fs->output_needed++; + } + return TRUE; +} + static inline gboolean gst_vaapi_frame_store_has_frame(GstVaapiFrameStore *fs) { @@ -448,9 +517,9 @@ struct _GstVaapiDecoderH264Private { GstVaapiProfile profile; GstVaapiEntrypoint entrypoint; GstVaapiChromaType chroma_type; - GstVaapiPictureH264 *short_ref[16]; + GstVaapiPictureH264 *short_ref[32]; guint short_ref_count; - GstVaapiPictureH264 *long_ref[16]; + GstVaapiPictureH264 *long_ref[32]; guint long_ref_count; GstVaapiPictureH264 *RefPicList0[32]; guint RefPicList0_count; @@ -473,6 +542,7 @@ struct _GstVaapiDecoderH264Private { guint is_opened : 1; guint is_avc : 1; guint has_context : 1; + guint progressive_sequence : 1; }; static gboolean @@ -602,8 +672,11 @@ dpb_output( { picture->output_needed = FALSE; - if (fs) - fs->output_needed--; + if (fs) { + if (--fs->output_needed > 0) + return TRUE; + picture = fs->buffers[0]; + } /* XXX: update cropping rectangle */ return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture)); @@ -686,13 +759,27 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) } } - // Create new frame store + // Check if picture is the second field and the first field is still in DPB + fs = priv->prev_frame; + if (fs && !gst_vaapi_frame_store_has_frame(fs)) { + g_return_val_if_fail(fs->num_buffers == 1, FALSE); + g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FRAME(picture), FALSE); + g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture), FALSE); + return gst_vaapi_frame_store_add(fs, picture); + } + + // Create new frame store, and split fields if necessary fs = gst_vaapi_frame_store_new(picture); if (!fs) return FALSE; gst_vaapi_frame_store_replace(&priv->prev_frame, fs); gst_vaapi_frame_store_unref(fs); + if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) { + if (!gst_vaapi_frame_store_split_fields(fs)) + return FALSE; + } + // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { while (priv->dpb_count == priv->dpb_size) { @@ -928,6 +1015,12 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) priv->height = sps->height; } + priv->progressive_sequence = sps->frame_mbs_only_flag; +#if 0 + /* XXX: we only output complete frames for now */ + gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence); +#endif + gst_vaapi_decoder_set_pixel_aspect_ratio( base_decoder, sps->vui_parameters.par_n, @@ -1045,10 +1138,12 @@ decode_current_picture(GstVaapiDecoderH264 *decoder) goto error; if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture))) goto error; - gst_vaapi_picture_replace(&priv->current_picture, NULL); + if (priv->prev_frame && gst_vaapi_frame_store_has_frame(priv->prev_frame)) + gst_vaapi_picture_replace(&priv->current_picture, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; 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; } @@ -1448,6 +1543,59 @@ init_picture_refs_pic_num( #define SORT_REF_LIST(list, n, compare_func) \ qsort(list, n, sizeof(*(list)), compare_picture_##compare_func) +static void +init_picture_refs_fields_1( + guint picture_structure, + GstVaapiPictureH264 *RefPicList[32], + guint *RefPicList_count, + GstVaapiPictureH264 *ref_list[32], + guint ref_list_count +) +{ + guint i, j, n; + + i = 0; + j = 0; + n = *RefPicList_count; + do { + g_assert(n < 32); + for (; i < ref_list_count; i++) { + if (ref_list[i]->structure == picture_structure) { + RefPicList[n++] = ref_list[i++]; + break; + } + } + for (; j < ref_list_count; j++) { + if (ref_list[j]->structure != picture_structure) { + RefPicList[n++] = ref_list[j++]; + break; + } + } + } while (i < ref_list_count || j < ref_list_count); + *RefPicList_count = n; +} + +static inline void +init_picture_refs_fields( + GstVaapiPictureH264 *picture, + GstVaapiPictureH264 *RefPicList[32], + guint *RefPicList_count, + GstVaapiPictureH264 *short_ref[32], + guint short_ref_count, + GstVaapiPictureH264 *long_ref[32], + guint long_ref_count +) +{ + guint n = 0; + + /* 8.2.4.2.5 - reference picture lists in fields */ + init_picture_refs_fields_1(picture->structure, RefPicList, &n, + short_ref, short_ref_count); + init_picture_refs_fields_1(picture->structure, RefPicList, &n, + long_ref, long_ref_count); + *RefPicList_count = n; +} + static void init_picture_refs_p_slice( GstVaapiDecoderH264 *decoder, @@ -1486,8 +1634,6 @@ init_picture_refs_p_slice( GstVaapiPictureH264 *long_ref[32]; guint long_ref_count = 0; - // XXX: handle second field if current field is marked as - // "used for short-term reference" if (priv->short_ref_count > 0) { for (i = 0; i < priv->short_ref_count; i++) short_ref[i] = priv->short_ref[i]; @@ -1495,8 +1641,6 @@ init_picture_refs_p_slice( short_ref_count = i; } - // XXX: handle second field if current field is marked as - // "used for long-term reference" if (priv->long_ref_count > 0) { for (i = 0; i < priv->long_ref_count; i++) long_ref[i] = priv->long_ref[i]; @@ -1504,7 +1648,12 @@ init_picture_refs_p_slice( long_ref_count = i; } - // XXX: handle 8.2.4.2.5 + init_picture_refs_fields( + picture, + priv->RefPicList0, &priv->RefPicList0_count, + short_ref, short_ref_count, + long_ref, long_ref_count + ); } } @@ -1637,8 +1786,20 @@ init_picture_refs_b_slice( long_ref_count = i; } - // XXX: handle 8.2.4.2.5 - } + init_picture_refs_fields( + picture, + priv->RefPicList0, &priv->RefPicList0_count, + short_ref0, short_ref0_count, + long_ref, long_ref_count + ); + + init_picture_refs_fields( + picture, + priv->RefPicList1, &priv->RefPicList1_count, + short_ref1, short_ref1_count, + long_ref, long_ref_count + ); + } /* Check whether RefPicList1 is identical to RefPicList0, then swap if necessary */ @@ -1837,7 +1998,7 @@ static void init_picture_ref_lists(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = decoder->priv; - guint i, short_ref_count, long_ref_count; + guint i, j, short_ref_count, long_ref_count; short_ref_count = 0; long_ref_count = 0; @@ -1853,6 +2014,21 @@ init_picture_ref_lists(GstVaapiDecoderH264 *decoder) else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) priv->long_ref[long_ref_count++] = picture; picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + picture->other_field = fs->buffers[1]; + } + } + else { + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + for (j = 0; j < fs->num_buffers; j++) { + GstVaapiPictureH264 * const picture = fs->buffers[j]; + if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) + priv->short_ref[short_ref_count++] = picture; + else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) + priv->long_ref[long_ref_count++] = picture; + picture->structure = picture->base.structure; + picture->other_field = fs->buffers[j ^ 1]; + } } } @@ -1963,10 +2139,13 @@ init_picture( /* Initialize picture structure */ if (!slice_hdr->field_pic_flag) base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - else if (!slice_hdr->bottom_field_flag) - base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; - else - base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + else { + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED); + if (!slice_hdr->bottom_field_flag) + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + else + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + } picture->structure = base_picture->structure; /* Initialize reference flags */ @@ -2000,9 +2179,14 @@ exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) GST_DEBUG("reference picture marking process (sliding window)"); + if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD(priv->current_picture)) + return TRUE; + max_num_ref_frames = sps->num_ref_frames; if (max_num_ref_frames == 0) max_num_ref_frames = 1; + if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) + max_num_ref_frames <<= 1; if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames) return TRUE; @@ -2018,6 +2202,18 @@ exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) ref_picture = priv->short_ref[m]; gst_vaapi_picture_h264_set_reference(ref_picture, 0); ARRAY_REMOVE_INDEX(priv->short_ref, m); + + /* Both fields need to be marked as "unused for reference" */ + if (ref_picture->other_field) + gst_vaapi_picture_h264_set_reference(ref_picture->other_field, 0); + if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) { + for (i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i] == ref_picture->other_field) { + ARRAY_REMOVE_INDEX(priv->short_ref, i); + break; + } + } + } return TRUE; } @@ -2455,12 +2651,24 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceH if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - picture = gst_vaapi_picture_h264_new(decoder); - if (!picture) { - GST_ERROR("failed to allocate picture"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + if (priv->current_picture) { + /* Re-use current picture where the first field was decoded */ + picture = gst_vaapi_picture_h264_new_field(priv->current_picture); + if (!picture) { + GST_ERROR("failed to allocate field picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } } - priv->current_picture = picture; + else { + /* Create new picture */ + picture = gst_vaapi_picture_h264_new(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); picture->pps = pps; @@ -2986,6 +3194,7 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->is_opened = FALSE; priv->is_avc = FALSE; priv->has_context = FALSE; + priv->progressive_sequence = TRUE; memset(priv->dpb, 0, sizeof(priv->dpb)); memset(priv->short_ref, 0, sizeof(priv->short_ref)); From f196605fc81ca928e446876d4e5ec93881f430cf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Nov 2012 10:27:12 +0100 Subject: [PATCH 0895/3781] h264: fix interlaced stream decoding with MMCO. Fix decoding of interlaced streams when adaptive_ref_pic_marking_mode_flag is equal to 1, i.e. when memory management control operations are used. In particular, when field_pic_flag is set to 0, the new reference flags shall be applied to both fields. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 32 ++++++++++++++--------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index ed812adacc..f9998a2d88 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -185,13 +185,19 @@ gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder) static inline void gst_vaapi_picture_h264_set_reference( GstVaapiPictureH264 *picture, - guint reference_flags + guint reference_flags, + gboolean other_field ) { g_return_if_fail(GST_VAAPI_IS_PICTURE_H264(picture)); GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags); + + if (!other_field || !(picture = picture->other_field)) + return; + GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); + GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags); } static inline GstVaapiPictureH264 * @@ -2200,13 +2206,12 @@ exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) } ref_picture = priv->short_ref[m]; - gst_vaapi_picture_h264_set_reference(ref_picture, 0); + gst_vaapi_picture_h264_set_reference(ref_picture, 0, TRUE); ARRAY_REMOVE_INDEX(priv->short_ref, m); - /* Both fields need to be marked as "unused for reference" */ - if (ref_picture->other_field) - gst_vaapi_picture_h264_set_reference(ref_picture->other_field, 0); - if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) { + /* Both fields need to be marked as "unused for reference", so + remove the other field from the short_ref[] list as well */ + if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture) && ref_picture->other_field) { for (i = 0; i < priv->short_ref_count; i++) { if (priv->short_ref[i] == ref_picture->other_field) { ARRAY_REMOVE_INDEX(priv->short_ref, i); @@ -2246,7 +2251,8 @@ exec_ref_pic_marking_adaptive_mmco_1( if (i < 0) return; - gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0); + gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0, + GST_VAAPI_PICTURE_IS_FRAME(picture)); ARRAY_REMOVE_INDEX(priv->short_ref, i); } @@ -2265,7 +2271,8 @@ exec_ref_pic_marking_adaptive_mmco_2( if (i < 0) return; - gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0); + gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, + GST_VAAPI_PICTURE_IS_FRAME(picture)); ARRAY_REMOVE_INDEX(priv->long_ref, i); } @@ -2286,7 +2293,7 @@ exec_ref_pic_marking_adaptive_mmco_3( break; } if (i != priv->long_ref_count) { - gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0); + gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE); ARRAY_REMOVE_INDEX(priv->long_ref, i); } @@ -2301,7 +2308,8 @@ exec_ref_pic_marking_adaptive_mmco_3( ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; gst_vaapi_picture_h264_set_reference(ref_picture, - GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, + GST_VAAPI_PICTURE_IS_FRAME(picture)); } /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx @@ -2321,7 +2329,7 @@ exec_ref_pic_marking_adaptive_mmco_4( for (i = 0; i < priv->long_ref_count; i++) { if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx) continue; - gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0); + gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, FALSE); ARRAY_REMOVE_INDEX(priv->long_ref, i); i--; } @@ -2364,7 +2372,7 @@ exec_ref_pic_marking_adaptive_mmco_6( { picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; gst_vaapi_picture_h264_set_reference(picture, - GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, FALSE); } /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */ From 1fc397affdef0f26969af34e59c9841fe2b0959c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Nov 2012 14:25:34 +0100 Subject: [PATCH 0896/3781] h264: fix VAPictureParameterBufferH264.ReferenceFrames[] construction. ... for interlaced streams. The short_ref[] and long_ref[] arrays may contain up to 32 fields but VA ReferenceFrames[] array expects up to 16 reference frames, thus including both fields. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 25 +++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index f9998a2d88..8e88220c8b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2458,8 +2458,12 @@ vaapi_init_picture(VAPictureH264 *pic) } static void -vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture) +vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture, + guint picture_structure) { + if (!picture_structure) + picture_structure = picture->structure; + pic->picture_id = picture->base.surface_id; pic->flags = 0; @@ -2473,7 +2477,7 @@ vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture) pic->frame_idx = picture->frame_num; } - switch (picture->structure) { + switch (picture_structure) { case GST_VAAPI_PICTURE_STRUCTURE_FRAME: pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD]; pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD]; @@ -2507,11 +2511,14 @@ fill_picture( guint i, n; /* Fill in VAPictureParameterBufferH264 */ - vaapi_fill_picture(&pic_param->CurrPic, picture); - for (i = 0, n = 0; i < priv->short_ref_count; i++, n++) - vaapi_fill_picture(&pic_param->ReferenceFrames[n], priv->short_ref[i]); - for (i = 0; i < priv->long_ref_count; i++, n++) - vaapi_fill_picture(&pic_param->ReferenceFrames[n], priv->long_ref[i]); + vaapi_fill_picture(&pic_param->CurrPic, picture, 0); + + for (i = 0, n = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + if (gst_vaapi_frame_store_has_reference(fs)) + vaapi_fill_picture(&pic_param->ReferenceFrames[n++], + fs->buffers[0], fs->structure); + } for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++) vaapi_init_picture(&pic_param->ReferenceFrames[n]); @@ -2793,7 +2800,7 @@ fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) slice_hdr->num_ref_idx_l0_active_minus1; for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++) - vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i]); + vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i], 0); for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++) vaapi_init_picture(&slice_param->RefPicList0[i]); @@ -2804,7 +2811,7 @@ fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) slice_hdr->num_ref_idx_l1_active_minus1; for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++) - vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i]); + vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i], 0); for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++) vaapi_init_picture(&slice_param->RefPicList1[i]); return TRUE; From 4d31e1e58acbd016105895808f7648383316741c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Nov 2012 18:40:47 +0100 Subject: [PATCH 0897/3781] h264: start decoding slices after first SPS/PPS activation. Only start decoding slices when at least one SPS and PPS got activated. This fixes cases when a source represents a substream of another stream and no SPS and PPS was inserted before the first slice of the generated substream. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 8e88220c8b..6a0e07e6d4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -547,6 +547,8 @@ struct _GstVaapiDecoderH264Private { guint is_constructed : 1; guint is_opened : 1; guint is_avc : 1; + guint got_sps : 1; + guint got_pps : 1; guint has_context : 1; guint progressive_sequence : 1; }; @@ -1168,6 +1170,7 @@ decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) if (result != GST_H264_PARSER_OK) return get_status(result); + priv->got_pps = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1185,6 +1188,7 @@ decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) if (result != GST_H264_PARSER_OK) return get_status(result); + priv->got_sps = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2910,12 +2914,15 @@ scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) static GstVaapiDecoderStatus decode_nalu(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) { + GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiDecoderStatus status; switch (nalu->type) { case GST_H264_NAL_SLICE_IDR: /* fall-through. IDR specifics are handled in init_picture() */ case GST_H264_NAL_SLICE: + if (!priv->got_sps || !priv->got_pps) + return GST_VAAPI_DECODER_STATUS_SUCCESS; status = decode_slice(decoder, nalu); break; case GST_H264_NAL_SPS: From 1e506ad6eec8d1599353545c644a78b247cc164e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Nov 2012 19:22:13 +0100 Subject: [PATCH 0898/3781] h264: fix incorrect integration of previous commit (4d31e1e). git am got confused somehow, though the end result doesn't change at all since we require both SPS and PPS to be parsed prior to decoding the first slice. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 6a0e07e6d4..dbe8eb44b7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1170,7 +1170,7 @@ decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) if (result != GST_H264_PARSER_OK) return get_status(result); - priv->got_pps = TRUE; + priv->got_sps = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1188,7 +1188,7 @@ decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) if (result != GST_H264_PARSER_OK) return get_status(result); - priv->got_sps = TRUE; + priv->got_pps = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } From b794f6cb92d43b4ea41d60955bf62b83766dd64d Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Fri, 2 Nov 2012 18:18:37 +0000 Subject: [PATCH 0899/3781] wayland: port to 1.0 version of the protocol. This patch updates to relect the 1.0 version of the protocol. The main changes are the switch to wl_registry for global object notifications and the way that the event queue and file descriptor is processed. Signed-off-by: Gwenole Beauchesne --- configure.ac | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 38 +++++++++---------- .../gst/vaapi/gstvaapidisplay_wayland_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 6 ++- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/configure.ac b/configure.ac index f38d9f9624..20e193dc12 100644 --- a/configure.ac +++ b/configure.ac @@ -42,7 +42,7 @@ m4_define([gst_plugins_bad_version], [gst_plugins_bad_major_version.gst_plugins_bad_minor_version.gst_plugins_bad_micro_version]) # Wayland minimum version number -m4_define([wayland_api_version], [0.95.0]) +m4_define([wayland_api_version], [1.0.0]) # VA-API minimum version number m4_define([va_api_version], [0.30.4]) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 1ebeb3d308..ec2c81a226 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -253,34 +253,31 @@ static const struct wl_output_listener output_listener = { }; static void -display_handle_global( - struct wl_display *display, - uint32_t id, - const char *interface, - uint32_t version, - void *data +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_display_bind(display, id, &wl_compositor_interface); + priv->compositor = + wl_registry_bind(registry, id, &wl_compositor_interface, 1); else if (strcmp(interface, "wl_shell") == 0) - priv->shell = wl_display_bind(display, id, &wl_shell_interface); + priv->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1); else if (strcmp(interface, "wl_output") == 0) { - priv->output = wl_display_bind(display, id, &wl_output_interface); + priv->output = wl_registry_bind(registry, id, &wl_output_interface, 1); wl_output_add_listener(priv->output, &output_listener, priv); } } -static int -event_mask_update(uint32_t mask, void *data) -{ - GstVaapiDisplayWaylandPrivate * const priv = data; - - priv->event_mask = mask; - return 0; -} +static const struct wl_registry_listener registry_listener = { + registry_handle_global, + NULL, +}; static gboolean gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display) @@ -296,9 +293,9 @@ gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display) return FALSE; wl_display_set_user_data(priv->wl_display, priv); - wl_display_add_global_listener(priv->wl_display, display_handle_global, priv); - priv->event_fd = wl_display_get_fd(priv->wl_display, event_mask_update, priv); - wl_display_iterate(priv->wl_display, priv->event_mask); + 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->compositor) { @@ -477,7 +474,6 @@ gst_vaapi_display_wayland_init(GstVaapiDisplayWayland *display) priv->phys_width = 0; priv->phys_height = 0; priv->event_fd = -1; - priv->event_mask = 0; } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index 429de3682c..1fff458604 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -51,12 +51,12 @@ struct _GstVaapiDisplayWaylandPrivate { struct wl_compositor *compositor; struct wl_shell *shell; struct wl_output *output; + struct wl_registry *registry; guint width; guint height; guint phys_width; guint phys_height; gint event_fd; - guint32 event_mask; guint create_display : 1; }; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 8e04f2d7f5..c22c678793 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -260,7 +260,7 @@ gst_vaapi_window_wayland_render( /* Wait for the previous frame to complete redraw */ if (priv->redraw_pending) - wl_display_iterate(wl_display, WL_DISPLAY_READABLE); + wl_display_dispatch(wl_display); /* XXX: use VA/VPP for other filters */ va_flags = from_GstVaapiSurfaceRenderFlags(flags); @@ -292,7 +292,9 @@ gst_vaapi_window_wayland_render( priv->opaque_region = NULL; } - wl_display_iterate(wl_display, WL_DISPLAY_WRITABLE); + wl_surface_commit(priv->surface); + + wl_display_flush(wl_display); priv->redraw_pending = TRUE; priv->buffer = buffer; From ca8b5035de457f16bb2adcae39127b87dd423a34 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 15 Nov 2012 15:00:43 +0100 Subject: [PATCH 0900/3781] Fix build with the GNU gold linker. In particular, fix libgstvaapi-glx DSO dependencies to include libgstbase and libgstvideo libs, e.g. for gst_video_buffer_get_overlay_composition(). --- gst-libs/gst/vaapi/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 49b1b3b5ff..313d5500c2 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -307,12 +307,15 @@ libgstvaapi_glx_@GST_MAJORMINOR@_la_CFLAGS = \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ $(GL_CFLAGS) \ $(LIBVA_GLX_CFLAGS) \ $(NULL) libgstvaapi_glx_@GST_MAJORMINOR@_la_LIBADD = \ $(GLIB_LIBS) \ + $(GST_BASE_LIBS) \ + $(GST_VIDEO_LIBS) \ $(GL_LIBS) \ $(LIBVA_GLX_LIBS) \ libgstvaapi-x11-@GST_MAJORMINOR@.la \ From 9367c8ea5839d000875b1c92aa645badd592d5e6 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 8 Nov 2012 11:40:47 +0200 Subject: [PATCH 0901/3781] mpeg2: fix PAR calculation from commit bd11bae. Invoke gst_mpeg_video_finalise_mpeg2_sequence_header() to get the correct PAR values. While doing so, require a newer version of the bitstream parser library. Note: it may be necessary to also parse the Sequence_Display_Extension() header. Signed-off-by: Sreerenj Balachandran Signed-off-by: Gwenole Beauchesne --- configure.ac | 24 ++++++++++++++++++++++ gst-libs/gst/codecparsers/Makefile.am | 13 ++++++++---- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 14 ++++++++----- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 20e193dc12..0a27282d00 100644 --- a/configure.ac +++ b/configure.ac @@ -214,6 +214,30 @@ dnl ... bitstream parsers PKG_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_MAJORMINOR >= gst_plugins_bad_version]) +dnl ... MPEG-2 parser, with the required extensions +AC_CACHE_CHECK([for MPEG-2 parser], + ac_cv_have_gst_mpeg2_parser, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[GstMpegVideoSequenceHdr seq_hdr; + GstMpegVideoSequenceExt seq_ext; + GstMpegVideoSequenceDisplayExt seq_dpy; + gst_mpeg_video_finalise_mpeg2_sequence_header(&seq_hdr, + &seq_ext, &seq_dpy);]])], + [ac_cv_have_gst_mpeg2_parser="yes"], + [ac_cv_have_gst_mpeg2_parser="no"] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +]) +AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_MPEG2], + [test "$ac_cv_have_gst_mpeg2_parser" != "yes"]) + dnl ... H.264 parser, with the required extensions AC_CACHE_CHECK([for H.264 parser], ac_cv_have_gst_h264_parser, [ diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 4f226cbcc8..46851c054f 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -17,17 +17,22 @@ libgstvaapi_codecparsers_libs = \ $(GST_LIBS) \ $(NULL) -gen_source_c = -gen_source_h = +gen_source_c = parserutils.c +gen_source_h = parserutils.h if USE_LOCAL_CODEC_PARSERS_JPEG gen_source_c += gstjpegparser.c gen_source_h += gstjpegparser.h endif +if USE_LOCAL_CODEC_PARSERS_MPEG2 +gen_source_c += gstmpegvideoparser.c +gen_source_h += gstmpegvideoparser.h +endif + if USE_LOCAL_CODEC_PARSERS_H264 -gen_source_c += gsth264parser.c parserutils.c -gen_source_h += gsth264parser.h parserutils.h +gen_source_c += gsth264parser.c +gen_source_h += gsth264parser.h endif GENFILES = \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 7b479057fc..8bdb13f116 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -519,11 +519,9 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) pts_set_framerate(&priv->tsg, priv->fps_n, priv->fps_d); gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); - gst_vaapi_decoder_set_pixel_aspect_ratio( - base_decoder, - seq_hdr->par_w, - seq_hdr->par_h - ); + if (gst_mpeg_video_finalise_mpeg2_sequence_header(seq_hdr, NULL, NULL)) + gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, + seq_hdr->par_w, seq_hdr->par_h); priv->width = seq_hdr->width; priv->height = seq_hdr->height; @@ -539,6 +537,7 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr; GstMpegVideoSequenceExt * const seq_ext = &priv->seq_ext; GstVaapiProfile profile; guint width, height; @@ -590,6 +589,11 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) priv->profile = profile; priv->profile_changed = TRUE; } + + if (gst_mpeg_video_finalise_mpeg2_sequence_header(seq_hdr, seq_ext, NULL)) + gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, + seq_hdr->par_w, seq_hdr->par_h); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 18245b484dc5b050220505e80322f25a0bc74ec0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 15 Nov 2012 17:50:45 +0100 Subject: [PATCH 0902/3781] codecparsers: always build the VC-1 parser library. ... this is useful to make sure pixel-aspect-ratio and framerate information are correctly parsed since we have no means to detect that at configure time. --- gst-libs/gst/codecparsers/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 46851c054f..007da412ba 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -17,8 +17,8 @@ libgstvaapi_codecparsers_libs = \ $(GST_LIBS) \ $(NULL) -gen_source_c = parserutils.c -gen_source_h = parserutils.h +gen_source_c = gstvc1parser.c parserutils.c +gen_source_h = gstvc1parser.h parserutils.h if USE_LOCAL_CODEC_PARSERS_JPEG gen_source_c += gstjpegparser.c From 9ab3ce293261ee6cfc6fbcf94adf60225ee83b89 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 16 Nov 2012 16:18:52 +0100 Subject: [PATCH 0903/3781] codecparsers: always build parserutils first. Fix commit 18245b4 so that to link and build parserutils.[ch] first. This is needed since that's the common dependency for actual codec parsers (gstvc1parser.c for instance). --- gst-libs/gst/codecparsers/Makefile.am | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 007da412ba..9b40eb6a6f 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -17,8 +17,12 @@ libgstvaapi_codecparsers_libs = \ $(GST_LIBS) \ $(NULL) -gen_source_c = gstvc1parser.c parserutils.c -gen_source_h = gstvc1parser.h parserutils.h +gen_source_c = parserutils.c +gen_source_h = parserutils.h + +# Always build VC-1 parser for now +gen_source_c += gstvc1parser.c +gen_source_h += gstvc1parser.h if USE_LOCAL_CODEC_PARSERS_JPEG gen_source_c += gstjpegparser.c From cb0da4ed7acbb51f2d5dba34c0b37b2c5ad8bff4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 16 Nov 2012 18:00:10 +0100 Subject: [PATCH 0904/3781] h264: fix picture size in macroblocks. The picture size signalled by sps->{width,height} is the actual size with cropping applied, not the original size derived from pic_width_in_mbs_minus1 and pic_height_in_map_units_minus1. VA driver expects that original size, uncropped. There is another issue pending: frame cropping information needs to be taken care of. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 27 +++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index dbe8eb44b7..4426d81711 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -532,8 +532,8 @@ struct _GstVaapiDecoderH264Private { GstVaapiPictureH264 *RefPicList1[32]; guint RefPicList1_count; guint nal_length_size; - guint width; - guint height; + guint mb_width; + guint mb_height; gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt gint32 poc_msb; // PicOrderCntMsb gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header()) @@ -991,6 +991,7 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) GstVaapiProfile profile; GstVaapiChromaType chroma_type; gboolean reset_context = FALSE; + guint mb_width, mb_height; profile = get_profile(decoder, sps); if (!profile) { @@ -1016,11 +1017,14 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) priv->chroma_type = chroma_type; } - if (priv->width != sps->width || priv->height != sps->height) { + mb_width = sps->pic_width_in_mbs_minus1 + 1; + mb_height = (sps->pic_height_in_map_units_minus1 + 1) << + !sps->frame_mbs_only_flag; + if (priv->mb_width != mb_width || priv->mb_height != mb_height) { GST_DEBUG("size changed"); - reset_context = TRUE; - priv->width = sps->width; - priv->height = sps->height; + reset_context = TRUE; + priv->mb_width = mb_width; + priv->mb_height = mb_height; } priv->progressive_sequence = sps->frame_mbs_only_flag; @@ -1038,10 +1042,11 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) if (!reset_context && priv->has_context) return GST_VAAPI_DECODER_STATUS_SUCCESS; + /* XXX: fix surface size when cropping is implemented */ info.profile = priv->profile; info.entrypoint = priv->entrypoint; - info.width = priv->width; - info.height = priv->height; + info.width = sps->width; + info.height = sps->height; info.ref_frames = get_max_dec_frame_buffering(sps); if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info)) @@ -2532,8 +2537,8 @@ fill_picture( #define COPY_BFM(a, s, f) \ pic_param->a.bits.f = (s)->f - pic_param->picture_width_in_mbs_minus1 = ((priv->width + 15) >> 4) - 1; - pic_param->picture_height_in_mbs_minus1 = ((priv->height + 15) >> 4) - 1; + pic_param->picture_width_in_mbs_minus1 = priv->mb_width - 1; + pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1; pic_param->frame_num = priv->frame_num; COPY_FIELD(sps, bit_depth_luma_minus8); @@ -3198,8 +3203,6 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->RefPicList0_count = 0; priv->RefPicList1_count = 0; priv->nal_length_size = 0; - priv->width = 0; - priv->height = 0; priv->adapter = NULL; priv->field_poc[0] = 0; priv->field_poc[1] = 0; From a9f8e17ec58d40f0918980455457f091ceff6931 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 19 Nov 2012 10:04:52 +0100 Subject: [PATCH 0905/3781] NEWS: updates. --- NEWS | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 9c1b6e7313..43c7e29561 100644 --- a/NEWS +++ b/NEWS @@ -1,16 +1,30 @@ -gst-vaapi NEWS -- summary of changes. 2012-08-DD +gst-vaapi NEWS -- summary of changes. 2012-12-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora -Version 0.4.0 - DD.Aug.2012 +Version 0.5.0 - DD.Dec.2012 +* Require glib >= 2.31.2 + +Version 0.4.1 - 20.Nov.2012 +* Add support for H.264 interlaced streams +* Add support for Wayland 1.0 protocol (Robert Bradford) +* Add upstream bitstream parsers library (codecparsers) +* Fix build with the GNU gold linker +* Fix detection of H.264 picture boundaries +* Fix memory leak in MPEG-2 decoder for empty user-data packets +* Fix H.264 decoder with MMCO-based reference picture marking process +* Decode pending packets when an end-of-stream is received (+Feng Yuan) +* Use pixel-aspect-ratio from bitstream parsers (Simon Farnsworth) + +Version 0.4.0 - 05.Oct.2012 * Add support for video rotation * Add new video display APIs: Wayland and raw DRM for headless pipelines * Drop FFmpeg-based decoders, only use codecparsers-based ones * Only reset decoder if meaningful caps changed, e.g. size * Allocate the minimal number of video surfaces useful for decoding * Fix vaapisink to scale video down to fit the screen dimensions -* Fix vaapidecode crash when trying to release an inexisten lock (Philip Lorenz) +* Fix vaapidecode crash when trying to release inexistent lock (Philip Lorenz) Version 0.3.8 - 20.Sep.2012 * Disable FFmpeg-based decoders by default From 5fac9d4b5533c92240805e4845064c95e78b1873 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 30 Oct 2012 13:15:45 +0800 Subject: [PATCH 0906/3781] videobuffer: fix memory leak for surface and image. Fix reference leak of surface and image in GstVaapiVideoBuffer wrapper, thus resulting on actual memory leak of GstVaapiImage when using them for downloads/uploads from VA surfaces and more specifically surfaces when the pipeline is shutdown. i.e. vaTerminate() was never called because the resources were not unreferenced, and thus not deallocated in the end. Signed-off-by: Gwenole Beauchesne --- NEWS | 1 + gst-libs/gst/vaapi/gstvaapivideobuffer.c | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 43c7e29561..64b58ffe3c 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Copyright (C) 2011 Collabora Version 0.5.0 - DD.Dec.2012 * Require glib >= 2.31.2 +* Fix memory leak in GstVaapiVideoBuffer for images and surfaces (Feng Yuan) Version 0.4.1 - 20.Nov.2012 * Add support for H.264 interlaced streams diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 0a108535f9..cd1c948bc0 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -86,8 +86,7 @@ gst_vaapi_video_buffer_destroy_image(GstVaapiVideoBuffer *buffer) if (priv->image) { if (priv->image_pool) gst_vaapi_video_pool_put_object(priv->image_pool, priv->image); - else - g_object_unref(priv->image); + g_object_unref(priv->image); priv->image = NULL; } @@ -104,8 +103,7 @@ gst_vaapi_video_buffer_destroy_surface(GstVaapiVideoBuffer *buffer) if (priv->surface) { if (priv->surface_pool) gst_vaapi_video_pool_put_object(priv->surface_pool, priv->surface); - else - g_object_unref(priv->surface); + g_object_unref(priv->surface); priv->surface = NULL; } From c38c0853ebf2979f1321892d42217afb1b9b88fa Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 20 Nov 2012 14:36:29 +0100 Subject: [PATCH 0907/3781] image: fix GstVaapiImage map and unmap. Fix gst_vaapi_image_map() to return TRUE and the GstVaapiImageRaw structure correctly filled in if the image was already mapped. Likewise, make gst_vaapi_image_unmap() return TRUE if the image was already unmapped. --- gst-libs/gst/vaapi/gstvaapiimage.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 0961234bf4..65d79a5e74 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -753,12 +753,11 @@ _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image) { GstVaapiImagePrivate * const priv = image->priv; GstVaapiDisplay *display; - void *image_data; VAStatus status; guint i; if (_gst_vaapi_image_is_mapped(image)) - return TRUE; + goto map_success; display = GST_VAAPI_OBJECT_DISPLAY(image); if (!display) @@ -767,15 +766,14 @@ _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image) GST_VAAPI_DISPLAY_LOCK(display); status = vaMapBuffer( GST_VAAPI_DISPLAY_VADISPLAY(display), - image->priv->image.buf, - &image_data + priv->image.buf, + (void **)&priv->image_data ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaMapBuffer()")) return FALSE; - image->priv->image_data = image_data; - +map_success: if (raw_image) { const VAImage * const va_image = &priv->image; raw_image->format = priv->format; @@ -783,7 +781,8 @@ _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image) raw_image->height = va_image->height; raw_image->num_planes = va_image->num_planes; for (i = 0; i < raw_image->num_planes; i++) { - raw_image->pixels[i] = (guchar *)image_data + va_image->offsets[i]; + raw_image->pixels[i] = (guchar *)priv->image_data + + va_image->offsets[i]; raw_image->stride[i] = va_image->pitches[i]; } } @@ -815,7 +814,7 @@ _gst_vaapi_image_unmap(GstVaapiImage *image) VAStatus status; if (!_gst_vaapi_image_is_mapped(image)) - return FALSE; + return TRUE; display = GST_VAAPI_OBJECT_DISPLAY(image); if (!display) From 499e0dd981fb5ef770d25fe98d791e764f1089c9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 20 Nov 2012 14:28:55 +0100 Subject: [PATCH 0908/3781] vaapisink: add support for raw YUV buffers. Add new GstVaapiUploader helper to upload raw YUV buffers to VA surfaces. It is up to the caller to negotiate source caps (for images) and output caps (for surfaces). gst_vaapi_uploader_has_direct_rendering() is available to help decide between the creation of a GstVaapiVideoBuffer or a regular GstBuffer on sink pads. Signed-off-by: Zhao Halley Signed-off-by: Gwenole Beauchesne --- NEWS | 1 + gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapisink.c | 88 +++++++- gst/vaapi/gstvaapisink.h | 3 + gst/vaapi/gstvaapiuploader.c | 394 +++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiuploader.h | 111 ++++++++++ 6 files changed, 593 insertions(+), 6 deletions(-) create mode 100644 gst/vaapi/gstvaapiuploader.c create mode 100644 gst/vaapi/gstvaapiuploader.h diff --git a/NEWS b/NEWS index 64b58ffe3c..621c5500d8 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Copyright (C) 2011 Collabora Version 0.5.0 - DD.Dec.2012 * Require glib >= 2.31.2 +* Add support for raw YUV buffers in vaapisink (+Halley Zhao) * Fix memory leak in GstVaapiVideoBuffer for images and surfaces (Feng Yuan) Version 0.4.1 - 20.Nov.2012 diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 0c1097ca31..4da267e31e 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -38,6 +38,7 @@ libgstvaapi_la_SOURCES = \ gstvaapipostproc.c \ gstvaapisink.c \ gstvaapiupload.c \ + gstvaapiuploader.c \ $(NULL) noinst_HEADERS = \ @@ -48,6 +49,7 @@ noinst_HEADERS = \ gstvaapipostproc.h \ gstvaapisink.h \ gstvaapiupload.h \ + gstvaapiuploader.h \ $(NULL) libgstvaapi_la_CFLAGS = \ diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 72513981b8..916cd8e176 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -72,12 +72,18 @@ static const GstElementDetails gst_vaapisink_details = "Gwenole Beauchesne "); /* Default template */ +static const char gst_vaapisink_sink_caps_str[] = + "video/x-raw-yuv, " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]; " + GST_VAAPI_SURFACE_CAPS; + static GstStaticPadTemplate gst_vaapisink_sink_factory = GST_STATIC_PAD_TEMPLATE( "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS(GST_VAAPI_SURFACE_CAPS)); + GST_STATIC_CAPS(gst_vaapisink_sink_caps_str)); static void gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface); @@ -228,6 +234,7 @@ gst_vaapisink_destroy(GstVaapiSink *sink) gst_buffer_replace(&sink->video_buffer, NULL); g_clear_object(&sink->texture); g_clear_object(&sink->display); + g_clear_object(&sink->uploader); gst_caps_replace(&sink->caps, NULL); } @@ -561,7 +568,13 @@ gst_vaapisink_start(GstBaseSink *base_sink) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - return gst_vaapisink_ensure_display(sink); + if (!gst_vaapisink_ensure_display(sink)) + return FALSE; + + sink->uploader = gst_vaapi_uploader_new(sink->display); + if (!sink->uploader) + return FALSE; + return TRUE; } static gboolean @@ -572,6 +585,7 @@ gst_vaapisink_stop(GstBaseSink *base_sink) gst_buffer_replace(&sink->video_buffer, NULL); g_clear_object(&sink->window); g_clear_object(&sink->display); + g_clear_object(&sink->uploader); return TRUE; } @@ -598,6 +612,9 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) sink->video_width = video_width; sink->video_height = video_height; + if (gst_structure_has_name(structure, "video/x-raw-yuv")) + sink->use_video_raw = TRUE; + gst_video_parse_caps_pixel_aspect_ratio(caps, &video_par_n, &video_par_d); sink->video_par_n = video_par_n; sink->video_par_d = video_par_d; @@ -808,26 +825,45 @@ static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); + GstVaapiVideoBuffer *vbuffer; GstVaapiSurface *surface; guint flags; gboolean success; GstVideoOverlayComposition * const composition = gst_video_buffer_get_overlay_composition(buffer); + if (!sink->use_video_raw) + buffer = gst_buffer_ref(buffer); + else { + GstBuffer * const src_buffer = buffer; + if (GST_VAAPI_IS_VIDEO_BUFFER(buffer)) + buffer = gst_buffer_ref(src_buffer); + else if (GST_VAAPI_IS_VIDEO_BUFFER(buffer->parent)) + buffer = gst_buffer_ref(src_buffer->parent); + else { + buffer = gst_vaapi_uploader_get_buffer(sink->uploader); + if (!buffer) + return GST_FLOW_UNEXPECTED; + } + if (!gst_vaapi_uploader_process(sink->uploader, src_buffer, buffer)) + goto error; + } + vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); + g_return_val_if_fail(vbuffer != NULL, GST_FLOW_UNEXPECTED); + if (sink->display != gst_vaapi_video_buffer_get_display (vbuffer)) { g_clear_object(&sink->display); sink->display = g_object_ref (gst_vaapi_video_buffer_get_display (vbuffer)); } if (!sink->window) - return GST_FLOW_UNEXPECTED; + goto error; gst_vaapisink_ensure_rotation(sink, TRUE); surface = gst_vaapi_video_buffer_get_surface(vbuffer); if (!surface) - return GST_FLOW_UNEXPECTED; + goto error; GST_DEBUG("render surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); @@ -865,11 +901,50 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) break; } if (!success) - return GST_FLOW_UNEXPECTED; + goto error; /* Retain VA surface until the next one is displayed */ if (sink->use_overlay) gst_buffer_replace(&sink->video_buffer, buffer); + gst_buffer_unref(buffer); + return GST_FLOW_OK; + +error: + gst_buffer_unref(buffer); + return GST_FLOW_UNEXPECTED; +} + +static GstFlowReturn +gst_vaapisink_buffer_alloc( + GstBaseSink *base_sink, + guint64 offset, + guint size, + GstCaps *caps, + GstBuffer **pbuf +) +{ + GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + GstStructure *structure; + GstBuffer *buf; + + *pbuf = NULL; + + structure = gst_caps_get_structure(caps, 0); + if (!gst_structure_has_name(structure, "video/x-raw-yuv")) + return GST_FLOW_OK; + + if (!gst_vaapi_uploader_ensure_display(sink->uploader, sink->display)) + return GST_FLOW_NOT_SUPPORTED; + if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL)) + return GST_FLOW_NOT_SUPPORTED; + + buf = gst_vaapi_uploader_get_buffer(sink->uploader); + if (!buf) { + GST_WARNING("failed to allocate resources for raw YUV buffer"); + return GST_FLOW_NOT_SUPPORTED; + } + + *pbuf = buf; return GST_FLOW_OK; } @@ -974,6 +1049,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->preroll = gst_vaapisink_show_frame; basesink_class->render = gst_vaapisink_show_frame; basesink_class->query = gst_vaapisink_query; + basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; gst_element_class_set_details_simple( element_class, diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index a2e8bff66d..b8b082a960 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -30,6 +30,7 @@ #include #endif #include "gstvaapipluginutil.h" +#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -67,6 +68,7 @@ struct _GstVaapiSink { /*< private >*/ GstVideoSink parent_instance; + GstVaapiUploader *uploader; GstCaps *caps; GstVaapiDisplay *display; GstVaapiDisplayType display_type; @@ -88,6 +90,7 @@ struct _GstVaapiSink { guint use_reflection : 1; guint use_overlay : 1; guint use_rotation : 1; + guint use_video_raw : 1; }; struct _GstVaapiSinkClass { diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c new file mode 100644 index 0000000000..d7ba1f979e --- /dev/null +++ b/gst/vaapi/gstvaapiuploader.c @@ -0,0 +1,394 @@ +/* + * gstvaapiuploader.c - VA-API video upload helper + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2012 Intel Corporation + * + * 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 "gst/vaapi/sysdeps.h" +#include +#include +#include +#include +#include + +#include "gstvaapiuploader.h" +#include "gstvaapipluginbuffer.h" + +#define GST_HELPER_NAME "vaapiupload" +#define GST_HELPER_DESC "VA-API video uploader" + +GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapi_uploader); +#define GST_CAT_DEFAULT gst_debug_vaapi_uploader + +G_DEFINE_TYPE(GstVaapiUploader, gst_vaapi_uploader, G_TYPE_OBJECT) + +#define GST_VAAPI_UPLOADER_CAST(obj) \ + ((GstVaapiUploader *)(obj)) + +#define GST_VAAPI_UPLOADER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_UPLOADER, \ + GstVaapiUploaderPrivate)) + +struct _GstVaapiUploaderPrivate { + GstVaapiDisplay *display; + GstVaapiVideoPool *images; + GstCaps *image_caps; + guint image_width; + guint image_height; + GstVaapiVideoPool *surfaces; + guint surface_width; + guint surface_height; + guint direct_rendering; +}; + +enum { + PROP_0, + + PROP_DISPLAY, +}; + +static void +gst_vaapi_uploader_destroy(GstVaapiUploader *uploader) +{ + GstVaapiUploaderPrivate * const priv = uploader->priv; + + gst_caps_replace(&priv->image_caps, NULL); + g_clear_object(&priv->images); + g_clear_object(&priv->surfaces); + g_clear_object(&priv->display); +} + +static gboolean +ensure_display(GstVaapiUploader *uploader, GstVaapiDisplay *display) +{ + GstVaapiUploaderPrivate * const priv = uploader->priv; + + if (priv->display == display) + return TRUE; + + g_clear_object(&priv->display); + if (display) + priv->display = g_object_ref(display); + return TRUE; +} + +static gboolean +ensure_image_pool(GstVaapiUploader *uploader, GstCaps *caps) +{ + GstVaapiUploaderPrivate * const priv = uploader->priv; + GstStructure * const structure = gst_caps_get_structure(caps, 0); + gint width, height; + + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + + if (width != priv->image_width || height != priv->image_height) { + priv->image_width = width; + priv->image_height = height; + g_clear_object(&priv->images); + priv->images = gst_vaapi_image_pool_new(priv->display, caps); + if (!priv->images) + return FALSE; + gst_caps_replace(&priv->image_caps, caps); + } + return TRUE; +} + +static gboolean +ensure_surface_pool(GstVaapiUploader *uploader, GstCaps *caps) +{ + GstVaapiUploaderPrivate * const priv = uploader->priv; + GstStructure * const structure = gst_caps_get_structure(caps, 0); + gint width, height; + + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + + if (width != priv->surface_width || height != priv->surface_height) { + priv->surface_width = width; + priv->surface_height = height; + g_clear_object(&priv->surfaces); + priv->surfaces = gst_vaapi_surface_pool_new(priv->display, caps); + if (!priv->surfaces) + return FALSE; + } + return TRUE; +} + +static void +gst_vaapi_uploader_finalize(GObject *object) +{ + gst_vaapi_uploader_destroy(GST_VAAPI_UPLOADER_CAST(object)); + + G_OBJECT_CLASS(gst_vaapi_uploader_parent_class)->finalize(object); +} + +static void +gst_vaapi_uploader_set_property(GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + GstVaapiUploader * const uploader = GST_VAAPI_UPLOADER_CAST(object); + + switch (prop_id) { + case PROP_DISPLAY: + ensure_display(uploader, g_value_get_object(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_uploader_get_property(GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + GstVaapiUploader * const uploader = GST_VAAPI_UPLOADER_CAST(object); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_object(value, uploader->priv->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_uploader_class_init(GstVaapiUploaderClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapi_uploader, + GST_HELPER_NAME, 0, GST_HELPER_DESC); + + g_type_class_add_private(klass, sizeof(GstVaapiUploaderPrivate)); + + object_class->finalize = gst_vaapi_uploader_finalize; + object_class->set_property = gst_vaapi_uploader_set_property; + object_class->get_property = gst_vaapi_uploader_get_property; + + g_object_class_install_property( + object_class, + PROP_DISPLAY, + g_param_spec_object( + "display", + "Display", + "The GstVaapiDisplay this object is bound to", + GST_VAAPI_TYPE_DISPLAY, + G_PARAM_READWRITE)); +} + +static void +gst_vaapi_uploader_init(GstVaapiUploader *uploader) +{ + GstVaapiUploaderPrivate *priv; + + priv = GST_VAAPI_UPLOADER_GET_PRIVATE(uploader); + uploader->priv = priv; +} + +GstVaapiUploader * +gst_vaapi_uploader_new(GstVaapiDisplay *display) +{ + return g_object_new(GST_VAAPI_TYPE_UPLOADER, "display", display, NULL); +} + +gboolean +gst_vaapi_uploader_ensure_display( + GstVaapiUploader *uploader, + GstVaapiDisplay *display +) +{ + g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + + return ensure_display(uploader,display); +} + +gboolean +gst_vaapi_uploader_ensure_caps( + GstVaapiUploader *uploader, + GstCaps *src_caps, + GstCaps *out_caps +) +{ + GstVaapiUploaderPrivate *priv; + GstVaapiImage *image; + GstVaapiImageFormat vaformat; + GstVideoFormat vformat; + GstStructure *structure; + gint width, height; + + g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); + g_return_val_if_fail(src_caps != NULL, FALSE); + + if (!ensure_image_pool(uploader, src_caps)) + return FALSE; + if (!ensure_surface_pool(uploader, out_caps ? out_caps : src_caps)) + return FALSE; + + priv = uploader->priv; + + structure = gst_caps_get_structure(src_caps, 0); + if (!structure) + return FALSE; + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + + /* Translate from Gst video format to VA image format */ + if (!gst_video_format_parse_caps(src_caps, &vformat, NULL, NULL)) + return FALSE; + if (!gst_video_format_is_yuv(vformat)) + return FALSE; + vaformat = gst_vaapi_image_format_from_video(vformat); + if (!vaformat) + return FALSE; + + /* Check if we can alias source and output buffers (same data_size) */ + image = gst_vaapi_video_pool_get_object(priv->images); + if (image) { + if (gst_vaapi_image_get_format(image) == vaformat && + gst_vaapi_image_is_linear(image) && + (gst_vaapi_image_get_data_size(image) == + gst_video_format_get_size(vformat, width, height))) + priv->direct_rendering = 1; + gst_vaapi_video_pool_put_object(priv->images, image); + } + return TRUE; +} + +gboolean +gst_vaapi_uploader_process( + GstVaapiUploader *uploader, + GstBuffer *src_buffer, + GstBuffer *out_buffer +) +{ + GstVaapiVideoBuffer *out_vbuffer; + GstVaapiSurface *surface; + GstVaapiImage *image; + + g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); + + if (GST_VAAPI_IS_VIDEO_BUFFER(out_buffer)) + out_vbuffer = GST_VAAPI_VIDEO_BUFFER(out_buffer); + else if (GST_VAAPI_IS_VIDEO_BUFFER(out_buffer->parent)) + out_vbuffer = GST_VAAPI_VIDEO_BUFFER(out_buffer->parent); + else { + GST_WARNING("expected an output video buffer"); + return FALSE; + } + + surface = gst_vaapi_video_buffer_get_surface(out_vbuffer); + g_return_val_if_fail(surface != NULL, FALSE); + + if (GST_VAAPI_IS_VIDEO_BUFFER(src_buffer)) { + /* GstVaapiVideoBuffer with mapped VA image */ + image = gst_vaapi_video_buffer_get_image( + GST_VAAPI_VIDEO_BUFFER(src_buffer)); + if (!image || !gst_vaapi_image_unmap(image)) + return FALSE; + } + else if (GST_VAAPI_IS_VIDEO_BUFFER(src_buffer->parent)) { + /* Sub-buffer from GstVaapiVideoBuffer with mapped VA image */ + image = gst_vaapi_video_buffer_get_image( + GST_VAAPI_VIDEO_BUFFER(src_buffer->parent)); + if (!image || !gst_vaapi_image_unmap(image)) + return FALSE; + } + else { + /* Regular GstBuffer that needs to be uploaded to a VA image */ + image = gst_vaapi_video_buffer_get_image(out_vbuffer); + if (!image) { + image = gst_vaapi_video_pool_get_object(uploader->priv->images); + if (!image) + return FALSE; + gst_vaapi_video_buffer_set_image(out_vbuffer, image); + } + if (!gst_vaapi_image_update_from_buffer(image, src_buffer, NULL)) + return FALSE; + } + g_return_val_if_fail(image != NULL, FALSE); + + if (!gst_vaapi_surface_put_image(surface, image)) { + GST_WARNING("failed to upload YUV buffer to VA surface"); + return FALSE; + } + + /* Map again for next uploads */ + if (!gst_vaapi_image_map(image)) + return FALSE; + return TRUE; +} + +GstBuffer * +gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) +{ + GstVaapiUploaderPrivate *priv; + GstVaapiSurface *surface; + GstVaapiImage *image; + GstVaapiVideoBuffer *vbuffer; + GstBuffer *buffer = NULL; + + g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), NULL); + + priv = uploader->priv; + + buffer = gst_vaapi_video_buffer_new_from_pool(priv->images); + if (!buffer) { + GST_WARNING("failed to allocate video buffer"); + goto error; + } + vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); + + surface = gst_vaapi_video_pool_get_object(priv->surfaces); + if (!surface) { + GST_WARNING("failed to allocate VA surface"); + goto error; + } + + gst_vaapi_video_buffer_set_surface(vbuffer, surface); + + image = gst_vaapi_video_buffer_get_image(vbuffer); + if (!gst_vaapi_image_map(image)) { + GST_WARNING("failed to map VA image"); + goto error; + } + + GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0); + GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image); + + gst_buffer_set_caps(buffer, priv->image_caps); + return buffer; + +error: + gst_buffer_unref(buffer); + return buffer; +} + +gboolean +gst_vaapi_uploader_has_direct_rendering(GstVaapiUploader *uploader) +{ + g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); + + return uploader->priv->direct_rendering; +} diff --git a/gst/vaapi/gstvaapiuploader.h b/gst/vaapi/gstvaapiuploader.h new file mode 100644 index 0000000000..06f62d3957 --- /dev/null +++ b/gst/vaapi/gstvaapiuploader.h @@ -0,0 +1,111 @@ +/* + * gstvaapiuploader.h - VA-API video upload helper + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2012 Intel Corporation + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA +*/ + +#ifndef GST_VAAPIUPLOADER_H +#define GST_VAAPIUPLOADER_H + +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_UPLOADER \ + (gst_vaapi_uploader_get_type()) + +#define GST_VAAPI_UPLOADER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_UPLOADER, \ + GstVaapiUploader)) + +#define GST_VAAPI_UPLOADER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_UPLOADER, \ + GstVaapiUploaderClass)) + +#define GST_VAAPI_IS_UPLOADER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_UPLOADER)) + +#define GST_VAAPI_IS_UPLOADER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_UPLOADER)) + +#define GST_VAAPI_UPLOADER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_UPLOADER, \ + GstVaapiUploaderClass)) + +typedef struct _GstVaapiUploader GstVaapiUploader; +typedef struct _GstVaapiUploaderPrivate GstVaapiUploaderPrivate; +typedef struct _GstVaapiUploaderClass GstVaapiUploaderClass; + +struct _GstVaapiUploader { + /*< private >*/ + GObject parent_instance; + + GstVaapiUploaderPrivate *priv; +}; + +struct _GstVaapiUploaderClass { + /*< private >*/ + GObjectClass parent_class; +}; + +G_GNUC_INTERNAL +GType +gst_vaapi_uploader_get_type(void) G_GNUC_CONST; + +G_GNUC_INTERNAL +GstVaapiUploader * +gst_vaapi_uploader_new(GstVaapiDisplay *display); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_uploader_ensure_display( + GstVaapiUploader *uploader, + GstVaapiDisplay *display +); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_uploader_ensure_caps( + GstVaapiUploader *uploader, + GstCaps *src_caps, + GstCaps *out_caps +); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_uploader_process( + GstVaapiUploader *uploader, + GstBuffer *src_buffer, + GstBuffer *out_buffer +); + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_uploader_has_direct_rendering(GstVaapiUploader *uploader); + +G_END_DECLS + +#endif /* GST_VAAPI_UPLOADER_H */ From d4a4a49168bff11f94def0c2a716812db942f287 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 20 Nov 2012 15:50:56 +0100 Subject: [PATCH 0909/3781] vaapisink: compute and expose the supported set of YUV caps. Make vaapisink expose only the set of supported caps for raw YUV buffers. Add gst_vaapi_uploader_get_caps() helper function to determine the set of supported YUV caps as source (for images). This function actually tries to zero and upload each image to a 64x64 test surface. Of course, this relies on VA drivers to not claim success if vaPutImage() is not correctly supported. --- gst/vaapi/gstvaapisink.c | 33 +++++++++++++ gst/vaapi/gstvaapiuploader.c | 96 ++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiuploader.h | 4 ++ 3 files changed, 133 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 916cd8e176..b74927ab1b 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -329,6 +329,20 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink) return TRUE; } +static gboolean +gst_vaapisink_ensure_uploader(GstVaapiSink *sink) +{ + if (!gst_vaapisink_ensure_display(sink)) + return FALSE; + + if (!sink->uploader) { + sink->uploader = gst_vaapi_uploader_new(sink->display); + if (!sink->uploader) + return FALSE; + } + return TRUE; +} + static gboolean gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) { @@ -590,6 +604,24 @@ gst_vaapisink_stop(GstBaseSink *base_sink) return TRUE; } +static GstCaps * +gst_vaapisink_get_caps(GstBaseSink *base_sink) +{ + GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + GstCaps *out_caps, *yuv_caps; + + out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS); + if (!out_caps) + return NULL; + + if (gst_vaapisink_ensure_uploader(sink)) { + yuv_caps = gst_vaapi_uploader_get_caps(sink->uploader); + if (yuv_caps) + gst_caps_append(out_caps, gst_caps_copy(yuv_caps)); + } + return out_caps; +} + static gboolean gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { @@ -1045,6 +1077,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->start = gst_vaapisink_start; basesink_class->stop = gst_vaapisink_stop; + basesink_class->get_caps = gst_vaapisink_get_caps; basesink_class->set_caps = gst_vaapisink_set_caps; basesink_class->preroll = gst_vaapisink_show_frame; basesink_class->render = gst_vaapisink_show_frame; diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index d7ba1f979e..451da7183c 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -21,6 +21,7 @@ */ #include "gst/vaapi/sysdeps.h" +#include #include #include #include @@ -48,6 +49,7 @@ G_DEFINE_TYPE(GstVaapiUploader, gst_vaapi_uploader, G_TYPE_OBJECT) struct _GstVaapiUploaderPrivate { GstVaapiDisplay *display; + GstCaps *allowed_caps; GstVaapiVideoPool *images; GstCaps *image_caps; guint image_width; @@ -70,6 +72,8 @@ gst_vaapi_uploader_destroy(GstVaapiUploader *uploader) GstVaapiUploaderPrivate * const priv = uploader->priv; gst_caps_replace(&priv->image_caps, NULL); + gst_caps_replace(&priv->allowed_caps, NULL); + g_clear_object(&priv->images); g_clear_object(&priv->surfaces); g_clear_object(&priv->display); @@ -89,6 +93,88 @@ ensure_display(GstVaapiUploader *uploader, GstVaapiDisplay *display) return TRUE; } +static gboolean +ensure_image(GstVaapiImage *image) +{ + guint i, num_planes, width, height; + + /* Make the image fully dirty */ + if (!gst_vaapi_image_map(image)) + return FALSE; + + gst_vaapi_image_get_size(image, &width, &height); + + num_planes = gst_vaapi_image_get_plane_count(image); + for (i = 0; i < num_planes; i++) { + guchar * const plane = gst_vaapi_image_get_plane(image, i); + if (plane) + memset(plane, 0, height * gst_vaapi_image_get_pitch(image, i)); + } + + if (!gst_vaapi_image_unmap(image)) + gst_vaapi_image_unmap(image); + return TRUE; +} + +static gboolean +ensure_allowed_caps(GstVaapiUploader *uploader) +{ + GstVaapiUploaderPrivate * const priv = uploader->priv; + GstVaapiSurface *surface = NULL; + GstCaps *out_caps, *image_caps = NULL; + guint i, n_structures; + gboolean success = FALSE; + + enum { WIDTH = 64, HEIGHT = 64 }; + + if (priv->allowed_caps) + return TRUE; + + out_caps = gst_caps_new_empty(); + if (!out_caps) + return FALSE; + + image_caps = gst_vaapi_display_get_image_caps(priv->display); + if (!image_caps) + goto end; + + surface = gst_vaapi_surface_new(priv->display, + GST_VAAPI_CHROMA_TYPE_YUV420, WIDTH, HEIGHT); + if (!surface) + goto end; + + n_structures = gst_caps_get_size(image_caps); + for (i = 0; i < n_structures; i++) { + GstStructure * const structure = gst_caps_get_structure(image_caps, i); + GstVaapiImage *image; + GstVaapiImageFormat format; + guint32 fourcc; + + if (!gst_structure_get_fourcc(structure, "format", &fourcc)) + continue; + format = gst_vaapi_image_format_from_fourcc(fourcc); + if (!format) + continue; + image = gst_vaapi_image_new(priv->display, format, WIDTH, HEIGHT); + if (!image) + continue; + if (ensure_image(image) && gst_vaapi_surface_put_image(surface, image)) + gst_caps_append_structure(out_caps, gst_structure_copy(structure)); + gst_object_unref(image); + } + + gst_caps_replace(&priv->allowed_caps, out_caps); + success = TRUE; + +end: + gst_caps_unref(out_caps); + if (image_caps) + gst_caps_unref(image_caps); + if (surface) + gst_object_unref(surface); + return success; +} + static gboolean ensure_image_pool(GstVaapiUploader *uploader, GstCaps *caps) { @@ -340,6 +426,16 @@ gst_vaapi_uploader_process( return TRUE; } +GstCaps * +gst_vaapi_uploader_get_caps(GstVaapiUploader *uploader) +{ + g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), NULL); + + if (!ensure_allowed_caps(uploader)) + return NULL; + return uploader->priv->allowed_caps; +} + GstBuffer * gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) { diff --git a/gst/vaapi/gstvaapiuploader.h b/gst/vaapi/gstvaapiuploader.h index 06f62d3957..db2dcdbc85 100644 --- a/gst/vaapi/gstvaapiuploader.h +++ b/gst/vaapi/gstvaapiuploader.h @@ -98,6 +98,10 @@ gst_vaapi_uploader_process( GstBuffer *out_buffer ); +G_GNUC_INTERNAL +GstCaps * +gst_vaapi_uploader_get_caps(GstVaapiUploader *uploader); + G_GNUC_INTERNAL GstBuffer * gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader); From c2a610735ff2b3f7e6f7b801ec4263a5eb8359de Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Tue, 20 Nov 2012 14:32:40 +0100 Subject: [PATCH 0910/3781] vaapiupload: use new GstVaapiUploader helper. Use GstVaapiUploader helper that automatically handles direct rendering mode, thus making the "direct-rendering" property obsolete and hence it is now removed. The "direct-rendering" level 2, i.e. exposing VA surface buffers, was never really well supported and it could actually trigger degraded performance. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapiupload.c | 412 +++++-------------------------------- gst/vaapi/gstvaapiupload.h | 22 +- 2 files changed, 56 insertions(+), 378 deletions(-) diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 88b43a5ce1..44c06c0dd0 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -1,5 +1,5 @@ /* - * gstvaapiupload.c - VA-API video uploader + * gstvaapiupload.c - VA-API video upload element * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011-2012 Intel Corporation @@ -91,20 +91,6 @@ G_DEFINE_TYPE_WITH_CODE( G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init)) -/* - * Direct rendering levels (direct-rendering) - * 0: upstream allocated YUV pixels - * 1: vaapiupload allocated YUV pixels (mapped from VA image) - * 2: vaapiupload allocated YUV pixels (mapped from VA surface) - */ -#define DIRECT_RENDERING_DEFAULT 2 - -enum { - PROP_0, - - PROP_DIRECT_RENDERING, -}; - static gboolean gst_vaapiupload_start(GstBaseTransform *trans); @@ -186,8 +172,12 @@ static void gst_vaapiupload_set_video_context(GstVideoContext *context, const gchar *type, const GValue *value) { - GstVaapiUpload *upload = GST_VAAPIUPLOAD (context); - gst_vaapi_set_display (type, value, &upload->display); + GstVaapiUpload * const upload = GST_VAAPIUPLOAD(context); + + gst_vaapi_set_display(type, value, &upload->display); + + if (upload->uploader) + gst_vaapi_uploader_ensure_display(upload->uploader, upload->display); } static void @@ -199,8 +189,7 @@ gst_video_context_interface_init(GstVideoContextInterface *iface) static void gst_vaapiupload_destroy(GstVaapiUpload *upload) { - g_clear_object(&upload->images); - g_clear_object(&upload->surfaces); + g_clear_object(&upload->uploader); g_clear_object(&upload->display); } @@ -212,49 +201,6 @@ gst_vaapiupload_finalize(GObject *object) G_OBJECT_CLASS(gst_vaapiupload_parent_class)->finalize(object); } - -static void -gst_vaapiupload_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiUpload * const upload = GST_VAAPIUPLOAD(object); - - switch (prop_id) { - case PROP_DIRECT_RENDERING: - GST_OBJECT_LOCK(upload); - upload->direct_rendering = g_value_get_uint(value); - GST_OBJECT_UNLOCK(upload); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapiupload_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiUpload * const upload = GST_VAAPIUPLOAD(object); - - switch (prop_id) { - case PROP_DIRECT_RENDERING: - g_value_set_uint(value, upload->direct_rendering); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - static void gst_vaapiupload_class_init(GstVaapiUploadClass *klass) { @@ -267,8 +213,6 @@ gst_vaapiupload_class_init(GstVaapiUploadClass *klass) GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapiupload_finalize; - object_class->set_property = gst_vaapiupload_set_property; - object_class->get_property = gst_vaapiupload_get_property; trans_class->start = gst_vaapiupload_start; trans_class->stop = gst_vaapiupload_stop; @@ -295,35 +239,6 @@ gst_vaapiupload_class_init(GstVaapiUploadClass *klass) pad_template = gst_static_pad_template_get(&gst_vaapiupload_src_factory); gst_element_class_add_pad_template(element_class, pad_template); gst_object_unref(pad_template); - - /** - * GstVaapiUpload:direct-rendering: - * - * Selects the direct rendering level. - * - * - * Disables direct rendering. - * - * - * Enables direct rendering to the output buffer. i.e. this - * tries to use a single buffer for both sink and src pads. - * - * - * Enables direct rendering to the underlying surface. i.e. with - * drivers supporting vaDeriveImage(), the output surface pixels - * will be modified directly. - * - * - */ - g_object_class_install_property - (object_class, - PROP_DIRECT_RENDERING, - g_param_spec_uint("direct-rendering", - "Direct rendering", - "Direct rendering level", - 0, 2, - DIRECT_RENDERING_DEFAULT, - G_PARAM_READWRITE)); } static void @@ -331,18 +246,6 @@ gst_vaapiupload_init(GstVaapiUpload *upload) { GstPad *sinkpad, *srcpad; - upload->display = NULL; - upload->images = NULL; - upload->images_reset = FALSE; - upload->image_width = 0; - upload->image_height = 0; - upload->surfaces = NULL; - upload->surfaces_reset = FALSE; - upload->surface_width = 0; - upload->surface_height = 0; - upload->direct_rendering_caps = 0; - upload->direct_rendering = G_MAXUINT32; - /* Override buffer allocator on sink pad */ sinkpad = gst_element_get_static_pad(GST_ELEMENT(upload), "sink"); gst_pad_set_bufferalloc_function( @@ -365,12 +268,28 @@ gst_vaapiupload_ensure_display(GstVaapiUpload *upload) &upload->display); } +static gboolean +gst_vaapiupload_ensure_uploader(GstVaapiUpload *upload) +{ + if (!gst_vaapiupload_ensure_display(upload)) + return FALSE; + + if (!upload->uploader) { + upload->uploader = gst_vaapi_uploader_new(upload->display); + if (!upload->uploader) + return FALSE; + } + if (!gst_vaapi_uploader_ensure_display(upload->uploader, upload->display)) + return FALSE; + return TRUE; +} + static gboolean gst_vaapiupload_start(GstBaseTransform *trans) { GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - if (!gst_vaapiupload_ensure_display(upload)) + if (!gst_vaapiupload_ensure_uploader(upload)) return FALSE; return TRUE; } @@ -393,55 +312,10 @@ gst_vaapiupload_transform( ) { GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - GstVaapiVideoBuffer *vbuffer; - GstVaapiSurface *surface; - GstVaapiImage *image; - gboolean success; - vbuffer = GST_VAAPI_VIDEO_BUFFER(outbuf); - surface = gst_vaapi_video_buffer_get_surface(vbuffer); - if (!surface) + if (!gst_vaapi_uploader_process(upload->uploader, inbuf, outbuf)) return GST_FLOW_UNEXPECTED; - - if (upload->direct_rendering) { - if (!GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) { - GST_DEBUG("GstVaapiVideoBuffer was expected"); - return GST_FLOW_UNEXPECTED; - } - - vbuffer = GST_VAAPI_VIDEO_BUFFER(inbuf); - image = gst_vaapi_video_buffer_get_image(vbuffer); - if (!image) - return GST_FLOW_UNEXPECTED; - if (!gst_vaapi_image_unmap(image)) - return GST_FLOW_UNEXPECTED; - - if (upload->direct_rendering < 2) { - if (!gst_vaapi_surface_put_image(surface, image)) - goto error_put_image; - } - return GST_FLOW_OK; - } - - image = gst_vaapi_video_pool_get_object(upload->images); - if (!image) - return GST_FLOW_UNEXPECTED; - - gst_vaapi_image_update_from_buffer(image, inbuf, NULL); - success = gst_vaapi_surface_put_image(surface, image); - gst_vaapi_video_pool_put_object(upload->images, image); - if (!success) - goto error_put_image; return GST_FLOW_OK; - -error_put_image: - { - GST_WARNING("failed to upload %" GST_FOURCC_FORMAT " image " - "to surface 0x%08x", - GST_FOURCC_ARGS(gst_vaapi_image_get_format(image)), - gst_vaapi_surface_get_id(surface)); - return GST_FLOW_OK; - } } static GstCaps * @@ -495,139 +369,6 @@ gst_vaapiupload_transform_caps( return out_caps; } -static gboolean -gst_vaapiupload_ensure_image_pool(GstVaapiUpload *upload, GstCaps *caps) -{ - GstStructure * const structure = gst_caps_get_structure(caps, 0); - gint width, height; - - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); - - if (width != upload->image_width || height != upload->image_height) { - upload->image_width = width; - upload->image_height = height; - g_clear_object(&upload->images); - upload->images = gst_vaapi_image_pool_new(upload->display, caps); - if (!upload->images) - return FALSE; - upload->images_reset = TRUE; - } - return TRUE; -} - -static gboolean -gst_vaapiupload_ensure_surface_pool(GstVaapiUpload *upload, GstCaps *caps) -{ - GstStructure * const structure = gst_caps_get_structure(caps, 0); - gint width, height; - - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); - - if (width != upload->surface_width || height != upload->surface_height) { - upload->surface_width = width; - upload->surface_height = height; - g_clear_object(&upload->surfaces); - upload->surfaces = gst_vaapi_surface_pool_new(upload->display, caps); - if (!upload->surfaces) - return FALSE; - upload->surfaces_reset = TRUE; - } - return TRUE; -} - -static void -gst_vaapiupload_ensure_direct_rendering_caps( - GstVaapiUpload *upload, - GstCaps *caps -) -{ - GstVaapiSurface *surface; - GstVaapiImage *image; - GstVaapiImageFormat vaformat; - GstVideoFormat vformat; - GstStructure *structure; - gint width, height; - - if (!upload->images_reset && !upload->surfaces_reset) - return; - - upload->images_reset = FALSE; - upload->surfaces_reset = FALSE; - upload->direct_rendering_caps = 0; - - structure = gst_caps_get_structure(caps, 0); - if (!structure) - return; - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); - - /* Translate from Gst video format to VA image format */ - if (!gst_video_format_parse_caps(caps, &vformat, NULL, NULL)) - return; - if (!gst_video_format_is_yuv(vformat)) - return; - vaformat = gst_vaapi_image_format_from_video(vformat); - if (!vaformat) - return; - - /* Check if we can alias sink & output buffers (same data_size) */ - image = gst_vaapi_video_pool_get_object(upload->images); - if (image) { - if (upload->direct_rendering_caps == 0 && - (gst_vaapi_image_get_format(image) == vaformat && - gst_vaapi_image_is_linear(image) && - (gst_vaapi_image_get_data_size(image) == - gst_video_format_get_size(vformat, width, height)))) - upload->direct_rendering_caps = 1; - gst_vaapi_video_pool_put_object(upload->images, image); - } - - /* Check if we can access to the surface pixels directly */ - surface = gst_vaapi_video_pool_get_object(upload->surfaces); - if (surface) { - image = gst_vaapi_surface_derive_image(surface); - if (image) { - if (gst_vaapi_image_map(image)) { - if (upload->direct_rendering_caps == 1 && - (gst_vaapi_image_get_format(image) == vaformat && - gst_vaapi_image_is_linear(image) && - (gst_vaapi_image_get_data_size(image) == - gst_video_format_get_size(vformat, width, height)))) - upload->direct_rendering_caps = 2; - gst_vaapi_image_unmap(image); - } - g_object_unref(image); - } - gst_vaapi_video_pool_put_object(upload->surfaces, surface); - } -} - -static gboolean -gst_vaapiupload_negotiate_buffers( - GstVaapiUpload *upload, - GstCaps *incaps, - GstCaps *outcaps -) -{ - guint dr; - - if (!gst_vaapiupload_ensure_image_pool(upload, incaps)) - return FALSE; - - if (!gst_vaapiupload_ensure_surface_pool(upload, outcaps)) - return FALSE; - - gst_vaapiupload_ensure_direct_rendering_caps(upload, incaps); - dr = MIN(upload->direct_rendering, upload->direct_rendering_caps); - if (upload->direct_rendering != dr) { - upload->direct_rendering = dr; - GST_DEBUG("direct-rendering level: %d", dr); - } - return TRUE; -} - static gboolean gst_vaapiupload_set_caps( GstBaseTransform *trans, @@ -637,9 +378,8 @@ gst_vaapiupload_set_caps( { GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - if (!gst_vaapiupload_negotiate_buffers(upload, incaps, outcaps)) + if (!gst_vaapi_uploader_ensure_caps(upload->uploader, incaps, outcaps)) return FALSE; - return TRUE; } @@ -673,64 +413,19 @@ gst_vaapiupload_buffer_alloc( ) { GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - GstBuffer *buffer = NULL; - GstVaapiImage *image = NULL; - GstVaapiSurface *surface = NULL; - GstVaapiVideoBuffer *vbuffer; - /* Check if we can use direct-rendering */ - if (!gst_vaapiupload_negotiate_buffers(upload, caps, caps)) - goto error; - if (!upload->direct_rendering) + *pbuf = NULL; + + if (!gst_vaapi_uploader_ensure_display(upload->uploader, upload->display)) + return GST_FLOW_NOT_SUPPORTED; + if (!gst_vaapi_uploader_ensure_caps(upload->uploader, caps, NULL)) + return GST_FLOW_NOT_SUPPORTED; + + /* Allocate a regular GstBuffer if direct rendering is not supported */ + if (!gst_vaapi_uploader_has_direct_rendering(upload->uploader)) return GST_FLOW_OK; - switch (upload->direct_rendering) { - case 2: - buffer = gst_vaapi_video_buffer_new_from_pool(upload->surfaces); - if (!buffer) - goto error; - vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); - - surface = gst_vaapi_video_buffer_get_surface(vbuffer); - image = gst_vaapi_surface_derive_image(surface); - if (image && gst_vaapi_image_get_data_size(image) == size) { - gst_vaapi_video_buffer_set_image(vbuffer, image); - g_object_unref(image); /* video buffer owns an extra reference */ - break; - } - - /* We can't use the derive-image optimization. Disable it. */ - upload->direct_rendering = 1; - gst_buffer_unref(buffer); - buffer = NULL; - - case 1: - buffer = gst_vaapi_video_buffer_new_from_pool(upload->images); - if (!buffer) - goto error; - vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); - - image = gst_vaapi_video_buffer_get_image(vbuffer); - break; - } - g_assert(image); - - if (!gst_vaapi_image_map(image)) - goto error; - - GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0); - GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image); - - gst_buffer_set_caps(buffer, caps); - *pbuf = buffer; - return GST_FLOW_OK; - -error: - /* We can't use the inout-buffers optimization. Disable it. */ - GST_DEBUG("disable in/out buffer optimization"); - if (buffer) - gst_buffer_unref(buffer); - upload->direct_rendering = 0; + *pbuf = gst_vaapi_uploader_get_buffer(upload->uploader); return GST_FLOW_OK; } @@ -765,25 +460,24 @@ gst_vaapiupload_prepare_output_buffer( ) { GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - GstBuffer *buffer = NULL; + GstBuffer *buffer; - if (upload->direct_rendering == 2) { - if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) { - buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf); - GST_BUFFER_SIZE(buffer) = size; - } - else { - GST_DEBUG("upstream element destroyed our in/out buffer"); - upload->direct_rendering = 1; - } - } + *poutbuf = NULL; - if (!buffer) { - buffer = gst_vaapi_video_buffer_new_from_pool(upload->surfaces); - if (!buffer) - return GST_FLOW_UNEXPECTED; - gst_buffer_set_caps(buffer, caps); - } + if (!gst_vaapi_uploader_has_direct_rendering(upload->uploader)) + buffer = gst_vaapi_uploader_get_buffer(upload->uploader); + else if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) + buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf); + else if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf->parent)) + buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf->parent); + else + buffer = NULL; + if (!buffer) + return GST_FLOW_UNEXPECTED; + + gst_buffer_set_caps(buffer, caps); + GST_BUFFER_DATA(buffer) = NULL; + GST_BUFFER_SIZE(buffer) = 0; *poutbuf = buffer; return GST_FLOW_OK; diff --git a/gst/vaapi/gstvaapiupload.h b/gst/vaapi/gstvaapiupload.h index 386a62c3c2..cb22036a33 100644 --- a/gst/vaapi/gstvaapiupload.h +++ b/gst/vaapi/gstvaapiupload.h @@ -1,5 +1,5 @@ /* - * gstvaapiupload.h - VA-API video uploader + * gstvaapiupload.h - VA-API video upload element * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011-2012 Intel Corporation @@ -24,11 +24,7 @@ #define GST_VAAPIUPLOAD_H #include -#include -#include -#include -#include -#include +#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -59,24 +55,12 @@ G_BEGIN_DECLS typedef struct _GstVaapiUpload GstVaapiUpload; typedef struct _GstVaapiUploadClass GstVaapiUploadClass; -/* Max output surfaces */ -#define GST_VAAPIUPLOAD_MAX_SURFACES 2 - struct _GstVaapiUpload { /*< private >*/ GstBaseTransform parent_instance; GstVaapiDisplay *display; - GstVaapiVideoPool *images; - guint image_width; - guint image_height; - GstVaapiVideoPool *surfaces; - guint surface_width; - guint surface_height; - guint direct_rendering_caps; - guint direct_rendering; - unsigned int images_reset : 1; - unsigned int surfaces_reset : 1; + GstVaapiUploader *uploader; }; struct _GstVaapiUploadClass { From 237a4adb0cdf4aa6a12c6de1bede4e7f8bb1d796 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 20 Nov 2012 14:42:24 +0100 Subject: [PATCH 0911/3781] vaapiupload: fix sink caps to report the supported set of YUV caps. Try to allocate the GstVaapiUploader helper object prior to listing the supported image formats. Otherwise, only a single generic caps is output with no particular pixel format referenced in there. --- gst/vaapi/gstvaapiupload.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 44c06c0dd0..19209684fd 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -350,13 +350,12 @@ gst_vaapiupload_transform_caps( if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) return NULL; out_caps = gst_caps_from_string(gst_vaapiupload_yuv_caps_str); - if (upload->display) { + if (gst_vaapiupload_ensure_uploader(upload)) { GstCaps *allowed_caps, *inter_caps; - allowed_caps = gst_vaapi_display_get_image_caps(upload->display); + allowed_caps = gst_vaapi_uploader_get_caps(upload->uploader); if (!allowed_caps) return NULL; inter_caps = gst_caps_intersect(out_caps, allowed_caps); - gst_caps_unref(allowed_caps); gst_caps_unref(out_caps); out_caps = inter_caps; } From df1eb6e01e1bf76e23c8eb7d219f15804b109d2d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 20 Nov 2012 18:21:41 +0100 Subject: [PATCH 0912/3781] vaapiupload: reset direct-rendering to zero when changing caps. Make sure to reset direct-rendering flag to zero when caps are changed, and only derive it to one when the next checks succeed. --- gst/vaapi/gstvaapiuploader.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 451da7183c..e6bf74dd20 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -333,6 +333,7 @@ gst_vaapi_uploader_ensure_caps( return FALSE; priv = uploader->priv; + priv->direct_rendering = 0; structure = gst_caps_get_structure(src_caps, 0); if (!structure) From 1d669a3e123075b1ba1e0d89f8635d818d0ae9e6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 17 Dec 2012 04:15:53 -0800 Subject: [PATCH 0913/3781] libs: only export gst_vaapi_*() symbols. This fixes symbol clashes between the gst-vaapi built-in codecparsers/ library and the system-provided one, mainly used by videoparses/. Now, only symbols with the gst_vaapi_* prefix will be exported, if they are not marked as "hidden" to libgstvaapi. --- gst-libs/gst/vaapi/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 313d5500c2..8eb2235f4c 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -220,6 +220,7 @@ libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ libgstvaapi_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ + -export-symbols-regex "^gst_.*vaapi.*" \ $(NULL) libgstvaapi_drm_@GST_MAJORMINOR@_la_SOURCES = \ From 97c3b2ddffbf87fef4f037f0b0fcb6fec273dbab Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 17 Dec 2012 10:10:55 +0100 Subject: [PATCH 0914/3781] libs: use glib >= 2.32 semantics for mutexes. Use glib >= 2.32 semantics for GMutex and GRecMutex wrt. initialization and termination. Basically, the new mutex objects can be used as static mutex objects from the deprecated APIs, e.g. GStaticMutex and GStaticRecMutex. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplaycache.c | 22 +++++++++++----------- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 11 ++++------- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 40ac5a65cf..35a3d57c69 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -725,7 +725,7 @@ gst_vaapi_display_lock_default(GstVaapiDisplay *display) if (priv->parent) priv = priv->parent->priv; - g_static_rec_mutex_lock(&priv->mutex); + g_rec_mutex_lock(&priv->mutex); } static void @@ -735,7 +735,7 @@ gst_vaapi_display_unlock_default(GstVaapiDisplay *display) if (priv->parent) priv = priv->parent->priv; - g_static_rec_mutex_unlock(&priv->mutex); + g_rec_mutex_unlock(&priv->mutex); } static void @@ -745,7 +745,7 @@ gst_vaapi_display_finalize(GObject *object) gst_vaapi_display_destroy(display); - g_static_rec_mutex_free(&display->priv->mutex); + g_rec_mutex_clear(&display->priv->mutex); G_OBJECT_CLASS(gst_vaapi_display_parent_class)->finalize(object); } @@ -998,7 +998,7 @@ gst_vaapi_display_init(GstVaapiDisplay *display) priv->properties = NULL; priv->create_display = TRUE; - g_static_rec_mutex_init(&priv->mutex); + g_rec_mutex_init(&priv->mutex); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index ac0555e3d6..cb5302b063 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -73,7 +73,7 @@ G_BEGIN_DECLS */ struct _GstVaapiDisplayPrivate { GstVaapiDisplay *parent; - GStaticRecMutex mutex; + GRecMutex mutex; GstVaapiDisplayType display_type; VADisplay display; guint width; diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index 0e6ef36c62..5f5ae8d410 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -33,7 +33,7 @@ struct _CacheEntry { }; struct _GstVaapiDisplayCache { - GStaticMutex mutex; + GMutex mutex; GList *list; }; @@ -86,14 +86,14 @@ error: #define CACHE_LOOKUP(cache, res, prop, comp_func, comp_data, user_data) do { \ GList *l; \ \ - g_static_mutex_lock(&(cache)->mutex); \ + g_mutex_lock(&(cache)->mutex); \ for (l = (cache)->list; l != NULL; l = l->next) { \ GstVaapiDisplayInfo * const info = \ &((CacheEntry *)l->data)->info; \ if (comp_func(info->prop, comp_data, user_data)) \ break; \ } \ - g_static_mutex_unlock(&(cache)->mutex); \ + g_mutex_unlock(&(cache)->mutex); \ res = l; \ } while (0) @@ -146,7 +146,7 @@ gst_vaapi_display_cache_new(void) if (!cache) return NULL; - g_static_mutex_init(&cache->mutex); + g_mutex_init(&cache->mutex); return cache; } @@ -170,7 +170,7 @@ gst_vaapi_display_cache_free(GstVaapiDisplayCache *cache) g_list_free(cache->list); cache->list = NULL; } - g_static_mutex_free(&cache->mutex); + g_mutex_clear(&cache->mutex); g_slice_free(GstVaapiDisplayCache, cache); } @@ -189,9 +189,9 @@ gst_vaapi_display_cache_get_size(GstVaapiDisplayCache *cache) g_return_val_if_fail(cache != NULL, 0); - g_static_mutex_lock(&cache->mutex); + g_mutex_lock(&cache->mutex); size = g_list_length(cache->list); - g_static_mutex_unlock(&cache->mutex); + g_mutex_unlock(&cache->mutex); return size; } @@ -220,9 +220,9 @@ gst_vaapi_display_cache_add( if (!entry) return FALSE; - g_static_mutex_lock(&cache->mutex); + g_mutex_lock(&cache->mutex); cache->list = g_list_prepend(cache->list, entry); - g_static_mutex_unlock(&cache->mutex); + g_mutex_unlock(&cache->mutex); return TRUE; } @@ -246,9 +246,9 @@ gst_vaapi_display_cache_remove( return; cache_entry_free(m->data); - g_static_mutex_lock(&cache->mutex); + g_mutex_lock(&cache->mutex); cache->list = g_list_delete_link(cache->list, m); - g_static_mutex_unlock(&cache->mutex); + g_mutex_unlock(&cache->mutex); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 9a742ca109..4788c95b41 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -741,16 +741,13 @@ gl_init_vtable(void) GLVTable * gl_get_vtable(void) { - static GStaticMutex mutex = G_STATIC_MUTEX_INIT; - static gboolean gl_vtable_init = TRUE; + static gsize gl_vtable_init = FALSE; static GLVTable *gl_vtable = NULL; - g_static_mutex_lock(&mutex); - if (gl_vtable_init) { - gl_vtable_init = FALSE; - gl_vtable = gl_init_vtable(); + if (g_once_init_enter(&gl_vtable_init)) { + gl_vtable = gl_init_vtable(); + g_once_init_leave(&gl_vtable_init, TRUE); } - g_static_mutex_unlock(&mutex); return gl_vtable; } From 48f4f0564e45a5dcbf7e3543fff590943c6581e1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 17 Dec 2012 09:41:24 +0100 Subject: [PATCH 0915/3781] libs: fix compatibility with glib 2.28. Always prefer non deprecated APIs by default and provide compatibility glue for older glib versions when necessary. --- gst-libs/gst/vaapi/glibcompat.h | 93 ++++++++++++++++++++++++--------- gst/vaapi/gstvaapi.c | 6 +-- 2 files changed, 70 insertions(+), 29 deletions(-) diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 0a6115c913..6c1f8f4e7a 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -25,6 +25,13 @@ #include #include +#define G_COMPAT_DEFINE(new_api, new_args, old_api, old_args) \ +static inline void \ +new_api new_args \ +{ \ + old_api old_args; \ +} + #if !GLIB_CHECK_VERSION(2,27,2) static inline void g_list_free_full(GList *list, GDestroyNotify free_func) @@ -52,31 +59,39 @@ g_clear_object_inline(volatile GObject **object_ptr) #define g_clear_object(obj) g_clear_object_inline((volatile GObject **)(obj)) #endif -#if GLIB_CHECK_VERSION(2,31,2) -#define GStaticMutex GMutex -#undef g_static_mutex_init -#define g_static_mutex_init(mutex) g_mutex_init(mutex) -#undef g_static_mutex_free -#define g_static_mutex_free(mutex) g_mutex_clear(mutex) -#undef g_static_mutex_lock -#define g_static_mutex_lock(mutex) g_mutex_lock(mutex) -#undef g_static_mutex_unlock -#define g_static_mutex_unlock(mutex) g_mutex_unlock(mutex) - -#define GStaticRecMutex GRecMutex -#undef g_static_rec_mutex_init -#define g_static_rec_mutex_init(mutex) g_rec_mutex_init(mutex) -#undef g_static_rec_mutex_free -#define g_static_rec_mutex_free(mutex) g_rec_mutex_clear(mutex) -#undef g_static_rec_mutex_lock -#define g_static_rec_mutex_lock(mutex) g_rec_mutex_lock(mutex) -#undef g_static_rec_mutex_unlock -#define g_static_rec_mutex_unlock(m) g_rec_mutex_unlock(m) -#endif - #if !GLIB_CHECK_VERSION(2,31,2) +typedef GStaticMutex GCompatMutex; +G_COMPAT_DEFINE(g_compat_mutex_init, (GCompatMutex *mutex), + g_static_mutex_init, (mutex)) +G_COMPAT_DEFINE(g_compat_mutex_clear, (GCompatMutex *mutex), + g_static_mutex_free, (mutex)) +G_COMPAT_DEFINE(g_compat_mutex_lock, (GCompatMutex *mutex), + g_static_mutex_lock, (mutex)) +G_COMPAT_DEFINE(g_compat_mutex_unlock, (GCompatMutex *mutex), + g_static_mutex_unlock, (mutex)) + +typedef GStaticRecMutex GCompatRecMutex; +G_COMPAT_DEFINE(g_compat_rec_mutex_init, (GCompatRecMutex *mutex), + g_static_rec_mutex_init, (mutex)) +G_COMPAT_DEFINE(g_compat_rec_mutex_clear, (GCompatRecMutex *mutex), + g_static_rec_mutex_free, (mutex)) +G_COMPAT_DEFINE(g_compat_rec_mutex_lock, (GCompatRecMutex *mutex), + g_static_rec_mutex_lock, (mutex)) +G_COMPAT_DEFINE(g_compat_rec_mutex_unlock, (GCompatRecMutex *mutex), + g_static_rec_mutex_unlock, (mutex)) + +typedef GCond *GCompatCond; +G_COMPAT_DEFINE(g_compat_cond_init, (GCompatCond *cond), + *cond = g_cond_new, ()) +G_COMPAT_DEFINE(g_compat_cond_clear, (GCompatCond *cond), + if (*cond) g_cond_free, (*cond)) +G_COMPAT_DEFINE(g_compat_cond_signal, (GCompatCond *cond), + g_cond_signal, (*cond)) +G_COMPAT_DEFINE(g_compat_cond_broadcast, (GCompatCond *cond), + g_cond_broadcast, (*cond)) + static inline gboolean -g_cond_wait_until(GCond *cond, GMutex *mutex, gint64 end_time) +g_cond_wait_until(GCompatCond *cond, GStaticMutex *mutex, gint64 end_time) { gint64 diff_time; GTimeVal timeout; @@ -84,8 +99,38 @@ g_cond_wait_until(GCond *cond, GMutex *mutex, gint64 end_time) diff_time = end_time - g_get_monotonic_time(); g_get_current_time(&timeout); g_time_val_add(&timeout, diff_time > 0 ? diff_time : 0); - return g_cond_timed_wait(cond, mutex, &timeout); + return g_cond_timed_wait(*cond, g_static_mutex_get_mutex(mutex), &timeout); } + +#define GMutex GCompatMutex +#undef g_mutex_init +#define g_mutex_init(mutex) g_compat_mutex_init(mutex) +#undef g_mutex_clear +#define g_mutex_clear(mutex) g_compat_mutex_clear(mutex) +#undef g_mutex_lock +#define g_mutex_lock(mutex) g_compat_mutex_lock(mutex) +#undef g_mutex_unlock +#define g_mutex_unlock(mutex) g_compat_mutex_unlock(mutex) + +#define GRecMutex GCompatRecMutex +#undef g_rec_mutex_init +#define g_rec_mutex_init(mutex) g_compat_rec_mutex_init(mutex) +#undef g_rec_mutex_clear +#define g_rec_mutex_clear(mutex) g_compat_rec_mutex_clear(mutex) +#undef g_rec_mutex_lock +#define g_rec_mutex_lock(mutex) g_compat_rec_mutex_lock(mutex) +#undef g_rec_mutex_unlock +#define g_rec_mutex_unlock(mutex) g_compat_rec_mutex_unlock(mutex) + +#define GCond GCompatCond +#undef g_cond_init +#define g_cond_init(cond) g_compat_cond_init(cond) +#undef g_cond_clear +#define g_cond_clear(cond) g_compat_cond_clear(cond) +#undef g_cond_signal +#define g_cond_signal(cond) g_compat_cond_signal(cond) #endif +#undef G_COMPAT_DEFINE + #endif /* GLIB_COMPAT_H */ diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 5e115c4799..5a6462f9d1 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -21,12 +21,8 @@ * Boston, MA 02110-1301 USA */ -#ifdef HAVE_CONFIG_H -#include -#endif - +#include "gst/vaapi/sysdeps.h" #include - #include "gstvaapidownload.h" #include "gstvaapiupload.h" #include "gstvaapidecode.h" From 4c01e25a1593e419b0b37ecdf3fae833120bcad6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 17 Dec 2012 14:27:56 +0100 Subject: [PATCH 0916/3781] configure: downgrade glib required version to 2.28. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 0a27282d00..0f6adda7be 100644 --- a/configure.ac +++ b/configure.ac @@ -11,8 +11,8 @@ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) # glib version number m4_define([glib_major_version], [2]) -m4_define([glib_minor_version], [31]) -m4_define([glib_micro_version], [2]) +m4_define([glib_minor_version], [28]) +m4_define([glib_micro_version], [0]) m4_define([glib_major_minor_version], [glib_major_version.glib_minor_version]) m4_define([glib_version], From 8e8dc03677d8a244d8631715f9aea4fff7fc2b1c Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Wed, 5 Dec 2012 09:15:32 +0800 Subject: [PATCH 0917/3781] configure: install plugin elements in GST_PLUGIN_PATH, if set. If GST_PLUGIN_PATH environment variable exists and points to a valid directory, then use it as the system installation path for gst-vaapi plugin elements. Signed-off-by: Gwenole Beauchesne --- configure.ac | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 0f6adda7be..256608aa81 100644 --- a/configure.ac +++ b/configure.ac @@ -295,11 +295,15 @@ GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^([_]*gst_plug AC_SUBST(GST_PLUGIN_LDFLAGS) dnl Check for the GStreamer plugins directory +AC_ARG_VAR([GST_PLUGIN_PATH], [installation path for gstreamer-vaapi plugin elements]) AC_MSG_CHECKING([for GStreamer plugins directory]) -GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_MAJORMINOR --variable pluginsdir` -if test -z "$GST_PLUGINS_DIR"; then - echo "FAIL FAIL FAIL" - GST_PLUGINS_DIR="\$(libdir)/gstreamer-$GST_MAJORMINOR" +if test -d "$GST_PLUGIN_PATH"; then + GST_PLUGINS_DIR="$GST_PLUGIN_PATH" +else + GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_MAJORMINOR --variable pluginsdir` + if test -z "$GST_PLUGINS_DIR"; then + GST_PLUGINS_DIR="\$(libdir)/gstreamer-$GST_MAJORMINOR" + fi fi AC_MSG_RESULT([$GST_PLUGINS_DIR]) plugindir="$GST_PLUGINS_DIR" From 1bd5ab4db379cacbfadaa74537aa2fc7ee3b2569 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 17 Dec 2012 04:42:29 -0800 Subject: [PATCH 0918/3781] h264: initialize VA context before allocating the first slice. Fix decode_slice() to ensure a VA context exists prior to creating a new GstVaapiSliceH264, which invokes vaCreateBuffer() with some VA context ID. i.e. the latter was not initialized, thus causing failures on Cedar Trail for example. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 34 +++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 4426d81711..3f8bb84419 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -515,6 +515,9 @@ struct _GstVaapiDecoderH264Private { /* Last decoded PPS. May not be the last activated one. Just here because it may not fit stack memory allocation in decode_pps() */ GstH264PPS last_pps; + /* Temporary slice header. Just here because it may not fit stack + memory allocation in decode_slice() */ + GstH264SliceHdr temp_slice_hdr; GstVaapiPictureH264 *current_picture; GstVaapiFrameStore *prev_frame; GstVaapiFrameStore *dpb[16]; @@ -2863,9 +2866,25 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) GstVaapiSliceH264 *slice = NULL; GstH264SliceHdr *slice_hdr; GstH264ParserResult result; + gboolean is_first_slice = !priv->has_context; GST_DEBUG("slice (%u bytes)", nalu->size); + if (is_first_slice) { + slice_hdr = &priv->temp_slice_hdr; + memset(slice_hdr, 0, sizeof(*slice_hdr)); + result = gst_h264_parser_parse_slice_hdr(priv->parser, nalu, + slice_hdr, TRUE, TRUE); + if (result != GST_H264_PARSER_OK) { + status = get_status(result); + goto error; + } + + status = ensure_context(decoder, slice_hdr->pps->sequence); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + slice = gst_vaapi_slice_h264_new( decoder, nalu->data + nalu->offset, @@ -2877,11 +2896,16 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) } slice_hdr = &slice->slice_hdr; - memset(slice_hdr, 0, sizeof(*slice_hdr)); - result = gst_h264_parser_parse_slice_hdr(priv->parser, nalu, slice_hdr, TRUE, TRUE); - if (result != GST_H264_PARSER_OK) { - status = get_status(result); - goto error; + if (is_first_slice) + memcpy(slice_hdr, &priv->temp_slice_hdr, sizeof(*slice_hdr)); + else { + memset(slice_hdr, 0, sizeof(*slice_hdr)); + result = gst_h264_parser_parse_slice_hdr(priv->parser, nalu, + slice_hdr, TRUE, TRUE); + if (result != GST_H264_PARSER_OK) { + status = get_status(result); + goto error; + } } if (is_new_picture(decoder, nalu, slice_hdr)) { From 0e5895c31847607f54b84477dac298c7ff2cf4f2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 17 Dec 2012 02:51:17 -0800 Subject: [PATCH 0919/3781] tests: add test for MPEG-4:2 decoding. --- tests/Makefile.am | 8 +- tests/test-decode.c | 6 + tests/test-mpeg4.c | 1672 +++++++++++++++++++++++++++++++++++++++++++ tests/test-mpeg4.h | 30 + 4 files changed, 1715 insertions(+), 1 deletion(-) create mode 100644 tests/test-mpeg4.c create mode 100644 tests/test-mpeg4.h diff --git a/tests/Makefile.am b/tests/Makefile.am index 4c8edbbc8a..314afa951e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -56,7 +56,13 @@ TEST_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-@GST_MAJORMINOR@.la endif -test_codecs_source_c = test-mpeg2.c test-h264.c test-vc1.c test-jpeg.c +test_codecs_source_c = \ + test-h264.c \ + test-jpeg.c \ + test-mpeg2.c \ + test-mpeg4.c \ + test-vc1.c \ + $(NULL) test_codecs_source_h = $(test_codecs_source_c:%.c=%.h) test-decode.h test_utils_source_c = image.c output.c $(test_codecs_source_c) diff --git a/tests/test-decode.c b/tests/test-decode.c index a425f822a0..458416e623 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -27,9 +27,11 @@ #include #include #include +#include #include #include "test-jpeg.h" #include "test-mpeg2.h" +#include "test-mpeg4.h" #include "test-h264.h" #include "test-vc1.h" #include "output.h" @@ -49,6 +51,7 @@ static const CodecDefs g_codec_defs[] = { #define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info } INIT_FUNCS(jpeg), INIT_FUNCS(mpeg2), + INIT_FUNCS(mpeg4), INIT_FUNCS(h264), INIT_FUNCS(vc1), #undef INIT_FUNCS @@ -150,6 +153,9 @@ main(int argc, char *argv[]) case GST_VAAPI_CODEC_MPEG2: decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); break; + case GST_VAAPI_CODEC_MPEG4: + decoder = gst_vaapi_decoder_mpeg4_new(display, decoder_caps); + break; case GST_VAAPI_CODEC_VC1: decoder = gst_vaapi_decoder_vc1_new(display, decoder_caps); break; diff --git a/tests/test-mpeg4.c b/tests/test-mpeg4.c new file mode 100644 index 0000000000..13984ba0a1 --- /dev/null +++ b/tests/test-mpeg4.c @@ -0,0 +1,1672 @@ +/* + * test-mpeg4.c - MPEG-4 test data + * + * Copyright (C) 2012 Intel Corporation + * + * 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 "test-mpeg4.h" + +#define MPEG4_CLIP_WIDTH 320 +#define MPEG4_CLIP_HEIGHT 240 +#define MPEG4_CLIP_DATA_SIZE 19592 + +/* Data dump of a 320x240 MPEG-4 video clip (mpeg4.m4v), it has a single frame */ +static const guchar mpeg4_clip[MPEG4_CLIP_DATA_SIZE] = { + 0x00, 0x00, 0x01, 0xb0, 0x01, 0x00, 0x00, 0x01, 0xb5, 0x89, 0x13, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0xc4, 0x8d, 0x88, 0x00, + 0xcd, 0x0a, 0x04, 0x1e, 0x14, 0x43, 0x00, 0x00, 0x01, 0xb2, 0x4c, 0x61, + 0x76, 0x63, 0x35, 0x34, 0x2e, 0x36, 0x32, 0x2e, 0x31, 0x30, 0x30, 0x00, + 0x00, 0x01, 0xb3, 0x00, 0x10, 0x07, 0x00, 0x00, 0x01, 0xb6, 0x10, 0x60, + 0x85, 0x85, 0x41, 0x08, 0x78, 0xab, 0x44, 0x81, 0x29, 0x06, 0xd1, 0xd2, + 0x4d, 0xe9, 0x2d, 0x55, 0xe0, 0x95, 0x36, 0x42, 0x10, 0x71, 0xfc, 0xa0, + 0x4f, 0x8b, 0x9a, 0x0a, 0xd8, 0x84, 0xca, 0x81, 0x18, 0x48, 0x80, 0xf0, + 0xd0, 0x0b, 0x97, 0x12, 0x83, 0x01, 0x47, 0x13, 0x97, 0x59, 0xfe, 0x22, + 0x5b, 0x9d, 0x88, 0xfb, 0x38, 0x46, 0x2e, 0x29, 0x11, 0x39, 0xb3, 0x7a, + 0x08, 0x02, 0x5f, 0x16, 0xf6, 0x52, 0x8d, 0x3e, 0x33, 0x2f, 0x12, 0x04, + 0xb5, 0x5d, 0xa0, 0x88, 0xcd, 0xe2, 0xeb, 0x7a, 0xd9, 0xc0, 0x61, 0x30, + 0xbd, 0x4e, 0xce, 0x8a, 0xb8, 0xe6, 0xbf, 0x14, 0x43, 0xed, 0x8d, 0xd8, + 0x4d, 0x74, 0x47, 0x69, 0x5b, 0x23, 0x9c, 0xb5, 0xad, 0x82, 0x06, 0xfb, + 0xfe, 0x9d, 0xec, 0x5d, 0x70, 0x49, 0x0b, 0xca, 0x95, 0x5f, 0xb3, 0xec, + 0x0e, 0x6c, 0x0c, 0xdc, 0x68, 0x7b, 0xfc, 0x0f, 0xad, 0xbe, 0xcd, 0xd2, + 0x58, 0xbf, 0x38, 0x4e, 0x30, 0x2e, 0x49, 0x7c, 0x95, 0x52, 0xb9, 0x3a, + 0xc2, 0xfa, 0x69, 0x46, 0xf1, 0x14, 0x0e, 0x48, 0xd3, 0xa5, 0xa0, 0xc2, + 0x6f, 0x29, 0x19, 0x61, 0x21, 0xaf, 0x0e, 0x32, 0x79, 0x06, 0x49, 0x06, + 0x10, 0xf1, 0xb1, 0xef, 0x51, 0xf3, 0xa7, 0x14, 0x0f, 0xf2, 0x90, 0xaa, + 0x3d, 0xde, 0xcb, 0x20, 0x71, 0xd1, 0x35, 0x30, 0x86, 0xc3, 0x21, 0x7f, + 0xff, 0x70, 0xd2, 0xf4, 0x96, 0xac, 0xb1, 0x19, 0xff, 0x5f, 0xfe, 0xf3, + 0x0a, 0xc3, 0x94, 0x0b, 0x10, 0xe6, 0xe7, 0x55, 0x54, 0x36, 0x6d, 0x2a, + 0x35, 0x2d, 0x27, 0xa9, 0xd9, 0xb3, 0x7c, 0x37, 0x71, 0x85, 0x96, 0x2c, + 0x2e, 0xdc, 0x6a, 0xd9, 0x9c, 0x51, 0xfe, 0x4a, 0x8a, 0xd2, 0x90, 0x13, + 0x02, 0x19, 0x72, 0x86, 0x33, 0xf9, 0x11, 0x0c, 0x77, 0x2f, 0x57, 0x79, + 0xc6, 0x9b, 0x2b, 0x8a, 0x79, 0x36, 0xf0, 0xa9, 0x15, 0xa4, 0xae, 0x11, + 0x0e, 0x73, 0xe5, 0xca, 0x35, 0x74, 0x03, 0x2a, 0x41, 0x9b, 0xab, 0x53, + 0xe5, 0x9e, 0x11, 0x8b, 0x69, 0x7b, 0x45, 0x9a, 0xa2, 0x94, 0xf2, 0x14, + 0x50, 0x5b, 0x0a, 0x1b, 0x4a, 0x9e, 0xdd, 0x6b, 0x53, 0x52, 0xcf, 0x23, + 0x57, 0x37, 0xca, 0x0d, 0x2c, 0x0b, 0x50, 0xc7, 0x60, 0xe3, 0xf6, 0x44, + 0x1a, 0x1e, 0x0d, 0x4a, 0x79, 0xa9, 0x8c, 0x66, 0xed, 0x2a, 0x6f, 0x23, + 0x73, 0x39, 0x6d, 0x5e, 0x77, 0xa1, 0xa6, 0x1f, 0xdb, 0xe8, 0x0c, 0x97, + 0x8b, 0x38, 0xd6, 0xfd, 0x5e, 0x16, 0x7a, 0x67, 0x77, 0xb7, 0xab, 0x0a, + 0x46, 0xfb, 0xf1, 0x05, 0x62, 0xcd, 0xc2, 0xec, 0x11, 0x14, 0xa8, 0xa2, + 0x07, 0x39, 0xdb, 0x03, 0x96, 0x74, 0xa8, 0x18, 0x4e, 0x3f, 0x12, 0x53, + 0xff, 0xff, 0x9e, 0xff, 0xc1, 0x59, 0x9a, 0x1e, 0x68, 0x89, 0xbf, 0x5d, + 0x7e, 0x08, 0xba, 0xa4, 0x3a, 0xc0, 0x62, 0x0a, 0xd6, 0x94, 0xb5, 0x3d, + 0x2d, 0x62, 0x4b, 0x3f, 0x57, 0xed, 0x05, 0x7f, 0xfe, 0x1e, 0x29, 0x0d, + 0x00, 0xa7, 0x4c, 0xe6, 0x16, 0xd7, 0x96, 0x5a, 0x6f, 0xae, 0x35, 0xcc, + 0xcf, 0x4b, 0xb9, 0x1a, 0x5b, 0xb5, 0x44, 0x0e, 0xcb, 0x20, 0x71, 0x9c, + 0x50, 0xa4, 0x18, 0x84, 0xaa, 0x0b, 0xea, 0xb5, 0xa3, 0x3e, 0x14, 0x82, + 0xdd, 0x14, 0x8a, 0x38, 0xb0, 0x7b, 0xf5, 0x11, 0x42, 0x91, 0xbd, 0xec, + 0x96, 0x9e, 0x68, 0xba, 0xa6, 0xdb, 0xb4, 0xd0, 0xd8, 0xa6, 0x86, 0xea, + 0x01, 0xf3, 0x7f, 0xfb, 0xd8, 0xf9, 0x68, 0xe5, 0x51, 0xd5, 0x3d, 0xe6, + 0x62, 0xeb, 0x95, 0x71, 0xd5, 0x69, 0x6a, 0x8d, 0x8b, 0x29, 0x47, 0x10, + 0xd8, 0x0c, 0x0b, 0xab, 0x68, 0x71, 0xf6, 0xa7, 0x17, 0x9d, 0xa8, 0xca, + 0xed, 0xe2, 0xcb, 0xbd, 0x3a, 0xb5, 0x86, 0x94, 0x48, 0x50, 0x73, 0xcf, + 0xb6, 0x70, 0x4b, 0xfe, 0xb4, 0xab, 0x6b, 0x19, 0x9a, 0xda, 0x89, 0x3d, + 0x9b, 0xd9, 0x2d, 0xb7, 0x8b, 0xd0, 0xd0, 0xf9, 0xa6, 0x81, 0xba, 0x59, + 0x39, 0x33, 0xb0, 0xa8, 0xb2, 0x95, 0xd9, 0x10, 0x2e, 0x0c, 0x13, 0x48, + 0xee, 0x96, 0x0e, 0x2d, 0xcb, 0x71, 0x72, 0xb8, 0xba, 0xf5, 0x01, 0xea, + 0xc6, 0x7a, 0xdc, 0xf7, 0x91, 0xe8, 0xc0, 0x4e, 0x92, 0x75, 0xc2, 0xf9, + 0x42, 0xc6, 0xd8, 0xf7, 0xea, 0xc1, 0x13, 0x14, 0xdc, 0x94, 0xb6, 0x4d, + 0x99, 0x9c, 0xbc, 0x2c, 0x5d, 0x71, 0x38, 0xc7, 0xe9, 0x44, 0x05, 0x0d, + 0x30, 0x1d, 0xad, 0x3a, 0x13, 0x17, 0x65, 0x36, 0xf0, 0xaf, 0x67, 0xed, + 0x83, 0x6e, 0x2c, 0x50, 0x7d, 0x3c, 0x1f, 0x2a, 0x03, 0x6d, 0x0e, 0x6e, + 0xe2, 0xea, 0x79, 0x50, 0xea, 0x38, 0xe1, 0x6f, 0x7f, 0xde, 0x9c, 0x32, + 0x99, 0xb0, 0x9d, 0xb1, 0x73, 0x03, 0xc2, 0xf0, 0xfe, 0x07, 0xaa, 0x64, + 0xf6, 0x29, 0xd4, 0x59, 0x10, 0xd9, 0x20, 0x8b, 0xaa, 0x6b, 0xc2, 0xfb, + 0x4d, 0x07, 0x85, 0x9d, 0xee, 0x76, 0xd3, 0x53, 0xb5, 0x15, 0x78, 0x97, + 0xd7, 0xeb, 0x20, 0xe8, 0x2e, 0x53, 0xcb, 0xc8, 0x74, 0x62, 0xea, 0x9b, + 0x4e, 0x53, 0xe5, 0x9b, 0xaa, 0x19, 0x2d, 0xcd, 0xf4, 0x2d, 0x6b, 0x6a, + 0xe6, 0xf8, 0xa6, 0x5b, 0x41, 0x6e, 0x36, 0xd6, 0xcb, 0x3f, 0xdf, 0x87, + 0x41, 0xd5, 0x43, 0xab, 0xd5, 0xb8, 0x1b, 0x29, 0x3c, 0x7d, 0x2f, 0xef, + 0x59, 0xbe, 0xe7, 0x4b, 0x7f, 0xce, 0xac, 0x8a, 0xdd, 0x3c, 0x74, 0x42, + 0x2f, 0x64, 0x47, 0xf3, 0x3a, 0xad, 0x55, 0x85, 0x89, 0x59, 0x6b, 0x25, + 0x97, 0x30, 0xb3, 0xd5, 0x6a, 0x56, 0x0e, 0x05, 0x48, 0x24, 0x36, 0x79, + 0x34, 0x43, 0x30, 0xcc, 0x56, 0x9d, 0x6d, 0xbb, 0x33, 0x17, 0xb2, 0x73, + 0x90, 0x92, 0x43, 0xc2, 0xba, 0x47, 0x98, 0x9d, 0x67, 0x03, 0x47, 0xe2, + 0xb5, 0xad, 0xb3, 0xe5, 0xdb, 0x62, 0x37, 0xea, 0x6e, 0x45, 0x84, 0xc3, + 0x05, 0x2b, 0x09, 0xdd, 0x93, 0x38, 0xde, 0xf1, 0xb8, 0x81, 0x15, 0xe8, + 0x9c, 0xa0, 0x22, 0xa3, 0xef, 0x50, 0xa8, 0x19, 0x10, 0xac, 0xad, 0x7d, + 0xce, 0x8a, 0x8f, 0x9f, 0x4a, 0x89, 0xd1, 0xb3, 0x2d, 0xb7, 0xdb, 0xda, + 0x48, 0x35, 0x32, 0xcb, 0x30, 0xf0, 0xec, 0x1a, 0x97, 0x8e, 0xd3, 0x09, + 0x1b, 0xf1, 0x22, 0x75, 0x5e, 0x37, 0xe1, 0x10, 0x73, 0x4b, 0x0a, 0xe5, + 0xb3, 0xc1, 0xc9, 0x10, 0x64, 0xc0, 0x64, 0xad, 0x52, 0xc6, 0x0b, 0xfb, + 0xef, 0xff, 0xd8, 0x5b, 0xf8, 0x36, 0x9b, 0x62, 0xf3, 0xf0, 0x44, 0x01, + 0x36, 0x1b, 0x05, 0xa4, 0x3e, 0xd8, 0x30, 0xc1, 0x4a, 0x0c, 0x39, 0x03, + 0x7f, 0x56, 0x3c, 0x56, 0x55, 0xbd, 0x05, 0x62, 0xca, 0x51, 0xea, 0xf0, + 0xa8, 0xe8, 0xcd, 0x26, 0x83, 0x37, 0x9b, 0x8a, 0xf1, 0xbb, 0xe4, 0x41, + 0xdf, 0xfd, 0x32, 0xc4, 0x7c, 0xb2, 0x07, 0x20, 0xc2, 0x65, 0xc4, 0xb1, + 0xdb, 0x71, 0xbc, 0x03, 0x4a, 0xb5, 0x29, 0x68, 0xdb, 0x73, 0xb7, 0x38, + 0x8a, 0x71, 0x40, 0x9a, 0xfe, 0x90, 0x14, 0x25, 0xe1, 0xea, 0xec, 0x4e, + 0xad, 0x85, 0xb1, 0xae, 0x0c, 0x94, 0xa9, 0x06, 0x1a, 0x94, 0xde, 0xb5, + 0x78, 0x1e, 0xff, 0x41, 0x85, 0x4d, 0xbc, 0x36, 0x2d, 0x6c, 0x2f, 0x30, + 0x0c, 0xc8, 0x8e, 0xc6, 0xcf, 0x0f, 0x44, 0x60, 0x30, 0x8a, 0xab, 0x4d, + 0x6e, 0xce, 0x9b, 0xe6, 0x88, 0x84, 0x62, 0xf6, 0x41, 0x46, 0xd0, 0xe1, + 0xb4, 0xfe, 0x67, 0x2f, 0x98, 0xca, 0xa7, 0x14, 0xcb, 0xaa, 0x78, 0x86, + 0x08, 0x80, 0x24, 0x39, 0x27, 0x08, 0x41, 0x05, 0x89, 0x59, 0xfc, 0xff, + 0xd6, 0xee, 0xee, 0x33, 0x7f, 0x78, 0x6e, 0x95, 0xa9, 0x3c, 0x33, 0xc5, + 0x37, 0x7a, 0xbe, 0xd1, 0x9b, 0xc6, 0x54, 0x9e, 0x72, 0xd1, 0x51, 0x69, + 0x0e, 0xbd, 0x28, 0x84, 0x10, 0xaf, 0x3b, 0x41, 0x8b, 0x07, 0x83, 0x28, + 0x08, 0x82, 0xc4, 0xd5, 0x31, 0x37, 0xbb, 0x37, 0x96, 0x6f, 0x22, 0xdd, + 0x5a, 0x23, 0x71, 0x92, 0xe4, 0xaa, 0x44, 0x81, 0x19, 0xaf, 0x49, 0x14, + 0x0e, 0x87, 0x92, 0xd4, 0x36, 0xc5, 0x5e, 0x71, 0x75, 0x58, 0xa1, 0xac, + 0x95, 0x65, 0xa7, 0x45, 0x3f, 0x11, 0x3a, 0xd6, 0xff, 0x31, 0xab, 0x9a, + 0xbf, 0x46, 0x47, 0x15, 0x61, 0x4f, 0x2d, 0x40, 0x0b, 0xf9, 0xb7, 0x0a, + 0x4f, 0x25, 0x6c, 0xe2, 0x94, 0x50, 0x17, 0xdb, 0x36, 0x74, 0x77, 0xa5, + 0xab, 0x01, 0x00, 0xa1, 0x11, 0xe3, 0x2a, 0x58, 0xe7, 0x60, 0x79, 0x6b, + 0x91, 0xa9, 0xb1, 0x47, 0xd9, 0xb0, 0xae, 0xf4, 0x65, 0xda, 0xb0, 0x30, + 0xd0, 0xc1, 0x77, 0xe7, 0x76, 0x72, 0x42, 0xde, 0x02, 0x3c, 0xec, 0xaf, + 0x63, 0x15, 0xd6, 0x7b, 0x76, 0x64, 0x0b, 0x55, 0xd5, 0xf7, 0x88, 0x05, + 0xe4, 0xae, 0x7f, 0xc5, 0x2c, 0x5c, 0x24, 0x5c, 0x50, 0x6f, 0x5b, 0x9e, + 0x37, 0x78, 0x13, 0x44, 0x6c, 0x56, 0xdf, 0xbd, 0xc5, 0x05, 0x85, 0x55, + 0x62, 0x61, 0xef, 0xd5, 0x28, 0xbb, 0x37, 0x2e, 0x59, 0x69, 0x47, 0x0d, + 0x9f, 0xa8, 0x24, 0xaa, 0xe4, 0x52, 0xa6, 0x5e, 0xc4, 0x04, 0x22, 0xd4, + 0xac, 0xe7, 0xf2, 0xdb, 0x17, 0xfd, 0xf1, 0x66, 0xdc, 0xea, 0xd3, 0xb9, + 0xc0, 0x71, 0x98, 0x46, 0x6a, 0x9e, 0x1f, 0x6f, 0xd1, 0xe6, 0xff, 0xca, + 0x51, 0x07, 0x14, 0x84, 0x32, 0xa5, 0xfb, 0x75, 0x57, 0x35, 0x7d, 0x63, + 0x64, 0xa8, 0x2f, 0x10, 0x57, 0x1c, 0x6e, 0x2b, 0xf7, 0xfc, 0x58, 0xa5, + 0xb6, 0x24, 0x91, 0x9c, 0x35, 0x40, 0x88, 0x64, 0x0c, 0x35, 0x54, 0x7b, + 0x26, 0x7f, 0x39, 0x24, 0x53, 0xe2, 0xb2, 0x83, 0x4f, 0x48, 0x71, 0x0f, + 0xb7, 0x23, 0xef, 0xfb, 0xf6, 0x36, 0x97, 0x4a, 0xa7, 0xf1, 0x4d, 0x24, + 0x8b, 0x2e, 0x0c, 0x12, 0xda, 0x56, 0xf5, 0x4e, 0xea, 0x9c, 0x8a, 0x8b, + 0x20, 0xe3, 0x8b, 0xad, 0xc5, 0xb9, 0x04, 0x55, 0x38, 0x09, 0x63, 0x6f, + 0xf7, 0xca, 0x73, 0x06, 0xc5, 0xa8, 0x91, 0xce, 0x71, 0x60, 0xcc, 0x18, + 0x2a, 0x1f, 0x88, 0xcd, 0xff, 0xea, 0xa7, 0xa1, 0x5f, 0xfc, 0x06, 0x27, + 0x44, 0x46, 0x2a, 0xf3, 0xe0, 0x49, 0x6c, 0x13, 0xcf, 0xe1, 0x11, 0x82, + 0xd2, 0xe2, 0x30, 0x39, 0xb5, 0x0c, 0x9d, 0x52, 0xa6, 0x2f, 0x2c, 0xa8, + 0xbb, 0xaa, 0x77, 0x1a, 0xc1, 0xb2, 0x8c, 0x06, 0x23, 0x45, 0xb9, 0xa8, + 0x91, 0xcb, 0x2c, 0xf7, 0x8b, 0x24, 0x9d, 0x06, 0x37, 0xf0, 0xd3, 0x01, + 0x82, 0x91, 0x59, 0x67, 0xa4, 0xcc, 0xfc, 0xcd, 0xb4, 0x45, 0x11, 0x25, + 0x46, 0x88, 0x2d, 0x31, 0x7d, 0x0a, 0xa2, 0x35, 0xb9, 0x6a, 0xeb, 0x40, + 0x26, 0x28, 0x34, 0xc7, 0xde, 0x49, 0x51, 0xc4, 0x5f, 0xee, 0x14, 0x53, + 0x88, 0x6a, 0xd1, 0x4a, 0xf6, 0x02, 0xa1, 0x75, 0xcd, 0x1e, 0xea, 0x24, + 0xf1, 0x42, 0xc4, 0xab, 0x1c, 0x36, 0xce, 0x6f, 0x5a, 0xa5, 0xab, 0xfb, + 0xb6, 0x48, 0x55, 0x6a, 0xcb, 0x2c, 0x22, 0xa1, 0x06, 0x1a, 0xf0, 0xbf, + 0x2e, 0x20, 0x40, 0x72, 0x7d, 0xea, 0xde, 0x8c, 0x46, 0x88, 0xb1, 0x6e, + 0xe1, 0x5f, 0xb9, 0x56, 0xea, 0x0d, 0x29, 0x80, 0xb5, 0x22, 0x91, 0x6c, + 0xbf, 0x36, 0xb0, 0x9b, 0x90, 0xe9, 0x40, 0xa3, 0xea, 0xb3, 0xed, 0x4f, + 0x54, 0x73, 0x85, 0x22, 0x61, 0xc0, 0xe2, 0xa6, 0x6e, 0x95, 0x41, 0xc8, + 0x89, 0xf0, 0xcc, 0x11, 0xf0, 0xfa, 0x25, 0x87, 0x61, 0xdb, 0xb7, 0xd1, + 0xb5, 0x7b, 0x65, 0xb0, 0x3d, 0xcd, 0xd5, 0x84, 0x01, 0x8f, 0xd4, 0x8a, + 0x84, 0xfb, 0x72, 0x6f, 0x96, 0xee, 0x8b, 0xc8, 0xa3, 0x31, 0x48, 0x22, + 0x28, 0xe4, 0x93, 0xb7, 0x70, 0xdd, 0x27, 0x9e, 0xf5, 0x3f, 0xe6, 0x20, + 0xdb, 0xc1, 0x98, 0x26, 0x8d, 0x13, 0x98, 0xab, 0x4a, 0xeb, 0xae, 0xf2, + 0xea, 0x15, 0x89, 0x05, 0x46, 0x93, 0xb6, 0x58, 0x93, 0xf5, 0x0d, 0x8a, + 0x21, 0x4b, 0xea, 0xea, 0x81, 0xba, 0x33, 0x83, 0x11, 0xea, 0x79, 0xa5, + 0x51, 0x14, 0x81, 0x5b, 0x0b, 0xa6, 0x6b, 0x2a, 0xc3, 0x51, 0x7f, 0xb6, + 0xad, 0x60, 0x88, 0xa4, 0x60, 0xe7, 0x08, 0x94, 0x2d, 0x51, 0xee, 0xce, + 0xe6, 0xe6, 0x95, 0x14, 0xf7, 0xbd, 0x0a, 0x55, 0xca, 0x9a, 0x98, 0xdc, + 0xfc, 0x0b, 0x6f, 0x12, 0xa8, 0xb5, 0xb9, 0xc9, 0xff, 0x7e, 0xb5, 0xc4, + 0x71, 0x42, 0x0a, 0x1a, 0x99, 0xa5, 0x5f, 0x9c, 0xd5, 0x28, 0xef, 0x41, + 0x1e, 0xd2, 0x33, 0x58, 0x3c, 0xc0, 0x36, 0xcb, 0x2b, 0xda, 0xa3, 0x16, + 0x43, 0x62, 0x3b, 0xf9, 0x01, 0x82, 0xb2, 0xd4, 0x58, 0x7e, 0xa6, 0x47, + 0xe5, 0xf1, 0x56, 0x23, 0x85, 0x70, 0x6d, 0x88, 0x23, 0xcf, 0x6a, 0x79, + 0x14, 0xff, 0x6c, 0x92, 0x77, 0x76, 0xf5, 0x6e, 0x13, 0x8d, 0xeb, 0x19, + 0xa1, 0xec, 0xb6, 0xce, 0x1b, 0x38, 0xbb, 0x6a, 0x62, 0x9b, 0xe9, 0x36, + 0x56, 0xb7, 0xca, 0x34, 0xdd, 0x42, 0x1a, 0x23, 0x06, 0x1a, 0xba, 0x82, + 0x68, 0xd8, 0xf5, 0x28, 0x20, 0xee, 0x33, 0x14, 0x44, 0x8d, 0xa6, 0x6f, + 0xfe, 0x91, 0x5e, 0xa7, 0x8c, 0x2d, 0x78, 0xb4, 0x8a, 0x3f, 0xad, 0xe9, + 0xd1, 0x1e, 0xfc, 0x2b, 0x0c, 0xad, 0x0e, 0xf0, 0x4a, 0x2f, 0x10, 0x04, + 0x90, 0x40, 0xc6, 0xb0, 0xb6, 0xdf, 0x25, 0xcc, 0xac, 0xdc, 0xb6, 0xf2, + 0x7f, 0xb4, 0x6f, 0x81, 0xb6, 0x16, 0x16, 0x77, 0x01, 0x8e, 0x08, 0xc2, + 0x0a, 0xb1, 0xfd, 0x49, 0xbe, 0x12, 0xbf, 0x14, 0xfe, 0x5d, 0x9f, 0xde, + 0xa9, 0x92, 0xca, 0x1e, 0x40, 0xe3, 0x43, 0x50, 0x7c, 0xef, 0xfe, 0xe2, + 0x3c, 0x58, 0x12, 0xb3, 0x60, 0xb6, 0x6d, 0x54, 0xe2, 0x4a, 0xaf, 0xb6, + 0xca, 0x46, 0xbf, 0x35, 0xb5, 0x4b, 0xb3, 0xe4, 0x39, 0x6a, 0x20, 0x60, + 0xa8, 0x36, 0x02, 0x0a, 0x68, 0xa8, 0x7b, 0xfd, 0xc0, 0xe9, 0x9e, 0xfe, + 0x06, 0xbd, 0x0f, 0x60, 0x30, 0xd4, 0x19, 0x2d, 0x25, 0x4e, 0x3e, 0x2f, + 0x10, 0x6d, 0xd1, 0x07, 0xdf, 0xd1, 0x06, 0x7f, 0xb6, 0xdb, 0xde, 0x7e, + 0x7f, 0xa4, 0x69, 0x08, 0xe3, 0xff, 0x0f, 0xf7, 0xd5, 0xa9, 0x73, 0x32, + 0x55, 0xa8, 0x73, 0xfa, 0xa6, 0xf0, 0x36, 0x0b, 0x4e, 0xdb, 0xd8, 0x78, + 0xeb, 0xa7, 0xe8, 0x32, 0x0c, 0x5a, 0xac, 0x11, 0x3c, 0x9a, 0x37, 0xfc, + 0x9e, 0xb5, 0x16, 0xd9, 0xdc, 0xa8, 0x2f, 0x03, 0x80, 0x9c, 0xc5, 0x65, + 0xbd, 0x1b, 0xff, 0xf4, 0x09, 0xda, 0x70, 0xe8, 0xa0, 0x20, 0x01, 0xef, + 0x89, 0x35, 0x4d, 0x2a, 0x55, 0x29, 0x5e, 0x9b, 0xa6, 0x9c, 0x36, 0xed, + 0x89, 0x82, 0x00, 0x8e, 0x93, 0xd2, 0x30, 0x3b, 0xf7, 0x5a, 0xf7, 0x7f, + 0x8d, 0xc2, 0xdb, 0xaa, 0x6d, 0x5e, 0x7d, 0x46, 0xa9, 0xdc, 0x50, 0x22, + 0x02, 0xd8, 0x15, 0x82, 0x36, 0x09, 0x1f, 0x60, 0xb4, 0x79, 0x18, 0x10, + 0x3e, 0x0c, 0x1c, 0x49, 0x95, 0x4a, 0x1b, 0x4a, 0x82, 0xd1, 0x3b, 0x22, + 0x10, 0x34, 0x4d, 0x0b, 0x13, 0xff, 0x1a, 0xd5, 0x00, 0xc6, 0xfb, 0xf0, + 0x60, 0x4d, 0x0c, 0x42, 0x11, 0x78, 0x21, 0x01, 0xef, 0xab, 0xfb, 0x03, + 0xd6, 0x5b, 0x10, 0x71, 0x42, 0x8b, 0xef, 0xf1, 0x6a, 0xa6, 0x72, 0x8e, + 0x3d, 0x81, 0xb0, 0x31, 0x1c, 0x3c, 0x52, 0xe6, 0x1f, 0x00, 0x00, 0x8a, + 0x08, 0x6c, 0x46, 0x25, 0x2c, 0x3c, 0x1e, 0x03, 0xc3, 0xc0, 0x1e, 0x9a, + 0x8c, 0x1a, 0x70, 0x55, 0xba, 0xb6, 0x14, 0x3a, 0x44, 0xa9, 0x28, 0xe8, + 0x4a, 0x9d, 0xef, 0xf5, 0x22, 0xa5, 0x89, 0x22, 0xa8, 0x46, 0xaf, 0xdb, + 0xf1, 0x6c, 0x62, 0x76, 0xee, 0x2a, 0xc5, 0x2b, 0x15, 0x22, 0x84, 0x22, + 0xee, 0x14, 0x88, 0x9d, 0x74, 0xb9, 0xbe, 0x40, 0x5d, 0x55, 0x5e, 0xc0, + 0x5c, 0x5d, 0xff, 0x16, 0x42, 0xfd, 0xd2, 0xc9, 0xc8, 0xbe, 0xd1, 0x91, + 0xd9, 0xdd, 0x36, 0x05, 0xb7, 0x03, 0x6b, 0xc1, 0x93, 0x94, 0x2e, 0x55, + 0x31, 0x55, 0xbc, 0x5f, 0xff, 0xac, 0x92, 0xf2, 0xc9, 0x0f, 0x47, 0xa2, + 0x33, 0xe4, 0x9c, 0xb5, 0x32, 0xb9, 0x9b, 0xe4, 0x62, 0x83, 0xa3, 0xfc, + 0xcf, 0x6c, 0xe8, 0xd9, 0x9e, 0xf0, 0x52, 0xf4, 0x44, 0x0d, 0x60, 0x4e, + 0x78, 0x0f, 0xff, 0xa9, 0xe6, 0x45, 0xd4, 0x39, 0x9f, 0x96, 0x32, 0x6d, + 0x22, 0x3e, 0x13, 0x25, 0x89, 0xbf, 0x61, 0x77, 0xad, 0xf6, 0x4f, 0xe6, + 0xc0, 0xf5, 0x17, 0x57, 0xfc, 0xbd, 0x0e, 0x77, 0x0f, 0x8b, 0xd8, 0xfe, + 0x36, 0xab, 0x21, 0x65, 0xf3, 0x2a, 0x14, 0x75, 0x1c, 0x34, 0x5b, 0xc1, + 0x14, 0xc3, 0x56, 0xaa, 0x2b, 0xbe, 0x53, 0xb7, 0xad, 0x0c, 0x97, 0x27, + 0x66, 0x3c, 0x5c, 0xea, 0xad, 0x55, 0xdc, 0xc6, 0xc0, 0xa2, 0x95, 0x05, + 0xbc, 0x58, 0xd4, 0x06, 0x09, 0x06, 0xc9, 0xdb, 0xf6, 0x35, 0x65, 0x69, + 0x4b, 0x3f, 0xd5, 0xb5, 0x1f, 0x2a, 0x1e, 0x95, 0x00, 0x9d, 0x7a, 0x85, + 0x7a, 0xb1, 0x5a, 0x1e, 0x49, 0xc7, 0x20, 0x3f, 0xf7, 0x1b, 0xbb, 0xc4, + 0x7d, 0x18, 0x90, 0x97, 0xc8, 0x79, 0xb1, 0x96, 0x96, 0x2d, 0x35, 0x6d, + 0x9c, 0x24, 0xed, 0x36, 0xec, 0x39, 0x92, 0xa9, 0x6b, 0x6c, 0xa6, 0xe2, + 0xd6, 0x3c, 0x8a, 0xa0, 0xfb, 0x12, 0xa9, 0x56, 0xd4, 0xff, 0xaa, 0xc4, + 0xbe, 0x05, 0x4c, 0x0d, 0xc1, 0x2d, 0x97, 0xa4, 0xf3, 0x4c, 0xa8, 0xd8, + 0x5a, 0xd1, 0x57, 0x34, 0x36, 0xb3, 0xb2, 0x83, 0x0d, 0x32, 0xdf, 0x13, + 0x21, 0xf6, 0xc5, 0xaa, 0x80, 0xfd, 0x1b, 0x25, 0xc2, 0xd4, 0x45, 0x70, + 0x6f, 0x2c, 0x45, 0x5e, 0x2b, 0x53, 0x8c, 0xe7, 0x73, 0x9f, 0x8a, 0x25, + 0x1c, 0xa2, 0x92, 0xd8, 0x8c, 0x35, 0xc0, 0x5a, 0x2e, 0xd8, 0x91, 0xd0, + 0xf4, 0x7d, 0xdb, 0xeb, 0xc2, 0xc4, 0x1e, 0xb5, 0x0f, 0xba, 0x0c, 0x83, + 0x70, 0x12, 0x07, 0x62, 0x10, 0xf4, 0x18, 0xb1, 0x96, 0x7c, 0xaf, 0xd4, + 0xb3, 0xe1, 0xdf, 0xb5, 0x1f, 0xa9, 0xb9, 0x01, 0x2e, 0xd8, 0x69, 0xc6, + 0xb7, 0x93, 0x48, 0xad, 0x36, 0xb3, 0x93, 0xa1, 0xdf, 0xd0, 0xa0, 0x40, + 0x46, 0xa2, 0x4e, 0xff, 0xf7, 0xfc, 0xb3, 0x25, 0x29, 0x94, 0x4e, 0x17, + 0xf2, 0x2f, 0x8c, 0xb5, 0xc2, 0xcf, 0xe0, 0x7b, 0x71, 0x7c, 0x6e, 0x58, + 0xb7, 0x01, 0x82, 0x42, 0xca, 0xb9, 0x25, 0xc9, 0x92, 0x4c, 0x44, 0x68, + 0xf1, 0x83, 0x4d, 0x92, 0x45, 0x28, 0xd5, 0x06, 0xaf, 0x54, 0x03, 0x90, + 0x90, 0xfd, 0x20, 0x18, 0x32, 0x3b, 0x83, 0xa8, 0x36, 0xad, 0xef, 0xf9, + 0xe6, 0x3d, 0x03, 0x9b, 0x3a, 0x08, 0xc6, 0x24, 0x9d, 0xb1, 0xc4, 0xb4, + 0x42, 0xdc, 0x37, 0xf8, 0xd4, 0xbd, 0x20, 0x1d, 0xfd, 0x3e, 0x6b, 0x36, + 0xd5, 0xe0, 0x50, 0x75, 0x9f, 0xa7, 0xdb, 0xe0, 0x45, 0x58, 0x3c, 0xbf, + 0x45, 0xc9, 0x0f, 0x0f, 0x70, 0x7a, 0x5a, 0x24, 0xb3, 0x27, 0x4b, 0x27, + 0xb1, 0x74, 0x1c, 0xf1, 0x55, 0x5c, 0x68, 0x4f, 0x9a, 0x2d, 0xe8, 0x2d, + 0x8b, 0xdc, 0x53, 0x8f, 0x6d, 0x01, 0xce, 0x61, 0x6b, 0x3d, 0xe0, 0x2b, + 0x20, 0xc7, 0x84, 0xc3, 0xa2, 0xe1, 0xfe, 0x45, 0x62, 0x0a, 0x94, 0x7f, + 0xa3, 0x0a, 0x7c, 0xa0, 0x32, 0x9f, 0x52, 0xd6, 0x00, 0xa5, 0xca, 0xba, + 0x0a, 0xbc, 0x40, 0x1c, 0x02, 0xde, 0xa0, 0x8c, 0x39, 0x0f, 0x55, 0x7f, + 0x9f, 0xf8, 0x14, 0xfd, 0x2a, 0x99, 0x45, 0x65, 0xcf, 0x4c, 0xe8, 0xe6, + 0x02, 0x49, 0x89, 0x3d, 0x70, 0x3b, 0x8a, 0x1e, 0xd9, 0x5d, 0x1e, 0x88, + 0x3f, 0x2c, 0x95, 0x1a, 0x23, 0x5d, 0x26, 0x5d, 0xbc, 0xd2, 0xdb, 0x10, + 0xb8, 0xff, 0x87, 0x57, 0xb6, 0x02, 0x2f, 0xae, 0x7b, 0x61, 0x6e, 0xf8, + 0xae, 0x4d, 0x35, 0x00, 0x4a, 0xa5, 0xe2, 0x5b, 0x5e, 0x66, 0xe5, 0x6c, + 0xb7, 0xf9, 0x6b, 0x55, 0x41, 0x5c, 0x9b, 0x39, 0xd9, 0xd1, 0xb3, 0x5a, + 0xbc, 0x2d, 0xc2, 0x53, 0x07, 0xb7, 0x32, 0x11, 0x0b, 0x99, 0x6c, 0xab, + 0x43, 0xcf, 0x96, 0x46, 0x5b, 0xe1, 0x62, 0x35, 0x12, 0xf7, 0x78, 0x80, + 0x1c, 0x60, 0xd0, 0xfe, 0x87, 0xb2, 0x41, 0xb2, 0x0e, 0x2f, 0x14, 0xa1, + 0x87, 0xc9, 0x8f, 0x0b, 0xf4, 0x6f, 0x9a, 0xa2, 0x28, 0x37, 0xd9, 0x29, + 0xb3, 0xde, 0xa9, 0x56, 0x57, 0xfc, 0x6b, 0x29, 0x6f, 0xdb, 0x0f, 0x17, + 0xea, 0x09, 0x40, 0x9e, 0x70, 0xcd, 0x68, 0xcb, 0x1f, 0x4e, 0xe6, 0x49, + 0x11, 0x23, 0x46, 0x27, 0x37, 0x59, 0x65, 0x7f, 0x55, 0xeb, 0x5d, 0x6b, + 0xa8, 0xed, 0xc9, 0xd2, 0xce, 0xa8, 0x11, 0x14, 0x3d, 0x38, 0x4f, 0xda, + 0x4a, 0xa7, 0x5b, 0xaa, 0xb7, 0xad, 0x6f, 0xf6, 0x6a, 0x05, 0xe7, 0xec, + 0xb0, 0x2a, 0x2a, 0x14, 0x05, 0xa5, 0xa7, 0x87, 0xdb, 0xf0, 0xf5, 0xaf, + 0xc9, 0x9c, 0x1b, 0x72, 0x59, 0x14, 0x20, 0xe0, 0xc6, 0x83, 0x0d, 0x7b, + 0x71, 0xbc, 0x2b, 0x90, 0xa9, 0x71, 0x4a, 0x32, 0x21, 0x25, 0x1b, 0x20, + 0x86, 0xcf, 0x25, 0xd5, 0x9d, 0xf7, 0x86, 0x6b, 0x63, 0x34, 0xa9, 0xfd, + 0xe5, 0x03, 0x9d, 0x9c, 0xbb, 0x7b, 0x5b, 0xd9, 0xe9, 0x21, 0x22, 0x91, + 0xba, 0x30, 0xb0, 0x60, 0xac, 0x4b, 0x11, 0xb9, 0x4b, 0x52, 0xb1, 0x39, + 0xde, 0xf3, 0xf3, 0x6f, 0x49, 0x23, 0x87, 0xe0, 0xcd, 0x89, 0x1a, 0x5e, + 0x24, 0xb4, 0xc5, 0x66, 0x4a, 0x9e, 0x6e, 0xa4, 0x2d, 0xd5, 0x11, 0x6e, + 0x16, 0xb5, 0x00, 0x9f, 0x35, 0x40, 0x15, 0x07, 0xc8, 0x80, 0x1c, 0x30, + 0xc0, 0x38, 0xc6, 0x25, 0xf3, 0x4c, 0xb3, 0xb3, 0x9b, 0xc6, 0x79, 0xce, + 0xa2, 0xec, 0x2c, 0xfc, 0x19, 0x18, 0x83, 0x9b, 0x00, 0xa2, 0x97, 0x45, + 0x3a, 0x81, 0xcd, 0x86, 0xa0, 0x3a, 0x10, 0xbc, 0xda, 0xb6, 0xd5, 0xa6, + 0x6f, 0xb6, 0xf3, 0x4b, 0x39, 0xc5, 0x36, 0xa1, 0x80, 0x24, 0x33, 0x5c, + 0xb9, 0x6e, 0x6c, 0xe5, 0x88, 0xc9, 0xc5, 0xad, 0x81, 0xc2, 0xf2, 0xd1, + 0x05, 0xa6, 0x53, 0xc6, 0xb9, 0x8d, 0x15, 0xaf, 0x67, 0xa2, 0x29, 0x2a, + 0x90, 0xe1, 0xc1, 0x1f, 0xc1, 0x00, 0x7d, 0xa5, 0x5f, 0x62, 0xb3, 0x68, + 0x15, 0xfe, 0xd1, 0xcd, 0x19, 0xa0, 0x21, 0x80, 0x89, 0xaa, 0xd7, 0x9e, + 0x1c, 0x3d, 0xf5, 0x57, 0x50, 0x05, 0x8d, 0x96, 0x54, 0x3e, 0x4e, 0xae, + 0x29, 0x6b, 0xca, 0x60, 0x6b, 0x30, 0x1c, 0xa4, 0x8c, 0x83, 0x0c, 0x82, + 0x0b, 0x1b, 0x0b, 0x95, 0x08, 0x39, 0x77, 0x2b, 0x58, 0xc6, 0x42, 0xa5, + 0xd0, 0xc9, 0x0a, 0xa6, 0x83, 0x06, 0xe0, 0xf9, 0x5f, 0xfd, 0xd6, 0xe0, + 0x84, 0x93, 0x33, 0xa1, 0xfc, 0x2c, 0x0e, 0xbd, 0x85, 0x9a, 0xa6, 0xf5, + 0x6e, 0x51, 0x88, 0x31, 0x01, 0x46, 0x12, 0xab, 0x92, 0x03, 0x16, 0x08, + 0x4c, 0xed, 0x0e, 0x53, 0xec, 0x60, 0x18, 0x13, 0x6d, 0x1f, 0x66, 0x23, + 0xf9, 0xda, 0x38, 0x15, 0xb6, 0x16, 0x84, 0x60, 0x6c, 0xf4, 0x98, 0xd9, + 0x7e, 0x29, 0x66, 0xf3, 0x7f, 0xbf, 0xaa, 0x43, 0xd4, 0x21, 0xaa, 0x10, + 0x13, 0x20, 0x7c, 0x74, 0x07, 0x87, 0x59, 0xa3, 0xf2, 0xf6, 0xb5, 0x3d, + 0x5b, 0xde, 0xf2, 0x9b, 0x33, 0xbc, 0xbc, 0xf4, 0xe0, 0xd9, 0x15, 0x06, + 0x27, 0x0a, 0xa3, 0xe2, 0xe6, 0x5b, 0xf6, 0x6a, 0xb9, 0x23, 0x6a, 0x21, + 0x6e, 0x65, 0xb7, 0xd2, 0xa1, 0x0d, 0x42, 0xc5, 0xc4, 0x70, 0x38, 0x3c, + 0x05, 0x68, 0xf4, 0x7b, 0xf9, 0xbe, 0x69, 0xa5, 0x83, 0xf5, 0xd8, 0x6a, + 0x49, 0xc0, 0xf3, 0xca, 0x46, 0xfb, 0xa0, 0xa8, 0xff, 0xc6, 0xc2, 0xc7, + 0xf9, 0x60, 0x58, 0xbb, 0xce, 0x11, 0x3f, 0x00, 0x00, 0x8f, 0x08, 0x2c, + 0x44, 0x23, 0x2c, 0x98, 0x78, 0x6c, 0x19, 0x42, 0x65, 0x15, 0x07, 0x47, + 0x10, 0xe1, 0x26, 0x35, 0x5b, 0x2a, 0x65, 0xd0, 0x33, 0x94, 0xd1, 0x02, + 0x63, 0xad, 0xf0, 0x31, 0x60, 0xf1, 0x06, 0x82, 0xa8, 0xb8, 0x95, 0x71, + 0xc7, 0x97, 0x06, 0x13, 0xcf, 0x99, 0x98, 0x1e, 0xa8, 0xa6, 0xbb, 0x17, + 0x46, 0x86, 0xb8, 0x5c, 0x52, 0x22, 0x72, 0x65, 0x7a, 0x38, 0xee, 0xea, + 0xfa, 0x19, 0x39, 0x60, 0x45, 0x5f, 0x91, 0x1f, 0x51, 0x2c, 0xbd, 0x06, + 0x13, 0xad, 0xad, 0x08, 0x3d, 0xd1, 0x06, 0x6c, 0xed, 0xea, 0x85, 0xce, + 0x29, 0x4b, 0x99, 0xe4, 0x2c, 0x92, 0x31, 0xb0, 0x3b, 0xdd, 0x2b, 0xab, + 0x03, 0x02, 0xeb, 0x2b, 0x40, 0xe9, 0x64, 0x5a, 0x4a, 0xd5, 0x47, 0xb9, + 0x28, 0x6b, 0xde, 0x53, 0x47, 0xe3, 0xe9, 0x58, 0x6a, 0x4d, 0xdf, 0xce, + 0x5e, 0xf0, 0x96, 0xc4, 0x71, 0xc3, 0x78, 0xc2, 0xc5, 0x9d, 0x53, 0x28, + 0x2f, 0x4d, 0x09, 0x7f, 0xeb, 0x6c, 0x78, 0x6d, 0xef, 0x7a, 0x64, 0x42, + 0xbb, 0x8a, 0x64, 0xcf, 0x68, 0x87, 0x2f, 0x59, 0x51, 0x63, 0x5e, 0xb3, + 0xd8, 0x86, 0xdd, 0xb2, 0xf2, 0x86, 0xc4, 0x5d, 0x37, 0x87, 0x3c, 0x67, + 0xf9, 0x0b, 0x6f, 0x69, 0x2f, 0x2d, 0xe8, 0x30, 0xd6, 0x5a, 0x93, 0xed, + 0x64, 0xf5, 0x95, 0x42, 0x72, 0xb8, 0x84, 0x3a, 0x47, 0xc1, 0x38, 0x9d, + 0xae, 0xe2, 0x30, 0x4c, 0x38, 0xfe, 0x99, 0x25, 0xbd, 0x37, 0xe6, 0x86, + 0xa6, 0x8b, 0x7a, 0xb9, 0xb0, 0xaf, 0xb3, 0xcd, 0x63, 0x94, 0x89, 0x7e, + 0xfb, 0xc0, 0x91, 0xd2, 0x29, 0x5a, 0x46, 0x15, 0xb1, 0x1b, 0xec, 0xb1, + 0x00, 0x56, 0x9c, 0x57, 0x9d, 0x86, 0xea, 0x08, 0xbb, 0xcb, 0xd9, 0x43, + 0x20, 0xab, 0xa5, 0x86, 0x06, 0xe5, 0xcb, 0x72, 0x8d, 0xe6, 0xf0, 0xd1, + 0xf4, 0xff, 0xfb, 0xad, 0x30, 0x6f, 0xd2, 0xb5, 0x4a, 0x25, 0xec, 0x0c, + 0xc1, 0x82, 0xa2, 0xa2, 0x3c, 0x50, 0x9c, 0x35, 0x82, 0xf7, 0x2c, 0xd6, + 0x75, 0x86, 0xf9, 0x2e, 0xe9, 0x6c, 0x2a, 0x88, 0xf9, 0x65, 0xeb, 0xf8, + 0xf2, 0xc8, 0x08, 0xdb, 0xe0, 0x44, 0x4a, 0xc3, 0x3f, 0x99, 0x2d, 0xf0, + 0x81, 0xd4, 0x52, 0xfe, 0xf2, 0xc0, 0xaa, 0x12, 0x97, 0x2a, 0x2f, 0xf8, + 0xe3, 0x8a, 0x20, 0xe2, 0xe7, 0x99, 0xc5, 0xb9, 0xce, 0x76, 0x5a, 0x22, + 0xe2, 0x90, 0x4a, 0x86, 0x3d, 0xe1, 0xd3, 0x0a, 0x12, 0xe1, 0x6b, 0x69, + 0x6c, 0x2c, 0xcc, 0xc1, 0xcc, 0xf2, 0xfc, 0x85, 0xaa, 0x0a, 0x86, 0xd5, + 0x48, 0x30, 0x9d, 0x1e, 0xa8, 0x1c, 0x4c, 0x5a, 0xc9, 0x75, 0x17, 0x39, + 0x2a, 0x29, 0x01, 0x69, 0x8c, 0xe9, 0x56, 0x91, 0xb6, 0x3d, 0xf0, 0xfc, + 0xbc, 0x20, 0x37, 0x58, 0x52, 0xa7, 0xdd, 0x5f, 0xda, 0x1d, 0x6c, 0x37, + 0x03, 0x83, 0x22, 0x01, 0xd0, 0x86, 0xa9, 0x2d, 0x51, 0x29, 0x66, 0x83, + 0x1a, 0xd0, 0xca, 0x50, 0x4b, 0x2a, 0x10, 0x47, 0x5a, 0xd8, 0x32, 0xf8, + 0x57, 0x79, 0x0b, 0x4d, 0x8a, 0x43, 0xba, 0xf9, 0x4d, 0x3c, 0xbe, 0x29, + 0x05, 0xb1, 0x53, 0x3c, 0xc8, 0xa5, 0xb2, 0x2c, 0xad, 0x7c, 0x33, 0x17, + 0x9d, 0x38, 0x9d, 0x9f, 0x79, 0x2b, 0x0a, 0x7c, 0x39, 0xab, 0x21, 0x92, + 0xc9, 0x3c, 0x8c, 0xac, 0x52, 0x13, 0x41, 0x48, 0xcf, 0xd5, 0x89, 0x49, + 0xeb, 0x34, 0xb7, 0x55, 0x33, 0xc9, 0xfd, 0x5f, 0x54, 0x59, 0x81, 0xe0, + 0x38, 0xc5, 0x7f, 0x28, 0x22, 0xd6, 0x74, 0xad, 0x6e, 0x44, 0x0b, 0x42, + 0x2f, 0x21, 0x1b, 0x7a, 0x73, 0x45, 0xad, 0xa8, 0x5f, 0xf8, 0xad, 0x95, + 0x17, 0xbc, 0xbe, 0xe5, 0xc1, 0x97, 0x01, 0x86, 0x81, 0xc8, 0x7a, 0x0f, + 0x05, 0x01, 0x98, 0x06, 0x2b, 0xf9, 0x7e, 0xb0, 0x3f, 0x57, 0x59, 0x53, + 0x83, 0x8f, 0x16, 0x65, 0xfc, 0xf8, 0x31, 0x54, 0xb7, 0x01, 0x83, 0x8d, + 0x80, 0xc1, 0x52, 0xca, 0xd4, 0xee, 0xac, 0x8b, 0x90, 0xb4, 0xdf, 0x0d, + 0x47, 0x88, 0x47, 0xe9, 0x02, 0x11, 0x7a, 0x61, 0xc2, 0xb6, 0x26, 0xf8, + 0xab, 0x7f, 0x36, 0xf1, 0x78, 0xbc, 0xb4, 0x09, 0x82, 0x52, 0xe6, 0x6f, + 0x16, 0xa0, 0x92, 0x54, 0x84, 0x6d, 0xd2, 0xaa, 0xca, 0x74, 0x8d, 0x27, + 0x6f, 0xdb, 0x3f, 0xff, 0x79, 0xbb, 0xb8, 0x1d, 0x77, 0xfe, 0xe8, 0x79, + 0x43, 0x83, 0xab, 0x88, 0x60, 0x1a, 0x10, 0xc4, 0xa4, 0x89, 0x01, 0x13, + 0x1a, 0xd9, 0xbf, 0x04, 0x46, 0xfb, 0x9f, 0xac, 0xce, 0xfe, 0xf2, 0x50, + 0x24, 0x55, 0xe3, 0x2b, 0x8f, 0x1b, 0xf4, 0x55, 0xaa, 0xb4, 0xaf, 0xd9, + 0xa0, 0xac, 0x43, 0x4b, 0x2a, 0x25, 0xc3, 0x6e, 0x28, 0x05, 0x70, 0x58, + 0x30, 0x11, 0xf7, 0x22, 0x7b, 0x20, 0x32, 0x1f, 0x45, 0x11, 0x41, 0x50, + 0x78, 0xb7, 0x3a, 0x1c, 0x83, 0x04, 0x62, 0x97, 0x0b, 0x78, 0xd5, 0x2a, + 0xa6, 0x0a, 0x3c, 0xd8, 0xb8, 0x47, 0x06, 0xd5, 0x41, 0x09, 0x21, 0x73, + 0x52, 0xf3, 0xec, 0xa8, 0xcc, 0x9c, 0x1b, 0x67, 0x03, 0xd6, 0xe8, 0x6e, + 0xa6, 0x39, 0x41, 0x2b, 0xdf, 0x12, 0xee, 0x33, 0x17, 0x4d, 0xff, 0xd6, + 0xd4, 0xc5, 0xfd, 0xff, 0xd0, 0xef, 0xfd, 0x11, 0x77, 0x4e, 0x06, 0x51, + 0xe8, 0x1c, 0xf3, 0x2c, 0xe2, 0xb5, 0x7e, 0xad, 0xa9, 0xf2, 0xf9, 0x2f, + 0x26, 0x67, 0x56, 0xed, 0x0e, 0x54, 0x38, 0x4c, 0x10, 0x82, 0x00, 0x94, + 0xd6, 0x65, 0x54, 0xac, 0x77, 0xea, 0xb7, 0x1a, 0x05, 0x5b, 0x73, 0xde, + 0xd1, 0xbd, 0xe3, 0x19, 0xb8, 0xc6, 0xe2, 0x3c, 0x2b, 0xf0, 0xb4, 0x61, + 0x9f, 0x7d, 0x50, 0xde, 0x7b, 0x42, 0xd7, 0xb0, 0xf2, 0x61, 0x6d, 0x47, + 0x95, 0x4e, 0x35, 0x92, 0x2c, 0xbe, 0xc5, 0xad, 0xa6, 0x9e, 0xa2, 0x97, + 0x9e, 0x61, 0x56, 0xf8, 0xac, 0x41, 0xd6, 0x40, 0xa1, 0x5a, 0x0a, 0x40, + 0x80, 0x96, 0x98, 0x7e, 0x90, 0x79, 0xe1, 0xff, 0xb2, 0x83, 0x23, 0x8b, + 0x71, 0x4e, 0xcc, 0xb2, 0xae, 0x08, 0xe0, 0x20, 0xe1, 0x35, 0x6e, 0xd4, + 0x2b, 0x67, 0x8c, 0x31, 0x72, 0x5f, 0xd9, 0x3f, 0x7f, 0x6c, 0x05, 0x60, + 0x15, 0xe7, 0x01, 0x90, 0x81, 0x00, 0x61, 0x88, 0x25, 0x0d, 0x81, 0xb9, + 0x04, 0x65, 0x6a, 0xd3, 0x62, 0x78, 0xad, 0x81, 0xc8, 0xe7, 0x32, 0x81, + 0x76, 0xa7, 0xd1, 0xca, 0x1c, 0xe2, 0x91, 0x14, 0xb4, 0x18, 0x12, 0xc7, + 0x25, 0xe1, 0x04, 0x1b, 0x83, 0xed, 0x1d, 0x8f, 0x59, 0xd6, 0xbd, 0xb9, + 0x60, 0xf9, 0x0a, 0xb4, 0xf4, 0xd2, 0x68, 0x87, 0x30, 0x39, 0x06, 0x22, + 0x06, 0x48, 0xfc, 0x1a, 0x8e, 0xd3, 0x8f, 0xc1, 0x4f, 0x35, 0x46, 0xf9, + 0x6f, 0x51, 0xbe, 0xa8, 0x88, 0x8b, 0x6e, 0x8d, 0xc1, 0x86, 0x94, 0x72, + 0x02, 0x9a, 0xe8, 0x58, 0xd9, 0x5c, 0xf9, 0xe4, 0x47, 0x27, 0x1d, 0x06, + 0x4e, 0x01, 0xbc, 0xe0, 0x29, 0xf8, 0x4b, 0x18, 0x6a, 0x51, 0x98, 0x08, + 0x95, 0x40, 0xc9, 0x40, 0xeb, 0x1b, 0x77, 0x53, 0x87, 0xf2, 0xa3, 0xf3, + 0x39, 0x2e, 0x0c, 0xb8, 0x36, 0x7a, 0xd4, 0xf9, 0x50, 0x05, 0x9d, 0x65, + 0xcd, 0x86, 0xb0, 0x64, 0xe3, 0xb4, 0xc9, 0xb4, 0x46, 0x10, 0x58, 0x10, + 0x78, 0x9c, 0x72, 0x59, 0xdb, 0x36, 0x7a, 0x4b, 0x2d, 0xf5, 0x82, 0x2a, + 0x9b, 0x01, 0x24, 0xa3, 0x69, 0x8b, 0x87, 0xa9, 0x15, 0x04, 0x34, 0x8d, + 0xed, 0x9e, 0xb1, 0xb8, 0x86, 0xd9, 0x65, 0xef, 0x83, 0x6d, 0xc3, 0xe6, + 0xc2, 0x18, 0x8f, 0xf0, 0x82, 0x94, 0x3f, 0xd0, 0xf3, 0x8d, 0x66, 0x4c, + 0xea, 0xd3, 0x92, 0x77, 0x80, 0x4f, 0xa6, 0x42, 0x98, 0x30, 0x90, 0x3b, + 0xc6, 0xbc, 0x0c, 0x58, 0xae, 0x95, 0x2b, 0xba, 0xdb, 0x55, 0x16, 0x42, + 0xc8, 0xba, 0xe3, 0x10, 0x61, 0xa7, 0x8c, 0xaf, 0x49, 0xbc, 0x16, 0xb7, + 0x81, 0x57, 0x0b, 0x2d, 0xb1, 0x4c, 0x91, 0x10, 0x8a, 0xb3, 0x83, 0x30, + 0xf4, 0x20, 0xb2, 0xcf, 0xf3, 0xc9, 0x18, 0xd4, 0x89, 0x27, 0x03, 0xfd, + 0x56, 0x55, 0xb7, 0x6a, 0x3f, 0x12, 0x28, 0x07, 0x07, 0xa1, 0x60, 0x88, + 0xbc, 0x7a, 0xab, 0xdc, 0x6c, 0xb9, 0x26, 0x2b, 0x34, 0xdf, 0xf9, 0x9e, + 0x44, 0x1d, 0x95, 0x95, 0xe8, 0x2a, 0x03, 0xa2, 0xd0, 0x62, 0x73, 0x62, + 0x1a, 0xa1, 0xe8, 0x43, 0x6c, 0xb5, 0x8c, 0xef, 0x76, 0xd1, 0xc7, 0x96, + 0xed, 0xa8, 0xed, 0x50, 0x54, 0xa4, 0xc8, 0xb3, 0x2d, 0xef, 0x22, 0x8a, + 0x75, 0x3f, 0xfe, 0x9e, 0x6f, 0x60, 0x80, 0xc2, 0x56, 0x9b, 0xda, 0xa7, + 0x54, 0x42, 0xbd, 0xee, 0xf1, 0x9b, 0x17, 0xbe, 0xaa, 0x14, 0x28, 0xc5, + 0xf0, 0x58, 0x26, 0x4d, 0x37, 0x74, 0x0c, 0x4d, 0xfe, 0xff, 0x94, 0x6f, + 0xdb, 0x79, 0x16, 0x91, 0x49, 0x56, 0x00, 0x82, 0x63, 0xa0, 0x38, 0x24, + 0xe7, 0xb0, 0x72, 0xa3, 0x35, 0x85, 0xd4, 0x56, 0xe6, 0xa9, 0xc8, 0xb4, + 0x9c, 0xc2, 0x97, 0x0b, 0x41, 0x08, 0x78, 0xda, 0xa8, 0xad, 0x2a, 0x55, + 0x19, 0x54, 0x48, 0xc7, 0xb1, 0x16, 0x67, 0x3b, 0xf0, 0x26, 0xa5, 0xd3, + 0xdf, 0x2c, 0x62, 0xef, 0xfd, 0xfe, 0xe8, 0x31, 0x14, 0xca, 0xb1, 0x13, + 0x61, 0x74, 0x74, 0x95, 0x9f, 0x35, 0xf0, 0xfd, 0x37, 0xd2, 0x31, 0xec, + 0x0e, 0xd9, 0xbe, 0x85, 0xb2, 0x4e, 0xff, 0xeb, 0x16, 0x95, 0x61, 0xe0, + 0x60, 0x83, 0x32, 0x0d, 0xf4, 0xe2, 0x3a, 0xb9, 0xe4, 0x95, 0xb6, 0x07, + 0x4d, 0x68, 0x18, 0x40, 0x1f, 0xd8, 0x0c, 0x87, 0xe0, 0xe0, 0x29, 0x80, + 0xe3, 0x21, 0x9c, 0x14, 0xa2, 0x3b, 0x2c, 0xfa, 0x2a, 0x54, 0x1e, 0x35, + 0x7b, 0x55, 0xd5, 0xef, 0xef, 0xa2, 0x29, 0xcc, 0x04, 0x70, 0x61, 0x30, + 0xc1, 0x76, 0xd4, 0x67, 0xb3, 0x29, 0x66, 0xc0, 0x33, 0xd5, 0xf9, 0x51, + 0xda, 0x0b, 0x41, 0xbf, 0xfa, 0xa8, 0x9b, 0x51, 0x99, 0x30, 0xc9, 0x6a, + 0x0f, 0x87, 0x1e, 0x1d, 0x0e, 0xac, 0x5f, 0xe0, 0xaa, 0x4d, 0xde, 0xaf, + 0x3a, 0x38, 0xf1, 0x02, 0x82, 0x08, 0x71, 0x9d, 0xde, 0x2f, 0xbc, 0xe4, + 0x14, 0x2e, 0x3c, 0x52, 0x0a, 0xa2, 0xe5, 0x1d, 0xb4, 0x14, 0xca, 0x86, + 0x03, 0x87, 0x18, 0x10, 0x0b, 0xf7, 0x96, 0x67, 0x09, 0x77, 0xf2, 0x2c, + 0x6f, 0x86, 0x1b, 0xe1, 0x54, 0x3a, 0x9e, 0x8c, 0xce, 0x29, 0x45, 0xf4, + 0x4a, 0x3c, 0x50, 0x84, 0x44, 0x04, 0x70, 0x7c, 0x98, 0x01, 0xd4, 0xac, + 0xb7, 0x6f, 0x95, 0x62, 0xbb, 0x2d, 0xc5, 0x3b, 0xde, 0xa8, 0x99, 0x10, + 0x41, 0xc1, 0x69, 0x58, 0x6c, 0x58, 0x2c, 0x59, 0xb9, 0xf9, 0xb2, 0x02, + 0xb2, 0xea, 0x95, 0xf9, 0x6a, 0xeb, 0xaf, 0x3a, 0xa1, 0x40, 0x5a, 0xb3, + 0x77, 0xa2, 0x1b, 0x05, 0xf1, 0x5a, 0x72, 0xea, 0x93, 0x2f, 0xab, 0x4c, + 0x37, 0xd6, 0x9b, 0xcf, 0xcb, 0xd8, 0xcc, 0xc2, 0xdc, 0x6f, 0x34, 0x15, + 0xc5, 0xa5, 0x86, 0x09, 0xf0, 0xa8, 0xc2, 0xd3, 0x52, 0xa6, 0x50, 0xe4, + 0x31, 0x06, 0x0a, 0x4d, 0x17, 0xf9, 0xb2, 0xdc, 0xea, 0xf6, 0xdd, 0x51, + 0xd4, 0x5c, 0xa7, 0x05, 0xf3, 0xf9, 0xe6, 0xae, 0x94, 0x92, 0x89, 0x85, + 0x09, 0x38, 0x9d, 0xab, 0x3f, 0xcd, 0x5e, 0xac, 0x87, 0xb6, 0xf5, 0x67, + 0xc2, 0xdc, 0x99, 0x61, 0x23, 0xcc, 0xb1, 0xcf, 0x25, 0xb8, 0xdb, 0x3c, + 0x2d, 0xdf, 0xe6, 0x16, 0x4e, 0x5b, 0x6f, 0xa7, 0x14, 0xfc, 0x44, 0xe1, + 0x68, 0x31, 0x3c, 0xb0, 0xb8, 0x2f, 0xd3, 0xa5, 0xc5, 0x9c, 0xad, 0x77, + 0xb7, 0x83, 0x2e, 0x11, 0xbf, 0x2d, 0x17, 0x46, 0x8f, 0xa5, 0x0e, 0xa6, + 0xcf, 0xb5, 0x9a, 0x2f, 0x57, 0xca, 0x58, 0x86, 0x0b, 0x90, 0x3b, 0xb0, + 0x93, 0x19, 0x2b, 0xfd, 0xa1, 0xb9, 0xaa, 0x48, 0x0b, 0x61, 0xa7, 0xf5, + 0x4a, 0x7d, 0x6d, 0x07, 0x68, 0xc3, 0xa7, 0x05, 0xca, 0xa7, 0x0a, 0xd0, + 0x03, 0xba, 0xeb, 0x6d, 0x60, 0x44, 0x07, 0x82, 0xff, 0x8d, 0xaf, 0xe0, + 0x30, 0x16, 0xf7, 0xbb, 0x98, 0x1c, 0x6f, 0xaf, 0x00, 0x9a, 0x93, 0xa9, + 0xa3, 0x7d, 0x0e, 0xbc, 0xc8, 0x2b, 0x75, 0x95, 0xad, 0xfd, 0x29, 0xe5, + 0xa7, 0xfb, 0x8b, 0x85, 0x8a, 0x07, 0x65, 0xcd, 0x6a, 0xa5, 0x6a, 0xef, + 0x6f, 0xd4, 0x4f, 0x40, 0xe3, 0x9c, 0xef, 0x78, 0x1c, 0x9c, 0x3a, 0x01, + 0xd9, 0xdf, 0x0f, 0xe7, 0xb4, 0xb1, 0x92, 0xcf, 0x16, 0x74, 0x67, 0xd0, + 0x61, 0xaa, 0x63, 0xfd, 0xe8, 0xf9, 0x5b, 0x5e, 0x1b, 0xf7, 0xbf, 0x24, + 0xce, 0x68, 0x44, 0x90, 0x07, 0x42, 0xc5, 0x41, 0xfd, 0x2a, 0xd6, 0xd5, + 0x8e, 0x0d, 0xac, 0x58, 0xb0, 0x66, 0xf7, 0x3a, 0x83, 0x10, 0x97, 0x99, + 0xad, 0xb4, 0xa9, 0x36, 0x96, 0x34, 0xd4, 0x03, 0x7a, 0x56, 0x8b, 0x27, + 0xea, 0xdc, 0x85, 0x44, 0x97, 0x0a, 0xc0, 0xae, 0xe0, 0x0a, 0xa6, 0xbe, + 0x5a, 0xde, 0xe2, 0x8b, 0x9c, 0xdc, 0x1b, 0xad, 0x6d, 0xb1, 0x7a, 0x0c, + 0x35, 0x32, 0x07, 0x53, 0x7c, 0x70, 0x5b, 0x8a, 0x6f, 0x95, 0x5b, 0xb7, + 0x00, 0x86, 0xf6, 0x4f, 0x37, 0x0d, 0x29, 0x3a, 0xaa, 0x46, 0x7f, 0xa3, + 0xd9, 0xbf, 0xfa, 0x9c, 0x60, 0x7c, 0xab, 0xbd, 0x1b, 0xdb, 0x60, 0x2c, + 0x41, 0x82, 0xa6, 0x96, 0x77, 0xd1, 0xed, 0x88, 0x99, 0xf5, 0xfc, 0x88, + 0x64, 0xdd, 0xec, 0x0d, 0xa3, 0xc5, 0x21, 0x0c, 0x75, 0x5a, 0xa2, 0x0f, + 0xb2, 0x96, 0x7e, 0xef, 0x20, 0x70, 0x48, 0x7c, 0x52, 0xb5, 0x97, 0x11, + 0xcb, 0x41, 0x38, 0x2e, 0xb3, 0xf8, 0x55, 0x2e, 0x62, 0x8d, 0xe8, 0xa1, + 0xf1, 0xe7, 0xb5, 0xa5, 0x8f, 0x6d, 0x50, 0x6c, 0x51, 0x44, 0x21, 0xfe, + 0x45, 0xbe, 0x1f, 0x95, 0x94, 0x96, 0x4a, 0xe3, 0xa3, 0xf4, 0xfd, 0xfb, + 0x6c, 0x76, 0xb5, 0xb7, 0x9d, 0xda, 0xbc, 0xdc, 0x43, 0x39, 0xa5, 0xaa, + 0x11, 0xcd, 0x2a, 0x2c, 0x04, 0x8a, 0x1e, 0x35, 0x89, 0x3e, 0x5e, 0xd6, + 0x49, 0x31, 0x3e, 0xcf, 0xc4, 0x12, 0x3f, 0x08, 0xe3, 0xaf, 0xea, 0x7e, + 0xf0, 0x13, 0x89, 0x54, 0xa0, 0xb6, 0xca, 0x0c, 0x4c, 0x57, 0xb5, 0x4f, + 0xe8, 0x2d, 0xdb, 0x2a, 0xab, 0xfe, 0x69, 0x8b, 0xe5, 0xd9, 0xca, 0x37, + 0xbf, 0xbd, 0xde, 0x2c, 0xbc, 0xa1, 0xc2, 0x20, 0x10, 0x32, 0x03, 0xb9, + 0x8a, 0xb8, 0xaf, 0xea, 0xfc, 0x1f, 0x67, 0xe7, 0xba, 0xa3, 0xf1, 0x45, + 0xbc, 0x2c, 0x58, 0x34, 0xa0, 0x94, 0x7d, 0xa6, 0x1b, 0x4c, 0xc8, 0xe3, + 0xe3, 0x6f, 0xc0, 0xf0, 0x92, 0xdb, 0x0e, 0x12, 0x06, 0x12, 0x73, 0xd4, + 0x21, 0x6c, 0x6f, 0x73, 0x19, 0xe6, 0x08, 0x1e, 0x11, 0x7f, 0x3d, 0x64, + 0x0c, 0x41, 0x82, 0xa4, 0x1c, 0xd6, 0x39, 0xb1, 0x19, 0x89, 0xba, 0x59, + 0x87, 0xdb, 0x17, 0x17, 0x30, 0xaa, 0xb5, 0xce, 0xdd, 0x2d, 0x91, 0x7e, + 0xcb, 0xef, 0xc5, 0x97, 0x61, 0x40, 0x25, 0x0a, 0x87, 0x62, 0x40, 0xe5, + 0x88, 0xd3, 0x5f, 0x8d, 0x7d, 0x4e, 0x37, 0x9b, 0x62, 0x98, 0xb0, 0x14, + 0xb0, 0x16, 0xe0, 0xd0, 0x60, 0x19, 0x58, 0x1f, 0x04, 0x0c, 0xd4, 0xc3, + 0xc4, 0xf8, 0x59, 0xb6, 0x87, 0x9b, 0x91, 0x96, 0xb0, 0x15, 0xca, 0x46, + 0xdb, 0xa0, 0x55, 0x40, 0x31, 0x1d, 0xf8, 0x18, 0x4b, 0x04, 0x36, 0xd3, + 0xa9, 0x6c, 0x7f, 0x85, 0x7d, 0x06, 0x02, 0x8d, 0x45, 0x1d, 0x02, 0x1c, + 0xc0, 0x10, 0x3b, 0x4b, 0xfa, 0x37, 0x70, 0xc0, 0x7f, 0xd2, 0x06, 0xc2, + 0x82, 0x61, 0x20, 0x79, 0xa3, 0x82, 0xe0, 0xff, 0xe0, 0xdd, 0xcc, 0xfa, + 0xbf, 0xe7, 0x95, 0x96, 0x37, 0x65, 0xa1, 0xec, 0xfb, 0x01, 0xee, 0x0e, + 0x17, 0x50, 0x56, 0x5a, 0x0c, 0x70, 0xd3, 0x3e, 0x89, 0x36, 0xae, 0x38, + 0xef, 0xca, 0xa2, 0x3b, 0xc2, 0x62, 0x41, 0x00, 0x03, 0x7c, 0x01, 0x83, + 0xb0, 0x61, 0x04, 0xbc, 0x41, 0x67, 0xfb, 0xe6, 0x70, 0xa8, 0xaf, 0x6d, + 0xf9, 0x2b, 0x7a, 0x2a, 0xa6, 0x41, 0x84, 0x30, 0x36, 0x3f, 0xd5, 0x7f, + 0x2e, 0xd2, 0xc4, 0x7e, 0xc1, 0x06, 0x76, 0x5e, 0xac, 0x0c, 0x09, 0x4f, + 0x5b, 0x9a, 0x47, 0xe3, 0x7d, 0x05, 0xb3, 0x62, 0x81, 0x0b, 0xd2, 0xf9, + 0xa9, 0xab, 0xaf, 0x34, 0xa7, 0x51, 0x9f, 0x38, 0x0c, 0xac, 0x18, 0x4b, + 0x11, 0x81, 0x01, 0x8f, 0xb1, 0xdf, 0x17, 0x8e, 0xee, 0x52, 0xc1, 0xe6, + 0x2e, 0xa2, 0xf1, 0x1a, 0x70, 0x63, 0x4d, 0x03, 0xe5, 0xff, 0xf6, 0x78, + 0x20, 0x83, 0x0e, 0xc4, 0x31, 0x24, 0x0c, 0x34, 0xcb, 0x63, 0xe2, 0xee, + 0x70, 0x3e, 0x63, 0x54, 0x29, 0x25, 0xff, 0xf0, 0xaf, 0x43, 0x40, 0x48, + 0x1f, 0x87, 0x77, 0xb6, 0xdb, 0x6a, 0x1d, 0x5e, 0x8d, 0x4d, 0xaf, 0x70, + 0xb6, 0xa0, 0x6b, 0x08, 0x61, 0x0c, 0x7e, 0x07, 0xd2, 0xd4, 0xa3, 0xf6, + 0xcb, 0x75, 0x16, 0x64, 0x2a, 0x69, 0x8f, 0x20, 0x69, 0x8f, 0x0d, 0x9a, + 0xc3, 0x07, 0xd8, 0x59, 0x07, 0x99, 0xae, 0x64, 0x3e, 0x9b, 0x6c, 0x5f, + 0x48, 0x2b, 0x4f, 0xd0, 0xe9, 0x25, 0x79, 0x2a, 0xac, 0x37, 0x20, 0x66, + 0x41, 0x6b, 0x43, 0x48, 0xa2, 0xa7, 0x62, 0x7f, 0x85, 0x97, 0xf9, 0x36, + 0xd4, 0x52, 0x5b, 0x27, 0x68, 0x6d, 0x82, 0x63, 0x23, 0xd4, 0x9f, 0x12, + 0x87, 0xe9, 0x03, 0xf1, 0xd3, 0x25, 0xf9, 0x3c, 0x20, 0x2a, 0xd6, 0xb7, + 0x89, 0x3f, 0x2c, 0xbd, 0xa0, 0x61, 0x4e, 0xc0, 0x54, 0x30, 0x1e, 0x0d, + 0xcc, 0x8d, 0x02, 0xe0, 0x33, 0x56, 0x7c, 0x10, 0x07, 0x55, 0x19, 0x56, + 0xe6, 0x9b, 0xef, 0xbf, 0x70, 0x1f, 0x5e, 0x00, 0x52, 0x15, 0x2f, 0x5e, + 0x58, 0xb1, 0xb3, 0x40, 0xca, 0x5a, 0xf2, 0x62, 0xd2, 0xc8, 0xa2, 0x28, + 0x9a, 0x5d, 0xf5, 0xac, 0xb6, 0xc9, 0xce, 0x69, 0x59, 0x50, 0x72, 0x64, + 0x2c, 0x29, 0x2e, 0x2f, 0x61, 0xb0, 0x6e, 0x7e, 0xa4, 0x4e, 0x59, 0x40, + 0xb7, 0xd4, 0x73, 0x49, 0x4a, 0x8a, 0xd4, 0x19, 0x26, 0x23, 0x8f, 0x18, + 0x1f, 0xa4, 0x6f, 0x2c, 0x0f, 0x67, 0xba, 0xd5, 0x42, 0xa6, 0x22, 0x9d, + 0x1a, 0x87, 0x71, 0xd4, 0x4b, 0xe5, 0x7b, 0x6f, 0xa3, 0x5c, 0xdb, 0xf5, + 0x25, 0xbd, 0xe6, 0xa2, 0xab, 0x28, 0x11, 0x75, 0xf7, 0xfa, 0x89, 0x63, + 0x85, 0x3d, 0x31, 0xda, 0xa1, 0x1c, 0x20, 0xaa, 0x66, 0xb4, 0xad, 0x3f, + 0x6c, 0xcc, 0xcd, 0x0f, 0xf2, 0x55, 0xe5, 0x47, 0x37, 0x14, 0x6e, 0xe0, + 0x2d, 0xd6, 0x68, 0x20, 0xe8, 0x29, 0xbe, 0xd3, 0x21, 0xe5, 0xf9, 0x66, + 0x0e, 0x5a, 0xbc, 0xca, 0xbc, 0x97, 0x81, 0xc6, 0x99, 0x16, 0xab, 0x2c, + 0x6f, 0x9f, 0x6d, 0xbf, 0x4f, 0xf9, 0x66, 0xe6, 0x0d, 0xed, 0x40, 0xb0, + 0x88, 0x54, 0x7c, 0x73, 0xbe, 0x1b, 0x60, 0x22, 0xa8, 0x54, 0xa0, 0x3f, + 0xdf, 0x7d, 0x78, 0x89, 0x1f, 0x44, 0x42, 0x33, 0xff, 0xf4, 0x05, 0xaa, + 0x5d, 0x5b, 0x36, 0x10, 0xd5, 0x35, 0x90, 0x3f, 0x6b, 0xf7, 0x18, 0xdd, + 0xc2, 0xdf, 0x72, 0xe9, 0x65, 0xa0, 0x54, 0xa8, 0xae, 0x62, 0x90, 0xec, + 0x1c, 0x64, 0x42, 0x3e, 0x12, 0x1b, 0xcd, 0x2c, 0xe7, 0x3f, 0xfe, 0x8e, + 0x16, 0xeb, 0x4d, 0xf5, 0x15, 0xee, 0x08, 0xaa, 0x00, 0x49, 0x31, 0xf3, + 0x43, 0xc6, 0xfa, 0x38, 0x6d, 0x4d, 0x51, 0x54, 0x45, 0x2b, 0x20, 0x5e, + 0x06, 0xc7, 0x42, 0xd8, 0x40, 0x1c, 0x82, 0x20, 0x19, 0xde, 0xf3, 0xfb, + 0x3d, 0x10, 0xe6, 0x14, 0x89, 0x8b, 0xd6, 0xeb, 0x72, 0x78, 0x82, 0xca, + 0x16, 0xbf, 0x00, 0x00, 0x99, 0x08, 0x2c, 0x2c, 0x88, 0x5a, 0x0f, 0x05, + 0x00, 0xd8, 0xea, 0x23, 0xa0, 0xa6, 0x2e, 0x19, 0x40, 0xf8, 0xc1, 0x66, + 0xe6, 0xa2, 0x9b, 0x7c, 0x4a, 0x43, 0x22, 0x52, 0x8f, 0x08, 0xc2, 0x57, + 0x06, 0xf4, 0x78, 0x5c, 0x0f, 0x17, 0x00, 0x6c, 0x3a, 0xbb, 0x6a, 0xd4, + 0x23, 0x19, 0x04, 0xa2, 0x82, 0x51, 0x13, 0x9b, 0x31, 0x8c, 0x66, 0x76, + 0x4f, 0xdb, 0xab, 0xaf, 0xc5, 0x86, 0x01, 0x6c, 0xc5, 0x4d, 0x35, 0xf0, + 0xe6, 0xac, 0x37, 0x93, 0xa7, 0x14, 0x6a, 0xee, 0xd9, 0x7b, 0x02, 0x22, + 0xb5, 0x65, 0xd1, 0x84, 0xc9, 0x87, 0x21, 0xe6, 0xd7, 0x1e, 0xea, 0xc3, + 0x45, 0x53, 0x08, 0x31, 0x57, 0xfe, 0xc2, 0x06, 0x73, 0xbd, 0x5e, 0x58, + 0x59, 0x7b, 0x02, 0x83, 0x42, 0x4f, 0xd1, 0x41, 0x58, 0xa0, 0xb9, 0x57, + 0xa0, 0x8d, 0x24, 0x02, 0xb9, 0x7f, 0x4a, 0x6f, 0x29, 0xf7, 0xa4, 0x35, + 0xe9, 0x93, 0x4c, 0x3d, 0x2d, 0xe1, 0x6c, 0x51, 0x69, 0x27, 0x20, 0xc0, + 0x12, 0x8b, 0xa7, 0x5b, 0xda, 0xa1, 0x69, 0xca, 0x4a, 0xb9, 0xf1, 0xae, + 0xfa, 0xf9, 0x9d, 0xca, 0x36, 0xf8, 0xba, 0x55, 0xe5, 0x06, 0x13, 0x0a, + 0x30, 0xad, 0x8c, 0xcb, 0x66, 0xd9, 0xce, 0xa0, 0x9c, 0x90, 0x8d, 0xd1, + 0x98, 0xa9, 0x8d, 0xd1, 0x3c, 0x50, 0x3a, 0xef, 0xe1, 0x65, 0x44, 0x13, + 0x12, 0x9e, 0xca, 0x20, 0xea, 0x9f, 0x6c, 0x62, 0x55, 0x3c, 0xfa, 0x14, + 0x73, 0xa5, 0x40, 0x90, 0x2f, 0x12, 0x3d, 0xd1, 0xf3, 0x4a, 0xd6, 0xbf, + 0x67, 0x27, 0xcb, 0x62, 0x2b, 0x96, 0x07, 0x9c, 0x0d, 0x94, 0x3e, 0xfb, + 0x08, 0x6d, 0x45, 0x96, 0xc5, 0x9d, 0x26, 0x97, 0xcd, 0xd9, 0xa8, 0xcf, + 0xac, 0x3f, 0x57, 0xe6, 0x9a, 0xe5, 0xb7, 0x2e, 0xad, 0x14, 0x73, 0xb3, + 0xb1, 0x1c, 0x0b, 0x53, 0x2c, 0xe7, 0xc1, 0x97, 0xbf, 0x55, 0x11, 0x37, + 0xf9, 0x3f, 0xbd, 0xe5, 0xe7, 0x96, 0xb2, 0x06, 0xb9, 0xd3, 0x10, 0xcd, + 0xbe, 0x03, 0x1e, 0x88, 0x94, 0x07, 0xd8, 0x36, 0x88, 0xd1, 0x06, 0x60, + 0x2c, 0xf2, 0x41, 0x03, 0x0b, 0x2f, 0x8b, 0x69, 0x5c, 0x52, 0xa7, 0x54, + 0xe8, 0x2b, 0xfa, 0x16, 0x13, 0x4f, 0x97, 0xe2, 0x0e, 0xf6, 0xf3, 0xcc, + 0xf9, 0x5c, 0xe2, 0xdd, 0x92, 0xae, 0xe7, 0x19, 0x0b, 0xcb, 0xe2, 0x5c, + 0x51, 0x72, 0xf3, 0x07, 0x1f, 0x6a, 0x7b, 0xf2, 0xf3, 0x92, 0xca, 0x81, + 0x48, 0xa4, 0x71, 0x5a, 0xd5, 0x43, 0xdd, 0xd5, 0xaf, 0xb0, 0x3e, 0x52, + 0xd9, 0xbf, 0x7f, 0xc0, 0xe2, 0xae, 0x29, 0x50, 0x0b, 0x75, 0x07, 0xaa, + 0x44, 0x00, 0x65, 0xe9, 0x53, 0x2a, 0x14, 0x64, 0xed, 0xda, 0xb8, 0x79, + 0x7d, 0x30, 0x45, 0x11, 0x7e, 0x04, 0x40, 0x48, 0xbf, 0x4a, 0x87, 0x9f, + 0x83, 0x6b, 0xe6, 0xe2, 0xa6, 0x90, 0x4f, 0xf2, 0xf3, 0xd6, 0xc1, 0x10, + 0xab, 0xa0, 0xc3, 0x56, 0xfa, 0x72, 0xc5, 0x96, 0x23, 0xb0, 0x6c, 0x6e, + 0x1a, 0x36, 0x0e, 0x30, 0xa5, 0x0f, 0x65, 0xf7, 0x7b, 0xce, 0x59, 0x45, + 0x6d, 0x68, 0x59, 0x22, 0x2e, 0x28, 0x19, 0x47, 0x2a, 0xc7, 0xc1, 0x5a, + 0xdb, 0x00, 0x42, 0xf6, 0x14, 0x52, 0x38, 0x79, 0x74, 0x5b, 0xd5, 0x4b, + 0x59, 0xbf, 0xf5, 0x19, 0xca, 0x28, 0x41, 0x55, 0xea, 0x56, 0x17, 0xe4, + 0xfe, 0xe7, 0xaa, 0xd2, 0xde, 0xdb, 0x17, 0x9d, 0x1b, 0x19, 0x5a, 0xd2, + 0xc0, 0x62, 0xde, 0x2d, 0x4b, 0x7d, 0x46, 0x56, 0x57, 0xca, 0x9b, 0x55, + 0x4f, 0xe0, 0xdf, 0xb8, 0x32, 0x7f, 0xc7, 0xa6, 0x45, 0x2f, 0x14, 0xec, + 0xe5, 0x67, 0x7c, 0x89, 0x47, 0xa6, 0x2e, 0x81, 0x75, 0x2a, 0x02, 0xd0, + 0xe0, 0x0d, 0x71, 0x92, 0xf0, 0x84, 0x21, 0x96, 0x97, 0x5c, 0xac, 0x31, + 0xa5, 0x9b, 0x7f, 0x2a, 0xfd, 0x45, 0x6e, 0x08, 0xa0, 0xc1, 0x21, 0x5c, + 0x04, 0x54, 0xa5, 0x8c, 0xaa, 0xc2, 0xd9, 0x64, 0x1c, 0xcb, 0xdc, 0xaa, + 0x79, 0xdb, 0xcf, 0x83, 0x8c, 0x85, 0x66, 0xda, 0xd6, 0x58, 0xd9, 0xf9, + 0xd0, 0xf1, 0x43, 0x71, 0x1e, 0x6f, 0x62, 0x10, 0x5b, 0xca, 0x29, 0x16, + 0xb0, 0x6e, 0xc1, 0xf3, 0x0a, 0xd3, 0x36, 0xce, 0xa7, 0xf7, 0x93, 0xf8, + 0x18, 0x44, 0xbc, 0x97, 0x60, 0x30, 0x4e, 0xa2, 0x41, 0x23, 0xcc, 0xaa, + 0x56, 0xaf, 0xe5, 0xfe, 0x55, 0x58, 0x45, 0x9b, 0x17, 0xd3, 0x52, 0x15, + 0x98, 0x0a, 0xa0, 0xcd, 0x83, 0x0f, 0xb4, 0x75, 0xb8, 0x5e, 0xc2, 0xe9, + 0x2f, 0xfb, 0xa6, 0xda, 0x9d, 0x45, 0xd4, 0x24, 0x61, 0xa5, 0x29, 0x77, + 0xa2, 0xba, 0x20, 0x5e, 0xaa, 0x9c, 0xe2, 0xfd, 0xb5, 0xe6, 0xbd, 0x8c, + 0x1b, 0x53, 0x78, 0xa6, 0xf4, 0x32, 0x15, 0xa9, 0xc3, 0xe8, 0x2b, 0xc5, + 0xde, 0xbe, 0x4b, 0x0c, 0xb7, 0x78, 0xf2, 0x1e, 0x30, 0x5e, 0x39, 0x39, + 0x84, 0x7f, 0x36, 0x32, 0xa9, 0x1d, 0xff, 0x0f, 0x6f, 0x6c, 0xa2, 0x61, + 0x62, 0x1a, 0x84, 0x98, 0xbb, 0x00, 0x58, 0xfa, 0xdf, 0xab, 0x53, 0x63, + 0x12, 0x18, 0xec, 0x54, 0xd8, 0xc1, 0xbf, 0x00, 0x90, 0xae, 0x0c, 0x90, + 0x03, 0xda, 0x1e, 0x16, 0x8e, 0x93, 0xa9, 0x50, 0xdb, 0x73, 0xed, 0x59, + 0x2e, 0x95, 0xd9, 0xcd, 0x9c, 0x41, 0x8b, 0x02, 0x48, 0xb5, 0x38, 0xf9, + 0x5e, 0x49, 0xff, 0xf9, 0x6e, 0x45, 0xc9, 0x09, 0xc3, 0x2e, 0xfa, 0x8d, + 0xf1, 0x18, 0xbc, 0x4c, 0x55, 0x52, 0xc7, 0xdc, 0xb3, 0xb8, 0xb9, 0xe6, + 0xc2, 0x39, 0x6e, 0x55, 0xe5, 0x09, 0x47, 0xe5, 0xec, 0x64, 0x4f, 0xf6, + 0x43, 0xa6, 0xad, 0xbd, 0x50, 0x88, 0x96, 0x83, 0x8c, 0x83, 0x31, 0x20, + 0x28, 0x44, 0x32, 0xe8, 0xa3, 0xb8, 0xdc, 0xe0, 0x30, 0x8b, 0x2d, 0xe4, + 0x29, 0xcd, 0x31, 0x49, 0xc2, 0x18, 0x8e, 0x25, 0x95, 0x5b, 0x3c, 0xd2, + 0x25, 0x0d, 0x15, 0x41, 0x88, 0x24, 0x92, 0xca, 0x59, 0xb9, 0x16, 0x3a, + 0x5d, 0x6c, 0x2d, 0x6c, 0x30, 0x8e, 0xc4, 0x74, 0xcc, 0x5d, 0x85, 0xda, + 0xdd, 0x56, 0xb5, 0x8a, 0xf3, 0x79, 0x99, 0x67, 0x65, 0xf5, 0x9b, 0x9a, + 0xa4, 0x8d, 0x00, 0x84, 0x3b, 0x06, 0xee, 0x6a, 0xa6, 0x4b, 0x04, 0x14, + 0x3b, 0xa8, 0xdb, 0x88, 0xd6, 0xe1, 0x40, 0x24, 0x26, 0x3e, 0x12, 0xbf, + 0xfa, 0xa3, 0x1a, 0x2d, 0x5c, 0x3d, 0xab, 0xdb, 0x0d, 0xf1, 0x46, 0x7f, + 0x54, 0x83, 0x04, 0xa2, 0x3a, 0x0c, 0x3e, 0x2f, 0x1f, 0x87, 0xaa, 0x93, + 0x02, 0x9b, 0x99, 0xc9, 0x7a, 0x59, 0x94, 0xd5, 0x2c, 0xd0, 0x56, 0xdb, + 0xa1, 0xce, 0xe0, 0xb0, 0x60, 0xfd, 0x3e, 0xd8, 0xb3, 0xe1, 0x0d, 0x50, + 0x1a, 0xa3, 0xe5, 0x4d, 0x07, 0xdc, 0xd8, 0x0a, 0xd9, 0x38, 0x89, 0x6e, + 0x70, 0x37, 0x04, 0x90, 0xbc, 0x0a, 0x45, 0x7e, 0xf8, 0xf1, 0x40, 0xe4, + 0xb7, 0xfe, 0xfe, 0xa9, 0x52, 0x55, 0x39, 0x7b, 0x57, 0x06, 0x09, 0x51, + 0x4c, 0x0c, 0x5c, 0x23, 0x8f, 0x9a, 0xcd, 0x4a, 0x94, 0x7c, 0xc6, 0x29, + 0x52, 0xdd, 0x56, 0x37, 0x6f, 0x2a, 0xfc, 0x8a, 0x0a, 0xd4, 0xe8, 0x6c, + 0x5a, 0x2d, 0x58, 0x1c, 0x91, 0x54, 0x0f, 0x87, 0xdb, 0x83, 0x91, 0x17, + 0xd8, 0x91, 0xbb, 0xfe, 0x22, 0x9c, 0xf6, 0xef, 0xd3, 0xee, 0x86, 0xe1, + 0xf0, 0x30, 0xc0, 0x58, 0x54, 0xdf, 0x49, 0x0e, 0xd1, 0x04, 0xf3, 0x67, + 0xc7, 0xcc, 0xcf, 0x0e, 0x8b, 0xb7, 0x6a, 0x89, 0x0b, 0x95, 0x12, 0xa2, + 0x6a, 0x1c, 0x6c, 0x4f, 0xa5, 0x64, 0x3f, 0xdc, 0x83, 0x88, 0x36, 0xcd, + 0x42, 0x4a, 0xe1, 0xe0, 0x29, 0xda, 0xc2, 0xe6, 0x95, 0xa5, 0xf9, 0x60, + 0xf8, 0x74, 0x99, 0x36, 0xb3, 0x50, 0xda, 0x59, 0x24, 0xf4, 0x80, 0xc8, + 0x77, 0x4f, 0xac, 0x23, 0x03, 0x02, 0x18, 0x84, 0xad, 0x2a, 0x61, 0xf0, + 0x7c, 0xda, 0xa0, 0x37, 0xbf, 0xcd, 0x65, 0xbb, 0x27, 0xb3, 0x7b, 0xc4, + 0xd0, 0x1e, 0x23, 0xff, 0x70, 0xe4, 0x3c, 0x2c, 0x06, 0x15, 0xb6, 0x11, + 0xbc, 0xd2, 0x26, 0xc5, 0x7e, 0xf6, 0x62, 0x29, 0x30, 0xa0, 0xe5, 0xab, + 0xde, 0x70, 0x98, 0x24, 0xe7, 0xe1, 0x27, 0x0d, 0xf4, 0xe1, 0xd5, 0x6a, + 0xcb, 0x7e, 0x59, 0xde, 0xe7, 0x8b, 0x69, 0xa2, 0xb9, 0xde, 0xd0, 0xd0, + 0x1f, 0x3f, 0xff, 0xb8, 0x44, 0x51, 0xf6, 0xfa, 0x75, 0x55, 0x3e, 0xe6, + 0x7a, 0x77, 0x7a, 0xe2, 0x6c, 0x45, 0x0a, 0x9a, 0xf0, 0x70, 0xc6, 0x4a, + 0x53, 0xc7, 0x2b, 0xf6, 0x6a, 0x89, 0xef, 0x5e, 0x2c, 0x1e, 0xd4, 0x6b, + 0x9a, 0x07, 0x18, 0x51, 0x33, 0x65, 0xa9, 0x9a, 0xf9, 0xbf, 0x40, 0xa3, + 0xe9, 0x1d, 0x7a, 0x64, 0xc7, 0xac, 0x29, 0xe2, 0x39, 0xcb, 0x57, 0x8b, + 0x53, 0xc3, 0xd1, 0x2f, 0xfa, 0xa8, 0x7c, 0xb6, 0xc6, 0xd7, 0x8b, 0x22, + 0xb6, 0x72, 0x86, 0xa0, 0x24, 0xbf, 0xfa, 0x5b, 0xd1, 0x11, 0x7e, 0xc1, + 0x59, 0x90, 0x3b, 0x58, 0x03, 0x39, 0xbb, 0x25, 0x63, 0x8c, 0xe6, 0x08, + 0xbd, 0x2d, 0xe7, 0x78, 0x1c, 0x2d, 0x4c, 0x7c, 0x06, 0x0a, 0xd9, 0x31, + 0x98, 0x90, 0x23, 0x8e, 0xc7, 0x60, 0x1c, 0x9c, 0x70, 0x5c, 0xd3, 0x0d, + 0xb3, 0xa9, 0x58, 0x0f, 0x6d, 0x0e, 0xa7, 0xcb, 0x27, 0xe5, 0xd0, 0xdb, + 0xa3, 0x60, 0xec, 0x2c, 0x0a, 0xe2, 0x50, 0xfd, 0xb5, 0x41, 0x08, 0x4a, + 0x49, 0x9e, 0xd6, 0x77, 0xde, 0xf6, 0x5d, 0x5a, 0x4f, 0x2a, 0x61, 0x61, + 0xcf, 0xd4, 0x96, 0x0d, 0xfb, 0x0a, 0x83, 0x50, 0x62, 0x61, 0x6a, 0x44, + 0x94, 0xb8, 0xab, 0x57, 0xf7, 0xf9, 0xb9, 0xc4, 0x39, 0x65, 0xbc, 0x0d, + 0x4e, 0xf0, 0x38, 0xc3, 0x7d, 0x1f, 0xeb, 0x3f, 0x80, 0x6b, 0xe5, 0x90, + 0xb9, 0xa2, 0xce, 0x6a, 0xa6, 0x18, 0x40, 0xc9, 0x59, 0x5e, 0xee, 0xf7, + 0x41, 0x84, 0xe4, 0xf1, 0x47, 0x85, 0x7d, 0x8a, 0x38, 0x1f, 0xb7, 0xee, + 0xd5, 0x18, 0xa2, 0xdb, 0xc5, 0xef, 0x65, 0xce, 0xae, 0x1b, 0x9f, 0xb4, + 0xe1, 0x00, 0x7d, 0xfb, 0x6f, 0xf3, 0x76, 0xde, 0x73, 0x54, 0xde, 0xcc, + 0x35, 0x04, 0x43, 0x18, 0x79, 0x7a, 0xd6, 0xa5, 0xd9, 0xc0, 0x45, 0x19, + 0x87, 0x93, 0xb3, 0xd0, 0x09, 0xe4, 0x0b, 0x4a, 0xa8, 0xa8, 0xd6, 0xe0, + 0x14, 0x25, 0x71, 0xce, 0x58, 0xbc, 0xbd, 0x32, 0x44, 0x8d, 0x08, 0x1e, + 0x2a, 0x44, 0xa1, 0x0f, 0xff, 0xa6, 0xed, 0x42, 0x62, 0xb3, 0x40, 0xb6, + 0xff, 0x81, 0xef, 0x3d, 0xa8, 0x0a, 0xe4, 0x44, 0x78, 0x8a, 0x74, 0xde, + 0x4e, 0x37, 0x1b, 0xc9, 0x14, 0x14, 0xb8, 0x6c, 0xcf, 0x84, 0x0b, 0x2d, + 0x58, 0x44, 0xfd, 0x25, 0x95, 0x18, 0x55, 0x70, 0xbc, 0xb4, 0x9b, 0xd2, + 0xcc, 0xd6, 0x3e, 0x57, 0x7d, 0xf5, 0x2d, 0x72, 0xce, 0xa8, 0xab, 0x88, + 0xa1, 0xc6, 0x74, 0x05, 0x9c, 0x4b, 0x75, 0xb1, 0xf2, 0x55, 0x5a, 0x05, + 0xd4, 0x41, 0xea, 0xa8, 0x0c, 0x1b, 0x74, 0x1c, 0xa5, 0x4f, 0x70, 0x18, + 0x4d, 0x29, 0x6a, 0x9c, 0x9b, 0xe8, 0x5a, 0x36, 0xe0, 0x89, 0x64, 0xfa, + 0xdd, 0xe8, 0x69, 0x41, 0x20, 0xba, 0x7c, 0x50, 0x9c, 0x4a, 0xad, 0x48, + 0xa2, 0xc9, 0x93, 0x09, 0x0b, 0x29, 0x6f, 0x43, 0x5c, 0xe6, 0x89, 0xf7, + 0x20, 0xb4, 0xa6, 0x96, 0xcf, 0x6f, 0xd1, 0xd8, 0x50, 0x75, 0x5d, 0xf5, + 0x04, 0x52, 0xdf, 0x2d, 0xcf, 0x02, 0xb4, 0xd4, 0xcb, 0x62, 0x30, 0xa9, + 0x4c, 0x6f, 0xd0, 0x72, 0x9a, 0x6c, 0x9b, 0x9f, 0xb7, 0xc5, 0xab, 0x4b, + 0x2a, 0xf0, 0xf1, 0x50, 0xef, 0xb1, 0x9f, 0x45, 0xe5, 0x28, 0x50, 0x48, + 0x15, 0x72, 0xca, 0x0e, 0x30, 0x3f, 0x6e, 0x37, 0xc5, 0x0d, 0xb5, 0xed, + 0x24, 0xef, 0x39, 0xc0, 0xad, 0x6e, 0xe6, 0x26, 0xf2, 0x08, 0x5b, 0xc3, + 0x6b, 0x74, 0x99, 0x55, 0x20, 0xa6, 0xfe, 0x78, 0x0b, 0xb1, 0x50, 0x7d, + 0x7f, 0xcc, 0x9c, 0x0f, 0x7d, 0x44, 0x5c, 0x0b, 0x14, 0x4b, 0x04, 0x01, + 0x05, 0x42, 0xec, 0x6e, 0x46, 0x70, 0xa6, 0x70, 0xb6, 0x74, 0x18, 0x2b, + 0xf2, 0xcb, 0x0e, 0x99, 0xe0, 0xeb, 0xde, 0x9c, 0x9f, 0xcd, 0xad, 0x12, + 0xcc, 0x9d, 0x5e, 0x40, 0xe0, 0x89, 0x02, 0x44, 0x1b, 0xce, 0xd0, 0xdc, + 0x98, 0xf8, 0xf1, 0xa9, 0xf6, 0x55, 0xa6, 0x67, 0x79, 0x54, 0xa9, 0xf7, + 0xf8, 0x56, 0xbf, 0x2a, 0xc3, 0x51, 0x18, 0x37, 0x18, 0xf4, 0x0e, 0xdb, + 0xd1, 0x7d, 0xe9, 0xa0, 0xd8, 0x85, 0xae, 0x0d, 0x9c, 0x58, 0x2d, 0x01, + 0xa8, 0xf1, 0xb1, 0xf8, 0x40, 0x1f, 0xaa, 0x69, 0x7e, 0xfa, 0x95, 0x73, + 0xb7, 0xa2, 0xa0, 0x7b, 0xfd, 0xaf, 0xfb, 0x77, 0x3f, 0xd9, 0xfc, 0xb6, + 0x6c, 0xd5, 0xaf, 0x62, 0x37, 0x0b, 0xd9, 0xff, 0x94, 0xdc, 0xcf, 0xde, + 0x14, 0xf6, 0x1f, 0x08, 0xa0, 0xc1, 0x0c, 0x21, 0x07, 0xc9, 0xc1, 0x8b, + 0x55, 0x07, 0x4a, 0xf9, 0x15, 0xa0, 0x0f, 0x78, 0x47, 0x12, 0xba, 0xd2, + 0xd3, 0x08, 0xa8, 0xeb, 0xc3, 0xc0, 0xb5, 0x49, 0x9d, 0x7c, 0x7b, 0x4f, + 0x05, 0x85, 0x7c, 0x2c, 0x21, 0x18, 0x5a, 0x21, 0xa5, 0x16, 0xf5, 0xe5, + 0x9a, 0x2e, 0xdf, 0xf3, 0xcb, 0x4f, 0xac, 0x55, 0xb6, 0x79, 0x64, 0x40, + 0x97, 0x76, 0xe1, 0x96, 0x25, 0xce, 0xa1, 0x87, 0x86, 0xbf, 0x23, 0x0b, + 0xc9, 0x04, 0x64, 0xcc, 0x07, 0x96, 0x62, 0xbd, 0xb8, 0x39, 0x6d, 0xba, + 0x54, 0xc3, 0x52, 0x72, 0x70, 0x0a, 0x8e, 0x75, 0x7a, 0x55, 0x81, 0xc0, + 0x31, 0x18, 0x7a, 0xaa, 0x87, 0x23, 0xff, 0xb5, 0xe2, 0xbf, 0x46, 0x76, + 0x29, 0x41, 0xc9, 0xfb, 0x21, 0xe2, 0xf7, 0xca, 0x24, 0x05, 0xba, 0xd3, + 0x8d, 0xe4, 0x8b, 0x80, 0x53, 0x6c, 0xa9, 0x46, 0x9a, 0xb0, 0x60, 0x7c, + 0x52, 0x0c, 0xa1, 0x52, 0x61, 0xf6, 0xeb, 0x65, 0xbe, 0xde, 0xc1, 0xc0, + 0x71, 0xb2, 0x2c, 0x88, 0x1c, 0x64, 0x67, 0xf5, 0x45, 0xb3, 0x70, 0x92, + 0xd1, 0xa4, 0xb9, 0x73, 0x9d, 0x80, 0x92, 0xc8, 0xb8, 0xb0, 0x24, 0xb6, + 0x56, 0x81, 0xf4, 0xbe, 0xb7, 0x15, 0x2f, 0x96, 0xa9, 0xee, 0xfa, 0x22, + 0xa8, 0x2a, 0x95, 0x2a, 0x4c, 0x05, 0x76, 0x01, 0x84, 0x01, 0xea, 0x46, + 0xd3, 0xa7, 0x98, 0x3e, 0x65, 0xab, 0x3d, 0x54, 0x2c, 0xd6, 0xed, 0x9d, + 0x2d, 0x9e, 0x11, 0x75, 0x67, 0xa2, 0x10, 0x1a, 0x85, 0xe5, 0x4c, 0x0f, + 0x07, 0xe9, 0x7f, 0x99, 0x39, 0xbe, 0x61, 0x4f, 0xbb, 0xc0, 0xea, 0xfd, + 0x4a, 0x8c, 0xc0, 0xdc, 0x18, 0x80, 0x5d, 0x01, 0x87, 0x42, 0x3b, 0x69, + 0xe6, 0xab, 0xf2, 0x65, 0x5e, 0xbf, 0xeb, 0x61, 0xec, 0xa5, 0x5d, 0x0e, + 0xa0, 0xd8, 0x0c, 0xe0, 0x2d, 0x44, 0x77, 0x15, 0x28, 0x8a, 0x5b, 0x52, + 0x0a, 0x80, 0x62, 0x14, 0x53, 0x21, 0x0b, 0x66, 0x70, 0x46, 0xc5, 0x61, + 0xea, 0x6f, 0xe3, 0x71, 0x4a, 0x84, 0x5c, 0xbd, 0x14, 0x0b, 0x0b, 0x81, + 0xbc, 0x3f, 0x57, 0x54, 0x0e, 0x19, 0xcf, 0x28, 0xed, 0x57, 0x24, 0xc9, + 0xde, 0x74, 0xb3, 0xca, 0x46, 0xfa, 0x0e, 0xf1, 0x00, 0x54, 0x8c, 0x0f, + 0x00, 0x39, 0xaf, 0x70, 0xb3, 0x2d, 0xc9, 0x9d, 0xdd, 0xac, 0x97, 0xfe, + 0x44, 0x65, 0x8a, 0x4a, 0xb3, 0x31, 0x6d, 0x53, 0x85, 0x9e, 0x06, 0x21, + 0x27, 0x34, 0x49, 0x6f, 0xc0, 0xf0, 0x50, 0x0c, 0xa6, 0xc9, 0x7f, 0x7d, + 0x7c, 0xac, 0xbf, 0x64, 0xf4, 0x96, 0x77, 0xb3, 0xc0, 0xc8, 0x41, 0xc2, + 0x28, 0x31, 0x18, 0xee, 0xa8, 0x40, 0x44, 0x79, 0x68, 0xa8, 0xb0, 0xb2, + 0x21, 0x17, 0x0f, 0xc4, 0x64, 0xd5, 0xa4, 0x82, 0x41, 0x7a, 0xb4, 0xfb, + 0x80, 0x5f, 0xfe, 0x69, 0x8b, 0x64, 0x0e, 0xa4, 0x51, 0xa5, 0x58, 0x8f, + 0x42, 0xd2, 0xd8, 0x3c, 0x05, 0x09, 0x7d, 0xeb, 0x3e, 0x89, 0x32, 0x0d, + 0x87, 0x2d, 0xc5, 0x0d, 0x0c, 0xb0, 0xb7, 0x5b, 0x07, 0x07, 0x80, 0x90, + 0x5f, 0xd8, 0x23, 0x83, 0xc2, 0x7f, 0xd6, 0x23, 0xb4, 0xd4, 0x5c, 0xa8, + 0xb9, 0x8f, 0x34, 0xde, 0xf1, 0x7e, 0x16, 0xe9, 0x68, 0xe3, 0x14, 0x4a, + 0x0f, 0x9b, 0xff, 0xd9, 0xf1, 0xf8, 0x21, 0xfa, 0x7c, 0x70, 0xc4, 0xd1, + 0xfa, 0x8a, 0x59, 0xc5, 0x3f, 0xb8, 0xb2, 0x0a, 0x1f, 0x03, 0x02, 0x4e, + 0xf5, 0xf6, 0x6a, 0xa6, 0x2e, 0x8a, 0xf3, 0xba, 0x5e, 0x08, 0x23, 0xd9, + 0xf4, 0x4d, 0x65, 0x05, 0x32, 0x98, 0x8e, 0x56, 0x74, 0x19, 0x06, 0x03, + 0x06, 0xc1, 0xc1, 0x81, 0x52, 0x61, 0xf0, 0x1f, 0x5b, 0x80, 0xaa, 0x12, + 0x32, 0xa3, 0x4c, 0x5c, 0xc4, 0x8d, 0xd2, 0x5f, 0xd5, 0x03, 0x70, 0x23, + 0xa5, 0xbf, 0x06, 0x3a, 0x21, 0xf0, 0x96, 0xdf, 0x93, 0x63, 0x6c, 0xb0, + 0x1f, 0x76, 0x75, 0xa5, 0x59, 0xe5, 0xe4, 0xbc, 0x0f, 0x68, 0x89, 0x99, + 0xab, 0x16, 0x29, 0x06, 0x3a, 0xb5, 0xd0, 0x86, 0xae, 0x87, 0x8d, 0x6c, + 0xc0, 0xdb, 0x92, 0xa8, 0xea, 0x3e, 0x87, 0x20, 0xc4, 0xe7, 0x57, 0x00, + 0x00, 0xa3, 0x08, 0x6c, 0x98, 0x37, 0x15, 0x17, 0x84, 0x04, 0xc9, 0x9b, + 0x63, 0x15, 0xb0, 0xca, 0xa4, 0xda, 0xce, 0x08, 0x92, 0xc5, 0x5e, 0xe0, + 0x13, 0x04, 0xb0, 0xd6, 0x3b, 0x06, 0x08, 0x45, 0xd6, 0x7f, 0x47, 0x40, + 0x63, 0xe8, 0xe7, 0xb7, 0xbb, 0xee, 0x92, 0x51, 0xbe, 0x03, 0xe5, 0xc0, + 0x0e, 0x81, 0x75, 0x07, 0x82, 0x80, 0x64, 0xb9, 0x47, 0x38, 0x06, 0x98, + 0x52, 0x81, 0x7a, 0xd3, 0x82, 0xae, 0xf6, 0x3c, 0x94, 0x27, 0xc5, 0xb0, + 0xeb, 0x61, 0x58, 0x46, 0x56, 0xcd, 0x12, 0x93, 0x34, 0x9e, 0xe8, 0x29, + 0xfd, 0x31, 0x51, 0x7a, 0x94, 0x7d, 0xf7, 0xb9, 0xc9, 0x44, 0x55, 0x3b, + 0x14, 0xa9, 0x06, 0x21, 0x4b, 0x00, 0xbb, 0x66, 0xf8, 0xc8, 0x64, 0xf5, + 0x65, 0xd5, 0x25, 0xb6, 0xec, 0x90, 0x6e, 0xba, 0xdb, 0xe4, 0x32, 0x86, + 0x98, 0x57, 0xe0, 0x71, 0x8a, 0x4a, 0xac, 0x3e, 0x48, 0x5e, 0x5f, 0x8c, + 0x56, 0xf5, 0xac, 0xad, 0xfa, 0x0d, 0x94, 0x87, 0x9c, 0xb3, 0xa1, 0xc2, + 0x83, 0xe5, 0xf7, 0xae, 0x84, 0x29, 0x8d, 0x02, 0x18, 0x97, 0x82, 0x51, + 0x73, 0x6a, 0xe8, 0xde, 0x74, 0x71, 0x8b, 0x77, 0xec, 0xa0, 0x81, 0x9e, + 0x83, 0x09, 0x82, 0xf8, 0x33, 0x05, 0xed, 0x97, 0x80, 0x70, 0x8d, 0xf6, + 0x7f, 0xd6, 0x59, 0x2e, 0x9b, 0xf4, 0x0b, 0xcf, 0xef, 0x8b, 0x64, 0x0e, + 0x16, 0x70, 0x7b, 0x4e, 0x3d, 0x6c, 0x20, 0xd8, 0xad, 0x91, 0x13, 0xf9, + 0x15, 0x01, 0x0f, 0x5b, 0x28, 0x78, 0x56, 0x37, 0x69, 0x48, 0x3e, 0x47, + 0xff, 0x60, 0xb4, 0x10, 0x92, 0x7d, 0x85, 0x60, 0x19, 0xad, 0xb3, 0x41, + 0xc9, 0x04, 0x88, 0x5d, 0xf4, 0xd8, 0xb3, 0x57, 0xe5, 0xe5, 0x97, 0xed, + 0x86, 0xb9, 0xb2, 0x67, 0xb0, 0x1f, 0x23, 0xff, 0xb6, 0xc5, 0xba, 0xf8, + 0xd8, 0xa7, 0x71, 0xe1, 0xf0, 0x4b, 0x69, 0x58, 0x38, 0x14, 0x6a, 0xd5, + 0xe3, 0x3e, 0xd5, 0x57, 0x1a, 0x55, 0xf5, 0x57, 0x3b, 0x7b, 0xee, 0xc8, + 0x1e, 0x86, 0xb7, 0xe5, 0x40, 0xb7, 0x32, 0x10, 0xc7, 0xe0, 0xca, 0x07, + 0x49, 0xcb, 0xd0, 0xb1, 0x91, 0x41, 0x2e, 0xdb, 0x3d, 0x03, 0x30, 0x60, + 0xa4, 0x30, 0xd0, 0x52, 0xe5, 0x6e, 0xd6, 0xa3, 0x69, 0x59, 0xaa, 0xd1, + 0x62, 0xca, 0x76, 0xaf, 0x6d, 0xa0, 0xb4, 0x12, 0x4d, 0xe5, 0x56, 0x5d, + 0x6e, 0xa8, 0x06, 0x26, 0x59, 0xc2, 0x14, 0xc2, 0xfb, 0x42, 0x4f, 0xbb, + 0xe2, 0xa2, 0xcb, 0x99, 0x27, 0xa7, 0x4a, 0xa2, 0xdc, 0x9c, 0x06, 0x13, + 0x15, 0x54, 0xad, 0x2a, 0x95, 0x3d, 0x37, 0xc8, 0x22, 0x73, 0xa0, 0xc1, + 0x48, 0x47, 0x1d, 0x30, 0x39, 0x2c, 0xdb, 0x39, 0xbc, 0xce, 0xf2, 0x5d, + 0xe6, 0xad, 0x6c, 0x58, 0x4e, 0x2a, 0x6f, 0xf1, 0xa6, 0xb1, 0x9f, 0xb0, + 0x6a, 0x61, 0xbb, 0x79, 0xd9, 0x78, 0x1a, 0x39, 0xd9, 0x5b, 0xa4, 0xd0, + 0xb1, 0x24, 0x2f, 0x03, 0x6d, 0x79, 0x07, 0xda, 0xb1, 0x64, 0x1c, 0xe2, + 0x37, 0x6e, 0xd2, 0xd8, 0xcf, 0x6f, 0x72, 0x5c, 0xe0, 0x89, 0xcb, 0x65, + 0x44, 0x1c, 0x9c, 0x3e, 0x20, 0xd4, 0xfb, 0x2a, 0x2e, 0x20, 0x0c, 0x4f, + 0x6d, 0x66, 0xb1, 0x64, 0xfa, 0x14, 0x44, 0xae, 0x3d, 0xcf, 0x36, 0x80, + 0xe6, 0xdb, 0x9b, 0xd5, 0x91, 0x14, 0x74, 0x84, 0x60, 0x3f, 0x53, 0xd6, + 0x7c, 0x1c, 0x87, 0xad, 0x21, 0x9d, 0x88, 0x02, 0x94, 0x58, 0x57, 0x14, + 0x95, 0xf2, 0xcb, 0xde, 0x62, 0x2a, 0xba, 0x23, 0xc8, 0xff, 0x27, 0x25, + 0x8b, 0xdc, 0xea, 0x84, 0x15, 0x11, 0x33, 0xeb, 0x8e, 0x65, 0xd7, 0x6d, + 0x03, 0x2e, 0xc7, 0x50, 0xc9, 0x71, 0x45, 0x47, 0x16, 0xe0, 0x3b, 0x0c, + 0xab, 0x9b, 0xf5, 0x5e, 0x1f, 0x4d, 0x05, 0x68, 0x81, 0xaa, 0xf5, 0x5f, + 0xf5, 0x17, 0xbb, 0xd2, 0xc9, 0x01, 0xc3, 0x60, 0xdc, 0xc1, 0x92, 0xdf, + 0xb7, 0x8c, 0x5f, 0x77, 0x39, 0xa1, 0xea, 0x0e, 0xdb, 0x3b, 0xca, 0x1c, + 0x98, 0x69, 0xf6, 0x4f, 0x36, 0x39, 0x2a, 0xdb, 0xf9, 0xfe, 0x7a, 0x42, + 0xbf, 0x7a, 0xad, 0x39, 0x44, 0x5d, 0x30, 0xe7, 0xdc, 0xa5, 0x63, 0xdc, + 0x53, 0x56, 0xde, 0x0c, 0xe3, 0xce, 0x5a, 0xdd, 0xd9, 0x16, 0xe3, 0x1e, + 0xf6, 0x96, 0xd5, 0x94, 0xac, 0xbc, 0xe6, 0x15, 0x05, 0xa6, 0x77, 0xf8, + 0x9c, 0x7c, 0xd7, 0xd8, 0xfd, 0xde, 0x5a, 0x1d, 0x87, 0x76, 0xc5, 0xaa, + 0xc1, 0xb1, 0xe4, 0xda, 0x6c, 0x14, 0xec, 0x56, 0x2d, 0x51, 0xf5, 0x08, + 0xf8, 0x32, 0xec, 0x0e, 0x40, 0x4f, 0x6d, 0x0d, 0xe3, 0x2a, 0x90, 0x29, + 0xaa, 0x54, 0x51, 0x81, 0xc3, 0x41, 0xda, 0x6c, 0xf6, 0xc0, 0xf4, 0xb9, + 0x7f, 0xfa, 0xae, 0x39, 0x61, 0x15, 0x82, 0xf7, 0x1b, 0x1f, 0x7e, 0xa9, + 0xd1, 0xf3, 0x28, 0xe2, 0x9c, 0x88, 0x3b, 0x62, 0x38, 0x04, 0xc6, 0xe1, + 0x69, 0x76, 0xbc, 0xdf, 0x87, 0xb1, 0x8a, 0x1d, 0x6f, 0xad, 0xc9, 0x50, + 0x43, 0x41, 0xa0, 0x25, 0x46, 0x2d, 0xa9, 0x2c, 0x69, 0xa5, 0x7d, 0x46, + 0xd5, 0x55, 0xbf, 0xcb, 0xdb, 0xd9, 0x7a, 0xc0, 0x13, 0x46, 0x60, 0x44, + 0xab, 0xda, 0xa8, 0x7d, 0x6a, 0xbb, 0x77, 0x6e, 0x1b, 0x45, 0xde, 0x11, + 0x98, 0x63, 0x8c, 0xe2, 0x52, 0xee, 0x5c, 0x9f, 0x56, 0xae, 0x7a, 0xa1, + 0xc6, 0x65, 0x53, 0x2c, 0x0d, 0x70, 0xfb, 0x1d, 0x33, 0xa9, 0x4b, 0x9a, + 0xea, 0xed, 0xaa, 0xd0, 0xf9, 0x94, 0x1d, 0xbe, 0x58, 0x1d, 0xa0, 0x93, + 0x4a, 0x16, 0x58, 0xdc, 0xb4, 0x3f, 0x57, 0x15, 0x26, 0x8b, 0x45, 0xfe, + 0x80, 0xa6, 0x05, 0x67, 0x41, 0x92, 0x8e, 0xa2, 0x50, 0x38, 0x96, 0xa0, + 0x4c, 0xab, 0x74, 0xdd, 0xec, 0x44, 0x0c, 0x09, 0xa1, 0x7c, 0x3e, 0x05, + 0x6c, 0xdc, 0xc9, 0xec, 0xc9, 0x14, 0x20, 0x29, 0xa7, 0x83, 0x08, 0x30, + 0x96, 0xae, 0x60, 0x07, 0x08, 0xeb, 0xf0, 0x19, 0x6d, 0x18, 0xa2, 0x80, + 0xc1, 0x5d, 0x2e, 0xc1, 0xd4, 0x6d, 0x08, 0x0f, 0x26, 0x20, 0x25, 0x24, + 0xfa, 0x55, 0x6c, 0x30, 0xd6, 0x29, 0xfb, 0x7f, 0xcc, 0xf4, 0x25, 0xaf, + 0xd1, 0x11, 0x2d, 0x78, 0x4d, 0x06, 0x05, 0x10, 0x42, 0xad, 0x97, 0xfc, + 0x4b, 0xd8, 0x1e, 0x0f, 0xb2, 0x28, 0xb4, 0x18, 0x39, 0xfc, 0x45, 0x03, + 0x4c, 0x07, 0x29, 0x30, 0xcc, 0xd8, 0x27, 0x8b, 0x81, 0x44, 0x25, 0x08, + 0xca, 0x95, 0x03, 0x2c, 0xd7, 0xd2, 0xc6, 0xbb, 0xad, 0xec, 0xb7, 0xaa, + 0xd6, 0xed, 0x85, 0x6b, 0x15, 0x80, 0x9a, 0x82, 0x37, 0x87, 0x0c, 0x32, + 0x9d, 0x8c, 0x6d, 0x2a, 0x8a, 0x5b, 0xfd, 0xe6, 0xe4, 0xea, 0xfc, 0x93, + 0x54, 0x85, 0x82, 0xc5, 0x6c, 0xa8, 0xd5, 0x05, 0x97, 0x50, 0xdb, 0x96, + 0x52, 0xce, 0x93, 0xbf, 0xec, 0x04, 0x4f, 0xc5, 0x32, 0xff, 0xf2, 0x96, + 0x67, 0x50, 0x8a, 0x48, 0xe4, 0x9c, 0x79, 0x64, 0xcd, 0x86, 0xc0, 0x61, + 0x2c, 0x7a, 0x98, 0x4a, 0x2e, 0x2c, 0x4c, 0xa2, 0x0f, 0x52, 0x87, 0x8a, + 0x31, 0x65, 0x1e, 0xa8, 0xff, 0x62, 0x00, 0x60, 0x8c, 0x35, 0x02, 0x88, + 0x20, 0x36, 0xc9, 0x5a, 0x8e, 0xa1, 0xe2, 0x3b, 0x7a, 0x8a, 0x40, 0xe7, + 0x4c, 0x9a, 0x2e, 0x06, 0x48, 0xcb, 0x25, 0xff, 0x2f, 0x08, 0x2c, 0xa9, + 0x67, 0xff, 0xdf, 0x88, 0x1e, 0xed, 0xfc, 0x95, 0x12, 0xe2, 0x22, 0x90, + 0x7c, 0x78, 0x01, 0xc1, 0x79, 0x83, 0xc5, 0x43, 0xc0, 0xf3, 0x3a, 0x5c, + 0xc2, 0xc1, 0xd4, 0xe7, 0xed, 0x29, 0xd2, 0xbb, 0xa1, 0xa1, 0x60, 0xb1, + 0xae, 0xa9, 0xfa, 0xe4, 0x46, 0x5d, 0x5c, 0x16, 0xad, 0x85, 0xdd, 0x06, + 0x82, 0x39, 0x7d, 0x06, 0x5f, 0x3c, 0xc3, 0x19, 0xd1, 0x01, 0x4b, 0x2a, + 0x27, 0xb2, 0x50, 0xf1, 0x61, 0x17, 0x73, 0x8e, 0x15, 0x0f, 0x81, 0x00, + 0x74, 0x5d, 0xef, 0xfa, 0xf9, 0x20, 0xfd, 0xbf, 0x8d, 0xeb, 0x7f, 0xb7, + 0xd2, 0x21, 0x94, 0xa8, 0x18, 0x2a, 0xe0, 0xc5, 0x82, 0x40, 0xfe, 0xdb, + 0xf4, 0xe3, 0xf6, 0xff, 0xaa, 0x54, 0x7f, 0x7f, 0xcf, 0x49, 0xda, 0xb4, + 0x11, 0x1a, 0x0e, 0x00, 0x88, 0x30, 0xad, 0x26, 0x80, 0xf0, 0xe9, 0xac, + 0x9c, 0xf2, 0xb2, 0xc5, 0x94, 0xe6, 0xfe, 0xa8, 0xdb, 0xc0, 0x2b, 0x46, + 0xfb, 0x88, 0xca, 0x8b, 0x40, 0x54, 0xfe, 0xdf, 0x91, 0xbd, 0xf8, 0x5b, + 0x68, 0x08, 0x11, 0x40, 0xe3, 0x04, 0x7a, 0x91, 0x23, 0x41, 0xda, 0x61, + 0x29, 0x53, 0x49, 0x3d, 0x32, 0x15, 0x70, 0x41, 0xdd, 0x53, 0x81, 0xc2, + 0x90, 0xf0, 0x12, 0x92, 0x83, 0xc5, 0x6c, 0xaa, 0x99, 0x89, 0x41, 0x94, + 0x35, 0xda, 0x54, 0xa8, 0x1c, 0x94, 0x7f, 0x49, 0x59, 0x2f, 0x52, 0x55, + 0xba, 0xb1, 0x56, 0x16, 0x83, 0xe4, 0x40, 0x0e, 0x49, 0x82, 0xe4, 0xca, + 0x81, 0xe0, 0xe0, 0x17, 0x69, 0x84, 0x93, 0xa1, 0xed, 0x64, 0xae, 0xd2, + 0x48, 0x0b, 0x6d, 0xbb, 0xa1, 0xed, 0x9f, 0xee, 0x7a, 0x69, 0x6a, 0x8c, + 0xbc, 0x58, 0xaf, 0xb0, 0x39, 0xd1, 0x10, 0x2d, 0x77, 0xbf, 0x82, 0x37, + 0x95, 0x5c, 0xdb, 0xe6, 0x44, 0x76, 0x43, 0x92, 0xff, 0xf9, 0xa6, 0x3a, + 0x51, 0xa5, 0xbb, 0xa8, 0xa1, 0x5e, 0x80, 0xb4, 0x9b, 0x68, 0x0f, 0xa5, + 0x2d, 0x07, 0x17, 0xb0, 0xc3, 0x53, 0xbc, 0x2c, 0xaa, 0x63, 0x59, 0x11, + 0xcf, 0x4c, 0x2a, 0x02, 0x7a, 0x5a, 0x88, 0x16, 0xeb, 0xa9, 0x4a, 0xdc, + 0x91, 0x84, 0xc9, 0x6f, 0xef, 0xe4, 0xf6, 0xab, 0xf7, 0x9a, 0xe7, 0x91, + 0x96, 0xf0, 0x45, 0xc5, 0x05, 0x4a, 0x41, 0xc6, 0x0b, 0x32, 0xa9, 0xb2, + 0xbe, 0xb3, 0xcd, 0xb2, 0xf1, 0x47, 0xf9, 0x3a, 0x87, 0x90, 0x45, 0x31, + 0xf6, 0x61, 0xa0, 0x0e, 0xac, 0xc1, 0xc8, 0x92, 0x10, 0xdb, 0x4e, 0xd4, + 0x0e, 0xa7, 0xbf, 0x7d, 0x0b, 0x0d, 0x5b, 0x03, 0x93, 0xe2, 0xff, 0x62, + 0x44, 0xca, 0x18, 0x2e, 0x55, 0x31, 0x69, 0xca, 0xb0, 0xbe, 0x88, 0x80, + 0xe3, 0x2a, 0xe2, 0x6c, 0x8c, 0x7b, 0xd9, 0xf9, 0x76, 0x48, 0xa7, 0x76, + 0x15, 0x6f, 0xf8, 0x8b, 0x88, 0x14, 0xe8, 0x3e, 0x3f, 0xff, 0x6a, 0xd4, + 0x85, 0x72, 0xa5, 0x6f, 0x7f, 0x68, 0x14, 0xf5, 0xe7, 0xa1, 0x48, 0x72, + 0x84, 0x18, 0x9b, 0xec, 0x8c, 0x1c, 0xcc, 0x0f, 0x6c, 0xcb, 0x6a, 0xe5, + 0x7d, 0x9c, 0xe2, 0xd0, 0x12, 0x31, 0x6f, 0x83, 0x95, 0xf8, 0x8e, 0x2c, + 0xe3, 0x7a, 0xcb, 0x05, 0x93, 0xcd, 0x2d, 0x18, 0x52, 0x8a, 0x2c, 0x8d, + 0x79, 0x03, 0x90, 0x12, 0xb3, 0x4a, 0xea, 0xbd, 0xe0, 0x80, 0xa7, 0x0d, + 0xd4, 0x10, 0xd9, 0xef, 0x7f, 0x00, 0x00, 0xa8, 0x08, 0x6c, 0x82, 0x69, + 0x41, 0xb8, 0x5c, 0x0f, 0x0f, 0x00, 0x7a, 0xa0, 0x78, 0xb8, 0x02, 0x5d, + 0x57, 0x54, 0x23, 0x87, 0x44, 0x41, 0x0b, 0x18, 0x4a, 0x10, 0x07, 0x4a, + 0x64, 0xd2, 0xc2, 0xe5, 0x4d, 0x03, 0xc5, 0x40, 0x1b, 0x08, 0x83, 0x10, + 0x21, 0xe0, 0xec, 0x75, 0xfd, 0xfb, 0x42, 0x55, 0x4a, 0x3c, 0x9e, 0xb4, + 0x41, 0x63, 0x41, 0x5b, 0xe9, 0x10, 0x7f, 0xda, 0x8c, 0x15, 0x06, 0x45, + 0x8f, 0x0b, 0xa0, 0x73, 0x76, 0x20, 0xe1, 0x6f, 0x96, 0x5e, 0xd8, 0x15, + 0xa8, 0x25, 0x66, 0xcc, 0x12, 0x40, 0x3b, 0xf7, 0xb4, 0x15, 0xbf, 0x1f, + 0x7e, 0xa1, 0x2e, 0x67, 0xa1, 0xe4, 0x06, 0x0d, 0x1b, 0xee, 0x02, 0xb8, + 0x2c, 0x1f, 0x0f, 0x87, 0xe9, 0x47, 0xbf, 0x94, 0x74, 0x3a, 0x2f, 0x5b, + 0xaa, 0x5b, 0xdf, 0x49, 0xef, 0x59, 0x38, 0xb7, 0xd0, 0xee, 0xe8, 0x08, + 0x37, 0x8a, 0xcb, 0xc4, 0x81, 0x1f, 0x3e, 0x94, 0xb5, 0x53, 0x7f, 0xfc, + 0x2d, 0x52, 0x1f, 0xb3, 0xfb, 0xeb, 0x43, 0xa4, 0xd7, 0x5b, 0x51, 0x98, + 0xa7, 0x85, 0x78, 0xab, 0xc4, 0x45, 0xe0, 0xb2, 0x53, 0x2d, 0x87, 0xd5, + 0x00, 0xc1, 0xf2, 0xbc, 0xdf, 0xb0, 0x5a, 0x20, 0x33, 0x47, 0x09, 0xb7, + 0xb8, 0x20, 0xb3, 0x3f, 0x57, 0x0d, 0x9a, 0xcd, 0x8a, 0x54, 0x81, 0x50, + 0xb0, 0x20, 0x7a, 0x8f, 0x52, 0xfa, 0xfd, 0x89, 0x80, 0xa7, 0x10, 0x26, + 0x96, 0xa2, 0x6b, 0x15, 0xf2, 0x6c, 0x81, 0xa2, 0x90, 0x7c, 0x98, 0x01, + 0xd2, 0x06, 0xd1, 0xf2, 0xbd, 0x10, 0xd3, 0xa7, 0x48, 0xa7, 0xbb, 0x7d, + 0x7e, 0xd2, 0xf6, 0xb6, 0x1e, 0x2e, 0x97, 0xc5, 0x4b, 0xe2, 0x30, 0x60, + 0xac, 0x58, 0x10, 0x36, 0x41, 0x29, 0x52, 0xc5, 0x6c, 0xfa, 0x6e, 0xa0, + 0xbd, 0xe4, 0xe8, 0x30, 0xd3, 0xb8, 0x45, 0x30, 0x85, 0xb3, 0x20, 0xc1, + 0x0f, 0xc0, 0x7c, 0x7e, 0x3e, 0x1f, 0x52, 0xec, 0x9f, 0xc5, 0x5d, 0x6c, + 0x7a, 0x93, 0xdf, 0xea, 0x9f, 0x96, 0x48, 0x1e, 0x03, 0x1b, 0x10, 0x03, + 0xd0, 0x61, 0xa8, 0x7c, 0x06, 0xf2, 0xb1, 0xf2, 0xa4, 0xea, 0xd4, 0xe6, + 0x81, 0xbd, 0xff, 0x1a, 0x96, 0x77, 0x99, 0x10, 0x77, 0x46, 0xc8, 0x41, + 0x18, 0xc4, 0x33, 0xf2, 0x31, 0x00, 0x35, 0x03, 0x81, 0xe8, 0x38, 0x0f, + 0x89, 0x0a, 0x30, 0x7e, 0xd5, 0x52, 0xcf, 0x90, 0x32, 0x6e, 0xc8, 0x22, + 0xb6, 0x0f, 0x97, 0xff, 0xda, 0x60, 0x79, 0xb3, 0x78, 0xa6, 0x18, 0x5b, + 0x38, 0x75, 0xb0, 0x57, 0x03, 0x41, 0x24, 0xb8, 0xbf, 0xec, 0x97, 0x16, + 0xc8, 0xad, 0x52, 0x8d, 0xfb, 0x4b, 0x5b, 0xcf, 0xa2, 0x02, 0x78, 0x05, + 0x70, 0x16, 0xe1, 0x4b, 0x5a, 0x69, 0xb6, 0xae, 0x7c, 0x3a, 0xe7, 0x56, + 0x5a, 0xac, 0x85, 0xc1, 0xf0, 0x19, 0xa0, 0x80, 0x5e, 0x3b, 0x1d, 0xb0, + 0x07, 0x4b, 0xff, 0x0b, 0xa3, 0x1b, 0x1b, 0xf0, 0xe3, 0xc3, 0x86, 0x53, + 0xef, 0x50, 0xa8, 0x1b, 0x60, 0x6a, 0x0c, 0x46, 0x0a, 0x56, 0x95, 0x88, + 0x29, 0x9b, 0x6a, 0xef, 0x34, 0xb3, 0x46, 0xf5, 0x6e, 0xf1, 0x6e, 0xa8, + 0x46, 0x56, 0x56, 0x16, 0x5f, 0xd2, 0xda, 0xa4, 0x12, 0x1c, 0x4c, 0x99, + 0xcc, 0x04, 0x45, 0x54, 0x0c, 0x67, 0x2e, 0xf5, 0x47, 0xf5, 0x7b, 0x64, + 0xab, 0xf2, 0xe9, 0x5e, 0x03, 0x8c, 0x49, 0x7a, 0xa6, 0x87, 0xbe, 0x8a, + 0x6d, 0x53, 0x33, 0xb9, 0xb1, 0x65, 0xc9, 0x43, 0x93, 0x03, 0x44, 0xd9, + 0xbd, 0xf0, 0x37, 0x6c, 0xd5, 0x69, 0x13, 0x4c, 0x2d, 0xf6, 0x71, 0xae, + 0xff, 0x9d, 0x2c, 0xe8, 0xd9, 0x4f, 0x20, 0xd0, 0xbc, 0x1e, 0x96, 0x49, + 0xe5, 0x28, 0x61, 0x2a, 0xc8, 0x60, 0x30, 0x9e, 0xd8, 0x16, 0x2a, 0x63, + 0x95, 0x5f, 0x2f, 0x54, 0x95, 0x7f, 0x7b, 0x1a, 0x49, 0x96, 0xfd, 0x2f, + 0xd1, 0x66, 0x5f, 0x7e, 0x02, 0xb2, 0xa8, 0x02, 0xea, 0x79, 0xbf, 0x02, + 0x9e, 0x16, 0x0b, 0x83, 0xf8, 0xa7, 0x03, 0xdc, 0x5f, 0x3a, 0x6f, 0xb6, + 0x8a, 0xc5, 0x4c, 0x71, 0x3e, 0x7e, 0xf7, 0xb2, 0xf6, 0x6e, 0x71, 0x18, + 0xad, 0x2a, 0x3e, 0xf7, 0x87, 0x16, 0x7a, 0x75, 0x0e, 0x20, 0xb6, 0xc4, + 0x60, 0x8d, 0x21, 0x86, 0x27, 0x32, 0xf5, 0x64, 0x3c, 0x6d, 0x7c, 0xc9, + 0xe1, 0x9c, 0x98, 0x0c, 0x4e, 0x68, 0x18, 0x6f, 0x6a, 0xcd, 0x7e, 0xcb, + 0x8d, 0x54, 0x36, 0x42, 0xc4, 0x7d, 0x0e, 0x34, 0x6e, 0x16, 0x0c, 0x40, + 0xd5, 0xa0, 0xc1, 0xfa, 0xad, 0x51, 0x44, 0x16, 0x3f, 0xcc, 0x44, 0xb5, + 0x8b, 0x76, 0x83, 0x05, 0x52, 0xab, 0x1a, 0x60, 0x79, 0xec, 0xc9, 0x9e, + 0xbe, 0x9b, 0x39, 0xc5, 0x2b, 0xc8, 0x86, 0x88, 0xad, 0xa2, 0x2b, 0x06, + 0x38, 0x70, 0xc5, 0xd8, 0x1a, 0xc4, 0xc3, 0x86, 0xb5, 0x68, 0x56, 0xd7, + 0xb9, 0xbc, 0x93, 0xab, 0xf0, 0xf2, 0x91, 0x33, 0x6a, 0xbf, 0x6c, 0xb3, + 0x64, 0xf5, 0xb8, 0x51, 0xd9, 0x6f, 0xb8, 0x1b, 0x8d, 0xc1, 0x84, 0xda, + 0x33, 0x0b, 0xd2, 0x31, 0xfe, 0x15, 0xaf, 0x91, 0x6e, 0x64, 0xb2, 0xf2, + 0x40, 0xd4, 0x2c, 0xa6, 0xbf, 0x6a, 0x50, 0x34, 0xbd, 0x03, 0x42, 0x08, + 0xe3, 0x54, 0xa1, 0x5a, 0x59, 0x60, 0x6c, 0x36, 0x06, 0x1a, 0xd7, 0xb4, + 0xa8, 0x7c, 0xae, 0xe0, 0x88, 0x9f, 0xfe, 0xbf, 0x35, 0x78, 0xb5, 0x9d, + 0x05, 0xba, 0xc0, 0xab, 0x67, 0xcc, 0xa6, 0xe1, 0x5e, 0x45, 0x0c, 0x32, + 0xa5, 0x19, 0x6f, 0xff, 0xc0, 0x76, 0x72, 0x95, 0x83, 0x10, 0xda, 0x8f, + 0x83, 0x29, 0xc6, 0x6f, 0x07, 0x11, 0xa9, 0x95, 0x7e, 0xec, 0xef, 0x27, + 0x78, 0x27, 0x2f, 0x98, 0x5a, 0x5f, 0x22, 0x89, 0xbc, 0x93, 0x54, 0xa0, + 0x9c, 0x59, 0x60, 0xdc, 0x8e, 0x76, 0x46, 0xa4, 0x6b, 0x59, 0xa9, 0xfc, + 0xb5, 0x9d, 0xea, 0xcb, 0x6a, 0xdd, 0xe8, 0x38, 0xcc, 0x08, 0xdd, 0x4c, + 0x1f, 0xa7, 0xfa, 0x9b, 0x89, 0x59, 0x52, 0x56, 0x8f, 0x85, 0x92, 0x40, + 0xa1, 0x1d, 0x66, 0x66, 0x95, 0x66, 0xae, 0x19, 0x93, 0x9b, 0x2d, 0x57, + 0x7f, 0xf2, 0xde, 0x46, 0xa7, 0x33, 0xd1, 0x4f, 0x6d, 0xa8, 0x7b, 0x06, + 0x40, 0xef, 0x03, 0x11, 0x70, 0xb1, 0x5f, 0xcb, 0xf0, 0x71, 0xdf, 0x54, + 0x70, 0x66, 0x50, 0xe0, 0xfc, 0x0c, 0x10, 0x42, 0x1a, 0x6a, 0x10, 0x34, + 0x75, 0x9b, 0x8c, 0x8f, 0x53, 0xb7, 0x9e, 0x0f, 0x9a, 0xb3, 0x59, 0xcc, + 0x0e, 0xed, 0xff, 0x86, 0xe4, 0x03, 0xfe, 0xfd, 0x17, 0xf1, 0x65, 0x2b, + 0x71, 0x1a, 0xd5, 0x1f, 0x41, 0x2a, 0x1b, 0x08, 0x0c, 0x2a, 0x4e, 0xc9, + 0x78, 0xf9, 0x52, 0xaa, 0xaf, 0xff, 0xff, 0xd5, 0x97, 0x8f, 0xff, 0x36, + 0x35, 0x6c, 0x9d, 0xe5, 0xd1, 0x4c, 0x42, 0xd4, 0x67, 0x1b, 0x0f, 0xcd, + 0x03, 0x60, 0x1d, 0xb7, 0xdb, 0x44, 0xa6, 0x73, 0xdc, 0x96, 0x65, 0xe4, + 0xb6, 0xa3, 0x44, 0x16, 0x82, 0xbc, 0x0e, 0x2a, 0x07, 0x01, 0xe1, 0x19, + 0xa1, 0xf3, 0x0d, 0x34, 0x1f, 0xd0, 0x32, 0x9d, 0xbd, 0xff, 0x32, 0xb3, + 0xf4, 0x70, 0xb2, 0x0d, 0xd4, 0x0d, 0xbc, 0x1e, 0x87, 0x46, 0x01, 0x6e, + 0x59, 0x53, 0x8e, 0x1b, 0xf9, 0x7b, 0x36, 0x2d, 0x98, 0x20, 0x78, 0x40, + 0x48, 0xa7, 0x9b, 0xde, 0x5d, 0xcf, 0x6b, 0x79, 0x99, 0x29, 0x58, 0x31, + 0x15, 0x7b, 0xe3, 0xec, 0xfc, 0x61, 0x85, 0x79, 0xad, 0xa0, 0x0f, 0x6e, + 0xd2, 0x8a, 0x54, 0xa5, 0x48, 0x6c, 0x0c, 0x71, 0xc2, 0xcb, 0xd2, 0x62, + 0xcb, 0x56, 0x6c, 0x52, 0x39, 0xd9, 0x6e, 0xf0, 0xa9, 0x44, 0xcc, 0x5a, + 0x73, 0x9c, 0x1b, 0xe8, 0x30, 0xd4, 0xcc, 0xea, 0xb5, 0x38, 0x5b, 0x58, + 0x6a, 0x22, 0x1c, 0x15, 0x52, 0x8a, 0x1c, 0x18, 0xbb, 0xeb, 0xfe, 0xdd, + 0xe4, 0x1b, 0x96, 0xde, 0x72, 0xf4, 0x92, 0x08, 0x80, 0xe3, 0x2a, 0x8e, + 0x18, 0x4c, 0xa3, 0xad, 0xfd, 0x42, 0xf5, 0x44, 0x8a, 0x54, 0xf1, 0x17, + 0x4a, 0xc9, 0x6e, 0x80, 0x85, 0x73, 0xe9, 0xd6, 0x09, 0x0a, 0xb3, 0xe5, + 0xb2, 0x7f, 0x11, 0xe9, 0x6d, 0x4e, 0xdc, 0x2d, 0xa6, 0xff, 0x30, 0x6f, + 0x9a, 0x1b, 0xfc, 0x1f, 0x22, 0x00, 0x74, 0xc7, 0x09, 0x97, 0x52, 0xda, + 0x1b, 0xfe, 0x2e, 0x59, 0xd5, 0x96, 0x94, 0x6e, 0x65, 0x50, 0x53, 0x97, + 0x62, 0xe0, 0x67, 0xe1, 0xb5, 0xec, 0xce, 0x94, 0x69, 0x50, 0x3e, 0x5f, + 0xff, 0x64, 0x98, 0x6d, 0xa5, 0x79, 0x34, 0x71, 0x4a, 0xb8, 0x4b, 0x8b, + 0xce, 0xf0, 0x55, 0x9e, 0xef, 0x55, 0x9a, 0xe2, 0xaa, 0xa2, 0xa0, 0x83, + 0x8b, 0x44, 0xe6, 0x17, 0x55, 0x9f, 0x66, 0xab, 0xa1, 0xff, 0xfd, 0x03, + 0xcc, 0xc0, 0xf6, 0xd3, 0x50, 0xac, 0x04, 0x4b, 0x31, 0x3b, 0x36, 0x78, + 0x19, 0x12, 0x49, 0x90, 0xad, 0x6d, 0xbb, 0xa8, 0xd1, 0x06, 0xc3, 0x61, + 0x61, 0x6c, 0x68, 0xbb, 0x01, 0x97, 0x99, 0xdf, 0xe0, 0xdc, 0xb5, 0x7d, + 0xec, 0x47, 0x43, 0x64, 0x20, 0x2e, 0xe5, 0xa9, 0x15, 0xab, 0x8d, 0x4d, + 0x06, 0x1c, 0x7f, 0xf3, 0x17, 0xfb, 0x2a, 0xf7, 0xd6, 0xe5, 0xa8, 0x6f, + 0xb0, 0xaf, 0x01, 0xc6, 0x0e, 0x83, 0xc1, 0x7f, 0xc6, 0xdf, 0xef, 0xfd, + 0xac, 0xc5, 0x3c, 0x1c, 0x31, 0x9a, 0x06, 0x98, 0x2c, 0xea, 0xe3, 0x75, + 0x3a, 0xa1, 0x16, 0x03, 0x13, 0x99, 0x06, 0x10, 0x6e, 0xa7, 0xd0, 0x78, + 0x28, 0x05, 0xee, 0xfa, 0x72, 0xb0, 0xce, 0x7e, 0xdf, 0x7e, 0xd4, 0x56, + 0xf9, 0x42, 0x81, 0xb5, 0xa0, 0x24, 0x49, 0xdd, 0x8d, 0x6d, 0x6f, 0xd3, + 0xdc, 0xea, 0x8c, 0xf7, 0x3b, 0xc8, 0xb9, 0x68, 0x6c, 0x89, 0x40, 0x30, + 0x9f, 0x5e, 0x1e, 0x2c, 0x48, 0xd0, 0x1b, 0x92, 0xd1, 0xdb, 0x2c, 0x29, + 0xd0, 0xeb, 0xca, 0xbb, 0xe9, 0x09, 0x2d, 0x11, 0x41, 0xf2, 0x60, 0x07, + 0xe1, 0xfc, 0xcb, 0x56, 0xc0, 0xcd, 0x4e, 0x8a, 0x46, 0xc2, 0x52, 0x5f, + 0x2b, 0xdd, 0x69, 0x85, 0x48, 0xbb, 0xa0, 0xad, 0xde, 0xa1, 0x5e, 0xdb, + 0xb8, 0xa5, 0x42, 0x90, 0x7c, 0xf8, 0x01, 0xc5, 0x6a, 0x43, 0xdf, 0x67, + 0xb3, 0xdd, 0x93, 0xb4, 0x9b, 0x6a, 0x28, 0xbc, 0xa2, 0xb3, 0x7d, 0x56, + 0x88, 0x96, 0x5e, 0xde, 0x70, 0xd8, 0x24, 0x74, 0xe5, 0xcd, 0xfe, 0x5c, + 0x9f, 0x99, 0x94, 0x44, 0x11, 0x78, 0x0c, 0x13, 0xc3, 0x34, 0xaa, 0x96, + 0x5c, 0x2d, 0x81, 0xea, 0x8e, 0xf0, 0x60, 0x1b, 0x29, 0x3e, 0xbf, 0xb5, + 0x94, 0xbe, 0x02, 0x0d, 0xc8, 0x04, 0x4a, 0x89, 0x78, 0x54, 0x57, 0xa6, + 0x25, 0xb3, 0x1e, 0x1e, 0x66, 0x72, 0x5d, 0xdd, 0x2b, 0x5e, 0x23, 0x83, + 0x30, 0x61, 0x39, 0x60, 0x2d, 0x35, 0x65, 0x11, 0x72, 0xda, 0x8a, 0xf0, + 0x91, 0xd2, 0xc3, 0x51, 0x8a, 0x57, 0xa2, 0x0b, 0x77, 0xb5, 0x4d, 0xec, + 0x92, 0x52, 0x04, 0x16, 0xd5, 0x0a, 0x67, 0x56, 0x0f, 0x4d, 0x28, 0x25, + 0x7f, 0xb6, 0xb8, 0x07, 0x08, 0xe2, 0x40, 0x29, 0x8b, 0x87, 0xd8, 0x97, + 0xc0, 0x6f, 0xc9, 0x13, 0x16, 0xfa, 0xad, 0x4b, 0x41, 0x13, 0xd6, 0xf0, + 0x39, 0x47, 0x41, 0x86, 0x81, 0x79, 0xb1, 0xfe, 0x37, 0xf8, 0xc7, 0x97, + 0x9b, 0xde, 0xea, 0x07, 0x8e, 0x02, 0x10, 0x84, 0xde, 0x26, 0xf2, 0x72, + 0xc8, 0xa5, 0x5b, 0x5e, 0xaa, 0x41, 0x51, 0x7d, 0x39, 0x20, 0x8a, 0x36, + 0x90, 0xb4, 0x18, 0x56, 0x26, 0xf2, 0x68, 0xd7, 0x35, 0x1d, 0x58, 0x90, + 0x81, 0x7f, 0x67, 0x64, 0xc4, 0x40, 0xf9, 0x9f, 0xfd, 0xc8, 0x89, 0xcd, + 0x9a, 0xad, 0x46, 0x1a, 0xdf, 0x31, 0x93, 0xcb, 0x22, 0xc2, 0xab, 0xc3, + 0x51, 0x46, 0x15, 0x69, 0xc1, 0xb8, 0x30, 0x81, 0xf6, 0xd3, 0xb6, 0x3f, + 0xfa, 0xa8, 0x5b, 0x79, 0xc5, 0xe6, 0xc9, 0xe8, 0x55, 0x20, 0x70, 0xa4, + 0x1f, 0x5e, 0x00, 0x74, 0x2d, 0x2d, 0xb2, 0x10, 0x08, 0x9b, 0xbc, 0xc5, + 0x11, 0x6e, 0x85, 0x1c, 0x21, 0x43, 0xc5, 0xa8, 0xca, 0x4e, 0x2b, 0x61, + 0x3e, 0xc0, 0x56, 0xf9, 0x4a, 0x84, 0x35, 0x1a, 0x33, 0xf4, 0x9a, 0xdf, + 0xe5, 0xb4, 0xa8, 0xd4, 0x45, 0x4a, 0x4f, 0x53, 0x4a, 0xbd, 0xf2, 0xbf, + 0xf3, 0x54, 0x29, 0x92, 0x58, 0x86, 0xd4, 0x61, 0x55, 0xab, 0xc9, 0x96, + 0x6e, 0x2d, 0x11, 0x70, 0x83, 0x92, 0x1e, 0x6c, 0x34, 0x03, 0x68, 0xec, + 0x14, 0xa3, 0xcc, 0xfb, 0x23, 0xc1, 0xe3, 0x0d, 0xa6, 0xf2, 0x34, 0xf9, + 0xd6, 0xdb, 0xf4, 0x37, 0x53, 0x42, 0xc5, 0x18, 0x88, 0xac, 0x18, 0xe8, + 0x70, 0xba, 0x07, 0xc1, 0x05, 0xba, 0xdb, 0x6d, 0xf6, 0x4d, 0x02, 0xed, + 0xfe, 0x34, 0xd6, 0x6f, 0x51, 0x40, 0xdd, 0x71, 0xb0, 0x7a, 0x2d, 0x13, + 0x8f, 0x75, 0x5b, 0x10, 0x72, 0xc6, 0xc9, 0x33, 0xea, 0x55, 0xe2, 0x85, + 0x23, 0x94, 0xdc, 0xf9, 0x6f, 0xa4, 0x0e, 0x51, 0x0d, 0x01, 0x76, 0xa8, + 0x7c, 0x07, 0x84, 0x7d, 0x05, 0x3a, 0x46, 0x34, 0xb9, 0x5c, 0x59, 0xae, + 0xac, 0x91, 0x8f, 0xf0, 0x3b, 0xf4, 0xc0, 0x56, 0x63, 0x62, 0x2a, 0x90, + 0xec, 0x04, 0xd8, 0xd7, 0xe9, 0x5f, 0x43, 0xc0, 0x62, 0x17, 0xd9, 0x4d, + 0x9c, 0x4c, 0x17, 0x60, 0x18, 0x91, 0x38, 0xe9, 0x23, 0x0c, 0x0e, 0x7a, + 0x55, 0x83, 0x91, 0x07, 0xff, 0xda, 0xa7, 0x8b, 0xc2, 0xb1, 0xb6, 0x60, + 0x71, 0x80, 0x28, 0x64, 0xd2, 0xbe, 0x35, 0xcb, 0x65, 0x24, 0x9d, 0x99, + 0xd0, 0x61, 0xa8, 0xb9, 0x20, 0x3c, 0x1f, 0xfc, 0xaa, 0x82, 0x11, 0x7b, + 0x4d, 0xea, 0x74, 0xea, 0x59, 0x10, 0x7d, 0x14, 0xe7, 0x95, 0x78, 0x15, + 0x22, 0x26, 0x29, 0xe6, 0x28, 0x06, 0x21, 0x28, 0xac, 0x75, 0x7b, 0xd6, + 0x38, 0x22, 0x42, 0xc4, 0x59, 0xc8, 0x72, 0x6a, 0xc8, 0x42, 0xd4, 0x4d, + 0x3e, 0x95, 0x16, 0xcb, 0xd0, 0xe6, 0x14, 0xa3, 0xa7, 0xcc, 0xe5, 0x69, + 0xbd, 0xb8, 0x8b, 0x57, 0x44, 0xb1, 0xde, 0x3c, 0xf4, 0xf2, 0x75, 0x6d, + 0x7f, 0x9f, 0x93, 0xd0, 0x92, 0x2f, 0xce, 0xb9, 0x0c, 0x12, 0x95, 0x79, + 0x3b, 0x4a, 0xe1, 0x52, 0x8d, 0x29, 0x95, 0x67, 0xb6, 0x91, 0xcb, 0xe3, + 0xe6, 0x3c, 0xab, 0xaa, 0x3f, 0xfb, 0x3f, 0x2f, 0xef, 0x61, 0x57, 0x61, + 0x2a, 0x91, 0xb9, 0x95, 0xc1, 0x56, 0x06, 0xfe, 0x20, 0x26, 0xda, 0x5b, + 0xed, 0x2c, 0x56, 0x8c, 0x0c, 0x52, 0xcc, 0xa1, 0xc1, 0x59, 0x50, 0xb5, + 0x12, 0xff, 0x8e, 0x39, 0x3d, 0xb9, 0x85, 0xa5, 0x44, 0xbd, 0xb2, 0xa2, + 0x0e, 0x0c, 0x9d, 0x48, 0x25, 0x7c, 0xbb, 0x15, 0x4f, 0x37, 0x77, 0x2e, + 0xb3, 0xa9, 0xf5, 0xbd, 0xad, 0xfd, 0x9d, 0xbc, 0x91, 0x7d, 0xd1, 0x10, + 0xf2, 0x16, 0xda, 0x2b, 0x35, 0xfd, 0x0e, 0x2e, 0x72, 0xff, 0x46, 0xfb, + 0xfe, 0x2e, 0x0c, 0x26, 0x55, 0x26, 0x66, 0x28, 0xea, 0x2f, 0x96, 0xd8, + 0x82, 0xcc, 0xbc, 0x92, 0x70, 0x38, 0x58, 0x12, 0x64, 0x7e, 0xd4, 0x6d, + 0xaf, 0xfb, 0xb6, 0x73, 0x24, 0xc4, 0x01, 0xec, 0x2b, 0x07, 0x08, 0x82, + 0x7f, 0xcf, 0x2b, 0x69, 0x53, 0x68, 0x5a, 0x58, 0x97, 0xa4, 0xe8, 0x2d, + 0x4f, 0x91, 0xd9, 0x5c, 0xc1, 0xc5, 0x0f, 0xb2, 0x4d, 0xf4, 0xf5, 0xb1, + 0x07, 0x3f, 0x2b, 0x86, 0x83, 0xcd, 0xc8, 0xcf, 0xb3, 0xea, 0x0b, 0x6d, + 0xd5, 0x35, 0x0c, 0x93, 0x96, 0xda, 0x1a, 0xed, 0x06, 0x05, 0xc2, 0xe3, + 0xd6, 0xea, 0x6f, 0xe6, 0xcd, 0xa3, 0x60, 0xeb, 0x9c, 0x9a, 0x33, 0x52, + 0x55, 0xaa, 0x41, 0x2d, 0x7d, 0x4c, 0x0f, 0x05, 0xff, 0x1b, 0x25, 0xed, + 0x7b, 0x1b, 0xf7, 0x94, 0x33, 0x73, 0xd6, 0x29, 0xec, 0x6a, 0xdb, 0xd1, + 0x17, 0x14, 0x6f, 0x00, 0xa0, 0x31, 0x19, 0x87, 0x5a, 0xdf, 0xd5, 0x74, + 0x7a, 0xda, 0x6f, 0x6c, 0xbf, 0xfe, 0xe6, 0xe7, 0xec, 0x2a, 0xc5, 0x5e, + 0x47, 0xe0, 0xd7, 0x3a, 0x0f, 0x91, 0xff, 0xd8, 0xa5, 0xa1, 0xbb, 0x70, + 0x73, 0x37, 0xeb, 0x68, 0x80, 0x83, 0x32, 0x01, 0x0a, 0x27, 0x14, 0xaa, + 0xb8, 0xaf, 0x85, 0xe5, 0x93, 0x0b, 0x24, 0x53, 0x54, 0xc1, 0xb5, 0x92, + 0xbc, 0xdb, 0x73, 0xf9, 0xfa, 0xdf, 0xbe, 0xd6, 0x35, 0xf5, 0x00, 0xad, + 0x11, 0x4b, 0x22, 0xf6, 0x40, 0xd4, 0xc7, 0x2c, 0xc7, 0xc7, 0x2c, 0xff, + 0x7b, 0xb7, 0x18, 0x59, 0x41, 0x65, 0x50, 0xdd, 0x5a, 0xf7, 0xb4, 0x2c, + 0x37, 0x1b, 0x2c, 0xcb, 0xce, 0x66, 0x4d, 0xaa, 0x3b, 0x7b, 0x6f, 0x3a, + 0xb5, 0xbb, 0x8a, 0x54, 0x82, 0xdd, 0x46, 0xcb, 0xd8, 0x43, 0xf5, 0xf1, + 0x71, 0xb7, 0x2a, 0x84, 0x4b, 0x45, 0x23, 0x64, 0x65, 0x78, 0x68, 0xc9, + 0x86, 0xf8, 0xaf, 0x3c, 0xad, 0x54, 0xdd, 0xfe, 0x6e, 0xe7, 0xae, 0xc2, + 0xc4, 0xd1, 0x18, 0x77, 0xed, 0x07, 0x07, 0x86, 0x7e, 0xd4, 0xea, 0xb6, + 0x54, 0xdd, 0xe3, 0x0d, 0x22, 0x9a, 0x8a, 0x2e, 0x6b, 0xe2, 0x2e, 0x86, + 0xe0, 0xf9, 0x3f, 0xfd, 0x93, 0x10, 0x07, 0x57, 0x7c, 0x0f, 0x09, 0xff, + 0x9f, 0xd8, 0xef, 0x26, 0xf5, 0xbc, 0x52, 0x86, 0xf2, 0x61, 0x5e, 0x91, + 0xa6, 0xd3, 0x0d, 0xe2, 0x9d, 0x2f, 0x4f, 0x2f, 0x87, 0x13, 0x8d, 0x62, + 0x29, 0x27, 0x03, 0xd0, 0xd7, 0x4c, 0x25, 0x0b, 0x56, 0xfb, 0x1b, 0x26, + 0x40, 0x61, 0x11, 0x8e, 0x77, 0xa8, 0xa4, 0x66, 0xa9, 0x2b, 0xd0, 0xd8, + 0x3c, 0x07, 0xc7, 0xff, 0xee, 0xbd, 0xfa, 0x3a, 0xcd, 0x67, 0xec, 0x97, + 0xc0, 0x30, 0xc1, 0x53, 0x1e, 0x9f, 0xb9, 0xe5, 0x11, 0x72, 0xce, 0x60, + 0x88, 0x0b, 0x65, 0x34, 0x7a, 0x3e, 0xf7, 0x71, 0xac, 0xf6, 0x6f, 0xf9, + 0x0a, 0xa1, 0x64, 0xea, 0x00, 0xf7, 0x46, 0xfb, 0xa3, 0x75, 0x00, 0xfa, + 0x1f, 0xfd, 0xa9, 0x27, 0xf6, 0xe8, 0x7f, 0x6d, 0x94, 0x3c, 0x1c, 0x71, + 0x4f, 0x62, 0x25, 0xa2, 0x90, 0x5a, 0xa3, 0xf6, 0x18, 0x68, 0x3d, 0xad, + 0x49, 0x72, 0x49, 0x8d, 0x6f, 0x14, 0x62, 0xc8, 0xdc, 0xbd, 0x98, 0x61, + 0x32, 0xbf, 0xd2, 0xd2, 0xfd, 0xaa, 0x24, 0x8a, 0x3d, 0xb6, 0xcf, 0x14, + 0xdf, 0x07, 0x01, 0xb0, 0x3e, 0x6c, 0x00, 0xe9, 0xa5, 0xa5, 0xc0, 0x63, + 0xcd, 0xb7, 0xbb, 0xb6, 0x55, 0x1e, 0xc5, 0xa5, 0x9d, 0x40, 0x1c, 0x18, + 0x58, 0x41, 0x6d, 0x5c, 0x0e, 0x31, 0x4a, 0xe8, 0x67, 0x17, 0x20, 0x5d, + 0xa6, 0xb4, 0x72, 0xa5, 0x1c, 0xce, 0xc9, 0xfd, 0x5f, 0x6d, 0xea, 0x00, + 0x63, 0x46, 0x25, 0x2f, 0x52, 0xe5, 0x56, 0xc6, 0xee, 0xcd, 0xf4, 0xce, + 0xdc, 0x9d, 0xde, 0x54, 0x1d, 0x53, 0xa0, 0xc0, 0x92, 0xaf, 0x9b, 0x66, + 0xf0, 0xb1, 0x54, 0xcf, 0x5f, 0xa8, 0xf7, 0xaf, 0x32, 0x28, 0x02, 0x36, + 0xe8, 0x8a, 0xa6, 0x05, 0x85, 0x9a, 0x8d, 0xcd, 0xa8, 0xf9, 0x01, 0x19, + 0x61, 0x5a, 0xc9, 0xcb, 0xb5, 0xb2, 0xcf, 0xeb, 0x7b, 0xb3, 0x3f, 0x37, + 0x4b, 0x1b, 0xfe, 0x62, 0x1e, 0xf3, 0xc1, 0xab, 0xf5, 0x23, 0xb4, 0x8b, + 0xee, 0xe2, 0x3f, 0xa8, 0x43, 0xcf, 0x59, 0xce, 0xca, 0x1b, 0x03, 0x05, + 0x26, 0x1a, 0x64, 0x7f, 0x7d, 0x7c, 0xc3, 0x5e, 0xcf, 0x40, 0x64, 0x36, + 0xdd, 0xbc, 0xec, 0xed, 0xa1, 0xce, 0x99, 0x54, 0x40, 0x41, 0xcd, 0x8b, + 0xaf, 0x36, 0xaf, 0xc4, 0x00, 0xc3, 0x52, 0x65, 0x9a, 0x58, 0x54, 0xa3, + 0x80, 0xed, 0x90, 0xd7, 0x01, 0x82, 0x7b, 0x4b, 0x32, 0x3f, 0x4a, 0xc8, + 0xf1, 0x5f, 0xbe, 0x0a, 0xd4, 0xfd, 0xd9, 0xe6, 0x3c, 0xc7, 0x3c, 0xd6, + 0x6d, 0x95, 0x1d, 0xa1, 0xce, 0xf0, 0x15, 0xc1, 0x69, 0xec, 0x2f, 0x65, + 0xbe, 0xf9, 0x5a, 0x42, 0xcc, 0x5a, 0x71, 0x7d, 0xb5, 0x60, 0x46, 0x50, + 0x1b, 0x81, 0x52, 0xa0, 0x62, 0x25, 0xe6, 0x15, 0xe4, 0xaa, 0x6e, 0xd8, + 0x05, 0x45, 0x0b, 0x55, 0x51, 0x4e, 0x36, 0xda, 0xdc, 0xea, 0x25, 0xfb, + 0x5f, 0x1e, 0x99, 0x2c, 0xa7, 0xa6, 0x31, 0x8a, 0x18, 0xf1, 0x67, 0x51, + 0x7b, 0xd8, 0x22, 0x92, 0xc0, 0x5a, 0x18, 0x4d, 0x35, 0x8a, 0xdb, 0x6c, + 0xfd, 0x47, 0xd9, 0xb3, 0xd9, 0xeb, 0x7a, 0x59, 0x64, 0xb1, 0x68, 0x80, + 0x85, 0x34, 0xd4, 0x71, 0x4a, 0xb2, 0xa8, 0xce, 0xf7, 0x4d, 0x9f, 0x51, + 0xbe, 0x8e, 0x73, 0x54, 0x5d, 0x81, 0xc4, 0x58, 0xf4, 0xcf, 0xd9, 0x54, + 0x8a, 0x9a, 0xd2, 0xdb, 0xab, 0x6e, 0x77, 0x3b, 0x6c, 0xed, 0x80, 0xe2, + 0xa0, 0x5a, 0xc6, 0x79, 0xbb, 0x4b, 0x3d, 0xef, 0x56, 0xb2, 0xa1, 0x0e, + 0x01, 0xc5, 0x60, 0xb5, 0x86, 0xbd, 0xab, 0xd8, 0xa2, 0x29, 0x84, 0x8b, + 0x52, 0x52, 0xa1, 0x4e, 0x89, 0x95, 0xf3, 0x69, 0x6d, 0xb9, 0x7b, 0x6a, + 0x81, 0xb1, 0xef, 0xb4, 0x8b, 0x33, 0xda, 0xbf, 0xed, 0xb1, 0x02, 0x3e, + 0x0a, 0xb7, 0xed, 0x59, 0x44, 0x51, 0xef, 0xad, 0xc8, 0x8e, 0x93, 0xce, + 0x6b, 0x18, 0x1d, 0x7a, 0xb7, 0xf2, 0x51, 0xb0, 0x9d, 0x16, 0x8b, 0x68, + 0x7b, 0xbb, 0x32, 0x20, 0xf6, 0x1a, 0x27, 0xbb, 0x00, 0x00, 0xb2, 0x08, + 0x2c, 0x2d, 0x8f, 0x37, 0xa3, 0xa1, 0x28, 0x90, 0x74, 0x5d, 0x01, 0xe2, + 0xa0, 0x0d, 0x16, 0x27, 0x77, 0x8a, 0x68, 0xa5, 0x31, 0x23, 0x80, 0xc2, + 0x00, 0xeb, 0xa0, 0xf0, 0xb0, 0x0b, 0x97, 0x03, 0xc5, 0xc0, 0x1a, 0x2c, + 0x5d, 0x2b, 0x60, 0xe1, 0x99, 0x00, 0xb8, 0xa6, 0x10, 0x26, 0x66, 0x6a, + 0x3b, 0x56, 0x26, 0x6b, 0xff, 0x45, 0x2b, 0x12, 0x21, 0xb7, 0x9c, 0x25, + 0x26, 0x2c, 0xa2, 0x64, 0x43, 0x03, 0x3f, 0x94, 0x86, 0xc0, 0xb6, 0x43, + 0xea, 0x99, 0x26, 0xb9, 0x03, 0xc4, 0x7c, 0xee, 0xfe, 0xa0, 0x94, 0xab, + 0x0f, 0x19, 0x56, 0x8d, 0xed, 0x32, 0x2b, 0x79, 0x33, 0xa5, 0x52, 0x20, + 0xe4, 0x5c, 0x1c, 0xa5, 0xea, 0x37, 0xf9, 0x3f, 0x72, 0xd2, 0xb5, 0xc2, + 0x95, 0x74, 0x6c, 0xfe, 0xf1, 0x7e, 0x8a, 0xcc, 0xa6, 0x03, 0x89, 0x9b, + 0x12, 0x19, 0x54, 0x56, 0x1e, 0x0e, 0xe8, 0xfe, 0x6a, 0xf9, 0x79, 0x7f, + 0xda, 0xd7, 0xae, 0x68, 0x70, 0x02, 0x14, 0x4b, 0xfc, 0xf0, 0x73, 0xba, + 0x83, 0x3d, 0x3b, 0x78, 0x6c, 0x1c, 0x60, 0xf3, 0x02, 0x58, 0xed, 0xb4, + 0xac, 0x8f, 0x15, 0x66, 0x87, 0xd5, 0x46, 0xa9, 0xea, 0xf1, 0x98, 0x1e, + 0xfa, 0x74, 0x6c, 0x1f, 0x6f, 0x03, 0xdc, 0xd0, 0xef, 0xc0, 0xc4, 0xc2, + 0xfe, 0x01, 0x76, 0xbd, 0x32, 0x38, 0x39, 0xf7, 0xec, 0x2a, 0x51, 0x9d, + 0xde, 0xdd, 0x92, 0xcc, 0x97, 0x9c, 0xaa, 0x44, 0x4c, 0xe4, 0x05, 0x78, + 0x08, 0x16, 0x2a, 0x2f, 0xd5, 0x78, 0xa3, 0xd3, 0x7a, 0xb1, 0x5d, 0x85, + 0x4b, 0xc5, 0xb9, 0x41, 0x2c, 0x48, 0xa8, 0x0f, 0x2a, 0x03, 0xe9, 0x18, + 0x6c, 0x76, 0xca, 0xb1, 0xcb, 0x0a, 0x47, 0x2c, 0x30, 0xac, 0x15, 0x97, + 0xfd, 0x5e, 0x27, 0x8d, 0x15, 0x6e, 0x2d, 0x00, 0x45, 0x97, 0x08, 0x38, + 0x5b, 0x03, 0xea, 0xd2, 0xa6, 0xbb, 0x8a, 0x4b, 0x65, 0x9f, 0xc9, 0x16, + 0xbe, 0xf6, 0x62, 0x98, 0xd2, 0x22, 0xc5, 0x21, 0xe8, 0x30, 0xa8, 0xd5, + 0xbb, 0x5c, 0xe9, 0xbc, 0x06, 0x5b, 0xeb, 0xd5, 0x2d, 0xf2, 0x07, 0xfa, + 0x80, 0xc2, 0x17, 0x54, 0xa1, 0xef, 0x51, 0x0a, 0x08, 0x97, 0x35, 0xef, + 0x4d, 0xfc, 0xc2, 0xb4, 0xf6, 0x7d, 0x9a, 0x8f, 0xb7, 0x9c, 0xf4, 0x0d, + 0x02, 0xc6, 0x97, 0xdf, 0x03, 0x01, 0xf5, 0x9e, 0x0f, 0x62, 0x99, 0xc5, + 0xb6, 0x2f, 0xd8, 0x04, 0xc6, 0xe2, 0x6b, 0x5f, 0x1b, 0xa6, 0x07, 0xcc, + 0x48, 0xd4, 0xd6, 0xdb, 0xff, 0xf3, 0xbb, 0x23, 0x7a, 0xa7, 0xb6, 0xf5, + 0x70, 0x46, 0xaa, 0x14, 0x01, 0x03, 0x0b, 0x88, 0x6a, 0xc1, 0xb8, 0x98, + 0x72, 0xa3, 0xff, 0xbe, 0x51, 0x3c, 0xa9, 0xa8, 0xa6, 0xdb, 0x6f, 0x24, + 0x9e, 0x11, 0x77, 0x76, 0x85, 0x91, 0x0a, 0xd4, 0x51, 0xb6, 0xa0, 0x21, + 0xa6, 0x79, 0x5b, 0x81, 0xe2, 0x96, 0xe5, 0xa5, 0x88, 0x03, 0x6e, 0xb9, + 0xc2, 0xd7, 0x3e, 0xdc, 0xb0, 0x9b, 0x4b, 0xf6, 0x0e, 0x7b, 0x2a, 0x89, + 0x7f, 0xe4, 0x45, 0x9b, 0x50, 0x15, 0x15, 0x03, 0x02, 0x67, 0xf6, 0x08, + 0x1a, 0x5e, 0x3e, 0xd0, 0xeb, 0xd2, 0xb3, 0xe1, 0xaa, 0x69, 0xba, 0xc1, + 0x6a, 0x92, 0xbb, 0x7a, 0x53, 0xd3, 0xe3, 0x96, 0x44, 0xbc, 0x81, 0x0d, + 0xb6, 0xb7, 0xdf, 0x9f, 0xbe, 0xca, 0x88, 0xab, 0xea, 0x97, 0xc5, 0xa8, + 0x8a, 0xa3, 0x90, 0x05, 0xdd, 0xbd, 0x80, 0xe3, 0x0e, 0xdc, 0x39, 0x66, + 0x84, 0x9c, 0xd4, 0xe9, 0x98, 0x67, 0xc5, 0x7e, 0xf6, 0x5b, 0x60, 0x8a, + 0x89, 0x6e, 0x50, 0xe5, 0x49, 0xe3, 0x23, 0xc2, 0xd8, 0x25, 0xd2, 0xdc, + 0xb8, 0xa6, 0x42, 0xd3, 0x5b, 0x95, 0xa9, 0xd9, 0x60, 0x88, 0x02, 0x57, + 0x56, 0x5e, 0xca, 0xa4, 0x89, 0x4a, 0xa2, 0x91, 0xf3, 0x2a, 0xbf, 0xe1, + 0x13, 0xaa, 0x99, 0xa1, 0xe0, 0x11, 0x2b, 0xc3, 0x14, 0x3b, 0xd2, 0xdc, + 0xc1, 0xd9, 0x75, 0x2a, 0x4b, 0x98, 0x20, 0x9b, 0xce, 0x45, 0xef, 0x43, + 0x9d, 0xd8, 0xa0, 0x18, 0x4c, 0x68, 0xc5, 0x95, 0x2e, 0x67, 0x01, 0x4c, + 0xa7, 0x18, 0xfc, 0xef, 0xff, 0x88, 0x3b, 0x27, 0xba, 0x8e, 0x0d, 0xca, + 0xf8, 0x09, 0x0a, 0x33, 0xef, 0x6c, 0xd8, 0xdc, 0x6d, 0x45, 0x99, 0xa1, + 0xe2, 0xda, 0xb2, 0xd6, 0x50, 0xe3, 0x17, 0x07, 0xc9, 0xff, 0xed, 0x66, + 0x19, 0xab, 0x7b, 0x7b, 0xcc, 0xb0, 0x15, 0xeb, 0x72, 0xde, 0x40, 0xdf, + 0xa0, 0x92, 0x5d, 0x56, 0x01, 0xb6, 0x62, 0x85, 0xa7, 0x69, 0x2c, 0x51, + 0xea, 0x8c, 0x0a, 0x03, 0x83, 0x73, 0x1c, 0x2c, 0xb8, 0x2a, 0x98, 0xc1, + 0xc3, 0x38, 0xd2, 0x76, 0x65, 0xc8, 0xa1, 0xa9, 0xe9, 0x93, 0xb6, 0x2c, + 0x06, 0xff, 0x85, 0x7b, 0x98, 0x0b, 0x55, 0x7e, 0xa5, 0xa9, 0xd5, 0x72, + 0x34, 0x1c, 0x7b, 0xc5, 0x70, 0x92, 0x83, 0x10, 0x09, 0x43, 0xd5, 0xb2, + 0x49, 0x32, 0xc5, 0xea, 0x10, 0x60, 0x4f, 0x0c, 0x40, 0x82, 0xac, 0x14, + 0xdd, 0xeb, 0x5d, 0x99, 0xcd, 0x10, 0x75, 0x7c, 0x97, 0xf6, 0xe7, 0xbd, + 0xc0, 0x5a, 0xf9, 0xe2, 0xd5, 0x8a, 0x19, 0xf5, 0xa5, 0x6b, 0xca, 0x57, + 0x45, 0x67, 0xf1, 0xa4, 0xbe, 0x82, 0x03, 0x45, 0xa5, 0x93, 0xa5, 0x51, + 0x7b, 0x57, 0x42, 0x0b, 0x53, 0x4d, 0x0f, 0x61, 0x7b, 0x19, 0x27, 0xe7, + 0xe1, 0xb5, 0x9a, 0x53, 0x22, 0x3b, 0xcd, 0x05, 0xa1, 0x2c, 0x6c, 0x70, + 0xc2, 0xde, 0xfa, 0x9d, 0x2b, 0x2c, 0xc8, 0x5a, 0x86, 0xc0, 0xef, 0x04, + 0x50, 0x4b, 0xda, 0xf5, 0xc5, 0xd7, 0x99, 0x4b, 0xef, 0xef, 0xbf, 0x32, + 0x32, 0xa4, 0x3c, 0xcf, 0x52, 0xdd, 0xc8, 0x6e, 0x86, 0xa0, 0xb4, 0x21, + 0x62, 0x55, 0x4a, 0xbd, 0x2f, 0xb1, 0x2e, 0x95, 0xee, 0xea, 0xc5, 0xb3, + 0xf4, 0xd2, 0x90, 0x5a, 0x6a, 0xd8, 0xe1, 0xa5, 0x2d, 0xfb, 0x8c, 0xfe, + 0x95, 0x60, 0x8a, 0x87, 0x94, 0x37, 0x07, 0x19, 0xbf, 0x6b, 0x65, 0x80, + 0xad, 0x8a, 0x36, 0xad, 0x31, 0x4f, 0x14, 0x44, 0x6b, 0x95, 0x02, 0x4a, + 0xd3, 0xf7, 0x5e, 0xfa, 0x99, 0x9e, 0x2b, 0x9d, 0xc9, 0xdd, 0x2c, 0xa3, + 0x7e, 0x23, 0xe2, 0x95, 0x18, 0x16, 0xb0, 0x65, 0xd4, 0x5e, 0x28, 0x9b, + 0x11, 0x62, 0x9e, 0xd3, 0xdd, 0xbd, 0x5f, 0x9d, 0xa1, 0xa6, 0x2d, 0x05, + 0x69, 0xe3, 0x55, 0x65, 0xa0, 0xcc, 0xae, 0x70, 0x57, 0xe5, 0xa4, 0xc5, + 0xfe, 0xfa, 0x68, 0xe2, 0xf9, 0xbc, 0xb1, 0x1a, 0xf6, 0xec, 0x47, 0x78, + 0x36, 0xc0, 0xb6, 0xb5, 0x2a, 0x8e, 0x4c, 0x10, 0x4b, 0x57, 0x0f, 0x31, + 0x12, 0xe8, 0xab, 0xca, 0x15, 0xf1, 0x6e, 0x5a, 0x4a, 0x70, 0xd3, 0x78, + 0xae, 0x01, 0x8f, 0xec, 0x5e, 0x75, 0x15, 0xd8, 0x50, 0x73, 0xaf, 0xbb, + 0xf2, 0xda, 0x57, 0x2a, 0x9a, 0x8d, 0x48, 0x77, 0x68, 0x2a, 0x46, 0x10, + 0x69, 0x15, 0x75, 0x89, 0x8e, 0xc6, 0xb9, 0x6f, 0x51, 0x92, 0x2c, 0x44, + 0x86, 0x5e, 0x5e, 0xcc, 0xa1, 0x95, 0xb4, 0xd8, 0x38, 0xc4, 0x6b, 0xf7, + 0xa8, 0x26, 0x96, 0x08, 0xb6, 0x23, 0x28, 0x06, 0x08, 0x92, 0xce, 0xcc, + 0x0f, 0x3d, 0x2e, 0x81, 0x49, 0xcb, 0x2f, 0x09, 0x68, 0x25, 0x3a, 0xd3, + 0x3f, 0xe5, 0x46, 0x6e, 0x11, 0x6f, 0x16, 0xf5, 0x4f, 0xff, 0x4d, 0x23, + 0xe8, 0xc8, 0xf7, 0x2d, 0x4b, 0xaa, 0x6c, 0x9b, 0x81, 0xea, 0x18, 0xa7, + 0xb9, 0xd0, 0x60, 0x9e, 0x07, 0x0d, 0xde, 0xc1, 0xb6, 0x1a, 0x84, 0x45, + 0xaf, 0xf2, 0x77, 0x77, 0x7d, 0xef, 0x40, 0x23, 0x7d, 0x96, 0xf4, 0x09, + 0x9c, 0x1b, 0x8e, 0xc1, 0x99, 0x00, 0xe1, 0x1a, 0x6c, 0xd1, 0x2d, 0x51, + 0x6f, 0x68, 0x78, 0xab, 0xa9, 0xfe, 0x8a, 0xf0, 0x0b, 0x16, 0xe6, 0x29, + 0xd0, 0xe4, 0x05, 0x58, 0xda, 0x78, 0x3e, 0xc8, 0x8d, 0xb5, 0xa8, 0x70, + 0x8d, 0x72, 0x7d, 0x8d, 0x34, 0xaa, 0x95, 0x5f, 0xde, 0x23, 0x36, 0x78, + 0x30, 0xf8, 0x18, 0x10, 0xf0, 0x7f, 0x3c, 0xc2, 0xa2, 0xea, 0x1f, 0xfc, + 0x6e, 0x20, 0xb7, 0x77, 0x3c, 0x32, 0xcc, 0xf0, 0xe4, 0x1f, 0x2a, 0x00, + 0x71, 0x88, 0x86, 0x0c, 0x1f, 0x89, 0x39, 0x41, 0xe0, 0xbf, 0xe9, 0x56, + 0x81, 0x43, 0x59, 0xa3, 0x86, 0x96, 0x45, 0x2f, 0x9a, 0x51, 0xd0, 0x71, + 0x91, 0x6f, 0x24, 0xfb, 0x7e, 0x53, 0x80, 0x24, 0xac, 0x55, 0xff, 0x91, + 0x36, 0x38, 0x03, 0xa0, 0xc3, 0xb0, 0x38, 0x07, 0x80, 0xc6, 0x5c, 0x4e, + 0x5e, 0x85, 0x53, 0x1c, 0xb7, 0x28, 0x2a, 0x7f, 0x8a, 0x73, 0x35, 0x60, + 0x48, 0x06, 0x10, 0x41, 0x06, 0x12, 0xc0, 0x3c, 0x47, 0x6f, 0x9e, 0xfd, + 0x1e, 0x24, 0xe9, 0x53, 0x4c, 0x2d, 0xbc, 0xed, 0x0e, 0xd9, 0x1b, 0xd2, + 0xa0, 0xe0, 0xb3, 0xc0, 0xc2, 0xa0, 0xd8, 0xc0, 0x1c, 0x67, 0xff, 0xfe, + 0x6d, 0x2c, 0x50, 0x22, 0xa3, 0xaf, 0xe9, 0x44, 0x8a, 0x5d, 0x3b, 0x1b, + 0xbf, 0x17, 0x51, 0x80, 0x2d, 0x28, 0x7c, 0xaf, 0x8a, 0x6b, 0x5f, 0xc8, + 0x60, 0xa1, 0x03, 0x70, 0x81, 0xb0, 0xdc, 0x0f, 0x03, 0xfd, 0x8b, 0x0c, + 0x26, 0x68, 0x78, 0x3c, 0x54, 0xd8, 0xf4, 0xbd, 0x21, 0x73, 0x0d, 0x7e, + 0x28, 0xbe, 0x69, 0xaf, 0xc6, 0xa7, 0xa4, 0xbf, 0x1b, 0xe9, 0x5c, 0xa3, + 0x62, 0x63, 0x43, 0xf0, 0x43, 0xd6, 0x1a, 0x00, 0xcd, 0x1f, 0xfe, 0xc6, + 0xdb, 0x67, 0xca, 0xd5, 0x96, 0x45, 0x96, 0x9b, 0x3e, 0x1a, 0x35, 0x9b, + 0x46, 0xc0, 0x28, 0x38, 0x09, 0x1a, 0x9e, 0x78, 0x20, 0xc4, 0xd9, 0xdd, + 0xf8, 0x96, 0x9d, 0x4f, 0x67, 0x33, 0x92, 0xc0, 0x2a, 0x6f, 0x17, 0x01, + 0x06, 0x44, 0x76, 0xd8, 0x57, 0xf1, 0xf7, 0xae, 0xff, 0x59, 0xe6, 0x31, + 0xb2, 0xd5, 0xfd, 0xe2, 0xd8, 0x5b, 0x38, 0x22, 0x6e, 0xf5, 0x40, 0x2b, + 0x82, 0xd2, 0xe2, 0xee, 0x3f, 0x34, 0xe5, 0x85, 0x14, 0x9c, 0xd0, 0x65, + 0xe7, 0x37, 0x39, 0x0b, 0x34, 0x44, 0xbd, 0x5c, 0xb6, 0x06, 0xca, 0x38, + 0x0c, 0x35, 0x75, 0x47, 0x6e, 0xf6, 0xed, 0x5c, 0xa0, 0x4c, 0x0a, 0x35, + 0x58, 0xa1, 0x8c, 0xf7, 0xa7, 0x33, 0xd0, 0xab, 0x09, 0x08, 0x2a, 0x90, + 0x30, 0xba, 0x6a, 0xb5, 0xfe, 0x70, 0x97, 0x82, 0x63, 0xc3, 0xfd, 0xea, + 0x5d, 0x52, 0x8b, 0xa4, 0x6b, 0xf5, 0x77, 0x0d, 0x93, 0xa5, 0xb5, 0xb5, + 0x7b, 0x92, 0xed, 0x9d, 0x0f, 0x11, 0xdb, 0x62, 0x28, 0x08, 0xe7, 0x9a, + 0xc2, 0x28, 0x98, 0xf5, 0x29, 0x72, 0x4f, 0x84, 0x3e, 0x55, 0x7f, 0xdf, + 0x8f, 0xeb, 0x1e, 0xac, 0x2f, 0x67, 0xd3, 0x7b, 0xdd, 0xfa, 0xa2, 0xa0, + 0x2c, 0xd2, 0x2d, 0xfe, 0xe8, 0x77, 0xf5, 0x01, 0xe8, 0x31, 0x00, 0x83, + 0xd1, 0x33, 0x0c, 0x4f, 0x31, 0xe9, 0xe9, 0x88, 0x9a, 0x40, 0x8b, 0x88, + 0x86, 0xca, 0x14, 0x3c, 0x2e, 0xaa, 0xc6, 0xbd, 0x99, 0xd1, 0xc6, 0xa5, + 0x9e, 0xa2, 0x0a, 0xbf, 0x64, 0xbc, 0xb5, 0x1f, 0xa7, 0xc3, 0x80, 0xb5, + 0x95, 0x32, 0x8d, 0x6d, 0x5e, 0x0c, 0x29, 0xea, 0x88, 0x51, 0xb6, 0x32, + 0x06, 0x04, 0x41, 0x24, 0x7f, 0xff, 0x2a, 0x1d, 0x0f, 0xf0, 0x4a, 0x12, + 0x94, 0xe5, 0x64, 0xb0, 0xb6, 0x33, 0x2a, 0xe1, 0xe3, 0x0a, 0x14, 0x15, + 0x68, 0x73, 0xbf, 0xff, 0x80, 0x40, 0x4f, 0x55, 0xe0, 0x44, 0x63, 0xca, + 0x94, 0xeb, 0x79, 0x24, 0xef, 0xfe, 0xbe, 0xfe, 0xf3, 0x9d, 0x78, 0x5b, + 0x12, 0x22, 0x8f, 0x2e, 0x87, 0x83, 0x17, 0x26, 0x87, 0x68, 0x31, 0xa2, + 0xbe, 0x21, 0xe1, 0xb7, 0x1b, 0x46, 0xef, 0xb5, 0xcd, 0xe1, 0xb2, 0x25, + 0xa2, 0x01, 0x44, 0x35, 0x6f, 0xf7, 0x50, 0xf1, 0x00, 0xa8, 0xdb, 0x65, + 0xfe, 0xa8, 0xd7, 0x17, 0xc3, 0xf9, 0x26, 0xa9, 0xf8, 0x79, 0x74, 0x91, + 0x74, 0x04, 0xde, 0x10, 0xc7, 0xda, 0x7f, 0x9c, 0xca, 0xb7, 0x68, 0xbc, + 0x90, 0x29, 0x30, 0xc7, 0xbf, 0x43, 0xbd, 0xd5, 0x08, 0x0d, 0xf0, 0xd9, + 0xf1, 0x4a, 0xc6, 0xa7, 0x57, 0x25, 0x13, 0x97, 0x53, 0x6f, 0x54, 0xa3, + 0x5e, 0x2c, 0x8b, 0x88, 0x01, 0x84, 0xeb, 0x13, 0x46, 0xcd, 0x98, 0x8f, + 0xa8, 0x8a, 0x46, 0xa1, 0xb9, 0xb0, 0x0f, 0x1f, 0xa5, 0x06, 0x4b, 0x82, + 0x09, 0x67, 0x93, 0x30, 0x0a, 0x71, 0xd2, 0xaf, 0x48, 0x57, 0xcf, 0xad, + 0x2f, 0xea, 0x82, 0xbd, 0xd5, 0x70, 0x58, 0x61, 0x4f, 0x64, 0xe2, 0xf1, + 0x7e, 0x94, 0xc3, 0x96, 0x10, 0xc1, 0x48, 0x38, 0x10, 0xd2, 0x97, 0xdb, + 0xb3, 0xca, 0xd5, 0xd4, 0xfe, 0xb1, 0x69, 0xdb, 0x7b, 0x60, 0x12, 0x32, + 0x9e, 0xea, 0xf2, 0x45, 0x34, 0xc9, 0x49, 0x85, 0xa2, 0xad, 0x6f, 0x13, + 0x59, 0xdf, 0x27, 0x55, 0x58, 0xb5, 0x19, 0x66, 0xc8, 0x5a, 0xc7, 0x68, + 0x88, 0x06, 0x2d, 0x04, 0x63, 0x26, 0x07, 0xd2, 0xc4, 0x83, 0xd6, 0xbd, + 0x73, 0xf7, 0xc9, 0xfc, 0x1a, 0x71, 0x15, 0xe5, 0x0d, 0xf4, 0xf9, 0xcf, + 0xb3, 0xbe, 0x06, 0x1c, 0x17, 0xf3, 0xac, 0x7f, 0x85, 0xaa, 0x17, 0xb8, + 0xcf, 0x9b, 0xab, 0xda, 0x22, 0x81, 0x8f, 0xd0, 0x61, 0xa6, 0xf6, 0xf9, + 0x21, 0x78, 0x41, 0x80, 0xc8, 0x2f, 0x99, 0xf8, 0x13, 0xb2, 0x7c, 0x1c, + 0xa5, 0xe3, 0x54, 0xe7, 0x65, 0x31, 0xa2, 0xd5, 0x1f, 0xcc, 0xfc, 0x9b, + 0xed, 0x67, 0x88, 0xf6, 0x6c, 0xb9, 0x0b, 0x25, 0x41, 0x8a, 0x22, 0x8f, + 0x01, 0x00, 0x61, 0x3a, 0x6a, 0x94, 0xc5, 0x20, 0x53, 0x33, 0xa5, 0x42, + 0x2f, 0x50, 0xce, 0x88, 0xa0, 0xe3, 0x2c, 0x79, 0x28, 0x7d, 0x95, 0x4f, + 0x2f, 0x9b, 0xde, 0xee, 0xaf, 0x14, 0x5f, 0x7b, 0xa7, 0xa9, 0x3f, 0xf2, + 0x28, 0x63, 0xd5, 0x6b, 0x06, 0xe8, 0xd1, 0xae, 0xed, 0x8b, 0x1e, 0xab, + 0x2f, 0x4e, 0xde, 0x2a, 0x51, 0xbf, 0xf6, 0x31, 0x66, 0x95, 0x6a, 0xff, + 0x9d, 0x45, 0x41, 0x81, 0x7c, 0x68, 0x47, 0x6b, 0x04, 0xba, 0xa1, 0xbd, + 0x6d, 0x3e, 0x79, 0xac, 0xba, 0xaa, 0xfe, 0xfa, 0x7d, 0x5c, 0x25, 0xcc, + 0xd2, 0xac, 0xca, 0x1e, 0x83, 0x0a, 0xd5, 0x81, 0xee, 0x61, 0x60, 0x14, + 0x53, 0x9d, 0xd5, 0xb3, 0x92, 0xa1, 0x79, 0x66, 0x3c, 0xa0, 0x19, 0x7d, + 0xfe, 0xfe, 0x7a, 0xd0, 0xf3, 0x3f, 0x46, 0xe8, 0xf8, 0x1b, 0xa9, 0xd8, + 0xa5, 0x40, 0x10, 0x30, 0xb1, 0xc5, 0xc3, 0x4d, 0x35, 0x85, 0x8c, 0x2a, + 0x1f, 0x42, 0xd6, 0x16, 0xff, 0xf6, 0x15, 0x76, 0x2d, 0x67, 0x83, 0x60, + 0x71, 0x94, 0xac, 0xfe, 0xdc, 0xf5, 0xd9, 0xee, 0x76, 0xd9, 0xee, 0xca, + 0xa3, 0xa4, 0x26, 0x71, 0x5b, 0x2d, 0xb3, 0x1a, 0x5b, 0x3a, 0xa6, 0xfd, + 0x45, 0x5f, 0xb5, 0x04, 0xa1, 0xce, 0x03, 0x10, 0xaf, 0xa1, 0xe6, 0x08, + 0x0a, 0x94, 0xfd, 0xba, 0x56, 0x57, 0xbd, 0xbc, 0xa8, 0x6d, 0x13, 0xf4, + 0xfd, 0xad, 0xff, 0xd1, 0xcf, 0xf6, 0x76, 0xcc, 0x5b, 0x11, 0x5b, 0xd3, + 0x60, 0xfa, 0xbf, 0xfe, 0xa9, 0x75, 0x4c, 0x2d, 0xe7, 0x7e, 0xb7, 0x3a, + 0x8a, 0x3d, 0x16, 0x98, 0x51, 0x14, 0xef, 0x2e, 0xf2, 0x2f, 0xc9, 0xce, + 0x83, 0x04, 0xf7, 0xdc, 0xde, 0xa1, 0x0e, 0x51, 0x49, 0xd9, 0x78, 0x88, + 0x2c, 0xda, 0xf7, 0xa5, 0xd5, 0xef, 0xd0, 0x40, 0xf3, 0x25, 0x9c, 0x37, + 0xd0, 0x5a, 0xef, 0x30, 0x8b, 0x7b, 0xa5, 0x1d, 0xe3, 0xe5, 0xac, 0xe5, + 0xda, 0x6b, 0xa8, 0x2c, 0x5b, 0xa0, 0xc1, 0x41, 0x7b, 0xba, 0x59, 0x83, + 0x62, 0xb3, 0x4b, 0xd3, 0xcb, 0xb6, 0xae, 0xb5, 0xde, 0x28, 0xf4, 0x29, + 0xdf, 0xde, 0xb8, 0xbd, 0xf6, 0xd9, 0x92, 0xaf, 0x56, 0x82, 0x65, 0x14, + 0x37, 0xf0, 0xea, 0xc9, 0x3d, 0xc5, 0x2b, 0xf5, 0x63, 0x6f, 0xb6, 0xdb, + 0xc4, 0xde, 0x97, 0x57, 0x53, 0xd9, 0x9f, 0x8b, 0xcb, 0x61, 0x0c, 0x74, + 0xe5, 0xd4, 0x4e, 0x6c, 0x5b, 0x5a, 0x8d, 0x5a, 0x81, 0x11, 0x2d, 0x3a, + 0x7c, 0x7e, 0x23, 0x8f, 0x92, 0x6c, 0x68, 0x3d, 0x65, 0xb5, 0x0a, 0x47, + 0x0a, 0xbd, 0x7f, 0xfe, 0x12, 0xcc, 0x2a, 0x68, 0x35, 0xdf, 0x8b, 0x07, + 0xc3, 0xf1, 0x1d, 0x31, 0x78, 0x82, 0x3c, 0x05, 0x5d, 0x69, 0x5f, 0xd4, + 0xfb, 0xbe, 0xdb, 0xef, 0xf8, 0x96, 0x50, 0xb1, 0x62, 0xe4, 0xca, 0xc4, + 0x81, 0x1b, 0x1a, 0xd2, 0xd1, 0xeb, 0x73, 0xbe, 0xf6, 0xfb, 0x14, 0xb7, + 0x7d, 0xdb, 0x7d, 0xda, 0xa4, 0x6c, 0x12, 0x97, 0x8c, 0x07, 0x24, 0x42, + 0x98, 0xa8, 0x39, 0x01, 0x0d, 0x8e, 0x20, 0x32, 0xb5, 0x65, 0x78, 0x99, + 0x21, 0x65, 0x96, 0x45, 0x0c, 0xd0, 0xf5, 0x74, 0x56, 0xcc, 0x1b, 0xa0, + 0x06, 0x21, 0x36, 0xd8, 0x33, 0x62, 0x5c, 0x61, 0xb6, 0xbe, 0x90, 0xb9, + 0x86, 0xf3, 0x68, 0x19, 0xc5, 0xfd, 0x96, 0x5e, 0x5f, 0xd8, 0xa0, 0xaf, + 0x71, 0x72, 0xa0, 0x16, 0x19, 0x04, 0xb1, 0xd0, 0x43, 0x6d, 0x3c, 0x6d, + 0x86, 0x8b, 0xfd, 0xff, 0xee, 0xd0, 0x56, 0xfa, 0x4b, 0x91, 0x0f, 0xbb, + 0x9a, 0x0c, 0x36, 0x5a, 0x15, 0x06, 0xe6, 0x47, 0xe5, 0xec, 0x04, 0x1a, + 0xce, 0x02, 0x2b, 0x4d, 0xfc, 0xb7, 0x7e, 0xd2, 0xac, 0x93, 0xa5, 0xb7, + 0xd7, 0x3b, 0x67, 0x86, 0x70, 0x04, 0x8a, 0x96, 0xa4, 0x80, 0xf0, 0x90, + 0x07, 0xa9, 0x79, 0x45, 0x9e, 0x06, 0x05, 0xa3, 0x63, 0x56, 0xd2, 0x30, + 0x01, 0xec, 0xc1, 0xeb, 0x25, 0xe0, 0xca, 0x7f, 0x3d, 0x9c, 0x53, 0xfe, + 0x64, 0xe0, 0x14, 0x10, 0x03, 0x83, 0xa7, 0x13, 0x82, 0x83, 0x1b, 0x66, + 0xeb, 0x49, 0xb6, 0xf0, 0x19, 0x1f, 0xb2, 0x15, 0x7b, 0x62, 0x1f, 0x06, + 0xda, 0x0c, 0x13, 0x96, 0x2e, 0x1e, 0x0e, 0xd2, 0x32, 0xd3, 0x63, 0x82, + 0xff, 0x55, 0x33, 0x9e, 0x6b, 0xd6, 0xac, 0x6d, 0x6d, 0x06, 0x0a, 0x82, + 0x43, 0x09, 0x4b, 0xb2, 0xe0, 0x83, 0x5b, 0x1e, 0x27, 0x9c, 0x97, 0xff, + 0x8a, 0x1a, 0x6f, 0x7a, 0x88, 0x18, 0x22, 0xfd, 0xff, 0x74, 0x0b, 0x28, + 0x07, 0xcb, 0x80, 0x1c, 0xbc, 0x98, 0x04, 0x02, 0xc6, 0xcc, 0xaa, 0x03, + 0xde, 0xf3, 0x2a, 0x44, 0x0d, 0x9b, 0x39, 0x7c, 0xbd, 0xf4, 0xc0, 0x46, + 0x04, 0x91, 0x1a, 0x6d, 0xdc, 0xcf, 0x83, 0x21, 0xfc, 0xe8, 0xe2, 0x21, + 0xbf, 0x44, 0x0c, 0x34, 0x58, 0x7f, 0x9b, 0xf1, 0x24, 0xae, 0xcf, 0x64, + 0xe6, 0x69, 0x66, 0x0d, 0xef, 0xca, 0xfd, 0xfe, 0x29, 0x52, 0x82, 0x95, + 0x87, 0x40, 0x24, 0xaf, 0xbd, 0xe2, 0xe6, 0xda, 0xc1, 0x01, 0x3f, 0xdb, + 0x6e, 0xf6, 0x5c, 0x62, 0xec, 0x80, 0xaf, 0xa0, 0xc1, 0x58, 0xa9, 0x6a, + 0xaf, 0x65, 0x51, 0xef, 0x63, 0xd0, 0x04, 0x36, 0x0b, 0xe4, 0x80, 0x84, + 0xaf, 0xe9, 0x14, 0xab, 0x64, 0x40, 0x56, 0xce, 0xee, 0x83, 0x22, 0x96, + 0xe4, 0xb7, 0xa5, 0x9c, 0x52, 0xa0, 0x04, 0x06, 0x40, 0x0d, 0x05, 0x20, + 0xec, 0x7c, 0x0c, 0x57, 0xf6, 0xc1, 0x15, 0x27, 0x43, 0xb8, 0x54, 0xa2, + 0x54, 0x3f, 0xf0, 0x7a, 0x7a, 0x53, 0x83, 0x01, 0xb5, 0x6a, 0x14, 0x25, + 0x82, 0x53, 0x4b, 0x83, 0x08, 0x9d, 0x2f, 0xbb, 0xd3, 0x5b, 0xab, 0x62, + 0xc0, 0xc1, 0x41, 0x40, 0x86, 0x0c, 0x1f, 0xa4, 0xbb, 0xef, 0xa5, 0x56, + 0xca, 0xad, 0xe9, 0x5d, 0xda, 0x59, 0x61, 0xa3, 0xc3, 0x5f, 0xfe, 0xfe, + 0x2f, 0xff, 0x9e, 0x6b, 0x0f, 0xbf, 0x00, 0x00, 0xbc, 0x08, 0x6c, 0x78, + 0x3a, 0xa9, 0x82, 0x10, 0x8c, 0x5f, 0xf4, 0xbf, 0x03, 0x03, 0xd1, 0xea, + 0xb0, 0x2d, 0x14, 0xb6, 0x5b, 0xff, 0xde, 0x72, 0x15, 0x15, 0xe6, 0x47, + 0x8e, 0xc7, 0xc2, 0x52, 0x71, 0x24, 0x7e, 0xda, 0xbf, 0x34, 0x5b, 0x8c, + 0x4f, 0xee, 0x63, 0x7c, 0xbd, 0x43, 0x3b, 0x43, 0x91, 0x14, 0x15, 0xe6, + 0x46, 0xcd, 0x63, 0x4c, 0xab, 0xd8, 0xaf, 0xfe, 0xa5, 0x9a, 0xc9, 0x63, + 0x4a, 0xea, 0x86, 0x03, 0xb4, 0x2f, 0x0b, 0x6c, 0x0f, 0x80, 0xe9, 0x79, + 0x77, 0xe8, 0x84, 0x5d, 0x8a, 0xb1, 0x42, 0x85, 0x49, 0xd8, 0xe5, 0x68, + 0x44, 0xed, 0x03, 0x21, 0xb0, 0x8a, 0x0f, 0x95, 0xff, 0xd8, 0x9c, 0x38, + 0xb1, 0x63, 0x8d, 0x82, 0x9d, 0x35, 0x8d, 0x8f, 0x93, 0x7e, 0x72, 0xa9, + 0x6b, 0x29, 0x2c, 0xbc, 0x9d, 0x07, 0x6b, 0xf9, 0x90, 0xe6, 0x0d, 0x80, + 0xa3, 0xa3, 0xc9, 0x42, 0x00, 0x1d, 0x1c, 0xb4, 0xce, 0x7f, 0x4b, 0x12, + 0xef, 0xa0, 0xe2, 0xcb, 0x6d, 0xe5, 0xfe, 0x0d, 0xb1, 0x4f, 0x75, 0x4e, + 0x87, 0x80, 0x24, 0x56, 0x3d, 0x06, 0x4a, 0x07, 0x87, 0xca, 0x73, 0x13, + 0xf8, 0xbd, 0x3c, 0x9a, 0x06, 0x15, 0x6c, 0xb1, 0x12, 0xdd, 0xf8, 0xdb, + 0x0a, 0xc3, 0x82, 0xd1, 0x6a, 0x1e, 0x15, 0x9a, 0xe6, 0xc6, 0x40, 0x74, + 0x4b, 0x54, 0x24, 0x0f, 0xb5, 0xb6, 0x55, 0xf9, 0xab, 0xfe, 0xf9, 0xa5, + 0x28, 0xef, 0xcd, 0x40, 0xd0, 0xc0, 0x7f, 0xd4, 0xb4, 0x7f, 0x91, 0x33, + 0x4d, 0xee, 0x62, 0xbd, 0x5d, 0x96, 0x2a, 0x8d, 0x51, 0x11, 0xc9, 0x54, + 0x0a, 0x01, 0xa0, 0x10, 0xc0, 0xf8, 0xf4, 0x03, 0x52, 0xeb, 0x29, 0xf6, + 0x4c, 0xce, 0x8e, 0x13, 0x4d, 0xb1, 0xa6, 0xb0, 0xd7, 0x83, 0x70, 0xdc, + 0x18, 0x84, 0x5a, 0x07, 0x07, 0xca, 0xcb, 0x27, 0xf6, 0x2d, 0x43, 0xae, + 0xa3, 0x51, 0x51, 0x03, 0x05, 0x53, 0xd2, 0x6f, 0xe2, 0xca, 0x61, 0x86, + 0x9a, 0xa5, 0xed, 0x88, 0x04, 0x86, 0xd3, 0xa6, 0xf6, 0x2a, 0x4c, 0xdd, + 0x5f, 0x92, 0x62, 0xd6, 0x92, 0x2e, 0x64, 0x2e, 0xa6, 0xc1, 0x25, 0xac, + 0x10, 0x47, 0xed, 0xfb, 0xa2, 0x23, 0x5e, 0x93, 0x7e, 0x49, 0x2d, 0x05, + 0xaa, 0x82, 0x32, 0x7c, 0x48, 0x5f, 0x0b, 0x57, 0x2c, 0xca, 0x56, 0xb6, + 0x49, 0x56, 0xe0, 0xdd, 0x18, 0x30, 0x98, 0x5e, 0x3e, 0x95, 0x5b, 0x11, + 0x2d, 0xea, 0x9d, 0x97, 0x5a, 0xce, 0x70, 0xa9, 0x07, 0x46, 0x2a, 0x41, + 0x5c, 0x16, 0x10, 0xcd, 0xf6, 0x6a, 0x8f, 0x41, 0x62, 0x3d, 0x31, 0x7a, + 0xa1, 0xea, 0xb1, 0xb9, 0x67, 0xba, 0xb5, 0x10, 0x37, 0x66, 0xef, 0x49, + 0x3c, 0x16, 0x21, 0x44, 0x7f, 0xdd, 0xef, 0xf9, 0x9a, 0xb0, 0xd9, 0x69, + 0x36, 0x2d, 0x61, 0xe1, 0x9d, 0xc6, 0x7e, 0x9e, 0x6e, 0x20, 0xe8, 0x7a, + 0x4a, 0x7c, 0x43, 0xf1, 0xe4, 0xfa, 0x65, 0x4d, 0xed, 0xeb, 0x3f, 0xf1, + 0x5e, 0xc5, 0x97, 0x15, 0x8d, 0x5a, 0xb9, 0xf6, 0xbc, 0xa5, 0x84, 0xf7, + 0x14, 0xf9, 0x46, 0xde, 0x5b, 0xfc, 0x45, 0x61, 0x2b, 0x85, 0x8c, 0x24, + 0xf4, 0xcb, 0xbc, 0x95, 0x47, 0x42, 0xa3, 0xb4, 0x3f, 0x4c, 0xa0, 0x45, + 0xe2, 0x21, 0x12, 0x70, 0x52, 0x18, 0x15, 0x83, 0x7d, 0x2a, 0xa0, 0x0c, + 0x6c, 0x21, 0xb2, 0x3e, 0xf2, 0x98, 0x06, 0x1a, 0x2e, 0x55, 0xbd, 0x8d, + 0xed, 0x6e, 0x30, 0xc5, 0xee, 0x60, 0xdb, 0x7a, 0xa5, 0x49, 0x60, 0x74, + 0x0c, 0x40, 0xd4, 0xb8, 0x84, 0x80, 0x98, 0xa6, 0xde, 0x6d, 0xe8, 0xac, + 0x2f, 0x26, 0x4f, 0x9e, 0x54, 0xd3, 0x76, 0x01, 0x9f, 0xb5, 0x85, 0x48, + 0xb9, 0x6c, 0x96, 0x86, 0x80, 0x26, 0xae, 0xd6, 0xef, 0x51, 0x51, 0xac, + 0xe3, 0xd3, 0x5c, 0x73, 0xcf, 0x8d, 0xb6, 0x4b, 0x51, 0x94, 0x23, 0xa0, + 0xe3, 0x06, 0x99, 0x63, 0xe5, 0xe0, 0x43, 0xec, 0x71, 0x68, 0x87, 0x9d, + 0x9d, 0xe0, 0x6e, 0x0b, 0x7b, 0x56, 0xa8, 0xb6, 0xe6, 0x96, 0xec, 0xdf, + 0x66, 0x96, 0x58, 0x88, 0x3d, 0x96, 0x72, 0xc1, 0x14, 0x8d, 0x44, 0x89, + 0x9b, 0x4d, 0xd1, 0xc6, 0xde, 0x5d, 0x2d, 0xb8, 0x05, 0x14, 0xd4, 0x76, + 0x44, 0x0a, 0x4c, 0x97, 0xd3, 0x54, 0xee, 0xd8, 0xf1, 0x5b, 0x00, 0xa6, + 0x1f, 0x0f, 0xcb, 0xb7, 0x6c, 0x69, 0x66, 0xd5, 0x1b, 0xce, 0xb7, 0xb7, + 0x92, 0x87, 0x28, 0xcc, 0x27, 0x38, 0xca, 0x71, 0xf3, 0x7a, 0xbf, 0x87, + 0xe5, 0xdf, 0xc6, 0x50, 0x6e, 0x46, 0x27, 0x3f, 0x68, 0x72, 0x56, 0x0c, + 0x44, 0x44, 0x47, 0x54, 0xa3, 0x7c, 0x20, 0xf7, 0x7c, 0x3d, 0xd8, 0xd7, + 0x62, 0x39, 0x7f, 0x7b, 0x60, 0x54, 0xba, 0x6c, 0xbf, 0x54, 0x93, 0xb2, + 0xa9, 0xdf, 0x0e, 0xd2, 0x40, 0xe7, 0x24, 0xbd, 0x02, 0x4a, 0x79, 0x4b, + 0x4c, 0x0d, 0x7c, 0x12, 0x47, 0x3e, 0x37, 0x79, 0x65, 0x9a, 0x2a, 0x1e, + 0x0f, 0xda, 0x50, 0xb6, 0x07, 0xcd, 0xc2, 0xc5, 0xeb, 0x79, 0x7d, 0x01, + 0x1d, 0x40, 0x31, 0x0b, 0x57, 0xca, 0xa9, 0x33, 0x79, 0xf2, 0xad, 0x51, + 0x9b, 0xbc, 0xe4, 0x92, 0x44, 0x40, 0xc2, 0x75, 0x58, 0xc4, 0xe1, 0xfe, + 0xfe, 0x5f, 0xe6, 0x7f, 0xcc, 0x42, 0xc9, 0xc9, 0xc8, 0xc4, 0x99, 0x67, + 0x83, 0x4d, 0xee, 0x83, 0x10, 0x24, 0x93, 0x3c, 0xd2, 0xa1, 0xea, 0x66, + 0x6a, 0x94, 0xcc, 0x37, 0xa5, 0x9d, 0x5f, 0xb9, 0xfa, 0x0c, 0x73, 0x73, + 0xd6, 0x9f, 0x3e, 0x59, 0x5a, 0xc2, 0xa2, 0xab, 0x71, 0x40, 0x8b, 0x49, + 0x68, 0x72, 0x1b, 0x03, 0x10, 0x28, 0x91, 0x49, 0x79, 0x76, 0xb4, 0x5a, + 0x58, 0xdb, 0x4d, 0x83, 0x2f, 0xa2, 0x2d, 0x43, 0x21, 0xfb, 0x12, 0x35, + 0x96, 0x29, 0x7b, 0x17, 0x36, 0xb0, 0xc7, 0xbb, 0xea, 0x8e, 0xf2, 0xc0, + 0x2d, 0xd0, 0xe5, 0x70, 0xf0, 0x50, 0x92, 0xae, 0x64, 0xd2, 0xcc, 0x59, + 0x3d, 0xcd, 0xea, 0x15, 0xa5, 0x97, 0xb0, 0x36, 0x04, 0x85, 0xed, 0x3f, + 0xf2, 0x03, 0x0d, 0x98, 0xf7, 0x27, 0x27, 0xf5, 0x16, 0xa9, 0x42, 0x76, + 0xd7, 0x69, 0x9b, 0xa3, 0x69, 0x5a, 0xcf, 0x14, 0xa2, 0xe7, 0x06, 0x9f, + 0x77, 0x96, 0xcb, 0x96, 0xf0, 0x6d, 0xc5, 0xe5, 0xde, 0x5a, 0xb8, 0x2d, + 0xe3, 0x58, 0x10, 0x73, 0x07, 0x37, 0x9f, 0xbf, 0xe7, 0x3a, 0xa6, 0x87, + 0x92, 0x07, 0x96, 0x88, 0x84, 0x1d, 0xb9, 0xb8, 0xb5, 0xee, 0xdd, 0xda, + 0x36, 0xc1, 0x12, 0x1a, 0x76, 0xee, 0x95, 0x22, 0xea, 0x22, 0x45, 0x90, + 0x48, 0x09, 0x69, 0x60, 0x6e, 0xb6, 0x9d, 0xf4, 0x6c, 0xb2, 0x25, 0xca, + 0x78, 0x4d, 0x29, 0x7b, 0xb3, 0x96, 0xa2, 0x97, 0xb2, 0xc8, 0x88, 0x94, + 0xfc, 0x83, 0x2c, 0xa9, 0x8a, 0xde, 0xf3, 0x18, 0x92, 0x77, 0xf5, 0x68, + 0x79, 0x3f, 0x78, 0xb7, 0xca, 0x21, 0x54, 0xe8, 0xcf, 0x82, 0xae, 0x3d, + 0x49, 0xef, 0xaa, 0x99, 0x7d, 0x19, 0x62, 0x74, 0x41, 0xc5, 0x17, 0xaa, + 0x38, 0xb5, 0xe2, 0x92, 0xbc, 0x31, 0x27, 0xbd, 0x77, 0xa4, 0xcd, 0x8f, + 0x07, 0xa0, 0xa3, 0x07, 0x02, 0x9c, 0x46, 0x03, 0x4d, 0xa4, 0x82, 0x06, + 0xdf, 0x36, 0x88, 0xb5, 0x0a, 0xd7, 0x06, 0xf8, 0xcb, 0x5d, 0x06, 0x1a, + 0x93, 0xee, 0x34, 0x01, 0xc9, 0x34, 0x44, 0x55, 0xec, 0xe1, 0xae, 0x5b, + 0xa7, 0xc9, 0x44, 0x8d, 0x7f, 0xc9, 0x95, 0x01, 0x86, 0x4b, 0xbc, 0xb0, + 0xe6, 0xaf, 0x56, 0x5b, 0xd0, 0x39, 0xd2, 0xa1, 0x14, 0x05, 0xb1, 0x1c, + 0x4a, 0x0f, 0xc7, 0xda, 0x24, 0x0e, 0x75, 0x8c, 0x2a, 0x50, 0x58, 0x8e, + 0x16, 0x5b, 0xce, 0x5d, 0x1b, 0xe2, 0xe1, 0x61, 0x78, 0xe1, 0x1c, 0xc9, + 0x84, 0x49, 0x86, 0x3f, 0x46, 0x07, 0xe9, 0x7c, 0x97, 0x99, 0x64, 0x66, + 0x8e, 0x22, 0x32, 0x49, 0x43, 0x62, 0x30, 0xa4, 0xc3, 0x45, 0x4a, 0x36, + 0xcd, 0xb3, 0xb0, 0xda, 0x22, 0x26, 0x24, 0x00, 0x70, 0xfd, 0xa5, 0x7f, + 0xf0, 0xfc, 0x40, 0xa9, 0x98, 0x0e, 0xbe, 0xaa, 0x16, 0x6a, 0x74, 0x5c, + 0x2d, 0x8a, 0x56, 0xcc, 0x02, 0xa6, 0x11, 0x2e, 0xf3, 0x65, 0x94, 0x38, + 0xe2, 0xc6, 0xec, 0x43, 0xc0, 0xd0, 0x16, 0x8a, 0x2a, 0x44, 0xc6, 0x3e, + 0x4e, 0x39, 0xef, 0x2e, 0x6f, 0x97, 0x2b, 0x88, 0xfb, 0x2d, 0x97, 0xdc, + 0x11, 0x14, 0x1e, 0x1f, 0x7c, 0x4b, 0x4c, 0xa8, 0x21, 0xb3, 0xa9, 0x7b, + 0xfb, 0x26, 0xcf, 0x36, 0x8f, 0x1a, 0x63, 0x93, 0xbe, 0x90, 0x19, 0x01, + 0x58, 0x76, 0x04, 0x45, 0xa3, 0x01, 0xe3, 0x1b, 0x19, 0x2f, 0xd1, 0x05, + 0x56, 0x97, 0x33, 0x41, 0x58, 0xa1, 0x7d, 0xbf, 0x9f, 0x0f, 0x69, 0x21, + 0x5f, 0x70, 0x15, 0xf8, 0x65, 0x14, 0xa2, 0x43, 0x19, 0x9a, 0xc4, 0x62, + 0x75, 0xbe, 0xec, 0xd5, 0xe5, 0x2d, 0xa8, 0x6d, 0x01, 0x22, 0xab, 0x2c, + 0x75, 0x5b, 0x17, 0x02, 0x28, 0xfa, 0xa6, 0xfa, 0x71, 0xce, 0x08, 0x0c, + 0x50, 0x32, 0x58, 0x57, 0xc1, 0x51, 0x8a, 0x01, 0xa0, 0x80, 0xde, 0x07, + 0xcc, 0xe9, 0x6f, 0xb7, 0x90, 0x19, 0x76, 0xaa, 0x82, 0x9e, 0x87, 0xa0, + 0x24, 0xf0, 0x28, 0x95, 0x32, 0xc6, 0xfd, 0x22, 0xb6, 0xac, 0x95, 0x7e, + 0xa3, 0x63, 0x64, 0xfd, 0x40, 0x1c, 0xa8, 0xa0, 0xef, 0x83, 0xe5, 0x40, + 0x0e, 0xa0, 0x1d, 0x06, 0xc0, 0x36, 0x95, 0xb5, 0x63, 0xce, 0xe6, 0xad, + 0x0b, 0x28, 0x75, 0xb2, 0x2c, 0xb0, 0x70, 0x16, 0x31, 0x1f, 0xda, 0x4e, + 0xda, 0x81, 0x03, 0xd8, 0x0e, 0x03, 0xe9, 0x7e, 0x39, 0xa5, 0xed, 0x37, + 0x14, 0x17, 0x6e, 0xa2, 0x9c, 0xb2, 0xd9, 0xd0, 0x70, 0x74, 0x50, 0x64, + 0x2d, 0xa7, 0xde, 0x76, 0xa9, 0x51, 0xc8, 0x33, 0xe4, 0x01, 0x3d, 0xa6, + 0x0b, 0xc2, 0x00, 0x80, 0xce, 0xe4, 0x1c, 0x26, 0x6a, 0x23, 0xe6, 0x4b, + 0xb5, 0x1d, 0x02, 0x7b, 0xd3, 0x21, 0x9e, 0x04, 0x1f, 0x97, 0xb6, 0x20, + 0xb7, 0x14, 0xb5, 0xd1, 0xb7, 0xb9, 0xb9, 0xcb, 0x51, 0xac, 0x37, 0xd0, + 0x4b, 0x4c, 0x63, 0x77, 0xa4, 0xd5, 0xc9, 0x87, 0x10, 0x36, 0x3f, 0x10, + 0x68, 0x29, 0xf4, 0x11, 0x53, 0x66, 0xfc, 0x3a, 0xdb, 0x1b, 0xe7, 0x56, + 0x5f, 0x4b, 0x54, 0x6e, 0x60, 0x2d, 0x04, 0x8a, 0xc7, 0x89, 0xa8, 0x95, + 0x7b, 0xf6, 0x74, 0xb6, 0x4a, 0xd0, 0xe4, 0xae, 0xa8, 0xbc, 0xe4, 0xbf, + 0x0e, 0x57, 0x52, 0x1d, 0x02, 0x50, 0x5e, 0xd1, 0x23, 0xc1, 0xf3, 0x29, + 0xc7, 0xd6, 0x34, 0x9c, 0xb0, 0x72, 0x54, 0x8b, 0x64, 0x9d, 0x5d, 0xcb, + 0x89, 0x40, 0x77, 0xdb, 0x5a, 0x1f, 0x6f, 0xae, 0xdf, 0x2a, 0x1c, 0xab, + 0xde, 0x07, 0x9e, 0xd9, 0x11, 0x06, 0x60, 0xc3, 0x57, 0x9e, 0xe4, 0xef, + 0x54, 0x85, 0x91, 0x00, 0x00, 0xc1, 0x08, 0x6c, 0x37, 0x01, 0xaf, 0x67, + 0xc1, 0x16, 0x4e, 0xf3, 0x6a, 0x94, 0x75, 0x75, 0xea, 0xe0, 0xc2, 0x71, + 0x28, 0x84, 0x0c, 0xad, 0x58, 0xf8, 0x15, 0x99, 0xed, 0xfe, 0x5f, 0xe6, + 0x32, 0xba, 0x8f, 0x28, 0xb7, 0xf2, 0xd6, 0x3d, 0xaa, 0x14, 0xb6, 0x04, + 0x00, 0xaf, 0xc5, 0x88, 0x84, 0x14, 0xa0, 0xa6, 0x4c, 0x91, 0xb5, 0x4a, + 0xa6, 0xb7, 0xc8, 0x1f, 0xde, 0xdd, 0x96, 0x70, 0x18, 0x93, 0x0a, 0x81, + 0x84, 0xe1, 0x9b, 0xc9, 0x58, 0x57, 0xea, 0x20, 0x37, 0x3c, 0x96, 0xd8, + 0x06, 0x2c, 0xa5, 0xb2, 0xd9, 0x7b, 0x7d, 0xfd, 0x11, 0x73, 0x4a, 0x94, + 0x82, 0xdc, 0x2f, 0x99, 0x2a, 0x30, 0x4b, 0x16, 0xab, 0x9e, 0x6c, 0x31, + 0x03, 0x0f, 0x55, 0xb0, 0xda, 0x5f, 0x6c, 0xfb, 0x29, 0xda, 0x57, 0xea, + 0xcc, 0xac, 0xac, 0x94, 0x7d, 0xb7, 0xf4, 0x1c, 0x5d, 0x18, 0x06, 0x02, + 0x8d, 0x66, 0x73, 0x4a, 0xcb, 0x7e, 0xac, 0x3b, 0x2d, 0x16, 0x06, 0x7a, + 0x55, 0x85, 0xb7, 0xdf, 0xb3, 0xfd, 0x51, 0xfd, 0x8a, 0x25, 0xe2, 0xd6, + 0x40, 0xec, 0x12, 0x06, 0xbb, 0x77, 0xec, 0xeb, 0x5f, 0xff, 0xf7, 0x33, + 0x69, 0x69, 0x6f, 0x6b, 0x62, 0x0f, 0x2c, 0x5e, 0x83, 0x21, 0xc0, 0x60, + 0x96, 0x2a, 0x9b, 0xdf, 0x75, 0x42, 0x35, 0x19, 0xde, 0xe2, 0xe8, 0xe7, + 0x83, 0x7d, 0x58, 0x69, 0x37, 0xd2, 0x43, 0x87, 0x1e, 0x6d, 0x7c, 0x9d, + 0xab, 0x59, 0x09, 0x6a, 0xd3, 0xa8, 0xcf, 0x0b, 0x1a, 0x00, 0xd4, 0xfe, + 0xcc, 0xf7, 0xa6, 0x45, 0x12, 0x2e, 0xba, 0x04, 0x40, 0x97, 0x37, 0x39, + 0x67, 0x94, 0x59, 0x44, 0x54, 0x37, 0xa2, 0x83, 0xa5, 0x5e, 0x0e, 0xaf, + 0x4a, 0x73, 0x96, 0x12, 0x8d, 0xc1, 0xd8, 0x2b, 0x37, 0xdf, 0xff, 0xba, + 0xa2, 0x85, 0x90, 0xc3, 0x65, 0x30, 0x0e, 0xd6, 0xd9, 0x2e, 0x53, 0x24, + 0x68, 0x3f, 0x55, 0x47, 0x76, 0x2f, 0xac, 0x87, 0xb2, 0x5e, 0x83, 0x12, + 0x2e, 0xa0, 0x2c, 0x04, 0xc0, 0xf8, 0x76, 0xd0, 0x18, 0xd5, 0x38, 0xa3, + 0x99, 0x7b, 0xd5, 0x94, 0x54, 0x21, 0x5f, 0x97, 0xc5, 0x93, 0x37, 0x34, + 0xb6, 0x6a, 0xdc, 0x58, 0xaa, 0xca, 0xb0, 0x23, 0x9e, 0x06, 0x20, 0x20, + 0x02, 0x17, 0xe2, 0x65, 0x55, 0x96, 0x5b, 0xdd, 0xbb, 0xea, 0x58, 0x05, + 0x1a, 0x60, 0x6e, 0x59, 0xd0, 0xdc, 0x0a, 0xe1, 0x82, 0x98, 0x85, 0xbd, + 0xe8, 0x3e, 0x4f, 0xff, 0x65, 0x7b, 0xa7, 0x53, 0x16, 0xb2, 0x91, 0x23, + 0x61, 0xec, 0x84, 0xaa, 0x71, 0x65, 0x89, 0xe7, 0xed, 0x8e, 0x72, 0x4e, + 0x95, 0x7b, 0x27, 0x03, 0x7b, 0x22, 0x20, 0x60, 0x8c, 0x20, 0xfc, 0x7f, + 0x58, 0x68, 0x3e, 0xf6, 0x95, 0xd0, 0xea, 0x41, 0x13, 0xc8, 0x7b, 0x46, + 0x88, 0x8f, 0xbb, 0xff, 0x50, 0xf5, 0x0d, 0x44, 0x8e, 0x0a, 0xad, 0xce, + 0x4e, 0xbd, 0x53, 0x19, 0xe2, 0x51, 0x07, 0xc3, 0xff, 0x2b, 0x51, 0x8d, + 0x96, 0xcc, 0xc4, 0x1c, 0x9f, 0x85, 0x92, 0x5a, 0x32, 0xba, 0x0c, 0x26, + 0xe1, 0x08, 0x7c, 0x0c, 0xa0, 0x7c, 0xa8, 0x79, 0x9f, 0xad, 0xf9, 0x37, + 0xf7, 0x8b, 0xdd, 0x51, 0x96, 0xdb, 0x3d, 0x3f, 0xa3, 0x75, 0x1d, 0xa5, + 0x62, 0xb1, 0xb8, 0x28, 0xd2, 0x46, 0xc1, 0x54, 0x24, 0x35, 0x95, 0x43, + 0x29, 0xe2, 0xb5, 0x6a, 0xef, 0xef, 0x4b, 0x7c, 0xbc, 0x0f, 0x30, 0xad, + 0xb0, 0x54, 0x82, 0xa3, 0x00, 0x50, 0x5c, 0x04, 0x51, 0xe4, 0xf4, 0xd9, + 0xe2, 0xc6, 0x47, 0x05, 0x7c, 0xca, 0x36, 0x58, 0xd0, 0x73, 0xc8, 0x65, + 0xec, 0x5a, 0x50, 0x5a, 0xbb, 0x78, 0x41, 0x48, 0xd8, 0x8e, 0x58, 0x0a, + 0xdc, 0x4f, 0x9e, 0xdd, 0x06, 0x43, 0x3d, 0xfc, 0xf5, 0xe7, 0x2d, 0x50, + 0x38, 0xd0, 0x7c, 0xbf, 0xfe, 0xc5, 0xad, 0x6c, 0xdd, 0xe6, 0x2e, 0x2e, + 0x38, 0x61, 0x5c, 0xf2, 0x56, 0x22, 0xb6, 0x11, 0xe4, 0x9d, 0x36, 0x78, + 0xf8, 0x85, 0x44, 0x01, 0x07, 0xed, 0xdb, 0x61, 0x67, 0x61, 0xa2, 0x74, + 0xb8, 0x1e, 0x52, 0x79, 0x1c, 0x99, 0x7f, 0xe7, 0x0a, 0x6c, 0x0a, 0xc6, + 0x3f, 0xed, 0x5b, 0xcb, 0x71, 0x6b, 0x4d, 0x57, 0x23, 0xe0, 0x87, 0x8a, + 0xfe, 0x55, 0x29, 0x62, 0x85, 0xd0, 0x93, 0x22, 0xb4, 0xee, 0xcb, 0x2e, + 0x21, 0x36, 0x34, 0x65, 0x1c, 0x23, 0xdb, 0x18, 0x0f, 0xe2, 0xbc, 0x50, + 0xa2, 0xf7, 0x9c, 0xbb, 0xb5, 0x1d, 0xde, 0xc4, 0x41, 0xc0, 0x58, 0xbb, + 0x4a, 0xc3, 0xea, 0x99, 0xa0, 0x60, 0xe0, 0xbf, 0x71, 0x7a, 0x0c, 0x1c, + 0xb7, 0x4b, 0x38, 0x1c, 0x95, 0x47, 0xa0, 0x96, 0xe6, 0xf9, 0x59, 0xaf, + 0xb5, 0xbc, 0x37, 0xc9, 0x09, 0x87, 0x81, 0xdc, 0x1f, 0x33, 0xea, 0x05, + 0xd5, 0x97, 0x53, 0x7c, 0x92, 0x7f, 0xa5, 0x28, 0x9c, 0x63, 0x64, 0x07, + 0xab, 0x9c, 0xe5, 0x05, 0xa9, 0x64, 0x87, 0x98, 0x0e, 0x2f, 0x67, 0x6a, + 0xf5, 0x56, 0x32, 0xa9, 0x4a, 0x1e, 0x4b, 0x3f, 0xe0, 0x76, 0x3c, 0xcf, + 0xc6, 0xc5, 0xf3, 0xeb, 0x8e, 0x7a, 0x55, 0x17, 0xa8, 0xf9, 0x28, 0x56, + 0x24, 0xc0, 0x2e, 0x07, 0xf7, 0xdc, 0xc5, 0x2c, 0x0f, 0x98, 0x52, 0x86, + 0xfe, 0xfa, 0xf7, 0xb0, 0x66, 0xa4, 0x18, 0x86, 0x33, 0x2c, 0xda, 0x39, + 0xd9, 0xfc, 0x69, 0xa9, 0x14, 0xf2, 0x44, 0x53, 0x91, 0x61, 0x13, 0x42, + 0xd3, 0x0f, 0x7d, 0x97, 0xfe, 0xe2, 0x64, 0x9f, 0xfc, 0x80, 0x66, 0xfa, + 0x74, 0xdd, 0xb2, 0x70, 0xea, 0xc3, 0xc6, 0xff, 0xa5, 0xc0, 0x6f, 0xfc, + 0x52, 0xa7, 0x67, 0xbd, 0x16, 0x42, 0xb8, 0x30, 0x26, 0x98, 0x4e, 0xd0, + 0x7e, 0x3e, 0x50, 0x86, 0x0d, 0xd7, 0x5e, 0x71, 0x6b, 0x4f, 0xa8, 0x92, + 0xfb, 0x5a, 0x2c, 0xef, 0x40, 0xd7, 0x3c, 0xa3, 0x9c, 0xec, 0x07, 0x07, + 0x3c, 0x01, 0x32, 0xda, 0x55, 0x9c, 0xc3, 0x57, 0xb2, 0x29, 0x95, 0x0f, + 0x48, 0x76, 0xc0, 0xeb, 0x7a, 0x8a, 0x52, 0xd3, 0x6b, 0xf1, 0x70, 0xdb, + 0x48, 0x92, 0x2b, 0x53, 0x59, 0xcc, 0xa1, 0xe7, 0x3b, 0x91, 0x7b, 0xf2, + 0x4a, 0x6f, 0x0c, 0x20, 0x5b, 0x2a, 0x8f, 0xf2, 0xe4, 0xb0, 0xae, 0x59, + 0xc5, 0xc8, 0x65, 0xba, 0x53, 0x56, 0xe5, 0x58, 0x2b, 0x2a, 0xd4, 0x98, + 0xba, 0x0b, 0xc0, 0xc9, 0x70, 0x60, 0xae, 0x15, 0x16, 0x7c, 0x6c, 0x45, + 0x19, 0x83, 0x7b, 0xd5, 0xbd, 0x0a, 0x69, 0xff, 0x6d, 0xcc, 0x5a, 0xb2, + 0x39, 0x53, 0x24, 0xd9, 0x5a, 0x5a, 0x72, 0x8a, 0x4b, 0xe6, 0xd5, 0x6d, + 0x66, 0x31, 0xd8, 0x86, 0xaf, 0xda, 0xa4, 0x15, 0x20, 0xb5, 0xeb, 0xf2, + 0xd4, 0x77, 0xa3, 0x2b, 0x38, 0x44, 0x70, 0x19, 0x48, 0x29, 0xbd, 0x73, + 0x33, 0x01, 0x4e, 0xcd, 0xe1, 0x50, 0x14, 0x95, 0x0b, 0xd6, 0xce, 0x64, + 0x78, 0x9e, 0x07, 0x4e, 0x4d, 0x4e, 0x2a, 0x55, 0xef, 0xe3, 0x31, 0x85, + 0xfb, 0xb6, 0x87, 0x51, 0x4f, 0xea, 0x9e, 0xd1, 0xb9, 0x5a, 0xe1, 0x68, + 0xf4, 0xbd, 0x28, 0xfd, 0x55, 0xdd, 0x05, 0x30, 0x29, 0xd5, 0x4e, 0xa8, + 0x4a, 0x5d, 0xff, 0x6c, 0x2c, 0x88, 0xa7, 0x06, 0xe1, 0x6d, 0x44, 0x93, + 0xfc, 0x0f, 0xc0, 0xcf, 0x3b, 0xde, 0x8d, 0xb7, 0xf5, 0x1f, 0xec, 0x11, + 0x51, 0x03, 0xe4, 0x40, 0x0e, 0x2c, 0xd9, 0x18, 0x6b, 0xfb, 0x33, 0x81, + 0xed, 0xe4, 0x88, 0xa7, 0xbd, 0xe6, 0xea, 0xc1, 0xc0, 0x38, 0x3d, 0x23, + 0x2b, 0x10, 0x38, 0xa4, 0xc6, 0x43, 0xe0, 0x41, 0x1f, 0x0f, 0x75, 0x5e, + 0x7c, 0x72, 0xc6, 0xb5, 0x32, 0xee, 0x6c, 0x5e, 0xf6, 0x55, 0xa7, 0x11, + 0xe0, 0x6e, 0x04, 0x5e, 0x5d, 0xb1, 0xf8, 0x20, 0x96, 0x68, 0x29, 0x87, + 0xcc, 0x02, 0x9b, 0xd2, 0xb7, 0x9e, 0x56, 0xae, 0x81, 0xbf, 0xb1, 0x3d, + 0xc9, 0x39, 0x83, 0x6d, 0xdd, 0x0e, 0x43, 0xd0, 0x28, 0x58, 0x02, 0x03, + 0x48, 0x40, 0xd2, 0xf1, 0xd8, 0x8e, 0x3d, 0xd4, 0xe3, 0xe1, 0xc1, 0x72, + 0xd8, 0xa8, 0x41, 0x2e, 0x8d, 0x37, 0xf9, 0x6f, 0x7d, 0x63, 0x25, 0x5b, + 0x73, 0x32, 0x52, 0xad, 0xf0, 0x71, 0xf0, 0x63, 0x82, 0xf6, 0xf3, 0x19, + 0x12, 0xd8, 0x11, 0x8b, 0x59, 0x5d, 0xaa, 0x3d, 0x67, 0x9c, 0xe7, 0xd8, + 0x62, 0xcf, 0x16, 0x5a, 0xa1, 0x6c, 0xdd, 0xff, 0xb4, 0xa8, 0x3d, 0x2a, + 0x33, 0x09, 0xd9, 0x33, 0xd8, 0x3b, 0x12, 0x04, 0x96, 0x98, 0xfc, 0x54, + 0xce, 0x27, 0xac, 0xc5, 0x59, 0xe6, 0x98, 0xfc, 0x8d, 0x5e, 0x5b, 0x7f, + 0xfb, 0x85, 0x43, 0x85, 0xa9, 0x5e, 0x81, 0x50, 0xb0, 0xbd, 0x1d, 0xa7, + 0x1d, 0x77, 0xea, 0xcb, 0xbe, 0x9c, 0x4a, 0x85, 0x41, 0xfb, 0x0a, 0xad, + 0xfe, 0x2f, 0x27, 0x2f, 0xb0, 0xac, 0xc8, 0x83, 0x13, 0x7b, 0x3d, 0x47, + 0x1c, 0x68, 0xaa, 0xae, 0x59, 0xee, 0x61, 0xbb, 0xc0, 0xb0, 0x31, 0x89, + 0x69, 0x84, 0x9a, 0x3e, 0x4e, 0x3f, 0x2e, 0xd5, 0x5a, 0x59, 0x20, 0x80, + 0xaa, 0x61, 0x64, 0x6c, 0x3d, 0x93, 0xe2, 0x0a, 0x8d, 0x02, 0xea, 0x2d, + 0xd5, 0x00, 0xb6, 0x61, 0xca, 0x0e, 0x03, 0x10, 0xaa, 0x65, 0xda, 0xc0, + 0x56, 0x96, 0xf5, 0xbd, 0x89, 0xff, 0xdf, 0x31, 0x57, 0xdf, 0x44, 0x53, + 0x90, 0x19, 0x06, 0x01, 0x11, 0x4c, 0x60, 0x41, 0x1d, 0x03, 0x2f, 0x31, + 0xbf, 0x7c, 0x3e, 0x99, 0x76, 0xb4, 0x57, 0x92, 0xde, 0x87, 0x85, 0xa3, + 0x6d, 0xd5, 0x12, 0x95, 0x03, 0x8c, 0x0c, 0x42, 0x08, 0x92, 0x0c, 0x1f, + 0x08, 0x41, 0xf8, 0xe2, 0x37, 0xaa, 0xff, 0xe5, 0x43, 0x8c, 0x97, 0x16, + 0xfd, 0x85, 0xb1, 0x62, 0xb5, 0x0a, 0x3a, 0x36, 0x02, 0xb8, 0x60, 0x89, + 0x70, 0x1c, 0x12, 0x13, 0x2a, 0x91, 0x50, 0xf3, 0xcd, 0x34, 0xde, 0x42, + 0xd9, 0x73, 0xb6, 0xdb, 0x3a, 0xba, 0x90, 0x60, 0x9c, 0x82, 0xda, 0x72, + 0x36, 0x18, 0x15, 0x88, 0x69, 0xc4, 0x94, 0xfb, 0xe6, 0x39, 0x83, 0xe5, + 0xe7, 0x36, 0x4e, 0xff, 0x3a, 0xbf, 0x6e, 0xe7, 0xca, 0x8e, 0x23, 0xe2, + 0xe5, 0x4a, 0xb9, 0x41, 0x4d, 0x99, 0x2c, 0x0e, 0xd8, 0x5d, 0x47, 0x4d, + 0xb9, 0x30, 0x6a, 0x0a, 0x46, 0xea, 0x66, 0xd9, 0x03, 0xdf, 0xd6, 0x2f, + 0xa4, 0x2d, 0x1e, 0x7b, 0x93, 0xdf, 0x9e, 0x42, 0xc2, 0x82, 0xc1, 0xc3, + 0x61, 0xb0, 0x31, 0x08, 0xff, 0xc0, 0xd5, 0x80, 0x35, 0x47, 0x42, 0x4f, + 0x99, 0x80, 0xe1, 0xf3, 0x00, 0x67, 0xdb, 0x6e, 0xa9, 0xbe, 0x9d, 0x96, + 0x6e, 0x29, 0xc4, 0x63, 0x72, 0xd0, 0xef, 0x01, 0x85, 0x65, 0xe0, 0x05, + 0xe1, 0x6b, 0x62, 0x90, 0x37, 0x8d, 0x0e, 0xbe, 0xa3, 0x0b, 0x7f, 0x9e, + 0xe7, 0xad, 0x35, 0x79, 0xca, 0x0c, 0x34, 0x1d, 0x7b, 0xec, 0x88, 0x93, + 0x27, 0xd6, 0x5f, 0x88, 0xa7, 0x91, 0x40, 0x71, 0x83, 0xa0, 0xf0, 0x3f, + 0xe2, 0xb3, 0xea, 0x0e, 0x49, 0x01, 0x8a, 0xa4, 0x91, 0xa4, 0xcd, 0xf3, + 0x6a, 0xd6, 0x4b, 0x7e, 0xce, 0x67, 0xb7, 0x73, 0x57, 0x05, 0x77, 0xc2, + 0xc0, 0x90, 0x5d, 0x81, 0xfa, 0x46, 0x07, 0xea, 0x24, 0x1c, 0xfa, 0x55, + 0x19, 0xaa, 0x56, 0xb2, 0x55, 0xea, 0x8f, 0x00, 0x93, 0xbf, 0xb1, 0x03, + 0xb0, 0xb5, 0xb1, 0xa8, 0x96, 0x23, 0xb2, 0x20, 0x36, 0x25, 0x45, 0x59, + 0x7b, 0xbb, 0xd6, 0x4b, 0x6c, 0x97, 0x0b, 0x6e, 0xcf, 0x59, 0x99, 0xe0, + 0x7c, 0xbf, 0xfe, 0xc6, 0xfe, 0x53, 0x36, 0xed, 0x63, 0xbe, 0x2b, 0xc5, + 0x02, 0x24, 0xec, 0x0e, 0xe5, 0x1b, 0x82, 0xb8, 0xc1, 0x8d, 0xf7, 0xbe, + 0x5e, 0xcc, 0xf8, 0x79, 0xc5, 0x7a, 0xa3, 0xcb, 0xdb, 0xfb, 0x6d, 0xa5, + 0xb3, 0x88, 0xd0, 0x69, 0x58, 0x74, 0x16, 0x8a, 0x63, 0x1d, 0xdf, 0xb4, + 0xcd, 0xbf, 0x51, 0x81, 0xfb, 0x1b, 0xad, 0xc2, 0xd9, 0xd5, 0x84, 0x4c, + 0x51, 0x88, 0xc1, 0x85, 0x65, 0xe6, 0x76, 0x38, 0xc2, 0x66, 0xde, 0xf8, + 0xb7, 0x7d, 0xad, 0x29, 0x92, 0xd5, 0xd1, 0xe5, 0x59, 0x1f, 0xfb, 0xa0, + 0xf9, 0x5f, 0xfd, 0x89, 0x12, 0x09, 0x50, 0xbf, 0x2f, 0x19, 0x6b, 0x97, + 0xf3, 0x0b, 0x57, 0xe8, 0x83, 0x22, 0xd2, 0x4c, 0x2b, 0x02, 0x78, 0x2c, + 0x14, 0x0f, 0x00, 0xe6, 0xb6, 0x5c, 0xd2, 0x86, 0x2f, 0xdb, 0xd5, 0xbc, + 0x57, 0xdb, 0xab, 0xce, 0xb7, 0x7e, 0x1c, 0x62, 0xe5, 0x42, 0xb9, 0x56, + 0x24, 0x30, 0x3c, 0x1d, 0xe0, 0x39, 0x2e, 0xda, 0xb0, 0x38, 0x14, 0xd3, + 0xb1, 0xad, 0x88, 0xe7, 0xe0, 0x7a, 0x39, 0x6d, 0x48, 0x75, 0x80, 0xf9, + 0x70, 0x03, 0xad, 0x92, 0x10, 0x10, 0x16, 0x36, 0xa8, 0x96, 0x21, 0x54, + 0x9a, 0xd6, 0x25, 0xb0, 0x3f, 0xdf, 0xcf, 0x75, 0x4f, 0x6e, 0xc9, 0xd8, + 0x8e, 0x61, 0x52, 0x01, 0xb8, 0x31, 0x17, 0x03, 0x40, 0xdc, 0xdd, 0xf3, + 0x25, 0x8c, 0xb0, 0x04, 0x3c, 0x1e, 0xe3, 0x17, 0xeb, 0xf7, 0xfe, 0xc1, + 0xba, 0x85, 0xb0, 0x3b, 0x06, 0x23, 0x18, 0x00, 0x6c, 0xdf, 0xa5, 0xf6, + 0xe3, 0x3e, 0x98, 0xce, 0xf8, 0x3c, 0xd9, 0xca, 0x9b, 0x22, 0x30, 0x36, + 0xc9, 0x5e, 0x62, 0x3b, 0xaa, 0x30, 0x18, 0xe8, 0xc9, 0xb2, 0xfb, 0x9f, + 0x57, 0x55, 0x02, 0xb3, 0xde, 0x51, 0xe6, 0x04, 0x0e, 0x6f, 0x7f, 0xe5, + 0x83, 0xc6, 0x73, 0x17, 0xcd, 0xca, 0x37, 0xd0, 0xf4, 0x04, 0xda, 0x58, + 0x68, 0x2c, 0xb4, 0xa9, 0xed, 0xb0, 0x84, 0x90, 0x7d, 0xa1, 0x05, 0xac, + 0xdc, 0xbf, 0x4d, 0xe5, 0xff, 0x7f, 0xb2, 0x77, 0x64, 0xcb, 0xce, 0x68, + 0x2d, 0xc2, 0xd3, 0x45, 0xec, 0x5e, 0x28, 0xcb, 0x68, 0xba, 0xf2, 0x13, + 0xd7, 0xd3, 0x81, 0xa6, 0xcb, 0x92, 0xe3, 0x54, 0xb5, 0x6d, 0x56, 0x5b, + 0xe2, 0xcd, 0xdd, 0x43, 0x3a, 0x0e, 0x2b, 0x0f, 0x11, 0x19, 0x0c, 0x00, + 0x1c, 0x07, 0x47, 0x82, 0x5a, 0xbd, 0x4d, 0xf1, 0xc9, 0x70, 0x78, 0xa6, + 0x6a, 0xdc, 0xdc, 0x88, 0xe4, 0x50, 0x09, 0x0b, 0x85, 0x93, 0xdc, 0x42, + 0x66, 0x61, 0x94, 0xc7, 0xa9, 0x12, 0x83, 0x16, 0xab, 0xb9, 0xec, 0x6f, + 0x8c, 0x36, 0xa2, 0xc1, 0x12, 0xd8, 0x8d, 0xe2, 0x42, 0xf2, 0xf6, 0xcb, + 0x9a, 0xf3, 0x09, 0x98, 0xd6, 0x4b, 0xdb, 0xe0, 0xe1, 0x86, 0xb9, 0xd9, + 0x3a, 0xbf, 0xff, 0x74, 0xa9, 0xac, 0x30, 0x2f, 0xa0, 0xdf, 0x1f, 0x24, + 0xe8, 0xf0, 0x0f, 0x26, 0x1c, 0xab, 0xdb, 0x14, 0x56, 0xc3, 0xc9, 0xfd, + 0xad, 0xf3, 0xfc, 0x2a, 0x52, 0xa7, 0x17, 0xd5, 0x20, 0xc4, 0x49, 0x97, + 0x76, 0x26, 0x0f, 0xdb, 0x53, 0x1b, 0x66, 0x52, 0xd5, 0xca, 0xc5, 0x07, + 0x5c, 0xa0, 0x97, 0x13, 0x16, 0xdc, 0xba, 0xcf, 0xb7, 0xfc, 0xdd, 0x51, + 0x04, 0x55, 0x25, 0x96, 0xc0, 0xf6, 0x74, 0x1c, 0x64, 0xd0, 0x30, 0xd9, + 0x5e, 0x7c, 0x08, 0xe4, 0x83, 0x0a, 0xbc, 0x07, 0x38, 0x31, 0x32, 0xae, + 0x88, 0x49, 0xcb, 0x35, 0x40, 0x7c, 0x3d, 0xe4, 0x2e, 0x8a, 0x40, 0xc8, + 0x29, 0xcb, 0x57, 0xec, 0xd5, 0x0a, 0x71, 0x9e, 0xc2, 0xb2, 0xd0, 0xf3, + 0x85, 0x80, 0x96, 0x17, 0x23, 0x7a, 0xc9, 0x73, 0x4d, 0xc2, 0xbd, 0x63, + 0x8a, 0x78, 0x6b, 0x88, 0xc2, 0x85, 0x1b, 0x10, 0xab, 0x63, 0xc0, 0x66, + 0xd3, 0x27, 0x61, 0x8a, 0x94, 0x78, 0x3d, 0x6c, 0xb9, 0x8f, 0xf2, 0xa5, + 0xcf, 0x75, 0x7d, 0x47, 0x3e, 0x0c, 0x13, 0x0e, 0xc0, 0x30, 0x21, 0x8e, + 0xf0, 0x78, 0xd8, 0x90, 0x5f, 0x76, 0x96, 0xec, 0xdf, 0x2b, 0x6d, 0x76, + 0xdb, 0x62, 0xaf, 0xca, 0x68, 0x80, 0x88, 0x20, 0xfd, 0x27, 0xc0, 0x30, + 0x7a, 0x0a, 0x7b, 0x63, 0x02, 0x00, 0x7b, 0xc9, 0xdd, 0x47, 0x37, 0x92, + 0x07, 0x2a, 0x40, 0x40, 0x63, 0x6c, 0x76, 0xde, 0xea, 0x49, 0x0b, 0x73, + 0x9f, 0x55, 0x89, 0x23, 0x19, 0x36, 0x46, 0x27, 0xb3, 0xd3, 0xbf, 0x11, + 0x74, 0x88, 0x96, 0x35, 0x64, 0x40, 0x90, 0xae, 0x4c, 0x80, 0xf8, 0x21, + 0xf0, 0x03, 0xd5, 0x09, 0x13, 0x92, 0x6a, 0xaf, 0xb7, 0xff, 0xad, 0x6e, + 0xd4, 0x73, 0xd0, 0x36, 0x51, 0xc2, 0xd0, 0xb4, 0x29, 0x35, 0x85, 0xa5, + 0x5a, 0x36, 0x47, 0xa1, 0x21, 0x30, 0x0e, 0x1e, 0x0f, 0x63, 0x29, 0x44, + 0xb9, 0xf5, 0x78, 0x97, 0xdf, 0x1c, 0x71, 0xbd, 0x9a, 0xdb, 0x32, 0x45, + 0x3f, 0xed, 0xd2, 0xcc, 0xcc, 0x52, 0x2c, 0x5d, 0x21, 0x7a, 0x9f, 0x24, + 0xc1, 0xb7, 0xd3, 0xb5, 0x3f, 0xbd, 0x46, 0xb7, 0x25, 0x96, 0x06, 0xb4, + 0x12, 0x5d, 0xb2, 0xb3, 0xb5, 0xb1, 0x69, 0x67, 0x96, 0x53, 0x27, 0x77, + 0xa0, 0x8d, 0xc2, 0x22, 0x6a, 0x32, 0x25, 0xcf, 0x4e, 0x4e, 0x0f, 0xcb, + 0x0d, 0xe4, 0xc9, 0x29, 0x60, 0x30, 0x9d, 0x54, 0x56, 0xc2, 0xa5, 0x32, + 0x49, 0xce, 0xf6, 0xce, 0xa2, 0xe8, 0x2d, 0x3e, 0xf8, 0x70, 0x3f, 0xcf, + 0x2f, 0x41, 0xc5, 0xfe, 0x57, 0x56, 0x40, 0x38, 0xbe, 0xa0, 0xfa, 0xdf, + 0xfe, 0x8e, 0x7d, 0xf0, 0x02, 0xec, 0xd2, 0xbf, 0x46, 0x58, 0x1d, 0x81, + 0x91, 0xc5, 0x6c, 0x7b, 0xe6, 0x09, 0x26, 0xb1, 0x3d, 0x7d, 0x65, 0x0d, + 0x4b, 0x31, 0x40, 0xac, 0xbb, 0x7f, 0xe0, 0xed, 0xa4, 0x96, 0x03, 0x15, + 0x32, 0x5d, 0x4a, 0xea, 0x2a, 0xaf, 0xd6, 0xe7, 0xc2, 0x98, 0x67, 0xd8, + 0x0d, 0xcd, 0x4a, 0xbc, 0x98, 0x3f, 0x65, 0x3b, 0x38, 0xa1, 0x6d, 0xf0, + 0x7e, 0x59, 0x7d, 0x43, 0x75, 0xbc, 0x05, 0x01, 0x28, 0xc8, 0x93, 0x41, + 0x97, 0x10, 0x93, 0xe5, 0x9f, 0x06, 0x5f, 0xec, 0x55, 0x08, 0xda, 0xf3, + 0x2d, 0x76, 0x5b, 0x04, 0x45, 0x07, 0xb5, 0x2f, 0xb4, 0x0c, 0x8b, 0x5a, + 0xe7, 0x0b, 0x31, 0x45, 0x81, 0x92, 0xe2, 0x61, 0x9b, 0x17, 0x66, 0xa7, + 0xdc, 0x47, 0x7e, 0x59, 0x72, 0x2d, 0x2e, 0xf6, 0x55, 0xe8, 0x72, 0x46, + 0x8c, 0x6f, 0x2d, 0x67, 0x7d, 0xf1, 0xcc, 0xdc, 0x50, 0xb1, 0x5e, 0x77, + 0xdc, 0x94, 0x18, 0x4e, 0x92, 0xa0, 0x61, 0xba, 0x71, 0x11, 0x4e, 0xc2, + 0xaa, 0x6d, 0x0b, 0xf3, 0x1f, 0x62, 0xff, 0x77, 0xbf, 0x5d, 0x7e, 0x8b, + 0x8d, 0x74, 0x16, 0xb7, 0xa8, 0x9f, 0xd7, 0xcf, 0xde, 0x5a, 0xa7, 0xaa, + 0x51, 0xf2, 0x72, 0xce, 0x9e, 0xbd, 0xdf, 0x7f, 0x23, 0x70, 0xa8, 0xae, + 0x4d, 0xf0, 0x8b, 0x9b, 0x50, 0x3f, 0x97, 0x95, 0x64, 0x51, 0x2a, 0x25, + 0x3d, 0x50, 0x6a, 0x48, 0x43, 0x73, 0x56, 0xec, 0x0d, 0x0a, 0x60, 0xaf, + 0xd2, 0xb6, 0x25, 0xcf, 0x96, 0x69, 0x5e, 0x45, 0xbb, 0x22, 0xfc, 0x22, + 0x94, 0xc3, 0x65, 0x17, 0x9d, 0xbd, 0x84, 0x8a, 0x79, 0x29, 0xfe, 0xb6, + 0x18, 0x81, 0x46, 0x0d, 0x5a, 0x04, 0x26, 0x20, 0xe5, 0xaa, 0xde, 0xa5, + 0x6d, 0x98, 0xd7, 0xa7, 0x20, 0x32, 0x2f, 0x45, 0xe8, 0x6c, 0xa7, 0x98, + 0x0c, 0x27, 0x0e, 0x00, 0xc1, 0x08, 0x4b, 0x56, 0x3f, 0x00, 0xf1, 0x27, + 0xea, 0xdb, 0xbb, 0xa9, 0xda, 0x03, 0x7b, 0x28, 0xdb, 0xb1, 0x5e, 0x45, + 0x83, 0x85, 0x05, 0xa1, 0x60, 0x30, 0x81, 0x82, 0x19, 0x78, 0x22, 0x84, + 0x36, 0x58, 0xff, 0x71, 0xb2, 0xe6, 0xea, 0xac, 0xca, 0xb4, 0x2c, 0x5a, + 0xdd, 0x80, 0xaf, 0xda, 0xa4, 0x4c, 0x4c, 0x46, 0x05, 0x18, 0x1c, 0x05, + 0x00, 0xf9, 0x52, 0xa1, 0xe3, 0x1f, 0x4e, 0x3f, 0x6e, 0xfb, 0x44, 0xb4, + 0xab, 0x7b, 0xdc, 0x02, 0xbe, 0xf5, 0xd2, 0xb6, 0xd4, 0x40, 0xeb, 0x0b, + 0x33, 0xc0, 0xc2, 0xbe, 0xde, 0xd9, 0x10, 0x18, 0x69, 0x48, 0x9b, 0x08, + 0x62, 0x48, 0x07, 0x97, 0x01, 0xc6, 0x23, 0x23, 0xff, 0xdc, 0xcb, 0xfc, + 0xf6, 0x49, 0x8a, 0x77, 0x76, 0xf6, 0xc2, 0xc8, 0x22, 0xe2, 0x89, 0x4b, + 0x41, 0xc6, 0x21, 0x30, 0x92, 0x98, 0x49, 0xc0, 0xfc, 0xb9, 0x96, 0x95, + 0xb5, 0xdb, 0x14, 0xfa, 0xf7, 0x9a, 0xb5, 0xe5, 0x0d, 0xd7, 0x70, 0x39, + 0x00, 0x3c, 0x43, 0x6c, 0x20, 0x89, 0x7f, 0x2f, 0x6e, 0xd9, 0xe5, 0x20, + 0x61, 0xa4, 0x73, 0xd8, 0x88, 0x11, 0xd6, 0x52, 0x2d, 0x09, 0xc0, 0xc0, + 0x18, 0x3d, 0x68, 0x0d, 0x25, 0x1d, 0x03, 0x21, 0x8c, 0xd5, 0x78, 0x81, + 0x4f, 0xac, 0x92, 0xac, 0x1b, 0x16, 0x03, 0x05, 0x77, 0x2f, 0x6b, 0xdf, + 0x0c, 0xa6, 0x16, 0x32, 0xf3, 0xbb, 0x51, 0x40, 0xa4, 0xc9, 0x72, 0xad, + 0xd0, 0x51, 0xe0, 0x96, 0xa7, 0x26, 0x03, 0x0e, 0x28, 0xfa, 0xe7, 0x17, + 0x52, 0x1f, 0xc6, 0x6f, 0xe0, 0x2d, 0x85, 0xc2, 0x38, 0x1f, 0x83, 0xa0, + 0x0d, 0x49, 0xa9, 0xcb, 0xc0, 0xd0, 0xf1, 0x81, 0xf7, 0xf5, 0xbf, 0x2f, + 0xba, 0xaf, 0x59, 0xfd, 0xe4, 0xf7, 0xb0, 0x6f, 0xb9, 0xbe, 0x1b, 0xe8, + 0x2b, 0x8b, 0x41, 0x8e, 0x8b, 0x13, 0x82, 0x95, 0x30, 0x8c, 0x91, 0x50, + 0x87, 0xaa, 0x77, 0xcd, 0xea, 0x65, 0x0a, 0x16, 0xda, 0x20, 0xce, 0xdb, + 0xc0, 0xdb, 0x3b, 0xaa, 0x01, 0x6c, 0x9a, 0x44, 0xa9, 0xa0, 0xc9, 0x53, + 0x14, 0xdf, 0xc1, 0x81, 0x34, 0x42, 0x9e, 0xe0, 0x32, 0x8b, 0x28, 0x8a, + 0x19, 0xcb, 0xd0, 0xc1, 0xe6, 0x9a, 0x1f, 0xf8, 0x49, 0x4c, 0x98, 0xbd, + 0x37, 0xe7, 0xd8, 0x67, 0x25, 0x86, 0xe2, 0xc8, 0xac, 0x0e, 0x44, 0x41, + 0x68, 0x61, 0x05, 0x08, 0x29, 0x4b, 0x84, 0xa6, 0x2f, 0xb7, 0xfd, 0xd8, + 0xa4, 0xa9, 0x15, 0x52, 0xba, 0xd2, 0x08, 0xa1, 0xc0, 0x5b, 0x7d, 0x9d, + 0x33, 0x53, 0x0f, 0x20, 0x1a, 0x59, 0x8d, 0x81, 0xc9, 0x6c, 0xac, 0x41, + 0xdd, 0x2d, 0x88, 0xb3, 0x3f, 0x7d, 0x79, 0xfb, 0x43, 0xd1, 0x16, 0x82, + 0x41, 0x4f, 0x88, 0xe5, 0xc1, 0xff, 0x8b, 0xaa, 0x76, 0xb5, 0x5e, 0xe0, + 0x74, 0x39, 0xf5, 0xfd, 0xd4, 0x2b, 0x66, 0x8a, 0x8f, 0x17, 0x01, 0xb0, + 0x0f, 0x4c, 0x0d, 0xd2, 0xf2, 0xa2, 0xe2, 0xda, 0x58, 0xaa, 0xf0, 0xae, + 0xf2, 0xae, 0x1b, 0x28, 0xe8, 0x24, 0x86, 0xf1, 0xd3, 0x40, 0xc0, 0x88, + 0xac, 0x3a, 0x49, 0xff, 0x27, 0x6c, 0x18, 0x6f, 0xbe, 0x07, 0x25, 0x10, + 0x7f, 0x41, 0x83, 0x90, 0xf7, 0x54, 0x28, 0xe8, 0x08, 0x2b, 0x5a, 0xe8, + 0x6e, 0xa0, 0x58, 0xad, 0x85, 0x4c, 0x2c, 0xeb, 0x7b, 0xc0, 0x64, 0x7c, + 0xa8, 0x79, 0xc9, 0x16, 0x38, 0x0c, 0xe5, 0x6a, 0x87, 0x40, 0xab, 0x10, + 0xf9, 0xef, 0x6b, 0x3e, 0x2f, 0x4f, 0xad, 0x29, 0xb4, 0x71, 0x9c, 0xfd, + 0xec, 0xf8, 0x38, 0xc0, 0x51, 0x45, 0xda, 0x8c, 0x3c, 0x18, 0xde, 0xca, + 0xec, 0x01, 0xe2, 0x47, 0xea, 0x7d, 0xdf, 0xa9, 0xb2, 0xb6, 0xcd, 0xd9, + 0xe5, 0xe8, 0x83, 0xf5, 0xa7, 0xc3, 0x40, 0x4a, 0xd5, 0x77, 0x9f, 0x58, + 0x2d, 0xf4, 0xc3, 0x67, 0x7c, 0xdb, 0x4a, 0xdb, 0x9d, 0xcf, 0x7b, 0x2c, + 0x03, 0x33, 0xd3, 0x96, 0xd0, 0x28, 0x58, 0xa7, 0x4a, 0xb0, 0x44, 0x52, + 0x5a, 0x58, 0x59, 0xa0, 0xc4, 0x50, 0x10, 0x07, 0x4a, 0x82, 0x00, 0x95, + 0x14, 0xfe, 0x29, 0x4f, 0xb8, 0xad, 0x46, 0x7e, 0x37, 0xe5, 0xfd, 0x27, + 0x3d, 0x60, 0xdf, 0x30, 0x39, 0x06, 0x21, 0x16, 0x81, 0xe6, 0x47, 0x80, + 0xdd, 0xd2, 0xe5, 0x79, 0x38, 0x38, 0xac, 0x51, 0xcf, 0x5b, 0x53, 0xf9, + 0x11, 0x79, 0x9d, 0x2c, 0x1c, 0x66, 0xf2, 0x83, 0x10, 0x07, 0xf0, 0x86, + 0x25, 0xab, 0xd6, 0x9b, 0x63, 0x14, 0xa6, 0x2e, 0x8d, 0xcf, 0x34, 0xa8, + 0x0a, 0xef, 0xb9, 0x65, 0x9d, 0xc2, 0xac, 0xc5, 0x83, 0xdc, 0x02, 0x26, + 0x4b, 0xff, 0x36, 0x23, 0x04, 0x83, 0x7a, 0x46 +}; + +void mpeg4_get_video_info(VideoDecodeInfo *info) +{ + info->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; + info->width = MPEG4_CLIP_WIDTH; + info->height = MPEG4_CLIP_HEIGHT; + info->data = mpeg4_clip; + info->data_size = MPEG4_CLIP_DATA_SIZE; +} diff --git a/tests/test-mpeg4.h b/tests/test-mpeg4.h new file mode 100644 index 0000000000..8ac1e82153 --- /dev/null +++ b/tests/test-mpeg4.h @@ -0,0 +1,30 @@ +/* + * test-mpeg4.h - MPEG-4 test data + * + * Copyright (C) 2012 Intel Corporation + * + * 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 TEST_MPEG4_H +#define TEST_MPEG4_H + +#include +#include "test-decode.h" + +void mpeg4_get_video_info(VideoDecodeInfo *info); + +#endif /* TEST_MPEG4_H */ From 44945ac9eb7cc468640d358e3018504a4585b6fd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 30 Nov 2012 17:25:07 +0100 Subject: [PATCH 0920/3781] Add GstVaapiMiniObject. Introduce a new reference counted object that is very lightweight and also provides flags and user-data functionalities. Initialization and finalization times are reduced by up to a factor 5x vs GstMiniObject from GStreamer 0.10 stack. This is a libgstvaapi internal object. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapiminiobject.c | 253 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiminiobject.h | 155 +++++++++++++++ 3 files changed, 410 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiminiobject.c create mode 100644 gst-libs/gst/vaapi/gstvaapiminiobject.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 8eb2235f4c..fe1e44bb55 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -55,6 +55,7 @@ libgstvaapi_source_c = \ gstvaapiimage.c \ gstvaapiimageformat.c \ gstvaapiimagepool.c \ + gstvaapiminiobject.c \ gstvaapiobject.c \ gstvaapiparamspecs.c \ gstvaapiprofile.c \ @@ -105,6 +106,7 @@ libgstvaapi_source_priv_h = \ gstvaapidecoder_objects.h \ gstvaapidecoder_priv.h \ gstvaapidisplay_priv.h \ + gstvaapiminiobject.h \ gstvaapiobject_priv.h \ gstvaapisurface_priv.h \ gstvaapiutils.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.c b/gst-libs/gst/vaapi/gstvaapiminiobject.c new file mode 100644 index 0000000000..039f2058b1 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.c @@ -0,0 +1,253 @@ +/* + * gstvaapiminiobject.c - A lightweight reference counted object + * + * Copyright (C) 2012 Intel Corporation + * + * 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 +#include "gstvaapiminiobject.h" + +typedef struct _GstVaapiMiniObjectBase GstVaapiMiniObjectBase; +struct _GstVaapiMiniObjectBase { + gconstpointer object_class; + gint ref_count; + GDestroyNotify user_data_destroy_notify; +}; + +static inline GstVaapiMiniObjectBase * +object2base(GstVaapiMiniObject *object) +{ + return GUINT_TO_POINTER(GPOINTER_TO_UINT(object) - + sizeof(GstVaapiMiniObjectBase)); +} + +static inline GstVaapiMiniObject * +base2object(GstVaapiMiniObjectBase *base_object) +{ + return GUINT_TO_POINTER(GPOINTER_TO_UINT(base_object) + + sizeof(GstVaapiMiniObjectBase)); +} + +static void +gst_vaapi_mini_object_free(GstVaapiMiniObject *object) +{ + GstVaapiMiniObjectBase * const base_object = object2base(object); + const GstVaapiMiniObjectClass * const klass = base_object->object_class; + + g_atomic_int_inc(&base_object->ref_count); + + if (klass->finalize) + klass->finalize(object); + + if (G_LIKELY(g_atomic_int_dec_and_test(&base_object->ref_count))) { + if (object->user_data && base_object->user_data_destroy_notify) + base_object->user_data_destroy_notify(object->user_data); + g_slice_free1(sizeof(*base_object) + klass->size, base_object); + } +} + +const GstVaapiMiniObjectClass * +gst_vaapi_mini_object_get_class(GstVaapiMiniObject *object) +{ + g_return_val_if_fail(object != NULL, NULL); + + return object2base(object)->object_class; +} + +/** + * gst_vaapi_mini_object_new: + * @object_class: (optional): The object class + * + * Creates a new #GstVaapiMiniObject. If @object_class is NULL, then the + * size of the allocated object is the same as sizeof(GstVaapiMiniObject). + * If @object_class is not NULL, typically when a sub-class is implemented, + * that pointer shall reference a statically allocated descriptor. + * + * This function does *not* zero-initialize the derived object data, + * use gst_vaapi_mini_object_new0() to fill this purpose. + * + * Returns: The newly allocated #GstVaapiMiniObject + */ +GstVaapiMiniObject * +gst_vaapi_mini_object_new(const GstVaapiMiniObjectClass *object_class) +{ + GstVaapiMiniObject *object; + GstVaapiMiniObjectBase *base_object; + + static const GstVaapiMiniObjectClass default_object_class = { + .size = sizeof(GstVaapiMiniObject), + }; + + if (!object_class) + object_class = &default_object_class; + + g_return_val_if_fail(object_class->size >= sizeof(*object), NULL); + + base_object = g_slice_alloc(sizeof(*base_object) + object_class->size); + if (!base_object) + return NULL; + + object = base2object(base_object); + object->flags = 0; + object->user_data = 0; + + base_object->object_class = object_class; + base_object->ref_count = 1; + base_object->user_data_destroy_notify = NULL; + return object; +} + +/** + * gst_vaapi_mini_object_new0: + * @object_class: (optional): The object class + * + * Creates a new #GstVaapiMiniObject. This function is similar to + * gst_vaapi_mini_object_new() but derived object data is initialized + * to zeroes. + * + * Returns: The newly allocated #GstVaapiMiniObject + */ +GstVaapiMiniObject * +gst_vaapi_mini_object_new0(const GstVaapiMiniObjectClass *object_class) +{ + GstVaapiMiniObject *object; + guint sub_size; + + object = gst_vaapi_mini_object_new(object_class); + if (!object) + return NULL; + + object_class = object2base(object)->object_class; + + sub_size = object_class->size - sizeof(*object); + if (sub_size > 0) + memset(((guchar *)object) + sizeof(*object), 0, sub_size); + return object; +} + +/** + * gst_vaapi_mini_object_ref: + * @object: a #GstVaapiMiniObject + * + * Atomically increases the reference count of the given @object by one. + * + * Returns: The same @object argument + */ +GstVaapiMiniObject * +gst_vaapi_mini_object_ref(GstVaapiMiniObject *object) +{ + g_return_val_if_fail(object != NULL, NULL); + + g_atomic_int_inc(&object2base(object)->ref_count); + return object; +} + +/** + * gst_vaapi_mini_object_unref: + * @object: a #GstVaapiMiniObject + * + * Atomically decreases the reference count of the @object by one. If + * the reference count reaches zero, the object will be free'd. + */ +void +gst_vaapi_mini_object_unref(GstVaapiMiniObject *object) +{ + g_return_if_fail(object != NULL); + g_return_if_fail(object2base(object)->ref_count > 0); + + if (g_atomic_int_dec_and_test(&object2base(object)->ref_count)) + gst_vaapi_mini_object_free(object); +} + +/** + * gst_vaapi_mini_object_replace: + * @old_object_ptr: a pointer to a #GstVaapiMiniObject + * @new_object: a #GstVaapiMiniObject + * + * Atomically replaces the object held in @old_object_ptr with + * @new_object. This means that @old_object_ptr shall reference a + * valid object. However, @new_object can be NULL. + */ +void +gst_vaapi_mini_object_replace(GstVaapiMiniObject **old_object_ptr, + GstVaapiMiniObject *new_object) +{ + GstVaapiMiniObject *old_object; + + g_return_if_fail(old_object_ptr != NULL); + + old_object = g_atomic_pointer_get((gpointer *)old_object_ptr); + + if (old_object == new_object) + return; + + if (new_object) + gst_vaapi_mini_object_ref(new_object); + + while (!g_atomic_pointer_compare_and_exchange((gpointer *)old_object_ptr, + old_object, new_object)) + old_object = g_atomic_pointer_get((gpointer *)old_object_ptr); + + if (old_object) + gst_vaapi_mini_object_unref(old_object); +} + +/** + * gst_vaapi_mini_object_get_user_data: + * @object: a #GstVaapiMiniObject + * + * Gets user-provided data set on the object via a previous call to + * gst_vaapi_mini_object_set_user_data(). + * + * Returns: (transfer none): The previously set user_data + */ +gpointer +gst_vaapi_mini_object_get_user_data(GstVaapiMiniObject *object) +{ + g_return_val_if_fail(object != NULL, NULL); + + return object->user_data; +} + +/** + * gst_vaapi_mini_object_set_user_data: + * @object: a #GstVaapiMiniObject + * @user_data: user-provided data + * @destroy_notify: (closure user_data): a #GDestroyNotify + * + * Sets @user_data on the object and the #GDestroyNotify that will be + * called when the data is freed. + * + * If some @user_data was previously set, then the former @destroy_notify + * function will be called before the @user_data is replaced. + */ +void +gst_vaapi_mini_object_set_user_data(GstVaapiMiniObject *object, + gpointer user_data, GDestroyNotify destroy_notify) +{ + GstVaapiMiniObjectBase *base_object; + + g_return_if_fail(object != NULL); + + base_object = object2base(object); + if (object->user_data && base_object->user_data_destroy_notify) + base_object->user_data_destroy_notify(object->user_data); + + object->user_data = user_data; + base_object->user_data_destroy_notify = destroy_notify; +} diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.h b/gst-libs/gst/vaapi/gstvaapiminiobject.h new file mode 100644 index 0000000000..4cf27d9621 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.h @@ -0,0 +1,155 @@ +/* + * gstvaapiminiobject.h - A lightweight reference counted object + * + * Copyright (C) 2012 Intel Corporation + * + * 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_MINI_OBJECT_H +#define GST_VAAPI_MINI_OBJECT_H + +#include + +G_BEGIN_DECLS + +typedef struct _GstVaapiMiniObject GstVaapiMiniObject; +typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; + +/** + * GST_VAAPI_MINI_OBJECT: + * @object: a #GstVaapiMiniObject + * + * Casts the @object to a #GstVaapiMiniObject + */ +#define GST_VAAPI_MINI_OBJECT(object) \ + ((GstVaapiMiniObject *)(object)) + +/** + * GST_VAAPI_MINI_OBJECT_GET_CLASS: + * @object: a #GstVaapiMiniObject + * + * Retrieves the #GstVaapiMiniObjectClass associated with the @object + */ +#define GST_VAAPI_MINI_OBJECT_GET_CLASS(object) \ + gst_vaapi_mini_object_get_class(GST_VAAPI_MINI_OBJECT(object)) + +/** + * GST_VAAPI_MINI_OBJECT_FLAGS: + * @object: a #GstVaapiMiniObject + * + * The entire set of flags for the @object + */ +#define GST_VAAPI_MINI_OBJECT_FLAGS(object) \ + (GST_VAAPI_MINI_OBJECT(object)->flags) + +/** + * GST_VAAPI_MINI_OBJECT_FLAG_IS_SET: + * @object: a #GstVaapiMiniObject + * @flag: a flag to check for + * + * Checks whether the given @flag is set + */ +#define GST_VAAPI_MINI_OBJECT_FLAG_IS_SET(object, flag) \ + ((GST_VAAPI_MINI_OBJECT_FLAGS(object) & (flag)) != 0) + +/** + * GST_VAAPI_MINI_OBJECT_FLAG_SET: + * @object: a #GstVaapiMiniObject + * @flags: flags to set + * + * This macro sets the given bits + */ +#define GST_VAAPI_MINI_OBJECT_FLAG_SET(object, flags) \ + (GST_VAAPI_MINI_OBJECT_FLAGS(object) |= (flags)) + +/** + * GST_VAAPI_MINI_OBJECT_FLAG_UNSET: + * @object: a #GstVaapiMiniObject + * @flags: flags to unset + * + * This macro unsets the given bits. + */ +#define GST_VAAPI_MINI_OBJECT_FLAG_UNSET(object, flags) \ + (GST_VAAPI_MINI_OBJECT_FLAGS(object) &= ~(flags)) + +/** + * GstVaapiMiniObject: + * @flags: set of flags that should be manipulated through + * GST_VAAPI_MINI_OBJECT_FLAG_*() functions + * @user_data: user-provided data from gst_vaapi_mini_object_set_user_data() + * + * A #GstVaapiMiniObject represents a minimal reference counted data + * structure that can hold a set of flags and user-provided data. + */ +struct _GstVaapiMiniObject { + /*< private >*/ + guint flags; + gpointer user_data; +}; + +/** + * GstVaapiMiniObjectClass: + * @size: size in bytes of the #GstVaapiMiniObject, plus any + * additional data for derived classes + * @finalize: function called to destroy data in derived classes + * + * A #GstVaapiMiniObjectClass represents the base object class that + * defines the size of the #GstVaapiMiniObject and utility function to + * dispose child objects + */ +struct _GstVaapiMiniObjectClass { + guint size; + GDestroyNotify finalize; +}; + +G_GNUC_INTERNAL +const GstVaapiMiniObjectClass * +gst_vaapi_mini_object_get_class(GstVaapiMiniObject *object) G_GNUC_CONST; + +G_GNUC_INTERNAL +GstVaapiMiniObject * +gst_vaapi_mini_object_new(const GstVaapiMiniObjectClass *object_class); + +G_GNUC_INTERNAL +GstVaapiMiniObject * +gst_vaapi_mini_object_new0(const GstVaapiMiniObjectClass *object_class); + +G_GNUC_INTERNAL +GstVaapiMiniObject * +gst_vaapi_mini_object_ref(GstVaapiMiniObject *object); + +G_GNUC_INTERNAL +void +gst_vaapi_mini_object_unref(GstVaapiMiniObject *object); + +G_GNUC_INTERNAL +void +gst_vaapi_mini_object_replace(GstVaapiMiniObject **old_object_ptr, + GstVaapiMiniObject *new_object); + +G_GNUC_INTERNAL +gpointer +gst_vaapi_mini_object_get_user_data(GstVaapiMiniObject *object); + +G_GNUC_INTERNAL +void +gst_vaapi_mini_object_set_user_data(GstVaapiMiniObject *object, + gpointer user_data, GDestroyNotify destroy_notify); + +G_END_DECLS + +#endif /* GST_VAAPI_MINI_OBJECT_H */ From 1130a46837500e6d162a5e28bcc726570bf03f70 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 3 Dec 2012 13:46:28 +0100 Subject: [PATCH 0921/3781] surfaceproxy: port to GstVaapiMiniObject. GstVaapiSurfaceProxy does not use any particular functionality from GObject. Actually, it only needs a basic object type with reference counting. This is an API and ABI change. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 3 +- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 6 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 346 ++++++++----------- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 71 +--- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 8 +- gst/vaapi/gstvaapidecode.c | 17 +- gst/vaapi/gstvaapipluginbuffer.c | 2 +- tests/test-decode.c | 2 +- tests/test-subpicture.c | 2 +- 9 files changed, 185 insertions(+), 272 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index b8052d30dd..f2513393ca 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -229,7 +229,8 @@ gst_vaapi_decoder_finalize(GObject *object) } if (priv->surfaces) { - clear_queue(priv->surfaces, (GDestroyNotify)g_object_unref); + clear_queue(priv->surfaces, (GDestroyNotify) + gst_vaapi_surface_proxy_unref); g_queue_free(priv->surfaces); priv->surfaces = NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 06cdc9a418..35f823ca87 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -82,7 +82,7 @@ gst_vaapi_picture_destroy(GstVaapiPicture *picture) } if (picture->proxy) { - g_object_unref(picture->proxy); + gst_vaapi_surface_proxy_unref(picture->proxy); picture->proxy = NULL; } else if (picture->surface) { @@ -107,7 +107,7 @@ gst_vaapi_picture_create( if (args->flags & GST_VAAPI_CREATE_PICTURE_FLAG_CLONE) { GstVaapiPicture * const parent_picture = GST_VAAPI_PICTURE(args->data); - picture->proxy = g_object_ref(parent_picture->proxy); + picture->proxy = gst_vaapi_surface_proxy_ref(parent_picture->proxy); picture->surface = gst_vaapi_surface_proxy_get_surface(picture->proxy); picture->type = parent_picture->type; picture->pts = parent_picture->pts; @@ -341,7 +341,7 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) return FALSE; if (!GST_VAAPI_PICTURE_IS_SKIPPED(picture)) { - proxy = g_object_ref(picture->proxy); + proxy = gst_vaapi_surface_proxy_ref(picture->proxy); gst_vaapi_surface_proxy_set_timestamp(proxy, picture->pts); if (GST_VAAPI_PICTURE_IS_INTERLACED(picture)) gst_vaapi_surface_proxy_set_interlaced(proxy, TRUE); diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index dc5d52ff1c..10bd736988 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -28,18 +28,21 @@ #include "sysdeps.h" #include "gstvaapisurfaceproxy.h" #include "gstvaapiobject_priv.h" +#include "gstvaapiminiobject.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiSurfaceProxy, gst_vaapi_surface_proxy, G_TYPE_OBJECT) +#define GST_VAAPI_SURFACE_PROXY(obj) \ + ((GstVaapiSurfaceProxy *)(obj)) -#define GST_VAAPI_SURFACE_PROXY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_SURFACE_PROXY, \ - GstVaapiSurfaceProxyPrivate)) +#define GST_VAAPI_IS_SURFACE_PROXY(obj) \ + (GST_VAAPI_SURFACE_PROXY(obj) != NULL) + +struct _GstVaapiSurfaceProxy { + /*< private >*/ + GstVaapiMiniObject parent_instance; -struct _GstVaapiSurfaceProxyPrivate { GstVaapiContext *context; GstVaapiSurface *surface; GstClockTime timestamp; @@ -48,175 +51,31 @@ struct _GstVaapiSurfaceProxyPrivate { guint tff : 1; }; -enum { - PROP_0, - - PROP_CONTEXT, - PROP_SURFACE, - PROP_TIMESTAMP, - PROP_DURATION, - PROP_INTERLACED, - PROP_TFF -}; - static void -gst_vaapi_surface_proxy_finalize(GObject *object) +gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) { - GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(object); - gst_vaapi_surface_proxy_set_surface(proxy, NULL); gst_vaapi_surface_proxy_set_context(proxy, NULL); - - G_OBJECT_CLASS(gst_vaapi_surface_proxy_parent_class)->finalize(object); -} - -static void -gst_vaapi_surface_proxy_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(object); - - switch (prop_id) { - case PROP_CONTEXT: - gst_vaapi_surface_proxy_set_context(proxy, g_value_get_pointer(value)); - break; - case PROP_SURFACE: - gst_vaapi_surface_proxy_set_surface(proxy, g_value_get_pointer(value)); - break; - case PROP_TIMESTAMP: - gst_vaapi_surface_proxy_set_timestamp(proxy, g_value_get_uint64(value)); - break; - case PROP_DURATION: - gst_vaapi_surface_proxy_set_duration(proxy, g_value_get_uint64(value)); - break; - case PROP_INTERLACED: - gst_vaapi_surface_proxy_set_interlaced(proxy, g_value_get_boolean(value)); - break; - case PROP_TFF: - gst_vaapi_surface_proxy_set_tff(proxy, g_value_get_boolean(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_surface_proxy_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(object); - - switch (prop_id) { - case PROP_CONTEXT: - g_value_set_pointer(value, gst_vaapi_surface_proxy_get_context(proxy)); - break; - case PROP_SURFACE: - g_value_set_pointer(value, gst_vaapi_surface_proxy_get_surface(proxy)); - break; - case PROP_TIMESTAMP: - g_value_set_uint64(value, gst_vaapi_surface_proxy_get_timestamp(proxy)); - break; - case PROP_DURATION: - g_value_set_uint64(value, gst_vaapi_surface_proxy_get_duration(proxy)); - break; - case PROP_INTERLACED: - g_value_set_boolean(value, gst_vaapi_surface_proxy_get_interlaced(proxy)); - break; - case PROP_TFF: - g_value_set_boolean(value, gst_vaapi_surface_proxy_get_tff(proxy)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_surface_proxy_class_init(GstVaapiSurfaceProxyClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiSurfaceProxyPrivate)); - - object_class->finalize = gst_vaapi_surface_proxy_finalize; - object_class->set_property = gst_vaapi_surface_proxy_set_property; - object_class->get_property = gst_vaapi_surface_proxy_get_property; - - g_object_class_install_property - (object_class, - PROP_CONTEXT, - g_param_spec_pointer("context", - "Context", - "The context stored in the proxy", - G_PARAM_READWRITE)); - - g_object_class_install_property - (object_class, - PROP_SURFACE, - g_param_spec_pointer("surface", - "Surface", - "The surface stored in the proxy", - G_PARAM_READWRITE)); - - g_object_class_install_property - (object_class, - PROP_TIMESTAMP, - g_param_spec_uint64("timestamp", - "Timestamp", - "The presentation time of the surface", - 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, - G_PARAM_READWRITE)); - - g_object_class_install_property - (object_class, - PROP_DURATION, - g_param_spec_uint64("duration", - "Duration", - "The amount of time the surface is to be presented", - 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, - G_PARAM_READWRITE)); - - g_object_class_install_property - (object_class, - PROP_INTERLACED, - g_param_spec_boolean("interlaced", - "Interlaced", - "Flag indicating whether surface is interlaced", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property - (object_class, - PROP_TFF, - g_param_spec_boolean("tff", - "Top-Field-First", - "Flag indicating for interlaced surfaces whether Top Field is First", - FALSE, - G_PARAM_READWRITE)); } static void gst_vaapi_surface_proxy_init(GstVaapiSurfaceProxy *proxy) { - GstVaapiSurfaceProxyPrivate *priv; + proxy->timestamp = GST_CLOCK_TIME_NONE; + proxy->duration = GST_CLOCK_TIME_NONE; - priv = GST_VAAPI_SURFACE_PROXY_GET_PRIVATE(proxy); - proxy->priv = priv; - priv->context = NULL; - priv->surface = NULL; - priv->timestamp = GST_CLOCK_TIME_NONE; - priv->duration = GST_CLOCK_TIME_NONE; - priv->is_interlaced = FALSE; - priv->tff = FALSE; + proxy->is_interlaced = FALSE; + proxy->tff = FALSE; +} + +static inline const GstVaapiMiniObjectClass * +gst_vaapi_surface_proxy_class(void) +{ + static const GstVaapiMiniObjectClass GstVaapiSurfaceProxyClass = { + sizeof(GstVaapiSurfaceProxy), + (GDestroyNotify)gst_vaapi_surface_proxy_finalize + }; + return &GstVaapiSurfaceProxyClass; } /** @@ -232,13 +91,111 @@ gst_vaapi_surface_proxy_init(GstVaapiSurfaceProxy *proxy) GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface) { + GstVaapiMiniObject *object; + GstVaapiSurfaceProxy *proxy; + g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - return g_object_new(GST_VAAPI_TYPE_SURFACE_PROXY, - "context", context, - "surface", surface, - NULL); + object = gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class()); + if (!object) + return NULL; + + proxy = GST_VAAPI_SURFACE_PROXY(object); + gst_vaapi_surface_proxy_init(proxy); + gst_vaapi_surface_proxy_set_context(proxy, context); + gst_vaapi_surface_proxy_set_surface(proxy, surface); + return proxy; +} + +/** + * gst_vaapi_surface_proxy_ref: + * @proxy: a #GstVaapiSurfaceProxy + * + * Atomically increases the reference count of the given @proxy by one. + * + * Returns: The same @proxy argument + */ +GstVaapiSurfaceProxy * +gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); + + return GST_VAAPI_SURFACE_PROXY(gst_vaapi_mini_object_ref( + GST_VAAPI_MINI_OBJECT(proxy))); +} + +/** + * gst_vaapi_surface_proxy_unref: + * @proxy: a #GstVaapiSurfaceProxy + * + * 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_surface_proxy_unref(GstVaapiSurfaceProxy *proxy) +{ + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(proxy)); +} + +/** + * gst_vaapi_surface_proxy_replace: + * @old_proxy_ptr: a pointer to a #GstVaapiSurfaceProxy + * @new_proxy: a #GstVaapiSurfaceProxy + * + * 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_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr, + GstVaapiSurfaceProxy *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_surface_proxy_get_user_data: + * @proxy: a #GstVaapiSurfaceProxy + * + * Gets user-provided data set on the object via a previous call to + * gst_vaapi_surface_proxy_set_user_data(). + * + * Returns: (transfer none): The previously set user_data + */ +gpointer +gst_vaapi_surface_proxy_get_user_data(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); + + return gst_vaapi_mini_object_get_user_data(GST_VAAPI_MINI_OBJECT(proxy)); +} + +/** + * gst_vaapi_surface_proxy_set_user_data: + * @proxy: a #GstVaapiSurfaceProxy + * @user_data: user-provided data + * @destroy_notify: (closure user_data): a #GDestroyNotify + * + * Sets @user_data on the object and the #GDestroyNotify that will be + * called when the data is freed. + * + * If some @user_data was previously set, then the former @destroy_notify + * function will be called before the @user_data is replaced. + */ +void +gst_vaapi_surface_proxy_set_user_data(GstVaapiSurfaceProxy *proxy, + gpointer user_data, GDestroyNotify destroy_notify) +{ + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + + gst_vaapi_mini_object_set_user_data(GST_VAAPI_MINI_OBJECT(proxy), + user_data, destroy_notify); } /** @@ -254,7 +211,7 @@ gst_vaapi_surface_proxy_get_context(GstVaapiSurfaceProxy *proxy) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); - return proxy->priv->context; + return proxy->context; } /** @@ -272,16 +229,12 @@ gst_vaapi_surface_proxy_set_context( GstVaapiContext *context ) { - GstVaapiSurfaceProxyPrivate *priv; - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - priv = proxy->priv; - - g_clear_object(&priv->context); + g_clear_object(&proxy->context); if (context) - priv->context = g_object_ref(context); + proxy->context = g_object_ref(context); } /** @@ -297,7 +250,7 @@ gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); - return proxy->priv->surface; + return proxy->surface; } /** @@ -312,9 +265,9 @@ GstVaapiID gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), GST_VAAPI_ID_NONE); - g_return_val_if_fail(proxy->priv->surface != NULL, GST_VAAPI_ID_NONE); + g_return_val_if_fail(proxy->surface != NULL, GST_VAAPI_ID_NONE); - return GST_VAAPI_OBJECT_ID(proxy->priv->surface); + return GST_VAAPI_OBJECT_ID(proxy->surface); } /** @@ -332,21 +285,17 @@ gst_vaapi_surface_proxy_set_surface( GstVaapiSurface *surface ) { - GstVaapiSurfaceProxyPrivate *priv; - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - priv = proxy->priv; - - if (priv->surface) { - if (priv->context) - gst_vaapi_context_put_surface(priv->context, priv->surface); - g_object_unref(priv->surface); - priv->surface = NULL; + if (proxy->surface) { + if (proxy->context) + gst_vaapi_context_put_surface(proxy->context, proxy->surface); + g_object_unref(proxy->surface); + proxy->surface = NULL; } if (surface) - priv->surface = g_object_ref(surface); + proxy->surface = g_object_ref(surface); } /** @@ -361,9 +310,10 @@ gst_vaapi_surface_proxy_set_surface( GstClockTime gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), GST_CLOCK_TIME_NONE); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), + GST_CLOCK_TIME_NONE); - return proxy->priv->timestamp; + return proxy->timestamp; } /** @@ -381,7 +331,7 @@ gst_vaapi_surface_proxy_set_timestamp( { g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - proxy->priv->timestamp = timestamp; + proxy->timestamp = timestamp; } /** @@ -399,7 +349,7 @@ gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy) g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), GST_CLOCK_TIME_NONE); - return proxy->priv->duration; + return proxy->duration; } /** @@ -417,7 +367,7 @@ gst_vaapi_surface_proxy_set_duration( { g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - proxy->priv->duration = duration; + proxy->duration = duration; } /** @@ -434,7 +384,7 @@ gst_vaapi_surface_proxy_get_interlaced(GstVaapiSurfaceProxy *proxy) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE); - return proxy->priv->is_interlaced; + return proxy->is_interlaced; } /** @@ -450,7 +400,7 @@ gst_vaapi_surface_proxy_set_interlaced(GstVaapiSurfaceProxy *proxy, gboolean b) { g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - proxy->priv->is_interlaced = b; + proxy->is_interlaced = b; } /** @@ -466,7 +416,7 @@ gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE); - return proxy->priv->is_interlaced && proxy->priv->tff; + return proxy->is_interlaced && proxy->tff; } /** @@ -481,5 +431,5 @@ gst_vaapi_surface_proxy_set_tff(GstVaapiSurfaceProxy *proxy, gboolean tff) { g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - proxy->priv->tff = tff; + proxy->tff = tff; } diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index ef333ba394..064c755003 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -23,35 +23,12 @@ #ifndef GST_VAAPI_SURFACE_PROXY_H #define GST_VAAPI_SURFACE_PROXY_H -#include #include #include G_BEGIN_DECLS -#define GST_VAAPI_TYPE_SURFACE_PROXY \ - (gst_vaapi_surface_proxy_get_type()) - -#define GST_VAAPI_SURFACE_PROXY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_SURFACE_PROXY, \ - GstVaapiSurfaceProxy)) - -#define GST_VAAPI_SURFACE_PROXY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_SURFACE_PROXY, \ - GstVaapiSurfaceProxyClass)) - -#define GST_VAAPI_IS_SURFACE_PROXY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SURFACE_PROXY)) - -#define GST_VAAPI_IS_SURFACE_PROXY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SURFACE_PROXY)) - -#define GST_VAAPI_SURFACE_PROXY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_SURFACE_PROXY, \ - GstVaapiSurfaceProxyClass)) +typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; /** * GST_VAAPI_SURFACE_PROXY_SURFACE: @@ -100,38 +77,26 @@ G_BEGIN_DECLS #define GST_VAAPI_SURFACE_PROXY_TFF(surface) \ gst_vaapi_surface_proxy_get_tff(surface) -typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; -typedef struct _GstVaapiSurfaceProxyPrivate GstVaapiSurfaceProxyPrivate; -typedef struct _GstVaapiSurfaceProxyClass GstVaapiSurfaceProxyClass; - -/** - * GstVaapiSurfaceProxy: - * - * A wrapper around a VA surface and context. - */ -struct _GstVaapiSurfaceProxy { - /*< private >*/ - GObject parent_instance; - - GstVaapiSurfaceProxyPrivate *priv; -}; - -/** - * GstVaapiSurfaceProxyClass: - * - * A wrapper around a VA surface and context. - */ -struct _GstVaapiSurfaceProxyClass { - /*< private >*/ - GObjectClass parent_class; -}; - -GType -gst_vaapi_surface_proxy_get_type(void) G_GNUC_CONST; - GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface); +GstVaapiSurfaceProxy * +gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy); + +void +gst_vaapi_surface_proxy_unref(GstVaapiSurfaceProxy *proxy); + +void +gst_vaapi_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr, + GstVaapiSurfaceProxy *new_proxy); + +gpointer +gst_vaapi_surface_proxy_get_user_data(GstVaapiSurfaceProxy *proxy); + +void +gst_vaapi_surface_proxy_set_user_data(GstVaapiSurfaceProxy *proxy, + gpointer user_data, GDestroyNotify destroy_notify); + GstVaapiContext * gst_vaapi_surface_proxy_get_context(GstVaapiSurfaceProxy *proxy); diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index cd1c948bc0..987b467d57 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -98,7 +98,7 @@ gst_vaapi_video_buffer_destroy_surface(GstVaapiVideoBuffer *buffer) { GstVaapiVideoBufferPrivate * const priv = buffer->priv; - g_clear_object(&priv->proxy); + gst_vaapi_surface_proxy_replace(&priv->proxy, NULL); if (priv->surface) { if (priv->surface_pool) @@ -353,7 +353,7 @@ gst_vaapi_video_buffer_typed_new_with_surface_proxy( { GstVaapiVideoBuffer *buffer; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); + g_return_val_if_fail(proxy != NULL, NULL); buffer = _gst_vaapi_video_buffer_typed_new(type); if (buffer) @@ -570,7 +570,7 @@ gst_vaapi_video_buffer_set_surface_proxy( GstVaapiSurface *surface; g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer)); - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + g_return_if_fail(proxy != NULL); gst_vaapi_video_buffer_destroy_surface(buffer); @@ -579,7 +579,7 @@ gst_vaapi_video_buffer_set_surface_proxy( if (!surface) return; set_surface(buffer, surface); - buffer->priv->proxy = g_object_ref(proxy); + buffer->priv->proxy = gst_vaapi_surface_proxy_ref(proxy); } } diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index e58a31b2ce..3eb6683b34 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -171,7 +171,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) } static void -gst_vaapidecode_release(GstVaapiDecode *decode, GObject *dead_object) +gst_vaapidecode_release(GstVaapiDecode *decode) { g_mutex_lock(&decode->decoder_mutex); g_cond_signal(&decode->decoder_ready); @@ -216,11 +216,8 @@ gst_vaapidecode_step(GstVaapiDecode *decode) break; } - g_object_weak_ref( - G_OBJECT(proxy), - (GWeakNotify)gst_vaapidecode_release, - decode - ); + gst_vaapi_surface_proxy_set_user_data(proxy, + decode, (GDestroyNotify)gst_vaapidecode_release); buffer = gst_vaapi_video_buffer_new(decode->display); if (!buffer) @@ -247,7 +244,7 @@ gst_vaapidecode_step(GstVaapiDecode *decode) if (ret != GST_FLOW_OK) goto error_commit_buffer; - g_object_unref(proxy); + gst_vaapi_surface_proxy_unref(proxy); } return GST_FLOW_OK; @@ -281,13 +278,13 @@ error_create_buffer: GST_DEBUG("video sink failed to create video buffer for proxy'ed " "surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); - g_object_unref(proxy); + gst_vaapi_surface_proxy_unref(proxy); return GST_FLOW_UNEXPECTED; } error_commit_buffer: { GST_DEBUG("video sink rejected the video buffer (error %d)", ret); - g_object_unref(proxy); + gst_vaapi_surface_proxy_unref(proxy); return GST_FLOW_UNEXPECTED; } } @@ -366,7 +363,7 @@ gst_vaapidecode_destroy(GstVaapiDecode *decode) decode->decoder_caps = NULL; } - gst_vaapidecode_release(decode, NULL); + gst_vaapidecode_release(decode); } static gboolean diff --git a/gst/vaapi/gstvaapipluginbuffer.c b/gst/vaapi/gstvaapipluginbuffer.c index 33cb9176c3..9d6859dc31 100644 --- a/gst/vaapi/gstvaapipluginbuffer.c +++ b/gst/vaapi/gstvaapipluginbuffer.c @@ -122,7 +122,7 @@ gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) GstVaapiDisplay *display; GstVaapiSurface *surface; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); + g_return_val_if_fail(proxy != NULL, NULL); surface = gst_vaapi_surface_proxy_get_surface(proxy); if (!surface) diff --git a/tests/test-decode.c b/tests/test-decode.c index 458416e623..b8c7e75b24 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -194,7 +194,7 @@ main(int argc, char *argv[]) pause(); - g_object_unref(proxy); + gst_vaapi_surface_proxy_unref(proxy); g_object_unref(decoder); g_object_unref(window); g_object_unref(display); diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 7a65fe34c7..913d183160 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -219,7 +219,7 @@ main(int argc, char *argv[]) pause(); gst_buffer_unref(buffer); - g_object_unref(proxy); + gst_vaapi_surface_proxy_unref(proxy); g_object_unref(decoder); g_object_unref(window); g_object_unref(display); From f88374d6422ce6d8afbfd4ca2c389fc59da7e910 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 3 Dec 2012 11:19:08 +0100 Subject: [PATCH 0922/3781] Port codec objects to GstVaapiMiniObject. --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 161 ++++-------- gst-libs/gst/vaapi/gstvaapicodec_objects.h | 257 +++---------------- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 107 ++------ gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 117 +++------ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 102 ++------ 5 files changed, 188 insertions(+), 556 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index e79341d001..450e50eb8f 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -35,98 +35,69 @@ /* --- Base Codec Object --- */ /* ------------------------------------------------------------------------- */ -G_DEFINE_TYPE(GstVaapiCodecObject, gst_vaapi_codec_object, GST_TYPE_MINI_OBJECT) +#define GST_VAAPI_CODEC_OBJECT_GET_CLASS(object) \ + gst_vaapi_codec_object_get_class(object) -static void -gst_vaapi_codec_object_finalize(GstMiniObject *object) +const GstVaapiCodecObjectClass * +gst_vaapi_codec_object_get_class(GstVaapiCodecObject *object) { - GstVaapiCodecObject * const obj = GST_VAAPI_CODEC_OBJECT(object); - - obj->codec = NULL; -} - -static void -gst_vaapi_codec_object_init(GstVaapiCodecObject *obj) -{ - obj->codec = NULL; + return (const GstVaapiCodecObjectClass *) + gst_vaapi_mini_object_get_class(GST_VAAPI_MINI_OBJECT(object)); } static gboolean -gst_vaapi_codec_object_create( - GstVaapiCodecObject *obj, - const GstVaapiCodecObjectConstructorArgs *args -) +gst_vaapi_codec_object_create(GstVaapiCodecObject *object, + const GstVaapiCodecObjectConstructorArgs *args) { - obj->codec = args->codec; + 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; } -static void -gst_vaapi_codec_object_class_init(GstVaapiCodecObjectClass *klass) -{ - GstMiniObjectClass * const object_class = GST_MINI_OBJECT_CLASS(klass); - - object_class->finalize = gst_vaapi_codec_object_finalize; - klass->construct = gst_vaapi_codec_object_create; -} - GstVaapiCodecObject * -gst_vaapi_codec_object_new( - GType type, - GstVaapiCodecBase *codec, - gconstpointer param, - guint param_size, - gconstpointer data, - guint data_size -) +gst_vaapi_codec_object_new(const GstVaapiCodecObjectClass *object_class, + GstVaapiCodecBase *codec, gconstpointer param, guint param_size, + gconstpointer data, guint data_size, guint flags) { - GstMiniObject *obj; + GstVaapiMiniObject *obj; GstVaapiCodecObject *va_obj; GstVaapiCodecObjectConstructorArgs args; - obj = gst_mini_object_new(type); + g_return_val_if_fail(codec != NULL, NULL); + + obj = gst_vaapi_mini_object_new0(&object_class->parent_class); if (!obj) return NULL; va_obj = GST_VAAPI_CODEC_OBJECT(obj); - args.codec = codec; + va_obj->codec = codec; + args.param = param; args.param_size = param_size; args.data = data; args.data_size = data_size; - args.flags = 0; - if (gst_vaapi_codec_object_construct(va_obj, &args)) + args.flags = flags; + + if (gst_vaapi_codec_object_create(va_obj, &args)) return va_obj; - gst_mini_object_unref(obj); + gst_vaapi_mini_object_unref(obj); return NULL; } -gboolean -gst_vaapi_codec_object_construct( - GstVaapiCodecObject *obj, - const GstVaapiCodecObjectConstructorArgs *args -) -{ - GstVaapiCodecObjectClass *klass; - - g_return_val_if_fail(GST_VAAPI_CODEC_OBJECT(obj), FALSE); - g_return_val_if_fail(args->codec != NULL, FALSE); - g_return_val_if_fail(args->param_size > 0, FALSE); - - if (GST_MINI_OBJECT_FLAG_IS_SET(obj, GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED)) - return TRUE; - - klass = GST_VAAPI_CODEC_OBJECT_GET_CLASS(obj); - if (!klass || !klass->construct || !klass->construct(obj, args)) - return FALSE; - - GST_MINI_OBJECT_FLAG_SET(obj, GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED); - return TRUE; -} - #define GET_DECODER(obj) GST_VAAPI_DECODER_CAST((obj)->parent_instance.codec) -#define GET_CONTEXT(obj) GET_DECODER(obj)->priv->context #define GET_VA_DISPLAY(obj) GET_DECODER(obj)->priv->va_display #define GET_VA_CONTEXT(obj) GET_DECODER(obj)->priv->va_context @@ -134,23 +105,22 @@ gst_vaapi_codec_object_construct( /* --- Inverse Quantization Matrices --- */ /* ------------------------------------------------------------------------- */ -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiIqMatrix, - gst_vaapi_iq_matrix, - GST_VAAPI_TYPE_CODEC_OBJECT) +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiIqMatrix, gst_vaapi_iq_matrix); -static void +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; } -static gboolean +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, @@ -160,13 +130,6 @@ gst_vaapi_iq_matrix_create( &iq_matrix->param); } -static void -gst_vaapi_iq_matrix_init(GstVaapiIqMatrix *iq_matrix) -{ - iq_matrix->param = NULL; - iq_matrix->param_id = VA_INVALID_ID; -} - GstVaapiIqMatrix * gst_vaapi_iq_matrix_new( GstVaapiDecoder *decoder, @@ -179,10 +142,11 @@ gst_vaapi_iq_matrix_new( g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); object = gst_vaapi_codec_object_new( - GST_VAAPI_TYPE_IQ_MATRIX, + &GstVaapiIqMatrixClass, GST_VAAPI_CODEC_BASE(decoder), param, param_size, - NULL, 0 + NULL, 0, + 0 ); if (!object) return NULL; @@ -193,23 +157,22 @@ gst_vaapi_iq_matrix_new( /* --- VC-1 Bit Planes --- */ /* ------------------------------------------------------------------------- */ -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiBitPlane, - gst_vaapi_bitplane, - GST_VAAPI_TYPE_CODEC_OBJECT) +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiBitPlane, gst_vaapi_bitplane); -static void +void gst_vaapi_bitplane_destroy(GstVaapiBitPlane *bitplane) { vaapi_destroy_buffer(GET_VA_DISPLAY(bitplane), &bitplane->data_id); bitplane->data = NULL; } -static gboolean +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, @@ -219,12 +182,6 @@ gst_vaapi_bitplane_create( (void **)&bitplane->data); } -static void -gst_vaapi_bitplane_init(GstVaapiBitPlane *bitplane) -{ - bitplane->data = NULL; - bitplane->data_id = VA_INVALID_ID; -} GstVaapiBitPlane * gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size) @@ -234,10 +191,11 @@ gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size) g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); object = gst_vaapi_codec_object_new( - GST_VAAPI_TYPE_BITPLANE, + &GstVaapiBitPlaneClass, GST_VAAPI_CODEC_BASE(decoder), data, data_size, - NULL, 0 + NULL, 0, + 0 ); if (!object) return NULL; @@ -249,23 +207,22 @@ gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size) /* ------------------------------------------------------------------------- */ #if USE_JPEG_DECODER -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiHuffmanTable, - gst_vaapi_huffman_table, - GST_VAAPI_TYPE_CODEC_OBJECT) +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiHuffmanTable, gst_vaapi_huffman_table); -static void +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; } -static gboolean +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, @@ -275,13 +232,6 @@ gst_vaapi_huffman_table_create( (void **)&huf_table->param); } -static void -gst_vaapi_huffman_table_init(GstVaapiHuffmanTable *huf_table) -{ - huf_table->param = NULL; - huf_table->param_id = VA_INVALID_ID; -} - GstVaapiHuffmanTable * gst_vaapi_huffman_table_new( GstVaapiDecoder *decoder, @@ -294,10 +244,11 @@ gst_vaapi_huffman_table_new( g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); object = gst_vaapi_codec_object_new( - GST_VAAPI_TYPE_HUFFMAN_TABLE, + &GstVaapiHuffmanTableClass, GST_VAAPI_CODEC_BASE(decoder), data, data_size, - NULL, 0 + NULL, 0, + 0 ); if (!object) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index a064c1595a..b6dc8aab08 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -23,7 +23,7 @@ #ifndef GST_VAAPI_CODEC_COMMON_H #define GST_VAAPI_CODEC_COMMON_H -#include +#include #include G_BEGIN_DECLS @@ -32,11 +32,8 @@ typedef gpointer GstVaapiCodecBase; typedef struct _GstVaapiCodecObject GstVaapiCodecObject; typedef struct _GstVaapiCodecObjectClass GstVaapiCodecObjectClass; typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix; -typedef struct _GstVaapiIqMatrixClass GstVaapiIqMatrixClass; typedef struct _GstVaapiBitPlane GstVaapiBitPlane; -typedef struct _GstVaapiBitPlaneClass GstVaapiBitPlaneClass; typedef struct _GstVaapiHuffmanTable GstVaapiHuffmanTable; -typedef struct _GstVaapiHuffmanTableClass GstVaapiHuffmanTableClass; /* ------------------------------------------------------------------------- */ /* --- Base Codec Object --- */ @@ -46,38 +43,15 @@ typedef struct _GstVaapiHuffmanTableClass GstVaapiHuffmanTableClass; #define GST_VAAPI_CODEC_BASE(obj) \ ((GstVaapiCodecBase *)(obj)) -#define GST_VAAPI_TYPE_CODEC_OBJECT \ - (gst_vaapi_codec_object_get_type()) - -#define GST_VAAPI_CODEC_OBJECT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_CODEC_OBJECT, \ - GstVaapiCodecObject)) - -#define GST_VAAPI_CODEC_OBJECT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_CODEC_OBJECT, \ - GstVaapiCodecObjectClass)) - -#define GST_VAAPI_IS_CODEC_OBJECT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_CODEC_OBJECT)) - -#define GST_VAAPI_IS_CODEC_OBJECT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_CODEC_OBJECT)) - -#define GST_VAAPI_CODEC_OBJECT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_CODEC_OBJECT, \ - GstVaapiCodecObjectClass)) +#define GST_VAAPI_CODEC_OBJECT(obj) \ + ((GstVaapiCodecObject *)(obj)) enum { - GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED = (GST_MINI_OBJECT_FLAG_LAST << 0), - GST_VAAPI_CODEC_OBJECT_FLAG_LAST = (GST_MINI_OBJECT_FLAG_LAST << 1) + GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED = (1 << 0), + GST_VAAPI_CODEC_OBJECT_FLAG_LAST = (1 << 1) }; typedef struct { - GstVaapiCodecObject *obj; - GstVaapiCodecBase *codec; gconstpointer param; guint param_size; gconstpointer data; @@ -85,14 +59,20 @@ typedef struct { guint flags; } GstVaapiCodecObjectConstructorArgs; +typedef gboolean +(*GstVaapiCodecObjectCreateFunc)(GstVaapiCodecObject *object, + const GstVaapiCodecObjectConstructorArgs *args); + +typedef GDestroyNotify GstVaapiCodecObjectDestroyFunc; + /** * GstVaapiCodecObject: * - * A #GstMiniObject holding the base codec object data + * A #GstVaapiMiniObject holding the base codec object data */ struct _GstVaapiCodecObject { /*< private >*/ - GstMiniObject parent_instance; + GstVaapiMiniObject parent_instance; GstVaapiCodecBase *codec; }; @@ -103,65 +83,28 @@ struct _GstVaapiCodecObject { */ struct _GstVaapiCodecObjectClass { /*< private >*/ - GstMiniObjectClass parent_class; + GstVaapiMiniObjectClass parent_class; - gboolean (*construct) (GstVaapiCodecObject *obj, - const GstVaapiCodecObjectConstructorArgs *args); + GstVaapiCodecObjectCreateFunc create; }; G_GNUC_INTERNAL -GType -gst_vaapi_codec_object_get_type(void) G_GNUC_CONST; +const GstVaapiCodecObjectClass * +gst_vaapi_codec_object_get_class(GstVaapiCodecObject *object) G_GNUC_CONST; G_GNUC_INTERNAL GstVaapiCodecObject * -gst_vaapi_codec_object_new( - GType type, - GstVaapiCodecBase *codec, - gconstpointer param, - guint param_size, - gconstpointer data, - guint data_size -); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_codec_object_construct( - GstVaapiCodecObject *obj, - const GstVaapiCodecObjectConstructorArgs *args -); +gst_vaapi_codec_object_new(const GstVaapiCodecObjectClass *object_class, + GstVaapiCodecBase *codec, gconstpointer param, guint param_size, + gconstpointer data, guint data_size, guint flags); /* ------------------------------------------------------------------------- */ /* --- Inverse Quantization Matrices --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_TYPE_IQ_MATRIX \ - (gst_vaapi_iq_matrix_get_type()) - #define GST_VAAPI_IQ_MATRIX_CAST(obj) \ ((GstVaapiIqMatrix *)(obj)) -#define GST_VAAPI_IQ_MATRIX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_IQ_MATRIX, \ - GstVaapiIqMatrix)) - -#define GST_VAAPI_IQ_MATRIX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_IQ_MATRIX, \ - GstVaapiIqMatrixClass)) - -#define GST_VAAPI_IS_IQ_MATRIX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_IQ_MATRIX)) - -#define GST_VAAPI_IS_IQ_MATRIX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_IQ_MATRIX)) - -#define GST_VAAPI_IQ_MATRIX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_IQ_MATRIX, \ - GstVaapiIqMatrixClass)) - /** * GstVaapiIqMatrix: * @@ -176,20 +119,6 @@ struct _GstVaapiIqMatrix { gpointer param; }; -/** - * GstVaapiIqMatrixClass: - * - * The #GstVaapiIqMatrix base class. - */ -struct _GstVaapiIqMatrixClass { - /*< private >*/ - GstVaapiCodecObjectClass parent_class; -}; - -G_GNUC_INTERNAL -GType -gst_vaapi_iq_matrix_get_type(void) G_GNUC_CONST; - G_GNUC_INTERNAL GstVaapiIqMatrix * gst_vaapi_iq_matrix_new( @@ -202,33 +131,9 @@ gst_vaapi_iq_matrix_new( /* --- VC-1 Bit Planes --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_TYPE_BITPLANE \ - (gst_vaapi_bitplane_get_type()) - #define GST_VAAPI_BITPLANE_CAST(obj) \ ((GstVaapiBitPlane *)(obj)) -#define GST_VAAPI_BITPLANE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_BITPLANE, \ - GstVaapiBitPlane)) - -#define GST_VAAPI_BITPLANE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_BITPLANE, \ - GstVaapiBitPlaneClass)) - -#define GST_VAAPI_IS_BITPLANE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_BITPLANE)) - -#define GST_VAAPI_IS_BITPLANE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_BITPLANE)) - -#define GST_VAAPI_BITPLANE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_BITPLANE, \ - GstVaapiBitPlaneClass)) - /** * GstVaapiBitPlane: * @@ -243,20 +148,6 @@ struct _GstVaapiBitPlane { guint8 *data; }; -/** - * GstVaapiBitPlaneClass: - * - * The #GstVaapiBitPlane base class. - */ -struct _GstVaapiBitPlaneClass { - /*< private >*/ - GstVaapiCodecObjectClass parent_class; -}; - -G_GNUC_INTERNAL -GType -gst_vaapi_bitplane_get_type(void) G_GNUC_CONST; - G_GNUC_INTERNAL GstVaapiBitPlane * gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size); @@ -265,33 +156,9 @@ gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size); /* --- JPEG Huffman Tables --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_TYPE_HUFFMAN_TABLE \ - (gst_vaapi_huffman_table_get_type()) - #define GST_VAAPI_HUFFMAN_TABLE_CAST(obj) \ ((GstVaapiHuffmanTable *)(obj)) -#define GST_VAAPI_HUFFMAN_TABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_HUFFMAN_TABLE, \ - GstVaapiHuffmanTable)) - -#define GST_VAAPI_HUFFMAN_TABLE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_HUFFMAN_TABLE, \ - GstVaapiHuffmanTableClass)) - -#define GST_VAAPI_IS_HUFFMAN_TABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_HUFFMAN_TABLE)) - -#define GST_VAAPI_IS_HUFFMAN_TABLE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_HUFFMAN_TABLE)) - -#define GST_VAAPI_HUFFMAN_TABLE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_HUFFMAN_TABLE, \ - GstVaapiHuffmanTableClass)) - /** * GstVaapiHuffmanTable: * @@ -306,20 +173,6 @@ struct _GstVaapiHuffmanTable { gpointer param; }; -/** - * GstVaapiHuffmanTableClass: - * - * The #GstVaapiHuffmanTable base class. - */ -struct _GstVaapiHuffmanTableClass { - /*< private >*/ - GstVaapiCodecObjectClass parent_class; -}; - -G_GNUC_INTERNAL -GType -gst_vaapi_huffman_table_get_type(void) G_GNUC_CONST; - G_GNUC_INTERNAL GstVaapiHuffmanTable * gst_vaapi_huffman_table_new( @@ -332,56 +185,26 @@ gst_vaapi_huffman_table_new( /* --- Helpers to create codec-dependent objects --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_CODEC_DEFINE_TYPE(type, prefix, base_type) \ -G_DEFINE_TYPE(type, prefix, base_type) \ - \ -static void \ -prefix##_destroy(type *); \ - \ -static gboolean \ -prefix##_create( \ - type *, \ - const GstVaapiCodecObjectConstructorArgs *args \ -); \ - \ -static void \ -prefix##_finalize(GstMiniObject *object) \ -{ \ - GstMiniObjectClass *parent_class; \ - \ - prefix##_destroy((type *)object); \ - \ - parent_class = GST_MINI_OBJECT_CLASS(prefix##_parent_class); \ - if (parent_class->finalize) \ - parent_class->finalize(object); \ -} \ - \ -static gboolean \ -prefix##_construct( \ - GstVaapiCodecObject *object, \ - const GstVaapiCodecObjectConstructorArgs *args \ -) \ -{ \ - GstVaapiCodecObjectClass *parent_class; \ - \ - parent_class = GST_VAAPI_CODEC_OBJECT_CLASS(prefix##_parent_class); \ - if (parent_class->construct) { \ - if (!parent_class->construct(object, args)) \ - return FALSE; \ - } \ - return prefix##_create((type *)object, args); \ -} \ - \ -static void \ -prefix##_class_init(type##Class *klass) \ -{ \ - GstMiniObjectClass * const object_class = \ - GST_MINI_OBJECT_CLASS(klass); \ - GstVaapiCodecObjectClass * const codec_class = \ - GST_VAAPI_CODEC_OBJECT_CLASS(klass); \ - \ - object_class->finalize = prefix##_finalize; \ - codec_class->construct = prefix##_construct; \ +#define GST_VAAPI_CODEC_DEFINE_TYPE(type, prefix) \ +G_GNUC_INTERNAL \ +void \ +prefix##_destroy(type *); \ + \ +G_GNUC_INTERNAL \ +gboolean \ +prefix##_create( \ + type *, \ + const GstVaapiCodecObjectConstructorArgs *args \ +); \ + \ +static const GstVaapiCodecObjectClass type##Class = { \ + .parent_class = { \ + .size = sizeof(type), \ + .finalize = (GstVaapiCodecObjectDestroyFunc) \ + prefix##_destroy \ + }, \ + .create = (GstVaapiCodecObjectCreateFunc) \ + prefix##_create, \ } #define GST_VAAPI_IQ_MATRIX_NEW(codec, decoder) \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 3f8bb84419..db2e03c00c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -43,9 +43,7 @@ typedef struct _GstVaapiFrameStore GstVaapiFrameStore; typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; -typedef struct _GstVaapiPictureH264Class GstVaapiPictureH264Class; typedef struct _GstVaapiSliceH264 GstVaapiSliceH264; -typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class; // Used for field_poc[] #define TOP_FIELD 0 @@ -55,32 +53,14 @@ typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class; /* --- H.264 Pictures --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_TYPE_PICTURE_H264 \ - (gst_vaapi_picture_h264_get_type()) - #define GST_VAAPI_PICTURE_H264_CAST(obj) \ ((GstVaapiPictureH264 *)(obj)) -#define GST_VAAPI_PICTURE_H264(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_PICTURE_H264, \ - GstVaapiPictureH264)) - -#define GST_VAAPI_PICTURE_H264_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_PICTURE_H264, \ - GstVaapiPictureH264Class)) +#define GST_VAAPI_PICTURE_H264(obj) \ + GST_VAAPI_PICTURE_H264_CAST(obj) #define GST_VAAPI_IS_PICTURE_H264(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_PICTURE_H264)) - -#define GST_VAAPI_IS_PICTURE_H264_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_PICTURE_H264)) - -#define GST_VAAPI_PICTURE_H264_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_PICTURE_H264, \ - GstVaapiPictureH264Class)) + (GST_VAAPI_PICTURE_H264(obj) != NULL) /* * Extended picture flags: @@ -133,35 +113,27 @@ struct _GstVaapiPictureH264 { guint output_needed : 1; }; -struct _GstVaapiPictureH264Class { - /*< private >*/ - GstVaapiPictureClass parent_class; -}; +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264, gst_vaapi_picture_h264); -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264, - gst_vaapi_picture_h264, - GST_VAAPI_TYPE_PICTURE) - -static void -gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *decoder) +void +gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *picture) { + gst_vaapi_picture_destroy(GST_VAAPI_PICTURE(picture)); } -static gboolean +gboolean gst_vaapi_picture_h264_create( GstVaapiPictureH264 *picture, const GstVaapiCodecObjectConstructorArgs *args ) { - return TRUE; -} + if (!gst_vaapi_picture_create(GST_VAAPI_PICTURE(picture), args)) + return FALSE; -static void -gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture) -{ picture->field_poc[0] = G_MAXINT32; picture->field_poc[1] = G_MAXINT32; picture->output_needed = FALSE; + return TRUE; } static inline GstVaapiPictureH264 * @@ -172,10 +144,11 @@ gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder) g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); object = gst_vaapi_codec_object_new( - GST_VAAPI_TYPE_PICTURE_H264, + &GstVaapiPictureH264Class, GST_VAAPI_CODEC_BASE(decoder), NULL, sizeof(VAPictureParameterBufferH264), - NULL, 0 + NULL, 0, + 0 ); if (!object) return NULL; @@ -228,66 +201,39 @@ gst_vaapi_picture_h264_get_last_slice(GstVaapiPictureH264 *picture) /* --- Slices --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_TYPE_SLICE_H264 \ - (gst_vaapi_slice_h264_get_type()) - #define GST_VAAPI_SLICE_H264_CAST(obj) \ ((GstVaapiSliceH264 *)(obj)) -#define GST_VAAPI_SLICE_H264(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_SLICE_H264, \ - GstVaapiSliceH264)) - -#define GST_VAAPI_SLICE_H264_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_SLICE_H264, \ - GstVaapiSliceH264Class)) +#define GST_VAAPI_SLICE_H264(obj) \ + GST_VAAPI_SLICE_H264(obj) #define GST_VAAPI_IS_SLICE_H264(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SLICE_H264)) - -#define GST_VAAPI_IS_SLICE_H264_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SLICE_H264)) - -#define GST_VAAPI_SLICE_H264_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_SLICE_H264, \ - GstVaapiSliceH264Class)) + (GST_VAAPI_SLICE_H264(obj) != NULL) struct _GstVaapiSliceH264 { GstVaapiSlice base; GstH264SliceHdr slice_hdr; // parsed slice_header() }; -struct _GstVaapiSliceH264Class { - /*< private >*/ - GstVaapiSliceClass parent_class; -}; +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSliceH264, gst_vaapi_slice_h264); -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSliceH264, - gst_vaapi_slice_h264, - GST_VAAPI_TYPE_SLICE) - -static void +void gst_vaapi_slice_h264_destroy(GstVaapiSliceH264 *slice) { + gst_vaapi_slice_destroy(GST_VAAPI_SLICE(slice)); } -static gboolean +gboolean gst_vaapi_slice_h264_create( GstVaapiSliceH264 *slice, const GstVaapiCodecObjectConstructorArgs *args ) { + if (!gst_vaapi_slice_create(GST_VAAPI_SLICE(slice), args)) + return FALSE; return TRUE; } -static void -gst_vaapi_slice_h264_init(GstVaapiSliceH264 *slice) -{ -} - static inline GstVaapiSliceH264 * gst_vaapi_slice_h264_new( GstVaapiDecoderH264 *decoder, @@ -300,10 +246,11 @@ gst_vaapi_slice_h264_new( g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); object = gst_vaapi_codec_object_new( - GST_VAAPI_TYPE_SLICE_H264, + &GstVaapiSliceH264Class, GST_VAAPI_CODEC_BASE(decoder), NULL, sizeof(VASliceParameterBufferH264), - data, data_size + data, data_size, + 0 ); if (!object) return NULL; @@ -2927,7 +2874,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) error: if (slice) - gst_mini_object_unref(GST_MINI_OBJECT(slice)); + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(slice)); return status; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 35f823ca87..165ac79128 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -40,9 +40,7 @@ /* --- Pictures --- */ /* ------------------------------------------------------------------------- */ -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPicture, - gst_vaapi_picture, - GST_VAAPI_TYPE_CODEC_OBJECT) +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPicture, gst_vaapi_picture); enum { GST_VAAPI_CREATE_PICTURE_FLAG_CLONE = 1 << 0, @@ -52,12 +50,12 @@ enum { static void destroy_slice_cb(gpointer data, gpointer user_data) { - GstMiniObject * const object = data; + GstVaapiMiniObject * const object = data; - gst_mini_object_unref(object); + gst_vaapi_mini_object_unref(object); } -static void +void gst_vaapi_picture_destroy(GstVaapiPicture *picture) { if (picture->slices) { @@ -66,20 +64,12 @@ gst_vaapi_picture_destroy(GstVaapiPicture *picture) picture->slices = NULL; } - if (picture->iq_matrix) { - gst_mini_object_unref(GST_MINI_OBJECT(picture->iq_matrix)); - picture->iq_matrix = NULL; - } - - if (picture->huf_table) { - gst_mini_object_unref(GST_MINI_OBJECT(picture->huf_table)); - picture->huf_table = NULL; - } - - if (picture->bitplane) { - gst_mini_object_unref(GST_MINI_OBJECT(picture->bitplane)); - picture->bitplane = NULL; - } + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)&picture->iq_matrix, + NULL); + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)&picture->huf_table, + NULL); + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)&picture->bitplane, + NULL); if (picture->proxy) { gst_vaapi_surface_proxy_unref(picture->proxy); @@ -96,7 +86,7 @@ gst_vaapi_picture_destroy(GstVaapiPicture *picture) picture->param = NULL; } -static gboolean +gboolean gst_vaapi_picture_create( GstVaapiPicture *picture, const GstVaapiCodecObjectConstructorArgs *args @@ -139,6 +129,9 @@ gst_vaapi_picture_create( } } else { + picture->type = GST_VAAPI_PICTURE_TYPE_NONE; + picture->pts = GST_CLOCK_TIME_NONE; + picture->surface = gst_vaapi_context_get_surface(GET_CONTEXT(picture)); if (!picture->surface) return FALSE; @@ -153,6 +146,7 @@ gst_vaapi_picture_create( } picture->surface_id = gst_vaapi_surface_get_id(picture->surface); + picture->param_id = VA_INVALID_ID; success = vaapi_create_buffer( GET_VA_DISPLAY(picture), GET_VA_CONTEXT(picture), @@ -172,24 +166,6 @@ gst_vaapi_picture_create( return TRUE; } -static void -gst_vaapi_picture_init(GstVaapiPicture *picture) -{ - picture->type = GST_VAAPI_PICTURE_TYPE_NONE; - picture->surface = NULL; - picture->proxy = NULL; - picture->surface_id = VA_INVALID_ID; - picture->param = NULL; - picture->param_id = VA_INVALID_ID; - picture->param_size = 0; - picture->slices = NULL; - picture->iq_matrix = NULL; - picture->huf_table = NULL; - picture->bitplane = NULL; - picture->pts = GST_CLOCK_TIME_NONE; - picture->poc = 0; -} - GstVaapiPicture * gst_vaapi_picture_new( GstVaapiDecoder *decoder, @@ -202,10 +178,11 @@ gst_vaapi_picture_new( g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); object = gst_vaapi_codec_object_new( - GST_VAAPI_TYPE_PICTURE, + &GstVaapiPictureClass, GST_VAAPI_CODEC_BASE(decoder), param, param_size, - NULL, 0 + NULL, 0, + 0 ); if (!object) return NULL; @@ -215,31 +192,20 @@ gst_vaapi_picture_new( GstVaapiPicture * gst_vaapi_picture_new_field(GstVaapiPicture *picture) { - GType type; - GstMiniObject *obj; - GstVaapiCodecObject *va_obj; - GstVaapiCodecObjectConstructorArgs args; + GstVaapiDecoder * const decoder = GET_DECODER(picture); + GstVaapiCodecObject *object; - g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), NULL); - - type = G_TYPE_FROM_CLASS(GST_VAAPI_PICTURE_GET_CLASS(picture)); - obj = gst_mini_object_new(type); - if (!obj) + 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; - - va_obj = GST_VAAPI_CODEC_OBJECT(obj); - args.codec = GST_VAAPI_CODEC_BASE(GET_DECODER(picture)); - args.param = NULL; - args.param_size = picture->param_size; - args.data = picture; - args.data_size = 0; - args.flags = (GST_VAAPI_CREATE_PICTURE_FLAG_CLONE| - GST_VAAPI_CREATE_PICTURE_FLAG_FIELD); - if (gst_vaapi_codec_object_construct(va_obj, &args)) - return GST_VAAPI_PICTURE_CAST(va_obj); - - gst_mini_object_unref(obj); - return NULL; + return GST_VAAPI_PICTURE_CAST(object); } void @@ -357,11 +323,9 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) /* --- Slices --- */ /* ------------------------------------------------------------------------- */ -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSlice, - gst_vaapi_slice, - GST_VAAPI_TYPE_CODEC_OBJECT) +GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSlice, gst_vaapi_slice); -static void +void gst_vaapi_slice_destroy(GstVaapiSlice *slice) { VADisplay const va_display = GET_VA_DISPLAY(slice); @@ -371,7 +335,7 @@ gst_vaapi_slice_destroy(GstVaapiSlice *slice) slice->param = NULL; } -static gboolean +gboolean gst_vaapi_slice_create( GstVaapiSlice *slice, const GstVaapiCodecObjectConstructorArgs *args @@ -380,6 +344,7 @@ gst_vaapi_slice_create( VASliceParameterBufferBase *slice_param; gboolean success; + slice->data_id = VA_INVALID_ID; success = vaapi_create_buffer( GET_VA_DISPLAY(slice), GET_VA_CONTEXT(slice), @@ -392,6 +357,7 @@ gst_vaapi_slice_create( if (!success) return FALSE; + slice->param_id = VA_INVALID_ID; success = vaapi_create_buffer( GET_VA_DISPLAY(slice), GET_VA_CONTEXT(slice), @@ -411,14 +377,6 @@ gst_vaapi_slice_create( return TRUE; } -static void -gst_vaapi_slice_init(GstVaapiSlice *slice) -{ - slice->param = NULL; - slice->param_id = VA_INVALID_ID; - slice->data_id = VA_INVALID_ID; -} - GstVaapiSlice * gst_vaapi_slice_new( GstVaapiDecoder *decoder, @@ -433,10 +391,11 @@ gst_vaapi_slice_new( g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); object = gst_vaapi_codec_object_new( - GST_VAAPI_TYPE_SLICE, + &GstVaapiSliceClass, GST_VAAPI_CODEC_BASE(decoder), param, param_size, - data, data_size + data, data_size, + 0 ); return GST_VAAPI_SLICE_CAST(object); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index b95f4e00ef..beea9acec0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -28,40 +28,20 @@ G_BEGIN_DECLS typedef struct _GstVaapiPicture GstVaapiPicture; -typedef struct _GstVaapiPictureClass GstVaapiPictureClass; typedef struct _GstVaapiSlice GstVaapiSlice; -typedef struct _GstVaapiSliceClass GstVaapiSliceClass; /* ------------------------------------------------------------------------- */ /* --- Pictures --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_TYPE_PICTURE \ - (gst_vaapi_picture_get_type()) - #define GST_VAAPI_PICTURE_CAST(obj) \ ((GstVaapiPicture *)(obj)) -#define GST_VAAPI_PICTURE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_PICTURE, \ - GstVaapiPicture)) - -#define GST_VAAPI_PICTURE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_PICTURE, \ - GstVaapiPictureClass)) +#define GST_VAAPI_PICTURE(obj) \ + GST_VAAPI_PICTURE_CAST(obj) #define GST_VAAPI_IS_PICTURE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_PICTURE)) - -#define GST_VAAPI_IS_PICTURE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_PICTURE)) - -#define GST_VAAPI_PICTURE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_PICTURE, \ - GstVaapiPictureClass)) + (GST_VAAPI_PICTURE(obj) != NULL) typedef enum { GST_VAAPI_PICTURE_TYPE_NONE = 0, // Undefined @@ -96,10 +76,10 @@ enum { GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 6), }; -#define GST_VAAPI_PICTURE_FLAGS GST_MINI_OBJECT_FLAGS -#define GST_VAAPI_PICTURE_FLAG_IS_SET GST_MINI_OBJECT_FLAG_IS_SET -#define GST_VAAPI_PICTURE_FLAG_SET GST_MINI_OBJECT_FLAG_SET -#define GST_VAAPI_PICTURE_FLAG_UNSET GST_MINI_OBJECT_FLAG_UNSET +#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) @@ -152,19 +132,14 @@ struct _GstVaapiPicture { guint structure; }; -/** - * GstVaapiPictureClass: - * - * The #GstVaapiPicture base class. - */ -struct _GstVaapiPictureClass { - /*< private >*/ - GstVaapiCodecObjectClass parent_class; -}; +G_GNUC_INTERNAL +void +gst_vaapi_picture_destroy(GstVaapiPicture *picture); G_GNUC_INTERNAL -GType -gst_vaapi_picture_get_type(void) G_GNUC_CONST; +gboolean +gst_vaapi_picture_create(GstVaapiPicture *picture, + const GstVaapiCodecObjectConstructorArgs *args); G_GNUC_INTERNAL GstVaapiPicture * @@ -193,49 +168,31 @@ gst_vaapi_picture_output(GstVaapiPicture *picture); static inline gpointer gst_vaapi_picture_ref(gpointer ptr) { - return gst_mini_object_ref(GST_MINI_OBJECT(ptr)); + return gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(ptr)); } static inline void gst_vaapi_picture_unref(gpointer ptr) { - gst_mini_object_unref(GST_MINI_OBJECT(ptr)); + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(ptr)); } -#define gst_vaapi_picture_replace(old_picture_p, new_picture) \ - gst_mini_object_replace((GstMiniObject **)(old_picture_p), \ - (GstMiniObject *)(new_picture)) +#define gst_vaapi_picture_replace(old_picture_p, new_picture) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_picture_p), \ + (GstVaapiMiniObject *)(new_picture)) /* ------------------------------------------------------------------------- */ /* --- Slices --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_TYPE_SLICE \ - (gst_vaapi_slice_get_type()) - #define GST_VAAPI_SLICE_CAST(obj) \ ((GstVaapiSlice *)(obj)) -#define GST_VAAPI_SLICE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_SLICE, \ - GstVaapiSlice)) - -#define GST_VAAPI_SLICE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_SLICE, \ - GstVaapiSliceClass)) +#define GST_VAAPI_SLICE(obj) \ + GST_VAAPI_SLICE_CAST(obj) #define GST_VAAPI_IS_SLICE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SLICE)) - -#define GST_VAAPI_IS_SLICE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SLICE)) - -#define GST_VAAPI_SLICE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_SLICE, \ - GstVaapiSliceClass)) + (GST_VAAPI_SLICE(obj) != NULL) /** * GstVaapiSlice: @@ -252,19 +209,14 @@ struct _GstVaapiSlice { gpointer param; }; -/** - * GstVaapiSliceClass: - * - * The #GstVaapiSlice base class. - */ -struct _GstVaapiSliceClass { - /*< private >*/ - GstVaapiCodecObjectClass parent_class; -}; +G_GNUC_INTERNAL +void +gst_vaapi_slice_destroy(GstVaapiSlice *slice); G_GNUC_INTERNAL -GType -gst_vaapi_slice_get_type(void) G_GNUC_CONST; +gboolean +gst_vaapi_slice_create(GstVaapiSlice *slice, + const GstVaapiCodecObjectConstructorArgs *args); G_GNUC_INTERNAL GstVaapiSlice * From 74533de9c6c476571d50b80f30a10832070d1b99 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 3 Dec 2012 14:09:01 +0100 Subject: [PATCH 0923/3781] Port GstVaapiFrameStore to GstVaapiMiniObject. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 80 ++++++----------------- 1 file changed, 19 insertions(+), 61 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index db2e03c00c..3ca0bf1d7f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -261,36 +261,18 @@ gst_vaapi_slice_h264_new( /* --- Frame Buffers (DPB) --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_TYPE_FRAME_STORE \ - (gst_vaapi_frame_store_get_type()) - #define GST_VAAPI_FRAME_STORE_CAST(obj) \ ((GstVaapiFrameStore *)(obj)) -#define GST_VAAPI_FRAME_STORE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_FRAME_STORE, \ - GstVaapiFrameStore)) - -#define GST_VAAPI_FRAME_STORE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_FRAME_STORE, \ - GstVaapiFrameStoreClass)) +#define GST_VAAPI_FRAME_STORE(obj) \ + GST_VAAPI_FRAME_STORE_CAST(obj) #define GST_VAAPI_IS_FRAME_STORE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_FRAME_STORE)) - -#define GST_VAAPI_IS_FRAME_STORE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_FRAME_STORE)) - -#define GST_VAAPI_FRAME_STORE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_FRAME_STORE, \ - GstVaapiFrameStoreClass)) + (GST_VAAPI_MINI_OBJECT(obj) != NULL) struct _GstVaapiFrameStore { /*< private >*/ - GstMiniObject parent_instance; + GstVaapiMiniObject parent_instance; guint structure; GstVaapiPictureH264 *buffers[2]; @@ -298,45 +280,14 @@ struct _GstVaapiFrameStore { guint output_needed; }; -struct _GstVaapiFrameStoreClass { - /*< private >*/ - GstMiniObjectClass parent_class; -}; - -G_DEFINE_TYPE(GstVaapiFrameStore, gst_vaapi_frame_store, GST_TYPE_MINI_OBJECT) - static void -gst_vaapi_frame_store_finalize(GstMiniObject *object) +gst_vaapi_frame_store_finalize(gpointer object) { - GstVaapiFrameStore * const fs = GST_VAAPI_FRAME_STORE_CAST(object); - GstMiniObjectClass *parent_class; + GstVaapiFrameStore * const fs = object; guint i; for (i = 0; i < fs->num_buffers; i++) gst_vaapi_picture_replace(&fs->buffers[i], NULL); - - parent_class = GST_MINI_OBJECT_CLASS(gst_vaapi_frame_store_parent_class); - if (parent_class->finalize) - parent_class->finalize(object); -} - -static void -gst_vaapi_frame_store_init(GstVaapiFrameStore *fs) -{ -} - -static void -gst_vaapi_frame_store_class_init(GstVaapiFrameStoreClass *klass) -{ - GstMiniObjectClass * const object_class = GST_MINI_OBJECT_CLASS(klass); - - object_class->finalize = gst_vaapi_frame_store_finalize; -} - -static inline gpointer -_gst_vaapi_frame_store_new(void) -{ - return gst_mini_object_new(GST_VAAPI_TYPE_FRAME_STORE); } static GstVaapiFrameStore * @@ -344,14 +295,21 @@ gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture) { GstVaapiFrameStore *fs; + static const GstVaapiMiniObjectClass GstVaapiFrameStoreClass = { + sizeof(GstVaapiFrameStore), + gst_vaapi_frame_store_finalize + }; + g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL); - fs = _gst_vaapi_frame_store_new(); + fs = (GstVaapiFrameStore *) + gst_vaapi_mini_object_new(&GstVaapiFrameStoreClass); if (!fs) return NULL; fs->structure = picture->structure; fs->buffers[0] = gst_vaapi_picture_ref(picture); + fs->buffers[1] = NULL; fs->num_buffers = 1; fs->output_needed = picture->output_needed; return fs; @@ -431,14 +389,14 @@ gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs) } #define gst_vaapi_frame_store_ref(fs) \ - gst_mini_object_ref(GST_MINI_OBJECT(fs)) + gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(fs)) #define gst_vaapi_frame_store_unref(fs) \ - gst_mini_object_unref(GST_MINI_OBJECT(fs)) + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(fs)) -#define gst_vaapi_frame_store_replace(old_fs_p, new_fs) \ - gst_mini_object_replace((GstMiniObject **)(old_fs_p), \ - (GstMiniObject *)(new_fs)) +#define gst_vaapi_frame_store_replace(old_fs_p, new_fs) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_fs_p), \ + (GstVaapiMiniObject *)(new_fs)) /* ------------------------------------------------------------------------- */ /* --- H.264 Decoder --- */ From 49dbb9af50315f322b179a8ee86959ece4f8e13c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 6 Dec 2012 09:44:01 +0100 Subject: [PATCH 0924/3781] decoder: add new "decoder-unit" object. Introduce GstVaapiDecoderUnit which represents a fragment of the source stream to be decoded. For instance, a decode-unit will be a NAL unit for H.264 streams, an EBDU for VC-1 streams, and a video packet for MPEG-2 streams. This is a libgstvaapi internal object. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidecoder_unit.c | 149 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_unit.h | 175 ++++++++++++++++++++++ 3 files changed, 326 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_unit.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_unit.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index fe1e44bb55..4893480a4e 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -49,6 +49,7 @@ libgstvaapi_source_c = \ gstvaapidecoder_mpeg2.c \ gstvaapidecoder_mpeg4.c \ gstvaapidecoder_objects.c \ + gstvaapidecoder_unit.c \ gstvaapidecoder_vc1.c \ gstvaapidisplay.c \ gstvaapidisplaycache.c \ @@ -105,6 +106,7 @@ libgstvaapi_source_priv_h = \ gstvaapidecoder_dpb.h \ gstvaapidecoder_objects.h \ gstvaapidecoder_priv.h \ + gstvaapidecoder_unit.h \ gstvaapidisplay_priv.h \ gstvaapiminiobject.h \ gstvaapiobject_priv.h \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c new file mode 100644 index 0000000000..4b2648e780 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c @@ -0,0 +1,149 @@ +/* + * gstvaapidecoder_unit.c - VA decoder units + * + * Copyright (C) 2012 Intel Corporation + * + * 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" + +static inline const GstVaapiMiniObjectClass * +gst_vaapi_decoder_unit_class(void) +{ + static const GstVaapiMiniObjectClass GstVaapiDecoderUnitClass = { + sizeof(GstVaapiDecoderUnit), + (GDestroyNotify)gst_vaapi_decoder_unit_finalize + }; + return &GstVaapiDecoderUnitClass; +} + +/** + * 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. + */ +static inline void +decoder_unit_init(GstVaapiDecoderUnit *unit, guint size) +{ + unit->size = size; + unit->offset = 0; + unit->buffer = NULL; + + unit->parsed_info = NULL; + unit->parsed_info_destroy_notify = NULL; +} + +void +gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit, guint size) +{ + decoder_unit_init(unit, size); +} + +/** + * gst_vaapi_decoder_unit_finalize: + * @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. + */ +static inline void +decoder_unit_finalize(GstVaapiDecoderUnit *unit) +{ + gst_buffer_replace(&unit->buffer, NULL); + gst_vaapi_decoder_unit_set_parsed_info(unit, NULL, NULL); +} + +void +gst_vaapi_decoder_unit_finalize(GstVaapiDecoderUnit *unit) +{ + decoder_unit_finalize(unit); +} + +/** + * gst_vaapi_decoder_unit_new: + * @size: size in bytes of this bitstream data chunk + * + * Creates a new #GstVaapiDecoderUnit object. + * + * Returns: The newly allocated #GstVaapiDecoderUnit + */ +GstVaapiDecoderUnit * +gst_vaapi_decoder_unit_new(guint size) +{ + GstVaapiDecoderUnit *unit; + + unit = (GstVaapiDecoderUnit *) + gst_vaapi_mini_object_new(gst_vaapi_decoder_unit_class()); + if (!unit) + return NULL; + + decoder_unit_init(unit, size); + return unit; +} + +/** + * gst_vaapi_decoder_unit_set_buffer: + * @unit: a #GstVaapiDecoderUnit + * @buffer: the new #GstBuffer to set + * + * Sets new buffer to the supplied decoder unit. The @unit holds an + * extra reference to the @buffer if it is not NULL. + */ +void +gst_vaapi_decoder_unit_set_buffer(GstVaapiDecoderUnit *unit, GstBuffer *buffer) +{ + g_return_if_fail(GST_VAAPI_IS_DECODER_UNIT(unit)); + + gst_buffer_replace(&unit->buffer, buffer); +} + +/** + * 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; +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h new file mode 100644 index 0000000000..1b4746d7a0 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h @@ -0,0 +1,175 @@ +/* + * gstvaapidecoder_unit.h - VA decoder units + * + * Copyright (C) 2012 Intel Corporation + * + * 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 + +#include +#include + +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: marks 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; + +#define GST_VAAPI_DECODER_UNIT_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS +#define GST_VAAPI_DECODER_UNIT_FLAG_IS_SET GST_VAAPI_MINI_OBJECT_FLAG_IS_SET +#define GST_VAAPI_DECODER_UNIT_FLAG_SET GST_VAAPI_MINI_OBJECT_FLAG_SET +#define GST_VAAPI_DECODER_UNIT_FLAG_UNSET GST_VAAPI_MINI_OBJECT_FLAG_UNSET + +/** + * 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 + * @buffer: (optional) associated buffer or sub-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 { + /*< private >*/ + GstVaapiMiniObject parent_instance; + + guint size; + guint offset; + GstBuffer *buffer; + gpointer parsed_info; + GDestroyNotify parsed_info_destroy_notify; +}; + +G_GNUC_INTERNAL +void +gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit, guint size); + +G_GNUC_INTERNAL +void +gst_vaapi_decoder_unit_finalize(GstVaapiDecoderUnit *unit); + +G_GNUC_INTERNAL +GstVaapiDecoderUnit * +gst_vaapi_decoder_unit_new(guint size); + +G_GNUC_INTERNAL +void +gst_vaapi_decoder_unit_set_buffer(GstVaapiDecoderUnit *unit, GstBuffer *buffer); + +G_GNUC_INTERNAL +void +gst_vaapi_decoder_unit_set_parsed_info(GstVaapiDecoderUnit *unit, + gpointer parsed_info, GDestroyNotify destroy_notify); + +#define gst_vaapi_decoder_unit_ref(unit) \ + gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(unit)) + +#define gst_vaapi_decoder_unit_unref(unit) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(unit)) + +#define gst_vaapi_decoder_unit_replace(old_unit_p, new_unit) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_unit_p), \ + (GstVaapiMiniObject *)(new_unit)) + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_UNIT_H */ From f5e6444b78f86bb99e709ed20e559d13ec2260de Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 5 Dec 2012 10:51:41 +0100 Subject: [PATCH 0925/3781] decoder: add new "decoder-frame" object. Introduce a new GstVaapiDecoderFrame that is just a list of decoder units (GstVaapiDecoderUnit objects) that constitute a frame. This object is just an extension to GstVideoCodecFrame for VA decoder purposes. It is available as the user-data member element. This is a libgstvaapi internal object. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidecoder_frame.c | 81 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_frame.h | 94 ++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_frame.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_frame.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 4893480a4e..143794b284 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -45,6 +45,7 @@ libgstvaapi_source_c = \ gstvaapicontext.c \ gstvaapidecoder.c \ gstvaapidecoder_dpb.c \ + gstvaapidecoder_frame.c \ gstvaapidecoder_h264.c \ gstvaapidecoder_mpeg2.c \ gstvaapidecoder_mpeg4.c \ @@ -104,6 +105,7 @@ libgstvaapi_source_priv_h = \ gstvaapicompat.h \ gstvaapidebug.h \ gstvaapidecoder_dpb.h \ + gstvaapidecoder_frame.h \ gstvaapidecoder_objects.h \ gstvaapidecoder_priv.h \ gstvaapidecoder_unit.h \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.c b/gst-libs/gst/vaapi/gstvaapidecoder_frame.c new file mode 100644 index 0000000000..cddb5e5276 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_frame.c @@ -0,0 +1,81 @@ +/* + * gstvaapidecoder_frame.c - VA decoder frame + * + * Copyright (C) 2012 Intel Corporation + * + * 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_frame + * @short_description: VA decoder frame + */ + +#include "sysdeps.h" +#include "gstvaapidecoder_frame.h" + +static inline const GstVaapiMiniObjectClass * +gst_vaapi_decoder_frame_class(void) +{ + static const GstVaapiMiniObjectClass GstVaapiDecoderFrameClass = { + sizeof(GstVaapiDecoderFrame), + (GDestroyNotify)gst_vaapi_decoder_frame_free + }; + return &GstVaapiDecoderFrameClass; +} + +/** + * gst_vaapi_decoder_frame_new: + * + * Creates a new #GstVaapiDecoderFrame object. + * + * Returns: The newly allocated #GstVaapiDecoderFrame + */ +GstVaapiDecoderFrame * +gst_vaapi_decoder_frame_new(void) +{ + GstVaapiDecoderFrame *frame; + + frame = (GstVaapiDecoderFrame *) + gst_vaapi_mini_object_new(gst_vaapi_decoder_frame_class()); + if (!frame) + return NULL; + + frame->output_offset = 0; + frame->units = NULL; + frame->prev_slice = NULL; + return frame; +} + +/** + * gst_vaapi_decoder_frame_free: + * @frame: a #GstVaapiDecoderFrame + * + * Deallocates any internal resources bound to the supplied decoder + * @frame. + * + * @note This is an internal function used to implement lightweight + * sub-classes. + */ +void +gst_vaapi_decoder_frame_free(GstVaapiDecoderFrame *frame) +{ + if (frame->units) { + g_slist_free_full(frame->units, + (GDestroyNotify)gst_vaapi_mini_object_unref); + frame->units = NULL; + } +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h new file mode 100644 index 0000000000..69a6c42f2f --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h @@ -0,0 +1,94 @@ +/* + * gstvaapidecoder_frame.h - VA decoder frame + * + * Copyright (C) 2012 Intel Corporation + * + * 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_FRAME_H +#define GST_VAAPI_DECODER_FRAME_H + +#include +#include + +G_BEGIN_DECLS + +typedef struct _GstVaapiDecoderFrame GstVaapiDecoderFrame; + +#define GST_VAAPI_DECODER_FRAME(frame) \ + ((GstVaapiDecoderFrame *)(frame)) + +#define GST_VAAPI_IS_DECODER_FRAME(frame) \ + (GST_VAAPI_DECODER_FRAME(frame) != NULL) + +/** + * GstVaapiDecoderFrameFlags: + * + * Flags for #GstVaapiDecoderFrame. + */ +typedef enum { + GST_VAAPI_DECODER_FRAME_FLAG_LAST = (1 << 0) +} GstVaapiDecoderFrameFlags; + +#define GST_VAAPI_DECODER_FRAME_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS +#define GST_VAAPI_DECODER_FRAME_FLAG_IS_SET GST_VAAPI_MINI_OBJECT_FLAG_IS_SET +#define GST_VAAPI_DECODER_FRAME_FLAG_SET GST_VAAPI_MINI_OBJECT_FLAG_SET +#define GST_VAAPI_DECODER_FRAME_FLAG_UNSET GST_VAAPI_MINI_OBJECT_FLAG_UNSET + +/** + * GstVaapiDecoderFrame: + * @output_offset: current offset to the reconstructed #GstBuffer for + * this #GstVideoCodecFrame. This is used to initialize the decoder + * unit offset + * @units: list of #GstVaapiDecoderUnit objects + * @prev_slice: previous #GstVaapiDecoderUnit that was a slice, or NULL + * if no slice data unit was received yet + * + * An extension to #GstVideoCodecFrame with #GstVaapiDecoder specific + * information. Decoder frames are usually attached to codec frames as + * the user_data anchor point. + */ +struct _GstVaapiDecoderFrame { + /*< private >*/ + GstVaapiMiniObject parent_instance; + + guint output_offset; + GSList *units; + GstVaapiDecoderUnit *prev_slice; +}; + +G_GNUC_INTERNAL +GstVaapiDecoderFrame * +gst_vaapi_decoder_frame_new(void); + +G_GNUC_INTERNAL +void +gst_vaapi_decoder_frame_free(GstVaapiDecoderFrame *frame); + +#define gst_vaapi_decoder_frame_ref(frame) \ + gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(frame)) + +#define gst_vaapi_decoder_frame_unref(frame) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(frame)) + +#define gst_vaapi_decoder_frame_replace(old_frame_p, new_frame) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_frame_p), \ + (GstVaapiMiniObject *)(new_frame)) + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_FRAME_H */ From 66cc8754fcfbbe51fdc056110c23a4a9ed90a717 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 6 Dec 2012 13:57:42 +0100 Subject: [PATCH 0926/3781] decoder: add new GstVaapiDecoder API. Split decoding process into two steps: (i) parse incoming bitstreams into simple decoder-units until the frame or field is complete; and (ii) decode the whole frame or field at once. This is an ABI change. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 194 +++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidecoder.h | 9 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 35 ++++ 3 files changed, 231 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index f2513393ca..85a2cd0ce2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -48,6 +48,64 @@ enum { static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; +static void +parser_state_finalize(GstVaapiParserState *ps) +{ + if (ps->input_adapter) { + gst_adapter_clear(ps->input_adapter); + g_object_unref(ps->input_adapter); + ps->input_adapter = NULL; + } + + if (ps->output_adapter) { + gst_adapter_clear(ps->output_adapter); + g_object_unref(ps->output_adapter); + ps->output_adapter = NULL; + } +} + +static gboolean +parser_state_init(GstVaapiParserState *ps) +{ + ps->input_adapter = gst_adapter_new(); + if (!ps->input_adapter) + return FALSE; + + ps->output_adapter = gst_adapter_new(); + if (!ps->output_adapter) + return FALSE; + return TRUE; +} + +static inline GstVaapiDecoderUnit * +parser_state_get_pending_unit(GstVaapiParserState *ps, GstAdapter *adapter) +{ + GstVaapiDecoderUnit * const unit = ps->pending_unit; + + ps->pending_unit = NULL; + return unit; +} + +static inline void +parser_state_set_pending_unit(GstVaapiParserState *ps, + GstAdapter *adapter, GstVaapiDecoderUnit *unit) +{ + ps->pending_unit = unit; +} + +static void +parser_state_prepare(GstVaapiParserState *ps, GstAdapter *adapter) +{ + /* XXX: check we really have a continuity from the previous call */ + if (ps->current_adapter != adapter) + goto reset; + return; + +reset: + ps->current_adapter = adapter; + ps->input_offset2 = -1; +} + static void destroy_buffer(GstBuffer *buffer) { @@ -89,13 +147,97 @@ pop_buffer(GstVaapiDecoder *decoder) return buffer; } +static GstVaapiDecoderStatus +do_parse(GstVaapiDecoder *decoder, + GstVideoCodecFrame *base_frame, GstAdapter *adapter, gboolean at_eos, + guint *got_unit_size_ptr, gboolean *got_frame_ptr) +{ + GstVaapiParserState * const ps = &decoder->priv->parser_state; + GstVaapiDecoderFrame *frame; + GstVaapiDecoderUnit *unit; + GstVaapiDecoderStatus status; + + *got_unit_size_ptr = 0; + *got_frame_ptr = FALSE; + + frame = gst_video_codec_frame_get_user_data(base_frame); + if (!frame) { + frame = gst_vaapi_decoder_frame_new(); + if (!frame) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + gst_video_codec_frame_set_user_data(base_frame, + frame, (GDestroyNotify)gst_vaapi_mini_object_unref); + } + + parser_state_prepare(ps, adapter); + + unit = parser_state_get_pending_unit(ps, adapter); + if (unit) + goto got_unit; + + ps->current_frame = base_frame; + status = GST_VAAPI_DECODER_GET_CLASS(decoder)->parse(decoder, + adapter, at_eos, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + if (unit) + gst_vaapi_decoder_unit_unref(unit); + return status; + } + + if (GST_VAAPI_DECODER_UNIT_IS_FRAME_START(unit) && frame->prev_slice) { + parser_state_set_pending_unit(ps, adapter, unit); + goto got_frame; + } + +got_unit: + unit->offset = frame->output_offset; + frame->units = g_slist_prepend(frame->units, unit); + frame->output_offset += unit->size; + if (GST_VAAPI_DECODER_UNIT_IS_SLICE(unit)) + frame->prev_slice = unit; + + *got_unit_size_ptr = unit->size; + if (GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit)) { + got_frame: + frame->units = g_slist_reverse(frame->units); + *got_frame_ptr = TRUE; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) +{ + GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); + GstVaapiParserState * const ps = &decoder->priv->parser_state; + GstVaapiDecoderFrame *frame; + GstVaapiDecoderStatus status; + GSList *l; + + ps->current_frame = base_frame; + + frame = base_frame->user_data; + for (l = frame->units; l != NULL; l = l->next) { + GstVaapiDecoderUnit * const unit = l->data; + if (GST_VAAPI_DECODER_UNIT_IS_SKIPPED(unit)) + continue; + status = klass->decode(decoder, unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus decode_step(GstVaapiDecoder *decoder) { + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiParserState * const ps = &priv->parser_state; GstVaapiDecoderStatus status; GstBuffer *buffer; + gboolean at_eos, got_frame; + guint got_unit_size; - /* Decoding will fail if there is no surface left */ status = gst_vaapi_decoder_check_status(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; @@ -105,11 +247,47 @@ decode_step(GstVaapiDecoder *decoder) if (!buffer) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - status = GST_VAAPI_DECODER_GET_CLASS(decoder)->decode(decoder, buffer); - GST_DEBUG("decode frame (status = %d)", status); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS && GST_BUFFER_IS_EOS(buffer)) - status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM; - gst_buffer_unref(buffer); + at_eos = GST_BUFFER_IS_EOS(buffer); + if (!at_eos) + gst_adapter_push(ps->input_adapter, buffer); + + do { + if (!ps->current_frame) { + ps->current_frame = g_slice_new0(GstVideoCodecFrame); + if (!ps->current_frame) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + ps->current_frame->ref_count = 1; + } + + status = do_parse(decoder, ps->current_frame, + ps->input_adapter, at_eos, &got_unit_size, &got_frame); + GST_DEBUG("parse frame (status = %d)", status); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + break; + + if (got_unit_size > 0) { + buffer = gst_adapter_take_buffer(ps->input_adapter, + got_unit_size); + if (gst_adapter_available(ps->output_adapter) == 0) { + ps->current_frame->pts = + gst_adapter_prev_timestamp(ps->input_adapter, NULL); + } + gst_adapter_push(ps->output_adapter, buffer); + } + + if (got_frame) { + ps->current_frame->input_buffer = gst_adapter_take_buffer( + ps->output_adapter, + gst_adapter_available(ps->output_adapter)); + + status = do_decode(decoder, ps->current_frame); + GST_DEBUG("decode frame (status = %d)", status); + + gst_video_codec_frame_unref(ps->current_frame); + ps->current_frame = NULL; + } + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && + gst_adapter_available(ps->input_adapter) > 0); } while (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA); return status; } @@ -211,6 +389,8 @@ gst_vaapi_decoder_finalize(GObject *object) set_codec_data(decoder, NULL); + parser_state_finalize(&priv->parser_state); + if (priv->caps) { gst_caps_unref(priv->caps); priv->caps = NULL; @@ -332,6 +512,8 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) { GstVaapiDecoderPrivate *priv = GST_VAAPI_DECODER_GET_PRIVATE(decoder); + parser_state_init(&priv->parser_state); + decoder->priv = priv; priv->display = NULL; priv->va_display = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index b5a397bd2e..a61705d9dc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -24,8 +24,10 @@ #define GST_VAAPI_DECODER_H #include +#include #include #include +#include G_BEGIN_DECLS @@ -56,6 +58,7 @@ G_BEGIN_DECLS typedef struct _GstVaapiDecoder GstVaapiDecoder; typedef struct _GstVaapiDecoderPrivate GstVaapiDecoderPrivate; typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; + struct _GstVaapiDecoderUnit; /** * GstVaapiDecoderStatus: @@ -110,7 +113,11 @@ struct _GstVaapiDecoderClass { /*< private >*/ GObjectClass parent_class; - GstVaapiDecoderStatus (*decode)(GstVaapiDecoder *decoder, GstBuffer *buffer); + GstVaapiDecoderStatus (*parse)(GstVaapiDecoder *decoder, + GstAdapter *adapter, gboolean at_eos, + struct _GstVaapiDecoderUnit **unit_ptr); + GstVaapiDecoderStatus (*decode)(GstVaapiDecoder *decoder, + struct _GstVaapiDecoderUnit *unit); }; GType diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 7ab4906dbd..8a1a98a619 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -25,12 +25,24 @@ #include #include +#include #include G_BEGIN_DECLS #define GST_VAAPI_DECODER_CAST(decoder) ((GstVaapiDecoder *)(decoder)) +/** + * 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)->priv->parser_state) + /** * GST_VAAPI_DECODER_DISPLAY: * @decoder: a #GstVaapiDecoder @@ -76,6 +88,18 @@ G_BEGIN_DECLS #define GST_VAAPI_DECODER_CODEC_DATA(decoder) \ GST_VAAPI_DECODER_CAST(decoder)->priv->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 @@ -109,6 +133,16 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DECODER, \ GstVaapiDecoderPrivate)) +typedef struct _GstVaapiParserState GstVaapiParserState; +struct _GstVaapiParserState { + GstVideoCodecFrame *current_frame; + GstAdapter *current_adapter; + GstAdapter *input_adapter; + gint input_offset2; + GstAdapter *output_adapter; + GstVaapiDecoderUnit *pending_unit; +}; + struct _GstVaapiDecoderPrivate { GstVaapiDisplay *display; VADisplay va_display; @@ -125,6 +159,7 @@ struct _GstVaapiDecoderPrivate { guint par_d; GQueue *buffers; GQueue *surfaces; + GstVaapiParserState parser_state; guint is_interlaced : 1; }; From ea9703362c084a7295dc6d132cead99cd8cb685e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Dec 2012 10:20:35 +0100 Subject: [PATCH 0927/3781] decoder: add {start,end}_frame() hooks. The start_frame() hook is called prior to traversing all decode-units for decoding. The unit argument represents the first slice in the frame. Some codecs (e.g. H.264) need to wait for the first slice in order to determine the actual VA context parameters. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 21 +++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapidecoder.h | 3 +++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 85a2cd0ce2..e930f7e2d0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -210,13 +210,24 @@ do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) { GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); GstVaapiParserState * const ps = &decoder->priv->parser_state; - GstVaapiDecoderFrame *frame; + GstVaapiDecoderFrame * const frame = base_frame->user_data; GstVaapiDecoderStatus status; GSList *l; ps->current_frame = base_frame; - frame = base_frame->user_data; + if (klass->start_frame) { + for (l = frame->units; l != NULL; l = l->next) { + GstVaapiDecoderUnit * const unit = l->data; + if (GST_VAAPI_DECODER_UNIT_IS_SLICE(unit)) { + status = klass->start_frame(decoder, unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + break; + } + } + } + for (l = frame->units; l != NULL; l = l->next) { GstVaapiDecoderUnit * const unit = l->data; if (GST_VAAPI_DECODER_UNIT_IS_SKIPPED(unit)) @@ -225,6 +236,12 @@ do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; } + + if (klass->end_frame) { + status = klass->end_frame(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } return GST_VAAPI_DECODER_STATUS_SUCCESS; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index a61705d9dc..70188b6c5c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -118,6 +118,9 @@ struct _GstVaapiDecoderClass { struct _GstVaapiDecoderUnit **unit_ptr); GstVaapiDecoderStatus (*decode)(GstVaapiDecoder *decoder, struct _GstVaapiDecoderUnit *unit); + GstVaapiDecoderStatus (*start_frame)(GstVaapiDecoder *decoder, + struct _GstVaapiDecoderUnit *unit); + GstVaapiDecoderStatus (*end_frame)(GstVaapiDecoder *decoder); }; GType From 6bed9ebe0fa3aeb5a97abc3d0f564ca3a5dc7613 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 29 Nov 2012 15:06:00 +0100 Subject: [PATCH 0928/3781] decoder: expose new parse/decode API. Introduce new decoding process whereby a GstVideoCodecFrame is created first. Next, input stream buffers are accumulated into a GstAdapter, that is then passed to the _parse() function. The GstVaapiDecoder object accumulates all parsed units and when a complete frame or field is detected, that GstVideoCodecFrame is passed to the _decode() function. Ultimately, the caller receives a GstVaapiSurfaceProxy if decoding process was successful. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 47 ++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder.h | 11 +++++ gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 4 ++ 3 files changed, 62 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index e930f7e2d0..1e48d9fbc3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -787,3 +787,50 @@ gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder) return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } + +GstVaapiDecoderStatus +gst_vaapi_decoder_parse(GstVaapiDecoder *decoder, + GstVideoCodecFrame *base_frame, GstAdapter *adapter, gboolean at_eos, + guint *got_unit_size_ptr, gboolean *got_frame_ptr) +{ + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail(base_frame != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail(adapter != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail(got_unit_size_ptr != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail(got_frame_ptr != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + + return do_parse(decoder, base_frame, adapter, at_eos, + got_unit_size_ptr, got_frame_ptr); +} + +GstVaapiDecoderStatus +gst_vaapi_decoder_decode(GstVaapiDecoder *decoder, + GstVideoCodecFrame *base_frame, GstVaapiSurfaceProxy **out_proxy_ptr) +{ + GstVaapiDecoderStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail(base_frame != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail(base_frame->user_data != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail(out_proxy_ptr != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + + status = gst_vaapi_decoder_check_status(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + status = do_decode(decoder, base_frame); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + *out_proxy_ptr = pop_surface(decoder); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 70188b6c5c..6632a26421 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -73,6 +73,7 @@ typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; * @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(). @@ -89,6 +90,7 @@ typedef enum { 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; @@ -141,6 +143,15 @@ gst_vaapi_decoder_get_surface( GstVaapiDecoderStatus *pstatus ); +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, GstVaapiSurfaceProxy **out_proxy_ptr); + G_END_DECLS #endif /* GST_VAAPI_DECODER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 165ac79128..aad758c8e8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -163,6 +163,10 @@ gst_vaapi_picture_create( picture->slices = g_ptr_array_new(); if (!picture->slices) return FALSE; + + gst_vaapi_mini_object_set_user_data( + GST_VAAPI_MINI_OBJECT(picture->proxy), + GST_VAAPI_DECODER_CODEC_FRAME(GET_DECODER(picture)), NULL); return TRUE; } From 798e84bd9305ddc256770f83d03cc49143b9f2fc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Dec 2012 16:40:44 +0100 Subject: [PATCH 0929/3781] decoder: use standard helper functions. Use g_clear_object(), gst_buffer_replace() and gst_caps_replace() whenever necessary. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 50 ++++++---------------------- 1 file changed, 10 insertions(+), 40 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 1e48d9fbc3..f64b25ae3c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -106,12 +106,6 @@ reset: ps->input_offset2 = -1; } -static void -destroy_buffer(GstBuffer *buffer) -{ - gst_buffer_unref(buffer); -} - static gboolean push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) { @@ -334,20 +328,6 @@ pop_surface(GstVaapiDecoder *decoder) return g_queue_pop_head(priv->surfaces); } -static inline void -set_codec_data(GstVaapiDecoder *decoder, GstBuffer *codec_data) -{ - GstVaapiDecoderPrivate * const priv = decoder->priv; - - if (priv->codec_data) { - gst_buffer_unref(priv->codec_data); - priv->codec_data = NULL; - } - - if (codec_data) - priv->codec_data = gst_buffer_ref(codec_data); -} - static void set_caps(GstVaapiDecoder *decoder, GstCaps *caps) { @@ -388,7 +368,8 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps) v_codec_data = gst_structure_get_value(structure, "codec_data"); if (v_codec_data) - set_codec_data(decoder, gst_value_get_buffer(v_codec_data)); + gst_buffer_replace(&priv->codec_data, + gst_value_get_buffer(v_codec_data)); } static void @@ -404,23 +385,12 @@ gst_vaapi_decoder_finalize(GObject *object) GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object); GstVaapiDecoderPrivate * const priv = decoder->priv; - set_codec_data(decoder, NULL); - + gst_buffer_replace(&priv->codec_data, NULL); + gst_caps_replace(&priv->caps, NULL); parser_state_finalize(&priv->parser_state); - - if (priv->caps) { - gst_caps_unref(priv->caps); - priv->caps = NULL; - } - - if (priv->context) { - g_object_unref(priv->context); - priv->context = NULL; - priv->va_context = VA_INVALID_ID; - } if (priv->buffers) { - clear_queue(priv->buffers, (GDestroyNotify)destroy_buffer); + clear_queue(priv->buffers, (GDestroyNotify)gst_buffer_unref); g_queue_free(priv->buffers); priv->buffers = NULL; } @@ -432,11 +402,11 @@ gst_vaapi_decoder_finalize(GObject *object) priv->surfaces = NULL; } - if (priv->display) { - g_object_unref(priv->display); - priv->display = NULL; - priv->va_display = NULL; - } + g_clear_object(&priv->context); + priv->va_context = VA_INVALID_ID; + + g_clear_object(&priv->display); + priv->va_display = NULL; G_OBJECT_CLASS(gst_vaapi_decoder_parent_class)->finalize(object); } From 14a6e0f629072a4ce2b947f50cf9eb344e354d81 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 12 Dec 2012 13:44:07 +0100 Subject: [PATCH 0930/3781] decoder: update gst_vaapi_decoder_get_surface() semantics. Align gst_vaapi_decoder_get_surface() semantics with the rest of the API. That is, return a GstVaapiDecoderStatus and the decoded surface as a handle to GstVaapiSurfaceProxy in parameter. This is an API/ABI change. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 33 ++++++++++++++-------------- gst-libs/gst/vaapi/gstvaapidecoder.h | 8 +++---- tests/test-decode.c | 4 ++-- tests/test-subpicture.c | 4 ++-- 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index f64b25ae3c..e78b6e235e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -582,28 +582,28 @@ gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf) /** * gst_vaapi_decoder_get_surface: * @decoder: a #GstVaapiDecoder - * @pstatus: return location for the decoder status, or %NULL + * @out_proxy_ptr: the next decoded surface as a #GstVaapiSurfaceProxy * * Flushes encoded buffers to the decoder and returns a decoded * surface, if any. * - * Return value: a #GstVaapiSurfaceProxy holding the decoded surface, - * or %NULL if none is available (e.g. an error). Caller owns the - * returned object. g_object_unref() after usage. + * On successful return, *@out_proxy_ptr contains the decoded surface + * as a #GstVaapiSurfaceProxy. The caller owns this object, so + * gst_vaapi_surface_proxy_unref() shall be called after usage. + * + * Return value: a #GstVaapiDecoderStatus */ -GstVaapiSurfaceProxy * -gst_vaapi_decoder_get_surface( - GstVaapiDecoder *decoder, - GstVaapiDecoderStatus *pstatus -) +GstVaapiDecoderStatus +gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, + GstVaapiSurfaceProxy **out_proxy_ptr) { GstVaapiSurfaceProxy *proxy; GstVaapiDecoderStatus status; - if (pstatus) - *pstatus = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail(out_proxy_ptr != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); proxy = pop_surface(decoder); if (!proxy) { @@ -615,10 +615,11 @@ gst_vaapi_decoder_get_surface( if (proxy) status = GST_VAAPI_DECODER_STATUS_SUCCESS; + else if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - if (pstatus) - *pstatus = status; - return proxy; + *out_proxy_ptr = proxy; + return status; } void diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 6632a26421..cfa5884398 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -137,11 +137,9 @@ gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder); gboolean gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf); -GstVaapiSurfaceProxy * -gst_vaapi_decoder_get_surface( - GstVaapiDecoder *decoder, - GstVaapiDecoderStatus *pstatus -); +GstVaapiDecoderStatus +gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, + GstVaapiSurfaceProxy **out_proxy_ptr); GstVaapiDecoderStatus gst_vaapi_decoder_parse(GstVaapiDecoder *decoder, diff --git a/tests/test-decode.c b/tests/test-decode.c index b8c7e75b24..f855a146ad 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -179,8 +179,8 @@ main(int argc, char *argv[]) if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) g_error("could not send EOS to the decoder"); - proxy = gst_vaapi_decoder_get_surface(decoder, &status); - if (!proxy) + status = gst_vaapi_decoder_get_surface(decoder, &proxy); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) g_error("could not get decoded surface (decoder status %d)", status); gst_vaapi_window_show(window); diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 913d183160..11d018b973 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -157,8 +157,8 @@ main(int argc, char *argv[]) if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) g_error("could not send EOS to the decoder"); - proxy = gst_vaapi_decoder_get_surface(decoder, &status); - if (!proxy) + status = gst_vaapi_decoder_get_surface(decoder, &proxy); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) g_error("could not get decoded surface (decoder status %d)", status); surface = gst_vaapi_surface_proxy_get_surface(proxy); From e7e5c74a6e8c55e1c4361fbbeb1136fa78f1f6c5 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 12 Dec 2012 15:09:21 +0100 Subject: [PATCH 0931/3781] decoder: use GstVideoCodecState. Use standard GstVideoCodecState throughout GstVaapiDecoder and expose it with a new gst_vaapi_decoder_get_codec_state() function. This makes it possible to drop picture size (width, height) information, framerate (fps_n, fps_d) information, pixel aspect ratio (par_n, par_d) information, and interlace mode (is_interlaced field). This is a new API with backwards compatibility maintained. In particular, gst_vaapi_decoder_get_caps() is still available. Signed-off-by: Sreerenj Balachandran Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder.c | 173 ++++++++++++---------- gst-libs/gst/vaapi/gstvaapidecoder.h | 3 + gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 33 +++-- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 10 +- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- gst-libs/gst/vaapi/gstvaapiprofile.h | 2 +- 6 files changed, 129 insertions(+), 94 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index e78b6e235e..279f958ab6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -307,14 +307,15 @@ static inline void push_surface(GstVaapiDecoder *decoder, GstVaapiSurfaceProxy *proxy) { GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVideoInfo * const vi = &priv->codec_state->info; GstClockTime duration; GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id(proxy))); - if (priv->fps_n && priv->fps_d) { + if (vi->fps_n && vi->fps_d) { /* Actual field duration is computed in vaapipostproc */ - duration = gst_util_uint64_scale(GST_SECOND, priv->fps_d, priv->fps_n); + duration = gst_util_uint64_scale(GST_SECOND, vi->fps_d, vi->fps_n); gst_vaapi_surface_proxy_set_duration(proxy, duration); } g_queue_push_tail(priv->surfaces, proxy); @@ -329,49 +330,39 @@ pop_surface(GstVaapiDecoder *decoder) } static void -set_caps(GstVaapiDecoder *decoder, GstCaps *caps) +set_caps(GstVaapiDecoder *decoder, const GstCaps *caps) { GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVideoCodecState * const codec_state = priv->codec_state; GstStructure * const structure = gst_caps_get_structure(caps, 0); GstVaapiProfile profile; const GValue *v_codec_data; - gint v1, v2; - gboolean b; profile = gst_vaapi_profile_from_caps(caps); if (!profile) return; - priv->caps = gst_caps_copy(caps); - priv->codec = gst_vaapi_profile_get_codec(profile); if (!priv->codec) return; - if (gst_structure_get_int(structure, "width", &v1)) - priv->width = v1; - if (gst_structure_get_int(structure, "height", &v2)) - priv->height = v2; + if (!gst_video_info_from_caps(&codec_state->info, caps)) + return; - if (gst_structure_get_fraction(structure, "framerate", &v1, &v2)) { - priv->fps_n = v1; - priv->fps_d = v2; - } - - if (gst_structure_get_fraction(structure, "pixel-aspect-ratio", &v1, &v2)) { - priv->par_n = v1; - priv->par_d = v2; - } - - if (gst_structure_get_boolean(structure, "interlaced", &b)) - priv->is_interlaced = b; + codec_state->caps = gst_caps_copy(caps); v_codec_data = gst_structure_get_value(structure, "codec_data"); if (v_codec_data) - gst_buffer_replace(&priv->codec_data, + gst_buffer_replace(&codec_state->codec_data, gst_value_get_buffer(v_codec_data)); } +static inline GstCaps * +get_caps(GstVaapiDecoder *decoder) +{ + return GST_VAAPI_DECODER_CODEC_STATE(decoder)->caps; +} + static void clear_queue(GQueue *q, GDestroyNotify destroy) { @@ -385,8 +376,9 @@ gst_vaapi_decoder_finalize(GObject *object) GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object); GstVaapiDecoderPrivate * const priv = decoder->priv; - gst_buffer_replace(&priv->codec_data, NULL); - gst_caps_replace(&priv->caps, NULL); + gst_video_codec_state_unref(priv->codec_state); + priv->codec_state = NULL; + parser_state_finalize(&priv->parser_state); if (priv->buffers) { @@ -447,14 +439,15 @@ gst_vaapi_decoder_get_property( GParamSpec *pspec ) { - GstVaapiDecoderPrivate * const priv = GST_VAAPI_DECODER(object)->priv; + GstVaapiDecoder * const decoder = GST_VAAPI_DECODER_CAST(object); + GstVaapiDecoderPrivate * const priv = decoder->priv; switch (prop_id) { case PROP_DISPLAY: g_value_set_object(value, priv->display); break; case PROP_CAPS: - gst_value_set_caps(value, priv->caps); + gst_value_set_caps(value, get_caps(decoder)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -498,26 +491,23 @@ static void gst_vaapi_decoder_init(GstVaapiDecoder *decoder) { GstVaapiDecoderPrivate *priv = GST_VAAPI_DECODER_GET_PRIVATE(decoder); + GstVideoCodecState *codec_state; parser_state_init(&priv->parser_state); + codec_state = g_slice_new0(GstVideoCodecState); + codec_state->ref_count = 1; + gst_video_info_init(&codec_state->info); + decoder->priv = priv; priv->display = NULL; priv->va_display = NULL; priv->context = NULL; priv->va_context = VA_INVALID_ID; - priv->caps = NULL; priv->codec = 0; - priv->codec_data = NULL; - priv->width = 0; - priv->height = 0; - priv->fps_n = 0; - priv->fps_d = 0; - priv->par_n = 0; - priv->par_d = 0; + priv->codec_state = codec_state; priv->buffers = g_queue_new(); priv->surfaces = g_queue_new(); - priv->is_interlaced = FALSE; } /** @@ -536,6 +526,24 @@ gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder) return decoder->priv->codec; } +/** + * gst_vaapi_decoder_get_codec_state: + * @decoder: a #GstVaapiDecoder + * + * Retrieves the @decoder codec state. The caller owns an extra reference + * to the #GstVideoCodecState, so gst_video_codec_state_unref() shall be + * called after usage. + * + * Return value: the #GstVideoCodecState object for @decoder + */ +GstVideoCodecState * +gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder) +{ + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + return gst_video_codec_state_ref(decoder->priv->codec_state); +} + /** * gst_vaapi_decoder_get_caps: * @decoder: a #GstVaapiDecoder @@ -548,7 +556,7 @@ gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder) GstCaps * gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder) { - return decoder->priv->caps; + return get_caps(decoder); } /** @@ -629,20 +637,22 @@ gst_vaapi_decoder_set_picture_size( guint height ) { - GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVideoCodecState * const codec_state = decoder->priv->codec_state; gboolean size_changed = FALSE; - if (priv->width != width) { + if (codec_state->info.width != width) { GST_DEBUG("picture width changed to %d", width); - priv->width = width; - gst_caps_set_simple(priv->caps, "width", G_TYPE_INT, width, NULL); + codec_state->info.width = width; + gst_caps_set_simple(codec_state->caps, + "width", G_TYPE_INT, width, NULL); size_changed = TRUE; } - if (priv->height != height) { + if (codec_state->info.height != height) { GST_DEBUG("picture height changed to %d", height); - priv->height = height; - gst_caps_set_simple(priv->caps, "height", G_TYPE_INT, height, NULL); + codec_state->info.height = height; + gst_caps_set_simple(codec_state->caps, + "height", G_TYPE_INT, height, NULL); size_changed = TRUE; } @@ -657,20 +667,17 @@ gst_vaapi_decoder_set_framerate( guint fps_d ) { - GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVideoCodecState * const codec_state = decoder->priv->codec_state; if (!fps_n || !fps_d) return; - if (priv->fps_n != fps_n || priv->fps_d != fps_d) { + if (codec_state->info.fps_n != fps_n || codec_state->info.fps_d != fps_d) { GST_DEBUG("framerate changed to %u/%u", fps_n, fps_d); - priv->fps_n = fps_n; - priv->fps_d = fps_d; - gst_caps_set_simple( - priv->caps, - "framerate", GST_TYPE_FRACTION, fps_n, fps_d, - NULL - ); + codec_state->info.fps_n = fps_n; + codec_state->info.fps_d = fps_d; + gst_caps_set_simple(codec_state->caps, + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); } } @@ -682,20 +689,44 @@ gst_vaapi_decoder_set_pixel_aspect_ratio( guint par_d ) { - GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVideoCodecState * const codec_state = decoder->priv->codec_state; if (!par_n || !par_d) return; - if (priv->par_n != par_n || priv->par_d != par_d) { + if (codec_state->info.par_n != par_n || codec_state->info.par_d != par_d) { GST_DEBUG("pixel-aspect-ratio changed to %u/%u", par_n, par_d); - priv->par_n = par_n; - priv->par_d = par_d; - gst_caps_set_simple( - priv->caps, - "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, - NULL - ); + codec_state->info.par_n = par_n; + codec_state->info.par_d = par_d; + gst_caps_set_simple(codec_state->caps, + "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL); + g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); + } +} + +static const gchar * +gst_interlace_mode_to_string(GstVideoInterlaceMode mode) +{ + switch (mode) { + case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE: return "progressive"; + case GST_VIDEO_INTERLACE_MODE_INTERLEAVED: return "interleaved"; + case GST_VIDEO_INTERLACE_MODE_MIXED: return "mixed"; + } + return ""; +} + +void +gst_vaapi_decoder_set_interlace_mode(GstVaapiDecoder *decoder, + GstVideoInterlaceMode mode) +{ + GstVideoCodecState * const codec_state = decoder->priv->codec_state; + + if (codec_state->info.interlace_mode != mode) { + GST_DEBUG("interlace mode changed to %s", + gst_interlace_mode_to_string(mode)); + codec_state->info.interlace_mode = mode; + gst_caps_set_simple(codec_state->caps, "interlaced", + G_TYPE_BOOLEAN, mode != GST_VIDEO_INTERLACE_MODE_PROGRESSIVE, NULL); g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); } } @@ -703,18 +734,10 @@ gst_vaapi_decoder_set_pixel_aspect_ratio( void gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced) { - GstVaapiDecoderPrivate * const priv = decoder->priv; - - if (priv->is_interlaced != interlaced) { - GST_DEBUG("interlaced changed to %s", interlaced ? "true" : "false"); - priv->is_interlaced = interlaced; - gst_caps_set_simple( - priv->caps, - "interlaced", G_TYPE_BOOLEAN, interlaced, - NULL - ); - g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); - } + gst_vaapi_decoder_set_interlace_mode(decoder, + (interlaced ? + GST_VIDEO_INTERLACE_MODE_INTERLEAVED : + GST_VIDEO_INTERLACE_MODE_PROGRESSIVE)); } gboolean diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index cfa5884398..9ca3d4093f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -131,6 +131,9 @@ gst_vaapi_decoder_get_type(void) G_GNUC_CONST; GstVaapiCodec gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder); +GstVideoCodecState * +gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder); + GstCaps * gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 8a1a98a619..a74673e095 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -76,6 +76,18 @@ G_BEGIN_DECLS #define GST_VAAPI_DECODER_CODEC(decoder) \ GST_VAAPI_DECODER_CAST(decoder)->priv->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)->priv->codec_state + /** * GST_VAAPI_DECODER_CODEC_DATA: * @decoder: a #GstVaapiDecoder @@ -86,7 +98,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DECODER_CODEC_DATA #define GST_VAAPI_DECODER_CODEC_DATA(decoder) \ - GST_VAAPI_DECODER_CAST(decoder)->priv->codec_data + GST_VAAPI_DECODER_CODEC_STATE(decoder)->codec_data /** * GST_VAAPI_DECODER_CODEC_FRAME: @@ -109,7 +121,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DECODER_WIDTH #define GST_VAAPI_DECODER_WIDTH(decoder) \ - GST_VAAPI_DECODER_CAST(decoder)->priv->width + GST_VAAPI_DECODER_CODEC_STATE(decoder)->info.width /** * GST_VAAPI_DECODER_HEIGHT: @@ -120,7 +132,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DECODER_HEIGHT #define GST_VAAPI_DECODER_HEIGHT(decoder) \ - GST_VAAPI_DECODER_CAST(decoder)->priv->height + GST_VAAPI_DECODER_CODEC_STATE(decoder)->info.height /* End-of-Stream buffer */ #define GST_BUFFER_FLAG_EOS (GST_BUFFER_FLAG_LAST + 0) @@ -148,19 +160,11 @@ struct _GstVaapiDecoderPrivate { VADisplay va_display; GstVaapiContext *context; VAContextID va_context; - GstCaps *caps; GstVaapiCodec codec; - GstBuffer *codec_data; - guint width; - guint height; - guint fps_n; - guint fps_d; - guint par_n; - guint par_d; + GstVideoCodecState *codec_state; GQueue *buffers; GQueue *surfaces; GstVaapiParserState parser_state; - guint is_interlaced : 1; }; G_GNUC_INTERNAL @@ -187,6 +191,11 @@ gst_vaapi_decoder_set_pixel_aspect_ratio( 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); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 57ff80c3d3..4949a288dc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1133,15 +1133,15 @@ decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) if (!buf || buf_size == 0) return GST_VAAPI_DECODER_STATUS_SUCCESS; - caps = GST_VAAPI_DECODER_CAST(decoder)->priv->caps; - structure = gst_caps_get_structure(caps, 0); - - if (!gst_structure_get_int(structure, "width", &width) || - !gst_structure_get_int(structure, "height", &height)) { + width = GST_VAAPI_DECODER_WIDTH(decoder); + height = GST_VAAPI_DECODER_HEIGHT(decoder); + if (!width || !height) { GST_DEBUG("failed to parse size from codec-data"); return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } + caps = GST_VAAPI_DECODER_CODEC_STATE(decoder)->caps; + structure = gst_caps_get_structure(caps, 0); if (!gst_structure_get_fourcc(structure, "format", &format)) { GST_DEBUG("failed to parse profile from codec-data"); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 7536c446ed..a2b3da499b 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -210,7 +210,7 @@ gst_vaapi_profile_from_codec_data(GstVaapiCodec codec, GstBuffer *buffer) * Return value: the #GstVaapiProfile describing the @caps */ GstVaapiProfile -gst_vaapi_profile_from_caps(GstCaps *caps) +gst_vaapi_profile_from_caps(const GstCaps *caps) { const GstVaapiProfileMap *m; GstCaps *caps_test; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index f742e134a7..a3a0f95d61 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -134,7 +134,7 @@ GstVaapiProfile gst_vaapi_profile(VAProfile profile); GstVaapiProfile -gst_vaapi_profile_from_caps(GstCaps *caps); +gst_vaapi_profile_from_caps(const GstCaps *caps); VAProfile gst_vaapi_profile_get_va_profile(GstVaapiProfile profile); From 50090d6138f40775357f903bb39257029d57c356 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 6 Dec 2012 14:01:46 +0100 Subject: [PATCH 0932/3781] mpeg2: initial port to new GstVaapiDecoder API. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 190 +++++++++++++-------- 1 file changed, 115 insertions(+), 75 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 8bdb13f116..f3e35b8923 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -178,7 +178,6 @@ struct _GstVaapiDecoderMpeg2Private { GstMpegVideoQuantMatrixExt quant_matrix_ext; GstVaapiPicture *current_picture; GstVaapiDpb *dpb; - GstAdapter *adapter; PTSGenerator tsg; guint is_constructed : 1; guint is_opened : 1; @@ -284,25 +283,15 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) gst_vaapi_dpb_unref(priv->dpb); priv->dpb = NULL; } - - if (priv->adapter) { - gst_adapter_clear(priv->adapter); - g_object_unref(priv->adapter); - priv->adapter = NULL; - } } static gboolean -gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) +gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; gst_vaapi_decoder_mpeg2_close(decoder); - priv->adapter = gst_adapter_new(); - if (!priv->adapter) - return FALSE; - priv->dpb = gst_vaapi_dpb_mpeg2_new(); if (!priv->dpb) return FALSE; @@ -629,7 +618,6 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoGop gop; - GstClockTime pts; if (!gst_mpeg_video_parse_gop(&gop, buf, buf_size, 4)) { GST_ERROR("failed to parse GOP"); @@ -643,8 +631,7 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) gop.hour, gop.minute, gop.second, gop.frame, priv->closed_gop, priv->broken_link); - pts = gst_adapter_prev_timestamp(priv->adapter, NULL); - pts_sync(&priv->tsg, pts); + pts_sync(&priv->tsg, GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -655,7 +642,6 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr; GstVaapiPicture *picture; GstVaapiDecoderStatus status; - GstClockTime pts; status = ensure_context(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { @@ -715,8 +701,8 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) } /* Update presentation time */ - pts = gst_adapter_prev_timestamp(priv->adapter, NULL); - picture->pts = pts_eval(&priv->tsg, pts, pic_hdr->tsn); + picture->pts = pts_eval(&priv->tsg, + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts, pic_hdr->tsn); picture->poc = pts_get_poc(&priv->tsg); return status; } @@ -1044,81 +1030,135 @@ undefined_picture: static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstVaapiDecoderStatus status; - gboolean is_eos; guchar *buf; - guint buf_size, size; - guint32 start_code; - gint ofs; + guint buf_size; buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); - is_eos = GST_BUFFER_IS_EOS(buffer); - if (buf && buf_size > 0) - gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); - size = gst_adapter_available(priv->adapter); - do { - if (size == 0) { - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } - - status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - if (size < 4) - break; - ofs = scan_for_start_code(priv->adapter, 0, size, &start_code); - if (ofs < 0) - break; - gst_adapter_flush(priv->adapter, ofs); - size -= ofs; - - status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder)); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - break; - - status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - if (size < 8) - break; - ofs = scan_for_start_code(priv->adapter, 4, size - 4, NULL); - if (ofs < 0) { - // Assume the whole packet is present if end-of-stream - if (!is_eos) - break; - ofs = size; - } - buffer = gst_adapter_take_buffer(priv->adapter, ofs); - size -= ofs; - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - status = decode_packet(decoder, buf, buf_size); - - gst_buffer_unref(buffer); - } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); - - if (is_eos && (status == GST_VAAPI_DECODER_STATUS_SUCCESS || - status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA)) - status = decode_sequence_end(decoder); + status = decode_packet(decoder, buf, buf_size); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; return status; } -GstVaapiDecoderStatus -gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base, GstBuffer *buffer) +static GstVaapiDecoderStatus +ensure_decoder(GstVaapiDecoderMpeg2 *decoder) { - GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2(base); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; g_return_val_if_fail(priv->is_constructed, GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); if (!priv->is_opened) { - priv->is_opened = gst_vaapi_decoder_mpeg2_open(decoder, buffer); + priv->is_opened = gst_vaapi_decoder_mpeg2_open(decoder); if (!priv->is_opened) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; } - return decode_buffer(decoder, buffer); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, + GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) +{ + GstVaapiDecoderMpeg2 * const decoder = + GST_VAAPI_DECODER_MPEG2(base_decoder); + GstVaapiDecoderUnit *unit = NULL; + GstVaapiDecoderStatus status; + guint32 start_code; + guint8 pkt_type, ext_type; + guint size, buf_size, flags = 0; + gint ofs; + + status = ensure_decoder(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + size = gst_adapter_available(adapter); + if (size < 4) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + ofs = scan_for_start_code(adapter, 0, size, &start_code); + if (ofs < 0) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + gst_adapter_flush(adapter, ofs); + size -= ofs; + + ofs = G_UNLIKELY(size < 8) ? -1 : + scan_for_start_code(adapter, 4, size - 4, NULL); + if (ofs < 0) { + // Assume the whole packet is present if end-of-stream + if (!at_eos) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + ofs = size; + } + buf_size = ofs; + + unit = gst_vaapi_decoder_unit_new(buf_size); + if (!unit) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + /* Check for start of new picture */ + pkt_type = start_code & 0xff; + switch (pkt_type) { + case GST_MPEG_VIDEO_PACKET_SEQUENCE_END: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; + break; + case GST_MPEG_VIDEO_PACKET_USER_DATA: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + /* fall-through */ + case GST_MPEG_VIDEO_PACKET_SEQUENCE: + case GST_MPEG_VIDEO_PACKET_GOP: + case GST_MPEG_VIDEO_PACKET_PICTURE: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; + case GST_MPEG_VIDEO_PACKET_EXTENSION: + if (buf_size < 5) + break; + gst_adapter_copy(adapter, &ext_type, 4, 1); + switch (ext_type) { + case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; + } + break; + default: + if (pkt_type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + pkt_type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + break; + } + GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); + + *unit_ptr = unit; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base_decoder, + GstVaapiDecoderUnit *unit) +{ + GstVaapiDecoderMpeg2 * const decoder = + GST_VAAPI_DECODER_MPEG2(base_decoder); + GstVaapiDecoderStatus status; + + status = ensure_decoder(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + unit->buffer = gst_buffer_create_sub( + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, + unit->offset, unit->size); + if (!unit->buffer) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + status = decode_buffer(decoder, unit->buffer); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static void @@ -1156,6 +1196,7 @@ gst_vaapi_decoder_mpeg2_class_init(GstVaapiDecoderMpeg2Class *klass) object_class->finalize = gst_vaapi_decoder_mpeg2_finalize; object_class->constructed = gst_vaapi_decoder_mpeg2_constructed; + decoder_class->parse = gst_vaapi_decoder_mpeg2_parse; decoder_class->decode = gst_vaapi_decoder_mpeg2_decode; } @@ -1173,7 +1214,6 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv->hw_profile = GST_VAAPI_PROFILE_UNKNOWN; priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; priv->current_picture = NULL; - priv->adapter = NULL; priv->is_constructed = FALSE; priv->is_opened = FALSE; priv->has_seq_ext = FALSE; From 8fbd05ca82735f171446f62236738252252dcbd7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 17 Dec 2012 09:47:20 -0800 Subject: [PATCH 0933/3781] mpeg4: initial port to new GstVaapiDecoder API --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 264 ++++++++++++--------- 1 file changed, 155 insertions(+), 109 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index f408cd634c..fae5a99f97 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -68,8 +68,6 @@ struct _GstVaapiDecoderMpeg4Private { GstVaapiPicture *next_picture; // backward reference pic GstVaapiPicture *prev_picture; - GstAdapter *adapter; - GstBuffer *sub_buffer; GstClockTime seq_pts; GstClockTime gop_pts; GstClockTime pts_diff; @@ -108,21 +106,10 @@ gst_vaapi_decoder_mpeg4_close(GstVaapiDecoderMpeg4 *decoder) gst_vaapi_picture_replace(&priv->curr_picture, NULL); gst_vaapi_picture_replace(&priv->next_picture, NULL); gst_vaapi_picture_replace(&priv->prev_picture, NULL); - - if (priv->sub_buffer) { - gst_buffer_unref(priv->sub_buffer); - priv->sub_buffer = NULL; - } - - if (priv->adapter) { - gst_adapter_clear(priv->adapter); - g_object_unref(priv->adapter); - priv->adapter = NULL; - } } static gboolean -gst_vaapi_decoder_mpeg4_open(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) +gst_vaapi_decoder_mpeg4_open(GstVaapiDecoderMpeg4 *decoder) { GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg4Private * const priv = decoder->priv; @@ -131,10 +118,6 @@ gst_vaapi_decoder_mpeg4_open(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) gst_vaapi_decoder_mpeg4_close(decoder); - priv->adapter = gst_adapter_new(); - if (!priv->adapter) - return FALSE; - priv->is_svh = 0; caps = gst_vaapi_decoder_get_caps(base_decoder); if (caps) { @@ -320,7 +303,7 @@ decode_sequence(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size priv->profile = profile; priv->profile_changed = TRUE; } - priv->seq_pts = gst_adapter_prev_timestamp(priv->adapter, NULL); + priv->seq_pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; priv->size_changed = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -444,7 +427,7 @@ calculate_pts_diff(GstVaapiDecoderMpeg4 *decoder, GstVaapiDecoderMpeg4Private * const priv = decoder->priv; GstClockTime frame_timestamp; - frame_timestamp = gst_adapter_prev_timestamp(priv->adapter, NULL); + frame_timestamp = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; if (frame_timestamp && frame_timestamp != GST_CLOCK_TIME_NONE) { /* Buffer with timestamp */ if (priv->max_pts != GST_CLOCK_TIME_NONE && @@ -807,10 +790,6 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) if (tos->size < 0) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder)); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - // packet.size is the size from current marker to the next. if (tos->type == GST_MPEG4_VISUAL_OBJ_SEQ_START) { status = decode_sequence(decoder, packet.data + packet.offset, packet.size); @@ -902,6 +881,10 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) GST_WARNING("Ignore marker: %x\n", tos->type); status = GST_VAAPI_DECODER_STATUS_SUCCESS; } + else { + GST_ERROR("unsupported start code %x\n", tos->type); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + } return status; } @@ -910,91 +893,35 @@ static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) { GstVaapiDecoderMpeg4Private * const priv = decoder->priv; - GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - guchar *buf; - guint pos, buf_size; - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - - // visual object sequence end - if (!buf && buf_size == 0) - return decode_sequence_end(decoder); - - gst_buffer_ref(buffer); - gst_adapter_push(priv->adapter, buffer); - - if (priv->sub_buffer) { - buffer = gst_buffer_merge(priv->sub_buffer, buffer); - if (!buffer) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - gst_buffer_unref(priv->sub_buffer); - priv->sub_buffer = NULL; - } - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - pos = 0; - + GstVaapiDecoderStatus status; GstMpeg4Packet packet; - GstMpeg4ParseResult result = GST_MPEG4_PARSER_OK; - guint consumed_size = 0; + const guchar *buf; + guint buf_size, ofs; + + buf = GST_BUFFER_DATA(buffer); + buf_size = GST_BUFFER_SIZE(buffer); if (priv->is_svh) { - while (result == GST_MPEG4_PARSER_OK && pos < buf_size) { - result = gst_h263_parse (&packet,buf, pos, buf_size); - if (result != GST_MPEG4_PARSER_OK) { - break; - } - status = decode_picture(decoder, packet.data+packet.offset, packet.size); - if (GST_VAAPI_DECODER_STATUS_SUCCESS == status) { - // MBs are not byte aligned, so we set the start address with byte aligned - // and mb offset with (priv->svh_hdr.size)%8 - status = decode_slice(decoder, packet.data+packet.offset+(priv->svh_hdr.size)/8, - packet.size - (priv->svh_hdr.size)/8, FALSE); - status = decode_current_picture(decoder); + status = decode_picture(decoder, buf, buf_size); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; - consumed_size = packet.offset + packet.size; - pos += consumed_size; - if (gst_adapter_available(priv->adapter) >= pos) - gst_adapter_flush(priv->adapter, pos); - } - else { - GST_WARNING("decode h263 packet failed\n"); - break; - } - } + ofs = priv->svh_hdr.size / 8; + status = decode_slice(decoder, buf + ofs, buf_size - ofs, FALSE); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; } else { - while (pos < buf_size) { - // don't skip user data, we need the size to pop tsb buffer - result = gst_mpeg4_parse(&packet, FALSE, NULL, buf, pos, buf_size); - if (result != GST_MPEG4_PARSER_OK) { - break; - } - status = decode_packet(decoder, packet); - if (GST_VAAPI_DECODER_STATUS_SUCCESS == status || - GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA == status) { - consumed_size = packet.offset + packet.size - pos; - pos = packet.offset + packet.size; - if (gst_adapter_available(priv->adapter) >= pos) - gst_adapter_flush(priv->adapter, pos); - } - else { - GST_WARNING("decode mp4 packet failed\n"); - break; - } - } - } + packet.data = buf; + packet.offset = 0; + packet.size = buf_size; + packet.type = (GstMpeg4StartCode)packet.data[0]; - if ((result == GST_MPEG4_PARSER_NO_PACKET || - result == GST_MPEG4_PARSER_NO_PACKET_END || - status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) && - pos < buf_size) { - priv->sub_buffer = gst_buffer_create_sub(buffer, pos, buf_size-pos); - status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + status = decode_packet(decoder, packet); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; } - return status; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus @@ -1037,19 +964,18 @@ decode_codec_data(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) return status; } -GstVaapiDecoderStatus -gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base, GstBuffer *buffer) +static GstVaapiDecoderStatus +ensure_decoder(GstVaapiDecoderMpeg4 *decoder) { - GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4(base); GstVaapiDecoderMpeg4Private * const priv = decoder->priv; - GstBuffer *codec_data = NULL; GstVaapiDecoderStatus status; + GstBuffer *codec_data; g_return_val_if_fail(priv->is_constructed, GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); if (!priv->is_opened) { - priv->is_opened = gst_vaapi_decoder_mpeg4_open(decoder, buffer); + priv->is_opened = gst_vaapi_decoder_mpeg4_open(decoder); if (!priv->is_opened) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; @@ -1060,7 +986,128 @@ gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base, GstBuffer *buffer) return status; } } - return decode_buffer(decoder, buffer); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg4_parse(GstVaapiDecoder *base_decoder, + GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) +{ + GstVaapiDecoderMpeg4 * const decoder = + GST_VAAPI_DECODER_MPEG4(base_decoder); + GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderUnit *unit = NULL; + GstVaapiDecoderStatus status; + GstMpeg4Packet packet; + GstMpeg4ParseResult result; + const guchar *buf; + guint size, buf_size, flags = 0; + + status = ensure_decoder(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + size = gst_adapter_available(adapter); + buf = gst_adapter_peek(adapter, size); + if (!buf) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + if (priv->is_svh) + result = gst_h263_parse(&packet, buf, 0, size); + else + result = gst_mpeg4_parse(&packet, FALSE, NULL, buf, 0, size); + if (result == GST_MPEG4_PARSER_NO_PACKET_END && at_eos) + packet.size = size - packet.offset; + else if (result == GST_MPEG4_PARSER_ERROR) + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + else if (result != GST_MPEG4_PARSER_OK) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + buf_size = packet.size; + gst_adapter_flush(adapter, packet.offset); + + /* Check for start of new picture */ + switch (packet.type) { + case GST_MPEG4_VIDEO_SESSION_ERR: + case GST_MPEG4_FBA: + case GST_MPEG4_FBA_PLAN: + case GST_MPEG4_MESH: + case GST_MPEG4_MESH_PLAN: + case GST_MPEG4_STILL_TEXTURE_OBJ: + case GST_MPEG4_TEXTURE_SPATIAL: + case GST_MPEG4_TEXTURE_SNR_LAYER: + case GST_MPEG4_TEXTURE_TILE: + case GST_MPEG4_SHAPE_LAYER: + case GST_MPEG4_STUFFING: + gst_adapter_flush(adapter, packet.size); + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + case GST_MPEG4_USER_DATA: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + break; + case GST_MPEG4_VISUAL_OBJ_SEQ_END: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; + break; + case GST_MPEG4_VIDEO_OBJ_PLANE: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + /* fall-through */ + case GST_MPEG4_VISUAL_OBJ_SEQ_START: + case GST_MPEG4_VISUAL_OBJ: + case GST_MPEG4_GROUP_OF_VOP: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; + default: + if (packet.type >= GST_MPEG4_VIDEO_OBJ_FIRST && + packet.type <= GST_MPEG4_VIDEO_OBJ_LAST) { + gst_adapter_flush(adapter, packet.size); + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } + if (packet.type >= GST_MPEG4_VIDEO_LAYER_FIRST && + packet.type <= GST_MPEG4_VIDEO_LAYER_LAST) { + break; + } + if (packet.type >= GST_MPEG4_SYSTEM_FIRST && + packet.type <= GST_MPEG4_SYSTEM_LAST) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + break; + } + GST_WARNING("unsupported start code (0x%02x)", packet.type); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + unit = gst_vaapi_decoder_unit_new(buf_size); + if (!unit) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); + + *unit_ptr = unit; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base_decoder, + GstVaapiDecoderUnit *unit) +{ + GstVaapiDecoderMpeg4 * const decoder = + GST_VAAPI_DECODER_MPEG4(base_decoder); + GstVaapiDecoderStatus status; + + status = ensure_decoder(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + unit->buffer = gst_buffer_create_sub( + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, + unit->offset, unit->size); + if (!unit->buffer) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + status = decode_buffer(decoder, unit->buffer); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static void @@ -1098,6 +1145,7 @@ gst_vaapi_decoder_mpeg4_class_init(GstVaapiDecoderMpeg4Class *klass) object_class->finalize = gst_vaapi_decoder_mpeg4_finalize; object_class->constructed = gst_vaapi_decoder_mpeg4_constructed; + decoder_class->parse = gst_vaapi_decoder_mpeg4_parse; decoder_class->decode = gst_vaapi_decoder_mpeg4_decode; } @@ -1116,8 +1164,6 @@ gst_vaapi_decoder_mpeg4_init(GstVaapiDecoderMpeg4 *decoder) priv->curr_picture = NULL; priv->next_picture = NULL; priv->prev_picture = NULL; - priv->adapter = NULL; - priv->sub_buffer = NULL; priv->seq_pts = GST_CLOCK_TIME_NONE; priv->gop_pts = GST_CLOCK_TIME_NONE; priv->max_pts = GST_CLOCK_TIME_NONE; From 7e6660fcae6f76802fa4ac116c46f5739536b09d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 6 Dec 2012 14:02:17 +0100 Subject: [PATCH 0934/3781] h264: initial port to new GstVaapiDecoder API --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 262 +++++++++++++--------- 1 file changed, 160 insertions(+), 102 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 3ca0bf1d7f..aca954fbe8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -412,7 +412,6 @@ G_DEFINE_TYPE(GstVaapiDecoderH264, GstVaapiDecoderH264Private)) struct _GstVaapiDecoderH264Private { - GstAdapter *adapter; GstH264NalParser *parser; /* Last decoded SPS. May not be the last activated one. Just here because it may not fit stack memory allocation in decode_sps() */ @@ -779,25 +778,15 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) gst_h264_nal_parser_free(priv->parser); priv->parser = NULL; } - - if (priv->adapter) { - gst_adapter_clear(priv->adapter); - g_object_unref(priv->adapter); - priv->adapter = NULL; - } } static gboolean -gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) +gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = decoder->priv; gst_vaapi_decoder_h264_close(decoder); - priv->adapter = gst_adapter_new(); - if (!priv->adapter) - return FALSE; - priv->parser = gst_h264_nal_parser_new(); if (!priv->parser) return FALSE; @@ -2031,7 +2020,7 @@ init_picture( picture->frame_num = priv->frame_num; picture->frame_num_wrap = priv->frame_num; picture->output_flag = TRUE; /* XXX: conformant to Annex A only */ - base_picture->pts = gst_adapter_prev_timestamp(priv->adapter, NULL); + base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; /* Reset decoder state for IDR pictures */ if (nalu->type == GST_H264_NAL_SLICE_IDR) { @@ -2894,93 +2883,23 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) GstVaapiDecoderStatus status; GstH264ParserResult result; GstH264NalUnit nalu; - gboolean is_eos; - const guchar *buf; - guint i, buf_size, nalu_size, size; - guint32 start_code; - gint ofs; + guchar *buf; + guint buf_size; buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); - is_eos = GST_BUFFER_IS_EOS(buffer); - if (buf && buf_size > 0) - gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); - size = gst_adapter_available(priv->adapter); - do { - if (size == 0) { - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } + if (priv->is_avc) + result = gst_h264_parser_identify_nalu_avc(priv->parser, + buf, 0, buf_size, priv->nal_length_size, &nalu); + else + result = gst_h264_parser_identify_nalu_unchecked(priv->parser, + buf, 0, buf_size, &nalu); + status = get_status(result); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; - status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder)); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - break; - - status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - if (priv->is_avc) { - if (size < priv->nal_length_size) - break; - buf = gst_adapter_peek(priv->adapter, priv->nal_length_size); - - nalu_size = 0; - for (i = 0; i < priv->nal_length_size; i++) - nalu_size = (nalu_size << 8) | buf[i]; - - buf_size = priv->nal_length_size + nalu_size; - if (size < buf_size) - break; - buffer = gst_adapter_take_buffer(priv->adapter, buf_size); - size -= buf_size; - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - - result = gst_h264_parser_identify_nalu_avc( - priv->parser, - buf, 0, buf_size, priv->nal_length_size, - &nalu - ); - } - else { - if (size < 4) - break; - ofs = scan_for_start_code(priv->adapter, 0, size, &start_code); - if (ofs < 0) - break; - gst_adapter_flush(priv->adapter, ofs); - size -= ofs; - - ofs = G_UNLIKELY(size < 8) ? -1 : - scan_for_start_code(priv->adapter, 4, size - 4, NULL); - if (ofs < 0) { - // Assume the whole NAL unit is present if end-of-stream - if (!is_eos) - break; - ofs = size; - } - buffer = gst_adapter_take_buffer(priv->adapter, ofs); - size -= ofs; - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - - result = gst_h264_parser_identify_nalu_unchecked( - priv->parser, - buf, 0, buf_size, - &nalu - ); - } - status = get_status(result); - if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) - status = decode_nalu(decoder, &nalu); - gst_buffer_unref(buffer); - } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); - - if (is_eos && (status == GST_VAAPI_DECODER_STATUS_SUCCESS || - status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA)) - status = decode_sequence_end(decoder); - return status; + return decode_nalu(decoder, &nalu); } static GstVaapiDecoderStatus @@ -3049,10 +2968,9 @@ decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) return status; } -GstVaapiDecoderStatus -gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base, GstBuffer *buffer) +static GstVaapiDecoderStatus +ensure_decoder(GstVaapiDecoderH264 *decoder) { - GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base); GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiDecoderStatus status; GstBuffer *codec_data; @@ -3061,7 +2979,7 @@ gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base, GstBuffer *buffer) GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); if (!priv->is_opened) { - priv->is_opened = gst_vaapi_decoder_h264_open(decoder, buffer); + priv->is_opened = gst_vaapi_decoder_h264_open(decoder); if (!priv->is_opened) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; @@ -3071,8 +2989,148 @@ gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base, GstBuffer *buffer) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; } - } - return decode_buffer(decoder, buffer); + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, + GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) +{ + GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base_decoder); + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderUnit *unit; + GstVaapiDecoderStatus status; + GstH264NalUnit nalu; + GstH264ParserResult result; + guchar *buf; + guint i, size, buf_size, nalu_size, flags; + guint32 start_code; + gint ofs; + + status = ensure_decoder(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + size = gst_adapter_available(adapter); + + if (priv->is_avc) { + if (size < priv->nal_length_size) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + buf = (guchar *)&start_code; + g_assert(priv->nal_length_size <= sizeof(start_code)); + gst_adapter_copy(adapter, buf, 0, priv->nal_length_size); + + nalu_size = 0; + for (i = 0; i < priv->nal_length_size; i++) + nalu_size = (nalu_size << 8) | buf[i]; + + buf_size = priv->nal_length_size + nalu_size; + if (size < buf_size) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } + else { + if (size < 4) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + ofs = scan_for_start_code(adapter, 0, size, NULL); + if (ofs < 0) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + gst_adapter_flush(adapter, ofs); + size -= ofs; + + ofs = G_UNLIKELY(size < 8) ? -1 : + scan_for_start_code(adapter, 4, size - 4, NULL); + if (ofs < 0) { + // Assume the whole NAL unit is present if end-of-stream + if (!at_eos) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + ofs = size; + } + buf_size = ofs; + } + + buf = (guchar *)gst_adapter_peek(adapter, buf_size); + if (!buf) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + unit = gst_vaapi_decoder_unit_new(buf_size); + if (!unit) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + if (priv->is_avc) + result = gst_h264_parser_identify_nalu_avc(priv->parser, + buf, 0, buf_size, priv->nal_length_size, &nalu); + else + result = gst_h264_parser_identify_nalu_unchecked(priv->parser, + buf, 0, buf_size, &nalu); + status = get_status(result); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + gst_vaapi_decoder_unit_unref(unit); + return status; + } + + flags = 0; + switch (nalu.type) { + case GST_H264_NAL_AU_DELIMITER: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + /* fall-through */ + case GST_H264_NAL_FILLER_DATA: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + break; + case GST_H264_NAL_STREAM_END: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; + /* fall-through */ + case GST_H264_NAL_SEQ_END: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + break; + case GST_H264_NAL_SPS: + case GST_H264_NAL_PPS: + case GST_H264_NAL_SEI: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; + case GST_H264_NAL_SLICE_IDR: + case GST_H264_NAL_SLICE: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + /* XXX: assume we got a new frame if first_mb_in_slice is set + to zero, thus ignoring Arbitrary Slice Order (ASO) feature + from Baseline profile */ + if (nalu.offset + 2 <= nalu.size && + (nalu.data[nalu.offset + 1] & 0x80)) + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; + default: + if (nalu.type >= 14 && nalu.type <= 18) + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; + } + GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); + + *unit_ptr = unit; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base_decoder, + GstVaapiDecoderUnit *unit) +{ + GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base_decoder); + GstVaapiDecoderStatus status; + + status = ensure_decoder(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + unit->buffer = gst_buffer_create_sub( + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, + unit->offset, unit->size); + if (!unit->buffer) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + status = decode_buffer(decoder, unit->buffer); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static void @@ -3110,6 +3168,7 @@ gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass) object_class->finalize = gst_vaapi_decoder_h264_finalize; object_class->constructed = gst_vaapi_decoder_h264_constructed; + decoder_class->parse = gst_vaapi_decoder_h264_parse; decoder_class->decode = gst_vaapi_decoder_h264_decode; } @@ -3132,7 +3191,6 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv->RefPicList0_count = 0; priv->RefPicList1_count = 0; priv->nal_length_size = 0; - priv->adapter = NULL; priv->field_poc[0] = 0; priv->field_poc[1] = 0; priv->poc_msb = 0; From 94982b5c0590a9ecfe0485fbab4f4ab65f107409 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 6 Dec 2012 14:02:21 +0100 Subject: [PATCH 0935/3781] vc1: initial port to new GstVaapiDecoder API --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 206 ++++++++++++++--------- 1 file changed, 124 insertions(+), 82 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 4949a288dc..b8b86cf0c2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -29,6 +29,7 @@ #include #include "gstvaapidecoder_vc1.h" #include "gstvaapidecoder_objects.h" +#include "gstvaapidecoder_unit.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" @@ -56,13 +57,12 @@ struct _GstVaapiDecoderVC1Private { GstVaapiPicture *current_picture; GstVaapiPicture *next_picture; GstVaapiPicture *prev_picture; - GstAdapter *adapter; - GstBuffer *sub_buffer; guint8 *rbdu_buffer; guint rbdu_buffer_size; guint is_constructed : 1; guint is_opened : 1; guint is_first_field : 1; + guint has_codec_data : 1; guint has_entrypoint : 1; guint size_changed : 1; guint profile_changed : 1; @@ -101,34 +101,19 @@ gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder) gst_vaapi_picture_replace(&priv->next_picture, NULL); gst_vaapi_picture_replace(&priv->prev_picture, NULL); - if (priv->sub_buffer) { - gst_buffer_unref(priv->sub_buffer); - priv->sub_buffer = NULL; - } - if (priv->bitplanes) { gst_vc1_bitplanes_free(priv->bitplanes); priv->bitplanes = NULL; } - - if (priv->adapter) { - gst_adapter_clear(priv->adapter); - g_object_unref(priv->adapter); - priv->adapter = NULL; - } } static gboolean -gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) +gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder) { GstVaapiDecoderVC1Private * const priv = decoder->priv; gst_vaapi_decoder_vc1_close(decoder); - priv->adapter = gst_adapter_new(); - if (!priv->adapter) - return FALSE; - priv->bitplanes = gst_vc1_bitplanes_new(); if (!priv->bitplanes) return FALSE; @@ -861,7 +846,6 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) GstVaapiSlice *slice; GstVaapiDecoderStatus status; VASliceParameterBufferVC1 *slice_param; - GstClockTime pts; status = ensure_context(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { @@ -922,8 +906,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) } /* Update presentation time */ - pts = gst_adapter_prev_timestamp(priv->adapter, NULL); - picture->pts = pts; + picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; /* Update reference pictures */ if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { @@ -1046,71 +1029,26 @@ static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) { GstVaapiDecoderVC1Private * const priv = decoder->priv; - GstVaapiDecoderStatus status; - GstVC1ParserResult result; GstVC1BDU ebdu; - GstBuffer *codec_data; guchar *buf; - guint buf_size, ofs; + guint buf_size; buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); - if (!buf && buf_size == 0) - return decode_sequence_end(decoder); - gst_buffer_ref(buffer); - gst_adapter_push(priv->adapter, buffer); - - /* Assume demuxer sends out plain frames if codec-data */ - codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); - if (codec_data && codec_data != buffer) { + if (priv->has_codec_data) { ebdu.type = GST_VC1_FRAME; - ebdu.size = buf_size; ebdu.sc_offset = 0; ebdu.offset = 0; - ebdu.data = buf; - status = decode_ebdu(decoder, &ebdu); - - if (gst_adapter_available(priv->adapter) >= buf_size) - gst_adapter_flush(priv->adapter, buf_size); - return status; } - - if (priv->sub_buffer) { - buffer = gst_buffer_merge(priv->sub_buffer, buffer); - if (!buffer) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - gst_buffer_unref(priv->sub_buffer); - priv->sub_buffer = NULL; + else { + ebdu.type = buf[3]; + ebdu.sc_offset = 0; + ebdu.offset = 4; } - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - ofs = 0; - do { - result = gst_vc1_identify_next_bdu( - buf + ofs, - buf_size - ofs, - &ebdu - ); - status = get_status(result); - - if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) { - priv->sub_buffer = gst_buffer_create_sub(buffer, ofs, buf_size - ofs); - break; - } - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - break; - - ofs += ebdu.offset + ebdu.size; - if (gst_adapter_available(priv->adapter) >= ebdu.offset) - gst_adapter_flush(priv->adapter, ebdu.offset); - - status = decode_ebdu(decoder, &ebdu); - if (gst_adapter_available(priv->adapter) >= ebdu.size) - gst_adapter_flush(priv->adapter, ebdu.size); - } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); - return status; + ebdu.data = buf; + ebdu.size = buf_size; + return decode_ebdu(decoder, &ebdu); } static GstVaapiDecoderStatus @@ -1190,10 +1128,9 @@ decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) return status; } -GstVaapiDecoderStatus -gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base, GstBuffer *buffer) +static GstVaapiDecoderStatus +ensure_decoder(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base); GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVaapiDecoderStatus status; GstBuffer *codec_data; @@ -1202,7 +1139,7 @@ gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base, GstBuffer *buffer) GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); if (!priv->is_opened) { - priv->is_opened = gst_vaapi_decoder_vc1_open(decoder, buffer); + priv->is_opened = gst_vaapi_decoder_vc1_open(decoder); if (!priv->is_opened) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; @@ -1211,9 +1148,115 @@ gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base, GstBuffer *buffer) status = decode_codec_data(decoder, codec_data); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; + priv->has_codec_data = TRUE; } } - return decode_buffer(decoder, buffer); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static inline gint +scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) +{ + return (gint)gst_adapter_masked_scan_uint32_peek(adapter, + 0xffffff00, 0x00000100, ofs, size, scp); +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_vc1_parse(GstVaapiDecoder *base_decoder, + GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) +{ + GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + GstVaapiDecoderUnit *unit; + guint8 bdu_type; + guint size, buf_size, flags = 0; + gint ofs; + + status = ensure_decoder(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + size = gst_adapter_available(adapter); + + if (priv->has_codec_data) { + // Assume demuxer sends out plain frames + if (size < 1) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + buf_size = size; + bdu_type = GST_VC1_FRAME; + } + else { + if (size < 4) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + ofs = scan_for_start_code(adapter, 0, size, NULL); + if (ofs < 0) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + gst_adapter_flush(adapter, ofs); + size -= ofs; + + ofs = G_UNLIKELY(size < 8) ? -1 : + scan_for_start_code(adapter, 4, size - 4, NULL); + if (ofs < 0) { + // Assume the whole packet is present if end-of-stream + if (!at_eos) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + ofs = size; + } + buf_size = ofs; + gst_adapter_copy(adapter, &bdu_type, 3, 1); + } + + unit = gst_vaapi_decoder_unit_new(buf_size); + if (!unit) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + /* Check for new picture layer */ + switch (bdu_type) { + case GST_VC1_END_OF_SEQ: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; + break; + case GST_VC1_SEQUENCE: + case GST_VC1_ENTRYPOINT: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; + case GST_VC1_FRAME: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + break; + case GST_VC1_SLICE: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + break; + } + GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); + + *unit_ptr = unit; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base_decoder, + GstVaapiDecoderUnit *unit) +{ + GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); + GstVaapiDecoderStatus status; + + status = ensure_decoder(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + unit->buffer = gst_buffer_create_sub( + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, + unit->offset, unit->size); + if (!unit->buffer) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + status = decode_buffer(decoder, unit->buffer); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static void @@ -1251,6 +1294,7 @@ gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass) object_class->finalize = gst_vaapi_decoder_vc1_finalize; object_class->constructed = gst_vaapi_decoder_vc1_constructed; + decoder_class->parse = gst_vaapi_decoder_vc1_parse; decoder_class->decode = gst_vaapi_decoder_vc1_decode; } @@ -1267,8 +1311,6 @@ gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder) priv->current_picture = NULL; priv->next_picture = NULL; priv->prev_picture = NULL; - priv->adapter = NULL; - priv->sub_buffer = NULL; priv->rbdu_buffer = NULL; priv->rbdu_buffer_size = 0; priv->is_constructed = FALSE; From ddc74f8a20be07ba9ae52d77c380b4f9d215cd52 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 6 Dec 2012 14:02:25 +0100 Subject: [PATCH 0936/3781] jpeg: initial port to new GstVaapiDecoder API --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 105 ++++++++++++++++++---- 1 file changed, 90 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index ddeb24dacc..936ba10d02 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -87,7 +87,7 @@ gst_vaapi_decoder_jpeg_close(GstVaapiDecoderJpeg *decoder) } static gboolean -gst_vaapi_decoder_jpeg_open(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) +gst_vaapi_decoder_jpeg_open(GstVaapiDecoderJpeg *decoder) { gst_vaapi_decoder_jpeg_close(decoder); @@ -315,8 +315,7 @@ decode_picture( GstVaapiDecoderJpeg *decoder, guint8 profile, guchar *buf, - guint buf_size, - GstClockTime pts + guint buf_size ) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; @@ -362,7 +361,7 @@ decode_picture( return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; /* Update presentation time */ - picture->pts = pts; + picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -497,19 +496,15 @@ decode_buffer(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; GstJpegMarkerSegment seg; GstJpegScanSegment scan_seg; - GstClockTime pts; guchar *buf; guint buf_size, ofs; gboolean append_ecs; buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); - if (!buf && buf_size == 0) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; memset(&scan_seg, 0, sizeof(scan_seg)); - pts = GST_BUFFER_TIMESTAMP(buffer); ofs = 0; while (gst_jpeg_parse(&seg, buf, buf_size, ofs)) { if (seg.size < 0) { @@ -586,8 +581,7 @@ decode_buffer(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) status = decode_picture( decoder, seg.marker, - buf + seg.offset, seg.size, - pts + buf + seg.offset, seg.size ); break; } @@ -615,18 +609,98 @@ end: return status; } -GstVaapiDecoderStatus -gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base, GstBuffer *buffer) +static GstVaapiDecoderStatus +ensure_decoder(GstVaapiDecoderJpeg *decoder) { - GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(base); GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + g_return_val_if_fail(priv->is_constructed, + GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); + if (!priv->is_opened) { - priv->is_opened = gst_vaapi_decoder_jpeg_open(decoder, buffer); + priv->is_opened = gst_vaapi_decoder_jpeg_open(decoder); if (!priv->is_opened) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; } - return decode_buffer(decoder, buffer); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static inline gint +scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) +{ + return (gint)gst_adapter_masked_scan_uint32_peek(adapter, + 0xffff0000, 0xffd80000, ofs, size, scp); +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder, + GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) +{ + GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(base_decoder); + GstVaapiDecoderStatus status; + GstVaapiDecoderUnit *unit; + guint size, buf_size, flags = 0; + gint ofs; + + status = ensure_decoder(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + /* Expect at least 4 bytes, SOI .. EOI */ + size = gst_adapter_available(adapter); + if (size < 4) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + ofs = scan_for_start_code(adapter, 0, size, NULL); + if (ofs < 0) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + gst_adapter_flush(adapter, ofs); + size -= ofs; + + ofs = G_UNLIKELY(size < 4) ? -1 : + scan_for_start_code(adapter, 2, size - 2, NULL); + if (ofs < 0) { + // Assume the whole packet is present if end-of-stream + if (!at_eos) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + ofs = size; + } + buf_size = ofs; + + unit = gst_vaapi_decoder_unit_new(buf_size); + if (!unit) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); + + *unit_ptr = unit; + 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(base_decoder); + GstVaapiDecoderStatus status; + + status = ensure_decoder(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + unit->buffer = gst_buffer_create_sub( + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, + unit->offset, unit->size); + if (!unit->buffer) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + status = decode_buffer(decoder, unit->buffer); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static void @@ -664,6 +738,7 @@ gst_vaapi_decoder_jpeg_class_init(GstVaapiDecoderJpegClass *klass) object_class->finalize = gst_vaapi_decoder_jpeg_finalize; object_class->constructed = gst_vaapi_decoder_jpeg_constructed; + decoder_class->parse = gst_vaapi_decoder_jpeg_parse; decoder_class->decode = gst_vaapi_decoder_jpeg_decode; } From 9127f17d8158e10861f1a65201f8d6c02e7573f0 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 4 Dec 2012 14:45:29 +0100 Subject: [PATCH 0937/3781] vaapidecode: move to GstVideoDecoder base class. Make vaapidecode derive from the standard GstVideoDecoder base element class. This simplifies the code to the strict minimum for the decoder element and makes it easier to port to GStreamer 1.x API. Signed-off-by: Sreerenj Balachandran Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 385 +++++++++++++++---------------------- gst/vaapi/gstvaapidecode.h | 8 +- 2 files changed, 160 insertions(+), 233 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3eb6683b34..f8d24e317a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -98,7 +98,7 @@ gst_video_context_interface_init(GstVideoContextInterface *iface); G_DEFINE_TYPE_WITH_CODE( GstVaapiDecode, gst_vaapidecode, - GST_TYPE_ELEMENT, + GST_TYPE_VIDEO_DECODER, G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapidecode_implements_iface_init); G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, @@ -131,43 +131,46 @@ gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps) static gboolean gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) { - GstCaps *other_caps; - GstStructure *structure; - const GValue *v_width, *v_height, *v_framerate, *v_par, *v_interlaced; - gboolean success; + GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); + GstVideoCodecState *state, *ref_state; + GstVideoInfo info; - if (!decode->srcpad_caps) { - decode->srcpad_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); - if (!decode->srcpad_caps) - return FALSE; - } + if (!gst_video_info_from_caps(&info, caps)) + return FALSE; - structure = gst_caps_get_structure(caps, 0); - v_width = gst_structure_get_value(structure, "width"); - v_height = gst_structure_get_value(structure, "height"); - v_framerate = gst_structure_get_value(structure, "framerate"); - v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); - v_interlaced = gst_structure_get_value(structure, "interlaced"); + ref_state = g_slice_new0(GstVideoCodecState); + ref_state->ref_count = 1; + ref_state->info = info; - structure = gst_caps_get_structure(decode->srcpad_caps, 0); - if (v_width && v_height) { - gst_structure_set_value(structure, "width", v_width); - gst_structure_set_value(structure, "height", v_height); - } - if (v_framerate) - gst_structure_set_value(structure, "framerate", v_framerate); - if (v_par) - gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); - if (v_interlaced) - gst_structure_set_value(structure, "interlaced", v_interlaced); + state = gst_video_decoder_set_output_state(vdec, + GST_VIDEO_INFO_FORMAT(&info), info.width, info.height, ref_state); + gst_video_codec_state_unref(ref_state); + if (!state) + return FALSE; - gst_structure_set(structure, "type", G_TYPE_STRING, "vaapi", NULL); - gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_GLX, NULL); + gst_video_codec_state_unref(state); - other_caps = gst_caps_copy(decode->srcpad_caps); - success = gst_pad_set_caps(decode->srcpad, other_caps); - gst_caps_unref(other_caps); - return success; + /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not + reconstruct suitable caps for "encoded" video formats */ + state->caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); + if (!state->caps) + return FALSE; + + gst_caps_set_simple(state->caps, + "type", G_TYPE_STRING, "vaapi", + "opengl", G_TYPE_BOOLEAN, USE_GLX, + "width", G_TYPE_INT, info.width, + "height", G_TYPE_INT, info.height, + "framerate", GST_TYPE_FRACTION, info.fps_n, info.fps_d, + "pixel-aspect-ratio", GST_TYPE_FRACTION, info.par_n, info.par_d, + NULL); + + if (GST_VIDEO_INFO_IS_INTERLACED(&info)) + gst_caps_set_simple(state->caps, "interlaced", G_TYPE_BOOLEAN, + TRUE, NULL); + + gst_caps_replace(&decode->srcpad_caps, state->caps); + return TRUE; } static void @@ -179,13 +182,13 @@ gst_vaapidecode_release(GstVaapiDecode *decode) } static GstFlowReturn -gst_vaapidecode_step(GstVaapiDecode *decode) +gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) { + GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstVaapiSurfaceProxy *proxy; GstVaapiDecoderStatus status; - GstBuffer *buffer; + GstVideoCodecFrame *out_frame; GstFlowReturn ret; - GstClockTime timestamp; gint64 end_time; for (;;) { @@ -195,56 +198,51 @@ gst_vaapidecode_step(GstVaapiDecode *decode) end_time += GST_TIME_AS_USECONDS(decode->last_buffer_time); end_time += G_TIME_SPAN_SECOND; - proxy = gst_vaapi_decoder_get_surface(decode->decoder, &status); - if (!proxy) { - if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { - gboolean was_signalled; - g_mutex_lock(&decode->decoder_mutex); - was_signalled = g_cond_wait_until( - &decode->decoder_ready, - &decode->decoder_mutex, - end_time - ); - g_mutex_unlock(&decode->decoder_mutex); - if (was_signalled) - continue; - goto error_decode_timeout; - } - if (status != GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) - goto error_decode; - /* More data is needed */ - break; + status = gst_vaapi_decoder_decode(decode->decoder, frame, &proxy); + if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { + gboolean was_signalled; + g_mutex_lock(&decode->decoder_mutex); + was_signalled = g_cond_wait_until( + &decode->decoder_ready, + &decode->decoder_mutex, + end_time + ); + g_mutex_unlock(&decode->decoder_mutex); + if (was_signalled) + continue; + goto error_decode_timeout; } + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto error_decode; + + /* Current frame was decoded but no surface was output */ + if (!proxy) + break; + + out_frame = gst_vaapi_surface_proxy_get_user_data(proxy); gst_vaapi_surface_proxy_set_user_data(proxy, decode, (GDestroyNotify)gst_vaapidecode_release); - buffer = gst_vaapi_video_buffer_new(decode->display); - if (!buffer) + out_frame->output_buffer = gst_vaapi_video_buffer_new(decode->display); + if (!out_frame->output_buffer) goto error_create_buffer; - timestamp = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); - if (!decode->render_time_base) - decode->render_time_base = g_get_monotonic_time(); - decode->last_buffer_time = timestamp; - - GST_BUFFER_TIMESTAMP(buffer) = timestamp; - GST_BUFFER_DURATION(buffer) = GST_VAAPI_SURFACE_PROXY_DURATION(proxy); - gst_buffer_set_caps(buffer, GST_PAD_CAPS(decode->srcpad)); + out_frame->pts = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); + out_frame->duration = GST_VAAPI_SURFACE_PROXY_DURATION(proxy); if (GST_VAAPI_SURFACE_PROXY_TFF(proxy)) - GST_BUFFER_FLAG_SET(buffer, GST_VIDEO_BUFFER_TFF); + GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, + GST_VIDEO_CODEC_FRAME_FLAG_TFF); gst_vaapi_video_buffer_set_surface_proxy( - GST_VAAPI_VIDEO_BUFFER(buffer), - proxy - ); + GST_VAAPI_VIDEO_BUFFER(out_frame->output_buffer), proxy); + gst_vaapi_surface_proxy_unref(proxy); - ret = gst_pad_push(decode->srcpad, buffer); + ret = gst_video_decoder_finish_frame(vdec, out_frame); if (ret != GST_FLOW_OK) goto error_commit_buffer; - - gst_vaapi_surface_proxy_unref(proxy); + break; } return GST_FLOW_OK; @@ -268,6 +266,7 @@ error_decode: ret = GST_FLOW_UNEXPECTED; break; } + gst_video_decoder_drop_frame(vdec, frame); return ret; } error_create_buffer: @@ -278,13 +277,13 @@ error_create_buffer: GST_DEBUG("video sink failed to create video buffer for proxy'ed " "surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); - gst_vaapi_surface_proxy_unref(proxy); + gst_video_decoder_drop_frame(vdec, out_frame); return GST_FLOW_UNEXPECTED; } error_commit_buffer: { GST_DEBUG("video sink rejected the video buffer (error %d)", ret); - gst_vaapi_surface_proxy_unref(proxy); + gst_video_decoder_drop_frame(vdec, out_frame); return GST_FLOW_UNEXPECTED; } } @@ -353,7 +352,6 @@ static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { if (decode->decoder) { - (void)gst_vaapi_decoder_put_buffer(decode->decoder, NULL); g_object_unref(decode->decoder); decode->decoder = NULL; } @@ -384,18 +382,6 @@ gst_vaapidecode_reset(GstVaapiDecode *decode, GstCaps *caps) return gst_vaapidecode_create(decode, caps); } -static gboolean -gst_vaapidecode_flush(GstVaapiDecode *decode) -{ - g_return_val_if_fail(decode->decoder, FALSE); - - if (!gst_vaapi_decoder_put_buffer(decode->decoder, NULL)) - return FALSE; - if (gst_vaapidecode_step(decode) != GST_FLOW_OK) - return FALSE; - return TRUE; -} - /* GstImplementsInterface interface */ static gboolean @@ -453,53 +439,84 @@ gst_vaapidecode_finalize(GObject *object) decode->allowed_caps = NULL; } - if (decode->delayed_new_seg) { - gst_event_unref(decode->delayed_new_seg); - decode->delayed_new_seg = NULL; - } - g_cond_clear(&decode->decoder_ready); g_mutex_clear(&decode->decoder_mutex); G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object); } -static GstStateChangeReturn -gst_vaapidecode_change_state(GstElement *element, GstStateChange transition) +static gboolean +gst_vaapidecode_open(GstVideoDecoder *vdec) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(element); - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - decode->is_ready = TRUE; + decode->is_ready = TRUE; + return TRUE; +} + +static gboolean +gst_vaapidecode_close(GstVideoDecoder *vdec) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + + gst_vaapidecode_destroy(decode); + g_clear_object(&decode->display); + decode->is_ready = FALSE; + return TRUE; +} + +static gboolean +gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + GstCaps * const caps = state->caps; + + if (!gst_vaapidecode_update_sink_caps(decode, caps)) + return FALSE; + if (!gst_vaapidecode_update_src_caps(decode, caps)) + return FALSE; + if (!gst_vaapidecode_reset(decode, decode->sinkpad_caps)) + return FALSE; + return TRUE; +} + +static GstFlowReturn +gst_vaapidecode_parse(GstVideoDecoder *vdec, + GstVideoCodecFrame *frame, GstAdapter *adapter, gboolean at_eos) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + GstVaapiDecoderStatus status; + GstFlowReturn ret; + guint got_unit_size; + gboolean got_frame; + + status = gst_vaapi_decoder_parse(decode->decoder, frame, + adapter, at_eos, &got_unit_size, &got_frame); + + switch (status) { + case GST_VAAPI_DECODER_STATUS_SUCCESS: + if (got_unit_size > 0) + gst_video_decoder_add_to_frame(vdec, got_unit_size); + if (got_frame) + ret = gst_video_decoder_have_frame(vdec); + else + ret = GST_FLOW_OK; break; - case GST_STATE_CHANGE_READY_TO_PAUSED: + case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: + ret = GST_VIDEO_DECODER_FLOW_NEED_DATA; break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: + GST_WARNING("parse error %d", status); + ret = GST_FLOW_NOT_SUPPORTED; break; default: + GST_ERROR("parse error %d", status); + ret = GST_FLOW_UNEXPECTED; break; } - - ret = GST_ELEMENT_CLASS(gst_vaapidecode_parent_class)->change_state(element, transition); - if (ret != GST_STATE_CHANGE_SUCCESS) - return ret; - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_NULL: - gst_vaapidecode_destroy(decode); - g_clear_object(&decode->display); - decode->is_ready = FALSE; - break; - default: - break; - } - return GST_STATE_CHANGE_SUCCESS; + return ret; } static void @@ -507,14 +524,19 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstVideoDecoderClass * const vdec_class = GST_VIDEO_DECODER_CLASS(klass); GstPadTemplate *pad_template; GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - object_class->finalize = gst_vaapidecode_finalize; + object_class->finalize = gst_vaapidecode_finalize; - element_class->change_state = gst_vaapidecode_change_state; + vdec_class->open = GST_DEBUG_FUNCPTR(gst_vaapidecode_open); + vdec_class->close = GST_DEBUG_FUNCPTR(gst_vaapidecode_close); + vdec_class->set_format = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_format); + vdec_class->parse = GST_DEBUG_FUNCPTR(gst_vaapidecode_parse); + vdec_class->handle_frame = GST_DEBUG_FUNCPTR(gst_vaapidecode_handle_frame); gst_element_class_set_details_simple( element_class, @@ -610,90 +632,6 @@ gst_vaapidecode_get_caps(GstPad *pad) return gst_caps_ref(decode->allowed_caps); } -static gboolean -gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) -{ - GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); - - g_return_val_if_fail(pad == decode->sinkpad, FALSE); - - if (!gst_vaapidecode_update_sink_caps(decode, caps)) - return FALSE; - if (!gst_vaapidecode_update_src_caps(decode, caps)) - return FALSE; - if (!gst_vaapidecode_reset(decode, decode->sinkpad_caps)) - return FALSE; - - /* Propagate NEWSEGMENT event downstream, now that pads are linked */ - if (decode->delayed_new_seg) { - if (gst_pad_push_event(decode->srcpad, decode->delayed_new_seg)) - gst_event_unref(decode->delayed_new_seg); - decode->delayed_new_seg = NULL; - } - return TRUE; -} - -static GstFlowReturn -gst_vaapidecode_chain(GstPad *pad, GstBuffer *buf) -{ - GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); - - if (!gst_vaapi_decoder_put_buffer(decode->decoder, buf)) - goto error_push_buffer; - - gst_buffer_unref(buf); - return gst_vaapidecode_step(decode); - - /* ERRORS */ -error_push_buffer: - { - GST_DEBUG("failed to push input buffer to decoder"); - gst_buffer_unref(buf); - return GST_FLOW_UNEXPECTED; - } -} - -static gboolean -gst_vaapidecode_sink_event(GstPad *pad, GstEvent *event) -{ - GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); - - GST_DEBUG("handle sink event '%s'", GST_EVENT_TYPE_NAME(event)); - - /* Propagate event downstream */ - switch (GST_EVENT_TYPE(event)) { - case GST_EVENT_NEWSEGMENT: - if (decode->delayed_new_seg) { - gst_event_unref(decode->delayed_new_seg); - decode->delayed_new_seg = NULL; - } - if (!GST_PAD_PEER(decode->srcpad)) { - decode->delayed_new_seg = gst_event_ref(event); - return TRUE; - } - break; - case GST_EVENT_EOS: - if (!gst_vaapidecode_flush(decode)) { - GST_WARNING("failed to flush buffers"); - } - break; - default: - break; - } - return gst_pad_push_event(decode->srcpad, event); -} - -static gboolean -gst_vaapidecode_src_event(GstPad *pad, GstEvent *event) -{ - GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); - - GST_DEBUG("handle src event '%s'", GST_EVENT_TYPE_NAME(event)); - - /* Propagate event upstream */ - return gst_pad_push_event(decode->sinkpad, event); -} - static gboolean gst_vaapidecode_query (GstPad *pad, GstQuery *query) { GstVaapiDecode *decode = GST_VAAPIDECODE (gst_pad_get_parent_element (pad)); @@ -703,8 +641,10 @@ gst_vaapidecode_query (GstPad *pad, GstQuery *query) { if (gst_vaapi_reply_to_query (query, decode->display)) res = TRUE; + else if (GST_PAD_IS_SINK(pad)) + res = decode->sinkpad_query(decode->sinkpad, query); else - res = gst_pad_query_default (pad, query); + res = decode->srcpad_query(decode->srcpad, query); g_object_unref (decode); return res; @@ -713,14 +653,12 @@ gst_vaapidecode_query (GstPad *pad, GstQuery *query) { static void gst_vaapidecode_init(GstVaapiDecode *decode) { - GstVaapiDecodeClass *klass = GST_VAAPIDECODE_GET_CLASS(decode); - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); decode->display = NULL; decode->decoder = NULL; decode->decoder_caps = NULL; decode->allowed_caps = NULL; - decode->delayed_new_seg = NULL; decode->render_time_base = 0; decode->last_buffer_time = 0; decode->is_ready = FALSE; @@ -728,29 +666,16 @@ gst_vaapidecode_init(GstVaapiDecode *decode) g_mutex_init(&decode->decoder_mutex); g_cond_init(&decode->decoder_ready); - /* Pad through which data comes in to the element */ - decode->sinkpad = gst_pad_new_from_template( - gst_element_class_get_pad_template(element_class, "sink"), - "sink" - ); - decode->sinkpad_caps = NULL; + gst_video_decoder_set_packetized(vdec, FALSE); - gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps); - gst_pad_set_setcaps_function(decode->sinkpad, gst_vaapidecode_set_caps); - gst_pad_set_chain_function(decode->sinkpad, gst_vaapidecode_chain); - gst_pad_set_event_function(decode->sinkpad, gst_vaapidecode_sink_event); + /* Pad through which data comes in to the element */ + decode->sinkpad = GST_VIDEO_DECODER_SINK_PAD(vdec); + decode->sinkpad_query = GST_PAD_QUERYFUNC(decode->sinkpad); gst_pad_set_query_function(decode->sinkpad, gst_vaapidecode_query); - gst_element_add_pad(GST_ELEMENT(decode), decode->sinkpad); + gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps); /* Pad through which data goes out of the element */ - decode->srcpad = gst_pad_new_from_template( - gst_element_class_get_pad_template(element_class, "src"), - "src" - ); - decode->srcpad_caps = NULL; - - gst_pad_use_fixed_caps(decode->srcpad); - gst_pad_set_event_function(decode->srcpad, gst_vaapidecode_src_event); + decode->srcpad = GST_VIDEO_DECODER_SRC_PAD(vdec); + decode->srcpad_query = GST_PAD_QUERYFUNC(decode->srcpad); gst_pad_set_query_function(decode->srcpad, gst_vaapidecode_query); - gst_element_add_pad(GST_ELEMENT(decode), decode->srcpad); } diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 87e280724a..35adabac71 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -59,19 +60,20 @@ typedef struct _GstVaapiDecodeClass GstVaapiDecodeClass; struct _GstVaapiDecode { /*< private >*/ - GstElement parent_instance; + GstVideoDecoder parent_instance; GstPad *sinkpad; GstCaps *sinkpad_caps; + GstPadQueryFunction sinkpad_query; GstPad *srcpad; GstCaps *srcpad_caps; + GstPadQueryFunction srcpad_query; GstVaapiDisplay *display; GstVaapiDecoder *decoder; GMutex decoder_mutex; GCond decoder_ready; GstCaps *decoder_caps; GstCaps *allowed_caps; - GstEvent *delayed_new_seg; gint64 render_time_base; GstClockTime last_buffer_time; unsigned int is_ready : 1; @@ -79,7 +81,7 @@ struct _GstVaapiDecode { struct _GstVaapiDecodeClass { /*< private >*/ - GstElementClass parent_class; + GstVideoDecoderClass parent_class; }; GType From cfdc5c5b43bb094afd426c506681c3eb0fbef641 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 4 Dec 2012 14:53:15 +0100 Subject: [PATCH 0938/3781] vaapidecode: use more standard helpers. Use g_clear_object() [glib >= 2.28] and gst_caps_replace() helper functions in more places. --- gst/vaapi/gstvaapidecode.c | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f8d24e317a..aaa6fc6f00 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -122,9 +122,7 @@ gst_vaapi_decoder_notify_caps(GObject *obj, GParamSpec *pspec, void *user_data) static inline gboolean gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps) { - if (decode->sinkpad_caps) - gst_caps_unref(decode->sinkpad_caps); - decode->sinkpad_caps = gst_caps_ref(caps); + gst_caps_replace(&decode->sinkpad_caps, caps); return TRUE; } @@ -351,16 +349,8 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { - if (decode->decoder) { - g_object_unref(decode->decoder); - decode->decoder = NULL; - } - - if (decode->decoder_caps) { - gst_caps_unref(decode->decoder_caps); - decode->decoder_caps = NULL; - } - + g_clear_object(&decode->decoder); + gst_caps_replace(&decode->decoder_caps, NULL); gst_vaapidecode_release(decode); } @@ -422,23 +412,12 @@ gst_vaapidecode_finalize(GObject *object) gst_vaapidecode_destroy(decode); - if (decode->sinkpad_caps) { - gst_caps_unref(decode->sinkpad_caps); - decode->sinkpad_caps = NULL; - } - - if (decode->srcpad_caps) { - gst_caps_unref(decode->srcpad_caps); - decode->srcpad_caps = NULL; - } + gst_caps_replace(&decode->sinkpad_caps, NULL); + gst_caps_replace(&decode->srcpad_caps, NULL); + gst_caps_replace(&decode->allowed_caps, NULL); g_clear_object(&decode->display); - if (decode->allowed_caps) { - gst_caps_unref(decode->allowed_caps); - decode->allowed_caps = NULL; - } - g_cond_clear(&decode->decoder_ready); g_mutex_clear(&decode->decoder_mutex); From cb3c0a3e8f2580660af90d25ee47ff3309ae1e4d Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 12 Dec 2012 15:22:32 +0100 Subject: [PATCH 0939/3781] vaapidecode: use gst_vaapi_decoder_get_codec_state(). Directly use the GstVideoCodecState associated with the VA decoder instead of parsing caps again. Signed-off-by: Sreerenj Balachandran Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 44 +++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index aaa6fc6f00..569d1e6b6a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -105,18 +105,20 @@ G_DEFINE_TYPE_WITH_CODE( gst_video_context_interface_init)) static gboolean -gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps); +gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, + GstVideoCodecState *ref_state); static void gst_vaapi_decoder_notify_caps(GObject *obj, GParamSpec *pspec, void *user_data) { GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data); - GstCaps *caps; + GstVideoCodecState *codec_state; g_assert(decode->decoder == GST_VAAPI_DECODER(obj)); - caps = gst_vaapi_decoder_get_caps(decode->decoder); - gst_vaapidecode_update_src_caps(decode, caps); + codec_state = gst_vaapi_decoder_get_codec_state(decode->decoder); + gst_vaapidecode_update_src_caps(decode, codec_state); + gst_video_codec_state_unref(codec_state); } static inline gboolean @@ -127,25 +129,20 @@ gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps) } static gboolean -gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) +gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, + GstVideoCodecState *ref_state) { GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); - GstVideoCodecState *state, *ref_state; - GstVideoInfo info; - - if (!gst_video_info_from_caps(&info, caps)) - return FALSE; - - ref_state = g_slice_new0(GstVideoCodecState); - ref_state->ref_count = 1; - ref_state->info = info; + GstVideoCodecState *state; + GstVideoInfo *vi; state = gst_video_decoder_set_output_state(vdec, - GST_VIDEO_INFO_FORMAT(&info), info.width, info.height, ref_state); - gst_video_codec_state_unref(ref_state); + GST_VIDEO_INFO_FORMAT(&ref_state->info), + ref_state->info.width, ref_state->info.height, ref_state); if (!state) return FALSE; + vi = &state->info; gst_video_codec_state_unref(state); /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not @@ -157,13 +154,13 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps) gst_caps_set_simple(state->caps, "type", G_TYPE_STRING, "vaapi", "opengl", G_TYPE_BOOLEAN, USE_GLX, - "width", G_TYPE_INT, info.width, - "height", G_TYPE_INT, info.height, - "framerate", GST_TYPE_FRACTION, info.fps_n, info.fps_d, - "pixel-aspect-ratio", GST_TYPE_FRACTION, info.par_n, info.par_d, + "width", G_TYPE_INT, vi->width, + "height", G_TYPE_INT, vi->height, + "framerate", GST_TYPE_FRACTION, vi->fps_n, vi->fps_d, + "pixel-aspect-ratio", GST_TYPE_FRACTION, vi->par_n, vi->par_d, NULL); - if (GST_VIDEO_INFO_IS_INTERLACED(&info)) + if (GST_VIDEO_INFO_IS_INTERLACED(vi)) gst_caps_set_simple(state->caps, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL); @@ -448,11 +445,10 @@ static gboolean gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - GstCaps * const caps = state->caps; - if (!gst_vaapidecode_update_sink_caps(decode, caps)) + if (!gst_vaapidecode_update_sink_caps(decode, state->caps)) return FALSE; - if (!gst_vaapidecode_update_src_caps(decode, caps)) + if (!gst_vaapidecode_update_src_caps(decode, state)) return FALSE; if (!gst_vaapidecode_reset(decode, decode->sinkpad_caps)) return FALSE; From d19c59ba318375f3a5ff2ba5baf5279828b7fa43 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 4 Dec 2012 11:01:42 +0100 Subject: [PATCH 0940/3781] vaapisink: handle sub video-buffers. Intermediate elements may produce a sub-buffer from a valid GstVaapiVideoBuffer for non raw YUV cases. Make sure vaapisink now understands those buffers. --- gst/vaapi/gstvaapisink.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index b74927ab1b..22284da093 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -854,32 +854,31 @@ gst_vaapisink_put_surface( } static GstFlowReturn -gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) +gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + GstVideoOverlayComposition *composition; GstVaapiVideoBuffer *vbuffer; GstVaapiSurface *surface; + GstBuffer *buffer; guint flags; gboolean success; - GstVideoOverlayComposition * const composition = - gst_video_buffer_get_overlay_composition(buffer); - if (!sink->use_video_raw) - buffer = gst_buffer_ref(buffer); - else { - GstBuffer * const src_buffer = buffer; - if (GST_VAAPI_IS_VIDEO_BUFFER(buffer)) - buffer = gst_buffer_ref(src_buffer); - else if (GST_VAAPI_IS_VIDEO_BUFFER(buffer->parent)) - buffer = gst_buffer_ref(src_buffer->parent); - else { - buffer = gst_vaapi_uploader_get_buffer(sink->uploader); - if (!buffer) - return GST_FLOW_UNEXPECTED; - } - if (!gst_vaapi_uploader_process(sink->uploader, src_buffer, buffer)) - goto error; - } + if (GST_VAAPI_IS_VIDEO_BUFFER(src_buffer)) + buffer = gst_buffer_ref(src_buffer); + else if (GST_VAAPI_IS_VIDEO_BUFFER(src_buffer->parent)) + buffer = gst_buffer_ref(src_buffer->parent); + else if (sink->use_video_raw) + buffer = gst_vaapi_uploader_get_buffer(sink->uploader); + else + buffer = NULL; + if (!buffer) + return GST_FLOW_UNEXPECTED; + + if (sink->use_video_raw && !gst_vaapi_uploader_process(sink->uploader, + src_buffer, buffer)) + goto error; + vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); g_return_val_if_fail(vbuffer != NULL, GST_FLOW_UNEXPECTED); @@ -902,6 +901,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) flags = gst_vaapi_video_buffer_get_render_flags(vbuffer); + composition = gst_video_buffer_get_overlay_composition(src_buffer); if (!gst_vaapi_surface_set_subpictures_from_composition(surface, composition, TRUE)) GST_WARNING("could not update subtitles"); From 63c455d28d977e550813cc09103bb188242c755b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 6 Dec 2012 17:25:01 +0100 Subject: [PATCH 0941/3781] h264: add codec specific decoder unit. Introduce new GstVaapiDecoderUnitH264 object, which holds the standard NAL unit header (GstH264NalUnit) and additional parsed header info. Besides, we now parse headers as early as in the _parse() function so that to avoid un-necessary creation of sub-buffers in _decode() for NAL units that are not slices. This is a performance win by ~+1.1% only. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 258 +++++++++++----------- 1 file changed, 127 insertions(+), 131 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index aca954fbe8..6b36c841b3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -42,6 +42,7 @@ typedef struct _GstVaapiFrameStore GstVaapiFrameStore; typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; +typedef struct _GstVaapiDecoderUnitH264 GstVaapiDecoderUnitH264; typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; typedef struct _GstVaapiSliceH264 GstVaapiSliceH264; @@ -49,6 +50,39 @@ typedef struct _GstVaapiSliceH264 GstVaapiSliceH264; #define TOP_FIELD 0 #define BOTTOM_FIELD 1 +/* ------------------------------------------------------------------------- */ +/* --- H.264 Decoder Units --- */ +/* ------------------------------------------------------------------------- */ + +struct _GstVaapiDecoderUnitH264 { + GstVaapiDecoderUnit base; + GstH264NalUnit nalu; + union { + GstH264SPS sps; + GstH264PPS pps; + GstH264SliceHdr slice_hdr; + } data; +}; + +static GstVaapiDecoderUnitH264 * +gst_vaapi_decoder_unit_h264_new(guint size) +{ + GstVaapiDecoderUnitH264 *unit; + + static const GstVaapiMiniObjectClass GstVaapiDecoderUnitH264Class = { + sizeof(GstVaapiDecoderUnitH264), + (GDestroyNotify)gst_vaapi_decoder_unit_finalize + }; + + unit = (GstVaapiDecoderUnitH264 *) + gst_vaapi_mini_object_new0(&GstVaapiDecoderUnitH264Class); + if (!unit) + return NULL; + + unit->base.size = size; + return unit; +} + /* ------------------------------------------------------------------------- */ /* --- H.264 Pictures --- */ /* ------------------------------------------------------------------------- */ @@ -413,15 +447,6 @@ G_DEFINE_TYPE(GstVaapiDecoderH264, struct _GstVaapiDecoderH264Private { GstH264NalParser *parser; - /* Last decoded SPS. May not be the last activated one. Just here because - it may not fit stack memory allocation in decode_sps() */ - GstH264SPS last_sps; - /* Last decoded PPS. May not be the last activated one. Just here because - it may not fit stack memory allocation in decode_pps() */ - GstH264PPS last_pps; - /* Temporary slice header. Just here because it may not fit stack - memory allocation in decode_slice() */ - GstH264SliceHdr temp_slice_hdr; GstVaapiPictureH264 *current_picture; GstVaapiFrameStore *prev_frame; GstVaapiFrameStore *dpb[16]; @@ -1059,16 +1084,15 @@ error: } static GstVaapiDecoderStatus -decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) +parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264SPS * const sps = &priv->last_sps; + GstH264SPS * const sps = &unit->data.sps; GstH264ParserResult result; - GST_DEBUG("decode SPS"); + GST_DEBUG("parse SPS"); - memset(sps, 0, sizeof(*sps)); - result = gst_h264_parser_parse_sps(priv->parser, nalu, sps, TRUE); + result = gst_h264_parser_parse_sps(priv->parser, &unit->nalu, sps, TRUE); if (result != GST_H264_PARSER_OK) return get_status(result); @@ -1077,16 +1101,15 @@ decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) } static GstVaapiDecoderStatus -decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) +parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264PPS * const pps = &priv->last_pps; + GstH264PPS * const pps = &unit->data.pps; GstH264ParserResult result; - GST_DEBUG("decode PPS"); + GST_DEBUG("parse PPS"); - memset(pps, 0, sizeof(*pps)); - result = gst_h264_parser_parse_pps(priv->parser, nalu, pps); + result = gst_h264_parser_parse_pps(priv->parser, &unit->nalu, pps); if (result != GST_H264_PARSER_OK) return get_status(result); @@ -1095,24 +1118,41 @@ decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) } static GstVaapiDecoderStatus -decode_sei(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) +parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstH264SEIMessage sei; GstH264ParserResult result; - GST_DEBUG("decode SEI"); + GST_DEBUG("parse SEI"); memset(&sei, 0, sizeof(sei)); - result = gst_h264_parser_parse_sei(priv->parser, nalu, &sei); + result = gst_h264_parser_parse_sei(priv->parser, &unit->nalu, &sei); if (result != GST_H264_PARSER_OK) { - GST_WARNING("failed to decode SEI, payload type:%d", sei.payloadType); + GST_WARNING("failed to parse SEI, payload type:%d", sei.payloadType); return get_status(result); } return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static GstVaapiDecoderStatus +parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) +{ + GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; + GstH264ParserResult result; + + GST_DEBUG("parse slice"); + + result = gst_h264_parser_parse_slice_hdr(priv->parser, &unit->nalu, + slice_hdr, TRUE, TRUE); + if (result != GST_H264_PARSER_OK) + return get_status(result); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderH264 *decoder) { @@ -2752,56 +2792,42 @@ fill_slice( } static GstVaapiDecoderStatus -decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) +decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; + GstH264NalUnit * const nalu = &unit->nalu; GstVaapiDecoderStatus status; GstVaapiPictureH264 *picture; GstVaapiSliceH264 *slice = NULL; - GstH264SliceHdr *slice_hdr; - GstH264ParserResult result; - gboolean is_first_slice = !priv->has_context; GST_DEBUG("slice (%u bytes)", nalu->size); - if (is_first_slice) { - slice_hdr = &priv->temp_slice_hdr; - memset(slice_hdr, 0, sizeof(*slice_hdr)); - result = gst_h264_parser_parse_slice_hdr(priv->parser, nalu, - slice_hdr, TRUE, TRUE); - if (result != GST_H264_PARSER_OK) { - status = get_status(result); - goto error; - } + if (!priv->got_sps || !priv->got_pps) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!priv->has_context) { status = ensure_context(decoder, slice_hdr->pps->sequence); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; } - slice = gst_vaapi_slice_h264_new( - decoder, - nalu->data + nalu->offset, - nalu->size - ); + unit->base.buffer = gst_buffer_create_sub( + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, + unit->base.offset, unit->base.size); + if (!unit->base.buffer) { + GST_ERROR("failed to allocate slice data"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + slice = gst_vaapi_slice_h264_new(decoder, + GST_BUFFER_DATA(unit->base.buffer) + nalu->offset, nalu->size); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } - slice_hdr = &slice->slice_hdr; - if (is_first_slice) - memcpy(slice_hdr, &priv->temp_slice_hdr, sizeof(*slice_hdr)); - else { - memset(slice_hdr, 0, sizeof(*slice_hdr)); - result = gst_h264_parser_parse_slice_hdr(priv->parser, nalu, - slice_hdr, TRUE, TRUE); - if (result != GST_H264_PARSER_OK) { - status = get_status(result); - goto error; - } - } - + slice->slice_hdr = *slice_hdr; if (is_new_picture(decoder, nalu, slice_hdr)) { status = decode_picture(decoder, nalu, slice_hdr); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) @@ -2835,79 +2861,36 @@ scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) } static GstVaapiDecoderStatus -decode_nalu(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu) +decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) { - GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiDecoderStatus status; - switch (nalu->type) { + switch (unit->nalu.type) { case GST_H264_NAL_SLICE_IDR: /* fall-through. IDR specifics are handled in init_picture() */ case GST_H264_NAL_SLICE: - if (!priv->got_sps || !priv->got_pps) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - status = decode_slice(decoder, nalu); - break; - case GST_H264_NAL_SPS: - status = decode_sps(decoder, nalu); - break; - case GST_H264_NAL_PPS: - status = decode_pps(decoder, nalu); - break; - case GST_H264_NAL_SEI: - status = decode_sei(decoder, nalu); + status = decode_slice(decoder, unit); break; case GST_H264_NAL_SEQ_END: status = decode_sequence_end(decoder); break; - case GST_H264_NAL_AU_DELIMITER: - /* skip all Access Unit NALs */ - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - case GST_H264_NAL_FILLER_DATA: - /* skip all Filler Data NALs */ + case GST_H264_NAL_SEI: status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; default: - GST_WARNING("unsupported NAL unit type %d", nalu->type); + GST_WARNING("unsupported NAL unit type %d", unit->nalu.type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } return status; } -static GstVaapiDecoderStatus -decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) -{ - GstVaapiDecoderH264Private * const priv = decoder->priv; - GstVaapiDecoderStatus status; - GstH264ParserResult result; - GstH264NalUnit nalu; - guchar *buf; - guint buf_size; - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - - if (priv->is_avc) - result = gst_h264_parser_identify_nalu_avc(priv->parser, - buf, 0, buf_size, priv->nal_length_size, &nalu); - else - result = gst_h264_parser_identify_nalu_unchecked(priv->parser, - buf, 0, buf_size, &nalu); - status = get_status(result); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - - return decode_nalu(decoder, &nalu); -} - static GstVaapiDecoderStatus decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiDecoderStatus status; - GstH264NalUnit nalu; + GstVaapiDecoderUnitH264 unit; GstH264ParserResult result; guchar *buf; guint buf_size; @@ -2935,15 +2918,15 @@ decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) result = gst_h264_parser_identify_nalu_avc( priv->parser, buf, ofs, buf_size, 2, - &nalu + &unit.nalu ); if (result != GST_H264_PARSER_OK) return get_status(result); - status = decode_sps(decoder, &nalu); + status = parse_sps(decoder, &unit); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - ofs = nalu.offset + nalu.size; + ofs = unit.nalu.offset + unit.nalu.size; } num_pps = buf[ofs]; @@ -2953,19 +2936,19 @@ decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) result = gst_h264_parser_identify_nalu_avc( priv->parser, buf, ofs, buf_size, 2, - &nalu + &unit.nalu ); if (result != GST_H264_PARSER_OK) return get_status(result); - status = decode_pps(decoder, &nalu); + status = parse_pps(decoder, &unit); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - ofs = nalu.offset + nalu.size; + ofs = unit.nalu.offset + unit.nalu.size; } priv->is_avc = TRUE; - return status; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus @@ -2999,9 +2982,8 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, { GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base_decoder); GstVaapiDecoderH264Private * const priv = decoder->priv; - GstVaapiDecoderUnit *unit; + GstVaapiDecoderUnitH264 *unit; GstVaapiDecoderStatus status; - GstH264NalUnit nalu; GstH264ParserResult result; guchar *buf; guint i, size, buf_size, nalu_size, flags; @@ -3054,24 +3036,45 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, if (!buf) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - unit = gst_vaapi_decoder_unit_new(buf_size); + unit = gst_vaapi_decoder_unit_h264_new(buf_size); if (!unit) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; if (priv->is_avc) result = gst_h264_parser_identify_nalu_avc(priv->parser, - buf, 0, buf_size, priv->nal_length_size, &nalu); + buf, 0, buf_size, priv->nal_length_size, &unit->nalu); else result = gst_h264_parser_identify_nalu_unchecked(priv->parser, - buf, 0, buf_size, &nalu); + buf, 0, buf_size, &unit->nalu); status = get_status(result); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { gst_vaapi_decoder_unit_unref(unit); return status; } + switch (unit->nalu.type) { + case GST_H264_NAL_SPS: + status = parse_sps(decoder, unit); + break; + case GST_H264_NAL_PPS: + status = parse_pps(decoder, unit); + break; + case GST_H264_NAL_SEI: + status = parse_sei(decoder, unit); + break; + case GST_H264_NAL_SLICE_IDR: + case GST_H264_NAL_SLICE: + status = parse_slice(decoder, unit); + break; + default: + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + flags = 0; - switch (nalu.type) { + switch (unit->nalu.type) { case GST_H264_NAL_AU_DELIMITER: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; /* fall-through */ @@ -3086,6 +3089,8 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, break; case GST_H264_NAL_SPS: case GST_H264_NAL_PPS: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + /* fall-through */ case GST_H264_NAL_SEI: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; @@ -3095,18 +3100,19 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, /* XXX: assume we got a new frame if first_mb_in_slice is set to zero, thus ignoring Arbitrary Slice Order (ASO) feature from Baseline profile */ - if (nalu.offset + 2 <= nalu.size && - (nalu.data[nalu.offset + 1] & 0x80)) + if (unit->nalu.offset + 2 <= unit->nalu.size && + (unit->nalu.data[unit->nalu.offset + 1] & 0x80)) flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; default: - if (nalu.type >= 14 && nalu.type <= 18) + if (unit->nalu.type >= 14 && unit->nalu.type <= 18) flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; } GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); - *unit_ptr = unit; + unit->nalu.data = NULL; + *unit_ptr = &unit->base; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -3120,17 +3126,7 @@ gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base_decoder, status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - - unit->buffer = gst_buffer_create_sub( - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, - unit->offset, unit->size); - if (!unit->buffer) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - - status = decode_buffer(decoder, unit->buffer); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + return decode_unit(decoder, (GstVaapiDecoderUnitH264 *)unit); } static void From f7f73931482550024fb71536b63a83dab1ea961d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 12 Dec 2012 18:33:52 +0100 Subject: [PATCH 0942/3781] h264: optimize scan for the second start code. Optimize scan for the second start code, on the next parse() call so that to avoid scanning again earlier bytes where we didn't find any start code. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 24 +++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 6b36c841b3..af57d2052a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2982,13 +2982,14 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, { GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base_decoder); GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiDecoderUnitH264 *unit; GstVaapiDecoderStatus status; GstH264ParserResult result; guchar *buf; guint i, size, buf_size, nalu_size, flags; guint32 start_code; - gint ofs; + gint ofs, ofs2; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) @@ -3015,22 +3016,33 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, else { if (size < 4) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + ofs = scan_for_start_code(adapter, 0, size, NULL); if (ofs < 0) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - gst_adapter_flush(adapter, ofs); - size -= ofs; - ofs = G_UNLIKELY(size < 8) ? -1 : - scan_for_start_code(adapter, 4, size - 4, NULL); + if (ofs > 0) { + gst_adapter_flush(adapter, ofs); + size -= ofs; + } + + ofs2 = ps->input_offset2 - ofs - 4; + if (ofs2 < 4) + ofs2 = 4; + + ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 : + scan_for_start_code(adapter, ofs2, size - ofs2, NULL); if (ofs < 0) { // Assume the whole NAL unit is present if end-of-stream - if (!at_eos) + if (!at_eos) { + ps->input_offset2 = size; return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } ofs = size; } buf_size = ofs; } + ps->input_offset2 = 0; buf = (guchar *)gst_adapter_peek(adapter, buf_size); if (!buf) From d9ec93fe4604c22e794499b5b4e948a38d026fd0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Dec 2012 10:21:46 +0100 Subject: [PATCH 0943/3781] h264: implement {start,end}_frame() hooks. Implement GstVaapiDecoder.start_frame() and end_frame() semantics so that to create new VA context earlier and submit VA pictures to the HW for decoding as soon as possible. i.e. don't wait for the next frame to start decoding the previous one. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 79 +++++++++++------------ 1 file changed, 36 insertions(+), 43 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index af57d2052a..9327a778d6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1058,15 +1058,10 @@ decode_current_picture(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiPictureH264 * const picture = priv->current_picture; - GstVaapiDecoderStatus status; if (!picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; - status = ensure_context(decoder, picture->pps->sequence); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - if (!exec_ref_pic_marking(decoder, picture)) goto error; if (!dpb_add(decoder, picture)) @@ -1165,7 +1160,7 @@ decode_sequence_end(GstVaapiDecoderH264 *decoder) return status; dpb_flush(decoder); - return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } /* 8.2.1.1 - Decoding process for picture order count type 0 */ @@ -2047,13 +2042,11 @@ init_picture_refs( static gboolean init_picture( GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr, - GstH264NalUnit *nalu -) + GstVaapiPictureH264 *picture, GstVaapiDecoderUnitH264 *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiPicture * const base_picture = &picture->base; + GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; priv->prev_frame_num = priv->frame_num; priv->frame_num = slice_hdr->frame_num; @@ -2063,7 +2056,7 @@ init_picture( base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; /* Reset decoder state for IDR pictures */ - if (nalu->type == GST_H264_NAL_SLICE_IDR) { + if (unit->nalu.type == GST_H264_NAL_SLICE_IDR) { GST_DEBUG(""); GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR); dpb_flush(decoder); @@ -2101,7 +2094,7 @@ init_picture( picture->structure = base_picture->structure; /* Initialize reference flags */ - if (nalu->ref_idc) { + if (unit->nalu.ref_idc) { GstH264DecRefPicMarking * const dec_ref_pic_marking = &slice_hdr->dec_ref_pic_marking; @@ -2442,15 +2435,12 @@ vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture, } static gboolean -fill_picture( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr, - GstH264NalUnit *nalu -) +fill_picture(GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, GstVaapiDecoderUnitH264 *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiPicture * const base_picture = &picture->base; + GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; GstH264PPS * const pps = picture->pps; GstH264SPS * const sps = pps->sequence; VAPictureParameterBufferH264 * const pic_param = base_picture->param; @@ -2596,17 +2586,14 @@ is_new_picture( } static GstVaapiDecoderStatus -decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceHdr *slice_hdr) +decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstVaapiPictureH264 *picture; - GstVaapiDecoderStatus status; + GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; - - status = decode_current_picture(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; + GstVaapiPictureH264 *picture; + GstVaapiDecoderStatus status; status = ensure_context(decoder, sps); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) @@ -2639,9 +2626,9 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceH return status; } - if (!init_picture(decoder, picture, slice_hdr, nalu)) + if (!init_picture(decoder, picture, unit)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - if (!fill_picture(decoder, picture, slice_hdr, nalu)) + if (!fill_picture(decoder, picture, unit)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2798,20 +2785,13 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; GstH264NalUnit * const nalu = &unit->nalu; GstVaapiDecoderStatus status; - GstVaapiPictureH264 *picture; - GstVaapiSliceH264 *slice = NULL; + GstVaapiSliceH264 *slice; GST_DEBUG("slice (%u bytes)", nalu->size); if (!priv->got_sps || !priv->got_pps) return GST_VAAPI_DECODER_STATUS_SUCCESS; - if (!priv->has_context) { - status = ensure_context(decoder, slice_hdr->pps->sequence); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - unit->base.buffer = gst_buffer_create_sub( GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, unit->base.offset, unit->base.size); @@ -2828,19 +2808,12 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) } slice->slice_hdr = *slice_hdr; - if (is_new_picture(decoder, nalu, slice_hdr)) { - status = decode_picture(decoder, nalu, slice_hdr); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - goto error; - } - picture = priv->current_picture; - if (!fill_slice(decoder, slice, nalu)) { status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; goto error; } gst_vaapi_picture_add_slice( - GST_VAAPI_PICTURE_CAST(picture), + GST_VAAPI_PICTURE_CAST(priv->current_picture), GST_VAAPI_SLICE_CAST(slice) ); return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -3141,6 +3114,24 @@ gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base_decoder, return decode_unit(decoder, (GstVaapiDecoderUnitH264 *)unit); } +static GstVaapiDecoderStatus +gst_vaapi_decoder_h264_start_frame(GstVaapiDecoder *base_decoder, + GstVaapiDecoderUnit *base_unit) +{ + GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base_decoder); + GstVaapiDecoderUnitH264 * const unit = (GstVaapiDecoderUnitH264 *)base_unit; + + return decode_picture(decoder, unit); +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_h264_end_frame(GstVaapiDecoder *base_decoder) +{ + GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base_decoder); + + return decode_current_picture(decoder); +} + static void gst_vaapi_decoder_h264_finalize(GObject *object) { @@ -3178,6 +3169,8 @@ gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass) decoder_class->parse = gst_vaapi_decoder_h264_parse; decoder_class->decode = gst_vaapi_decoder_h264_decode; + decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame; + decoder_class->end_frame = gst_vaapi_decoder_h264_end_frame; } static void From f8a9e49fd85bd98b0c1ebd21f481516f65350e75 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Dec 2012 10:47:25 +0100 Subject: [PATCH 0944/3781] h264: detect new pictures from decode-units. Update is_new_picture() to cope with GstVaapiDecoderUnitH264, instead of assuming frame boundaries when first_mb_in_slice is zero. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 40 +++++++++-------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 9327a778d6..5cb0fac720 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -448,6 +448,7 @@ G_DEFINE_TYPE(GstVaapiDecoderH264, struct _GstVaapiDecoderH264Private { GstH264NalParser *parser; GstVaapiPictureH264 *current_picture; + GstVaapiDecoderUnitH264 *prev_slice_unit; GstVaapiFrameStore *prev_frame; GstVaapiFrameStore *dpb[16]; guint dpb_count; @@ -796,6 +797,7 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) GstVaapiDecoderH264Private * const priv = decoder->priv; gst_vaapi_picture_replace(&priv->current_picture, NULL); + gst_vaapi_decoder_unit_replace(&priv->prev_slice_unit, NULL); dpb_clear(decoder); @@ -2510,25 +2512,17 @@ fill_picture(GstVaapiDecoderH264 *decoder, /* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */ static gboolean -is_new_picture( - GstVaapiDecoderH264 *decoder, - GstH264NalUnit *nalu, - GstH264SliceHdr *slice_hdr -) +is_new_picture(GstVaapiDecoderUnitH264 *unit, + GstVaapiDecoderUnitH264 *prev_unit) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; - GstVaapiSliceH264 *slice; GstH264SliceHdr *prev_slice_hdr; - if (!priv->current_picture) + if (!prev_unit) return TRUE; - - slice = gst_vaapi_picture_h264_get_last_slice(priv->current_picture); - if (!slice) - return FALSE; - prev_slice_hdr = &slice->slice_hdr; + prev_slice_hdr = &prev_unit->data.slice_hdr; #define CHECK_EXPR(expr, field_name) do { \ if (!(expr)) { \ @@ -2554,8 +2548,8 @@ is_new_picture( CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag); /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */ - CHECK_EXPR(((GST_VAAPI_PICTURE_IS_REFERENCE(priv->current_picture) ^ - (nalu->ref_idc != 0)) == 0), "nal_ref_idc"); + CHECK_EXPR((unit->nalu.ref_idc != 0) == + (prev_unit->nalu.ref_idc != 0), "nal_ref_idc"); /* POC type is 0 for both and either pic_order_cnt_lsb differs in value or delta_pic_order_cnt_bottom differs in value */ @@ -2573,11 +2567,10 @@ is_new_picture( } /* IdrPicFlag differs in value */ - CHECK_EXPR(((GST_VAAPI_PICTURE_IS_IDR(priv->current_picture) ^ - (nalu->type == GST_H264_NAL_SLICE_IDR)) == 0), "IdrPicFlag"); + CHECK_VALUE(&unit->nalu, &prev_unit->nalu, idr_pic_flag); /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */ - if (GST_VAAPI_PICTURE_IS_IDR(priv->current_picture)) + if (unit->nalu.idr_pic_flag) CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id); #undef CHECK_EXPR @@ -2789,8 +2782,10 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) GST_DEBUG("slice (%u bytes)", nalu->size); - if (!priv->got_sps || !priv->got_pps) + if (!priv->got_sps || !priv->got_pps) { + GST_ERROR("not initialized yet"); return GST_VAAPI_DECODER_STATUS_SUCCESS; + } unit->base.buffer = gst_buffer_create_sub( GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, @@ -3082,12 +3077,9 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, case GST_H264_NAL_SLICE_IDR: case GST_H264_NAL_SLICE: flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; - /* XXX: assume we got a new frame if first_mb_in_slice is set - to zero, thus ignoring Arbitrary Slice Order (ASO) feature - from Baseline profile */ - if (unit->nalu.offset + 2 <= unit->nalu.size && - (unit->nalu.data[unit->nalu.offset + 1] & 0x80)) + if (is_new_picture(unit, priv->prev_slice_unit)) flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + gst_vaapi_decoder_unit_replace(&priv->prev_slice_unit, unit); break; default: if (unit->nalu.type >= 14 && unit->nalu.type <= 18) From 4992e7c60f55f170acf87b316f74f3aafb0e7a1b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Dec 2012 17:45:03 +0100 Subject: [PATCH 0945/3781] h264: drop GstVaapiSliceH264 object. Use standard GstVaapiSlice object from now on since we already have parsed and recorded the slice headers (GstH264SliceHdr decode units). --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 134 ++++------------------ 1 file changed, 25 insertions(+), 109 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 5cb0fac720..93da0970dc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -44,7 +44,6 @@ typedef struct _GstVaapiFrameStore GstVaapiFrameStore; typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; typedef struct _GstVaapiDecoderUnitH264 GstVaapiDecoderUnitH264; typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; -typedef struct _GstVaapiSliceH264 GstVaapiSliceH264; // Used for field_poc[] #define TOP_FIELD 0 @@ -135,6 +134,7 @@ enum { struct _GstVaapiPictureH264 { GstVaapiPicture base; GstH264PPS *pps; + GstH264SliceHdr *last_slice_hdr; guint structure; gint32 field_poc[2]; gint32 frame_num; // Original frame_num from slice_header() @@ -220,77 +220,6 @@ gst_vaapi_picture_h264_new_field(GstVaapiPictureH264 *picture) return GST_VAAPI_PICTURE_H264_CAST(base_picture); } -static inline GstVaapiSliceH264 * -gst_vaapi_picture_h264_get_last_slice(GstVaapiPictureH264 *picture) -{ - g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL); - - if (G_UNLIKELY(picture->base.slices->len < 1)) - return NULL; - return g_ptr_array_index(picture->base.slices, - picture->base.slices->len - 1); -} - -/* ------------------------------------------------------------------------- */ -/* --- Slices --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_SLICE_H264_CAST(obj) \ - ((GstVaapiSliceH264 *)(obj)) - -#define GST_VAAPI_SLICE_H264(obj) \ - GST_VAAPI_SLICE_H264(obj) - -#define GST_VAAPI_IS_SLICE_H264(obj) \ - (GST_VAAPI_SLICE_H264(obj) != NULL) - -struct _GstVaapiSliceH264 { - GstVaapiSlice base; - GstH264SliceHdr slice_hdr; // parsed slice_header() -}; - -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSliceH264, gst_vaapi_slice_h264); - -void -gst_vaapi_slice_h264_destroy(GstVaapiSliceH264 *slice) -{ - gst_vaapi_slice_destroy(GST_VAAPI_SLICE(slice)); -} - -gboolean -gst_vaapi_slice_h264_create( - GstVaapiSliceH264 *slice, - const GstVaapiCodecObjectConstructorArgs *args -) -{ - if (!gst_vaapi_slice_create(GST_VAAPI_SLICE(slice), args)) - return FALSE; - return TRUE; -} - -static inline GstVaapiSliceH264 * -gst_vaapi_slice_h264_new( - GstVaapiDecoderH264 *decoder, - const guint8 *data, - guint data_size -) -{ - GstVaapiCodecObject *object; - - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - - object = gst_vaapi_codec_object_new( - &GstVaapiSliceH264Class, - GST_VAAPI_CODEC_BASE(decoder), - NULL, sizeof(VASliceParameterBufferH264), - data, data_size, - 0 - ); - if (!object) - return NULL; - return GST_VAAPI_SLICE_H264_CAST(object); -} - /* ------------------------------------------------------------------------- */ /* --- Frame Buffers (DPB) --- */ /* ------------------------------------------------------------------------- */ @@ -2372,10 +2301,8 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return TRUE; if (!GST_VAAPI_PICTURE_IS_IDR(picture)) { - GstVaapiSliceH264 * const slice = - gst_vaapi_picture_h264_get_last_slice(picture); GstH264DecRefPicMarking * const dec_ref_pic_marking = - &slice->slice_hdr.dec_ref_pic_marking; + &picture->last_slice_hdr->dec_ref_pic_marking; if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) { if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking)) return FALSE; @@ -2627,7 +2554,7 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) } static inline guint -get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, GstH264NalUnit *nalu) +get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr) { guint epb_count; @@ -2636,13 +2563,13 @@ get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, GstH264NalUnit *nalu) } static gboolean -fill_pred_weight_table(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) +fill_pred_weight_table(GstVaapiDecoderH264 *decoder, + GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr) { - GstH264SliceHdr * const slice_hdr = &slice->slice_hdr; + VASliceParameterBufferH264 * const slice_param = slice->param; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table; - VASliceParameterBufferH264 * const slice_param = slice->base.param; guint num_weight_tables = 0; gint i, j; @@ -2702,11 +2629,11 @@ fill_pred_weight_table(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) } static gboolean -fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) +fill_RefPicList(GstVaapiDecoderH264 *decoder, + GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264SliceHdr * const slice_hdr = &slice->slice_hdr; - VASliceParameterBufferH264 * const slice_param = slice->base.param; + VASliceParameterBufferH264 * const slice_param = slice->param; guint i, num_ref_lists = 0; slice_param->num_ref_idx_l0_active_minus1 = 0; @@ -2744,17 +2671,13 @@ fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice) } static gboolean -fill_slice( - GstVaapiDecoderH264 *decoder, - GstVaapiSliceH264 *slice, - GstH264NalUnit *nalu -) +fill_slice(GstVaapiDecoderH264 *decoder, + GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr) { - GstH264SliceHdr * const slice_hdr = &slice->slice_hdr; - VASliceParameterBufferH264 * const slice_param = slice->base.param; + VASliceParameterBufferH264 * const slice_param = slice->param; /* Fill in VASliceParameterBufferH264 */ - slice_param->slice_data_bit_offset = get_slice_data_bit_offset(slice_hdr, nalu); + slice_param->slice_data_bit_offset = get_slice_data_bit_offset(slice_hdr); slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice; slice_param->slice_type = slice_hdr->type % 5; slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag; @@ -2764,9 +2687,9 @@ fill_slice( slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2; slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2; - if (!fill_RefPicList(decoder, slice)) + if (!fill_RefPicList(decoder, slice, slice_hdr)) return FALSE; - if (!fill_pred_weight_table(decoder, slice)) + if (!fill_pred_weight_table(decoder, slice, slice_hdr)) return FALSE; return TRUE; } @@ -2775,10 +2698,10 @@ static GstVaapiDecoderStatus decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiPictureH264 * const picture = priv->current_picture; GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; GstH264NalUnit * const nalu = &unit->nalu; - GstVaapiDecoderStatus status; - GstVaapiSliceH264 *slice; + GstVaapiSlice *slice; GST_DEBUG("slice (%u bytes)", nalu->size); @@ -2795,28 +2718,21 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } - slice = gst_vaapi_slice_h264_new(decoder, + slice = GST_VAAPI_SLICE_NEW(H264, decoder, GST_BUFFER_DATA(unit->base.buffer) + nalu->offset, nalu->size); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } - slice->slice_hdr = *slice_hdr; - if (!fill_slice(decoder, slice, nalu)) { - status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - goto error; - } - gst_vaapi_picture_add_slice( - GST_VAAPI_PICTURE_CAST(priv->current_picture), - GST_VAAPI_SLICE_CAST(slice) - ); - return GST_VAAPI_DECODER_STATUS_SUCCESS; - -error: - if (slice) + if (!fill_slice(decoder, slice, slice_hdr)) { gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(slice)); - return status; + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + gst_vaapi_picture_add_slice(GST_VAAPI_PICTURE_CAST(picture), slice); + picture->last_slice_hdr = slice_hdr; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static inline gint From 0b2e399235e82f11a47f17629bc4b05f471959f4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Dec 2012 11:48:06 +0100 Subject: [PATCH 0946/3781] h264: minor clean-ups. Drop explicit initialization of most fields that are implicitly set to zero. Drop helper macros for casting to GstVaapiPictureH264 or GstVaapiFrameStore. Also remove some useless checks for NULL pointers. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 110 +++++----------------- 1 file changed, 25 insertions(+), 85 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 93da0970dc..e85cb67852 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -86,15 +86,6 @@ gst_vaapi_decoder_unit_h264_new(guint size) /* --- H.264 Pictures --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_PICTURE_H264_CAST(obj) \ - ((GstVaapiPictureH264 *)(obj)) - -#define GST_VAAPI_PICTURE_H264(obj) \ - GST_VAAPI_PICTURE_H264_CAST(obj) - -#define GST_VAAPI_IS_PICTURE_H264(obj) \ - (GST_VAAPI_PICTURE_H264(obj) != NULL) - /* * Extended picture flags: * @@ -173,20 +164,12 @@ gst_vaapi_picture_h264_create( static inline GstVaapiPictureH264 * gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder) { - GstVaapiCodecObject *object; - - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - - object = gst_vaapi_codec_object_new( + return (GstVaapiPictureH264 *)gst_vaapi_codec_object_new( &GstVaapiPictureH264Class, GST_VAAPI_CODEC_BASE(decoder), NULL, sizeof(VAPictureParameterBufferH264), NULL, 0, - 0 - ); - if (!object) - return NULL; - return GST_VAAPI_PICTURE_H264_CAST(object); + 0); } static inline void @@ -196,8 +179,8 @@ gst_vaapi_picture_h264_set_reference( gboolean other_field ) { - g_return_if_fail(GST_VAAPI_IS_PICTURE_H264(picture)); - + if (!picture) + return; GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags); @@ -210,29 +193,15 @@ gst_vaapi_picture_h264_set_reference( static inline GstVaapiPictureH264 * gst_vaapi_picture_h264_new_field(GstVaapiPictureH264 *picture) { - GstVaapiPicture *base_picture; + g_return_val_if_fail(picture, NULL); - g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL); - - base_picture = gst_vaapi_picture_new_field(&picture->base); - if (!base_picture) - return NULL; - return GST_VAAPI_PICTURE_H264_CAST(base_picture); + return (GstVaapiPictureH264 *)gst_vaapi_picture_new_field(&picture->base); } /* ------------------------------------------------------------------------- */ /* --- Frame Buffers (DPB) --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_FRAME_STORE_CAST(obj) \ - ((GstVaapiFrameStore *)(obj)) - -#define GST_VAAPI_FRAME_STORE(obj) \ - GST_VAAPI_FRAME_STORE_CAST(obj) - -#define GST_VAAPI_IS_FRAME_STORE(obj) \ - (GST_VAAPI_MINI_OBJECT(obj) != NULL) - struct _GstVaapiFrameStore { /*< private >*/ GstVaapiMiniObject parent_instance; @@ -263,8 +232,6 @@ gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture) gst_vaapi_frame_store_finalize }; - g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL); - fs = (GstVaapiFrameStore *) gst_vaapi_mini_object_new(&GstVaapiFrameStoreClass); if (!fs) @@ -283,10 +250,9 @@ gst_vaapi_frame_store_add(GstVaapiFrameStore *fs, GstVaapiPictureH264 *picture) { guint field; - g_return_val_if_fail(GST_VAAPI_IS_FRAME_STORE(fs), FALSE); g_return_val_if_fail(fs->num_buffers == 1, FALSE); - g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), FALSE); g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FRAME(picture), FALSE); + g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture), FALSE); gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], picture); if (picture->output_flag) { @@ -369,6 +335,9 @@ G_DEFINE_TYPE(GstVaapiDecoderH264, gst_vaapi_decoder_h264, GST_VAAPI_TYPE_DECODER) +#define GST_VAAPI_DECODER_H264_CAST(decoder) \ + ((GstVaapiDecoderH264 *)(decoder)) + #define GST_VAAPI_DECODER_H264_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ GST_VAAPI_TYPE_DECODER_H264, \ @@ -408,7 +377,7 @@ struct _GstVaapiDecoderH264Private { gboolean prev_pic_structure; // previous picture structure guint is_constructed : 1; guint is_opened : 1; - guint is_avc : 1; + guint is_avcC : 1; guint got_sps : 1; guint got_pps : 1; guint has_context : 1; @@ -631,12 +600,8 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) // Check if picture is the second field and the first field is still in DPB fs = priv->prev_frame; - if (fs && !gst_vaapi_frame_store_has_frame(fs)) { - g_return_val_if_fail(fs->num_buffers == 1, FALSE); - g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FRAME(picture), FALSE); - g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture), FALSE); + if (fs && !gst_vaapi_frame_store_has_frame(fs)) return gst_vaapi_frame_store_add(fs, picture); - } // Create new frame store, and split fields if necessary fs = gst_vaapi_frame_store_new(picture); @@ -2831,7 +2796,7 @@ decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) ofs = unit.nalu.offset + unit.nalu.size; } - priv->is_avc = TRUE; + priv->is_avcC = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2864,7 +2829,8 @@ static GstVaapiDecoderStatus gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) { - GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base_decoder); + GstVaapiDecoderH264 * const decoder = + GST_VAAPI_DECODER_H264_CAST(base_decoder); GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiDecoderUnitH264 *unit; @@ -2881,7 +2847,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, size = gst_adapter_available(adapter); - if (priv->is_avc) { + if (priv->is_avcC) { if (size < priv->nal_length_size) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; @@ -2936,7 +2902,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, if (!unit) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - if (priv->is_avc) + if (priv->is_avcC) result = gst_h264_parser_identify_nalu_avc(priv->parser, buf, 0, buf_size, priv->nal_length_size, &unit->nalu); else @@ -3013,7 +2979,8 @@ static GstVaapiDecoderStatus gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base_decoder); + GstVaapiDecoderH264 * const decoder = + GST_VAAPI_DECODER_H264_CAST(base_decoder); GstVaapiDecoderStatus status; status = ensure_decoder(decoder); @@ -3026,7 +2993,8 @@ static GstVaapiDecoderStatus gst_vaapi_decoder_h264_start_frame(GstVaapiDecoder *base_decoder, GstVaapiDecoderUnit *base_unit) { - GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base_decoder); + GstVaapiDecoderH264 * const decoder = + GST_VAAPI_DECODER_H264_CAST(base_decoder); GstVaapiDecoderUnitH264 * const unit = (GstVaapiDecoderUnitH264 *)base_unit; return decode_picture(decoder, unit); @@ -3035,7 +3003,8 @@ gst_vaapi_decoder_h264_start_frame(GstVaapiDecoder *base_decoder, static GstVaapiDecoderStatus gst_vaapi_decoder_h264_end_frame(GstVaapiDecoder *base_decoder) { - GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base_decoder); + GstVaapiDecoderH264 * const decoder = + GST_VAAPI_DECODER_H264_CAST(base_decoder); return decode_current_picture(decoder); } @@ -3043,7 +3012,7 @@ gst_vaapi_decoder_h264_end_frame(GstVaapiDecoder *base_decoder) static void gst_vaapi_decoder_h264_finalize(GObject *object) { - GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object); + GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(object); gst_vaapi_decoder_h264_destroy(decoder); @@ -3053,7 +3022,7 @@ gst_vaapi_decoder_h264_finalize(GObject *object) static void gst_vaapi_decoder_h264_constructed(GObject *object) { - GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object); + GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(object); GstVaapiDecoderH264Private * const priv = decoder->priv; GObjectClass *parent_class; @@ -3088,40 +3057,11 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder); decoder->priv = priv; - priv->parser = NULL; - priv->current_picture = NULL; - priv->dpb_count = 0; - priv->dpb_size = 0; priv->profile = GST_VAAPI_PROFILE_UNKNOWN; priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD; priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - priv->short_ref_count = 0; - priv->long_ref_count = 0; - priv->RefPicList0_count = 0; - priv->RefPicList1_count = 0; - priv->nal_length_size = 0; - priv->field_poc[0] = 0; - priv->field_poc[1] = 0; - priv->poc_msb = 0; - priv->poc_lsb = 0; - priv->prev_poc_msb = 0; - priv->prev_poc_lsb = 0; - priv->frame_num_offset = 0; - priv->frame_num = 0; - priv->prev_frame_num = 0; - priv->prev_pic_has_mmco5 = FALSE; priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - priv->is_constructed = FALSE; - priv->is_opened = FALSE; - priv->is_avc = FALSE; - priv->has_context = FALSE; priv->progressive_sequence = TRUE; - - memset(priv->dpb, 0, sizeof(priv->dpb)); - memset(priv->short_ref, 0, sizeof(priv->short_ref)); - memset(priv->long_ref, 0, sizeof(priv->long_ref)); - memset(priv->RefPicList0, 0, sizeof(priv->RefPicList0)); - memset(priv->RefPicList1, 0, sizeof(priv->RefPicList1)); } /** From 098eb2624ec6c32d9afa5a5054ca84fce90bf2e8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 18 Dec 2012 14:57:36 +0100 Subject: [PATCH 0947/3781] h264: optimize initialization process of decoder units. Decoder units were zero-initialized, including the SPS/PPS/slice headers. The latter don't require zero-initialization since the codecparsers/ lib will do so for key variables already. This is not a great value per se but at least it makes it possible to check whether the default initialization decisions made in the codecparsers/ lib were right or not. This can be reverted if this exposes too many issues. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index e85cb67852..e601bdcc60 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -74,11 +74,11 @@ gst_vaapi_decoder_unit_h264_new(guint size) }; unit = (GstVaapiDecoderUnitH264 *) - gst_vaapi_mini_object_new0(&GstVaapiDecoderUnitH264Class); + gst_vaapi_mini_object_new(&GstVaapiDecoderUnitH264Class); if (!unit) return NULL; - unit->base.size = size; + gst_vaapi_decoder_unit_init(&unit->base, size); return unit; } From 936d8b8fc6287424485670d6e3d51ce39d41bb5f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Dec 2012 13:27:33 +0100 Subject: [PATCH 0948/3781] vaapipostproc: handle video sub-buffers. Intermediate elements may produce a sub-buffer from a valid GstVaapiVideoBuffer for non raw YUV cases. Make sure vaapipostproc now understands those buffers. --- gst/vaapi/gstvaapipostproc.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index bcd25228dd..353c6b1979 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -255,7 +255,7 @@ gst_vaapipostproc_stop(GstVaapiPostproc *postproc) static GstFlowReturn gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) { - GstVaapiVideoBuffer *vbuf = GST_VAAPI_VIDEO_BUFFER(buf); + GstVaapiVideoBuffer *vbuf; GstVaapiSurfaceProxy *proxy; GstClockTime timestamp; GstFlowReturn ret; @@ -263,6 +263,13 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) guint outbuf_flags, flags; gboolean interlaced, tff; + if (GST_VAAPI_IS_VIDEO_BUFFER(buf)) + vbuf = GST_VAAPI_VIDEO_BUFFER(buf); + else if (GST_VAAPI_IS_VIDEO_BUFFER(buf->parent)) + vbuf = GST_VAAPI_VIDEO_BUFFER(buf->parent); + else + goto error_invalid_buffer; + flags = gst_vaapi_video_buffer_get_render_flags(vbuf); /* Deinterlacing disabled, push frame */ @@ -328,6 +335,12 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) return GST_FLOW_OK; /* ERRORS */ +error_invalid_buffer: + { + GST_ERROR("failed to receive a valid video buffer"); + gst_buffer_unref(buf); + return GST_FLOW_UNEXPECTED; + } error_create_buffer: { GST_ERROR("failed to create output buffer"); From c21d76cff2d6fe0dbab212bf7f55b0c9d5f83c46 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Dec 2012 15:47:27 +0100 Subject: [PATCH 0949/3781] vaapipostproc: use GstBuffer flags for TFF. Determine whether the buffer represents the top-field only by checking for the GST_VIDEO_BUFFER_TFF flag instead of relying on the GstVaapiSurfaceProxy flag. Also trust "interlaced" caps to determine whether the input frame is interleaved or not. --- gst/vaapi/gstvaapipostproc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 353c6b1979..6355d9bfe3 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -261,7 +261,7 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) GstFlowReturn ret; GstBuffer *outbuf = NULL; guint outbuf_flags, flags; - gboolean interlaced, tff; + gboolean tff; if (GST_VAAPI_IS_VIDEO_BUFFER(buf)) vbuf = GST_VAAPI_VIDEO_BUFFER(buf); @@ -283,8 +283,7 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) timestamp = GST_BUFFER_TIMESTAMP(buf); proxy = gst_vaapi_video_buffer_get_surface_proxy(vbuf); - interlaced = gst_vaapi_surface_proxy_get_interlaced(proxy); - tff = gst_vaapi_surface_proxy_get_tff(proxy); + tff = GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_TFF); flags &= ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); @@ -296,7 +295,7 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf); outbuf_flags = flags; - outbuf_flags |= interlaced ? ( + outbuf_flags |= postproc->deinterlace ? ( tff ? GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) : @@ -317,7 +316,7 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf); outbuf_flags = flags; - outbuf_flags |= interlaced ? ( + outbuf_flags |= postproc->deinterlace ? ( tff ? GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD : GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) : From 09c9e2037941730675441c305089beaf079c5f3e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Dec 2012 14:27:18 +0100 Subject: [PATCH 0950/3781] decoder: add gst_vaapi_decoder_get_frame() API. Add new gst_vaapi_decoder_get_frame() function meant to be used with gst_vaapi_decoder_decode(). The purpose is to return the next decoded frame as a GstVideoCodecFrame and the associated GstVaapiSurfaceProxy as the user-data object. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 62 ++++++++++++++++++++++------ gst-libs/gst/vaapi/gstvaapidecoder.h | 7 +++- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 279f958ab6..aca76af54b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -630,6 +630,51 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, return status; } +/** + * gst_vaapi_decoder_get_frame: + * @decoder: a #GstVaapiDecoder + * @out_frame_ptr: the next decoded frame as a #GstVideoCodecFrame + * + * Returns the next frame available in the list of decoded frames. + * @GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA is returned if there is no + * decoded frame pending in the queue. + * + * The actual surface is available as a #GstVaapiSurfaceProxy attached + * to the user-data anchor of the output frame. Ownership of the proxy + * is transferred to the frame. + * + * Return value: a #GstVaapiDecoderStatus + */ +GstVaapiDecoderStatus +gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder, + GstVideoCodecFrame **out_frame_ptr) +{ + GstVaapiSurfaceProxy *proxy; + GstVideoCodecFrame *out_frame; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail(out_frame_ptr != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + + proxy = pop_surface(decoder); + if (!proxy || !(out_frame = gst_vaapi_surface_proxy_get_user_data(proxy))) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + gst_video_codec_frame_set_user_data(out_frame, + proxy, (GDestroyNotify)gst_vaapi_mini_object_unref); + + out_frame->pts = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); + out_frame->duration = GST_VAAPI_SURFACE_PROXY_DURATION(proxy); + + if (GST_VAAPI_SURFACE_PROXY_TFF(proxy)) + GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, + GST_VIDEO_CODEC_FRAME_FLAG_TFF); + + *out_frame_ptr = out_frame; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + void gst_vaapi_decoder_set_picture_size( GstVaapiDecoder *decoder, @@ -803,28 +848,19 @@ gst_vaapi_decoder_parse(GstVaapiDecoder *decoder, } GstVaapiDecoderStatus -gst_vaapi_decoder_decode(GstVaapiDecoder *decoder, - GstVideoCodecFrame *base_frame, GstVaapiSurfaceProxy **out_proxy_ptr) +gst_vaapi_decoder_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) { GstVaapiDecoderStatus status; g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(base_frame != NULL, + g_return_val_if_fail(frame != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(base_frame->user_data != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(out_proxy_ptr != NULL, + g_return_val_if_fail(frame->user_data != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); status = gst_vaapi_decoder_check_status(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - - status = do_decode(decoder, base_frame); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - - *out_proxy_ptr = pop_surface(decoder); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + return do_decode(decoder, frame); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 9ca3d4093f..88a0c1f26d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -144,14 +144,17 @@ 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_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, GstVaapiSurfaceProxy **out_proxy_ptr); +gst_vaapi_decoder_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame); G_END_DECLS From 039eb3bb6c11a3e0bf7a797a7b884d9884e3de4d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Dec 2012 14:30:18 +0100 Subject: [PATCH 0951/3781] vaapidecode: output all decoded frames as soon as possible. Make sure to push all decoded frames downstream as soon as possible. This makes sure we don't need to wait for a new frame to be ready to be decoded before receiving new decoded frames. This also separates the decode process and the output process. The latter could be moved to a specific GstTask later on. --- gst/vaapi/gstvaapidecode.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 569d1e6b6a..047d1b53ec 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -186,6 +186,7 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) GstFlowReturn ret; gint64 end_time; + /* Decode current frame */ for (;;) { end_time = decode->render_time_base; if (!end_time) @@ -193,7 +194,7 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) end_time += GST_TIME_AS_USECONDS(decode->last_buffer_time); end_time += G_TIME_SPAN_SECOND; - status = gst_vaapi_decoder_decode(decode->decoder, frame, &proxy); + status = gst_vaapi_decoder_decode(decode->decoder, frame); if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { gboolean was_signalled; g_mutex_lock(&decode->decoder_mutex); @@ -209,12 +210,16 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) } if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto error_decode; + break; + } - /* Current frame was decoded but no surface was output */ - if (!proxy) - break; + /* Output all decoded frames */ + for (;;) { + status = gst_vaapi_decoder_get_frame(decode->decoder, &out_frame); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return GST_FLOW_OK; - out_frame = gst_vaapi_surface_proxy_get_user_data(proxy); + proxy = gst_video_codec_frame_get_user_data(out_frame); gst_vaapi_surface_proxy_set_user_data(proxy, decode, (GDestroyNotify)gst_vaapidecode_release); @@ -223,22 +228,13 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) if (!out_frame->output_buffer) goto error_create_buffer; - out_frame->pts = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); - out_frame->duration = GST_VAAPI_SURFACE_PROXY_DURATION(proxy); - - if (GST_VAAPI_SURFACE_PROXY_TFF(proxy)) - GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, - GST_VIDEO_CODEC_FRAME_FLAG_TFF); - gst_vaapi_video_buffer_set_surface_proxy( GST_VAAPI_VIDEO_BUFFER(out_frame->output_buffer), proxy); - gst_vaapi_surface_proxy_unref(proxy); ret = gst_video_decoder_finish_frame(vdec, out_frame); if (ret != GST_FLOW_OK) goto error_commit_buffer; - break; - } + }; return GST_FLOW_OK; /* ERRORS */ From 8c2d9bcd2426756c85cbfeef8d85af775690bbef Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Dec 2012 15:34:10 +0100 Subject: [PATCH 0952/3781] decoder: maintain decoded frames as GstVideoCodecFrame objects. Maintain decoded surfaces as GstVideoCodecFrame objects instead of GstVaapiSurfaceProxy objects. The latter will tend to be reduced to the strict minimum: a context and a surface. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 94 ++++++++++---------- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 47 +++++++--- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 8 +- gst/vaapi/gstvaapidecode.c | 3 + 5 files changed, 87 insertions(+), 66 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index aca76af54b..be4d1f9cc1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -304,29 +304,32 @@ decode_step(GstVaapiDecoder *decoder) } static inline void -push_surface(GstVaapiDecoder *decoder, GstVaapiSurfaceProxy *proxy) +push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) { GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVideoInfo * const vi = &priv->codec_state->info; - GstClockTime duration; GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id(proxy))); + GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id( + frame->user_data))); - if (vi->fps_n && vi->fps_d) { - /* Actual field duration is computed in vaapipostproc */ - duration = gst_util_uint64_scale(GST_SECOND, vi->fps_d, vi->fps_n); - gst_vaapi_surface_proxy_set_duration(proxy, duration); - } - g_queue_push_tail(priv->surfaces, proxy); + g_queue_push_tail(priv->frames, frame); } -static inline GstVaapiSurfaceProxy * -pop_surface(GstVaapiDecoder *decoder) +static inline GstVideoCodecFrame * +pop_frame(GstVaapiDecoder *decoder) { GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVideoCodecFrame *frame; - return g_queue_pop_head(priv->surfaces); + frame = g_queue_pop_head(priv->frames); + if (!frame) + return NULL; + + GST_DEBUG("dequeue decoded surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id( + frame->user_data))); + + return frame; } static void @@ -387,11 +390,11 @@ gst_vaapi_decoder_finalize(GObject *object) priv->buffers = NULL; } - if (priv->surfaces) { - clear_queue(priv->surfaces, (GDestroyNotify) - gst_vaapi_surface_proxy_unref); - g_queue_free(priv->surfaces); - priv->surfaces = NULL; + if (priv->frames) { + clear_queue(priv->frames, (GDestroyNotify) + gst_video_codec_frame_unref); + g_queue_free(priv->frames); + priv->frames = NULL; } g_clear_object(&priv->context); @@ -507,7 +510,7 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->codec = 0; priv->codec_state = codec_state; priv->buffers = g_queue_new(); - priv->surfaces = g_queue_new(); + priv->frames = g_queue_new(); } /** @@ -605,7 +608,7 @@ GstVaapiDecoderStatus gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, GstVaapiSurfaceProxy **out_proxy_ptr) { - GstVaapiSurfaceProxy *proxy; + GstVideoCodecFrame *frame; GstVaapiDecoderStatus status; g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), @@ -613,20 +616,24 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, g_return_val_if_fail(out_proxy_ptr != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - proxy = pop_surface(decoder); - if (!proxy) { + frame = pop_frame(decoder); + if (!frame) { do { status = decode_step(decoder); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); - proxy = pop_surface(decoder); + frame = pop_frame(decoder); } - if (proxy) + if (frame) { + *out_proxy_ptr = gst_vaapi_surface_proxy_ref(frame->user_data); + gst_video_codec_frame_unref(frame); status = GST_VAAPI_DECODER_STATUS_SUCCESS; - else if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) - status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - - *out_proxy_ptr = proxy; + } + else { + *out_proxy_ptr = NULL; + if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } return status; } @@ -635,9 +642,11 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, * @decoder: a #GstVaapiDecoder * @out_frame_ptr: the next decoded frame as a #GstVideoCodecFrame * - * Returns the next frame available in the list of decoded frames. - * @GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA is returned if there is no - * decoded frame pending in the queue. + * On successful return, *@out_frame_ptr contains the next decoded + * frame available as a #GstVideoCodecFrame. The caller owns this + * object, so gst_video_codec_frame_unref() shall be called after + * usage. Otherwise, @GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA is + * returned if no decoded frame is available. * * The actual surface is available as a #GstVaapiSurfaceProxy attached * to the user-data anchor of the output frame. Ownership of the proxy @@ -649,7 +658,6 @@ GstVaapiDecoderStatus gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame **out_frame_ptr) { - GstVaapiSurfaceProxy *proxy; GstVideoCodecFrame *out_frame; g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), @@ -657,20 +665,10 @@ gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder, g_return_val_if_fail(out_frame_ptr != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - proxy = pop_surface(decoder); - if (!proxy || !(out_frame = gst_vaapi_surface_proxy_get_user_data(proxy))) + out_frame = pop_frame(decoder); + if (!out_frame) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - gst_video_codec_frame_set_user_data(out_frame, - proxy, (GDestroyNotify)gst_vaapi_mini_object_unref); - - out_frame->pts = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); - out_frame->duration = GST_VAAPI_SURFACE_PROXY_DURATION(proxy); - - if (GST_VAAPI_SURFACE_PROXY_TFF(proxy)) - GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, - GST_VIDEO_CODEC_FRAME_FLAG_TFF); - *out_frame_ptr = out_frame; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -809,12 +807,10 @@ gst_vaapi_decoder_ensure_context( } void -gst_vaapi_decoder_push_surface_proxy( - GstVaapiDecoder *decoder, - GstVaapiSurfaceProxy *proxy -) +gst_vaapi_decoder_push_frame(GstVaapiDecoder *decoder, + GstVideoCodecFrame *frame) { - push_surface(decoder, proxy); + push_frame(decoder, frame); } GstVaapiDecoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index aad758c8e8..988c40971d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -84,6 +84,11 @@ gst_vaapi_picture_destroy(GstVaapiPicture *picture) 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 @@ -164,9 +169,8 @@ gst_vaapi_picture_create( if (!picture->slices) return FALSE; - gst_vaapi_mini_object_set_user_data( - GST_VAAPI_MINI_OBJECT(picture->proxy), - GST_VAAPI_DECODER_CODEC_FRAME(GET_DECODER(picture)), NULL); + picture->frame = gst_video_codec_frame_ref( + GST_VAAPI_DECODER_CODEC_FRAME(GET_DECODER(picture))); return TRUE; } @@ -304,21 +308,40 @@ gboolean gst_vaapi_picture_output(GstVaapiPicture *picture) { GstVaapiSurfaceProxy *proxy; + GstVideoCodecFrame *out_frame; g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE); if (!picture->proxy) return FALSE; - if (!GST_VAAPI_PICTURE_IS_SKIPPED(picture)) { - proxy = gst_vaapi_surface_proxy_ref(picture->proxy); - gst_vaapi_surface_proxy_set_timestamp(proxy, picture->pts); - if (GST_VAAPI_PICTURE_IS_INTERLACED(picture)) - gst_vaapi_surface_proxy_set_interlaced(proxy, TRUE); - if (GST_VAAPI_PICTURE_IS_TFF(picture)) - gst_vaapi_surface_proxy_set_tff(proxy, TRUE); - gst_vaapi_decoder_push_surface_proxy(GET_DECODER(picture), proxy); - } + out_frame = gst_video_codec_frame_ref(picture->frame); + + proxy = gst_vaapi_surface_proxy_ref(picture->proxy); + gst_video_codec_frame_set_user_data(out_frame, + proxy, (GDestroyNotify)gst_vaapi_mini_object_unref); + + if (!GST_CLOCK_TIME_IS_VALID(out_frame->pts)) + 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_TFF(picture)) + GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, + GST_VIDEO_CODEC_FRAME_FLAG_TFF); + + /* XXX: to be removed later */ + if (GST_CLOCK_TIME_IS_VALID(out_frame->pts)) + gst_vaapi_surface_proxy_set_timestamp(proxy, out_frame->pts); + if (GST_CLOCK_TIME_IS_VALID(out_frame->duration)) + gst_vaapi_surface_proxy_set_duration(proxy, out_frame->duration); + if (GST_VAAPI_PICTURE_IS_INTERLACED(picture)) + gst_vaapi_surface_proxy_set_interlaced(proxy, TRUE); + if (GST_VAAPI_PICTURE_IS_TFF(picture)) + gst_vaapi_surface_proxy_set_tff(proxy, TRUE); + + gst_vaapi_decoder_push_frame(GET_DECODER(picture), out_frame); + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_OUTPUT); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index beea9acec0..2dcdde3f21 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -114,6 +114,7 @@ enum { struct _GstVaapiPicture { /*< private >*/ GstVaapiCodecObject parent_instance; + GstVideoCodecFrame *frame; GstVaapiSurface *surface; GstVaapiSurfaceProxy *proxy; VABufferID param_id; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index a74673e095..4f864068f3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -163,7 +163,7 @@ struct _GstVaapiDecoderPrivate { GstVaapiCodec codec; GstVideoCodecState *codec_state; GQueue *buffers; - GQueue *surfaces; + GQueue *frames; GstVaapiParserState parser_state; }; @@ -209,10 +209,8 @@ gst_vaapi_decoder_ensure_context( G_GNUC_INTERNAL void -gst_vaapi_decoder_push_surface_proxy( - GstVaapiDecoder *decoder, - GstVaapiSurfaceProxy *proxy -); +gst_vaapi_decoder_push_frame(GstVaapiDecoder *decoder, + GstVideoCodecFrame *frame); G_GNUC_INTERNAL GstVaapiDecoderStatus diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 047d1b53ec..b588046342 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -234,6 +234,7 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) ret = gst_video_decoder_finish_frame(vdec, out_frame); if (ret != GST_FLOW_OK) goto error_commit_buffer; + gst_video_codec_frame_unref(out_frame); }; return GST_FLOW_OK; @@ -269,12 +270,14 @@ error_create_buffer: "surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); gst_video_decoder_drop_frame(vdec, out_frame); + gst_video_codec_frame_unref(out_frame); return GST_FLOW_UNEXPECTED; } error_commit_buffer: { GST_DEBUG("video sink rejected the video buffer (error %d)", ret); gst_video_decoder_drop_frame(vdec, out_frame); + gst_video_codec_frame_unref(out_frame); return GST_FLOW_UNEXPECTED; } } From 51d028a628396b81a3c9f0f39ee4829c3fac668d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Dec 2012 15:51:24 +0100 Subject: [PATCH 0953/3781] surfaceproxy: drop accessors to obsolete attributes. Make GstVaapiSurfaceProxy only a thin wrapper around a VA context and a VA surface. i.e. drop any other attribute like timestamp, duration, interlaced or top-field-first. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 10 -- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 151 ------------------- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 68 --------- 3 files changed, 229 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 988c40971d..541a0975bc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -330,16 +330,6 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, GST_VIDEO_CODEC_FRAME_FLAG_TFF); - /* XXX: to be removed later */ - if (GST_CLOCK_TIME_IS_VALID(out_frame->pts)) - gst_vaapi_surface_proxy_set_timestamp(proxy, out_frame->pts); - if (GST_CLOCK_TIME_IS_VALID(out_frame->duration)) - gst_vaapi_surface_proxy_set_duration(proxy, out_frame->duration); - if (GST_VAAPI_PICTURE_IS_INTERLACED(picture)) - gst_vaapi_surface_proxy_set_interlaced(proxy, TRUE); - if (GST_VAAPI_PICTURE_IS_TFF(picture)) - gst_vaapi_surface_proxy_set_tff(proxy, TRUE); - gst_vaapi_decoder_push_frame(GET_DECODER(picture), out_frame); GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_OUTPUT); diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 10bd736988..0d18ac91cc 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -45,10 +45,6 @@ struct _GstVaapiSurfaceProxy { GstVaapiContext *context; GstVaapiSurface *surface; - GstClockTime timestamp; - GstClockTime duration; - guint is_interlaced : 1; - guint tff : 1; }; static void @@ -58,16 +54,6 @@ gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) gst_vaapi_surface_proxy_set_context(proxy, NULL); } -static void -gst_vaapi_surface_proxy_init(GstVaapiSurfaceProxy *proxy) -{ - proxy->timestamp = GST_CLOCK_TIME_NONE; - proxy->duration = GST_CLOCK_TIME_NONE; - - proxy->is_interlaced = FALSE; - proxy->tff = FALSE; -} - static inline const GstVaapiMiniObjectClass * gst_vaapi_surface_proxy_class(void) { @@ -102,7 +88,6 @@ gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface) return NULL; proxy = GST_VAAPI_SURFACE_PROXY(object); - gst_vaapi_surface_proxy_init(proxy); gst_vaapi_surface_proxy_set_context(proxy, context); gst_vaapi_surface_proxy_set_surface(proxy, surface); return proxy; @@ -297,139 +282,3 @@ gst_vaapi_surface_proxy_set_surface( if (surface) proxy->surface = g_object_ref(surface); } - -/** - * gst_vaapi_surface_proxy_get_timestamp: - * @proxy: a #GstVaapiSurfaceProxy - * - * Returns the presentation timestamp of the #GstVaapiSurface held by @proxy. - * - * Return value: the presentation timestamp of the surface, or - * %GST_CLOCK_TIME_NONE is none was set - */ -GstClockTime -gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy) -{ - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), - GST_CLOCK_TIME_NONE); - - return proxy->timestamp; -} - -/** - * gst_vaapi_surface_proxy_set_timestamp: - * @proxy: a #GstVaapiSurfaceProxy - * @timestamp: the new presentation timestamp as a #GstClockTime - * - * Sets the presentation timestamp of the @proxy surface to @timestamp. - */ -void -gst_vaapi_surface_proxy_set_timestamp( - GstVaapiSurfaceProxy *proxy, - GstClockTime timestamp -) -{ - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - - proxy->timestamp = timestamp; -} - -/** - * gst_vaapi_surface_proxy_get_duration: - * @proxy: a #GstVaapiSurfaceProxy - * - * Returns the presentation duration of the #GstVaapiSurface held by @proxy. - * - * Return value: the presentation duration of the surface, or - * %GST_CLOCK_TIME_NONE is none was set - */ -GstClockTime -gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy) -{ - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), - GST_CLOCK_TIME_NONE); - - return proxy->duration; -} - -/** - * gst_vaapi_surface_proxy_set_duration: - * @proxy: a #GstVaapiSurfaceProxy - * @duration: the presentation duration of this surface as a #GstClockTime - * - * Sets the presentation duration of the @proxy surface to @duration. - */ -void -gst_vaapi_surface_proxy_set_duration( - GstVaapiSurfaceProxy *proxy, - GstClockTime duration -) -{ - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - - proxy->duration = duration; -} - -/** - * gst_vaapi_surface_proxy_get_interlaced: - * @proxy: a #GstVaapiSurfaceProxy - * - * Returns whether the @proxy holds an interlaced #GstVaapiSurface or not. - * - * Return value: %TRUE if the underlying surface is interlaced, %FALSE - * otherwise. - */ -gboolean -gst_vaapi_surface_proxy_get_interlaced(GstVaapiSurfaceProxy *proxy) -{ - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE); - - return proxy->is_interlaced; -} - -/** - * gst_vaapi_surface_proxy_set_interlaced: - * @proxy: a #GstVaapiSurfaceProxy - * @b: a boolean value - * - * Sets whether the underlying #GstVaapiSurface for @proxy is interlaced - * or not. - */ -void -gst_vaapi_surface_proxy_set_interlaced(GstVaapiSurfaceProxy *proxy, gboolean b) -{ - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - - proxy->is_interlaced = b; -} - -/** - * gst_vaapi_surface_proxy_get_tff: - * @proxy: a #GstVaapiSurfaceProxy - * - * Returns the TFF flag of the #GstVaapiSurface held by @proxy. - * - * Return value: the TFF flag of the surface - */ -gboolean -gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy) -{ - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE); - - return proxy->is_interlaced && proxy->tff; -} - -/** - * gst_vaapi_surface_proxy_set_tff: - * @proxy: a #GstVaapiSurfaceProxy - * @tff: the new value of the TFF flag - * - * Sets the TFF flag of the @proxy surface to @tff. - */ -void -gst_vaapi_surface_proxy_set_tff(GstVaapiSurfaceProxy *proxy, gboolean tff) -{ - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - - proxy->tff = tff; -} diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 064c755003..a8fe2d16d7 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -39,44 +39,6 @@ typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; #define GST_VAAPI_SURFACE_PROXY_SURFACE(surface) \ gst_vaapi_surface_proxy_get_surface(surface) -/** - * GST_VAAPI_SURFACE_PROXY_TIMESTAMP: - * @surface: a #GstVaapiSurfaceProxy - * - * Macro that evaluates to the @surface timestamp, or - * %GST_CLOCK_TIME_NONE if none was set. - */ -#define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(surface) \ - gst_vaapi_surface_proxy_get_timestamp(surface) - -/** - * GST_VAAPI_SURFACE_PROXY_DURATION: - * @surface: a #GstVaapiSurfaceProxy - * - * Macro that evaluates to the amount of time the @surface should be - * displayed, or %GST_CLOCK_TIME_NONE if none was set. - */ -#define GST_VAAPI_SURFACE_PROXY_DURATION(surface) \ - gst_vaapi_surface_proxy_get_duration(surface) - -/** - * GST_VAAPI_SURFACE_PROXY_INTERLACED: - * @surface: a #GstVaapiSurfaceProxy - * - * Macro that evaluates to %TRUE if the @surface is interlaced. - */ -#define GST_VAAPI_SURFACE_PROXY_INTERLACED(surface) \ - gst_vaapi_surface_proxy_get_interlaced(surface) - -/** - * GST_VAAPI_SURFACE_PROXY_TFF: - * @surface: a #GstVaapiSurfaceProxy - * - * Macro that evaluates to the tff flag of the @surface - */ -#define GST_VAAPI_SURFACE_PROXY_TFF(surface) \ - gst_vaapi_surface_proxy_get_tff(surface) - GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface); @@ -118,36 +80,6 @@ gst_vaapi_surface_proxy_set_surface( GstVaapiSurface *surface ); -GstClockTime -gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy); - -void -gst_vaapi_surface_proxy_set_timestamp( - GstVaapiSurfaceProxy *proxy, - GstClockTime timestamp -); - -GstClockTime -gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy); - -void -gst_vaapi_surface_proxy_set_duration( - GstVaapiSurfaceProxy *proxy, - GstClockTime duration -); - -gboolean -gst_vaapi_surface_proxy_get_interlaced(GstVaapiSurfaceProxy *proxy); - -void -gst_vaapi_surface_proxy_set_interlaced(GstVaapiSurfaceProxy *proxy, gboolean b); - -gboolean -gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy); - -void -gst_vaapi_surface_proxy_set_tff(GstVaapiSurfaceProxy *proxy, gboolean tff); - G_END_DECLS #endif /* GST_VAAPI_SURFACE_PROXY_H */ From 9dcf0820020061baf2ce96f952a87fba138e03e8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Dec 2012 16:02:52 +0100 Subject: [PATCH 0954/3781] surfaceproxy: minor clean-ups. --- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 0d18ac91cc..db0db25bee 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -77,19 +77,18 @@ gst_vaapi_surface_proxy_class(void) GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface) { - GstVaapiMiniObject *object; GstVaapiSurfaceProxy *proxy; g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - object = gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class()); - if (!object) + proxy = (GstVaapiSurfaceProxy *) + gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class()); + if (!proxy) return NULL; - proxy = GST_VAAPI_SURFACE_PROXY(object); - gst_vaapi_surface_proxy_set_context(proxy, context); - gst_vaapi_surface_proxy_set_surface(proxy, surface); + proxy->context = g_object_ref(context); + proxy->surface = g_object_ref(surface); return proxy; } From f5294b813adae6b521b0be0eec2f27c465425570 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 18 Dec 2012 15:15:52 +0100 Subject: [PATCH 0955/3781] Bump library major version. Increase library major so that to cope with API/ABI incompatible changes since 0.4.x series and avoid user issues. --- configure.ac | 16 +++++++++++++++- gst-libs/gst/vaapi/Makefile.am | 5 +++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 256608aa81..748b1d9498 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,11 @@ m4_if(gst_vaapi_pre_version, [0], [], [ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) ]) +# gstreamer-vaapi library (libtool) version number +m4_define([gst_vaapi_lt_current], [1]) +m4_define([gst_vaapi_lt_revision], [0]) +m4_define([gst_vaapi_lt_age], [0]) + # glib version number m4_define([glib_major_version], [2]) m4_define([glib_minor_version], [28]) @@ -80,7 +85,7 @@ AM_INIT_AUTOMAKE([1.11 tar-ustar no-dist-gzip dist-bzip2]) TODAY="`LC_ALL=C date +'%a, %d %b %Y %X %z'`" AC_SUBST(TODAY) -GST_VAAPI_MAJOR_VERSION=gst_vaapi_major_version +GST_VAAPI_MAJOR_VERSION=gst_vaapi_lt_current AC_SUBST(GST_VAAPI_MAJOR_VERSION) LIBVA_PACKAGE_VERSION=libva_x11_package_version @@ -282,6 +287,15 @@ AC_CACHE_CHECK([for JPEG parser], AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_JPEG], [test "$ac_cv_have_gst_jpeg_parser" != "yes"]) +dnl GST_VAAPI_LT_LDFLAGS: +GST_VAAPI_LT_CURRENT=gst_vaapi_lt_current +GST_VAAPI_LT_REV=gst_vaapi_lt_revision +GST_VAAPI_LT_AGE=gst_vaapi_lt_age +GST_VAAPI_LT_VERSION="$GST_VAAPI_LT_CURRENT:$GST_VAAPI_LT_REV:$GST_VAAPI_LT_AGE" +GST_VAAPI_LT_LDFLAGS="-version-info $GST_VAAPI_LT_VERSION" +AC_SUBST(GST_VAAPI_LT_VERSION) +AC_SUBST(GST_VAAPI_LT_LDFLAGS) + dnl GST_ALL_LDFLAGS: dnl LDFLAGS really should only contain flags, not libs - they get added before dnl whatevertarget_LIBS and -L flags here affect the rest of the linking diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 143794b284..b0779d442e 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -226,6 +226,7 @@ libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ libgstvaapi_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ + $(GST_VAAPI_LT_LDFLAGS) \ -export-symbols-regex "^gst_.*vaapi.*" \ $(NULL) @@ -261,6 +262,7 @@ libgstvaapi_drm_@GST_MAJORMINOR@_la_LIBADD = \ libgstvaapi_drm_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ + $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) libgstvaapi_x11_@GST_MAJORMINOR@_la_SOURCES = \ @@ -295,6 +297,7 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_LIBADD = \ libgstvaapi_x11_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ + $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) libgstvaapi_glx_@GST_MAJORMINOR@_la_SOURCES = \ @@ -330,6 +333,7 @@ libgstvaapi_glx_@GST_MAJORMINOR@_la_LIBADD = \ libgstvaapi_glx_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ + $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) libgstvaapi_wayland_@GST_MAJORMINOR@_la_SOURCES = \ @@ -362,6 +366,7 @@ libgstvaapi_wayland_@GST_MAJORMINOR@_la_LIBADD = \ libgstvaapi_wayland_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ + $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) # Extra clean files so that maintainer-clean removes *everything* From 3734b8101d972b7dfc399aab90671bdb03acb28e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 18 Dec 2012 15:29:58 +0100 Subject: [PATCH 0956/3781] NEWS: updates. --- NEWS | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 621c5500d8..cf399a7ca6 100644 --- a/NEWS +++ b/NEWS @@ -4,11 +4,19 @@ Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora Version 0.5.0 - DD.Dec.2012 -* Require glib >= 2.31.2 +* Use GstVideoDecoder API for vaapidecode (+Sreerenj Balachandran) * Add support for raw YUV buffers in vaapisink (+Halley Zhao) * Fix memory leak in GstVaapiVideoBuffer for images and surfaces (Feng Yuan) -Version 0.4.1 - 20.Nov.2012 +Version 0.4.2 - 18.Dec.2012 +* Fix H.264 decoding on Cedar Trail platforms +* Fix MPEG-4 decoding at end-of-stream (Feng Yuan) +* Fix MPEG-4 decoding when a buffer contains multiple packets (Feng Yuan) +* Fix memory leak in GstVaapiVideoBuffer for images and surfaces (Feng Yuan) +* Fix symbols collision between built-in codecparsers/ and system library +* Use GST_PLUGIN_PATH, if set, to install plugin elements (Halley Zhao) + +Version 0.4.1 - 27.Nov.2012 * Add support for H.264 interlaced streams * Add support for Wayland 1.0 protocol (Robert Bradford) * Add upstream bitstream parsers library (codecparsers) From 646b9565e198b6caf6df37e537cfad919a9a01b3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 18 Dec 2012 16:17:22 +0100 Subject: [PATCH 0957/3781] docs: fix entries for GstVaapiSurfaceProxy. --- docs/reference/libs/libs-sections.txt | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 1d9869a19b..bcbaf95970 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -541,26 +541,17 @@ GST_VAAPI_DECODER_VC1_GET_CLASS
gstvaapisurfaceproxy GstVaapiSurfaceProxy -GstVaapiSurfaceProxy -GstVaapiSurfaceProxyClass -gst_vaapi_surface_proxy_new gst_vaapi_surface_proxy_get_context -gst_vaapi_surface_proxy_set_context gst_vaapi_surface_proxy_get_surface gst_vaapi_surface_proxy_get_surface_id +gst_vaapi_surface_proxy_get_user_data +gst_vaapi_surface_proxy_new +gst_vaapi_surface_proxy_ref +gst_vaapi_surface_proxy_replace +gst_vaapi_surface_proxy_set_context gst_vaapi_surface_proxy_set_surface -gst_vaapi_surface_proxy_get_timestamp -gst_vaapi_surface_proxy_set_timestamp -gst_vaapi_surface_proxy_get_interlaced -gst_vaapi_surface_proxy_set_interlaced -gst_vaapi_surface_proxy_get_tff -gst_vaapi_surface_proxy_set_tff +gst_vaapi_surface_proxy_set_user_data +gst_vaapi_surface_proxy_unref -GST_VAAPI_SURFACE_PROXY -GST_VAAPI_IS_SURFACE_PROXY -GST_VAAPI_TYPE_SURFACE_PROXY -gst_vaapi_surface_proxy_get_type -GST_VAAPI_SURFACE_PROXY_CLASS -GST_VAAPI_IS_SURFACE_PROXY_CLASS -GST_VAAPI_SURFACE_PROXY_GET_CLASS +GST_VAAPI_SURFACE_PROXY_SURFACE
From 3506e1d45bbd839c528aa1b94886f05011eb9d9a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 18 Dec 2012 16:21:31 +0100 Subject: [PATCH 0958/3781] docs: remove obsolete gst_vaapi_surface_proxy_get_type(). GstVaapiSurfaceProxy is no longer based on the GType system. --- docs/reference/libs/libs.core.types | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/reference/libs/libs.core.types b/docs/reference/libs/libs.core.types index 12710bd226..b4ce7dad6a 100644 --- a/docs/reference/libs/libs.core.types +++ b/docs/reference/libs/libs.core.types @@ -7,7 +7,6 @@ gst_vaapi_object_get_type gst_vaapi_subpicture_get_type gst_vaapi_surface_get_type gst_vaapi_surface_pool_get_type -gst_vaapi_surface_proxy_get_type gst_vaapi_video_buffer_get_type gst_vaapi_video_pool_get_type gst_vaapi_window_get_type From 4344a1053dc6addc1948d4981a08aeabd26b6bc8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 18 Dec 2012 16:36:01 +0100 Subject: [PATCH 0959/3781] configure: check for GstVideoDecoder API. GstVideoDecoder API is part of an unreleased GStreamer 0.10 stack. In particular, this is only available in git 0.10 branch or GStreamer >= 1.0 stack. Interested parties may either use upstream git 0.10 branch or backport the necessary support for GstVideoDecoder API, thus including helper tools like GstVideoCodecFrame et al. --- configure.ac | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/configure.ac b/configure.ac index 748b1d9498..68dcd0eead 100644 --- a/configure.ac +++ b/configure.ac @@ -211,6 +211,33 @@ if test "$ac_cv_have_gst_video_overlay_composition" != "yes"; then AC_MSG_ERROR([GstVideoOverlayComposition is not available]) fi +dnl ... GstVideoDecoder (gstreamer-video) +AC_CACHE_CHECK([for GstVideoDecoder], + ac_cv_have_gst_video_decoder, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_VIDEO_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $GST_LIBS $GST_VIDEO_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[GstVideoCodecFrame *f; + GstVideoDecoder vdec; + f = g_slice_new0(GstVideoCodecFrame); + f->ref_count = 1; + gst_video_decoder_have_frame(&vdec); + gst_video_decoder_finish_frame(&vdec, f); + gst_video_codec_frame_unref(f);]])], + [ac_cv_have_gst_video_decoder="yes"], + [ac_cv_have_gst_video_decoder="no"] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +]) +if test "$ac_cv_have_gst_video_decoder" != "yes"; then + AC_MSG_ERROR([GstVideoDecoder is not available]) +fi + dnl GStreamer -bad plugins PKG_CHECK_MODULES([GST_BASEVIDEO], [gstreamer-basevideo-$GST_MAJORMINOR >= gst_plugins_bad_version]) From 9e643a614771617be59e21ee2c63a6cb56ff36fe Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 21 Dec 2012 14:29:01 +0100 Subject: [PATCH 0960/3781] Add videoutils submodule for GstVideoDecoder APIs. --- .gitmodules | 3 ++ autogen.sh | 8 ++++- configure.ac | 6 ++-- ext/Makefile.am | 19 ++++++++++ ext/videoutils | 1 + gst-libs/gst/Makefile.am | 2 +- gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/video/Makefile.am | 64 ++++++++++++++++++++++++++++++++++ gst/vaapi/Makefile.am | 3 +- 9 files changed, 101 insertions(+), 6 deletions(-) create mode 160000 ext/videoutils create mode 100644 gst-libs/gst/video/Makefile.am diff --git a/.gitmodules b/.gitmodules index e40ceed55b..bad3c46dea 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "ext/codecparsers"] path = ext/codecparsers url = git://gitorious.org/vaapi/gstreamer-codecparsers.git +[submodule "ext/videoutils"] + path = ext/videoutils + url = git://gitorious.org/vaapi/gstreamer-videoutils.git diff --git a/autogen.sh b/autogen.sh index 4314352f43..b4a63f367b 100755 --- a/autogen.sh +++ b/autogen.sh @@ -20,7 +20,13 @@ if test -z "$GIT"; then echo "*** No git found ***" exit 1 else - if test ! -f ext/codecparsers/autogen.sh; then + submodule_init="no" + for ext_module in codecparsers videoutils; do + if test ! -f ext/${ext_module}/autogen.sh; then + submodule_init="yes" + fi + done + if test "$submodule_init" = "yes"; then $GIT submodule init fi $GIT submodule update diff --git a/configure.ac b/configure.ac index 68dcd0eead..657bea8e7d 100644 --- a/configure.ac +++ b/configure.ac @@ -234,9 +234,8 @@ AC_CACHE_CHECK([for GstVideoDecoder], CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) -if test "$ac_cv_have_gst_video_decoder" != "yes"; then - AC_MSG_ERROR([GstVideoDecoder is not available]) -fi +AM_CONDITIONAL([USE_LOCAL_GST_VIDEO_DECODER], + [test "$ac_cv_have_gst_video_decoder" != "yes"]) dnl GStreamer -bad plugins PKG_CHECK_MODULES([GST_BASEVIDEO], @@ -597,6 +596,7 @@ debian.upstream/libgstvaapi-x11.install.in gst-libs/gst/Makefile gst-libs/gst/codecparsers/Makefile gst-libs/gst/vaapi/Makefile + gst-libs/gst/video/Makefile gst/Makefile gst/vaapi/Makefile pkgconfig/Makefile diff --git a/ext/Makefile.am b/ext/Makefile.am index bad55d50e3..cfb2bc0300 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -25,5 +25,24 @@ codecparsers_source_h = \ EXTRA_DIST += $(codecparsers_source_h:%.h=$(codecparsers_srcdir)/%.h) +videoutils_srcdir = \ + $(top_srcdir)/ext/videoutils/gst-libs/gst/video + +videoutils_source_c = \ + gstvideodecoder.c \ + gstvideoutils.c \ + video.c \ + $(NULL) + +EXTRA_DIST += $(videoutils_source_c:%.c=$(videoutils_srcdir)/%.c) + +videoutils_source_h = \ + gstvideodecoder.h \ + gstvideoutils.h \ + video.h \ + $(NULL) + +EXTRA_DIST += $(videoutils_source_h:%.h=$(videoutils_srcdir)/%.h) + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/ext/videoutils b/ext/videoutils new file mode 160000 index 0000000000..251df2b095 --- /dev/null +++ b/ext/videoutils @@ -0,0 +1 @@ +Subproject commit 251df2b0958e6265cf5752fdfc82c69a2869eca7 diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 06d14db0df..6d09e2b5ee 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = codecparsers vaapi +SUBDIRS = codecparsers video vaapi # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in $(gen_headers) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index b0779d442e..79684e2ef7 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -38,6 +38,7 @@ libgstvaapi_libs = \ $(GST_VIDEO_LIBS) \ $(GST_CODEC_PARSERS_LIBS) \ $(LIBVA_LIBS) \ + $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la \ $(top_builddir)/gst-libs/gst/codecparsers/libgstvaapi-codecparsers.la libgstvaapi_source_c = \ diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am new file mode 100644 index 0000000000..fc0ca0121e --- /dev/null +++ b/gst-libs/gst/video/Makefile.am @@ -0,0 +1,64 @@ +noinst_LTLIBRARIES = \ + libgstvaapi-videoutils.la \ + $(NULL) + +local_videoutils_srcdir = \ + $(top_srcdir)/ext/videoutils/gst-libs/gst/video + +libgstvaapi_videoutils_cflags = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + $(GST_BASE_CFLAGS) \ + $(GST_CFLAGS) \ + $(NULL) + +libgstvaapi_videoutils_libs = \ + $(GST_BASE_LIBS) \ + $(GST_LIBS) \ + $(NULL) + +gen_source_c = +gen_source_h = + +if USE_LOCAL_GST_VIDEO_DECODER +gen_source_c += gstvideodecoder.c gstvideoutils.c video.c +gen_source_h += gstvideodecoder.h gstvideoutils.h video.h +endif + +GENFILES = \ + $(gen_source_c) \ + $(gen_source_h) \ + $(NULL) + +nodist_EXTRA_libgstvaapi_videoutils_la_SOURCES = dummy.c + +nodist_libgstvaapi_videoutils_la_SOURCES = \ + $(gen_source_c) \ + $(NULL) + +libgstvaapi_videoutils_la_CFLAGS = \ + $(libgstvaapi_videoutils_cflags) \ + $(NULL) + +libgstvaapi_videoutils_la_LIBADD = \ + $(libgstvaapi_videoutils_libs) \ + $(NULL) + +libgstvaapi_videoutils_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(NULL) + +all-local: .timestamp.symlinks + +.timestamp.symlinks: $(GENFILES) + touch $@ + +$(gen_source_c): %.c: $(local_videoutils_srcdir)/%.c %.h + $(LN_S) -f $< $@ +$(gen_source_h): %.h: $(local_videoutils_srcdir)/%.h + $(LN_S) -f $< $@ + +DISTCLEANFILES = $(GENFILES) .timestamp.symlinks + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 4da267e31e..df61ad96f8 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -68,7 +68,8 @@ libgstvaapi_la_LIBADD = \ $(GST_VIDEO_LIBS) \ $(GST_INTERFACES_LIBS) \ $(GST_BASEVIDEO_LIBS) \ - $(GST_PLUGINS_BASE_LIBS) + $(GST_PLUGINS_BASE_LIBS) \ + $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvaapi_la_LIBTOOLFLAGS = --tag=disable-static From 0ff8556f6518a33618025bd59fa421b52f0ee0e0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 27 Dec 2012 09:55:14 +0100 Subject: [PATCH 0961/3781] vaapidecode: avoid double release of frame on error. Don't call gst_video_decoder_drop_frame() if gst_video_decoder_finish_frame() was already called before and it returned an error. In that case, we were releasing the frame again, thus leading to a "double-free" condition. --- gst/vaapi/gstvaapidecode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b588046342..4c459d6152 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -276,7 +276,6 @@ error_create_buffer: error_commit_buffer: { GST_DEBUG("video sink rejected the video buffer (error %d)", ret); - gst_video_decoder_drop_frame(vdec, out_frame); gst_video_codec_frame_unref(out_frame); return GST_FLOW_UNEXPECTED; } From 3d3f37c55841861d5eee5628dde9d5ebbdf4a9ed Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 27 Dec 2012 10:35:45 +0100 Subject: [PATCH 0962/3781] vaapidecode: use GST_ERROR to print error messages. --- gst/vaapi/gstvaapidecode.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4c459d6152..95339f8945 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -241,13 +241,13 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) /* ERRORS */ error_decode_timeout: { - GST_DEBUG("decode timeout. Decoder required a VA surface but none " - "got available within one second"); + GST_WARNING("decode timeout. Decoder required a VA surface but none " + "got available within one second"); return GST_FLOW_UNEXPECTED; } error_decode: { - GST_DEBUG("decode error %d", status); + GST_ERROR("decode error %d", status); switch (status) { case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: @@ -266,7 +266,7 @@ error_create_buffer: const GstVaapiID surface_id = gst_vaapi_surface_get_id(GST_VAAPI_SURFACE_PROXY_SURFACE(proxy)); - GST_DEBUG("video sink failed to create video buffer for proxy'ed " + GST_ERROR("video sink failed to create video buffer for proxy'ed " "surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); gst_video_decoder_drop_frame(vdec, out_frame); @@ -575,17 +575,17 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) /* ERRORS */ error_no_display: { - GST_DEBUG("failed to retrieve VA display"); + GST_ERROR("failed to retrieve VA display"); return FALSE; } error_no_decode_caps: { - GST_DEBUG("failed to retrieve VA decode caps"); + GST_ERROR("failed to retrieve VA decode caps"); return FALSE; } error_no_memory: { - GST_DEBUG("failed to allocate allowed-caps set"); + GST_ERROR("failed to allocate allowed-caps set"); gst_caps_unref(decode_caps); return FALSE; } From c727e5b6d6944851d1dd19b3b45eabefb039d899 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 2 Jan 2013 16:06:18 +0100 Subject: [PATCH 0963/3781] decoder: drop useless checks for codec objects. Codec objects are used internally only and they are bound to be created with a valid GstVaapiDecoder object. --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 8 -------- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 4 ---- 2 files changed, 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 450e50eb8f..eddd7bd6b4 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -75,8 +75,6 @@ gst_vaapi_codec_object_new(const GstVaapiCodecObjectClass *object_class, GstVaapiCodecObject *va_obj; GstVaapiCodecObjectConstructorArgs args; - g_return_val_if_fail(codec != NULL, NULL); - obj = gst_vaapi_mini_object_new0(&object_class->parent_class); if (!obj) return NULL; @@ -139,8 +137,6 @@ gst_vaapi_iq_matrix_new( { GstVaapiCodecObject *object; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - object = gst_vaapi_codec_object_new( &GstVaapiIqMatrixClass, GST_VAAPI_CODEC_BASE(decoder), @@ -188,8 +184,6 @@ gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size) { GstVaapiCodecObject *object; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - object = gst_vaapi_codec_object_new( &GstVaapiBitPlaneClass, GST_VAAPI_CODEC_BASE(decoder), @@ -241,8 +235,6 @@ gst_vaapi_huffman_table_new( { GstVaapiCodecObject *object; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - object = gst_vaapi_codec_object_new( &GstVaapiHuffmanTableClass, GST_VAAPI_CODEC_BASE(decoder), diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 541a0975bc..eb6a83f01c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -183,8 +183,6 @@ gst_vaapi_picture_new( { GstVaapiCodecObject *object; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - object = gst_vaapi_codec_object_new( &GstVaapiPictureClass, GST_VAAPI_CODEC_BASE(decoder), @@ -405,8 +403,6 @@ gst_vaapi_slice_new( { GstVaapiCodecObject *object; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - object = gst_vaapi_codec_object_new( &GstVaapiSliceClass, GST_VAAPI_CODEC_BASE(decoder), From 63a7e424847d55a0531f106777c528385ed8131e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 27 Dec 2012 18:52:43 +0100 Subject: [PATCH 0964/3781] decoder: introduce lists of units to decode before/after frame. Theory of operations: all units marked as "slice" are moved to the "units" list. Since this list only contains slice data units, the prev_slice pointer was removed. Besides, we now maintain two extra lists of units to be decoded before or after slice data units. In particular, all units in the "pre_units" list will be decoded before GstVaapiDecoder::start_frame() is called and units in the "post_units" list will be decoded after GstVaapiDecoder::end_frame() is called. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 78 +++++++++++++++------- gst-libs/gst/vaapi/gstvaapidecoder_frame.c | 32 ++++----- gst-libs/gst/vaapi/gstvaapidecoder_frame.h | 7 +- gst-libs/gst/vaapi/gstvaapidecoder_unit.h | 2 +- 4 files changed, 75 insertions(+), 44 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index be4d1f9cc1..94477e6839 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -150,6 +150,7 @@ do_parse(GstVaapiDecoder *decoder, GstVaapiDecoderFrame *frame; GstVaapiDecoderUnit *unit; GstVaapiDecoderStatus status; + GSList **unit_list_ptr; *got_unit_size_ptr = 0; *got_frame_ptr = FALSE; @@ -178,23 +179,48 @@ do_parse(GstVaapiDecoder *decoder, return status; } - if (GST_VAAPI_DECODER_UNIT_IS_FRAME_START(unit) && frame->prev_slice) { + if (GST_VAAPI_DECODER_UNIT_IS_FRAME_START(unit) && frame->units) { parser_state_set_pending_unit(ps, adapter, unit); goto got_frame; } got_unit: unit->offset = frame->output_offset; - frame->units = g_slist_prepend(frame->units, unit); frame->output_offset += unit->size; + if (GST_VAAPI_DECODER_UNIT_IS_SLICE(unit)) - frame->prev_slice = unit; + unit_list_ptr = &frame->units; + else if (GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit)) + unit_list_ptr = &frame->post_units; + else + unit_list_ptr = &frame->pre_units; + *unit_list_ptr = g_slist_prepend(*unit_list_ptr, unit); *got_unit_size_ptr = unit->size; if (GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit)) { got_frame: - frame->units = g_slist_reverse(frame->units); - *got_frame_ptr = TRUE; + frame->units = g_slist_reverse(frame->units); + frame->pre_units = g_slist_reverse(frame->pre_units); + frame->post_units = g_slist_reverse(frame->post_units); + *got_frame_ptr = TRUE; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +do_decode_list(GstVaapiDecoder *decoder, GSList *units) +{ + GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); + GstVaapiDecoderStatus status; + GSList *l; + + for (l = units; l != NULL; l = l->next) { + GstVaapiDecoderUnit * const unit = l->data; + if (GST_VAAPI_DECODER_UNIT_IS_SKIPPED(unit)) + continue; + status = klass->decode(decoder, unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; } return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -206,33 +232,35 @@ do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) GstVaapiParserState * const ps = &decoder->priv->parser_state; GstVaapiDecoderFrame * const frame = base_frame->user_data; GstVaapiDecoderStatus status; - GSList *l; ps->current_frame = base_frame; - if (klass->start_frame) { - for (l = frame->units; l != NULL; l = l->next) { - GstVaapiDecoderUnit * const unit = l->data; - if (GST_VAAPI_DECODER_UNIT_IS_SLICE(unit)) { - status = klass->start_frame(decoder, unit); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - break; - } - } - } - - for (l = frame->units; l != NULL; l = l->next) { - GstVaapiDecoderUnit * const unit = l->data; - if (GST_VAAPI_DECODER_UNIT_IS_SKIPPED(unit)) - continue; - status = klass->decode(decoder, unit); + if (frame->pre_units) { + status = do_decode_list(decoder, frame->pre_units); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; } - if (klass->end_frame) { - status = klass->end_frame(decoder); + if (frame->units) { + if (klass->start_frame) { + status = klass->start_frame(decoder, frame->units->data); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + + status = do_decode_list(decoder, frame->units); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + if (klass->end_frame) { + status = klass->end_frame(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + } + + if (frame->post_units) { + status = do_decode_list(decoder, frame->post_units); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.c b/gst-libs/gst/vaapi/gstvaapidecoder_frame.c index cddb5e5276..cde29ce46b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_frame.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_frame.c @@ -37,6 +37,17 @@ gst_vaapi_decoder_frame_class(void) return &GstVaapiDecoderFrameClass; } +static inline void +free_units(GSList **units_ptr) +{ + GSList * const units = *units_ptr; + + if (units) { + g_slist_free_full(units, (GDestroyNotify)gst_vaapi_mini_object_unref); + *units_ptr = NULL; + } +} + /** * gst_vaapi_decoder_frame_new: * @@ -47,17 +58,8 @@ gst_vaapi_decoder_frame_class(void) GstVaapiDecoderFrame * gst_vaapi_decoder_frame_new(void) { - GstVaapiDecoderFrame *frame; - - frame = (GstVaapiDecoderFrame *) - gst_vaapi_mini_object_new(gst_vaapi_decoder_frame_class()); - if (!frame) - return NULL; - - frame->output_offset = 0; - frame->units = NULL; - frame->prev_slice = NULL; - return frame; + return (GstVaapiDecoderFrame *) + gst_vaapi_mini_object_new0(gst_vaapi_decoder_frame_class()); } /** @@ -73,9 +75,7 @@ gst_vaapi_decoder_frame_new(void) void gst_vaapi_decoder_frame_free(GstVaapiDecoderFrame *frame) { - if (frame->units) { - g_slist_free_full(frame->units, - (GDestroyNotify)gst_vaapi_mini_object_unref); - frame->units = NULL; - } + free_units(&frame->units); + free_units(&frame->pre_units); + free_units(&frame->post_units); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h index 69a6c42f2f..609cafd750 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h @@ -54,7 +54,9 @@ typedef enum { * @output_offset: current offset to the reconstructed #GstBuffer for * this #GstVideoCodecFrame. This is used to initialize the decoder * unit offset - * @units: list of #GstVaapiDecoderUnit objects + * @units: list of #GstVaapiDecoderUnit objects (slice data) + * @pre_units: list of units to decode before GstVaapiDecoder:start_frame() + * @post_units: list of units to decode after GstVaapiDecoder:end_frame() * @prev_slice: previous #GstVaapiDecoderUnit that was a slice, or NULL * if no slice data unit was received yet * @@ -68,7 +70,8 @@ struct _GstVaapiDecoderFrame { guint output_offset; GSList *units; - GstVaapiDecoderUnit *prev_slice; + GSList *pre_units; + GSList *post_units; }; G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h index 1b4746d7a0..70742e25ce 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h @@ -40,7 +40,7 @@ typedef struct _GstVaapiDecoderUnit GstVaapiDecoderUnit; * @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: marks the unit contains slice data. + * @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. From 549b5a93890908df37201c7d5038e5d6f87b9e0b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 27 Dec 2012 14:41:04 +0100 Subject: [PATCH 0965/3781] mpeg2: add codec specific decoder unit. Introduce new GstVaapiDecoderUnitMpeg2 object, which holds the standard GstMpegVideoPacket and additional parsed header info. Besides, we now parse as early as in the _parse() function so that to avoid un-necessary creation of sub-buffers in _decode() for video packets that are not slices. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 366 ++++++++++++++------- 1 file changed, 239 insertions(+), 127 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index f3e35b8923..15f1aa02d6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -61,7 +61,10 @@ G_DEFINE_TYPE(GstVaapiDecoderMpeg2, } \ } G_STMT_END -/* PTS Generator */ +/* ------------------------------------------------------------------------- */ +/* --- PTS Generator --- */ +/* ------------------------------------------------------------------------- */ + typedef struct _PTSGenerator PTSGenerator; struct _PTSGenerator { GstClockTime gop_pts; // Current GOP PTS @@ -164,6 +167,48 @@ pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn) return pts; } +/* ------------------------------------------------------------------------- */ +/* --- MPEG-2 Decoder Units --- */ +/* ------------------------------------------------------------------------- */ + +typedef struct _GstVaapiDecoderUnitMpeg2 GstVaapiDecoderUnitMpeg2; +struct _GstVaapiDecoderUnitMpeg2 { + GstVaapiDecoderUnit base; + GstMpegVideoPacket packet; + guint8 extension_type; /* for Extension packets */ + union { + GstMpegVideoSequenceHdr seq_hdr; + GstMpegVideoSequenceExt seq_ext; + GstMpegVideoGop gop; + GstMpegVideoQuantMatrixExt quant_matrix; + GstMpegVideoPictureHdr pic_hdr; + GstMpegVideoPictureExt pic_ext; + } data; +}; + +static GstVaapiDecoderUnitMpeg2 * +gst_vaapi_decoder_unit_mpeg2_new(guint size) +{ + GstVaapiDecoderUnitMpeg2 *unit; + + static const GstVaapiMiniObjectClass GstVaapiDecoderUnitMpeg2Class = { + sizeof(GstVaapiDecoderUnitMpeg2), + (GDestroyNotify)gst_vaapi_decoder_unit_finalize + }; + + unit = (GstVaapiDecoderUnitMpeg2 *) + gst_vaapi_mini_object_new(&GstVaapiDecoderUnitMpeg2Class); + if (!unit) + return NULL; + + gst_vaapi_decoder_unit_init(&unit->base, size); + return unit; +} + +/* ------------------------------------------------------------------------- */ +/* --- MPEG-2 Decoder --- */ +/* ------------------------------------------------------------------------- */ + struct _GstVaapiDecoderMpeg2Private { GstVaapiProfile profile; GstVaapiProfile hw_profile; @@ -492,16 +537,26 @@ decode_current_picture(GstVaapiDecoderMpeg2 *decoder) } static GstVaapiDecoderStatus -decode_sequence(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +parse_sequence(GstVaapiDecoderUnitMpeg2 *unit) +{ + GstMpegVideoPacket * const packet = &unit->packet; + + if (!gst_mpeg_video_parse_sequence_header(&unit->data.seq_hdr, + packet->data, packet->size, packet->offset)) { + GST_ERROR("failed to parse sequence header"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr; - if (!gst_mpeg_video_parse_sequence_header(seq_hdr, buf, buf_size, 4)) { - GST_ERROR("failed to parse sequence header"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + *seq_hdr = unit->data.seq_hdr; priv->fps_n = seq_hdr->fps_n; priv->fps_d = seq_hdr->fps_d; @@ -522,7 +577,21 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) } static GstVaapiDecoderStatus -decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +parse_sequence_ext(GstVaapiDecoderUnitMpeg2 *unit) +{ + GstMpegVideoPacket * const packet = &unit->packet; + + if (!gst_mpeg_video_parse_sequence_extension(&unit->data.seq_ext, + packet->data, packet->size, packet->offset)) { + GST_ERROR("failed to parse sequence-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnitMpeg2 *unit) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; @@ -531,10 +600,8 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) GstVaapiProfile profile; guint width, height; - if (!gst_mpeg_video_parse_sequence_extension(seq_ext, buf, buf_size, 4)) { - GST_ERROR("failed to parse sequence-extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + *seq_ext = unit->data.seq_ext; + priv->has_seq_ext = TRUE; priv->progressive_sequence = seq_ext->progressive; gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence); @@ -595,40 +662,58 @@ decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; gst_vaapi_dpb_flush(priv->dpb); - return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +parse_quant_matrix_ext(GstVaapiDecoderUnitMpeg2 *unit) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoQuantMatrixExt * const quant_matrix_ext = &priv->quant_matrix_ext; + GstMpegVideoPacket * const packet = &unit->packet; - if (!gst_mpeg_video_parse_quant_matrix_extension(quant_matrix_ext, buf, buf_size, 4)) { + if (!gst_mpeg_video_parse_quant_matrix_extension(&unit->data.quant_matrix, + packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse quant-matrix-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnitMpeg2 *unit) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + + priv->quant_matrix_ext = unit->data.quant_matrix; priv->has_quant_matrix_ext = TRUE; priv->quant_matrix_changed = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +parse_gop(GstVaapiDecoderUnitMpeg2 *unit) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoGop gop; + GstMpegVideoPacket * const packet = &unit->packet; - if (!gst_mpeg_video_parse_gop(&gop, buf, buf_size, 4)) { + if (!gst_mpeg_video_parse_gop(&unit->data.gop, + packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse GOP"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} - priv->closed_gop = gop.closed_gop; - priv->broken_link = gop.broken_link; +static GstVaapiDecoderStatus +decode_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoGop * const gop = &unit->data.gop; + + priv->closed_gop = gop->closed_gop; + priv->broken_link = gop->broken_link; GST_DEBUG("GOP %02u:%02u:%02u:%02u (closed_gop %d, broken_link %d)", - gop.hour, gop.minute, gop.second, gop.frame, + gop->hour, gop->minute, gop->second, gop->frame, priv->closed_gop, priv->broken_link); pts_sync(&priv->tsg, GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts); @@ -636,13 +721,28 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) } static GstVaapiDecoderStatus -decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +parse_picture(GstVaapiDecoderUnitMpeg2 *unit) +{ + GstMpegVideoPacket * const packet = &unit->packet; + + if (!gst_mpeg_video_parse_picture_header(&unit->data.pic_hdr, + packet->data, packet->size, packet->offset)) { + GST_ERROR("failed to parse picture header"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr; GstVaapiPicture *picture; GstVaapiDecoderStatus status; + *pic_hdr = unit->data.pic_hdr; + status = ensure_context(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { GST_ERROR("failed to reset context"); @@ -677,10 +777,6 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) return status; } - if (!gst_mpeg_video_parse_picture_header(pic_hdr, buf, buf_size, 4)) { - GST_ERROR("failed to parse picture header"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } priv->has_pic_ext = FALSE; switch (pic_hdr->pic_type) { @@ -704,20 +800,32 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) picture->pts = pts_eval(&priv->tsg, GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts, pic_hdr->tsn); picture->poc = pts_get_poc(&priv->tsg); - return status; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +parse_picture_ext(GstVaapiDecoderUnitMpeg2 *unit) +{ + GstMpegVideoPacket * const packet = &unit->packet; + + if (!gst_mpeg_video_parse_picture_extension(&unit->data.pic_ext, + packet->data, packet->size, packet->offset)) { + GST_ERROR("failed to parse picture-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnitMpeg2 *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext; GstVaapiPicture * const picture = priv->current_picture; - if (!gst_mpeg_video_parse_picture_extension(pic_ext, buf, buf_size, 4)) { - GST_ERROR("failed to parse picture-extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + *pic_ext = unit->data.pic_ext; + priv->has_pic_ext = TRUE; if (priv->progressive_sequence && !pic_ext->progressive_frame) { @@ -855,17 +963,14 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) } static GstVaapiDecoderStatus -decode_slice( - GstVaapiDecoderMpeg2 *decoder, - int slice_no, - guchar *buf, - guint buf_size -) +decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstVaapiPicture * const picture = priv->current_picture; GstVaapiSlice *slice; VASliceParameterBufferMPEG2 *slice_param; + GstMpegVideoPacket * const packet = &unit->packet; + const gint slice_no = packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN; GstBitReader br; gint mb_x, mb_y, mb_inc; guint macroblock_offset; @@ -874,12 +979,24 @@ decode_slice( guint8 intra_slice = 0; guint8 extra_bit_slice, junk8; - GST_DEBUG("slice %d @ %p, %u bytes)", slice_no, buf, buf_size); + GST_DEBUG("slice %d (%u bytes)", slice_no, packet->size); + + if (!picture) + return GST_VAAPI_DECODER_STATUS_SUCCESS; if (picture->slices->len == 0 && !fill_picture(decoder, picture)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, buf, buf_size); + unit->base.buffer = gst_buffer_create_sub( + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, + unit->base.offset, unit->base.size); + if (!unit->base.buffer) { + GST_ERROR("failed to allocate slice data"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, + GST_BUFFER_DATA(unit->base.buffer), packet->size); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -887,7 +1004,7 @@ decode_slice( gst_vaapi_picture_add_slice(picture, slice); /* Parse slice */ - gst_bit_reader_init(&br, buf, buf_size); + gst_bit_reader_init(&br, GST_BUFFER_DATA(unit->base.buffer), packet->size); SKIP(&br, 32); /* slice_start_code */ if (priv->height > 2800) READ_UINT8(&br, slice_vertical_position_extension, 3); @@ -942,73 +1059,55 @@ scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) } static GstVaapiDecoderStatus -decode_packet(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size) +decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + const GstMpegVideoPacketTypeCode type = unit->packet.type; GstVaapiDecoderStatus status; - guchar type; - /* The packet defined by buf and buf_size contains the start code */ - type = buf[3]; switch (type) { case GST_MPEG_VIDEO_PACKET_PICTURE: if (!priv->width || !priv->height) goto unknown_picture_size; - status = decode_picture(decoder, buf, buf_size); + status = decode_picture(decoder, unit); break; case GST_MPEG_VIDEO_PACKET_SEQUENCE: - status = decode_sequence(decoder, buf, buf_size); + status = decode_sequence(decoder, unit); break; - case GST_MPEG_VIDEO_PACKET_EXTENSION: { - const guchar id = buf[4] >> 4; - switch (id) { + case GST_MPEG_VIDEO_PACKET_EXTENSION: + switch (unit->extension_type) { case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: - status = decode_sequence_ext(decoder, buf, buf_size); + status = decode_sequence_ext(decoder, unit); break; case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: - status = decode_quant_matrix_ext(decoder, buf, buf_size); + status = decode_quant_matrix_ext(decoder, unit); break; case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: if (!priv->width || !priv->height) goto unknown_picture_size; - status = decode_picture_ext(decoder, buf, buf_size); + status = decode_picture_ext(decoder, unit); break; default: // Ignore unknown start-code extensions - GST_WARNING("unsupported start code extension (0x%02x)", id); + GST_WARNING("unsupported packet extension type 0x%02x", + unit->extension_type); status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; } break; - } case GST_MPEG_VIDEO_PACKET_SEQUENCE_END: status = decode_sequence_end(decoder); break; case GST_MPEG_VIDEO_PACKET_GOP: - status = decode_gop(decoder, buf, buf_size); - break; - case GST_MPEG_VIDEO_PACKET_USER_DATA: - // Ignore user-data packets - status = GST_VAAPI_DECODER_STATUS_SUCCESS; + status = decode_gop(decoder, unit); break; default: if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { - if (!priv->current_picture) - goto undefined_picture; - status = decode_slice( - decoder, - type - GST_MPEG_VIDEO_PACKET_SLICE_MIN, - buf, buf_size - ); + status = decode_slice(decoder, unit); break; } - else if (type >= 0xb9 && type <= 0xff) { - // Ignore system start codes (PES headers) - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } - GST_WARNING("unsupported start code (0x%02x)", type); + GST_WARNING("unsupported packet type 0x%02x", type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } @@ -1019,28 +1118,6 @@ unknown_picture_size: // i.e. missing sequence headers, or not parsed correctly GST_WARNING("failed to parse picture of unknown size"); return GST_VAAPI_DECODER_STATUS_SUCCESS; - -undefined_picture: - // Ignore packet while picture is undefined - // i.e. missing picture headers, or not parsed correctly - GST_WARNING("failed to parse slice with undefined picture"); - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) -{ - GstVaapiDecoderStatus status; - guchar *buf; - guint buf_size; - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - - status = decode_packet(decoder, buf, buf_size); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - return status; } static GstVaapiDecoderStatus @@ -1065,11 +1142,12 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, { GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2(base_decoder); - GstVaapiDecoderUnit *unit = NULL; + GstVaapiDecoderUnitMpeg2 *unit; GstVaapiDecoderStatus status; + GstMpegVideoPacket *packet; + const guchar *buf; guint32 start_code; - guint8 pkt_type, ext_type; - guint size, buf_size, flags = 0; + guint size, buf_size, flags; gint ofs; status = ensure_decoder(decoder); @@ -1096,13 +1174,62 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, } buf_size = ofs; - unit = gst_vaapi_decoder_unit_new(buf_size); + buf = gst_adapter_peek(adapter, buf_size); + if (!buf) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + unit = gst_vaapi_decoder_unit_mpeg2_new(buf_size); if (!unit) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + packet = &unit->packet; + packet->data = buf; + packet->size = buf_size; + packet->offset = 4; + packet->type = start_code & 0xff; + + /* Parse data */ + switch (packet->type) { + case GST_MPEG_VIDEO_PACKET_SEQUENCE: + status = parse_sequence(unit); + break; + case GST_MPEG_VIDEO_PACKET_GOP: + status = parse_gop(unit); + break; + case GST_MPEG_VIDEO_PACKET_PICTURE: + status = parse_picture(unit); + break; + case GST_MPEG_VIDEO_PACKET_EXTENSION: + if (G_UNLIKELY(buf_size < 5)) { + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + unit->extension_type = buf[4] >> 4; + switch (unit->extension_type) { + case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: + status = parse_sequence_ext(unit); + break; + case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: + status = parse_quant_matrix_ext(unit); + break; + case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: + status = parse_picture_ext(unit); + break; + default: + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + break; + default: + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + /* Check for start of new picture */ - pkt_type = start_code & 0xff; - switch (pkt_type) { + flags = 0; + switch (packet->type) { case GST_MPEG_VIDEO_PACKET_SEQUENCE_END: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; @@ -1115,25 +1242,20 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, case GST_MPEG_VIDEO_PACKET_PICTURE: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; - case GST_MPEG_VIDEO_PACKET_EXTENSION: - if (buf_size < 5) - break; - gst_adapter_copy(adapter, &ext_type, 4, 1); - switch (ext_type) { - case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - break; - } - break; default: - if (pkt_type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && - pkt_type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) + if (packet->type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + packet->type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + + // Ignore system start codes (PES headers) + else if (packet->type >= 0xb9 && packet->type <= 0xff) + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; break; } GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); - *unit_ptr = unit; + unit->packet.data = NULL; + *unit_ptr = &unit->base; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1148,17 +1270,7 @@ gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base_decoder, status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - - unit->buffer = gst_buffer_create_sub( - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, - unit->offset, unit->size); - if (!unit->buffer) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - - status = decode_buffer(decoder, unit->buffer); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + return decode_unit(decoder, (GstVaapiDecoderUnitMpeg2 *)unit); } static void From 4a39efa9f672af85971de865e24eff39f01527fb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 27 Dec 2012 14:54:29 +0100 Subject: [PATCH 0966/3781] mpeg2: parse slice() header earlier. Parse slice() header and first macroblock position earlier in _parse() function instead of waiting for the _decode() stage. This doesn't change anything but readability. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 128 +++++++++++++-------- 1 file changed, 78 insertions(+), 50 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 15f1aa02d6..36a35492a6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -171,6 +171,17 @@ pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn) /* --- MPEG-2 Decoder Units --- */ /* ------------------------------------------------------------------------- */ +typedef struct _GstMpegVideoSliceHdr GstMpegVideoSliceHdr; +struct _GstMpegVideoSliceHdr { + guint16 slice_horizontal_position; + guint16 slice_vertical_position; + guint8 quantiser_scale_code; + guint8 intra_slice; + + /* Size of the slice() header in bits */ + guint header_size; +}; + typedef struct _GstVaapiDecoderUnitMpeg2 GstVaapiDecoderUnitMpeg2; struct _GstVaapiDecoderUnitMpeg2 { GstVaapiDecoderUnit base; @@ -183,6 +194,7 @@ struct _GstVaapiDecoderUnitMpeg2 { GstMpegVideoQuantMatrixExt quant_matrix; GstMpegVideoPictureHdr pic_hdr; GstMpegVideoPictureExt pic_ext; + GstMpegVideoSliceHdr slice_hdr; } data; }; @@ -733,6 +745,58 @@ parse_picture(GstVaapiDecoderUnitMpeg2 *unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static GstVaapiDecoderStatus +parse_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoSliceHdr * const slice_hdr = &unit->data.slice_hdr; + GstMpegVideoPacket * const packet = &unit->packet; + GstBitReader br; + gint mb_x, mb_y, mb_inc; + guint8 slice_vertical_position_extension; + guint8 extra_bit_slice, junk8; + + gst_bit_reader_init(&br, packet->data + packet->offset, packet->size); + if (priv->height > 2800) + READ_UINT8(&br, slice_vertical_position_extension, 3); + if (priv->has_seq_scalable_ext) { + GST_ERROR("failed to parse slice with sequence_scalable_extension()"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + READ_UINT8(&br, slice_hdr->quantiser_scale_code, 5); + READ_UINT8(&br, extra_bit_slice, 1); + if (!extra_bit_slice) + slice_hdr->intra_slice = 0; + else { + READ_UINT8(&br, slice_hdr->intra_slice, 1); + READ_UINT8(&br, junk8, 7); + READ_UINT8(&br, extra_bit_slice, 1); + while (extra_bit_slice) { + READ_UINT8(&br, junk8, 8); + READ_UINT8(&br, extra_bit_slice, 1); + } + } + slice_hdr->header_size = 32 + gst_bit_reader_get_pos(&br); + + mb_y = packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN; + mb_x = -1; + do { + if (!decode_vlc(&br, &mb_inc, mpeg2_mbaddr_vlc_table, + G_N_ELEMENTS(mpeg2_mbaddr_vlc_table))) { + GST_WARNING("failed to decode first macroblock_address_increment"); + goto failed; + } + mb_x += mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE ? 33 : mb_inc; + } while (mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE); + + slice_hdr->slice_horizontal_position = mb_x; + slice_hdr->slice_vertical_position = mb_y; + return GST_VAAPI_DECODER_STATUS_SUCCESS; + +failed: + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; +} + static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) { @@ -970,16 +1034,10 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) GstVaapiSlice *slice; VASliceParameterBufferMPEG2 *slice_param; GstMpegVideoPacket * const packet = &unit->packet; - const gint slice_no = packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN; - GstBitReader br; - gint mb_x, mb_y, mb_inc; - guint macroblock_offset; - guint8 slice_vertical_position_extension; - guint8 quantiser_scale_code; - guint8 intra_slice = 0; - guint8 extra_bit_slice, junk8; + GstMpegVideoSliceHdr * const slice_hdr = &unit->data.slice_hdr; - GST_DEBUG("slice %d (%u bytes)", slice_no, packet->size); + GST_DEBUG("slice %d (%u bytes)", slice_hdr->slice_vertical_position, + packet->size); if (!picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -1003,50 +1061,14 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) } gst_vaapi_picture_add_slice(picture, slice); - /* Parse slice */ - gst_bit_reader_init(&br, GST_BUFFER_DATA(unit->base.buffer), packet->size); - SKIP(&br, 32); /* slice_start_code */ - if (priv->height > 2800) - READ_UINT8(&br, slice_vertical_position_extension, 3); - if (priv->has_seq_scalable_ext) { - GST_ERROR("failed to parse slice %d. Unsupported sequence_scalable_extension()", slice_no); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } - READ_UINT8(&br, quantiser_scale_code, 5); - READ_UINT8(&br, extra_bit_slice, 1); - if (extra_bit_slice == 1) { - READ_UINT8(&br, intra_slice, 1); - READ_UINT8(&br, junk8, 7); - READ_UINT8(&br, extra_bit_slice, 1); - while (extra_bit_slice == 1) { - READ_UINT8(&br, junk8, 8); - READ_UINT8(&br, extra_bit_slice, 1); - } - } - macroblock_offset = gst_bit_reader_get_pos(&br); - - mb_y = slice_no; - mb_x = -1; - do { - if (!decode_vlc(&br, &mb_inc, mpeg2_mbaddr_vlc_table, - G_N_ELEMENTS(mpeg2_mbaddr_vlc_table))) { - GST_WARNING("failed to decode first macroblock_address_increment"); - goto failed; - } - mb_x += mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE ? 33 : mb_inc; - } while (mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE); - /* Fill in VASliceParameterBufferMPEG2 */ slice_param = slice->param; - slice_param->macroblock_offset = macroblock_offset; - slice_param->slice_horizontal_position = mb_x; - slice_param->slice_vertical_position = mb_y; - slice_param->quantiser_scale_code = quantiser_scale_code; - slice_param->intra_slice_flag = intra_slice; + slice_param->macroblock_offset = slice_hdr->header_size; + slice_param->slice_horizontal_position = slice_hdr->slice_horizontal_position; + slice_param->slice_vertical_position = slice_hdr->slice_vertical_position; + slice_param->quantiser_scale_code = slice_hdr->quantiser_scale_code; + slice_param->intra_slice_flag = slice_hdr->intra_slice; return GST_VAAPI_DECODER_STATUS_SUCCESS; - -failed: - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } static inline gint @@ -1221,6 +1243,12 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, } break; default: + if (packet->type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + packet->type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { + status = parse_slice(decoder, unit); + break; + } + status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; } From 748a8dbdc6335814c4900b6ecd5da67eb169ba26 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 27 Dec 2012 15:18:55 +0100 Subject: [PATCH 0967/3781] mpeg2: implement {start,end}_frame() hooks. Implement GstVaapiDecoder.start_frame() and end_frame() semantics so that to create new VA context earlier and submit VA pictures to the HW for decoding as soon as possible. i.e. don't wait for the next frame to start decoding the previous one. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 340 ++++++++++++--------- 1 file changed, 188 insertions(+), 152 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 36a35492a6..6fe9a3a7cb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -228,20 +228,17 @@ struct _GstVaapiDecoderMpeg2Private { guint height; guint fps_n; guint fps_d; - GstMpegVideoSequenceHdr seq_hdr; - GstMpegVideoSequenceExt seq_ext; - GstMpegVideoPictureHdr pic_hdr; - GstMpegVideoPictureExt pic_ext; - GstMpegVideoQuantMatrixExt quant_matrix_ext; + GstVaapiDecoderUnitMpeg2 *seq_hdr_unit; + GstVaapiDecoderUnitMpeg2 *seq_ext_unit; + GstVaapiDecoderUnitMpeg2 *seq_scalable_ext_unit; + GstVaapiDecoderUnitMpeg2 *pic_hdr_unit; + GstVaapiDecoderUnitMpeg2 *pic_ext_unit; + GstVaapiDecoderUnitMpeg2 *quant_matrix_unit; GstVaapiPicture *current_picture; GstVaapiDpb *dpb; PTSGenerator tsg; guint is_constructed : 1; guint is_opened : 1; - guint has_seq_ext : 1; - guint has_seq_scalable_ext : 1; - guint has_pic_ext : 1; - guint has_quant_matrix_ext : 1; guint size_changed : 1; guint profile_changed : 1; guint quant_matrix_changed : 1; @@ -336,6 +333,13 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) gst_vaapi_picture_replace(&priv->current_picture, NULL); + gst_vaapi_decoder_unit_replace(&priv->seq_hdr_unit, NULL); + gst_vaapi_decoder_unit_replace(&priv->seq_ext_unit, NULL); + gst_vaapi_decoder_unit_replace(&priv->seq_scalable_ext_unit, NULL); + gst_vaapi_decoder_unit_replace(&priv->pic_hdr_unit, NULL); + gst_vaapi_decoder_unit_replace(&priv->pic_ext_unit, NULL); + gst_vaapi_decoder_unit_replace(&priv->quant_matrix_unit, NULL); + if (priv->dpb) { gst_vaapi_dpb_unref(priv->dpb); priv->dpb = NULL; @@ -413,9 +417,10 @@ get_profile(GstVaapiDecoderMpeg2 *decoder, GstVaapiEntrypoint entrypoint) break; case GST_VAAPI_PROFILE_MPEG2_HIGH: // Try to map to main profile if no high profile specific bits used - if (priv->profile == profile && - !priv->has_seq_scalable_ext && - (priv->has_seq_ext && priv->seq_ext.chroma_format == 1)) { + if (priv->profile == profile && + !priv->seq_scalable_ext_unit && + (priv->seq_ext_unit && + priv->seq_ext_unit->data.seq_ext.chroma_format == 1)) { profile = GST_VAAPI_PROFILE_MPEG2_MAIN; break; } @@ -477,6 +482,7 @@ static GstVaapiDecoderStatus ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr_unit->data.seq_hdr; VAIQMatrixBufferMPEG2 *iq_matrix; guint8 *intra_quant_matrix = NULL; guint8 *non_intra_quant_matrix = NULL; @@ -495,17 +501,20 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) } iq_matrix = picture->iq_matrix->param; - intra_quant_matrix = priv->seq_hdr.intra_quantizer_matrix; - non_intra_quant_matrix = priv->seq_hdr.non_intra_quantizer_matrix; - if (priv->has_quant_matrix_ext) { - if (priv->quant_matrix_ext.load_intra_quantiser_matrix) - intra_quant_matrix = priv->quant_matrix_ext.intra_quantiser_matrix; - if (priv->quant_matrix_ext.load_non_intra_quantiser_matrix) - non_intra_quant_matrix = priv->quant_matrix_ext.non_intra_quantiser_matrix; - if (priv->quant_matrix_ext.load_chroma_intra_quantiser_matrix) - chroma_intra_quant_matrix = priv->quant_matrix_ext.chroma_intra_quantiser_matrix; - if (priv->quant_matrix_ext.load_chroma_non_intra_quantiser_matrix) - chroma_non_intra_quant_matrix = priv->quant_matrix_ext.chroma_non_intra_quantiser_matrix; + intra_quant_matrix = seq_hdr->intra_quantizer_matrix; + non_intra_quant_matrix = seq_hdr->non_intra_quantizer_matrix; + + if (priv->quant_matrix_unit) { + GstMpegVideoQuantMatrixExt * const quant_matrix = + &priv->quant_matrix_unit->data.quant_matrix; + if (quant_matrix->load_intra_quantiser_matrix) + intra_quant_matrix = quant_matrix->intra_quantiser_matrix; + if (quant_matrix->load_non_intra_quantiser_matrix) + non_intra_quant_matrix = quant_matrix->non_intra_quantiser_matrix; + if (quant_matrix->load_chroma_intra_quantiser_matrix) + chroma_intra_quant_matrix = quant_matrix->chroma_intra_quantiser_matrix; + if (quant_matrix->load_chroma_non_intra_quantiser_matrix) + chroma_non_intra_quant_matrix = quant_matrix->chroma_non_intra_quantiser_matrix; } iq_matrix->load_intra_quantiser_matrix = intra_quant_matrix != NULL; @@ -530,22 +539,28 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static gboolean +static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderMpeg2 *decoder) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstVaapiPicture * const picture = priv->current_picture; - if (picture) { - if (!gst_vaapi_picture_decode(picture)) - return FALSE; - if (GST_VAAPI_PICTURE_IS_COMPLETE(picture)) { - if (!gst_vaapi_dpb_add(priv->dpb, picture)) - return FALSE; - gst_vaapi_picture_replace(&priv->current_picture, NULL); - } + if (!picture) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (!gst_vaapi_picture_decode(picture)) + goto error; + if (GST_VAAPI_PICTURE_IS_COMPLETE(picture)) { + if (!gst_vaapi_dpb_add(priv->dpb, picture)) + goto error; + gst_vaapi_picture_replace(&priv->current_picture, NULL); } - return TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; + +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 @@ -566,9 +581,11 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr; + GstMpegVideoSequenceHdr *seq_hdr; - *seq_hdr = unit->data.seq_hdr; + gst_vaapi_decoder_unit_replace(&priv->seq_hdr_unit, unit); + seq_hdr = &priv->seq_hdr_unit->data.seq_hdr; + gst_vaapi_decoder_unit_replace(&priv->seq_ext_unit, NULL); priv->fps_n = seq_hdr->fps_n; priv->fps_d = seq_hdr->fps_d; @@ -581,7 +598,6 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) priv->width = seq_hdr->width; priv->height = seq_hdr->height; - priv->has_seq_ext = FALSE; priv->size_changed = TRUE; priv->quant_matrix_changed = TRUE; priv->progressive_sequence = TRUE; @@ -607,14 +623,14 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr; - GstMpegVideoSequenceExt * const seq_ext = &priv->seq_ext; + GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr_unit->data.seq_hdr; + GstMpegVideoSequenceExt *seq_ext; GstVaapiProfile profile; guint width, height; - *seq_ext = unit->data.seq_ext; + gst_vaapi_decoder_unit_replace(&priv->seq_ext_unit, unit); + seq_ext = &priv->seq_ext_unit->data.seq_ext; - priv->has_seq_ext = TRUE; priv->progressive_sequence = seq_ext->progressive; gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence); @@ -669,9 +685,11 @@ static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; - if (priv->current_picture && !decode_current_picture(decoder)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + status = decode_current_picture(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; gst_vaapi_dpb_flush(priv->dpb); return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -696,8 +714,7 @@ decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - priv->quant_matrix_ext = unit->data.quant_matrix; - priv->has_quant_matrix_ext = TRUE; + gst_vaapi_decoder_unit_replace(&priv->quant_matrix_unit, unit); priv->quant_matrix_changed = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -759,7 +776,7 @@ parse_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) gst_bit_reader_init(&br, packet->data + packet->offset, packet->size); if (priv->height > 2800) READ_UINT8(&br, slice_vertical_position_extension, 3); - if (priv->has_seq_scalable_ext) { + if (priv->seq_scalable_ext_unit) { GST_ERROR("failed to parse slice with sequence_scalable_extension()"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -801,69 +818,9 @@ static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr; - GstVaapiPicture *picture; - GstVaapiDecoderStatus status; - *pic_hdr = unit->data.pic_hdr; - - status = ensure_context(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_ERROR("failed to reset context"); - return status; - } - - if (priv->current_picture && !decode_current_picture(decoder)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - - if (priv->current_picture) { - /* Re-use current picture where the first field was decoded */ - picture = gst_vaapi_picture_new_field(priv->current_picture); - if (!picture) { - GST_ERROR("failed to allocate field picture"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - } - else { - /* Create new picture */ - picture = GST_VAAPI_PICTURE_NEW(MPEG2, 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) { - GST_ERROR("failed to reset quantizer matrix"); - return status; - } - - priv->has_pic_ext = FALSE; - - switch (pic_hdr->pic_type) { - case GST_MPEG_VIDEO_PICTURE_TYPE_I: - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - picture->type = GST_VAAPI_PICTURE_TYPE_I; - break; - case GST_MPEG_VIDEO_PICTURE_TYPE_P: - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - picture->type = GST_VAAPI_PICTURE_TYPE_P; - break; - case GST_MPEG_VIDEO_PICTURE_TYPE_B: - picture->type = GST_VAAPI_PICTURE_TYPE_B; - break; - default: - GST_ERROR("unsupported picture type %d", pic_hdr->pic_type); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - - /* Update presentation time */ - picture->pts = pts_eval(&priv->tsg, - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts, pic_hdr->tsn); - picture->poc = pts_get_poc(&priv->tsg); + gst_vaapi_decoder_unit_replace(&priv->pic_hdr_unit, unit); + gst_vaapi_decoder_unit_replace(&priv->pic_ext_unit, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -885,12 +842,10 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext; - GstVaapiPicture * const picture = priv->current_picture; + GstMpegVideoPictureExt *pic_ext; - *pic_ext = unit->data.pic_ext; - - priv->has_pic_ext = TRUE; + gst_vaapi_decoder_unit_replace(&priv->pic_ext_unit, unit); + pic_ext = &priv->pic_ext_unit->data.pic_ext; if (priv->progressive_sequence && !pic_ext->progressive_frame) { GST_WARNING("invalid interlaced frame in progressive sequence, fixing"); @@ -904,6 +859,41 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, pic_ext->picture_structure); pic_ext->picture_structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME; } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static inline guint32 +pack_f_code(guint8 f_code[2][2]) +{ + return (((guint32)f_code[0][0] << 12) | + ((guint32)f_code[0][1] << 8) | + ((guint32)f_code[1][0] << 4) | + ( f_code[1][1] )); +} + +static GstVaapiDecoderStatus +init_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr_unit->data.pic_hdr; + GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext_unit->data.pic_ext; + + switch (pic_hdr->pic_type) { + case GST_MPEG_VIDEO_PICTURE_TYPE_I: + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + picture->type = GST_VAAPI_PICTURE_TYPE_I; + break; + case GST_MPEG_VIDEO_PICTURE_TYPE_P: + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + picture->type = GST_VAAPI_PICTURE_TYPE_P; + break; + case GST_MPEG_VIDEO_PICTURE_TYPE_B: + picture->type = GST_VAAPI_PICTURE_TYPE_B; + break; + default: + GST_ERROR("unsupported picture type %d", pic_hdr->pic_type); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } if (!priv->progressive_sequence && !pic_ext->progressive_frame) { GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED); @@ -955,42 +945,36 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, } GST_INFO("allocated dummy picture for first field based I-frame"); } + + /* Update presentation time */ + picture->pts = pts_eval(&priv->tsg, + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts, pic_hdr->tsn); + picture->poc = pts_get_poc(&priv->tsg); return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static inline guint32 -pack_f_code(guint8 f_code[2][2]) -{ - return (((guint32)f_code[0][0] << 12) | - ((guint32)f_code[0][1] << 8) | - ((guint32)f_code[1][0] << 4) | - ( f_code[1][1] )); -} - -static gboolean +static void fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; VAPictureParameterBufferMPEG2 * const pic_param = picture->param; - GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr; - GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext; + GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr_unit->data.pic_hdr; + GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext_unit->data.pic_ext; GstVaapiPicture *prev_picture, *next_picture; - if (!priv->has_pic_ext) - return FALSE; - /* Fill in VAPictureParameterBufferMPEG2 */ - pic_param->horizontal_size = priv->width; - pic_param->vertical_size = priv->height; - pic_param->forward_reference_picture = VA_INVALID_ID; - pic_param->backward_reference_picture = VA_INVALID_ID; - pic_param->picture_coding_type = pic_hdr->pic_type; - pic_param->f_code = pack_f_code(pic_ext->f_code); + pic_param->horizontal_size = priv->width; + pic_param->vertical_size = priv->height; + pic_param->forward_reference_picture = VA_INVALID_ID; + pic_param->backward_reference_picture = VA_INVALID_ID; + pic_param->picture_coding_type = pic_hdr->pic_type; + pic_param->f_code = pack_f_code(pic_ext->f_code); #define COPY_FIELD(a, b, f) \ pic_param->a.b.f = pic_ext->f - pic_param->picture_coding_extension.value = 0; - pic_param->picture_coding_extension.bits.is_first_field = GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture); + pic_param->picture_coding_extension.value = 0; + pic_param->picture_coding_extension.bits.is_first_field = + GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture); COPY_FIELD(picture_coding_extension, bits, intra_dc_precision); COPY_FIELD(picture_coding_extension, bits, picture_structure); COPY_FIELD(picture_coding_extension, bits, top_field_first); @@ -1002,12 +986,8 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) COPY_FIELD(picture_coding_extension, bits, repeat_first_field); COPY_FIELD(picture_coding_extension, bits, progressive_frame); - gst_vaapi_dpb_mpeg2_get_references( - priv->dpb, - picture, - &prev_picture, - &next_picture - ); + gst_vaapi_dpb_mpeg2_get_references(priv->dpb, picture, + &prev_picture, &next_picture); switch (pic_hdr->pic_type) { case GST_MPEG_VIDEO_PICTURE_TYPE_B: @@ -1023,7 +1003,6 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) pic_param->forward_reference_picture = prev_picture->surface_id; break; } - return TRUE; } static GstVaapiDecoderStatus @@ -1039,12 +1018,6 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) GST_DEBUG("slice %d (%u bytes)", slice_hdr->slice_vertical_position, packet->size); - if (!picture) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - if (picture->slices->len == 0 && !fill_picture(decoder, picture)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - unit->base.buffer = gst_buffer_create_sub( GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, unit->base.offset, unit->base.size); @@ -1301,6 +1274,71 @@ gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base_decoder, return decode_unit(decoder, (GstVaapiDecoderUnitMpeg2 *)unit); } +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder, + GstVaapiDecoderUnit *base_unit) +{ + GstVaapiDecoderMpeg2 * const decoder = + GST_VAAPI_DECODER_MPEG2(base_decoder); + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiPicture *picture; + GstVaapiDecoderStatus status; + + if (!priv->width || !priv->height) { + // Ignore packet while picture size is undefined + // i.e. missing sequence headers, or not parsed correctly + GST_WARNING("failed to decode picture of unknown size"); + 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; + } + + if (priv->current_picture) { + /* Re-use current picture where the first field was decoded */ + picture = gst_vaapi_picture_new_field(priv->current_picture); + if (!picture) { + GST_ERROR("failed to allocate field picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + } + else { + /* Create new picture */ + picture = GST_VAAPI_PICTURE_NEW(MPEG2, 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) { + GST_ERROR("failed to reset quantizer matrix"); + return status; + } + + status = init_picture(decoder, picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + fill_picture(decoder, picture); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg2_end_frame(GstVaapiDecoder *base_decoder) +{ + GstVaapiDecoderMpeg2 * const decoder = + GST_VAAPI_DECODER_MPEG2(base_decoder); + + return decode_current_picture(decoder); +} + static void gst_vaapi_decoder_mpeg2_finalize(GObject *object) { @@ -1338,6 +1376,8 @@ gst_vaapi_decoder_mpeg2_class_init(GstVaapiDecoderMpeg2Class *klass) decoder_class->parse = gst_vaapi_decoder_mpeg2_parse; decoder_class->decode = gst_vaapi_decoder_mpeg2_decode; + decoder_class->start_frame = gst_vaapi_decoder_mpeg2_start_frame; + decoder_class->end_frame = gst_vaapi_decoder_mpeg2_end_frame; } static void @@ -1356,10 +1396,6 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv->current_picture = NULL; priv->is_constructed = FALSE; priv->is_opened = FALSE; - priv->has_seq_ext = FALSE; - priv->has_seq_scalable_ext = FALSE; - priv->has_pic_ext = FALSE; - priv->has_quant_matrix_ext = FALSE; priv->size_changed = FALSE; priv->profile_changed = TRUE; /* Allow fallbacks to work */ priv->quant_matrix_changed = FALSE; From 65ede48b7bfd84aaf7f2cbd3908e915a08525172 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 2 Jan 2013 14:02:29 +0100 Subject: [PATCH 0968/3781] mpeg2: handle sequence_display_extension(). --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 6fe9a3a7cb..16b4f7510b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -190,6 +190,7 @@ struct _GstVaapiDecoderUnitMpeg2 { union { GstMpegVideoSequenceHdr seq_hdr; GstMpegVideoSequenceExt seq_ext; + GstMpegVideoSequenceDisplayExt seq_display_ext; GstMpegVideoGop gop; GstMpegVideoQuantMatrixExt quant_matrix; GstMpegVideoPictureHdr pic_hdr; @@ -230,6 +231,7 @@ struct _GstVaapiDecoderMpeg2Private { guint fps_d; GstVaapiDecoderUnitMpeg2 *seq_hdr_unit; GstVaapiDecoderUnitMpeg2 *seq_ext_unit; + GstVaapiDecoderUnitMpeg2 *seq_display_ext_unit; GstVaapiDecoderUnitMpeg2 *seq_scalable_ext_unit; GstVaapiDecoderUnitMpeg2 *pic_hdr_unit; GstVaapiDecoderUnitMpeg2 *pic_ext_unit; @@ -335,6 +337,7 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) gst_vaapi_decoder_unit_replace(&priv->seq_hdr_unit, NULL); gst_vaapi_decoder_unit_replace(&priv->seq_ext_unit, NULL); + gst_vaapi_decoder_unit_replace(&priv->seq_display_ext_unit, NULL); gst_vaapi_decoder_unit_replace(&priv->seq_scalable_ext_unit, NULL); gst_vaapi_decoder_unit_replace(&priv->pic_hdr_unit, NULL); gst_vaapi_decoder_unit_replace(&priv->pic_ext_unit, NULL); @@ -586,6 +589,7 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) gst_vaapi_decoder_unit_replace(&priv->seq_hdr_unit, unit); seq_hdr = &priv->seq_hdr_unit->data.seq_hdr; gst_vaapi_decoder_unit_replace(&priv->seq_ext_unit, NULL); + gst_vaapi_decoder_unit_replace(&priv->seq_display_ext_unit, NULL); priv->fps_n = seq_hdr->fps_n; priv->fps_d = seq_hdr->fps_d; @@ -681,6 +685,32 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static GstVaapiDecoderStatus +parse_sequence_display_ext(GstVaapiDecoderUnitMpeg2 *unit) +{ + GstMpegVideoPacket * const packet = &unit->packet; + + if (!gst_mpeg_video_parse_sequence_display_extension( + &unit->data.seq_display_ext, + packet->data, packet->size, packet->offset)) { + GST_ERROR("failed to parse sequence-display-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnitMpeg2 *unit) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + + gst_vaapi_decoder_unit_replace(&priv->seq_display_ext_unit, unit); + + /* XXX: handle color primaries and cropping */ + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) { @@ -1074,6 +1104,9 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: status = decode_sequence_ext(decoder, unit); break; + case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY: + status = decode_sequence_display_ext(decoder, unit); + break; case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: status = decode_quant_matrix_ext(decoder, unit); break; @@ -1204,6 +1237,9 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: status = parse_sequence_ext(unit); break; + case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY: + status = parse_sequence_display_ext(unit); + break; case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: status = parse_quant_matrix_ext(unit); break; From 9458bbdc162ceecc51a35d7d2db95b343093d903 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 2 Jan 2013 14:10:20 +0100 Subject: [PATCH 0969/3781] mpeg2: use sequence_display_extension() to compute PAR. Also compute pixel-aspect-ratio from sequence_display_extension(), should it exist in the bitstream. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 16b4f7510b..7ecd9d19c3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -596,10 +596,6 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) pts_set_framerate(&priv->tsg, priv->fps_n, priv->fps_d); gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); - if (gst_mpeg_video_finalise_mpeg2_sequence_header(seq_hdr, NULL, NULL)) - gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, - seq_hdr->par_w, seq_hdr->par_h); - priv->width = seq_hdr->width; priv->height = seq_hdr->height; priv->size_changed = TRUE; @@ -627,7 +623,6 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr_unit->data.seq_hdr; GstMpegVideoSequenceExt *seq_ext; GstVaapiProfile profile; guint width, height; @@ -677,11 +672,6 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, priv->profile = profile; priv->profile_changed = TRUE; } - - if (gst_mpeg_video_finalise_mpeg2_sequence_header(seq_hdr, seq_ext, NULL)) - gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, - seq_hdr->par_w, seq_hdr->par_h); - return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1317,6 +1307,9 @@ gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder, GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2(base_decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoSequenceHdr *seq_hdr; + GstMpegVideoSequenceExt *seq_ext; + GstMpegVideoSequenceDisplayExt *seq_display_ext; GstVaapiPicture *picture; GstVaapiDecoderStatus status; @@ -1327,6 +1320,15 @@ gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; } + seq_hdr = &priv->seq_hdr_unit->data.seq_hdr; + seq_ext = priv->seq_ext_unit ? &priv->seq_ext_unit->data.seq_ext : NULL; + seq_display_ext = priv->seq_display_ext_unit ? + &priv->seq_display_ext_unit->data.seq_display_ext : NULL; + if (gst_mpeg_video_finalise_mpeg2_sequence_header(seq_hdr, seq_ext, + seq_display_ext)) + gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, + seq_hdr->par_w, seq_hdr->par_h); + status = ensure_context(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { GST_ERROR("failed to reset context"); From 7ca43932e5d37035d5876988678d051168f8d371 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 2 Jan 2013 14:18:31 +0100 Subject: [PATCH 0970/3781] mpeg2: optimize scan for the second start code. Optimize scan for the second start code, on the next parse() call so that to avoid scanning again earlier bytes where we didn't find any start code. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 23 ++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 7ecd9d19c3..1624dd8fbb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1160,13 +1160,14 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, { GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2(base_decoder); + GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiDecoderUnitMpeg2 *unit; GstVaapiDecoderStatus status; GstMpegVideoPacket *packet; const guchar *buf; guint32 start_code; guint size, buf_size, flags; - gint ofs; + gint ofs, ofs2; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) @@ -1179,18 +1180,28 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, ofs = scan_for_start_code(adapter, 0, size, &start_code); if (ofs < 0) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - gst_adapter_flush(adapter, ofs); - size -= ofs; - ofs = G_UNLIKELY(size < 8) ? -1 : - scan_for_start_code(adapter, 4, size - 4, NULL); + if (ofs > 0) { + gst_adapter_flush(adapter, ofs); + size -= ofs; + } + + ofs2 = ps->input_offset2 - ofs - 4; + if (ofs2 < 4) + ofs2 = 4; + + ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 : + scan_for_start_code(adapter, ofs2, size - ofs2, NULL); if (ofs < 0) { // Assume the whole packet is present if end-of-stream - if (!at_eos) + if (!at_eos) { + ps->input_offset2 = size; return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } ofs = size; } buf_size = ofs; + ps->input_offset2 = 0; buf = gst_adapter_peek(adapter, buf_size); if (!buf) From 4556b1fd4731128a3b63f73e71980fb2812a640b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 2 Jan 2013 14:45:50 +0100 Subject: [PATCH 0971/3781] mpeg2: minor clean-ups. Drop explicit initialization of most fields that are implicitly set to zero. Remove some useless checks for NULL pointers. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 211 ++++++++++----------- 1 file changed, 103 insertions(+), 108 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 1624dd8fbb..c12e4970b0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -38,14 +38,9 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDecoderMpeg2, - gst_vaapi_decoder_mpeg2, - GST_VAAPI_TYPE_DECODER) - -#define GST_VAAPI_DECODER_MPEG2_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DECODER_MPEG2, \ - GstVaapiDecoderMpeg2Private)) +/* ------------------------------------------------------------------------- */ +/* --- VLC Reader --- */ +/* ------------------------------------------------------------------------- */ #define READ_UINT8(br, val, nbits) G_STMT_START { \ if (!gst_bit_reader_get_bits_uint8 (br, &val, nbits)) { \ @@ -61,6 +56,85 @@ G_DEFINE_TYPE(GstVaapiDecoderMpeg2, } \ } G_STMT_END +/* VLC decoder from gst-plugins-bad */ +typedef struct _VLCTable VLCTable; +struct _VLCTable { + gint value; + guint cword; + guint cbits; +}; + +static gboolean +decode_vlc(GstBitReader *br, gint *res, const VLCTable *table, guint length) +{ + guint8 i; + guint cbits = 0; + guint32 value = 0; + + for (i = 0; i < length; i++) { + if (cbits != table[i].cbits) { + cbits = table[i].cbits; + if (!gst_bit_reader_peek_bits_uint32(br, &value, cbits)) { + goto failed; + } + } + + if (value == table[i].cword) { + SKIP(br, cbits); + if (res) + *res = table[i].value; + return TRUE; + } + } + GST_DEBUG("failed to find VLC code"); + +failed: + GST_WARNING("failed to decode VLC, returning"); + return FALSE; +} + +enum { + GST_MPEG_VIDEO_MACROBLOCK_ESCAPE = -1, +}; + +/* Table B-1: Variable length codes for macroblock_address_increment */ +static const VLCTable mpeg2_mbaddr_vlc_table[] = { + { 1, 0x01, 1 }, + { 2, 0x03, 3 }, + { 3, 0x02, 3 }, + { 4, 0x03, 4 }, + { 5, 0x02, 4 }, + { 6, 0x03, 5 }, + { 7, 0x02, 5 }, + { 8, 0x07, 7 }, + { 9, 0x06, 7 }, + { 10, 0x0b, 8 }, + { 11, 0x0a, 8 }, + { 12, 0x09, 8 }, + { 13, 0x08, 8 }, + { 14, 0x07, 8 }, + { 15, 0x06, 8 }, + { 16, 0x17, 10 }, + { 17, 0x16, 10 }, + { 18, 0x15, 10 }, + { 19, 0x14, 10 }, + { 20, 0x13, 10 }, + { 21, 0x12, 10 }, + { 22, 0x23, 11 }, + { 23, 0x22, 11 }, + { 24, 0x21, 11 }, + { 25, 0x20, 11 }, + { 26, 0x1f, 11 }, + { 27, 0x1e, 11 }, + { 28, 0x1d, 11 }, + { 29, 0x1c, 11 }, + { 30, 0x1b, 11 }, + { 31, 0x1a, 11 }, + { 32, 0x19, 11 }, + { 33, 0x18, 11 }, + { GST_MPEG_VIDEO_MACROBLOCK_ESCAPE, 0x08, 11 } +}; + /* ------------------------------------------------------------------------- */ /* --- PTS Generator --- */ /* ------------------------------------------------------------------------- */ @@ -222,6 +296,18 @@ gst_vaapi_decoder_unit_mpeg2_new(guint size) /* --- MPEG-2 Decoder --- */ /* ------------------------------------------------------------------------- */ +G_DEFINE_TYPE(GstVaapiDecoderMpeg2, + gst_vaapi_decoder_mpeg2, + GST_VAAPI_TYPE_DECODER) + +#define GST_VAAPI_DECODER_MPEG2_CAST(decoder) \ + ((GstVaapiDecoderMpeg2 *)(decoder)) + +#define GST_VAAPI_DECODER_MPEG2_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DECODER_MPEG2, \ + GstVaapiDecoderMpeg2Private)) + struct _GstVaapiDecoderMpeg2Private { GstVaapiProfile profile; GstVaapiProfile hw_profile; @@ -249,85 +335,6 @@ struct _GstVaapiDecoderMpeg2Private { guint broken_link : 1; }; -/* VLC decoder from gst-plugins-bad */ -typedef struct _VLCTable VLCTable; -struct _VLCTable { - gint value; - guint cword; - guint cbits; -}; - -static gboolean -decode_vlc(GstBitReader *br, gint *res, const VLCTable *table, guint length) -{ - guint8 i; - guint cbits = 0; - guint32 value = 0; - - for (i = 0; i < length; i++) { - if (cbits != table[i].cbits) { - cbits = table[i].cbits; - if (!gst_bit_reader_peek_bits_uint32(br, &value, cbits)) { - goto failed; - } - } - - if (value == table[i].cword) { - SKIP(br, cbits); - if (res) - *res = table[i].value; - return TRUE; - } - } - GST_DEBUG("failed to find VLC code"); - -failed: - GST_WARNING("failed to decode VLC, returning"); - return FALSE; -} - -enum { - GST_MPEG_VIDEO_MACROBLOCK_ESCAPE = -1, -}; - -/* Table B-1: Variable length codes for macroblock_address_increment */ -static const VLCTable mpeg2_mbaddr_vlc_table[] = { - { 1, 0x01, 1 }, - { 2, 0x03, 3 }, - { 3, 0x02, 3 }, - { 4, 0x03, 4 }, - { 5, 0x02, 4 }, - { 6, 0x03, 5 }, - { 7, 0x02, 5 }, - { 8, 0x07, 7 }, - { 9, 0x06, 7 }, - { 10, 0x0b, 8 }, - { 11, 0x0a, 8 }, - { 12, 0x09, 8 }, - { 13, 0x08, 8 }, - { 14, 0x07, 8 }, - { 15, 0x06, 8 }, - { 16, 0x17, 10 }, - { 17, 0x16, 10 }, - { 18, 0x15, 10 }, - { 19, 0x14, 10 }, - { 20, 0x13, 10 }, - { 21, 0x12, 10 }, - { 22, 0x23, 11 }, - { 23, 0x22, 11 }, - { 24, 0x21, 11 }, - { 25, 0x20, 11 }, - { 26, 0x1f, 11 }, - { 27, 0x1e, 11 }, - { 28, 0x1d, 11 }, - { 29, 0x1c, 11 }, - { 30, 0x1b, 11 }, - { 31, 0x1a, 11 }, - { 32, 0x19, 11 }, - { 33, 0x18, 11 }, - { GST_MPEG_VIDEO_MACROBLOCK_ESCAPE, 0x08, 11 } -}; - static void gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) { @@ -472,7 +479,7 @@ ensure_context(GstVaapiDecoderMpeg2 *decoder) info.height = priv->height; info.ref_frames = 2; reset_context = gst_vaapi_decoder_ensure_context( - GST_VAAPI_DECODER(decoder), + GST_VAAPI_DECODER_CAST(decoder), &info ); if (!reset_context) @@ -582,7 +589,7 @@ parse_sequence(GstVaapiDecoderUnitMpeg2 *unit) static GstVaapiDecoderStatus decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoSequenceHdr *seq_hdr; @@ -621,7 +628,7 @@ static GstVaapiDecoderStatus decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); + GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoSequenceExt *seq_ext; GstVaapiProfile profile; @@ -1159,7 +1166,7 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) { GstVaapiDecoderMpeg2 * const decoder = - GST_VAAPI_DECODER_MPEG2(base_decoder); + GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiDecoderUnitMpeg2 *unit; GstVaapiDecoderStatus status; @@ -1302,7 +1309,7 @@ gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2 * const decoder = - GST_VAAPI_DECODER_MPEG2(base_decoder); + GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); GstVaapiDecoderStatus status; status = ensure_decoder(decoder); @@ -1316,7 +1323,7 @@ gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder, GstVaapiDecoderUnit *base_unit) { GstVaapiDecoderMpeg2 * const decoder = - GST_VAAPI_DECODER_MPEG2(base_decoder); + GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoSequenceHdr *seq_hdr; GstMpegVideoSequenceExt *seq_ext; @@ -1383,7 +1390,7 @@ static GstVaapiDecoderStatus gst_vaapi_decoder_mpeg2_end_frame(GstVaapiDecoder *base_decoder) { GstVaapiDecoderMpeg2 * const decoder = - GST_VAAPI_DECODER_MPEG2(base_decoder); + GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); return decode_current_picture(decoder); } @@ -1391,7 +1398,7 @@ gst_vaapi_decoder_mpeg2_end_frame(GstVaapiDecoder *base_decoder) static void gst_vaapi_decoder_mpeg2_finalize(GObject *object) { - GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2(object); + GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(object); gst_vaapi_decoder_mpeg2_destroy(decoder); @@ -1401,7 +1408,7 @@ gst_vaapi_decoder_mpeg2_finalize(GObject *object) static void gst_vaapi_decoder_mpeg2_constructed(GObject *object) { - GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2(object); + GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(object); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GObjectClass *parent_class; @@ -1436,21 +1443,9 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) priv = GST_VAAPI_DECODER_MPEG2_GET_PRIVATE(decoder); decoder->priv = priv; - priv->width = 0; - priv->height = 0; - priv->fps_n = 0; - priv->fps_d = 0; priv->hw_profile = GST_VAAPI_PROFILE_UNKNOWN; priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; - priv->current_picture = NULL; - priv->is_constructed = FALSE; - priv->is_opened = FALSE; - priv->size_changed = FALSE; priv->profile_changed = TRUE; /* Allow fallbacks to work */ - priv->quant_matrix_changed = FALSE; - priv->progressive_sequence = FALSE; - priv->closed_gop = FALSE; - priv->broken_link = FALSE; } /** From eda01ab027351dc10c437050ff3e2dd485ccc2cf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 2 Jan 2013 17:23:53 +0100 Subject: [PATCH 0972/3781] mpeg2: don't create sub-buffer for slice data. Avoid creating a GstBuffer for slice data. Rather, directly use the codec frame input buffer data. This is possible because the codec frame is valid until end_frame() where we submit the VA buffers for decoding. Anyway, the slice data buffer is copied into the VA buffer when it is created. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index c12e4970b0..541e01269b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1039,22 +1039,14 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) GstVaapiPicture * const picture = priv->current_picture; GstVaapiSlice *slice; VASliceParameterBufferMPEG2 *slice_param; - GstMpegVideoPacket * const packet = &unit->packet; GstMpegVideoSliceHdr * const slice_hdr = &unit->data.slice_hdr; GST_DEBUG("slice %d (%u bytes)", slice_hdr->slice_vertical_position, - packet->size); - - unit->base.buffer = gst_buffer_create_sub( - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, - unit->base.offset, unit->base.size); - if (!unit->base.buffer) { - GST_ERROR("failed to allocate slice data"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } + unit->base.size); slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, - GST_BUFFER_DATA(unit->base.buffer), packet->size); + (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) + + unit->base.offset), unit->base.size); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; From 9bba1e5fe32b414882c5a2821241f117264d03b5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jan 2013 11:16:44 +0100 Subject: [PATCH 0973/3781] decoder: create new context when encoded resolution changes. Create a new VA context if the encoded surface size changes because we need to keep the underlying surface pool until the last one was released. Otherwise, either of the following cases could have happened: (i) release a VA surface to an inexistent pool, or (ii) release VA surface to an existing surface pool, but with different size. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 94477e6839..222726b4d7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -818,8 +818,19 @@ gst_vaapi_decoder_ensure_context( ) { GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVideoCodecState * const codec_state = priv->codec_state; + gboolean size_changed; - gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height); + size_changed = codec_state->info.width != cip->width || + codec_state->info.height != cip->height; + + /* Create a new context if the requested size for surfaces changed + * because we need to keep the context underlying surface pool + * until all surfaces are released */ + if (size_changed) { + gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height); + g_clear_object(&priv->context); + } if (priv->context) { if (!gst_vaapi_context_reset_full(priv->context, cip)) From 3f60f136cc70d1fb8ef91943e0b9a197d9cd347a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 2 Jan 2013 17:33:15 +0100 Subject: [PATCH 0974/3781] h264: don't create sub-buffer for slice data. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index e601bdcc60..a37548cef6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2675,16 +2675,9 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; } - unit->base.buffer = gst_buffer_create_sub( - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, - unit->base.offset, unit->base.size); - if (!unit->base.buffer) { - GST_ERROR("failed to allocate slice data"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - slice = GST_VAAPI_SLICE_NEW(H264, decoder, - GST_BUFFER_DATA(unit->base.buffer) + nalu->offset, nalu->size); + (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) + + unit->base.offset + nalu->offset), nalu->size); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; From 492cafdbc14460e142b00feefd731a46646ac595 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jan 2013 13:05:47 +0100 Subject: [PATCH 0975/3781] decoder: always use the calculated presentation timestamp. Use PTS value computed by the decoder, which could also be derived from the GstVideoCodecFrame PTS. This makes it possible to fix up the PTS if the original one was miscomputed or only represented a DTS instead. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index eb6a83f01c..efc95a3ba9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -319,8 +319,7 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) gst_video_codec_frame_set_user_data(out_frame, proxy, (GDestroyNotify)gst_vaapi_mini_object_unref); - if (!GST_CLOCK_TIME_IS_VALID(out_frame->pts)) - out_frame->pts = picture->pts; + 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); From 5788d8ae45025bf0f0521e7683ef02fbfb12195c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jan 2013 13:10:33 +0100 Subject: [PATCH 0976/3781] vaapidecode: fix calculation of the time-out value. Fix calculation of the time-out value for cases where no VA surface is available for decoding. In this case, we need to wait until downstream sink consumed at least one surface. The time-out was miscalculated as it was always set to + one second, which is not suitable for streams with larger gaps. --- gst/vaapi/gstvaapidecode.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 95339f8945..611c713019 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -186,14 +186,14 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) GstFlowReturn ret; gint64 end_time; + if (!decode->render_time_base) + decode->render_time_base = g_get_monotonic_time(); + end_time = decode->render_time_base; + end_time += GST_TIME_AS_USECONDS(decode->last_buffer_time); + end_time += G_TIME_SPAN_SECOND; + /* Decode current frame */ for (;;) { - end_time = decode->render_time_base; - if (!end_time) - end_time = g_get_monotonic_time(); - end_time += GST_TIME_AS_USECONDS(decode->last_buffer_time); - end_time += G_TIME_SPAN_SECOND; - status = gst_vaapi_decoder_decode(decode->decoder, frame); if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { gboolean was_signalled; @@ -234,6 +234,8 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) ret = gst_video_decoder_finish_frame(vdec, out_frame); if (ret != GST_FLOW_OK) goto error_commit_buffer; + + decode->last_buffer_time = out_frame->pts; gst_video_codec_frame_unref(out_frame); }; return GST_FLOW_OK; From b1636c3585dfaf149d75454c125b3721e65c77c6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 5 Jan 2013 08:31:24 +0100 Subject: [PATCH 0977/3781] videobuffer: add video meta information. Add new GstVaapiVideoMeta object that holds all information needed to convey gst-vaapi specific data as a GstBuffer. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapivideometa.c | 683 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivideometa.h | 118 +++++ 3 files changed, 803 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapivideometa.c create mode 100644 gst-libs/gst/vaapi/gstvaapivideometa.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 79684e2ef7..acf393b06f 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -69,6 +69,7 @@ libgstvaapi_source_c = \ gstvaapiutils.c \ gstvaapivalue.c \ gstvaapivideobuffer.c \ + gstvaapivideometa.c \ gstvaapivideopool.c \ gstvaapiwindow.c \ $(NULL) @@ -95,6 +96,7 @@ libgstvaapi_source_h = \ gstvaapitypes.h \ gstvaapivalue.h \ gstvaapivideobuffer.h \ + gstvaapivideometa.h \ gstvaapivideopool.h \ gstvaapiwindow.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapivideometa.c b/gst-libs/gst/vaapi/gstvaapivideometa.c new file mode 100644 index 0000000000..95f016848a --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideometa.c @@ -0,0 +1,683 @@ +/* + * gstvaapivideometa.c - Gst VA video meta + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2013 Intel Corporation + * + * 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:gstvaapivideometa + * @short_description: VA video meta for GStreamer + */ + +#include "sysdeps.h" +#include "gstvaapivideometa.h" +#include "gstvaapiminiobject.h" +#include "gstvaapiimagepool.h" +#include "gstvaapisurfacepool.h" +#include "gstvaapiobject_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +#define GST_VAAPI_VIDEO_META(obj) \ + ((GstVaapiVideoMeta *)(obj)) + +#define GST_VAAPI_IS_VIDEO_META(obj) \ + (GST_VAAPI_VIDEO_META(obj) != NULL) + +struct _GstVaapiVideoMeta { + GstVaapiDisplay *display; + GstVaapiVideoPool *image_pool; + GstVaapiImage *image; + GstVaapiVideoPool *surface_pool; + GstVaapiSurface *surface; + GstVaapiSurfaceProxy *proxy; + GFunc converter; + guint render_flags; +}; + +static void +set_display(GstVaapiVideoMeta *meta, GstVaapiDisplay *display) +{ + g_clear_object(&meta->display); + + if (display) + meta->display = g_object_ref(display); +} + +static inline void +set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image) +{ + meta->image = g_object_ref(image); + set_display(meta, GST_VAAPI_OBJECT_DISPLAY(image)); +} + +static inline void +set_surface(GstVaapiVideoMeta *meta, GstVaapiSurface *surface) +{ + meta->surface = g_object_ref(surface); + set_display(meta, GST_VAAPI_OBJECT_DISPLAY(surface)); +} + +static void +gst_vaapi_video_meta_destroy_image(GstVaapiVideoMeta *meta) +{ + if (meta->image) { + if (meta->image_pool) + gst_vaapi_video_pool_put_object(meta->image_pool, meta->image); + g_object_unref(meta->image); + meta->image = NULL; + } + g_clear_object(&meta->image_pool); +} + +static void +gst_vaapi_video_meta_destroy_surface(GstVaapiVideoMeta *meta) +{ + gst_vaapi_surface_proxy_replace(&meta->proxy, NULL); + + if (meta->surface) { + if (meta->surface_pool) + gst_vaapi_video_pool_put_object(meta->surface_pool, meta->surface); + g_object_unref(meta->surface); + meta->surface = NULL; + } + g_clear_object(&meta->surface_pool); +} + +GType +gst_vaapi_video_meta_get_type(void) +{ + static gsize g_type; + + if (g_once_init_enter(&g_type)) { + GType type; + type = g_boxed_type_register_static("GstVaapiVideoMeta", + (GBoxedCopyFunc)gst_vaapi_video_meta_ref, + (GBoxedFreeFunc)gst_vaapi_video_meta_unref); + g_once_init_leave(&g_type, type); + } + return (GType)g_type; +} + +static void +gst_vaapi_video_meta_finalize(GstVaapiVideoMeta *meta) +{ + gst_vaapi_video_meta_destroy_image(meta); + gst_vaapi_video_meta_destroy_surface(meta); + g_clear_object(&meta->display); +} + +static void +gst_vaapi_video_meta_init(GstVaapiVideoMeta *meta) +{ + meta->display = NULL; + meta->image_pool = NULL; + meta->image = NULL; + meta->surface_pool = NULL; + meta->surface = NULL; + meta->proxy = NULL; + meta->converter = NULL; + meta->render_flags = 0; +} + +static inline const GstVaapiMiniObjectClass * +gst_vaapi_video_meta_class(void) +{ + static const GstVaapiMiniObjectClass GstVaapiVideoMetaClass = { + sizeof(GstVaapiVideoMeta), + (GDestroyNotify)gst_vaapi_video_meta_finalize + }; + return &GstVaapiVideoMetaClass; +} + +static inline GstVaapiVideoMeta * +_gst_vaapi_video_meta_new(void) +{ + GstVaapiVideoMeta *meta; + + meta = (GstVaapiVideoMeta *) + gst_vaapi_mini_object_new(gst_vaapi_video_meta_class()); + if (meta) + gst_vaapi_video_meta_init(meta); + return meta; +} + +/** + * gst_vaapi_video_meta_new: + * @display: a #GstVaapiDisplay + * + * Creates an empty #GstVaapiVideoMeta. The caller is responsible for completing + * the initialization of the meta with the gst_vaapi_video_meta_set_*() + * functions. + * + * This function shall only be called from within gstreamer-vaapi + * plugin elements. + * + * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL or error + */ +GstVaapiVideoMeta * +gst_vaapi_video_meta_new(GstVaapiDisplay *display) +{ + GstVaapiVideoMeta *meta; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + meta = _gst_vaapi_video_meta_new(); + if (G_UNLIKELY(!meta)) + return NULL; + + set_display(meta, display); + return meta; +} + +/** + * gst_vaapi_video_meta_new_from_pool: + * @pool: a #GstVaapiVideoPool + * + * Creates a #GstVaapiVideoMeta with a video object allocated from a @pool. + * Only #GstVaapiSurfacePool and #GstVaapiImagePool pools are supported. + * + * The meta object is destroyed through the last call to + * gst_vaapi_video_meta_unref() and the video objects are pushed back + * to their respective pools. + * + * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL on error + */ +GstVaapiVideoMeta * +gst_vaapi_video_meta_new_from_pool(GstVaapiVideoPool *pool) +{ + GstVaapiVideoMeta *meta; + + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); + + meta = _gst_vaapi_video_meta_new(); + if (G_UNLIKELY(!meta)) + return NULL; + + if (!(GST_VAAPI_IS_IMAGE_POOL(pool) && + gst_vaapi_video_meta_set_image_from_pool(meta, pool)) && + !(GST_VAAPI_IS_SURFACE_POOL(pool) && + gst_vaapi_video_meta_set_surface_from_pool(meta, pool))) + goto error; + + set_display(meta, gst_vaapi_video_pool_get_display(pool)); + return meta; + +error: + gst_vaapi_video_meta_unref(meta); + return NULL; +} + +/** + * gst_vaapi_video_meta_new_with_image: + * @image: a #GstVaapiImage + * + * Creates a #GstVaapiVideoMeta with the specified @image. The resulting + * meta holds an additional reference to the @image. + * + * This function shall only be called from within gstreamer-vaapi + * plugin elements. + * + * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL on error + */ +GstVaapiVideoMeta * +gst_vaapi_video_meta_new_with_image(GstVaapiImage *image) +{ + GstVaapiVideoMeta *meta; + + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); + + meta = _gst_vaapi_video_meta_new(); + if (G_UNLIKELY(!meta)) + return NULL; + + gst_vaapi_video_meta_set_image(meta, image); + return meta; +} + +/** + * gst_vaapi_video_meta_new_with_surface: + * @surface: a #GstVaapiSurface + * + * Creates a #GstVaapiVideoMeta with the specified @surface. The resulting + * meta holds an additional reference to the @surface. + * + * This function shall only be called from within gstreamer-vaapi + * plugin elements. + * + * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL on error + */ +GstVaapiVideoMeta * +gst_vaapi_video_meta_new_with_surface(GstVaapiSurface *surface) +{ + GstVaapiVideoMeta *meta; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); + + meta = _gst_vaapi_video_meta_new(); + if (G_UNLIKELY(!meta)) + return NULL; + + gst_vaapi_video_meta_set_surface(meta, surface); + return meta; +} + +/** + * gst_vaapi_video_meta_new_with_surface_proxy: + * @proxy: a #GstVaapiSurfaceProxy + * + * Creates a #GstVaapiVideoMeta with the specified surface @proxy. The + * resulting meta holds an additional reference to the @proxy. + * + * This function shall only be called from within gstreamer-vaapi + * plugin elements. + * + * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL on error + */ +GstVaapiVideoMeta * +gst_vaapi_video_meta_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) +{ + GstVaapiVideoMeta *meta; + + g_return_val_if_fail(proxy != NULL, NULL); + + meta = _gst_vaapi_video_meta_new(); + if (G_UNLIKELY(!meta)) + return NULL; + + gst_vaapi_video_meta_set_surface_proxy(meta, proxy); + return meta; +} + +/** + * gst_vaapi_video_meta_ref: + * @meta: a #GstVaapiVideoMeta + * + * Atomically increases the reference count of the given @meta by one. + * + * Returns: The same @meta argument + */ +GstVaapiVideoMeta * +gst_vaapi_video_meta_ref(GstVaapiVideoMeta *meta) +{ + return (GstVaapiVideoMeta *) + gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(meta)); +} + +/** + * gst_vaapi_video_meta_unref: + * @meta: a #GstVaapiVideoMeta + * + * Atomically decreases the reference count of the @meta by one. If + * the reference count reaches zero, the object will be free'd. + */ +void +gst_vaapi_video_meta_unref(GstVaapiVideoMeta *meta) +{ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(meta)); +} + +/** + * gst_vaapi_video_meta_replace: + * @old_meta_ptr: a pointer to a #GstVaapiVideoMeta + * @new_meta: a #GstVaapiVideoMeta + * + * @new_meta. This means that @old_meta_ptr shall reference a valid + * Atomically replaces the meta object held in @old_meta_ptr with + * object. However, @new_meta can be NULL. + */ +void +gst_vaapi_video_meta_replace(GstVaapiVideoMeta **old_meta_ptr, + GstVaapiVideoMeta *new_meta) +{ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_meta_ptr), + (GstVaapiMiniObject *)(new_meta)); +} + +/** + * gst_vaapi_video_meta_get_display: + * @meta: a #GstVaapiVideoMeta + * + * Retrieves the #GstVaapiDisplay the @meta is bound to. The @meta + * owns the returned #GstVaapiDisplay object so the caller is + * responsible for calling g_object_ref() when needed. + * + * Return value: the #GstVaapiDisplay the @meta is bound to + */ +GstVaapiDisplay * +gst_vaapi_video_meta_get_display(GstVaapiVideoMeta *meta) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + + return meta->display; +} + +/** + * gst_vaapi_video_meta_get_image: + * @meta: a #GstVaapiVideoMeta + * + * Retrieves the #GstVaapiImage bound to the @meta. The @meta owns + * the #GstVaapiImage so the caller is responsible for calling + * g_object_ref() when needed. + * + * Return value: the #GstVaapiImage bound to the @meta, or %NULL if + * there is none + */ +GstVaapiImage * +gst_vaapi_video_meta_get_image(GstVaapiVideoMeta *meta) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + + return meta->image; +} + +/** + * gst_vaapi_video_meta_set_image: + * @meta: a #GstVaapiVideoMeta + * @image: a #GstVaapiImage + * + * Binds @image to the @meta. If the @meta contains another image + * previously allocated from a pool, it's pushed back to its parent + * pool and the pool is also released. + */ +void +gst_vaapi_video_meta_set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image) +{ + g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + g_return_if_fail(GST_VAAPI_IS_IMAGE(image)); + + gst_vaapi_video_meta_destroy_image(meta); + + if (image) + set_image(meta, image); +} + +/** + * gst_vaapi_video_meta_set_image_from_pool + * @meta: a #GstVaapiVideoMeta + * @pool: a #GstVaapiVideoPool + * + * Binds a newly allocated video object from the @pool. The @pool + * shall be of type #GstVaapiImagePool. Previously allocated objects + * are released and returned to their parent pools, if any. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_video_meta_set_image_from_pool(GstVaapiVideoMeta *meta, + GstVaapiVideoPool *pool) +{ + GstVaapiImage *image; + + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_IMAGE_POOL(pool), FALSE); + + gst_vaapi_video_meta_destroy_image(meta); + + if (pool) { + image = gst_vaapi_video_pool_get_object(pool); + if (!image) + return FALSE; + set_image(meta, image); + meta->image_pool = g_object_ref(pool); + } + return TRUE; +} + +/** + * gst_vaapi_video_meta_get_surface: + * @meta: a #GstVaapiVideoMeta + * + * Retrieves the #GstVaapiSurface bound to the @meta. The @meta + * owns the #GstVaapiSurface so the caller is responsible for calling + * g_object_ref() when needed. + * + * Return value: the #GstVaapiSurface bound to the @meta, or %NULL if + * there is none + */ +GstVaapiSurface * +gst_vaapi_video_meta_get_surface(GstVaapiVideoMeta *meta) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + + return meta->surface; +} + +/** + * gst_vaapi_video_meta_set_surface: + * @meta: a #GstVaapiVideoMeta + * @surface: a #GstVaapiSurface + * + * Binds @surface to the @meta. If the @meta contains another + * surface previously allocated from a pool, it's pushed back to its + * parent pool and the pool is also released. + */ +void +gst_vaapi_video_meta_set_surface(GstVaapiVideoMeta *meta, + GstVaapiSurface *surface) +{ + g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); + + gst_vaapi_video_meta_destroy_surface(meta); + + if (surface) + set_surface(meta, surface); +} + +/** + * gst_vaapi_video_meta_set_surface_from_pool + * @meta: a #GstVaapiVideoMeta + * @pool: a #GstVaapiVideoPool + * + * Binds a newly allocated video object from the @pool. The @pool + * shall be of type #GstVaapiSurfacePool. Previously allocated objects + * are released and returned to their parent pools, if any. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_video_meta_set_surface_from_pool(GstVaapiVideoMeta *meta, + GstVaapiVideoPool *pool) +{ + GstVaapiSurface *surface; + + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), FALSE); + + gst_vaapi_video_meta_destroy_surface(meta); + + if (pool) { + surface = gst_vaapi_video_pool_get_object(pool); + if (!surface) + return FALSE; + set_surface(meta, surface); + meta->surface_pool = g_object_ref(pool); + } + return TRUE; +} + +/** + * gst_vaapi_video_meta_get_surface_proxy: + * @meta: a #GstVaapiVideoMeta + * + * Retrieves the #GstVaapiSurfaceProxy bound to the @meta. The @meta + * owns the #GstVaapiSurfaceProxy so the caller is responsible for calling + * g_object_ref() when needed. + * + * Return value: the #GstVaapiSurfaceProxy bound to the @meta, or + * %NULL if there is none + */ +GstVaapiSurfaceProxy * +gst_vaapi_video_meta_get_surface_proxy(GstVaapiVideoMeta *meta) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + + return meta->proxy; +} + +/** + * gst_vaapi_video_meta_set_surface_proxy: + * @meta: a #GstVaapiVideoMeta + * @proxy: a #GstVaapiSurfaceProxy + * + * Binds surface @proxy to the @meta. If the @meta contains another + * surface previously allocated from a pool, it's pushed back to its + * parent pool and the pool is also released. + */ +void +gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, + GstVaapiSurfaceProxy *proxy) +{ + GstVaapiSurface *surface; + + g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + g_return_if_fail(proxy != NULL); + + gst_vaapi_video_meta_destroy_surface(meta); + + if (proxy) { + surface = GST_VAAPI_SURFACE_PROXY_SURFACE(proxy); + if (!surface) + return; + set_surface(meta, surface); + meta->proxy = gst_vaapi_surface_proxy_ref(proxy); + } +} + +/** + * gst_vaapi_video_meta_get_surface_converter: + * @meta: a #GstVaapiVideoMeta + * + * Retrieves the surface converter bound to the @meta. + * + * Return value: the surface converter associated with the video @meta + */ +GFunc +gst_vaapi_video_meta_get_surface_converter(GstVaapiVideoMeta *meta) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + + return meta->converter; +} + +/** + * gst_vaapi_video_meta_set_surface_converter: + * @meta: a #GstVaapiVideoMeta + * @func: a pointer to the surface converter function + * + * Sets the @meta surface converter function to @func. + */ +void +gst_vaapi_video_meta_set_surface_converter(GstVaapiVideoMeta *meta, GFunc func) +{ + g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + + meta->converter = func; +} + +/** + * gst_vaapi_video_meta_get_render_flags: + * @meta: a #GstVaapiVideoMeta + * + * Retrieves the surface render flags bound to the @meta. + * + * Return value: a combination for #GstVaapiSurfaceRenderFlags + */ +guint +gst_vaapi_video_meta_get_render_flags(GstVaapiVideoMeta *meta) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), 0); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(meta->surface), 0); + + return meta->render_flags; +} + +/** + * gst_vaapi_video_meta_set_render_flags: + * @meta: a #GstVaapiVideoMeta + * @flags: a set of surface render flags + * + * Sets #GstVaapiSurfaceRenderFlags to the @meta. + */ +void +gst_vaapi_video_meta_set_render_flags(GstVaapiVideoMeta *meta, guint flags) +{ + g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + g_return_if_fail(GST_VAAPI_IS_SURFACE(meta->surface)); + + meta->render_flags = flags; +} + +#define GST_VAAPI_VIDEO_META_QUARK gst_vaapi_video_meta_quark_get() +static GQuark +gst_vaapi_video_meta_quark_get(void) +{ + static gsize g_quark; + + if (g_once_init_enter(&g_quark)) { + gsize quark = (gsize)g_quark_from_static_string("GstVaapiVideoMeta"); + g_once_init_leave(&g_quark, quark); + } + return g_quark; +} + +#define META_QUARK meta_quark_get() +static GQuark +meta_quark_get(void) +{ + static gsize g_quark; + + if (g_once_init_enter(&g_quark)) { + gsize quark = (gsize)g_quark_from_static_string("meta"); + g_once_init_leave(&g_quark, quark); + } + return g_quark; +} + +GstVaapiVideoMeta * +gst_buffer_get_vaapi_video_meta(GstBuffer *buffer) +{ + const GstStructure *structure; + const GValue *value; + + g_return_val_if_fail(GST_IS_BUFFER(buffer), NULL); + + structure = gst_buffer_get_qdata(buffer, GST_VAAPI_VIDEO_META_QUARK); + if (!structure) + return NULL; + + value = gst_structure_id_get_value(structure, META_QUARK); + if (!value) + return NULL; + + return GST_VAAPI_VIDEO_META(g_value_get_boxed(value)); +} + +void +gst_buffer_set_vaapi_video_meta(GstBuffer *buffer, GstVaapiVideoMeta *meta) +{ + g_return_if_fail(GST_IS_BUFFER(buffer)); + g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + + gst_buffer_set_qdata(buffer, GST_VAAPI_VIDEO_META_QUARK, + gst_structure_id_new(GST_VAAPI_VIDEO_META_QUARK, + META_QUARK, GST_VAAPI_TYPE_VIDEO_META, meta, NULL)); +} diff --git a/gst-libs/gst/vaapi/gstvaapivideometa.h b/gst-libs/gst/vaapi/gstvaapivideometa.h new file mode 100644 index 0000000000..42bda676c4 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideometa.h @@ -0,0 +1,118 @@ +/* + * gstvaapivideometa.h - Gstreamer/VA video meta + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2013 Intel Corporation + * + * 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_VIDEO_META_H +#define GST_VAAPI_VIDEO_META_H + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_VIDEO_META \ + (gst_vaapi_video_meta_get_type()) + +typedef struct _GstVaapiVideoMeta GstVaapiVideoMeta; + +GType +gst_vaapi_video_meta_get_type(void) G_GNUC_CONST; + +GstVaapiVideoMeta * +gst_vaapi_video_meta_new(GstVaapiDisplay *display); + +GstVaapiVideoMeta * +gst_vaapi_video_meta_new_from_pool(GstVaapiVideoPool *pool); + +GstVaapiVideoMeta * +gst_vaapi_video_meta_new_with_image(GstVaapiImage *image); + +GstVaapiVideoMeta * +gst_vaapi_video_meta_new_with_surface(GstVaapiSurface *surface); + +GstVaapiVideoMeta * +gst_vaapi_video_meta_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); + +GstVaapiVideoMeta * +gst_vaapi_video_meta_ref(GstVaapiVideoMeta *meta); + +void +gst_vaapi_video_meta_unref(GstVaapiVideoMeta *meta); + +void +gst_vaapi_video_meta_replace(GstVaapiVideoMeta **old_meta_ptr, + GstVaapiVideoMeta *new_meta); + +GstVaapiDisplay * +gst_vaapi_video_meta_get_display(GstVaapiVideoMeta *meta); + +GstVaapiImage * +gst_vaapi_video_meta_get_image(GstVaapiVideoMeta *meta); + +void +gst_vaapi_video_meta_set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image); + +gboolean +gst_vaapi_video_meta_set_image_from_pool(GstVaapiVideoMeta *meta, + GstVaapiVideoPool *pool); + +GstVaapiSurface * +gst_vaapi_video_meta_get_surface(GstVaapiVideoMeta *meta); + +void +gst_vaapi_video_meta_set_surface(GstVaapiVideoMeta *meta, + GstVaapiSurface *surface); + +gboolean +gst_vaapi_video_meta_set_surface_from_pool(GstVaapiVideoMeta *meta, + GstVaapiVideoPool *pool); + +GstVaapiSurfaceProxy * +gst_vaapi_video_meta_get_surface_proxy(GstVaapiVideoMeta *meta); + +void +gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, + GstVaapiSurfaceProxy *proxy); + +GFunc +gst_vaapi_video_meta_get_surface_converter(GstVaapiVideoMeta *meta); + +void +gst_vaapi_video_meta_set_surface_converter(GstVaapiVideoMeta *meta, GFunc func); + +guint +gst_vaapi_video_meta_get_render_flags(GstVaapiVideoMeta *meta); + +void +gst_vaapi_video_meta_set_render_flags(GstVaapiVideoMeta *meta, guint flags); + +GstVaapiVideoMeta * +gst_buffer_get_vaapi_video_meta(GstBuffer *buffer); + +void +gst_buffer_set_vaapi_video_meta(GstBuffer *buffer, GstVaapiVideoMeta *meta); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_META_H */ From d6bbc652b4c12a98dc5411145134150cab5be6d1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 5 Jan 2013 17:37:13 +0100 Subject: [PATCH 0978/3781] videobuffer: wrap video meta into a surface buffer. Make GstVaapiVideoBuffer a simple wrapper for video meta. This buffer is no longer necessary but for compatibility with GStreamer 0.10 APIs or users expecting a GstSurfaceBuffer like Clutter. --- gst-libs/gst/vaapi/Makefile.am | 3 - gst-libs/gst/vaapi/gstvaapivideobuffer.c | 571 +----------------- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 59 +- gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c | 55 -- gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h | 85 --- gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h | 59 -- .../gst/vaapi/gstvaapivideoconverter_glx.c | 33 +- 7 files changed, 52 insertions(+), 813 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c delete mode 100644 gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h delete mode 100644 gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index acf393b06f..205f902583 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -117,7 +117,6 @@ libgstvaapi_source_priv_h = \ gstvaapiobject_priv.h \ gstvaapisurface_priv.h \ gstvaapiutils.h \ - gstvaapivideobuffer_priv.h \ gstvaapiworkarounds.h \ sysdeps.h \ $(NULL) @@ -169,7 +168,6 @@ libgstvaapi_glx_source_c = \ gstvaapiutils.c \ gstvaapiutils_glx.c \ gstvaapiutils_x11.c \ - gstvaapivideobuffer_glx.c \ gstvaapivideoconverter_glx.c \ gstvaapiwindow_glx.c \ $(NULL) @@ -177,7 +175,6 @@ libgstvaapi_glx_source_c = \ libgstvaapi_glx_source_h = \ gstvaapidisplay_glx.h \ gstvaapitexture.h \ - gstvaapivideobuffer_glx.h \ gstvaapivideoconverter_glx.h \ gstvaapiwindow_glx.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 987b467d57..994f057370 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -27,591 +27,80 @@ #include "sysdeps.h" #include "gstvaapivideobuffer.h" -#include "gstvaapivideobuffer_priv.h" -#include "gstvaapiimagepool.h" -#include "gstvaapisurfacepool.h" -#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, GST_TYPE_SURFACE_BUFFER) +G_DEFINE_TYPE(GstVaapiVideoBuffer, + gst_vaapi_video_buffer, + GST_TYPE_SURFACE_BUFFER) -#define GST_VAAPI_VIDEO_BUFFER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_VIDEO_BUFFER, \ - GstVaapiVideoBufferPrivate)) +typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc)( + GstSurfaceBuffer *surface, const gchar *type, GValue *dest); -struct _GstVaapiVideoBufferPrivate { - GstVaapiDisplay *display; - GstVaapiVideoPool *image_pool; - GstVaapiImage *image; - GstVaapiVideoPool *surface_pool; - GstVaapiSurface *surface; - GstVaapiSurfaceProxy *proxy; - GstBuffer *buffer; - guint render_flags; -}; - -static void -set_display(GstVaapiVideoBuffer *buffer, GstVaapiDisplay *display) +static GstSurfaceConverter * +gst_vaapi_video_buffer_create_converter(GstSurfaceBuffer *surface, + const gchar *type, GValue *dest) { - GstVaapiVideoBufferPrivate * const priv = buffer->priv; + GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(surface); + GstSurfaceConverterCreateFunc func; - g_clear_object(&priv->display); + func = (GstSurfaceConverterCreateFunc) + gst_vaapi_video_meta_get_surface_converter(vbuffer->meta); - if (display) - priv->display = g_object_ref(display); -} - -static inline void -set_image(GstVaapiVideoBuffer *buffer, GstVaapiImage *image) -{ - buffer->priv->image = g_object_ref(image); - set_display(buffer, GST_VAAPI_OBJECT_DISPLAY(image)); -} - -static inline void -set_surface(GstVaapiVideoBuffer *buffer, GstVaapiSurface *surface) -{ - buffer->priv->surface = g_object_ref(surface); - set_display(buffer, GST_VAAPI_OBJECT_DISPLAY(surface)); -} - -static void -gst_vaapi_video_buffer_destroy_image(GstVaapiVideoBuffer *buffer) -{ - GstVaapiVideoBufferPrivate * const priv = buffer->priv; - - if (priv->image) { - if (priv->image_pool) - gst_vaapi_video_pool_put_object(priv->image_pool, priv->image); - g_object_unref(priv->image); - priv->image = NULL; - } - - g_clear_object(&priv->image_pool); -} - -static void -gst_vaapi_video_buffer_destroy_surface(GstVaapiVideoBuffer *buffer) -{ - GstVaapiVideoBufferPrivate * const priv = buffer->priv; - - gst_vaapi_surface_proxy_replace(&priv->proxy, NULL); - - if (priv->surface) { - if (priv->surface_pool) - gst_vaapi_video_pool_put_object(priv->surface_pool, priv->surface); - g_object_unref(priv->surface); - priv->surface = NULL; - } - - g_clear_object(&priv->surface_pool); - - if (priv->buffer) { - gst_buffer_unref(priv->buffer); - priv->buffer = NULL; - } -} - -static void -gst_vaapi_video_buffer_finalize(GstMiniObject *object) -{ - GstVaapiVideoBuffer * const buffer = GST_VAAPI_VIDEO_BUFFER(object); - GstMiniObjectClass *parent_class; - - gst_vaapi_video_buffer_destroy_image(buffer); - gst_vaapi_video_buffer_destroy_surface(buffer); - - set_display(buffer, NULL); - - parent_class = GST_MINI_OBJECT_CLASS(gst_vaapi_video_buffer_parent_class); - if (parent_class->finalize) - parent_class->finalize(object); + return func ? func(surface, type, dest) : NULL; } static void gst_vaapi_video_buffer_class_init(GstVaapiVideoBufferClass *klass) { - GstMiniObjectClass * const object_class = GST_MINI_OBJECT_CLASS(klass); + GstSurfaceBufferClass * const surface_class = + GST_SURFACE_BUFFER_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiVideoBufferPrivate)); - - object_class->finalize = gst_vaapi_video_buffer_finalize; + surface_class->create_converter = gst_vaapi_video_buffer_create_converter; } static void gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) { - GstVaapiVideoBufferPrivate *priv; - - priv = GST_VAAPI_VIDEO_BUFFER_GET_PRIVATE(buffer); - buffer->priv = priv; - priv->display = NULL; - priv->image_pool = NULL; - priv->image = NULL; - priv->surface_pool = NULL; - priv->surface = NULL; - priv->proxy = NULL; - priv->buffer = NULL; - priv->render_flags = 0; -} - -static inline gboolean -gst_vaapi_video_buffer_is_a(GstBuffer *buffer, GType type) -{ - return G_TYPE_CHECK_INSTANCE_TYPE(buffer, type); -} - -static inline gpointer -_gst_vaapi_video_buffer_typed_new(GType type) -{ - g_return_val_if_fail(g_type_is_a(type, GST_VAAPI_TYPE_VIDEO_BUFFER), NULL); - - return gst_mini_object_new(type); } /** - * gst_vaapi_video_buffer_typed_new: - * @display: a #GstVaapiDisplay + * gst_vaapi_video_buffer_new: + * @meta: a #GstVaapiVideoMeta * - * Creates an empty #GstBuffer. The caller is responsible for completing - * the initialization of the buffer with the gst_vaapi_video_buffer_set_*() - * functions. - * - * This function shall only be called from within gstreamer-vaapi - * plugin elements. + * Creates a #GstBuffer that holds video @meta information. * * Return value: the newly allocated #GstBuffer, or %NULL or error */ GstBuffer * -gst_vaapi_video_buffer_typed_new(GType type, GstVaapiDisplay *display) +gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta) { GstBuffer *buffer; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(meta != NULL, NULL); - buffer = _gst_vaapi_video_buffer_typed_new(type); + buffer = GST_BUFFER_CAST(gst_mini_object_new(GST_TYPE_SURFACE_BUFFER)); if (!buffer) return NULL; - set_display(GST_VAAPI_VIDEO_BUFFER(buffer), display); + gst_buffer_set_vaapi_video_meta(buffer, meta); return buffer; } /** - * gst_vaapi_video_buffer_typed_new_from_pool: - * @pool: a #GstVaapiVideoPool - * - * Creates a #GstBuffer with a video object allocated from a @pool. - * Only #GstVaapiSurfacePool and #GstVaapiImagePool pools are supported. - * - * The buffer is destroyed through the last call to gst_buffer_unref() - * and the video objects are pushed back to their respective pools. - * - * Return value: the newly allocated #GstBuffer, or %NULL on error - */ -GstBuffer * -gst_vaapi_video_buffer_typed_new_from_pool(GType type, GstVaapiVideoPool *pool) -{ - GstVaapiVideoBuffer *buffer; - gboolean is_image_pool, is_surface_pool; - - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); - - is_image_pool = GST_VAAPI_IS_IMAGE_POOL(pool); - is_surface_pool = GST_VAAPI_IS_SURFACE_POOL(pool); - - if (!is_image_pool && !is_surface_pool) - return NULL; - - buffer = _gst_vaapi_video_buffer_typed_new(type); - if (buffer && - ((is_image_pool && - gst_vaapi_video_buffer_set_image_from_pool(buffer, pool)) || - (is_surface_pool && - gst_vaapi_video_buffer_set_surface_from_pool(buffer, pool)))) { - set_display(buffer, gst_vaapi_video_pool_get_display(pool)); - return GST_BUFFER(buffer); - } - - gst_mini_object_unref(GST_MINI_OBJECT(buffer)); - return NULL; -} - -/** - * gst_vaapi_video_buffer_typed_new_from_buffer: - * @buffer: a #GstBuffer - * - * Creates a #GstBuffer with video objects bound to @buffer video - * objects, if any. - * - * This function shall only be called from within gstreamer-vaapi - * plugin elements. - * - * Return value: the newly allocated #GstBuffer, or %NULL on error - */ -GstBuffer * -gst_vaapi_video_buffer_typed_new_from_buffer(GType type, GstBuffer *buffer) -{ - GstVaapiVideoBuffer *inbuf, *outbuf; - - if (!gst_vaapi_video_buffer_is_a(buffer, type)) { - if (!buffer->parent || - !gst_vaapi_video_buffer_is_a(buffer->parent, type)) - return NULL; - buffer = buffer->parent; - } - inbuf = GST_VAAPI_VIDEO_BUFFER(buffer); - - outbuf = _gst_vaapi_video_buffer_typed_new(type); - if (!outbuf) - return NULL; - - if (inbuf->priv->image) - gst_vaapi_video_buffer_set_image(outbuf, inbuf->priv->image); - if (inbuf->priv->surface) - gst_vaapi_video_buffer_set_surface(outbuf, inbuf->priv->surface); - if (inbuf->priv->proxy) - gst_vaapi_video_buffer_set_surface_proxy(outbuf, inbuf->priv->proxy); - - outbuf->priv->buffer = gst_buffer_ref(buffer); - return GST_BUFFER(outbuf); -} - -/** - * gst_vaapi_video_buffer_typed_new_with_image: - * @image: a #GstVaapiImage - * - * Creates a #GstBuffer with the specified @image. The resulting - * buffer holds an additional reference to the @image. - * - * This function shall only be called from within gstreamer-vaapi - * plugin elements. - * - * Return value: the newly allocated #GstBuffer, or %NULL on error - */ -GstBuffer * -gst_vaapi_video_buffer_typed_new_with_image(GType type, GstVaapiImage *image) -{ - GstVaapiVideoBuffer *buffer; - - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); - - buffer = _gst_vaapi_video_buffer_typed_new(type); - if (buffer) - gst_vaapi_video_buffer_set_image(buffer, image); - return GST_BUFFER(buffer); -} - -/** - * gst_vaapi_video_buffer_typed_new_with_surface: - * @surface: a #GstVaapiSurface - * - * Creates a #GstBuffer with the specified @surface. The resulting - * buffer holds an additional reference to the @surface. - * - * This function shall only be called from within gstreamer-vaapi - * plugin elements. - * - * Return value: the newly allocated #GstBuffer, or %NULL on error - */ -GstBuffer * -gst_vaapi_video_buffer_typed_new_with_surface( - GType type, - GstVaapiSurface *surface -) -{ - GstVaapiVideoBuffer *buffer; - - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - - buffer = _gst_vaapi_video_buffer_typed_new(type); - if (buffer) - gst_vaapi_video_buffer_set_surface(buffer, surface); - return GST_BUFFER(buffer); -} - -/** - * gst_vaapi_video_buffer_typed_new_with_surface_proxy: - * @proxy: a #GstVaapiSurfaceProxy - * - * Creates a #GstBuffer with the specified surface @proxy. The - * resulting buffer holds an additional reference to the @proxy. - * - * This function shall only be called from within gstreamer-vaapi - * plugin elements. - * - * Return value: the newly allocated #GstBuffer, or %NULL on error - */ -GstBuffer * -gst_vaapi_video_buffer_typed_new_with_surface_proxy( - GType type, - GstVaapiSurfaceProxy *proxy -) -{ - GstVaapiVideoBuffer *buffer; - - g_return_val_if_fail(proxy != NULL, NULL); - - buffer = _gst_vaapi_video_buffer_typed_new(type); - if (buffer) - gst_vaapi_video_buffer_set_surface_proxy(buffer, proxy); - return GST_BUFFER(buffer); -} - -/** - * gst_vaapi_video_buffer_get_display: + * gst_vaapi_video_buffer_get_meta: * @buffer: a #GstVaapiVideoBuffer * - * Retrieves the #GstVaapiDisplay the @buffer is bound to. The @buffer - * owns the returned #GstVaapiDisplay object so the caller is - * responsible for calling g_object_ref() when needed. + * Returns the #GstVaapiVideoMeta associated to this @buffer. * - * Return value: the #GstVaapiDisplay the @buffer is bound to + * Return value: the #GstVaapiVideoMeta bound to the @buffer, or %NULL + * if none was found */ -GstVaapiDisplay * -gst_vaapi_video_buffer_get_display(GstVaapiVideoBuffer *buffer) +GstVaapiVideoMeta * +gst_vaapi_video_buffer_get_meta(GstVaapiVideoBuffer *buffer) { g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL); - return buffer->priv->display; -} - -/** - * gst_vaapi_video_buffer_get_image: - * @buffer: a #GstVaapiVideoBuffer - * - * Retrieves the #GstVaapiImage bound to the @buffer. The @buffer owns - * the #GstVaapiImage so the caller is responsible for calling - * g_object_ref() when needed. - * - * Return value: the #GstVaapiImage bound to the @buffer, or %NULL if - * there is none - */ -GstVaapiImage * -gst_vaapi_video_buffer_get_image(GstVaapiVideoBuffer *buffer) -{ - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL); - - return buffer->priv->image; -} - -/** - * gst_vaapi_video_buffer_set_image: - * @buffer: a #GstVaapiVideoBuffer - * @image: a #GstVaapiImage - * - * Binds @image to the @buffer. If the @buffer contains another image - * previously allocated from a pool, it's pushed back to its parent - * pool and the pool is also released. - */ -void -gst_vaapi_video_buffer_set_image( - GstVaapiVideoBuffer *buffer, - GstVaapiImage *image -) -{ - g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer)); - g_return_if_fail(GST_VAAPI_IS_IMAGE(image)); - - gst_vaapi_video_buffer_destroy_image(buffer); - - if (image) - set_image(buffer, image); -} - -/** - * gst_vaapi_video_buffer_set_image_from_pool - * @buffer: a #GstVaapiVideoBuffer - * @pool: a #GstVaapiVideoPool - * - * Binds a newly allocated video object from the @pool. The @pool - * shall be of type #GstVaapiImagePool. Previously allocated objects - * are released and returned to their parent pools, if any. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_video_buffer_set_image_from_pool( - GstVaapiVideoBuffer *buffer, - GstVaapiVideoPool *pool -) -{ - GstVaapiImage *image; - - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_IMAGE_POOL(pool), FALSE); - - gst_vaapi_video_buffer_destroy_image(buffer); - - if (pool) { - image = gst_vaapi_video_pool_get_object(pool); - if (!image) - return FALSE; - set_image(buffer, image); - buffer->priv->image_pool = g_object_ref(pool); - } - return TRUE; -} - -/** - * gst_vaapi_video_buffer_get_surface: - * @buffer: a #GstVaapiVideoBuffer - * - * Retrieves the #GstVaapiSurface bound to the @buffer. The @buffer - * owns the #GstVaapiSurface so the caller is responsible for calling - * g_object_ref() when needed. - * - * Return value: the #GstVaapiSurface bound to the @buffer, or %NULL if - * there is none - */ -GstVaapiSurface * -gst_vaapi_video_buffer_get_surface(GstVaapiVideoBuffer *buffer) -{ - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL); - - return buffer->priv->surface; -} - -/** - * gst_vaapi_video_buffer_set_surface: - * @buffer: a #GstVaapiVideoBuffer - * @surface: a #GstVaapiSurface - * - * Binds @surface to the @buffer. If the @buffer contains another - * surface previously allocated from a pool, it's pushed back to its - * parent pool and the pool is also released. - */ -void -gst_vaapi_video_buffer_set_surface( - GstVaapiVideoBuffer *buffer, - GstVaapiSurface *surface -) -{ - g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer)); - g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); - - gst_vaapi_video_buffer_destroy_surface(buffer); - - if (surface) - set_surface(buffer, surface); -} - -/** - * gst_vaapi_video_buffer_set_surface_from_pool - * @buffer: a #GstVaapiVideoBuffer - * @pool: a #GstVaapiVideoPool - * - * Binds a newly allocated video object from the @pool. The @pool - * shall be of type #GstVaapiSurfacePool. Previously allocated objects - * are released and returned to their parent pools, if any. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_video_buffer_set_surface_from_pool( - GstVaapiVideoBuffer *buffer, - GstVaapiVideoPool *pool -) -{ - GstVaapiSurface *surface; - - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), FALSE); - - gst_vaapi_video_buffer_destroy_surface(buffer); - - if (pool) { - surface = gst_vaapi_video_pool_get_object(pool); - if (!surface) - return FALSE; - set_surface(buffer, surface); - buffer->priv->surface_pool = g_object_ref(pool); - } - return TRUE; -} - -/** - * gst_vaapi_video_buffer_get_surface_proxy: - * @buffer: a #GstVaapiVideoBuffer - * - * Retrieves the #GstVaapiSurfaceProxy bound to the @buffer. The @buffer - * owns the #GstVaapiSurfaceProxy so the caller is responsible for calling - * g_object_ref() when needed. - * - * Return value: the #GstVaapiSurfaceProxy bound to the @buffer, or - * %NULL if there is none - */ -GstVaapiSurfaceProxy * -gst_vaapi_video_buffer_get_surface_proxy(GstVaapiVideoBuffer *buffer) -{ - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL); - - return buffer->priv->proxy; -} - -/** - * gst_vaapi_video_buffer_set_surface_proxy: - * @buffer: a #GstVaapiVideoBuffer - * @proxy: a #GstVaapiSurfaceProxy - * - * Binds surface @proxy to the @buffer. If the @buffer contains another - * surface previously allocated from a pool, it's pushed back to its - * parent pool and the pool is also released. - */ -void -gst_vaapi_video_buffer_set_surface_proxy( - GstVaapiVideoBuffer *buffer, - GstVaapiSurfaceProxy *proxy -) -{ - GstVaapiSurface *surface; - - g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer)); - g_return_if_fail(proxy != NULL); - - gst_vaapi_video_buffer_destroy_surface(buffer); - - if (proxy) { - surface = GST_VAAPI_SURFACE_PROXY_SURFACE(proxy); - if (!surface) - return; - set_surface(buffer, surface); - buffer->priv->proxy = gst_vaapi_surface_proxy_ref(proxy); - } -} - -/** - * gst_vaapi_video_buffer_get_render_flags: - * @buffer: a #GstVaapiVideoBuffer - * - * Retrieves the surface render flags bound to the @buffer. - * - * Return value: a combination for #GstVaapiSurfaceRenderFlags - */ -guint -gst_vaapi_video_buffer_get_render_flags(GstVaapiVideoBuffer *buffer) -{ - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), 0); - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(buffer->priv->surface), 0); - - return buffer->priv->render_flags; -} - -/** - * gst_vaapi_video_buffer_set_render_flags: - * @buffer: a #GstVaapiVideoBuffer - * @flags: a set of surface render flags - * - * Sets #GstVaapiSurfaceRenderFlags to the @buffer. - */ -void -gst_vaapi_video_buffer_set_render_flags(GstVaapiVideoBuffer *buffer, guint flags) -{ - g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer)); - g_return_if_fail(GST_VAAPI_IS_SURFACE(buffer->priv->surface)); - - buffer->priv->render_flags = flags; + return buffer->meta; } diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index 5d479b241f..e7f09ed3be 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -24,11 +24,7 @@ #define GST_VAAPI_VIDEO_BUFFER_H #include -#include -#include -#include -#include -#include +#include G_BEGIN_DECLS @@ -57,7 +53,6 @@ G_BEGIN_DECLS GstVaapiVideoBufferClass)) typedef struct _GstVaapiVideoBuffer GstVaapiVideoBuffer; -typedef struct _GstVaapiVideoBufferPrivate GstVaapiVideoBufferPrivate; typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass; /** @@ -69,7 +64,7 @@ struct _GstVaapiVideoBuffer { /*< private >*/ GstSurfaceBuffer parent_instance; - GstVaapiVideoBufferPrivate *priv; + GstVaapiVideoMeta *meta; }; /** @@ -85,53 +80,11 @@ struct _GstVaapiVideoBufferClass { GType gst_vaapi_video_buffer_get_type(void) G_GNUC_CONST; -GstVaapiDisplay * -gst_vaapi_video_buffer_get_display(GstVaapiVideoBuffer *buffer); +GstBuffer * +gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta); -GstVaapiImage * -gst_vaapi_video_buffer_get_image(GstVaapiVideoBuffer *buffer); - -void -gst_vaapi_video_buffer_set_image( - GstVaapiVideoBuffer *buffer, - GstVaapiImage *image -); - -gboolean -gst_vaapi_video_buffer_set_image_from_pool( - GstVaapiVideoBuffer *buffer, - GstVaapiVideoPool *pool -); - -GstVaapiSurface * -gst_vaapi_video_buffer_get_surface(GstVaapiVideoBuffer *buffer); - -void -gst_vaapi_video_buffer_set_surface( - GstVaapiVideoBuffer *buffer, - GstVaapiSurface *surface -); - -gboolean -gst_vaapi_video_buffer_set_surface_from_pool( - GstVaapiVideoBuffer *buffer, - GstVaapiVideoPool *pool -); - -GstVaapiSurfaceProxy * -gst_vaapi_video_buffer_get_surface_proxy(GstVaapiVideoBuffer *buffer); - -void -gst_vaapi_video_buffer_set_surface_proxy( - GstVaapiVideoBuffer *buffer, - GstVaapiSurfaceProxy *proxy -); - -guint -gst_vaapi_video_buffer_get_render_flags(GstVaapiVideoBuffer *buffer); - -void -gst_vaapi_video_buffer_set_render_flags(GstVaapiVideoBuffer *buffer, guint flags); +GstVaapiVideoMeta * +gst_vaapi_video_buffer_get_meta(GstVaapiVideoBuffer *buffer); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c deleted file mode 100644 index 7ab4b51e1c..0000000000 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * gstvaapivideobuffer_glx.c - Gst VA video buffer - * - * Copyright (C) 2011 Intel Corporation - * Copyright (C) 2011 Collabora Ltd. - * Author: Nicolas Dufresne - * - * 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:gstvaapivideobufferglx - * @short_description: VA video buffer for GStreamer with GLX support - */ - -#include "sysdeps.h" -#include "gstvaapivideobuffer_glx.h" -#include "gstvaapivideoconverter_glx.h" -#include "gstvaapivideopool.h" -#include "gstvaapivideobuffer_priv.h" -#include "gstvaapidisplay_priv.h" - -#define DEBUG 1 -#include "gstvaapidebug.h" - -G_DEFINE_TYPE(GstVaapiVideoBufferGLX, - gst_vaapi_video_buffer_glx, - GST_VAAPI_TYPE_VIDEO_BUFFER) - -static void -gst_vaapi_video_buffer_glx_class_init(GstVaapiVideoBufferGLXClass *klass) -{ - GstSurfaceBufferClass * const surface_class = - GST_SURFACE_BUFFER_CLASS(klass); - - surface_class->create_converter = gst_vaapi_video_converter_glx_new; -} - -static void -gst_vaapi_video_buffer_glx_init(GstVaapiVideoBufferGLX *buffer) -{ -} diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h b/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h deleted file mode 100644 index 0dbe065c09..0000000000 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * gstvaapivideobuffer_glx.h - Gstreamer/VA video buffer - * - * Copyright (C) 2011 Intel Corporation - * Copyright (C) 2011 Collabora Ltd. - * Author: Nicolas Dufresne - * - * 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_VIDEO_BUFFER_GLX_H -#define GST_VAAPI_VIDEO_BUFFER_GLX_H - -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_VAAPI_TYPE_VIDEO_BUFFER_GLX \ - (gst_vaapi_video_buffer_glx_get_type()) - -#define GST_VAAPI_VIDEO_BUFFER_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, \ - GstVaapiVideoBufferGLX)) - -#define GST_VAAPI_VIDEO_BUFFER_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, \ - GstVaapiVideoBufferGLXClass)) - -#define GST_VAAPI_IS_VIDEO_BUFFER_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_BUFFER_GLX)) - -#define GST_VAAPI_IS_VIDEO_BUFFER_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_BUFFER_GLX)) - -#define GST_VAAPI_VIDEO_BUFFER_GLX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_VIDEO_BUFFER_GLX, \ - GstVaapiVideoBufferGLXClass)) - -typedef struct _GstVaapiVideoBufferGLX GstVaapiVideoBufferGLX; -typedef struct _GstVaapiVideoBufferGLXClass GstVaapiVideoBufferGLXClass; - -/** - * GstVaapiVideoBufferGLX: - * - * A #GstBuffer holding video objects (#GstVaapiSurface and #GstVaapiImage). - */ -struct _GstVaapiVideoBufferGLX { - /*< private >*/ - GstVaapiVideoBuffer parent_instance; -}; - -/** - * GstVaapiVideoBufferGLXClass: - * - * A #GstBuffer holding video objects - */ -struct _GstVaapiVideoBufferGLXClass { - /*< private >*/ - GstVaapiVideoBufferClass parent_class; -}; - -GType gst_vaapi_video_buffer_glx_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* GST_VAAPI_VIDEO_BUFFER_GLX_H */ diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h b/gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h deleted file mode 100644 index a08edbd8bf..0000000000 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * gstvaapivideobuffer_priv.h - Gstreamer/VA video buffer (private interface) - * - * Copyright (C) 2011 Intel Corporation - * Copyright (C) 2011 Collabora Ltd. - * Author: Nicolas Dufresne - * - * 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_VIDEO_BUFFER_PRIV_H -#define GST_VAAPI_VIDEO_BUFFER_PRIV_H - -#include - -G_BEGIN_DECLS - -/* Private API for gstreamer-vaapi plugin elements only */ - -GstBuffer * -gst_vaapi_video_buffer_typed_new(GType type, GstVaapiDisplay *display); - -GstBuffer * -gst_vaapi_video_buffer_typed_new_from_pool(GType type, GstVaapiVideoPool *pool); - -GstBuffer * -gst_vaapi_video_buffer_typed_new_from_buffer(GType type, GstBuffer *buffer); - -GstBuffer * -gst_vaapi_video_buffer_typed_new_with_image(GType type, GstVaapiImage *image); - -GstBuffer * -gst_vaapi_video_buffer_typed_new_with_surface( - GType type, - GstVaapiSurface *surface -); - -GstBuffer * -gst_vaapi_video_buffer_typed_new_with_surface_proxy( - GType type, - GstVaapiSurfaceProxy *proxy -); - -G_END_DECLS - -#endif /* GST_VAAPI_VIDEO_BUFFER_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index 26de76803f..dc5c62e21e 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -87,27 +87,25 @@ GstSurfaceConverter * gst_vaapi_video_converter_glx_new(GstSurfaceBuffer *surface, const gchar *type, GValue *dest) { - GstVaapiVideoBuffer *buffer = GST_VAAPI_VIDEO_BUFFER (surface); - GstVaapiDisplay *display = gst_vaapi_video_buffer_get_display (buffer); + GstVaapiVideoMeta * const meta = + gst_vaapi_video_buffer_get_meta(GST_VAAPI_VIDEO_BUFFER(surface)); GstVaapiTexture *texture; - GstVaapiVideoConverterGLX *converter = NULL; + GstVaapiVideoConverterGLX *converter; /* We only support Open GL texture conversion */ - if (strcmp(type, "opengl") || !G_VALUE_HOLDS_UINT (dest)) + if (strcmp(type, "opengl") || !G_VALUE_HOLDS_UINT(dest)) return NULL; /* FIXME Should we assume target and format ? */ - texture = gst_vaapi_texture_new_with_texture (display, - g_value_get_uint (dest), - GL_TEXTURE_2D, - GL_BGRA); + texture = gst_vaapi_texture_new_with_texture( + gst_vaapi_video_meta_get_display(meta), + g_value_get_uint(dest), GL_TEXTURE_2D, GL_BGRA); + if (!texture) + return NULL; - if (texture) { - converter = g_object_new (GST_VAAPI_TYPE_VIDEO_CONVERTER, NULL); - converter->priv->texture = texture; - } - - return GST_SURFACE_CONVERTER (converter); + converter = g_object_new(GST_VAAPI_TYPE_VIDEO_CONVERTER, NULL); + converter->priv->texture = texture; + return GST_SURFACE_CONVERTER(converter); } gboolean @@ -116,8 +114,9 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *converter, { GstVaapiVideoConverterGLXPrivate *priv = GST_VAAPI_VIDEO_CONVERTER_GLX (converter)->priv; - GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER (buffer); - GstVaapiSurface *surface = gst_vaapi_video_buffer_get_surface (vbuffer); + GstVaapiVideoMeta * const meta = + gst_vaapi_video_buffer_get_meta (GST_VAAPI_VIDEO_BUFFER (buffer)); + GstVaapiSurface *surface = gst_vaapi_video_meta_get_surface (meta); GstVaapiDisplay *new_dpy, *old_dpy; GstVideoOverlayComposition * const composition = gst_video_buffer_get_overlay_composition (GST_BUFFER (buffer)); @@ -139,5 +138,5 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *converter, GST_WARNING ("could not update subtitles"); return gst_vaapi_texture_put_surface (priv->texture, surface, - gst_vaapi_video_buffer_get_render_flags (vbuffer)); + gst_vaapi_video_meta_get_render_flags (meta)); } From a00ae0918a00cd6b8b187e7120f60e738b47ccfb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 5 Jan 2013 17:55:47 +0100 Subject: [PATCH 0979/3781] plugins: cope with new GstVaapiVideoMeta API. Update plugin elements with the new GstVaapiVideoMeta API. This also fixes support for subpictures/overlay because GstVideoDecoder generates a sub-buffer from the GstVaapiVideoBuffer. So, that sub-buffer is marked as read-only. However, when comes in the textoverlay element for example, it checks whether the input buffer is writable. Since that buffer read-only, then a new GstBuffer is created. Since gst_buffer_copy() does not preserve the parent field, the generated buffer in textoverlay is not exploitable because we lost all VA specific information. Now, with GstVaapiVideoMeta information attached to a standard GstBuffer, all information are preserved through gst_buffer_copy() since the latter does copy metadata (qdata in this case). --- gst/vaapi/gstvaapidecode.c | 8 ++- gst/vaapi/gstvaapidownload.c | 14 ++--- gst/vaapi/gstvaapipluginbuffer.c | 92 +++++++++----------------------- gst/vaapi/gstvaapipluginbuffer.h | 4 -- gst/vaapi/gstvaapipostproc.c | 25 ++++----- gst/vaapi/gstvaapisink.c | 38 +++++++------ gst/vaapi/gstvaapiupload.c | 8 +-- gst/vaapi/gstvaapiuploader.c | 41 ++++++-------- 8 files changed, 82 insertions(+), 148 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 611c713019..572d8a9fa5 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -30,7 +30,7 @@ #include "gst/vaapi/sysdeps.h" #include -#include +#include #include #include "gstvaapidecode.h" @@ -224,13 +224,11 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) gst_vaapi_surface_proxy_set_user_data(proxy, decode, (GDestroyNotify)gst_vaapidecode_release); - out_frame->output_buffer = gst_vaapi_video_buffer_new(decode->display); + out_frame->output_buffer = + gst_vaapi_video_buffer_new_with_surface_proxy(proxy); if (!out_frame->output_buffer) goto error_create_buffer; - gst_vaapi_video_buffer_set_surface_proxy( - GST_VAAPI_VIDEO_BUFFER(out_frame->output_buffer), proxy); - ret = gst_video_decoder_finish_frame(vdec, out_frame); if (ret != GST_FLOW_OK) goto error_commit_buffer; diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 2f1271131c..34a8dcbe0a 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "gstvaapidownload.h" #include "gstvaapipluginutil.h" @@ -333,14 +333,14 @@ get_surface_format(GstVaapiSurface *surface) static gboolean gst_vaapidownload_update_src_caps(GstVaapiDownload *download, GstBuffer *buffer) { - GstVaapiVideoBuffer *vbuffer; + GstVaapiVideoMeta *meta; GstVaapiSurface *surface; GstVaapiImageFormat format; GstPad *srcpad; GstCaps *in_caps, *out_caps; - vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); - surface = gst_vaapi_video_buffer_get_surface(vbuffer); + meta = gst_buffer_get_vaapi_video_meta(buffer); + surface = gst_vaapi_video_meta_get_surface(meta); if (!surface) { GST_WARNING("failed to retrieve VA surface from buffer"); return FALSE; @@ -395,13 +395,13 @@ gst_vaapidownload_transform( ) { GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - GstVaapiVideoBuffer *vbuffer; + GstVaapiVideoMeta *meta; GstVaapiSurface *surface; GstVaapiImage *image = NULL; gboolean success; - vbuffer = GST_VAAPI_VIDEO_BUFFER(inbuf); - surface = gst_vaapi_video_buffer_get_surface(vbuffer); + meta = gst_buffer_get_vaapi_video_meta(inbuf); + surface = gst_vaapi_video_meta_get_surface(meta); if (!surface) return GST_FLOW_UNEXPECTED; diff --git a/gst/vaapi/gstvaapipluginbuffer.c b/gst/vaapi/gstvaapipluginbuffer.c index 9d6859dc31..560081d611 100644 --- a/gst/vaapi/gstvaapipluginbuffer.c +++ b/gst/vaapi/gstvaapipluginbuffer.c @@ -23,115 +23,73 @@ # include "config.h" #endif +#include #include -#include #if USE_GLX -# include +# include #endif #include "gstvaapipluginbuffer.h" -static GType -get_type(GstVaapiDisplay *display) +static GFunc +get_surface_converter(GstVaapiDisplay *display) { - GType type; + GFunc func; switch (gst_vaapi_display_get_display_type(display)) { #if USE_GLX case GST_VAAPI_DISPLAY_TYPE_GLX: - type = GST_VAAPI_TYPE_VIDEO_BUFFER_GLX; + func = (GFunc)gst_vaapi_video_converter_glx_new; break; #endif default: - type = GST_VAAPI_TYPE_VIDEO_BUFFER; + func = NULL; break; } - return type; + return func; } -GstBuffer * -gst_vaapi_video_buffer_new(GstVaapiDisplay *display) +static GstBuffer * +get_buffer(GstVaapiVideoMeta *meta) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + GstBuffer *buffer; - return gst_vaapi_video_buffer_typed_new(get_type(display), display); + if (!meta) + return NULL; + + gst_vaapi_video_meta_set_surface_converter(meta, + get_surface_converter(gst_vaapi_video_meta_get_display(meta))); + + buffer = gst_vaapi_video_buffer_new(meta); + gst_vaapi_video_meta_unref(meta); + return buffer; } GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) { - GstVaapiDisplay *display; - - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); - - display = gst_vaapi_video_pool_get_display(pool); - if (!display) - return NULL; - return gst_vaapi_video_buffer_typed_new_from_pool(get_type(display), pool); + return get_buffer(gst_vaapi_video_meta_new_from_pool(pool)); } GstBuffer * gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) { - GstVaapiVideoBuffer *vbuffer; - GstVaapiDisplay *display; - - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL); - - vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); - display = gst_vaapi_video_buffer_get_display(vbuffer); - if (!display) - return NULL; - - return gst_vaapi_video_buffer_typed_new_from_buffer( - get_type(display), buffer); + return get_buffer(gst_buffer_get_vaapi_video_meta(buffer)); } GstBuffer * gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) { - GstVaapiDisplay *display; - - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); - - display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(image)); - if (!display) - return NULL; - - return gst_vaapi_video_buffer_typed_new_with_image( - get_type(display), image); + return get_buffer(gst_vaapi_video_meta_new_with_image(image)); } GstBuffer * gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) { - GstVaapiDisplay *display; - - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - - display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); - if (!display) - return NULL; - - return gst_vaapi_video_buffer_typed_new_with_surface( - get_type(display), surface); + return get_buffer(gst_vaapi_video_meta_new_with_surface(surface)); } GstBuffer * gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) { - GstVaapiDisplay *display; - GstVaapiSurface *surface; - - g_return_val_if_fail(proxy != NULL, NULL); - - surface = gst_vaapi_surface_proxy_get_surface(proxy); - if (!surface) - return NULL; - - display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); - if (!display) - return NULL; - - return gst_vaapi_video_buffer_typed_new_with_surface_proxy( - get_type(display), proxy); + return get_buffer(gst_vaapi_video_meta_new_with_surface_proxy(proxy)); } diff --git a/gst/vaapi/gstvaapipluginbuffer.h b/gst/vaapi/gstvaapipluginbuffer.h index d6798d5d9d..fb2dbfff4b 100644 --- a/gst/vaapi/gstvaapipluginbuffer.h +++ b/gst/vaapi/gstvaapipluginbuffer.h @@ -22,10 +22,6 @@ #ifndef GST_VAAPI_PLUGIN_BUFFER_H #define GST_VAAPI_PLUGIN_BUFFER_H -G_GNUC_INTERNAL -GstBuffer * -gst_vaapi_video_buffer_new(GstVaapiDisplay *display); - G_GNUC_INTERNAL GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6355d9bfe3..62dcc115ac 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -31,7 +31,7 @@ #include "gst/vaapi/sysdeps.h" #include #include -#include +#include #include "gstvaapipostproc.h" #include "gstvaapipluginutil.h" @@ -255,7 +255,7 @@ gst_vaapipostproc_stop(GstVaapiPostproc *postproc) static GstFlowReturn gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) { - GstVaapiVideoBuffer *vbuf; + GstVaapiVideoMeta *meta; GstVaapiSurfaceProxy *proxy; GstClockTime timestamp; GstFlowReturn ret; @@ -263,18 +263,15 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) guint outbuf_flags, flags; gboolean tff; - if (GST_VAAPI_IS_VIDEO_BUFFER(buf)) - vbuf = GST_VAAPI_VIDEO_BUFFER(buf); - else if (GST_VAAPI_IS_VIDEO_BUFFER(buf->parent)) - vbuf = GST_VAAPI_VIDEO_BUFFER(buf->parent); - else + meta = gst_buffer_get_vaapi_video_meta(buf); + if (!meta) goto error_invalid_buffer; - flags = gst_vaapi_video_buffer_get_render_flags(vbuf); + flags = gst_vaapi_video_meta_get_render_flags(meta); /* Deinterlacing disabled, push frame */ if (!postproc->deinterlace) { - gst_vaapi_video_buffer_set_render_flags(vbuf, flags); + gst_vaapi_video_meta_set_render_flags(meta, flags); ret = gst_pad_push(postproc->srcpad, buf); if (ret != GST_FLOW_OK) goto error_push_buffer; @@ -282,7 +279,7 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) } timestamp = GST_BUFFER_TIMESTAMP(buf); - proxy = gst_vaapi_video_buffer_get_surface_proxy(vbuf); + proxy = gst_vaapi_video_meta_get_surface_proxy(meta); tff = GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_TFF); flags &= ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| @@ -293,14 +290,14 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) if (!outbuf) goto error_create_buffer; - vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf); + meta = gst_buffer_get_vaapi_video_meta(outbuf); outbuf_flags = flags; outbuf_flags |= postproc->deinterlace ? ( tff ? GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) : GST_VAAPI_PICTURE_STRUCTURE_FRAME; - gst_vaapi_video_buffer_set_render_flags(vbuf, outbuf_flags); + gst_vaapi_video_meta_set_render_flags(meta, outbuf_flags); GST_BUFFER_TIMESTAMP(outbuf) = timestamp; GST_BUFFER_DURATION(outbuf) = postproc->field_duration; @@ -314,14 +311,14 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) if (!outbuf) goto error_create_buffer; - vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf); + meta = gst_buffer_get_vaapi_video_meta(outbuf); outbuf_flags = flags; outbuf_flags |= postproc->deinterlace ? ( tff ? GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD : GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) : GST_VAAPI_PICTURE_STRUCTURE_FRAME; - gst_vaapi_video_buffer_set_render_flags(vbuf, outbuf_flags); + gst_vaapi_video_meta_set_render_flags(meta, outbuf_flags); GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration; GST_BUFFER_DURATION(outbuf) = postproc->field_duration; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 22284da093..aa3249ceef 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #if USE_DRM # include #endif @@ -858,33 +858,31 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstVideoOverlayComposition *composition; - GstVaapiVideoBuffer *vbuffer; + GstVaapiVideoMeta *meta; GstVaapiSurface *surface; GstBuffer *buffer; guint flags; gboolean success; - if (GST_VAAPI_IS_VIDEO_BUFFER(src_buffer)) + meta = gst_buffer_get_vaapi_video_meta(src_buffer); + if (meta) buffer = gst_buffer_ref(src_buffer); - else if (GST_VAAPI_IS_VIDEO_BUFFER(src_buffer->parent)) - buffer = gst_buffer_ref(src_buffer->parent); - else if (sink->use_video_raw) + else if (sink->use_video_raw) { buffer = gst_vaapi_uploader_get_buffer(sink->uploader); + if (!buffer) + return GST_FLOW_UNEXPECTED; + if (!gst_vaapi_uploader_process(sink->uploader, src_buffer, buffer)) + goto error; + meta = gst_buffer_get_vaapi_video_meta(buffer); + if (!meta) + goto error; + } else - buffer = NULL; - if (!buffer) return GST_FLOW_UNEXPECTED; - if (sink->use_video_raw && !gst_vaapi_uploader_process(sink->uploader, - src_buffer, buffer)) - goto error; - - vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); - g_return_val_if_fail(vbuffer != NULL, GST_FLOW_UNEXPECTED); - - if (sink->display != gst_vaapi_video_buffer_get_display (vbuffer)) { - g_clear_object(&sink->display); - sink->display = g_object_ref (gst_vaapi_video_buffer_get_display (vbuffer)); + if (sink->display != gst_vaapi_video_meta_get_display(meta)) { + g_clear_object(&sink->display); + sink->display = g_object_ref(gst_vaapi_video_meta_get_display(meta)); } if (!sink->window) @@ -892,14 +890,14 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) gst_vaapisink_ensure_rotation(sink, TRUE); - surface = gst_vaapi_video_buffer_get_surface(vbuffer); + surface = gst_vaapi_video_meta_get_surface(meta); if (!surface) goto error; GST_DEBUG("render surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); - flags = gst_vaapi_video_buffer_get_render_flags(vbuffer); + flags = gst_vaapi_video_meta_get_render_flags(meta); composition = gst_video_buffer_get_overlay_composition(src_buffer); if (!gst_vaapi_surface_set_subpictures_from_composition(surface, diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 19209684fd..6e5b054534 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include "gstvaapiupload.h" #include "gstvaapipluginutil.h" @@ -465,12 +465,8 @@ gst_vaapiupload_prepare_output_buffer( if (!gst_vaapi_uploader_has_direct_rendering(upload->uploader)) buffer = gst_vaapi_uploader_get_buffer(upload->uploader); - else if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) - buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf); - else if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf->parent)) - buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf->parent); else - buffer = NULL; + buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf); if (!buffer) return GST_FLOW_UNEXPECTED; diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index e6bf74dd20..425b2e77e9 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include "gstvaapiuploader.h" #include "gstvaapipluginbuffer.h" @@ -370,46 +370,36 @@ gst_vaapi_uploader_process( GstBuffer *out_buffer ) { - GstVaapiVideoBuffer *out_vbuffer; + GstVaapiVideoMeta *src_meta, *out_meta; GstVaapiSurface *surface; GstVaapiImage *image; g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); - if (GST_VAAPI_IS_VIDEO_BUFFER(out_buffer)) - out_vbuffer = GST_VAAPI_VIDEO_BUFFER(out_buffer); - else if (GST_VAAPI_IS_VIDEO_BUFFER(out_buffer->parent)) - out_vbuffer = GST_VAAPI_VIDEO_BUFFER(out_buffer->parent); - else { + out_meta = gst_buffer_get_vaapi_video_meta(out_buffer); + if (!out_meta) { GST_WARNING("expected an output video buffer"); return FALSE; } - surface = gst_vaapi_video_buffer_get_surface(out_vbuffer); + surface = gst_vaapi_video_meta_get_surface(out_meta); g_return_val_if_fail(surface != NULL, FALSE); - if (GST_VAAPI_IS_VIDEO_BUFFER(src_buffer)) { + src_meta = gst_buffer_get_vaapi_video_meta(src_buffer); + if (src_meta) { /* GstVaapiVideoBuffer with mapped VA image */ - image = gst_vaapi_video_buffer_get_image( - GST_VAAPI_VIDEO_BUFFER(src_buffer)); - if (!image || !gst_vaapi_image_unmap(image)) - return FALSE; - } - else if (GST_VAAPI_IS_VIDEO_BUFFER(src_buffer->parent)) { - /* Sub-buffer from GstVaapiVideoBuffer with mapped VA image */ - image = gst_vaapi_video_buffer_get_image( - GST_VAAPI_VIDEO_BUFFER(src_buffer->parent)); + image = gst_vaapi_video_meta_get_image(src_meta); if (!image || !gst_vaapi_image_unmap(image)) return FALSE; } else { /* Regular GstBuffer that needs to be uploaded to a VA image */ - image = gst_vaapi_video_buffer_get_image(out_vbuffer); + image = gst_vaapi_video_meta_get_image(out_meta); if (!image) { image = gst_vaapi_video_pool_get_object(uploader->priv->images); if (!image) return FALSE; - gst_vaapi_video_buffer_set_image(out_vbuffer, image); + gst_vaapi_video_meta_set_image(out_meta, image); } if (!gst_vaapi_image_update_from_buffer(image, src_buffer, NULL)) return FALSE; @@ -443,8 +433,8 @@ gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) GstVaapiUploaderPrivate *priv; GstVaapiSurface *surface; GstVaapiImage *image; - GstVaapiVideoBuffer *vbuffer; - GstBuffer *buffer = NULL; + GstVaapiVideoMeta *meta; + GstBuffer *buffer; g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), NULL); @@ -455,7 +445,8 @@ gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) GST_WARNING("failed to allocate video buffer"); goto error; } - vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer); + + meta = gst_buffer_get_vaapi_video_meta(buffer); surface = gst_vaapi_video_pool_get_object(priv->surfaces); if (!surface) { @@ -463,9 +454,9 @@ gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) goto error; } - gst_vaapi_video_buffer_set_surface(vbuffer, surface); + gst_vaapi_video_meta_set_surface(meta, surface); - image = gst_vaapi_video_buffer_get_image(vbuffer); + image = gst_vaapi_video_meta_get_image(meta); if (!gst_vaapi_image_map(image)) { GST_WARNING("failed to map VA image"); goto error; From cc769f0c2da8dc7b772c54af22f5dc9f291ef44f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sun, 6 Jan 2013 19:05:49 +0100 Subject: [PATCH 0980/3781] codecparsers: update to gst-vaapi-rebased commit b47983a. b47983a h264: add inferred value for slice_beta_offset_div2 --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 73d6aab46c..b47983a6ab 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 73d6aab46c14d943f2a0238e70812d775f06ffee +Subproject commit b47983a6ab0893815f62c03b4410b7104463c57f From 0963afce0b8084062848fbb1d74e07ba28afdf6e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Sat, 5 Jan 2013 12:33:06 +0200 Subject: [PATCH 0981/3781] h264: set default values for some header fields. The SPS, PPS and slice headers are not fully zero-initialized in the codecparsers/ library. Rather, the standard upstream behaviour is to initialize only certain syntax elements with some inferred values if they are not present in the bitstream. At the gstreamer-vaapi decoder level, we need to further initialize certain syntax elements with some sensible default values so that to not complicate VA drivers that just pass those verbatim to the HW, and also avoid an memset() of the whole decoder unit. Signed-off-by: Sreerenj Balachandran Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index a37548cef6..ac93d1f196 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -983,6 +983,10 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) GST_DEBUG("parse SPS"); + /* Variables that don't have inferred values per the H.264 + standard but that should get a default value anyway */ + sps->log2_max_pic_order_cnt_lsb_minus4 = 0; + result = gst_h264_parser_parse_sps(priv->parser, &unit->nalu, sps, TRUE); if (result != GST_H264_PARSER_OK) return get_status(result); @@ -1000,6 +1004,11 @@ parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) GST_DEBUG("parse PPS"); + /* Variables that don't have inferred values per the H.264 + standard but that should get a default value anyway */ + pps->slice_group_map_type = 0; + pps->slice_group_change_rate_minus1 = 0; + result = gst_h264_parser_parse_pps(priv->parser, &unit->nalu, pps); if (result != GST_H264_PARSER_OK) return get_status(result); @@ -1036,6 +1045,11 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) GST_DEBUG("parse slice"); + /* Variables that don't have inferred values per the H.264 + standard but that should get a default value anyway */ + slice_hdr->cabac_init_idc = 0; + slice_hdr->direct_spatial_mv_pred_flag = 0; + result = gst_h264_parser_parse_slice_hdr(priv->parser, &unit->nalu, slice_hdr, TRUE, TRUE); if (result != GST_H264_PARSER_OK) From 8d2b7241fcdf5fca129d1638d18ce51305d3139c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 7 Jan 2013 10:22:54 +0100 Subject: [PATCH 0982/3781] h264: introduce parser info instead of H.264 specific decoder unit. Use a new GstVaapiParserInfoH264 data structure instead of deriving from GstVaapiDecoderUnit for H.264 specific parser information. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 185 ++++++++++++---------- 1 file changed, 104 insertions(+), 81 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index ac93d1f196..71dc753977 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -42,7 +42,7 @@ typedef struct _GstVaapiFrameStore GstVaapiFrameStore; typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; -typedef struct _GstVaapiDecoderUnitH264 GstVaapiDecoderUnitH264; +typedef struct _GstVaapiParserInfoH264 GstVaapiParserInfoH264; typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; // Used for field_poc[] @@ -50,11 +50,13 @@ typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; #define BOTTOM_FIELD 1 /* ------------------------------------------------------------------------- */ -/* --- H.264 Decoder Units --- */ +/* --- H.264 Parser Info --- */ /* ------------------------------------------------------------------------- */ -struct _GstVaapiDecoderUnitH264 { - GstVaapiDecoderUnit base; +#define GST_VAAPI_PARSER_INFO_H264(obj) \ + ((GstVaapiParserInfoH264 *)(obj)) + +struct _GstVaapiParserInfoH264 { GstH264NalUnit nalu; union { GstH264SPS sps; @@ -63,25 +65,33 @@ struct _GstVaapiDecoderUnitH264 { } data; }; -static GstVaapiDecoderUnitH264 * -gst_vaapi_decoder_unit_h264_new(guint size) +static inline const GstVaapiMiniObjectClass * +gst_vaapi_parser_info_h264_class(void) { - GstVaapiDecoderUnitH264 *unit; - - static const GstVaapiMiniObjectClass GstVaapiDecoderUnitH264Class = { - sizeof(GstVaapiDecoderUnitH264), - (GDestroyNotify)gst_vaapi_decoder_unit_finalize + static const GstVaapiMiniObjectClass GstVaapiParserInfoH264Class = { + sizeof(GstVaapiParserInfoH264), + NULL }; - - unit = (GstVaapiDecoderUnitH264 *) - gst_vaapi_mini_object_new(&GstVaapiDecoderUnitH264Class); - if (!unit) - return NULL; - - gst_vaapi_decoder_unit_init(&unit->base, size); - return unit; + return &GstVaapiParserInfoH264Class; } +static inline GstVaapiParserInfoH264 * +gst_vaapi_parser_info_h264_new(void) +{ + return (GstVaapiParserInfoH264 *) + gst_vaapi_mini_object_new(gst_vaapi_parser_info_h264_class()); +} + +#define gst_vaapi_parser_info_h264_ref(pi) \ + gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pi)) + +#define gst_vaapi_parser_info_h264_unref(pi) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pi)) + +#define gst_vaapi_parser_info_h264_replace(old_pi_ptr, new_pi) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pi_ptr), \ + (GstVaapiMiniObject *)(new_pi)) + /* ------------------------------------------------------------------------- */ /* --- H.264 Pictures --- */ /* ------------------------------------------------------------------------- */ @@ -346,7 +356,7 @@ G_DEFINE_TYPE(GstVaapiDecoderH264, struct _GstVaapiDecoderH264Private { GstH264NalParser *parser; GstVaapiPictureH264 *current_picture; - GstVaapiDecoderUnitH264 *prev_slice_unit; + GstVaapiParserInfoH264 *prev_slice_pi; GstVaapiFrameStore *prev_frame; GstVaapiFrameStore *dpb[16]; guint dpb_count; @@ -691,7 +701,7 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) GstVaapiDecoderH264Private * const priv = decoder->priv; gst_vaapi_picture_replace(&priv->current_picture, NULL); - gst_vaapi_decoder_unit_replace(&priv->prev_slice_unit, NULL); + gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL); dpb_clear(decoder); @@ -975,10 +985,11 @@ error: } static GstVaapiDecoderStatus -parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) +parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264SPS * const sps = &unit->data.sps; + GstVaapiParserInfoH264 * const pi = unit->parsed_info; + GstH264SPS * const sps = &pi->data.sps; GstH264ParserResult result; GST_DEBUG("parse SPS"); @@ -987,7 +998,7 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) standard but that should get a default value anyway */ sps->log2_max_pic_order_cnt_lsb_minus4 = 0; - result = gst_h264_parser_parse_sps(priv->parser, &unit->nalu, sps, TRUE); + result = gst_h264_parser_parse_sps(priv->parser, &pi->nalu, sps, TRUE); if (result != GST_H264_PARSER_OK) return get_status(result); @@ -996,10 +1007,11 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) } static GstVaapiDecoderStatus -parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) +parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264PPS * const pps = &unit->data.pps; + GstVaapiParserInfoH264 * const pi = unit->parsed_info; + GstH264PPS * const pps = &pi->data.pps; GstH264ParserResult result; GST_DEBUG("parse PPS"); @@ -1009,7 +1021,7 @@ parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) pps->slice_group_map_type = 0; pps->slice_group_change_rate_minus1 = 0; - result = gst_h264_parser_parse_pps(priv->parser, &unit->nalu, pps); + result = gst_h264_parser_parse_pps(priv->parser, &pi->nalu, pps); if (result != GST_H264_PARSER_OK) return get_status(result); @@ -1018,16 +1030,17 @@ parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) } static GstVaapiDecoderStatus -parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) +parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstH264SEIMessage sei; GstH264ParserResult result; GST_DEBUG("parse SEI"); memset(&sei, 0, sizeof(sei)); - result = gst_h264_parser_parse_sei(priv->parser, &unit->nalu, &sei); + result = gst_h264_parser_parse_sei(priv->parser, &pi->nalu, &sei); if (result != GST_H264_PARSER_OK) { GST_WARNING("failed to parse SEI, payload type:%d", sei.payloadType); return get_status(result); @@ -1037,10 +1050,11 @@ parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) } static GstVaapiDecoderStatus -parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) +parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; + GstVaapiParserInfoH264 * const pi = unit->parsed_info; + GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstH264ParserResult result; GST_DEBUG("parse slice"); @@ -1050,7 +1064,7 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) slice_hdr->cabac_init_idc = 0; slice_hdr->direct_spatial_mv_pred_flag = 0; - result = gst_h264_parser_parse_slice_hdr(priv->parser, &unit->nalu, + result = gst_h264_parser_parse_slice_hdr(priv->parser, &pi->nalu, slice_hdr, TRUE, TRUE); if (result != GST_H264_PARSER_OK) return get_status(result); @@ -1952,11 +1966,11 @@ init_picture_refs( static gboolean init_picture( GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, GstVaapiDecoderUnitH264 *unit) + GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiPicture * const base_picture = &picture->base; - GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; + GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; priv->prev_frame_num = priv->frame_num; priv->frame_num = slice_hdr->frame_num; @@ -1966,7 +1980,7 @@ init_picture( base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; /* Reset decoder state for IDR pictures */ - if (unit->nalu.type == GST_H264_NAL_SLICE_IDR) { + if (pi->nalu.type == GST_H264_NAL_SLICE_IDR) { GST_DEBUG(""); GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR); dpb_flush(decoder); @@ -2004,7 +2018,7 @@ init_picture( picture->structure = base_picture->structure; /* Initialize reference flags */ - if (unit->nalu.ref_idc) { + if (pi->nalu.ref_idc) { GstH264DecRefPicMarking * const dec_ref_pic_marking = &slice_hdr->dec_ref_pic_marking; @@ -2344,11 +2358,11 @@ vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture, static gboolean fill_picture(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, GstVaapiDecoderUnitH264 *unit) + GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiPicture * const base_picture = &picture->base; - GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; + GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstH264PPS * const pps = picture->pps; GstH264SPS * const sps = pps->sequence; VAPictureParameterBufferH264 * const pic_param = base_picture->param; @@ -2418,17 +2432,16 @@ fill_picture(GstVaapiDecoderH264 *decoder, /* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */ static gboolean -is_new_picture(GstVaapiDecoderUnitH264 *unit, - GstVaapiDecoderUnitH264 *prev_unit) +is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) { - GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; + GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; GstH264SliceHdr *prev_slice_hdr; - if (!prev_unit) + if (!prev_pi) return TRUE; - prev_slice_hdr = &prev_unit->data.slice_hdr; + prev_slice_hdr = &prev_pi->data.slice_hdr; #define CHECK_EXPR(expr, field_name) do { \ if (!(expr)) { \ @@ -2454,8 +2467,8 @@ is_new_picture(GstVaapiDecoderUnitH264 *unit, CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag); /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */ - CHECK_EXPR((unit->nalu.ref_idc != 0) == - (prev_unit->nalu.ref_idc != 0), "nal_ref_idc"); + CHECK_EXPR((pi->nalu.ref_idc != 0) == + (prev_pi->nalu.ref_idc != 0), "nal_ref_idc"); /* POC type is 0 for both and either pic_order_cnt_lsb differs in value or delta_pic_order_cnt_bottom differs in value */ @@ -2473,10 +2486,10 @@ is_new_picture(GstVaapiDecoderUnitH264 *unit, } /* IdrPicFlag differs in value */ - CHECK_VALUE(&unit->nalu, &prev_unit->nalu, idr_pic_flag); + CHECK_VALUE(&pi->nalu, &prev_pi->nalu, idr_pic_flag); /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */ - if (unit->nalu.idr_pic_flag) + if (pi->nalu.idr_pic_flag) CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id); #undef CHECK_EXPR @@ -2485,10 +2498,11 @@ is_new_picture(GstVaapiDecoderUnitH264 *unit, } static GstVaapiDecoderStatus -decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) +decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; - GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; + GstVaapiParserInfoH264 * const pi = unit->parsed_info; + GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; GstVaapiPictureH264 *picture; @@ -2525,9 +2539,9 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) return status; } - if (!init_picture(decoder, picture, unit)) + if (!init_picture(decoder, picture, pi)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - if (!fill_picture(decoder, picture, unit)) + if (!fill_picture(decoder, picture, pi)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2674,15 +2688,15 @@ fill_slice(GstVaapiDecoderH264 *decoder, } static GstVaapiDecoderStatus -decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) +decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstVaapiPictureH264 * const picture = priv->current_picture; - GstH264SliceHdr * const slice_hdr = &unit->data.slice_hdr; - GstH264NalUnit * const nalu = &unit->nalu; + GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstVaapiSlice *slice; - GST_DEBUG("slice (%u bytes)", nalu->size); + GST_DEBUG("slice (%u bytes)", pi->nalu.size); if (!priv->got_sps || !priv->got_pps) { GST_ERROR("not initialized yet"); @@ -2691,7 +2705,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) slice = GST_VAAPI_SLICE_NEW(H264, decoder, (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) + - unit->base.offset + nalu->offset), nalu->size); + unit->offset + pi->nalu.offset), pi->nalu.size); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -2717,11 +2731,12 @@ scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) } static GstVaapiDecoderStatus -decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) +decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { + GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstVaapiDecoderStatus status; - switch (unit->nalu.type) { + switch (pi->nalu.type) { case GST_H264_NAL_SLICE_IDR: /* fall-through. IDR specifics are handled in init_picture() */ case GST_H264_NAL_SLICE: @@ -2734,7 +2749,7 @@ decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnitH264 *unit) status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; default: - GST_WARNING("unsupported NAL unit type %d", unit->nalu.type); + GST_WARNING("unsupported NAL unit type %d", pi->nalu.type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } @@ -2746,12 +2761,15 @@ decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiDecoderStatus status; - GstVaapiDecoderUnitH264 unit; + GstVaapiDecoderUnit unit; + GstVaapiParserInfoH264 pi; GstH264ParserResult result; guchar *buf; guint buf_size; guint i, ofs, num_sps, num_pps; + unit.parsed_info = π + buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); if (!buf || buf_size == 0) @@ -2774,7 +2792,7 @@ decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) result = gst_h264_parser_identify_nalu_avc( priv->parser, buf, ofs, buf_size, 2, - &unit.nalu + &pi.nalu ); if (result != GST_H264_PARSER_OK) return get_status(result); @@ -2782,7 +2800,7 @@ decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) status = parse_sps(decoder, &unit); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - ofs = unit.nalu.offset + unit.nalu.size; + ofs = pi.nalu.offset + pi.nalu.size; } num_pps = buf[ofs]; @@ -2792,7 +2810,7 @@ decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) result = gst_h264_parser_identify_nalu_avc( priv->parser, buf, ofs, buf_size, 2, - &unit.nalu + &pi.nalu ); if (result != GST_H264_PARSER_OK) return get_status(result); @@ -2800,7 +2818,7 @@ decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) status = parse_pps(decoder, &unit); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - ofs = unit.nalu.offset + unit.nalu.size; + ofs = pi.nalu.offset + pi.nalu.size; } priv->is_avcC = TRUE; @@ -2840,7 +2858,8 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, GST_VAAPI_DECODER_H264_CAST(base_decoder); GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); - GstVaapiDecoderUnitH264 *unit; + GstVaapiParserInfoH264 *pi; + GstVaapiDecoderUnit *unit; GstVaapiDecoderStatus status; GstH264ParserResult result; guchar *buf; @@ -2905,23 +2924,29 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, if (!buf) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - unit = gst_vaapi_decoder_unit_h264_new(buf_size); + unit = gst_vaapi_decoder_unit_new(buf_size); if (!unit) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + *unit_ptr = unit; + + pi = gst_vaapi_parser_info_h264_new(); + if (!pi) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + gst_vaapi_decoder_unit_set_parsed_info(unit, + pi, (GDestroyNotify)gst_vaapi_mini_object_unref); if (priv->is_avcC) result = gst_h264_parser_identify_nalu_avc(priv->parser, - buf, 0, buf_size, priv->nal_length_size, &unit->nalu); + buf, 0, buf_size, priv->nal_length_size, &pi->nalu); else result = gst_h264_parser_identify_nalu_unchecked(priv->parser, - buf, 0, buf_size, &unit->nalu); + buf, 0, buf_size, &pi->nalu); status = get_status(result); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - gst_vaapi_decoder_unit_unref(unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - } - switch (unit->nalu.type) { + switch (pi->nalu.type) { case GST_H264_NAL_SPS: status = parse_sps(decoder, unit); break; @@ -2943,7 +2968,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, return status; flags = 0; - switch (unit->nalu.type) { + switch (pi->nalu.type) { case GST_H264_NAL_AU_DELIMITER: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; /* fall-through */ @@ -2966,19 +2991,18 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, case GST_H264_NAL_SLICE_IDR: case GST_H264_NAL_SLICE: flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; - if (is_new_picture(unit, priv->prev_slice_unit)) + if (is_new_picture(pi, priv->prev_slice_pi)) flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - gst_vaapi_decoder_unit_replace(&priv->prev_slice_unit, unit); + gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, pi); break; default: - if (unit->nalu.type >= 14 && unit->nalu.type <= 18) + if (pi->nalu.type >= 14 && pi->nalu.type <= 18) flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; } GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); - unit->nalu.data = NULL; - *unit_ptr = &unit->base; + pi->nalu.data = NULL; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2993,16 +3017,15 @@ gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base_decoder, status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - return decode_unit(decoder, (GstVaapiDecoderUnitH264 *)unit); + return decode_unit(decoder, unit); } static GstVaapiDecoderStatus gst_vaapi_decoder_h264_start_frame(GstVaapiDecoder *base_decoder, - GstVaapiDecoderUnit *base_unit) + GstVaapiDecoderUnit *unit) { GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(base_decoder); - GstVaapiDecoderUnitH264 * const unit = (GstVaapiDecoderUnitH264 *)base_unit; return decode_picture(decoder, unit); } From 78e9a78de8d62e98c05c7cf988a79fc81016bcc0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 7 Jan 2013 10:48:27 +0100 Subject: [PATCH 0983/3781] mpeg2: introduce parser info instead of MPEG-2 specific decoder unit. Use a new GstVaapiParserInfoMpeg2 data structure instead of deriving from GstVaapiDecoderUnit for MPEG-2 specific parser information. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 254 ++++++++++++--------- 1 file changed, 140 insertions(+), 114 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 541e01269b..59ecdcb6c4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -242,7 +242,7 @@ pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn) } /* ------------------------------------------------------------------------- */ -/* --- MPEG-2 Decoder Units --- */ +/* --- MPEG-2 Parser Info --- */ /* ------------------------------------------------------------------------- */ typedef struct _GstMpegVideoSliceHdr GstMpegVideoSliceHdr; @@ -256,11 +256,10 @@ struct _GstMpegVideoSliceHdr { guint header_size; }; -typedef struct _GstVaapiDecoderUnitMpeg2 GstVaapiDecoderUnitMpeg2; -struct _GstVaapiDecoderUnitMpeg2 { - GstVaapiDecoderUnit base; - GstMpegVideoPacket packet; - guint8 extension_type; /* for Extension packets */ +typedef struct _GstVaapiParserInfoMpeg2 GstVaapiParserInfoMpeg2; +struct _GstVaapiParserInfoMpeg2 { + GstMpegVideoPacket packet; + guint8 extension_type; /* for Extension packets */ union { GstMpegVideoSequenceHdr seq_hdr; GstMpegVideoSequenceExt seq_ext; @@ -273,25 +272,33 @@ struct _GstVaapiDecoderUnitMpeg2 { } data; }; -static GstVaapiDecoderUnitMpeg2 * -gst_vaapi_decoder_unit_mpeg2_new(guint size) +static inline const GstVaapiMiniObjectClass * +gst_vaapi_parser_info_mpeg2_class(void) { - GstVaapiDecoderUnitMpeg2 *unit; - - static const GstVaapiMiniObjectClass GstVaapiDecoderUnitMpeg2Class = { - sizeof(GstVaapiDecoderUnitMpeg2), - (GDestroyNotify)gst_vaapi_decoder_unit_finalize + static const GstVaapiMiniObjectClass GstVaapiParserInfoMpeg2Class = { + sizeof(GstVaapiParserInfoMpeg2), + NULL }; - - unit = (GstVaapiDecoderUnitMpeg2 *) - gst_vaapi_mini_object_new(&GstVaapiDecoderUnitMpeg2Class); - if (!unit) - return NULL; - - gst_vaapi_decoder_unit_init(&unit->base, size); - return unit; + return &GstVaapiParserInfoMpeg2Class; } +static inline GstVaapiParserInfoMpeg2 * +gst_vaapi_parser_info_mpeg2_new(void) +{ + return (GstVaapiParserInfoMpeg2 *) + gst_vaapi_mini_object_new(gst_vaapi_parser_info_mpeg2_class()); +} + +#define gst_vaapi_parser_info_mpeg2_ref(pi) \ + gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pi)) + +#define gst_vaapi_parser_info_mpeg2_unref(pi) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pi)) + +#define gst_vaapi_parser_info_mpeg2_replace(old_pi_ptr, new_pi) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pi_ptr), \ + (GstVaapiMiniObject *)(new_pi)) + /* ------------------------------------------------------------------------- */ /* --- MPEG-2 Decoder --- */ /* ------------------------------------------------------------------------- */ @@ -315,13 +322,13 @@ struct _GstVaapiDecoderMpeg2Private { guint height; guint fps_n; guint fps_d; - GstVaapiDecoderUnitMpeg2 *seq_hdr_unit; - GstVaapiDecoderUnitMpeg2 *seq_ext_unit; - GstVaapiDecoderUnitMpeg2 *seq_display_ext_unit; - GstVaapiDecoderUnitMpeg2 *seq_scalable_ext_unit; - GstVaapiDecoderUnitMpeg2 *pic_hdr_unit; - GstVaapiDecoderUnitMpeg2 *pic_ext_unit; - GstVaapiDecoderUnitMpeg2 *quant_matrix_unit; + GstVaapiParserInfoMpeg2 *seq_hdr; + GstVaapiParserInfoMpeg2 *seq_ext; + GstVaapiParserInfoMpeg2 *seq_display_ext; + GstVaapiParserInfoMpeg2 *seq_scalable_ext; + GstVaapiParserInfoMpeg2 *pic_hdr; + GstVaapiParserInfoMpeg2 *pic_ext; + GstVaapiParserInfoMpeg2 *quant_matrix; GstVaapiPicture *current_picture; GstVaapiDpb *dpb; PTSGenerator tsg; @@ -342,13 +349,13 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) gst_vaapi_picture_replace(&priv->current_picture, NULL); - gst_vaapi_decoder_unit_replace(&priv->seq_hdr_unit, NULL); - gst_vaapi_decoder_unit_replace(&priv->seq_ext_unit, NULL); - gst_vaapi_decoder_unit_replace(&priv->seq_display_ext_unit, NULL); - gst_vaapi_decoder_unit_replace(&priv->seq_scalable_ext_unit, NULL); - gst_vaapi_decoder_unit_replace(&priv->pic_hdr_unit, NULL); - gst_vaapi_decoder_unit_replace(&priv->pic_ext_unit, NULL); - gst_vaapi_decoder_unit_replace(&priv->quant_matrix_unit, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->seq_hdr, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->seq_scalable_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->pic_hdr, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, NULL); if (priv->dpb) { gst_vaapi_dpb_unref(priv->dpb); @@ -428,9 +435,9 @@ get_profile(GstVaapiDecoderMpeg2 *decoder, GstVaapiEntrypoint entrypoint) case GST_VAAPI_PROFILE_MPEG2_HIGH: // Try to map to main profile if no high profile specific bits used if (priv->profile == profile && - !priv->seq_scalable_ext_unit && - (priv->seq_ext_unit && - priv->seq_ext_unit->data.seq_ext.chroma_format == 1)) { + !priv->seq_scalable_ext && + (priv->seq_ext && + priv->seq_ext->data.seq_ext.chroma_format == 1)) { profile = GST_VAAPI_PROFILE_MPEG2_MAIN; break; } @@ -492,7 +499,7 @@ static GstVaapiDecoderStatus ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr_unit->data.seq_hdr; + GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr->data.seq_hdr; VAIQMatrixBufferMPEG2 *iq_matrix; guint8 *intra_quant_matrix = NULL; guint8 *non_intra_quant_matrix = NULL; @@ -514,9 +521,9 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) intra_quant_matrix = seq_hdr->intra_quantizer_matrix; non_intra_quant_matrix = seq_hdr->non_intra_quantizer_matrix; - if (priv->quant_matrix_unit) { + if (priv->quant_matrix) { GstMpegVideoQuantMatrixExt * const quant_matrix = - &priv->quant_matrix_unit->data.quant_matrix; + &priv->quant_matrix->data.quant_matrix; if (quant_matrix->load_intra_quantiser_matrix) intra_quant_matrix = quant_matrix->intra_quantiser_matrix; if (quant_matrix->load_non_intra_quantiser_matrix) @@ -574,11 +581,12 @@ error: } static GstVaapiDecoderStatus -parse_sequence(GstVaapiDecoderUnitMpeg2 *unit) +parse_sequence(GstVaapiDecoderUnit *unit) { - GstMpegVideoPacket * const packet = &unit->packet; + GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; + GstMpegVideoPacket * const packet = &pi->packet; - if (!gst_mpeg_video_parse_sequence_header(&unit->data.seq_hdr, + if (!gst_mpeg_video_parse_sequence_header(&pi->data.seq_hdr, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse sequence header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; @@ -587,16 +595,16 @@ parse_sequence(GstVaapiDecoderUnitMpeg2 *unit) } static GstVaapiDecoderStatus -decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) +decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoSequenceHdr *seq_hdr; - gst_vaapi_decoder_unit_replace(&priv->seq_hdr_unit, unit); - seq_hdr = &priv->seq_hdr_unit->data.seq_hdr; - gst_vaapi_decoder_unit_replace(&priv->seq_ext_unit, NULL); - gst_vaapi_decoder_unit_replace(&priv->seq_display_ext_unit, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->seq_hdr, unit->parsed_info); + seq_hdr = &priv->seq_hdr->data.seq_hdr; + gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, NULL); priv->fps_n = seq_hdr->fps_n; priv->fps_d = seq_hdr->fps_d; @@ -612,11 +620,12 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) } static GstVaapiDecoderStatus -parse_sequence_ext(GstVaapiDecoderUnitMpeg2 *unit) +parse_sequence_ext(GstVaapiDecoderUnit *unit) { - GstMpegVideoPacket * const packet = &unit->packet; + GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; + GstMpegVideoPacket * const packet = &pi->packet; - if (!gst_mpeg_video_parse_sequence_extension(&unit->data.seq_ext, + if (!gst_mpeg_video_parse_sequence_extension(&pi->data.seq_ext, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse sequence-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; @@ -626,7 +635,7 @@ parse_sequence_ext(GstVaapiDecoderUnitMpeg2 *unit) static GstVaapiDecoderStatus decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnitMpeg2 *unit) + GstVaapiDecoderUnit *unit) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; @@ -634,8 +643,8 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiProfile profile; guint width, height; - gst_vaapi_decoder_unit_replace(&priv->seq_ext_unit, unit); - seq_ext = &priv->seq_ext_unit->data.seq_ext; + gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, unit->parsed_info); + seq_ext = &priv->seq_ext->data.seq_ext; priv->progressive_sequence = seq_ext->progressive; gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence); @@ -683,12 +692,13 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, } static GstVaapiDecoderStatus -parse_sequence_display_ext(GstVaapiDecoderUnitMpeg2 *unit) +parse_sequence_display_ext(GstVaapiDecoderUnit *unit) { - GstMpegVideoPacket * const packet = &unit->packet; + GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; + GstMpegVideoPacket * const packet = &pi->packet; if (!gst_mpeg_video_parse_sequence_display_extension( - &unit->data.seq_display_ext, + &pi->data.seq_display_ext, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse sequence-display-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; @@ -698,11 +708,12 @@ parse_sequence_display_ext(GstVaapiDecoderUnitMpeg2 *unit) static GstVaapiDecoderStatus decode_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnitMpeg2 *unit) + GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - gst_vaapi_decoder_unit_replace(&priv->seq_display_ext_unit, unit); + gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, + unit->parsed_info); /* XXX: handle color primaries and cropping */ return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -723,11 +734,12 @@ decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) } static GstVaapiDecoderStatus -parse_quant_matrix_ext(GstVaapiDecoderUnitMpeg2 *unit) +parse_quant_matrix_ext(GstVaapiDecoderUnit *unit) { - GstMpegVideoPacket * const packet = &unit->packet; + GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; + GstMpegVideoPacket * const packet = &pi->packet; - if (!gst_mpeg_video_parse_quant_matrix_extension(&unit->data.quant_matrix, + if (!gst_mpeg_video_parse_quant_matrix_extension(&pi->data.quant_matrix, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse quant-matrix-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; @@ -737,21 +749,22 @@ parse_quant_matrix_ext(GstVaapiDecoderUnitMpeg2 *unit) static GstVaapiDecoderStatus decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnitMpeg2 *unit) + GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - gst_vaapi_decoder_unit_replace(&priv->quant_matrix_unit, unit); + gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, unit->parsed_info); priv->quant_matrix_changed = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_gop(GstVaapiDecoderUnitMpeg2 *unit) +parse_gop(GstVaapiDecoderUnit *unit) { - GstMpegVideoPacket * const packet = &unit->packet; + GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; + GstMpegVideoPacket * const packet = &pi->packet; - if (!gst_mpeg_video_parse_gop(&unit->data.gop, + if (!gst_mpeg_video_parse_gop(&pi->data.gop, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse GOP"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; @@ -760,10 +773,11 @@ parse_gop(GstVaapiDecoderUnitMpeg2 *unit) } static GstVaapiDecoderStatus -decode_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) +decode_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoGop * const gop = &unit->data.gop; + GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; + GstMpegVideoGop * const gop = &pi->data.gop; priv->closed_gop = gop->closed_gop; priv->broken_link = gop->broken_link; @@ -777,11 +791,12 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) } static GstVaapiDecoderStatus -parse_picture(GstVaapiDecoderUnitMpeg2 *unit) +parse_picture(GstVaapiDecoderUnit *unit) { - GstMpegVideoPacket * const packet = &unit->packet; + GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; + GstMpegVideoPacket * const packet = &pi->packet; - if (!gst_mpeg_video_parse_picture_header(&unit->data.pic_hdr, + if (!gst_mpeg_video_parse_picture_header(&pi->data.pic_hdr, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse picture header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; @@ -790,11 +805,12 @@ parse_picture(GstVaapiDecoderUnitMpeg2 *unit) } static GstVaapiDecoderStatus -parse_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) +parse_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoSliceHdr * const slice_hdr = &unit->data.slice_hdr; - GstMpegVideoPacket * const packet = &unit->packet; + GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; + GstMpegVideoSliceHdr * const slice_hdr = &pi->data.slice_hdr; + GstMpegVideoPacket * const packet = &pi->packet; GstBitReader br; gint mb_x, mb_y, mb_inc; guint8 slice_vertical_position_extension; @@ -803,7 +819,7 @@ parse_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) gst_bit_reader_init(&br, packet->data + packet->offset, packet->size); if (priv->height > 2800) READ_UINT8(&br, slice_vertical_position_extension, 3); - if (priv->seq_scalable_ext_unit) { + if (priv->seq_scalable_ext) { GST_ERROR("failed to parse slice with sequence_scalable_extension()"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -842,21 +858,22 @@ failed: } static GstVaapiDecoderStatus -decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) +decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - gst_vaapi_decoder_unit_replace(&priv->pic_hdr_unit, unit); - gst_vaapi_decoder_unit_replace(&priv->pic_ext_unit, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->pic_hdr, unit->parsed_info); + gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_picture_ext(GstVaapiDecoderUnitMpeg2 *unit) +parse_picture_ext(GstVaapiDecoderUnit *unit) { - GstMpegVideoPacket * const packet = &unit->packet; + GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; + GstMpegVideoPacket * const packet = &pi->packet; - if (!gst_mpeg_video_parse_picture_extension(&unit->data.pic_ext, + if (!gst_mpeg_video_parse_picture_extension(&pi->data.pic_ext, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse picture-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; @@ -866,13 +883,13 @@ parse_picture_ext(GstVaapiDecoderUnitMpeg2 *unit) static GstVaapiDecoderStatus decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnitMpeg2 *unit) + GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoPictureExt *pic_ext; - gst_vaapi_decoder_unit_replace(&priv->pic_ext_unit, unit); - pic_ext = &priv->pic_ext_unit->data.pic_ext; + gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, unit->parsed_info); + pic_ext = &priv->pic_ext->data.pic_ext; if (priv->progressive_sequence && !pic_ext->progressive_frame) { GST_WARNING("invalid interlaced frame in progressive sequence, fixing"); @@ -902,8 +919,8 @@ static GstVaapiDecoderStatus init_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr_unit->data.pic_hdr; - GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext_unit->data.pic_ext; + GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr->data.pic_hdr; + GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext->data.pic_ext; switch (pic_hdr->pic_type) { case GST_MPEG_VIDEO_PICTURE_TYPE_I: @@ -985,8 +1002,8 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; VAPictureParameterBufferMPEG2 * const pic_param = picture->param; - GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr_unit->data.pic_hdr; - GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext_unit->data.pic_ext; + GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr->data.pic_hdr; + GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext->data.pic_ext; GstVaapiPicture *prev_picture, *next_picture; /* Fill in VAPictureParameterBufferMPEG2 */ @@ -1033,20 +1050,21 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) } static GstVaapiDecoderStatus -decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) +decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; GstVaapiPicture * const picture = priv->current_picture; GstVaapiSlice *slice; VASliceParameterBufferMPEG2 *slice_param; - GstMpegVideoSliceHdr * const slice_hdr = &unit->data.slice_hdr; + GstMpegVideoSliceHdr * const slice_hdr = &pi->data.slice_hdr; GST_DEBUG("slice %d (%u bytes)", slice_hdr->slice_vertical_position, - unit->base.size); + unit->size); slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) + - unit->base.offset), unit->base.size); + unit->offset), unit->size); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -1073,13 +1091,13 @@ scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) } static GstVaapiDecoderStatus -decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) +decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - const GstMpegVideoPacketTypeCode type = unit->packet.type; + GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; GstVaapiDecoderStatus status; - switch (type) { + switch (pi->packet.type) { case GST_MPEG_VIDEO_PACKET_PICTURE: if (!priv->width || !priv->height) goto unknown_picture_size; @@ -1089,7 +1107,7 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) status = decode_sequence(decoder, unit); break; case GST_MPEG_VIDEO_PACKET_EXTENSION: - switch (unit->extension_type) { + switch (pi->extension_type) { case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: status = decode_sequence_ext(decoder, unit); break; @@ -1107,7 +1125,7 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) default: // Ignore unknown start-code extensions GST_WARNING("unsupported packet extension type 0x%02x", - unit->extension_type); + pi->extension_type); status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; } @@ -1119,12 +1137,12 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit) status = decode_gop(decoder, unit); break; default: - if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && - type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { + if (pi->packet.type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + pi->packet.type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { status = decode_slice(decoder, unit); break; } - GST_WARNING("unsupported packet type 0x%02x", type); + GST_WARNING("unsupported packet type 0x%02x", pi->packet.type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } @@ -1160,7 +1178,8 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); - GstVaapiDecoderUnitMpeg2 *unit; + GstVaapiParserInfoMpeg2 *pi; + GstVaapiDecoderUnit *unit; GstVaapiDecoderStatus status; GstMpegVideoPacket *packet; const guchar *buf; @@ -1206,11 +1225,19 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, if (!buf) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - unit = gst_vaapi_decoder_unit_mpeg2_new(buf_size); + unit = gst_vaapi_decoder_unit_new(buf_size); if (!unit) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + *unit_ptr = unit; - packet = &unit->packet; + pi = gst_vaapi_parser_info_mpeg2_new(); + if (!pi) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + gst_vaapi_decoder_unit_set_parsed_info(unit, + pi, (GDestroyNotify)gst_vaapi_mini_object_unref); + + packet = &pi->packet; packet->data = buf; packet->size = buf_size; packet->offset = 4; @@ -1232,8 +1259,8 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } - unit->extension_type = buf[4] >> 4; - switch (unit->extension_type) { + pi->extension_type = buf[4] >> 4; + switch (pi->extension_type) { case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: status = parse_sequence_ext(unit); break; @@ -1291,8 +1318,7 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, } GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); - unit->packet.data = NULL; - *unit_ptr = &unit->base; + pi->packet.data = NULL; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1307,7 +1333,7 @@ gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base_decoder, status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - return decode_unit(decoder, (GstVaapiDecoderUnitMpeg2 *)unit); + return decode_unit(decoder, unit); } static GstVaapiDecoderStatus @@ -1330,10 +1356,10 @@ gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; } - seq_hdr = &priv->seq_hdr_unit->data.seq_hdr; - seq_ext = priv->seq_ext_unit ? &priv->seq_ext_unit->data.seq_ext : NULL; - seq_display_ext = priv->seq_display_ext_unit ? - &priv->seq_display_ext_unit->data.seq_display_ext : NULL; + seq_hdr = &priv->seq_hdr->data.seq_hdr; + seq_ext = priv->seq_ext ? &priv->seq_ext->data.seq_ext : NULL; + seq_display_ext = priv->seq_display_ext ? + &priv->seq_display_ext->data.seq_display_ext : NULL; if (gst_mpeg_video_finalise_mpeg2_sequence_header(seq_hdr, seq_ext, seq_display_ext)) gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, From 2c449e42cae859e823718d020ca4a3a009d7c0ee Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 7 Jan 2013 11:13:07 +0100 Subject: [PATCH 0984/3781] decoder: refactor decoder unit API. Allocate decoder unit earlier in the main parse() function and don't delegate this task to derived classes. The ultimate purpose is to get rid of dynamic allocation of decoder units. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 6 +++++- gst-libs/gst/vaapi/gstvaapidecoder.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 8 ++------ gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 9 ++------- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 8 ++------ gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 11 ++--------- gst-libs/gst/vaapi/gstvaapidecoder_unit.c | 22 +++++++++++----------- gst-libs/gst/vaapi/gstvaapidecoder_unit.h | 6 +++--- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 9 ++------- 9 files changed, 30 insertions(+), 51 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 222726b4d7..9f46bc7f3c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -170,9 +170,13 @@ do_parse(GstVaapiDecoder *decoder, if (unit) goto got_unit; + unit = gst_vaapi_decoder_unit_new(); + if (!unit) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + ps->current_frame = base_frame; status = GST_VAAPI_DECODER_GET_CLASS(decoder)->parse(decoder, - adapter, at_eos, &unit); + adapter, at_eos, unit); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { if (unit) gst_vaapi_decoder_unit_unref(unit); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 88a0c1f26d..050992ce52 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -117,7 +117,7 @@ struct _GstVaapiDecoderClass { GstVaapiDecoderStatus (*parse)(GstVaapiDecoder *decoder, GstAdapter *adapter, gboolean at_eos, - struct _GstVaapiDecoderUnit **unit_ptr); + struct _GstVaapiDecoderUnit *unit); GstVaapiDecoderStatus (*decode)(GstVaapiDecoder *decoder, struct _GstVaapiDecoderUnit *unit); GstVaapiDecoderStatus (*start_frame)(GstVaapiDecoder *decoder, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 71dc753977..2c5a8978b8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2852,14 +2852,13 @@ ensure_decoder(GstVaapiDecoderH264 *decoder) static GstVaapiDecoderStatus gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, - GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) + GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) { GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(base_decoder); GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiParserInfoH264 *pi; - GstVaapiDecoderUnit *unit; GstVaapiDecoderStatus status; GstH264ParserResult result; guchar *buf; @@ -2924,10 +2923,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, if (!buf) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - unit = gst_vaapi_decoder_unit_new(buf_size); - if (!unit) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - *unit_ptr = unit; + unit->size = buf_size; pi = gst_vaapi_parser_info_h264_new(); if (!pi) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 936ba10d02..22161c3e0f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -634,11 +634,10 @@ scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) static GstVaapiDecoderStatus gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder, - GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) + GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) { GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(base_decoder); GstVaapiDecoderStatus status; - GstVaapiDecoderUnit *unit; guint size, buf_size, flags = 0; gint ofs; @@ -667,16 +666,12 @@ gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder, } buf_size = ofs; - unit = gst_vaapi_decoder_unit_new(buf_size); - if (!unit) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + unit->size = buf_size; flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); - - *unit_ptr = unit; return GST_VAAPI_DECODER_STATUS_SUCCESS; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 59ecdcb6c4..f9944d6b9b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1173,13 +1173,12 @@ ensure_decoder(GstVaapiDecoderMpeg2 *decoder) static GstVaapiDecoderStatus gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, - GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) + GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiParserInfoMpeg2 *pi; - GstVaapiDecoderUnit *unit; GstVaapiDecoderStatus status; GstMpegVideoPacket *packet; const guchar *buf; @@ -1225,10 +1224,7 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, if (!buf) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - unit = gst_vaapi_decoder_unit_new(buf_size); - if (!unit) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - *unit_ptr = unit; + unit->size = buf_size; pi = gst_vaapi_parser_info_mpeg2_new(); if (!pi) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index fae5a99f97..49754b3cb0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -991,12 +991,11 @@ ensure_decoder(GstVaapiDecoderMpeg4 *decoder) static GstVaapiDecoderStatus gst_vaapi_decoder_mpeg4_parse(GstVaapiDecoder *base_decoder, - GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) + GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4(base_decoder); GstVaapiDecoderMpeg4Private * const priv = decoder->priv; - GstVaapiDecoderUnit *unit = NULL; GstVaapiDecoderStatus status; GstMpeg4Packet packet; GstMpeg4ParseResult result; @@ -1025,6 +1024,7 @@ gst_vaapi_decoder_mpeg4_parse(GstVaapiDecoder *base_decoder, buf_size = packet.size; gst_adapter_flush(adapter, packet.offset); + unit->size = buf_size; /* Check for start of new picture */ switch (packet.type) { @@ -1075,14 +1075,7 @@ gst_vaapi_decoder_mpeg4_parse(GstVaapiDecoder *base_decoder, GST_WARNING("unsupported start code (0x%02x)", packet.type); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } - - unit = gst_vaapi_decoder_unit_new(buf_size); - if (!unit) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); - - *unit_ptr = unit; return GST_VAAPI_DECODER_STATUS_SUCCESS; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c index 4b2648e780..c169958d80 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c @@ -32,7 +32,7 @@ gst_vaapi_decoder_unit_class(void) { static const GstVaapiMiniObjectClass GstVaapiDecoderUnitClass = { sizeof(GstVaapiDecoderUnit), - (GDestroyNotify)gst_vaapi_decoder_unit_finalize + (GDestroyNotify)gst_vaapi_decoder_unit_clear }; return &GstVaapiDecoderUnitClass; } @@ -47,9 +47,9 @@ gst_vaapi_decoder_unit_class(void) * sub-classes. */ static inline void -decoder_unit_init(GstVaapiDecoderUnit *unit, guint size) +decoder_unit_init(GstVaapiDecoderUnit *unit) { - unit->size = size; + unit->size = 0; unit->offset = 0; unit->buffer = NULL; @@ -58,13 +58,13 @@ decoder_unit_init(GstVaapiDecoderUnit *unit, guint size) } void -gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit, guint size) +gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit) { - decoder_unit_init(unit, size); + decoder_unit_init(unit); } /** - * gst_vaapi_decoder_unit_finalize: + * gst_vaapi_decoder_unit_clear: * @unit: a #GstVaapiDecoderUnit * * Deallocates any internal resources bound to the supplied decoder @@ -74,16 +74,16 @@ gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit, guint size) * sub-classes. */ static inline void -decoder_unit_finalize(GstVaapiDecoderUnit *unit) +decoder_unit_clear(GstVaapiDecoderUnit *unit) { gst_buffer_replace(&unit->buffer, NULL); gst_vaapi_decoder_unit_set_parsed_info(unit, NULL, NULL); } void -gst_vaapi_decoder_unit_finalize(GstVaapiDecoderUnit *unit) +gst_vaapi_decoder_unit_clear(GstVaapiDecoderUnit *unit) { - decoder_unit_finalize(unit); + decoder_unit_clear(unit); } /** @@ -95,7 +95,7 @@ gst_vaapi_decoder_unit_finalize(GstVaapiDecoderUnit *unit) * Returns: The newly allocated #GstVaapiDecoderUnit */ GstVaapiDecoderUnit * -gst_vaapi_decoder_unit_new(guint size) +gst_vaapi_decoder_unit_new(void) { GstVaapiDecoderUnit *unit; @@ -104,7 +104,7 @@ gst_vaapi_decoder_unit_new(guint size) if (!unit) return NULL; - decoder_unit_init(unit, size); + decoder_unit_init(unit); return unit; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h index 70742e25ce..9842afb8a6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h @@ -141,15 +141,15 @@ struct _GstVaapiDecoderUnit { G_GNUC_INTERNAL void -gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit, guint size); +gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit); G_GNUC_INTERNAL void -gst_vaapi_decoder_unit_finalize(GstVaapiDecoderUnit *unit); +gst_vaapi_decoder_unit_clear(GstVaapiDecoderUnit *unit); G_GNUC_INTERNAL GstVaapiDecoderUnit * -gst_vaapi_decoder_unit_new(guint size); +gst_vaapi_decoder_unit_new(void); G_GNUC_INTERNAL void diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index b8b86cf0c2..2cc33ccc17 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1163,12 +1163,11 @@ scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) static GstVaapiDecoderStatus gst_vaapi_decoder_vc1_parse(GstVaapiDecoder *base_decoder, - GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit **unit_ptr) + GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) { GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVaapiDecoderStatus status; - GstVaapiDecoderUnit *unit; guint8 bdu_type; guint size, buf_size, flags = 0; gint ofs; @@ -1208,9 +1207,7 @@ gst_vaapi_decoder_vc1_parse(GstVaapiDecoder *base_decoder, gst_adapter_copy(adapter, &bdu_type, 3, 1); } - unit = gst_vaapi_decoder_unit_new(buf_size); - if (!unit) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + unit->size = buf_size; /* Check for new picture layer */ switch (bdu_type) { @@ -1231,8 +1228,6 @@ gst_vaapi_decoder_vc1_parse(GstVaapiDecoder *base_decoder, break; } GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); - - *unit_ptr = unit; return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 4fd99cc989acf8ee43a709a2c10cd41448ce3d38 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 7 Jan 2013 13:41:59 +0100 Subject: [PATCH 0985/3781] decoder: use an array of units instead of a single-linked list. Use a GArray to hold decoder units in a frame, instead of a single-linked list. This makes 'append' calls faster, but not that much. At least, this makes things clearer. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 111 +++++++++------------ gst-libs/gst/vaapi/gstvaapidecoder_frame.c | 70 +++++++++++-- gst-libs/gst/vaapi/gstvaapidecoder_frame.h | 11 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 13 +-- gst-libs/gst/vaapi/gstvaapidecoder_unit.c | 2 + 5 files changed, 128 insertions(+), 79 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 9f46bc7f3c..7a5cf0501b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -62,6 +62,11 @@ parser_state_finalize(GstVaapiParserState *ps) g_object_unref(ps->output_adapter); ps->output_adapter = NULL; } + + if (ps->next_unit_pending) { + gst_vaapi_decoder_unit_clear(&ps->next_unit); + ps->next_unit_pending = FALSE; + } } static gboolean @@ -77,22 +82,6 @@ parser_state_init(GstVaapiParserState *ps) return TRUE; } -static inline GstVaapiDecoderUnit * -parser_state_get_pending_unit(GstVaapiParserState *ps, GstAdapter *adapter) -{ - GstVaapiDecoderUnit * const unit = ps->pending_unit; - - ps->pending_unit = NULL; - return unit; -} - -static inline void -parser_state_set_pending_unit(GstVaapiParserState *ps, - GstAdapter *adapter, GstVaapiDecoderUnit *unit) -{ - ps->pending_unit = unit; -} - static void parser_state_prepare(GstVaapiParserState *ps, GstAdapter *adapter) { @@ -150,7 +139,6 @@ do_parse(GstVaapiDecoder *decoder, GstVaapiDecoderFrame *frame; GstVaapiDecoderUnit *unit; GstVaapiDecoderStatus status; - GSList **unit_list_ptr; *got_unit_size_ptr = 0; *got_frame_ptr = FALSE; @@ -166,60 +154,42 @@ do_parse(GstVaapiDecoder *decoder, parser_state_prepare(ps, adapter); - unit = parser_state_get_pending_unit(ps, adapter); - if (unit) + unit = &ps->next_unit; + if (ps->next_unit_pending) { + ps->next_unit_pending = FALSE; goto got_unit; - - unit = gst_vaapi_decoder_unit_new(); - if (!unit) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + gst_vaapi_decoder_unit_init(unit); ps->current_frame = base_frame; status = GST_VAAPI_DECODER_GET_CLASS(decoder)->parse(decoder, adapter, at_eos, unit); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - if (unit) - gst_vaapi_decoder_unit_unref(unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - } - if (GST_VAAPI_DECODER_UNIT_IS_FRAME_START(unit) && frame->units) { - parser_state_set_pending_unit(ps, adapter, unit); - goto got_frame; + if (GST_VAAPI_DECODER_UNIT_IS_FRAME_START(unit) && frame->units->len > 0) { + ps->next_unit_pending = TRUE; + *got_frame_ptr = TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } got_unit: - unit->offset = frame->output_offset; - frame->output_offset += unit->size; - - if (GST_VAAPI_DECODER_UNIT_IS_SLICE(unit)) - unit_list_ptr = &frame->units; - else if (GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit)) - unit_list_ptr = &frame->post_units; - else - unit_list_ptr = &frame->pre_units; - *unit_list_ptr = g_slist_prepend(*unit_list_ptr, unit); - + gst_vaapi_decoder_frame_append_unit(frame, unit); *got_unit_size_ptr = unit->size; - if (GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit)) { - got_frame: - frame->units = g_slist_reverse(frame->units); - frame->pre_units = g_slist_reverse(frame->pre_units); - frame->post_units = g_slist_reverse(frame->post_units); - *got_frame_ptr = TRUE; - } + *got_frame_ptr = GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit); return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -do_decode_list(GstVaapiDecoder *decoder, GSList *units) +do_decode_units(GstVaapiDecoder *decoder, GArray *units) { GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); GstVaapiDecoderStatus status; - GSList *l; + guint i; - for (l = units; l != NULL; l = l->next) { - GstVaapiDecoderUnit * const unit = l->data; + for (i = 0; i < units->len; i++) { + GstVaapiDecoderUnit * const unit = + &g_array_index(units, GstVaapiDecoderUnit, i); if (GST_VAAPI_DECODER_UNIT_IS_SKIPPED(unit)) continue; status = klass->decode(decoder, unit); @@ -230,29 +200,27 @@ do_decode_list(GstVaapiDecoder *decoder, GSList *units) } static GstVaapiDecoderStatus -do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) +do_decode_1(GstVaapiDecoder *decoder, GstVaapiDecoderFrame *frame) { GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); - GstVaapiParserState * const ps = &decoder->priv->parser_state; - GstVaapiDecoderFrame * const frame = base_frame->user_data; GstVaapiDecoderStatus status; - ps->current_frame = base_frame; - - if (frame->pre_units) { - status = do_decode_list(decoder, frame->pre_units); + if (frame->pre_units->len > 0) { + status = do_decode_units(decoder, frame->pre_units); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; } - if (frame->units) { + if (frame->units->len > 0) { if (klass->start_frame) { - status = klass->start_frame(decoder, frame->units->data); + GstVaapiDecoderUnit * const unit = + &g_array_index(frame->units, GstVaapiDecoderUnit, 0); + status = klass->start_frame(decoder, unit); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; } - status = do_decode_list(decoder, frame->units); + status = do_decode_units(decoder, frame->units); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; @@ -263,14 +231,29 @@ do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) } } - if (frame->post_units) { - status = do_decode_list(decoder, frame->post_units); + if (frame->post_units->len > 0) { + status = do_decode_units(decoder, frame->post_units); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; } return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static inline GstVaapiDecoderStatus +do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) +{ + GstVaapiParserState * const ps = &decoder->priv->parser_state; + GstVaapiDecoderFrame * const frame = base_frame->user_data; + GstVaapiDecoderStatus status; + + ps->current_frame = base_frame; + + gst_vaapi_decoder_frame_ref(frame); + status = do_decode_1(decoder, frame); + gst_vaapi_decoder_frame_unref(frame); + return status; +} + static GstVaapiDecoderStatus decode_step(GstVaapiDecoder *decoder) { diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.c b/gst-libs/gst/vaapi/gstvaapidecoder_frame.c index cde29ce46b..4c1c178cee 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_frame.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_frame.c @@ -37,13 +37,29 @@ gst_vaapi_decoder_frame_class(void) return &GstVaapiDecoderFrameClass; } -static inline void -free_units(GSList **units_ptr) +static inline gboolean +alloc_units(GArray **units_ptr, guint size) { - GSList * const units = *units_ptr; + GArray *units; + + units = g_array_sized_new(FALSE, FALSE, sizeof(GstVaapiDecoderUnit), size); + *units_ptr = units; + return units != NULL; +} + +static inline void +free_units(GArray **units_ptr) +{ + GArray * const units = *units_ptr; + guint i; if (units) { - g_slist_free_full(units, (GDestroyNotify)gst_vaapi_mini_object_unref); + for (i = 0; i < units->len; i++) { + GstVaapiDecoderUnit * const unit = + &g_array_index(units, GstVaapiDecoderUnit, i); + gst_vaapi_decoder_unit_clear(unit); + } + g_array_free(units, TRUE); *units_ptr = NULL; } } @@ -58,8 +74,25 @@ free_units(GSList **units_ptr) GstVaapiDecoderFrame * gst_vaapi_decoder_frame_new(void) { - return (GstVaapiDecoderFrame *) - gst_vaapi_mini_object_new0(gst_vaapi_decoder_frame_class()); + GstVaapiDecoderFrame *frame; + + frame = (GstVaapiDecoderFrame *) + gst_vaapi_mini_object_new(gst_vaapi_decoder_frame_class()); + if (!frame) + return NULL; + + if (!alloc_units(&frame->pre_units, 4)) + goto error; + if (!alloc_units(&frame->units, 1)) + goto error; + if (!alloc_units(&frame->post_units, 1)) + goto error; + frame->output_offset = 0; + return frame; + +error: + gst_vaapi_decoder_frame_unref(frame); + return NULL; } /** @@ -79,3 +112,28 @@ gst_vaapi_decoder_frame_free(GstVaapiDecoderFrame *frame) free_units(&frame->pre_units); free_units(&frame->post_units); } + +/** + * gst_vaapi_decoder_frame_append_unit: + * @frame: a #GstVaapiDecoderFrame + * @unit: a #GstVaapiDecoderUnit + * + * Appends unit to the @frame. + */ +void +gst_vaapi_decoder_frame_append_unit(GstVaapiDecoderFrame *frame, + GstVaapiDecoderUnit *unit) +{ + GArray **unit_array_ptr; + + unit->offset = frame->output_offset; + frame->output_offset += unit->size; + + if (GST_VAAPI_DECODER_UNIT_IS_SLICE(unit)) + unit_array_ptr = &frame->units; + else if (GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit)) + unit_array_ptr = &frame->post_units; + else + unit_array_ptr = &frame->pre_units; + g_array_append_val(*unit_array_ptr, *unit); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h index 609cafd750..b89bb5dae9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h @@ -69,9 +69,9 @@ struct _GstVaapiDecoderFrame { GstVaapiMiniObject parent_instance; guint output_offset; - GSList *units; - GSList *pre_units; - GSList *post_units; + GArray *units; + GArray *pre_units; + GArray *post_units; }; G_GNUC_INTERNAL @@ -82,6 +82,11 @@ G_GNUC_INTERNAL void gst_vaapi_decoder_frame_free(GstVaapiDecoderFrame *frame); +G_GNUC_INTERNAL +void +gst_vaapi_decoder_frame_append_unit(GstVaapiDecoderFrame *frame, + GstVaapiDecoderUnit *unit); + #define gst_vaapi_decoder_frame_ref(frame) \ gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(frame)) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 4f864068f3..968f49a46f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -147,12 +147,13 @@ G_BEGIN_DECLS typedef struct _GstVaapiParserState GstVaapiParserState; struct _GstVaapiParserState { - GstVideoCodecFrame *current_frame; - GstAdapter *current_adapter; - GstAdapter *input_adapter; - gint input_offset2; - GstAdapter *output_adapter; - GstVaapiDecoderUnit *pending_unit; + GstVideoCodecFrame *current_frame; + GstAdapter *current_adapter; + GstAdapter *input_adapter; + gint input_offset2; + GstAdapter *output_adapter; + GstVaapiDecoderUnit next_unit; + gboolean next_unit_pending; }; struct _GstVaapiDecoderPrivate { diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c index c169958d80..27e64165af 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c @@ -55,6 +55,8 @@ decoder_unit_init(GstVaapiDecoderUnit *unit) unit->parsed_info = NULL; unit->parsed_info_destroy_notify = NULL; + + GST_VAAPI_DECODER_UNIT_FLAGS(unit) = 0; } void From a486d1af667e93e299b35b83625d49ee12575a90 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 7 Jan 2013 13:59:07 +0100 Subject: [PATCH 0986/3781] decoder: optimize pre-allocation of decoder units. Optimize pre-allocation of decoder units, thus avoiding un-necessary memory reallocations. The heuristic used is that we could have around one slice unit per macroblock line. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 7 +++++-- gst-libs/gst/vaapi/gstvaapidecoder_frame.c | 13 ++++++++++--- gst-libs/gst/vaapi/gstvaapidecoder_frame.h | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 7a5cf0501b..966d3ea784 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -135,7 +135,8 @@ do_parse(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame, GstAdapter *adapter, gboolean at_eos, guint *got_unit_size_ptr, gboolean *got_frame_ptr) { - GstVaapiParserState * const ps = &decoder->priv->parser_state; + GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiParserState * const ps = &priv->parser_state; GstVaapiDecoderFrame *frame; GstVaapiDecoderUnit *unit; GstVaapiDecoderStatus status; @@ -145,7 +146,9 @@ do_parse(GstVaapiDecoder *decoder, frame = gst_video_codec_frame_get_user_data(base_frame); if (!frame) { - frame = gst_vaapi_decoder_frame_new(); + GstVideoCodecState * const codec_state = priv->codec_state; + frame = gst_vaapi_decoder_frame_new(codec_state->info.width, + codec_state->info.height); if (!frame) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; gst_video_codec_frame_set_user_data(base_frame, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.c b/gst-libs/gst/vaapi/gstvaapidecoder_frame.c index 4c1c178cee..cae0d30873 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_frame.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_frame.c @@ -66,24 +66,31 @@ free_units(GArray **units_ptr) /** * gst_vaapi_decoder_frame_new: + * @width: frame width in pixels + * @height: frame height in pixels * * Creates a new #GstVaapiDecoderFrame object. * * Returns: The newly allocated #GstVaapiDecoderFrame */ GstVaapiDecoderFrame * -gst_vaapi_decoder_frame_new(void) +gst_vaapi_decoder_frame_new(guint width, guint height) { GstVaapiDecoderFrame *frame; + guint num_slices; frame = (GstVaapiDecoderFrame *) gst_vaapi_mini_object_new(gst_vaapi_decoder_frame_class()); if (!frame) return NULL; - if (!alloc_units(&frame->pre_units, 4)) + if (!height) + height = 1088; + num_slices = (height + 15) / 16; + + if (!alloc_units(&frame->pre_units, 16)) goto error; - if (!alloc_units(&frame->units, 1)) + if (!alloc_units(&frame->units, num_slices)) goto error; if (!alloc_units(&frame->post_units, 1)) goto error; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h index b89bb5dae9..4a3595a368 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h @@ -76,7 +76,7 @@ struct _GstVaapiDecoderFrame { G_GNUC_INTERNAL GstVaapiDecoderFrame * -gst_vaapi_decoder_frame_new(void); +gst_vaapi_decoder_frame_new(guint width, guint height); G_GNUC_INTERNAL void From 8c403c2d98310aec59893f41c4c966dc4b176e2f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 7 Jan 2013 14:04:22 +0100 Subject: [PATCH 0987/3781] decoder: decoder units are no longer dynamically allocated objects. --- gst-libs/gst/vaapi/gstvaapidecoder_unit.c | 55 ++-------------------- gst-libs/gst/vaapi/gstvaapidecoder_unit.h | 57 ++++++++++++++++------- 2 files changed, 44 insertions(+), 68 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c index 27e64165af..217dde609d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c @@ -27,16 +27,6 @@ #include "sysdeps.h" #include "gstvaapidecoder_unit.h" -static inline const GstVaapiMiniObjectClass * -gst_vaapi_decoder_unit_class(void) -{ - static const GstVaapiMiniObjectClass GstVaapiDecoderUnitClass = { - sizeof(GstVaapiDecoderUnit), - (GDestroyNotify)gst_vaapi_decoder_unit_clear - }; - return &GstVaapiDecoderUnitClass; -} - /** * gst_vaapi_decoder_unit_init: * @unit: a #GstVaapiDecoderUnit @@ -46,23 +36,16 @@ gst_vaapi_decoder_unit_class(void) * @note This is an internal function used to implement lightweight * sub-classes. */ -static inline void -decoder_unit_init(GstVaapiDecoderUnit *unit) +void +gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit) { + unit->flags = 0; unit->size = 0; unit->offset = 0; unit->buffer = NULL; unit->parsed_info = NULL; unit->parsed_info_destroy_notify = NULL; - - GST_VAAPI_DECODER_UNIT_FLAGS(unit) = 0; -} - -void -gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit) -{ - decoder_unit_init(unit); } /** @@ -75,39 +58,11 @@ gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit) * @note This is an internal function used to implement lightweight * sub-classes. */ -static inline void -decoder_unit_clear(GstVaapiDecoderUnit *unit) -{ - gst_buffer_replace(&unit->buffer, NULL); - gst_vaapi_decoder_unit_set_parsed_info(unit, NULL, NULL); -} - void gst_vaapi_decoder_unit_clear(GstVaapiDecoderUnit *unit) { - decoder_unit_clear(unit); -} - -/** - * gst_vaapi_decoder_unit_new: - * @size: size in bytes of this bitstream data chunk - * - * Creates a new #GstVaapiDecoderUnit object. - * - * Returns: The newly allocated #GstVaapiDecoderUnit - */ -GstVaapiDecoderUnit * -gst_vaapi_decoder_unit_new(void) -{ - GstVaapiDecoderUnit *unit; - - unit = (GstVaapiDecoderUnit *) - gst_vaapi_mini_object_new(gst_vaapi_decoder_unit_class()); - if (!unit) - return NULL; - - decoder_unit_init(unit); - return unit; + gst_buffer_replace(&unit->buffer, NULL); + gst_vaapi_decoder_unit_set_parsed_info(unit, NULL, NULL); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h index 9842afb8a6..2c10129f4f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h @@ -23,7 +23,6 @@ #define GST_VAAPI_DECODER_UNIT_H #include -#include G_BEGIN_DECLS @@ -54,10 +53,44 @@ typedef enum { GST_VAAPI_DECODER_UNIT_FLAG_LAST = (1 << 5) } GstVaapiDecoderUnitFlags; -#define GST_VAAPI_DECODER_UNIT_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS -#define GST_VAAPI_DECODER_UNIT_FLAG_IS_SET GST_VAAPI_MINI_OBJECT_FLAG_IS_SET -#define GST_VAAPI_DECODER_UNIT_FLAG_SET GST_VAAPI_MINI_OBJECT_FLAG_SET -#define GST_VAAPI_DECODER_UNIT_FLAG_UNSET GST_VAAPI_MINI_OBJECT_FLAG_UNSET +/** + * 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: @@ -129,9 +162,7 @@ typedef enum { * A chunk of bitstream data that was parsed. */ struct _GstVaapiDecoderUnit { - /*< private >*/ - GstVaapiMiniObject parent_instance; - + guint flags; guint size; guint offset; GstBuffer *buffer; @@ -160,16 +191,6 @@ void gst_vaapi_decoder_unit_set_parsed_info(GstVaapiDecoderUnit *unit, gpointer parsed_info, GDestroyNotify destroy_notify); -#define gst_vaapi_decoder_unit_ref(unit) \ - gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(unit)) - -#define gst_vaapi_decoder_unit_unref(unit) \ - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(unit)) - -#define gst_vaapi_decoder_unit_replace(old_unit_p, new_unit) \ - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_unit_p), \ - (GstVaapiMiniObject *)(new_unit)) - G_END_DECLS #endif /* GST_VAAPI_DECODER_UNIT_H */ From 6dd8eab023621951b7b57ecd3d4b3ef84f6656cb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 7 Jan 2013 15:24:51 +0100 Subject: [PATCH 0988/3781] mpeg2: avoid too many allocations of parser info objects. Move parsing back to decoding step, but keep functions separate for now. This is needed for future optimizations that may introduce some meta data for parsed info attached to codec frames. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 372 +++++++++++++-------- 1 file changed, 227 insertions(+), 145 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index f9944d6b9b..ff227ca71f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -289,6 +289,18 @@ gst_vaapi_parser_info_mpeg2_new(void) gst_vaapi_mini_object_new(gst_vaapi_parser_info_mpeg2_class()); } +static inline GstVaapiParserInfoMpeg2 * +gst_vaapi_parser_info_mpeg2_ensure(GstVaapiParserInfoMpeg2 **pi_ptr) +{ + GstVaapiParserInfoMpeg2 *pi = *pi_ptr; + + if (G_LIKELY(pi != NULL)) + return pi; + + *pi_ptr = pi = gst_vaapi_parser_info_mpeg2_new(); + return pi; +} + #define gst_vaapi_parser_info_mpeg2_ref(pi) \ gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pi)) @@ -326,9 +338,11 @@ struct _GstVaapiDecoderMpeg2Private { GstVaapiParserInfoMpeg2 *seq_ext; GstVaapiParserInfoMpeg2 *seq_display_ext; GstVaapiParserInfoMpeg2 *seq_scalable_ext; + GstVaapiParserInfoMpeg2 *gop; GstVaapiParserInfoMpeg2 *pic_hdr; GstVaapiParserInfoMpeg2 *pic_ext; GstVaapiParserInfoMpeg2 *quant_matrix; + GstVaapiParserInfoMpeg2 *slice_hdr; GstVaapiPicture *current_picture; GstVaapiDpb *dpb; PTSGenerator tsg; @@ -353,9 +367,11 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->seq_scalable_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->gop, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->pic_hdr, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->slice_hdr, NULL); if (priv->dpb) { gst_vaapi_dpb_unref(priv->dpb); @@ -581,16 +597,26 @@ error: } static GstVaapiDecoderStatus -parse_sequence(GstVaapiDecoderUnit *unit) +parse_sequence(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; - GstMpegVideoPacket * const packet = &pi->packet; + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoSequenceHdr *seq_hdr; - if (!gst_mpeg_video_parse_sequence_header(&pi->data.seq_hdr, + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_hdr)) { + GST_ERROR("failed to allocate parser info for sequence header"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + seq_hdr = &priv->seq_hdr->data.seq_hdr; + + if (!gst_mpeg_video_parse_sequence_header(seq_hdr, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse sequence header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } + + gst_vaapi_decoder_unit_set_parsed_info(unit, seq_hdr, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -599,10 +625,8 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoSequenceHdr *seq_hdr; + GstMpegVideoSequenceHdr * const seq_hdr = unit->parsed_info; - gst_vaapi_parser_info_mpeg2_replace(&priv->seq_hdr, unit->parsed_info); - seq_hdr = &priv->seq_hdr->data.seq_hdr; gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, NULL); @@ -620,32 +644,38 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) } static GstVaapiDecoderStatus -parse_sequence_ext(GstVaapiDecoderUnit *unit) +parse_sequence_ext(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; - GstMpegVideoPacket * const packet = &pi->packet; + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoSequenceExt *seq_ext; - if (!gst_mpeg_video_parse_sequence_extension(&pi->data.seq_ext, + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_ext)) { + GST_ERROR("failed to allocate parser info for sequence extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + seq_ext = &priv->seq_ext->data.seq_ext; + + if (!gst_mpeg_video_parse_sequence_extension(seq_ext, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse sequence-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } + + gst_vaapi_decoder_unit_set_parsed_info(unit, seq_ext, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit) +decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoSequenceExt *seq_ext; + GstMpegVideoSequenceExt * const seq_ext = unit->parsed_info; GstVaapiProfile profile; guint width, height; - gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, unit->parsed_info); - seq_ext = &priv->seq_ext->data.seq_ext; - priv->progressive_sequence = seq_ext->progressive; gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence); @@ -692,17 +722,26 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, } static GstVaapiDecoderStatus -parse_sequence_display_ext(GstVaapiDecoderUnit *unit) +parse_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; - GstMpegVideoPacket * const packet = &pi->packet; + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoSequenceDisplayExt *seq_display_ext; - if (!gst_mpeg_video_parse_sequence_display_extension( - &pi->data.seq_display_ext, + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_display_ext)) { + GST_ERROR("failed to allocate parser info for sequence display extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + seq_display_ext = &priv->seq_display_ext->data.seq_display_ext; + + if (!gst_mpeg_video_parse_sequence_display_extension(seq_display_ext, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse sequence-display-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } + + gst_vaapi_decoder_unit_set_parsed_info(unit, seq_display_ext, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -710,11 +749,6 @@ static GstVaapiDecoderStatus decode_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - - gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, - unit->parsed_info); - /* XXX: handle color primaries and cropping */ return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -734,16 +768,26 @@ decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) } static GstVaapiDecoderStatus -parse_quant_matrix_ext(GstVaapiDecoderUnit *unit) +parse_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; - GstMpegVideoPacket * const packet = &pi->packet; + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoQuantMatrixExt *quant_matrix; - if (!gst_mpeg_video_parse_quant_matrix_extension(&pi->data.quant_matrix, + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->quant_matrix)) { + GST_ERROR("failed to allocate parser info for quantization matrix"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + quant_matrix = &priv->quant_matrix->data.quant_matrix; + + if (!gst_mpeg_video_parse_quant_matrix_extension(quant_matrix, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse quant-matrix-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } + + gst_vaapi_decoder_unit_set_parsed_info(unit, quant_matrix, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -753,22 +797,31 @@ decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, unit->parsed_info); priv->quant_matrix_changed = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_gop(GstVaapiDecoderUnit *unit) +parse_gop(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; - GstMpegVideoPacket * const packet = &pi->packet; + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoGop *gop; - if (!gst_mpeg_video_parse_gop(&pi->data.gop, + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->gop)) { + GST_ERROR("failed to allocate parser info for GOP"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + gop = &priv->gop->data.gop; + + if (!gst_mpeg_video_parse_gop(gop, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse GOP"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } + + gst_vaapi_decoder_unit_set_parsed_info(unit, gop, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -776,8 +829,7 @@ static GstVaapiDecoderStatus decode_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; - GstMpegVideoGop * const gop = &pi->data.gop; + GstMpegVideoGop * const gop = unit->parsed_info; priv->closed_gop = gop->closed_gop; priv->broken_link = gop->broken_link; @@ -791,31 +843,47 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) } static GstVaapiDecoderStatus -parse_picture(GstVaapiDecoderUnit *unit) +parse_picture(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; - GstMpegVideoPacket * const packet = &pi->packet; + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoPictureHdr *pic_hdr; - if (!gst_mpeg_video_parse_picture_header(&pi->data.pic_hdr, + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->pic_hdr)) { + GST_ERROR("failed to allocate parser info for picture header"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + pic_hdr = &priv->pic_hdr->data.pic_hdr; + + if (!gst_mpeg_video_parse_picture_header(pic_hdr, packet->data, packet->size, packet->offset)) { GST_ERROR("failed to parse picture header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } + + gst_vaapi_decoder_unit_set_parsed_info(unit, pic_hdr, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) +parse_slice(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; - GstMpegVideoSliceHdr * const slice_hdr = &pi->data.slice_hdr; - GstMpegVideoPacket * const packet = &pi->packet; + GstMpegVideoSliceHdr *slice_hdr; GstBitReader br; gint mb_x, mb_y, mb_inc; guint8 slice_vertical_position_extension; guint8 extra_bit_slice, junk8; + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->slice_hdr)) { + GST_ERROR("failed to allocate parser info for slice header"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + slice_hdr = &priv->slice_hdr->data.slice_hdr; + gst_bit_reader_init(&br, packet->data + packet->offset, packet->size); if (priv->height > 2800) READ_UINT8(&br, slice_vertical_position_extension, 3); @@ -851,6 +919,8 @@ parse_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) slice_hdr->slice_horizontal_position = mb_x; slice_hdr->slice_vertical_position = mb_y; + + gst_vaapi_decoder_unit_set_parsed_info(unit, slice_hdr, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; failed: @@ -862,35 +932,40 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - gst_vaapi_parser_info_mpeg2_replace(&priv->pic_hdr, unit->parsed_info); gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_picture_ext(GstVaapiDecoderUnit *unit) -{ - GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; - GstMpegVideoPacket * const packet = &pi->packet; - - if (!gst_mpeg_video_parse_picture_extension(&pi->data.pic_ext, - packet->data, packet->size, packet->offset)) { - GST_ERROR("failed to parse picture-extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit) +parse_picture_ext(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoPictureExt *pic_ext; - gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, unit->parsed_info); + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->pic_ext)) { + GST_ERROR("failed to allocate parser info for picture extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + pic_ext = &priv->pic_ext->data.pic_ext; + if (!gst_mpeg_video_parse_picture_extension(pic_ext, + packet->data, packet->size, packet->offset)) { + GST_ERROR("failed to parse picture-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + gst_vaapi_decoder_unit_set_parsed_info(unit, pic_ext, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoPictureExt * const pic_ext = unit->parsed_info; + if (priv->progressive_sequence && !pic_ext->progressive_frame) { GST_WARNING("invalid interlaced frame in progressive sequence, fixing"); pic_ext->progressive_frame = 1; @@ -1053,11 +1128,10 @@ static GstVaapiDecoderStatus decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; GstVaapiPicture * const picture = priv->current_picture; GstVaapiSlice *slice; VASliceParameterBufferMPEG2 *slice_param; - GstMpegVideoSliceHdr * const slice_hdr = &pi->data.slice_hdr; + GstMpegVideoSliceHdr * const slice_hdr = unit->parsed_info; GST_DEBUG("slice %d (%u bytes)", slice_hdr->slice_vertical_position, unit->size); @@ -1091,13 +1165,67 @@ scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) } static GstVaapiDecoderStatus -decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) +parse_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, + GstMpegVideoPacket *packet) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info; + GstMpegVideoPacketTypeCode type; + GstMpegVideoPacketExtensionCode ext_type; GstVaapiDecoderStatus status; - switch (pi->packet.type) { + type = packet->type; + switch (type) { + case GST_MPEG_VIDEO_PACKET_PICTURE: + status = parse_picture(decoder, unit, packet); + break; + case GST_MPEG_VIDEO_PACKET_SEQUENCE: + status = parse_sequence(decoder, unit, packet); + break; + case GST_MPEG_VIDEO_PACKET_EXTENSION: + ext_type = packet->data[4] >> 4; + switch (ext_type) { + case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: + status = parse_sequence_ext(decoder, unit, packet); + break; + case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY: + status = parse_sequence_display_ext(decoder, unit, packet); + break; + case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: + status = parse_quant_matrix_ext(decoder, unit, packet); + break; + case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: + status = parse_picture_ext(decoder, unit, packet); + break; + default: + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + break; + case GST_MPEG_VIDEO_PACKET_GOP: + status = parse_gop(decoder, unit, packet); + break; + default: + if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { + status = parse_slice(decoder, unit, packet); + break; + } + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + return status; +} + +static GstVaapiDecoderStatus +decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, + GstMpegVideoPacket *packet) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoPacketTypeCode type; + GstMpegVideoPacketExtensionCode ext_type; + GstVaapiDecoderStatus status; + + type = packet->type; + switch (type) { case GST_MPEG_VIDEO_PACKET_PICTURE: if (!priv->width || !priv->height) goto unknown_picture_size; @@ -1107,7 +1235,8 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) status = decode_sequence(decoder, unit); break; case GST_MPEG_VIDEO_PACKET_EXTENSION: - switch (pi->extension_type) { + ext_type = packet->data[4] >> 4; + switch (ext_type) { case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: status = decode_sequence_ext(decoder, unit); break; @@ -1124,8 +1253,7 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) break; default: // Ignore unknown start-code extensions - GST_WARNING("unsupported packet extension type 0x%02x", - pi->extension_type); + GST_WARNING("unsupported packet extension type 0x%02x", ext_type); status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; } @@ -1137,12 +1265,12 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) status = decode_gop(decoder, unit); break; default: - if (pi->packet.type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && - pi->packet.type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { + if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { status = decode_slice(decoder, unit); break; } - GST_WARNING("unsupported packet type 0x%02x", pi->packet.type); + GST_WARNING("unsupported packet type 0x%02x", type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } @@ -1178,9 +1306,8 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); - GstVaapiParserInfoMpeg2 *pi; GstVaapiDecoderStatus status; - GstMpegVideoPacket *packet; + GstMpegVideoPacketTypeCode type; const guchar *buf; guint32 start_code; guint size, buf_size, flags; @@ -1226,70 +1353,11 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, unit->size = buf_size; - pi = gst_vaapi_parser_info_mpeg2_new(); - if (!pi) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - - gst_vaapi_decoder_unit_set_parsed_info(unit, - pi, (GDestroyNotify)gst_vaapi_mini_object_unref); - - packet = &pi->packet; - packet->data = buf; - packet->size = buf_size; - packet->offset = 4; - packet->type = start_code & 0xff; - - /* Parse data */ - switch (packet->type) { - case GST_MPEG_VIDEO_PACKET_SEQUENCE: - status = parse_sequence(unit); - break; - case GST_MPEG_VIDEO_PACKET_GOP: - status = parse_gop(unit); - break; - case GST_MPEG_VIDEO_PACKET_PICTURE: - status = parse_picture(unit); - break; - case GST_MPEG_VIDEO_PACKET_EXTENSION: - if (G_UNLIKELY(buf_size < 5)) { - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - break; - } - pi->extension_type = buf[4] >> 4; - switch (pi->extension_type) { - case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: - status = parse_sequence_ext(unit); - break; - case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY: - status = parse_sequence_display_ext(unit); - break; - case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: - status = parse_quant_matrix_ext(unit); - break; - case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: - status = parse_picture_ext(unit); - break; - default: - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } - break; - default: - if (packet->type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && - packet->type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { - status = parse_slice(decoder, unit); - break; - } - - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; + type = start_code & 0xff; /* Check for start of new picture */ flags = 0; - switch (packet->type) { + switch (type) { case GST_MPEG_VIDEO_PACKET_SEQUENCE_END: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; @@ -1302,19 +1370,21 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, case GST_MPEG_VIDEO_PACKET_PICTURE: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; + case GST_MPEG_VIDEO_PACKET_EXTENSION: + if (G_UNLIKELY(buf_size < 5)) + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; default: - if (packet->type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && - packet->type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) + if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; // Ignore system start codes (PES headers) - else if (packet->type >= 0xb9 && packet->type <= 0xff) + else if (type >= 0xb9 && type <= 0xff) flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; break; } GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); - - pi->packet.data = NULL; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1325,11 +1395,23 @@ gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); GstVaapiDecoderStatus status; + GstMpegVideoPacket packet; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - return decode_unit(decoder, unit); + + packet.data = + (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) + + unit->offset); + packet.size = unit->size; + packet.type = packet.data[3]; + packet.offset = 4; + + status = parse_unit(decoder, unit, &packet); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + return decode_unit(decoder, unit, &packet); } static GstVaapiDecoderStatus From 4a69e395cd8a45349a965a9fae2021a518376567 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 7 Jan 2013 16:07:38 +0100 Subject: [PATCH 0989/3781] mpeg2: cosmetics: move parse_slice() down. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 122 ++++++++++----------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index ff227ca71f..86daa44e28 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -866,67 +866,6 @@ parse_picture(GstVaapiDecoderMpeg2 *decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static GstVaapiDecoderStatus -parse_slice(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) -{ - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstMpegVideoSliceHdr *slice_hdr; - GstBitReader br; - gint mb_x, mb_y, mb_inc; - guint8 slice_vertical_position_extension; - guint8 extra_bit_slice, junk8; - - if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->slice_hdr)) { - GST_ERROR("failed to allocate parser info for slice header"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - - slice_hdr = &priv->slice_hdr->data.slice_hdr; - - gst_bit_reader_init(&br, packet->data + packet->offset, packet->size); - if (priv->height > 2800) - READ_UINT8(&br, slice_vertical_position_extension, 3); - if (priv->seq_scalable_ext) { - GST_ERROR("failed to parse slice with sequence_scalable_extension()"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } - READ_UINT8(&br, slice_hdr->quantiser_scale_code, 5); - READ_UINT8(&br, extra_bit_slice, 1); - if (!extra_bit_slice) - slice_hdr->intra_slice = 0; - else { - READ_UINT8(&br, slice_hdr->intra_slice, 1); - READ_UINT8(&br, junk8, 7); - READ_UINT8(&br, extra_bit_slice, 1); - while (extra_bit_slice) { - READ_UINT8(&br, junk8, 8); - READ_UINT8(&br, extra_bit_slice, 1); - } - } - slice_hdr->header_size = 32 + gst_bit_reader_get_pos(&br); - - mb_y = packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN; - mb_x = -1; - do { - if (!decode_vlc(&br, &mb_inc, mpeg2_mbaddr_vlc_table, - G_N_ELEMENTS(mpeg2_mbaddr_vlc_table))) { - GST_WARNING("failed to decode first macroblock_address_increment"); - goto failed; - } - mb_x += mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE ? 33 : mb_inc; - } while (mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE); - - slice_hdr->slice_horizontal_position = mb_x; - slice_hdr->slice_vertical_position = mb_y; - - gst_vaapi_decoder_unit_set_parsed_info(unit, slice_hdr, NULL); - return GST_VAAPI_DECODER_STATUS_SUCCESS; - -failed: - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; -} - static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { @@ -1124,6 +1063,67 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) } } +static GstVaapiDecoderStatus +parse_slice(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstMpegVideoSliceHdr *slice_hdr; + GstBitReader br; + gint mb_x, mb_y, mb_inc; + guint8 slice_vertical_position_extension; + guint8 extra_bit_slice, junk8; + + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->slice_hdr)) { + GST_ERROR("failed to allocate parser info for slice header"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + slice_hdr = &priv->slice_hdr->data.slice_hdr; + + gst_bit_reader_init(&br, packet->data + packet->offset, packet->size); + if (priv->height > 2800) + READ_UINT8(&br, slice_vertical_position_extension, 3); + if (priv->seq_scalable_ext) { + GST_ERROR("failed to parse slice with sequence_scalable_extension()"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + READ_UINT8(&br, slice_hdr->quantiser_scale_code, 5); + READ_UINT8(&br, extra_bit_slice, 1); + if (!extra_bit_slice) + slice_hdr->intra_slice = 0; + else { + READ_UINT8(&br, slice_hdr->intra_slice, 1); + READ_UINT8(&br, junk8, 7); + READ_UINT8(&br, extra_bit_slice, 1); + while (extra_bit_slice) { + READ_UINT8(&br, junk8, 8); + READ_UINT8(&br, extra_bit_slice, 1); + } + } + slice_hdr->header_size = 32 + gst_bit_reader_get_pos(&br); + + mb_y = packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN; + mb_x = -1; + do { + if (!decode_vlc(&br, &mb_inc, mpeg2_mbaddr_vlc_table, + G_N_ELEMENTS(mpeg2_mbaddr_vlc_table))) { + GST_WARNING("failed to decode first macroblock_address_increment"); + goto failed; + } + mb_x += mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE ? 33 : mb_inc; + } while (mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE); + + slice_hdr->slice_horizontal_position = mb_x; + slice_hdr->slice_vertical_position = mb_y; + + gst_vaapi_decoder_unit_set_parsed_info(unit, slice_hdr, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; + +failed: + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; +} + static GstVaapiDecoderStatus decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { From 0180ef635c53a9ed062cde7040be3a3971379e9a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 8 Jan 2013 16:41:44 +0100 Subject: [PATCH 0990/3781] mpeg2: drop useless gst_adapter_peek(). Drop useless gst_adapter_peek() since the returned buffer was not used and this could incur superfluous memcpy(). --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 86daa44e28..784618c325 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1308,7 +1308,6 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiDecoderStatus status; GstMpegVideoPacketTypeCode type; - const guchar *buf; guint32 start_code; guint size, buf_size, flags; gint ofs, ofs2; @@ -1347,10 +1346,6 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, buf_size = ofs; ps->input_offset2 = 0; - buf = gst_adapter_peek(adapter, buf_size); - if (!buf) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - unit->size = buf_size; type = start_code & 0xff; From 3bc6078f32c4366a6c7839f63dfb35c2314bd5df Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 9 Jan 2013 13:44:18 +0100 Subject: [PATCH 0991/3781] mpeg2: optimize scan for start codes. Accelerate scan for start codes by skipping up to 3 bytes per iteration. A start code prefix is defined by the following bytes: 00 00 01. Thus, for any group of 3 bytes (xx yy zz), we have the following possible cases: 1. If zz != 1, this cannot be a start code, then skip 3 bytes; 2. If yy != 0, this cannot be a start code, then skip 2 bytes; 3. If xx != 0 or zz != 1, this cannot be a start code, then skip 1 byte; 4. xx == 00, yy == 00, zz == 1, we have match! This algorithm requires to peek bytes from the adapter. This increases the amount of bytes copied to a temporary buffer, but this process is much faster than scanning for all the bytes and using shift/masks. So, overall, this is a win. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 73 +++++++++++++--------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 784618c325..e4a5db8b03 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1156,12 +1156,28 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) } static inline gint -scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) +scan_for_start_code(const guchar *buf, guint buf_size, + GstMpegVideoPacketTypeCode *type_ptr) { - return (gint)gst_adapter_masked_scan_uint32_peek(adapter, - 0xffffff00, 0x00000100, - ofs, size, - scp); + guint i = 0; + + while (i <= (buf_size - 4)) { + if (buf[i + 2] > 1) + i += 3; + else if (buf[i + 1]) + i += 2; + else if (buf[i] || buf[i + 2] != 1) + i++; + else + break; + } + + if (i <= (buf_size - 4)) { + if (type_ptr) + *type_ptr = buf[i + 3]; + return i; + } + return -1; } static GstVaapiDecoderStatus @@ -1308,47 +1324,46 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiDecoderStatus status; GstMpegVideoPacketTypeCode type; - guint32 start_code; - guint size, buf_size, flags; - gint ofs, ofs2; + const guchar *buf; + guint buf_size, flags; + gint ofs, ofs1, ofs2; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - size = gst_adapter_available(adapter); - if (size < 4) + buf_size = gst_adapter_available(adapter); + if (buf_size < 4) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - ofs = scan_for_start_code(adapter, 0, size, &start_code); + buf = gst_adapter_peek(adapter, buf_size); + if (!buf) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + ofs = scan_for_start_code(buf, buf_size, &type); if (ofs < 0) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + ofs1 = ofs; - if (ofs > 0) { - gst_adapter_flush(adapter, ofs); - size -= ofs; - } + ofs2 = ps->input_offset2 - 4; + if (ofs2 < ofs1 + 4) + ofs2 = ofs1 + 4; - ofs2 = ps->input_offset2 - ofs - 4; - if (ofs2 < 4) - ofs2 = 4; - - ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 : - scan_for_start_code(adapter, ofs2, size - ofs2, NULL); + ofs = G_UNLIKELY(buf_size < ofs2 + 4) ? -1 : + scan_for_start_code(&buf[ofs2], buf_size - ofs2, NULL); if (ofs < 0) { // Assume the whole packet is present if end-of-stream if (!at_eos) { - ps->input_offset2 = size; + ps->input_offset2 = buf_size; return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; } - ofs = size; + ofs = buf_size - ofs2; } - buf_size = ofs; - ps->input_offset2 = 0; + ofs2 += ofs; - unit->size = buf_size; - - type = start_code & 0xff; + unit->size = ofs2 - ofs1; + gst_adapter_flush(adapter, ofs1); + ps->input_offset2 = 4; /* Check for start of new picture */ flags = 0; @@ -1366,7 +1381,7 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; case GST_MPEG_VIDEO_PACKET_EXTENSION: - if (G_UNLIKELY(buf_size < 5)) + if (G_UNLIKELY(unit->size < 5)) return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; default: From 0ecb3a627bf5485cdb2be998fd78cdc07bf61a97 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 9 Jan 2013 16:05:39 +0100 Subject: [PATCH 0992/3781] mpeg2: optimize scan for the end of the frame. Heuristic: if the second start-code is available, check whether that one marks the start of a new frame because e.g. this is a sequence or picture header. This doesn't save much, since we already cache the results. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index e4a5db8b03..cde9278940 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1323,7 +1323,7 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiDecoderStatus status; - GstMpegVideoPacketTypeCode type; + GstMpegVideoPacketTypeCode type, type2 = GST_MPEG_VIDEO_PACKET_NONE; const guchar *buf; guint buf_size, flags; gint ofs, ofs1, ofs2; @@ -1350,7 +1350,7 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, ofs2 = ofs1 + 4; ofs = G_UNLIKELY(buf_size < ofs2 + 4) ? -1 : - scan_for_start_code(&buf[ofs2], buf_size - ofs2, NULL); + scan_for_start_code(&buf[ofs2], buf_size - ofs2, &type2); if (ofs < 0) { // Assume the whole packet is present if end-of-stream if (!at_eos) { @@ -1386,8 +1386,19 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, break; default: if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && - type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) + type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + switch (type2) { + case GST_MPEG_VIDEO_PACKET_USER_DATA: + case GST_MPEG_VIDEO_PACKET_SEQUENCE: + case GST_MPEG_VIDEO_PACKET_GOP: + case GST_MPEG_VIDEO_PACKET_PICTURE: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + break; + default: + break; + } + } // Ignore system start codes (PES headers) else if (type >= 0xb9 && type <= 0xff) From 591b637cfc85d526096469e6bf786effb810e20f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 10 Jan 2013 10:12:25 +0100 Subject: [PATCH 0993/3781] decoder: fix mini object implementation on 64-bit systems. Use GPOINTER_TO_SIZE() instead of GPOINTER_TO_UINT() while manipulating pointers. The latter is meant to be 32-bit only, not uintptr_t like size. Only a gsize can hold all bits of a pointer. Thanks to Ouping Zhang for spotting this error. --- gst-libs/gst/vaapi/gstvaapiminiobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.c b/gst-libs/gst/vaapi/gstvaapiminiobject.c index 039f2058b1..08427d3497 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.c @@ -32,14 +32,14 @@ struct _GstVaapiMiniObjectBase { static inline GstVaapiMiniObjectBase * object2base(GstVaapiMiniObject *object) { - return GUINT_TO_POINTER(GPOINTER_TO_UINT(object) - + return GSIZE_TO_POINTER(GPOINTER_TO_SIZE(object) - sizeof(GstVaapiMiniObjectBase)); } static inline GstVaapiMiniObject * base2object(GstVaapiMiniObjectBase *base_object) { - return GUINT_TO_POINTER(GPOINTER_TO_UINT(base_object) + + return GSIZE_TO_POINTER(GPOINTER_TO_SIZE(base_object) + sizeof(GstVaapiMiniObjectBase)); } From 20a3709de3a2b820b6076583650b2ed53020954a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 11 Jan 2013 14:11:39 +0100 Subject: [PATCH 0994/3781] configure: fix checks for packages installed in non-standard roots. --- configure.ac | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 657bea8e7d..af7676937a 100644 --- a/configure.ac +++ b/configure.ac @@ -163,8 +163,8 @@ PKG_CHECK_MODULES([GST], [gstreamer-$GST_MAJORMINOR >= gst_version]) PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-$GST_MAJORMINOR >= gst_version]) AC_CACHE_CHECK([for GstBaseSink::query hook], ac_cv_have_gst_base_sink_query, [ - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $GST_BASE_CFLAGS" + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_BASE_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $GST_BASE_LIBS" AC_COMPILE_IFELSE( @@ -174,7 +174,7 @@ AC_CACHE_CHECK([for GstBaseSink::query hook], ac_cv_have_gst_base_sink_query, [ [ac_cv_have_gst_base_sink_query="yes"], [ac_cv_have_gst_base_sink_query="no"] ) - CFLAGS="$saved_CFLAGS" + CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) if test "$ac_cv_have_gst_base_sink_query" != "yes"; then @@ -193,8 +193,8 @@ PKG_CHECK_MODULES([GST_VIDEO], AC_CACHE_CHECK([for GstVideoOverlayComposition], ac_cv_have_gst_video_overlay_composition, [ - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $GST_CFLAGS" + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $GST_LIBS" AC_COMPILE_IFELSE( @@ -204,7 +204,7 @@ AC_CACHE_CHECK([for GstVideoOverlayComposition], [ac_cv_have_gst_video_overlay_composition="yes"], [ac_cv_have_gst_video_overlay_composition="no"] ) - CFLAGS="$saved_CFLAGS" + CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) if test "$ac_cv_have_gst_video_overlay_composition" != "yes"; then @@ -506,10 +506,10 @@ dnl Check for JPEG decoding API (0.32.1+) USE_JPEG_DECODER=0 AC_CACHE_CHECK([for JPEG decoding API], ac_cv_have_jpeg_decoding_api, [ - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $LIBVA_CFLAGS" + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" - LIBS="$CFLAGS $LIBVA_LIBS" + LIBS="$LIBS $LIBVA_LIBS" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], @@ -520,7 +520,7 @@ AC_CACHE_CHECK([for JPEG decoding API], [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=1], [ac_cv_have_jpeg_decoding_api="no"] ) - CFLAGS="$saved_CFLAGS" + CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) From d4a8e39656dcdf8f2992dedeb859dc06a5e0334c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 11 Jan 2013 13:34:45 +0100 Subject: [PATCH 0995/3781] libs: fix build of submodule wrappers. Make sure to build codecparsers/ and videoutils/ sources against the newly generated headers when out-of-source builds are used. --- gst-libs/gst/codecparsers/Makefile.am | 1 + gst-libs/gst/video/Makefile.am | 1 + tests/Makefile.am | 1 + 3 files changed, 3 insertions(+) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 9b40eb6a6f..8df6533582 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -8,6 +8,7 @@ local_codecparsers_srcdir = \ libgstvaapi_codecparsers_cflags = \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ + -I$(top_builddir)/gst-libs \ $(GST_BASE_CFLAGS) \ $(GST_CFLAGS) \ $(NULL) diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index fc0ca0121e..f6504f7f33 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -8,6 +8,7 @@ local_videoutils_srcdir = \ libgstvaapi_videoutils_cflags = \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ + -I$(top_builddir)/gst-libs \ $(GST_BASE_CFLAGS) \ $(GST_CFLAGS) \ $(NULL) diff --git a/tests/Makefile.am b/tests/Makefile.am index 314afa951e..fc258eed1a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,6 +15,7 @@ endif TEST_CFLAGS = \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ + -I$(top_builddir)/gst-libs \ $(LIBVA_CFLAGS) \ $(GST_CFLAGS) \ $(NULL) From fc1f9a64e4bd23248321a4759ca0d23c30fbce84 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jan 2013 18:02:49 +0100 Subject: [PATCH 0996/3781] display: allow image/subpicture formats with additional flags. Introduce new GstVaapiFormatInfo to store the actual GstVaapiImageFormat and any additional flags needed. Currently, all flags are set to zero. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 84 ++++++++++++++++++---------- 1 file changed, 55 insertions(+), 29 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 35a3d57c69..a51c0b5e45 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -53,6 +53,12 @@ struct _GstVaapiProperty { gint old_value; }; +typedef struct _GstVaapiFormatInfo GstVaapiFormatInfo; +struct _GstVaapiFormatInfo { + GstVaapiImageFormat format; + guint flags; +}; + #define DEFAULT_RENDER_MODE GST_VAAPI_RENDER_MODE_TEXTURE #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 @@ -149,22 +155,28 @@ gst_vaapi_display_type_get_type(void) /* Append GstVaapiImageFormat to formats array */ static inline void -append_format(GArray *formats, GstVaapiImageFormat format) +append_format(GArray *formats, GstVaapiImageFormat format, guint flags) { - g_array_append_val(formats, format); + GstVaapiFormatInfo fi; + + fi.format = format; + fi.flags = flags; + g_array_append_val(formats, fi); } /* Append VAImageFormats to formats array */ static void -append_formats(GArray *formats, const VAImageFormat *va_formats, guint n) +append_formats(GArray *formats, const VAImageFormat *va_formats, + guint *flags, guint n) { GstVaapiImageFormat format; - gboolean has_YV12 = FALSE; - gboolean has_I420 = FALSE; + const GstVaapiFormatInfo *YV12_fip = NULL; + const GstVaapiFormatInfo *I420_fip = NULL; guint i; for (i = 0; i < n; i++) { const VAImageFormat * const va_format = &va_formats[i]; + const GstVaapiFormatInfo **fipp; format = gst_vaapi_image_format(va_format); if (!format) { @@ -172,34 +184,38 @@ append_formats(GArray *formats, const VAImageFormat *va_formats, guint n) GST_FOURCC_ARGS(va_format->fourcc)); continue; } + append_format(formats, format, flags ? flags[i] : 0); switch (format) { case GST_VAAPI_IMAGE_YV12: - has_YV12 = TRUE; + fipp = &YV12_fip; break; case GST_VAAPI_IMAGE_I420: - has_I420 = TRUE; + fipp = &I420_fip; break; default: + fipp = NULL; break; } - append_format(formats, format); + if (fipp) + *fipp = &g_array_index(formats, GstVaapiFormatInfo, + formats->len - 1); } /* Append I420 (resp. YV12) format if YV12 (resp. I420) is not supported by the underlying driver */ - if (has_YV12 && !has_I420) - append_format(formats, GST_VAAPI_IMAGE_I420); - else if (has_I420 && !has_YV12) - append_format(formats, GST_VAAPI_IMAGE_YV12); + if (YV12_fip && !I420_fip) + append_format(formats, GST_VAAPI_IMAGE_I420, YV12_fip->flags); + else if (I420_fip && !YV12_fip) + append_format(formats, GST_VAAPI_IMAGE_YV12, I420_fip->flags); } /* Sort image formats. Prefer YUV formats first */ static gint compare_yuv_formats(gconstpointer a, gconstpointer b) { - const GstVaapiImageFormat fmt1 = *(GstVaapiImageFormat *)a; - const GstVaapiImageFormat fmt2 = *(GstVaapiImageFormat *)b; + const GstVaapiImageFormat fmt1 = ((GstVaapiFormatInfo *)a)->format; + const GstVaapiImageFormat fmt2 = ((GstVaapiFormatInfo *)b)->format; const gboolean is_fmt1_yuv = gst_vaapi_image_format_is_yuv(fmt1); const gboolean is_fmt2_yuv = gst_vaapi_image_format_is_yuv(fmt2); @@ -215,8 +231,8 @@ compare_yuv_formats(gconstpointer a, gconstpointer b) static gint compare_rgb_formats(gconstpointer a, gconstpointer b) { - const GstVaapiImageFormat fmt1 = *(GstVaapiImageFormat *)a; - const GstVaapiImageFormat fmt2 = *(GstVaapiImageFormat *)b; + const GstVaapiImageFormat fmt1 = ((GstVaapiFormatInfo *)a)->format; + const GstVaapiImageFormat fmt2 = ((GstVaapiFormatInfo *)b)->format; const gboolean is_fmt1_rgb = gst_vaapi_image_format_is_rgb(fmt1); const gboolean is_fmt2_rgb = gst_vaapi_image_format_is_rgb(fmt2); @@ -304,23 +320,33 @@ get_profile_caps(GArray *configs) return out_caps; } +/* Find format info */ +static const GstVaapiFormatInfo * +find_format_info(GArray *formats, GstVaapiImageFormat format) +{ + const GstVaapiFormatInfo *fip; + guint i; + + for (i = 0; i < formats->len; i++) { + fip = &g_array_index(formats, GstVaapiFormatInfo, i); + if (fip->format == format) + return fip; + } + return NULL; +} + /* Check if formats array contains format */ static inline gboolean find_format(GArray *formats, GstVaapiImageFormat format) { - guint i; - - for (i = 0; i < formats->len; i++) - if (g_array_index(formats, GstVaapiImageFormat, i) == format) - return TRUE; - return FALSE; + return find_format_info(formats, format) != NULL; } /* Convert formats array to GstCaps */ static GstCaps * get_format_caps(GArray *formats) { - GstVaapiImageFormat format; + const GstVaapiFormatInfo *fip; GstCaps *out_caps, *caps; guint i; @@ -329,8 +355,8 @@ get_format_caps(GArray *formats) return NULL; for (i = 0; i < formats->len; i++) { - format = g_array_index(formats, GstVaapiImageFormat, i); - caps = gst_vaapi_image_format_get_caps(format); + fip = &g_array_index(formats, GstVaapiFormatInfo, i); + caps = gst_vaapi_image_format_get_caps(fip->format); if (caps) gst_caps_append(out_caps, caps); } @@ -676,10 +702,10 @@ gst_vaapi_display_create(GstVaapiDisplay *display) GST_DEBUG(" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc)); priv->image_formats = - g_array_new(FALSE, FALSE, sizeof(GstVaapiImageFormat)); + g_array_new(FALSE, FALSE, sizeof(GstVaapiFormatInfo)); if (!priv->image_formats) goto end; - append_formats(priv->image_formats, formats, n); + append_formats(priv->image_formats, formats, NULL, n); g_array_sort(priv->image_formats, compare_yuv_formats); /* VA subpicture formats */ @@ -697,10 +723,10 @@ gst_vaapi_display_create(GstVaapiDisplay *display) GST_DEBUG(" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc)); priv->subpicture_formats = - g_array_new(FALSE, FALSE, sizeof(GstVaapiImageFormat)); + g_array_new(FALSE, FALSE, sizeof(GstVaapiFormatInfo)); if (!priv->subpicture_formats) goto end; - append_formats(priv->subpicture_formats, formats, n); + append_formats(priv->subpicture_formats, formats, NULL, n); g_array_sort(priv->subpicture_formats, compare_rgb_formats); if (!cached_info) { From 1307a5b4ef167869bccd3f66ce8ccea3166c4c97 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 4 Jan 2013 09:41:25 +0100 Subject: [PATCH 0997/3781] subpicture: add premultiplied-alpha and global-alpha feature flags. Add premultiplied-alpha and global-alpha feature flags, along with converters between VA-API and gstreamer-vaapi definitions. Another round of helpers is also necessary for GstVideoOverlayComposition API. --- gst-libs/gst/vaapi/gstvaapisubpicture.h | 15 +++++++++ gst-libs/gst/vaapi/gstvaapiutils.c | 45 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 8 +++++ 3 files changed, 68 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index e7a6dbfdca..7a2bdae70b 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -58,6 +58,21 @@ typedef struct _GstVaapiSubpicture GstVaapiSubpicture; typedef struct _GstVaapiSubpicturePrivate GstVaapiSubpicturePrivate; typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass; +/** + * GstVaapiSubpictureFlags: + * @GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA: + * subpicture has RGB pixels with pre-multiplied alpha + * @GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA: + * subpicture needs to be blended with some global-alpha value at + * rendering time + * + * The set of all subpicture rendering flags for #GstVaapiSubpicture. + */ +typedef enum { + GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA = (1 << 0), + GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA = (1 << 1), +} GstVaapiSubpictureFlags; + /** * GstVaapiSubpicture: * diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 996e328cc6..30d043501b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -24,6 +24,7 @@ #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapisurface.h" +#include "gstvaapisubpicture.h" #include #include @@ -202,6 +203,50 @@ string_of_VADisplayAttributeType(VADisplayAttribType attribute_type) return ""; } +/** + * from_GstVaapiSubpictureFlags: + * @flags: the #GstVaapiSubpictureFlags + * + * Converts #GstVaapiSubpictureFlags to flags suitable for + * vaAssociateSubpicture(). + */ +guint +from_GstVaapiSubpictureFlags(guint flags) +{ + guint va_flags = 0; + + if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) + va_flags |= VA_SUBPICTURE_GLOBAL_ALPHA; +#ifdef VA_SUBPICTURE_PREMULTIPLIED_ALPHA + if (flags & GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA) + flags |= VA_SUBPICTURE_PREMULTIPLIED_ALPHA; +#endif + return va_flags; +} + +/** + * to_GstVaapiSubpictureFlags: + * @flags: the #GstVaapiSubpictureFlags flags to translate + * + * Converts vaQuerySubpictureFormats() @flags to #GstVaapiSubpictureFlags + * flags. + * + * Return value: the #GstVaapiSubpictureFlags flags + */ +guint +to_GstVaapiSubpictureFlags(guint va_flags) +{ + guint flags = 0; + + if (va_flags & VA_SUBPICTURE_GLOBAL_ALPHA) + flags |= GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA; +#ifdef VA_SUBPICTURE_PREMULTIPLIED_ALPHA + if (va_flags & VA_SUBPICTURE_PREMULTIPLIED_ALPHA) + flags |= GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA; +#endif + return flags; +} + /** * from_GstVaapiSurfaceRenderFlags: * @flags: the #GstVaapiSurfaceRenderFlags diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 98d91e37e9..a5f96f1c1d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -73,6 +73,14 @@ G_GNUC_INTERNAL const char * string_of_VADisplayAttributeType(VADisplayAttribType attribute_type); +G_GNUC_INTERNAL +guint +from_GstVaapiSubpictureFlags(guint flags); + +G_GNUC_INTERNAL +guint +to_GstVaapiSubpictureFlags(guint va_flags); + G_GNUC_INTERNAL guint from_GstVaapiSurfaceRenderFlags(guint flags); From 1cd4a8fc046d4774fa1d53534fbb4e3b14ab3c36 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Tue, 15 May 2012 10:24:08 +0200 Subject: [PATCH 0998/3781] subpicture: add support for global-alpha. Add the necessary helpers in GstVaapiDisplay to determine whether subpictures with global alpha are supported or not. Also add accessors in GstVaapiSubpicture to address this feature. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidisplay.c | 23 +++- gst-libs/gst/vaapi/gstvaapidisplay.h | 3 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 148 +++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapisubpicture.h | 12 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- tests/image.c | 4 +- tests/test-subpicture.c | 2 +- 7 files changed, 178 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index a51c0b5e45..4677a79bdb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -719,14 +719,16 @@ gst_vaapi_display_create(GstVaapiDisplay *display) goto end; GST_DEBUG("%d subpicture formats", n); - for (i = 0; i < n; i++) + for (i = 0; i < n; i++) { GST_DEBUG(" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc)); + flags[i] = to_GstVaapiSubpictureFlags(flags[i]); + } priv->subpicture_formats = g_array_new(FALSE, FALSE, sizeof(GstVaapiFormatInfo)); if (!priv->subpicture_formats) goto end; - append_formats(priv->subpicture_formats, formats, NULL, n); + append_formats(priv->subpicture_formats, formats, flags, n); g_array_sort(priv->subpicture_formats, compare_rgb_formats); if (!cached_info) { @@ -1404,21 +1406,32 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) * gst_vaapi_display_has_subpicture_format: * @display: a #GstVaapiDisplay * @format: a #GstVaapiFormat + * @flags: #GstVaapiSubpictureFlags, or zero * - * Returns whether VA @display supports @format subpicture format. + * Returns whether VA @display supports @format subpicture format with + * the supplied @flags. * * Return value: %TRUE if VA @display supports @format subpicture format */ gboolean gst_vaapi_display_has_subpicture_format( GstVaapiDisplay *display, - GstVaapiImageFormat format + GstVaapiImageFormat format, + guint *flags_ptr ) { + const GstVaapiFormatInfo *fip; + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); g_return_val_if_fail(format, FALSE); - return find_format(display->priv->subpicture_formats, format); + fip = find_format_info(display->priv->subpicture_formats, format); + if (!fip) + return FALSE; + + if (flags_ptr) + *flags_ptr = fip->flags; + return TRUE; } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index d23b0ad94c..ddfb3750bc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -231,7 +231,8 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display); gboolean gst_vaapi_display_has_subpicture_format( GstVaapiDisplay *display, - GstVaapiImageFormat format + GstVaapiImageFormat format, + guint *flags_ptr ); gboolean diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index a09f246333..86d40dcdb0 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -44,11 +44,15 @@ G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, GST_VAAPI_TYPE_OBJECT) struct _GstVaapiSubpicturePrivate { GstVaapiImage *image; + guint flags; + gfloat global_alpha; }; enum { PROP_0, + PROP_FLAGS, + PROP_GLOBAL_ALPHA, PROP_IMAGE }; @@ -128,6 +132,13 @@ gst_vaapi_subpicture_set_property( GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object); switch (prop_id) { + case PROP_FLAGS: + subpicture->priv->flags = g_value_get_uint(value); + break; + case PROP_GLOBAL_ALPHA: + gst_vaapi_subpicture_set_global_alpha(subpicture, + g_value_get_float(value)); + break; case PROP_IMAGE: gst_vaapi_subpicture_set_image(subpicture, g_value_get_object(value)); break; @@ -148,6 +159,13 @@ gst_vaapi_subpicture_get_property( GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object); switch (prop_id) { + case PROP_FLAGS: + g_value_set_uint(value, subpicture->priv->flags); + break; + case PROP_GLOBAL_ALPHA: + g_value_set_float(value, + gst_vaapi_subpicture_get_global_alpha(subpicture)); + break; case PROP_IMAGE: g_value_set_object(value, gst_vaapi_subpicture_get_image(subpicture)); break; @@ -168,6 +186,34 @@ gst_vaapi_subpicture_class_init(GstVaapiSubpictureClass *klass) object_class->set_property = gst_vaapi_subpicture_set_property; object_class->get_property = gst_vaapi_subpicture_get_property; + /** + * GstVaapiSubpicture:flags: + * + * The #GstVaapiSubpictureFlags this subpicture requires. + */ + g_object_class_install_property + (object_class, + PROP_FLAGS, + g_param_spec_uint("flags", + "Flags", + "The GstVaapiSubpictureFlags this subpicture requires", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + /** + * GstVaapiSubpicture:global-alpha: + * + * The global-alpha value associated with this subpicture. + */ + g_object_class_install_property + (object_class, + PROP_GLOBAL_ALPHA, + g_param_spec_float("global-alpha", + "Global Alpha", + "The global-alpha value associated with this subpicture", + 0.0f, 1.0f, 1.0f, + G_PARAM_READWRITE)); + /** * GstVaapiSubpicture:image: * @@ -190,11 +236,13 @@ gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture) subpicture->priv = priv; priv->image = NULL; + priv->global_alpha = 1.0f; } /** * gst_vaapi_subpicture_new: * @image: a #GstVaapiImage + * @flags: #GstVaapiSubpictureFlags, or zero * * Creates a new #GstVaapiSubpicture with @image as source pixels. The * newly created object holds a reference on @image. @@ -202,17 +250,30 @@ gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture) * Return value: the newly allocated #GstVaapiSubpicture object */ GstVaapiSubpicture * -gst_vaapi_subpicture_new(GstVaapiImage *image) +gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags) { + GstVaapiDisplay *display; + GstVaapiImageFormat format; + guint va_flags; + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); GST_DEBUG("create from image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(image))); + display = GST_VAAPI_OBJECT_DISPLAY(image); + format = gst_vaapi_image_get_format(image); + if (!gst_vaapi_display_has_subpicture_format(display, format, &va_flags)) + return NULL; + if (flags & ~va_flags) + return NULL; + return g_object_new(GST_VAAPI_TYPE_SUBPICTURE, - "display", GST_VAAPI_OBJECT_DISPLAY(image), - "id", GST_VAAPI_ID(VA_INVALID_ID), - "image", image, + "display", GST_VAAPI_OBJECT_DISPLAY(image), + "id", GST_VAAPI_ID(VA_INVALID_ID), + "flags", flags, + "global-alpha", 1.0f, + "image", image, NULL); } @@ -273,7 +334,7 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( return NULL; } - subpicture = gst_vaapi_subpicture_new(image); + subpicture = gst_vaapi_subpicture_new(image, 0); g_object_unref(image); return subpicture; } @@ -294,6 +355,22 @@ gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture) return GST_VAAPI_OBJECT_ID(subpicture); } +/** + * gst_vaapi_subpicture_get_flags: + * @subpicture: a #GstVaapiSubpicture + * + * Returns the @subpicture flags. + * + * Return value: the @subpicture flags + */ +guint +gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture) +{ + g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 0); + + return subpicture->priv->flags; +} + /** * gst_vaapi_subpicture_get_image: * @subpicture: a #GstVaapiSubpicture @@ -332,3 +409,64 @@ gst_vaapi_subpicture_set_image( subpicture->priv->image = g_object_ref(image); gst_vaapi_subpicture_create(subpicture); } + +/** + * gst_vaapi_subpicture_get_global_alpha: + * @subpicture: a #GstVaapiSubpicture + * + * Returns the value of global_alpha, set for this @subpicture. + * + * Return value: the global_alpha value of this @subpicture + */ +gfloat +gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture) +{ + g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 1.0); + + return subpicture->priv->global_alpha; +} + +/** + * gst_vaapi_subpicture_set_global_alpha: + * @subpicture: a #GstVaapiSubpicture + * @global_alpha: value for global-alpha (range: 0.0 to 1.0, inclusive) + * + * Sets the global_alpha value of @subpicture. This function calls + * vaSetSubpictureGlobalAlpha() if the format of @subpicture, i.e. + * the current VA driver supports it. + * + * Return value: %TRUE if global_alpha could be set, %FALSE otherwise + */ +gboolean +gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture, + gfloat global_alpha) +{ + GstVaapiSubpicturePrivate *priv; + GstVaapiDisplay *display; + VAStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); + + priv = subpicture->priv; + + if (!(priv->flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA)) + return FALSE; + + if (priv->global_alpha == global_alpha) + return TRUE; + + display = GST_VAAPI_OBJECT_DISPLAY(subpicture); + + GST_VAAPI_DISPLAY_LOCK(display); + status = vaSetSubpictureGlobalAlpha( + GST_VAAPI_DISPLAY_VADISPLAY(display), + GST_VAAPI_OBJECT_ID(subpicture), + global_alpha + ); + GST_VAAPI_DISPLAY_UNLOCK(display); + if (!vaapi_check_status(status, "vaSetSubpictureGlobalAlpha()")) + return FALSE; + + priv->global_alpha = global_alpha; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 7a2bdae70b..80c05d3824 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -99,7 +99,7 @@ GType gst_vaapi_subpicture_get_type(void) G_GNUC_CONST; GstVaapiSubpicture * -gst_vaapi_subpicture_new(GstVaapiImage *image); +gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags); GstVaapiSubpicture * gst_vaapi_subpicture_new_from_overlay_rectangle( @@ -110,6 +110,9 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( GstVaapiID gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture); +guint +gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture); + GstVaapiImage * gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture); @@ -119,6 +122,13 @@ gst_vaapi_subpicture_set_image( GstVaapiImage *image ); +gfloat +gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture); + +gboolean +gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture, + gfloat global_alpha); + G_END_DECLS #endif /* GST_VAAPI_SUBPICTURE_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 745495d47e..46ad45e067 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -723,7 +723,7 @@ _gst_vaapi_surface_associate_subpicture( &surface_id, 1, src_rect->x, src_rect->y, src_rect->width, src_rect->height, dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height, - 0 + from_GstVaapiSubpictureFlags(gst_vaapi_subpicture_get_flags(subpicture)) ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaAssociateSubpicture()")) diff --git a/tests/image.c b/tests/image.c index 39a8ac5e7e..289e2a30b8 100644 --- a/tests/image.c +++ b/tests/image.c @@ -341,12 +341,12 @@ image_upload(GstVaapiImage *image, GstVaapiSurface *surface) g_print("could not upload %" GST_FOURCC_FORMAT" image to surface\n", GST_FOURCC_ARGS(format)); - if (!gst_vaapi_display_has_subpicture_format(display, format)) + if (!gst_vaapi_display_has_subpicture_format(display, format, NULL)) return FALSE; g_print("trying as a subpicture\n"); - subpicture = gst_vaapi_subpicture_new(image); + subpicture = gst_vaapi_subpicture_new(image, 0); if (!subpicture) g_error("could not create VA subpicture"); diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 11d018b973..6a1620ca80 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -192,7 +192,7 @@ main(int argc, char *argv[]) if (!gst_vaapi_image_update_from_buffer (subtitle_image, buffer, NULL)) g_error ("could not update VA image with subtitle data"); - subpicture = gst_vaapi_subpicture_new (subtitle_image); + subpicture = gst_vaapi_subpicture_new (subtitle_image, 0); /* We position it as a subtitle, centered at the bottom. */ sub_rect.x = (surf_width - subinfo.width) / 2; From 2d2334afed32abdcaf9396edb5fa8a3f27ea0db1 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Tue, 15 May 2012 10:24:08 +0200 Subject: [PATCH 0999/3781] overlay: add support for global-alpha. Handle global-alpha from GstVideoOverlayComposition API. Likewise, the same code path could also work for premultiplied-alpha but this was not tested. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapisubpicture.c | 31 +++++++++++++------ gst-libs/gst/vaapi/gstvaapiutils.c | 40 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 8 +++++ 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 86d40dcdb0..99429c1dfc 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -300,24 +300,29 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( GstVaapiImage *image; GstVaapiImageRaw raw_image; GstBuffer *buffer; + gfloat global_alpha; guint width, height, stride; + guint hw_flags, flags; g_return_val_if_fail(GST_IS_VIDEO_OVERLAY_RECTANGLE(rect), NULL); - buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb( - rect, - &width, &height, &stride, - GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE - ); - if (!buffer) - return NULL; - /* XXX: use gst_vaapi_image_format_from_video() */ #if G_BYTE_ORDER == G_LITTLE_ENDIAN format = GST_VAAPI_IMAGE_BGRA; #else format = GST_VAAPI_IMAGE_ARGB; #endif + if (!gst_vaapi_display_has_subpicture_format(display, format, &hw_flags)) + return NULL; + + flags = hw_flags & from_GstVideoOverlayFormatFlags( + gst_video_overlay_rectangle_get_flags(rect)); + + buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect, + &width, &height, &stride, to_GstVideoOverlayFormatFlags(flags)); + if (!buffer) + return NULL; + image = gst_vaapi_image_new(display, format, width, height); if (!image) return NULL; @@ -334,8 +339,16 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( return NULL; } - subpicture = gst_vaapi_subpicture_new(image, 0); + subpicture = gst_vaapi_subpicture_new(image, flags); g_object_unref(image); + if (!subpicture) + return NULL; + + if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) { + global_alpha = gst_video_overlay_rectangle_get_global_alpha(rect); + if (!gst_vaapi_subpicture_set_global_alpha(subpicture, global_alpha)) + return NULL; + } return subpicture; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 30d043501b..f69036e738 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -247,6 +247,46 @@ to_GstVaapiSubpictureFlags(guint va_flags) return flags; } +/** + * from_GstVideoOverlayFormatFlags: + * @flags: the #GstVideoOverlayFormatFlags flags to translate + * + * Converts #GstVaapiSubpictureFlags to #GstVaapiSubpictureFlags. + * + * Return value: the #GstVaapiSubpictureFlags flags + */ +guint +from_GstVideoOverlayFormatFlags(guint ovl_flags) +{ + guint flags = 0; + + if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA) + flags |= GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA; + if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA) + flags |= GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA; + return flags; +} + +/** + * to_GstVideoOverlayFormatFlags: + * @flags: the #GstVaapiSubpictureFlags flags to translate + * + * Converts #GstVaapiSubpictureFlags to #GstVideoOverlayFormatFlags. + * + * Return value: the #GstVideoOverlayFormatFlags flags + */ +guint +to_GstVideoOverlayFormatFlags(guint flags) +{ + guint ovl_flags = 0; + + if (flags & GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA) + ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA; + if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) + ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA; + return ovl_flags; +} + /** * from_GstVaapiSurfaceRenderFlags: * @flags: the #GstVaapiSurfaceRenderFlags diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index a5f96f1c1d..791fe1460d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -81,6 +81,14 @@ G_GNUC_INTERNAL guint to_GstVaapiSubpictureFlags(guint va_flags); +G_GNUC_INTERNAL +guint +from_GstVideoOverlayFormatFlags(guint ovl_flags); + +G_GNUC_INTERNAL +guint +to_GstVideoOverlayFormatFlags(guint flags); + G_GNUC_INTERNAL guint from_GstVaapiSurfaceRenderFlags(guint flags); From ad6cdc0b52e8d738ebe65dbfe0bdba0c65a0b551 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 10 Jan 2013 13:41:39 +0100 Subject: [PATCH 1000/3781] overlay: simplify caching of GstVideoOverlayComposition objects. Create the GPtrArray once in the _init() function and destroy it only in the _finalize() function. Then use overlay_clear() to remove all subpicture associations for intermediate updates, don't recreate the GPtrArray. Make GstVaapiOverlayRectangle a reference counted object. Also make sure that overlay_rectangle_new() actually creates and associates the VA subpicture. --- gst-libs/gst/vaapi/gstvaapicontext.c | 238 +++++++++++++++++---------- 1 file changed, 153 insertions(+), 85 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index fe15bdc914..186c3e387f 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -34,6 +34,7 @@ #include "gstvaapisurfacepool.h" #include "gstvaapiimage.h" #include "gstvaapisubpicture.h" +#include "gstvaapiminiobject.h" #include "gstvaapiutils.h" #include "gstvaapi_priv.h" @@ -51,8 +52,9 @@ typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle; struct _GstVaapiOverlayRectangle { GstVaapiContext *context; GstVaapiSubpicture *subpicture; - GstVaapiRectangle rect; + GstVaapiRectangle render_rect; guint seq_num; + guint is_associated : 1; }; /* XXX: optimize for the effective number of reference frames */ @@ -92,50 +94,151 @@ get_max_ref_frames(GstVaapiProfile profile) return ref_frames; } +#define overlay_rectangle_ref(overlay) \ + gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(overlay)) + +#define overlay_rectangle_unref(overlay) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(overlay)) + +#define overlay_rectangle_replace(old_overlay_ptr, new_overlay) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_overlay_ptr), \ + (GstVaapiMiniObject *)(new_overlay)) + +static void +overlay_rectangle_finalize(GstVaapiOverlayRectangle *overlay); + +static gboolean +overlay_rectangle_associate(GstVaapiOverlayRectangle *overlay); + +static gboolean +overlay_rectangle_deassociate(GstVaapiOverlayRectangle *overlay); + +static inline const GstVaapiMiniObjectClass * +overlay_rectangle_class(void) +{ + static const GstVaapiMiniObjectClass GstVaapiOverlayRectangleClass = { + sizeof(GstVaapiOverlayRectangle), + (GDestroyNotify)overlay_rectangle_finalize + }; + return &GstVaapiOverlayRectangleClass; +} + static GstVaapiOverlayRectangle * -overlay_rectangle_new(GstVaapiContext *context) +overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context) { GstVaapiOverlayRectangle *overlay; + GstVaapiRectangle *render_rect; + guint width, height; + gint x, y; - overlay = g_slice_new0(GstVaapiOverlayRectangle); + overlay = (GstVaapiOverlayRectangle *) + gst_vaapi_mini_object_new0(overlay_rectangle_class()); if (!overlay) return NULL; - overlay->context = context; + overlay->context = context; + overlay->seq_num = gst_video_overlay_rectangle_get_seqnum(rect); + + overlay->subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle( + GST_VAAPI_OBJECT_DISPLAY(context), rect); + if (!overlay->subpicture) + goto error; + + gst_video_overlay_rectangle_get_render_rectangle(rect, + &x, &y, &width, &height); + render_rect = &overlay->render_rect; + render_rect->x = x; + render_rect->y = y; + render_rect->width = width; + render_rect->height = height; + + if (!overlay_rectangle_associate(overlay)) { + GST_WARNING("could not render overlay rectangle %p", rect); + goto error; + } return overlay; + +error: + overlay_rectangle_unref(overlay); + return NULL; } static void -overlay_rectangle_destroy(GstVaapiOverlayRectangle *overlay) +overlay_rectangle_finalize(GstVaapiOverlayRectangle *overlay) { - GstVaapiContextPrivate *priv; - guint i; - - if (!overlay) - return; - priv = overlay->context->priv; - if (overlay->subpicture) { - if (priv->surfaces) { - GstVaapiSubpicture * const subpicture = overlay->subpicture; - for (i = 0; i < priv->surfaces->len; i++) { - GstVaapiSurface * const surface = - g_ptr_array_index(priv->surfaces, i); - gst_vaapi_surface_deassociate_subpicture(surface, subpicture); - } - } + overlay_rectangle_deassociate(overlay); g_object_unref(overlay->subpicture); overlay->subpicture = NULL; } - g_slice_free(GstVaapiOverlayRectangle, overlay); +} + +static gboolean +overlay_rectangle_associate(GstVaapiOverlayRectangle *overlay) +{ + GstVaapiSubpicture * const subpicture = overlay->subpicture; + GPtrArray * const surfaces = overlay->context->priv->surfaces; + guint i, n_associated; + + if (overlay->is_associated) + return TRUE; + + n_associated = 0; + for (i = 0; i < surfaces->len; i++) { + GstVaapiSurface * const surface = g_ptr_array_index(surfaces, i); + if (gst_vaapi_surface_associate_subpicture(surface, subpicture, + NULL, &overlay->render_rect)) + n_associated++; + } + + overlay->is_associated = TRUE; + return n_associated == surfaces->len; +} + +static gboolean +overlay_rectangle_deassociate(GstVaapiOverlayRectangle *overlay) +{ + GstVaapiSubpicture * const subpicture = overlay->subpicture; + GPtrArray * const surfaces = overlay->context->priv->surfaces; + guint i, n_associated; + + if (!overlay->is_associated) + return TRUE; + + n_associated = surfaces->len; + for (i = 0; i < surfaces->len; i++) { + GstVaapiSurface * const surface = g_ptr_array_index(surfaces, i); + if (gst_vaapi_surface_deassociate_subpicture(surface, subpicture)) + n_associated--; + } + + overlay->is_associated = FALSE; + return n_associated == 0; +} + +static inline GPtrArray * +overlay_new(void) +{ + return g_ptr_array_new_with_free_func( + (GDestroyNotify)gst_vaapi_mini_object_unref); } static void -destroy_overlay_cb(gpointer data, gpointer user_data) +overlay_destroy(GPtrArray **overlay_ptr) { - GstVaapiOverlayRectangle * const overlay = data; + GPtrArray * const overlay = *overlay_ptr; - overlay_rectangle_destroy(overlay); + if (!overlay) + return; + g_ptr_array_unref(overlay); + *overlay_ptr = NULL; +} + +static void +overlay_clear(GPtrArray *overlay) +{ + if (overlay && overlay->len > 0) + g_ptr_array_remove_range(overlay, 0, overlay->len); } static void @@ -143,12 +246,7 @@ gst_vaapi_context_destroy_overlay(GstVaapiContext *context) { GstVaapiContextPrivate * const priv = context->priv; - if (!priv->overlay) - return; - - g_ptr_array_foreach(priv->overlay, destroy_overlay_cb, priv); - g_ptr_array_free(priv->overlay, TRUE); - priv->overlay = NULL; + overlay_clear(priv->overlay); } static void @@ -219,11 +317,10 @@ gst_vaapi_context_create_overlay(GstVaapiContext *context) { GstVaapiContextPrivate * const priv = context->priv; - if (!priv->overlay) { - priv->overlay = g_ptr_array_new(); - if (!priv->overlay) - return FALSE; - } + if (!priv->overlay) + return FALSE; + + overlay_clear(priv->overlay); return TRUE; } @@ -377,7 +474,9 @@ static void gst_vaapi_context_finalize(GObject *object) { GstVaapiContext * const context = GST_VAAPI_CONTEXT(object); + GstVaapiContextPrivate * const priv = context->priv; + overlay_destroy(&priv->overlay); gst_vaapi_context_destroy(context); gst_vaapi_context_destroy_surfaces(context); @@ -516,7 +615,7 @@ gst_vaapi_context_init(GstVaapiContext *context) priv->config_id = VA_INVALID_ID; priv->surfaces = NULL; priv->surfaces_pool = NULL; - priv->overlay = NULL; + priv->overlay = overlay_new(); priv->profile = 0; priv->entrypoint = 0; priv->width = 0; @@ -869,9 +968,6 @@ gst_vaapi_context_composition_changed( GstVideoOverlayRectangle *rect; guint i, n_rectangles; - if (!priv->overlay || !composition) - return TRUE; - n_rectangles = gst_video_overlay_composition_n_rectangles(composition); if (priv->overlay->len != n_rectangles) return TRUE; @@ -907,69 +1003,41 @@ gst_vaapi_context_apply_composition( ) { GstVaapiContextPrivate *priv; - GstVideoOverlayRectangle *rect; - GstVaapiOverlayRectangle *overlay = NULL; - GstVaapiDisplay *display; - guint i, j, n_rectangles; + guint i, n_rectangles; g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE); priv = context->priv; + if (!priv->surfaces) return FALSE; - display = GST_VAAPI_OBJECT_DISPLAY(context); - if (!display) - return FALSE; - - if (!gst_vaapi_context_composition_changed(context, composition)) + if (!composition) { + if (priv->overlay->len > 0) + overlay_clear(priv->overlay); return TRUE; - gst_vaapi_context_destroy_overlay(context); - - if (!composition) + } + else if (!gst_vaapi_context_composition_changed(context, composition)) return TRUE; - if (!gst_vaapi_context_create_overlay(context)) - return FALSE; + + overlay_clear(priv->overlay); n_rectangles = gst_video_overlay_composition_n_rectangles(composition); for (i = 0; i < n_rectangles; i++) { - rect = gst_video_overlay_composition_get_rectangle(composition, i); + GstVideoOverlayRectangle * const rect = + gst_video_overlay_composition_get_rectangle(composition, i); + GstVaapiOverlayRectangle *overlay; - overlay = overlay_rectangle_new(context); + overlay = overlay_rectangle_new(rect, context); if (!overlay) { GST_WARNING("could not create VA overlay rectangle"); - return FALSE; - } - overlay->seq_num = gst_video_overlay_rectangle_get_seqnum(rect); - - overlay->subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle( - display, - rect - ); - if (!overlay->subpicture) { - overlay_rectangle_destroy(overlay); - return FALSE; - } - - gst_video_overlay_rectangle_get_render_rectangle( - rect, - (gint *)&overlay->rect.x, - (gint *)&overlay->rect.y, - &overlay->rect.width, - &overlay->rect.height - ); - - for (j = 0; j < priv->surfaces->len; j++) { - GstVaapiSurface * const surface = - g_ptr_array_index(priv->surfaces, j); - if (!gst_vaapi_surface_associate_subpicture(surface, - overlay->subpicture, NULL, &overlay->rect)) { - GST_WARNING("could not render overlay rectangle %p", rect); - overlay_rectangle_destroy(overlay); - return FALSE; - } + goto error; } g_ptr_array_add(priv->overlay, overlay); } return TRUE; + +error: + overlay_clear(priv->overlay); + return FALSE; } From a14d259060255febe46923a59482a6e7ff25b262 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 10 Jan 2013 18:42:37 +0100 Subject: [PATCH 1001/3781] overlay: optimize cache at the GstVideoOverlayRectangle level. We previously assumed that an overlay composition changed if the number of overlay rectangles in there actually changed, or that the rectangle was updated, and thus its seqnum was also updated. Now, we can cope with cases where the GstVideoOverlayComposition grew by one or a few more overlay rectangles, and the initial overlay rectangles are kept as is. --- gst-libs/gst/vaapi/gstvaapicontext.c | 128 +++++++++++++++++---------- 1 file changed, 83 insertions(+), 45 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 186c3e387f..db96dfb9e1 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -54,6 +54,7 @@ struct _GstVaapiOverlayRectangle { GstVaapiSubpicture *subpicture; GstVaapiRectangle render_rect; guint seq_num; + GstVideoOverlayRectangle *rect; guint is_associated : 1; }; @@ -62,7 +63,8 @@ struct _GstVaapiContextPrivate { VAConfigID config_id; GPtrArray *surfaces; GstVaapiVideoPool *surfaces_pool; - GPtrArray *overlay; + GPtrArray *overlays[2]; + guint overlay_id; GstVaapiProfile profile; GstVaapiEntrypoint entrypoint; guint width; @@ -94,6 +96,14 @@ get_max_ref_frames(GstVaapiProfile profile) return ref_frames; } +static inline void +gst_video_overlay_rectangle_replace(GstVideoOverlayRectangle **old_rect_ptr, + GstVideoOverlayRectangle *new_rect) +{ + gst_mini_object_replace((GstMiniObject **)old_rect_ptr, + GST_MINI_OBJECT_CAST(new_rect)); +} + #define overlay_rectangle_ref(overlay) \ gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(overlay)) @@ -138,6 +148,7 @@ overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context) overlay->context = context; overlay->seq_num = gst_video_overlay_rectangle_get_seqnum(rect); + overlay->rect = gst_video_overlay_rectangle_ref(rect); overlay->subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle( GST_VAAPI_OBJECT_DISPLAY(context), rect); @@ -166,6 +177,8 @@ error: static void overlay_rectangle_finalize(GstVaapiOverlayRectangle *overlay) { + gst_video_overlay_rectangle_unref(overlay->rect); + if (overlay->subpicture) { overlay_rectangle_deassociate(overlay); g_object_unref(overlay->subpicture); @@ -216,6 +229,25 @@ overlay_rectangle_deassociate(GstVaapiOverlayRectangle *overlay) return n_associated == 0; } +static gboolean +overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay, + GstVideoOverlayRectangle *rect) +{ + if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum(rect)) + return FALSE; + return TRUE; +} + +static gboolean +overlay_rectangle_update(GstVaapiOverlayRectangle *overlay, + GstVideoOverlayRectangle *rect) +{ + if (overlay_rectangle_changed_pixels(overlay, rect)) + return FALSE; + gst_video_overlay_rectangle_replace(&overlay->rect, rect); + return TRUE; +} + static inline GPtrArray * overlay_new(void) { @@ -241,12 +273,35 @@ overlay_clear(GPtrArray *overlay) g_ptr_array_remove_range(overlay, 0, overlay->len); } +static GstVaapiOverlayRectangle * +overlay_lookup(GPtrArray *overlays, GstVideoOverlayRectangle *rect) +{ + guint i; + + for (i = 0; i < overlays->len; i++) { + GstVaapiOverlayRectangle * const overlay = + g_ptr_array_index(overlays, i); + + if (overlay->rect == rect) + return overlay; + } + return NULL; +} + static void -gst_vaapi_context_destroy_overlay(GstVaapiContext *context) +gst_vaapi_context_clear_overlay(GstVaapiContext *context) { GstVaapiContextPrivate * const priv = context->priv; - overlay_clear(priv->overlay); + overlay_clear(priv->overlays[0]); + overlay_clear(priv->overlays[1]); + priv->overlay_id = 0; +} + +static inline void +gst_vaapi_context_destroy_overlay(GstVaapiContext *context) +{ + gst_vaapi_context_clear_overlay(context); } static void @@ -317,10 +372,10 @@ gst_vaapi_context_create_overlay(GstVaapiContext *context) { GstVaapiContextPrivate * const priv = context->priv; - if (!priv->overlay) + if (!priv->overlays[0] || !priv->overlays[1]) return FALSE; - overlay_clear(priv->overlay); + gst_vaapi_context_clear_overlay(context); return TRUE; } @@ -476,7 +531,8 @@ gst_vaapi_context_finalize(GObject *object) GstVaapiContext * const context = GST_VAAPI_CONTEXT(object); GstVaapiContextPrivate * const priv = context->priv; - overlay_destroy(&priv->overlay); + overlay_destroy(&priv->overlays[0]); + overlay_destroy(&priv->overlays[1]); gst_vaapi_context_destroy(context); gst_vaapi_context_destroy_surfaces(context); @@ -615,7 +671,8 @@ gst_vaapi_context_init(GstVaapiContext *context) priv->config_id = VA_INVALID_ID; priv->surfaces = NULL; priv->surfaces_pool = NULL; - priv->overlay = overlay_new(); + priv->overlays[0] = overlay_new(); + priv->overlays[1] = overlay_new(); priv->profile = 0; priv->entrypoint = 0; priv->width = 0; @@ -956,33 +1013,6 @@ gst_vaapi_context_find_surface_by_id(GstVaapiContext *context, GstVaapiID id) return NULL; } -/* Check if composition changed */ -static gboolean -gst_vaapi_context_composition_changed( - GstVaapiContext *context, - GstVideoOverlayComposition *composition -) -{ - GstVaapiContextPrivate * const priv = context->priv; - GstVaapiOverlayRectangle *overlay; - GstVideoOverlayRectangle *rect; - guint i, n_rectangles; - - n_rectangles = gst_video_overlay_composition_n_rectangles(composition); - if (priv->overlay->len != n_rectangles) - return TRUE; - - for (i = 0; i < n_rectangles; i++) { - rect = gst_video_overlay_composition_get_rectangle(composition, i); - g_return_val_if_fail(rect, TRUE); - overlay = g_ptr_array_index(priv->overlay, i); - g_return_val_if_fail(overlay, TRUE); - if (overlay->seq_num != gst_video_overlay_rectangle_get_seqnum(rect)) - return TRUE; - } - return FALSE; -} - /** * gst_vaapi_context_apply_composition: * @context: a #GstVaapiContext @@ -1003,6 +1033,7 @@ gst_vaapi_context_apply_composition( ) { GstVaapiContextPrivate *priv; + GPtrArray *curr_overlay, *next_overlay; guint i, n_rectangles; g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE); @@ -1013,14 +1044,13 @@ gst_vaapi_context_apply_composition( return FALSE; if (!composition) { - if (priv->overlay->len > 0) - overlay_clear(priv->overlay); + gst_vaapi_context_clear_overlay(context); return TRUE; } - else if (!gst_vaapi_context_composition_changed(context, composition)) - return TRUE; - overlay_clear(priv->overlay); + curr_overlay = priv->overlays[priv->overlay_id]; + next_overlay = priv->overlays[priv->overlay_id ^ 1]; + overlay_clear(next_overlay); n_rectangles = gst_video_overlay_composition_n_rectangles(composition); for (i = 0; i < n_rectangles; i++) { @@ -1028,16 +1058,24 @@ gst_vaapi_context_apply_composition( gst_video_overlay_composition_get_rectangle(composition, i); GstVaapiOverlayRectangle *overlay; - overlay = overlay_rectangle_new(rect, context); - if (!overlay) { - GST_WARNING("could not create VA overlay rectangle"); - goto error; + overlay = overlay_lookup(curr_overlay, rect); + if (overlay && overlay_rectangle_update(overlay, rect)) + overlay_rectangle_ref(overlay); + else { + overlay = overlay_rectangle_new(rect, context); + if (!overlay) { + GST_WARNING("could not create VA overlay rectangle"); + goto error; + } } - g_ptr_array_add(priv->overlay, overlay); + g_ptr_array_add(next_overlay, overlay); } + + overlay_clear(curr_overlay); + priv->overlay_id ^= 1; return TRUE; error: - overlay_clear(priv->overlay); + gst_vaapi_context_clear_overlay(context); return FALSE; } From e876d9a5814be41a3f258214b0d24bb2b82707df Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 11 Jan 2013 11:12:26 +0100 Subject: [PATCH 1002/3781] overlay: fix check for pixels buffer change. A GstVideoOverlayRectangle is created whenever the underlying pixels data change. However, when global-alpha is supported, it is possible to re-use the same GstVideoOverlayRectangle but with a change to the global-alpha value. This process causes a change of sequence number, so we can no longer check for that. Still, if sequence numbers did not change, then there was no change in global-alpha either. So, we need a way to compare the underlying GstBuffer pointers. There is no API to retrieve the original pixels buffer from a GstVideoOverlayRectangle. So, we use the following heuristics: 1. Use gst_video_overlay_rectangle_get_pixels_unscaled_argb() with the same format flags from which the GstVideoOverlayRectangle was created. This will work if there was no prior consumer of the GstVideoOverlayRectangle with alternate (non-"native") format flags. 2. In overlay_rectangle_has_changed_pixels(), we have to use the same gst_video_overlay_rectangle_get_pixels_unscaled_argb() function but with flags that match the subpicture. This is needed to cope with platforms that don't support global-alpha in HW, so the gst-video layer takes care of that and fixes this up with a possibly new GstBuffer, and hence pixels data (or) in-place by caching the current global-alpha value applied. So we have to determine the rectangle was previously used, based on what previous flags were used to retrieve the ARGB pixels buffer. --- gst-libs/gst/vaapi/gstvaapicontext.c | 33 +++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index db96dfb9e1..737c4aca1f 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -54,6 +54,7 @@ struct _GstVaapiOverlayRectangle { GstVaapiSubpicture *subpicture; GstVaapiRectangle render_rect; guint seq_num; + GstBuffer *rect_buffer; GstVideoOverlayRectangle *rect; guint is_associated : 1; }; @@ -104,6 +105,21 @@ gst_video_overlay_rectangle_replace(GstVideoOverlayRectangle **old_rect_ptr, GST_MINI_OBJECT_CAST(new_rect)); } +static inline GstBuffer * +gst_video_overlay_rectangle_get_pixels_raw(GstVideoOverlayRectangle *rect) +{ + guint width, height, stride, flags; + + flags = gst_video_overlay_rectangle_get_flags(rect); + + /* Try to retrieve the original buffer that was passed to + gst_video_overlay_rectangle_new_argb(). This will only work if + there was no previous user that required pixels with non native + alpha type */ + return gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect, + &width, &height, &stride, flags); +} + #define overlay_rectangle_ref(overlay) \ gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(overlay)) @@ -150,6 +166,11 @@ overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context) overlay->seq_num = gst_video_overlay_rectangle_get_seqnum(rect); overlay->rect = gst_video_overlay_rectangle_ref(rect); + gst_buffer_replace(&overlay->rect_buffer, + gst_video_overlay_rectangle_get_pixels_raw(rect)); + if (!overlay->rect_buffer) + goto error; + overlay->subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle( GST_VAAPI_OBJECT_DISPLAY(context), rect); if (!overlay->subpicture) @@ -177,6 +198,7 @@ error: static void overlay_rectangle_finalize(GstVaapiOverlayRectangle *overlay) { + gst_buffer_replace(&overlay->rect_buffer, NULL); gst_video_overlay_rectangle_unref(overlay->rect); if (overlay->subpicture) { @@ -233,9 +255,18 @@ static gboolean overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay, GstVideoOverlayRectangle *rect) { + guint width, height, stride, flags; + GstBuffer *buffer; + if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum(rect)) return FALSE; - return TRUE; + + flags = to_GstVideoOverlayFormatFlags( + gst_vaapi_subpicture_get_flags(overlay->subpicture)); + + buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect, + &width, &height, &stride, flags); + return GST_BUFFER_DATA(overlay->rect_buffer) != GST_BUFFER_DATA(buffer); } static gboolean From e6390d6e5f88a00243e8d1c61bbd9b1d58ede03e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 11 Jan 2013 11:53:05 +0100 Subject: [PATCH 1003/3781] overlay: detect render-rect changes. Don't re-upload VA subpicture if only the render rectangle changed. Rather deassociate the subpicture and re-associate it with the new render rectangle. --- gst-libs/gst/vaapi/gstvaapicontext.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 737c4aca1f..5967738f5b 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -269,12 +269,40 @@ overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay, return GST_BUFFER_DATA(overlay->rect_buffer) != GST_BUFFER_DATA(buffer); } +static gboolean +overlay_rectangle_update_render_rect(GstVaapiOverlayRectangle *overlay, + GstVideoOverlayRectangle *rect) +{ + GstVaapiRectangle * const render_rect = &overlay->render_rect; + guint width, height; + gint x, y; + + gst_video_overlay_rectangle_get_render_rectangle(rect, + &x, &y, &width, &height); + + if (x == render_rect->x && + y == render_rect->y && + width == render_rect->width && + height == render_rect->height) + return TRUE; + + overlay_rectangle_deassociate(overlay); + + render_rect->x = x; + render_rect->y = y; + render_rect->width = width; + render_rect->height = height; + return overlay_rectangle_associate(overlay); +} + static gboolean overlay_rectangle_update(GstVaapiOverlayRectangle *overlay, GstVideoOverlayRectangle *rect) { if (overlay_rectangle_changed_pixels(overlay, rect)) return FALSE; + if (!overlay_rectangle_update_render_rect(overlay, rect)) + return FALSE; gst_video_overlay_rectangle_replace(&overlay->rect, rect); return TRUE; } From 2ecb95562638f92209258e79d361d8da8be851c7 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Tue, 15 May 2012 10:24:08 +0200 Subject: [PATCH 1004/3781] overlay: fix support for global-alpha. Fix support for global-alpha subpictures. The previous changes brought the ability to check for GstVideoOverlayRectangle changes by comparing the underlying pixel buffer pointers. If sequence number and pixel data did not change, then this is an indication that only the global-alpha value changed. Now, try to update the underlying VA subpicture global-alpha value. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapicontext.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 5967738f5b..d300fb46fd 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -295,6 +295,17 @@ overlay_rectangle_update_render_rect(GstVaapiOverlayRectangle *overlay, return overlay_rectangle_associate(overlay); } +static inline gboolean +overlay_rectangle_update_global_alpha(GstVaapiOverlayRectangle *overlay, + GstVideoOverlayRectangle *rect) +{ + const guint flags = gst_video_overlay_rectangle_get_flags(rect); + if (!(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)) + return TRUE; + return gst_vaapi_subpicture_set_global_alpha(overlay->subpicture, + gst_video_overlay_rectangle_get_global_alpha(rect)); +} + static gboolean overlay_rectangle_update(GstVaapiOverlayRectangle *overlay, GstVideoOverlayRectangle *rect) @@ -303,6 +314,8 @@ overlay_rectangle_update(GstVaapiOverlayRectangle *overlay, return FALSE; if (!overlay_rectangle_update_render_rect(overlay, rect)) return FALSE; + if (!overlay_rectangle_update_global_alpha(overlay, rect)) + return FALSE; gst_video_overlay_rectangle_replace(&overlay->rect, rect); return TRUE; } From 7e1a8eabfeaa4e7ca7f3998881d5b35d23a2b64f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 11 Jan 2013 15:19:45 +0100 Subject: [PATCH 1005/3781] overlay: fix ordering of composition layers. Make sure to maintain the association order of composition layers when GstVideoOverlayRectangle objects are kept around (cached). --- gst-libs/gst/vaapi/gstvaapicontext.c | 51 +++++++++++++++++++--------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index d300fb46fd..b69d4d57e2 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -54,6 +54,7 @@ struct _GstVaapiOverlayRectangle { GstVaapiSubpicture *subpicture; GstVaapiRectangle render_rect; guint seq_num; + guint layer_id; GstBuffer *rect_buffer; GstVideoOverlayRectangle *rect; guint is_associated : 1; @@ -150,7 +151,8 @@ overlay_rectangle_class(void) } static GstVaapiOverlayRectangle * -overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context) +overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context, + guint layer_id) { GstVaapiOverlayRectangle *overlay; GstVaapiRectangle *render_rect; @@ -164,6 +166,7 @@ overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context) overlay->context = context; overlay->seq_num = gst_video_overlay_rectangle_get_seqnum(rect); + overlay->layer_id = layer_id; overlay->rect = gst_video_overlay_rectangle_ref(rect); gst_buffer_replace(&overlay->rect_buffer, @@ -183,11 +186,6 @@ overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context) render_rect->y = y; render_rect->width = width; render_rect->height = height; - - if (!overlay_rectangle_associate(overlay)) { - GST_WARNING("could not render overlay rectangle %p", rect); - goto error; - } return overlay; error: @@ -270,7 +268,7 @@ overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay, } static gboolean -overlay_rectangle_update_render_rect(GstVaapiOverlayRectangle *overlay, +overlay_rectangle_changed_render_rect(GstVaapiOverlayRectangle *overlay, GstVideoOverlayRectangle *rect) { GstVaapiRectangle * const render_rect = &overlay->render_rect; @@ -284,15 +282,13 @@ overlay_rectangle_update_render_rect(GstVaapiOverlayRectangle *overlay, y == render_rect->y && width == render_rect->width && height == render_rect->height) - return TRUE; - - overlay_rectangle_deassociate(overlay); + return FALSE; render_rect->x = x; render_rect->y = y; render_rect->width = width; render_rect->height = height; - return overlay_rectangle_associate(overlay); + return TRUE; } static inline gboolean @@ -308,12 +304,12 @@ overlay_rectangle_update_global_alpha(GstVaapiOverlayRectangle *overlay, static gboolean overlay_rectangle_update(GstVaapiOverlayRectangle *overlay, - GstVideoOverlayRectangle *rect) + GstVideoOverlayRectangle *rect, gboolean *reassociate_ptr) { if (overlay_rectangle_changed_pixels(overlay, rect)) return FALSE; - if (!overlay_rectangle_update_render_rect(overlay, rect)) - return FALSE; + if (overlay_rectangle_changed_render_rect(overlay, rect)) + *reassociate_ptr = TRUE; if (!overlay_rectangle_update_global_alpha(overlay, rect)) return FALSE; gst_video_overlay_rectangle_replace(&overlay->rect, rect); @@ -360,6 +356,21 @@ overlay_lookup(GPtrArray *overlays, GstVideoOverlayRectangle *rect) return NULL; } +static gboolean +overlay_reassociate(GPtrArray *overlays) +{ + guint i; + + for (i = 0; i < overlays->len; i++) + overlay_rectangle_deassociate(g_ptr_array_index(overlays, i)); + + for (i = 0; i < overlays->len; i++) { + if (!overlay_rectangle_associate(g_ptr_array_index(overlays, i))) + return FALSE; + } + return TRUE; +} + static void gst_vaapi_context_clear_overlay(GstVaapiContext *context) { @@ -1107,6 +1118,7 @@ gst_vaapi_context_apply_composition( GstVaapiContextPrivate *priv; GPtrArray *curr_overlay, *next_overlay; guint i, n_rectangles; + gboolean reassociate = FALSE; g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE); @@ -1131,20 +1143,27 @@ gst_vaapi_context_apply_composition( GstVaapiOverlayRectangle *overlay; overlay = overlay_lookup(curr_overlay, rect); - if (overlay && overlay_rectangle_update(overlay, rect)) + if (overlay && overlay_rectangle_update(overlay, rect, &reassociate)) { overlay_rectangle_ref(overlay); + if (overlay->layer_id != i) + reassociate = TRUE; + } else { - overlay = overlay_rectangle_new(rect, context); + overlay = overlay_rectangle_new(rect, context, i); if (!overlay) { GST_WARNING("could not create VA overlay rectangle"); goto error; } + reassociate = TRUE; } g_ptr_array_add(next_overlay, overlay); } overlay_clear(curr_overlay); priv->overlay_id ^= 1; + + if (reassociate && !overlay_reassociate(next_overlay)) + return FALSE; return TRUE; error: From d9111eeaf5af485c2ea7b23c0b0c3385e46a623e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 10 Jan 2013 11:22:38 +0100 Subject: [PATCH 1006/3781] tests: add decoder helpers. --- tests/Makefile.am | 22 +++-- tests/decoder.c | 210 ++++++++++++++++++++++++++++++++++++++++++++ tests/decoder.h | 39 ++++++++ tests/test-decode.c | 122 +++---------------------- 4 files changed, 274 insertions(+), 119 deletions(-) create mode 100644 tests/decoder.c create mode 100644 tests/decoder.h diff --git a/tests/Makefile.am b/tests/Makefile.am index fc258eed1a..afe894db88 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -57,25 +57,28 @@ TEST_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-@GST_MAJORMINOR@.la endif -test_codecs_source_c = \ +test_utils_dec_source_c = \ + decoder.c \ test-h264.c \ test-jpeg.c \ test-mpeg2.c \ test-mpeg4.c \ test-vc1.c \ $(NULL) -test_codecs_source_h = $(test_codecs_source_c:%.c=%.h) test-decode.h +test_utils_dec_source_h = $(test_utils_dec_source_c:%.c=%.h) test-decode.h -test_utils_source_c = image.c output.c $(test_codecs_source_c) -test_utils_source_h = image.h output.h $(test_codecs_source_h) +test_utils_source_c = image.c output.c +test_utils_source_h = image.h output.h -noinst_LTLIBRARIES = libutils.la +noinst_LTLIBRARIES = libutils.la libutils_dec.la libutils_la_SOURCES = $(test_utils_source_c) libutils_la_CFLAGS = $(TEST_CFLAGS) +libutils_dec_la_SOURCES = $(test_utils_dec_source_c) +libutils_dec_la_CFLAGS = $(TEST_CFLAGS) -test_decode_SOURCES = test-decode.c $(test_codecs_source_c) +test_decode_SOURCES = test-decode.c test_decode_CFLAGS = $(TEST_CFLAGS) -test_decode_LDADD = libutils.la $(TEST_LIBS) +test_decode_LDADD = libutils.la libutils_dec.la $(TEST_LIBS) test_display_SOURCES = test-display.c test_display_CFLAGS = $(TEST_CFLAGS) @@ -98,8 +101,9 @@ test_textures_CFLAGS = $(TEST_CFLAGS) test_textures_LDADD = libutils.la $(TEST_LIBS) EXTRA_DIST = \ - test-subpicture-data.h \ - $(test_utils_source_h) \ + test-subpicture-data.h \ + $(test_utils_dec_source_h) \ + $(test_utils_source_h) \ $(NULL) # Extra clean files so that maintainer-clean removes *everything* diff --git a/tests/decoder.c b/tests/decoder.c new file mode 100644 index 0000000000..17e2ad89cd --- /dev/null +++ b/tests/decoder.c @@ -0,0 +1,210 @@ +/* + * decoder.h - Decoder utilities for the tests + * + * Copyright (C) 2013 Intel Corporation + * + * 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 "config.h" +#include +#include +#include +#include +#include +#include +#include "decoder.h" +#include "test-jpeg.h" +#include "test-mpeg2.h" +#include "test-mpeg4.h" +#include "test-h264.h" +#include "test-vc1.h" + +typedef void (*GetVideoInfoFunc)(VideoDecodeInfo *info); + +typedef struct _CodecDefs CodecDefs; +struct _CodecDefs { + const gchar *codec_str; + GetVideoInfoFunc get_video_info; +}; + +static const CodecDefs g_codec_defs[] = { +#define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info } + INIT_FUNCS(jpeg), + INIT_FUNCS(mpeg2), + INIT_FUNCS(mpeg4), + INIT_FUNCS(h264), + INIT_FUNCS(vc1), +#undef INIT_FUNCS + { NULL, } +}; + +static const CodecDefs * +find_codec_defs(const gchar *codec_str) +{ + const CodecDefs *c; + for (c = g_codec_defs; c->codec_str; c++) + if (strcmp(codec_str, c->codec_str) == 0) + return c; + return NULL; +} + +#define CODEC_DEFS_KEY "codec-defs" + +static inline const CodecDefs * +get_codec_defs(GstVaapiDecoder *decoder) +{ + return g_object_get_data(G_OBJECT(decoder), CODEC_DEFS_KEY); +} + +static inline void +set_codec_defs(GstVaapiDecoder *decoder, const CodecDefs *c) +{ + g_object_set_data(G_OBJECT(decoder), CODEC_DEFS_KEY, (gpointer)c); +} + +GstVaapiDecoder * +decoder_new(GstVaapiDisplay *display, const gchar *codec_name) +{ + GstVaapiDecoder *decoder; + const CodecDefs *codec; + GstCaps *caps; + VideoDecodeInfo info; + + if (!codec_name) + codec_name = "h264"; + + codec = find_codec_defs(codec_name); + if (!codec) { + GST_ERROR("failed to find %s codec data", codec_name); + return NULL; + } + + codec->get_video_info(&info); + caps = gst_vaapi_profile_get_caps(info.profile); + if (!caps) { + GST_ERROR("failed to create decoder caps"); + return NULL; + } + + if (info.width > 0 && info.height > 0) + gst_caps_set_simple(caps, + "width", G_TYPE_INT, info.width, + "height", G_TYPE_INT, info.height, + NULL); + + switch (gst_vaapi_profile_get_codec(info.profile)) { + case GST_VAAPI_CODEC_H264: + decoder = gst_vaapi_decoder_h264_new(display, caps); + break; +#if USE_JPEG_DECODER + case GST_VAAPI_CODEC_JPEG: + decoder = gst_vaapi_decoder_jpeg_new(display, caps); + break; +#endif + case GST_VAAPI_CODEC_MPEG2: + decoder = gst_vaapi_decoder_mpeg2_new(display, caps); + break; + case GST_VAAPI_CODEC_MPEG4: + decoder = gst_vaapi_decoder_mpeg4_new(display, caps); + break; + case GST_VAAPI_CODEC_VC1: + decoder = gst_vaapi_decoder_vc1_new(display, caps); + break; + default: + decoder = NULL; + break; + } + gst_caps_unref(caps); + if (!decoder) { + GST_ERROR("failed to create %s decoder", codec->codec_str); + return NULL; + } + + set_codec_defs(decoder, codec); + return decoder; +} + +gboolean +decoder_put_buffers(GstVaapiDecoder *decoder) +{ + const CodecDefs *codec; + VideoDecodeInfo info; + GstBuffer *buffer; + gboolean success; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); + + codec = get_codec_defs(decoder); + g_return_val_if_fail(codec != NULL, FALSE); + + buffer = gst_buffer_new(); + if (!buffer) { + GST_ERROR("failed to create encoded data buffer"); + return FALSE; + } + + codec->get_video_info(&info); + gst_buffer_set_data(buffer, (guchar *)info.data, info.data_size); + + success = gst_vaapi_decoder_put_buffer(decoder, buffer); + gst_buffer_unref(buffer); + if (!success) { + GST_ERROR("failed to send video data to the decoder"); + return FALSE; + } + + if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) { + GST_ERROR("failed to submit to the decoder"); + return FALSE; + } + return TRUE; +} + +GstVaapiSurface * +decoder_get_surface(GstVaapiDecoder *decoder) +{ + GstVaapiSurface *surface; + GstVaapiSurfaceProxy *proxy; + GstVaapiDecoderStatus status; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + status = gst_vaapi_decoder_get_surface(decoder, &proxy); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_ERROR("failed to get decoded surface (decoder status %d)", status); + return NULL; + } + + /* Note: we only have a single I-frame to decode, so this is fine + to just release the surface proxy right away */ + surface = gst_vaapi_surface_proxy_get_surface(proxy); + gst_vaapi_surface_proxy_unref(proxy); + return surface; +} + +const gchar * +decoder_get_codec_name(GstVaapiDecoder *decoder) +{ + const CodecDefs *codec; + + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + codec = get_codec_defs(decoder); + g_return_val_if_fail(codec != NULL, FALSE); + + return codec->codec_str; +} diff --git a/tests/decoder.h b/tests/decoder.h new file mode 100644 index 0000000000..7ab95719f2 --- /dev/null +++ b/tests/decoder.h @@ -0,0 +1,39 @@ +/* + * decoder.h - Decoder utilities for the tests + * + * Copyright (C) 2013 Intel Corporation + * + * 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 DECODER_H +#define DECODER_H + +#include + +GstVaapiDecoder * +decoder_new(GstVaapiDisplay *display, const gchar *codec_name); + +gboolean +decoder_put_buffers(GstVaapiDecoder *decoder); + +GstVaapiSurface * +decoder_get_surface(GstVaapiDecoder *decoder); + +const gchar * +decoder_get_codec_name(GstVaapiDecoder *decoder); + +#endif /* DECODER_H */ diff --git a/tests/test-decode.c b/tests/test-decode.c index f855a146ad..4afed15c12 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -22,52 +22,13 @@ #include "config.h" #include -#include #include -#include -#include -#include -#include -#include -#include "test-jpeg.h" -#include "test-mpeg2.h" -#include "test-mpeg4.h" -#include "test-h264.h" -#include "test-vc1.h" +#include "decoder.h" #include "output.h" /* Set to 1 to check display cache works (shared VA display) */ #define CHECK_DISPLAY_CACHE 1 -typedef void (*GetVideoInfoFunc)(VideoDecodeInfo *info); - -typedef struct _CodecDefs CodecDefs; -struct _CodecDefs { - const gchar *codec_str; - GetVideoInfoFunc get_video_info; -}; - -static const CodecDefs g_codec_defs[] = { -#define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info } - INIT_FUNCS(jpeg), - INIT_FUNCS(mpeg2), - INIT_FUNCS(mpeg4), - INIT_FUNCS(h264), - INIT_FUNCS(vc1), -#undef INIT_FUNCS - { NULL, } -}; - -static const CodecDefs * -get_codec_defs(const gchar *codec_str) -{ - const CodecDefs *c; - for (c = g_codec_defs; c->codec_str; c++) - if (strcmp(codec_str, c->codec_str) == 0) - return c; - return NULL; -} - static inline void pause(void) { g_print("Press any key to continue...\n"); @@ -90,13 +51,7 @@ main(int argc, char *argv[]) GstVaapiDisplay *display, *display2; GstVaapiWindow *window; GstVaapiDecoder *decoder; - GstCaps *decoder_caps; - GstStructure *structure; - GstVaapiDecoderStatus status; - const CodecDefs *codec; - GstBuffer *buffer; - GstVaapiSurfaceProxy *proxy; - VideoDecodeInfo info; + GstVaapiSurface *surface; static const guint win_width = 640; static const guint win_height = 480; @@ -104,13 +59,7 @@ main(int argc, char *argv[]) if (!video_output_init(&argc, argv, g_options)) g_error("failed to initialize video output subsystem"); - if (!g_codec_str) - g_codec_str = g_strdup("h264"); - - g_print("Test %s decode\n", g_codec_str); - codec = get_codec_defs(g_codec_str); - if (!codec) - g_error("no %s codec data found", g_codec_str); + g_print("Test decode\n"); display = video_output_create_display(NULL); if (!display) @@ -127,74 +76,27 @@ main(int argc, char *argv[]) if (!window) g_error("could not create window"); - codec->get_video_info(&info); - decoder_caps = gst_vaapi_profile_get_caps(info.profile); - if (!decoder_caps) - g_error("could not create decoder caps"); - - structure = gst_caps_get_structure(decoder_caps, 0); - if (info.width > 0 && info.height > 0) - gst_structure_set( - structure, - "width", G_TYPE_INT, info.width, - "height", G_TYPE_INT, info.height, - NULL - ); - - switch (gst_vaapi_profile_get_codec(info.profile)) { - case GST_VAAPI_CODEC_H264: - decoder = gst_vaapi_decoder_h264_new(display, decoder_caps); - break; -#if USE_JPEG_DECODER - case GST_VAAPI_CODEC_JPEG: - decoder = gst_vaapi_decoder_jpeg_new(display, decoder_caps); - break; -#endif - case GST_VAAPI_CODEC_MPEG2: - decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); - break; - case GST_VAAPI_CODEC_MPEG4: - decoder = gst_vaapi_decoder_mpeg4_new(display, decoder_caps); - break; - case GST_VAAPI_CODEC_VC1: - decoder = gst_vaapi_decoder_vc1_new(display, decoder_caps); - break; - default: - decoder = NULL; - break; - } + decoder = decoder_new(display, g_codec_str); if (!decoder) g_error("could not create decoder"); - gst_caps_unref(decoder_caps); - buffer = gst_buffer_new(); - if (!buffer) - g_error("could not create encoded data buffer"); - gst_buffer_set_data(buffer, (guchar *)info.data, info.data_size); + g_print("Decode %s sample frame\n", decoder_get_codec_name(decoder)); - if (!gst_vaapi_decoder_put_buffer(decoder, buffer)) - g_error("could not send video data to the decoder"); - gst_buffer_unref(buffer); + if (!decoder_put_buffers(decoder)) + g_error("could not fill decoder with sample data"); - if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) - g_error("could not send EOS to the decoder"); - - status = gst_vaapi_decoder_get_surface(decoder, &proxy); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - g_error("could not get decoded surface (decoder status %d)", status); + surface = decoder_get_surface(decoder); + if (!surface) + g_error("could not get decoded surface"); gst_vaapi_window_show(window); - if (!gst_vaapi_window_put_surface(window, - GST_VAAPI_SURFACE_PROXY_SURFACE(proxy), - NULL, - NULL, - GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) g_error("could not render surface"); pause(); - gst_vaapi_surface_proxy_unref(proxy); g_object_unref(decoder); g_object_unref(window); g_object_unref(display); From 886f6d9f110284e606503a62e2396722102f3d0d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 10 Jan 2013 11:26:17 +0100 Subject: [PATCH 1007/3781] tests: use common decoder helpers for subpicture test. Use common decoder helpers for subpicture test, thus allowing to decode sample images in an alternate format. --- tests/Makefile.am | 2 +- tests/test-subpicture.c | 95 ++++++----------------------------------- 2 files changed, 13 insertions(+), 84 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index afe894db88..7dae54959d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -90,7 +90,7 @@ test_surfaces_LDADD = libutils.la $(TEST_LIBS) test_subpicture_SOURCES = test-subpicture.c test-subpicture-data.c test_subpicture_CFLAGS = $(TEST_CFLAGS) -test_subpicture_LDADD = libutils.la $(TEST_LIBS) +test_subpicture_LDADD = libutils.la libutils_dec.la $(TEST_LIBS) test_windows_SOURCES = test-windows.c test_windows_CFLAGS = $(TEST_CFLAGS) diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 6a1620ca80..308547d1c8 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -22,38 +22,11 @@ #include "config.h" #include -#include -#include #include +#include "decoder.h" #include "output.h" -#include "test-mpeg2.h" #include "test-subpicture-data.h" -typedef void (*GetVideoInfoFunc)(VideoDecodeInfo *info); - -typedef struct _CodecDefs CodecDefs; -struct _CodecDefs { - const gchar *codec_str; - GetVideoInfoFunc get_video_info; -}; - -static const CodecDefs g_codec_defs[] = { -#define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info } - INIT_FUNCS(mpeg2), -#undef INIT_FUNCS - { NULL, } -}; - -static const CodecDefs * -get_codec_defs(const gchar *codec_str) -{ - const CodecDefs *c; - for (c = g_codec_defs; c->codec_str; c++) - if (strcmp(codec_str, c->codec_str) == 0) - return c; - return NULL; -} - static inline void pause(void) { g_print("Press any key to continue...\n"); @@ -88,15 +61,9 @@ main(int argc, char *argv[]) { GstVaapiDisplay *display; GstVaapiWindow *window; - GstVaapiDecoder *decoder = NULL; - GstCaps *decoder_caps; - GstStructure *structure; - GstVaapiDecoderStatus status; - const CodecDefs *codec; - GstBuffer *buffer; - GstVaapiSurfaceProxy *proxy; + GstVaapiDecoder *decoder; GstVaapiSurface *surface; - VideoDecodeInfo info; + GstBuffer *buffer; VideoSubpictureInfo subinfo; GstVaapiImage *subtitle_image; GstVaapiSubpicture *subpicture; @@ -110,13 +77,7 @@ main(int argc, char *argv[]) if (!video_output_init(&argc, argv, g_options)) g_error("failed to initialize video output subsystem"); - if (!g_codec_str) - g_codec_str = g_strdup("mpeg2"); - - g_print("Test %s decode\n", g_codec_str); - codec = get_codec_defs(g_codec_str); - if (!codec) - g_error("no %s codec data found", g_codec_str); + g_print("Test subpicture\n"); display = video_output_create_display(NULL); if (!display) @@ -126,44 +87,16 @@ main(int argc, char *argv[]) if (!window) g_error("could not create window"); - codec->get_video_info(&info); - decoder_caps = gst_vaapi_profile_get_caps(info.profile); - if (!decoder_caps) - g_error("could not create decoder caps"); - - structure = gst_caps_get_structure(decoder_caps, 0); - if (info.width > 0 && info.height > 0) - gst_structure_set( - structure, - "width", G_TYPE_INT, info.width, - "height", G_TYPE_INT, info.height, - NULL - ); - - decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps); + decoder = decoder_new(display, g_codec_str); if (!decoder) - g_error("could not create video decoder"); - gst_caps_unref(decoder_caps); + g_error("could not create decoder"); - buffer = gst_buffer_new(); - if (!buffer) - g_error("could not create encoded data buffer"); - gst_buffer_set_data(buffer, (guchar *)info.data, info.data_size); + if (!decoder_put_buffers(decoder)) + g_error("could not fill decoder with sample data"); - if (!gst_vaapi_decoder_put_buffer(decoder, buffer)) - g_error("could not send video data to the decoder"); - gst_buffer_unref(buffer); - - if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) - g_error("could not send EOS to the decoder"); - - status = gst_vaapi_decoder_get_surface(decoder, &proxy); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - g_error("could not get decoded surface (decoder status %d)", status); - - surface = gst_vaapi_surface_proxy_get_surface(proxy); + surface = decoder_get_surface(decoder); if (!surface) - g_error("could not get underlying surface"); + g_error("could not get decoded surface"); gst_vaapi_surface_get_size(surface, &surf_width, &surf_height); printf("surface size %dx%d\n", surf_width, surf_height); @@ -209,17 +142,13 @@ main(int argc, char *argv[]) gst_vaapi_window_show(window); - if (!gst_vaapi_window_put_surface(window, - GST_VAAPI_SURFACE_PROXY_SURFACE(proxy), - NULL, - NULL, - GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) g_error("could not render surface"); pause(); gst_buffer_unref(buffer); - gst_vaapi_surface_proxy_unref(proxy); g_object_unref(decoder); g_object_unref(window); g_object_unref(display); From cbf2f2716871eaf39b8c9fe17cb0b43aa95a0867 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 10 Jan 2013 13:09:28 +0100 Subject: [PATCH 1008/3781] tests: use GstVideoOverlayComposition API for subpicture test. --- tests/Makefile.am | 5 ++- tests/test-subpicture.c | 84 +++++++++++++++++------------------------ 2 files changed, 37 insertions(+), 52 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 7dae54959d..3c98df0a24 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -89,8 +89,9 @@ test_surfaces_CFLAGS = $(TEST_CFLAGS) test_surfaces_LDADD = libutils.la $(TEST_LIBS) test_subpicture_SOURCES = test-subpicture.c test-subpicture-data.c -test_subpicture_CFLAGS = $(TEST_CFLAGS) -test_subpicture_LDADD = libutils.la libutils_dec.la $(TEST_LIBS) +test_subpicture_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) +test_subpicture_LDADD = libutils.la libutils_dec.la $(TEST_LIBS) \ + $(GST_VIDEO_LIBS) test_windows_SOURCES = test-windows.c test_windows_CFLAGS = $(TEST_CFLAGS) diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 308547d1c8..bba341b3a9 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -44,15 +44,16 @@ static GOptionEntry g_options[] = { }; static void -upload_image (guint8 *dst, const guint32 *src, guint size) +upload_subpicture(GstBuffer *buffer, const VideoSubpictureInfo *subinfo) { - guint i; + guint32 * const dst = (guint32 *)GST_BUFFER_DATA(buffer); + const guint32 * const src = subinfo->data; + guint i, len = subinfo->data_size / 4; - for (i = 0; i < size; i += 4) { - dst[i ] = *src >> 24; - dst[i + 1] = *src >> 16; - dst[i + 2] = *src >> 8; - dst[i + 3] = *src++; + /* Convert from RGBA source to ARGB */ + for (i = 0; i < len; i++) { + const guint32 rgba = src[i]; + dst[i] = (rgba >> 8) | (rgba << 24); } } @@ -65,11 +66,10 @@ main(int argc, char *argv[]) GstVaapiSurface *surface; GstBuffer *buffer; VideoSubpictureInfo subinfo; - GstVaapiImage *subtitle_image; - GstVaapiSubpicture *subpicture; - GstCaps *argbcaps; - GstVaapiRectangle sub_rect; - guint surf_width, surf_height; + GstVaapiRectangle subrect; + GstVideoOverlayRectangle *overlay; + GstVideoOverlayComposition *compo; + guint flags = 0; static const guint win_width = 640; static const guint win_height = 480; @@ -98,47 +98,31 @@ main(int argc, char *argv[]) if (!surface) g_error("could not get decoded surface"); - gst_vaapi_surface_get_size(surface, &surf_width, &surf_height); - printf("surface size %dx%d\n", surf_width, surf_height); + subpicture_get_info(&subinfo); + buffer = gst_buffer_new_and_alloc(subinfo.data_size); + upload_subpicture(buffer, &subinfo); - subpicture_get_info (&subinfo); + /* We position the subpicture at the bottom center */ + subrect.x = (gst_vaapi_surface_get_width(surface) - subinfo.width) / 2; + subrect.y = gst_vaapi_surface_get_height(surface) - subinfo.height - 10; + subrect.height = subinfo.height; + subrect.width = subinfo.width; - /* Adding subpicture */ - argbcaps = gst_caps_new_simple ("video/x-raw-rgb", - "endianness", G_TYPE_INT, G_BIG_ENDIAN, - "bpp", G_TYPE_INT, 32, - "red_mask", G_TYPE_INT, 0xff000000, - "green_mask", G_TYPE_INT, 0x00ff0000, - "blue_mask", G_TYPE_INT, 0x0000ff00, - "alpha_mask", G_TYPE_INT, 0x000000ff, - "width", G_TYPE_INT, subinfo.width, - "height", G_TYPE_INT, subinfo.height, - NULL); + overlay = gst_video_overlay_rectangle_new_argb(buffer, + subinfo.width, subinfo.height, subinfo.width * 4, + subrect.x, subrect.y, subrect.width, subrect.height, flags); + if (!overlay) + g_error("could not create video overlay"); + gst_buffer_unref(buffer); - buffer = gst_buffer_new_and_alloc (subinfo.data_size); - upload_image (GST_BUFFER_DATA (buffer), subinfo.data, subinfo.data_size); - gst_buffer_set_caps (buffer, argbcaps); + compo = gst_video_overlay_composition_new(overlay); + if (!compo) + g_error("could not create video overlay composition"); + gst_video_overlay_rectangle_unref(overlay); - subtitle_image = gst_vaapi_image_new (display, - GST_VAAPI_IMAGE_RGBA, subinfo.width, subinfo.height); - - if (!gst_vaapi_image_update_from_buffer (subtitle_image, buffer, NULL)) - g_error ("could not update VA image with subtitle data"); - - subpicture = gst_vaapi_subpicture_new (subtitle_image, 0); - - /* We position it as a subtitle, centered at the bottom. */ - sub_rect.x = (surf_width - subinfo.width) / 2; - sub_rect.y = surf_height - subinfo.height - 10; - sub_rect.height = subinfo.height; - sub_rect.width = subinfo.width; - - if (!gst_vaapi_surface_associate_subpicture ( - surface, - subpicture, - NULL, - &sub_rect)) - g_error("could not associate subpicture"); + if (!gst_vaapi_surface_set_subpictures_from_composition(surface, compo, + FALSE)) + g_error("could not create subpictures from video overlay compoition"); gst_vaapi_window_show(window); @@ -148,7 +132,7 @@ main(int argc, char *argv[]) pause(); - gst_buffer_unref(buffer); + gst_video_overlay_composition_unref(compo); g_object_unref(decoder); g_object_unref(window); g_object_unref(display); From bfc4e6e4f6108e7077287fce37d3804132342cef Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 4 Jan 2013 10:19:56 +0100 Subject: [PATCH 1009/3781] tests: add support for global-alpha subpictures. Add --global-alpha option to test-subpicture. --- tests/test-subpicture.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index bba341b3a9..32c9c1918f 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -34,12 +34,17 @@ static inline void pause(void) } static gchar *g_codec_str; +static gdouble g_global_alpha = 1.0; static GOptionEntry g_options[] = { { "codec", 'c', 0, G_OPTION_ARG_STRING, &g_codec_str, "codec to test", NULL }, + { "global-alpha", 'g', + 0, + G_OPTION_ARG_DOUBLE, &g_global_alpha, + "global-alpha value", NULL }, { NULL, } }; @@ -77,6 +82,9 @@ main(int argc, char *argv[]) if (!video_output_init(&argc, argv, g_options)) g_error("failed to initialize video output subsystem"); + if (g_global_alpha != 1.0) + flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA; + g_print("Test subpicture\n"); display = video_output_create_display(NULL); @@ -115,6 +123,9 @@ main(int argc, char *argv[]) g_error("could not create video overlay"); gst_buffer_unref(buffer); + if (flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA) + gst_video_overlay_rectangle_set_global_alpha(overlay, g_global_alpha); + compo = gst_video_overlay_composition_new(overlay); if (!compo) g_error("could not create video overlay composition"); From 082a56599b021b0b459ee6168dbbaa42f283db40 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Fri, 20 Jul 2012 12:36:33 +0200 Subject: [PATCH 1010/3781] overlay: fix build without advanced GstVideoOverlayFormatFlags. Check for global-alpha support in GstVideoOverlayComposition API. Signed-off-by: Gwenole Beauchesne --- configure.ac | 31 +++++++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapicontext.c | 2 ++ gst-libs/gst/vaapi/gstvaapiutils.c | 4 ++++ gst-libs/gst/vaapi/sysdeps.h | 6 ++++++ tests/test-subpicture.c | 6 ++++++ 5 files changed, 48 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index af7676937a..0d21875747 100644 --- a/configure.ac +++ b/configure.ac @@ -200,7 +200,8 @@ AC_CACHE_CHECK([for GstVideoOverlayComposition], AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], - [[GstVideoOverlayComposition *c = gst_video_overlay_composition_new(0);]])], + [[GstVideoOverlayComposition *c; + c = gst_video_overlay_composition_new(0);]])], [ac_cv_have_gst_video_overlay_composition="yes"], [ac_cv_have_gst_video_overlay_composition="no"] ) @@ -211,6 +212,34 @@ if test "$ac_cv_have_gst_video_overlay_composition" != "yes"; then AC_MSG_ERROR([GstVideoOverlayComposition is not available]) fi +AC_CACHE_CHECK([... with advanced format flags], + ac_cv_have_gst_video_overlay_hwcaps, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_VIDEO_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $GST_LIBS $GST_VIDEO_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[GstVideoOverlayRectangle *rect; + const guint w = 64, h = 64; + guint flags = ( + GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA| + GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA); + rect = gst_video_overlay_rectangle_new_argb(NULL, w, h, w * 4, + 0, 0, w, h, flags); + gst_video_overlay_rectangle_set_global_alpha(rect, 0.5f);]])], + [ac_cv_have_gst_video_overlay_hwcaps="yes"], + [ac_cv_have_gst_video_overlay_hwcaps="no"] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +]) +if test "$ac_cv_have_gst_video_overlay_hwcaps" = "yes"; then + AC_DEFINE_UNQUOTED([HAVE_GST_VIDEO_OVERLAY_HWCAPS], 1, + [Defined to 1 if GstVideoOverlayComposition API supports HW hints.]) +fi + dnl ... GstVideoDecoder (gstreamer-video) AC_CACHE_CHECK([for GstVideoDecoder], ac_cv_have_gst_video_decoder, [ diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index b69d4d57e2..84ff9d7aa3 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -295,9 +295,11 @@ static inline gboolean overlay_rectangle_update_global_alpha(GstVaapiOverlayRectangle *overlay, GstVideoOverlayRectangle *rect) { +#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS const guint flags = gst_video_overlay_rectangle_get_flags(rect); if (!(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)) return TRUE; +#endif return gst_vaapi_subpicture_set_global_alpha(overlay->subpicture, gst_video_overlay_rectangle_get_global_alpha(rect)); } diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index f69036e738..1461b2817b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -260,10 +260,12 @@ from_GstVideoOverlayFormatFlags(guint ovl_flags) { guint flags = 0; +#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA) flags |= GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA; if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA) flags |= GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA; +#endif return flags; } @@ -280,10 +282,12 @@ to_GstVideoOverlayFormatFlags(guint flags) { guint ovl_flags = 0; +#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS if (flags & GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA) ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA; if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA; +#endif return ovl_flags; } diff --git a/gst-libs/gst/vaapi/sysdeps.h b/gst-libs/gst/vaapi/sysdeps.h index c8be89076c..6f072fc39d 100644 --- a/gst-libs/gst/vaapi/sysdeps.h +++ b/gst-libs/gst/vaapi/sysdeps.h @@ -28,4 +28,10 @@ #include "glibcompat.h" +/* compatibility glue */ +#ifndef HAVE_GST_VIDEO_OVERLAY_HWCAPS +# define gst_video_overlay_rectangle_get_flags(rect) (0) +# define gst_video_overlay_rectangle_get_global_alpha(rect) (1.0f) +#endif + #endif /* SYSDEPS_H */ diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 32c9c1918f..c94ddb9c3b 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -41,10 +41,12 @@ static GOptionEntry g_options[] = { 0, G_OPTION_ARG_STRING, &g_codec_str, "codec to test", NULL }, +#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS { "global-alpha", 'g', 0, G_OPTION_ARG_DOUBLE, &g_global_alpha, "global-alpha value", NULL }, +#endif { NULL, } }; @@ -82,8 +84,10 @@ main(int argc, char *argv[]) if (!video_output_init(&argc, argv, g_options)) g_error("failed to initialize video output subsystem"); +#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS if (g_global_alpha != 1.0) flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA; +#endif g_print("Test subpicture\n"); @@ -123,8 +127,10 @@ main(int argc, char *argv[]) g_error("could not create video overlay"); gst_buffer_unref(buffer); +#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS if (flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA) gst_video_overlay_rectangle_set_global_alpha(overlay, g_global_alpha); +#endif compo = gst_video_overlay_composition_new(overlay); if (!compo) From eefe1eca328582840661ec66ab02048c98584a95 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 11 Jan 2013 15:57:09 +0100 Subject: [PATCH 1011/3781] NEWS: updates. --- NEWS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index cf399a7ca6..853c48e98f 100644 --- a/NEWS +++ b/NEWS @@ -4,9 +4,10 @@ Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora Version 0.5.0 - DD.Dec.2012 +* Optimize MPEG-2 and H.264 decoders * Use GstVideoDecoder API for vaapidecode (+Sreerenj Balachandran) * Add support for raw YUV buffers in vaapisink (+Halley Zhao) -* Fix memory leak in GstVaapiVideoBuffer for images and surfaces (Feng Yuan) +* Add support for global-alpha subpictures/overlay (+Holger Kaelberer) Version 0.4.2 - 18.Dec.2012 * Fix H.264 decoding on Cedar Trail platforms From 86af31e426f2924c655a9477fc0dcaf5628cf9ff Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 11 Jan 2013 16:04:30 +0100 Subject: [PATCH 1012/3781] Bump version for pre-release. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0d21875747..85b3f41b13 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [2]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From eafdd771aef40a6f68fb0147736393e72a40ed49 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 2 Aug 2012 15:56:54 +0300 Subject: [PATCH 1013/3781] dpb: rename GstVaapiDpbMpeg2 to GstVaapiDpb2. Move GstVaapiDpbMpeg2 API to a more generic version that could also be useful to other decoders that require 2 reference pictures, e.g. VC-1. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 30 +++++----- gst-libs/gst/vaapi/gstvaapidecoder_dpb.h | 64 +++++++++++----------- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 4 +- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index c5a5a76864..b674998261 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -247,21 +247,21 @@ gst_vaapi_dpb_size(GstVaapiDpb *dpb) } /* ------------------------------------------------------------------------- */ -/* --- MPEG-2 Decoded Picture Buffer --- */ +/* --- Decoded Picture Buffer (optimized for 2 reference pictures) --- */ /* ------------------------------------------------------------------------- */ -/* At most two reference pictures for MPEG-2 */ -#define MAX_MPEG2_REFERENCES 2 +/* At most two reference pictures for DPB2*/ +#define MAX_DPB2_REFERENCES 2 -G_DEFINE_TYPE(GstVaapiDpbMpeg2, gst_vaapi_dpb_mpeg2, GST_VAAPI_TYPE_DPB) +G_DEFINE_TYPE(GstVaapiDpb2, gst_vaapi_dpb2, GST_VAAPI_TYPE_DPB) static gboolean -gst_vaapi_dpb_mpeg2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) +gst_vaapi_dpb2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) { GstVaapiPicture *ref_picture; gint index = -1; - g_return_val_if_fail(GST_VAAPI_IS_DPB_MPEG2(dpb), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_DPB2(dpb), FALSE); /* * Purpose: only store reference decoded pictures into the DPB @@ -271,7 +271,7 @@ gst_vaapi_dpb_mpeg2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) * - ... 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 == MAX_MPEG2_REFERENCES)) { + if (G_LIKELY(dpb->num_pictures == MAX_DPB2_REFERENCES)) { index = (dpb->pictures[0]->poc > dpb->pictures[1]->poc); ref_picture = dpb->pictures[index]; if (!GST_VAAPI_PICTURE_IS_OUTPUT(ref_picture)) { @@ -290,37 +290,37 @@ gst_vaapi_dpb_mpeg2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) } static void -gst_vaapi_dpb_mpeg2_init(GstVaapiDpbMpeg2 *dpb) +gst_vaapi_dpb2_init(GstVaapiDpb2 *dpb) { } static void -gst_vaapi_dpb_mpeg2_class_init(GstVaapiDpbMpeg2Class *klass) +gst_vaapi_dpb2_class_init(GstVaapiDpb2Class *klass) { GstVaapiDpbClass * const dpb_class = GST_VAAPI_DPB_CLASS(klass); - dpb_class->add = gst_vaapi_dpb_mpeg2_add; + dpb_class->add = gst_vaapi_dpb2_add; } GstVaapiDpb * -gst_vaapi_dpb_mpeg2_new(void) +gst_vaapi_dpb2_new(void) { - return dpb_new(GST_VAAPI_TYPE_DPB_MPEG2, MAX_MPEG2_REFERENCES); + return dpb_new(GST_VAAPI_TYPE_DPB2, MAX_DPB2_REFERENCES); } void -gst_vaapi_dpb_mpeg2_get_references( +gst_vaapi_dpb2_get_references( GstVaapiDpb *dpb, GstVaapiPicture *picture, GstVaapiPicture **prev_picture_ptr, GstVaapiPicture **next_picture_ptr ) { - GstVaapiPicture *ref_picture, *ref_pictures[MAX_MPEG2_REFERENCES]; + GstVaapiPicture *ref_picture, *ref_pictures[MAX_DPB2_REFERENCES]; GstVaapiPicture **picture_ptr; guint i, index; - g_return_if_fail(GST_VAAPI_IS_DPB_MPEG2(dpb)); + g_return_if_fail(GST_VAAPI_IS_DPB2(dpb)); g_return_if_fail(GST_VAAPI_IS_PICTURE(picture)); ref_pictures[0] = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h index 3cbaa48e84..e0ba009fcd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h @@ -28,8 +28,8 @@ G_BEGIN_DECLS typedef struct _GstVaapiDpb GstVaapiDpb; typedef struct _GstVaapiDpbClass GstVaapiDpbClass; -typedef struct _GstVaapiDpbMpeg2 GstVaapiDpbMpeg2; -typedef struct _GstVaapiDpbMpeg2Class GstVaapiDpbMpeg2Class; +typedef struct _GstVaapiDpb2 GstVaapiDpb2; +typedef struct _GstVaapiDpb2Class GstVaapiDpb2Class; /* ------------------------------------------------------------------------- */ /* --- Base Decoded Picture Buffer --- */ @@ -120,67 +120,67 @@ gst_vaapi_dpb_unref(gpointer ptr) } /* ------------------------------------------------------------------------- */ -/* --- MPEG-2 Decoded Picture Buffer --- */ +/* --- Decoded Picture Buffer (optimized for 2 reference pictures) --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_TYPE_DPB_MPEG2 \ - (gst_vaapi_dpb_mpeg2_get_type()) +#define GST_VAAPI_TYPE_DPB2 \ + (gst_vaapi_dpb2_get_type()) -#define GST_VAAPI_DPB_MPEG2_CAST(obj) \ - ((GstVaapiDpbMpeg2 *)(obj)) +#define GST_VAAPI_DPB2_CAST(obj) \ + ((GstVaapiDpb2 *)(obj)) -#define GST_VAAPI_DPB_MPEG2(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DPB_MPEG2, \ - GstVaapiDpbMpeg2)) +#define GST_VAAPI_DPB2(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DPB2, \ + GstVaapiDpb2)) -#define GST_VAAPI_DPB_MPEG2_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DPB_MPEG2, \ - GstVaapiDpbMpeg2Class)) +#define GST_VAAPI_DPB2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DPB2, \ + GstVaapiDpb2Class)) -#define GST_VAAPI_IS_DPB_MPEG2(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DPB_MPEG2)) +#define GST_VAAPI_IS_DPB2(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DPB2)) -#define GST_VAAPI_IS_DPB_MPEG2_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DPB_MPEG2)) +#define GST_VAAPI_IS_DPB2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DPB2)) -#define GST_VAAPI_DPB_MPEG2_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DPB_MPEG2, \ - GstVaapiDpbMpeg2Class)) +#define GST_VAAPI_DPB2_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DPB2, \ + GstVaapiDpb2Class)) /** - * GstVaapiDpbMpeg2: + * GstVaapiDpb2: * - * A decoded picture buffer (DPB_MPEG2) object. + * A decoded picture buffer (DPB2) object. */ -struct _GstVaapiDpbMpeg2 { +struct _GstVaapiDpb2 { /*< private >*/ GstVaapiDpb parent_instance; }; /** - * GstVaapiDpbMpeg2Class: + * GstVaapiDpb2Class: * - * The #GstVaapiDpbMpeg2 base class. + * The #GstVaapiDpb2 base class. */ -struct _GstVaapiDpbMpeg2Class { +struct _GstVaapiDpb2Class { /*< private >*/ GstVaapiDpbClass parent_class; }; G_GNUC_INTERNAL GType -gst_vaapi_dpb_mpeg2_get_type(void) G_GNUC_CONST; +gst_vaapi_dpb2_get_type(void) G_GNUC_CONST; G_GNUC_INTERNAL GstVaapiDpb * -gst_vaapi_dpb_mpeg2_new(void); +gst_vaapi_dpb2_new(void); G_GNUC_INTERNAL void -gst_vaapi_dpb_mpeg2_get_references( +gst_vaapi_dpb2_get_references( GstVaapiDpb *dpb, GstVaapiPicture *picture, GstVaapiPicture **prev_picture_ptr, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index cde9278940..fcbee061bc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -386,7 +386,7 @@ gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder) gst_vaapi_decoder_mpeg2_close(decoder); - priv->dpb = gst_vaapi_dpb_mpeg2_new(); + priv->dpb = gst_vaapi_dpb2_new(); if (!priv->dpb) return FALSE; @@ -1044,7 +1044,7 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) COPY_FIELD(picture_coding_extension, bits, repeat_first_field); COPY_FIELD(picture_coding_extension, bits, progressive_frame); - gst_vaapi_dpb_mpeg2_get_references(priv->dpb, picture, + gst_vaapi_dpb2_get_references(priv->dpb, picture, &prev_picture, &next_picture); switch (pic_hdr->pic_type) { From 6f4e01258ddaae4a0553b364bb4c4d440db21c0d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 14 Jan 2013 10:21:53 +0100 Subject: [PATCH 1014/3781] dpb: drop GstVaapiDpb2 interface, keep only one class. Keep only one DPB interface and rename gst_vaapi_dpb2_get_references() to gst_vaapi_dpb_get_neighbours() so that to retrieve pictures in DPB around the specified picture POC. --- gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 149 +++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapidecoder_dpb.h | 89 +++--------- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 4 +- 3 files changed, 155 insertions(+), 87 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index b674998261..51c1c8bc45 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -25,6 +25,13 @@ #define DEBUG 1 #include "gstvaapidebug.h" +G_GNUC_INTERNAL +GType +gst_vaapi_dpb2_get_type(void) G_GNUC_CONST; + +#define GST_VAAPI_TYPE_DPB2 \ + (gst_vaapi_dpb2_get_type()) + /* ------------------------------------------------------------------------- */ /* --- Common Decoded Picture Buffer utilities --- */ /* ------------------------------------------------------------------------- */ @@ -177,6 +184,45 @@ gst_vaapi_dpb_base_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) return TRUE; } +void +gst_vaapi_dpb_base_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; +} + static void gst_vaapi_dpb_finalize(GstMiniObject *object) { @@ -209,6 +255,15 @@ gst_vaapi_dpb_class_init(GstVaapiDpbClass *klass) object_class->finalize = gst_vaapi_dpb_finalize; klass->flush = gst_vaapi_dpb_base_flush; klass->add = gst_vaapi_dpb_base_add; + klass->get_neighbours = gst_vaapi_dpb_base_get_neighbours; +} + +GstVaapiDpb * +gst_vaapi_dpb_new(guint max_pictures) +{ + if (G_LIKELY(max_pictures == 2)) + return dpb_new(GST_VAAPI_TYPE_DPB2, max_pictures); + return dpb_new(GST_VAAPI_TYPE_DPB, max_pictures); } void @@ -246,22 +301,94 @@ gst_vaapi_dpb_size(GstVaapiDpb *dpb) return dpb->num_pictures; } +void +gst_vaapi_dpb_get_neighbours( + GstVaapiDpb *dpb, + GstVaapiPicture *picture, + GstVaapiPicture **prev_picture_ptr, + GstVaapiPicture **next_picture_ptr +) +{ + 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); +} + /* ------------------------------------------------------------------------- */ /* --- Decoded Picture Buffer (optimized for 2 reference pictures) --- */ /* ------------------------------------------------------------------------- */ -/* At most two reference pictures for DPB2*/ -#define MAX_DPB2_REFERENCES 2 +typedef struct _GstVaapiDpb2 GstVaapiDpb2; +typedef struct _GstVaapiDpb2Class GstVaapiDpb2Class; + +#define GST_VAAPI_DPB2_CAST(obj) \ + ((GstVaapiDpb2 *)(obj)) + +#define GST_VAAPI_DPB2(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DPB2, \ + GstVaapiDpb2)) + +#define GST_VAAPI_DPB2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DPB2, \ + GstVaapiDpb2Class)) + +#define GST_VAAPI_IS_DPB2(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DPB2)) + +#define GST_VAAPI_IS_DPB2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DPB2)) + +#define GST_VAAPI_DPB2_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DPB2, \ + GstVaapiDpb2Class)) + +/** + * GstVaapiDpb2: + * + * A decoded picture buffer (DPB2) object. + */ +struct _GstVaapiDpb2 { + /*< private >*/ + GstVaapiDpb parent_instance; +}; + +/** + * GstVaapiDpb2Class: + * + * The #GstVaapiDpb2 base class. + */ +struct _GstVaapiDpb2Class { + /*< private >*/ + GstVaapiDpbClass parent_class; +}; G_DEFINE_TYPE(GstVaapiDpb2, gst_vaapi_dpb2, GST_VAAPI_TYPE_DPB) +static void +gst_vaapi_dpb2_get_neighbours( + GstVaapiDpb *dpb, + GstVaapiPicture *picture, + GstVaapiPicture **prev_picture_ptr, + GstVaapiPicture **next_picture_ptr +); + static gboolean gst_vaapi_dpb2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) { GstVaapiPicture *ref_picture; gint index = -1; - g_return_val_if_fail(GST_VAAPI_IS_DPB2(dpb), FALSE); + 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 @@ -271,7 +398,7 @@ gst_vaapi_dpb2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) * - ... 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 == MAX_DPB2_REFERENCES)) { + 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)) { @@ -300,27 +427,23 @@ gst_vaapi_dpb2_class_init(GstVaapiDpb2Class *klass) GstVaapiDpbClass * const dpb_class = GST_VAAPI_DPB_CLASS(klass); dpb_class->add = gst_vaapi_dpb2_add; -} - -GstVaapiDpb * -gst_vaapi_dpb2_new(void) -{ - return dpb_new(GST_VAAPI_TYPE_DPB2, MAX_DPB2_REFERENCES); + dpb_class->get_neighbours = gst_vaapi_dpb2_get_neighbours; } void -gst_vaapi_dpb2_get_references( +gst_vaapi_dpb2_get_neighbours( GstVaapiDpb *dpb, GstVaapiPicture *picture, GstVaapiPicture **prev_picture_ptr, GstVaapiPicture **next_picture_ptr ) { - GstVaapiPicture *ref_picture, *ref_pictures[MAX_DPB2_REFERENCES]; + GstVaapiPicture *ref_picture, *ref_pictures[2]; GstVaapiPicture **picture_ptr; guint i, index; - g_return_if_fail(GST_VAAPI_IS_DPB2(dpb)); + 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; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h index e0ba009fcd..98acb351ba 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h @@ -28,8 +28,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiDpb GstVaapiDpb; typedef struct _GstVaapiDpbClass GstVaapiDpbClass; -typedef struct _GstVaapiDpb2 GstVaapiDpb2; -typedef struct _GstVaapiDpb2Class GstVaapiDpb2Class; /* ------------------------------------------------------------------------- */ /* --- Base Decoded Picture Buffer --- */ @@ -87,14 +85,20 @@ struct _GstVaapiDpbClass { GstMiniObjectClass parent_class; /*< protected >*/ - void (*flush) (GstVaapiDpb *dpb); - gboolean (*add) (GstVaapiDpb *dpb, GstVaapiPicture *picture); + 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); }; G_GNUC_INTERNAL GType gst_vaapi_dpb_get_type(void) G_GNUC_CONST; +G_GNUC_INTERNAL +GstVaapiDpb * +gst_vaapi_dpb_new(guint max_pictures); + G_GNUC_INTERNAL void gst_vaapi_dpb_flush(GstVaapiDpb *dpb); @@ -107,6 +111,15 @@ 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 +); + static inline gpointer gst_vaapi_dpb_ref(gpointer ptr) { @@ -119,74 +132,6 @@ gst_vaapi_dpb_unref(gpointer ptr) gst_mini_object_unref(GST_MINI_OBJECT(ptr)); } -/* ------------------------------------------------------------------------- */ -/* --- Decoded Picture Buffer (optimized for 2 reference pictures) --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_TYPE_DPB2 \ - (gst_vaapi_dpb2_get_type()) - -#define GST_VAAPI_DPB2_CAST(obj) \ - ((GstVaapiDpb2 *)(obj)) - -#define GST_VAAPI_DPB2(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DPB2, \ - GstVaapiDpb2)) - -#define GST_VAAPI_DPB2_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DPB2, \ - GstVaapiDpb2Class)) - -#define GST_VAAPI_IS_DPB2(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DPB2)) - -#define GST_VAAPI_IS_DPB2_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DPB2)) - -#define GST_VAAPI_DPB2_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DPB2, \ - GstVaapiDpb2Class)) - -/** - * GstVaapiDpb2: - * - * A decoded picture buffer (DPB2) object. - */ -struct _GstVaapiDpb2 { - /*< private >*/ - GstVaapiDpb parent_instance; -}; - -/** - * GstVaapiDpb2Class: - * - * The #GstVaapiDpb2 base class. - */ -struct _GstVaapiDpb2Class { - /*< private >*/ - GstVaapiDpbClass parent_class; -}; - -G_GNUC_INTERNAL -GType -gst_vaapi_dpb2_get_type(void) G_GNUC_CONST; - -G_GNUC_INTERNAL -GstVaapiDpb * -gst_vaapi_dpb2_new(void); - -G_GNUC_INTERNAL -void -gst_vaapi_dpb2_get_references( - GstVaapiDpb *dpb, - GstVaapiPicture *picture, - GstVaapiPicture **prev_picture_ptr, - GstVaapiPicture **next_picture_ptr -); - G_END_DECLS #endif /* GST_VAAPI_DECODER_DPB */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index fcbee061bc..4b32f092d1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -386,7 +386,7 @@ gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder) gst_vaapi_decoder_mpeg2_close(decoder); - priv->dpb = gst_vaapi_dpb2_new(); + priv->dpb = gst_vaapi_dpb_new(2); if (!priv->dpb) return FALSE; @@ -1044,7 +1044,7 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) COPY_FIELD(picture_coding_extension, bits, repeat_first_field); COPY_FIELD(picture_coding_extension, bits, progressive_frame); - gst_vaapi_dpb2_get_references(priv->dpb, picture, + gst_vaapi_dpb_get_neighbours(priv->dpb, picture, &prev_picture, &next_picture); switch (pic_hdr->pic_type) { From e44d8ee6e3c271281c30ca3e26074a0bf9a2b63c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 14 Jan 2013 10:46:25 +0100 Subject: [PATCH 1015/3781] dpb: port to GstVaapiMiniObject. --- gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 179 +++++++++------------ gst-libs/gst/vaapi/gstvaapidecoder_dpb.h | 80 ++------- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 5 +- 3 files changed, 89 insertions(+), 175 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index 51c1c8bc45..17e6fef1f0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -25,38 +25,78 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_GNUC_INTERNAL -GType -gst_vaapi_dpb2_get_type(void) G_GNUC_CONST; +#define GST_VAAPI_DPB_CLASS(klass) \ + ((GstVaapiDpbClass *)(klass)) -#define GST_VAAPI_TYPE_DPB2 \ - (gst_vaapi_dpb2_get_type()) +#define GST_VAAPI_DPB_GET_CLASS(obj) \ + GST_VAAPI_DPB_CLASS(gst_vaapi_mini_object_get_class( \ + GST_VAAPI_MINI_OBJECT(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 Decoded Picture Buffer utilities --- */ /* ------------------------------------------------------------------------- */ static GstVaapiDpb * -dpb_new(GType type, guint max_pictures) +dpb_new(guint max_pictures) { - GstMiniObject *obj; + const GstVaapiMiniObjectClass *klass; GstVaapiDpb *dpb; g_return_val_if_fail(max_pictures > 0, NULL); - obj = gst_mini_object_new(type); - if (!obj) + klass = max_pictures == 2 ? gst_vaapi_dpb2_class() : gst_vaapi_dpb_class(); + + dpb = (GstVaapiDpb *)gst_vaapi_mini_object_new(klass); + if (!dpb) return NULL; - dpb = GST_VAAPI_DPB_CAST(obj); + dpb->num_pictures = 0; + dpb->max_pictures = max_pictures; + dpb->pictures = g_new0(GstVaapiPicture *, max_pictures); if (!dpb->pictures) goto error; - dpb->max_pictures = max_pictures; return dpb; error: - gst_mini_object_unref(obj); + gst_vaapi_dpb_unref(dpb); return NULL; } @@ -130,8 +170,6 @@ dpb_clear(GstVaapiDpb *dpb) /* --- Base Decoded Picture Buffer --- */ /* ------------------------------------------------------------------------- */ -G_DEFINE_TYPE(GstVaapiDpb, gst_vaapi_dpb, GST_TYPE_MINI_OBJECT) - static void gst_vaapi_dpb_base_flush(GstVaapiDpb *dpb) { @@ -224,52 +262,38 @@ gst_vaapi_dpb_base_get_neighbours( } static void -gst_vaapi_dpb_finalize(GstMiniObject *object) +gst_vaapi_dpb_finalize(GstVaapiDpb *dpb) { - GstVaapiDpb * const dpb = GST_VAAPI_DPB_CAST(object); - GstMiniObjectClass *parent_class; - if (dpb->pictures) { dpb_clear(dpb); g_free(dpb->pictures); } - - parent_class = GST_MINI_OBJECT_CLASS(gst_vaapi_dpb_parent_class); - if (parent_class->finalize) - parent_class->finalize(object); } -static void -gst_vaapi_dpb_init(GstVaapiDpb *dpb) +static const GstVaapiMiniObjectClass * +gst_vaapi_dpb_class(void) { - dpb->pictures = NULL; - dpb->num_pictures = 0; - dpb->max_pictures = 0; -} + static const GstVaapiDpbClass GstVaapiDpbClass = { + { sizeof(GstVaapiDpb), + (GDestroyNotify)gst_vaapi_dpb_finalize }, -static void -gst_vaapi_dpb_class_init(GstVaapiDpbClass *klass) -{ - GstMiniObjectClass * const object_class = GST_MINI_OBJECT_CLASS(klass); - - object_class->finalize = gst_vaapi_dpb_finalize; - klass->flush = gst_vaapi_dpb_base_flush; - klass->add = gst_vaapi_dpb_base_add; - klass->get_neighbours = gst_vaapi_dpb_base_get_neighbours; + gst_vaapi_dpb_base_flush, + gst_vaapi_dpb_base_add, + gst_vaapi_dpb_base_get_neighbours + }; + return &GstVaapiDpbClass.parent_class; } GstVaapiDpb * gst_vaapi_dpb_new(guint max_pictures) { - if (G_LIKELY(max_pictures == 2)) - return dpb_new(GST_VAAPI_TYPE_DPB2, max_pictures); - return dpb_new(GST_VAAPI_TYPE_DPB, max_pictures); + return dpb_new(max_pictures); } void gst_vaapi_dpb_flush(GstVaapiDpb *dpb) { - GstVaapiDpbClass *klass; + const GstVaapiDpbClass *klass; g_return_if_fail(GST_VAAPI_IS_DPB(dpb)); @@ -282,7 +306,7 @@ gst_vaapi_dpb_flush(GstVaapiDpb *dpb) gboolean gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) { - GstVaapiDpbClass *klass; + 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); @@ -309,7 +333,7 @@ gst_vaapi_dpb_get_neighbours( GstVaapiPicture **next_picture_ptr ) { - GstVaapiDpbClass *klass; + const GstVaapiDpbClass *klass; g_return_if_fail(GST_VAAPI_IS_DPB(dpb)); g_return_if_fail(GST_VAAPI_IS_PICTURE(picture)); @@ -324,55 +348,6 @@ gst_vaapi_dpb_get_neighbours( /* --- Decoded Picture Buffer (optimized for 2 reference pictures) --- */ /* ------------------------------------------------------------------------- */ -typedef struct _GstVaapiDpb2 GstVaapiDpb2; -typedef struct _GstVaapiDpb2Class GstVaapiDpb2Class; - -#define GST_VAAPI_DPB2_CAST(obj) \ - ((GstVaapiDpb2 *)(obj)) - -#define GST_VAAPI_DPB2(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DPB2, \ - GstVaapiDpb2)) - -#define GST_VAAPI_DPB2_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DPB2, \ - GstVaapiDpb2Class)) - -#define GST_VAAPI_IS_DPB2(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DPB2)) - -#define GST_VAAPI_IS_DPB2_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DPB2)) - -#define GST_VAAPI_DPB2_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DPB2, \ - GstVaapiDpb2Class)) - -/** - * GstVaapiDpb2: - * - * A decoded picture buffer (DPB2) object. - */ -struct _GstVaapiDpb2 { - /*< private >*/ - GstVaapiDpb parent_instance; -}; - -/** - * GstVaapiDpb2Class: - * - * The #GstVaapiDpb2 base class. - */ -struct _GstVaapiDpb2Class { - /*< private >*/ - GstVaapiDpbClass parent_class; -}; - -G_DEFINE_TYPE(GstVaapiDpb2, gst_vaapi_dpb2, GST_VAAPI_TYPE_DPB) - static void gst_vaapi_dpb2_get_neighbours( GstVaapiDpb *dpb, @@ -416,18 +391,18 @@ gst_vaapi_dpb2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) return TRUE; } -static void -gst_vaapi_dpb2_init(GstVaapiDpb2 *dpb) +static const GstVaapiMiniObjectClass * +gst_vaapi_dpb2_class(void) { -} + static const GstVaapiDpbClass GstVaapiDpb2Class = { + { sizeof(GstVaapiDpb), + (GDestroyNotify)gst_vaapi_dpb_finalize }, -static void -gst_vaapi_dpb2_class_init(GstVaapiDpb2Class *klass) -{ - GstVaapiDpbClass * const dpb_class = GST_VAAPI_DPB_CLASS(klass); - - dpb_class->add = gst_vaapi_dpb2_add; - dpb_class->get_neighbours = gst_vaapi_dpb2_get_neighbours; + gst_vaapi_dpb_base_flush, + gst_vaapi_dpb2_add, + gst_vaapi_dpb2_get_neighbours + }; + return &GstVaapiDpb2Class.parent_class; } void diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h index 98acb351ba..18dbf572a8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h @@ -30,70 +30,14 @@ typedef struct _GstVaapiDpb GstVaapiDpb; typedef struct _GstVaapiDpbClass GstVaapiDpbClass; /* ------------------------------------------------------------------------- */ -/* --- Base Decoded Picture Buffer --- */ +/* --- Decoded Picture Buffer --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_TYPE_DPB \ - (gst_vaapi_dpb_get_type()) - -#define GST_VAAPI_DPB_CAST(obj) \ +#define GST_VAAPI_DPB(obj) \ ((GstVaapiDpb *)(obj)) -#define GST_VAAPI_DPB(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DPB, \ - GstVaapiDpb)) - -#define GST_VAAPI_DPB_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DPB, \ - GstVaapiDpbClass)) - #define GST_VAAPI_IS_DPB(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DPB)) - -#define GST_VAAPI_IS_DPB_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DPB)) - -#define GST_VAAPI_DPB_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DPB, \ - GstVaapiDpbClass)) - -/** - * GstVaapiDpb: - * - * A decoded picture buffer (DPB) object. - */ -struct _GstVaapiDpb { - /*< private >*/ - GstMiniObject parent_instance; - - /*< protected >*/ - GstVaapiPicture **pictures; - guint num_pictures; - guint max_pictures; -}; - -/** - * GstVaapiDpbClass: - * - * The #GstVaapiDpb base class. - */ -struct _GstVaapiDpbClass { - /*< private >*/ - GstMiniObjectClass 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); -}; - -G_GNUC_INTERNAL -GType -gst_vaapi_dpb_get_type(void) G_GNUC_CONST; + (GST_VAAPI_DPB(obj) != NULL) G_GNUC_INTERNAL GstVaapiDpb * @@ -120,17 +64,15 @@ gst_vaapi_dpb_get_neighbours( GstVaapiPicture **next_picture_ptr ); -static inline gpointer -gst_vaapi_dpb_ref(gpointer ptr) -{ - return gst_mini_object_ref(GST_MINI_OBJECT(ptr)); -} +#define gst_vaapi_dpb_ref(dpb) \ + gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(dpb)) -static inline void -gst_vaapi_dpb_unref(gpointer ptr) -{ - gst_mini_object_unref(GST_MINI_OBJECT(ptr)); -} +#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 diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 4b32f092d1..c243648685 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -373,10 +373,7 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->slice_hdr, NULL); - if (priv->dpb) { - gst_vaapi_dpb_unref(priv->dpb); - priv->dpb = NULL; - } + gst_vaapi_dpb_replace(&priv->dpb, NULL); } static gboolean From 9372f14f941aeb4fffc70a19d40981a34dd31310 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 14 Jan 2013 10:58:49 +0100 Subject: [PATCH 1016/3781] dpb: cosmetics (clean-ups). --- gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 230 +++++++++++------------ 1 file changed, 105 insertions(+), 125 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index 17e6fef1f0..adcfd828c7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -70,20 +70,18 @@ static const GstVaapiMiniObjectClass * gst_vaapi_dpb2_class(void); /* ------------------------------------------------------------------------- */ -/* --- Common Decoded Picture Buffer utilities --- */ +/* --- Common utilities --- */ /* ------------------------------------------------------------------------- */ -static GstVaapiDpb * +static inline GstVaapiDpb * dpb_new(guint max_pictures) { - const GstVaapiMiniObjectClass *klass; GstVaapiDpb *dpb; g_return_val_if_fail(max_pictures > 0, NULL); - klass = max_pictures == 2 ? gst_vaapi_dpb2_class() : gst_vaapi_dpb_class(); - - dpb = (GstVaapiDpb *)gst_vaapi_mini_object_new(klass); + dpb = (GstVaapiDpb *)gst_vaapi_mini_object_new( + max_pictures == 2 ? gst_vaapi_dpb2_class() : gst_vaapi_dpb_class()); if (!dpb) return NULL; @@ -166,20 +164,20 @@ dpb_clear(GstVaapiDpb *dpb) dpb->num_pictures = 0; } -/* ------------------------------------------------------------------------- */ -/* --- Base Decoded Picture Buffer --- */ -/* ------------------------------------------------------------------------- */ - static void -gst_vaapi_dpb_base_flush(GstVaapiDpb *dpb) +dpb_flush(GstVaapiDpb *dpb) { while (dpb_bump(dpb)) ; dpb_clear(dpb); } +/* ------------------------------------------------------------------------- */ +/* --- Generic implementation --- */ +/* ------------------------------------------------------------------------- */ + static gboolean -gst_vaapi_dpb_base_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) +dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) { guint i; @@ -222,13 +220,9 @@ gst_vaapi_dpb_base_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) return TRUE; } -void -gst_vaapi_dpb_base_get_neighbours( - GstVaapiDpb *dpb, - GstVaapiPicture *picture, - GstVaapiPicture **prev_picture_ptr, - GstVaapiPicture **next_picture_ptr -) +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; @@ -261,13 +255,82 @@ gst_vaapi_dpb_base_get_neighbours( *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) { - if (dpb->pictures) { - dpb_clear(dpb); - g_free(dpb->pictures); - } + dpb_clear(dpb); + g_free(dpb->pictures); } static const GstVaapiMiniObjectClass * @@ -277,13 +340,27 @@ gst_vaapi_dpb_class(void) { sizeof(GstVaapiDpb), (GDestroyNotify)gst_vaapi_dpb_finalize }, - gst_vaapi_dpb_base_flush, - gst_vaapi_dpb_base_add, - gst_vaapi_dpb_base_get_neighbours + 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) { @@ -326,12 +403,8 @@ gst_vaapi_dpb_size(GstVaapiDpb *dpb) } void -gst_vaapi_dpb_get_neighbours( - GstVaapiDpb *dpb, - GstVaapiPicture *picture, - GstVaapiPicture **prev_picture_ptr, - GstVaapiPicture **next_picture_ptr -) +gst_vaapi_dpb_get_neighbours(GstVaapiDpb *dpb, GstVaapiPicture *picture, + GstVaapiPicture **prev_picture_ptr, GstVaapiPicture **next_picture_ptr) { const GstVaapiDpbClass *klass; @@ -343,96 +416,3 @@ gst_vaapi_dpb_get_neighbours( return; klass->get_neighbours(dpb, picture, prev_picture_ptr, next_picture_ptr); } - -/* ------------------------------------------------------------------------- */ -/* --- Decoded Picture Buffer (optimized for 2 reference pictures) --- */ -/* ------------------------------------------------------------------------- */ - -static void -gst_vaapi_dpb2_get_neighbours( - GstVaapiDpb *dpb, - GstVaapiPicture *picture, - GstVaapiPicture **prev_picture_ptr, - GstVaapiPicture **next_picture_ptr -); - -static gboolean -gst_vaapi_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 const GstVaapiMiniObjectClass * -gst_vaapi_dpb2_class(void) -{ - static const GstVaapiDpbClass GstVaapiDpb2Class = { - { sizeof(GstVaapiDpb), - (GDestroyNotify)gst_vaapi_dpb_finalize }, - - gst_vaapi_dpb_base_flush, - gst_vaapi_dpb2_add, - gst_vaapi_dpb2_get_neighbours - }; - return &GstVaapiDpb2Class.parent_class; -} - -void -gst_vaapi_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]; -} From 74b25cabb4d3d05658e2eec50a414bb3bbbf8486 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 14 Jan 2013 12:58:20 +0100 Subject: [PATCH 1017/3781] NEWS: updates. --- NEWS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 853c48e98f..5c4e06da5d 100644 --- a/NEWS +++ b/NEWS @@ -1,13 +1,14 @@ -gst-vaapi NEWS -- summary of changes. 2012-12-DD +gst-vaapi NEWS -- summary of changes. 2013-01-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora -Version 0.5.0 - DD.Dec.2012 +Version 0.5.0 - DD.Jan.2013 * Optimize MPEG-2 and H.264 decoders * Use GstVideoDecoder API for vaapidecode (+Sreerenj Balachandran) * Add support for raw YUV buffers in vaapisink (+Halley Zhao) * Add support for global-alpha subpictures/overlay (+Holger Kaelberer) +* Fix calculation of the vaapidecode time-out for a surface to get released Version 0.4.2 - 18.Dec.2012 * Fix H.264 decoding on Cedar Trail platforms From 059e032103552f286e5512478afb1bef418f1284 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 14 Jan 2013 11:48:58 +0100 Subject: [PATCH 1018/3781] docs: expose new interfaces. --- docs/reference/libs/libs-docs.xml.in | 1 + docs/reference/libs/libs-sections.txt | 61 ++++++++++++++------ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 6 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapiprofile.h | 3 + 5 files changed, 52 insertions(+), 21 deletions(-) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 474a64144a..a7873bdf4e 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -28,6 +28,7 @@ + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index bcbaf95970..11c742f6d6 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -140,6 +140,11 @@ gst_vaapi_display_get_image_caps gst_vaapi_display_has_image_format gst_vaapi_display_get_subpicture_caps gst_vaapi_display_has_subpicture_format +gst_vaapi_display_has_property +gst_vaapi_display_get_rotation +gst_vaapi_display_set_rotation +gst_vaapi_display_get_render_mode +gst_vaapi_display_set_render_mode GST_VAAPI_DISPLAY GST_VAAPI_IS_DISPLAY @@ -171,23 +176,8 @@ GST_VAAPI_IMAGE_POOL_GET_CLASS GstVaapiVideoBuffer GstVaapiVideoBuffer GstVaapiVideoBufferClass -gst_vaapi_video_buffer_typed_new -gst_vaapi_video_buffer_typed_new_from_pool -gst_vaapi_video_buffer_typed_new_from_buffer -gst_vaapi_video_buffer_typed_new_with_image -gst_vaapi_video_buffer_typed_new_with_surface -gst_vaapi_video_buffer_typed_new_with_surface_proxy -gst_vaapi_video_buffer_get_display -gst_vaapi_video_buffer_get_image -gst_vaapi_video_buffer_set_image -gst_vaapi_video_buffer_set_image_from_pool -gst_vaapi_video_buffer_get_surface -gst_vaapi_video_buffer_get_surface_proxy -gst_vaapi_video_buffer_set_surface -gst_vaapi_video_buffer_set_surface_proxy -gst_vaapi_video_buffer_set_surface_from_pool -gst_vaapi_video_buffer_get_render_flags -gst_vaapi_video_buffer_set_render_flags +gst_vaapi_video_buffer_new +gst_vaapi_video_buffer_get_meta GST_VAAPI_VIDEO_BUFFER GST_VAAPI_IS_VIDEO_BUFFER @@ -198,6 +188,34 @@ GST_VAAPI_IS_VIDEO_BUFFER_CLASS GST_VAAPI_VIDEO_BUFFER_GET_CLASS
+
+gstvaapivideometa +GstVaapiVideoMeta +gst_vaapi_video_meta_new +gst_vaapi_video_meta_new_from_pool +gst_vaapi_video_meta_new_with_image +gst_vaapi_video_meta_new_with_surface +gst_vaapi_video_meta_new_with_surface_proxy +gst_vaapi_video_meta_ref +gst_vaapi_video_meta_unref +gst_vaapi_video_meta_replace +gst_vaapi_video_meta_get_display +gst_vaapi_video_meta_get_image +gst_vaapi_video_meta_set_image +gst_vaapi_video_meta_set_image_from_pool +gst_vaapi_video_meta_get_surface +gst_vaapi_video_meta_set_surface +gst_vaapi_video_meta_set_surface_from_pool +gst_vaapi_video_meta_set_surface_converter +gst_vaapi_video_meta_get_surface_converter +gst_vaapi_video_meta_get_surface_proxy +gst_vaapi_video_meta_set_surface_proxy +gst_vaapi_video_meta_get_render_flags +gst_vaapi_video_meta_set_render_flags + +gst_vaapi_video_meta_get_type +
+
gstvaapitypes Basic data structures @@ -345,7 +363,11 @@ GST_VAAPI_SURFACE_GET_CLASS GstVaapiSubpicture GstVaapiSubpictureClass gst_vaapi_subpicture_new +gst_vaapi_subpicture_new_from_overlay_rectangle gst_vaapi_subpicture_get_id +gst_vaapi_subpicture_get_flags +gst_vaapi_subpicture_get_global_alpha +gst_vaapi_subpicture_set_global_alpha gst_vaapi_subpicture_get_image gst_vaapi_subpicture_set_image @@ -446,8 +468,13 @@ GstVaapiDecoderStatus GstVaapiDecoder GstVaapiDecoderClass gst_vaapi_decoder_get_caps +gst_vaapi_decoder_get_codec +gst_vaapi_decoder_get_codec_state gst_vaapi_decoder_put_buffer gst_vaapi_decoder_get_surface +gst_vaapi_decoder_get_frame +gst_vaapi_decoder_parse +gst_vaapi_decoder_decode GST_VAAPI_DECODER GST_VAAPI_IS_DECODER diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 2dcdde3f21..f6066e9cb2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -55,7 +55,7 @@ typedef enum { } GstVaapiPictureType; /** - * Picture flags: + * GstVaapiPictureFlags: * @GST_VAAPI_PICTURE_FLAG_SKIPPED: skipped frame * @GST_VAAPI_PICTURE_FLAG_REFERENCE: reference frame * @GST_VAAPI_PICTURE_FLAG_OUTPUT: frame was output @@ -66,7 +66,7 @@ typedef enum { * * Enum values used for #GstVaapiPicture flags. */ -enum { +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), @@ -74,7 +74,7 @@ enum { 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_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 6), -}; +} 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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 4677a79bdb..f8acf62fb2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1406,7 +1406,7 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) * gst_vaapi_display_has_subpicture_format: * @display: a #GstVaapiDisplay * @format: a #GstVaapiFormat - * @flags: #GstVaapiSubpictureFlags, or zero + * @flags_ptr: pointer to #GstVaapiSubpictureFlags, or zero * * Returns whether VA @display supports @format subpicture format with * the supplied @flags. diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index a3a0f95d61..1be5f8ffa1 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -35,6 +35,7 @@ G_BEGIN_DECLS * @GST_VAAPI_CODEC_H264: H.264 aka MPEG-4 Part 10 (ISO/IEC 14496-10) * @GST_VAAPI_CODEC_WMV3: Windows Media Video 9. VC-1 Simple or Main profile (SMPTE 421M) * @GST_VAAPI_CODEC_VC1: VC-1 Advanced profile (SMPTE 421M) + * @GST_VAAPI_CODEC_JPEG: JPEG (ITU-T 81) * * The set of all codecs for #GstVaapiCodec. */ @@ -92,6 +93,8 @@ typedef enum { * VC-1 main profile * @GST_VAAPI_PROFILE_VC1_ADVANCED: * VC-1 advanced profile + * @GST_VAAPI_PROFILE_JPEG_BASELINE: + * JPEG baseline profile * * The set of all profiles for #GstVaapiProfile. */ From 154fa7baf65910cb8a472793d431e09a709e1761 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 15 Jan 2013 09:21:08 +0100 Subject: [PATCH 1019/3781] 0.5.0. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 5c4e06da5d..8ee2fabd19 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2013-01-DD +gst-vaapi NEWS -- summary of changes. 2013-01-15 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora -Version 0.5.0 - DD.Jan.2013 +Version 0.5.0 - 15.Jan.2013 * Optimize MPEG-2 and H.264 decoders * Use GstVideoDecoder API for vaapidecode (+Sreerenj Balachandran) * Add support for raw YUV buffers in vaapisink (+Halley Zhao) diff --git a/configure.ac b/configure.ac index 85b3f41b13..97e15c2fd8 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_pre_version], [2]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From e13bca460944ea5f4affdc98200b46e8727fe5ee Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 15 Jan 2013 09:21:36 +0100 Subject: [PATCH 1020/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 97e15c2fd8..2c2ff5bc91 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 9485b17fd76a1ac30198cdff3502b9a3191cc094 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 17 Jan 2013 15:47:17 +0100 Subject: [PATCH 1021/3781] codecparsers: update to gst-vaapi-branch commit b47983a. 8840c2d h264: zero-initialize SPS VUI parameters --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index b47983a6ab..59acdd7e26 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit b47983a6ab0893815f62c03b4410b7104463c57f +Subproject commit 59acdd7e268e0b2d6648652c71ada55bab01d00e From cc347cb41e0b79406acb0d70a91768fc5b402d77 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 15 Jan 2013 16:55:29 +0100 Subject: [PATCH 1022/3781] decoder: make decode_step() return once the frame is decoded. Make sure we always have a free surface left to use for decoding the current frame. This means that decode_step() has to return once a frame gets decoded. If the current adapter contains more buffers with valid frames, they will get parsed and decoded on subsequent iterations. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 966d3ea784..4cb18fc0b2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -264,13 +264,16 @@ decode_step(GstVaapiDecoder *decoder) GstVaapiParserState * const ps = &priv->parser_state; GstVaapiDecoderStatus status; GstBuffer *buffer; - gboolean at_eos, got_frame; + gboolean got_frame, at_eos = FALSE; guint got_unit_size; status = gst_vaapi_decoder_check_status(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; + if (ps->current_frame) + goto parse; + do { buffer = pop_buffer(decoder); if (!buffer) @@ -288,6 +291,7 @@ decode_step(GstVaapiDecoder *decoder) ps->current_frame->ref_count = 1; } + parse: status = do_parse(decoder, ps->current_frame, ps->input_adapter, at_eos, &got_unit_size, &got_frame); GST_DEBUG("parse frame (status = %d)", status); @@ -314,6 +318,7 @@ decode_step(GstVaapiDecoder *decoder) gst_video_codec_frame_unref(ps->current_frame); ps->current_frame = NULL; + break; } } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && gst_adapter_available(ps->input_adapter) > 0); @@ -634,13 +639,12 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, g_return_val_if_fail(out_proxy_ptr != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - frame = pop_frame(decoder); - if (!frame) { - do { - status = decode_step(decoder); - } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); + do { frame = pop_frame(decoder); - } + if (frame) + break; + status = decode_step(decoder); + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); if (frame) { *out_proxy_ptr = gst_vaapi_surface_proxy_ref(frame->user_data); From e4e3a58bc0ed2eb8110e8ecef2f0ac9959ba1126 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 15 Jan 2013 17:21:50 +0100 Subject: [PATCH 1023/3781] decoder: fix check for end-of-stream in raw API mode. Make sure to immediately return GST_VAAPI_DECODER_STATUS_END_OF_STREAM if the end-of-stream was already reached at the previous iteration. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 11 +++++++---- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 4cb18fc0b2..5abdfc5fd5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -264,9 +264,12 @@ decode_step(GstVaapiDecoder *decoder) GstVaapiParserState * const ps = &priv->parser_state; GstVaapiDecoderStatus status; GstBuffer *buffer; - gboolean got_frame, at_eos = FALSE; + gboolean got_frame; guint got_unit_size; + if (G_UNLIKELY(ps->at_eos)) + return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + status = gst_vaapi_decoder_check_status(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; @@ -279,8 +282,8 @@ decode_step(GstVaapiDecoder *decoder) if (!buffer) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - at_eos = GST_BUFFER_IS_EOS(buffer); - if (!at_eos) + ps->at_eos = GST_BUFFER_IS_EOS(buffer); + if (!ps->at_eos) gst_adapter_push(ps->input_adapter, buffer); do { @@ -293,7 +296,7 @@ decode_step(GstVaapiDecoder *decoder) parse: status = do_parse(decoder, ps->current_frame, - ps->input_adapter, at_eos, &got_unit_size, &got_frame); + ps->input_adapter, ps->at_eos, &got_unit_size, &got_frame); GST_DEBUG("parse frame (status = %d)", status); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) break; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 968f49a46f..1887ee4cbd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -153,7 +153,8 @@ struct _GstVaapiParserState { gint input_offset2; GstAdapter *output_adapter; GstVaapiDecoderUnit next_unit; - gboolean next_unit_pending; + guint next_unit_pending : 1; + guint at_eos : 1; }; struct _GstVaapiDecoderPrivate { From 60acedb56e5899df73a396e58626277729552036 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 17 Jan 2013 18:33:32 +0100 Subject: [PATCH 1024/3781] decoder: add GstVaapiDecoder::flush() hook. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 19 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder.h | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 5abdfc5fd5..7437582631 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -257,6 +257,16 @@ do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) return status; } +static inline GstVaapiDecoderStatus +do_flush(GstVaapiDecoder *decoder) +{ + GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); + + if (klass->flush) + return klass->flush(decoder); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus decode_step(GstVaapiDecoder *decoder) { @@ -896,3 +906,12 @@ gst_vaapi_decoder_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) return status; return do_decode(decoder, frame); } + +GstVaapiDecoderStatus +gst_vaapi_decoder_flush(GstVaapiDecoder *decoder) +{ + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + + return do_flush(decoder); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 050992ce52..7af4a3a2e5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -123,6 +123,7 @@ struct _GstVaapiDecoderClass { GstVaapiDecoderStatus (*start_frame)(GstVaapiDecoder *decoder, struct _GstVaapiDecoderUnit *unit); GstVaapiDecoderStatus (*end_frame)(GstVaapiDecoder *decoder); + GstVaapiDecoderStatus (*flush)(GstVaapiDecoder *decoder); }; GType @@ -156,6 +157,9 @@ gst_vaapi_decoder_parse(GstVaapiDecoder *decoder, GstVaapiDecoderStatus gst_vaapi_decoder_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame); +GstVaapiDecoderStatus +gst_vaapi_decoder_flush(GstVaapiDecoder *decoder); + G_END_DECLS #endif /* GST_VAAPI_DECODER_H */ From cbcdc3bfae86adfa6cd3797642b9ecaf5c436195 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 17 Jan 2013 18:19:14 +0100 Subject: [PATCH 1025/3781] vaapidecode: split gvd_handle_frame() into decode/push frames. Split GstVideoDecoder::handle_frame() implementation into two functions: (i) one for decoding the provided GstVideoCodecFrame and (ii) another one for purging all decoded frames and submit them downstream. --- gst/vaapi/gstvaapidecode.c | 72 +++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 572d8a9fa5..ac82c752d7 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -177,12 +177,10 @@ gst_vaapidecode_release(GstVaapiDecode *decode) } static GstFlowReturn -gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) +gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - GstVaapiSurfaceProxy *proxy; GstVaapiDecoderStatus status; - GstVideoCodecFrame *out_frame; GstFlowReturn ret; gint64 end_time; @@ -212,6 +210,41 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) goto error_decode; break; } + return GST_FLOW_OK; + + /* ERRORS */ +error_decode_timeout: + { + GST_WARNING("decode timeout. Decoder required a VA surface but none " + "got available within one second"); + return GST_FLOW_UNEXPECTED; + } +error_decode: + { + GST_ERROR("decode error %d", status); + switch (status) { + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: + ret = GST_FLOW_NOT_SUPPORTED; + break; + default: + ret = GST_FLOW_UNEXPECTED; + break; + } + gst_video_decoder_drop_frame(vdec, frame); + return ret; + } +} + +static GstFlowReturn +gst_vaapidecode_push_decoded_frames(GstVideoDecoder *vdec) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + GstVaapiSurfaceProxy *proxy; + GstVaapiDecoderStatus status; + GstVideoCodecFrame *out_frame; + GstFlowReturn ret; /* Output all decoded frames */ for (;;) { @@ -239,28 +272,6 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) return GST_FLOW_OK; /* ERRORS */ -error_decode_timeout: - { - GST_WARNING("decode timeout. Decoder required a VA surface but none " - "got available within one second"); - return GST_FLOW_UNEXPECTED; - } -error_decode: - { - GST_ERROR("decode error %d", status); - switch (status) { - case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: - case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: - case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: - ret = GST_FLOW_NOT_SUPPORTED; - break; - default: - ret = GST_FLOW_UNEXPECTED; - break; - } - gst_video_decoder_drop_frame(vdec, frame); - return ret; - } error_create_buffer: { const GstVaapiID surface_id = @@ -281,6 +292,17 @@ error_commit_buffer: } } +static GstFlowReturn +gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) +{ + GstFlowReturn ret; + + ret = gst_vaapidecode_decode_frame(vdec, frame); + if (ret != GST_FLOW_OK) + return ret; + return gst_vaapidecode_push_decoded_frames(vdec); +} + static inline gboolean gst_vaapidecode_ensure_display(GstVaapiDecode *decode) { From 236e8833d12d325570056a6a188f026a1d109cb3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 17 Jan 2013 18:22:49 +0100 Subject: [PATCH 1026/3781] vaapidecode: handle EOS events. Flush all decoded frames to downstream when EOS is received. This is performed by implementing GstVideoDecoder::finish() hook. --- gst/vaapi/gstvaapidecode.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ac82c752d7..e33a73444a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -303,6 +303,25 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) return gst_vaapidecode_push_decoded_frames(vdec); } +static GstFlowReturn +gst_vaapidecode_finish(GstVideoDecoder *vdec) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + GstVaapiDecoderStatus status; + + status = gst_vaapi_decoder_flush(decode->decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto error_flush; + return gst_vaapidecode_push_decoded_frames(vdec); + + /* ERRORS */ +error_flush: + { + GST_ERROR("failed to flush decoder (status %d)", status); + return GST_FLOW_UNEXPECTED; + } +} + static inline gboolean gst_vaapidecode_ensure_display(GstVaapiDecode *decode) { @@ -532,6 +551,7 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) vdec_class->set_format = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_format); vdec_class->parse = GST_DEBUG_FUNCPTR(gst_vaapidecode_parse); vdec_class->handle_frame = GST_DEBUG_FUNCPTR(gst_vaapidecode_handle_frame); + vdec_class->finish = GST_DEBUG_FUNCPTR(gst_vaapidecode_finish); gst_element_class_set_details_simple( element_class, From 34162f500192ad558f5ee6c40a4337ef1c76805c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 17 Jan 2013 18:07:03 +0100 Subject: [PATCH 1027/3781] h264: handle end-of-stream NALU. Handle NAL unit to actually flush any pending picture from the DPB. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 2c5a8978b8..dae14678a4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2743,6 +2743,7 @@ decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) status = decode_slice(decoder, unit); break; case GST_H264_NAL_SEQ_END: + case GST_H264_NAL_STREAM_END: status = decode_sequence_end(decoder); break; case GST_H264_NAL_SEI: From 319f87f142ec49677b4e22aeec07468a2ab4eeae Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 17 Jan 2013 18:35:58 +0100 Subject: [PATCH 1028/3781] h264: implement GstVaapiDecoder::flush() as a DPB flush. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index dae14678a4..7ca10fc3fb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -3036,6 +3036,16 @@ gst_vaapi_decoder_h264_end_frame(GstVaapiDecoder *base_decoder) return decode_current_picture(decoder); } +static GstVaapiDecoderStatus +gst_vaapi_decoder_h264_flush(GstVaapiDecoder *base_decoder) +{ + GstVaapiDecoderH264 * const decoder = + GST_VAAPI_DECODER_H264_CAST(base_decoder); + + dpb_flush(decoder); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static void gst_vaapi_decoder_h264_finalize(GObject *object) { @@ -3075,6 +3085,7 @@ gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass) decoder_class->decode = gst_vaapi_decoder_h264_decode; decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame; decoder_class->end_frame = gst_vaapi_decoder_h264_end_frame; + decoder_class->flush = gst_vaapi_decoder_h264_flush; } static void From ea3905fa148b6be76450ab45734687e8ff84a450 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 15 Jan 2013 17:47:13 +0100 Subject: [PATCH 1029/3781] tests: allow fullscreen mode. Add new --fullscreen|-f option to create new windows in fullscreen mode. --- tests/output.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/output.c b/tests/output.c index 438c04c0d3..a1b427f445 100644 --- a/tests/output.c +++ b/tests/output.c @@ -72,6 +72,7 @@ static const VideoOutputInfo g_video_outputs[] = { static gchar *g_output_name; static gboolean g_list_outputs = FALSE; +static gboolean g_fullscreen = FALSE; static GOptionEntry g_options[] = { { "list-outputs", 0, @@ -82,6 +83,10 @@ static GOptionEntry g_options[] = { 0, G_OPTION_ARG_STRING, &g_output_name, "video output name", NULL }, + { "fullscreen", 'f', + 0, + G_OPTION_ARG_NONE, &g_fullscreen, + "fullscreen mode", NULL }, { NULL, } }; @@ -181,7 +186,17 @@ video_output_create_display(const gchar *display_name) GstVaapiWindow * video_output_create_window(GstVaapiDisplay *display, guint width, guint height) { + GstVaapiWindow *window; + if (!g_video_output) return NULL; - return g_video_output->create_window(display, width, height); + + window = g_video_output->create_window(display, width, height); + if (!window) + return NULL; + + /* Force fullscreen mode, should this be requested by the user */ + if (g_fullscreen) + gst_vaapi_window_set_fullscreen(window, TRUE); + return window; } From b22bade3106d097ce767befb46b9786e095e7497 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 15 Jan 2013 17:30:57 +0100 Subject: [PATCH 1030/3781] tests: add codec helper utils. Add helper functions to determine the codec type from a specific file or utility functions to convert from codec type to GstCaps or from codec name to codec type. --- tests/Makefile.am | 4 +- tests/codec.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++ tests/codec.h | 39 ++++++++++ 3 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 tests/codec.c create mode 100644 tests/codec.h diff --git a/tests/Makefile.am b/tests/Makefile.am index 3c98df0a24..83d1e773ab 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -67,8 +67,8 @@ test_utils_dec_source_c = \ $(NULL) test_utils_dec_source_h = $(test_utils_dec_source_c:%.c=%.h) test-decode.h -test_utils_source_c = image.c output.c -test_utils_source_h = image.h output.h +test_utils_source_c = codec.c image.c output.c +test_utils_source_h = codec.h image.h output.h noinst_LTLIBRARIES = libutils.la libutils_dec.la libutils_la_SOURCES = $(test_utils_source_c) diff --git a/tests/codec.c b/tests/codec.c new file mode 100644 index 0000000000..5288589e59 --- /dev/null +++ b/tests/codec.c @@ -0,0 +1,192 @@ +/* + * codec.c - Codec utilities for the tests + * + * Copyright (C) 2013 Intel Corporation + * + * 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 "config.h" +#include +#include "codec.h" + +typedef struct { + const gchar *codec_str; + GstVaapiCodec codec; + const gchar *caps_str; +} CodecMap; + +static const CodecMap g_codec_map[] = { + { "h264", GST_VAAPI_CODEC_H264, + "video/x-h264" }, + { "jpeg", GST_VAAPI_CODEC_JPEG, + "image/jpeg" }, + { "mpeg2", GST_VAAPI_CODEC_MPEG2, + "video/mpeg, mpegversion=2" }, + { "mpeg4", GST_VAAPI_CODEC_MPEG4, + "video/mpeg, mpegversion=4" }, + { "wmv3", GST_VAAPI_CODEC_VC1, + "video/x-wmv, wmvversion=3" }, + { "vc1", GST_VAAPI_CODEC_VC1, + "video/x-wmv, wmvversion=3, format=(fourcc)WVC1" }, + { NULL, } +}; + +static const CodecMap * +get_codec_map(GstVaapiCodec codec) +{ + const CodecMap *m; + + if (codec) { + for (m = g_codec_map; m->codec_str != NULL; m++) { + if (m->codec == codec) + return m; + } + } + return NULL; +} + +const gchar * +string_from_codec(GstVaapiCodec codec) +{ + const CodecMap * const m = get_codec_map(codec); + + return m ? m->codec_str : NULL; +} + +GstCaps * +caps_from_codec(GstVaapiCodec codec) +{ + const CodecMap * const m = get_codec_map(codec); + + return m ? gst_caps_from_string(m->caps_str) : NULL; +} + +GstVaapiCodec +identify_codec_from_string(const gchar *codec_str) +{ + const CodecMap *m; + + if (codec_str) { + for (m = g_codec_map; m->codec_str != NULL; m++) { + if (g_ascii_strcasecmp(m->codec_str, codec_str) == 0) + return m->codec; + } + } + return 0; +} + +typedef struct { + GMappedFile *file; + guint8 *data; + guint size; + guint probability; + GstCaps *caps; + GstTypeFind type_find; +} CodecIdentifier; + +static guint8 * +codec_identifier_peek(gpointer data, gint64 offset, guint size) +{ + CodecIdentifier * const cip = data; + + if (offset >= 0 && offset + size <= cip->size) + return cip->data + offset; + if (offset < 0 && ((gint)cip->size + offset) >= 0) + return &cip->data[cip->size + offset]; + return NULL; +} + +static void +codec_identifier_suggest(gpointer data, guint probability, const GstCaps *caps) +{ + CodecIdentifier * const cip = data; + + if (cip->probability < probability) { + cip->probability = probability; + gst_caps_replace(&cip->caps, (GstCaps *)caps); + } +} + +static void +codec_identifier_free(CodecIdentifier *cip) +{ + if (!cip) + return; + + if (cip->file) { + g_mapped_file_unref(cip->file); + cip->file = NULL; + } + gst_caps_replace(&cip->caps, NULL); + g_slice_free(CodecIdentifier, cip); +} + +static CodecIdentifier * +codec_identifier_new(const gchar *filename) +{ + CodecIdentifier *cip; + GstTypeFind *tfp; + + cip = g_slice_new0(CodecIdentifier); + if (!cip) + return NULL; + + cip->file = g_mapped_file_new(filename, FALSE, NULL); + if (!cip->file) + goto error; + + cip->size = g_mapped_file_get_length(cip->file); + cip->data = (guint8 *)g_mapped_file_get_contents(cip->file); + if (!cip->data) + goto error; + + tfp = &cip->type_find; + tfp->peek = codec_identifier_peek; + tfp->suggest = codec_identifier_suggest; + tfp->data = cip; + return cip; + +error: + codec_identifier_free(cip); + return NULL; +} + +GstVaapiCodec +identify_codec(const gchar *filename) +{ + CodecIdentifier *cip; + GList *type_list, *l; + guint32 codec = 0; + + cip = codec_identifier_new(filename); + if (!cip) + return 0; + + type_list = gst_type_find_factory_get_list(); + for (l = type_list; l != NULL; l = l->next) { + GstTypeFindFactory * const factory = GST_TYPE_FIND_FACTORY(l->data); + gst_type_find_factory_call_function(factory, &cip->type_find); + } + g_list_free(type_list); + + if (cip->probability >= GST_TYPE_FIND_LIKELY) + codec = gst_vaapi_profile_get_codec( + gst_vaapi_profile_from_caps(cip->caps)); + + codec_identifier_free(cip); + return codec; +} diff --git a/tests/codec.h b/tests/codec.h new file mode 100644 index 0000000000..fad160b241 --- /dev/null +++ b/tests/codec.h @@ -0,0 +1,39 @@ +/* + * codec.h - Codec utilities for the tests + * + * Copyright (C) 2013 Intel Corporation + * + * 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 CODEC_H +#define CODEC_H + +#include + +const gchar * +string_from_codec(GstVaapiCodec codec); + +GstCaps * +caps_from_codec(GstVaapiCodec codec); + +GstVaapiCodec +identify_codec_from_string(const gchar *codec_str); + +GstVaapiCodec +identify_codec(const gchar *filename); + +#endif /* CODEC_H */ From c094fe303849a384d6761c512c235e1e04a33a2d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 15 Jan 2013 17:33:18 +0100 Subject: [PATCH 1031/3781] tests: add simple decoder application. Add simple decoder application to show off decoding capabilities from raw bitstreams, for debugging or performance evaluation purposes. --- tests/Makefile.am | 8 + tests/simple-decoder.c | 577 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 585 insertions(+) create mode 100644 tests/simple-decoder.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 83d1e773ab..dbba30effe 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,5 @@ noinst_PROGRAMS = \ + simple-decoder \ test-decode \ test-display \ test-surfaces \ @@ -101,8 +102,15 @@ test_textures_SOURCES = test-textures.c test_textures_CFLAGS = $(TEST_CFLAGS) test_textures_LDADD = libutils.la $(TEST_LIBS) +simple_decoder_source_c = simple-decoder.c +simple_decoder_source_h = +simple_decoder_SOURCES = $(simple_decoder_source_c) +simple_decoder_CFLAGS = $(TEST_CFLAGS) +simple_decoder_LDADD = libutils.la $(TEST_LIBS) + EXTRA_DIST = \ test-subpicture-data.h \ + $(simple_decoder_source_h) \ $(test_utils_dec_source_h) \ $(test_utils_source_h) \ $(NULL) diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c new file mode 100644 index 0000000000..76d4c3959c --- /dev/null +++ b/tests/simple-decoder.c @@ -0,0 +1,577 @@ +/* + * simple-decoder.c - Simple Decoder Application + * + * Copyright (C) 2013 Intel Corporation + * + * 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 + */ + +/* + * This is a really simple decoder application that only accepts raw + * bitstreams. So, it may be needed to suggest what codec to use to + * the application. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "codec.h" +#include "output.h" + +static gchar *g_codec_str; + +static GOptionEntry g_options[] = { + { "codec", 'c', + 0, + G_OPTION_ARG_STRING, &g_codec_str, + "suggested codec", NULL }, + { NULL, } +}; + +typedef enum { + APP_RUNNING, + APP_GOT_EOS, + APP_GOT_ERROR, +} AppEvent; + +typedef enum { + APP_ERROR_NONE, + APP_ERROR_DECODER, + APP_ERROR_RENDERER, +} AppError; + +typedef struct { + GMutex mutex; + GMappedFile *file; + gchar *file_name; + guint file_offset; + guint file_size; + guchar *file_data; + GstVaapiDisplay *display; + GstVaapiDecoder *decoder; + GThread *decoder_thread; + volatile gboolean decoder_thread_cancel; + GCond decoder_ready; + GAsyncQueue *decoder_queue; + GstVaapiCodec codec; + GstVideoCodecState codec_state; + GstVaapiWindow *window; + GThread *render_thread; + volatile gboolean render_thread_cancel; + GstBuffer *last_buffer; + GError *error; + AppEvent event; + GCond event_cond; +} App; + +#define APP_ERROR app_error_quark() +static GQuark +app_error_quark(void) +{ + static gsize g_quark; + + if (g_once_init_enter(&g_quark)) { + gsize quark = (gsize)g_quark_from_static_string("AppError"); + g_once_init_leave(&g_quark, quark); + } + return g_quark; +} + +static void +app_send_error(App *app, GError *error) +{ + g_mutex_lock(&app->mutex); + app->error = error; + app->event = APP_GOT_ERROR; + g_cond_signal(&app->event_cond); + g_mutex_unlock(&app->mutex); +} + +static void +app_send_eos(App *app) +{ + g_mutex_lock(&app->mutex); + app->event = APP_GOT_EOS; + g_cond_signal(&app->event_cond); + g_mutex_unlock(&app->mutex); +} + +static const gchar * +get_decoder_status_string(GstVaapiDecoderStatus status) +{ + const gchar *str; + +#define DEFINE_STATUS(status, status_string) \ + case GST_VAAPI_DECODER_STATUS_##status: \ + str = status_string; \ + break + + switch (status) { + DEFINE_STATUS(SUCCESS, ""); + DEFINE_STATUS(END_OF_STREAM, ""); + DEFINE_STATUS(ERROR_ALLOCATION_FAILED, "allocation failed"); + DEFINE_STATUS(ERROR_INIT_FAILED, "initialization failed"); + DEFINE_STATUS(ERROR_UNSUPPORTED_CODEC, "unsupported codec"); + DEFINE_STATUS(ERROR_NO_DATA, "not enough data"); + DEFINE_STATUS(ERROR_NO_SURFACE, "no surface vailable"); + DEFINE_STATUS(ERROR_INVALID_SURFACE, "invalid surface"); + DEFINE_STATUS(ERROR_BITSTREAM_PARSER, "bitstream parser error"); + DEFINE_STATUS(ERROR_UNSUPPORTED_PROFILE, + "unsupported profile"); + DEFINE_STATUS(ERROR_UNSUPPORTED_CHROMA_FORMAT, + "unsupported chroma-format"); + DEFINE_STATUS(ERROR_INVALID_PARAMETER, "invalid parameter"); + default: + str = ""; + break; + } +#undef DEFINE_STATUS + + return str; +} + +static const gchar * +get_error_string(AppError error) +{ + const gchar *str; + +#define DEFINE_ERROR(error, error_string) \ + case APP_ERROR_##error: \ + str = error_string; \ + break + + switch (error) { + DEFINE_ERROR(NONE, ""); + DEFINE_ERROR(DECODER, "decoder"); + DEFINE_ERROR(RENDERER, "renderer"); + default: + str = "unknown"; + break; + } +#undef DEFINE_ERROR + + return str; +} + +static void +decoder_release(App *app) +{ + g_mutex_lock(&app->mutex); + g_cond_signal(&app->decoder_ready); + g_mutex_unlock(&app->mutex); +} + +static gpointer +decoder_thread(gpointer data) +{ + App * const app = data; + GError *error = NULL; + GstVaapiDecoderStatus status; + GstVaapiSurfaceProxy *proxy; + GstVaapiVideoMeta *meta; + GstBuffer *buffer; + gboolean got_surface; + gint64 end_time; + guint ofs; + + g_print("Decoder thread started\n"); + +#define SEND_ERROR(...) \ + do { \ + error = g_error_new(APP_ERROR, APP_ERROR_DECODER, __VA_ARGS__); \ + goto send_error; \ + } while (0) + + ofs = 0; + while (!app->decoder_thread_cancel) { + if (G_UNLIKELY(ofs == app->file_size)) + buffer = NULL; + else { + buffer = gst_buffer_new(); + if (!buffer) + SEND_ERROR("failed to allocate new buffer"); + + GST_BUFFER_DATA(buffer) = app->file_data + ofs; + GST_BUFFER_SIZE(buffer) = MIN(4096, app->file_size - ofs); + ofs += GST_BUFFER_SIZE(buffer); + } + if (!gst_vaapi_decoder_put_buffer(app->decoder, buffer)) + SEND_ERROR("failed to push buffer to decoder"); + gst_buffer_replace(&buffer, NULL); + + get_surface: + status = gst_vaapi_decoder_get_surface(app->decoder, &proxy); + switch (status) { + case GST_VAAPI_DECODER_STATUS_SUCCESS: + gst_vaapi_surface_proxy_set_user_data(proxy, + app, (GDestroyNotify)decoder_release); + meta = gst_vaapi_video_meta_new_with_surface_proxy(proxy); + gst_vaapi_surface_proxy_unref(proxy); + if (!meta) + SEND_ERROR("failed to allocate video meta"); + buffer = gst_buffer_new(); + if (!buffer) + SEND_ERROR("failed to allocate output buffer"); + gst_buffer_set_vaapi_video_meta(buffer, meta); + gst_vaapi_video_meta_unref(meta); + g_async_queue_push(app->decoder_queue, buffer); + break; + case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: + /* nothing to do, just continue to the next iteration */ + break; + case GST_VAAPI_DECODER_STATUS_END_OF_STREAM: + goto send_eos; + case GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE: + end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND; + g_mutex_lock(&app->mutex); + got_surface = g_cond_wait_until(&app->decoder_ready, &app->mutex, + end_time); + g_mutex_unlock(&app->mutex); + if (got_surface) + goto get_surface; + SEND_ERROR("failed to acquire a surface within one second"); + break; + default: + SEND_ERROR("%s", get_decoder_status_string(status)); + break; + } + } + return NULL; + +#undef SEND_ERROR + +send_eos: + app_send_eos(app); + return NULL; + +send_error: + app_send_error(app, error); + return NULL; +} + +static gboolean +start_decoder(App *app) +{ + GstCaps *caps; + + app->file = g_mapped_file_new(app->file_name, FALSE, NULL); + if (!app->file) + return FALSE; + + app->file_size = g_mapped_file_get_length(app->file); + app->file_data = (guint8 *)g_mapped_file_get_contents(app->file); + if (!app->file_data) + return FALSE; + + caps = caps_from_codec(app->codec); + switch (app->codec) { + case GST_VAAPI_CODEC_H264: + app->decoder = gst_vaapi_decoder_h264_new(app->display, caps); + break; +#if USE_JPEG_DECODER + case GST_VAAPI_CODEC_JPEG: + app->decoder = gst_vaapi_decoder_jpeg_new(app->display, caps); + break; +#endif + case GST_VAAPI_CODEC_MPEG2: + app->decoder = gst_vaapi_decoder_mpeg2_new(app->display, caps); + break; + case GST_VAAPI_CODEC_MPEG4: + app->decoder = gst_vaapi_decoder_mpeg4_new(app->display, caps); + break; + case GST_VAAPI_CODEC_VC1: + app->decoder = gst_vaapi_decoder_vc1_new(app->display, caps); + break; + default: + app->decoder = NULL; + break; + } + if (!app->decoder) + return FALSE; + + app->decoder_thread = g_thread_create(decoder_thread, app, TRUE, NULL); + if (!app->decoder_thread) + return FALSE; + return TRUE; +} + +static gboolean +stop_decoder(App *app) +{ + app->decoder_thread_cancel = TRUE; + g_thread_join(app->decoder_thread); + g_print("Decoder thread stopped\n"); + return TRUE; +} + +static gboolean +renderer_process(App *app, GstBuffer *buffer) +{ + GError *error = NULL; + GstVaapiVideoMeta *meta; + GstVaapiSurface *surface; + +#define SEND_ERROR(...) \ + do { \ + error = g_error_new(APP_ERROR, APP_ERROR_RENDERER, __VA_ARGS__); \ + goto send_error; \ + } while (0) + + meta = gst_buffer_get_vaapi_video_meta(buffer); + if (!meta) + SEND_ERROR("failed to get video meta"); + + surface = gst_vaapi_video_meta_get_surface(meta); + if (!surface) + SEND_ERROR("failed to get decoded surface from video meta"); + + if (!gst_vaapi_window_put_surface(app->window, surface, NULL, NULL, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + SEND_ERROR("failed to render surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); + + gst_buffer_replace(&app->last_buffer, buffer); + gst_buffer_unref(buffer); + return TRUE; + +#undef SEND_ERROR + +send_error: + app_send_error(app, error); + return FALSE; +} + +static gpointer +renderer_thread(gpointer data) +{ + App * const app = data; + GstBuffer *buffer; + + g_print("Render thread started\n"); + + while (!app->render_thread_cancel) { + buffer = g_async_queue_timeout_pop(app->decoder_queue, 1000000); + if (buffer && !renderer_process(app, buffer)) + break; + } + return NULL; +} + +static gboolean +flush_decoder_queue(App *app) +{ + GstBuffer *buffer; + + /* Flush pending surfaces */ + do { + buffer = g_async_queue_try_pop(app->decoder_queue); + if (!buffer) + return TRUE; + } while (renderer_process(app, buffer)); + return FALSE; +} + +static gboolean +start_renderer(App *app) +{ + app->render_thread = g_thread_create(renderer_thread, app, TRUE, NULL); + if (!app->render_thread) + return FALSE; + return TRUE; +} + +static gboolean +stop_renderer(App *app) +{ + app->render_thread_cancel = TRUE; + g_thread_join(app->render_thread); + + g_print("Render thread stopped\n"); + + flush_decoder_queue(app); + gst_buffer_replace(&app->last_buffer, NULL); + return TRUE; +} + +static void +app_free(App *app) +{ + if (!app) + return; + + if (app->file) { + g_mapped_file_unref(app->file); + app->file = NULL; + } + g_free(app->file_name); + + g_clear_object(&app->decoder); + g_clear_object(&app->window); + g_clear_object(&app->display); + + if (app->decoder_queue) { + g_async_queue_unref(app->decoder_queue); + app->decoder_queue = NULL; + } + g_cond_clear(&app->decoder_ready); + + g_cond_clear(&app->event_cond); + g_mutex_clear(&app->mutex); + g_slice_free(App, app); +} + +static App * +app_new(void) +{ + App *app; + + app = g_slice_new0(App); + if (!app) + return NULL; + + g_mutex_init(&app->mutex); + g_cond_init(&app->event_cond); + g_cond_init(&app->decoder_ready); + + app->decoder_queue = g_async_queue_new_full( + (GDestroyNotify)gst_buffer_unref); + if (!app->decoder_queue) + goto error; + return app; + +error: + app_free(app); + return NULL; +} + +static gboolean +app_check_events(App *app) +{ + GError *error = NULL; + gboolean stop = FALSE; + + do { + g_mutex_lock(&app->mutex); + while (app->event == APP_RUNNING) + g_cond_wait(&app->event_cond, &app->mutex); + + switch (app->event) { + case APP_GOT_ERROR: + error = app->error; + app->error = NULL; + /* fall-through */ + case APP_GOT_EOS: + stop = TRUE; + break; + default: + break; + } + g_mutex_unlock(&app->mutex); + } while (!stop); + + if (!error) + return TRUE; + + g_message("%s error: %s", get_error_string(error->code), error->message); + g_error_free(error); + return FALSE; +} + +static gboolean +app_run(App *app, int argc, char *argv[]) +{ + if (!video_output_init(&argc, argv, g_options)) { + g_message("failed to initialize video output subsystem"); + return FALSE; + } + + if (argc < 2) { + g_message("no bitstream file specified"); + return FALSE; + } + app->file_name = g_strdup(argv[1]); + + if (!g_file_test(app->file_name, G_FILE_TEST_IS_REGULAR)) { + g_message("failed to find file '%s'", app->file_name); + return FALSE; + } + + app->codec = identify_codec(app->file_name); + if (!app->codec) { + app->codec = identify_codec_from_string(g_codec_str); + if (!app->codec) { + g_message("failed to identify codec for '%s'", app->file_name); + return FALSE; + } + } + + g_print("Simple decoder (%s bitstream)\n", string_from_codec(app->codec)); + + app->display = video_output_create_display(NULL); + if (!app->display) { + g_message("failed to create VA display"); + return FALSE; + } + + app->window = video_output_create_window(app->display, 640, 480); + if (!app->window) { + g_message("failed to create window"); + return FALSE; + } + + gst_vaapi_window_show(app->window); + + if (!start_decoder(app)) { + g_message("failed to start decoder thread"); + return FALSE; + } + + if (!start_renderer(app)) { + g_message("failed to start renderer thread"); + return FALSE; + } + + app_check_events(app); + + stop_renderer(app); + stop_decoder(app); + video_output_exit(); + return TRUE; +} + +int +main(int argc, char *argv[]) +{ + App *app; + gint ret; + + app = app_new(); + if (!app) + g_error("failed to create application context"); + + ret = !app_run(app, argc, argv); + + app_free(app); + g_free(g_codec_str); + return ret; +} From 7b4dadc8ae0ee9a8b0ec531264a4348ee646c6b4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 15 Jan 2013 18:49:28 +0100 Subject: [PATCH 1032/3781] tests: simple-decoder: set window size to the surface dimensions. Set the window size to the decoded surface dimensions, if the user has not requested the application to run in full-screen mode. Besides, no effort is made to preserve aspect ratio or to center the video within the mapped window. --- tests/simple-decoder.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index 76d4c3959c..d01ae42f67 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -74,8 +74,11 @@ typedef struct { GCond decoder_ready; GAsyncQueue *decoder_queue; GstVaapiCodec codec; - GstVideoCodecState codec_state; + guint surface_width; + guint surface_height; GstVaapiWindow *window; + guint window_width; + guint window_height; GThread *render_thread; volatile gboolean render_thread_cancel; GstBuffer *last_buffer; @@ -324,6 +327,25 @@ stop_decoder(App *app) return TRUE; } +static void +ensure_window_size(App *app, GstVaapiSurface *surface) +{ + guint width, height; + + if (gst_vaapi_window_get_fullscreen(app->window)) + return; + + gst_vaapi_surface_get_size(surface, &width, &height); + if (app->surface_width == width && app->surface_height == height) + return; + app->surface_width = width; + app->surface_height = height; + + gst_vaapi_window_set_size(app->window, width, height); + gst_vaapi_window_get_size(app->window, + &app->window_width, &app->window_height); +} + static gboolean renderer_process(App *app, GstBuffer *buffer) { @@ -345,6 +367,8 @@ renderer_process(App *app, GstBuffer *buffer) if (!surface) SEND_ERROR("failed to get decoded surface from video meta"); + ensure_window_size(app, surface); + if (!gst_vaapi_window_put_surface(app->window, surface, NULL, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) SEND_ERROR("failed to render surface %" GST_VAAPI_ID_FORMAT, @@ -453,6 +477,9 @@ app_new(void) g_cond_init(&app->event_cond); g_cond_init(&app->decoder_ready); + app->window_width = 640; + app->window_height = 480; + app->decoder_queue = g_async_queue_new_full( (GDestroyNotify)gst_buffer_unref); if (!app->decoder_queue) @@ -533,7 +560,8 @@ app_run(App *app, int argc, char *argv[]) return FALSE; } - app->window = video_output_create_window(app->display, 640, 480); + app->window = video_output_create_window(app->display, + app->window_width, app->window_height); if (!app->window) { g_message("failed to create window"); return FALSE; From 14242cda5d39f0f0f6a4685691a0ba99cccdbccb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 16 Jan 2013 13:29:06 +0100 Subject: [PATCH 1033/3781] tests: simple-decoder: honour framerate from the bitstream. Try to honour the framerate from the bitstream, or cap the playback to 60 fps by default. --- tests/Makefile.am | 4 +-- tests/simple-decoder.c | 55 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index dbba30effe..b95cb0a4cb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -105,8 +105,8 @@ test_textures_LDADD = libutils.la $(TEST_LIBS) simple_decoder_source_c = simple-decoder.c simple_decoder_source_h = simple_decoder_SOURCES = $(simple_decoder_source_c) -simple_decoder_CFLAGS = $(TEST_CFLAGS) -simple_decoder_LDADD = libutils.la $(TEST_LIBS) +simple_decoder_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) +simple_decoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) EXTRA_DIST = \ test-subpicture-data.h \ diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index d01ae42f67..b041dcf052 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -74,6 +74,9 @@ typedef struct { GCond decoder_ready; GAsyncQueue *decoder_queue; GstVaapiCodec codec; + guint fps_n; + guint fps_d; + guint32 frame_duration; guint surface_width; guint surface_height; GstVaapiWindow *window; @@ -81,6 +84,7 @@ typedef struct { guint window_height; GThread *render_thread; volatile gboolean render_thread_cancel; + GCond render_ready; GstBuffer *last_buffer; GError *error; AppEvent event; @@ -193,6 +197,7 @@ decoder_thread(gpointer data) GstVaapiSurfaceProxy *proxy; GstVaapiVideoMeta *meta; GstBuffer *buffer; + GstClockTime pts; gboolean got_surface; gint64 end_time; guint ofs; @@ -205,6 +210,7 @@ decoder_thread(gpointer data) goto send_error; \ } while (0) + pts = g_get_monotonic_time(); ofs = 0; while (!app->decoder_thread_cancel) { if (G_UNLIKELY(ofs == app->file_size)) @@ -235,6 +241,9 @@ decoder_thread(gpointer data) buffer = gst_buffer_new(); if (!buffer) SEND_ERROR("failed to allocate output buffer"); + GST_BUFFER_TIMESTAMP(buffer) = pts; + GST_BUFFER_DURATION(buffer) = app->frame_duration; + pts += app->frame_duration; gst_buffer_set_vaapi_video_meta(buffer, meta); gst_vaapi_video_meta_unref(meta); g_async_queue_push(app->decoder_queue, buffer); @@ -272,6 +281,35 @@ send_error: return NULL; } +static void +app_set_framerate(App *app, guint fps_n, guint fps_d) +{ + if (!fps_n || !fps_d) + return; + + g_mutex_lock(&app->mutex); + if (fps_n != app->fps_n || fps_d != app->fps_d) { + app->fps_n = fps_n; + app->fps_d = fps_d; + app->frame_duration = gst_util_uint64_scale( + GST_TIME_AS_USECONDS(GST_SECOND), fps_d, fps_n); + } + g_mutex_unlock(&app->mutex); +} + +static void +handle_decoder_caps(GObject *obj, GParamSpec *pspec, void *user_data) +{ + App * const app = user_data; + GstVideoCodecState *codec_state; + + g_assert(app->decoder == GST_VAAPI_DECODER(obj)); + + codec_state = gst_vaapi_decoder_get_codec_state(app->decoder); + app_set_framerate(app, codec_state->info.fps_n, codec_state->info.fps_d); + gst_video_codec_state_unref(codec_state); +} + static gboolean start_decoder(App *app) { @@ -312,6 +350,9 @@ start_decoder(App *app) if (!app->decoder) return FALSE; + g_signal_connect(G_OBJECT(app->decoder), "notify::caps", + G_CALLBACK(handle_decoder_caps), app); + app->decoder_thread = g_thread_create(decoder_thread, app, TRUE, NULL); if (!app->decoder_thread) return FALSE; @@ -346,6 +387,15 @@ ensure_window_size(App *app, GstVaapiSurface *surface) &app->window_width, &app->window_height); } +static inline void +renderer_wait_until(App *app, GstClockTime pts) +{ + g_mutex_lock(&app->mutex); + do { + } while (g_cond_wait_until(&app->render_ready, &app->mutex, pts)); + g_mutex_unlock(&app->mutex); +} + static gboolean renderer_process(App *app, GstBuffer *buffer) { @@ -369,6 +419,8 @@ renderer_process(App *app, GstBuffer *buffer) ensure_window_size(app, surface); + renderer_wait_until(app, GST_BUFFER_TIMESTAMP(buffer)); + if (!gst_vaapi_window_put_surface(app->window, surface, NULL, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) SEND_ERROR("failed to render surface %" GST_VAAPI_ID_FORMAT, @@ -459,6 +511,7 @@ app_free(App *app) } g_cond_clear(&app->decoder_ready); + g_cond_clear(&app->render_ready); g_cond_clear(&app->event_cond); g_mutex_clear(&app->mutex); g_slice_free(App, app); @@ -476,7 +529,9 @@ app_new(void) g_mutex_init(&app->mutex); g_cond_init(&app->event_cond); g_cond_init(&app->decoder_ready); + g_cond_init(&app->render_ready); + app_set_framerate(app, 60, 1); app->window_width = 640; app->window_height = 480; From 0a7a9e83048647751ba11654c42cd16d1b479a30 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 16 Jan 2013 13:53:43 +0100 Subject: [PATCH 1034/3781] tests: simple-decoder: add benchmark mode. Add --benchmark option to enable benchmark mode where rendering is not synchronized with presentation timestamps of the decoded surfaces. --- tests/simple-decoder.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index b041dcf052..89ac4e602c 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -39,12 +39,17 @@ #include "output.h" static gchar *g_codec_str; +static gboolean g_benchmark; static GOptionEntry g_options[] = { { "codec", 'c', 0, G_OPTION_ARG_STRING, &g_codec_str, "suggested codec", NULL }, + { "benchmark", 0, + 0, + G_OPTION_ARG_NONE, &g_benchmark, + "benchmark mode", NULL }, { NULL, } }; @@ -89,6 +94,8 @@ typedef struct { GError *error; AppEvent event; GCond event_cond; + GTimer *timer; + guint32 num_frames; } App; #define APP_ERROR app_error_quark() @@ -353,6 +360,8 @@ start_decoder(App *app) g_signal_connect(G_OBJECT(app->decoder), "notify::caps", G_CALLBACK(handle_decoder_caps), app); + g_timer_start(app->timer); + app->decoder_thread = g_thread_create(decoder_thread, app, TRUE, NULL); if (!app->decoder_thread) return FALSE; @@ -362,6 +371,8 @@ start_decoder(App *app) static gboolean stop_decoder(App *app) { + g_timer_stop(app->timer); + app->decoder_thread_cancel = TRUE; g_thread_join(app->decoder_thread); g_print("Decoder thread stopped\n"); @@ -419,13 +430,19 @@ renderer_process(App *app, GstBuffer *buffer) ensure_window_size(app, surface); - renderer_wait_until(app, GST_BUFFER_TIMESTAMP(buffer)); + if (!gst_vaapi_surface_sync(surface)) + SEND_ERROR("failed to sync decoded surface"); + + if (G_LIKELY(!g_benchmark)) + renderer_wait_until(app, GST_BUFFER_TIMESTAMP(buffer)); if (!gst_vaapi_window_put_surface(app->window, surface, NULL, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) SEND_ERROR("failed to render surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); + app->num_frames++; + gst_buffer_replace(&app->last_buffer, buffer); gst_buffer_unref(buffer); return TRUE; @@ -511,6 +528,11 @@ app_free(App *app) } g_cond_clear(&app->decoder_ready); + if (app->timer) { + g_timer_destroy(app->timer); + app->timer = NULL; + } + g_cond_clear(&app->render_ready); g_cond_clear(&app->event_cond); g_mutex_clear(&app->mutex); @@ -539,6 +561,10 @@ app_new(void) (GDestroyNotify)gst_buffer_unref); if (!app->decoder_queue) goto error; + + app->timer = g_timer_new(); + if (!app->timer) + goto error; return app; error: @@ -638,6 +664,15 @@ app_run(App *app, int argc, char *argv[]) stop_renderer(app); stop_decoder(app); + + g_print("Decoded %u frames", app->num_frames); + if (g_benchmark) { + const gdouble elapsed = g_timer_elapsed(app->timer, NULL); + g_print(" in %.2f sec (%.1f fps)\n", + elapsed, (gdouble)app->num_frames / elapsed); + } + g_print("\n"); + video_output_exit(); return TRUE; } From caee174e2fa03b464a26c83dd1fbdfbb0a659b21 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Jan 2013 10:25:14 +0100 Subject: [PATCH 1035/3781] tests: simple-decoder: drop use of GstVaapiVideoMeta. Don't use GstVaapiVideoMeta since that object is not guaranteed to live in libgstvaapi forever. Rather, that'd move to plugin elements at some point. --- tests/simple-decoder.c | 87 +++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index 89ac4e602c..373fd8e3c3 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include "codec.h" #include "output.h" @@ -65,6 +64,12 @@ typedef enum { APP_ERROR_RENDERER, } AppError; +typedef struct { + GstVaapiSurfaceProxy *proxy; + GstClockTime pts; + GstClockTime duration; +} RenderFrame; + typedef struct { GMutex mutex; GMappedFile *file; @@ -90,7 +95,7 @@ typedef struct { GThread *render_thread; volatile gboolean render_thread_cancel; GCond render_ready; - GstBuffer *last_buffer; + RenderFrame *last_frame; GError *error; AppEvent event; GCond event_cond; @@ -98,6 +103,29 @@ typedef struct { guint32 num_frames; } App; +static inline RenderFrame * +render_frame_new(void) +{ + return g_slice_new(RenderFrame); +} + +static void +render_frame_free(RenderFrame *rfp) +{ + if (G_UNLIKELY(!rfp)) + return; + gst_vaapi_surface_proxy_replace(&rfp->proxy, NULL); + g_slice_free(RenderFrame, rfp); +} + +static inline void +render_frame_replace(RenderFrame **rfp_ptr, RenderFrame *new_rfp) +{ + if (*rfp_ptr) + render_frame_free(*rfp_ptr); + *rfp_ptr = new_rfp; +} + #define APP_ERROR app_error_quark() static GQuark app_error_quark(void) @@ -202,7 +230,7 @@ decoder_thread(gpointer data) GError *error = NULL; GstVaapiDecoderStatus status; GstVaapiSurfaceProxy *proxy; - GstVaapiVideoMeta *meta; + RenderFrame *rfp; GstBuffer *buffer; GstClockTime pts; gboolean got_surface; @@ -241,19 +269,14 @@ decoder_thread(gpointer data) case GST_VAAPI_DECODER_STATUS_SUCCESS: gst_vaapi_surface_proxy_set_user_data(proxy, app, (GDestroyNotify)decoder_release); - meta = gst_vaapi_video_meta_new_with_surface_proxy(proxy); - gst_vaapi_surface_proxy_unref(proxy); - if (!meta) - SEND_ERROR("failed to allocate video meta"); - buffer = gst_buffer_new(); - if (!buffer) - SEND_ERROR("failed to allocate output buffer"); - GST_BUFFER_TIMESTAMP(buffer) = pts; - GST_BUFFER_DURATION(buffer) = app->frame_duration; + rfp = render_frame_new(); + if (!rfp) + SEND_ERROR("failed to allocate render frame"); + rfp->proxy = proxy; + rfp->pts = pts; + rfp->duration = app->frame_duration; pts += app->frame_duration; - gst_buffer_set_vaapi_video_meta(buffer, meta); - gst_vaapi_video_meta_unref(meta); - g_async_queue_push(app->decoder_queue, buffer); + g_async_queue_push(app->decoder_queue, rfp); break; case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: /* nothing to do, just continue to the next iteration */ @@ -408,10 +431,9 @@ renderer_wait_until(App *app, GstClockTime pts) } static gboolean -renderer_process(App *app, GstBuffer *buffer) +renderer_process(App *app, RenderFrame *rfp) { GError *error = NULL; - GstVaapiVideoMeta *meta; GstVaapiSurface *surface; #define SEND_ERROR(...) \ @@ -420,13 +442,9 @@ renderer_process(App *app, GstBuffer *buffer) goto send_error; \ } while (0) - meta = gst_buffer_get_vaapi_video_meta(buffer); - if (!meta) - SEND_ERROR("failed to get video meta"); - - surface = gst_vaapi_video_meta_get_surface(meta); + surface = gst_vaapi_surface_proxy_get_surface(rfp->proxy); if (!surface) - SEND_ERROR("failed to get decoded surface from video meta"); + SEND_ERROR("failed to get decoded surface from render frame"); ensure_window_size(app, surface); @@ -434,7 +452,7 @@ renderer_process(App *app, GstBuffer *buffer) SEND_ERROR("failed to sync decoded surface"); if (G_LIKELY(!g_benchmark)) - renderer_wait_until(app, GST_BUFFER_TIMESTAMP(buffer)); + renderer_wait_until(app, rfp->pts); if (!gst_vaapi_window_put_surface(app->window, surface, NULL, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) @@ -443,8 +461,7 @@ renderer_process(App *app, GstBuffer *buffer) app->num_frames++; - gst_buffer_replace(&app->last_buffer, buffer); - gst_buffer_unref(buffer); + render_frame_replace(&app->last_frame, rfp); return TRUE; #undef SEND_ERROR @@ -458,13 +475,13 @@ static gpointer renderer_thread(gpointer data) { App * const app = data; - GstBuffer *buffer; + RenderFrame *rfp; g_print("Render thread started\n"); while (!app->render_thread_cancel) { - buffer = g_async_queue_timeout_pop(app->decoder_queue, 1000000); - if (buffer && !renderer_process(app, buffer)) + rfp = g_async_queue_timeout_pop(app->decoder_queue, 1000000); + if (rfp && !renderer_process(app, rfp)) break; } return NULL; @@ -473,14 +490,14 @@ renderer_thread(gpointer data) static gboolean flush_decoder_queue(App *app) { - GstBuffer *buffer; + RenderFrame *rfp; /* Flush pending surfaces */ do { - buffer = g_async_queue_try_pop(app->decoder_queue); - if (!buffer) + rfp = g_async_queue_try_pop(app->decoder_queue); + if (!rfp) return TRUE; - } while (renderer_process(app, buffer)); + } while (renderer_process(app, rfp)); return FALSE; } @@ -502,7 +519,7 @@ stop_renderer(App *app) g_print("Render thread stopped\n"); flush_decoder_queue(app); - gst_buffer_replace(&app->last_buffer, NULL); + render_frame_replace(&app->last_frame, NULL); return TRUE; } @@ -558,7 +575,7 @@ app_new(void) app->window_height = 480; app->decoder_queue = g_async_queue_new_full( - (GDestroyNotify)gst_buffer_unref); + (GDestroyNotify)render_frame_free); if (!app->decoder_queue) goto error; From 48b67470e3ddad5c590e120cea5db7616bf97833 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Jan 2013 10:35:44 +0100 Subject: [PATCH 1036/3781] tests: simple-decoder: flush decoded frames at EOS. Flush the remaining decoded frames when an end-of-stream is reached. --- tests/simple-decoder.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index 373fd8e3c3..e6c47387ad 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -233,7 +233,7 @@ decoder_thread(gpointer data) RenderFrame *rfp; GstBuffer *buffer; GstClockTime pts; - gboolean got_surface; + gboolean got_surface, got_eos = FALSE; gint64 end_time; guint ofs; @@ -282,7 +282,11 @@ decoder_thread(gpointer data) /* nothing to do, just continue to the next iteration */ break; case GST_VAAPI_DECODER_STATUS_END_OF_STREAM: - goto send_eos; + gst_vaapi_decoder_flush(app->decoder); + if (got_eos) + goto send_eos; + got_eos = TRUE; + break; case GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE: end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND; g_mutex_lock(&app->mutex); From 732320d87830b05767088b768c8680202c01a8b8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Jan 2013 14:30:48 +0100 Subject: [PATCH 1037/3781] tests: simple-decoder: fix build with built-in videoutils. Fix build with built-in videoutils, i.e. when system GStreamer installation does not know about GstVideoDecoder API. --- tests/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index b95cb0a4cb..fe16b94d43 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -106,7 +106,8 @@ simple_decoder_source_c = simple-decoder.c simple_decoder_source_h = simple_decoder_SOURCES = $(simple_decoder_source_c) simple_decoder_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) -simple_decoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) +simple_decoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) \ + $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la EXTRA_DIST = \ test-subpicture-data.h \ From 655f400e1c055c07b12c39e8bf5785d996fbddc3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Jan 2013 14:17:34 +0100 Subject: [PATCH 1038/3781] display: dump gstreamer-vaapi version for debugging purposes. --- configure.ac | 4 +++ gst-libs/gst/vaapi/Makefile.am | 37 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.c | 17 ++++++++++++ gst-libs/gst/vaapi/gstvaapiversion.h.in | 33 ++++++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiversion.h.in diff --git a/configure.ac b/configure.ac index 2c2ff5bc91..102e642c4e 100644 --- a/configure.ac +++ b/configure.ac @@ -114,6 +114,10 @@ dnl Check for tools AC_PROG_CC AM_PROG_CC_C_O +AC_ARG_VAR([GIT], [Path to git program, if any]) +AC_PATH_PROG([GIT], [git]) +AM_CONDITIONAL([HAVE_GIT], [test -n "$GIT"]) + dnl Initialize libtool LT_PREREQ([2.2]) LT_INIT diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 205f902583..6ec6794eaf 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -117,6 +117,7 @@ libgstvaapi_source_priv_h = \ gstvaapiobject_priv.h \ gstvaapisurface_priv.h \ gstvaapiutils.h \ + gstvaapiversion.h \ gstvaapiworkarounds.h \ sysdeps.h \ $(NULL) @@ -369,5 +370,41 @@ libgstvaapi_wayland_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) +VERSION_FILE = .VERSION +OLD_VERSION_FILE = $(VERSION_FILE).old +NEW_VERSION_FILE = $(VERSION_FILE).new +PKG_VERSION_FILE = $(VERSION_FILE).pkg + +gstvaapiversion.h: gen-version + $(AM_V_GEN) \ + OV=`[ -f $(OLD_VERSION_FILE) ] && cat $(OLD_VERSION_FILE) || :`; \ + NV=`cat $(NEW_VERSION_FILE)`; \ + if [ "$$OV" != "$$NV" -o ! -f gstvaapiversion.h ]; then \ + cp -f $(NEW_VERSION_FILE) $(OLD_VERSION_FILE); \ + $(SED) -e "s|\@GST_VAAPI_VERSION_ID\@|$${NV}|" \ + $(srcdir)/gstvaapiversion.h.in > gstvaapiversion.h; \ + fi + +gen-version: + @echo $(VERSION) > $(NEW_VERSION_FILE) +if HAVE_GIT + @[ -d $(top_srcdir)/.git ] && \ + (cd $(top_srcdir) && $(GIT) describe --tags) > $(NEW_VERSION_FILE) || : +endif + @[ -f $(srcdir)/$(PKG_VERSION_FILE) ] && \ + cp -f $(srcdir)/$(PKG_VERSION_FILE) $(NEW_VERSION_FILE) || : + +$(PKG_VERSION_FILE): $(NEW_VERSION_FILE) + @cp -f $< $@ + +BUILT_SOURCES = gstvaapiversion.h +EXTRA_DIST = gstvaapiversion.h.in $(PKG_VERSION_FILE) + +CLEANFILES = \ + $(OLD_VERSION_FILE) \ + $(NEW_VERSION_FILE) \ + $(PKG_VERSION_FILE) \ + $(NULL) + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index f8acf62fb2..9598275297 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -32,6 +32,7 @@ #include "gstvaapidisplay.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiworkarounds.h" +#include "gstvaapiversion.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -95,6 +96,20 @@ get_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat *v); static gboolean set_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat v); +static void +dump_version(void) +{ + static gsize g_once = FALSE; + + if (!g_once_init_enter(&g_once)) + return; + + /* Dump gstreamer-vaapi version for debugging purposes */ + GST_INFO("gstreamer-vaapi version %s", GST_VAAPI_VERSION_ID); + + g_once_init_leave(&g_once, TRUE); +} + static inline GstVaapiDisplayCache * get_display_cache(void) { @@ -885,6 +900,8 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) GST_DEBUG_CATEGORY_INIT(gst_debug_vaapi, "vaapi", 0, "VA-API helper"); + dump_version(); + g_type_class_add_private(klass, sizeof(GstVaapiDisplayPrivate)); object_class->finalize = gst_vaapi_display_finalize; diff --git a/gst-libs/gst/vaapi/gstvaapiversion.h.in b/gst-libs/gst/vaapi/gstvaapiversion.h.in new file mode 100644 index 0000000000..e4896a4fe2 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiversion.h.in @@ -0,0 +1,33 @@ +/* + * gstvaapiversion.h - Versioning + * + * Copyright (C) 2013 Intel Corporation + * + * 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_VERSION_H +#define GST_VAAPI_VERSION_H + +/** + * GST_VAAPI_VERSION_ID: + * + * The full version identifier of gstreamer-vaapi, in string form + * (suitable for string concatenation). + */ +#define GST_VAAPI_VERSION_ID "@GST_VAAPI_VERSION_ID@" + +#endif /* GST_VAAPI_VERSION_H */ From cd52fa315ab21865fa84d8f3a7c03983b08adfea Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Jan 2013 14:46:23 +0100 Subject: [PATCH 1039/3781] display: move "vaapi" debug init to libgstvaapi_init_once(). --- gst-libs/gst/vaapi/gstvaapidisplay.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 9598275297..a3cd13ccae 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -97,13 +97,15 @@ static gboolean set_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat v); static void -dump_version(void) +libgstvaapi_init_once(void) { static gsize g_once = FALSE; if (!g_once_init_enter(&g_once)) return; + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapi, "vaapi", 0, "VA-API helper"); + /* Dump gstreamer-vaapi version for debugging purposes */ GST_INFO("gstreamer-vaapi version %s", GST_VAAPI_VERSION_ID); @@ -898,9 +900,7 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapi, "vaapi", 0, "VA-API helper"); - - dump_version(); + libgstvaapi_init_once(); g_type_class_add_private(klass, sizeof(GstVaapiDisplayPrivate)); From a811a5de3d1349f91a9f2d95ef279664963480a0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Jan 2013 16:56:15 +0100 Subject: [PATCH 1040/3781] decoder: optimize and clean decode_step() up. Avoid usage of goto. Simplify decode_step() process to first accumulate all pending buffers into the GstAdapter, and then parse and decode units from that input adapter. Stop the process once a frame is fully decoded or an error occurred. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 95 +++++++++++++++------------- 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 7437582631..6209c40584 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -275,67 +275,72 @@ decode_step(GstVaapiDecoder *decoder) GstVaapiDecoderStatus status; GstBuffer *buffer; gboolean got_frame; - guint got_unit_size; - - if (G_UNLIKELY(ps->at_eos)) - return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + guint got_unit_size, input_size; status = gst_vaapi_decoder_check_status(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - if (ps->current_frame) - goto parse; - - do { + /* Fill adapter with all buffers we have in the queue */ + for (;;) { buffer = pop_buffer(decoder); if (!buffer) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + break; ps->at_eos = GST_BUFFER_IS_EOS(buffer); if (!ps->at_eos) gst_adapter_push(ps->input_adapter, buffer); + } - do { - if (!ps->current_frame) { - ps->current_frame = g_slice_new0(GstVideoCodecFrame); - if (!ps->current_frame) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - ps->current_frame->ref_count = 1; + /* Parse and decode all decode units */ + input_size = gst_adapter_available(ps->input_adapter); + if (input_size == 0) { + if (ps->at_eos) + return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } + + do { + if (!ps->current_frame) { + ps->current_frame = g_slice_new0(GstVideoCodecFrame); + if (!ps->current_frame) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + ps->current_frame->ref_count = 1; + } + + status = do_parse(decoder, ps->current_frame, ps->input_adapter, + ps->at_eos, &got_unit_size, &got_frame); + GST_DEBUG("parse frame (status = %d)", status); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA && ps->at_eos) + status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + break; + } + + if (got_unit_size > 0) { + buffer = gst_adapter_take_buffer(ps->input_adapter, got_unit_size); + input_size -= got_unit_size; + + if (gst_adapter_available(ps->output_adapter) == 0) { + ps->current_frame->pts = + gst_adapter_prev_timestamp(ps->input_adapter, NULL); } + gst_adapter_push(ps->output_adapter, buffer); + } - parse: - status = do_parse(decoder, ps->current_frame, - ps->input_adapter, ps->at_eos, &got_unit_size, &got_frame); - GST_DEBUG("parse frame (status = %d)", status); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - break; + if (got_frame) { + ps->current_frame->input_buffer = gst_adapter_take_buffer( + ps->output_adapter, + gst_adapter_available(ps->output_adapter)); - if (got_unit_size > 0) { - buffer = gst_adapter_take_buffer(ps->input_adapter, - got_unit_size); - if (gst_adapter_available(ps->output_adapter) == 0) { - ps->current_frame->pts = - gst_adapter_prev_timestamp(ps->input_adapter, NULL); - } - gst_adapter_push(ps->output_adapter, buffer); - } + status = do_decode(decoder, ps->current_frame); + GST_DEBUG("decode frame (status = %d)", status); - if (got_frame) { - ps->current_frame->input_buffer = gst_adapter_take_buffer( - ps->output_adapter, - gst_adapter_available(ps->output_adapter)); - - status = do_decode(decoder, ps->current_frame); - GST_DEBUG("decode frame (status = %d)", status); - - gst_video_codec_frame_unref(ps->current_frame); - ps->current_frame = NULL; - break; - } - } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && - gst_adapter_available(ps->input_adapter) > 0); - } while (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA); + gst_video_codec_frame_unref(ps->current_frame); + ps->current_frame = NULL; + break; + } + } while (input_size > 0); return status; } From b24752da4ff7dec70390912de4bc8568680cb8f5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Jan 2013 17:00:18 +0100 Subject: [PATCH 1041/3781] decoder: simplify gst_vaapi_decoder_get_surface(). Avoid extraenous branches, i.e. immediately return with success once we have a decoded frame available. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 6209c40584..360374690f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -659,21 +659,15 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, do { frame = pop_frame(decoder); - if (frame) - break; + if (frame) { + *out_proxy_ptr = gst_vaapi_surface_proxy_ref(frame->user_data); + gst_video_codec_frame_unref(frame); + return GST_VAAPI_DECODER_STATUS_SUCCESS; + } status = decode_step(decoder); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); - if (frame) { - *out_proxy_ptr = gst_vaapi_surface_proxy_ref(frame->user_data); - gst_video_codec_frame_unref(frame); - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - } - else { - *out_proxy_ptr = NULL; - if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) - status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - } + *out_proxy_ptr = NULL; return status; } From 142e13f637f35adaaa203d108e5c5a351d72d52a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 15 Jan 2013 17:10:56 +0100 Subject: [PATCH 1042/3781] vc1: fix decode_sequence_end() to return success, not EOS. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 2cc33ccc17..b7717dd01c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -351,7 +351,7 @@ decode_sequence_end(GstVaapiDecoderVC1 *decoder) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; } - return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus From 472f3473e0822166df9131f8c6af67cacc9316bf Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 2 Aug 2012 17:15:26 +0300 Subject: [PATCH 1043/3781] vc1: port to common GstVaapiDpb interface. Use GstVaapiDpb interface instead of maintaining our own prev and next picture pointers. While doing so, try to derive a sensible POC value. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 104 +++++++++++------------ 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index b7717dd01c..81ab154e8c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -29,6 +29,7 @@ #include #include "gstvaapidecoder_vc1.h" #include "gstvaapidecoder_objects.h" +#include "gstvaapidecoder_dpb.h" #include "gstvaapidecoder_unit.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" @@ -55,8 +56,9 @@ struct _GstVaapiDecoderVC1Private { GstVC1FrameHdr frame_hdr; GstVC1BitPlanes *bitplanes; GstVaapiPicture *current_picture; - GstVaapiPicture *next_picture; - GstVaapiPicture *prev_picture; + GstVaapiPicture *last_non_b_picture; + GstVaapiDpb *dpb; + gint32 next_poc; guint8 *rbdu_buffer; guint rbdu_buffer_size; guint is_constructed : 1; @@ -97,9 +99,9 @@ gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder) { GstVaapiDecoderVC1Private * const priv = decoder->priv; + gst_vaapi_picture_replace(&priv->last_non_b_picture, NULL); gst_vaapi_picture_replace(&priv->current_picture, NULL); - gst_vaapi_picture_replace(&priv->next_picture, NULL); - gst_vaapi_picture_replace(&priv->prev_picture, NULL); + gst_vaapi_dpb_replace(&priv->dpb, NULL); if (priv->bitplanes) { gst_vc1_bitplanes_free(priv->bitplanes); @@ -114,6 +116,10 @@ gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder) gst_vaapi_decoder_vc1_close(decoder); + priv->dpb = gst_vaapi_dpb_new(2); + if (!priv->dpb) + return FALSE; + priv->bitplanes = gst_vc1_bitplanes_new(); if (!priv->bitplanes) return FALSE; @@ -194,31 +200,28 @@ ensure_context(GstVaapiDecoderVC1 *decoder) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static inline GstVaapiDecoderStatus -render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) -{ - if (!gst_vaapi_picture_output(picture)) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderVC1 *decoder) { GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVaapiPicture * const picture = priv->current_picture; - GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; - if (picture) { - if (!gst_vaapi_picture_decode(picture)) - status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { - if (priv->prev_picture && priv->next_picture) - status = render_picture(decoder, picture); - } + if (!picture) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (!gst_vaapi_picture_decode(picture)) + goto error; + if (GST_VAAPI_PICTURE_IS_COMPLETE(picture)) { + if (!gst_vaapi_dpb_add(priv->dpb, picture)) + goto error; gst_vaapi_picture_replace(&priv->current_picture, NULL); } - return status; + return GST_VAAPI_DECODER_STATUS_SUCCESS; + +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 @@ -337,20 +340,11 @@ decode_sequence_end(GstVaapiDecoderVC1 *decoder) GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVaapiDecoderStatus status; - if (priv->current_picture) { - status = decode_current_picture(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - status = render_picture(decoder, priv->current_picture); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } + status = decode_current_picture(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; - if (priv->next_picture) { - status = render_picture(decoder, priv->next_picture); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } + gst_vaapi_dpb_flush(priv->dpb); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -733,6 +727,7 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) VAPictureParameterBufferVC1 * const pic_param = picture->param; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + GstVaapiPicture *prev_picture, *next_picture; /* Fill in VAPictureParameterBufferVC1 (common fields) */ pic_param->forward_reference_picture = VA_INVALID_ID; @@ -777,14 +772,17 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) return FALSE; } + gst_vaapi_dpb_get_neighbours(priv->dpb, picture, + &prev_picture, &next_picture); + switch (picture->type) { case GST_VAAPI_PICTURE_TYPE_B: - if (priv->next_picture) - pic_param->backward_reference_picture = priv->next_picture->surface_id; + if (next_picture) + pic_param->backward_reference_picture = next_picture->surface_id; // fall-through case GST_VAAPI_PICTURE_TYPE_P: - if (priv->prev_picture) - pic_param->forward_reference_picture = priv->prev_picture->surface_id; + if (prev_picture) + pic_param->forward_reference_picture = prev_picture->surface_id; break; default: break; @@ -859,12 +857,13 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) return status; } - priv->current_picture = GST_VAAPI_PICTURE_NEW(VC1, decoder); - if (!priv->current_picture) { + picture = GST_VAAPI_PICTURE_NEW(VC1, decoder); + if (!picture) { GST_DEBUG("failed to allocate picture"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } - picture = priv->current_picture; + gst_vaapi_picture_replace(&priv->current_picture, picture); + gst_vaapi_picture_unref(picture); if (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, seq_hdr)) { GST_DEBUG("failed to allocate bitplanes"); @@ -906,15 +905,19 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) } /* Update presentation time */ - picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; - - /* Update reference pictures */ if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { - if (priv->next_picture) - status = render_picture(decoder, priv->next_picture); - gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture); - gst_vaapi_picture_replace(&priv->next_picture, picture); + picture->poc = priv->last_non_b_picture ? + (priv->last_non_b_picture->poc + 1) : priv->next_poc; + priv->next_poc = picture->poc + 1; + gst_vaapi_picture_replace(&priv->last_non_b_picture, picture); } + else if (!priv->last_non_b_picture) + picture->poc = priv->next_poc++; + else { /* B or BI */ + picture->poc = priv->last_non_b_picture->poc++; + priv->next_poc = priv->last_non_b_picture->poc + 1; + } + picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; if (!fill_picture(decoder, picture)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; @@ -936,8 +939,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) slice_param->macroblock_offset = 8 * (ebdu->offset - ebdu->sc_offset) + frame_hdr->header_size; slice_param->slice_vertical_position = 0; - /* Decode picture right away, we got the full frame */ - return decode_current_picture(decoder); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static gboolean @@ -1304,8 +1306,6 @@ gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder) priv->height = 0; priv->profile = (GstVaapiProfile)0; priv->current_picture = NULL; - priv->next_picture = NULL; - priv->prev_picture = NULL; priv->rbdu_buffer = NULL; priv->rbdu_buffer_size = 0; priv->is_constructed = FALSE; From 823f16d7ce236587d2ed742388a5e850edb0048d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 22 Jan 2013 09:30:04 +0100 Subject: [PATCH 1044/3781] vc1: fix next POC for new sequence layers. Fix next POC when a new sequence layer is reached. At this point, we need to reset any previous reference picture, i.e. non B-frame. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 81ab154e8c..7baf02eeb1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -248,6 +248,13 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) priv->has_entrypoint = FALSE; + /* Reset POC */ + if (priv->last_non_b_picture) { + if (priv->last_non_b_picture->poc == priv->next_poc) + priv->next_poc++; + gst_vaapi_picture_replace(&priv->last_non_b_picture, NULL); + } + /* Validate profile */ switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: From 1513f52fc1b3458b27f0e30a46640f49ab5b325c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 22 Jan 2013 13:44:32 +0100 Subject: [PATCH 1045/3781] vc1: implement {start,end}_frame() hooks. Implement GstVaapiDecoder.start_frame() and end_frame() semantics so that to create new VA context earlier and submit VA pictures to the HW for decoding as soon as possible. i.e. don't wait for the next frame to start decoding the previous one. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 71 ++++++++++++++---------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 7baf02eeb1..3fe8a9799c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -844,45 +844,18 @@ static GstVaapiDecoderStatus decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { GstVaapiDecoderVC1Private * const priv = decoder->priv; - GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; GstVC1ParserResult result; - GstVaapiPicture *picture; + GstVaapiPicture * const picture = priv->current_picture; GstVaapiSlice *slice; - GstVaapiDecoderStatus status; VASliceParameterBufferVC1 *slice_param; - status = ensure_context(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_DEBUG("failed to reset context"); - return status; - } - - if (priv->current_picture) { - status = decode_current_picture(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - - picture = GST_VAAPI_PICTURE_NEW(VC1, decoder); - if (!picture) { - GST_DEBUG("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 (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, seq_hdr)) { - GST_DEBUG("failed to allocate bitplanes"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - memset(frame_hdr, 0, sizeof(*frame_hdr)); result = gst_vc1_parse_frame_header( rbdu->data + rbdu->offset, rbdu->size, frame_hdr, - seq_hdr, + &priv->seq_hdr, priv->bitplanes ); if (result != GST_VC1_PARSER_OK) { @@ -1263,6 +1236,44 @@ gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base_decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static GstVaapiDecoderStatus +gst_vaapi_decoder_vc1_start_frame(GstVaapiDecoder *base_decoder, + GstVaapiDecoderUnit *unit) +{ + GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderStatus status; + GstVaapiPicture *picture; + + status = ensure_context(decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_DEBUG("failed to reset context"); + return status; + } + + picture = GST_VAAPI_PICTURE_NEW(VC1, decoder); + if (!picture) { + GST_DEBUG("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 (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, &priv->seq_hdr)) { + GST_DEBUG("failed to allocate bitplanes"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_vc1_end_frame(GstVaapiDecoder *base_decoder) +{ + GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); + + return decode_current_picture(decoder); +} + static void gst_vaapi_decoder_vc1_finalize(GObject *object) { @@ -1300,6 +1311,8 @@ gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass) decoder_class->parse = gst_vaapi_decoder_vc1_parse; decoder_class->decode = gst_vaapi_decoder_vc1_decode; + decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame; + decoder_class->end_frame = gst_vaapi_decoder_vc1_end_frame; } static void From ec3c4576c025b6a5d3aacd69ac0dd4e97db0b7fd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 22 Jan 2013 16:03:18 +0100 Subject: [PATCH 1046/3781] vc1: implement flush() hook. Make it a simple DPB flush. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 3fe8a9799c..b746bea1c9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1274,6 +1274,16 @@ gst_vaapi_decoder_vc1_end_frame(GstVaapiDecoder *base_decoder) return decode_current_picture(decoder); } +static GstVaapiDecoderStatus +gst_vaapi_decoder_vc1_flush(GstVaapiDecoder *base_decoder) +{ + GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); + GstVaapiDecoderVC1Private * const priv = decoder->priv; + + gst_vaapi_dpb_flush(priv->dpb); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static void gst_vaapi_decoder_vc1_finalize(GObject *object) { @@ -1313,6 +1323,7 @@ gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass) decoder_class->decode = gst_vaapi_decoder_vc1_decode; decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame; decoder_class->end_frame = gst_vaapi_decoder_vc1_end_frame; + decoder_class->flush = gst_vaapi_decoder_vc1_flush; } static void From b134a97d42c92d11dd5dcdee9f4848eea7cf776d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 22 Jan 2013 13:50:39 +0100 Subject: [PATCH 1047/3781] vc1: don't create GstBuffers for all decoder units. Don't create temporary GstBuffers for all decoder units, even if they are lightweight "sub-buffers", since it is not really necessary to keep the buffer data around. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index b746bea1c9..995e2f2509 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1008,15 +1008,10 @@ decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu) } static GstVaapiDecoderStatus -decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) +decode_buffer(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) { GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVC1BDU ebdu; - guchar *buf; - guint buf_size; - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); if (priv->has_codec_data) { ebdu.type = GST_VC1_FRAME; @@ -1224,13 +1219,9 @@ gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base_decoder, if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - unit->buffer = gst_buffer_create_sub( - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, - unit->offset, unit->size); - if (!unit->buffer) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - - status = decode_buffer(decoder, unit->buffer); + status = decode_buffer(decoder, + (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) + + unit->offset), unit->size); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; return GST_VAAPI_DECODER_STATUS_SUCCESS; From d69cb4389f12eec6d59a2970a4f06ad7156733f8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 22 Jan 2013 13:28:13 +0100 Subject: [PATCH 1048/3781] vc1: review and report errors accordingly. Use GST_ERROR() to report real errors instead of hiding them into GST_DEBUG(). --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 995e2f2509..9baf388c00 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -242,7 +242,7 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) seq_hdr ); if (result != GST_VC1_PARSER_OK) { - GST_DEBUG("failed to parse sequence layer"); + GST_ERROR("failed to parse sequence layer"); return get_status(result); } @@ -262,7 +262,7 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) case GST_VC1_PROFILE_ADVANCED: break; default: - GST_DEBUG("unsupported profile %d", seq_hdr->profile); + GST_ERROR("unsupported profile %d", seq_hdr->profile); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } @@ -370,7 +370,7 @@ decode_entry_point(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu seq_hdr ); if (result != GST_VC1_PARSER_OK) { - GST_DEBUG("failed to parse entrypoint layer"); + GST_ERROR("failed to parse entrypoint layer"); return get_status(result); } @@ -859,7 +859,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) priv->bitplanes ); if (result != GST_VC1_PARSER_OK) { - GST_DEBUG("failed to parse frame layer"); + GST_ERROR("failed to parse frame layer"); return get_status(result); } @@ -880,7 +880,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) picture->type = GST_VAAPI_PICTURE_TYPE_BI; break; default: - GST_DEBUG("unsupported picture type %d", frame_hdr->ptype); + GST_ERROR("unsupported picture type %d", frame_hdr->ptype); return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } @@ -909,7 +909,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) ebdu->size + ebdu->offset - ebdu->sc_offset ); if (!slice) { - GST_DEBUG("failed to allocate slice"); + GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } gst_vaapi_picture_add_slice(picture, slice); @@ -1000,7 +1000,7 @@ decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu) status = decode_sequence_end(decoder); break; default: - GST_DEBUG("unsupported BDU type %d", ebdu->type); + GST_WARNING("unsupported BDU type %d", ebdu->type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; break; } @@ -1051,14 +1051,14 @@ decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) width = GST_VAAPI_DECODER_WIDTH(decoder); height = GST_VAAPI_DECODER_HEIGHT(decoder); if (!width || !height) { - GST_DEBUG("failed to parse size from codec-data"); + GST_ERROR("failed to parse size from codec-data"); return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } caps = GST_VAAPI_DECODER_CODEC_STATE(decoder)->caps; structure = gst_caps_get_structure(caps, 0); if (!gst_structure_get_fourcc(structure, "format", &format)) { - GST_DEBUG("failed to parse profile from codec-data"); + GST_ERROR("failed to parse profile from codec-data"); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; } @@ -1238,20 +1238,20 @@ gst_vaapi_decoder_vc1_start_frame(GstVaapiDecoder *base_decoder, status = ensure_context(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_DEBUG("failed to reset context"); + GST_ERROR("failed to reset context"); return status; } picture = GST_VAAPI_PICTURE_NEW(VC1, decoder); if (!picture) { - GST_DEBUG("failed to allocate 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 (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, &priv->seq_hdr)) { - GST_DEBUG("failed to allocate bitplanes"); + GST_ERROR("failed to allocate bitplanes"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } return GST_VAAPI_DECODER_STATUS_SUCCESS; From a68c218c8ebf95b4c327dae5a990c09ecba09701 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 11 Jan 2013 17:08:00 +0800 Subject: [PATCH 1049/3781] vc1: fix decoding of WMV3 videos in AVI format. The AVI demuxer (avidemux) does not set a proper "format" attribute to the generated caps. So, try to recover the video codec format from the "wmvversion" property instead. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 9baf388c00..1fe3883ba7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1042,6 +1042,7 @@ decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) guint buf_size, ofs; gint width, height; guint32 format; + gint version; buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); @@ -1058,6 +1059,12 @@ decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) caps = GST_VAAPI_DECODER_CODEC_STATE(decoder)->caps; structure = gst_caps_get_structure(caps, 0); if (!gst_structure_get_fourcc(structure, "format", &format)) { + /* Try to determine format from "wmvversion" property */ + if (gst_structure_get_int(structure, "wmvversion", &version)) + format = (version >= 1 && version <= 3) ? + GST_MAKE_FOURCC('W','M','V',('0'+version)) : 0; + } + if (!format) { GST_ERROR("failed to parse profile from codec-data"); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; } From df411e435f08a7208a074291e7d734fbd0d04eed Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 22 Jan 2013 15:47:09 +0100 Subject: [PATCH 1050/3781] vc1: fix size of encapsulated BDU. Fix size of encapsulated BDUs since GstVC1BDU.size actually represents the size of the BDU data, starting from offset, i.e. after any start code is parsed. This fixes a buffer overflow during the unescaping process. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 1fe3883ba7..a34bc9f69a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1024,7 +1024,7 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) ebdu.offset = 4; } ebdu.data = buf; - ebdu.size = buf_size; + ebdu.size = buf_size - ebdu.offset; return decode_ebdu(decoder, &ebdu); } @@ -1098,7 +1098,7 @@ decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) switch (result) { case GST_VC1_PARSER_NO_BDU_END: /* Assume the EBDU is complete within codec-data bounds */ - ebdu.size = buf_size - ofs - (ebdu.offset - ebdu.sc_offset); + ebdu.size = buf_size - ofs - ebdu.offset; // fall-through case GST_VC1_PARSER_OK: status = decode_ebdu(decoder, &ebdu); From 0d256a49dad7820da41896df303cff164b79c5e8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 22 Jan 2013 10:51:40 +0100 Subject: [PATCH 1051/3781] codecparsers: update to gst-vaapi-branch commit 5d33da8. 5d33da8 vc1: fix bitplanes decoding 562bdc4 vc1: fix VOPDQUANT parser for DQUANT == 2 0b13d2b vc1: fix calculation of ALTPQUANT ba88e63 vc1: fix parser for DQPROFILE in VOPDQUANT --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 59acdd7e26..5d33da8709 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 59acdd7e268e0b2d6648652c71ada55bab01d00e +Subproject commit 5d33da8709f9620bbd5889f2345cc1d89692e56d From 56c31ca1c93db9759ab982c7006beaf670820111 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 23 Jan 2013 10:24:04 +0100 Subject: [PATCH 1052/3781] codecparsers: update to gst-vaapi-branch commit 3d2c67c. 3d2c67c vc1: simplify GstVC1VopDquant structure --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 5d33da8709..3d2c67ce3d 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 5d33da8709f9620bbd5889f2345cc1d89692e56d +Subproject commit 3d2c67ce3d80ec9028d50062e9dc9b84383caa75 From ee181d1b85dff40711f37561921cb0d73b0c649b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 23 Jan 2013 10:25:52 +0100 Subject: [PATCH 1053/3781] vc1: cope with latest codecparser changes. Fix build with newer VC-1 codecparser where dqsbedge was renamed to dqbedge, and now represents either DQSBEDGE or DQDBEDGE depending on the actual value of DQPROFILE. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index a34bc9f69a..4341560a2a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -734,6 +734,7 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) VAPictureParameterBufferVC1 * const pic_param = picture->param; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + GstVC1VopDquant * const vopdquant = &frame_hdr->vopdquant; GstVaapiPicture *prev_picture, *next_picture; /* Fill in VAPictureParameterBufferVC1 (common fields) */ @@ -760,12 +761,12 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) pic_param->pic_quantizer_fields.bits.half_qp = frame_hdr->halfqp; pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = frame_hdr->pquant; pic_param->pic_quantizer_fields.bits.pic_quantizer_type = frame_hdr->pquantizer; - pic_param->pic_quantizer_fields.bits.dq_frame = frame_hdr->vopdquant.dquantfrm; - pic_param->pic_quantizer_fields.bits.dq_profile = frame_hdr->vopdquant.dqprofile; - pic_param->pic_quantizer_fields.bits.dq_sb_edge = frame_hdr->vopdquant.dqsbedge; - pic_param->pic_quantizer_fields.bits.dq_db_edge = frame_hdr->vopdquant.dqsbedge; - pic_param->pic_quantizer_fields.bits.dq_binary_level = frame_hdr->vopdquant.dqbilevel; - pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = frame_hdr->vopdquant.altpquant; + pic_param->pic_quantizer_fields.bits.dq_frame = vopdquant->dquantfrm; + pic_param->pic_quantizer_fields.bits.dq_profile = vopdquant->dqprofile; + pic_param->pic_quantizer_fields.bits.dq_sb_edge = vopdquant->dqprofile == GST_VC1_DQPROFILE_SINGLE_EDGE ? vopdquant->dqbedge : 0; + pic_param->pic_quantizer_fields.bits.dq_db_edge = vopdquant->dqprofile == GST_VC1_DQPROFILE_DOUBLE_EDGES ? vopdquant->dqbedge : 0; + pic_param->pic_quantizer_fields.bits.dq_binary_level = vopdquant->dqbilevel; + pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = vopdquant->altpquant; pic_param->transform_fields.value = 0; pic_param->transform_fields.bits.transform_ac_codingset_idx1 = frame_hdr->transacfrm; pic_param->transform_fields.bits.intra_transform_dc_table = frame_hdr->transdctab; From 3eeff1786aa458356849db08859869078f1d7890 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 23 Jan 2013 11:11:25 +0100 Subject: [PATCH 1054/3781] vc1: handle CLOSED_ENTRY. When CLOSED_ENTRY == 0, and if the B pictures that follow an entry-point lack a reference anchor picture, these B pictures shall be discarded. https://bugs.freedesktop.org/show_bug.cgi?id=59505 --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 4341560a2a..70fdb34714 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -787,7 +787,11 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) case GST_VAAPI_PICTURE_TYPE_B: if (next_picture) pic_param->backward_reference_picture = next_picture->surface_id; - // fall-through + if (prev_picture) + pic_param->forward_reference_picture = prev_picture->surface_id; + else if (!priv->closed_entry) + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_SKIPPED); + break; case GST_VAAPI_PICTURE_TYPE_P: if (prev_picture) pic_param->forward_reference_picture = prev_picture->surface_id; From 9f2b2a56d67711205e6759dc6c2aa667773595e7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 23 Jan 2013 17:01:34 +0100 Subject: [PATCH 1055/3781] codecparsers: update to gst-vaapi-branch commit 3fba492. 3fba492 vc1: add API to parse slice headers --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 3d2c67ce3d..3fba492c9e 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 3d2c67ce3d80ec9028d50062e9dc9b84383caa75 +Subproject commit 3fba492c9ea8cbbcbe4049f103699fd63cbc463c From efd90114bfdc00d8c2010ab4271395ed5ae340bd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 23 Jan 2013 16:38:24 +0100 Subject: [PATCH 1056/3781] vc1: handle frames with multiple slices. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 67 +++++++++++++++++------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 70fdb34714..f1b98a2b3b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -845,6 +845,32 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) return TRUE; } +static GstVaapiDecoderStatus +decode_slice_chunk(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu, + guint slice_addr, guint header_size) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiPicture * const picture = priv->current_picture; + GstVaapiSlice *slice; + VASliceParameterBufferVC1 *slice_param; + + slice = GST_VAAPI_SLICE_NEW(VC1, decoder, + ebdu->data + ebdu->sc_offset, + ebdu->size + ebdu->offset - ebdu->sc_offset); + if (!slice) { + GST_ERROR("failed to allocate slice"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + gst_vaapi_picture_add_slice(picture, slice); + + /* Fill in VASliceParameterBufferVC1 */ + slice_param = slice->param; + slice_param->macroblock_offset = 8 * (ebdu->offset - ebdu->sc_offset) + + header_size; + slice_param->slice_vertical_position = slice_addr; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { @@ -852,8 +878,6 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; GstVC1ParserResult result; GstVaapiPicture * const picture = priv->current_picture; - GstVaapiSlice *slice; - VASliceParameterBufferVC1 *slice_param; memset(frame_hdr, 0, sizeof(*frame_hdr)); result = gst_vc1_parse_frame_header( @@ -906,25 +930,29 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) if (!fill_picture(decoder, picture)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + return decode_slice_chunk(decoder, ebdu, 0, frame_hdr->header_size); +} - slice = GST_VAAPI_SLICE_NEW( - VC1, - decoder, - ebdu->data + ebdu->sc_offset, - ebdu->size + ebdu->offset - ebdu->sc_offset +static GstVaapiDecoderStatus +decode_slice(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) +{ + GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVC1SliceHdr slice_hdr; + GstVC1ParserResult result; + + memset(&slice_hdr, 0, sizeof(slice_hdr)); + result = gst_vc1_parse_slice_header( + rbdu->data + rbdu->offset, + rbdu->size, + &slice_hdr, + &priv->seq_hdr ); - if (!slice) { - GST_ERROR("failed to allocate slice"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + if (result != GST_VC1_PARSER_OK) { + GST_ERROR("failed to parse slice layer"); + return get_status(result); } - gst_vaapi_picture_add_slice(picture, slice); - - /* Fill in VASliceParameterBufferVC1 */ - slice_param = slice->param; - slice_param->macroblock_offset = 8 * (ebdu->offset - ebdu->sc_offset) + frame_hdr->header_size; - slice_param->slice_vertical_position = 0; - - return GST_VAAPI_DECODER_STATUS_SUCCESS; + return decode_slice_chunk(decoder, ebdu, slice_hdr.slice_addr, + slice_hdr.header_size); } static gboolean @@ -998,8 +1026,7 @@ decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu) status = decode_frame(decoder, &rbdu, ebdu); break; case GST_VC1_SLICE: - GST_DEBUG("decode slice"); - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + status = decode_slice(decoder, &rbdu, ebdu); break; case GST_VC1_END_OF_SEQ: status = decode_sequence_end(decoder); From 0ed1735d8bd3eabcf69d5201a78f81f649abec09 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 24 Jan 2013 17:38:53 +0100 Subject: [PATCH 1057/3781] codecparsers: update to gst-vaapi-branch commit 21a098e. 21a098e vc1: fix bitplanes decoding (DIFF6 or NORM6) [residual] f8c836a vc1: fix bitplanes decoding (DIFF6 or NORM6) --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 3fba492c9e..21a098e462 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 3fba492c9ea8cbbcbe4049f103699fd63cbc463c +Subproject commit 21a098e46204048fe4daf190655f76ea9c6bb76e From 087bf30c23ac335c482c8be2e5759d7a918cf2c6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jan 2013 14:45:28 +0100 Subject: [PATCH 1058/3781] wayland: fix display sharing. When the Wayland display is shared, we still have to create our own local shell and compositor objects, since they are not propagated from the cache. Likewise, we also need to determine the display size or vaapisink would fail to account for the display aspect ratio, and will try to create a 0x0 window. --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index ec2c81a226..bb91128b7c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -285,12 +285,11 @@ gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display) GstVaapiDisplayWaylandPrivate * const priv = GST_VAAPI_DISPLAY_WAYLAND(display)->priv; - if (!priv->create_display) - return priv->wl_display != NULL; - - priv->wl_display = wl_display_connect(get_display_name(display)); - if (!priv->wl_display) - return FALSE; + if (priv->create_display) { + priv->wl_display = wl_display_connect(get_display_name(display)); + if (!priv->wl_display) + return FALSE; + } wl_display_set_user_data(priv->wl_display, priv); priv->registry = wl_display_get_registry(priv->wl_display); @@ -298,6 +297,14 @@ gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display) 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; From 23c6053b947f72962aec98f77da37b72d54fad9f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 23 Jan 2013 10:10:35 +0100 Subject: [PATCH 1059/3781] wayland: fix frame_redraw callback. The redraw callback needs to be attached to the surface prior to the commit. Otherwise, the callback notifies the next surface repaint, which is not the desired behaviour. i.e. we want to be notified for the surface we have just filled. Another isse was the redraw_pending was reset before the actual completion of the frame redraw callback function, thus causing concurrency issues. e.g. the callback could have been called again, but with a NULL buffer. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index c22c678793..850dae40f4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -208,10 +208,10 @@ frame_redraw_callback(void *data, struct wl_callback *callback, uint32_t time) { GstVaapiWindowWaylandPrivate * const priv = data; - priv->redraw_pending = FALSE; wl_buffer_destroy(priv->buffer); priv->buffer = NULL; wl_callback_destroy(callback); + priv->redraw_pending = FALSE; } static const struct wl_callback_listener frame_callback_listener = { @@ -292,14 +292,13 @@ gst_vaapi_window_wayland_render( priv->opaque_region = NULL; } - wl_surface_commit(priv->surface); - - wl_display_flush(wl_display); priv->redraw_pending = TRUE; priv->buffer = buffer; - callback = wl_surface_frame(priv->surface); wl_callback_add_listener(callback, &frame_callback_listener, priv); + + wl_surface_commit(priv->surface); + wl_display_flush(wl_display); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); return TRUE; } From 1fb25b0853ac46ed13d7d2f345ab9945873b18d9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jan 2013 16:37:28 +0100 Subject: [PATCH 1060/3781] wayland: really wait until the pending redraw completed. Introduce gst_vaapi_window_wayland_sync() helper function to wait for the completion of the redraw request. Use it in _render() function to actually block until the previous draw request is completed. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 28 ++++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 850dae40f4..e475514fe0 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -71,6 +71,26 @@ gst_vaapi_window_wayland_hide(GstVaapiWindow *window) return TRUE; } +static gboolean +gst_vaapi_window_wayland_sync(GstVaapiWindow *window) +{ + GstVaapiWindowWaylandPrivate * const priv = + GST_VAAPI_WINDOW_WAYLAND(window)->priv; + gboolean success = TRUE; + + if (priv->redraw_pending) { + struct wl_display * const wl_display = + GST_VAAPI_OBJECT_WL_DISPLAY(window); + + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + do { + success = wl_display_dispatch(wl_display) >= 0; + } while (success && priv->redraw_pending); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + } + return success; +} + static void handle_ping(void *data, struct wl_shell_surface *shell_surface, uint32_t serial) @@ -256,11 +276,11 @@ gst_vaapi_window_wayland_render( if (surface_id == VA_INVALID_ID) return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - /* Wait for the previous frame to complete redraw */ - if (priv->redraw_pending) - wl_display_dispatch(wl_display); + if (!gst_vaapi_window_wayland_sync(window)) + return FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); /* XXX: use VA/VPP for other filters */ va_flags = from_GstVaapiSurfaceRenderFlags(flags); From 96d12f9eb12b31f3844912a02f89687d2a1d15b9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jan 2013 17:28:58 +0100 Subject: [PATCH 1061/3781] wayland: fix thread-safe issues. The Wayland API is not fully thread-safe and client applications shall perform locking themselves on key functions. Besides, make sure to release the lock if the _render() function fails. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index e475514fe0..b09c7d4b61 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -157,12 +157,16 @@ gst_vaapi_window_wayland_create( g_return_val_if_fail(priv_display->compositor != NULL, FALSE); g_return_val_if_fail(priv_display->shell != NULL, FALSE); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); priv->surface = wl_compositor_create_surface(priv_display->compositor); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (!priv->surface) return FALSE; + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); priv->shell_surface = wl_shell_get_shell_surface(priv_display->shell, priv->surface); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (!priv->shell_surface) return FALSE; @@ -217,7 +221,9 @@ gst_vaapi_window_wayland_resize( if (priv->opaque_region) wl_region_destroy(priv->opaque_region); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); priv->opaque_region = wl_compositor_create_region(priv_display->compositor); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); wl_region_add(priv->opaque_region, 0, 0, width, height); return TRUE; @@ -280,9 +286,8 @@ gst_vaapi_window_wayland_render( if (!gst_vaapi_window_wayland_sync(window)) return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - /* XXX: use VA/VPP for other filters */ + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); va_flags = from_GstVaapiSurfaceRenderFlags(flags); status = vaGetSurfaceBufferWl( GST_VAAPI_DISPLAY_VADISPLAY(display), @@ -299,10 +304,12 @@ gst_vaapi_window_wayland_render( &buffer ); } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (!vaapi_check_status(status, "vaGetSurfaceBufferWl()")) return FALSE; /* XXX: attach to the specified target rectangle */ + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); wl_surface_attach(priv->surface, buffer, 0, 0); wl_surface_damage(priv->surface, 0, 0, width, height); From 1d16669acae6b6a1f3bf4935cfe6f24353d1fef3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jan 2013 18:09:09 +0100 Subject: [PATCH 1062/3781] wayland: use a local event queue to avoid lock contention. This improves performance when rendering several surfaces from within the same process. e.g. a tee of vaapidecode'd buffers to vaapisink. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 25 ++++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index b09c7d4b61..82f07b3cf6 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -50,6 +50,7 @@ struct _GstVaapiWindowWaylandPrivate { struct wl_surface *surface; struct wl_buffer *buffer; struct wl_region *opaque_region; + struct wl_event_queue *event_queue; guint redraw_pending : 1; guint is_shown : 1; guint fullscreen_on_show : 1; @@ -76,19 +77,17 @@ gst_vaapi_window_wayland_sync(GstVaapiWindow *window) { GstVaapiWindowWaylandPrivate * const priv = GST_VAAPI_WINDOW_WAYLAND(window)->priv; - gboolean success = TRUE; if (priv->redraw_pending) { struct wl_display * const wl_display = GST_VAAPI_OBJECT_WL_DISPLAY(window); - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); do { - success = wl_display_dispatch(wl_display) >= 0; - } while (success && priv->redraw_pending); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + if (wl_display_dispatch_queue(wl_display, priv->event_queue) < 0) + return FALSE; + } while (priv->redraw_pending); } - return success; + return TRUE; } static void @@ -157,11 +156,18 @@ gst_vaapi_window_wayland_create( g_return_val_if_fail(priv_display->compositor != NULL, FALSE); g_return_val_if_fail(priv_display->shell != NULL, FALSE); + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + priv->event_queue = wl_display_create_queue(priv_display->wl_display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + if (!priv->event_queue) + return FALSE; + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); priv->surface = wl_compositor_create_surface(priv_display->compositor); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (!priv->surface) return FALSE; + wl_proxy_set_queue((struct wl_proxy *)priv->surface, priv->event_queue); GST_VAAPI_OBJECT_LOCK_DISPLAY(window); priv->shell_surface = @@ -169,6 +175,8 @@ gst_vaapi_window_wayland_create( GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); if (!priv->shell_surface) return FALSE; + wl_proxy_set_queue((struct wl_proxy *)priv->shell_surface, + priv->event_queue); wl_shell_surface_add_listener(priv->shell_surface, &shell_surface_listener, priv); @@ -203,6 +211,11 @@ gst_vaapi_window_wayland_destroy(GstVaapiWindow * window) wl_buffer_destroy(priv->buffer); priv->buffer = NULL; } + + if (priv->event_queue) { + wl_event_queue_destroy(priv->event_queue); + priv->event_queue = NULL; + } } static gboolean From e8ea18b2098787775ebf04243ad00c499389d7f1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 29 Jan 2013 13:37:41 +0100 Subject: [PATCH 1063/3781] NEWS: updates. --- NEWS | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 8ee2fabd19..b42f82a07e 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,16 @@ -gst-vaapi NEWS -- summary of changes. 2013-01-15 +gst-vaapi NEWS -- summary of changes. 2013-01-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2012 Intel Corporation Copyright (C) 2011 Collabora +Version 0.5.1 - DD.Jan.2013 +* Add simple decoder demo that only uses libgstvaapi +* Fix thread-safety issues in the Wayland renderer +* Fix VC-1 decoding bugs #692461, #692312, #692271, #692270, #692267 +* Fix decoding of VC-1 videos in AVI containers (Feng Yuan) +* Fix H.264 parser to zero-initialize key syntax elements +* Fix MPEG-2, H.264 and VC-1 decoders to submit all decoded frames on + Version 0.5.0 - 15.Jan.2013 * Optimize MPEG-2 and H.264 decoders * Use GstVideoDecoder API for vaapidecode (+Sreerenj Balachandran) From 0f662a89131e30bbc353b3ca74e1f38d8767ac3e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 29 Jan 2013 14:00:04 +0100 Subject: [PATCH 1064/3781] legal: add Intel copyright on modified files. --- gst-libs/gst/vaapi/gstvaapicompat.h | 1 + gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 1 + gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 1 + gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 1 + gst-libs/gst/vaapi/gstvaapiimagepool.c | 1 + gst-libs/gst/vaapi/gstvaapiimagepool.h | 1 + gst-libs/gst/vaapi/gstvaapiobject.c | 1 + gst-libs/gst/vaapi/gstvaapiobject.h | 1 + gst-libs/gst/vaapi/gstvaapiobject_priv.h | 1 + gst-libs/gst/vaapi/gstvaapiparamspecs.c | 1 + gst-libs/gst/vaapi/gstvaapiparamspecs.h | 1 + gst-libs/gst/vaapi/gstvaapiprofile.c | 1 + gst-libs/gst/vaapi/gstvaapiprofile.h | 1 + gst-libs/gst/vaapi/gstvaapisurfacepool.c | 1 + gst-libs/gst/vaapi/gstvaapisurfacepool.h | 1 + gst-libs/gst/vaapi/gstvaapitexture.c | 1 + gst-libs/gst/vaapi/gstvaapitexture.h | 1 + gst-libs/gst/vaapi/gstvaapitypes.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_glx.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_x11.h | 1 + gst-libs/gst/vaapi/gstvaapivalue.c | 1 + gst-libs/gst/vaapi/gstvaapivalue.h | 1 + gst-libs/gst/vaapi/gstvaapivideopool.c | 1 + gst-libs/gst/vaapi/gstvaapivideopool.h | 1 + gst-libs/gst/vaapi/gstvaapiwindow.h | 1 + gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 1 + gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 1 + gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 1 + gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 1 + tests/test-display.c | 1 + tests/test-surfaces.c | 1 + tests/test-windows.c | 1 + 32 files changed, 32 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 4a1f93d8d7..9e8ce5914b 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -2,6 +2,7 @@ * gstvapicompat.h - VA-API compatibility glue * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index 6f115e5096..057baf78db 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -2,6 +2,7 @@ * gstvaapidisplay_glx.h - VA/GLX display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 358f59f8a8..66f8f1b9b1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -2,6 +2,7 @@ * gstvaapidisplay_x11.h - VA/X11 display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index bc04ecbea2..17b54beda9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -2,6 +2,7 @@ * gstvaapidisplay_x11_priv.h - Internal VA/X11 interface * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 26462d3b2f..a23c4a0ec4 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -2,6 +2,7 @@ * gstvaapiimagepool.c - Gst VA image pool * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index 2478c470b4..fa6d6b15cd 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -2,6 +2,7 @@ * gstvaapiimagepool.h - Gst VA image pool * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 7e7b1913e8..b9f6f62bf9 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -2,6 +2,7 @@ * gstvaapiobject.c - Base VA object * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index 913cac8690..40da7a81d1 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -2,6 +2,7 @@ * gstvaapiobject.h - Base VA object * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index aa1b110943..1e871b2a3f 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -2,6 +2,7 @@ * gstvaapiobject_priv.h - Base VA object (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.c b/gst-libs/gst/vaapi/gstvaapiparamspecs.c index 8905af4d21..46a4e8d847 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.c +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.c @@ -2,6 +2,7 @@ * gstvaapiparamspecs.c - GParamSpecs for some of our types * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.h b/gst-libs/gst/vaapi/gstvaapiparamspecs.h index 5b201496ff..a97071a1b3 100644 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.h +++ b/gst-libs/gst/vaapi/gstvaapiparamspecs.h @@ -2,6 +2,7 @@ * gstvaapiparamspecs.h - GParamSpecs for some of our types * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index a2b3da499b..76a55c39ce 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -2,6 +2,7 @@ * gstvaapiprofile.c - VA profile abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 1be5f8ffa1..ce0851bdd3 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -2,6 +2,7 @@ * gstvaapiprofile.h - VA profile abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 528d6f4d52..0caf5ad1bd 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -2,6 +2,7 @@ * gstvaapisurfacepool.c - Gst VA surface pool * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 2bb661c884..aff88ca890 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -2,6 +2,7 @@ * gstvaapisurfacepool.h - Gst VA surface pool * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 1b38ef330a..6f3f75b17a 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -2,6 +2,7 @@ * gstvaapitexture.c - VA texture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 4f8f3ce379..42959817ed 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -2,6 +2,7 @@ * gstvaapitexture.h - VA texture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 1ca4dd7238..e3a6e9ce5e 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -2,6 +2,7 @@ * gstvaapitypes.h - Basic types * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 912d0723b3..12d2205868 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -2,6 +2,7 @@ * gstvaapiutils_glx.h - GLX utilties * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index 090b403718..60befa5ffc 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -2,6 +2,7 @@ * gstvaapiutils_x11.h - X11 utilties * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 401770e759..c709f22431 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -2,6 +2,7 @@ * gstvaapivalue.c - GValue implementations specific to VA-API * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index ec99f8e57e..a363417287 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -2,6 +2,7 @@ * gstvaapivalue.h - GValue implementations specific to VA-API * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 774305ee1c..3c2dd63bf3 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -2,6 +2,7 @@ * gstvaapivideopool.c - Video object pool abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index f2fdb5e5cd..77233e4a81 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -2,6 +2,7 @@ * gstvaapivideopool.h - Video object pool abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 5fdaf812f6..36d6c416e2 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -2,6 +2,7 @@ * gstvaapiwindow.h - VA window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 9266bbbc06..7870debfc2 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -2,6 +2,7 @@ * gstvaapiwindow_glx.c - VA/GLX window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index 55473557c9..6bdbb667ee 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -2,6 +2,7 @@ * gstvaapiwindow_glx.h - VA/GLX window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 9a5db7943a..13fd7195c2 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -2,6 +2,7 @@ * gstvaapiwindow_x11.c - VA/X11 window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index f1f22d4780..47d9665544 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -2,6 +2,7 @@ * gstvaapiwindow_x11.h - VA/X11 window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-display.c b/tests/test-display.c index fa381cdd83..568c368113 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -2,6 +2,7 @@ * test-display.c - Test GstVaapiDisplayX11 * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index c236e5ee16..a5b5f69f9d 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -2,6 +2,7 @@ * test-surfaces.c - Test GstVaapiSurface and GstVaapiSurfacePool * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-windows.c b/tests/test-windows.c index 8abc7842a0..9c3b7688c3 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -2,6 +2,7 @@ * test-windows.c - Test GstVaapiWindow * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License From 22094ed053c163dcf1050287a5f0f37fb400aa0d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 29 Jan 2013 14:03:27 +0100 Subject: [PATCH 1065/3781] legal: fix year for some copyright notices (2012). --- gst-libs/gst/vaapi/gstvaapicontext.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_vc1.h | 2 +- gst-libs/gst/vaapi/gstvaapiimageformat.c | 2 +- gst-libs/gst/vaapi/gstvaapiimageformat.h | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.h | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- gst-libs/gst/vaapi/gstvaapisurface_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 2 +- gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h | 2 +- gst/vaapi/gstvaapidecode.h | 2 +- gst/vaapi/gstvaapisink.h | 2 +- tests/test-subpicture.c | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index cffbd7ebb0..41ce0c5016 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -2,7 +2,7 @@ * gstvaapicontext.h - VA context abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 7af4a3a2e5..793596a3fc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -2,7 +2,7 @@ * gstvaapidecoder.h - VA decoder abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index c243648685..90459e1733 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_mpeg2.c - MPEG-2 decoder * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h index e438c39654..dd3468a85b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_mpeg2.h - MPEG-2 decoder * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 49754b3cb0..e56012bc5c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_mpeg4.c - MPEG-4 decoder * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h index 4c877bbae8..5d24fdd6f5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_mpeg4.h - MPEG-4 decoder * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index f1b98a2b3b..9dcd0af987 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_vc1.c - VC-1 decoder * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h index 1bed6067c9..53ecde4e64 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_vc1.h - VC-1 decoder * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index d29ef6c286..4cb0296dd2 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -2,7 +2,7 @@ * gstvaapiimageformat.c - VA image format abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index 9e1e66274d..d5b0c964d9 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -2,7 +2,7 @@ * gstvaapiimageformat.h - VA image format abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 99429c1dfc..e0b87c01ef 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -2,7 +2,7 @@ * gstvaapisubpicture.c - VA subpicture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 80c05d3824..22a09f0a75 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -2,7 +2,7 @@ * gstvaapisubpicture.h - VA subpicture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 46ad45e067..8f90706b15 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -2,7 +2,7 @@ * gstvaapisurface.c - VA surface abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 4b8aaeac50..9b74e7a0b0 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -2,7 +2,7 @@ * gstvaapisurface.h - VA surface abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index 0817b2911c..d3b487e241 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -1,7 +1,7 @@ /* * gstvaapisurface_priv.h - VA surface abstraction (private data) * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index abc58b8e73..83a13ee904 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -2,7 +2,7 @@ * gstvaapiutils_x11.c - X11 utilties * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 994f057370..98229426c7 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -2,7 +2,7 @@ * gstvaapivideobuffer.c - Gst VA video buffer * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index e7f09ed3be..e60ecf29f7 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -2,7 +2,7 @@ * gstvaapivideobuffer.h - Gstreamer/VA video buffer * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index dc5c62e21e..9413695341 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -1,7 +1,7 @@ /* * gstvaapivideoconverter_glx.c - Gst VA video converter * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * Copyright (C) 2011 Collabora Ltd. * Author: Nicolas Dufresne * diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h index 0215444d49..67d0f2e7e0 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h @@ -1,7 +1,7 @@ /* * gstvaapivideoconverter_glx.h - Gstreamer/VA video converter * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * Copyright (C) 2011 Collabora Ltd. * Author: Nicolas Dufresne * diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 35adabac71..89966f09e8 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -2,7 +2,7 @@ * gstvaapidecode.h - VA-API video decoder * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index b8b082a960..8db8ac2387 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -2,7 +2,7 @@ * gstvaapisink.h - VA-API video sink * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index c94ddb9c3b..eb98582906 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -1,7 +1,7 @@ /* * test-subpicture.c - Test GstVaapiSubpicture * - * Copyright (C) <2011> Intel Corporation + * Copyright (C) <2011-2012> Intel Corporation * Copyright (C) <2011> Collabora Ltd. * Copyright (C) <2011> Thibault Saunier * From 0c99f351fcadedb555d096b61f5188b2dd3ca88b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 29 Jan 2013 14:14:45 +0100 Subject: [PATCH 1066/3781] legal: fix year for some copyright notices (2013). --- NEWS | 2 +- README | 2 +- debian.upstream/copyright | 2 +- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 2 +- gst-libs/gst/vaapi/gstvaapicontext.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_dpb.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_frame.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_frame.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_unit.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_unit.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 2 +- gst-libs/gst/vaapi/gstvaapiminiobject.c | 2 +- gst-libs/gst/vaapi/gstvaapiprofile.h | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.h | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils.h | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.c | 2 +- gst-libs/gst/vaapi/gstvaapivideobuffer.h | 2 +- gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 2 +- gst-libs/gst/vaapi/sysdeps.h | 2 +- gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapidownload.c | 2 +- gst/vaapi/gstvaapipluginbuffer.c | 2 +- gst/vaapi/gstvaapipluginbuffer.h | 2 +- gst/vaapi/gstvaapipostproc.c | 2 +- gst/vaapi/gstvaapisink.c | 2 +- gst/vaapi/gstvaapiupload.c | 2 +- gst/vaapi/gstvaapiuploader.c | 2 +- tests/output.c | 2 +- tests/test-decode.c | 2 +- tests/test-subpicture.c | 2 +- 47 files changed, 47 insertions(+), 47 deletions(-) diff --git a/NEWS b/NEWS index b42f82a07e..c149a75f04 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ gst-vaapi NEWS -- summary of changes. 2013-01-DD Copyright (C) 2010-2011 Splitted-Desktop Systems -Copyright (C) 2011-2012 Intel Corporation +Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora Version 0.5.1 - DD.Jan.2013 diff --git a/README b/README index 91dc10827a..9b65f72a68 100644 --- a/README +++ b/README @@ -3,7 +3,7 @@ VA-API support to GStreamer Copyright (C) 2010-2011 Splitted-Desktop Systems - Copyright (C) 2011-2012 Intel Corporation + Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora Ltd. diff --git a/debian.upstream/copyright b/debian.upstream/copyright index bb733ae5a7..083ce8634e 100644 --- a/debian.upstream/copyright +++ b/debian.upstream/copyright @@ -9,7 +9,7 @@ Copyright: License: Copyright (C) 2010-2011, Splitted-Desktop Systems. - Copyright (C) 2011-2012, Intel Corporation. + Copyright (C) 2011-2013, Intel Corporation. Copyright (C) 2011, Collabora Ltd. gstreamer-vaapi helper libraries and plugins elements are available under diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index eddd7bd6b4..32792436b9 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -2,7 +2,7 @@ * gstvaapicodec_objects.c - VA codec objects abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 84ff9d7aa3..95ddbbcae1 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -2,7 +2,7 @@ * gstvaapicontext.c - VA context abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 360374690f..b217acd1f0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -2,7 +2,7 @@ * gstvaapidecoder.c - VA decoder abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 793596a3fc..1558d28daa 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -2,7 +2,7 @@ * gstvaapidecoder.h - VA decoder abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index adcfd828c7..047fa24514 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_dpb.c - Decoded Picture Buffer * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h index 18dbf572a8..4fc1a20d97 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_dpb.h - Decoded Picture Buffer * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.c b/gst-libs/gst/vaapi/gstvaapidecoder_frame.c index cae0d30873..c2e659b814 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_frame.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_frame.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_frame.c - VA decoder frame * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h index 4a3595a368..ed42fe2462 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_frame.h - VA decoder frame * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 7ca10fc3fb..db180965ec 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_h264.c - H.264 decoder * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 22161c3e0f..f3221b992a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_jpeg.c - JPEG decoder * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 90459e1733..0751203e32 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_mpeg2.c - MPEG-2 decoder * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index e56012bc5c..0dd3425570 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_mpeg4.c - MPEG-4 decoder * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index efc95a3ba9..9b450bb499 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -2,7 +2,7 @@ * gstvaapidecoder_objects.c - VA decoder objects helpers * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index f6066e9cb2..f0e173f650 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -2,7 +2,7 @@ * gstvaapidecoder_objects.h - VA decoder objects * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 1887ee4cbd..9b0867d4ab 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -2,7 +2,7 @@ * gstvaapidecoder_priv.h - VA decoder abstraction (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c index 217dde609d..af37947900 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_unit.c - VA decoder units * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h index 2c10129f4f..6ccc59bddf 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_unit.h - VA decoder units * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 9dcd0af987..d42f72e151 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_vc1.c - VC-1 decoder * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index a3cd13ccae..4a6dae0024 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -2,7 +2,7 @@ * gstvaapidisplay.c - VA display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index ddfb3750bc..53809b62e9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -2,7 +2,7 @@ * gstvaapidisplay.h - VA display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index bb91128b7c..3d162b15e7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -1,7 +1,7 @@ /* * gstvaapidisplay_wayland.c - VA/Wayland display abstraction * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.c b/gst-libs/gst/vaapi/gstvaapiminiobject.c index 08427d3497..081df1d905 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.c @@ -1,7 +1,7 @@ /* * gstvaapiminiobject.c - A lightweight reference counted object * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index ce0851bdd3..8663029a75 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -2,7 +2,7 @@ * gstvaapiprofile.h - VA profile abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index e0b87c01ef..bed0d89aa5 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -2,7 +2,7 @@ * gstvaapisubpicture.c - VA subpicture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 22a09f0a75..674f5ce726 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -2,7 +2,7 @@ * gstvaapisubpicture.h - VA subpicture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 8f90706b15..d9c676ceeb 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -2,7 +2,7 @@ * gstvaapisurface.c - VA surface abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 1461b2817b..f959dd9d49 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -2,7 +2,7 @@ * gstvaapiutils.c - VA-API utilities * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 791fe1460d..da693447df 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -2,7 +2,7 @@ * gstvaapiutils.h - VA-API utilities * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst-libs/gst/vaapi/gstvaapivideobuffer.c index 98229426c7..afb173cf6d 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.c @@ -2,7 +2,7 @@ * gstvaapivideobuffer.c - Gst VA video buffer * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h index e60ecf29f7..adc88d0024 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ b/gst-libs/gst/vaapi/gstvaapivideobuffer.h @@ -2,7 +2,7 @@ * gstvaapivideobuffer.h - Gstreamer/VA video buffer * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c index 9413695341..afb6e6ed8a 100644 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c @@ -1,7 +1,7 @@ /* * gstvaapivideoconverter_glx.c - Gst VA video converter * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Copyright (C) 2011 Collabora Ltd. * Author: Nicolas Dufresne * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 82f07b3cf6..38d62636f7 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -1,7 +1,7 @@ /* * gstvaapiwindow_wayland.c - VA/Wayland window abstraction * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/sysdeps.h b/gst-libs/gst/vaapi/sysdeps.h index 6f072fc39d..2748e02316 100644 --- a/gst-libs/gst/vaapi/sysdeps.h +++ b/gst-libs/gst/vaapi/sysdeps.h @@ -1,7 +1,7 @@ /* * sysdeps.h - System-dependent definitions * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index e33a73444a..45f1b8e741 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -2,7 +2,7 @@ * gstvaapidecode.c - VA-API video decoder * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 34a8dcbe0a..4d1d49fef8 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -2,7 +2,7 @@ * gstvaapidownload.c - VA-API video downloader * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapipluginbuffer.c b/gst/vaapi/gstvaapipluginbuffer.c index 560081d611..1ed8f980e4 100644 --- a/gst/vaapi/gstvaapipluginbuffer.c +++ b/gst/vaapi/gstvaapipluginbuffer.c @@ -1,7 +1,7 @@ /* * gstvaapipluginbuffer.c - Private GStreamer/VA video buffers * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapipluginbuffer.h b/gst/vaapi/gstvaapipluginbuffer.h index fb2dbfff4b..d3a509f998 100644 --- a/gst/vaapi/gstvaapipluginbuffer.h +++ b/gst/vaapi/gstvaapipluginbuffer.h @@ -1,7 +1,7 @@ /* * gstvaapipluginbuffer.h - Private GStreamer/VA video buffers * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 62dcc115ac..a40352f744 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1,7 +1,7 @@ /* * gstvaapipostproc.c - VA-API video postprocessing * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index aa3249ceef..1ca403f6b9 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -2,7 +2,7 @@ * gstvaapisink.c - VA-API video sink * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 6e5b054534..6118454634 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -2,7 +2,7 @@ * gstvaapiupload.c - VA-API video upload element * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 425b2e77e9..460435e54a 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -2,7 +2,7 @@ * gstvaapiuploader.c - VA-API video upload helper * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/output.c b/tests/output.c index a1b427f445..5116baddab 100644 --- a/tests/output.c +++ b/tests/output.c @@ -1,7 +1,7 @@ /* * output.c - Video output helpers * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-decode.c b/tests/test-decode.c index 4afed15c12..6ee32b2e7c 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -2,7 +2,7 @@ * test-decode.c - Test GstVaapiDecoder * * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index eb98582906..5c81942392 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -1,7 +1,7 @@ /* * test-subpicture.c - Test GstVaapiSubpicture * - * Copyright (C) <2011-2012> Intel Corporation + * Copyright (C) <2011-2013> Intel Corporation * Copyright (C) <2011> Collabora Ltd. * Copyright (C) <2011> Thibault Saunier * From aee91a31ba83d2ae2f93bda4700b6cf46df53fe9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 29 Jan 2013 16:18:13 +0100 Subject: [PATCH 1067/3781] decoder: assume current frame is complete at end-of-stream. Assume we got a complete frame when the end-of-stream is reached and that the current codec frame contains at least one slice data unit. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index b217acd1f0..97baec2d1b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -167,8 +167,15 @@ do_parse(GstVaapiDecoder *decoder, ps->current_frame = base_frame; status = GST_VAAPI_DECODER_GET_CLASS(decoder)->parse(decoder, adapter, at_eos, unit); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + if (at_eos && frame->units->len > 0 && + status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) { + /* XXX: assume the frame is complete at */ + *got_frame_ptr = TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; + } return status; + } if (GST_VAAPI_DECODER_UNIT_IS_FRAME_START(unit) && frame->units->len > 0) { ps->next_unit_pending = TRUE; From 3e4c7f564dac3fa05219ff9c07b0a66e05a42d64 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 24 Jan 2013 17:34:43 +0200 Subject: [PATCH 1068/3781] decoder: fix documentation for GstVaapiDecoderFrame. Drop superfluous reference to prev_slice member. --- gst-libs/gst/vaapi/gstvaapidecoder_frame.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h index ed42fe2462..84b5f6ff27 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_frame.h @@ -57,8 +57,6 @@ typedef enum { * @units: list of #GstVaapiDecoderUnit objects (slice data) * @pre_units: list of units to decode before GstVaapiDecoder:start_frame() * @post_units: list of units to decode after GstVaapiDecoder:end_frame() - * @prev_slice: previous #GstVaapiDecoderUnit that was a slice, or NULL - * if no slice data unit was received yet * * An extension to #GstVideoCodecFrame with #GstVaapiDecoder specific * information. Decoder frames are usually attached to codec frames as From 0d5e203e799c022d05c44a6f8d39120fa4a23b3f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 24 Jan 2013 00:48:26 +0200 Subject: [PATCH 1069/3781] mpeg2: implement GstVaapiDecoder::flush() as a DPB flush. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 0751203e32..575af43d9a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1509,6 +1509,17 @@ gst_vaapi_decoder_mpeg2_end_frame(GstVaapiDecoder *base_decoder) return decode_current_picture(decoder); } +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg2_flush(GstVaapiDecoder *base_decoder) +{ + GstVaapiDecoderMpeg2 * const decoder = + GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + + gst_vaapi_dpb_flush(priv->dpb); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static void gst_vaapi_decoder_mpeg2_finalize(GObject *object) { @@ -1548,6 +1559,7 @@ gst_vaapi_decoder_mpeg2_class_init(GstVaapiDecoderMpeg2Class *klass) decoder_class->decode = gst_vaapi_decoder_mpeg2_decode; decoder_class->start_frame = gst_vaapi_decoder_mpeg2_start_frame; decoder_class->end_frame = gst_vaapi_decoder_mpeg2_end_frame; + decoder_class->flush = gst_vaapi_decoder_mpeg2_flush; } static void From 52fd545c6e5e59ef7d1c3d4ce80ee047dc4fd3dc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jan 2013 09:37:38 +0100 Subject: [PATCH 1070/3781] 0.5.1. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index c149a75f04..df2c09ea05 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2013-01-DD +gst-vaapi NEWS -- summary of changes. 2013-01-29 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora -Version 0.5.1 - DD.Jan.2013 +Version 0.5.1 - 29.Jan.2013 * Add simple decoder demo that only uses libgstvaapi * Fix thread-safety issues in the Wayland renderer * Fix VC-1 decoding bugs #692461, #692312, #692271, #692270, #692267 diff --git a/configure.ac b/configure.ac index 102e642c4e..9d8f0fac72 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 1568922c1c1b69574142ccfd6ebd56b491cf0bd9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jan 2013 09:38:07 +0100 Subject: [PATCH 1071/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 9d8f0fac72..4e2226a69e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [2]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 0847b3888d42b3680c43d06cba84d69e67fb3c3b Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 24 Jan 2013 00:49:17 +0200 Subject: [PATCH 1072/3781] vaapidecode: add support for post-seek semantics reset. Implement GstVideoDecoder::reset() as a destruction of the VA decoder and the creation of a new VA decoder. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 45f1b8e741..c7a353bac0 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -391,12 +391,18 @@ gst_vaapidecode_destroy(GstVaapiDecode *decode) } static gboolean -gst_vaapidecode_reset(GstVaapiDecode *decode, GstCaps *caps) +gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) { GstVaapiCodec codec; + /* Reset timers if hard reset was requested (e.g. seek) */ + if (hard) { + decode->render_time_base = 0; + decode->last_buffer_time = 0; + } + /* Only reset decoder if codec type changed */ - if (decode->decoder && decode->decoder_caps) { + else if (decode->decoder && decode->decoder_caps) { if (gst_caps_is_always_compatible(caps, decode->decoder_caps)) return TRUE; codec = gst_vaapi_codec_from_caps(caps); @@ -480,6 +486,14 @@ gst_vaapidecode_close(GstVideoDecoder *vdec) return TRUE; } +static gboolean +gst_vaapidecode_reset(GstVideoDecoder *vdec, gboolean hard) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + + return gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, hard); +} + static gboolean gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) { @@ -489,7 +503,7 @@ gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) return FALSE; if (!gst_vaapidecode_update_src_caps(decode, state)) return FALSE; - if (!gst_vaapidecode_reset(decode, decode->sinkpad_caps)) + if (!gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, FALSE)) return FALSE; return TRUE; } @@ -549,6 +563,7 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) vdec_class->open = GST_DEBUG_FUNCPTR(gst_vaapidecode_open); vdec_class->close = GST_DEBUG_FUNCPTR(gst_vaapidecode_close); vdec_class->set_format = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_format); + vdec_class->reset = GST_DEBUG_FUNCPTR(gst_vaapidecode_reset); vdec_class->parse = GST_DEBUG_FUNCPTR(gst_vaapidecode_parse); vdec_class->handle_frame = GST_DEBUG_FUNCPTR(gst_vaapidecode_handle_frame); vdec_class->finish = GST_DEBUG_FUNCPTR(gst_vaapidecode_finish); From 41dcd82e2f5747113bd90acea6034fb2d613536f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jan 2013 16:26:07 +0100 Subject: [PATCH 1073/3781] vaapidecode: handle decode-only frames. Decode-only frames may not have a valid surface proxy. So, simply discard them gracefully, i.e. don't create meta data information. GstVideoDecoder base class will properly handle this case and won't try to push any buffer to downstream elements. --- gst/vaapi/gstvaapidecode.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index c7a353bac0..545a604be9 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -252,21 +252,24 @@ gst_vaapidecode_push_decoded_frames(GstVideoDecoder *vdec) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return GST_FLOW_OK; - proxy = gst_video_codec_frame_get_user_data(out_frame); + if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(out_frame)) { + proxy = gst_video_codec_frame_get_user_data(out_frame); - gst_vaapi_surface_proxy_set_user_data(proxy, - decode, (GDestroyNotify)gst_vaapidecode_release); + gst_vaapi_surface_proxy_set_user_data(proxy, + decode, (GDestroyNotify)gst_vaapidecode_release); - out_frame->output_buffer = - gst_vaapi_video_buffer_new_with_surface_proxy(proxy); - if (!out_frame->output_buffer) - goto error_create_buffer; + out_frame->output_buffer = + gst_vaapi_video_buffer_new_with_surface_proxy(proxy); + if (!out_frame->output_buffer) + goto error_create_buffer; + } ret = gst_video_decoder_finish_frame(vdec, out_frame); if (ret != GST_FLOW_OK) goto error_commit_buffer; - decode->last_buffer_time = out_frame->pts; + if (GST_CLOCK_TIME_IS_VALID(out_frame->pts)) + decode->last_buffer_time = out_frame->pts; gst_video_codec_frame_unref(out_frame); }; return GST_FLOW_OK; From 2305b0db461753c756fe60b4ad60d5497f642ab0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jan 2013 16:33:48 +0100 Subject: [PATCH 1074/3781] decoder: allow frames to be dropped. If the decoder was not able to decode a frame because insufficient information was available, e.g. missing sequence or picture header, then allow the frame to be gracefully dropped without generating any error. It is also possible that a frame is not meant to be displayed but only used as a reference, so dropping that frame is also a valid operation since GstVideoDecoder base class has extra references to that GstVideoCodecFrame that needs to be released. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 31 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 4 +++ 2 files changed, 35 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 97baec2d1b..1f346e682e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -48,6 +48,9 @@ enum { static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; +static void +drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame); + static void parser_state_finalize(GstVaapiParserState *ps) { @@ -246,6 +249,10 @@ do_decode_1(GstVaapiDecoder *decoder, GstVaapiDecoderFrame *frame) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; } + + /* Drop frame if there is no slice data unit in there */ + if (G_UNLIKELY(frame->units->len == 0)) + return GST_VAAPI_DECODER_STATUS_DROP_FRAME; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -261,6 +268,13 @@ do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) gst_vaapi_decoder_frame_ref(frame); status = do_decode_1(decoder, frame); gst_vaapi_decoder_frame_unref(frame); + + switch ((guint)status) { + case GST_VAAPI_DECODER_STATUS_DROP_FRAME: + drop_frame(decoder, base_frame); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } return status; } @@ -351,6 +365,23 @@ decode_step(GstVaapiDecoder *decoder) return status; } +static void +drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) +{ + GstVaapiDecoderPrivate * const priv = decoder->priv; + + GST_DEBUG("drop frame %d", frame->system_frame_number); + + /* no surface proxy */ + gst_video_codec_frame_set_user_data(frame, NULL, NULL); + + frame->pts = GST_CLOCK_TIME_NONE; + GST_VIDEO_CODEC_FRAME_FLAG_SET(frame, + GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); + + g_queue_push_tail(priv->frames, gst_video_codec_frame_ref(frame)); +} + static inline void push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) { diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 9b0867d4ab..bb4e02ba08 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -145,6 +145,10 @@ G_BEGIN_DECLS GST_VAAPI_TYPE_DECODER, \ GstVaapiDecoderPrivate)) +typedef enum { + GST_VAAPI_DECODER_STATUS_DROP_FRAME = -2 +} GstVaapiDecoderStatusPrivate; + typedef struct _GstVaapiParserState GstVaapiParserState; struct _GstVaapiParserState { GstVideoCodecFrame *current_frame; From 4499f39274b93a9987684f254d2cb0b60cf11659 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jan 2013 18:58:01 +0100 Subject: [PATCH 1075/3781] decoder: handle decode-only frames in raw API mode. Fix gst_vaapi_decoder_get_surface() to only return frames with a valid surface proxy, i.e. with a valid VA surface. This means that any frame marked as decode-only is simply skipped. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 1f346e682e..3f6577fb10 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -697,10 +697,14 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, do { frame = pop_frame(decoder); - if (frame) { - *out_proxy_ptr = gst_vaapi_surface_proxy_ref(frame->user_data); + while (frame) { + if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(frame)) { + *out_proxy_ptr = gst_vaapi_surface_proxy_ref(frame->user_data); + gst_video_codec_frame_unref(frame); + return GST_VAAPI_DECODER_STATUS_SUCCESS; + } gst_video_codec_frame_unref(frame); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + frame = pop_frame(decoder); } status = decode_step(decoder); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); From 23b2386fd0df6f16166f9e6855950da4e0adfef6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jan 2013 15:10:06 +0100 Subject: [PATCH 1076/3781] mpeg2: improve robustness when packets are missing. Improve robustness when some expected packets where not received yet or that were not correctly decoded. For example, don't try to decode a picture if there was no valid sequence or picture headers. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 94 ++++++++++++++++++---- 1 file changed, 78 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 575af43d9a..88a48405a4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -327,6 +327,25 @@ G_DEFINE_TYPE(GstVaapiDecoderMpeg2, GST_VAAPI_TYPE_DECODER_MPEG2, \ GstVaapiDecoderMpeg2Private)) +typedef enum { + GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR = 1 << 0, + GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT = 1 << 1, + GST_MPEG_VIDEO_STATE_GOT_PIC_HDR = 1 << 2, + GST_MPEG_VIDEO_STATE_GOT_PIC_EXT = 1 << 3, + GST_MPEG_VIDEO_STATE_GOT_SLICE = 1 << 4, + + GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS = ( + GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| + GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT), + GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS = ( + GST_MPEG_VIDEO_STATE_GOT_PIC_HDR| + GST_MPEG_VIDEO_STATE_GOT_PIC_EXT), + GST_MPEG_VIDEO_STATE_VALID_PICTURE = ( + GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS| + GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS| + GST_MPEG_VIDEO_STATE_GOT_SLICE) +} GstMpegVideoState; + struct _GstVaapiDecoderMpeg2Private { GstVaapiProfile profile; GstVaapiProfile hw_profile; @@ -334,6 +353,7 @@ struct _GstVaapiDecoderMpeg2Private { guint height; guint fps_n; guint fps_d; + guint state; GstVaapiParserInfoMpeg2 *seq_hdr; GstVaapiParserInfoMpeg2 *seq_ext; GstVaapiParserInfoMpeg2 *seq_display_ext; @@ -569,12 +589,24 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static inline gboolean +is_valid_state(GstVaapiDecoderMpeg2 *decoder, guint state) +{ + GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + + return (priv->state & state) == state; +} + static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderMpeg2 *decoder) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstVaapiPicture * const picture = priv->current_picture; + if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PICTURE)) + goto drop_frame; + priv->state &= GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS; + if (!picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -591,6 +623,10 @@ 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; + +drop_frame: + priv->state &= GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS; + return GST_VAAPI_DECODER_STATUS_DROP_FRAME; } static GstVaapiDecoderStatus @@ -600,6 +636,8 @@ parse_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoSequenceHdr *seq_hdr; + priv->state = 0; + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_hdr)) { GST_ERROR("failed to allocate parser info for sequence header"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -637,6 +675,8 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) priv->size_changed = TRUE; priv->quant_matrix_changed = TRUE; priv->progressive_sequence = TRUE; + + priv->state |= GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -647,6 +687,8 @@ parse_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoSequenceExt *seq_ext; + priv->state &= GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR; + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_ext)) { GST_ERROR("failed to allocate parser info for sequence extension"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -673,6 +715,9 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) GstVaapiProfile profile; guint width, height; + if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR)) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + priv->progressive_sequence = seq_ext->progressive; gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence); @@ -715,6 +760,8 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) priv->profile = profile; priv->profile_changed = TRUE; } + + priv->state |= GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -846,6 +893,9 @@ parse_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoPictureHdr *pic_hdr; + priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| + GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT); + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->pic_hdr)) { GST_ERROR("failed to allocate parser info for picture header"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -868,7 +918,12 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS)) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, NULL); + + priv->state |= GST_MPEG_VIDEO_STATE_GOT_PIC_HDR; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -879,6 +934,10 @@ parse_picture_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoPictureExt *pic_ext; + priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| + GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT| + GST_MPEG_VIDEO_STATE_GOT_PIC_HDR); + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->pic_ext)) { GST_ERROR("failed to allocate parser info for picture extension"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -902,6 +961,9 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoPictureExt * const pic_ext = unit->parsed_info; + if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_GOT_PIC_HDR)) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (priv->progressive_sequence && !pic_ext->progressive_frame) { GST_WARNING("invalid interlaced frame in progressive sequence, fixing"); pic_ext->progressive_frame = 1; @@ -914,6 +976,8 @@ decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) pic_ext->picture_structure); pic_ext->picture_structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME; } + + priv->state |= GST_MPEG_VIDEO_STATE_GOT_PIC_EXT; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1071,6 +1135,11 @@ parse_slice(GstVaapiDecoderMpeg2 *decoder, guint8 slice_vertical_position_extension; guint8 extra_bit_slice, junk8; + priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| + GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT| + GST_MPEG_VIDEO_STATE_GOT_PIC_HDR| + GST_MPEG_VIDEO_STATE_GOT_PIC_EXT); + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->slice_hdr)) { GST_ERROR("failed to allocate parser info for slice header"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -1133,6 +1202,9 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) GST_DEBUG("slice %d (%u bytes)", slice_hdr->slice_vertical_position, unit->size); + if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) + unit->offset), unit->size); @@ -1149,6 +1221,8 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) slice_param->slice_vertical_position = slice_hdr->slice_vertical_position; slice_param->quantiser_scale_code = slice_hdr->quantiser_scale_code; slice_param->intra_slice_flag = slice_hdr->intra_slice; + + priv->state |= GST_MPEG_VIDEO_STATE_GOT_SLICE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1232,7 +1306,6 @@ static GstVaapiDecoderStatus decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstMpegVideoPacketTypeCode type; GstMpegVideoPacketExtensionCode ext_type; GstVaapiDecoderStatus status; @@ -1240,8 +1313,6 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, type = packet->type; switch (type) { case GST_MPEG_VIDEO_PACKET_PICTURE: - if (!priv->width || !priv->height) - goto unknown_picture_size; status = decode_picture(decoder, unit); break; case GST_MPEG_VIDEO_PACKET_SEQUENCE: @@ -1260,8 +1331,6 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, status = decode_quant_matrix_ext(decoder, unit); break; case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: - if (!priv->width || !priv->height) - goto unknown_picture_size; status = decode_picture_ext(decoder, unit); break; default: @@ -1288,12 +1357,6 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, break; } return status; - -unknown_picture_size: - // Ignore packet while picture size is undefined - // i.e. missing sequence headers, or not parsed correctly - GST_WARNING("failed to parse picture of unknown size"); - return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus @@ -1445,12 +1508,9 @@ gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder, GstVaapiPicture *picture; GstVaapiDecoderStatus status; - if (!priv->width || !priv->height) { - // Ignore packet while picture size is undefined - // i.e. missing sequence headers, or not parsed correctly - GST_WARNING("failed to decode picture of unknown size"); + if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) return GST_VAAPI_DECODER_STATUS_SUCCESS; - } + priv->state &= ~GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS; seq_hdr = &priv->seq_hdr->data.seq_hdr; seq_ext = priv->seq_ext ? &priv->seq_ext->data.seq_ext : NULL; @@ -1497,6 +1557,8 @@ gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder, return status; fill_picture(decoder, picture); + + priv->state |= GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS; return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 564ca5d2213d21e439f08867cfa40684963d513b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jan 2013 18:54:13 +0100 Subject: [PATCH 1077/3781] mpeg2: fix decoding of sequence_end(). There shall be only one place to call decode_current_picture(), and this is in the end_frame() hook. The EOS unit is processed after end_frame() so this means we cannot have a valid picture to decode/output at this point. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 88a48405a4..540e5ee2dc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -801,11 +801,6 @@ static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GstVaapiDecoderStatus status; - - status = decode_current_picture(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; gst_vaapi_dpb_flush(priv->dpb); return GST_VAAPI_DECODER_STATUS_SUCCESS; From 06725d651e6229659c8322f9658fbf88acb2c64f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jan 2013 18:38:38 +0100 Subject: [PATCH 1078/3781] mpeg2: fix decoding of 4K videos. Account for slice_vertical_position_extension when vertical_size > 2800. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 540e5ee2dc..c889e9a497 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1127,7 +1127,7 @@ parse_slice(GstVaapiDecoderMpeg2 *decoder, GstMpegVideoSliceHdr *slice_hdr; GstBitReader br; gint mb_x, mb_y, mb_inc; - guint8 slice_vertical_position_extension; + guint8 slice_vertical_position_extension = 0; guint8 extra_bit_slice, junk8; priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| @@ -1164,7 +1164,8 @@ parse_slice(GstVaapiDecoderMpeg2 *decoder, } slice_hdr->header_size = 32 + gst_bit_reader_get_pos(&br); - mb_y = packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN; + mb_y = ((guint)slice_vertical_position_extension << 7) + + packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN; mb_x = -1; do { if (!decode_vlc(&br, &mb_inc, mpeg2_mbaddr_vlc_table, From 20a81f5a708308960e98b571e464e1f1060714e9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 31 Jan 2013 11:25:18 +0100 Subject: [PATCH 1079/3781] glibcompat: add replacement for g_cond_wait(). --- gst-libs/gst/vaapi/glibcompat.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 6c1f8f4e7a..6c9a8aa1dc 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -89,6 +89,8 @@ G_COMPAT_DEFINE(g_compat_cond_signal, (GCompatCond *cond), g_cond_signal, (*cond)) G_COMPAT_DEFINE(g_compat_cond_broadcast, (GCompatCond *cond), g_cond_broadcast, (*cond)) +G_COMPAT_DEFINE(g_compat_cond_wait, (GCompatCond *cond, GCompatMutex *mutex), + g_cond_wait, (*cond, g_static_mutex_get_mutex(mutex))) static inline gboolean g_cond_wait_until(GCompatCond *cond, GStaticMutex *mutex, gint64 end_time) @@ -129,6 +131,8 @@ g_cond_wait_until(GCompatCond *cond, GStaticMutex *mutex, gint64 end_time) #define g_cond_clear(cond) g_compat_cond_clear(cond) #undef g_cond_signal #define g_cond_signal(cond) g_compat_cond_signal(cond) +#undef g_cond_wait +#define g_cond_wait(cond, mutex) g_compat_cond_wait(cond, mutex) #endif #undef G_COMPAT_DEFINE From 56bc1ce98c8e529baabadc0df4644818d0d3c91d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 31 Jan 2013 11:30:12 +0100 Subject: [PATCH 1080/3781] glibcompat: add replacement for g_async_queue_timeout_pop(). g_async_queue_timeout_pop() appeared in glib 2.31.18. Implement it as g_async_queue_timed_pop() with a GTimeVal as the final time to wait for new data to arrive in the queue. --- gst-libs/gst/vaapi/glibcompat.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 6c9a8aa1dc..24057f82f5 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -135,6 +135,18 @@ g_cond_wait_until(GCompatCond *cond, GStaticMutex *mutex, gint64 end_time) #define g_cond_wait(cond, mutex) g_compat_cond_wait(cond, mutex) #endif +#if !GLIB_CHECK_VERSION(2,31,18) +static inline gpointer +g_async_queue_timeout_pop(GAsyncQueue *queue, guint64 timeout) +{ + GTimeVal end_time; + + g_get_current_time(&end_time); + g_time_val_add(&end_time, timeout); + return g_async_queue_timed_pop(queue, &end_time); +} +#endif + #undef G_COMPAT_DEFINE #endif /* GLIB_COMPAT_H */ From 6e04081a13849672229c40031ecfb4eecfbf134e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 31 Jan 2013 11:32:24 +0100 Subject: [PATCH 1081/3781] tests: simple-decoder: fix build on older platforms. Make simple-decoder build and execute correctly on older platforms, and more precisely older versions of glib. --- tests/simple-decoder.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index e6c47387ad..de299b4e34 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -25,7 +25,7 @@ * the application. */ -#include "config.h" +#include "gst/vaapi/sysdeps.h" #include #include #include @@ -629,11 +629,6 @@ app_check_events(App *app) static gboolean app_run(App *app, int argc, char *argv[]) { - if (!video_output_init(&argc, argv, g_options)) { - g_message("failed to initialize video output subsystem"); - return FALSE; - } - if (argc < 2) { g_message("no bitstream file specified"); return FALSE; @@ -693,8 +688,6 @@ app_run(App *app, int argc, char *argv[]) elapsed, (gdouble)app->num_frames / elapsed); } g_print("\n"); - - video_output_exit(); return TRUE; } @@ -704,6 +697,9 @@ main(int argc, char *argv[]) App *app; gint ret; + if (!video_output_init(&argc, argv, g_options)) + g_error("failed to initialize video output subsystem"); + app = app_new(); if (!app) g_error("failed to create application context"); @@ -712,5 +708,6 @@ main(int argc, char *argv[]) app_free(app); g_free(g_codec_str); + video_output_exit(); return ret; } From 46fdbcd15043483184ae3c144b49eb6e84f6ee74 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 6 Feb 2013 15:21:27 +0100 Subject: [PATCH 1082/3781] codecparsers: update to gst-vaapi-branch commit 31b1c57. 8957fb7 mpeg2: add helpers to convert quantization matrices 07c4034 mpeg2: store quantization matrices in zigzag scan order --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 21a098e462..31b1c57d44 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 21a098e46204048fe4daf190655f76ea9c6bb76e +Subproject commit 31b1c57d44ac1228e4bfede2a924eb8d5f8e76fc From ad925b30a6f4e5246f0f5dd6dd7467aaec3494cd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 6 Feb 2013 15:27:18 +0100 Subject: [PATCH 1083/3781] NEWS: updates. --- NEWS | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index df2c09ea05..50fc0c00f5 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,15 @@ -gst-vaapi NEWS -- summary of changes. 2013-01-29 +gst-vaapi NEWS -- summary of changes. 2013-02-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora +Version 0.5.2 - DD.Feb.2013 +* Add support for video seek/reset (+Sreerenj Balachandran) +* Improve MPEG-2 decoder robustness when packets are missing +* Fix build on older Linux distributions with glib < 2.32 +* Fix decoding of MPEG-2 videos with height > 2800 pixels +* Fix MPEG-2 decoding with explicit quantization matrices set (Cong Zhong) + Version 0.5.1 - 29.Jan.2013 * Add simple decoder demo that only uses libgstvaapi * Fix thread-safety issues in the Wayland renderer From ed6ad0be26d209d6069dbfc034ffd63fb6534c86 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 7 Feb 2013 15:29:44 +0100 Subject: [PATCH 1084/3781] codecparsers: update to gst-vaapi-branch commit 500bc02. 500bc02 h264: add profile enums --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 31b1c57d44..500bc02db4 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 31b1c57d44ac1228e4bfede2a924eb8d5f8e76fc +Subproject commit 500bc02db4c55727d81d153da4e378d2420bedd8 From 0c3650e7e8fb394e290294f5d6e8b4360321f858 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 7 Feb 2013 15:42:55 +0100 Subject: [PATCH 1085/3781] h264: use new profile definitions from codecparsers. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index db180965ec..0a20335e22 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -438,11 +438,11 @@ get_max_dec_frame_buffering(GstH264SPS *sps) else { switch (sps->profile_idc) { case 44: // CAVLC 4:4:4 Intra profile - case 86: // Scalable High profile - case 100: // High profile - case 110: // High 10 profile - case 122: // High 4:2:2 profile - case 244: // High 4:4:4 Predictive profile + case GST_H264_PROFILE_SCALABLE_HIGH: + case GST_H264_PROFILE_HIGH: + case GST_H264_PROFILE_HIGH10: + case GST_H264_PROFILE_HIGH_422: + case GST_H264_PROFILE_HIGH_444: if (sps->constraint_set3_flag) max_dec_frame_buffering = 0; break; @@ -744,13 +744,13 @@ h264_get_profile(GstH264SPS *sps) guint profile = 0; switch (sps->profile_idc) { - case 66: + case GST_H264_PROFILE_BASELINE: profile = GST_VAAPI_PROFILE_H264_BASELINE; break; - case 77: + case GST_H264_PROFILE_MAIN: profile = GST_VAAPI_PROFILE_H264_MAIN; break; - case 100: + case GST_H264_PROFILE_HIGH: profile = GST_VAAPI_PROFILE_H264_HIGH; break; } From ddaaa4202029ddbc04f01302e366f10a35f87087 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 8 Feb 2013 11:56:54 +0100 Subject: [PATCH 1086/3781] h264: set {luma,chroma}_log2_weight_denom to 0 if no pred_weight_table(). Force luma_log2_weight_denom and chroma_log2_weight_denom to zero if there is no pred_weight_table() that was parsed. This is a workaround for the VA intel-driver on Ivy Bridge. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 0a20335e22..bd318d7684 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2574,8 +2574,8 @@ fill_pred_weight_table(GstVaapiDecoderH264 *decoder, else num_weight_tables = 0; - slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom; - slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom; + slice_param->luma_log2_weight_denom = 0; + slice_param->chroma_log2_weight_denom = 0; slice_param->luma_weight_l0_flag = 0; slice_param->chroma_weight_l0_flag = 0; slice_param->luma_weight_l1_flag = 0; @@ -2584,6 +2584,9 @@ fill_pred_weight_table(GstVaapiDecoderH264 *decoder, if (num_weight_tables < 1) return TRUE; + slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom; + slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom; + slice_param->luma_weight_l0_flag = 1; for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { slice_param->luma_weight_l0[i] = w->luma_weight_l0[i]; From bd3aa01de5438b736bd37c2ecb154e19fbbce773 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Sun, 17 Feb 2013 16:28:47 +0800 Subject: [PATCH 1087/3781] build: fix compiling of local GstVideoDecoder and codecparsers. Generated source files were missing a dependency on the complete set of generated header files. e.g. gstvideodecoder.c requires gstvideoutils.h to build and almost every codec parser source depends on parserutils.h. https://bugs.freedesktop.org/show_bug.cgi?id=59575 Signed-off-by: Xiang, Haihao Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/codecparsers/Makefile.am | 2 +- gst-libs/gst/video/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 8df6533582..a09a8fd4e1 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -68,7 +68,7 @@ all-local: .timestamp.symlinks .timestamp.symlinks: $(GENFILES) touch $@ -$(gen_source_c): %.c: $(local_codecparsers_srcdir)/%.c %.h +$(gen_source_c): %.c: $(local_codecparsers_srcdir)/%.c $(gen_source_h) $(LN_S) -f $< $@ $(gen_source_h): %.h: $(local_codecparsers_srcdir)/%.h $(LN_S) -f $< $@ diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index f6504f7f33..a790e87798 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -54,7 +54,7 @@ all-local: .timestamp.symlinks .timestamp.symlinks: $(GENFILES) touch $@ -$(gen_source_c): %.c: $(local_videoutils_srcdir)/%.c %.h +$(gen_source_c): %.c: $(local_videoutils_srcdir)/%.c $(gen_source_h) $(LN_S) -f $< $@ $(gen_source_h): %.h: $(local_videoutils_srcdir)/%.h $(LN_S) -f $< $@ From 9bf1ae04ccdc3de04a3c694b573c90266a59bea6 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Tue, 26 Feb 2013 00:38:24 +0100 Subject: [PATCH 1088/3781] vaapiupload: fix illegal write in ensure_image(). Fix ensure_image() to only zero-initialize the first line of each plane. Properly initializing each plane to their full vertical resolution would require to actually compute it based on the image format. In particular, for NV12 images, the UV plane has half vertical resolution vs. the Y plane. So using the full image height to initialize the UV plane will obviously lead to a buffer overflow. Likewise for other YUV format. Since ensure_image() is only a helper function to initialize something, and not necessarily the whole thing, it is fine to initializ the first line only. Besides, the target surface is not rendered either. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapiuploader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 460435e54a..437f6af489 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -108,7 +108,7 @@ ensure_image(GstVaapiImage *image) for (i = 0; i < num_planes; i++) { guchar * const plane = gst_vaapi_image_get_plane(image, i); if (plane) - memset(plane, 0, height * gst_vaapi_image_get_pitch(image, i)); + memset(plane, 0, gst_vaapi_image_get_pitch(image, i)); } if (!gst_vaapi_image_unmap(image)) From 127f544fbba3049efbff5cdb2325ff5e1b5b6428 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 11:28:06 +0100 Subject: [PATCH 1089/3781] configure: improve check for H.264 codecparser. --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 4e2226a69e..41e7655a58 100644 --- a/configure.ac +++ b/configure.ac @@ -314,6 +314,7 @@ AC_CACHE_CHECK([for H.264 parser], [[#include ]], [[GstH264SliceHdr slice_hdr; GstH264VUIParams vui_params; + GstH264Profile profile = GST_H264_PROFILE_HIGH; slice_hdr.n_emulation_prevention_bytes = 0; vui_params.par_n = 0; vui_params.par_d = 0;]])], From 4dd6035dace482f974eef87333dbceead9ab8d14 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 11:44:10 +0100 Subject: [PATCH 1090/3781] configure: rename GST_MAJORMINOR to GST_API_VERSION. --- configure.ac | 75 ++++++----------- debian.upstream/Makefile.am | 4 +- debian.upstream/changelog.in | 2 +- debian.upstream/control.in | 18 ++-- .../gstreamer-vaapi-doc.install.in | 2 +- debian.upstream/libgstvaapi-dev.install.in | 2 +- debian.upstream/libgstvaapi-drm.install.in | 2 +- debian.upstream/libgstvaapi-glx.install.in | 2 +- .../libgstvaapi-wayland.install.in | 2 +- debian.upstream/libgstvaapi-x11.install.in | 2 +- debian.upstream/libgstvaapi.install.in | 2 +- docs/reference/libs/Makefile.am | 6 +- docs/reference/libs/libs-docs.xml.in | 2 +- docs/reference/plugins/Makefile.am | 4 +- docs/reference/plugins/plugins-docs.xml.in | 2 +- gst-libs/gst/vaapi/Makefile.am | 82 +++++++++---------- gst/vaapi/Makefile.am | 8 +- pkgconfig/Makefile.am | 4 +- pkgconfig/gstreamer-vaapi-drm.pc.in | 8 +- pkgconfig/gstreamer-vaapi-glx.pc.in | 8 +- pkgconfig/gstreamer-vaapi-wayland.pc.in | 8 +- pkgconfig/gstreamer-vaapi-x11.pc.in | 8 +- pkgconfig/gstreamer-vaapi.pc.in | 8 +- tests/Makefile.am | 10 +-- 24 files changed, 123 insertions(+), 148 deletions(-) diff --git a/configure.ac b/configure.ac index 41e7655a58..f1d517e709 100644 --- a/configure.ac +++ b/configure.ac @@ -15,36 +15,13 @@ m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [0]) # glib version number -m4_define([glib_major_version], [2]) -m4_define([glib_minor_version], [28]) -m4_define([glib_micro_version], [0]) -m4_define([glib_major_minor_version], - [glib_major_version.glib_minor_version]) -m4_define([glib_version], - [glib_major_version.glib_minor_version.glib_micro_version]) +m4_define([glib_version], [2.28]) -# gst version number -m4_define([gst_major_version], [0]) -m4_define([gst_minor_version], [10]) -m4_define([gst_micro_version], [36]) -m4_define([gst_major_minor_version], - [gst_major_version.gst_minor_version]) -m4_define([gst_version], - [gst_major_version.gst_minor_version.gst_micro_version]) - -# gst plugins-base version number -m4_define([gst_plugins_base_major_version], [0]) -m4_define([gst_plugins_base_minor_version], [10]) -m4_define([gst_plugins_base_micro_version], [31]) -m4_define([gst_plugins_base_version], - [gst_plugins_base_major_version.gst_plugins_base_minor_version.gst_plugins_base_micro_version]) - -# gst plugins-bad version number -m4_define([gst_plugins_bad_major_version], [0]) -m4_define([gst_plugins_bad_minor_version], [10]) -m4_define([gst_plugins_bad_micro_version], [22]) -m4_define([gst_plugins_bad_version], - [gst_plugins_bad_major_version.gst_plugins_bad_minor_version.gst_plugins_bad_micro_version]) +# gstreamer version number +m4_define([gst_api_version], [0.10]) +m4_define([gst_version], [0.10.36]) +m4_define([gst_plugins_base_version], [0.10.31]) +m4_define([gst_plugins_bad_version], [0.10.22]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.0]) @@ -64,9 +41,7 @@ m4_define([libva_wld_package_version], [1.1.0]) # gtk-doc version number # XXX: introspection annotations require gtk-doc >= 1.12 -m4_define([gtkdoc_major_version], [1]) -m4_define([gtkdoc_minor_version], [9]) -m4_define([gtkdoc_version], [gtkdoc_major_version.gtkdoc_minor_version]) +m4_define([gtkdoc_version], [1.9]) AC_PREREQ([2.58]) AC_INIT([gst_vaapi], [gst_vaapi_version], @@ -95,11 +70,11 @@ WAYLAND_API_VERSION=wayland_api_version AC_SUBST(WAYLAND_API_VERSION) dnl Versions for GStreamer and plugins-base -GST_MAJORMINOR=gst_major_minor_version +GST_API_VERSION=gst_api_version GST_VERSION_REQUIRED=gst_version GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst_plugins_bad_version -AC_SUBST(GST_MAJORMINOR) +AC_SUBST(GST_API_VERSION) AC_SUBST(GST_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED) @@ -163,8 +138,8 @@ dnl -- GStreamer -- dnl --------------------------------------------------------------------------- dnl GStreamer Core -PKG_CHECK_MODULES([GST], [gstreamer-$GST_MAJORMINOR >= gst_version]) -PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-$GST_MAJORMINOR >= gst_version]) +PKG_CHECK_MODULES([GST], [gstreamer-$GST_API_VERSION >= gst_version]) +PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-$GST_API_VERSION >= gst_version]) AC_CACHE_CHECK([for GstBaseSink::query hook], ac_cv_have_gst_base_sink_query, [ saved_CPPFLAGS="$CPPFLAGS" @@ -187,13 +162,13 @@ fi dnl GStreamer -base plugins PKG_CHECK_MODULES([GST_PLUGINS_BASE], - [gstreamer-plugins-base-$GST_MAJORMINOR >= gst_plugins_base_version]) + [gstreamer-plugins-base-$GST_API_VERSION >= gst_plugins_base_version]) PKG_CHECK_MODULES([GST_INTERFACES], - [gstreamer-interfaces-$GST_MAJORMINOR >= gst_plugins_base_version]) + [gstreamer-interfaces-$GST_API_VERSION >= gst_plugins_base_version]) dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], - [gstreamer-video-$GST_MAJORMINOR >= gst_plugins_base_version]) + [gstreamer-video-$GST_API_VERSION >= gst_plugins_base_version]) AC_CACHE_CHECK([for GstVideoOverlayComposition], ac_cv_have_gst_video_overlay_composition, [ @@ -272,11 +247,11 @@ AM_CONDITIONAL([USE_LOCAL_GST_VIDEO_DECODER], dnl GStreamer -bad plugins PKG_CHECK_MODULES([GST_BASEVIDEO], - [gstreamer-basevideo-$GST_MAJORMINOR >= gst_plugins_bad_version]) + [gstreamer-basevideo-$GST_API_VERSION >= gst_plugins_bad_version]) dnl ... bitstream parsers PKG_CHECK_MODULES([GST_CODEC_PARSERS], - [gstreamer-codecparsers-$GST_MAJORMINOR >= gst_plugins_bad_version]) + [gstreamer-codecparsers-$GST_API_VERSION >= gst_plugins_bad_version]) dnl ... MPEG-2 parser, with the required extensions AC_CACHE_CHECK([for MPEG-2 parser], @@ -374,9 +349,9 @@ AC_MSG_CHECKING([for GStreamer plugins directory]) if test -d "$GST_PLUGIN_PATH"; then GST_PLUGINS_DIR="$GST_PLUGIN_PATH" else - GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_MAJORMINOR --variable pluginsdir` + GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_API_VERSION --variable pluginsdir` if test -z "$GST_PLUGINS_DIR"; then - GST_PLUGINS_DIR="\$(libdir)/gstreamer-$GST_MAJORMINOR" + GST_PLUGINS_DIR="\$(libdir)/gstreamer-$GST_API_VERSION" fi fi AC_MSG_RESULT([$GST_PLUGINS_DIR]) @@ -604,9 +579,9 @@ AC_CONFIG_FILES([ debian.upstream/Makefile debian.upstream/changelog debian.upstream/control - debian.upstream/gstreamer$GST_MAJORMINOR-vaapi-doc.install:\ + debian.upstream/gstreamer$GST_API_VERSION-vaapi-doc.install:\ debian.upstream/gstreamer-vaapi-doc.install.in - debian.upstream/gstreamer$GST_MAJORMINOR-vaapi.install:\ + debian.upstream/gstreamer$GST_API_VERSION-vaapi.install:\ debian.upstream/gstreamer-vaapi.install.in debian.upstream/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi.install.in @@ -634,15 +609,15 @@ debian.upstream/libgstvaapi-x11.install.in gst/Makefile gst/vaapi/Makefile pkgconfig/Makefile - pkgconfig/gstreamer-vaapi-$GST_MAJORMINOR.pc:\ + pkgconfig/gstreamer-vaapi-$GST_API_VERSION.pc:\ pkgconfig/gstreamer-vaapi.pc.in - pkgconfig/gstreamer-vaapi-drm-$GST_MAJORMINOR.pc:\ + pkgconfig/gstreamer-vaapi-drm-$GST_API_VERSION.pc:\ pkgconfig/gstreamer-vaapi-drm.pc.in - pkgconfig/gstreamer-vaapi-glx-$GST_MAJORMINOR.pc:\ + pkgconfig/gstreamer-vaapi-glx-$GST_API_VERSION.pc:\ pkgconfig/gstreamer-vaapi-glx.pc.in - pkgconfig/gstreamer-vaapi-wayland-$GST_MAJORMINOR.pc:\ + pkgconfig/gstreamer-vaapi-wayland-$GST_API_VERSION.pc:\ pkgconfig/gstreamer-vaapi-wayland.pc.in - pkgconfig/gstreamer-vaapi-x11-$GST_MAJORMINOR.pc:\ + pkgconfig/gstreamer-vaapi-x11-$GST_API_VERSION.pc:\ pkgconfig/gstreamer-vaapi-x11.pc.in tests/Makefile ]) diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index eba85db789..f7e33496ff 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -24,8 +24,8 @@ DEBIANFILES = \ DEBIANGENFILES = \ changelog \ control \ - gstreamer$(GST_MAJORMINOR)-vaapi-doc.install \ - gstreamer$(GST_MAJORMINOR)-vaapi.install \ + gstreamer$(GST_API_VERSION)-vaapi-doc.install \ + gstreamer$(GST_API_VERSION)-vaapi.install \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-dev.install \ libgstvaapi-drm-$(GST_VAAPI_MAJOR_VERSION).install \ diff --git a/debian.upstream/changelog.in b/debian.upstream/changelog.in index 92f9d3dea3..e84ef3e430 100644 --- a/debian.upstream/changelog.in +++ b/debian.upstream/changelog.in @@ -1,4 +1,4 @@ -gstreamer@GST_MAJORMINOR@-vaapi (@PACKAGE_VERSION@-1) unstable; urgency=low +gstreamer@GST_API_VERSION@-vaapi (@PACKAGE_VERSION@-1) unstable; urgency=low * Autogenerated package, see NEWS file for ChangeLog. diff --git a/debian.upstream/control.in b/debian.upstream/control.in index e89a657a16..cd51abc431 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -1,13 +1,13 @@ -Source: gstreamer@GST_MAJORMINOR@-vaapi +Source: gstreamer@GST_API_VERSION@-vaapi Section: libs Priority: optional Maintainer: Gwenole Beauchesne Build-Depends: debhelper (>= 5), cdbs, libglib2.0-dev (>= @GLIB_VERSION_REQUIRED@), - libgstreamer@GST_MAJORMINOR@-dev (>= @GST_VERSION_REQUIRED@), - libgstreamer-plugins-base@GST_MAJORMINOR@-dev (>= @GST_PLUGINS_BASE_VERSION_REQUIRED@), - libgstreamer-plugins-bad@GST_MAJORMINOR@-dev (>= @GST_PLUGINS_BAD_VERSION_REQUIRED@), + libgstreamer@GST_API_VERSION@-dev (>= @GST_VERSION_REQUIRED@), + libgstreamer-plugins-base@GST_API_VERSION@-dev (>= @GST_PLUGINS_BASE_VERSION_REQUIRED@), + libgstreamer-plugins-bad@GST_API_VERSION@-dev (>= @GST_PLUGINS_BAD_VERSION_REQUIRED@), @USE_DRM_TRUE@ libdrm-dev, libudev-dev, @USE_X11_TRUE@ libx11-dev, libxrandr-dev, @USE_GLX_TRUE@ libgl-dev, @@ -16,11 +16,11 @@ Build-Depends: debhelper (>= 5), Build-Depends-Indep: gtk-doc-tools (>= @GTKDOC_VERSION@) Standards-Version: 3.7.2 -Package: gstreamer@GST_MAJORMINOR@-vaapi +Package: gstreamer@GST_API_VERSION@-vaapi Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} -Suggests: gstreamer@GST_MAJORMINOR@-vaapi-doc +Suggests: gstreamer@GST_API_VERSION@-vaapi-doc Description: VA-API plugins for GStreamer This package contains GStreamer plugins for VA-API support: - `vaapidecode': decode bitstreams using VA-API @@ -29,17 +29,17 @@ Description: VA-API plugins for GStreamer - `vaapipostproc': postprocess VA surfaces, e.g. deinterlacing - `vaapisink': a VA-API based video sink -Package: gstreamer@GST_MAJORMINOR@-vaapi-doc +Package: gstreamer@GST_API_VERSION@-vaapi-doc Architecture: all Section: doc Recommends: libgstvaapi@GST_VAAPI_MAJOR_VERSION@-dev (= ${source:Version}) Description: GStreamer VA-API documentation and manuals This packages contains documentation for libraries and elements. -Package: gstreamer@GST_MAJORMINOR@-vaapi-dbg +Package: gstreamer@GST_API_VERSION@-vaapi-dbg Section: libdevel Architecture: any -Depends: gstreamer@GST_MAJORMINOR@-vaapi (= ${Source-Version}) +Depends: gstreamer@GST_API_VERSION@-vaapi (= ${Source-Version}) Description: VA-API plugins for GStreamer VA-API support plugins for GStreamer. . diff --git a/debian.upstream/gstreamer-vaapi-doc.install.in b/debian.upstream/gstreamer-vaapi-doc.install.in index ff84ca1736..ff90f75b40 100644 --- a/debian.upstream/gstreamer-vaapi-doc.install.in +++ b/debian.upstream/gstreamer-vaapi-doc.install.in @@ -1 +1 @@ -debian/tmp/usr/share/doc/gstreamer@GST_MAJORMINOR@-vaapi +debian/tmp/usr/share/doc/gstreamer@GST_API_VERSION@-vaapi diff --git a/debian.upstream/libgstvaapi-dev.install.in b/debian.upstream/libgstvaapi-dev.install.in index a940c52778..764bc3ac0d 100644 --- a/debian.upstream/libgstvaapi-dev.install.in +++ b/debian.upstream/libgstvaapi-dev.install.in @@ -1,3 +1,3 @@ debian/tmp/usr/lib/libgstvaapi*.so debian/tmp/usr/lib/pkgconfig/gstreamer-vaapi*.pc -debian/tmp/usr/include/gstreamer-@GST_MAJORMINOR@/gst/vaapi/*.h +debian/tmp/usr/include/gstreamer-@GST_API_VERSION@/gst/vaapi/*.h diff --git a/debian.upstream/libgstvaapi-drm.install.in b/debian.upstream/libgstvaapi-drm.install.in index de8b898c1b..3b18b62ef7 100644 --- a/debian.upstream/libgstvaapi-drm.install.in +++ b/debian.upstream/libgstvaapi-drm.install.in @@ -1 +1 @@ -debian/tmp/usr/lib/libgstvaapi-drm-@GST_MAJORMINOR@.so.* +debian/tmp/usr/lib/libgstvaapi-drm-@GST_API_VERSION@.so.* diff --git a/debian.upstream/libgstvaapi-glx.install.in b/debian.upstream/libgstvaapi-glx.install.in index cd7352a2b4..c1001021ac 100644 --- a/debian.upstream/libgstvaapi-glx.install.in +++ b/debian.upstream/libgstvaapi-glx.install.in @@ -1 +1 @@ -debian/tmp/usr/lib/libgstvaapi-glx-@GST_MAJORMINOR@.so.* +debian/tmp/usr/lib/libgstvaapi-glx-@GST_API_VERSION@.so.* diff --git a/debian.upstream/libgstvaapi-wayland.install.in b/debian.upstream/libgstvaapi-wayland.install.in index e1740b5c92..ce4b3dd64e 100644 --- a/debian.upstream/libgstvaapi-wayland.install.in +++ b/debian.upstream/libgstvaapi-wayland.install.in @@ -1 +1 @@ -debian/tmp/usr/lib/libgstvaapi-wayland-@GST_MAJORMINOR@.so.* +debian/tmp/usr/lib/libgstvaapi-wayland-@GST_API_VERSION@.so.* diff --git a/debian.upstream/libgstvaapi-x11.install.in b/debian.upstream/libgstvaapi-x11.install.in index 8754fb8456..ff05932a2c 100644 --- a/debian.upstream/libgstvaapi-x11.install.in +++ b/debian.upstream/libgstvaapi-x11.install.in @@ -1 +1 @@ -debian/tmp/usr/lib/libgstvaapi-x11-@GST_MAJORMINOR@.so.* +debian/tmp/usr/lib/libgstvaapi-x11-@GST_API_VERSION@.so.* diff --git a/debian.upstream/libgstvaapi.install.in b/debian.upstream/libgstvaapi.install.in index e585a6b302..f719a6f347 100644 --- a/debian.upstream/libgstvaapi.install.in +++ b/debian.upstream/libgstvaapi.install.in @@ -1 +1 @@ -debian/tmp/usr/lib/libgstvaapi-@GST_MAJORMINOR@.so.* +debian/tmp/usr/lib/libgstvaapi-@GST_API_VERSION@.so.* diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index d4747b3281..3183fa66b6 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -108,14 +108,14 @@ INCLUDES = \ GTKDOC_LIBS = \ $(GLIB_LIBS) \ $(GST_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_API_VERSION).la GTKDOC_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la if USE_GLX GTKDOC_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la endif $(srcdir)/$(DOC_MODULE).types: $(SCANOBJ_TYPES) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index a7873bdf4e..17c41a2b23 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -3,7 +3,7 @@ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> - GStreamer VA-API Plugins @GST_MAJORMINOR@ Library Reference Manual + GStreamer VA-API Plugins @GST_API_VERSION@ Library Reference Manual diff --git a/docs/reference/plugins/Makefile.am b/docs/reference/plugins/Makefile.am index 0bb388cb96..6b89cade56 100644 --- a/docs/reference/plugins/Makefile.am +++ b/docs/reference/plugins/Makefile.am @@ -88,8 +88,8 @@ INCLUDES = \ $(NULL) GTKDOC_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_MAJORMINOR).la \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_API_VERSION).la \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la \ $(top_builddir)/gst/vaapi/libgstvaapi.la \ $(GLIB_LIBS) \ $(GST_LIBS) \ diff --git a/docs/reference/plugins/plugins-docs.xml.in b/docs/reference/plugins/plugins-docs.xml.in index 3532a551b7..a12206f318 100644 --- a/docs/reference/plugins/plugins-docs.xml.in +++ b/docs/reference/plugins/plugins-docs.xml.in @@ -6,7 +6,7 @@ ]> - GStreamer VA-API Plugins @GST_MAJORMINOR@ Plugins Reference Manual + GStreamer VA-API Plugins @GST_API_VERSION@ Plugins Reference Manual diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 6ec6794eaf..cec86709be 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -1,23 +1,23 @@ -lib_LTLIBRARIES = libgstvaapi-@GST_MAJORMINOR@.la +lib_LTLIBRARIES = libgstvaapi-@GST_API_VERSION@.la if USE_DRM -lib_LTLIBRARIES += libgstvaapi-drm-@GST_MAJORMINOR@.la +lib_LTLIBRARIES += libgstvaapi-drm-@GST_API_VERSION@.la endif if USE_X11 -lib_LTLIBRARIES += libgstvaapi-x11-@GST_MAJORMINOR@.la +lib_LTLIBRARIES += libgstvaapi-x11-@GST_API_VERSION@.la endif if USE_GLX -lib_LTLIBRARIES += libgstvaapi-glx-@GST_MAJORMINOR@.la +lib_LTLIBRARIES += libgstvaapi-glx-@GST_API_VERSION@.la endif if USE_WAYLAND -lib_LTLIBRARIES += libgstvaapi-wayland-@GST_MAJORMINOR@.la +lib_LTLIBRARIES += libgstvaapi-wayland-@GST_API_VERSION@.la endif -libgstvaapi_includedir = \ - $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi +libgstvaapi_includedir = \ + $(includedir)/gstreamer-$(GST_API_VERSION)/gst/vaapi libgstvaapi_cflags = \ -DGST_USE_UNSTABLE_API \ @@ -205,45 +205,45 @@ libgstvaapi_wayland_source_priv_h = \ gstvaapiutils.h \ $(NULL) -libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \ +libgstvaapi_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_source_c) \ $(libgstvaapi_source_priv_h) \ $(NULL) -libgstvaapi_@GST_MAJORMINOR@include_HEADERS = \ +libgstvaapi_@GST_API_VERSION@include_HEADERS = \ $(libgstvaapi_source_h) \ $(NULL) -libgstvaapi_@GST_MAJORMINOR@includedir = \ +libgstvaapi_@GST_API_VERSION@includedir = \ $(libgstvaapi_includedir) -libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \ +libgstvaapi_@GST_API_VERSION@_la_CFLAGS = \ $(libgstvaapi_cflags) \ $(NULL) -libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \ +libgstvaapi_@GST_API_VERSION@_la_LIBADD = \ $(libgstvaapi_libs) \ $(NULL) -libgstvaapi_@GST_MAJORMINOR@_la_LDFLAGS = \ +libgstvaapi_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(GST_VAAPI_LT_LDFLAGS) \ -export-symbols-regex "^gst_.*vaapi.*" \ $(NULL) -libgstvaapi_drm_@GST_MAJORMINOR@_la_SOURCES = \ +libgstvaapi_drm_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_drm_source_c) \ $(libgstvaapi_drm_source_priv_h) \ $(NULL) -libgstvaapi_drm_@GST_MAJORMINOR@include_HEADERS = \ +libgstvaapi_drm_@GST_API_VERSION@include_HEADERS = \ $(libgstvaapi_drm_source_h) \ $(NULL) -libgstvaapi_drm_@GST_MAJORMINOR@includedir = \ +libgstvaapi_drm_@GST_API_VERSION@includedir = \ $(libgstvaapi_includedir) -libgstvaapi_drm_@GST_MAJORMINOR@_la_CFLAGS = \ +libgstvaapi_drm_@GST_API_VERSION@_la_CFLAGS = \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ @@ -253,32 +253,32 @@ libgstvaapi_drm_@GST_MAJORMINOR@_la_CFLAGS = \ $(LIBVA_DRM_CFLAGS) \ $(NULL) -libgstvaapi_drm_@GST_MAJORMINOR@_la_LIBADD = \ +libgstvaapi_drm_@GST_API_VERSION@_la_LIBADD = \ $(GLIB_LIBS) \ $(UDEV_LIBS) \ $(DRM_LIBS) \ $(LIBVA_DRM_LIBS) \ - libgstvaapi-@GST_MAJORMINOR@.la \ + libgstvaapi-$(GST_API_VERSION).la \ $(NULL) -libgstvaapi_drm_@GST_MAJORMINOR@_la_LDFLAGS = \ +libgstvaapi_drm_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) -libgstvaapi_x11_@GST_MAJORMINOR@_la_SOURCES = \ +libgstvaapi_x11_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_x11_source_c) \ $(libgstvaapi_x11_source_priv_h) \ $(NULL) -libgstvaapi_x11_@GST_MAJORMINOR@include_HEADERS = \ +libgstvaapi_x11_@GST_API_VERSION@include_HEADERS = \ $(libgstvaapi_x11_source_h) \ $(NULL) -libgstvaapi_x11_@GST_MAJORMINOR@includedir = \ +libgstvaapi_x11_@GST_API_VERSION@includedir = \ $(libgstvaapi_includedir) -libgstvaapi_x11_@GST_MAJORMINOR@_la_CFLAGS = \ +libgstvaapi_x11_@GST_API_VERSION@_la_CFLAGS = \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ @@ -288,32 +288,32 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_CFLAGS = \ $(LIBVA_X11_CFLAGS) \ $(NULL) -libgstvaapi_x11_@GST_MAJORMINOR@_la_LIBADD = \ +libgstvaapi_x11_@GST_API_VERSION@_la_LIBADD = \ $(GLIB_LIBS) \ $(X11_LIBS) \ $(XRANDR_LIBS) \ $(LIBVA_X11_LIBS) \ - libgstvaapi-@GST_MAJORMINOR@.la \ + libgstvaapi-$(GST_API_VERSION).la \ $(NULL) -libgstvaapi_x11_@GST_MAJORMINOR@_la_LDFLAGS = \ +libgstvaapi_x11_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) -libgstvaapi_glx_@GST_MAJORMINOR@_la_SOURCES = \ +libgstvaapi_glx_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_glx_source_c) \ $(libgstvaapi_glx_source_priv_h) \ $(NULL) -libgstvaapi_glx_@GST_MAJORMINOR@include_HEADERS = \ +libgstvaapi_glx_@GST_API_VERSION@include_HEADERS = \ $(libgstvaapi_glx_source_h) \ $(NULL) -libgstvaapi_glx_@GST_MAJORMINOR@includedir = \ +libgstvaapi_glx_@GST_API_VERSION@includedir = \ $(libgstvaapi_includedir) -libgstvaapi_glx_@GST_MAJORMINOR@_la_CFLAGS = \ +libgstvaapi_glx_@GST_API_VERSION@_la_CFLAGS = \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ @@ -323,33 +323,33 @@ libgstvaapi_glx_@GST_MAJORMINOR@_la_CFLAGS = \ $(LIBVA_GLX_CFLAGS) \ $(NULL) -libgstvaapi_glx_@GST_MAJORMINOR@_la_LIBADD = \ +libgstvaapi_glx_@GST_API_VERSION@_la_LIBADD = \ $(GLIB_LIBS) \ $(GST_BASE_LIBS) \ $(GST_VIDEO_LIBS) \ $(GL_LIBS) \ $(LIBVA_GLX_LIBS) \ - libgstvaapi-x11-@GST_MAJORMINOR@.la \ + libgstvaapi-x11-$(GST_API_VERSION).la \ $(NULL) -libgstvaapi_glx_@GST_MAJORMINOR@_la_LDFLAGS = \ +libgstvaapi_glx_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) -libgstvaapi_wayland_@GST_MAJORMINOR@_la_SOURCES = \ +libgstvaapi_wayland_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_wayland_source_c) \ $(libgstvaapi_wayland_source_priv_h) \ $(NULL) -libgstvaapi_wayland_@GST_MAJORMINOR@include_HEADERS = \ +libgstvaapi_wayland_@GST_API_VERSION@include_HEADERS = \ $(libgstvaapi_wayland_source_h) \ $(NULL) -libgstvaapi_wayland_@GST_MAJORMINOR@includedir = \ +libgstvaapi_wayland_@GST_API_VERSION@includedir = \ $(libgstvaapi_includedir) -libgstvaapi_wayland_@GST_MAJORMINOR@_la_CFLAGS = \ +libgstvaapi_wayland_@GST_API_VERSION@_la_CFLAGS = \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ @@ -358,14 +358,14 @@ libgstvaapi_wayland_@GST_MAJORMINOR@_la_CFLAGS = \ $(LIBVA_WAYLAND_CFLAGS) \ $(NULL) -libgstvaapi_wayland_@GST_MAJORMINOR@_la_LIBADD = \ +libgstvaapi_wayland_@GST_API_VERSION@_la_LIBADD = \ $(GLIB_LIBS) \ $(WAYLAND_LIBS) \ $(LIBVA_WAYLAND_LIBS) \ - libgstvaapi-@GST_MAJORMINOR@.la \ + libgstvaapi-$(GST_API_VERSION).la \ $(NULL) -libgstvaapi_wayland_@GST_MAJORMINOR@_la_LDFLAGS = \ +libgstvaapi_wayland_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index df61ad96f8..e1462bf124 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -11,22 +11,22 @@ libgstvaapi_LIBS = if USE_DRM libgstvaapi_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm-$(GST_MAJORMINOR).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm-$(GST_API_VERSION).la endif if USE_X11 libgstvaapi_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la endif if USE_GLX libgstvaapi_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la endif if USE_WAYLAND libgstvaapi_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-$(GST_MAJORMINOR).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-$(GST_API_VERSION).la endif libgstvaapi_la_SOURCES = \ diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index 04537d1776..c6339977ad 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -12,7 +12,7 @@ if USE_WAYLAND pcfiles_in += gstreamer-vaapi-wayland.pc.in endif -pcfiles = $(pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc) +pcfiles = $(pcfiles_in:%.pc.in=%-$(GST_API_VERSION).pc) all_pcfiles_in = gstreamer-vaapi.pc.in all_pcfiles_in += gstreamer-vaapi-drm.pc.in @@ -20,7 +20,7 @@ all_pcfiles_in += gstreamer-vaapi-x11.pc.in all_pcfiles_in += gstreamer-vaapi-glx.pc.in all_pcfiles_in += gstreamer-vaapi-wayland.pc.in -all_pcfiles = $(all_pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc) +all_pcfiles = $(all_pcfiles_in:%.pc.in=%-$(GST_API_VERSION).pc) pkgconfigdir = @pkgconfigdir@ pkgconfig_DATA = $(pcfiles) diff --git a/pkgconfig/gstreamer-vaapi-drm.pc.in b/pkgconfig/gstreamer-vaapi-drm.pc.in index 3ebfadfc87..b7f3d917f3 100644 --- a/pkgconfig/gstreamer-vaapi-drm.pc.in +++ b/pkgconfig/gstreamer-vaapi-drm.pc.in @@ -1,12 +1,12 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ -pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ +includedir=@includedir@/gstreamer-@GST_API_VERSION@ +pluginsdir=@libdir@/gstreamer-@GST_API_VERSION@ Name: GStreamer VA-API (DRM) Plugins Libraries Description: Streaming media framework, VA-API (DRM) plugins libraries -Requires: gstreamer-vaapi-@GST_MAJORMINOR@ libva-drm +Requires: gstreamer-vaapi-@GST_API_VERSION@ libva-drm Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-drm-@GST_MAJORMINOR@ +Libs: -L${libdir} -lgstvaapi-drm-@GST_API_VERSION@ Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi-glx.pc.in b/pkgconfig/gstreamer-vaapi-glx.pc.in index 86dad312d4..789a2e176c 100644 --- a/pkgconfig/gstreamer-vaapi-glx.pc.in +++ b/pkgconfig/gstreamer-vaapi-glx.pc.in @@ -1,12 +1,12 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ -pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ +includedir=@includedir@/gstreamer-@GST_API_VERSION@ +pluginsdir=@libdir@/gstreamer-@GST_API_VERSION@ Name: GStreamer VA-API (GLX) Plugins Libraries Description: Streaming media framework, VA-API (GLX) plugins libraries -Requires: gstreamer-vaapi-@GST_MAJORMINOR@ @LIBVA_GLX_PKGNAME@ +Requires: gstreamer-vaapi-@GST_API_VERSION@ @LIBVA_GLX_PKGNAME@ Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-glx-@GST_MAJORMINOR@ +Libs: -L${libdir} -lgstvaapi-glx-@GST_API_VERSION@ Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi-wayland.pc.in b/pkgconfig/gstreamer-vaapi-wayland.pc.in index 07f1da0145..90492084e9 100644 --- a/pkgconfig/gstreamer-vaapi-wayland.pc.in +++ b/pkgconfig/gstreamer-vaapi-wayland.pc.in @@ -1,12 +1,12 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ -pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ +includedir=@includedir@/gstreamer-@GST_API_VERSION@ +pluginsdir=@libdir@/gstreamer-@GST_API_VERSION@ Name: GStreamer VA-API (Wayland) Plugins Libraries Description: Streaming media framework, VA-API (Wayland) plugins libraries -Requires: gstreamer-vaapi-@GST_MAJORMINOR@ libva-wayland +Requires: gstreamer-vaapi-@GST_API_VERSION@ libva-wayland Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-wayland-@GST_MAJORMINOR@ +Libs: -L${libdir} -lgstvaapi-wayland-@GST_API_VERSION@ Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi-x11.pc.in b/pkgconfig/gstreamer-vaapi-x11.pc.in index fc52ffcee3..fd968b682c 100644 --- a/pkgconfig/gstreamer-vaapi-x11.pc.in +++ b/pkgconfig/gstreamer-vaapi-x11.pc.in @@ -1,12 +1,12 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ -pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ +includedir=@includedir@/gstreamer-@GST_API_VERSION@ +pluginsdir=@libdir@/gstreamer-@GST_API_VERSION@ Name: GStreamer VA-API (X11) Plugins Libraries Description: Streaming media framework, VA-API (X11) plugins libraries -Requires: gstreamer-vaapi-@GST_MAJORMINOR@ @LIBVA_X11_PKGNAME@ +Requires: gstreamer-vaapi-@GST_API_VERSION@ @LIBVA_X11_PKGNAME@ Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-x11-@GST_MAJORMINOR@ +Libs: -L${libdir} -lgstvaapi-x11-@GST_API_VERSION@ Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi.pc.in b/pkgconfig/gstreamer-vaapi.pc.in index 004affab5e..a33fc513c0 100644 --- a/pkgconfig/gstreamer-vaapi.pc.in +++ b/pkgconfig/gstreamer-vaapi.pc.in @@ -1,12 +1,12 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ -pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@ +includedir=@includedir@/gstreamer-@GST_API_VERSION@ +pluginsdir=@libdir@/gstreamer-@GST_API_VERSION@ Name: GStreamer VA-API Plugins Libraries Description: Streaming media framework, VA-API plugins libraries -Requires: gstreamer-@GST_MAJORMINOR@ gstreamer-base-@GST_MAJORMINOR@ @LIBVA_PKGNAME@ +Requires: gstreamer-@GST_API_VERSION@ gstreamer-base-@GST_API_VERSION@ @LIBVA_PKGNAME@ Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-@GST_MAJORMINOR@ +Libs: -L${libdir} -lgstvaapi-@GST_API_VERSION@ Cflags: -I${includedir} diff --git a/tests/Makefile.am b/tests/Makefile.am index fe16b94d43..8c4d967dec 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -24,13 +24,13 @@ TEST_CFLAGS = \ TEST_LIBS = \ $(LIBVA_LIBS) \ $(GST_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-@GST_MAJORMINOR@.la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_API_VERSION).la if USE_DRM TEST_CFLAGS += $(LIBVA_DRM_CFLAGS) TEST_LIBS += \ $(LIBVA_DRM_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm-@GST_MAJORMINOR@.la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm-$(GST_API_VERSION).la endif if USE_X11 @@ -38,7 +38,7 @@ TEST_CFLAGS += $(X11_CFLAGS) TEST_LIBS += \ $(LIBVA_X11_LIBS) \ $(X11_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la endif if USE_GLX @@ -47,7 +47,7 @@ TEST_LIBS += \ $(LIBVA_GLX_LIBS) \ $(X11_LIBS) \ $(GL_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-@GST_MAJORMINOR@.la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la endif if USE_WAYLAND @@ -55,7 +55,7 @@ TEST_CFLAGS += $(WAYLAND_CFLAGS) TEST_LIBS += \ $(LIBVA_WAYLAND_LIBS) \ $(WAYLAND_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-@GST_MAJORMINOR@.la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-$(GST_API_VERSION).la endif test_utils_dec_source_c = \ From 8602c0459d1cf3b4181f62192666fcd11e45c442 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 14:43:46 +0100 Subject: [PATCH 1091/3781] configure: improve GStreamer API version checks. --- configure.ac | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/configure.ac b/configure.ac index f1d517e709..2b4623cbe1 100644 --- a/configure.ac +++ b/configure.ac @@ -19,9 +19,9 @@ m4_define([glib_version], [2.28]) # gstreamer version number m4_define([gst_api_version], [0.10]) -m4_define([gst_version], [0.10.36]) -m4_define([gst_plugins_base_version], [0.10.31]) -m4_define([gst_plugins_bad_version], [0.10.22]) +m4_define([gst0_version], [0.10.36]) +m4_define([gst0_plugins_base_version], [0.10.31]) +m4_define([gst0_plugins_bad_version], [0.10.22]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.0]) @@ -69,16 +69,6 @@ AC_SUBST(LIBVA_PACKAGE_VERSION) WAYLAND_API_VERSION=wayland_api_version AC_SUBST(WAYLAND_API_VERSION) -dnl Versions for GStreamer and plugins-base -GST_API_VERSION=gst_api_version -GST_VERSION_REQUIRED=gst_version -GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version -GST_PLUGINS_BAD_VERSION_REQUIRED=gst_plugins_bad_version -AC_SUBST(GST_API_VERSION) -AC_SUBST(GST_VERSION_REQUIRED) -AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) -AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED) - dnl Use pretty build output with automake >= 1.11 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [ AM_DEFAULT_VERBOSITY=1 @@ -137,9 +127,28 @@ dnl --------------------------------------------------------------------------- dnl -- GStreamer -- dnl --------------------------------------------------------------------------- +dnl Versions for GStreamer and plugins-base +GST_API_VERSION=gst_api_version +case $GST_API_VERSION in +0.10) + GST_VERSION_REQUIRED=gst0_version + GST_PLUGINS_BASE_VERSION_REQUIRED=gst0_plugins_base_version + GST_PLUGINS_BAD_VERSION_REQUIRED=gst0_plugins_bad_version + ;; +*) + AC_MSG_ERROR([unsupported GStreamer API version $GST_API_VERSION]) + ;; +esac +AC_SUBST(GST_API_VERSION) +AC_SUBST(GST_VERSION_REQUIRED) +AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) +AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED) + dnl GStreamer Core -PKG_CHECK_MODULES([GST], [gstreamer-$GST_API_VERSION >= gst_version]) -PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-$GST_API_VERSION >= gst_version]) +PKG_CHECK_MODULES([GST], + [gstreamer-$GST_API_VERSION >= $GST_VERSION_REQUIRED]) +PKG_CHECK_MODULES([GST_BASE], + [gstreamer-base-$GST_API_VERSION >= $GST_VERSION_REQUIRED]) AC_CACHE_CHECK([for GstBaseSink::query hook], ac_cv_have_gst_base_sink_query, [ saved_CPPFLAGS="$CPPFLAGS" @@ -162,13 +171,13 @@ fi dnl GStreamer -base plugins PKG_CHECK_MODULES([GST_PLUGINS_BASE], - [gstreamer-plugins-base-$GST_API_VERSION >= gst_plugins_base_version]) + [gstreamer-plugins-base-$GST_API_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) PKG_CHECK_MODULES([GST_INTERFACES], - [gstreamer-interfaces-$GST_API_VERSION >= gst_plugins_base_version]) + [gstreamer-interfaces-$GST_API_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], - [gstreamer-video-$GST_API_VERSION >= gst_plugins_base_version]) + [gstreamer-video-$GST_API_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) AC_CACHE_CHECK([for GstVideoOverlayComposition], ac_cv_have_gst_video_overlay_composition, [ @@ -247,11 +256,11 @@ AM_CONDITIONAL([USE_LOCAL_GST_VIDEO_DECODER], dnl GStreamer -bad plugins PKG_CHECK_MODULES([GST_BASEVIDEO], - [gstreamer-basevideo-$GST_API_VERSION >= gst_plugins_bad_version]) + [gstreamer-basevideo-$GST_API_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) dnl ... bitstream parsers PKG_CHECK_MODULES([GST_CODEC_PARSERS], - [gstreamer-codecparsers-$GST_API_VERSION >= gst_plugins_bad_version]) + [gstreamer-codecparsers-$GST_API_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) dnl ... MPEG-2 parser, with the required extensions AC_CACHE_CHECK([for MPEG-2 parser], @@ -637,6 +646,7 @@ AS_IF([test $USE_WAYLAND -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS wayland"]) echo echo $PACKAGE configuration summary: echo +echo GStreamer API version ............ : $GST_API_VERSION echo VA-API version ................... : $VA_VERSION_STR echo Video outputs .................... : $VIDEO_OUTPUTS echo From 87624fd6c81fb9feb9b3a94d48f24d405fed3bf6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 11:56:15 +0100 Subject: [PATCH 1092/3781] sysdeps: add more standard includes by default. --- gst-libs/gst/vaapi/sysdeps.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/sysdeps.h b/gst-libs/gst/vaapi/sysdeps.h index 2748e02316..1e675c7b3a 100644 --- a/gst-libs/gst/vaapi/sysdeps.h +++ b/gst-libs/gst/vaapi/sysdeps.h @@ -26,6 +26,10 @@ # include "config.h" #endif +#include +#include +#include + #include "glibcompat.h" /* compatibility glue */ From 833ebf9caeae10fd776aa101d5ab890d50046d1a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 18:12:18 +0100 Subject: [PATCH 1093/3781] sysdeps: split out GStreamer API compatibility glue to "gstcompat.h". --- gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstcompat.h | 35 ++++++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/sysdeps.h | 7 +------ 3 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstcompat.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index cec86709be..f007b0f2f4 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -103,6 +103,7 @@ libgstvaapi_source_h = \ libgstvaapi_source_priv_h = \ glibcompat.h \ + gstcompat.h \ gstvaapi_priv.h \ gstvaapicodec_objects.h \ gstvaapicompat.h \ diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h new file mode 100644 index 0000000000..45de7f4d23 --- /dev/null +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -0,0 +1,35 @@ +/* + * gstcompat.h - Compatibility glue for GStreamer + * + * Copyright (C) 2013 Intel Corporation + * + * 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_COMPAT_H +#define GST_COMPAT_H + +#include + +/* GstVideoOverlayComposition */ +#include + +#ifndef HAVE_GST_VIDEO_OVERLAY_HWCAPS +#define gst_video_overlay_rectangle_get_flags(rect) (0) +#define gst_video_overlay_rectangle_get_global_alpha(rect) (1.0f) +#endif + +#endif /* GST_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/sysdeps.h b/gst-libs/gst/vaapi/sysdeps.h index 1e675c7b3a..467118e854 100644 --- a/gst-libs/gst/vaapi/sysdeps.h +++ b/gst-libs/gst/vaapi/sysdeps.h @@ -31,11 +31,6 @@ #include #include "glibcompat.h" - -/* compatibility glue */ -#ifndef HAVE_GST_VIDEO_OVERLAY_HWCAPS -# define gst_video_overlay_rectangle_get_flags(rect) (0) -# define gst_video_overlay_rectangle_get_global_alpha(rect) (1.0f) -#endif +#include "gstcompat.h" #endif /* SYSDEPS_H */ From c7567668059f7395349835d82c32a48d910d32ad Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 11:10:31 +0100 Subject: [PATCH 1094/3781] image: add gst_vaapi_image_format_from_structure() helper. Add helper function to convert video formats from a GstStructure to a plain GstVaapiImageFormat. --- gst-libs/gst/vaapi/gstvaapiimageformat.c | 24 ++++++++++++++++++++---- gst-libs/gst/vaapi/gstvaapiimageformat.h | 3 +++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 4cb0296dd2..69fe778eb8 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -171,11 +171,7 @@ gst_vaapi_image_format(const VAImageFormat *va_format) GstVaapiImageFormat gst_vaapi_image_format_from_caps(GstCaps *caps) { - const GstVaapiImageFormatMap *m; GstStructure *structure; - VAImageFormat *va_format, va_formats[2]; - gint endian, rmask, gmask, bmask, amask = 0; - guint32 fourcc; if (!caps) return 0; @@ -183,6 +179,26 @@ gst_vaapi_image_format_from_caps(GstCaps *caps) structure = gst_caps_get_structure(caps, 0); if (!structure) return 0; + return gst_vaapi_image_format_from_structure(structure); +} + +/** + * gst_vaapi_image_format_from_structure: + * @structure: a #GstStructure + * + * Converts @structure into the corresponding #GstVaapiImageFormat. If + * the image format cannot be represented by #GstVaapiImageFormat, + * then zero is returned. + * + * Return value: the #GstVaapiImageFormat describing the @structure + */ +GstVaapiImageFormat +gst_vaapi_image_format_from_structure(GstStructure *structure) +{ + const GstVaapiImageFormatMap *m; + VAImageFormat *va_format, va_formats[2]; + gint endian, rmask, gmask, bmask, amask = 0; + guint32 fourcc; /* Check for YUV format */ if (gst_structure_get_fourcc(structure, "format", &fourcc)) diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h index d5b0c964d9..3e068e67af 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.h @@ -72,6 +72,9 @@ gst_vaapi_image_format(const VAImageFormat *va_format); GstVaapiImageFormat gst_vaapi_image_format_from_caps(GstCaps *caps); +GstVaapiImageFormat +gst_vaapi_image_format_from_structure(GstStructure *structure); + GstVaapiImageFormat gst_vaapi_image_format_from_fourcc(guint32 fourcc); From 0ad846e68d357b7b09a2deaccaaaef7fca01dc7d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 18:25:05 +0100 Subject: [PATCH 1095/3781] subpicture: use gst_video_overlay_rectangle_get_pixels_unscaled_raw(). Use newer gst_video_overlay_rectangle_get_pixels_unscaled_raw() helper function with GStreamer 0.10 compatible semantics, or that tries to approach the current meaning. Basically, this is also just about moving the helper to gstcompat.h. --- gst-libs/gst/vaapi/gstcompat.h | 18 ++++++++++++++ gst-libs/gst/vaapi/gstvaapicontext.c | 31 ++++++++----------------- gst-libs/gst/vaapi/gstvaapisubpicture.c | 4 +++- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index 45de7f4d23..81fa868168 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -27,9 +27,27 @@ /* GstVideoOverlayComposition */ #include +#undef gst_video_overlay_rectangle_get_pixels_unscaled_raw +#define gst_video_overlay_rectangle_get_pixels_unscaled_raw(rect, flags) \ + gst_compat_video_overlay_rectangle_get_pixels_unscaled_raw(rect, flags) + #ifndef HAVE_GST_VIDEO_OVERLAY_HWCAPS #define gst_video_overlay_rectangle_get_flags(rect) (0) #define gst_video_overlay_rectangle_get_global_alpha(rect) (1.0f) #endif +static inline GstBuffer * +gst_compat_video_overlay_rectangle_get_pixels_unscaled_raw( + GstVideoOverlayRectangle *rect, GstVideoOverlayFormatFlags flags) +{ + guint width, height, stride; + + /* Try to retrieve the original buffer that was passed to + gst_video_overlay_rectangle_new_argb(). This will only work if + there was no previous user that required pixels with non native + alpha type */ + return gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect, + &width, &height, &stride, flags); +} + #endif /* GST_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 95ddbbcae1..8d5a6d1d68 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -106,21 +106,6 @@ gst_video_overlay_rectangle_replace(GstVideoOverlayRectangle **old_rect_ptr, GST_MINI_OBJECT_CAST(new_rect)); } -static inline GstBuffer * -gst_video_overlay_rectangle_get_pixels_raw(GstVideoOverlayRectangle *rect) -{ - guint width, height, stride, flags; - - flags = gst_video_overlay_rectangle_get_flags(rect); - - /* Try to retrieve the original buffer that was passed to - gst_video_overlay_rectangle_new_argb(). This will only work if - there was no previous user that required pixels with non native - alpha type */ - return gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect, - &width, &height, &stride, flags); -} - #define overlay_rectangle_ref(overlay) \ gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(overlay)) @@ -156,7 +141,7 @@ overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context, { GstVaapiOverlayRectangle *overlay; GstVaapiRectangle *render_rect; - guint width, height; + guint width, height, flags; gint x, y; overlay = (GstVaapiOverlayRectangle *) @@ -169,8 +154,9 @@ overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context, overlay->layer_id = layer_id; overlay->rect = gst_video_overlay_rectangle_ref(rect); + flags = gst_video_overlay_rectangle_get_flags(rect); gst_buffer_replace(&overlay->rect_buffer, - gst_video_overlay_rectangle_get_pixels_raw(rect)); + gst_video_overlay_rectangle_get_pixels_unscaled_raw(rect, flags)); if (!overlay->rect_buffer) goto error; @@ -253,7 +239,7 @@ static gboolean overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay, GstVideoOverlayRectangle *rect) { - guint width, height, stride, flags; + guint flags; GstBuffer *buffer; if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum(rect)) @@ -262,9 +248,12 @@ overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay, flags = to_GstVideoOverlayFormatFlags( gst_vaapi_subpicture_get_flags(overlay->subpicture)); - buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect, - &width, &height, &stride, flags); - return GST_BUFFER_DATA(overlay->rect_buffer) != GST_BUFFER_DATA(buffer); + buffer = gst_video_overlay_rectangle_get_pixels_unscaled_raw(rect, flags); + if (!buffer) + return FALSE; + if (GST_BUFFER_DATA(overlay->rect_buffer) != GST_BUFFER_DATA(buffer)) + return FALSE; + return TRUE; } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index bed0d89aa5..b1c237b6dd 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -300,6 +300,7 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( GstVaapiImage *image; GstVaapiImageRaw raw_image; GstBuffer *buffer; + guint8 *data; gfloat global_alpha; guint width, height, stride; guint hw_flags, flags; @@ -322,6 +323,7 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( &width, &height, &stride, to_GstVideoOverlayFormatFlags(flags)); if (!buffer) return NULL; + data = GST_BUFFER_DATA(buffer); image = gst_vaapi_image_new(display, format, width, height); if (!image) @@ -331,7 +333,7 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( raw_image.width = width; raw_image.height = height; raw_image.num_planes = 1; - raw_image.pixels[0] = GST_BUFFER_DATA(buffer); + raw_image.pixels[0] = data; raw_image.stride[0] = stride; if (!gst_vaapi_image_update_from_raw(image, &raw_image, NULL)) { GST_WARNING("could not update VA image with subtitle data"); From 9128e5af48121e659f74d31745699f0b91e9d5a1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 11:50:15 +0100 Subject: [PATCH 1096/3781] tests: include "sysdeps.h" header instead of "config.h". --- tests/codec.c | 2 +- tests/decoder.c | 2 +- tests/output.c | 2 +- tests/test-decode.c | 2 +- tests/test-display.c | 2 +- tests/test-subpicture.c | 2 +- tests/test-textures.c | 1 + tests/test-windows.c | 2 +- 8 files changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/codec.c b/tests/codec.c index 5288589e59..2a8aca194c 100644 --- a/tests/codec.c +++ b/tests/codec.c @@ -19,7 +19,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "gst/vaapi/sysdeps.h" #include #include "codec.h" diff --git a/tests/decoder.c b/tests/decoder.c index 17e2ad89cd..cb918c7076 100644 --- a/tests/decoder.c +++ b/tests/decoder.c @@ -19,7 +19,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "gst/vaapi/sysdeps.h" #include #include #include diff --git a/tests/output.c b/tests/output.c index 5116baddab..33ed52c9a3 100644 --- a/tests/output.c +++ b/tests/output.c @@ -19,7 +19,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "gst/vaapi/sysdeps.h" #include #include #if USE_DRM diff --git a/tests/test-decode.c b/tests/test-decode.c index 6ee32b2e7c..3663d69528 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "gst/vaapi/sysdeps.h" #include #include #include "decoder.h" diff --git a/tests/test-display.c b/tests/test-display.c index 568c368113..e3d594f15c 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "gst/vaapi/sysdeps.h" #include #if USE_DRM # include diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 5c81942392..24482746ea 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" +#include "gst/vaapi/sysdeps.h" #include #include #include "decoder.h" diff --git a/tests/test-textures.c b/tests/test-textures.c index 7bf40fd3a8..6c5d17d10e 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -19,6 +19,7 @@ * Boston, MA 02110-1301 USA */ +#include "gst/vaapi/sysdeps.h" #include #include #include diff --git a/tests/test-windows.c b/tests/test-windows.c index 9c3b7688c3..6aa9e94dc0 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "config.h" +#include "gst/vaapi/sysdeps.h" #include #include #if USE_DRM From 8088b1b2b426069d00c3c38be280bd8a21bf9103 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 11:53:59 +0100 Subject: [PATCH 1097/3781] tests: use gst_vaapi_image_format_from_structure() in test-display. Use gst_vaapi_image_format_from_structure() helper in test-display and then extract a VAImageFormat from it instead of relying on GstCaps for YUV and RGB formats. --- tests/test-display.c | 65 ++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/tests/test-display.c b/tests/test-display.c index e3d594f15c..3f4ddc75d5 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -88,6 +88,31 @@ print_profile_caps(GstCaps *caps, const gchar *name) } } +static void +print_format_caps_yuv(const VAImageFormat *va_format) +{ + const guint32 fourcc = va_format->fourcc; + + g_print(" fourcc '%c%c%c%c'", + fourcc & 0xff, + (fourcc >> 8) & 0xff, + (fourcc >> 16) & 0xff, + (fourcc >> 24) & 0xff); +} + +static void +print_format_caps_rgb(const VAImageFormat *va_format) +{ + g_print(" %d bits per pixel, %s endian,", + va_format->bits_per_pixel, + va_format->byte_order == VA_MSB_FIRST ? "big" : "little"); + g_print(" %s masks", va_format->alpha_mask ? "rgba" : "rgb"); + g_print(" 0x%08x 0x%08x 0x%08x", + va_format->red_mask, va_format->green_mask, va_format->blue_mask); + if (va_format->alpha_mask) + g_print(" 0x%08x", va_format->alpha_mask); +} + static void print_format_caps(GstCaps *caps, const gchar *name) { @@ -97,40 +122,26 @@ print_format_caps(GstCaps *caps, const gchar *name) for (i = 0; i < gst_caps_get_size(caps); i++) { GstStructure * const structure = gst_caps_get_structure(caps, i); + const VAImageFormat *va_format; + GstVaapiImageFormat format; + if (!structure) g_error("could not get caps structure %d", i); g_print(" %s:", gst_structure_get_name(structure)); - if (gst_structure_has_name(structure, "video/x-raw-yuv")) { - guint32 fourcc; + format = gst_vaapi_image_format_from_structure(structure); + if (!format) + g_error("could not determine format"); - gst_structure_get_fourcc(structure, "format", &fourcc); + va_format = gst_vaapi_image_format_get_va_format(format); + if (!va_format) + g_error("could not determine VA format"); - g_print(" fourcc '%c%c%c%c'", - fourcc & 0xff, - (fourcc >> 8) & 0xff, - (fourcc >> 16) & 0xff, - (fourcc >> 24) & 0xff); - } - else { - gint bpp, endian, rmask, gmask, bmask, amask; - gboolean has_alpha; - - gst_structure_get_int(structure, "bpp", &bpp); - gst_structure_get_int(structure, "endianness", &endian); - gst_structure_get_int(structure, "red_mask", &rmask); - gst_structure_get_int(structure, "blue_mask", &bmask); - gst_structure_get_int(structure, "green_mask", &gmask); - has_alpha = gst_structure_get_int(structure, "alpha_mask", &amask); - - g_print(" %d bits per pixel, %s endian,", - bpp, endian == G_BIG_ENDIAN ? "big" : "little"); - g_print(" %s masks", has_alpha ? "rgba" : "rgb"); - g_print(" 0x%08x 0x%08x 0x%08x", rmask, gmask, bmask); - if (has_alpha) - g_print(" 0x%08x", amask); - } + if (gst_vaapi_image_format_is_yuv(format)) + print_format_caps_yuv(va_format); + else + print_format_caps_rgb(va_format); g_print("\n"); } } From 110c9ab43c67d975f5031d09f3f46665511aa76e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 11:57:57 +0100 Subject: [PATCH 1098/3781] tests: fix license templates. --- tests/image.c | 2 +- tests/image.h | 2 +- tests/test-decode.c | 2 +- tests/test-display.c | 2 +- tests/test-h264.c | 2 +- tests/test-h264.h | 2 +- tests/test-jpeg.c | 2 +- tests/test-jpeg.h | 2 +- tests/test-mpeg2.c | 2 +- tests/test-mpeg2.h | 2 +- tests/test-mpeg4.c | 2 +- tests/test-mpeg4.h | 2 +- tests/test-textures.c | 2 +- tests/test-vc1.c | 2 +- tests/test-vc1.h | 2 +- tests/test-windows.c | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/image.c b/tests/image.c index 289e2a30b8..7f6f395b53 100644 --- a/tests/image.c +++ b/tests/image.c @@ -17,7 +17,7 @@ * 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 "image.h" diff --git a/tests/image.h b/tests/image.h index f9580650ed..0b7f487f11 100644 --- a/tests/image.h +++ b/tests/image.h @@ -17,7 +17,7 @@ * 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 IMAGE_H #define IMAGE_H diff --git a/tests/test-decode.c b/tests/test-decode.c index 3663d69528..d0952be9dc 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -18,7 +18,7 @@ * 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 "gst/vaapi/sysdeps.h" #include diff --git a/tests/test-display.c b/tests/test-display.c index 3f4ddc75d5..43ae20bbb9 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -18,7 +18,7 @@ * 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 "gst/vaapi/sysdeps.h" #include diff --git a/tests/test-h264.c b/tests/test-h264.c index e25c3927be..6a7fa84b60 100644 --- a/tests/test-h264.c +++ b/tests/test-h264.c @@ -17,7 +17,7 @@ * 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 "test-h264.h" diff --git a/tests/test-h264.h b/tests/test-h264.h index 93b79cabe0..f960b6e7ff 100644 --- a/tests/test-h264.h +++ b/tests/test-h264.h @@ -17,7 +17,7 @@ * 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 TEST_H264_H #define TEST_H264_H diff --git a/tests/test-jpeg.c b/tests/test-jpeg.c index ab7aff0b0f..3a1879afeb 100644 --- a/tests/test-jpeg.c +++ b/tests/test-jpeg.c @@ -17,7 +17,7 @@ * 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 "test-jpeg.h" diff --git a/tests/test-jpeg.h b/tests/test-jpeg.h index 8fdbcfe3ca..673c9d14bf 100644 --- a/tests/test-jpeg.h +++ b/tests/test-jpeg.h @@ -17,7 +17,7 @@ * 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 TEST_JPEG_H #define TEST_JPEG_H diff --git a/tests/test-mpeg2.c b/tests/test-mpeg2.c index 3e75143a9e..294463858f 100644 --- a/tests/test-mpeg2.c +++ b/tests/test-mpeg2.c @@ -17,7 +17,7 @@ * 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 "test-mpeg2.h" diff --git a/tests/test-mpeg2.h b/tests/test-mpeg2.h index c43154dbc7..867bbac866 100644 --- a/tests/test-mpeg2.h +++ b/tests/test-mpeg2.h @@ -17,7 +17,7 @@ * 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 TEST_MPEG2_H #define TEST_MPEG2_H diff --git a/tests/test-mpeg4.c b/tests/test-mpeg4.c index 13984ba0a1..e06e8e8361 100644 --- a/tests/test-mpeg4.c +++ b/tests/test-mpeg4.c @@ -17,7 +17,7 @@ * 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 "test-mpeg4.h" diff --git a/tests/test-mpeg4.h b/tests/test-mpeg4.h index 8ac1e82153..06a2b7ab77 100644 --- a/tests/test-mpeg4.h +++ b/tests/test-mpeg4.h @@ -17,7 +17,7 @@ * 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 TEST_MPEG4_H #define TEST_MPEG4_H diff --git a/tests/test-textures.c b/tests/test-textures.c index 6c5d17d10e..9d6e58b97f 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -17,7 +17,7 @@ * 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 "gst/vaapi/sysdeps.h" #include diff --git a/tests/test-vc1.c b/tests/test-vc1.c index 60170f1628..7555214b76 100644 --- a/tests/test-vc1.c +++ b/tests/test-vc1.c @@ -17,7 +17,7 @@ * 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 "test-vc1.h" diff --git a/tests/test-vc1.h b/tests/test-vc1.h index 1d785043c5..30c6ec8d8c 100644 --- a/tests/test-vc1.h +++ b/tests/test-vc1.h @@ -17,7 +17,7 @@ * 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 TEST_VC1_H #define TEST_VC1_H diff --git a/tests/test-windows.c b/tests/test-windows.c index 6aa9e94dc0..2b98f84f30 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -18,7 +18,7 @@ * 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 "gst/vaapi/sysdeps.h" #include From e539092f214ab7adb86aca4ffd01e78fb631b9dd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 18:33:23 +0100 Subject: [PATCH 1099/3781] tests: modernize GstTypeFind functions. Use the GstTypeFind hooks from GStreamer 1.0. They look safer and exactly correspond to the expected behaviour. --- gst-libs/gst/vaapi/gstcompat.h | 9 +++++++++ tests/codec.c | 10 +++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index 81fa868168..8ff3180620 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -50,4 +50,13 @@ gst_compat_video_overlay_rectangle_get_pixels_unscaled_raw( &width, &height, &stride, flags); } +/* GstTypeFind */ +#undef GstTypeFindPeekFunction +#define GstTypeFindPeekFunction GstCompatTypeFindPeekFunction +#undef GstTypeFindSuggestFunction +#define GstTypeFindSuggestFunction GstCompatTypeFindSuggestFunction + +typedef guint8 *(*GstCompatTypeFindPeekFunction)(gpointer, gint64, guint); +typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, const GstCaps *); + #endif /* GST_COMPAT_H */ diff --git a/tests/codec.c b/tests/codec.c index 2a8aca194c..fa690f1490 100644 --- a/tests/codec.c +++ b/tests/codec.c @@ -98,7 +98,7 @@ typedef struct { GstTypeFind type_find; } CodecIdentifier; -static guint8 * +static const guint8 * codec_identifier_peek(gpointer data, gint64 offset, guint size) { CodecIdentifier * const cip = data; @@ -111,13 +111,13 @@ codec_identifier_peek(gpointer data, gint64 offset, guint size) } static void -codec_identifier_suggest(gpointer data, guint probability, const GstCaps *caps) +codec_identifier_suggest(gpointer data, guint probability, GstCaps *caps) { CodecIdentifier * const cip = data; if (cip->probability < probability) { cip->probability = probability; - gst_caps_replace(&cip->caps, (GstCaps *)caps); + gst_caps_replace(&cip->caps, caps); } } @@ -155,8 +155,8 @@ codec_identifier_new(const gchar *filename) goto error; tfp = &cip->type_find; - tfp->peek = codec_identifier_peek; - tfp->suggest = codec_identifier_suggest; + tfp->peek = (GstTypeFindPeekFunction)codec_identifier_peek; + tfp->suggest = (GstTypeFindSuggestFunction)codec_identifier_suggest; tfp->data = cip; return cip; From 7bb5750266e20cc1c7cb3c2367385d3848be0aa4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 11:57:03 +0100 Subject: [PATCH 1100/3781] plugins: include "sysdeps.h" header instead of "config.h". --- gst/vaapi/gstvaapipluginbuffer.c | 5 +---- gst/vaapi/gstvaapipluginutil.c | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbuffer.c b/gst/vaapi/gstvaapipluginbuffer.c index 1ed8f980e4..305eee886b 100644 --- a/gst/vaapi/gstvaapipluginbuffer.c +++ b/gst/vaapi/gstvaapipluginbuffer.c @@ -19,10 +19,7 @@ * Boston, MA 02110-1301 USA */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - +#include "gst/vaapi/sysdeps.h" #include #include #if USE_GLX diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 0a56893a0c..4ee73ad64e 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -21,10 +21,7 @@ * Boston, MA 02110-1301 USA */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include +#include "gst/vaapi/sysdeps.h" #include #if USE_DRM # include From 4fa2315557e26db436a8935ba74e06393e5756ef Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 14:02:48 +0100 Subject: [PATCH 1101/3781] plugins: fix creation of video buffer from another source buffer. gst_vaapi_video_buffer_new_from_buffer() needs to reference the source buffer video meta since it would be unreference'd from the get_buffer() helper function. For other cases, we still use (steal) the newly created video meta. --- gst/vaapi/gstvaapipluginbuffer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbuffer.c b/gst/vaapi/gstvaapipluginbuffer.c index 305eee886b..37171edf1d 100644 --- a/gst/vaapi/gstvaapipluginbuffer.c +++ b/gst/vaapi/gstvaapipluginbuffer.c @@ -70,7 +70,11 @@ gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) GstBuffer * gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) { - return get_buffer(gst_buffer_get_vaapi_video_meta(buffer)); + GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); + + if (!meta) + return NULL; + return get_buffer(gst_vaapi_video_meta_ref(meta)); } GstBuffer * From 13c5d3244b68eeeafb0b453e7bf174c574e3bbf1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 12:57:18 +0100 Subject: [PATCH 1102/3781] plugins: upgrade to newer APIs (GstVideoInfo based helpers). Use GstVideoInfo and gst_video_info_from_caps() helper wherever possible. Also use the newly added gst_vaapi_image_format_from_structure() helper in GstVaapiUploader::ensure_allowed_caps(). --- gst/vaapi/gstvaapisink.c | 21 ++++++++------------- gst/vaapi/gstvaapiuploader.c | 24 ++++++------------------ 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 1ca403f6b9..5d41d05c5e 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -627,31 +627,26 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstStructure * const structure = gst_caps_get_structure(caps, 0); + GstVideoInfo vi; guint win_width, win_height; - gint video_width, video_height, video_par_n = 1, video_par_d = 1; #if USE_DRM if (sink->display_type == GST_VAAPI_DISPLAY_TYPE_DRM) return TRUE; #endif - if (!structure) + if (!gst_video_info_from_caps(&vi, caps)) return FALSE; - if (!gst_structure_get_int(structure, "width", &video_width)) - return FALSE; - if (!gst_structure_get_int(structure, "height", &video_height)) - return FALSE; - sink->video_width = video_width; - sink->video_height = video_height; + sink->video_width = GST_VIDEO_INFO_WIDTH(&vi); + sink->video_height = GST_VIDEO_INFO_HEIGHT(&vi); + sink->video_par_n = GST_VIDEO_INFO_PAR_N(&vi); + sink->video_par_d = GST_VIDEO_INFO_PAR_D(&vi); + GST_DEBUG("video pixel-aspect-ratio %d/%d", + sink->video_par_n, sink->video_par_d); if (gst_structure_has_name(structure, "video/x-raw-yuv")) sink->use_video_raw = TRUE; - gst_video_parse_caps_pixel_aspect_ratio(caps, &video_par_n, &video_par_d); - sink->video_par_n = video_par_n; - sink->video_par_d = video_par_d; - GST_DEBUG("video pixel-aspect-ratio %d/%d", video_par_n, video_par_d); - gst_caps_replace(&sink->caps, caps); if (!gst_vaapisink_ensure_display(sink)) diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 437f6af489..4ee4af18d6 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -148,11 +148,8 @@ ensure_allowed_caps(GstVaapiUploader *uploader) GstStructure * const structure = gst_caps_get_structure(image_caps, i); GstVaapiImage *image; GstVaapiImageFormat format; - guint32 fourcc; - if (!gst_structure_get_fourcc(structure, "format", &fourcc)) - continue; - format = gst_vaapi_image_format_from_fourcc(fourcc); + format = gst_vaapi_image_format_from_structure(structure); if (!format) continue; image = gst_vaapi_image_new(priv->display, format, WIDTH, HEIGHT); @@ -320,9 +317,7 @@ gst_vaapi_uploader_ensure_caps( GstVaapiUploaderPrivate *priv; GstVaapiImage *image; GstVaapiImageFormat vaformat; - GstVideoFormat vformat; - GstStructure *structure; - gint width, height; + GstVideoInfo vi; g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); g_return_val_if_fail(src_caps != NULL, FALSE); @@ -335,18 +330,12 @@ gst_vaapi_uploader_ensure_caps( priv = uploader->priv; priv->direct_rendering = 0; - structure = gst_caps_get_structure(src_caps, 0); - if (!structure) - return FALSE; - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); - /* Translate from Gst video format to VA image format */ - if (!gst_video_format_parse_caps(src_caps, &vformat, NULL, NULL)) + if (!gst_video_info_from_caps(&vi, src_caps)) return FALSE; - if (!gst_video_format_is_yuv(vformat)) + if (!GST_VIDEO_INFO_IS_YUV(&vi)) return FALSE; - vaformat = gst_vaapi_image_format_from_video(vformat); + vaformat = gst_vaapi_image_format_from_video(GST_VIDEO_INFO_FORMAT(&vi)); if (!vaformat) return FALSE; @@ -355,8 +344,7 @@ gst_vaapi_uploader_ensure_caps( if (image) { if (gst_vaapi_image_get_format(image) == vaformat && gst_vaapi_image_is_linear(image) && - (gst_vaapi_image_get_data_size(image) == - gst_video_format_get_size(vformat, width, height))) + gst_vaapi_image_get_data_size(image) == GST_VIDEO_INFO_SIZE(&vi)) priv->direct_rendering = 1; gst_vaapi_video_pool_put_object(priv->images, image); } From 7fd648b8b0954f2e90df89fa448c58fada29ea63 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 18:04:39 +0100 Subject: [PATCH 1103/3781] plugins: move up interfaces (cosmetics). Move GstImplementsInterface and GstVideoContext support functions up so that to keep a clear separation between the plugin element and its interface hooks. --- gst/vaapi/gstvaapidecode.c | 64 ++++++++++++++----------------- gst/vaapi/gstvaapidownload.c | 64 ++++++++++++++----------------- gst/vaapi/gstvaapipostproc.c | 72 ++++++++++++++++------------------- gst/vaapi/gstvaapisink.c | 66 ++++++++++++++------------------ gst/vaapi/gstvaapiupload.c | 73 ++++++++++++++++-------------------- 5 files changed, 150 insertions(+), 189 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 545a604be9..b1f4bc5f4e 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -88,11 +88,36 @@ static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapidecode_src_caps_str)); -static void -gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface); +/* GstImplementsInterface interface */ +static gboolean +gst_vaapidecode_implements_interface_supported( + GstImplementsInterface *iface, + GType type +) +{ + return (type == GST_TYPE_VIDEO_CONTEXT); +} static void -gst_video_context_interface_init(GstVideoContextInterface *iface); +gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface) +{ + iface->supported = gst_vaapidecode_implements_interface_supported; +} + +/* GstVideoContext interface */ +static void +gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type, + const GValue *value) +{ + GstVaapiDecode *decode = GST_VAAPIDECODE (context); + gst_vaapi_set_display (type, value, &decode->display); +} + +static void +gst_video_context_interface_init(GstVideoContextInterface *iface) +{ + iface->set_context = gst_vaapidecode_set_video_context; +} #define GstVideoContextClass GstVideoContextInterface G_DEFINE_TYPE_WITH_CODE( @@ -417,39 +442,6 @@ gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) return gst_vaapidecode_create(decode, caps); } -/* GstImplementsInterface interface */ - -static gboolean -gst_vaapidecode_implements_interface_supported( - GstImplementsInterface *iface, - GType type -) -{ - return (type == GST_TYPE_VIDEO_CONTEXT); -} - -static void -gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface) -{ - iface->supported = gst_vaapidecode_implements_interface_supported; -} - -/* GstVideoContext interface */ - -static void -gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type, - const GValue *value) -{ - GstVaapiDecode *decode = GST_VAAPIDECODE (context); - gst_vaapi_set_display (type, value, &decode->display); -} - -static void -gst_video_context_interface_init(GstVideoContextInterface *iface) -{ - iface->set_context = gst_vaapidecode_set_video_context; -} - static void gst_vaapidecode_finalize(GObject *object) { diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 4d1d49fef8..5a29501fc1 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -99,11 +99,36 @@ struct _GstVaapiDownloadClass { GstBaseTransformClass parent_class; }; -static void -gst_vaapidownload_implements_iface_init(GstImplementsInterfaceClass *iface); +/* GstImplementsInterface interface */ +static gboolean +gst_vaapidownload_implements_interface_supported( + GstImplementsInterface *iface, + GType type +) +{ + return (type == GST_TYPE_VIDEO_CONTEXT); +} static void -gst_video_context_interface_init(GstVideoContextInterface *iface); +gst_vaapidownload_implements_iface_init(GstImplementsInterfaceClass *iface) +{ + iface->supported = gst_vaapidownload_implements_interface_supported; +} + +/* GstVideoContext interface */ +static void +gst_vaapidownload_set_video_context(GstVideoContext *context, const gchar *type, + const GValue *value) +{ + GstVaapiDownload *download = GST_VAAPIDOWNLOAD (context); + gst_vaapi_set_display (type, value, &download->display); +} + +static void +gst_video_context_interface_init(GstVideoContextInterface *iface) +{ + iface->set_context = gst_vaapidownload_set_video_context; +} #define GstVideoContextClass GstVideoContextInterface G_DEFINE_TYPE_WITH_CODE( @@ -161,39 +186,6 @@ gst_vaapidownload_query( GstQuery *query ); -/* GstImplementsInterface interface */ - -static gboolean -gst_vaapidownload_implements_interface_supported( - GstImplementsInterface *iface, - GType type -) -{ - return (type == GST_TYPE_VIDEO_CONTEXT); -} - -static void -gst_vaapidownload_implements_iface_init(GstImplementsInterfaceClass *iface) -{ - iface->supported = gst_vaapidownload_implements_interface_supported; -} - -/* GstVideoContext interface */ - -static void -gst_vaapidownload_set_video_context(GstVideoContext *context, const gchar *type, - const GValue *value) -{ - GstVaapiDownload *download = GST_VAAPIDOWNLOAD (context); - gst_vaapi_set_display (type, value, &download->display); -} - -static void -gst_video_context_interface_init(GstVideoContextInterface *iface) -{ - iface->set_context = gst_vaapidownload_set_video_context; -} - static void gst_vaapidownload_destroy(GstVaapiDownload *download) { diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index a40352f744..3172482005 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -74,11 +74,40 @@ static GstStaticPadTemplate gst_vaapipostproc_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapipostproc_src_caps_str)); -static void -gst_vaapipostproc_implements_iface_init(GstImplementsInterfaceClass *iface); +/* GstImplementsInterface interface */ +static gboolean +gst_vaapipostproc_implements_interface_supported( + GstImplementsInterface *iface, + GType type +) +{ + return (type == GST_TYPE_VIDEO_CONTEXT); +} static void -gst_video_context_interface_init(GstVideoContextInterface *iface); +gst_vaapipostproc_implements_iface_init(GstImplementsInterfaceClass *iface) +{ + iface->supported = gst_vaapipostproc_implements_interface_supported; +} + +/* GstVideoContext interface */ +static void +gst_vaapipostproc_set_video_context( + GstVideoContext *context, + const gchar *type, + const GValue *value +) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(context); + + gst_vaapi_set_display(type, value, &postproc->display); +} + +static void +gst_video_context_interface_init(GstVideoContextInterface *iface) +{ + iface->set_context = gst_vaapipostproc_set_video_context; +} #define GstVideoContextClass GstVideoContextInterface G_DEFINE_TYPE_WITH_CODE( @@ -161,43 +190,6 @@ get_vaapipostproc_from_pad(GstPad *pad) return GST_VAAPIPOSTPROC(gst_pad_get_parent_element(pad)); } -/* GstImplementsInterface interface */ - -static gboolean -gst_vaapipostproc_implements_interface_supported( - GstImplementsInterface *iface, - GType type -) -{ - return (type == GST_TYPE_VIDEO_CONTEXT); -} - -static void -gst_vaapipostproc_implements_iface_init(GstImplementsInterfaceClass *iface) -{ - iface->supported = gst_vaapipostproc_implements_interface_supported; -} - -/* GstVideoContext interface */ - -static void -gst_vaapipostproc_set_video_context( - GstVideoContext *context, - const gchar *type, - const GValue *value -) -{ - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(context); - - gst_vaapi_set_display(type, value, &postproc->display); -} - -static void -gst_video_context_interface_init(GstVideoContextInterface *iface) -{ - iface->set_context = gst_vaapipostproc_set_video_context; -} - static inline gboolean gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc) { diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 5d41d05c5e..90350dec5a 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -85,11 +85,37 @@ static GstStaticPadTemplate gst_vaapisink_sink_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapisink_sink_caps_str)); -static void -gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface); +/* GstImplementsInterface interface */ +static gboolean +gst_vaapisink_implements_interface_supported( + GstImplementsInterface *iface, + GType type +) +{ + return (type == GST_TYPE_VIDEO_CONTEXT || + type == GST_TYPE_X_OVERLAY); +} static void -gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface); +gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface) +{ + iface->supported = gst_vaapisink_implements_interface_supported; +} + +/* GstVideoContext interface */ +static void +gst_vaapisink_set_video_context(GstVideoContext *context, const gchar *type, + const GValue *value) +{ + GstVaapiSink *sink = GST_VAAPISINK (context); + gst_vaapi_set_display (type, value, &sink->display); +} + +static void +gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface) +{ + iface->set_context = gst_vaapisink_set_video_context; +} static void gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface); @@ -118,40 +144,6 @@ enum { #define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 -/* GstImplementsInterface interface */ - -static gboolean -gst_vaapisink_implements_interface_supported( - GstImplementsInterface *iface, - GType type -) -{ - return (type == GST_TYPE_VIDEO_CONTEXT || - type == GST_TYPE_X_OVERLAY); -} - -static void -gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface) -{ - iface->supported = gst_vaapisink_implements_interface_supported; -} - -/* GstVideoContext interface */ - -static void -gst_vaapisink_set_video_context(GstVideoContext *context, const gchar *type, - const GValue *value) -{ - GstVaapiSink *sink = GST_VAAPISINK (context); - gst_vaapi_set_display (type, value, &sink->display); -} - -static void -gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface) -{ - iface->set_context = gst_vaapisink_set_video_context; -} - /* GstXOverlay interface */ #if USE_X11 diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 6118454634..05941d555c 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -75,11 +75,41 @@ static GstStaticPadTemplate gst_vaapiupload_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapiupload_vaapi_caps_str)); -static void -gst_vaapiupload_implements_iface_init(GstImplementsInterfaceClass *iface); + +/* GstImplementsInterface interface */ +static gboolean +gst_vaapiupload_implements_interface_supported( + GstImplementsInterface *iface, + GType type +) +{ + return (type == GST_TYPE_VIDEO_CONTEXT); +} static void -gst_video_context_interface_init(GstVideoContextInterface *iface); +gst_vaapiupload_implements_iface_init(GstImplementsInterfaceClass *iface) +{ + iface->supported = gst_vaapiupload_implements_interface_supported; +} + +/* GstVideoContext interface */ +static void +gst_vaapiupload_set_video_context(GstVideoContext *context, const gchar *type, + const GValue *value) +{ + GstVaapiUpload * const upload = GST_VAAPIUPLOAD(context); + + gst_vaapi_set_display(type, value, &upload->display); + + if (upload->uploader) + gst_vaapi_uploader_ensure_display(upload->uploader, upload->display); +} + +static void +gst_video_context_interface_init(GstVideoContextInterface *iface) +{ + iface->set_context = gst_vaapiupload_set_video_context; +} #define GstVideoContextClass GstVideoContextInterface G_DEFINE_TYPE_WITH_CODE( @@ -149,43 +179,6 @@ gst_vaapiupload_query( GstQuery *query ); -/* GstImplementsInterface interface */ - -static gboolean -gst_vaapiupload_implements_interface_supported( - GstImplementsInterface *iface, - GType type -) -{ - return (type == GST_TYPE_VIDEO_CONTEXT); -} - -static void -gst_vaapiupload_implements_iface_init(GstImplementsInterfaceClass *iface) -{ - iface->supported = gst_vaapiupload_implements_interface_supported; -} - -/* GstVideoContext interface */ - -static void -gst_vaapiupload_set_video_context(GstVideoContext *context, const gchar *type, - const GValue *value) -{ - GstVaapiUpload * const upload = GST_VAAPIUPLOAD(context); - - gst_vaapi_set_display(type, value, &upload->display); - - if (upload->uploader) - gst_vaapi_uploader_ensure_display(upload->uploader, upload->display); -} - -static void -gst_video_context_interface_init(GstVideoContextInterface *iface) -{ - iface->set_context = gst_vaapiupload_set_video_context; -} - static void gst_vaapiupload_destroy(GstVaapiUpload *upload) { From 2dcc9f19da5a44062521104705e2b8e9e30a30a9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 18:41:40 +0100 Subject: [PATCH 1104/3781] plugins: use modern GstElement metadata information. Use gst_element_class_set_static_metadata() from GStreamer 1.0, which basically is the same as gst_element_class_set_details_simple() in GStreamer 0.10 context. --- gst-libs/gst/vaapi/gstcompat.h | 12 ++++++++++++ gst/vaapi/gstvaapidecode.c | 20 +++++--------------- gst/vaapi/gstvaapidownload.c | 20 +++++--------------- gst/vaapi/gstvaapipostproc.c | 20 +++++--------------- gst/vaapi/gstvaapisink.c | 20 +++++--------------- gst/vaapi/gstvaapiupload.c | 20 +++++--------------- 6 files changed, 37 insertions(+), 75 deletions(-) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index 8ff3180620..4f5ff6258f 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -50,6 +50,18 @@ gst_compat_video_overlay_rectangle_get_pixels_unscaled_raw( &width, &height, &stride, flags); } +/* GstElement */ +#undef gst_element_class_set_static_metadata +#define gst_element_class_set_static_metadata(klass, name, path, desc, author) \ + gst_compat_element_class_set_static_metadata(klass, name, path, desc, author) + +static inline void +gst_compat_element_class_set_static_metadata(GstElementClass *klass, + const gchar *name, const char *path, const gchar *desc, const gchar *author) +{ + gst_element_class_set_details_simple(klass, name, path, desc, author); +} + /* GstTypeFind */ #undef GstTypeFindPeekFunction #define GstTypeFindPeekFunction GstCompatTypeFindPeekFunction diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b1f4bc5f4e..508a32356d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -49,14 +49,6 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapidecode); #define GST_CAT_DEFAULT gst_debug_vaapidecode -/* ElementFactory information */ -static const GstElementDetails gst_vaapidecode_details = - GST_ELEMENT_DETAILS( - "VA-API decoder", - "Codec/Decoder/Video", - GST_PLUGIN_DESC, - "Gwenole Beauchesne "); - /* Default templates */ #define GST_CAPS_CODEC(CODEC) CODEC "; " @@ -563,13 +555,11 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) vdec_class->handle_frame = GST_DEBUG_FUNCPTR(gst_vaapidecode_handle_frame); vdec_class->finish = GST_DEBUG_FUNCPTR(gst_vaapidecode_finish); - gst_element_class_set_details_simple( - element_class, - gst_vaapidecode_details.longname, - gst_vaapidecode_details.klass, - gst_vaapidecode_details.description, - gst_vaapidecode_details.author - ); + gst_element_class_set_static_metadata(element_class, + "VA-API decoder", + "Codec/Decoder/Video", + GST_PLUGIN_DESC, + "Gwenole Beauchesne "); /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapidecode_sink_factory); diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 5a29501fc1..3000fd91eb 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -43,14 +43,6 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapidownload); #define GST_CAT_DEFAULT gst_debug_vaapidownload -/* ElementFactory information */ -static const GstElementDetails gst_vaapidownload_details = - GST_ELEMENT_DETAILS( - "VA-API colorspace converter", - "Filter/Converter/Video", - GST_PLUGIN_DESC, - "Gwenole Beauchesne "); - /* Default templates */ static const char gst_vaapidownload_yuv_caps_str[] = "video/x-raw-yuv, " @@ -237,13 +229,11 @@ gst_vaapidownload_class_init(GstVaapiDownloadClass *klass) trans_class->transform_size = gst_vaapidownload_transform_size; trans_class->set_caps = gst_vaapidownload_set_caps; - gst_element_class_set_details_simple( - element_class, - gst_vaapidownload_details.longname, - gst_vaapidownload_details.klass, - gst_vaapidownload_details.description, - gst_vaapidownload_details.author - ); + gst_element_class_set_static_metadata(element_class, + "VA-API colorspace converter", + "Filter/Converter/Video", + GST_PLUGIN_DESC, + "Gwenole Beauchesne "); /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapidownload_sink_factory); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 3172482005..b0ea884c85 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -43,14 +43,6 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapipostproc); #define GST_CAT_DEFAULT gst_debug_vaapipostproc -/* ElementFactory information */ -static const GstElementDetails gst_vaapipostproc_details = - GST_ELEMENT_DETAILS( - "VA-API video postprocessing", - "Filter/Converter/Video", - GST_PLUGIN_DESC, - "Gwenole Beauchesne "); - /* Default templates */ static const char gst_vaapipostproc_sink_caps_str[] = GST_VAAPI_SURFACE_CAPS ", " @@ -651,13 +643,11 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) element_class->change_state = gst_vaapipostproc_change_state; - gst_element_class_set_details_simple( - element_class, - gst_vaapipostproc_details.longname, - gst_vaapipostproc_details.klass, - gst_vaapipostproc_details.description, - gst_vaapipostproc_details.author - ); + gst_element_class_set_static_metadata(element_class, + "VA-API video postprocessing", + "Filter/Converter/Video", + GST_PLUGIN_DESC, + "Gwenole Beauchesne "); /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapipostproc_sink_factory); diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 90350dec5a..e81ddde436 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -63,14 +63,6 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink); #define GST_CAT_DEFAULT gst_debug_vaapisink -/* ElementFactory information */ -static const GstElementDetails gst_vaapisink_details = - GST_ELEMENT_DETAILS( - "VA-API sink", - "Sink/Video", - GST_PLUGIN_DESC, - "Gwenole Beauchesne "); - /* Default template */ static const char gst_vaapisink_sink_caps_str[] = "video/x-raw-yuv, " @@ -1069,13 +1061,11 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->query = gst_vaapisink_query; basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; - gst_element_class_set_details_simple( - element_class, - gst_vaapisink_details.longname, - gst_vaapisink_details.klass, - gst_vaapisink_details.description, - gst_vaapisink_details.author - ); + gst_element_class_set_static_metadata(element_class, + "VA-API sink", + "Sink/Video", + GST_PLUGIN_DESC, + "Gwenole Beauchesne "); pad_template = gst_static_pad_template_get(&gst_vaapisink_sink_factory); gst_element_class_add_pad_template(element_class, pad_template); diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 05941d555c..4b4f7c9600 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -44,14 +44,6 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapiupload); #define GST_CAT_DEFAULT gst_debug_vaapiupload -/* ElementFactory information */ -static const GstElementDetails gst_vaapiupload_details = - GST_ELEMENT_DETAILS( - "VA-API colorspace converter", - "Filter/Converter/Video", - GST_PLUGIN_DESC, - "Gwenole Beauchesne "); - /* Default templates */ static const char gst_vaapiupload_yuv_caps_str[] = "video/x-raw-yuv, " @@ -215,13 +207,11 @@ gst_vaapiupload_class_init(GstVaapiUploadClass *klass) trans_class->get_unit_size = gst_vaapiupload_get_unit_size; trans_class->prepare_output_buffer = gst_vaapiupload_prepare_output_buffer; - gst_element_class_set_details_simple( - element_class, - gst_vaapiupload_details.longname, - gst_vaapiupload_details.klass, - gst_vaapiupload_details.description, - gst_vaapiupload_details.author - ); + gst_element_class_set_static_metadata(element_class, + "VA-API colorspace converter", + "Filter/Converter/Video", + GST_PLUGIN_DESC, + "Gwenole Beauchesne "); /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapiupload_sink_factory); From 6ce6712ed563dc09eafe28603820289dec2a593b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 13:42:15 +0100 Subject: [PATCH 1105/3781] vaapisink: fix support for raw YUV buffers. If the raw YUV buffer was created from vaapisink, through the buffer_alloc() hook, then it will have a valid GstVaapiVideoMeta object attached to it. However, we previously assumed in that case that it was a "native" VA buffer, thus not calling into GstVaapiUploader::process(). --- gst/vaapi/gstvaapisink.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index e81ddde436..0b4a0bd0cc 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -850,8 +850,6 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) buffer = gst_vaapi_uploader_get_buffer(sink->uploader); if (!buffer) return GST_FLOW_UNEXPECTED; - if (!gst_vaapi_uploader_process(sink->uploader, src_buffer, buffer)) - goto error; meta = gst_buffer_get_vaapi_video_meta(buffer); if (!meta) goto error; @@ -859,6 +857,12 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) else return GST_FLOW_UNEXPECTED; + if (sink->use_video_raw && + !gst_vaapi_uploader_process(sink->uploader, src_buffer, buffer)) { + GST_WARNING("failed to process raw YUV buffer"); + goto error; + } + if (sink->display != gst_vaapi_video_meta_get_display(meta)) { g_clear_object(&sink->display); sink->display = g_object_ref(gst_vaapi_video_meta_get_display(meta)); From 9e1da769715fd8cba65d937a0ffdea5ccb688352 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 17:34:38 +0100 Subject: [PATCH 1106/3781] vaapisink: add helper function to apply a composition buffer. Simplify application of a composition buffer to a GstVaapiSurface, and all its peers, until that function is eventually promoted to libgstvaapi. --- gst/vaapi/gstvaapisink.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 0b4a0bd0cc..28aca3e524 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -832,11 +832,22 @@ gst_vaapisink_put_surface( return TRUE; } +static inline gboolean +set_composition_from_buffer(GstVaapiSurface *surface, GstBuffer *buffer) +{ + GstVideoOverlayComposition * const composition = + gst_video_buffer_get_overlay_composition(buffer); + + if (!composition) + return FALSE; + return gst_vaapi_surface_set_subpictures_from_composition(surface, + composition, TRUE); +} + static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstVideoOverlayComposition *composition; GstVaapiVideoMeta *meta; GstVaapiSurface *surface; GstBuffer *buffer; @@ -882,9 +893,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) flags = gst_vaapi_video_meta_get_render_flags(meta); - composition = gst_video_buffer_get_overlay_composition(src_buffer); - if (!gst_vaapi_surface_set_subpictures_from_composition(surface, - composition, TRUE)) + if (!set_composition_from_buffer(surface, src_buffer)) GST_WARNING("could not update subtitles"); switch (sink->display_type) { From 57ed7e3f8b803f9aa50da72586260d381258e1d0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Mar 2013 13:28:05 +0100 Subject: [PATCH 1107/3781] decoder: sanitize uses of codec frame input buffer (cosmetics). Alias GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer to a simple "buffer" variable. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 6 ++++-- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 6 +++--- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 11 ++++++----- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 6 +++--- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 5 +++-- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index bd318d7684..1ff9193428 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2698,6 +2698,8 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GstVaapiPictureH264 * const picture = priv->current_picture; GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstVaapiSlice *slice; + GstBuffer * const buffer = + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; GST_DEBUG("slice (%u bytes)", pi->nalu.size); @@ -2707,8 +2709,8 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) } slice = GST_VAAPI_SLICE_NEW(H264, decoder, - (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) + - unit->offset + pi->nalu.offset), pi->nalu.size); + (GST_BUFFER_DATA(buffer) + unit->offset + pi->nalu.offset), + pi->nalu.size); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index f3221b992a..65e648059d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -681,14 +681,14 @@ gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder, { GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(base_decoder); GstVaapiDecoderStatus status; + GstBuffer * const buffer = + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - unit->buffer = gst_buffer_create_sub( - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, - unit->offset, unit->size); + unit->buffer = gst_buffer_create_sub(buffer, unit->offset, unit->size); if (!unit->buffer) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index c889e9a497..074d65e8e0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1194,6 +1194,8 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) GstVaapiSlice *slice; VASliceParameterBufferMPEG2 *slice_param; GstMpegVideoSliceHdr * const slice_hdr = unit->parsed_info; + GstBuffer * const buffer = + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; GST_DEBUG("slice %d (%u bytes)", slice_hdr->slice_vertical_position, unit->size); @@ -1202,8 +1204,7 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, - (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) + - unit->offset), unit->size); + (GST_BUFFER_DATA(buffer) + unit->offset), unit->size); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -1473,14 +1474,14 @@ gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base_decoder, GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); GstVaapiDecoderStatus status; GstMpegVideoPacket packet; + GstBuffer * const buffer = + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - packet.data = - (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) + - unit->offset); + packet.data = GST_BUFFER_DATA(buffer) + unit->offset; packet.size = unit->size; packet.type = packet.data[3]; packet.offset = 4; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 0dd3425570..8d800b4104 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -1086,14 +1086,14 @@ gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4(base_decoder); GstVaapiDecoderStatus status; + GstBuffer * const buffer = + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - unit->buffer = gst_buffer_create_sub( - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer, - unit->offset, unit->size); + unit->buffer = gst_buffer_create_sub(buffer, unit->offset, unit->size); if (!unit->buffer) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index d42f72e151..754729076b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1253,14 +1253,15 @@ gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base_decoder, { GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); GstVaapiDecoderStatus status; + GstBuffer * const buffer = + GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; status = decode_buffer(decoder, - (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) + - unit->offset), unit->size); + (GST_BUFFER_DATA(buffer) + unit->offset), unit->size); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; return GST_VAAPI_DECODER_STATUS_SUCCESS; From ba8a7ab6cd0f4c1f82b46fe8446fd3675a38ed98 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Mar 2013 13:41:28 +0100 Subject: [PATCH 1108/3781] decoder: get rid of GstVaapiDecoderUnit::buffer field. Drop GstVaapiDecoderUnit buffer field (GstBuffer) since it's totally useless nowadays as creating sub-buffers doesn't bring any value. It actually means more memory allocations. We can't do without that in JPEG and MPEG-4:2 decoders. --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 17 +++++++---------- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 17 +++++++---------- gst-libs/gst/vaapi/gstvaapidecoder_unit.c | 18 ------------------ gst-libs/gst/vaapi/gstvaapidecoder_unit.h | 8 -------- 4 files changed, 14 insertions(+), 46 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 65e648059d..5fc7f16024 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -490,19 +490,15 @@ decode_scan( } static GstVaapiDecoderStatus -decode_buffer(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer) +decode_buffer(GstVaapiDecoderJpeg *decoder, guchar *buf, guint buf_size) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; GstJpegMarkerSegment seg; GstJpegScanSegment scan_seg; - guchar *buf; - guint buf_size, ofs; + guint ofs; gboolean append_ecs; - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - memset(&scan_seg, 0, sizeof(scan_seg)); ofs = 0; @@ -683,16 +679,17 @@ gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderStatus status; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; + guchar *buf; + guint buf_size; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - unit->buffer = gst_buffer_create_sub(buffer, unit->offset, unit->size); - if (!unit->buffer) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + buf = GST_BUFFER_DATA(buffer) + unit->offset; + buf_size = unit->size; - status = decode_buffer(decoder, unit->buffer); + status = decode_buffer(decoder, buf, buf_size); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; return GST_VAAPI_DECODER_STATUS_SUCCESS; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 8d800b4104..c3dd265eb1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -890,16 +890,12 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) } static GstVaapiDecoderStatus -decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) +decode_buffer(GstVaapiDecoderMpeg4 *decoder, const guchar *buf, guint buf_size) { GstVaapiDecoderMpeg4Private * const priv = decoder->priv; GstVaapiDecoderStatus status; GstMpeg4Packet packet; - const guchar *buf; - guint buf_size, ofs; - - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); + guint ofs; if (priv->is_svh) { status = decode_picture(decoder, buf, buf_size); @@ -1088,16 +1084,17 @@ gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderStatus status; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; + const guchar *buf; + guint buf_size; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - unit->buffer = gst_buffer_create_sub(buffer, unit->offset, unit->size); - if (!unit->buffer) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + buf = GST_BUFFER_DATA(buffer) + unit->offset; + buf_size = unit->size; - status = decode_buffer(decoder, unit->buffer); + status = decode_buffer(decoder, buf, buf_size); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; return GST_VAAPI_DECODER_STATUS_SUCCESS; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c index af37947900..57c4d2b3b5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c @@ -42,7 +42,6 @@ gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit) unit->flags = 0; unit->size = 0; unit->offset = 0; - unit->buffer = NULL; unit->parsed_info = NULL; unit->parsed_info_destroy_notify = NULL; @@ -61,26 +60,9 @@ gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit) void gst_vaapi_decoder_unit_clear(GstVaapiDecoderUnit *unit) { - gst_buffer_replace(&unit->buffer, NULL); gst_vaapi_decoder_unit_set_parsed_info(unit, NULL, NULL); } -/** - * gst_vaapi_decoder_unit_set_buffer: - * @unit: a #GstVaapiDecoderUnit - * @buffer: the new #GstBuffer to set - * - * Sets new buffer to the supplied decoder unit. The @unit holds an - * extra reference to the @buffer if it is not NULL. - */ -void -gst_vaapi_decoder_unit_set_buffer(GstVaapiDecoderUnit *unit, GstBuffer *buffer) -{ - g_return_if_fail(GST_VAAPI_IS_DECODER_UNIT(unit)); - - gst_buffer_replace(&unit->buffer, buffer); -} - /** * gst_vaapi_decoder_unit_set_parsed_info: * @unit: a #GstVaapiDecoderUnit diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h index 6ccc59bddf..717e805526 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h @@ -22,8 +22,6 @@ #ifndef GST_VAAPI_DECODER_UNIT_H #define GST_VAAPI_DECODER_UNIT_H -#include - G_BEGIN_DECLS typedef struct _GstVaapiDecoderUnit GstVaapiDecoderUnit; @@ -155,7 +153,6 @@ typedef enum { * @size: size in bytes of this bitstream unit * @offset: relative offset in bytes to bitstream unit within the * associated #GstVideoCodecFrame input_buffer - * @buffer: (optional) associated buffer or sub-buffer * @parsed_info: parser-specific data (this is codec specific) * @parsed_info_destroy_notify: function used to release @parsed_info data * @@ -165,7 +162,6 @@ struct _GstVaapiDecoderUnit { guint flags; guint size; guint offset; - GstBuffer *buffer; gpointer parsed_info; GDestroyNotify parsed_info_destroy_notify; }; @@ -182,10 +178,6 @@ G_GNUC_INTERNAL GstVaapiDecoderUnit * gst_vaapi_decoder_unit_new(void); -G_GNUC_INTERNAL -void -gst_vaapi_decoder_unit_set_buffer(GstVaapiDecoderUnit *unit, GstBuffer *buffer); - G_GNUC_INTERNAL void gst_vaapi_decoder_unit_set_parsed_info(GstVaapiDecoderUnit *unit, From 4009430becf613c536da3dccbe962554c258ae8d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Mar 2013 14:36:40 +0100 Subject: [PATCH 1109/3781] decoder: sanitize codec-data decoding. Add a new GstVaapiDecoder::decode_codec_data() hook to actually decode codec-data in the decoder sub-class. Provide a common shared helper function to do the actual work and delegating further to the sub-class. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 25 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 26 ++++++++--------- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 28 ++++++++++-------- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 4 +++ gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 33 +++++++++++----------- 6 files changed, 75 insertions(+), 43 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 3f6577fb10..d1cbd3a3a5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -956,3 +956,28 @@ gst_vaapi_decoder_flush(GstVaapiDecoder *decoder) return do_flush(decoder); } + +GstVaapiDecoderStatus +gst_vaapi_decoder_decode_codec_data(GstVaapiDecoder *decoder) +{ + GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); + GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); + GstVaapiDecoderStatus status; + const guchar *buf; + guint buf_size; + + if (!codec_data) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + /* FIXME: add a meaningful error code? */ + if (!klass->decode_codec_data) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + buf = GST_BUFFER_DATA(codec_data); + buf_size = GST_BUFFER_SIZE(codec_data); + if (!buf || buf_size == 0) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + status = klass->decode_codec_data(decoder, buf, buf_size); + return status; +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 1558d28daa..8d083ea2f1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -124,6 +124,8 @@ struct _GstVaapiDecoderClass { struct _GstVaapiDecoderUnit *unit); GstVaapiDecoderStatus (*end_frame)(GstVaapiDecoder *decoder); GstVaapiDecoderStatus (*flush)(GstVaapiDecoder *decoder); + GstVaapiDecoderStatus (*decode_codec_data)(GstVaapiDecoder *decoder, + const guchar *buf, guint buf_size); }; GType diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 1ff9193428..49b482d093 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2763,24 +2763,20 @@ decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) } static GstVaapiDecoderStatus -decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) +gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder, + const guchar *buf, guint buf_size) { + GstVaapiDecoderH264 * const decoder = + GST_VAAPI_DECODER_H264_CAST(base_decoder); GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiDecoderStatus status; GstVaapiDecoderUnit unit; GstVaapiParserInfoH264 pi; GstH264ParserResult result; - guchar *buf; - guint buf_size; guint i, ofs, num_sps, num_pps; unit.parsed_info = π - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - if (!buf || buf_size == 0) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - if (buf_size < 8) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; @@ -2836,7 +2832,6 @@ ensure_decoder(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiDecoderStatus status; - GstBuffer *codec_data; g_return_val_if_fail(priv->is_constructed, GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); @@ -2846,12 +2841,10 @@ ensure_decoder(GstVaapiDecoderH264 *decoder) if (!priv->is_opened) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; - codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); - if (codec_data) { - status = decode_codec_data(decoder, codec_data); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } + status = gst_vaapi_decoder_decode_codec_data( + GST_VAAPI_DECODER_CAST(decoder)); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; } return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -3091,6 +3084,9 @@ gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass) decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame; decoder_class->end_frame = gst_vaapi_decoder_h264_end_frame; decoder_class->flush = gst_vaapi_decoder_h264_flush; + + decoder_class->decode_codec_data = + gst_vaapi_decoder_h264_decode_codec_data; } static void diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index c3dd265eb1..1c4272e63a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -41,6 +41,9 @@ G_DEFINE_TYPE(GstVaapiDecoderMpeg4, gst_vaapi_decoder_mpeg4, GST_VAAPI_TYPE_DECODER) +#define GST_VAAPI_DECODER_MPEG4_CAST(decoder) \ + ((GstVaapiDecoderMpeg4 *)(decoder)) + #define GST_VAAPI_DECODER_MPEG4_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ GST_VAAPI_TYPE_DECODER_MPEG4, \ @@ -921,14 +924,15 @@ decode_buffer(GstVaapiDecoderMpeg4 *decoder, const guchar *buf, guint buf_size) } static GstVaapiDecoderStatus -decode_codec_data(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) +gst_vaapi_decoder_mpeg4_decode_codec_data(GstVaapiDecoder *base_decoder, + const guchar *_buf, guint _buf_size) { + GstVaapiDecoderMpeg4 * const decoder = + GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); GstVaapiDecoderStatus status; - guchar *buf, *_buf; - guint pos, buf_size, _buf_size; + guchar *buf; + guint pos, buf_size; - _buf = GST_BUFFER_DATA(buffer); - _buf_size = GST_BUFFER_SIZE(buffer); // add additional 0x000001b2 to enclose the last header buf_size = _buf_size + 4; buf = malloc(buf_size); @@ -965,7 +969,6 @@ ensure_decoder(GstVaapiDecoderMpeg4 *decoder) { GstVaapiDecoderMpeg4Private * const priv = decoder->priv; GstVaapiDecoderStatus status; - GstBuffer *codec_data; g_return_val_if_fail(priv->is_constructed, GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); @@ -975,12 +978,10 @@ ensure_decoder(GstVaapiDecoderMpeg4 *decoder) if (!priv->is_opened) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; - codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); - if (codec_data) { - status = decode_codec_data(decoder, codec_data); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } + status = gst_vaapi_decoder_decode_codec_data( + GST_VAAPI_DECODER_CAST(decoder)); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; } return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1137,6 +1138,9 @@ gst_vaapi_decoder_mpeg4_class_init(GstVaapiDecoderMpeg4Class *klass) decoder_class->parse = gst_vaapi_decoder_mpeg4_parse; decoder_class->decode = gst_vaapi_decoder_mpeg4_decode; + + decoder_class->decode_codec_data = + gst_vaapi_decoder_mpeg4_decode_codec_data; } static void diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index bb4e02ba08..4bf4afe1d7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -222,6 +222,10 @@ G_GNUC_INTERNAL GstVaapiDecoderStatus gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder); +G_GNUC_INTERNAL +GstVaapiDecoderStatus +gst_vaapi_decoder_decode_codec_data(GstVaapiDecoder *decoder); + G_END_DECLS #endif /* GST_VAAPI_DECODER_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 754729076b..b951d3f8a6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -42,6 +42,9 @@ G_DEFINE_TYPE(GstVaapiDecoderVC1, gst_vaapi_decoder_vc1, GST_VAAPI_TYPE_DECODER) +#define GST_VAAPI_DECODER_VC1_CAST(decoder) \ + ((GstVaapiDecoderVC1 *)(decoder)) + #define GST_VAAPI_DECODER_VC1_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ GST_VAAPI_TYPE_DECODER_VC1, \ @@ -1061,8 +1064,11 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) } static GstVaapiDecoderStatus -decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) +gst_vaapi_decoder_vc1_decode_codec_data(GstVaapiDecoder *base_decoder, + const guchar *buf, guint buf_size) { + GstVaapiDecoderVC1 * const decoder = + GST_VAAPI_DECODER_VC1_CAST(base_decoder); GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVaapiDecoderStatus status; @@ -1070,16 +1076,12 @@ decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) GstVC1BDU ebdu; GstCaps *caps; GstStructure *structure; - guchar *buf; - guint buf_size, ofs; + guint ofs; gint width, height; guint32 format; gint version; - buf = GST_BUFFER_DATA(buffer); - buf_size = GST_BUFFER_SIZE(buffer); - if (!buf || buf_size == 0) - return GST_VAAPI_DECODER_STATUS_SUCCESS; + priv->has_codec_data = TRUE; width = GST_VAAPI_DECODER_WIDTH(decoder); height = GST_VAAPI_DECODER_HEIGHT(decoder); @@ -1109,7 +1111,7 @@ decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer) ebdu.size = buf_size; ebdu.sc_offset = 0; ebdu.offset = 0; - ebdu.data = buf; + ebdu.data = (guint8 *)buf; return decode_ebdu(decoder, &ebdu); } @@ -1149,7 +1151,6 @@ ensure_decoder(GstVaapiDecoderVC1 *decoder) { GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVaapiDecoderStatus status; - GstBuffer *codec_data; g_return_val_if_fail(priv->is_constructed, GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); @@ -1159,13 +1160,10 @@ ensure_decoder(GstVaapiDecoderVC1 *decoder) if (!priv->is_opened) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; - codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); - if (codec_data) { - status = decode_codec_data(decoder, codec_data); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - priv->has_codec_data = TRUE; - } + status = gst_vaapi_decoder_decode_codec_data( + GST_VAAPI_DECODER_CAST(decoder)); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; } return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1355,6 +1353,9 @@ gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass) decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame; decoder_class->end_frame = gst_vaapi_decoder_vc1_end_frame; decoder_class->flush = gst_vaapi_decoder_vc1_flush; + + decoder_class->decode_codec_data = + gst_vaapi_decoder_vc1_decode_codec_data; } static void From 2c6e235e4df9e8b6c8f36f5a239fe9734507a044 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Mar 2013 13:43:46 +0100 Subject: [PATCH 1110/3781] jpeg: propagate buffer data as a const guchar * pointer (cosmetics). --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 5fc7f16024..f1976a52c3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -314,7 +314,7 @@ static GstVaapiDecoderStatus decode_picture( GstVaapiDecoderJpeg *decoder, guint8 profile, - guchar *buf, + const guchar *buf, guint buf_size ) { @@ -368,7 +368,7 @@ decode_picture( static GstVaapiDecoderStatus decode_huffman_table( GstVaapiDecoderJpeg *decoder, - guchar *buf, + const guchar *buf, guint buf_size ) { @@ -385,7 +385,7 @@ decode_huffman_table( static GstVaapiDecoderStatus decode_quant_table( GstVaapiDecoderJpeg *decoder, - guchar *buf, + const guchar *buf, guint buf_size ) { @@ -402,7 +402,7 @@ decode_quant_table( static GstVaapiDecoderStatus decode_restart_interval( GstVaapiDecoderJpeg *decoder, - guchar *buf, + const guchar *buf, guint buf_size ) { @@ -418,10 +418,11 @@ decode_restart_interval( static GstVaapiDecoderStatus decode_scan( GstVaapiDecoderJpeg *decoder, - guchar *scan_header, + const guchar *scan_header, guint scan_header_size, - guchar *scan_data, - guint scan_data_size) + const guchar *scan_data, + guint scan_data_size +) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstVaapiPicture *picture = priv->current_picture; @@ -490,7 +491,7 @@ decode_scan( } static GstVaapiDecoderStatus -decode_buffer(GstVaapiDecoderJpeg *decoder, guchar *buf, guint buf_size) +decode_buffer(GstVaapiDecoderJpeg *decoder, const guchar *buf, guint buf_size) { GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; @@ -679,7 +680,7 @@ gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderStatus status; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; - guchar *buf; + const guchar *buf; guint buf_size; status = ensure_decoder(decoder); From 2000d5d6e12e9bddaeb4180311ae0d8c18f28c9c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Mar 2013 13:32:15 +0100 Subject: [PATCH 1111/3781] vc1: fix use of possibly uninitialized variable. In decode_codec_data(), force initialization of format to zero so that we can catch up cases where codec-data has neither "format" nor "wmvversion" fields, thus making it possible to gracefully fail in this case. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index b951d3f8a6..702abcbf68 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1097,6 +1097,8 @@ gst_vaapi_decoder_vc1_decode_codec_data(GstVaapiDecoder *base_decoder, if (gst_structure_get_int(structure, "wmvversion", &version)) format = (version >= 1 && version <= 3) ? GST_MAKE_FOURCC('W','M','V',('0'+version)) : 0; + else + format = 0; } if (!format) { GST_ERROR("failed to parse profile from codec-data"); From 17e7e67c1fbeef6358f6a17eeebb3961c3c50848 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Mar 2013 16:09:42 +0100 Subject: [PATCH 1112/3781] plugins: integrate GstVaapiVideoConverterGLX from libgstvaapi. Make sure libgstvaapi core decoding library doesn't include un-needed dependencies. So, move out GstVaapiVideoConverterGLX to plugins instead. Besides, even if the vaapisink element is not used, we are bound to have a correctly populated GstSurfaceBuffer from vaapidecode. Also clean-up the file along the way. --- gst-libs/gst/vaapi/Makefile.am | 2 - .../gst/vaapi/gstvaapivideoconverter_glx.c | 142 ---------------- .../gst/vaapi/gstvaapivideoconverter_glx.h | 75 --------- gst/vaapi/Makefile.am | 12 +- gst/vaapi/gstvaapipluginbuffer.c | 2 +- gst/vaapi/gstvaapivideoconverter_glx.c | 154 ++++++++++++++++++ gst/vaapi/gstvaapivideoconverter_glx.h | 90 ++++++++++ 7 files changed, 255 insertions(+), 222 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c delete mode 100644 gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h create mode 100644 gst/vaapi/gstvaapivideoconverter_glx.c create mode 100644 gst/vaapi/gstvaapivideoconverter_glx.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f007b0f2f4..68bb260852 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -170,14 +170,12 @@ libgstvaapi_glx_source_c = \ gstvaapiutils.c \ gstvaapiutils_glx.c \ gstvaapiutils_x11.c \ - gstvaapivideoconverter_glx.c \ gstvaapiwindow_glx.c \ $(NULL) libgstvaapi_glx_source_h = \ gstvaapidisplay_glx.h \ gstvaapitexture.h \ - gstvaapivideoconverter_glx.h \ gstvaapiwindow_glx.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c deleted file mode 100644 index afb6e6ed8a..0000000000 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * gstvaapivideoconverter_glx.c - Gst VA video converter - * - * Copyright (C) 2011-2013 Intel Corporation - * Copyright (C) 2011 Collabora Ltd. - * Author: Nicolas Dufresne - * - * 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 -#include "gstvaapivideoconverter_glx.h" -#include "gstvaapivideobuffer.h" -#include "gstvaapitexture.h" - -static void gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoConverterGLX, gst_vaapi_video_converter_glx, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (GST_TYPE_SURFACE_CONVERTER, - gst_vaapi_video_converter_glx_iface_init)) - -struct _GstVaapiVideoConverterGLXPrivate { - GstVaapiTexture *texture; -}; - -static void -gst_vaapi_video_converter_glx_dispose(GObject *object) -{ - GstVaapiVideoConverterGLXPrivate *priv = - GST_VAAPI_VIDEO_CONVERTER_GLX (object)->priv; - - g_clear_object(&priv->texture); - - G_OBJECT_CLASS (gst_vaapi_video_converter_glx_parent_class)->dispose (object); -} - -static void -gst_vaapi_video_converter_glx_class_init(GstVaapiVideoConverterGLXClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (GstVaapiVideoConverterGLXPrivate)); - object_class->dispose = gst_vaapi_video_converter_glx_dispose; -} - -static void -gst_vaapi_video_converter_glx_init(GstVaapiVideoConverterGLX *buffer) -{ - buffer->priv = G_TYPE_INSTANCE_GET_PRIVATE(buffer, - GST_VAAPI_TYPE_VIDEO_CONVERTER, - GstVaapiVideoConverterGLXPrivate); -} - -static void -gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface *iface) { - iface->upload = gst_vaapi_video_converter_glx_upload; -} - -/** - * gst_vaapi_video_converter_glx_new: - * @surface: the #GstSurfaceBuffer - * @type: type of the target buffer (must be "opengl") - * @dest: target of the conversion (must be GL texture id) - * - * Creates an empty #GstBuffer. The caller is responsible for - * completing the initialization of the buffer with the - * gst_vaapi_video_converter_glx_set_*() functions. - * - * Return value: the newly allocated #GstBuffer, or %NULL on error - */ -GstSurfaceConverter * -gst_vaapi_video_converter_glx_new(GstSurfaceBuffer *surface, const gchar *type, - GValue *dest) -{ - GstVaapiVideoMeta * const meta = - gst_vaapi_video_buffer_get_meta(GST_VAAPI_VIDEO_BUFFER(surface)); - GstVaapiTexture *texture; - GstVaapiVideoConverterGLX *converter; - - /* We only support Open GL texture conversion */ - if (strcmp(type, "opengl") || !G_VALUE_HOLDS_UINT(dest)) - return NULL; - - /* FIXME Should we assume target and format ? */ - texture = gst_vaapi_texture_new_with_texture( - gst_vaapi_video_meta_get_display(meta), - g_value_get_uint(dest), GL_TEXTURE_2D, GL_BGRA); - if (!texture) - return NULL; - - converter = g_object_new(GST_VAAPI_TYPE_VIDEO_CONVERTER, NULL); - converter->priv->texture = texture; - return GST_SURFACE_CONVERTER(converter); -} - -gboolean -gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *converter, - GstSurfaceBuffer *buffer) -{ - GstVaapiVideoConverterGLXPrivate *priv = - GST_VAAPI_VIDEO_CONVERTER_GLX (converter)->priv; - GstVaapiVideoMeta * const meta = - gst_vaapi_video_buffer_get_meta (GST_VAAPI_VIDEO_BUFFER (buffer)); - GstVaapiSurface *surface = gst_vaapi_video_meta_get_surface (meta); - GstVaapiDisplay *new_dpy, *old_dpy; - GstVideoOverlayComposition * const composition = - gst_video_buffer_get_overlay_composition (GST_BUFFER (buffer)); - - new_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); - old_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (priv->texture)); - - if (old_dpy != new_dpy) { - guint texture = gst_vaapi_texture_get_id (priv->texture); - g_object_unref (priv->texture); - priv->texture = gst_vaapi_texture_new_with_texture (new_dpy, - texture, - GL_TEXTURE_2D, - GL_BGRA); - } - - if (!gst_vaapi_surface_set_subpictures_from_composition (surface, - composition, TRUE)) - GST_WARNING ("could not update subtitles"); - - return gst_vaapi_texture_put_surface (priv->texture, surface, - gst_vaapi_video_meta_get_render_flags (meta)); -} diff --git a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h b/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h deleted file mode 100644 index 67d0f2e7e0..0000000000 --- a/gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * gstvaapivideoconverter_glx.h - Gstreamer/VA video converter - * - * Copyright (C) 2011-2012 Intel Corporation - * Copyright (C) 2011 Collabora Ltd. - * Author: Nicolas Dufresne - * - * 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_VIDEO_CONVERTER_GLX_H -#define GST_VAAPI_VIDEO_CONVERTER_GLX_H - -#include - -G_BEGIN_DECLS - -#define GST_VAAPI_TYPE_VIDEO_CONVERTER (gst_vaapi_video_converter_glx_get_type ()) -#define GST_VAAPI_VIDEO_CONVERTER_GLX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER, GstVaapiVideoConverterGLX)) -#define GST_VAAPI_VIDEO_CONVERTER_GLX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER, GstVaapiVideoConverterGLXClass)) -#define GST_VAAPI_IS_VIDEO_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER)) -#define GST_VAAPI_IS_VIDEO_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER)) -#define GST_VAAPI_VIDEO_CONVERTER_GLX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER, GstVaapiVideoConverterGLXClass)) - -typedef struct _GstVaapiVideoConverterGLX GstVaapiVideoConverterGLX; -typedef struct _GstVaapiVideoConverterGLXPrivate GstVaapiVideoConverterGLXPrivate; -typedef struct _GstVaapiVideoConverterGLXClass GstVaapiVideoConverterGLXClass; - -/** - * GstVaapiVideoConverterGLX: - * - * Converter to transform VA buffers into GL textures. - */ -struct _GstVaapiVideoConverterGLX { - /*< private >*/ - GObject parent_instance; - - GstVaapiVideoConverterGLXPrivate *priv; -}; - -/** - * GstVaapiVideoConverterGLXClass: - * - * Converter to transform VA buffers into GL textures. - */ -struct _GstVaapiVideoConverterGLXClass { - /*< private >*/ - GObjectClass parent_class; -}; - -GType gst_vaapi_video_converter_glx_get_type (void) G_GNUC_CONST; - -GstSurfaceConverter *gst_vaapi_video_converter_glx_new (GstSurfaceBuffer *buffer, - const gchar *type, - GValue *dest); - -gboolean gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *self, - GstSurfaceBuffer *buffer); - -G_END_DECLS - -#endif /* GST_VAAPI_VIDEO_CONVERTER_GLX_H */ diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index e1462bf124..67b95fbebe 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -29,7 +29,7 @@ libgstvaapi_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-$(GST_API_VERSION).la endif -libgstvaapi_la_SOURCES = \ +libgstvaapi_source_c = \ gstvaapi.c \ gstvaapidecode.c \ gstvaapidownload.c \ @@ -41,7 +41,7 @@ libgstvaapi_la_SOURCES = \ gstvaapiuploader.c \ $(NULL) -noinst_HEADERS = \ +libgstvaapi_source_h = \ gstvaapidecode.h \ gstvaapidownload.h \ gstvaapipluginbuffer.h \ @@ -52,6 +52,14 @@ noinst_HEADERS = \ gstvaapiuploader.h \ $(NULL) +if USE_GLX +libgstvaapi_source_c += gstvaapivideoconverter_glx.c +libgstvaapi_source_h += gstvaapivideoconverter_glx.h +endif + +libgstvaapi_la_SOURCES = $(libgstvaapi_source_c) +noinst_HEADERS = $(libgstvaapi_source_h) + libgstvaapi_la_CFLAGS = \ $(libgstvaapi_CFLAGS) \ $(GST_CFLAGS) \ diff --git a/gst/vaapi/gstvaapipluginbuffer.c b/gst/vaapi/gstvaapipluginbuffer.c index 37171edf1d..766978f364 100644 --- a/gst/vaapi/gstvaapipluginbuffer.c +++ b/gst/vaapi/gstvaapipluginbuffer.c @@ -23,7 +23,7 @@ #include #include #if USE_GLX -# include +# include "gstvaapivideoconverter_glx.h" #endif #include "gstvaapipluginbuffer.h" diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c new file mode 100644 index 0000000000..842225695c --- /dev/null +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -0,0 +1,154 @@ +/* + * gstvaapivideoconverter_glx.c - Gst VA video converter + * + * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011 Collabora Ltd. + * Author: Nicolas Dufresne + * + * 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 "gst/vaapi/sysdeps.h" +#include +#include +#include "gstvaapivideoconverter_glx.h" + +typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *, + GstSurfaceBuffer *); + +static void +gst_vaapi_video_converter_glx_iface_init(GstSurfaceConverterInterface *iface); + +G_DEFINE_TYPE_WITH_CODE( + GstVaapiVideoConverterGLX, + gst_vaapi_video_converter_glx, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(GST_TYPE_SURFACE_CONVERTER, + gst_vaapi_video_converter_glx_iface_init)) + +#define GST_VAAPI_VIDEO_CONVERTER_GLX_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ + GstVaapiVideoConverterGLXPrivate)) + +struct _GstVaapiVideoConverterGLXPrivate { + GstVaapiTexture *texture; +}; + +static gboolean +gst_vaapi_video_converter_glx_upload(GstSurfaceConverter *self, + GstBuffer *buffer); + +static void +gst_vaapi_video_converter_glx_dispose(GObject *object) +{ + GstVaapiVideoConverterGLXPrivate * const priv = + GST_VAAPI_VIDEO_CONVERTER_GLX(object)->priv; + + g_clear_object(&priv->texture); + + G_OBJECT_CLASS(gst_vaapi_video_converter_glx_parent_class)->dispose(object); +} + +static void +gst_vaapi_video_converter_glx_class_init(GstVaapiVideoConverterGLXClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiVideoConverterGLXPrivate)); + + object_class->dispose = gst_vaapi_video_converter_glx_dispose; +} + +static void +gst_vaapi_video_converter_glx_init(GstVaapiVideoConverterGLX *buffer) +{ + buffer->priv = GST_VAAPI_VIDEO_CONVERTER_GLX_GET_PRIVATE(buffer); +} + +static void +gst_vaapi_video_converter_glx_iface_init(GstSurfaceConverterInterface *iface) +{ + iface->upload = (GstSurfaceUploadFunction) + gst_vaapi_video_converter_glx_upload; +} + +/** + * gst_vaapi_video_converter_glx_new: + * @surface: the #GstSurfaceBuffer + * @type: type of the target buffer (must be "opengl") + * @dest: target of the conversion (must be GL texture id) + * + * Creates an empty #GstBuffer. The caller is responsible for + * completing the initialization of the buffer with the + * gst_vaapi_video_converter_glx_set_*() functions. + * + * Return value: the newly allocated #GstBuffer, or %NULL on error + */ +GstSurfaceConverter * +gst_vaapi_video_converter_glx_new(GstBuffer *buffer, const gchar *type, + GValue *dest) +{ + GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); + GstVaapiTexture *texture; + GstVaapiVideoConverterGLX *converter; + + /* We only support Open GL texture conversion */ + if (strcmp(type, "opengl") != 0 || !G_VALUE_HOLDS_UINT(dest)) + return NULL; + + /* FIXME Should we assume target and format ? */ + texture = gst_vaapi_texture_new_with_texture( + gst_vaapi_video_meta_get_display(meta), + g_value_get_uint(dest), GL_TEXTURE_2D, GL_BGRA); + if (!texture) + return NULL; + + converter = g_object_new(GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, NULL); + converter->priv->texture = texture; + return GST_SURFACE_CONVERTER(converter); +} + +gboolean +gst_vaapi_video_converter_glx_upload(GstSurfaceConverter *self, + GstBuffer *buffer) +{ + GstVaapiVideoConverterGLXPrivate * const priv = + GST_VAAPI_VIDEO_CONVERTER_GLX(self)->priv; + GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); + GstVaapiSurface * const surface = gst_vaapi_video_meta_get_surface(meta); + GstVaapiDisplay *new_dpy, *old_dpy; + GstVideoOverlayComposition * const composition = + gst_video_buffer_get_overlay_composition(buffer); + + new_dpy = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); + old_dpy = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(priv->texture)); + + if (old_dpy != new_dpy) { + const guint texture = gst_vaapi_texture_get_id(priv->texture); + + g_clear_object(&priv->texture); + priv->texture = gst_vaapi_texture_new_with_texture(new_dpy, + texture, GL_TEXTURE_2D, GL_BGRA); + } + + if (!gst_vaapi_surface_set_subpictures_from_composition(surface, + composition, TRUE)) + GST_WARNING("could not update subtitles"); + + return gst_vaapi_texture_put_surface(priv->texture, surface, + gst_vaapi_video_meta_get_render_flags(meta)); +} diff --git a/gst/vaapi/gstvaapivideoconverter_glx.h b/gst/vaapi/gstvaapivideoconverter_glx.h new file mode 100644 index 0000000000..70e2edf1ae --- /dev/null +++ b/gst/vaapi/gstvaapivideoconverter_glx.h @@ -0,0 +1,90 @@ +/* + * gstvaapivideoconverter_glx.h - Gstreamer/VA video converter + * + * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011 Collabora Ltd. + * Author: Nicolas Dufresne + * + * 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_VIDEO_CONVERTER_GLX_H +#define GST_VAAPI_VIDEO_CONVERTER_GLX_H + +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX \ + (gst_vaapi_video_converter_glx_get_type ()) + +#define GST_VAAPI_VIDEO_CONVERTER_GLX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ + GstVaapiVideoConverterGLX)) + +#define GST_VAAPI_VIDEO_CONVERTER_GLX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ + GstVaapiVideoConverterGLXClass)) + +#define GST_VAAPI_IS_VIDEO_CONVERTER_GLX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX)) + +#define GST_VAAPI_IS_VIDEO_CONVERTER_GLX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX)) + +#define GST_VAAPI_VIDEO_CONVERTER_GLX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ + GstVaapiVideoConverterGLXClass)) + +typedef struct _GstVaapiVideoConverterGLX GstVaapiVideoConverterGLX; +typedef struct _GstVaapiVideoConverterGLXPrivate GstVaapiVideoConverterGLXPrivate; +typedef struct _GstVaapiVideoConverterGLXClass GstVaapiVideoConverterGLXClass; + +/** + * GstVaapiVideoConverterGLX: + * + * Converter to transform VA buffers into GL textures. + */ +struct _GstVaapiVideoConverterGLX { + /*< private >*/ + GObject parent_instance; + + GstVaapiVideoConverterGLXPrivate *priv; +}; + +/** + * GstVaapiVideoConverterGLXClass: + * + * Converter class to transform VA buffers into GL textures. + */ +struct _GstVaapiVideoConverterGLXClass { + /*< private >*/ + GObjectClass parent_class; +}; + +GType +gst_vaapi_video_converter_glx_get_type(void) G_GNUC_CONST; + +GstSurfaceConverter * +gst_vaapi_video_converter_glx_new(GstBuffer *buffer, const gchar *type, + GValue *dest); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_CONVERTER_GLX_H */ From 95b865968c6d76dd9a860f18eb90512f06b2d7a7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Mar 2013 16:32:43 +0100 Subject: [PATCH 1113/3781] plugins: use common helper function to apply compositions. Use common gst_vaapi_apply_composition() helper function to apply compositions attached to a buffer in vaapisink or GstVaapiVideoConverterGLX. --- gst/vaapi/gstvaapipluginutil.c | 12 ++++++++++++ gst/vaapi/gstvaapipluginutil.h | 5 +++++ gst/vaapi/gstvaapisink.c | 14 +------------- gst/vaapi/gstvaapivideoconverter_glx.c | 6 ++---- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 4ee73ad64e..d42fa21943 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -328,3 +328,15 @@ gst_vaapi_append_surface_caps(GstCaps *out_caps, GstCaps *in_caps) } return TRUE; } + +gboolean +gst_vaapi_apply_composition(GstVaapiSurface *surface, GstBuffer *buffer) +{ + GstVideoOverlayComposition * const composition = + gst_video_buffer_get_overlay_composition(buffer); + + if (!composition) + return FALSE; + return gst_vaapi_surface_set_subpictures_from_composition(surface, + composition, TRUE); +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 78f274f5c6..8cb70d17dd 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -25,6 +25,7 @@ #define GST_VAAPI_PLUGIN_UTIL_H #include +#include G_GNUC_INTERNAL gboolean @@ -50,6 +51,10 @@ G_GNUC_INTERNAL gboolean gst_vaapi_append_surface_caps (GstCaps *out_caps, GstCaps *in_caps); +G_GNUC_INTERNAL +gboolean +gst_vaapi_apply_composition(GstVaapiSurface *surface, GstBuffer *buffer); + #ifndef G_PRIMITIVE_SWAP #define G_PRIMITIVE_SWAP(type, a, b) do { \ const type t = a; a = b; b = t; \ diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 28aca3e524..ff062ba006 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -832,18 +832,6 @@ gst_vaapisink_put_surface( return TRUE; } -static inline gboolean -set_composition_from_buffer(GstVaapiSurface *surface, GstBuffer *buffer) -{ - GstVideoOverlayComposition * const composition = - gst_video_buffer_get_overlay_composition(buffer); - - if (!composition) - return FALSE; - return gst_vaapi_surface_set_subpictures_from_composition(surface, - composition, TRUE); -} - static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) { @@ -893,7 +881,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) flags = gst_vaapi_video_meta_get_render_flags(meta); - if (!set_composition_from_buffer(surface, src_buffer)) + if (!gst_vaapi_apply_composition(surface, src_buffer)) GST_WARNING("could not update subtitles"); switch (sink->display_type) { diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index 842225695c..7cbd65479d 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -25,6 +25,7 @@ #include #include #include "gstvaapivideoconverter_glx.h" +#include "gstvaapipluginutil.h" typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *, GstSurfaceBuffer *); @@ -131,8 +132,6 @@ gst_vaapi_video_converter_glx_upload(GstSurfaceConverter *self, GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); GstVaapiSurface * const surface = gst_vaapi_video_meta_get_surface(meta); GstVaapiDisplay *new_dpy, *old_dpy; - GstVideoOverlayComposition * const composition = - gst_video_buffer_get_overlay_composition(buffer); new_dpy = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); old_dpy = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(priv->texture)); @@ -145,8 +144,7 @@ gst_vaapi_video_converter_glx_upload(GstSurfaceConverter *self, texture, GL_TEXTURE_2D, GL_BGRA); } - if (!gst_vaapi_surface_set_subpictures_from_composition(surface, - composition, TRUE)) + if (!gst_vaapi_apply_composition(surface, buffer)) GST_WARNING("could not update subtitles"); return gst_vaapi_texture_put_surface(priv->texture, surface, From 4cf44e3ad28d5c9f80769784dfc2ff8cefdab976 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Mar 2013 17:06:43 +0100 Subject: [PATCH 1114/3781] plugins: integrate GstVaapiVideoBuffer from libgstvaapi. Move GstVaapiVideoBuffer from core libgstvaapi decoding library to the actual plugin elements. That's only useful there. --- docs/reference/libs/libs-sections.txt | 17 ---- docs/reference/libs/libs.core.types | 1 - gst-libs/gst/vaapi/Makefile.am | 2 - gst-libs/gst/vaapi/gstvaapivideobuffer.h | 91 ------------------- gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapidownload.h | 1 - gst/vaapi/gstvaapipluginbuffer.c | 2 +- gst/vaapi/gstvaapipostproc.h | 1 - .../gst => gst}/vaapi/gstvaapivideobuffer.c | 74 ++++++++++----- gst/vaapi/gstvaapivideobuffer.h | 42 +++++++++ gst/vaapi/gstvaapivideoconverter_glx.h | 1 + 11 files changed, 99 insertions(+), 135 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapivideobuffer.h rename {gst-libs/gst => gst}/vaapi/gstvaapivideobuffer.c (62%) create mode 100644 gst/vaapi/gstvaapivideobuffer.h diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 11c742f6d6..71e1ab9f67 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -171,23 +171,6 @@ GST_VAAPI_IS_IMAGE_POOL_CLASS GST_VAAPI_IMAGE_POOL_GET_CLASS
-
-gstvaapivideobuffer -GstVaapiVideoBuffer -GstVaapiVideoBuffer -GstVaapiVideoBufferClass -gst_vaapi_video_buffer_new -gst_vaapi_video_buffer_get_meta - -GST_VAAPI_VIDEO_BUFFER -GST_VAAPI_IS_VIDEO_BUFFER -GST_VAAPI_TYPE_VIDEO_BUFFER -gst_vaapi_video_buffer_get_type -GST_VAAPI_VIDEO_BUFFER_CLASS -GST_VAAPI_IS_VIDEO_BUFFER_CLASS -GST_VAAPI_VIDEO_BUFFER_GET_CLASS -
-
gstvaapivideometa GstVaapiVideoMeta diff --git a/docs/reference/libs/libs.core.types b/docs/reference/libs/libs.core.types index b4ce7dad6a..97954cf3ef 100644 --- a/docs/reference/libs/libs.core.types +++ b/docs/reference/libs/libs.core.types @@ -7,6 +7,5 @@ gst_vaapi_object_get_type gst_vaapi_subpicture_get_type gst_vaapi_surface_get_type gst_vaapi_surface_pool_get_type -gst_vaapi_video_buffer_get_type gst_vaapi_video_pool_get_type gst_vaapi_window_get_type diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 68bb260852..90ec07b839 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -68,7 +68,6 @@ libgstvaapi_source_c = \ gstvaapisurfaceproxy.c \ gstvaapiutils.c \ gstvaapivalue.c \ - gstvaapivideobuffer.c \ gstvaapivideometa.c \ gstvaapivideopool.c \ gstvaapiwindow.c \ @@ -95,7 +94,6 @@ libgstvaapi_source_h = \ gstvaapisurfaceproxy.h \ gstvaapitypes.h \ gstvaapivalue.h \ - gstvaapivideobuffer.h \ gstvaapivideometa.h \ gstvaapivideopool.h \ gstvaapiwindow.h \ diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.h b/gst-libs/gst/vaapi/gstvaapivideobuffer.h deleted file mode 100644 index adc88d0024..0000000000 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * gstvaapivideobuffer.h - Gstreamer/VA video buffer - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2013 Intel Corporation - * - * 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_VIDEO_BUFFER_H -#define GST_VAAPI_VIDEO_BUFFER_H - -#include -#include - -G_BEGIN_DECLS - -#define GST_VAAPI_TYPE_VIDEO_BUFFER \ - (gst_vaapi_video_buffer_get_type()) - -#define GST_VAAPI_VIDEO_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_VIDEO_BUFFER, \ - GstVaapiVideoBuffer)) - -#define GST_VAAPI_VIDEO_BUFFER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_VIDEO_BUFFER, \ - GstVaapiVideoBufferClass)) - -#define GST_VAAPI_IS_VIDEO_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_BUFFER)) - -#define GST_VAAPI_IS_VIDEO_BUFFER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_BUFFER)) - -#define GST_VAAPI_VIDEO_BUFFER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_VIDEO_BUFFER, \ - GstVaapiVideoBufferClass)) - -typedef struct _GstVaapiVideoBuffer GstVaapiVideoBuffer; -typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass; - -/** - * GstVaapiVideoBuffer: - * - * A #GstBuffer holding video objects (#GstVaapiSurface and #GstVaapiImage). - */ -struct _GstVaapiVideoBuffer { - /*< private >*/ - GstSurfaceBuffer parent_instance; - - GstVaapiVideoMeta *meta; -}; - -/** - * GstVaapiVideoBufferClass: - * - * A #GstBuffer holding video objects - */ -struct _GstVaapiVideoBufferClass { - /*< private >*/ - GstSurfaceBufferClass parent_class; -}; - -GType -gst_vaapi_video_buffer_get_type(void) G_GNUC_CONST; - -GstBuffer * -gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta); - -GstVaapiVideoMeta * -gst_vaapi_video_buffer_get_meta(GstVaapiVideoBuffer *buffer); - -G_END_DECLS - -#endif /* GST_VAAPI_VIDEO_BUFFER_H */ diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 67b95fbebe..f12a43ee3b 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -39,6 +39,7 @@ libgstvaapi_source_c = \ gstvaapisink.c \ gstvaapiupload.c \ gstvaapiuploader.c \ + gstvaapivideobuffer.c \ $(NULL) libgstvaapi_source_h = \ @@ -50,6 +51,7 @@ libgstvaapi_source_h = \ gstvaapisink.h \ gstvaapiupload.h \ gstvaapiuploader.h \ + gstvaapivideobuffer.h \ $(NULL) if USE_GLX diff --git a/gst/vaapi/gstvaapidownload.h b/gst/vaapi/gstvaapidownload.h index 7a594c4d85..28b58e73c2 100644 --- a/gst/vaapi/gstvaapidownload.h +++ b/gst/vaapi/gstvaapidownload.h @@ -28,7 +28,6 @@ #include #include #include -#include G_BEGIN_DECLS diff --git a/gst/vaapi/gstvaapipluginbuffer.c b/gst/vaapi/gstvaapipluginbuffer.c index 766978f364..e24676e8dc 100644 --- a/gst/vaapi/gstvaapipluginbuffer.c +++ b/gst/vaapi/gstvaapipluginbuffer.c @@ -21,11 +21,11 @@ #include "gst/vaapi/sysdeps.h" #include -#include #if USE_GLX # include "gstvaapivideoconverter_glx.h" #endif #include "gstvaapipluginbuffer.h" +#include "gstvaapivideobuffer.h" static GFunc get_surface_converter(GstVaapiDisplay *display) diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 4ad4f705f8..e983a312f6 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -26,7 +26,6 @@ #include #include #include -#include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c similarity index 62% rename from gst-libs/gst/vaapi/gstvaapivideobuffer.c rename to gst/vaapi/gstvaapivideobuffer.c index afb173cf6d..f5945eda32 100644 --- a/gst-libs/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -1,5 +1,5 @@ /* - * gstvaapivideobuffer.c - Gst VA video buffer + * gstvaapivideobuffer.c - Gstreamer/VA video buffer * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011-2013 Intel Corporation @@ -25,11 +25,60 @@ * @short_description: VA video buffer for GStreamer */ -#include "sysdeps.h" +#include "gst/vaapi/sysdeps.h" +#include #include "gstvaapivideobuffer.h" -#define DEBUG 1 -#include "gstvaapidebug.h" +#define GST_VAAPI_TYPE_VIDEO_BUFFER \ + (gst_vaapi_video_buffer_get_type()) + +#define GST_VAAPI_VIDEO_BUFFER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_VIDEO_BUFFER, \ + GstVaapiVideoBuffer)) + +#define GST_VAAPI_VIDEO_BUFFER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_VIDEO_BUFFER, \ + GstVaapiVideoBufferClass)) + +#define GST_VAAPI_IS_VIDEO_BUFFER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_BUFFER)) + +#define GST_VAAPI_IS_VIDEO_BUFFER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_BUFFER)) + +#define GST_VAAPI_VIDEO_BUFFER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_VIDEO_BUFFER, \ + GstVaapiVideoBufferClass)) + +typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass; + +/** + * GstVaapiVideoBuffer: + * + * A #GstBuffer holding video objects (#GstVaapiSurface and #GstVaapiImage). + */ +struct _GstVaapiVideoBuffer { + /*< private >*/ + GstSurfaceBuffer parent_instance; + + GstVaapiVideoMeta *meta; +}; + +/** + * GstVaapiVideoBufferClass: + * + * A #GstBuffer holding video objects + */ +struct _GstVaapiVideoBufferClass { + /*< private >*/ + GstSurfaceBufferClass parent_class; +}; + +GType +gst_vaapi_video_buffer_get_type(void) G_GNUC_CONST; G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, @@ -65,14 +114,6 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) { } -/** - * gst_vaapi_video_buffer_new: - * @meta: a #GstVaapiVideoMeta - * - * Creates a #GstBuffer that holds video @meta information. - * - * Return value: the newly allocated #GstBuffer, or %NULL or error - */ GstBuffer * gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta) { @@ -88,15 +129,6 @@ gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta) return buffer; } -/** - * gst_vaapi_video_buffer_get_meta: - * @buffer: a #GstVaapiVideoBuffer - * - * Returns the #GstVaapiVideoMeta associated to this @buffer. - * - * Return value: the #GstVaapiVideoMeta bound to the @buffer, or %NULL - * if none was found - */ GstVaapiVideoMeta * gst_vaapi_video_buffer_get_meta(GstVaapiVideoBuffer *buffer) { diff --git a/gst/vaapi/gstvaapivideobuffer.h b/gst/vaapi/gstvaapivideobuffer.h new file mode 100644 index 0000000000..52d6eb7c99 --- /dev/null +++ b/gst/vaapi/gstvaapivideobuffer.h @@ -0,0 +1,42 @@ +/* + * gstvaapivideobuffer.h - Gstreamer/VA video buffer + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2013 Intel Corporation + * + * 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_VIDEO_BUFFER_H +#define GST_VAAPI_VIDEO_BUFFER_H + +#include + +G_BEGIN_DECLS + +typedef struct _GstVaapiVideoBuffer GstVaapiVideoBuffer; + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta); + +G_GNUC_INTERNAL +GstVaapiVideoMeta * +gst_vaapi_video_buffer_get_meta(GstVaapiVideoBuffer *buffer); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_BUFFER_H */ diff --git a/gst/vaapi/gstvaapivideoconverter_glx.h b/gst/vaapi/gstvaapivideoconverter_glx.h index 70e2edf1ae..97aa6556c8 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.h +++ b/gst/vaapi/gstvaapivideoconverter_glx.h @@ -25,6 +25,7 @@ #define GST_VAAPI_VIDEO_CONVERTER_GLX_H #include +#include "gstvaapivideobuffer.h" G_BEGIN_DECLS From 63fedf67676275b8842e88f08a4590fa29b76fcf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Mar 2013 17:17:53 +0100 Subject: [PATCH 1115/3781] plugins: drop gstvaapipluginbuffer.[ch] helper files. Move all gst_vaapi_video_buffer_new*() helpers from gstvaapipluginbuffer.[ch] to gstvaapivideobuffer.[ch], and drop the obsolete files. --- gst/vaapi/Makefile.am | 2 - gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapidownload.c | 2 +- gst/vaapi/gstvaapipluginbuffer.c | 96 -------------------------------- gst/vaapi/gstvaapipluginbuffer.h | 45 --------------- gst/vaapi/gstvaapipostproc.c | 2 +- gst/vaapi/gstvaapiupload.c | 2 +- gst/vaapi/gstvaapiuploader.c | 2 +- gst/vaapi/gstvaapivideobuffer.c | 67 ++++++++++++++++++++-- gst/vaapi/gstvaapivideobuffer.h | 18 +++++- 10 files changed, 83 insertions(+), 155 deletions(-) delete mode 100644 gst/vaapi/gstvaapipluginbuffer.c delete mode 100644 gst/vaapi/gstvaapipluginbuffer.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index f12a43ee3b..b2e442c4ff 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -33,7 +33,6 @@ libgstvaapi_source_c = \ gstvaapi.c \ gstvaapidecode.c \ gstvaapidownload.c \ - gstvaapipluginbuffer.c \ gstvaapipluginutil.c \ gstvaapipostproc.c \ gstvaapisink.c \ @@ -45,7 +44,6 @@ libgstvaapi_source_c = \ libgstvaapi_source_h = \ gstvaapidecode.h \ gstvaapidownload.h \ - gstvaapipluginbuffer.h \ gstvaapipluginutil.h \ gstvaapipostproc.h \ gstvaapisink.h \ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 508a32356d..8d19182aef 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -35,7 +35,7 @@ #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" -#include "gstvaapipluginbuffer.h" +#include "gstvaapivideobuffer.h" #include #include diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 3000fd91eb..9bb032f8e3 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -35,7 +35,7 @@ #include "gstvaapidownload.h" #include "gstvaapipluginutil.h" -#include "gstvaapipluginbuffer.h" +#include "gstvaapivideobuffer.h" #define GST_PLUGIN_NAME "vaapidownload" #define GST_PLUGIN_DESC "A VA to video flow filter" diff --git a/gst/vaapi/gstvaapipluginbuffer.c b/gst/vaapi/gstvaapipluginbuffer.c deleted file mode 100644 index e24676e8dc..0000000000 --- a/gst/vaapi/gstvaapipluginbuffer.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * gstvaapipluginbuffer.c - Private GStreamer/VA video buffers - * - * Copyright (C) 2012-2013 Intel Corporation - * - * 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 "gst/vaapi/sysdeps.h" -#include -#if USE_GLX -# include "gstvaapivideoconverter_glx.h" -#endif -#include "gstvaapipluginbuffer.h" -#include "gstvaapivideobuffer.h" - -static GFunc -get_surface_converter(GstVaapiDisplay *display) -{ - GFunc func; - - switch (gst_vaapi_display_get_display_type(display)) { -#if USE_GLX - case GST_VAAPI_DISPLAY_TYPE_GLX: - func = (GFunc)gst_vaapi_video_converter_glx_new; - break; -#endif - default: - func = NULL; - break; - } - return func; -} - -static GstBuffer * -get_buffer(GstVaapiVideoMeta *meta) -{ - GstBuffer *buffer; - - if (!meta) - return NULL; - - gst_vaapi_video_meta_set_surface_converter(meta, - get_surface_converter(gst_vaapi_video_meta_get_display(meta))); - - buffer = gst_vaapi_video_buffer_new(meta); - gst_vaapi_video_meta_unref(meta); - return buffer; -} - -GstBuffer * -gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) -{ - return get_buffer(gst_vaapi_video_meta_new_from_pool(pool)); -} - -GstBuffer * -gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) -{ - GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); - - if (!meta) - return NULL; - return get_buffer(gst_vaapi_video_meta_ref(meta)); -} - -GstBuffer * -gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) -{ - return get_buffer(gst_vaapi_video_meta_new_with_image(image)); -} - -GstBuffer * -gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) -{ - return get_buffer(gst_vaapi_video_meta_new_with_surface(surface)); -} - -GstBuffer * -gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) -{ - return get_buffer(gst_vaapi_video_meta_new_with_surface_proxy(proxy)); -} diff --git a/gst/vaapi/gstvaapipluginbuffer.h b/gst/vaapi/gstvaapipluginbuffer.h deleted file mode 100644 index d3a509f998..0000000000 --- a/gst/vaapi/gstvaapipluginbuffer.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * gstvaapipluginbuffer.h - Private GStreamer/VA video buffers - * - * Copyright (C) 2012-2013 Intel Corporation - * - * 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_PLUGIN_BUFFER_H -#define GST_VAAPI_PLUGIN_BUFFER_H - -G_GNUC_INTERNAL -GstBuffer * -gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); - -G_GNUC_INTERNAL -GstBuffer * -gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer); - -G_GNUC_INTERNAL -GstBuffer * -gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image); - -G_GNUC_INTERNAL -GstBuffer * -gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface); - -G_GNUC_INTERNAL -GstBuffer * -gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); - -#endif /* GST_VAAPI_PLUGIN_BUFFER_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index b0ea884c85..e2f0e5cad7 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -35,7 +35,7 @@ #include "gstvaapipostproc.h" #include "gstvaapipluginutil.h" -#include "gstvaapipluginbuffer.h" +#include "gstvaapivideobuffer.h" #define GST_PLUGIN_NAME "vaapipostproc" #define GST_PLUGIN_DESC "A video postprocessing filter" diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 4b4f7c9600..9ac8d7a589 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -36,7 +36,7 @@ #include "gstvaapiupload.h" #include "gstvaapipluginutil.h" -#include "gstvaapipluginbuffer.h" +#include "gstvaapivideobuffer.h" #define GST_PLUGIN_NAME "vaapiupload" #define GST_PLUGIN_DESC "A video to VA flow filter" diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 4ee4af18d6..1c898d37f9 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -29,7 +29,7 @@ #include #include "gstvaapiuploader.h" -#include "gstvaapipluginbuffer.h" +#include "gstvaapivideobuffer.h" #define GST_HELPER_NAME "vaapiupload" #define GST_HELPER_DESC "VA-API video uploader" diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index f5945eda32..27dd1fb2b6 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -28,6 +28,9 @@ #include "gst/vaapi/sysdeps.h" #include #include "gstvaapivideobuffer.h" +#if USE_GLX +# include "gstvaapivideoconverter_glx.h" +#endif #define GST_VAAPI_TYPE_VIDEO_BUFFER \ (gst_vaapi_video_buffer_get_type()) @@ -114,21 +117,73 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) { } -GstBuffer * -gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta) +static GFunc +get_surface_converter(GstVaapiDisplay *display) +{ + GFunc func; + + switch (gst_vaapi_display_get_display_type(display)) { +#if USE_GLX + case GST_VAAPI_DISPLAY_TYPE_GLX: + func = (GFunc)gst_vaapi_video_converter_glx_new; + break; +#endif + default: + func = NULL; + break; + } + return func; +} + +static GstBuffer * +new_vbuffer(GstVaapiVideoMeta *meta) { GstBuffer *buffer; g_return_val_if_fail(meta != NULL, NULL); - buffer = GST_BUFFER_CAST(gst_mini_object_new(GST_TYPE_SURFACE_BUFFER)); - if (!buffer) - return NULL; + gst_vaapi_video_meta_set_surface_converter(meta, + get_surface_converter(gst_vaapi_video_meta_get_display(meta))); - gst_buffer_set_vaapi_video_meta(buffer, meta); + buffer = GST_BUFFER_CAST(gst_mini_object_new(GST_TYPE_SURFACE_BUFFER)); + if (buffer) + gst_buffer_set_vaapi_video_meta(buffer, meta); + gst_vaapi_video_meta_unref(meta); return buffer; } +GstBuffer * +gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) +{ + return new_vbuffer(gst_vaapi_video_meta_new_from_pool(pool)); +} + +GstBuffer * +gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) +{ + GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); + + return meta ? new_vbuffer(gst_vaapi_video_meta_ref(meta)) : NULL; +} + +GstBuffer * +gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) +{ + return new_vbuffer(gst_vaapi_video_meta_new_with_image(image)); +} + +GstBuffer * +gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) +{ + return new_vbuffer(gst_vaapi_video_meta_new_with_surface(surface)); +} + +GstBuffer * +gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) +{ + return new_vbuffer(gst_vaapi_video_meta_new_with_surface_proxy(proxy)); +} + GstVaapiVideoMeta * gst_vaapi_video_buffer_get_meta(GstVaapiVideoBuffer *buffer) { diff --git a/gst/vaapi/gstvaapivideobuffer.h b/gst/vaapi/gstvaapivideobuffer.h index 52d6eb7c99..e658172fe7 100644 --- a/gst/vaapi/gstvaapivideobuffer.h +++ b/gst/vaapi/gstvaapivideobuffer.h @@ -31,7 +31,23 @@ typedef struct _GstVaapiVideoBuffer GstVaapiVideoBuffer; G_GNUC_INTERNAL GstBuffer * -gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta); +gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer); + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image); + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface); + +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); G_GNUC_INTERNAL GstVaapiVideoMeta * From 140fa66be339f9574dd8ae6193e4d9b89099cb9a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Mar 2013 10:31:10 +0100 Subject: [PATCH 1116/3781] plugins: integrate GstVaapiVideoMeta from libgstvaapi. Move GstVaapiVideoMeta from core libgstvaapi decoding library to the actual plugin elements. That's only useful there. Also inline reference counting code from GstVaapiMiniObject. --- docs/reference/libs/libs-sections.txt | 28 ------- gst-libs/gst/vaapi/Makefile.am | 2 - gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapidecode.c | 1 - gst/vaapi/gstvaapidownload.c | 1 - gst/vaapi/gstvaapipostproc.c | 1 - gst/vaapi/gstvaapisink.c | 2 +- gst/vaapi/gstvaapiupload.c | 1 - gst/vaapi/gstvaapiuploader.c | 1 - gst/vaapi/gstvaapivideobuffer.h | 2 +- gst/vaapi/gstvaapivideoconverter_glx.c | 2 +- .../gst => gst}/vaapi/gstvaapivideometa.c | 81 ++++++++++++------- .../gst => gst}/vaapi/gstvaapivideometa.h | 29 +++++-- 13 files changed, 80 insertions(+), 73 deletions(-) rename {gst-libs/gst => gst}/vaapi/gstvaapivideometa.c (91%) rename {gst-libs/gst => gst}/vaapi/gstvaapivideometa.h (89%) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 71e1ab9f67..140232363c 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -171,34 +171,6 @@ GST_VAAPI_IS_IMAGE_POOL_CLASS GST_VAAPI_IMAGE_POOL_GET_CLASS
-
-gstvaapivideometa -GstVaapiVideoMeta -gst_vaapi_video_meta_new -gst_vaapi_video_meta_new_from_pool -gst_vaapi_video_meta_new_with_image -gst_vaapi_video_meta_new_with_surface -gst_vaapi_video_meta_new_with_surface_proxy -gst_vaapi_video_meta_ref -gst_vaapi_video_meta_unref -gst_vaapi_video_meta_replace -gst_vaapi_video_meta_get_display -gst_vaapi_video_meta_get_image -gst_vaapi_video_meta_set_image -gst_vaapi_video_meta_set_image_from_pool -gst_vaapi_video_meta_get_surface -gst_vaapi_video_meta_set_surface -gst_vaapi_video_meta_set_surface_from_pool -gst_vaapi_video_meta_set_surface_converter -gst_vaapi_video_meta_get_surface_converter -gst_vaapi_video_meta_get_surface_proxy -gst_vaapi_video_meta_set_surface_proxy -gst_vaapi_video_meta_get_render_flags -gst_vaapi_video_meta_set_render_flags - -gst_vaapi_video_meta_get_type -
-
gstvaapitypes Basic data structures diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 90ec07b839..16a27a60ff 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -68,7 +68,6 @@ libgstvaapi_source_c = \ gstvaapisurfaceproxy.c \ gstvaapiutils.c \ gstvaapivalue.c \ - gstvaapivideometa.c \ gstvaapivideopool.c \ gstvaapiwindow.c \ $(NULL) @@ -94,7 +93,6 @@ libgstvaapi_source_h = \ gstvaapisurfaceproxy.h \ gstvaapitypes.h \ gstvaapivalue.h \ - gstvaapivideometa.h \ gstvaapivideopool.h \ gstvaapiwindow.h \ $(NULL) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index b2e442c4ff..c5955cb4c2 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -39,6 +39,7 @@ libgstvaapi_source_c = \ gstvaapiupload.c \ gstvaapiuploader.c \ gstvaapivideobuffer.c \ + gstvaapivideometa.c \ $(NULL) libgstvaapi_source_h = \ @@ -50,6 +51,7 @@ libgstvaapi_source_h = \ gstvaapiupload.h \ gstvaapiuploader.h \ gstvaapivideobuffer.h \ + gstvaapivideometa.h \ $(NULL) if USE_GLX diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 8d19182aef..18377fe88e 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -30,7 +30,6 @@ #include "gst/vaapi/sysdeps.h" #include -#include #include #include "gstvaapidecode.h" diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 9bb032f8e3..f90cfa2af9 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -31,7 +31,6 @@ #include #include #include -#include #include "gstvaapidownload.h" #include "gstvaapipluginutil.h" diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index e2f0e5cad7..bb0d76c12d 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -31,7 +31,6 @@ #include "gst/vaapi/sysdeps.h" #include #include -#include #include "gstvaapipostproc.h" #include "gstvaapipluginutil.h" diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index ff062ba006..0669d22906 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -34,7 +34,6 @@ #include #include #include -#include #if USE_DRM # include #endif @@ -56,6 +55,7 @@ #include "gstvaapisink.h" #include "gstvaapipluginutil.h" +#include "gstvaapivideometa.h" #define GST_PLUGIN_NAME "vaapisink" #define GST_PLUGIN_DESC "A VA-API based videosink" diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 9ac8d7a589..ecb0743e65 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "gstvaapiupload.h" #include "gstvaapipluginutil.h" diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 1c898d37f9..a0d5ef1357 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "gstvaapiuploader.h" #include "gstvaapivideobuffer.h" diff --git a/gst/vaapi/gstvaapivideobuffer.h b/gst/vaapi/gstvaapivideobuffer.h index e658172fe7..36bbd28abf 100644 --- a/gst/vaapi/gstvaapivideobuffer.h +++ b/gst/vaapi/gstvaapivideobuffer.h @@ -23,7 +23,7 @@ #ifndef GST_VAAPI_VIDEO_BUFFER_H #define GST_VAAPI_VIDEO_BUFFER_H -#include +#include "gstvaapivideometa.h" G_BEGIN_DECLS diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index 7cbd65479d..323013f39b 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -22,10 +22,10 @@ */ #include "gst/vaapi/sysdeps.h" -#include #include #include "gstvaapivideoconverter_glx.h" #include "gstvaapipluginutil.h" +#include "gstvaapivideometa.h" typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *, GstSurfaceBuffer *); diff --git a/gst-libs/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c similarity index 91% rename from gst-libs/gst/vaapi/gstvaapivideometa.c rename to gst/vaapi/gstvaapivideometa.c index 95f016848a..2b4370093d 100644 --- a/gst-libs/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -25,15 +25,13 @@ * @short_description: VA video meta for GStreamer */ -#include "sysdeps.h" +#include "gst/vaapi/sysdeps.h" +#include +#include #include "gstvaapivideometa.h" -#include "gstvaapiminiobject.h" -#include "gstvaapiimagepool.h" -#include "gstvaapisurfacepool.h" -#include "gstvaapiobject_priv.h" -#define DEBUG 1 -#include "gstvaapidebug.h" +#define GST_VAAPI_TYPE_VIDEO_META \ + (gst_vaapi_video_meta_get_type()) #define GST_VAAPI_VIDEO_META(obj) \ ((GstVaapiVideoMeta *)(obj)) @@ -42,6 +40,7 @@ (GST_VAAPI_VIDEO_META(obj) != NULL) struct _GstVaapiVideoMeta { + gint ref_count; GstVaapiDisplay *display; GstVaapiVideoPool *image_pool; GstVaapiImage *image; @@ -65,14 +64,14 @@ static inline void set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image) { meta->image = g_object_ref(image); - set_display(meta, GST_VAAPI_OBJECT_DISPLAY(image)); + set_display(meta, gst_vaapi_object_get_display(GST_VAAPI_OBJECT(image))); } static inline void set_surface(GstVaapiVideoMeta *meta, GstVaapiSurface *surface) { meta->surface = g_object_ref(surface); - set_display(meta, GST_VAAPI_OBJECT_DISPLAY(surface)); + set_display(meta, gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface))); } static void @@ -101,7 +100,7 @@ gst_vaapi_video_meta_destroy_surface(GstVaapiVideoMeta *meta) g_clear_object(&meta->surface_pool); } -GType +static GType gst_vaapi_video_meta_get_type(void) { static gsize g_type; @@ -127,6 +126,7 @@ gst_vaapi_video_meta_finalize(GstVaapiVideoMeta *meta) static void gst_vaapi_video_meta_init(GstVaapiVideoMeta *meta) { + meta->ref_count = 1; meta->display = NULL; meta->image_pool = NULL; meta->image = NULL; @@ -137,28 +137,29 @@ gst_vaapi_video_meta_init(GstVaapiVideoMeta *meta) meta->render_flags = 0; } -static inline const GstVaapiMiniObjectClass * -gst_vaapi_video_meta_class(void) -{ - static const GstVaapiMiniObjectClass GstVaapiVideoMetaClass = { - sizeof(GstVaapiVideoMeta), - (GDestroyNotify)gst_vaapi_video_meta_finalize - }; - return &GstVaapiVideoMetaClass; -} - static inline GstVaapiVideoMeta * _gst_vaapi_video_meta_new(void) { GstVaapiVideoMeta *meta; - meta = (GstVaapiVideoMeta *) - gst_vaapi_mini_object_new(gst_vaapi_video_meta_class()); - if (meta) - gst_vaapi_video_meta_init(meta); + meta = g_slice_alloc(sizeof(*meta)); + if (!meta) + return NULL; + gst_vaapi_video_meta_init(meta); return meta; } +static inline void +_gst_vaapi_video_meta_free(GstVaapiVideoMeta *meta) +{ + g_atomic_int_inc(&meta->ref_count); + + gst_vaapi_video_meta_finalize(meta); + + if (G_LIKELY(g_atomic_int_dec_and_test(&meta->ref_count))) + g_slice_free1(sizeof(*meta), meta); +} + /** * gst_vaapi_video_meta_new: * @display: a #GstVaapiDisplay @@ -317,8 +318,10 @@ gst_vaapi_video_meta_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) GstVaapiVideoMeta * gst_vaapi_video_meta_ref(GstVaapiVideoMeta *meta) { - return (GstVaapiVideoMeta *) - gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(meta)); + g_return_val_if_fail(meta != NULL, NULL); + + g_atomic_int_inc(&meta->ref_count); + return meta; } /** @@ -331,7 +334,11 @@ gst_vaapi_video_meta_ref(GstVaapiVideoMeta *meta) void gst_vaapi_video_meta_unref(GstVaapiVideoMeta *meta) { - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(meta)); + g_return_if_fail(meta != NULL); + g_return_if_fail(meta->ref_count > 0); + + if (g_atomic_int_dec_and_test(&meta->ref_count)) + _gst_vaapi_video_meta_free(meta); } /** @@ -347,8 +354,24 @@ void gst_vaapi_video_meta_replace(GstVaapiVideoMeta **old_meta_ptr, GstVaapiVideoMeta *new_meta) { - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_meta_ptr), - (GstVaapiMiniObject *)(new_meta)); + GstVaapiVideoMeta *old_meta; + + g_return_if_fail(old_meta_ptr != NULL); + + old_meta = g_atomic_pointer_get((gpointer *)old_meta_ptr); + + if (old_meta == new_meta) + return; + + if (new_meta) + gst_vaapi_video_meta_ref(new_meta); + + while (!g_atomic_pointer_compare_and_exchange((gpointer *)old_meta_ptr, + old_meta, new_meta)) + old_meta = g_atomic_pointer_get((gpointer *)old_meta_ptr); + + if (old_meta) + gst_vaapi_video_meta_unref(old_meta); } /** diff --git a/gst-libs/gst/vaapi/gstvaapivideometa.h b/gst/vaapi/gstvaapivideometa.h similarity index 89% rename from gst-libs/gst/vaapi/gstvaapivideometa.h rename to gst/vaapi/gstvaapivideometa.h index 42bda676c4..47d07e345d 100644 --- a/gst-libs/gst/vaapi/gstvaapivideometa.h +++ b/gst/vaapi/gstvaapivideometa.h @@ -31,85 +31,102 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_VIDEO_META \ - (gst_vaapi_video_meta_get_type()) - typedef struct _GstVaapiVideoMeta GstVaapiVideoMeta; -GType -gst_vaapi_video_meta_get_type(void) G_GNUC_CONST; - +G_GNUC_INTERNAL GstVaapiVideoMeta * gst_vaapi_video_meta_new(GstVaapiDisplay *display); +G_GNUC_INTERNAL GstVaapiVideoMeta * gst_vaapi_video_meta_new_from_pool(GstVaapiVideoPool *pool); +G_GNUC_INTERNAL GstVaapiVideoMeta * gst_vaapi_video_meta_new_with_image(GstVaapiImage *image); +G_GNUC_INTERNAL GstVaapiVideoMeta * gst_vaapi_video_meta_new_with_surface(GstVaapiSurface *surface); +G_GNUC_INTERNAL GstVaapiVideoMeta * gst_vaapi_video_meta_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); +G_GNUC_INTERNAL GstVaapiVideoMeta * gst_vaapi_video_meta_ref(GstVaapiVideoMeta *meta); +G_GNUC_INTERNAL void gst_vaapi_video_meta_unref(GstVaapiVideoMeta *meta); +G_GNUC_INTERNAL void gst_vaapi_video_meta_replace(GstVaapiVideoMeta **old_meta_ptr, GstVaapiVideoMeta *new_meta); +G_GNUC_INTERNAL GstVaapiDisplay * gst_vaapi_video_meta_get_display(GstVaapiVideoMeta *meta); +G_GNUC_INTERNAL GstVaapiImage * gst_vaapi_video_meta_get_image(GstVaapiVideoMeta *meta); +G_GNUC_INTERNAL void gst_vaapi_video_meta_set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image); +G_GNUC_INTERNAL gboolean gst_vaapi_video_meta_set_image_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool); +G_GNUC_INTERNAL GstVaapiSurface * gst_vaapi_video_meta_get_surface(GstVaapiVideoMeta *meta); +G_GNUC_INTERNAL void gst_vaapi_video_meta_set_surface(GstVaapiVideoMeta *meta, GstVaapiSurface *surface); +G_GNUC_INTERNAL gboolean gst_vaapi_video_meta_set_surface_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool); +G_GNUC_INTERNAL GstVaapiSurfaceProxy * gst_vaapi_video_meta_get_surface_proxy(GstVaapiVideoMeta *meta); +G_GNUC_INTERNAL void gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, GstVaapiSurfaceProxy *proxy); +G_GNUC_INTERNAL GFunc gst_vaapi_video_meta_get_surface_converter(GstVaapiVideoMeta *meta); +G_GNUC_INTERNAL void gst_vaapi_video_meta_set_surface_converter(GstVaapiVideoMeta *meta, GFunc func); +G_GNUC_INTERNAL guint gst_vaapi_video_meta_get_render_flags(GstVaapiVideoMeta *meta); +G_GNUC_INTERNAL void gst_vaapi_video_meta_set_render_flags(GstVaapiVideoMeta *meta, guint flags); +G_GNUC_INTERNAL GstVaapiVideoMeta * gst_buffer_get_vaapi_video_meta(GstBuffer *buffer); +G_GNUC_INTERNAL void gst_buffer_set_vaapi_video_meta(GstBuffer *buffer, GstVaapiVideoMeta *meta); From e6f0cbadd3bb75ddb1b1c4ebbd7b5a107289b83a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Mar 2013 18:45:53 +0100 Subject: [PATCH 1117/3781] plugins: streamline video buffers. Add new gst_vaapi_video_buffer_new() helper function that allocates a video buffer from a GstVaapiVideoMeta. Also remove obsolete and useless function gst_vaapi_video_buffer_get_meta(). --- gst/vaapi/gstvaapivideobuffer.c | 16 ++++++++-------- gst/vaapi/gstvaapivideobuffer.h | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 27dd1fb2b6..c6c1a0ac2c 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -152,6 +152,14 @@ new_vbuffer(GstVaapiVideoMeta *meta) return buffer; } +GstBuffer * +gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta) +{ + g_return_val_if_fail(meta != NULL, NULL); + + return new_vbuffer(gst_vaapi_video_meta_ref(meta)); +} + GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) { @@ -183,11 +191,3 @@ gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) { return new_vbuffer(gst_vaapi_video_meta_new_with_surface_proxy(proxy)); } - -GstVaapiVideoMeta * -gst_vaapi_video_buffer_get_meta(GstVaapiVideoBuffer *buffer) -{ - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL); - - return buffer->meta; -} diff --git a/gst/vaapi/gstvaapivideobuffer.h b/gst/vaapi/gstvaapivideobuffer.h index 36bbd28abf..f4457ab606 100644 --- a/gst/vaapi/gstvaapivideobuffer.h +++ b/gst/vaapi/gstvaapivideobuffer.h @@ -29,6 +29,10 @@ G_BEGIN_DECLS typedef struct _GstVaapiVideoBuffer GstVaapiVideoBuffer; +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta); + G_GNUC_INTERNAL GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); @@ -49,10 +53,6 @@ G_GNUC_INTERNAL GstBuffer * gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); -G_GNUC_INTERNAL -GstVaapiVideoMeta * -gst_vaapi_video_buffer_get_meta(GstVaapiVideoBuffer *buffer); - G_END_DECLS #endif /* GST_VAAPI_VIDEO_BUFFER_H */ From 578f7886509f39d34e47baa2c53ba718d2e15122 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Mar 2013 18:57:00 +0100 Subject: [PATCH 1118/3781] plugins: fix usage of gst_vaapi_reply_to_query(). Make gst_vaapi_reply_to_query() first check whether the query argument is actually a video-context query, i.e. with type GST_QUERY_TYPE_CUSTOM. Then, make sure vaapisink propagates the query to the parent class if it is not a video-context query. --- gst/vaapi/gstvaapipluginutil.c | 3 +++ gst/vaapi/gstvaapisink.c | 11 ++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index d42fa21943..df311142c8 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -220,6 +220,9 @@ gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) gint i; gboolean res = FALSE; + if (GST_QUERY_TYPE(query) != GST_QUERY_CUSTOM) + return FALSE; + if (!display) return FALSE; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 0669d22906..fbf931cf7f 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -961,9 +961,14 @@ gst_vaapisink_buffer_alloc( static gboolean gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query) { - GstVaapiSink *sink = GST_VAAPISINK(base_sink); - GST_DEBUG ("sharing display %p", sink->display); - return gst_vaapi_reply_to_query (query, sink->display); + GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + + if (gst_vaapi_reply_to_query(query, sink->display)) { + GST_DEBUG("sharing display %p", sink->display); + return TRUE; + } + return GST_BASE_SINK_CLASS(gst_vaapisink_parent_class)->query(base_sink, + query); } static void From 7153da636ab6b301214d046444775fde84efd808 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Mar 2013 10:15:53 +0100 Subject: [PATCH 1119/3781] NEWS: updates. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 50fc0c00f5..842295445c 100644 --- a/NEWS +++ b/NEWS @@ -6,9 +6,11 @@ Copyright (C) 2011 Collabora Version 0.5.2 - DD.Feb.2013 * Add support for video seek/reset (+Sreerenj Balachandran) * Improve MPEG-2 decoder robustness when packets are missing +* Fix support for raw YUV buffers in vaapisink * Fix build on older Linux distributions with glib < 2.32 * Fix decoding of MPEG-2 videos with height > 2800 pixels * Fix MPEG-2 decoding with explicit quantization matrices set (Cong Zhong) +* Fix illegal write in vaapiupload for NV12 surfaces (Holger Kaelberer) Version 0.5.1 - 29.Jan.2013 * Add simple decoder demo that only uses libgstvaapi From f1ee2d8453bd43047387bf76fbabc46aa5942e37 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Mar 2013 10:18:51 +0100 Subject: [PATCH 1120/3781] 0.5.2. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 842295445c..920bf924c3 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2013-02-DD +gst-vaapi NEWS -- summary of changes. 2013-03-28 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora -Version 0.5.2 - DD.Feb.2013 +Version 0.5.2 - 28.Mar.2013 * Add support for video seek/reset (+Sreerenj Balachandran) * Improve MPEG-2 decoder robustness when packets are missing * Fix support for raw YUV buffers in vaapisink diff --git a/configure.ac b/configure.ac index 2b4623cbe1..6aff34b8ea 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [2]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From e76089f98b139aa46e6eb009d4c5a37114f67786 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 29 Mar 2013 10:39:37 +0100 Subject: [PATCH 1121/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 6aff34b8ea..9a5065cfb1 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [2]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [3]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From e22a863084eff8a6ceaeb2c5a327da17eccbd62f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 3 Apr 2013 11:37:44 +0200 Subject: [PATCH 1122/3781] decoder: simplify acquisition/release of spare surface. Introduce gst_vaapi_surface_proxy_new_from_pool() to allocate a new surface proxy from the context surface pool. This change also makes sure to retain the parent surface pool in the proxy. Besides, it was also totally useless to attach/detach parent context to VA surface each time we acquire/release it. Since the whole context owns all associated VA surfaces, we can mark this as such only once and for all. --- docs/reference/libs/libs-sections.txt | 2 ++ gst-libs/gst/vaapi/gstvaapicontext.c | 36 +++++++++++++++----- gst-libs/gst/vaapi/gstvaapicontext.h | 3 ++ gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 12 ++----- gst-libs/gst/vaapi/gstvaapisurface.h | 1 + gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 33 +++++++++++++++++- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 6 ++-- 7 files changed, 71 insertions(+), 22 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 140232363c..fcb701ec69 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -401,6 +401,7 @@ gst_vaapi_context_get_profile gst_vaapi_context_set_profile gst_vaapi_context_get_entrypoint gst_vaapi_context_get_size +gst_vaapi_context_get_surface_proxy gst_vaapi_context_get_surface gst_vaapi_context_get_surface_count gst_vaapi_context_put_surface @@ -528,6 +529,7 @@ gst_vaapi_surface_proxy_get_surface gst_vaapi_surface_proxy_get_surface_id gst_vaapi_surface_proxy_get_user_data gst_vaapi_surface_proxy_new +gst_vaapi_surface_proxy_new_from_pool gst_vaapi_surface_proxy_ref gst_vaapi_surface_proxy_replace gst_vaapi_surface_proxy_set_context diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 8d5a6d1d68..44cafc469a 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -32,6 +32,7 @@ #include "gstvaapisurface.h" #include "gstvaapisurface_priv.h" #include "gstvaapisurfacepool.h" +#include "gstvaapisurfaceproxy.h" #include "gstvaapiimage.h" #include "gstvaapisubpicture.h" #include "gstvaapiminiobject.h" @@ -503,6 +504,7 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context) ); if (!surface) return FALSE; + gst_vaapi_surface_set_parent_context(surface, context); g_ptr_array_add(priv->surfaces, surface); if (!gst_vaapi_video_pool_add_object(priv->surfaces_pool, surface)) return FALSE; @@ -998,6 +1000,30 @@ gst_vaapi_context_get_size( *pheight = context->priv->height; } +/** + * 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(GST_VAAPI_IS_CONTEXT(context), NULL); + + return gst_vaapi_surface_proxy_new_from_pool( + GST_VAAPI_SURFACE_POOL(context->priv->surfaces_pool)); +} + /** * gst_vaapi_context_get_surface: * @context: a #GstVaapiContext @@ -1012,16 +1038,9 @@ gst_vaapi_context_get_size( GstVaapiSurface * gst_vaapi_context_get_surface(GstVaapiContext *context) { - GstVaapiSurface *surface; - g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); - surface = gst_vaapi_video_pool_get_object(context->priv->surfaces_pool); - if (!surface) - return NULL; - - gst_vaapi_surface_set_parent_context(surface, context); - return surface; + return gst_vaapi_video_pool_get_object(context->priv->surfaces_pool); } /** @@ -1053,7 +1072,6 @@ gst_vaapi_context_put_surface(GstVaapiContext *context, GstVaapiSurface *surface g_return_if_fail(GST_VAAPI_IS_CONTEXT(context)); g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); - gst_vaapi_surface_set_parent_context(surface, NULL); gst_vaapi_video_pool_put_object(context->priv->surfaces_pool, surface); } diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 41ce0c5016..11c38ffc9a 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -143,6 +143,9 @@ gst_vaapi_context_get_size( guint *pheight ); +GstVaapiSurfaceProxy * +gst_vaapi_context_get_surface_proxy(GstVaapiContext *context); + GstVaapiSurface * gst_vaapi_context_get_surface(GstVaapiContext *context); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 9b450bb499..dfa841826f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -75,10 +75,6 @@ gst_vaapi_picture_destroy(GstVaapiPicture *picture) gst_vaapi_surface_proxy_unref(picture->proxy); picture->proxy = NULL; } - else if (picture->surface) { - /* Explicitly release any surface that was not bound to a proxy */ - gst_vaapi_context_put_surface(GET_CONTEXT(picture), picture->surface); - } picture->surface_id = VA_INVALID_ID; picture->surface = NULL; @@ -103,7 +99,6 @@ gst_vaapi_picture_create( GstVaapiPicture * const parent_picture = GST_VAAPI_PICTURE(args->data); picture->proxy = gst_vaapi_surface_proxy_ref(parent_picture->proxy); - picture->surface = gst_vaapi_surface_proxy_get_surface(picture->proxy); picture->type = parent_picture->type; picture->pts = parent_picture->pts; picture->poc = parent_picture->poc; @@ -137,18 +132,15 @@ gst_vaapi_picture_create( picture->type = GST_VAAPI_PICTURE_TYPE_NONE; picture->pts = GST_CLOCK_TIME_NONE; - picture->surface = gst_vaapi_context_get_surface(GET_CONTEXT(picture)); - if (!picture->surface) - return FALSE; - picture->proxy = - gst_vaapi_surface_proxy_new(GET_CONTEXT(picture), picture->surface); + 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_get_surface(picture->proxy); picture->surface_id = gst_vaapi_surface_get_id(picture->surface); picture->param_id = VA_INVALID_ID; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 9b74e7a0b0..2d98b5e67a 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -140,6 +140,7 @@ typedef enum { typedef struct _GstVaapiSurface GstVaapiSurface; typedef struct _GstVaapiSurfacePrivate GstVaapiSurfacePrivate; typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; +typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; /** * GstVaapiSurface: diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index db0db25bee..84b4256c64 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -43,6 +43,7 @@ struct _GstVaapiSurfaceProxy { /*< private >*/ GstVaapiMiniObject parent_instance; + GstVaapiVideoPool *pool; GstVaapiContext *context; GstVaapiSurface *surface; }; @@ -87,11 +88,37 @@ gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface) if (!proxy) return NULL; + proxy->pool = NULL; proxy->context = g_object_ref(context); proxy->surface = g_object_ref(surface); return proxy; } +GstVaapiSurfaceProxy * +gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) +{ + GstVaapiSurfaceProxy *proxy; + + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), NULL); + + proxy = (GstVaapiSurfaceProxy *) + gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class()); + if (!proxy) + return NULL; + + proxy->pool = g_object_ref(pool); + proxy->context = NULL; + proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool); + if (!proxy->surface) + goto error; + g_object_ref(proxy->surface); + return proxy; + +error: + gst_vaapi_surface_proxy_unref(proxy); + return NULL; +} + /** * gst_vaapi_surface_proxy_ref: * @proxy: a #GstVaapiSurfaceProxy @@ -272,12 +299,16 @@ gst_vaapi_surface_proxy_set_surface( g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); if (proxy->surface) { - if (proxy->context) + if (proxy->pool) + gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface); + else if (proxy->context) gst_vaapi_context_put_surface(proxy->context, proxy->surface); g_object_unref(proxy->surface); proxy->surface = NULL; } + g_clear_object(&proxy->pool); + if (surface) proxy->surface = g_object_ref(surface); } diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index a8fe2d16d7..15a933a5b9 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -25,11 +25,10 @@ #include #include +#include G_BEGIN_DECLS -typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; - /** * GST_VAAPI_SURFACE_PROXY_SURFACE: * @surface: a #GstVaapiSurfaceProxy @@ -42,6 +41,9 @@ typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface); +GstVaapiSurfaceProxy * +gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool); + GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy); From 6e82da1e93390cd4585d1c56383008b67c6391c5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 3 Apr 2013 13:14:59 +0200 Subject: [PATCH 1123/3781] decoder: delegate surface size check to VA context reset. Now that the surface pool is reference counted in the surface proxy wrapper, we can safely ignore surface size checks in gst_vaapi_decoder_ensure_context(). Besides, this check is already performed in gst_vaapi_context_reset_full(). --- gst-libs/gst/vaapi/gstvaapidecoder.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index d1cbd3a3a5..1801147038 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -866,19 +866,6 @@ gst_vaapi_decoder_ensure_context( ) { GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVideoCodecState * const codec_state = priv->codec_state; - gboolean size_changed; - - size_changed = codec_state->info.width != cip->width || - codec_state->info.height != cip->height; - - /* Create a new context if the requested size for surfaces changed - * because we need to keep the context underlying surface pool - * until all surfaces are released */ - if (size_changed) { - gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height); - g_clear_object(&priv->context); - } if (priv->context) { if (!gst_vaapi_context_reset_full(priv->context, cip)) From e65726de8db680adde86e990ca8d7aa5b29fde67 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 3 Apr 2013 13:08:55 +0200 Subject: [PATCH 1124/3781] decoder: drop obsolete functions. Drop the following functions that are now obsolete: - gst_vaapi_context_get_surface() - gst_vaapi_context_put_surface() - gst_vaapi_context_find_surface_by_id() - gst_vaapi_surface_proxy_new() - gst_vaapi_surface_proxy_get_context() - gst_vaapi_surface_proxy_set_context() - gst_vaapi_surface_proxy_set_surface() This is an API change. --- docs/reference/libs/libs-sections.txt | 7 -- gst-libs/gst/vaapi/gstvaapicontext.c | 65 ------------- gst-libs/gst/vaapi/gstvaapicontext.h | 9 -- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 111 ++-------------------- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 19 ---- 5 files changed, 7 insertions(+), 204 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index fcb701ec69..33f645b556 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -402,10 +402,7 @@ gst_vaapi_context_set_profile gst_vaapi_context_get_entrypoint gst_vaapi_context_get_size gst_vaapi_context_get_surface_proxy -gst_vaapi_context_get_surface gst_vaapi_context_get_surface_count -gst_vaapi_context_put_surface -gst_vaapi_context_find_surface_by_id gst_vaapi_context_apply_composition GST_VAAPI_CONTEXT @@ -524,16 +521,12 @@ GST_VAAPI_DECODER_VC1_GET_CLASS
gstvaapisurfaceproxy GstVaapiSurfaceProxy -gst_vaapi_surface_proxy_get_context gst_vaapi_surface_proxy_get_surface gst_vaapi_surface_proxy_get_surface_id gst_vaapi_surface_proxy_get_user_data -gst_vaapi_surface_proxy_new gst_vaapi_surface_proxy_new_from_pool gst_vaapi_surface_proxy_ref gst_vaapi_surface_proxy_replace -gst_vaapi_surface_proxy_set_context -gst_vaapi_surface_proxy_set_surface gst_vaapi_surface_proxy_set_user_data gst_vaapi_surface_proxy_unref diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 44cafc469a..d9ee4cddbe 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -1024,25 +1024,6 @@ gst_vaapi_context_get_surface_proxy(GstVaapiContext *context) GST_VAAPI_SURFACE_POOL(context->priv->surfaces_pool)); } -/** - * gst_vaapi_context_get_surface: - * @context: a #GstVaapiContext - * - * Acquires a free surface. The returned surface but be released with - * gst_vaapi_context_put_surface(). 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 - */ -GstVaapiSurface * -gst_vaapi_context_get_surface(GstVaapiContext *context) -{ - g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); - - return gst_vaapi_video_pool_get_object(context->priv->surfaces_pool); -} - /** * gst_vaapi_context_get_surface_count: * @context: a #GstVaapiContext @@ -1059,52 +1040,6 @@ gst_vaapi_context_get_surface_count(GstVaapiContext *context) return gst_vaapi_video_pool_get_size(context->priv->surfaces_pool); } -/** - * gst_vaapi_context_put_surface: - * @context: a #GstVaapiContext - * @surface: the #GstVaapiSurface to release - * - * Releases a surface acquired by gst_vaapi_context_get_surface(). - */ -void -gst_vaapi_context_put_surface(GstVaapiContext *context, GstVaapiSurface *surface) -{ - g_return_if_fail(GST_VAAPI_IS_CONTEXT(context)); - g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); - - gst_vaapi_video_pool_put_object(context->priv->surfaces_pool, surface); -} - -/** - * gst_vaapi_context_find_surface_by_id: - * @context: a #GstVaapiContext - * @id: the VA surface id to find - * - * Finds VA surface by @id in the list of surfaces attached to the @context. - * - * Return value: the matching #GstVaapiSurface object, or %NULL if - * none was found - */ -GstVaapiSurface * -gst_vaapi_context_find_surface_by_id(GstVaapiContext *context, GstVaapiID id) -{ - GstVaapiContextPrivate *priv; - GstVaapiSurface *surface; - guint i; - - g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); - - priv = context->priv; - g_return_val_if_fail(priv->surfaces, NULL); - - for (i = 0; i < priv->surfaces->len; i++) { - surface = g_ptr_array_index(priv->surfaces, i); - if (GST_VAAPI_OBJECT_ID(surface) == id) - return surface; - } - return NULL; -} - /** * gst_vaapi_context_apply_composition: * @context: a #GstVaapiContext diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 11c38ffc9a..208a4381e7 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -146,18 +146,9 @@ gst_vaapi_context_get_size( GstVaapiSurfaceProxy * gst_vaapi_context_get_surface_proxy(GstVaapiContext *context); -GstVaapiSurface * -gst_vaapi_context_get_surface(GstVaapiContext *context); - guint gst_vaapi_context_get_surface_count(GstVaapiContext *context); -void -gst_vaapi_context_put_surface(GstVaapiContext *context, GstVaapiSurface *surface); - -GstVaapiSurface * -gst_vaapi_context_find_surface_by_id(GstVaapiContext *context, GstVaapiID id); - gboolean gst_vaapi_context_apply_composition( GstVaapiContext *context, diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 84b4256c64..e802eab40e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -44,15 +44,19 @@ struct _GstVaapiSurfaceProxy { GstVaapiMiniObject parent_instance; GstVaapiVideoPool *pool; - GstVaapiContext *context; GstVaapiSurface *surface; }; static void gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) { - gst_vaapi_surface_proxy_set_surface(proxy, NULL); - gst_vaapi_surface_proxy_set_context(proxy, NULL); + if (proxy->surface) { + if (proxy->pool) + gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface); + g_object_unref(proxy->surface); + proxy->surface = NULL; + } + g_clear_object(&proxy->pool); } static inline const GstVaapiMiniObjectClass * @@ -65,35 +69,6 @@ gst_vaapi_surface_proxy_class(void) return &GstVaapiSurfaceProxyClass; } -/** - * gst_vaapi_surface_proxy_new: - * @context: a #GstVaapiContext - * @surface: a #GstVaapiSurface - * - * Creates a new #GstVaapiSurfaceProxy with the specified context and - * surface. - * - * Return value: the newly allocated #GstVaapiSurfaceProxy object - */ -GstVaapiSurfaceProxy * -gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface) -{ - GstVaapiSurfaceProxy *proxy; - - g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - - proxy = (GstVaapiSurfaceProxy *) - gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class()); - if (!proxy) - return NULL; - - proxy->pool = NULL; - proxy->context = g_object_ref(context); - proxy->surface = g_object_ref(surface); - return proxy; -} - GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) { @@ -107,7 +82,6 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) return NULL; proxy->pool = g_object_ref(pool); - proxy->context = NULL; proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool); if (!proxy->surface) goto error; @@ -209,45 +183,6 @@ gst_vaapi_surface_proxy_set_user_data(GstVaapiSurfaceProxy *proxy, user_data, destroy_notify); } -/** - * gst_vaapi_surface_proxy_get_context: - * @proxy: a #GstVaapiSurfaceProxy - * - * Returns the #GstVaapiContext stored in the @proxy. - * - * Return value: the #GstVaapiContext - */ -GstVaapiContext * -gst_vaapi_surface_proxy_get_context(GstVaapiSurfaceProxy *proxy) -{ - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); - - return proxy->context; -} - -/** - * gst_vaapi_surface_proxy_set_context: - * @proxy: a #GstVaapiSurfaceProxy - * @context: the new #GstVaapiContext to be stored in @proxy - * - * Stores a new @context into the @proxy. The proxy releases the - * previous reference, if any, and then holds a reference to the new - * @context. - */ -void -gst_vaapi_surface_proxy_set_context( - GstVaapiSurfaceProxy *proxy, - GstVaapiContext *context -) -{ - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - - g_clear_object(&proxy->context); - - if (context) - proxy->context = g_object_ref(context); -} - /** * gst_vaapi_surface_proxy_get_surface: * @proxy: a #GstVaapiSurfaceProxy @@ -280,35 +215,3 @@ gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) return GST_VAAPI_OBJECT_ID(proxy->surface); } - -/** - * gst_vaapi_surface_proxy_set_surface: - * @proxy: a #GstVaapiSurfaceProxy - * @surface: the new #GstVaapiSurface to be stored in @proxy - * - * Stores a new @surface into the @proxy. The proxy releases the - * previous reference, if any, and then holds a reference to the new - * @surface. - */ -void -gst_vaapi_surface_proxy_set_surface( - GstVaapiSurfaceProxy *proxy, - GstVaapiSurface *surface -) -{ - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - - if (proxy->surface) { - if (proxy->pool) - gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface); - else if (proxy->context) - gst_vaapi_context_put_surface(proxy->context, proxy->surface); - g_object_unref(proxy->surface); - proxy->surface = NULL; - } - - g_clear_object(&proxy->pool); - - if (surface) - proxy->surface = g_object_ref(surface); -} diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 15a933a5b9..467699dace 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -23,7 +23,6 @@ #ifndef GST_VAAPI_SURFACE_PROXY_H #define GST_VAAPI_SURFACE_PROXY_H -#include #include #include @@ -38,9 +37,6 @@ G_BEGIN_DECLS #define GST_VAAPI_SURFACE_PROXY_SURFACE(surface) \ gst_vaapi_surface_proxy_get_surface(surface) -GstVaapiSurfaceProxy * -gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface); - GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool); @@ -61,27 +57,12 @@ void gst_vaapi_surface_proxy_set_user_data(GstVaapiSurfaceProxy *proxy, gpointer user_data, GDestroyNotify destroy_notify); -GstVaapiContext * -gst_vaapi_surface_proxy_get_context(GstVaapiSurfaceProxy *proxy); - -void -gst_vaapi_surface_proxy_set_context( - GstVaapiSurfaceProxy *proxy, - GstVaapiContext *context -); - GstVaapiSurface * gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy); GstVaapiID gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy); -void -gst_vaapi_surface_proxy_set_surface( - GstVaapiSurfaceProxy *proxy, - GstVaapiSurface *surface -); - G_END_DECLS #endif /* GST_VAAPI_SURFACE_PROXY_H */ From cadc42eafea8de67f2d93a2d2f1d4f9dcd372d1b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 3 Apr 2013 14:59:33 +0200 Subject: [PATCH 1125/3781] vaapidecode: expose the exact set of supported HW decoders. Don't return static caps that don't mean anything for the underlying codecs that are actually supported for decoding. i.e. always allocate a VA display and retrieve the exact set of HW decoders available. That VA display may be re-used later on during negotiation through GstVideoContext "prepare-context". This fixes fallback to SW decoding if no HW decoder is available. --- gst/vaapi/gstvaapidecode.c | 18 +++++++++++------- gst/vaapi/gstvaapidecode.h | 1 - 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 18377fe88e..58c3358727 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -456,9 +456,18 @@ static gboolean gst_vaapidecode_open(GstVideoDecoder *vdec) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + GstVaapiDisplay * const old_display = decode->display; + gboolean success; - decode->is_ready = TRUE; - return TRUE; + /* Let GstVideoContext ask for a proper display to its neighbours */ + /* Note: steal old display that may be allocated from get_caps() + so that to retain a reference to it, thus avoiding extra + initialization steps if we turn out to simply re-use the + existing (cached) VA display */ + decode->display = NULL; + success = gst_vaapidecode_ensure_display(decode); + g_clear_object(&old_display); + return success; } static gboolean @@ -468,7 +477,6 @@ gst_vaapidecode_close(GstVideoDecoder *vdec) gst_vaapidecode_destroy(decode); g_clear_object(&decode->display); - decode->is_ready = FALSE; return TRUE; } @@ -637,9 +645,6 @@ gst_vaapidecode_get_caps(GstPad *pad) { GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); - if (!decode->is_ready) - return gst_static_pad_template_get_caps(&gst_vaapidecode_sink_factory); - if (!gst_vaapidecode_ensure_allowed_caps(decode)) return gst_caps_new_empty(); @@ -675,7 +680,6 @@ gst_vaapidecode_init(GstVaapiDecode *decode) decode->allowed_caps = NULL; decode->render_time_base = 0; decode->last_buffer_time = 0; - decode->is_ready = FALSE; g_mutex_init(&decode->decoder_mutex); g_cond_init(&decode->decoder_ready); diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 89966f09e8..05b7769c4d 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -76,7 +76,6 @@ struct _GstVaapiDecode { GstCaps *allowed_caps; gint64 render_time_base; GstClockTime last_buffer_time; - unsigned int is_ready : 1; }; struct _GstVaapiDecodeClass { From 378ea2e23796fa7b823e0626ae11cc9d1402448a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 3 Apr 2013 15:06:46 +0200 Subject: [PATCH 1126/3781] plugins: don't fail if there is no overlay composition to apply. Fix gst_vaapi_apply_composition() to not fail if no overlay composition was found. i.e. return success (TRUE). This was harmless though extra debug messages are not nice. This is a regression introduced by commit 95b8659. --- gst/vaapi/gstvaapipluginutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index df311142c8..b2cc92f1d4 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -339,7 +339,7 @@ gst_vaapi_apply_composition(GstVaapiSurface *surface, GstBuffer *buffer) gst_video_buffer_get_overlay_composition(buffer); if (!composition) - return FALSE; + return TRUE; return gst_vaapi_surface_set_subpictures_from_composition(surface, composition, TRUE); } From 6136ebe5e2fbedc496ac73cdd6461f194630b313 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 3 Apr 2013 15:58:57 +0200 Subject: [PATCH 1127/3781] vaapisink: improve check for raw YUV format mode. Improve check for raw YUV format modes by avoiding checks against strings ("video/x-raw-yuv") for each new GstBuffer allocation. In the usual case, GstBaseSink::set_caps() is called first and if VA surface format mode is used, then GstBaseSink::buffer_alloc() is not called. If the latter is called before set_caps(), then we just make a full check. This one is pretty rare though, e.g. it usually happens once for custom pipelines. --- gst/vaapi/gstvaapisink.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index fbf931cf7f..1bf8026a0e 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -610,7 +610,6 @@ static gboolean gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstStructure * const structure = gst_caps_get_structure(caps, 0); GstVideoInfo vi; guint win_width, win_height; @@ -621,16 +620,14 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) if (!gst_video_info_from_caps(&vi, caps)) return FALSE; - sink->video_width = GST_VIDEO_INFO_WIDTH(&vi); - sink->video_height = GST_VIDEO_INFO_HEIGHT(&vi); - sink->video_par_n = GST_VIDEO_INFO_PAR_N(&vi); - sink->video_par_d = GST_VIDEO_INFO_PAR_D(&vi); + sink->use_video_raw = GST_VIDEO_INFO_IS_YUV(&vi); + sink->video_width = GST_VIDEO_INFO_WIDTH(&vi); + sink->video_height = GST_VIDEO_INFO_HEIGHT(&vi); + sink->video_par_n = GST_VIDEO_INFO_PAR_N(&vi); + sink->video_par_d = GST_VIDEO_INFO_PAR_D(&vi); GST_DEBUG("video pixel-aspect-ratio %d/%d", sink->video_par_n, sink->video_par_d); - if (gst_structure_has_name(structure, "video/x-raw-yuv")) - sink->use_video_raw = TRUE; - gst_caps_replace(&sink->caps, caps); if (!gst_vaapisink_ensure_display(sink)) @@ -934,14 +931,21 @@ gst_vaapisink_buffer_alloc( ) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstStructure *structure; + GstVideoInfo vi; GstBuffer *buf; *pbuf = NULL; - structure = gst_caps_get_structure(caps, 0); - if (!gst_structure_has_name(structure, "video/x-raw-yuv")) - return GST_FLOW_OK; + if (!sink->use_video_raw) { + /* Note: this code path is rarely used but for raw YUV formats + from custom pipeline. Otherwise, GstBaseSink::set_caps() is + called first, and GstBaseSink::buffer_alloc() is not called + in VA surface format mode */ + if (!gst_video_info_from_caps(&vi, caps)) + return GST_FLOW_NOT_SUPPORTED; + if (!GST_VIDEO_INFO_IS_YUV(&vi)) + return GST_FLOW_OK; + } if (!gst_vaapi_uploader_ensure_display(sink->uploader, sink->display)) return GST_FLOW_NOT_SUPPORTED; From 51151e7aa1637d23880b7c051602970d76a9a45a Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 4 Sep 2012 15:12:18 +0300 Subject: [PATCH 1128/3781] Add initial support for GStreamer 1.0. This integrates support for GStreamer API >= 1.0 only in the libgstvaapi core decoding library. The changes are kept rather minimal here so that the library retains as little dependency as possible on core GStreamer functionality. Signed-off-by: Gwenole Beauchesne --- configure.ac | 12 ++++++- gst-libs/gst/vaapi/gstcompat.h | 33 ++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapicontext.c | 22 +++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder.c | 22 ++++++++----- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 11 +++++-- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 11 ++++--- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 18 +++++++++-- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 13 ++++---- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 3 ++ gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 9 ++++-- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.c | 19 +++++++++++ gst-libs/gst/vaapi/gstvaapiimageformat.c | 4 +-- gst-libs/gst/vaapi/gstvaapiprofile.c | 9 ++++-- gst-libs/gst/vaapi/gstvaapisubpicture.c | 24 ++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 3 +- 16 files changed, 179 insertions(+), 36 deletions(-) diff --git a/configure.ac b/configure.ac index 9a5065cfb1..ec7c5d13e8 100644 --- a/configure.ac +++ b/configure.ac @@ -18,10 +18,13 @@ m4_define([gst_vaapi_lt_age], [0]) m4_define([glib_version], [2.28]) # gstreamer version number -m4_define([gst_api_version], [0.10]) +m4_define([gst_api_version], [1.0]) m4_define([gst0_version], [0.10.36]) m4_define([gst0_plugins_base_version], [0.10.31]) m4_define([gst0_plugins_bad_version], [0.10.22]) +m4_define([gst1_version], [1.0.0]) +m4_define([gst1_plugins_base_version], [1.0.0]) +m4_define([gst1_plugins_bad_version], [1.0.0]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.0]) @@ -135,6 +138,11 @@ case $GST_API_VERSION in GST_PLUGINS_BASE_VERSION_REQUIRED=gst0_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst0_plugins_bad_version ;; +1.0) + GST_VERSION_REQUIRED=gst1_version + GST_PLUGINS_BASE_VERSION_REQUIRED=gst1_plugins_base_version + GST_PLUGINS_BAD_VERSION_REQUIRED=gst1_plugins_bad_version + ;; *) AC_MSG_ERROR([unsupported GStreamer API version $GST_API_VERSION]) ;; @@ -172,8 +180,10 @@ fi dnl GStreamer -base plugins PKG_CHECK_MODULES([GST_PLUGINS_BASE], [gstreamer-plugins-base-$GST_API_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) +if test "$GST_API_VERSION" = "0.10"; then PKG_CHECK_MODULES([GST_INTERFACES], [gstreamer-interfaces-$GST_API_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) +fi dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index 4f5ff6258f..1868dc1376 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -24,6 +24,37 @@ #include +/* ------------------------------------------------------------------------ */ +/* --- GStreamer >= 1.0 --- */ +/* ------------------------------------------------------------------------ */ + +#if GST_CHECK_VERSION(1,0,0) +#include + +/* GstStructure */ +#undef gst_structure_get_fourcc +#define gst_structure_get_fourcc(structure, fieldname, value) \ + gst_compat_structure_get_fourcc(structure, fieldname, value) + +static inline gboolean +gst_compat_structure_get_fourcc(const GstStructure *structure, + const gchar *fieldname, guint32 *value) +{ + const gchar *s = gst_structure_get_string(structure, fieldname); + + if (!s || strlen(s) != 4) + return FALSE; + + *value = GST_MAKE_FOURCC(s[0], s[1], s[2], s[3]); + return TRUE; +} + +/* ------------------------------------------------------------------------ */ +/* --- GStreamer = 0.10 --- */ +/* ------------------------------------------------------------------------ */ + +#else + /* GstVideoOverlayComposition */ #include @@ -71,4 +102,6 @@ gst_compat_element_class_set_static_metadata(GstElementClass *klass, typedef guint8 *(*GstCompatTypeFindPeekFunction)(gpointer, gint64, guint); typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, const GstCaps *); +#endif + #endif /* GST_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index d9ee4cddbe..2ef44036da 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -252,8 +252,30 @@ overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay, buffer = gst_video_overlay_rectangle_get_pixels_unscaled_raw(rect, flags); if (!buffer) return FALSE; +#if GST_CHECK_VERSION(1,0,0) + { + const guint n_blocks = gst_buffer_n_memory(buffer); + gsize ofs; + guint i; + + if (buffer == overlay->rect_buffer) + return TRUE; + + if (n_blocks != gst_buffer_n_memory(overlay->rect_buffer)) + return FALSE; + + for (i = 0; i < n_blocks; i++) { + GstMemory * const mem1 = gst_buffer_peek_memory(buffer, i); + GstMemory * const mem2 = + gst_buffer_peek_memory(overlay->rect_buffer, i); + if (!gst_memory_is_span(mem1, mem2, &ofs)) + return FALSE; + } + } +#else if (GST_BUFFER_DATA(overlay->rect_buffer) != GST_BUFFER_DATA(buffer)) return FALSE; +#endif return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 1801147038..77fe11995a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -111,7 +111,7 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) } GST_DEBUG("queue encoded data buffer %p (%d bytes)", - buffer, GST_BUFFER_SIZE(buffer)); + buffer, gst_buffer_get_size(buffer)); g_queue_push_tail(priv->buffers, buffer); return TRUE; @@ -128,7 +128,7 @@ pop_buffer(GstVaapiDecoder *decoder) return NULL; GST_DEBUG("dequeue buffer %p for decoding (%d bytes)", - buffer, GST_BUFFER_SIZE(buffer)); + buffer, gst_buffer_get_size(buffer)); return buffer; } @@ -662,7 +662,7 @@ gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf) g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); if (buf) { - if (!GST_BUFFER_DATA(buf) || GST_BUFFER_SIZE(buf) <= 0) + if (gst_buffer_get_size(buf) == 0) return TRUE; buf = gst_buffer_ref(buf); } @@ -950,6 +950,7 @@ gst_vaapi_decoder_decode_codec_data(GstVaapiDecoder *decoder) GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); GstVaapiDecoderStatus status; + GstMapInfo map_info; const guchar *buf; guint buf_size; @@ -960,11 +961,16 @@ gst_vaapi_decoder_decode_codec_data(GstVaapiDecoder *decoder) if (!klass->decode_codec_data) return GST_VAAPI_DECODER_STATUS_SUCCESS; - buf = GST_BUFFER_DATA(codec_data); - buf_size = GST_BUFFER_SIZE(codec_data); - if (!buf || buf_size == 0) - return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_buffer_map(codec_data, &map_info, GST_MAP_READ)) { + GST_ERROR("failed to map buffer"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } - status = klass->decode_codec_data(decoder, buf, buf_size); + buf = map_info.data; + buf_size = map_info.size; + if (G_LIKELY(buf && buf_size > 0)) + status = klass->decode_codec_data(decoder, buf, buf_size); + else + status = GST_VAAPI_DECODER_STATUS_SUCCESS; return status; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 49b482d093..6b6908242b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2700,6 +2700,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GstVaapiSlice *slice; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; + GstMapInfo map_info; GST_DEBUG("slice (%u bytes)", pi->nalu.size); @@ -2708,9 +2709,13 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; } + if (!gst_buffer_map(buffer, &map_info, GST_MAP_READ)) { + GST_ERROR("failed to map buffer"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + slice = GST_VAAPI_SLICE_NEW(H264, decoder, - (GST_BUFFER_DATA(buffer) + unit->offset + pi->nalu.offset), - pi->nalu.size); + (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -2918,7 +2923,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, } ps->input_offset2 = 0; - buf = (guchar *)gst_adapter_peek(adapter, buf_size); + buf = (guchar *)gst_adapter_map(adapter, buf_size); if (!buf) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index f1976a52c3..ba77436a58 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -680,17 +680,18 @@ gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderStatus status; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; - const guchar *buf; - guint buf_size; + GstMapInfo map_info; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - buf = GST_BUFFER_DATA(buffer) + unit->offset; - buf_size = unit->size; + 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, buf, buf_size); + status = decode_buffer(decoder, map_info.data + unit->offset, unit->size); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; return GST_VAAPI_DECODER_STATUS_SUCCESS; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 074d65e8e0..5c857e1f89 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1196,6 +1196,7 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) GstMpegVideoSliceHdr * const slice_hdr = unit->parsed_info; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; + GstMapInfo map_info; GST_DEBUG("slice %d (%u bytes)", slice_hdr->slice_vertical_position, unit->size); @@ -1203,8 +1204,13 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_buffer_map(buffer, &map_info, GST_MAP_READ)) { + GST_ERROR("failed to map buffer"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, - (GST_BUFFER_DATA(buffer) + unit->offset), unit->size); + (map_info.data + unit->offset), unit->size); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -1393,7 +1399,7 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, if (buf_size < 4) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - buf = gst_adapter_peek(adapter, buf_size); + buf = gst_adapter_map(adapter, buf_size); if (!buf) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; @@ -1476,12 +1482,18 @@ gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base_decoder, GstMpegVideoPacket packet; 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; - packet.data = GST_BUFFER_DATA(buffer) + unit->offset; + if (!gst_buffer_map(buffer, &map_info, GST_MAP_READ)) { + GST_ERROR("failed to map buffer"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + packet.data = map_info.data + unit->offset; packet.size = unit->size; packet.type = packet.data[3]; packet.offset = 4; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 1c4272e63a..d2a0b36541 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -1004,7 +1004,7 @@ gst_vaapi_decoder_mpeg4_parse(GstVaapiDecoder *base_decoder, return status; size = gst_adapter_available(adapter); - buf = gst_adapter_peek(adapter, size); + buf = gst_adapter_map(adapter, size); if (!buf) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; @@ -1085,17 +1085,18 @@ gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderStatus status; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; - const guchar *buf; - guint buf_size; + GstMapInfo map_info; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - buf = GST_BUFFER_DATA(buffer) + unit->offset; - buf_size = unit->size; + 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, buf, buf_size); + status = decode_buffer(decoder, map_info.data + unit->offset, unit->size); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; return GST_VAAPI_DECODER_STATUS_SUCCESS; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index dfa841826f..dbae6448cb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -315,9 +315,12 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) if (GST_VAAPI_PICTURE_IS_SKIPPED(picture)) GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); +#if !GST_CHECK_VERSION(1,0,0) + /* XXX: replaced with GST_VIDEO_BUFFER_FLAG_TFF */ if (GST_VAAPI_PICTURE_IS_TFF(picture)) GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, GST_VIDEO_CODEC_FRAME_FLAG_TFF); +#endif gst_vaapi_decoder_push_frame(GET_DECODER(picture), out_frame); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 702abcbf68..e063cd268b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1255,13 +1255,18 @@ gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderStatus status; 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; - status = decode_buffer(decoder, - (GST_BUFFER_DATA(buffer) + unit->offset), unit->size); + 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); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; return GST_VAAPI_DECODER_STATUS_SUCCESS; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 4a6dae0024..602dbb4a22 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -332,7 +332,7 @@ get_profile_caps(GArray *configs) config = &g_array_index(configs, GstVaapiConfig, i); caps = gst_vaapi_profile_get_caps(config->profile); if (caps) - gst_caps_merge(out_caps, caps); + out_caps = gst_caps_merge(out_caps, caps); } return out_caps; } diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 65d79a5e74..af72bee7e5 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -913,6 +913,24 @@ gst_vaapi_image_get_data_size(GstVaapiImage *image) return image->priv->image.data_size; } +#if GST_CHECK_VERSION(1,0,0) +#include + +static gboolean +init_image_from_video_meta(GstVaapiImageRaw *raw_image, GstVideoMeta *vmeta) +{ + GST_FIXME("map from GstVideoMeta + add fini_image_from_buffer()"); + return FALSE; +} + +static gboolean +init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) +{ + GstVideoMeta * const vmeta = gst_buffer_get_video_meta(buffer); + + return vmeta ? init_image_from_video_meta(raw_image, vmeta) : FALSE; +} +#else static gboolean init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) { @@ -989,6 +1007,7 @@ init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) } return TRUE; } +#endif /* Copy N lines of an image */ static inline void diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 69fe778eb8..1bbd6f3b10 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -50,10 +50,10 @@ struct _GstVaapiImageFormatMap { GST_VAAPI_IMAGE_##FORMAT, \ CAPS_STR #define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP) \ - { DEF(YCBCR, FORMAT, GST_VIDEO_CAPS_YUV(#FORMAT)), \ + { DEF(YCBCR, FORMAT, GST_VIDEO_CAPS_MAKE(#FORMAT)), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } #define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \ - { DEF(RGB, FORMAT, GST_VIDEO_CAPS_##FORMAT), \ + { DEF(RGB, FORMAT, GST_VIDEO_CAPS_MAKE(#FORMAT)), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } /* Image formats, listed in HW order preference */ diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 76a55c39ce..62089197db 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -91,7 +91,7 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-wmv, wmvversion=3", "main" }, { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, - "video/x-wmv, wmvversion=3, format=(fourcc)WVC1", "advanced" + "video/x-wmv, wmvversion=3, format=(string)WVC1", "advanced" }, #if VA_CHECK_VERSION(0,32,0) { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline, @@ -168,7 +168,10 @@ static GstVaapiProfile gst_vaapi_profile_from_codec_data_h264(GstBuffer *buffer) { /* MPEG-4 Part 15: Advanced Video Coding (AVC) file format */ - guchar * const buf = GST_BUFFER_DATA(buffer); + guchar buf[2]; + + if (gst_buffer_extract(buffer, 0, buf, sizeof(buf)) != sizeof(buf)) + return 0; if (buf[0] != 1) /* configurationVersion = 1 */ return 0; @@ -317,7 +320,7 @@ gst_vaapi_profile_get_caps(GstVaapiProfile profile) "profile", G_TYPE_STRING, m->profile_str, NULL ); - gst_caps_merge(out_caps, caps); + out_caps = gst_caps_merge(out_caps, caps); } return out_caps; } diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index b1c237b6dd..3d6d4413b8 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -304,6 +304,10 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( gfloat global_alpha; guint width, height, stride; guint hw_flags, flags; +#if GST_CHECK_VERSION(1,0,0) + GstVideoMeta *vmeta; + GstMapInfo map_info; +#endif g_return_val_if_fail(GST_IS_VIDEO_OVERLAY_RECTANGLE(rect), NULL); @@ -319,11 +323,28 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( flags = hw_flags & from_GstVideoOverlayFormatFlags( gst_video_overlay_rectangle_get_flags(rect)); +#if GST_CHECK_VERSION(1,0,0) buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect, + to_GstVideoOverlayFormatFlags(flags)); + if (!buffer) + return NULL; + + vmeta = gst_buffer_get_video_meta(buffer); + if (!vmeta) + return NULL; + width = vmeta->width; + height = vmeta->height; + + if (!gst_video_meta_map(vmeta, 0, &map_info, (gpointer *)&data, + (gint *)&stride, GST_MAP_READ)) + return NULL; +#else + buffer = (gst_video_overlay_rectangle_get_pixels_unscaled_argb)(rect, &width, &height, &stride, to_GstVideoOverlayFormatFlags(flags)); if (!buffer) return NULL; data = GST_BUFFER_DATA(buffer); +#endif image = gst_vaapi_image_new(display, format, width, height); if (!image) @@ -343,6 +364,9 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( subpicture = gst_vaapi_subpicture_new(image, flags); g_object_unref(image); +#if GST_CHECK_VERSION(1,0,0) + gst_video_meta_unmap(vmeta, 0, &map_info); +#endif if (!subpicture) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 2d98b5e67a..21f43cfd66 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -27,7 +27,6 @@ #include #include #include -#include #include G_BEGIN_DECLS @@ -37,7 +36,7 @@ G_BEGIN_DECLS * * Generic caps type for VA surfaces. */ -#define GST_VAAPI_SURFACE_CAPS_NAME GST_VIDEO_CAPS_SURFACE +#define GST_VAAPI_SURFACE_CAPS_NAME "video/x-surface" /** * GST_VAAPI_SURFACE_CAPS: From 13ca9f382cba888c4248956a76d7179f9f953cb5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Mar 2013 10:12:09 +0100 Subject: [PATCH 1129/3781] tests: add support for GStreamer 1.0. --- gst-libs/gst/vaapi/gstcompat.h | 9 +++++++++ tests/codec.c | 2 +- tests/decoder.c | 7 +++---- tests/simple-decoder.c | 9 ++++----- tests/test-subpicture.c | 23 ++++++++++++++++++++++- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index 1868dc1376..9d4d82a1a2 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -49,6 +49,15 @@ gst_compat_structure_get_fourcc(const GstStructure *structure, return TRUE; } +/* GstTypeFind */ +#undef GstTypeFindPeekFunction +#define GstTypeFindPeekFunction GstCompatTypeFindPeekFunction +#undef GstTypeFindSuggestFunction +#define GstTypeFindSuggestFunction GstCompatTypeFindSuggestFunction + +typedef const guint8 *(*GstCompatTypeFindPeekFunction)(gpointer, gint64, guint); +typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, GstCaps *); + /* ------------------------------------------------------------------------ */ /* --- GStreamer = 0.10 --- */ /* ------------------------------------------------------------------------ */ diff --git a/tests/codec.c b/tests/codec.c index fa690f1490..a1dd0812e6 100644 --- a/tests/codec.c +++ b/tests/codec.c @@ -41,7 +41,7 @@ static const CodecMap g_codec_map[] = { { "wmv3", GST_VAAPI_CODEC_VC1, "video/x-wmv, wmvversion=3" }, { "vc1", GST_VAAPI_CODEC_VC1, - "video/x-wmv, wmvversion=3, format=(fourcc)WVC1" }, + "video/x-wmv, wmvversion=3, format=(string)WVC1" }, { NULL, } }; diff --git a/tests/decoder.c b/tests/decoder.c index cb918c7076..881f0a1781 100644 --- a/tests/decoder.c +++ b/tests/decoder.c @@ -151,15 +151,14 @@ decoder_put_buffers(GstVaapiDecoder *decoder) codec = get_codec_defs(decoder); g_return_val_if_fail(codec != NULL, FALSE); - buffer = gst_buffer_new(); + codec->get_video_info(&info); + buffer = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY, + (guchar *)info.data, info.data_size, 0, info.data_size, NULL, NULL); if (!buffer) { GST_ERROR("failed to create encoded data buffer"); return FALSE; } - codec->get_video_info(&info); - gst_buffer_set_data(buffer, (guchar *)info.data, info.data_size); - success = gst_vaapi_decoder_put_buffer(decoder, buffer); gst_buffer_unref(buffer); if (!success) { diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index de299b4e34..04625a627b 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -251,13 +251,12 @@ decoder_thread(gpointer data) if (G_UNLIKELY(ofs == app->file_size)) buffer = NULL; else { - buffer = gst_buffer_new(); + const gsize size = MIN(4096, app->file_size - ofs); + buffer = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY, + app->file_data, app->file_size, ofs, size, NULL, NULL); if (!buffer) SEND_ERROR("failed to allocate new buffer"); - - GST_BUFFER_DATA(buffer) = app->file_data + ofs; - GST_BUFFER_SIZE(buffer) = MIN(4096, app->file_size - ofs); - ofs += GST_BUFFER_SIZE(buffer); + ofs += size; } if (!gst_vaapi_decoder_put_buffer(app->decoder, buffer)) SEND_ERROR("failed to push buffer to decoder"); diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 24482746ea..be1ec5832e 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -53,15 +53,22 @@ static GOptionEntry g_options[] = { static void upload_subpicture(GstBuffer *buffer, const VideoSubpictureInfo *subinfo) { - guint32 * const dst = (guint32 *)GST_BUFFER_DATA(buffer); const guint32 * const src = subinfo->data; guint i, len = subinfo->data_size / 4; + GstMapInfo map_info; + guint32 *dst; + + if (!gst_buffer_map(buffer, &map_info, GST_MAP_WRITE)) + return; + dst = (guint32 *)map_info.data; /* Convert from RGBA source to ARGB */ for (i = 0; i < len; i++) { const guint32 rgba = src[i]; dst[i] = (rgba >> 8) | (rgba << 24); } + + gst_buffer_unmap(buffer, &map_info); } int @@ -120,9 +127,23 @@ main(int argc, char *argv[]) subrect.height = subinfo.height; subrect.width = subinfo.width; +#if GST_CHECK_VERSION(1,0,0) + { + GstVideoMeta * const vmeta = + gst_buffer_add_video_meta(buffer, GST_VIDEO_FRAME_FLAG_NONE, + GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB, + subinfo.width, subinfo.height); + if (!vmeta) + g_error("could not create video meta"); + + overlay = gst_video_overlay_rectangle_new_raw(buffer, + subrect.x, subrect.y, subrect.width, subrect.height, flags); + } +#else overlay = gst_video_overlay_rectangle_new_argb(buffer, subinfo.width, subinfo.height, subinfo.width * 4, subrect.x, subrect.y, subrect.width, subrect.height, flags); +#endif if (!overlay) g_error("could not create video overlay"); gst_buffer_unref(buffer); From 38d84d968eb06b876a807f43e41896af27558ed5 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 3 Sep 2012 14:00:25 +0300 Subject: [PATCH 1130/3781] plugins: initial port to GStreamer 1.0. Port vaapidecode and vaapisink plugins to GStreamer API >= 1.0. This is rather minimalistic so that to test the basic functionality. Disable vaapiupload, vaapidownload and vaapipostproc plugins. The latter needs polishing wrt. to GStreamer 1.x functionality and the former are totally phased out in favor of GstVaapiVideoMemory map/unmap facilities, which are yet to be implemented. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/Makefile.am | 6 -- gst/vaapi/gstvaapi.c | 6 +- gst/vaapi/gstvaapidecode.c | 29 ++++--- gst/vaapi/gstvaapidownload.c | 2 - gst/vaapi/gstvaapipluginutil.c | 11 ++- gst/vaapi/gstvaapipostproc.c | 2 - gst/vaapi/gstvaapisink.c | 84 ++++++++++++++------ gst/vaapi/gstvaapiupload.c | 2 - gst/vaapi/gstvaapiuploader.c | 2 + gst/vaapi/gstvaapivideobuffer.c | 19 ++++- gst/vaapi/gstvaapivideoconverter_glx.c | 5 ++ gst/vaapi/gstvaapivideometa.c | 106 ++++++++++++++++++++++++- gst/vaapi/gstvaapivideometa.h | 9 +++ 13 files changed, 228 insertions(+), 55 deletions(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index c5955cb4c2..e8d663372a 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -32,11 +32,8 @@ endif libgstvaapi_source_c = \ gstvaapi.c \ gstvaapidecode.c \ - gstvaapidownload.c \ gstvaapipluginutil.c \ - gstvaapipostproc.c \ gstvaapisink.c \ - gstvaapiupload.c \ gstvaapiuploader.c \ gstvaapivideobuffer.c \ gstvaapivideometa.c \ @@ -44,11 +41,8 @@ libgstvaapi_source_c = \ libgstvaapi_source_h = \ gstvaapidecode.h \ - gstvaapidownload.h \ gstvaapipluginutil.h \ - gstvaapipostproc.h \ gstvaapisink.h \ - gstvaapiupload.h \ gstvaapiuploader.h \ gstvaapivideobuffer.h \ gstvaapivideometa.h \ diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 5a6462f9d1..909be71dc0 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -32,18 +32,22 @@ static gboolean plugin_init (GstPlugin *plugin) { +#if !GST_CHECK_VERSION(1,0,0) gst_element_register(plugin, "vaapidownload", GST_RANK_SECONDARY, GST_TYPE_VAAPIDOWNLOAD); gst_element_register(plugin, "vaapiupload", GST_RANK_PRIMARY, GST_TYPE_VAAPIUPLOAD); +#endif gst_element_register(plugin, "vaapidecode", GST_RANK_PRIMARY, GST_TYPE_VAAPIDECODE); +#if !GST_CHECK_VERSION(1,0,0) gst_element_register(plugin, "vaapipostproc", GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); +#endif gst_element_register(plugin, "vaapisink", GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); @@ -52,7 +56,7 @@ plugin_init (GstPlugin *plugin) GST_PLUGIN_DEFINE( GST_VERSION_MAJOR, GST_VERSION_MINOR, - "vaapi", + vaapi, "VA-API based elements", plugin_init, PACKAGE_VERSION, diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 58c3358727..77c437ba82 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -80,6 +80,7 @@ static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_STATIC_CAPS(gst_vaapidecode_src_caps_str)); /* GstImplementsInterface interface */ +#if !GST_CHECK_VERSION(1,0,0) static gboolean gst_vaapidecode_implements_interface_supported( GstImplementsInterface *iface, @@ -94,6 +95,7 @@ gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface) { iface->supported = gst_vaapidecode_implements_interface_supported; } +#endif /* GstVideoContext interface */ static void @@ -115,8 +117,10 @@ G_DEFINE_TYPE_WITH_CODE( GstVaapiDecode, gst_vaapidecode, GST_TYPE_VIDEO_DECODER, +#if !GST_CHECK_VERSION(1,0,0) G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapidecode_implements_iface_init); +#endif G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init)) @@ -233,7 +237,7 @@ error_decode_timeout: { GST_WARNING("decode timeout. Decoder required a VA surface but none " "got available within one second"); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } error_decode: { @@ -245,7 +249,7 @@ error_decode: ret = GST_FLOW_NOT_SUPPORTED; break; default: - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; break; } gst_video_decoder_drop_frame(vdec, frame); @@ -301,13 +305,13 @@ error_create_buffer: GST_VAAPI_ID_ARGS(surface_id)); gst_video_decoder_drop_frame(vdec, out_frame); gst_video_codec_frame_unref(out_frame); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } error_commit_buffer: { GST_DEBUG("video sink rejected the video buffer (error %d)", ret); gst_video_codec_frame_unref(out_frame); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } } @@ -337,7 +341,7 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) error_flush: { GST_ERROR("failed to flush decoder (status %d)", status); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } } @@ -535,7 +539,7 @@ gst_vaapidecode_parse(GstVideoDecoder *vdec, break; default: GST_ERROR("parse error %d", status); - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; break; } return ret; @@ -571,12 +575,10 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapidecode_sink_factory); gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); /* src pad */ pad_template = gst_static_pad_template_get(&gst_vaapidecode_src_factory); gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); } static gboolean @@ -615,7 +617,8 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL ); - gst_caps_merge_structure(decode->allowed_caps, structure); + decode->allowed_caps = + gst_caps_merge_structure(decode->allowed_caps, structure); } gst_caps_unref(decode_caps); @@ -652,7 +655,7 @@ gst_vaapidecode_get_caps(GstPad *pad) } static gboolean -gst_vaapidecode_query (GstPad *pad, GstQuery *query) { +gst_vaapidecode_query (GstPad *pad, GstObject *parent, GstQuery *query) { GstVaapiDecode *decode = GST_VAAPIDECODE (gst_pad_get_parent_element (pad)); gboolean res; @@ -661,9 +664,9 @@ gst_vaapidecode_query (GstPad *pad, GstQuery *query) { if (gst_vaapi_reply_to_query (query, decode->display)) res = TRUE; else if (GST_PAD_IS_SINK(pad)) - res = decode->sinkpad_query(decode->sinkpad, query); + res = decode->sinkpad_query(decode->sinkpad, parent, query); else - res = decode->srcpad_query(decode->srcpad, query); + res = decode->srcpad_query(decode->srcpad, parent, query); g_object_unref (decode); return res; @@ -690,7 +693,9 @@ gst_vaapidecode_init(GstVaapiDecode *decode) decode->sinkpad = GST_VIDEO_DECODER_SINK_PAD(vdec); decode->sinkpad_query = GST_PAD_QUERYFUNC(decode->sinkpad); gst_pad_set_query_function(decode->sinkpad, gst_vaapidecode_query); +#if !GST_CHECK_VERSION(1,0,0) gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps); +#endif /* Pad through which data goes out of the element */ decode->srcpad = GST_VIDEO_DECODER_SRC_PAD(vdec); diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index f90cfa2af9..a122258599 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -237,12 +237,10 @@ gst_vaapidownload_class_init(GstVaapiDownloadClass *klass) /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapidownload_sink_factory); gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); /* src pad */ pad_template = gst_static_pad_template_get(&gst_vaapidownload_src_factory); gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); } static void diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index b2cc92f1d4..6364fbb188 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -335,9 +335,18 @@ gst_vaapi_append_surface_caps(GstCaps *out_caps, GstCaps *in_caps) gboolean gst_vaapi_apply_composition(GstVaapiSurface *surface, GstBuffer *buffer) { +#if GST_CHECK_VERSION(1,0,0) + GstVideoOverlayCompositionMeta * const cmeta = + gst_buffer_get_video_overlay_composition_meta(buffer); + GstVideoOverlayComposition *composition; + + if (!cmeta) + return TRUE; + composition = cmeta->overlay; +#else GstVideoOverlayComposition * const composition = gst_video_buffer_get_overlay_composition(buffer); - +#endif if (!composition) return TRUE; return gst_vaapi_surface_set_subpictures_from_composition(surface, diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index bb0d76c12d..534017e693 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -651,12 +651,10 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapipostproc_sink_factory); gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); /* src pad */ pad_template = gst_static_pad_template_get(&gst_vaapipostproc_src_factory); gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); /** * GstVaapiPostproc:deinterlace-mode: diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 1bf8026a0e..28c61f1279 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -51,7 +51,21 @@ #endif /* Supported interfaces */ -#include +#if GST_CHECK_VERSION(1,0,0) +# include +#else +# include + +# define GST_TYPE_VIDEO_OVERLAY GST_TYPE_X_OVERLAY +# define GST_VIDEO_OVERLAY GST_X_OVERLAY +# define GstVideoOverlay GstXOverlay +# define GstVideoOverlayInterface GstXOverlayClass + +# define gst_video_overlay_prepare_window_handle(sink) \ + gst_x_overlay_prepare_xwindow_id(sink) +# define gst_video_overlay_got_window_handle(sink, window_handle) \ + gst_x_overlay_got_window_handle(sink, window_handle) +#endif #include "gstvaapisink.h" #include "gstvaapipluginutil.h" @@ -65,9 +79,11 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink); /* Default template */ static const char gst_vaapisink_sink_caps_str[] = +#if !GST_CHECK_VERSION(1,0,0) "video/x-raw-yuv, " "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]; " +#endif GST_VAAPI_SURFACE_CAPS; static GstStaticPadTemplate gst_vaapisink_sink_factory = @@ -78,6 +94,7 @@ static GstStaticPadTemplate gst_vaapisink_sink_factory = GST_STATIC_CAPS(gst_vaapisink_sink_caps_str)); /* GstImplementsInterface interface */ +#if !GST_CHECK_VERSION(1,0,0) static gboolean gst_vaapisink_implements_interface_supported( GstImplementsInterface *iface, @@ -85,7 +102,7 @@ gst_vaapisink_implements_interface_supported( ) { return (type == GST_TYPE_VIDEO_CONTEXT || - type == GST_TYPE_X_OVERLAY); + type == GST_TYPE_VIDEO_OVERLAY); } static void @@ -93,6 +110,7 @@ gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface) { iface->supported = gst_vaapisink_implements_interface_supported; } +#endif /* GstVideoContext interface */ static void @@ -110,18 +128,20 @@ gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface) } static void -gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface); +gst_vaapisink_video_overlay_iface_init(GstVideoOverlayInterface *iface); G_DEFINE_TYPE_WITH_CODE( GstVaapiSink, gst_vaapisink, GST_TYPE_VIDEO_SINK, +#if !GST_CHECK_VERSION(1,0,0) G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapisink_implements_iface_init); +#endif G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_vaapisink_video_context_iface_init); - G_IMPLEMENT_INTERFACE(GST_TYPE_X_OVERLAY, - gst_vaapisink_xoverlay_iface_init)) + G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_OVERLAY, + gst_vaapisink_video_overlay_iface_init)) enum { PROP_0, @@ -136,7 +156,7 @@ enum { #define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 -/* GstXOverlay interface */ +/* GstVideoOverlay interface */ #if USE_X11 static gboolean @@ -147,7 +167,7 @@ static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); static void -gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window) +gst_vaapisink_video_overlay_set_window_handle(GstVideoOverlay *overlay, guintptr window) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); @@ -170,8 +190,8 @@ gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window) } static void -gst_vaapisink_xoverlay_set_render_rectangle( - GstXOverlay *overlay, +gst_vaapisink_video_overlay_set_render_rectangle( + GstVideoOverlay *overlay, gint x, gint y, gint width, @@ -192,12 +212,19 @@ gst_vaapisink_xoverlay_set_render_rectangle( } static void -gst_vaapisink_xoverlay_expose(GstXOverlay *overlay) +gst_vaapisink_video_overlay_expose(GstVideoOverlay *overlay) { GstBaseSink * const base_sink = GST_BASE_SINK(overlay); GstBuffer *buffer; +#if GST_CHECK_VERSION(1,0,0) + GstSample * const sample = gst_base_sink_get_last_sample(base_sink); + if (!sample) + return; + buffer = gst_sample_get_buffer(sample); +#else buffer = gst_base_sink_get_last_buffer(base_sink); +#endif if (buffer) { gst_vaapisink_show_frame(base_sink, buffer); gst_buffer_unref(buffer); @@ -205,11 +232,11 @@ gst_vaapisink_xoverlay_expose(GstXOverlay *overlay) } static void -gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface) +gst_vaapisink_video_overlay_iface_init(GstVideoOverlayInterface *iface) { - iface->set_window_handle = gst_vaapisink_xoverlay_set_window_handle; - iface->set_render_rectangle = gst_vaapisink_xoverlay_set_render_rectangle; - iface->expose = gst_vaapisink_xoverlay_expose; + iface->set_window_handle = gst_vaapisink_video_overlay_set_window_handle; + iface->set_render_rectangle = gst_vaapisink_video_overlay_set_render_rectangle; + iface->expose = gst_vaapisink_video_overlay_expose; } static void @@ -443,16 +470,16 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) #if USE_GLX case GST_VAAPI_DISPLAY_TYPE_GLX: sink->window = gst_vaapi_window_glx_new(display, width, height); - goto notify_xoverlay_interface; + goto notify_video_overlay_interface; #endif #if USE_X11 case GST_VAAPI_DISPLAY_TYPE_X11: sink->window = gst_vaapi_window_x11_new(display, width, height); - notify_xoverlay_interface: + notify_video_overlay_interface: if (!sink->window) break; - gst_x_overlay_got_window_handle( - GST_X_OVERLAY(sink), + gst_video_overlay_got_window_handle( + GST_VIDEO_OVERLAY(sink), gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) ); break; @@ -589,7 +616,7 @@ gst_vaapisink_stop(GstBaseSink *base_sink) } static GstCaps * -gst_vaapisink_get_caps(GstBaseSink *base_sink) +gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstCaps *out_caps, *yuv_caps; @@ -642,7 +669,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) } else { gst_vaapi_display_lock(sink->display); - gst_x_overlay_prepare_xwindow_id(GST_X_OVERLAY(sink)); + gst_video_overlay_prepare_window_handle(GST_VIDEO_OVERLAY(sink)); gst_vaapi_display_unlock(sink->display); if (sink->window) return TRUE; @@ -840,24 +867,30 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) gboolean success; meta = gst_buffer_get_vaapi_video_meta(src_buffer); +#if GST_CHECK_VERSION(1,0,0) + if (!meta) + return GST_FLOW_EOS; + buffer = gst_buffer_ref(src_buffer); +#else if (meta) buffer = gst_buffer_ref(src_buffer); else if (sink->use_video_raw) { buffer = gst_vaapi_uploader_get_buffer(sink->uploader); if (!buffer) - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; meta = gst_buffer_get_vaapi_video_meta(buffer); if (!meta) goto error; } else - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; if (sink->use_video_raw && !gst_vaapi_uploader_process(sink->uploader, src_buffer, buffer)) { GST_WARNING("failed to process raw YUV buffer"); goto error; } +#endif if (sink->display != gst_vaapi_video_meta_get_display(meta)) { g_clear_object(&sink->display); @@ -918,9 +951,10 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) error: gst_buffer_unref(buffer); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } +#if !GST_CHECK_VERSION(1,0,0) static GstFlowReturn gst_vaapisink_buffer_alloc( GstBaseSink *base_sink, @@ -961,6 +995,7 @@ gst_vaapisink_buffer_alloc( *pbuf = buf; return GST_FLOW_OK; } +#endif static gboolean gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query) @@ -1069,7 +1104,9 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->preroll = gst_vaapisink_show_frame; basesink_class->render = gst_vaapisink_show_frame; basesink_class->query = gst_vaapisink_query; +#if !GST_CHECK_VERSION(1,0,0) basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; +#endif gst_element_class_set_static_metadata(element_class, "VA-API sink", @@ -1079,7 +1116,6 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) pad_template = gst_static_pad_template_get(&gst_vaapisink_sink_factory); gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); g_object_class_install_property (object_class, diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index ecb0743e65..50c8c9ff6b 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -215,12 +215,10 @@ gst_vaapiupload_class_init(GstVaapiUploadClass *klass) /* sink pad */ pad_template = gst_static_pad_template_get(&gst_vaapiupload_sink_factory); gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); /* src pad */ pad_template = gst_static_pad_template_get(&gst_vaapiupload_src_factory); gst_element_class_add_pad_template(element_class, pad_template); - gst_object_unref(pad_template); } static void diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index a0d5ef1357..ac7afd745f 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -449,10 +449,12 @@ gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) goto error; } +#if 0 GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0); GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image); gst_buffer_set_caps(buffer, priv->image_caps); +#endif return buffer; error: diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index c6c1a0ac2c..1ae3f794c7 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -26,12 +26,20 @@ */ #include "gst/vaapi/sysdeps.h" -#include #include "gstvaapivideobuffer.h" #if USE_GLX # include "gstvaapivideoconverter_glx.h" #endif +#if GST_CHECK_VERSION(1,0,0) +static inline GstBuffer * +gst_surface_buffer_new(void) +{ + return gst_buffer_new(); +} +#else +#include + #define GST_VAAPI_TYPE_VIDEO_BUFFER \ (gst_vaapi_video_buffer_get_type()) @@ -117,6 +125,13 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) { } +static inline GstBuffer * +gst_surface_buffer_new(void) +{ + return GST_BUFFER_CAST(gst_mini_object_new(GST_TYPE_SURFACE_BUFFER)); +} +#endif + static GFunc get_surface_converter(GstVaapiDisplay *display) { @@ -145,7 +160,7 @@ new_vbuffer(GstVaapiVideoMeta *meta) gst_vaapi_video_meta_set_surface_converter(meta, get_surface_converter(gst_vaapi_video_meta_get_display(meta))); - buffer = GST_BUFFER_CAST(gst_mini_object_new(GST_TYPE_SURFACE_BUFFER)); + buffer = gst_surface_buffer_new(); if (buffer) gst_buffer_set_vaapi_video_meta(buffer, meta); gst_vaapi_video_meta_unref(meta); diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index 323013f39b..cfbf163b9b 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -27,8 +27,13 @@ #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" +#if GST_CHECK_VERSION(1,0,0) +typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *, + GstBuffer *); +#else typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *, GstSurfaceBuffer *); +#endif static void gst_vaapi_video_converter_glx_iface_init(GstSurfaceConverterInterface *iface); diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index 2b4370093d..18d10e85b0 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -30,9 +30,6 @@ #include #include "gstvaapivideometa.h" -#define GST_VAAPI_TYPE_VIDEO_META \ - (gst_vaapi_video_meta_get_type()) - #define GST_VAAPI_VIDEO_META(obj) \ ((GstVaapiVideoMeta *)(obj)) @@ -100,6 +97,8 @@ gst_vaapi_video_meta_destroy_surface(GstVaapiVideoMeta *meta) g_clear_object(&meta->surface_pool); } +#if !GST_CHECK_VERSION(1,0,0) +#define GST_VAAPI_TYPE_VIDEO_META gst_vaapi_video_meta_get_type() static GType gst_vaapi_video_meta_get_type(void) { @@ -114,6 +113,7 @@ gst_vaapi_video_meta_get_type(void) } return (GType)g_type; } +#endif static void gst_vaapi_video_meta_finalize(GstVaapiVideoMeta *meta) @@ -649,6 +649,105 @@ gst_vaapi_video_meta_set_render_flags(GstVaapiVideoMeta *meta, guint flags) meta->render_flags = flags; } +#if GST_CHECK_VERSION(1,0,0) + +#define GST_VAAPI_VIDEO_META_HOLDER(meta) \ + ((GstVaapiVideoMetaHolder *)(meta)) + +typedef struct _GstVaapiVideoMetaHolder GstVaapiVideoMetaHolder; +struct _GstVaapiVideoMetaHolder { + GstMeta base; + GstVaapiVideoMeta *meta; +}; + +static gboolean +gst_vaapi_video_meta_holder_init(GstVaapiVideoMetaHolder *meta, + gpointer params, GstBuffer *buffer) +{ + meta->meta = NULL; + return TRUE; +} + +static void +gst_vaapi_video_meta_holder_free(GstVaapiVideoMetaHolder *meta, + GstBuffer *buffer) +{ + if (meta->meta) + gst_vaapi_video_meta_unref(meta->meta); +} + +static gboolean +gst_vaapi_video_meta_holder_transform(GstBuffer *dst_buffer, GstMeta *meta, + GstBuffer *src_buffer, GQuark type, gpointer data) +{ + GstVaapiVideoMetaHolder * const src_meta = + GST_VAAPI_VIDEO_META_HOLDER(meta); + + if (GST_META_TRANSFORM_IS_COPY(type)) { + gst_buffer_set_vaapi_video_meta(dst_buffer, src_meta->meta); + return TRUE; + } + return FALSE; +} + +GType +gst_vaapi_video_meta_api_get_type(void) +{ + static gsize g_type; + static const gchar *tags[] = { "memory", NULL }; + + if (g_once_init_enter(&g_type)) { + GType type = gst_meta_api_type_register("GstVaapiVideoMetaAPI", tags); + g_once_init_leave(&g_type, type); + } + return g_type; +} + +#define GST_VAAPI_VIDEO_META_INFO gst_vaapi_video_meta_info_get() +static const GstMetaInfo * +gst_vaapi_video_meta_info_get(void) +{ + static gsize g_meta_info; + + if (g_once_init_enter(&g_meta_info)) { + gsize meta_info = GPOINTER_TO_SIZE(gst_meta_register( + GST_VAAPI_VIDEO_META_API_TYPE, + "GstVaapiVideoMeta", sizeof(GstVaapiVideoMetaHolder), + (GstMetaInitFunction)gst_vaapi_video_meta_holder_init, + (GstMetaFreeFunction)gst_vaapi_video_meta_holder_free, + (GstMetaTransformFunction)gst_vaapi_video_meta_holder_transform)); + g_once_init_leave(&g_meta_info, meta_info); + } + return GSIZE_TO_POINTER(g_meta_info); +} + +GstVaapiVideoMeta * +gst_buffer_get_vaapi_video_meta(GstBuffer *buffer) +{ + GstMeta *m; + + g_return_val_if_fail(GST_IS_BUFFER(buffer), NULL); + + m = gst_buffer_get_meta(buffer, GST_VAAPI_VIDEO_META_API_TYPE); + if (!m) + return NULL; + return GST_VAAPI_VIDEO_META_HOLDER(m)->meta; +} + +void +gst_buffer_set_vaapi_video_meta(GstBuffer *buffer, GstVaapiVideoMeta *meta) +{ + GstMeta *m; + + g_return_if_fail(GST_IS_BUFFER(buffer)); + g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + + m = gst_buffer_add_meta(buffer, GST_VAAPI_VIDEO_META_INFO, NULL); + if (m) + GST_VAAPI_VIDEO_META_HOLDER(m)->meta = gst_vaapi_video_meta_ref(meta); +} +#else + #define GST_VAAPI_VIDEO_META_QUARK gst_vaapi_video_meta_quark_get() static GQuark gst_vaapi_video_meta_quark_get(void) @@ -704,3 +803,4 @@ gst_buffer_set_vaapi_video_meta(GstBuffer *buffer, GstVaapiVideoMeta *meta) gst_structure_id_new(GST_VAAPI_VIDEO_META_QUARK, META_QUARK, GST_VAAPI_TYPE_VIDEO_META, meta, NULL)); } +#endif diff --git a/gst/vaapi/gstvaapivideometa.h b/gst/vaapi/gstvaapivideometa.h index 47d07e345d..2d566497fb 100644 --- a/gst/vaapi/gstvaapivideometa.h +++ b/gst/vaapi/gstvaapivideometa.h @@ -33,6 +33,15 @@ G_BEGIN_DECLS typedef struct _GstVaapiVideoMeta GstVaapiVideoMeta; +#if GST_CHECK_VERSION(1,0,0) +#define GST_VAAPI_VIDEO_META_API_TYPE \ + gst_vaapi_video_meta_api_get_type() + +G_GNUC_INTERNAL +GType +gst_vaapi_video_meta_api_get_type(void) G_GNUC_CONST; +#endif + G_GNUC_INTERNAL GstVaapiVideoMeta * gst_vaapi_video_meta_new(GstVaapiDisplay *display); From 8fe00114502c0f4afcb080d6ac3434416ea5b7fb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 4 Apr 2013 16:16:31 +0200 Subject: [PATCH 1131/3781] plugins: make it possible to clear VA objects from GstVaapiVideoMeta. Fix GstVaapiVideoMeta to allow VA objects to be destroyed when they are reset to NULL. i.e. make gst_vaapi_video_meta_set_{image,surface}() and gst_vaapi_video_meta_set_surface_proxy() actually clear VA objects when argument is NULL. --- gst/vaapi/gstvaapivideometa.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index 18d10e85b0..aef63102a4 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -424,7 +424,6 @@ void gst_vaapi_video_meta_set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image) { g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); - g_return_if_fail(GST_VAAPI_IS_IMAGE(image)); gst_vaapi_video_meta_destroy_image(meta); @@ -497,7 +496,6 @@ gst_vaapi_video_meta_set_surface(GstVaapiVideoMeta *meta, GstVaapiSurface *surface) { g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); - g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); gst_vaapi_video_meta_destroy_surface(meta); @@ -572,7 +570,6 @@ gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, GstVaapiSurface *surface; g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); - g_return_if_fail(proxy != NULL); gst_vaapi_video_meta_destroy_surface(meta); From c8db926547eeba02f1e6499d89cdc9aba45c0082 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 4 Apr 2013 17:36:45 +0200 Subject: [PATCH 1132/3781] plugins: allow copies of GstVaapiVideoMeta objects. Make it possible to copy GstVaapiVideoMeta objects, unless they contain VA objects created from GstVaapiVideoPool. This is mostly useful to clone a GstVaapiVideoMeta object containing a VA surface proxy so that to alter its rendering flags. --- gst/vaapi/gstvaapivideometa.c | 58 +++++++++++++++++++++++++++++++++-- gst/vaapi/gstvaapivideometa.h | 4 +++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index aef63102a4..a6f4a1442c 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -137,12 +137,24 @@ gst_vaapi_video_meta_init(GstVaapiVideoMeta *meta) meta->render_flags = 0; } +static inline GstVaapiVideoMeta * +_gst_vaapi_video_meta_create(void) +{ + return g_slice_new(GstVaapiVideoMeta); +} + +static inline void +_gst_vaapi_video_meta_destroy(GstVaapiVideoMeta *meta) +{ + g_slice_free1(sizeof(*meta), meta); +} + static inline GstVaapiVideoMeta * _gst_vaapi_video_meta_new(void) { GstVaapiVideoMeta *meta; - meta = g_slice_alloc(sizeof(*meta)); + meta = _gst_vaapi_video_meta_create(); if (!meta) return NULL; gst_vaapi_video_meta_init(meta); @@ -157,7 +169,44 @@ _gst_vaapi_video_meta_free(GstVaapiVideoMeta *meta) gst_vaapi_video_meta_finalize(meta); if (G_LIKELY(g_atomic_int_dec_and_test(&meta->ref_count))) - g_slice_free1(sizeof(*meta), meta); + _gst_vaapi_video_meta_destroy(meta); +} + +/** + * gst_vaapi_video_meta_copy: + * @meta: a #GstVaapiVideoMeta + * + * Creates a copy of #GstVaapiVideoMeta object @meta. The original + * @meta object shall not contain any VA objects created from a + * #GstVaapiVideoPool. + * + * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL on error + */ +GstVaapiVideoMeta * +gst_vaapi_video_meta_copy(GstVaapiVideoMeta *meta) +{ + GstVaapiVideoMeta *copy; + + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + + if (meta->image_pool || meta->surface_pool) + return NULL; + + copy = _gst_vaapi_video_meta_create(); + if (!copy) + return NULL; + + copy->ref_count = 1; + copy->display = g_object_ref(meta->display); + copy->image_pool = NULL; + copy->image = meta->image ? g_object_ref(meta->image) : NULL; + copy->surface_pool = NULL; + copy->surface = meta->surface ? g_object_ref(meta->surface) : NULL; + copy->proxy = meta->proxy ? + gst_vaapi_surface_proxy_ref(meta->proxy) : NULL; + copy->converter = meta->converter; + copy->render_flags = meta->render_flags; + return copy; } /** @@ -681,7 +730,10 @@ gst_vaapi_video_meta_holder_transform(GstBuffer *dst_buffer, GstMeta *meta, GST_VAAPI_VIDEO_META_HOLDER(meta); if (GST_META_TRANSFORM_IS_COPY(type)) { - gst_buffer_set_vaapi_video_meta(dst_buffer, src_meta->meta); + GstVaapiVideoMeta * const dst_meta = + gst_vaapi_video_meta_copy(src_meta->meta); + gst_buffer_set_vaapi_video_meta(dst_buffer, dst_meta); + gst_vaapi_video_meta_unref(dst_meta); return TRUE; } return FALSE; diff --git a/gst/vaapi/gstvaapivideometa.h b/gst/vaapi/gstvaapivideometa.h index 2d566497fb..93b40ed68a 100644 --- a/gst/vaapi/gstvaapivideometa.h +++ b/gst/vaapi/gstvaapivideometa.h @@ -42,6 +42,10 @@ GType gst_vaapi_video_meta_api_get_type(void) G_GNUC_CONST; #endif +G_GNUC_INTERNAL +GstVaapiVideoMeta * +gst_vaapi_video_meta_copy(GstVaapiVideoMeta *meta); + G_GNUC_INTERNAL GstVaapiVideoMeta * gst_vaapi_video_meta_new(GstVaapiDisplay *display); From 5b11b833210e5097aad60af873556e5b6af63e7d Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 8 Nov 2012 16:41:22 +0200 Subject: [PATCH 1133/3781] plugins: add GstVaapiVideoMemory and GstVaapiVideoBufferPool objects. Add initial support for GstVaapiVideoMemory backed buffer pool. The memory object currently holds a reference to GstVaapiVideoMeta. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/Makefile.am | 10 + gst/vaapi/gstvaapivideobufferpool.c | 283 ++++++++++++++++++++++++++++ gst/vaapi/gstvaapivideobufferpool.h | 91 +++++++++ gst/vaapi/gstvaapivideomemory.c | 177 +++++++++++++++++ gst/vaapi/gstvaapivideomemory.h | 113 +++++++++++ 5 files changed, 674 insertions(+) create mode 100644 gst/vaapi/gstvaapivideobufferpool.c create mode 100644 gst/vaapi/gstvaapivideobufferpool.h create mode 100644 gst/vaapi/gstvaapivideomemory.c create mode 100644 gst/vaapi/gstvaapivideomemory.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index e8d663372a..dd730bb12e 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -53,6 +53,16 @@ libgstvaapi_source_c += gstvaapivideoconverter_glx.c libgstvaapi_source_h += gstvaapivideoconverter_glx.h endif +libgstvaapi_source_c += \ + gstvaapivideobufferpool.c \ + gstvaapivideomemory.c \ + $(NULL) + +libgstvaapi_source_h += \ + gstvaapivideobufferpool.h \ + gstvaapivideomemory.h \ + $(NULL) + libgstvaapi_la_SOURCES = $(libgstvaapi_source_c) noinst_HEADERS = $(libgstvaapi_source_h) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c new file mode 100644 index 0000000000..06e8d85549 --- /dev/null +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -0,0 +1,283 @@ +/* + * gstvaapivideobufferpool.c - Gstreamer/VA video buffer pool + * + * Copyright (C) 2013 Intel Corporation + * + * 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 "gst/vaapi/sysdeps.h" +#include "gstvaapivideobufferpool.h" +#include "gstvaapivideobuffer.h" +#include "gstvaapivideomemory.h" + +GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideopool); +#define GST_CAT_DEFAULT gst_debug_vaapivideopool + +G_DEFINE_TYPE(GstVaapiVideoBufferPool, + gst_vaapi_video_buffer_pool, + GST_TYPE_BUFFER_POOL) + +enum { + PROP_0, + + PROP_DISPLAY, +}; + +struct _GstVaapiVideoBufferPoolPrivate { + GstAllocator *allocator; + GstVaapiDisplay *display; + guint has_video_meta : 1; +}; + +#define GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, \ + GstVaapiVideoBufferPoolPrivate)) + +static void +gst_vaapi_video_buffer_pool_finalize(GObject *object) +{ + GstVaapiVideoBufferPoolPrivate * const priv = + GST_VAAPI_VIDEO_BUFFER_POOL(object)->priv; + + G_OBJECT_CLASS(gst_vaapi_video_buffer_pool_parent_class)->finalize(object); + + g_clear_object(&priv->display); + g_clear_object(&priv->allocator); +} + +static void +gst_vaapi_video_buffer_pool_set_property(GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + GstVaapiVideoBufferPoolPrivate * const priv = + GST_VAAPI_VIDEO_BUFFER_POOL(object)->priv; + + switch (prop_id) { + case PROP_DISPLAY: + priv->display = g_object_ref(g_value_get_object(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_video_buffer_pool_get_property(GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + GstVaapiVideoBufferPoolPrivate * const priv = + GST_VAAPI_VIDEO_BUFFER_POOL(object)->priv; + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_object(value, priv->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static const gchar ** +gst_vaapi_video_buffer_pool_get_options(GstBufferPool *pool) +{ + static const gchar *g_options[] = { + GST_BUFFER_POOL_OPTION_VIDEO_META, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META, + NULL, + }; + return g_options; +} + +static gboolean +gst_vaapi_video_buffer_pool_set_config(GstBufferPool *pool, + GstStructure *config) +{ + GstVaapiVideoBufferPoolPrivate * const priv = + GST_VAAPI_VIDEO_BUFFER_POOL(pool)->priv; + GstCaps *caps = NULL; + + if (!gst_buffer_pool_config_get_params(config, &caps, NULL, NULL, NULL)) + goto error_invalid_config; + if (!caps) + goto error_no_caps; + + g_clear_object(&priv->allocator); + priv->allocator = gst_vaapi_video_allocator_new(priv->display, caps); + if (!priv->allocator) + goto error_create_allocator; + + if (!gst_buffer_pool_config_has_option(config, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) + goto error_no_vaapi_video_meta_option; + + priv->has_video_meta = gst_buffer_pool_config_has_option(config, + GST_BUFFER_POOL_OPTION_VIDEO_META); + + return GST_BUFFER_POOL_CLASS(gst_vaapi_video_buffer_pool_parent_class)-> + set_config(pool, config); + + /* ERRORS */ +error_invalid_config: + { + GST_ERROR("invalid config"); + return FALSE; + } +error_no_caps: + { + GST_ERROR("no caps in config"); + return FALSE; + } +error_create_allocator: + { + GST_ERROR("failed to create GstVaapiVideoAllocator object"); + return FALSE; + } +error_no_vaapi_video_meta_option: + { + GST_ERROR("no GstVaapiVideoMeta option"); + return FALSE; + } +} + +static GstFlowReturn +gst_vaapi_video_buffer_pool_alloc_buffer(GstBufferPool *pool, + GstBuffer **out_buffer_ptr, GstBufferPoolAcquireParams *params) +{ + GstVaapiVideoBufferPoolPrivate * const priv = + GST_VAAPI_VIDEO_BUFFER_POOL(pool)->priv; + GstVaapiVideoMeta *meta; + GstMemory *mem; + GstBuffer *buffer; + + if (!priv->allocator) + goto error_no_allocator; + + meta = gst_vaapi_video_meta_new(priv->display); + if (!meta) + goto error_create_meta; + + buffer = gst_vaapi_video_buffer_new(meta); + if (!buffer) + goto error_create_buffer; + + mem = gst_vaapi_video_memory_new(priv->allocator, meta); + if (!mem) + goto error_create_memory; + gst_vaapi_video_meta_unref(meta); + gst_buffer_append_memory(buffer, mem); + + if (priv->has_video_meta) { + GstVideoInfo * const vip = + &GST_VAAPI_VIDEO_ALLOCATOR_CAST(priv->allocator)->video_info; + + gst_buffer_add_video_meta(buffer, 0, GST_VIDEO_INFO_FORMAT(vip), + GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + } + + *out_buffer_ptr = buffer; + return GST_FLOW_OK; + + /* ERRORS */ +error_no_allocator: + { + GST_ERROR("no GstAllocator in buffer pool"); + return GST_FLOW_ERROR; + } +error_create_meta: + { + GST_ERROR("failed to allocate vaapi video meta"); + return GST_FLOW_ERROR; + } +error_create_buffer: + { + GST_ERROR("failed to create video buffer"); + gst_vaapi_video_meta_unref(meta); + return GST_FLOW_ERROR; + } +error_create_memory: + { + GST_ERROR("failed to create video memory"); + gst_buffer_unref(buffer); + gst_vaapi_video_meta_unref(meta); + return GST_FLOW_ERROR; + } +} + +static void +gst_vaapi_video_buffer_pool_reset_buffer(GstBufferPool *pool, GstBuffer *buffer) +{ + GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); + + /* Release the underlying surface proxy */ + gst_vaapi_video_meta_set_surface_proxy(meta, NULL); + + GST_BUFFER_POOL_CLASS(gst_vaapi_video_buffer_pool_parent_class)-> + reset_buffer(pool, buffer); +} + +static void +gst_vaapi_video_buffer_pool_class_init(GstVaapiVideoBufferPoolClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstBufferPoolClass * const pool_class = GST_BUFFER_POOL_CLASS(klass); + + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapivideopool, + "vaapivideopool", 0, "VA-API video pool"); + + g_type_class_add_private(klass, sizeof(GstVaapiVideoBufferPoolPrivate)); + + object_class->finalize = gst_vaapi_video_buffer_pool_finalize; + object_class->set_property = gst_vaapi_video_buffer_pool_set_property; + object_class->get_property = gst_vaapi_video_buffer_pool_get_property; + pool_class->get_options = gst_vaapi_video_buffer_pool_get_options; + pool_class->set_config = gst_vaapi_video_buffer_pool_set_config; + pool_class->alloc_buffer = gst_vaapi_video_buffer_pool_alloc_buffer; + pool_class->reset_buffer = gst_vaapi_video_buffer_pool_reset_buffer; + + /** + * GstVaapiVideoBufferPool:display: + * + * The #GstVaapiDisplay this object is bound to. + */ + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_object("display", + "Display", + "The GstVaapiDisplay to use for this video pool", + GST_VAAPI_TYPE_DISPLAY, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_video_buffer_pool_init(GstVaapiVideoBufferPool *pool) +{ + GstVaapiVideoBufferPoolPrivate * const priv = + GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(pool); + + pool->priv = priv; +} + +GstBufferPool * +gst_vaapi_video_buffer_pool_new(GstVaapiDisplay *display) +{ + return g_object_new(GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, + "display", display, NULL); +} diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h new file mode 100644 index 0000000000..5b391e78f2 --- /dev/null +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -0,0 +1,91 @@ +/* + * gstvaapivideobufferpool.h - Gstreamer/VA video buffer pool + * + * Copyright (C) 2013 Intel Corporation + * + * 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_VIDEO_BUFFER_POOL_H +#define GST_VAAPI_VIDEO_BUFFER_POOL_H + +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_VIDEO_BUFFER_POOL \ + (gst_vaapi_video_buffer_pool_get_type()) + +#define GST_VAAPI_VIDEO_BUFFER_POOL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, \ + GstVaapiVideoBufferPool)) + +#define GST_VAAPI_VIDEO_BUFFER_POOL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, \ + GstVaapiVideoBufferPoolClass)) + +#define GST_VAAPI_IS_VIDEO_BUFFER_POOL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_BUFFER_POOL)) + +#define GST_VAAPI_IS_VIDEO_BUFFER_POOL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_BUFFER_POOL)) + +typedef struct _GstVaapiVideoBufferPool GstVaapiVideoBufferPool; +typedef struct _GstVaapiVideoBufferPoolClass GstVaapiVideoBufferPoolClass; +typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; + +/** + * GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META: + * + * An option that can be activated on bufferpool to request vaapi + * video metadata on buffers from the pool. + */ +#define GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META "GstBufferPoolOptionVaapiVideoMeta" + +/** + * GstVaapiVideoBufferPool: + * + * A VA video buffer pool object. + */ +struct _GstVaapiVideoBufferPool { + GstBufferPool parent_instance; + + /*< private >*/ + GstVaapiVideoBufferPoolPrivate *priv; +}; + +/** + * GstVaapiVideoBufferPoolClass: + * + * A VA video buffer pool class. + */ +struct _GstVaapiVideoBufferPoolClass { + GstBufferPoolClass parent_class; +}; + +GType +gst_vaapi_video_buffer_pool_get_type(void) G_GNUC_CONST; + +G_GNUC_INTERNAL +GstBufferPool * +gst_vaapi_video_buffer_pool_new(GstVaapiDisplay *display) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_BUFFER_POOL_H */ diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c new file mode 100644 index 0000000000..d016c12711 --- /dev/null +++ b/gst/vaapi/gstvaapivideomemory.c @@ -0,0 +1,177 @@ +/* + * gstvaapivideomemory.c - Gstreamer/VA video memory + * + * Copyright (C) 2013 Intel Corporation + * + * 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 "gst/vaapi/sysdeps.h" +#include "gstvaapivideomemory.h" + +GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideomemory); +#define GST_CAT_DEFAULT gst_debug_vaapivideomemory + +/* ------------------------------------------------------------------------ */ +/* --- GstVaapiVideoMemory --- */ +/* ------------------------------------------------------------------------ */ + +GstMemory * +gst_vaapi_video_memory_new(GstAllocator *base_allocator, + GstVaapiVideoMeta *meta) +{ + GstVaapiVideoAllocator * const allocator = + GST_VAAPI_VIDEO_ALLOCATOR_CAST(base_allocator); + const GstVideoInfo *vip; + GstVaapiVideoMemory *mem; + + mem = g_slice_new(GstVaapiVideoMemory); + if (!mem) + return NULL; + + vip = &allocator->video_info; + gst_memory_init(&mem->parent_instance, 0, base_allocator, NULL, + GST_VIDEO_INFO_SIZE(vip), 0, 0, GST_VIDEO_INFO_SIZE(vip)); + + mem->meta = gst_vaapi_video_meta_ref(meta); + return GST_MEMORY_CAST(mem); +} + +static void +gst_vaapi_video_memory_free(GstVaapiVideoMemory *mem) +{ + gst_vaapi_video_meta_unref(mem->meta); + g_slice_free(GstVaapiVideoMemory, mem); +} + +static gpointer +gst_vaapi_video_memory_map(GstVaapiVideoMemory *mem, gsize maxsize, guint flags) +{ + GST_FIXME("unimplemented GstVaapiVideoAllocator::mem_map() hook"); + return NULL; +} + +static void +gst_vaapi_video_memory_unmap(GstVaapiVideoMemory *mem) +{ + GST_FIXME("unimplemented GstVaapiVideoAllocator::mem_unmap() hook"); +} + +static GstVaapiVideoMemory * +gst_vaapi_video_memory_copy(GstVaapiVideoMemory *mem, + gssize offset, gssize size) +{ + GST_FIXME("unimplemented GstVaapiVideoAllocator::mem_copy() hook"); + return NULL; +} + +static GstVaapiVideoMemory * +gst_vaapi_video_memory_share(GstVaapiVideoMemory *mem, + gssize offset, gssize size) +{ + GST_FIXME("unimplemented GstVaapiVideoAllocator::mem_share() hook"); + return NULL; +} + +static gboolean +gst_vaapi_video_memory_is_span(GstVaapiVideoMemory *mem1, + GstVaapiVideoMemory *mem2, gsize *offset_ptr) +{ + GST_FIXME("unimplemented GstVaapiVideoAllocator::mem_is_span() hook"); + return FALSE; +} + +/* ------------------------------------------------------------------------ */ +/* --- GstVaapiVideoAllocator --- */ +/* ------------------------------------------------------------------------ */ + +#define GST_VAAPI_VIDEO_ALLOCATOR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_VIDEO_ALLOCATOR, \ + GstVaapiVideoAllocatorClass)) + +#define GST_VAAPI_IS_VIDEO_ALLOCATOR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_ALLOCATOR)) + +G_DEFINE_TYPE(GstVaapiVideoAllocator, + gst_vaapi_video_allocator, + GST_TYPE_ALLOCATOR) + +static GstMemory * +gst_vaapi_video_allocator_alloc(GstAllocator *allocator, gsize size, + GstAllocationParams *params) +{ + g_warning("use gst_vaapi_video_memory_new() to allocate from " + "GstVaapiVideoMemory allocator"); + + return NULL; +} + +static void +gst_vaapi_video_allocator_free(GstAllocator *allocator, GstMemory *mem) +{ + gst_vaapi_video_memory_free(GST_VAAPI_VIDEO_MEMORY_CAST(mem)); +} + +static void +gst_vaapi_video_allocator_class_init(GstVaapiVideoAllocatorClass *klass) +{ + GstAllocatorClass * const allocator_class = GST_ALLOCATOR_CLASS(klass); + + GST_DEBUG_CATEGORY_INIT(gst_debug_vaapivideomemory, + "vaapivideomemory", 0, "VA-API video memory allocator"); + + allocator_class->alloc = gst_vaapi_video_allocator_alloc; + allocator_class->free = gst_vaapi_video_allocator_free; +} + +static void +gst_vaapi_video_allocator_init(GstVaapiVideoAllocator *allocator) +{ + GstAllocator * const base_allocator = GST_ALLOCATOR_CAST(allocator); + + base_allocator->mem_type = GST_VAAPI_VIDEO_MEMORY_NAME; + base_allocator->mem_map = (GstMemoryMapFunction) + gst_vaapi_video_memory_map; + base_allocator->mem_unmap = (GstMemoryUnmapFunction) + gst_vaapi_video_memory_unmap; + base_allocator->mem_copy = (GstMemoryCopyFunction) + gst_vaapi_video_memory_copy; + base_allocator->mem_share = (GstMemoryShareFunction) + gst_vaapi_video_memory_share; + base_allocator->mem_is_span = (GstMemoryIsSpanFunction) + gst_vaapi_video_memory_is_span; +} + +GstAllocator * +gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) +{ + GstVaapiVideoAllocator *allocator; + GstVideoInfo *vip; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + allocator = g_object_new(GST_VAAPI_TYPE_VIDEO_ALLOCATOR, NULL); + if (!allocator) + return NULL; + + vip = &allocator->video_info; + gst_video_info_init(vip); + gst_video_info_from_caps(vip, caps); + + return GST_ALLOCATOR_CAST(allocator); +} diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h new file mode 100644 index 0000000000..447dd93f47 --- /dev/null +++ b/gst/vaapi/gstvaapivideomemory.h @@ -0,0 +1,113 @@ +/* + * gstvaapivideomemory.h - Gstreamer/VA video memory + * + * Copyright (C) 2013 Intel Corporation + * + * 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_VIDEO_MEMORY_H +#define GST_VAAPI_VIDEO_MEMORY_H + +#include +#include +#include +#include "gstvaapivideometa.h" + +G_BEGIN_DECLS + +typedef struct _GstVaapiVideoMemory GstVaapiVideoMemory; +typedef struct _GstVaapiVideoAllocator GstVaapiVideoAllocator; +typedef struct _GstVaapiVideoAllocatorClass GstVaapiVideoAllocatorClass; + +/* ------------------------------------------------------------------------ */ +/* --- GstVaapiVideoMemory --- */ +/* ------------------------------------------------------------------------ */ + +#define GST_VAAPI_VIDEO_MEMORY_CAST(mem) \ + ((GstVaapiVideoMemory *)(mem)) + +#define GST_VAAPI_VIDEO_MEMORY_NAME "GstVaapiVideoMemory" + +/** + * GstVaapiVideoMemory: + * + * A VA video memory object holder, including VA surfaces, images and + * proxies. + */ +struct _GstVaapiVideoMemory { + GstMemory parent_instance; + + /*< private >*/ + GstVaapiVideoMeta *meta; +}; + +G_GNUC_INTERNAL +GstMemory * +gst_vaapi_video_memory_new(GstAllocator *allocator, GstVaapiVideoMeta *meta); + +/* ------------------------------------------------------------------------ */ +/* --- GstVaapiVideoAllocator --- */ +/* ------------------------------------------------------------------------ */ + +#define GST_VAAPI_VIDEO_ALLOCATOR_CAST(allocator) \ + ((GstVaapiVideoAllocator *)(allocator)) + +#define GST_VAAPI_TYPE_VIDEO_ALLOCATOR \ + (gst_vaapi_video_allocator_get_type()) + +#define GST_VAAPI_VIDEO_ALLOCATOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_VIDEO_ALLOCATOR, \ + GstVaapiVideoAllocator)) + +#define GST_VAAPI_IS_VIDEO_ALLOCATOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_ALLOCATOR)) + +#define GST_VAAPI_VIDEO_ALLOCATOR_NAME "GstVaapiVideoAllocator" + +/** + * GstVaapiVideoAllocator: + * + * A VA video memory allocator object. + */ +struct _GstVaapiVideoAllocator { + GstAllocator parent_instance; + + /*< private >*/ + GstVideoInfo video_info; +}; + +/** + * GstVaapiVideoAllocatorClass: + * + * A VA video memory allocator class. + */ +struct _GstVaapiVideoAllocatorClass { + GstAllocatorClass parent_class; +}; + +G_GNUC_INTERNAL +GType +gst_vaapi_video_allocator_get_type(void) G_GNUC_CONST; + +G_GNUC_INTERNAL +GstAllocator * +gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_MEMORY_H */ From 551ac4c5b34dccf1ba774a88f189d29caff2415e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 8 Nov 2012 16:41:22 +0200 Subject: [PATCH 1134/3781] plugins: use new video buffer pools. Use new GstVaapiVideoBufferPool to maintain video buffers. Implement GstBaseSink::propose_allocation() to expose that pool to upstream elements; and also implement GstVideoDecoder::decide_allocation() to actually use that pool (from downstream), if any, or create one. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 104 +++++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapisink.c | 106 ++++++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapisink.h | 2 + 3 files changed, 209 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 77c437ba82..dd3327b9fb 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -35,6 +35,8 @@ #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" #include "gstvaapivideobuffer.h" +#include "gstvaapivideobufferpool.h" +#include "gstvaapivideomemory.h" #include #include @@ -154,7 +156,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, { GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); GstVideoCodecState *state; - GstVideoInfo *vi; + GstVideoInfo *vi, vis; state = gst_video_decoder_set_output_state(vdec, GST_VIDEO_INFO_FORMAT(&ref_state->info), @@ -163,6 +165,12 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, return FALSE; vi = &state->info; + if (GST_VIDEO_INFO_FORMAT(vi) == GST_VIDEO_FORMAT_ENCODED) { + gst_video_info_init(&vis); + gst_video_info_set_format(&vis, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); + vi->size = vis.size; + } gst_video_codec_state_unref(state); /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not @@ -263,6 +271,7 @@ gst_vaapidecode_push_decoded_frames(GstVideoDecoder *vdec) GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstVaapiSurfaceProxy *proxy; GstVaapiDecoderStatus status; + GstVaapiVideoMeta *meta; GstVideoCodecFrame *out_frame; GstFlowReturn ret; @@ -278,10 +287,21 @@ gst_vaapidecode_push_decoded_frames(GstVideoDecoder *vdec) gst_vaapi_surface_proxy_set_user_data(proxy, decode, (GDestroyNotify)gst_vaapidecode_release); +#if GST_CHECK_VERSION(1,0,0) + ret = gst_video_decoder_allocate_output_frame(vdec, out_frame); + if (ret != GST_FLOW_OK) + goto error_create_buffer; + + meta = gst_buffer_get_vaapi_video_meta(out_frame->output_buffer); + if (!meta) + goto error_get_meta; + gst_vaapi_video_meta_set_surface_proxy(meta, proxy); +#else out_frame->output_buffer = gst_vaapi_video_buffer_new_with_surface_proxy(proxy); if (!out_frame->output_buffer) goto error_create_buffer; +#endif } ret = gst_video_decoder_finish_frame(vdec, out_frame); @@ -307,6 +327,13 @@ error_create_buffer: gst_video_codec_frame_unref(out_frame); return GST_FLOW_EOS; } +error_get_meta: + { + GST_ERROR("failed to get vaapi video meta attached to video buffer"); + gst_video_decoder_drop_frame(vdec, out_frame); + gst_video_codec_frame_unref(out_frame); + return GST_FLOW_EOS; + } error_commit_buffer: { GST_DEBUG("video sink rejected the video buffer (error %d)", ret); @@ -345,6 +372,78 @@ error_flush: } } +static gboolean +gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + GstCaps *caps = NULL; + GstBufferPool *pool; + GstStructure *config; + GstVideoInfo vi; + guint size, min, max; + gboolean need_pool, update_pool; + + gst_query_parse_allocation(query, &caps, &need_pool); + + if (!caps) + goto error_no_caps; + + gst_video_info_init(&vi); + gst_video_info_from_caps(&vi, caps); + if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) + gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); + + g_return_val_if_fail(decode->display != NULL, FALSE); + + if (gst_query_get_n_allocation_pools(query) > 0) { + gst_query_parse_nth_allocation_pool(query, 0, &pool, &size, &min, &max); + size = MAX(size, vi.size); + update_pool = TRUE; + } + else { + pool = NULL; + size = vi.size; + min = max = 0; + update_pool = FALSE; + } + + if (!pool || !gst_buffer_pool_has_option(pool, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) { + GST_INFO("no pool or doesn't support GstVaapiVideoMeta, " + "making new pool"); + pool = gst_vaapi_video_buffer_pool_new(decode->display); + if (!pool) + goto error_create_pool; + + config = gst_buffer_pool_get_config(pool); + gst_buffer_pool_config_set_params(config, caps, size, min, max); + gst_buffer_pool_config_add_option(config, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); + gst_buffer_pool_set_config(pool, config); + } + + if (update_pool) + gst_query_set_nth_allocation_pool(query, 0, pool, size, min, max); + else + gst_query_add_allocation_pool(query, pool, size, min, max); + if (pool) + g_object_unref(pool); + return TRUE; + + /* ERRORS */ +error_no_caps: + { + GST_ERROR("no caps specified"); + return FALSE; + } +error_create_pool: + { + GST_ERROR("failed to create buffer pool"); + return FALSE; + } +} + static inline gboolean gst_vaapidecode_ensure_display(GstVaapiDecode *decode) { @@ -566,6 +665,9 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) vdec_class->handle_frame = GST_DEBUG_FUNCPTR(gst_vaapidecode_handle_frame); vdec_class->finish = GST_DEBUG_FUNCPTR(gst_vaapidecode_finish); + vdec_class->decide_allocation = + GST_DEBUG_FUNCPTR(gst_vaapidecode_decide_allocation); + gst_element_class_set_static_metadata(element_class, "VA-API decoder", "Codec/Decoder/Video", diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 28c61f1279..7393aab3ef 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -70,6 +70,8 @@ #include "gstvaapisink.h" #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" +#include "gstvaapivideobufferpool.h" +#include "gstvaapivideomemory.h" #define GST_PLUGIN_NAME "vaapisink" #define GST_PLUGIN_DESC "A VA-API based videosink" @@ -588,6 +590,66 @@ end: return success; } +static gboolean +gst_vaapisink_ensure_video_buffer_pool(GstVaapiSink *sink, GstCaps *caps) +{ + GstBufferPool *pool; + GstCaps *pool_caps; + GstStructure *config; + GstVideoInfo vi; + gboolean need_pool; + + if (!gst_vaapisink_ensure_display(sink)) + return FALSE; + + if (sink->video_buffer_pool) { + config = gst_buffer_pool_get_config(sink->video_buffer_pool); + gst_buffer_pool_config_get_params(config, &pool_caps, NULL, NULL, NULL); + need_pool = !gst_caps_is_equal(caps, pool_caps); + gst_structure_free(config); + if (!need_pool) + return TRUE; + g_clear_object(&sink->video_buffer_pool); + sink->video_buffer_size = 0; + } + + pool = gst_vaapi_video_buffer_pool_new(sink->display); + if (!pool) + goto error_create_pool; + + gst_video_info_init(&vi); + gst_video_info_from_caps(&vi, caps); + if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) { + GST_DEBUG("assume video buffer pool format is NV12"); + gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); + } + sink->video_buffer_size = vi.size; + + config = gst_buffer_pool_get_config(pool); + gst_buffer_pool_config_set_params(config, caps, sink->video_buffer_size, + 0, 0); + gst_buffer_pool_config_add_option(config, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); + if (!gst_buffer_pool_set_config(pool, config)) + goto error_pool_config; + sink->video_buffer_pool = pool; + return TRUE; + + /* ERRORS */ +error_create_pool: + { + GST_ERROR("failed to create buffer pool"); + return FALSE; + } +error_pool_config: + { + GST_ERROR("failed to reset buffer pool config"); + g_object_unref(pool); + return FALSE; + } +} + static gboolean gst_vaapisink_start(GstBaseSink *base_sink) { @@ -608,6 +670,7 @@ gst_vaapisink_stop(GstBaseSink *base_sink) GstVaapiSink * const sink = GST_VAAPISINK(base_sink); gst_buffer_replace(&sink->video_buffer, NULL); + g_clear_object(&sink->video_buffer_pool); g_clear_object(&sink->window); g_clear_object(&sink->display); g_clear_object(&sink->uploader); @@ -645,6 +708,9 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return TRUE; #endif + if (!gst_vaapisink_ensure_video_buffer_pool(sink, caps)) + return FALSE; + if (!gst_video_info_from_caps(&vi, caps)) return FALSE; sink->use_video_raw = GST_VIDEO_INFO_IS_YUV(&vi); @@ -954,7 +1020,41 @@ error: return GST_FLOW_EOS; } -#if !GST_CHECK_VERSION(1,0,0) +#if GST_CHECK_VERSION(1,0,0) +static gboolean +gst_vaapisink_propose_allocation(GstBaseSink *base_sink, GstQuery *query) +{ + GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + GstCaps *caps = NULL; + gboolean need_pool; + + gst_query_parse_allocation(query, &caps, &need_pool); + + if (need_pool) { + if (!caps) + goto error_no_caps; + if (!gst_vaapisink_ensure_video_buffer_pool(sink, caps)) + return FALSE; + gst_query_add_allocation_pool(query, sink->video_buffer_pool, + sink->video_buffer_size, 0, 0); + } + + gst_query_add_allocation_meta(query, + GST_VAAPI_VIDEO_META_API_TYPE, NULL); + gst_query_add_allocation_meta(query, + GST_VIDEO_META_API_TYPE, NULL); + gst_query_add_allocation_meta(query, + GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL); + return TRUE; + + /* ERRORS */ +error_no_caps: + { + GST_ERROR("no caps specified"); + return FALSE; + } +} +#else static GstFlowReturn gst_vaapisink_buffer_alloc( GstBaseSink *base_sink, @@ -1104,7 +1204,9 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->preroll = gst_vaapisink_show_frame; basesink_class->render = gst_vaapisink_show_frame; basesink_class->query = gst_vaapisink_query; -#if !GST_CHECK_VERSION(1,0,0) +#if GST_CHECK_VERSION(1,0,0) + basesink_class->propose_allocation = gst_vaapisink_propose_allocation; +#else basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; #endif diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 8db8ac2387..c68efd634b 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -76,6 +76,8 @@ struct _GstVaapiSink { guint window_width; guint window_height; GstVaapiTexture *texture; + GstBufferPool *video_buffer_pool; + guint video_buffer_size; GstBuffer *video_buffer; guint video_width; guint video_height; From 1b500dee54795254e1e3616f90329c0e5da1f95a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 14:40:57 +0100 Subject: [PATCH 1135/3781] Allow build against either GStreamer API (0.10 or 1.0). Introduce a new configure option --with-gstreamer-api that determines the desired GStreamer API to use. By default, GStreamer 1.0 is selected. Also integrate more compatibility glue into gstcompat.h and plugins. --- configure.ac | 18 ++- gst-libs/gst/vaapi/gstcompat.h | 158 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiimageformat.c | 16 ++- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- gst/vaapi/Makefile.am | 16 +++ gst/vaapi/gstvaapi.c | 2 +- gst/vaapi/gstvaapidecode.c | 28 ++-- gst/vaapi/gstvaapisink.c | 20 ++- gst/vaapi/gstvaapisink.h | 2 + gst/vaapi/gstvaapiuploader.c | 2 +- tests/codec.c | 2 +- 11 files changed, 249 insertions(+), 17 deletions(-) diff --git a/configure.ac b/configure.ac index ec7c5d13e8..649497e8d5 100644 --- a/configure.ac +++ b/configure.ac @@ -46,7 +46,7 @@ m4_define([libva_wld_package_version], [1.1.0]) # XXX: introspection annotations require gtk-doc >= 1.12 m4_define([gtkdoc_version], [1.9]) -AC_PREREQ([2.58]) +AC_PREREQ([2.66]) AC_INIT([gst_vaapi], [gst_vaapi_version], [gwenole.beauchesne@intel.com], [gstreamer-vaapi]) @@ -110,6 +110,12 @@ AC_ARG_ENABLE(wayland, [enable Wayland output @<:@default=yes@:>@]), [], [enable_wayland="yes"]) +AC_ARG_WITH([gstreamer-api], + AC_HELP_STRING([--with-gstreamer-api=VERSION], + [build against the specified GStreamer API version + @<:@default=gst_api_version@:>@]), + [GST_API_VERSION="$with_gstreamer_api"], [GST_API_VERSION=gst_api_version]) + dnl Check for basic libraries AC_CHECK_LIB(m, tan) @@ -131,7 +137,6 @@ dnl -- GStreamer -- dnl --------------------------------------------------------------------------- dnl Versions for GStreamer and plugins-base -GST_API_VERSION=gst_api_version case $GST_API_VERSION in 0.10) GST_VERSION_REQUIRED=gst0_version @@ -152,6 +157,15 @@ AC_SUBST(GST_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED) +USE_GST_API_0_10="no" +USE_GST_API_1_0p="no" +AS_VERSION_COMPARE([$GST_API_VERSION], [0.10], + [], [USE_GST_API_0_10="yes"], []) +AS_VERSION_COMPARE([$GST_API_VERSION], [1.0], + [], [USE_GST_API_1_0p="yes"], [USE_GST_API_1_0p="yes"]) +AM_CONDITIONAL([USE_GST_API_0_10], [test "$USE_GST_API_0_10" = "yes"]) +AM_CONDITIONAL([USE_GST_API_1_0p], [test "$USE_GST_API_1_0p" = "yes"]) + dnl GStreamer Core PKG_CHECK_MODULES([GST], [gstreamer-$GST_API_VERSION >= $GST_VERSION_REQUIRED]) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index 9d4d82a1a2..aedd93b219 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -58,12 +58,153 @@ gst_compat_structure_get_fourcc(const GstStructure *structure, typedef const guint8 *(*GstCompatTypeFindPeekFunction)(gpointer, gint64, guint); typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, GstCaps *); +/* GstQuery */ +#define GST_PAD_QUERY_FUNCTION_ARGS \ + GstPad *pad, GstObject *parent, GstQuery *query +#define GST_PAD_QUERY_FUNCTION_CALL(func, pad, parent, query) \ + (func)(pad, parent, query) + +/* GstPlugin */ +#define GST_PLUGIN_DESC_NAME(NAME) NAME + +/* Misc helpers */ +#define GST_MAKE_FORMAT_STRING(FORMAT) \ + "format=(string)" G_STRINGIFY(FORMAT) + /* ------------------------------------------------------------------------ */ /* --- GStreamer = 0.10 --- */ /* ------------------------------------------------------------------------ */ #else +/* GstMemory */ +typedef enum { + GST_MEMORY_FLAG_READONLY = GST_MINI_OBJECT_FLAG_READONLY +} GstMemoryFlags; + +typedef enum { + GST_MAP_READ = 1 << 0, + GST_MAP_WRITE = 1 << 1 +} GstMapFlags; + +typedef struct { + GstMapFlags flags; + guint8 *data; + gsize size; +} GstMapInfo; + +/* GstBuffer */ +#undef gst_buffer_new_wrapped +#define gst_buffer_new_wrapped(data, size) \ + gst_compat_buffer_new_wrapped_full(0, data, size, 0, size, data, g_free) +#undef gst_buffer_new_wrapped_full +#define gst_buffer_new_wrapped_full(flags, data, maxsize, ofs, size, ud, udd) \ + gst_compat_buffer_new_wrapped_full(flags, data, maxsize, ofs, size, ud, udd) +#undef gst_buffer_get_size +#define gst_buffer_get_size(buffer) gst_compat_buffer_get_size(buffer) +#undef gst_buffer_map +#define gst_buffer_map(buffer, mip, f) gst_compat_buffer_map(buffer, mip, f) +#undef gst_buffer_unmap +#define gst_buffer_unmap(buffer, mip) gst_compat_buffer_unmap(buffer, mip) +#undef gst_buffer_extract +#define gst_buffer_extract(buffer, offset, dest, size) \ + gst_compat_buffer_extract(buffer, offset, dest, size) + +static inline GstBuffer * +gst_compat_buffer_new_wrapped_full(GstMemoryFlags flags, gpointer data, + gsize maxsize, gsize offset, gsize size, gpointer user_data, + GDestroyNotify notify) +{ + GstBuffer *buffer; + + /* XXX: unsupported */ + g_return_val_if_fail(user_data == NULL, NULL); + g_return_val_if_fail(notify == NULL, NULL); + g_return_val_if_fail(maxsize >= size, NULL); + + buffer = gst_buffer_new(); + if (!buffer) + return NULL; + + GST_BUFFER_DATA(buffer) = data + offset; + GST_BUFFER_SIZE(buffer) = size; + return buffer; +} + +static inline gsize +gst_compat_buffer_get_size(GstBuffer *buffer) +{ + return GST_BUFFER_SIZE(buffer); +} + +static inline gboolean +gst_compat_buffer_map(GstBuffer *buffer, GstMapInfo *mip, GstMapFlags flags) +{ + mip->flags = flags; + mip->data = GST_BUFFER_DATA(buffer); + mip->size = GST_BUFFER_SIZE(buffer); + return TRUE; +} + +static inline void +gst_compat_buffer_unmap(GstBuffer *buffer, GstMapInfo *mip) +{ +} + +static inline gsize +gst_compat_buffer_extract(GstBuffer *buffer, gsize offset, gpointer dest, + gsize size) +{ + gsize esize; + + if (!buffer || !dest || offset >= GST_BUFFER_SIZE(buffer)) + return 0; + + esize = MIN(size, GST_BUFFER_SIZE(buffer) - offset); + memcpy(dest, GST_BUFFER_DATA(buffer) + offset, esize); + return esize; +} + +/* GstAdapter */ +#include + +#undef gst_adapter_map +#define gst_adapter_map(adapter, size) gst_compat_adapter_map(adapter, size) +#undef gst_adapter_unmap +#define gst_adapter_unmap(adapter) gst_compat_adapter_unmap(adapter) + +static inline gconstpointer +gst_compat_adapter_map(GstAdapter *adapter, gsize size) +{ + return gst_adapter_peek(adapter, size); +} + +static inline void +gst_compat_adapter_unmap(GstAdapter *adapter) +{ +} + +/* GstCaps */ +#undef gst_caps_merge +#define gst_caps_merge(caps1, caps2) gst_compat_caps_merge(caps1, caps2) +#undef gst_caps_merge_structure +#define gst_caps_merge_structure(caps, structure) \ + gst_compat_caps_merge_structure(caps, structure) + +static inline GstCaps * +gst_compat_caps_merge(GstCaps *caps1, GstCaps *caps2) +{ + (gst_caps_merge)(caps1, caps2); + return caps1; +} + +static inline GstCaps * +gst_compat_caps_merge_structure(GstCaps *caps, GstStructure *structure) +{ + (gst_caps_merge_structure)(caps, structure); + return caps; +} + /* GstVideoOverlayComposition */ #include @@ -90,6 +231,10 @@ gst_compat_video_overlay_rectangle_get_pixels_unscaled_raw( &width, &height, &stride, flags); } +/* GstPad */ +#undef GST_FLOW_EOS +#define GST_FLOW_EOS GST_FLOW_UNEXPECTED + /* GstElement */ #undef gst_element_class_set_static_metadata #define gst_element_class_set_static_metadata(klass, name, path, desc, author) \ @@ -111,6 +256,19 @@ gst_compat_element_class_set_static_metadata(GstElementClass *klass, typedef guint8 *(*GstCompatTypeFindPeekFunction)(gpointer, gint64, guint); typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, const GstCaps *); +/* GstQuery */ +#define GST_PAD_QUERY_FUNCTION_ARGS \ + GstPad *pad, GstQuery *query +#define GST_PAD_QUERY_FUNCTION_CALL(func, pad, parent, query) \ + (func)(pad, query) + +/* GstPlugin */ +#define GST_PLUGIN_DESC_NAME(NAME) G_STRINGIFY(NAME) + +/* Misc helpers */ +#define GST_MAKE_FORMAT_STRING(FORMAT) \ + "format=(fourcc)" G_STRINGIFY(FORMAT) + #endif #endif /* GST_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c index 1bbd6f3b10..54c94aa463 100644 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ b/gst-libs/gst/vaapi/gstvaapiimageformat.c @@ -45,15 +45,27 @@ struct _GstVaapiImageFormatMap { VAImageFormat va_format; }; +#if GST_CHECK_VERSION(1,0,0) +# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \ + GST_VIDEO_CAPS_MAKE(#FORMAT) +# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \ + GST_VIDEO_CAPS_MAKE(#FORMAT) +#else +# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \ + GST_VIDEO_CAPS_YUV(#FORMAT) +# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \ + GST_VIDEO_CAPS_##FORMAT +#endif + #define DEF(TYPE, FORMAT, CAPS_STR) \ GST_VAAPI_IMAGE_FORMAT_TYPE_##TYPE, \ GST_VAAPI_IMAGE_##FORMAT, \ CAPS_STR #define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP) \ - { DEF(YCBCR, FORMAT, GST_VIDEO_CAPS_MAKE(#FORMAT)), \ + { DEF(YCBCR, FORMAT, GST_VIDEO_CAPS_MAKE_YUV(FORMAT)), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } #define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \ - { DEF(RGB, FORMAT, GST_VIDEO_CAPS_MAKE(#FORMAT)), \ + { DEF(RGB, FORMAT, GST_VIDEO_CAPS_MAKE_RGB(FORMAT)), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } /* Image formats, listed in HW order preference */ diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 62089197db..1c5c51544a 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -91,7 +91,7 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-wmv, wmvversion=3", "main" }, { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, - "video/x-wmv, wmvversion=3, format=(string)WVC1", "advanced" + "video/x-wmv, wmvversion=3, " GST_MAKE_FORMAT_STRING(WVC1), "advanced" }, #if VA_CHECK_VERSION(0,32,0) { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline, diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index dd730bb12e..3f104e4ae7 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -53,6 +53,7 @@ libgstvaapi_source_c += gstvaapivideoconverter_glx.c libgstvaapi_source_h += gstvaapivideoconverter_glx.h endif +if USE_GST_API_1_0p libgstvaapi_source_c += \ gstvaapivideobufferpool.c \ gstvaapivideomemory.c \ @@ -62,6 +63,21 @@ libgstvaapi_source_h += \ gstvaapivideobufferpool.h \ gstvaapivideomemory.h \ $(NULL) +endif + +if USE_GST_API_0_10 +libgstvaapi_source_c += \ + gstvaapidownload.c \ + gstvaapipostproc.c \ + gstvaapiupload.c \ + $(NULL) + +libgstvaapi_source_h += \ + gstvaapidownload.h \ + gstvaapipostproc.h \ + gstvaapiupload.h \ + $(NULL) +endif libgstvaapi_la_SOURCES = $(libgstvaapi_source_c) noinst_HEADERS = $(libgstvaapi_source_h) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 909be71dc0..407989d45f 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -56,7 +56,7 @@ plugin_init (GstPlugin *plugin) GST_PLUGIN_DEFINE( GST_VERSION_MAJOR, GST_VERSION_MINOR, - vaapi, + GST_PLUGIN_DESC_NAME(vaapi), "VA-API based elements", plugin_init, PACKAGE_VERSION, diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index dd3327b9fb..fe99ee5808 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -35,8 +35,10 @@ #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" #include "gstvaapivideobuffer.h" +#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" #include "gstvaapivideomemory.h" +#endif #include #include @@ -327,6 +329,7 @@ error_create_buffer: gst_video_codec_frame_unref(out_frame); return GST_FLOW_EOS; } +#if GST_CHECK_VERSION(1,0,0) error_get_meta: { GST_ERROR("failed to get vaapi video meta attached to video buffer"); @@ -334,6 +337,7 @@ error_get_meta: gst_video_codec_frame_unref(out_frame); return GST_FLOW_EOS; } +#endif error_commit_buffer: { GST_DEBUG("video sink rejected the video buffer (error %d)", ret); @@ -372,6 +376,7 @@ error_flush: } } +#if GST_CHECK_VERSION(1,0,0) static gboolean gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) { @@ -443,6 +448,7 @@ error_create_pool: return FALSE; } } +#endif static inline gboolean gst_vaapidecode_ensure_display(GstVaapiDecode *decode) @@ -665,8 +671,10 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) vdec_class->handle_frame = GST_DEBUG_FUNCPTR(gst_vaapidecode_handle_frame); vdec_class->finish = GST_DEBUG_FUNCPTR(gst_vaapidecode_finish); +#if GST_CHECK_VERSION(1,0,0) vdec_class->decide_allocation = GST_DEBUG_FUNCPTR(gst_vaapidecode_decide_allocation); +#endif gst_element_class_set_static_metadata(element_class, "VA-API decoder", @@ -757,20 +765,24 @@ gst_vaapidecode_get_caps(GstPad *pad) } static gboolean -gst_vaapidecode_query (GstPad *pad, GstObject *parent, GstQuery *query) { - GstVaapiDecode *decode = GST_VAAPIDECODE (gst_pad_get_parent_element (pad)); +gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) +{ + GstVaapiDecode * const decode = + GST_VAAPIDECODE(gst_pad_get_parent_element(pad)); gboolean res; - GST_DEBUG ("sharing display %p", decode->display); + GST_DEBUG("sharing display %p", decode->display); - if (gst_vaapi_reply_to_query (query, decode->display)) - res = TRUE; + if (gst_vaapi_reply_to_query(query, decode->display)) + res = TRUE; else if (GST_PAD_IS_SINK(pad)) - res = decode->sinkpad_query(decode->sinkpad, parent, query); + res = GST_PAD_QUERY_FUNCTION_CALL(decode->sinkpad_query, + decode->sinkpad, parent, query); else - res = decode->srcpad_query(decode->srcpad, parent, query); + res = GST_PAD_QUERY_FUNCTION_CALL(decode->srcpad_query, + decode->srcpad, parent, query); - g_object_unref (decode); + g_object_unref(decode); return res; } diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 7393aab3ef..6c0cf90b81 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -70,8 +70,10 @@ #include "gstvaapisink.h" #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" +#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" #include "gstvaapivideomemory.h" +#endif #define GST_PLUGIN_NAME "vaapisink" #define GST_PLUGIN_DESC "A VA-API based videosink" @@ -593,6 +595,7 @@ end: static gboolean gst_vaapisink_ensure_video_buffer_pool(GstVaapiSink *sink, GstCaps *caps) { +#if GST_CHECK_VERSION(1,0,0) GstBufferPool *pool; GstCaps *pool_caps; GstStructure *config; @@ -648,6 +651,9 @@ error_pool_config: g_object_unref(pool); return FALSE; } +#else + return TRUE; +#endif } static gboolean @@ -670,7 +676,9 @@ gst_vaapisink_stop(GstBaseSink *base_sink) GstVaapiSink * const sink = GST_VAAPISINK(base_sink); gst_buffer_replace(&sink->video_buffer, NULL); +#if GST_CHECK_VERSION(1,0,0) g_clear_object(&sink->video_buffer_pool); +#endif g_clear_object(&sink->window); g_clear_object(&sink->display); g_clear_object(&sink->uploader); @@ -679,7 +687,7 @@ gst_vaapisink_stop(GstBaseSink *base_sink) } static GstCaps * -gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter) +gst_vaapisink_get_caps_impl(GstBaseSink *base_sink) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstCaps *out_caps, *yuv_caps; @@ -696,6 +704,16 @@ gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter) return out_caps; } +#if GST_CHECK_VERSION(1,0,0) +static inline GstCaps * +gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter) +{ + return gst_vaapisink_get_caps_impl(base_sink); +} +#else +#define gst_vaapisink_get_caps gst_vaapisink_get_caps_impl +#endif + static gboolean gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index c68efd634b..58abb46895 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -76,7 +76,9 @@ struct _GstVaapiSink { guint window_width; guint window_height; GstVaapiTexture *texture; +#if GST_CHECK_VERSION(1,0,0) GstBufferPool *video_buffer_pool; +#endif guint video_buffer_size; GstBuffer *video_buffer; guint video_width; diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index ac7afd745f..f2c341f37b 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -449,7 +449,7 @@ gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) goto error; } -#if 0 +#if !GST_CHECK_VERSION(1,0,0) GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0); GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image); diff --git a/tests/codec.c b/tests/codec.c index a1dd0812e6..ff9b1250b2 100644 --- a/tests/codec.c +++ b/tests/codec.c @@ -41,7 +41,7 @@ static const CodecMap g_codec_map[] = { { "wmv3", GST_VAAPI_CODEC_VC1, "video/x-wmv, wmvversion=3" }, { "vc1", GST_VAAPI_CODEC_VC1, - "video/x-wmv, wmvversion=3, format=(string)WVC1" }, + "video/x-wmv, wmvversion=3, " GST_MAKE_FORMAT_STRING(WVC1) }, { NULL, } }; From 788d337505da430eac6afe435b657d0260d8cc18 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Mar 2013 11:26:38 +0100 Subject: [PATCH 1136/3781] decoder: fix unpaired GstBuffer map/unmaps. This possibly fixes a few memory leaks along the way. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 1 + 6 files changed, 7 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 77fe11995a..3225b9f3e6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -972,5 +972,6 @@ gst_vaapi_decoder_decode_codec_data(GstVaapiDecoder *decoder) status = klass->decode_codec_data(decoder, buf, buf_size); else status = GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_buffer_unmap(codec_data, &map_info); return status; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 6b6908242b..aa61aeb411 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2716,6 +2716,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) slice = GST_VAAPI_SLICE_NEW(H264, decoder, (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size); + gst_buffer_unmap(buffer, &map_info); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index ba77436a58..bb50e220e8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -692,6 +692,7 @@ gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder, } 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; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 5c857e1f89..b32024850b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1211,6 +1211,7 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, (map_info.data + unit->offset), unit->size); + gst_buffer_unmap(buffer, &map_info); if (!slice) { GST_ERROR("failed to allocate slice"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -1499,6 +1500,7 @@ gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base_decoder, packet.offset = 4; status = parse_unit(decoder, unit, &packet); + gst_buffer_unmap(buffer, &map_info); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; return decode_unit(decoder, unit, &packet); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index d2a0b36541..b7b6e0bc8b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -1097,6 +1097,7 @@ gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base_decoder, } 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; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index e063cd268b..6eb701b6b1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1267,6 +1267,7 @@ gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base_decoder, } 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; From ead7ec2f43795a1ead0a9bb9e784bfa81baba7b9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 2 Apr 2013 16:12:16 +0200 Subject: [PATCH 1137/3781] vaapidecode: reply to CAPS queries. Handle GST_QUERY_CAPS, which is the GStreamer 1.0 mechanism to retrieve the set of allowed caps, i.e. it works similar to GstPad::get_caps(). This fixes fallback to SW decoding if no HW decoder is available. --- gst/vaapi/gstvaapidecode.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index fe99ee5808..9476cb30e4 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -775,9 +775,23 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) if (gst_vaapi_reply_to_query(query, decode->display)) res = TRUE; - else if (GST_PAD_IS_SINK(pad)) - res = GST_PAD_QUERY_FUNCTION_CALL(decode->sinkpad_query, - decode->sinkpad, parent, query); + else if (GST_PAD_IS_SINK(pad)) { + switch (GST_QUERY_TYPE(query)) { +#if GST_CHECK_VERSION(1,0,0) + case GST_QUERY_CAPS: { + GstCaps * const caps = gst_vaapidecode_get_caps(pad); + gst_query_set_caps_result(query, caps); + gst_caps_unref(caps); + res = TRUE; + break; + } +#endif + default: + res = GST_PAD_QUERY_FUNCTION_CALL(decode->sinkpad_query, + decode->sinkpad, parent, query); + break; + } + } else res = GST_PAD_QUERY_FUNCTION_CALL(decode->srcpad_query, decode->srcpad, parent, query); From 1ed3df201ec115f83065f0730ba84261d3061d08 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 3 Apr 2013 11:10:41 +0200 Subject: [PATCH 1138/3781] vaapidecode: submit all decoded frames before decoding a new one. Make sure to purge all pending frames that were already decoded prior to decoding a new one. This helps release VA surfaces as early as possible. --- gst/vaapi/gstvaapidecode.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9476cb30e4..c51ca63922 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -351,9 +351,17 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) { GstFlowReturn ret; + /* Purge all pending frames we might have already. This helps + release VA surfaces as early as possible for _decode_frame() */ + ret = gst_vaapidecode_push_decoded_frames(vdec); + if (ret != GST_FLOW_OK) + return ret; + ret = gst_vaapidecode_decode_frame(vdec, frame); if (ret != GST_FLOW_OK) return ret; + + /* Purge any pending frame thay may have been decoded already */ return gst_vaapidecode_push_decoded_frames(vdec); } From c698a015a3000a52bcd5e0d5e3a7ed63d9e34e3f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Apr 2013 16:02:06 +0200 Subject: [PATCH 1139/3781] plugins: implement uploads from raw YUV buffers for GStreamer 1.0. Implement GstVideoMeta::{,un}map() to support raw YUV buffer upload when the last component is unmapped. Downloads are not supported yet. The aim was to first support SW decoding + HW accelerated rendering (vaapisink). e.g. for Wayland. --- gst/vaapi/gstvaapivideobufferpool.c | 12 +- gst/vaapi/gstvaapivideomemory.c | 216 +++++++++++++++++++++++++++- gst/vaapi/gstvaapivideomemory.h | 17 +++ 3 files changed, 241 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 06e8d85549..b6002fb561 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -185,10 +185,16 @@ gst_vaapi_video_buffer_pool_alloc_buffer(GstBufferPool *pool, if (priv->has_video_meta) { GstVideoInfo * const vip = - &GST_VAAPI_VIDEO_ALLOCATOR_CAST(priv->allocator)->video_info; + &GST_VAAPI_VIDEO_ALLOCATOR_CAST(priv->allocator)->image_info; + GstVideoMeta *vmeta; - gst_buffer_add_video_meta(buffer, 0, GST_VIDEO_INFO_FORMAT(vip), - GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + vmeta = gst_buffer_add_video_meta_full(buffer, 0, + GST_VIDEO_INFO_FORMAT(vip), GST_VIDEO_INFO_WIDTH(vip), + GST_VIDEO_INFO_HEIGHT(vip), GST_VIDEO_INFO_N_PLANES(vip), + &GST_VIDEO_INFO_PLANE_OFFSET(vip, 0), + &GST_VIDEO_INFO_PLANE_STRIDE(vip, 0)); + vmeta->map = gst_video_meta_map_vaapi_memory; + vmeta->unmap = gst_video_meta_unmap_vaapi_memory; } *out_buffer_ptr = buffer; diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index d016c12711..a7d65caecc 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -25,10 +25,160 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideomemory); #define GST_CAT_DEFAULT gst_debug_vaapivideomemory +#ifndef GST_VIDEO_INFO_FORMAT_STRING +#define GST_VIDEO_INFO_FORMAT_STRING(vip) \ + gst_video_format_to_string(GST_VIDEO_INFO_FORMAT(vip)) +#endif + /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoMemory --- */ /* ------------------------------------------------------------------------ */ +static GstVaapiImage * +new_image(GstVaapiDisplay *display, const GstVideoInfo *vip) +{ + GstVaapiImageFormat format; + + format = gst_vaapi_image_format_from_video(GST_VIDEO_INFO_FORMAT(vip)); + if (!format) + return NULL; + + return gst_vaapi_image_new(display, format, + GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); +} + +static gboolean +ensure_image(GstVaapiVideoMemory *mem) +{ + if (!mem->image) { + GstVaapiDisplay * const display = + gst_vaapi_video_meta_get_display(mem->meta); + + mem->image = new_image(display, mem->image_info); + if (!mem->image) + return FALSE; + } + gst_vaapi_video_meta_set_image(mem->meta, mem->image); + return TRUE; +} + +static GstVaapiSurface * +new_surface(GstVaapiDisplay *display, const GstVideoInfo *vip) +{ + if (GST_VIDEO_INFO_FORMAT(vip) != GST_VIDEO_FORMAT_NV12) + return NULL; + + return gst_vaapi_surface_new(display, GST_VAAPI_CHROMA_TYPE_YUV420, + GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); +} + +static gboolean +ensure_surface(GstVaapiVideoMemory *mem) +{ + if (!mem->surface) { + GstVaapiDisplay * const display = + gst_vaapi_video_meta_get_display(mem->meta); + + mem->surface = new_surface(display, mem->surface_info); + if (!mem->surface) + return FALSE; + } + gst_vaapi_video_meta_set_surface(mem->meta, mem->surface); + return TRUE; +} + +gboolean +gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, + GstMapInfo *info, gpointer *data, gint *stride, GstMapFlags flags) +{ + GstVaapiVideoMemory * const mem = + GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_get_memory(meta->buffer, 0)); + + g_return_val_if_fail(mem, FALSE); + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_ALLOCATOR(mem->parent_instance. + allocator), FALSE); + g_return_val_if_fail(mem->meta, FALSE); + + if ((flags & GST_MAP_READWRITE) == GST_MAP_READ) + goto error_unsupported_map; + + if (++mem->map_count == 1) { + if (!ensure_surface(mem)) + goto error_ensure_surface; + if (!ensure_image(mem)) + goto error_ensure_image; + if (!gst_vaapi_image_map(mem->image)) + goto error_map_image; + } + + *data = gst_vaapi_image_get_plane(mem->image, plane); + *stride = gst_vaapi_image_get_pitch(mem->image, plane); + info->flags = flags; + return TRUE; + + /* ERRORS */ +error_unsupported_map: + { + GST_ERROR("unsupported map flags (0x%x)", flags); + return FALSE; + } +error_ensure_surface: + { + const GstVideoInfo * const vip = mem->surface_info; + GST_ERROR("failed to create %s surface of size %ux%u", + GST_VIDEO_INFO_FORMAT_STRING(vip), + GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + return FALSE; + } +error_ensure_image: + { + const GstVideoInfo * const vip = mem->image_info; + GST_ERROR("failed to create %s image of size %ux%u", + GST_VIDEO_INFO_FORMAT_STRING(vip), + GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + return FALSE; + } +error_map_image: + { + GST_ERROR("failed to map image %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(gst_vaapi_image_get_id(mem->image))); + return FALSE; + } +} + +gboolean +gst_video_meta_unmap_vaapi_memory(GstVideoMeta *meta, guint plane, + GstMapInfo *info) +{ + GstVaapiVideoMemory * const mem = + GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_get_memory(meta->buffer, 0)); + + g_return_val_if_fail(mem, FALSE); + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_ALLOCATOR(mem->parent_instance. + allocator), FALSE); + g_return_val_if_fail(mem->meta, FALSE); + g_return_val_if_fail(mem->surface, FALSE); + g_return_val_if_fail(mem->image, FALSE); + + if (--mem->map_count == 0) { + gst_vaapi_image_unmap(mem->image); + + /* Commit VA image to surface */ + if (info->flags & GST_MAP_WRITE) { + if (!gst_vaapi_surface_put_image(mem->surface, mem->image)) + goto error_upload_image; + } + } + return TRUE; + + /* ERRORS */ +error_upload_image: + { + GST_ERROR("failed to upload image"); + return FALSE; + } +} + GstMemory * gst_vaapi_video_memory_new(GstAllocator *base_allocator, GstVaapiVideoMeta *meta) @@ -42,17 +192,24 @@ gst_vaapi_video_memory_new(GstAllocator *base_allocator, if (!mem) return NULL; - vip = &allocator->video_info; + vip = &allocator->image_info; gst_memory_init(&mem->parent_instance, 0, base_allocator, NULL, GST_VIDEO_INFO_SIZE(vip), 0, 0, GST_VIDEO_INFO_SIZE(vip)); + mem->surface_info = &allocator->surface_info; + mem->surface = NULL; + mem->image_info = &allocator->image_info; + mem->image = NULL; mem->meta = gst_vaapi_video_meta_ref(meta); + mem->map_count = 0; return GST_MEMORY_CAST(mem); } static void gst_vaapi_video_memory_free(GstVaapiVideoMemory *mem) { + g_clear_object(&mem->surface); + g_clear_object(&mem->image); gst_vaapi_video_meta_unref(mem->meta); g_slice_free(GstVaapiVideoMemory, mem); } @@ -156,11 +313,48 @@ gst_vaapi_video_allocator_init(GstVaapiVideoAllocator *allocator) gst_vaapi_video_memory_is_span; } +static gboolean +gst_video_info_update_from_image(GstVideoInfo *vip, GstVaapiImage *image) +{ + const guchar *data; + guint i, num_planes, data_size; + + num_planes = gst_vaapi_image_get_plane_count(image); + g_return_val_if_fail(num_planes == GST_VIDEO_INFO_N_PLANES(vip), FALSE); + + /* Determine the base data pointer */ + data = gst_vaapi_image_get_plane(image, 0); + for (i = 1; i < num_planes; i++) { + const guchar * const plane = gst_vaapi_image_get_plane(image, i); + if (data > plane) + data = plane; + } + data_size = gst_vaapi_image_get_data_size(image); + + /* Check that we don't have disjoint planes */ + for (i = 0; i < num_planes; i++) { + const guchar * const plane = gst_vaapi_image_get_plane(image, i); + if (plane - data > data_size) + return FALSE; + } + + /* Update GstVideoInfo structure */ + for (i = 0; i < num_planes; i++) { + const guchar * const plane = gst_vaapi_image_get_plane(image, i); + GST_VIDEO_INFO_PLANE_OFFSET(vip, i) = plane - data; + GST_VIDEO_INFO_PLANE_STRIDE(vip, i) = + gst_vaapi_image_get_pitch(image, i); + } + GST_VIDEO_INFO_SIZE(vip) = data_size; + return TRUE; +} + GstAllocator * gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) { GstVaapiVideoAllocator *allocator; GstVideoInfo *vip; + GstVaapiImage *image; g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); g_return_val_if_fail(GST_IS_CAPS(caps), NULL); @@ -173,5 +367,25 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) gst_video_info_init(vip); gst_video_info_from_caps(vip, caps); + gst_video_info_set_format(&allocator->surface_info, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + + allocator->image_info = *vip; + if (GST_VIDEO_INFO_FORMAT(vip) == GST_VIDEO_FORMAT_ENCODED) + gst_video_info_set_format(&allocator->image_info, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + + if (1) { + do { + image = new_image(display, &allocator->image_info); + if (!image) + break; + if (!gst_vaapi_image_map(image)) + break; + gst_video_info_update_from_image(&allocator->image_info, image); + gst_vaapi_image_unmap(image); + } while (0); + g_clear_object(&image); + } return GST_ALLOCATOR_CAST(allocator); } diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 447dd93f47..29f9582ff5 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -52,13 +52,28 @@ struct _GstVaapiVideoMemory { GstMemory parent_instance; /*< private >*/ + const GstVideoInfo *surface_info; + GstVaapiSurface *surface; + const GstVideoInfo *image_info; + GstVaapiImage *image; GstVaapiVideoMeta *meta; + gint map_count; }; G_GNUC_INTERNAL GstMemory * gst_vaapi_video_memory_new(GstAllocator *allocator, GstVaapiVideoMeta *meta); +G_GNUC_INTERNAL +gboolean +gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, + GstMapInfo *info, gpointer *data, gint *stride, GstMapFlags flags); + +G_GNUC_INTERNAL +gboolean +gst_video_meta_unmap_vaapi_memory(GstVideoMeta *meta, guint plane, + GstMapInfo *info); + /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoAllocator --- */ /* ------------------------------------------------------------------------ */ @@ -89,6 +104,8 @@ struct _GstVaapiVideoAllocator { /*< private >*/ GstVideoInfo video_info; + GstVideoInfo surface_info; + GstVideoInfo image_info; }; /** From 3f15a682eaeeaa49cacfd0f69ca9e168383d7f16 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Apr 2013 14:37:42 +0200 Subject: [PATCH 1140/3781] plugins: implement direct-rendering mode for raw YUV buffer uploads. Allow direct-rendering (writes) into target VA surfaces. --- gst/vaapi/gstvaapivideomemory.c | 38 +++++++++++++++++++++++++++++++-- gst/vaapi/gstvaapivideomemory.h | 2 ++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index a7d65caecc..5a84629f2f 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -50,6 +50,14 @@ new_image(GstVaapiDisplay *display, const GstVideoInfo *vip) static gboolean ensure_image(GstVaapiVideoMemory *mem) { + if (!mem->image && mem->use_direct_rendering) { + mem->image = gst_vaapi_surface_derive_image(mem->surface); + if (!mem->image) { + GST_WARNING("failed to derive image, fallbacking to copy"); + mem->use_direct_rendering = FALSE; + } + } + if (!mem->image) { GstVaapiDisplay * const display = gst_vaapi_video_meta_get_display(mem->meta); @@ -164,7 +172,7 @@ gst_video_meta_unmap_vaapi_memory(GstVideoMeta *meta, guint plane, gst_vaapi_image_unmap(mem->image); /* Commit VA image to surface */ - if (info->flags & GST_MAP_WRITE) { + if ((info->flags & GST_MAP_WRITE) && !mem->use_direct_rendering) { if (!gst_vaapi_surface_put_image(mem->surface, mem->image)) goto error_upload_image; } @@ -202,6 +210,7 @@ gst_vaapi_video_memory_new(GstAllocator *base_allocator, mem->image = NULL; mem->meta = gst_vaapi_video_meta_ref(meta); mem->map_count = 0; + mem->use_direct_rendering = allocator->has_direct_rendering; return GST_MEMORY_CAST(mem); } @@ -354,6 +363,7 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) { GstVaapiVideoAllocator *allocator; GstVideoInfo *vip; + GstVaapiSurface *surface; GstVaapiImage *image; g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); @@ -370,12 +380,36 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) gst_video_info_set_format(&allocator->surface_info, GST_VIDEO_FORMAT_NV12, GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + if (GST_VIDEO_INFO_FORMAT(vip) != GST_VIDEO_FORMAT_ENCODED) { + image = NULL; + do { + surface = new_surface(display, vip); + if (!surface) + break; + image = gst_vaapi_surface_derive_image(surface); + if (!image) + break; + if (!gst_vaapi_image_map(image)) + break; + allocator->has_direct_rendering = gst_video_info_update_from_image( + &allocator->surface_info, image); + gst_vaapi_image_unmap(image); + GST_INFO("has direct-rendering for %s surfaces: %s", + GST_VIDEO_INFO_FORMAT_STRING(&allocator->surface_info), + allocator->has_direct_rendering ? "yes" : "no"); + } while (0); + g_clear_object(&surface); + g_clear_object(&image); + } + allocator->image_info = *vip; if (GST_VIDEO_INFO_FORMAT(vip) == GST_VIDEO_FORMAT_ENCODED) gst_video_info_set_format(&allocator->image_info, GST_VIDEO_FORMAT_NV12, GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); - if (1) { + if (allocator->has_direct_rendering) + allocator->image_info = allocator->surface_info; + else { do { image = new_image(display, &allocator->image_info); if (!image) diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 29f9582ff5..615412da28 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -58,6 +58,7 @@ struct _GstVaapiVideoMemory { GstVaapiImage *image; GstVaapiVideoMeta *meta; gint map_count; + gboolean use_direct_rendering; }; G_GNUC_INTERNAL @@ -106,6 +107,7 @@ struct _GstVaapiVideoAllocator { GstVideoInfo video_info; GstVideoInfo surface_info; GstVideoInfo image_info; + gboolean has_direct_rendering; }; /** From 25538ca279f29e92793f61eaf1f1d9a924effcb0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Apr 2013 15:21:57 +0200 Subject: [PATCH 1141/3781] Bump library major version. Bump library major version, while preserving a major version of 0 for GStreamer 1.0 based libraries, and a major version of 2 for GStreamer 0.10 based librarieS. --- configure.ac | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 649497e8d5..700ee5e430 100644 --- a/configure.ac +++ b/configure.ac @@ -10,9 +10,11 @@ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) ]) # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1]) -m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [0]) +m4_define([gst_vaapi_lt_current], [2]) +m4_define([gst0_vaapi_lt_current_bias], [0]) +m4_define([gst1_vaapi_lt_current_bias], [2]) +m4_define([gst_vaapi_lt_revision], [0]) +m4_define([gst_vaapi_lt_age], [0]) # glib version number m4_define([glib_version], [2.28]) @@ -63,9 +65,6 @@ AM_INIT_AUTOMAKE([1.11 tar-ustar no-dist-gzip dist-bzip2]) TODAY="`LC_ALL=C date +'%a, %d %b %Y %X %z'`" AC_SUBST(TODAY) -GST_VAAPI_MAJOR_VERSION=gst_vaapi_lt_current -AC_SUBST(GST_VAAPI_MAJOR_VERSION) - LIBVA_PACKAGE_VERSION=libva_x11_package_version AC_SUBST(LIBVA_PACKAGE_VERSION) @@ -355,8 +354,15 @@ AC_CACHE_CHECK([for JPEG parser], AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_JPEG], [test "$ac_cv_have_gst_jpeg_parser" != "yes"]) +case $GST_API_VERSION in +0.10) lt_bias=gst0_vaapi_lt_current_bias;; +1.0) lt_bias=gst1_vaapi_lt_current_bias;; +esac +GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - "$lt_bias"` +AC_SUBST(GST_VAAPI_MAJOR_VERSION) + dnl GST_VAAPI_LT_LDFLAGS: -GST_VAAPI_LT_CURRENT=gst_vaapi_lt_current +GST_VAAPI_LT_CURRENT="$GST_VAAPI_MAJOR_VERSION" GST_VAAPI_LT_REV=gst_vaapi_lt_revision GST_VAAPI_LT_AGE=gst_vaapi_lt_age GST_VAAPI_LT_VERSION="$GST_VAAPI_LT_CURRENT:$GST_VAAPI_LT_REV:$GST_VAAPI_LT_AGE" From aedef381b2d6fd0580d6b46edb5504fba28daa4d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Apr 2013 15:31:41 +0200 Subject: [PATCH 1142/3781] Fix make dist to include all source files, in any case. Fix make dist to allow build for either GStreamer 0.10 or 1.0. i.e. make sure to include all source files in either case while generating source tarballs. --- gst-libs/gst/vaapi/Makefile.am | 11 +++++++++-- gst/vaapi/Makefile.am | 34 +++++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 16a27a60ff..858fb910a6 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -119,9 +119,11 @@ libgstvaapi_source_priv_h = \ sysdeps.h \ $(NULL) +libgstvaapi_jpegdec_source_c = gstvaapidecoder_jpeg.c +libgstvaapi_jpegdec_source_h = gstvaapidecoder_jpeg.h if USE_JPEG_DECODER -libgstvaapi_source_c += gstvaapidecoder_jpeg.c -libgstvaapi_source_h += gstvaapidecoder_jpeg.h +libgstvaapi_source_c += $(libgstvaapi_jpegdec_source_c) +libgstvaapi_source_h += $(libgstvaapi_jpegdec_source_h) endif libgstvaapi_drm_source_c = \ @@ -395,6 +397,11 @@ $(PKG_VERSION_FILE): $(NEW_VERSION_FILE) BUILT_SOURCES = gstvaapiversion.h EXTRA_DIST = gstvaapiversion.h.in $(PKG_VERSION_FILE) +EXTRA_DIST += \ + $(libgstvaapi_jpegdec_source_c) \ + $(libgstvaapi_jpegdec_source_h) \ + $(NULL) + CLEANFILES = \ $(OLD_VERSION_FILE) \ $(NEW_VERSION_FILE) \ diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 3f104e4ae7..d73bbadc33 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -48,37 +48,48 @@ libgstvaapi_source_h = \ gstvaapivideometa.h \ $(NULL) +libgstvaapi_glx_source_c = gstvaapivideoconverter_glx.c +libgstvaapi_glx_source_h = gstvaapivideoconverter_glx.h + if USE_GLX -libgstvaapi_source_c += gstvaapivideoconverter_glx.c -libgstvaapi_source_h += gstvaapivideoconverter_glx.h +libgstvaapi_source_c += $(libgstvaapi_glx_source_c) +libgstvaapi_source_h += $(libgstvaapi_glx_source_h) endif -if USE_GST_API_1_0p -libgstvaapi_source_c += \ +libgstvaapi_1_0p_source_c = \ gstvaapivideobufferpool.c \ gstvaapivideomemory.c \ $(NULL) -libgstvaapi_source_h += \ +libgstvaapi_1_0p_source_h = \ gstvaapivideobufferpool.h \ gstvaapivideomemory.h \ $(NULL) + +if USE_GST_API_1_0p +libgstvaapi_source_c += $(libgstvaapi_1_0p_source_c) +libgstvaapi_source_h += $(libgstvaapi_1_0p_source_h) endif if USE_GST_API_0_10 -libgstvaapi_source_c += \ +libgstvaapi_0_10_source_c = \ gstvaapidownload.c \ gstvaapipostproc.c \ gstvaapiupload.c \ $(NULL) -libgstvaapi_source_h += \ +libgstvaapi_0_10_source_h = \ gstvaapidownload.h \ gstvaapipostproc.h \ gstvaapiupload.h \ $(NULL) endif +if USE_GST_API_0_10 +libgstvaapi_source_c += $(libgstvaapi_0_10_source_c) +libgstvaapi_source_h += $(libgstvaapi_0_10_source_h) +endif + libgstvaapi_la_SOURCES = $(libgstvaapi_source_c) noinst_HEADERS = $(libgstvaapi_source_h) @@ -104,5 +115,14 @@ libgstvaapi_la_LIBADD = \ libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvaapi_la_LIBTOOLFLAGS = --tag=disable-static +EXTRA_DIST = \ + $(libgstvaapi_glx_source_c) \ + $(libgstvaapi_glx_source_h) \ + $(libgstvaapi_1_0p_source_c) \ + $(libgstvaapi_1_0p_source_h) \ + $(libgstvaapi_0_10_source_c) \ + $(libgstvaapi_0_10_source_h) \ + $(NULL) + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in From 1732e3fa87796d0c5ff44a06bfe58becbbff1fc5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Apr 2013 16:54:01 +0200 Subject: [PATCH 1143/3781] NEWS: updates. --- NEWS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 920bf924c3..3778e3496d 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,12 @@ -gst-vaapi NEWS -- summary of changes. 2013-03-28 +gst-vaapi NEWS -- summary of changes. 2013-04-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora +Version 0.5.3 - DD.Apr.2013 +* Add support for GStreamer 1.0.x API (+Sreerenj Balachandran) +* Fix fallback to sofware decoding if no hardware decoder is available + Version 0.5.2 - 28.Mar.2013 * Add support for video seek/reset (+Sreerenj Balachandran) * Improve MPEG-2 decoder robustness when packets are missing From be210a47223da6398b1d4b77e26b76ba91a985f5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 11 Apr 2013 09:24:44 +0200 Subject: [PATCH 1144/3781] README: updates. Update build requirements for GStreamer 1.0.x support. Add section for ways to report bugs. --- README | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README b/README index 9b65f72a68..b9bc070254 100644 --- a/README +++ b/README @@ -13,6 +13,7 @@ License gstreamer-vaapi helper libraries and plugin elements are available under the terms of the GNU Lesser General Public License v2.1+ + Overview -------- @@ -60,6 +61,12 @@ Software requirements libgstreamer-plugins-bad0.10-dev (>= 0.10.22.1) or with GstVideoContext, GstSurfaceBuffer, codecparsers + * GStreamer 1.0.x: + libglib2.0-dev (>= 2.28) + libgstreamer1.0-dev (>= 1.0.0) + libgstreamer-plugins-base1.0-dev (>= 1.0.0) + libgstreamer-plugins-bad1.0-dev (>= 1.0.0) + * Renderers: DRM: libva-dev (>= 1.1.0), libdrm-dev, libudev-dev X11: libva-dev (>= 1.0.1) @@ -90,3 +97,13 @@ Usage * Play a raw MPEG-2 interlaced stream $ gst-launch-0.10 -v filesrc location=/path/to/mpeg2.bits ! \ mpegvideoparse ! vaapidecode ! vaapipostproc ! vaapisink + + +Reporting Bugs +-------------- + + Bugs can be reported in the GNOME Bugzilla system at: + + + From the main page, new bugs can be reported through New -> Other -> + gstreamer-vaapi product. From 9b981dd2445f1793dad0e704d431e15590736ade Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 12 Apr 2013 13:44:52 +0200 Subject: [PATCH 1145/3781] plugins: fix description for gst-inspect. Fix the name of the plug-in element reported to gst-inspect-1.0. i.e. we need an explicit definition for GStreamer >= 1.0 because the GST_PLUGIN_DEFINE incorrectly uses #name for creating the plug-in name, instead of using macro expansion (and let further expansion of macros) through e.g. G_STRINGIFY(). --- gst-libs/gst/vaapi/gstcompat.h | 6 ------ gst/vaapi/gstvaapi.c | 24 +++++++++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index aedd93b219..16b3c71f58 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -64,9 +64,6 @@ typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, GstCaps *); #define GST_PAD_QUERY_FUNCTION_CALL(func, pad, parent, query) \ (func)(pad, parent, query) -/* GstPlugin */ -#define GST_PLUGIN_DESC_NAME(NAME) NAME - /* Misc helpers */ #define GST_MAKE_FORMAT_STRING(FORMAT) \ "format=(string)" G_STRINGIFY(FORMAT) @@ -262,9 +259,6 @@ typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, const GstCaps #define GST_PAD_QUERY_FUNCTION_CALL(func, pad, parent, query) \ (func)(pad, query) -/* GstPlugin */ -#define GST_PLUGIN_DESC_NAME(NAME) G_STRINGIFY(NAME) - /* Misc helpers */ #define GST_MAKE_FORMAT_STRING(FORMAT) \ "format=(fourcc)" G_STRINGIFY(FORMAT) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 407989d45f..600632d60f 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -29,6 +29,10 @@ #include "gstvaapipostproc.h" #include "gstvaapisink.h" +#define PLUGIN_NAME "vaapi" +#define PLUGIN_DESC "VA-API based elements" +#define PLUGIN_LICENSE "LGPL" + static gboolean plugin_init (GstPlugin *plugin) { @@ -54,12 +58,14 @@ plugin_init (GstPlugin *plugin) return TRUE; } -GST_PLUGIN_DEFINE( - GST_VERSION_MAJOR, GST_VERSION_MINOR, - GST_PLUGIN_DESC_NAME(vaapi), - "VA-API based elements", - plugin_init, - PACKAGE_VERSION, - "LGPL", - PACKAGE, - PACKAGE_BUGREPORT) +#if GST_CHECK_VERSION(1,0,0) +/* XXX: use PLUGIN_NAME when GST_PLUGIN_DEFINE is fixed to use + G_STRINGIFY() for name argument, instead of plain #name */ +GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, + vaapi, PLUGIN_DESC, plugin_init, + PACKAGE_VERSION, PLUGIN_LICENSE, PACKAGE, PACKAGE_BUGREPORT) +#else +GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, + PLUGIN_NAME, PLUGIN_DESC, plugin_init, + PACKAGE_VERSION, PLUGIN_LICENSE, PACKAGE, PACKAGE_BUGREPORT) +#endif From ca0e77756b056f65c1eb156dadd0194c9817760e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 12 Apr 2013 17:05:06 +0200 Subject: [PATCH 1146/3781] vaapisink: fix memory leak of GstSample objects. Fix memory leak of GstSample objects in GstVideoOverlayInterface::expose(). This also fixes extra unreferencing of the underlying GstBuffer in the common path afterwards (for both 0.10 or 1.0). --- gst/vaapi/gstvaapisink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 6c0cf90b81..2cde568b4b 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -225,7 +225,8 @@ gst_vaapisink_video_overlay_expose(GstVideoOverlay *overlay) GstSample * const sample = gst_base_sink_get_last_sample(base_sink); if (!sample) return; - buffer = gst_sample_get_buffer(sample); + buffer = gst_buffer_ref(gst_sample_get_buffer(sample)); + gst_sample_unref(sample); #else buffer = gst_base_sink_get_last_buffer(base_sink); #endif From ad56d80c9e6b2944de1a29c193296dd949cfbaeb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 12 Apr 2013 17:12:43 +0200 Subject: [PATCH 1147/3781] vaapisink: optimize GstVideoOverlayInterface::expose(). When render-mode is "overlay", then it is not really useful to peek into the GstBaseSink::last_buffer, since we have our own video_buffer already recorded and maintained into GstVaapiSink. --- gst/vaapi/gstvaapisink.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 2cde568b4b..35313dd2ff 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -218,18 +218,23 @@ gst_vaapisink_video_overlay_set_render_rectangle( static void gst_vaapisink_video_overlay_expose(GstVideoOverlay *overlay) { + GstVaapiSink * const sink = GST_VAAPISINK(overlay); GstBaseSink * const base_sink = GST_BASE_SINK(overlay); GstBuffer *buffer; + if (sink->use_overlay) + buffer = sink->video_buffer ? gst_buffer_ref(sink->video_buffer) : NULL; + else { #if GST_CHECK_VERSION(1,0,0) - GstSample * const sample = gst_base_sink_get_last_sample(base_sink); - if (!sample) - return; - buffer = gst_buffer_ref(gst_sample_get_buffer(sample)); - gst_sample_unref(sample); + GstSample * const sample = gst_base_sink_get_last_sample(base_sink); + if (!sample) + return; + buffer = gst_buffer_ref(gst_sample_get_buffer(sample)); + gst_sample_unref(sample); #else - buffer = gst_base_sink_get_last_buffer(base_sink); + buffer = gst_base_sink_get_last_buffer(base_sink); #endif + } if (buffer) { gst_vaapisink_show_frame(base_sink, buffer); gst_buffer_unref(buffer); From 132d78ad3e56e5c6d5ab5992b364c572f60da6bc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Apr 2013 13:48:43 +0200 Subject: [PATCH 1148/3781] plugins: implement GstSurfaceMeta API. Implement GstSurfaceMeta API for GStreamer 1.0.x. Even though this is an unstable/deprecated API, this makes it possible to support Clutter sink with minimal changes. Tested against clutter-gst 1.9.92. --- gst/vaapi/gstvaapivideobuffer.c | 110 +++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 1ae3f794c7..1d4ec80573 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -32,10 +32,116 @@ #endif #if GST_CHECK_VERSION(1,0,0) -static inline GstBuffer * +#include + +#define GST_VAAPI_SURFACE_META_CAST(obj) \ + ((GstVaapiSurfaceMeta *)(obj)) + +typedef struct _GstVaapiSurfaceMeta GstVaapiSurfaceMeta; +struct _GstVaapiSurfaceMeta { + GstSurfaceMeta base; + GstBuffer *buffer; +}; + +#define GST_VAAPI_SURFACE_META_INFO gst_vaapi_surface_meta_get_info() +static const GstMetaInfo * +gst_vaapi_surface_meta_get_info(void); + +typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc)( + GstSurfaceMeta *meta, const gchar *type, GValue *dest); + +#if USE_GLX +static GstSurfaceConverter * +gst_vaapi_surface_create_converter_glx(GstSurfaceMeta *base_meta, + const gchar *type, GValue *dest) +{ + GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta); + + return gst_vaapi_video_converter_glx_new(meta->buffer, type, dest); +} + +#undef gst_vaapi_video_converter_glx_new +#define gst_vaapi_video_converter_glx_new \ + gst_vaapi_surface_create_converter_glx +#endif + +static GstSurfaceConverter * +gst_vaapi_surface_create_converter(GstSurfaceMeta *base_meta, + const gchar *type, GValue *dest) +{ + GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta); + GstVaapiVideoMeta * const vmeta = + gst_buffer_get_vaapi_video_meta(meta->buffer); + GstSurfaceConverterCreateFunc func; + + if (G_UNLIKELY(!vmeta)) + return NULL; + + func = (GstSurfaceConverterCreateFunc) + gst_vaapi_video_meta_get_surface_converter(vmeta); + + return func ? func(base_meta, type, dest) : NULL; +} + +static gboolean +gst_vaapi_surface_meta_init(GstVaapiSurfaceMeta *meta, gpointer params, + GstBuffer *buffer) +{ + meta->base.create_converter = gst_vaapi_surface_create_converter; + meta->buffer = buffer; + return TRUE; +} + +static void +gst_vaapi_surface_meta_free(GstVaapiSurfaceMeta *meta, GstBuffer *buffer) +{ +} + +static gboolean +gst_vaapi_surface_meta_transform(GstBuffer *dst_buffer, GstMeta *meta, + GstBuffer *src_buffer, GQuark type, gpointer data) +{ + GstVaapiVideoMeta * const src_vmeta = + gst_buffer_get_vaapi_video_meta(src_buffer); + + if (GST_META_TRANSFORM_IS_COPY(type)) { + GstVaapiSurfaceMeta * const dst_smeta = GST_VAAPI_SURFACE_META_CAST( + gst_buffer_add_meta(dst_buffer, GST_VAAPI_SURFACE_META_INFO, NULL)); + + /* Note: avoid meta lookups in gst_vaapi_surface_create_converter() + by directly calling the GstVaapiVideoMeta::surface_converter hook */ + dst_smeta->base.create_converter = (GstSurfaceConverterCreateFunc) + gst_vaapi_video_meta_get_surface_converter(src_vmeta); + return TRUE; + } + return FALSE; +} + +const GstMetaInfo * +gst_vaapi_surface_meta_get_info(void) +{ + static gsize g_meta_info; + + if (g_once_init_enter(&g_meta_info)) { + gsize meta_info = GPOINTER_TO_SIZE(gst_meta_register( + GST_SURFACE_META_API_TYPE, + "GstVaapiSurfaceMeta", sizeof(GstVaapiSurfaceMeta), + (GstMetaInitFunction)gst_vaapi_surface_meta_init, + (GstMetaFreeFunction)gst_vaapi_surface_meta_free, + (GstMetaTransformFunction)gst_vaapi_surface_meta_transform)); + g_once_init_leave(&g_meta_info, meta_info); + } + return GSIZE_TO_POINTER(g_meta_info); +} + +static GstBuffer * gst_surface_buffer_new(void) { - return gst_buffer_new(); + GstBuffer * const buffer = gst_buffer_new(); + + if (buffer) + gst_buffer_add_meta(buffer, GST_VAAPI_SURFACE_META_INFO, NULL); + return buffer; } #else #include From 55b3053b886e5256500886bb593a903364c61103 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Apr 2013 13:52:19 +0200 Subject: [PATCH 1149/3781] plugins: mark a few more functions as internal. Mark the following functions are internal, i.e. private to the vaapi plug-in: - gst_vaapi_video_buffer_pool_get_type() - gst_vaapi_video_converter_glx_get_type() - gst_vaapi_video_converter_glx_new() --- gst/vaapi/gstvaapivideobufferpool.h | 1 + gst/vaapi/gstvaapivideoconverter_glx.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index 5b391e78f2..1b97bb1b88 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -79,6 +79,7 @@ struct _GstVaapiVideoBufferPoolClass { GstBufferPoolClass parent_class; }; +G_GNUC_INTERNAL GType gst_vaapi_video_buffer_pool_get_type(void) G_GNUC_CONST; diff --git a/gst/vaapi/gstvaapivideoconverter_glx.h b/gst/vaapi/gstvaapivideoconverter_glx.h index 97aa6556c8..54ea70929e 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.h +++ b/gst/vaapi/gstvaapivideoconverter_glx.h @@ -79,9 +79,11 @@ struct _GstVaapiVideoConverterGLXClass { GObjectClass parent_class; }; +G_GNUC_INTERNAL GType gst_vaapi_video_converter_glx_get_type(void) G_GNUC_CONST; +G_GNUC_INTERNAL GstSurfaceConverter * gst_vaapi_video_converter_glx_new(GstBuffer *buffer, const gchar *type, GValue *dest); From 1790823ed48ce6f9b3e3347b0b10b348f5a0f2ae Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Apr 2013 13:58:58 +0200 Subject: [PATCH 1150/3781] decoder: make gst_vaapi_decoder_get_codec_state() return the original state. Make gst_vaapi_decoder_get_codec_state() return the original codec state, i.e. make the GstVaapiDecoder object own the return state so that callers that want an extra reference to it would just gst_video_codec_state_ref() it before usage. This aligns the behaviour with what we had before with gst_vaapi_decoder_get_caps(). This is an ABI incompatible change, library major version was bumped from previous release (0.5.2). --- gst-libs/gst/vaapi/gstvaapidecoder.c | 8 ++++---- gst/vaapi/gstvaapidecode.c | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 3225b9f3e6..35294c66f0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -612,9 +612,9 @@ gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder) * gst_vaapi_decoder_get_codec_state: * @decoder: a #GstVaapiDecoder * - * Retrieves the @decoder codec state. The caller owns an extra reference - * to the #GstVideoCodecState, so gst_video_codec_state_unref() shall be - * called after usage. + * Retrieves the @decoder codec state. The decoder owns the returned + * #GstVideoCodecState structure, so use gst_video_codec_state_ref() + * whenever necessary. * * Return value: the #GstVideoCodecState object for @decoder */ @@ -630,7 +630,7 @@ gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder) * gst_vaapi_decoder_get_caps: * @decoder: a #GstVaapiDecoder * - * Retrieves the @decoder caps. The deocder owns the returned caps, so + * Retrieves the @decoder caps. The decoder owns the returned caps, so * use gst_caps_ref() whenever necessary. * * Return value: the @decoder caps diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index c51ca63922..a12c0c8166 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -136,13 +136,11 @@ static void gst_vaapi_decoder_notify_caps(GObject *obj, GParamSpec *pspec, void *user_data) { GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data); - GstVideoCodecState *codec_state; g_assert(decode->decoder == GST_VAAPI_DECODER(obj)); - codec_state = gst_vaapi_decoder_get_codec_state(decode->decoder); - gst_vaapidecode_update_src_caps(decode, codec_state); - gst_video_codec_state_unref(codec_state); + gst_vaapidecode_update_src_caps(decode, + gst_vaapi_decoder_get_codec_state(decode->decoder)); } static inline gboolean From 8cce65c6f1314f824a8a3ea5a995f983cf4d059f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Apr 2013 14:22:57 +0200 Subject: [PATCH 1151/3781] decoder: fix gst_vaapi_decoder_get_codec_state(). Fix previous commit whereby gst_vaapi_decoder_get_codec_state() was supposed to make GstVaapiDecoder own the return GstVideoCodecState object. Only comment was updated, not the actual code. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 35294c66f0..ccd4f77338 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -623,7 +623,7 @@ gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder) { g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); - return gst_video_codec_state_ref(decoder->priv->codec_state); + return GST_VAAPI_DECODER_CODEC_STATE(decoder); } /** From 2db47c0ade98b4e4e1359dab23aa48f9b15c69b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 Apr 2013 12:52:51 +0400 Subject: [PATCH 1152/3781] build: link libgstvaapi-glx-1.0.so against libdl. Ensure libgstvaapi-glx*.so builds against libdl since dlsym() is used to resolve glXGetProcAddress() from GLX libraries. This fix builds on Fedora 17. https://bugzilla.gnome.org/show_bug.cgi?id=698046 Signed-off-by: Gwenole Beauchesne --- configure.ac | 6 ++++++ gst-libs/gst/vaapi/Makefile.am | 1 + 2 files changed, 7 insertions(+) diff --git a/configure.ac b/configure.ac index 700ee5e430..a91a459925 100644 --- a/configure.ac +++ b/configure.ac @@ -131,6 +131,12 @@ GLIB_VERSION_REQUIRED=glib_version PKG_CHECK_MODULES([GLIB], [glib-2.0 >= $GLIB_VERSION_REQUIRED]) AC_SUBST(GLIB_VERSION_REQUIRED) +dnl Check to see if dlopen is in default libraries (like Solaris, which +dnl has it in libc), or if libdl is needed to get it. +AC_CHECK_FUNC([dlopen], [], [ + AC_CHECK_LIB([dl], [dlopen], [DLOPEN_LIBS="-ldl"])]) +AC_SUBST([DLOPEN_LIBS]) + dnl --------------------------------------------------------------------------- dnl -- GStreamer -- dnl --------------------------------------------------------------------------- diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 858fb910a6..6f52d472fa 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -327,6 +327,7 @@ libgstvaapi_glx_@GST_API_VERSION@_la_LIBADD = \ $(GL_LIBS) \ $(LIBVA_GLX_LIBS) \ libgstvaapi-x11-$(GST_API_VERSION).la \ + $(DLOPEN_LIBS) \ $(NULL) libgstvaapi_glx_@GST_API_VERSION@_la_LDFLAGS = \ From 0bd929dfa275e648abae82406704290868453d09 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 16 Apr 2013 13:48:00 +0200 Subject: [PATCH 1153/3781] surfaceproxy: drop user-data support from GstVaapiSurfaceProxy. Drop user-data support from GstVaapiSurfaceProxy. Rather make it explicit to call some user-provided function when the surface proxy is released. --- docs/reference/libs/libs-sections.txt | 3 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 66 ++++++++++------------- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 11 ++-- gst/vaapi/gstvaapidecode.c | 4 +- tests/simple-decoder.c | 4 +- 5 files changed, 36 insertions(+), 52 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 33f645b556..81b4b9a5d2 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -523,11 +523,10 @@ GST_VAAPI_DECODER_VC1_GET_CLASS GstVaapiSurfaceProxy gst_vaapi_surface_proxy_get_surface gst_vaapi_surface_proxy_get_surface_id -gst_vaapi_surface_proxy_get_user_data gst_vaapi_surface_proxy_new_from_pool gst_vaapi_surface_proxy_ref gst_vaapi_surface_proxy_replace -gst_vaapi_surface_proxy_set_user_data +gst_vaapi_surface_proxy_set_destroy_notify gst_vaapi_surface_proxy_unref GST_VAAPI_SURFACE_PROXY_SURFACE diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index e802eab40e..83faf19159 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -45,11 +45,16 @@ struct _GstVaapiSurfaceProxy { GstVaapiVideoPool *pool; GstVaapiSurface *surface; + GDestroyNotify destroy_func; + gpointer destroy_data; }; static void gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) { + if (proxy->destroy_func) + proxy->destroy_func(proxy->destroy_data); + if (proxy->surface) { if (proxy->pool) gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface); @@ -85,6 +90,7 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool); if (!proxy->surface) goto error; + proxy->destroy_func = NULL; g_object_ref(proxy->surface); return proxy; @@ -144,45 +150,6 @@ gst_vaapi_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr, GST_VAAPI_MINI_OBJECT(new_proxy)); } -/** - * gst_vaapi_surface_proxy_get_user_data: - * @proxy: a #GstVaapiSurfaceProxy - * - * Gets user-provided data set on the object via a previous call to - * gst_vaapi_surface_proxy_set_user_data(). - * - * Returns: (transfer none): The previously set user_data - */ -gpointer -gst_vaapi_surface_proxy_get_user_data(GstVaapiSurfaceProxy *proxy) -{ - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); - - return gst_vaapi_mini_object_get_user_data(GST_VAAPI_MINI_OBJECT(proxy)); -} - -/** - * gst_vaapi_surface_proxy_set_user_data: - * @proxy: a #GstVaapiSurfaceProxy - * @user_data: user-provided data - * @destroy_notify: (closure user_data): a #GDestroyNotify - * - * Sets @user_data on the object and the #GDestroyNotify that will be - * called when the data is freed. - * - * If some @user_data was previously set, then the former @destroy_notify - * function will be called before the @user_data is replaced. - */ -void -gst_vaapi_surface_proxy_set_user_data(GstVaapiSurfaceProxy *proxy, - gpointer user_data, GDestroyNotify destroy_notify) -{ - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); - - gst_vaapi_mini_object_set_user_data(GST_VAAPI_MINI_OBJECT(proxy), - user_data, destroy_notify); -} - /** * gst_vaapi_surface_proxy_get_surface: * @proxy: a #GstVaapiSurfaceProxy @@ -215,3 +182,24 @@ gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) return GST_VAAPI_OBJECT_ID(proxy->surface); } + +/** + * gst_vaapi_surface_proxy_set_destroy_notify: + * @proxy: a @GstVaapiSurfaceProxy + * @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 surface @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_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy, + GDestroyNotify destroy_func, gpointer user_data) +{ + g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + + proxy->destroy_func = destroy_func; + proxy->destroy_data = user_data; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 467699dace..ef8ee691cf 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -50,19 +50,16 @@ void gst_vaapi_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr, GstVaapiSurfaceProxy *new_proxy); -gpointer -gst_vaapi_surface_proxy_get_user_data(GstVaapiSurfaceProxy *proxy); - -void -gst_vaapi_surface_proxy_set_user_data(GstVaapiSurfaceProxy *proxy, - gpointer user_data, GDestroyNotify destroy_notify); - GstVaapiSurface * gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy); GstVaapiID gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy); +void +gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy, + GDestroyNotify destroy_func, gpointer user_data); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_PROXY_H */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a12c0c8166..f0e5654a0f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -284,8 +284,8 @@ gst_vaapidecode_push_decoded_frames(GstVideoDecoder *vdec) if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(out_frame)) { proxy = gst_video_codec_frame_get_user_data(out_frame); - gst_vaapi_surface_proxy_set_user_data(proxy, - decode, (GDestroyNotify)gst_vaapidecode_release); + gst_vaapi_surface_proxy_set_destroy_notify(proxy, + (GDestroyNotify)gst_vaapidecode_release, decode); #if GST_CHECK_VERSION(1,0,0) ret = gst_video_decoder_allocate_output_frame(vdec, out_frame); diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index 04625a627b..7e33f0c641 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -266,8 +266,8 @@ decoder_thread(gpointer data) status = gst_vaapi_decoder_get_surface(app->decoder, &proxy); switch (status) { case GST_VAAPI_DECODER_STATUS_SUCCESS: - gst_vaapi_surface_proxy_set_user_data(proxy, - app, (GDestroyNotify)decoder_release); + gst_vaapi_surface_proxy_set_destroy_notify(proxy, + (GDestroyNotify)decoder_release, app); rfp = render_frame_new(); if (!rfp) SEND_ERROR("failed to allocate render frame"); From c7dff071c7ac118fe7bbb593276f199df9258b3f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 16 Apr 2013 18:35:48 +0200 Subject: [PATCH 1154/3781] surfaceproxy: add more attributes for raw decoding modes. Add more attributes for raw decoding modes, i.e. directly through the libgstvaapi helper library. In particular, add presentation timestamp, duration and a couple of flags (interlaced, TFF, RFF, one-field). --- docs/reference/libs/libs-sections.txt | 3 + gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 76 +++++++++---- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 67 ++++++++++- .../gst/vaapi/gstvaapisurfaceproxy_priv.h | 104 ++++++++++++++++++ 5 files changed, 225 insertions(+), 26 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 81b4b9a5d2..5f37cf6474 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -521,8 +521,11 @@ GST_VAAPI_DECODER_VC1_GET_CLASS
gstvaapisurfaceproxy GstVaapiSurfaceProxy +gst_vaapi_surface_proxy_get_duration +gst_vaapi_surface_proxy_get_flags gst_vaapi_surface_proxy_get_surface gst_vaapi_surface_proxy_get_surface_id +gst_vaapi_surface_proxy_get_timestamp gst_vaapi_surface_proxy_new_from_pool gst_vaapi_surface_proxy_ref gst_vaapi_surface_proxy_replace diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 6f52d472fa..9d20cd62b5 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -113,6 +113,7 @@ libgstvaapi_source_priv_h = \ gstvaapiminiobject.h \ gstvaapiobject_priv.h \ gstvaapisurface_priv.h \ + gstvaapisurfaceproxy_priv.h \ gstvaapiutils.h \ gstvaapiversion.h \ gstvaapiworkarounds.h \ diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 83faf19159..c0827b78c8 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -27,28 +27,11 @@ #include "sysdeps.h" #include "gstvaapisurfaceproxy.h" -#include "gstvaapiobject_priv.h" -#include "gstvaapiminiobject.h" +#include "gstvaapisurfaceproxy_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -#define GST_VAAPI_SURFACE_PROXY(obj) \ - ((GstVaapiSurfaceProxy *)(obj)) - -#define GST_VAAPI_IS_SURFACE_PROXY(obj) \ - (GST_VAAPI_SURFACE_PROXY(obj) != NULL) - -struct _GstVaapiSurfaceProxy { - /*< private >*/ - GstVaapiMiniObject parent_instance; - - GstVaapiVideoPool *pool; - GstVaapiSurface *surface; - GDestroyNotify destroy_func; - gpointer destroy_data; -}; - static void gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) { @@ -86,10 +69,12 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) if (!proxy) return NULL; - proxy->pool = g_object_ref(pool); + proxy->pool = g_object_ref(pool); proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool); if (!proxy->surface) goto error; + proxy->timestamp = GST_CLOCK_TIME_NONE; + proxy->duration = GST_CLOCK_TIME_NONE; proxy->destroy_func = NULL; g_object_ref(proxy->surface); return proxy; @@ -163,7 +148,24 @@ gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); - return proxy->surface; + return GST_VAAPI_SURFACE_PROXY_SURFACE(proxy); +} + +/** + * gst_vaapi_surface_proxy_get_flags: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the #GstVaapiSurfaceProxyFlags associated with this surface + * @proxy. + * + * Return value: the set of #GstVaapiSurfaceProxyFlags + */ +guint +gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0); + + return GST_VAAPI_SURFACE_PROXY_FLAGS(proxy); } /** @@ -180,7 +182,39 @@ gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), GST_VAAPI_ID_NONE); g_return_val_if_fail(proxy->surface != NULL, GST_VAAPI_ID_NONE); - return GST_VAAPI_OBJECT_ID(proxy->surface); + return GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy); +} + +/** + * gst_vaapi_surface_proxy_get_timestamp: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the presentation timestamp for this surface @proxy. + * + * Return value: the presentation timestamp + */ +GstClockTime +gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0); + + return GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); +} + +/** + * gst_vaapi_surface_proxy_get_duration: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the presentation duration for this surface @proxy. + * + * Return value: the presentation duration + */ +GstClockTime +gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0); + + return GST_VAAPI_SURFACE_PROXY_DURATION(proxy); } /** diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index ef8ee691cf..c9def5708e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -29,13 +29,61 @@ G_BEGIN_DECLS /** - * GST_VAAPI_SURFACE_PROXY_SURFACE: - * @surface: a #GstVaapiSurfaceProxy + * GstVaapiSurfaceProxyFlags: + * @GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED: interlaced frame + * @GST_VAAPI_SURFACE_PROXY_FLAG_TFF: top-field-first + * @GST_VAAPI_SURFACE_PROXY_FLAG_RFF: repeat-field-first + * @GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD: only one field is available + * @GST_VAAPI_SURFACE_PROXY_FLAG_LAST: first flag that can be used by subclasses * - * Macro that evaluates to the #GstVaapiSurface of @surface. + * Flags for #GstVaapiDecoderFrame. */ -#define GST_VAAPI_SURFACE_PROXY_SURFACE(surface) \ - gst_vaapi_surface_proxy_get_surface(surface) +typedef enum { + GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED = (1 << 0), + GST_VAAPI_SURFACE_PROXY_FLAG_TFF = (1 << 1), + GST_VAAPI_SURFACE_PROXY_FLAG_RFF = (1 << 2), + GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD = (1 << 3), + GST_VAAPI_SURFACE_PROXY_FLAG_LAST = (1 << 8) +} GstVaapiSurfaceProxyFlags; + +/** + * GST_VAAPI_SURFACE_PROXY_SURFACE: + * @proxy: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the #GstVaapiSurface of @proxy. + */ +#define GST_VAAPI_SURFACE_PROXY_SURFACE(proxy) \ + gst_vaapi_surface_proxy_get_surface(proxy) + +/** + * GST_VAAPI_SURFACE_PROXY_SURFACE_ID: + * @proxy: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the VA surface ID of the underlying @proxy + * surface. + */ +#define GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) \ + gst_vaapi_surface_proxy_get_surface_id(proxy) + +/** + * GST_VAAPI_SURFACE_PROXY_TIMESTAMP: + * @proxy: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the presentation timestamp of the + * underlying @proxy surface. + */ +#define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy) \ + gst_vaapi_surface_proxy_get_timestamp(proxy) + +/** + * GST_VAAPI_SURFACE_PROXY_DURATION: + * @proxy: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the presentation duration of the + * underlying @proxy surface. + */ +#define GST_VAAPI_SURFACE_PROXY_DURATION(proxy) \ + gst_vaapi_surface_proxy_get_duration(proxy) GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool); @@ -50,12 +98,21 @@ void gst_vaapi_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr, GstVaapiSurfaceProxy *new_proxy); +guint +gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy); + GstVaapiSurface * gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy); GstVaapiID gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy); +GstClockTime +gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy); + +GstClockTime +gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy); + void gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy, GDestroyNotify destroy_func, gpointer user_data); diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h new file mode 100644 index 0000000000..7df307fd04 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -0,0 +1,104 @@ +/* + * gstvaapisurfaceproxy_priv.h - VA surface proxy (private definitions) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2012 Intel Corporation + * + * 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_SURFACE_PROXY_PRIV_H +#define GST_VAAPI_SURFACE_PROXY_PRIV_H + +#include "gstvaapiminiobject.h" +#include "gstvaapisurfaceproxy.h" +#include "gstvaapiobject_priv.h" +#include "gstvaapisurface_priv.h" + +#define GST_VAAPI_SURFACE_PROXY(obj) \ + ((GstVaapiSurfaceProxy *)(obj)) + +#define GST_VAAPI_IS_SURFACE_PROXY(obj) \ + (GST_VAAPI_SURFACE_PROXY(obj) != NULL) + +struct _GstVaapiSurfaceProxy { + /*< private >*/ + GstVaapiMiniObject parent_instance; + + GstVaapiVideoPool *pool; + GstVaapiSurface *surface; + GstClockTime timestamp; + GstClockTime duration; + GDestroyNotify destroy_func; + gpointer destroy_data; +}; + +#define GST_VAAPI_SURFACE_PROXY_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS +#define GST_VAAPI_SURFACE_PROXY_FLAG_IS_SET GST_VAAPI_MINI_OBJECT_FLAG_IS_SET +#define GST_VAAPI_SURFACE_PROXY_FLAG_SET GST_VAAPI_MINI_OBJECT_FLAG_SET +#define GST_VAAPI_SURFACE_PROXY_FLAG_UNSET GST_VAAPI_MINI_OBJECT_FLAG_UNSET + +/** + * GST_VAAPI_SURFACE_PROXY_SURFACE: + * @proxy: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the #GstVaapiSurface of @proxy. + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_SURFACE_PROXY_SURFACE +#define GST_VAAPI_SURFACE_PROXY_SURFACE(proxy) \ + proxy->surface + +/** + * GST_VAAPI_SURFACE_PROXY_SURFACE_ID: + * @proxy: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the VA surface ID of the underlying @proxy + * surface. + * + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_SURFACE_PROXY_SURFACE_ID +#define GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) \ + GST_VAAPI_OBJECT_ID(proxy->surface) + +/** + * GST_VAAPI_SURFACE_PROXY_TIMESTAMP: + * @proxy: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the presentation timestamp of the + * underlying @proxy surface. + * + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_SURFACE_PROXY_TIMESTAMP +#define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy) \ + proxy->timestamp + +/** + * GST_VAAPI_SURFACE_PROXY_DURATION: + * @proxy: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the presentation duration of the + * underlying @proxy surface. + * + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_SURFACE_PROXY_DURATION +#define GST_VAAPI_SURFACE_PROXY_DURATION(proxy) \ + proxy->duration + +#endif /* GST_VAAPI_SURFACE_PROXY_PRIV_H */ From 87e5717f667774e15bd1bd170974ece634e4f63c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 16 Apr 2013 18:56:24 +0200 Subject: [PATCH 1155/3781] decoder: use new GstVaapiSurfaceProxy utility functions. Use new GstVaapiSurfaceProxy internal helper functions to propagate the necessary GstVideoCodecFrame flags to vaapidecode (GStreamer 0.10). Also make GstVaapiDecoder push_frame() operate similarly to drop_frame(). i.e. increase the GstVideoCodecFrame reference count in push_frame rather than gst_vaapi_picture_output(). --- gst-libs/gst/vaapi/gstvaapidecoder.c | 26 ++++++++++++++++---- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 24 +++++++++--------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index ccd4f77338..e7468d03d8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -29,6 +29,7 @@ #include "gstvaapicompat.h" #include "gstvaapidecoder.h" #include "gstvaapidecoder_priv.h" +#include "gstvaapisurfaceproxy_priv.h" #include "gstvaapiutils.h" #include "gstvaapi_priv.h" @@ -386,12 +387,12 @@ static inline void push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) { GstVaapiDecoderPrivate * const priv = decoder->priv; + GstVaapiSurfaceProxy * const proxy = frame->user_data; GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id( - frame->user_data))); + GST_VAAPI_ID_ARGS(GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy))); - g_queue_push_tail(priv->frames, frame); + g_queue_push_tail(priv->frames, gst_video_codec_frame_ref(frame)); } static inline GstVideoCodecFrame * @@ -399,14 +400,15 @@ pop_frame(GstVaapiDecoder *decoder) { GstVaapiDecoderPrivate * const priv = decoder->priv; GstVideoCodecFrame *frame; + GstVaapiSurfaceProxy *proxy; frame = g_queue_pop_head(priv->frames); if (!frame) return NULL; + proxy = frame->user_data; GST_DEBUG("dequeue decoded surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id( - frame->user_data))); + GST_VAAPI_ID_ARGS(GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy))); return frame; } @@ -745,6 +747,20 @@ gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder, if (!out_frame) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; +#if !GST_CHECK_VERSION(1,0,0) + if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(out_frame)) { + const guint flags = GST_VAAPI_SURFACE_PROXY_FLAGS(out_frame->user_data); + guint out_flags = 0; + + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF) + out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_TFF; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF) + out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_RFF; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) + out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_ONEFIELD; + } +#endif + *out_frame_ptr = out_frame; return GST_VAAPI_DECODER_STATUS_SUCCESS; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index dbae6448cb..f94fd6c43f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -25,6 +25,7 @@ #include #include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" +#include "gstvaapisurfaceproxy_priv.h" #include "gstvaapicompat.h" #include "gstvaapiutils.h" @@ -140,8 +141,8 @@ gst_vaapi_picture_create( picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_FF); } - picture->surface = gst_vaapi_surface_proxy_get_surface(picture->proxy); - picture->surface_id = gst_vaapi_surface_get_id(picture->surface); + picture->surface = GST_VAAPI_SURFACE_PROXY_SURFACE(picture->proxy); + picture->surface_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID(picture->proxy); picture->param_id = VA_INVALID_ID; success = vaapi_create_buffer( @@ -297,30 +298,31 @@ gst_vaapi_picture_decode(GstVaapiPicture *picture) gboolean gst_vaapi_picture_output(GstVaapiPicture *picture) { + GstVideoCodecFrame * const out_frame = picture->frame; GstVaapiSurfaceProxy *proxy; - GstVideoCodecFrame *out_frame; + guint flags = 0; g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE); if (!picture->proxy) return FALSE; - out_frame = gst_video_codec_frame_ref(picture->frame); - proxy = gst_vaapi_surface_proxy_ref(picture->proxy); 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_CHECK_VERSION(1,0,0) - /* XXX: replaced with GST_VIDEO_BUFFER_FLAG_TFF */ - if (GST_VAAPI_PICTURE_IS_TFF(picture)) - GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, - GST_VIDEO_CODEC_FRAME_FLAG_TFF); -#endif + + 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; + } + GST_VAAPI_SURFACE_PROXY_FLAG_SET(proxy, flags); gst_vaapi_decoder_push_frame(GET_DECODER(picture), out_frame); From 2ac474b207e0848367661fc4769f72da50779d92 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 16 Apr 2013 19:09:30 +0200 Subject: [PATCH 1156/3781] decoder: export presentation timestamp for raw decoding mode. Fix regression from 0.4-branch whereby GstVaapiSurfaceProxy no longer held any information about the expected presentation timestamp, frame duration or additional flags like interlaced or top-field-first. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index e7468d03d8..1d3eb108d7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -701,7 +701,10 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, frame = pop_frame(decoder); while (frame) { if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(frame)) { - *out_proxy_ptr = gst_vaapi_surface_proxy_ref(frame->user_data); + GstVaapiSurfaceProxy * const proxy = frame->user_data; + proxy->timestamp = frame->pts; + proxy->duration = frame->duration; + *out_proxy_ptr = proxy; gst_video_codec_frame_unref(frame); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From a24e2164660b909b43d2c916d6651514603e6c07 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 16 Apr 2013 13:23:41 +0200 Subject: [PATCH 1157/3781] decoder: rename GstVaapiDecoderFrame to GstVaapiParserFrame. Rename GstVaapiDecoderFrame to GstVaapiParserFrame because this data structure was only useful to parsing and a proper GstvaapiDecoderFrame instance will be created instead. --- gst-libs/gst/vaapi/Makefile.am | 4 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 15 ++--- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 +- ...decoder_frame.c => gstvaapiparser_frame.c} | 46 +++++++------- ...decoder_frame.h => gstvaapiparser_frame.h} | 60 +++++++------------ 5 files changed, 57 insertions(+), 70 deletions(-) rename gst-libs/gst/vaapi/{gstvaapidecoder_frame.c => gstvaapiparser_frame.c} (74%) rename gst-libs/gst/vaapi/{gstvaapidecoder_frame.h => gstvaapiparser_frame.h} (55%) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 9d20cd62b5..7c021a2748 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -46,7 +46,6 @@ libgstvaapi_source_c = \ gstvaapicontext.c \ gstvaapidecoder.c \ gstvaapidecoder_dpb.c \ - gstvaapidecoder_frame.c \ gstvaapidecoder_h264.c \ gstvaapidecoder_mpeg2.c \ gstvaapidecoder_mpeg4.c \ @@ -61,6 +60,7 @@ libgstvaapi_source_c = \ gstvaapiminiobject.c \ gstvaapiobject.c \ gstvaapiparamspecs.c \ + gstvaapiparser_frame.c \ gstvaapiprofile.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ @@ -105,13 +105,13 @@ libgstvaapi_source_priv_h = \ gstvaapicompat.h \ gstvaapidebug.h \ gstvaapidecoder_dpb.h \ - gstvaapidecoder_frame.h \ gstvaapidecoder_objects.h \ gstvaapidecoder_priv.h \ gstvaapidecoder_unit.h \ gstvaapidisplay_priv.h \ gstvaapiminiobject.h \ gstvaapiobject_priv.h \ + gstvaapiparser_frame.h \ gstvaapisurface_priv.h \ gstvaapisurfaceproxy_priv.h \ gstvaapiutils.h \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 1d3eb108d7..2a3dd76af3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -29,6 +29,7 @@ #include "gstvaapicompat.h" #include "gstvaapidecoder.h" #include "gstvaapidecoder_priv.h" +#include "gstvaapiparser_frame.h" #include "gstvaapisurfaceproxy_priv.h" #include "gstvaapiutils.h" #include "gstvaapi_priv.h" @@ -141,7 +142,7 @@ do_parse(GstVaapiDecoder *decoder, { GstVaapiDecoderPrivate * const priv = decoder->priv; GstVaapiParserState * const ps = &priv->parser_state; - GstVaapiDecoderFrame *frame; + GstVaapiParserFrame *frame; GstVaapiDecoderUnit *unit; GstVaapiDecoderStatus status; @@ -151,7 +152,7 @@ do_parse(GstVaapiDecoder *decoder, frame = gst_video_codec_frame_get_user_data(base_frame); if (!frame) { GstVideoCodecState * const codec_state = priv->codec_state; - frame = gst_vaapi_decoder_frame_new(codec_state->info.width, + frame = gst_vaapi_parser_frame_new(codec_state->info.width, codec_state->info.height); if (!frame) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -188,7 +189,7 @@ do_parse(GstVaapiDecoder *decoder, } got_unit: - gst_vaapi_decoder_frame_append_unit(frame, unit); + gst_vaapi_parser_frame_append_unit(frame, unit); *got_unit_size_ptr = unit->size; *got_frame_ptr = GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit); return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -214,7 +215,7 @@ do_decode_units(GstVaapiDecoder *decoder, GArray *units) } static GstVaapiDecoderStatus -do_decode_1(GstVaapiDecoder *decoder, GstVaapiDecoderFrame *frame) +do_decode_1(GstVaapiDecoder *decoder, GstVaapiParserFrame *frame) { GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); GstVaapiDecoderStatus status; @@ -261,14 +262,14 @@ static inline GstVaapiDecoderStatus do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) { GstVaapiParserState * const ps = &decoder->priv->parser_state; - GstVaapiDecoderFrame * const frame = base_frame->user_data; + GstVaapiParserFrame * const frame = base_frame->user_data; GstVaapiDecoderStatus status; ps->current_frame = base_frame; - gst_vaapi_decoder_frame_ref(frame); + gst_vaapi_parser_frame_ref(frame); status = do_decode_1(decoder, frame); - gst_vaapi_decoder_frame_unref(frame); + gst_vaapi_parser_frame_unref(frame); switch ((guint)status) { case GST_VAAPI_DECODER_STATUS_DROP_FRAME: diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 4bf4afe1d7..12af49c06f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.c b/gst-libs/gst/vaapi/gstvaapiparser_frame.c similarity index 74% rename from gst-libs/gst/vaapi/gstvaapidecoder_frame.c rename to gst-libs/gst/vaapi/gstvaapiparser_frame.c index c2e659b814..9c87300ce2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_frame.c +++ b/gst-libs/gst/vaapi/gstvaapiparser_frame.c @@ -1,5 +1,5 @@ /* - * gstvaapidecoder_frame.c - VA decoder frame + * gstvaapiparser_frame.c - VA parser frame * * Copyright (C) 2012-2013 Intel Corporation * @@ -20,21 +20,21 @@ */ /** - * SECTION:gstvaapidecoder_frame + * SECTION:gstvaapiparser_frame * @short_description: VA decoder frame */ #include "sysdeps.h" -#include "gstvaapidecoder_frame.h" +#include "gstvaapiparser_frame.h" static inline const GstVaapiMiniObjectClass * -gst_vaapi_decoder_frame_class(void) +gst_vaapi_parser_frame_class(void) { - static const GstVaapiMiniObjectClass GstVaapiDecoderFrameClass = { - sizeof(GstVaapiDecoderFrame), - (GDestroyNotify)gst_vaapi_decoder_frame_free + static const GstVaapiMiniObjectClass GstVaapiParserFrameClass = { + sizeof(GstVaapiParserFrame), + (GDestroyNotify)gst_vaapi_parser_frame_free }; - return &GstVaapiDecoderFrameClass; + return &GstVaapiParserFrameClass; } static inline gboolean @@ -65,22 +65,22 @@ free_units(GArray **units_ptr) } /** - * gst_vaapi_decoder_frame_new: + * gst_vaapi_parser_frame_new: * @width: frame width in pixels * @height: frame height in pixels * - * Creates a new #GstVaapiDecoderFrame object. + * Creates a new #GstVaapiParserFrame object. * - * Returns: The newly allocated #GstVaapiDecoderFrame + * Returns: The newly allocated #GstVaapiParserFrame */ -GstVaapiDecoderFrame * -gst_vaapi_decoder_frame_new(guint width, guint height) +GstVaapiParserFrame * +gst_vaapi_parser_frame_new(guint width, guint height) { - GstVaapiDecoderFrame *frame; + GstVaapiParserFrame *frame; guint num_slices; - frame = (GstVaapiDecoderFrame *) - gst_vaapi_mini_object_new(gst_vaapi_decoder_frame_class()); + frame = (GstVaapiParserFrame *) + gst_vaapi_mini_object_new(gst_vaapi_parser_frame_class()); if (!frame) return NULL; @@ -98,13 +98,13 @@ gst_vaapi_decoder_frame_new(guint width, guint height) return frame; error: - gst_vaapi_decoder_frame_unref(frame); + gst_vaapi_parser_frame_unref(frame); return NULL; } /** - * gst_vaapi_decoder_frame_free: - * @frame: a #GstVaapiDecoderFrame + * gst_vaapi_parser_frame_free: + * @frame: a #GstVaapiParserFrame * * Deallocates any internal resources bound to the supplied decoder * @frame. @@ -113,7 +113,7 @@ error: * sub-classes. */ void -gst_vaapi_decoder_frame_free(GstVaapiDecoderFrame *frame) +gst_vaapi_parser_frame_free(GstVaapiParserFrame *frame) { free_units(&frame->units); free_units(&frame->pre_units); @@ -121,14 +121,14 @@ gst_vaapi_decoder_frame_free(GstVaapiDecoderFrame *frame) } /** - * gst_vaapi_decoder_frame_append_unit: - * @frame: a #GstVaapiDecoderFrame + * gst_vaapi_parser_frame_append_unit: + * @frame: a #GstVaapiParserFrame * @unit: a #GstVaapiDecoderUnit * * Appends unit to the @frame. */ void -gst_vaapi_decoder_frame_append_unit(GstVaapiDecoderFrame *frame, +gst_vaapi_parser_frame_append_unit(GstVaapiParserFrame *frame, GstVaapiDecoderUnit *unit) { GArray **unit_array_ptr; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h b/gst-libs/gst/vaapi/gstvaapiparser_frame.h similarity index 55% rename from gst-libs/gst/vaapi/gstvaapidecoder_frame.h rename to gst-libs/gst/vaapi/gstvaapiparser_frame.h index 84b5f6ff27..b9b0b0b476 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_frame.h +++ b/gst-libs/gst/vaapi/gstvaapiparser_frame.h @@ -1,5 +1,5 @@ /* - * gstvaapidecoder_frame.h - VA decoder frame + * gstvaapiparser_frame.h - VA parser frame * * Copyright (C) 2012-2013 Intel Corporation * @@ -19,38 +19,24 @@ * Boston, MA 02110-1301 USA */ -#ifndef GST_VAAPI_DECODER_FRAME_H -#define GST_VAAPI_DECODER_FRAME_H +#ifndef GST_VAAPI_PARSER_FRAME_H +#define GST_VAAPI_PARSER_FRAME_H #include #include G_BEGIN_DECLS -typedef struct _GstVaapiDecoderFrame GstVaapiDecoderFrame; +typedef struct _GstVaapiParserFrame GstVaapiParserFrame; -#define GST_VAAPI_DECODER_FRAME(frame) \ - ((GstVaapiDecoderFrame *)(frame)) +#define GST_VAAPI_PARSER_FRAME(frame) \ + ((GstVaapiParserFrame *)(frame)) -#define GST_VAAPI_IS_DECODER_FRAME(frame) \ - (GST_VAAPI_DECODER_FRAME(frame) != NULL) +#define GST_VAAPI_IS_PARSER_FRAME(frame) \ + (GST_VAAPI_PARSER_FRAME(frame) != NULL) /** - * GstVaapiDecoderFrameFlags: - * - * Flags for #GstVaapiDecoderFrame. - */ -typedef enum { - GST_VAAPI_DECODER_FRAME_FLAG_LAST = (1 << 0) -} GstVaapiDecoderFrameFlags; - -#define GST_VAAPI_DECODER_FRAME_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS -#define GST_VAAPI_DECODER_FRAME_FLAG_IS_SET GST_VAAPI_MINI_OBJECT_FLAG_IS_SET -#define GST_VAAPI_DECODER_FRAME_FLAG_SET GST_VAAPI_MINI_OBJECT_FLAG_SET -#define GST_VAAPI_DECODER_FRAME_FLAG_UNSET GST_VAAPI_MINI_OBJECT_FLAG_UNSET - -/** - * GstVaapiDecoderFrame: + * GstVaapiParserFrame: * @output_offset: current offset to the reconstructed #GstBuffer for * this #GstVideoCodecFrame. This is used to initialize the decoder * unit offset @@ -62,39 +48,39 @@ typedef enum { * information. Decoder frames are usually attached to codec frames as * the user_data anchor point. */ -struct _GstVaapiDecoderFrame { +struct _GstVaapiParserFrame { /*< private >*/ - GstVaapiMiniObject parent_instance; + GstVaapiMiniObject parent_instance; - guint output_offset; - GArray *units; - GArray *pre_units; - GArray *post_units; + guint output_offset; + GArray *units; + GArray *pre_units; + GArray *post_units; }; G_GNUC_INTERNAL -GstVaapiDecoderFrame * -gst_vaapi_decoder_frame_new(guint width, guint height); +GstVaapiParserFrame * +gst_vaapi_parser_frame_new(guint width, guint height); G_GNUC_INTERNAL void -gst_vaapi_decoder_frame_free(GstVaapiDecoderFrame *frame); +gst_vaapi_parser_frame_free(GstVaapiParserFrame *frame); G_GNUC_INTERNAL void -gst_vaapi_decoder_frame_append_unit(GstVaapiDecoderFrame *frame, +gst_vaapi_parser_frame_append_unit(GstVaapiParserFrame *frame, GstVaapiDecoderUnit *unit); -#define gst_vaapi_decoder_frame_ref(frame) \ +#define gst_vaapi_parser_frame_ref(frame) \ gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(frame)) -#define gst_vaapi_decoder_frame_unref(frame) \ +#define gst_vaapi_parser_frame_unref(frame) \ gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(frame)) -#define gst_vaapi_decoder_frame_replace(old_frame_p, new_frame) \ +#define gst_vaapi_parser_frame_replace(old_frame_p, new_frame) \ gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_frame_p), \ (GstVaapiMiniObject *)(new_frame)) G_END_DECLS -#endif /* GST_VAAPI_DECODER_FRAME_H */ +#endif /* GST_VAAPI_PARSER_FRAME_H */ From 2909d0229dfe144a1994247a498a4231b3772c77 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 17 Apr 2013 10:14:55 +0200 Subject: [PATCH 1158/3781] decoder: fix GstVideoCodecFrame flags for interlaced contents. Fix support for interlaced contents with GStreamer 0.10. In particular, propagate GstVaapiSurfaceProxy frame flags to GstVideoCodecFrame flags correctly. This is a regression from commit 87e5717. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 2a3dd76af3..5c548d8e21 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -762,6 +762,7 @@ gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder, out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_RFF; if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_ONEFIELD; + GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, out_flags); } #endif From 945516c9c7ef5120d643c95fbb1efc1d2f4b2311 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 17 Apr 2013 10:18:45 +0200 Subject: [PATCH 1159/3781] vaapipostproc: port to GStreamer 1.0. Add support for interlaced streams with GStreamer 1.0 too. Basically, this enables vaapipostproc, though it is not auto-plugged yet. We also make sure to reply to CAPS queries, and happily handle CAPS events. --- gst-libs/gst/vaapi/gstcompat.h | 19 +++++++- gst/vaapi/Makefile.am | 4 +- gst/vaapi/gstvaapi.c | 2 - gst/vaapi/gstvaapidecode.c | 22 +++++++-- gst/vaapi/gstvaapipluginutil.h | 39 ++++++++++++++++ gst/vaapi/gstvaapipostproc.c | 85 ++++++++++++++++++++++------------ 6 files changed, 132 insertions(+), 39 deletions(-) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index 16b3c71f58..a921fa69e4 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -58,7 +58,11 @@ gst_compat_structure_get_fourcc(const GstStructure *structure, typedef const guint8 *(*GstCompatTypeFindPeekFunction)(gpointer, gint64, guint); typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, GstCaps *); -/* GstQuery */ +/* GstPad */ +#define GST_PAD_CHAIN_FUNCTION_ARGS \ + GstPad *pad, GstObject *parent, GstBuffer *buffer +#define GST_PAD_EVENT_FUNCTION_ARGS \ + GstPad *pad, GstObject *parent, GstEvent *event #define GST_PAD_QUERY_FUNCTION_ARGS \ GstPad *pad, GstObject *parent, GstQuery *query #define GST_PAD_QUERY_FUNCTION_CALL(func, pad, parent, query) \ @@ -228,9 +232,22 @@ gst_compat_video_overlay_rectangle_get_pixels_unscaled_raw( &width, &height, &stride, flags); } +typedef enum { + GST_VIDEO_BUFFER_FLAG_TFF = GST_VIDEO_BUFFER_TFF, + GST_VIDEO_BUFFER_FLAG_RFF = GST_VIDEO_BUFFER_RFF, + GST_VIDEO_BUFFER_FLAG_ONEFIELD = GST_VIDEO_BUFFER_ONEFIELD +} GstVideoBufferFlags; + /* GstPad */ #undef GST_FLOW_EOS #define GST_FLOW_EOS GST_FLOW_UNEXPECTED +#undef GST_FLOW_FLUSHING +#define GST_FLOW_FLUSHING GST_FLOW_WRONG_STATE + +#define GST_PAD_CHAIN_FUNCTION_ARGS \ + GstPad *pad, GstBuffer *buffer +#define GST_PAD_EVENT_FUNCTION_ARGS \ + GstPad *pad, GstEvent *event /* GstElement */ #undef gst_element_class_set_static_metadata diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index d73bbadc33..bd9dedd4d8 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -33,6 +33,7 @@ libgstvaapi_source_c = \ gstvaapi.c \ gstvaapidecode.c \ gstvaapipluginutil.c \ + gstvaapipostproc.c \ gstvaapisink.c \ gstvaapiuploader.c \ gstvaapivideobuffer.c \ @@ -42,6 +43,7 @@ libgstvaapi_source_c = \ libgstvaapi_source_h = \ gstvaapidecode.h \ gstvaapipluginutil.h \ + gstvaapipostproc.h \ gstvaapisink.h \ gstvaapiuploader.h \ gstvaapivideobuffer.h \ @@ -74,13 +76,11 @@ endif if USE_GST_API_0_10 libgstvaapi_0_10_source_c = \ gstvaapidownload.c \ - gstvaapipostproc.c \ gstvaapiupload.c \ $(NULL) libgstvaapi_0_10_source_h = \ gstvaapidownload.h \ - gstvaapipostproc.h \ gstvaapiupload.h \ $(NULL) endif diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 600632d60f..3000b2296f 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -47,11 +47,9 @@ plugin_init (GstPlugin *plugin) gst_element_register(plugin, "vaapidecode", GST_RANK_PRIMARY, GST_TYPE_VAAPIDECODE); -#if !GST_CHECK_VERSION(1,0,0) gst_element_register(plugin, "vaapipostproc", GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); -#endif gst_element_register(plugin, "vaapisink", GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f0e5654a0f..cd773f7502 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -188,10 +188,11 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, "pixel-aspect-ratio", GST_TYPE_FRACTION, vi->par_n, vi->par_d, NULL); - if (GST_VIDEO_INFO_IS_INTERLACED(vi)) - gst_caps_set_simple(state->caps, "interlaced", G_TYPE_BOOLEAN, - TRUE, NULL); - + if (GST_VIDEO_INFO_IS_INTERLACED(vi)) { + GstStructure * const structure = + gst_caps_get_structure(state->caps, 0); + gst_structure_set_interlaced(structure, TRUE); + } gst_caps_replace(&decode->srcpad_caps, state->caps); return TRUE; } @@ -274,6 +275,7 @@ gst_vaapidecode_push_decoded_frames(GstVideoDecoder *vdec) GstVaapiVideoMeta *meta; GstVideoCodecFrame *out_frame; GstFlowReturn ret; + guint flags; /* Output all decoded frames */ for (;;) { @@ -296,6 +298,18 @@ gst_vaapidecode_push_decoded_frames(GstVideoDecoder *vdec) if (!meta) goto error_get_meta; gst_vaapi_video_meta_set_surface_proxy(meta, proxy); + + flags = gst_vaapi_surface_proxy_get_flags(proxy); + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED) { + guint out_flags = GST_VIDEO_BUFFER_FLAG_INTERLACED; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF) + out_flags |= GST_VIDEO_BUFFER_FLAG_TFF; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF) + out_flags |= GST_VIDEO_BUFFER_FLAG_RFF; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) + out_flags |= GST_VIDEO_BUFFER_FLAG_ONEFIELD; + GST_BUFFER_FLAG_SET(out_frame->output_buffer, out_flags); + } #else out_frame->output_buffer = gst_vaapi_video_buffer_new_with_surface_proxy(proxy); diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 8cb70d17dd..6212a9d648 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -61,4 +61,43 @@ gst_vaapi_apply_composition(GstVaapiSurface *surface, GstBuffer *buffer); } while (0) #endif +/* Helpers to handle interlaced contents */ +#if GST_CHECK_VERSION(1,0,0) +# define GST_CAPS_INTERLACED_MODES \ + "interlace-mode = (string){ progressive, interleaved }" +# define GST_CAPS_INTERLACED_FALSE \ + "interlace-mode = (string)progressive" + +static inline void +gst_structure_remove_interlaced_field(GstStructure *structure) +{ + gst_structure_remove_field(structure, "interlace-mode"); +} + +static inline void +gst_structure_set_interlaced(GstStructure *structure, gboolean interlaced) +{ + gst_structure_set(structure, "interlace-mode", + G_TYPE_STRING, interlaced ? "interleaved" : "progressive", NULL); +} +#else +# define GST_CAPS_INTERLACED_MODES \ + "interlaced = (boolean){ true, false }" +# define GST_CAPS_INTERLACED_FALSE \ + "interlaced = (boolean)false" + +static inline void +gst_structure_remove_interlaced_field(GstStructure *structure) +{ + gst_structure_remove_field(structure, "interlaced"); +} + +static inline void +gst_structure_set_interlaced(GstStructure *structure, gboolean interlaced) +{ + gst_structure_set(structure, "interlaced", + G_TYPE_BOOLEAN, interlaced, NULL); +} +#endif + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 534017e693..28a9cc3574 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -45,11 +45,11 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapipostproc); /* Default templates */ static const char gst_vaapipostproc_sink_caps_str[] = GST_VAAPI_SURFACE_CAPS ", " - "interlaced = (boolean) { true, false }"; + GST_CAPS_INTERLACED_MODES; static const char gst_vaapipostproc_src_caps_str[] = GST_VAAPI_SURFACE_CAPS ", " - "interlaced = (boolean) false"; + GST_CAPS_INTERLACED_FALSE; static GstStaticPadTemplate gst_vaapipostproc_sink_factory = GST_STATIC_PAD_TEMPLATE( @@ -66,6 +66,7 @@ static GstStaticPadTemplate gst_vaapipostproc_src_factory = GST_STATIC_CAPS(gst_vaapipostproc_src_caps_str)); /* GstImplementsInterface interface */ +#if !GST_CHECK_VERSION(1,0,0) static gboolean gst_vaapipostproc_implements_interface_supported( GstImplementsInterface *iface, @@ -80,6 +81,7 @@ gst_vaapipostproc_implements_iface_init(GstImplementsInterfaceClass *iface) { iface->supported = gst_vaapipostproc_implements_interface_supported; } +#endif /* GstVideoContext interface */ static void @@ -105,8 +107,10 @@ G_DEFINE_TYPE_WITH_CODE( GstVaapiPostproc, gst_vaapipostproc, GST_TYPE_ELEMENT, +#if !GST_CHECK_VERSION(1,0,0) G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapipostproc_implements_iface_init); +#endif G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init)) @@ -263,7 +267,7 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) timestamp = GST_BUFFER_TIMESTAMP(buf); proxy = gst_vaapi_video_meta_get_surface_proxy(meta); - tff = GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_TFF); + tff = GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_FLAG_TFF); flags &= ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); @@ -284,7 +288,9 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) GST_BUFFER_TIMESTAMP(outbuf) = timestamp; GST_BUFFER_DURATION(outbuf) = postproc->field_duration; +#if !GST_CHECK_VERSION(1,0,0) gst_buffer_set_caps(outbuf, postproc->srcpad_caps); +#endif ret = gst_pad_push(postproc->srcpad, outbuf); if (ret != GST_FLOW_OK) goto error_push_buffer; @@ -305,7 +311,9 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration; GST_BUFFER_DURATION(outbuf) = postproc->field_duration; +#if !GST_CHECK_VERSION(1,0,0) gst_buffer_set_caps(outbuf, postproc->srcpad_caps); +#endif ret = gst_pad_push(postproc->srcpad, outbuf); if (ret != GST_FLOW_OK) goto error_push_buffer; @@ -318,39 +326,36 @@ error_invalid_buffer: { GST_ERROR("failed to receive a valid video buffer"); gst_buffer_unref(buf); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } error_create_buffer: { GST_ERROR("failed to create output buffer"); gst_buffer_unref(buf); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } error_push_buffer: { - if (ret != GST_FLOW_WRONG_STATE) + if (ret != GST_FLOW_FLUSHING) GST_ERROR("failed to push output buffer to video sink"); gst_buffer_unref(buf); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } } static gboolean gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps) { - gint fps_n, fps_d; - gboolean interlaced; + GstVideoInfo vi; - if (!gst_video_parse_caps_framerate(caps, &fps_n, &fps_d)) + if (!gst_video_info_from_caps(&vi, caps)) return FALSE; - postproc->fps_n = fps_n; - postproc->fps_d = fps_d; + postproc->fps_n = GST_VIDEO_INFO_FPS_N(&vi); + postproc->fps_d = GST_VIDEO_INFO_FPS_D(&vi); switch (postproc->deinterlace_mode) { case GST_VAAPI_DEINTERLACE_MODE_AUTO: - if (!gst_video_format_parse_caps_interlaced(caps, &interlaced)) - return FALSE; - postproc->deinterlace = interlaced; + postproc->deinterlace = GST_VIDEO_INFO_IS_INTERLACED(&vi); break; case GST_VAAPI_DEINTERLACE_MODE_INTERLACED: postproc->deinterlace = TRUE; @@ -403,7 +408,7 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps) gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_GLX, NULL); if (!postproc->deinterlace) - gst_structure_remove_field(structure, "interlaced"); + gst_structure_remove_interlaced_field(structure); else { /* Set double framerate in interlaced mode */ if (!gst_util_fraction_multiply(postproc->fps_n, postproc->fps_d, @@ -411,12 +416,9 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps) &fps_n, &fps_d)) return FALSE; - gst_structure_set( - structure, - "interlaced", G_TYPE_BOOLEAN, FALSE, - "framerate", GST_TYPE_FRACTION, fps_n, fps_d, - NULL - ); + gst_structure_set(structure, "framerate", + GST_TYPE_FRACTION, fps_n, fps_d, NULL); + gst_structure_set_interlaced(structure, FALSE); } return gst_pad_set_caps(postproc->srcpad, src_caps); } @@ -473,32 +475,44 @@ gst_vaapipostproc_set_caps(GstPad *pad, GstCaps *caps) } static GstFlowReturn -gst_vaapipostproc_chain(GstPad *pad, GstBuffer *buf) +gst_vaapipostproc_chain(GST_PAD_CHAIN_FUNCTION_ARGS) { GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); GstFlowReturn ret; - ret = gst_vaapipostproc_process(postproc, buf); + ret = gst_vaapipostproc_process(postproc, buffer); gst_object_unref(postproc); return ret; } static gboolean -gst_vaapipostproc_sink_event(GstPad *pad, GstEvent *event) +gst_vaapipostproc_sink_event(GST_PAD_EVENT_FUNCTION_ARGS) { GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); gboolean success; GST_DEBUG("handle sink event '%s'", GST_EVENT_TYPE_NAME(event)); - /* Propagate event downstream */ - success = gst_pad_push_event(postproc->srcpad, event); + switch (GST_EVENT_TYPE(event)) { +#if GST_CHECK_VERSION(1,0,0) + case GST_EVENT_CAPS: { + GstCaps *caps; + gst_event_parse_caps(event, &caps); + success = gst_vaapipostproc_set_caps(pad, caps); + break; + } +#endif + default: + /* Propagate event downstream */ + success = gst_pad_push_event(postproc->srcpad, event); + break; + } gst_object_unref(postproc); return success; } static gboolean -gst_vaapipostproc_src_event(GstPad *pad, GstEvent *event) +gst_vaapipostproc_src_event(GST_PAD_EVENT_FUNCTION_ARGS) { GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); gboolean success; @@ -512,7 +526,7 @@ gst_vaapipostproc_src_event(GstPad *pad, GstEvent *event) } static gboolean -gst_vaapipostproc_query(GstPad *pad, GstQuery *query) +gst_vaapipostproc_query(GST_PAD_QUERY_FUNCTION_ARGS) { GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); gboolean success; @@ -521,8 +535,17 @@ gst_vaapipostproc_query(GstPad *pad, GstQuery *query) if (gst_vaapi_reply_to_query(query, postproc->display)) success = TRUE; +#if GST_CHECK_VERSION(1,0,0) + else if (GST_PAD_IS_SINK(pad) && GST_QUERY_TYPE(query) == GST_QUERY_CAPS) { + GstCaps * const caps = gst_vaapipostproc_get_caps(pad); + gst_query_set_caps_result(query, caps); + gst_caps_unref(caps); + success = TRUE; + } +#endif else - success = gst_pad_query_default(pad, query); + success = GST_PAD_QUERY_FUNCTION_CALL(gst_pad_query_default, pad, + parent, query); gst_object_unref(postproc); return success; @@ -714,8 +737,10 @@ gst_vaapipostproc_init(GstVaapiPostproc *postproc) ); postproc->sinkpad_caps = NULL; +#if !GST_CHECK_VERSION(1,0,0) gst_pad_set_getcaps_function(postproc->sinkpad, gst_vaapipostproc_get_caps); gst_pad_set_setcaps_function(postproc->sinkpad, gst_vaapipostproc_set_caps); +#endif gst_pad_set_chain_function(postproc->sinkpad, gst_vaapipostproc_chain); gst_pad_set_event_function(postproc->sinkpad, gst_vaapipostproc_sink_event); gst_pad_set_query_function(postproc->sinkpad, gst_vaapipostproc_query); From 6b259abc02d7243b3c64e1de074af48f92757151 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 17 Apr 2013 10:53:03 +0200 Subject: [PATCH 1160/3781] vaapipostproc: fix reference counting buf for passthrough mode. Fix reference counting bug for passthrough mode, whereby the input buffer was propagated as is downstream through gst_pad_push() without increasing its reference count before. The was a problem when gst_pad_push() returns an error and we further decrease the reference count of the input buffer. --- gst/vaapi/gstvaapipostproc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 28a9cc3574..5f1df4c323 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -258,10 +258,13 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) /* Deinterlacing disabled, push frame */ if (!postproc->deinterlace) { - gst_vaapi_video_meta_set_render_flags(meta, flags); - ret = gst_pad_push(postproc->srcpad, buf); + outbuf = gst_buffer_ref(buf); + if (!outbuf) + goto error_create_buffer; + ret = gst_pad_push(postproc->srcpad, outbuf); if (ret != GST_FLOW_OK) goto error_push_buffer; + gst_buffer_unref(buf); return GST_FLOW_OK; } From a0e587667a0977a4d649b3830bce1bdf488d8763 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 17 Apr 2013 10:58:04 +0200 Subject: [PATCH 1161/3781] vaapipostproc: minor clean-ups. Use g_clear_object() wherever appropriate and remove dead-code. --- gst/vaapi/gstvaapipostproc.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 5f1df4c323..7663b5bd1d 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -232,10 +232,7 @@ gst_vaapipostproc_start(GstVaapiPostproc *postproc) static gboolean gst_vaapipostproc_stop(GstVaapiPostproc *postproc) { - if (postproc->display) { - g_object_unref(postproc->display); - postproc->display = NULL; - } + g_clear_object(&postproc->display); return TRUE; } @@ -246,7 +243,7 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) GstVaapiSurfaceProxy *proxy; GstClockTime timestamp; GstFlowReturn ret; - GstBuffer *outbuf = NULL; + GstBuffer *outbuf; guint outbuf_flags, flags; gboolean tff; @@ -254,8 +251,6 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) if (!meta) goto error_invalid_buffer; - flags = gst_vaapi_video_meta_get_render_flags(meta); - /* Deinterlacing disabled, push frame */ if (!postproc->deinterlace) { outbuf = gst_buffer_ref(buf); @@ -272,8 +267,9 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) proxy = gst_vaapi_video_meta_get_surface_proxy(meta); tff = GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_FLAG_TFF); - flags &= ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); + flags = gst_vaapi_video_meta_get_render_flags(meta) & + ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); /* First field */ outbuf = gst_vaapi_video_buffer_new_with_surface_proxy(proxy); From cb076da7e10178fa42900d72c7bba79bc02031a0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 17 Apr 2013 13:17:26 +0200 Subject: [PATCH 1162/3781] debian: fix build of GStreamer 0.10 packages. Fix build of Debian packages to scan the actual GStreamer API version from the generated changelog file. --- debian.upstream/rules | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/debian.upstream/rules b/debian.upstream/rules index 0ec96be6ec..75787a9474 100755 --- a/debian.upstream/rules +++ b/debian.upstream/rules @@ -5,7 +5,8 @@ include /usr/share/cdbs/1/class/autotools.mk include /usr/share/cdbs/1/rules/simple-patchsys.mk include /usr/share/cdbs/1/rules/utils.mk -gst_pkgname = $(shell dpkg-parsechangelog | grep ^Source: | cut -d' ' -f2) +GST_API_VERSION = $(shell echo "$(DEB_SOURCE_PACKAGE)" | \ + sed -n '/gstreamer\([0-9][0-9.]*\)-vaapi/s//\1/p') # Allow SMP build ifeq ($(DEBIAN_BUILD_NCPUS),) @@ -18,7 +19,8 @@ MAKE += $(EXTRA_MAKE_FLAGS) # Allow HTML documentation build indep_conf_flags = \ - --with-html-dir=\$${prefix}/share/doc/$(gst_pkgname) + --with-html-dir=\$${prefix}/share/doc/$(DEB_SOURCE_PACKAGE) \ + --with-gstreamer-api=$(GST_API_VERSION) # only build the docs if gtk-doc-tools is installed, i.e. binary-indep is # called From 0db41333476c4f10d9b4c7451858524675178c0d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 17 Apr 2013 14:21:16 +0200 Subject: [PATCH 1163/3781] docs: drop obsolete plug-ins. Drop documentation for obsolete plug-ins, even for GStreamer 0.10. i.e. vaapiupload and vaapidownload are no longer the recommended plug-ins to use. --- docs/reference/plugins/plugins-docs.xml.in | 2 -- docs/reference/plugins/plugins-sections.txt | 28 --------------------- docs/reference/plugins/plugins.types | 2 -- 3 files changed, 32 deletions(-) diff --git a/docs/reference/plugins/plugins-docs.xml.in b/docs/reference/plugins/plugins-docs.xml.in index a12206f318..ee1a53ab35 100644 --- a/docs/reference/plugins/plugins-docs.xml.in +++ b/docs/reference/plugins/plugins-docs.xml.in @@ -13,8 +13,6 @@ gst-plugins-vaapi Plugins - - diff --git a/docs/reference/plugins/plugins-sections.txt b/docs/reference/plugins/plugins-sections.txt index 58f3fe8107..110c90a62c 100644 --- a/docs/reference/plugins/plugins-sections.txt +++ b/docs/reference/plugins/plugins-sections.txt @@ -39,31 +39,3 @@ GST_VAAPIPOSTPROC_CLASS GST_IS_VAAPIPOSTPROC_CLASS GST_VAAPIPOSTPROC_GET_CLASS
- -
-gstvaapiupload -GstVaapiUpload -GstVaapiUpload - -GST_VAAPIUPLOAD -GST_IS_VAAPIUPLOAD -GST_TYPE_VAAPIUPLOAD -gst_vaapiupload_get_type -GST_VAAPIUPLOAD_CLASS -GST_IS_VAAPIUPLOAD_CLASS -GST_VAAPIUPLOAD_GET_CLASS -
- -
-gstvaapidownload -GstVaapiDownload -GstVaapiDownload - -GST_VAAPIDOWNLOAD -GST_IS_VAAPIDOWNLOAD -GST_TYPE_VAAPIDOWNLOAD -gst_vaapidownload_get_type -GST_VAAPIDOWNLOAD_CLASS -GST_IS_VAAPIDOWNLOAD_CLASS -GST_VAAPIDOWNLOAD_GET_CLASS -
diff --git a/docs/reference/plugins/plugins.types b/docs/reference/plugins/plugins.types index 41175802af..183cdd3ea3 100644 --- a/docs/reference/plugins/plugins.types +++ b/docs/reference/plugins/plugins.types @@ -1,5 +1,3 @@ gst_vaapidecode_get_type -gst_vaapidownload_get_type gst_vaapipostproc_get_type gst_vaapisink_get_type -gst_vaapiupload_get_type From 9d8bac313febefdd6006135d54df43664b7d5076 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 18 Apr 2013 10:06:15 +0200 Subject: [PATCH 1164/3781] plugins: use gst_object_unref() wherever applicable. Use gst_object_unref() wherever applicable, e.g. objects derived from GstElement, GstVideoPool, etc. --- gst/vaapi/gstvaapidecode.c | 4 ++-- gst/vaapi/gstvaapidownload.c | 2 +- gst/vaapi/gstvaapisink.c | 2 +- gst/vaapi/gstvaapiupload.c | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index cd773f7502..ccb54924dd 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -453,7 +453,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) else gst_query_add_allocation_pool(query, pool, size, min, max); if (pool) - g_object_unref(pool); + gst_object_unref(pool); return TRUE; /* ERRORS */ @@ -816,7 +816,7 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) res = GST_PAD_QUERY_FUNCTION_CALL(decode->srcpad_query, decode->srcpad, parent, query); - g_object_unref(decode); + gst_object_unref(decode); return res; } diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index a122258599..1a5f090f19 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -592,7 +592,7 @@ gst_vaapidownload_query(GstPad *pad, GstQuery *query) else res = gst_pad_query_default(pad, query); - g_object_unref(download); + gst_object_unref(download); return res; } diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 35313dd2ff..4c8d46d912 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -654,7 +654,7 @@ error_create_pool: error_pool_config: { GST_ERROR("failed to reset buffer pool config"); - g_object_unref(pool); + gst_object_unref(pool); return FALSE; } #else diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 50c8c9ff6b..aa22057fa9 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -233,12 +233,12 @@ gst_vaapiupload_init(GstVaapiUpload *upload) gst_vaapiupload_sinkpad_buffer_alloc ); gst_pad_set_query_function(sinkpad, gst_vaapiupload_query); - g_object_unref(sinkpad); + gst_object_unref(sinkpad); /* Override query on src pad */ srcpad = gst_element_get_static_pad(GST_ELEMENT(upload), "src"); gst_pad_set_query_function(srcpad, gst_vaapiupload_query); - g_object_unref(srcpad); + gst_object_unref(srcpad); } static inline gboolean @@ -425,7 +425,7 @@ gst_vaapiupload_sinkpad_buffer_alloc( return GST_FLOW_UNEXPECTED; ret = gst_vaapiupload_buffer_alloc(trans, size, caps, pbuf); - g_object_unref(trans); + gst_object_unref(trans); return ret; } @@ -471,6 +471,6 @@ gst_vaapiupload_query(GstPad *pad, GstQuery *query) else res = gst_pad_query_default (pad, query); - g_object_unref (upload); + gst_object_unref (upload); return res; } From 851cc000c25b02db491492a7903d8082d8b39ea4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 18 Apr 2013 15:50:02 +0200 Subject: [PATCH 1165/3781] vaapidecode: rework GstVideoDecoder::handle_frame() with a task. Rework GstVideoDecoder::handle_frame() to decode the current frame, while possibly waiting for a free surface, and separately submit all decoded frames from a task. This makes it possible to pop and render decoded frames as soon as possible. --- gst-libs/gst/vaapi/gstcompat.h | 13 ++++ gst/vaapi/gstvaapidecode.c | 133 +++++++++++++++++++-------------- 2 files changed, 88 insertions(+), 58 deletions(-) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index a921fa69e4..4407648142 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -249,6 +249,19 @@ typedef enum { #define GST_PAD_EVENT_FUNCTION_ARGS \ GstPad *pad, GstEvent *event +static inline gboolean +gst_compat_pad_start_task(GstPad *pad, GstTaskFunction func, gpointer user_data, + GDestroyNotify notify) +{ + g_return_val_if_fail(notify == NULL, FALSE); + + return gst_pad_start_task(pad, func, user_data); +} + +#undef gst_pad_start_task +#define gst_pad_start_task(pad, func, user_data, notify) \ + gst_compat_pad_start_task(pad, func, user_data, notify) + /* GstElement */ #undef gst_element_class_set_static_metadata #define gst_element_class_set_static_metadata(klass, name, path, desc, author) \ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ccb54924dd..cb261a76f1 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -224,6 +224,7 @@ gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) status = gst_vaapi_decoder_decode(decode->decoder, frame); if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { gboolean was_signalled; + GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); g_mutex_lock(&decode->decoder_mutex); was_signalled = g_cond_wait_until( &decode->decoder_ready, @@ -231,6 +232,7 @@ gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) end_time ); g_mutex_unlock(&decode->decoder_mutex); + GST_VIDEO_DECODER_STREAM_LOCK(vdec); if (was_signalled) continue; goto error_decode_timeout; @@ -267,7 +269,7 @@ error_decode: } static GstFlowReturn -gst_vaapidecode_push_decoded_frames(GstVideoDecoder *vdec) +gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstVaapiSurfaceProxy *proxy; @@ -277,55 +279,52 @@ gst_vaapidecode_push_decoded_frames(GstVideoDecoder *vdec) GstFlowReturn ret; guint flags; - /* Output all decoded frames */ - for (;;) { - status = gst_vaapi_decoder_get_frame(decode->decoder, &out_frame); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return GST_FLOW_OK; + status = gst_vaapi_decoder_get_frame(decode->decoder, &out_frame); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return GST_VIDEO_DECODER_FLOW_NEED_DATA; - if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(out_frame)) { - proxy = gst_video_codec_frame_get_user_data(out_frame); + if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(out_frame)) { + proxy = gst_video_codec_frame_get_user_data(out_frame); - gst_vaapi_surface_proxy_set_destroy_notify(proxy, - (GDestroyNotify)gst_vaapidecode_release, decode); + gst_vaapi_surface_proxy_set_destroy_notify(proxy, + (GDestroyNotify)gst_vaapidecode_release, decode); #if GST_CHECK_VERSION(1,0,0) - ret = gst_video_decoder_allocate_output_frame(vdec, out_frame); - if (ret != GST_FLOW_OK) - goto error_create_buffer; - - meta = gst_buffer_get_vaapi_video_meta(out_frame->output_buffer); - if (!meta) - goto error_get_meta; - gst_vaapi_video_meta_set_surface_proxy(meta, proxy); - - flags = gst_vaapi_surface_proxy_get_flags(proxy); - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED) { - guint out_flags = GST_VIDEO_BUFFER_FLAG_INTERLACED; - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF) - out_flags |= GST_VIDEO_BUFFER_FLAG_TFF; - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF) - out_flags |= GST_VIDEO_BUFFER_FLAG_RFF; - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) - out_flags |= GST_VIDEO_BUFFER_FLAG_ONEFIELD; - GST_BUFFER_FLAG_SET(out_frame->output_buffer, out_flags); - } -#else - out_frame->output_buffer = - gst_vaapi_video_buffer_new_with_surface_proxy(proxy); - if (!out_frame->output_buffer) - goto error_create_buffer; -#endif - } - - ret = gst_video_decoder_finish_frame(vdec, out_frame); + ret = gst_video_decoder_allocate_output_frame(vdec, out_frame); if (ret != GST_FLOW_OK) - goto error_commit_buffer; + goto error_create_buffer; - if (GST_CLOCK_TIME_IS_VALID(out_frame->pts)) - decode->last_buffer_time = out_frame->pts; - gst_video_codec_frame_unref(out_frame); - }; + meta = gst_buffer_get_vaapi_video_meta(out_frame->output_buffer); + if (!meta) + goto error_get_meta; + gst_vaapi_video_meta_set_surface_proxy(meta, proxy); + + flags = gst_vaapi_surface_proxy_get_flags(proxy); + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED) { + guint out_flags = GST_VIDEO_BUFFER_FLAG_INTERLACED; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF) + out_flags |= GST_VIDEO_BUFFER_FLAG_TFF; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF) + out_flags |= GST_VIDEO_BUFFER_FLAG_RFF; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) + out_flags |= GST_VIDEO_BUFFER_FLAG_ONEFIELD; + GST_BUFFER_FLAG_SET(out_frame->output_buffer, out_flags); + } +#else + out_frame->output_buffer = + gst_vaapi_video_buffer_new_with_surface_proxy(proxy); + if (!out_frame->output_buffer) + goto error_create_buffer; +#endif + } + + ret = gst_video_decoder_finish_frame(vdec, out_frame); + if (ret != GST_FLOW_OK) + goto error_commit_buffer; + + if (GST_CLOCK_TIME_IS_VALID(out_frame->pts)) + decode->last_buffer_time = out_frame->pts; + gst_video_codec_frame_unref(out_frame); return GST_FLOW_OK; /* ERRORS */ @@ -363,18 +362,26 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) { GstFlowReturn ret; - /* Purge all pending frames we might have already. This helps - release VA surfaces as early as possible for _decode_frame() */ - ret = gst_vaapidecode_push_decoded_frames(vdec); - if (ret != GST_FLOW_OK) - return ret; - + /* Make sure to release the base class stream lock so that decode + loop can call gst_video_decoder_finish_frame() without blocking */ + GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); ret = gst_vaapidecode_decode_frame(vdec, frame); - if (ret != GST_FLOW_OK) - return ret; + GST_VIDEO_DECODER_STREAM_LOCK(vdec); + return ret; +} - /* Purge any pending frame thay may have been decoded already */ - return gst_vaapidecode_push_decoded_frames(vdec); +static void +gst_vaapidecode_decode_loop(GstVaapiDecode *decode) +{ + GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); + GstFlowReturn ret; + + ret = gst_vaapidecode_push_decoded_frame(vdec); + if (ret == GST_FLOW_OK || ret == GST_VIDEO_DECODER_FLOW_NEED_DATA) + return; + + /* ERRORS */ + gst_pad_pause_task(decode->srcpad); } static GstFlowReturn @@ -386,7 +393,17 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) status = gst_vaapi_decoder_flush(decode->decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto error_flush; - return gst_vaapidecode_push_decoded_frames(vdec); + + /* Make sure the decode loop function has a chance to return, thus + possibly unlocking gst_video_decoder_finish_frame() */ + GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); + gst_pad_stop_task(decode->srcpad); + GST_VIDEO_DECODER_STREAM_LOCK(vdec); + + /* Submit all frames that got decoded so far */ + while (gst_vaapidecode_push_decoded_frame(vdec) == GST_FLOW_OK) + ; + return GST_FLOW_OK; /* ERRORS */ error_flush: @@ -527,12 +544,14 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) ); decode->decoder_caps = gst_caps_ref(caps); - return TRUE; + return gst_pad_start_task(decode->srcpad, + (GstTaskFunction)gst_vaapidecode_decode_loop, decode, NULL); } static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { + gst_pad_stop_task(decode->srcpad); g_clear_object(&decode->decoder); gst_caps_replace(&decode->decoder_caps, NULL); gst_vaapidecode_release(decode); @@ -567,8 +586,6 @@ gst_vaapidecode_finalize(GObject *object) { GstVaapiDecode * const decode = GST_VAAPIDECODE(object); - gst_vaapidecode_destroy(decode); - gst_caps_replace(&decode->sinkpad_caps, NULL); gst_caps_replace(&decode->srcpad_caps, NULL); gst_caps_replace(&decode->allowed_caps, NULL); From d2bf4ffd979d4e66e79a86629ef12955c25e89f7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 18 Apr 2013 15:55:26 +0200 Subject: [PATCH 1166/3781] vaapidecode: rework heuristics to detect decode timeout. Rework heuristics to detect when downstream element ran into errors, and thus failing to release any VA surface in due time for the current frame to get decoded. In particular, recalibrate the render time base when the first frame gets submitted downstream, or when there is no timestamp that could be inferred. --- gst/vaapi/gstvaapidecode.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index cb261a76f1..292a8da39b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -213,9 +213,10 @@ gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) GstFlowReturn ret; gint64 end_time; - if (!decode->render_time_base) - decode->render_time_base = g_get_monotonic_time(); - end_time = decode->render_time_base; + if (decode->render_time_base) + end_time = decode->render_time_base; + else + end_time = g_get_monotonic_time(); end_time += GST_TIME_AS_USECONDS(decode->last_buffer_time); end_time += G_TIME_SPAN_SECOND; @@ -322,8 +323,22 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec) if (ret != GST_FLOW_OK) goto error_commit_buffer; - if (GST_CLOCK_TIME_IS_VALID(out_frame->pts)) + /* Estimate when this frame would no longer be needed for rendering */ + if (GST_CLOCK_TIME_IS_VALID(out_frame->pts)) { + if (!decode->render_time_base) + decode->render_time_base = g_get_monotonic_time() - + GST_TIME_AS_USECONDS(out_frame->pts); decode->last_buffer_time = out_frame->pts; + if (GST_CLOCK_TIME_IS_VALID(out_frame->duration)) + decode->last_buffer_time += out_frame->duration; + else + decode->last_buffer_time += GST_SECOND; + } + else { + decode->render_time_base = 0; + decode->last_buffer_time = 0; + } + gst_video_codec_frame_unref(out_frame); return GST_FLOW_OK; @@ -351,7 +366,8 @@ error_get_meta: #endif error_commit_buffer: { - GST_DEBUG("video sink rejected the video buffer (error %d)", ret); + if (ret != GST_FLOW_FLUSHING) + GST_ERROR("video sink rejected the video buffer (error %d)", ret); gst_video_codec_frame_unref(out_frame); return GST_FLOW_EOS; } From 46b77ea4da14c34a463db71800a7cab5e511952f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 18 Apr 2013 19:08:39 +0200 Subject: [PATCH 1167/3781] NEWS: updates. --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 3778e3496d..d49325dac0 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,10 @@ Copyright (C) 2011 Collabora Version 0.5.3 - DD.Apr.2013 * Add support for GStreamer 1.0.x API (+Sreerenj Balachandran) +* Fix build on Fedora 17 (Víctor Manuel Jáquez) +* Fix vaapidecode heuristics to detect decode timeouts * Fix fallback to sofware decoding if no hardware decoder is available +* Fix regression in raw decoding mode whereby PTS or picture flags were lost Version 0.5.2 - 28.Mar.2013 * Add support for video seek/reset (+Sreerenj Balachandran) From af9202b2538791d509597957565c3e05317ad47d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 18 Apr 2013 19:09:45 +0200 Subject: [PATCH 1168/3781] 0.5.3. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index d49325dac0..a5aa8c3ab4 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2013-04-DD +gst-vaapi NEWS -- summary of changes. 2013-04-18 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora -Version 0.5.3 - DD.Apr.2013 +Version 0.5.3 - 18.Apr.2013 * Add support for GStreamer 1.0.x API (+Sreerenj Balachandran) * Fix build on Fedora 17 (Víctor Manuel Jáquez) * Fix vaapidecode heuristics to detect decode timeouts diff --git a/configure.ac b/configure.ac index a91a459925..85c4e58506 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [3]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 4b91e31a76d25a282760a46a48355692cfb32b53 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 19 Apr 2013 14:38:59 +0200 Subject: [PATCH 1169/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 85c4e58506..9e6109dd18 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [3]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [4]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From c43a2d497a78a0e168ee11d2172ff6f8a426913b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 25 Apr 2013 13:56:18 +0200 Subject: [PATCH 1170/3781] decoder: add gst_vaapi_decoder_get_frame_with_timeout(). Add gst_vaapi_decoder_get_frame_with_timeout() helper function that will wait for a frame to be decoded, until the specified timeout in microseconds, prior to returning to the caller. This is a fix to performance regression from 851cc0, whereby the vaapidecode loop executed on the srcpad task was called to often, thus starving all CPU resources. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapidecoder.c | 69 +++++++++++++++-------- gst-libs/gst/vaapi/gstvaapidecoder.h | 4 ++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 4 +- gst/vaapi/gstvaapidecode.c | 3 +- 5 files changed, 55 insertions(+), 26 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 5f37cf6474..e9e52761b1 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -426,6 +426,7 @@ gst_vaapi_decoder_get_codec_state gst_vaapi_decoder_put_buffer gst_vaapi_decoder_get_surface gst_vaapi_decoder_get_frame +gst_vaapi_decoder_get_frame_with_timeout gst_vaapi_decoder_parse gst_vaapi_decoder_decode diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 5c548d8e21..9df3554e4d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -115,7 +115,7 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) GST_DEBUG("queue encoded data buffer %p (%d bytes)", buffer, gst_buffer_get_size(buffer)); - g_queue_push_tail(priv->buffers, buffer); + g_async_queue_push(priv->buffers, buffer); return TRUE; } @@ -125,7 +125,7 @@ pop_buffer(GstVaapiDecoder *decoder) GstVaapiDecoderPrivate * const priv = decoder->priv; GstBuffer *buffer; - buffer = g_queue_pop_head(priv->buffers); + buffer = g_async_queue_try_pop(priv->buffers); if (!buffer) return NULL; @@ -381,7 +381,7 @@ drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) GST_VIDEO_CODEC_FRAME_FLAG_SET(frame, GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); - g_queue_push_tail(priv->frames, gst_video_codec_frame_ref(frame)); + g_async_queue_push(priv->frames, gst_video_codec_frame_ref(frame)); } static inline void @@ -393,17 +393,20 @@ push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy))); - g_queue_push_tail(priv->frames, gst_video_codec_frame_ref(frame)); + g_async_queue_push(priv->frames, gst_video_codec_frame_ref(frame)); } static inline GstVideoCodecFrame * -pop_frame(GstVaapiDecoder *decoder) +pop_frame(GstVaapiDecoder *decoder, guint64 timeout) { GstVaapiDecoderPrivate * const priv = decoder->priv; GstVideoCodecFrame *frame; GstVaapiSurfaceProxy *proxy; - frame = g_queue_pop_head(priv->frames); + if (G_LIKELY(timeout > 0)) + frame = g_async_queue_timeout_pop(priv->frames, timeout); + else + frame = g_async_queue_try_pop(priv->frames); if (!frame) return NULL; @@ -448,13 +451,6 @@ get_caps(GstVaapiDecoder *decoder) return GST_VAAPI_DECODER_CODEC_STATE(decoder)->caps; } -static void -clear_queue(GQueue *q, GDestroyNotify destroy) -{ - while (!g_queue_is_empty(q)) - destroy(g_queue_pop_head(q)); -} - static void gst_vaapi_decoder_finalize(GObject *object) { @@ -467,15 +463,12 @@ gst_vaapi_decoder_finalize(GObject *object) parser_state_finalize(&priv->parser_state); if (priv->buffers) { - clear_queue(priv->buffers, (GDestroyNotify)gst_buffer_unref); - g_queue_free(priv->buffers); + g_async_queue_unref(priv->buffers); priv->buffers = NULL; } if (priv->frames) { - clear_queue(priv->frames, (GDestroyNotify) - gst_video_codec_frame_unref); - g_queue_free(priv->frames); + g_async_queue_unref(priv->frames); priv->frames = NULL; } @@ -591,8 +584,10 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->va_context = VA_INVALID_ID; priv->codec = 0; priv->codec_state = codec_state; - priv->buffers = g_queue_new(); - priv->frames = g_queue_new(); + + priv->buffers = g_async_queue_new_full((GDestroyNotify)gst_buffer_unref); + priv->frames = g_async_queue_new_full((GDestroyNotify) + gst_video_codec_frame_unref); } /** @@ -699,7 +694,7 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); do { - frame = pop_frame(decoder); + frame = pop_frame(decoder, 0); while (frame) { if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(frame)) { GstVaapiSurfaceProxy * const proxy = frame->user_data; @@ -710,7 +705,7 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; } gst_video_codec_frame_unref(frame); - frame = pop_frame(decoder); + frame = pop_frame(decoder, 0); } status = decode_step(decoder); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); @@ -734,11 +729,39 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, * to the user-data anchor of the output frame. Ownership of the proxy * is transferred to the frame. * + * This is equivalent to gst_vaapi_decoder_get_frame_with_timeout() + * with a timeout value of zero. + * * Return value: a #GstVaapiDecoderStatus */ GstVaapiDecoderStatus gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame **out_frame_ptr) +{ + return gst_vaapi_decoder_get_frame_with_timeout(decoder, out_frame_ptr, 0); +} + +/** + * gst_vaapi_decoder_get_frame_with_timeout: + * @decoder: a #GstVaapiDecoder + * @out_frame_ptr: the next decoded frame as a #GstVideoCodecFrame + * @timeout: the number of microseconds to wait for the frame, at most + * + * On successful return, *@out_frame_ptr contains the next decoded + * frame available as a #GstVideoCodecFrame. The caller owns this + * object, so gst_video_codec_frame_unref() shall be called after + * usage. Otherwise, @GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA is + * returned if no decoded frame is available. + * + * The actual surface is available as a #GstVaapiSurfaceProxy attached + * to the user-data anchor of the output frame. Ownership of the proxy + * is transferred to the frame. + * + * Return value: a #GstVaapiDecoderStatus + */ +GstVaapiDecoderStatus +gst_vaapi_decoder_get_frame_with_timeout(GstVaapiDecoder *decoder, + GstVideoCodecFrame **out_frame_ptr, guint64 timeout) { GstVideoCodecFrame *out_frame; @@ -747,7 +770,7 @@ gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder, g_return_val_if_fail(out_frame_ptr != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - out_frame = pop_frame(decoder); + out_frame = pop_frame(decoder, timeout); if (!out_frame) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 8d083ea2f1..8dea2e4a06 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -151,6 +151,10 @@ 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, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 12af49c06f..094043f096 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -168,8 +168,8 @@ struct _GstVaapiDecoderPrivate { VAContextID va_context; GstVaapiCodec codec; GstVideoCodecState *codec_state; - GQueue *buffers; - GQueue *frames; + GAsyncQueue *buffers; + GAsyncQueue *frames; GstVaapiParserState parser_state; }; diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 292a8da39b..b4d711ff9f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -280,7 +280,8 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec) GstFlowReturn ret; guint flags; - status = gst_vaapi_decoder_get_frame(decode->decoder, &out_frame); + status = gst_vaapi_decoder_get_frame_with_timeout(decode->decoder, + &out_frame, 100000); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return GST_VIDEO_DECODER_FLOW_NEED_DATA; From 5ea1a675ab3f8c60f606e99a9c5737af9a51541f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 25 Apr 2013 14:16:01 +0200 Subject: [PATCH 1171/3781] decoder: fix raw decoding mode. Fix gst_vaapi_decoder_get_surface() to actually transfer ownership of the surface proxy to the caller. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 9df3554e4d..b41d3f91d8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -700,7 +700,7 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, GstVaapiSurfaceProxy * const proxy = frame->user_data; proxy->timestamp = frame->pts; proxy->duration = frame->duration; - *out_proxy_ptr = proxy; + *out_proxy_ptr = gst_vaapi_surface_proxy_ref(proxy); gst_video_codec_frame_unref(frame); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From da2493f731abf9fa16576dcc62e5bd76f4aa1b5d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 7 May 2013 16:43:51 +0200 Subject: [PATCH 1172/3781] decoder: update picture size from the bitstream. Propagate the picture size from the bitstream to the GstVaapiDecoder, and subsequent user who installed a signal on notify::caps. This fixes decoding of TS streams when the demuxer failed to extract the required information. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index b41d3f91d8..6b2b1f4de2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -911,6 +911,8 @@ gst_vaapi_decoder_ensure_context( { GstVaapiDecoderPrivate * const priv = decoder->priv; + gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height); + if (priv->context) { if (!gst_vaapi_context_reset_full(priv->context, cip)) return FALSE; From 6439169db54fa9895c2728a20a430de79e3e2dbf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 30 Apr 2013 10:28:30 +0200 Subject: [PATCH 1173/3781] libs: refine GstVaapiMiniObject. Drop support for user-defined data since this capability was not used so far and GstVaapiMiniObject represents the smallest reference counted object type. Add missing GST_VAAPI_MINI_OBJECT_CLASS() helper macro. Besides, since GstVaapiMiniObject is a libgstvaapi internal object, it is also possible to further simplify the layout of the object. i.e. merge GstVaapiMiniObjectBase into GstVaapiMiniObject. --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 3 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 1 + gst-libs/gst/vaapi/gstvaapiminiobject.c | 109 +++------------------ gst-libs/gst/vaapi/gstvaapiminiobject.h | 31 +++--- 6 files changed, 32 insertions(+), 115 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 32792436b9..1cd658392c 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -42,7 +42,7 @@ const GstVaapiCodecObjectClass * gst_vaapi_codec_object_get_class(GstVaapiCodecObject *object) { return (const GstVaapiCodecObjectClass *) - gst_vaapi_mini_object_get_class(GST_VAAPI_MINI_OBJECT(object)); + GST_VAAPI_MINI_OBJECT_GET_CLASS(object); } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index 047fa24514..c8c2c78de0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -29,8 +29,7 @@ ((GstVaapiDpbClass *)(klass)) #define GST_VAAPI_DPB_GET_CLASS(obj) \ - GST_VAAPI_DPB_CLASS(gst_vaapi_mini_object_get_class( \ - GST_VAAPI_MINI_OBJECT(obj))) + GST_VAAPI_DPB_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) /** * GstVaapiDpb: diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index aa61aeb411..aff30c4846 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -57,6 +57,7 @@ typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; ((GstVaapiParserInfoH264 *)(obj)) struct _GstVaapiParserInfoH264 { + GstVaapiMiniObject parent_instance; GstH264NalUnit nalu; union { GstH264SPS sps; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index b32024850b..ecc9d7fcbb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -258,6 +258,7 @@ struct _GstMpegVideoSliceHdr { typedef struct _GstVaapiParserInfoMpeg2 GstVaapiParserInfoMpeg2; struct _GstVaapiParserInfoMpeg2 { + GstVaapiMiniObject parent_instance; GstMpegVideoPacket packet; guint8 extension_type; /* for Extension packets */ union { diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.c b/gst-libs/gst/vaapi/gstvaapiminiobject.c index 081df1d905..477d00a3e7 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.c @@ -22,51 +22,18 @@ #include #include "gstvaapiminiobject.h" -typedef struct _GstVaapiMiniObjectBase GstVaapiMiniObjectBase; -struct _GstVaapiMiniObjectBase { - gconstpointer object_class; - gint ref_count; - GDestroyNotify user_data_destroy_notify; -}; - -static inline GstVaapiMiniObjectBase * -object2base(GstVaapiMiniObject *object) -{ - return GSIZE_TO_POINTER(GPOINTER_TO_SIZE(object) - - sizeof(GstVaapiMiniObjectBase)); -} - -static inline GstVaapiMiniObject * -base2object(GstVaapiMiniObjectBase *base_object) -{ - return GSIZE_TO_POINTER(GPOINTER_TO_SIZE(base_object) + - sizeof(GstVaapiMiniObjectBase)); -} - static void gst_vaapi_mini_object_free(GstVaapiMiniObject *object) { - GstVaapiMiniObjectBase * const base_object = object2base(object); - const GstVaapiMiniObjectClass * const klass = base_object->object_class; + const GstVaapiMiniObjectClass * const klass = object->object_class; - g_atomic_int_inc(&base_object->ref_count); + g_atomic_int_inc(&object->ref_count); if (klass->finalize) klass->finalize(object); - if (G_LIKELY(g_atomic_int_dec_and_test(&base_object->ref_count))) { - if (object->user_data && base_object->user_data_destroy_notify) - base_object->user_data_destroy_notify(object->user_data); - g_slice_free1(sizeof(*base_object) + klass->size, base_object); - } -} - -const GstVaapiMiniObjectClass * -gst_vaapi_mini_object_get_class(GstVaapiMiniObject *object) -{ - g_return_val_if_fail(object != NULL, NULL); - - return object2base(object)->object_class; + if (G_LIKELY(g_atomic_int_dec_and_test(&object->ref_count))) + g_slice_free1(klass->size, object); } /** @@ -87,28 +54,23 @@ GstVaapiMiniObject * gst_vaapi_mini_object_new(const GstVaapiMiniObjectClass *object_class) { GstVaapiMiniObject *object; - GstVaapiMiniObjectBase *base_object; static const GstVaapiMiniObjectClass default_object_class = { .size = sizeof(GstVaapiMiniObject), }; - if (!object_class) + if (G_UNLIKELY(!object_class)) object_class = &default_object_class; g_return_val_if_fail(object_class->size >= sizeof(*object), NULL); - base_object = g_slice_alloc(sizeof(*base_object) + object_class->size); - if (!base_object) + object = g_slice_alloc(object_class->size); + if (!object) return NULL; - object = base2object(base_object); + object->object_class = object_class; + object->ref_count = 1; object->flags = 0; - object->user_data = 0; - - base_object->object_class = object_class; - base_object->ref_count = 1; - base_object->user_data_destroy_notify = NULL; return object; } @@ -132,7 +94,7 @@ gst_vaapi_mini_object_new0(const GstVaapiMiniObjectClass *object_class) if (!object) return NULL; - object_class = object2base(object)->object_class; + object_class = object->object_class; sub_size = object_class->size - sizeof(*object); if (sub_size > 0) @@ -153,7 +115,7 @@ gst_vaapi_mini_object_ref(GstVaapiMiniObject *object) { g_return_val_if_fail(object != NULL, NULL); - g_atomic_int_inc(&object2base(object)->ref_count); + g_atomic_int_inc(&object->ref_count); return object; } @@ -168,9 +130,9 @@ void gst_vaapi_mini_object_unref(GstVaapiMiniObject *object) { g_return_if_fail(object != NULL); - g_return_if_fail(object2base(object)->ref_count > 0); + g_return_if_fail(object->ref_count > 0); - if (g_atomic_int_dec_and_test(&object2base(object)->ref_count)) + if (g_atomic_int_dec_and_test(&object->ref_count)) gst_vaapi_mini_object_free(object); } @@ -206,48 +168,3 @@ gst_vaapi_mini_object_replace(GstVaapiMiniObject **old_object_ptr, if (old_object) gst_vaapi_mini_object_unref(old_object); } - -/** - * gst_vaapi_mini_object_get_user_data: - * @object: a #GstVaapiMiniObject - * - * Gets user-provided data set on the object via a previous call to - * gst_vaapi_mini_object_set_user_data(). - * - * Returns: (transfer none): The previously set user_data - */ -gpointer -gst_vaapi_mini_object_get_user_data(GstVaapiMiniObject *object) -{ - g_return_val_if_fail(object != NULL, NULL); - - return object->user_data; -} - -/** - * gst_vaapi_mini_object_set_user_data: - * @object: a #GstVaapiMiniObject - * @user_data: user-provided data - * @destroy_notify: (closure user_data): a #GDestroyNotify - * - * Sets @user_data on the object and the #GDestroyNotify that will be - * called when the data is freed. - * - * If some @user_data was previously set, then the former @destroy_notify - * function will be called before the @user_data is replaced. - */ -void -gst_vaapi_mini_object_set_user_data(GstVaapiMiniObject *object, - gpointer user_data, GDestroyNotify destroy_notify) -{ - GstVaapiMiniObjectBase *base_object; - - g_return_if_fail(object != NULL); - - base_object = object2base(object); - if (object->user_data && base_object->user_data_destroy_notify) - base_object->user_data_destroy_notify(object->user_data); - - object->user_data = user_data; - base_object->user_data_destroy_notify = destroy_notify; -} diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.h b/gst-libs/gst/vaapi/gstvaapiminiobject.h index 4cf27d9621..900b232d7d 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.h @@ -38,6 +38,15 @@ typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; #define GST_VAAPI_MINI_OBJECT(object) \ ((GstVaapiMiniObject *)(object)) +/** + * GST_VAAPI_MINI_OBJECT_CLASS: + * @klass: a #GstVaapiMiniObjectClass + * + * Casts the @klass to a #GstVaapiMiniObjectClass + */ +#define GST_VAAPI_MINI_OBJECT_CLASS(klass) \ + ((GstVaapiMiniObjectClass *)(klass)) + /** * GST_VAAPI_MINI_OBJECT_GET_CLASS: * @object: a #GstVaapiMiniObject @@ -45,7 +54,7 @@ typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; * Retrieves the #GstVaapiMiniObjectClass associated with the @object */ #define GST_VAAPI_MINI_OBJECT_GET_CLASS(object) \ - gst_vaapi_mini_object_get_class(GST_VAAPI_MINI_OBJECT(object)) + (GST_VAAPI_MINI_OBJECT(object)->object_class) /** * GST_VAAPI_MINI_OBJECT_FLAGS: @@ -88,17 +97,20 @@ typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; /** * GstVaapiMiniObject: + * @object_class: the #GstVaapiMiniObjectClass + * @ref_count: the object reference count that should be manipulated + * through gst_vaapi_mini_object_ref() et al. helpers * @flags: set of flags that should be manipulated through * GST_VAAPI_MINI_OBJECT_FLAG_*() functions - * @user_data: user-provided data from gst_vaapi_mini_object_set_user_data() * * A #GstVaapiMiniObject represents a minimal reference counted data * structure that can hold a set of flags and user-provided data. */ struct _GstVaapiMiniObject { /*< private >*/ + gconstpointer object_class; + volatile gint ref_count; guint flags; - gpointer user_data; }; /** @@ -116,10 +128,6 @@ struct _GstVaapiMiniObjectClass { GDestroyNotify finalize; }; -G_GNUC_INTERNAL -const GstVaapiMiniObjectClass * -gst_vaapi_mini_object_get_class(GstVaapiMiniObject *object) G_GNUC_CONST; - G_GNUC_INTERNAL GstVaapiMiniObject * gst_vaapi_mini_object_new(const GstVaapiMiniObjectClass *object_class); @@ -141,15 +149,6 @@ void gst_vaapi_mini_object_replace(GstVaapiMiniObject **old_object_ptr, GstVaapiMiniObject *new_object); -G_GNUC_INTERNAL -gpointer -gst_vaapi_mini_object_get_user_data(GstVaapiMiniObject *object); - -G_GNUC_INTERNAL -void -gst_vaapi_mini_object_set_user_data(GstVaapiMiniObject *object, - gpointer user_data, GDestroyNotify destroy_notify); - G_END_DECLS #endif /* GST_VAAPI_MINI_OBJECT_H */ From 1f15c28a1b552ebf15edcefb6dac815fd0de7b36 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 30 Apr 2013 17:20:46 +0200 Subject: [PATCH 1174/3781] Port GstVaapiObject to GstVaapiMiniObject. --- gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapiobject.c | 228 +++++++++-------------- gst-libs/gst/vaapi/gstvaapiobject.h | 58 +----- gst-libs/gst/vaapi/gstvaapiobject_priv.h | 108 +++++++++-- 4 files changed, 195 insertions(+), 200 deletions(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 7c021a2748..d783d8df1d 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -20,6 +20,7 @@ libgstvaapi_includedir = \ $(includedir)/gstreamer-$(GST_API_VERSION)/gst/vaapi libgstvaapi_cflags = \ + -DGST_VAAPI_CORE \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ -I$(top_builddir)/gst-libs \ diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index b9f6f62bf9..59efb5d2b0 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -27,169 +27,117 @@ #include "sysdeps.h" #include "gstvaapiobject.h" -#include "gstvaapi_priv.h" -#include "gstvaapiparamspecs.h" -#include "gstvaapivalue.h" +#include "gstvaapiobject_priv.h" +#include "gstvaapiminiobject.h" +#include "gstvaapidisplay_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiObject, gst_vaapi_object, G_TYPE_OBJECT) - -enum { - PROP_0, - - PROP_DISPLAY, - PROP_ID -}; - -enum { - DESTROY, - - LAST_SIGNAL -}; - -static guint object_signals[LAST_SIGNAL] = { 0, }; +/* Ensure those symbols are actually defined in the resulting libraries */ +#undef gst_vaapi_object_ref +#undef gst_vaapi_object_unref +#undef gst_vaapi_object_replace static void -gst_vaapi_object_dispose(GObject *object) +gst_vaapi_object_finalize(GstVaapiObject *object) { - GstVaapiObjectPrivate * const priv = GST_VAAPI_OBJECT(object)->priv; + const GstVaapiObjectClass * const klass = + GST_VAAPI_OBJECT_GET_CLASS(object); - if (!priv->is_destroying) { - priv->is_destroying = TRUE; - g_signal_emit(object, object_signals[DESTROY], 0); - priv->is_destroying = FALSE; - } - - G_OBJECT_CLASS(gst_vaapi_object_parent_class)->dispose(object); + if (klass->finalize) + klass->finalize(object); + g_clear_object(&object->display); } -static void -gst_vaapi_object_finalize(GObject *object) +void +gst_vaapi_object_class_init(GstVaapiObjectClass *klass, guint size) { - GstVaapiObjectPrivate * const priv = GST_VAAPI_OBJECT(object)->priv; + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); - priv->id = GST_VAAPI_ID_NONE; - - g_clear_object(&priv->display); - - G_OBJECT_CLASS(gst_vaapi_object_parent_class)->finalize(object); + object_class->size = size; + object_class->finalize = (GDestroyNotify)gst_vaapi_object_finalize; } -static void -gst_vaapi_object_set_property( - GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) +/** + * gst_vaapi_object_new: + * @object_class: The object class + * + * Creates a new #GstVaapiObject. If @object_class is NULL, then the + * size of the allocated object is the same as sizeof(GstVaapiObject). + * If @object_class is not NULL, typically when a sub-class is implemented, + * that pointer shall reference a statically allocated descriptor. + * + * This function zero-initializes the derived object data. Also note + * that this is an internal function that shall not be used outside of + * libgstvaapi libraries. + * + * Returns: The newly allocated #GstVaapiObject + */ +gpointer +gst_vaapi_object_new(const GstVaapiObjectClass *klass, GstVaapiDisplay *display) { - GstVaapiObject * const object = GST_VAAPI_OBJECT(gobject); + const GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); + GstVaapiObject *object; + guint sub_size; - switch (prop_id) { - case PROP_DISPLAY: - object->priv->display = g_object_ref(g_value_get_object(value)); - break; - case PROP_ID: - object->priv->id = gst_vaapi_value_get_id(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); - break; - } + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + + object = (GstVaapiObject *)gst_vaapi_mini_object_new(object_class); + if (!object) + return NULL; + + object->display = g_object_ref(display); + object->object_id = VA_INVALID_ID; + + sub_size = object_class->size - sizeof(*object); + if (sub_size > 0) + memset(((guchar *)object) + sizeof(*object), 0, sub_size); + return object; } -static void -gst_vaapi_object_get_property( - GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec -) +/** + * gst_vaapi_object_ref: + * @object: a #GstVaapiObject + * + * Atomically increases the reference count of the given @object by one. + * + * Returns: The same @object argument + */ +gpointer +gst_vaapi_object_ref(gpointer object) { - GstVaapiObject * const object = GST_VAAPI_OBJECT(gobject); - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_object(value, gst_vaapi_object_get_display(object)); - break; - case PROP_ID: - gst_vaapi_value_set_id(value, gst_vaapi_object_get_id(object)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); - break; - } + return gst_vaapi_object_ref_internal(object); } -static void -gst_vaapi_object_class_init(GstVaapiObjectClass *klass) +/** + * gst_vaapi_object_unref: + * @object: a #GstVaapiObject + * + * Atomically decreases the reference count of the @object by one. If + * the reference count reaches zero, the object will be free'd. + */ +void +gst_vaapi_object_unref(gpointer object) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiObjectPrivate)); - - object_class->dispose = gst_vaapi_object_dispose; - object_class->finalize = gst_vaapi_object_finalize; - object_class->set_property = gst_vaapi_object_set_property; - object_class->get_property = gst_vaapi_object_get_property; - - /** - * GstVaapiObject:display: - * - * The #GstVaapiDisplay this object is bound to. - */ - g_object_class_install_property - (object_class, - PROP_DISPLAY, - g_param_spec_object("display", - "Display", - "The GstVaapiDisplay this object is bound to", - GST_VAAPI_TYPE_DISPLAY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiObject:id: - * - * The #GstVaapiID contained in this object. - */ - g_object_class_install_property - (object_class, - PROP_ID, - gst_vaapi_param_spec_id("id", - "ID", - "The GstVaapiID contained in this object", - GST_VAAPI_ID_NONE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiObject::destroy: - * @object: the object which received the signal - * - * The ::destroy signal is emitted when an object is destroyed, - * when the user released the last reference to @object. - */ - object_signals[DESTROY] = g_signal_new( - "destroy", - G_TYPE_FROM_CLASS(object_class), - G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - G_STRUCT_OFFSET(GstVaapiObjectClass, destroy), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0 - ); + gst_vaapi_object_unref_internal(object); } -static void -gst_vaapi_object_init(GstVaapiObject *object) +/** + * gst_vaapi_object_replace: + * @old_object_ptr: a pointer to a #GstVaapiObject + * @new_object: a #GstVaapiObject + * + * Atomically replaces the object object held in @old_object_ptr with + * @new_object. This means that @old_object_ptr shall reference a + * valid object. However, @new_object can be NULL. + */ +void +gst_vaapi_object_replace(gpointer old_object_ptr, gpointer new_object) { - GstVaapiObjectPrivate *priv = GST_VAAPI_OBJECT_GET_PRIVATE(object); - - object->priv = priv; - priv->display = NULL; - priv->id = GST_VAAPI_ID_NONE; - priv->is_destroying = FALSE; + gst_vaapi_object_replace_internal(old_object_ptr, new_object); } /** @@ -205,7 +153,7 @@ gst_vaapi_object_get_display(GstVaapiObject *object) { g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), NULL); - return object->priv->display; + return GST_VAAPI_OBJECT_DISPLAY(object); } /** @@ -253,5 +201,5 @@ gst_vaapi_object_get_id(GstVaapiObject *object) { g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), GST_VAAPI_ID_NONE); - return object->priv->id; + return GST_VAAPI_OBJECT_ID(object); } diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index 40da7a81d1..cdc59d4fad 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -28,62 +28,22 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_OBJECT \ - (gst_vaapi_object_get_type()) - -#define GST_VAAPI_OBJECT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_OBJECT, \ - GstVaapiObject)) - -#define GST_VAAPI_OBJECT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_OBJECT, \ - GstVaapiObjectClass)) +#define GST_VAAPI_OBJECT(obj) \ + ((GstVaapiObject *)(obj)) #define GST_VAAPI_IS_OBJECT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_OBJECT)) - -#define GST_VAAPI_IS_OBJECT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_OBJECT)) - -#define GST_VAAPI_OBJECT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_OBJECT, \ - GstVaapiObjectClass)) + ((obj) != NULL) typedef struct _GstVaapiObject GstVaapiObject; -typedef struct _GstVaapiObjectPrivate GstVaapiObjectPrivate; -typedef struct _GstVaapiObjectClass GstVaapiObjectClass; -/** - * GstVaapiObject: - * - * VA object base. - */ -struct _GstVaapiObject { - /*< private >*/ - GObject parent_instance; +gpointer +gst_vaapi_object_ref(gpointer object); - GstVaapiObjectPrivate *priv; -}; +void +gst_vaapi_object_unref(gpointer object); -/** - * GstVaapiObjectClass: - * @destroy: signal class handler for #GstVaapiObject::destroy - * - * VA object base class. - */ -struct _GstVaapiObjectClass { - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - void (*destroy)(GstVaapiObject *oject); -}; - -GType -gst_vaapi_object_get_type(void) G_GNUC_CONST; +void +gst_vaapi_object_replace(gpointer old_object_ptr, gpointer new_object); GstVaapiDisplay * gst_vaapi_object_get_display(GstVaapiObject *object); diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 1e871b2a3f..f1e80590eb 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -24,15 +24,45 @@ #define GST_VAAPI_OBJECT_PRIV_H #include +#include "gstvaapiminiobject.h" +#include "gstvaapidisplay_priv.h" G_BEGIN_DECLS -#define GST_VAAPI_OBJECT_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_OBJECT, \ - GstVaapiObjectPrivate)) +#define GST_VAAPI_OBJECT_CLASS(klass) \ + ((GstVaapiObjectClass *)(klass)) -#define GST_VAAPI_OBJECT_CAST(object) ((GstVaapiObject *)(object)) +#define GST_VAAPI_IS_OBJECT_CLASS(klass) \ + ((klass) != NULL) + +#define GST_VAAPI_OBJECT_GET_CLASS(object) \ + GST_VAAPI_OBJECT_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(object)) + +typedef struct _GstVaapiObjectClass GstVaapiObjectClass; +typedef void (*GstVaapiObjectInitFunc) (GstVaapiObject *object); +typedef void (*GstVaapiObjectFinalizeFunc) (GstVaapiObject *object); + +#define GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE(TN, t_n, code) \ +static inline const GstVaapiObjectClass * \ +G_PASTE(t_n,_class)(void) \ +{ \ + static G_PASTE(TN,Class) g_class; \ + static gsize g_class_init = FALSE; \ + \ + if (g_once_init_enter(&g_class_init)) { \ + GstVaapiObjectClass * const klass = \ + GST_VAAPI_OBJECT_CLASS(&g_class); \ + gst_vaapi_object_class_init(klass, sizeof(TN)); \ + code; \ + klass->finalize = (GstVaapiObjectFinalizeFunc) \ + G_PASTE(t_n,_finalize); \ + g_once_init_leave(&g_class_init, TRUE); \ + } \ + return GST_VAAPI_OBJECT_CLASS(&g_class); \ +} + +#define GST_VAAPI_OBJECT_DEFINE_CLASS(TN, t_n) \ + GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE(TN, t_n, /**/) /** * GST_VAAPI_OBJECT_DISPLAY: @@ -42,7 +72,7 @@ G_BEGIN_DECLS * This is an internal macro that does not do any run-time type check. */ #define GST_VAAPI_OBJECT_DISPLAY(object) \ - GST_VAAPI_OBJECT_CAST(object)->priv->display + GST_VAAPI_OBJECT(object)->display /** * GST_VAAPI_OBJECT_ID: @@ -52,7 +82,7 @@ G_BEGIN_DECLS * This is an internal macro that does not do any run-time type checks. */ #define GST_VAAPI_OBJECT_ID(object) \ - GST_VAAPI_OBJECT_CAST(object)->priv->id + GST_VAAPI_OBJECT(object)->object_id /** * GST_VAAPI_OBJECT_DISPLAY_X11: @@ -152,16 +182,72 @@ G_BEGIN_DECLS GST_VAAPI_DISPLAY_UNLOCK(GST_VAAPI_OBJECT_DISPLAY(object)) /** - * GstVaapiObjectPrivate: + * GstVaapiObject: * * VA object base. */ -struct _GstVaapiObjectPrivate { +struct _GstVaapiObject { + /*< private >*/ + GstVaapiMiniObject parent_instance; + GstVaapiDisplay *display; - GstVaapiID id; - guint is_destroying : 1; + GstVaapiID object_id; }; +/** + * GstVaapiObjectClass: + * + * VA object base class. + */ +struct _GstVaapiObjectClass { + /*< private >*/ + GstVaapiMiniObjectClass parent_class; + + GstVaapiObjectInitFunc init; + GstVaapiObjectFinalizeFunc finalize; +}; + +void +gst_vaapi_object_class_init(GstVaapiObjectClass *klass, guint size); + +gpointer +gst_vaapi_object_new(const GstVaapiObjectClass *klass, + GstVaapiDisplay *display); + +/* Inline reference counting for core libgstvaapi library */ +#ifdef GST_VAAPI_CORE +static inline gpointer +gst_vaapi_object_ref_internal(gpointer object) +{ + return gst_vaapi_mini_object_ref(object); +} + +static inline void +gst_vaapi_object_unref_internal(gpointer object) +{ + gst_vaapi_mini_object_unref(object); +} + +static inline void +gst_vaapi_object_replace_internal(gpointer old_object_ptr, gpointer new_object) +{ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)old_object_ptr, + new_object); +} + +#undef gst_vaapi_object_ref +#define gst_vaapi_object_ref(object) \ + gst_vaapi_object_ref_internal((object)) + +#undef gst_vaapi_object_unref +#define gst_vaapi_object_unref(object) \ + gst_vaapi_object_unref_internal((object)) + +#undef gst_vaapi_object_replace +#define gst_vaapi_object_replace(old_object_ptr, new_object) \ + gst_vaapi_object_replace_internal((old_object_ptr), (new_object)) +#endif + G_END_DECLS #endif /* GST_VAAPI_OBJECT_PRIV_H */ From 6c46179709a7fff04687f6deb97326d4f45160a8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 30 Apr 2013 17:22:15 +0200 Subject: [PATCH 1175/3781] libs: use GstVaapiObject for VA objects. --- gst-libs/gst/vaapi/gstvaapicontext.c | 402 +++++++-------------- gst-libs/gst/vaapi/gstvaapicontext.h | 57 +-- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.c | 413 ++++++---------------- gst-libs/gst/vaapi/gstvaapiimage.h | 51 +-- gst-libs/gst/vaapi/gstvaapisubpicture.c | 229 +++--------- gst-libs/gst/vaapi/gstvaapisubpicture.h | 59 +--- gst-libs/gst/vaapi/gstvaapisurface.c | 284 ++++----------- gst-libs/gst/vaapi/gstvaapisurface.h | 51 +-- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 4 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 15 +- 11 files changed, 385 insertions(+), 1182 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 2ef44036da..9312384ae7 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -29,25 +29,46 @@ #include #include "gstvaapicompat.h" #include "gstvaapicontext.h" +#include "gstvaapiobject_priv.h" #include "gstvaapisurface.h" #include "gstvaapisurface_priv.h" #include "gstvaapisurfacepool.h" #include "gstvaapisurfaceproxy.h" #include "gstvaapiimage.h" #include "gstvaapisubpicture.h" -#include "gstvaapiminiobject.h" #include "gstvaapiutils.h" -#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiContext, gst_vaapi_context, GST_VAAPI_TYPE_OBJECT) +typedef struct _GstVaapiContextClass GstVaapiContextClass; -#define GST_VAAPI_CONTEXT_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_CONTEXT, \ - GstVaapiContextPrivate)) +/** + * GstVaapiContext: + * + * A VA context wrapper. + */ +struct _GstVaapiContext { + /*< private >*/ + GstVaapiObject parent_instance; + + GstVaapiContextInfo info; + VAConfigID config_id; + GPtrArray *surfaces; + GstVaapiVideoPool *surfaces_pool; + GPtrArray *overlays[2]; + guint overlay_id; +}; + +/** + * GstVaapiContextClass: + * + * A VA context wrapper class. + */ +struct _GstVaapiContextClass { + /*< private >*/ + GstVaapiObjectClass parent_class; +}; typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle; struct _GstVaapiOverlayRectangle { @@ -61,31 +82,6 @@ struct _GstVaapiOverlayRectangle { guint is_associated : 1; }; -/* XXX: optimize for the effective number of reference frames */ -struct _GstVaapiContextPrivate { - VAConfigID config_id; - GPtrArray *surfaces; - GstVaapiVideoPool *surfaces_pool; - GPtrArray *overlays[2]; - guint overlay_id; - GstVaapiProfile profile; - GstVaapiEntrypoint entrypoint; - guint width; - guint height; - guint ref_frames; - guint is_constructed : 1; -}; - -enum { - PROP_0, - - PROP_PROFILE, - PROP_ENTRYPOINT, - PROP_WIDTH, - PROP_HEIGHT, - PROP_REF_FRAMES -}; - static guint get_max_ref_frames(GstVaapiProfile profile) { @@ -188,7 +184,7 @@ overlay_rectangle_finalize(GstVaapiOverlayRectangle *overlay) if (overlay->subpicture) { overlay_rectangle_deassociate(overlay); - g_object_unref(overlay->subpicture); + gst_vaapi_object_unref(overlay->subpicture); overlay->subpicture = NULL; } } @@ -197,7 +193,7 @@ static gboolean overlay_rectangle_associate(GstVaapiOverlayRectangle *overlay) { GstVaapiSubpicture * const subpicture = overlay->subpicture; - GPtrArray * const surfaces = overlay->context->priv->surfaces; + GPtrArray * const surfaces = overlay->context->surfaces; guint i, n_associated; if (overlay->is_associated) @@ -219,7 +215,7 @@ static gboolean overlay_rectangle_deassociate(GstVaapiOverlayRectangle *overlay) { GstVaapiSubpicture * const subpicture = overlay->subpicture; - GPtrArray * const surfaces = overlay->context->priv->surfaces; + GPtrArray * const surfaces = overlay->context->surfaces; guint i, n_associated; if (!overlay->is_associated) @@ -388,11 +384,9 @@ overlay_reassociate(GPtrArray *overlays) static void gst_vaapi_context_clear_overlay(GstVaapiContext *context) { - GstVaapiContextPrivate * const priv = context->priv; - - overlay_clear(priv->overlays[0]); - overlay_clear(priv->overlays[1]); - priv->overlay_id = 0; + overlay_clear(context->overlays[0]); + overlay_clear(context->overlays[1]); + context->overlay_id = 0; } static inline void @@ -407,30 +401,26 @@ unref_surface_cb(gpointer data, gpointer user_data) GstVaapiSurface * const surface = GST_VAAPI_SURFACE(data); gst_vaapi_surface_set_parent_context(surface, NULL); - g_object_unref(surface); + gst_vaapi_object_unref(surface); } static void gst_vaapi_context_destroy_surfaces(GstVaapiContext *context) { - GstVaapiContextPrivate * const priv = context->priv; - gst_vaapi_context_destroy_overlay(context); - if (priv->surfaces) { - g_ptr_array_foreach(priv->surfaces, unref_surface_cb, NULL); - g_ptr_array_free(priv->surfaces, TRUE); - priv->surfaces = NULL; + if (context->surfaces) { + g_ptr_array_foreach(context->surfaces, unref_surface_cb, NULL); + g_ptr_array_free(context->surfaces, TRUE); + context->surfaces = NULL; } - - g_clear_object(&priv->surfaces_pool); + g_clear_object(&context->surfaces_pool); } static void gst_vaapi_context_destroy(GstVaapiContext *context) { GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context); - GstVaapiContextPrivate * const priv = context->priv; VAContextID context_id; VAStatus status; @@ -450,26 +440,24 @@ gst_vaapi_context_destroy(GstVaapiContext *context) GST_VAAPI_OBJECT_ID(context) = VA_INVALID_ID; } - if (priv->config_id != VA_INVALID_ID) { + if (context->config_id != VA_INVALID_ID) { GST_VAAPI_DISPLAY_LOCK(display); status = vaDestroyConfig( GST_VAAPI_DISPLAY_VADISPLAY(display), - priv->config_id + context->config_id ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaDestroyConfig()")) g_warning("failed to destroy config %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(priv->config_id)); - priv->config_id = VA_INVALID_ID; + GST_VAAPI_ID_ARGS(context->config_id)); + context->config_id = VA_INVALID_ID; } } static gboolean gst_vaapi_context_create_overlay(GstVaapiContext *context) { - GstVaapiContextPrivate * const priv = context->priv; - - if (!priv->overlays[0] || !priv->overlays[1]) + if (!context->overlays[0] || !context->overlays[1]) return FALSE; gst_vaapi_context_clear_overlay(context); @@ -479,7 +467,7 @@ gst_vaapi_context_create_overlay(GstVaapiContext *context) static gboolean gst_vaapi_context_create_surfaces(GstVaapiContext *context) { - GstVaapiContextPrivate * const priv = context->priv; + const GstVaapiContextInfo * const cip = &context->info; GstCaps *caps; GstVaapiSurface *surface; guint i, num_surfaces; @@ -490,45 +478,45 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context) if (!gst_vaapi_context_create_overlay(context)) return FALSE; - if (!priv->surfaces) { - priv->surfaces = g_ptr_array_new(); - if (!priv->surfaces) + if (!context->surfaces) { + context->surfaces = g_ptr_array_new(); + if (!context->surfaces) return FALSE; } - if (!priv->surfaces_pool) { + if (!context->surfaces_pool) { caps = gst_caps_new_simple( GST_VAAPI_SURFACE_CAPS_NAME, "type", G_TYPE_STRING, "vaapi", - "width", G_TYPE_INT, priv->width, - "height", G_TYPE_INT, priv->height, + "width", G_TYPE_INT, cip->width, + "height", G_TYPE_INT, cip->height, NULL ); if (!caps) return FALSE; - priv->surfaces_pool = gst_vaapi_surface_pool_new( + context->surfaces_pool = gst_vaapi_surface_pool_new( GST_VAAPI_OBJECT_DISPLAY(context), caps ); gst_caps_unref(caps); - if (!priv->surfaces_pool) + if (!context->surfaces_pool) return FALSE; } - num_surfaces = priv->ref_frames + SCRATCH_SURFACES_COUNT; - gst_vaapi_video_pool_set_capacity(priv->surfaces_pool, num_surfaces); + num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; + gst_vaapi_video_pool_set_capacity(context->surfaces_pool, num_surfaces); - for (i = priv->surfaces->len; i < num_surfaces; i++) { + for (i = context->surfaces->len; i < num_surfaces; i++) { surface = gst_vaapi_surface_new( GST_VAAPI_OBJECT_DISPLAY(context), GST_VAAPI_CHROMA_TYPE_YUV420, - priv->width, priv->height + cip->width, cip->height ); if (!surface) return FALSE; gst_vaapi_surface_set_parent_context(surface, context); - g_ptr_array_add(priv->surfaces, surface); - if (!gst_vaapi_video_pool_add_object(priv->surfaces_pool, surface)) + g_ptr_array_add(context->surfaces, surface); + if (!gst_vaapi_video_pool_add_object(context->surfaces_pool, surface)) return FALSE; } return TRUE; @@ -537,8 +525,8 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context) static gboolean gst_vaapi_context_create(GstVaapiContext *context) { + const GstVaapiContextInfo * const cip = &context->info; GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context); - GstVaapiContextPrivate * const priv = context->priv; VAProfile va_profile; VAEntrypoint va_entrypoint; VAConfigAttrib attrib; @@ -549,31 +537,32 @@ gst_vaapi_context_create(GstVaapiContext *context) gboolean success = FALSE; guint i; - if (!priv->surfaces && !gst_vaapi_context_create_surfaces(context)) + if (!context->surfaces && !gst_vaapi_context_create_surfaces(context)) goto end; surfaces = g_array_sized_new( FALSE, FALSE, sizeof(VASurfaceID), - priv->surfaces->len + context->surfaces->len ); if (!surfaces) goto end; - for (i = 0; i < priv->surfaces->len; i++) { - GstVaapiSurface * const surface = g_ptr_array_index(priv->surfaces, i); + for (i = 0; i < context->surfaces->len; i++) { + GstVaapiSurface * const surface = + g_ptr_array_index(context->surfaces, i); if (!surface) goto end; surface_id = GST_VAAPI_OBJECT_ID(surface); g_array_append_val(surfaces, surface_id); } - assert(surfaces->len == priv->surfaces->len); + assert(surfaces->len == context->surfaces->len); - if (!priv->profile || !priv->entrypoint) + if (!cip->profile || !cip->entrypoint) goto end; - va_profile = gst_vaapi_profile_get_va_profile(priv->profile); - va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint(priv->entrypoint); + va_profile = gst_vaapi_profile_get_va_profile(cip->profile); + va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint(cip->entrypoint); GST_VAAPI_DISPLAY_LOCK(display); attrib.type = VAConfigAttribRTFormat; @@ -595,7 +584,7 @@ gst_vaapi_context_create(GstVaapiContext *context) va_profile, va_entrypoint, &attrib, 1, - &priv->config_id + &context->config_id ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaCreateConfig()")) @@ -604,8 +593,8 @@ gst_vaapi_context_create(GstVaapiContext *context) GST_VAAPI_DISPLAY_LOCK(display); status = vaCreateContext( GST_VAAPI_DISPLAY_VADISPLAY(display), - priv->config_id, - priv->width, priv->height, + context->config_id, + cip->width, cip->height, VA_PROGRESSIVE, (VASurfaceID *)surfaces->data, surfaces->len, &context_id @@ -623,160 +612,25 @@ end: return success; } -static void -gst_vaapi_context_finalize(GObject *object) +static inline void +gst_vaapi_context_init(GstVaapiContext *context, const GstVaapiContextInfo *cip) { - GstVaapiContext * const context = GST_VAAPI_CONTEXT(object); - GstVaapiContextPrivate * const priv = context->priv; + context->info = *cip; + context->config_id = VA_INVALID_ID; + context->overlays[0] = overlay_new(); + context->overlays[1] = overlay_new(); +} - overlay_destroy(&priv->overlays[0]); - overlay_destroy(&priv->overlays[1]); +static void +gst_vaapi_context_finalize(GstVaapiContext *context) +{ + overlay_destroy(&context->overlays[0]); + overlay_destroy(&context->overlays[1]); gst_vaapi_context_destroy(context); gst_vaapi_context_destroy_surfaces(context); - - G_OBJECT_CLASS(gst_vaapi_context_parent_class)->finalize(object); } -static void -gst_vaapi_context_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiContext * const context = GST_VAAPI_CONTEXT(object); - GstVaapiContextPrivate * const priv = context->priv; - - switch (prop_id) { - case PROP_PROFILE: - gst_vaapi_context_set_profile(context, g_value_get_uint(value)); - break; - case PROP_ENTRYPOINT: - priv->entrypoint = g_value_get_uint(value); - break; - case PROP_WIDTH: - priv->width = g_value_get_uint(value); - break; - case PROP_HEIGHT: - priv->height = g_value_get_uint(value); - break; - case PROP_REF_FRAMES: - priv->ref_frames = g_value_get_uint(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_context_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiContext * const context = GST_VAAPI_CONTEXT(object); - GstVaapiContextPrivate * const priv = context->priv; - - switch (prop_id) { - case PROP_PROFILE: - g_value_set_uint(value, gst_vaapi_context_get_profile(context)); - break; - case PROP_ENTRYPOINT: - g_value_set_uint(value, gst_vaapi_context_get_entrypoint(context)); - break; - case PROP_WIDTH: - g_value_set_uint(value, priv->width); - break; - case PROP_HEIGHT: - g_value_set_uint(value, priv->height); - break; - case PROP_REF_FRAMES: - g_value_set_uint(value, priv->ref_frames); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_context_class_init(GstVaapiContextClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiContextPrivate)); - - object_class->finalize = gst_vaapi_context_finalize; - object_class->set_property = gst_vaapi_context_set_property; - object_class->get_property = gst_vaapi_context_get_property; - - g_object_class_install_property - (object_class, - PROP_PROFILE, - g_param_spec_uint("profile", - "Profile", - "The profile used for decoding", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE)); - - g_object_class_install_property - (object_class, - PROP_ENTRYPOINT, - g_param_spec_uint("entrypoint", - "Entrypoint", - "The decoder entrypoint", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_WIDTH, - g_param_spec_uint("width", - "Width", - "The width of decoded surfaces", - 0, G_MAXINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_HEIGHT, - g_param_spec_uint("height", - "Height", - "The height of the decoded surfaces", - 0, G_MAXINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_REF_FRAMES, - g_param_spec_uint("ref-frames", - "Reference Frames", - "The number of reference frames", - 0, G_MAXINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); -} - -static void -gst_vaapi_context_init(GstVaapiContext *context) -{ - GstVaapiContextPrivate *priv = GST_VAAPI_CONTEXT_GET_PRIVATE(context); - - context->priv = priv; - priv->config_id = VA_INVALID_ID; - priv->surfaces = NULL; - priv->surfaces_pool = NULL; - priv->overlays[0] = overlay_new(); - priv->overlays[1] = overlay_new(); - priv->profile = 0; - priv->entrypoint = 0; - priv->width = 0; - priv->height = 0; - priv->ref_frames = 0; -} +GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiContext, gst_vaapi_context) /** * gst_vaapi_context_new: @@ -822,32 +676,28 @@ gst_vaapi_context_new( * Return value: the newly allocated #GstVaapiContext object */ GstVaapiContext * -gst_vaapi_context_new_full(GstVaapiDisplay *display, GstVaapiContextInfo *cip) +gst_vaapi_context_new_full(GstVaapiDisplay *display, + const GstVaapiContextInfo *cip) { GstVaapiContext *context; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); g_return_val_if_fail(cip->profile, NULL); g_return_val_if_fail(cip->entrypoint, NULL); g_return_val_if_fail(cip->width > 0, NULL); g_return_val_if_fail(cip->height > 0, NULL); - context = g_object_new( - GST_VAAPI_TYPE_CONTEXT, - "display", display, - "id", GST_VAAPI_ID(VA_INVALID_ID), - "profile", cip->profile, - "entrypoint", cip->entrypoint, - "width", cip->width, - "height", cip->height, - "ref-frames", cip->ref_frames, - NULL - ); - if (!context->priv->is_constructed) { - g_object_unref(context); + context = gst_vaapi_object_new(gst_vaapi_context_class(), display); + if (!context) return NULL; - } + + gst_vaapi_context_init(context, cip); + if (!gst_vaapi_context_create(context)) + goto error; return context; + +error: + gst_vaapi_object_unref(context); + return NULL; } /** @@ -872,14 +722,13 @@ gst_vaapi_context_reset( unsigned int height ) { - GstVaapiContextPrivate * const priv = context->priv; GstVaapiContextInfo info; info.profile = profile; info.entrypoint = entrypoint; info.width = width; info.height = height; - info.ref_frames = priv->ref_frames; + info.ref_frames = context->info.ref_frames; return gst_vaapi_context_reset_full(context, &info); } @@ -887,32 +736,35 @@ gst_vaapi_context_reset( /** * gst_vaapi_context_reset_full: * @context: a #GstVaapiContext - * @cip: a pointer to the new #GstVaapiContextInfo details + * @new_cip: a pointer to the new #GstVaapiContextInfo details * - * Resets @context to the configuration specified by @cip, thus + * 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_full(GstVaapiContext *context, GstVaapiContextInfo *cip) +gst_vaapi_context_reset_full(GstVaapiContext *context, + const GstVaapiContextInfo *new_cip) { - GstVaapiContextPrivate * const priv = context->priv; + GstVaapiContextInfo * const cip = &context->info; gboolean size_changed, codec_changed; - size_changed = priv->width != cip->width || priv->height != cip->height; + size_changed = cip->width != new_cip->width || + cip->height != new_cip->height; if (size_changed) { gst_vaapi_context_destroy_surfaces(context); - priv->width = cip->width; - priv->height = cip->height; + cip->width = new_cip->width; + cip->height = new_cip->height; } - codec_changed = priv->profile != cip->profile || priv->entrypoint != cip->entrypoint; + codec_changed = cip->profile != new_cip->profile || + cip->entrypoint != new_cip->entrypoint; if (codec_changed) { gst_vaapi_context_destroy(context); - priv->profile = cip->profile; - priv->entrypoint = cip->entrypoint; + cip->profile = new_cip->profile; + cip->entrypoint = new_cip->entrypoint; } if (size_changed && !gst_vaapi_context_create_surfaces(context)) @@ -921,7 +773,6 @@ gst_vaapi_context_reset_full(GstVaapiContext *context, GstVaapiContextInfo *cip) if (codec_changed && !gst_vaapi_context_create(context)) return FALSE; - priv->is_constructed = TRUE; return TRUE; } @@ -954,7 +805,7 @@ gst_vaapi_context_get_profile(GstVaapiContext *context) { g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0); - return context->priv->profile; + return context->info.profile; } /** @@ -977,9 +828,9 @@ gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile) return gst_vaapi_context_reset(context, profile, - context->priv->entrypoint, - context->priv->width, - context->priv->height); + context->info.entrypoint, + context->info.width, + context->info.height); } /** @@ -995,7 +846,7 @@ gst_vaapi_context_get_entrypoint(GstVaapiContext *context) { g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0); - return context->priv->entrypoint; + return context->info.entrypoint; } /** @@ -1016,10 +867,10 @@ gst_vaapi_context_get_size( g_return_if_fail(GST_VAAPI_IS_CONTEXT(context)); if (pwidth) - *pwidth = context->priv->width; + *pwidth = context->info.width; if (pheight) - *pheight = context->priv->height; + *pheight = context->info.height; } /** @@ -1043,7 +894,7 @@ gst_vaapi_context_get_surface_proxy(GstVaapiContext *context) g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); return gst_vaapi_surface_proxy_new_from_pool( - GST_VAAPI_SURFACE_POOL(context->priv->surfaces_pool)); + GST_VAAPI_SURFACE_POOL(context->surfaces_pool)); } /** @@ -1059,7 +910,7 @@ gst_vaapi_context_get_surface_count(GstVaapiContext *context) { g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0); - return gst_vaapi_video_pool_get_size(context->priv->surfaces_pool); + return gst_vaapi_video_pool_get_size(context->surfaces_pool); } /** @@ -1081,16 +932,13 @@ gst_vaapi_context_apply_composition( GstVideoOverlayComposition *composition ) { - GstVaapiContextPrivate *priv; GPtrArray *curr_overlay, *next_overlay; guint i, n_rectangles; gboolean reassociate = FALSE; g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE); - priv = context->priv; - - if (!priv->surfaces) + if (!context->surfaces) return FALSE; if (!composition) { @@ -1098,8 +946,8 @@ gst_vaapi_context_apply_composition( return TRUE; } - curr_overlay = priv->overlays[priv->overlay_id]; - next_overlay = priv->overlays[priv->overlay_id ^ 1]; + curr_overlay = context->overlays[context->overlay_id]; + next_overlay = context->overlays[context->overlay_id ^ 1]; overlay_clear(next_overlay); n_rectangles = gst_video_overlay_composition_n_rectangles(composition); @@ -1126,7 +974,7 @@ gst_vaapi_context_apply_composition( } overlay_clear(curr_overlay); - priv->overlay_id ^= 1; + context->overlay_id ^= 1; if (reassociate && !overlay_reassociate(next_overlay)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 208a4381e7..82f11461f1 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -31,34 +31,14 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_CONTEXT \ - (gst_vaapi_context_get_type()) - -#define GST_VAAPI_CONTEXT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_CONTEXT, \ - GstVaapiContext)) - -#define GST_VAAPI_CONTEXT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_CONTEXT, \ - GstVaapiContextClass)) +#define GST_VAAPI_CONTEXT(obj) \ + ((GstVaapiContext *)(obj)) #define GST_VAAPI_IS_CONTEXT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_CONTEXT)) - -#define GST_VAAPI_IS_CONTEXT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_CONTEXT)) - -#define GST_VAAPI_CONTEXT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_CONTEXT, \ - GstVaapiContextClass)) + ((obj) != NULL) typedef struct _GstVaapiContext GstVaapiContext; typedef struct _GstVaapiContextInfo GstVaapiContextInfo; -typedef struct _GstVaapiContextPrivate GstVaapiContextPrivate; -typedef struct _GstVaapiContextClass GstVaapiContextClass; /** * GstVaapiContextInfo: @@ -75,31 +55,6 @@ struct _GstVaapiContextInfo { guint ref_frames; }; -/** - * GstVaapiContext: - * - * A VA context wrapper. - */ -struct _GstVaapiContext { - /*< private >*/ - GstVaapiObject parent_instance; - - GstVaapiContextPrivate *priv; -}; - -/** - * GstVaapiContextClass: - * - * A VA context wrapper class. - */ -struct _GstVaapiContextClass { - /*< private >*/ - GstVaapiObjectClass parent_class; -}; - -GType -gst_vaapi_context_get_type(void) G_GNUC_CONST; - GstVaapiContext * gst_vaapi_context_new( GstVaapiDisplay *display, @@ -110,7 +65,8 @@ gst_vaapi_context_new( ); GstVaapiContext * -gst_vaapi_context_new_full(GstVaapiDisplay *display, GstVaapiContextInfo *cip); +gst_vaapi_context_new_full(GstVaapiDisplay *display, + const GstVaapiContextInfo *cip); gboolean gst_vaapi_context_reset( @@ -122,7 +78,8 @@ gst_vaapi_context_reset( ); gboolean -gst_vaapi_context_reset_full(GstVaapiContext *context, GstVaapiContextInfo *cip); +gst_vaapi_context_reset_full(GstVaapiContext *context, + const GstVaapiContextInfo *new_cip); GstVaapiID gst_vaapi_context_get_id(GstVaapiContext *context); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 6b2b1f4de2..f5b03b7094 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -472,7 +472,7 @@ gst_vaapi_decoder_finalize(GObject *object) priv->frames = NULL; } - g_clear_object(&priv->context); + gst_vaapi_object_replace(&priv->context, NULL); priv->va_context = VA_INVALID_ID; g_clear_object(&priv->display); diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index af72bee7e5..3ed97c3069 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -30,19 +30,22 @@ #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapiimage.h" -#include "gstvaapi_priv.h" +#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, GST_VAAPI_TYPE_OBJECT) +typedef struct _GstVaapiImageClass GstVaapiImageClass; -#define GST_VAAPI_IMAGE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_IMAGE, \ - GstVaapiImagePrivate)) +/** + * GstVaapiImage: + * + * A VA image wrapper + */ +struct _GstVaapiImage { + /*< private >*/ + GstVaapiObject parent_instance; -struct _GstVaapiImagePrivate { VAImage internal_image; VAImage image; guchar *image_data; @@ -50,18 +53,17 @@ struct _GstVaapiImagePrivate { GstVaapiImageFormat format; guint width; guint height; - guint create_image : 1; - guint is_constructed : 1; guint is_linear : 1; }; -enum { - PROP_0, - - PROP_IMAGE, - PROP_FORMAT, - PROP_WIDTH, - PROP_HEIGHT +/** + * GstVaapiImageClass: + * + * A VA image wrapper class + */ +struct _GstVaapiImageClass { + /*< private >*/ + GstVaapiObjectClass parent_class; }; #define SWAP_UINT(a, b) do { \ @@ -83,35 +85,6 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image); * VAImage wrapper */ -#define VAAPI_TYPE_IMAGE vaapi_image_get_type() - -static gpointer -vaapi_image_copy(gpointer va_image) -{ - return g_slice_dup(VAImage, va_image); -} - -static void -vaapi_image_free(gpointer va_image) -{ - if (G_LIKELY(va_image)) - g_slice_free(VAImage, va_image); -} - -static GType -vaapi_image_get_type(void) -{ - static GType type = 0; - - if (G_UNLIKELY(type == 0)) - type = g_boxed_type_register_static( - "VAImage", - vaapi_image_copy, - vaapi_image_free - ); - return type; -} - static gboolean vaapi_image_is_linear(const VAImage *va_image) { @@ -173,7 +146,6 @@ static gboolean _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) { GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image); - GstVaapiImagePrivate * const priv = image->priv; const VAImageFormat *va_format; VAStatus status; @@ -188,30 +160,29 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) status = vaCreateImage( GST_VAAPI_DISPLAY_VADISPLAY(display), (VAImageFormat *)va_format, - priv->width, - priv->height, - &priv->internal_image + image->width, + image->height, + &image->internal_image ); GST_VAAPI_DISPLAY_UNLOCK(display); if (status != VA_STATUS_SUCCESS || - priv->internal_image.format.fourcc != va_format->fourcc) + image->internal_image.format.fourcc != va_format->fourcc) return FALSE; - priv->internal_format = format; + image->internal_format = format; return TRUE; } static gboolean -gst_vaapi_image_create(GstVaapiImage *image) +gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format, + guint width, guint height) { - GstVaapiImagePrivate * const priv = image->priv; - GstVaapiImageFormat format = priv->format; const VAImageFormat *va_format; VAImageID image_id; - if (!priv->create_image) - return (priv->image.image_id != VA_INVALID_ID && - priv->image.buf != VA_INVALID_ID); + image->format = format; + image->width = width; + image->height = height; if (!_gst_vaapi_image_create(image, format)) { switch (format) { @@ -228,25 +199,25 @@ gst_vaapi_image_create(GstVaapiImage *image) if (!format || !_gst_vaapi_image_create(image, format)) return FALSE; } - priv->image = priv->internal_image; - image_id = priv->image.image_id; + image->image = image->internal_image; + image_id = image->image.image_id; - if (priv->format != priv->internal_format) { - switch (priv->format) { + if (image->format != image->internal_format) { + switch (image->format) { case GST_VAAPI_IMAGE_YV12: case GST_VAAPI_IMAGE_I420: - va_format = gst_vaapi_image_format_get_va_format(priv->format); + va_format = gst_vaapi_image_format_get_va_format(image->format); if (!va_format) return FALSE; - priv->image.format = *va_format; - SWAP_UINT(priv->image.offsets[1], priv->image.offsets[2]); - SWAP_UINT(priv->image.pitches[1], priv->image.pitches[2]); + image->image.format = *va_format; + SWAP_UINT(image->image.offsets[1], image->image.offsets[2]); + SWAP_UINT(image->image.pitches[1], image->image.pitches[2]); break; default: break; } } - priv->is_linear = vaapi_image_is_linear(&priv->image); + image->is_linear = vaapi_image_is_linear(&image->image); GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id)); GST_VAAPI_OBJECT_ID(image) = image_id; @@ -254,168 +225,28 @@ gst_vaapi_image_create(GstVaapiImage *image) } static void -gst_vaapi_image_finalize(GObject *object) +gst_vaapi_image_init(GstVaapiImage *image) { - gst_vaapi_image_destroy(GST_VAAPI_IMAGE(object)); - - G_OBJECT_CLASS(gst_vaapi_image_parent_class)->finalize(object); -} - -static void -gst_vaapi_image_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiImage * const image = GST_VAAPI_IMAGE(object); - GstVaapiImagePrivate * const priv = image->priv; - - switch (prop_id) { - case PROP_IMAGE: { - const VAImage * const va_image = g_value_get_boxed(value); - if (va_image) - _gst_vaapi_image_set_image(image, va_image); - break; - } - case PROP_FORMAT: - if (priv->create_image) - priv->format = g_value_get_uint(value); - break; - case PROP_WIDTH: - if (priv->create_image) - priv->width = g_value_get_uint(value); - break; - case PROP_HEIGHT: - if (priv->create_image) - priv->height = g_value_get_uint(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_image_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiImage * const image = GST_VAAPI_IMAGE(object); - - switch (prop_id) { - case PROP_IMAGE: - g_value_set_boxed(value, &image->priv->image); - break; - case PROP_FORMAT: - g_value_set_uint(value, gst_vaapi_image_get_format(image)); - break; - case PROP_WIDTH: - g_value_set_uint(value, gst_vaapi_image_get_width(image)); - break; - case PROP_HEIGHT: - g_value_set_uint(value, gst_vaapi_image_get_height(image)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_image_constructed(GObject *object) -{ - GstVaapiImage * const image = GST_VAAPI_IMAGE(object); - GObjectClass *parent_class; - - image->priv->is_constructed = gst_vaapi_image_create(image); - - parent_class = G_OBJECT_CLASS(gst_vaapi_image_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); + image->internal_image.image_id = VA_INVALID_ID; + image->internal_image.buf = VA_INVALID_ID; + image->image.image_id = VA_INVALID_ID; + image->image.buf = VA_INVALID_ID; } static void gst_vaapi_image_class_init(GstVaapiImageClass *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiObjectClass * const object_class = + GST_VAAPI_OBJECT_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiImagePrivate)); - - object_class->finalize = gst_vaapi_image_finalize; - object_class->set_property = gst_vaapi_image_set_property; - object_class->get_property = gst_vaapi_image_get_property; - object_class->constructed = gst_vaapi_image_constructed; - - g_object_class_install_property - (object_class, - PROP_IMAGE, - g_param_spec_boxed("image", - "Image", - "The underlying VA image", - VAAPI_TYPE_IMAGE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_WIDTH, - g_param_spec_uint("width", - "width", - "The image width", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_HEIGHT, - g_param_spec_uint("height", - "heighr", - "The image height", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiImage:format: - * - * The #GstVaapiImageFormat of the image - */ - g_object_class_install_property - (object_class, - PROP_FORMAT, - g_param_spec_uint("format", - "Format", - "The underlying image format", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + object_class->init = (GstVaapiObjectInitFunc)gst_vaapi_image_init; } -static void -gst_vaapi_image_init(GstVaapiImage *image) -{ - GstVaapiImagePrivate *priv = GST_VAAPI_IMAGE_GET_PRIVATE(image); - - image->priv = priv; - priv->image_data = NULL; - priv->width = 0; - priv->height = 0; - priv->internal_format = 0; - priv->format = 0; - priv->create_image = TRUE; - priv->is_constructed = FALSE; - priv->is_linear = FALSE; - - memset(&priv->internal_image, 0, sizeof(priv->internal_image)); - priv->internal_image.image_id = VA_INVALID_ID; - priv->internal_image.buf = VA_INVALID_ID; - - memset(&priv->image, 0, sizeof(priv->image)); - priv->image.image_id = VA_INVALID_ID; - priv->image.buf = VA_INVALID_ID; -} +#define gst_vaapi_image_finalize gst_vaapi_image_destroy +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( + GstVaapiImage, + gst_vaapi_image, + gst_vaapi_image_class_init(&g_class)) /** * gst_vaapi_image_new: @@ -439,30 +270,23 @@ gst_vaapi_image_new( { GstVaapiImage *image; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); g_return_val_if_fail(width > 0, NULL); g_return_val_if_fail(height > 0, NULL); GST_DEBUG("format %" GST_FOURCC_FORMAT ", size %ux%u", GST_FOURCC_ARGS(format), width, height); - image = g_object_new( - GST_VAAPI_TYPE_IMAGE, - "display", display, - "id", GST_VAAPI_ID(VA_INVALID_ID), - "format", format, - "width", width, - "height", height, - NULL - ); + image = gst_vaapi_object_new(gst_vaapi_image_class(), display); if (!image) return NULL; - if (!image->priv->is_constructed) { - g_object_unref(image); - return NULL; - } + if (!gst_vaapi_image_create(image, format, width, height)) + goto error; return image; + +error: + gst_vaapi_object_unref(image); + return NULL; } /** @@ -482,7 +306,6 @@ gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image) { GstVaapiImage *image; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); g_return_val_if_fail(va_image, NULL); g_return_val_if_fail(va_image->image_id != VA_INVALID_ID, NULL); g_return_val_if_fail(va_image->buf != VA_INVALID_ID, NULL); @@ -492,21 +315,17 @@ gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image) GST_FOURCC_ARGS(va_image->format.fourcc), va_image->width, va_image->height); - image = g_object_new( - GST_VAAPI_TYPE_IMAGE, - "display", display, - "id", GST_VAAPI_ID(va_image->image_id), - "image", va_image, - NULL - ); + image = gst_vaapi_object_new(gst_vaapi_image_class(), display); if (!image) return NULL; - if (!image->priv->is_constructed) { - g_object_unref(image); - return NULL; - } + if (!_gst_vaapi_image_set_image(image, va_image)) + goto error; return image; + +error: + gst_vaapi_object_unref(image); + return NULL; } /** @@ -521,7 +340,6 @@ GstVaapiID gst_vaapi_image_get_id(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID); - g_return_val_if_fail(image->priv->is_constructed, VA_INVALID_ID); return GST_VAAPI_OBJECT_ID(image); } @@ -539,10 +357,9 @@ gboolean gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); - g_return_val_if_fail(image->priv->is_constructed, FALSE); if (va_image) - *va_image = image->priv->image; + *va_image = image->image; return TRUE; } @@ -564,29 +381,26 @@ gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image) gboolean _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) { - GstVaapiImagePrivate * const priv = image->priv; GstVaapiImageFormat format; VAImage alt_va_image; const VAImageFormat *alt_va_format; - if (!va_image) - return FALSE; - format = gst_vaapi_image_format(&va_image->format); if (!format) return FALSE; - priv->create_image = FALSE; - priv->internal_image = *va_image; - priv->internal_format = format; - priv->is_linear = vaapi_image_is_linear(va_image); - priv->image = *va_image; - priv->format = format; - priv->width = va_image->width; - priv->height = va_image->height; + image->internal_image = *va_image; + image->internal_format = format; + image->is_linear = vaapi_image_is_linear(va_image); + image->image = *va_image; + image->format = format; + image->width = va_image->width; + image->height = va_image->height; + + GST_VAAPI_OBJECT_ID(image) = va_image->image_id; /* Try to linearize image */ - if (!priv->is_linear) { + if (!image->is_linear) { switch (format) { case GST_VAAPI_IMAGE_I420: format = GST_VAAPI_IMAGE_YV12; @@ -605,9 +419,9 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) SWAP_UINT(alt_va_image.offsets[1], alt_va_image.offsets[2]); SWAP_UINT(alt_va_image.pitches[1], alt_va_image.pitches[2]); if (vaapi_image_is_linear(&alt_va_image)) { - priv->image = alt_va_image; - priv->format = format; - priv->is_linear = TRUE; + image->image = alt_va_image; + image->format = format; + image->is_linear = TRUE; GST_DEBUG("linearized image to %" GST_FOURCC_FORMAT " format", GST_FOURCC_ARGS(format)); } @@ -628,9 +442,8 @@ GstVaapiImageFormat gst_vaapi_image_get_format(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); - g_return_val_if_fail(image->priv->is_constructed, 0); - return image->priv->format; + return image->format; } /** @@ -645,9 +458,8 @@ guint gst_vaapi_image_get_width(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); - g_return_val_if_fail(image->priv->is_constructed, 0); - return image->priv->width; + return image->width; } /** @@ -662,9 +474,8 @@ guint gst_vaapi_image_get_height(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); - g_return_val_if_fail(image->priv->is_constructed, 0); - return image->priv->height; + return image->height; } /** @@ -679,13 +490,12 @@ void gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) { g_return_if_fail(GST_VAAPI_IS_IMAGE(image)); - g_return_if_fail(image->priv->is_constructed); if (pwidth) - *pwidth = image->priv->width; + *pwidth = image->width; if (pheight) - *pheight = image->priv->height; + *pheight = image->height; } /** @@ -702,9 +512,8 @@ gboolean gst_vaapi_image_is_linear(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); - g_return_val_if_fail(image->priv->is_constructed, FALSE); - return image->priv->is_linear; + return image->is_linear; } /** @@ -718,14 +527,13 @@ gst_vaapi_image_is_linear(GstVaapiImage *image) static inline gboolean _gst_vaapi_image_is_mapped(GstVaapiImage *image) { - return image->priv->image_data != NULL; + return image->image_data != NULL; } gboolean gst_vaapi_image_is_mapped(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); - g_return_val_if_fail(image->priv->is_constructed, FALSE); return _gst_vaapi_image_is_mapped(image); } @@ -743,7 +551,6 @@ gboolean gst_vaapi_image_map(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); - g_return_val_if_fail(image->priv->is_constructed, FALSE); return _gst_vaapi_image_map(image, NULL); } @@ -751,7 +558,6 @@ gst_vaapi_image_map(GstVaapiImage *image) gboolean _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image) { - GstVaapiImagePrivate * const priv = image->priv; GstVaapiDisplay *display; VAStatus status; guint i; @@ -766,8 +572,8 @@ _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image) GST_VAAPI_DISPLAY_LOCK(display); status = vaMapBuffer( GST_VAAPI_DISPLAY_VADISPLAY(display), - priv->image.buf, - (void **)&priv->image_data + image->image.buf, + (void **)&image->image_data ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaMapBuffer()")) @@ -775,13 +581,13 @@ _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image) map_success: if (raw_image) { - const VAImage * const va_image = &priv->image; - raw_image->format = priv->format; + const VAImage * const va_image = &image->image; + raw_image->format = image->format; raw_image->width = va_image->width; raw_image->height = va_image->height; raw_image->num_planes = va_image->num_planes; for (i = 0; i < raw_image->num_planes; i++) { - raw_image->pixels[i] = (guchar *)priv->image_data + + raw_image->pixels[i] = (guchar *)image->image_data + va_image->offsets[i]; raw_image->stride[i] = va_image->pitches[i]; } @@ -802,7 +608,6 @@ gboolean gst_vaapi_image_unmap(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); - g_return_val_if_fail(image->priv->is_constructed, FALSE); return _gst_vaapi_image_unmap(image); } @@ -823,13 +628,13 @@ _gst_vaapi_image_unmap(GstVaapiImage *image) GST_VAAPI_DISPLAY_LOCK(display); status = vaUnmapBuffer( GST_VAAPI_DISPLAY_VADISPLAY(display), - image->priv->image.buf + image->image.buf ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaUnmapBuffer()")) return FALSE; - image->priv->image_data = NULL; + image->image_data = NULL; return TRUE; } @@ -846,10 +651,9 @@ guint gst_vaapi_image_get_plane_count(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); - g_return_val_if_fail(image->priv->is_constructed, FALSE); g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0); - return image->priv->image.num_planes; + return image->image.num_planes; } /** @@ -866,11 +670,10 @@ guchar * gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); - g_return_val_if_fail(image->priv->is_constructed, FALSE); g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL); - g_return_val_if_fail(plane < image->priv->image.num_planes, NULL); + g_return_val_if_fail(plane < image->image.num_planes, NULL); - return image->priv->image_data + image->priv->image.offsets[plane]; + return image->image_data + image->image.offsets[plane]; } /** @@ -887,11 +690,10 @@ guint gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); - g_return_val_if_fail(image->priv->is_constructed, FALSE); g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0); - g_return_val_if_fail(plane < image->priv->image.num_planes, 0); + g_return_val_if_fail(plane < image->image.num_planes, 0); - return image->priv->image.pitches[plane]; + return image->image.pitches[plane]; } /** @@ -908,9 +710,8 @@ guint gst_vaapi_image_get_data_size(GstVaapiImage *image) { g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); - g_return_val_if_fail(image->priv->is_constructed, FALSE); - return image->priv->image.data_size; + return image->image.data_size; } #if GST_CHECK_VERSION(1,0,0) @@ -1175,21 +976,17 @@ gst_vaapi_image_get_buffer( GstVaapiRectangle *rect ) { - GstVaapiImagePrivate *priv; GstVaapiImageRaw dst_image, src_image; gboolean success; g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); - g_return_val_if_fail(image->priv->is_constructed, FALSE); g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE); - priv = image->priv; - if (!init_image_from_buffer(&dst_image, buffer)) return FALSE; - if (dst_image.format != priv->format) + if (dst_image.format != image->format) return FALSE; - if (dst_image.width != priv->width || dst_image.height != priv->height) + if (dst_image.width != image->width || dst_image.height != image->height) return FALSE; if (!_gst_vaapi_image_map(image, &src_image)) @@ -1226,7 +1023,6 @@ gst_vaapi_image_get_raw( gboolean success; g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); - g_return_val_if_fail(image->priv->is_constructed, FALSE); if (!_gst_vaapi_image_map(image, &src_image)) return FALSE; @@ -1258,21 +1054,17 @@ gst_vaapi_image_update_from_buffer( GstVaapiRectangle *rect ) { - GstVaapiImagePrivate *priv; GstVaapiImageRaw dst_image, src_image; gboolean success; g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); - g_return_val_if_fail(image->priv->is_constructed, FALSE); g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE); - priv = image->priv; - if (!init_image_from_buffer(&src_image, buffer)) return FALSE; - if (src_image.format != priv->format) + if (src_image.format != image->format) return FALSE; - if (src_image.width != priv->width || src_image.height != priv->height) + if (src_image.width != image->width || src_image.height != image->height) return FALSE; if (!_gst_vaapi_image_map(image, &dst_image)) @@ -1310,7 +1102,6 @@ gst_vaapi_image_update_from_raw( gboolean success; g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); - g_return_val_if_fail(image->priv->is_constructed, FALSE); if (!_gst_vaapi_image_map(image, &dst_image)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index d0c3cf3053..8b9abf51d9 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -30,29 +30,11 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_IMAGE \ - (gst_vaapi_image_get_type()) - -#define GST_VAAPI_IMAGE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_IMAGE, \ - GstVaapiImage)) - -#define GST_VAAPI_IMAGE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_IMAGE, \ - GstVaapiImageClass)) +#define GST_VAAPI_IMAGE(obj) \ + ((GstVaapiImage *)(obj)) #define GST_VAAPI_IS_IMAGE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_IMAGE)) - -#define GST_VAAPI_IS_IMAGE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_IMAGE)) - -#define GST_VAAPI_IMAGE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_IMAGE, \ - GstVaapiImageClass)) + ((obj) != NULL) /** * GST_VAAPI_IMAGE_FORMAT: @@ -79,32 +61,8 @@ G_BEGIN_DECLS #define GST_VAAPI_IMAGE_HEIGHT(image) gst_vaapi_image_get_height(image) typedef struct _GstVaapiImage GstVaapiImage; -typedef struct _GstVaapiImagePrivate GstVaapiImagePrivate; -typedef struct _GstVaapiImageClass GstVaapiImageClass; typedef struct _GstVaapiImageRaw GstVaapiImageRaw; -/** - * GstVaapiImage: - * - * A VA image wrapper - */ -struct _GstVaapiImage { - /*< private >*/ - GstVaapiObject parent_instance; - - GstVaapiImagePrivate *priv; -}; - -/** - * GstVaapiImageClass: - * - * A VA image wrapper class - */ -struct _GstVaapiImageClass { - /*< private >*/ - GstVaapiObjectClass parent_class; -}; - /** * GstVaapiImageRaw: * @@ -120,9 +78,6 @@ struct _GstVaapiImageRaw { guint stride[3]; }; -GType -gst_vaapi_image_get_type(void) G_GNUC_CONST; - GstVaapiImage * gst_vaapi_image_new( GstVaapiDisplay *display, diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 3d6d4413b8..eb510265de 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -30,37 +30,41 @@ #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapisubpicture.h" -#include "gstvaapi_priv.h" +#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, GST_VAAPI_TYPE_OBJECT) +typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass; -#define GST_VAAPI_SUBPICTURE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_SUBPICTURE, \ - GstVaapiSubpicturePrivate)) +/** + * GstVaapiSubpicture: + * + * A VA subpicture wrapper + */ +struct _GstVaapiSubpicture { + /*< private >*/ + GstVaapiObject parent_instance; -struct _GstVaapiSubpicturePrivate { GstVaapiImage *image; guint flags; gfloat global_alpha; }; -enum { - PROP_0, - - PROP_FLAGS, - PROP_GLOBAL_ALPHA, - PROP_IMAGE +/** + * GstVaapiSubpictureClass: + * + * A VA subpicture wrapper class + */ +struct _GstVaapiSubpictureClass { + /*< private >*/ + GstVaapiObjectClass parent_class; }; static void gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) { GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture); - GstVaapiSubpicturePrivate * const priv = subpicture->priv; VASubpictureID subpicture_id; VAStatus status; @@ -82,25 +86,21 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) } GST_VAAPI_OBJECT_ID(subpicture) = VA_INVALID_ID; } - - g_clear_object(&priv->image); + gst_vaapi_object_replace(&subpicture->image, NULL); } static gboolean -gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture) +gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture, + GstVaapiImage *image) { GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture); - GstVaapiSubpicturePrivate * const priv = subpicture->priv; VASubpictureID subpicture_id; VAStatus status; - if (!priv->image) - return FALSE; - GST_VAAPI_DISPLAY_LOCK(display); status = vaCreateSubpicture( GST_VAAPI_DISPLAY_VADISPLAY(display), - GST_VAAPI_OBJECT_ID(priv->image), + GST_VAAPI_OBJECT_ID(image), &subpicture_id ); GST_VAAPI_DISPLAY_UNLOCK(display); @@ -110,134 +110,12 @@ gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture) GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(subpicture_id)); GST_VAAPI_OBJECT_ID(subpicture) = subpicture_id; + subpicture->image = gst_vaapi_object_ref(image); return TRUE; } -static void -gst_vaapi_subpicture_finalize(GObject *object) -{ - gst_vaapi_subpicture_destroy(GST_VAAPI_SUBPICTURE(object)); - - G_OBJECT_CLASS(gst_vaapi_subpicture_parent_class)->finalize(object); -} - -static void -gst_vaapi_subpicture_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object); - - switch (prop_id) { - case PROP_FLAGS: - subpicture->priv->flags = g_value_get_uint(value); - break; - case PROP_GLOBAL_ALPHA: - gst_vaapi_subpicture_set_global_alpha(subpicture, - g_value_get_float(value)); - break; - case PROP_IMAGE: - gst_vaapi_subpicture_set_image(subpicture, g_value_get_object(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_subpicture_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object); - - switch (prop_id) { - case PROP_FLAGS: - g_value_set_uint(value, subpicture->priv->flags); - break; - case PROP_GLOBAL_ALPHA: - g_value_set_float(value, - gst_vaapi_subpicture_get_global_alpha(subpicture)); - break; - case PROP_IMAGE: - g_value_set_object(value, gst_vaapi_subpicture_get_image(subpicture)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_subpicture_class_init(GstVaapiSubpictureClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiSubpicturePrivate)); - - object_class->finalize = gst_vaapi_subpicture_finalize; - object_class->set_property = gst_vaapi_subpicture_set_property; - object_class->get_property = gst_vaapi_subpicture_get_property; - - /** - * GstVaapiSubpicture:flags: - * - * The #GstVaapiSubpictureFlags this subpicture requires. - */ - g_object_class_install_property - (object_class, - PROP_FLAGS, - g_param_spec_uint("flags", - "Flags", - "The GstVaapiSubpictureFlags this subpicture requires", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiSubpicture:global-alpha: - * - * The global-alpha value associated with this subpicture. - */ - g_object_class_install_property - (object_class, - PROP_GLOBAL_ALPHA, - g_param_spec_float("global-alpha", - "Global Alpha", - "The global-alpha value associated with this subpicture", - 0.0f, 1.0f, 1.0f, - G_PARAM_READWRITE)); - - /** - * GstVaapiSubpicture:image: - * - * The #GstVaapiImage this subpicture is bound to. - */ - g_object_class_install_property - (object_class, - PROP_IMAGE, - g_param_spec_object("image", - "Image", - "The GstVaapiImage this subpicture is bound to", - GST_VAAPI_TYPE_IMAGE, - G_PARAM_READWRITE)); -} - -static void -gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture) -{ - GstVaapiSubpicturePrivate *priv = GST_VAAPI_SUBPICTURE_GET_PRIVATE(subpicture); - - subpicture->priv = priv; - priv->image = NULL; - priv->global_alpha = 1.0f; -} +#define gst_vaapi_subpicture_finalize gst_vaapi_subpicture_destroy +GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiSubpicture, gst_vaapi_subpicture) /** * gst_vaapi_subpicture_new: @@ -252,6 +130,7 @@ gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture) GstVaapiSubpicture * gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags) { + GstVaapiSubpicture *subpicture; GstVaapiDisplay *display; GstVaapiImageFormat format; guint va_flags; @@ -268,13 +147,18 @@ gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags) if (flags & ~va_flags) return NULL; - return g_object_new(GST_VAAPI_TYPE_SUBPICTURE, - "display", GST_VAAPI_OBJECT_DISPLAY(image), - "id", GST_VAAPI_ID(VA_INVALID_ID), - "flags", flags, - "global-alpha", 1.0f, - "image", image, - NULL); + subpicture = gst_vaapi_object_new(gst_vaapi_subpicture_class(), display); + if (!subpicture) + return NULL; + + subpicture->global_alpha = 1.0f; + if (!gst_vaapi_subpicture_set_image(subpicture, image)) + goto error; + return subpicture; + +error: + gst_vaapi_object_unref(subpicture); + return NULL; } /** @@ -358,12 +242,12 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( raw_image.stride[0] = stride; if (!gst_vaapi_image_update_from_raw(image, &raw_image, NULL)) { GST_WARNING("could not update VA image with subtitle data"); - g_object_unref(image); + gst_vaapi_object_unref(image); return NULL; } subpicture = gst_vaapi_subpicture_new(image, flags); - g_object_unref(image); + gst_vaapi_object_unref(image); #if GST_CHECK_VERSION(1,0,0) gst_video_meta_unmap(vmeta, 0, &map_info); #endif @@ -407,7 +291,7 @@ gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture) { g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 0); - return subpicture->priv->flags; + return subpicture->flags; } /** @@ -423,7 +307,7 @@ gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture) { g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), NULL); - return subpicture->priv->image; + return subpicture->image; } /** @@ -433,20 +317,18 @@ gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture) * * Binds a new #GstVaapiImage to the @subpicture. The reference to the * previous image is released and a new one is acquired on @image. + * + * Return value: %TRUE on success */ -void -gst_vaapi_subpicture_set_image( - GstVaapiSubpicture *subpicture, - GstVaapiImage *image -) +gboolean +gst_vaapi_subpicture_set_image(GstVaapiSubpicture *subpicture, + GstVaapiImage *image) { - g_return_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture)); - g_return_if_fail(GST_VAAPI_IS_IMAGE(image)); + g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); gst_vaapi_subpicture_destroy(subpicture); - - subpicture->priv->image = g_object_ref(image); - gst_vaapi_subpicture_create(subpicture); + return gst_vaapi_subpicture_create(subpicture, image); } /** @@ -462,7 +344,7 @@ gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture) { g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 1.0); - return subpicture->priv->global_alpha; + return subpicture->global_alpha; } /** @@ -480,18 +362,15 @@ gboolean gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture, gfloat global_alpha) { - GstVaapiSubpicturePrivate *priv; GstVaapiDisplay *display; VAStatus status; g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); - priv = subpicture->priv; - - if (!(priv->flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA)) + if (!(subpicture->flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA)) return FALSE; - if (priv->global_alpha == global_alpha) + if (subpicture->global_alpha == global_alpha) return TRUE; display = GST_VAAPI_OBJECT_DISPLAY(subpicture); @@ -506,6 +385,6 @@ gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture, if (!vaapi_check_status(status, "vaSetSubpictureGlobalAlpha()")) return FALSE; - priv->global_alpha = global_alpha; + subpicture->global_alpha = global_alpha; return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 674f5ce726..c7fb05311a 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -30,33 +30,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_SUBPICTURE \ - (gst_vaapi_subpicture_get_type()) - -#define GST_VAAPI_SUBPICTURE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_SUBPICTURE, \ - GstVaapiSubpicture)) - -#define GST_VAAPI_SUBPICTURE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_SUBPICTURE, \ - GstVaapiSubpictureClass)) +#define GST_VAAPI_SUBPICTURE(obj) \ + ((GstVaapiSubpicture *)(obj)) #define GST_VAAPI_IS_SUBPICTURE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SUBPICTURE)) - -#define GST_VAAPI_IS_SUBPICTURE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SUBPICTURE)) - -#define GST_VAAPI_SUBPICTURE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_SUBPICTURE, \ - GstVaapiSubpictureClass)) + ((obj) != NULL) typedef struct _GstVaapiSubpicture GstVaapiSubpicture; -typedef struct _GstVaapiSubpicturePrivate GstVaapiSubpicturePrivate; -typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass; /** * GstVaapiSubpictureFlags: @@ -73,31 +53,6 @@ typedef enum { GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA = (1 << 1), } GstVaapiSubpictureFlags; -/** - * GstVaapiSubpicture: - * - * A VA subpicture wrapper - */ -struct _GstVaapiSubpicture { - /*< private >*/ - GstVaapiObject parent_instance; - - GstVaapiSubpicturePrivate *priv; -}; - -/** - * GstVaapiSubpictureClass: - * - * A VA subpicture wrapper class - */ -struct _GstVaapiSubpictureClass { - /*< private >*/ - GstVaapiObjectClass parent_class; -}; - -GType -gst_vaapi_subpicture_get_type(void) G_GNUC_CONST; - GstVaapiSubpicture * gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags); @@ -116,11 +71,9 @@ gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture); GstVaapiImage * gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture); -void -gst_vaapi_subpicture_set_image( - GstVaapiSubpicture *subpicture, - GstVaapiImage *image -); +gboolean +gst_vaapi_subpicture_set_image(GstVaapiSubpicture *subpicture, + GstVaapiImage *image); gfloat gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index d9c676ceeb..1c5992808a 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -30,21 +30,24 @@ #include "gstvaapiutils.h" #include "gstvaapisurface.h" #include "gstvaapisurface_priv.h" +#include "gstvaapiobject_priv.h" #include "gstvaapicontext.h" #include "gstvaapiimage.h" -#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiSurface, gst_vaapi_surface, GST_VAAPI_TYPE_OBJECT) +typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; -#define GST_VAAPI_SURFACE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_SURFACE, \ - GstVaapiSurfacePrivate)) +/** + * GstVaapiSurface: + * + * A VA surface wrapper. + */ +struct _GstVaapiSurface { + /*< private >*/ + GstVaapiObject parent_instance; -struct _GstVaapiSurfacePrivate { guint width; guint height; GstVaapiChromaType chroma_type; @@ -52,13 +55,14 @@ struct _GstVaapiSurfacePrivate { GstVaapiContext *parent_context; }; -enum { - PROP_0, - - PROP_WIDTH, - PROP_HEIGHT, - PROP_CHROMA_TYPE, - PROP_PARENT_CONTEXT +/** + * GstVaapiSurfaceClass: + * + * A VA surface wrapper class. + */ +struct _GstVaapiSurfaceClass { + /*< private >*/ + GstVaapiObjectClass parent_class; }; static gboolean @@ -79,18 +83,17 @@ static void destroy_subpicture_cb(gpointer subpicture, gpointer surface) { _gst_vaapi_surface_deassociate_subpicture(surface, subpicture); - g_object_unref(subpicture); + gst_vaapi_object_unref(subpicture); } static void gst_vaapi_surface_destroy_subpictures(GstVaapiSurface *surface) { - GstVaapiSurfacePrivate * const priv = surface->priv; - - if (priv->subpictures) { - g_ptr_array_foreach(priv->subpictures, destroy_subpicture_cb, surface); - g_ptr_array_free(priv->subpictures, TRUE); - priv->subpictures = NULL; + if (surface->subpictures) { + g_ptr_array_foreach(surface->subpictures, destroy_subpicture_cb, + surface); + g_ptr_array_free(surface->subpictures, TRUE); + surface->subpictures = NULL; } } @@ -122,15 +125,15 @@ gst_vaapi_surface_destroy(GstVaapiSurface *surface) } static gboolean -gst_vaapi_surface_create(GstVaapiSurface *surface) +gst_vaapi_surface_create(GstVaapiSurface *surface, + GstVaapiChromaType chroma_type, guint width, guint height) { GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface); - GstVaapiSurfacePrivate * const priv = surface->priv; VASurfaceID surface_id; VAStatus status; guint format; - switch (priv->chroma_type) { + switch (chroma_type) { case GST_VAAPI_CHROMA_TYPE_YUV420: format = VA_RT_FORMAT_YUV420; break; @@ -141,168 +144,31 @@ gst_vaapi_surface_create(GstVaapiSurface *surface) format = VA_RT_FORMAT_YUV444; break; default: - GST_DEBUG("unsupported chroma-type %u\n", priv->chroma_type); + GST_DEBUG("unsupported chroma-type %u\n", chroma_type); return FALSE; } GST_VAAPI_DISPLAY_LOCK(display); status = vaCreateSurfaces( GST_VAAPI_DISPLAY_VADISPLAY(display), - priv->width, - priv->height, - format, + width, height, format, 1, &surface_id ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaCreateSurfaces()")) return FALSE; + surface->chroma_type = chroma_type; + surface->width = width; + surface->height = height; + GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); GST_VAAPI_OBJECT_ID(surface) = surface_id; return TRUE; } -static void -gst_vaapi_surface_finalize(GObject *object) -{ - gst_vaapi_surface_destroy(GST_VAAPI_SURFACE(object)); - - G_OBJECT_CLASS(gst_vaapi_surface_parent_class)->finalize(object); -} - -static void -gst_vaapi_surface_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); - GstVaapiSurfacePrivate * const priv = surface->priv; - - switch (prop_id) { - case PROP_WIDTH: - priv->width = g_value_get_uint(value); - break; - case PROP_HEIGHT: - priv->height = g_value_get_uint(value); - break; - case PROP_CHROMA_TYPE: - priv->chroma_type = g_value_get_uint(value); - break; - case PROP_PARENT_CONTEXT: - gst_vaapi_surface_set_parent_context(surface, g_value_get_object(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_surface_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); - - switch (prop_id) { - case PROP_WIDTH: - g_value_set_uint(value, gst_vaapi_surface_get_width(surface)); - break; - case PROP_HEIGHT: - g_value_set_uint(value, gst_vaapi_surface_get_height(surface)); - break; - case PROP_CHROMA_TYPE: - g_value_set_uint(value, gst_vaapi_surface_get_chroma_type(surface)); - break; - case PROP_PARENT_CONTEXT: - g_value_set_object(value, gst_vaapi_surface_get_parent_context(surface)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_surface_constructed(GObject *object) -{ - GstVaapiSurface * const surface = GST_VAAPI_SURFACE(object); - GObjectClass *parent_class; - - gst_vaapi_surface_create(surface); - - parent_class = G_OBJECT_CLASS(gst_vaapi_surface_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); -} - -static void -gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiSurfacePrivate)); - - object_class->finalize = gst_vaapi_surface_finalize; - object_class->set_property = gst_vaapi_surface_set_property; - object_class->get_property = gst_vaapi_surface_get_property; - object_class->constructed = gst_vaapi_surface_constructed; - - g_object_class_install_property - (object_class, - PROP_WIDTH, - g_param_spec_uint("width", - "Width", - "The width of the surface", - 0, G_MAXINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_HEIGHT, - g_param_spec_uint("height", - "Height", - "The height of the surface", - 0, G_MAXINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_CHROMA_TYPE, - g_param_spec_uint("chroma-type", - "Chroma type", - "The chroma type of the surface", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_PARENT_CONTEXT, - g_param_spec_object("parent-context", - "Parent Context", - "The parent context, if any", - GST_VAAPI_TYPE_CONTEXT, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); -} - -static void -gst_vaapi_surface_init(GstVaapiSurface *surface) -{ - GstVaapiSurfacePrivate *priv = GST_VAAPI_SURFACE_GET_PRIVATE(surface); - - surface->priv = priv; - priv->width = 0; - priv->height = 0; - priv->chroma_type = 0; - priv->subpictures = NULL; - priv->parent_context = NULL; -} +#define gst_vaapi_surface_finalize gst_vaapi_surface_destroy +GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiSurface, gst_vaapi_surface) /** * gst_vaapi_surface_new: @@ -324,15 +190,21 @@ gst_vaapi_surface_new( guint height ) { + GstVaapiSurface *surface; + GST_DEBUG("size %ux%u, chroma type 0x%x", width, height, chroma_type); - return g_object_new(GST_VAAPI_TYPE_SURFACE, - "display", display, - "id", GST_VAAPI_ID(VA_INVALID_ID), - "width", width, - "height", height, - "chroma-type", chroma_type, - NULL); + surface = gst_vaapi_object_new(gst_vaapi_surface_class(), display); + if (!surface) + return NULL; + + if (!gst_vaapi_surface_create(surface, chroma_type, width, height)) + goto error; + return surface; + +error: + gst_vaapi_object_unref(surface); + return NULL; } /** @@ -364,7 +236,7 @@ gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); - return surface->priv->chroma_type; + return surface->chroma_type; } /** @@ -380,7 +252,7 @@ gst_vaapi_surface_get_width(GstVaapiSurface *surface) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); - return surface->priv->width; + return surface->width; } /** @@ -396,7 +268,7 @@ gst_vaapi_surface_get_height(GstVaapiSurface *surface) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); - return surface->priv->height; + return surface->height; } /** @@ -438,16 +310,9 @@ gst_vaapi_surface_set_parent_context( GstVaapiContext *context ) { - GstVaapiSurfacePrivate *priv; - g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); - priv = surface->priv; - - g_clear_object(&priv->parent_context); - - if (context) - priv->parent_context = g_object_ref(context); + gst_vaapi_object_replace(&surface->parent_context, context); } /** @@ -465,7 +330,7 @@ gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface) { g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); - return surface->priv->parent_context; + return surface->parent_context; } /** @@ -487,7 +352,7 @@ gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface) * unreferenced when it's no longer needed. The image and image buffer * data structures will be destroyed. However, the surface contents * will remain unchanged until destroyed through the last call to - * g_object_unref(). + * gst_vaapi_object_unref(). * * Return value: the newly allocated #GstVaapiImage object, or %NULL * on failure @@ -546,7 +411,7 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) return FALSE; gst_vaapi_image_get_size(image, &width, &height); - if (width != surface->priv->width || height != surface->priv->height) + if (width != surface->width || height != surface->height) return FALSE; image_id = GST_VAAPI_OBJECT_ID(image); @@ -593,7 +458,7 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) return FALSE; gst_vaapi_image_get_size(image, &width, &height); - if (width != surface->priv->width || height != surface->priv->height) + if (width != surface->width || height != surface->height) return FALSE; image_id = GST_VAAPI_OBJECT_ID(image); @@ -646,15 +511,16 @@ gst_vaapi_surface_associate_subpicture( g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); - if (!surface->priv->subpictures) { - surface->priv->subpictures = g_ptr_array_new(); - if (!surface->priv->subpictures) + if (!surface->subpictures) { + surface->subpictures = g_ptr_array_new(); + if (!surface->subpictures) return FALSE; } - if (g_ptr_array_remove_fast(surface->priv->subpictures, subpicture)) { - success = _gst_vaapi_surface_deassociate_subpicture(surface, subpicture); - g_object_unref(subpicture); + if (g_ptr_array_remove_fast(surface->subpictures, subpicture)) { + success = _gst_vaapi_surface_deassociate_subpicture(surface, + subpicture); + gst_vaapi_object_unref(subpicture); if (!success) return FALSE; } @@ -668,7 +534,7 @@ gst_vaapi_surface_associate_subpicture( if (!success) return FALSE; - g_ptr_array_add(surface->priv->subpictures, g_object_ref(subpicture)); + g_ptr_array_add(surface->subpictures, gst_vaapi_object_ref(subpicture)); return TRUE; } @@ -712,8 +578,8 @@ _gst_vaapi_surface_associate_subpicture( dst_rect = &dst_rect_default; dst_rect_default.x = 0; dst_rect_default.y = 0; - dst_rect_default.width = surface->priv->width; - dst_rect_default.height = surface->priv->height; + dst_rect_default.width = surface->width; + dst_rect_default.height = surface->height; } GST_VAAPI_DISPLAY_LOCK(display); @@ -752,11 +618,11 @@ gst_vaapi_surface_deassociate_subpicture( g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); - if (!surface->priv->subpictures) + if (!surface->subpictures) return TRUE; /* First, check subpicture was really associated with this surface */ - if (!g_ptr_array_remove_fast(surface->priv->subpictures, subpicture)) { + if (!g_ptr_array_remove_fast(surface->subpictures, subpicture)) { GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT " was not bound to " "surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(subpicture)), @@ -765,7 +631,7 @@ gst_vaapi_surface_deassociate_subpicture( } success = _gst_vaapi_surface_deassociate_subpicture(surface, subpicture); - g_object_unref(subpicture); + gst_vaapi_object_unref(subpicture); return success; } @@ -894,11 +760,9 @@ gst_vaapi_surface_set_subpictures_from_composition( g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - if (propagate_context) { - GstVaapiContext * const context = surface->priv->parent_context; - if (context) - return gst_vaapi_context_apply_composition(context, composition); - } + if (propagate_context && surface->parent_context) + return gst_vaapi_context_apply_composition(surface->parent_context, + composition); display = GST_VAAPI_OBJECT_DISPLAY(surface); if (!display) @@ -929,10 +793,10 @@ gst_vaapi_surface_set_subpictures_from_composition( if (!gst_vaapi_surface_associate_subpicture (surface, subpicture, NULL, &sub_rect)) { GST_WARNING ("could not render overlay rectangle %p", rect); - g_object_unref (subpicture); + gst_vaapi_object_unref (subpicture); return FALSE; } - g_object_unref (subpicture); + gst_vaapi_object_unref (subpicture); } return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 21f43cfd66..0d36fe9892 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -112,60 +112,15 @@ typedef enum { GST_VAAPI_COLOR_STANDARD_ITUR_BT_709 = 1 << 3, } GstVaapiSurfaceRenderFlags; -#define GST_VAAPI_TYPE_SURFACE \ - (gst_vaapi_surface_get_type()) - -#define GST_VAAPI_SURFACE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_SURFACE, \ - GstVaapiSurface)) - -#define GST_VAAPI_SURFACE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_SURFACE, \ - GstVaapiSurfaceClass)) +#define GST_VAAPI_SURFACE(obj) \ + ((GstVaapiSurface *)(obj)) #define GST_VAAPI_IS_SURFACE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SURFACE)) - -#define GST_VAAPI_IS_SURFACE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SURFACE)) - -#define GST_VAAPI_SURFACE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_SURFACE, \ - GstVaapiSurfaceClass)) + ((obj) != NULL) typedef struct _GstVaapiSurface GstVaapiSurface; -typedef struct _GstVaapiSurfacePrivate GstVaapiSurfacePrivate; -typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; -/** - * GstVaapiSurface: - * - * A VA surface wrapper. - */ -struct _GstVaapiSurface { - /*< private >*/ - GstVaapiObject parent_instance; - - GstVaapiSurfacePrivate *priv; -}; - -/** - * GstVaapiSurfaceClass: - * - * A VA surface wrapper class. - */ -struct _GstVaapiSurfaceClass { - /*< private >*/ - GstVaapiObjectClass parent_class; -}; - -GType -gst_vaapi_surface_get_type(void) G_GNUC_CONST; - GstVaapiSurface * gst_vaapi_surface_new( GstVaapiDisplay *display, diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index c0827b78c8..9479866fbf 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -41,7 +41,7 @@ gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) if (proxy->surface) { if (proxy->pool) gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface); - g_object_unref(proxy->surface); + gst_vaapi_object_unref(proxy->surface); proxy->surface = NULL; } g_clear_object(&proxy->pool); @@ -76,7 +76,7 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) proxy->timestamp = GST_CLOCK_TIME_NONE; proxy->duration = GST_CLOCK_TIME_NONE; proxy->destroy_func = NULL; - g_object_ref(proxy->surface); + gst_vaapi_object_ref(proxy->surface); return proxy; error: diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 3c2dd63bf3..ded8ec9711 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -27,6 +27,7 @@ #include "sysdeps.h" #include "gstvaapivideopool.h" +#include "gstvaapiobject.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -75,13 +76,13 @@ gst_vaapi_video_pool_clear(GstVaapiVideoPool *pool) for (list = priv->used_objects; list; list = next) { next = list->next; - g_object_unref(list->data); + gst_vaapi_object_unref(list->data); g_list_free_1(list); } priv->used_objects = NULL; while ((object = g_queue_pop_head(&priv->free_objects))) - g_object_unref(object); + gst_vaapi_object_unref(object); } static void @@ -313,7 +314,7 @@ gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) ++priv->used_count; priv->used_objects = g_list_prepend(priv->used_objects, object); - return g_object_ref(object); + return gst_vaapi_object_ref(object); } /** @@ -333,14 +334,14 @@ gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) GList *elem; g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool)); - g_return_if_fail(G_IS_OBJECT(object)); + g_return_if_fail(GST_VAAPI_IS_OBJECT(object)); priv = pool->priv; elem = g_list_find(priv->used_objects, object); if (!elem) return; - g_object_unref(object); + gst_vaapi_object_unref(object); --priv->used_count; priv->used_objects = g_list_delete_link(priv->used_objects, elem); g_queue_push_tail(&priv->free_objects, object); @@ -361,9 +362,9 @@ gboolean gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object) { g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE); - g_return_val_if_fail(G_IS_OBJECT(object), FALSE); + g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), FALSE); - g_queue_push_tail(&pool->priv->free_objects, g_object_ref(object)); + g_queue_push_tail(&pool->priv->free_objects, gst_vaapi_object_ref(object)); return TRUE; } From 8402b04ac9149f67e101f7b49d1c5f65e514a3b7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 30 Apr 2013 17:20:14 +0200 Subject: [PATCH 1176/3781] libs: use GstVaapiObject for window objects. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapiwindow.c | 292 +++++++------------ gst-libs/gst/vaapi/gstvaapiwindow.h | 77 +---- gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 89 +++--- gst-libs/gst/vaapi/gstvaapiwindow_drm.h | 48 +-- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 264 +++++++---------- gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 52 +--- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 131 +++++++++ gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 108 ++++--- gst-libs/gst/vaapi/gstvaapiwindow_wayland.h | 51 ---- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 125 +++----- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 58 +--- gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 83 ++++++ 13 files changed, 573 insertions(+), 807 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_priv.h create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index d783d8df1d..10ea08a8cf 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -117,6 +117,7 @@ libgstvaapi_source_priv_h = \ gstvaapisurfaceproxy_priv.h \ gstvaapiutils.h \ gstvaapiversion.h \ + gstvaapiwindow_priv.h \ gstvaapiworkarounds.h \ sysdeps.h \ $(NULL) @@ -162,6 +163,7 @@ libgstvaapi_x11_source_priv_h = \ gstvaapidisplay_x11_priv.h \ gstvaapiutils.h \ gstvaapiutils_x11.h \ + gstvaapiwindow_x11_priv.h \ $(NULL) libgstvaapi_glx_source_c = \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 9fb41489cc..2031c89b4b 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -27,209 +27,141 @@ #include "sysdeps.h" #include "gstvaapiwindow.h" -#include "gstvaapi_priv.h" +#include "gstvaapiwindow_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, GST_VAAPI_TYPE_OBJECT) - -#define GST_VAAPI_WINDOW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_WINDOW, \ - GstVaapiWindowPrivate)) - -struct _GstVaapiWindowPrivate { - guint width; - guint height; - guint display_width; - guint display_height; - gboolean is_constructed : 1; - guint is_fullscreen : 1; - guint check_geometry : 1; -}; - -enum { - PROP_0, - - PROP_WIDTH, - PROP_HEIGHT, - PROP_FULLSCREEN -}; +/* Ensure those symbols are actually defined in the resulting libraries */ +#undef gst_vaapi_window_ref +#undef gst_vaapi_window_unref +#undef gst_vaapi_window_replace static void gst_vaapi_window_ensure_size(GstVaapiWindow *window) { - GstVaapiWindowPrivate * const priv = window->priv; - GstVaapiWindowClass * const klass = GST_VAAPI_WINDOW_GET_CLASS(window); + const GstVaapiWindowClass * const klass = + GST_VAAPI_WINDOW_GET_CLASS(window); - if (!priv->check_geometry) + if (!window->check_geometry) return; if (klass->get_geometry) - klass->get_geometry(window, NULL, NULL, &priv->width, &priv->height); + klass->get_geometry(window, NULL, NULL, + &window->width, &window->height); - priv->check_geometry = FALSE; - priv->is_fullscreen = (priv->width == priv->display_width && - priv->height == priv->display_height); -} - -static void -gst_vaapi_window_destroy(GstVaapiWindow *window) -{ - GST_VAAPI_WINDOW_GET_CLASS(window)->destroy(window); + window->check_geometry = FALSE; + window->is_fullscreen = (window->width == window->display_width && + window->height == window->display_height); } static gboolean -gst_vaapi_window_create(GstVaapiWindow *window) +gst_vaapi_window_create(GstVaapiWindow *window, guint width, guint height) { - GstVaapiWindowPrivate * const priv = window->priv; - guint width, height; - - width = priv->width; - height = priv->height; - gst_vaapi_display_get_size( GST_VAAPI_OBJECT_DISPLAY(window), - &priv->display_width, - &priv->display_height + &window->display_width, + &window->display_height ); if (!GST_VAAPI_WINDOW_GET_CLASS(window)->create(window, &width, &height)) return FALSE; - if (width != priv->width || height != priv->height) { + if (width != window->width || height != window->height) { GST_DEBUG("backend resized window to %ux%u", width, height); - priv->width = width; - priv->height = height; + window->width = width; + window->height = height; } return TRUE; } -static void -gst_vaapi_window_finalize(GObject *object) +GstVaapiWindow * +gst_vaapi_window_new(const GstVaapiWindowClass *window_class, + GstVaapiDisplay *display, guint width, guint height) { - gst_vaapi_window_destroy(GST_VAAPI_WINDOW(object)); + GstVaapiWindow *window; - G_OBJECT_CLASS(gst_vaapi_window_parent_class)->finalize(object); + g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(height > 0, NULL); + + window = gst_vaapi_object_new(GST_VAAPI_OBJECT_CLASS(window_class), + display); + if (!window) + return NULL; + + GST_VAAPI_OBJECT_ID(window) = 0; + if (!gst_vaapi_window_create(window, width, height)) + goto error; + return window; + +error: + gst_vaapi_window_unref_internal(window); + return NULL; } -static void -gst_vaapi_window_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) +GstVaapiWindow * +gst_vaapi_window_new_from_native(const GstVaapiWindowClass *window_class, + GstVaapiDisplay *display, gpointer native_window) { - GstVaapiWindow * const window = GST_VAAPI_WINDOW(object); + GstVaapiWindow *window; - switch (prop_id) { - case PROP_WIDTH: - gst_vaapi_window_set_width(window, g_value_get_uint(value)); - break; - case PROP_HEIGHT: - gst_vaapi_window_set_height(window, g_value_get_uint(value)); - break; - case PROP_FULLSCREEN: - gst_vaapi_window_set_fullscreen(window, g_value_get_boolean(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + window = gst_vaapi_object_new(GST_VAAPI_OBJECT_CLASS(window_class), + display); + if (!window) + return NULL; + + GST_VAAPI_OBJECT_ID(window) = GPOINTER_TO_SIZE(native_window); + window->use_foreign_window = TRUE; + if (!gst_vaapi_window_create(window, 0, 0)) + goto error; + return window; + +error: + gst_vaapi_window_unref_internal(window); + return NULL; } -static void -gst_vaapi_window_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) +/** + * gst_vaapi_window_ref: + * @window: a #GstVaapiWindow + * + * Atomically increases the reference count of the given @window by one. + * + * Returns: The same @window argument + */ +GstVaapiWindow * +gst_vaapi_window_ref(GstVaapiWindow *window) { - GstVaapiWindow * const window = GST_VAAPI_WINDOW(object); - - switch (prop_id) { - case PROP_WIDTH: - g_value_set_uint(value, gst_vaapi_window_get_width(window)); - break; - case PROP_HEIGHT: - g_value_set_uint(value, gst_vaapi_window_get_height(window)); - break; - case PROP_FULLSCREEN: - g_value_set_boolean(value, window->priv->is_fullscreen); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + return gst_vaapi_window_ref_internal(window); } -static void -gst_vaapi_window_constructed(GObject *object) +/** + * gst_vaapi_window_unref: + * @window: a #GstVaapiWindow + * + * Atomically decreases the reference count of the @window by one. If + * the reference count reaches zero, the window will be free'd. + */ +void +gst_vaapi_window_unref(GstVaapiWindow *window) { - GstVaapiWindow * const window = GST_VAAPI_WINDOW(object); - GObjectClass *parent_class; - - window->priv->is_constructed = gst_vaapi_window_create(window); - - parent_class = G_OBJECT_CLASS(gst_vaapi_window_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); + gst_vaapi_window_unref_internal(window); } -static void -gst_vaapi_window_class_init(GstVaapiWindowClass *klass) +/** + * gst_vaapi_window_replace: + * @old_window_ptr: a pointer to a #GstVaapiWindow + * @new_window: a #GstVaapiWindow + * + * Atomically replaces the window window held in @old_window_ptr with + * @new_window. This means that @old_window_ptr shall reference a + * valid window. However, @new_window can be NULL. + */ +void +gst_vaapi_window_replace(GstVaapiWindow **old_window_ptr, + GstVaapiWindow *new_window) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiWindowPrivate)); - - object_class->finalize = gst_vaapi_window_finalize; - object_class->set_property = gst_vaapi_window_set_property; - object_class->get_property = gst_vaapi_window_get_property; - object_class->constructed = gst_vaapi_window_constructed; - - g_object_class_install_property - (object_class, - PROP_WIDTH, - g_param_spec_uint("width", - "Width", - "The window width", - 1, G_MAXUINT32, 1, - G_PARAM_READWRITE)); - - g_object_class_install_property - (object_class, - PROP_HEIGHT, - g_param_spec_uint("height", - "height", - "The window height", - 1, G_MAXUINT32, 1, - G_PARAM_READWRITE)); - - g_object_class_install_property - (object_class, - PROP_FULLSCREEN, - g_param_spec_boolean("fullscreen", - "Fullscreen", - "The fullscreen state of the window", - FALSE, - G_PARAM_READWRITE)); -} - -static void -gst_vaapi_window_init(GstVaapiWindow *window) -{ - GstVaapiWindowPrivate *priv = GST_VAAPI_WINDOW_GET_PRIVATE(window); - - window->priv = priv; - priv->width = 1; - priv->height = 1; - priv->is_constructed = FALSE; - priv->is_fullscreen = FALSE; - priv->check_geometry = FALSE; + gst_vaapi_window_replace_internal(old_window_ptr, new_window); } /** @@ -259,10 +191,9 @@ void gst_vaapi_window_show(GstVaapiWindow *window) { g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); - g_return_if_fail(window->priv->is_constructed); GST_VAAPI_WINDOW_GET_CLASS(window)->show(window); - window->priv->check_geometry = TRUE; + window->check_geometry = TRUE; } /** @@ -276,7 +207,6 @@ void gst_vaapi_window_hide(GstVaapiWindow *window) { g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); - g_return_if_fail(window->priv->is_constructed); GST_VAAPI_WINDOW_GET_CLASS(window)->hide(window); } @@ -296,7 +226,7 @@ gst_vaapi_window_get_fullscreen(GstVaapiWindow *window) gst_vaapi_window_ensure_size(window); - return window->priv->is_fullscreen; + return window->is_fullscreen; } /** @@ -309,16 +239,16 @@ gst_vaapi_window_get_fullscreen(GstVaapiWindow *window) void gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) { - GstVaapiWindowClass *klass; + const GstVaapiWindowClass *klass; g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); klass = GST_VAAPI_WINDOW_GET_CLASS(window); - if (window->priv->is_fullscreen != fullscreen && + if (window->is_fullscreen != fullscreen && klass->set_fullscreen && klass->set_fullscreen(window, fullscreen)) { - window->priv->is_fullscreen = fullscreen; - window->priv->check_geometry = TRUE; + window->is_fullscreen = fullscreen; + window->check_geometry = TRUE; } } @@ -334,11 +264,10 @@ guint gst_vaapi_window_get_width(GstVaapiWindow *window) { g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0); - g_return_val_if_fail(window->priv->is_constructed, 0); gst_vaapi_window_ensure_size(window); - return window->priv->width; + return window->width; } /** @@ -353,11 +282,10 @@ guint gst_vaapi_window_get_height(GstVaapiWindow *window) { g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0); - g_return_val_if_fail(window->priv->is_constructed, 0); gst_vaapi_window_ensure_size(window); - return window->priv->height; + return window->height; } /** @@ -372,15 +300,14 @@ void gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight) { g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); - g_return_if_fail(window->priv->is_constructed); gst_vaapi_window_ensure_size(window); if (pwidth) - *pwidth = window->priv->width; + *pwidth = window->width; if (pheight) - *pheight = window->priv->height; + *pheight = window->height; } /** @@ -395,7 +322,7 @@ gst_vaapi_window_set_width(GstVaapiWindow *window, guint width) { g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); - gst_vaapi_window_set_size(window, width, window->priv->height); + gst_vaapi_window_set_size(window, width, window->height); } /** @@ -410,7 +337,7 @@ gst_vaapi_window_set_height(GstVaapiWindow *window, guint height) { g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); - gst_vaapi_window_set_size(window, window->priv->width, height); + gst_vaapi_window_set_size(window, window->width, height); } /** @@ -426,14 +353,14 @@ gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) { g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); - if (width == window->priv->width && height == window->priv->height) + if (width == window->width && height == window->height) return; - window->priv->width = width; - window->priv->height = height; + if (!GST_VAAPI_WINDOW_GET_CLASS(window)->resize(window, width, height)) + return; - if (window->priv->is_constructed) - GST_VAAPI_WINDOW_GET_CLASS(window)->resize(window, width, height); + window->width = width; + window->height = height; } static inline void @@ -487,11 +414,10 @@ gst_vaapi_window_put_surface( guint flags ) { - GstVaapiWindowClass *klass; + const GstVaapiWindowClass *klass; GstVaapiRectangle src_rect_default, dst_rect_default; g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE); - g_return_val_if_fail(window->priv->is_constructed, FALSE); g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); klass = GST_VAAPI_WINDOW_GET_CLASS(window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 36d6c416e2..24c806f978 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -31,81 +31,24 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_WINDOW \ - (gst_vaapi_window_get_type()) - -#define GST_VAAPI_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_WINDOW, \ - GstVaapiWindow)) - -#define GST_VAAPI_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_WINDOW, \ - GstVaapiWindowClass)) +#define GST_VAAPI_WINDOW(obj) \ + ((GstVaapiWindow *)(obj)) #define GST_VAAPI_IS_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW)) - -#define GST_VAAPI_IS_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW)) - -#define GST_VAAPI_WINDOW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_WINDOW, \ - GstVaapiWindowClass)) + ((obj) != NULL) typedef struct _GstVaapiWindow GstVaapiWindow; -typedef struct _GstVaapiWindowPrivate GstVaapiWindowPrivate; typedef struct _GstVaapiWindowClass GstVaapiWindowClass; -/** - * GstVaapiWindow: - * - * Base class for system-dependent windows. - */ -struct _GstVaapiWindow { - /*< private >*/ - GstVaapiObject parent_instance; +GstVaapiWindow * +gst_vaapi_window_ref(GstVaapiWindow *window); - GstVaapiWindowPrivate *priv; -}; +void +gst_vaapi_window_unref(GstVaapiWindow *window); -/** - * GstVaapiWindowClass: - * @create: virtual function to create a window with width and height - * @destroy: virtual function to destroy a window - * @show: virtual function to show (map) a window - * @hide: virtual function to hide (unmap) a window - * @set_fullscreen: virtual function to change window fullscreen state - * @resize: virtual function to resize a window - * @render: virtual function to render a #GstVaapiSurface into a window - * - * Base class for system-dependent windows. - */ -struct _GstVaapiWindowClass { - /*< private >*/ - GstVaapiObjectClass parent_class; - - /*< public >*/ - gboolean (*create) (GstVaapiWindow *window, guint *width, guint *height); - void (*destroy)(GstVaapiWindow *window); - gboolean (*show) (GstVaapiWindow *window); - gboolean (*hide) (GstVaapiWindow *window); - gboolean (*get_geometry) (GstVaapiWindow *window, - gint *px, gint *py, - guint *pwidth, guint *pheight); - gboolean (*set_fullscreen)(GstVaapiWindow *window, gboolean fullscreen); - gboolean (*resize) (GstVaapiWindow *window, guint width, guint height); - gboolean (*render) (GstVaapiWindow *window, - GstVaapiSurface *surface, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect, - guint flags); -}; - -GType -gst_vaapi_window_get_type(void) G_GNUC_CONST; +void +gst_vaapi_window_replace(GstVaapiWindow **old_window_ptr, + GstVaapiWindow *new_window); GstVaapiDisplay * gst_vaapi_window_get_display(GstVaapiWindow *window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c index 812bf51258..746f31fd3f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -26,13 +26,32 @@ #include "sysdeps.h" #include "gstvaapiwindow_drm.h" +#include "gstvaapiwindow_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiWindowDRM, - gst_vaapi_window_drm, - GST_VAAPI_TYPE_WINDOW) +typedef struct _GstVaapiWindowDRMClass GstVaapiWindowDRMClass; + +/** + * GstVaapiWindowDRM: + * + * A dummy DRM window abstraction. + */ +struct _GstVaapiWindowDRM { + /*< private >*/ + GstVaapiWindow parent_instance; +}; + +/** + * GstVaapiWindowDRMClass: + * + * A dummy DRM window abstraction class. + */ +struct _GstVaapiWindowDRMClass { + /*< private >*/ + GstVaapiWindowClass parent_instance; +}; static gboolean gst_vaapi_window_drm_show(GstVaapiWindow *window) @@ -56,11 +75,6 @@ gst_vaapi_window_drm_create( return TRUE; } -static void -gst_vaapi_window_drm_destroy(GstVaapiWindow * window) -{ -} - static gboolean gst_vaapi_window_drm_resize( GstVaapiWindow * window, @@ -83,44 +97,29 @@ gst_vaapi_window_drm_render( return TRUE; } -static void -gst_vaapi_window_drm_finalize(GObject *object) +void +gst_vaapi_window_drm_class_init(GstVaapiWindowDRMClass *klass) { - G_OBJECT_CLASS(gst_vaapi_window_drm_parent_class)->finalize(object); + GstVaapiWindowClass * const window_class = + GST_VAAPI_WINDOW_CLASS(klass); + + window_class->create = gst_vaapi_window_drm_create; + window_class->show = gst_vaapi_window_drm_show; + window_class->hide = gst_vaapi_window_drm_hide; + window_class->resize = gst_vaapi_window_drm_resize; + window_class->render = gst_vaapi_window_drm_render; } static void -gst_vaapi_window_drm_constructed(GObject *object) -{ - GObjectClass *parent_class; - - parent_class = G_OBJECT_CLASS(gst_vaapi_window_drm_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); -} - -static void -gst_vaapi_window_drm_class_init(GstVaapiWindowDRMClass * klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstVaapiWindowClass * const window_class = GST_VAAPI_WINDOW_CLASS(klass); - - object_class->finalize = gst_vaapi_window_drm_finalize; - object_class->constructed = gst_vaapi_window_drm_constructed; - - window_class->create = gst_vaapi_window_drm_create; - window_class->destroy = gst_vaapi_window_drm_destroy; - window_class->show = gst_vaapi_window_drm_show; - window_class->hide = gst_vaapi_window_drm_hide; - window_class->render = gst_vaapi_window_drm_render; - window_class->resize = gst_vaapi_window_drm_resize; -} - -static void -gst_vaapi_window_drm_init(GstVaapiWindowDRM * window) +gst_vaapi_window_drm_finalize(GstVaapiWindowDRM *window) { } +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( + GstVaapiWindowDRM, + gst_vaapi_window_drm, + gst_vaapi_window_drm_class_init(&g_class)) + /** * gst_vaapi_window_drm_new: * @display: a #GstVaapiDisplay @@ -148,14 +147,6 @@ gst_vaapi_window_drm_new( { GST_DEBUG("new window, size %ux%u", width, height); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(width > 0, NULL); - g_return_val_if_fail(height > 0, NULL); - - return g_object_new(GST_VAAPI_TYPE_WINDOW_DRM, - "display", display, - "id", GST_VAAPI_ID(0), - "width", width, - "height", height, - NULL); + return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( + gst_vaapi_window_drm_class()), display, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h index 47e053a31f..563e6acc17 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h @@ -27,55 +27,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_WINDOW_DRM \ - (gst_vaapi_window_drm_get_type()) - -#define GST_VAAPI_WINDOW_DRM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_WINDOW_DRM, \ - GstVaapiWindowDRM)) - -#define GST_VAAPI_WINDOW_DRM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_WINDOW_DRM, \ - GstVaapiWindowDRMClass)) +#define GST_VAAPI_WINDOW_DRM(obj) \ + ((GstVaapiWindowDRM *)(obj)) #define GST_VAAPI_IS_WINDOW_DRM(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW_DRM)) - -#define GST_VAAPI_IS_WINDOW_DRM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW_DRM)) - -#define GST_VAAPI_WINDOW_DRM_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_WINDOW_DRM, \ - GstVaapiWindowDRMClass)) + ((obj) != NULL) typedef struct _GstVaapiWindowDRM GstVaapiWindowDRM; -typedef struct _GstVaapiWindowDRMClass GstVaapiWindowDRMClass; - -/** - * GstVaapiWindowDRM: - * - * A dummy DRM window abstraction. - */ -struct _GstVaapiWindowDRM { - /*< private >*/ - GstVaapiWindow parent_instance; -}; - -/** - * GstVaapiWindowDRMClass: - * - * A DRM window class. - */ -struct _GstVaapiWindowDRMClass { - /*< private >*/ - GstVaapiWindowClass parent_class; -}; - -GType -gst_vaapi_window_drm_get_type(void) G_GNUC_CONST; GstVaapiWindow * gst_vaapi_window_drm_new(GstVaapiDisplay *display, guint width, guint height); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 7870debfc2..0e9430b6d5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -27,35 +27,58 @@ #include "sysdeps.h" #include "gstvaapiwindow_glx.h" +#include "gstvaapiwindow_x11_priv.h" #include "gstvaapidisplay_x11.h" #include "gstvaapidisplay_x11_priv.h" #include "gstvaapiutils_x11.h" #include "gstvaapiutils_glx.h" -#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiWindowGLX, - gst_vaapi_window_glx, - GST_VAAPI_TYPE_WINDOW_X11) +#define GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window) \ + (&GST_VAAPI_WINDOW_GLX(window)->priv) -#define GST_VAAPI_WINDOW_GLX_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_WINDOW_GLX, \ - GstVaapiWindowGLXPrivate)) +#define GST_VAAPI_IS_WINDOW_GLX(obj) \ + ((obj) != NULL) + +#define GST_VAAPI_WINDOW_GLX_CLASS(klass) \ + ((GstVaapiWindowGLXClass *)(klass)) + +#define GST_VAAPI_WINDOW_GLX_GET_CLASS(obj) \ + GST_VAAPI_WINDOW_GLX_CLASS(GST_VAAPI_OBJECT_GET_CLASS(obj)) + +typedef struct _GstVaapiWindowGLXPrivate GstVaapiWindowGLXPrivate; +typedef struct _GstVaapiWindowGLXClass GstVaapiWindowGLXClass; struct _GstVaapiWindowGLXPrivate { Colormap cmap; GLContextState *gl_context; - guint is_constructed : 1; - guint foreign_window : 1; }; -enum { - PROP_0, +/** + * GstVaapiWindowGLX: + * + * An X11 #Window suitable for GLX rendering. + */ +struct _GstVaapiWindowGLX { + /*< private >*/ + GstVaapiWindowX11 parent_instance; - PROP_GLX_CONTEXT + GstVaapiWindowGLXPrivate priv; +}; + +/** + * GstVaapiWindowGLXClass: + * + * An X11 #Window suitable for GLX rendering. + */ +struct _GstVaapiWindowGLXClass { + /*< private >*/ + GstVaapiWindowX11Class parent_class; + + GstVaapiObjectFinalizeFunc parent_finalize; + GstVaapiWindowResizeFunc parent_resize; }; /* Fill rectangle coords with capped bounds */ @@ -88,9 +111,10 @@ fill_rect( } static void -_gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window) +_gst_vaapi_window_glx_destroy_context(GstVaapiWindow *window) { - GstVaapiWindowGLXPrivate * const priv = window->priv; + GstVaapiWindowGLXPrivate * const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); GST_VAAPI_OBJECT_LOCK_DISPLAY(window); if (priv->gl_context) { @@ -102,11 +126,12 @@ _gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window) static gboolean _gst_vaapi_window_glx_create_context( - GstVaapiWindowGLX *window, - GLXContext foreign_context + GstVaapiWindow *window, + GLXContext foreign_context ) { - GstVaapiWindowGLXPrivate * const priv = window->priv; + GstVaapiWindowGLXPrivate * const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); GLContextState parent_cs; @@ -141,11 +166,12 @@ end: static gboolean _gst_vaapi_window_glx_ensure_context( - GstVaapiWindowGLX *window, - GLXContext foreign_context + GstVaapiWindow *window, + GLXContext foreign_context ) { - GstVaapiWindowGLXPrivate * const priv = window->priv; + GstVaapiWindowGLXPrivate * const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); if (priv->gl_context) { if (!foreign_context || foreign_context == priv->gl_context->context) @@ -157,11 +183,12 @@ _gst_vaapi_window_glx_ensure_context( static gboolean gst_vaapi_window_glx_ensure_context( - GstVaapiWindowGLX *window, - GLXContext foreign_context + GstVaapiWindow *window, + GLXContext foreign_context ) { - GstVaapiWindowGLXPrivate * const priv = window->priv; + GstVaapiWindowGLXPrivate * const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); GLContextState old_cs; guint width, height; @@ -182,7 +209,7 @@ gst_vaapi_window_glx_ensure_context( glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gst_vaapi_window_get_size(GST_VAAPI_WINDOW(window), &width, &height); + gst_vaapi_window_get_size(window, &width, &height); gl_resize(width, height); gl_set_bgcolor(0); @@ -194,21 +221,23 @@ gst_vaapi_window_glx_ensure_context( static Visual * gst_vaapi_window_glx_get_visual(GstVaapiWindow *window) { - GstVaapiWindowGLX * const glx_window = GST_VAAPI_WINDOW_GLX(window); + GstVaapiWindowGLXPrivate * const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); - if (!_gst_vaapi_window_glx_ensure_context(glx_window, NULL)) + if (!_gst_vaapi_window_glx_ensure_context(window, NULL)) return NULL; - return glx_window->priv->gl_context->visual->visual; + return priv->gl_context->visual->visual; } static void -gst_vaapi_window_glx_destroy_colormap(GstVaapiWindowGLX *window) +gst_vaapi_window_glx_destroy_colormap(GstVaapiWindow *window) { - GstVaapiWindowGLXPrivate * const priv = window->priv; + GstVaapiWindowGLXPrivate * const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); if (priv->cmap) { - if (!priv->foreign_window) { + if (!window->use_foreign_window) { GST_VAAPI_OBJECT_LOCK_DISPLAY(window); XFreeColormap(dpy, priv->cmap); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); @@ -218,16 +247,17 @@ gst_vaapi_window_glx_destroy_colormap(GstVaapiWindowGLX *window) } static Colormap -gst_vaapi_window_glx_create_colormap(GstVaapiWindowGLX *window) +gst_vaapi_window_glx_create_colormap(GstVaapiWindow *window) { - GstVaapiWindowGLXPrivate * const priv = window->priv; + GstVaapiWindowGLXPrivate * const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); int screen; XWindowAttributes wattr; gboolean success = FALSE; if (!priv->cmap) { - if (!priv->foreign_window) { + if (!window->use_foreign_window) { if (!_gst_vaapi_window_glx_ensure_context(window, NULL)) return None; GST_VAAPI_OBJECT_LOCK_DISPLAY(window); @@ -260,18 +290,21 @@ gst_vaapi_window_glx_create_colormap(GstVaapiWindowGLX *window) static Colormap gst_vaapi_window_glx_get_colormap(GstVaapiWindow *window) { - return gst_vaapi_window_glx_create_colormap(GST_VAAPI_WINDOW_GLX(window)); + return gst_vaapi_window_glx_create_colormap(window); } static gboolean -gst_vaapi_window_glx_resize(GstVaapiWindow *window, guint width, guint height) +gst_vaapi_window_glx_resize(GstVaapiWindow *window, + guint width, guint height) { - GstVaapiWindowGLXPrivate * const priv = GST_VAAPI_WINDOW_GLX(window)->priv; + GstVaapiWindowGLXPrivate * const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); + const GstVaapiWindowGLXClass * const klass = + GST_VAAPI_WINDOW_GLX_GET_CLASS(window); Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); GLContextState old_cs; - if (!GST_VAAPI_WINDOW_CLASS(gst_vaapi_window_glx_parent_class)-> - resize(window, width, height)) + if (!klass->parent_resize(window, width, height)) return FALSE; GST_VAAPI_OBJECT_LOCK_DISPLAY(window); @@ -285,117 +318,37 @@ gst_vaapi_window_glx_resize(GstVaapiWindow *window, guint width, guint height) } static void -gst_vaapi_window_glx_finalize(GObject *object) +gst_vaapi_window_glx_finalize(GstVaapiWindowGLX *window) { - GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(object); + GstVaapiWindow * const base_window = GST_VAAPI_WINDOW(window); - _gst_vaapi_window_glx_destroy_context(window); - gst_vaapi_window_glx_destroy_colormap(window); + _gst_vaapi_window_glx_destroy_context(base_window); + gst_vaapi_window_glx_destroy_colormap(base_window); - G_OBJECT_CLASS(gst_vaapi_window_glx_parent_class)->finalize(object); -} - -static void -gst_vaapi_window_glx_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(object); - - switch (prop_id) { - case PROP_GLX_CONTEXT: - gst_vaapi_window_glx_set_context(window, g_value_get_pointer(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_window_glx_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(object); - - switch (prop_id) { - case PROP_GLX_CONTEXT: - g_value_set_pointer(value, gst_vaapi_window_glx_get_context(window)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_window_glx_constructed(GObject *object) -{ - GstVaapiWindowGLXPrivate * const priv = GST_VAAPI_WINDOW_GLX(object)->priv; - GObjectClass *parent_class; - - parent_class = G_OBJECT_CLASS(gst_vaapi_window_glx_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); - - priv->foreign_window = - gst_vaapi_window_x11_is_foreign_xid(GST_VAAPI_WINDOW_X11(object)); - - priv->is_constructed = - gst_vaapi_window_glx_ensure_context(GST_VAAPI_WINDOW_GLX(object), NULL); + GST_VAAPI_WINDOW_GLX_GET_CLASS(window)->parent_finalize( + GST_VAAPI_OBJECT(window)); } static void gst_vaapi_window_glx_class_init(GstVaapiWindowGLXClass *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstVaapiWindowClass * const win_class = GST_VAAPI_WINDOW_CLASS(klass); - GstVaapiWindowX11Class * const xwin_class = GST_VAAPI_WINDOW_X11_CLASS(klass); + GstVaapiWindowClass * const window_class = + GST_VAAPI_WINDOW_CLASS(klass); + GstVaapiWindowX11Class * const xwindow_class = + GST_VAAPI_WINDOW_X11_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiWindowGLXPrivate)); - - object_class->finalize = gst_vaapi_window_glx_finalize; - object_class->set_property = gst_vaapi_window_glx_set_property; - object_class->get_property = gst_vaapi_window_glx_get_property; - object_class->constructed = gst_vaapi_window_glx_constructed; - - win_class->resize = gst_vaapi_window_glx_resize; - xwin_class->get_visual = gst_vaapi_window_glx_get_visual; - xwin_class->get_colormap = gst_vaapi_window_glx_get_colormap; - - /** - * GstVaapiDisplayGLX:glx-context: - * - * The GLX context that was created by gst_vaapi_window_glx_new() - * or that was bound from gst_vaapi_window_glx_set_context(). - */ - g_object_class_install_property - (object_class, - PROP_GLX_CONTEXT, - g_param_spec_pointer("glx-context", - "GLX context", - "GLX context", - G_PARAM_READWRITE)); + gst_vaapi_window_x11_class_init(xwindow_class); + klass->parent_resize = window_class->resize; + klass->parent_finalize = GST_VAAPI_OBJECT_CLASS(klass)->finalize; + window_class->resize = gst_vaapi_window_glx_resize; + xwindow_class->get_visual = gst_vaapi_window_glx_get_visual; + xwindow_class->get_colormap = gst_vaapi_window_glx_get_colormap; } -static void -gst_vaapi_window_glx_init(GstVaapiWindowGLX *window) -{ - GstVaapiWindowGLXPrivate *priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); - - window->priv = priv; - priv->cmap = None; - priv->gl_context = NULL; - priv->is_constructed = FALSE; - priv->foreign_window = FALSE; -} +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( + GstVaapiWindowGLX, + gst_vaapi_window_glx, + gst_vaapi_window_glx_class_init(&g_class)) /** * gst_vaapi_window_glx_new: @@ -412,16 +365,8 @@ gst_vaapi_window_glx_init(GstVaapiWindowGLX *window) GstVaapiWindow * gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(width > 0, NULL); - g_return_val_if_fail(height > 0, NULL); - - return g_object_new(GST_VAAPI_TYPE_WINDOW_GLX, - "display", display, - "id", GST_VAAPI_ID(None), - "width", width, - "height", height, - NULL); + return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( + gst_vaapi_window_glx_class()), display, width, height); } /** @@ -441,13 +386,10 @@ gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid) { GST_DEBUG("new window from xid 0x%08x", xid); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); g_return_val_if_fail(xid != None, NULL); - return g_object_new(GST_VAAPI_TYPE_WINDOW_GLX, - "display", display, - "id", GST_VAAPI_ID(xid), - NULL); + return gst_vaapi_window_new_from_native(GST_VAAPI_WINDOW_CLASS( + gst_vaapi_window_glx_class()), display, GINT_TO_POINTER(xid)); } /** @@ -462,9 +404,8 @@ GLXContext gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window) { g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), NULL); - g_return_val_if_fail(window->priv->is_constructed, FALSE); - return window->priv->gl_context->context; + return GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window)->gl_context->context; } /** @@ -483,9 +424,8 @@ gboolean gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx) { g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE); - g_return_val_if_fail(window->priv->is_constructed, FALSE); - return gst_vaapi_window_glx_ensure_context(window, ctx); + return gst_vaapi_window_glx_ensure_context(GST_VAAPI_WINDOW(window), ctx); } /** @@ -504,10 +444,9 @@ gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window) gboolean success; g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE); - g_return_val_if_fail(window->priv->is_constructed, FALSE); GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - success = gl_set_current_context(window->priv->gl_context, NULL); + success = gl_set_current_context(window->priv.gl_context, NULL); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); return success; } @@ -524,10 +463,9 @@ void gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window) { g_return_if_fail(GST_VAAPI_IS_WINDOW_GLX(window)); - g_return_if_fail(window->priv->is_constructed); GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - gl_swap_buffers(window->priv->gl_context); + gl_swap_buffers(window->priv.gl_context); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); } @@ -564,7 +502,7 @@ gst_vaapi_window_glx_put_texture( guint win_width, win_height; g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), FALSE); + g_return_val_if_fail(texture != NULL, FALSE); gst_vaapi_texture_get_size(texture, &tex_width, &tex_height); fill_rect(&tmp_src_rect, src_rect, tex_width, tex_height); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index 6bdbb667ee..9d0042f6c1 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -30,58 +30,10 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_WINDOW_GLX \ - (gst_vaapi_window_glx_get_type()) - -#define GST_VAAPI_WINDOW_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_WINDOW_GLX, \ - GstVaapiWindowGLX)) - -#define GST_VAAPI_WINDOW_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_WINDOW_GLX, \ - GstVaapiWindowGLXClass)) - -#define GST_VAAPI_IS_WINDOW_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW_GLX)) - -#define GST_VAAPI_IS_WINDOW_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW_GLX)) - -#define GST_VAAPI_WINDOW_GLX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_WINDOW_GLX, \ - GstVaapiWindowGLXClass)) +#define GST_VAAPI_WINDOW_GLX(obj) \ + ((GstVaapiWindowGLX *)(obj)) typedef struct _GstVaapiWindowGLX GstVaapiWindowGLX; -typedef struct _GstVaapiWindowGLXPrivate GstVaapiWindowGLXPrivate; -typedef struct _GstVaapiWindowGLXClass GstVaapiWindowGLXClass; - -/** - * GstVaapiWindowGLX: - * - * An X11 #Window suitable for GLX rendering. - */ -struct _GstVaapiWindowGLX { - /*< private >*/ - GstVaapiWindowX11 parent_instance; - - GstVaapiWindowGLXPrivate *priv; -}; - -/** - * GstVaapiWindowGLXClass: - * - * An X11 #Window suitable for GLX rendering. - */ -struct _GstVaapiWindowGLXClass { - /*< private >*/ - GstVaapiWindowX11Class parent_class; -}; - -GType -gst_vaapi_window_glx_get_type(void) G_GNUC_CONST; GstVaapiWindow * gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h new file mode 100644 index 0000000000..39ca6a448e --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -0,0 +1,131 @@ +/* + * gstvaapiwindow_priv.h - VA window abstraction (private definitions) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation + * + * 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_WINDOW_PRIV_H +#define GST_VAAPI_WINDOW_PRIV_H + +#include "gstvaapiobject_priv.h" + +G_BEGIN_DECLS + +#define GST_VAAPI_WINDOW_CLASS(klass) \ + ((GstVaapiWindowClass *)(klass)) + +#define GST_VAAPI_WINDOW_GET_CLASS(obj) \ + GST_VAAPI_WINDOW_CLASS(GST_VAAPI_OBJECT_GET_CLASS(obj)) + +/* GstVaapiWindowClass hooks */ +typedef gboolean (*GstVaapiWindowCreateFunc) (GstVaapiWindow *window, + guint *width, guint *height); +typedef gboolean (*GstVaapiWindowShowFunc) (GstVaapiWindow *window); +typedef gboolean (*GstVaapiWindowHideFunc) (GstVaapiWindow *window); +typedef gboolean (*GstVaapiWindowGetGeometryFunc)(GstVaapiWindow *window, + gint *px, gint *py, guint *pwidth, guint *pheight); +typedef gboolean (*GstVaapiWindowSetFullscreenFunc)(GstVaapiWindow *window, + gboolean fullscreen); +typedef gboolean (*GstVaapiWindowResizeFunc) (GstVaapiWindow *window, + guint width, guint height); +typedef gboolean (*GstVaapiWindowRenderFunc) (GstVaapiWindow *window, + GstVaapiSurface *surface, const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect, guint flags); + +/** + * GstVaapiWindow: + * + * Base class for system-dependent windows. + */ +struct _GstVaapiWindow { + /*< private >*/ + GstVaapiObject parent_instance; + + /*< protected >*/ + guint width; + guint height; + guint display_width; + guint display_height; + guint use_foreign_window : 1; + guint is_fullscreen : 1; + guint check_geometry : 1; +}; + +/** + * GstVaapiWindowClass: + * @create: virtual function to create a window with width and height + * @show: virtual function to show (map) a window + * @hide: virtual function to hide (unmap) a window + * @get_geometry: virtual function to get the current window geometry + * @set_fullscreen: virtual function to change window fullscreen state + * @resize: virtual function to resize a window + * @render: virtual function to render a #GstVaapiSurface into a window + * + * Base class for system-dependent windows. + */ +struct _GstVaapiWindowClass { + /*< private >*/ + GstVaapiObjectClass parent_class; + + /*< protected >*/ + GstVaapiWindowCreateFunc create; + GstVaapiWindowShowFunc show; + GstVaapiWindowHideFunc hide; + GstVaapiWindowGetGeometryFunc get_geometry; + GstVaapiWindowSetFullscreenFunc set_fullscreen; + GstVaapiWindowResizeFunc resize; + GstVaapiWindowRenderFunc render; +}; + +GstVaapiWindow * +gst_vaapi_window_new(const GstVaapiWindowClass *window_class, + GstVaapiDisplay *display, guint width, guint height); + +GstVaapiWindow * +gst_vaapi_window_new_from_native(const GstVaapiWindowClass *window_class, + GstVaapiDisplay *display, gpointer native_window); + +/* Inline reference counting for core libgstvaapi library */ +#ifdef GST_VAAPI_CORE +#define gst_vaapi_window_ref_internal(window) \ + ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(window))) + +#define gst_vaapi_window_unref_internal(window) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(window)) + +#define gst_vaapi_window_replace_internal(old_window_ptr, new_window) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_window_ptr), \ + GST_VAAPI_MINI_OBJECT(new_window)) + +#undef gst_vaapi_window_ref +#define gst_vaapi_window_ref(window) \ + gst_vaapi_window_ref_internal((window)) + +#undef gst_vaapi_window_unref +#define gst_vaapi_window_unref(window) \ + gst_vaapi_window_unref_internal((window)) + +#undef gst_vaapi_window_replace +#define gst_vaapi_window_replace(old_window_ptr, new_window) \ + gst_vaapi_window_replace_internal((old_window_ptr), (new_window)) +#endif + +G_END_DECLS + +#endif /* GST_VAAPI_WINDOW_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 38d62636f7..0c32c1d07a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -28,22 +28,22 @@ #include #include "gstvaapicompat.h" #include "gstvaapiwindow_wayland.h" +#include "gstvaapiwindow_priv.h" #include "gstvaapidisplay_wayland.h" #include "gstvaapidisplay_wayland_priv.h" #include "gstvaapiutils.h" -#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiWindowWayland, - gst_vaapi_window_wayland, - GST_VAAPI_TYPE_WINDOW) +#define GST_VAAPI_WINDOW_WAYLAND_CAST(obj) \ + ((GstVaapiWindowWayland *)(obj)) -#define GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_WINDOW_WAYLAND, \ - GstVaapiWindowWaylandPrivate)) +#define GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(obj) \ + (&GST_VAAPI_WINDOW_WAYLAND_CAST(obj)->priv) + +typedef struct _GstVaapiWindowWaylandPrivate GstVaapiWindowWaylandPrivate; +typedef struct _GstVaapiWindowWaylandClass GstVaapiWindowWaylandClass; struct _GstVaapiWindowWaylandPrivate { struct wl_shell_surface *shell_surface; @@ -56,6 +56,28 @@ struct _GstVaapiWindowWaylandPrivate { guint fullscreen_on_show : 1; }; +/** + * GstVaapiWindowWayland: + * + * A Wayland window abstraction. + */ +struct _GstVaapiWindowWayland { + /*< private >*/ + GstVaapiWindow parent_instance; + + GstVaapiWindowWaylandPrivate priv; +}; + +/** + * GstVaapiWindowWaylandClass: + * + * An Wayland #Window wrapper class. + */ +struct _GstVaapiWindowWaylandClass { + /*< private >*/ + GstVaapiWindowClass parent_class; +}; + static gboolean gst_vaapi_window_wayland_show(GstVaapiWindow *window) { @@ -76,7 +98,7 @@ static gboolean gst_vaapi_window_wayland_sync(GstVaapiWindow *window) { GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND(window)->priv; + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); if (priv->redraw_pending) { struct wl_display * const wl_display = @@ -118,7 +140,7 @@ static gboolean gst_vaapi_window_wayland_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) { GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND(window)->priv; + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); if (!priv->is_shown) { priv->fullscreen_on_show = fullscreen; @@ -147,9 +169,9 @@ gst_vaapi_window_wayland_create( ) { GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND(window)->priv; + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); GstVaapiDisplayWaylandPrivate * const priv_display = - GST_VAAPI_OBJECT_DISPLAY_WAYLAND(window)->priv; + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(GST_VAAPI_OBJECT_DISPLAY(window)); GST_DEBUG("create window, size %ux%u", *width, *height); @@ -195,7 +217,7 @@ static void gst_vaapi_window_wayland_destroy(GstVaapiWindow * window) { GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND(window)->priv; + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); if (priv->shell_surface) { wl_shell_surface_destroy(priv->shell_surface); @@ -226,9 +248,9 @@ gst_vaapi_window_wayland_resize( ) { GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND(window)->priv; + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); GstVaapiDisplayWaylandPrivate * const priv_display = - GST_VAAPI_OBJECT_DISPLAY_WAYLAND(window)->priv; + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(GST_VAAPI_OBJECT_DISPLAY(window)); GST_DEBUG("resize window, new size %ux%u", width, height); @@ -267,7 +289,7 @@ gst_vaapi_window_wayland_render( ) { GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND(window)->priv; + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(window); struct wl_display * const wl_display = GST_VAAPI_OBJECT_WL_DISPLAY(window); struct wl_buffer *buffer; @@ -343,35 +365,16 @@ gst_vaapi_window_wayland_render( return TRUE; } -static void -gst_vaapi_window_wayland_finalize(GObject *object) -{ - G_OBJECT_CLASS(gst_vaapi_window_wayland_parent_class)->finalize(object); -} - -static void -gst_vaapi_window_wayland_constructed(GObject *object) -{ - GObjectClass *parent_class; - - parent_class = G_OBJECT_CLASS(gst_vaapi_window_wayland_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); -} - static void gst_vaapi_window_wayland_class_init(GstVaapiWindowWaylandClass * klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiObjectClass * const object_class = GST_VAAPI_OBJECT_CLASS(klass); GstVaapiWindowClass * const window_class = GST_VAAPI_WINDOW_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiWindowWaylandPrivate)); - - object_class->finalize = gst_vaapi_window_wayland_finalize; - object_class->constructed = gst_vaapi_window_wayland_constructed; + object_class->finalize = (GstVaapiObjectFinalizeFunc) + gst_vaapi_window_wayland_destroy; window_class->create = gst_vaapi_window_wayland_create; - window_class->destroy = gst_vaapi_window_wayland_destroy; window_class->show = gst_vaapi_window_wayland_show; window_class->hide = gst_vaapi_window_wayland_hide; window_class->render = gst_vaapi_window_wayland_render; @@ -379,18 +382,13 @@ gst_vaapi_window_wayland_class_init(GstVaapiWindowWaylandClass * klass) window_class->set_fullscreen = gst_vaapi_window_wayland_set_fullscreen; } -static void -gst_vaapi_window_wayland_init(GstVaapiWindowWayland * window) -{ - GstVaapiWindowWaylandPrivate *priv = - GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); +#define gst_vaapi_window_wayland_finalize \ + gst_vaapi_window_wayland_destroy - window->priv = priv; - priv->shell_surface = NULL; - priv->surface = NULL; - priv->buffer = NULL; - priv->redraw_pending = FALSE; -} +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( + GstVaapiWindowWayland, + gst_vaapi_window_wayland, + gst_vaapi_window_wayland_class_init(&g_class)) /** * gst_vaapi_window_wayland_new: @@ -413,14 +411,6 @@ gst_vaapi_window_wayland_new( { GST_DEBUG("new window, size %ux%u", width, height); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(width > 0, NULL); - g_return_val_if_fail(height > 0, NULL); - - return g_object_new(GST_VAAPI_TYPE_WINDOW_WAYLAND, - "display", display, - "id", GST_VAAPI_ID(0), - "width", width, - "height", height, - NULL); + return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( + gst_vaapi_window_wayland_class()), display, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h index d711fb776b..5f285bef4b 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h @@ -28,58 +28,7 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_WINDOW_WAYLAND \ - (gst_vaapi_window_wayland_get_type()) - -#define GST_VAAPI_WINDOW_WAYLAND(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_WINDOW_WAYLAND, \ - GstVaapiWindowWayland)) - -#define GST_VAAPI_WINDOW_WAYLAND_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_WINDOW_WAYLAND, \ - GstVaapiWindowWaylandClass)) - -#define GST_VAAPI_IS_WINDOW_WAYLAND(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW_WAYLAND)) - -#define GST_VAAPI_IS_WINDOW_WAYLAND_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW_WAYLAND)) - -#define GST_VAAPI_WINDOW_WAYLAND_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_WINDOW_WAYLAND, \ - GstVaapiWindowWaylandClass)) - typedef struct _GstVaapiWindowWayland GstVaapiWindowWayland; -typedef struct _GstVaapiWindowWaylandPrivate GstVaapiWindowWaylandPrivate; -typedef struct _GstVaapiWindowWaylandClass GstVaapiWindowWaylandClass; - -/** - * GstVaapiWindowWayland: - * - * A Wayland window abstraction. - */ -struct _GstVaapiWindowWayland { - /*< private >*/ - GstVaapiWindow parent_instance; - - GstVaapiWindowWaylandPrivate *priv; -}; - -/** - * GstVaapiWindowWaylandClass: - * - * An Wayland #Window wrapper class. - */ -struct _GstVaapiWindowWaylandClass { - /*< private >*/ - GstVaapiWindowClass parent_class; -}; - -GType -gst_vaapi_window_wayland_get_type(void) G_GNUC_CONST; GstVaapiWindow * gst_vaapi_window_wayland_new(GstVaapiDisplay *display, guint width, guint height); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 13fd7195c2..a04d12dc36 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -30,38 +30,24 @@ #include #include "gstvaapicompat.h" #include "gstvaapiwindow_x11.h" +#include "gstvaapiwindow_x11_priv.h" #include "gstvaapidisplay_x11.h" #include "gstvaapidisplay_x11_priv.h" #include "gstvaapiutils.h" #include "gstvaapiutils_x11.h" -#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiWindowX11, gst_vaapi_window_x11, GST_VAAPI_TYPE_WINDOW) - -#define GST_VAAPI_WINDOW_X11_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_WINDOW_X11, \ - GstVaapiWindowX11Private)) - -struct _GstVaapiWindowX11Private { - Atom atom_NET_WM_STATE; - Atom atom_NET_WM_STATE_FULLSCREEN; - guint create_window : 1; - guint is_mapped : 1; - guint fullscreen_on_map : 1; -}; - #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ #define _NET_WM_STATE_ADD 1 /* add/set property */ #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ static void -send_wmspec_change_state(GstVaapiWindowX11 *window, Atom state, gboolean add) +send_wmspec_change_state(GstVaapiWindow *window, Atom state, gboolean add) { - GstVaapiWindowX11Private * const priv = window->priv; + GstVaapiWindowX11Private * const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); XClientMessageEvent xclient; @@ -140,7 +126,8 @@ timed_wait_event(GstVaapiWindow *window, int type, guint64 end_time, XEvent *e) static gboolean gst_vaapi_window_x11_show(GstVaapiWindow *window) { - GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + GstVaapiWindowX11Private * const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); const Window xid = GST_VAAPI_OBJECT_ID(window); XWindowAttributes wattr; @@ -151,7 +138,7 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) GST_VAAPI_OBJECT_LOCK_DISPLAY(window); x11_trap_errors(); - if (!priv->create_window) { + if (window->use_foreign_window) { XGetWindowAttributes(dpy, xid, &wattr); if (!(wattr.your_event_mask & StructureNotifyMask)) XSelectInput(dpy, xid, StructureNotifyMask); @@ -162,7 +149,7 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) if (!has_errors) { wait_event(window, MapNotify); - if (!priv->create_window && + if (window->use_foreign_window && !(wattr.your_event_mask & StructureNotifyMask)) { GST_VAAPI_OBJECT_LOCK_DISPLAY(window); x11_trap_errors(); @@ -181,7 +168,8 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window) static gboolean gst_vaapi_window_x11_hide(GstVaapiWindow *window) { - GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + GstVaapiWindowX11Private * const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); const Window xid = GST_VAAPI_OBJECT_ID(window); XWindowAttributes wattr; @@ -192,7 +180,7 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) GST_VAAPI_OBJECT_LOCK_DISPLAY(window); x11_trap_errors(); - if (!priv->create_window) { + if (window->use_foreign_window) { XGetWindowAttributes(dpy, xid, &wattr); if (!(wattr.your_event_mask & StructureNotifyMask)) XSelectInput(dpy, xid, StructureNotifyMask); @@ -203,7 +191,7 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) if (!has_errors) { wait_event(window, UnmapNotify); - if (!priv->create_window && + if (window->use_foreign_window && !(wattr.your_event_mask & StructureNotifyMask)) { GST_VAAPI_OBJECT_LOCK_DISPLAY(window); x11_trap_errors(); @@ -219,12 +207,13 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window) static gboolean gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) { - GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + GstVaapiWindowX11Private * const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); Window xid = GST_VAAPI_OBJECT_ID(window); Visual *vis = NULL; Colormap cmap = None; - GstVaapiWindowX11Class *klass; + const GstVaapiWindowX11Class *klass; XWindowAttributes wattr; Atom atoms[2]; gboolean ok; @@ -234,7 +223,7 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) "_NET_WM_STATE_FULLSCREEN", }; - if (!priv->create_window && xid) { + if (window->use_foreign_window && xid) { GST_VAAPI_OBJECT_LOCK_DISPLAY(window); XGetWindowAttributes(dpy, xid, &wattr); priv->is_mapped = wattr.map_state == IsViewable; @@ -274,12 +263,11 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) static void gst_vaapi_window_x11_destroy(GstVaapiWindow *window) { - GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); const Window xid = GST_VAAPI_OBJECT_ID(window); if (xid) { - if (priv->create_window) { + if (!window->use_foreign_window) { GST_VAAPI_OBJECT_LOCK_DISPLAY(window); XDestroyWindow(dpy, xid); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); @@ -305,7 +293,8 @@ gst_vaapi_window_x11_get_geometry( static gboolean gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) { - GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; + GstVaapiWindowX11Private * const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); const Window xid = GST_VAAPI_OBJECT_ID(window); XEvent e; @@ -330,7 +319,7 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) } else { send_wmspec_change_state( - GST_VAAPI_WINDOW_X11(window), + window, priv->atom_NET_WM_STATE_FULLSCREEN, TRUE ); @@ -348,7 +337,7 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) } else { send_wmspec_change_state( - GST_VAAPI_WINDOW_X11(window), + window, priv->atom_NET_WM_STATE_FULLSCREEN, FALSE ); @@ -361,7 +350,7 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) return FALSE; /* Try to wait for the completion of the fullscreen mode switch */ - if (priv->create_window && priv->is_mapped) { + if (!window->use_foreign_window && priv->is_mapped) { const guint DELAY = 100000; /* 100 ms */ g_get_current_time(&now); end_time = DELAY + ((guint64)now.tv_sec * 1000000 + now.tv_usec); @@ -445,38 +434,18 @@ gst_vaapi_window_x11_render( return TRUE; } -static void -gst_vaapi_window_x11_finalize(GObject *object) -{ - G_OBJECT_CLASS(gst_vaapi_window_x11_parent_class)->finalize(object); -} - -static void -gst_vaapi_window_x11_constructed(GObject *object) -{ - GstVaapiWindowX11 * const window = GST_VAAPI_WINDOW_X11(object); - GObjectClass *parent_class; - - window->priv->create_window = GST_VAAPI_OBJECT_ID(object) == None; - - parent_class = G_OBJECT_CLASS(gst_vaapi_window_x11_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); -} - -static void +void gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstVaapiWindowClass * const window_class = GST_VAAPI_WINDOW_CLASS(klass); + GstVaapiObjectClass * const object_class = + GST_VAAPI_OBJECT_CLASS(klass); + GstVaapiWindowClass * const window_class = + GST_VAAPI_WINDOW_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiWindowX11Private)); - - object_class->finalize = gst_vaapi_window_x11_finalize; - object_class->constructed = gst_vaapi_window_x11_constructed; + object_class->finalize = (GstVaapiObjectFinalizeFunc) + gst_vaapi_window_x11_destroy; window_class->create = gst_vaapi_window_x11_create; - window_class->destroy = gst_vaapi_window_x11_destroy; window_class->show = gst_vaapi_window_x11_show; window_class->hide = gst_vaapi_window_x11_hide; window_class->get_geometry = gst_vaapi_window_x11_get_geometry; @@ -485,16 +454,13 @@ gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) window_class->render = gst_vaapi_window_x11_render; } -static void -gst_vaapi_window_x11_init(GstVaapiWindowX11 *window) -{ - GstVaapiWindowX11Private *priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); +#define gst_vaapi_window_x11_finalize \ + gst_vaapi_window_x11_destroy - window->priv = priv; - priv->create_window = TRUE; - priv->is_mapped = FALSE; - priv->fullscreen_on_map = FALSE; -} +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( + GstVaapiWindowX11, + gst_vaapi_window_x11, + gst_vaapi_window_x11_class_init(&g_class)) /** * gst_vaapi_window_x11_new: @@ -513,16 +479,8 @@ gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) { GST_DEBUG("new window, size %ux%u", width, height); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(width > 0, NULL); - g_return_val_if_fail(height > 0, NULL); - - return g_object_new(GST_VAAPI_TYPE_WINDOW_X11, - "display", display, - "id", GST_VAAPI_ID(None), - "width", width, - "height", height, - NULL); + return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( + gst_vaapi_window_x11_class()), display, width, height); } /** @@ -542,13 +500,10 @@ gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) { GST_DEBUG("new window from xid 0x%08x", xid); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); g_return_val_if_fail(xid != None, NULL); - return g_object_new(GST_VAAPI_TYPE_WINDOW_X11, - "display", display, - "id", GST_VAAPI_ID(xid), - NULL); + return gst_vaapi_window_new_from_native(GST_VAAPI_WINDOW_CLASS( + gst_vaapi_window_x11_class()), display, GINT_TO_POINTER(xid)); } /** @@ -583,5 +538,5 @@ gst_vaapi_window_x11_is_foreign_xid(GstVaapiWindowX11 *window) { g_return_val_if_fail(GST_VAAPI_IS_WINDOW_X11(window), FALSE); - return !window->priv->create_window; + return GST_VAAPI_WINDOW(window)->use_foreign_window; } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index 47d9665544..507dd9bb8f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -29,29 +29,11 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_WINDOW_X11 \ - (gst_vaapi_window_x11_get_type()) - -#define GST_VAAPI_WINDOW_X11(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_WINDOW_X11, \ - GstVaapiWindowX11)) - -#define GST_VAAPI_WINDOW_X11_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_WINDOW_X11, \ - GstVaapiWindowX11Class)) +#define GST_VAAPI_WINDOW_X11(obj) \ + ((GstVaapiWindowX11 *)(obj)) #define GST_VAAPI_IS_WINDOW_X11(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW_X11)) - -#define GST_VAAPI_IS_WINDOW_X11_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW_X11)) - -#define GST_VAAPI_WINDOW_X11_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_WINDOW_X11, \ - GstVaapiWindowX11Class)) + ((obj) != NULL) /** * GST_VAAPI_WINDOW_XWINDOW: @@ -63,40 +45,6 @@ G_BEGIN_DECLS gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(window)) typedef struct _GstVaapiWindowX11 GstVaapiWindowX11; -typedef struct _GstVaapiWindowX11Private GstVaapiWindowX11Private; -typedef struct _GstVaapiWindowX11Class GstVaapiWindowX11Class; - -/** - * GstVaapiWindowX11: - * - * An X11 #Window wrapper. - */ -struct _GstVaapiWindowX11 { - /*< private >*/ - GstVaapiWindow parent_instance; - - GstVaapiWindowX11Private *priv; -}; - -/** - * GstVaapiWindowX11Class: - * @get_visual: virtual function to get the desired visual used to - * create the window - * @get_colormap: virtual function to get the desired colormap used to - * create the window - * - * An X11 #Window wrapper class. - */ -struct _GstVaapiWindowX11Class { - /*< private >*/ - GstVaapiWindowClass parent_class; - - Visual * (*get_visual) (GstVaapiWindow *window); - Colormap (*get_colormap) (GstVaapiWindow *window); -}; - -GType -gst_vaapi_window_x11_get_type(void) G_GNUC_CONST; GstVaapiWindow * gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h new file mode 100644 index 0000000000..2622ac8147 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -0,0 +1,83 @@ +/* + * gstvaapiwindow_x11_priv.h - VA/X11 window abstraction (private definitions) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation + * + * 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_WINDOW_X11_PRIV_H +#define GST_VAAPI_WINDOW_X11_PRIV_H + +#include "gstvaapiwindow_priv.h" + +G_BEGIN_DECLS + +#define GST_VAAPI_WINDOW_X11_GET_PRIVATE(obj) \ + (&GST_VAAPI_WINDOW_X11(obj)->priv) + +#define GST_VAAPI_WINDOW_X11_CLASS(klass) \ + ((GstVaapiWindowX11Class *)(klass)) + +#define GST_VAAPI_WINDOW_X11_GET_CLASS(obj) \ + GST_VAAPI_WINDOW_X11_CLASS(GST_VAAPI_WINDOW_GET_CLASS(obj)) + +typedef struct _GstVaapiWindowX11Private GstVaapiWindowX11Private; +typedef struct _GstVaapiWindowX11Class GstVaapiWindowX11Class; + +struct _GstVaapiWindowX11Private { + Atom atom_NET_WM_STATE; + Atom atom_NET_WM_STATE_FULLSCREEN; + guint is_mapped : 1; + guint fullscreen_on_map : 1; +}; + +/** + * GstVaapiWindowX11: + * + * An X11 #Window wrapper. + */ +struct _GstVaapiWindowX11 { + /*< private >*/ + GstVaapiWindow parent_instance; + + GstVaapiWindowX11Private priv; +}; + +/** + * GstVaapiWindowX11Class: + * @get_visual: virtual function to get the desired visual used to + * create the window + * @get_colormap: virtual function to get the desired colormap used to + * create the window + * + * An X11 #Window wrapper class. + */ +struct _GstVaapiWindowX11Class { + /*< private >*/ + GstVaapiWindowClass parent_class; + + Visual * (*get_visual) (GstVaapiWindow *window); + Colormap (*get_colormap) (GstVaapiWindow *window); +}; + +void +gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass); + +G_END_DECLS + +#endif /* GST_VAAPI_WINDOW_X11_PRIV_H */ From 98c70689370a1cdfd5dfe9fd52a5c51367babb3a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 30 Apr 2013 17:22:00 +0200 Subject: [PATCH 1177/3781] libs: use GstVaapiObject for texture objects. --- gst-libs/gst/vaapi/gstvaapitexture.c | 420 +++++++++++---------------- gst-libs/gst/vaapi/gstvaapitexture.h | 63 +--- 2 files changed, 181 insertions(+), 302 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 6f3f75b17a..13696cdf7f 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -31,20 +31,23 @@ #include "gstvaapiutils.h" #include "gstvaapiutils_glx.h" #include "gstvaapidisplay_glx.h" -#include "gstvaapi_priv.h" #include "gstvaapidisplay_x11_priv.h" +#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiTexture, gst_vaapi_texture, GST_VAAPI_TYPE_OBJECT) +typedef struct _GstVaapiTextureClass GstVaapiTextureClass; -#define GST_VAAPI_TEXTURE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_TEXTURE, \ - GstVaapiTexturePrivate)) +/** + * GstVaapiTexture: + * + * Base object for system-dependent textures. + */ +struct _GstVaapiTexture { + /*< private >*/ + GstVaapiObject parent_instance; -struct _GstVaapiTexturePrivate { GLenum target; GLenum format; guint width; @@ -54,54 +57,51 @@ struct _GstVaapiTexturePrivate { GLPixmapObject *pixo; GLFramebufferObject *fbo; guint foreign_texture : 1; - guint is_constructed : 1; }; -enum { - PROP_0, - - PROP_TARGET, - PROP_FORMAT, - PROP_WIDTH, - PROP_HEIGHT +/** + * GstVaapiTextureClass: + * + * Base class for system-dependent textures. + */ +struct _GstVaapiTextureClass { + GstVaapiObjectClass parent_class; }; static void _gst_vaapi_texture_destroy_objects(GstVaapiTexture *texture) { - GstVaapiTexturePrivate * const priv = texture->priv; - #if USE_VAAPI_GLX GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - if (priv->gl_surface) { + if (texture->gl_surface) { vaDestroySurfaceGLX( GST_VAAPI_OBJECT_VADISPLAY(texture), - priv->gl_surface + texture->gl_surface ); - priv->gl_surface = NULL; + texture->gl_surface = NULL; } GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); #else GLContextState old_cs; GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - if (priv->gl_context) - gl_set_current_context(priv->gl_context, &old_cs); + if (texture->gl_context) + gl_set_current_context(texture->gl_context, &old_cs); - if (priv->fbo) { - gl_destroy_framebuffer_object(priv->fbo); - priv->fbo = NULL; + if (texture->fbo) { + gl_destroy_framebuffer_object(texture->fbo); + texture->fbo = NULL; } - if (priv->pixo) { - gl_destroy_pixmap_object(priv->pixo); - priv->pixo = NULL; + if (texture->pixo) { + gl_destroy_pixmap_object(texture->pixo); + texture->pixo = NULL; } - if (priv->gl_context) { + if (texture->gl_context) { gl_set_current_context(&old_cs, NULL); - gl_destroy_context(priv->gl_context); - priv->gl_context = NULL; + gl_destroy_context(texture->gl_context); + texture->gl_context = NULL; } GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); #endif @@ -110,13 +110,12 @@ _gst_vaapi_texture_destroy_objects(GstVaapiTexture *texture) static void gst_vaapi_texture_destroy(GstVaapiTexture *texture) { - GstVaapiTexturePrivate * const priv = texture->priv; const GLuint texture_id = GST_VAAPI_OBJECT_ID(texture); _gst_vaapi_texture_destroy_objects(texture); if (texture_id) { - if (!priv->foreign_texture) + if (!texture->foreign_texture) glDeleteTextures(1, &texture_id); GST_VAAPI_OBJECT_ID(texture) = 0; } @@ -125,7 +124,6 @@ gst_vaapi_texture_destroy(GstVaapiTexture *texture) static gboolean _gst_vaapi_texture_create_objects(GstVaapiTexture *texture, GLuint texture_id) { - GstVaapiTexturePrivate * const priv = texture->priv; gboolean success = FALSE; #if USE_VAAPI_GLX @@ -134,9 +132,9 @@ _gst_vaapi_texture_create_objects(GstVaapiTexture *texture, GLuint texture_id) GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); status = vaCreateSurfaceGLX( GST_VAAPI_OBJECT_VADISPLAY(texture), - priv->target, + texture->target, texture_id, - &priv->gl_surface + &texture->gl_surface ); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); success = vaapi_check_status(status, "vaCreateSurfaceGLX()"); @@ -145,29 +143,30 @@ _gst_vaapi_texture_create_objects(GstVaapiTexture *texture, GLuint texture_id) GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); gl_get_current_context(&old_cs); - priv->gl_context = gl_create_context( + texture->gl_context = gl_create_context( GST_VAAPI_OBJECT_XDISPLAY(texture), GST_VAAPI_OBJECT_XSCREEN(texture), &old_cs ); - if (!priv->gl_context || !gl_set_current_context(priv->gl_context, NULL)) + if (!texture->gl_context || + !gl_set_current_context(texture->gl_context, NULL)) goto end; - priv->pixo = gl_create_pixmap_object( + texture->pixo = gl_create_pixmap_object( GST_VAAPI_OBJECT_XDISPLAY(texture), - priv->width, - priv->height + texture->width, + texture->height ); - if (!priv->pixo) + if (!texture->pixo) goto end; - priv->fbo = gl_create_framebuffer_object( - priv->target, + texture->fbo = gl_create_framebuffer_object( + texture->target, texture_id, - priv->width, - priv->height + texture->width, + texture->height ); - if (priv->fbo) + if (texture->fbo) success = TRUE; end: gl_set_current_context(&old_cs, NULL); @@ -179,18 +178,17 @@ end: static gboolean gst_vaapi_texture_create(GstVaapiTexture *texture) { - GstVaapiTexturePrivate * const priv = texture->priv; GLuint texture_id; - if (priv->foreign_texture) + if (texture->foreign_texture) texture_id = GST_VAAPI_OBJECT_ID(texture); else { GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); texture_id = gl_create_texture( - priv->target, - priv->format, - priv->width, - priv->height + texture->target, + texture->format, + texture->width, + texture->height ); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); if (!texture_id) @@ -202,151 +200,20 @@ gst_vaapi_texture_create(GstVaapiTexture *texture) } static void -gst_vaapi_texture_finalize(GObject *object) +gst_vaapi_texture_init(GstVaapiTexture *texture, GLuint texture_id, + GLenum target, GLenum format, guint width, guint height) { - gst_vaapi_texture_destroy(GST_VAAPI_TEXTURE(object)); + GST_VAAPI_OBJECT_ID(texture) = texture_id; + texture->foreign_texture = texture_id != GL_NONE; - G_OBJECT_CLASS(gst_vaapi_texture_parent_class)->finalize(object); + texture->target = target; + texture->format = format; + texture->width = width; + texture->height = height; } -static void -gst_vaapi_texture_constructed(GObject *object) -{ - GstVaapiTexture * const texture = GST_VAAPI_TEXTURE(object); - GObjectClass *parent_class; - - texture->priv->foreign_texture = GST_VAAPI_OBJECT_ID(texture) != 0; - texture->priv->is_constructed = gst_vaapi_texture_create(texture); - - parent_class = G_OBJECT_CLASS(gst_vaapi_texture_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); -} - -static void -gst_vaapi_texture_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiTexture * const texture = GST_VAAPI_TEXTURE(object); - - switch (prop_id) { - case PROP_TARGET: - texture->priv->target = g_value_get_uint(value); - break; - case PROP_FORMAT: - texture->priv->format = g_value_get_uint(value); - break; - case PROP_WIDTH: - texture->priv->width = g_value_get_uint(value); - break; - case PROP_HEIGHT: - texture->priv->height = g_value_get_uint(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_texture_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiTexture * const texture = GST_VAAPI_TEXTURE(object); - - switch (prop_id) { - case PROP_TARGET: - g_value_set_uint(value, gst_vaapi_texture_get_target(texture)); - break; - case PROP_FORMAT: - g_value_set_uint(value, gst_vaapi_texture_get_format(texture)); - break; - case PROP_WIDTH: - g_value_set_uint(value, gst_vaapi_texture_get_width(texture)); - break; - case PROP_HEIGHT: - g_value_set_uint(value, gst_vaapi_texture_get_height(texture)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_texture_class_init(GstVaapiTextureClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiTexturePrivate)); - - object_class->finalize = gst_vaapi_texture_finalize; - object_class->set_property = gst_vaapi_texture_set_property; - object_class->get_property = gst_vaapi_texture_get_property; - object_class->constructed = gst_vaapi_texture_constructed; - - g_object_class_install_property - (object_class, - PROP_TARGET, - g_param_spec_uint("target", - "Target", - "The texture target", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_FORMAT, - g_param_spec_uint("format", - "Format", - "The texture format", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_WIDTH, - g_param_spec_uint("width", - "width", - "The texture width", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, - PROP_HEIGHT, - g_param_spec_uint("height", - "height", - "The texture height", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); -} - -static void -gst_vaapi_texture_init(GstVaapiTexture *texture) -{ - GstVaapiTexturePrivate *priv = GST_VAAPI_TEXTURE_GET_PRIVATE(texture); - - texture->priv = priv; - priv->target = GL_NONE; - priv->format = GL_NONE; - priv->width = 0; - priv->height = 0; - priv->gl_context = NULL; - priv->gl_surface = NULL; - priv->pixo = NULL; - priv->fbo = NULL; - priv->foreign_texture = FALSE; - priv->is_constructed = FALSE; -} +#define gst_vaapi_texture_finalize gst_vaapi_texture_destroy +GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiTexture, gst_vaapi_texture) /** * gst_vaapi_texture_new: @@ -376,29 +243,39 @@ gst_vaapi_texture_new( guint height ) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + GstVaapiTexture *texture; - return g_object_new(GST_VAAPI_TYPE_TEXTURE, - "display", display, - "id", GST_VAAPI_ID(0), - "target", target, - "format", format, - "width", width, - "height", height, - NULL); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(target != GL_NONE, NULL); + g_return_val_if_fail(format != GL_NONE, NULL); + g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(height > 0, NULL); + + texture = gst_vaapi_object_new(gst_vaapi_texture_class(), display); + if (!texture) + return NULL; + + gst_vaapi_texture_init(texture, GL_NONE, target, format, width, height); + if (!gst_vaapi_texture_create(texture)) + goto error; + return texture; + +error: + gst_vaapi_object_unref(texture); + return NULL; } /** * gst_vaapi_texture_new_with_texture: * @display: a #GstVaapiDisplay - * @texture: the foreign GL texture name to use + * @texture_id: the foreign GL texture name to use * @target: the target to which the texture is bound * @format: the format of the pixel data * * Creates a texture from an existing GL texture, with the specified * @target and @format. Note that only GL_TEXTURE_2D @target and * GL_RGBA or GL_BGRA formats are supported at this time. The - * dimensions will be retrieved from the @texture. + * dimensions will be retrieved from the @texture_id. * * The application shall maintain the live GL context itself. That is, * gst_vaapi_window_glx_make_current() must be called beforehand, or @@ -410,20 +287,23 @@ gst_vaapi_texture_new( GstVaapiTexture * gst_vaapi_texture_new_with_texture( GstVaapiDisplay *display, - GLuint texture, + GLuint texture_id, GLenum target, GLenum format ) { + GstVaapiTexture *texture; guint width, height, border_width; GLTextureState ts; gboolean success; g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(target != GL_NONE, NULL); + g_return_val_if_fail(format != GL_NONE, NULL); /* Check texture dimensions */ GST_VAAPI_DISPLAY_LOCK(display); - success = gl_bind_texture(&ts, target, texture); + success = gl_bind_texture(&ts, target, texture_id); if (success) { if (!gl_get_texture_param(target, GL_TEXTURE_WIDTH, &width) || !gl_get_texture_param(target, GL_TEXTURE_HEIGHT, &height) || @@ -437,17 +317,64 @@ gst_vaapi_texture_new_with_texture( width -= 2 * border_width; height -= 2 * border_width; - if (width == 0 || height == 0) + g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(height > 0, NULL); + + texture = gst_vaapi_object_new(gst_vaapi_texture_class(), display); + if (!texture) return NULL; - return g_object_new(GST_VAAPI_TYPE_TEXTURE, - "display", display, - "id", GST_VAAPI_ID(texture), - "target", target, - "format", format, - "width", width, - "height", height, - NULL); + gst_vaapi_texture_init(texture, texture_id, target, format, width, height); + if (!gst_vaapi_texture_create(texture)) + goto error; + return texture; + +error: + gst_vaapi_object_unref(texture); + return NULL; +} + +/** + * gst_vaapi_texture_ref: + * @texture: a #GstVaapiTexture + * + * Atomically increases the reference count of the given @texture by one. + * + * Returns: The same @texture argument + */ +GstVaapiTexture * +gst_vaapi_texture_ref(GstVaapiTexture *texture) +{ + return gst_vaapi_object_ref(texture); +} + +/** + * gst_vaapi_texture_unref: + * @texture: a #GstVaapiTexture + * + * Atomically decreases the reference count of the @texture by one. If + * the reference count reaches zero, the texture will be free'd. + */ +void +gst_vaapi_texture_unref(GstVaapiTexture *texture) +{ + gst_vaapi_object_unref(texture); +} + +/** + * gst_vaapi_texture_replace: + * @old_texture_ptr: a pointer to a #GstVaapiTexture + * @new_texture: a #GstVaapiTexture + * + * Atomically replaces the texture texture held in @old_texture_ptr + * with @new_texture. This means that @old_texture_ptr shall reference + * a valid texture. However, @new_texture can be NULL. + */ +void +gst_vaapi_texture_replace(GstVaapiTexture **old_texture_ptr, + GstVaapiTexture *new_texture) +{ + gst_vaapi_object_replace(old_texture_ptr, new_texture); } /** @@ -461,7 +388,7 @@ gst_vaapi_texture_new_with_texture( GLuint gst_vaapi_texture_get_id(GstVaapiTexture *texture) { - g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), 0); + g_return_val_if_fail(texture != NULL, 0); return GST_VAAPI_OBJECT_ID(texture); } @@ -477,10 +404,9 @@ gst_vaapi_texture_get_id(GstVaapiTexture *texture) GLenum gst_vaapi_texture_get_target(GstVaapiTexture *texture) { - g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), GL_NONE); - g_return_val_if_fail(texture->priv->is_constructed, GL_NONE); + g_return_val_if_fail(texture != NULL, GL_NONE); - return texture->priv->target; + return texture->target; } /** @@ -494,10 +420,9 @@ gst_vaapi_texture_get_target(GstVaapiTexture *texture) GLenum gst_vaapi_texture_get_format(GstVaapiTexture *texture) { - g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), GL_NONE); - g_return_val_if_fail(texture->priv->is_constructed, GL_NONE); + g_return_val_if_fail(texture != NULL, GL_NONE); - return texture->priv->format; + return texture->format; } /** @@ -511,10 +436,9 @@ gst_vaapi_texture_get_format(GstVaapiTexture *texture) guint gst_vaapi_texture_get_width(GstVaapiTexture *texture) { - g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), 0); - g_return_val_if_fail(texture->priv->is_constructed, 0); + g_return_val_if_fail(texture != NULL, 0); - return texture->priv->width; + return texture->width; } /** @@ -528,10 +452,9 @@ gst_vaapi_texture_get_width(GstVaapiTexture *texture) guint gst_vaapi_texture_get_height(GstVaapiTexture *texture) { - g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), 0); - g_return_val_if_fail(texture->priv->is_constructed, 0); + g_return_val_if_fail(texture != NULL, 0); - return texture->priv->height; + return texture->height; } /** @@ -549,14 +472,13 @@ gst_vaapi_texture_get_size( guint *pheight ) { - g_return_if_fail(GST_VAAPI_IS_TEXTURE(texture)); - g_return_if_fail(texture->priv->is_constructed); + g_return_if_fail(texture != NULL); if (pwidth) - *pwidth = texture->priv->width; + *pwidth = texture->width; if (pheight) - *pheight = texture->priv->height; + *pheight = texture->height; } /** @@ -578,14 +500,13 @@ _gst_vaapi_texture_put_surface( guint flags ) { - GstVaapiTexturePrivate * const priv = texture->priv; VAStatus status; #if USE_VAAPI_GLX GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); status = vaCopySurfaceGLX( GST_VAAPI_OBJECT_VADISPLAY(texture), - priv->gl_surface, + texture->gl_surface, GST_VAAPI_OBJECT_ID(surface), from_GstVaapiSurfaceRenderFlags(flags) ); @@ -603,9 +524,9 @@ _gst_vaapi_texture_put_surface( status = vaPutSurface( GST_VAAPI_OBJECT_VADISPLAY(texture), GST_VAAPI_OBJECT_ID(surface), - priv->pixo->pixmap, + texture->pixo->pixmap, 0, 0, surface_width, surface_height, - 0, 0, priv->width, priv->height, + 0, 0, texture->width, texture->height, NULL, 0, from_GstVaapiSurfaceRenderFlags(flags) ); @@ -614,13 +535,13 @@ _gst_vaapi_texture_put_surface( return FALSE; GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - if (priv->gl_context) { - success = gl_set_current_context(priv->gl_context, &old_cs); + if (texture->gl_context) { + success = gl_set_current_context(texture->gl_context, &old_cs); if (!success) goto end; } - success = gl_bind_framebuffer_object(priv->fbo); + success = gl_bind_framebuffer_object(texture->fbo); if (!success) { GST_DEBUG("could not bind FBO"); goto out_reset_context; @@ -634,7 +555,7 @@ _gst_vaapi_texture_put_surface( goto out_unbind_fbo; } - success = gl_bind_pixmap_object(priv->pixo); + success = gl_bind_pixmap_object(texture->pixo); if (!success) { GST_DEBUG("could not bind GLX pixmap"); goto out_unbind_fbo; @@ -643,24 +564,24 @@ _gst_vaapi_texture_put_surface( glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); { - glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0 ); - glTexCoord2f(0.0f, 1.0f); glVertex2i(0, priv->height); - glTexCoord2f(1.0f, 1.0f); glVertex2i(priv->width, priv->height); - glTexCoord2f(1.0f, 0.0f); glVertex2i(priv->width, 0 ); + glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0 ); + glTexCoord2f(0.0f, 1.0f); glVertex2i(0, texture->height); + glTexCoord2f(1.0f, 1.0f); glVertex2i(texture->width, texture->height); + glTexCoord2f(1.0f, 0.0f); glVertex2i(texture->width, 0 ); } glEnd(); - success = gl_unbind_pixmap_object(priv->pixo); + success = gl_unbind_pixmap_object(texture->pixo); if (!success) { GST_DEBUG("could not release GLX pixmap"); goto out_unbind_fbo; } out_unbind_fbo: - if (!gl_unbind_framebuffer_object(priv->fbo)) + if (!gl_unbind_framebuffer_object(texture->fbo)) success = FALSE; out_reset_context: - if (priv->gl_context && !gl_set_current_context(&old_cs, NULL)) + if (texture->gl_context && !gl_set_current_context(&old_cs, NULL)) success = FALSE; end: GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); @@ -676,8 +597,7 @@ gst_vaapi_texture_put_surface( guint flags ) { - g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), FALSE); - g_return_val_if_fail(texture->priv->is_constructed, FALSE); + g_return_val_if_fail(texture != NULL, FALSE); g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); return _gst_vaapi_texture_put_surface(texture, surface, flags); diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 42959817ed..f70c89f294 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -31,58 +31,7 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_TEXTURE \ - (gst_vaapi_texture_get_type()) - -#define GST_VAAPI_TEXTURE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_TEXTURE, \ - GstVaapiTexture)) - -#define GST_VAAPI_TEXTURE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_TEXTURE, \ - GstVaapiTextureClass)) - -#define GST_VAAPI_IS_TEXTURE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_TEXTURE)) - -#define GST_VAAPI_IS_TEXTURE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_TEXTURE)) - -#define GST_VAAPI_TEXTURE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_TEXTURE, \ - GstVaapiTextureClass)) - typedef struct _GstVaapiTexture GstVaapiTexture; -typedef struct _GstVaapiTexturePrivate GstVaapiTexturePrivate; -typedef struct _GstVaapiTextureClass GstVaapiTextureClass; - -/** - * GstVaapiTexture: - * - * Base class for system-dependent textures. - */ -struct _GstVaapiTexture { - /*< private >*/ - GstVaapiObject parent_instance; - - GstVaapiTexturePrivate *priv; -}; - -/** - * GstVaapiTextureClass: - * - * Base class for system-dependent textures. - */ -struct _GstVaapiTextureClass { - /*< private >*/ - GstVaapiObjectClass parent_class; -}; - -GType -gst_vaapi_texture_get_type(void) G_GNUC_CONST; GstVaapiTexture * gst_vaapi_texture_new( @@ -96,11 +45,21 @@ gst_vaapi_texture_new( GstVaapiTexture * gst_vaapi_texture_new_with_texture( GstVaapiDisplay *display, - GLuint texture, + GLuint texture_id, GLenum target, GLenum format ); +GstVaapiTexture * +gst_vaapi_texture_ref(GstVaapiTexture *texture); + +void +gst_vaapi_texture_unref(GstVaapiTexture *texture); + +void +gst_vaapi_texture_replace(GstVaapiTexture **old_texture_ptr, + GstVaapiTexture *new_texture); + GLuint gst_vaapi_texture_get_id(GstVaapiTexture *texture); From 2e6ff64a34801a3aaf1e0596e93a1f0b91f6367e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 3 May 2013 11:01:12 +0200 Subject: [PATCH 1178/3781] libs: use GstVaapiMiniObject for video object pools. Port GstVaapiVideoPool, GstVaapiSurfacePool and GstVaapiImagePool to GstVaapiMiniObject. Drop gst_vaapi_video_pool_get_caps() since it was no longer used for a long time. Make object allocators static, i.e. local to the shared library. --- docs/reference/libs/libs-sections.txt | 1 - gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapicontext.c | 3 +- gst-libs/gst/vaapi/gstvaapiimagepool.c | 104 +++---- gst-libs/gst/vaapi/gstvaapiimagepool.h | 51 +--- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 104 +++---- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 51 +--- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 5 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 306 +++++--------------- gst-libs/gst/vaapi/gstvaapivideopool.h | 65 +---- gst-libs/gst/vaapi/gstvaapivideopool_priv.h | 102 +++++++ 11 files changed, 294 insertions(+), 499 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapivideopool_priv.h diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index e9e52761b1..1b26099096 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -20,7 +20,6 @@ GST_VAAPI_SURFACE_POOL_GET_CLASS GstVaapiVideoPool GstVaapiVideoPoolClass gst_vaapi_video_pool_get_display -gst_vaapi_video_pool_get_caps gst_vaapi_video_pool_get_object gst_vaapi_video_pool_put_object gst_vaapi_video_pool_add_object diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 10ea08a8cf..61793481e1 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -117,6 +117,7 @@ libgstvaapi_source_priv_h = \ gstvaapisurfaceproxy_priv.h \ gstvaapiutils.h \ gstvaapiversion.h \ + gstvaapivideopool_priv.h \ gstvaapiwindow_priv.h \ gstvaapiworkarounds.h \ sysdeps.h \ diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 9312384ae7..174e809a58 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -34,6 +34,7 @@ #include "gstvaapisurface_priv.h" #include "gstvaapisurfacepool.h" #include "gstvaapisurfaceproxy.h" +#include "gstvaapivideopool_priv.h" #include "gstvaapiimage.h" #include "gstvaapisubpicture.h" #include "gstvaapiutils.h" @@ -414,7 +415,7 @@ gst_vaapi_context_destroy_surfaces(GstVaapiContext *context) g_ptr_array_free(context->surfaces, TRUE); context->surfaces = NULL; } - g_clear_object(&context->surfaces_pool); + gst_vaapi_video_pool_replace(&context->surfaces_pool, NULL); } static void diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index a23c4a0ec4..1699c2f544 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -27,30 +27,29 @@ #include "sysdeps.h" #include "gstvaapiimagepool.h" +#include "gstvaapivideopool_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE( - GstVaapiImagePool, - gst_vaapi_image_pool, - GST_VAAPI_TYPE_VIDEO_POOL) +/** + * GstVaapiImagePool: + * + * A pool of lazily allocated #GstVaapiImage objects. + */ +struct _GstVaapiImagePool { + /*< private >*/ + GstVaapiVideoPool parent_instance; -#define GST_VAAPI_IMAGE_POOL_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_IMAGE_POOL, \ - GstVaapiImagePoolPrivate)) - -struct _GstVaapiImagePoolPrivate { GstVaapiImageFormat format; guint width; guint height; }; -static void -gst_vaapi_image_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) +static gboolean +gst_vaapi_image_pool_set_caps(GstVaapiVideoPool *base_pool, GstCaps *caps) { - GstVaapiImagePoolPrivate * const priv = GST_VAAPI_IMAGE_POOL(pool)->priv; + GstVaapiImagePool * const pool = GST_VAAPI_IMAGE_POOL(base_pool); GstStructure *structure; gint width, height; @@ -58,54 +57,31 @@ gst_vaapi_image_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) gst_structure_get_int(structure, "width", &width); gst_structure_get_int(structure, "height", &height); - priv->format = gst_vaapi_image_format_from_caps(caps); - priv->width = width; - priv->height = height; + pool->format = gst_vaapi_image_format_from_caps(caps); + pool->width = width; + pool->height = height; + return TRUE; } -gpointer -gst_vaapi_image_pool_alloc_object( - GstVaapiVideoPool *pool, - GstVaapiDisplay *display -) +static gpointer +gst_vaapi_image_pool_alloc_object(GstVaapiVideoPool *base_pool) { - GstVaapiImagePoolPrivate * const priv = GST_VAAPI_IMAGE_POOL(pool)->priv; + GstVaapiImagePool * const pool = GST_VAAPI_IMAGE_POOL(base_pool); - return gst_vaapi_image_new(display, - priv->format, - priv->width, - priv->height); + return gst_vaapi_image_new(base_pool->display, pool->format, + pool->width, pool->height); } -static void -gst_vaapi_image_pool_finalize(GObject *object) +static inline const GstVaapiMiniObjectClass * +gst_vaapi_image_pool_class(void) { - G_OBJECT_CLASS(gst_vaapi_image_pool_parent_class)->finalize(object); -} + static const GstVaapiVideoPoolClass GstVaapiImagePoolClass = { + { sizeof(GstVaapiImagePool), + (GDestroyNotify)gst_vaapi_video_pool_finalize }, -static void -gst_vaapi_image_pool_class_init(GstVaapiImagePoolClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstVaapiVideoPoolClass * const pool_class = GST_VAAPI_VIDEO_POOL_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiImagePoolPrivate)); - - object_class->finalize = gst_vaapi_image_pool_finalize; - - pool_class->set_caps = gst_vaapi_image_pool_set_caps; - pool_class->alloc_object = gst_vaapi_image_pool_alloc_object; -} - -static void -gst_vaapi_image_pool_init(GstVaapiImagePool *pool) -{ - GstVaapiImagePoolPrivate *priv = GST_VAAPI_IMAGE_POOL_GET_PRIVATE(pool); - - pool->priv = priv; - priv->format = 0; - priv->width = 0; - priv->height = 0; + .alloc_object = gst_vaapi_image_pool_alloc_object + }; + return GST_VAAPI_MINI_OBJECT_CLASS(&GstVaapiImagePoolClass); } /** @@ -121,8 +97,22 @@ gst_vaapi_image_pool_init(GstVaapiImagePool *pool) GstVaapiVideoPool * gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps) { - return g_object_new(GST_VAAPI_TYPE_IMAGE_POOL, - "display", display, - "caps", caps, - NULL); + GstVaapiVideoPool *pool; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + pool = (GstVaapiVideoPool *) + gst_vaapi_mini_object_new(gst_vaapi_image_pool_class()); + if (!pool) + return NULL; + + gst_vaapi_video_pool_init(pool, display); + if (!gst_vaapi_image_pool_set_caps(pool, caps)) + goto error; + return pool; + +error: + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pool)); + return NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index fa6d6b15cd..a56a18a21e 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -28,58 +28,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_IMAGE_POOL \ - (gst_vaapi_image_pool_get_type()) - -#define GST_VAAPI_IMAGE_POOL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_IMAGE_POOL, \ - GstVaapiImagePool)) - -#define GST_VAAPI_IMAGE_POOL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_IMAGE_POOL, \ - GstVaapiImagePoolClass)) +#define GST_VAAPI_IMAGE_POOL(obj) \ + ((GstVaapiImagePool *)(obj)) #define GST_VAAPI_IS_IMAGE_POOL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_IMAGE_POOL)) - -#define GST_VAAPI_IS_IMAGE_POOL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_IMAGE_POOL)) - -#define GST_VAAPI_IMAGE_POOL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_IMAGE_POOL, \ - GstVaapiImagePoolClass)) + ((obj) != NULL) typedef struct _GstVaapiImagePool GstVaapiImagePool; -typedef struct _GstVaapiImagePoolPrivate GstVaapiImagePoolPrivate; -typedef struct _GstVaapiImagePoolClass GstVaapiImagePoolClass; - -/** - * GstVaapiImagePool: - * - * A pool of lazily allocated #GstVaapiImage objects. - */ -struct _GstVaapiImagePool { - /*< private >*/ - GstVaapiVideoPool parent_instance; - - GstVaapiImagePoolPrivate *priv; -}; - -/** - * GstVaapiImagePoolClass: - * - * A pool of lazily allocated #GstVaapiImage objects. - */ -struct _GstVaapiImagePoolClass { - /*< private >*/ - GstVaapiVideoPoolClass parent_class; -}; - -GType -gst_vaapi_image_pool_get_type(void) G_GNUC_CONST; GstVaapiVideoPool * gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 0caf5ad1bd..33118a653c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -27,30 +27,29 @@ #include "sysdeps.h" #include "gstvaapisurfacepool.h" +#include "gstvaapivideopool_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE( - GstVaapiSurfacePool, - gst_vaapi_surface_pool, - GST_VAAPI_TYPE_VIDEO_POOL) +/** + * GstVaapiSurfacePool: + * + * A pool of lazily allocated #GstVaapiSurface objects. + */ +struct _GstVaapiSurfacePool { + /*< private >*/ + GstVaapiVideoPool parent_instance; -#define GST_VAAPI_SURFACE_POOL_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_SURFACE_POOL, \ - GstVaapiSurfacePoolPrivate)) - -struct _GstVaapiSurfacePoolPrivate { GstVaapiChromaType chroma_type; guint width; guint height; }; -static void -gst_vaapi_surface_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) +static gboolean +gst_vaapi_surface_pool_set_caps(GstVaapiVideoPool *base_pool, GstCaps *caps) { - GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL(pool)->priv; + GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(base_pool); GstStructure *structure; gint width, height; @@ -58,54 +57,31 @@ gst_vaapi_surface_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) gst_structure_get_int(structure, "width", &width); gst_structure_get_int(structure, "height", &height); - priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - priv->width = width; - priv->height = height; + pool->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + pool->width = width; + pool->height = height; + return TRUE; } -gpointer -gst_vaapi_surface_pool_alloc_object( - GstVaapiVideoPool *pool, - GstVaapiDisplay *display -) +static gpointer +gst_vaapi_surface_pool_alloc_object(GstVaapiVideoPool *base_pool) { - GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL(pool)->priv; + GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(base_pool); - return gst_vaapi_surface_new(display, - priv->chroma_type, - priv->width, - priv->height); + return gst_vaapi_surface_new(base_pool->display, + pool->chroma_type, pool->width, pool->height); } -static void -gst_vaapi_surface_pool_finalize(GObject *object) +static inline const GstVaapiMiniObjectClass * +gst_vaapi_surface_pool_class(void) { - G_OBJECT_CLASS(gst_vaapi_surface_pool_parent_class)->finalize(object); -} + static const GstVaapiVideoPoolClass GstVaapiSurfacePoolClass = { + { sizeof(GstVaapiSurfacePool), + (GDestroyNotify)gst_vaapi_video_pool_finalize }, -static void -gst_vaapi_surface_pool_class_init(GstVaapiSurfacePoolClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstVaapiVideoPoolClass * const pool_class = GST_VAAPI_VIDEO_POOL_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiSurfacePoolPrivate)); - - object_class->finalize = gst_vaapi_surface_pool_finalize; - - pool_class->set_caps = gst_vaapi_surface_pool_set_caps; - pool_class->alloc_object = gst_vaapi_surface_pool_alloc_object; -} - -static void -gst_vaapi_surface_pool_init(GstVaapiSurfacePool *pool) -{ - GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL_GET_PRIVATE(pool); - - pool->priv = priv; - priv->chroma_type = 0; - priv->width = 0; - priv->height = 0; + .alloc_object = gst_vaapi_surface_pool_alloc_object + }; + return GST_VAAPI_MINI_OBJECT_CLASS(&GstVaapiSurfacePoolClass); } /** @@ -121,8 +97,22 @@ gst_vaapi_surface_pool_init(GstVaapiSurfacePool *pool) GstVaapiVideoPool * gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps) { - return g_object_new(GST_VAAPI_TYPE_SURFACE_POOL, - "display", display, - "caps", caps, - NULL); + GstVaapiVideoPool *pool; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + pool = (GstVaapiVideoPool *) + gst_vaapi_mini_object_new(gst_vaapi_surface_pool_class()); + if (!pool) + return NULL; + + gst_vaapi_video_pool_init(pool, display); + if (!gst_vaapi_surface_pool_set_caps(pool, caps)) + goto error; + return pool; + +error: + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pool)); + return NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index aff88ca890..635af47dc9 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -28,58 +28,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_SURFACE_POOL \ - (gst_vaapi_surface_pool_get_type()) - -#define GST_VAAPI_SURFACE_POOL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_SURFACE_POOL, \ - GstVaapiSurfacePool)) - -#define GST_VAAPI_SURFACE_POOL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_SURFACE_POOL, \ - GstVaapiSurfacePoolClass)) +#define GST_VAAPI_SURFACE_POOL(obj) \ + ((GstVaapiSurfacePool *)(obj)) #define GST_VAAPI_IS_SURFACE_POOL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SURFACE_POOL)) - -#define GST_VAAPI_IS_SURFACE_POOL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SURFACE_POOL)) - -#define GST_VAAPI_SURFACE_POOL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_SURFACE_POOL, \ - GstVaapiSurfacePoolClass)) + ((obj) != NULL) typedef struct _GstVaapiSurfacePool GstVaapiSurfacePool; -typedef struct _GstVaapiSurfacePoolPrivate GstVaapiSurfacePoolPrivate; -typedef struct _GstVaapiSurfacePoolClass GstVaapiSurfacePoolClass; - -/** - * GstVaapiSurfacePool: - * - * A pool of lazily allocated #GstVaapiSurface objects. - */ -struct _GstVaapiSurfacePool { - /*< private >*/ - GstVaapiVideoPool parent_instance; - - GstVaapiSurfacePoolPrivate *priv; -}; - -/** - * GstVaapiSurfacePoolClass: - * - * A pool of lazily allocated #GstVaapiSurface objects. - */ -struct _GstVaapiSurfacePoolClass { - /*< private >*/ - GstVaapiVideoPoolClass parent_class; -}; - -GType -gst_vaapi_surface_pool_get_type(void) G_GNUC_CONST; GstVaapiVideoPool * gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 9479866fbf..86168eb2cf 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -28,6 +28,7 @@ #include "sysdeps.h" #include "gstvaapisurfaceproxy.h" #include "gstvaapisurfaceproxy_priv.h" +#include "gstvaapivideopool_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -44,7 +45,7 @@ gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) gst_vaapi_object_unref(proxy->surface); proxy->surface = NULL; } - g_clear_object(&proxy->pool); + gst_vaapi_video_pool_replace(&proxy->pool, NULL); } static inline const GstVaapiMiniObjectClass * @@ -69,7 +70,7 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) if (!proxy) return NULL; - proxy->pool = g_object_ref(pool); + proxy->pool = gst_vaapi_video_pool_ref(pool); proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool); if (!proxy->surface) goto error; diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index ded8ec9711..adb7b34f8b 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -27,207 +27,92 @@ #include "sysdeps.h" #include "gstvaapivideopool.h" +#include "gstvaapivideopool_priv.h" #include "gstvaapiobject.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiVideoPool, gst_vaapi_video_pool, G_TYPE_OBJECT) +/* Ensure those symbols are actually defined in the resulting libraries */ +#undef gst_vaapi_video_pool_ref +#undef gst_vaapi_video_pool_unref +#undef gst_vaapi_video_pool_replace -#define GST_VAAPI_VIDEO_POOL_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_VIDEO_POOL, \ - GstVaapiVideoPoolPrivate)) +#define GST_VAAPI_VIDEO_POOL_GET_CLASS(obj) \ + gst_vaapi_video_pool_get_class(GST_VAAPI_VIDEO_POOL(obj)) -struct _GstVaapiVideoPoolPrivate { - GstVaapiDisplay *display; - GQueue free_objects; - GList *used_objects; - GstCaps *caps; - guint used_count; - guint capacity; -}; - -enum { - PROP_0, - - PROP_DISPLAY, - PROP_CAPS, - PROP_CAPACITY -}; - -static void -gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps); +static inline const GstVaapiVideoPoolClass * +gst_vaapi_video_pool_get_class(GstVaapiVideoPool *pool) +{ + return GST_VAAPI_VIDEO_POOL_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(pool)); +} static inline gpointer gst_vaapi_video_pool_alloc_object(GstVaapiVideoPool *pool) { - GstVaapiVideoPoolClass * const klass = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool); - - return klass->alloc_object(pool, pool->priv->display); + return GST_VAAPI_VIDEO_POOL_GET_CLASS(pool)->alloc_object(pool); } -static void -gst_vaapi_video_pool_clear(GstVaapiVideoPool *pool) +void +gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display) { - GstVaapiVideoPoolPrivate * const priv = pool->priv; - gpointer object; - GList *list, *next; + pool->display = g_object_ref(display); + pool->used_objects = NULL; + pool->used_count = 0; + pool->capacity = 0; - for (list = priv->used_objects; list; list = next) { - next = list->next; - gst_vaapi_object_unref(list->data); - g_list_free_1(list); - } - priv->used_objects = NULL; - - while ((object = g_queue_pop_head(&priv->free_objects))) - gst_vaapi_object_unref(object); + g_queue_init(&pool->free_objects); } -static void -gst_vaapi_video_pool_destroy(GstVaapiVideoPool *pool) +void +gst_vaapi_video_pool_finalize(GstVaapiVideoPool *pool) { - GstVaapiVideoPoolPrivate * const priv = pool->priv; - - gst_vaapi_video_pool_clear(pool); - - if (priv->caps) { - gst_caps_unref(priv->caps); - priv->caps = NULL; - } - - g_clear_object(&priv->display); + g_list_free_full(pool->used_objects, gst_vaapi_object_unref); + g_queue_free_full(&pool->free_objects, gst_vaapi_object_unref); + g_clear_object(&pool->display); } -static void -gst_vaapi_video_pool_finalize(GObject *object) +/** + * gst_vaapi_video_pool_ref: + * @pool: a #GstVaapiVideoPool + * + * Atomically increases the reference count of the given @pool by one. + * + * Returns: The same @pool argument + */ +GstVaapiVideoPool * +gst_vaapi_video_pool_ref(GstVaapiVideoPool *pool) { - gst_vaapi_video_pool_destroy(GST_VAAPI_VIDEO_POOL(object)); - - G_OBJECT_CLASS(gst_vaapi_video_pool_parent_class)->finalize(object); + return gst_vaapi_video_pool_ref_internal(pool); } -static void -gst_vaapi_video_pool_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) +/** + * gst_vaapi_video_pool_unref: + * @pool: a #GstVaapiVideoPool + * + * Atomically decreases the reference count of the @pool by one. If + * the reference count reaches zero, the pool will be free'd. + */ +void +gst_vaapi_video_pool_unref(GstVaapiVideoPool *pool) { - GstVaapiVideoPool * const pool = GST_VAAPI_VIDEO_POOL(object); - - switch (prop_id) { - case PROP_DISPLAY: - pool->priv->display = g_object_ref(g_value_get_object(value)); - break; - case PROP_CAPS: - gst_vaapi_video_pool_set_caps(pool, g_value_get_pointer(value)); - break; - case PROP_CAPACITY: - gst_vaapi_video_pool_set_capacity(pool, g_value_get_uint(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + gst_vaapi_video_pool_unref_internal(pool); } -static void -gst_vaapi_video_pool_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) +/** + * gst_vaapi_video_pool_replace: + * @old_pool_ptr: a pointer to a #GstVaapiVideoPool + * @new_pool: a #GstVaapiVideoPool + * + * Atomically replaces the pool pool held in @old_pool_ptr with + * @new_pool. This means that @old_pool_ptr shall reference a valid + * pool. However, @new_pool can be NULL. + */ +void +gst_vaapi_video_pool_replace(GstVaapiVideoPool **old_pool_ptr, + GstVaapiVideoPool *new_pool) { - GstVaapiVideoPool * const pool = GST_VAAPI_VIDEO_POOL(object); - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_object(value, gst_vaapi_video_pool_get_display(pool)); - break; - case PROP_CAPS: - g_value_set_pointer(value, gst_vaapi_video_pool_get_caps(pool)); - break; - case PROP_CAPACITY: - g_value_set_uint(value, gst_vaapi_video_pool_get_capacity(pool)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_video_pool_class_init(GstVaapiVideoPoolClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiVideoPoolPrivate)); - - object_class->finalize = gst_vaapi_video_pool_finalize; - object_class->set_property = gst_vaapi_video_pool_set_property; - object_class->get_property = gst_vaapi_video_pool_get_property; - - /** - * GstVaapiVideoPool:display: - * - * The #GstVaapiDisplay this pool is bound to. - */ - g_object_class_install_property - (object_class, - PROP_DISPLAY, - g_param_spec_object("display", - "Display", - "The GstVaapiDisplay this pool is bound to", - GST_VAAPI_TYPE_DISPLAY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiVidePool:caps: - * - * The video object capabilities represented as a #GstCaps. This - * shall hold at least the "width" and "height" properties. - */ - g_object_class_install_property - (object_class, - PROP_CAPS, - g_param_spec_pointer("caps", - "caps", - "The video object capabilities", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiVidePool:capacity: - * - * The maximum number of objects in the pool. Or zero, the pool - * will allocate as many objects as possible. - */ - g_object_class_install_property - (object_class, - PROP_CAPACITY, - g_param_spec_uint("capacity", - "capacity", - "The maximum number of objects in the pool", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE)); -} - -static void -gst_vaapi_video_pool_init(GstVaapiVideoPool *pool) -{ - GstVaapiVideoPoolPrivate *priv = GST_VAAPI_VIDEO_POOL_GET_PRIVATE(pool); - - pool->priv = priv; - priv->display = NULL; - priv->used_objects = NULL; - priv->caps = NULL; - priv->used_count = 0; - priv->capacity = 0; - - g_queue_init(&priv->free_objects); + gst_vaapi_video_pool_replace_internal(old_pool_ptr, new_pool); } /** @@ -244,42 +129,7 @@ gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool) { g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); - return pool->priv->display; -} - -/** - * gst_vaapi_video_pool_get_caps: - * @pool: a #GstVaapiVideoPool - * - * Retrieves the #GstCaps the @pool was created with. The @pool owns - * the returned object and it shall not be unref'ed. - * - * Return value: the #GstCaps the @pool was created with - */ -GstCaps * -gst_vaapi_video_pool_get_caps(GstVaapiVideoPool *pool) -{ - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); - - return pool->priv->caps; -} - -/* - * gst_vaapi_video_pool_set_caps: - * @pool: a #GstVaapiVideoPool - * @caps: a #GstCaps - * - * Binds new @caps to the @pool and notify the sub-classes. - */ -void -gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) -{ - GstVaapiVideoPoolClass * const klass = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool); - - pool->priv->caps = gst_caps_ref(caps); - - if (klass->set_caps) - klass->set_caps(pool, caps); + return pool->display; } /** @@ -296,24 +146,22 @@ gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps) gpointer gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) { - GstVaapiVideoPoolPrivate *priv; gpointer object; g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); - priv = pool->priv; - if (priv->capacity && priv->used_count >= priv->capacity) + if (pool->capacity && pool->used_count >= pool->capacity) return NULL; - object = g_queue_pop_head(&priv->free_objects); + object = g_queue_pop_head(&pool->free_objects); if (!object) { object = gst_vaapi_video_pool_alloc_object(pool); if (!object) return NULL; } - ++priv->used_count; - priv->used_objects = g_list_prepend(priv->used_objects, object); + ++pool->used_count; + pool->used_objects = g_list_prepend(pool->used_objects, object); return gst_vaapi_object_ref(object); } @@ -330,21 +178,19 @@ gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) void gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) { - GstVaapiVideoPoolPrivate *priv; GList *elem; g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool)); g_return_if_fail(GST_VAAPI_IS_OBJECT(object)); - priv = pool->priv; - elem = g_list_find(priv->used_objects, object); + elem = g_list_find(pool->used_objects, object); if (!elem) return; gst_vaapi_object_unref(object); - --priv->used_count; - priv->used_objects = g_list_delete_link(priv->used_objects, elem); - g_queue_push_tail(&priv->free_objects, object); + --pool->used_count; + pool->used_objects = g_list_delete_link(pool->used_objects, elem); + g_queue_push_tail(&pool->free_objects, object); } /** @@ -364,7 +210,7 @@ gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object) g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE); g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), FALSE); - g_queue_push_tail(&pool->priv->free_objects, gst_vaapi_object_ref(object)); + g_queue_push_tail(&pool->free_objects, gst_vaapi_object_ref(object)); return TRUE; } @@ -407,7 +253,7 @@ gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool) { g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0); - return g_queue_get_length(&pool->priv->free_objects); + return g_queue_get_length(&pool->free_objects); } /** @@ -429,18 +275,18 @@ gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n) g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0); - num_allocated = gst_vaapi_video_pool_get_size(pool) + pool->priv->used_count; + num_allocated = gst_vaapi_video_pool_get_size(pool) + pool->used_count; if (n < num_allocated) return TRUE; - if ((n -= num_allocated) > pool->priv->capacity) - n = pool->priv->capacity; + if ((n -= num_allocated) > pool->capacity) + n = pool->capacity; for (i = num_allocated; i < n; i++) { gpointer const object = gst_vaapi_video_pool_alloc_object(pool); if (!object) return FALSE; - g_queue_push_tail(&pool->priv->free_objects, object); + g_queue_push_tail(&pool->free_objects, object); } return TRUE; } @@ -459,7 +305,7 @@ gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool) { g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0); - return pool->priv->capacity; + return pool->capacity; } /** @@ -474,5 +320,5 @@ gst_vaapi_video_pool_set_capacity(GstVaapiVideoPool *pool, guint capacity) { g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool)); - pool->priv->capacity = capacity; + pool->capacity = capacity; } diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 77233e4a81..44dbf20082 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -29,72 +29,27 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_VIDEO_POOL \ - (gst_vaapi_video_pool_get_type()) - -#define GST_VAAPI_VIDEO_POOL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_VIDEO_POOL, \ - GstVaapiVideoPool)) - -#define GST_VAAPI_VIDEO_POOL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_VIDEO_POOL, \ - GstVaapiVideoPoolClass)) +#define GST_VAAPI_VIDEO_POOL(obj) \ + ((GstVaapiVideoPool *)(obj)) #define GST_VAAPI_IS_VIDEO_POOL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_POOL)) - -#define GST_VAAPI_IS_VIDEO_POOL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_POOL)) - -#define GST_VAAPI_VIDEO_POOL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_VIDEO_POOL, \ - GstVaapiVideoPoolClass)) + ((obj) != NULL) typedef struct _GstVaapiVideoPool GstVaapiVideoPool; -typedef struct _GstVaapiVideoPoolPrivate GstVaapiVideoPoolPrivate; -typedef struct _GstVaapiVideoPoolClass GstVaapiVideoPoolClass; -/** - * GstVaapiVideoPool: - * - * A pool of lazily allocated video objects. e.g. surfaces, images. - */ -struct _GstVaapiVideoPool { - /*< private >*/ - GObject parent_instance; +GstVaapiVideoPool * +gst_vaapi_video_pool_ref(GstVaapiVideoPool *pool); - GstVaapiVideoPoolPrivate *priv; -}; +void +gst_vaapi_video_pool_unref(GstVaapiVideoPool *pool); -/** - * GstVaapiVideoPoolClass: - * @set_caps: virtual function for notifying the subclass of the - * negotiated caps - * @alloc_object: virtual function for allocating a video pool object - * - * A pool base class used to hold video objects. e.g. surfaces, images. - */ -struct _GstVaapiVideoPoolClass { - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - void (*set_caps) (GstVaapiVideoPool *pool, GstCaps *caps); - gpointer (*alloc_object)(GstVaapiVideoPool *pool, GstVaapiDisplay *display); -}; - -GType -gst_vaapi_video_pool_get_type(void) G_GNUC_CONST; +void +gst_vaapi_video_pool_replace(GstVaapiVideoPool **old_pool_ptr, + GstVaapiVideoPool *new_pool); GstVaapiDisplay * gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool); -GstCaps * -gst_vaapi_video_pool_get_caps(GstVaapiVideoPool *pool); - gpointer gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool); diff --git a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h new file mode 100644 index 0000000000..df66480965 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h @@ -0,0 +1,102 @@ +/* + * gstvaapivideopool_priv.h - Video object pool abstraction (private defs) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012 Intel Corporation + * + * 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_VIDEO_POOL_PRIV_H +#define GST_VAAPI_VIDEO_POOL_PRIV_H + +#include "gstvaapiminiobject.h" + +G_BEGIN_DECLS + +#define GST_VAAPI_VIDEO_POOL_CLASS(klass) \ + ((GstVaapiVideoPoolClass *)(klass)) + +#define GST_VAAPI_IS_VIDEO_POOL_CLASS(klass) \ + ((klass) != NULL) + +typedef struct _GstVaapiVideoPoolClass GstVaapiVideoPoolClass; + +/** + * GstVaapiVideoPool: + * + * A pool of lazily allocated video objects. e.g. surfaces, images. + */ +struct _GstVaapiVideoPool { + /*< private >*/ + GstVaapiMiniObject parent_instance; + + GstVaapiDisplay *display; + GQueue free_objects; + GList *used_objects; + guint used_count; + guint capacity; +}; + +/** + * GstVaapiVideoPoolClass: + * @alloc_object: virtual function for allocating a video pool object + * + * A pool base class used to hold video objects. e.g. surfaces, images. + */ +struct _GstVaapiVideoPoolClass { + /*< private >*/ + GstVaapiMiniObjectClass parent_class; + + /*< public >*/ + gpointer (*alloc_object)(GstVaapiVideoPool *pool); +}; + +G_GNUC_INTERNAL +void +gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display); + +G_GNUC_INTERNAL +void +gst_vaapi_video_pool_finalize(GstVaapiVideoPool *pool); + +/* Internal aliases */ + +#define gst_vaapi_video_pool_ref_internal(pool) \ + ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pool))) + +#define gst_vaapi_video_pool_unref_internal(pool) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pool)) + +#define gst_vaapi_video_pool_replace_internal(old_pool_ptr, new_pool) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pool_ptr), \ + GST_VAAPI_MINI_OBJECT(new_pool)) + +#undef gst_vaapi_video_pool_ref +#define gst_vaapi_video_pool_ref(pool) \ + gst_vaapi_video_pool_ref_internal((pool)) + +#undef gst_vaapi_video_pool_unref +#define gst_vaapi_video_pool_unref(pool) \ + gst_vaapi_video_pool_unref_internal((pool)) + +#undef gst_vaapi_video_pool_replace +#define gst_vaapi_video_pool_replace(old_pool_ptr, new_pool) \ + gst_vaapi_video_pool_replace_internal((old_pool_ptr), (new_pool)) + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_POOL_PRIV_H */ From 3cc7b26961153659d617e491917c7f0775edab54 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 6 May 2013 14:07:17 +0200 Subject: [PATCH 1179/3781] libs: use GstVaapiMiniObject for video decoders. Port GstVaapiDecoder and GstVaapiDecoder{MPEG2,MPEG4,JPEG,H264,VC1} to GstVaapiMiniObject. Add gst_vaapi_decoder_set_codec_state_changed_func() helper function to let the user add a callback to a function triggered whenever the codec state (e.g. caps) changes. --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 4 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 384 ++++++++++--------- gst-libs/gst/vaapi/gstvaapidecoder.h | 76 +--- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 210 +++++----- gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 51 --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 160 ++++---- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h | 51 --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 177 ++++----- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h | 51 --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 188 ++++----- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h | 51 --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 6 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 72 +++- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 200 +++++----- gst-libs/gst/vaapi/gstvaapidecoder_vc1.h | 51 --- 15 files changed, 709 insertions(+), 1023 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 1cd658392c..c910cf8036 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -96,8 +96,8 @@ gst_vaapi_codec_object_new(const GstVaapiCodecObjectClass *object_class, } #define GET_DECODER(obj) GST_VAAPI_DECODER_CAST((obj)->parent_instance.codec) -#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->priv->va_display -#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->priv->va_context +#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->va_display +#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->va_context /* ------------------------------------------------------------------------- */ /* --- Inverse Quantization Matrices --- */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index f5b03b7094..15b09ed015 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -32,24 +32,10 @@ #include "gstvaapiparser_frame.h" #include "gstvaapisurfaceproxy_priv.h" #include "gstvaapiutils.h" -#include "gstvaapi_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDecoder, gst_vaapi_decoder, G_TYPE_OBJECT) - -enum { - PROP_0, - - PROP_DISPLAY, - PROP_CAPS, - - N_PROPERTIES -}; - -static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; - static void drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame); @@ -77,6 +63,8 @@ parser_state_finalize(GstVaapiParserState *ps) static gboolean parser_state_init(GstVaapiParserState *ps) { + memset(ps, 0, sizeof(*ps)); + ps->input_adapter = gst_adapter_new(); if (!ps->input_adapter) return FALSE; @@ -103,8 +91,6 @@ reset: static gboolean push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) { - GstVaapiDecoderPrivate * const priv = decoder->priv; - if (!buffer) { buffer = gst_buffer_new(); if (!buffer) @@ -115,17 +101,16 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) GST_DEBUG("queue encoded data buffer %p (%d bytes)", buffer, gst_buffer_get_size(buffer)); - g_async_queue_push(priv->buffers, buffer); + g_async_queue_push(decoder->buffers, buffer); return TRUE; } static GstBuffer * pop_buffer(GstVaapiDecoder *decoder) { - GstVaapiDecoderPrivate * const priv = decoder->priv; GstBuffer *buffer; - buffer = g_async_queue_try_pop(priv->buffers); + buffer = g_async_queue_try_pop(decoder->buffers); if (!buffer) return NULL; @@ -140,8 +125,7 @@ do_parse(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame, GstAdapter *adapter, gboolean at_eos, guint *got_unit_size_ptr, gboolean *got_frame_ptr) { - GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVaapiParserState * const ps = &priv->parser_state; + GstVaapiParserState * const ps = &decoder->parser_state; GstVaapiParserFrame *frame; GstVaapiDecoderUnit *unit; GstVaapiDecoderStatus status; @@ -151,7 +135,7 @@ do_parse(GstVaapiDecoder *decoder, frame = gst_video_codec_frame_get_user_data(base_frame); if (!frame) { - GstVideoCodecState * const codec_state = priv->codec_state; + GstVideoCodecState * const codec_state = decoder->codec_state; frame = gst_vaapi_parser_frame_new(codec_state->info.width, codec_state->info.height); if (!frame) @@ -261,7 +245,7 @@ do_decode_1(GstVaapiDecoder *decoder, GstVaapiParserFrame *frame) static inline GstVaapiDecoderStatus do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) { - GstVaapiParserState * const ps = &decoder->priv->parser_state; + GstVaapiParserState * const ps = &decoder->parser_state; GstVaapiParserFrame * const frame = base_frame->user_data; GstVaapiDecoderStatus status; @@ -293,8 +277,7 @@ do_flush(GstVaapiDecoder *decoder) static GstVaapiDecoderStatus decode_step(GstVaapiDecoder *decoder) { - GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVaapiParserState * const ps = &priv->parser_state; + GstVaapiParserState * const ps = &decoder->parser_state; GstVaapiDecoderStatus status; GstBuffer *buffer; gboolean got_frame; @@ -370,8 +353,6 @@ decode_step(GstVaapiDecoder *decoder) static void drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) { - GstVaapiDecoderPrivate * const priv = decoder->priv; - GST_DEBUG("drop frame %d", frame->system_frame_number); /* no surface proxy */ @@ -381,32 +362,30 @@ drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) GST_VIDEO_CODEC_FRAME_FLAG_SET(frame, GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); - g_async_queue_push(priv->frames, gst_video_codec_frame_ref(frame)); + g_async_queue_push(decoder->frames, gst_video_codec_frame_ref(frame)); } static inline void push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) { - GstVaapiDecoderPrivate * const priv = decoder->priv; GstVaapiSurfaceProxy * const proxy = frame->user_data; GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy))); - g_async_queue_push(priv->frames, gst_video_codec_frame_ref(frame)); + g_async_queue_push(decoder->frames, gst_video_codec_frame_ref(frame)); } static inline GstVideoCodecFrame * pop_frame(GstVaapiDecoder *decoder, guint64 timeout) { - GstVaapiDecoderPrivate * const priv = decoder->priv; GstVideoCodecFrame *frame; GstVaapiSurfaceProxy *proxy; if (G_LIKELY(timeout > 0)) - frame = g_async_queue_timeout_pop(priv->frames, timeout); + frame = g_async_queue_timeout_pop(decoder->frames, timeout); else - frame = g_async_queue_try_pop(priv->frames); + frame = g_async_queue_try_pop(decoder->frames); if (!frame) return NULL; @@ -417,25 +396,24 @@ pop_frame(GstVaapiDecoder *decoder, guint64 timeout) return frame; } -static void +static gboolean set_caps(GstVaapiDecoder *decoder, const GstCaps *caps) { - GstVaapiDecoderPrivate * const priv = decoder->priv; - GstVideoCodecState * const codec_state = priv->codec_state; + GstVideoCodecState * const codec_state = decoder->codec_state; GstStructure * const structure = gst_caps_get_structure(caps, 0); GstVaapiProfile profile; const GValue *v_codec_data; profile = gst_vaapi_profile_from_caps(caps); if (!profile) - return; + return FALSE; - priv->codec = gst_vaapi_profile_get_codec(profile); - if (!priv->codec) - return; + decoder->codec = gst_vaapi_profile_get_codec(profile); + if (!decoder->codec) + return FALSE; if (!gst_video_info_from_caps(&codec_state->info, caps)) - return; + return FALSE; codec_state->caps = gst_caps_copy(caps); @@ -443,6 +421,7 @@ set_caps(GstVaapiDecoder *decoder, const GstCaps *caps) if (v_codec_data) gst_buffer_replace(&codec_state->codec_data, gst_value_get_buffer(v_codec_data)); + return TRUE; } static inline GstCaps * @@ -452,142 +431,181 @@ get_caps(GstVaapiDecoder *decoder) } static void -gst_vaapi_decoder_finalize(GObject *object) +notify_codec_state_changed(GstVaapiDecoder *decoder) { - GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object); - GstVaapiDecoderPrivate * const priv = decoder->priv; + if (decoder->codec_state_changed_func) + decoder->codec_state_changed_func(decoder, decoder->codec_state, + decoder->codec_state_changed_data); +} - gst_video_codec_state_unref(priv->codec_state); - priv->codec_state = NULL; +void +gst_vaapi_decoder_finalize(GstVaapiDecoder *decoder) +{ + const GstVaapiDecoderClass * const klass = + GST_VAAPI_DECODER_GET_CLASS(decoder); - parser_state_finalize(&priv->parser_state); + if (klass->destroy) + klass->destroy(decoder); + + gst_video_codec_state_unref(decoder->codec_state); + decoder->codec_state = NULL; + + parser_state_finalize(&decoder->parser_state); - if (priv->buffers) { - g_async_queue_unref(priv->buffers); - priv->buffers = NULL; + if (decoder->buffers) { + g_async_queue_unref(decoder->buffers); + decoder->buffers = NULL; } - if (priv->frames) { - g_async_queue_unref(priv->frames); - priv->frames = NULL; + if (decoder->frames) { + g_async_queue_unref(decoder->frames); + decoder->frames = NULL; } - gst_vaapi_object_replace(&priv->context, NULL); - priv->va_context = VA_INVALID_ID; + gst_vaapi_object_replace(&decoder->context, NULL); + decoder->va_context = VA_INVALID_ID; - g_clear_object(&priv->display); - priv->va_display = NULL; - - G_OBJECT_CLASS(gst_vaapi_decoder_parent_class)->finalize(object); + g_clear_object(&decoder->display); + decoder->va_display = NULL; } -static void -gst_vaapi_decoder_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) +static gboolean +gst_vaapi_decoder_init(GstVaapiDecoder *decoder, GstVaapiDisplay *display, + GstCaps *caps) { - GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object); - GstVaapiDecoderPrivate * const priv = decoder->priv; - - switch (prop_id) { - case PROP_DISPLAY: - priv->display = g_object_ref(g_value_get_object(value)); - if (priv->display) - priv->va_display = gst_vaapi_display_get_display(priv->display); - else - priv->va_display = NULL; - break; - case PROP_CAPS: - set_caps(decoder, g_value_get_pointer(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_decoder_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDecoder * const decoder = GST_VAAPI_DECODER_CAST(object); - GstVaapiDecoderPrivate * const priv = decoder->priv; - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_object(value, priv->display); - break; - case PROP_CAPS: - gst_value_set_caps(value, get_caps(decoder)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - - g_type_class_add_private(klass, sizeof(GstVaapiDecoderPrivate)); - - object_class->finalize = gst_vaapi_decoder_finalize; - object_class->set_property = gst_vaapi_decoder_set_property; - object_class->get_property = gst_vaapi_decoder_get_property; - - /** - * GstVaapiDecoder:display: - * - * The #GstVaapiDisplay this decoder is bound to. - */ - g_properties[PROP_DISPLAY] = - g_param_spec_object("display", - "Display", - "The GstVaapiDisplay this decoder is bound to", - GST_VAAPI_TYPE_DISPLAY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - - g_properties[PROP_CAPS] = - g_param_spec_pointer("caps", - "Decoder caps", - "The decoder caps", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - - g_object_class_install_properties(object_class, N_PROPERTIES, g_properties); -} - -static void -gst_vaapi_decoder_init(GstVaapiDecoder *decoder) -{ - GstVaapiDecoderPrivate *priv = GST_VAAPI_DECODER_GET_PRIVATE(decoder); + const GstVaapiDecoderClass * const klass = + GST_VAAPI_DECODER_GET_CLASS(decoder); GstVideoCodecState *codec_state; + guint sub_size; - parser_state_init(&priv->parser_state); + parser_state_init(&decoder->parser_state); codec_state = g_slice_new0(GstVideoCodecState); codec_state->ref_count = 1; gst_video_info_init(&codec_state->info); - decoder->priv = priv; - priv->display = NULL; - priv->va_display = NULL; - priv->context = NULL; - priv->va_context = VA_INVALID_ID; - priv->codec = 0; - priv->codec_state = codec_state; + decoder->user_data = NULL; + decoder->display = g_object_ref(display); + decoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY(display); + decoder->context = NULL; + decoder->va_context = VA_INVALID_ID; + decoder->codec = 0; + decoder->codec_state = codec_state; + decoder->codec_state_changed_func = NULL; + decoder->codec_state_changed_data = NULL; - priv->buffers = g_async_queue_new_full((GDestroyNotify)gst_buffer_unref); - priv->frames = g_async_queue_new_full((GDestroyNotify) + decoder->buffers = g_async_queue_new_full((GDestroyNotify)gst_buffer_unref); + decoder->frames = g_async_queue_new_full((GDestroyNotify) gst_video_codec_frame_unref); + + if (!set_caps(decoder, caps)) + return FALSE; + + sub_size = GST_VAAPI_MINI_OBJECT_CLASS(klass)->size - sizeof(*decoder); + if (sub_size > 0) + memset(((guchar *)decoder) + sizeof(*decoder), 0, sub_size); + + if (klass->create && !klass->create(decoder)) + return FALSE; + return TRUE; +} + +GstVaapiDecoder * +gst_vaapi_decoder_new(const GstVaapiDecoderClass *klass, + GstVaapiDisplay *display, GstCaps *caps) +{ + GstVaapiDecoder *decoder; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + decoder = (GstVaapiDecoder *) + gst_vaapi_mini_object_new(GST_VAAPI_MINI_OBJECT_CLASS(klass)); + if (!decoder) + return NULL; + + if (!gst_vaapi_decoder_init(decoder, display, caps)) + goto error; + return decoder; + +error: + gst_vaapi_decoder_unref(decoder); + return NULL; +} + +/** + * gst_vaapi_decoder_ref: + * @decoder: a #GstVaapiDecoder + * + * Atomically increases the reference count of the given @decoder by one. + * + * Returns: The same @decoder argument + */ +GstVaapiDecoder * +gst_vaapi_decoder_ref(GstVaapiDecoder *decoder) +{ + return gst_vaapi_object_ref(decoder); +} + +/** + * gst_vaapi_decoder_unref: + * @decoder: a #GstVaapiDecoder + * + * Atomically decreases the reference count of the @decoder by one. If + * the reference count reaches zero, the decoder will be free'd. + */ +void +gst_vaapi_decoder_unref(GstVaapiDecoder *decoder) +{ + gst_vaapi_object_unref(decoder); +} + +/** + * gst_vaapi_decoder_replace: + * @old_decoder_ptr: a pointer to a #GstVaapiDecoder + * @new_decoder: a #GstVaapiDecoder + * + * Atomically replaces the decoder decoder held in @old_decoder_ptr + * with @new_decoder. This means that @old_decoder_ptr shall reference + * a valid decoder. However, @new_decoder can be NULL. + */ +void +gst_vaapi_decoder_replace(GstVaapiDecoder **old_decoder_ptr, + GstVaapiDecoder *new_decoder) +{ + gst_vaapi_object_replace(old_decoder_ptr, new_decoder); +} + +/** + * gst_vaapi_decoder_get_user_data: + * @decoder: a #GstVaapiDecoder + * + * Retrieves the user-defined data associated with the @decoder, if any. + * + * Return value: the user-defined data associated with the @decoder + */ +gpointer +gst_vaapi_decoder_get_user_data(GstVaapiDecoder *decoder) +{ + g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + + return decoder->user_data; +} + +/** + * gst_vaapi_decoder_set_user_data: + * @decoder: a #GstVaapiDecoder + * @user_data: the pointer to user-defined data + * + * Associates user-defined @user_data to the @decoder. Retrieve the + * attached value with gst_vaapi_decoder_get_user_data() function. + */ +void +gst_vaapi_decoder_set_user_data(GstVaapiDecoder *decoder, gpointer user_data) +{ + g_return_if_fail(GST_VAAPI_IS_DECODER(decoder)); + + decoder->user_data = user_data; } /** @@ -603,7 +621,7 @@ gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder) { g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), (GstVaapiCodec)0); - return decoder->priv->codec; + return decoder->codec; } /** @@ -624,6 +642,25 @@ gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder) return GST_VAAPI_DECODER_CODEC_STATE(decoder); } +/** + * gst_vaapi_decoder_set_codec_state_changed_func: + * @decoder: a #GstVaapiDecoder + * @func: the function to call when codec state changed + * @user_data: a pointer to user-defined data + * + * Sets @func as the function to call whenever the @decoder codec + * state changes. + */ +void +gst_vaapi_decoder_set_codec_state_changed_func(GstVaapiDecoder *decoder, + GstVaapiDecoderStateChangedFunc func, gpointer user_data) +{ + g_return_if_fail(GST_VAAPI_IS_DECODER(decoder)); + + decoder->codec_state_changed_func = func; + decoder->codec_state_changed_data = user_data; +} + /** * gst_vaapi_decoder_get_caps: * @decoder: a #GstVaapiDecoder @@ -800,7 +837,7 @@ gst_vaapi_decoder_set_picture_size( guint height ) { - GstVideoCodecState * const codec_state = decoder->priv->codec_state; + GstVideoCodecState * const codec_state = decoder->codec_state; gboolean size_changed = FALSE; if (codec_state->info.width != width) { @@ -820,7 +857,7 @@ gst_vaapi_decoder_set_picture_size( } if (size_changed) - g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); + notify_codec_state_changed(decoder); } void @@ -830,7 +867,7 @@ gst_vaapi_decoder_set_framerate( guint fps_d ) { - GstVideoCodecState * const codec_state = decoder->priv->codec_state; + GstVideoCodecState * const codec_state = decoder->codec_state; if (!fps_n || !fps_d) return; @@ -841,7 +878,7 @@ gst_vaapi_decoder_set_framerate( codec_state->info.fps_d = fps_d; gst_caps_set_simple(codec_state->caps, "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); - g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); + notify_codec_state_changed(decoder); } } @@ -852,7 +889,7 @@ gst_vaapi_decoder_set_pixel_aspect_ratio( guint par_d ) { - GstVideoCodecState * const codec_state = decoder->priv->codec_state; + GstVideoCodecState * const codec_state = decoder->codec_state; if (!par_n || !par_d) return; @@ -863,7 +900,7 @@ gst_vaapi_decoder_set_pixel_aspect_ratio( codec_state->info.par_d = par_d; gst_caps_set_simple(codec_state->caps, "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL); - g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); + notify_codec_state_changed(decoder); } } @@ -882,7 +919,7 @@ void gst_vaapi_decoder_set_interlace_mode(GstVaapiDecoder *decoder, GstVideoInterlaceMode mode) { - GstVideoCodecState * const codec_state = decoder->priv->codec_state; + GstVideoCodecState * const codec_state = decoder->codec_state; if (codec_state->info.interlace_mode != mode) { GST_DEBUG("interlace mode changed to %s", @@ -890,7 +927,7 @@ gst_vaapi_decoder_set_interlace_mode(GstVaapiDecoder *decoder, codec_state->info.interlace_mode = mode; gst_caps_set_simple(codec_state->caps, "interlaced", G_TYPE_BOOLEAN, mode != GST_VIDEO_INTERLACE_MODE_PROGRESSIVE, NULL); - g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]); + notify_codec_state_changed(decoder); } } @@ -909,20 +946,18 @@ gst_vaapi_decoder_ensure_context( GstVaapiContextInfo *cip ) { - GstVaapiDecoderPrivate * const priv = decoder->priv; - gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height); - if (priv->context) { - if (!gst_vaapi_context_reset_full(priv->context, cip)) + if (decoder->context) { + if (!gst_vaapi_context_reset_full(decoder->context, cip)) return FALSE; } else { - priv->context = gst_vaapi_context_new_full(priv->display, cip); - if (!priv->context) + decoder->context = gst_vaapi_context_new_full(decoder->display, cip); + if (!decoder->context) return FALSE; } - priv->va_context = gst_vaapi_context_get_id(priv->context); + decoder->va_context = gst_vaapi_context_get_id(decoder->context); return TRUE; } @@ -936,9 +971,8 @@ gst_vaapi_decoder_push_frame(GstVaapiDecoder *decoder, GstVaapiDecoderStatus gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder) { - GstVaapiDecoderPrivate * const priv = decoder->priv; - - if (priv->context && gst_vaapi_context_get_surface_count(priv->context) < 1) + if (decoder->context && + gst_vaapi_context_get_surface_count(decoder->context) < 1) return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 8dea2e4a06..e2854f3920 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -31,34 +31,15 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DECODER \ - (gst_vaapi_decoder_get_type()) - -#define GST_VAAPI_DECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DECODER, \ - GstVaapiDecoder)) - -#define GST_VAAPI_DECODER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DECODER, \ - GstVaapiDecoderClass)) +#define GST_VAAPI_DECODER(obj) \ + ((GstVaapiDecoder *)(obj)) #define GST_VAAPI_IS_DECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER)) - -#define GST_VAAPI_IS_DECODER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER)) - -#define GST_VAAPI_DECODER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DECODER, \ - GstVaapiDecoderClass)) + ((obj) != NULL) typedef struct _GstVaapiDecoder GstVaapiDecoder; -typedef struct _GstVaapiDecoderPrivate GstVaapiDecoderPrivate; -typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; - struct _GstVaapiDecoderUnit; +typedef void (*GstVaapiDecoderStateChangedFunc)(GstVaapiDecoder *decoder, + const GstVideoCodecState *codec_state, gpointer user_data); /** * GstVaapiDecoderStatus: @@ -94,42 +75,21 @@ typedef enum { GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN = -1 } GstVaapiDecoderStatus; -/** - * GstVaapiDecoder: - * - * A VA decoder base instance. - */ -struct _GstVaapiDecoder { - /*< private >*/ - GObject parent_instance; +GstVaapiDecoder * +gst_vaapi_decoder_ref(GstVaapiDecoder *decoder); - GstVaapiDecoderPrivate *priv; -}; +void +gst_vaapi_decoder_unref(GstVaapiDecoder *decoder); -/** - * GstVaapiDecoderClass: - * - * A VA decoder base class. - */ -struct _GstVaapiDecoderClass { - /*< private >*/ - GObjectClass parent_class; +void +gst_vaapi_decoder_replace(GstVaapiDecoder **old_decoder_ptr, + GstVaapiDecoder *new_decoder); - 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 (*decode_codec_data)(GstVaapiDecoder *decoder, - const guchar *buf, guint buf_size); -}; +gpointer +gst_vaapi_decoder_get_user_data(GstVaapiDecoder *decoder); -GType -gst_vaapi_decoder_get_type(void) G_GNUC_CONST; +void +gst_vaapi_decoder_set_user_data(GstVaapiDecoder *decoder, gpointer user_data); GstVaapiCodec gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder); @@ -137,6 +97,10 @@ 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); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index aff30c4846..8892d52eaf 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -40,6 +40,8 @@ /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */ #define USE_STRICT_DPB_ORDERING 0 +typedef struct _GstVaapiDecoderH264Private GstVaapiDecoderH264Private; +typedef struct _GstVaapiDecoderH264Class GstVaapiDecoderH264Class; typedef struct _GstVaapiFrameStore GstVaapiFrameStore; typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; typedef struct _GstVaapiParserInfoH264 GstVaapiParserInfoH264; @@ -342,18 +344,9 @@ gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs) /* --- H.264 Decoder --- */ /* ------------------------------------------------------------------------- */ -G_DEFINE_TYPE(GstVaapiDecoderH264, - gst_vaapi_decoder_h264, - GST_VAAPI_TYPE_DECODER) - #define GST_VAAPI_DECODER_H264_CAST(decoder) \ ((GstVaapiDecoderH264 *)(decoder)) -#define GST_VAAPI_DECODER_H264_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DECODER_H264, \ - GstVaapiDecoderH264Private)) - struct _GstVaapiDecoderH264Private { GstH264NalParser *parser; GstVaapiPictureH264 *current_picture; @@ -386,7 +379,6 @@ struct _GstVaapiDecoderH264Private { gint32 prev_frame_num; // prevFrameNum gboolean prev_pic_has_mmco5; // prevMmco5Pic gboolean prev_pic_structure; // previous picture structure - guint is_constructed : 1; guint is_opened : 1; guint is_avcC : 1; guint got_sps : 1; @@ -395,6 +387,27 @@ struct _GstVaapiDecoderH264Private { guint progressive_sequence : 1; }; +/** + * GstVaapiDecoderH264: + * + * A decoder based on H264. + */ +struct _GstVaapiDecoderH264 { + /*< private >*/ + GstVaapiDecoder parent_instance; + GstVaapiDecoderH264Private priv; +}; + +/** + * GstVaapiDecoderH264Class: + * + * A decoder class based on H264. + */ +struct _GstVaapiDecoderH264Class { + /*< private >*/ + GstVaapiDecoderClass parent_class; +}; + static gboolean exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture); @@ -501,7 +514,7 @@ array_remove_index(void *array, guint *array_length_ptr, guint index) static void dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; guint i, num_frames = --priv->dpb_count; if (USE_STRICT_DPB_ORDERING) { @@ -535,7 +548,8 @@ dpb_output( static inline void dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i) { - GstVaapiFrameStore * const fs = decoder->priv->dpb[i]; + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiFrameStore * const fs = priv->dpb[i]; if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs)) dpb_remove_index(decoder, i); @@ -544,7 +558,7 @@ dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i) static gboolean dpb_bump(GstVaapiDecoderH264 *decoder) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPictureH264 *found_picture = NULL; guint i, j, found_index; gboolean success; @@ -572,7 +586,7 @@ dpb_bump(GstVaapiDecoderH264 *decoder) static void dpb_clear(GstVaapiDecoderH264 *decoder) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; guint i; for (i = 0; i < priv->dpb_count; i++) @@ -593,7 +607,7 @@ dpb_flush(GstVaapiDecoderH264 *decoder) static gboolean dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiFrameStore *fs; guint i, j; @@ -668,7 +682,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) static inline void dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; priv->dpb_size = get_max_dec_frame_buffering(sps); GST_DEBUG("DPB size %u", priv->dpb_size); @@ -699,7 +713,7 @@ get_status(GstH264ParserResult result) static void gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; gst_vaapi_picture_replace(&priv->current_picture, NULL); gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL); @@ -715,7 +729,7 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) static gboolean gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; gst_vaapi_decoder_h264_close(decoder); @@ -726,16 +740,26 @@ gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder) } static void -gst_vaapi_decoder_h264_destroy(GstVaapiDecoderH264 *decoder) +gst_vaapi_decoder_h264_destroy(GstVaapiDecoder *base_decoder) { + GstVaapiDecoderH264 * const decoder = + GST_VAAPI_DECODER_H264_CAST(base_decoder); + gst_vaapi_decoder_h264_close(decoder); } static gboolean -gst_vaapi_decoder_h264_create(GstVaapiDecoderH264 *decoder) +gst_vaapi_decoder_h264_create(GstVaapiDecoder *base_decoder) { - if (!GST_VAAPI_DECODER_CODEC(decoder)) - return FALSE; + GstVaapiDecoderH264 * const decoder = + GST_VAAPI_DECODER_H264_CAST(base_decoder); + GstVaapiDecoderH264Private * const priv = &decoder->priv; + + priv->profile = GST_VAAPI_PROFILE_UNKNOWN; + priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD; + priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + priv->progressive_sequence = TRUE; return TRUE; } @@ -781,7 +805,7 @@ h264_get_chroma_type(GstH264SPS *sps) static GstVaapiProfile get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder); GstVaapiProfile profile, profiles[2]; guint i, n_profiles = 0; @@ -815,7 +839,7 @@ static GstVaapiDecoderStatus ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiContextInfo info; GstVaapiProfile profile; GstVaapiChromaType chroma_type; @@ -963,7 +987,7 @@ ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderH264 *decoder) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPictureH264 * const picture = priv->current_picture; if (!picture) @@ -988,7 +1012,7 @@ error: static GstVaapiDecoderStatus parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstH264SPS * const sps = &pi->data.sps; GstH264ParserResult result; @@ -1010,7 +1034,7 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) static GstVaapiDecoderStatus parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstH264PPS * const pps = &pi->data.pps; GstH264ParserResult result; @@ -1033,7 +1057,7 @@ parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) static GstVaapiDecoderStatus parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstH264SEIMessage sei; GstH264ParserResult result; @@ -1053,7 +1077,7 @@ parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) static GstVaapiDecoderStatus parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstH264ParserResult result; @@ -1096,7 +1120,7 @@ init_picture_poc_0( GstH264SliceHdr *slice_hdr ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); @@ -1157,7 +1181,7 @@ init_picture_poc_1( GstH264SliceHdr *slice_hdr ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); @@ -1240,7 +1264,7 @@ init_picture_poc_2( GstH264SliceHdr *slice_hdr ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); @@ -1284,7 +1308,7 @@ init_picture_poc( GstH264SliceHdr *slice_hdr ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; @@ -1369,7 +1393,7 @@ init_picture_refs_pic_num( GstH264SliceHdr *slice_hdr ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); @@ -1475,7 +1499,7 @@ init_picture_refs_p_slice( GstH264SliceHdr *slice_hdr ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPictureH264 **ref_list; guint i; @@ -1536,7 +1560,7 @@ init_picture_refs_b_slice( GstH264SliceHdr *slice_hdr ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPictureH264 **ref_list; guint i, n; @@ -1690,7 +1714,7 @@ init_picture_refs_b_slice( static gint find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; guint i; for (i = 0; i < priv->short_ref_count; i++) { @@ -1705,7 +1729,7 @@ find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num) static gint find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; guint i; for (i = 0; i < priv->long_ref_count; i++) { @@ -1725,7 +1749,7 @@ exec_picture_refs_modification_1( guint list ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstH264PPS * const pps = slice_hdr->pps; GstH264SPS * const sps = pps->sequence; GstH264RefPicListModification *ref_pic_list_modification; @@ -1869,7 +1893,7 @@ exec_picture_refs_modification( static void init_picture_ref_lists(GstVaapiDecoderH264 *decoder) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; guint i, j, short_ref_count, long_ref_count; short_ref_count = 0; @@ -1920,7 +1944,7 @@ init_picture_refs( GstH264SliceHdr *slice_hdr ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPicture * const base_picture = &picture->base; guint i, num_refs; @@ -1969,7 +1993,7 @@ init_picture( GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPicture * const base_picture = &picture->base; GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; @@ -2041,7 +2065,7 @@ init_picture( static gboolean exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstH264PPS * const pps = priv->current_picture->pps; GstH264SPS * const sps = pps->sequence; GstVaapiPictureH264 *ref_picture; @@ -2107,7 +2131,7 @@ exec_ref_pic_marking_adaptive_mmco_1( GstH264RefPicMarking *ref_pic_marking ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; gint32 i, picNumX; picNumX = get_picNumX(picture, ref_pic_marking); @@ -2128,7 +2152,7 @@ exec_ref_pic_marking_adaptive_mmco_2( GstH264RefPicMarking *ref_pic_marking ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; gint32 i; i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num); @@ -2148,7 +2172,7 @@ exec_ref_pic_marking_adaptive_mmco_3( GstH264RefPicMarking *ref_pic_marking ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPictureH264 *ref_picture; gint32 i, picNumX; @@ -2185,7 +2209,7 @@ exec_ref_pic_marking_adaptive_mmco_4( GstH264RefPicMarking *ref_pic_marking ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; gint32 i, long_term_frame_idx; long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1; @@ -2207,7 +2231,7 @@ exec_ref_pic_marking_adaptive_mmco_5( GstH264RefPicMarking *ref_pic_marking ) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; dpb_flush(decoder); @@ -2286,7 +2310,7 @@ exec_ref_pic_marking_adaptive( static gboolean exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; priv->prev_pic_has_mmco5 = FALSE; priv->prev_pic_structure = picture->structure; @@ -2361,7 +2385,7 @@ static gboolean fill_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPicture * const base_picture = &picture->base; GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstH264PPS * const pps = picture->pps; @@ -2501,7 +2525,7 @@ is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstH264PPS * const pps = slice_hdr->pps; @@ -2629,7 +2653,7 @@ static gboolean fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; VASliceParameterBufferH264 * const slice_param = slice->param; guint i, num_ref_lists = 0; @@ -2694,7 +2718,7 @@ fill_slice(GstVaapiDecoderH264 *decoder, static GstVaapiDecoderStatus decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstVaapiPictureH264 * const picture = priv->current_picture; GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; @@ -2775,7 +2799,7 @@ gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder, { GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(base_decoder); - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; GstVaapiDecoderUnit unit; GstVaapiParserInfoH264 pi; @@ -2837,12 +2861,9 @@ gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder, static GstVaapiDecoderStatus ensure_decoder(GstVaapiDecoderH264 *decoder) { - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; - g_return_val_if_fail(priv->is_constructed, - GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); - if (!priv->is_opened) { priv->is_opened = gst_vaapi_decoder_h264_open(decoder); if (!priv->is_opened) @@ -2862,7 +2883,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, { GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(base_decoder); - GstVaapiDecoderH264Private * const priv = decoder->priv; + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiParserInfoH264 *pi; GstVaapiDecoderStatus status; @@ -3051,41 +3072,18 @@ gst_vaapi_decoder_h264_flush(GstVaapiDecoder *base_decoder) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static void -gst_vaapi_decoder_h264_finalize(GObject *object) -{ - GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(object); - - gst_vaapi_decoder_h264_destroy(decoder); - - G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class)->finalize(object); -} - -static void -gst_vaapi_decoder_h264_constructed(GObject *object) -{ - GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(object); - GstVaapiDecoderH264Private * const priv = decoder->priv; - GObjectClass *parent_class; - - parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); - - priv->is_constructed = gst_vaapi_decoder_h264_create(decoder); -} - static void gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiDecoderH264Private)); - - object_class->finalize = gst_vaapi_decoder_h264_finalize; - object_class->constructed = gst_vaapi_decoder_h264_constructed; + object_class->size = sizeof(GstVaapiDecoderH264); + object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize; + decoder_class->create = gst_vaapi_decoder_h264_create; + decoder_class->destroy = gst_vaapi_decoder_h264_destroy; decoder_class->parse = gst_vaapi_decoder_h264_parse; decoder_class->decode = gst_vaapi_decoder_h264_decode; decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame; @@ -3096,18 +3094,17 @@ gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass) gst_vaapi_decoder_h264_decode_codec_data; } -static void -gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) +static inline const GstVaapiDecoderClass * +gst_vaapi_decoder_h264_class(void) { - GstVaapiDecoderH264Private *priv; + static GstVaapiDecoderH264Class g_class; + static gsize g_class_init = FALSE; - priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder); - decoder->priv = priv; - priv->profile = GST_VAAPI_PROFILE_UNKNOWN; - priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD; - priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - priv->progressive_sequence = TRUE; + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_decoder_h264_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS(&g_class); } /** @@ -3123,20 +3120,5 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder) GstVaapiDecoder * gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps) { - GstVaapiDecoderH264 *decoder; - - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); - - decoder = g_object_new( - GST_VAAPI_TYPE_DECODER_H264, - "display", display, - "caps", caps, - NULL - ); - if (!decoder->priv->is_constructed) { - g_object_unref(decoder); - return NULL; - } - return GST_VAAPI_DECODER_CAST(decoder); + return gst_vaapi_decoder_new(gst_vaapi_decoder_h264_class(), display, caps); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h index 79a08f174a..2b318f02c3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -26,58 +26,7 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DECODER_H264 \ - (gst_vaapi_decoder_h264_get_type()) - -#define GST_VAAPI_DECODER_H264(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DECODER_H264, \ - GstVaapiDecoderH264)) - -#define GST_VAAPI_DECODER_H264_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DECODER_H264, \ - GstVaapiDecoderH264Class)) - -#define GST_VAAPI_IS_DECODER_H264(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_H264)) - -#define GST_VAAPI_IS_DECODER_H264_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_H264)) - -#define GST_VAAPI_DECODER_H264_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DECODER_H264, \ - GstVaapiDecoderH264Class)) - typedef struct _GstVaapiDecoderH264 GstVaapiDecoderH264; -typedef struct _GstVaapiDecoderH264Private GstVaapiDecoderH264Private; -typedef struct _GstVaapiDecoderH264Class GstVaapiDecoderH264Class; - -/** - * GstVaapiDecoderH264: - * - * A decoder based on H264. - */ -struct _GstVaapiDecoderH264 { - /*< private >*/ - GstVaapiDecoder parent_instance; - - GstVaapiDecoderH264Private *priv; -}; - -/** - * GstVaapiDecoderH264Class: - * - * A decoder class based on H264. - */ -struct _GstVaapiDecoderH264Class { - /*< private >*/ - GstVaapiDecoderClass parent_class; -}; - -GType -gst_vaapi_decoder_h264_get_type(void) G_GNUC_CONST; GstVaapiDecoder * gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index bb50e220e8..0dde75cdc3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -37,14 +37,11 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDecoderJpeg, - gst_vaapi_decoder_jpeg, - GST_VAAPI_TYPE_DECODER) +#define GST_VAAPI_DECODER_JPEG_CAST(decoder) \ + ((GstVaapiDecoderJpeg *)(decoder)) -#define GST_VAAPI_DECODER_JPEG_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DECODER_JPEG, \ - GstVaapiDecoderJpegPrivate)) +typedef struct _GstVaapiDecoderJpegPrivate GstVaapiDecoderJpegPrivate; +typedef struct _GstVaapiDecoderJpegClass GstVaapiDecoderJpegClass; struct _GstVaapiDecoderJpegPrivate { GstVaapiProfile profile; @@ -59,7 +56,27 @@ struct _GstVaapiDecoderJpegPrivate { guint mcu_restart; guint is_opened : 1; guint profile_changed : 1; - guint is_constructed : 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; }; typedef struct _GstJpegScanSegment GstJpegScanSegment; @@ -74,7 +91,7 @@ struct _GstJpegScanSegment { static void gst_vaapi_decoder_jpeg_close(GstVaapiDecoderJpeg *decoder) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; gst_vaapi_picture_replace(&priv->current_picture, NULL); @@ -95,23 +112,30 @@ gst_vaapi_decoder_jpeg_open(GstVaapiDecoderJpeg *decoder) } static void -gst_vaapi_decoder_jpeg_destroy(GstVaapiDecoderJpeg *decoder) +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(GstVaapiDecoderJpeg *decoder) +gst_vaapi_decoder_jpeg_create(GstVaapiDecoder *base_decoder) { - if (!GST_VAAPI_DECODER_CODEC(decoder)) - return FALSE; + 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; return TRUE; } static GstVaapiDecoderStatus ensure_context(GstVaapiDecoderJpeg *decoder) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstVaapiProfile profiles[2]; GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; guint i, n_profiles = 0; @@ -157,7 +181,7 @@ ensure_context(GstVaapiDecoderJpeg *decoder) static gboolean decode_current_picture(GstVaapiDecoderJpeg *decoder) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstVaapiPicture * const picture = priv->current_picture; gboolean success = TRUE; @@ -209,7 +233,7 @@ fill_quantization_table( GstVaapiPicture *picture ) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; VAIQMatrixBufferJPEGBaseline *iq_matrix; guint i, j, num_tables; @@ -246,7 +270,7 @@ fill_huffman_table( GstVaapiPicture *picture ) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstJpegHuffmanTables * const huf_tables = &priv->huf_tables; VAHuffmanTableBufferJPEGBaseline *huffman_table; guint i, num_tables; @@ -318,7 +342,7 @@ decode_picture( guint buf_size ) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstJpegFrameHdr * const frame_hdr = &priv->frame_hdr; GstVaapiPicture *picture; GstVaapiDecoderStatus status; @@ -372,7 +396,7 @@ decode_huffman_table( guint buf_size ) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; if (!gst_jpeg_parse_huffman_table(&priv->huf_tables, buf, buf_size, 0)) { GST_DEBUG("failed to parse Huffman table"); @@ -389,7 +413,7 @@ decode_quant_table( guint buf_size ) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; if (!gst_jpeg_parse_quant_table(&priv->quant_tables, buf, buf_size, 0)) { GST_DEBUG("failed to parse quantization table"); @@ -406,7 +430,7 @@ decode_restart_interval( guint buf_size ) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; if (!gst_jpeg_parse_restart_interval(&priv->mcu_restart, buf, buf_size, 0)) { GST_DEBUG("failed to parse restart interval"); @@ -424,7 +448,7 @@ decode_scan( guint scan_data_size ) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstVaapiPicture *picture = priv->current_picture; VASliceParameterBufferJPEGBaseline *slice_param; GstVaapiSlice *gst_slice; @@ -493,7 +517,7 @@ decode_scan( static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderJpeg *decoder, const guchar *buf, guint buf_size) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; GstJpegMarkerSegment seg; GstJpegScanSegment scan_seg; @@ -609,10 +633,7 @@ end: static GstVaapiDecoderStatus ensure_decoder(GstVaapiDecoderJpeg *decoder) { - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; - - g_return_val_if_fail(priv->is_constructed, - GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; if (!priv->is_opened) { priv->is_opened = gst_vaapi_decoder_jpeg_open(decoder); @@ -633,7 +654,8 @@ static GstVaapiDecoderStatus gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder, GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(base_decoder); + GstVaapiDecoderJpeg * const decoder = + GST_VAAPI_DECODER_JPEG_CAST(base_decoder); GstVaapiDecoderStatus status; guint size, buf_size, flags = 0; gint ofs; @@ -676,7 +698,8 @@ static GstVaapiDecoderStatus gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(base_decoder); + GstVaapiDecoderJpeg * const decoder = + GST_VAAPI_DECODER_JPEG_CAST(base_decoder); GstVaapiDecoderStatus status; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; @@ -698,65 +721,33 @@ gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static void -gst_vaapi_decoder_jpeg_finalize(GObject *object) -{ - GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(object); - - gst_vaapi_decoder_jpeg_destroy(decoder); - - G_OBJECT_CLASS(gst_vaapi_decoder_jpeg_parent_class)->finalize(object); -} - -static void -gst_vaapi_decoder_jpeg_constructed(GObject *object) -{ - GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(object); - GstVaapiDecoderJpegPrivate * const priv = decoder->priv; - GObjectClass *parent_class; - - parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_jpeg_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); - - priv->is_constructed = gst_vaapi_decoder_jpeg_create(decoder); -} - static void gst_vaapi_decoder_jpeg_class_init(GstVaapiDecoderJpegClass *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiDecoderJpegPrivate)); - - object_class->finalize = gst_vaapi_decoder_jpeg_finalize; - object_class->constructed = gst_vaapi_decoder_jpeg_constructed; + object_class->size = sizeof(GstVaapiDecoderJpeg); + object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize; + decoder_class->create = gst_vaapi_decoder_jpeg_create; + decoder_class->destroy = gst_vaapi_decoder_jpeg_destroy; decoder_class->parse = gst_vaapi_decoder_jpeg_parse; decoder_class->decode = gst_vaapi_decoder_jpeg_decode; } -static void -gst_vaapi_decoder_jpeg_init(GstVaapiDecoderJpeg *decoder) +static inline const GstVaapiDecoderClass * +gst_vaapi_decoder_jpeg_class(void) { - GstVaapiDecoderJpegPrivate *priv; + static GstVaapiDecoderJpegClass g_class; + static gsize g_class_init = FALSE; - priv = GST_VAAPI_DECODER_JPEG_GET_PRIVATE(decoder); - decoder->priv = priv; - priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; - priv->width = 0; - priv->height = 0; - priv->current_picture = NULL; - priv->has_huf_table = FALSE; - priv->has_quant_table = FALSE; - priv->mcu_restart = 0; - priv->is_opened = FALSE; - priv->profile_changed = TRUE; - priv->is_constructed = FALSE; - memset(&priv->frame_hdr, 0, sizeof(priv->frame_hdr)); - memset(&priv->huf_tables, 0, sizeof(priv->huf_tables)); - memset(&priv->quant_tables, 0, sizeof(priv->quant_tables)); + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_decoder_jpeg_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS(&g_class); } /** @@ -772,20 +763,5 @@ gst_vaapi_decoder_jpeg_init(GstVaapiDecoderJpeg *decoder) GstVaapiDecoder * gst_vaapi_decoder_jpeg_new(GstVaapiDisplay *display, GstCaps *caps) { - GstVaapiDecoderJpeg *decoder; - - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); - - decoder = g_object_new( - GST_VAAPI_TYPE_DECODER_JPEG, - "display", display, - "caps", caps, - NULL - ); - if (!decoder->priv->is_constructed) { - g_object_unref(decoder); - return NULL; - } - return GST_VAAPI_DECODER_CAST(decoder); + return gst_vaapi_decoder_new(gst_vaapi_decoder_jpeg_class(), display, caps); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h index cd3b975d67..8c81de1c6d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h @@ -26,58 +26,7 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DECODER_JPEG \ - (gst_vaapi_decoder_jpeg_get_type()) - -#define GST_VAAPI_DECODER_JPEG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DECODER_JPEG, \ - GstVaapiDecoderJpeg)) - -#define GST_VAAPI_DECODER_JPEG_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DECODER_JPEG, \ - GstVaapiDecoderJpegClass)) - -#define GST_VAAPI_IS_DECODER_JPEG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_JPEG)) - -#define GST_VAAPI_IS_DECODER_JPEG_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_JPEG)) - -#define GST_VAAPI_DECODER_JPEG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DECODER_JPEG, \ - GstVaapiDecoderJpegClass)) - typedef struct _GstVaapiDecoderJpeg GstVaapiDecoderJpeg; -typedef struct _GstVaapiDecoderJpegPrivate GstVaapiDecoderJpegPrivate; -typedef struct _GstVaapiDecoderJpegClass GstVaapiDecoderJpegClass; - -/** - * 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; -}; - -GType -gst_vaapi_decoder_jpeg_get_type(void) G_GNUC_CONST; GstVaapiDecoder * gst_vaapi_decoder_jpeg_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index ecc9d7fcbb..b99d3e7ce7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -316,17 +316,11 @@ gst_vaapi_parser_info_mpeg2_ensure(GstVaapiParserInfoMpeg2 **pi_ptr) /* --- MPEG-2 Decoder --- */ /* ------------------------------------------------------------------------- */ -G_DEFINE_TYPE(GstVaapiDecoderMpeg2, - gst_vaapi_decoder_mpeg2, - GST_VAAPI_TYPE_DECODER) - #define GST_VAAPI_DECODER_MPEG2_CAST(decoder) \ ((GstVaapiDecoderMpeg2 *)(decoder)) -#define GST_VAAPI_DECODER_MPEG2_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DECODER_MPEG2, \ - GstVaapiDecoderMpeg2Private)) +typedef struct _GstVaapiDecoderMpeg2Private GstVaapiDecoderMpeg2Private; +typedef struct _GstVaapiDecoderMpeg2Class GstVaapiDecoderMpeg2Class; typedef enum { GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR = 1 << 0, @@ -367,7 +361,6 @@ struct _GstVaapiDecoderMpeg2Private { GstVaapiPicture *current_picture; GstVaapiDpb *dpb; PTSGenerator tsg; - guint is_constructed : 1; guint is_opened : 1; guint size_changed : 1; guint profile_changed : 1; @@ -377,10 +370,31 @@ struct _GstVaapiDecoderMpeg2Private { guint broken_link : 1; }; +/** + * GstVaapiDecoderMpeg2: + * + * A decoder based on Mpeg2. + */ +struct _GstVaapiDecoderMpeg2 { + /*< private >*/ + GstVaapiDecoder parent_instance; + GstVaapiDecoderMpeg2Private priv; +}; + +/** + * GstVaapiDecoderMpeg2Class: + * + * A decoder class based on Mpeg2. + */ +struct _GstVaapiDecoderMpeg2Class { + /*< private >*/ + GstVaapiDecoderClass parent_class; +}; + static void gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; gst_vaapi_picture_replace(&priv->current_picture, NULL); @@ -400,7 +414,7 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) static gboolean gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; gst_vaapi_decoder_mpeg2_close(decoder); @@ -413,16 +427,24 @@ gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder) } static void -gst_vaapi_decoder_mpeg2_destroy(GstVaapiDecoderMpeg2 *decoder) +gst_vaapi_decoder_mpeg2_destroy(GstVaapiDecoder *base_decoder) { + GstVaapiDecoderMpeg2 * const decoder = + GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); + gst_vaapi_decoder_mpeg2_close(decoder); } static gboolean -gst_vaapi_decoder_mpeg2_create(GstVaapiDecoderMpeg2 *decoder) +gst_vaapi_decoder_mpeg2_create(GstVaapiDecoder *base_decoder) { - if (!GST_VAAPI_DECODER_CODEC(decoder)) - return FALSE; + GstVaapiDecoderMpeg2 * const decoder = + GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; + + priv->hw_profile = GST_VAAPI_PROFILE_UNKNOWN; + priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; + priv->profile_changed = TRUE; /* Allow fallbacks to work */ return TRUE; } @@ -450,7 +472,7 @@ static GstVaapiProfile get_profile(GstVaapiDecoderMpeg2 *decoder, GstVaapiEntrypoint entrypoint) { GstVaapiDisplay * const va_display = GST_VAAPI_DECODER_DISPLAY(decoder); - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstVaapiProfile profile = priv->profile; do { @@ -491,7 +513,7 @@ get_profile(GstVaapiDecoderMpeg2 *decoder, GstVaapiEntrypoint entrypoint) static GstVaapiDecoderStatus ensure_context(GstVaapiDecoderMpeg2 *decoder) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; gboolean reset_context = FALSE; @@ -532,7 +554,7 @@ ensure_context(GstVaapiDecoderMpeg2 *decoder) static GstVaapiDecoderStatus ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr->data.seq_hdr; VAIQMatrixBufferMPEG2 *iq_matrix; guint8 *intra_quant_matrix = NULL; @@ -593,7 +615,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) static inline gboolean is_valid_state(GstVaapiDecoderMpeg2 *decoder, guint state) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; return (priv->state & state) == state; } @@ -601,7 +623,7 @@ is_valid_state(GstVaapiDecoderMpeg2 *decoder, guint state) static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderMpeg2 *decoder) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstVaapiPicture * const picture = priv->current_picture; if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PICTURE)) @@ -634,7 +656,7 @@ static GstVaapiDecoderStatus parse_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSequenceHdr *seq_hdr; priv->state = 0; @@ -660,7 +682,7 @@ static GstVaapiDecoderStatus decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSequenceHdr * const seq_hdr = unit->parsed_info; gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL); @@ -685,7 +707,7 @@ static GstVaapiDecoderStatus parse_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSequenceExt *seq_ext; priv->state &= GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR; @@ -711,7 +733,7 @@ static GstVaapiDecoderStatus decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSequenceExt * const seq_ext = unit->parsed_info; GstVaapiProfile profile; guint width, height; @@ -770,7 +792,7 @@ static GstVaapiDecoderStatus parse_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSequenceDisplayExt *seq_display_ext; if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_display_ext)) { @@ -801,7 +823,7 @@ decode_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; gst_vaapi_dpb_flush(priv->dpb); return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -811,7 +833,7 @@ static GstVaapiDecoderStatus parse_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoQuantMatrixExt *quant_matrix; if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->quant_matrix)) { @@ -835,7 +857,7 @@ static GstVaapiDecoderStatus decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; priv->quant_matrix_changed = TRUE; return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -845,7 +867,7 @@ static GstVaapiDecoderStatus parse_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoGop *gop; if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->gop)) { @@ -868,7 +890,7 @@ parse_gop(GstVaapiDecoderMpeg2 *decoder, static GstVaapiDecoderStatus decode_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoGop * const gop = unit->parsed_info; priv->closed_gop = gop->closed_gop; @@ -886,7 +908,7 @@ static GstVaapiDecoderStatus parse_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoPictureHdr *pic_hdr; priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| @@ -912,7 +934,7 @@ parse_picture(GstVaapiDecoderMpeg2 *decoder, static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS)) return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -927,7 +949,7 @@ static GstVaapiDecoderStatus parse_picture_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoPictureExt *pic_ext; priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| @@ -954,7 +976,7 @@ parse_picture_ext(GstVaapiDecoderMpeg2 *decoder, static GstVaapiDecoderStatus decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoPictureExt * const pic_ext = unit->parsed_info; if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_GOT_PIC_HDR)) @@ -989,7 +1011,7 @@ pack_f_code(guint8 f_code[2][2]) static GstVaapiDecoderStatus init_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr->data.pic_hdr; GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext->data.pic_ext; @@ -1071,7 +1093,7 @@ init_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) static void fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; VAPictureParameterBufferMPEG2 * const pic_param = picture->param; GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr->data.pic_hdr; GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext->data.pic_ext; @@ -1124,7 +1146,7 @@ static GstVaapiDecoderStatus parse_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSliceHdr *slice_hdr; GstBitReader br; gint mb_x, mb_y, mb_inc; @@ -1190,7 +1212,7 @@ failed: static GstVaapiDecoderStatus decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstVaapiPicture * const picture = priv->current_picture; GstVaapiSlice *slice; VASliceParameterBufferMPEG2 *slice_param; @@ -1367,10 +1389,7 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, static GstVaapiDecoderStatus ensure_decoder(GstVaapiDecoderMpeg2 *decoder) { - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - - g_return_val_if_fail(priv->is_constructed, - GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; if (!priv->is_opened) { priv->is_opened = gst_vaapi_decoder_mpeg2_open(decoder); @@ -1513,7 +1532,7 @@ gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder, { GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSequenceHdr *seq_hdr; GstMpegVideoSequenceExt *seq_ext; GstMpegVideoSequenceDisplayExt *seq_display_ext; @@ -1588,47 +1607,24 @@ gst_vaapi_decoder_mpeg2_flush(GstVaapiDecoder *base_decoder) { GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; gst_vaapi_dpb_flush(priv->dpb); return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static void -gst_vaapi_decoder_mpeg2_finalize(GObject *object) -{ - GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(object); - - gst_vaapi_decoder_mpeg2_destroy(decoder); - - G_OBJECT_CLASS(gst_vaapi_decoder_mpeg2_parent_class)->finalize(object); -} - -static void -gst_vaapi_decoder_mpeg2_constructed(GObject *object) -{ - GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(object); - GstVaapiDecoderMpeg2Private * const priv = decoder->priv; - GObjectClass *parent_class; - - parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_mpeg2_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); - - priv->is_constructed = gst_vaapi_decoder_mpeg2_create(decoder); -} - static void gst_vaapi_decoder_mpeg2_class_init(GstVaapiDecoderMpeg2Class *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiDecoderMpeg2Private)); - - object_class->finalize = gst_vaapi_decoder_mpeg2_finalize; - object_class->constructed = gst_vaapi_decoder_mpeg2_constructed; + object_class->size = sizeof(GstVaapiDecoderMpeg2); + object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize; + decoder_class->create = gst_vaapi_decoder_mpeg2_create; + decoder_class->destroy = gst_vaapi_decoder_mpeg2_destroy; decoder_class->parse = gst_vaapi_decoder_mpeg2_parse; decoder_class->decode = gst_vaapi_decoder_mpeg2_decode; decoder_class->start_frame = gst_vaapi_decoder_mpeg2_start_frame; @@ -1636,16 +1632,17 @@ gst_vaapi_decoder_mpeg2_class_init(GstVaapiDecoderMpeg2Class *klass) decoder_class->flush = gst_vaapi_decoder_mpeg2_flush; } -static void -gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) +static inline const GstVaapiDecoderClass * +gst_vaapi_decoder_mpeg2_class(void) { - GstVaapiDecoderMpeg2Private *priv; + static GstVaapiDecoderMpeg2Class g_class; + static gsize g_class_init = FALSE; - priv = GST_VAAPI_DECODER_MPEG2_GET_PRIVATE(decoder); - decoder->priv = priv; - priv->hw_profile = GST_VAAPI_PROFILE_UNKNOWN; - priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; - priv->profile_changed = TRUE; /* Allow fallbacks to work */ + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_decoder_mpeg2_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS(&g_class); } /** @@ -1661,20 +1658,6 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder) GstVaapiDecoder * gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps) { - GstVaapiDecoderMpeg2 *decoder; - - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); - - decoder = g_object_new( - GST_VAAPI_TYPE_DECODER_MPEG2, - "display", display, - "caps", caps, - NULL - ); - if (!decoder->priv->is_constructed) { - g_object_unref(decoder); - return NULL; - } - return GST_VAAPI_DECODER_CAST(decoder); + return gst_vaapi_decoder_new(gst_vaapi_decoder_mpeg2_class(), + display, caps); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h index dd3468a85b..bdf40fb9b7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h @@ -27,58 +27,7 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DECODER_MPEG2 \ - (gst_vaapi_decoder_mpeg2_get_type()) - -#define GST_VAAPI_DECODER_MPEG2(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DECODER_MPEG2, \ - GstVaapiDecoderMpeg2)) - -#define GST_VAAPI_DECODER_MPEG2_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DECODER_MPEG2, \ - GstVaapiDecoderMpeg2Class)) - -#define GST_VAAPI_IS_DECODER_MPEG2(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_MPEG2)) - -#define GST_VAAPI_IS_DECODER_MPEG2_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_MPEG2)) - -#define GST_VAAPI_DECODER_MPEG2_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DECODER_MPEG2, \ - GstVaapiDecoderMpeg2Class)) - typedef struct _GstVaapiDecoderMpeg2 GstVaapiDecoderMpeg2; -typedef struct _GstVaapiDecoderMpeg2Private GstVaapiDecoderMpeg2Private; -typedef struct _GstVaapiDecoderMpeg2Class GstVaapiDecoderMpeg2Class; - -/** - * GstVaapiDecoderMpeg2: - * - * A decoder based on Mpeg2. - */ -struct _GstVaapiDecoderMpeg2 { - /*< private >*/ - GstVaapiDecoder parent_instance; - - GstVaapiDecoderMpeg2Private *priv; -}; - -/** - * GstVaapiDecoderMpeg2Class: - * - * A decoder class based on Mpeg2. - */ -struct _GstVaapiDecoderMpeg2Class { - /*< private >*/ - GstVaapiDecoderClass parent_class; -}; - -GType -gst_vaapi_decoder_mpeg2_get_type(void) G_GNUC_CONST; GstVaapiDecoder * gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index b7b6e0bc8b..79b15bed4c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -37,17 +37,11 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDecoderMpeg4, - gst_vaapi_decoder_mpeg4, - GST_VAAPI_TYPE_DECODER) - #define GST_VAAPI_DECODER_MPEG4_CAST(decoder) \ ((GstVaapiDecoderMpeg4 *)(decoder)) -#define GST_VAAPI_DECODER_MPEG4_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DECODER_MPEG4, \ - GstVaapiDecoderMpeg4Private)) +typedef struct _GstVaapiDecoderMpeg4Private GstVaapiDecoderMpeg4Private; +typedef struct _GstVaapiDecoderMpeg4Class GstVaapiDecoderMpeg4Class; struct _GstVaapiDecoderMpeg4Private { GstVaapiProfile profile; @@ -89,7 +83,6 @@ struct _GstVaapiDecoderMpeg4Private { GstClockTime trd; // temporal_reference of previous frame of svh guint8 prev_t_ref; - guint is_constructed : 1; guint is_opened : 1; guint is_first_field : 1; guint size_changed : 1; @@ -101,10 +94,32 @@ struct _GstVaapiDecoderMpeg4Private { guint is_svh : 1; }; +/** + * GstVaapiDecoderMpeg4: + * + * A decoder based on Mpeg4. + */ +struct _GstVaapiDecoderMpeg4 { + /*< private >*/ + GstVaapiDecoder parent_instance; + GstVaapiDecoderMpeg4Private priv; +}; + +/** + * GstVaapiDecoderMpeg4Class: + * + * A decoder class based on Mpeg4. + */ +typedef struct _GstVaapiDecoderMpeg4Class GstVaapiDecoderMpeg4Class; +struct _GstVaapiDecoderMpeg4Class { + /*< private >*/ + GstVaapiDecoderClass parent_class; +}; + static void gst_vaapi_decoder_mpeg4_close(GstVaapiDecoderMpeg4 *decoder) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; gst_vaapi_picture_replace(&priv->curr_picture, NULL); gst_vaapi_picture_replace(&priv->next_picture, NULL); @@ -115,7 +130,7 @@ static gboolean gst_vaapi_decoder_mpeg4_open(GstVaapiDecoderMpeg4 *decoder) { GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER(decoder); - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstCaps *caps = NULL; GstStructure *structure = NULL; @@ -137,16 +152,28 @@ gst_vaapi_decoder_mpeg4_open(GstVaapiDecoderMpeg4 *decoder) } static void -gst_vaapi_decoder_mpeg4_destroy(GstVaapiDecoderMpeg4 *decoder) +gst_vaapi_decoder_mpeg4_destroy(GstVaapiDecoder *base_decoder) { + GstVaapiDecoderMpeg4 * const decoder = + GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); + gst_vaapi_decoder_mpeg4_close(decoder); } static gboolean -gst_vaapi_decoder_mpeg4_create(GstVaapiDecoderMpeg4 *decoder) +gst_vaapi_decoder_mpeg4_create(GstVaapiDecoder *base_decoder) { - if (!GST_VAAPI_DECODER_CODEC(decoder)) - return FALSE; + GstVaapiDecoderMpeg4 * const decoder = + GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; + + priv->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; + priv->seq_pts = GST_CLOCK_TIME_NONE; + priv->gop_pts = GST_CLOCK_TIME_NONE; + priv->max_pts = GST_CLOCK_TIME_NONE; + priv->calculate_pts_diff = TRUE; + priv->size_changed = TRUE; + priv->profile_changed = TRUE; return TRUE; } @@ -159,7 +186,7 @@ copy_quant_matrix(guint8 dst[64], const guint8 src[64]) static GstVaapiDecoderStatus ensure_context(GstVaapiDecoderMpeg4 *decoder) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstVaapiProfile profiles[2]; GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; guint i, n_profiles = 0; @@ -211,7 +238,7 @@ ensure_context(GstVaapiDecoderMpeg4 *decoder) static GstVaapiDecoderStatus ensure_quant_matrix(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; VAIQMatrixBufferMPEG4 *iq_matrix; if (!priv->vol_hdr.load_intra_quant_mat && !priv->vol_hdr.load_non_intra_quant_mat) { @@ -260,7 +287,7 @@ render_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderMpeg4 *decoder) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstVaapiPicture * const picture = priv->curr_picture; GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -280,7 +307,7 @@ decode_current_picture(GstVaapiDecoderMpeg4 *decoder) static GstVaapiDecoderStatus decode_sequence(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstMpeg4VisualObjectSequence * const vos_hdr = &priv->vos_hdr; GstVaapiProfile profile; @@ -315,7 +342,7 @@ decode_sequence(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderMpeg4 *decoder) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; if (priv->curr_picture) { @@ -338,7 +365,7 @@ decode_sequence_end(GstVaapiDecoderMpeg4 *decoder) static GstVaapiDecoderStatus decode_visual_object(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstMpeg4VisualObject * vo_hdr = &priv->vo_hdr; GstMpeg4VideoSignalType * signal_type = &priv->signal_type; @@ -355,7 +382,7 @@ static GstVaapiDecoderStatus decode_video_object_layer(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstMpeg4VisualObject * vo_hdr = &priv->vo_hdr; GstMpeg4VideoObjectLayer * vol_hdr = &priv->vol_hdr; @@ -384,7 +411,7 @@ decode_video_object_layer(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guin static GstVaapiDecoderStatus decode_gop(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstMpeg4GroupOfVOP gop; GstClockTime gop_time; @@ -427,7 +454,7 @@ calculate_pts_diff(GstVaapiDecoderMpeg4 *decoder, GstMpeg4VideoObjectLayer *vol_hdr, GstMpeg4VideoObjectPlane *vop_hdr) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstClockTime frame_timestamp; frame_timestamp = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; @@ -473,7 +500,7 @@ static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) { GstMpeg4ParseResult parser_result = GST_MPEG4_PARSER_OK; - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr; GstMpeg4VideoObjectLayer * const vol_hdr = &priv->vol_hdr; GstMpeg4SpriteTrajectory * const sprite_trajectory = &priv->sprite_trajectory; @@ -643,7 +670,7 @@ get_vop_coding_type(GstVaapiPicture *picture) static gboolean fill_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; VAPictureParameterBufferMPEG4 * const pic_param = picture->param; GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr; @@ -742,7 +769,7 @@ decode_slice( gboolean has_packet_header ) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstVaapiPicture * const picture = priv->curr_picture; GstVaapiSlice *slice; VASliceParameterBufferMPEG4 *slice_param; @@ -786,7 +813,7 @@ decode_slice( static GstVaapiDecoderStatus decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstMpeg4Packet *tos = &packet; GstVaapiDecoderStatus status; @@ -895,7 +922,7 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderMpeg4 *decoder, const guchar *buf, guint buf_size) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; GstMpeg4Packet packet; guint ofs; @@ -967,12 +994,9 @@ gst_vaapi_decoder_mpeg4_decode_codec_data(GstVaapiDecoder *base_decoder, static GstVaapiDecoderStatus ensure_decoder(GstVaapiDecoderMpeg4 *decoder) { - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; - g_return_val_if_fail(priv->is_constructed, - GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); - if (!priv->is_opened) { priv->is_opened = gst_vaapi_decoder_mpeg4_open(decoder); if (!priv->is_opened) @@ -991,8 +1015,8 @@ gst_vaapi_decoder_mpeg4_parse(GstVaapiDecoder *base_decoder, GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg4 * const decoder = - GST_VAAPI_DECODER_MPEG4(base_decoder); - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; + GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); + GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; GstMpeg4Packet packet; GstMpeg4ParseResult result; @@ -1081,7 +1105,7 @@ gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderMpeg4 * const decoder = - GST_VAAPI_DECODER_MPEG4(base_decoder); + GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); GstVaapiDecoderStatus status; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; @@ -1103,41 +1127,18 @@ gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base_decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static void -gst_vaapi_decoder_mpeg4_finalize(GObject *object) -{ - GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4(object); - - gst_vaapi_decoder_mpeg4_destroy(decoder); - - G_OBJECT_CLASS(gst_vaapi_decoder_mpeg4_parent_class)->finalize(object); -} - -static void -gst_vaapi_decoder_mpeg4_constructed(GObject *object) -{ - GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4(object); - GstVaapiDecoderMpeg4Private * const priv = decoder->priv; - GObjectClass *parent_class; - - parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_mpeg4_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); - - priv->is_constructed = gst_vaapi_decoder_mpeg4_create(decoder); -} - static void gst_vaapi_decoder_mpeg4_class_init(GstVaapiDecoderMpeg4Class *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiDecoderMpeg4Private)); - - object_class->finalize = gst_vaapi_decoder_mpeg4_finalize; - object_class->constructed = gst_vaapi_decoder_mpeg4_constructed; + object_class->size = sizeof(GstVaapiDecoderMpeg4); + object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize; + decoder_class->create = gst_vaapi_decoder_mpeg4_create; + decoder_class->destroy = gst_vaapi_decoder_mpeg4_destroy; decoder_class->parse = gst_vaapi_decoder_mpeg4_parse; decoder_class->decode = gst_vaapi_decoder_mpeg4_decode; @@ -1145,38 +1146,17 @@ gst_vaapi_decoder_mpeg4_class_init(GstVaapiDecoderMpeg4Class *klass) gst_vaapi_decoder_mpeg4_decode_codec_data; } -static void -gst_vaapi_decoder_mpeg4_init(GstVaapiDecoderMpeg4 *decoder) +static inline const GstVaapiDecoderClass * +gst_vaapi_decoder_mpeg4_class(void) { - GstVaapiDecoderMpeg4Private *priv; + static GstVaapiDecoderMpeg4Class g_class; + static gsize g_class_init = FALSE; - priv = GST_VAAPI_DECODER_MPEG4_GET_PRIVATE(decoder); - decoder->priv = priv; - priv->width = 0; - priv->height = 0; - priv->fps_n = 0; - priv->fps_d = 0; - priv->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; - priv->curr_picture = NULL; - priv->next_picture = NULL; - priv->prev_picture = NULL; - priv->seq_pts = GST_CLOCK_TIME_NONE; - priv->gop_pts = GST_CLOCK_TIME_NONE; - priv->max_pts = GST_CLOCK_TIME_NONE; - priv->pts_diff = 0; - priv->calculate_pts_diff = TRUE; - priv->is_constructed = FALSE; - priv->is_opened = FALSE; - priv->is_first_field = FALSE; - priv->size_changed = TRUE; - priv->profile_changed = TRUE; - priv->progressive_sequence = FALSE; - priv->closed_gop = FALSE; - priv->broken_link = FALSE; - priv->last_non_b_scale_time = 0; - priv->non_b_scale_time = 0; - priv->trb = 0; - priv->trd = 0; + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_decoder_mpeg4_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS(&g_class); } /** @@ -1192,20 +1172,6 @@ gst_vaapi_decoder_mpeg4_init(GstVaapiDecoderMpeg4 *decoder) GstVaapiDecoder * gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps) { - GstVaapiDecoderMpeg4 *decoder; - - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); - - decoder = g_object_new( - GST_VAAPI_TYPE_DECODER_MPEG4, - "display", display, - "caps", caps, - NULL - ); - if (!decoder->priv->is_constructed) { - g_object_unref(decoder); - return NULL; - } - return GST_VAAPI_DECODER_CAST(decoder); + return gst_vaapi_decoder_new(gst_vaapi_decoder_mpeg4_class(), + display, caps); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h index 5d24fdd6f5..07134a75a2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h @@ -27,58 +27,7 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DECODER_MPEG4 \ - (gst_vaapi_decoder_mpeg4_get_type()) - -#define GST_VAAPI_DECODER_MPEG4(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DECODER_MPEG4, \ - GstVaapiDecoderMpeg4)) - -#define GST_VAAPI_DECODER_MPEG4_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DECODER_MPEG4, \ - GstVaapiDecoderMpeg4Class)) - -#define GST_VAAPI_IS_DECODER_MPEG4(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_MPEG4)) - -#define GST_VAAPI_IS_DECODER_MPEG4_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_MPEG4)) - -#define GST_VAAPI_DECODER_MPEG4_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DECODER_MPEG4, \ - GstVaapiDecoderMpeg4Class)) - typedef struct _GstVaapiDecoderMpeg4 GstVaapiDecoderMpeg4; -typedef struct _GstVaapiDecoderMpeg4Private GstVaapiDecoderMpeg4Private; -typedef struct _GstVaapiDecoderMpeg4Class GstVaapiDecoderMpeg4Class; - -/** - * GstVaapiDecoderMpeg4: - * - * A decoder based on Mpeg4. - */ -struct _GstVaapiDecoderMpeg4 { - /*< private >*/ - GstVaapiDecoder parent_instance; - - GstVaapiDecoderMpeg4Private *priv; -}; - -/** - * GstVaapiDecoderMpeg4Class: - * - * A decoder class based on Mpeg4. - */ -struct _GstVaapiDecoderMpeg4Class { - /*< private >*/ - GstVaapiDecoderClass parent_class; -}; - -GType -gst_vaapi_decoder_mpeg4_get_type(void) G_GNUC_CONST; GstVaapiDecoder * gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index f94fd6c43f..3390aea76d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -33,9 +33,9 @@ #include "gstvaapidebug.h" #define GET_DECODER(obj) GST_VAAPI_DECODER_CAST((obj)->parent_instance.codec) -#define GET_CONTEXT(obj) GET_DECODER(obj)->priv->context -#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->priv->va_display -#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->priv->va_context +#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 /* ------------------------------------------------------------------------- */ /* --- Pictures --- */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 094043f096..a86b4a16ae 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -27,10 +27,24 @@ #include #include #include +#include "gstvaapiminiobject.h" G_BEGIN_DECLS -#define GST_VAAPI_DECODER_CAST(decoder) ((GstVaapiDecoder *)(decoder)) +#define GST_VAAPI_DECODER_CAST(decoder) \ + ((GstVaapiDecoder *)(decoder)) + +#define GST_VAAPI_DECODER_CLASS(klass) \ + ((GstVaapiDecoderClass *)(klass)) + +#define GST_VAAPI_IS_DECODER_CLASS(klass) \ + ((klass) != NULL)) + +#define GST_VAAPI_DECODER_GET_CLASS(obj) \ + GST_VAAPI_DECODER_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + +typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; + struct _GstVaapiDecoderUnit; /** * GST_VAAPI_PARSER_STATE: @@ -41,7 +55,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_PARSER_STATE #define GST_VAAPI_PARSER_STATE(decoder) \ - (&GST_VAAPI_DECODER_CAST(decoder)->priv->parser_state) + (&GST_VAAPI_DECODER_CAST(decoder)->parser_state) /** * GST_VAAPI_DECODER_DISPLAY: @@ -52,7 +66,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DECODER_DISPLAY #define GST_VAAPI_DECODER_DISPLAY(decoder) \ - GST_VAAPI_DECODER_CAST(decoder)->priv->display + GST_VAAPI_DECODER_CAST(decoder)->display /** * GST_VAAPI_DECODER_CONTEXT: @@ -63,7 +77,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DECODER_CONTEXT #define GST_VAAPI_DECODER_CONTEXT(decoder) \ - GST_VAAPI_DECODER_CAST(decoder)->priv->context + GST_VAAPI_DECODER_CAST(decoder)->context /** * GST_VAAPI_DECODER_CODEC: @@ -74,7 +88,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DECODER_CODEC #define GST_VAAPI_DECODER_CODEC(decoder) \ - GST_VAAPI_DECODER_CAST(decoder)->priv->codec + GST_VAAPI_DECODER_CAST(decoder)->codec /** * GST_VAAPI_DECODER_CODEC_STATE: @@ -86,7 +100,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DECODER_CODEC_STATE #define GST_VAAPI_DECODER_CODEC_STATE(decoder) \ - GST_VAAPI_DECODER_CAST(decoder)->priv->codec_state + GST_VAAPI_DECODER_CAST(decoder)->codec_state /** * GST_VAAPI_DECODER_CODEC_DATA: @@ -161,7 +175,16 @@ struct _GstVaapiParserState { guint at_eos : 1; }; -struct _GstVaapiDecoderPrivate { +/** + * GstVaapiDecoder: + * + * A VA decoder base instance. + */ +struct _GstVaapiDecoder { + /*< private >*/ + GstVaapiMiniObject parent_instance; + + gpointer user_data; GstVaapiDisplay *display; VADisplay va_display; GstVaapiContext *context; @@ -171,8 +194,43 @@ struct _GstVaapiDecoderPrivate { 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 >*/ + GstVaapiMiniObjectClass parent_class; + + gboolean (*create)(GstVaapiDecoder *decoder); + void (*destroy)(GstVaapiDecoder *decoder); + 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 (*decode_codec_data)(GstVaapiDecoder *decoder, + const guchar *buf, guint buf_size); +}; + +G_GNUC_INTERNAL +GstVaapiDecoder * +gst_vaapi_decoder_new(const GstVaapiDecoderClass *klass, + GstVaapiDisplay *display, GstCaps *caps); + +G_GNUC_INTERNAL +void +gst_vaapi_decoder_finalize(GstVaapiDecoder *decoder); + G_GNUC_INTERNAL void gst_vaapi_decoder_set_picture_size( diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 6eb701b6b1..752ee6858f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -38,18 +38,17 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDecoderVC1, - gst_vaapi_decoder_vc1, - GST_VAAPI_TYPE_DECODER) - #define GST_VAAPI_DECODER_VC1_CAST(decoder) \ ((GstVaapiDecoderVC1 *)(decoder)) -#define GST_VAAPI_DECODER_VC1_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DECODER_VC1, \ - GstVaapiDecoderVC1Private)) +typedef struct _GstVaapiDecoderVC1Private GstVaapiDecoderVC1Private; +typedef struct _GstVaapiDecoderVC1Class GstVaapiDecoderVC1Class; +/** + * GstVaapiDecoderVC1: + * + * A decoder based on VC1. + */ struct _GstVaapiDecoderVC1Private { GstVaapiProfile profile; guint width; @@ -64,7 +63,6 @@ struct _GstVaapiDecoderVC1Private { gint32 next_poc; guint8 *rbdu_buffer; guint rbdu_buffer_size; - guint is_constructed : 1; guint is_opened : 1; guint is_first_field : 1; guint has_codec_data : 1; @@ -75,6 +73,27 @@ struct _GstVaapiDecoderVC1Private { guint broken_link : 1; }; +/** + * GstVaapiDecoderVC1: + * + * A decoder based on VC1. + */ +struct _GstVaapiDecoderVC1 { + /*< private >*/ + GstVaapiDecoder parent_instance; + GstVaapiDecoderVC1Private priv; +}; + +/** + * GstVaapiDecoderVC1Class: + * + * A decoder class based on VC1. + */ +struct _GstVaapiDecoderVC1Class { + /*< private >*/ + GstVaapiDecoderClass parent_class; +}; + static GstVaapiDecoderStatus get_status(GstVC1ParserResult result) { @@ -100,7 +119,7 @@ get_status(GstVC1ParserResult result) static void gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; gst_vaapi_picture_replace(&priv->last_non_b_picture, NULL); gst_vaapi_picture_replace(&priv->current_picture, NULL); @@ -115,7 +134,7 @@ gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder) static gboolean gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; gst_vaapi_decoder_vc1_close(decoder); @@ -130,9 +149,11 @@ gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder) } static void -gst_vaapi_decoder_vc1_destroy(GstVaapiDecoderVC1 *decoder) +gst_vaapi_decoder_vc1_destroy(GstVaapiDecoder *base_decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1 * const decoder = + GST_VAAPI_DECODER_VC1_CAST(base_decoder); + GstVaapiDecoderVC1Private * const priv = &decoder->priv; gst_vaapi_decoder_vc1_close(decoder); @@ -144,17 +165,20 @@ gst_vaapi_decoder_vc1_destroy(GstVaapiDecoderVC1 *decoder) } static gboolean -gst_vaapi_decoder_vc1_create(GstVaapiDecoderVC1 *decoder) +gst_vaapi_decoder_vc1_create(GstVaapiDecoder *base_decoder) { - if (!GST_VAAPI_DECODER_CODEC(decoder)) - return FALSE; + GstVaapiDecoderVC1 * const decoder = + GST_VAAPI_DECODER_VC1_CAST(base_decoder); + GstVaapiDecoderVC1Private * const priv = &decoder->priv; + + priv->profile = (GstVaapiProfile)0; return TRUE; } static GstVaapiDecoderStatus ensure_context(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVaapiProfile profiles[2]; GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; guint i, n_profiles = 0; @@ -206,7 +230,7 @@ ensure_context(GstVaapiDecoderVC1 *decoder) static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVaapiPicture * const picture = priv->current_picture; if (!picture) @@ -231,7 +255,7 @@ static GstVaapiDecoderStatus decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1AdvancedSeqHdr * const adv_hdr = &seq_hdr->advanced; GstVC1SeqStructC * const structc = &seq_hdr->struct_c; @@ -347,7 +371,7 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; status = decode_current_picture(decoder); @@ -361,7 +385,7 @@ decode_sequence_end(GstVaapiDecoderVC1 *decoder) static GstVaapiDecoderStatus decode_entry_point(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr; GstVC1ParserResult result; @@ -503,7 +527,7 @@ get_MVMODE2(GstVC1FrameHdr *frame_hdr) static inline int has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; guint mvmode, mvmode2; @@ -531,7 +555,7 @@ has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder) static inline int has_SKIPMB_bitplane(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; @@ -552,7 +576,7 @@ has_SKIPMB_bitplane(GstVaapiDecoderVC1 *decoder) static inline int has_DIRECTMB_bitplane(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; @@ -572,7 +596,7 @@ has_DIRECTMB_bitplane(GstVaapiDecoderVC1 *decoder) static inline int has_ACPRED_bitplane(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; @@ -588,7 +612,7 @@ has_ACPRED_bitplane(GstVaapiDecoderVC1 *decoder) static inline int has_OVERFLAGS_bitplane(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; @@ -623,7 +647,7 @@ pack_bitplanes(GstVaapiBitPlane *bitplane, guint n, const guint8 *bitplanes[3], static gboolean fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; VAPictureParameterBufferVC1 * const pic_param = picture->param; GstVC1SeqStructC * const structc = &priv->seq_hdr.struct_c; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; @@ -666,7 +690,7 @@ fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) static gboolean fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; VAPictureParameterBufferVC1 * const pic_param = picture->param; GstVC1AdvancedSeqHdr * const adv_hdr = &priv->seq_hdr.advanced; GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr; @@ -733,7 +757,7 @@ fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) static gboolean fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; VAPictureParameterBufferVC1 * const pic_param = picture->param; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; @@ -852,7 +876,7 @@ static GstVaapiDecoderStatus decode_slice_chunk(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu, guint slice_addr, guint header_size) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVaapiPicture * const picture = priv->current_picture; GstVaapiSlice *slice; VASliceParameterBufferVC1 *slice_param; @@ -877,7 +901,7 @@ decode_slice_chunk(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu, static GstVaapiDecoderStatus decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; GstVC1ParserResult result; GstVaapiPicture * const picture = priv->current_picture; @@ -939,7 +963,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) static GstVaapiDecoderStatus decode_slice(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVC1SliceHdr slice_hdr; GstVC1ParserResult result; @@ -961,7 +985,7 @@ decode_slice(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) static gboolean decode_rbdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; guint8 *rbdu_buffer; guint i, j, rbdu_buffer_size; @@ -1045,7 +1069,7 @@ decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu) static GstVaapiDecoderStatus decode_buffer(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVC1BDU ebdu; if (priv->has_codec_data) { @@ -1069,7 +1093,7 @@ gst_vaapi_decoder_vc1_decode_codec_data(GstVaapiDecoder *base_decoder, { GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1_CAST(base_decoder); - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVaapiDecoderStatus status; GstVC1ParserResult result; @@ -1151,12 +1175,9 @@ gst_vaapi_decoder_vc1_decode_codec_data(GstVaapiDecoder *base_decoder, static GstVaapiDecoderStatus ensure_decoder(GstVaapiDecoderVC1 *decoder) { - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; - g_return_val_if_fail(priv->is_constructed, - GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED); - if (!priv->is_opened) { priv->is_opened = gst_vaapi_decoder_vc1_open(decoder); if (!priv->is_opened) @@ -1181,8 +1202,9 @@ static GstVaapiDecoderStatus gst_vaapi_decoder_vc1_parse(GstVaapiDecoder *base_decoder, GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1 * const decoder = + GST_VAAPI_DECODER_VC1_CAST(base_decoder); + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; guint8 bdu_type; guint size, buf_size, flags = 0; @@ -1251,7 +1273,8 @@ static GstVaapiDecoderStatus gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); + GstVaapiDecoderVC1 * const decoder = + GST_VAAPI_DECODER_VC1_CAST(base_decoder); GstVaapiDecoderStatus status; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; @@ -1277,8 +1300,9 @@ static GstVaapiDecoderStatus gst_vaapi_decoder_vc1_start_frame(GstVaapiDecoder *base_decoder, GstVaapiDecoderUnit *unit) { - GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1 * const decoder = + GST_VAAPI_DECODER_VC1_CAST(base_decoder); + GstVaapiDecoderVC1Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; GstVaapiPicture *picture; @@ -1306,7 +1330,8 @@ gst_vaapi_decoder_vc1_start_frame(GstVaapiDecoder *base_decoder, static GstVaapiDecoderStatus gst_vaapi_decoder_vc1_end_frame(GstVaapiDecoder *base_decoder) { - GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); + GstVaapiDecoderVC1 * const decoder = + GST_VAAPI_DECODER_VC1_CAST(base_decoder); return decode_current_picture(decoder); } @@ -1314,48 +1339,26 @@ gst_vaapi_decoder_vc1_end_frame(GstVaapiDecoder *base_decoder) static GstVaapiDecoderStatus gst_vaapi_decoder_vc1_flush(GstVaapiDecoder *base_decoder) { - GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder); - GstVaapiDecoderVC1Private * const priv = decoder->priv; + GstVaapiDecoderVC1 * const decoder = + GST_VAAPI_DECODER_VC1_CAST(base_decoder); + GstVaapiDecoderVC1Private * const priv = &decoder->priv; gst_vaapi_dpb_flush(priv->dpb); return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static void -gst_vaapi_decoder_vc1_finalize(GObject *object) -{ - GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object); - - gst_vaapi_decoder_vc1_destroy(decoder); - - G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class)->finalize(object); -} - -static void -gst_vaapi_decoder_vc1_constructed(GObject *object) -{ - GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object); - GstVaapiDecoderVC1Private * const priv = decoder->priv; - GObjectClass *parent_class; - - parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); - - priv->is_constructed = gst_vaapi_decoder_vc1_create(decoder); -} - static void gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiDecoderVC1Private)); - - object_class->finalize = gst_vaapi_decoder_vc1_finalize; - object_class->constructed = gst_vaapi_decoder_vc1_constructed; + object_class->size = sizeof(GstVaapiDecoderVC1); + object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize; + decoder_class->create = gst_vaapi_decoder_vc1_create; + decoder_class->destroy = gst_vaapi_decoder_vc1_destroy; decoder_class->parse = gst_vaapi_decoder_vc1_parse; decoder_class->decode = gst_vaapi_decoder_vc1_decode; decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame; @@ -1366,27 +1369,17 @@ gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass) gst_vaapi_decoder_vc1_decode_codec_data; } -static void -gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder) +static inline const GstVaapiDecoderClass * +gst_vaapi_decoder_vc1_class(void) { - GstVaapiDecoderVC1Private *priv; + static GstVaapiDecoderVC1Class g_class; + static gsize g_class_init = FALSE; - priv = GST_VAAPI_DECODER_VC1_GET_PRIVATE(decoder); - decoder->priv = priv; - priv->width = 0; - priv->height = 0; - priv->profile = (GstVaapiProfile)0; - priv->current_picture = NULL; - priv->rbdu_buffer = NULL; - priv->rbdu_buffer_size = 0; - priv->is_constructed = FALSE; - priv->is_opened = FALSE; - priv->is_first_field = FALSE; - priv->has_entrypoint = FALSE; - priv->size_changed = FALSE; - priv->profile_changed = FALSE; - priv->closed_entry = FALSE; - priv->broken_link = FALSE; + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_decoder_vc1_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS(&g_class); } /** @@ -1402,20 +1395,5 @@ gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder) GstVaapiDecoder * gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps) { - GstVaapiDecoderVC1 *decoder; - - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); - - decoder = g_object_new( - GST_VAAPI_TYPE_DECODER_VC1, - "display", display, - "caps", caps, - NULL - ); - if (!decoder->priv->is_constructed) { - g_object_unref(decoder); - return NULL; - } - return GST_VAAPI_DECODER_CAST(decoder); + return gst_vaapi_decoder_new(gst_vaapi_decoder_vc1_class(), display, caps); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h index 53ecde4e64..405b1e7cc1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h @@ -27,58 +27,7 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DECODER_VC1 \ - (gst_vaapi_decoder_vc1_get_type()) - -#define GST_VAAPI_DECODER_VC1(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DECODER_VC1, \ - GstVaapiDecoderVC1)) - -#define GST_VAAPI_DECODER_VC1_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DECODER_VC1, \ - GstVaapiDecoderVC1Class)) - -#define GST_VAAPI_IS_DECODER_VC1(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_VC1)) - -#define GST_VAAPI_IS_DECODER_VC1_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_VC1)) - -#define GST_VAAPI_DECODER_VC1_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DECODER_VC1, \ - GstVaapiDecoderVC1Class)) - typedef struct _GstVaapiDecoderVC1 GstVaapiDecoderVC1; -typedef struct _GstVaapiDecoderVC1Private GstVaapiDecoderVC1Private; -typedef struct _GstVaapiDecoderVC1Class GstVaapiDecoderVC1Class; - -/** - * GstVaapiDecoderVC1: - * - * A decoder based on VC1. - */ -struct _GstVaapiDecoderVC1 { - /*< private >*/ - GstVaapiDecoder parent_instance; - - GstVaapiDecoderVC1Private *priv; -}; - -/** - * GstVaapiDecoderVC1Class: - * - * A decoder class based on VC1. - */ -struct _GstVaapiDecoderVC1Class { - /*< private >*/ - GstVaapiDecoderClass parent_class; -}; - -GType -gst_vaapi_decoder_vc1_get_type(void) G_GNUC_CONST; GstVaapiDecoder * gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps); From 915cef5e010c83ba28fc5d924ed313f6a2134357 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 7 May 2013 11:39:34 +0200 Subject: [PATCH 1180/3781] libs: use GstVaapiMiniObject for display objects. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 4 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 535 ++++++++++-------- gst-libs/gst/vaapi/gstvaapidisplay.h | 92 +-- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 282 ++++----- gst-libs/gst/vaapi/gstvaapidisplay_drm.h | 52 +- gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h | 44 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 48 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 49 +- gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 34 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 132 ++++- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 272 +++------ gst-libs/gst/vaapi/gstvaapidisplay_wayland.h | 51 +- .../gst/vaapi/gstvaapidisplay_wayland_priv.h | 38 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 326 ++++------- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 56 +- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 54 +- gst-libs/gst/vaapi/gstvaapiobject.c | 4 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 4 +- 18 files changed, 938 insertions(+), 1139 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 15b09ed015..c11b0f6a2f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -465,7 +465,7 @@ gst_vaapi_decoder_finalize(GstVaapiDecoder *decoder) gst_vaapi_object_replace(&decoder->context, NULL); decoder->va_context = VA_INVALID_ID; - g_clear_object(&decoder->display); + gst_vaapi_display_replace(&decoder->display, NULL); decoder->va_display = NULL; } @@ -485,7 +485,7 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder, GstVaapiDisplay *display, gst_video_info_init(&codec_state->info); decoder->user_data = NULL; - decoder->display = g_object_ref(display); + decoder->display = gst_vaapi_display_ref(display); decoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY(display); decoder->context = NULL; decoder->va_context = VA_INVALID_ID; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 602dbb4a22..a8b4e9967b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -39,7 +39,10 @@ GST_DEBUG_CATEGORY(gst_debug_vaapi); -G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT) +/* Ensure those symbols are actually defined in the resulting libraries */ +#undef gst_vaapi_display_ref +#undef gst_vaapi_display_unref +#undef gst_vaapi_display_replace typedef struct _GstVaapiConfig GstVaapiConfig; struct _GstVaapiConfig { @@ -66,10 +69,6 @@ struct _GstVaapiFormatInfo { enum { PROP_0, - PROP_DISPLAY, - PROP_DISPLAY_TYPE, - PROP_WIDTH, - PROP_HEIGHT, PROP_RENDER_MODE, PROP_ROTATION, PROP_HUE, @@ -84,6 +83,9 @@ static GstVaapiDisplayCache *g_display_cache = NULL; static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; +static void +gst_vaapi_display_properties_init(void); + static gboolean get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value); @@ -109,6 +111,8 @@ libgstvaapi_init_once(void) /* Dump gstreamer-vaapi version for debugging purposes */ GST_INFO("gstreamer-vaapi version %s", GST_VAAPI_VERSION_ID); + gst_vaapi_display_properties_init(); + g_once_init_leave(&g_once, TRUE); } @@ -417,13 +421,43 @@ find_property_by_type(GArray *properties, VADisplayAttribType type) static inline const GstVaapiProperty * find_property_by_pspec(GstVaapiDisplay *display, GParamSpec *pspec) { - return find_property(display->priv->properties, pspec->name); + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); + + return find_property(priv->properties, pspec->name); +} + +static guint +find_property_id(const gchar *name) +{ + typedef struct { + const gchar *name; + guint id; + } property_map; + + static const property_map g_property_map[] = { + { GST_VAAPI_DISPLAY_PROP_RENDER_MODE, PROP_RENDER_MODE }, + { GST_VAAPI_DISPLAY_PROP_ROTATION, PROP_ROTATION }, + { GST_VAAPI_DISPLAY_PROP_HUE, PROP_HUE }, + { GST_VAAPI_DISPLAY_PROP_SATURATION, PROP_SATURATION }, + { GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, PROP_BRIGHTNESS }, + { GST_VAAPI_DISPLAY_PROP_CONTRAST, PROP_CONTRAST }, + { NULL, } + }; + + const property_map *m; + for (m = g_property_map; m->name != NULL; m++) { + if (strcmp(m->name, name) == 0) + return m->id; + } + return 0; } static void gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display) { - GstVaapiDisplayPrivate * const priv = display->priv; + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); gdouble ratio, delta; gint i, j, index, windex; @@ -472,7 +506,8 @@ gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display) static void gst_vaapi_display_destroy(GstVaapiDisplay *display) { - GstVaapiDisplayPrivate * const priv = display->priv; + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); if (priv->decoders) { g_array_free(priv->decoders, TRUE); @@ -505,13 +540,13 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) priv->display = NULL; } - if (priv->create_display) { + if (!priv->use_foreign_display) { GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); if (klass->close_display) klass->close_display(display); } - g_clear_object(&priv->parent); + gst_vaapi_display_replace_internal(&priv->parent, NULL); if (g_display_cache) { gst_vaapi_display_cache_remove(get_display_cache(), display); @@ -520,9 +555,13 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) } static gboolean -gst_vaapi_display_create(GstVaapiDisplay *display) +gst_vaapi_display_create(GstVaapiDisplay *display, + GstVaapiDisplayInitType init_type, gpointer init_value) { - GstVaapiDisplayPrivate * const priv = display->priv; + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); + const GstVaapiDisplayClass * const klass = + GST_VAAPI_DISPLAY_GET_CLASS(display); GstVaapiDisplayCache *cache; gboolean has_errors = TRUE; VADisplayAttribute *display_attrs = NULL; @@ -539,12 +578,21 @@ gst_vaapi_display_create(GstVaapiDisplay *display) info.display = display; info.display_type = priv->display_type; - if (priv->display) - info.va_display = priv->display; - else if (priv->create_display) { - GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); - if (klass->open_display && !klass->open_display(display)) + switch (init_type) { + case GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY: + info.va_display = init_value; + priv->display = init_value; + priv->use_foreign_display = TRUE; + break; + case GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME: + if (klass->open_display && !klass->open_display(display, init_value)) return FALSE; + goto create_display; + case GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY: + if (klass->bind_display && !klass->bind_display(display, init_value)) + return FALSE; + // fall-through + create_display: if (!klass->get_display || !klass->get_display(display, &info)) return FALSE; priv->display = info.va_display; @@ -554,6 +602,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) if (klass->get_size_mm) klass->get_size_mm(display, &priv->width_mm, &priv->height_mm); gst_vaapi_display_calculate_pixel_aspect_ratio(display); + break; } if (!priv->display) return FALSE; @@ -561,13 +610,11 @@ gst_vaapi_display_create(GstVaapiDisplay *display) cache = get_display_cache(); if (!cache) return FALSE; - cached_info = gst_vaapi_display_cache_lookup_by_va_display( - cache, - info.va_display - ); + cached_info = gst_vaapi_display_cache_lookup_by_va_display(cache, + info.va_display); if (cached_info) { - g_clear_object(&priv->parent); - priv->parent = g_object_ref(cached_info->display); + gst_vaapi_display_replace_internal(&priv->parent, + cached_info->display); priv->display_type = cached_info->display_type; } @@ -766,180 +813,69 @@ end: static void gst_vaapi_display_lock_default(GstVaapiDisplay *display) { - GstVaapiDisplayPrivate *priv = display->priv; + GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); if (priv->parent) - priv = priv->parent->priv; + priv = GST_VAAPI_DISPLAY_GET_PRIVATE(priv->parent); g_rec_mutex_lock(&priv->mutex); } static void gst_vaapi_display_unlock_default(GstVaapiDisplay *display) { - GstVaapiDisplayPrivate *priv = display->priv; + GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); if (priv->parent) - priv = priv->parent->priv; + priv = GST_VAAPI_DISPLAY_GET_PRIVATE(priv->parent); g_rec_mutex_unlock(&priv->mutex); } static void -gst_vaapi_display_finalize(GObject *object) +gst_vaapi_display_init(GstVaapiDisplay *display) { - GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); + const GstVaapiDisplayClass * const dpy_class = + GST_VAAPI_DISPLAY_GET_CLASS(display); + + priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; + priv->par_n = 1; + priv->par_d = 1; + + g_rec_mutex_init(&priv->mutex); + + if (dpy_class->init) + dpy_class->init(display); +} + +static void +gst_vaapi_display_finalize(GstVaapiDisplay *display) +{ + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); gst_vaapi_display_destroy(display); - - g_rec_mutex_clear(&display->priv->mutex); - - G_OBJECT_CLASS(gst_vaapi_display_parent_class)->finalize(object); + g_rec_mutex_clear(&priv->mutex); } -static void -gst_vaapi_display_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); - - switch (prop_id) { - case PROP_DISPLAY: - display->priv->display = g_value_get_pointer(value); - break; - case PROP_DISPLAY_TYPE: - display->priv->display_type = g_value_get_enum(value); - break; - case PROP_RENDER_MODE: - gst_vaapi_display_set_render_mode(display, g_value_get_enum(value)); - break; - case PROP_ROTATION: - gst_vaapi_display_set_rotation(display, g_value_get_enum(value)); - break; - case PROP_HUE: - case PROP_SATURATION: - case PROP_BRIGHTNESS: - case PROP_CONTRAST: - set_color_balance(display, prop_id, g_value_get_float(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_display_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_pointer(value, gst_vaapi_display_get_display(display)); - break; - case PROP_DISPLAY_TYPE: - g_value_set_enum(value, gst_vaapi_display_get_display_type(display)); - break; - case PROP_WIDTH: - g_value_set_uint(value, gst_vaapi_display_get_width(display)); - break; - case PROP_HEIGHT: - g_value_set_uint(value, gst_vaapi_display_get_height(display)); - break; - case PROP_RENDER_MODE: { - GstVaapiRenderMode mode; - if (!gst_vaapi_display_get_render_mode(display, &mode)) - mode = DEFAULT_RENDER_MODE; - g_value_set_enum(value, mode); - break; - } - case PROP_ROTATION: - g_value_set_enum(value, gst_vaapi_display_get_rotation(display)); - break; - case PROP_HUE: - case PROP_SATURATION: - case PROP_BRIGHTNESS: - case PROP_CONTRAST: { - gfloat v; - if (!get_color_balance(display, prop_id, &v)) - v = G_PARAM_SPEC_FLOAT(pspec)->default_value; - g_value_set_float(value, v); - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_display_constructed(GObject *object) -{ - GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); - GObjectClass *parent_class; - - display->priv->create_display = display->priv->display == NULL; - if (!gst_vaapi_display_create(display)) - gst_vaapi_display_destroy(display); - - parent_class = G_OBJECT_CLASS(gst_vaapi_display_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); -} - -static void +void gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); libgstvaapi_init_once(); - g_type_class_add_private(klass, sizeof(GstVaapiDisplayPrivate)); - - object_class->finalize = gst_vaapi_display_finalize; - object_class->set_property = gst_vaapi_display_set_property; - object_class->get_property = gst_vaapi_display_get_property; - object_class->constructed = gst_vaapi_display_constructed; - + object_class->size = sizeof(GstVaapiDisplay); + object_class->finalize = (GDestroyNotify)gst_vaapi_display_finalize; dpy_class->lock = gst_vaapi_display_lock_default; dpy_class->unlock = gst_vaapi_display_unlock_default; +} - g_properties[PROP_DISPLAY] = - g_param_spec_pointer("display", - "VA display", - "VA display", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - - g_properties[PROP_DISPLAY_TYPE] = - g_param_spec_enum("display-type", - "VA display type", - "VA display type", - GST_VAAPI_TYPE_DISPLAY_TYPE, - GST_VAAPI_DISPLAY_TYPE_ANY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - - g_properties[PROP_WIDTH] = - g_param_spec_uint("width", - "Width", - "The display width", - 1, G_MAXUINT32, 1, - G_PARAM_READABLE); - - g_properties[PROP_HEIGHT] = - g_param_spec_uint("height", - "height", - "The display height", - 1, G_MAXUINT32, 1, - G_PARAM_READABLE); - +static void +gst_vaapi_display_properties_init(void) +{ /** * GstVaapiDisplay:render-mode: * @@ -1017,33 +953,40 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) "The display contrast value", 0.0, 2.0, 1.0, G_PARAM_READWRITE); - - g_object_class_install_properties(object_class, N_PROPERTIES, g_properties); } -static void -gst_vaapi_display_init(GstVaapiDisplay *display) +static inline const GstVaapiDisplayClass * +gst_vaapi_display_class(void) { - GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); + static GstVaapiDisplayClass g_class; + static gsize g_class_init = FALSE; - display->priv = priv; - priv->parent = NULL; - priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; - priv->display = NULL; - priv->width = 0; - priv->height = 0; - priv->width_mm = 0; - priv->height_mm = 0; - priv->par_n = 1; - priv->par_d = 1; - priv->decoders = NULL; - priv->encoders = NULL; - priv->image_formats = NULL; - priv->subpicture_formats = NULL; - priv->properties = NULL; - priv->create_display = TRUE; + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_display_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return &g_class; +} - g_rec_mutex_init(&priv->mutex); +GstVaapiDisplay * +gst_vaapi_display_new(const GstVaapiDisplayClass *klass, + GstVaapiDisplayInitType init_type, gpointer init_value) +{ + GstVaapiDisplay *display; + + display = (GstVaapiDisplay *) + gst_vaapi_mini_object_new0(GST_VAAPI_MINI_OBJECT_CLASS(klass)); + if (!display) + return NULL; + + gst_vaapi_display_init(display); + if (!gst_vaapi_display_create(display, init_type, init_value)) + goto error; + return display; + +error: + gst_vaapi_display_unref_internal(display); + return NULL; } /** @@ -1066,11 +1009,53 @@ gst_vaapi_display_new_with_display(VADisplay va_display) info = gst_vaapi_display_cache_lookup_by_va_display(cache, va_display); if (info) - return g_object_ref(info->display); + return gst_vaapi_display_ref_internal(info->display); - return g_object_new(GST_VAAPI_TYPE_DISPLAY, - "display", va_display, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_class(), + GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, va_display); +} + +/** + * gst_vaapi_display_ref: + * @display: a #GstVaapiDisplay + * + * Atomically increases the reference count of the given @display by one. + * + * Returns: The same @display argument + */ +GstVaapiDisplay * +gst_vaapi_display_ref(GstVaapiDisplay *display) +{ + return gst_vaapi_display_ref_internal(display); +} + +/** + * gst_vaapi_display_unref: + * @display: a #GstVaapiDisplay + * + * Atomically decreases the reference count of the @display by one. If + * the reference count reaches zero, the display will be free'd. + */ +void +gst_vaapi_display_unref(GstVaapiDisplay *display) +{ + gst_vaapi_display_unref_internal(display); +} + +/** + * gst_vaapi_display_replace: + * @old_display_ptr: a pointer to a #GstVaapiDisplay + * @new_display: a #GstVaapiDisplay + * + * Atomically replaces the display display held in @old_display_ptr + * with @new_display. This means that @old_display_ptr shall reference + * a valid display. However, @new_display can be NULL. + */ +void +gst_vaapi_display_replace(GstVaapiDisplay **old_display_ptr, + GstVaapiDisplay *new_display) +{ + gst_vaapi_display_replace_internal(old_display_ptr, new_display); } /** @@ -1173,7 +1158,7 @@ gst_vaapi_display_get_display_type(GstVaapiDisplay *display) g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), GST_VAAPI_DISPLAY_TYPE_ANY); - return display->priv->display_type; + return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->display_type; } /** @@ -1189,7 +1174,7 @@ gst_vaapi_display_get_display(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return display->priv->display; + return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->display; } /** @@ -1205,7 +1190,7 @@ gst_vaapi_display_get_width(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), 0); - return display->priv->width; + return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->width; } /** @@ -1221,7 +1206,7 @@ gst_vaapi_display_get_height(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), 0); - return display->priv->height; + return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->height; } /** @@ -1238,10 +1223,10 @@ gst_vaapi_display_get_size(GstVaapiDisplay *display, guint *pwidth, guint *pheig g_return_if_fail(GST_VAAPI_DISPLAY(display)); if (pwidth) - *pwidth = display->priv->width; + *pwidth = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->width; if (pheight) - *pheight = display->priv->height; + *pheight = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->height; } /** @@ -1262,10 +1247,10 @@ gst_vaapi_display_get_pixel_aspect_ratio( g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); if (par_n) - *par_n = display->priv->par_n; + *par_n = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->par_n; if (par_d) - *par_d = display->priv->par_d; + *par_d = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->par_d; } /** @@ -1281,7 +1266,7 @@ gst_vaapi_display_get_decode_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return get_profile_caps(display->priv->decoders); + return get_profile_caps(GST_VAAPI_DISPLAY_GET_PRIVATE(display)->decoders); } /** @@ -1304,7 +1289,8 @@ gst_vaapi_display_has_decoder( { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); - return find_config(display->priv->decoders, profile, entrypoint); + return find_config( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->decoders, profile, entrypoint); } /** @@ -1320,7 +1306,7 @@ gst_vaapi_display_get_encode_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return get_profile_caps(display->priv->encoders); + return get_profile_caps(GST_VAAPI_DISPLAY_GET_PRIVATE(display)->encoders); } /** @@ -1343,7 +1329,8 @@ gst_vaapi_display_has_encoder( { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); - return find_config(display->priv->encoders, profile, entrypoint); + return find_config( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->encoders, profile, entrypoint); } /** @@ -1367,7 +1354,8 @@ gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return get_format_caps(display->priv->image_formats); + return get_format_caps( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->image_formats); } /** @@ -1388,14 +1376,16 @@ gst_vaapi_display_has_image_format( g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); g_return_val_if_fail(format, FALSE); - if (find_format(display->priv->image_formats, format)) + if (find_format( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->image_formats, format)) return TRUE; /* XXX: try subpicture formats since some drivers could report a * set of VA image formats that is not a superset of the set of VA * subpicture formats */ - return find_format(display->priv->subpicture_formats, format); + return find_format( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->subpicture_formats, format); } /** @@ -1416,7 +1406,8 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return get_format_caps(display->priv->subpicture_formats); + return get_format_caps( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->subpicture_formats); } /** @@ -1442,7 +1433,8 @@ gst_vaapi_display_has_subpicture_format( g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); g_return_val_if_fail(format, FALSE); - fip = find_format_info(display->priv->subpicture_formats, format); + fip = find_format_info( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->subpicture_formats, format); if (!fip) return FALSE; @@ -1469,18 +1461,118 @@ gst_vaapi_display_has_property(GstVaapiDisplay *display, const gchar *name) g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); g_return_val_if_fail(name, FALSE); - return find_property(display->priv->properties, name) != NULL; + return find_property( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->properties, name) != NULL; +} + +gboolean +gst_vaapi_display_get_property(GstVaapiDisplay *display, const gchar *name, + GValue *out_value) +{ + const GstVaapiProperty *prop; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(name != NULL, FALSE); + g_return_val_if_fail(out_value != NULL, FALSE); + + prop = find_property( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->properties, name); + if (!prop) + return FALSE; + + switch (prop->attribute.type) { + case VADisplayAttribRenderMode: { + GstVaapiRenderMode mode; + if (!gst_vaapi_display_get_render_mode(display, &mode)) + return FALSE; + g_value_init(out_value, GST_VAAPI_TYPE_RENDER_MODE); + g_value_set_enum(out_value, mode); + break; + } + case VADisplayAttribRotation: { + GstVaapiRotation rotation; + rotation = gst_vaapi_display_get_rotation(display); + g_value_init(out_value, GST_VAAPI_TYPE_ROTATION); + g_value_set_enum(out_value, rotation); + break; + } + case VADisplayAttribHue: + case VADisplayAttribSaturation: + case VADisplayAttribBrightness: + case VADisplayAttribContrast: { + gfloat value; + if (!get_color_balance(display, find_property_id(name), &value)) + return FALSE; + g_value_init(out_value, G_TYPE_FLOAT); + g_value_set_float(out_value, value); + break; + } + default: + GST_WARNING("unsupported property '%s'", name); + return FALSE; + } + return TRUE; +} + +gboolean +gst_vaapi_display_set_property(GstVaapiDisplay *display, const gchar *name, + const GValue *value) +{ + const GstVaapiProperty *prop; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(name != NULL, FALSE); + g_return_val_if_fail(value != NULL, FALSE); + + prop = find_property( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->properties, name); + if (!prop) + return FALSE; + + switch (prop->attribute.type) { + case VADisplayAttribRenderMode: { + GstVaapiRenderMode mode; + if (!G_VALUE_HOLDS(value, GST_VAAPI_TYPE_RENDER_MODE)) + return FALSE; + mode = g_value_get_enum(value); + return gst_vaapi_display_set_render_mode(display, mode); + } + case VADisplayAttribRotation: { + GstVaapiRotation rotation; + if (!G_VALUE_HOLDS(value, GST_VAAPI_TYPE_ROTATION)) + return FALSE; + rotation = g_value_get_enum(value); + return gst_vaapi_display_set_rotation(display, rotation); + } + case VADisplayAttribHue: + case VADisplayAttribSaturation: + case VADisplayAttribBrightness: + case VADisplayAttribContrast: { + gfloat v; + if (!G_VALUE_HOLDS(value, G_TYPE_FLOAT)) + return FALSE; + v = g_value_get_float(value); + return set_color_balance(display, find_property_id(name), v); + } + default: + break; + } + + GST_WARNING("unsupported property '%s'", name); + return FALSE; } static gboolean get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value) { + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); VADisplayAttribute attr; VAStatus status; attr.type = type; attr.flags = VA_DISPLAY_ATTRIB_GETTABLE; - status = vaGetDisplayAttributes(display->priv->display, &attr, 1); + status = vaGetDisplayAttributes(priv->display, &attr, 1); if (!vaapi_check_status(status, "vaGetDisplayAttributes()")) return FALSE; *value = attr.value; @@ -1490,13 +1582,15 @@ get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value) static gboolean set_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint value) { + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); VADisplayAttribute attr; VAStatus status; attr.type = type; attr.value = value; attr.flags = VA_DISPLAY_ATTRIB_SETTABLE; - status = vaSetDisplayAttributes(display->priv->display, &attr, 1); + status = vaSetDisplayAttributes(priv->display, &attr, 1); if (!vaapi_check_status(status, "vaSetDisplayAttributes()")) return FALSE; return TRUE; @@ -1553,7 +1647,10 @@ get_render_mode_default( GstVaapiRenderMode *pmode ) { - switch (display->priv->display_type) { + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); + + switch (priv->display_type) { #if USE_WAYLAND case GST_VAAPI_DISPLAY_TYPE_WAYLAND: /* wl_buffer mapped from VA surface through vaGetSurfaceBufferWl() */ @@ -1647,8 +1744,6 @@ gst_vaapi_display_set_render_mode( return FALSE; if (!set_attribute(display, VADisplayAttribRenderMode, modes)) return FALSE; - - g_object_notify_by_pspec(G_OBJECT(display), g_properties[PROP_RENDER_MODE]); return TRUE; } @@ -1700,8 +1795,6 @@ gst_vaapi_display_set_rotation( value = from_GstVaapiRotation(rotation); if (!set_attribute(display, VADisplayAttribRotation, value)) return FALSE; - - g_object_notify_by_pspec(G_OBJECT(display), g_properties[PROP_ROTATION]); return TRUE; } @@ -1769,7 +1862,5 @@ set_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat v) (attr->value - attr->min_value)); if (!set_attribute(display, attr->type, value)) return FALSE; - - g_object_notify_by_pspec(G_OBJECT(display), g_properties[prop_id]); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 53809b62e9..c5f392e7b8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -31,34 +31,14 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DISPLAY \ - (gst_vaapi_display_get_type()) - -#define GST_VAAPI_DISPLAY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DISPLAY, \ - GstVaapiDisplay)) - -#define GST_VAAPI_DISPLAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DISPLAY, \ - GstVaapiDisplayClass)) +#define GST_VAAPI_DISPLAY(obj) \ + ((GstVaapiDisplay *)(obj)) #define GST_VAAPI_IS_DISPLAY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY)) - -#define GST_VAAPI_IS_DISPLAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY)) - -#define GST_VAAPI_DISPLAY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DISPLAY, \ - GstVaapiDisplayClass)) + ((obj) != NULL) typedef struct _GstVaapiDisplayInfo GstVaapiDisplayInfo; typedef struct _GstVaapiDisplay GstVaapiDisplay; -typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; -typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; /** * GstVaapiDisplayType: @@ -111,57 +91,19 @@ struct _GstVaapiDisplayInfo { #define GST_VAAPI_DISPLAY_PROP_BRIGHTNESS "brightness" #define GST_VAAPI_DISPLAY_PROP_CONTRAST "contrast" -/** - * GstVaapiDisplay: - * - * Base class for VA displays. - */ -struct _GstVaapiDisplay { - /*< private >*/ - GObject 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 - * - * Base class for VA displays. - */ -struct _GstVaapiDisplayClass { - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - gboolean (*open_display) (GstVaapiDisplay *display); - 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); -}; - -GType -gst_vaapi_display_get_type(void) G_GNUC_CONST; - GstVaapiDisplay * gst_vaapi_display_new_with_display(VADisplay va_display); +GstVaapiDisplay * +gst_vaapi_display_ref(GstVaapiDisplay *display); + +void +gst_vaapi_display_unref(GstVaapiDisplay *display); + +void +gst_vaapi_display_replace(GstVaapiDisplay **old_display_ptr, + GstVaapiDisplay *new_display); + void gst_vaapi_display_lock(GstVaapiDisplay *display); @@ -238,6 +180,14 @@ gst_vaapi_display_has_subpicture_format( gboolean gst_vaapi_display_has_property(GstVaapiDisplay *display, const gchar *name); +gboolean +gst_vaapi_display_get_property(GstVaapiDisplay *display, const gchar *name, + GValue *out_value); + +gboolean +gst_vaapi_display_set_property(GstVaapiDisplay *display, const gchar *name, + const GValue *value); + gboolean gst_vaapi_display_get_render_mode( GstVaapiDisplay *display, diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 8178c2c2fb..da6235c369 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -39,17 +39,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDisplayDRM, - gst_vaapi_display_drm, - GST_VAAPI_TYPE_DISPLAY) - -enum { - PROP_0, - - PROP_DEVICE_PATH, - PROP_DRM_DEVICE -}; - #define NAME_PREFIX "DRM:" #define NAME_PREFIX_LENGTH 4 @@ -74,18 +63,12 @@ compare_device_path(gconstpointer a, gconstpointer b, gpointer user_data) return strcmp(cached_name, tested_name) == 0; } -static void -gst_vaapi_display_drm_finalize(GObject *object) -{ - G_OBJECT_CLASS(gst_vaapi_display_drm_parent_class)->finalize(object); -} - /* Get default device path. Actually, the first match in the DRM subsystem */ static const gchar * -get_default_device_path(gpointer ptr) +get_default_device_path(GstVaapiDisplay *display) { - GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(ptr); - GstVaapiDisplayDRMPrivate * const priv = display->priv; + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); const gchar *syspath, *devpath; struct udev *udev = NULL; struct udev_device *device, *parent; @@ -137,10 +120,11 @@ get_default_device_path(gpointer ptr) /* Reconstruct a device path without our prefix */ static const gchar * -get_device_path(gpointer ptr) +get_device_path(GstVaapiDisplay *display) { - GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(ptr); - const gchar *device_path = display->priv->device_path; + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); + const gchar *device_path = priv->device_path; if (!device_path) return NULL; @@ -154,10 +138,11 @@ get_device_path(gpointer ptr) } /* Mangle device path with our prefix */ -static void -set_device_path(GstVaapiDisplayDRM *display, const gchar *device_path) +static gboolean +set_device_path(GstVaapiDisplay *display, const gchar *device_path) { - GstVaapiDisplayDRMPrivate * const priv = display->priv; + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); g_free(priv->device_path); priv->device_path = NULL; @@ -165,34 +150,37 @@ set_device_path(GstVaapiDisplayDRM *display, const gchar *device_path) if (!device_path) { device_path = get_default_device_path(display); if (!device_path) - return; + return FALSE; } priv->device_path = g_strdup_printf("%s%s", NAME_PREFIX, device_path); + return priv->device_path != NULL; } /* Set device path from file descriptor */ -static void -set_device_path_from_fd(GstVaapiDisplayDRM *display, gint drm_device) +static gboolean +set_device_path_from_fd(GstVaapiDisplay *display, gint drm_device) { - GstVaapiDisplayDRMPrivate * const priv = display->priv; + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); const gchar *busid, *path, *str; gsize busid_length, path_length; struct udev *udev = NULL; struct udev_device *device; struct udev_enumerate *e = NULL; struct udev_list_entry *l; + gboolean success = FALSE; g_free(priv->device_path); priv->device_path = NULL; if (drm_device < 0) - return; + goto end; busid = drmGetBusid(drm_device); if (!busid) - return; + goto end; if (strncmp(busid, "pci:", 4) != 0) - return; + goto end; busid += 4; busid_length = strlen(busid); @@ -227,109 +215,57 @@ set_device_path_from_fd(GstVaapiDisplayDRM *display, gint drm_device) udev_device_unref(device); break; } + success = TRUE; end: if (e) udev_enumerate_unref(e); if (udev) udev_unref(udev); -} - -static void -gst_vaapi_display_drm_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); - - switch (prop_id) { - case PROP_DEVICE_PATH: - set_device_path(display, g_value_get_string(value)); - break; - case PROP_DRM_DEVICE: - display->priv->drm_device = g_value_get_int(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_display_drm_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); - - switch (prop_id) { - case PROP_DEVICE_PATH: - g_value_set_string(value, get_device_path(display)); - break; - case PROP_DRM_DEVICE: - g_value_set_int(value, display->priv->drm_device); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_display_drm_constructed(GObject *object) -{ - GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); - GstVaapiDisplayDRMPrivate * const priv = display->priv; - GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache(); - const GstVaapiDisplayInfo *info; - GObjectClass *parent_class; - - priv->create_display = priv->drm_device < 0; - - /* Don't create DRM display if there is one in the cache already */ - if (priv->create_display) { - info = gst_vaapi_display_cache_lookup_by_name( - cache, - priv->device_path, - compare_device_path, NULL - ); - if (info) { - priv->drm_device = GPOINTER_TO_INT(info->native_display); - priv->create_display = FALSE; - } - } - - /* Reset device-path if the user provided his own DRM display */ - if (!priv->create_display) - set_device_path_from_fd(display, priv->drm_device); - - parent_class = G_OBJECT_CLASS(gst_vaapi_display_drm_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); + return success; } static gboolean -gst_vaapi_display_drm_open_display(GstVaapiDisplay *display) +gst_vaapi_display_drm_bind_display(GstVaapiDisplay *display, + gpointer native_display) { GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM(display)->priv; + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); - if (priv->create_display) { - const gchar *device_path = get_device_path(display); - if (!device_path) - return FALSE; - priv->drm_device = open(device_path, O_RDWR|O_CLOEXEC); + 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); + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *info; + + cache = gst_vaapi_display_get_cache(); + g_return_val_if_fail(cache != NULL, FALSE); + + if (!set_device_path(display, name)) + return FALSE; + + info = gst_vaapi_display_cache_lookup_by_name(cache, priv->device_path, + compare_device_path, NULL); + if (info) { + priv->drm_device = GPOINTER_TO_INT(info->native_display); + priv->use_foreign_display = TRUE; + } + else { + priv->drm_device = open(get_device_path(display), O_RDWR|O_CLOEXEC); if (priv->drm_device < 0) return FALSE; + priv->use_foreign_display = FALSE; } - if (priv->drm_device < 0) - return FALSE; return TRUE; } @@ -337,10 +273,10 @@ static void gst_vaapi_display_drm_close_display(GstVaapiDisplay *display) { GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM(display)->priv; + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); if (priv->drm_device >= 0) { - if (priv->create_display) + if (!priv->use_foreign_display) close(priv->drm_device); priv->drm_device = -1; } @@ -357,13 +293,11 @@ gst_vaapi_display_drm_close_display(GstVaapiDisplay *display) } static gboolean -gst_vaapi_display_drm_get_display_info( - GstVaapiDisplay *display, - GstVaapiDisplayInfo *info -) +gst_vaapi_display_drm_get_display_info(GstVaapiDisplay *display, + GstVaapiDisplayInfo *info) { GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM(display)->priv; + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); GstVaapiDisplayCache *cache; const GstVaapiDisplayInfo *cached_info; @@ -391,62 +325,42 @@ gst_vaapi_display_drm_get_display_info( } static void -gst_vaapi_display_drm_class_init(GstVaapiDisplayDRMClass *klass) +gst_vaapi_display_drm_init(GstVaapiDisplay *display) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); - g_type_class_add_private(klass, sizeof(GstVaapiDisplayDRMPrivate)); - - object_class->finalize = gst_vaapi_display_drm_finalize; - object_class->set_property = gst_vaapi_display_drm_set_property; - object_class->get_property = gst_vaapi_display_drm_get_property; - object_class->constructed = gst_vaapi_display_drm_constructed; - - 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; - - /** - * GstVaapiDisplayDRM:drm-device: - * - * The DRM device (file descriptor). - */ - g_object_class_install_property - (object_class, - PROP_DRM_DEVICE, - g_param_spec_int("drm-device", - "DRM device", - "DRM device", - -1, G_MAXINT32, -1, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiDisplayDRM:device-path: - * - * The DRM device path. - */ - g_object_class_install_property - (object_class, - PROP_DEVICE_PATH, - g_param_spec_string("device-path", - "DRM device path", - "DRM device path", - NULL, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + priv->drm_device = -1; } static void -gst_vaapi_display_drm_init(GstVaapiDisplayDRM *display) +gst_vaapi_display_drm_class_init(GstVaapiDisplayDRMClass *klass) { - GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM_GET_PRIVATE(display); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); + GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); - display->priv = priv; - priv->device_path_default = NULL; - priv->device_path = NULL; - priv->drm_device = -1; - priv->create_display = TRUE; + gst_vaapi_display_class_init(&klass->parent_class); + + object_class->size = sizeof(GstVaapiDisplayDRM); + dpy_class->init = gst_vaapi_display_drm_init; + 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; +} + +static inline const GstVaapiDisplayClass * +gst_vaapi_display_drm_class(void) +{ + static GstVaapiDisplayDRMClass g_class; + static gsize g_class_init = FALSE; + + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_display_drm_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS(&g_class); } /** @@ -466,9 +380,8 @@ gst_vaapi_display_drm_init(GstVaapiDisplayDRM *display) GstVaapiDisplay * gst_vaapi_display_drm_new(const gchar *device_path) { - return g_object_new(GST_VAAPI_TYPE_DISPLAY_DRM, - "device-path", device_path, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_drm_class(), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)device_path); } /** @@ -487,9 +400,8 @@ gst_vaapi_display_drm_new_with_device(gint device) { g_return_val_if_fail(device >= 0, NULL); - return g_object_new(GST_VAAPI_TYPE_DISPLAY_DRM, - "drm-device", device, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_drm_class(), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, GINT_TO_POINTER(device)); } /** @@ -507,7 +419,7 @@ gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), -1); - return display->priv->drm_device; + return GST_VAAPI_DISPLAY_DRM_DEVICE(display); } /** @@ -528,5 +440,5 @@ gst_vaapi_display_drm_get_device_path(GstVaapiDisplayDRM *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), NULL); - return display->priv->device_path; + return get_device_path(GST_VAAPI_DISPLAY_CAST(display)); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h index fad0d530c1..a0b10428d0 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h @@ -26,59 +26,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DISPLAY_DRM \ - (gst_vaapi_display_drm_get_type()) - -#define GST_VAAPI_DISPLAY_DRM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DISPLAY_DRM, \ - GstVaapiDisplayDRM)) - -#define GST_VAAPI_DISPLAY_DRM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DISPLAY_DRM, \ - GstVaapiDisplayDRMClass)) +#define GST_VAAPI_DISPLAY_DRM(obj) \ + ((GstVaapiDisplayDRM *)(obj)) #define GST_VAAPI_IS_DISPLAY_DRM(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_DRM)) - -#define GST_VAAPI_IS_DISPLAY_DRM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_DRM)) - -#define GST_VAAPI_DISPLAY_DRM_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DISPLAY_DRM, \ - GstVaapiDisplayDRMClass)) + ((obj) != NULL) typedef struct _GstVaapiDisplayDRM GstVaapiDisplayDRM; -typedef struct _GstVaapiDisplayDRMPrivate GstVaapiDisplayDRMPrivate; -typedef struct _GstVaapiDisplayDRMClass GstVaapiDisplayDRMClass; - -/** - * 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; -}; - -GType -gst_vaapi_display_drm_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_display_drm_new(const gchar *device_path); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h index f6211a73ad..3b8df8ceb9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h @@ -26,12 +26,14 @@ G_BEGIN_DECLS -#define GST_VAAPI_DISPLAY_DRM_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DISPLAY_DRM, \ - GstVaapiDisplayDRMPrivate)) +#define GST_VAAPI_DISPLAY_DRM_CAST(display) \ + ((GstVaapiDisplayDRM *)(display)) -#define GST_VAAPI_DISPLAY_DRM_CAST(display) ((GstVaapiDisplayDRM *)(display)) +#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: @@ -41,13 +43,35 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DISPLAY_DRM_DEVICE #define GST_VAAPI_DISPLAY_DRM_DEVICE(display) \ - GST_VAAPI_DISPLAY_DRM_CAST(display)->priv->drm_device + GST_VAAPI_DISPLAY_DRM_PRIVATE(display)->drm_device struct _GstVaapiDisplayDRMPrivate { - gchar *device_path_default; - gchar *device_path; - gint drm_device; - guint create_display : 1; + 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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 10077ee1ce..0810239602 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -37,45 +37,47 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDisplayGLX, - gst_vaapi_display_glx, - GST_VAAPI_TYPE_DISPLAY_X11) - -static void -gst_vaapi_display_glx_finalize(GObject *object) -{ - G_OBJECT_CLASS(gst_vaapi_display_glx_parent_class)->finalize(object); -} - static gboolean gst_vaapi_display_glx_get_display_info( GstVaapiDisplay *display, GstVaapiDisplayInfo *info ) { - GstVaapiDisplayClass * const dpy_class = - GST_VAAPI_DISPLAY_CLASS(gst_vaapi_display_glx_parent_class); + const GstVaapiDisplayGLXClass * const klass = + GST_VAAPI_DISPLAY_GLX_GET_CLASS(display); info->va_display = vaGetDisplayGLX(GST_VAAPI_DISPLAY_XDISPLAY(display)); if (!info->va_display) return FALSE; info->display_type = GST_VAAPI_DISPLAY_TYPE_GLX; - return dpy_class->get_display(display, info); + return klass->parent_get_display(display, info); } static void gst_vaapi_display_glx_class_init(GstVaapiDisplayGLXClass *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); - object_class->finalize = gst_vaapi_display_glx_finalize; + gst_vaapi_display_x11_class_init(&klass->parent_class); + + object_class->size = sizeof(GstVaapiDisplayGLX); + klass->parent_get_display = dpy_class->get_display; dpy_class->get_display = gst_vaapi_display_glx_get_display_info; } -static void -gst_vaapi_display_glx_init(GstVaapiDisplayGLX *display) +static inline const GstVaapiDisplayClass * +gst_vaapi_display_glx_class(void) { + static GstVaapiDisplayGLXClass g_class; + static gsize g_class_init = FALSE; + + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_display_glx_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS(&g_class); } /** @@ -91,9 +93,8 @@ gst_vaapi_display_glx_init(GstVaapiDisplayGLX *display) GstVaapiDisplay * gst_vaapi_display_glx_new(const gchar *display_name) { - return g_object_new(GST_VAAPI_TYPE_DISPLAY_GLX, - "display-name", display_name, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_glx_class(), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name); } /** @@ -110,7 +111,8 @@ gst_vaapi_display_glx_new(const gchar *display_name) GstVaapiDisplay * gst_vaapi_display_glx_new_with_display(Display *x11_display) { - return g_object_new(GST_VAAPI_TYPE_DISPLAY_GLX, - "x11-display", x11_display, - NULL); + g_return_val_if_fail(x11_display != NULL, NULL); + + return gst_vaapi_display_new(gst_vaapi_display_glx_class(), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index 057baf78db..cf318f5e94 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -29,56 +29,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DISPLAY_GLX \ - (gst_vaapi_display_glx_get_type()) - -#define GST_VAAPI_DISPLAY_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DISPLAY_GLX, \ - GstVaapiDisplayGLX)) - -#define GST_VAAPI_DISPLAY_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DISPLAY_GLX, \ - GstVaapiDisplayGLXClass)) +#define GST_VAAPI_DISPLAY_GLX(obj) \ + ((GstVaapiDisplayGLX *)(obj)) #define GST_VAAPI_IS_DISPLAY_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_GLX)) - -#define GST_VAAPI_IS_DISPLAY_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_GLX)) - -#define GST_VAAPI_DISPLAY_GLX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DISPLAY_GLX, \ - GstVaapiDisplayGLXClass)) + ((obj) != NULL) typedef struct _GstVaapiDisplayGLX GstVaapiDisplayGLX; -typedef struct _GstVaapiDisplayGLXClass GstVaapiDisplayGLXClass; - -/** - * GstVaapiDisplayGLX: - * - * VA/GLX display wrapper. - */ -struct _GstVaapiDisplayGLX { - /*< private >*/ - GstVaapiDisplayX11 parent_instance; -}; - - -/** - * GstVaapiDisplayGLXClass: - * - * VA/GLX display wrapper clas. - */ -struct _GstVaapiDisplayGLXClass { - /*< private >*/ - GstVaapiDisplayX11Class parent_class; -}; - -GType -gst_vaapi_display_glx_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_display_glx_new(const gchar *display_name); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index a843b38407..72e44d4795 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -24,10 +24,42 @@ #include #include +#include "gstvaapidisplay_x11_priv.h" G_BEGIN_DECLS -#define GST_VAAPI_DISPLAY_GLX_CAST(display) ((GstVaapiDisplayGLX *)(display)) +#define GST_VAAPI_DISPLAY_GLX_CAST(display) \ + ((GstVaapiDisplayGLX *)(display)) + +#define GST_VAAPI_DISPLAY_GLX_CLASS(klass) \ + ((GstVaapiDisplayGLXClass *)(klass)) + +#define GST_VAAPI_DISPLAY_GLX_GET_CLASS(obj) \ + GST_VAAPI_DISPLAY_GLX_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + +typedef struct _GstVaapiDisplayGLXClass GstVaapiDisplayGLXClass; + +/** + * GstVaapiDisplayGLX: + * + * VA/GLX display wrapper. + */ +struct _GstVaapiDisplayGLX { + /*< private >*/ + GstVaapiDisplayX11 parent_instance; +}; + +/** + * GstVaapiDisplayGLXClass: + * + * VA/GLX display wrapper clas. + */ +struct _GstVaapiDisplayGLXClass { + /*< private >*/ + GstVaapiDisplayX11Class parent_class; + + GstVaapiDisplayGetInfoFunc parent_get_display; +}; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index cb5302b063..24bf751793 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -25,15 +25,45 @@ #include #include +#include "gstvaapiminiobject.h" G_BEGIN_DECLS -#define GST_VAAPI_DISPLAY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DISPLAY, \ - GstVaapiDisplayPrivate)) +#define GST_VAAPI_DISPLAY_CAST(display) \ + ((GstVaapiDisplay *)(display)) -#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) \ + ((GstVaapiDisplayClass *)(klass)) + +#define GST_VAAPI_IS_DISPLAY_CLASS(klass) \ + ((klass) != NULL) + +#define GST_VAAPI_DISPLAY_GET_CLASS(obj) \ + GST_VAAPI_DISPLAY_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + +typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; +typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; +typedef enum _GstVaapiDisplayInitType GstVaapiDisplayInitType; + +typedef void (*GstVaapiDisplayInitFunc) (GstVaapiDisplay *display); +typedef gboolean (*GstVaapiDisplayBindFunc) (GstVaapiDisplay *display, + gpointer native_dpy); +typedef gboolean (*GstVaapiDisplayOpenFunc) (GstVaapiDisplay *display, + const gchar *name); +typedef void (*GstVaapiDisplayCloseFunc) (GstVaapiDisplay *display); +typedef void (*GstVaapiDisplayLockFunc) (GstVaapiDisplay *display); +typedef void (*GstVaapiDisplayUnlockFunc) (GstVaapiDisplay *display); +typedef void (*GstVaapiDisplaySyncFunc) (GstVaapiDisplay *display); +typedef void (*GstVaapiDisplayFlushFunc) (GstVaapiDisplay *display); +typedef gboolean (*GstVaapiDisplayGetInfoFunc) (GstVaapiDisplay *display, + GstVaapiDisplayInfo *info); +typedef void (*GstVaapiDisplayGetSizeFunc) (GstVaapiDisplay *display, + guint *pwidth, guint *pheight); +typedef void (*GstVaapiDisplayGetSizeMFunc)(GstVaapiDisplay *display, + guint *pwidth, guint *pheight); /** * GST_VAAPI_DISPLAY_VADISPLAY: @@ -44,7 +74,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DISPLAY_VADISPLAY #define GST_VAAPI_DISPLAY_VADISPLAY(display_) \ - GST_VAAPI_DISPLAY_CAST(display_)->priv->display + GST_VAAPI_DISPLAY_GET_PRIVATE(display_)->display /** * GST_VAAPI_DISPLAY_LOCK: @@ -66,11 +96,6 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_UNLOCK(display) \ gst_vaapi_display_unlock(GST_VAAPI_DISPLAY_CAST(display)) -/** - * GstVaapiDisplayPrivate: - * - * Base class for VA displays. - */ struct _GstVaapiDisplayPrivate { GstVaapiDisplay *parent; GRecMutex mutex; @@ -87,12 +112,95 @@ struct _GstVaapiDisplayPrivate { GArray *image_formats; GArray *subpicture_formats; GArray *properties; - guint create_display : 1; + guint use_foreign_display : 1; }; +/** + * GstVaapiDisplay: + * + * Base class for VA displays. + */ +struct _GstVaapiDisplay { + /*< private >*/ + GstVaapiMiniObject 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 + * + * Base class for VA displays. + */ +struct _GstVaapiDisplayClass { + /*< private >*/ + GstVaapiMiniObjectClass parent_class; + + /*< public >*/ + GstVaapiDisplayInitFunc init; + GstVaapiDisplayBindFunc bind_display; + GstVaapiDisplayOpenFunc open_display; + GstVaapiDisplayCloseFunc close_display; + GstVaapiDisplayLockFunc lock; + GstVaapiDisplayUnlockFunc unlock; + GstVaapiDisplaySyncFunc sync; + GstVaapiDisplayFlushFunc flush; + GstVaapiDisplayGetInfoFunc get_display; + GstVaapiDisplayGetSizeFunc get_size; + GstVaapiDisplayGetSizeMFunc get_size_mm; +}; + +/* 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 +}; + +void +gst_vaapi_display_class_init(GstVaapiDisplayClass *klass); + +GstVaapiDisplay * +gst_vaapi_display_new(const GstVaapiDisplayClass *klass, + GstVaapiDisplayInitType init_type, gpointer init_value); + GstVaapiDisplayCache * gst_vaapi_display_get_cache(void); +/* Inline reference counting for core libgstvaapi library */ +#ifdef GST_VAAPI_CORE +#define gst_vaapi_display_ref_internal(display) \ + ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(display))) + +#define gst_vaapi_display_unref_internal(display) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(display)) + +#define gst_vaapi_display_replace_internal(old_display_ptr, new_display) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_display_ptr), \ + GST_VAAPI_MINI_OBJECT(new_display)) + +#undef gst_vaapi_display_ref +#define gst_vaapi_display_ref(display) \ + gst_vaapi_display_ref_internal((display)) + +#undef gst_vaapi_display_unref +#define gst_vaapi_display_unref(display) \ + gst_vaapi_display_unref_internal((display)) + +#undef gst_vaapi_display_replace +#define gst_vaapi_display_replace(old_display_ptr, new_display) \ + gst_vaapi_display_replace_internal((old_display_ptr), (new_display)) +#endif + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 3d162b15e7..08e8cf844d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -33,17 +33,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDisplayWayland, - gst_vaapi_display_wayland, - GST_VAAPI_TYPE_DISPLAY) - -enum { - PROP_0, - - PROP_DISPLAY_NAME, - PROP_WL_DISPLAY -}; - #define NAME_PREFIX "WLD:" #define NAME_PREFIX_LENGTH 4 @@ -98,18 +87,13 @@ compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data) return TRUE; } -static void -gst_vaapi_display_wayland_finalize(GObject *object) -{ - G_OBJECT_CLASS(gst_vaapi_display_wayland_parent_class)->finalize(object); -} - /* Reconstruct a display name without our prefix */ static const gchar * -get_display_name(gpointer ptr) +get_display_name(GstVaapiDisplayWayland *display) { - GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(ptr); - const gchar *display_name = display->priv->display_name; + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + const gchar *display_name = priv->display_name; if (!display_name) return NULL; @@ -127,10 +111,11 @@ get_display_name(gpointer ptr) } /* Mangle display name with our prefix */ -static void -set_display_name(GstVaapiDisplayWayland *display, const gchar *display_name) +static gboolean +set_display_name(GstVaapiDisplay *display, const gchar *display_name) { - GstVaapiDisplayWaylandPrivate * const priv = display->priv; + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); g_free(priv->display_name); @@ -140,87 +125,7 @@ set_display_name(GstVaapiDisplayWayland *display, const gchar *display_name) display_name = ""; } priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, display_name); -} - -static void -gst_vaapi_display_wayland_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(object); - - switch (prop_id) { - case PROP_DISPLAY_NAME: - set_display_name(display, g_value_get_string(value)); - break; - case PROP_WL_DISPLAY: - display->priv->wl_display = g_value_get_pointer(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} -static void -gst_vaapi_display_wayland_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(object); - - switch (prop_id) { - case PROP_DISPLAY_NAME: - g_value_set_string(value, get_display_name(display)); - break; - case PROP_WL_DISPLAY: - g_value_set_pointer(value, gst_vaapi_display_wayland_get_display(display)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_display_wayland_constructed(GObject *object) -{ - GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(object); - GstVaapiDisplayWaylandPrivate * const priv = display->priv; - GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache(); - const GstVaapiDisplayInfo *info; - GObjectClass *parent_class; - - priv->create_display = priv->wl_display == NULL; - - /* Don't create Wayland display if there is one in the cache already */ - if (priv->create_display) { - info = gst_vaapi_display_cache_lookup_by_name( - cache, - priv->display_name, - compare_display_name, NULL - ); - if (info) { - priv->wl_display = info->native_display; - priv->create_display = FALSE; - } - } - - /* Reset display-name if the user provided his own Wayland display */ - if (!priv->create_display) { - /* XXX: how to get socket/display name? */ - GST_WARNING("wayland: get display name"); - set_display_name(display, NULL); - } - - parent_class = G_OBJECT_CLASS(gst_vaapi_display_wayland_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); + return priv->display_name != NULL; } static void @@ -280,16 +185,10 @@ static const struct wl_registry_listener registry_listener = { }; static gboolean -gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display) +gst_vaapi_display_wayland_setup(GstVaapiDisplay *display) { GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND(display)->priv; - - if (priv->create_display) { - priv->wl_display = wl_display_connect(get_display_name(display)); - if (!priv->wl_display) - return FALSE; - } + 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); @@ -317,11 +216,58 @@ gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display) 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); + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *info; + + cache = gst_vaapi_display_get_cache(); + g_return_val_if_fail(cache != NULL, FALSE); + + if (!set_display_name(display, name)) + return FALSE; + + info = gst_vaapi_display_cache_lookup_by_name(cache, priv->display_name, + compare_display_name, NULL); + if (info) { + priv->wl_display = info->native_display; + priv->use_foreign_display = TRUE; + } + else { + 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(display)->priv; + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); if (priv->compositor) { wl_compositor_destroy(priv->compositor); @@ -329,7 +275,7 @@ gst_vaapi_display_wayland_close_display(GstVaapiDisplay * display) } if (priv->wl_display) { - if (priv->create_display) + if (!priv->use_foreign_display) wl_display_disconnect(priv->wl_display); priv->wl_display = NULL; } @@ -347,7 +293,7 @@ gst_vaapi_display_wayland_get_display_info( ) { GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND(display)->priv; + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); GstVaapiDisplayCache *cache; const GstVaapiDisplayInfo *cached_info; @@ -355,8 +301,8 @@ gst_vaapi_display_wayland_get_display_info( cache = gst_vaapi_display_get_cache(); if (!cache) return FALSE; - cached_info = - gst_vaapi_display_cache_lookup_by_native_display(cache, priv->wl_display); + cached_info = gst_vaapi_display_cache_lookup_by_native_display(cache, + priv->wl_display); if (cached_info) { *info = *cached_info; return TRUE; @@ -382,7 +328,7 @@ gst_vaapi_display_wayland_get_size( ) { GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND(display)->priv; + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); if (!priv->output) return; @@ -402,7 +348,7 @@ gst_vaapi_display_wayland_get_size_mm( ) { GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND(display)->priv; + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); if (!priv->output) return; @@ -414,73 +360,45 @@ gst_vaapi_display_wayland_get_size_mm( *pheight = priv->phys_height; } +static void +gst_vaapi_display_wayland_init(GstVaapiDisplay *display) +{ + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + + priv->event_fd = -1; +} + static void gst_vaapi_display_wayland_class_init(GstVaapiDisplayWaylandClass * klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiDisplayWaylandPrivate)); - - object_class->finalize = gst_vaapi_display_wayland_finalize; - object_class->set_property = gst_vaapi_display_wayland_set_property; - object_class->get_property = gst_vaapi_display_wayland_get_property; - object_class->constructed = gst_vaapi_display_wayland_constructed; + gst_vaapi_display_class_init(&klass->parent_class); + object_class->size = sizeof(GstVaapiDisplayWayland); + dpy_class->init = gst_vaapi_display_wayland_init; + 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; - - /** - * GstVaapiDisplayWayland:wayland-display: - * - * The Wayland #wl_display that was created by - * gst_vaapi_display_wayland_new() or that was bound from - * gst_vaapi_display_wayland_new_with_display(). - */ - g_object_class_install_property - (object_class, - PROP_WL_DISPLAY, - g_param_spec_pointer("wl-display", - "Wayland display", - "Wayland display", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiDisplayWayland:display-name: - * - * The Wayland display name. - */ - g_object_class_install_property - (object_class, - PROP_DISPLAY_NAME, - g_param_spec_string("display-name", - "Wayland display name", - "Wayland display name", - NULL, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } -static void -gst_vaapi_display_wayland_init(GstVaapiDisplayWayland *display) +static inline const GstVaapiDisplayClass * +gst_vaapi_display_wayland_class(void) { - GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + static GstVaapiDisplayWaylandClass g_class; + static gsize g_class_init = FALSE; - display->priv = priv; - priv->create_display = TRUE; - priv->display_name = NULL; - priv->wl_display = NULL; - priv->compositor = NULL; - priv->shell = NULL; - priv->output = NULL; - priv->width = 0; - priv->height = 0; - priv->phys_width = 0; - priv->phys_height = 0; - priv->event_fd = -1; + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_display_wayland_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS(&g_class); } /** @@ -496,9 +414,8 @@ gst_vaapi_display_wayland_init(GstVaapiDisplayWayland *display) GstVaapiDisplay * gst_vaapi_display_wayland_new(const gchar *display_name) { - return g_object_new(GST_VAAPI_TYPE_DISPLAY_WAYLAND, - "display-name", display_name, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_wayland_class(), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name); } /** @@ -517,9 +434,8 @@ gst_vaapi_display_wayland_new_with_display(struct wl_display *wl_display) { g_return_val_if_fail(wl_display, NULL); - return g_object_new(GST_VAAPI_TYPE_DISPLAY_WAYLAND, - "wl-display", wl_display, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_wayland_class(), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, wl_display); } /** @@ -537,5 +453,5 @@ gst_vaapi_display_wayland_get_display(GstVaapiDisplayWayland *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_WAYLAND(display), NULL); - return display->priv->wl_display; + return GST_VAAPI_DISPLAY_WL_DISPLAY(display); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h index c5fc0f635c..3f1772888c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h @@ -27,58 +27,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DISPLAY_WAYLAND \ - (gst_vaapi_display_wayland_get_type()) - -#define GST_VAAPI_DISPLAY_WAYLAND(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ - GstVaapiDisplayWayland)) - -#define GST_VAAPI_DISPLAY_WAYLAND_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ - GstVaapiDisplayWaylandClass)) +#define GST_VAAPI_DISPLAY_WAYLAND(obj) \ + ((GstVaapiDisplayWayland *)(obj)) #define GST_VAAPI_IS_DISPLAY_WAYLAND(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_WAYLAND)) - -#define GST_VAAPI_IS_DISPLAY_WAYLAND_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_WAYLAND)) - -#define GST_VAAPI_DISPLAY_WAYLAND_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ - GstVaapiDisplayWaylandClass)) + ((obj) != NULL) typedef struct _GstVaapiDisplayWayland GstVaapiDisplayWayland; -typedef struct _GstVaapiDisplayWaylandPrivate GstVaapiDisplayWaylandPrivate; -typedef struct _GstVaapiDisplayWaylandClass GstVaapiDisplayWaylandClass; - -/** - * 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; -}; - -GType -gst_vaapi_display_wayland_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_display_wayland_new(const gchar *display_name); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index 1fff458604..3c09c5fe16 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -23,17 +23,19 @@ #define GST_VAAPI_DISPLAY_WAYLAND_PRIV_H #include +#include "gstvaapidisplay_priv.h" G_BEGIN_DECLS -#define GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ - GstVaapiDisplayWaylandPrivate)) - #define GST_VAAPI_DISPLAY_WAYLAND_CAST(display) \ ((GstVaapiDisplayWayland *)(display)) +#define GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display) \ + (&GST_VAAPI_DISPLAY_WAYLAND_CAST(display)->priv) + +typedef struct _GstVaapiDisplayWaylandPrivate GstVaapiDisplayWaylandPrivate; +typedef struct _GstVaapiDisplayWaylandClass GstVaapiDisplayWaylandClass; + /** * GST_VAAPI_DISPLAY_WL_DISPLAY: * @display: a #GstVaapiDisplay @@ -43,7 +45,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DISPLAY_WL_DISPLAY #define GST_VAAPI_DISPLAY_WL_DISPLAY(display) \ - GST_VAAPI_DISPLAY_WAYLAND_CAST(display)->priv->wl_display + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display)->wl_display struct _GstVaapiDisplayWaylandPrivate { gchar *display_name; @@ -57,7 +59,29 @@ struct _GstVaapiDisplayWaylandPrivate { guint phys_width; guint phys_height; gint event_fd; - guint create_display : 1; + 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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index d632e48711..970b255888 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -39,19 +39,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDisplayX11, - gst_vaapi_display_x11, - GST_VAAPI_TYPE_DISPLAY) - -enum { - PROP_0, - - PROP_SYNCHRONOUS, - PROP_DISPLAY_NAME, - PROP_X11_DISPLAY, - PROP_X11_SCREEN -}; - #define NAME_PREFIX "X11:" #define NAME_PREFIX_LENGTH 4 @@ -105,18 +92,12 @@ compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data) return TRUE; } -static void -gst_vaapi_display_x11_finalize(GObject *object) -{ - G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class)->finalize(object); -} - /* Reconstruct a display name without our prefix */ static const gchar * -get_display_name(gpointer ptr) +get_display_name(GstVaapiDisplayX11 *display) { - GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(ptr); - const gchar *display_name = display->priv->display_name; + GstVaapiDisplayX11Private * const priv = &display->priv; + const gchar *display_name = priv->display_name; if (!display_name) return NULL; @@ -134,10 +115,10 @@ get_display_name(gpointer ptr) } /* Mangle display name with our prefix */ -static void +static gboolean set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name) { - GstVaapiDisplayX11Private * const priv = display->priv; + GstVaapiDisplayX11Private * const priv = &display->priv; g_free(priv->display_name); @@ -147,12 +128,14 @@ set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name) display_name = ""; } priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, 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; + GstVaapiDisplayX11Private * const priv = &display->priv; if (priv->synchronous != synchronous) { priv->synchronous = synchronous; @@ -161,122 +144,70 @@ set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous) } } +/* Check whether XRANDR extension is available */ static void -gst_vaapi_display_x11_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) +check_xrandr(GstVaapiDisplayX11 *display) { - GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); +#ifdef HAVE_XRANDR + GstVaapiDisplayX11Private * const priv = + GST_VAAPI_DISPLAY_X11_PRIVATE(display); + int evt_base, err_base; - switch (prop_id) { - case PROP_SYNCHRONOUS: - set_synchronous(display, g_value_get_boolean(value)); - break; - case PROP_DISPLAY_NAME: - set_display_name(display, g_value_get_string(value)); - break; - case PROP_X11_DISPLAY: - display->priv->x11_display = g_value_get_pointer(value); - break; - case PROP_X11_SCREEN: - display->priv->x11_screen = g_value_get_int(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_display_x11_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); - - switch (prop_id) { - case PROP_SYNCHRONOUS: - g_value_set_boolean(value, display->priv->synchronous); - break; - case PROP_DISPLAY_NAME: - g_value_set_string(value, get_display_name(display)); - break; - case PROP_X11_DISPLAY: - g_value_set_pointer(value, gst_vaapi_display_x11_get_display(display)); - break; - case PROP_X11_SCREEN: - g_value_set_int(value, gst_vaapi_display_x11_get_screen(display)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_display_x11_constructed(GObject *object) -{ - GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); - GstVaapiDisplayX11Private * const priv = display->priv; - GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache(); - const GstVaapiDisplayInfo *info; - GObjectClass *parent_class; - - priv->create_display = priv->x11_display == NULL; - - /* Don't create X11 display if there is one in the cache already */ - if (priv->create_display) { - info = gst_vaapi_display_cache_lookup_by_name( - cache, - priv->display_name, - compare_display_name, NULL - ); - if (info) { - priv->x11_display = info->native_display; - priv->create_display = FALSE; - } - } - - /* Reset display-name if the user provided his own X11 display */ - if (!priv->create_display) - set_display_name(display, XDisplayString(priv->x11_display)); - - parent_class = G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); + priv->use_xrandr = XRRQueryExtension(priv->x11_display, + &evt_base, &err_base); +#endif } static gboolean -gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) +gst_vaapi_display_x11_bind_display(GstVaapiDisplay *base_display, + gpointer native_display) { - GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GstVaapiDisplayX11 * const display = + GST_VAAPI_DISPLAY_X11_CAST(base_display); + GstVaapiDisplayX11Private * const priv = &display->priv; - if (priv->create_display) { + priv->x11_display = native_display; + priv->x11_screen = DefaultScreen(native_display); + priv->use_foreign_display = TRUE; + + check_xrandr(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; + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *info; + + cache = gst_vaapi_display_get_cache(); + g_return_val_if_fail(cache != NULL, FALSE); + + if (!set_display_name(display, name)) + return FALSE; + + info = gst_vaapi_display_cache_lookup_by_name(cache, priv->display_name, + compare_display_name, NULL); + if (info) { + priv->x11_display = info->native_display; + priv->use_foreign_display = TRUE; + } + else { priv->x11_display = XOpenDisplay(get_display_name(display)); if (!priv->x11_display) return FALSE; - priv->x11_screen = DefaultScreen(priv->x11_display); + priv->use_foreign_display = FALSE; } - if (!priv->x11_display) - return FALSE; + priv->x11_screen = DefaultScreen(priv->x11_display); - if (priv->synchronous) - XSynchronize(priv->x11_display, True); - -#ifdef HAVE_XRANDR - { - int evt_base, err_base; - priv->use_xrandr = XRRQueryExtension( - priv->x11_display, &evt_base, &err_base); - } -#endif + check_xrandr(display); return TRUE; } @@ -284,10 +215,10 @@ static void gst_vaapi_display_x11_close_display(GstVaapiDisplay *display) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); if (priv->x11_display) { - if (priv->create_display) + if (!priv->use_foreign_display) XCloseDisplay(priv->x11_display); priv->x11_display = NULL; } @@ -302,7 +233,7 @@ static void gst_vaapi_display_x11_sync(GstVaapiDisplay *display) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); if (priv->x11_display) { GST_VAAPI_DISPLAY_LOCK(display); @@ -315,7 +246,7 @@ static void gst_vaapi_display_x11_flush(GstVaapiDisplay *display) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); if (priv->x11_display) { GST_VAAPI_DISPLAY_LOCK(display); @@ -331,7 +262,7 @@ gst_vaapi_display_x11_get_display_info( ) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); GstVaapiDisplayCache *cache; const GstVaapiDisplayInfo *cached_info; @@ -366,7 +297,7 @@ gst_vaapi_display_x11_get_size( ) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); if (!priv->x11_display) return; @@ -386,7 +317,7 @@ gst_vaapi_display_x11_get_size_mm( ) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); guint width_mm, height_mm; if (!priv->x11_display) @@ -435,19 +366,17 @@ gst_vaapi_display_x11_get_size_mm( *pheight = height_mm; } -static void +void gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiDisplayX11Private)); - - object_class->finalize = gst_vaapi_display_x11_finalize; - object_class->set_property = gst_vaapi_display_x11_set_property; - object_class->get_property = gst_vaapi_display_x11_get_property; - object_class->constructed = gst_vaapi_display_x11_constructed; + gst_vaapi_display_class_init(&klass->parent_class); + object_class->size = sizeof(GstVaapiDisplayX11); + 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; @@ -455,77 +384,19 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) 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; - - /** - * GstVaapiDisplayX11:synchronous: - * - * When enabled, runs the X display in synchronous mode. Note that - * this is used only for debugging. - */ - g_object_class_install_property - (object_class, - PROP_SYNCHRONOUS, - g_param_spec_boolean("synchronous", - "Synchronous mode", - "Toggles X display synchronous mode", - FALSE, - G_PARAM_READWRITE)); - - /** - * GstVaapiDisplayX11:x11-display: - * - * The X11 #Display that was created by gst_vaapi_display_x11_new() - * or that was bound from gst_vaapi_display_x11_new_with_display(). - */ - g_object_class_install_property - (object_class, - PROP_X11_DISPLAY, - g_param_spec_pointer("x11-display", - "X11 display", - "X11 display", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiDisplayX11:x11-screen: - * - * The X11 screen that was created by gst_vaapi_display_x11_new() - * or that was bound from gst_vaapi_display_x11_new_with_display(). - */ - g_object_class_install_property - (object_class, - PROP_X11_SCREEN, - g_param_spec_int("x11-screen", - "X11 screen", - "X11 screen", - 0, G_MAXINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiDisplayX11:display-name: - * - * The X11 display name. - */ - g_object_class_install_property - (object_class, - PROP_DISPLAY_NAME, - g_param_spec_string("display-name", - "X11 display name", - "X11 display name", - NULL, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } -static void -gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) +static inline const GstVaapiDisplayClass * +gst_vaapi_display_x11_class(void) { - GstVaapiDisplayX11Private *priv = GST_VAAPI_DISPLAY_X11_GET_PRIVATE(display); + static GstVaapiDisplayX11Class g_class; + static gsize g_class_init = FALSE; - display->priv = priv; - priv->create_display = TRUE; - priv->x11_display = NULL; - priv->x11_screen = 0; - priv->display_name = NULL; - priv->use_xrandr = FALSE; + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_display_x11_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS(&g_class); } /** @@ -541,9 +412,8 @@ gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) GstVaapiDisplay * gst_vaapi_display_x11_new(const gchar *display_name) { - return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, - "display-name", display_name, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_x11_class(), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name); } /** @@ -562,10 +432,8 @@ gst_vaapi_display_x11_new_with_display(Display *x11_display) { g_return_val_if_fail(x11_display, NULL); - return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, - "x11-display", x11_display, - "x11-screen", DefaultScreen(x11_display), - NULL); + return gst_vaapi_display_new(gst_vaapi_display_x11_class(), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display); } /** @@ -583,7 +451,7 @@ gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); - return display->priv->x11_display; + return GST_VAAPI_DISPLAY_XDISPLAY(display); } /** @@ -601,5 +469,25 @@ gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), -1); - return display->priv->x11_screen; + 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); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 66f8f1b9b1..68922232fa 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -28,59 +28,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DISPLAY_X11 \ - (gst_vaapi_display_x11_get_type()) - -#define GST_VAAPI_DISPLAY_X11(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DISPLAY_X11, \ - GstVaapiDisplayX11)) - -#define GST_VAAPI_DISPLAY_X11_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DISPLAY_X11, \ - GstVaapiDisplayX11Class)) +#define GST_VAAPI_DISPLAY_X11(obj) \ + ((GstVaapiDisplayX11 *)(obj)) #define GST_VAAPI_IS_DISPLAY_X11(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_X11)) - -#define GST_VAAPI_IS_DISPLAY_X11_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_X11)) - -#define GST_VAAPI_DISPLAY_X11_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DISPLAY_X11, \ - GstVaapiDisplayX11Class)) + ((obj) != NULL) typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11; -typedef struct _GstVaapiDisplayX11Private GstVaapiDisplayX11Private; -typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class; - -/** - * GstVaapiDisplayX11: - * - * VA/X11 display wrapper. - */ -struct _GstVaapiDisplayX11 { - /*< private >*/ - GstVaapiDisplay parent_instance; - - GstVaapiDisplayX11Private *priv; -}; - - -/** - * GstVaapiDisplayX11Class: - * - * VA/X11 display wrapper clas. - */ -struct _GstVaapiDisplayX11Class { - /*< private >*/ - GstVaapiDisplayClass parent_class; -}; - -GType -gst_vaapi_display_x11_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_display_x11_new(const gchar *display_name); @@ -94,6 +48,10 @@ 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); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_X11_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index 17b54beda9..2d8203cb79 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -25,15 +25,18 @@ #include #include +#include "gstvaapidisplay_priv.h" G_BEGIN_DECLS -#define GST_VAAPI_DISPLAY_X11_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DISPLAY_X11, \ - GstVaapiDisplayX11Private)) +#define GST_VAAPI_DISPLAY_X11_CAST(display) \ + ((GstVaapiDisplayX11 *)(display)) -#define GST_VAAPI_DISPLAY_X11_CAST(display) ((GstVaapiDisplayX11 *)(display)) +#define GST_VAAPI_DISPLAY_X11_PRIVATE(display) \ + (&GST_VAAPI_DISPLAY_X11_CAST(display)->priv) + +typedef struct _GstVaapiDisplayX11Private GstVaapiDisplayX11Private; +typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class; /** * GST_VAAPI_DISPLAY_XDISPLAY: @@ -43,7 +46,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DISPLAY_XDISPLAY #define GST_VAAPI_DISPLAY_XDISPLAY(display) \ - GST_VAAPI_DISPLAY_X11_CAST(display)->priv->x11_display + GST_VAAPI_DISPLAY_X11_PRIVATE(display)->x11_display /** * GST_VAAPI_DISPLAY_XSCREEN: @@ -53,17 +56,42 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DISPLAY_XSCREEN #define GST_VAAPI_DISPLAY_XSCREEN(display) \ - GST_VAAPI_DISPLAY_X11_CAST(display)->priv->x11_screen + GST_VAAPI_DISPLAY_X11_PRIVATE(display)->x11_screen struct _GstVaapiDisplayX11Private { - gchar *display_name; - Display *x11_display; - int x11_screen; - guint create_display : 1; - guint synchronous : 1; - guint use_xrandr : 1; + gchar *display_name; + Display *x11_display; + int x11_screen; + 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 clas. + */ +struct _GstVaapiDisplayX11Class { + /*< private >*/ + GstVaapiDisplayClass parent_class; +}; + +void +gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_X11_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 59efb5d2b0..2e380093e0 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -47,7 +47,7 @@ gst_vaapi_object_finalize(GstVaapiObject *object) if (klass->finalize) klass->finalize(object); - g_clear_object(&object->display); + gst_vaapi_display_replace(&object->display, NULL); } void @@ -89,7 +89,7 @@ gst_vaapi_object_new(const GstVaapiObjectClass *klass, GstVaapiDisplay *display) if (!object) return NULL; - object->display = g_object_ref(display); + object->display = gst_vaapi_display_ref(display); object->object_id = VA_INVALID_ID; sub_size = object_class->size - sizeof(*object); diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index adb7b34f8b..1f86ead599 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -56,7 +56,7 @@ gst_vaapi_video_pool_alloc_object(GstVaapiVideoPool *pool) void gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display) { - pool->display = g_object_ref(display); + pool->display = gst_vaapi_display_ref(display); pool->used_objects = NULL; pool->used_count = 0; pool->capacity = 0; @@ -69,7 +69,7 @@ gst_vaapi_video_pool_finalize(GstVaapiVideoPool *pool) { g_list_free_full(pool->used_objects, gst_vaapi_object_unref); g_queue_free_full(&pool->free_objects, gst_vaapi_object_unref); - g_clear_object(&pool->display); + gst_vaapi_display_replace(&pool->display, NULL); } /** From 4ffdc98ab4819db2586991b74278b125376c4099 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 2 May 2013 16:11:53 +0200 Subject: [PATCH 1181/3781] libs: drop obsolete function helpers and objects. Drop obsolete GstVaapiID related function helpers for passing them as GValues. --- gst-libs/gst/vaapi/Makefile.am | 3 - gst-libs/gst/vaapi/gstvaapi_priv.h | 28 ----- gst-libs/gst/vaapi/gstvaapiparamspecs.c | 141 ------------------------ gst-libs/gst/vaapi/gstvaapiparamspecs.h | 72 ------------ gst-libs/gst/vaapi/gstvaapivalue.c | 136 ----------------------- gst-libs/gst/vaapi/gstvaapivalue.h | 26 ----- 6 files changed, 406 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapi_priv.h delete mode 100644 gst-libs/gst/vaapi/gstvaapiparamspecs.c delete mode 100644 gst-libs/gst/vaapi/gstvaapiparamspecs.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 61793481e1..e5dbc5f6c0 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -60,7 +60,6 @@ libgstvaapi_source_c = \ gstvaapiimagepool.c \ gstvaapiminiobject.c \ gstvaapiobject.c \ - gstvaapiparamspecs.c \ gstvaapiparser_frame.c \ gstvaapiprofile.c \ gstvaapisubpicture.c \ @@ -86,7 +85,6 @@ libgstvaapi_source_h = \ gstvaapiimageformat.h \ gstvaapiimagepool.h \ gstvaapiobject.h \ - gstvaapiparamspecs.h \ gstvaapiprofile.h \ gstvaapisubpicture.h \ gstvaapisurface.h \ @@ -101,7 +99,6 @@ libgstvaapi_source_h = \ libgstvaapi_source_priv_h = \ glibcompat.h \ gstcompat.h \ - gstvaapi_priv.h \ gstvaapicodec_objects.h \ gstvaapicompat.h \ gstvaapidebug.h \ diff --git a/gst-libs/gst/vaapi/gstvaapi_priv.h b/gst-libs/gst/vaapi/gstvaapi_priv.h deleted file mode 100644 index 8416b83386..0000000000 --- a/gst-libs/gst/vaapi/gstvaapi_priv.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * gstvaapi_priv.h - Helper to include all private headers - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * - * 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_PRIV_H -#define GST_VAAPI_PRIV_H - -#include -#include - -#endif /* GST_VAAPI_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.c b/gst-libs/gst/vaapi/gstvaapiparamspecs.c deleted file mode 100644 index 46a4e8d847..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * gstvaapiparamspecs.c - GParamSpecs for some of our types - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2012 Intel Corporation - * - * 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:gstvaapiparamspecs - * @short_description: GParamSpecs for some of our types - */ - -#include "sysdeps.h" -#include "gstvaapiparamspecs.h" -#include "gstvaapivalue.h" - -/* --- GstVaapiParamSpecID --- */ - -static void -gst_vaapi_param_id_init(GParamSpec *pspec) -{ - GST_VAAPI_PARAM_SPEC_ID(pspec)->default_value = GST_VAAPI_ID_NONE; -} - -static void -gst_vaapi_param_id_set_default(GParamSpec *pspec, GValue *value) -{ - gst_vaapi_value_set_id(value, GST_VAAPI_PARAM_SPEC_ID(pspec)->default_value); -} - -static gboolean -gst_vaapi_param_id_validate(GParamSpec *pspec, GValue *value) -{ - /* Return FALSE if everything is OK, otherwise TRUE */ - return FALSE; -} - -static gint -gst_vaapi_param_id_compare( - GParamSpec *pspec, - const GValue *value1, - const GValue *value2 -) -{ - const GstVaapiID v1 = gst_vaapi_value_get_id(value1); - const GstVaapiID v2 = gst_vaapi_value_get_id(value2); - - return (v1 < v2 ? -1 : (v1 > v2 ? 1 : 0)); -} - -GType -gst_vaapi_param_spec_id_get_type(void) -{ - static GType type; - - if (G_UNLIKELY(type == 0)) { - static GParamSpecTypeInfo pspec_info = { - sizeof(GstVaapiParamSpecID), /* instance_size */ - 0, /* n_preallocs */ - gst_vaapi_param_id_init, /* instance_init */ - G_TYPE_INVALID, /* value_type */ - NULL, /* finalize */ - gst_vaapi_param_id_set_default, /* value_set_default */ - gst_vaapi_param_id_validate, /* value_validate */ - gst_vaapi_param_id_compare, /* values_cmp */ - }; - pspec_info.value_type = GST_VAAPI_TYPE_ID; - type = g_param_type_register_static("GstVaapiParamSpecID", &pspec_info); - } - return type; -} - -/** - * gst_vaapi_param_spec_id: - * @name: canonical name of the property specified - * @nick: nick name for the property specified - * @blurb: description of the property specified - * @default_value: default value - * @flags: flags for the property specified - * - * This function creates an ID GParamSpec for use by #GstVaapiObject - * objects. This function is typically used in connection with - * g_object_class_install_property() in a GObjects's instance_init - * function. - * - * Return value: a newly created parameter specification - */ -GParamSpec * -gst_vaapi_param_spec_id( - const gchar *name, - const gchar *nick, - const gchar *blurb, - GstVaapiID default_value, - GParamFlags flags -) -{ - GstVaapiParamSpecID *ispec; - GParamSpec *pspec; - GValue value = { 0, }; - - ispec = g_param_spec_internal( - GST_VAAPI_TYPE_PARAM_ID, - name, - nick, - blurb, - flags - ); - if (!ispec) - return NULL; - - ispec->default_value = default_value; - pspec = G_PARAM_SPEC(ispec); - - /* Validate default value */ - g_value_init(&value, GST_VAAPI_TYPE_ID); - gst_vaapi_value_set_id(&value, default_value); - if (gst_vaapi_param_id_validate(pspec, &value)) { - g_param_spec_ref(pspec); - g_param_spec_sink(pspec); - g_param_spec_unref(pspec); - pspec = NULL; - } - g_value_unset(&value); - - return pspec; -} diff --git a/gst-libs/gst/vaapi/gstvaapiparamspecs.h b/gst-libs/gst/vaapi/gstvaapiparamspecs.h deleted file mode 100644 index a97071a1b3..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiparamspecs.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * gstvaapiparamspecs.h - GParamSpecs for some of our types - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2012 Intel Corporation - * - * 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_PARAM_SPECS_H -#define GST_VAAPI_PARAM_SPECS_H - -#include -#include - -G_BEGIN_DECLS - -/** - * GstVaapiParamSpecID: - * @parent_instance: super class - * @default_value: default value - * - * A GParamSpec derived structure that contains the meta data for - * #GstVaapiID properties. - */ -typedef struct _GstVaapiParamSpecID GstVaapiParamSpecID; -struct _GstVaapiParamSpecID { - GParamSpec parent_instance; - - GstVaapiID default_value; -}; - -#define GST_VAAPI_TYPE_PARAM_ID \ - (gst_vaapi_param_spec_id_get_type()) - -#define GST_VAAPI_IS_PARAM_SPEC_ID(pspec) \ - (G_TYPE_CHECK_INSTANCE_TYPE((pspec), \ - GST_VAAPI_TYPE_PARAM_ID)) - -#define GST_VAAPI_PARAM_SPEC_ID(pspec) \ - (G_TYPE_CHECK_INSTANCE_CAST((pspec), \ - GST_VAAPI_TYPE_PARAM_ID, \ - GstVaapiParamSpecID)) - -GType -gst_vaapi_param_spec_id_get_type(void) G_GNUC_CONST; - -GParamSpec * -gst_vaapi_param_spec_id( - const gchar *name, - const gchar *nick, - const gchar *blurb, - GstVaapiID default_value, - GParamFlags flags -); - -G_END_DECLS - -#endif /* GST_VAAPI_PARAM_SPECS_H */ diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index c709f22431..e66e225a21 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -29,142 +29,6 @@ #include #include "gstvaapivalue.h" -static GTypeInfo gst_vaapi_type_info = { - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - 0, - 0, - NULL, - NULL, -}; - -static GTypeFundamentalInfo gst_vaapi_type_finfo = { - 0 -}; - -#define GST_VAAPI_TYPE_DEFINE(type, name) \ -GType gst_vaapi_ ## type ## _get_type(void) \ -{ \ - static GType gst_vaapi_ ## type ## _type = 0; \ - \ - if (G_UNLIKELY(gst_vaapi_ ## type ## _type == 0)) { \ - gst_vaapi_type_info.value_table = \ - &gst_vaapi_ ## type ## _value_table; \ - gst_vaapi_ ## type ## _type = g_type_register_fundamental( \ - g_type_fundamental_next(), \ - name, \ - &gst_vaapi_type_info, \ - &gst_vaapi_type_finfo, \ - 0 \ - ); \ - } \ - return gst_vaapi_ ## type ## _type; \ -} - -/* --- GstVaapiID --- */ - -#if GST_VAAPI_TYPE_ID_SIZE == 4 -# define GST_VAAPI_VALUE_ID_(cvalue) ((cvalue).v_int) -# define GST_VAAPI_VALUE_ID_CFORMAT "i" -#elif GST_VAAPI_TYPE_ID_SIZE == 8 -# define GST_VAAPI_VALUE_ID_(cvalue) ((cvalue).v_int64) -# define GST_VAAPI_VALUE_ID_CFORMAT "q" -#else -# error "unsupported GstVaapiID size" -#endif -#define GST_VAAPI_VALUE_ID(value) GST_VAAPI_VALUE_ID_((value)->data[0]) - -static void -gst_vaapi_value_id_init(GValue *value) -{ - GST_VAAPI_VALUE_ID(value) = 0; -} - -static void -gst_vaapi_value_id_copy(const GValue *src_value, GValue *dst_value) -{ - GST_VAAPI_VALUE_ID(dst_value) = GST_VAAPI_VALUE_ID(src_value); -} - -static gchar * -gst_vaapi_value_id_collect( - GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags -) -{ - GST_VAAPI_VALUE_ID(value) = GST_VAAPI_VALUE_ID_(collect_values[0]); - - return NULL; -} - -static gchar * -gst_vaapi_value_id_lcopy( - const GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags -) -{ - GstVaapiID *id_p = collect_values[0].v_pointer; - - if (!id_p) - return g_strdup_printf("value location for `%s' passed as NULL", - G_VALUE_TYPE_NAME(value)); - - *id_p = GST_VAAPI_VALUE_ID(value); - return NULL; -} - -static const GTypeValueTable gst_vaapi_id_value_table = { - gst_vaapi_value_id_init, - NULL, - gst_vaapi_value_id_copy, - NULL, - GST_VAAPI_VALUE_ID_CFORMAT, - gst_vaapi_value_id_collect, - "p", - gst_vaapi_value_id_lcopy -}; - -GST_VAAPI_TYPE_DEFINE(id, "GstVaapiID") - -/** - * gst_vaapi_value_get_id: - * @value: a GValue initialized to #GstVaapiID - * - * Gets the integer contained in @value. - * - * Return value: the integer contained in @value - */ -GstVaapiID -gst_vaapi_value_get_id(const GValue *value) -{ - g_return_val_if_fail(GST_VAAPI_VALUE_HOLDS_ID(value), 0); - - return GST_VAAPI_VALUE_ID(value); -} - -/** - * gst_vaapi_value_set_id: - * @value: a GValue initialized to #GstVaapiID - * @id: a #GstVaapiID - * - * Sets the integer contained in @id to @value. - */ -void -gst_vaapi_value_set_id(GValue *value, GstVaapiID id) -{ - g_return_if_fail(GST_VAAPI_VALUE_HOLDS_ID(value)); - - GST_VAAPI_VALUE_ID(value) = id; -} - /* --- GstVaapiRenderMode --- */ GType diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index a363417287..9762f582b6 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -28,23 +28,6 @@ G_BEGIN_DECLS -/** - * GST_VAAPI_TYPE_ID: - * - * A #GValue type that represents a VA identifier. - * - * Return value: the #GType of GstVaapiID - */ -#define GST_VAAPI_TYPE_ID gst_vaapi_id_get_type() - -/** - * GST_VAAPI_VALUE_HOLDS_ID: - * @x: the #GValue to check - * - * Checks if the given #GValue contains a #GstVaapiID value. - */ -#define GST_VAAPI_VALUE_HOLDS_ID(x) (G_VALUE_HOLDS((x), GST_VAAPI_TYPE_ID)) - /** * GST_VAAPI_TYPE_RENDER_MODE: * @@ -64,15 +47,6 @@ G_BEGIN_DECLS */ #define GST_VAAPI_TYPE_ROTATION gst_vaapi_rotation_get_type() -GType -gst_vaapi_id_get_type(void) G_GNUC_CONST; - -GstVaapiID -gst_vaapi_value_get_id(const GValue *value); - -void -gst_vaapi_value_set_id(GValue *value, GstVaapiID id); - GType gst_vaapi_render_mode_get_type(void) G_GNUC_CONST; From c2abeb1290d9f59b456d545651770f786f2be277 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 7 May 2013 18:17:10 +0200 Subject: [PATCH 1182/3781] libs: simplify GstVaapiID definitions. Make GstVaapiID a gsize instead of guessing an underlying integer large enough to hold all bits of a pointer. Also drop GST_VAAPI_ID_NONE since this is plain zero and that it is no longer passed as varargs. --- gst-libs/gst/vaapi/gstvaapiobject.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 4 +-- gst-libs/gst/vaapi/gstvaapitypes.h | 34 ++--------------------- 3 files changed, 5 insertions(+), 35 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 2e380093e0..b270edaf8a 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -199,7 +199,7 @@ gst_vaapi_object_unlock_display(GstVaapiObject *object) GstVaapiID gst_vaapi_object_get_id(GstVaapiObject *object) { - g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), GST_VAAPI_ID_NONE); + g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), 0); return GST_VAAPI_OBJECT_ID(object); } diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 86168eb2cf..7242e9548a 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -180,8 +180,8 @@ gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy) GstVaapiID gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), GST_VAAPI_ID_NONE); - g_return_val_if_fail(proxy->surface != NULL, GST_VAAPI_ID_NONE); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0); + g_return_val_if_fail(proxy->surface != NULL, 0); return GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy); } diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index e3a6e9ce5e..81ef6fcfea 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -33,37 +33,7 @@ G_BEGIN_DECLS * An integer large enough to hold a generic VA id or a pointer * wherever necessary. */ -#if defined(GLIB_SIZEOF_VOID_P) -# define GST_VAAPI_TYPE_ID_SIZE GLIB_SIZEOF_VOID_P -#elif G_MAXULONG == 0xffffffff -# define GST_VAAPI_TYPE_ID_SIZE 4 -#elif G_MAXULONG == 0xffffffffffffffffull -# define GST_VAAPI_TYPE_ID_SIZE 8 -#else -# error "could not determine size of GstVaapiID" -#endif -#if GST_VAAPI_TYPE_ID_SIZE == 4 -typedef guint32 GstVaapiID; -#elif GST_VAAPI_TYPE_ID_SIZE == 8 -typedef guint64 GstVaapiID; -#else -# error "unsupported value for GST_VAAPI_TYPE_ID_SIZE" -#endif - -/** - * GST_VAAPI_ID: - * @id: an arbitrary integer value - * - * Macro that creates a #GstVaapiID from @id. - */ -#define GST_VAAPI_ID(id) ((GstVaapiID)(id)) - -/** - * GST_VAAPI_ID_NONE: - * - * Macro that evaluates to the default #GstVaapiID value. - */ -#define GST_VAAPI_ID_NONE GST_VAAPI_ID(0) +typedef gsize GstVaapiID; /** * GST_VAAPI_ID_FORMAT: @@ -85,7 +55,7 @@ typedef guint64 GstVaapiID; * Can be used together with #GST_VAAPI_ID_FORMAT to properly output * an integer value in a printf()-style text message. */ -#define GST_VAAPI_ID_ARGS(id) GUINT_TO_POINTER(id) +#define GST_VAAPI_ID_ARGS(id) GSIZE_TO_POINTER(id) /** * GstVaapiPoint: From 4cf1213b0452cac6c69f8c76f3d76618aa1d6bc7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 3 May 2013 19:02:23 +0200 Subject: [PATCH 1183/3781] videopool: simplify creation of video objects pool. --- gst-libs/gst/vaapi/gstvaapiimagepool.c | 14 ++++++-------- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 12 +++++------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 1699c2f544..311f9f0bec 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -50,16 +50,14 @@ static gboolean gst_vaapi_image_pool_set_caps(GstVaapiVideoPool *base_pool, GstCaps *caps) { GstVaapiImagePool * const pool = GST_VAAPI_IMAGE_POOL(base_pool); - GstStructure *structure; - gint width, height; + GstVideoInfo vi; - structure = gst_caps_get_structure(caps, 0); - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); + if (!gst_video_info_from_caps(&vi, caps)) + return FALSE; - pool->format = gst_vaapi_image_format_from_caps(caps); - pool->width = width; - pool->height = height; + pool->format = gst_vaapi_image_format_from_video(GST_VIDEO_INFO_FORMAT(&vi)); + pool->width = GST_VIDEO_INFO_WIDTH(&vi); + pool->height = GST_VIDEO_INFO_HEIGHT(&vi); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 33118a653c..d57fb849a2 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -50,16 +50,14 @@ static gboolean gst_vaapi_surface_pool_set_caps(GstVaapiVideoPool *base_pool, GstCaps *caps) { GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(base_pool); - GstStructure *structure; - gint width, height; + GstVideoInfo vi; - structure = gst_caps_get_structure(caps, 0); - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); + if (!gst_video_info_from_caps(&vi, caps)) + return FALSE; pool->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - pool->width = width; - pool->height = height; + pool->width = GST_VIDEO_INFO_WIDTH(&vi); + pool->height = GST_VIDEO_INFO_HEIGHT(&vi); return TRUE; } From 98bee4240fc9b57e94524c3a68a0c4b5eaa3c538 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 7 May 2013 15:38:51 +0200 Subject: [PATCH 1184/3781] display: fix set_synchronous() to lock display. --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 970b255888..cad9251915 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -139,8 +139,11 @@ set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous) if (priv->synchronous != synchronous) { priv->synchronous = synchronous; - if (priv->x11_display) + if (priv->x11_display) { + GST_VAAPI_DISPLAY_LOCK(display); XSynchronize(priv->x11_display, synchronous); + GST_VAAPI_DISPLAY_UNLOCK(display); + } } } From da403b62d0023b370c5def46f8af76df6384f69e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 7 May 2013 11:45:10 +0200 Subject: [PATCH 1185/3781] tests: cope with new GstVaapiMiniObject objects. --- tests/decoder.c | 6 ++--- tests/image.c | 4 ++-- tests/output.c | 2 +- tests/simple-decoder.c | 19 +++++++--------- tests/test-decode.c | 10 ++++----- tests/test-display.c | 49 ++++++++++++++--------------------------- tests/test-subpicture.c | 6 ++--- tests/test-surfaces.c | 30 +++++-------------------- tests/test-textures.c | 8 +++---- tests/test-windows.c | 22 +++++++++--------- 10 files changed, 59 insertions(+), 97 deletions(-) diff --git a/tests/decoder.c b/tests/decoder.c index 881f0a1781..b2ca16e2ab 100644 --- a/tests/decoder.c +++ b/tests/decoder.c @@ -62,18 +62,16 @@ find_codec_defs(const gchar *codec_str) return NULL; } -#define CODEC_DEFS_KEY "codec-defs" - static inline const CodecDefs * get_codec_defs(GstVaapiDecoder *decoder) { - return g_object_get_data(G_OBJECT(decoder), CODEC_DEFS_KEY); + return gst_vaapi_decoder_get_user_data(decoder); } static inline void set_codec_defs(GstVaapiDecoder *decoder, const CodecDefs *c) { - g_object_set_data(G_OBJECT(decoder), CODEC_DEFS_KEY, (gpointer)c); + gst_vaapi_decoder_set_user_data(decoder, (gpointer)c); } GstVaapiDecoder * diff --git a/tests/image.c b/tests/image.c index 7f6f395b53..5c45391fd2 100644 --- a/tests/image.c +++ b/tests/image.c @@ -43,7 +43,7 @@ image_generate( image_draw_rectangle(image, w/2, h/2, w/2, h/2, 0xff000000)) return image; - g_object_unref(image); + gst_vaapi_object_unref(image); return NULL; } @@ -355,6 +355,6 @@ image_upload(GstVaapiImage *image, GstVaapiSurface *surface) g_error("could not associate subpicture to surface"); /* The surface holds a reference to the subpicture. This is safe */ - g_object_unref(subpicture); + gst_vaapi_object_unref(subpicture); return TRUE; } diff --git a/tests/output.c b/tests/output.c index 33ed52c9a3..5fa7e5a14a 100644 --- a/tests/output.c +++ b/tests/output.c @@ -167,7 +167,7 @@ video_output_create_display(const gchar *display_name) if (display) { if (gst_vaapi_display_get_display(display)) break; - g_object_unref(display); + gst_vaapi_display_unref(display); display = NULL; } } diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index 7e33f0c641..3cf46cc078 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -331,16 +331,13 @@ app_set_framerate(App *app, guint fps_n, guint fps_d) } static void -handle_decoder_caps(GObject *obj, GParamSpec *pspec, void *user_data) +handle_decoder_state_changes(GstVaapiDecoder *decoder, + const GstVideoCodecState *codec_state, gpointer user_data) { App * const app = user_data; - GstVideoCodecState *codec_state; - g_assert(app->decoder == GST_VAAPI_DECODER(obj)); - - codec_state = gst_vaapi_decoder_get_codec_state(app->decoder); + g_assert(app->decoder == decoder); app_set_framerate(app, codec_state->info.fps_n, codec_state->info.fps_d); - gst_video_codec_state_unref(codec_state); } static gboolean @@ -383,8 +380,8 @@ start_decoder(App *app) if (!app->decoder) return FALSE; - g_signal_connect(G_OBJECT(app->decoder), "notify::caps", - G_CALLBACK(handle_decoder_caps), app); + gst_vaapi_decoder_set_codec_state_changed_func(app->decoder, + handle_decoder_state_changes, app); g_timer_start(app->timer); @@ -538,9 +535,9 @@ app_free(App *app) } g_free(app->file_name); - g_clear_object(&app->decoder); - g_clear_object(&app->window); - g_clear_object(&app->display); + gst_vaapi_decoder_replace(&app->decoder, NULL); + gst_vaapi_window_replace(&app->window, NULL); + gst_vaapi_display_replace(&app->display, NULL); if (app->decoder_queue) { g_async_queue_unref(app->decoder_queue); diff --git a/tests/test-decode.c b/tests/test-decode.c index d0952be9dc..2d49a6c3b7 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -68,7 +68,7 @@ main(int argc, char *argv[]) if (CHECK_DISPLAY_CACHE) display2 = video_output_create_display(NULL); else - display2 = g_object_ref(display); + display2 = gst_vaapi_display_ref(display); if (!display2) g_error("could not create second VA display"); @@ -97,10 +97,10 @@ main(int argc, char *argv[]) pause(); - g_object_unref(decoder); - g_object_unref(window); - g_object_unref(display); - g_object_unref(display2); + gst_vaapi_decoder_unref(decoder); + gst_vaapi_window_unref(window); + gst_vaapi_display_unref(display); + gst_vaapi_display_unref(display2); g_free(g_codec_str); video_output_exit(); return 0; diff --git a/tests/test-display.c b/tests/test-display.c index 43ae20bbb9..e463d5f372 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -179,17 +179,6 @@ free_property_cb(gpointer data, gpointer user_data) gst_vaapi_display_property_free(data); } -static inline GParamSpec * -get_display_property(GstVaapiDisplay *display, const gchar *name) -{ - GObjectClass *klass; - - klass = G_OBJECT_CLASS(GST_VAAPI_DISPLAY_GET_CLASS(display)); - if (!klass) - return NULL; - return g_object_class_find_property(klass, name); -} - static void dump_properties(GstVaapiDisplay *display) { @@ -212,25 +201,21 @@ dump_properties(GstVaapiDisplay *display) return; for (i = 0; g_properties[i] != NULL; i++) { - GParamSpec *pspec = get_display_property(display, g_properties[i]); + const gchar * const name = g_properties[i]; - if (!pspec) { - GST_ERROR("failed to find GstVaapiDisplay property '%s'", - g_properties[i]); - goto end; - } - - if (!gst_vaapi_display_has_property(display, pspec->name)) + if (!gst_vaapi_display_has_property(display, name)) continue; - prop = gst_vaapi_display_property_new(pspec->name); + prop = gst_vaapi_display_property_new(name); if (!prop) { GST_ERROR("failed to allocate GstVaapiDisplayProperty"); goto end; } - g_value_init(&prop->value, pspec->value_type); - g_object_get_property(G_OBJECT(display), pspec->name, &prop->value); + if (!gst_vaapi_display_get_property(display, name, &prop->value)) { + GST_ERROR("failed to get property '%s'", name); + goto end; + } g_ptr_array_add(properties, prop); } @@ -301,7 +286,7 @@ main(int argc, char *argv[]) g_error("could not create Gst/VA display"); dump_info(display); - g_object_unref(display); + gst_vaapi_display_unref(display); } g_print("\n"); @@ -320,7 +305,7 @@ main(int argc, char *argv[]) g_error("could not create Gst/VA display"); dump_info(display); - g_object_unref(display); + gst_vaapi_display_unref(display); close(drm_device); } g_print("\n"); @@ -345,7 +330,7 @@ main(int argc, char *argv[]) g_error("could not create Gst/VA display"); dump_info(display); - g_object_unref(display); + gst_vaapi_display_unref(display); close(drm_device); } g_print("\n"); @@ -367,7 +352,7 @@ main(int argc, char *argv[]) g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); dump_info(display); - g_object_unref(display); + gst_vaapi_display_unref(display); } g_print("\n"); @@ -386,7 +371,7 @@ main(int argc, char *argv[]) g_error("could not create Gst/VA display"); dump_info(display); - g_object_unref(display); + gst_vaapi_display_unref(display); XCloseDisplay(x11_display); } g_print("\n"); @@ -411,7 +396,7 @@ main(int argc, char *argv[]) g_error("could not create Gst/VA display"); dump_info(display); - g_object_unref(display); + gst_vaapi_display_unref(display); XCloseDisplay(x11_display); } g_print("\n"); @@ -433,7 +418,7 @@ main(int argc, char *argv[]) g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); dump_info(display); - g_object_unref(display); + gst_vaapi_display_unref(display); } g_print("\n"); @@ -452,7 +437,7 @@ main(int argc, char *argv[]) g_error("could not create Gst/VA display"); dump_info(display); - g_object_unref(display); + gst_vaapi_display_unref(display); XCloseDisplay(x11_display); } g_print("\n"); @@ -478,7 +463,7 @@ main(int argc, char *argv[]) g_error("could not create Gst/VA display"); dump_info(display); - g_object_unref(display); + gst_vaapi_display_unref(display); XCloseDisplay(x11_display); } g_print("\n"); @@ -501,7 +486,7 @@ main(int argc, char *argv[]) g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); dump_info(display); - g_object_unref(display); + gst_vaapi_display_unref(display); } g_print("\n"); #endif diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index be1ec5832e..0f828aea7a 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -171,9 +171,9 @@ main(int argc, char *argv[]) pause(); gst_video_overlay_composition_unref(compo); - g_object_unref(decoder); - g_object_unref(window); - g_object_unref(display); + gst_vaapi_decoder_unref(decoder); + gst_vaapi_window_unref(window); + gst_vaapi_display_unref(display); g_free(g_codec_str); video_output_exit(); return 0; diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index a5b5f69f9d..806f8f31bc 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -26,12 +26,6 @@ #define MAX_SURFACES 4 -static void -gst_vaapi_object_destroy_cb(gpointer object, gpointer user_data) -{ - g_print("destroying GstVaapiObject %p\n", object); -} - int main(int argc, char *argv[]) { @@ -58,14 +52,11 @@ main(int argc, char *argv[]) if (!surface) g_error("could not create Gst/VA surface"); - /* This also tests for the GstVaapiParamSpecID */ - g_object_get(G_OBJECT(surface), "id", &surface_id, NULL); - if (surface_id != gst_vaapi_surface_get_id(surface)) - g_error("could not retrieve the native surface ID"); + surface_id = gst_vaapi_surface_get_id(surface); g_print("created surface %" GST_VAAPI_ID_FORMAT "\n", GST_VAAPI_ID_ARGS(surface_id)); - g_object_unref(surface); + gst_vaapi_object_unref(surface); caps = gst_caps_new_simple( GST_VAAPI_SURFACE_CAPS_NAME, @@ -91,7 +82,7 @@ main(int argc, char *argv[]) } /* Check the pool doesn't return the last free'd surface */ - surface = g_object_ref(surfaces[1]); + surface = gst_vaapi_object_ref(surfaces[1]); for (i = 0; i < 2; i++) gst_vaapi_video_pool_put_object(pool, surfaces[i]); @@ -114,20 +105,11 @@ main(int argc, char *argv[]) surfaces[i] = NULL; } - g_signal_connect( - G_OBJECT(surface), - "destroy", - G_CALLBACK(gst_vaapi_object_destroy_cb), NULL - ); - /* Unref in random order to check objects are correctly refcounted */ - g_print("unref display\n"); - g_object_unref(display); + gst_vaapi_display_unref(display); gst_caps_unref(caps); - g_print("unref pool\n"); - g_object_unref(pool); - g_print("unref surface\n"); - g_object_unref(surface); + gst_vaapi_video_pool_unref(pool); + gst_vaapi_object_unref(surface); video_output_exit(); return 0; } diff --git a/tests/test-textures.c b/tests/test-textures.c index 9d6e58b97f..e89fb5f2ea 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -182,12 +182,12 @@ main(int argc, char *argv[]) gst_vaapi_window_glx_swap_buffers(glx_window); pause(); - g_object_unref(textures[0]); - g_object_unref(textures[1]); + gst_vaapi_texture_unref(textures[0]); + gst_vaapi_texture_unref(textures[1]); glDeleteTextures(1, &texture_id); - g_object_unref(window); - g_object_unref(display); + gst_vaapi_window_unref(window); + gst_vaapi_display_unref(display); gst_deinit(); return 0; } diff --git a/tests/test-windows.c b/tests/test-windows.c index 2b98f84f30..a305205ea4 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -83,7 +83,7 @@ create_test_surface(GstVaapiDisplay *display, guint width, guint height) if (!gst_vaapi_surface_sync(surface)) g_error("could not complete image upload"); - g_object_unref(image); + gst_vaapi_object_unref(image); return surface; } @@ -125,11 +125,11 @@ main(int argc, char *argv[]) g_error("could not render surface"); pause(); - g_object_unref(window); + gst_vaapi_window_unref(window); } - g_object_unref(surface); - g_object_unref(display); + gst_vaapi_object_unref(surface); + gst_vaapi_display_unref(display); #endif #if USE_X11 @@ -155,7 +155,7 @@ main(int argc, char *argv[]) g_error("could not render surface"); pause(); - g_object_unref(window); + gst_vaapi_window_unref(window); } g_print("#\n"); @@ -192,13 +192,13 @@ main(int argc, char *argv[]) g_error("could not render surface"); pause(); - g_object_unref(window); + gst_vaapi_window_unref(window); XUnmapWindow(dpy, win); XDestroyWindow(dpy, win); } - g_object_unref(surface); - g_object_unref(display); + gst_vaapi_object_unref(surface); + gst_vaapi_display_unref(display); #endif #if USE_WAYLAND @@ -224,11 +224,11 @@ main(int argc, char *argv[]) g_error("could not render surface"); pause(); - g_object_unref(window); + gst_vaapi_window_unref(window); } - g_object_unref(surface); - g_object_unref(display); + gst_vaapi_object_unref(surface); + gst_vaapi_display_unref(display); #endif gst_deinit(); From 9535bb995071f25271d518549db6363c9b60c471 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 6 May 2013 14:43:38 +0200 Subject: [PATCH 1186/3781] plugins: cope with new GstVaapiMiniObject objects. --- gst/vaapi/gstvaapidecode.c | 32 +++++++++++----------- gst/vaapi/gstvaapidownload.c | 11 ++++---- gst/vaapi/gstvaapipluginutil.c | 13 +++++---- gst/vaapi/gstvaapipostproc.c | 4 +-- gst/vaapi/gstvaapisink.c | 17 ++++++------ gst/vaapi/gstvaapiupload.c | 5 ++-- gst/vaapi/gstvaapiuploader.c | 28 ++++++++----------- gst/vaapi/gstvaapivideobufferpool.c | 9 +++---- gst/vaapi/gstvaapivideoconverter_glx.c | 4 +-- gst/vaapi/gstvaapivideomemory.c | 10 +++---- gst/vaapi/gstvaapivideometa.c | 37 ++++++++++++-------------- 11 files changed, 77 insertions(+), 93 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b4d711ff9f..e91bbdd133 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -130,17 +130,17 @@ G_DEFINE_TYPE_WITH_CODE( static gboolean gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, - GstVideoCodecState *ref_state); + const GstVideoCodecState *ref_state); static void -gst_vaapi_decoder_notify_caps(GObject *obj, GParamSpec *pspec, void *user_data) +gst_vaapi_decoder_state_changed(GstVaapiDecoder *decoder, + const GstVideoCodecState *codec_state, gpointer user_data) { GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data); - g_assert(decode->decoder == GST_VAAPI_DECODER(obj)); + g_assert(decode->decoder == decoder); - gst_vaapidecode_update_src_caps(decode, - gst_vaapi_decoder_get_codec_state(decode->decoder)); + gst_vaapidecode_update_src_caps(decode, codec_state); } static inline gboolean @@ -152,7 +152,7 @@ gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps) static gboolean gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, - GstVideoCodecState *ref_state) + const GstVideoCodecState *ref_state) { GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); GstVideoCodecState *state; @@ -160,7 +160,8 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, state = gst_video_decoder_set_output_state(vdec, GST_VIDEO_INFO_FORMAT(&ref_state->info), - ref_state->info.width, ref_state->info.height, ref_state); + ref_state->info.width, ref_state->info.height, + (GstVideoCodecState *)ref_state); if (!state) return FALSE; @@ -553,12 +554,8 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) if (!decode->decoder) return FALSE; - g_signal_connect( - G_OBJECT(decode->decoder), - "notify::caps", - G_CALLBACK(gst_vaapi_decoder_notify_caps), - decode - ); + gst_vaapi_decoder_set_codec_state_changed_func(decode->decoder, + gst_vaapi_decoder_state_changed, decode); decode->decoder_caps = gst_caps_ref(caps); return gst_pad_start_task(decode->srcpad, @@ -569,7 +566,7 @@ static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { gst_pad_stop_task(decode->srcpad); - g_clear_object(&decode->decoder); + gst_vaapi_decoder_replace(&decode->decoder, NULL); gst_caps_replace(&decode->decoder_caps, NULL); gst_vaapidecode_release(decode); } @@ -607,7 +604,7 @@ gst_vaapidecode_finalize(GObject *object) gst_caps_replace(&decode->srcpad_caps, NULL); gst_caps_replace(&decode->allowed_caps, NULL); - g_clear_object(&decode->display); + gst_vaapi_display_replace(&decode->display, NULL); g_cond_clear(&decode->decoder_ready); g_mutex_clear(&decode->decoder_mutex); @@ -629,7 +626,8 @@ gst_vaapidecode_open(GstVideoDecoder *vdec) existing (cached) VA display */ decode->display = NULL; success = gst_vaapidecode_ensure_display(decode); - g_clear_object(&old_display); + if (old_display) + gst_vaapi_display_unref(old_display); return success; } @@ -639,7 +637,7 @@ gst_vaapidecode_close(GstVideoDecoder *vdec) GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); gst_vaapidecode_destroy(decode); - g_clear_object(&decode->display); + gst_vaapi_display_replace(&decode->display, NULL); return TRUE; } diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 1a5f090f19..4f0d20dc6c 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -196,8 +196,8 @@ gst_vaapidownload_destroy(GstVaapiDownload *download) download->allowed_caps = NULL; } - g_clear_object(&download->images); - g_clear_object(&download->display); + gst_vaapi_video_pool_replace(&download->images, NULL); + gst_vaapi_display_replace(&download->display, NULL); } static void @@ -289,8 +289,7 @@ gst_vaapidownload_stop(GstBaseTransform *trans) { GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - g_clear_object(&download->display); - + gst_vaapi_display_replace(&download->display, NULL); return TRUE; } @@ -304,7 +303,7 @@ get_surface_format(GstVaapiSurface *surface) image = gst_vaapi_surface_derive_image(surface); if (image) { format = gst_vaapi_image_get_format(image); - g_object_unref(image); + gst_vaapi_object_unref(image); } return format; } @@ -499,7 +498,7 @@ gst_vaapidownload_ensure_image_pool(GstVaapiDownload *download, GstCaps *caps) download->image_format = format; download->image_width = width; download->image_height = height; - g_clear_object(&download->images); + gst_vaapi_video_pool_replace(&download->images, NULL); download->images = gst_vaapi_image_pool_new(download->display, caps); if (!download->images) return FALSE; diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 6364fbb188..855952ada4 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -127,7 +127,7 @@ gst_vaapi_ensure_display( display_type = m->type; break; } - g_object_unref(display); + gst_vaapi_display_unref(display); display = NULL; } @@ -154,8 +154,8 @@ gst_vaapi_set_display( dpy = gst_vaapi_display_new_with_display(g_value_get_pointer(value)); } else if (!strcmp(type, "gst-vaapi-display")) { - g_return_if_fail(G_VALUE_HOLDS_OBJECT(value)); - dpy = g_value_dup_object(value); + g_return_if_fail(G_VALUE_HOLDS_POINTER(value)); + dpy = gst_vaapi_display_ref(g_value_get_pointer(value)); } #if USE_DRM else if (!strcmp(type, "drm-device")) { @@ -205,9 +205,8 @@ gst_vaapi_set_display( #endif if (dpy) { - if (*display) - g_object_unref(*display); - *display = dpy; + gst_vaapi_display_replace(display, dpy); + gst_vaapi_display_unref(dpy); } } @@ -237,7 +236,7 @@ gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) res = TRUE; if (!strcmp(type, "gst-vaapi-display")) { - gst_video_context_query_set_object(query, type, G_OBJECT(display)); + gst_video_context_query_set_pointer(query, type, display); } else if (!strcmp(type, "vaapi-display")) { VADisplay vadpy = gst_vaapi_display_get_display(display); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 7663b5bd1d..944e11f87f 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -207,7 +207,7 @@ gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) { gst_caps_replace(&postproc->postproc_caps, NULL); - g_clear_object(&postproc->display); + gst_vaapi_display_replace(&postproc->display, NULL); } static gboolean @@ -232,7 +232,7 @@ gst_vaapipostproc_start(GstVaapiPostproc *postproc) static gboolean gst_vaapipostproc_stop(GstVaapiPostproc *postproc) { - g_clear_object(&postproc->display); + gst_vaapi_display_replace(&postproc->display, NULL); return TRUE; } diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 4c8d46d912..d9da5ccb22 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -253,8 +253,8 @@ static void gst_vaapisink_destroy(GstVaapiSink *sink) { gst_buffer_replace(&sink->video_buffer, NULL); - g_clear_object(&sink->texture); - g_clear_object(&sink->display); + gst_vaapi_texture_replace(&sink->texture, NULL); + gst_vaapi_display_replace(&sink->display, NULL); g_clear_object(&sink->uploader); gst_caps_replace(&sink->caps, NULL); @@ -540,7 +540,7 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) == xid) return TRUE; - g_clear_object(&sink->window); + gst_vaapi_window_replace(&sink->window, NULL); switch (sink->display_type) { #if USE_GLX @@ -685,8 +685,8 @@ gst_vaapisink_stop(GstBaseSink *base_sink) #if GST_CHECK_VERSION(1,0,0) g_clear_object(&sink->video_buffer_pool); #endif - g_clear_object(&sink->window); - g_clear_object(&sink->display); + gst_vaapi_window_replace(&sink->window, NULL); + gst_vaapi_display_replace(&sink->display, NULL); g_clear_object(&sink->uploader); return TRUE; @@ -982,10 +982,9 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) } #endif - if (sink->display != gst_vaapi_video_meta_get_display(meta)) { - g_clear_object(&sink->display); - sink->display = g_object_ref(gst_vaapi_video_meta_get_display(meta)); - } + if (sink->display != gst_vaapi_video_meta_get_display(meta)) + gst_vaapi_display_replace(&sink->display, + gst_vaapi_video_meta_get_display(meta)); if (!sink->window) goto error; diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index aa22057fa9..5c80c5a1bc 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -174,7 +174,7 @@ static void gst_vaapiupload_destroy(GstVaapiUpload *upload) { g_clear_object(&upload->uploader); - g_clear_object(&upload->display); + gst_vaapi_display_replace(&upload->display, NULL); } static void @@ -279,8 +279,7 @@ gst_vaapiupload_stop(GstBaseTransform *trans) { GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - g_clear_object(&upload->display); - + gst_vaapi_display_replace(&upload->display, NULL); return TRUE; } diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index f2c341f37b..bf0970047e 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -73,9 +73,9 @@ gst_vaapi_uploader_destroy(GstVaapiUploader *uploader) gst_caps_replace(&priv->image_caps, NULL); gst_caps_replace(&priv->allowed_caps, NULL); - g_clear_object(&priv->images); - g_clear_object(&priv->surfaces); - g_clear_object(&priv->display); + gst_vaapi_video_pool_replace(&priv->images, NULL); + gst_vaapi_video_pool_replace(&priv->surfaces, NULL); + gst_vaapi_display_replace(&priv->display, NULL); } static gboolean @@ -83,12 +83,7 @@ ensure_display(GstVaapiUploader *uploader, GstVaapiDisplay *display) { GstVaapiUploaderPrivate * const priv = uploader->priv; - if (priv->display == display) - return TRUE; - - g_clear_object(&priv->display); - if (display) - priv->display = g_object_ref(display); + gst_vaapi_display_replace(&priv->display, display); return TRUE; } @@ -156,7 +151,7 @@ ensure_allowed_caps(GstVaapiUploader *uploader) continue; if (ensure_image(image) && gst_vaapi_surface_put_image(surface, image)) gst_caps_append_structure(out_caps, gst_structure_copy(structure)); - gst_object_unref(image); + gst_vaapi_object_unref(image); } gst_caps_replace(&priv->allowed_caps, out_caps); @@ -167,7 +162,7 @@ end: if (image_caps) gst_caps_unref(image_caps); if (surface) - gst_object_unref(surface); + gst_vaapi_object_unref(surface); return success; } @@ -184,7 +179,7 @@ ensure_image_pool(GstVaapiUploader *uploader, GstCaps *caps) if (width != priv->image_width || height != priv->image_height) { priv->image_width = width; priv->image_height = height; - g_clear_object(&priv->images); + gst_vaapi_video_pool_replace(&priv->images, NULL); priv->images = gst_vaapi_image_pool_new(priv->display, caps); if (!priv->images) return FALSE; @@ -206,7 +201,7 @@ ensure_surface_pool(GstVaapiUploader *uploader, GstCaps *caps) if (width != priv->surface_width || height != priv->surface_height) { priv->surface_width = width; priv->surface_height = height; - g_clear_object(&priv->surfaces); + gst_vaapi_video_pool_replace(&priv->surfaces, NULL); priv->surfaces = gst_vaapi_surface_pool_new(priv->display, caps); if (!priv->surfaces) return FALSE; @@ -230,7 +225,7 @@ gst_vaapi_uploader_set_property(GObject *object, guint prop_id, switch (prop_id) { case PROP_DISPLAY: - ensure_display(uploader, g_value_get_object(value)); + ensure_display(uploader, g_value_get_pointer(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -246,7 +241,7 @@ gst_vaapi_uploader_get_property(GObject *object, guint prop_id, switch (prop_id) { case PROP_DISPLAY: - g_value_set_object(value, uploader->priv->display); + g_value_set_pointer(value, uploader->priv->display); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -271,11 +266,10 @@ gst_vaapi_uploader_class_init(GstVaapiUploaderClass *klass) g_object_class_install_property( object_class, PROP_DISPLAY, - g_param_spec_object( + g_param_spec_pointer( "display", "Display", "The GstVaapiDisplay this object is bound to", - GST_VAAPI_TYPE_DISPLAY, G_PARAM_READWRITE)); } diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index b6002fb561..5c84ab1b43 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -56,7 +56,7 @@ gst_vaapi_video_buffer_pool_finalize(GObject *object) G_OBJECT_CLASS(gst_vaapi_video_buffer_pool_parent_class)->finalize(object); - g_clear_object(&priv->display); + gst_vaapi_display_replace(&priv->display, NULL); g_clear_object(&priv->allocator); } @@ -69,7 +69,7 @@ gst_vaapi_video_buffer_pool_set_property(GObject *object, guint prop_id, switch (prop_id) { case PROP_DISPLAY: - priv->display = g_object_ref(g_value_get_object(value)); + priv->display = gst_vaapi_display_ref(g_value_get_pointer(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -86,7 +86,7 @@ gst_vaapi_video_buffer_pool_get_property(GObject *object, guint prop_id, switch (prop_id) { case PROP_DISPLAY: - g_value_set_object(value, priv->display); + g_value_set_pointer(value, priv->display); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -265,10 +265,9 @@ gst_vaapi_video_buffer_pool_class_init(GstVaapiVideoBufferPoolClass *klass) g_object_class_install_property (object_class, PROP_DISPLAY, - g_param_spec_object("display", + g_param_spec_pointer("display", "Display", "The GstVaapiDisplay to use for this video pool", - GST_VAAPI_TYPE_DISPLAY, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index cfbf163b9b..aaa9c35060 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -64,7 +64,7 @@ gst_vaapi_video_converter_glx_dispose(GObject *object) GstVaapiVideoConverterGLXPrivate * const priv = GST_VAAPI_VIDEO_CONVERTER_GLX(object)->priv; - g_clear_object(&priv->texture); + gst_vaapi_texture_replace(&priv->texture, NULL); G_OBJECT_CLASS(gst_vaapi_video_converter_glx_parent_class)->dispose(object); } @@ -144,7 +144,7 @@ gst_vaapi_video_converter_glx_upload(GstSurfaceConverter *self, if (old_dpy != new_dpy) { const guint texture = gst_vaapi_texture_get_id(priv->texture); - g_clear_object(&priv->texture); + gst_vaapi_texture_replace(&priv->texture, NULL); priv->texture = gst_vaapi_texture_new_with_texture(new_dpy, texture, GL_TEXTURE_2D, GL_BGRA); } diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 5a84629f2f..7551bfcd10 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -217,8 +217,8 @@ gst_vaapi_video_memory_new(GstAllocator *base_allocator, static void gst_vaapi_video_memory_free(GstVaapiVideoMemory *mem) { - g_clear_object(&mem->surface); - g_clear_object(&mem->image); + gst_vaapi_object_replace(&mem->surface, NULL); + gst_vaapi_object_replace(&mem->image, NULL); gst_vaapi_video_meta_unref(mem->meta); g_slice_free(GstVaapiVideoMemory, mem); } @@ -398,8 +398,8 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) GST_VIDEO_INFO_FORMAT_STRING(&allocator->surface_info), allocator->has_direct_rendering ? "yes" : "no"); } while (0); - g_clear_object(&surface); - g_clear_object(&image); + gst_vaapi_object_unref(surface); + gst_vaapi_object_unref(image); } allocator->image_info = *vip; @@ -419,7 +419,7 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) gst_video_info_update_from_image(&allocator->image_info, image); gst_vaapi_image_unmap(image); } while (0); - g_clear_object(&image); + gst_vaapi_object_unref(image); } return GST_ALLOCATOR_CAST(allocator); } diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index a6f4a1442c..fe41db3097 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -48,26 +48,23 @@ struct _GstVaapiVideoMeta { guint render_flags; }; -static void +static inline void set_display(GstVaapiVideoMeta *meta, GstVaapiDisplay *display) { - g_clear_object(&meta->display); - - if (display) - meta->display = g_object_ref(display); + gst_vaapi_display_replace(&meta->display, display); } static inline void set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image) { - meta->image = g_object_ref(image); + meta->image = gst_vaapi_object_ref(image); set_display(meta, gst_vaapi_object_get_display(GST_VAAPI_OBJECT(image))); } static inline void set_surface(GstVaapiVideoMeta *meta, GstVaapiSurface *surface) { - meta->surface = g_object_ref(surface); + meta->surface = gst_vaapi_object_ref(surface); set_display(meta, gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface))); } @@ -77,10 +74,10 @@ gst_vaapi_video_meta_destroy_image(GstVaapiVideoMeta *meta) if (meta->image) { if (meta->image_pool) gst_vaapi_video_pool_put_object(meta->image_pool, meta->image); - g_object_unref(meta->image); + gst_vaapi_object_unref(meta->image); meta->image = NULL; } - g_clear_object(&meta->image_pool); + gst_vaapi_video_pool_replace(&meta->image_pool, NULL); } static void @@ -91,10 +88,10 @@ gst_vaapi_video_meta_destroy_surface(GstVaapiVideoMeta *meta) if (meta->surface) { if (meta->surface_pool) gst_vaapi_video_pool_put_object(meta->surface_pool, meta->surface); - g_object_unref(meta->surface); + gst_vaapi_object_unref(meta->surface); meta->surface = NULL; } - g_clear_object(&meta->surface_pool); + gst_vaapi_video_pool_replace(&meta->surface_pool, NULL); } #if !GST_CHECK_VERSION(1,0,0) @@ -120,7 +117,7 @@ gst_vaapi_video_meta_finalize(GstVaapiVideoMeta *meta) { gst_vaapi_video_meta_destroy_image(meta); gst_vaapi_video_meta_destroy_surface(meta); - g_clear_object(&meta->display); + gst_vaapi_display_replace(&meta->display, NULL); } static void @@ -197,11 +194,11 @@ gst_vaapi_video_meta_copy(GstVaapiVideoMeta *meta) return NULL; copy->ref_count = 1; - copy->display = g_object_ref(meta->display); + copy->display = gst_vaapi_display_ref(meta->display); copy->image_pool = NULL; - copy->image = meta->image ? g_object_ref(meta->image) : NULL; + copy->image = meta->image ? gst_vaapi_object_ref(meta->image) : NULL; copy->surface_pool = NULL; - copy->surface = meta->surface ? g_object_ref(meta->surface) : NULL; + copy->surface = meta->surface ? gst_vaapi_object_ref(meta->surface) : NULL; copy->proxy = meta->proxy ? gst_vaapi_surface_proxy_ref(meta->proxy) : NULL; copy->converter = meta->converter; @@ -447,7 +444,7 @@ gst_vaapi_video_meta_get_display(GstVaapiVideoMeta *meta) * * Retrieves the #GstVaapiImage bound to the @meta. The @meta owns * the #GstVaapiImage so the caller is responsible for calling - * g_object_ref() when needed. + * gst_vaapi_object_ref() when needed. * * Return value: the #GstVaapiImage bound to the @meta, or %NULL if * there is none @@ -507,7 +504,7 @@ gst_vaapi_video_meta_set_image_from_pool(GstVaapiVideoMeta *meta, if (!image) return FALSE; set_image(meta, image); - meta->image_pool = g_object_ref(pool); + meta->image_pool = gst_vaapi_video_pool_ref(pool); } return TRUE; } @@ -518,7 +515,7 @@ gst_vaapi_video_meta_set_image_from_pool(GstVaapiVideoMeta *meta, * * Retrieves the #GstVaapiSurface bound to the @meta. The @meta * owns the #GstVaapiSurface so the caller is responsible for calling - * g_object_ref() when needed. + * gst_vaapi_object_ref() when needed. * * Return value: the #GstVaapiSurface bound to the @meta, or %NULL if * there is none @@ -579,7 +576,7 @@ gst_vaapi_video_meta_set_surface_from_pool(GstVaapiVideoMeta *meta, if (!surface) return FALSE; set_surface(meta, surface); - meta->surface_pool = g_object_ref(pool); + meta->surface_pool = gst_vaapi_video_pool_ref(pool); } return TRUE; } @@ -590,7 +587,7 @@ gst_vaapi_video_meta_set_surface_from_pool(GstVaapiVideoMeta *meta, * * Retrieves the #GstVaapiSurfaceProxy bound to the @meta. The @meta * owns the #GstVaapiSurfaceProxy so the caller is responsible for calling - * g_object_ref() when needed. + * gst_surface_proxy_ref() when needed. * * Return value: the #GstVaapiSurfaceProxy bound to the @meta, or * %NULL if there is none From 85d50c1c6301e4f5baa45074034264dd62779f6e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 7 May 2013 18:37:24 +0200 Subject: [PATCH 1187/3781] docs: cope with removed APIs. Some APIs are dead because they are no longer based on GObject. --- docs/reference/libs/Makefile.am | 17 +-- docs/reference/libs/libs-docs.xml.in | 2 - docs/reference/libs/libs-sections.txt | 161 -------------------------- docs/reference/libs/libs.core.types | 11 -- docs/reference/libs/libs.glx.types | 3 - docs/reference/libs/libs.x11.types | 2 - 6 files changed, 2 insertions(+), 194 deletions(-) delete mode 100644 docs/reference/libs/libs.core.types delete mode 100644 docs/reference/libs/libs.glx.types delete mode 100644 docs/reference/libs/libs.x11.types diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index 3183fa66b6..bda6fe62dd 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -24,11 +24,7 @@ DOC_SOURCE_DIR = $(top_srcdir)/gst-libs/gst/vaapi SCANGOBJ_OPTIONS = --type-init-func="g_type_init()" # List files used by scanobj -SCANOBJ_TYPES = $(srcdir)/$(DOC_MODULE).core.types -SCANOBJ_TYPES += $(srcdir)/$(DOC_MODULE).x11.types -if USE_GLX -SCANOBJ_TYPES += $(srcdir)/$(DOC_MODULE).glx.types -endif +SCANOBJ_TYPES = # Extra options to supply to gtkdoc-scan. # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" @@ -54,7 +50,7 @@ FIXXREF_OPTIONS = \ # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c HFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.h -CFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.c $(srcdir)/$(DOC_MODULE).types +CFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.c # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h @@ -118,9 +114,6 @@ GTKDOC_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la endif -$(srcdir)/$(DOC_MODULE).types: $(SCANOBJ_TYPES) - cat $(SCANOBJ_TYPES) > $@ - # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make @@ -128,13 +121,7 @@ include $(top_srcdir)/gtk-doc.make # e.g. EXTRA_DIST += version.xml.in EXTRA_DIST += \ libs-docs.xml.in \ - libs.core.types \ - libs.x11.types \ - libs.glx.types \ $(NULL) -DISTCLEANFILES = $(srcdir)/$(DOC_MODULE).types -BUILT_SOURCES = $(srcdir)/$(DOC_MODULE).types - # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in lib-docs.xml diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 17c41a2b23..ea7617a001 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -9,8 +9,6 @@ gst-plugins-vaapi Library - - diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 1b26099096..7f4fcba311 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -2,23 +2,17 @@ gstvaapisurfacepool GstVaapiSurfacePool GstVaapiSurfacePool -GstVaapiSurfacePoolClass gst_vaapi_surface_pool_new GST_VAAPI_SURFACE_POOL GST_VAAPI_IS_SURFACE_POOL -GST_VAAPI_TYPE_SURFACE_POOL gst_vaapi_surface_pool_get_type -GST_VAAPI_SURFACE_POOL_CLASS -GST_VAAPI_IS_SURFACE_POOL_CLASS -GST_VAAPI_SURFACE_POOL_GET_CLASS
gstvaapivideopool GstVaapiVideoPool GstVaapiVideoPool -GstVaapiVideoPoolClass gst_vaapi_video_pool_get_display gst_vaapi_video_pool_get_object gst_vaapi_video_pool_put_object @@ -31,18 +25,12 @@ gst_vaapi_video_pool_reserve GST_VAAPI_VIDEO_POOL GST_VAAPI_IS_VIDEO_POOL -GST_VAAPI_TYPE_VIDEO_POOL -gst_vaapi_video_pool_get_type -GST_VAAPI_VIDEO_POOL_CLASS -GST_VAAPI_IS_VIDEO_POOL_CLASS -GST_VAAPI_VIDEO_POOL_GET_CLASS
gstvaapidisplay_x11 GstVaapiDisplayX11 GstVaapiDisplayX11 -GstVaapiDisplayX11Class gst_vaapi_display_x11_new gst_vaapi_display_x11_new_with_display gst_vaapi_display_x11_get_display @@ -50,18 +38,12 @@ gst_vaapi_display_x11_get_screen GST_VAAPI_DISPLAY_X11 GST_VAAPI_IS_DISPLAY_X11 -GST_VAAPI_TYPE_DISPLAY_X11 -gst_vaapi_display_x11_get_type -GST_VAAPI_DISPLAY_X11_CLASS -GST_VAAPI_IS_DISPLAY_X11_CLASS -GST_VAAPI_DISPLAY_X11_GET_CLASS
gstvaapiwindow_x11 GstVaapiWindowX11 GstVaapiWindowX11 -GstVaapiWindowX11Class GST_VAAPI_WINDOW_XWINDOW gst_vaapi_window_x11_new gst_vaapi_window_x11_new_with_xid @@ -70,35 +52,23 @@ gst_vaapi_window_x11_is_foreign_xid GST_VAAPI_WINDOW_X11 GST_VAAPI_IS_WINDOW_X11 -GST_VAAPI_TYPE_WINDOW_X11 -gst_vaapi_window_x11_get_type -GST_VAAPI_WINDOW_X11_CLASS -GST_VAAPI_IS_WINDOW_X11_CLASS -GST_VAAPI_WINDOW_X11_GET_CLASS
gstvaapidisplay_glx GstVaapiDisplayGLX GstVaapiDisplayGLX -GstVaapiDisplayGLXClass gst_vaapi_display_glx_new gst_vaapi_display_glx_new_with_display GST_VAAPI_DISPLAY_GLX GST_VAAPI_IS_DISPLAY_GLX -GST_VAAPI_TYPE_DISPLAY_GLX -gst_vaapi_display_glx_get_type -GST_VAAPI_DISPLAY_GLX_CLASS -GST_VAAPI_IS_DISPLAY_GLX_CLASS -GST_VAAPI_DISPLAY_GLX_GET_CLASS
gstvaapiwindow_glx GstVaapiWindowGLX GstVaapiWindowGLX -GstVaapiWindowGLXClass gst_vaapi_window_glx_new gst_vaapi_window_glx_new_with_xid gst_vaapi_window_glx_get_context @@ -108,19 +78,12 @@ gst_vaapi_window_glx_swap_buffers gst_vaapi_window_glx_put_texture GST_VAAPI_WINDOW_GLX -GST_VAAPI_IS_WINDOW_GLX -GST_VAAPI_TYPE_WINDOW_GLX -gst_vaapi_window_glx_get_type -GST_VAAPI_WINDOW_GLX_CLASS -GST_VAAPI_IS_WINDOW_GLX_CLASS -GST_VAAPI_WINDOW_GLX_GET_CLASS
gstvaapidisplay GstVaapiDisplay GstVaapiDisplay -GstVaapiDisplayClass gst_vaapi_display_new_with_display gst_vaapi_display_lock gst_vaapi_display_unlock @@ -147,27 +110,16 @@ gst_vaapi_display_set_render_mode GST_VAAPI_DISPLAY GST_VAAPI_IS_DISPLAY -GST_VAAPI_TYPE_DISPLAY -gst_vaapi_display_get_type -GST_VAAPI_DISPLAY_CLASS -GST_VAAPI_IS_DISPLAY_CLASS -GST_VAAPI_DISPLAY_GET_CLASS
gstvaapiimagepool GstVaapiImagePool GstVaapiImagePool -GstVaapiImagePoolClass gst_vaapi_image_pool_new GST_VAAPI_IMAGE_POOL GST_VAAPI_IS_IMAGE_POOL -GST_VAAPI_TYPE_IMAGE_POOL -gst_vaapi_image_pool_get_type -GST_VAAPI_IMAGE_POOL_CLASS -GST_VAAPI_IS_IMAGE_POOL_CLASS -GST_VAAPI_IMAGE_POOL_GET_CLASS
@@ -176,32 +128,14 @@ GST_VAAPI_IMAGE_POOL_GET_CLASS GstVaapiID GST_VAAPI_ID_FORMAT GST_VAAPI_ID_ARGS -GST_VAAPI_ID -GST_VAAPI_ID_NONE GstVaapiPoint GstVaapiRectangle
-
-gstvaapivalue - -GST_VAAPI_TYPE_ID -gst_vaapi_value_get_id -gst_vaapi_value_set_id -
- -
-gstvaapiparamspecs - -GstVaapiParamSpecID -gst_vaapi_param_spec_id -
-
gstvaapiwindow GstVaapiWindow GstVaapiWindow -GstVaapiWindowClass gst_vaapi_window_get_display gst_vaapi_window_show gst_vaapi_window_hide @@ -217,18 +151,12 @@ gst_vaapi_window_put_surface GST_VAAPI_WINDOW GST_VAAPI_IS_WINDOW -GST_VAAPI_TYPE_WINDOW -gst_vaapi_window_get_type -GST_VAAPI_WINDOW_CLASS -GST_VAAPI_IS_WINDOW_CLASS -GST_VAAPI_WINDOW_GET_CLASS
gstvaapiobject GstVaapiObject GstVaapiObject -GstVaapiObjectClass gst_vaapi_object_get_display gst_vaapi_object_lock_display gst_vaapi_object_unlock_display @@ -236,11 +164,6 @@ gst_vaapi_object_get_id GST_VAAPI_OBJECT GST_VAAPI_IS_OBJECT -GST_VAAPI_TYPE_OBJECT -gst_vaapi_object_get_type -GST_VAAPI_OBJECT_CLASS -GST_VAAPI_IS_OBJECT_CLASS -GST_VAAPI_OBJECT_GET_CLASS
@@ -250,7 +173,6 @@ GST_VAAPI_IMAGE_WIDTH GST_VAAPI_IMAGE_HEIGHT GstVaapiImage GstVaapiImage -GstVaapiImageClass gst_vaapi_image_new gst_vaapi_image_new_with_image gst_vaapi_image_get_id @@ -273,11 +195,6 @@ gst_vaapi_image_update_from_buffer GST_VAAPI_IMAGE GST_VAAPI_IS_IMAGE -GST_VAAPI_TYPE_IMAGE -gst_vaapi_image_get_type -GST_VAAPI_IMAGE_CLASS -GST_VAAPI_IS_IMAGE_CLASS -GST_VAAPI_IMAGE_GET_CLASS
@@ -287,7 +204,6 @@ GstVaapiSurfaceStatus GstVaapiSurfaceRenderFlags GstVaapiSurface GstVaapiSurface -GstVaapiSurfaceClass gst_vaapi_surface_new gst_vaapi_surface_get_id gst_vaapi_surface_get_chroma_type @@ -304,18 +220,12 @@ gst_vaapi_surface_query_status GST_VAAPI_SURFACE GST_VAAPI_IS_SURFACE -GST_VAAPI_TYPE_SURFACE -gst_vaapi_surface_get_type -GST_VAAPI_SURFACE_CLASS -GST_VAAPI_IS_SURFACE_CLASS -GST_VAAPI_SURFACE_GET_CLASS
gstvaapisubpicture GstVaapiSubpicture GstVaapiSubpicture -GstVaapiSubpictureClass gst_vaapi_subpicture_new gst_vaapi_subpicture_new_from_overlay_rectangle gst_vaapi_subpicture_get_id @@ -327,11 +237,6 @@ gst_vaapi_subpicture_set_image GST_VAAPI_SUBPICTURE GST_VAAPI_IS_SUBPICTURE -GST_VAAPI_TYPE_SUBPICTURE -gst_vaapi_subpicture_get_type -GST_VAAPI_SUBPICTURE_CLASS -GST_VAAPI_IS_SUBPICTURE_CLASS -GST_VAAPI_SUBPICTURE_GET_CLASS
@@ -368,7 +273,6 @@ gst_vaapi_entrypoint_get_va_entrypoint gstvaapitexture GstVaapiTexture GstVaapiTexture -GstVaapiTextureClass gst_vaapi_texture_new gst_vaapi_texture_new_with_texture gst_vaapi_texture_get_id @@ -378,21 +282,12 @@ gst_vaapi_texture_get_width gst_vaapi_texture_get_height gst_vaapi_texture_get_size gst_vaapi_texture_put_surface - -GST_VAAPI_TEXTURE -GST_VAAPI_IS_TEXTURE -GST_VAAPI_TYPE_TEXTURE -gst_vaapi_texture_get_type -GST_VAAPI_TEXTURE_CLASS -GST_VAAPI_IS_TEXTURE_CLASS -GST_VAAPI_TEXTURE_GET_CLASS
gstvaapicontext GstVaapiContext GstVaapiContext -GstVaapiContextClass gst_vaapi_context_new gst_vaapi_context_reset gst_vaapi_context_get_id @@ -406,11 +301,6 @@ gst_vaapi_context_apply_composition GST_VAAPI_CONTEXT GST_VAAPI_IS_CONTEXT -GST_VAAPI_TYPE_CONTEXT -gst_vaapi_context_get_type -GST_VAAPI_CONTEXT_CLASS -GST_VAAPI_IS_CONTEXT_CLASS -GST_VAAPI_CONTEXT_GET_CLASS
@@ -418,7 +308,6 @@ GST_VAAPI_CONTEXT_GET_CLASS GstVaapiDecoderStatus GstVaapiDecoder GstVaapiDecoder -GstVaapiDecoderClass gst_vaapi_decoder_get_caps gst_vaapi_decoder_get_codec gst_vaapi_decoder_get_codec_state @@ -431,91 +320,41 @@ gst_vaapi_decoder_decode GST_VAAPI_DECODER GST_VAAPI_IS_DECODER -GST_VAAPI_TYPE_DECODER -gst_vaapi_decoder_get_type -GST_VAAPI_DECODER_CLASS -GST_VAAPI_IS_DECODER_CLASS -GST_VAAPI_DECODER_GET_CLASS
gstvaapidecoder_jpeg GstVaapiDecoderJpeg GstVaapiDecoderJpeg -GstVaapiDecoderJpegClass gst_vaapi_decoder_jpeg_new - -GST_VAAPI_DECODER_JPEG -GST_VAAPI_IS_DECODER_JPEG -GST_VAAPI_TYPE_DECODER_JPEG -gst_vaapi_decoder_jpeg_get_type -GST_VAAPI_DECODER_JPEG_CLASS -GST_VAAPI_IS_DECODER_JPEG_CLASS -GST_VAAPI_DECODER_JPEG_GET_CLASS
gstvaapidecoder_mpeg2 GstVaapiDecoderMpeg2 GstVaapiDecoderMpeg2 -GstVaapiDecoderMpeg2Class gst_vaapi_decoder_mpeg2_new - -GST_VAAPI_DECODER_MPEG2 -GST_VAAPI_IS_DECODER_MPEG2 -GST_VAAPI_TYPE_DECODER_MPEG2 -gst_vaapi_decoder_mpeg2_get_type -GST_VAAPI_DECODER_MPEG2_CLASS -GST_VAAPI_IS_DECODER_MPEG2_CLASS -GST_VAAPI_DECODER_MPEG2_GET_CLASS
gstvaapidecoder_mpeg4 GstVaapiDecoderMpeg4 GstVaapiDecoderMpeg4 -GstVaapiDecoderMpeg4Class gst_vaapi_decoder_mpeg4_new - -GST_VAAPI_DECODER_MPEG4 -GST_VAAPI_IS_DECODER_MPEG4 -GST_VAAPI_TYPE_DECODER_MPEG4 -gst_vaapi_decoder_mpeg4_get_type -GST_VAAPI_DECODER_MPEG4_CLASS -GST_VAAPI_IS_DECODER_MPEG4_CLASS -GST_VAAPI_DECODER_MPEG4_GET_CLASS
gstvaapidecoder_h264 GstVaapiDecoderH264 GstVaapiDecoderH264 -GstVaapiDecoderH264Class gst_vaapi_decoder_h264_new - -GST_VAAPI_DECODER_H264 -GST_VAAPI_IS_DECODER_H264 -GST_VAAPI_TYPE_DECODER_H264 -gst_vaapi_decoder_h264_get_type -GST_VAAPI_DECODER_H264_CLASS -GST_VAAPI_IS_DECODER_H264_CLASS -GST_VAAPI_DECODER_H264_GET_CLASS
gstvaapidecoder_vc1 GstVaapiDecoderVC1 GstVaapiDecoderVC1 -GstVaapiDecoderVC1Class gst_vaapi_decoder_vc1_new - -GST_VAAPI_DECODER_VC1 -GST_VAAPI_IS_DECODER_VC1 -GST_VAAPI_TYPE_DECODER_VC1 -gst_vaapi_decoder_vc1_get_type -GST_VAAPI_DECODER_VC1_CLASS -GST_VAAPI_IS_DECODER_VC1_CLASS -GST_VAAPI_DECODER_VC1_GET_CLASS
diff --git a/docs/reference/libs/libs.core.types b/docs/reference/libs/libs.core.types deleted file mode 100644 index 97954cf3ef..0000000000 --- a/docs/reference/libs/libs.core.types +++ /dev/null @@ -1,11 +0,0 @@ -gst_vaapi_context_get_type -gst_vaapi_decoder_get_type -gst_vaapi_display_get_type -gst_vaapi_image_get_type -gst_vaapi_image_pool_get_type -gst_vaapi_object_get_type -gst_vaapi_subpicture_get_type -gst_vaapi_surface_get_type -gst_vaapi_surface_pool_get_type -gst_vaapi_video_pool_get_type -gst_vaapi_window_get_type diff --git a/docs/reference/libs/libs.glx.types b/docs/reference/libs/libs.glx.types deleted file mode 100644 index 6ecd3545e8..0000000000 --- a/docs/reference/libs/libs.glx.types +++ /dev/null @@ -1,3 +0,0 @@ -gst_vaapi_display_glx_get_type -gst_vaapi_texture_get_type -gst_vaapi_window_glx_get_type diff --git a/docs/reference/libs/libs.x11.types b/docs/reference/libs/libs.x11.types deleted file mode 100644 index c083ce07d4..0000000000 --- a/docs/reference/libs/libs.x11.types +++ /dev/null @@ -1,2 +0,0 @@ -gst_vaapi_display_x11_get_type -gst_vaapi_window_x11_get_type From f77e1642dc2bd0001d78721ecd6bac9437ecd11b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 7 May 2013 18:52:28 +0200 Subject: [PATCH 1188/3781] Bump library major version. The whole libgstvaapi libraries got a major refresh to get rid of GObject. This is a fundamental change that requires a new SONAME. More changes are underway to streamline the core libraries. So far, the net result is a reduction of .text size (code) by 32KB, i.e. -10%. On one particular test (sintel HD trailer), the total number of executed instruction was reduced by 8%. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 9e6109dd18..3380626a2d 100644 --- a/configure.ac +++ b/configure.ac @@ -10,7 +10,7 @@ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) ]) # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [2]) +m4_define([gst_vaapi_lt_current], [3]) m4_define([gst0_vaapi_lt_current_bias], [0]) m4_define([gst1_vaapi_lt_current_bias], [2]) m4_define([gst_vaapi_lt_revision], [0]) From 67eea920446b332a451e0d6dcb62c2374ac87634 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 May 2013 18:15:48 +0200 Subject: [PATCH 1189/3781] libs: drop GST_VAAPI_IS_xxx() helper macros. Drop obsolete GST_VAAPI_IS_xxx() helper macros since we are no longer deriving from GObject and so those were only checking for whether the argument was NULL or not. This is now irrelevant, and even confusing to some extent, because we no longer have type checking. Note: this incurs more type checking (review) but the libgstvaapi is rather small, so this is manageable. --- docs/reference/libs/libs-sections.txt | 14 ------ gst-libs/gst/vaapi/gstvaapicontext.c | 16 +++--- gst-libs/gst/vaapi/gstvaapicontext.h | 3 -- gst-libs/gst/vaapi/gstvaapidecoder.c | 24 ++++----- gst-libs/gst/vaapi/gstvaapidecoder.h | 3 -- gst-libs/gst/vaapi/gstvaapidisplay.c | 49 +++++++++---------- gst-libs/gst/vaapi/gstvaapidisplay.h | 3 -- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 4 +- gst-libs/gst/vaapi/gstvaapidisplay_drm.h | 3 -- gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 3 -- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_wayland.h | 3 -- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 6 +-- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 3 -- gst-libs/gst/vaapi/gstvaapiimage.c | 36 +++++++------- gst-libs/gst/vaapi/gstvaapiimage.h | 3 -- gst-libs/gst/vaapi/gstvaapiimagepool.c | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.h | 3 -- gst-libs/gst/vaapi/gstvaapiobject.c | 10 ++-- gst-libs/gst/vaapi/gstvaapiobject.h | 3 -- gst-libs/gst/vaapi/gstvaapisubpicture.c | 16 +++--- gst-libs/gst/vaapi/gstvaapisubpicture.h | 3 -- gst-libs/gst/vaapi/gstvaapisurface.c | 38 +++++++------- gst-libs/gst/vaapi/gstvaapisurface.h | 3 -- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 3 -- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 18 +++---- .../gst/vaapi/gstvaapisurfaceproxy_priv.h | 3 -- gst-libs/gst/vaapi/gstvaapitexture.c | 6 +-- gst-libs/gst/vaapi/gstvaapivideopool.c | 22 ++++----- gst-libs/gst/vaapi/gstvaapivideopool.h | 3 -- gst-libs/gst/vaapi/gstvaapiwindow.c | 26 +++++----- gst-libs/gst/vaapi/gstvaapiwindow.h | 3 -- gst-libs/gst/vaapi/gstvaapiwindow_drm.h | 3 -- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 13 ++--- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 4 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 3 -- 37 files changed, 145 insertions(+), 217 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 7f4fcba311..423704c1e9 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -5,7 +5,6 @@ GstVaapiSurfacePool gst_vaapi_surface_pool_new GST_VAAPI_SURFACE_POOL -GST_VAAPI_IS_SURFACE_POOL gst_vaapi_surface_pool_get_type
@@ -24,7 +23,6 @@ gst_vaapi_video_pool_get_size gst_vaapi_video_pool_reserve GST_VAAPI_VIDEO_POOL -GST_VAAPI_IS_VIDEO_POOL
@@ -37,7 +35,6 @@ gst_vaapi_display_x11_get_display gst_vaapi_display_x11_get_screen GST_VAAPI_DISPLAY_X11 -GST_VAAPI_IS_DISPLAY_X11
@@ -51,7 +48,6 @@ gst_vaapi_window_x11_get_xid gst_vaapi_window_x11_is_foreign_xid GST_VAAPI_WINDOW_X11 -GST_VAAPI_IS_WINDOW_X11
@@ -62,7 +58,6 @@ gst_vaapi_display_glx_new gst_vaapi_display_glx_new_with_display GST_VAAPI_DISPLAY_GLX -GST_VAAPI_IS_DISPLAY_GLX
@@ -109,7 +104,6 @@ gst_vaapi_display_get_render_mode gst_vaapi_display_set_render_mode GST_VAAPI_DISPLAY -GST_VAAPI_IS_DISPLAY
@@ -119,7 +113,6 @@ GstVaapiImagePool gst_vaapi_image_pool_new GST_VAAPI_IMAGE_POOL -GST_VAAPI_IS_IMAGE_POOL
@@ -150,7 +143,6 @@ gst_vaapi_window_set_size gst_vaapi_window_put_surface GST_VAAPI_WINDOW -GST_VAAPI_IS_WINDOW
@@ -163,7 +155,6 @@ gst_vaapi_object_unlock_display gst_vaapi_object_get_id GST_VAAPI_OBJECT -GST_VAAPI_IS_OBJECT
@@ -194,7 +185,6 @@ gst_vaapi_image_get_raw gst_vaapi_image_update_from_buffer GST_VAAPI_IMAGE -GST_VAAPI_IS_IMAGE
@@ -219,7 +209,6 @@ gst_vaapi_surface_sync gst_vaapi_surface_query_status GST_VAAPI_SURFACE -GST_VAAPI_IS_SURFACE
@@ -236,7 +225,6 @@ gst_vaapi_subpicture_get_image gst_vaapi_subpicture_set_image GST_VAAPI_SUBPICTURE -GST_VAAPI_IS_SUBPICTURE
@@ -300,7 +288,6 @@ gst_vaapi_context_get_surface_count gst_vaapi_context_apply_composition GST_VAAPI_CONTEXT -GST_VAAPI_IS_CONTEXT
@@ -319,7 +306,6 @@ gst_vaapi_decoder_parse gst_vaapi_decoder_decode GST_VAAPI_DECODER -GST_VAAPI_IS_DECODER
diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 174e809a58..a132e82746 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -788,7 +788,7 @@ gst_vaapi_context_reset_full(GstVaapiContext *context, GstVaapiID gst_vaapi_context_get_id(GstVaapiContext *context) { - g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), VA_INVALID_ID); + g_return_val_if_fail(context != NULL, VA_INVALID_ID); return GST_VAAPI_OBJECT_ID(context); } @@ -804,7 +804,7 @@ gst_vaapi_context_get_id(GstVaapiContext *context) GstVaapiProfile gst_vaapi_context_get_profile(GstVaapiContext *context) { - g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0); + g_return_val_if_fail(context != NULL, 0); return context->info.profile; } @@ -824,7 +824,7 @@ gst_vaapi_context_get_profile(GstVaapiContext *context) gboolean gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile) { - g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE); + g_return_val_if_fail(context != NULL, FALSE); g_return_val_if_fail(profile, FALSE); return gst_vaapi_context_reset(context, @@ -845,7 +845,7 @@ gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile) GstVaapiEntrypoint gst_vaapi_context_get_entrypoint(GstVaapiContext *context) { - g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0); + g_return_val_if_fail(context != NULL, 0); return context->info.entrypoint; } @@ -865,7 +865,7 @@ gst_vaapi_context_get_size( guint *pheight ) { - g_return_if_fail(GST_VAAPI_IS_CONTEXT(context)); + g_return_if_fail(context != NULL); if (pwidth) *pwidth = context->info.width; @@ -892,7 +892,7 @@ gst_vaapi_context_get_size( GstVaapiSurfaceProxy * gst_vaapi_context_get_surface_proxy(GstVaapiContext *context) { - g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL); + g_return_val_if_fail(context != NULL, NULL); return gst_vaapi_surface_proxy_new_from_pool( GST_VAAPI_SURFACE_POOL(context->surfaces_pool)); @@ -909,7 +909,7 @@ gst_vaapi_context_get_surface_proxy(GstVaapiContext *context) guint gst_vaapi_context_get_surface_count(GstVaapiContext *context) { - g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0); + g_return_val_if_fail(context != NULL, 0); return gst_vaapi_video_pool_get_size(context->surfaces_pool); } @@ -937,7 +937,7 @@ gst_vaapi_context_apply_composition( guint i, n_rectangles; gboolean reassociate = FALSE; - g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE); + g_return_val_if_fail(context != NULL, FALSE); if (!context->surfaces) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 82f11461f1..2414e9da92 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -34,9 +34,6 @@ G_BEGIN_DECLS #define GST_VAAPI_CONTEXT(obj) \ ((GstVaapiContext *)(obj)) -#define GST_VAAPI_IS_CONTEXT(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiContext GstVaapiContext; typedef struct _GstVaapiContextInfo GstVaapiContextInfo; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index c11b0f6a2f..787029195b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -516,7 +516,7 @@ gst_vaapi_decoder_new(const GstVaapiDecoderClass *klass, { GstVaapiDecoder *decoder; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); g_return_val_if_fail(GST_IS_CAPS(caps), NULL); decoder = (GstVaapiDecoder *) @@ -587,7 +587,7 @@ gst_vaapi_decoder_replace(GstVaapiDecoder **old_decoder_ptr, gpointer gst_vaapi_decoder_get_user_data(GstVaapiDecoder *decoder) { - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + g_return_val_if_fail(decoder != NULL, NULL); return decoder->user_data; } @@ -603,7 +603,7 @@ gst_vaapi_decoder_get_user_data(GstVaapiDecoder *decoder) void gst_vaapi_decoder_set_user_data(GstVaapiDecoder *decoder, gpointer user_data) { - g_return_if_fail(GST_VAAPI_IS_DECODER(decoder)); + g_return_if_fail(decoder != NULL); decoder->user_data = user_data; } @@ -619,7 +619,7 @@ gst_vaapi_decoder_set_user_data(GstVaapiDecoder *decoder, gpointer user_data) GstVaapiCodec gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder) { - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), (GstVaapiCodec)0); + g_return_val_if_fail(decoder != NULL, (GstVaapiCodec)0); return decoder->codec; } @@ -637,7 +637,7 @@ gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder) GstVideoCodecState * gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder) { - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + g_return_val_if_fail(decoder != NULL, NULL); return GST_VAAPI_DECODER_CODEC_STATE(decoder); } @@ -655,7 +655,7 @@ void gst_vaapi_decoder_set_codec_state_changed_func(GstVaapiDecoder *decoder, GstVaapiDecoderStateChangedFunc func, gpointer user_data) { - g_return_if_fail(GST_VAAPI_IS_DECODER(decoder)); + g_return_if_fail(decoder != NULL); decoder->codec_state_changed_func = func; decoder->codec_state_changed_data = user_data; @@ -694,7 +694,7 @@ gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder) gboolean gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf) { - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); + g_return_val_if_fail(decoder != NULL, FALSE); if (buf) { if (gst_buffer_get_size(buf) == 0) @@ -725,7 +725,7 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame; GstVaapiDecoderStatus status; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), + g_return_val_if_fail(decoder != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); g_return_val_if_fail(out_proxy_ptr != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); @@ -802,7 +802,7 @@ gst_vaapi_decoder_get_frame_with_timeout(GstVaapiDecoder *decoder, { GstVideoCodecFrame *out_frame; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), + g_return_val_if_fail(decoder != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); g_return_val_if_fail(out_frame_ptr != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); @@ -982,7 +982,7 @@ gst_vaapi_decoder_parse(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame, GstAdapter *adapter, gboolean at_eos, guint *got_unit_size_ptr, gboolean *got_frame_ptr) { - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), + g_return_val_if_fail(decoder != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); g_return_val_if_fail(base_frame != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); @@ -1002,7 +1002,7 @@ gst_vaapi_decoder_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) { GstVaapiDecoderStatus status; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), + g_return_val_if_fail(decoder != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); g_return_val_if_fail(frame != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); @@ -1018,7 +1018,7 @@ gst_vaapi_decoder_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) GstVaapiDecoderStatus gst_vaapi_decoder_flush(GstVaapiDecoder *decoder) { - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), + g_return_val_if_fail(decoder != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); return do_flush(decoder); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index e2854f3920..6dbcb5b83d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -34,9 +34,6 @@ G_BEGIN_DECLS #define GST_VAAPI_DECODER(obj) \ ((GstVaapiDecoder *)(obj)) -#define GST_VAAPI_IS_DECODER(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiDecoder GstVaapiDecoder; typedef void (*GstVaapiDecoderStateChangedFunc)(GstVaapiDecoder *decoder, const GstVideoCodecState *codec_state, gpointer user_data); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index a8b4e9967b..919f24bd1f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1071,7 +1071,7 @@ gst_vaapi_display_lock(GstVaapiDisplay *display) { GstVaapiDisplayClass *klass; - g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); + g_return_if_fail(display != NULL); klass = GST_VAAPI_DISPLAY_GET_CLASS(display); if (klass->lock) @@ -1091,7 +1091,7 @@ gst_vaapi_display_unlock(GstVaapiDisplay *display) { GstVaapiDisplayClass *klass; - g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); + g_return_if_fail(display != NULL); klass = GST_VAAPI_DISPLAY_GET_CLASS(display); if (klass->unlock) @@ -1114,7 +1114,7 @@ gst_vaapi_display_sync(GstVaapiDisplay *display) { GstVaapiDisplayClass *klass; - g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); + g_return_if_fail(display != NULL); klass = GST_VAAPI_DISPLAY_GET_CLASS(display); if (klass->sync) @@ -1137,7 +1137,7 @@ gst_vaapi_display_flush(GstVaapiDisplay *display) { GstVaapiDisplayClass *klass; - g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); + g_return_if_fail(display != NULL); klass = GST_VAAPI_DISPLAY_GET_CLASS(display); if (klass->flush) @@ -1155,8 +1155,7 @@ gst_vaapi_display_flush(GstVaapiDisplay *display) GstVaapiDisplayType gst_vaapi_display_get_display_type(GstVaapiDisplay *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), - GST_VAAPI_DISPLAY_TYPE_ANY); + g_return_val_if_fail(display != NULL, GST_VAAPI_DISPLAY_TYPE_ANY); return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->display_type; } @@ -1172,7 +1171,7 @@ gst_vaapi_display_get_display_type(GstVaapiDisplay *display) VADisplay gst_vaapi_display_get_display(GstVaapiDisplay *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->display; } @@ -1188,7 +1187,7 @@ gst_vaapi_display_get_display(GstVaapiDisplay *display) guint gst_vaapi_display_get_width(GstVaapiDisplay *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), 0); + g_return_val_if_fail(display != NULL, 0); return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->width; } @@ -1204,7 +1203,7 @@ gst_vaapi_display_get_width(GstVaapiDisplay *display) guint gst_vaapi_display_get_height(GstVaapiDisplay *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), 0); + g_return_val_if_fail(display != NULL, 0); return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->height; } @@ -1244,7 +1243,7 @@ gst_vaapi_display_get_pixel_aspect_ratio( guint *par_d ) { - g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); + g_return_if_fail(display != NULL); if (par_n) *par_n = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->par_n; @@ -1264,7 +1263,7 @@ gst_vaapi_display_get_pixel_aspect_ratio( GstCaps * gst_vaapi_display_get_decode_caps(GstVaapiDisplay *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); return get_profile_caps(GST_VAAPI_DISPLAY_GET_PRIVATE(display)->decoders); } @@ -1287,7 +1286,7 @@ gst_vaapi_display_has_decoder( GstVaapiEntrypoint entrypoint ) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(display != NULL, FALSE); return find_config( GST_VAAPI_DISPLAY_GET_PRIVATE(display)->decoders, profile, entrypoint); @@ -1304,7 +1303,7 @@ gst_vaapi_display_has_decoder( GstCaps * gst_vaapi_display_get_encode_caps(GstVaapiDisplay *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); return get_profile_caps(GST_VAAPI_DISPLAY_GET_PRIVATE(display)->encoders); } @@ -1327,7 +1326,7 @@ gst_vaapi_display_has_encoder( GstVaapiEntrypoint entrypoint ) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(display != NULL, FALSE); return find_config( GST_VAAPI_DISPLAY_GET_PRIVATE(display)->encoders, profile, entrypoint); @@ -1352,7 +1351,7 @@ gst_vaapi_display_has_encoder( GstCaps * gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); return get_format_caps( GST_VAAPI_DISPLAY_GET_PRIVATE(display)->image_formats); @@ -1373,7 +1372,7 @@ gst_vaapi_display_has_image_format( GstVaapiImageFormat format ) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(display != NULL, FALSE); g_return_val_if_fail(format, FALSE); if (find_format( @@ -1404,7 +1403,7 @@ gst_vaapi_display_has_image_format( GstCaps * gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); return get_format_caps( GST_VAAPI_DISPLAY_GET_PRIVATE(display)->subpicture_formats); @@ -1430,7 +1429,7 @@ gst_vaapi_display_has_subpicture_format( { const GstVaapiFormatInfo *fip; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(display != NULL, FALSE); g_return_val_if_fail(format, FALSE); fip = find_format_info( @@ -1458,7 +1457,7 @@ gst_vaapi_display_has_subpicture_format( gboolean gst_vaapi_display_has_property(GstVaapiDisplay *display, const gchar *name) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(display != NULL, FALSE); g_return_val_if_fail(name, FALSE); return find_property( @@ -1471,7 +1470,7 @@ gst_vaapi_display_get_property(GstVaapiDisplay *display, const gchar *name, { const GstVaapiProperty *prop; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(display != NULL, FALSE); g_return_val_if_fail(name != NULL, FALSE); g_return_val_if_fail(out_value != NULL, FALSE); @@ -1520,7 +1519,7 @@ gst_vaapi_display_set_property(GstVaapiDisplay *display, const gchar *name, { const GstVaapiProperty *prop; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(display != NULL, FALSE); g_return_val_if_fail(name != NULL, FALSE); g_return_val_if_fail(value != NULL, FALSE); @@ -1686,7 +1685,7 @@ gst_vaapi_display_get_render_mode( GstVaapiRenderMode *pmode ) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(display != NULL, FALSE); /* Try with render-mode attribute */ if (get_render_mode_VADisplayAttribRenderMode(display, pmode)) @@ -1720,7 +1719,7 @@ gst_vaapi_display_set_render_mode( { gint modes, devices; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(display != NULL, FALSE); if (!get_attribute(display, VADisplayAttribRenderDevice, &devices)) return FALSE; @@ -1762,7 +1761,7 @@ gst_vaapi_display_get_rotation(GstVaapiDisplay *display) { gint value; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), DEFAULT_ROTATION); + g_return_val_if_fail(display != NULL, DEFAULT_ROTATION); if (!get_attribute(display, VADisplayAttribRotation, &value)) value = VA_ROTATION_NONE; @@ -1790,7 +1789,7 @@ gst_vaapi_display_set_rotation( { guint value; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(display != NULL, FALSE); value = from_GstVaapiRotation(rotation); if (!set_attribute(display, VADisplayAttribRotation, value)) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index c5f392e7b8..ff6908765d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -34,9 +34,6 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY(obj) \ ((GstVaapiDisplay *)(obj)) -#define GST_VAAPI_IS_DISPLAY(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiDisplayInfo GstVaapiDisplayInfo; typedef struct _GstVaapiDisplay GstVaapiDisplay; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index da6235c369..641a8ed2b1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -417,7 +417,7 @@ gst_vaapi_display_drm_new_with_device(gint device) gint gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), -1); + g_return_val_if_fail(display != NULL, -1); return GST_VAAPI_DISPLAY_DRM_DEVICE(display); } @@ -438,7 +438,7 @@ gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display) const gchar * gst_vaapi_display_drm_get_device_path(GstVaapiDisplayDRM *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), NULL); + g_return_val_if_fail(display != NULL, NULL); return get_device_path(GST_VAAPI_DISPLAY_CAST(display)); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h index a0b10428d0..0d946cc879 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h @@ -29,9 +29,6 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_DRM(obj) \ ((GstVaapiDisplayDRM *)(obj)) -#define GST_VAAPI_IS_DISPLAY_DRM(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiDisplayDRM GstVaapiDisplayDRM; GstVaapiDisplay * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index cf318f5e94..bd46a8c7b5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -32,9 +32,6 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_GLX(obj) \ ((GstVaapiDisplayGLX *)(obj)) -#define GST_VAAPI_IS_DISPLAY_GLX(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiDisplayGLX GstVaapiDisplayGLX; GstVaapiDisplay * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 08e8cf844d..2d9c778c2b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -451,7 +451,7 @@ gst_vaapi_display_wayland_new_with_display(struct wl_display *wl_display) struct wl_display * gst_vaapi_display_wayland_get_display(GstVaapiDisplayWayland *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_WAYLAND(display), NULL); + g_return_val_if_fail(display != NULL, NULL); return GST_VAAPI_DISPLAY_WL_DISPLAY(display); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h index 3f1772888c..730a434aef 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h @@ -30,9 +30,6 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_WAYLAND(obj) \ ((GstVaapiDisplayWayland *)(obj)) -#define GST_VAAPI_IS_DISPLAY_WAYLAND(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiDisplayWayland GstVaapiDisplayWayland; GstVaapiDisplay * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index cad9251915..7cbc5a6a47 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -452,7 +452,7 @@ gst_vaapi_display_x11_new_with_display(Display *x11_display) Display * gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); + g_return_val_if_fail(display != NULL, NULL); return GST_VAAPI_DISPLAY_XDISPLAY(display); } @@ -470,7 +470,7 @@ gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) int gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), -1); + g_return_val_if_fail(display != NULL, -1); return GST_VAAPI_DISPLAY_XSCREEN(display); } @@ -490,7 +490,7 @@ void gst_vaapi_display_x11_set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous) { - g_return_if_fail(GST_VAAPI_IS_DISPLAY_X11(display)); + g_return_if_fail(display != NULL); set_synchronous(display, synchronous); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 68922232fa..5711095779 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -31,9 +31,6 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_X11(obj) \ ((GstVaapiDisplayX11 *)(obj)) -#define GST_VAAPI_IS_DISPLAY_X11(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11; GstVaapiDisplay * diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 3ed97c3069..72c04ff3ae 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -339,7 +339,7 @@ error: GstVaapiID gst_vaapi_image_get_id(GstVaapiImage *image) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID); + g_return_val_if_fail(image != NULL, VA_INVALID_ID); return GST_VAAPI_OBJECT_ID(image); } @@ -356,7 +356,7 @@ gst_vaapi_image_get_id(GstVaapiImage *image) gboolean gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image != NULL, FALSE); if (va_image) *va_image = image->image; @@ -441,7 +441,7 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) GstVaapiImageFormat gst_vaapi_image_get_format(GstVaapiImage *image) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image != NULL, 0); return image->format; } @@ -457,7 +457,7 @@ gst_vaapi_image_get_format(GstVaapiImage *image) guint gst_vaapi_image_get_width(GstVaapiImage *image) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image != NULL, 0); return image->width; } @@ -473,7 +473,7 @@ gst_vaapi_image_get_width(GstVaapiImage *image) guint gst_vaapi_image_get_height(GstVaapiImage *image) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image != NULL, 0); return image->height; } @@ -489,7 +489,7 @@ gst_vaapi_image_get_height(GstVaapiImage *image) void gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) { - g_return_if_fail(GST_VAAPI_IS_IMAGE(image)); + g_return_if_fail(image != NULL); if (pwidth) *pwidth = image->width; @@ -511,7 +511,7 @@ gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) gboolean gst_vaapi_image_is_linear(GstVaapiImage *image) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image != NULL, FALSE); return image->is_linear; } @@ -533,7 +533,7 @@ _gst_vaapi_image_is_mapped(GstVaapiImage *image) gboolean gst_vaapi_image_is_mapped(GstVaapiImage *image) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image != NULL, FALSE); return _gst_vaapi_image_is_mapped(image); } @@ -550,7 +550,7 @@ gst_vaapi_image_is_mapped(GstVaapiImage *image) gboolean gst_vaapi_image_map(GstVaapiImage *image) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image != NULL, FALSE); return _gst_vaapi_image_map(image, NULL); } @@ -607,7 +607,7 @@ map_success: gboolean gst_vaapi_image_unmap(GstVaapiImage *image) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image != NULL, FALSE); return _gst_vaapi_image_unmap(image); } @@ -650,7 +650,7 @@ _gst_vaapi_image_unmap(GstVaapiImage *image) guint gst_vaapi_image_get_plane_count(GstVaapiImage *image) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image != NULL, 0); g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0); return image->image.num_planes; @@ -669,7 +669,7 @@ gst_vaapi_image_get_plane_count(GstVaapiImage *image) guchar * gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); + g_return_val_if_fail(image != NULL, NULL); g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL); g_return_val_if_fail(plane < image->image.num_planes, NULL); @@ -689,7 +689,7 @@ gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane) guint gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image != NULL, 0); g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0); g_return_val_if_fail(plane < image->image.num_planes, 0); @@ -709,7 +709,7 @@ gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane) guint gst_vaapi_image_get_data_size(GstVaapiImage *image) { - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0); + g_return_val_if_fail(image != NULL, 0); return image->image.data_size; } @@ -979,7 +979,7 @@ gst_vaapi_image_get_buffer( GstVaapiImageRaw dst_image, src_image; gboolean success; - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image != NULL, FALSE); g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE); if (!init_image_from_buffer(&dst_image, buffer)) @@ -1022,7 +1022,7 @@ gst_vaapi_image_get_raw( GstVaapiImageRaw src_image; gboolean success; - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image != NULL, FALSE); if (!_gst_vaapi_image_map(image, &src_image)) return FALSE; @@ -1057,7 +1057,7 @@ gst_vaapi_image_update_from_buffer( GstVaapiImageRaw dst_image, src_image; gboolean success; - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image != NULL, FALSE); g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE); if (!init_image_from_buffer(&src_image, buffer)) @@ -1101,7 +1101,7 @@ gst_vaapi_image_update_from_raw( GstVaapiImageRaw dst_image; gboolean success; - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(image != NULL, FALSE); if (!_gst_vaapi_image_map(image, &dst_image)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 8b9abf51d9..9def1003da 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -33,9 +33,6 @@ G_BEGIN_DECLS #define GST_VAAPI_IMAGE(obj) \ ((GstVaapiImage *)(obj)) -#define GST_VAAPI_IS_IMAGE(obj) \ - ((obj) != NULL) - /** * GST_VAAPI_IMAGE_FORMAT: * @image: a #GstVaapiImage diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 311f9f0bec..7f262e972d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -97,7 +97,7 @@ gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps) { GstVaapiVideoPool *pool; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); g_return_val_if_fail(GST_IS_CAPS(caps), NULL); pool = (GstVaapiVideoPool *) diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index a56a18a21e..801cdaedd3 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -31,9 +31,6 @@ G_BEGIN_DECLS #define GST_VAAPI_IMAGE_POOL(obj) \ ((GstVaapiImagePool *)(obj)) -#define GST_VAAPI_IS_IMAGE_POOL(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiImagePool GstVaapiImagePool; GstVaapiVideoPool * diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index b270edaf8a..2be82ceb05 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -83,7 +83,7 @@ gst_vaapi_object_new(const GstVaapiObjectClass *klass, GstVaapiDisplay *display) GstVaapiObject *object; guint sub_size; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); object = (GstVaapiObject *)gst_vaapi_mini_object_new(object_class); if (!object) @@ -151,7 +151,7 @@ gst_vaapi_object_replace(gpointer old_object_ptr, gpointer new_object) GstVaapiDisplay * gst_vaapi_object_get_display(GstVaapiObject *object) { - g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), NULL); + g_return_val_if_fail(object != NULL, NULL); return GST_VAAPI_OBJECT_DISPLAY(object); } @@ -167,7 +167,7 @@ gst_vaapi_object_get_display(GstVaapiObject *object) void gst_vaapi_object_lock_display(GstVaapiObject *object) { - g_return_if_fail(GST_VAAPI_IS_OBJECT(object)); + g_return_if_fail(object != NULL); GST_VAAPI_OBJECT_LOCK_DISPLAY(object); } @@ -183,7 +183,7 @@ gst_vaapi_object_lock_display(GstVaapiObject *object) void gst_vaapi_object_unlock_display(GstVaapiObject *object) { - g_return_if_fail(GST_VAAPI_IS_OBJECT(object)); + g_return_if_fail(object != NULL); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(object); } @@ -199,7 +199,7 @@ gst_vaapi_object_unlock_display(GstVaapiObject *object) GstVaapiID gst_vaapi_object_get_id(GstVaapiObject *object) { - g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), 0); + g_return_val_if_fail(object != NULL, 0); return GST_VAAPI_OBJECT_ID(object); } diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index cdc59d4fad..081b2c6751 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -31,9 +31,6 @@ G_BEGIN_DECLS #define GST_VAAPI_OBJECT(obj) \ ((GstVaapiObject *)(obj)) -#define GST_VAAPI_IS_OBJECT(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiObject GstVaapiObject; gpointer diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index eb510265de..9e2566aee6 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -135,7 +135,7 @@ gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags) GstVaapiImageFormat format; guint va_flags; - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); + g_return_val_if_fail(image != NULL, NULL); GST_DEBUG("create from image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(image))); @@ -273,7 +273,7 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( GstVaapiID gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture) { - g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), VA_INVALID_ID); + g_return_val_if_fail(subpicture != NULL, VA_INVALID_ID); return GST_VAAPI_OBJECT_ID(subpicture); } @@ -289,7 +289,7 @@ gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture) guint gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture) { - g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 0); + g_return_val_if_fail(subpicture != NULL, 0); return subpicture->flags; } @@ -305,7 +305,7 @@ gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture) GstVaapiImage * gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture) { - g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), NULL); + g_return_val_if_fail(subpicture != NULL, NULL); return subpicture->image; } @@ -324,8 +324,8 @@ gboolean gst_vaapi_subpicture_set_image(GstVaapiSubpicture *subpicture, GstVaapiImage *image) { - g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(subpicture != NULL, FALSE); + g_return_val_if_fail(image != NULL, FALSE); gst_vaapi_subpicture_destroy(subpicture); return gst_vaapi_subpicture_create(subpicture, image); @@ -342,7 +342,7 @@ gst_vaapi_subpicture_set_image(GstVaapiSubpicture *subpicture, gfloat gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture) { - g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 1.0); + g_return_val_if_fail(subpicture != NULL, 1.0); return subpicture->global_alpha; } @@ -365,7 +365,7 @@ gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture, GstVaapiDisplay *display; VAStatus status; - g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); + g_return_val_if_fail(subpicture != NULL, FALSE); if (!(subpicture->flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index c7fb05311a..9a15efdf95 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -33,9 +33,6 @@ G_BEGIN_DECLS #define GST_VAAPI_SUBPICTURE(obj) \ ((GstVaapiSubpicture *)(obj)) -#define GST_VAAPI_IS_SUBPICTURE(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiSubpicture GstVaapiSubpicture; /** diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 1c5992808a..1cfcec245c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -218,7 +218,7 @@ error: GstVaapiID gst_vaapi_surface_get_id(GstVaapiSurface *surface) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), VA_INVALID_SURFACE); + g_return_val_if_fail(surface != NULL, VA_INVALID_SURFACE); return GST_VAAPI_OBJECT_ID(surface); } @@ -234,7 +234,7 @@ gst_vaapi_surface_get_id(GstVaapiSurface *surface) GstVaapiChromaType gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); + g_return_val_if_fail(surface != NULL, 0); return surface->chroma_type; } @@ -250,7 +250,7 @@ gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface) guint gst_vaapi_surface_get_width(GstVaapiSurface *surface) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); + g_return_val_if_fail(surface != NULL, 0); return surface->width; } @@ -266,7 +266,7 @@ gst_vaapi_surface_get_width(GstVaapiSurface *surface) guint gst_vaapi_surface_get_height(GstVaapiSurface *surface) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0); + g_return_val_if_fail(surface != NULL, 0); return surface->height; } @@ -286,7 +286,7 @@ gst_vaapi_surface_get_size( guint *pheight ) { - g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); + g_return_if_fail(surface != NULL); if (pwidth) *pwidth = gst_vaapi_surface_get_width(surface); @@ -310,7 +310,7 @@ gst_vaapi_surface_set_parent_context( GstVaapiContext *context ) { - g_return_if_fail(GST_VAAPI_IS_SURFACE(surface)); + g_return_if_fail(surface != NULL); gst_vaapi_object_replace(&surface->parent_context, context); } @@ -328,7 +328,7 @@ gst_vaapi_surface_set_parent_context( GstVaapiContext * gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); + g_return_val_if_fail(surface != NULL, NULL); return surface->parent_context; } @@ -364,7 +364,7 @@ gst_vaapi_surface_derive_image(GstVaapiSurface *surface) VAImage va_image; VAStatus status; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); + g_return_val_if_fail(surface != NULL, NULL); display = GST_VAAPI_OBJECT_DISPLAY(surface); va_image.image_id = VA_INVALID_ID; @@ -403,8 +403,8 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) VAStatus status; guint width, height; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(surface != NULL, FALSE); + g_return_val_if_fail(image != NULL, FALSE); display = GST_VAAPI_OBJECT_DISPLAY(surface); if (!display) @@ -450,8 +450,8 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) VAStatus status; guint width, height; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE); + g_return_val_if_fail(surface != NULL, FALSE); + g_return_val_if_fail(image != NULL, FALSE); display = GST_VAAPI_OBJECT_DISPLAY(surface); if (!display) @@ -508,8 +508,8 @@ gst_vaapi_surface_associate_subpicture( { gboolean success; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); + g_return_val_if_fail(surface != NULL, FALSE); + g_return_val_if_fail(subpicture != NULL, FALSE); if (!surface->subpictures) { surface->subpictures = g_ptr_array_new(); @@ -615,8 +615,8 @@ gst_vaapi_surface_deassociate_subpicture( { gboolean success; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE); + g_return_val_if_fail(surface != NULL, FALSE); + g_return_val_if_fail(subpicture != NULL, FALSE); if (!surface->subpictures) return TRUE; @@ -681,7 +681,7 @@ gst_vaapi_surface_sync(GstVaapiSurface *surface) GstVaapiDisplay *display; VAStatus status; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + g_return_val_if_fail(surface != NULL, FALSE); display = GST_VAAPI_OBJECT_DISPLAY(surface); if (!display) @@ -718,7 +718,7 @@ gst_vaapi_surface_query_status( VASurfaceStatus surface_status; VAStatus status; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + g_return_val_if_fail(surface != NULL, FALSE); GST_VAAPI_OBJECT_LOCK_DISPLAY(surface); status = vaQuerySurfaceStatus( @@ -758,7 +758,7 @@ gst_vaapi_surface_set_subpictures_from_composition( GstVaapiDisplay *display; guint n, nb_rectangles; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + g_return_val_if_fail(surface != NULL, FALSE); if (propagate_context && surface->parent_context) return gst_vaapi_context_apply_composition(surface->parent_context, diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 0d36fe9892..15f8b7da3e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -115,9 +115,6 @@ typedef enum { #define GST_VAAPI_SURFACE(obj) \ ((GstVaapiSurface *)(obj)) -#define GST_VAAPI_IS_SURFACE(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiSurface GstVaapiSurface; typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index d57fb849a2..d39588d289 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -97,7 +97,7 @@ gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps) { GstVaapiVideoPool *pool; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); g_return_val_if_fail(GST_IS_CAPS(caps), NULL); pool = (GstVaapiVideoPool *) diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 635af47dc9..48ea71edc7 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -31,9 +31,6 @@ G_BEGIN_DECLS #define GST_VAAPI_SURFACE_POOL(obj) \ ((GstVaapiSurfacePool *)(obj)) -#define GST_VAAPI_IS_SURFACE_POOL(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiSurfacePool GstVaapiSurfacePool; GstVaapiVideoPool * diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 7242e9548a..a2cd002fc3 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -63,7 +63,7 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) { GstVaapiSurfaceProxy *proxy; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), NULL); + g_return_val_if_fail(pool != NULL, NULL); proxy = (GstVaapiSurfaceProxy *) gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class()); @@ -96,7 +96,7 @@ error: GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); + g_return_val_if_fail(proxy != NULL, NULL); return GST_VAAPI_SURFACE_PROXY(gst_vaapi_mini_object_ref( GST_VAAPI_MINI_OBJECT(proxy))); @@ -112,7 +112,7 @@ gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy) void gst_vaapi_surface_proxy_unref(GstVaapiSurfaceProxy *proxy) { - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + g_return_if_fail(proxy != NULL); gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(proxy)); } @@ -147,7 +147,7 @@ gst_vaapi_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr, GstVaapiSurface * gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL); + g_return_val_if_fail(proxy != NULL, NULL); return GST_VAAPI_SURFACE_PROXY_SURFACE(proxy); } @@ -164,7 +164,7 @@ gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy) guint gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0); + g_return_val_if_fail(proxy != NULL, 0); return GST_VAAPI_SURFACE_PROXY_FLAGS(proxy); } @@ -180,7 +180,7 @@ gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy) GstVaapiID gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0); + g_return_val_if_fail(proxy != NULL, 0); g_return_val_if_fail(proxy->surface != NULL, 0); return GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy); @@ -197,7 +197,7 @@ gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) GstClockTime gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0); + g_return_val_if_fail(proxy != NULL, 0); return GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); } @@ -213,7 +213,7 @@ gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy) GstClockTime gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy) { - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0); + g_return_val_if_fail(proxy != NULL, 0); return GST_VAAPI_SURFACE_PROXY_DURATION(proxy); } @@ -233,7 +233,7 @@ void gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy, GDestroyNotify destroy_func, gpointer user_data) { - g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy)); + g_return_if_fail(proxy != NULL); proxy->destroy_func = destroy_func; proxy->destroy_data = user_data; diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index 7df307fd04..d3fbcbc3ed 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -31,9 +31,6 @@ #define GST_VAAPI_SURFACE_PROXY(obj) \ ((GstVaapiSurfaceProxy *)(obj)) -#define GST_VAAPI_IS_SURFACE_PROXY(obj) \ - (GST_VAAPI_SURFACE_PROXY(obj) != NULL) - struct _GstVaapiSurfaceProxy { /*< private >*/ GstVaapiMiniObject parent_instance; diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 13696cdf7f..ae54ec33f2 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -245,7 +245,7 @@ gst_vaapi_texture_new( { GstVaapiTexture *texture; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); g_return_val_if_fail(target != GL_NONE, NULL); g_return_val_if_fail(format != GL_NONE, NULL); g_return_val_if_fail(width > 0, NULL); @@ -297,7 +297,7 @@ gst_vaapi_texture_new_with_texture( GLTextureState ts; gboolean success; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); g_return_val_if_fail(target != GL_NONE, NULL); g_return_val_if_fail(format != GL_NONE, NULL); @@ -598,7 +598,7 @@ gst_vaapi_texture_put_surface( ) { g_return_val_if_fail(texture != NULL, FALSE); - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + g_return_val_if_fail(surface != NULL, FALSE); return _gst_vaapi_texture_put_surface(texture, surface, flags); } diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 1f86ead599..360c9ed304 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -127,7 +127,7 @@ gst_vaapi_video_pool_replace(GstVaapiVideoPool **old_pool_ptr, GstVaapiDisplay * gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); + g_return_val_if_fail(pool != NULL, NULL); return pool->display; } @@ -148,7 +148,7 @@ gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) { gpointer object; - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); + g_return_val_if_fail(pool != NULL, NULL); if (pool->capacity && pool->used_count >= pool->capacity) return NULL; @@ -180,8 +180,8 @@ gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) { GList *elem; - g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool)); - g_return_if_fail(GST_VAAPI_IS_OBJECT(object)); + g_return_if_fail(pool != NULL); + g_return_if_fail(object != NULL); elem = g_list_find(pool->used_objects, object); if (!elem) @@ -207,8 +207,8 @@ gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) gboolean gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), FALSE); + g_return_val_if_fail(pool != NULL, FALSE); + g_return_val_if_fail(object != NULL, FALSE); g_queue_push_tail(&pool->free_objects, gst_vaapi_object_ref(object)); return TRUE; @@ -230,7 +230,7 @@ gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects) { guint i; - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE); + g_return_val_if_fail(pool != NULL, FALSE); for (i = 0; i < objects->len; i++) { gpointer const object = g_ptr_array_index(objects, i); @@ -251,7 +251,7 @@ gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects) guint gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0); + g_return_val_if_fail(pool != NULL, 0); return g_queue_get_length(&pool->free_objects); } @@ -273,7 +273,7 @@ gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n) { guint i, num_allocated; - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0); + g_return_val_if_fail(pool != NULL, 0); num_allocated = gst_vaapi_video_pool_get_size(pool) + pool->used_count; if (n < num_allocated) @@ -303,7 +303,7 @@ gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n) guint gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0); + g_return_val_if_fail(pool != NULL, 0); return pool->capacity; } @@ -318,7 +318,7 @@ gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool) void gst_vaapi_video_pool_set_capacity(GstVaapiVideoPool *pool, guint capacity) { - g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool)); + g_return_if_fail(pool != NULL); pool->capacity = capacity; } diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 44dbf20082..2f13277532 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -32,9 +32,6 @@ G_BEGIN_DECLS #define GST_VAAPI_VIDEO_POOL(obj) \ ((GstVaapiVideoPool *)(obj)) -#define GST_VAAPI_IS_VIDEO_POOL(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiVideoPool GstVaapiVideoPool; GstVaapiVideoPool * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 2031c89b4b..5215ef34cc 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -175,7 +175,7 @@ gst_vaapi_window_replace(GstVaapiWindow **old_window_ptr, GstVaapiDisplay * gst_vaapi_window_get_display(GstVaapiWindow *window) { - g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), NULL); + g_return_val_if_fail(window != NULL, NULL); return GST_VAAPI_OBJECT_DISPLAY(window); } @@ -190,7 +190,7 @@ gst_vaapi_window_get_display(GstVaapiWindow *window) void gst_vaapi_window_show(GstVaapiWindow *window) { - g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + g_return_if_fail(window != NULL); GST_VAAPI_WINDOW_GET_CLASS(window)->show(window); window->check_geometry = TRUE; @@ -206,7 +206,7 @@ gst_vaapi_window_show(GstVaapiWindow *window) void gst_vaapi_window_hide(GstVaapiWindow *window) { - g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + g_return_if_fail(window != NULL); GST_VAAPI_WINDOW_GET_CLASS(window)->hide(window); } @@ -222,7 +222,7 @@ gst_vaapi_window_hide(GstVaapiWindow *window) gboolean gst_vaapi_window_get_fullscreen(GstVaapiWindow *window) { - g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE); + g_return_val_if_fail(window != NULL, FALSE); gst_vaapi_window_ensure_size(window); @@ -241,7 +241,7 @@ gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) { const GstVaapiWindowClass *klass; - g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + g_return_if_fail(window != NULL); klass = GST_VAAPI_WINDOW_GET_CLASS(window); @@ -263,7 +263,7 @@ gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) guint gst_vaapi_window_get_width(GstVaapiWindow *window) { - g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0); + g_return_val_if_fail(window != NULL, 0); gst_vaapi_window_ensure_size(window); @@ -281,7 +281,7 @@ gst_vaapi_window_get_width(GstVaapiWindow *window) guint gst_vaapi_window_get_height(GstVaapiWindow *window) { - g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0); + g_return_val_if_fail(window != NULL, 0); gst_vaapi_window_ensure_size(window); @@ -299,7 +299,7 @@ gst_vaapi_window_get_height(GstVaapiWindow *window) void gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight) { - g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + g_return_if_fail(window != NULL); gst_vaapi_window_ensure_size(window); @@ -320,7 +320,7 @@ gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight) void gst_vaapi_window_set_width(GstVaapiWindow *window, guint width) { - g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + g_return_if_fail(window != NULL); gst_vaapi_window_set_size(window, width, window->height); } @@ -335,7 +335,7 @@ gst_vaapi_window_set_width(GstVaapiWindow *window, guint width) void gst_vaapi_window_set_height(GstVaapiWindow *window, guint height) { - g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + g_return_if_fail(window != NULL); gst_vaapi_window_set_size(window, window->width, height); } @@ -351,7 +351,7 @@ gst_vaapi_window_set_height(GstVaapiWindow *window, guint height) void gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) { - g_return_if_fail(GST_VAAPI_IS_WINDOW(window)); + g_return_if_fail(window != NULL); if (width == window->width && height == window->height) return; @@ -417,8 +417,8 @@ gst_vaapi_window_put_surface( const GstVaapiWindowClass *klass; GstVaapiRectangle src_rect_default, dst_rect_default; - g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + g_return_val_if_fail(window != NULL, FALSE); + g_return_val_if_fail(surface != NULL, FALSE); klass = GST_VAAPI_WINDOW_GET_CLASS(window); if (!klass->render) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 24c806f978..13359d74d4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -34,9 +34,6 @@ G_BEGIN_DECLS #define GST_VAAPI_WINDOW(obj) \ ((GstVaapiWindow *)(obj)) -#define GST_VAAPI_IS_WINDOW(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiWindow GstVaapiWindow; typedef struct _GstVaapiWindowClass GstVaapiWindowClass; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h index 563e6acc17..fc155b89da 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h @@ -30,9 +30,6 @@ G_BEGIN_DECLS #define GST_VAAPI_WINDOW_DRM(obj) \ ((GstVaapiWindowDRM *)(obj)) -#define GST_VAAPI_IS_WINDOW_DRM(obj) \ - ((obj) != NULL) - typedef struct _GstVaapiWindowDRM GstVaapiWindowDRM; GstVaapiWindow * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 0e9430b6d5..3802a32833 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -39,9 +39,6 @@ #define GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window) \ (&GST_VAAPI_WINDOW_GLX(window)->priv) -#define GST_VAAPI_IS_WINDOW_GLX(obj) \ - ((obj) != NULL) - #define GST_VAAPI_WINDOW_GLX_CLASS(klass) \ ((GstVaapiWindowGLXClass *)(klass)) @@ -403,7 +400,7 @@ gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid) GLXContext gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window) { - g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), NULL); + g_return_val_if_fail(window != NULL, NULL); return GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window)->gl_context->context; } @@ -423,7 +420,7 @@ gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window) gboolean gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx) { - g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE); + g_return_val_if_fail(window != NULL, FALSE); return gst_vaapi_window_glx_ensure_context(GST_VAAPI_WINDOW(window), ctx); } @@ -443,7 +440,7 @@ gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window) { gboolean success; - g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE); + g_return_val_if_fail(window != NULL, FALSE); GST_VAAPI_OBJECT_LOCK_DISPLAY(window); success = gl_set_current_context(window->priv.gl_context, NULL); @@ -462,7 +459,7 @@ gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window) void gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window) { - g_return_if_fail(GST_VAAPI_IS_WINDOW_GLX(window)); + g_return_if_fail(window != NULL); GST_VAAPI_OBJECT_LOCK_DISPLAY(window); gl_swap_buffers(window->priv.gl_context); @@ -501,7 +498,7 @@ gst_vaapi_window_glx_put_texture( guint tex_width, tex_height; guint win_width, win_height; - g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE); + g_return_val_if_fail(window != NULL, FALSE); g_return_val_if_fail(texture != NULL, FALSE); gst_vaapi_texture_get_size(texture, &tex_width, &tex_height); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index a04d12dc36..d30bf09da3 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -519,7 +519,7 @@ gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) Window gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window) { - g_return_val_if_fail(GST_VAAPI_IS_WINDOW_X11(window), None); + g_return_val_if_fail(window != NULL, None); return GST_VAAPI_OBJECT_ID(window); } @@ -536,7 +536,7 @@ gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window) gboolean gst_vaapi_window_x11_is_foreign_xid(GstVaapiWindowX11 *window) { - g_return_val_if_fail(GST_VAAPI_IS_WINDOW_X11(window), FALSE); + g_return_val_if_fail(window != NULL, FALSE); return GST_VAAPI_WINDOW(window)->use_foreign_window; } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index 507dd9bb8f..57c514347a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -32,9 +32,6 @@ G_BEGIN_DECLS #define GST_VAAPI_WINDOW_X11(obj) \ ((GstVaapiWindowX11 *)(obj)) -#define GST_VAAPI_IS_WINDOW_X11(obj) \ - ((obj) != NULL) - /** * GST_VAAPI_WINDOW_XWINDOW: * @window: a #GstVaapiWindow From 809c7e097b62166ab51caf666d1bf810a952e354 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 May 2013 18:45:23 +0200 Subject: [PATCH 1190/3781] libs: add query for GstVaapiVideoPool object types. Add API to identify the underlying GstVaapiVideoPool object type. --- docs/reference/libs/libs-sections.txt | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.c | 3 ++- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 3 ++- gst-libs/gst/vaapi/gstvaapivideopool.c | 21 ++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapivideopool.h | 15 +++++++++++++++ gst-libs/gst/vaapi/gstvaapivideopool_priv.h | 4 +++- 6 files changed, 43 insertions(+), 5 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 423704c1e9..e25b0e6499 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -5,7 +5,6 @@ GstVaapiSurfacePool gst_vaapi_surface_pool_new GST_VAAPI_SURFACE_POOL -gst_vaapi_surface_pool_get_type
@@ -13,6 +12,7 @@ gst_vaapi_surface_pool_get_type GstVaapiVideoPool GstVaapiVideoPool gst_vaapi_video_pool_get_display +gst_vaapi_video_pool_get_object_type gst_vaapi_video_pool_get_object gst_vaapi_video_pool_put_object gst_vaapi_video_pool_add_object diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 7f262e972d..dd3868acfc 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -105,7 +105,8 @@ gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps) if (!pool) return NULL; - gst_vaapi_video_pool_init(pool, display); + gst_vaapi_video_pool_init(pool, display, + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE); if (!gst_vaapi_image_pool_set_caps(pool, caps)) goto error; return pool; diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index d39588d289..f429b9d2f7 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -105,7 +105,8 @@ gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps) if (!pool) return NULL; - gst_vaapi_video_pool_init(pool, display); + gst_vaapi_video_pool_init(pool, display, + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE); if (!gst_vaapi_surface_pool_set_caps(pool, caps)) goto error; return pool; diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 360c9ed304..23912e6198 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -54,8 +54,10 @@ gst_vaapi_video_pool_alloc_object(GstVaapiVideoPool *pool) } void -gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display) +gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display, + GstVaapiVideoPoolObjectType object_type) { + pool->object_type = object_type; pool->display = gst_vaapi_display_ref(display); pool->used_objects = NULL; pool->used_count = 0; @@ -132,6 +134,23 @@ gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool) return pool->display; } +/** + * gst_vaapi_video_pool_get_object_type: + * @pool: a #GstVaapiVideoPool + * + * Retrieves the type of objects the video @pool supports. + * + * Return value: the #GstVaapiVideoPoolObjectType of the underlying pool + * objects + */ +GstVaapiVideoPoolObjectType +gst_vaapi_video_pool_get_object_type(GstVaapiVideoPool *pool) +{ + g_return_val_if_fail(pool != NULL, (GstVaapiVideoPoolObjectType)0); + + return pool->object_type; +} + /** * gst_vaapi_video_pool_get_object: * @pool: a #GstVaapiVideoPool diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 2f13277532..03b6cffdc3 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -34,6 +34,18 @@ G_BEGIN_DECLS typedef struct _GstVaapiVideoPool GstVaapiVideoPool; +/** + * GstVaapiVideoPoolObjectType: + * @GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE: #GstVaapiImage objects. + * @GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE: #GstVaapiSurface objects. + * + * The set of all supported #GstVaapiVideoPool object types. + */ +typedef enum { + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE = 1, + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE +} GstVaapiVideoPoolObjectType; + GstVaapiVideoPool * gst_vaapi_video_pool_ref(GstVaapiVideoPool *pool); @@ -47,6 +59,9 @@ gst_vaapi_video_pool_replace(GstVaapiVideoPool **old_pool_ptr, GstVaapiDisplay * gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool); +GstVaapiVideoPoolObjectType +gst_vaapi_video_pool_get_object_type(GstVaapiVideoPool *pool); + gpointer gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool); diff --git a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h index df66480965..8da750e9be 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h @@ -44,6 +44,7 @@ struct _GstVaapiVideoPool { /*< private >*/ GstVaapiMiniObject parent_instance; + guint object_type; GstVaapiDisplay *display; GQueue free_objects; GList *used_objects; @@ -67,7 +68,8 @@ struct _GstVaapiVideoPoolClass { G_GNUC_INTERNAL void -gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display); +gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display, + GstVaapiVideoPoolObjectType object_type); G_GNUC_INTERNAL void From 3c751b2dfdaa7c32b5d6091bc58fdcf47b558eb9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 May 2013 18:19:24 +0200 Subject: [PATCH 1191/3781] tests: cope with GST_VAAPI_IS_xxx() macros removal. --- tests/decoder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/decoder.c b/tests/decoder.c index b2ca16e2ab..b051f46bcb 100644 --- a/tests/decoder.c +++ b/tests/decoder.c @@ -144,7 +144,7 @@ decoder_put_buffers(GstVaapiDecoder *decoder) GstBuffer *buffer; gboolean success; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE); + g_return_val_if_fail(decoder != NULL, FALSE); codec = get_codec_defs(decoder); g_return_val_if_fail(codec != NULL, FALSE); @@ -178,7 +178,7 @@ decoder_get_surface(GstVaapiDecoder *decoder) GstVaapiSurfaceProxy *proxy; GstVaapiDecoderStatus status; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + g_return_val_if_fail(decoder != NULL, NULL); status = gst_vaapi_decoder_get_surface(decoder, &proxy); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { @@ -198,7 +198,7 @@ decoder_get_codec_name(GstVaapiDecoder *decoder) { const CodecDefs *codec; - g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL); + g_return_val_if_fail(decoder != NULL, NULL); codec = get_codec_defs(decoder); g_return_val_if_fail(codec != NULL, FALSE); From e52ea35b1109690aee124b27fb032340f114e566 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 May 2013 18:22:50 +0200 Subject: [PATCH 1192/3781] plugins: cope with GST_VAAPI_IS_xxx() macros removal. --- gst/vaapi/gstvaapiuploader.c | 2 +- gst/vaapi/gstvaapivideomemory.c | 2 +- gst/vaapi/gstvaapivideometa.c | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index bf0970047e..d542e8be8f 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -295,7 +295,7 @@ gst_vaapi_uploader_ensure_display( ) { g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(display != NULL, FALSE); return ensure_display(uploader,display); } diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 7551bfcd10..d6a52087fb 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -366,7 +366,7 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) GstVaapiSurface *surface; GstVaapiImage *image; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); g_return_val_if_fail(GST_IS_CAPS(caps), NULL); allocator = g_object_new(GST_VAAPI_TYPE_VIDEO_ALLOCATOR, NULL); diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index fe41db3097..d08b053b5e 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -224,7 +224,7 @@ gst_vaapi_video_meta_new(GstVaapiDisplay *display) { GstVaapiVideoMeta *meta; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(display != NULL, NULL); meta = _gst_vaapi_video_meta_new(); if (G_UNLIKELY(!meta)) @@ -289,7 +289,7 @@ gst_vaapi_video_meta_new_with_image(GstVaapiImage *image) { GstVaapiVideoMeta *meta; - g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL); + g_return_val_if_fail(image != NULL, NULL); meta = _gst_vaapi_video_meta_new(); if (G_UNLIKELY(!meta)) @@ -316,7 +316,7 @@ gst_vaapi_video_meta_new_with_surface(GstVaapiSurface *surface) { GstVaapiVideoMeta *meta; - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL); + g_return_val_if_fail(surface != NULL, NULL); meta = _gst_vaapi_video_meta_new(); if (G_UNLIKELY(!meta)) @@ -671,7 +671,7 @@ guint gst_vaapi_video_meta_get_render_flags(GstVaapiVideoMeta *meta) { g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), 0); - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(meta->surface), 0); + g_return_val_if_fail(meta->surface != NULL, 0); return meta->render_flags; } @@ -687,7 +687,7 @@ void gst_vaapi_video_meta_set_render_flags(GstVaapiVideoMeta *meta, guint flags) { g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); - g_return_if_fail(GST_VAAPI_IS_SURFACE(meta->surface)); + g_return_if_fail(meta->surface != NULL); meta->render_flags = flags; } From 35eaa9e763d6ed65d0cf02b5bd1cd0c898553a3f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 May 2013 18:56:43 +0200 Subject: [PATCH 1193/3781] plugins: fix gst_vaapi_video_meta_new_from_pool(). Since GST_VAAPI_IS_xxx_VIDEO_POOL() was only testing for NULL and not the underlying object type, the gst_vaapi_video_meta_new_from_pool() was hereby totally broken. Fixed this regression by using the newly provided gst_vaapi_video_pool_get_object_type() function. --- gst/vaapi/gstvaapivideometa.c | 74 +++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index d08b053b5e..77b8af4c41 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -61,6 +61,19 @@ set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image) set_display(meta, gst_vaapi_object_get_display(GST_VAAPI_OBJECT(image))); } +static gboolean +set_image_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool) +{ + GstVaapiImage *image; + + image = gst_vaapi_video_pool_get_object(pool); + if (!image) + return FALSE; + set_image(meta, image); + meta->image_pool = gst_vaapi_video_pool_ref(pool); + return TRUE; +} + static inline void set_surface(GstVaapiVideoMeta *meta, GstVaapiSurface *surface) { @@ -68,6 +81,19 @@ set_surface(GstVaapiVideoMeta *meta, GstVaapiSurface *surface) set_display(meta, gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface))); } +static gboolean +set_surface_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool) +{ + GstVaapiSurface *surface; + + surface = gst_vaapi_video_pool_get_object(pool); + if (!surface) + return FALSE; + set_surface(meta, surface); + meta->surface_pool = gst_vaapi_video_pool_ref(pool); + return TRUE; +} + static void gst_vaapi_video_meta_destroy_image(GstVaapiVideoMeta *meta) { @@ -252,18 +278,22 @@ gst_vaapi_video_meta_new_from_pool(GstVaapiVideoPool *pool) { GstVaapiVideoMeta *meta; - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL); + g_return_val_if_fail(pool != NULL, NULL); meta = _gst_vaapi_video_meta_new(); if (G_UNLIKELY(!meta)) return NULL; - if (!(GST_VAAPI_IS_IMAGE_POOL(pool) && - gst_vaapi_video_meta_set_image_from_pool(meta, pool)) && - !(GST_VAAPI_IS_SURFACE_POOL(pool) && - gst_vaapi_video_meta_set_surface_from_pool(meta, pool))) - goto error; - + switch (gst_vaapi_video_pool_get_object_type(pool)) { + case GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE: + if (!set_image_from_pool(meta, pool)) + goto error; + break; + case GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE: + if (!set_surface_from_pool(meta, pool)) + goto error; + break; + } set_display(meta, gst_vaapi_video_pool_get_display(pool)); return meta; @@ -492,21 +522,14 @@ gboolean gst_vaapi_video_meta_set_image_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool) { - GstVaapiImage *image; - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_IMAGE_POOL(pool), FALSE); + g_return_val_if_fail(pool != NULL, FALSE); + g_return_val_if_fail(gst_vaapi_video_pool_get_object_type(pool) == + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE, FALSE); gst_vaapi_video_meta_destroy_image(meta); - if (pool) { - image = gst_vaapi_video_pool_get_object(pool); - if (!image) - return FALSE; - set_image(meta, image); - meta->image_pool = gst_vaapi_video_pool_ref(pool); - } - return TRUE; + return set_image_from_pool(meta, pool); } /** @@ -564,21 +587,14 @@ gboolean gst_vaapi_video_meta_set_surface_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool) { - GstVaapiSurface *surface; - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), FALSE); - g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), FALSE); + g_return_val_if_fail(pool != NULL, FALSE); + g_return_val_if_fail(gst_vaapi_video_pool_get_object_type(pool) == + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE, FALSE); gst_vaapi_video_meta_destroy_surface(meta); - if (pool) { - surface = gst_vaapi_video_pool_get_object(pool); - if (!surface) - return FALSE; - set_surface(meta, surface); - meta->surface_pool = gst_vaapi_video_pool_ref(pool); - } - return TRUE; + return set_surface_from_pool(meta, pool); } /** From dadf0ef9783367ad58672c1f89fcf61a52cd3d71 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Wed, 15 May 2013 10:33:16 +0800 Subject: [PATCH 1194/3781] uploader: fix memory leak in GStreamer 0.10 builds. In GStreamer 0.10 builds, gst_vaapi_uploader_get_buffer() was used but it exhibited a memory leak because the surface generated for the GstVaapiVideoMeta totally lost its parent video pool. So, it was not possible to release that surface back to the parent pool when the meta gets released, and the memory consumption kept growing. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapiuploader.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) mode change 100644 => 100755 gst/vaapi/gstvaapiuploader.c diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c old mode 100644 new mode 100755 index d542e8be8f..8413fe679f --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -412,7 +412,6 @@ GstBuffer * gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) { GstVaapiUploaderPrivate *priv; - GstVaapiSurface *surface; GstVaapiImage *image; GstVaapiVideoMeta *meta; GstBuffer *buffer; @@ -428,15 +427,11 @@ gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) } meta = gst_buffer_get_vaapi_video_meta(buffer); - - surface = gst_vaapi_video_pool_get_object(priv->surfaces); - if (!surface) { + if (!gst_vaapi_video_meta_set_surface_from_pool(meta, priv->surfaces)) { GST_WARNING("failed to allocate VA surface"); goto error; } - gst_vaapi_video_meta_set_surface(meta, surface); - image = gst_vaapi_video_meta_get_image(meta); if (!gst_vaapi_image_map(image)) { GST_WARNING("failed to map VA image"); From 811c1abbc6d128da947da0c2397ef1233492c532 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 24 May 2013 15:05:45 +0200 Subject: [PATCH 1195/3781] tests: improve check for display cache. Improve check for display cache infrastructure. In particular, for X11 and GLX backends, we need to make sure that we can create a GstVaapiDisplayX11 from another GstVaapiDisplayGLX, i.e. underlying X11 and VA displays can be shared. Besides, allocating a GstVaapiDisplayGLX while a GstVaapiDisplayX11 already exists will have to generate different VA displays. --- tests/test-display.c | 78 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/tests/test-display.c b/tests/test-display.c index e463d5f372..4155fc1331 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -45,6 +45,9 @@ # include #endif +/* Set to 1 to check display cache works (shared VA display) */ +#define CHECK_DISPLAY_CACHE 1 + static void print_value(const GValue *value, const gchar *name) { @@ -271,7 +274,7 @@ dump_info(GstVaapiDisplay *display) int main(int argc, char *argv[]) { - GstVaapiDisplay *display; + GstVaapiDisplay *display, *display2; guint width, height, par_n, par_d; gst_init(&argc, &argv); @@ -345,6 +348,39 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); + if (CHECK_DISPLAY_CACHE) { + display2 = gst_vaapi_display_x11_new(NULL); + + /* Check for the same X11 display */ + g_assert(gst_vaapi_display_x11_get_display( + GST_VAAPI_DISPLAY_X11(display)) == + gst_vaapi_display_x11_get_display( + GST_VAAPI_DISPLAY_X11(display2))); + + /* Check for the same VA display */ + g_assert(gst_vaapi_display_get_display(display) == + gst_vaapi_display_get_display(display2)); + + gst_vaapi_display_unref(display2); + +#if USE_GLX + display2 = gst_vaapi_display_glx_new(NULL); + + /* Check for the different X11 display */ + /* XXX: it is also desired to cache underlying X11 displays */ + g_assert(gst_vaapi_display_x11_get_display( + GST_VAAPI_DISPLAY_X11(display)) != + gst_vaapi_display_x11_get_display( + GST_VAAPI_DISPLAY_X11(display2))); + + /* Check for different VA display */ + g_assert(gst_vaapi_display_get_display(display) != + gst_vaapi_display_get_display(display2)); + + gst_vaapi_display_unref(display2); +#endif + } + gst_vaapi_display_get_size(display, &width, &height); g_print("Display size: %ux%u\n", width, height); @@ -370,6 +406,16 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); + if (CHECK_DISPLAY_CACHE) { + display2 = gst_vaapi_display_x11_new_with_display(x11_display); + + /* Check for the same VA display */ + g_assert(gst_vaapi_display_get_display(display) == + gst_vaapi_display_get_display(display2)); + + gst_vaapi_display_unref(display2); + } + dump_info(display); gst_vaapi_display_unref(display); XCloseDisplay(x11_display); @@ -411,6 +457,36 @@ main(int argc, char *argv[]) if (!display) g_error("could not create Gst/VA display"); + if (CHECK_DISPLAY_CACHE) { + display2 = gst_vaapi_display_glx_new(NULL); + + /* Check for the same X11 display */ + g_assert(gst_vaapi_display_x11_get_display( + GST_VAAPI_DISPLAY_X11(display)) == + gst_vaapi_display_x11_get_display( + GST_VAAPI_DISPLAY_X11(display2))); + + /* Check for the same VA display */ + g_assert(gst_vaapi_display_get_display(display) == + gst_vaapi_display_get_display(display2)); + + gst_vaapi_display_unref(display2); + + display2 = gst_vaapi_display_x11_new(NULL); + + /* Check for the same X11 display */ + g_assert(gst_vaapi_display_x11_get_display( + GST_VAAPI_DISPLAY_X11(display)) == + gst_vaapi_display_x11_get_display( + GST_VAAPI_DISPLAY_X11(display2))); + + /* Check for the same VA display */ + g_assert(gst_vaapi_display_get_display(display) == + gst_vaapi_display_get_display(display2)); + + gst_vaapi_display_unref(display2); + } + gst_vaapi_display_get_size(display, &width, &height); g_print("Display size: %ux%u\n", width, height); From b59445b2ab68ac492bc3989e1f74277cc3377147 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 24 May 2013 16:12:01 +0200 Subject: [PATCH 1196/3781] display: rework display cache API. Simplify display cache API, while making it more flexible. We can now create custom lookup functions with gst_vaapi_display_cache_lookup_custom(). --- gst-libs/gst/vaapi/gstvaapidisplaycache.c | 165 +++++++++++----------- gst-libs/gst/vaapi/gstvaapidisplaycache.h | 11 +- 2 files changed, 92 insertions(+), 84 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index 5f5ae8d410..6512bf8dd7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -83,51 +83,66 @@ error: return NULL; } -#define CACHE_LOOKUP(cache, res, prop, comp_func, comp_data, user_data) do { \ - GList *l; \ - \ - g_mutex_lock(&(cache)->mutex); \ - for (l = (cache)->list; l != NULL; l = l->next) { \ - GstVaapiDisplayInfo * const info = \ - &((CacheEntry *)l->data)->info; \ - if (comp_func(info->prop, comp_data, user_data)) \ - break; \ - } \ - g_mutex_unlock(&(cache)->mutex); \ - res = l; \ - } while (0) - -#define compare_equal(a, b, user_data) \ - ((a) == (b)) - -#define compare_string(a, b, user_data) \ - ((a) == (b) || ((a) && (b) && strcmp(a, b) == 0)) - static GList * -cache_lookup_display(GstVaapiDisplayCache *cache, GstVaapiDisplay *display) +cache_lookup_1(GstVaapiDisplayCache *cache, GCompareFunc func, + gconstpointer data) { - GList *m; + GList *l; - CACHE_LOOKUP(cache, m, display, compare_equal, display, NULL); - return m; + g_mutex_lock(&cache->mutex); + for (l = cache->list; l != NULL; l = l->next) { + GstVaapiDisplayInfo * const info = &((CacheEntry *)l->data)->info; + if (func(info, data)) + break; + } + g_mutex_unlock(&cache->mutex); + return l; } -static GList * -cache_lookup_va_display(GstVaapiDisplayCache *cache, VADisplay va_display) +static inline const GstVaapiDisplayInfo * +cache_lookup(GstVaapiDisplayCache *cache, GCompareFunc func, + gconstpointer data) { - GList *m; + GList * const m = cache_lookup_1(cache, func, data); - CACHE_LOOKUP(cache, m, va_display, compare_equal, va_display, NULL); - return m; + return m ? &((CacheEntry *)m->data)->info : NULL; } -static GList * -cache_lookup_native_display(GstVaapiDisplayCache *cache, gpointer native_display) +static gint +compare_display(gconstpointer a, gconstpointer display) { - GList *m; + const GstVaapiDisplayInfo * const info = a; - CACHE_LOOKUP(cache, m, native_display, compare_equal, native_display, NULL); - return m; + return info->display == display; +} + +static gint +compare_va_display(gconstpointer a, gconstpointer va_display) +{ + const GstVaapiDisplayInfo * const info = a; + + return info->va_display == va_display; +} + +static gint +compare_native_display(gconstpointer a, gconstpointer native_display) +{ + const GstVaapiDisplayInfo * const info = a; + + return info->native_display == native_display; +} + +static gint +compare_display_name(gconstpointer a, gconstpointer b) +{ + const GstVaapiDisplayInfo * const info = a; + const gchar * const display_name = b; + + if (info->display_name == NULL && display_name == NULL) + return TRUE; + if (!info->display_name || !display_name) + return FALSE; + return strcmp(info->display_name, display_name) == 0; } /** @@ -241,7 +256,7 @@ gst_vaapi_display_cache_remove( { GList *m; - m = cache_lookup_display(cache, display); + m = cache_lookup_1(cache, compare_display, display); if (!m) return; @@ -267,18 +282,39 @@ gst_vaapi_display_cache_lookup( GstVaapiDisplay *display ) { - CacheEntry *entry; - GList *m; - g_return_val_if_fail(cache != NULL, NULL); g_return_val_if_fail(display != NULL, NULL); - m = cache_lookup_display(cache, display); - if (!m) - return NULL; + return cache_lookup(cache, compare_display, display); +} - entry = m->data; - return &entry->info; +/** + * gst_vaapi_display_cache_lookup_custom: + * @cache: the #GstVaapiDisplayCache + * @func: an comparison function + * @data: user data passed to the function + * + * Looks up an element in the display @cache using the supplied + * function @func to find the desired element. It iterates over all + * elements in cache, calling the given function which should return + * %TRUE when the desired element is found. + * + * The comparison function takes two gconstpointer arguments, a + * #GstVaapiDisplayInfo as the first argument, and that is used to + * compare against the given user @data argument as the second + * argument. + * + * Return value: a #GstVaapiDisplayInfo causing @func to succeed + * (i.e. returning %TRUE), or %NULL if none was found + */ +const GstVaapiDisplayInfo * +gst_vaapi_display_cache_lookup_custom(GstVaapiDisplayCache *cache, + GCompareFunc func, gconstpointer data) +{ + g_return_val_if_fail(cache != NULL, NULL); + g_return_val_if_fail(func != NULL, NULL); + + return cache_lookup(cache, func, data); } /** @@ -297,18 +333,10 @@ gst_vaapi_display_cache_lookup_by_va_display( VADisplay va_display ) { - CacheEntry *entry; - GList *m; - g_return_val_if_fail(cache != NULL, NULL); g_return_val_if_fail(va_display != NULL, NULL); - m = cache_lookup_va_display(cache, va_display); - if (!m) - return NULL; - - entry = m->data; - return &entry->info; + return cache_lookup(cache, compare_va_display, va_display); } /** @@ -327,30 +355,18 @@ gst_vaapi_display_cache_lookup_by_native_display( gpointer native_display ) { - CacheEntry *entry; - GList *m; - g_return_val_if_fail(cache != NULL, NULL); g_return_val_if_fail(native_display != NULL, NULL); - m = cache_lookup_native_display(cache, native_display); - if (!m) - return NULL; - - entry = m->data; - return &entry->info; + return cache_lookup(cache, compare_native_display, native_display); } /** * gst_vaapi_display_cache_lookup_by_name: * @cache: the #GstVaapiDisplayCache * @display_name: the display name to match - * @compare_func: an optional string comparison function - * @user_data: any relevant data pointer to the comparison function * - * Looks up the display cache for the specified display name. A - * specific comparison function can be provided to avoid a plain - * strcmp(). + * Looks up the display cache for the specified display name. * * Return value: a #GstVaapiDisplayInfo matching @display_name, or * %NULL if none was found @@ -358,23 +374,10 @@ gst_vaapi_display_cache_lookup_by_native_display( const GstVaapiDisplayInfo * gst_vaapi_display_cache_lookup_by_name( GstVaapiDisplayCache *cache, - const gchar *display_name, - GCompareDataFunc compare_func, - gpointer user_data + const gchar *display_name ) { - CacheEntry *entry; - GList *m; - g_return_val_if_fail(cache != NULL, NULL); - if (compare_func) - CACHE_LOOKUP(cache, m, display_name, compare_func, display_name, user_data); - else - CACHE_LOOKUP(cache, m, display_name, compare_string, display_name, NULL); - if (!m) - return NULL; - - entry = m->data; - return &entry->info; + return cache_lookup(cache, compare_display_name, display_name); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h index 12c29531d3..70e4d28f9e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.h +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.h @@ -53,6 +53,13 @@ gst_vaapi_display_cache_lookup( GstVaapiDisplay *display ); +const GstVaapiDisplayInfo * +gst_vaapi_display_cache_lookup_custom( + GstVaapiDisplayCache *cache, + GCompareFunc func, + gconstpointer data +); + const GstVaapiDisplayInfo * gst_vaapi_display_cache_lookup_by_va_display( GstVaapiDisplayCache *cache, @@ -68,9 +75,7 @@ gst_vaapi_display_cache_lookup_by_native_display( const GstVaapiDisplayInfo * gst_vaapi_display_cache_lookup_by_name( GstVaapiDisplayCache *cache, - const gchar *display_name, - GCompareDataFunc compare_func, - gpointer user_data + const gchar *display_name ); #endif /* GSTVAAPIDISPLAYCACHE_H */ From c957823e8a504dc116c3aaca35c6949a87908bea Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 24 May 2013 16:19:23 +0200 Subject: [PATCH 1197/3781] display: cope with new display cache API. --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 18 +----------------- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 11 ++++++----- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 11 ++++++----- 3 files changed, 13 insertions(+), 27 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 641a8ed2b1..8720b4bebf 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -48,21 +48,6 @@ is_device_path(const gchar *device_path) return strncmp(device_path, NAME_PREFIX, NAME_PREFIX_LENGTH) == 0; } -static gboolean -compare_device_path(gconstpointer a, gconstpointer b, gpointer user_data) -{ - const gchar *cached_name = a; - const gchar *tested_name = b; - - if (!cached_name || !is_device_path(cached_name)) - return FALSE; - g_return_val_if_fail(tested_name && is_device_path(tested_name), FALSE); - - cached_name += NAME_PREFIX_LENGTH; - tested_name += NAME_PREFIX_LENGTH; - return strcmp(cached_name, tested_name) == 0; -} - /* Get default device path. Actually, the first match in the DRM subsystem */ static const gchar * get_default_device_path(GstVaapiDisplay *display) @@ -254,8 +239,7 @@ gst_vaapi_display_drm_open_display(GstVaapiDisplay *display, const gchar *name) if (!set_device_path(display, name)) return FALSE; - info = gst_vaapi_display_cache_lookup_by_name(cache, priv->device_path, - compare_device_path, NULL); + info = gst_vaapi_display_cache_lookup_by_name(cache, priv->device_path); if (info) { priv->drm_device = GPOINTER_TO_INT(info->native_display); priv->use_foreign_display = TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 2d9c778c2b..11087e3670 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -63,10 +63,11 @@ get_display_name_length(const gchar *display_name) return strlen(display_name); } -static gboolean -compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data) +static gint +compare_display_name(gconstpointer a, gconstpointer b) { - const gchar *cached_name = a; + const GstVaapiDisplayInfo * const info = a; + const gchar *cached_name = info->display_name; const gchar *tested_name = b; guint cached_name_length, tested_name_length; @@ -248,8 +249,8 @@ gst_vaapi_display_wayland_open_display(GstVaapiDisplay *display, if (!set_display_name(display, name)) return FALSE; - info = gst_vaapi_display_cache_lookup_by_name(cache, priv->display_name, - compare_display_name, NULL); + info = gst_vaapi_display_cache_lookup_custom(cache, compare_display_name, + priv->display_name); if (info) { priv->wl_display = info->native_display; priv->use_foreign_display = TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 7cbc5a6a47..b23cb6e240 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -58,10 +58,11 @@ get_default_display_name(void) return g_display_name; } -static gboolean -compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data) +static gint +compare_display_name(gconstpointer a, gconstpointer b) { - const gchar *cached_name = a, *cached_name_end; + const GstVaapiDisplayInfo * const info = a; + const gchar *cached_name = info->display_name, *cached_name_end; const gchar *tested_name = b, *tested_name_end; guint cached_name_length, tested_name_length; @@ -196,8 +197,8 @@ gst_vaapi_display_x11_open_display(GstVaapiDisplay *base_display, if (!set_display_name(display, name)) return FALSE; - info = gst_vaapi_display_cache_lookup_by_name(cache, priv->display_name, - compare_display_name, NULL); + info = gst_vaapi_display_cache_lookup_custom(cache, compare_display_name, + priv->display_name); if (info) { priv->x11_display = info->native_display; priv->use_foreign_display = TRUE; From 71ab07d9c6ef2268078e8448c81e82e33470fce8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 27 May 2013 13:17:31 +0200 Subject: [PATCH 1198/3781] display: make it possible to lookup the display cache by type. Make it possible to add extra an extra filter to most of display cache lookup functions so that the GstVaapiDisplay instance can really match a compatible and existing display by type, instead of relying on extra string tags (e.g. "X11:" prefix, etc.). --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 9 +++- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 3 ++ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 22 +++++++++ gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 7 ++- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 9 +++- gst-libs/gst/vaapi/gstvaapidisplaycache.c | 50 +++++++++++++++----- gst-libs/gst/vaapi/gstvaapidisplaycache.h | 9 ++-- 7 files changed, 87 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 8720b4bebf..3d416baa65 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -42,6 +42,8 @@ #define NAME_PREFIX "DRM:" #define NAME_PREFIX_LENGTH 4 +static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_DRM; + static inline gboolean is_device_path(const gchar *device_path) { @@ -239,7 +241,8 @@ gst_vaapi_display_drm_open_display(GstVaapiDisplay *display, const gchar *name) if (!set_device_path(display, name)) return FALSE; - info = gst_vaapi_display_cache_lookup_by_name(cache, priv->device_path); + info = gst_vaapi_display_cache_lookup_by_name(cache, priv->device_path, + GST_VAAPI_DISPLAY_TYPES(display)); if (info) { priv->drm_device = GPOINTER_TO_INT(info->native_display); priv->use_foreign_display = TRUE; @@ -290,7 +293,8 @@ gst_vaapi_display_drm_get_display_info(GstVaapiDisplay *display, if (!cache) return FALSE; cached_info = gst_vaapi_display_cache_lookup_by_native_display( - cache, GINT_TO_POINTER(priv->drm_device)); + cache, GINT_TO_POINTER(priv->drm_device), + GST_VAAPI_DISPLAY_TYPES(display)); if (cached_info) { *info = *cached_info; return TRUE; @@ -327,6 +331,7 @@ gst_vaapi_display_drm_class_init(GstVaapiDisplayDRMClass *klass) gst_vaapi_display_class_init(&klass->parent_class); object_class->size = sizeof(GstVaapiDisplayDRM); + dpy_class->display_types = g_display_types; dpy_class->init = gst_vaapi_display_drm_init; dpy_class->bind_display = gst_vaapi_display_drm_bind_display; dpy_class->open_display = gst_vaapi_display_drm_open_display; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 0810239602..f81f381d2b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -37,6 +37,8 @@ #define DEBUG 1 #include "gstvaapidebug.h" +static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_GLX; + static gboolean gst_vaapi_display_glx_get_display_info( GstVaapiDisplay *display, @@ -64,6 +66,7 @@ gst_vaapi_display_glx_class_init(GstVaapiDisplayGLXClass *klass) object_class->size = sizeof(GstVaapiDisplayGLX); klass->parent_get_display = dpy_class->get_display; + dpy_class->display_types = g_display_types; dpy_class->get_display = gst_vaapi_display_glx_get_display_info; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 24bf751793..0608f428fd 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -96,6 +96,16 @@ typedef void (*GstVaapiDisplayGetSizeMFunc)(GstVaapiDisplay *display, #define GST_VAAPI_DISPLAY_UNLOCK(display) \ gst_vaapi_display_unlock(GST_VAAPI_DISPLAY_CAST(display)) +/** + * GST_VAAPI_DISPLAY_TYPES: + * @display: a #GstVaapiDisplay + * + * Returns compatible @display types as a set of flags + */ +#undef GST_VAAPI_DISPLAY_TYPES +#define GST_VAAPI_DISPLAY_TYPES(display) \ + gst_vaapi_display_get_display_types(GST_VAAPI_DISPLAY_CAST(display)) + struct _GstVaapiDisplayPrivate { GstVaapiDisplay *parent; GRecMutex mutex; @@ -145,6 +155,9 @@ struct _GstVaapiDisplayClass { /*< private >*/ GstVaapiMiniObjectClass parent_class; + /*< protected >*/ + guint display_types; + /*< public >*/ GstVaapiDisplayInitFunc init; GstVaapiDisplayBindFunc bind_display; @@ -176,6 +189,15 @@ gst_vaapi_display_new(const GstVaapiDisplayClass *klass, GstVaapiDisplayCache * gst_vaapi_display_get_cache(void); +static inline guint +gst_vaapi_display_get_display_types(GstVaapiDisplay *display) +{ + const GstVaapiDisplayClass * const dpy_class = + GST_VAAPI_DISPLAY_GET_CLASS(display); + + return dpy_class->display_types; +} + /* Inline reference counting for core libgstvaapi library */ #ifdef GST_VAAPI_CORE #define gst_vaapi_display_ref_internal(display) \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 11087e3670..1386a701c6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -36,6 +36,8 @@ #define NAME_PREFIX "WLD:" #define NAME_PREFIX_LENGTH 4 +static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_WAYLAND; + static inline gboolean is_display_name(const gchar *display_name) { @@ -250,7 +252,7 @@ gst_vaapi_display_wayland_open_display(GstVaapiDisplay *display, return FALSE; info = gst_vaapi_display_cache_lookup_custom(cache, compare_display_name, - priv->display_name); + priv->display_name, GST_VAAPI_DISPLAY_TYPES(display)); if (info) { priv->wl_display = info->native_display; priv->use_foreign_display = TRUE; @@ -303,7 +305,7 @@ gst_vaapi_display_wayland_get_display_info( if (!cache) return FALSE; cached_info = gst_vaapi_display_cache_lookup_by_native_display(cache, - priv->wl_display); + priv->wl_display, GST_VAAPI_DISPLAY_TYPES(display)); if (cached_info) { *info = *cached_info; return TRUE; @@ -380,6 +382,7 @@ gst_vaapi_display_wayland_class_init(GstVaapiDisplayWaylandClass * klass) gst_vaapi_display_class_init(&klass->parent_class); object_class->size = sizeof(GstVaapiDisplayWayland); + dpy_class->display_types = g_display_types; dpy_class->init = gst_vaapi_display_wayland_init; dpy_class->bind_display = gst_vaapi_display_wayland_bind_display; dpy_class->open_display = gst_vaapi_display_wayland_open_display; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index b23cb6e240..bcc80d3e2f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -42,6 +42,10 @@ #define NAME_PREFIX "X11:" #define NAME_PREFIX_LENGTH 4 +static const guint g_display_types = + (1U << GST_VAAPI_DISPLAY_TYPE_X11) | + (1U << GST_VAAPI_DISPLAY_TYPE_GLX); + static inline gboolean is_display_name(const gchar *display_name) { @@ -198,7 +202,7 @@ gst_vaapi_display_x11_open_display(GstVaapiDisplay *base_display, return FALSE; info = gst_vaapi_display_cache_lookup_custom(cache, compare_display_name, - priv->display_name); + priv->display_name, GST_VAAPI_DISPLAY_TYPES(display)); if (info) { priv->x11_display = info->native_display; priv->use_foreign_display = TRUE; @@ -275,7 +279,7 @@ gst_vaapi_display_x11_get_display_info( if (!cache) return FALSE; cached_info = gst_vaapi_display_cache_lookup_by_native_display( - cache, priv->x11_display); + cache, priv->x11_display, GST_VAAPI_DISPLAY_TYPES(display)); if (cached_info) { *info = *cached_info; return TRUE; @@ -380,6 +384,7 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) gst_vaapi_display_class_init(&klass->parent_class); object_class->size = sizeof(GstVaapiDisplayX11); + dpy_class->display_types = g_display_types; 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; diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index 6512bf8dd7..baca686314 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -83,15 +83,28 @@ error: return NULL; } +static inline gboolean +is_compatible_display_type(const GstVaapiDisplayType display_type, + guint display_types) +{ + if (display_type == GST_VAAPI_DISPLAY_TYPE_ANY) + return TRUE; + if (display_types == GST_VAAPI_DISPLAY_TYPE_ANY) + return TRUE; + return ((1U << display_type) & display_types) != 0; +} + static GList * cache_lookup_1(GstVaapiDisplayCache *cache, GCompareFunc func, - gconstpointer data) + gconstpointer data, guint display_types) { GList *l; g_mutex_lock(&cache->mutex); for (l = cache->list; l != NULL; l = l->next) { GstVaapiDisplayInfo * const info = &((CacheEntry *)l->data)->info; + if (!is_compatible_display_type(info->display_type, display_types)) + continue; if (func(info, data)) break; } @@ -101,9 +114,9 @@ cache_lookup_1(GstVaapiDisplayCache *cache, GCompareFunc func, static inline const GstVaapiDisplayInfo * cache_lookup(GstVaapiDisplayCache *cache, GCompareFunc func, - gconstpointer data) + gconstpointer data, guint display_types) { - GList * const m = cache_lookup_1(cache, func, data); + GList * const m = cache_lookup_1(cache, func, data, display_types); return m ? &((CacheEntry *)m->data)->info : NULL; } @@ -256,7 +269,8 @@ gst_vaapi_display_cache_remove( { GList *m; - m = cache_lookup_1(cache, compare_display, display); + m = cache_lookup_1(cache, compare_display, display, + GST_VAAPI_DISPLAY_TYPE_ANY); if (!m) return; @@ -285,7 +299,8 @@ gst_vaapi_display_cache_lookup( g_return_val_if_fail(cache != NULL, NULL); g_return_val_if_fail(display != NULL, NULL); - return cache_lookup(cache, compare_display, display); + return cache_lookup(cache, compare_display, display, + GST_VAAPI_DISPLAY_TYPE_ANY); } /** @@ -308,13 +323,17 @@ gst_vaapi_display_cache_lookup( * (i.e. returning %TRUE), or %NULL if none was found */ const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_custom(GstVaapiDisplayCache *cache, - GCompareFunc func, gconstpointer data) +gst_vaapi_display_cache_lookup_custom( + GstVaapiDisplayCache *cache, + GCompareFunc func, + gconstpointer data, + guint display_types +) { g_return_val_if_fail(cache != NULL, NULL); g_return_val_if_fail(func != NULL, NULL); - return cache_lookup(cache, func, data); + return cache_lookup(cache, func, data, display_types); } /** @@ -336,7 +355,8 @@ gst_vaapi_display_cache_lookup_by_va_display( g_return_val_if_fail(cache != NULL, NULL); g_return_val_if_fail(va_display != NULL, NULL); - return cache_lookup(cache, compare_va_display, va_display); + return cache_lookup(cache, compare_va_display, va_display, + GST_VAAPI_DISPLAY_TYPE_ANY); } /** @@ -352,13 +372,15 @@ gst_vaapi_display_cache_lookup_by_va_display( const GstVaapiDisplayInfo * gst_vaapi_display_cache_lookup_by_native_display( GstVaapiDisplayCache *cache, - gpointer native_display + gpointer native_display, + guint display_types ) { g_return_val_if_fail(cache != NULL, NULL); g_return_val_if_fail(native_display != NULL, NULL); - return cache_lookup(cache, compare_native_display, native_display); + return cache_lookup(cache, compare_native_display, native_display, + display_types); } /** @@ -374,10 +396,12 @@ gst_vaapi_display_cache_lookup_by_native_display( const GstVaapiDisplayInfo * gst_vaapi_display_cache_lookup_by_name( GstVaapiDisplayCache *cache, - const gchar *display_name + const gchar *display_name, + guint display_types ) { g_return_val_if_fail(cache != NULL, NULL); - return cache_lookup(cache, compare_display_name, display_name); + return cache_lookup(cache, compare_display_name, display_name, + display_types); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h index 70e4d28f9e..72b6fac038 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.h +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.h @@ -57,7 +57,8 @@ const GstVaapiDisplayInfo * gst_vaapi_display_cache_lookup_custom( GstVaapiDisplayCache *cache, GCompareFunc func, - gconstpointer data + gconstpointer data, + guint display_types ); const GstVaapiDisplayInfo * @@ -69,13 +70,15 @@ gst_vaapi_display_cache_lookup_by_va_display( const GstVaapiDisplayInfo * gst_vaapi_display_cache_lookup_by_native_display( GstVaapiDisplayCache *cache, - gpointer native_display + gpointer native_display, + guint display_types ); const GstVaapiDisplayInfo * gst_vaapi_display_cache_lookup_by_name( GstVaapiDisplayCache *cache, - const gchar *display_name + const gchar *display_name, + guint display_types ); #endif /* GSTVAAPIDISPLAYCACHE_H */ From b40cd3b382228505321286ff46e591786b09fc86 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 27 May 2013 16:13:33 +0200 Subject: [PATCH 1199/3781] display: drop internal NAME_PREFIX, store the real display name. Always store a valid display name/device path, instead of adding a particular prefix. i.e. make it simply a strdup(), or "" if it was initially NULL. --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 21 ++-------- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 43 ++------------------ gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 30 ++------------ 3 files changed, 11 insertions(+), 83 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 3d416baa65..5ce7ac86c1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -39,17 +39,8 @@ #define DEBUG 1 #include "gstvaapidebug.h" -#define NAME_PREFIX "DRM:" -#define NAME_PREFIX_LENGTH 4 - static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_DRM; -static inline gboolean -is_device_path(const gchar *device_path) -{ - return strncmp(device_path, NAME_PREFIX, NAME_PREFIX_LENGTH) == 0; -} - /* Get default device path. Actually, the first match in the DRM subsystem */ static const gchar * get_default_device_path(GstVaapiDisplay *display) @@ -113,13 +104,7 @@ get_device_path(GstVaapiDisplay *display) GST_VAAPI_DISPLAY_DRM_PRIVATE(display); const gchar *device_path = priv->device_path; - if (!device_path) - return NULL; - - g_return_val_if_fail(is_device_path(device_path), NULL); - - device_path += NAME_PREFIX_LENGTH; - if (*device_path == '\0') + if (!device_path || *device_path == '\0') return NULL; return device_path; } @@ -139,7 +124,7 @@ set_device_path(GstVaapiDisplay *display, const gchar *device_path) if (!device_path) return FALSE; } - priv->device_path = g_strdup_printf("%s%s", NAME_PREFIX, device_path); + priv->device_path = g_strdup(device_path); return priv->device_path != NULL; } @@ -198,7 +183,7 @@ set_device_path_from_fd(GstVaapiDisplay *display, gint drm_device) continue; path = udev_device_get_devnode(device); - priv->device_path = g_strdup_printf("%s%s", NAME_PREFIX, path); + priv->device_path = g_strdup(path); udev_device_unref(device); break; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 1386a701c6..f454768237 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -33,17 +33,8 @@ #define DEBUG 1 #include "gstvaapidebug.h" -#define NAME_PREFIX "WLD:" -#define NAME_PREFIX_LENGTH 4 - static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_WAYLAND; -static inline gboolean -is_display_name(const gchar *display_name) -{ - return strncmp(display_name, NAME_PREFIX, NAME_PREFIX_LENGTH) == 0; -} - static inline const gchar * get_default_display_name(void) { @@ -73,13 +64,10 @@ compare_display_name(gconstpointer a, gconstpointer b) const gchar *tested_name = b; guint cached_name_length, tested_name_length; - if (!cached_name || !is_display_name(cached_name)) - return FALSE; - cached_name += NAME_PREFIX_LENGTH; - cached_name_length = get_display_name_length(cached_name); + g_return_val_if_fail(cached_name, FALSE); + g_return_val_if_fail(tested_name, FALSE); - g_return_val_if_fail(tested_name && is_display_name(tested_name), FALSE); - tested_name += NAME_PREFIX_LENGTH; + cached_name_length = get_display_name_length(cached_name); tested_name_length = get_display_name_length(tested_name); /* XXX: handle screen number and default WAYLAND_DISPLAY name */ @@ -90,29 +78,6 @@ compare_display_name(gconstpointer a, gconstpointer b) return TRUE; } -/* Reconstruct a display name without our prefix */ -static const gchar * -get_display_name(GstVaapiDisplayWayland *display) -{ - GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); - const gchar *display_name = priv->display_name; - - if (!display_name) - return NULL; - - if (is_display_name(display_name)) { - display_name += NAME_PREFIX_LENGTH; - if (*display_name == '\0') - return NULL; - return display_name; - } - - /* XXX: this should not happen */ - g_assert(0 && "display name without prefix"); - return display_name; -} - /* Mangle display name with our prefix */ static gboolean set_display_name(GstVaapiDisplay *display, const gchar *display_name) @@ -127,7 +92,7 @@ set_display_name(GstVaapiDisplay *display, const gchar *display_name) if (!display_name) display_name = ""; } - priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, display_name); + priv->display_name = g_strdup(display_name); return priv->display_name != NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index bcc80d3e2f..c765ac6043 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -39,19 +39,10 @@ #define DEBUG 1 #include "gstvaapidebug.h" -#define NAME_PREFIX "X11:" -#define NAME_PREFIX_LENGTH 4 - static const guint g_display_types = (1U << GST_VAAPI_DISPLAY_TYPE_X11) | (1U << GST_VAAPI_DISPLAY_TYPE_GLX); -static inline gboolean -is_display_name(const gchar *display_name) -{ - return strncmp(display_name, NAME_PREFIX, NAME_PREFIX_LENGTH) == 0; -} - static inline const gchar * get_default_display_name(void) { @@ -70,18 +61,15 @@ compare_display_name(gconstpointer a, gconstpointer b) const gchar *tested_name = b, *tested_name_end; guint cached_name_length, tested_name_length; - if (!cached_name || !is_display_name(cached_name)) - return FALSE; - g_return_val_if_fail(tested_name && is_display_name(tested_name), FALSE); + g_return_val_if_fail(cached_name, FALSE); + g_return_val_if_fail(tested_name, FALSE); - cached_name += NAME_PREFIX_LENGTH; cached_name_end = strchr(cached_name, ':'); if (cached_name_end) cached_name_length = cached_name_end - cached_name; else cached_name_length = strlen(cached_name); - tested_name += NAME_PREFIX_LENGTH; tested_name_end = strchr(tested_name, ':'); if (tested_name_end) tested_name_length = tested_name_end - tested_name; @@ -104,18 +92,8 @@ get_display_name(GstVaapiDisplayX11 *display) GstVaapiDisplayX11Private * const priv = &display->priv; const gchar *display_name = priv->display_name; - if (!display_name) + if (!display_name || *display_name == '\0') return NULL; - - if (is_display_name(display_name)) { - display_name += NAME_PREFIX_LENGTH; - if (*display_name == '\0') - return NULL; - return display_name; - } - - /* XXX: this should not happen */ - g_assert(0 && "display name without prefix"); return display_name; } @@ -132,7 +110,7 @@ set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name) if (!display_name) display_name = ""; } - priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, display_name); + priv->display_name = g_strdup(display_name); return priv->display_name != NULL; } From b1e5dfab96ac9cb1fdc50aa5a7176680c4f453e6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 27 May 2013 17:18:40 +0200 Subject: [PATCH 1200/3781] display: validate display types. --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 4 ++-- gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h | 5 +++++ gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 4 ++++ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 10 ++++++++++ gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h | 4 ++++ gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 6 +++--- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 5 +++++ gst-libs/gst/vaapi/gstvaapitexture.c | 5 +++-- gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 3 +++ gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 4 ++++ gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 3 +++ 13 files changed, 49 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 5ce7ac86c1..68cc119d6a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -391,7 +391,7 @@ gst_vaapi_display_drm_new_with_device(gint device) gint gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display) { - g_return_val_if_fail(display != NULL, -1); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), -1); return GST_VAAPI_DISPLAY_DRM_DEVICE(display); } @@ -412,7 +412,7 @@ gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display) const gchar * gst_vaapi_display_drm_get_device_path(GstVaapiDisplayDRM *display) { - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), NULL); return get_device_path(GST_VAAPI_DISPLAY_CAST(display)); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h index 3b8df8ceb9..8e40b22ca8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h @@ -23,9 +23,14 @@ #define GST_VAAPI_DISPLAY_DRM_PRIV_H #include +#include "gstvaapidisplay_priv.h" G_BEGIN_DECLS +#define GST_VAAPI_IS_DISPLAY_DRM(display) \ + ((display) != NULL && \ + GST_VAAPI_DISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_DRM) + #define GST_VAAPI_DISPLAY_DRM_CAST(display) \ ((GstVaapiDisplayDRM *)(display)) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index 72e44d4795..e0cee01880 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -28,6 +28,10 @@ G_BEGIN_DECLS +#define GST_VAAPI_IS_DISPLAY_GLX(display) \ + ((display) != NULL && \ + GST_VAAPI_DISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_GLX) + #define GST_VAAPI_DISPLAY_GLX_CAST(display) \ ((GstVaapiDisplayGLX *)(display)) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 0608f428fd..81768208ab 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -96,6 +96,16 @@ typedef void (*GstVaapiDisplayGetSizeMFunc)(GstVaapiDisplay *display, #define GST_VAAPI_DISPLAY_UNLOCK(display) \ gst_vaapi_display_unlock(GST_VAAPI_DISPLAY_CAST(display)) +/** + * GST_VAAPI_DISPLAY_TYPE: + * @display: a #GstVaapiDisplay + * + * Returns the @display type + */ +#undef GST_VAAPI_DISPLAY_TYPE +#define GST_VAAPI_DISPLAY_TYPE(display) \ + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->display_type + /** * GST_VAAPI_DISPLAY_TYPES: * @display: a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index f454768237..ee25a93b6e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -420,7 +420,7 @@ gst_vaapi_display_wayland_new_with_display(struct wl_display *wl_display) struct wl_display * gst_vaapi_display_wayland_get_display(GstVaapiDisplayWayland *display) { - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_WAYLAND(display), NULL); return GST_VAAPI_DISPLAY_WL_DISPLAY(display); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index 3c09c5fe16..313697a07c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -27,6 +27,10 @@ G_BEGIN_DECLS +#define GST_VAAPI_IS_DISPLAY_WAYLAND(display) \ + ((display) != NULL && \ + GST_VAAPI_DISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_WAYLAND) + #define GST_VAAPI_DISPLAY_WAYLAND_CAST(display) \ ((GstVaapiDisplayWayland *)(display)) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index c765ac6043..10f3dfbc3e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -436,7 +436,7 @@ gst_vaapi_display_x11_new_with_display(Display *x11_display) Display * gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) { - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); return GST_VAAPI_DISPLAY_XDISPLAY(display); } @@ -454,7 +454,7 @@ gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) int gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display) { - g_return_val_if_fail(display != NULL, -1); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), -1); return GST_VAAPI_DISPLAY_XSCREEN(display); } @@ -474,7 +474,7 @@ void gst_vaapi_display_x11_set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous) { - g_return_if_fail(display != NULL); + g_return_if_fail(GST_VAAPI_IS_DISPLAY_X11(display)); set_synchronous(display, synchronous); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index 2d8203cb79..843950b2a9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -29,6 +29,11 @@ G_BEGIN_DECLS +#define GST_VAAPI_IS_DISPLAY_X11(display) \ + ((display) != NULL && \ + (GST_VAAPI_DISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_X11 || \ + GST_VAAPI_DISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_GLX)) + #define GST_VAAPI_DISPLAY_X11_CAST(display) \ ((GstVaapiDisplayX11 *)(display)) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index ae54ec33f2..4309f36297 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -32,6 +32,7 @@ #include "gstvaapiutils_glx.h" #include "gstvaapidisplay_glx.h" #include "gstvaapidisplay_x11_priv.h" +#include "gstvaapidisplay_glx_priv.h" #include "gstvaapiobject_priv.h" #define DEBUG 1 @@ -245,7 +246,7 @@ gst_vaapi_texture_new( { GstVaapiTexture *texture; - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); g_return_val_if_fail(target != GL_NONE, NULL); g_return_val_if_fail(format != GL_NONE, NULL); g_return_val_if_fail(width > 0, NULL); @@ -297,7 +298,7 @@ gst_vaapi_texture_new_with_texture( GLTextureState ts; gboolean success; - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); g_return_val_if_fail(target != GL_NONE, NULL); g_return_val_if_fail(format != GL_NONE, NULL); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c index 746f31fd3f..b4a05c97c7 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -27,6 +27,7 @@ #include "sysdeps.h" #include "gstvaapiwindow_drm.h" #include "gstvaapiwindow_priv.h" +#include "gstvaapidisplay_drm_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -147,6 +148,8 @@ gst_vaapi_window_drm_new( { GST_DEBUG("new window, size %ux%u", width, height); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), NULL); + return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( gst_vaapi_window_drm_class()), display, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 3802a32833..1c84250b76 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -30,6 +30,7 @@ #include "gstvaapiwindow_x11_priv.h" #include "gstvaapidisplay_x11.h" #include "gstvaapidisplay_x11_priv.h" +#include "gstvaapidisplay_glx_priv.h" #include "gstvaapiutils_x11.h" #include "gstvaapiutils_glx.h" @@ -362,6 +363,8 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( GstVaapiWindow * gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height) { + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); + return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( gst_vaapi_window_glx_class()), display, width, height); } @@ -383,6 +386,7 @@ gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid) { GST_DEBUG("new window from xid 0x%08x", xid); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); g_return_val_if_fail(xid != None, NULL); return gst_vaapi_window_new_from_native(GST_VAAPI_WINDOW_CLASS( diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 0c32c1d07a..fb88a2b0bf 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -411,6 +411,8 @@ gst_vaapi_window_wayland_new( { GST_DEBUG("new window, size %ux%u", width, height); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_WAYLAND(display), NULL); + return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( gst_vaapi_window_wayland_class()), display, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index d30bf09da3..d5fc0bbd90 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -479,6 +479,8 @@ gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) { GST_DEBUG("new window, size %ux%u", width, height); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); + return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( gst_vaapi_window_x11_class()), display, width, height); } @@ -500,6 +502,7 @@ gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) { GST_DEBUG("new window from xid 0x%08x", xid); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); g_return_val_if_fail(xid != None, NULL); return gst_vaapi_window_new_from_native(GST_VAAPI_WINDOW_CLASS( From 382542c74797b52b4c665c0b66a3f36a68fadd7a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 27 May 2013 15:59:08 +0200 Subject: [PATCH 1201/3781] window: fix GLX window initialization. Make sure to create the GLX context once the window object has completed its creation. Since gl_resize() relies on the newly created window size, then we cannot simply overload the GstVaapiWindowClass::create() hook. So, we just call into gst_vaapi_window_glx_ensure_context() once the window object is created in the gst_vaapi_window_glx_new*() functions. --- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 28 +++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 1c84250b76..d725178dee 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -363,10 +363,22 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( GstVaapiWindow * gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height) { + GstVaapiWindow *window; + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); - return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( + window = gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( gst_vaapi_window_glx_class()), display, width, height); + if (!window) + return NULL; + + if (!gst_vaapi_window_glx_ensure_context(window, NULL)) + goto error; + return window; + +error: + gst_vaapi_window_unref(window); + return NULL; } /** @@ -384,13 +396,25 @@ gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height) GstVaapiWindow * gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid) { + GstVaapiWindow *window; + GST_DEBUG("new window from xid 0x%08x", xid); g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); g_return_val_if_fail(xid != None, NULL); - return gst_vaapi_window_new_from_native(GST_VAAPI_WINDOW_CLASS( + window = gst_vaapi_window_new_from_native(GST_VAAPI_WINDOW_CLASS( gst_vaapi_window_glx_class()), display, GINT_TO_POINTER(xid)); + if (!window) + return NULL; + + if (!gst_vaapi_window_glx_ensure_context(window, NULL)) + goto error; + return window; + +error: + gst_vaapi_window_unref(window); + return NULL; } /** From c12dc19b8b5bde6cf370afd1b012b1cb13220fda Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 27 May 2013 14:01:48 +0200 Subject: [PATCH 1202/3781] vaapisink: fix one-time initialization when display property is set. Fix gst_vaapisink_ensure_display() to perform one-time initialization tasks even if the `display' property was explicitly set. --- gst/vaapi/gstvaapisink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index d9da5ccb22..808739b2e9 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -329,12 +329,13 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink) { GstVaapiDisplayType display_type; GstVaapiRenderMode render_mode; + const gboolean had_display = sink->display != NULL; if (!gst_vaapi_ensure_display(sink, sink->display_type, &sink->display)) return FALSE; display_type = gst_vaapi_display_get_display_type(sink->display); - if (display_type != sink->display_type) { + if (display_type != sink->display_type || (!had_display && sink->display)) { GST_INFO("created %s %p", get_display_type_name(display_type), sink->display); sink->display_type = display_type; From 18031dc6ffede9b2f6bb73a2d16edcb097b43566 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 30 May 2013 18:17:07 +0200 Subject: [PATCH 1203/3781] surface: fix memory leak through unreleased parent context. Break the circular references between GstVaapiContext and its children GstVaapiSurfaces. Since the VA surfaces held an extra reference to the context, which holds a reference to its VA surfaces, then none of those were released. How does this impact support for subpictures? The only situation when the parent context needs to disappear is when it is replaced with another one because of a resolution change in the video stream for instance, or a normal destroy. In this case, it does not really matter to apply subpictures to the peer surfaces since they are either gone, or those that are left in the pipe can probably bear a reinstantiation of the subpictures for it. So, parent_context is set to NULL when the parent context is destroyed, other VA surfaces can still get subpictures attached to them, individually not as a whole. i.e. subpictures for surface S1 will be created from active composition buffers and associated to S1, subpictures for S2 will be created from the next active composition buffers, etc. We don't try to cache the subpictures in those cases (pending surfaces until EOS is reached, or pending surfaces until new surfaces matching new VA context get to be used instead). --- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 1cfcec245c..42b8d5cb2d 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -312,7 +312,7 @@ gst_vaapi_surface_set_parent_context( { g_return_if_fail(surface != NULL); - gst_vaapi_object_replace(&surface->parent_context, context); + surface->parent_context = NULL; } /** From 33f641569640b6886a670454c431983bb6aeb519 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 3 Jun 2013 10:06:29 +0200 Subject: [PATCH 1204/3781] plugins: improve video memory flags safety checks. On map, ensure we have GST_MAP_WRITE flags since this is only what we support for now. Likewise, on unmap, make sure that the VA image is unmapped for either read or write, while still committing it to the VA surface if write was requested. --- gst/vaapi/gstvaapivideomemory.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index d6a52087fb..f8db2e2493 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -107,9 +107,10 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, allocator), FALSE); g_return_val_if_fail(mem->meta, FALSE); - if ((flags & GST_MAP_READWRITE) == GST_MAP_READ) + if ((flags & GST_MAP_READWRITE) != GST_MAP_WRITE) goto error_unsupported_map; + /* Map for writing */ if (++mem->map_count == 1) { if (!ensure_surface(mem)) goto error_ensure_surface; @@ -169,7 +170,9 @@ gst_video_meta_unmap_vaapi_memory(GstVideoMeta *meta, guint plane, g_return_val_if_fail(mem->image, FALSE); if (--mem->map_count == 0) { - gst_vaapi_image_unmap(mem->image); + /* Unmap VA image used for read/writes */ + if (info->flags & GST_MAP_READWRITE) + gst_vaapi_image_unmap(mem->image); /* Commit VA image to surface */ if ((info->flags & GST_MAP_WRITE) && !mem->use_direct_rendering) { From eb9dd361f8d3594f254299403fd1370805ca845c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 3 Jun 2013 10:22:44 +0200 Subject: [PATCH 1205/3781] plugins: silence check for direct-rendering mode in video memory. Fix gst_vaapi_video_allocator_new() to silently check for direct-rendering mode support, and not trigger fatal-criticals if either test surface or image could not be created. Typical case: pixel format mismatch, e.g. NV12 supported by most hardware vs. I420 supported by most software decoders. --- gst/vaapi/gstvaapivideomemory.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index f8db2e2493..e535a60b39 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -401,8 +401,10 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) GST_VIDEO_INFO_FORMAT_STRING(&allocator->surface_info), allocator->has_direct_rendering ? "yes" : "no"); } while (0); - gst_vaapi_object_unref(surface); - gst_vaapi_object_unref(image); + if (surface) + gst_vaapi_object_unref(surface); + if (image) + gst_vaapi_object_unref(image); } allocator->image_info = *vip; From e712abba11350e9517e373cd15876256c7f1017b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 5 Jun 2013 11:01:51 +0200 Subject: [PATCH 1206/3781] plugins: allow buffer mappings to GstVaapiSurfaceProxy. Allow plain gst_buffer_map() interface to work with gstreamer-vaapi video buffers, i.e. expose the underlying GstVaapiSurfaceProxy to the caller. This is the only sensible enough thing to do in this mode as the underlying surface pixels need to be extracted through an explicit call to the gst_video_frame_map() function instead. A possible use-case of this is to implement a "handoff" signal handler to fakesink or identity element for further processing. --- gst/vaapi/gstvaapivideomemory.c | 67 +++++++++++++++++++++++++++++++-- gst/vaapi/gstvaapivideomemory.h | 16 ++++++++ 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index e535a60b39..db27b08f15 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -107,6 +107,9 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, allocator), FALSE); g_return_val_if_fail(mem->meta, FALSE); + if (mem->map_type && + mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR) + goto error_incompatible_map; if ((flags & GST_MAP_READWRITE) != GST_MAP_WRITE) goto error_unsupported_map; @@ -118,6 +121,7 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, goto error_ensure_image; if (!gst_vaapi_image_map(mem->image)) goto error_map_image; + mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR; } *data = gst_vaapi_image_get_plane(mem->image, plane); @@ -126,6 +130,11 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, return TRUE; /* ERRORS */ +error_incompatible_map: + { + GST_ERROR("incompatible map type (%d)", mem->map_type); + return FALSE; + } error_unsupported_map: { GST_ERROR("unsupported map flags (0x%x)", flags); @@ -170,6 +179,8 @@ gst_video_meta_unmap_vaapi_memory(GstVideoMeta *meta, guint plane, g_return_val_if_fail(mem->image, FALSE); if (--mem->map_count == 0) { + mem->map_type = 0; + /* Unmap VA image used for read/writes */ if (info->flags & GST_MAP_READWRITE) gst_vaapi_image_unmap(mem->image); @@ -207,11 +218,13 @@ gst_vaapi_video_memory_new(GstAllocator *base_allocator, gst_memory_init(&mem->parent_instance, 0, base_allocator, NULL, GST_VIDEO_INFO_SIZE(vip), 0, 0, GST_VIDEO_INFO_SIZE(vip)); + mem->proxy = NULL; mem->surface_info = &allocator->surface_info; mem->surface = NULL; mem->image_info = &allocator->image_info; mem->image = NULL; mem->meta = gst_vaapi_video_meta_ref(meta); + mem->map_type = 0; mem->map_count = 0; mem->use_direct_rendering = allocator->has_direct_rendering; return GST_MEMORY_CAST(mem); @@ -229,21 +242,69 @@ gst_vaapi_video_memory_free(GstVaapiVideoMemory *mem) static gpointer gst_vaapi_video_memory_map(GstVaapiVideoMemory *mem, gsize maxsize, guint flags) { - GST_FIXME("unimplemented GstVaapiVideoAllocator::mem_map() hook"); + if (mem->map_type && + mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE) + goto error_incompatible_map; + + if (mem->map_count == 0) { + gst_vaapi_surface_proxy_replace(&mem->proxy, + gst_vaapi_video_meta_get_surface_proxy(mem->meta)); + if (!mem->proxy) + goto error_no_surface_proxy; + mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE; + } + mem->map_count++; + return mem->proxy; + + /* ERRORS */ +error_incompatible_map: + GST_ERROR("failed to map memory to a GstVaapiSurfaceProxy"); + return NULL; +error_no_surface_proxy: + GST_ERROR("failed to extract GstVaapiSurfaceProxy from video meta"); return NULL; } static void gst_vaapi_video_memory_unmap(GstVaapiVideoMemory *mem) { - GST_FIXME("unimplemented GstVaapiVideoAllocator::mem_unmap() hook"); + if (mem->map_type && + mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE) + goto error_incompatible_map; + + if (--mem->map_count == 0) { + gst_vaapi_surface_proxy_replace(&mem->proxy, NULL); + mem->map_type = 0; + } + return; + + /* ERRORS */ +error_incompatible_map: + GST_ERROR("incompatible map type (%d)", mem->map_type); + return; } static GstVaapiVideoMemory * gst_vaapi_video_memory_copy(GstVaapiVideoMemory *mem, gssize offset, gssize size) { - GST_FIXME("unimplemented GstVaapiVideoAllocator::mem_copy() hook"); + GstMemory *out_mem; + + if (offset != 0 || size != -1) + goto error_unsupported; + + out_mem = gst_vaapi_video_memory_new(mem->parent_instance.allocator, + mem->meta); + if (!out_mem) + goto error_allocate_memory; + return GST_VAAPI_VIDEO_MEMORY_CAST(out_mem); + + /* ERRORS */ +error_unsupported: + GST_ERROR("failed to copy partial memory (unsupported operation)"); + return NULL; +error_allocate_memory: + GST_ERROR("failed to allocate GstVaapiVideoMemory copy"); return NULL; } diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 615412da28..a169930361 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -42,6 +42,20 @@ typedef struct _GstVaapiVideoAllocatorClass GstVaapiVideoAllocatorClass; #define GST_VAAPI_VIDEO_MEMORY_NAME "GstVaapiVideoMemory" +/** + * GstVaapiVideoMemoryMapType: + * @GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: map with gst_buffer_map() + * as a whole and return a #GstVaapiSurfaceProxy + * @GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR: map individual plane with + * gst_video_frame_map() + * + * The set of all #GstVaapiVideoMemory map types. + */ +typedef enum { + GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE = 1, + GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR +} GstVaapiVideoMemoryMapType; + /** * GstVaapiVideoMemory: * @@ -52,11 +66,13 @@ struct _GstVaapiVideoMemory { GstMemory parent_instance; /*< private >*/ + GstVaapiSurfaceProxy *proxy; const GstVideoInfo *surface_info; GstVaapiSurface *surface; const GstVideoInfo *image_info; GstVaapiImage *image; GstVaapiVideoMeta *meta; + guint map_type; gint map_count; gboolean use_direct_rendering; }; From bbd7a130e29fb5ca69d4cb451ed36cb04d7e0cb6 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Tue, 4 Jun 2013 07:14:22 +0800 Subject: [PATCH 1207/3781] vaapisink: fix build without VA/GLX support. --- gst/vaapi/gstvaapisink.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 808739b2e9..324b482391 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -253,7 +253,9 @@ static void gst_vaapisink_destroy(GstVaapiSink *sink) { gst_buffer_replace(&sink->video_buffer, NULL); +#if USE_GLX gst_vaapi_texture_replace(&sink->texture, NULL); +#endif gst_vaapi_display_replace(&sink->display, NULL); g_clear_object(&sink->uploader); From 779325060762f2f743a19fc0071838ffc3808bf9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 31 May 2013 11:09:40 +0200 Subject: [PATCH 1208/3781] wayland: fix memory leak of display resources. --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index ee25a93b6e..b10165b6dc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -237,6 +237,16 @@ gst_vaapi_display_wayland_close_display(GstVaapiDisplay * display) GstVaapiDisplayWaylandPrivate * const priv = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + if (priv->output) { + wl_output_destroy(priv->output); + priv->output = NULL; + } + + if (priv->shell) { + wl_shell_destroy(priv->shell); + priv->shell = NULL; + } + if (priv->compositor) { wl_compositor_destroy(priv->compositor); priv->compositor = NULL; From 5fe72d9eff4dd8f3d826d916b58c653a60ae263e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 5 Jun 2013 17:42:00 +0200 Subject: [PATCH 1209/3781] NEWS: updates. --- NEWS | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index a5aa8c3ab4..609148e4a2 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,15 @@ -gst-vaapi NEWS -- summary of changes. 2013-04-18 +gst-vaapi NEWS -- summary of changes. 2013-06-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora +Version 0.5.4 - DD.Jun.2013 +* Fix destruction of Wayland display resources +* Fix explicit specification of display type to vaapisink +* Fix memory leak in vaapiupload in GStreamer 0.10 builds (Halley Zhao) +* Fix performance regression caused by improper use of GstTask callback +* Fix raw decoding mode to transfer ownership of surface proxy to caller + Version 0.5.3 - 18.Apr.2013 * Add support for GStreamer 1.0.x API (+Sreerenj Balachandran) * Fix build on Fedora 17 (Víctor Manuel Jáquez) From d3de247b2ee3c89202808354a9f4a9e25030e2a0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 12 Jun 2013 13:48:26 +0100 Subject: [PATCH 1210/3781] debian: fix libgstvaapi -dev package name. Fix libgstvaapi -dev package name so that to allow installation of both GStreamer 0.10 and 1.0.x based packages. --- configure.ac | 3 ++- debian.upstream/Makefile.am | 2 +- debian.upstream/control.in | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 3380626a2d..b93165c0f1 100644 --- a/configure.ac +++ b/configure.ac @@ -628,9 +628,10 @@ AC_CONFIG_FILES([ debian.upstream/gstreamer-vaapi-doc.install.in debian.upstream/gstreamer$GST_API_VERSION-vaapi.install:\ debian.upstream/gstreamer-vaapi.install.in + debian.upstream/libgstvaapi$GST_API_VERSION-dev.install:\ +debian.upstream/libgstvaapi-dev.install.in debian.upstream/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi.install.in - debian.upstream/libgstvaapi-dev.install debian.upstream/libgstvaapi-drm-$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi-drm.install.in debian.upstream/libgstvaapi-glx-$GST_VAAPI_MAJOR_VERSION.install:\ diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index f7e33496ff..07ada99c28 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -26,8 +26,8 @@ DEBIANGENFILES = \ control \ gstreamer$(GST_API_VERSION)-vaapi-doc.install \ gstreamer$(GST_API_VERSION)-vaapi.install \ + libgstvaapi$(GST_VAAPI_MAJOR_VERSION)-dev.install \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ - libgstvaapi-dev.install \ libgstvaapi-drm-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-wayland-$(GST_VAAPI_MAJOR_VERSION).install \ diff --git a/debian.upstream/control.in b/debian.upstream/control.in index cd51abc431..2ee622545c 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -32,7 +32,7 @@ Description: VA-API plugins for GStreamer Package: gstreamer@GST_API_VERSION@-vaapi-doc Architecture: all Section: doc -Recommends: libgstvaapi@GST_VAAPI_MAJOR_VERSION@-dev (= ${source:Version}) +Recommends: libgstvaapi@GST_API_VERSION@-dev (= ${source:Version}) Description: GStreamer VA-API documentation and manuals This packages contains documentation for libraries and elements. @@ -90,7 +90,7 @@ Description: GStreamer libraries from the "vaapi" set @USE_WAYLAND_TRUE@ . @USE_WAYLAND_TRUE@ This package contains Wayland libraries for the "vaapi" set. -Package: libgstvaapi-dev +Package: libgstvaapi@GST_API_VERSION@-dev Architecture: any Section: libdevel Depends: ${shlibs:Depends}, ${misc:Depends}, From a398fb64d608cc0dd96e97df4e82383c2a380b77 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 12 Jun 2013 14:16:17 +0100 Subject: [PATCH 1211/3781] debian: fix list of generated files for .deb packaging. --- debian.upstream/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index 07ada99c28..e4e606a193 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -26,7 +26,7 @@ DEBIANGENFILES = \ control \ gstreamer$(GST_API_VERSION)-vaapi-doc.install \ gstreamer$(GST_API_VERSION)-vaapi.install \ - libgstvaapi$(GST_VAAPI_MAJOR_VERSION)-dev.install \ + libgstvaapi$(GST_API_VERSION)-dev.install \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-drm-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ From d6cff6e14859dde75f0c0f3e26867590a1297d83 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 14 Jun 2013 11:14:23 +0200 Subject: [PATCH 1212/3781] codecparsers: update to gst-vaapi-branch commit 843ce3e. 843ce3e jpeg: fix default Huffman tables generation. 8655187 mpeg2: fix the pixel-aspect-ratio calculation 21099dc mpeg2: actually store video bitrate values dd02087 mpeg2: fix picture packet extension size check 25948e9 mpeg2: increase min size for picture coding ext f1f5a40 ensure the debug category is properly initialized --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 500bc02db4..843ce3e004 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 500bc02db4c55727d81d153da4e378d2420bedd8 +Subproject commit 843ce3e0041b37cde3349ca285918c145d66d0d0 From bcabfcc08b80f5d42920336266e95919c2e4b507 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 14 Jun 2013 11:32:36 +0200 Subject: [PATCH 1213/3781] configure: add --enable-builtin-codecparsers [default="yes"] option. Add flag to have all codecparsers built-in, thus ensuring that the resulting binaries have all the necessary bug fixes and this is what the QA has been testing anyway. Of course, for a completely up-to-date Linux distribution, you could also opt for --disable-builtin-codecparsers and use the system ones. Though, some core fixes could be missing, and those cannot be tested for with API checks. --- configure.ac | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/configure.ac b/configure.ac index b93165c0f1..be45f77602 100644 --- a/configure.ac +++ b/configure.ac @@ -89,6 +89,11 @@ dnl Initialize libtool LT_PREREQ([2.2]) LT_INIT +AC_ARG_ENABLE(builtin_codecparsers, + AS_HELP_STRING([--enable-builtin-codecparsers], + [enable built-in codecparsers @<:@default=yes@:>@]), + [], [enable_builtin_codecparsers="yes"]) + AC_ARG_ENABLE(drm, AS_HELP_STRING([--enable-drm], [enable DRM backend @<:@default=yes@:>@]), @@ -288,6 +293,11 @@ PKG_CHECK_MODULES([GST_BASEVIDEO], [gstreamer-basevideo-$GST_API_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) dnl ... bitstream parsers +if test "$enable_builtin_codecparsers" = "yes"; then + ac_cv_have_gst_mpeg2_parser="no" + ac_cv_have_gst_h264_parser="no" + ac_cv_have_gst_jpeg_parser="no" +fi PKG_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_API_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) From 4559f691a1285e415605c10e705ff58d131e4d5d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 14 Jun 2013 11:39:54 +0200 Subject: [PATCH 1214/3781] configure: always build the MPEG-4 parser. Always build the MPEG-4 parser for now as there are also core fixes included in the parser that cannot be tested for with API checks. --- configure.ac | 3 ++- gst-libs/gst/codecparsers/Makefile.am | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index be45f77602..fca5cd9e2a 100644 --- a/configure.ac +++ b/configure.ac @@ -297,9 +297,10 @@ if test "$enable_builtin_codecparsers" = "yes"; then ac_cv_have_gst_mpeg2_parser="no" ac_cv_have_gst_h264_parser="no" ac_cv_have_gst_jpeg_parser="no" -fi +else PKG_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_API_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) +fi dnl ... MPEG-2 parser, with the required extensions AC_CACHE_CHECK([for MPEG-2 parser], diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index a09a8fd4e1..c0581e3cbe 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -21,9 +21,9 @@ libgstvaapi_codecparsers_libs = \ gen_source_c = parserutils.c gen_source_h = parserutils.h -# Always build VC-1 parser for now -gen_source_c += gstvc1parser.c -gen_source_h += gstvc1parser.h +# Always build VC-1 and MPEG-4 parsers for now +gen_source_c += gstvc1parser.c gstmpeg4parser.c +gen_source_h += gstvc1parser.h gstmpeg4parser.h if USE_LOCAL_CODEC_PARSERS_JPEG gen_source_c += gstjpegparser.c From 0fed6d8faf05d9b5c243ac851c0e7eaaf8dfeb6d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 14 Jun 2013 11:43:46 +0200 Subject: [PATCH 1215/3781] NEWS: updates. --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 609148e4a2..1b8b3c405c 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,9 @@ Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora Version 0.5.4 - DD.Jun.2013 +* Streamline core libgstvaapi decoding library (API/ABI changes) +* Use built-in codecparsers by default (or --disable-builtin-codecparsers) +* Fix default Huffman tables generation (Feng Yuan) * Fix destruction of Wayland display resources * Fix explicit specification of display type to vaapisink * Fix memory leak in vaapiupload in GStreamer 0.10 builds (Halley Zhao) From 1e1af8a5dfbb5374f650822e439ceba6b682ca39 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 14 Jun 2013 11:47:50 +0200 Subject: [PATCH 1216/3781] 0.5.4. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 1b8b3c405c..691836a45c 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2013-06-DD +gst-vaapi NEWS -- summary of changes. 2013-06-14 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora -Version 0.5.4 - DD.Jun.2013 +Version 0.5.4 - 14.Jun.2013 * Streamline core libgstvaapi decoding library (API/ABI changes) * Use built-in codecparsers by default (or --disable-builtin-codecparsers) * Fix default Huffman tables generation (Feng Yuan) diff --git a/configure.ac b/configure.ac index fca5cd9e2a..8708578097 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [4]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 9f410af4a3fdbf900b5284867869fb0afc20de66 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 14 Jun 2013 13:41:14 +0200 Subject: [PATCH 1217/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 8708578097..aefdbb404b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [4]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [5]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From b3525c824a76acb5c8fc2f3bf01477cbc88b60b2 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Sat, 27 Apr 2013 15:15:49 +0800 Subject: [PATCH 1218/3781] image: fix wrong check for rect bounds in copy_image(). --- gst-libs/gst/vaapi/gstvaapiimage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 72c04ff3ae..e08ae658dc 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -923,9 +923,9 @@ copy_image( if (rect) { if (rect->x >= src_image->width || - rect->x + src_image->width > src_image->width || + rect->x + rect->width > src_image->width || rect->y >= src_image->height || - rect->y + src_image->height > src_image->height) + rect->y + rect->height > src_image->height) return FALSE; } else { From 8e0d65b3275617735e7f0ca5e9d1aa640611a385 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Thu, 25 Apr 2013 17:07:13 +0100 Subject: [PATCH 1219/3781] configure: use GST_PLUGIN_PATH_1_0 instead of GST_PLUGIN_PATH for Gst 1.0. jhbuild sets $GST_PLUGIN_PATH_1_0 which overrides $GST_PLUGIN_PATH. https://bugzilla.gnome.org/show_bug.cgi?id=698858 Signed-off-by: Gwenole Beauchesne --- configure.ac | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index aefdbb404b..f7aa11735e 100644 --- a/configure.ac +++ b/configure.ac @@ -400,10 +400,15 @@ GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^([_]*gst_plug AC_SUBST(GST_PLUGIN_LDFLAGS) dnl Check for the GStreamer plugins directory -AC_ARG_VAR([GST_PLUGIN_PATH], [installation path for gstreamer-vaapi plugin elements]) +AC_ARG_VAR([GST_PLUGIN_PATH], [installation path for gstreamer-vaapi plugin elements for GStreamer 0.10]) +AC_ARG_VAR([GST_PLUGIN_PATH_1_0], [installation path for gstreamer-vaapi plugin elements for GStreamer 1.0]) AC_MSG_CHECKING([for GStreamer plugins directory]) -if test -d "$GST_PLUGIN_PATH"; then - GST_PLUGINS_DIR="$GST_PLUGIN_PATH" +case $GST_API_VERSION in +0.10) _gst_plugin_path="$GST_PLUGIN_PATH";; +1.0) _gst_plugin_path="$GST_PLUGIN_PATH_1_0";; +esac +if test -d "$_gst_plugin_path"; then + GST_PLUGINS_DIR="$_gst_plugin_path" else GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_API_VERSION --variable pluginsdir` if test -z "$GST_PLUGINS_DIR"; then From 2fafbd7b64fc8f9deb14af58a0e40d2c5ebf7f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Jun 2013 05:36:03 -0400 Subject: [PATCH 1220/3781] plugins: try to allocate a GLX display first over an X11 one. If the gstreamer-vaapi plug-in elements are built with GLX support, then try to allocate a GstVaapiDisplayGLX first before resorting to a VA/X11 display next. https://bugzilla.gnome.org/show_bug.cgi?id=701742 --- gst/vaapi/gstvaapipluginutil.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 855952ada4..fe7b2b7656 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -68,16 +68,16 @@ static const DisplayMap g_display_map[] = { GST_VAAPI_DISPLAY_TYPE_WAYLAND, gst_vaapi_display_wayland_new }, #endif -#if USE_X11 - { "x11", - GST_VAAPI_DISPLAY_TYPE_X11, - gst_vaapi_display_x11_new }, -#endif #if USE_GLX { "glx", GST_VAAPI_DISPLAY_TYPE_GLX, gst_vaapi_display_glx_new }, #endif +#if USE_X11 + { "x11", + GST_VAAPI_DISPLAY_TYPE_X11, + gst_vaapi_display_x11_new }, +#endif #if USE_DRM { "drm", GST_VAAPI_DISPLAY_TYPE_DRM, From ece5cb2d83d41fdecef4bbda874208b2089fb33a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 27 Jun 2013 13:53:46 +0200 Subject: [PATCH 1221/3781] vaapisink: add "use-glx" property for OpenGL rendering. Now that VA/GLX capable buffers are generated by default on X11, thus depending on a VA/GLX display, we stil want to use vaPutSurface() for rendering since it is faster. Anyway, OpenGL rendering in vaapisink was only meant for testing and enabling "fancy" effects to play with. This has no real value. So, disable OpenGL rendering by default. --- gst/vaapi/gstvaapisink.c | 29 ++++++++++++++++++++++++----- gst/vaapi/gstvaapisink.h | 1 + 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 324b482391..e53697be02 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -153,6 +153,7 @@ enum { PROP_DISPLAY_TYPE, PROP_FULLSCREEN, PROP_SYNCHRONOUS, + PROP_USE_GLX, PROP_USE_REFLECTION, PROP_ROTATION, }; @@ -1007,18 +1008,21 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) GST_WARNING("could not update subtitles"); switch (sink->display_type) { -#if USE_GLX - case GST_VAAPI_DISPLAY_TYPE_GLX: - success = gst_vaapisink_show_frame_glx(sink, surface, flags); - break; -#endif #if USE_DRM case GST_VAAPI_DISPLAY_TYPE_DRM: success = TRUE; break; #endif +#if USE_GLX + case GST_VAAPI_DISPLAY_TYPE_GLX: + if (!sink->use_glx) + goto put_surface_x11; + success = gst_vaapisink_show_frame_glx(sink, surface, flags); + break; +#endif #if USE_X11 case GST_VAAPI_DISPLAY_TYPE_X11: + put_surface_x11: success = gst_vaapisink_put_surface(sink, surface, flags); break; #endif @@ -1164,6 +1168,9 @@ gst_vaapisink_set_property( case PROP_SYNCHRONOUS: sink->synchronous = g_value_get_boolean(value); break; + case PROP_USE_GLX: + sink->use_glx = g_value_get_boolean(value); + break; case PROP_USE_REFLECTION: sink->use_reflection = g_value_get_boolean(value); break; @@ -1196,6 +1203,9 @@ gst_vaapisink_get_property( case PROP_SYNCHRONOUS: g_value_set_boolean(value, sink->synchronous); break; + case PROP_USE_GLX: + g_value_set_boolean(value, sink->use_glx); + break; case PROP_USE_REFLECTION: g_value_set_boolean(value, sink->use_reflection); break; @@ -1256,6 +1266,15 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); #if USE_GLX + g_object_class_install_property + (object_class, + PROP_USE_GLX, + g_param_spec_boolean("use-glx", + "OpenGL rendering", + "Enables OpenGL rendering", + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_USE_REFLECTION, diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 58abb46895..b73065e34f 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -91,6 +91,7 @@ struct _GstVaapiSink { guint foreign_window : 1; guint fullscreen : 1; guint synchronous : 1; + guint use_glx : 1; guint use_reflection : 1; guint use_overlay : 1; guint use_rotation : 1; From 769f33cab29ab298a90b39257ca9dbbca26e1498 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 27 Jun 2013 12:25:44 +0300 Subject: [PATCH 1222/3781] vaapisink: expose the raw video formats in static caps template. Expose all raw video formats in the static caps template since the vaapisink is supporting raw data. We will get the exact set of formats supported by the driver dynamically through the _get_caps() routine. This also fixes an inconsistency wrt. GStreamer 0.10 builds. https://bugzilla.gnome.org/show_bug.cgi?id=702178 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index e53697be02..4a8c7443fe 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -83,7 +83,9 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink); /* Default template */ static const char gst_vaapisink_sink_caps_str[] = -#if !GST_CHECK_VERSION(1,0,0) +#if GST_CHECK_VERSION(1,0,0) + GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) "; " +#else "video/x-raw-yuv, " "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]; " From 7da02c8c59eb20a30e222c0879d7e7ae3cfdd7cc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 5 Jul 2013 17:51:26 +0200 Subject: [PATCH 1223/3781] codecparsers: update to gst-vaapi-branch commit dddd182. dddd182 mpeg2: add slice header parsing API 94e6228 mpeg2: add sequence scalable extension parsing API 531134f mpeg2: add new API that takes GstMpegVideoPacket arguments 4b135d3 h264: fix the return value type for the SEI palyload parsing methods --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 843ce3e004..0e44e0902f 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 843ce3e0041b37cde3349ca285918c145d66d0d0 +Subproject commit 0e44e0902fe9cc4e97fb926e823e44902ccbf79f From 800b66f07164a73e87a3b3e23fd38c14ed35e000 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 5 Jul 2013 15:49:34 +0200 Subject: [PATCH 1224/3781] mpeg2: cope with latest codecparser changes. Fix build with newer MPEG-2 codecparser where GstMpegVideoPacket are used in individual header parsers. Also use the new slice parsing API. --- configure.ac | 4 + gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 245 ++++++--------------- 2 files changed, 73 insertions(+), 176 deletions(-) diff --git a/configure.ac b/configure.ac index f7aa11735e..da8bd43f42 100644 --- a/configure.ac +++ b/configure.ac @@ -315,6 +315,10 @@ AC_CACHE_CHECK([for MPEG-2 parser], [[GstMpegVideoSequenceHdr seq_hdr; GstMpegVideoSequenceExt seq_ext; GstMpegVideoSequenceDisplayExt seq_dpy; + GstMpegVideoSliceHdr slice_hdr; + GstMpegVideoPacket packet; + gst_mpeg_video_packet_parse_slice_header(&packet, &slice_hdr, + &seq_hdr, NULL); gst_mpeg_video_finalise_mpeg2_sequence_header(&seq_hdr, &seq_ext, &seq_dpy);]])], [ac_cv_have_gst_mpeg2_parser="yes"], diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index b99d3e7ce7..c753b48c93 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -38,103 +38,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -/* ------------------------------------------------------------------------- */ -/* --- VLC Reader --- */ -/* ------------------------------------------------------------------------- */ - -#define READ_UINT8(br, val, nbits) G_STMT_START { \ - if (!gst_bit_reader_get_bits_uint8 (br, &val, nbits)) { \ - GST_WARNING ("failed to read uint8, nbits: %d", nbits); \ - goto failed; \ - } \ -} G_STMT_END - -#define SKIP(reader, nbits) G_STMT_START { \ - if (!gst_bit_reader_skip (reader, nbits)) { \ - GST_WARNING ("failed to skip nbits: %d", nbits); \ - goto failed; \ - } \ -} G_STMT_END - -/* VLC decoder from gst-plugins-bad */ -typedef struct _VLCTable VLCTable; -struct _VLCTable { - gint value; - guint cword; - guint cbits; -}; - -static gboolean -decode_vlc(GstBitReader *br, gint *res, const VLCTable *table, guint length) -{ - guint8 i; - guint cbits = 0; - guint32 value = 0; - - for (i = 0; i < length; i++) { - if (cbits != table[i].cbits) { - cbits = table[i].cbits; - if (!gst_bit_reader_peek_bits_uint32(br, &value, cbits)) { - goto failed; - } - } - - if (value == table[i].cword) { - SKIP(br, cbits); - if (res) - *res = table[i].value; - return TRUE; - } - } - GST_DEBUG("failed to find VLC code"); - -failed: - GST_WARNING("failed to decode VLC, returning"); - return FALSE; -} - -enum { - GST_MPEG_VIDEO_MACROBLOCK_ESCAPE = -1, -}; - -/* Table B-1: Variable length codes for macroblock_address_increment */ -static const VLCTable mpeg2_mbaddr_vlc_table[] = { - { 1, 0x01, 1 }, - { 2, 0x03, 3 }, - { 3, 0x02, 3 }, - { 4, 0x03, 4 }, - { 5, 0x02, 4 }, - { 6, 0x03, 5 }, - { 7, 0x02, 5 }, - { 8, 0x07, 7 }, - { 9, 0x06, 7 }, - { 10, 0x0b, 8 }, - { 11, 0x0a, 8 }, - { 12, 0x09, 8 }, - { 13, 0x08, 8 }, - { 14, 0x07, 8 }, - { 15, 0x06, 8 }, - { 16, 0x17, 10 }, - { 17, 0x16, 10 }, - { 18, 0x15, 10 }, - { 19, 0x14, 10 }, - { 20, 0x13, 10 }, - { 21, 0x12, 10 }, - { 22, 0x23, 11 }, - { 23, 0x22, 11 }, - { 24, 0x21, 11 }, - { 25, 0x20, 11 }, - { 26, 0x1f, 11 }, - { 27, 0x1e, 11 }, - { 28, 0x1d, 11 }, - { 29, 0x1c, 11 }, - { 30, 0x1b, 11 }, - { 31, 0x1a, 11 }, - { 32, 0x19, 11 }, - { 33, 0x18, 11 }, - { GST_MPEG_VIDEO_MACROBLOCK_ESCAPE, 0x08, 11 } -}; - /* ------------------------------------------------------------------------- */ /* --- PTS Generator --- */ /* ------------------------------------------------------------------------- */ @@ -245,17 +148,6 @@ pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn) /* --- MPEG-2 Parser Info --- */ /* ------------------------------------------------------------------------- */ -typedef struct _GstMpegVideoSliceHdr GstMpegVideoSliceHdr; -struct _GstMpegVideoSliceHdr { - guint16 slice_horizontal_position; - guint16 slice_vertical_position; - guint8 quantiser_scale_code; - guint8 intra_slice; - - /* Size of the slice() header in bits */ - guint header_size; -}; - typedef struct _GstVaapiParserInfoMpeg2 GstVaapiParserInfoMpeg2; struct _GstVaapiParserInfoMpeg2 { GstVaapiMiniObject parent_instance; @@ -265,6 +157,7 @@ struct _GstVaapiParserInfoMpeg2 { GstMpegVideoSequenceHdr seq_hdr; GstMpegVideoSequenceExt seq_ext; GstMpegVideoSequenceDisplayExt seq_display_ext; + GstMpegVideoSequenceScalableExt seq_scalable_ext; GstMpegVideoGop gop; GstMpegVideoQuantMatrixExt quant_matrix; GstMpegVideoPictureHdr pic_hdr; @@ -654,7 +547,7 @@ drop_frame: static GstVaapiDecoderStatus parse_sequence(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) + GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) { GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSequenceHdr *seq_hdr; @@ -668,8 +561,7 @@ parse_sequence(GstVaapiDecoderMpeg2 *decoder, seq_hdr = &priv->seq_hdr->data.seq_hdr; - if (!gst_mpeg_video_parse_sequence_header(seq_hdr, - packet->data, packet->size, packet->offset)) { + if (!gst_mpeg_video_packet_parse_sequence_header(packet, seq_hdr)) { GST_ERROR("failed to parse sequence header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -687,6 +579,7 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->seq_scalable_ext, NULL); priv->fps_n = seq_hdr->fps_n; priv->fps_d = seq_hdr->fps_d; @@ -705,7 +598,7 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) static GstVaapiDecoderStatus parse_sequence_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) + GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) { GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSequenceExt *seq_ext; @@ -719,8 +612,7 @@ parse_sequence_ext(GstVaapiDecoderMpeg2 *decoder, seq_ext = &priv->seq_ext->data.seq_ext; - if (!gst_mpeg_video_parse_sequence_extension(seq_ext, - packet->data, packet->size, packet->offset)) { + if (!gst_mpeg_video_packet_parse_sequence_extension(packet, seq_ext)) { GST_ERROR("failed to parse sequence-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -790,7 +682,7 @@ decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) static GstVaapiDecoderStatus parse_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) + GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) { GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSequenceDisplayExt *seq_display_ext; @@ -802,8 +694,8 @@ parse_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, seq_display_ext = &priv->seq_display_ext->data.seq_display_ext; - if (!gst_mpeg_video_parse_sequence_display_extension(seq_display_ext, - packet->data, packet->size, packet->offset)) { + if (!gst_mpeg_video_packet_parse_sequence_display_extension(packet, + seq_display_ext)) { GST_ERROR("failed to parse sequence-display-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -820,6 +712,38 @@ decode_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static GstVaapiDecoderStatus +parse_sequence_scalable_ext(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) +{ + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; + GstMpegVideoSequenceScalableExt *seq_scalable_ext; + + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_scalable_ext)) { + GST_ERROR("failed to allocate parser info for sequence scalable extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + seq_scalable_ext = &priv->seq_scalable_ext->data.seq_scalable_ext; + + if (!gst_mpeg_video_packet_parse_sequence_scalable_extension(packet, + seq_scalable_ext)) { + GST_ERROR("failed to parse sequence-scalable-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + gst_vaapi_decoder_unit_set_parsed_info(unit, seq_scalable_ext, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence_scalable_ext(GstVaapiDecoderMpeg2 *decoder, + GstVaapiDecoderUnit *unit) +{ + /* XXX: unsupported header -- ignore */ + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) { @@ -831,7 +755,7 @@ decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) static GstVaapiDecoderStatus parse_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) + GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) { GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoQuantMatrixExt *quant_matrix; @@ -843,8 +767,8 @@ parse_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, quant_matrix = &priv->quant_matrix->data.quant_matrix; - if (!gst_mpeg_video_parse_quant_matrix_extension(quant_matrix, - packet->data, packet->size, packet->offset)) { + if (!gst_mpeg_video_packet_parse_quant_matrix_extension(packet, + quant_matrix)) { GST_ERROR("failed to parse quant-matrix-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -865,7 +789,7 @@ decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, static GstVaapiDecoderStatus parse_gop(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) + GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) { GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoGop *gop; @@ -877,8 +801,7 @@ parse_gop(GstVaapiDecoderMpeg2 *decoder, gop = &priv->gop->data.gop; - if (!gst_mpeg_video_parse_gop(gop, - packet->data, packet->size, packet->offset)) { + if (!gst_mpeg_video_packet_parse_gop(packet, gop)) { GST_ERROR("failed to parse GOP"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -906,7 +829,7 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) static GstVaapiDecoderStatus parse_picture(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) + GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) { GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoPictureHdr *pic_hdr; @@ -921,8 +844,7 @@ parse_picture(GstVaapiDecoderMpeg2 *decoder, pic_hdr = &priv->pic_hdr->data.pic_hdr; - if (!gst_mpeg_video_parse_picture_header(pic_hdr, - packet->data, packet->size, packet->offset)) { + if (!gst_mpeg_video_packet_parse_picture_header(packet, pic_hdr)) { GST_ERROR("failed to parse picture header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -947,7 +869,7 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) static GstVaapiDecoderStatus parse_picture_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) + GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) { GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoPictureExt *pic_ext; @@ -963,8 +885,7 @@ parse_picture_ext(GstVaapiDecoderMpeg2 *decoder, pic_ext = &priv->pic_ext->data.pic_ext; - if (!gst_mpeg_video_parse_picture_extension(pic_ext, - packet->data, packet->size, packet->offset)) { + if (!gst_mpeg_video_packet_parse_picture_extension(packet, pic_ext)) { GST_ERROR("failed to parse picture-extension"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -1144,14 +1065,12 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) static GstVaapiDecoderStatus parse_slice(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet) + GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) { GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; GstMpegVideoSliceHdr *slice_hdr; - GstBitReader br; - gint mb_x, mb_y, mb_inc; - guint8 slice_vertical_position_extension = 0; - guint8 extra_bit_slice, junk8; + GstMpegVideoSequenceHdr *seq_hdr; + GstMpegVideoSequenceScalableExt *seq_scalable_ext; priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT| @@ -1164,49 +1083,18 @@ parse_slice(GstVaapiDecoderMpeg2 *decoder, } slice_hdr = &priv->slice_hdr->data.slice_hdr; + seq_hdr = &priv->seq_hdr->data.seq_hdr; + seq_scalable_ext = priv->seq_scalable_ext ? + &priv->seq_scalable_ext->data.seq_scalable_ext : NULL; - gst_bit_reader_init(&br, packet->data + packet->offset, packet->size); - if (priv->height > 2800) - READ_UINT8(&br, slice_vertical_position_extension, 3); - if (priv->seq_scalable_ext) { - GST_ERROR("failed to parse slice with sequence_scalable_extension()"); + if (!gst_mpeg_video_packet_parse_slice_header(packet, slice_hdr, + seq_hdr, seq_scalable_ext)) { + GST_ERROR("failed to parse slice header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } - READ_UINT8(&br, slice_hdr->quantiser_scale_code, 5); - READ_UINT8(&br, extra_bit_slice, 1); - if (!extra_bit_slice) - slice_hdr->intra_slice = 0; - else { - READ_UINT8(&br, slice_hdr->intra_slice, 1); - READ_UINT8(&br, junk8, 7); - READ_UINT8(&br, extra_bit_slice, 1); - while (extra_bit_slice) { - READ_UINT8(&br, junk8, 8); - READ_UINT8(&br, extra_bit_slice, 1); - } - } - slice_hdr->header_size = 32 + gst_bit_reader_get_pos(&br); - - mb_y = ((guint)slice_vertical_position_extension << 7) + - packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN; - mb_x = -1; - do { - if (!decode_vlc(&br, &mb_inc, mpeg2_mbaddr_vlc_table, - G_N_ELEMENTS(mpeg2_mbaddr_vlc_table))) { - GST_WARNING("failed to decode first macroblock_address_increment"); - goto failed; - } - mb_x += mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE ? 33 : mb_inc; - } while (mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE); - - slice_hdr->slice_horizontal_position = mb_x; - slice_hdr->slice_vertical_position = mb_y; gst_vaapi_decoder_unit_set_parsed_info(unit, slice_hdr, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; - -failed: - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } static GstVaapiDecoderStatus @@ -1221,8 +1109,7 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; GstMapInfo map_info; - GST_DEBUG("slice %d (%u bytes)", slice_hdr->slice_vertical_position, - unit->size); + GST_DEBUG("slice %d (%u bytes)", slice_hdr->mb_row, unit->size); if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -1243,9 +1130,9 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) /* Fill in VASliceParameterBufferMPEG2 */ slice_param = slice->param; - slice_param->macroblock_offset = slice_hdr->header_size; - slice_param->slice_horizontal_position = slice_hdr->slice_horizontal_position; - slice_param->slice_vertical_position = slice_hdr->slice_vertical_position; + slice_param->macroblock_offset = slice_hdr->header_size + 32; + slice_param->slice_horizontal_position = slice_hdr->mb_column; + slice_param->slice_vertical_position = slice_hdr->mb_row; slice_param->quantiser_scale_code = slice_hdr->quantiser_scale_code; slice_param->intra_slice_flag = slice_hdr->intra_slice; @@ -1303,6 +1190,9 @@ parse_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY: status = parse_sequence_display_ext(decoder, unit, packet); break; + case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_SCALABLE: + status = parse_sequence_scalable_ext(decoder, unit, packet); + break; case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: status = parse_quant_matrix_ext(decoder, unit, packet); break; @@ -1354,6 +1244,9 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY: status = decode_sequence_display_ext(decoder, unit); break; + case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_SCALABLE: + status = decode_sequence_scalable_ext(decoder, unit); + break; case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: status = decode_quant_matrix_ext(decoder, unit); break; From c2ddf464e5484cb847dba6c078efc255ccfb5c4b Mon Sep 17 00:00:00 2001 From: Zhong Cong Date: Fri, 7 Jun 2013 20:08:43 +0800 Subject: [PATCH 1225/3781] mpeg2: reset quantization matrices on new sequence headers. The MPEG-2 standard specifies (6.3.7) that all quantisation matrices shall be reset to their default values when a Sequence_Header() is decoded. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index c753b48c93..bb67bd5c89 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -580,6 +580,7 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->seq_scalable_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, NULL); priv->fps_n = seq_hdr->fps_n; priv->fps_d = seq_hdr->fps_d; From b80a804b0848de6f4cb7708aa17c58ef9d4ffbab Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 5 Jul 2013 19:03:41 +0200 Subject: [PATCH 1226/3781] codecparsers: update to gst-vaapi-branch commit 0f68a71. 0f68a71 mpeg2: fix video packet header size checks --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 0e44e0902f..5b90f9d79f 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 0e44e0902fe9cc4e97fb926e823e44902ccbf79f +Subproject commit 5b90f9d79f752149f9db13cf5b872a413d67d6de From 746631c64c1b5282e98b483bc672d4714c21dc4b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 8 Jul 2013 17:30:30 +0200 Subject: [PATCH 1227/3781] codecparsers: update to gst-vaapi-branch commit f90de0a. f90de0a h264: fix calculation of the frame cropping rectangle 535515c h264: parse the cropping rectangle separately --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 5b90f9d79f..f90de0a583 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 5b90f9d79f752149f9db13cf5b872a413d67d6de +Subproject commit f90de0a5836546f8e37b41adca14f76bfaaec44d From e66e72e7e3d714309db64727eb1cc1f8b337c5a1 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 15 Feb 2013 18:42:12 +0200 Subject: [PATCH 1228/3781] decoder: add support for video cropping. Add gst_vaapi_picture_set_crop_rect() helper function to copy the video cropping information from raw bitstreams to each picture being decoded. Also add helper function to surface proxy to propagate that information outside of libgstvaapi. e.g. plug-in elements or standalone applications. Signed-off-by: Sreerenj Balachandran Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 20 +++++++ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 7 +++ gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 57 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 7 +++ .../gst/vaapi/gstvaapisurfaceproxy_priv.h | 13 +++++ 5 files changed, 104 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 3390aea76d..92f0f7bbd9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -128,6 +128,11 @@ gst_vaapi_picture_create( } 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; @@ -308,6 +313,10 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) 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); @@ -330,6 +339,17 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) return TRUE; } +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 --- */ /* ------------------------------------------------------------------------- */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index f0e173f650..9bc2436cf7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -131,6 +131,8 @@ struct _GstVaapiPicture { GstClockTime pts; gint32 poc; guint structure; + GstVaapiRectangle crop_rect; + guint has_crop_rect : 1; }; G_GNUC_INTERNAL @@ -166,6 +168,11 @@ 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); + static inline gpointer gst_vaapi_picture_ref(gpointer ptr) { diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index a2cd002fc3..9df4eaf0b9 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -33,6 +33,27 @@ #define DEBUG 1 #include "gstvaapidebug.h" +static void +set_crop_rect_from_surface(GstVaapiSurfaceProxy *proxy) +{ + guint width, height; + + gst_vaapi_surface_get_size(proxy->surface, &width, &height); + proxy->crop_rect.x = 0; + proxy->crop_rect.y = 0; + proxy->crop_rect.width = width; + proxy->crop_rect.height = height; +} + +static inline void +set_crop_rect(GstVaapiSurfaceProxy *proxy, const GstVaapiRectangle *crop_rect) +{ + if (crop_rect) + proxy->crop_rect = *crop_rect; + else + set_crop_rect_from_surface(proxy); +} + static void gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) { @@ -74,6 +95,8 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool); if (!proxy->surface) goto error; + set_crop_rect_from_surface(proxy); + proxy->timestamp = GST_CLOCK_TIME_NONE; proxy->duration = GST_CLOCK_TIME_NONE; proxy->destroy_func = NULL; @@ -238,3 +261,37 @@ gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy, proxy->destroy_func = destroy_func; proxy->destroy_data = user_data; } + +/** + * gst_vaapi_surface_proxy_get_crop_rect: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the #GstVaapiRectangle stored in the @proxy and that + * represents the cropping rectangle for the underlying surface to be + * used for rendering. + * + * Return value: the #GstVaapiRectangle + */ +const GstVaapiRectangle * +gst_vaapi_surface_proxy_get_crop_rect(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(proxy != NULL, NULL); + + return GST_VAAPI_SURFACE_PROXY_CROP_RECT(proxy); +} + +/** + * gst_vaapi_surface_proxy_set_crop_rect: + * @proxy: #GstVaapiSurfaceProxy + * @crop_rect: the #GstVaapiRectangle to be stored in @proxy + * + * Associates the @crop_rect with the @proxy + */ +void +gst_vaapi_surface_proxy_set_crop_rect(GstVaapiSurfaceProxy *proxy, + const GstVaapiRectangle *crop_rect) +{ + g_return_if_fail(proxy != NULL); + + set_crop_rect(proxy, crop_rect); +} diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index c9def5708e..69ddbc490c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -117,6 +117,13 @@ void gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy, GDestroyNotify destroy_func, gpointer user_data); +const GstVaapiRectangle * +gst_vaapi_surface_proxy_get_crop_rect(GstVaapiSurfaceProxy *proxy); + +void +gst_vaapi_surface_proxy_set_crop_rect(GstVaapiSurfaceProxy *proxy, + const GstVaapiRectangle *crop_rect); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_PROXY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index d3fbcbc3ed..6e5d75828a 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -41,6 +41,7 @@ struct _GstVaapiSurfaceProxy { GstClockTime duration; GDestroyNotify destroy_func; gpointer destroy_data; + GstVaapiRectangle crop_rect; }; #define GST_VAAPI_SURFACE_PROXY_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS @@ -98,4 +99,16 @@ struct _GstVaapiSurfaceProxy { #define GST_VAAPI_SURFACE_PROXY_DURATION(proxy) \ proxy->duration +/** + * GST_VAAPI_SURFACE_PROXY_CROP_RECT: + * @proxy: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the video cropping rectangle of the underlying @proxy surface. + * + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_SURFACE_PROXY_CROP_RECT +#define GST_VAAPI_SURFACE_PROXY_CROP_RECT(proxy) \ + &(proxy)->crop_rect + #endif /* GST_VAAPI_SURFACE_PROXY_PRIV_H */ From 99dfd44f3308de2588ca4c26cb59b868907082d6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 8 Jul 2013 11:43:27 +0200 Subject: [PATCH 1229/3781] surface: add simple surface info accessors as helper macros. Add helper macros to retrieve the VA surface information like size (width, height) or chroma type. This is a micro-optimization to avoid useless function calls and NULL pointer re-checks in internal routines. --- gst-libs/gst/vaapi/gstvaapisurface.c | 39 ++------------ gst-libs/gst/vaapi/gstvaapisurface_priv.h | 65 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 9 ++-- gst-libs/gst/vaapi/gstvaapiwindow.c | 8 ++- 4 files changed, 76 insertions(+), 45 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 42b8d5cb2d..e6329b956e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -30,41 +30,12 @@ #include "gstvaapiutils.h" #include "gstvaapisurface.h" #include "gstvaapisurface_priv.h" -#include "gstvaapiobject_priv.h" #include "gstvaapicontext.h" #include "gstvaapiimage.h" #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; - -/** - * GstVaapiSurface: - * - * A VA surface wrapper. - */ -struct _GstVaapiSurface { - /*< private >*/ - GstVaapiObject parent_instance; - - guint width; - guint height; - GstVaapiChromaType chroma_type; - GPtrArray *subpictures; - GstVaapiContext *parent_context; -}; - -/** - * GstVaapiSurfaceClass: - * - * A VA surface wrapper class. - */ -struct _GstVaapiSurfaceClass { - /*< private >*/ - GstVaapiObjectClass parent_class; -}; - static gboolean _gst_vaapi_surface_associate_subpicture( GstVaapiSurface *surface, @@ -236,7 +207,7 @@ gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface) { g_return_val_if_fail(surface != NULL, 0); - return surface->chroma_type; + return GST_VAAPI_SURFACE_CHROMA_TYPE(surface); } /** @@ -252,7 +223,7 @@ gst_vaapi_surface_get_width(GstVaapiSurface *surface) { g_return_val_if_fail(surface != NULL, 0); - return surface->width; + return GST_VAAPI_SURFACE_WIDTH(surface); } /** @@ -268,7 +239,7 @@ gst_vaapi_surface_get_height(GstVaapiSurface *surface) { g_return_val_if_fail(surface != NULL, 0); - return surface->height; + return GST_VAAPI_SURFACE_HEIGHT(surface); } /** @@ -289,10 +260,10 @@ gst_vaapi_surface_get_size( g_return_if_fail(surface != NULL); if (pwidth) - *pwidth = gst_vaapi_surface_get_width(surface); + *pwidth = GST_VAAPI_SURFACE_WIDTH(surface); if (pheight) - *pheight = gst_vaapi_surface_get_height(surface); + *pheight = GST_VAAPI_SURFACE_HEIGHT(surface); } /** diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index d3b487e241..f7d04b8c36 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -24,6 +24,71 @@ #include #include +#include "gstvaapiobject_priv.h" + +typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; + +/** + * GstVaapiSurface: + * + * A VA surface wrapper. + */ +struct _GstVaapiSurface { + /*< private >*/ + GstVaapiObject parent_instance; + + guint width; + guint height; + GstVaapiChromaType chroma_type; + GPtrArray *subpictures; + GstVaapiContext *parent_context; +}; + +/** + * GstVaapiSurfaceClass: + * + * A VA surface wrapper class. + */ +struct _GstVaapiSurfaceClass { + /*< private >*/ + GstVaapiObjectClass parent_class; +}; + +/** + * GST_VAAPI_SURFACE_SURFACE_CHROMA_TYPE: + * @surface: a #GstVaapiSurface + * + * Macro that evaluates to the @surface chroma type. + * + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_SURFACE_CHROMA_TYPE +#define GST_VAAPI_SURFACE_CHROMA_TYPE(surface) \ + GST_VAAPI_SURFACE(surface)->chroma_type + +/** + * GST_VAAPI_SURFACE_SURFACE_WIDTH: + * @surface: a #GstVaapiSurface + * + * Macro that evaluates to the @surface width in pixels. + * + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_SURFACE_WIDTH +#define GST_VAAPI_SURFACE_WIDTH(surface) \ + GST_VAAPI_SURFACE(surface)->width + +/** + * GST_VAAPI_SURFACE_SURFACE_HEIGHT: + * @surface: a #GstVaapiSurface + * + * Macro that evaluates to the @surface height in pixels. + * + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_SURFACE_HEIGHT +#define GST_VAAPI_SURFACE_HEIGHT(surface) \ + GST_VAAPI_SURFACE(surface)->height G_GNUC_INTERNAL void diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 9df4eaf0b9..e069a2308d 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -33,16 +33,13 @@ #define DEBUG 1 #include "gstvaapidebug.h" -static void +static inline void set_crop_rect_from_surface(GstVaapiSurfaceProxy *proxy) { - guint width, height; - - gst_vaapi_surface_get_size(proxy->surface, &width, &height); proxy->crop_rect.x = 0; proxy->crop_rect.y = 0; - proxy->crop_rect.width = width; - proxy->crop_rect.height = height; + proxy->crop_rect.width = GST_VAAPI_SURFACE_WIDTH(proxy->surface); + proxy->crop_rect.height = GST_VAAPI_SURFACE_HEIGHT(proxy->surface); } static inline void diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 5215ef34cc..bb73d94abc 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -28,6 +28,7 @@ #include "sysdeps.h" #include "gstvaapiwindow.h" #include "gstvaapiwindow_priv.h" +#include "gstvaapisurface_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -366,13 +367,10 @@ gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) static inline void get_surface_rect(GstVaapiSurface *surface, GstVaapiRectangle *rect) { - guint width, height; - - gst_vaapi_surface_get_size(surface, &width, &height); rect->x = 0; rect->y = 0; - rect->width = width; - rect->height = height; + rect->width = GST_VAAPI_SURFACE_WIDTH(surface); + rect->height = GST_VAAPI_SURFACE_HEIGHT(surface); } static inline void From ad7202bb77971a717f3139ecafce4412e34ea67d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 8 Jul 2013 11:41:59 +0200 Subject: [PATCH 1230/3781] surfaceproxy: clean-up helper macros. Always use the GST_VAAPI_SURFACE_PROXY() helper macro to cast from a proxy macro argument to a GstVaapiSurfaceProxy pointer. --- gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index 6e5d75828a..a89bf7737f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -58,7 +58,7 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_SURFACE #define GST_VAAPI_SURFACE_PROXY_SURFACE(proxy) \ - proxy->surface + GST_VAAPI_SURFACE_PROXY(proxy)->surface /** * GST_VAAPI_SURFACE_PROXY_SURFACE_ID: @@ -71,7 +71,7 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_SURFACE_ID #define GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) \ - GST_VAAPI_OBJECT_ID(proxy->surface) + GST_VAAPI_OBJECT_ID(GST_VAAPI_SURFACE_PROXY(proxy)->surface) /** * GST_VAAPI_SURFACE_PROXY_TIMESTAMP: @@ -84,7 +84,7 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_TIMESTAMP #define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy) \ - proxy->timestamp + GST_VAAPI_SURFACE_PROXY(proxy)->timestamp /** * GST_VAAPI_SURFACE_PROXY_DURATION: @@ -97,7 +97,7 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_DURATION #define GST_VAAPI_SURFACE_PROXY_DURATION(proxy) \ - proxy->duration + GST_VAAPI_SURFACE_PROXY(proxy)->duration /** * GST_VAAPI_SURFACE_PROXY_CROP_RECT: @@ -109,6 +109,6 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_CROP_RECT #define GST_VAAPI_SURFACE_PROXY_CROP_RECT(proxy) \ - &(proxy)->crop_rect + &GST_VAAPI_SURFACE_PROXY(proxy)->crop_rect #endif /* GST_VAAPI_SURFACE_PROXY_PRIV_H */ From eb00f6d10179c8919a386ef93fededa8c97eb8cf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 8 Jul 2013 14:47:24 +0200 Subject: [PATCH 1231/3781] surfaceproxy: allow for NULL cropping rectangle. Make it possible associate an empty cropping rectangle to the surface proxy, thus resetting any cropping rectangle that was previously set. This allows for returning plain NULL when no cropping rectangle was initially set up to the surface proxy, or if it was reset to defaults. --- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 31 ++++++------------- .../gst/vaapi/gstvaapisurfaceproxy_priv.h | 4 ++- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index e069a2308d..9a7f2c4bc5 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -33,24 +33,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -static inline void -set_crop_rect_from_surface(GstVaapiSurfaceProxy *proxy) -{ - proxy->crop_rect.x = 0; - proxy->crop_rect.y = 0; - proxy->crop_rect.width = GST_VAAPI_SURFACE_WIDTH(proxy->surface); - proxy->crop_rect.height = GST_VAAPI_SURFACE_HEIGHT(proxy->surface); -} - -static inline void -set_crop_rect(GstVaapiSurfaceProxy *proxy, const GstVaapiRectangle *crop_rect) -{ - if (crop_rect) - proxy->crop_rect = *crop_rect; - else - set_crop_rect_from_surface(proxy); -} - static void gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) { @@ -92,11 +74,10 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool); if (!proxy->surface) goto error; - set_crop_rect_from_surface(proxy); - proxy->timestamp = GST_CLOCK_TIME_NONE; proxy->duration = GST_CLOCK_TIME_NONE; proxy->destroy_func = NULL; + proxy->has_crop_rect = FALSE; gst_vaapi_object_ref(proxy->surface); return proxy; @@ -267,7 +248,11 @@ gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy, * represents the cropping rectangle for the underlying surface to be * used for rendering. * - * Return value: the #GstVaapiRectangle + * If no cropping rectangle was associated with the @proxy, then this + * function returns %NULL. + * + * Return value: the #GstVaapiRectangle, or %NULL if none was + * associated with the surface proxy */ const GstVaapiRectangle * gst_vaapi_surface_proxy_get_crop_rect(GstVaapiSurfaceProxy *proxy) @@ -290,5 +275,7 @@ gst_vaapi_surface_proxy_set_crop_rect(GstVaapiSurfaceProxy *proxy, { g_return_if_fail(proxy != NULL); - set_crop_rect(proxy, crop_rect); + proxy->has_crop_rect = crop_rect != NULL; + if (proxy->has_crop_rect) + proxy->crop_rect = *crop_rect; } diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index a89bf7737f..5ed0e701dd 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -42,6 +42,7 @@ struct _GstVaapiSurfaceProxy { GDestroyNotify destroy_func; gpointer destroy_data; GstVaapiRectangle crop_rect; + guint has_crop_rect : 1; }; #define GST_VAAPI_SURFACE_PROXY_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS @@ -109,6 +110,7 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_CROP_RECT #define GST_VAAPI_SURFACE_PROXY_CROP_RECT(proxy) \ - &GST_VAAPI_SURFACE_PROXY(proxy)->crop_rect + (GST_VAAPI_SURFACE_PROXY(proxy)->has_crop_rect ? \ + &GST_VAAPI_SURFACE_PROXY(proxy)->crop_rect : NULL) #endif /* GST_VAAPI_SURFACE_PROXY_PRIV_H */ From dbb58f4152ca64da16eb5d23b4cbdac4828b06c3 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 15 Feb 2013 18:24:24 +0200 Subject: [PATCH 1232/3781] plugins: add helper functions to set the render rectangle. Some video clips may have a clipping region that needs to propogate to the renderer. These helper functions make it possible to attach that clipping region, as a GstVaapiRectangle, the the video meta associated with the buffer. Signed-off-by: Sreerenj Balachandran signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapivideometa.c | 43 +++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapivideometa.h | 9 ++++++++ 2 files changed, 52 insertions(+) diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index 77b8af4c41..e05466419a 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -46,6 +46,8 @@ struct _GstVaapiVideoMeta { GstVaapiSurfaceProxy *proxy; GFunc converter; guint render_flags; + GstVaapiRectangle render_rect; + guint has_render_rect : 1; }; static inline void @@ -158,6 +160,7 @@ gst_vaapi_video_meta_init(GstVaapiVideoMeta *meta) meta->proxy = NULL; meta->converter = NULL; meta->render_flags = 0; + meta->has_render_rect = FALSE; } static inline GstVaapiVideoMeta * @@ -229,6 +232,10 @@ gst_vaapi_video_meta_copy(GstVaapiVideoMeta *meta) gst_vaapi_surface_proxy_ref(meta->proxy) : NULL; copy->converter = meta->converter; copy->render_flags = meta->render_flags; + + copy->has_render_rect = meta->has_render_rect; + if (copy->has_render_rect) + copy->render_rect = meta->render_rect; return copy; } @@ -708,6 +715,42 @@ gst_vaapi_video_meta_set_render_flags(GstVaapiVideoMeta *meta, guint flags) meta->render_flags = flags; } +/** + * gst_vaapi_video_meta_get_render_rect: + * @meta: a #GstVaapiVideoMeta + * + * Retrieves the render rectangle bound to the @meta + * + * Return value: render rectangle associated with the video meta. + */ +const GstVaapiRectangle * +gst_vaapi_video_meta_get_render_rect(GstVaapiVideoMeta *meta) +{ + g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + + if (!meta->has_render_rect) + return NULL; + return &meta->render_rect; +} + +/** + * gst_vaapi_video_meta_set_render_rect: + * @meta: a #GstVaapiVideoMeta + * @rect: a #GstVaapiRectangle + * + * Sets the render rectangle @rect to the @meta. + */ +void +gst_vaapi_video_meta_set_render_rect(GstVaapiVideoMeta *meta, + const GstVaapiRectangle *rect) +{ + g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + + meta->has_render_rect = rect != NULL; + if (meta->has_render_rect) + meta->render_rect = *rect; +} + #if GST_CHECK_VERSION(1,0,0) #define GST_VAAPI_VIDEO_META_HOLDER(meta) \ diff --git a/gst/vaapi/gstvaapivideometa.h b/gst/vaapi/gstvaapivideometa.h index 93b40ed68a..cb1dc2b61b 100644 --- a/gst/vaapi/gstvaapivideometa.h +++ b/gst/vaapi/gstvaapivideometa.h @@ -135,6 +135,15 @@ G_GNUC_INTERNAL void gst_vaapi_video_meta_set_render_flags(GstVaapiVideoMeta *meta, guint flags); +G_GNUC_INTERNAL +const GstVaapiRectangle * +gst_vaapi_video_meta_get_render_rect(GstVaapiVideoMeta *meta); + +G_GNUC_INTERNAL +void +gst_vaapi_video_meta_set_render_rect(GstVaapiVideoMeta *meta, + const GstVaapiRectangle *rect); + G_GNUC_INTERNAL GstVaapiVideoMeta * gst_buffer_get_vaapi_video_meta(GstBuffer *buffer); From 5bbab30859b599a8473dda2b83744eaefaff4fd2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 8 Jul 2013 14:50:42 +0200 Subject: [PATCH 1233/3781] plugins: add support for video cropping. Add support for GstVideoCropMeta in GStreamer >= 1.0.x builds and gst-vaapi specific meta information to hold video cropping details. Make the sink support video cropping in X11 and GLX modes. --- gst/vaapi/gstvaapidecode.c | 17 +++++++- gst/vaapi/gstvaapisink.c | 77 +++++++++++++++++++++++++++-------- gst/vaapi/gstvaapivideometa.c | 5 +++ 3 files changed, 82 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index e91bbdd133..399b004f93 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -276,10 +276,13 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec) GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstVaapiSurfaceProxy *proxy; GstVaapiDecoderStatus status; - GstVaapiVideoMeta *meta; GstVideoCodecFrame *out_frame; GstFlowReturn ret; +#if GST_CHECK_VERSION(1,0,0) + const GstVaapiRectangle *crop_rect; + GstVaapiVideoMeta *meta; guint flags; +#endif status = gst_vaapi_decoder_get_frame_with_timeout(decode->decoder, &out_frame, 100000); @@ -313,6 +316,18 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec) out_flags |= GST_VIDEO_BUFFER_FLAG_ONEFIELD; GST_BUFFER_FLAG_SET(out_frame->output_buffer, out_flags); } + + crop_rect = gst_vaapi_surface_proxy_get_crop_rect(proxy); + if (crop_rect) { + GstVideoCropMeta * const crop_meta = + gst_buffer_add_video_crop_meta(out_frame->output_buffer); + if (crop_meta) { + crop_meta->x = crop_rect->x; + crop_meta->y = crop_rect->y; + crop_meta->width = crop_rect->width; + crop_meta->height = crop_rect->height; + } + } #else out_frame->output_buffer = gst_vaapi_video_buffer_new_with_surface_proxy(proxy); diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 4a8c7443fe..6e3b0c352a 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -827,20 +827,37 @@ render_background(GstVaapiSink *sink) } static void -render_frame(GstVaapiSink *sink) +render_frame(GstVaapiSink *sink, GstVaapiSurface *surface, + const GstVaapiRectangle *surface_rect) { const guint x1 = sink->display_rect.x; const guint x2 = sink->display_rect.x + sink->display_rect.width; const guint y1 = sink->display_rect.y; const guint y2 = sink->display_rect.y + sink->display_rect.height; + gfloat tx1, tx2, ty1, ty2; + guint width, height; + + if (surface_rect) { + gst_vaapi_surface_get_size(surface, &width, &height); + tx1 = (gfloat)surface_rect->x / width; + ty1 = (gfloat)surface_rect->y / height; + tx2 = (gfloat)(surface_rect->x + surface_rect->width) / width; + ty2 = (gfloat)(surface_rect->y + surface_rect->height) / height; + } + else { + tx1 = 0.0f; + ty1 = 0.0f; + tx2 = 1.0f; + ty2 = 1.0f; + } glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); { - glTexCoord2f(0.0f, 0.0f); glVertex2i(x1, y1); - glTexCoord2f(0.0f, 1.0f); glVertex2i(x1, y2); - glTexCoord2f(1.0f, 1.0f); glVertex2i(x2, y2); - glTexCoord2f(1.0f, 0.0f); glVertex2i(x2, y1); + glTexCoord2f(tx1, ty1); glVertex2i(x1, y1); + glTexCoord2f(tx1, ty2); glVertex2i(x1, y2); + glTexCoord2f(tx2, ty2); glVertex2i(x2, y2); + glTexCoord2f(tx2, ty1); glVertex2i(x2, y1); } glEnd(); } @@ -869,9 +886,10 @@ render_reflection(GstVaapiSink *sink) static gboolean gst_vaapisink_show_frame_glx( - GstVaapiSink *sink, - GstVaapiSurface *surface, - guint flags + GstVaapiSink *sink, + GstVaapiSurface *surface, + const GstVaapiRectangle *surface_rect, + guint flags ) { GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window); @@ -909,7 +927,7 @@ gst_vaapisink_show_frame_glx( glRotatef(20.0f, 0.0f, 1.0f, 0.0f); glTranslatef(50.0f, 0.0f, 0.0f); } - render_frame(sink); + render_frame(sink, surface, surface_rect); if (sink->use_reflection) { glPushMatrix(); glTranslatef(0.0, (GLfloat)sink->display_rect.height + 5.0f, 0.0f); @@ -939,13 +957,14 @@ error_transfer_surface: static inline gboolean gst_vaapisink_put_surface( - GstVaapiSink *sink, - GstVaapiSurface *surface, - guint flags + GstVaapiSink *sink, + GstVaapiSurface *surface, + const GstVaapiRectangle *surface_rect, + guint flags ) { if (!gst_vaapi_window_put_surface(sink->window, surface, - NULL, &sink->display_rect, flags)) { + surface_rect, &sink->display_rect, flags)) { GST_DEBUG("could not render VA surface"); return FALSE; } @@ -961,12 +980,26 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) GstBuffer *buffer; guint flags; gboolean success; + GstVaapiRectangle *surface_rect = NULL; +#if GST_CHECK_VERSION(1,0,0) + GstVaapiRectangle tmp_rect; +#endif meta = gst_buffer_get_vaapi_video_meta(src_buffer); #if GST_CHECK_VERSION(1,0,0) if (!meta) return GST_FLOW_EOS; buffer = gst_buffer_ref(src_buffer); + + GstVideoCropMeta * const crop_meta = + gst_buffer_get_video_crop_meta(buffer); + if (crop_meta) { + surface_rect = &tmp_rect; + surface_rect->x = crop_meta->x; + surface_rect->y = crop_meta->y; + surface_rect->width = crop_meta->width; + surface_rect->height = crop_meta->height; + } #else if (meta) buffer = gst_buffer_ref(src_buffer); @@ -1004,6 +1037,15 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) GST_DEBUG("render surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); + if (!surface_rect) + surface_rect = (GstVaapiRectangle *) + gst_vaapi_video_meta_get_render_rect(meta); + + if (surface_rect) + GST_DEBUG("render rect (%d,%d), size %ux%u", + surface_rect->x, surface_rect->y, + surface_rect->width, surface_rect->height); + flags = gst_vaapi_video_meta_get_render_flags(meta); if (!gst_vaapi_apply_composition(surface, src_buffer)) @@ -1019,18 +1061,19 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) case GST_VAAPI_DISPLAY_TYPE_GLX: if (!sink->use_glx) goto put_surface_x11; - success = gst_vaapisink_show_frame_glx(sink, surface, flags); + success = gst_vaapisink_show_frame_glx(sink, surface, surface_rect, + flags); break; #endif #if USE_X11 case GST_VAAPI_DISPLAY_TYPE_X11: put_surface_x11: - success = gst_vaapisink_put_surface(sink, surface, flags); + success = gst_vaapisink_put_surface(sink, surface, surface_rect, flags); break; #endif #if USE_WAYLAND case GST_VAAPI_DISPLAY_TYPE_WAYLAND: - success = gst_vaapisink_put_surface(sink, surface, flags); + success = gst_vaapisink_put_surface(sink, surface, surface_rect, flags); break; #endif default: @@ -1075,6 +1118,8 @@ gst_vaapisink_propose_allocation(GstBaseSink *base_sink, GstQuery *query) GST_VAAPI_VIDEO_META_API_TYPE, NULL); gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL); + gst_query_add_allocation_meta(query, + GST_VIDEO_CROP_META_API_TYPE, NULL); gst_query_add_allocation_meta(query, GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL); return TRUE; diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index e05466419a..4f98795c52 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -637,6 +637,7 @@ gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, GstVaapiSurfaceProxy *proxy) { GstVaapiSurface *surface; + const GstVaapiRectangle *crop_rect; g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); @@ -648,6 +649,10 @@ gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, return; set_surface(meta, surface); meta->proxy = gst_vaapi_surface_proxy_ref(proxy); + + crop_rect = gst_vaapi_surface_proxy_get_crop_rect(proxy); + if (crop_rect) + gst_vaapi_video_meta_set_render_rect(meta, crop_rect); } } From 0829d94f38d88f5f59311023ce193993ce088800 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 8 Jul 2013 17:01:21 +0200 Subject: [PATCH 1234/3781] tests: add basic support for video cropping. Change generic decoder of sample I-frame to return a GstVaapiSurfaceProxy instead of a plain GstVaapiSurface. This means that we can now retrieve the frame cropping rectangle from the surface proxy, along with additional information if ever needed. --- tests/decoder.c | 10 ++-------- tests/decoder.h | 2 +- tests/test-decode.c | 12 +++++++++--- tests/test-subpicture.c | 8 ++++++-- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/tests/decoder.c b/tests/decoder.c index b051f46bcb..f932658394 100644 --- a/tests/decoder.c +++ b/tests/decoder.c @@ -171,10 +171,9 @@ decoder_put_buffers(GstVaapiDecoder *decoder) return TRUE; } -GstVaapiSurface * +GstVaapiSurfaceProxy * decoder_get_surface(GstVaapiDecoder *decoder) { - GstVaapiSurface *surface; GstVaapiSurfaceProxy *proxy; GstVaapiDecoderStatus status; @@ -185,12 +184,7 @@ decoder_get_surface(GstVaapiDecoder *decoder) GST_ERROR("failed to get decoded surface (decoder status %d)", status); return NULL; } - - /* Note: we only have a single I-frame to decode, so this is fine - to just release the surface proxy right away */ - surface = gst_vaapi_surface_proxy_get_surface(proxy); - gst_vaapi_surface_proxy_unref(proxy); - return surface; + return proxy; } const gchar * diff --git a/tests/decoder.h b/tests/decoder.h index 7ab95719f2..b13712e514 100644 --- a/tests/decoder.h +++ b/tests/decoder.h @@ -30,7 +30,7 @@ decoder_new(GstVaapiDisplay *display, const gchar *codec_name); gboolean decoder_put_buffers(GstVaapiDecoder *decoder); -GstVaapiSurface * +GstVaapiSurfaceProxy * decoder_get_surface(GstVaapiDecoder *decoder); const gchar * diff --git a/tests/test-decode.c b/tests/test-decode.c index 2d49a6c3b7..cff76122be 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -51,7 +51,9 @@ main(int argc, char *argv[]) GstVaapiDisplay *display, *display2; GstVaapiWindow *window; GstVaapiDecoder *decoder; + GstVaapiSurfaceProxy *proxy; GstVaapiSurface *surface; + const GstVaapiRectangle *crop_rect; static const guint win_width = 640; static const guint win_height = 480; @@ -85,18 +87,22 @@ main(int argc, char *argv[]) if (!decoder_put_buffers(decoder)) g_error("could not fill decoder with sample data"); - surface = decoder_get_surface(decoder); - if (!surface) + proxy = decoder_get_surface(decoder); + if (!proxy) g_error("could not get decoded surface"); + surface = gst_vaapi_surface_proxy_get_surface(proxy); + crop_rect = gst_vaapi_surface_proxy_get_crop_rect(proxy); + gst_vaapi_window_show(window); - if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, + if (!gst_vaapi_window_put_surface(window, surface, crop_rect, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) g_error("could not render surface"); pause(); + gst_vaapi_surface_proxy_unref(proxy); gst_vaapi_decoder_unref(decoder); gst_vaapi_window_unref(window); gst_vaapi_display_unref(display); diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 0f828aea7a..87cbace6cb 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -77,6 +77,7 @@ main(int argc, char *argv[]) GstVaapiDisplay *display; GstVaapiWindow *window; GstVaapiDecoder *decoder; + GstVaapiSurfaceProxy *proxy; GstVaapiSurface *surface; GstBuffer *buffer; VideoSubpictureInfo subinfo; @@ -113,10 +114,12 @@ main(int argc, char *argv[]) if (!decoder_put_buffers(decoder)) g_error("could not fill decoder with sample data"); - surface = decoder_get_surface(decoder); - if (!surface) + proxy = decoder_get_surface(decoder); + if (!proxy) g_error("could not get decoded surface"); + surface = gst_vaapi_surface_proxy_get_surface(proxy); + subpicture_get_info(&subinfo); buffer = gst_buffer_new_and_alloc(subinfo.data_size); upload_subpicture(buffer, &subinfo); @@ -171,6 +174,7 @@ main(int argc, char *argv[]) pause(); gst_video_overlay_composition_unref(compo); + gst_vaapi_surface_proxy_unref(proxy); gst_vaapi_decoder_unref(decoder); gst_vaapi_window_unref(window); gst_vaapi_display_unref(display); From 976d27841a19cf37e2742cae5770c8a7555f72db Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 15 Feb 2013 18:50:26 +0200 Subject: [PATCH 1235/3781] h264: add support for video cropping. If the encoded stream has the frame_cropping_flag set, then associate the cropping rectangle to GstVaapiPicture. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 8892d52eaf..aad434cfac 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -540,8 +540,6 @@ dpb_output( return TRUE; picture = fs->buffers[0]; } - - /* XXX: update cropping rectangle */ return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture)); } @@ -2556,6 +2554,16 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) gst_vaapi_picture_replace(&priv->current_picture, picture); gst_vaapi_picture_unref(picture); + /* Update cropping rectangle */ + if (sps->frame_cropping_flag) { + GstVaapiRectangle crop_rect; + crop_rect.x = sps->crop_rect_x; + crop_rect.y = sps->crop_rect_y; + crop_rect.width = sps->crop_rect_width; + crop_rect.height = sps->crop_rect_height; + gst_vaapi_picture_set_crop_rect(&picture->base, &crop_rect); + } + picture->pps = pps; status = ensure_quant_matrix(decoder, picture); From f9ae0c0de4bc569dd3b4cdf5c18d776e9be50ff8 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 18 Feb 2013 15:05:37 +0200 Subject: [PATCH 1236/3781] vc1: add support for video cropping. If the Advanced profile has display_extension fields, then set the display width/height dimension as cropping rectangle to the GstVaapiPicture. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 752ee6858f..a2ee00234d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1320,6 +1320,26 @@ gst_vaapi_decoder_vc1_start_frame(GstVaapiDecoder *base_decoder, gst_vaapi_picture_replace(&priv->current_picture, picture); gst_vaapi_picture_unref(picture); + /* Update cropping rectangle */ + do { + GstVC1AdvancedSeqHdr *adv_hdr; + GstVaapiRectangle crop_rect; + + if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) + break; + + adv_hdr = &priv->seq_hdr.advanced; + if (!adv_hdr->display_ext) + break; + + crop_rect.x = 0; + crop_rect.y = 0; + crop_rect.width = adv_hdr->disp_horiz_size; + crop_rect.height = adv_hdr->disp_vert_size; + if (crop_rect.width <= priv->width && crop_rect.height <= priv->height) + gst_vaapi_picture_set_crop_rect(picture, &crop_rect); + } while (0); + if (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, &priv->seq_hdr)) { GST_ERROR("failed to allocate bitplanes"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; From 0b1faa62d0ce64bddbfd9abb5a9ce666943027d3 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 18 Feb 2013 16:28:27 +0200 Subject: [PATCH 1237/3781] mpeg2: add support for video cropping. If the stream has a sequence_display_extenion, then attach the display_horizontal/display_vertical dimension as the cropping rectangle width/height to the GstVaapiPicture. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index bb67bd5c89..fdc6596b15 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1471,6 +1471,17 @@ gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder, gst_vaapi_picture_replace(&priv->current_picture, picture); gst_vaapi_picture_unref(picture); + /* Update cropping rectangle */ + if (seq_display_ext) { + GstVaapiRectangle crop_rect; + crop_rect.x = 0; + crop_rect.y = 0; + crop_rect.width = seq_display_ext->display_horizontal_size; + crop_rect.height = seq_display_ext->display_vertical_size; + if (crop_rect.width <= priv->width && crop_rect.height <= priv->height) + gst_vaapi_picture_set_crop_rect(picture, &crop_rect); + } + status = ensure_quant_matrix(decoder, picture); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { GST_ERROR("failed to reset quantizer matrix"); From 40b6832b820ea2d35860b7a6453fbceab519af82 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 8 Jul 2013 18:32:00 +0200 Subject: [PATCH 1238/3781] vaapisink: fix creation of GLX texture. Fix creation of GLX texture, to not depend on the GstCaps video size that could be wrong, especially in presence of frame cropping. So, use the size from the source VA surfaces. An optimization could be to reduce the texture size to the actual visible size on screen. i.e. scale down the texture size to match the screen dimensions, while preserving the VA surface aspect ratio. However, some VA drivers don't honour that. --- gst/vaapi/gstvaapisink.c | 49 +++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 6e3b0c352a..b0061cb386 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -884,6 +884,42 @@ render_reflection(GstVaapiSink *sink) glEnd(); } +static gboolean +gst_vaapisink_ensure_texture(GstVaapiSink *sink, GstVaapiSurface *surface) +{ + GstVideoRectangle tex_rect, dis_rect, out_rect; + guint width, height; + + if (sink->texture) + return TRUE; + + gst_vaapi_surface_get_size(surface, &width, &height); + tex_rect.x = 0; + tex_rect.y = 0; + tex_rect.w = width; + tex_rect.h = height; + + gst_vaapi_display_get_size(sink->display, &width, &height); + dis_rect.x = 0; + dis_rect.y = 0; + dis_rect.w = width; + dis_rect.h = height; + + gst_video_sink_center_rect(tex_rect, dis_rect, &out_rect, TRUE); + + /* XXX: use surface size for now since some VA drivers have issues + with downscaling to the provided texture size. i.e. we should be + using the resulting out_rect size, which preserves the aspect + ratio of the surface */ + width = tex_rect.w; + height = tex_rect.h; + GST_INFO("texture size %ux%u", width, height); + + sink->texture = gst_vaapi_texture_new(sink->display, + GL_TEXTURE_2D, GL_BGRA, width, height); + return sink->texture != NULL; +} + static gboolean gst_vaapisink_show_frame_glx( GstVaapiSink *sink, @@ -897,17 +933,8 @@ gst_vaapisink_show_frame_glx( GLuint texture; gst_vaapi_window_glx_make_current(window); - if (!sink->texture) { - sink->texture = gst_vaapi_texture_new( - sink->display, - GL_TEXTURE_2D, - GL_BGRA, - sink->video_width, - sink->video_height - ); - if (!sink->texture) - goto error_create_texture; - } + if (!gst_vaapisink_ensure_texture(sink, surface)) + goto error_create_texture; if (!gst_vaapi_texture_put_surface(sink->texture, surface, flags)) goto error_transfer_surface; From 42e46cd9d1a3b60f6af04817e6488c8f68dc502c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Jul 2013 11:13:59 +0200 Subject: [PATCH 1239/3781] NEWS: updates. --- NEWS | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 691836a45c..62b0e5d78e 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,15 @@ -gst-vaapi NEWS -- summary of changes. 2013-06-14 +gst-vaapi NEWS -- summary of changes. 2013-07-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora +Version 0.5.5 - DD.Jul.2013 +* Allocate VA/GLX capable buffers by default on X11 servers (Victor Jaquez) +* Add support for video cropping in MPEG-2, VC-1 and H.264 codecs (+Sreerenj) +* Fix creation of VA/GLX textures when video cropping is used +* Fix raw image copies in vaapidownload / vaapiupload (Feng Yuan) +* Fix MPEG-2 quantization matrices reset on new sequence headers (Cong Zhong) + Version 0.5.4 - 14.Jun.2013 * Streamline core libgstvaapi decoding library (API/ABI changes) * Use built-in codecparsers by default (or --disable-builtin-codecparsers) From 430598cf005ce3bdc51b03754a639e18c9eb5fd6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Jul 2013 15:29:59 +0200 Subject: [PATCH 1240/3781] Add new video format API. Leverage GstVideoFormat utilities from core GStreamer to provide an adaptation layer to VA image formats. --- docs/reference/libs/libs-docs.xml.in | 1 + docs/reference/libs/libs-sections.txt | 13 ++ gst-libs/gst/vaapi/Makefile.am | 4 +- gst-libs/gst/vaapi/video-format.c | 317 ++++++++++++++++++++++++++ gst-libs/gst/vaapi/video-format.h | 57 +++++ 5 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 gst-libs/gst/vaapi/video-format.c create mode 100644 gst-libs/gst/vaapi/video-format.h diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index ea7617a001..b50e81372e 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -8,6 +8,7 @@ gst-plugins-vaapi Library + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index e25b0e6499..8690092013 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -1,3 +1,16 @@ +
+videoformat +GstVideoFormat +gst_video_format_from_caps +gst_video_format_from_structure +gst_video_format_from_va_format +gst_video_format_get_score +gst_video_format_is_rgb +gst_video_format_is_yuv +gst_video_format_to_caps +gst_video_format_to_va_format +
+
gstvaapisurfacepool GstVaapiSurfacePool diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index e5dbc5f6c0..fab2fab3a9 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -70,6 +70,7 @@ libgstvaapi_source_c = \ gstvaapivalue.c \ gstvaapivideopool.c \ gstvaapiwindow.c \ + video-format.c \ $(NULL) libgstvaapi_source_h = \ @@ -94,6 +95,7 @@ libgstvaapi_source_h = \ gstvaapivalue.h \ gstvaapivideopool.h \ gstvaapiwindow.h \ + video-format.h \ $(NULL) libgstvaapi_source_priv_h = \ @@ -227,7 +229,7 @@ libgstvaapi_@GST_API_VERSION@_la_LIBADD = \ libgstvaapi_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(GST_VAAPI_LT_LDFLAGS) \ - -export-symbols-regex "^gst_.*vaapi.*" \ + -export-symbols-regex "^gst_(.*vaapi|video_format).*" \ $(NULL) libgstvaapi_drm_@GST_API_VERSION@_la_SOURCES = \ diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c new file mode 100644 index 0000000000..d9236dce9e --- /dev/null +++ b/gst-libs/gst/vaapi/video-format.c @@ -0,0 +1,317 @@ +/* + * video-format.c - Video format abstraction + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2013 Intel Corporation + * + * 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:videoformat + * @short_description: Video format abstraction + */ + +#include "sysdeps.h" +#include +#include "gstvaapicompat.h" +#include "video-format.h" + +typedef struct _GstVideoFormatMap GstVideoFormatMap; +struct _GstVideoFormatMap { + GstVideoFormat format; + const char *caps_str; + VAImageFormat va_format; +}; + +#if GST_CHECK_VERSION(1,0,0) +# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \ + GST_VIDEO_CAPS_MAKE(#FORMAT) +# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \ + GST_VIDEO_CAPS_MAKE(#FORMAT) +#else +# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \ + GST_VIDEO_CAPS_YUV(#FORMAT) +# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \ + GST_VIDEO_CAPS_##FORMAT +#endif + +#define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP) \ + { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ + GST_VIDEO_CAPS_MAKE_YUV(FORMAT), \ + { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } +#define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \ + { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ + GST_VIDEO_CAPS_MAKE_RGB(FORMAT), \ + { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } + +/* Image formats, listed in HW order preference */ +static const GstVideoFormatMap gst_video_formats[] = { + DEF_YUV(NV12, ('N','V','1','2'), LSB, 12), + DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12), + DEF_YUV(I420, ('I','4','2','0'), LSB, 12), + DEF_YUV(AYUV, ('A','Y','U','V'), LSB, 32), +#if G_BYTE_ORDER == G_BIG_ENDIAN + DEF_RGB(ARGB, ('A','R','G','B'), MSB, 32, + 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), + DEF_RGB(ABGR, ('A','B','G','R'), MSB, 32, + 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), +#elif G_BYTE_ORDER == G_LITTLE_ENDIAN + DEF_RGB(BGRA, ('B','G','R','A'), LSB, 32, + 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), + DEF_RGB(RGBA, ('R','G','B','A'), LSB, 32, + 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), +#endif + { 0, } +}; + +#undef DEF_RGB +#undef DEF_YUV + +static inline gboolean +va_format_is_rgb(const VAImageFormat *va_format) +{ + return va_format->depth != 0; +} + +static inline gboolean +va_format_is_yuv(const VAImageFormat *va_format) +{ + return va_format->depth == 0; +} + +static inline gboolean +va_format_is_same_rgb(const VAImageFormat *fmt1, const VAImageFormat *fmt2) +{ + return (fmt1->byte_order == fmt2->byte_order && + fmt1->red_mask == fmt2->red_mask && + fmt1->green_mask == fmt2->green_mask && + fmt1->blue_mask == fmt2->blue_mask && + fmt1->alpha_mask == fmt2->alpha_mask); +} + +static inline gboolean +va_format_is_same(const VAImageFormat *fmt1, const VAImageFormat *fmt2) +{ + if (fmt1->fourcc != fmt2->fourcc) + return FALSE; + return va_format_is_rgb(fmt1) ? va_format_is_same_rgb(fmt1, fmt2) : TRUE; +} + +static const GstVideoFormatMap * +get_map(GstVideoFormat format) +{ + const GstVideoFormatMap *m; + + for (m = gst_video_formats; m->format; m++) { + if (m->format == format) + return m; + } + return NULL; +} + +/** + * gst_video_format_is_rgb: + * @format: a #GstVideoFormat + * + * Checks whether the format is an RGB format. + * + * Return value: %TRUE if @format is RGB format + */ +#if GST_CHECK_VERSION(1,0,0) +gboolean +gst_video_format_is_rgb(GstVideoFormat format) +{ + const GstVideoFormatMap * const m = get_map(format); + + return m && va_format_is_rgb(&m->va_format); +} +#endif + +/** + * gst_video_format_is_yuv: + * @format: a #GstVideoFormat + * + * Checks whether the format is an YUV format. + * + * Return value: %TRUE if @format is YUV format + */ +#if GST_CHECK_VERSION(1,0,0) +gboolean +gst_video_format_is_yuv(GstVideoFormat format) +{ + const GstVideoFormatMap * const m = get_map(format); + + return m && va_format_is_yuv(&m->va_format); +} +#endif + +/** + * gst_video_format_from_caps: + * @caps: a #GstCaps + * + * Converts @caps into the corresponding #GstVideoFormat. If the + * image format cannot be represented by #GstVideoFormat, then + * zero is returned. + * + * Return value: the #GstVideoFormat describing the @caps + */ +GstVideoFormat +gst_video_format_from_caps(GstCaps *caps) +{ + GstStructure *structure; + + if (!caps) + return 0; + + structure = gst_caps_get_structure(caps, 0); + if (!structure) + return 0; + return gst_video_format_from_structure(structure); +} + +/** + * gst_video_format_from_structure: + * @structure: a #GstStructure + * + * Converts @structure into the corresponding #GstVideoFormat. If + * the image format cannot be represented by #GstVideoFormat, + * then zero is returned. + * + * Return value: the #GstVideoFormat describing the @structure + */ +GstVideoFormat +gst_video_format_from_structure(GstStructure *structure) +{ +#if GST_CHECK_VERSION(1,0,0) + const gchar * format = gst_structure_get_string(structure, "format"); + if (format) + return gst_video_format_from_string(format); + return GST_VIDEO_FORMAT_UNKNOWN; +#else + const GstVideoFormatMap *m; + VAImageFormat *va_format, va_formats[2]; + gint endian, rmask, gmask, bmask, amask = 0; + guint32 fourcc; + + /* Check for YUV format */ + if (gst_structure_get_fourcc(structure, "format", &fourcc)) + return gst_video_format_from_fourcc(fourcc); + + /* Check for RGB format */ + gst_structure_get_int(structure, "endianness", &endian); + gst_structure_get_int(structure, "red_mask", &rmask); + gst_structure_get_int(structure, "green_mask", &gmask); + gst_structure_get_int(structure, "blue_mask", &bmask); + gst_structure_get_int(structure, "alpha_mask", &amask); + + va_format = &va_formats[0]; + va_format->byte_order = endian == G_BIG_ENDIAN ? VA_MSB_FIRST : VA_LSB_FIRST; + va_format->red_mask = rmask; + va_format->green_mask = gmask; + va_format->blue_mask = bmask; + va_format->alpha_mask = amask; + + va_format = &va_formats[1]; + va_format->byte_order = endian == G_BIG_ENDIAN ? VA_LSB_FIRST : VA_MSB_FIRST; + va_format->red_mask = GUINT32_SWAP_LE_BE(rmask); + va_format->green_mask = GUINT32_SWAP_LE_BE(gmask); + va_format->blue_mask = GUINT32_SWAP_LE_BE(bmask); + va_format->alpha_mask = GUINT32_SWAP_LE_BE(amask); + + for (m = gst_video_formats; m->format; m++) { + if (va_format_is_rgb(&m->va_format) && + (va_format_is_same_rgb(&m->va_format, &va_formats[0]) || + va_format_is_same_rgb(&m->va_format, &va_formats[1]))) + return m->format; + } + return GST_VIDEO_FORMAT_UNKNOWN; +#endif +} + +/** + * gst_video_format_to_caps: + * @format: a #GstVideoFormat + * + * Converts a #GstVideoFormat into the corresponding #GstCaps. If + * no matching caps were found, %NULL is returned. + * + * Return value: the newly allocated #GstCaps, or %NULL if none was found + */ +GstCaps * +gst_video_format_to_caps(GstVideoFormat format) +{ + const GstVideoFormatMap * const m = get_map(format); + + return m ? gst_caps_from_string(m->caps_str) : NULL; +} + +/** + * gst_video_format_from_va_format: + * @va_format: a #VAImageFormat + * + * Converts a VA image format into the corresponding #GstVideoFormat. + * If the image format cannot be represented by #GstVideoFormat, + * then zero is returned. + * + * Return value: the #GstVideoFormat describing the @va_format + */ +GstVideoFormat +gst_video_format_from_va_format(const VAImageFormat *va_format) +{ + const GstVideoFormatMap *m; + + for (m = gst_video_formats; m->format; m++) { + if (va_format_is_same(&m->va_format, va_format)) + return m->format; + } + return GST_VIDEO_FORMAT_UNKNOWN; +} + +/** + * gst_video_format_to_va_format: + * @format: a #GstVideoFormat + * + * Converts a #GstVideoFormat into the corresponding VA image + * format. If no matching VA image format was found, %NULL is returned + * and this error must be reported to be fixed. + * + * Return value: the VA image format, or %NULL if none was found + */ +const VAImageFormat * +gst_video_format_to_va_format(GstVideoFormat format) +{ + const GstVideoFormatMap * const m = get_map(format); + + return m ? &m->va_format : NULL; +} + +/** + * gst_video_format_get_score: + * @format: a #GstVideoFormat + * + * Determines how "native" is this @format. The lower is the returned + * score, the best format this is for the underlying hardware. + * + * Return value: the @format score, or %G_MAXUINT if none was found + */ +guint +gst_video_format_get_score(GstVideoFormat format) +{ + const GstVideoFormatMap * const m = get_map(format); + + return m ? (m - &gst_video_formats[0]) : G_MAXUINT; +} diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h new file mode 100644 index 0000000000..5ba395023d --- /dev/null +++ b/gst-libs/gst/vaapi/video-format.h @@ -0,0 +1,57 @@ +/* + * video-format.h - Video format abstraction + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2013 Intel Corporation + * + * 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_VIDEO_FORMAT_H +#define GST_VAAPI_VIDEO_FORMAT_H + +#include +#include + +G_BEGIN_DECLS + +gboolean +gst_video_format_is_rgb(GstVideoFormat format); + +gboolean +gst_video_format_is_yuv(GstVideoFormat format); + +GstVideoFormat +gst_video_format_from_structure(GstStructure *structure); + +GstVideoFormat +gst_video_format_from_caps(GstCaps *caps); + +GstCaps * +gst_video_format_to_caps(GstVideoFormat format); + +GstVideoFormat +gst_video_format_from_va_format(const VAImageFormat *va_format); + +const VAImageFormat * +gst_video_format_to_va_format(GstVideoFormat format); + +guint +gst_video_format_get_score(GstVideoFormat format); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_FORMAT_H */ From e61c5fc3d13bd9db69511a5644fb97bda3050fa5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Jul 2013 14:03:01 +0200 Subject: [PATCH 1241/3781] libs: port to new video format API. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 58 ++++++++--------- gst-libs/gst/vaapi/gstvaapidisplay.h | 6 +- gst-libs/gst/vaapi/gstvaapiimage.c | 82 ++++++++++++------------- gst-libs/gst/vaapi/gstvaapiimage.h | 10 +-- gst-libs/gst/vaapi/gstvaapiimagepool.c | 4 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 8 +-- 6 files changed, 84 insertions(+), 84 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 919f24bd1f..a92e304641 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -59,7 +59,7 @@ struct _GstVaapiProperty { typedef struct _GstVaapiFormatInfo GstVaapiFormatInfo; struct _GstVaapiFormatInfo { - GstVaapiImageFormat format; + GstVideoFormat format; guint flags; }; @@ -174,9 +174,9 @@ gst_vaapi_display_type_get_type(void) return g_type; } -/* Append GstVaapiImageFormat to formats array */ +/* Append GstVideoFormat to formats array */ static inline void -append_format(GArray *formats, GstVaapiImageFormat format, guint flags) +append_format(GArray *formats, GstVideoFormat format, guint flags) { GstVaapiFormatInfo fi; @@ -190,7 +190,7 @@ static void append_formats(GArray *formats, const VAImageFormat *va_formats, guint *flags, guint n) { - GstVaapiImageFormat format; + GstVideoFormat format; const GstVaapiFormatInfo *YV12_fip = NULL; const GstVaapiFormatInfo *I420_fip = NULL; guint i; @@ -199,8 +199,8 @@ append_formats(GArray *formats, const VAImageFormat *va_formats, const VAImageFormat * const va_format = &va_formats[i]; const GstVaapiFormatInfo **fipp; - format = gst_vaapi_image_format(va_format); - if (!format) { + format = gst_video_format_from_va_format(va_format); + if (format == GST_VIDEO_FORMAT_UNKNOWN) { GST_DEBUG("unsupported format %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(va_format->fourcc)); continue; @@ -208,10 +208,10 @@ append_formats(GArray *formats, const VAImageFormat *va_formats, append_format(formats, format, flags ? flags[i] : 0); switch (format) { - case GST_VAAPI_IMAGE_YV12: + case GST_VIDEO_FORMAT_YV12: fipp = &YV12_fip; break; - case GST_VAAPI_IMAGE_I420: + case GST_VIDEO_FORMAT_I420: fipp = &I420_fip; break; default: @@ -226,43 +226,43 @@ append_formats(GArray *formats, const VAImageFormat *va_formats, /* Append I420 (resp. YV12) format if YV12 (resp. I420) is not supported by the underlying driver */ if (YV12_fip && !I420_fip) - append_format(formats, GST_VAAPI_IMAGE_I420, YV12_fip->flags); + append_format(formats, GST_VIDEO_FORMAT_I420, YV12_fip->flags); else if (I420_fip && !YV12_fip) - append_format(formats, GST_VAAPI_IMAGE_YV12, I420_fip->flags); + append_format(formats, GST_VIDEO_FORMAT_YV12, I420_fip->flags); } /* Sort image formats. Prefer YUV formats first */ static gint compare_yuv_formats(gconstpointer a, gconstpointer b) { - const GstVaapiImageFormat fmt1 = ((GstVaapiFormatInfo *)a)->format; - const GstVaapiImageFormat fmt2 = ((GstVaapiFormatInfo *)b)->format; + const GstVideoFormat fmt1 = ((GstVaapiFormatInfo *)a)->format; + const GstVideoFormat fmt2 = ((GstVaapiFormatInfo *)b)->format; - const gboolean is_fmt1_yuv = gst_vaapi_image_format_is_yuv(fmt1); - const gboolean is_fmt2_yuv = gst_vaapi_image_format_is_yuv(fmt2); + const gboolean is_fmt1_yuv = gst_video_format_is_yuv(fmt1); + const gboolean is_fmt2_yuv = gst_video_format_is_yuv(fmt2); if (is_fmt1_yuv != is_fmt2_yuv) return is_fmt1_yuv ? -1 : 1; - return ((gint)gst_vaapi_image_format_get_score(fmt1) - - (gint)gst_vaapi_image_format_get_score(fmt2)); + return ((gint)gst_video_format_get_score(fmt1) - + (gint)gst_video_format_get_score(fmt2)); } /* Sort subpicture formats. Prefer RGB formats first */ static gint compare_rgb_formats(gconstpointer a, gconstpointer b) { - const GstVaapiImageFormat fmt1 = ((GstVaapiFormatInfo *)a)->format; - const GstVaapiImageFormat fmt2 = ((GstVaapiFormatInfo *)b)->format; + const GstVideoFormat fmt1 = ((GstVaapiFormatInfo *)a)->format; + const GstVideoFormat fmt2 = ((GstVaapiFormatInfo *)b)->format; - const gboolean is_fmt1_rgb = gst_vaapi_image_format_is_rgb(fmt1); - const gboolean is_fmt2_rgb = gst_vaapi_image_format_is_rgb(fmt2); + const gboolean is_fmt1_rgb = gst_video_format_is_rgb(fmt1); + const gboolean is_fmt2_rgb = gst_video_format_is_rgb(fmt2); if (is_fmt1_rgb != is_fmt2_rgb) return is_fmt1_rgb ? -1 : 1; - return ((gint)gst_vaapi_image_format_get_score(fmt1) - - (gint)gst_vaapi_image_format_get_score(fmt2)); + return ((gint)gst_video_format_get_score(fmt1) - + (gint)gst_video_format_get_score(fmt2)); } /* Check if configs array contains profile at entrypoint */ @@ -343,7 +343,7 @@ get_profile_caps(GArray *configs) /* Find format info */ static const GstVaapiFormatInfo * -find_format_info(GArray *formats, GstVaapiImageFormat format) +find_format_info(GArray *formats, GstVideoFormat format) { const GstVaapiFormatInfo *fip; guint i; @@ -358,7 +358,7 @@ find_format_info(GArray *formats, GstVaapiImageFormat format) /* Check if formats array contains format */ static inline gboolean -find_format(GArray *formats, GstVaapiImageFormat format) +find_format(GArray *formats, GstVideoFormat format) { return find_format_info(formats, format) != NULL; } @@ -377,7 +377,7 @@ get_format_caps(GArray *formats) for (i = 0; i < formats->len; i++) { fip = &g_array_index(formats, GstVaapiFormatInfo, i); - caps = gst_vaapi_image_format_get_caps(fip->format); + caps = gst_video_format_to_caps(fip->format); if (caps) gst_caps_append(out_caps, caps); } @@ -1360,7 +1360,7 @@ gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) /** * gst_vaapi_display_has_image_format: * @display: a #GstVaapiDisplay - * @format: a #GstVaapiFormat + * @format: a #GstVideoFormat * * Returns whether VA @display supports @format image format. * @@ -1369,7 +1369,7 @@ gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) gboolean gst_vaapi_display_has_image_format( GstVaapiDisplay *display, - GstVaapiImageFormat format + GstVideoFormat format ) { g_return_val_if_fail(display != NULL, FALSE); @@ -1412,7 +1412,7 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) /** * gst_vaapi_display_has_subpicture_format: * @display: a #GstVaapiDisplay - * @format: a #GstVaapiFormat + * @format: a #GstVideoFormat * @flags_ptr: pointer to #GstVaapiSubpictureFlags, or zero * * Returns whether VA @display supports @format subpicture format with @@ -1423,7 +1423,7 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) gboolean gst_vaapi_display_has_subpicture_format( GstVaapiDisplay *display, - GstVaapiImageFormat format, + GstVideoFormat format, guint *flags_ptr ) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index ff6908765d..1949b2497d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -26,8 +26,8 @@ #include #include #include -#include #include +#include G_BEGIN_DECLS @@ -161,7 +161,7 @@ gst_vaapi_display_get_image_caps(GstVaapiDisplay *display); gboolean gst_vaapi_display_has_image_format( GstVaapiDisplay *display, - GstVaapiImageFormat format + GstVideoFormat format ); GstCaps * @@ -170,7 +170,7 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display); gboolean gst_vaapi_display_has_subpicture_format( GstVaapiDisplay *display, - GstVaapiImageFormat format, + GstVideoFormat format, guint *flags_ptr ); diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index e08ae658dc..5872b8c6cc 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -49,8 +49,8 @@ struct _GstVaapiImage { VAImage internal_image; VAImage image; guchar *image_data; - GstVaapiImageFormat internal_format; - GstVaapiImageFormat format; + GstVideoFormat internal_format; + GstVideoFormat format; guint width; guint height; guint is_linear : 1; @@ -143,7 +143,7 @@ gst_vaapi_image_destroy(GstVaapiImage *image) } static gboolean -_gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) +_gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format) { GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image); const VAImageFormat *va_format; @@ -152,7 +152,7 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) if (!gst_vaapi_display_has_image_format(display, format)) return FALSE; - va_format = gst_vaapi_image_format_get_va_format(format); + va_format = gst_video_format_to_va_format(format); if (!va_format) return FALSE; @@ -174,7 +174,7 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format) } static gboolean -gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format, +gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format, guint width, guint height) { const VAImageFormat *va_format; @@ -186,11 +186,11 @@ gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format, if (!_gst_vaapi_image_create(image, format)) { switch (format) { - case GST_VAAPI_IMAGE_I420: - format = GST_VAAPI_IMAGE_YV12; + case GST_VIDEO_FORMAT_I420: + format = GST_VIDEO_FORMAT_YV12; break; - case GST_VAAPI_IMAGE_YV12: - format = GST_VAAPI_IMAGE_I420; + case GST_VIDEO_FORMAT_YV12: + format = GST_VIDEO_FORMAT_I420; break; default: format = 0; @@ -204,9 +204,9 @@ gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format, if (image->format != image->internal_format) { switch (image->format) { - case GST_VAAPI_IMAGE_YV12: - case GST_VAAPI_IMAGE_I420: - va_format = gst_vaapi_image_format_get_va_format(image->format); + case GST_VIDEO_FORMAT_YV12: + case GST_VIDEO_FORMAT_I420: + va_format = gst_video_format_to_va_format(image->format); if (!va_format) return FALSE; image->image.format = *va_format; @@ -251,7 +251,7 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( /** * gst_vaapi_image_new: * @display: a #GstVaapiDisplay - * @format: a #GstVaapiImageFormat + * @format: a #GstVideoFormat * @width: the requested image width * @height: the requested image height * @@ -263,7 +263,7 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( GstVaapiImage * gst_vaapi_image_new( GstVaapiDisplay *display, - GstVaapiImageFormat format, + GstVideoFormat format, guint width, guint height ) @@ -381,12 +381,12 @@ gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image) gboolean _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) { - GstVaapiImageFormat format; + GstVideoFormat format; VAImage alt_va_image; const VAImageFormat *alt_va_format; - format = gst_vaapi_image_format(&va_image->format); - if (!format) + format = gst_video_format_from_va_format(&va_image->format); + if (format == GST_VIDEO_FORMAT_UNKNOWN) return FALSE; image->internal_image = *va_image; @@ -402,18 +402,18 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) /* Try to linearize image */ if (!image->is_linear) { switch (format) { - case GST_VAAPI_IMAGE_I420: - format = GST_VAAPI_IMAGE_YV12; + case GST_VIDEO_FORMAT_I420: + format = GST_VIDEO_FORMAT_YV12; break; - case GST_VAAPI_IMAGE_YV12: - format = GST_VAAPI_IMAGE_I420; + case GST_VIDEO_FORMAT_YV12: + format = GST_VIDEO_FORMAT_I420; break; default: format = 0; break; } if (format && - (alt_va_format = gst_vaapi_image_format_get_va_format(format))) { + (alt_va_format = gst_video_format_to_va_format(format))) { alt_va_image = *va_image; alt_va_image.format = *alt_va_format; SWAP_UINT(alt_va_image.offsets[1], alt_va_image.offsets[2]); @@ -434,11 +434,11 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) * gst_vaapi_image_get_format: * @image: a #GstVaapiImage * - * Returns the #GstVaapiImageFormat the @image was created with. + * Returns the #GstVideoFormat the @image was created with. * - * Return value: the #GstVaapiImageFormat + * Return value: the #GstVideoFormat */ -GstVaapiImageFormat +GstVideoFormat gst_vaapi_image_get_format(GstVaapiImage *image) { g_return_val_if_fail(image != NULL, 0); @@ -737,7 +737,7 @@ init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) { GstStructure *structure; GstCaps *caps; - GstVaapiImageFormat format; + GstVideoFormat format; guint width2, height2, size2; gint width, height; guchar *data; @@ -750,7 +750,7 @@ init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) if (!caps) return FALSE; - format = gst_vaapi_image_format_from_caps(caps); + format = gst_video_format_from_caps(caps); structure = gst_caps_get_structure(caps, 0); gst_structure_get_int(structure, "width", &width); @@ -764,7 +764,7 @@ init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) height2 = (height + 1) / 2; size2 = 0; switch (format) { - case GST_VAAPI_IMAGE_NV12: + case GST_VIDEO_FORMAT_NV12: raw_image->num_planes = 2; raw_image->pixels[0] = data; raw_image->stride[0] = GST_ROUND_UP_4(width); @@ -773,8 +773,8 @@ init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) raw_image->stride[1] = raw_image->stride[0]; size2 += height2 * raw_image->stride[1]; break; - case GST_VAAPI_IMAGE_YV12: - case GST_VAAPI_IMAGE_I420: + case GST_VIDEO_FORMAT_YV12: + case GST_VIDEO_FORMAT_I420: raw_image->num_planes = 3; raw_image->pixels[0] = data; raw_image->stride[0] = GST_ROUND_UP_4(width); @@ -786,10 +786,10 @@ init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) raw_image->stride[2] = raw_image->stride[1]; size2 += height2 * raw_image->stride[2]; break; - case GST_VAAPI_IMAGE_ARGB: - case GST_VAAPI_IMAGE_RGBA: - case GST_VAAPI_IMAGE_ABGR: - case GST_VAAPI_IMAGE_BGRA: + case GST_VIDEO_FORMAT_ARGB: + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_BGRA: raw_image->num_planes = 1; raw_image->pixels[0] = data; raw_image->stride[0] = width * 4; @@ -937,17 +937,17 @@ copy_image( } switch (dst_image->format) { - case GST_VAAPI_IMAGE_NV12: + case GST_VIDEO_FORMAT_NV12: copy_image_NV12(dst_image, src_image, rect); break; - case GST_VAAPI_IMAGE_YV12: - case GST_VAAPI_IMAGE_I420: + case GST_VIDEO_FORMAT_YV12: + case GST_VIDEO_FORMAT_I420: copy_image_YV12(dst_image, src_image, rect); break; - case GST_VAAPI_IMAGE_ARGB: - case GST_VAAPI_IMAGE_RGBA: - case GST_VAAPI_IMAGE_ABGR: - case GST_VAAPI_IMAGE_BGRA: + case GST_VIDEO_FORMAT_ARGB: + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_BGRA: copy_image_RGBA(dst_image, src_image, rect); break; default: diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 9def1003da..94eff61362 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include G_BEGIN_DECLS @@ -37,7 +37,7 @@ G_BEGIN_DECLS * GST_VAAPI_IMAGE_FORMAT: * @image: a #GstVaapiImage * - * Macro that evaluates to the #GstVaapiImageFormat of @image. + * Macro that evaluates to the #GstVideoFormat of @image. */ #define GST_VAAPI_IMAGE_FORMAT(image) gst_vaapi_image_get_format(image) @@ -67,7 +67,7 @@ typedef struct _GstVaapiImageRaw GstVaapiImageRaw; * the fields with sensible values. */ struct _GstVaapiImageRaw { - GstVaapiImageFormat format; + GstVideoFormat format; guint width; guint height; guint num_planes; @@ -78,7 +78,7 @@ struct _GstVaapiImageRaw { GstVaapiImage * gst_vaapi_image_new( GstVaapiDisplay *display, - GstVaapiImageFormat format, + GstVideoFormat format, guint width, guint height ); @@ -92,7 +92,7 @@ gst_vaapi_image_get_id(GstVaapiImage *image); gboolean gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image); -GstVaapiImageFormat +GstVideoFormat gst_vaapi_image_get_format(GstVaapiImage *image); guint diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index dd3868acfc..2f85bcabd9 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -41,7 +41,7 @@ struct _GstVaapiImagePool { /*< private >*/ GstVaapiVideoPool parent_instance; - GstVaapiImageFormat format; + GstVideoFormat format; guint width; guint height; }; @@ -55,7 +55,7 @@ gst_vaapi_image_pool_set_caps(GstVaapiVideoPool *base_pool, GstCaps *caps) if (!gst_video_info_from_caps(&vi, caps)) return FALSE; - pool->format = gst_vaapi_image_format_from_video(GST_VIDEO_INFO_FORMAT(&vi)); + pool->format = GST_VIDEO_INFO_FORMAT(&vi); pool->width = GST_VIDEO_INFO_WIDTH(&vi); pool->height = GST_VIDEO_INFO_HEIGHT(&vi); return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 9e2566aee6..92bbb2e335 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -132,7 +132,7 @@ gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags) { GstVaapiSubpicture *subpicture; GstVaapiDisplay *display; - GstVaapiImageFormat format; + GstVideoFormat format; guint va_flags; g_return_val_if_fail(image != NULL, NULL); @@ -180,7 +180,7 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( ) { GstVaapiSubpicture *subpicture; - GstVaapiImageFormat format; + GstVideoFormat format; GstVaapiImage *image; GstVaapiImageRaw raw_image; GstBuffer *buffer; @@ -197,9 +197,9 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( /* XXX: use gst_vaapi_image_format_from_video() */ #if G_BYTE_ORDER == G_LITTLE_ENDIAN - format = GST_VAAPI_IMAGE_BGRA; + format = GST_VIDEO_FORMAT_BGRA; #else - format = GST_VAAPI_IMAGE_ARGB; + format = GST_VIDEO_FORMAT_ARGB; #endif if (!gst_vaapi_display_has_subpicture_format(display, format, &hw_flags)) return NULL; From cb808f91aa6e71510042f678aa89b9c2f760c0cf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Jul 2013 16:38:05 +0200 Subject: [PATCH 1242/3781] libs: drop GstVaapiImageFormat helpers. Drop GstVaapiImageFormat helpers since everything was moved to the new GstVideoFormat based API. Don't bother with backwards compatibility and just bump the library major version afterwards. --- docs/reference/libs/libs-docs.xml.in | 1 - docs/reference/libs/libs-sections.txt | 15 - gst-libs/gst/vaapi/Makefile.am | 2 - gst-libs/gst/vaapi/gstvaapiimageformat.c | 343 ----------------------- gst-libs/gst/vaapi/gstvaapiimageformat.h | 95 ------- 5 files changed, 456 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapiimageformat.c delete mode 100644 gst-libs/gst/vaapi/gstvaapiimageformat.h diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index b50e81372e..3fff5e7b5c 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -19,7 +19,6 @@ - diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 8690092013..36cd6f4224 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -240,21 +240,6 @@ gst_vaapi_subpicture_set_image GST_VAAPI_SUBPICTURE
-
-gstvaapiimageformat -GstVaapiImageFormat -GstVaapiImageFormat -gst_vaapi_image_format_is_rgb -gst_vaapi_image_format_is_yuv -gst_vaapi_image_format -gst_vaapi_image_format_from_caps -gst_vaapi_image_format_from_fourcc -gst_vaapi_image_format_from_video -gst_vaapi_image_format_get_va_format -gst_vaapi_image_format_get_caps -gst_vaapi_image_format_get_score -
-
gstvaapiprofile GstVaapiProfile diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index fab2fab3a9..f4e771e332 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -56,7 +56,6 @@ libgstvaapi_source_c = \ gstvaapidisplay.c \ gstvaapidisplaycache.c \ gstvaapiimage.c \ - gstvaapiimageformat.c \ gstvaapiimagepool.c \ gstvaapiminiobject.c \ gstvaapiobject.c \ @@ -83,7 +82,6 @@ libgstvaapi_source_h = \ gstvaapidisplay.h \ gstvaapidisplaycache.h \ gstvaapiimage.h \ - gstvaapiimageformat.h \ gstvaapiimagepool.h \ gstvaapiobject.h \ gstvaapiprofile.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c deleted file mode 100644 index 54c94aa463..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * gstvaapiimageformat.c - VA image format abstraction - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation - * - * 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:gstvaapiimageformat - * @short_description: VA image format abstraction - */ - -#include "sysdeps.h" -#include -#include "gstvaapicompat.h" -#include "gstvaapiimageformat.h" - -typedef struct _GstVaapiImageFormatMap GstVaapiImageFormatMap; - -typedef enum { - GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR = 1, /* YUV */ - GST_VAAPI_IMAGE_FORMAT_TYPE_RGB, /* RGB */ - GST_VAAPI_IMAGE_FORMAT_TYPE_INDEXED /* paletted */ -} GstVaapiImageFormatType; - -struct _GstVaapiImageFormatMap { - GstVaapiImageFormatType type; - GstVaapiImageFormat format; - const char *caps_str; - VAImageFormat va_format; -}; - -#if GST_CHECK_VERSION(1,0,0) -# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \ - GST_VIDEO_CAPS_MAKE(#FORMAT) -# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \ - GST_VIDEO_CAPS_MAKE(#FORMAT) -#else -# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \ - GST_VIDEO_CAPS_YUV(#FORMAT) -# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \ - GST_VIDEO_CAPS_##FORMAT -#endif - -#define DEF(TYPE, FORMAT, CAPS_STR) \ - GST_VAAPI_IMAGE_FORMAT_TYPE_##TYPE, \ - GST_VAAPI_IMAGE_##FORMAT, \ - CAPS_STR -#define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP) \ - { DEF(YCBCR, FORMAT, GST_VIDEO_CAPS_MAKE_YUV(FORMAT)), \ - { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } -#define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \ - { DEF(RGB, FORMAT, GST_VIDEO_CAPS_MAKE_RGB(FORMAT)), \ - { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } - -/* Image formats, listed in HW order preference */ -static const GstVaapiImageFormatMap gst_vaapi_image_formats[] = { - DEF_YUV(NV12, ('N','V','1','2'), LSB, 12), - DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12), - DEF_YUV(I420, ('I','4','2','0'), LSB, 12), - DEF_YUV(AYUV, ('A','Y','U','V'), LSB, 32), -#if G_BYTE_ORDER == G_BIG_ENDIAN - DEF_RGB(ARGB, ('A','R','G','B'), MSB, 32, - 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), - DEF_RGB(ABGR, ('A','B','G','R'), MSB, 32, - 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), -#elif G_BYTE_ORDER == G_LITTLE_ENDIAN - DEF_RGB(BGRA, ('B','G','R','A'), LSB, 32, - 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), - DEF_RGB(RGBA, ('R','G','B','A'), LSB, 32, - 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), -#endif - { 0, } -}; - -#undef DEF_RGB -#undef DEF_YUV -#undef DEF - -static inline gboolean -match_va_format_rgb(const VAImageFormat *fmt1, const VAImageFormat *fmt2) -{ - return (fmt1->byte_order == fmt2->byte_order && - fmt1->red_mask == fmt2->red_mask && - fmt1->green_mask == fmt2->green_mask && - fmt1->blue_mask == fmt2->blue_mask && - fmt1->alpha_mask == fmt2->alpha_mask); -} - -static const GstVaapiImageFormatMap * -get_map(GstVaapiImageFormat format) -{ - const GstVaapiImageFormatMap *m; - - for (m = gst_vaapi_image_formats; m->format; m++) - if (m->format == format) - return m; - return NULL; -} - -/** - * gst_vaapi_image_format_is_rgb: - * @format: a #GstVaapiImageFormat - * - * Checks whether the format is an RGB format. - * - * Return value: %TRUE if @format is RGB format - */ -gboolean -gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format) -{ - const GstVaapiImageFormatMap * const m = get_map(format); - - return m ? (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB) : FALSE; -} - -/** - * gst_vaapi_image_format_is_yuv: - * @format: a #GstVaapiImageFormat - * - * Checks whether the format is an YUV format. - * - * Return value: %TRUE if @format is YUV format - */ -gboolean -gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format) -{ - const GstVaapiImageFormatMap * const m = get_map(format); - - return m ? (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR) : FALSE; -} - -/** - * gst_vaapi_image_format: - * @va_format: a #VAImageFormat - * - * Converts a VA image format into the corresponding #GstVaapiImageFormat. - * If the image format cannot be represented by #GstVaapiImageFormat, - * then zero is returned. - * - * Return value: the #GstVaapiImageFormat describing the @va_format - */ -GstVaapiImageFormat -gst_vaapi_image_format(const VAImageFormat *va_format) -{ - const GstVaapiImageFormatMap *m; - - for (m = gst_vaapi_image_formats; m->format; m++) - if (m->va_format.fourcc == va_format->fourcc && - (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB ? - match_va_format_rgb(&m->va_format, va_format) : - TRUE)) - return m->format; - - return 0; -} - -/** - * gst_vaapi_image_format_from_caps: - * @caps: a #GstCaps - * - * Converts @caps into the corresponding #GstVaapiImageFormat. If the - * image format cannot be represented by #GstVaapiImageFormat, then - * zero is returned. - * - * Return value: the #GstVaapiImageFormat describing the @caps - */ -GstVaapiImageFormat -gst_vaapi_image_format_from_caps(GstCaps *caps) -{ - GstStructure *structure; - - if (!caps) - return 0; - - structure = gst_caps_get_structure(caps, 0); - if (!structure) - return 0; - return gst_vaapi_image_format_from_structure(structure); -} - -/** - * gst_vaapi_image_format_from_structure: - * @structure: a #GstStructure - * - * Converts @structure into the corresponding #GstVaapiImageFormat. If - * the image format cannot be represented by #GstVaapiImageFormat, - * then zero is returned. - * - * Return value: the #GstVaapiImageFormat describing the @structure - */ -GstVaapiImageFormat -gst_vaapi_image_format_from_structure(GstStructure *structure) -{ - const GstVaapiImageFormatMap *m; - VAImageFormat *va_format, va_formats[2]; - gint endian, rmask, gmask, bmask, amask = 0; - guint32 fourcc; - - /* Check for YUV format */ - if (gst_structure_get_fourcc(structure, "format", &fourcc)) - return gst_vaapi_image_format_from_fourcc(fourcc); - - /* Check for RGB format */ - gst_structure_get_int(structure, "endianness", &endian); - gst_structure_get_int(structure, "red_mask", &rmask); - gst_structure_get_int(structure, "green_mask", &gmask); - gst_structure_get_int(structure, "blue_mask", &bmask); - gst_structure_get_int(structure, "alpha_mask", &amask); - - va_format = &va_formats[0]; - va_format->byte_order = endian == G_BIG_ENDIAN ? VA_MSB_FIRST : VA_LSB_FIRST; - va_format->red_mask = rmask; - va_format->green_mask = gmask; - va_format->blue_mask = bmask; - va_format->alpha_mask = amask; - - va_format = &va_formats[1]; - va_format->byte_order = endian == G_BIG_ENDIAN ? VA_LSB_FIRST : VA_MSB_FIRST; - va_format->red_mask = GUINT32_SWAP_LE_BE(rmask); - va_format->green_mask = GUINT32_SWAP_LE_BE(gmask); - va_format->blue_mask = GUINT32_SWAP_LE_BE(bmask); - va_format->alpha_mask = GUINT32_SWAP_LE_BE(amask); - - for (m = gst_vaapi_image_formats; m->format; m++) - if (match_va_format_rgb(&m->va_format, &va_formats[0]) || - match_va_format_rgb(&m->va_format, &va_formats[1])) - return m->format; - - return 0; -} - -/** - * gst_vaapi_image_format_from_fourcc: - * @fourcc: a FOURCC value - * - * Converts a FOURCC value into the corresponding #GstVaapiImageFormat. - * If the image format cannot be represented by #GstVaapiImageFormat, - * then zero is returned. - * - * Return value: the #GstVaapiImageFormat describing the FOURCC value - */ -GstVaapiImageFormat -gst_vaapi_image_format_from_fourcc(guint32 fourcc) -{ - return (GstVaapiImageFormat)fourcc; -} - -/** - * gst_vaapi_image_format_from_video: - * @format: a #GstVideoFormat - * - * Converts a #GstVideoFormat into the corresponding - * #GstVaapiImageFormat. If the image format cannot be represented by - * #GstVaapiImageFormat, then zero is returned. - * - * Return value: the #GstVaapiImageFormat describing the video format - */ -GstVaapiImageFormat -gst_vaapi_image_format_from_video(GstVideoFormat format) -{ - GstVaapiImageFormat va_format; - - switch (format) { - case GST_VIDEO_FORMAT_NV12: va_format = GST_VAAPI_IMAGE_NV12; break; - case GST_VIDEO_FORMAT_YV12: va_format = GST_VAAPI_IMAGE_YV12; break; - case GST_VIDEO_FORMAT_I420: va_format = GST_VAAPI_IMAGE_I420; break; - case GST_VIDEO_FORMAT_AYUV: va_format = GST_VAAPI_IMAGE_AYUV; break; - case GST_VIDEO_FORMAT_ARGB: va_format = GST_VAAPI_IMAGE_ARGB; break; - case GST_VIDEO_FORMAT_RGBA: va_format = GST_VAAPI_IMAGE_RGBA; break; - case GST_VIDEO_FORMAT_ABGR: va_format = GST_VAAPI_IMAGE_ABGR; break; - case GST_VIDEO_FORMAT_BGRA: va_format = GST_VAAPI_IMAGE_BGRA; break; - default: va_format = (GstVaapiImageFormat)0; break; - } - return va_format; -} - -/** - * gst_vaapi_image_format_get_va_format: - * @format: a #GstVaapiImageFormat - * - * Converts a #GstVaapiImageFormat into the corresponding VA image - * format. If no matching VA image format was found, %NULL is returned - * and this error must be reported to be fixed. - * - * Return value: the VA image format, or %NULL if none was found - */ -const VAImageFormat * -gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format) -{ - const GstVaapiImageFormatMap * const m = get_map(format); - - return m ? &m->va_format : NULL; -} - -/** - * gst_vaapi_image_format_get_caps: - * @format: a #GstVaapiImageFormat - * - * Converts a #GstVaapiImageFormat into the corresponding #GstCaps. If - * no matching caps were found, %NULL is returned. - * - * Return value: the newly allocated #GstCaps, or %NULL if none was found - */ -GstCaps * -gst_vaapi_image_format_get_caps(GstVaapiImageFormat format) -{ - const GstVaapiImageFormatMap * const m = get_map(format); - - return m ? gst_caps_from_string(m->caps_str) : NULL; -} - -/** - * gst_vaapi_image_format_get_score: - * @format: a #GstVaapiImageFormat - * - * Determines how "native" is this @format. The lower is the returned - * score, the best format this is for the underlying hardware. - * - * Return value: the @format score, or %G_MAXUINT if none was found - */ -guint -gst_vaapi_image_format_get_score(GstVaapiImageFormat format) -{ - const GstVaapiImageFormatMap * const m = get_map(format); - - return m ? (m - &gst_vaapi_image_formats[0]) : G_MAXUINT; -} diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h deleted file mode 100644 index 3e068e67af..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiimageformat.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * gstvaapiimageformat.h - VA image format abstraction - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Copyright (C) 2011-2012 Intel Corporation - * - * 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_IMAGE_FORMAT_H -#define GST_VAAPI_IMAGE_FORMAT_H - -#include -#include - -G_BEGIN_DECLS - -/** - * GstVaapiImageFormat: - * @GST_VAAPI_IMAGE_NV12: - * planar YUV 4:2:0, 12-bit, 1 plane for Y and 1 plane for UV - * @GST_VAAPI_IMAGE_YV12: - * planar YUV 4:2:0, 12-bit, 3 planes for Y V U - * @GST_VAAPI_IMAGE_I420: - * planar YUV 4:2:0, 12-bit, 3 planes for Y U V - * @GST_VAAPI_IMAGE_AYUV: - * packed YUV 4:4:4, 32-bit, A Y U V, native endian byte-order - * @GST_VAAPI_IMAGE_ARGB: - * packed RGB 8:8:8, 32-bit, A R G B - * @GST_VAAPI_IMAGE_RGBA: - * packed RGB 8:8:8, 32-bit, R G B A - * @GST_VAAPI_IMAGE_ABGR: - * packed RGB 8:8:8, 32-bit, A B G R - * @GST_VAAPI_IMAGE_BGRA: - * packed RGB 8:8:8, 32-bit, B G R A - * - * The set of all image formats for #GstVaapiImage. - */ -typedef enum { - GST_VAAPI_IMAGE_NV12 = GST_MAKE_FOURCC('N','V','1','2'), - GST_VAAPI_IMAGE_YV12 = GST_MAKE_FOURCC('Y','V','1','2'), - GST_VAAPI_IMAGE_I420 = GST_MAKE_FOURCC('I','4','2','0'), - GST_VAAPI_IMAGE_AYUV = GST_MAKE_FOURCC('A','Y','U','V'), - GST_VAAPI_IMAGE_ARGB = GST_MAKE_FOURCC('A','R','G','B'), - GST_VAAPI_IMAGE_RGBA = GST_MAKE_FOURCC('R','G','B','A'), - GST_VAAPI_IMAGE_ABGR = GST_MAKE_FOURCC('A','B','G','R'), - GST_VAAPI_IMAGE_BGRA = GST_MAKE_FOURCC('B','G','R','A'), -} GstVaapiImageFormat; - -gboolean -gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format); - -gboolean -gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format); - -GstVaapiImageFormat -gst_vaapi_image_format(const VAImageFormat *va_format); - -GstVaapiImageFormat -gst_vaapi_image_format_from_caps(GstCaps *caps); - -GstVaapiImageFormat -gst_vaapi_image_format_from_structure(GstStructure *structure); - -GstVaapiImageFormat -gst_vaapi_image_format_from_fourcc(guint32 fourcc); - -GstVaapiImageFormat -gst_vaapi_image_format_from_video(GstVideoFormat format); - -const VAImageFormat * -gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format); - -GstCaps * -gst_vaapi_image_format_get_caps(GstVaapiImageFormat format); - -guint -gst_vaapi_image_format_get_score(GstVaapiImageFormat format); - -G_END_DECLS - -#endif /* GST_GST_VAAPI_IMAGE_H */ From 40ac87b45e721b9141b183cfc682b1ccbabf3087 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Jul 2013 16:26:11 +0200 Subject: [PATCH 1243/3781] libs: use GstVideoInfo wherever possible. In particular, use gst_video_info_from_caps() helper function in VA image for implementating gst_vaapi_image_get_buffer() [vaapidownload] and gst_vaapi_image_update_from_buffer() [subpictures] in GStreamer 0.10 builds. --- gst-libs/gst/vaapi/gstvaapiimage.c | 80 +++++++++--------------------- 1 file changed, 24 insertions(+), 56 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 5872b8c6cc..4a67500227 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -735,13 +735,11 @@ init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) static gboolean init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) { - GstStructure *structure; GstCaps *caps; - GstVideoFormat format; - guint width2, height2, size2; - gint width, height; guchar *data; guint32 data_size; + GstVideoInfo vi; + guint i, frame_size; data = GST_BUFFER_DATA(buffer); data_size = GST_BUFFER_SIZE(buffer); @@ -750,63 +748,33 @@ init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) if (!caps) return FALSE; - format = gst_video_format_from_caps(caps); + if (!gst_video_info_from_caps(&vi, caps)) + goto error_unsupported_caps; - structure = gst_caps_get_structure(caps, 0); - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); + /* Check for compatible data size */ + frame_size = GST_VIDEO_INFO_SIZE(&vi); + if (frame_size != data_size) + goto error_incompatible_size; - /* XXX: copied from gst_video_format_get_row_stride() -- no NV12? */ - raw_image->format = format; - raw_image->width = width; - raw_image->height = height; - width2 = (width + 1) / 2; - height2 = (height + 1) / 2; - size2 = 0; - switch (format) { - case GST_VIDEO_FORMAT_NV12: - raw_image->num_planes = 2; - raw_image->pixels[0] = data; - raw_image->stride[0] = GST_ROUND_UP_4(width); - size2 += height * raw_image->stride[0]; - raw_image->pixels[1] = data + size2; - raw_image->stride[1] = raw_image->stride[0]; - size2 += height2 * raw_image->stride[1]; - break; - case GST_VIDEO_FORMAT_YV12: - case GST_VIDEO_FORMAT_I420: - raw_image->num_planes = 3; - raw_image->pixels[0] = data; - raw_image->stride[0] = GST_ROUND_UP_4(width); - size2 += height * raw_image->stride[0]; - raw_image->pixels[1] = data + size2; - raw_image->stride[1] = GST_ROUND_UP_4(width2); - size2 += height2 * raw_image->stride[1]; - raw_image->pixels[2] = data + size2; - raw_image->stride[2] = raw_image->stride[1]; - size2 += height2 * raw_image->stride[2]; - break; - case GST_VIDEO_FORMAT_ARGB: - case GST_VIDEO_FORMAT_RGBA: - case GST_VIDEO_FORMAT_ABGR: - case GST_VIDEO_FORMAT_BGRA: - raw_image->num_planes = 1; - raw_image->pixels[0] = data; - raw_image->stride[0] = width * 4; - size2 += height * raw_image->stride[0]; - break; - default: - g_error("could not compute row-stride for %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS(format)); - return FALSE; - } + raw_image->format = GST_VIDEO_INFO_FORMAT(&vi); + raw_image->width = GST_VIDEO_INFO_WIDTH(&vi); + raw_image->height = GST_VIDEO_INFO_HEIGHT(&vi); - if (size2 != data_size) { - g_error("data_size mismatch %d / %u", size2, data_size); - if (size2 > data_size) - return FALSE; + raw_image->num_planes = GST_VIDEO_INFO_N_PLANES(&vi); + for (i = 0; i < raw_image->num_planes; i++) { + raw_image->pixels[i] = data + GST_VIDEO_INFO_PLANE_OFFSET(&vi, i); + raw_image->stride[i] = GST_VIDEO_INFO_PLANE_STRIDE(&vi, i); } return TRUE; + + /* ERRORS */ +error_unsupported_caps: + GST_ERROR("unsupported caps %" GST_PTR_FORMAT, caps); + return FALSE; +error_incompatible_size: + GST_ERROR("incompatible frame size (%u) with buffer size (%u)", + frame_size, data_size); + return FALSE; } #endif From 09397fa0d85ffdc5aff819a72a700c7e2b4031a5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Jul 2013 15:44:35 +0200 Subject: [PATCH 1244/3781] plugins: port to new video format API. --- gst/vaapi/gstvaapidownload.c | 16 ++++++++-------- gst/vaapi/gstvaapiuploader.c | 16 +++++++--------- gst/vaapi/gstvaapivideomemory.c | 8 +------- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 4f0d20dc6c..4988800cc4 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -79,7 +79,7 @@ struct _GstVaapiDownload { GstCaps *allowed_caps; TransformSizeCache transform_size_cache[2]; GstVaapiVideoPool *images; - GstVaapiImageFormat image_format; + GstVideoFormat image_format; guint image_width; guint image_height; unsigned int images_reset : 1; @@ -252,7 +252,7 @@ gst_vaapidownload_init(GstVaapiDownload *download) download->allowed_caps = NULL; download->images = NULL; download->images_reset = FALSE; - download->image_format = (GstVaapiImageFormat)0; + download->image_format = GST_VIDEO_FORMAT_UNKNOWN; download->image_width = 0; download->image_height = 0; @@ -293,11 +293,11 @@ gst_vaapidownload_stop(GstBaseTransform *trans) return TRUE; } -static GstVaapiImageFormat +static GstVideoFormat get_surface_format(GstVaapiSurface *surface) { GstVaapiImage *image; - GstVaapiImageFormat format = GST_VAAPI_IMAGE_NV12; + GstVideoFormat format = GST_VIDEO_FORMAT_NV12; /* XXX: NV12 is assumed by default */ image = gst_vaapi_surface_derive_image(surface); @@ -313,7 +313,7 @@ gst_vaapidownload_update_src_caps(GstVaapiDownload *download, GstBuffer *buffer) { GstVaapiVideoMeta *meta; GstVaapiSurface *surface; - GstVaapiImageFormat format; + GstVideoFormat format; GstPad *srcpad; GstCaps *in_caps, *out_caps; @@ -334,7 +334,7 @@ gst_vaapidownload_update_src_caps(GstVaapiDownload *download, GstBuffer *buffer) return FALSE; } - out_caps = gst_vaapi_image_format_get_caps(format); + out_caps = gst_video_format_to_caps(format); if (!out_caps) { GST_WARNING("failed to create caps from format %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(format)); @@ -485,10 +485,10 @@ static gboolean gst_vaapidownload_ensure_image_pool(GstVaapiDownload *download, GstCaps *caps) { GstStructure * const structure = gst_caps_get_structure(caps, 0); - GstVaapiImageFormat format; + GstVideoFormat format; gint width, height; - format = gst_vaapi_image_format_from_caps(caps); + format = gst_video_format_from_caps(caps); gst_structure_get_int(structure, "width", &width); gst_structure_get_int(structure, "height", &height); diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 8413fe679f..814e73e19a 100755 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -141,10 +141,10 @@ ensure_allowed_caps(GstVaapiUploader *uploader) for (i = 0; i < n_structures; i++) { GstStructure * const structure = gst_caps_get_structure(image_caps, i); GstVaapiImage *image; - GstVaapiImageFormat format; + GstVideoFormat format; - format = gst_vaapi_image_format_from_structure(structure); - if (!format) + format = gst_video_format_from_structure(structure); + if (format == GST_VIDEO_FORMAT_UNKNOWN) continue; image = gst_vaapi_image_new(priv->display, format, WIDTH, HEIGHT); if (!image) @@ -309,7 +309,7 @@ gst_vaapi_uploader_ensure_caps( { GstVaapiUploaderPrivate *priv; GstVaapiImage *image; - GstVaapiImageFormat vaformat; + GstVideoFormat format; GstVideoInfo vi; g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); @@ -323,19 +323,17 @@ gst_vaapi_uploader_ensure_caps( priv = uploader->priv; priv->direct_rendering = 0; - /* Translate from Gst video format to VA image format */ + /* Strip out non-YUV formats */ if (!gst_video_info_from_caps(&vi, src_caps)) return FALSE; if (!GST_VIDEO_INFO_IS_YUV(&vi)) return FALSE; - vaformat = gst_vaapi_image_format_from_video(GST_VIDEO_INFO_FORMAT(&vi)); - if (!vaformat) - return FALSE; + format = GST_VIDEO_INFO_FORMAT(&vi); /* Check if we can alias source and output buffers (same data_size) */ image = gst_vaapi_video_pool_get_object(priv->images); if (image) { - if (gst_vaapi_image_get_format(image) == vaformat && + if (gst_vaapi_image_get_format(image) == format && gst_vaapi_image_is_linear(image) && gst_vaapi_image_get_data_size(image) == GST_VIDEO_INFO_SIZE(&vi)) priv->direct_rendering = 1; diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index db27b08f15..31cf259fd5 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -37,13 +37,7 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideomemory); static GstVaapiImage * new_image(GstVaapiDisplay *display, const GstVideoInfo *vip) { - GstVaapiImageFormat format; - - format = gst_vaapi_image_format_from_video(GST_VIDEO_INFO_FORMAT(vip)); - if (!format) - return NULL; - - return gst_vaapi_image_new(display, format, + return gst_vaapi_image_new(display, GST_VIDEO_INFO_FORMAT(vip), GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); } From cb92e7ca797839858f65f5780f6fceced7426b79 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Jul 2013 15:28:31 +0200 Subject: [PATCH 1245/3781] tests: port to new video format API. --- tests/image.c | 12 ++++++------ tests/image.h | 2 +- tests/test-display.c | 10 +++++----- tests/test-textures.c | 2 +- tests/test-windows.c | 24 ++++++++++++------------ 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/image.c b/tests/image.c index 5c45391fd2..d412a17cb7 100644 --- a/tests/image.c +++ b/tests/image.c @@ -24,7 +24,7 @@ GstVaapiImage * image_generate( GstVaapiDisplay *display, - GstVaapiImageFormat format, + GstVideoFormat format, guint width, guint height ) @@ -257,7 +257,7 @@ image_draw_rectangle( guint32 color ) { - const GstVaapiImageFormat image_format = gst_vaapi_image_get_format(image); + const GstVideoFormat image_format = gst_vaapi_image_get_format(image); const guint image_width = gst_vaapi_image_get_width(image); const guint image_height = gst_vaapi_image_get_height(image); GstVaapiDisplay *display; @@ -267,11 +267,11 @@ image_draw_rectangle( guint i; static const struct { - GstVaapiImageFormat format; + GstVideoFormat format; DrawRectFunc draw_rect; } map[] = { -#define _(FORMAT) { GST_VAAPI_IMAGE_##FORMAT, draw_rect_##FORMAT } +#define _(FORMAT) { GST_VIDEO_FORMAT_##FORMAT, draw_rect_##FORMAT } _(ARGB), _(BGRA), _(RGBA), @@ -302,7 +302,7 @@ image_draw_rectangle( stride[i] = gst_vaapi_image_get_pitch(image, i); } - if (gst_vaapi_image_format_is_yuv(image_format)) + if (gst_video_format_is_yuv(image_format)) color = argb2yuv(color); if (x < 0) @@ -324,7 +324,7 @@ gboolean image_upload(GstVaapiImage *image, GstVaapiSurface *surface) { GstVaapiDisplay *display; - GstVaapiImageFormat format; + GstVideoFormat format; GstVaapiSubpicture *subpicture; display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); diff --git a/tests/image.h b/tests/image.h index 0b7f487f11..6c7afaf961 100644 --- a/tests/image.h +++ b/tests/image.h @@ -28,7 +28,7 @@ GstVaapiImage * image_generate( GstVaapiDisplay *display, - GstVaapiImageFormat format, + GstVideoFormat format, guint width, guint height ); diff --git a/tests/test-display.c b/tests/test-display.c index 4155fc1331..263fa35c1c 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -126,22 +126,22 @@ print_format_caps(GstCaps *caps, const gchar *name) for (i = 0; i < gst_caps_get_size(caps); i++) { GstStructure * const structure = gst_caps_get_structure(caps, i); const VAImageFormat *va_format; - GstVaapiImageFormat format; + GstVideoFormat format; if (!structure) g_error("could not get caps structure %d", i); g_print(" %s:", gst_structure_get_name(structure)); - format = gst_vaapi_image_format_from_structure(structure); - if (!format) + format = gst_video_format_from_structure(structure); + if (format == GST_VIDEO_FORMAT_UNKNOWN) g_error("could not determine format"); - va_format = gst_vaapi_image_format_get_va_format(format); + va_format = gst_video_format_to_va_format(format); if (!va_format) g_error("could not determine VA format"); - if (gst_vaapi_image_format_is_yuv(format)) + if (gst_video_format_is_yuv(format)) print_format_caps_yuv(va_format); else print_format_caps_rgb(va_format); diff --git a/tests/test-textures.c b/tests/test-textures.c index e89fb5f2ea..14bb5151e3 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -71,7 +71,7 @@ main(int argc, char *argv[]) if (!surface) g_error("could not create VA surface"); - image = image_generate(display, GST_VAAPI_IMAGE_NV12, width, height); + image = image_generate(display, GST_VIDEO_FORMAT_NV12, width, height); if (!image) g_error("could not create VA image"); if (!image_upload(image, surface)) diff --git a/tests/test-windows.c b/tests/test-windows.c index a305205ea4..fa5b40b010 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -52,24 +52,24 @@ create_test_surface(GstVaapiDisplay *display, guint width, guint height) guint i; static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - static const GstVaapiImageFormat image_formats[] = { - GST_VAAPI_IMAGE_NV12, - GST_VAAPI_IMAGE_YV12, - GST_VAAPI_IMAGE_I420, - GST_VAAPI_IMAGE_AYUV, - GST_VAAPI_IMAGE_ARGB, - GST_VAAPI_IMAGE_BGRA, - GST_VAAPI_IMAGE_RGBA, - GST_VAAPI_IMAGE_ABGR, - 0 + static const GstVideoFormat image_formats[] = { + GST_VIDEO_FORMAT_NV12, + GST_VIDEO_FORMAT_YV12, + GST_VIDEO_FORMAT_I420, + GST_VIDEO_FORMAT_AYUV, + GST_VIDEO_FORMAT_ARGB, + GST_VIDEO_FORMAT_BGRA, + GST_VIDEO_FORMAT_RGBA, + GST_VIDEO_FORMAT_ABGR, + GST_VIDEO_FORMAT_UNKNOWN }; surface = gst_vaapi_surface_new(display, chroma_type, width, height); if (!surface) g_error("could not create Gst/VA surface"); - for (i = 0; image_formats[i]; i++) { - const GstVaapiImageFormat format = image_formats[i]; + for (i = 0; image_formats[i] != GST_VIDEO_FORMAT_UNKNOWN; i++) { + const GstVideoFormat format = image_formats[i]; image = image_generate(display, format, width, height); if (!image) From d469b7274ca0c41b8a44e139ee8477648bb7308c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Jul 2013 15:52:20 +0200 Subject: [PATCH 1246/3781] image: fix debug message with video format. Fix debug message string with image format expressed with GstVideoFormat instead of the obsolete format that turned out to be a fourcc. This is a regression from git commit e61c5fc. --- gst-libs/gst/vaapi/gstvaapiimage.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 4a67500227..2b86908ac1 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -273,8 +273,8 @@ gst_vaapi_image_new( g_return_val_if_fail(width > 0, NULL); g_return_val_if_fail(height > 0, NULL); - GST_DEBUG("format %" GST_FOURCC_FORMAT ", size %ux%u", - GST_FOURCC_ARGS(format), width, height); + GST_DEBUG("format %s, size %ux%u", gst_video_format_to_string(format), + width, height); image = gst_vaapi_object_new(gst_vaapi_image_class(), display); if (!image) @@ -422,8 +422,8 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) image->image = alt_va_image; image->format = format; image->is_linear = TRUE; - GST_DEBUG("linearized image to %" GST_FOURCC_FORMAT " format", - GST_FOURCC_ARGS(format)); + GST_DEBUG("linearized image to %s format", + gst_video_format_to_string(format)); } } } From 97c0316fe497ec359040a208783c8f870bea67a0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Jul 2013 18:03:36 +0200 Subject: [PATCH 1247/3781] Add more video formats. Add new video format mappings to VA image formats: - YUV: packed YUV (YUY2, UYVY), grayscale (Y800) ; - RGB: 32-bit RGB without alpha channel (XRGB, XBGR, RGBX, BGRX). --- gst-libs/gst/vaapi/gstvaapiimage.c | 14 +++++++++++++- gst-libs/gst/vaapi/video-format.c | 11 +++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 2b86908ac1..bb46866f50 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -105,15 +105,27 @@ vaapi_image_is_linear(const VAImage *va_image) case VA_FOURCC('I','4','2','0'): data_size = width * height + 2 * width2 * height2; break; + case VA_FOURCC('Y','U','Y','2'): + case VA_FOURCC('U','Y','V','Y'): + data_size = 2 * width * height; + break; + case VA_FOURCC('Y','8','0','0'): + data_size = width * height; + break; case VA_FOURCC('A','Y','U','V'): case VA_FOURCC('A','R','G','B'): case VA_FOURCC('R','G','B','A'): case VA_FOURCC('A','B','G','R'): case VA_FOURCC('B','G','R','A'): + case VA_FOURCC('X','R','G','B'): + case VA_FOURCC('R','G','B','X'): + case VA_FOURCC('X','B','G','R'): + case VA_FOURCC('B','G','R','X'): data_size = 4 * width * height; break; default: - g_error("FIXME: incomplete formats"); + g_error("FIXME: incomplete formats %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS(va_image->format.fourcc)); break; } return va_image->data_size == data_size; diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index d9236dce9e..7d9efca5a3 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -63,18 +63,29 @@ static const GstVideoFormatMap gst_video_formats[] = { DEF_YUV(NV12, ('N','V','1','2'), LSB, 12), DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12), DEF_YUV(I420, ('I','4','2','0'), LSB, 12), + DEF_YUV(YUY2, ('Y','U','Y','2'), LSB, 16), + DEF_YUV(UYVY, ('U','Y','V','Y'), LSB, 16), DEF_YUV(AYUV, ('A','Y','U','V'), LSB, 32), #if G_BYTE_ORDER == G_BIG_ENDIAN DEF_RGB(ARGB, ('A','R','G','B'), MSB, 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), DEF_RGB(ABGR, ('A','B','G','R'), MSB, 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), + DEF_RGB(xRGB, ('X','R','G','B'), MSB, 32, + 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), + DEF_RGB(xBGR, ('X','B','G','R'), MSB, 32, + 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), #elif G_BYTE_ORDER == G_LITTLE_ENDIAN DEF_RGB(BGRA, ('B','G','R','A'), LSB, 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), DEF_RGB(RGBA, ('R','G','B','A'), LSB, 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), + DEF_RGB(BGRx, ('B','G','R','X'), LSB, 32, + 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), + DEF_RGB(RGBx, ('R','G','B','X'), LSB, 32, + 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), #endif + DEF_YUV(GRAY8, ('Y','8','0','0'), LSB, 8), { 0, } }; From 4ca7922f4b15857b63fcf6c52aed411146d7c220 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Jul 2013 13:07:37 +0200 Subject: [PATCH 1248/3781] Use GstVideoInfo for video pools. Get rid of GstCaps to create surface/image pool, and use GstVideoInfo structures instead. Those are smaller, and allows for streamlining libgstvaapi more. --- gst-libs/gst/vaapi/gstvaapicontext.c | 18 +++---------- gst-libs/gst/vaapi/gstvaapiimagepool.c | 23 +++++++--------- gst-libs/gst/vaapi/gstvaapiimagepool.h | 3 ++- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 22 ++++++--------- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 3 ++- gst-libs/gst/vaapi/gstvaapivideopool.h | 1 - gst/vaapi/gstvaapidownload.c | 15 ++++++----- gst/vaapi/gstvaapiuploader.c | 34 ++++++++++++++++-------- tests/Makefile.am | 5 ++-- tests/test-surfaces.c | 15 +++-------- 10 files changed, 64 insertions(+), 75 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index a132e82746..6cdf1b39b6 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -469,7 +469,7 @@ static gboolean gst_vaapi_context_create_surfaces(GstVaapiContext *context) { const GstVaapiContextInfo * const cip = &context->info; - GstCaps *caps; + GstVideoInfo vi; GstVaapiSurface *surface; guint i, num_surfaces; @@ -486,20 +486,10 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context) } if (!context->surfaces_pool) { - caps = gst_caps_new_simple( - GST_VAAPI_SURFACE_CAPS_NAME, - "type", G_TYPE_STRING, "vaapi", - "width", G_TYPE_INT, cip->width, - "height", G_TYPE_INT, cip->height, - NULL - ); - if (!caps) - return FALSE; + gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_ENCODED, + cip->width, cip->height); context->surfaces_pool = gst_vaapi_surface_pool_new( - GST_VAAPI_OBJECT_DISPLAY(context), - caps - ); - gst_caps_unref(caps); + GST_VAAPI_OBJECT_DISPLAY(context), &vi); if (!context->surfaces_pool) return FALSE; } diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 2f85bcabd9..8b9a140264 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -47,17 +47,13 @@ struct _GstVaapiImagePool { }; static gboolean -gst_vaapi_image_pool_set_caps(GstVaapiVideoPool *base_pool, GstCaps *caps) +image_pool_init(GstVaapiVideoPool *base_pool, const GstVideoInfo *vip) { GstVaapiImagePool * const pool = GST_VAAPI_IMAGE_POOL(base_pool); - GstVideoInfo vi; - if (!gst_video_info_from_caps(&vi, caps)) - return FALSE; - - pool->format = GST_VIDEO_INFO_FORMAT(&vi); - pool->width = GST_VIDEO_INFO_WIDTH(&vi); - pool->height = GST_VIDEO_INFO_HEIGHT(&vi); + pool->format = GST_VIDEO_INFO_FORMAT(vip); + pool->width = GST_VIDEO_INFO_WIDTH(vip); + pool->height = GST_VIDEO_INFO_HEIGHT(vip); return TRUE; } @@ -85,20 +81,20 @@ gst_vaapi_image_pool_class(void) /** * gst_vaapi_image_pool_new: * @display: a #GstVaapiDisplay - * @caps: a #GstCaps + * @vip: the #GstVideoInfo * * Creates a new #GstVaapiVideoPool of #GstVaapiImage with the - * specified dimensions in @caps. + * specified format and dimensions in @vip. * * Return value: the newly allocated #GstVaapiVideoPool */ GstVaapiVideoPool * -gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps) +gst_vaapi_image_pool_new(GstVaapiDisplay *display, const GstVideoInfo *vip) { GstVaapiVideoPool *pool; g_return_val_if_fail(display != NULL, NULL); - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + g_return_val_if_fail(vip != NULL, NULL); pool = (GstVaapiVideoPool *) gst_vaapi_mini_object_new(gst_vaapi_image_pool_class()); @@ -107,7 +103,8 @@ gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps) gst_vaapi_video_pool_init(pool, display, GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE); - if (!gst_vaapi_image_pool_set_caps(pool, caps)) + + if (!image_pool_init(pool, vip)) goto error; return pool; diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index 801cdaedd3..19677eb1c8 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -25,6 +25,7 @@ #include #include +#include G_BEGIN_DECLS @@ -34,7 +35,7 @@ G_BEGIN_DECLS typedef struct _GstVaapiImagePool GstVaapiImagePool; GstVaapiVideoPool * -gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps); +gst_vaapi_image_pool_new(GstVaapiDisplay *display, const GstVideoInfo *vip); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index f429b9d2f7..7f691540bb 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -47,17 +47,11 @@ struct _GstVaapiSurfacePool { }; static gboolean -gst_vaapi_surface_pool_set_caps(GstVaapiVideoPool *base_pool, GstCaps *caps) +surface_pool_init(GstVaapiSurfacePool *pool, const GstVideoInfo *vip) { - GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(base_pool); - GstVideoInfo vi; - - if (!gst_video_info_from_caps(&vi, caps)) - return FALSE; - pool->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - pool->width = GST_VIDEO_INFO_WIDTH(&vi); - pool->height = GST_VIDEO_INFO_HEIGHT(&vi); + pool->width = GST_VIDEO_INFO_WIDTH(vip); + pool->height = GST_VIDEO_INFO_HEIGHT(vip); return TRUE; } @@ -85,20 +79,20 @@ gst_vaapi_surface_pool_class(void) /** * gst_vaapi_surface_pool_new: * @display: a #GstVaapiDisplay - * @caps: a #GstCaps + * @vip: a #GstVideoInfo * * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the - * specified dimensions in @caps. + * specified format and dimensions in @vip. * * Return value: the newly allocated #GstVaapiVideoPool */ GstVaapiVideoPool * -gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps) +gst_vaapi_surface_pool_new(GstVaapiDisplay *display, const GstVideoInfo *vip) { GstVaapiVideoPool *pool; g_return_val_if_fail(display != NULL, NULL); - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + g_return_val_if_fail(vip != NULL, NULL); pool = (GstVaapiVideoPool *) gst_vaapi_mini_object_new(gst_vaapi_surface_pool_class()); @@ -107,7 +101,7 @@ gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps) gst_vaapi_video_pool_init(pool, display, GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE); - if (!gst_vaapi_surface_pool_set_caps(pool, caps)) + if (!surface_pool_init(GST_VAAPI_SURFACE_POOL(pool), vip)) goto error; return pool; diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 48ea71edc7..7e47920651 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -25,6 +25,7 @@ #include #include +#include G_BEGIN_DECLS @@ -34,7 +35,7 @@ G_BEGIN_DECLS typedef struct _GstVaapiSurfacePool GstVaapiSurfacePool; GstVaapiVideoPool * -gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps); +gst_vaapi_surface_pool_new(GstVaapiDisplay *display, const GstVideoInfo *vip); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 03b6cffdc3..07ad7a35f3 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -24,7 +24,6 @@ #define GST_VAAPI_VIDEO_POOL_H #include -#include #include G_BEGIN_DECLS diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 4988800cc4..133615efab 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -484,13 +484,16 @@ gst_vaapidownload_transform_caps( static gboolean gst_vaapidownload_ensure_image_pool(GstVaapiDownload *download, GstCaps *caps) { - GstStructure * const structure = gst_caps_get_structure(caps, 0); + GstVideoInfo vi; GstVideoFormat format; - gint width, height; + guint width, height; - format = gst_video_format_from_caps(caps); - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); + if (!gst_video_info_from_caps(&vi, caps)) + return FALSE; + + format = GST_VIDEO_INFO_FORMAT(&vi); + width = GST_VIDEO_INFO_WIDTH(&vi); + height = GST_VIDEO_INFO_HEIGHT(&vi); if (format != download->image_format || width != download->image_width || @@ -499,7 +502,7 @@ gst_vaapidownload_ensure_image_pool(GstVaapiDownload *download, GstCaps *caps) download->image_width = width; download->image_height = height; gst_vaapi_video_pool_replace(&download->images, NULL); - download->images = gst_vaapi_image_pool_new(download->display, caps); + download->images = gst_vaapi_image_pool_new(download->display, &vi); if (!download->images) return FALSE; download->images_reset = TRUE; diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 814e73e19a..dc3a0dce64 100755 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -51,6 +51,7 @@ struct _GstVaapiUploaderPrivate { GstCaps *allowed_caps; GstVaapiVideoPool *images; GstCaps *image_caps; + GstVideoFormat image_format; guint image_width; guint image_height; GstVaapiVideoPool *surfaces; @@ -170,17 +171,25 @@ static gboolean ensure_image_pool(GstVaapiUploader *uploader, GstCaps *caps) { GstVaapiUploaderPrivate * const priv = uploader->priv; - GstStructure * const structure = gst_caps_get_structure(caps, 0); - gint width, height; + GstVideoInfo vi; + GstVideoFormat format; + guint width, height; - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); + if (!gst_video_info_from_caps(&vi, caps)) + return FALSE; - if (width != priv->image_width || height != priv->image_height) { + format = GST_VIDEO_INFO_FORMAT(&vi); + width = GST_VIDEO_INFO_WIDTH(&vi); + height = GST_VIDEO_INFO_HEIGHT(&vi); + + if (format != priv->image_format || + width != priv->image_width || + height != priv->image_height) { + priv->image_format = format; priv->image_width = width; priv->image_height = height; gst_vaapi_video_pool_replace(&priv->images, NULL); - priv->images = gst_vaapi_image_pool_new(priv->display, caps); + priv->images = gst_vaapi_image_pool_new(priv->display, &vi); if (!priv->images) return FALSE; gst_caps_replace(&priv->image_caps, caps); @@ -192,17 +201,20 @@ static gboolean ensure_surface_pool(GstVaapiUploader *uploader, GstCaps *caps) { GstVaapiUploaderPrivate * const priv = uploader->priv; - GstStructure * const structure = gst_caps_get_structure(caps, 0); - gint width, height; + GstVideoInfo vi; + guint width, height; - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); + if (!gst_video_info_from_caps(&vi, caps)) + return FALSE; + + width = GST_VIDEO_INFO_WIDTH(&vi); + height = GST_VIDEO_INFO_HEIGHT(&vi); if (width != priv->surface_width || height != priv->surface_height) { priv->surface_width = width; priv->surface_height = height; gst_vaapi_video_pool_replace(&priv->surfaces, NULL); - priv->surfaces = gst_vaapi_surface_pool_new(priv->display, caps); + priv->surfaces = gst_vaapi_surface_pool_new(priv->display, &vi); if (!priv->surfaces) return FALSE; } diff --git a/tests/Makefile.am b/tests/Makefile.am index 8c4d967dec..0bc4f73095 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -86,8 +86,9 @@ test_display_CFLAGS = $(TEST_CFLAGS) test_display_LDADD = libutils.la $(TEST_LIBS) test_surfaces_SOURCES = test-surfaces.c -test_surfaces_CFLAGS = $(TEST_CFLAGS) -test_surfaces_LDADD = libutils.la $(TEST_LIBS) +test_surfaces_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) +test_surfaces_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) \ + $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la test_subpicture_SOURCES = test-subpicture.c test-subpicture-data.c test_subpicture_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index 806f8f31bc..bc55dd7f8f 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -34,7 +34,7 @@ main(int argc, char *argv[]) GstVaapiID surface_id; GstVaapiSurface *surfaces[MAX_SURFACES]; GstVaapiVideoPool *pool; - GstCaps *caps; + GstVideoInfo vi; gint i; static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; @@ -58,17 +58,9 @@ main(int argc, char *argv[]) gst_vaapi_object_unref(surface); - caps = gst_caps_new_simple( - GST_VAAPI_SURFACE_CAPS_NAME, - "type", G_TYPE_STRING, "vaapi", - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - NULL - ); - if (!caps) - g_error("cound not create Gst/VA surface caps"); + gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_ENCODED, width, height); - pool = gst_vaapi_surface_pool_new(display, caps); + pool = gst_vaapi_surface_pool_new(display, &vi); if (!pool) g_error("could not create Gst/VA surface pool"); @@ -107,7 +99,6 @@ main(int argc, char *argv[]) /* Unref in random order to check objects are correctly refcounted */ gst_vaapi_display_unref(display); - gst_caps_unref(caps); gst_vaapi_video_pool_unref(pool); gst_vaapi_object_unref(surface); video_output_exit(); From 60b003709ffa76890e39d78a3ef528404f1821b5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Jul 2013 13:32:15 +0200 Subject: [PATCH 1249/3781] pool: fix image pool to check for the video format to use. Make gst_vaapi_image_pool_new() succeed, and thus returning a valid image pool object, only if the underlying VA display does support the requested VA image format. --- gst-libs/gst/vaapi/gstvaapiimagepool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 8b9a140264..3b5d4b775b 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -54,7 +54,7 @@ image_pool_init(GstVaapiVideoPool *base_pool, const GstVideoInfo *vip) pool->format = GST_VIDEO_INFO_FORMAT(vip); pool->width = GST_VIDEO_INFO_WIDTH(vip); pool->height = GST_VIDEO_INFO_HEIGHT(vip); - return TRUE; + return gst_vaapi_display_has_image_format(base_pool->display, pool->format); } static gpointer From d633e0d072b8de38a42713c40406bc94353116c5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Jul 2013 19:13:39 +0200 Subject: [PATCH 1250/3781] surface: add new chroma formats. Add new chroma formats available with VA-API >= 0.34.0. In particular, this includes "RGB" chroma formats, and more YUV subsampled formats. Also add a new from_GstVaapiChromaType() helper function to convert libgstvaapi chroma type to VA chroma format. --- gst-libs/gst/vaapi/gstvaapisurface.c | 26 +++++++---------- gst-libs/gst/vaapi/gstvaapisurface.h | 15 +++++++++- gst-libs/gst/vaapi/gstvaapiutils.c | 43 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 4 +++ 4 files changed, 71 insertions(+), 17 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index e6329b956e..9cd129d0dd 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -102,27 +102,16 @@ gst_vaapi_surface_create(GstVaapiSurface *surface, GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface); VASurfaceID surface_id; VAStatus status; - guint format; + guint va_chroma_format; - switch (chroma_type) { - case GST_VAAPI_CHROMA_TYPE_YUV420: - format = VA_RT_FORMAT_YUV420; - break; - case GST_VAAPI_CHROMA_TYPE_YUV422: - format = VA_RT_FORMAT_YUV422; - break; - case GST_VAAPI_CHROMA_TYPE_YUV444: - format = VA_RT_FORMAT_YUV444; - break; - default: - GST_DEBUG("unsupported chroma-type %u\n", chroma_type); - return FALSE; - } + va_chroma_format = from_GstVaapiChromaType(chroma_type); + if (!va_chroma_format) + goto error_unsupported_chroma_type; GST_VAAPI_DISPLAY_LOCK(display); status = vaCreateSurfaces( GST_VAAPI_DISPLAY_VADISPLAY(display), - width, height, format, + width, height, va_chroma_format, 1, &surface_id ); GST_VAAPI_DISPLAY_UNLOCK(display); @@ -136,6 +125,11 @@ gst_vaapi_surface_create(GstVaapiSurface *surface, GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); GST_VAAPI_OBJECT_ID(surface) = surface_id; return TRUE; + + /* ERRORS */ +error_unsupported_chroma_type: + GST_ERROR("unsupported chroma-type %u", chroma_type); + return FALSE; } #define gst_vaapi_surface_finalize gst_vaapi_surface_destroy diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 15f8b7da3e..e6ceaccaca 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -56,13 +56,26 @@ G_BEGIN_DECLS * @GST_VAAPI_CHROMA_TYPE_YUV420: 4:2:0 chroma format * @GST_VAAPI_CHROMA_TYPE_YUV422: 4:2:2 chroma format * @GST_VAAPI_CHROMA_TYPE_YUV444: 4:4:4 chroma format + * @GST_VAAPI_CHROMA_TYPE_YUV420: YUV 4:2:0 chroma format + * @GST_VAAPI_CHROMA_TYPE_YUV422: YUV 4:2:2 chroma format + * @GST_VAAPI_CHROMA_TYPE_YUV444: YUV 4:4:4 chroma format + * @GST_VAAPI_CHROMA_TYPE_YUV411: YUV 4:1:1 chroma format + * @GST_VAAPI_CHROMA_TYPE_YUV410: YUV 4:1:0 chroma format + * @GST_VAAPI_CHROMA_TYPE_YUV400: YUV 4:0:0 chroma format (grayscale) + * @GST_VAAPI_CHROMA_TYPE_RGB32: 32-bit RGB chroma format + * @GST_VAAPI_CHROMA_TYPE_RGB16: 16-bit RGB chroma format * * The set of all chroma types for #GstVaapiSurface. */ typedef enum { GST_VAAPI_CHROMA_TYPE_YUV420 = 1, GST_VAAPI_CHROMA_TYPE_YUV422, - GST_VAAPI_CHROMA_TYPE_YUV444 + GST_VAAPI_CHROMA_TYPE_YUV444, + GST_VAAPI_CHROMA_TYPE_YUV411, + GST_VAAPI_CHROMA_TYPE_YUV410, + GST_VAAPI_CHROMA_TYPE_YUV400, + GST_VAAPI_CHROMA_TYPE_RGB32, + GST_VAAPI_CHROMA_TYPE_RGB16 } GstVaapiChromaType; /** diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index f959dd9d49..aec68ff6d6 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -203,6 +203,49 @@ string_of_VADisplayAttributeType(VADisplayAttribType attribute_type) return ""; } +/** + * from_GstVaapiChromaType: + * @chroma_type: the #GstVaapiChromaType + * + * Converts #GstVaapiChromaType to a chroma format suitable for + * vaCreateSurfaces(). + */ +guint +from_GstVaapiChromaType(guint chroma_type) +{ + guint format; + + switch (chroma_type) { + case GST_VAAPI_CHROMA_TYPE_YUV420: + format = VA_RT_FORMAT_YUV420; + break; + case GST_VAAPI_CHROMA_TYPE_YUV422: + format = VA_RT_FORMAT_YUV422; + break; + case GST_VAAPI_CHROMA_TYPE_YUV444: + format = VA_RT_FORMAT_YUV444; + break; +#if VA_CHECK_VERSION(0,34,0) + case GST_VAAPI_CHROMA_TYPE_YUV411: + format = VA_RT_FORMAT_YUV411; + break; + case GST_VAAPI_CHROMA_TYPE_YUV400: + format = VA_RT_FORMAT_YUV400; + break; + case GST_VAAPI_CHROMA_TYPE_RGB32: + format = VA_RT_FORMAT_RGB32; + break; + case GST_VAAPI_CHROMA_TYPE_RGB16: + format = VA_RT_FORMAT_RGB16; + break; +#endif + default: + format = 0; + break; + } + return format; +} + /** * from_GstVaapiSubpictureFlags: * @flags: the #GstVaapiSubpictureFlags diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index da693447df..a0a84b4f37 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -73,6 +73,10 @@ G_GNUC_INTERNAL const char * string_of_VADisplayAttributeType(VADisplayAttribType attribute_type); +G_GNUC_INTERNAL +guint +from_GstVaapiChromaType(guint chroma_type); + G_GNUC_INTERNAL guint from_GstVaapiSubpictureFlags(guint flags); From e3da054e482b85a80c4e323db1195237f8dd32ce Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Jul 2013 09:48:40 +0200 Subject: [PATCH 1251/3781] surface: add helper function to get chroma type from GstVideoFormat. Add gst_video_format_get_chroma_type() helper function to determine the GstVaapiChromaType from a standard GStreamer video format. It is possible to reconstruct that from GstVideoFormatInfo but it is much simpler (and faster?) to use the local GstVideoFormatMap table. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/video-format.c | 39 +++++++++++++++++++++------ gst-libs/gst/vaapi/video-format.h | 3 +++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 36cd6f4224..bd0229c30f 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -4,6 +4,7 @@ gst_video_format_from_caps gst_video_format_from_structure gst_video_format_from_va_format +gst_video_format_get_chroma_type gst_video_format_get_score gst_video_format_is_rgb gst_video_format_is_yuv diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 7d9efca5a3..b5a3c85b23 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -28,11 +28,13 @@ #include "sysdeps.h" #include #include "gstvaapicompat.h" +#include "gstvaapisurface.h" #include "video-format.h" typedef struct _GstVideoFormatMap GstVideoFormatMap; struct _GstVideoFormatMap { GstVideoFormat format; + GstVaapiChromaType chroma_type; const char *caps_str; VAImageFormat va_format; }; @@ -49,23 +51,26 @@ struct _GstVideoFormatMap { GST_VIDEO_CAPS_##FORMAT #endif -#define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP) \ +#define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP, SUB) \ { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ + G_PASTE(GST_VAAPI_CHROMA_TYPE_YUV,SUB), \ GST_VIDEO_CAPS_MAKE_YUV(FORMAT), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } + #define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \ { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ + G_PASTE(GST_VAAPI_CHROMA_TYPE_RGB,BPP), \ GST_VIDEO_CAPS_MAKE_RGB(FORMAT), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } /* Image formats, listed in HW order preference */ static const GstVideoFormatMap gst_video_formats[] = { - DEF_YUV(NV12, ('N','V','1','2'), LSB, 12), - DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12), - DEF_YUV(I420, ('I','4','2','0'), LSB, 12), - DEF_YUV(YUY2, ('Y','U','Y','2'), LSB, 16), - DEF_YUV(UYVY, ('U','Y','V','Y'), LSB, 16), - DEF_YUV(AYUV, ('A','Y','U','V'), LSB, 32), + DEF_YUV(NV12, ('N','V','1','2'), LSB, 12, 420), + DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12, 420), + DEF_YUV(I420, ('I','4','2','0'), LSB, 12, 420), + DEF_YUV(YUY2, ('Y','U','Y','2'), LSB, 16, 422), + DEF_YUV(UYVY, ('U','Y','V','Y'), LSB, 16, 422), + DEF_YUV(AYUV, ('A','Y','U','V'), LSB, 32, 444), #if G_BYTE_ORDER == G_BIG_ENDIAN DEF_RGB(ARGB, ('A','R','G','B'), MSB, 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), @@ -85,7 +90,7 @@ static const GstVideoFormatMap gst_video_formats[] = { DEF_RGB(RGBx, ('R','G','B','X'), LSB, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), #endif - DEF_YUV(GRAY8, ('Y','8','0','0'), LSB, 8), + DEF_YUV(GRAY8, ('Y','8','0','0'), LSB, 8, 400), { 0, } }; @@ -310,6 +315,24 @@ gst_video_format_to_va_format(GstVideoFormat format) return m ? &m->va_format : NULL; } +/** + * gst_video_format_get_chroma_type: + * @format: a #GstVideoFormat + * + * Converts a #GstVideoFormat into the corresponding #GstVaapiChromaType + * format. + * + * Return value: the #GstVaapiChromaType format, or zero if no match + * was found. + */ +guint +gst_video_format_get_chroma_type(GstVideoFormat format) +{ + const GstVideoFormatMap * const m = get_map(format); + + return m ? m->chroma_type : 0; +} + /** * gst_video_format_get_score: * @format: a #GstVideoFormat diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index 5ba395023d..a1dc9f693d 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -49,6 +49,9 @@ gst_video_format_from_va_format(const VAImageFormat *va_format); const VAImageFormat * gst_video_format_to_va_format(GstVideoFormat format); +guint +gst_video_format_get_chroma_type(GstVideoFormat format); + guint gst_video_format_get_score(GstVideoFormat format); From a1b27c920b6c03d7770ece1ab6ec77a31a95559f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Jul 2013 19:08:37 +0200 Subject: [PATCH 1252/3781] surface: allow creation with explicit pixel format. Make it possible to create VA surfaces with a specific pixel format. This is a new capability brought in by VA-API >= 0.34.0. If that capability is not built-in (e.g. using VA-API < 0.34.0), then gst_vaapi_surface_new_with_format() will return NULL. --- docs/reference/libs/libs-sections.txt | 2 + gst-libs/gst/vaapi/gstvaapisurface.c | 117 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 15 ++- gst-libs/gst/vaapi/gstvaapisurface_priv.h | 13 +++ 4 files changed, 144 insertions(+), 3 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index bd0229c30f..827067cac3 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -209,8 +209,10 @@ GstVaapiSurfaceRenderFlags GstVaapiSurface GstVaapiSurface gst_vaapi_surface_new +gst_vaapi_surface_new_with_format gst_vaapi_surface_get_id gst_vaapi_surface_get_chroma_type +gst_vaapi_surface_get_format gst_vaapi_surface_get_width gst_vaapi_surface_get_height gst_vaapi_surface_get_size diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 9cd129d0dd..17535164bb 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -118,6 +118,7 @@ gst_vaapi_surface_create(GstVaapiSurface *surface, if (!vaapi_check_status(status, "vaCreateSurfaces()")) return FALSE; + surface->format = GST_VIDEO_FORMAT_ENCODED; surface->chroma_type = chroma_type; surface->width = width; surface->height = height; @@ -132,6 +133,64 @@ error_unsupported_chroma_type: return FALSE; } +static gboolean +gst_vaapi_surface_create_with_format(GstVaapiSurface *surface, + GstVideoFormat format, guint width, guint height) +{ +#if VA_CHECK_VERSION(0,34,0) + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface); + VASurfaceID surface_id; + VAStatus status; + guint chroma_type, va_chroma_format; + const VAImageFormat *va_format; + VASurfaceAttrib attrib; + + va_format = gst_video_format_to_va_format(format); + if (!va_format) + goto error_unsupported_format; + + chroma_type = gst_video_format_get_chroma_type(format); + if (!chroma_type) + goto error_unsupported_format; + + va_chroma_format = from_GstVaapiChromaType(chroma_type); + if (!va_chroma_format) + goto error_unsupported_format; + + attrib.flags = VA_SURFACE_ATTRIB_SETTABLE; + attrib.type = VASurfaceAttribPixelFormat; + attrib.value.type = VAGenericValueTypeInteger; + attrib.value.value.i = va_format->fourcc; + + GST_VAAPI_DISPLAY_LOCK(display); + status = vaCreateSurfaces( + GST_VAAPI_DISPLAY_VADISPLAY(display), + va_chroma_format, width, height, + &surface_id, 1, + &attrib, 1 + ); + GST_VAAPI_DISPLAY_UNLOCK(display); + if (!vaapi_check_status(status, "vaCreateSurfaces()")) + return FALSE; + + surface->format = format; + surface->chroma_type = chroma_type; + surface->width = width; + surface->height = height; + + GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); + GST_VAAPI_OBJECT_ID(surface) = surface_id; + return TRUE; + + /* ERRORS */ +error_unsupported_format: + GST_ERROR("unsupported format %u", gst_video_format_to_string(format)); + return FALSE; +#else + return FALSE; +#endif +} + #define gst_vaapi_surface_finalize gst_vaapi_surface_destroy GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiSurface, gst_vaapi_surface) @@ -172,6 +231,46 @@ error: return NULL; } +/** + * gst_vaapi_surface_new_with_format: + * @display: a #GstVaapiDisplay + * @format: the surface format + * @width: the requested surface width + * @height: the requested surface height + * + * Creates a new #GstVaapiSurface with the specified pixel format and + * dimensions. + * + * Return value: the newly allocated #GstVaapiSurface object, or %NULL + * if creation of VA surface with explicit pixel format is not + * supported or failed. + */ +GstVaapiSurface * +gst_vaapi_surface_new_with_format( + GstVaapiDisplay *display, + GstVideoFormat format, + guint width, + guint height +) +{ + GstVaapiSurface *surface; + + GST_DEBUG("size %ux%u, format %s", width, height, + gst_video_format_to_string(format)); + + surface = gst_vaapi_object_new(gst_vaapi_surface_class(), display); + if (!surface) + return NULL; + + if (!gst_vaapi_surface_create_with_format(surface, format, width, height)) + goto error; + return surface; + +error: + gst_vaapi_object_unref(surface); + return NULL; +} + /** * gst_vaapi_surface_get_id: * @surface: a #GstVaapiSurface @@ -204,6 +303,24 @@ gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface) return GST_VAAPI_SURFACE_CHROMA_TYPE(surface); } +/** + * gst_vaapi_surface_get_format: + * @surface: a #GstVaapiSurface + * + * Returns the #GstVideoFormat the @surface was created with. + * + * Return value: the #GstVideoFormat, or %GST_VIDEO_FORMAT_ENCODED if + * the surface was not created with an explicit video format, or if + * the underlying video format could not be determined + */ +GstVideoFormat +gst_vaapi_surface_get_format(GstVaapiSurface *surface) +{ + g_return_val_if_fail(surface != NULL, 0); + + return GST_VAAPI_SURFACE_FORMAT(surface); +} + /** * gst_vaapi_surface_get_width: * @surface: a #GstVaapiSurface diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index e6ceaccaca..13dbf4f925 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -27,6 +27,7 @@ #include #include #include +#include #include G_BEGIN_DECLS @@ -53,9 +54,6 @@ G_BEGIN_DECLS /** * GstVaapiChromaType: - * @GST_VAAPI_CHROMA_TYPE_YUV420: 4:2:0 chroma format - * @GST_VAAPI_CHROMA_TYPE_YUV422: 4:2:2 chroma format - * @GST_VAAPI_CHROMA_TYPE_YUV444: 4:4:4 chroma format * @GST_VAAPI_CHROMA_TYPE_YUV420: YUV 4:2:0 chroma format * @GST_VAAPI_CHROMA_TYPE_YUV422: YUV 4:2:2 chroma format * @GST_VAAPI_CHROMA_TYPE_YUV444: YUV 4:4:4 chroma format @@ -139,12 +137,23 @@ gst_vaapi_surface_new( guint height ); +GstVaapiSurface * +gst_vaapi_surface_new_with_format( + GstVaapiDisplay *display, + GstVideoFormat format, + guint width, + guint height +); + GstVaapiID gst_vaapi_surface_get_id(GstVaapiSurface *surface); GstVaapiChromaType gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface); +GstVideoFormat +gst_vaapi_surface_get_format(GstVaapiSurface *surface); + guint gst_vaapi_surface_get_width(GstVaapiSurface *surface); diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index f7d04b8c36..2114d721c1 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -37,6 +37,7 @@ struct _GstVaapiSurface { /*< private >*/ GstVaapiObject parent_instance; + GstVideoFormat format; guint width; guint height; GstVaapiChromaType chroma_type; @@ -66,6 +67,18 @@ struct _GstVaapiSurfaceClass { #define GST_VAAPI_SURFACE_CHROMA_TYPE(surface) \ GST_VAAPI_SURFACE(surface)->chroma_type +/** + * GST_VAAPI_SURFACE_SURFACE_FORMAT: + * @surface: a #GstVaapiSurface + * + * Macro that evaluates to the @surface format. + * + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_SURFACE_FORMAT +#define GST_VAAPI_SURFACE_FORMAT(surface) \ + GST_VAAPI_SURFACE(surface)->format + /** * GST_VAAPI_SURFACE_SURFACE_WIDTH: * @surface: a #GstVaapiSurface From 8663ad9492513f8b7715373b8bdd42670950af23 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Jul 2013 13:58:55 +0200 Subject: [PATCH 1253/3781] surface: try to determine the underlying VA surface format. If a VA surface was allocated with the chroma-format interface, try to determine the underlying pixel format on gst_vaapi_surface_get_format(), or return GST_VIDEO_FORMAT_ENCODED if this is not a supported operation. --- gst-libs/gst/vaapi/gstvaapisurface.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 17535164bb..0ffbc9ea21 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -118,7 +118,7 @@ gst_vaapi_surface_create(GstVaapiSurface *surface, if (!vaapi_check_status(status, "vaCreateSurfaces()")) return FALSE; - surface->format = GST_VIDEO_FORMAT_ENCODED; + surface->format = GST_VIDEO_FORMAT_UNKNOWN; surface->chroma_type = chroma_type; surface->width = width; surface->height = height; @@ -318,6 +318,16 @@ gst_vaapi_surface_get_format(GstVaapiSurface *surface) { g_return_val_if_fail(surface != NULL, 0); + /* Try to determine the underlying VA surface format */ + if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) { + GstVaapiImage * const image = gst_vaapi_surface_derive_image(surface); + if (image) { + surface->format = gst_vaapi_image_get_format(image); + gst_vaapi_object_unref(image); + } + if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) + surface->format = GST_VIDEO_FORMAT_ENCODED; + } return GST_VAAPI_SURFACE_FORMAT(surface); } From 1c9ebecb77027b7012e87330552c2214e54e0bad Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Jul 2013 14:20:30 +0200 Subject: [PATCH 1254/3781] surface: fix surface pool creation with an explicit pixel format. Fix creation of surface pool objects to honour explicit pixel format specification. If this operation is not supported, then fallback to the older interface with chroma format. --- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 26 +++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 7f691540bb..a5dbbe0f5f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -42,6 +42,7 @@ struct _GstVaapiSurfacePool { GstVaapiVideoPool parent_instance; GstVaapiChromaType chroma_type; + GstVideoFormat format; guint width; guint height; }; @@ -49,9 +50,19 @@ struct _GstVaapiSurfacePool { static gboolean surface_pool_init(GstVaapiSurfacePool *pool, const GstVideoInfo *vip) { - pool->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - pool->width = GST_VIDEO_INFO_WIDTH(vip); - pool->height = GST_VIDEO_INFO_HEIGHT(vip); + pool->format = GST_VIDEO_INFO_FORMAT(vip); + pool->width = GST_VIDEO_INFO_WIDTH(vip); + pool->height = GST_VIDEO_INFO_HEIGHT(vip); + + if (pool->format == GST_VIDEO_FORMAT_UNKNOWN) + return FALSE; + + if (pool->format == GST_VIDEO_FORMAT_ENCODED) + pool->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + else + pool->chroma_type = gst_video_format_get_chroma_type(pool->format); + if (!pool->chroma_type) + return FALSE; return TRUE; } @@ -60,6 +71,15 @@ gst_vaapi_surface_pool_alloc_object(GstVaapiVideoPool *base_pool) { GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(base_pool); + /* Try to allocate a surface with an explicit pixel format first */ + if (pool->format != GST_VIDEO_FORMAT_ENCODED) { + GstVaapiSurface * const surface = gst_vaapi_surface_new_with_format( + base_pool->display, pool->format, pool->width, pool->height); + if (surface) + return surface; + } + + /* Otherwise, fallback to the original interface, based on chroma format */ return gst_vaapi_surface_new(base_pool->display, pool->chroma_type, pool->width, pool->height); } From 1cfe03ee525da98c168c8bca58ceb67a11c26f19 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Jul 2013 10:34:24 +0200 Subject: [PATCH 1255/3781] plugins: allow creation of VA surfaces with explicit pixel format. Adapt GstVaapiVideoMemory allocator to support creation of VA surfaces with an explicit pixel format. This allows for direct rendering to VA surface memory from a software decoder. --- gst/vaapi/gstvaapivideomemory.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 31cf259fd5..5409068178 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -67,9 +67,18 @@ ensure_image(GstVaapiVideoMemory *mem) static GstVaapiSurface * new_surface(GstVaapiDisplay *display, const GstVideoInfo *vip) { + GstVaapiSurface *surface; + + /* Try with explicit format first */ + surface = gst_vaapi_surface_new_with_format(display, + GST_VIDEO_INFO_FORMAT(vip), GST_VIDEO_INFO_WIDTH(vip), + GST_VIDEO_INFO_HEIGHT(vip)); + if (surface) + return surface; + + /* Try to pick something compatible. Best bet: NV12 (YUV 4:2:0) */ if (GST_VIDEO_INFO_FORMAT(vip) != GST_VIDEO_FORMAT_NV12) return NULL; - return gst_vaapi_surface_new(display, GST_VAAPI_CHROMA_TYPE_YUV420, GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); } @@ -383,8 +392,14 @@ gst_vaapi_video_allocator_init(GstVaapiVideoAllocator *allocator) static gboolean gst_video_info_update_from_image(GstVideoInfo *vip, GstVaapiImage *image) { + GstVideoFormat format; const guchar *data; - guint i, num_planes, data_size; + guint i, num_planes, data_size, width, height; + + /* Reset format from image */ + format = gst_vaapi_image_get_format(image); + gst_vaapi_image_get_size(image, &width, &height); + gst_video_info_set_format(vip, format, width, height); num_planes = gst_vaapi_image_get_plane_count(image); g_return_val_if_fail(num_planes == GST_VIDEO_INFO_N_PLANES(vip), FALSE); From 419af5000901b81d5ea9b7420c82fdf2a286a003 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Jul 2013 15:03:43 +0200 Subject: [PATCH 1256/3781] plugins: use GstVideoInfo in video uploader helper. --- gst/vaapi/gstvaapiuploader.c | 79 +++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index dc3a0dce64..e26d0790ca 100755 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -50,13 +50,10 @@ struct _GstVaapiUploaderPrivate { GstVaapiDisplay *display; GstCaps *allowed_caps; GstVaapiVideoPool *images; + GstVideoInfo image_info; GstCaps *image_caps; - GstVideoFormat image_format; - guint image_width; - guint image_height; GstVaapiVideoPool *surfaces; - guint surface_width; - guint surface_height; + GstVideoInfo surface_info; guint direct_rendering; }; @@ -168,9 +165,11 @@ end: } static gboolean -ensure_image_pool(GstVaapiUploader *uploader, GstCaps *caps) +ensure_image_pool(GstVaapiUploader *uploader, GstCaps *caps, + gboolean *caps_changed_ptr) { GstVaapiUploaderPrivate * const priv = uploader->priv; + GstVaapiVideoPool *pool; GstVideoInfo vi; GstVideoFormat format; guint width, height; @@ -182,42 +181,55 @@ ensure_image_pool(GstVaapiUploader *uploader, GstCaps *caps) width = GST_VIDEO_INFO_WIDTH(&vi); height = GST_VIDEO_INFO_HEIGHT(&vi); - if (format != priv->image_format || - width != priv->image_width || - height != priv->image_height) { - priv->image_format = format; - priv->image_width = width; - priv->image_height = height; - gst_vaapi_video_pool_replace(&priv->images, NULL); - priv->images = gst_vaapi_image_pool_new(priv->display, &vi); - if (!priv->images) - return FALSE; - gst_caps_replace(&priv->image_caps, caps); - } + *caps_changed_ptr = + format != GST_VIDEO_INFO_FORMAT(&priv->image_info) || + width != GST_VIDEO_INFO_WIDTH(&priv->image_info) || + height != GST_VIDEO_INFO_HEIGHT(&priv->image_info); + if (!*caps_changed_ptr) + return TRUE; + + pool = gst_vaapi_image_pool_new(priv->display, &vi); + if (!pool) + return FALSE; + + gst_video_info_set_format(&priv->image_info, format, width, height); + gst_caps_replace(&priv->image_caps, caps); + gst_vaapi_video_pool_replace(&priv->images, pool); + gst_vaapi_video_pool_unref(pool); return TRUE; } static gboolean -ensure_surface_pool(GstVaapiUploader *uploader, GstCaps *caps) +ensure_surface_pool(GstVaapiUploader *uploader, GstCaps *caps, + gboolean *caps_changed_ptr) { GstVaapiUploaderPrivate * const priv = uploader->priv; + GstVaapiVideoPool *pool; GstVideoInfo vi; + GstVideoFormat format; guint width, height; if (!gst_video_info_from_caps(&vi, caps)) return FALSE; + format = GST_VIDEO_INFO_FORMAT(&vi); width = GST_VIDEO_INFO_WIDTH(&vi); height = GST_VIDEO_INFO_HEIGHT(&vi); - if (width != priv->surface_width || height != priv->surface_height) { - priv->surface_width = width; - priv->surface_height = height; - gst_vaapi_video_pool_replace(&priv->surfaces, NULL); - priv->surfaces = gst_vaapi_surface_pool_new(priv->display, &vi); - if (!priv->surfaces) - return FALSE; - } + *caps_changed_ptr = + format != GST_VIDEO_INFO_FORMAT(&priv->surface_info) || + width != GST_VIDEO_INFO_WIDTH(&priv->surface_info) || + height != GST_VIDEO_INFO_HEIGHT(&priv->surface_info); + if (!*caps_changed_ptr) + return TRUE; + + pool = gst_vaapi_surface_pool_new(priv->display, &vi); + if (!pool) + return FALSE; + + gst_video_info_set_format(&priv->surface_info, format, width, height); + gst_vaapi_video_pool_replace(&priv->surfaces, pool); + gst_vaapi_video_pool_unref(pool); return TRUE; } @@ -292,6 +304,9 @@ gst_vaapi_uploader_init(GstVaapiUploader *uploader) priv = GST_VAAPI_UPLOADER_GET_PRIVATE(uploader); uploader->priv = priv; + + gst_video_info_init(&priv->image_info); + gst_video_info_init(&priv->surface_info); } GstVaapiUploader * @@ -323,14 +338,20 @@ gst_vaapi_uploader_ensure_caps( GstVaapiImage *image; GstVideoFormat format; GstVideoInfo vi; + gboolean image_caps_changed, surface_caps_changed; g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); g_return_val_if_fail(src_caps != NULL, FALSE); - if (!ensure_image_pool(uploader, src_caps)) + if (!out_caps) + out_caps = src_caps; + + if (!ensure_image_pool(uploader, src_caps, &image_caps_changed)) return FALSE; - if (!ensure_surface_pool(uploader, out_caps ? out_caps : src_caps)) + if (!ensure_surface_pool(uploader, out_caps, &surface_caps_changed)) return FALSE; + if (!image_caps_changed && !surface_caps_changed) + return TRUE; priv = uploader->priv; priv->direct_rendering = 0; From ed1bec1e43c16b6fbae8ad495e0a3d0bec4aa687 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Jul 2013 15:15:11 +0200 Subject: [PATCH 1257/3781] plugins: clean-up video uploader helper. Fix gst_vaapi_uploader_get_buffer() to not assign caps since they were already negotiated beforehand, and they are not used from the buffer in upstream elements. Clean-up gst_vaapi_uploader_ensure_caps() to use the new image caps represented as a GstVideoInfo. --- gst/vaapi/gstvaapiuploader.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index e26d0790ca..ca7f675c5e 100755 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -51,7 +51,6 @@ struct _GstVaapiUploaderPrivate { GstCaps *allowed_caps; GstVaapiVideoPool *images; GstVideoInfo image_info; - GstCaps *image_caps; GstVaapiVideoPool *surfaces; GstVideoInfo surface_info; guint direct_rendering; @@ -68,9 +67,7 @@ gst_vaapi_uploader_destroy(GstVaapiUploader *uploader) { GstVaapiUploaderPrivate * const priv = uploader->priv; - gst_caps_replace(&priv->image_caps, NULL); gst_caps_replace(&priv->allowed_caps, NULL); - gst_vaapi_video_pool_replace(&priv->images, NULL); gst_vaapi_video_pool_replace(&priv->surfaces, NULL); gst_vaapi_display_replace(&priv->display, NULL); @@ -193,7 +190,6 @@ ensure_image_pool(GstVaapiUploader *uploader, GstCaps *caps, return FALSE; gst_video_info_set_format(&priv->image_info, format, width, height); - gst_caps_replace(&priv->image_caps, caps); gst_vaapi_video_pool_replace(&priv->images, pool); gst_vaapi_video_pool_unref(pool); return TRUE; @@ -336,8 +332,6 @@ gst_vaapi_uploader_ensure_caps( { GstVaapiUploaderPrivate *priv; GstVaapiImage *image; - GstVideoFormat format; - GstVideoInfo vi; gboolean image_caps_changed, surface_caps_changed; g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); @@ -356,22 +350,19 @@ gst_vaapi_uploader_ensure_caps( priv = uploader->priv; priv->direct_rendering = 0; - /* Strip out non-YUV formats */ - if (!gst_video_info_from_caps(&vi, src_caps)) - return FALSE; - if (!GST_VIDEO_INFO_IS_YUV(&vi)) - return FALSE; - format = GST_VIDEO_INFO_FORMAT(&vi); - /* Check if we can alias source and output buffers (same data_size) */ image = gst_vaapi_video_pool_get_object(priv->images); if (image) { - if (gst_vaapi_image_get_format(image) == format && + if ((gst_vaapi_image_get_format(image) == + GST_VIDEO_INFO_FORMAT(&priv->image_info)) && gst_vaapi_image_is_linear(image) && - gst_vaapi_image_get_data_size(image) == GST_VIDEO_INFO_SIZE(&vi)) + (gst_vaapi_image_get_data_size(image) == + GST_VIDEO_INFO_SIZE(&priv->image_info))) priv->direct_rendering = 1; gst_vaapi_video_pool_put_object(priv->images, image); } + + GST_INFO("direct-rendering: level %u", priv->direct_rendering); return TRUE; } @@ -472,8 +463,6 @@ gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) #if !GST_CHECK_VERSION(1,0,0) GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0); GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image); - - gst_buffer_set_caps(buffer, priv->image_caps); #endif return buffer; From 89321cd3c42b6bec568dc59189d096b3624669bf Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Wed, 24 Apr 2013 10:39:03 +0800 Subject: [PATCH 1258/3781] image: add support for raw YUY2/UYVY image copies. Implement raw image copies for YUY2 format. Add support for UYVY format too, with the same copy function as for YUY2. Even though components ordering differs, copying line strides is essentially the same. https://bugzilla.gnome.org/show_bug.cgi?id=703939 https://bugzilla.gnome.org/show_bug.cgi?id=703940 Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiimage.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index bb46866f50..9c39ee5ded 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -869,6 +869,25 @@ copy_image_YV12( } } +/* Copy YUY2 images */ +static void +copy_image_YUY2( + GstVaapiImageRaw *dst_image, + GstVaapiImageRaw *src_image, + const GstVaapiRectangle *rect +) +{ + guchar *dst, *src; + guint dst_stride, src_stride; + + /* YUV 4:2:2, full vertical resolution */ + dst_stride = dst_image->stride[0]; + dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x * 2; + src_stride = src_image->stride[0]; + src = src_image->pixels[0] + rect->y * src_stride + rect->x * 2; + memcpy_pic(dst, dst_stride, src, src_stride, rect->width * 2, rect->height); +} + /* Copy RGBA images */ static void copy_image_RGBA( @@ -924,6 +943,10 @@ copy_image( case GST_VIDEO_FORMAT_I420: copy_image_YV12(dst_image, src_image, rect); break; + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_UYVY: + copy_image_YUY2(dst_image, src_image, rect); + break; case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_RGBA: case GST_VIDEO_FORMAT_ABGR: From 4668e59bf6dc67797188b851b91d567d857e6441 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 11 Jul 2013 18:26:37 +0200 Subject: [PATCH 1259/3781] vaapidownload: fix debug string for image formats. The image is now expressed as a standard GstVideoFormat, which is not a FOURCC but rather a regular enum value. This is a regression introduced in commit 09397fa. --- gst/vaapi/gstvaapidownload.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 133615efab..1f84a534a3 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -336,8 +336,8 @@ gst_vaapidownload_update_src_caps(GstVaapiDownload *download, GstBuffer *buffer) out_caps = gst_video_format_to_caps(format); if (!out_caps) { - GST_WARNING("failed to create caps from format %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS(format)); + GST_WARNING("failed to create caps from format %s", + gst_video_format_to_string(format)); return FALSE; } @@ -397,9 +397,9 @@ gst_vaapidownload_transform( error_get_image: { - GST_WARNING("failed to download %" GST_FOURCC_FORMAT " image " - "from surface 0x%08x", - GST_FOURCC_ARGS(gst_vaapi_image_get_format(image)), + const GstVideoFormat format = gst_vaapi_image_get_format(image); + GST_WARNING("failed to download %s image from surface 0x%08x", + gst_video_format_to_string(format), gst_vaapi_surface_get_id(surface)); gst_vaapi_video_pool_put_object(download->images, image); return GST_FLOW_UNEXPECTED; From 9b3ad4daadab935f09cf632e0576868bf921ec43 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Wed, 13 Mar 2013 17:44:52 +0800 Subject: [PATCH 1260/3781] vaapidownload: fix src caps format error. This fixes direct linking of vaapidownload element to xvimagesink with VA drivers supporting vaGetImage() from the native VA surface format to a different VA image format. i.e. color conversion during download. http://bugzilla.gnome.org/show_bug.cgi?id=703937 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidownload.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 1f84a534a3..18ec0540aa 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -334,10 +334,10 @@ gst_vaapidownload_update_src_caps(GstVaapiDownload *download, GstBuffer *buffer) return FALSE; } - out_caps = gst_video_format_to_caps(format); + out_caps = gst_video_format_to_caps(download->image_format); if (!out_caps) { GST_WARNING("failed to create caps from format %s", - gst_video_format_to_string(format)); + gst_video_format_to_string(download->image_format)); return FALSE; } From ac757551050ea328b42ea701c4328ecbd7d279c6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 12 Jul 2013 15:01:01 +0200 Subject: [PATCH 1261/3781] pool: fix deallocation of video pools. The queue of free objects to used was deallocated with g_queue_free_full(). However, this convenience function shall only be used if the original queue was allocated with g_queue_new(). This caused memory corruption, eventually leading to a crash. The correct solution is to pair the g_queue_init() with the corresponding g_queue_clear(), while iterating over all free objects to deallocate them. --- gst-libs/gst/vaapi/gstvaapivideopool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 23912e6198..4dc523b6c5 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -70,7 +70,8 @@ void gst_vaapi_video_pool_finalize(GstVaapiVideoPool *pool) { g_list_free_full(pool->used_objects, gst_vaapi_object_unref); - g_queue_free_full(&pool->free_objects, gst_vaapi_object_unref); + g_queue_foreach(&pool->free_objects, (GFunc)gst_vaapi_object_unref, NULL); + g_queue_clear(&pool->free_objects); gst_vaapi_display_replace(&pool->display, NULL); } From d79d561819277cc24818a3106080258d32755c89 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 12 Jul 2013 15:15:07 +0200 Subject: [PATCH 1262/3781] vaapiupload: use implicit color conversion to NV12. Always perform conversion of sources buffers to NV12 since this is the way we tested for this capability in ensure_allowed_caps(). This also saves memory bandwidth for further rendering. However, this may not preserve quality since the YUV buffers are down-sampled to 4:2:0. --- gst/vaapi/gstvaapiuploader.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index ca7f675c5e..234674b9c9 100755 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -219,6 +219,21 @@ ensure_surface_pool(GstVaapiUploader *uploader, GstCaps *caps, if (!*caps_changed_ptr) return TRUE; + /* Always try to downsample source buffers to YUV 4:2:0 format as + this saves memory bandwidth for further rendering */ + /* XXX: this also means that visual quality is not preserved */ + if (format != GST_VIDEO_FORMAT_ENCODED) { + const GstVaapiChromaType chroma_type = + gst_video_format_get_chroma_type(format); + if (chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) { + const GstVideoFormat image_format = + GST_VIDEO_INFO_FORMAT(&priv->image_info); + GST_INFO("use implicit conversion of %s buffers to NV12 surfaces", + gst_video_format_to_string(image_format)); + gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12, width, height); + } + } + pool = gst_vaapi_surface_pool_new(priv->display, &vi); if (!pool) return FALSE; From c82a1bc0ff4339a150cf4e8f8075d51ba49c50f8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 12 Jul 2013 17:14:49 +0200 Subject: [PATCH 1263/3781] plugins: fix ref counting of GstVaapiVideoMemory allocator. Fix reference counting issue whereby gst_memory_init() does not hold an extra reference to the GstAllocator. So, there could be situations where the last instance of GstVaapiVideoAllocator gets released before a dangling GstVaapiVideoMemory object, thus possibly leading to a crash. --- gst/vaapi/gstvaapivideomemory.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 5409068178..29bc2a9bba 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -218,7 +218,7 @@ gst_vaapi_video_memory_new(GstAllocator *base_allocator, return NULL; vip = &allocator->image_info; - gst_memory_init(&mem->parent_instance, 0, base_allocator, NULL, + gst_memory_init(&mem->parent_instance, 0, gst_object_ref(allocator), NULL, GST_VIDEO_INFO_SIZE(vip), 0, 0, GST_VIDEO_INFO_SIZE(vip)); mem->proxy = NULL; @@ -239,6 +239,7 @@ gst_vaapi_video_memory_free(GstVaapiVideoMemory *mem) gst_vaapi_object_replace(&mem->surface, NULL); gst_vaapi_object_replace(&mem->image, NULL); gst_vaapi_video_meta_unref(mem->meta); + gst_object_unref(GST_MEMORY_CAST(mem)->allocator); g_slice_free(GstVaapiVideoMemory, mem); } From 5e18a5b1bd187c9e59a6356611557903abb91bb5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 12 Jul 2013 17:47:07 +0200 Subject: [PATCH 1264/3781] plugins: don't reallocate pool allocator for the same caps. If the video buffer pool config doesn't have new caps, then it's not necessary to reinstantiate the allocator. That could be a costly operation as we could do some extra heavy checking in there. --- gst/vaapi/gstvaapivideobufferpool.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 5c84ab1b43..fdcc360eb1 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -38,6 +38,7 @@ enum { }; struct _GstVaapiVideoBufferPoolPrivate { + GstCaps *caps; GstAllocator *allocator; GstVaapiDisplay *display; guint has_video_meta : 1; @@ -58,6 +59,7 @@ gst_vaapi_video_buffer_pool_finalize(GObject *object) gst_vaapi_display_replace(&priv->display, NULL); g_clear_object(&priv->allocator); + gst_caps_replace(&priv->caps, NULL); } static void @@ -118,10 +120,13 @@ gst_vaapi_video_buffer_pool_set_config(GstBufferPool *pool, if (!caps) goto error_no_caps; - g_clear_object(&priv->allocator); - priv->allocator = gst_vaapi_video_allocator_new(priv->display, caps); - if (!priv->allocator) - goto error_create_allocator; + if (!priv->caps || !gst_caps_is_equal(priv->caps, caps)) { + g_clear_object(&priv->allocator); + priv->allocator = gst_vaapi_video_allocator_new(priv->display, caps); + if (!priv->allocator) + goto error_create_allocator; + gst_caps_replace(&priv->caps, caps); + } if (!gst_buffer_pool_config_has_option(config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) From 3d290a162cde580c49609bffb0e177922c08b3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 24 May 2013 05:04:01 -0400 Subject: [PATCH 1265/3781] plugins: add gst_vaapi_create_display() helper. https://bugzilla.gnome.org/show_bug.cgi?id=703235 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipluginutil.c | 49 ++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index fe7b2b7656..86d28eecc1 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -86,6 +86,34 @@ static const DisplayMap g_display_map[] = { { NULL, } }; +static GstVaapiDisplay * +gst_vaapi_create_display(GstVaapiDisplayType *display_type) +{ + GstVaapiDisplay *display = NULL; + const DisplayMap *m; + + for (m = g_display_map; m->type_str != NULL; m++) { + if (*display_type != GST_VAAPI_DISPLAY_TYPE_ANY && + *display_type != m->type) + continue; + + display = m->create_display(NULL); + if (display) { + /* FIXME: allocator should return NULL if an error occurred */ + if (gst_vaapi_display_get_display(display)) { + *display_type = m->type; + break; + } + gst_vaapi_display_unref(display); + display = NULL; + } + + if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY) + break; + } + return display; +} + gboolean gst_vaapi_ensure_display( gpointer element, @@ -95,7 +123,6 @@ gst_vaapi_ensure_display( { GstVaapiDisplay *display; GstVideoContext *context; - const DisplayMap *m; g_return_val_if_fail(GST_IS_VIDEO_CONTEXT(element), FALSE); g_return_val_if_fail(display_ptr != NULL, FALSE); @@ -115,25 +142,7 @@ gst_vaapi_ensure_display( return TRUE; /* If no neighboor, or application not interested, use system default */ - for (m = g_display_map; m->type_str != NULL; m++) { - if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY && - display_type != m->type) - continue; - - display = m->create_display(NULL); - if (display) { - /* FIXME: allocator should return NULL if an error occurred */ - if (gst_vaapi_display_get_display(display)) { - display_type = m->type; - break; - } - gst_vaapi_display_unref(display); - display = NULL; - } - - if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY) - break; - } + display = gst_vaapi_create_display(&display_type); if (display_ptr) *display_ptr = display; From cee9101dd8932fdfc426c51d28ccd17db97cc045 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Jul 2013 11:58:31 +0200 Subject: [PATCH 1266/3781] plugins: simlpify gst_vaapi_create_display() helper. Simplify gst_vaapi_create_display() helper as gst_vaapi_display_XXX_new() performs the necessary validation checks for the underlying VA display prior to returning to the caller. So, if an error occurred, then NULL is really returned in that case. --- gst/vaapi/gstvaapipluginutil.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 86d28eecc1..a1dbad86e1 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -99,13 +99,8 @@ gst_vaapi_create_display(GstVaapiDisplayType *display_type) display = m->create_display(NULL); if (display) { - /* FIXME: allocator should return NULL if an error occurred */ - if (gst_vaapi_display_get_display(display)) { - *display_type = m->type; - break; - } - gst_vaapi_display_unref(display); - display = NULL; + *display_type = m->type; + break; } if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY) From 1fff3a44dde33a3d817a47a72cf7bb1ecb9c3bf7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 11 Jun 2013 15:11:34 +0200 Subject: [PATCH 1267/3781] decoder: fix memory leak when processing interlaced pictures. Fix memory leak when processing interlaced pictures and that occurs because the first field, represented as a GstVideoCodecFrame, never gets released. i.e. when the picture is completed, this is generally the case when the second field is successfully decoded, we need to propagate the GstVideoCodecFrame of the first field to the original GstVideoDecoder so that it could reclaim memory. Otherwise, we keep accumulating the first fields into GstVideoDecoder private frames list until the end-of-stream is reached. The frames are eventually released there, but too late, i.e. too much memory may have been consumed. https://bugzilla.gnome.org/show_bug.cgi?id=701257 --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 34 ++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 1 + 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 92f0f7bbd9..4b52134985 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -86,6 +86,7 @@ gst_vaapi_picture_destroy(GstVaapiPicture *picture) gst_video_codec_frame_unref(picture->frame); picture->frame = NULL; } + gst_vaapi_picture_replace(&picture->parent_picture, NULL); } gboolean @@ -99,6 +100,8 @@ gst_vaapi_picture_create( 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; @@ -300,14 +303,15 @@ gst_vaapi_picture_decode(GstVaapiPicture *picture) return TRUE; } -gboolean -gst_vaapi_picture_output(GstVaapiPicture *picture) +static gboolean +do_output(GstVaapiPicture *picture) { GstVideoCodecFrame * const out_frame = picture->frame; GstVaapiSurfaceProxy *proxy; guint flags = 0; - g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE); + if (GST_VAAPI_PICTURE_IS_OUTPUT(picture)) + return TRUE; if (!picture->proxy) return FALSE; @@ -339,6 +343,30 @@ gst_vaapi_picture_output(GstVaapiPicture *picture) 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; + 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) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 9bc2436cf7..90e8f04258 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -114,6 +114,7 @@ typedef enum { struct _GstVaapiPicture { /*< private >*/ GstVaapiCodecObject parent_instance; + GstVaapiPicture *parent_picture; GstVideoCodecFrame *frame; GstVaapiSurface *surface; GstVaapiSurfaceProxy *proxy; From 20db4f2ad9bc972bf59fe75df49cd7b9dd659929 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Jul 2013 13:44:43 +0200 Subject: [PATCH 1268/3781] NEWS: updates. --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 62b0e5d78e..b0358fb921 100644 --- a/NEWS +++ b/NEWS @@ -4,11 +4,15 @@ Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora Version 0.5.5 - DD.Jul.2013 +* Allow creation of video surfaces with an explicit pixel format * Allocate VA/GLX capable buffers by default on X11 servers (Victor Jaquez) * Add support for video cropping in MPEG-2, VC-1 and H.264 codecs (+Sreerenj) +* Fix memory leak when processing interlaced pictures * Fix creation of VA/GLX textures when video cropping is used * Fix raw image copies in vaapidownload / vaapiupload (Feng Yuan) * Fix MPEG-2 quantization matrices reset on new sequence headers (Cong Zhong) +* Fix direct linking of vaapidownload element to xvimagesink (Feng Yuan) +* Fix memory corruption in video pool implementation, e.g. for clutter-gst Version 0.5.4 - 14.Jun.2013 * Streamline core libgstvaapi decoding library (API/ABI changes) From abd432d7b1b49001ba35e4f082df924fe74b528d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Jul 2013 14:05:45 +0200 Subject: [PATCH 1269/3781] Bump library major version. Bump the library major version due to API/ABI changes that occurred in the imaging API. In particular, GstVaapiImageFormat type was replaced with the standard GstVideoFormat type. All dependent APIs were updated to match this change. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index da8bd43f42..2bd732ad39 100644 --- a/configure.ac +++ b/configure.ac @@ -10,7 +10,7 @@ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) ]) # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [3]) +m4_define([gst_vaapi_lt_current], [4]) m4_define([gst0_vaapi_lt_current_bias], [0]) m4_define([gst1_vaapi_lt_current_bias], [2]) m4_define([gst_vaapi_lt_revision], [0]) From 7fa4973f8ac26eade0ea02fcd9a8971b8b902593 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Jul 2013 14:42:33 +0200 Subject: [PATCH 1270/3781] Fix new video format API. Fix new internal video format API, based on GstVideoFormat, to not clobber with system symbols. So replace the gst_video_format_* prefix with gst_vaapi_video_format_ prefix, even if the format type remains GstVideoFormat. --- docs/reference/libs/libs-sections.txt | 18 ++++---- gst-libs/gst/vaapi/Makefile.am | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 20 ++++----- gst-libs/gst/vaapi/gstvaapiimage.c | 8 ++-- gst-libs/gst/vaapi/gstvaapisurface.c | 4 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 2 +- gst-libs/gst/vaapi/video-format.c | 56 +++++++++++------------- gst-libs/gst/vaapi/video-format.h | 20 ++++----- gst/vaapi/gstvaapidownload.c | 2 +- gst/vaapi/gstvaapiuploader.c | 4 +- tests/image.c | 2 +- tests/test-display.c | 6 +-- 12 files changed, 70 insertions(+), 74 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 827067cac3..5c687554d3 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -1,15 +1,15 @@
videoformat GstVideoFormat -gst_video_format_from_caps -gst_video_format_from_structure -gst_video_format_from_va_format -gst_video_format_get_chroma_type -gst_video_format_get_score -gst_video_format_is_rgb -gst_video_format_is_yuv -gst_video_format_to_caps -gst_video_format_to_va_format +gst_vaapi_video_format_from_caps +gst_vaapi_video_format_from_structure +gst_vaapi_video_format_from_va_format +gst_vaapi_video_format_get_chroma_type +gst_vaapi_video_format_get_score +gst_vaapi_video_format_is_rgb +gst_vaapi_video_format_is_yuv +gst_vaapi_video_format_to_caps +gst_vaapi_video_format_to_va_format
diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f4e771e332..a9e61d8791 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -227,7 +227,7 @@ libgstvaapi_@GST_API_VERSION@_la_LIBADD = \ libgstvaapi_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(GST_VAAPI_LT_LDFLAGS) \ - -export-symbols-regex "^gst_(.*vaapi|video_format).*" \ + -export-symbols-regex "^gst_.*vaapi.*" \ $(NULL) libgstvaapi_drm_@GST_API_VERSION@_la_SOURCES = \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index a92e304641..05833c8e7d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -199,7 +199,7 @@ append_formats(GArray *formats, const VAImageFormat *va_formats, const VAImageFormat * const va_format = &va_formats[i]; const GstVaapiFormatInfo **fipp; - format = gst_video_format_from_va_format(va_format); + format = gst_vaapi_video_format_from_va_format(va_format); if (format == GST_VIDEO_FORMAT_UNKNOWN) { GST_DEBUG("unsupported format %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(va_format->fourcc)); @@ -238,14 +238,14 @@ compare_yuv_formats(gconstpointer a, gconstpointer b) const GstVideoFormat fmt1 = ((GstVaapiFormatInfo *)a)->format; const GstVideoFormat fmt2 = ((GstVaapiFormatInfo *)b)->format; - const gboolean is_fmt1_yuv = gst_video_format_is_yuv(fmt1); - const gboolean is_fmt2_yuv = gst_video_format_is_yuv(fmt2); + const gboolean is_fmt1_yuv = gst_vaapi_video_format_is_yuv(fmt1); + const gboolean is_fmt2_yuv = gst_vaapi_video_format_is_yuv(fmt2); if (is_fmt1_yuv != is_fmt2_yuv) return is_fmt1_yuv ? -1 : 1; - return ((gint)gst_video_format_get_score(fmt1) - - (gint)gst_video_format_get_score(fmt2)); + return ((gint)gst_vaapi_video_format_get_score(fmt1) - + (gint)gst_vaapi_video_format_get_score(fmt2)); } /* Sort subpicture formats. Prefer RGB formats first */ @@ -255,14 +255,14 @@ compare_rgb_formats(gconstpointer a, gconstpointer b) const GstVideoFormat fmt1 = ((GstVaapiFormatInfo *)a)->format; const GstVideoFormat fmt2 = ((GstVaapiFormatInfo *)b)->format; - const gboolean is_fmt1_rgb = gst_video_format_is_rgb(fmt1); - const gboolean is_fmt2_rgb = gst_video_format_is_rgb(fmt2); + const gboolean is_fmt1_rgb = gst_vaapi_video_format_is_rgb(fmt1); + const gboolean is_fmt2_rgb = gst_vaapi_video_format_is_rgb(fmt2); if (is_fmt1_rgb != is_fmt2_rgb) return is_fmt1_rgb ? -1 : 1; - return ((gint)gst_video_format_get_score(fmt1) - - (gint)gst_video_format_get_score(fmt2)); + return ((gint)gst_vaapi_video_format_get_score(fmt1) - + (gint)gst_vaapi_video_format_get_score(fmt2)); } /* Check if configs array contains profile at entrypoint */ @@ -377,7 +377,7 @@ get_format_caps(GArray *formats) for (i = 0; i < formats->len; i++) { fip = &g_array_index(formats, GstVaapiFormatInfo, i); - caps = gst_video_format_to_caps(fip->format); + caps = gst_vaapi_video_format_to_caps(fip->format); if (caps) gst_caps_append(out_caps, caps); } diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 9c39ee5ded..776439dc63 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -164,7 +164,7 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format) if (!gst_vaapi_display_has_image_format(display, format)) return FALSE; - va_format = gst_video_format_to_va_format(format); + va_format = gst_vaapi_video_format_to_va_format(format); if (!va_format) return FALSE; @@ -218,7 +218,7 @@ gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format, switch (image->format) { case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_I420: - va_format = gst_video_format_to_va_format(image->format); + va_format = gst_vaapi_video_format_to_va_format(image->format); if (!va_format) return FALSE; image->image.format = *va_format; @@ -397,7 +397,7 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) VAImage alt_va_image; const VAImageFormat *alt_va_format; - format = gst_video_format_from_va_format(&va_image->format); + format = gst_vaapi_video_format_from_va_format(&va_image->format); if (format == GST_VIDEO_FORMAT_UNKNOWN) return FALSE; @@ -425,7 +425,7 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) break; } if (format && - (alt_va_format = gst_video_format_to_va_format(format))) { + (alt_va_format = gst_vaapi_video_format_to_va_format(format))) { alt_va_image = *va_image; alt_va_image.format = *alt_va_format; SWAP_UINT(alt_va_image.offsets[1], alt_va_image.offsets[2]); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 0ffbc9ea21..9c681a8890 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -145,11 +145,11 @@ gst_vaapi_surface_create_with_format(GstVaapiSurface *surface, const VAImageFormat *va_format; VASurfaceAttrib attrib; - va_format = gst_video_format_to_va_format(format); + va_format = gst_vaapi_video_format_to_va_format(format); if (!va_format) goto error_unsupported_format; - chroma_type = gst_video_format_get_chroma_type(format); + chroma_type = gst_vaapi_video_format_get_chroma_type(format); if (!chroma_type) goto error_unsupported_format; diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index a5dbbe0f5f..f185f00f07 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -60,7 +60,7 @@ surface_pool_init(GstVaapiSurfacePool *pool, const GstVideoInfo *vip) if (pool->format == GST_VIDEO_FORMAT_ENCODED) pool->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; else - pool->chroma_type = gst_video_format_get_chroma_type(pool->format); + pool->chroma_type = gst_vaapi_video_format_get_chroma_type(pool->format); if (!pool->chroma_type) return FALSE; return TRUE; diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index b5a3c85b23..9edd983941 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -1,5 +1,5 @@ /* - * video-format.c - Video format abstraction + * video-format.h - Video format helpers for VA-API * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011-2013 Intel Corporation @@ -22,7 +22,7 @@ /** * SECTION:videoformat - * @short_description: Video format abstraction + * @short_description: Video format helpers for VA-API */ #include "sysdeps.h" @@ -64,7 +64,7 @@ struct _GstVideoFormatMap { { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } /* Image formats, listed in HW order preference */ -static const GstVideoFormatMap gst_video_formats[] = { +static const GstVideoFormatMap gst_vaapi_video_formats[] = { DEF_YUV(NV12, ('N','V','1','2'), LSB, 12, 420), DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12, 420), DEF_YUV(I420, ('I','4','2','0'), LSB, 12, 420), @@ -132,7 +132,7 @@ get_map(GstVideoFormat format) { const GstVideoFormatMap *m; - for (m = gst_video_formats; m->format; m++) { + for (m = gst_vaapi_video_formats; m->format; m++) { if (m->format == format) return m; } @@ -140,43 +140,39 @@ get_map(GstVideoFormat format) } /** - * gst_video_format_is_rgb: + * gst_vaapi_video_format_is_rgb: * @format: a #GstVideoFormat * * Checks whether the format is an RGB format. * * Return value: %TRUE if @format is RGB format */ -#if GST_CHECK_VERSION(1,0,0) gboolean -gst_video_format_is_rgb(GstVideoFormat format) +gst_vaapi_video_format_is_rgb(GstVideoFormat format) { const GstVideoFormatMap * const m = get_map(format); return m && va_format_is_rgb(&m->va_format); } -#endif /** - * gst_video_format_is_yuv: + * gst_vaapi_video_format_is_yuv: * @format: a #GstVideoFormat * * Checks whether the format is an YUV format. * * Return value: %TRUE if @format is YUV format */ -#if GST_CHECK_VERSION(1,0,0) gboolean -gst_video_format_is_yuv(GstVideoFormat format) +gst_vaapi_video_format_is_yuv(GstVideoFormat format) { const GstVideoFormatMap * const m = get_map(format); return m && va_format_is_yuv(&m->va_format); } -#endif /** - * gst_video_format_from_caps: + * gst_vaapi_video_format_from_caps: * @caps: a #GstCaps * * Converts @caps into the corresponding #GstVideoFormat. If the @@ -186,7 +182,7 @@ gst_video_format_is_yuv(GstVideoFormat format) * Return value: the #GstVideoFormat describing the @caps */ GstVideoFormat -gst_video_format_from_caps(GstCaps *caps) +gst_vaapi_video_format_from_caps(GstCaps *caps) { GstStructure *structure; @@ -196,11 +192,11 @@ gst_video_format_from_caps(GstCaps *caps) structure = gst_caps_get_structure(caps, 0); if (!structure) return 0; - return gst_video_format_from_structure(structure); + return gst_vaapi_video_format_from_structure(structure); } /** - * gst_video_format_from_structure: + * gst_vaapi_video_format_from_structure: * @structure: a #GstStructure * * Converts @structure into the corresponding #GstVideoFormat. If @@ -210,7 +206,7 @@ gst_video_format_from_caps(GstCaps *caps) * Return value: the #GstVideoFormat describing the @structure */ GstVideoFormat -gst_video_format_from_structure(GstStructure *structure) +gst_vaapi_video_format_from_structure(GstStructure *structure) { #if GST_CHECK_VERSION(1,0,0) const gchar * format = gst_structure_get_string(structure, "format"); @@ -248,7 +244,7 @@ gst_video_format_from_structure(GstStructure *structure) va_format->blue_mask = GUINT32_SWAP_LE_BE(bmask); va_format->alpha_mask = GUINT32_SWAP_LE_BE(amask); - for (m = gst_video_formats; m->format; m++) { + for (m = gst_vaapi_video_formats; m->format; m++) { if (va_format_is_rgb(&m->va_format) && (va_format_is_same_rgb(&m->va_format, &va_formats[0]) || va_format_is_same_rgb(&m->va_format, &va_formats[1]))) @@ -259,7 +255,7 @@ gst_video_format_from_structure(GstStructure *structure) } /** - * gst_video_format_to_caps: + * gst_vaapi_video_format_to_caps: * @format: a #GstVideoFormat * * Converts a #GstVideoFormat into the corresponding #GstCaps. If @@ -268,7 +264,7 @@ gst_video_format_from_structure(GstStructure *structure) * Return value: the newly allocated #GstCaps, or %NULL if none was found */ GstCaps * -gst_video_format_to_caps(GstVideoFormat format) +gst_vaapi_video_format_to_caps(GstVideoFormat format) { const GstVideoFormatMap * const m = get_map(format); @@ -276,7 +272,7 @@ gst_video_format_to_caps(GstVideoFormat format) } /** - * gst_video_format_from_va_format: + * gst_vaapi_video_format_from_va_format: * @va_format: a #VAImageFormat * * Converts a VA image format into the corresponding #GstVideoFormat. @@ -286,11 +282,11 @@ gst_video_format_to_caps(GstVideoFormat format) * Return value: the #GstVideoFormat describing the @va_format */ GstVideoFormat -gst_video_format_from_va_format(const VAImageFormat *va_format) +gst_vaapi_video_format_from_va_format(const VAImageFormat *va_format) { const GstVideoFormatMap *m; - for (m = gst_video_formats; m->format; m++) { + for (m = gst_vaapi_video_formats; m->format; m++) { if (va_format_is_same(&m->va_format, va_format)) return m->format; } @@ -298,7 +294,7 @@ gst_video_format_from_va_format(const VAImageFormat *va_format) } /** - * gst_video_format_to_va_format: + * gst_vaapi_video_format_to_va_format: * @format: a #GstVideoFormat * * Converts a #GstVideoFormat into the corresponding VA image @@ -308,7 +304,7 @@ gst_video_format_from_va_format(const VAImageFormat *va_format) * Return value: the VA image format, or %NULL if none was found */ const VAImageFormat * -gst_video_format_to_va_format(GstVideoFormat format) +gst_vaapi_video_format_to_va_format(GstVideoFormat format) { const GstVideoFormatMap * const m = get_map(format); @@ -316,7 +312,7 @@ gst_video_format_to_va_format(GstVideoFormat format) } /** - * gst_video_format_get_chroma_type: + * gst_vaapi_video_format_get_chroma_type: * @format: a #GstVideoFormat * * Converts a #GstVideoFormat into the corresponding #GstVaapiChromaType @@ -326,7 +322,7 @@ gst_video_format_to_va_format(GstVideoFormat format) * was found. */ guint -gst_video_format_get_chroma_type(GstVideoFormat format) +gst_vaapi_video_format_get_chroma_type(GstVideoFormat format) { const GstVideoFormatMap * const m = get_map(format); @@ -334,7 +330,7 @@ gst_video_format_get_chroma_type(GstVideoFormat format) } /** - * gst_video_format_get_score: + * gst_vaapi_video_format_get_score: * @format: a #GstVideoFormat * * Determines how "native" is this @format. The lower is the returned @@ -343,9 +339,9 @@ gst_video_format_get_chroma_type(GstVideoFormat format) * Return value: the @format score, or %G_MAXUINT if none was found */ guint -gst_video_format_get_score(GstVideoFormat format) +gst_vaapi_video_format_get_score(GstVideoFormat format) { const GstVideoFormatMap * const m = get_map(format); - return m ? (m - &gst_video_formats[0]) : G_MAXUINT; + return m ? (m - &gst_vaapi_video_formats[0]) : G_MAXUINT; } diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index a1dc9f693d..eb7ec1dde1 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -1,5 +1,5 @@ /* - * video-format.h - Video format abstraction + * video-format.h - Video format helpers for VA-API * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Copyright (C) 2011-2013 Intel Corporation @@ -29,31 +29,31 @@ G_BEGIN_DECLS gboolean -gst_video_format_is_rgb(GstVideoFormat format); +gst_vaapi_video_format_is_rgb(GstVideoFormat format); gboolean -gst_video_format_is_yuv(GstVideoFormat format); +gst_vaapi_video_format_is_yuv(GstVideoFormat format); GstVideoFormat -gst_video_format_from_structure(GstStructure *structure); +gst_vaapi_video_format_from_structure(GstStructure *structure); GstVideoFormat -gst_video_format_from_caps(GstCaps *caps); +gst_vaapi_video_format_from_caps(GstCaps *caps); GstCaps * -gst_video_format_to_caps(GstVideoFormat format); +gst_vaapi_video_format_to_caps(GstVideoFormat format); GstVideoFormat -gst_video_format_from_va_format(const VAImageFormat *va_format); +gst_vaapi_video_format_from_va_format(const VAImageFormat *va_format); const VAImageFormat * -gst_video_format_to_va_format(GstVideoFormat format); +gst_vaapi_video_format_to_va_format(GstVideoFormat format); guint -gst_video_format_get_chroma_type(GstVideoFormat format); +gst_vaapi_video_format_get_chroma_type(GstVideoFormat format); guint -gst_video_format_get_score(GstVideoFormat format); +gst_vaapi_video_format_get_score(GstVideoFormat format); G_END_DECLS diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 18ec0540aa..ccdfe9c7c8 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -334,7 +334,7 @@ gst_vaapidownload_update_src_caps(GstVaapiDownload *download, GstBuffer *buffer) return FALSE; } - out_caps = gst_video_format_to_caps(download->image_format); + out_caps = gst_vaapi_video_format_to_caps(download->image_format); if (!out_caps) { GST_WARNING("failed to create caps from format %s", gst_video_format_to_string(download->image_format)); diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 234674b9c9..dc8f7a5878 100755 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -138,7 +138,7 @@ ensure_allowed_caps(GstVaapiUploader *uploader) GstVaapiImage *image; GstVideoFormat format; - format = gst_video_format_from_structure(structure); + format = gst_vaapi_video_format_from_structure(structure); if (format == GST_VIDEO_FORMAT_UNKNOWN) continue; image = gst_vaapi_image_new(priv->display, format, WIDTH, HEIGHT); @@ -224,7 +224,7 @@ ensure_surface_pool(GstVaapiUploader *uploader, GstCaps *caps, /* XXX: this also means that visual quality is not preserved */ if (format != GST_VIDEO_FORMAT_ENCODED) { const GstVaapiChromaType chroma_type = - gst_video_format_get_chroma_type(format); + gst_vaapi_video_format_get_chroma_type(format); if (chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) { const GstVideoFormat image_format = GST_VIDEO_INFO_FORMAT(&priv->image_info); diff --git a/tests/image.c b/tests/image.c index d412a17cb7..305322b0b5 100644 --- a/tests/image.c +++ b/tests/image.c @@ -302,7 +302,7 @@ image_draw_rectangle( stride[i] = gst_vaapi_image_get_pitch(image, i); } - if (gst_video_format_is_yuv(image_format)) + if (gst_vaapi_video_format_is_yuv(image_format)) color = argb2yuv(color); if (x < 0) diff --git a/tests/test-display.c b/tests/test-display.c index 263fa35c1c..07842a25c9 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -133,15 +133,15 @@ print_format_caps(GstCaps *caps, const gchar *name) g_print(" %s:", gst_structure_get_name(structure)); - format = gst_video_format_from_structure(structure); + format = gst_vaapi_video_format_from_structure(structure); if (format == GST_VIDEO_FORMAT_UNKNOWN) g_error("could not determine format"); - va_format = gst_video_format_to_va_format(format); + va_format = gst_vaapi_video_format_to_va_format(format); if (!va_format) g_error("could not determine VA format"); - if (gst_video_format_is_yuv(format)) + if (gst_vaapi_video_format_is_yuv(format)) print_format_caps_yuv(va_format); else print_format_caps_rgb(va_format); From 415e65a9802bfbc2d79aa43a6e55844922a635d7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Jul 2013 14:47:01 +0200 Subject: [PATCH 1271/3781] 0.5.5. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index b0358fb921..efbd29abb8 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2013-07-DD +gst-vaapi NEWS -- summary of changes. 2013-07-15 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora -Version 0.5.5 - DD.Jul.2013 +Version 0.5.5 - 15.Jul.2013 * Allow creation of video surfaces with an explicit pixel format * Allocate VA/GLX capable buffers by default on X11 servers (Victor Jaquez) * Add support for video cropping in MPEG-2, VC-1 and H.264 codecs (+Sreerenj) diff --git a/configure.ac b/configure.ac index 2bd732ad39..8e7855e914 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [5]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From b358651fb3a6335624ebe04c5e6fe40dca5a1327 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Jul 2013 17:43:34 +0200 Subject: [PATCH 1272/3781] decoder: dispose GstVideoCodecFrame earlier. Once the picture was output, it is no longer necessary to keep an extra reference to the underlying GstVideoCodecFrame. So, we can release it earlier, and maybe subsequently release the associate surface proxy earlier. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 4b52134985..fbbe5f7675 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -37,6 +37,15 @@ #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 --- */ /* ------------------------------------------------------------------------- */ @@ -82,10 +91,7 @@ gst_vaapi_picture_destroy(GstVaapiPicture *picture) 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; - } + gst_video_codec_frame_clear(&picture->frame); gst_vaapi_picture_replace(&picture->parent_picture, NULL); } @@ -338,6 +344,7 @@ do_output(GstVaapiPicture *picture) 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; From f4097931a1e1ce77671fafc90f70e0cb2b38cde5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Jul 2013 17:49:31 +0200 Subject: [PATCH 1273/3781] mpeg2: don't output dummy pictures. Mark dummy pictures as output already so that we don't try to submit them to the upper layer since this is purely internal / temporary picture for helping the decoder. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index fdc6596b15..7cf78219c4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -993,6 +993,7 @@ init_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) GST_VAAPI_PICTURE_FLAG_SET( dummy_picture, (GST_VAAPI_PICTURE_FLAG_SKIPPED | + GST_VAAPI_PICTURE_FLAG_OUTPUT | GST_VAAPI_PICTURE_FLAG_REFERENCE) ); From 07e890e81828d01806dad9d01d9e1d9cea690e8d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 17 Jul 2013 11:07:39 +0200 Subject: [PATCH 1274/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 8e7855e914..6e033e82f8 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [5]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [6]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From b868c6d88814bf491174f494d8c79298cf97a3d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Thu, 18 Jul 2013 02:54:54 -0300 Subject: [PATCH 1275/3781] plugins: fix display type comparison in gst_vaapi_create_display(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the code got moved to create the gst_vaapi_create_display() helper, this comparison was not updated to dereference the newly-created pointer, so the code was comparing the pointer itself to the type, and therefore failing to retrieve the VA display. This fixes the following error (and gets gst-vaapi decoding again): ERROR vaapidecode gstvaapidecode.c:807:gst_vaapidecode_ensure_allowed_caps: failed to retrieve VA display https://bugzilla.gnome.org/show_bug.cgi?id=704410 Signed-off-by: Emilio López --- gst/vaapi/gstvaapipluginutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index a1dbad86e1..ac48d01701 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -103,7 +103,7 @@ gst_vaapi_create_display(GstVaapiDisplayType *display_type) break; } - if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY) + if (*display_type != GST_VAAPI_DISPLAY_TYPE_ANY) break; } return display; From 4a8a80061f2f1c706ff6f5fef7d6e44f6a673528 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Jul 2013 15:15:48 +0200 Subject: [PATCH 1276/3781] libs: add and expose gst_vaapi_video_format_to_string() helper. This is just a wrapper over gst_video_format_to_string() for older GStreamer 0.10 builds. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapiimage.c | 4 ++-- gst-libs/gst/vaapi/gstvaapisurface.c | 4 ++-- gst-libs/gst/vaapi/video-format.c | 15 +++++++++++++++ gst-libs/gst/vaapi/video-format.h | 3 +++ 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 5c687554d3..a79f048830 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -1,6 +1,7 @@
videoformat GstVideoFormat +gst_vaapi_video_format_to_string gst_vaapi_video_format_from_caps gst_vaapi_video_format_from_structure gst_vaapi_video_format_from_va_format diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 776439dc63..30df81da94 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -285,7 +285,7 @@ gst_vaapi_image_new( g_return_val_if_fail(width > 0, NULL); g_return_val_if_fail(height > 0, NULL); - GST_DEBUG("format %s, size %ux%u", gst_video_format_to_string(format), + GST_DEBUG("format %s, size %ux%u", gst_vaapi_video_format_to_string(format), width, height); image = gst_vaapi_object_new(gst_vaapi_image_class(), display); @@ -435,7 +435,7 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) image->format = format; image->is_linear = TRUE; GST_DEBUG("linearized image to %s format", - gst_video_format_to_string(format)); + gst_vaapi_video_format_to_string(format)); } } } diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 9c681a8890..768a8a9b7c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -184,7 +184,7 @@ gst_vaapi_surface_create_with_format(GstVaapiSurface *surface, /* ERRORS */ error_unsupported_format: - GST_ERROR("unsupported format %u", gst_video_format_to_string(format)); + GST_ERROR("unsupported format %u", gst_vaapi_video_format_to_string(format)); return FALSE; #else return FALSE; @@ -256,7 +256,7 @@ gst_vaapi_surface_new_with_format( GstVaapiSurface *surface; GST_DEBUG("size %ux%u, format %s", width, height, - gst_video_format_to_string(format)); + gst_vaapi_video_format_to_string(format)); surface = gst_vaapi_object_new(gst_vaapi_surface_class(), display); if (!surface) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 9edd983941..68198a4167 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -139,6 +139,21 @@ get_map(GstVideoFormat format) return NULL; } +/** + * gst_vaapi_video_format_to_string: + * @format: a #GstVideoFormat + * + * Returns the string representation of the @format argument. + * + * Return value: string representation of @format, or %NULL if unknown + * or unsupported. + */ +const gchar * +gst_vaapi_video_format_to_string(GstVideoFormat format) +{ + return gst_video_format_to_string(format); +} + /** * gst_vaapi_video_format_is_rgb: * @format: a #GstVideoFormat diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index eb7ec1dde1..a3d7d5be58 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -28,6 +28,9 @@ G_BEGIN_DECLS +const char * +gst_vaapi_video_format_to_string(GstVideoFormat format); + gboolean gst_vaapi_video_format_is_rgb(GstVideoFormat format); From 5cabf4e305bd6b0fb216d773b0260d1f0ac6ca31 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Jul 2013 10:00:21 +0200 Subject: [PATCH 1277/3781] Add initial Pixmap API. Add API to transfer VA urfaces to native pixmaps. Also add an API to render a native pixmap, for completeness. In general, rendering to pixmap would only be useful to certain VA drivers and use cases on X11 display servers. e.g. GLX_EXT_texture_from_pixmap (TFP) handled in an upper layer. --- docs/reference/libs/libs-docs.xml.in | 1 + docs/reference/libs/libs-sections.txt | 17 ++ gst-libs/gst/vaapi/Makefile.am | 3 + gst-libs/gst/vaapi/gstvaapipixmap.c | 259 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapipixmap.h | 97 +++++++++ gst-libs/gst/vaapi/gstvaapipixmap_priv.h | 137 ++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow.c | 57 +++++ gst-libs/gst/vaapi/gstvaapiwindow.h | 9 + gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 4 + 9 files changed, 584 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapipixmap.c create mode 100644 gst-libs/gst/vaapi/gstvaapipixmap.h create mode 100644 gst-libs/gst/vaapi/gstvaapipixmap_priv.h diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 3fff5e7b5c..24c9e8345a 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -16,6 +16,7 @@ + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index a79f048830..4544f66883 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -140,6 +140,22 @@ GstVaapiPoint GstVaapiRectangle
+
+gstvaapipixmap +GstVaapiPixmap +GstVaapiPixmap +gst_vaapi_pixmap_ref +gst_vaapi_pixmap_unref +gst_vaapi_pixmap_replace +gst_vaapi_pixmap_get_format +gst_vaapi_pixmap_get_width +gst_vaapi_pixmap_get_height +gst_vaapi_pixmap_get_size +gst_vaapi_pixmap_put_surface + +GST_VAAPI_PIXMAP +
+
gstvaapiwindow GstVaapiWindow @@ -155,6 +171,7 @@ gst_vaapi_window_get_size gst_vaapi_window_set_width gst_vaapi_window_set_height gst_vaapi_window_set_size +gst_vaapi_window_put_pixmap gst_vaapi_window_put_surface GST_VAAPI_WINDOW diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index a9e61d8791..57e49c1ed0 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -60,6 +60,7 @@ libgstvaapi_source_c = \ gstvaapiminiobject.c \ gstvaapiobject.c \ gstvaapiparser_frame.c \ + gstvaapipixmap.c \ gstvaapiprofile.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ @@ -84,6 +85,7 @@ libgstvaapi_source_h = \ gstvaapiimage.h \ gstvaapiimagepool.h \ gstvaapiobject.h \ + gstvaapipixmap.h \ gstvaapiprofile.h \ gstvaapisubpicture.h \ gstvaapisurface.h \ @@ -110,6 +112,7 @@ libgstvaapi_source_priv_h = \ gstvaapiminiobject.h \ gstvaapiobject_priv.h \ gstvaapiparser_frame.h \ + gstvaapipixmap_priv.h \ gstvaapisurface_priv.h \ gstvaapisurfaceproxy_priv.h \ gstvaapiutils.h \ diff --git a/gst-libs/gst/vaapi/gstvaapipixmap.c b/gst-libs/gst/vaapi/gstvaapipixmap.c new file mode 100644 index 0000000000..5bb388c476 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapipixmap.c @@ -0,0 +1,259 @@ +/* + * gstvaapipixmap.c - Pixmap abstraction + * + * Copyright (C) 2013 Intel Corporation + * + * 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:gstvaapipixmap + * @short_description: Pixmap abstraction + */ + +#include "sysdeps.h" +#include "gstvaapipixmap.h" +#include "gstvaapipixmap_priv.h" +#include "gstvaapisurface_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +/* Ensure those symbols are actually defined in the resulting libraries */ +#undef gst_vaapi_pixmap_ref +#undef gst_vaapi_pixmap_unref +#undef gst_vaapi_pixmap_replace + +static inline GstVaapiPixmap * +gst_vaapi_pixmap_new_internal(const GstVaapiPixmapClass *pixmap_class, + GstVaapiDisplay *display) +{ + g_assert(pixmap_class->create != NULL); + g_assert(pixmap_class->render != NULL); + + return gst_vaapi_object_new(GST_VAAPI_OBJECT_CLASS(pixmap_class), display); +} + +GstVaapiPixmap * +gst_vaapi_pixmap_new(const GstVaapiPixmapClass *pixmap_class, + GstVaapiDisplay *display, GstVideoFormat format, guint width, guint height) +{ + GstVaapiPixmap *pixmap; + + g_return_val_if_fail(format != GST_VIDEO_FORMAT_UNKNOWN && + format != GST_VIDEO_FORMAT_ENCODED, NULL); + g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(height > 0, NULL); + + pixmap = gst_vaapi_pixmap_new_internal(pixmap_class, display); + if (!pixmap) + return NULL; + + pixmap->format = format; + pixmap->width = width; + pixmap->height = height; + if (!pixmap_class->create(pixmap)) + goto error; + return pixmap; + +error: + gst_vaapi_pixmap_unref_internal(pixmap); + return NULL; +} + +GstVaapiPixmap * +gst_vaapi_pixmap_new_from_native(const GstVaapiPixmapClass *pixmap_class, + GstVaapiDisplay *display, gpointer native_pixmap) +{ + GstVaapiPixmap *pixmap; + + pixmap = gst_vaapi_pixmap_new_internal(pixmap_class, display); + if (!pixmap) + return NULL; + + GST_VAAPI_OBJECT_ID(pixmap) = GPOINTER_TO_SIZE(native_pixmap); + pixmap->use_foreign_pixmap = TRUE; + if (!pixmap_class->create(pixmap)) + goto error; + return pixmap; + +error: + gst_vaapi_pixmap_unref_internal(pixmap); + return NULL; +} + +/** + * gst_vaapi_pixmap_ref: + * @pixmap: a #GstVaapiPixmap + * + * Atomically increases the reference count of the given @pixmap by one. + * + * Returns: The same @pixmap argument + */ +GstVaapiPixmap * +gst_vaapi_pixmap_ref(GstVaapiPixmap *pixmap) +{ + return gst_vaapi_pixmap_ref_internal(pixmap); +} + +/** + * gst_vaapi_pixmap_unref: + * @pixmap: a #GstVaapiPixmap + * + * Atomically decreases the reference count of the @pixmap by one. If + * the reference count reaches zero, the pixmap will be free'd. + */ +void +gst_vaapi_pixmap_unref(GstVaapiPixmap *pixmap) +{ + gst_vaapi_pixmap_unref_internal(pixmap); +} + +/** + * gst_vaapi_pixmap_replace: + * @old_pixmap_ptr: a pointer to a #GstVaapiPixmap + * @new_pixmap: a #GstVaapiPixmap + * + * Atomically replaces the pixmap pixmap held in @old_pixmap_ptr with + * @new_pixmap. This means that @old_pixmap_ptr shall reference a + * valid pixmap. However, @new_pixmap can be NULL. + */ +void +gst_vaapi_pixmap_replace(GstVaapiPixmap **old_pixmap_ptr, + GstVaapiPixmap *new_pixmap) +{ + gst_vaapi_pixmap_replace_internal(old_pixmap_ptr, new_pixmap); +} + +/** + * gst_vaapi_pixmap_get_display: + * @pixmap: a #GstVaapiPixmap + * + * Returns the #GstVaapiDisplay this @pixmap is bound to. + * + * Return value: the parent #GstVaapiDisplay object + */ +GstVaapiDisplay * +gst_vaapi_pixmap_get_display(GstVaapiPixmap *pixmap) +{ + g_return_val_if_fail(pixmap != NULL, NULL); + + return GST_VAAPI_OBJECT_DISPLAY(pixmap); +} + +/** + * gst_vaapi_pixmap_get_format: + * @pixmap: a #GstVaapiPixmap + * + * Retrieves the format of a #GstVaapiPixmap. + * + * Return value: the format of the @pixmap + */ +GstVideoFormat +gst_vaapi_pixmap_get_format(GstVaapiPixmap *pixmap) +{ + g_return_val_if_fail(pixmap != NULL, GST_VIDEO_FORMAT_UNKNOWN); + + return GST_VAAPI_PIXMAP_FORMAT(pixmap); +} + +/** + * gst_vaapi_pixmap_get_width: + * @pixmap: a #GstVaapiPixmap + * + * Retrieves the width of a #GstVaapiPixmap. + * + * Return value: the width of the @pixmap, in pixels + */ +guint +gst_vaapi_pixmap_get_width(GstVaapiPixmap *pixmap) +{ + g_return_val_if_fail(pixmap != NULL, 0); + + return GST_VAAPI_PIXMAP_WIDTH(pixmap); +} + +/** + * gst_vaapi_pixmap_get_height: + * @pixmap: a #GstVaapiPixmap + * + * Retrieves the height of a #GstVaapiPixmap + * + * Return value: the height of the @pixmap, in pixels + */ +guint +gst_vaapi_pixmap_get_height(GstVaapiPixmap *pixmap) +{ + g_return_val_if_fail(pixmap != NULL, 0); + + return GST_VAAPI_PIXMAP_HEIGHT(pixmap); +} + +/** + * gst_vaapi_pixmap_get_size: + * @pixmap: a #GstVaapiPixmap + * @width: return location for the width, or %NULL + * @height: return location for the height, or %NULL + * + * Retrieves the dimensions of a #GstVaapiPixmap. + */ +void +gst_vaapi_pixmap_get_size(GstVaapiPixmap *pixmap, guint *width, guint *height) +{ + g_return_if_fail(pixmap != NULL); + + if (width) + *width = GST_VAAPI_PIXMAP_WIDTH(pixmap); + + if (height) + *height = GST_VAAPI_PIXMAP_HEIGHT(pixmap); +} + +/** + * gst_vaapi_pixmap_put_surface: + * @pixmap: a #GstVaapiPixmap + * @surface: a #GstVaapiSurface + * @crop_rect: the video cropping rectangle, or %NULL if the entire + * surface is to be used. + * @flags: postprocessing flags. See #GstVaapiSurfaceRenderFlags + * + * Renders the whole @surface, or a cropped region defined with + * @crop_rect, into the @pixmap, while scaling to fit the target + * pixmap. The @flags specify how de-interlacing (if needed), color + * space conversion, scaling and other postprocessing transformations + * are performed. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_pixmap_put_surface(GstVaapiPixmap *pixmap, GstVaapiSurface *surface, + const GstVaapiRectangle *crop_rect, guint flags) +{ + GstVaapiRectangle src_rect; + + g_return_val_if_fail(pixmap != NULL, FALSE); + g_return_val_if_fail(surface != NULL, FALSE); + + if (!crop_rect) { + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = GST_VAAPI_SURFACE_WIDTH(surface); + src_rect.height = GST_VAAPI_SURFACE_HEIGHT(surface); + crop_rect = &src_rect; + } + return GST_VAAPI_PIXMAP_GET_CLASS(pixmap)->render(pixmap, surface, + crop_rect, flags); +} diff --git a/gst-libs/gst/vaapi/gstvaapipixmap.h b/gst-libs/gst/vaapi/gstvaapipixmap.h new file mode 100644 index 0000000000..fd2e138142 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapipixmap.h @@ -0,0 +1,97 @@ +/* + * gstvaapipixmap.h - Pixmap abstraction + * + * Copyright (C) 2013 Intel Corporation + * + * 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_PIXMAP_H +#define GST_VAAPI_PIXMAP_H + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_PIXMAP(obj) \ + ((GstVaapiPixmap *)(obj)) + +typedef struct _GstVaapiPixmap GstVaapiPixmap; +typedef struct _GstVaapiPixmapClass GstVaapiPixmapClass; + +/** + * GST_VAAPI_PIXMAP_FORMAT: + * @pixmap: a #GstVaapiPixmap + * + * Macro that evaluates to the format in pixels of the @pixmap. + */ +#define GST_VAAPI_PIXMAP_FORMAT(pixmap) \ + gst_vaapi_pixmap_get_format(GST_VAAPI_PIXMAP(pixmap)) + +/** + * GST_VAAPI_PIXMAP_WIDTH: + * @pixmap: a #GstVaapiPixmap + * + * Macro that evaluates to the width in pixels of the @pixmap. + */ +#define GST_VAAPI_PIXMAP_WIDTH(pixmap) \ + gst_vaapi_pixmap_get_width(GST_VAAPI_PIXMAP(pixmap)) + +/** + * GST_VAAPI_PIXMAP_HEIGHT: + * @pixmap: a #GstVaapiPixmap + * + * Macro that evaluates to the height in pixels of the @pixmap. + */ +#define GST_VAAPI_PIXMAP_HEIGHT(pixmap) \ + gst_vaapi_pixmap_get_height(GST_VAAPI_PIXMAP(pixmap)) + +GstVaapiPixmap * +gst_vaapi_pixmap_ref(GstVaapiPixmap *pixmap); + +void +gst_vaapi_pixmap_unref(GstVaapiPixmap *pixmap); + +void +gst_vaapi_pixmap_replace(GstVaapiPixmap **old_pixmap_ptr, + GstVaapiPixmap *new_pixmap); + +GstVaapiDisplay * +gst_vaapi_pixmap_get_display(GstVaapiPixmap *pixmap); + +GstVideoFormat +gst_vaapi_pixmap_get_format(GstVaapiPixmap *pixmap); + +guint +gst_vaapi_pixmap_get_width(GstVaapiPixmap *pixmap); + +guint +gst_vaapi_pixmap_get_height(GstVaapiPixmap *pixmap); + +void +gst_vaapi_pixmap_get_size(GstVaapiPixmap *pixmap, guint *width, guint *height); + +gboolean +gst_vaapi_pixmap_put_surface(GstVaapiPixmap *pixmap, GstVaapiSurface *surface, + const GstVaapiRectangle *crop_rect, guint flags); + +G_END_DECLS + +#endif /* GST_VAAPI_PIXMAP_H */ diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_priv.h b/gst-libs/gst/vaapi/gstvaapipixmap_priv.h new file mode 100644 index 0000000000..6856c5236e --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapipixmap_priv.h @@ -0,0 +1,137 @@ +/* + * gstvaapipixmap_priv.h - Pixmap abstraction (private definitions) + * + * Copyright (C) 2013 Intel Corporation + * + * 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_PIXMAP_PRIV_H +#define GST_VAAPI_PIXMAP_PRIV_H + +#include "gstvaapiobject_priv.h" + +G_BEGIN_DECLS + +#define GST_VAAPI_PIXMAP_CLASS(klass) \ + ((GstVaapiPixmapClass *)(klass)) + +#define GST_VAAPI_PIXMAP_GET_CLASS(obj) \ + GST_VAAPI_PIXMAP_CLASS(GST_VAAPI_OBJECT_GET_CLASS(obj)) + +/** + * GST_VAAPI_PIXMAP_FORMAT: + * @pixmap: a #GstVaapiPixmap + * + * Macro that evaluates to the format in pixels of the @pixmap. + */ +#undef GST_VAAPI_PIXMAP_FORMAT +#define GST_VAAPI_PIXMAP_FORMAT(pixmap) \ + (GST_VAAPI_PIXMAP(pixmap)->format) + +/** + * GST_VAAPI_PIXMAP_WIDTH: + * @pixmap: a #GstVaapiPixmap + * + * Macro that evaluates to the width in pixels of the @pixmap. + */ +#undef GST_VAAPI_PIXMAP_WIDTH +#define GST_VAAPI_PIXMAP_WIDTH(pixmap) \ + (GST_VAAPI_PIXMAP(pixmap)->width) + +/** + * GST_VAAPI_PIXMAP_HEIGHT: + * @pixmap: a #GstVaapiPixmap + * + * Macro that evaluates to the height in pixels of the @pixmap. + */ +#undef GST_VAAPI_PIXMAP_HEIGHT +#define GST_VAAPI_PIXMAP_HEIGHT(pixmap) \ + (GST_VAAPI_PIXMAP(pixmap)->height) + +/* GstVaapiPixmapClass hooks */ +typedef gboolean (*GstVaapiPixmapCreateFunc) (GstVaapiPixmap *pixmap); +typedef gboolean (*GstVaapiPixmapRenderFunc) (GstVaapiPixmap *pixmap, + GstVaapiSurface *surface, const GstVaapiRectangle *crop_rect, guint flags); + +/** + * GstVaapiPixmap: + * + * Base class for system-dependent pixmaps. + */ +struct _GstVaapiPixmap { + /*< private >*/ + GstVaapiObject parent_instance; + + /*< protected >*/ + GstVideoFormat format; + guint width; + guint height; + guint use_foreign_pixmap : 1; +}; + +/** + * GstVaapiPixmapClass: + * @create: virtual function to create a pixmap with width and height + * @render: virtual function to render a #GstVaapiSurface into a pixmap + * + * Base class for system-dependent pixmaps. + */ +struct _GstVaapiPixmapClass { + /*< private >*/ + GstVaapiObjectClass parent_class; + + /*< protected >*/ + GstVaapiPixmapCreateFunc create; + GstVaapiPixmapRenderFunc render; +}; + +GstVaapiPixmap * +gst_vaapi_pixmap_new(const GstVaapiPixmapClass *pixmap_class, + GstVaapiDisplay *display, GstVideoFormat format, guint width, guint height); + +GstVaapiPixmap * +gst_vaapi_pixmap_new_from_native(const GstVaapiPixmapClass *pixmap_class, + GstVaapiDisplay *display, gpointer native_pixmap); + +/* Inline reference counting for core libgstvaapi library */ +#ifdef GST_VAAPI_CORE +#define gst_vaapi_pixmap_ref_internal(pixmap) \ + ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pixmap))) + +#define gst_vaapi_pixmap_unref_internal(pixmap) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pixmap)) + +#define gst_vaapi_pixmap_replace_internal(old_pixmap_ptr, new_pixmap) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pixmap_ptr), \ + GST_VAAPI_MINI_OBJECT(new_pixmap)) + +#undef gst_vaapi_pixmap_ref +#define gst_vaapi_pixmap_ref(pixmap) \ + gst_vaapi_pixmap_ref_internal((pixmap)) + +#undef gst_vaapi_pixmap_unref +#define gst_vaapi_pixmap_unref(pixmap) \ + gst_vaapi_pixmap_unref_internal((pixmap)) + +#undef gst_vaapi_pixmap_replace +#define gst_vaapi_pixmap_replace(old_pixmap_ptr, new_pixmap) \ + gst_vaapi_pixmap_replace_internal((old_pixmap_ptr), (new_pixmap)) +#endif + +G_END_DECLS + +#endif /* GST_VAAPI_PIXMAP_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index bb73d94abc..d8f19723b5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -434,3 +434,60 @@ gst_vaapi_window_put_surface( return klass->render(window, surface, src_rect, dst_rect, flags); } + +static inline void +get_pixmap_rect(GstVaapiPixmap *pixmap, GstVaapiRectangle *rect) +{ + guint width, height; + + gst_vaapi_pixmap_get_size(pixmap, &width, &height); + rect->x = 0; + rect->y = 0; + rect->width = width; + rect->height = height; +} + +/** + * gst_vaapi_window_put_pixmap: + * @window: a #GstVaapiWindow + * @pixmap: a #GstVaapiPixmap + * @src_rect: the sub-rectangle of the source pixmap to + * extract and process. If %NULL, the entire pixmap will be used. + * @dst_rect: the sub-rectangle of the destination + * window into which the pixmap is rendered. If %NULL, the entire + * window will be used. + * + * Renders the @pixmap region specified by @src_rect into the @window + * region specified by @dst_rect. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_window_put_pixmap( + GstVaapiWindow *window, + GstVaapiPixmap *pixmap, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect +) +{ + const GstVaapiWindowClass *klass; + GstVaapiRectangle src_rect_default, dst_rect_default; + + g_return_val_if_fail(window != NULL, FALSE); + g_return_val_if_fail(pixmap != NULL, FALSE); + + klass = GST_VAAPI_WINDOW_GET_CLASS(window); + if (!klass->render_pixmap) + return FALSE; + + if (!src_rect) { + src_rect = &src_rect_default; + get_pixmap_rect(pixmap, &src_rect_default); + } + + if (!dst_rect) { + dst_rect = &dst_rect_default; + get_window_rect(window, &dst_rect_default); + } + return klass->render_pixmap(window, pixmap, src_rect, dst_rect); +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 13359d74d4..6d8a553da8 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -28,6 +28,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -89,6 +90,14 @@ gst_vaapi_window_put_surface( guint flags ); +gboolean +gst_vaapi_window_put_pixmap( + GstVaapiWindow *window, + GstVaapiPixmap *pixmap, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect +); + G_END_DECLS #endif /* GST_VAAPI_WINDOW_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index 39ca6a448e..6450d9587f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -47,6 +47,9 @@ typedef gboolean (*GstVaapiWindowResizeFunc) (GstVaapiWindow *window, typedef gboolean (*GstVaapiWindowRenderFunc) (GstVaapiWindow *window, GstVaapiSurface *surface, const GstVaapiRectangle *src_rect, const GstVaapiRectangle *dst_rect, guint flags); +typedef gboolean (*GstVaapiWindowRenderPixmapFunc)(GstVaapiWindow *window, + GstVaapiPixmap *pixmap, const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect); /** * GstVaapiWindow: @@ -91,6 +94,7 @@ struct _GstVaapiWindowClass { GstVaapiWindowSetFullscreenFunc set_fullscreen; GstVaapiWindowResizeFunc resize; GstVaapiWindowRenderFunc render; + GstVaapiWindowRenderPixmapFunc render_pixmap; }; GstVaapiWindow * From 5eb2cbb5efe6605128fd918dcdaf5d1dd3f5a8b4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Jul 2013 10:10:40 +0200 Subject: [PATCH 1278/3781] x11: update x11_get_geometry() helper function with depth output. Allow x11_get_geometry() utility function to also return the depth assigned to the X drawable. --- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 4 +++- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 3 ++- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 83a13ee904..2b7931b016 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -127,7 +127,8 @@ x11_get_geometry( gint *px, gint *py, guint *pwidth, - guint *pheight + guint *pheight, + guint *pdepth ) { Window rootwin; @@ -150,5 +151,6 @@ x11_get_geometry( if (py) *py = y; if (pwidth) *pwidth = width; if (pheight) *pheight = height; + if (pdepth) *pdepth = depth; return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index 60befa5ffc..252b4ae689 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -47,7 +47,8 @@ x11_get_geometry( gint *px, gint *py, guint *pwidth, - guint *pheight + guint *pheight, + guint *pdepth ); #endif /* GST_VAAPI_UTILS_X11_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index d5fc0bbd90..a5ea27752e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -227,7 +227,7 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) GST_VAAPI_OBJECT_LOCK_DISPLAY(window); XGetWindowAttributes(dpy, xid, &wattr); priv->is_mapped = wattr.map_state == IsViewable; - ok = x11_get_geometry(dpy, xid, NULL, NULL, width, height); + ok = x11_get_geometry(dpy, xid, NULL, NULL, width, height, NULL); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); return ok; } @@ -287,7 +287,7 @@ gst_vaapi_window_x11_get_geometry( Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); const Window xid = GST_VAAPI_OBJECT_ID(window); - return x11_get_geometry(dpy, xid, px, py, pwidth, pheight); + return x11_get_geometry(dpy, xid, px, py, pwidth, pheight, NULL); } static gboolean From 373329e6ff62857c0e1fc7f8a490d02114a8361a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 19 Jul 2013 15:05:34 +0200 Subject: [PATCH 1279/3781] x11: implement pixmap API. Implement the new render-to-pixmap API. The only supported pixmap format that will work is xRGB, with native byte ordering. Others might work but they were not tested. --- docs/reference/libs/libs-docs.xml.in | 1 + docs/reference/libs/libs-sections.txt | 13 + gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 115 ++++++++ gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 11 + gst-libs/gst/vaapi/gstvaapipixmap_x11.c | 253 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapipixmap_x11.h | 60 +++++ 7 files changed, 455 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapipixmap_x11.c create mode 100644 gst-libs/gst/vaapi/gstvaapipixmap_x11.h diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 24c9e8345a..f8940f8ac0 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -17,6 +17,7 @@ + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 4544f66883..e619f19cfb 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -65,6 +65,19 @@ gst_vaapi_window_x11_is_foreign_xid GST_VAAPI_WINDOW_X11
+
+gstvaapipixmap_x11 +GstVaapiPixmapX11 +GstVaapiPixmapX11 +GST_VAAPI_PIXMAP_XPIXMAP +gst_vaapi_pixmap_x11_new +gst_vaapi_pixmap_x11_new_with_xid +gst_vaapi_pixmap_x11_get_xid +gst_vaapi_pixmap_x11_is_foreign_xid + +GST_VAAPI_WINDOW_X11 +
+
gstvaapidisplay_glx GstVaapiDisplayGLX diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 57e49c1ed0..b2a5df56f8 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -149,6 +149,7 @@ libgstvaapi_drm_source_priv_h = \ libgstvaapi_x11_source_c = \ gstvaapidisplay_x11.c \ + gstvaapipixmap_x11.c \ gstvaapiutils.c \ gstvaapiutils_x11.c \ gstvaapiwindow_x11.c \ @@ -156,6 +157,7 @@ libgstvaapi_x11_source_c = \ libgstvaapi_x11_source_h = \ gstvaapidisplay_x11.h \ + gstvaapipixmap_x11.h \ gstvaapiwindow_x11.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 10f3dfbc3e..5fb0cba265 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -203,6 +203,11 @@ gst_vaapi_display_x11_close_display(GstVaapiDisplay *display) GstVaapiDisplayX11Private * const priv = GST_VAAPI_DISPLAY_X11_PRIVATE(display); + if (priv->pixmap_formats) { + g_array_free(priv->pixmap_formats, TRUE); + priv->pixmap_formats = NULL; + } + if (priv->x11_display) { if (!priv->use_foreign_display) XCloseDisplay(priv->x11_display); @@ -478,3 +483,113 @@ gst_vaapi_display_x11_set_synchronous(GstVaapiDisplayX11 *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; + 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; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index 843950b2a9..0593317080 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -67,6 +67,7 @@ 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; @@ -97,6 +98,16 @@ struct _GstVaapiDisplayX11Class { void gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass); +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 */ diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c new file mode 100644 index 0000000000..eed11dd997 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c @@ -0,0 +1,253 @@ +/* + * gstvaapipixmap_x11.c - X11 pixmap abstraction + * + * Copyright (C) 2013 Intel Corporation + * + * 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:gstvaapipixmap_x11 + * @short_description: X11 pixmap abstraction + */ + +#include "sysdeps.h" +#include "gstvaapicompat.h" +#include "gstvaapipixmap_x11.h" +#include "gstvaapipixmap_priv.h" +#include "gstvaapidisplay_x11.h" +#include "gstvaapidisplay_x11_priv.h" +#include "gstvaapiutils.h" +#include "gstvaapiutils_x11.h" +#include "gstvaapisurface_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +typedef struct _GstVaapiPixmapX11Class GstVaapiPixmapX11Class; + +struct _GstVaapiPixmapX11 { + GstVaapiPixmap parent_instance; +}; + +struct _GstVaapiPixmapX11Class { + GstVaapiPixmapClass parent_class; +}; + +static gboolean +gst_vaapi_pixmap_x11_create_from_xid(GstVaapiPixmap *pixmap, Pixmap xid) +{ + guint depth; + gboolean success; + + if (!xid) + return FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(pixmap); + success = x11_get_geometry(GST_VAAPI_OBJECT_XDISPLAY(pixmap), xid, + NULL, NULL, &pixmap->width, &pixmap->height, &depth); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(pixmap); + if (!success) + return FALSE; + + pixmap->format = gst_vaapi_display_x11_get_pixmap_format( + GST_VAAPI_DISPLAY_X11(GST_VAAPI_OBJECT_DISPLAY(pixmap)), depth); + if (pixmap->format == GST_VIDEO_FORMAT_UNKNOWN) + return FALSE; + return TRUE; +} + +static gboolean +gst_vaapi_pixmap_x11_create(GstVaapiPixmap *pixmap) +{ + GstVaapiDisplayX11 * const display = + GST_VAAPI_DISPLAY_X11(GST_VAAPI_OBJECT_DISPLAY(pixmap)); + Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(display); + Window rootwin; + Pixmap xid; + guint depth; + + if (pixmap->use_foreign_pixmap) + return gst_vaapi_pixmap_x11_create_from_xid(pixmap, + GST_VAAPI_OBJECT_ID(pixmap)); + + depth = gst_vaapi_display_x11_get_pixmap_depth(display, pixmap->format); + if (!depth) + return FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(pixmap); + rootwin = RootWindow(dpy, GST_VAAPI_DISPLAY_XSCREEN(display)); + xid = XCreatePixmap(dpy, rootwin, pixmap->width, pixmap->height, depth); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(pixmap); + + GST_DEBUG("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(xid)); + GST_VAAPI_OBJECT_ID(pixmap) = xid; + return xid != None; +} + +static void +gst_vaapi_pixmap_x11_destroy(GstVaapiPixmap *pixmap) +{ + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(pixmap); + const Pixmap xid = GST_VAAPI_OBJECT_ID(pixmap); + + if (xid) { + if (!pixmap->use_foreign_pixmap) { + GST_VAAPI_OBJECT_LOCK_DISPLAY(pixmap); + XFreePixmap(dpy, xid); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(pixmap); + } + GST_VAAPI_OBJECT_ID(pixmap) = None; + } +} + +static gboolean +gst_vaapi_pixmap_x11_render(GstVaapiPixmap *pixmap, GstVaapiSurface *surface, + const GstVaapiRectangle *crop_rect, guint flags) +{ + VASurfaceID surface_id; + VAStatus status; + + surface_id = GST_VAAPI_OBJECT_ID(surface); + if (surface_id == VA_INVALID_ID) + return FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(pixmap); + status = vaPutSurface( + GST_VAAPI_OBJECT_VADISPLAY(pixmap), + surface_id, + GST_VAAPI_OBJECT_ID(pixmap), + crop_rect->x, crop_rect->y, + crop_rect->width, crop_rect->height, + 0, 0, + GST_VAAPI_PIXMAP_WIDTH(pixmap), + GST_VAAPI_PIXMAP_HEIGHT(pixmap), + NULL, 0, + from_GstVaapiSurfaceRenderFlags(flags) + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(pixmap); + if (!vaapi_check_status(status, "vaPutSurface() [pixmap]")) + return FALSE; + return TRUE; +} + +void +gst_vaapi_pixmap_x11_class_init(GstVaapiPixmapX11Class *klass) +{ + GstVaapiObjectClass * const object_class = + GST_VAAPI_OBJECT_CLASS(klass); + GstVaapiPixmapClass * const pixmap_class = + GST_VAAPI_PIXMAP_CLASS(klass); + + object_class->finalize = (GstVaapiObjectFinalizeFunc) + gst_vaapi_pixmap_x11_destroy; + + pixmap_class->create = gst_vaapi_pixmap_x11_create; + pixmap_class->render = gst_vaapi_pixmap_x11_render; +} + +#define gst_vaapi_pixmap_x11_finalize \ + gst_vaapi_pixmap_x11_destroy + +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( + GstVaapiPixmapX11, + gst_vaapi_pixmap_x11, + gst_vaapi_pixmap_x11_class_init(&g_class)) + +/** + * gst_vaapi_pixmap_x11_new: + * @display: a #GstVaapiDisplay + * @format: the requested pixmap format + * @width: the requested pixmap width, in pixels + * @height: the requested windo height, in pixels + * + * Creates a pixmap with the specified @format, @width and + * @height. The pixmap will be attached to the @display. + * + * Return value: the newly allocated #GstVaapiPixmap object + */ +GstVaapiPixmap * +gst_vaapi_pixmap_x11_new(GstVaapiDisplay *display, GstVideoFormat format, + guint width, guint height) +{ + GST_DEBUG("new pixmap, format %s, size %ux%u", + gst_vaapi_video_format_to_string(format), width, height); + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); + + return gst_vaapi_pixmap_new(GST_VAAPI_PIXMAP_CLASS( + gst_vaapi_pixmap_x11_class()), display, format, width, height); +} + +/** + * gst_vaapi_pixmap_x11_new_with_xid: + * @display: a #GstVaapiDisplay + * @xid: an X11 #Pixmap id + * + * Creates a #GstVaapiPixmap using the X11 Pixmap @xid. The caller + * still owns the pixmap and must call XFreePixmap() when all + * #GstVaapiPixmap references are released. Doing so too early can + * yield undefined behaviour. + * + * Return value: the newly allocated #GstVaapiPixmap object + */ +GstVaapiPixmap * +gst_vaapi_pixmap_x11_new_with_xid(GstVaapiDisplay *display, Pixmap xid) +{ + GST_DEBUG("new pixmap from xid 0x%08x", xid); + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); + g_return_val_if_fail(xid != None, NULL); + + return gst_vaapi_pixmap_new_from_native(GST_VAAPI_PIXMAP_CLASS( + gst_vaapi_pixmap_x11_class()), display, GSIZE_TO_POINTER(xid)); +} + +/** + * gst_vaapi_pixmap_x11_get_xid: + * @pixmap: a #GstVaapiPixmapX11 + * + * Returns the underlying X11 Pixmap that was created by + * gst_vaapi_pixmap_x11_new() or that was bound with + * gst_vaapi_pixmap_x11_new_with_xid(). + * + * Return value: the underlying X11 Pixmap bound to @pixmap. + */ +Pixmap +gst_vaapi_pixmap_x11_get_xid(GstVaapiPixmapX11 *pixmap) +{ + g_return_val_if_fail(pixmap != NULL, None); + + return GST_VAAPI_OBJECT_ID(pixmap); +} + +/** + * gst_vaapi_pixmap_x11_is_foreign_xid: + * @pixmap: a #GstVaapiPixmapX11 + * + * Checks whether the @pixmap XID was created by gst_vaapi_pixmap_x11_new() + * or was bound with gst_vaapi_pixmap_x11_new_with_xid(). + * + * Return value: %TRUE if the underlying X pixmap is owned by the + * caller (foreign pixmap) + */ +gboolean +gst_vaapi_pixmap_x11_is_foreign_xid(GstVaapiPixmapX11 *pixmap) +{ + g_return_val_if_fail(pixmap != NULL, FALSE); + + return GST_VAAPI_PIXMAP(pixmap)->use_foreign_pixmap; +} diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.h b/gst-libs/gst/vaapi/gstvaapipixmap_x11.h new file mode 100644 index 0000000000..2c27ad43be --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapipixmap_x11.h @@ -0,0 +1,60 @@ +/* + * gstvaapipixmap_x11.h - X11 pixmap abstraction + * + * Copyright (C) 2013 Intel Corporation + * + * 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_PIXMAP_X11_H +#define GST_VAAPI_PIXMAP_X11_H + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_PIXMAP_X11(obj) \ + ((GstVaapiPixmapX11 *)(obj)) + +/** + * GST_VAAPI_PIXMAP_XPIXMAP: + * @pixmap: a #GstVaapiPixmap + * + * Macro that evaluates to the underlying X11 #Pixmap of @pixmap + */ +#define GST_VAAPI_PIXMAP_XPIXMAP(pixmap) \ + gst_vaapi_pixmap_x11_get_xid(GST_VAAPI_PIXMAP_X11(pixmap)) + +typedef struct _GstVaapiPixmapX11 GstVaapiPixmapX11; + +GstVaapiPixmap * +gst_vaapi_pixmap_x11_new(GstVaapiDisplay *display, GstVideoFormat format, + guint width, guint height); + +GstVaapiPixmap * +gst_vaapi_pixmap_x11_new_with_xid(GstVaapiDisplay *display, Pixmap xid); + +Pixmap +gst_vaapi_pixmap_x11_get_xid(GstVaapiPixmapX11 *pixmap); + +gboolean +gst_vaapi_pixmap_x11_is_foreign_xid(GstVaapiPixmapX11 *pixmap); + +G_END_DECLS + +#endif /* GST_VAAPI_PIXMAP_X11_H */ From 0af0849a92cf0a9db2fe92038c8466f5f3e636fe Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Jul 2013 09:00:38 +0200 Subject: [PATCH 1280/3781] x11: implement pixmap rendering with RENDER extension. Use hardware accelerated XRenderComposite() function, from the RENDER extension, to blit a pixmap to screen. Besides, this can also support cropping and scaling. --- configure.ac | 17 +++ gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 18 ++- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 12 ++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 124 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 8 ++ 6 files changed, 176 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 6e033e82f8..837ea1066c 100644 --- a/configure.ac +++ b/configure.ac @@ -470,6 +470,23 @@ if test $HAVE_XRANDR -eq 1; then [Defined to 1 if the XRandR extension exists.]) fi +dnl Check for XRender +HAVE_XRENDER=0 +if test $USE_X11 -eq 1; then + HAVE_XRENDER=1 + PKG_CHECK_MODULES([XRENDER], [xrender], [:], [HAVE_XRENDER=0]) + if test $HAVE_XRENDER -eq 1; then + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $XRENDER_CFLAGS" + AC_CHECK_HEADERS([X11/extensions/Xrender.h], [:], [HAVE_XRENDER=0]) + CPPFLAGS="$saved_CPPFLAGS" + fi +fi +if test $HAVE_XRENDER -eq 1; then + AC_DEFINE_UNQUOTED([HAVE_XRENDER], [1], + [Defined to 1 if the XRender extension exists.]) +fi + dnl OpenGL enable_opengl="no" if test "$enable_glx" = "yes"; then diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index b2a5df56f8..d4fa2485ae 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -289,6 +289,7 @@ libgstvaapi_x11_@GST_API_VERSION@_la_CFLAGS = \ $(GST_BASE_CFLAGS) \ $(X11_CFLAGS) \ $(XRANDR_CFLAGS) \ + $(XRENDER_CFLAGS) \ $(LIBVA_X11_CFLAGS) \ $(NULL) @@ -296,6 +297,7 @@ libgstvaapi_x11_@GST_API_VERSION@_la_LIBADD = \ $(GLIB_LIBS) \ $(X11_LIBS) \ $(XRANDR_LIBS) \ + $(XRENDER_LIBS) \ $(LIBVA_X11_LIBS) \ libgstvaapi-$(GST_API_VERSION).la \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 5fb0cba265..b633b1a6cb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -36,6 +36,10 @@ # include #endif +#ifdef HAVE_XRENDER +# include +#endif + #define DEBUG 1 #include "gstvaapidebug.h" @@ -130,18 +134,22 @@ set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous) } } -/* Check whether XRANDR extension is available */ +/* Check for display server extensions */ static void -check_xrandr(GstVaapiDisplayX11 *display) +check_extensions(GstVaapiDisplayX11 *display) { -#ifdef HAVE_XRANDR GstVaapiDisplayX11Private * const priv = GST_VAAPI_DISPLAY_X11_PRIVATE(display); int evt_base, err_base; +#ifdef HAVE_XRANDR priv->use_xrandr = XRRQueryExtension(priv->x11_display, &evt_base, &err_base); #endif +#ifdef HAVE_XRENDER + priv->has_xrender = XRenderQueryExtension(priv->x11_display, + &evt_base, &err_base); +#endif } static gboolean @@ -156,7 +164,7 @@ gst_vaapi_display_x11_bind_display(GstVaapiDisplay *base_display, priv->x11_screen = DefaultScreen(native_display); priv->use_foreign_display = TRUE; - check_xrandr(display); + check_extensions(display); if (!set_display_name(display, XDisplayString(priv->x11_display))) return FALSE; @@ -193,7 +201,7 @@ gst_vaapi_display_x11_open_display(GstVaapiDisplay *base_display, } priv->x11_screen = DefaultScreen(priv->x11_display); - check_xrandr(display); + check_extensions(display); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index 0593317080..45494bc8aa 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -63,6 +63,17 @@ typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class; #define GST_VAAPI_DISPLAY_XSCREEN(display) \ GST_VAAPI_DISPLAY_X11_PRIVATE(display)->x11_screen +/** + * GST_VAAPI_DISPLAY_HAS_XRENDER: + * @display: a #GstVaapiDisplay + * + * Macro that evaluates to the existence of the XRender extension on + * @display server. + */ +#undef GST_VAAPI_DISPLAY_HAS_XRENDER +#define GST_VAAPI_DISPLAY_HAS_XRENDER(display) \ + (GST_VAAPI_DISPLAY_X11_PRIVATE(display)->has_xrender) + struct _GstVaapiDisplayX11Private { gchar *display_name; Display *x11_display; @@ -70,6 +81,7 @@ struct _GstVaapiDisplayX11Private { GArray *pixmap_formats; guint use_foreign_display : 1; // Foreign native_display? guint use_xrandr : 1; + guint has_xrender : 1; // Has XRender extension? guint synchronous : 1; }; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index a5ea27752e..df58ef20cf 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -31,6 +31,8 @@ #include "gstvaapicompat.h" #include "gstvaapiwindow_x11.h" #include "gstvaapiwindow_x11_priv.h" +#include "gstvaapipixmap_x11.h" +#include "gstvaapipixmap_priv.h" #include "gstvaapidisplay_x11.h" #include "gstvaapidisplay_x11_priv.h" #include "gstvaapiutils.h" @@ -223,6 +225,9 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) "_NET_WM_STATE_FULLSCREEN", }; + priv->has_xrender = GST_VAAPI_DISPLAY_HAS_XRENDER( + GST_VAAPI_OBJECT_DISPLAY(window)); + if (window->use_foreign_window && xid) { GST_VAAPI_OBJECT_LOCK_DISPLAY(window); XGetWindowAttributes(dpy, xid, &wattr); @@ -266,6 +271,17 @@ gst_vaapi_window_x11_destroy(GstVaapiWindow *window) Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); const Window xid = GST_VAAPI_OBJECT_ID(window); +#ifdef HAVE_XRENDER + GstVaapiWindowX11Private * const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); + if (priv->picture) { + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + XRenderFreePicture(dpy, priv->picture); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + priv->picture = None; + } +#endif + if (xid) { if (!window->use_foreign_window) { GST_VAAPI_OBJECT_LOCK_DISPLAY(window); @@ -434,6 +450,113 @@ gst_vaapi_window_x11_render( return TRUE; } +static gboolean +gst_vaapi_window_x11_render_pixmap_xrender( + GstVaapiWindow *window, + GstVaapiPixmap *pixmap, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect +) +{ +#ifdef HAVE_XRENDER + GstVaapiWindowX11Private * const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); + Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + const Window win = GST_VAAPI_OBJECT_ID(window); + const Pixmap pix = GST_VAAPI_OBJECT_ID(pixmap); + Picture picture; + XRenderPictFormat *pic_fmt; + XWindowAttributes wattr; + int fmt, op; + gboolean success = FALSE; + + /* Ensure Picture for window is created */ + if (!priv->picture) { + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + XGetWindowAttributes(dpy, win, &wattr); + pic_fmt = XRenderFindVisualFormat(dpy, wattr.visual); + if (pic_fmt) + priv->picture = XRenderCreatePicture(dpy, win, pic_fmt, 0, NULL); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + if (!priv->picture) + return FALSE; + } + + /* Check pixmap format */ + switch (GST_VAAPI_PIXMAP_FORMAT(pixmap)) { + case GST_VIDEO_FORMAT_xRGB: + fmt = PictStandardRGB24; + op = PictOpSrc; + goto get_pic_fmt; + case GST_VIDEO_FORMAT_ARGB: + fmt = PictStandardARGB32; + op = PictOpOver; + get_pic_fmt: + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + pic_fmt = XRenderFindStandardFormat(dpy, fmt); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + break; + default: + pic_fmt = NULL; + break; + } + if (!pic_fmt) + return FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + do { + const double sx = (double)src_rect->width / dst_rect->width; + const double sy = (double)src_rect->height / dst_rect->height; + XTransform xform; + + picture = XRenderCreatePicture(dpy, pix, pic_fmt, 0, NULL); + if (!picture) + break; + + xform.matrix[0][0] = XDoubleToFixed(sx); + xform.matrix[0][1] = XDoubleToFixed(0.0); + xform.matrix[0][2] = XDoubleToFixed(src_rect->x); + xform.matrix[1][0] = XDoubleToFixed(0.0); + xform.matrix[1][1] = XDoubleToFixed(sy); + xform.matrix[1][2] = XDoubleToFixed(src_rect->y); + xform.matrix[2][0] = XDoubleToFixed(0.0); + xform.matrix[2][1] = XDoubleToFixed(0.0); + xform.matrix[2][2] = XDoubleToFixed(1.0); + XRenderSetPictureTransform(dpy, picture, &xform); + + XRenderComposite(dpy, op, picture, None, priv->picture, + 0, 0, 0, 0, dst_rect->x, dst_rect->y, + dst_rect->width, dst_rect->height); + XSync(dpy, False); + success = TRUE; + } while (0); + if (picture) + XRenderFreePicture(dpy, picture); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + return success; +#endif + return FALSE; +} + +static gboolean +gst_vaapi_window_x11_render_pixmap( + GstVaapiWindow *window, + GstVaapiPixmap *pixmap, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect +) +{ + GstVaapiWindowX11Private * const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); + + if (priv->has_xrender) + return gst_vaapi_window_x11_render_pixmap_xrender(window, pixmap, + src_rect, dst_rect); + + /* XXX: only X RENDER extension is supported for now */ + return FALSE; +} + void gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) { @@ -452,6 +575,7 @@ gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) window_class->set_fullscreen = gst_vaapi_window_x11_set_fullscreen; window_class->resize = gst_vaapi_window_x11_resize; window_class->render = gst_vaapi_window_x11_render; + window_class->render_pixmap = gst_vaapi_window_x11_render_pixmap; } #define gst_vaapi_window_x11_finalize \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index 2622ac8147..c5bebb64ce 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -25,6 +25,10 @@ #include "gstvaapiwindow_priv.h" +#ifdef HAVE_XRENDER +# include +#endif + G_BEGIN_DECLS #define GST_VAAPI_WINDOW_X11_GET_PRIVATE(obj) \ @@ -42,8 +46,12 @@ typedef struct _GstVaapiWindowX11Class GstVaapiWindowX11Class; struct _GstVaapiWindowX11Private { Atom atom_NET_WM_STATE; Atom atom_NET_WM_STATE_FULLSCREEN; +#ifdef HAVE_XRENDER + Picture picture; +#endif guint is_mapped : 1; guint fullscreen_on_map : 1; + guint has_xrender : 1; }; /** From 155af03491557edc8bc3a94b47ea63c36cca47aa Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Jul 2013 09:03:30 +0200 Subject: [PATCH 1281/3781] tests: add support for render-to-pixmap. Add --pixmap option to test-decode so that to allow copies of VA surface to an intermediate pixmap and rendering from that pixmap. Only X11 backends are supported for now. --- tests/output.c | 16 ++++++++++++++-- tests/output.h | 9 +++++++++ tests/test-decode.c | 32 +++++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/tests/output.c b/tests/output.c index 5fa7e5a14a..6a54f3b53d 100644 --- a/tests/output.c +++ b/tests/output.c @@ -29,6 +29,7 @@ #if USE_X11 # include # include +# include #endif #if USE_GLX # include @@ -52,13 +53,15 @@ static const VideoOutputInfo g_video_outputs[] = { #if USE_X11 { "x11", gst_vaapi_display_x11_new, - gst_vaapi_window_x11_new + gst_vaapi_window_x11_new, + gst_vaapi_pixmap_x11_new }, #endif #if USE_GLX { "glx", gst_vaapi_display_glx_new, - gst_vaapi_window_glx_new + gst_vaapi_window_glx_new, + gst_vaapi_pixmap_x11_new }, #endif #if USE_DRM @@ -200,3 +203,12 @@ video_output_create_window(GstVaapiDisplay *display, guint width, guint height) gst_vaapi_window_set_fullscreen(window, TRUE); return window; } + +GstVaapiPixmap * +video_output_create_pixmap(GstVaapiDisplay *display, GstVideoFormat format, + guint width, guint height) +{ + if (!g_video_output || !g_video_output->create_pixmap) + return NULL; + return g_video_output->create_pixmap(display, format, width, height); +} diff --git a/tests/output.h b/tests/output.h index 3377915491..29339c5a7a 100644 --- a/tests/output.h +++ b/tests/output.h @@ -25,16 +25,21 @@ #include #include #include +#include typedef GstVaapiDisplay *(*CreateDisplayFunc)(const gchar *display_name); typedef GstVaapiWindow *(*CreateWindowFunc)(GstVaapiDisplay *display, guint width, guint height); +typedef GstVaapiPixmap *(*CreatePixmapFunc)(GstVaapiDisplay *display, + GstVideoFormat format, guint width, guint height); + typedef struct _VideoOutputInfo VideoOutputInfo; struct _VideoOutputInfo { const gchar *name; CreateDisplayFunc create_display; CreateWindowFunc create_window; + CreatePixmapFunc create_pixmap; }; gboolean @@ -52,4 +57,8 @@ video_output_create_display(const gchar *display_name); GstVaapiWindow * video_output_create_window(GstVaapiDisplay *display, guint width, guint height); +GstVaapiPixmap * +video_output_create_pixmap(GstVaapiDisplay *display, GstVideoFormat format, + guint width, guint height); + #endif /* OUTPUT_H */ diff --git a/tests/test-decode.c b/tests/test-decode.c index cff76122be..8790a6e405 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -36,12 +36,17 @@ static inline void pause(void) } static gchar *g_codec_str; +static gboolean g_use_pixmap; static GOptionEntry g_options[] = { { "codec", 'c', 0, G_OPTION_ARG_STRING, &g_codec_str, "codec to test", NULL }, + { "pixmap", 0, + 0, + G_OPTION_ARG_NONE, &g_use_pixmap, + "use render-to-pixmap", NULL }, { NULL, } }; @@ -50,6 +55,7 @@ main(int argc, char *argv[]) { GstVaapiDisplay *display, *display2; GstVaapiWindow *window; + GstVaapiPixmap *pixmap = NULL; GstVaapiDecoder *decoder; GstVaapiSurfaceProxy *proxy; GstVaapiSurface *surface; @@ -96,12 +102,36 @@ main(int argc, char *argv[]) gst_vaapi_window_show(window); - if (!gst_vaapi_window_put_surface(window, surface, crop_rect, NULL, + if (g_use_pixmap) { + guint width, height; + + if (crop_rect) { + width = crop_rect->width; + height = crop_rect->height; + } + else + gst_vaapi_surface_get_size(surface, &width, &height); + + pixmap = video_output_create_pixmap(display, GST_VIDEO_FORMAT_xRGB, + width, height); + if (!pixmap) + g_error("could not create pixmap"); + + if (!gst_vaapi_pixmap_put_surface(pixmap, surface, crop_rect, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + g_error("could not render to pixmap"); + + if (!gst_vaapi_window_put_pixmap(window, pixmap, NULL, NULL)) + g_error("could not render pixmap"); + } + else if (!gst_vaapi_window_put_surface(window, surface, crop_rect, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) g_error("could not render surface"); pause(); + if (pixmap) + gst_vaapi_pixmap_unref(pixmap); gst_vaapi_surface_proxy_unref(proxy); gst_vaapi_decoder_unref(decoder); gst_vaapi_window_unref(window); From 2e85860c9c63829ee2af1544dfd1f27648a32d64 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Jul 2013 09:12:21 +0200 Subject: [PATCH 1282/3781] tests: simple-decoder: add support for video cropping. Handle video cropping information attached to a VA surface proxy. --- tests/simple-decoder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index 3cf46cc078..307bb1861e 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -435,6 +435,7 @@ renderer_process(App *app, RenderFrame *rfp) { GError *error = NULL; GstVaapiSurface *surface; + const GstVaapiRectangle *crop_rect; #define SEND_ERROR(...) \ do { \ @@ -454,7 +455,8 @@ renderer_process(App *app, RenderFrame *rfp) if (G_LIKELY(!g_benchmark)) renderer_wait_until(app, rfp->pts); - if (!gst_vaapi_window_put_surface(app->window, surface, NULL, NULL, + crop_rect = gst_vaapi_surface_proxy_get_crop_rect(rfp->proxy); + if (!gst_vaapi_window_put_surface(app->window, surface, crop_rect, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) SEND_ERROR("failed to render surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); From 17c8f17d06d99d8e90b83966ad3268dd48ffc1b2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Jul 2013 09:36:08 +0200 Subject: [PATCH 1283/3781] tests: simple-decoder: add support for pixmap API. Add support for the new render-to-pixmap API. Avoid flickering on platforms supporting video overlay by keeping up to 2 intermediate pixmaps. --- tests/simple-decoder.c | 74 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index 307bb1861e..5b50c87752 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -34,10 +34,12 @@ #include #include #include +#include #include "codec.h" #include "output.h" static gchar *g_codec_str; +static gboolean g_use_pixmap; static gboolean g_benchmark; static GOptionEntry g_options[] = { @@ -45,6 +47,10 @@ static GOptionEntry g_options[] = { 0, G_OPTION_ARG_STRING, &g_codec_str, "suggested codec", NULL }, + { "pixmap", 0, + 0, + G_OPTION_ARG_NONE, &g_use_pixmap, + "use render-to-pixmap", NULL }, { "benchmark", 0, 0, G_OPTION_ARG_NONE, &g_benchmark, @@ -89,6 +95,10 @@ typedef struct { guint32 frame_duration; guint surface_width; guint surface_height; + GstVaapiPixmap *pixmaps[2]; + guint pixmap_id; + guint pixmap_width; + guint pixmap_height; GstVaapiWindow *window; guint window_width; guint window_height; @@ -421,6 +431,44 @@ ensure_window_size(App *app, GstVaapiSurface *surface) &app->window_width, &app->window_height); } +static gboolean +ensure_pixmaps(App *app, GstVaapiSurface *surface, + const GstVaapiRectangle *crop_rect) +{ + GstVaapiPixmap *pixmaps[G_N_ELEMENTS(app->pixmaps)]; + guint num_pixmaps, i, width, height; + gboolean success = FALSE; + + if (crop_rect) { + width = crop_rect->width; + height = crop_rect->height; + } + else + gst_vaapi_surface_get_size(surface, &width, &height); + if (app->pixmap_width == width && app->pixmap_height == height) + return TRUE; + + for (i = 0, num_pixmaps = 0; i < G_N_ELEMENTS(pixmaps); i++) { + GstVaapiPixmap * const pixmap = + video_output_create_pixmap(app->display, GST_VIDEO_FORMAT_xRGB, + width, height); + if (!pixmap) + goto end; + pixmaps[num_pixmaps++] = pixmap; + } + + for (i = 0; i < num_pixmaps; i++) + gst_vaapi_pixmap_replace(&app->pixmaps[i], pixmaps[i]); + app->pixmap_width = width; + app->pixmap_height = height; + success = TRUE; + +end: + for (i = 0; i < num_pixmaps; i++) + gst_vaapi_pixmap_replace(&pixmaps[i], NULL); + return success; +} + static inline void renderer_wait_until(App *app, GstClockTime pts) { @@ -449,15 +497,31 @@ renderer_process(App *app, RenderFrame *rfp) ensure_window_size(app, surface); + crop_rect = gst_vaapi_surface_proxy_get_crop_rect(rfp->proxy); + if (!ensure_pixmaps(app, surface, crop_rect)) + SEND_ERROR("failed to create intermediate pixmaps"); + if (!gst_vaapi_surface_sync(surface)) SEND_ERROR("failed to sync decoded surface"); if (G_LIKELY(!g_benchmark)) renderer_wait_until(app, rfp->pts); - crop_rect = gst_vaapi_surface_proxy_get_crop_rect(rfp->proxy); - if (!gst_vaapi_window_put_surface(app->window, surface, crop_rect, NULL, - GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + if (G_UNLIKELY(g_use_pixmap)) { + GstVaapiPixmap * const pixmap = app->pixmaps[app->pixmap_id]; + + if (!gst_vaapi_pixmap_put_surface(pixmap, surface, crop_rect, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + SEND_ERROR("failed to render to pixmap"); + + if (!gst_vaapi_window_put_pixmap(app->window, pixmap, NULL, NULL)) + SEND_ERROR("failed to render surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(pixmap)); + + app->pixmap_id = (app->pixmap_id + 1) % G_N_ELEMENTS(app->pixmaps); + } + else if (!gst_vaapi_window_put_surface(app->window, surface, + crop_rect, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) SEND_ERROR("failed to render surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); @@ -528,6 +592,8 @@ stop_renderer(App *app) static void app_free(App *app) { + guint i; + if (!app) return; @@ -537,6 +603,8 @@ app_free(App *app) } g_free(app->file_name); + for (i = 0; i < G_N_ELEMENTS(app->pixmaps); i++) + gst_vaapi_pixmap_replace(&app->pixmaps[i], NULL); gst_vaapi_decoder_replace(&app->decoder, NULL); gst_vaapi_window_replace(&app->window, NULL); gst_vaapi_display_replace(&app->display, NULL); From 6f04a529059a548eb697ebe176ce5d165f28382e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Jul 2013 11:58:33 +0200 Subject: [PATCH 1284/3781] plugins: add support for "x11-pixmap" video converter type. Install a new video converter that supports X11 pixmap targets for X11 backends only, or make the GLX converter creation function chain up to the X11 converter whenever requested. --- gst/vaapi/Makefile.am | 8 ++ gst/vaapi/gstvaapivideobuffer.c | 25 +++- gst/vaapi/gstvaapivideoconverter_glx.c | 5 +- gst/vaapi/gstvaapivideoconverter_x11.c | 179 +++++++++++++++++++++++++ gst/vaapi/gstvaapivideoconverter_x11.h | 91 +++++++++++++ 5 files changed, 305 insertions(+), 3 deletions(-) create mode 100644 gst/vaapi/gstvaapivideoconverter_x11.c create mode 100644 gst/vaapi/gstvaapivideoconverter_x11.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index bd9dedd4d8..1b894670bb 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -50,6 +50,14 @@ libgstvaapi_source_h = \ gstvaapivideometa.h \ $(NULL) +libgstvaapi_x11_source_c = gstvaapivideoconverter_x11.c +libgstvaapi_x11_source_h = gstvaapivideoconverter_x11.h + +if USE_X11 +libgstvaapi_source_c += $(libgstvaapi_x11_source_c) +libgstvaapi_source_h += $(libgstvaapi_x11_source_h) +endif + libgstvaapi_glx_source_c = gstvaapivideoconverter_glx.c libgstvaapi_glx_source_h = gstvaapivideoconverter_glx.h diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 1d4ec80573..583f49ffeb 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -27,6 +27,9 @@ #include "gst/vaapi/sysdeps.h" #include "gstvaapivideobuffer.h" +#if USE_X11 +# include "gstvaapivideoconverter_x11.h" +#endif #if USE_GLX # include "gstvaapivideoconverter_glx.h" #endif @@ -50,6 +53,21 @@ gst_vaapi_surface_meta_get_info(void); typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc)( GstSurfaceMeta *meta, const gchar *type, GValue *dest); +#if USE_X11 +static GstSurfaceConverter * +gst_vaapi_surface_create_converter_x11(GstSurfaceMeta *base_meta, + const gchar *type, GValue *dest) +{ + GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta); + + return gst_vaapi_video_converter_x11_new(meta->buffer, type, dest); +} + +#undef gst_vaapi_video_converter_x11_new +#define gst_vaapi_video_converter_x11_new \ + gst_vaapi_surface_create_converter_x11 +#endif + #if USE_GLX static GstSurfaceConverter * gst_vaapi_surface_create_converter_glx(GstSurfaceMeta *base_meta, @@ -60,7 +78,7 @@ gst_vaapi_surface_create_converter_glx(GstSurfaceMeta *base_meta, return gst_vaapi_video_converter_glx_new(meta->buffer, type, dest); } -#undef gst_vaapi_video_converter_glx_new +#undef gst_vaapi_video_converter_glx_new #define gst_vaapi_video_converter_glx_new \ gst_vaapi_surface_create_converter_glx #endif @@ -244,6 +262,11 @@ get_surface_converter(GstVaapiDisplay *display) GFunc func; switch (gst_vaapi_display_get_display_type(display)) { +#if USE_X11 + case GST_VAAPI_DISPLAY_TYPE_X11: + func = (GFunc)gst_vaapi_video_converter_x11_new; + break; +#endif #if USE_GLX case GST_VAAPI_DISPLAY_TYPE_GLX: func = (GFunc)gst_vaapi_video_converter_glx_new; diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index aaa9c35060..f2c5c5dae9 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -24,6 +24,7 @@ #include "gst/vaapi/sysdeps.h" #include #include "gstvaapivideoconverter_glx.h" +#include "gstvaapivideoconverter_x11.h" #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" @@ -112,9 +113,9 @@ gst_vaapi_video_converter_glx_new(GstBuffer *buffer, const gchar *type, GstVaapiTexture *texture; GstVaapiVideoConverterGLX *converter; - /* We only support Open GL texture conversion */ + /* Check for "opengl" request, or chain up to X11 converter */ if (strcmp(type, "opengl") != 0 || !G_VALUE_HOLDS_UINT(dest)) - return NULL; + return gst_vaapi_video_converter_x11_new(buffer, type, dest); /* FIXME Should we assume target and format ? */ texture = gst_vaapi_texture_new_with_texture( diff --git a/gst/vaapi/gstvaapivideoconverter_x11.c b/gst/vaapi/gstvaapivideoconverter_x11.c new file mode 100644 index 0000000000..18f4e56aad --- /dev/null +++ b/gst/vaapi/gstvaapivideoconverter_x11.c @@ -0,0 +1,179 @@ +/* + * gstvaapivideoconverter_x11.h - VA video converter to X11 pixmap + * + * Copyright (C) 2013 Intel Corporation + * + * 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 "gst/vaapi/sysdeps.h" +#include +#include "gstvaapivideoconverter_x11.h" +#include "gstvaapipluginutil.h" +#include "gstvaapivideometa.h" + +#if GST_CHECK_VERSION(1,0,0) +typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *, + GstBuffer *); +#else +typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *, + GstSurfaceBuffer *); +#endif + +static void +gst_vaapi_video_converter_x11_iface_init(GstSurfaceConverterInterface *iface); + +G_DEFINE_TYPE_WITH_CODE( + GstVaapiVideoConverterX11, + gst_vaapi_video_converter_x11, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(GST_TYPE_SURFACE_CONVERTER, + gst_vaapi_video_converter_x11_iface_init)) + +#define GST_VAAPI_VIDEO_CONVERTER_X11_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ + GstVaapiVideoConverterX11Private)) + +struct _GstVaapiVideoConverterX11Private { + GstVaapiPixmap *pixmap; + XID pixmap_id; +}; + +static gboolean +gst_vaapi_video_converter_x11_upload(GstSurfaceConverter *self, + GstBuffer *buffer); + +static void +gst_vaapi_video_converter_x11_dispose(GObject *object) +{ + GstVaapiVideoConverterX11Private * const priv = + GST_VAAPI_VIDEO_CONVERTER_X11(object)->priv; + + gst_vaapi_pixmap_replace(&priv->pixmap, NULL); + + G_OBJECT_CLASS(gst_vaapi_video_converter_x11_parent_class)->dispose(object); +} + +static void +gst_vaapi_video_converter_x11_class_init(GstVaapiVideoConverterX11Class *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiVideoConverterX11Private)); + + object_class->dispose = gst_vaapi_video_converter_x11_dispose; +} + +static void +gst_vaapi_video_converter_x11_init(GstVaapiVideoConverterX11 *buffer) +{ + buffer->priv = GST_VAAPI_VIDEO_CONVERTER_X11_GET_PRIVATE(buffer); +} + +static void +gst_vaapi_video_converter_x11_iface_init(GstSurfaceConverterInterface *iface) +{ + iface->upload = (GstSurfaceUploadFunction) + gst_vaapi_video_converter_x11_upload; +} + +static gboolean +set_pixmap(GstVaapiVideoConverterX11 *converter, GstVaapiDisplay *display, + XID pixmap_id) +{ + GstVaapiVideoConverterX11Private * const priv = converter->priv; + GstVaapiPixmap *pixmap; + + pixmap = gst_vaapi_pixmap_x11_new_with_xid(display, pixmap_id); + if (!pixmap) + return FALSE; + + gst_vaapi_pixmap_replace(&priv->pixmap, pixmap); + gst_vaapi_pixmap_unref(pixmap); + priv->pixmap_id = pixmap_id; + return TRUE; +} + +/** + * gst_vaapi_video_converter_x11_new: + * @surface: the #GstSurfaceBuffer + * @type: type of the target buffer (must be "x11-pixmap") + * @dest: target of the conversion (must be an X11 pixmap id) + * + * Creates an empty #GstBuffer. The caller is responsible for + * completing the initialization of the buffer with the + * gst_vaapi_video_converter_x11_set_*() functions. + * + * Return value: the newly allocated #GstBuffer, or %NULL on error + */ +GstSurfaceConverter * +gst_vaapi_video_converter_x11_new(GstBuffer *buffer, const gchar *type, + GValue *dest) +{ + GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); + GstVaapiVideoConverterX11 *converter; + + /* We only support X11 pixmap conversion */ + if (strcmp(type, "x11-pixmap") != 0 || !G_VALUE_HOLDS_UINT(dest)) + return NULL; + + converter = g_object_new(GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, NULL); + if (!converter) + return NULL; + + if (!set_pixmap(converter, gst_vaapi_video_meta_get_display(meta), + g_value_get_uint(dest))) + goto error; + return GST_SURFACE_CONVERTER(converter); + +error: + g_object_unref(converter); + return NULL; +} + +gboolean +gst_vaapi_video_converter_x11_upload(GstSurfaceConverter *self, + GstBuffer *buffer) +{ + GstVaapiVideoConverterX11 * const converter = + GST_VAAPI_VIDEO_CONVERTER_X11(self); + GstVaapiVideoConverterX11Private * const priv = converter->priv; + GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); + GstVaapiSurface *surface; + GstVaapiDisplay *old_display, *new_display; + + g_return_val_if_fail(meta != NULL, FALSE); + + surface = gst_vaapi_video_meta_get_surface(meta); + if (!surface) + return FALSE; + + old_display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(priv->pixmap)); + new_display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); + + if (old_display != new_display) { + if (!set_pixmap(converter, new_display, priv->pixmap_id)) + return FALSE; + } + + if (!gst_vaapi_apply_composition(surface, buffer)) + GST_WARNING("could not update subtitles"); + + /* XXX: handle video cropping */ + return gst_vaapi_pixmap_put_surface(priv->pixmap, surface, NULL, + gst_vaapi_video_meta_get_render_flags(meta)); +} diff --git a/gst/vaapi/gstvaapivideoconverter_x11.h b/gst/vaapi/gstvaapivideoconverter_x11.h new file mode 100644 index 0000000000..be991b3ab3 --- /dev/null +++ b/gst/vaapi/gstvaapivideoconverter_x11.h @@ -0,0 +1,91 @@ +/* + * gstvaapivideoconverter_x11.h - VA video converter to X11 pixmap + * + * Copyright (C) 2013 Intel Corporation + * + * 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_VIDEO_CONVERTER_X11_H +#define GST_VAAPI_VIDEO_CONVERTER_X11_H + +#include +#include "gstvaapivideobuffer.h" + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_VIDEO_CONVERTER_X11 \ + (gst_vaapi_video_converter_x11_get_type ()) + +#define GST_VAAPI_VIDEO_CONVERTER_X11(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ + GstVaapiVideoConverterX11)) + +#define GST_VAAPI_VIDEO_CONVERTER_X11_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ + GstVaapiVideoConverterX11Class)) + +#define GST_VAAPI_IS_VIDEO_CONVERTER_X11(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11)) + +#define GST_VAAPI_IS_VIDEO_CONVERTER_X11_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11)) + +#define GST_VAAPI_VIDEO_CONVERTER_X11_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ + GstVaapiVideoConverterX11Class)) + +typedef struct _GstVaapiVideoConverterX11 GstVaapiVideoConverterX11; +typedef struct _GstVaapiVideoConverterX11Private GstVaapiVideoConverterX11Private; +typedef struct _GstVaapiVideoConverterX11Class GstVaapiVideoConverterX11Class; + +/** + * GstVaapiVideoConverterX11: + * + * Converter to transform VA buffers into GL textures. + */ +struct _GstVaapiVideoConverterX11 { + /*< private >*/ + GObject parent_instance; + + GstVaapiVideoConverterX11Private *priv; +}; + +/** + * GstVaapiVideoConverterX11Class: + * + * Converter class to transform VA buffers into GL textures. + */ +struct _GstVaapiVideoConverterX11Class { + /*< private >*/ + GObjectClass parent_class; +}; + +G_GNUC_INTERNAL +GType +gst_vaapi_video_converter_x11_get_type(void) G_GNUC_CONST; + +G_GNUC_INTERNAL +GstSurfaceConverter * +gst_vaapi_video_converter_x11_new(GstBuffer *buffer, const gchar *type, + GValue *dest); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_CONVERTER_X11_H */ From 0b1a97cbf93846eb7cc03d46d0eb8a04244fb8ab Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Jul 2013 14:53:51 +0200 Subject: [PATCH 1285/3781] plugins: handle video cropping in X11 pixmap converter. Use GstVideoCropMeta in GStreamer 1.0 or any other render rectangle we could decode from the stream. --- gst/vaapi/gstvaapivideoconverter_x11.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideoconverter_x11.c b/gst/vaapi/gstvaapivideoconverter_x11.c index 18f4e56aad..9de2df2bac 100644 --- a/gst/vaapi/gstvaapivideoconverter_x11.c +++ b/gst/vaapi/gstvaapivideoconverter_x11.c @@ -153,6 +153,7 @@ gst_vaapi_video_converter_x11_upload(GstSurfaceConverter *self, GST_VAAPI_VIDEO_CONVERTER_X11(self); GstVaapiVideoConverterX11Private * const priv = converter->priv; GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); + const GstVaapiRectangle *crop_rect = NULL; GstVaapiSurface *surface; GstVaapiDisplay *old_display, *new_display; @@ -173,7 +174,20 @@ gst_vaapi_video_converter_x11_upload(GstSurfaceConverter *self, if (!gst_vaapi_apply_composition(surface, buffer)) GST_WARNING("could not update subtitles"); - /* XXX: handle video cropping */ - return gst_vaapi_pixmap_put_surface(priv->pixmap, surface, NULL, +#if GST_CHECK_VERSION(1,0,0) + GstVideoCropMeta * const crop_meta = gst_buffer_get_video_crop_meta(buffer); + if (crop_meta) { + GstVaapiRectangle crop_rect_tmp; + crop_rect = &crop_rect_tmp; + crop_rect_tmp.x = crop_meta->x; + crop_rect_tmp.y = crop_meta->y; + crop_rect_tmp.width = crop_meta->width; + crop_rect_tmp.height = crop_meta->height; + } +#endif + if (!crop_rect) + crop_rect = gst_vaapi_video_meta_get_render_rect(meta); + + return gst_vaapi_pixmap_put_surface(priv->pixmap, surface, crop_rect, gst_vaapi_video_meta_get_render_flags(meta)); } From e183ea12908465f1a05e68d5b9e4cd9a941880fb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 26 Jul 2013 11:43:49 +0200 Subject: [PATCH 1286/3781] image: add gst_vaapi_image_copy() helper. Add gst_vaapi_image_copy() helper function to copy images of same format and size. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapiimage.c | 32 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiimage.h | 3 +++ 3 files changed, 36 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index e619f19cfb..9b005e61d2 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -228,6 +228,7 @@ gst_vaapi_image_get_data_size gst_vaapi_image_get_buffer gst_vaapi_image_get_raw gst_vaapi_image_update_from_buffer +gst_vaapi_image_copy GST_VAAPI_IMAGE
diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 30df81da94..3ddf124083 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -1116,3 +1116,35 @@ gst_vaapi_image_update_from_raw( return success; } + +/** + * gst_vaapi_image_copy: + * @dst_image: the target #GstVaapiImage + * @src_image: the source #GstVaapiImage + * + * Copies pixels data from @src_image to @dst_image. Both images shall + * have the same format and size. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_image_copy(GstVaapiImage *dst_image, GstVaapiImage *src_image) +{ + GstVaapiImageRaw dst_image_raw, src_image_raw; + gboolean success = FALSE; + + g_return_val_if_fail(dst_image != NULL, FALSE); + g_return_val_if_fail(src_image != NULL, FALSE); + + if (!_gst_vaapi_image_map(dst_image, &dst_image_raw)) + goto end; + if (!_gst_vaapi_image_map(src_image, &src_image_raw)) + goto end; + + success = copy_image(&dst_image_raw, &src_image_raw, NULL); + +end: + _gst_vaapi_image_unmap(src_image); + _gst_vaapi_image_unmap(dst_image); + return success; +} diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 94eff61362..124bdad54d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -156,6 +156,9 @@ gst_vaapi_image_update_from_raw( GstVaapiRectangle *rect ); +gboolean +gst_vaapi_image_copy(GstVaapiImage *dst_image, GstVaapiImage *src_image); + G_END_DECLS #endif /* GST_VAAPI_IMAGE_H */ From 2b0a4a03046ed3c71aeeee908b42ba5bd480fa9c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 26 Jul 2013 12:57:19 +0200 Subject: [PATCH 1287/3781] image: clean image API up. Don't expose functions that reference a GstVaapiImageRaw, those are meant to be internal only for implementing subpictures sync. Also add a few private definitions to avoid functions calls for retrieving image size and format information. --- docs/reference/libs/libs-sections.txt | 1 - gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapiimage.c | 32 +----- gst-libs/gst/vaapi/gstvaapiimage.h | 30 ------ gst-libs/gst/vaapi/gstvaapiimage_priv.h | 126 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisubpicture.c | 3 +- gst-libs/gst/vaapi/gstvaapisurface.c | 16 +-- 7 files changed, 138 insertions(+), 71 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiimage_priv.h diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 9b005e61d2..3c1b03aa9e 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -226,7 +226,6 @@ gst_vaapi_image_get_plane gst_vaapi_image_get_pitch gst_vaapi_image_get_data_size gst_vaapi_image_get_buffer -gst_vaapi_image_get_raw gst_vaapi_image_update_from_buffer gst_vaapi_image_copy diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index d4fa2485ae..a8ccd6fe8a 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -109,6 +109,7 @@ libgstvaapi_source_priv_h = \ gstvaapidecoder_priv.h \ gstvaapidecoder_unit.h \ gstvaapidisplay_priv.h \ + gstvaapiimage_priv.h \ gstvaapiminiobject.h \ gstvaapiobject_priv.h \ gstvaapiparser_frame.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 3ddf124083..49107ba9a4 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -30,42 +30,12 @@ #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapiimage.h" +#include "gstvaapiimage_priv.h" #include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiImageClass GstVaapiImageClass; - -/** - * GstVaapiImage: - * - * A VA image wrapper - */ -struct _GstVaapiImage { - /*< private >*/ - GstVaapiObject parent_instance; - - VAImage internal_image; - VAImage image; - guchar *image_data; - GstVideoFormat internal_format; - GstVideoFormat format; - guint width; - guint height; - guint is_linear : 1; -}; - -/** - * GstVaapiImageClass: - * - * A VA image wrapper class - */ -struct _GstVaapiImageClass { - /*< private >*/ - GstVaapiObjectClass parent_class; -}; - #define SWAP_UINT(a, b) do { \ guint v = a; \ a = b; \ diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 124bdad54d..c5c3ed2280 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -58,22 +58,6 @@ G_BEGIN_DECLS #define GST_VAAPI_IMAGE_HEIGHT(image) gst_vaapi_image_get_height(image) typedef struct _GstVaapiImage GstVaapiImage; -typedef struct _GstVaapiImageRaw GstVaapiImageRaw; - -/** - * GstVaapiImageRaw: - * - * A raw image wrapper. The caller is responsible for initializing all - * the fields with sensible values. - */ -struct _GstVaapiImageRaw { - GstVideoFormat format; - guint width; - guint height; - guint num_planes; - guchar *pixels[3]; - guint stride[3]; -}; GstVaapiImage * gst_vaapi_image_new( @@ -135,13 +119,6 @@ gst_vaapi_image_get_buffer( GstVaapiRectangle *rect ); -gboolean -gst_vaapi_image_get_raw( - GstVaapiImage *image, - GstVaapiImageRaw *dst_image, - GstVaapiRectangle *rect -); - gboolean gst_vaapi_image_update_from_buffer( GstVaapiImage *image, @@ -149,13 +126,6 @@ gst_vaapi_image_update_from_buffer( GstVaapiRectangle *rect ); -gboolean -gst_vaapi_image_update_from_raw( - GstVaapiImage *image, - GstVaapiImageRaw *src_image, - GstVaapiRectangle *rect -); - gboolean gst_vaapi_image_copy(GstVaapiImage *dst_image, GstVaapiImage *src_image); diff --git a/gst-libs/gst/vaapi/gstvaapiimage_priv.h b/gst-libs/gst/vaapi/gstvaapiimage_priv.h new file mode 100644 index 0000000000..bc99d0585e --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiimage_priv.h @@ -0,0 +1,126 @@ +/* + * gstvaapiimage_priv.h - VA image abstraction (private definitions) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2013 Intel Corporation + * + * 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_IMAGE_PRIV_H +#define GST_VAAPI_IMAGE_PRIV_H + +#include +#include "gstvaapiobject_priv.h" + +G_BEGIN_DECLS + +typedef struct _GstVaapiImageClass GstVaapiImageClass; +typedef struct _GstVaapiImageRaw GstVaapiImageRaw; + +/** + * GstVaapiImage: + * + * A VA image wrapper + */ +struct _GstVaapiImage { + /*< private >*/ + GstVaapiObject parent_instance; + + VAImage internal_image; + VAImage image; + guchar *image_data; + GstVideoFormat internal_format; + GstVideoFormat format; + guint width; + guint height; + guint is_linear : 1; +}; + +/** + * GstVaapiImageClass: + * + * A VA image wrapper class + */ +struct _GstVaapiImageClass { + /*< private >*/ + GstVaapiObjectClass parent_class; +}; + +/** + * GstVaapiImageRaw: + * + * A raw image wrapper. The caller is responsible for initializing all + * the fields with sensible values. + */ +struct _GstVaapiImageRaw { + GstVideoFormat format; + guint width; + guint height; + guint num_planes; + guchar *pixels[3]; + guint stride[3]; +}; + +/** + * GST_VAAPI_IMAGE_FORMAT: + * @image: a #GstVaapiImage + * + * Macro that evaluates to the #GstVideoFormat of @image. + */ +#undef GST_VAAPI_IMAGE_FORMAT +#define GST_VAAPI_IMAGE_FORMAT(image) \ + (GST_VAAPI_IMAGE(image)->format) + +/** + * GST_VAAPI_IMAGE_WIDTH: + * @image: a #GstVaapiImage + * + * Macro that evaluates to the width of @image. + */ +#undef GST_VAAPI_IMAGE_WIDTH +#define GST_VAAPI_IMAGE_WIDTH(image) \ + (GST_VAAPI_IMAGE(image)->width) + +/** + * GST_VAAPI_IMAGE_HEIGHT: + * @image: a #GstVaapiImage + * + * Macro that evaluates to the height of @image. + */ +#undef GST_VAAPI_IMAGE_HEIGHT +#define GST_VAAPI_IMAGE_HEIGHT(image) \ + (GST_VAAPI_IMAGE(image)->height) + +G_GNUC_INTERNAL +gboolean +gst_vaapi_image_get_raw( + GstVaapiImage *image, + GstVaapiImageRaw *dst_image, + GstVaapiRectangle *rect +); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_image_update_from_raw( + GstVaapiImage *image, + GstVaapiImageRaw *src_image, + GstVaapiRectangle *rect +); + +G_END_DECLS + +#endif /* GST_VAAPI_IMAGE_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 92bbb2e335..a269df5a49 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -31,6 +31,7 @@ #include "gstvaapiutils.h" #include "gstvaapisubpicture.h" #include "gstvaapiobject_priv.h" +#include "gstvaapiimage_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -141,7 +142,7 @@ gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags) GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(image))); display = GST_VAAPI_OBJECT_DISPLAY(image); - format = gst_vaapi_image_get_format(image); + format = GST_VAAPI_IMAGE_FORMAT(image); if (!gst_vaapi_display_has_subpicture_format(display, format, &va_flags)) return NULL; if (flags & ~va_flags) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 768a8a9b7c..1a094b7b38 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -32,6 +32,7 @@ #include "gstvaapisurface_priv.h" #include "gstvaapicontext.h" #include "gstvaapiimage.h" +#include "gstvaapiimage_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -322,7 +323,7 @@ gst_vaapi_surface_get_format(GstVaapiSurface *surface) if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) { GstVaapiImage * const image = gst_vaapi_surface_derive_image(surface); if (image) { - surface->format = gst_vaapi_image_get_format(image); + surface->format = GST_VAAPI_IMAGE_FORMAT(image); gst_vaapi_object_unref(image); } if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) @@ -502,7 +503,8 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) if (!display) return FALSE; - gst_vaapi_image_get_size(image, &width, &height); + width = GST_VAAPI_IMAGE_WIDTH(image); + height = GST_VAAPI_IMAGE_HEIGHT(image); if (width != surface->width || height != surface->height) return FALSE; @@ -549,7 +551,8 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) if (!display) return FALSE; - gst_vaapi_image_get_size(image, &width, &height); + width = GST_VAAPI_IMAGE_WIDTH(image); + height = GST_VAAPI_IMAGE_HEIGHT(image); if (width != surface->width || height != surface->height) return FALSE; @@ -659,11 +662,8 @@ _gst_vaapi_surface_associate_subpicture( src_rect = &src_rect_default; src_rect_default.x = 0; src_rect_default.y = 0; - gst_vaapi_image_get_size( - image, - &src_rect_default.width, - &src_rect_default.height - ); + src_rect_default.width = GST_VAAPI_IMAGE_WIDTH(image); + src_rect_default.height = GST_VAAPI_IMAGE_HEIGHT(image); } if (!dst_rect) { From e790722a8403687ab329a7cdedfe828383379805 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Jul 2013 13:55:04 +0200 Subject: [PATCH 1288/3781] tests: image: fix string representation for GstVideoFormat. --- tests/image.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/image.c b/tests/image.c index 305322b0b5..4155d82651 100644 --- a/tests/image.c +++ b/tests/image.c @@ -338,8 +338,8 @@ image_upload(GstVaapiImage *image, GstVaapiSurface *surface) if (gst_vaapi_surface_put_image(surface, image)) return TRUE; - g_print("could not upload %" GST_FOURCC_FORMAT" image to surface\n", - GST_FOURCC_ARGS(format)); + g_print("could not upload %s image to surface\n", + gst_vaapi_video_format_to_string(format)); if (!gst_vaapi_display_has_subpicture_format(display, format, NULL)) return FALSE; From 6e9ce9ae37384a1b0073de432ee6209e5d47d52a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 25 Jul 2013 18:10:40 +0200 Subject: [PATCH 1289/3781] tests: image: fix generation of I420/YV12 images. U/V planes were reversed, thus producing invalid images. --- tests/image.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/image.c b/tests/image.c index 4155d82651..8d1ecc050f 100644 --- a/tests/image.c +++ b/tests/image.c @@ -188,8 +188,8 @@ static void draw_rect_YV12( // Y, V, U planes width /= 2; height /= 2; - pU = pixels[1] + y * stride[1] + x; - pV = pixels[2] + y * stride[2] + x; + pV = pixels[1] + y * stride[1] + x; + pU = pixels[2] + y * stride[2] + x; for (j = 0; j < height; j++, pU += stride[1], pV += stride[2]) for (i = 0; i < width; i++) { pU[i] = Cb; From f997f6271f72dead273d3851f0751adb2942cdba Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 26 Jul 2013 10:05:06 +0200 Subject: [PATCH 1290/3781] tests: image: add support for packed YUV formats. Add support for packed YUV 4:2:2 formats, i.e. YUY2 and UYVY. --- tests/image.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/image.c b/tests/image.c index 8d1ecc050f..f5ee9a922f 100644 --- a/tests/image.c +++ b/tests/image.c @@ -213,6 +213,42 @@ static void draw_rect_I420( // Y, U, V planes draw_rect_YV12(new_pixels, new_stride, x, y, width, height, color); } +static void draw_rect_YUV422(guchar *pixels[3], guint stride[3], + gint x, gint y, guint width, guint height, guint32 color) +{ + guint i, j; + + width /= 2; + for (j = 0; j < height; j++) { + guint32 * const p = (guint32 *) + (pixels[0] + (y + j) * stride[0] + x * 2); + for (i = 0; i < width; i++) + p[i] = color; + } +} + +static void draw_rect_YUY2(guchar *pixels[3], guint stride[3], + gint x, gint y, guint width, guint height, guint32 color) +{ + const guchar Y = color >> 16; + const guchar Cb = color >> 8; + const guchar Cr = color; + + color = (Y << 24) | (Cb << 16) | (Y << 8) | Cr; + draw_rect_YUV422(pixels, stride, x, y, width, height, GUINT32_TO_BE(color)); +} + +static void draw_rect_UYVY(guchar *pixels[3], guint stride[3], + gint x, gint y, guint width, guint height, guint32 color) +{ + const guchar Y = color >> 16; + const guchar Cb = color >> 8; + const guchar Cr = color; + + color = (Cb << 24) | (Y << 16) | (Cr << 8) | Y; + draw_rect_YUV422(pixels, stride, x, y, width, height, GUINT32_TO_BE(color)); +} + static void draw_rect_AYUV( guchar *pixels[3], guint stride[3], @@ -279,6 +315,8 @@ image_draw_rectangle( _(NV12), _(YV12), _(I420), + _(YUY2), + _(UYVY), _(AYUV), #undef _ { 0, } From 73323ba76ad697939b0afe2cae53d1e5959eb36e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 26 Jul 2013 13:12:28 +0200 Subject: [PATCH 1291/3781] tests: image: try to upload images through vaDeriveImage() too. On some platforms, vaPutImage() would fail even if it does not involve color format conversion or scaling, whereas copying raw pixels through vaDeriveImage() could work instead. --- tests/image.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/image.c b/tests/image.c index f5ee9a922f..3abcaf82cc 100644 --- a/tests/image.c +++ b/tests/image.c @@ -363,7 +363,9 @@ image_upload(GstVaapiImage *image, GstVaapiSurface *surface) { GstVaapiDisplay *display; GstVideoFormat format; + GstVaapiImage *surface_image; GstVaapiSubpicture *subpicture; + gboolean success; display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); if (!display) @@ -376,6 +378,14 @@ image_upload(GstVaapiImage *image, GstVaapiSurface *surface) if (gst_vaapi_surface_put_image(surface, image)) return TRUE; + surface_image = gst_vaapi_surface_derive_image(surface); + if (surface_image) { + success = gst_vaapi_image_copy(surface_image, image); + gst_vaapi_object_unref(surface_image); + if (success) + return TRUE; + } + g_print("could not upload %s image to surface\n", gst_vaapi_video_format_to_string(format)); From dd6a0d87ffacb35c74abdf1019b88dbf6760b88b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 23 Aug 2013 16:25:39 +0200 Subject: [PATCH 1292/3781] tests: image: fix conversion from RGB to YUV. Fix RGB to YUV conversion to preserve full data range. --- tests/image.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/image.c b/tests/image.c index 3abcaf82cc..361874cffe 100644 --- a/tests/image.c +++ b/tests/image.c @@ -276,9 +276,9 @@ static inline guint32 argb2yuv(guint32 color) const gint32 g = (color >> 8) & 0xff; const gint32 b = (color ) & 0xff; - const guint32 y = (( 263 * r + 516 * g + 100 * b) >> 10) + 16; - const guint32 u = ((-152 * r - 298 * g + 450 * b) >> 10) + 128; - const guint32 v = (( 450 * r - 376 * g - 73 * b) >> 10) + 128; + const guint32 y = (( 306 * r + 601 * g + 116 * b) >> 10); + const guint32 u = ((-172 * r - 339 * g + 512 * b) >> 10) + 128; + const guint32 v = (( 512 * r - 428 * g - 83 * b) >> 10) + 128; return (y << 16) | (u << 8) | v; } From b1085b57d50007e8258da6445b0a9799a6219eac Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 23 Aug 2013 18:35:42 +0200 Subject: [PATCH 1293/3781] tests: image: allow creation of images with interleaved patterns. Add image_generate_full() function to create interleaved color rectangles. If flags is zero, the whole frame is generated with a unique pattern. If flags is non-zero, then each field is handled individually. --- tests/image.c | 113 +++++++++++++++++++++++++++++++++++++++++--------- tests/image.h | 15 ++++--- 2 files changed, 100 insertions(+), 28 deletions(-) diff --git a/tests/image.c b/tests/image.c index 361874cffe..53bb42f2d4 100644 --- a/tests/image.c +++ b/tests/image.c @@ -21,6 +21,40 @@ #include "image.h" +static gboolean +image_draw_rectangle( + GstVaapiImage *image, + gint x, + gint y, + guint width, + guint height, + guint32 color, + guint32 flags +); + +static gboolean +image_draw_color_rectangles( + GstVaapiImage *image, + guint width, + guint height, + const guint32 colors[4], + guint32 flags + ) +{ + const guint w = width / 2; + const guint h = height / 2; + + if (!image_draw_rectangle(image, 0, 0, w, h, colors[0], flags)) + return FALSE; + if (!image_draw_rectangle(image, w, 0, w, h, colors[1], flags)) + return FALSE; + if (!image_draw_rectangle(image, 0, h, w, h, colors[2], flags)) + return FALSE; + if (!image_draw_rectangle(image, w, h, w, h, colors[3], flags)) + return FALSE; + return TRUE; +} + GstVaapiImage * image_generate( GstVaapiDisplay *display, @@ -29,20 +63,49 @@ image_generate( guint height ) { - const guint w = width; - const guint h = height; + return image_generate_full(display, format, width, height, 0); +} + +GstVaapiImage * +image_generate_full( + GstVaapiDisplay *display, + GstVideoFormat format, + guint width, + guint height, + guint32 flags +) +{ GstVaapiImage *image; - image = gst_vaapi_image_new(display, format, w, h); + static const guint32 rgb_colors[4] = + { 0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000 }; + static const guint32 bgr_colors[4] = + { 0xff000000, 0xff0000ff, 0xff00ff00, 0xffff0000 }; + static const guint32 inv_colors[4] = + { 0xffdeadc0, 0xffdeadc0, 0xffdeadc0, 0xffdeadc0 }; + + image = gst_vaapi_image_new(display, format, width, height); if (!image) return NULL; - if (image_draw_rectangle(image, 0, 0, w/2, h/2, 0xffff0000) && - image_draw_rectangle(image, w/2, 0, w/2, h/2, 0xff00ff00) && - image_draw_rectangle(image, 0, h/2, w/2, h/2, 0xff0000ff) && - image_draw_rectangle(image, w/2, h/2, w/2, h/2, 0xff000000)) - return image; + if (flags) { + if (!image_draw_color_rectangles(image, width, height, + ((flags & GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) ? + rgb_colors : inv_colors), + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)) + goto error; + if (!image_draw_color_rectangles(image, width, height, + ((flags & GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) ? + bgr_colors : inv_colors), + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)) + goto error; + } + else if (!image_draw_color_rectangles(image, width, height, rgb_colors, 0)) + goto error; + return image; + +error: gst_vaapi_object_unref(image); return NULL; } @@ -290,7 +353,8 @@ image_draw_rectangle( gint y, guint width, guint height, - guint32 color + guint32 color, + guint32 flags ) { const GstVideoFormat image_format = gst_vaapi_image_get_format(image); @@ -328,6 +392,15 @@ image_draw_rectangle( if (!draw_rect) return FALSE; + if (x < 0) + x = 0; + if (y < 0) + y = 0; + if (width > image_width - x) + width = image_width - x; + if (height > image_height - y) + height = image_height - y; + display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(image)); if (!display) return FALSE; @@ -338,23 +411,23 @@ image_draw_rectangle( for (i = 0; i < gst_vaapi_image_get_plane_count(image); i++) { pixels[i] = gst_vaapi_image_get_plane(image, i); stride[i] = gst_vaapi_image_get_pitch(image, i); + switch (flags) { + case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: + pixels[i] += stride[i]; + // fall-through + case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: + stride[i] *= 2; + break; + } } + if (flags) + y /= 2, height /= 2; + if (gst_vaapi_video_format_is_yuv(image_format)) color = argb2yuv(color); - if (x < 0) - x = 0; - if (y < 0) - y = 0; - if (width > image_width - x) - width = image_width - x; - if (height > image_height - y) - height = image_height - y; - - gst_vaapi_display_lock(display); draw_rect(pixels, stride, x, y, width, height, color); - gst_vaapi_display_unlock(display); return gst_vaapi_image_unmap(image); } diff --git a/tests/image.h b/tests/image.h index 6c7afaf961..8c1229f885 100644 --- a/tests/image.h +++ b/tests/image.h @@ -33,14 +33,13 @@ image_generate( guint height ); -gboolean -image_draw_rectangle( - GstVaapiImage *image, - gint x, - gint y, - guint width, - guint height, - guint32 color +GstVaapiImage * +image_generate_full( + GstVaapiDisplay *display, + GstVideoFormat format, + guint width, + guint height, + guint32 flags ); gboolean From d8ffc2c150fd52731a2a6ec9061e91300779c467 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 26 Jul 2013 13:57:35 +0200 Subject: [PATCH 1294/3781] libs: drop some public APIs. Don't expose GstVaapiContext APIs and make them totally private to libgstvaapi core library. That API would also tend to disappear in a future revision. Likewise, don't expose GstVaapiDisplayCache API but keep symbols visible so that the various render backends could share a common display cache implementation in libgstvaapi. Try to clean-up the documentation from any stale entry too. --- docs/reference/libs/libs-docs.xml.in | 3 --- docs/reference/libs/libs-sections.txt | 18 ------------------ gst-libs/gst/vaapi/Makefile.am | 5 +++-- gst-libs/gst/vaapi/gstvaapicontext.h | 12 ++++++++++++ gst-libs/gst/vaapi/gstvaapidisplaycache.h | 5 +++++ 5 files changed, 20 insertions(+), 23 deletions(-) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index f8940f8ac0..1f7f8409b6 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -27,9 +27,6 @@ - - - diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 3c1b03aa9e..91796d9fe0 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -304,24 +304,6 @@ gst_vaapi_texture_get_size gst_vaapi_texture_put_surface
-
-gstvaapicontext -GstVaapiContext -GstVaapiContext -gst_vaapi_context_new -gst_vaapi_context_reset -gst_vaapi_context_get_id -gst_vaapi_context_get_profile -gst_vaapi_context_set_profile -gst_vaapi_context_get_entrypoint -gst_vaapi_context_get_size -gst_vaapi_context_get_surface_proxy -gst_vaapi_context_get_surface_count -gst_vaapi_context_apply_composition - -GST_VAAPI_CONTEXT -
-
gstvaapidecoder GstVaapiDecoderStatus diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index a8ccd6fe8a..3e0a02a4fd 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -74,14 +74,13 @@ libgstvaapi_source_c = \ $(NULL) libgstvaapi_source_h = \ - gstvaapicontext.h \ gstvaapidecoder.h \ gstvaapidecoder_h264.h \ gstvaapidecoder_mpeg2.h \ gstvaapidecoder_mpeg4.h \ gstvaapidecoder_vc1.h \ gstvaapidisplay.h \ - gstvaapidisplaycache.h \ + gstvaapifilter.h \ gstvaapiimage.h \ gstvaapiimagepool.h \ gstvaapiobject.h \ @@ -103,12 +102,14 @@ libgstvaapi_source_priv_h = \ gstcompat.h \ gstvaapicodec_objects.h \ gstvaapicompat.h \ + gstvaapicontext.h \ gstvaapidebug.h \ gstvaapidecoder_dpb.h \ gstvaapidecoder_objects.h \ gstvaapidecoder_priv.h \ gstvaapidecoder_unit.h \ gstvaapidisplay_priv.h \ + gstvaapidisplaycache.h \ gstvaapiimage_priv.h \ gstvaapiminiobject.h \ gstvaapiobject_priv.h \ diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 2414e9da92..3803314e3c 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -52,6 +52,7 @@ struct _GstVaapiContextInfo { guint ref_frames; }; +G_GNUC_INTERNAL GstVaapiContext * gst_vaapi_context_new( GstVaapiDisplay *display, @@ -61,10 +62,12 @@ gst_vaapi_context_new( guint height ); +G_GNUC_INTERNAL GstVaapiContext * gst_vaapi_context_new_full(GstVaapiDisplay *display, const GstVaapiContextInfo *cip); +G_GNUC_INTERNAL gboolean gst_vaapi_context_reset( GstVaapiContext *context, @@ -74,22 +77,28 @@ gst_vaapi_context_reset( guint height ); +G_GNUC_INTERNAL gboolean gst_vaapi_context_reset_full(GstVaapiContext *context, const GstVaapiContextInfo *new_cip); +G_GNUC_INTERNAL GstVaapiID gst_vaapi_context_get_id(GstVaapiContext *context); +G_GNUC_INTERNAL GstVaapiProfile gst_vaapi_context_get_profile(GstVaapiContext *context); +G_GNUC_INTERNAL gboolean gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile); +G_GNUC_INTERNAL GstVaapiEntrypoint gst_vaapi_context_get_entrypoint(GstVaapiContext *context); +G_GNUC_INTERNAL void gst_vaapi_context_get_size( GstVaapiContext *context, @@ -97,12 +106,15 @@ gst_vaapi_context_get_size( guint *pheight ); +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 gboolean gst_vaapi_context_apply_composition( GstVaapiContext *context, diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h index 72b6fac038..4b0bb5e75f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.h +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.h @@ -26,21 +26,26 @@ typedef struct _GstVaapiDisplayCache GstVaapiDisplayCache; +G_GNUC_INTERNAL GstVaapiDisplayCache * gst_vaapi_display_cache_new(void); +G_GNUC_INTERNAL void gst_vaapi_display_cache_free(GstVaapiDisplayCache *cache); +G_GNUC_INTERNAL guint gst_vaapi_display_cache_get_size(GstVaapiDisplayCache *cache); +G_GNUC_INTERNAL gboolean gst_vaapi_display_cache_add( GstVaapiDisplayCache *cache, GstVaapiDisplayInfo *info ); +G_GNUC_INTERNAL void gst_vaapi_display_cache_remove( GstVaapiDisplayCache *cache, From 53fc8bb4c79be5cebde22a5b238699df93ec8165 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Jul 2013 11:41:05 +0200 Subject: [PATCH 1295/3781] libs: add type definitions for GstVaapiPoint and GstVaapiRectangle. Add helper functions to describe GstVaapiPoint and GstVaapiRectangle structures as a standard GType. This could be useful to have them described as a GValue later on. --- gst-libs/gst/vaapi/gstvaapivalue.c | 43 ++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivalue.h | 25 +++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index e66e225a21..2912cc9c5d 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -29,6 +29,49 @@ #include #include "gstvaapivalue.h" +static gpointer +default_copy_func(gpointer data) +{ + return data; +} + +static void +default_free_func(gpointer data) +{ +} + +/* --- GstVaapiPoint --- */ + +GType +gst_vaapi_point_get_type(void) +{ + static volatile gsize g_type = 0; + + if (g_once_init_enter(&g_type)) { + GType type = g_boxed_type_register_static( + g_intern_static_string("GstVaapiPoint"), + default_copy_func, default_free_func); + g_once_init_leave(&g_type, type); + } + return g_type; +} + +/* --- GstVaapiRectangle --- */ + +GType +gst_vaapi_rectangle_get_type(void) +{ + static volatile gsize g_type = 0; + + if (g_once_init_enter(&g_type)) { + GType type = g_boxed_type_register_static( + g_intern_static_string("GstVaapiRectangle"), + default_copy_func, default_free_func); + g_once_init_leave(&g_type, type); + } + return g_type; +} + /* --- GstVaapiRenderMode --- */ GType diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index 9762f582b6..5ca8f5f916 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -28,6 +28,25 @@ G_BEGIN_DECLS +/** + * GST_VAAPI_TYPE_POINT: + * + * A #GstVaapiPoint type that represents a 2D point coordinates. + * + * Return value: the GType of #GstVaapiPoint + */ +#define GST_VAAPI_TYPE_POINT gst_vaapi_point_get_type() + +/** + * GST_VAAPI_TYPE_RECTANGLE: + * + * A #GstVaapiRectangle type that represents a 2D rectangle position + * and size. + * + * Return value: the GType of #GstVaapiRectangle + */ +#define GST_VAAPI_TYPE_RECTANGLE gst_vaapi_rectangle_get_type() + /** * GST_VAAPI_TYPE_RENDER_MODE: * @@ -47,6 +66,12 @@ G_BEGIN_DECLS */ #define GST_VAAPI_TYPE_ROTATION gst_vaapi_rotation_get_type() +GType +gst_vaapi_point_get_type(void) G_GNUC_CONST; + +GType +gst_vaapi_rectangle_get_type(void) G_GNUC_CONST; + GType gst_vaapi_render_mode_get_type(void) G_GNUC_CONST; From 8ffe11a9dff2b8995bd28b0ecd3b93436ab22d9b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Jul 2013 11:37:23 +0200 Subject: [PATCH 1296/3781] libs: add gst_vaapi_video_format_from_va_fourcc() helper. Add gst_vaapi_video_format_from_va_fourcc() helper that converts from a VA fourcc value to a suitable GstVideoFormat. --- gst-libs/gst/vaapi/video-format.c | 24 ++++++++++++++++++++++++ gst-libs/gst/vaapi/video-format.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 68198a4167..e3bbecb0ce 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -286,6 +286,30 @@ gst_vaapi_video_format_to_caps(GstVideoFormat format) return m ? gst_caps_from_string(m->caps_str) : NULL; } +/** + * gst_vaapi_video_format_from_va_fourcc: + * @fourcc: a FOURCC value + * + * Converts a VA fourcc into the corresponding #GstVideoFormat. If no + * matching fourcc was found, then zero is returned. + * + * Return value: the #GstVideoFormat corresponding to the VA @fourcc + */ +GstVideoFormat +gst_vaapi_video_format_from_va_fourcc(guint32 fourcc) +{ + const GstVideoFormatMap *m; + + /* Note: VA fourcc values are now standardized and shall represent + a unique format. The associated VAImageFormat is just a hint to + determine RGBA component ordering */ + for (m = gst_vaapi_video_formats; m->format; m++) { + if (m->va_format.fourcc == fourcc) + return m->format; + } + return GST_VIDEO_FORMAT_UNKNOWN; +} + /** * gst_vaapi_video_format_from_va_format: * @va_format: a #VAImageFormat diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index a3d7d5be58..84e9c75ab7 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -46,6 +46,9 @@ gst_vaapi_video_format_from_caps(GstCaps *caps); GstCaps * gst_vaapi_video_format_to_caps(GstVideoFormat format); +GstVideoFormat +gst_vaapi_video_format_from_va_fourcc(guint32 fourcc); + GstVideoFormat gst_vaapi_video_format_from_va_format(const VAImageFormat *va_format); From f34b6ffc60bfb87f03873c2d8ec2bebcfd3a5768 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Jul 2013 11:53:38 +0200 Subject: [PATCH 1297/3781] libs: add gst_vaapi_video_format_from_string() helper. Add gst_vaapi_video_format_from_string() helper function to convert from a video format string representation to a suitable GstVideoFormat. This is just an alias to gst_video_format_from_string() for GStreamer 1.0.x builds, and a proper iteration over all GstVideoFormat string representations otherwise for earlier GStreamer 0.10.x builds. --- gst-libs/gst/vaapi/video-format.c | 50 +++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/video-format.h | 3 ++ 2 files changed, 53 insertions(+) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index e3bbecb0ce..523e6fc2ea 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -139,6 +139,56 @@ get_map(GstVideoFormat format) return NULL; } +/** + * gst_vaapi_video_format_from_string: + * @str: a string representation of #GstVideoFormat + * + * Returns the #GstVideoFormat represented as the string @str. + * + * Return value: #GstVideoFormat for the string representation of + * video format in @str. + */ +GstVideoFormat +gst_vaapi_video_format_from_string(const gchar *str) +{ +#if GST_CHECK_VERSION(1,0,0) + return gst_video_format_from_string(str); +#else + GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; + + do { + /* Validate input string */ + if (!str) + break; + + /* Fast path: assume this represents a common fourcc value */ + const guint32 fourcc = GST_MAKE_FOURCC(str[0], str[1], str[2], str[3]); + format = gst_video_format_from_fourcc(fourcc); + if (format != GST_VIDEO_FORMAT_UNKNOWN) + break; + + /* Slow path: check through all registered enum values */ + GEnumClass * const enum_class = + g_type_class_ref(GST_TYPE_VIDEO_FORMAT); + if (!enum_class) + break; + + gchar * const video_format_str = + g_strdup_printf("GST_VIDEO_FORMAT_%s", str); + if (video_format_str) { + const GEnumValue * const enum_value = + g_enum_get_value_by_name(enum_class, video_format_str); + + if (enum_value) + format = enum_value->value; + g_free(video_format_str); + } + g_type_class_unref(enum_class); + } while (0); + return format; +#endif +} + /** * gst_vaapi_video_format_to_string: * @format: a #GstVideoFormat diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index 84e9c75ab7..fb2bb186b4 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -28,6 +28,9 @@ G_BEGIN_DECLS +GstVideoFormat +gst_vaapi_video_format_from_string(const gchar *str); + const char * gst_vaapi_video_format_to_string(GstVideoFormat format); From f09008a8d147950aa31fb342b3b8a105eadcf9a6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 23 Jul 2013 15:52:45 +0200 Subject: [PATCH 1298/3781] Add initial infrastructure for video processing. Add initial API for video processing: only scaling and color format conversion operations are supported. --- configure.ac | 29 + docs/reference/libs/libs-docs.xml.in | 1 + docs/reference/libs/libs-sections.txt | 16 + gst-libs/gst/vaapi/Makefile.am | 1 + gst-libs/gst/vaapi/gstvaapidisplay.c | 12 + gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 11 + gst-libs/gst/vaapi/gstvaapifilter.c | 821 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 104 +++ 8 files changed, 995 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapifilter.c create mode 100644 gst-libs/gst/vaapi/gstvaapifilter.h diff --git a/configure.ac b/configure.ac index 837ea1066c..66828fdcff 100644 --- a/configure.ac +++ b/configure.ac @@ -615,6 +615,31 @@ AC_CACHE_CHECK([for JPEG decoding API], LIBS="$saved_LIBS" ]) +dnl Check for vpp (video post-processing) support +USE_VA_VPP=0 +AC_CACHE_CHECK([for video post-postprocessing API], + ac_cv_have_va_vpp_api, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include ]], + [[VADisplay va_dpy; + VAContextID vpp_ctx; + VAProcFilterType filters[VAProcFilterCount]; + unsigned int num_filters = VAProcFilterCount; + vaQueryVideoProcFilters(va_dpy, vpp_ctx, filters, &num_filters); + ]])], + [ac_cv_have_va_vpp_api="yes" USE_VA_VPP=1], + [ac_cv_have_va_vpp_api="no"] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +]) + dnl VA/Wayland API if test "$enable_wayland" = "yes"; then PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= va_api_wld_version], @@ -633,6 +658,10 @@ case ":$USE_X11:$USE_GLX:$USE_WAYLAND:$USE_DRM:" in ;; esac +AC_DEFINE_UNQUOTED(USE_VA_VPP, $USE_VA_VPP, + [Defined to 1 if video post-processing is used]) +AM_CONDITIONAL(USE_VA_VPP, test $USE_VA_VPP -eq 1) + AC_DEFINE_UNQUOTED(USE_JPEG_DECODER, $USE_JPEG_DECODER, [Defined to 1 if JPEG decoder is used]) AM_CONDITIONAL(USE_JPEG_DECODER, test $USE_JPEG_DECODER -eq 1) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 1f7f8409b6..45e05eab13 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -34,6 +34,7 @@ + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 91796d9fe0..23a804f04a 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -373,3 +373,19 @@ gst_vaapi_surface_proxy_unref GST_VAAPI_SURFACE_PROXY_SURFACE
+ +
+gstvaapifilter +GstVaapiFilter +GstVaapiFilter +gst_vaapi_filter_new +gst_vaapi_filter_ref +gst_vaapi_filter_unref +gst_vaapi_filter_replace +gst_vaapi_filter_get_operations +gst_vaapi_filter_get_formats +gst_vaapi_filter_set_operation +gst_vaapi_filter_set_format + +GST_VAAPI_FILTER +
diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 3e0a02a4fd..ab605e1368 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -55,6 +55,7 @@ libgstvaapi_source_c = \ gstvaapidecoder_vc1.c \ gstvaapidisplay.c \ gstvaapidisplaycache.c \ + gstvaapifilter.c \ gstvaapiimage.c \ gstvaapiimagepool.c \ gstvaapiminiobject.c \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 05833c8e7d..ca8c6cb046 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -684,6 +684,18 @@ gst_vaapi_display_create(GstVaapiDisplay *display, } append_h263_config(priv->decoders); + /* Video processing API */ +#if USE_VA_VPP + status = vaQueryConfigEntrypoints(priv->display, VAProfileNone, + entrypoints, &num_entrypoints); + if (vaapi_check_status(status, "vaQueryEntrypoints() [VAProfileNone]")) { + for (j = 0; j < num_entrypoints; j++) { + if (entrypoints[j] == VAEntrypointVideoProc) + priv->has_vpp = TRUE; + } + } +#endif + /* VA display attributes */ display_attrs = g_new(VADisplayAttribute, vaMaxNumDisplayAttributes(priv->display)); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 81768208ab..1f7f46ceff 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -116,6 +116,16 @@ typedef void (*GstVaapiDisplayGetSizeMFunc)(GstVaapiDisplay *display, #define GST_VAAPI_DISPLAY_TYPES(display) \ gst_vaapi_display_get_display_types(GST_VAAPI_DISPLAY_CAST(display)) +/** + * GST_VAAPI_DISPLAY_HAS_VPP: + * @display: a @GstVaapiDisplay + * + * Returns whether the @display supports video processing (VA/VPP) + */ +#undef GST_VAAPI_DISPLAY_HAS_VPP +#define GST_VAAPI_DISPLAY_HAS_VPP(display) \ + (GST_VAAPI_DISPLAY_GET_PRIVATE(display)->has_vpp) + struct _GstVaapiDisplayPrivate { GstVaapiDisplay *parent; GRecMutex mutex; @@ -133,6 +143,7 @@ struct _GstVaapiDisplayPrivate { GArray *subpicture_formats; GArray *properties; guint use_foreign_display : 1; + guint has_vpp : 1; }; /** diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c new file mode 100644 index 0000000000..ce8556e0ea --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -0,0 +1,821 @@ +/* + * gstvaapifilter.c - Video processing abstraction + * + * Copyright (C) 2013 Intel Corporation + * + * 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 "gstvaapifilter.h" +#include "gstvaapiutils.h" +#include "gstvaapiminiobject.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapisurface_priv.h" + +#if USE_VA_VPP +# include +#endif + +#define DEBUG 1 +#include "gstvaapidebug.h" + +#define GST_VAAPI_FILTER(obj) \ + ((GstVaapiFilter *)(obj)) + +typedef struct _GstVaapiFilterOpData GstVaapiFilterOpData; +struct _GstVaapiFilterOpData { + GstVaapiFilterOp op; + GParamSpec *pspec; + volatile gint ref_count; + guint va_type; + guint va_subtype; + gpointer va_caps; + guint va_num_caps; + guint va_cap_size; + VABufferID va_buffer; + guint va_buffer_size; + guint is_enabled : 1; +}; + +struct _GstVaapiFilter { + /*< private >*/ + GstVaapiMiniObject parent_instance; + + GstVaapiDisplay *display; + VADisplay va_display; + VAConfigID va_config; + VAContextID va_context; + GPtrArray *operations; + GstVideoFormat format; + GArray *formats; +}; + +/* ------------------------------------------------------------------------- */ +/* --- VPP Helpers --- */ +/* ------------------------------------------------------------------------- */ + +#if USE_VA_VPP +static VAProcFilterType * +vpp_get_filters_unlocked(GstVaapiFilter *filter, guint *num_filters_ptr) +{ + VAProcFilterType *filters = NULL; + guint num_filters = 0; + VAStatus va_status; + + num_filters = VAProcFilterCount; + filters = g_malloc_n(num_filters, sizeof(*filters)); + if (!filters) + goto error; + + va_status = vaQueryVideoProcFilters(filter->va_display, filter->va_context, + filters, &num_filters); + + // Try to reallocate to the expected number of filters + if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) { + VAProcFilterType * const new_filters = + g_try_realloc_n(filters, num_filters, sizeof(*new_filters)); + if (!new_filters) + goto error; + filters = new_filters; + + va_status = vaQueryVideoProcFilters(filter->va_display, + filter->va_context, filters, &num_filters); + } + if (!vaapi_check_status(va_status, "vaQueryVideoProcFilters()")) + goto error; + + *num_filters_ptr = num_filters; + return filters; + +error: + g_free(filters); + return NULL; +} + +static VAProcFilterType * +vpp_get_filters(GstVaapiFilter *filter, guint *num_filters_ptr) +{ + VAProcFilterType *filters; + + GST_VAAPI_DISPLAY_LOCK(filter->display); + filters = vpp_get_filters_unlocked(filter, num_filters_ptr); + GST_VAAPI_DISPLAY_UNLOCK(filter->display); + return filters; +} +#endif + +/* ------------------------------------------------------------------------- */ +/* --- VPP Operations --- */ +/* ------------------------------------------------------------------------- */ + +#if USE_VA_VPP +#define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN + +enum { + PROP_0, + + PROP_FORMAT = GST_VAAPI_FILTER_OP_FORMAT, + + N_PROPERTIES +}; + +static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; +static gsize g_properties_initialized = FALSE; + +static void +init_properties(void) +{ + /** + * GstVaapiFilter:format: + * + * The forced output pixel format, expressed as a #GstVideoFormat. + */ + g_properties[PROP_FORMAT] = + g_param_spec_enum("format", + "Format", + "The forced output pixel format", + GST_TYPE_VIDEO_FORMAT, + DEFAULT_FORMAT, + G_PARAM_READWRITE); +} + +static void +ensure_properties(void) +{ + if (g_once_init_enter(&g_properties_initialized)) { + init_properties(); + g_once_init_leave(&g_properties_initialized, TRUE); + } +} + +static void +op_data_free(GstVaapiFilterOpData *op_data) +{ + g_free(op_data->va_caps); + g_slice_free(GstVaapiFilterOpData, op_data); +} + +static inline gpointer +op_data_new(GstVaapiFilterOp op, GParamSpec *pspec) +{ + GstVaapiFilterOpData *op_data; + + op_data = g_slice_new0(GstVaapiFilterOpData); + if (!op_data) + return NULL; + + op_data->op = op; + op_data->pspec = pspec; + op_data->ref_count = 1; + op_data->va_buffer = VA_INVALID_ID; + + switch (op) { + case GST_VAAPI_FILTER_OP_FORMAT: + op_data->va_type = VAProcFilterNone; + break; + default: + g_assert(0 && "unsupported operation"); + goto error; + } + return op_data; + +error: + op_data_free(op_data); + return NULL; +} + +static inline gpointer +op_data_ref(gpointer data) +{ + GstVaapiFilterOpData * const op_data = data; + + g_return_val_if_fail(op_data != NULL, NULL); + + g_atomic_int_inc(&op_data->ref_count); + return op_data; +} + +static void +op_data_unref(gpointer data) +{ + GstVaapiFilterOpData * const op_data = data; + + g_return_if_fail(op_data != NULL); + g_return_if_fail(op_data->ref_count > 0); + + if (g_atomic_int_dec_and_test(&op_data->ref_count)) + op_data_free(op_data); +} + +/* Get default list of operations supported by the library */ +static GPtrArray * +get_operations_default(void) +{ + GPtrArray *ops; + guint i; + + ops = g_ptr_array_new_full(N_PROPERTIES, op_data_unref); + if (!ops) + return NULL; + + ensure_properties(); + + for (i = 0; i < N_PROPERTIES; i++) { + GParamSpec * const pspec = g_properties[i]; + if (!pspec) + continue; + + GstVaapiFilterOpData * const op_data = op_data_new(i, pspec); + if (!op_data) + goto error; + g_ptr_array_add(ops, op_data); + } + return ops; + +error: + g_ptr_array_unref(ops); + return NULL; +} + +/* Get the ordered list of operations, based on VA/VPP queries */ +static GPtrArray * +get_operations_ordered(GstVaapiFilter *filter, GPtrArray *default_ops) +{ + GPtrArray *ops; + VAProcFilterType *filters; + guint i, j, num_filters; + + ops = g_ptr_array_new_full(default_ops->len, op_data_unref); + if (!ops) + return NULL; + + filters = vpp_get_filters(filter, &num_filters); + if (!filters) + goto error; + + // Append virtual ops first, i.e. those without an associated VA filter + for (i = 0; i < default_ops->len; i++) { + GstVaapiFilterOpData * const op_data = + g_ptr_array_index(default_ops, i); + if (op_data->va_type == VAProcFilterNone) + g_ptr_array_add(ops, op_data_ref(op_data)); + } + + // Append ops, while preserving the VA filters ordering + for (i = 0; i < num_filters; i++) { + const VAProcFilterType va_type = filters[i]; + if (va_type == VAProcFilterNone) + continue; + + for (j = 0; j < default_ops->len; j++) { + GstVaapiFilterOpData * const op_data = + g_ptr_array_index(default_ops, j); + if (op_data->va_type != va_type) + continue; + g_ptr_array_add(ops, op_data_ref(op_data)); + } + } + + if (filter->operations) + g_ptr_array_unref(filter->operations); + filter->operations = g_ptr_array_ref(ops); + + g_free(filters); + g_ptr_array_unref(default_ops); + return ops; + +error: + g_free(filters); + g_ptr_array_unref(ops); + g_ptr_array_unref(default_ops); + return NULL; +} + +/* Determine the set of supported VPP operations by the specific + filter, or known to this library if filter is NULL */ +static GPtrArray * +ensure_operations(GstVaapiFilter *filter) +{ + GPtrArray *ops; + + if (filter && filter->operations) + return g_ptr_array_ref(filter->operations); + + ops = get_operations_default(); + if (!ops) + return NULL; + return filter ? get_operations_ordered(filter, ops) : ops; +} +#endif + +/* Find whether the VPP operation is supported or not */ +GstVaapiFilterOpData * +find_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) +{ + guint i; + + if (!filter->operations) + return NULL; + + for (i = 0; i < filter->operations->len; i++) { + GstVaapiFilterOpData * const op_data = + g_ptr_array_index(filter->operations, i); + if (op_data->op == op) + return op_data; + } + return NULL; +} + +/* ------------------------------------------------------------------------- */ +/* --- Surface Formats --- */ +/* ------------------------------------------------------------------------- */ + +static GArray * +ensure_formats(GstVaapiFilter *filter) +{ + VASurfaceAttrib *surface_attribs = NULL; + guint i, num_surface_attribs = 0; + VAStatus va_status; + + if (G_LIKELY(filter->formats)) + return filter->formats; + +#if VA_CHECK_VERSION(0,34,0) + GST_VAAPI_DISPLAY_LOCK(filter->display); + va_status = vaQuerySurfaceAttributes(filter->va_display, filter->va_config, + NULL, &num_surface_attribs); + GST_VAAPI_DISPLAY_UNLOCK(filter->display); + if (!vaapi_check_status(va_status, "vaQuerySurfaceAttributes()")) + return NULL; + + surface_attribs = g_malloc(num_surface_attribs * sizeof(*surface_attribs)); + if (!surface_attribs) + return NULL; + + GST_VAAPI_DISPLAY_LOCK(filter->display); + va_status = vaQuerySurfaceAttributes(filter->va_display, filter->va_config, + surface_attribs, &num_surface_attribs); + GST_VAAPI_DISPLAY_UNLOCK(filter->display); + if (!vaapi_check_status(va_status, "vaQuerySurfaceAttributes()")) + return NULL; + + filter->formats = g_array_sized_new(FALSE, FALSE, sizeof(GstVideoFormat), + num_surface_attribs); + if (!filter->formats) + goto error; + + for (i = 0; i < num_surface_attribs; i++) { + const VASurfaceAttrib * const surface_attrib = &surface_attribs[i]; + GstVideoFormat format; + + if (surface_attrib->type != VASurfaceAttribPixelFormat) + continue; + if (!(surface_attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) + continue; + + format = gst_vaapi_video_format_from_va_fourcc( + surface_attrib->value.value.i); + if (format == GST_VIDEO_FORMAT_UNKNOWN) + continue; + g_array_append_val(filter->formats, format); + } +#endif + + g_free(surface_attribs); + return filter->formats; + +error: + g_free(surface_attribs); + return NULL; +} + +static inline gboolean +is_special_format(GstVideoFormat format) +{ + return format == GST_VIDEO_FORMAT_UNKNOWN || + format == GST_VIDEO_FORMAT_ENCODED; +} + +static gboolean +find_format(GstVaapiFilter *filter, GstVideoFormat format) +{ + guint i; + + if (is_special_format(format) || !filter->formats) + return FALSE; + + for (i = 0; i < filter->formats->len; i++) { + if (g_array_index(filter->formats, GstVideoFormat, i) == format) + return TRUE; + } + return FALSE; +} + +/* ------------------------------------------------------------------------- */ +/* --- Interface --- */ +/* ------------------------------------------------------------------------- */ + +#if USE_VA_VPP +static gboolean +gst_vaapi_filter_init(GstVaapiFilter *filter, GstVaapiDisplay *display) +{ + VAStatus va_status; + + filter->display = gst_vaapi_display_ref(display); + filter->va_display = GST_VAAPI_DISPLAY_VADISPLAY(display); + filter->va_config = VA_INVALID_ID; + filter->va_context = VA_INVALID_ID; + filter->format = DEFAULT_FORMAT; + + if (!GST_VAAPI_DISPLAY_HAS_VPP(display)) + return FALSE; + + va_status = vaCreateConfig(filter->va_display, VAProfileNone, + VAEntrypointVideoProc, NULL, 0, &filter->va_config); + if (!vaapi_check_status(va_status, "vaCreateConfig() [VPP]")) + return FALSE; + + va_status = vaCreateContext(filter->va_display, filter->va_config, 0, 0, 0, + NULL, 0, &filter->va_context); + if (!vaapi_check_status(va_status, "vaCreateContext() [VPP]")) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_filter_finalize(GstVaapiFilter *filter) +{ + guint i; + + GST_VAAPI_DISPLAY_LOCK(filter->display); + if (filter->operations) { + for (i = 0; i < filter->operations->len; i++) { + GstVaapiFilterOpData * const op_data = + g_ptr_array_index(filter->operations, i); + vaapi_destroy_buffer(filter->va_display, &op_data->va_buffer); + } + g_ptr_array_unref(filter->operations); + filter->operations = NULL; + } + + if (filter->va_context != VA_INVALID_ID) { + vaDestroyContext(filter->va_display, filter->va_context); + filter->va_context = VA_INVALID_ID; + } + + if (filter->va_config != VA_INVALID_ID) { + vaDestroyConfig(filter->va_display, filter->va_config); + filter->va_config = VA_INVALID_ID; + } + GST_VAAPI_DISPLAY_UNLOCK(filter->display); + gst_vaapi_display_replace(&filter->display, NULL); + + if (filter->formats) { + g_array_unref(filter->formats); + filter->formats = NULL; + } +} + +static inline const GstVaapiMiniObjectClass * +gst_vaapi_filter_class(void) +{ + static const GstVaapiMiniObjectClass GstVaapiFilterClass = { + sizeof(GstVaapiFilter), + (GDestroyNotify)gst_vaapi_filter_finalize + }; + return &GstVaapiFilterClass; +} +#endif + +/** + * gst_vaapi_filter_new: + * @display: a #GstVaapiDisplay + * + * Creates a new #GstVaapiFilter set up to operate in "identity" + * mode. This means that no other operation than scaling is performed. + * + * Return value: the newly created #GstVaapiFilter object + */ +GstVaapiFilter * +gst_vaapi_filter_new(GstVaapiDisplay *display) +{ +#if USE_VA_VPP + GstVaapiFilter *filter; + + filter = (GstVaapiFilter *) + gst_vaapi_mini_object_new0(gst_vaapi_filter_class()); + if (!filter) + return NULL; + + if (!gst_vaapi_filter_init(filter, display)) + goto error; + return filter; + +error: + gst_vaapi_filter_unref(filter); + return NULL; +#else + GST_WARNING("video processing is not supported, " + "please consider an upgrade to VA-API >= 0.34"); + return NULL; +#endif +} + +/** + * gst_vaapi_filter_ref: + * @filter: a #GstVaapiFilter + * + * Atomically increases the reference count of the given @filter by one. + * + * Returns: The same @filter argument + */ +GstVaapiFilter * +gst_vaapi_filter_ref(GstVaapiFilter *filter) +{ + g_return_val_if_fail(filter != NULL, NULL); + + return GST_VAAPI_FILTER(gst_vaapi_mini_object_ref( + GST_VAAPI_MINI_OBJECT(filter))); +} + +/** + * gst_vaapi_filter_unref: + * @filter: a #GstVaapiFilter + * + * Atomically decreases the reference count of the @filter by one. If + * the reference count reaches zero, the filter will be free'd. + */ +void +gst_vaapi_filter_unref(GstVaapiFilter *filter) +{ + g_return_if_fail(filter != NULL); + + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(filter)); +} + +/** + * gst_vaapi_filter_replace: + * @old_filter_ptr: a pointer to a #GstVaapiFilter + * @new_filter: a #GstVaapiFilter + * + * Atomically replaces the filter held in @old_filter_ptr with + * @new_filter. This means that @old_filter_ptr shall reference a + * valid filter. However, @new_filter can be NULL. + */ +void +gst_vaapi_filter_replace(GstVaapiFilter **old_filter_ptr, + GstVaapiFilter *new_filter) +{ + g_return_if_fail(old_filter_ptr != NULL); + + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)old_filter_ptr, + GST_VAAPI_MINI_OBJECT(new_filter)); +} + +/** + * gst_vaapi_filter_get_operations: + * @filter: a #GstVaapiFilter, or %NULL + * + * Determines the set of supported operations for video processing. + * The caller owns an extra reference to the resulting array of + * #GstVaapiFilterOpInfo elements, so it shall be released with + * g_ptr_array_unref() after usage. + * + * If @filter is %NULL, then this function returns the video + * processing operations supported by this library. + * + * Return value: the set of supported operations, or %NULL if an error + * occurred. + */ +GPtrArray * +gst_vaapi_filter_get_operations(GstVaapiFilter *filter) +{ +#if USE_VA_VPP + return ensure_operations(filter); +#else + return NULL; +#endif +} + +/** + * gst_vaapi_filter_set_operation: + * @filter: a #GstVaapiFilter + * @op: a #GstVaapiFilterOp + * @value: the @op settings + * + * Enable the specified operation @op to be performed during video + * processing, i.e. in gst_vaapi_filter_process(). The @value argument + * specifies the operation settings. e.g. deinterlacing method for + * deinterlacing, denoising level for noise reduction, etc. + * + * If @value is %NULL, then this function resets the operation + * settings to their default values. + * + * Return value: %TRUE if the specified operation may be supported, + * %FALSE otherwise + */ +gboolean +gst_vaapi_filter_set_operation(GstVaapiFilter *filter, GstVaapiFilterOp op, + const GValue *value) +{ +#if USE_VA_VPP + GstVaapiFilterOpData *op_data; + + g_return_val_if_fail(filter != NULL, FALSE); + + op_data = find_operation(filter, op); + if (!op_data) + return FALSE; + + if (value && !G_VALUE_HOLDS(value, G_PARAM_SPEC_VALUE_TYPE(op_data->pspec))) + return FALSE; + + switch (op) { + case GST_VAAPI_FILTER_OP_FORMAT: + return gst_vaapi_filter_set_format(filter, value ? + g_value_get_enum(value) : DEFAULT_FORMAT); + default: + break; + } +#endif + return FALSE; +} + +/** + * gst_vaapi_filter_process: + * @filter: a #GstVaapiFilter + * @src_surface: the source @GstVaapiSurface + * @dst_surface: the destination @GstVaapiSurface + * @flags: #GstVaapiSurfaceRenderFlags that apply to @src_surface + * + * Applies the operations currently defined in the @filter to + * @src_surface and return the output in @dst_surface. The order of + * operations is determined in a way that suits best the underlying + * hardware. i.e. the only guarantee held is the generated outcome, + * not any specific order of operations. + * + * Return value: a #GstVaapiFilterStatus + */ +static GstVaapiFilterStatus +gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter, + GstVaapiSurface *src_surface, GstVaapiSurface *dst_surface, guint flags) +{ +#if USE_VA_VPP + VAProcPipelineParameterBuffer *pipeline_param = NULL; + VABufferID pipeline_param_buf_id; + VABufferID filters[N_PROPERTIES]; + guint i, num_filters = 0; + VAStatus va_status; + VARectangle src_rect, dst_rect; + + if (!ensure_operations(filter)) + return GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED; + + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = GST_VAAPI_SURFACE_WIDTH(src_surface); + src_rect.height = GST_VAAPI_SURFACE_HEIGHT(src_surface); + + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = GST_VAAPI_SURFACE_WIDTH(dst_surface); + dst_rect.height = GST_VAAPI_SURFACE_HEIGHT(dst_surface); + + for (i = 0, num_filters = 0; i < filter->operations->len; i++) { + GstVaapiFilterOpData * const op_data = + g_ptr_array_index(filter->operations, i); + if (!op_data->is_enabled) + continue; + if (op_data->va_buffer == VA_INVALID_ID) { + GST_ERROR("invalid VA buffer for operation %s", + g_param_spec_get_name(op_data->pspec)); + goto error; + } + filters[num_filters++] = op_data->va_buffer; + } + + if (!vaapi_create_buffer(filter->va_display, filter->va_context, + VAProcPipelineParameterBufferType, sizeof(*pipeline_param), + NULL, &pipeline_param_buf_id, (gpointer *)&pipeline_param)) + goto error; + + memset(pipeline_param, 0, sizeof(*pipeline_param)); + pipeline_param->surface = GST_VAAPI_OBJECT_ID(src_surface); + pipeline_param->surface_region = &src_rect; + pipeline_param->surface_color_standard = VAProcColorStandardNone; + pipeline_param->output_region = &dst_rect; + pipeline_param->output_color_standard = VAProcColorStandardNone; + pipeline_param->output_background_color = 0xff000000; + pipeline_param->filter_flags = from_GstVaapiSurfaceRenderFlags(flags); + pipeline_param->filters = filters; + pipeline_param->num_filters = num_filters; + + vaapi_unmap_buffer(filter->va_display, pipeline_param_buf_id, NULL); + + va_status = vaBeginPicture(filter->va_display, filter->va_context, + GST_VAAPI_OBJECT_ID(dst_surface)); + if (!vaapi_check_status(va_status, "vaBeginPicture()")) + goto error; + + va_status = vaRenderPicture(filter->va_display, filter->va_context, + &pipeline_param_buf_id, 1); + if (!vaapi_check_status(va_status, "vaRenderPicture()")) + goto error; + + va_status = vaEndPicture(filter->va_display, filter->va_context); + if (!vaapi_check_status(va_status, "vaEndPicture()")) + goto error; + return GST_VAAPI_FILTER_STATUS_SUCCESS; + +error: + vaDestroyBuffer(filter->va_display, pipeline_param_buf_id); + return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED; +#endif + return GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_OPERATION; +} + +GstVaapiFilterStatus +gst_vaapi_filter_process(GstVaapiFilter *filter, GstVaapiSurface *src_surface, + GstVaapiSurface *dst_surface, guint flags) +{ + GstVaapiFilterStatus status; + + g_return_val_if_fail(filter != NULL, + GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail(src_surface != NULL, + GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail(dst_surface != NULL, + GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER); + + GST_VAAPI_DISPLAY_LOCK(filter->display); + status = gst_vaapi_filter_process_unlocked(filter, + src_surface, dst_surface, flags); + GST_VAAPI_DISPLAY_UNLOCK(filter->display); + return status; +} + +/** + * gst_vaapi_filter_get_formats: + * @filter: a #GstVaapiFilter + * + * Determines the set of supported source or target formats for video + * processing. The caller owns an extra reference to the resulting + * array of #GstVideoFormat elements, so it shall be released with + * g_array_unref() after usage. + * + * Return value: the set of supported target formats for video processing. + */ +GArray * +gst_vaapi_filter_get_formats(GstVaapiFilter *filter) +{ + g_return_val_if_fail(filter != NULL, NULL); + + return ensure_formats(filter); +} + +/** + * gst_vaapi_filter_set_format: + * @filter: a #GstVaapiFilter + * @format: the target surface format + * + * Sets the desired pixel format of the resulting video processing + * operations. + * + * If @format is #GST_VIDEO_FORMAT_UNKNOWN, the filter will assume iso + * format conversion, i.e. no color conversion at all and the target + * surface format shall match the source surface format. + * + * If @format is #GST_VIDEO_FORMAT_ENCODED, the filter will use the pixel + * format of the target surface passed to gst_vaapi_filter_process(). + * + * Return value: %TRUE if the color conversion to the specified @format + * may be supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_format(GstVaapiFilter *filter, GstVideoFormat format) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + if (!ensure_formats(filter)) + return FALSE; + + if (!is_special_format(format) && !find_format(filter, format)) + return FALSE; + + filter->format = format; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h new file mode 100644 index 0000000000..eb7d4f7318 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -0,0 +1,104 @@ +/* + * gstvaapifilter.h - Video processing abstraction + * + * Copyright (C) 2013 Intel Corporation + * + * 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 +#include + +G_BEGIN_DECLS + +typedef struct _GstVaapiFilter GstVaapiFilter; +typedef struct _GstVaapiFilterOpInfo GstVaapiFilterOpInfo; + +/** + * @GST_VAAPI_FILTER_OP_FORMAT: Force output pixel format (#GstVideoFormat). + * + * The set of operations that could be applied to the filter. + */ +typedef enum { + GST_VAAPI_FILTER_OP_FORMAT = 1, +} 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; + +GstVaapiFilter * +gst_vaapi_filter_new(GstVaapiDisplay *display); + +GstVaapiFilter * +gst_vaapi_filter_ref(GstVaapiFilter *filter); + +void +gst_vaapi_filter_unref(GstVaapiFilter *filter); + +void +gst_vaapi_filter_replace(GstVaapiFilter **old_filter_ptr, + GstVaapiFilter *new_filter); + +GPtrArray * +gst_vaapi_filter_get_operations(GstVaapiFilter *filter); + +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); + +#endif /* GST_VAAPI_FILTER_H */ From 87c8d28499d0934f219bbe894ae755aaafe31258 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 25 Jul 2013 13:55:15 +0200 Subject: [PATCH 1299/3781] filter: add helper functions. Add helper functions to ensure an operation VA buffer is allocated to the right size; that filter caps get parsed and assigned to the right operation too; and that float parameters are correctly scaled to fit the reported range from the VA driver. --- gst-libs/gst/vaapi/gstvaapifilter.c | 130 +++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index ce8556e0ea..770af0a0f4 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -116,6 +116,55 @@ vpp_get_filters(GstVaapiFilter *filter, guint *num_filters_ptr) GST_VAAPI_DISPLAY_UNLOCK(filter->display); return filters; } + +static gpointer +vpp_get_filter_caps_unlocked( + GstVaapiFilter *filter, VAProcFilterType type, + guint cap_size, guint *num_caps_ptr) +{ + gpointer caps; + guint num_caps = 1; + VAStatus va_status; + + caps = g_malloc(cap_size); + if (!caps) + goto error; + + va_status = vaQueryVideoProcFilterCaps(filter->va_display, + filter->va_context, type, caps, &num_caps); + + // Try to reallocate to the expected number of filters + if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) { + gpointer const new_caps = g_try_realloc_n(caps, num_caps, cap_size); + if (!new_caps) + goto error; + caps = new_caps; + + va_status = vaQueryVideoProcFilterCaps(filter->va_display, + filter->va_context, type, caps, &num_caps); + } + if (!vaapi_check_status(va_status, "vaQueryVideoProcFilterCaps()")) + goto error; + + *num_caps_ptr = num_caps; + return caps; + +error: + g_free(caps); + return NULL; +} + +static gpointer +vpp_get_filter_caps(GstVaapiFilter *filter, VAProcFilterType type, + guint cap_size, guint *num_caps_ptr) +{ + gpointer caps; + + GST_VAAPI_DISPLAY_LOCK(filter->display); + caps = vpp_get_filter_caps_unlocked(filter, type, cap_size, num_caps_ptr); + GST_VAAPI_DISPLAY_UNLOCK(filter->display); + return caps; +} #endif /* ------------------------------------------------------------------------- */ @@ -221,6 +270,61 @@ op_data_unref(gpointer data) op_data_free(op_data); } +/* Ensure capability info is set up for the VA filter we are interested in */ +static gboolean +op_data_ensure_caps(GstVaapiFilterOpData *op_data, gpointer filter_caps, + guint num_filter_caps) +{ + guchar *filter_cap = filter_caps; + guint i; + + // Find the VA filter cap matching the op info sub-type + if (op_data->va_subtype) { + for (i = 0; i < num_filter_caps; i++) { + /* XXX: sub-type shall always be the first field */ + if (op_data->va_subtype == *(guint *)filter_cap) { + num_filter_caps = 1; + break; + } + filter_cap += op_data->va_cap_size; + } + if (i == num_filter_caps) + return FALSE; + } + op_data->va_caps = g_memdup(filter_cap, + op_data->va_cap_size * num_filter_caps); + return op_data->va_caps != NULL; +} + +/* Scale the filter value wrt. library spec and VA driver spec */ +static gboolean +op_data_get_value_float(GstVaapiFilterOpData *op_data, + const VAProcFilterValueRange *range, gfloat value, gfloat *out_value_ptr) +{ + GParamSpecFloat * const pspec = G_PARAM_SPEC_FLOAT(op_data->pspec); + gfloat out_value; + + g_return_val_if_fail(range != NULL, FALSE); + g_return_val_if_fail(out_value_ptr != NULL, FALSE); + + if (value < pspec->minimum || value > pspec->maximum) + return FALSE; + + // Scale wrt. the medium ("default") value + out_value = range->default_value; + if (value > pspec->default_value) + out_value += ((value - pspec->default_value) / + (pspec->maximum - pspec->default_value) * + (range->max_value - range->default_value)); + else if (value < pspec->default_value) + out_value -= ((pspec->default_value - value) / + (pspec->default_value - pspec->minimum) * + (range->default_value - range->min_value)); + + *out_value_ptr = out_value; + return TRUE; +} + /* Get default list of operations supported by the library */ static GPtrArray * get_operations_default(void) @@ -257,7 +361,8 @@ get_operations_ordered(GstVaapiFilter *filter, GPtrArray *default_ops) { GPtrArray *ops; VAProcFilterType *filters; - guint i, j, num_filters; + gpointer filter_caps = NULL; + guint i, j, num_filters, num_filter_caps = 0; ops = g_ptr_array_new_full(default_ops->len, op_data_unref); if (!ops) @@ -286,8 +391,19 @@ get_operations_ordered(GstVaapiFilter *filter, GPtrArray *default_ops) g_ptr_array_index(default_ops, j); if (op_data->va_type != va_type) continue; + + if (!filter_caps) { + filter_caps = vpp_get_filter_caps(filter, va_type, + op_data->va_cap_size, &num_filter_caps); + if (!filter_caps) + goto error; + } + if (!op_data_ensure_caps(op_data, filter_caps, num_filter_caps)) + goto error; g_ptr_array_add(ops, op_data_ref(op_data)); } + free(filter_caps); + filter_caps = NULL; } if (filter->operations) @@ -299,6 +415,7 @@ get_operations_ordered(GstVaapiFilter *filter, GPtrArray *default_ops) return ops; error: + g_free(filter_caps); g_free(filters); g_ptr_array_unref(ops); g_ptr_array_unref(default_ops); @@ -340,6 +457,17 @@ find_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) return NULL; } +/* Ensure the operation's VA buffer is allocated */ +static inline gboolean +op_ensure_buffer(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data) +{ + if (G_LIKELY(op_data->va_buffer != VA_INVALID_ID)) + return TRUE; + return vaapi_create_buffer(filter->va_display, filter->va_context, + VAProcFilterParameterBufferType, op_data->va_buffer_size, NULL, + &op_data->va_buffer, NULL); +} + /* ------------------------------------------------------------------------- */ /* --- Surface Formats --- */ /* ------------------------------------------------------------------------- */ From 81395418e9c187a4fc4dba55948efe03177966c8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Jul 2013 14:22:28 +0200 Subject: [PATCH 1300/3781] filter: add support for frame cropping. Frame cropping is defined with a GstVaapiRectangle value. The default behaviour is to treat the source surface as a whole --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapifilter.c | 66 +++++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapifilter.h | 6 +++ 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 23a804f04a..68d1bc9087 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -386,6 +386,7 @@ gst_vaapi_filter_get_operations gst_vaapi_filter_get_formats gst_vaapi_filter_set_operation gst_vaapi_filter_set_format +gst_vaapi_filter_set_cropping_rectangle GST_VAAPI_FILTER
diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 770af0a0f4..9cf4f81151 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -22,6 +22,7 @@ #include "sysdeps.h" #include "gstvaapifilter.h" #include "gstvaapiutils.h" +#include "gstvaapivalue.h" #include "gstvaapiminiobject.h" #include "gstvaapidisplay_priv.h" #include "gstvaapisurface_priv.h" @@ -62,6 +63,8 @@ struct _GstVaapiFilter { GPtrArray *operations; GstVideoFormat format; GArray *formats; + GstVaapiRectangle crop_rect; + guint use_crop_rect : 1; }; /* ------------------------------------------------------------------------- */ @@ -178,6 +181,7 @@ enum { PROP_0, PROP_FORMAT = GST_VAAPI_FILTER_OP_FORMAT, + PROP_CROP = GST_VAAPI_FILTER_OP_CROP, N_PROPERTIES }; @@ -200,6 +204,18 @@ init_properties(void) GST_TYPE_VIDEO_FORMAT, DEFAULT_FORMAT, G_PARAM_READWRITE); + + /** + * GstVaapiFilter:crop-rect: + * + * The cropping rectangle, expressed as a #GstVaapiRectangle. + */ + g_properties[PROP_CROP] = + g_param_spec_boxed("crop-rect", + "Cropping Rectangle", + "The cropping rectangle", + GST_VAAPI_TYPE_RECTANGLE, + G_PARAM_READWRITE); } static void @@ -234,6 +250,7 @@ op_data_new(GstVaapiFilterOp op, GParamSpec *pspec) switch (op) { case GST_VAAPI_FILTER_OP_FORMAT: + case GST_VAAPI_FILTER_OP_CROP: op_data->va_type = VAProcFilterNone; break; default: @@ -776,6 +793,9 @@ gst_vaapi_filter_set_operation(GstVaapiFilter *filter, GstVaapiFilterOp op, case GST_VAAPI_FILTER_OP_FORMAT: return gst_vaapi_filter_set_format(filter, value ? g_value_get_enum(value) : DEFAULT_FORMAT); + case GST_VAAPI_FILTER_OP_CROP: + return gst_vaapi_filter_set_cropping_rectangle(filter, value ? + g_value_get_boxed(value) : NULL); default: break; } @@ -813,10 +833,26 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter, if (!ensure_operations(filter)) return GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED; - src_rect.x = 0; - src_rect.y = 0; - src_rect.width = GST_VAAPI_SURFACE_WIDTH(src_surface); - src_rect.height = GST_VAAPI_SURFACE_HEIGHT(src_surface); + if (filter->use_crop_rect) { + const GstVaapiRectangle * const crop_rect = &filter->crop_rect; + + if ((crop_rect->x + crop_rect->width > + GST_VAAPI_SURFACE_WIDTH(src_surface)) || + (crop_rect->y + crop_rect->height > + GST_VAAPI_SURFACE_HEIGHT(src_surface))) + goto error; + + src_rect.x = crop_rect->x; + src_rect.y = crop_rect->y; + src_rect.width = crop_rect->width; + src_rect.height = crop_rect->height; + } + else { + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = GST_VAAPI_SURFACE_WIDTH(src_surface); + src_rect.height = GST_VAAPI_SURFACE_HEIGHT(src_surface); + } dst_rect.x = 0; dst_rect.y = 0; @@ -947,3 +983,25 @@ gst_vaapi_filter_set_format(GstVaapiFilter *filter, GstVideoFormat format) filter->format = format; return TRUE; } + +/** + * gst_vaapi_filter_set_cropping_rectangle: + * @filter: a #GstVaapiFilter + * @rect: the cropping region + * + * Sets the source surface cropping rectangle to use during the video + * processing. If @rect is %NULL, the whole source surface will be used. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_cropping_rectangle(GstVaapiFilter *filter, + const GstVaapiRectangle *rect) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + filter->use_crop_rect = rect != NULL; + if (filter->use_crop_rect) + filter->crop_rect = *rect; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index eb7d4f7318..800fc418a3 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -32,11 +32,13 @@ typedef struct _GstVaapiFilterOpInfo GstVaapiFilterOpInfo; /** * @GST_VAAPI_FILTER_OP_FORMAT: Force output pixel format (#GstVideoFormat). + * @GST_VAAPI_FILTER_OP_CROP: Crop source surface (#GstVaapiRectangle). * * The set of operations that could be applied to the filter. */ typedef enum { GST_VAAPI_FILTER_OP_FORMAT = 1, + GST_VAAPI_FILTER_OP_CROP, } GstVaapiFilterOp; /** @@ -101,4 +103,8 @@ gst_vaapi_filter_get_formats(GstVaapiFilter *filter); gboolean gst_vaapi_filter_set_format(GstVaapiFilter *filter, GstVideoFormat format); +gboolean +gst_vaapi_filter_set_cropping_rectangle(GstVaapiFilter *filter, + const GstVaapiRectangle *rect); + #endif /* GST_VAAPI_FILTER_H */ From 22f55bd51338fbd4c0e35d42ac143debc02d4fb5 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Wed, 17 Jul 2013 17:29:41 +0800 Subject: [PATCH 1301/3781] filter: add support for denoising. Noise reduction is configured with a float value. The supported range is 0.0 .. 1.0 with 0.0 being the default, and that means no denoise operation at all. Signed-off-by: Gwenole Beauchesne --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapifilter.c | 88 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 5 ++ 3 files changed, 94 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 68d1bc9087..0fb0c82f95 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -387,6 +387,7 @@ gst_vaapi_filter_get_formats gst_vaapi_filter_set_operation gst_vaapi_filter_set_format gst_vaapi_filter_set_cropping_rectangle +gst_vaapi_filter_set_denoising_level GST_VAAPI_FILTER
diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 9cf4f81151..d27a77f187 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -182,6 +182,7 @@ enum { PROP_FORMAT = GST_VAAPI_FILTER_OP_FORMAT, PROP_CROP = GST_VAAPI_FILTER_OP_CROP, + PROP_DENOISE = GST_VAAPI_FILTER_OP_DENOISE, N_PROPERTIES }; @@ -216,6 +217,18 @@ init_properties(void) "The cropping rectangle", GST_VAAPI_TYPE_RECTANGLE, G_PARAM_READWRITE); + + /** + * GstVaapiFilter:denoise: + * + * The level of noise reduction to apply. + */ + g_properties[PROP_DENOISE] = + g_param_spec_float("denoise", + "Denoising Level", + "The level of denoising to apply", + 0.0, 1.0, 0.0, + G_PARAM_READWRITE); } static void @@ -253,6 +266,11 @@ op_data_new(GstVaapiFilterOp op, GParamSpec *pspec) case GST_VAAPI_FILTER_OP_CROP: op_data->va_type = VAProcFilterNone; break; + case GST_VAAPI_FILTER_OP_DENOISE: + op_data->va_type = VAProcFilterNoiseReduction; + op_data->va_cap_size = sizeof(VAProcFilterCap); + op_data->va_buffer_size = sizeof(VAProcFilterParameterBuffer); + break; default: g_assert(0 && "unsupported operation"); goto error; @@ -485,6 +503,53 @@ op_ensure_buffer(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data) &op_data->va_buffer, NULL); } +/* Update a generic filter (float value) */ +#if USE_VA_VPP +static gboolean +op_set_generic_unlocked(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, + gfloat value) +{ + VAProcFilterParameterBuffer *buf; + VAProcFilterCap *filter_cap; + gfloat va_value; + + if (!op_data || !op_ensure_buffer(filter, op_data)) + return FALSE; + + op_data->is_enabled = + (value != G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value); + if (!op_data->is_enabled) + return TRUE; + + filter_cap = op_data->va_caps; + if (!op_data_get_value_float(op_data, &filter_cap->range, value, &va_value)) + return FALSE; + + buf = vaapi_map_buffer(filter->va_display, op_data->va_buffer); + if (!buf) + return FALSE; + + buf->type = op_data->va_type; + buf->value = va_value; + vaapi_unmap_buffer(filter->va_display, op_data->va_buffer, NULL); + return TRUE; +} +#endif + +static inline gboolean +op_set_generic(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, + gfloat value) +{ + gboolean success = FALSE; + +#if USE_VA_VPP + GST_VAAPI_DISPLAY_LOCK(filter->display); + success = op_set_generic_unlocked(filter, op_data, value); + GST_VAAPI_DISPLAY_UNLOCK(filter->display); +#endif + return success; +} + /* ------------------------------------------------------------------------- */ /* --- Surface Formats --- */ /* ------------------------------------------------------------------------- */ @@ -796,6 +861,10 @@ gst_vaapi_filter_set_operation(GstVaapiFilter *filter, GstVaapiFilterOp op, case GST_VAAPI_FILTER_OP_CROP: return gst_vaapi_filter_set_cropping_rectangle(filter, value ? g_value_get_boxed(value) : NULL); + case GST_VAAPI_FILTER_OP_DENOISE: + return op_set_generic(filter, op_data, + (value ? g_value_get_float(value) : + G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value)); default: break; } @@ -1005,3 +1074,22 @@ gst_vaapi_filter_set_cropping_rectangle(GstVaapiFilter *filter, filter->crop_rect = *rect; return TRUE; } + +/** + * gst_vaapi_filter_set_denoising_level: + * @filter: a #GstVaapiFilter + * @level: the level of noise reduction to apply + * + * Sets the noise reduction level to apply. If @level is 0.0f, this + * corresponds to disabling the noise reduction algorithm. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_denoising_level(GstVaapiFilter *filter, gfloat level) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + return op_set_generic(filter, + find_operation(filter, GST_VAAPI_FILTER_OP_DENOISE), level); +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 800fc418a3..af6688a131 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -33,12 +33,14 @@ 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). * * 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, } GstVaapiFilterOp; /** @@ -107,4 +109,7 @@ gboolean gst_vaapi_filter_set_cropping_rectangle(GstVaapiFilter *filter, const GstVaapiRectangle *rect); +gboolean +gst_vaapi_filter_set_denoising_level(GstVaapiFilter *filter, gfloat level); + #endif /* GST_VAAPI_FILTER_H */ From a854768a8091ffa700f4e542690a9dd02066634b Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Wed, 17 Jul 2013 17:37:16 +0800 Subject: [PATCH 1302/3781] filter: add support for sharpening. Sharpening is configured with a float value. The supported range is -1.0 .. 1.0 with 0.0 being the default, and that means no sharpening operation at all. Signed-off-by: Gwenole Beauchesne --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapifilter.c | 38 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 5 ++++ 3 files changed, 44 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 0fb0c82f95..049f8f7c2f 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -388,6 +388,7 @@ gst_vaapi_filter_set_operation gst_vaapi_filter_set_format gst_vaapi_filter_set_cropping_rectangle gst_vaapi_filter_set_denoising_level +gst_vaapi_filter_set_sharpening_level GST_VAAPI_FILTER diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index d27a77f187..d6e84a4507 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -183,6 +183,7 @@ enum { PROP_FORMAT = GST_VAAPI_FILTER_OP_FORMAT, PROP_CROP = GST_VAAPI_FILTER_OP_CROP, PROP_DENOISE = GST_VAAPI_FILTER_OP_DENOISE, + PROP_SHARPEN = GST_VAAPI_FILTER_OP_SHARPEN, N_PROPERTIES }; @@ -229,6 +230,19 @@ init_properties(void) "The level of denoising to apply", 0.0, 1.0, 0.0, G_PARAM_READWRITE); + + /** + * GstVaapiFilter:sharpen: + * + * The level of sharpening to apply for positive values, or the + * level of blurring for negative values. + */ + g_properties[PROP_SHARPEN] = + g_param_spec_float("sharpen", + "Sharpening Level", + "The level of sharpening/blurring to apply", + -1.0, 1.0, 0.0, + G_PARAM_READWRITE); } static void @@ -271,6 +285,11 @@ op_data_new(GstVaapiFilterOp op, GParamSpec *pspec) op_data->va_cap_size = sizeof(VAProcFilterCap); op_data->va_buffer_size = sizeof(VAProcFilterParameterBuffer); break; + case GST_VAAPI_FILTER_OP_SHARPEN: + op_data->va_type = VAProcFilterSharpening; + op_data->va_cap_size = sizeof(VAProcFilterCap); + op_data->va_buffer_size = sizeof(VAProcFilterParameterBuffer); + break; default: g_assert(0 && "unsupported operation"); goto error; @@ -862,6 +881,7 @@ gst_vaapi_filter_set_operation(GstVaapiFilter *filter, GstVaapiFilterOp op, return gst_vaapi_filter_set_cropping_rectangle(filter, value ? g_value_get_boxed(value) : NULL); case GST_VAAPI_FILTER_OP_DENOISE: + case GST_VAAPI_FILTER_OP_SHARPEN: return op_set_generic(filter, op_data, (value ? g_value_get_float(value) : G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value)); @@ -1093,3 +1113,21 @@ gst_vaapi_filter_set_denoising_level(GstVaapiFilter *filter, gfloat level) return op_set_generic(filter, find_operation(filter, GST_VAAPI_FILTER_OP_DENOISE), level); } + +/** + * gst_vaapi_filter_set_sharpening_level: + * @filter: a #GstVaapiFilter + * @level: the sharpening factor + * + * Enables noise reduction with the specified factor. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_sharpening_level(GstVaapiFilter *filter, gfloat level) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + return op_set_generic(filter, + find_operation(filter, GST_VAAPI_FILTER_OP_SHARPEN), level); +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index af6688a131..977d929500 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -34,6 +34,7 @@ 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). * * The set of operations that could be applied to the filter. */ @@ -41,6 +42,7 @@ typedef enum { GST_VAAPI_FILTER_OP_FORMAT = 1, GST_VAAPI_FILTER_OP_CROP, GST_VAAPI_FILTER_OP_DENOISE, + GST_VAAPI_FILTER_OP_SHARPEN, } GstVaapiFilterOp; /** @@ -112,4 +114,7 @@ gst_vaapi_filter_set_cropping_rectangle(GstVaapiFilter *filter, gboolean gst_vaapi_filter_set_denoising_level(GstVaapiFilter *filter, gfloat level); +gboolean +gst_vaapi_filter_set_sharpening_level(GstVaapiFilter *filter, gfloat level); + #endif /* GST_VAAPI_FILTER_H */ From 1d222d3b4ae6a5e8959a7231ff93ad7234900239 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Wed, 17 Jul 2013 17:40:41 +0800 Subject: [PATCH 1303/3781] filter: add support for color balance adjustment. Add ProcAmp (color balance) adjustments for hue, saturation, brightness and contrast. The respective range for each filter shall be the same as for the VA display attributes. Signed-off-by: Gwenole Beauchesne --- docs/reference/libs/libs-sections.txt | 4 + gst-libs/gst/vaapi/gstvaapifilter.c | 191 ++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 20 +++ 3 files changed, 215 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 049f8f7c2f..0aa16205fe 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -389,6 +389,10 @@ gst_vaapi_filter_set_format gst_vaapi_filter_set_cropping_rectangle gst_vaapi_filter_set_denoising_level gst_vaapi_filter_set_sharpening_level +gst_vaapi_filter_set_hue +gst_vaapi_filter_set_saturation +gst_vaapi_filter_set_brightness +gst_vaapi_filter_set_saturation GST_VAAPI_FILTER diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index d6e84a4507..4ac3c221fd 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -184,6 +184,10 @@ enum { PROP_CROP = GST_VAAPI_FILTER_OP_CROP, PROP_DENOISE = GST_VAAPI_FILTER_OP_DENOISE, PROP_SHARPEN = GST_VAAPI_FILTER_OP_SHARPEN, + PROP_HUE = GST_VAAPI_FILTER_OP_HUE, + PROP_SATURATION = GST_VAAPI_FILTER_OP_SATURATION, + PROP_BRIGHTNESS = GST_VAAPI_FILTER_OP_BRIGHTNESS, + PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST, N_PROPERTIES }; @@ -243,6 +247,58 @@ init_properties(void) "The level of sharpening/blurring to apply", -1.0, 1.0, 0.0, G_PARAM_READWRITE); + + /** + * GstVaapiFilter:hue: + * + * The color hue, expressed as a float value. Range is -180.0 to + * 180.0. Default value is 0.0 and represents no modification. + */ + g_properties[PROP_HUE] = + g_param_spec_float("hue", + "Hue", + "The color hue value", + -180.0, 180.0, 0.0, + G_PARAM_READWRITE); + + /** + * GstVaapiFilter:saturation: + * + * The color saturation, expressed as a float value. Range is 0.0 + * to 2.0. Default value is 1.0 and represents no modification. + */ + g_properties[PROP_SATURATION] = + g_param_spec_float("saturation", + "Saturation", + "The color saturation value", + 0.0, 2.0, 1.0, + G_PARAM_READWRITE); + + /** + * GstVaapiFilter:brightness: + * + * The color brightness, expressed as a float value. Range is -1.0 + * to 1.0. Default value is 0.0 and represents no modification. + */ + g_properties[PROP_BRIGHTNESS] = + g_param_spec_float("brightness", + "Brightness", + "The color brightness value", + -1.0, 1.0, 0.0, + G_PARAM_READWRITE); + + /** + * GstVaapiFilter:contrast: + * + * The color contrast, expressed as a float value. Range is 0.0 to + * 2.0. Default value is 1.0 and represents no modification. + */ + g_properties[PROP_CONTRAST] = + g_param_spec_float("contrast", + "Contrast", + "The color contrast value", + 0.0, 2.0, 1.0, + G_PARAM_READWRITE); } static void @@ -290,6 +346,14 @@ op_data_new(GstVaapiFilterOp op, GParamSpec *pspec) op_data->va_cap_size = sizeof(VAProcFilterCap); op_data->va_buffer_size = sizeof(VAProcFilterParameterBuffer); break; + case GST_VAAPI_FILTER_OP_HUE: + case GST_VAAPI_FILTER_OP_SATURATION: + case GST_VAAPI_FILTER_OP_BRIGHTNESS: + case GST_VAAPI_FILTER_OP_CONTRAST: + op_data->va_type = VAProcFilterColorBalance; + op_data->va_cap_size = sizeof(VAProcFilterCapColorBalance); + op_data->va_buffer_size = sizeof(VAProcFilterParameterBufferColorBalance); + break; default: g_assert(0 && "unsupported operation"); goto error; @@ -569,6 +633,54 @@ op_set_generic(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, return success; } +/* Update the color balance filter */ +#if USE_VA_VPP +static gboolean +op_set_color_balance_unlocked(GstVaapiFilter *filter, + GstVaapiFilterOpData *op_data, gfloat value) +{ + VAProcFilterParameterBufferColorBalance *buf; + VAProcFilterCapColorBalance *filter_cap; + gfloat va_value; + + if (!op_data || !op_ensure_buffer(filter, op_data)) + return FALSE; + + op_data->is_enabled = + (value != G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value); + if (!op_data->is_enabled) + return TRUE; + + filter_cap = op_data->va_caps; + if (!op_data_get_value_float(op_data, &filter_cap->range, value, &va_value)) + return FALSE; + + buf = vaapi_map_buffer(filter->va_display, op_data->va_buffer); + if (!buf) + return FALSE; + + buf->type = op_data->va_type; + buf->attrib = op_data->va_subtype; + buf->value = va_value; + vaapi_unmap_buffer(filter->va_display, op_data->va_buffer, NULL); + return TRUE; +} +#endif + +static inline gboolean +op_set_color_balance(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, + gfloat value) +{ + gboolean success = FALSE; + +#if USE_VA_VPP + GST_VAAPI_DISPLAY_LOCK(filter->display); + success = op_set_color_balance_unlocked(filter, op_data, value); + GST_VAAPI_DISPLAY_UNLOCK(filter->display); +#endif + return success; +} + /* ------------------------------------------------------------------------- */ /* --- Surface Formats --- */ /* ------------------------------------------------------------------------- */ @@ -885,6 +997,13 @@ gst_vaapi_filter_set_operation(GstVaapiFilter *filter, GstVaapiFilterOp op, return op_set_generic(filter, op_data, (value ? g_value_get_float(value) : G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value)); + case GST_VAAPI_FILTER_OP_HUE: + case GST_VAAPI_FILTER_OP_SATURATION: + case GST_VAAPI_FILTER_OP_BRIGHTNESS: + case GST_VAAPI_FILTER_OP_CONTRAST: + return op_set_color_balance(filter, op_data, + (value ? g_value_get_float(value) : + G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value)); default: break; } @@ -1131,3 +1250,75 @@ gst_vaapi_filter_set_sharpening_level(GstVaapiFilter *filter, gfloat level) return op_set_generic(filter, find_operation(filter, GST_VAAPI_FILTER_OP_SHARPEN), level); } + +/** + * gst_vaapi_filter_set_hue: + * @filter: a #GstVaapiFilter + * @value: the color hue value + * + * Enables color hue adjustment to the specified value. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_hue(GstVaapiFilter *filter, gfloat value) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + return op_set_color_balance(filter, + find_operation(filter, GST_VAAPI_FILTER_OP_HUE), value); +} + +/** + * gst_vaapi_filter_set_saturation: + * @filter: a #GstVaapiFilter + * @value: the color saturation value + * + * Enables color saturation adjustment to the specified value. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_saturation(GstVaapiFilter *filter, gfloat value) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + return op_set_color_balance(filter, + find_operation(filter, GST_VAAPI_FILTER_OP_SATURATION), value); +} + +/** + * gst_vaapi_filter_set_brightness: + * @filter: a #GstVaapiFilter + * @value: the color brightness value + * + * Enables color brightness adjustment to the specified value. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_brightness(GstVaapiFilter *filter, gfloat value) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + return op_set_color_balance(filter, + find_operation(filter, GST_VAAPI_FILTER_OP_BRIGHTNESS), value); +} + +/** + * gst_vaapi_filter_set_contrast: + * @filter: a #GstVaapiFilter + * @value: the color contrast value + * + * Enables color contrast adjustment to the specified value. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_contrast(GstVaapiFilter *filter, gfloat value) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + return op_set_color_balance(filter, + find_operation(filter, GST_VAAPI_FILTER_OP_CONTRAST), value); +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 977d929500..8da28d47be 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -35,6 +35,10 @@ typedef struct _GstVaapiFilterOpInfo GstVaapiFilterOpInfo; * @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). * * The set of operations that could be applied to the filter. */ @@ -43,6 +47,10 @@ typedef enum { 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, } GstVaapiFilterOp; /** @@ -117,4 +125,16 @@ 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); + #endif /* GST_VAAPI_FILTER_H */ From 944a7bd077fdc77c7383f975af45f0db262bff77 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Mon, 29 Jul 2013 09:23:50 +0800 Subject: [PATCH 1304/3781] filter: add initial support for deinterlacing. Add basic deinterlacing support, i.e. bob-deinterlacing whereby only the selected field from the input surface is kept for the target surface. Setting gst_vaapi_filter_set_deinterlacing() method argument to GST_VAAPI_DEINTERLACE_METHOD_NONE means to disable deinterlacing. Also move GstVaapiDeinterlaceMethod definition from vaapipostproc plug-in to libgstvaapi core library. Signed-off-by: Gwenole Beauchesne --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapifilter.c | 162 +++++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapifilter.h | 52 +++++++++ gst-libs/gst/vaapi/gstvaapiutils.c | 46 ++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 8 ++ gst/vaapi/gstvaapipostproc.c | 30 ----- gst/vaapi/gstvaapipostproc.h | 15 +-- 7 files changed, 269 insertions(+), 45 deletions(-) mode change 100644 => 100755 gst-libs/gst/vaapi/gstvaapifilter.c mode change 100644 => 100755 gst-libs/gst/vaapi/gstvaapifilter.h mode change 100644 => 100755 gst/vaapi/gstvaapipostproc.c mode change 100644 => 100755 gst/vaapi/gstvaapipostproc.h diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index 0aa16205fe..b70eaaaaa9 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -393,6 +393,7 @@ gst_vaapi_filter_set_hue gst_vaapi_filter_set_saturation gst_vaapi_filter_set_brightness gst_vaapi_filter_set_saturation +gst_vaapi_filter_set_deinterlacing GST_VAAPI_FILTER diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c old mode 100644 new mode 100755 index 4ac3c221fd..78ab1078ae --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -67,6 +67,60 @@ struct _GstVaapiFilter { guint use_crop_rect : 1; }; +/* ------------------------------------------------------------------------- */ +/* --- VPP Types --- */ +/* ------------------------------------------------------------------------- */ + +GType +gst_vaapi_deinterlace_method_get_type(void) +{ + static gsize g_type = 0; + + static const GEnumValue enum_values[] = { + { GST_VAAPI_DEINTERLACE_METHOD_NONE, + "Disable deinterlacing", "none" }, + { GST_VAAPI_DEINTERLACE_METHOD_BOB, + "Bob deinterlacing", "bob" }, +#if USE_VA_VPP + { GST_VAAPI_DEINTERLACE_METHOD_WEAVE, + "Weave deinterlacing", "weave" }, + { GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE, + "Motion adaptive deinterlacing", "motion-adaptive" }, + { GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED, + "Motion compensated deinterlacing", "motion-compensated" }, +#endif + { 0, NULL, NULL }, + }; + + if (g_once_init_enter(&g_type)) { + const GType type = + g_enum_register_static("GstVaapiDeinterlaceMethod", enum_values); + g_once_init_leave(&g_type, type); + } + return g_type; +} + +GType +gst_vaapi_deinterlace_flags_get_type(void) +{ + static gsize g_type = 0; + + static const GEnumValue enum_values[] = { + { GST_VAAPI_DEINTERLACE_FLAG_TFF, + "Top-field first", "top-field-first" }, + { GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD, + "One field", "one-field" }, + { 0, NULL, NULL } + }; + + if (g_once_init_enter(&g_type)) { + const GType type = + g_enum_register_static("GstVaapiDeinterlaceFlags", enum_values); + g_once_init_leave(&g_type, type); + } + return g_type; +} + /* ------------------------------------------------------------------------- */ /* --- VPP Helpers --- */ /* ------------------------------------------------------------------------- */ @@ -188,6 +242,7 @@ enum { PROP_SATURATION = GST_VAAPI_FILTER_OP_SATURATION, PROP_BRIGHTNESS = GST_VAAPI_FILTER_OP_BRIGHTNESS, PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST, + PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING, N_PROPERTIES }; @@ -299,6 +354,20 @@ init_properties(void) "The color contrast value", 0.0, 2.0, 1.0, G_PARAM_READWRITE); + + /** + * GstVaapiFilter:deinterlace-method: + * + * The deinterlacing algorithm to apply, expressed a an enum + * value. See #GstVaapiDeinterlaceMethod. + */ + g_properties[PROP_DEINTERLACING] = + g_param_spec_enum("deinterlace", + "Deinterlacing Method", + "Deinterlacing method to apply", + GST_VAAPI_TYPE_DEINTERLACE_METHOD, + GST_VAAPI_DEINTERLACE_METHOD_NONE, + G_PARAM_READWRITE); } static void @@ -354,6 +423,11 @@ op_data_new(GstVaapiFilterOp op, GParamSpec *pspec) op_data->va_cap_size = sizeof(VAProcFilterCapColorBalance); op_data->va_buffer_size = sizeof(VAProcFilterParameterBufferColorBalance); break; + case GST_VAAPI_FILTER_OP_DEINTERLACING: + op_data->va_type = VAProcFilterDeinterlacing; + op_data->va_cap_size = sizeof(VAProcFilterCapDeinterlacing); + op_data->va_buffer_size = sizeof(VAProcFilterParameterBufferDeinterlacing); + break; default: g_assert(0 && "unsupported operation"); goto error; @@ -409,9 +483,14 @@ op_data_ensure_caps(GstVaapiFilterOpData *op_data, gpointer filter_caps, if (i == num_filter_caps) return FALSE; } + op_data->va_caps = g_memdup(filter_cap, op_data->va_cap_size * num_filter_caps); - return op_data->va_caps != NULL; + if (!op_data->va_caps) + return FALSE; + + op_data->va_num_caps = num_filter_caps; + return TRUE; } /* Scale the filter value wrt. library spec and VA driver spec */ @@ -681,6 +760,59 @@ op_set_color_balance(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, return success; } +/* Update deinterlace filter */ +#if USE_VA_VPP +static gboolean +op_set_deinterlace_unlocked(GstVaapiFilter *filter, + GstVaapiFilterOpData *op_data, GstVaapiDeinterlaceMethod method, + guint flags) +{ + VAProcFilterParameterBufferDeinterlacing *buf; + const VAProcFilterCapDeinterlacing *filter_caps; + VAProcDeinterlacingType algorithm; + guint i; + + if (!op_data || !op_ensure_buffer(filter, op_data)) + return FALSE; + + op_data->is_enabled = (method != GST_VAAPI_DEINTERLACE_METHOD_NONE); + if (!op_data->is_enabled) + return TRUE; + + algorithm = from_GstVaapiDeinterlaceMethod(method); + for (i = 0, filter_caps = op_data->va_caps; i < op_data->va_num_caps; i++) { + if (filter_caps[i].type == algorithm) + break; + } + if (i == op_data->va_num_caps) + return FALSE; + + buf = vaapi_map_buffer(filter->va_display, op_data->va_buffer); + if (!buf) + return FALSE; + + buf->type = op_data->va_type; + buf->algorithm = algorithm; + buf->flags = from_GstVaapiDeinterlaceFlags(flags); + vaapi_unmap_buffer(filter->va_display, op_data->va_buffer, NULL); + return TRUE; +} +#endif + +static inline gboolean +op_set_deinterlace(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, + GstVaapiDeinterlaceMethod method, guint flags) +{ + gboolean success = FALSE; + +#if USE_VA_VPP + GST_VAAPI_DISPLAY_LOCK(filter->display); + success = op_set_deinterlace_unlocked(filter, op_data, method, flags); + GST_VAAPI_DISPLAY_UNLOCK(filter->display); +#endif + return success; +} + /* ------------------------------------------------------------------------- */ /* --- Surface Formats --- */ /* ------------------------------------------------------------------------- */ @@ -1004,6 +1136,11 @@ gst_vaapi_filter_set_operation(GstVaapiFilter *filter, GstVaapiFilterOp op, return op_set_color_balance(filter, op_data, (value ? g_value_get_float(value) : G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value)); + case GST_VAAPI_FILTER_OP_DEINTERLACING: + return op_set_deinterlace(filter, op_data, + (value ? g_value_get_enum(value) : + G_PARAM_SPEC_ENUM(op_data->pspec)->default_value), 0); + break; default: break; } @@ -1322,3 +1459,26 @@ gst_vaapi_filter_set_contrast(GstVaapiFilter *filter, gfloat value) return op_set_color_balance(filter, find_operation(filter, GST_VAAPI_FILTER_OP_CONTRAST), value); } + +/** + * gst_vaapi_filter_set_deinterlacing: + * @filter: a #GstVaapiFilter + * @method: the deinterlacing algorithm (see #GstVaapiDeinterlaceMethod) + * @flags: the additional flags + * + * Applies deinterlacing to the video processing pipeline. If @method + * is not @GST_VAAPI_DEINTERLACE_METHOD_NONE, then @flags could + * represent the initial picture structure of the source frame. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_deinterlacing(GstVaapiFilter *filter, + GstVaapiDeinterlaceMethod method, guint flags) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + return op_set_deinterlace(filter, + find_operation(filter, GST_VAAPI_FILTER_OP_DEINTERLACING), method, + flags); +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h old mode 100644 new mode 100755 index 8da28d47be..bd770771e6 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -51,6 +51,7 @@ typedef enum { GST_VAAPI_FILTER_OP_SATURATION, GST_VAAPI_FILTER_OP_BRIGHTNESS, GST_VAAPI_FILTER_OP_CONTRAST, + GST_VAAPI_FILTER_OP_DEINTERLACING, } GstVaapiFilterOp; /** @@ -85,6 +86,53 @@ typedef enum { GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_FORMAT, } GstVaapiFilterStatus; +/** + * 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. + * @GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD: The input frame represents a + * single field. If this flag is not set, then the whole frame holds + * two fields. + * + * 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, +} GstVaapiDeinterlaceFlags; + +#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_vaapi_deinterlace_method_get_type(void) G_GNUC_CONST; + +GType +gst_vaapi_deinterlace_flags_get_type(void) G_GNUC_CONST; + GstVaapiFilter * gst_vaapi_filter_new(GstVaapiDisplay *display); @@ -137,4 +185,8 @@ 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); + #endif /* GST_VAAPI_FILTER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index aec68ff6d6..a0b0d0a712 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -25,9 +25,14 @@ #include "gstvaapiutils.h" #include "gstvaapisurface.h" #include "gstvaapisubpicture.h" +#include "gstvaapifilter.h" #include #include +#if USE_VA_VPP +# include +#endif + #define DEBUG 1 #include "gstvaapidebug.h" @@ -433,3 +438,44 @@ to_GstVaapiRotation(guint value) GST_ERROR("unsupported VA-API rotation value %d", value); return GST_VAAPI_ROTATION_0; } + +/* VPP: translate GstVaapiDeinterlaceMethod to VA deinterlacing algorithm */ +guint +from_GstVaapiDeinterlaceMethod(guint value) +{ + switch (value) { + case GST_VAAPI_DEINTERLACE_METHOD_NONE: + return 0; +#if USE_VA_VPP + case GST_VAAPI_DEINTERLACE_METHOD_BOB: + return VAProcDeinterlacingBob; + case GST_VAAPI_DEINTERLACE_METHOD_WEAVE: + return VAProcDeinterlacingWeave; + case GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE: + return VAProcDeinterlacingMotionAdaptive; + case GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED: + return VAProcDeinterlacingMotionCompensated; +#endif + } + GST_ERROR("unsupported GstVaapiDeinterlaceMethod value %d", value); + return 0; +} + +/* VPP: translate GstVaapiDeinterlaceFlags into VA deinterlacing flags */ +guint +from_GstVaapiDeinterlaceFlags(guint flags) +{ + guint va_flags = 0; + +#if USE_VA_VPP + if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF)) + va_flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST; + + if (flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD) { + va_flags |= VA_DEINTERLACING_ONE_FIELD; + if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF)) + va_flags |= VA_DEINTERLACING_BOTTOM_FIELD; + } +#endif + return va_flags; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index a0a84b4f37..0ab132bfc2 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -109,4 +109,12 @@ G_GNUC_INTERNAL guint to_GstVaapiRotation(guint value); +G_GNUC_INTERNAL +guint +from_GstVaapiDeinterlaceMethod(guint value); + +G_GNUC_INTERNAL +guint +from_GstVaapiDeinterlaceFlags(guint flags); + #endif /* GST_VAAPI_UTILS_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c old mode 100644 new mode 100755 index 944e11f87f..2504fb6b10 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -149,36 +149,6 @@ gst_vaapi_deinterlace_mode_get_type(void) return deinterlace_mode_type; } -#define GST_VAAPI_TYPE_DEINTERLACE_METHOD \ - gst_vaapi_deinterlace_method_get_type() - -static GType -gst_vaapi_deinterlace_method_get_type(void) -{ - static GType deinterlace_method_type = 0; - - static const GEnumValue method_types[] = { - { GST_VAAPI_DEINTERLACE_METHOD_BOB, - "Bob deinterlacing", "bob" }, -#if 0 - /* VA/VPP */ - { GST_VAAPI_DEINTERLACE_METHOD_WEAVE, - "Weave deinterlacing", "weave" }, - { GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE, - "Motion adaptive deinterlacing", "motion-adaptive" }, - { GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED, - "Motion compensated deinterlacing", "motion-compensated" }, -#endif - { 0, NULL, NULL }, - }; - - if (!deinterlace_method_type) { - deinterlace_method_type = - g_enum_register_static("GstVaapiDeinterlaceMethod", method_types); - } - return deinterlace_method_type; -} - static inline GstVaapiPostproc * get_vaapipostproc_from_pad(GstPad *pad) { diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h old mode 100644 new mode 100755 index e983a312f6..b33e724e32 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -26,6 +26,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -68,20 +69,6 @@ typedef enum { GST_VAAPI_DEINTERLACE_MODE_DISABLED, } GstVaapiDeinterlaceMode; -/** - * GstVaapiDeinterlaceMethod: - * @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. - */ -typedef enum { - GST_VAAPI_DEINTERLACE_METHOD_BOB = 1, - GST_VAAPI_DEINTERLACE_METHOD_WEAVE, - GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE, - GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED, -} GstVaapiDeinterlaceMethod; - struct _GstVaapiPostproc { /*< private >*/ GstElement parent_instance; From d7cc1374ed103217bc5a5661167a8c5302e021ea Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Mon, 8 Jul 2013 16:54:55 +0800 Subject: [PATCH 1305/3781] tests: add initial test for video processing. Add minimal test case for video processing: scaling and color format conversion. Signed-off-by: Gwenole Beauchesne --- tests/Makefile.am | 6 ++ tests/test-filter.c | 185 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100755 tests/test-filter.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 0bc4f73095..2e7f191bb4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,6 +2,7 @@ noinst_PROGRAMS = \ simple-decoder \ test-decode \ test-display \ + test-filter \ test-surfaces \ test-windows \ test-subpicture \ @@ -85,6 +86,11 @@ test_display_SOURCES = test-display.c test_display_CFLAGS = $(TEST_CFLAGS) test_display_LDADD = libutils.la $(TEST_LIBS) +test_filter_SOURCES = test-filter.c +test_filter_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) +test_filter_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) \ + $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la + test_surfaces_SOURCES = test-surfaces.c test_surfaces_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) test_surfaces_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) \ diff --git a/tests/test-filter.c b/tests/test-filter.c new file mode 100755 index 0000000000..c04e12e78a --- /dev/null +++ b/tests/test-filter.c @@ -0,0 +1,185 @@ +/* + * test-filter.c - Test GstVaapiFilter + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2012-2013 Intel Corporation + * + * 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 "gst/vaapi/sysdeps.h" +#include +#include +#include "image.h" +#include "output.h" + +static gchar *g_src_format_str; + +static GOptionEntry g_options[] = { + { "src-format", 's', + 0, + G_OPTION_ARG_STRING, &g_src_format_str, + "source surface format", NULL }, + { NULL, } +}; + +#define APP_ERROR app_error_quark() +static GQuark +app_error_quark(void) +{ + static gsize g_quark; + + if (g_once_init_enter(&g_quark)) { + gsize quark = (gsize)g_quark_from_static_string("AppError"); + g_once_init_leave(&g_quark, quark); + } + return g_quark; +} + +typedef enum { + APP_ERROR_NONE, + APP_ERROR_CREATE_TEST_SURFACE, +} AppError; + +static inline void +pause(void) +{ + g_print("Press any key to continue...\n"); + getchar(); +} + +static GstVaapiSurface * +create_test_surface(GstVaapiDisplay *display, guint width, guint height, + GError **error_ptr) +{ + GstVideoFormat format = GST_VIDEO_FORMAT_I420; + GstVaapiSurface *surface = NULL; + GstVaapiImage *image = NULL; + GError *error = NULL; + + if (g_src_format_str) { + format = gst_vaapi_video_format_from_string(g_src_format_str); + if (format == GST_VIDEO_FORMAT_UNKNOWN) + goto error_invalid_format; + } + + surface = gst_vaapi_surface_new_with_format(display, format, width, height); + if (!surface) + goto error_create_surface; + + image = image_generate(display, format, width, height); + if (!image) + goto error_create_image; + + if (!image_upload(image, surface)) + goto error_upload_image; + + gst_vaapi_object_unref(image); + return surface; + + /* ERRORS */ +error_invalid_format: + error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, + "unknown format %s", g_src_format_str); + goto error_cleanup; +error_create_surface: + error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, + "unsupported format %s", gst_vaapi_video_format_to_string(format)); + goto error_cleanup; +error_create_image: + error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, + "unsupported %s image", gst_vaapi_video_format_to_string(format)); + goto error_cleanup; +error_upload_image: + error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, + "failed to upload %s image", gst_vaapi_video_format_to_string(format)); + goto error_cleanup; +error_cleanup: + if (image) + gst_vaapi_object_unref(image); + if (surface) + gst_vaapi_object_unref(surface); + if (error_ptr) + *error_ptr = error; + else + g_error_free(error); + return NULL; +} + +int +main(int argc, char *argv[]) +{ + GstVaapiDisplay *display; + GstVaapiWindow *window; + GstVaapiSurface *src_surface, *dst_surface; + GstVaapiFilter *filter = NULL; + GstVaapiFilterStatus status; + guint filter_flags = 0; + GError *error = NULL; + + static const guint src_width = 320; + static const guint src_height = 240; + static const guint dst_width = 480; + static const guint dst_height = 360; + static const guint win_width = 640; + static const guint win_height = 480; + + if (!video_output_init(&argc, argv, g_options)) + g_error("failed to initialize video output subsystem"); + + display = video_output_create_display(NULL); + if (!display) + g_error("failed to create VA display"); + + window = video_output_create_window(display, win_width, win_height); + if (!window) + g_error("failed to create window"); + + src_surface = create_test_surface(display, src_width, src_height, &error); + if (!src_surface) + g_error("failed to create source VA surface: %s", error->message); + + dst_surface = gst_vaapi_surface_new(display, GST_VAAPI_CHROMA_TYPE_YUV420, + dst_width, dst_height); + if (!dst_surface) + g_error("failed to create target VA surface"); + + filter = gst_vaapi_filter_new(display); + if (!filter) + g_error("failed to create video processing pipeline"); + + status = gst_vaapi_filter_process(filter, src_surface, dst_surface, + filter_flags); + if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) + g_error("failed to process video filters"); + + gst_vaapi_window_show(window); + + if (!gst_vaapi_window_put_surface(window, dst_surface, NULL, NULL, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + g_error("failed to render target surface"); + + pause(); + + gst_vaapi_filter_unref(filter); + gst_vaapi_object_unref(dst_surface); + gst_vaapi_object_unref(src_surface); + gst_vaapi_window_unref(window); + gst_vaapi_display_unref(display); + video_output_exit(); + g_free(g_src_format_str); + return 0; +} From 290cc8b7c975b0696593ac5c2e12c6ce2ac8a25e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 23 Jul 2013 18:00:26 +0200 Subject: [PATCH 1306/3781] tests: filter: dump supported operations and formats. --- tests/test-filter.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/test-filter.c b/tests/test-filter.c index c04e12e78a..c12505aba0 100755 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -119,6 +119,57 @@ error_cleanup: return NULL; } +static void +dump_operation(GstVaapiFilterOpInfo *op_info) +{ + GParamSpec * const pspec = op_info->pspec; + GValue value = G_VALUE_INIT; + gchar *value_str; + + if (!op_info) + return; + + g_print(" %s: ", g_param_spec_get_name(pspec)); + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + g_param_value_set_default(pspec, &value); + value_str = g_strdup_value_contents(&value); + g_print("%s (default: %s)\n", G_VALUE_TYPE_NAME(&value), + value_str ? value_str : ""); + g_free(value_str); +} + +static void +dump_operations(GstVaapiFilter *filter) +{ + GPtrArray * const ops = gst_vaapi_filter_get_operations(filter); + guint i; + + if (!ops) + return; + + g_print("%u operations\n", ops->len); + for (i = 0; i < ops->len; i++) + dump_operation(g_ptr_array_index(ops, i)); + g_ptr_array_unref(ops); +} + +static void +dump_formats(GstVaapiFilter *filter) +{ + GArray * const formats = gst_vaapi_filter_get_formats(filter); + guint i; + + if (!formats) + return; + + g_print("%u formats\n", formats->len); + for (i = 0; i < formats->len; i++) { + GstVideoFormat format = g_array_index(formats, GstVideoFormat, i); + g_print(" %s\n", gst_vaapi_video_format_to_string(format)); + } + g_array_unref(formats); +} + int main(int argc, char *argv[]) { @@ -161,6 +212,9 @@ main(int argc, char *argv[]) if (!filter) g_error("failed to create video processing pipeline"); + dump_operations(filter); + dump_formats(filter); + status = gst_vaapi_filter_process(filter, src_surface, dst_surface, filter_flags); if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) From 96362e61625a75acc6474bc821c85b933317b886 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Jul 2013 14:31:34 +0200 Subject: [PATCH 1307/3781] tests: filter: add support for frame cropping. Add support for frame cropping through the --crop-rect|-c argument. The format used is either 'x' , with origin at (0,0) ; or full specification with '('? ',' ')'? 'x' . --- tests/test-filter.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/test-filter.c b/tests/test-filter.c index c12505aba0..643ffd357f 100755 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -27,12 +27,17 @@ #include "output.h" static gchar *g_src_format_str; +static gchar *g_crop_rect_str; static GOptionEntry g_options[] = { { "src-format", 's', 0, G_OPTION_ARG_STRING, &g_src_format_str, "source surface format", NULL }, + { "crop-rect", 'c', + 0, + G_OPTION_ARG_STRING, &g_crop_rect_str, + "cropping rectangle", NULL }, { NULL, } }; @@ -170,6 +175,27 @@ dump_formats(GstVaapiFilter *filter) g_array_unref(formats); } +static gboolean +parse_crop_rect(const gchar *str, GstVaapiRectangle *crop_rect) +{ + if (str) { + // Format: 'x' + if (sscanf(str, "%ux%u", &crop_rect->width, &crop_rect->height) == 2) { + crop_rect->x = 0; + crop_rect->y = 0; + return TRUE; + } + + // Format: '('? ',' ')'? 'x' + if (sscanf(str, "(%d,%d):%ux%u", &crop_rect->x, &crop_rect->y, + &crop_rect->width, &crop_rect->height) == 4 || + sscanf(str, "%d,%d:%ux%u", &crop_rect->x, &crop_rect->y, + &crop_rect->width, &crop_rect->height) == 4) + return TRUE; + } + return FALSE; +} + int main(int argc, char *argv[]) { @@ -215,6 +241,19 @@ main(int argc, char *argv[]) dump_operations(filter); dump_formats(filter); + if (g_crop_rect_str) { + GstVaapiRectangle crop_rect; + + if (!parse_crop_rect(g_crop_rect_str, &crop_rect)) + g_error("failed to parse cropping rectangle"); + + printf("Frame cropping: (%d,%d), size %ux%u\n", + crop_rect.x, crop_rect.y, crop_rect.width, crop_rect.height); + + if (!gst_vaapi_filter_set_cropping_rectangle(filter, &crop_rect)) + g_error("failed to set cropping rectangle"); + } + status = gst_vaapi_filter_process(filter, src_surface, dst_surface, filter_flags); if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) @@ -235,5 +274,6 @@ main(int argc, char *argv[]) gst_vaapi_display_unref(display); video_output_exit(); g_free(g_src_format_str); + g_free(g_crop_rect_str); return 0; } From d48a18c9f253e7d4f709a3e9b126fde9f164f08d Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Wed, 17 Jul 2013 17:29:41 +0800 Subject: [PATCH 1308/3781] tests: filter: add support for denoising and sharpening. Add --denoise option to enable noise reduction with the level specified as the option value (float). Likewise, add --sharpen option to enable sharpening. Signed-off-by: Gwenole Beauchesne --- tests/test-filter.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tests/test-filter.c b/tests/test-filter.c index 643ffd357f..9b3f6c335d 100755 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -21,6 +21,7 @@ */ #include "gst/vaapi/sysdeps.h" +#include #include #include #include "image.h" @@ -28,6 +29,8 @@ static gchar *g_src_format_str; static gchar *g_crop_rect_str; +static gchar *g_denoise_str; +static gchar *g_sharpen_str; static GOptionEntry g_options[] = { { "src-format", 's', @@ -38,6 +41,14 @@ static GOptionEntry g_options[] = { 0, G_OPTION_ARG_STRING, &g_crop_rect_str, "cropping rectangle", NULL }, + { "denoise", 0, + 0, + G_OPTION_ARG_STRING, &g_denoise_str, + "set noise reduction level", NULL }, + { "sharpen", 0, + 0, + G_OPTION_ARG_STRING, &g_sharpen_str, + "set sharpening level", NULL }, { NULL, } }; @@ -175,6 +186,23 @@ dump_formats(GstVaapiFilter *filter) g_array_unref(formats); } +static gboolean +parse_double(const gchar *str, gdouble *out_value_ptr) +{ + gchar *endptr = NULL; + gdouble out_value; + + g_return_val_if_fail(out_value_ptr != NULL, FALSE); + + errno = 0; + out_value = g_ascii_strtod(str, &endptr); + if (!endptr || *endptr != '\0' || errno == ERANGE) + return FALSE; + + *out_value_ptr = out_value; + return TRUE; +} + static gboolean parse_crop_rect(const gchar *str, GstVaapiRectangle *crop_rect) { @@ -205,6 +233,7 @@ main(int argc, char *argv[]) GstVaapiFilter *filter = NULL; GstVaapiFilterStatus status; guint filter_flags = 0; + gdouble denoise_level, sharpen_level; GError *error = NULL; static const guint src_width = 320; @@ -217,6 +246,12 @@ main(int argc, char *argv[]) if (!video_output_init(&argc, argv, g_options)) g_error("failed to initialize video output subsystem"); + if (g_denoise_str && !parse_double(g_denoise_str, &denoise_level)) + g_error("failed to parse noise reduction level"); + + if (g_sharpen_str && !parse_double(g_sharpen_str, &sharpen_level)) + g_error("failed to parse sharpening level"); + display = video_output_create_display(NULL); if (!display) g_error("failed to create VA display"); @@ -254,6 +289,20 @@ main(int argc, char *argv[]) g_error("failed to set cropping rectangle"); } + if (g_denoise_str) { + printf("Noise reduction level: %f\n", denoise_level); + + if (!gst_vaapi_filter_set_denoising_level(filter, denoise_level)) + g_error("failed to set denoising level"); + } + + if (g_sharpen_str) { + printf("Sharpening level: %f\n", sharpen_level); + + if (!gst_vaapi_filter_set_sharpening_level(filter, sharpen_level)) + g_error("failed to set sharpening level"); + } + status = gst_vaapi_filter_process(filter, src_surface, dst_surface, filter_flags); if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) @@ -275,5 +324,7 @@ main(int argc, char *argv[]) video_output_exit(); g_free(g_src_format_str); g_free(g_crop_rect_str); + g_free(g_denoise_str); + g_free(g_sharpen_str); return 0; } From ed9cc7c8d2b7a4fa987d4d8881a929b20569ca9d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 30 Jul 2013 15:59:40 +0200 Subject: [PATCH 1309/3781] tests: filter: add support for deinterlacing. Add --deinterlace option to enable deinterlacing through explicit VA/VPP deinterlacing filter. However, if --deinterlace option is not set but the --deinterlace-flags option is set with "top-field-first", then the very basic bob deinterlacing filter is set through VA/VPP proc pipeline flags. --- tests/test-filter.c | 138 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 127 insertions(+), 11 deletions(-) diff --git a/tests/test-filter.c b/tests/test-filter.c index 9b3f6c335d..a96c0335e8 100755 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -31,6 +31,8 @@ static gchar *g_src_format_str; static gchar *g_crop_rect_str; static gchar *g_denoise_str; static gchar *g_sharpen_str; +static gchar *g_deinterlace_str; +static gchar *g_deinterlace_flags_str; static GOptionEntry g_options[] = { { "src-format", 's', @@ -49,6 +51,14 @@ static GOptionEntry g_options[] = { 0, G_OPTION_ARG_STRING, &g_sharpen_str, "set sharpening level", NULL }, + { "deinterlace", 0, + 0, + G_OPTION_ARG_STRING, &g_deinterlace_str, + "enable deinterlacing", NULL }, + { "deinterlace-flags", 0, + 0, + G_OPTION_ARG_STRING, &g_deinterlace_flags_str, + "deinterlacing flags", NULL }, { NULL, } }; @@ -79,7 +89,7 @@ pause(void) static GstVaapiSurface * create_test_surface(GstVaapiDisplay *display, guint width, guint height, - GError **error_ptr) + guint flags, GError **error_ptr) { GstVideoFormat format = GST_VIDEO_FORMAT_I420; GstVaapiSurface *surface = NULL; @@ -96,7 +106,7 @@ create_test_surface(GstVaapiDisplay *display, guint width, guint height, if (!surface) goto error_create_surface; - image = image_generate(display, format, width, height); + image = image_generate_full(display, format, width, height, flags); if (!image) goto error_create_image; @@ -224,6 +234,74 @@ parse_crop_rect(const gchar *str, GstVaapiRectangle *crop_rect) return FALSE; } +static gboolean +parse_enum(const gchar *str, GType type, gint default_value, + gint *out_value_ptr) +{ + gint out_value = default_value; + + g_return_val_if_fail(out_value_ptr != NULL, FALSE); + + if (str) { + GEnumClass * const enum_class = g_type_class_ref(type); + if (!enum_class) + return FALSE; + + const GEnumValue * const enum_value = + g_enum_get_value_by_nick(enum_class, str); + if (enum_value) + out_value = enum_value->value; + g_type_class_unref(enum_class); + + if (!enum_value) + return FALSE; + } + *out_value_ptr = out_value; + return TRUE; +} + +static gboolean +parse_flags(const gchar *str, GType type, guint *out_value_ptr) +{ + gchar **tokens = NULL; + gint i, value, out_value = 0; + gboolean success = FALSE; + + g_return_val_if_fail(out_value_ptr != NULL, FALSE); + + if (str) { + tokens = g_strsplit(str, ",", 32); + if (!tokens) + return FALSE; + + for (i = 0; tokens[i] != NULL; i++) { + if (!parse_enum(tokens[i], type, 0, &value)) + goto end; + out_value |= value; + } + } + *out_value_ptr = out_value; + success = TRUE; + +end: + g_strfreev(tokens); + return success; +} + +static inline gboolean +parse_deinterlace(const gchar *str, GstVaapiDeinterlaceMethod *deinterlace_ptr) +{ + return parse_enum(str, GST_VAAPI_TYPE_DEINTERLACE_METHOD, + GST_VAAPI_DEINTERLACE_METHOD_NONE, (gint *)deinterlace_ptr); +} + +static inline gboolean +parse_deinterlace_flags(const gchar *str, guint *deinterlace_flags_ptr) +{ + return parse_flags(str, GST_VAAPI_TYPE_DEINTERLACE_FLAGS, + deinterlace_flags_ptr); +} + int main(int argc, char *argv[]) { @@ -232,7 +310,10 @@ main(int argc, char *argv[]) GstVaapiSurface *src_surface, *dst_surface; GstVaapiFilter *filter = NULL; GstVaapiFilterStatus status; + GstVaapiDeinterlaceMethod deinterlace_method; + guint deinterlace_flags = 0; guint filter_flags = 0; + guint surface_flags = 0; gdouble denoise_level, sharpen_level; GError *error = NULL; @@ -252,6 +333,13 @@ main(int argc, char *argv[]) if (g_sharpen_str && !parse_double(g_sharpen_str, &sharpen_level)) g_error("failed to parse sharpening level"); + if (!parse_deinterlace(g_deinterlace_str, &deinterlace_method)) + g_error("failed to parse deinterlace method `%s'", g_deinterlace_str); + + if (!parse_deinterlace_flags(g_deinterlace_flags_str, &deinterlace_flags)) + g_error("failed to parse deinterlace flags `%s'", + g_deinterlace_flags_str); + display = video_output_create_display(NULL); if (!display) g_error("failed to create VA display"); @@ -260,15 +348,6 @@ main(int argc, char *argv[]) if (!window) g_error("failed to create window"); - src_surface = create_test_surface(display, src_width, src_height, &error); - if (!src_surface) - g_error("failed to create source VA surface: %s", error->message); - - dst_surface = gst_vaapi_surface_new(display, GST_VAAPI_CHROMA_TYPE_YUV420, - dst_width, dst_height); - if (!dst_surface) - g_error("failed to create target VA surface"); - filter = gst_vaapi_filter_new(display); if (!filter) g_error("failed to create video processing pipeline"); @@ -303,6 +382,41 @@ main(int argc, char *argv[]) g_error("failed to set sharpening level"); } + if (deinterlace_method != GST_VAAPI_DEINTERLACE_METHOD_NONE) { + printf("Enable deinterlacing: %s\n", g_deinterlace_str); + + if (!gst_vaapi_filter_set_deinterlacing(filter, deinterlace_method, + deinterlace_flags)) + g_error("failed to set deinterlacing method"); + } + else if (deinterlace_flags) { + if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TFF) + filter_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + else + filter_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + } + + if (deinterlace_method != GST_VAAPI_DEINTERLACE_METHOD_NONE || + deinterlace_flags) { + if (!(deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD)) + surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD | + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + else if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TFF) + surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + else + surface_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + } + + src_surface = create_test_surface(display, src_width, src_height, + surface_flags, &error); + if (!src_surface) + g_error("failed to create source VA surface: %s", error->message); + + dst_surface = gst_vaapi_surface_new(display, GST_VAAPI_CHROMA_TYPE_YUV420, + dst_width, dst_height); + if (!dst_surface) + g_error("failed to create target VA surface"); + status = gst_vaapi_filter_process(filter, src_surface, dst_surface, filter_flags); if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) @@ -326,5 +440,7 @@ main(int argc, char *argv[]) g_free(g_crop_rect_str); g_free(g_denoise_str); g_free(g_sharpen_str); + g_free(g_deinterlace_str); + g_free(g_deinterlace_flags_str); return 0; } From d16db5896853345d65a3db8120de4663006079a3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 26 Aug 2013 11:31:06 +0200 Subject: [PATCH 1310/3781] mpeg4: fix double definition of GstVaapiDecoderMpeg4Class. This fixes the following issue: CC libgstvaapi_0.10_la-gstvaapidecoder_mpeg4.lo gstvaapidecoder_mpeg4.c:113: error: redefinition of typedef 'GstVaapiDecoderMpeg4Class' gstvaapidecoder_mpeg4.c:44: note: previous declaration of 'GstVaapiDecoderMpeg4Class' was here make[5]: *** [libgstvaapi_0.10_la-gstvaapidecoder_mpeg4.lo] Error 1 make[5]: Leaving directory `/builddir/build/BUILD/gstreamer-vaapi-0.5.5.1/gst-libs/gst/vaapi' https://bugzilla.gnome.org/show_bug.cgi?id=705148 --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 79b15bed4c..71fdef6a0b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -110,7 +110,6 @@ struct _GstVaapiDecoderMpeg4 { * * A decoder class based on Mpeg4. */ -typedef struct _GstVaapiDecoderMpeg4Class GstVaapiDecoderMpeg4Class; struct _GstVaapiDecoderMpeg4Class { /*< private >*/ GstVaapiDecoderClass parent_class; From 92a124f3065a4f05daf06c100d699b72757983bd Mon Sep 17 00:00:00 2001 From: "Guangxin.Xu" Date: Wed, 31 Jul 2013 16:49:20 +0800 Subject: [PATCH 1311/3781] vaapisink: fix get_caps() implementation for GStreamer 1.0. Fix GstBaseSink::get_caps() implementation for GStreamer 1.0.X builds by honouring the filter caps argument. More precisely, this fixes the following pipeline: gst-launch-1.0 videotestsrc ! vaapisink https://bugzilla.gnome.org/show_bug.cgi?id=705192 Signed-off-by: Guangxin.Xu Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index b0061cb386..d5a436d0d4 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -720,7 +720,17 @@ gst_vaapisink_get_caps_impl(GstBaseSink *base_sink) static inline GstCaps * gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter) { - return gst_vaapisink_get_caps_impl(base_sink); + GstCaps *caps, *out_caps; + + caps = gst_vaapisink_get_caps_impl(base_sink); + if (caps && filter) { + out_caps = gst_caps_intersect_full(caps, filter, + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref(caps); + } + else + out_caps = caps; + return out_caps; } #else #define gst_vaapisink_get_caps gst_vaapisink_get_caps_impl From e5a50af2ae9c8d82c749854460f87f18e3a64640 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 14 May 2013 15:19:04 +0800 Subject: [PATCH 1312/3781] vaapisink: fix memory leak of GstVaapiUploader instance. Make sure gst_vaapisink_ensure_uploader() checks for the existence of a former GstVaapiUploader instance prior to forcibly creating a new one. https://bugzilla.gnome.org/show_bug.cgi?id=703980 --- gst/vaapi/gstvaapisink.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index d5a436d0d4..8a828be91c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -673,13 +673,7 @@ gst_vaapisink_start(GstBaseSink *base_sink) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - if (!gst_vaapisink_ensure_display(sink)) - return FALSE; - - sink->uploader = gst_vaapi_uploader_new(sink->display); - if (!sink->uploader) - return FALSE; - return TRUE; + return gst_vaapisink_ensure_uploader(sink); } static gboolean From 0ef5979d77f10fba8d8a73037f85c8732d409ced Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Fri, 16 Aug 2013 16:58:58 +0100 Subject: [PATCH 1313/3781] vaapisink: allow scaling to ignore aspect ratio. Other GStreamer sinks, like xvimagesink, have a force-aspect-ratio property, which allows you to say that you don't want the sink to respect aspect ratio. Add the same property to vaapisink. http://lists.freedesktop.org/archives/libva/2012-September/001298.html Signed-off-by: Simon Farnsworth --- gst/vaapi/gstvaapisink.c | 36 ++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapisink.h | 1 + 2 files changed, 37 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 8a828be91c..092169ab2f 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -158,6 +158,7 @@ enum { PROP_USE_GLX, PROP_USE_REFLECTION, PROP_ROTATION, + PROP_FORCE_ASPECT_RATIO, }; #define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY @@ -381,6 +382,19 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) if (!sink->caps) return TRUE; + if (!sink->keep_aspect) { + display_rect->width = width; + display_rect->height = height; + display_rect->x = 0; + display_rect->y = 0; + + GST_DEBUG("force-aspect-ratio is false; distorting while scaling video"); + GST_DEBUG("render rect (%d,%d):%ux%u", + display_rect->x, display_rect->y, + display_rect->width, display_rect->height); + return TRUE; + } + GST_DEBUG("ensure render rect within %ux%u bounds", width, height); gst_vaapi_display_get_pixel_aspect_ratio( @@ -1255,6 +1269,9 @@ gst_vaapisink_set_property( case PROP_ROTATION: sink->rotation_req = g_value_get_enum(value); break; + case PROP_FORCE_ASPECT_RATIO: + sink->keep_aspect = g_value_get_boolean(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1290,6 +1307,9 @@ gst_vaapisink_get_property( case PROP_ROTATION: g_value_set_enum(value, sink->rotation); break; + case PROP_FORCE_ASPECT_RATIO: + g_value_set_boolean(value, sink->keep_aspect); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1401,6 +1421,21 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) GST_VAAPI_TYPE_ROTATION, DEFAULT_ROTATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiSink:force-aspect-ratio: + * + * When enabled, scaling respects video aspect ratio; when disabled, the + * video is distorted to fit the window. + */ + g_object_class_install_property + (object_class, + PROP_FORCE_ASPECT_RATIO, + g_param_spec_boolean("force-aspect-ratio", + "Force aspect ratio", + "When enabled, scaling will respect original aspect ratio", + TRUE, + G_PARAM_READWRITE)); } static void @@ -1426,4 +1461,5 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->use_reflection = FALSE; sink->use_overlay = FALSE; sink->use_rotation = FALSE; + sink->keep_aspect = TRUE; } diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index b73065e34f..c60258a618 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -95,6 +95,7 @@ struct _GstVaapiSink { guint use_reflection : 1; guint use_overlay : 1; guint use_rotation : 1; + guint keep_aspect : 1; guint use_video_raw : 1; }; From 292b2f51b4233b75f6f94e0d55d78dc593b261b1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 26 Aug 2013 16:15:49 +0200 Subject: [PATCH 1314/3781] mpeg2: disable video cropping as picture_display_extension() is missing. Disable video cropping in MPEG-2 codec because it is partially implemented and actually because nobody implements it that way, and the standard spec does not specify the display process either anyway. Most notably, there are two possible use cases for sequence_display_extension() horizontal_display_size & vertical_display_size: (i) guesstimating the pixel-aspect-ratio, or (ii) implement some kind of span & scan process in conjunction with picture_display_extension() information. https://bugzilla.gnome.org/show_bug.cgi?id=704848 --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 35 ++++++++++++++++------ 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 7cf78219c4..711755f328 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -242,6 +242,7 @@ struct _GstVaapiDecoderMpeg2Private { guint fps_n; guint fps_d; guint state; + GstVaapiRectangle crop_rect; GstVaapiParserInfoMpeg2 *seq_hdr; GstVaapiParserInfoMpeg2 *seq_ext; GstVaapiParserInfoMpeg2 *seq_display_ext; @@ -249,6 +250,7 @@ struct _GstVaapiDecoderMpeg2Private { GstVaapiParserInfoMpeg2 *gop; GstVaapiParserInfoMpeg2 *pic_hdr; GstVaapiParserInfoMpeg2 *pic_ext; + GstVaapiParserInfoMpeg2 *pic_display_ext; GstVaapiParserInfoMpeg2 *quant_matrix; GstVaapiParserInfoMpeg2 *slice_hdr; GstVaapiPicture *current_picture; @@ -298,6 +300,7 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) gst_vaapi_parser_info_mpeg2_replace(&priv->gop, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->pic_hdr, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->pic_display_ext, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->slice_hdr, NULL); @@ -581,6 +584,7 @@ decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->seq_scalable_ext, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, NULL); + gst_vaapi_parser_info_mpeg2_replace(&priv->pic_display_ext, NULL); priv->fps_n = seq_hdr->fps_n; priv->fps_d = seq_hdr->fps_d; @@ -709,7 +713,22 @@ static GstVaapiDecoderStatus decode_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) { - /* XXX: handle color primaries and cropping */ + GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; + GstMpegVideoSequenceDisplayExt *seq_display_ext; + + seq_display_ext = priv->seq_display_ext ? + &priv->seq_display_ext->data.seq_display_ext : NULL; + + /* Update cropping rectangle */ + if (seq_display_ext) { + GstVaapiRectangle * const crop_rect = &priv->crop_rect; + crop_rect->x = 0; + crop_rect->y = 0; + crop_rect->width = seq_display_ext->display_horizontal_size; + crop_rect->height = seq_display_ext->display_vertical_size; + } + + /* XXX: handle color primaries */ return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1473,14 +1492,12 @@ gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder, gst_vaapi_picture_unref(picture); /* Update cropping rectangle */ - if (seq_display_ext) { - GstVaapiRectangle crop_rect; - crop_rect.x = 0; - crop_rect.y = 0; - crop_rect.width = seq_display_ext->display_horizontal_size; - crop_rect.height = seq_display_ext->display_vertical_size; - if (crop_rect.width <= priv->width && crop_rect.height <= priv->height) - gst_vaapi_picture_set_crop_rect(picture, &crop_rect); + /* XXX: handle picture_display_extension() */ + if (seq_display_ext && priv->pic_display_ext) { + GstVaapiRectangle * const crop_rect = &priv->crop_rect; + if (crop_rect->x + crop_rect->width <= priv->width && + crop_rect->y + crop_rect->height <= priv->height) + gst_vaapi_picture_set_crop_rect(picture, crop_rect); } status = ensure_quant_matrix(decoder, picture); From 771071a4e593e231d111d835ca82e07a57555251 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 26 Aug 2013 17:14:33 +0200 Subject: [PATCH 1315/3781] decode: fix creation of GLX video buffers for GStreamer 0.10. Fix creation of GstVaapiVideoBuffer objects (i) to have that type for real; and (ii) to correctly extract the GstSurfaceConverter from the video buffer object meta. This fixes support for cluttersink with GStreamer 0.10 builds. --- gst/vaapi/gstvaapivideobuffer.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 583f49ffeb..19926d30e7 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -198,8 +198,6 @@ typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass; struct _GstVaapiVideoBuffer { /*< private >*/ GstSurfaceBuffer parent_instance; - - GstVaapiVideoMeta *meta; }; /** @@ -226,11 +224,14 @@ static GstSurfaceConverter * gst_vaapi_video_buffer_create_converter(GstSurfaceBuffer *surface, const gchar *type, GValue *dest) { - GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(surface); + GstVaapiVideoMeta * const meta = + gst_buffer_get_vaapi_video_meta(GST_BUFFER(surface)); GstSurfaceConverterCreateFunc func; + g_return_val_if_fail(meta != NULL, NULL); + func = (GstSurfaceConverterCreateFunc) - gst_vaapi_video_meta_get_surface_converter(vbuffer->meta); + gst_vaapi_video_meta_get_surface_converter(meta); return func ? func(surface, type, dest) : NULL; } @@ -252,7 +253,7 @@ gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) static inline GstBuffer * gst_surface_buffer_new(void) { - return GST_BUFFER_CAST(gst_mini_object_new(GST_TYPE_SURFACE_BUFFER)); + return GST_BUFFER_CAST(gst_mini_object_new(GST_VAAPI_TYPE_VIDEO_BUFFER)); } #endif From 71e5fd536f1ce2dd33d992437609c98fbedabc69 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 27 Aug 2013 18:06:10 +0200 Subject: [PATCH 1316/3781] filter: allow specification of render target regions. Add support for rendering the source surface to a particular region within the supplied target surface. The default background color is black. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapifilter.c | 52 ++++++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapifilter.h | 4 +++ 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index b70eaaaaa9..cc00f43012 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -387,6 +387,7 @@ gst_vaapi_filter_get_formats gst_vaapi_filter_set_operation gst_vaapi_filter_set_format gst_vaapi_filter_set_cropping_rectangle +gst_vaapi_filter_set_target_rectangle gst_vaapi_filter_set_denoising_level gst_vaapi_filter_set_sharpening_level gst_vaapi_filter_set_hue diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 78ab1078ae..ef07eb4fc3 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -64,7 +64,9 @@ struct _GstVaapiFilter { GstVideoFormat format; GArray *formats; GstVaapiRectangle crop_rect; + GstVaapiRectangle target_rect; guint use_crop_rect : 1; + guint use_target_rect : 1; }; /* ------------------------------------------------------------------------- */ @@ -1178,6 +1180,7 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter, if (!ensure_operations(filter)) return GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED; + /* Build surface region (source) */ if (filter->use_crop_rect) { const GstVaapiRectangle * const crop_rect = &filter->crop_rect; @@ -1199,10 +1202,27 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter, src_rect.height = GST_VAAPI_SURFACE_HEIGHT(src_surface); } - dst_rect.x = 0; - dst_rect.y = 0; - dst_rect.width = GST_VAAPI_SURFACE_WIDTH(dst_surface); - dst_rect.height = GST_VAAPI_SURFACE_HEIGHT(dst_surface); + /* Build output region (target) */ + if (filter->use_target_rect) { + const GstVaapiRectangle * const target_rect = &filter->target_rect; + + if ((target_rect->x + target_rect->width > + GST_VAAPI_SURFACE_WIDTH(dst_surface)) || + (target_rect->y + target_rect->height > + GST_VAAPI_SURFACE_HEIGHT(dst_surface))) + goto error; + + dst_rect.x = target_rect->x; + dst_rect.y = target_rect->y; + dst_rect.width = target_rect->width; + dst_rect.height = target_rect->height; + } + else { + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = GST_VAAPI_SURFACE_WIDTH(dst_surface); + dst_rect.height = GST_VAAPI_SURFACE_HEIGHT(dst_surface); + } for (i = 0, num_filters = 0; i < filter->operations->len; i++) { GstVaapiFilterOpData * const op_data = @@ -1351,6 +1371,30 @@ gst_vaapi_filter_set_cropping_rectangle(GstVaapiFilter *filter, return TRUE; } +/** + * gst_vaapi_filter_set_target_rectangle: + * @filter: a #GstVaapiFilter + * @rect: the target render region + * + * Sets the region within the target surface where the source surface + * would be rendered. i.e. where the hardware accelerator would emit + * the outcome of video processing. If @rect is %NULL, the whole + * source surface will be used. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_target_rectangle(GstVaapiFilter *filter, + const GstVaapiRectangle *rect) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + filter->use_target_rect = rect != NULL; + if (filter->use_target_rect) + filter->target_rect = *rect; + return TRUE; +} + /** * gst_vaapi_filter_set_denoising_level: * @filter: a #GstVaapiFilter diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index bd770771e6..2ea44052b9 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -167,6 +167,10 @@ 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); From 5fdc9a0e9512134d2e44a1574f596ad34b62461a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 27 Aug 2013 16:26:22 +0200 Subject: [PATCH 1317/3781] wayland: add new frame redraw infrastructure. Update the frame redraw infrastructure with a new FrameState stucture holds all the necessary information used to display the next pending surface. While we are at it, delay the sync operation down to when it is actually needed. That way, we keep performing additional tasks meanwhile. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 91 +++++++++++++++------ 1 file changed, 67 insertions(+), 24 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index fb88a2b0bf..4621ac4f03 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -44,14 +44,53 @@ typedef struct _GstVaapiWindowWaylandPrivate GstVaapiWindowWaylandPrivate; typedef struct _GstVaapiWindowWaylandClass GstVaapiWindowWaylandClass; +typedef struct _FrameState FrameState; + +struct _FrameState { + GstVaapiWindow *window; + struct wl_buffer *buffer; + struct wl_callback *callback; +}; + +static FrameState * +frame_state_new(GstVaapiWindow *window) +{ + FrameState *frame; + + frame = g_slice_new(FrameState); + if (!frame) + return NULL; + + frame->window = window; + frame->buffer = NULL; + frame->callback = NULL; + return frame; +} + +static void +frame_state_free(FrameState *frame) +{ + if (!frame) + return; + + if (frame->buffer) { + wl_buffer_destroy(frame->buffer); + frame->buffer = NULL; + } + + if (frame->callback) { + wl_callback_destroy(frame->callback); + frame->callback = NULL; + } + g_slice_free(FrameState, frame); +} struct _GstVaapiWindowWaylandPrivate { struct wl_shell_surface *shell_surface; struct wl_surface *surface; - struct wl_buffer *buffer; struct wl_region *opaque_region; struct wl_event_queue *event_queue; - guint redraw_pending : 1; + FrameState *frame; guint is_shown : 1; guint fullscreen_on_show : 1; }; @@ -100,14 +139,14 @@ gst_vaapi_window_wayland_sync(GstVaapiWindow *window) GstVaapiWindowWaylandPrivate * const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); - if (priv->redraw_pending) { + if (priv->frame) { struct wl_display * const wl_display = GST_VAAPI_OBJECT_WL_DISPLAY(window); do { if (wl_display_dispatch_queue(wl_display, priv->event_queue) < 0) return FALSE; - } while (priv->redraw_pending); + } while (priv->frame); } return TRUE; } @@ -207,7 +246,6 @@ gst_vaapi_window_wayland_create( if (priv->fullscreen_on_show) gst_vaapi_window_wayland_set_fullscreen(window, TRUE); - priv->redraw_pending = FALSE; priv->is_shown = TRUE; return TRUE; @@ -219,6 +257,11 @@ gst_vaapi_window_wayland_destroy(GstVaapiWindow * window) GstVaapiWindowWaylandPrivate * const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); + if (priv->frame) { + frame_state_free(priv->frame); + priv->frame = NULL; + } + if (priv->shell_surface) { wl_shell_surface_destroy(priv->shell_surface); priv->shell_surface = NULL; @@ -229,11 +272,6 @@ gst_vaapi_window_wayland_destroy(GstVaapiWindow * window) priv->surface = NULL; } - if (priv->buffer) { - wl_buffer_destroy(priv->buffer); - priv->buffer = NULL; - } - if (priv->event_queue) { wl_event_queue_destroy(priv->event_queue); priv->event_queue = NULL; @@ -267,12 +305,13 @@ gst_vaapi_window_wayland_resize( static void frame_redraw_callback(void *data, struct wl_callback *callback, uint32_t time) { - GstVaapiWindowWaylandPrivate * const priv = data; + FrameState * const frame = data; + GstVaapiWindowWaylandPrivate * const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(frame->window); - wl_buffer_destroy(priv->buffer); - priv->buffer = NULL; - wl_callback_destroy(callback); - priv->redraw_pending = FALSE; + frame_state_free(frame); + if (priv->frame == frame) + priv->frame = NULL; } static const struct wl_callback_listener frame_callback_listener = { @@ -293,7 +332,7 @@ gst_vaapi_window_wayland_render( GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(window); struct wl_display * const wl_display = GST_VAAPI_OBJECT_WL_DISPLAY(window); struct wl_buffer *buffer; - struct wl_callback *callback; + FrameState *frame; guint width, height, va_flags; VASurfaceID surface_id; VAStatus status; @@ -317,10 +356,6 @@ gst_vaapi_window_wayland_render( if (surface_id == VA_INVALID_ID) return FALSE; - /* Wait for the previous frame to complete redraw */ - if (!gst_vaapi_window_wayland_sync(window)) - return FALSE; - /* XXX: use VA/VPP for other filters */ GST_VAAPI_OBJECT_LOCK_DISPLAY(window); va_flags = from_GstVaapiSurfaceRenderFlags(flags); @@ -343,6 +378,15 @@ gst_vaapi_window_wayland_render( if (!vaapi_check_status(status, "vaGetSurfaceBufferWl()")) return FALSE; + /* Wait for the previous frame to complete redraw */ + if (!gst_vaapi_window_wayland_sync(window)) + return FALSE; + + frame = frame_state_new(window); + if (!frame) + return FALSE; + priv->frame = frame; + /* XXX: attach to the specified target rectangle */ GST_VAAPI_OBJECT_LOCK_DISPLAY(window); wl_surface_attach(priv->surface, buffer, 0, 0); @@ -354,10 +398,9 @@ gst_vaapi_window_wayland_render( priv->opaque_region = NULL; } - priv->redraw_pending = TRUE; - priv->buffer = buffer; - callback = wl_surface_frame(priv->surface); - wl_callback_add_listener(callback, &frame_callback_listener, priv); + frame->buffer = buffer; + frame->callback = wl_surface_frame(priv->surface); + wl_callback_add_listener(frame->callback, &frame_callback_listener, frame); wl_surface_commit(priv->surface); wl_display_flush(wl_display); From 7759acd2f009d21645bc5ecda1ce7eb11ca44ee8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 27 Aug 2013 18:20:08 +0200 Subject: [PATCH 1318/3781] wayland: add supporting for video processing. Try to use VA/VPP processing capabilities to handle video cropping and additional rendering flags that may not be directly supported by the underlying hardware when exposing a suitable Wayland buffer for the supplied VA surface. e.g. deinterlacing, different color primaries than BT.601, etc. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 173 ++++++++++++++++---- 1 file changed, 141 insertions(+), 32 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 4621ac4f03..98ee3552ae 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -32,6 +32,8 @@ #include "gstvaapidisplay_wayland.h" #include "gstvaapidisplay_wayland_priv.h" #include "gstvaapiutils.h" +#include "gstvaapifilter.h" +#include "gstvaapisurfacepool.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -48,6 +50,8 @@ typedef struct _FrameState FrameState; struct _FrameState { GstVaapiWindow *window; + GstVaapiSurface *surface; + GstVaapiVideoPool *surface_pool; struct wl_buffer *buffer; struct wl_callback *callback; }; @@ -62,6 +66,8 @@ frame_state_new(GstVaapiWindow *window) return NULL; frame->window = window; + frame->surface = NULL; + frame->surface_pool = NULL; frame->buffer = NULL; frame->callback = NULL; return frame; @@ -73,6 +79,14 @@ frame_state_free(FrameState *frame) if (!frame) return; + if (frame->surface) { + if (frame->surface_pool) + gst_vaapi_video_pool_put_object(frame->surface_pool, + frame->surface); + frame->surface = NULL; + } + gst_vaapi_video_pool_replace(&frame->surface_pool, NULL); + if (frame->buffer) { wl_buffer_destroy(frame->buffer); frame->buffer = NULL; @@ -91,8 +105,12 @@ struct _GstVaapiWindowWaylandPrivate { struct wl_region *opaque_region; struct wl_event_queue *event_queue; FrameState *frame; + GstVideoFormat surface_format; + GstVaapiVideoPool *surface_pool; + GstVaapiFilter *filter; guint is_shown : 1; guint fullscreen_on_show : 1; + guint use_vpp : 1; }; /** @@ -246,6 +264,8 @@ gst_vaapi_window_wayland_create( if (priv->fullscreen_on_show) gst_vaapi_window_wayland_set_fullscreen(window, TRUE); + priv->surface_format = GST_VIDEO_FORMAT_ENCODED; + priv->use_vpp = GST_VAAPI_DISPLAY_HAS_VPP(GST_VAAPI_OBJECT_DISPLAY(window)); priv->is_shown = TRUE; return TRUE; @@ -276,6 +296,9 @@ gst_vaapi_window_wayland_destroy(GstVaapiWindow * window) wl_event_queue_destroy(priv->event_queue); priv->event_queue = NULL; } + + gst_vaapi_filter_replace(&priv->filter, NULL); + gst_vaapi_video_pool_replace(&priv->surface_pool, NULL); } static gboolean @@ -318,6 +341,74 @@ static const struct wl_callback_listener frame_callback_listener = { frame_redraw_callback }; +static GstVaapiSurface * +vpp_convert( + GstVaapiWindow *window, + GstVaapiSurface *surface, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect, + guint flags +) +{ + GstVaapiWindowWaylandPrivate * const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); + GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(window); + GstVaapiSurface *vpp_surface = NULL; + GstVaapiFilterStatus status; + GstVideoInfo vi; + + /* Ensure VA surface pool is created */ + /* XXX: optimize the surface format to use. e.g. YUY2 */ + if (!priv->surface_pool) { + gst_video_info_set_format(&vi, priv->surface_format, + window->width, window->height); + priv->surface_pool = gst_vaapi_surface_pool_new(display, &vi); + if (!priv->surface_pool) + return NULL; + gst_vaapi_filter_replace(&priv->filter, NULL); + } + + /* Ensure VPP pipeline is built */ + if (!priv->filter) { + priv->filter = gst_vaapi_filter_new(display); + if (!priv->filter) + goto error_create_filter; + if (!gst_vaapi_filter_set_format(priv->filter, priv->surface_format)) + goto error_unsupported_format; + } + if (!gst_vaapi_filter_set_cropping_rectangle(priv->filter, src_rect)) + return NULL; + if (!gst_vaapi_filter_set_target_rectangle(priv->filter, dst_rect)) + return NULL; + + /* Post-process the decoded source surface */ + vpp_surface = gst_vaapi_video_pool_get_object(priv->surface_pool); + if (!vpp_surface) + return NULL; + + status = gst_vaapi_filter_process(priv->filter, surface, vpp_surface, + flags); + if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) + goto error_process_filter; + return vpp_surface; + + /* ERRORS */ +error_create_filter: + GST_WARNING("failed to create VPP filter. Disabling"); + priv->use_vpp = FALSE; + return NULL; +error_unsupported_format: + GST_ERROR("unsupported render target format %s", + gst_vaapi_video_format_to_string(priv->surface_format)); + priv->use_vpp = FALSE; + return NULL; +error_process_filter: + GST_ERROR("failed to process surface %" GST_VAAPI_ID_FORMAT " (error %d)", + GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface)), status); + gst_vaapi_video_pool_put_object(priv->surface_pool, vpp_surface); + return NULL; +} + static gboolean gst_vaapi_window_wayland_render( GstVaapiWindow *window, @@ -334,49 +425,62 @@ gst_vaapi_window_wayland_render( struct wl_buffer *buffer; FrameState *frame; guint width, height, va_flags; - VASurfaceID surface_id; VAStatus status; + gboolean need_vpp = FALSE; - /* XXX: use VPP to support unusual source and destination rectangles */ + /* Check that we don't need to crop source VA surface */ gst_vaapi_surface_get_size(surface, &width, &height); - if (src_rect->x != 0 || - src_rect->y != 0 || - src_rect->width != width || - src_rect->height != height) { - GST_ERROR("unsupported source rectangle for rendering"); - return FALSE; - } + if (src_rect->x != 0 || src_rect->y != 0) + need_vpp = TRUE; + if (src_rect->width != width || src_rect->height != height) + need_vpp = TRUE; - if (0 && (dst_rect->width != width || dst_rect->height != height)) { - GST_ERROR("unsupported target rectangle for rendering"); - return FALSE; - } + /* Check that we don't render to a subregion of this window */ + if (dst_rect->x != 0 || dst_rect->y != 0) + need_vpp = TRUE; + if (dst_rect->width != window->width || dst_rect->height != window->height) + need_vpp = TRUE; - surface_id = GST_VAAPI_OBJECT_ID(surface); - if (surface_id == VA_INVALID_ID) - return FALSE; - - /* XXX: use VA/VPP for other filters */ - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - va_flags = from_GstVaapiSurfaceRenderFlags(flags); - status = vaGetSurfaceBufferWl( - GST_VAAPI_DISPLAY_VADISPLAY(display), - surface_id, - va_flags & (VA_TOP_FIELD|VA_BOTTOM_FIELD), - &buffer - ); - if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED) { - /* XXX: de-interlacing flags not supported, try with VPP? */ + /* Try to construct a Wayland buffer from VA surface as is (without VPP) */ + if (!need_vpp) { + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + va_flags = from_GstVaapiSurfaceRenderFlags(flags); status = vaGetSurfaceBufferWl( GST_VAAPI_DISPLAY_VADISPLAY(display), - surface_id, + GST_VAAPI_OBJECT_ID(surface), + va_flags & (VA_TOP_FIELD|VA_BOTTOM_FIELD), + &buffer + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED) + need_vpp = TRUE; + else if (!vaapi_check_status(status, "vaGetSurfaceBufferWl()")) + return FALSE; + } + + /* Try to construct a Wayland buffer with VPP */ + if (need_vpp) { + if (priv->use_vpp) { + GstVaapiSurface * const vpp_surface = + vpp_convert(window, surface, src_rect, dst_rect, flags); + if (!vpp_surface) + return FALSE; + surface = vpp_surface; + width = window->width; + height = window->height; + } + + GST_VAAPI_OBJECT_LOCK_DISPLAY(window); + status = vaGetSurfaceBufferWl( + GST_VAAPI_DISPLAY_VADISPLAY(display), + GST_VAAPI_OBJECT_ID(surface), VA_FRAME_PICTURE, &buffer ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + if (!vaapi_check_status(status, "vaGetSurfaceBufferWl()")) + return FALSE; } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - if (!vaapi_check_status(status, "vaGetSurfaceBufferWl()")) - return FALSE; /* Wait for the previous frame to complete redraw */ if (!gst_vaapi_window_wayland_sync(window)) @@ -387,6 +491,11 @@ gst_vaapi_window_wayland_render( return FALSE; priv->frame = frame; + if (need_vpp && priv->use_vpp) { + frame->surface = surface; + frame->surface_pool = gst_vaapi_video_pool_ref(priv->surface_pool); + } + /* XXX: attach to the specified target rectangle */ GST_VAAPI_OBJECT_LOCK_DISPLAY(window); wl_surface_attach(priv->surface, buffer, 0, 0); From 1362352825015b6b7aa5306cfc10ede30296153a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 27 Aug 2013 18:24:12 +0200 Subject: [PATCH 1319/3781] wayland: render the raw surface if VPP failed. As a last resort, if video processing capabilities (VPP) are not available, or they did not produce anything conclusive enough, then try to fallback to the original rendering code path whereby the whole VA surface is rendered as is, no matter of video cropping or deinterlacing requests. Note: under those conditions, the visual outcome won't be correct but at least, something gets displayed instead of bailing out. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 98ee3552ae..bfb2f10d6e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -463,11 +463,13 @@ gst_vaapi_window_wayland_render( if (priv->use_vpp) { GstVaapiSurface * const vpp_surface = vpp_convert(window, surface, src_rect, dst_rect, flags); - if (!vpp_surface) - return FALSE; - surface = vpp_surface; - width = window->width; - height = window->height; + if (G_UNLIKELY(!vpp_surface)) + need_vpp = FALSE; + else { + surface = vpp_surface; + width = window->width; + height = window->height; + } } GST_VAAPI_OBJECT_LOCK_DISPLAY(window); From 91736b3a6032c53b05933037d6a6ddbfec3005d5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 29 Aug 2013 11:55:05 +0200 Subject: [PATCH 1320/3781] vaapidecode: push all decoded frames from within the task. Make sure to push all decoded frames from the task so that the unlying VA surfaces could all be rendered from the same thread. --- gst/vaapi/gstvaapidecode.c | 27 ++++++++++++++++++++------- gst/vaapi/gstvaapidecode.h | 2 ++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 399b004f93..29aa4eb1ba 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -410,11 +410,22 @@ gst_vaapidecode_decode_loop(GstVaapiDecode *decode) GstFlowReturn ret; ret = gst_vaapidecode_push_decoded_frame(vdec); - if (ret == GST_FLOW_OK || ret == GST_VIDEO_DECODER_FLOW_NEED_DATA) + if (ret == GST_FLOW_OK) return; - /* ERRORS */ - gst_pad_pause_task(decode->srcpad); + /* If invoked from gst_vaapidecode_finish(), then return right + away no matter the errors, or the GstVaapiDecoder needs further + data to complete decoding (there no more data to feed in) */ + if (decode->decoder_finish) { + g_mutex_lock(&decode->decoder_mutex); + g_cond_signal(&decode->decoder_finish_done); + g_mutex_unlock(&decode->decoder_mutex); + return; + } + + /* Suspend the task if an error occurred */ + if (ret != GST_VIDEO_DECODER_FLOW_NEED_DATA) + gst_pad_pause_task(decode->srcpad); } static GstFlowReturn @@ -430,12 +441,12 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) /* Make sure the decode loop function has a chance to return, thus possibly unlocking gst_video_decoder_finish_frame() */ GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); + g_mutex_lock(&decode->decoder_mutex); + decode->decoder_finish = TRUE; + g_cond_wait(&decode->decoder_finish_done, &decode->decoder_mutex); + g_mutex_unlock(&decode->decoder_mutex); gst_pad_stop_task(decode->srcpad); GST_VIDEO_DECODER_STREAM_LOCK(vdec); - - /* Submit all frames that got decoded so far */ - while (gst_vaapidecode_push_decoded_frame(vdec) == GST_FLOW_OK) - ; return GST_FLOW_OK; /* ERRORS */ @@ -621,6 +632,7 @@ gst_vaapidecode_finalize(GObject *object) gst_vaapi_display_replace(&decode->display, NULL); + g_cond_clear(&decode->decoder_finish_done); g_cond_clear(&decode->decoder_ready); g_mutex_clear(&decode->decoder_mutex); @@ -881,6 +893,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode) g_mutex_init(&decode->decoder_mutex); g_cond_init(&decode->decoder_ready); + g_cond_init(&decode->decoder_finish_done); gst_video_decoder_set_packetized(vdec, FALSE); diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 05b7769c4d..7b0dc610a4 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -72,6 +72,8 @@ struct _GstVaapiDecode { GstVaapiDecoder *decoder; GMutex decoder_mutex; GCond decoder_ready; + volatile gboolean decoder_finish; + GCond decoder_finish_done; GstCaps *decoder_caps; GstCaps *allowed_caps; gint64 render_time_base; From 111d7d4fa4b2ced74d29d70887b63f2d39cae7d3 Mon Sep 17 00:00:00 2001 From: "Guangxin.Xu" Date: Tue, 30 Jul 2013 14:05:39 +0800 Subject: [PATCH 1321/3781] vaapidecode: submit the last frame from output adapter to decoder. If there is no frame delimiter at the end of the stream, e.g. no end-of-stream or end-of-sequence marker, and that the current frame was fully parsed correctly, then assume that last frame is complete and submit it to the decoder. https://bugzilla.gnome.org/show_bug.cgi?id=705123 Signed-off-by: Guangxin.Xu Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 18 ++++++++++++++++-- gst/vaapi/gstvaapidecode.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 29aa4eb1ba..a016b71495 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -434,6 +434,11 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstVaapiDecoderStatus status; + /* If there is something in GstVideoDecoder's output adapter, then + submit the frame for decoding */ + if (decode->current_frame_size) + gst_video_decoder_have_frame(vdec); + status = gst_vaapi_decoder_flush(decode->decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto error_flush; @@ -617,6 +622,9 @@ gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) return TRUE; } + /* Reset tracked frame size */ + decode->current_frame_size = 0; + gst_vaapidecode_destroy(decode); return gst_vaapidecode_create(decode, caps); } @@ -705,10 +713,14 @@ gst_vaapidecode_parse(GstVideoDecoder *vdec, switch (status) { case GST_VAAPI_DECODER_STATUS_SUCCESS: - if (got_unit_size > 0) + if (got_unit_size > 0) { gst_video_decoder_add_to_frame(vdec, got_unit_size); - if (got_frame) + decode->current_frame_size += got_unit_size; + } + if (got_frame) { ret = gst_video_decoder_have_frame(vdec); + decode->current_frame_size = 0; + } else ret = GST_FLOW_OK; break; @@ -720,10 +732,12 @@ gst_vaapidecode_parse(GstVideoDecoder *vdec, case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: GST_WARNING("parse error %d", status); ret = GST_FLOW_NOT_SUPPORTED; + decode->current_frame_size = 0; break; default: GST_ERROR("parse error %d", status); ret = GST_FLOW_EOS; + decode->current_frame_size = 0; break; } return ret; diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 7b0dc610a4..23991cfea9 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -78,6 +78,7 @@ struct _GstVaapiDecode { GstCaps *allowed_caps; gint64 render_time_base; GstClockTime last_buffer_time; + guint current_frame_size; }; struct _GstVaapiDecodeClass { From 1be80e791c743ed9f5c0b95c5311d01d2fe1255f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 29 Aug 2013 19:33:02 +0200 Subject: [PATCH 1322/3781] vaapidecode: remove extraneous size information from allowed caps. Fix _getcaps() implementation to not report codecs with size information filled in the returned caps. That's totally useless nowadays. Ideally, this is a hint to insert a video parser element, thus allowing future optimizations, but this is not a strict requirement for gstreamer-vaapi, which is able to parse the elementary bitstreams itself. https://bugzilla.gnome.org/show_bug.cgi?id=704734 --- gst/vaapi/gstvaapidecode.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a016b71495..68cc58fee7 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -814,12 +814,6 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) if (!structure) continue; gst_structure_remove_field(structure, "profile"); - gst_structure_set( - structure, - "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, - "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, - NULL - ); decode->allowed_caps = gst_caps_merge_structure(decode->allowed_caps, structure); } From d2648afa323dd678f61a832dfa3d75b6373bf437 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 29 Aug 2013 18:34:57 +0200 Subject: [PATCH 1323/3781] vaapisink: handle raw buffers not created from VA video buffer pool. Handle raw video buffers that were not created from a VA video buffer pool. Use the generic GstVideo API to copy buffers in GStreamer 1.0.x builds instead of the GstVaapiUploader. https://bugs.freedesktop.org/show_bug.cgi?id=55818 --- gst/vaapi/gstvaapisink.c | 104 ++++++++++++++++++++++++++++++++++----- gst/vaapi/gstvaapisink.h | 1 + 2 files changed, 92 insertions(+), 13 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 092169ab2f..64e48d8cba 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -660,6 +660,8 @@ gst_vaapisink_ensure_video_buffer_pool(GstVaapiSink *sink, GstCaps *caps) 0, 0); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); + gst_buffer_pool_config_add_option(config, + GST_BUFFER_POOL_OPTION_VIDEO_META); if (!gst_buffer_pool_set_config(pool, config)) goto error_pool_config; sink->video_buffer_pool = pool; @@ -748,7 +750,7 @@ static gboolean gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstVideoInfo vi; + GstVideoInfo * const vip = &sink->video_info; guint win_width, win_height; #if USE_DRM @@ -759,13 +761,13 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) if (!gst_vaapisink_ensure_video_buffer_pool(sink, caps)) return FALSE; - if (!gst_video_info_from_caps(&vi, caps)) + if (!gst_video_info_from_caps(vip, caps)) return FALSE; - sink->use_video_raw = GST_VIDEO_INFO_IS_YUV(&vi); - sink->video_width = GST_VIDEO_INFO_WIDTH(&vi); - sink->video_height = GST_VIDEO_INFO_HEIGHT(&vi); - sink->video_par_n = GST_VIDEO_INFO_PAR_N(&vi); - sink->video_par_d = GST_VIDEO_INFO_PAR_D(&vi); + sink->use_video_raw = GST_VIDEO_INFO_IS_YUV(vip); + sink->video_width = GST_VIDEO_INFO_WIDTH(vip); + sink->video_height = GST_VIDEO_INFO_HEIGHT(vip); + sink->video_par_n = GST_VIDEO_INFO_PAR_N(vip); + sink->video_par_d = GST_VIDEO_INFO_PAR_D(vip); GST_DEBUG("video pixel-aspect-ratio %d/%d", sink->video_par_n, sink->video_par_d); @@ -1016,6 +1018,78 @@ gst_vaapisink_put_surface( return TRUE; } +#if GST_CHECK_VERSION(1,0,0) +static GstFlowReturn +gst_vaapisink_get_render_buffer(GstVaapiSink *sink, GstBuffer *src_buffer, + GstBuffer **out_buffer_ptr) +{ + GstVaapiVideoMeta *meta; + GstBuffer *out_buffer; + GstBufferPoolAcquireParams params = { 0, }; + GstVideoFrame src_frame, out_frame; + GstFlowReturn ret; + + meta = gst_buffer_get_vaapi_video_meta(src_buffer); + if (meta) { + *out_buffer_ptr = gst_buffer_ref(src_buffer); + return GST_FLOW_OK; + } + + if (!sink->use_video_raw) { + GST_ERROR("unsupported video buffer"); + return GST_FLOW_EOS; + } + + GST_DEBUG("buffer %p not from our pool, copying", src_buffer); + + *out_buffer_ptr = NULL; + if (!sink->video_buffer_pool) + goto error_no_pool; + + if (!gst_buffer_pool_set_active(sink->video_buffer_pool, TRUE)) + goto error_activate_pool; + + params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT; + ret = gst_buffer_pool_acquire_buffer(sink->video_buffer_pool, &out_buffer, + ¶ms); + if (ret != GST_FLOW_OK) + goto error_create_buffer; + + if (!gst_video_frame_map(&src_frame, &sink->video_info, src_buffer, + GST_MAP_READ)) + goto error_map_src_buffer; + + if (!gst_video_frame_map(&out_frame, &sink->video_info, out_buffer, + GST_MAP_WRITE)) + goto error_map_dst_buffer; + + gst_video_frame_copy(&out_frame, &src_frame); + gst_video_frame_unmap(&out_frame); + gst_video_frame_unmap(&src_frame); + + *out_buffer_ptr = out_buffer; + return GST_FLOW_OK; + + /* ERRORS */ +error_no_pool: + GST_ERROR("no buffer pool was negotiated"); + return GST_FLOW_ERROR; +error_activate_pool: + GST_ERROR("failed to activate buffer pool"); + return GST_FLOW_ERROR; +error_create_buffer: + GST_WARNING("failed to create image. Skipping this frame"); + return GST_FLOW_OK; +error_map_dst_buffer: + gst_video_frame_unmap(&src_frame); + // fall-through +error_map_src_buffer: + GST_WARNING("failed to map buffer. Skipping this frame"); + gst_buffer_unref(out_buffer); + return GST_FLOW_OK; +} +#endif + static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) { @@ -1029,15 +1103,11 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) #if GST_CHECK_VERSION(1,0,0) GstVaapiRectangle tmp_rect; #endif + GstFlowReturn ret; - meta = gst_buffer_get_vaapi_video_meta(src_buffer); #if GST_CHECK_VERSION(1,0,0) - if (!meta) - return GST_FLOW_EOS; - buffer = gst_buffer_ref(src_buffer); - GstVideoCropMeta * const crop_meta = - gst_buffer_get_video_crop_meta(buffer); + gst_buffer_get_video_crop_meta(src_buffer); if (crop_meta) { surface_rect = &tmp_rect; surface_rect->x = crop_meta->x; @@ -1045,7 +1115,14 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) surface_rect->width = crop_meta->width; surface_rect->height = crop_meta->height; } + + ret = gst_vaapisink_get_render_buffer(sink, src_buffer, &buffer); + if (ret != GST_FLOW_OK || !buffer) + return ret; + + meta = gst_buffer_get_vaapi_video_meta(buffer); #else + meta = gst_buffer_get_vaapi_video_meta(src_buffer); if (meta) buffer = gst_buffer_ref(src_buffer); else if (sink->use_video_raw) { @@ -1462,4 +1539,5 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->use_overlay = FALSE; sink->use_rotation = FALSE; sink->keep_aspect = TRUE; + gst_video_info_init(&sink->video_info); } diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index c60258a618..e732fc5801 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -85,6 +85,7 @@ struct _GstVaapiSink { guint video_height; gint video_par_n; gint video_par_d; + GstVideoInfo video_info; GstVaapiRectangle display_rect; GstVaapiRotation rotation; GstVaapiRotation rotation_req; From 6d7b5eef7de474cfb9e30629ecfffa06cc56c47c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 29 Aug 2013 19:07:34 +0200 Subject: [PATCH 1324/3781] vaapisink: simplify get_render_buffer() for GStreamer 0.10 builds. Implement and use gst_vaapisink_get_render_buffer() for GStreamer 0.10 builds as well. --- gst/vaapi/gstvaapisink.c | 61 +++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 64e48d8cba..868ab1b50b 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1088,6 +1088,44 @@ error_map_src_buffer: gst_buffer_unref(out_buffer); return GST_FLOW_OK; } +#else +static GstFlowReturn +gst_vaapisink_get_render_buffer(GstVaapiSink *sink, GstBuffer *src_buffer, + GstBuffer **out_buffer_ptr) +{ + GstVaapiVideoMeta *meta; + GstBuffer *out_buffer; + + *out_buffer_ptr = NULL; + meta = gst_buffer_get_vaapi_video_meta(src_buffer); + if (meta) + out_buffer = gst_buffer_ref(src_buffer); + else if (sink->use_video_raw) { + out_buffer = gst_vaapi_uploader_get_buffer(sink->uploader); + if (!out_buffer) + goto error_create_buffer; + } + else { + GST_ERROR("unsupported video buffer"); + return GST_FLOW_EOS; + } + + if (sink->use_video_raw && + !gst_vaapi_uploader_process(sink->uploader, src_buffer, out_buffer)) + goto error_copy_buffer; + + *out_buffer_ptr = out_buffer; + return GST_FLOW_OK; + + /* ERRORS */ +error_create_buffer: + GST_WARNING("failed to create buffer. Skipping this frame"); + return GST_FLOW_OK; +error_copy_buffer: + GST_WARNING("failed to copy buffers. Skipping this frame"); + gst_buffer_unref(out_buffer); + return GST_FLOW_OK; +} #endif static GstFlowReturn @@ -1115,34 +1153,13 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) surface_rect->width = crop_meta->width; surface_rect->height = crop_meta->height; } +#endif ret = gst_vaapisink_get_render_buffer(sink, src_buffer, &buffer); if (ret != GST_FLOW_OK || !buffer) return ret; meta = gst_buffer_get_vaapi_video_meta(buffer); -#else - meta = gst_buffer_get_vaapi_video_meta(src_buffer); - if (meta) - buffer = gst_buffer_ref(src_buffer); - else if (sink->use_video_raw) { - buffer = gst_vaapi_uploader_get_buffer(sink->uploader); - if (!buffer) - return GST_FLOW_EOS; - meta = gst_buffer_get_vaapi_video_meta(buffer); - if (!meta) - goto error; - } - else - return GST_FLOW_EOS; - - if (sink->use_video_raw && - !gst_vaapi_uploader_process(sink->uploader, src_buffer, buffer)) { - GST_WARNING("failed to process raw YUV buffer"); - goto error; - } -#endif - if (sink->display != gst_vaapi_video_meta_get_display(meta)) gst_vaapi_display_replace(&sink->display, gst_vaapi_video_meta_get_display(meta)); From 45b4ba7df713f6396cf057e9bc4b8472b9b2fa71 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Thu, 18 Apr 2013 19:49:42 +0800 Subject: [PATCH 1325/3781] vaapisink: ensure the uploader is setup for upstream allocated buffers. In GStreamer 0.10 builds, make sure that the GstVaapiUploader helper is setup in case upstream elements allocate buffers themselves without honouring our GstVaapiSink::bufer_alloc() hook. In particular, this fixes support for OGG video streams with WebKit. https://bugzilla.gnome.org/show_bug.cgi?id=703934 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 868ab1b50b..ae39a516e5 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -776,6 +776,16 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) if (!gst_vaapisink_ensure_display(sink)) return FALSE; +#if !GST_CHECK_VERSION(1,0,0) + if (sink->use_video_raw) { + /* Ensure the uploader is set up for upstream allocated buffers */ + if (!gst_vaapi_uploader_ensure_display(sink->uploader, sink->display)) + return FALSE; + if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL)) + return FALSE; + } +#endif + gst_vaapisink_ensure_rotation(sink, FALSE); gst_vaapisink_ensure_window_size(sink, &win_width, &win_height); From 621d48a5b1d1b51256ef8a6e76b8ee625fd4f7c3 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Thu, 15 Aug 2013 17:59:37 +0800 Subject: [PATCH 1326/3781] configure: fix detection of VA/JPEG decoding API. Fix detection of VA/JPEG decoding API with non-standard libva packages. More precisely, some packages were shipping with a header that did not include . https://bugzilla.gnome.org/show_bug.cgi?id=706055 Signed-off-by: Gwenole Beauchesne --- configure.ac | 12 +++++++++++- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 66828fdcff..027380b865 100644 --- a/configure.ac +++ b/configure.ac @@ -593,6 +593,12 @@ if test $USE_GLX -eq 1; then fi AC_SUBST(LIBVA_GLX_PKGNAME) +dnl Check for va_dec_jpeg.h header +saved_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" +AC_CHECK_HEADERS([va/va_dec_jpeg.h], [], [], [#include ]) +CPPFLAGS="$saved_CPPFLAGS" + dnl Check for JPEG decoding API (0.32.1+) USE_JPEG_DECODER=0 AC_CACHE_CHECK([for JPEG decoding API], @@ -603,7 +609,11 @@ AC_CACHE_CHECK([for JPEG decoding API], LIBS="$LIBS $LIBVA_LIBS" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - [[#include ]], + [[#include + #ifdef HAVE_VA_VA_DEC_JPEG_H + #include + #endif + ]], [[VAPictureParameterBufferJPEGBaseline pic_param; VASliceParameterBufferJPEGBaseline slice_param; VAHuffmanTableBufferJPEGBaseline huffman_table; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 0dde75cdc3..9e6277863e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -34,6 +34,10 @@ #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" +#ifdef HAVE_VA_VA_DEC_JPEG_H +# include +#endif + #define DEBUG 1 #include "gstvaapidebug.h" From 60c8ae0dad5b82ed243bf25eac5b0d9a4a243071 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 31 Aug 2013 15:46:25 +0200 Subject: [PATCH 1327/3781] NEWS: updates. --- NEWS | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index efbd29abb8..6df13a06b2 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,21 @@ -gst-vaapi NEWS -- summary of changes. 2013-07-15 +gst-vaapi NEWS -- summary of changes. 2013-08-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora +Version 0.5.6 - DD.Aug.2013 +* Add render-to-pixmap API to bypass VA/GLX in clutter-gst +* Add initial support for video-processing APIs (+Halley Zhao) +* Add support for video cropping and deinterlacing to the Wayland backend +* Add "force-aspect-ratio" property to vaapisink (Simon Farnsworth) +* Fix support for clutter-gst in GStreamer 0.10 builds +* Fix HW accelerated rendering with SW decoded pipelines +* Fix videotestsrc ! vaapisink pipelines (Guangxin Xu) +* Fix memory leak of raw video uploader objects (Feng Yuan) +* Fix decoding without a video parser element before `vaapidecde' +* Fix regression in MPEG-2 decoder due to incomplete video cropping support +* Fix dead-lock condition on Wayland when the end-of-stream is reached + Version 0.5.5 - 15.Jul.2013 * Allow creation of video surfaces with an explicit pixel format * Allocate VA/GLX capable buffers by default on X11 servers (Victor Jaquez) From 06872247967f38b73d17ea0eff59f03a1ad87321 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 31 Aug 2013 15:47:33 +0200 Subject: [PATCH 1328/3781] 0.5.6. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 6df13a06b2..86fafea4ff 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2013-08-DD +gst-vaapi NEWS -- summary of changes. 2013-08-29 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora -Version 0.5.6 - DD.Aug.2013 +Version 0.5.6 - 29.Aug.2013 * Add render-to-pixmap API to bypass VA/GLX in clutter-gst * Add initial support for video-processing APIs (+Halley Zhao) * Add support for video cropping and deinterlacing to the Wayland backend diff --git a/configure.ac b/configure.ac index 027380b865..ac3751001d 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [6]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 0a4582de6fa43f9f7fbfedf595e8c390f045f43f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 31 Aug 2013 16:00:05 +0200 Subject: [PATCH 1329/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index ac3751001d..3ff07bd589 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [6]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [7]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From a1d91e038cb8ea1abe80350f4774cebd47fd65d5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Sep 2013 18:30:18 +0200 Subject: [PATCH 1330/3781] codecparsers: update to gst-vaapi-branch commit 23c7dde. 23c7dde jpeg: fix calculation of segment size --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index f90de0a583..23c7dde404 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit f90de0a5836546f8e37b41adca14f76bfaaec44d +Subproject commit 23c7dde4048c54c9af6ad1f2894a669cebcd1f1f From 9c29bbde58e1a9a343b8e973295c6d98bb8fed91 Mon Sep 17 00:00:00 2001 From: Junfeng Xu Date: Tue, 10 Sep 2013 15:46:09 +0800 Subject: [PATCH 1331/3781] jpeg: fix calculation of offset to next marker segment. Fix calculation of the offset to the next marker segment since the correction of the codecparser part to match the API specification. i.e. the GstJpegMarkerSegment.size field represents the size in bytes of the segment minus any marker prefix. https://bugzilla.gnome.org/show_bug.cgi?id=707447 Signed-off-by: Junfeng Xu --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 9e6277863e..92b5926664 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -536,7 +536,7 @@ decode_buffer(GstVaapiDecoderJpeg *decoder, const guchar *buf, guint buf_size) GST_DEBUG("buffer to short for parsing"); return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; } - ofs += seg.size; + ofs = seg.offset + seg.size; /* Decode scan, if complete */ if (seg.marker == GST_JPEG_MARKER_EOI && scan_seg.header_size > 0) { From 77298beb15575131600867d6df2a3e85c3f1bc20 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 18 Sep 2013 17:59:44 +0200 Subject: [PATCH 1332/3781] jpeg: fix determination of image bounds. Look for the exact image bounds characterised by the and markers. Use the gst_jpeg_parse() codec parser utility function to optimize the lookup for the next marker segment. https://bugzilla.gnome.org/show_bug.cgi?id=707447 --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 61 ++++++++++++++++------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 92b5926664..f9fafbbc3b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -647,11 +647,21 @@ ensure_decoder(GstVaapiDecoderJpeg *decoder) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static inline gint -scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) +static gint +scan_for_marker_code(const guchar *buf, guint buf_size, + GstJpegMarkerCode marker) { - return (gint)gst_adapter_masked_scan_uint32_peek(adapter, - 0xffff0000, 0xffd80000, ofs, size, scp); + GstJpegMarkerSegment seg; + guint ofs = 0; + + while (gst_jpeg_parse(&seg, buf, buf_size, ofs)) { + if (seg.size < 0) + return -1; + if (seg.marker == marker) + return seg.offset - 2; + ofs = seg.offset + seg.size; + } + return -1; } static GstVaapiDecoderStatus @@ -660,37 +670,54 @@ gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder, { GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG_CAST(base_decoder); + GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiDecoderStatus status; - guint size, buf_size, flags = 0; - gint ofs; + const guchar *buf; + guint buf_size, flags; + gint ofs, ofs1, ofs2; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; /* Expect at least 4 bytes, SOI .. EOI */ - size = gst_adapter_available(adapter); - if (size < 4) + buf_size = gst_adapter_available(adapter); + if (buf_size < 4) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - ofs = scan_for_start_code(adapter, 0, size, NULL); - if (ofs < 0) + buf = gst_adapter_map(adapter, buf_size); + if (!buf) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - gst_adapter_flush(adapter, ofs); - size -= ofs; - ofs = G_UNLIKELY(size < 4) ? -1 : - scan_for_start_code(adapter, 2, size - 2, NULL); + ofs = scan_for_marker_code(buf, buf_size, GST_JPEG_MARKER_SOI); + if (ofs < 0) { + gst_adapter_unmap(adapter); + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } + ofs1 = ofs; + + ofs2 = ps->input_offset2 - 2; + if (ofs2 < ofs1 + 2) + ofs2 = ofs1 + 2; + + ofs = G_UNLIKELY(buf_size < ofs2 + 2) ? -1 : + scan_for_marker_code(&buf[ofs2], buf_size - ofs2, GST_JPEG_MARKER_EOI); + gst_adapter_unmap(adapter); if (ofs < 0) { // Assume the whole packet is present if end-of-stream - if (!at_eos) + if (!at_eos) { + ps->input_offset2 = buf_size; return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - ofs = size; + } + ofs = buf_size - ofs2; } - buf_size = ofs; + ofs2 += ofs; unit->size = buf_size; + gst_adapter_flush(adapter, ofs1); + ps->input_offset2 = 2; + flags = 0; flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; From a4aac6b89e70ed2ebb70051b3d5196184dab994a Mon Sep 17 00:00:00 2001 From: Junfeng Xu Date: Tue, 17 Sep 2013 14:29:54 +0800 Subject: [PATCH 1333/3781] jpeg: handle comment segments. Fix decode_buffer() function to gracefully skip comment (COM) segments. This fixes decoding of streams generated by certain cameras, e.g. like the Logitech Pro C920. https://bugzilla.gnome.org/show_bug.cgi?id=708208 Signed-off-by: Junfeng Xu --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index f9fafbbc3b..a810ae6c40 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -581,6 +581,9 @@ decode_buffer(GstVaapiDecoderJpeg *decoder, const guchar *buf, guint buf_size) case GST_JPEG_MARKER_DRI: status = decode_restart_interval(decoder, buf + seg.offset, seg.size); break; + case GST_JPEG_MARKER_COM: + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; case GST_JPEG_MARKER_DAC: GST_ERROR("unsupported arithmetic coding mode"); status = GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; From f52dfe57978789e2b2a654689807f91ffd8ac06e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Sep 2013 10:12:08 +0200 Subject: [PATCH 1334/3781] jpeg: rework and optimize parser. Split the input buffer data into decoder units that represent a JPEG segment. Handle scan decoder unit specifically so that it can include both the scan header (SOS) but also any other ECS or RSTi segment. That way, we parse the input buffer stream only once at the gst-vaapi level instead of (i) in gst_vaapi_decoder_jpeg_parse() to split the stream into frames SOI .. EOI and (ii) in decode_buffer() to further determine segment boundaries and decode them. In practice, this is a +15 to +25% performance improvement. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 473 +++++++++++----------- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 1 + 3 files changed, 235 insertions(+), 240 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 787029195b..76a46ffb84 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -85,6 +85,7 @@ parser_state_prepare(GstVaapiParserState *ps, GstAdapter *adapter) reset: ps->current_adapter = adapter; + ps->input_offset1 = -1; ps->input_offset2 = -1; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index a810ae6c40..ec9c3e7e35 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -60,6 +60,7 @@ struct _GstVaapiDecoderJpegPrivate { guint mcu_restart; guint is_opened : 1; guint profile_changed : 1; + guint expect_SOI : 1; }; /** @@ -83,14 +84,17 @@ struct _GstVaapiDecoderJpegClass { GstVaapiDecoderClass parent_class; }; -typedef struct _GstJpegScanSegment GstJpegScanSegment; -struct _GstJpegScanSegment { - guint header_offset; - guint header_size; - guint data_offset; - guint data_size; - guint is_valid : 1; -}; +static inline void +unit_set_marker_code(GstVaapiDecoderUnit *unit, GstJpegMarkerCode marker) +{ + unit->parsed_info = GSIZE_TO_POINTER(marker); +} + +static inline GstJpegMarkerCode +unit_get_marker_code(GstVaapiDecoderUnit *unit) +{ + return GPOINTER_TO_SIZE(unit->parsed_info); +} static void gst_vaapi_decoder_jpeg_close(GstVaapiDecoderJpeg *decoder) @@ -110,8 +114,11 @@ gst_vaapi_decoder_jpeg_close(GstVaapiDecoderJpeg *decoder) static gboolean gst_vaapi_decoder_jpeg_open(GstVaapiDecoderJpeg *decoder) { + GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; + gst_vaapi_decoder_jpeg_close(decoder); + priv->expect_SOI = TRUE; return TRUE; } @@ -182,21 +189,25 @@ ensure_context(GstVaapiDecoderJpeg *decoder) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static gboolean +static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderJpeg *decoder) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstVaapiPicture * const picture = priv->current_picture; - gboolean success = TRUE; - if (picture) { - if (!gst_vaapi_picture_decode(picture)) - success = FALSE; - else if (!gst_vaapi_picture_output(picture)) - success = FALSE; - gst_vaapi_picture_replace(&priv->current_picture, NULL); - } - return success; + 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; + +error: + gst_vaapi_picture_replace(&priv->current_picture, NULL); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } static gboolean @@ -339,57 +350,28 @@ get_max_vertical_samples(GstJpegFrameHdr *frame_hdr) } static GstVaapiDecoderStatus -decode_picture( - GstVaapiDecoderJpeg *decoder, - guint8 profile, - const guchar *buf, - guint buf_size -) +decode_picture(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, + const guchar *buf) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstJpegFrameHdr * const frame_hdr = &priv->frame_hdr; - GstVaapiPicture *picture; - GstVaapiDecoderStatus status; - switch (profile) { + switch (seg->marker) { case GST_JPEG_MARKER_SOF_MIN: priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; break; default: - GST_ERROR("unsupported profile %d", profile); + 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_parse_frame_hdr(frame_hdr, buf, buf_size, 0)) { + if (!gst_jpeg_parse_frame_hdr(frame_hdr, buf + seg->offset, seg->size, 0)) { GST_ERROR("failed to parse image"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } priv->height = frame_hdr->height; priv->width = frame_hdr->width; - - status = ensure_context(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_ERROR("failed to reset context"); - return status; - } - - if (priv->current_picture && !decode_current_picture(decoder)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - - 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, frame_hdr)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - - /* Update presentation time */ - picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -444,47 +426,35 @@ decode_restart_interval( } static GstVaapiDecoderStatus -decode_scan( - GstVaapiDecoderJpeg *decoder, - const guchar *scan_header, - guint scan_header_size, - const guchar *scan_data, - guint scan_data_size -) +decode_scan(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, + const guchar *buf) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; - GstVaapiPicture *picture = priv->current_picture; + GstVaapiPicture * const picture = priv->current_picture; + GstVaapiSlice *slice; VASliceParameterBufferJPEGBaseline *slice_param; - GstVaapiSlice *gst_slice; - guint total_h_samples, total_v_samples; - GstJpegScanHdr scan_hdr; - guint i; + GstJpegScanHdr scan_hdr; + guint scan_hdr_size, scan_data_size; + guint i, total_h_samples, total_v_samples; - if (!picture) { - GST_ERROR("There is no VAPicture before decoding scan."); - return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE; - } - - if (!fill_quantization_table(decoder, picture)) { - GST_ERROR("failed to fill in quantization table"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - - if (!fill_huffman_table(decoder, picture)) { - GST_ERROR("failed to fill in huffman table"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } + scan_hdr_size = (buf[seg->offset] << 8) | buf[seg->offset + 1]; + scan_data_size = seg->size - scan_hdr_size; memset(&scan_hdr, 0, sizeof(scan_hdr)); - if (!gst_jpeg_parse_scan_hdr(&scan_hdr, scan_header, scan_header_size, 0)) { + if (!gst_jpeg_parse_scan_hdr(&scan_hdr, buf + seg->offset, seg->size, 0)) { GST_DEBUG("Jpeg parsed scan failed."); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } - gst_slice = GST_VAAPI_SLICE_NEW(JPEGBaseline, decoder, scan_data, scan_data_size); - gst_vaapi_picture_add_slice(picture, gst_slice); + slice = GST_VAAPI_SLICE_NEW(JPEGBaseline, decoder, + buf + 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); - slice_param = gst_slice->param; + 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 = @@ -512,128 +482,47 @@ decode_scan( slice_param->num_mcus = ((priv->frame_hdr.width + total_h_samples*8 - 1)/(total_h_samples*8)) * ((priv->frame_hdr.height + total_v_samples*8 -1)/(total_v_samples*8)); } - - if (picture->slices && picture->slices->len) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_buffer(GstVaapiDecoderJpeg *decoder, const guchar *buf, guint buf_size) +decode_segment(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, + const guchar *buf) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; - GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - GstJpegMarkerSegment seg; - GstJpegScanSegment scan_seg; - guint ofs; - gboolean append_ecs; + GstVaapiDecoderStatus status; - memset(&scan_seg, 0, sizeof(scan_seg)); - - ofs = 0; - while (gst_jpeg_parse(&seg, buf, buf_size, ofs)) { - if (seg.size < 0) { - GST_DEBUG("buffer to short for parsing"); - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - } - ofs = seg.offset + seg.size; - - /* Decode scan, if complete */ - if (seg.marker == GST_JPEG_MARKER_EOI && scan_seg.header_size > 0) { - scan_seg.data_size = seg.offset - scan_seg.data_offset; - scan_seg.is_valid = TRUE; - } - if (scan_seg.is_valid) { - status = decode_scan( - decoder, - buf + scan_seg.header_offset, - scan_seg.header_size, - buf + scan_seg.data_offset, - scan_seg.data_size - ); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - break; - memset(&scan_seg, 0, sizeof(scan_seg)); - } - - append_ecs = TRUE; - switch (seg.marker) { - case GST_JPEG_MARKER_SOI: - priv->has_quant_table = FALSE; - priv->has_huf_table = FALSE; - priv->mcu_restart = 0; - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - case GST_JPEG_MARKER_EOI: - if (decode_current_picture(decoder)) { - /* Get out of the loop, trailing data is not needed */ - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - goto end; - } - status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - break; - case GST_JPEG_MARKER_DHT: - status = decode_huffman_table(decoder, buf + seg.offset, seg.size); - break; - case GST_JPEG_MARKER_DQT: - status = decode_quant_table(decoder, buf + seg.offset, seg.size); - break; - case GST_JPEG_MARKER_DRI: - status = decode_restart_interval(decoder, buf + seg.offset, seg.size); - break; - case GST_JPEG_MARKER_COM: - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - 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_SOS: - scan_seg.header_offset = seg.offset; - scan_seg.header_size = seg.size; - scan_seg.data_offset = seg.offset + seg.size; - scan_seg.data_size = 0; - append_ecs = FALSE; - break; - default: - /* Restart marker */ - if (seg.marker >= GST_JPEG_MARKER_RST_MIN && - seg.marker <= GST_JPEG_MARKER_RST_MAX) { - append_ecs = FALSE; - break; - } - - /* Frame header */ - if (seg.marker >= GST_JPEG_MARKER_SOF_MIN && - seg.marker <= GST_JPEG_MARKER_SOF_MAX) { - status = decode_picture( - decoder, - seg.marker, - buf + seg.offset, seg.size - ); - break; - } - - /* Application segments */ - if (seg.marker >= GST_JPEG_MARKER_APP_MIN && - seg.marker <= GST_JPEG_MARKER_APP_MAX) { - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } - - GST_WARNING("unsupported marker (0x%02x)", seg.marker); - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - break; - } - - /* Append entropy coded segments */ - if (append_ecs) - scan_seg.data_size = seg.offset - scan_seg.data_offset; - - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - break; + // Decode segment + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + switch (seg->marker) { + case GST_JPEG_MARKER_SOI: + priv->has_quant_table = FALSE; + priv->has_huf_table = FALSE; + priv->mcu_restart = 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, buf + seg->offset, seg->size); + break; + case GST_JPEG_MARKER_DQT: + status = decode_quant_table(decoder, buf + seg->offset, seg->size); + break; + case GST_JPEG_MARKER_DRI: + status = decode_restart_interval(decoder, buf + seg->offset, seg->size); + break; + case GST_JPEG_MARKER_SOS: + status = decode_scan(decoder, seg, buf); + break; + default: + // SOFn segments + if (seg->marker >= GST_JPEG_MARKER_SOF_MIN && + seg->marker <= GST_JPEG_MARKER_SOF_MAX) + status = decode_picture(decoder, seg, buf); + break; } -end: return status; } @@ -650,21 +539,11 @@ ensure_decoder(GstVaapiDecoderJpeg *decoder) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static gint -scan_for_marker_code(const guchar *buf, guint buf_size, - GstJpegMarkerCode marker) +static gboolean +is_scan_complete(GstJpegMarkerCode marker) { - GstJpegMarkerSegment seg; - guint ofs = 0; - - while (gst_jpeg_parse(&seg, buf, buf_size, ofs)) { - if (seg.size < 0) - return -1; - if (seg.marker == marker) - return seg.offset - 2; - ofs = seg.offset + seg.size; - } - return -1; + // 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 @@ -673,57 +552,113 @@ gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder, { 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; + GstJpegMarkerCode marker; + GstJpegMarkerSegment seg; const guchar *buf; guint buf_size, flags; - gint ofs, ofs1, ofs2; + gint ofs1, ofs2; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - /* Expect at least 4 bytes, SOI .. EOI */ + /* Expect at least 2 bytes for the marker */ buf_size = gst_adapter_available(adapter); - if (buf_size < 4) + 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; - ofs = scan_for_marker_code(buf, buf_size, GST_JPEG_MARKER_SOI); - if (ofs < 0) { - gst_adapter_unmap(adapter); - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - } - ofs1 = ofs; + ofs1 = ps->input_offset1 - 2; + if (ofs1 < 0) + ofs1 = 0; - ofs2 = ps->input_offset2 - 2; - if (ofs2 < ofs1 + 2) - ofs2 = ofs1 + 2; - - ofs = G_UNLIKELY(buf_size < ofs2 + 2) ? -1 : - scan_for_marker_code(&buf[ofs2], buf_size - ofs2, GST_JPEG_MARKER_EOI); - gst_adapter_unmap(adapter); - if (ofs < 0) { - // Assume the whole packet is present if end-of-stream - if (!at_eos) { - ps->input_offset2 = buf_size; + 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; } - ofs = buf_size - ofs2; - } - ofs2 += ofs; + ofs1 = seg.offset; - unit->size = buf_size; + marker = seg.marker; + if (priv->expect_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; - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + flags = 0; + switch (marker) { + case GST_JPEG_MARKER_SOI: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + priv->expect_SOI = FALSE; + break; + case GST_JPEG_MARKER_EOI: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + priv->expect_SOI = TRUE; + break; + case GST_JPEG_MARKER_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: + /* Application segments */ + 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; } @@ -735,6 +670,7 @@ gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG_CAST(base_decoder); GstVaapiDecoderStatus status; + GstJpegMarkerSegment seg; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; GstMapInfo map_info; @@ -748,13 +684,68 @@ gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder, return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } - status = decode_buffer(decoder, map_info.data + unit->offset, unit->size); + seg.marker = unit_get_marker_code(unit); + seg.offset = unit->offset; + seg.size = unit->size; + + status = decode_segment(decoder, &seg, map_info.data); 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; + + 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; + + if (!fill_quantization_table(decoder, picture)) { + GST_ERROR("failed to fill in quantization table"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!fill_huffman_table(decoder, picture)) { + GST_ERROR("failed to fill in huffman table"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + /* 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_class_init(GstVaapiDecoderJpegClass *klass) { @@ -769,6 +760,8 @@ gst_vaapi_decoder_jpeg_class_init(GstVaapiDecoderJpegClass *klass) decoder_class->destroy = gst_vaapi_decoder_jpeg_destroy; 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 inline const GstVaapiDecoderClass * diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index a86b4a16ae..8b6d8970c6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -168,6 +168,7 @@ struct _GstVaapiParserState { GstVideoCodecFrame *current_frame; GstAdapter *current_adapter; GstAdapter *input_adapter; + gint input_offset1; gint input_offset2; GstAdapter *output_adapter; GstVaapiDecoderUnit next_unit; From 22fef0944305ed43a2a14c9035f88b1ff55930a4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Sep 2013 16:46:43 +0200 Subject: [PATCH 1335/3781] jpeg: minor clean-ups. Improve debugging and error messages. Rename a few variables to fit the existing naming conventions. Change some fatal asserts to non-fatal error codes. --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 79 ++++++++++++----------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index ec9c3e7e35..6d8de08f11 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -214,39 +214,34 @@ static gboolean fill_picture( GstVaapiDecoderJpeg *decoder, GstVaapiPicture *picture, - GstJpegFrameHdr *jpeg_frame_hdr + GstJpegFrameHdr *frame_hdr ) { - VAPictureParameterBufferJPEGBaseline *pic_param = picture->param; + VAPictureParameterBufferJPEGBaseline * const pic_param = picture->param; guint i; - g_assert(pic_param); - memset(pic_param, 0, sizeof(VAPictureParameterBufferJPEGBaseline)); - pic_param->picture_width = jpeg_frame_hdr->width; - pic_param->picture_height = jpeg_frame_hdr->height; + pic_param->picture_width = frame_hdr->width; + pic_param->picture_height = frame_hdr->height; - pic_param->num_components = jpeg_frame_hdr->num_components; - if (jpeg_frame_hdr->num_components > 4) + 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 = - jpeg_frame_hdr->components[i].identifier; + frame_hdr->components[i].identifier; pic_param->components[i].h_sampling_factor = - jpeg_frame_hdr->components[i].horizontal_factor; + frame_hdr->components[i].horizontal_factor; pic_param->components[i].v_sampling_factor = - jpeg_frame_hdr->components[i].vertical_factor; + frame_hdr->components[i].vertical_factor; pic_param->components[i].quantiser_table_selector = - jpeg_frame_hdr->components[i].quant_table_selector; + frame_hdr->components[i].quant_table_selector; } return TRUE; } -static gboolean -fill_quantization_table( - GstVaapiDecoderJpeg *decoder, - GstVaapiPicture *picture -) +static GstVaapiDecoderStatus +fill_quantization_table(GstVaapiDecoderJpeg *decoder, GstVaapiPicture *picture) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; VAIQMatrixBufferJPEGBaseline *iq_matrix; @@ -256,7 +251,10 @@ fill_quantization_table( gst_jpeg_get_default_quantization_tables(&priv->quant_tables); picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(JPEGBaseline, decoder); - g_assert(picture->iq_matrix); + 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), @@ -270,20 +268,22 @@ fill_quantization_table( if (!iq_matrix->load_quantiser_table[i]) continue; - g_assert(quant_table->quant_precision == 0); + 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 TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static gboolean -fill_huffman_table( - GstVaapiDecoderJpeg *decoder, - GstVaapiPicture *picture -) +static GstVaapiDecoderStatus +fill_huffman_table(GstVaapiDecoderJpeg *decoder, GstVaapiPicture *picture) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstJpegHuffmanTables * const huf_tables = &priv->huf_tables; @@ -294,7 +294,10 @@ fill_huffman_table( gst_jpeg_get_default_huffman_tables(&priv->huf_tables); picture->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW(JPEGBaseline, decoder); - g_assert(picture->huf_table); + 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), @@ -322,7 +325,7 @@ fill_huffman_table( 0, sizeof(huffman_table->huffman_table[i].pad)); } - return TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static guint @@ -385,7 +388,7 @@ decode_huffman_table( GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; if (!gst_jpeg_parse_huffman_table(&priv->huf_tables, buf, buf_size, 0)) { - GST_DEBUG("failed to parse Huffman table"); + GST_ERROR("failed to parse Huffman table"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } priv->has_huf_table = TRUE; @@ -402,7 +405,7 @@ decode_quant_table( GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; if (!gst_jpeg_parse_quant_table(&priv->quant_tables, buf, buf_size, 0)) { - GST_DEBUG("failed to parse quantization table"); + GST_ERROR("failed to parse quantization table"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } priv->has_quant_table = TRUE; @@ -419,7 +422,7 @@ decode_restart_interval( GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; if (!gst_jpeg_parse_restart_interval(&priv->mcu_restart, buf, buf_size, 0)) { - GST_DEBUG("failed to parse restart interval"); + GST_ERROR("failed to parse restart interval"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -442,7 +445,7 @@ decode_scan(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, memset(&scan_hdr, 0, sizeof(scan_hdr)); if (!gst_jpeg_parse_scan_hdr(&scan_hdr, buf + seg->offset, seg->size, 0)) { - GST_DEBUG("Jpeg parsed scan failed."); + GST_ERROR("failed to parse scan header"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -722,15 +725,13 @@ gst_vaapi_decoder_jpeg_start_frame(GstVaapiDecoder *base_decoder, if (!fill_picture(decoder, picture, &priv->frame_hdr)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - if (!fill_quantization_table(decoder, picture)) { - GST_ERROR("failed to fill in quantization table"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } + status = fill_quantization_table(decoder, picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; - if (!fill_huffman_table(decoder, picture)) { - GST_ERROR("failed to fill in huffman table"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } + status = fill_huffman_table(decoder, picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; /* Update presentation time */ picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; From fd51db279a6af9d239a784cfc245d38921306ebd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Sep 2013 11:41:52 +0200 Subject: [PATCH 1336/3781] jpeg: improve robustness when packets are missing. Improve robustness when some expected packets where not received yet or that were not correctly decoded. For example, don't try to decode a picture if there was no valid frame headers. --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 93 +++++++++++++++++++---- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 6d8de08f11..921e14cdd8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -47,6 +47,19 @@ 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; @@ -55,12 +68,11 @@ struct _GstVaapiDecoderJpegPrivate { GstJpegFrameHdr frame_hdr; GstJpegHuffmanTables huf_tables; GstJpegQuantTables quant_tables; - gboolean has_huf_table; - gboolean has_quant_table; guint mcu_restart; + guint parser_state; + guint decoder_state; guint is_opened : 1; guint profile_changed : 1; - guint expect_SOI : 1; }; /** @@ -118,7 +130,8 @@ gst_vaapi_decoder_jpeg_open(GstVaapiDecoderJpeg *decoder) gst_vaapi_decoder_jpeg_close(decoder); - priv->expect_SOI = TRUE; + priv->parser_state = 0; + priv->decoder_state = 0; return TRUE; } @@ -189,12 +202,26 @@ ensure_context(GstVaapiDecoderJpeg *decoder) 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; @@ -208,6 +235,10 @@ decode_current_picture(GstVaapiDecoderJpeg *decoder) error: gst_vaapi_picture_replace(&priv->current_picture, NULL); return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + +drop_frame: + priv->decoder_state = 0; + return GST_VAAPI_DECODER_STATUS_DROP_FRAME; } static gboolean @@ -247,7 +278,7 @@ fill_quantization_table(GstVaapiDecoderJpeg *decoder, GstVaapiPicture *picture) VAIQMatrixBufferJPEGBaseline *iq_matrix; guint i, j, num_tables; - if (!priv->has_quant_table) + 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); @@ -290,7 +321,7 @@ fill_huffman_table(GstVaapiDecoderJpeg *decoder, GstVaapiPicture *picture) VAHuffmanTableBufferJPEGBaseline *huffman_table; guint i, num_tables; - if (!priv->has_huf_table) + if (!VALID_STATE(decoder, GOT_HUF_TABLE)) gst_jpeg_get_default_huffman_tables(&priv->huf_tables); picture->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW(JPEGBaseline, decoder); @@ -359,6 +390,9 @@ decode_picture(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *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; @@ -375,6 +409,8 @@ decode_picture(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, } 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; } @@ -387,11 +423,15 @@ decode_huffman_table( { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; + if (!VALID_STATE(decoder, GOT_SOI)) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_jpeg_parse_huffman_table(&priv->huf_tables, buf, buf_size, 0)) { GST_ERROR("failed to parse Huffman table"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } - priv->has_huf_table = TRUE; + + priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_HUF_TABLE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -404,11 +444,15 @@ decode_quant_table( { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; + if (!VALID_STATE(decoder, GOT_SOI)) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_jpeg_parse_quant_table(&priv->quant_tables, buf, buf_size, 0)) { GST_ERROR("failed to parse quantization table"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } - priv->has_quant_table = TRUE; + + priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_IQ_TABLE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -421,6 +465,9 @@ decode_restart_interval( { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; + if (!VALID_STATE(decoder, GOT_SOI)) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_jpeg_parse_restart_interval(&priv->mcu_restart, buf, buf_size, 0)) { GST_ERROR("failed to parse restart interval"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; @@ -440,6 +487,9 @@ decode_scan(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, guint scan_hdr_size, scan_data_size; guint i, total_h_samples, total_v_samples; + if (!VALID_STATE(decoder, GOT_SOF)) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + scan_hdr_size = (buf[seg->offset] << 8) | buf[seg->offset + 1]; scan_data_size = seg->size - scan_hdr_size; @@ -485,6 +535,8 @@ decode_scan(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, slice_param->num_mcus = ((priv->frame_hdr.width + total_h_samples*8 - 1)/(total_h_samples*8)) * ((priv->frame_hdr.height + total_v_samples*8 -1)/(total_v_samples*8)); } + + priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_SOS; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -499,9 +551,11 @@ decode_segment(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, status = GST_VAAPI_DECODER_STATUS_SUCCESS; switch (seg->marker) { case GST_JPEG_MARKER_SOI: - priv->has_quant_table = FALSE; - priv->has_huf_table = FALSE; 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"); @@ -591,7 +645,7 @@ gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder, ofs1 = seg.offset; marker = seg.marker; - if (priv->expect_SOI && marker != GST_JPEG_MARKER_SOI) + if (!VALID_STATE(parser, GOT_SOI) && marker != GST_JPEG_MARKER_SOI) continue; if (marker == GST_JPEG_MARKER_SOS) { ofs2 = ps->input_offset2 - 2; @@ -636,14 +690,15 @@ gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder, switch (marker) { case GST_JPEG_MARKER_SOI: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - priv->expect_SOI = FALSE; + priv->parser_state |= GST_JPEG_VIDEO_STATE_GOT_SOI; break; case GST_JPEG_MARKER_EOI: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; - priv->expect_SOI = TRUE; + 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_DNL: flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; @@ -652,9 +707,14 @@ gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder, 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 */ - if (marker >= GST_JPEG_MARKER_APP_MIN && - marker <= GST_JPEG_MARKER_APP_MAX) + else if (marker >= GST_JPEG_MARKER_APP_MIN && + marker <= GST_JPEG_MARKER_APP_MAX) flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; /* Reserved */ @@ -708,6 +768,9 @@ gst_vaapi_decoder_jpeg_start_frame(GstVaapiDecoder *base_decoder, 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"); From 5444ab44d2ed67c0d006dfbaa54799ae66397b17 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Sep 2013 16:49:41 +0200 Subject: [PATCH 1337/3781] jpeg: add support for multiscan images. Add support for images with multiple scans per frame. The Huffman table can be updated before SOS, and thus possibly requiring multiple uploads of Huffman tables to the VA driver. So, the latter must be able to cope with multiple VA buffers of type 'huffman-table' and with the correct sequential order. --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 74 ++++++++++++++------ gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 8 +++ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 3 + 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 921e14cdd8..45f8bb254c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -313,23 +313,37 @@ fill_quantization_table(GstVaapiDecoderJpeg *decoder, GstVaapiPicture *picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static GstVaapiDecoderStatus -fill_huffman_table(GstVaapiDecoderJpeg *decoder, GstVaapiPicture *picture) +static gboolean +huffman_tables_updated(const GstJpegHuffmanTables *huf_tables) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; - GstJpegHuffmanTables * const huf_tables = &priv->huf_tables; - VAHuffmanTableBufferJPEGBaseline *huffman_table; - guint i, num_tables; + guint i; - if (!VALID_STATE(decoder, GOT_HUF_TABLE)) - gst_jpeg_get_default_huffman_tables(&priv->huf_tables); - - picture->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW(JPEGBaseline, decoder); - 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; + 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); @@ -356,7 +370,6 @@ fill_huffman_table(GstVaapiDecoderJpeg *decoder, GstVaapiPicture *picture) 0, sizeof(huffman_table->huffman_table[i].pad)); } - return GST_VAAPI_DECODER_STATUS_SUCCESS; } static guint @@ -507,6 +520,21 @@ decode_scan(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, } 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++) { @@ -700,6 +728,16 @@ gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder, 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; @@ -792,10 +830,6 @@ gst_vaapi_decoder_jpeg_start_frame(GstVaapiDecoder *base_decoder, if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - status = fill_huffman_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; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index fbbe5f7675..218b51213e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -291,6 +291,11 @@ gst_vaapi_picture_decode(GstVaapiPicture *picture) 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; @@ -396,6 +401,9 @@ gst_vaapi_slice_destroy(GstVaapiSlice *slice) { VADisplay const va_display = GET_VA_DISPLAY(slice); + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)&slice->huf_table, + NULL); + vaapi_destroy_buffer(va_display, &slice->data_id); vaapi_destroy_buffer(va_display, &slice->param_id); slice->param = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 90e8f04258..3d595ae0cb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -216,6 +216,9 @@ struct _GstVaapiSlice { VABufferID param_id; VABufferID data_id; gpointer param; + + /* Per-slice overrides */ + GstVaapiHuffmanTable *huf_table; }; G_GNUC_INTERNAL From c171b007ffc11c707f62b1f6047b0d49eaaf9351 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 23 Sep 2013 19:14:56 +0200 Subject: [PATCH 1338/3781] jpeg: fix calculation of MCU count. Fix calculation of MCU count for image sizes that are not a multiple of 8 pixels in either dimension, but also for non-common sampling factors like 4:2:2 in non-interleaved mode. --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 74 ++++++++++++++--------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 45f8bb254c..c3655f08f3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -372,28 +372,39 @@ fill_huffman_table(GstVaapiHuffmanTable *huf_table, } } -static guint -get_max_horizontal_samples(GstJpegFrameHdr *frame_hdr) +static void +get_max_sampling_factors(const GstJpegFrameHdr *frame_hdr, + guint *h_max_ptr, guint *v_max_ptr) { - guint i, max_factor = 0; + guint h_max = frame_hdr->components[0].horizontal_factor; + guint v_max = frame_hdr->components[0].vertical_factor; + guint i; - for (i = 0; i < frame_hdr->num_components; i++) { - if (frame_hdr->components[i].horizontal_factor > max_factor) - max_factor = frame_hdr->components[i].horizontal_factor; + 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; } - return max_factor; + + if (h_max_ptr) + *h_max_ptr = h_max; + if (v_max_ptr) + *v_max_ptr = v_max; } -static guint -get_max_vertical_samples(GstJpegFrameHdr *frame_hdr) +static const GstJpegFrameComponent * +get_component(const GstJpegFrameHdr *frame_hdr, guint selector) { - guint i, max_factor = 0; + guint i; for (i = 0; i < frame_hdr->num_components; i++) { - if (frame_hdr->components[i].vertical_factor > max_factor) - max_factor = frame_hdr->components[i].vertical_factor; + const GstJpegFrameComponent * const fcp = &frame_hdr->components[i]; + if (fcp->identifier == selector) + return fcp; } - return max_factor; + return NULL; } static GstVaapiDecoderStatus @@ -498,7 +509,7 @@ decode_scan(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, VASliceParameterBufferJPEGBaseline *slice_param; GstJpegScanHdr scan_hdr; guint scan_hdr_size, scan_data_size; - guint i, total_h_samples, total_v_samples; + guint i, h_max, v_max, mcu_width, mcu_height; if (!VALID_STATE(decoder, GOT_SOF)) return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -546,23 +557,28 @@ decode_scan(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, scan_hdr.components[i].ac_selector; } slice_param->restart_interval = priv->mcu_restart; - if (scan_hdr.num_components == 1) { /*non-interleaved*/ - slice_param->slice_horizontal_position = 0; - slice_param->slice_vertical_position = 0; - /* Y mcu numbers*/ - if (slice_param->components[0].component_selector == priv->frame_hdr.components[0].identifier) { - slice_param->num_mcus = (priv->frame_hdr.width/8)*(priv->frame_hdr.height/8); - } else { /*Cr, Cb mcu numbers*/ - slice_param->num_mcus = (priv->frame_hdr.width/16)*(priv->frame_hdr.height/16); + 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; } - } else { /* interleaved */ - slice_param->slice_horizontal_position = 0; - slice_param->slice_vertical_position = 0; - total_v_samples = get_max_vertical_samples(&priv->frame_hdr); - total_h_samples = get_max_horizontal_samples(&priv->frame_hdr); - slice_param->num_mcus = ((priv->frame_hdr.width + total_h_samples*8 - 1)/(total_h_samples*8)) * - ((priv->frame_hdr.height + total_v_samples*8 -1)/(total_v_samples*8)); + 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; From 008eac1b7214dac272f3b0ab5356d4d92b70f931 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Sep 2013 16:22:59 +0200 Subject: [PATCH 1339/3781] codecparsers: update to gst-vaapi-branch commit b33bd32. b33bd32 jpeg: fix and optimize scan for next marker code --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 23c7dde404..b33bd3214e 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 23c7dde4048c54c9af6ad1f2894a669cebcd1f1f +Subproject commit b33bd3214e9780d75719099a7e32fa59a286541e From d262d36623546b07a73c156462a1b3b4b920986a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Sep 2013 16:21:11 +0200 Subject: [PATCH 1340/3781] tests: simple-decoder: fix for non-X11 backends. Don't try to create pixmaps if we have not requested that feature. This fixes execution for non-X11 backends, and most specifically DRM video output mode. --- tests/simple-decoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index 5b50c87752..3c434d0646 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -498,7 +498,7 @@ renderer_process(App *app, RenderFrame *rfp) ensure_window_size(app, surface); crop_rect = gst_vaapi_surface_proxy_get_crop_rect(rfp->proxy); - if (!ensure_pixmaps(app, surface, crop_rect)) + if (g_use_pixmap && !ensure_pixmaps(app, surface, crop_rect)) SEND_ERROR("failed to create intermediate pixmaps"); if (!gst_vaapi_surface_sync(surface)) From f75762d910097f0fe4f730fad3dc9ff1d4985438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 21 May 2013 12:42:39 -0400 Subject: [PATCH 1341/3781] plugins: initial port to GStreamer 1.2. Port vaapidecode and vaapisink plugins to GStreamer API >= 1.2. This is rather minimalistic so that to test the basic functionality. Disable vaapipostproc plugin for now as further polishing is needed. Also disable GstVideoContext interface support since this API is now gone in 1.2.x. This is preparatory work for GstContext support. https://bugzilla.gnome.org/show_bug.cgi?id=703235 Signed-off-by: Gwenole Beauchesne --- configure.ac | 24 ++++++++++++++++++++++-- gst/vaapi/Makefile.am | 11 +++++++++-- gst/vaapi/gstvaapi.c | 2 ++ gst/vaapi/gstvaapidecode.c | 10 +++++++++- gst/vaapi/gstvaapipluginutil.c | 10 ++++++++++ gst/vaapi/gstvaapisink.c | 7 +++++++ gst/vaapi/gstvaapivideobuffer.c | 16 +++++++++++----- 7 files changed, 70 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 3ff07bd589..2767349081 100644 --- a/configure.ac +++ b/configure.ac @@ -27,6 +27,9 @@ m4_define([gst0_plugins_bad_version], [0.10.22]) m4_define([gst1_version], [1.0.0]) m4_define([gst1_plugins_base_version], [1.0.0]) m4_define([gst1_plugins_bad_version], [1.0.0]) +m4_define([gst12_version], [1.1.0]) +m4_define([gst12_plugins_base_version], [1.1.0]) +m4_define([gst12_plugins_bad_version], [1.1.0]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.0]) @@ -158,6 +161,11 @@ case $GST_API_VERSION in GST_PLUGINS_BASE_VERSION_REQUIRED=gst1_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst1_plugins_bad_version ;; +1.2) + GST_VERSION_REQUIRED=gst12_version + GST_PLUGINS_BASE_VERSION_REQUIRED=gst12_plugins_base_version + GST_PLUGINS_BAD_VERSION_REQUIRED=gst12_plugins_bad_version + ;; *) AC_MSG_ERROR([unsupported GStreamer API version $GST_API_VERSION]) ;; @@ -169,12 +177,22 @@ AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED) USE_GST_API_0_10="no" USE_GST_API_1_0p="no" +USE_GST_API_1_2p="no" AS_VERSION_COMPARE([$GST_API_VERSION], [0.10], [], [USE_GST_API_0_10="yes"], []) AS_VERSION_COMPARE([$GST_API_VERSION], [1.0], [], [USE_GST_API_1_0p="yes"], [USE_GST_API_1_0p="yes"]) +AS_VERSION_COMPARE([$GST_API_VERSION], [1.2], + [], [USE_GST_API_1_2p="yes"], [USE_GST_API_1_2p="yes"]) AM_CONDITIONAL([USE_GST_API_0_10], [test "$USE_GST_API_0_10" = "yes"]) AM_CONDITIONAL([USE_GST_API_1_0p], [test "$USE_GST_API_1_0p" = "yes"]) +AM_CONDITIONAL([USE_GST_API_1_2p], [test "$USE_GST_API_1_2p" = "yes"]) + +dnl XXX: GStreamer 1.2.x APIs don't have their own namespace yet +GST_API_VERSION_ORIG=$GST_API_VERSION +if test "$USE_GST_API_1_2p" = "yes"; then + GST_API_VERSION="1.0" +fi dnl GStreamer Core PKG_CHECK_MODULES([GST], @@ -288,9 +306,11 @@ AC_CACHE_CHECK([for GstVideoDecoder], AM_CONDITIONAL([USE_LOCAL_GST_VIDEO_DECODER], [test "$ac_cv_have_gst_video_decoder" != "yes"]) -dnl GStreamer -bad plugins +dnl GStreamer -bad plugins (deprecated in GStreamer v1.2) +if test "$USE_GST_API_1_2p" != "yes"; then PKG_CHECK_MODULES([GST_BASEVIDEO], [gstreamer-basevideo-$GST_API_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) +fi dnl ... bitstream parsers if test "$enable_builtin_codecparsers" = "yes"; then @@ -759,7 +779,7 @@ AS_IF([test $USE_WAYLAND -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS wayland"]) echo echo $PACKAGE configuration summary: echo -echo GStreamer API version ............ : $GST_API_VERSION +echo GStreamer API version ............ : $GST_API_VERSION_ORIG echo VA-API version ................... : $VA_VERSION_STR echo Video outputs .................... : $VIDEO_OUTPUTS echo diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 1b894670bb..f6fc130785 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -33,7 +33,6 @@ libgstvaapi_source_c = \ gstvaapi.c \ gstvaapidecode.c \ gstvaapipluginutil.c \ - gstvaapipostproc.c \ gstvaapisink.c \ gstvaapiuploader.c \ gstvaapivideobuffer.c \ @@ -43,28 +42,36 @@ libgstvaapi_source_c = \ libgstvaapi_source_h = \ gstvaapidecode.h \ gstvaapipluginutil.h \ - gstvaapipostproc.h \ gstvaapisink.h \ gstvaapiuploader.h \ gstvaapivideobuffer.h \ gstvaapivideometa.h \ $(NULL) +if !USE_GST_API_1_2p +libgstvaapi_source_c += gstvaapipostproc.c +libgstvaapi_source_h += gstvaapipostproc.h +endif + libgstvaapi_x11_source_c = gstvaapivideoconverter_x11.c libgstvaapi_x11_source_h = gstvaapivideoconverter_x11.h if USE_X11 +if !USE_GST_API_1_2p libgstvaapi_source_c += $(libgstvaapi_x11_source_c) libgstvaapi_source_h += $(libgstvaapi_x11_source_h) endif +endif libgstvaapi_glx_source_c = gstvaapivideoconverter_glx.c libgstvaapi_glx_source_h = gstvaapivideoconverter_glx.h if USE_GLX +if !USE_GST_API_1_2p libgstvaapi_source_c += $(libgstvaapi_glx_source_c) libgstvaapi_source_h += $(libgstvaapi_glx_source_h) endif +endif libgstvaapi_1_0p_source_c = \ gstvaapivideobufferpool.c \ diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 3000b2296f..7d12a668b1 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -47,9 +47,11 @@ plugin_init (GstPlugin *plugin) gst_element_register(plugin, "vaapidecode", GST_RANK_PRIMARY, GST_TYPE_VAAPIDECODE); +#if !GST_CHECK_VERSION(1,1,0) gst_element_register(plugin, "vaapipostproc", GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); +#endif gst_element_register(plugin, "vaapisink", GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 68cc58fee7..c35af825da 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -30,7 +30,9 @@ #include "gst/vaapi/sysdeps.h" #include +#if !GST_CHECK_VERSION(1,1,0) #include +#endif #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" @@ -102,6 +104,7 @@ gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface) #endif /* GstVideoContext interface */ +#if !GST_CHECK_VERSION(1,1,0) static void gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type, const GValue *value) @@ -117,6 +120,8 @@ gst_video_context_interface_init(GstVideoContextInterface *iface) } #define GstVideoContextClass GstVideoContextInterface +#endif + G_DEFINE_TYPE_WITH_CODE( GstVaapiDecode, gst_vaapidecode, @@ -125,8 +130,11 @@ G_DEFINE_TYPE_WITH_CODE( G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapidecode_implements_iface_init); #endif +#if !GST_CHECK_VERSION(1,1,0) G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init)) + gst_video_context_interface_init) +#endif + ) static gboolean gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ac48d01701..75210d5380 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -22,7 +22,9 @@ */ #include "gst/vaapi/sysdeps.h" +#if !GST_CHECK_VERSION(1,1,0) #include +#endif #if USE_DRM # include #endif @@ -117,9 +119,11 @@ gst_vaapi_ensure_display( ) { GstVaapiDisplay *display; +#if !GST_CHECK_VERSION(1,1,0) GstVideoContext *context; g_return_val_if_fail(GST_IS_VIDEO_CONTEXT(element), FALSE); +#endif g_return_val_if_fail(display_ptr != NULL, FALSE); /* Already exist ? */ @@ -127,10 +131,12 @@ gst_vaapi_ensure_display( if (display) return TRUE; +#if !GST_CHECK_VERSION(1,1,0) context = GST_VIDEO_CONTEXT(element); g_return_val_if_fail(context != NULL, FALSE); gst_video_context_prepare(context, display_types); +#endif /* Neighbour found and it updated the display */ if (*display_ptr) @@ -217,6 +223,9 @@ gst_vaapi_set_display( gboolean gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) { +#if GST_CHECK_VERSION(1,1,0) + return FALSE; +#else GstVaapiDisplayType display_type; const gchar **types; const gchar *type; @@ -305,6 +314,7 @@ gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) } } return res; +#endif /* !GST_CHECK_VERSION(1,1,0) */ } gboolean diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index ae39a516e5..6b405520ba 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -32,7 +32,10 @@ #include "gst/vaapi/sysdeps.h" #include #include +#if !GST_CHECK_VERSION(1,1,0) #include +#endif + #include #if USE_DRM # include @@ -119,6 +122,7 @@ gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface) #endif /* GstVideoContext interface */ +#if !GST_CHECK_VERSION(1,1,0) static void gst_vaapisink_set_video_context(GstVideoContext *context, const gchar *type, const GValue *value) @@ -132,6 +136,7 @@ gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface) { iface->set_context = gst_vaapisink_set_video_context; } +#endif static void gst_vaapisink_video_overlay_iface_init(GstVideoOverlayInterface *iface); @@ -144,8 +149,10 @@ G_DEFINE_TYPE_WITH_CODE( G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapisink_implements_iface_init); #endif +#if !GST_CHECK_VERSION(1,1,0) G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_vaapisink_video_context_iface_init); +#endif G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_OVERLAY, gst_vaapisink_video_overlay_iface_init)) diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 19926d30e7..40c11e8232 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -27,14 +27,20 @@ #include "gst/vaapi/sysdeps.h" #include "gstvaapivideobuffer.h" -#if USE_X11 +#if USE_X11 && !GST_CHECK_VERSION(1,1,0) # include "gstvaapivideoconverter_x11.h" #endif -#if USE_GLX +#if USE_GLX && !GST_CHECK_VERSION(1,1,0) # include "gstvaapivideoconverter_glx.h" #endif -#if GST_CHECK_VERSION(1,0,0) +#if GST_CHECK_VERSION(1,1,0) +static inline GstBuffer * +gst_surface_buffer_new(void) +{ + return gst_buffer_new(); +} +#elif GST_CHECK_VERSION(1,0,0) #include #define GST_VAAPI_SURFACE_META_CAST(obj) \ @@ -263,12 +269,12 @@ get_surface_converter(GstVaapiDisplay *display) GFunc func; switch (gst_vaapi_display_get_display_type(display)) { -#if USE_X11 +#if USE_X11 && !GST_CHECK_VERSION(1,1,0) case GST_VAAPI_DISPLAY_TYPE_X11: func = (GFunc)gst_vaapi_video_converter_x11_new; break; #endif -#if USE_GLX +#if USE_GLX && !GST_CHECK_VERSION(1,1,0) case GST_VAAPI_DISPLAY_TYPE_GLX: func = (GFunc)gst_vaapi_video_converter_glx_new; break; From c67b783275a3b9bad1a26d6895ae2a51dd218456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 22 May 2013 12:07:52 -0400 Subject: [PATCH 1342/3781] plugins: add compat layer for GstVideoContext. Add thin compatibility layer for the deprecated GstVideoContext API. For GStreamer API >= 1.2, this involves the following two functions: - gst_vaapi_video_context_prepare(): queries if a context is already set in the pipeline ; - gst_vaapi_video_context_propagate(): propagates the newly-created context to the rest of the pipeline. https://bugzilla.gnome.org/show_bug.cgi?id=703235 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapipluginutil.c | 12 +-- gst/vaapi/gstvaapivideocontext.c | 163 +++++++++++++++++++++++++++++++ gst/vaapi/gstvaapivideocontext.h | 75 ++++++++++++++ 4 files changed, 244 insertions(+), 8 deletions(-) create mode 100644 gst/vaapi/gstvaapivideocontext.c create mode 100644 gst/vaapi/gstvaapivideocontext.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index f6fc130785..e9fba8cd8a 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -36,6 +36,7 @@ libgstvaapi_source_c = \ gstvaapisink.c \ gstvaapiuploader.c \ gstvaapivideobuffer.c \ + gstvaapivideocontext.c \ gstvaapivideometa.c \ $(NULL) @@ -45,6 +46,7 @@ libgstvaapi_source_h = \ gstvaapisink.h \ gstvaapiuploader.h \ gstvaapivideobuffer.h \ + gstvaapivideocontext.h \ gstvaapivideometa.h \ $(NULL) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 75210d5380..43b1fc580c 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -22,9 +22,7 @@ */ #include "gst/vaapi/sysdeps.h" -#if !GST_CHECK_VERSION(1,1,0) -#include -#endif +#include "gstvaapivideocontext.h" #if USE_DRM # include #endif @@ -119,11 +117,9 @@ gst_vaapi_ensure_display( ) { GstVaapiDisplay *display; -#if !GST_CHECK_VERSION(1,1,0) GstVideoContext *context; g_return_val_if_fail(GST_IS_VIDEO_CONTEXT(element), FALSE); -#endif g_return_val_if_fail(display_ptr != NULL, FALSE); /* Already exist ? */ @@ -131,12 +127,10 @@ gst_vaapi_ensure_display( if (display) return TRUE; -#if !GST_CHECK_VERSION(1,1,0) context = GST_VIDEO_CONTEXT(element); g_return_val_if_fail(context != NULL, FALSE); - gst_video_context_prepare(context, display_types); -#endif + gst_vaapi_video_context_prepare(context, display_types); /* Neighbour found and it updated the display */ if (*display_ptr) @@ -147,6 +141,8 @@ gst_vaapi_ensure_display( if (display_ptr) *display_ptr = display; + + gst_vaapi_video_context_propagate(context, display); return display != NULL; } diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c new file mode 100644 index 0000000000..1331d4beac --- /dev/null +++ b/gst/vaapi/gstvaapivideocontext.c @@ -0,0 +1,163 @@ +/* + * gstvaapivideocontext.c - GStreamer/VA video context + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2013 Igalia + * + * 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 "gst/vaapi/sysdeps.h" +#include "gstvaapivideocontext.h" + +#if GST_CHECK_VERSION(1,1,0) + +GST_DEBUG_CATEGORY_STATIC(GST_CAT_CONTEXT); + +#define GST_VAAPI_TYPE_DISPLAY \ + gst_vaapi_display_get_type() + +GType +gst_vaapi_display_get_type(void) G_GNUC_CONST; + +G_DEFINE_BOXED_TYPE(GstVaapiDisplay, gst_vaapi_display, + (GBoxedCopyFunc)gst_vaapi_display_ref, + (GBoxedFreeFunc)gst_vaapi_display_unref) + +GstContext * +gst_vaapi_video_context_new_with_display(GstVaapiDisplay *display, + gboolean persistent) +{ + GstContext *context; + GstStructure *structure; + + context = gst_context_new(GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, persistent); + structure = gst_context_writable_structure(context); + gst_structure_set(structure, "display", GST_VAAPI_TYPE_DISPLAY, + display, NULL); + return context; +} + +gboolean +gst_vaapi_video_context_get_display(GstContext *context, + GstVaapiDisplay **display_ptr) +{ + const GstStructure *structure; + + g_return_val_if_fail(GST_IS_CONTEXT(context), FALSE); + g_return_val_if_fail(g_strcmp0(gst_context_get_context_type(context), + GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) == 0, FALSE); + + structure = gst_context_get_structure(context); + return gst_structure_get(structure, "display", GST_VAAPI_TYPE_DISPLAY, + display_ptr, NULL); +} + +static gboolean +context_pad_query(const GValue *item, GValue *value, gpointer user_data) +{ + GstPad * const pad = g_value_get_object(item); + GstQuery * const query = user_data; + + if (gst_pad_peer_query(pad, query)) { + g_value_set_boolean(value, TRUE); + return FALSE; + } + + GST_CAT_INFO_OBJECT(GST_CAT_CONTEXT, pad, "context pad peer query failed"); + return TRUE; +} + +static gboolean +run_context_query(GstElement *element, GstQuery *query) +{ + GstIteratorFoldFunction const func = context_pad_query; + GstIterator *it; + GValue res = { 0 }; + + g_value_init(&res, G_TYPE_BOOLEAN); + g_value_set_boolean(&res, FALSE); + + /* Ask downstream neighbour */ + it = gst_element_iterate_src_pads(element); + while (gst_iterator_fold(it, func, &res, query) == GST_ITERATOR_RESYNC) + gst_iterator_resync(it); + gst_iterator_free(it); + + /* Ignore upstream neighbours */ + return g_value_get_boolean(&res); +} + +void +gst_vaapi_video_context_prepare(GstElement *element, const gchar **types) +{ + GstContext *context; + GstQuery *query; + + if (!GST_CAT_CONTEXT) + GST_DEBUG_CATEGORY_GET(GST_CAT_CONTEXT, "GST_CONTEXT"); + + /* (2) Query downstream with GST_QUERY_CONTEXT for the context and + check if downstream already has a context of the specified type */ + context = NULL; + query = gst_query_new_context(GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); + if (run_context_query(element, query)) { + gst_query_parse_context(query, &context); + GST_CAT_INFO_OBJECT(GST_CAT_CONTEXT, element, + "found context (%p) in query", context); + gst_element_set_context(element, context); + } + else { + /* (3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with + the required context types and afterwards check if a usable + context was set now as in (1). The message could be handled + by the parent bins of the element and the application */ + GstMessage *msg; + + GST_CAT_INFO_OBJECT(GST_CAT_CONTEXT, element, + "posting `need-context' message"); + msg = gst_message_new_need_context(GST_OBJECT_CAST(element), + GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); + gst_element_post_message(element, msg); + } + gst_query_unref(query); +} + +/* (4) Create context by itself and post a GST_MESSAGE_HAVE_CONTEXT + message and send a GST_EVENT_CONTEXT event downstream, thus + containing the complete context information at this time */ +void +gst_vaapi_video_context_propagate(GstElement *element, GstVaapiDisplay *display) +{ + GstContext *context; + GstMessage *msg; + + if (!display) { + GST_ERROR_OBJECT(element, "failed to get VA-API display connection"); + return; + } + + context = gst_vaapi_video_context_new_with_display(display, FALSE); + + GST_CAT_INFO_OBJECT(GST_CAT_CONTEXT, element, + "posting `have-context' (%p) message with display (%p)", + context, display); + msg = gst_message_new_have_context(GST_OBJECT_CAST(element), context); + gst_element_post_message(GST_ELEMENT_CAST(element), msg); +} + +#endif diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h new file mode 100644 index 0000000000..3ef5849d55 --- /dev/null +++ b/gst/vaapi/gstvaapivideocontext.h @@ -0,0 +1,75 @@ +/* + * gstvaapivideocontext.h - GStreamer/VA video context + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2013 Igalia + * + * 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_VIDEO_CONTEXT_H +#define GST_VAAPI_VIDEO_CONTEXT_H + +#include + +#if GST_CHECK_VERSION(1,1,0) + +#define GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME "gst.vaapi.Display" + +/* Fake GstVideoContext symbols */ +#define GST_VIDEO_CONTEXT(obj) (GST_ELEMENT(obj)) +#define GST_IS_VIDEO_CONTEXT(obj) (GST_IS_ELEMENT(obj)) +#define GstVideoContext GstElement +#define gst_video_context_prepare gst_vaapi_video_context_prepare + +G_GNUC_INTERNAL +GstContext * +gst_vaapi_video_context_new_with_display(GstVaapiDisplay *display, + gboolean persistent); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_video_context_get_display(GstContext *context, + GstVaapiDisplay **display_ptr); + +G_GNUC_INTERNAL +void +gst_vaapi_video_context_prepare(GstElement *element, const gchar **types); + +G_GNUC_INTERNAL +void +gst_vaapi_video_context_propagate(GstElement *element, + GstVaapiDisplay *display); + +#else +#include + +static inline void +gst_vaapi_video_context_prepare(GstVideoContext *context, const gchar **types) +{ + gst_video_context_prepare(context, types); +} + +static inline void +gst_vaapi_video_context_propagate(GstVideoContext *context, + GstVaapiDisplay *display) +{ +} + +#endif + +#endif /* GST_VAAPI_VIDEO_CONTEXT_H */ From 9e3d24c6696256afca1c3f382125636e1c536253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 12 Jul 2013 12:58:57 -0400 Subject: [PATCH 1343/3781] plugins: add support for GstContext API. Add support for the new GstContext API from GStreamer 1.2.x. - implement the GstElement::set_context() hook ; - reply to the `context' query from downstream elements. https://bugzilla.gnome.org/show_bug.cgi?id=703235 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 40 ++++++++++++++++++++++++++++++--- gst/vaapi/gstvaapisink.c | 46 +++++++++++++++++++++++++++++++++++--- 2 files changed, 80 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index c35af825da..965bd42469 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -30,12 +30,10 @@ #include "gst/vaapi/sysdeps.h" #include -#if !GST_CHECK_VERSION(1,1,0) -#include -#endif #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" +#include "gstvaapivideocontext.h" #include "gstvaapivideobuffer.h" #if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" @@ -544,6 +542,20 @@ error_create_pool: } #endif +#if GST_CHECK_VERSION(1,1,0) +static void +gst_vaapidecode_set_context(GstElement *element, GstContext *context) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(element); + GstVaapiDisplay *display = NULL; + + if (gst_vaapi_video_context_get_display(context, &display)) { + GST_INFO_OBJECT(element, "set display %p", display); + gst_vaapi_display_replace(&decode->display, display); + } +} +#endif + static inline gboolean gst_vaapidecode_ensure_display(GstVaapiDecode *decode) { @@ -777,6 +789,10 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) GST_DEBUG_FUNCPTR(gst_vaapidecode_decide_allocation); #endif +#if GST_CHECK_VERSION(1,1,0) + element_class->set_context = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_context); +#endif + gst_element_class_set_static_metadata(element_class, "VA-API decoder", "Codec/Decoder/Video", @@ -880,6 +896,24 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) res = TRUE; break; } +#endif +#if GST_CHECK_VERSION(1,1,0) + case GST_QUERY_CONTEXT: { + const gchar *context_type = NULL; + + if (gst_query_parse_context_type(query, &context_type) && + !g_strcmp0(context_type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) && + decode->display) { + GstContext *context; + + context = gst_vaapi_video_context_new_with_display( + decode->display, FALSE); + gst_query_set_context(query, context); + gst_context_unref(context); + return TRUE; + } + // fall-through + } #endif default: res = GST_PAD_QUERY_FUNCTION_CALL(decode->sinkpad_query, diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 6b405520ba..9cbb008e1a 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -32,9 +32,6 @@ #include "gst/vaapi/sysdeps.h" #include #include -#if !GST_CHECK_VERSION(1,1,0) -#include -#endif #include #if USE_DRM @@ -72,6 +69,7 @@ #include "gstvaapisink.h" #include "gstvaapipluginutil.h" +#include "gstvaapivideocontext.h" #include "gstvaapivideometa.h" #if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" @@ -1330,6 +1328,20 @@ gst_vaapisink_buffer_alloc( } #endif +#if GST_CHECK_VERSION(1,1,0) +static void +gst_vaapisink_set_context(GstElement *element, GstContext *context) +{ + GstVaapiSink * const sink = GST_VAAPISINK(element); + GstVaapiDisplay *display = NULL; + + if (gst_vaapi_video_context_get_display(context, &display)) { + GST_INFO_OBJECT(element, "set display %p", display); + gst_vaapi_display_replace(&sink->display, display); + } +} +#endif + static gboolean gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query) { @@ -1339,6 +1351,30 @@ gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query) GST_DEBUG("sharing display %p", sink->display); return TRUE; } + + switch(GST_QUERY_TYPE(query)) { +#if GST_CHECK_VERSION(1,1,0) + case GST_QUERY_CONTEXT: { + const gchar *context_type = NULL; + + if (gst_query_parse_context_type(query, &context_type) && + !g_strcmp0(context_type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) && + sink->display) { + GstContext *context; + + context = gst_vaapi_video_context_new_with_display( + sink->display, FALSE); + gst_query_set_context(query, context); + gst_context_unref(context); + return TRUE; + } + // fall-through + } +#endif + default: + break; + } + return GST_BASE_SINK_CLASS(gst_vaapisink_parent_class)->query(base_sink, query); } @@ -1455,6 +1491,10 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; #endif +#if GST_CHECK_VERSION(1,1,0) + element_class->set_context = gst_vaapisink_set_context; +#endif + gst_element_class_set_static_metadata(element_class, "VA-API sink", "Sink/Video", From 21aa850eb45d744c3eaea9140d0f9f4089a0380d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 12 Jul 2013 12:58:57 -0400 Subject: [PATCH 1344/3781] plugins: improve ::query() debugging messages. Fix gst_vaapidecode_query() to correctly display the query type name, instead of randomly displaying that we shared the underlying display. Also add debug info for the GstVaapiSink::query() handler, i.e. the supplied query type name actually. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 6 ++++-- gst/vaapi/gstvaapisink.c | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 965bd42469..5aedcaef94 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -882,10 +882,12 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) GST_VAAPIDECODE(gst_pad_get_parent_element(pad)); gboolean res; - GST_DEBUG("sharing display %p", decode->display); + GST_INFO_OBJECT(decode, "query type %s", GST_QUERY_TYPE_NAME(query)); - if (gst_vaapi_reply_to_query(query, decode->display)) + if (gst_vaapi_reply_to_query(query, decode->display)) { + GST_DEBUG("sharing display %p", decode->display); res = TRUE; + } else if (GST_PAD_IS_SINK(pad)) { switch (GST_QUERY_TYPE(query)) { #if GST_CHECK_VERSION(1,0,0) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 9cbb008e1a..fdada0a8e5 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1347,6 +1347,8 @@ gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + GST_INFO_OBJECT(sink, "query type %s", GST_QUERY_TYPE_NAME(query)); + if (gst_vaapi_reply_to_query(query, sink->display)) { GST_DEBUG("sharing display %p", sink->display); return TRUE; From 8fe3bb0b14120738834000d3de3dfa842e692e24 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 4 Jul 2013 11:03:52 +0300 Subject: [PATCH 1345/3781] plugins: add support for GstCaps features. Move VA video buffer memory from "video/x-surface,type=vaapi" format, as expressed in caps, to the more standard use of caps features. i.e. add "memory:VASurface" feature attribute to the associated caps. https://bugzilla.gnome.org/show_bug.cgi?id=703271 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 9 +++++++++ gst/vaapi/gstvaapisink.c | 13 ++++++++++++- gst/vaapi/gstvaapivideomemory.h | 4 ++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 5aedcaef94..627e71b621 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -67,7 +67,12 @@ static const char gst_vaapidecode_sink_caps_str[] = ; static const char gst_vaapidecode_src_caps_str[] = +#if GST_CHECK_VERSION(1,1,0) + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VIDEO_FORMATS_ALL); +#else GST_VAAPI_SURFACE_CAPS; +#endif static GstStaticPadTemplate gst_vaapidecode_sink_factory = GST_STATIC_PAD_TEMPLATE( @@ -180,6 +185,9 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, } gst_video_codec_state_unref(state); +#if GST_CHECK_VERSION(1,1,0) + state->caps = gst_video_info_to_caps(&vis); +#else /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not reconstruct suitable caps for "encoded" video formats */ state->caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); @@ -200,6 +208,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, gst_caps_get_structure(state->caps, 0); gst_structure_set_interlaced(structure, TRUE); } +#endif gst_caps_replace(&decode->srcpad_caps, state->caps); return TRUE; } diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index fdada0a8e5..a85885df68 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -84,6 +84,10 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink); /* Default template */ static const char gst_vaapisink_sink_caps_str[] = +#if GST_CHECK_VERSION(1,1,0) + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VIDEO_FORMATS_ALL); +#else #if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) "; " #else @@ -92,6 +96,7 @@ static const char gst_vaapisink_sink_caps_str[] = "height = (int) [ 1, MAX ]; " #endif GST_VAAPI_SURFACE_CAPS; +#endif static GstStaticPadTemplate gst_vaapisink_sink_factory = GST_STATIC_PAD_TEMPLATE( @@ -719,14 +724,20 @@ gst_vaapisink_get_caps_impl(GstBaseSink *base_sink) GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstCaps *out_caps, *yuv_caps; +#if GST_CHECK_VERSION(1,1,0) + out_caps = gst_static_pad_template_get_caps(&gst_vaapisink_sink_factory); +#else out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS); +#endif if (!out_caps) return NULL; if (gst_vaapisink_ensure_uploader(sink)) { yuv_caps = gst_vaapi_uploader_get_caps(sink->uploader); - if (yuv_caps) + if (yuv_caps) { + out_caps = gst_caps_make_writable(out_caps); gst_caps_append(out_caps, gst_caps_copy(yuv_caps)); + } } return out_caps; } diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index a169930361..a82742b233 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -42,6 +42,10 @@ typedef struct _GstVaapiVideoAllocatorClass GstVaapiVideoAllocatorClass; #define GST_VAAPI_VIDEO_MEMORY_NAME "GstVaapiVideoMemory" +#if GST_CHECK_VERSION(1,1,0) +#define GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "memory:VASurface" +#endif + /** * GstVaapiVideoMemoryMapType: * @GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: map with gst_buffer_map() From 41c4da5571d471b96f37062f5669303f87bd629a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 Jul 2013 13:41:00 +0200 Subject: [PATCH 1346/3781] plugins: add support for GstVideoGLTextureUploadMeta. If the allocation meta GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE is requested, and more specifically under a GLX configuration, then add the GstVideoGLTextureUploadMeta to the output buffer. https://bugzilla.gnome.org/show_bug.cgi?id=703236 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/Makefile.am | 15 +++++ gst/vaapi/gstvaapidecode.c | 27 +++++++- gst/vaapi/gstvaapidecode.h | 1 + gst/vaapi/gstvaapisink.c | 5 +- gst/vaapi/gstvaapivideometa_texture.c | 92 +++++++++++++++++++++++++++ gst/vaapi/gstvaapivideometa_texture.h | 37 +++++++++++ 6 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 gst/vaapi/gstvaapivideometa_texture.c create mode 100644 gst/vaapi/gstvaapivideometa_texture.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index e9fba8cd8a..0b8a45e2e1 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -75,6 +75,19 @@ libgstvaapi_source_h += $(libgstvaapi_glx_source_h) endif endif +libgstvaapi_1_2p_source_c = \ + gstvaapivideometa_texture.c \ + $(NULL) + +libgstvaapi_1_2p_source_h = \ + gstvaapivideometa_texture.h \ + $(NULL) + +if USE_GST_API_1_2p +libgstvaapi_source_c += $(libgstvaapi_1_2p_source_c) +libgstvaapi_source_h += $(libgstvaapi_1_2p_source_h) +endif + libgstvaapi_1_0p_source_c = \ gstvaapivideobufferpool.c \ gstvaapivideomemory.c \ @@ -135,6 +148,8 @@ libgstvaapi_la_LIBTOOLFLAGS = --tag=disable-static EXTRA_DIST = \ $(libgstvaapi_glx_source_c) \ $(libgstvaapi_glx_source_h) \ + $(libgstvaapi_1_2p_source_c) \ + $(libgstvaapi_1_2p_source_h) \ $(libgstvaapi_1_0p_source_c) \ $(libgstvaapi_1_0p_source_h) \ $(libgstvaapi_0_10_source_c) \ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 627e71b621..597a3fba00 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -35,6 +35,9 @@ #include "gstvaapipluginutil.h" #include "gstvaapivideocontext.h" #include "gstvaapivideobuffer.h" +#if GST_CHECK_VERSION(1,1,0) +#include "gstvaapivideometa_texture.h" +#endif #if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" #include "gstvaapivideomemory.h" @@ -69,7 +72,10 @@ static const char gst_vaapidecode_sink_caps_str[] = static const char gst_vaapidecode_src_caps_str[] = #if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VIDEO_FORMATS_ALL); + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VIDEO_FORMATS_ALL) ";" + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, + GST_VIDEO_FORMATS_ALL); #else GST_VAAPI_SURFACE_CAPS; #endif @@ -343,6 +349,11 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec) crop_meta->height = crop_rect->height; } } + +#if GST_CHECK_VERSION(1,1,0) + if (decode->has_texture_upload_meta) + gst_buffer_add_texture_upload_meta(out_frame->output_buffer); +#endif #else out_frame->output_buffer = gst_vaapi_video_buffer_new_with_surface_proxy(proxy); @@ -529,6 +540,18 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gst_buffer_pool_set_config(pool, config); } + decode->has_texture_upload_meta = FALSE; + if (gst_query_find_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL)) { + config = gst_buffer_pool_get_config(pool); + gst_buffer_pool_config_add_option(config, + GST_BUFFER_POOL_OPTION_VIDEO_META); + gst_buffer_pool_set_config(pool, config); +#if GST_CHECK_VERSION(1,1,0) + decode->has_texture_upload_meta = gst_query_find_allocation_meta(query, + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); +#endif + } + if (update_pool) gst_query_set_nth_allocation_pool(query, 0, pool, size, min, max); else @@ -636,6 +659,8 @@ gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) { GstVaapiCodec codec; + decode->has_texture_upload_meta = FALSE; + /* Reset timers if hard reset was requested (e.g. seek) */ if (hard) { decode->render_time_base = 0; diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 23991cfea9..161937bb6b 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -79,6 +79,7 @@ struct _GstVaapiDecode { gint64 render_time_base; GstClockTime last_buffer_time; guint current_frame_size; + guint has_texture_upload_meta : 1; }; struct _GstVaapiDecodeClass { diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index a85885df68..b6ffca3661 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -86,7 +86,10 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink); static const char gst_vaapisink_sink_caps_str[] = #if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VIDEO_FORMATS_ALL); + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VIDEO_FORMATS_ALL) ";" + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, + GST_VIDEO_FORMATS_ALL); #else #if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) "; " diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c new file mode 100644 index 0000000000..17b19a0088 --- /dev/null +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -0,0 +1,92 @@ +/* + * gstvaapivideometa_texture.c - GStreamer/VA video meta (GLTextureUpload) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2013 Igalia + * + * 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 "gst/vaapi/sysdeps.h" +#include "gstvaapivideometa.h" +#include "gstvaapivideometa_texture.h" +#include "gstvaapipluginutil.h" + +#if GST_CHECK_VERSION(1,1,0) && USE_GLX +static void +gst_vaapi_texure_upload_free(gpointer data) +{ + GstVaapiTexture * const texture = data; + + if (texture) + gst_vaapi_texture_unref(texture); +} + +static gboolean +gst_vaapi_texture_upload(GstVideoGLTextureUploadMeta *meta, guint texture_id[4]) +{ + GstVaapiVideoMeta * const vmeta = + gst_buffer_get_vaapi_video_meta(meta->buffer); + GstVaapiTexture *texture = meta->user_data; + GstVaapiSurface * const surface = gst_vaapi_video_meta_get_surface(vmeta); + GstVaapiDisplay * const dpy = + gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); + + if (gst_vaapi_display_get_display_type(dpy) != GST_VAAPI_DISPLAY_TYPE_GLX) + return FALSE; + + if (texture) { + GstVaapiDisplay * const tex_dpy = + gst_vaapi_object_get_display(GST_VAAPI_OBJECT(texture)); + if (tex_dpy != dpy) + gst_vaapi_texture_replace(&texture, NULL); + } + + if (!texture) { + /* FIXME: should we assume target? */ + texture = gst_vaapi_texture_new_with_texture(dpy, texture_id[0], + GL_TEXTURE_2D, GL_RGBA); + meta->user_data = texture; + } + + if (!gst_vaapi_apply_composition(surface, meta->buffer)) + GST_WARNING("could not update subtitles"); + + return gst_vaapi_texture_put_surface(texture, surface, + gst_vaapi_video_meta_get_render_flags(vmeta)); +} +#endif + +#if GST_CHECK_VERSION(1,1,0) +gboolean +gst_buffer_add_texture_upload_meta(GstBuffer *buffer) +{ + GstVideoGLTextureUploadMeta *meta = NULL; + GstVideoGLTextureType tex_type[] = { GST_VIDEO_GL_TEXTURE_TYPE_RGBA }; + + if (!buffer) + return FALSE; + +#if USE_GLX + meta = gst_buffer_add_video_gl_texture_upload_meta(buffer, + GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, + 1, tex_type, gst_vaapi_texture_upload, + NULL, NULL, gst_vaapi_texure_upload_free); +#endif + return meta != NULL; +} +#endif diff --git a/gst/vaapi/gstvaapivideometa_texture.h b/gst/vaapi/gstvaapivideometa_texture.h new file mode 100644 index 0000000000..2f954344ca --- /dev/null +++ b/gst/vaapi/gstvaapivideometa_texture.h @@ -0,0 +1,37 @@ +/* + * gstvaapivideometa_texture.h - GStreamer/VA video meta (GLTextureUpload) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2013 Igalia + * + * 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_VIDEO_META_TEXTURE_H +#define GST_VAAPI_VIDEO_META_TEXTURE_H + +#include + +G_BEGIN_DECLS + +G_GNUC_INTERNAL +gboolean +gst_buffer_add_texture_upload_meta(GstBuffer *buffer); + +G_END_DECLS + +#endif /* GST_VAAPI_VIDEO_META_TEXTURE_H */ From 6b3c08a729874d6a72b7ac777468b21d2ec4be10 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Sep 2013 15:21:24 +0200 Subject: [PATCH 1347/3781] Fix detection and packaging of GStreamer 1.2.x builds. The GStreamer 1.2.x packages sticked to the naming convention for 1.0.x packages, i.e. -1.0 suffix. However, for gstreamer-vaapi packaging purposes, update the versioning to -1.2 suffix instead. --- configure.ac | 32 ++++++++++++++++++-------------- debian.upstream/control.in | 6 +++--- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/configure.ac b/configure.ac index 2767349081..f9029e3f95 100644 --- a/configure.ac +++ b/configure.ac @@ -13,6 +13,7 @@ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) m4_define([gst_vaapi_lt_current], [4]) m4_define([gst0_vaapi_lt_current_bias], [0]) m4_define([gst1_vaapi_lt_current_bias], [2]) +m4_define([gst2_vaapi_lt_current_bias], [4]) m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [0]) @@ -27,7 +28,7 @@ m4_define([gst0_plugins_bad_version], [0.10.22]) m4_define([gst1_version], [1.0.0]) m4_define([gst1_plugins_base_version], [1.0.0]) m4_define([gst1_plugins_bad_version], [1.0.0]) -m4_define([gst12_version], [1.1.0]) +m4_define([gst12_version], [1.1.90]) m4_define([gst12_plugins_base_version], [1.1.0]) m4_define([gst12_plugins_bad_version], [1.1.0]) @@ -188,17 +189,18 @@ AM_CONDITIONAL([USE_GST_API_0_10], [test "$USE_GST_API_0_10" = "yes"]) AM_CONDITIONAL([USE_GST_API_1_0p], [test "$USE_GST_API_1_0p" = "yes"]) AM_CONDITIONAL([USE_GST_API_1_2p], [test "$USE_GST_API_1_2p" = "yes"]) -dnl XXX: GStreamer 1.2.x APIs don't have their own namespace yet -GST_API_VERSION_ORIG=$GST_API_VERSION +dnl GStreamer 1.2.x APIs don't have their own namespace +GST_PKG_VERSION="$GST_API_VERSION" if test "$USE_GST_API_1_2p" = "yes"; then - GST_API_VERSION="1.0" + GST_PKG_VERSION="1.0" fi +AC_SUBST([GST_PKG_VERSION]) dnl GStreamer Core PKG_CHECK_MODULES([GST], - [gstreamer-$GST_API_VERSION >= $GST_VERSION_REQUIRED]) + [gstreamer-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) PKG_CHECK_MODULES([GST_BASE], - [gstreamer-base-$GST_API_VERSION >= $GST_VERSION_REQUIRED]) + [gstreamer-base-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) AC_CACHE_CHECK([for GstBaseSink::query hook], ac_cv_have_gst_base_sink_query, [ saved_CPPFLAGS="$CPPFLAGS" @@ -221,15 +223,15 @@ fi dnl GStreamer -base plugins PKG_CHECK_MODULES([GST_PLUGINS_BASE], - [gstreamer-plugins-base-$GST_API_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + [gstreamer-plugins-base-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) if test "$GST_API_VERSION" = "0.10"; then PKG_CHECK_MODULES([GST_INTERFACES], - [gstreamer-interfaces-$GST_API_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + [gstreamer-interfaces-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) fi dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], - [gstreamer-video-$GST_API_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + [gstreamer-video-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) AC_CACHE_CHECK([for GstVideoOverlayComposition], ac_cv_have_gst_video_overlay_composition, [ @@ -309,7 +311,7 @@ AM_CONDITIONAL([USE_LOCAL_GST_VIDEO_DECODER], dnl GStreamer -bad plugins (deprecated in GStreamer v1.2) if test "$USE_GST_API_1_2p" != "yes"; then PKG_CHECK_MODULES([GST_BASEVIDEO], - [gstreamer-basevideo-$GST_API_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) + [gstreamer-basevideo-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) fi dnl ... bitstream parsers @@ -319,7 +321,7 @@ if test "$enable_builtin_codecparsers" = "yes"; then ac_cv_have_gst_jpeg_parser="no" else PKG_CHECK_MODULES([GST_CODEC_PARSERS], - [gstreamer-codecparsers-$GST_API_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) + [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) fi dnl ... MPEG-2 parser, with the required extensions @@ -398,6 +400,7 @@ AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_JPEG], case $GST_API_VERSION in 0.10) lt_bias=gst0_vaapi_lt_current_bias;; 1.0) lt_bias=gst1_vaapi_lt_current_bias;; +1.2) lt_bias=gst2_vaapi_lt_current_bias;; esac GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - "$lt_bias"` AC_SUBST(GST_VAAPI_MAJOR_VERSION) @@ -430,13 +433,14 @@ AC_MSG_CHECKING([for GStreamer plugins directory]) case $GST_API_VERSION in 0.10) _gst_plugin_path="$GST_PLUGIN_PATH";; 1.0) _gst_plugin_path="$GST_PLUGIN_PATH_1_0";; +1.2) _gst_plugin_path="$GST_PLUGIN_PATH_1_0";; esac if test -d "$_gst_plugin_path"; then GST_PLUGINS_DIR="$_gst_plugin_path" else - GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_API_VERSION --variable pluginsdir` + GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_PKG_VERSION --variable pluginsdir` if test -z "$GST_PLUGINS_DIR"; then - GST_PLUGINS_DIR="\$(libdir)/gstreamer-$GST_API_VERSION" + GST_PLUGINS_DIR="\$(libdir)/gstreamer-$GST_PKG_VERSION" fi fi AC_MSG_RESULT([$GST_PLUGINS_DIR]) @@ -779,7 +783,7 @@ AS_IF([test $USE_WAYLAND -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS wayland"]) echo echo $PACKAGE configuration summary: echo -echo GStreamer API version ............ : $GST_API_VERSION_ORIG +echo GStreamer API version ............ : $GST_API_VERSION echo VA-API version ................... : $VA_VERSION_STR echo Video outputs .................... : $VIDEO_OUTPUTS echo diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 2ee622545c..9897e9d9da 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -5,9 +5,9 @@ Maintainer: Gwenole Beauchesne Build-Depends: debhelper (>= 5), cdbs, libglib2.0-dev (>= @GLIB_VERSION_REQUIRED@), - libgstreamer@GST_API_VERSION@-dev (>= @GST_VERSION_REQUIRED@), - libgstreamer-plugins-base@GST_API_VERSION@-dev (>= @GST_PLUGINS_BASE_VERSION_REQUIRED@), - libgstreamer-plugins-bad@GST_API_VERSION@-dev (>= @GST_PLUGINS_BAD_VERSION_REQUIRED@), + libgstreamer@GST_PKG_VERSION@-dev (>= @GST_VERSION_REQUIRED@), + libgstreamer-plugins-base@GST_PKG_VERSION@-dev (>= @GST_PLUGINS_BASE_VERSION_REQUIRED@), + libgstreamer-plugins-bad@GST_PKG_VERSION@-dev (>= @GST_PLUGINS_BAD_VERSION_REQUIRED@), @USE_DRM_TRUE@ libdrm-dev, libudev-dev, @USE_X11_TRUE@ libx11-dev, libxrandr-dev, @USE_GLX_TRUE@ libgl-dev, From b56144e9241ae826b5eae7c3a3e7454f75259e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 1 Oct 2013 12:09:44 +0200 Subject: [PATCH 1348/3781] plugins: query upstream element for a GstContext. Fix gst_vaapi_video_context_prepare() to also query upstream elements for a valid GstContext. Improve comments regarding the steps used to lookup or build that context, thus conforming to the GstContext API recommendations. https://bugzilla.gnome.org/show_bug.cgi?id=709112 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapivideocontext.c | 45 +++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 1331d4beac..c33cc635d0 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -98,7 +98,15 @@ run_context_query(GstElement *element, GstQuery *query) gst_iterator_resync(it); gst_iterator_free(it); - /* Ignore upstream neighbours */ + if (g_value_get_boolean(&res)) + return TRUE; + + /* If none, ask upstream neighbour (auto-plugged case) */ + it = gst_element_iterate_sink_pads(element); + while (gst_iterator_fold(it, func, &res, query) == GST_ITERATOR_RESYNC) + gst_iterator_resync(it); + gst_iterator_free(it); + return g_value_get_boolean(&res); } @@ -107,12 +115,23 @@ gst_vaapi_video_context_prepare(GstElement *element, const gchar **types) { GstContext *context; GstQuery *query; + GstMessage *msg; if (!GST_CAT_CONTEXT) GST_DEBUG_CATEGORY_GET(GST_CAT_CONTEXT, "GST_CONTEXT"); - /* (2) Query downstream with GST_QUERY_CONTEXT for the context and - check if downstream already has a context of the specified type */ + /* 1) Check if the element already has a context of the specific + * type, i.e. it was previously set via + * gst_element_set_context(). */ + /* This was already done by the caller of this function: + * gst_vaapi_ensure_display() */ + + /* 2) Query downstream with GST_QUERY_CONTEXT for the context and + check if downstream already has a context of the specific + type */ + /* 3) Query upstream with GST_QUERY_CONTEXT for the context and + check if upstream already has a context of the specific + type */ context = NULL; query = gst_query_new_context(GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); if (run_context_query(element, query)) { @@ -122,24 +141,26 @@ gst_vaapi_video_context_prepare(GstElement *element, const gchar **types) gst_element_set_context(element, context); } else { - /* (3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with - the required context types and afterwards check if a usable - context was set now as in (1). The message could be handled - by the parent bins of the element and the application */ - GstMessage *msg; - + /* 4) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with + the required context types and afterwards check if an + usable context was set now as in 1). The message could + be handled by the parent bins of the element and the + application. */ GST_CAT_INFO_OBJECT(GST_CAT_CONTEXT, element, "posting `need-context' message"); msg = gst_message_new_need_context(GST_OBJECT_CAST(element), GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); gst_element_post_message(element, msg); + + /* The check of an usable context is done by the caller: + gst_vaapi_ensure_display() */ } + gst_query_unref(query); } -/* (4) Create context by itself and post a GST_MESSAGE_HAVE_CONTEXT - message and send a GST_EVENT_CONTEXT event downstream, thus - containing the complete context information at this time */ +/* 5) Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT message + on the bus. */ void gst_vaapi_video_context_propagate(GstElement *element, GstVaapiDisplay *display) { From 395260f24bd8ab6e0f8464a6bffd39032c8bc03d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 1 Oct 2013 17:57:11 +0200 Subject: [PATCH 1349/3781] plugins: hanle the context query in any pad. Also this patch simplifies the code, since now the query is common for the decoder and the sink. https://bugzilla.gnome.org/show_bug.cgi?id=709200 --- gst/vaapi/gstvaapidecode.c | 18 ------------------ gst/vaapi/gstvaapipluginutil.c | 21 ++++++++++++++++++++- gst/vaapi/gstvaapisink.c | 23 ----------------------- 3 files changed, 20 insertions(+), 42 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 597a3fba00..2f17a3bf05 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -932,24 +932,6 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) res = TRUE; break; } -#endif -#if GST_CHECK_VERSION(1,1,0) - case GST_QUERY_CONTEXT: { - const gchar *context_type = NULL; - - if (gst_query_parse_context_type(query, &context_type) && - !g_strcmp0(context_type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) && - decode->display) { - GstContext *context; - - context = gst_vaapi_video_context_new_with_display( - decode->display, FALSE); - gst_query_set_context(query, context); - gst_context_unref(context); - return TRUE; - } - // fall-through - } #endif default: res = GST_PAD_QUERY_FUNCTION_CALL(decode->sinkpad_query, diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 43b1fc580c..ec1c99c9a1 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -220,7 +220,26 @@ gboolean gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) { #if GST_CHECK_VERSION(1,1,0) - return FALSE; + const gchar *type = NULL; + GstContext *context; + + if (GST_QUERY_TYPE(query) != GST_QUERY_CONTEXT) + return FALSE; + + if (!display) + return FALSE; + + if (!gst_query_parse_context_type(query, &type)) + return FALSE; + + if (g_strcmp0(type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME)) + return FALSE; + + context = gst_vaapi_video_context_new_with_display(display, FALSE); + gst_query_set_context(query, context); + gst_context_unref(context); + + return TRUE; #else GstVaapiDisplayType display_type; const gchar **types; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index b6ffca3661..c71c80af49 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1368,29 +1368,6 @@ gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query) return TRUE; } - switch(GST_QUERY_TYPE(query)) { -#if GST_CHECK_VERSION(1,1,0) - case GST_QUERY_CONTEXT: { - const gchar *context_type = NULL; - - if (gst_query_parse_context_type(query, &context_type) && - !g_strcmp0(context_type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) && - sink->display) { - GstContext *context; - - context = gst_vaapi_video_context_new_with_display( - sink->display, FALSE); - gst_query_set_context(query, context); - gst_context_unref(context); - return TRUE; - } - // fall-through - } -#endif - default: - break; - } - return GST_BASE_SINK_CLASS(gst_vaapisink_parent_class)->query(base_sink, query); } From 94b554e7a233cb1741ac586a169c132a32a4c006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 30 Sep 2013 17:08:12 +0200 Subject: [PATCH 1350/3781] filter: fix VA-API 0.34.0 symbol guards. VASurfaceAttrib and VAProcFilterParameterBufferType are symbols that need to be guarded for libva 0.34 and 0.33, respectively. https://bugzilla.gnome.org/show_bug.cgi?id=709102 Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapifilter.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index ef07eb4fc3..99f4686e9d 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -657,6 +657,7 @@ find_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) } /* Ensure the operation's VA buffer is allocated */ +#if USE_VA_VPP static inline gboolean op_ensure_buffer(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data) { @@ -666,6 +667,7 @@ op_ensure_buffer(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data) VAProcFilterParameterBufferType, op_data->va_buffer_size, NULL, &op_data->va_buffer, NULL); } +#endif /* Update a generic filter (float value) */ #if USE_VA_VPP @@ -822,6 +824,7 @@ op_set_deinterlace(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, static GArray * ensure_formats(GstVaapiFilter *filter) { +#if VA_CHECK_VERSION(0,34,0) VASurfaceAttrib *surface_attribs = NULL; guint i, num_surface_attribs = 0; VAStatus va_status; @@ -829,7 +832,6 @@ ensure_formats(GstVaapiFilter *filter) if (G_LIKELY(filter->formats)) return filter->formats; -#if VA_CHECK_VERSION(0,34,0) GST_VAAPI_DISPLAY_LOCK(filter->display); va_status = vaQuerySurfaceAttributes(filter->va_display, filter->va_config, NULL, &num_surface_attribs); @@ -868,13 +870,13 @@ ensure_formats(GstVaapiFilter *filter) continue; g_array_append_val(filter->formats, format); } -#endif g_free(surface_attribs); return filter->formats; error: g_free(surface_attribs); +#endif return NULL; } From 3e4d8d27b3f9ece1a6efe65a483d14973ccacc8d Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Wed, 4 Sep 2013 13:53:25 +0800 Subject: [PATCH 1351/3781] filter: fix colorbalance related subtypes. Fix intiialization of GstVaapiFilterOpData for colorbalance related operations. In particular, fill in the va_subtype field accordingly. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapifilter.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 99f4686e9d..2781607551 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -418,9 +418,17 @@ op_data_new(GstVaapiFilterOp op, GParamSpec *pspec) op_data->va_buffer_size = sizeof(VAProcFilterParameterBuffer); break; case GST_VAAPI_FILTER_OP_HUE: + op_data->va_subtype = VAProcColorBalanceHue; + goto op_colorbalance; case GST_VAAPI_FILTER_OP_SATURATION: + op_data->va_subtype = VAProcColorBalanceSaturation; + goto op_colorbalance; case GST_VAAPI_FILTER_OP_BRIGHTNESS: + op_data->va_subtype = VAProcColorBalanceBrightness; + goto op_colorbalance; case GST_VAAPI_FILTER_OP_CONTRAST: + op_data->va_subtype = VAProcColorBalanceContrast; + op_colorbalance: op_data->va_type = VAProcFilterColorBalance; op_data->va_cap_size = sizeof(VAProcFilterCapColorBalance); op_data->va_buffer_size = sizeof(VAProcFilterParameterBufferColorBalance); From e05e65e349b7fae4eca981e7ea6e5d529ea5c9de Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Wed, 4 Sep 2013 13:53:25 +0800 Subject: [PATCH 1352/3781] filter: fix first-time operation lookup. Fix first-time operation lookup through find_operation() if the set of supported operations was not initially determined through the gst_vaapi_filter_get_operations() helper function. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapifilter.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 2781607551..2afba0f99e 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -628,12 +628,14 @@ error: g_ptr_array_unref(default_ops); return NULL; } +#endif /* Determine the set of supported VPP operations by the specific filter, or known to this library if filter is NULL */ static GPtrArray * ensure_operations(GstVaapiFilter *filter) { +#if USE_VA_VPP GPtrArray *ops; if (filter && filter->operations) @@ -643,8 +645,9 @@ ensure_operations(GstVaapiFilter *filter) if (!ops) return NULL; return filter ? get_operations_ordered(filter, ops) : ops; -} #endif + return NULL; +} /* Find whether the VPP operation is supported or not */ GstVaapiFilterOpData * @@ -652,7 +655,7 @@ find_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) { guint i; - if (!filter->operations) + if (!ensure_operations(filter)) return NULL; for (i = 0; i < filter->operations->len; i++) { From b242c5874b62cbc67920cba17d2cb3e90c4cd222 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 1 Oct 2013 18:26:39 +0200 Subject: [PATCH 1353/3781] filter: fix memory leak of VPP operations. Fix ensure_operations() to release the VPP operations array if non NULL, prior to returning to the caller. The former function was also renamed to a more meaningful get_operations() since the caller owns the returned array that needs to be released. --- gst-libs/gst/vaapi/gstvaapifilter.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 2afba0f99e..e185f6ea24 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -633,7 +633,7 @@ error: /* Determine the set of supported VPP operations by the specific filter, or known to this library if filter is NULL */ static GPtrArray * -ensure_operations(GstVaapiFilter *filter) +get_operations(GstVaapiFilter *filter) { #if USE_VA_VPP GPtrArray *ops; @@ -649,6 +649,27 @@ ensure_operations(GstVaapiFilter *filter) return NULL; } +/* Ensure the set of supported VPP operations is cached into the + GstVaapiFilter::operations member */ +static inline gboolean +ensure_operations(GstVaapiFilter *filter) +{ + GPtrArray *ops; + + if (!filter) + return FALSE; + + if (filter->operations) + return TRUE; + + ops = get_operations(filter); + if (!ops) + return FALSE; + + g_ptr_array_unref(ops); + return TRUE; +} + /* Find whether the VPP operation is supported or not */ GstVaapiFilterOpData * find_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) @@ -1092,11 +1113,7 @@ gst_vaapi_filter_replace(GstVaapiFilter **old_filter_ptr, GPtrArray * gst_vaapi_filter_get_operations(GstVaapiFilter *filter) { -#if USE_VA_VPP - return ensure_operations(filter); -#else - return NULL; -#endif + return get_operations(filter); } /** From 393e86e3d0a8e8431e44979faffcb075a97b92ae Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 4 Oct 2013 19:30:36 +0200 Subject: [PATCH 1354/3781] plugins: add helper function to disable deinterlacing in caps. Add gst_caps_set_interlaced() helper function that would reset the interlace-mode field to "progressive" for GStreamer >= 1.0, or the interlaced field to "false" for GStreamer 0.10. --- gst/vaapi/gstvaapidecode.c | 6 +----- gst/vaapi/gstvaapipluginutil.c | 29 +++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 30 ++++-------------------------- gst/vaapi/gstvaapipostproc.c | 6 ++---- 4 files changed, 36 insertions(+), 35 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 2f17a3bf05..1b926f8594 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -209,11 +209,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, "pixel-aspect-ratio", GST_TYPE_FRACTION, vi->par_n, vi->par_d, NULL); - if (GST_VIDEO_INFO_IS_INTERLACED(vi)) { - GstStructure * const structure = - gst_caps_get_structure(state->caps, 0); - gst_structure_set_interlaced(structure, TRUE); - } + gst_caps_set_interlaced(state->caps, vi); #endif gst_caps_replace(&decode->srcpad_caps, state->caps); return TRUE; diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ec1c99c9a1..e30dce2c31 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -380,3 +380,32 @@ gst_vaapi_apply_composition(GstVaapiSurface *surface, GstBuffer *buffer) return gst_vaapi_surface_set_subpictures_from_composition(surface, composition, TRUE); } + +gboolean +gst_caps_set_interlaced(GstCaps *caps, GstVideoInfo *vip) +{ +#if GST_CHECK_VERSION(1,0,0) + GstVideoInterlaceMode mode; + const gchar *mode_str; + + mode = vip ? GST_VIDEO_INFO_INTERLACE_MODE(vip) : + GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; + switch (mode) { + case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE: + mode_str = "progressive"; + break; + case GST_VIDEO_INTERLACE_MODE_INTERLEAVED: + mode_str = "interleaved"; + break; + default: + GST_ERROR("unsupported `interlace-mode' %d", mode); + return FALSE; + } + + gst_caps_set_simple(caps, "interlace-mode", G_TYPE_STRING, mode_str, NULL); +#else + gst_caps_set_simple(caps, "interlaced", G_TYPE_BOOLEAN, + vip ? GST_VIDEO_INFO_IS_INTERLACED(vip) : FALSE, NULL); +#endif + return TRUE; +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 6212a9d648..a2838197ac 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -67,37 +67,15 @@ gst_vaapi_apply_composition(GstVaapiSurface *surface, GstBuffer *buffer); "interlace-mode = (string){ progressive, interleaved }" # define GST_CAPS_INTERLACED_FALSE \ "interlace-mode = (string)progressive" - -static inline void -gst_structure_remove_interlaced_field(GstStructure *structure) -{ - gst_structure_remove_field(structure, "interlace-mode"); -} - -static inline void -gst_structure_set_interlaced(GstStructure *structure, gboolean interlaced) -{ - gst_structure_set(structure, "interlace-mode", - G_TYPE_STRING, interlaced ? "interleaved" : "progressive", NULL); -} #else # define GST_CAPS_INTERLACED_MODES \ "interlaced = (boolean){ true, false }" # define GST_CAPS_INTERLACED_FALSE \ "interlaced = (boolean)false" - -static inline void -gst_structure_remove_interlaced_field(GstStructure *structure) -{ - gst_structure_remove_field(structure, "interlaced"); -} - -static inline void -gst_structure_set_interlaced(GstStructure *structure, gboolean interlaced) -{ - gst_structure_set(structure, "interlaced", - G_TYPE_BOOLEAN, interlaced, NULL); -} #endif +G_GNUC_INTERNAL +gboolean +gst_caps_set_interlaced(GstCaps *caps, GstVideoInfo *vip); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 2504fb6b10..ad082cbb29 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -376,9 +376,7 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps) gst_structure_set(structure, "type", G_TYPE_STRING, "vaapi", NULL); gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_GLX, NULL); - if (!postproc->deinterlace) - gst_structure_remove_interlaced_field(structure); - else { + if (postproc->deinterlace) { /* Set double framerate in interlaced mode */ if (!gst_util_fraction_multiply(postproc->fps_n, postproc->fps_d, 2, 1, @@ -387,8 +385,8 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps) gst_structure_set(structure, "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); - gst_structure_set_interlaced(structure, FALSE); } + gst_caps_set_interlaced(src_caps, NULL); return gst_pad_set_caps(postproc->srcpad, src_caps); } From cc9afca3edf74a821e337b46d6bf383eff0fcac0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 4 Oct 2013 19:34:32 +0200 Subject: [PATCH 1355/3781] plugins: create a proxy for GstVaapiUploader allocated buffers. Always make sure to allocate a VA surface proxy for GstVaapiUploader allocated buffers, i.e. make gst_vaapi_uploader_get_buffer() allocate a proxy surface. This fixes cases where we want to retain the underlying surface longer, instead of releasing it back to the surface pool right away. --- gst/vaapi/gstvaapiuploader.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index dc8f7a5878..b26caa06b3 100755 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -451,6 +451,7 @@ gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) GstVaapiUploaderPrivate *priv; GstVaapiImage *image; GstVaapiVideoMeta *meta; + GstVaapiSurfaceProxy *proxy; GstBuffer *buffer; g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), NULL); @@ -463,12 +464,17 @@ gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) goto error; } - meta = gst_buffer_get_vaapi_video_meta(buffer); - if (!gst_vaapi_video_meta_set_surface_from_pool(meta, priv->surfaces)) { + proxy = gst_vaapi_surface_proxy_new_from_pool( + GST_VAAPI_SURFACE_POOL(priv->surfaces)); + if (!proxy) { GST_WARNING("failed to allocate VA surface"); goto error; } + meta = gst_buffer_get_vaapi_video_meta(buffer); + gst_vaapi_video_meta_set_surface_proxy(meta, proxy); + gst_vaapi_surface_proxy_unref(proxy); + image = gst_vaapi_video_meta_get_image(meta); if (!gst_vaapi_image_map(image)) { GST_WARNING("failed to map VA image"); From 4df68163dcd5f58e7b7e9bf6909d61be1658f30c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 9 Oct 2013 09:33:56 +0200 Subject: [PATCH 1356/3781] plugins: fix GstVaapiVideoMemory to allocate VA surface proxies. Make sure GstVaapiVideoMemory allocates VA surface proxies from a pool stored in the parent VA memory allocator. This fixes the following scenario: - VA video buffer 1 is allocated from a buffer pool - Another video buffer is created, and inherits info from buffer 1 - Buffer 1 is released, thus pushing it back to the buffer pool - New buffer alloc request comes it, this yields buffer 1 back - At this stage, buffers 1 and 2 still share the same underlying VA surface, but buffer 2 was already submitted downstream for further processing, thus conflicting with additional processing we were about to perform on buffer 1. Maybe the core GstBufferPool implementation should have been fixed instead to actually make sure that the returned GstBuffer memory we found from the pool is writable? --- gst/vaapi/gstvaapivideomemory.c | 57 ++++++++++++++++++++++++++++----- gst/vaapi/gstvaapivideomemory.h | 2 ++ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 29bc2a9bba..e50d2f90c9 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -83,18 +83,32 @@ new_surface(GstVaapiDisplay *display, const GstVideoInfo *vip) GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); } +static GstVaapiSurfaceProxy * +new_surface_proxy(GstVaapiVideoMemory *mem) +{ + GstVaapiVideoAllocator * const allocator = + GST_VAAPI_VIDEO_ALLOCATOR_CAST(GST_MEMORY_CAST(mem)->allocator); + + return gst_vaapi_surface_proxy_new_from_pool( + GST_VAAPI_SURFACE_POOL(allocator->surface_pool)); +} + static gboolean ensure_surface(GstVaapiVideoMemory *mem) { - if (!mem->surface) { - GstVaapiDisplay * const display = - gst_vaapi_video_meta_get_display(mem->meta); + if (!mem->proxy) { + gst_vaapi_surface_proxy_replace(&mem->proxy, + gst_vaapi_video_meta_get_surface_proxy(mem->meta)); - mem->surface = new_surface(display, mem->surface_info); - if (!mem->surface) - return FALSE; + if (!mem->proxy) { + mem->proxy = new_surface_proxy(mem); + if (!mem->proxy) + return FALSE; + gst_vaapi_video_meta_set_surface_proxy(mem->meta, mem->proxy); + } + mem->surface = GST_VAAPI_SURFACE_PROXY_SURFACE(mem->proxy); } - gst_vaapi_video_meta_set_surface(mem->meta, mem->surface); + g_return_val_if_fail(mem->surface != NULL, FALSE); return TRUE; } @@ -236,7 +250,8 @@ gst_vaapi_video_memory_new(GstAllocator *base_allocator, static void gst_vaapi_video_memory_free(GstVaapiVideoMemory *mem) { - gst_vaapi_object_replace(&mem->surface, NULL); + mem->surface = NULL; + gst_vaapi_surface_proxy_replace(&mem->proxy, NULL); gst_vaapi_object_replace(&mem->image, NULL); gst_vaapi_video_meta_unref(mem->meta); gst_object_unref(GST_MEMORY_CAST(mem)->allocator); @@ -360,14 +375,27 @@ gst_vaapi_video_allocator_free(GstAllocator *allocator, GstMemory *mem) gst_vaapi_video_memory_free(GST_VAAPI_VIDEO_MEMORY_CAST(mem)); } +static void +gst_vaapi_video_allocator_finalize(GObject *object) +{ + GstVaapiVideoAllocator * const allocator = + GST_VAAPI_VIDEO_ALLOCATOR_CAST(object); + + gst_vaapi_video_pool_replace(&allocator->surface_pool, NULL); + + G_OBJECT_CLASS(gst_vaapi_video_allocator_parent_class)->finalize(object); +} + static void gst_vaapi_video_allocator_class_init(GstVaapiVideoAllocatorClass *klass) { + GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstAllocatorClass * const allocator_class = GST_ALLOCATOR_CLASS(klass); GST_DEBUG_CATEGORY_INIT(gst_debug_vaapivideomemory, "vaapivideomemory", 0, "VA-API video memory allocator"); + object_class->finalize = gst_vaapi_video_allocator_finalize; allocator_class->alloc = gst_vaapi_video_allocator_alloc; allocator_class->free = gst_vaapi_video_allocator_free; } @@ -478,6 +506,11 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) gst_vaapi_object_unref(image); } + allocator->surface_pool = gst_vaapi_surface_pool_new(display, + &allocator->surface_info); + if (!allocator->surface_pool) + goto error_create_pool; + allocator->image_info = *vip; if (GST_VIDEO_INFO_FORMAT(vip) == GST_VIDEO_FORMAT_ENCODED) gst_video_info_set_format(&allocator->image_info, GST_VIDEO_FORMAT_NV12, @@ -498,4 +531,12 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) gst_vaapi_object_unref(image); } return GST_ALLOCATOR_CAST(allocator); + + /* ERRORS */ +error_create_pool: + { + GST_ERROR("failed to allocate VA surface pool"); + gst_object_unref(allocator); + return NULL; + } } diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index a82742b233..c4bd5fdda1 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "gstvaapivideometa.h" G_BEGIN_DECLS @@ -126,6 +127,7 @@ struct _GstVaapiVideoAllocator { /*< private >*/ GstVideoInfo video_info; GstVideoInfo surface_info; + GstVaapiVideoPool *surface_pool; GstVideoInfo image_info; gboolean has_direct_rendering; }; From f361d4a23d38ae180cdfbcaea9abddc7dc74aeca Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 9 Oct 2013 09:47:18 +0200 Subject: [PATCH 1357/3781] plugins: fix buffer pool reset_buffer() to reset memory resources. Fix GstVaapiVideoBufferPool::reset_buffer() to reset the underlying memory resources, and more particularly the VA surface proxy. Most importantly, the GstVaapiVideoMeta is retained. Cached surface in memory are released, thus triggering a new allocation the next time we need to map the buffer. --- gst/vaapi/gstvaapivideobufferpool.c | 4 ++-- gst/vaapi/gstvaapivideomemory.c | 10 ++++++++++ gst/vaapi/gstvaapivideomemory.h | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index fdcc360eb1..d9612a6bbb 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -234,10 +234,10 @@ error_create_memory: static void gst_vaapi_video_buffer_pool_reset_buffer(GstBufferPool *pool, GstBuffer *buffer) { - GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); + GstMemory * const mem = gst_buffer_peek_memory(buffer, 0); /* Release the underlying surface proxy */ - gst_vaapi_video_meta_set_surface_proxy(meta, NULL); + gst_vaapi_video_memory_reset_surface(GST_VAAPI_VIDEO_MEMORY_CAST(mem)); GST_BUFFER_POOL_CLASS(gst_vaapi_video_buffer_pool_parent_class)-> reset_buffer(pool, buffer); diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index e50d2f90c9..319d2574d9 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -258,6 +258,16 @@ gst_vaapi_video_memory_free(GstVaapiVideoMemory *mem) g_slice_free(GstVaapiVideoMemory, mem); } +void +gst_vaapi_video_memory_reset_surface(GstVaapiVideoMemory *mem) +{ + mem->surface = NULL; + gst_vaapi_surface_proxy_replace(&mem->proxy, NULL); + if (mem->use_direct_rendering) + gst_vaapi_object_replace(&mem->image, NULL); + gst_vaapi_video_meta_set_surface_proxy(mem->meta, NULL); +} + static gpointer gst_vaapi_video_memory_map(GstVaapiVideoMemory *mem, gsize maxsize, guint flags) { diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index c4bd5fdda1..dac4458691 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -96,6 +96,10 @@ gboolean gst_video_meta_unmap_vaapi_memory(GstVideoMeta *meta, guint plane, GstMapInfo *info); +G_GNUC_INTERNAL +void +gst_vaapi_video_memory_reset_surface(GstVaapiVideoMemory *mem); + /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoAllocator --- */ /* ------------------------------------------------------------------------ */ From 847e3efb4dd6e29e90ba2897a5fd029f4d67cb50 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 9 Oct 2013 10:06:40 +0200 Subject: [PATCH 1358/3781] plugins: fix check for direct-rendering support. Fix check for direct-rendering if the creation of VA surfaces with an explicit pixel format is not support, e.g. VA-API < 0.34.0, and that we tried to allocate a VA surface based on the corresponding chroma type. i.e. in that particular case, we have to make sure that the derived image has actually the expected format. --- gst/vaapi/gstvaapivideomemory.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 319d2574d9..377ea40661 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -68,18 +68,23 @@ static GstVaapiSurface * new_surface(GstVaapiDisplay *display, const GstVideoInfo *vip) { GstVaapiSurface *surface; + GstVaapiChromaType chroma_type; /* Try with explicit format first */ - surface = gst_vaapi_surface_new_with_format(display, - GST_VIDEO_INFO_FORMAT(vip), GST_VIDEO_INFO_WIDTH(vip), - GST_VIDEO_INFO_HEIGHT(vip)); - if (surface) - return surface; + if (GST_VIDEO_INFO_FORMAT(vip) != GST_VIDEO_FORMAT_ENCODED) { + surface = gst_vaapi_surface_new_with_format(display, + GST_VIDEO_INFO_FORMAT(vip), GST_VIDEO_INFO_WIDTH(vip), + GST_VIDEO_INFO_HEIGHT(vip)); + if (surface) + return surface; + } - /* Try to pick something compatible. Best bet: NV12 (YUV 4:2:0) */ - if (GST_VIDEO_INFO_FORMAT(vip) != GST_VIDEO_FORMAT_NV12) + /* Try to pick something compatible, i.e. with same chroma type */ + chroma_type = gst_vaapi_video_format_get_chroma_type( + GST_VIDEO_INFO_FORMAT(vip)); + if (!chroma_type) return NULL; - return gst_vaapi_surface_new(display, GST_VAAPI_CHROMA_TYPE_YUV420, + return gst_vaapi_surface_new(display, chroma_type, GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); } @@ -501,6 +506,8 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) image = gst_vaapi_surface_derive_image(surface); if (!image) break; + if (GST_VAAPI_IMAGE_FORMAT(image) != GST_VIDEO_INFO_FORMAT(vip)) + break; if (!gst_vaapi_image_map(image)) break; allocator->has_direct_rendering = gst_video_info_update_from_image( From 77b2d884520f8d5de7f5d77545f2373da002fd30 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 9 Oct 2013 10:33:55 +0200 Subject: [PATCH 1359/3781] plugins: enable memory maps for read & write with direct-rendering. Enable read and write mappings only if direct-rendering is supported. Otherwise, this means that we may need to download data from the VA surface first for correctness, even if the VA surface doesn't need to be read at all. i.e. sometimes, READWRITE mappings are meant for surfaces that are written to first, and read afterwards for further processing. https://bugzilla.gnome.org/show_bug.cgi?id=704078 --- gst/vaapi/gstvaapivideomemory.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 377ea40661..25c4bbf255 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -132,8 +132,6 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, if (mem->map_type && mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR) goto error_incompatible_map; - if ((flags & GST_MAP_READWRITE) != GST_MAP_WRITE) - goto error_unsupported_map; /* Map for writing */ if (++mem->map_count == 1) { @@ -141,6 +139,12 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, goto error_ensure_surface; if (!ensure_image(mem)) goto error_ensure_image; + + // Check that we can actually map the surface, or image + if ((flags & GST_MAP_READWRITE) != GST_MAP_WRITE && + !mem->use_direct_rendering) + goto error_unsupported_map; + if (!gst_vaapi_image_map(mem->image)) goto error_map_image; mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR; From 399e887c4fd365d2a79a208a52c24157afee7ebc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 9 Oct 2013 17:25:10 +0200 Subject: [PATCH 1360/3781] plugins: fix and optimize check for buffer pool allocator params. Reset the buffer pool allocator only if the config caps changed in a sensible way: format or resolution change. i.e. don't bother with other caps like colorimetry et al. as this doesn't affect the way to allocate VA surfaces or images. --- gst/vaapi/gstvaapivideobufferpool.c | 32 +++++++++++++++++++++-------- gst/vaapi/gstvaapivideomemory.c | 10 +++------ gst/vaapi/gstvaapivideomemory.h | 3 ++- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index d9612a6bbb..c293ad1f28 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -38,7 +38,8 @@ enum { }; struct _GstVaapiVideoBufferPoolPrivate { - GstCaps *caps; + GstVideoInfo video_info[2]; + guint video_info_index; GstAllocator *allocator; GstVaapiDisplay *display; guint has_video_meta : 1; @@ -59,7 +60,6 @@ gst_vaapi_video_buffer_pool_finalize(GObject *object) gst_vaapi_display_replace(&priv->display, NULL); g_clear_object(&priv->allocator); - gst_caps_replace(&priv->caps, NULL); } static void @@ -114,18 +114,29 @@ gst_vaapi_video_buffer_pool_set_config(GstBufferPool *pool, GstVaapiVideoBufferPoolPrivate * const priv = GST_VAAPI_VIDEO_BUFFER_POOL(pool)->priv; GstCaps *caps = NULL; + GstVideoInfo * const cur_vip = &priv->video_info[priv->video_info_index]; + GstVideoInfo * const new_vip = &priv->video_info[!priv->video_info_index]; + GstAllocator *allocator; + gboolean changed_caps; if (!gst_buffer_pool_config_get_params(config, &caps, NULL, NULL, NULL)) goto error_invalid_config; - if (!caps) + if (!caps || !gst_video_info_from_caps(new_vip, caps)) goto error_no_caps; - if (!priv->caps || !gst_caps_is_equal(priv->caps, caps)) { - g_clear_object(&priv->allocator); - priv->allocator = gst_vaapi_video_allocator_new(priv->display, caps); - if (!priv->allocator) + changed_caps = !priv->allocator || + GST_VIDEO_INFO_FORMAT(cur_vip) != GST_VIDEO_INFO_FORMAT(new_vip) || + GST_VIDEO_INFO_WIDTH(cur_vip) != GST_VIDEO_INFO_WIDTH(new_vip) || + GST_VIDEO_INFO_HEIGHT(cur_vip) != GST_VIDEO_INFO_HEIGHT(new_vip); + + if (changed_caps) { + allocator = gst_vaapi_video_allocator_new(priv->display, new_vip); + if (!allocator) goto error_create_allocator; - gst_caps_replace(&priv->caps, caps); + gst_object_replace((GstObject **)&priv->allocator, + GST_OBJECT_CAST(allocator)); + gst_object_unref(allocator); + priv->video_info_index ^= 1; } if (!gst_buffer_pool_config_has_option(config, @@ -146,7 +157,7 @@ error_invalid_config: } error_no_caps: { - GST_ERROR("no caps in config"); + GST_ERROR("no valid caps in config"); return FALSE; } error_create_allocator: @@ -283,6 +294,9 @@ gst_vaapi_video_buffer_pool_init(GstVaapiVideoBufferPool *pool) GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(pool); pool->priv = priv; + + gst_video_info_init(&priv->video_info[0]); + gst_video_info_init(&priv->video_info[1]); } GstBufferPool * diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 25c4bbf255..5e9179e269 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -480,24 +480,20 @@ gst_video_info_update_from_image(GstVideoInfo *vip, GstVaapiImage *image) } GstAllocator * -gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps) +gst_vaapi_video_allocator_new(GstVaapiDisplay *display, const GstVideoInfo *vip) { GstVaapiVideoAllocator *allocator; - GstVideoInfo *vip; GstVaapiSurface *surface; GstVaapiImage *image; g_return_val_if_fail(display != NULL, NULL); - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + g_return_val_if_fail(vip != NULL, NULL); allocator = g_object_new(GST_VAAPI_TYPE_VIDEO_ALLOCATOR, NULL); if (!allocator) return NULL; - vip = &allocator->video_info; - gst_video_info_init(vip); - gst_video_info_from_caps(vip, caps); - + allocator->video_info = *vip; gst_video_info_set_format(&allocator->surface_info, GST_VIDEO_FORMAT_NV12, GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index dac4458691..72b34e391d 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -151,7 +151,8 @@ gst_vaapi_video_allocator_get_type(void) G_GNUC_CONST; G_GNUC_INTERNAL GstAllocator * -gst_vaapi_video_allocator_new(GstVaapiDisplay *display, GstCaps *caps); +gst_vaapi_video_allocator_new(GstVaapiDisplay *display, + const GstVideoInfo *vip); G_END_DECLS From f6f24bfc55953b556ea4b0b4b1475a2ca7a4f45c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Oct 2013 19:04:07 +0200 Subject: [PATCH 1361/3781] vaapipostproc: rework plug-in element. Rewrite the vaapipostproc plug-in element so that it derives from GstBaseTransform, thus simplifying the caps negotiation process. --- gst-libs/gst/vaapi/gstcompat.h | 18 + gst/vaapi/gstvaapipostproc.c | 561 ++++++++++++++++---------------- gst/vaapi/gstvaapipostproc.h | 22 +- gst/vaapi/gstvaapivideobuffer.c | 6 + gst/vaapi/gstvaapivideobuffer.h | 4 + 5 files changed, 310 insertions(+), 301 deletions(-) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index 4407648142..c3a8ff8d00 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -83,6 +83,11 @@ typedef enum { GST_MEMORY_FLAG_READONLY = GST_MINI_OBJECT_FLAG_READONLY } GstMemoryFlags; +typedef enum { + GST_BUFFER_COPY_META = GST_BUFFER_COPY_QDATA, + GST_BUFFER_COPY_MEMORY = 0, +} GstBufferCopyFlags1_0; + typedef enum { GST_MAP_READ = 1 << 0, GST_MAP_WRITE = 1 << 1 @@ -110,6 +115,9 @@ typedef struct { #undef gst_buffer_extract #define gst_buffer_extract(buffer, offset, dest, size) \ gst_compat_buffer_extract(buffer, offset, dest, size) +#undef gst_buffer_copy_into +#define gst_buffer_copy_into(dest, src, flags, offset, size) \ + gst_compat_buffer_copy_into(dest, src, flags, offset, size) static inline GstBuffer * gst_compat_buffer_new_wrapped_full(GstMemoryFlags flags, gpointer data, @@ -166,6 +174,16 @@ gst_compat_buffer_extract(GstBuffer *buffer, gsize offset, gpointer dest, return esize; } +static inline void +gst_compat_buffer_copy_into(GstBuffer *dest, GstBuffer *src, + GstBufferCopyFlags flags, gsize offset, gsize size) +{ + g_return_if_fail(offset == 0); + g_return_if_fail(size == (gsize)-1); + + gst_buffer_copy_metadata(dest, src, flags); +} + /* GstAdapter */ #include diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index ad082cbb29..c22e3b8899 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -106,7 +106,7 @@ gst_video_context_interface_init(GstVideoContextInterface *iface) G_DEFINE_TYPE_WITH_CODE( GstVaapiPostproc, gst_vaapipostproc, - GST_TYPE_ELEMENT, + GST_TYPE_BASE_TRANSFORM, #if !GST_CHECK_VERSION(1,0,0) G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapipostproc_implements_iface_init); @@ -149,12 +149,6 @@ gst_vaapi_deinterlace_mode_get_type(void) return deinterlace_mode_type; } -static inline GstVaapiPostproc * -get_vaapipostproc_from_pad(GstPad *pad) -{ - return GST_VAAPIPOSTPROC(gst_pad_get_parent_element(pad)); -} - static inline gboolean gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc) { @@ -163,111 +157,127 @@ gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc) } static gboolean -gst_vaapipostproc_create(GstVaapiPostproc *postproc, GstCaps *caps) +gst_vaapipostproc_create(GstVaapiPostproc *postproc) { if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; - - gst_caps_replace(&postproc->postproc_caps, caps); return TRUE; } static void gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) { - gst_caps_replace(&postproc->postproc_caps, NULL); - gst_vaapi_display_replace(&postproc->display, NULL); + + gst_caps_replace(&postproc->sinkpad_caps, NULL); + gst_caps_replace(&postproc->srcpad_caps, NULL); + gst_caps_replace(&postproc->allowed_caps, NULL); } static gboolean -gst_vaapipostproc_reset(GstVaapiPostproc *postproc, GstCaps *caps) +gst_vaapipostproc_reset(GstVaapiPostproc *postproc) { - if (postproc->postproc_caps && - gst_caps_is_always_compatible(caps, postproc->postproc_caps)) - return TRUE; - gst_vaapipostproc_destroy(postproc); - return gst_vaapipostproc_create(postproc, caps); + return gst_vaapipostproc_create(postproc); } static gboolean -gst_vaapipostproc_start(GstVaapiPostproc *postproc) +gst_vaapipostproc_start(GstBaseTransform *trans) { + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; return TRUE; } static gboolean -gst_vaapipostproc_stop(GstVaapiPostproc *postproc) +gst_vaapipostproc_stop(GstBaseTransform *trans) { + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + gst_vaapi_display_replace(&postproc->display, NULL); return TRUE; } -static GstFlowReturn -gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) +static GstBuffer * +create_output_buffer(GstVaapiPostproc *postproc) { + GstBuffer *outbuf; + + /* Create a raw VA video buffer without GstVaapiVideoMeta attached + to it yet, as this will be done next in the transform() hook */ + outbuf = gst_vaapi_video_buffer_new_empty(); + if (!outbuf) + goto error_create_buffer; + +#if !GST_CHECK_VERSION(1,0,0) + gst_buffer_set_caps(outbuf, postproc->srcpad_caps); +#endif + return outbuf; + + /* ERRORS */ +error_create_buffer: + { + GST_ERROR("failed to create output video buffer"); + return NULL; + } +} + +static inline void +append_output_buffer_metadata(GstBuffer *outbuf, GstBuffer *inbuf, guint flags) +{ + gst_buffer_copy_into(outbuf, inbuf, flags | + GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META | GST_BUFFER_COPY_MEMORY, + 0, -1); +} + +static GstFlowReturn +gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf, + GstBuffer *outbuf) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); GstVaapiVideoMeta *meta; - GstVaapiSurfaceProxy *proxy; GstClockTime timestamp; GstFlowReturn ret; - GstBuffer *outbuf; - guint outbuf_flags, flags; + GstBuffer *fieldbuf; + guint fieldbuf_flags, outbuf_flags, flags; gboolean tff; - meta = gst_buffer_get_vaapi_video_meta(buf); + meta = gst_buffer_get_vaapi_video_meta(inbuf); if (!meta) goto error_invalid_buffer; - /* Deinterlacing disabled, push frame */ - if (!postproc->deinterlace) { - outbuf = gst_buffer_ref(buf); - if (!outbuf) - goto error_create_buffer; - ret = gst_pad_push(postproc->srcpad, outbuf); - if (ret != GST_FLOW_OK) - goto error_push_buffer; - gst_buffer_unref(buf); - return GST_FLOW_OK; - } - - timestamp = GST_BUFFER_TIMESTAMP(buf); - proxy = gst_vaapi_video_meta_get_surface_proxy(meta); - tff = GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_FLAG_TFF); + timestamp = GST_BUFFER_TIMESTAMP(inbuf); + tff = GST_BUFFER_FLAG_IS_SET(inbuf, GST_VIDEO_BUFFER_FLAG_TFF); flags = gst_vaapi_video_meta_get_render_flags(meta) & ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); /* First field */ - outbuf = gst_vaapi_video_buffer_new_with_surface_proxy(proxy); - if (!outbuf) + fieldbuf = create_output_buffer(postproc); + if (!fieldbuf) goto error_create_buffer; + append_output_buffer_metadata(fieldbuf, inbuf, 0); - meta = gst_buffer_get_vaapi_video_meta(outbuf); - outbuf_flags = flags; - outbuf_flags |= postproc->deinterlace ? ( + meta = gst_buffer_get_vaapi_video_meta(fieldbuf); + fieldbuf_flags = flags; + fieldbuf_flags |= postproc->deinterlace ? ( tff ? GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) : GST_VAAPI_PICTURE_STRUCTURE_FRAME; - gst_vaapi_video_meta_set_render_flags(meta, outbuf_flags); + gst_vaapi_video_meta_set_render_flags(meta, fieldbuf_flags); - GST_BUFFER_TIMESTAMP(outbuf) = timestamp; - GST_BUFFER_DURATION(outbuf) = postproc->field_duration; -#if !GST_CHECK_VERSION(1,0,0) - gst_buffer_set_caps(outbuf, postproc->srcpad_caps); -#endif - ret = gst_pad_push(postproc->srcpad, outbuf); + GST_BUFFER_TIMESTAMP(fieldbuf) = timestamp; + GST_BUFFER_DURATION(fieldbuf) = postproc->field_duration; + ret = gst_pad_push(trans->srcpad, fieldbuf); if (ret != GST_FLOW_OK) goto error_push_buffer; /* Second field */ - outbuf = gst_vaapi_video_buffer_new_with_surface_proxy(proxy); - if (!outbuf) - goto error_create_buffer; + append_output_buffer_metadata(outbuf, inbuf, 0); meta = gst_buffer_get_vaapi_video_meta(outbuf); outbuf_flags = flags; @@ -280,118 +290,118 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf) GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration; GST_BUFFER_DURATION(outbuf) = postproc->field_duration; -#if !GST_CHECK_VERSION(1,0,0) - gst_buffer_set_caps(outbuf, postproc->srcpad_caps); -#endif - ret = gst_pad_push(postproc->srcpad, outbuf); - if (ret != GST_FLOW_OK) - goto error_push_buffer; - - gst_buffer_unref(buf); return GST_FLOW_OK; /* ERRORS */ error_invalid_buffer: { - GST_ERROR("failed to receive a valid video buffer"); - gst_buffer_unref(buf); - return GST_FLOW_EOS; + GST_ERROR("failed to validate source buffer"); + return GST_FLOW_ERROR; } error_create_buffer: { GST_ERROR("failed to create output buffer"); - gst_buffer_unref(buf); return GST_FLOW_EOS; } error_push_buffer: { if (ret != GST_FLOW_FLUSHING) GST_ERROR("failed to push output buffer to video sink"); - gst_buffer_unref(buf); return GST_FLOW_EOS; } } +static GstFlowReturn +gst_vaapipostproc_passthrough(GstBaseTransform *trans, GstBuffer *inbuf, + GstBuffer *outbuf) +{ + GstVaapiVideoMeta *meta; + + /* No video processing needed, simply copy buffer metadata */ + meta = gst_buffer_get_vaapi_video_meta(inbuf); + if (!meta) + goto error_invalid_buffer; + + append_output_buffer_metadata(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS); + return GST_FLOW_OK; + + /* ERRORS */ +error_invalid_buffer: + { + GST_ERROR("failed to validate source buffer"); + return GST_FLOW_ERROR; + } +} + static gboolean -gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps) +is_deinterlace_enabled(GstVaapiPostproc *postproc, GstVideoInfo *vip) +{ + gboolean deinterlace; + + switch (postproc->deinterlace_mode) { + case GST_VAAPI_DEINTERLACE_MODE_AUTO: + deinterlace = GST_VIDEO_INFO_IS_INTERLACED(vip); + break; + case GST_VAAPI_DEINTERLACE_MODE_INTERLACED: + deinterlace = TRUE; + break; + default: + deinterlace = FALSE; + break; + } + return deinterlace; +} + +static gboolean +video_info_changed(GstVideoInfo *old_vip, GstVideoInfo *new_vip) +{ + if (GST_VIDEO_INFO_FORMAT(old_vip) != GST_VIDEO_INFO_FORMAT(new_vip)) + return TRUE; + if (GST_VIDEO_INFO_INTERLACE_MODE(old_vip) != + GST_VIDEO_INFO_INTERLACE_MODE(new_vip)) + return TRUE; + if (GST_VIDEO_INFO_WIDTH(old_vip) != GST_VIDEO_INFO_WIDTH(new_vip)) + return TRUE; + if (GST_VIDEO_INFO_HEIGHT(old_vip) != GST_VIDEO_INFO_HEIGHT(new_vip)) + return TRUE; + return FALSE; +} + +static gboolean +gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps, + gboolean *caps_changed_ptr) { GstVideoInfo vi; if (!gst_video_info_from_caps(&vi, caps)) return FALSE; - postproc->fps_n = GST_VIDEO_INFO_FPS_N(&vi); - postproc->fps_d = GST_VIDEO_INFO_FPS_D(&vi); - switch (postproc->deinterlace_mode) { - case GST_VAAPI_DEINTERLACE_MODE_AUTO: - postproc->deinterlace = GST_VIDEO_INFO_IS_INTERLACED(&vi); - break; - case GST_VAAPI_DEINTERLACE_MODE_INTERLACED: - postproc->deinterlace = TRUE; - break; - case GST_VAAPI_DEINTERLACE_MODE_DISABLED: - postproc->deinterlace = FALSE; - break; - } + if (video_info_changed(&vi, &postproc->sinkpad_info)) + postproc->sinkpad_info = vi, *caps_changed_ptr = TRUE; + postproc->deinterlace = is_deinterlace_enabled(postproc, &vi); postproc->field_duration = gst_util_uint64_scale( - GST_SECOND, - postproc->fps_d, - (1 + postproc->deinterlace) * postproc->fps_n - ); - - gst_caps_replace(&postproc->sinkpad_caps, caps); + GST_SECOND, GST_VIDEO_INFO_FPS_D(&vi), + (1 + postproc->deinterlace) * GST_VIDEO_INFO_FPS_N(&vi)); return TRUE; } static gboolean -gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps) +gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps, + gboolean *caps_changed_ptr) { - GstCaps *src_caps; - GstStructure *structure; - const GValue *v_width, *v_height, *v_par; - gint fps_n, fps_d; + GstVideoInfo vi; - if (postproc->srcpad_caps) - src_caps = gst_caps_make_writable(postproc->srcpad_caps); - else - src_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); - if (!src_caps) + if (!gst_video_info_from_caps(&vi, caps)) return FALSE; - postproc->srcpad_caps = src_caps; - structure = gst_caps_get_structure(caps, 0); - v_width = gst_structure_get_value(structure, "width"); - v_height = gst_structure_get_value(structure, "height"); - v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); - - structure = gst_caps_get_structure(src_caps, 0); - if (v_width && v_height) { - gst_structure_set_value(structure, "width", v_width); - gst_structure_set_value(structure, "height", v_height); - } - if (v_par) - gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); - - gst_structure_set(structure, "type", G_TYPE_STRING, "vaapi", NULL); - gst_structure_set(structure, "opengl", G_TYPE_BOOLEAN, USE_GLX, NULL); - - if (postproc->deinterlace) { - /* Set double framerate in interlaced mode */ - if (!gst_util_fraction_multiply(postproc->fps_n, postproc->fps_d, - 2, 1, - &fps_n, &fps_d)) - return FALSE; - - gst_structure_set(structure, "framerate", - GST_TYPE_FRACTION, fps_n, fps_d, NULL); - } - gst_caps_set_interlaced(src_caps, NULL); - return gst_pad_set_caps(postproc->srcpad, src_caps); + if (video_info_changed(&vi, &postproc->srcpad_info)) + postproc->srcpad_info = vi, *caps_changed_ptr = TRUE; + return TRUE; } static gboolean -gst_vaapipostproc_ensure_allowed_caps(GstVaapiPostproc *postproc) +ensure_allowed_caps(GstVaapiPostproc *postproc) { if (postproc->allowed_caps) return TRUE; @@ -406,116 +416,161 @@ gst_vaapipostproc_ensure_allowed_caps(GstVaapiPostproc *postproc) } static GstCaps * -gst_vaapipostproc_get_caps(GstPad *pad) +gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, + GstPadDirection direction, GstCaps *caps) { - GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + GstVideoInfo vi; + GstVideoFormat format; GstCaps *out_caps; + gint fps_n, fps_d, par_n, par_d; - if (gst_vaapipostproc_ensure_allowed_caps(postproc)) - out_caps = gst_caps_ref(postproc->allowed_caps); - else - out_caps = gst_caps_new_empty(); + if (!gst_caps_is_fixed(caps)) { + if (direction == GST_PAD_SINK) + return gst_caps_from_string(gst_vaapipostproc_src_caps_str); - gst_object_unref(postproc); + /* Generate the allowed set of caps on the sink pad */ + if (!ensure_allowed_caps(postproc)) + return NULL; + return gst_caps_ref(postproc->allowed_caps); + } + + /* Generate the other pad caps, based on the current pad caps, as + specified by the direction argument */ + if (!gst_video_info_from_caps(&vi, caps)) + return NULL; + + format = GST_VIDEO_INFO_FORMAT(&vi); + if (format == GST_VIDEO_FORMAT_UNKNOWN) + return NULL; + + fps_n = GST_VIDEO_INFO_FPS_N(&vi); + fps_d = GST_VIDEO_INFO_FPS_D(&vi); + if (direction == GST_PAD_SINK) { + if (is_deinterlace_enabled(postproc, &vi)) { + /* Set double framerate in interlaced mode */ + if (!gst_util_fraction_multiply(fps_n, fps_d, 2, 1, &fps_n, &fps_d)) + return NULL; + + /* Signal the other pad that we generate only progressive frames */ + GST_VIDEO_INFO_INTERLACE_MODE(&vi) = + GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; + } + } + else { + if (is_deinterlace_enabled(postproc, &vi)) { + /* Set half framerate in interlaced mode */ + if (!gst_util_fraction_multiply(fps_n, fps_d, 1, 2, &fps_n, &fps_d)) + return NULL; + } + } + + /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not + reconstruct suitable caps for "encoded" video formats */ + out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); + if (!out_caps) + return NULL; + + par_n = GST_VIDEO_INFO_PAR_N(&vi); + par_d = GST_VIDEO_INFO_PAR_D(&vi); + gst_caps_set_simple(out_caps, + "type", G_TYPE_STRING, "vaapi", + "opengl", G_TYPE_BOOLEAN, USE_GLX, + "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH(&vi), + "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT(&vi), + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, + "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, + NULL); + + gst_caps_set_interlaced(out_caps, &vi); return out_caps; } -static gboolean -gst_vaapipostproc_set_caps(GstPad *pad, GstCaps *caps) +#if GST_CHECK_VERSION(1,0,0) +static GstCaps * +gst_vaapipostproc_transform_caps(GstBaseTransform *trans, + GstPadDirection direction, GstCaps *caps, GstCaps *filter) { - GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); - gboolean success = FALSE; + GstCaps *out_caps; - g_return_val_if_fail(pad == postproc->sinkpad, FALSE); - - do { - if (!gst_vaapipostproc_update_sink_caps(postproc, caps)) - break; - if (!gst_vaapipostproc_update_src_caps(postproc, caps)) - break; - if (!gst_vaapipostproc_reset(postproc, postproc->sinkpad_caps)) - break; - success = TRUE; - } while (0); - gst_object_unref(postproc); - return success; + caps = gst_vaapipostproc_transform_caps_impl(trans, direction, caps); + if (caps && filter) { + out_caps = gst_caps_intersect_full(caps, filter, + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref(caps); + return out_caps; + } + return caps; } +#else +#define gst_vaapipostproc_transform_caps \ + gst_vaapipostproc_transform_caps_impl +#endif static GstFlowReturn -gst_vaapipostproc_chain(GST_PAD_CHAIN_FUNCTION_ARGS) +gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf, + GstBuffer *outbuf) { - GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); GstFlowReturn ret; - ret = gst_vaapipostproc_process(postproc, buffer); - gst_object_unref(postproc); + if (postproc->deinterlace) + ret = gst_vaapipostproc_process(trans, inbuf, outbuf); + else + ret = gst_vaapipostproc_passthrough(trans, inbuf, outbuf); return ret; } -static gboolean -gst_vaapipostproc_sink_event(GST_PAD_EVENT_FUNCTION_ARGS) -{ - GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); - gboolean success; - - GST_DEBUG("handle sink event '%s'", GST_EVENT_TYPE_NAME(event)); - - switch (GST_EVENT_TYPE(event)) { -#if GST_CHECK_VERSION(1,0,0) - case GST_EVENT_CAPS: { - GstCaps *caps; - gst_event_parse_caps(event, &caps); - success = gst_vaapipostproc_set_caps(pad, caps); - break; - } +static GstFlowReturn +gst_vaapipostproc_prepare_output_buffer(GstBaseTransform *trans, + GstBuffer *inbuf, +#if !GST_CHECK_VERSION(1,0,0) + gint size, GstCaps *caps, #endif - default: - /* Propagate event downstream */ - success = gst_pad_push_event(postproc->srcpad, event); - break; - } - gst_object_unref(postproc); - return success; + GstBuffer **outbuf_ptr) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + + *outbuf_ptr = create_output_buffer(postproc); + return *outbuf_ptr ? GST_FLOW_OK : GST_FLOW_ERROR; } static gboolean -gst_vaapipostproc_src_event(GST_PAD_EVENT_FUNCTION_ARGS) +gst_vaapipostproc_set_caps(GstBaseTransform *trans, GstCaps *caps, + GstCaps *out_caps) { - GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); - gboolean success; + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + gboolean caps_changed = FALSE; - GST_DEBUG("handle src event '%s'", GST_EVENT_TYPE_NAME(event)); + if (!gst_vaapipostproc_update_sink_caps(postproc, caps, &caps_changed)) + return FALSE; + if (!gst_vaapipostproc_update_src_caps(postproc, out_caps, &caps_changed)) + return FALSE; - /* Propagate event upstream */ - success = gst_pad_push_event(postproc->sinkpad, event); - gst_object_unref(postproc); - return success; + if (caps_changed) { + if (!gst_vaapipostproc_reset(postproc)) + return FALSE; + gst_caps_replace(&postproc->sinkpad_caps, caps); + gst_caps_replace(&postproc->srcpad_caps, out_caps); + } + return TRUE; } static gboolean -gst_vaapipostproc_query(GST_PAD_QUERY_FUNCTION_ARGS) +gst_vaapipostproc_query(GstBaseTransform *trans, GstPadDirection direction, + GstQuery *query) { - GstVaapiPostproc * const postproc = get_vaapipostproc_from_pad(pad); - gboolean success; + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); - GST_DEBUG("sharing display %p", postproc->display); + GST_INFO_OBJECT(trans, "query type `%s'", GST_QUERY_TYPE_NAME(query)); - if (gst_vaapi_reply_to_query(query, postproc->display)) - success = TRUE; -#if GST_CHECK_VERSION(1,0,0) - else if (GST_PAD_IS_SINK(pad) && GST_QUERY_TYPE(query) == GST_QUERY_CAPS) { - GstCaps * const caps = gst_vaapipostproc_get_caps(pad); - gst_query_set_caps_result(query, caps); - gst_caps_unref(caps); - success = TRUE; + if (gst_vaapi_reply_to_query(query, postproc->display)) { + GST_DEBUG("sharing display %p", postproc->display); + return TRUE; } -#endif - else - success = GST_PAD_QUERY_FUNCTION_CALL(gst_pad_query_default, pad, - parent, query); - gst_object_unref(postproc); - return success; + return GST_BASE_TRANSFORM_CLASS(gst_vaapipostproc_parent_class)->query( + trans, direction, query); } static void @@ -525,10 +580,6 @@ gst_vaapipostproc_finalize(GObject *object) gst_vaapipostproc_destroy(postproc); - gst_caps_replace(&postproc->sinkpad_caps, NULL); - gst_caps_replace(&postproc->srcpad_caps, NULL); - gst_caps_replace(&postproc->allowed_caps, NULL); - G_OBJECT_CLASS(gst_vaapipostproc_parent_class)->finalize(object); } @@ -578,49 +629,12 @@ gst_vaapipostproc_get_property( } } -static GstStateChangeReturn -gst_vaapipostproc_change_state(GstElement *element, GstStateChange transition) -{ - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(element); - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - if (!gst_vaapipostproc_start(postproc)) - return GST_STATE_CHANGE_FAILURE; - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS(gst_vaapipostproc_parent_class)->change_state(element, transition); - if (ret != GST_STATE_CHANGE_SUCCESS) - return ret; - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_NULL: - if (!gst_vaapipostproc_stop(postproc)) - return GST_STATE_CHANGE_FAILURE; - break; - default: - break; - } - return GST_STATE_CHANGE_SUCCESS; -} - static void gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); + GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); GstPadTemplate *pad_template; GST_DEBUG_CATEGORY_INIT(gst_debug_vaapipostproc, @@ -629,8 +643,15 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) object_class->finalize = gst_vaapipostproc_finalize; object_class->set_property = gst_vaapipostproc_set_property; object_class->get_property = gst_vaapipostproc_get_property; + trans_class->start = gst_vaapipostproc_start; + trans_class->stop = gst_vaapipostproc_stop; + trans_class->transform_caps = gst_vaapipostproc_transform_caps; + trans_class->transform = gst_vaapipostproc_transform; + trans_class->set_caps = gst_vaapipostproc_set_caps; + trans_class->query = gst_vaapipostproc_query; - element_class->change_state = gst_vaapipostproc_change_state; + trans_class->prepare_output_buffer = + gst_vaapipostproc_prepare_output_buffer; gst_element_class_set_static_metadata(element_class, "VA-API video postprocessing", @@ -656,8 +677,8 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) g_object_class_install_property (object_class, PROP_DEINTERLACE_MODE, - g_param_spec_enum("deinterlace", - "Deinterlace", + g_param_spec_enum("deinterlace-mode", + "Deinterlace mode", "Deinterlace mode to use", GST_VAAPI_TYPE_DEINTERLACE_MODE, DEFAULT_DEINTERLACE_MODE, @@ -682,45 +703,11 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) static void gst_vaapipostproc_init(GstVaapiPostproc *postproc) { - GstVaapiPostprocClass *klass = GST_VAAPIPOSTPROC_GET_CLASS(postproc); - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - - postproc->allowed_caps = NULL; - postproc->postproc_caps = NULL; - postproc->display = NULL; - postproc->surface_width = 0; - postproc->surface_height = 0; postproc->deinterlace = FALSE; postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE; postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; postproc->field_duration = GST_CLOCK_TIME_NONE; - postproc->fps_n = 0; - postproc->fps_d = 0; - /* Pad through which data comes in to the element */ - postproc->sinkpad = gst_pad_new_from_template( - gst_element_class_get_pad_template(element_class, "sink"), - "sink" - ); - postproc->sinkpad_caps = NULL; - -#if !GST_CHECK_VERSION(1,0,0) - gst_pad_set_getcaps_function(postproc->sinkpad, gst_vaapipostproc_get_caps); - gst_pad_set_setcaps_function(postproc->sinkpad, gst_vaapipostproc_set_caps); -#endif - gst_pad_set_chain_function(postproc->sinkpad, gst_vaapipostproc_chain); - gst_pad_set_event_function(postproc->sinkpad, gst_vaapipostproc_sink_event); - gst_pad_set_query_function(postproc->sinkpad, gst_vaapipostproc_query); - gst_element_add_pad(GST_ELEMENT(postproc), postproc->sinkpad); - - /* Pad through which data goes out of the element */ - postproc->srcpad = gst_pad_new_from_template( - gst_element_class_get_pad_template(element_class, "src"), - "src" - ); - postproc->srcpad_caps = NULL; - - gst_pad_set_event_function(postproc->srcpad, gst_vaapipostproc_src_event); - gst_pad_set_query_function(postproc->srcpad, gst_vaapipostproc_query); - gst_element_add_pad(GST_ELEMENT(postproc), postproc->srcpad); + gst_video_info_init(&postproc->sinkpad_info); + gst_video_info_init(&postproc->srcpad_info); } diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index b33e724e32..480753c8d8 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -22,7 +22,7 @@ #ifndef GST_VAAPIPOSTPROC_H #define GST_VAAPIPOSTPROC_H -#include +#include #include #include #include @@ -71,31 +71,25 @@ typedef enum { struct _GstVaapiPostproc { /*< private >*/ - GstElement parent_instance; - - GstPad *sinkpad; - GstCaps *sinkpad_caps; - GstPad *srcpad; - GstCaps *srcpad_caps; - GstCaps *allowed_caps; - GstCaps *postproc_caps; + GstBaseTransform parent_instance; GstVaapiDisplay *display; - guint surface_width; - guint surface_height; + GstCaps *allowed_caps; + GstCaps *sinkpad_caps; + GstVideoInfo sinkpad_info; + GstCaps *srcpad_caps; + GstVideoInfo srcpad_info; /* Deinterlacing */ gboolean deinterlace; GstVaapiDeinterlaceMode deinterlace_mode; GstVaapiDeinterlaceMethod deinterlace_method; GstClockTime field_duration; - gint fps_n; - gint fps_d; }; struct _GstVaapiPostprocClass { /*< private >*/ - GstElementClass parent_class; + GstBaseTransformClass parent_class; }; GType diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 40c11e8232..e03dd69c9c 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -311,6 +311,12 @@ gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta) return new_vbuffer(gst_vaapi_video_meta_ref(meta)); } +GstBuffer * +gst_vaapi_video_buffer_new_empty(void) +{ + return gst_surface_buffer_new(); +} + GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) { diff --git a/gst/vaapi/gstvaapivideobuffer.h b/gst/vaapi/gstvaapivideobuffer.h index f4457ab606..d172f449a0 100644 --- a/gst/vaapi/gstvaapivideobuffer.h +++ b/gst/vaapi/gstvaapivideobuffer.h @@ -33,6 +33,10 @@ G_GNUC_INTERNAL GstBuffer * gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta); +G_GNUC_INTERNAL +GstBuffer * +gst_vaapi_video_buffer_new_empty(void); + G_GNUC_INTERNAL GstBuffer * gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); From f0d50cfbc25d1e611763e870b359690ce683bb3e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 4 Oct 2013 16:00:56 +0200 Subject: [PATCH 1362/3781] vaapipostproc: add support for "mixed" interlace mode. Add support for "mixed" interlace-mode, whereby the video frame buffer shall be deinterlaced only if its flags mention that's actually an interlaced frame buffer. --- gst/vaapi/gstvaapipluginutil.c | 3 +++ gst/vaapi/gstvaapipluginutil.h | 2 +- gst/vaapi/gstvaapipostproc.c | 29 ++++++++++++++++++++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index e30dce2c31..a0b78c9449 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -397,6 +397,9 @@ gst_caps_set_interlaced(GstCaps *caps, GstVideoInfo *vip) case GST_VIDEO_INTERLACE_MODE_INTERLEAVED: mode_str = "interleaved"; break; + case GST_VIDEO_INTERLACE_MODE_MIXED: + mode_str = "mixed"; + break; default: GST_ERROR("unsupported `interlace-mode' %d", mode); return FALSE; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index a2838197ac..306ab4a5ce 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -64,7 +64,7 @@ gst_vaapi_apply_composition(GstVaapiSurface *surface, GstBuffer *buffer); /* Helpers to handle interlaced contents */ #if GST_CHECK_VERSION(1,0,0) # define GST_CAPS_INTERLACED_MODES \ - "interlace-mode = (string){ progressive, interleaved }" + "interlace-mode = (string){ progressive, interleaved, mixed }" # define GST_CAPS_INTERLACED_FALSE \ "interlace-mode = (string)progressive" #else diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index c22e3b8899..7b35043313 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -200,6 +200,28 @@ gst_vaapipostproc_stop(GstBaseTransform *trans) return TRUE; } +static gboolean +is_interlaced_buffer(GstVaapiPostproc *postproc, GstBuffer *buf) +{ + if (!postproc->deinterlace) + return FALSE; + + switch (GST_VIDEO_INFO_INTERLACE_MODE(&postproc->sinkpad_info)) { + case GST_VIDEO_INTERLACE_MODE_MIXED: +#if GST_CHECK_VERSION(1,0,0) + if (!GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_FLAG_INTERLACED)) + return FALSE; +#else + if (GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_PROGRESSIVE)) + return FALSE; +#endif + break; + default: + break; + } + return TRUE; +} + static GstBuffer * create_output_buffer(GstVaapiPostproc *postproc) { @@ -242,7 +264,7 @@ gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf, GstFlowReturn ret; GstBuffer *fieldbuf; guint fieldbuf_flags, outbuf_flags, flags; - gboolean tff; + gboolean tff, deint; meta = gst_buffer_get_vaapi_video_meta(inbuf); if (!meta) @@ -250,6 +272,7 @@ gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf, timestamp = GST_BUFFER_TIMESTAMP(inbuf); tff = GST_BUFFER_FLAG_IS_SET(inbuf, GST_VIDEO_BUFFER_FLAG_TFF); + deint = is_interlaced_buffer(postproc, inbuf); flags = gst_vaapi_video_meta_get_render_flags(meta) & ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| @@ -263,7 +286,7 @@ gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf, meta = gst_buffer_get_vaapi_video_meta(fieldbuf); fieldbuf_flags = flags; - fieldbuf_flags |= postproc->deinterlace ? ( + fieldbuf_flags |= deint ? ( tff ? GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) : @@ -281,7 +304,7 @@ gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf, meta = gst_buffer_get_vaapi_video_meta(outbuf); outbuf_flags = flags; - outbuf_flags |= postproc->deinterlace ? ( + outbuf_flags |= deint ? ( tff ? GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD : GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) : From ae5e5be80b9da5c39b55a646728ca89f2b767f13 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 4 Oct 2013 15:37:24 +0200 Subject: [PATCH 1363/3781] vaapipostproc: add support for raw YUV video source buffers. Allow video processing from raw YUV buffers coming from the sink pad, while still producing a VA surface for the downstream elements. --- gst/vaapi/gstvaapipostproc.c | 325 +++++++++++++++++++++++++++++++---- gst/vaapi/gstvaapipostproc.h | 8 + 2 files changed, 304 insertions(+), 29 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 7b35043313..6e99cb6e52 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -35,6 +35,10 @@ #include "gstvaapipostproc.h" #include "gstvaapipluginutil.h" #include "gstvaapivideobuffer.h" +#if GST_CHECK_VERSION(1,0,0) +#include "gstvaapivideobufferpool.h" +#include "gstvaapivideomemory.h" +#endif #define GST_PLUGIN_NAME "vaapipostproc" #define GST_PLUGIN_DESC "A video postprocessing filter" @@ -45,6 +49,15 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapipostproc); /* Default templates */ static const char gst_vaapipostproc_sink_caps_str[] = GST_VAAPI_SURFACE_CAPS ", " + GST_CAPS_INTERLACED_MODES "; " +#if GST_CHECK_VERSION(1,0,0) + GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) ", " +#else + "video/x-raw-yuv, " + "width = " GST_VIDEO_SIZE_RANGE ", " + "height = " GST_VIDEO_SIZE_RANGE ", " + "framerate = " GST_VIDEO_FPS_RANGE ", " +#endif GST_CAPS_INTERLACED_MODES; static const char gst_vaapipostproc_src_caps_str[] = @@ -94,6 +107,9 @@ gst_vaapipostproc_set_video_context( GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(context); gst_vaapi_set_display(type, value, &postproc->display); + + if (postproc->uploader) + gst_vaapi_uploader_ensure_display(postproc->uploader, postproc->display); } static void @@ -156,17 +172,54 @@ gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc) &postproc->display); } +static gboolean +gst_vaapipostproc_ensure_uploader(GstVaapiPostproc *postproc) +{ + if (!gst_vaapipostproc_ensure_display(postproc)) + return FALSE; + + if (!postproc->uploader) { + postproc->uploader = gst_vaapi_uploader_new(postproc->display); + if (!postproc->uploader) + return FALSE; + } + + if (!gst_vaapi_uploader_ensure_display(postproc->uploader, + postproc->display)) + return FALSE; + return TRUE; +} + +static gboolean +gst_vaapipostproc_ensure_uploader_caps(GstVaapiPostproc *postproc) +{ +#if !GST_CHECK_VERSION(1,0,0) + if (postproc->is_raw_yuv && !gst_vaapi_uploader_ensure_caps( + postproc->uploader, postproc->sinkpad_caps, NULL)) + return FALSE; +#endif + return TRUE; +} + static gboolean gst_vaapipostproc_create(GstVaapiPostproc *postproc) { if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; + if (!gst_vaapipostproc_ensure_uploader(postproc)) + return FALSE; + if (!gst_vaapipostproc_ensure_uploader_caps(postproc)) + return FALSE; return TRUE; } static void gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) { +#if GST_CHECK_VERSION(1,0,0) + g_clear_object(&postproc->sinkpad_buffer_pool); +#endif + g_clear_object(&postproc->uploader); gst_vaapi_display_replace(&postproc->display, NULL); gst_caps_replace(&postproc->sinkpad_caps, NULL); @@ -174,13 +227,6 @@ gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) gst_caps_replace(&postproc->allowed_caps, NULL); } -static gboolean -gst_vaapipostproc_reset(GstVaapiPostproc *postproc) -{ - gst_vaapipostproc_destroy(postproc); - return gst_vaapipostproc_create(postproc); -} - static gboolean gst_vaapipostproc_start(GstBaseTransform *trans) { @@ -406,6 +452,18 @@ gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps, postproc->field_duration = gst_util_uint64_scale( GST_SECOND, GST_VIDEO_INFO_FPS_D(&vi), (1 + postproc->deinterlace) * GST_VIDEO_INFO_FPS_N(&vi)); + + postproc->is_raw_yuv = GST_VIDEO_INFO_IS_YUV(&vi); +#if !GST_CHECK_VERSION(1,0,0) + if (postproc->is_raw_yuv) { + /* Ensure the uploader is set up for upstream allocated buffers */ + GstVaapiUploader * const uploader = postproc->uploader; + if (!gst_vaapi_uploader_ensure_display(uploader, postproc->display)) + return FALSE; + if (!gst_vaapi_uploader_ensure_caps(uploader, caps, NULL)) + return FALSE; + } +#endif return TRUE; } @@ -426,13 +484,28 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps, static gboolean ensure_allowed_caps(GstVaapiPostproc *postproc) { + GstCaps *out_caps, *yuv_caps; + if (postproc->allowed_caps) return TRUE; - postproc->allowed_caps = - gst_caps_from_string(gst_vaapipostproc_sink_caps_str); - if (!postproc->allowed_caps) + /* Create VA caps */ + out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS ", " + GST_CAPS_INTERLACED_MODES); + if (!out_caps) { + GST_ERROR("failed to create VA sink caps"); return FALSE; + } + + /* Append YUV caps */ + if (gst_vaapipostproc_ensure_uploader(postproc)) { + yuv_caps = gst_vaapi_uploader_get_caps(postproc->uploader); + if (yuv_caps) + gst_caps_append(out_caps, gst_caps_ref(yuv_caps)); + else + GST_WARNING("failed to create YUV sink caps"); + } + postproc->allowed_caps = out_caps; /* XXX: append VA/VPP filters */ return TRUE; @@ -479,6 +552,7 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, GST_VIDEO_INFO_INTERLACE_MODE(&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; } + format = GST_VIDEO_FORMAT_ENCODED; } else { if (is_deinterlace_enabled(postproc, &vi)) { @@ -488,22 +562,29 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, } } - /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not - reconstruct suitable caps for "encoded" video formats */ - out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); - if (!out_caps) - return NULL; + if (format != GST_VIDEO_FORMAT_ENCODED) { + out_caps = gst_video_info_to_caps(&vi); + if (!out_caps) + return NULL; + } + else { + /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not + reconstruct suitable caps for "encoded" video formats */ + out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); + if (!out_caps) + return NULL; - par_n = GST_VIDEO_INFO_PAR_N(&vi); - par_d = GST_VIDEO_INFO_PAR_D(&vi); - gst_caps_set_simple(out_caps, - "type", G_TYPE_STRING, "vaapi", - "opengl", G_TYPE_BOOLEAN, USE_GLX, - "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH(&vi), - "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT(&vi), - "framerate", GST_TYPE_FRACTION, fps_n, fps_d, - "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, - NULL); + par_n = GST_VIDEO_INFO_PAR_N(&vi); + par_d = GST_VIDEO_INFO_PAR_D(&vi); + gst_caps_set_simple(out_caps, + "type", G_TYPE_STRING, "vaapi", + "opengl", G_TYPE_BOOLEAN, USE_GLX, + "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH(&vi), + "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT(&vi), + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, + "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, + NULL); + } gst_caps_set_interlaced(out_caps, &vi); return out_caps; @@ -530,17 +611,85 @@ gst_vaapipostproc_transform_caps(GstBaseTransform *trans, gst_vaapipostproc_transform_caps_impl #endif +static gboolean +gst_vaapipostproc_transform_size(GstBaseTransform *trans, + GstPadDirection direction, GstCaps *caps, gsize size, + GstCaps *othercaps, gsize *othersize) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + + if (direction == GST_PAD_SINK || !postproc->is_raw_yuv) + *othersize = 0; + else + *othersize = size; + return TRUE; +} + +static GstBuffer * +get_source_buffer(GstVaapiPostproc *postproc, GstBuffer *inbuf) +{ + GstVaapiVideoMeta *meta; + GstBuffer *outbuf; + + meta = gst_buffer_get_vaapi_video_meta(inbuf); + if (meta) + return gst_buffer_ref(inbuf); + +#if GST_CHECK_VERSION(1,0,0) + outbuf = NULL; + goto error_invalid_buffer; + return outbuf; + + /* ERRORS */ +error_invalid_buffer: + { + GST_ERROR("failed to validate source buffer"); + return NULL; + } +#else + outbuf = gst_vaapi_uploader_get_buffer(postproc->uploader); + if (!outbuf) + goto error_create_buffer; + if (!gst_vaapi_uploader_process(postproc->uploader, inbuf, outbuf)) + goto error_copy_buffer; + + gst_buffer_copy_metadata(outbuf, inbuf, + GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); + return outbuf; + + /* ERRORS */ +error_create_buffer: + { + GST_ERROR("failed to create buffer"); + return NULL; + } +error_copy_buffer: + { + GST_ERROR("failed to upload buffer to VA surface"); + gst_buffer_unref(outbuf); + return NULL; + } +#endif +} + static GstFlowReturn gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf) { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + GstBuffer *buf; GstFlowReturn ret; + buf = get_source_buffer(postproc, inbuf); + if (!buf) + return GST_FLOW_ERROR; + if (postproc->deinterlace) - ret = gst_vaapipostproc_process(trans, inbuf, outbuf); + ret = gst_vaapipostproc_process(trans, buf, outbuf); else - ret = gst_vaapipostproc_passthrough(trans, inbuf, outbuf); + ret = gst_vaapipostproc_passthrough(trans, buf, outbuf); + + gst_buffer_unref(buf); return ret; } @@ -558,6 +707,72 @@ gst_vaapipostproc_prepare_output_buffer(GstBaseTransform *trans, return *outbuf_ptr ? GST_FLOW_OK : GST_FLOW_ERROR; } +static gboolean +ensure_sinkpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps) +{ +#if GST_CHECK_VERSION(1,0,0) + GstBufferPool *pool; + GstCaps *pool_caps; + GstStructure *config; + GstVideoInfo vi; + gboolean need_pool; + + if (!gst_vaapipostproc_ensure_display(postproc)) + return FALSE; + + if (postproc->sinkpad_buffer_pool) { + config = gst_buffer_pool_get_config(postproc->sinkpad_buffer_pool); + gst_buffer_pool_config_get_params(config, &pool_caps, NULL, NULL, NULL); + need_pool = !gst_caps_is_equal(caps, pool_caps); + gst_structure_free(config); + if (!need_pool) + return TRUE; + g_clear_object(&postproc->sinkpad_buffer_pool); + postproc->sinkpad_buffer_size = 0; + } + + pool = gst_vaapi_video_buffer_pool_new(postproc->display); + if (!pool) + goto error_create_pool; + + gst_video_info_init(&vi); + gst_video_info_from_caps(&vi, caps); + if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) { + GST_DEBUG("assume sink pad buffer pool format is NV12"); + gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); + } + postproc->sinkpad_buffer_size = vi.size; + + config = gst_buffer_pool_get_config(pool); + gst_buffer_pool_config_set_params(config, caps, + postproc->sinkpad_buffer_size, 0, 0); + gst_buffer_pool_config_add_option(config, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); + gst_buffer_pool_config_add_option(config, + GST_BUFFER_POOL_OPTION_VIDEO_META); + if (!gst_buffer_pool_set_config(pool, config)) + goto error_pool_config; + postproc->sinkpad_buffer_pool = pool; + return TRUE; + + /* ERRORS */ +error_create_pool: + { + GST_ERROR("failed to create buffer pool"); + return FALSE; + } +error_pool_config: + { + GST_ERROR("failed to reset buffer pool config"); + gst_object_unref(pool); + return FALSE; + } +#else + return TRUE; +#endif +} + static gboolean gst_vaapipostproc_set_caps(GstBaseTransform *trans, GstCaps *caps, GstCaps *out_caps) @@ -571,11 +786,15 @@ gst_vaapipostproc_set_caps(GstBaseTransform *trans, GstCaps *caps, return FALSE; if (caps_changed) { - if (!gst_vaapipostproc_reset(postproc)) - return FALSE; + gst_vaapipostproc_destroy(postproc); gst_caps_replace(&postproc->sinkpad_caps, caps); gst_caps_replace(&postproc->srcpad_caps, out_caps); + if (!gst_vaapipostproc_create(postproc)) + return FALSE; } + + if (!ensure_sinkpad_buffer_pool(postproc, caps)) + return FALSE; return TRUE; } @@ -596,6 +815,49 @@ gst_vaapipostproc_query(GstBaseTransform *trans, GstPadDirection direction, trans, direction, query); } +#if GST_CHECK_VERSION(1,0,0) +static gboolean +gst_vaapipostproc_propose_allocation(GstBaseTransform *trans, + GstQuery *decide_query, GstQuery *query) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + GstCaps *caps = NULL; + gboolean need_pool; + + /* Let vaapidecode allocate the video buffers */ + if (!postproc->is_raw_yuv) + return FALSE; + + gst_query_parse_allocation(query, &caps, &need_pool); + + if (need_pool) { + if (!caps) + goto error_no_caps; + if (!ensure_sinkpad_buffer_pool(postproc, caps)) + return FALSE; + gst_query_add_allocation_pool(query, postproc->sinkpad_buffer_pool, + postproc->sinkpad_buffer_size, 0, 0); + } + + gst_query_add_allocation_meta(query, + GST_VAAPI_VIDEO_META_API_TYPE, NULL); + gst_query_add_allocation_meta(query, + GST_VIDEO_META_API_TYPE, NULL); + gst_query_add_allocation_meta(query, + GST_VIDEO_CROP_META_API_TYPE, NULL); + gst_query_add_allocation_meta(query, + GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL); + return TRUE; + + /* ERRORS */ +error_no_caps: + { + GST_ERROR("no caps specified"); + return FALSE; + } +} +#endif + static void gst_vaapipostproc_finalize(GObject *object) { @@ -669,10 +931,15 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) trans_class->start = gst_vaapipostproc_start; trans_class->stop = gst_vaapipostproc_stop; trans_class->transform_caps = gst_vaapipostproc_transform_caps; + trans_class->transform_size = gst_vaapipostproc_transform_size; trans_class->transform = gst_vaapipostproc_transform; trans_class->set_caps = gst_vaapipostproc_set_caps; trans_class->query = gst_vaapipostproc_query; +#if GST_CHECK_VERSION(1,0,0) + trans_class->propose_allocation = gst_vaapipostproc_propose_allocation; +#endif + trans_class->prepare_output_buffer = gst_vaapipostproc_prepare_output_buffer; diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 480753c8d8..0826c1a26b 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -27,6 +27,7 @@ #include #include #include +#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -74,9 +75,16 @@ struct _GstVaapiPostproc { GstBaseTransform parent_instance; GstVaapiDisplay *display; + GstVaapiUploader *uploader; + gboolean is_raw_yuv; + GstCaps *allowed_caps; GstCaps *sinkpad_caps; GstVideoInfo sinkpad_info; +#if GST_CHECK_VERSION(1,0,0) + GstBufferPool *sinkpad_buffer_pool; +#endif + guint sinkpad_buffer_size; GstCaps *srcpad_caps; GstVideoInfo srcpad_info; From d71008210d197a9eb069aea38cc8defeaa8a5fc6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 16 Oct 2013 11:20:50 +0200 Subject: [PATCH 1364/3781] vaapipostproc: factor out operations to be applied into flags. Even if we only support deinterlacing for now, use flags to specify which filters are to be applied to each frame we receive in transform(). This is preparatory work for integrating new filters. --- gst/vaapi/gstvaapipostproc.c | 12 +++++++----- gst/vaapi/gstvaapipostproc.h | 31 ++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6e99cb6e52..6a8eb38a5b 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -249,7 +249,7 @@ gst_vaapipostproc_stop(GstBaseTransform *trans) static gboolean is_interlaced_buffer(GstVaapiPostproc *postproc, GstBuffer *buf) { - if (!postproc->deinterlace) + if (!(postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE)) return FALSE; switch (GST_VIDEO_INFO_INTERLACE_MODE(&postproc->sinkpad_info)) { @@ -441,6 +441,7 @@ gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps, gboolean *caps_changed_ptr) { GstVideoInfo vi; + gboolean deinterlace; if (!gst_video_info_from_caps(&vi, caps)) return FALSE; @@ -448,10 +449,12 @@ gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps, if (video_info_changed(&vi, &postproc->sinkpad_info)) postproc->sinkpad_info = vi, *caps_changed_ptr = TRUE; - postproc->deinterlace = is_deinterlace_enabled(postproc, &vi); + deinterlace = is_deinterlace_enabled(postproc, &vi); + if (deinterlace) + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_DEINTERLACE; postproc->field_duration = gst_util_uint64_scale( GST_SECOND, GST_VIDEO_INFO_FPS_D(&vi), - (1 + postproc->deinterlace) * GST_VIDEO_INFO_FPS_N(&vi)); + (1 + deinterlace) * GST_VIDEO_INFO_FPS_N(&vi)); postproc->is_raw_yuv = GST_VIDEO_INFO_IS_YUV(&vi); #if !GST_CHECK_VERSION(1,0,0) @@ -684,7 +687,7 @@ gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf, if (!buf) return GST_FLOW_ERROR; - if (postproc->deinterlace) + if (postproc->flags == GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) ret = gst_vaapipostproc_process(trans, buf, outbuf); else ret = gst_vaapipostproc_passthrough(trans, buf, outbuf); @@ -993,7 +996,6 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) static void gst_vaapipostproc_init(GstVaapiPostproc *postproc) { - postproc->deinterlace = FALSE; postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE; postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; postproc->field_duration = GST_CLOCK_TIME_NONE; diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 0826c1a26b..2c08dee192 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -70,12 +70,42 @@ typedef enum { GST_VAAPI_DEINTERLACE_MODE_DISABLED, } GstVaapiDeinterlaceMode; +/** + * GstVaapiPostprocFlags: + * @GST_VAAPI_POSTPROC_FLAG_FORMAT: Pixel format conversion. + * @GST_VAAPI_POSTPROC_FLAG_DENOISE: Noise reduction. + * @GST_VAAPI_POSTPROC_FLAG_SHARPEN: Sharpening. + * @GST_VAAPI_POSTPROC_FLAG_HUE: Change color hue. + * @GST_VAAPI_POSTPROC_FLAG_SATURATION: Change saturation. + * @GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS: Change brightness. + * @GST_VAAPI_POSTPROC_FLAG_CONTRAST: Change contrast. + * @GST_VAAPI_POSTPROC_FLAG_DEINTERLACE: Deinterlacing. + * @GST_VAAPI_POSTPROC_FLAG_SIZE: Video scaling. + * + * The set of operations that are to be performed for each frame. + */ +typedef enum { + GST_VAAPI_POSTPROC_FLAG_FORMAT = 1 << GST_VAAPI_FILTER_OP_FORMAT, + GST_VAAPI_POSTPROC_FLAG_DENOISE = 1 << GST_VAAPI_FILTER_OP_DENOISE, + GST_VAAPI_POSTPROC_FLAG_SHARPEN = 1 << GST_VAAPI_FILTER_OP_SHARPEN, + GST_VAAPI_POSTPROC_FLAG_HUE = 1 << GST_VAAPI_FILTER_OP_HUE, + GST_VAAPI_POSTPROC_FLAG_SATURATION = 1 << GST_VAAPI_FILTER_OP_SATURATION, + GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS = 1 << GST_VAAPI_FILTER_OP_BRIGHTNESS, + GST_VAAPI_POSTPROC_FLAG_CONTRAST = 1 << GST_VAAPI_FILTER_OP_CONTRAST, + GST_VAAPI_POSTPROC_FLAG_DEINTERLACE = 1 << GST_VAAPI_FILTER_OP_DEINTERLACING, + + /* Additional custom flags */ + GST_VAAPI_POSTPROC_FLAG_CUSTOM = 1 << 20, + GST_VAAPI_POSTPROC_FLAG_SIZE = GST_VAAPI_POSTPROC_FLAG_CUSTOM, +} GstVaapiPostprocFlags; + struct _GstVaapiPostproc { /*< private >*/ GstBaseTransform parent_instance; GstVaapiDisplay *display; GstVaapiUploader *uploader; + guint flags; gboolean is_raw_yuv; GstCaps *allowed_caps; @@ -89,7 +119,6 @@ struct _GstVaapiPostproc { GstVideoInfo srcpad_info; /* Deinterlacing */ - gboolean deinterlace; GstVaapiDeinterlaceMode deinterlace_mode; GstVaapiDeinterlaceMethod deinterlace_method; GstClockTime field_duration; From 6d86caa9d1353fd6aa84d52dcb1129751b722b13 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 16 Oct 2013 11:23:03 +0200 Subject: [PATCH 1365/3781] vaapipostproc: fix bug when user disabled deinterlacing. Fix pipeline error / hang when the user disabled deinterlacing through the deinterlace-mode=disabled property setting. --- gst/vaapi/gstvaapipostproc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6a8eb38a5b..c72507559c 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -550,12 +550,12 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, /* Set double framerate in interlaced mode */ if (!gst_util_fraction_multiply(fps_n, fps_d, 2, 1, &fps_n, &fps_d)) return NULL; - - /* Signal the other pad that we generate only progressive frames */ - GST_VIDEO_INFO_INTERLACE_MODE(&vi) = - GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; } format = GST_VIDEO_FORMAT_ENCODED; + + /* Signal the other pad that we generate only progressive frames */ + GST_VIDEO_INFO_INTERLACE_MODE(&vi) = + GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; } else { if (is_deinterlace_enabled(postproc, &vi)) { From cf69e7269c940057d8f68d12a6e96aea147c303c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Oct 2013 18:08:25 +0200 Subject: [PATCH 1366/3781] vaapipostproc: add initial support for color conversion. If VPP is available, we always try to implicitly convert the source buffer to the "native" surface format for the underlying accelerator. This means that no optimization is performed yet to propagate raw YUV buffers to the downstream element as is, if VPP is available. i.e. it will always cause a color conversion. --- gst/vaapi/gstvaapipostproc.c | 336 +++++++++++++++++++++++++++++++++-- gst/vaapi/gstvaapipostproc.h | 13 +- 2 files changed, 332 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index c72507559c..95db300f2e 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -133,10 +133,12 @@ G_DEFINE_TYPE_WITH_CODE( enum { PROP_0, + PROP_FORMAT, PROP_DEINTERLACE_MODE, PROP_DEINTERLACE_METHOD, }; +#define DEFAULT_FORMAT GST_VIDEO_FORMAT_ENCODED #define DEFAULT_DEINTERLACE_MODE GST_VAAPI_DEINTERLACE_MODE_AUTO #define DEFAULT_DEINTERLACE_METHOD GST_VAAPI_DEINTERLACE_METHOD_BOB @@ -165,6 +167,22 @@ gst_vaapi_deinterlace_mode_get_type(void) return deinterlace_mode_type; } +static GstVaapiFilterOpInfo * +find_filter_op(GPtrArray *filter_ops, GstVaapiFilterOp op) +{ + guint i; + + if (filter_ops) { + for (i = 0; i < filter_ops->len; i++) { + GstVaapiFilterOpInfo * const filter_op = + g_ptr_array_index(filter_ops, i); + if (filter_op->op == op) + return filter_op; + } + } + return NULL; +} + static inline gboolean gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc) { @@ -201,6 +219,37 @@ gst_vaapipostproc_ensure_uploader_caps(GstVaapiPostproc *postproc) return TRUE; } +static gboolean +gst_vaapipostproc_ensure_filter(GstVaapiPostproc *postproc) +{ + if (postproc->filter) + return TRUE; + + if (!gst_vaapipostproc_ensure_display(postproc)) + return FALSE; + + postproc->filter = gst_vaapi_filter_new(postproc->display); + if (!postproc->filter) + return FALSE; + return TRUE; +} + +static gboolean +gst_vaapipostproc_ensure_filter_caps(GstVaapiPostproc *postproc) +{ + if (!gst_vaapipostproc_ensure_filter(postproc)) + return FALSE; + + postproc->filter_ops = gst_vaapi_filter_get_operations(postproc->filter); + if (!postproc->filter_ops) + return FALSE; + + postproc->filter_formats = gst_vaapi_filter_get_formats(postproc->filter); + if (!postproc->filter_formats) + return FALSE; + return TRUE; +} + static gboolean gst_vaapipostproc_create(GstVaapiPostproc *postproc) { @@ -210,9 +259,26 @@ gst_vaapipostproc_create(GstVaapiPostproc *postproc) return FALSE; if (!gst_vaapipostproc_ensure_uploader_caps(postproc)) return FALSE; + if (gst_vaapipostproc_ensure_filter(postproc)) + postproc->use_vpp = TRUE; return TRUE; } +static void +gst_vaapipostproc_destroy_filter(GstVaapiPostproc *postproc) +{ + if (postproc->filter_formats) { + g_array_unref(postproc->filter_formats); + postproc->filter_formats = NULL; + } + + if (postproc->filter_ops) { + g_ptr_array_unref(postproc->filter_ops); + postproc->filter_ops = NULL; + } + gst_vaapi_filter_replace(&postproc->filter, NULL); +} + static void gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) { @@ -220,11 +286,13 @@ gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) g_clear_object(&postproc->sinkpad_buffer_pool); #endif g_clear_object(&postproc->uploader); + gst_vaapipostproc_destroy_filter(postproc); gst_vaapi_display_replace(&postproc->display, NULL); + gst_caps_replace(&postproc->allowed_sinkpad_caps, NULL); gst_caps_replace(&postproc->sinkpad_caps, NULL); + gst_caps_replace(&postproc->allowed_srcpad_caps, NULL); gst_caps_replace(&postproc->srcpad_caps, NULL); - gst_caps_replace(&postproc->allowed_caps, NULL); } static gboolean @@ -300,6 +368,65 @@ append_output_buffer_metadata(GstBuffer *outbuf, GstBuffer *inbuf, guint flags) 0, -1); } +static GstFlowReturn +gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, + GstBuffer *outbuf) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + GstVaapiVideoMeta *inbuf_meta, *outbuf_meta; + GstVaapiSurface *inbuf_surface, *outbuf_surface; + GstVaapiFilterStatus status; + guint flags; + + /* Validate filters */ + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) && + !gst_vaapi_filter_set_format(postproc->filter, postproc->format)) + return GST_FLOW_NOT_SUPPORTED; + + inbuf_meta = gst_buffer_get_vaapi_video_meta(inbuf); + if (!inbuf_meta) + goto error_invalid_buffer; + inbuf_surface = gst_vaapi_video_meta_get_surface(inbuf_meta); + + flags = gst_vaapi_video_meta_get_render_flags(inbuf_meta) & + ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); + + outbuf_meta = gst_vaapi_video_meta_new_from_pool(postproc->filter_pool); + if (!outbuf_meta) + goto error_create_meta; + outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); + + status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, + outbuf_surface, flags); + if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) + goto error_process_vpp; + + gst_buffer_copy_into(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); + gst_buffer_set_vaapi_video_meta(outbuf, outbuf_meta); + gst_vaapi_video_meta_unref(outbuf_meta); + return GST_FLOW_OK; + + /* ERRORS */ +error_invalid_buffer: + { + GST_ERROR("failed to validate source buffer"); + return GST_FLOW_ERROR; + } +error_create_meta: + { + GST_ERROR("failed to create new output buffer meta"); + gst_vaapi_video_meta_unref(outbuf_meta); + return GST_FLOW_ERROR; + } +error_process_vpp: + { + GST_ERROR("failed to apply VPP filters (error %d)", status); + gst_vaapi_video_meta_unref(outbuf_meta); + return GST_FLOW_ERROR; + } +} + static GstFlowReturn gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf) @@ -481,15 +608,18 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps, if (video_info_changed(&vi, &postproc->srcpad_info)) postproc->srcpad_info = vi, *caps_changed_ptr = TRUE; + + if (postproc->format != GST_VIDEO_INFO_FORMAT(&postproc->sinkpad_info)) + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_FORMAT; return TRUE; } static gboolean -ensure_allowed_caps(GstVaapiPostproc *postproc) +ensure_allowed_sinkpad_caps(GstVaapiPostproc *postproc) { GstCaps *out_caps, *yuv_caps; - if (postproc->allowed_caps) + if (postproc->allowed_sinkpad_caps) return TRUE; /* Create VA caps */ @@ -508,12 +638,111 @@ ensure_allowed_caps(GstVaapiPostproc *postproc) else GST_WARNING("failed to create YUV sink caps"); } - postproc->allowed_caps = out_caps; + postproc->allowed_sinkpad_caps = out_caps; /* XXX: append VA/VPP filters */ return TRUE; } +/* Build list of supported formats */ +static gboolean +build_format_list_value(GArray *formats, GValue *out_value) +{ + GValue v_format = { 0, }; + guint i; +#if GST_CHECK_VERSION(1,0,0) + const gchar *str; + + g_value_init(out_value, GST_TYPE_LIST); + + g_value_init(&v_format, G_TYPE_STRING); + g_value_set_string(&v_format, "encoded"); + gst_value_list_append_value(out_value, &v_format); + + for (i = 0; i < formats->len; i++) { + GstVideoFormat const format = + g_array_index(formats, GstVideoFormat, i); + + str = gst_vaapi_video_format_to_string(format); + if (!str) + continue; + g_value_set_string(&v_format, str); + gst_value_list_append_value(out_value, &v_format); + } +#else + guint32 fourcc; + + g_value_init(out_value, GST_TYPE_LIST); + g_value_init(&v_format, GST_TYPE_FOURCC); + for (i = 0; i < formats->len; i++) { + GstVideoFormat const format = + g_array_index(formats, GstVideoFormat, i); + + fourcc = gst_video_format_to_fourcc(format); + if (!fourcc) + continue; + gst_value_set_fourcc(&v_format, fourcc); + gst_value_list_append_value(out_value, &v_format); + } +#endif + + g_value_unset(&v_format); + return TRUE; +} + +/* Fixup output caps so that to reflect the supported set of pixel formats */ +static GstCaps * +expand_allowed_srcpad_caps(GstVaapiPostproc *postproc, GstCaps *caps) +{ + GValue value = { 0, }; + guint i, num_structures; + gboolean had_filter; + + had_filter = postproc->filter != NULL; + if (!had_filter && !gst_vaapipostproc_ensure_filter(postproc)) + goto cleanup; + if (!gst_vaapipostproc_ensure_filter_caps(postproc)) + goto cleanup; + + /* Reset "format" field for each structure */ + if (!build_format_list_value(postproc->filter_formats, &value)) + goto cleanup; + + num_structures = gst_caps_get_size(caps); + for (i = 0; i < num_structures; i++) { + GstStructure * const structure = gst_caps_get_structure(caps, i); + if (!structure) + continue; + gst_structure_set_value(structure, "format", &value); + } + g_value_unset(&value); + +cleanup: + if (!had_filter) + gst_vaapipostproc_destroy_filter(postproc); + return caps; +} + +static gboolean +ensure_allowed_srcpad_caps(GstVaapiPostproc *postproc) +{ + GstCaps *out_caps; + + if (postproc->allowed_srcpad_caps) + return TRUE; + + /* Create initial caps from pad template */ + out_caps = gst_caps_from_string(gst_vaapipostproc_src_caps_str); + if (!out_caps) { + GST_ERROR("failed to create VA src caps"); + return FALSE; + } + + postproc->allowed_srcpad_caps = + expand_allowed_srcpad_caps(postproc, out_caps); + return postproc->allowed_srcpad_caps != NULL; +} + static GstCaps * gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, GstPadDirection direction, GstCaps *caps) @@ -525,13 +754,18 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, gint fps_n, fps_d, par_n, par_d; if (!gst_caps_is_fixed(caps)) { - if (direction == GST_PAD_SINK) - return gst_caps_from_string(gst_vaapipostproc_src_caps_str); - - /* Generate the allowed set of caps on the sink pad */ - if (!ensure_allowed_caps(postproc)) - return NULL; - return gst_caps_ref(postproc->allowed_caps); + out_caps = NULL; + if (direction == GST_PAD_SINK) { + /* Generate the allowed set of caps on the src pad */ + if (ensure_allowed_srcpad_caps(postproc)) + out_caps = gst_caps_ref(postproc->allowed_srcpad_caps); + } + else { + /* Generate the allowed set of caps on the sink pad */ + if (ensure_allowed_sinkpad_caps(postproc)) + out_caps = gst_caps_ref(postproc->allowed_sinkpad_caps); + } + return out_caps; } /* Generate the other pad caps, based on the current pad caps, as @@ -687,11 +921,30 @@ gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf, if (!buf) return GST_FLOW_ERROR; - if (postproc->flags == GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) - ret = gst_vaapipostproc_process(trans, buf, outbuf); - else - ret = gst_vaapipostproc_passthrough(trans, buf, outbuf); + ret = GST_FLOW_NOT_SUPPORTED; + if (postproc->flags) { + /* Use VA/VPP extensions to process this frame */ + if (postproc->use_vpp && + postproc->flags != GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) { + ret = gst_vaapipostproc_process_vpp(trans, buf, outbuf); + if (ret != GST_FLOW_NOT_SUPPORTED) + goto done; + GST_WARNING("unsupported VPP filters. Disabling"); + postproc->use_vpp = FALSE; + } + /* Only append picture structure meta data (top/bottom field) */ + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) { + ret = gst_vaapipostproc_process(trans, buf, outbuf); + if (ret != GST_FLOW_NOT_SUPPORTED) + goto done; + } + } + + /* Fallback: passthrough to the downstream element as is */ + ret = gst_vaapipostproc_passthrough(trans, buf, outbuf); + +done: gst_buffer_unref(buf); return ret; } @@ -776,6 +1029,31 @@ error_pool_config: #endif } +static gboolean +ensure_srcpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps) +{ + GstVideoInfo vi; + GstVaapiVideoPool *pool; + + gst_video_info_init(&vi); + gst_video_info_from_caps(&vi, caps); + gst_video_info_set_format(&vi, postproc->format, + GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); + + if (!video_info_changed(&vi, &postproc->filter_pool_info)) + return TRUE; + postproc->filter_pool_info = vi; + + pool = gst_vaapi_surface_pool_new(postproc->display, + &postproc->filter_pool_info); + if (!pool) + return FALSE; + + gst_vaapi_video_pool_replace(&postproc->filter_pool, pool); + gst_vaapi_video_pool_unref(pool); + return TRUE; +} + static gboolean gst_vaapipostproc_set_caps(GstBaseTransform *trans, GstCaps *caps, GstCaps *out_caps) @@ -798,6 +1076,8 @@ gst_vaapipostproc_set_caps(GstBaseTransform *trans, GstCaps *caps, if (!ensure_sinkpad_buffer_pool(postproc, caps)) return FALSE; + if (!ensure_srcpad_buffer_pool(postproc, out_caps)) + return FALSE; return TRUE; } @@ -882,6 +1162,9 @@ gst_vaapipostproc_set_property( GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(object); switch (prop_id) { + case PROP_FORMAT: + postproc->format = g_value_get_enum(value); + break; case PROP_DEINTERLACE_MODE: postproc->deinterlace_mode = g_value_get_enum(value); break; @@ -905,6 +1188,9 @@ gst_vaapipostproc_get_property( GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(object); switch (prop_id) { + case PROP_FORMAT: + g_value_set_enum(value, postproc->format); + break; case PROP_DEINTERLACE_MODE: g_value_set_enum(value, postproc->deinterlace_mode); break; @@ -924,6 +1210,8 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); GstPadTemplate *pad_template; + GPtrArray *filter_ops; + GstVaapiFilterOpInfo *filter_op; GST_DEBUG_CATEGORY_INIT(gst_debug_vaapipostproc, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); @@ -991,15 +1279,33 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) GST_VAAPI_TYPE_DEINTERLACE_METHOD, DEFAULT_DEINTERLACE_METHOD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + filter_ops = gst_vaapi_filter_get_operations(NULL); + if (!filter_ops) + return; + + /** + * GstVaapiPostproc:format: + * + * The forced output pixel format, expressed as a #GstVideoFormat. + */ + filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_FORMAT); + if (filter_op) + g_object_class_install_property(object_class, + PROP_FORMAT, filter_op->pspec); + + g_ptr_array_unref(filter_ops); } static void gst_vaapipostproc_init(GstVaapiPostproc *postproc) { + postproc->format = DEFAULT_FORMAT; postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE; postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; postproc->field_duration = GST_CLOCK_TIME_NONE; gst_video_info_init(&postproc->sinkpad_info); gst_video_info_init(&postproc->srcpad_info); + gst_video_info_init(&postproc->filter_pool_info); } diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 2c08dee192..b85b3cb7c8 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -105,16 +105,22 @@ struct _GstVaapiPostproc { GstVaapiDisplay *display; GstVaapiUploader *uploader; + GstVaapiFilter *filter; + GPtrArray *filter_ops; + GstVaapiVideoPool *filter_pool; + GstVideoInfo filter_pool_info; + GArray *filter_formats; + GstVideoFormat format; /* output video format (encoded) */ guint flags; - gboolean is_raw_yuv; - GstCaps *allowed_caps; + GstCaps *allowed_sinkpad_caps; GstCaps *sinkpad_caps; GstVideoInfo sinkpad_info; #if GST_CHECK_VERSION(1,0,0) GstBufferPool *sinkpad_buffer_pool; #endif guint sinkpad_buffer_size; + GstCaps *allowed_srcpad_caps; GstCaps *srcpad_caps; GstVideoInfo srcpad_info; @@ -122,6 +128,9 @@ struct _GstVaapiPostproc { GstVaapiDeinterlaceMode deinterlace_mode; GstVaapiDeinterlaceMethod deinterlace_method; GstClockTime field_duration; + + guint is_raw_yuv : 1; + guint use_vpp : 1; }; struct _GstVaapiPostprocClass { From e7544dc57ecef55ac2a39053307b5904644156ee Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Oct 2013 18:08:25 +0200 Subject: [PATCH 1367/3781] vaapipostproc: add initial support for scaling. Add initial support for basic scaling with size specified through the "width" and "height" properties. If either user-provided dimension is zero and "force-aspect-ratio" is set to true (the default), then the other dimension is scaled to preserve the aspect ratio. --- gst/vaapi/gstvaapipostproc.c | 111 +++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipostproc.h | 3 + 2 files changed, 114 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 95db300f2e..1abc228454 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -134,6 +134,9 @@ enum { PROP_0, PROP_FORMAT, + PROP_WIDTH, + PROP_HEIGHT, + PROP_FORCE_ASPECT_RATIO, PROP_DEINTERLACE_MODE, PROP_DEINTERLACE_METHOD, }; @@ -611,6 +614,11 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps, if (postproc->format != GST_VIDEO_INFO_FORMAT(&postproc->sinkpad_info)) postproc->flags |= GST_VAAPI_POSTPROC_FLAG_FORMAT; + + if ((postproc->width || postproc->height) && + postproc->width != GST_VIDEO_INFO_WIDTH(&postproc->sinkpad_info) && + postproc->height != GST_VIDEO_INFO_HEIGHT(&postproc->sinkpad_info)) + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SIZE; return TRUE; } @@ -743,6 +751,38 @@ ensure_allowed_srcpad_caps(GstVaapiPostproc *postproc) return postproc->allowed_srcpad_caps != NULL; } +static void +find_best_size(GstVaapiPostproc *postproc, GstVideoInfo *vip, + guint *width_ptr, guint *height_ptr) +{ + guint width, height; + + width = GST_VIDEO_INFO_WIDTH(vip); + height = GST_VIDEO_INFO_HEIGHT(vip); + if (postproc->width && postproc->height) { + width = postproc->width; + height = postproc->height; + } + else if (postproc->keep_aspect) { + const gdouble ratio = (gdouble)width / height; + if (postproc->width) { + width = postproc->width; + height = postproc->width / ratio; + } + else if (postproc->height) { + height = postproc->height; + width = postproc->height * ratio; + } + } + else if (postproc->width) + width = postproc->width; + else if (postproc->height) + height = postproc->height; + + *width_ptr = width; + *height_ptr = height; +} + static GstCaps * gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, GstPadDirection direction, GstCaps *caps) @@ -751,6 +791,7 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, GstVideoInfo vi; GstVideoFormat format; GstCaps *out_caps; + guint width, height; gint fps_n, fps_d, par_n, par_d; if (!gst_caps_is_fixed(caps)) { @@ -790,6 +831,9 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, /* Signal the other pad that we generate only progressive frames */ GST_VIDEO_INFO_INTERLACE_MODE(&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; + + find_best_size(postproc, &vi, &width, &height); + gst_video_info_set_format(&vi, format, width, height); } else { if (is_deinterlace_enabled(postproc, &vi)) { @@ -1165,6 +1209,15 @@ gst_vaapipostproc_set_property( case PROP_FORMAT: postproc->format = g_value_get_enum(value); break; + case PROP_WIDTH: + postproc->width = g_value_get_uint(value); + break; + case PROP_HEIGHT: + postproc->height = g_value_get_uint(value); + break; + case PROP_FORCE_ASPECT_RATIO: + postproc->keep_aspect = g_value_get_boolean(value); + break; case PROP_DEINTERLACE_MODE: postproc->deinterlace_mode = g_value_get_enum(value); break; @@ -1191,6 +1244,15 @@ gst_vaapipostproc_get_property( case PROP_FORMAT: g_value_set_enum(value, postproc->format); break; + case PROP_WIDTH: + g_value_set_uint(value, postproc->width); + break; + case PROP_HEIGHT: + g_value_set_uint(value, postproc->height); + break; + case PROP_FORCE_ASPECT_RATIO: + g_value_set_boolean(value, postproc->keep_aspect); + break; case PROP_DEINTERLACE_MODE: g_value_set_enum(value, postproc->deinterlace_mode); break; @@ -1294,6 +1356,54 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) g_object_class_install_property(object_class, PROP_FORMAT, filter_op->pspec); + /** + * GstVaapiPostproc:width: + * + * The forced output width in pixels. If set to zero, the width is + * calculated from the height if aspect ration is preserved, or + * inherited from the sink caps width + */ + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_uint("width", + "Width", + "Forced output width", + 0, G_MAXINT, 0, + G_PARAM_READWRITE)); + + /** + * GstVaapiPostproc:height: + * + * The forced output height in pixels. If set to zero, the height + * is calculated from the width if aspect ration is preserved, or + * inherited from the sink caps height + */ + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_uint("height", + "Height", + "Forced output height", + 0, G_MAXINT, 0, + G_PARAM_READWRITE)); + + /** + * GstVaapiPostproc:force-aspect-ratio: + * + * When enabled, scaling respects video aspect ratio; when + * disabled, the video is distorted to fit the width and height + * properties. + */ + g_object_class_install_property + (object_class, + PROP_FORCE_ASPECT_RATIO, + g_param_spec_boolean("force-aspect-ratio", + "Force aspect ratio", + "When enabled, scaling will respect original aspect ratio", + TRUE, + G_PARAM_READWRITE)); + g_ptr_array_unref(filter_ops); } @@ -1304,6 +1414,7 @@ gst_vaapipostproc_init(GstVaapiPostproc *postproc) postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE; postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; postproc->field_duration = GST_CLOCK_TIME_NONE; + postproc->keep_aspect = TRUE; gst_video_info_init(&postproc->sinkpad_info); gst_video_info_init(&postproc->srcpad_info); diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index b85b3cb7c8..b82f751748 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -111,6 +111,8 @@ struct _GstVaapiPostproc { GstVideoInfo filter_pool_info; GArray *filter_formats; GstVideoFormat format; /* output video format (encoded) */ + guint width; + guint height; guint flags; GstCaps *allowed_sinkpad_caps; @@ -131,6 +133,7 @@ struct _GstVaapiPostproc { guint is_raw_yuv : 1; guint use_vpp : 1; + guint keep_aspect : 1; }; struct _GstVaapiPostprocClass { From 2aab27b8deb9bd4e751f62e06469d5b40057a202 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 15 Nov 2013 17:14:04 +0100 Subject: [PATCH 1368/3781] vaapipostproc: fix build on 64-bit platforms with GStreamer 0.10. The size argument for GstBaseTransform::transform_size() hook is a guint in GStreamer 0.10 APIs but a gsize in GStreamer >= 1.0.X APIs. --- gst/vaapi/gstvaapipostproc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 1abc228454..d79ae9e886 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -892,10 +892,16 @@ gst_vaapipostproc_transform_caps(GstBaseTransform *trans, gst_vaapipostproc_transform_caps_impl #endif +#if GST_CHECK_VERSION(1,0,0) +typedef gsize GstBaseTransformSizeType; +#else +typedef guint GstBaseTransformSizeType; +#endif + static gboolean gst_vaapipostproc_transform_size(GstBaseTransform *trans, - GstPadDirection direction, GstCaps *caps, gsize size, - GstCaps *othercaps, gsize *othersize) + GstPadDirection direction, GstCaps *caps, GstBaseTransformSizeType size, + GstCaps *othercaps, GstBaseTransformSizeType *othersize) { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); From be7a2ed64c136feeee24960b74f2cb17583c7fe9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 15 Nov 2013 19:04:07 +0100 Subject: [PATCH 1369/3781] vaapipostproc: add initial support for deinterlacing with VPP. Allow basic bob-deinterlacing to work when VPP is enabled. Currently, this only covers bob-deinterlacing when the output pixel format is explicitly set. --- gst/vaapi/gstvaapipostproc.c | 79 +++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index d79ae9e886..cb05661bfc 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -379,7 +379,11 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, GstVaapiVideoMeta *inbuf_meta, *outbuf_meta; GstVaapiSurface *inbuf_surface, *outbuf_surface; GstVaapiFilterStatus status; - guint flags; + GstClockTime timestamp; + GstFlowReturn ret; + GstBuffer *fieldbuf; + guint flags, deint_flags; + gboolean tff, deint; /* Validate filters */ if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) && @@ -391,21 +395,72 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, goto error_invalid_buffer; inbuf_surface = gst_vaapi_video_meta_get_surface(inbuf_meta); + timestamp = GST_BUFFER_TIMESTAMP(inbuf); + tff = GST_BUFFER_FLAG_IS_SET(inbuf, GST_VIDEO_BUFFER_FLAG_TFF); + deint = is_interlaced_buffer(postproc, inbuf); + flags = gst_vaapi_video_meta_get_render_flags(inbuf_meta) & ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); + /* First field */ + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) { + fieldbuf = create_output_buffer(postproc); + if (!fieldbuf) + goto error_create_buffer; + + outbuf_meta = gst_vaapi_video_meta_new_from_pool(postproc->filter_pool); + if (!outbuf_meta) + goto error_create_meta; + outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); + + if (deint) { + deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TFF : 0); + if (!gst_vaapi_filter_set_deinterlacing(postproc->filter, + postproc->deinterlace_method, deint_flags)) + goto error_op_deinterlace; + } + + status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, + outbuf_surface, flags); + if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) + goto error_process_vpp; + + gst_buffer_set_vaapi_video_meta(fieldbuf, outbuf_meta); + gst_vaapi_video_meta_unref(outbuf_meta); + + GST_BUFFER_TIMESTAMP(fieldbuf) = timestamp; + GST_BUFFER_DURATION(fieldbuf) = postproc->field_duration; + ret = gst_pad_push(trans->srcpad, fieldbuf); + if (ret != GST_FLOW_OK) + goto error_push_buffer; + } + fieldbuf = NULL; + + /* Second field */ outbuf_meta = gst_vaapi_video_meta_new_from_pool(postproc->filter_pool); if (!outbuf_meta) goto error_create_meta; outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); + if (deint) { + deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TFF); + if (!gst_vaapi_filter_set_deinterlacing(postproc->filter, + postproc->deinterlace_method, deint_flags)) + goto error_op_deinterlace; + } + status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, outbuf_surface, flags); if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) goto error_process_vpp; - gst_buffer_copy_into(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); + if (!(postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE)) + gst_buffer_copy_into(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); + else { + GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration; + GST_BUFFER_DURATION(outbuf) = postproc->field_duration; + } gst_buffer_set_vaapi_video_meta(outbuf, outbuf_meta); gst_vaapi_video_meta_unref(outbuf_meta); return GST_FLOW_OK; @@ -416,18 +471,38 @@ error_invalid_buffer: GST_ERROR("failed to validate source buffer"); return GST_FLOW_ERROR; } +error_create_buffer: + { + GST_ERROR("failed to create output buffer"); + return GST_FLOW_ERROR; + } error_create_meta: { GST_ERROR("failed to create new output buffer meta"); + gst_buffer_replace(&fieldbuf, NULL); gst_vaapi_video_meta_unref(outbuf_meta); return GST_FLOW_ERROR; } +error_op_deinterlace: + { + GST_ERROR("failed to apply deinterlacing filter"); + gst_buffer_replace(&fieldbuf, NULL); + gst_vaapi_video_meta_unref(outbuf_meta); + return GST_FLOW_NOT_SUPPORTED; + } error_process_vpp: { GST_ERROR("failed to apply VPP filters (error %d)", status); + gst_buffer_replace(&fieldbuf, NULL); gst_vaapi_video_meta_unref(outbuf_meta); return GST_FLOW_ERROR; } +error_push_buffer: + { + if (ret != GST_FLOW_FLUSHING) + GST_ERROR("failed to push output buffer to video sink"); + return GST_FLOW_ERROR; + } } static GstFlowReturn From cc055b72ce222ea07b7617ee800e9998554ace7a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 16 Nov 2013 07:02:24 +0100 Subject: [PATCH 1370/3781] vaapipostproc: try to downgrade deinterlace-method when needed. If the currently selected deinterlacing method is not supported by the underlying hardware, then try to downgrade the method to a supported one. At the minimum, basic bob-deinterlacing shall always be supported. --- gst/vaapi/gstvaapipostproc.c | 42 ++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index cb05661bfc..1e202871cd 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -371,6 +371,39 @@ append_output_buffer_metadata(GstBuffer *outbuf, GstBuffer *inbuf, guint flags) 0, -1); } +static GstVaapiDeinterlaceMethod +get_next_deint_method(GstVaapiDeinterlaceMethod deint_method) +{ + switch (deint_method) { + case GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED: + deint_method = GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE; + break; + default: + /* Default to basic "bob" for all others */ + deint_method = GST_VAAPI_DEINTERLACE_METHOD_BOB; + break; + } + return deint_method; +} + +static gboolean +set_best_deint_method(GstVaapiPostproc *postproc, guint flags, + GstVaapiDeinterlaceMethod *deint_method_ptr) +{ + GstVaapiDeinterlaceMethod deint_method = postproc->deinterlace_method; + gboolean success; + + for (;;) { + success = gst_vaapi_filter_set_deinterlacing(postproc->filter, + deint_method, flags); + if (success || deint_method == GST_VAAPI_DEINTERLACE_METHOD_BOB) + break; + deint_method = get_next_deint_method(deint_method); + } + *deint_method_ptr = deint_method; + return success; +} + static GstFlowReturn gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf) @@ -415,10 +448,15 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); if (deint) { + GstVaapiDeinterlaceMethod deint_method; deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TFF : 0); - if (!gst_vaapi_filter_set_deinterlacing(postproc->filter, - postproc->deinterlace_method, deint_flags)) + if (!set_best_deint_method(postproc, flags, &deint_method)) goto error_op_deinterlace; + if (deint_method != postproc->deinterlace_method) { + GST_DEBUG("unsupported deinterlace-method %u. Using %u instead", + postproc->deinterlace_method, deint_method); + postproc->deinterlace_method = deint_method; + } } status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, From b62bd57bda595fb98a9fdc918df3ab5938c8e9f0 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 1 Nov 2013 13:43:11 +0800 Subject: [PATCH 1371/3781] vaapipostproc: fix support for raw YUV data upload on GStreamer 1.0. Fix raw YUV data uploaded as in the following pipeline: $ gst-launch-1.0 filesrc video.yuv ! videoparse ! vaapipostproc ! vaapisink The main reason why it failed was that the videoparse element simply allocates GstBuffer with raw data chunk'ed off the sink pad without any prior knowledge of the actual frame info. i.e. it basically just calls gst_adapter_take_buffer(). We could avoid the extra copy performed in vaapipostproc if the videoparse element was aware of the downstream pool and bothers copying line by line, for each plane. This means that, for a single frame per buffer, the optimizatin will be to allocate the video buffer downstream, map it, and copy each line that is coming through until we need to fills in the successive planes. Still, optimized raw YUV uploads already worked with the following: $ gst-launch-1.0 videotestsrc ! vaapipostproc ! vaapisink https://bugzilla.gnome.org/show_bug.cgi?id=711250 [clean-ups, fixed error cases to unmap and unref outbuf] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipostproc.c | 58 ++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 1e202871cd..99b400ccf6 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1030,14 +1030,43 @@ get_source_buffer(GstVaapiPostproc *postproc, GstBuffer *inbuf) { GstVaapiVideoMeta *meta; GstBuffer *outbuf; +#if GST_CHECK_VERSION(1,0,0) + GstVideoFrame src_frame, out_frame; +#endif meta = gst_buffer_get_vaapi_video_meta(inbuf); if (meta) return gst_buffer_ref(inbuf); #if GST_CHECK_VERSION(1,0,0) + if (!postproc->is_raw_yuv) + goto error_invalid_buffer; + + if (!postproc->sinkpad_buffer_pool) + goto error_no_pool; + + if (!gst_buffer_pool_set_active(postproc->sinkpad_buffer_pool, TRUE)) + goto error_active_pool; + outbuf = NULL; - goto error_invalid_buffer; + if (gst_buffer_pool_acquire_buffer(postproc->sinkpad_buffer_pool, + &outbuf, NULL) != GST_FLOW_OK) + goto error_create_buffer; + + if (!gst_video_frame_map(&src_frame, &postproc->sinkpad_info, inbuf, + GST_MAP_READ)) + goto error_map_src_buffer; + + if (!gst_video_frame_map(&out_frame, &postproc->sinkpad_info, outbuf, + GST_MAP_WRITE)) + goto error_map_dst_buffer; + + if (!gst_video_frame_copy(&out_frame, &src_frame)) + goto error_copy_buffer; + + gst_video_frame_unmap(&out_frame); + gst_video_frame_unmap(&src_frame); + gst_buffer_copy_into(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); return outbuf; /* ERRORS */ @@ -1046,6 +1075,27 @@ error_invalid_buffer: GST_ERROR("failed to validate source buffer"); return NULL; } +error_no_pool: + { + GST_ERROR("no buffer pool was negotiated"); + return NULL; + } +error_active_pool: + { + GST_ERROR("failed to activate buffer pool"); + return NULL; + } +error_map_dst_buffer: + { + gst_video_frame_unmap(&src_frame); + // fall-through + } +error_map_src_buffer: + { + GST_ERROR("failed to map buffer"); + gst_buffer_unref(outbuf); + return NULL; + } #else outbuf = gst_vaapi_uploader_get_buffer(postproc->uploader); if (!outbuf) @@ -1056,6 +1106,7 @@ error_invalid_buffer: gst_buffer_copy_metadata(outbuf, inbuf, GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); return outbuf; +#endif /* ERRORS */ error_create_buffer: @@ -1066,10 +1117,13 @@ error_create_buffer: error_copy_buffer: { GST_ERROR("failed to upload buffer to VA surface"); +#if GST_CHECK_VERSION(1,0,0) + gst_video_frame_unmap(&out_frame); + gst_video_frame_unmap(&src_frame); +#endif gst_buffer_unref(outbuf); return NULL; } -#endif } static GstFlowReturn From 29270e3af6f0c145a50f26ff9fb24a0092c5dbe7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 18 Nov 2013 18:25:21 +0100 Subject: [PATCH 1372/3781] configure: automatically detect GStreamer API version. Automatically detect GStreamer API version. The --with-gstreamer-api configure option now defaults to "autodetect" and configure then tries to derive the GStreamer API version from the highest version based on what pkg-config --modversion would report. https://bugzilla.gnome.org/show_bug.cgi?id=711657 --- configure.ac | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index f9029e3f95..473e31b7a2 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ m4_define([gst_vaapi_lt_age], [0]) m4_define([glib_version], [2.28]) # gstreamer version number -m4_define([gst_api_version], [1.0]) +m4_define([gst_api_version], [autodetect]) m4_define([gst0_version], [0.10.36]) m4_define([gst0_plugins_base_version], [0.10.31]) m4_define([gst0_plugins_bad_version], [0.10.22]) @@ -150,6 +150,32 @@ dnl --------------------------------------------------------------------------- dnl -- GStreamer -- dnl --------------------------------------------------------------------------- +dnl If GStreamer API version is to be autodetected, then always try +dnl with the latest version first +AC_MSG_CHECKING([for GStreamer API version]) +if test "$GST_API_VERSION" = "autodetect"; then + gst_pkg_versions="1.0 0.10" +else + AS_VERSION_COMPARE([$GST_API_VERSION], [1.0], + [gst_pkg_versions="0.10"], [gst_pkg_versions="1.0"], + dnl GStreamer 1.2.x APIs don't have their own namespace + [gst_pkg_versions="1.0"]) +fi +for gst_pkg_version in ${gst_pkg_versions}; do + if $PKG_CONFIG --exists "gstreamer-$gst_pkg_version"; then + gst_version=`$PKG_CONFIG --modversion "gstreamer-$gst_pkg_version"` + gst_major_version=`echo "$gst_version" | cut -d'.' -f1` + gst_minor_version=`echo "$gst_version" | cut -d'.' -f2` + GST_API_VERSION="${gst_major_version}.${gst_minor_version}" + GST_PKG_VERSION="$gst_pkg_version" + break + fi +done +if test -z "$GST_PKG_VERSION"; then + AC_MSG_ERROR([version $GST_API_VERSION not found]) +fi +AC_MSG_RESULT([$GST_API_VERSION]) + dnl Versions for GStreamer and plugins-base case $GST_API_VERSION in 0.10) From b4eb1dcd424b9518bf07edd40445dbaead8eb6e9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Nov 2013 10:37:36 +0100 Subject: [PATCH 1373/3781] plugins: expose the expected format for GstVideoGLTextureUploadMeta. Fix vaapidecode srcpad caps to only expose RGBA video format for the meta:GstVideoGLTextureUploadMeta feature. That's only what is supported so far. Besides, drop this meta from the vaapisink sinkpad caps since we really don't support that for rendering. https://bugzilla.gnome.org/show_bug.cgi?id=711828 --- gst/vaapi/gstvaapidecode.c | 3 +-- gst/vaapi/gstvaapisink.c | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1b926f8594..09b8993e31 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -74,8 +74,7 @@ static const char gst_vaapidecode_src_caps_str[] = GST_VIDEO_CAPS_MAKE_WITH_FEATURES( GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VIDEO_FORMATS_ALL) ";" GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, - GST_VIDEO_FORMATS_ALL); + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA"); #else GST_VAAPI_SURFACE_CAPS; #endif diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index c71c80af49..f284ebea40 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -86,10 +86,7 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink); static const char gst_vaapisink_sink_caps_str[] = #if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VIDEO_FORMATS_ALL) ";" - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, - GST_VIDEO_FORMATS_ALL); + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VIDEO_FORMATS_ALL); #else #if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) "; " From d556c0a37afb641c2bab894df75ef646e169f697 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Nov 2013 10:45:23 +0100 Subject: [PATCH 1374/3781] plugins: streamline VA formats exposed in caps to a realistic set. Currently, the decoder only supports YUV 4:2:0 output. So, expose the output formats for GStreamer 1.2 in caps to a realistic subset. This means NV12, I420 or YV12 but also ENCODED if we cannot determine the underlying VA surface format, or if it is actually not allowed to get access to the surface contents. --- gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapisink.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 09b8993e31..ad5de46d2c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -72,7 +72,7 @@ static const char gst_vaapidecode_sink_caps_str[] = static const char gst_vaapidecode_src_caps_str[] = #if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VIDEO_FORMATS_ALL) ";" + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ";" GST_VIDEO_CAPS_MAKE_WITH_FEATURES( GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA"); #else diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index f284ebea40..f92939051b 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -86,7 +86,7 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink); static const char gst_vaapisink_sink_caps_str[] = #if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VIDEO_FORMATS_ALL); + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }"); #else #if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) "; " From 7e8470e1ecbe0e3a3aa0f4dccb4c9a030b70ff4c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Nov 2013 10:56:28 +0100 Subject: [PATCH 1375/3781] vaapidecode: fix srcpad caps for GStreamer 1.2. The srcpad caps exposed for GStreamer 1.2 were missing any useful info like framerate, pixel-aspect-ratio, interlace-mode et al. Not to mention that it relied on possibly un-initialized data. Fix srcpad caps to be initialized from a sanitized copy of GstVideoDecoder output state caps. Note: the correct way to expose the srcpad caps triggers an additional issue in core GStreamer auto-plugging capabilities as the correct caps to be exposed should be format=ENCODED with memory:VASurface caps feature at the minimum. In some situations, we could determine the underlying VA surface format, but this is not always possible. e.g. cases where it is not allowed to expose the underlying VA surface data, or when the VA driver implementation cannot actually provide such information. --- gst/vaapi/gstvaapidecode.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ad5de46d2c..27da3c5bf6 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -191,6 +191,15 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, gst_video_codec_state_unref(state); #if GST_CHECK_VERSION(1,1,0) + vis = *vi; + if (GST_VIDEO_INFO_FORMAT(vi) == GST_VIDEO_FORMAT_ENCODED) { + /* XXX: this is a workaround until auto-plugging is fixed when + format=ENCODED + memory:VASurface caps feature are provided. + Meanwhile, providing a random format here works but this is + a terribly wrong thing per se. */ + gst_video_info_set_format(&vis, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); + } state->caps = gst_video_info_to_caps(&vis); #else /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not From 367944ba322f66ecb7435583fcde7663f853aa40 Mon Sep 17 00:00:00 2001 From: XuGuangxin Date: Thu, 29 Aug 2013 14:12:10 +0800 Subject: [PATCH 1376/3781] vaapidecode: drop decode timeout, always wait for a free surface. vaapidecode used to wait up to one second past the expected time of presentation for the last decoded frame. This is not realistic in practice when it comes to video pause/resume. Changed behaviour to unconditionnally wait for a free VA surface prior to continuing the decoding. The decode task will continue pushing the output frames to the downstream element while also reporting errors at the same time to the main thread. https://bugzilla.gnome.org/show_bug.cgi?id=707108 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 63 ++++++++++---------------------------- gst/vaapi/gstvaapidecode.h | 3 +- 2 files changed, 17 insertions(+), 49 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 27da3c5bf6..d2c149f529 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -237,46 +237,32 @@ gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstVaapiDecoderStatus status; GstFlowReturn ret; - gint64 end_time; - if (decode->render_time_base) - end_time = decode->render_time_base; - else - end_time = g_get_monotonic_time(); - end_time += GST_TIME_AS_USECONDS(decode->last_buffer_time); - end_time += G_TIME_SPAN_SECOND; + ret = g_atomic_int_get(&decode->decoder_loop_status); + if (ret != GST_FLOW_OK) + return ret; /* Decode current frame */ for (;;) { status = gst_vaapi_decoder_decode(decode->decoder, frame); if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { - gboolean was_signalled; GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); g_mutex_lock(&decode->decoder_mutex); - was_signalled = g_cond_wait_until( - &decode->decoder_ready, - &decode->decoder_mutex, - end_time - ); + g_cond_wait(&decode->decoder_ready, &decode->decoder_mutex); g_mutex_unlock(&decode->decoder_mutex); GST_VIDEO_DECODER_STREAM_LOCK(vdec); - if (was_signalled) - continue; - goto error_decode_timeout; + continue; } if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto error_decode; break; } - return GST_FLOW_OK; + + /* Try to report back early any error that occured in the decode task */ + ret = g_atomic_int_get(&decode->decoder_loop_status); + return ret; /* ERRORS */ -error_decode_timeout: - { - GST_WARNING("decode timeout. Decoder required a VA surface but none " - "got available within one second"); - return GST_FLOW_EOS; - } error_decode: { GST_ERROR("decode error %d", status); @@ -287,7 +273,7 @@ error_decode: ret = GST_FLOW_NOT_SUPPORTED; break; default: - ret = GST_FLOW_EOS; + ret = GST_FLOW_ERROR; break; } gst_video_decoder_drop_frame(vdec, frame); @@ -370,22 +356,6 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec) if (ret != GST_FLOW_OK) goto error_commit_buffer; - /* Estimate when this frame would no longer be needed for rendering */ - if (GST_CLOCK_TIME_IS_VALID(out_frame->pts)) { - if (!decode->render_time_base) - decode->render_time_base = g_get_monotonic_time() - - GST_TIME_AS_USECONDS(out_frame->pts); - decode->last_buffer_time = out_frame->pts; - if (GST_CLOCK_TIME_IS_VALID(out_frame->duration)) - decode->last_buffer_time += out_frame->duration; - else - decode->last_buffer_time += GST_SECOND; - } - else { - decode->render_time_base = 0; - decode->last_buffer_time = 0; - } - gst_video_codec_frame_unref(out_frame); return GST_FLOW_OK; @@ -400,7 +370,7 @@ error_create_buffer: GST_VAAPI_ID_ARGS(surface_id)); gst_video_decoder_drop_frame(vdec, out_frame); gst_video_codec_frame_unref(out_frame); - return GST_FLOW_EOS; + return GST_FLOW_ERROR; } #if GST_CHECK_VERSION(1,0,0) error_get_meta: @@ -408,7 +378,7 @@ error_get_meta: GST_ERROR("failed to get vaapi video meta attached to video buffer"); gst_video_decoder_drop_frame(vdec, out_frame); gst_video_codec_frame_unref(out_frame); - return GST_FLOW_EOS; + return GST_FLOW_ERROR; } #endif error_commit_buffer: @@ -416,7 +386,7 @@ error_commit_buffer: if (ret != GST_FLOW_FLUSHING) GST_ERROR("video sink rejected the video buffer (error %d)", ret); gst_video_codec_frame_unref(out_frame); - return GST_FLOW_EOS; + return ret; } } @@ -442,6 +412,8 @@ gst_vaapidecode_decode_loop(GstVaapiDecode *decode) ret = gst_vaapidecode_push_decoded_frame(vdec); if (ret == GST_FLOW_OK) return; + g_atomic_int_compare_and_exchange(&decode->decoder_loop_status, + GST_FLOW_OK, ret); /* If invoked from gst_vaapidecode_finish(), then return right away no matter the errors, or the GstVaapiDecoder needs further @@ -667,8 +639,6 @@ gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) /* Reset timers if hard reset was requested (e.g. seek) */ if (hard) { - decode->render_time_base = 0; - decode->last_buffer_time = 0; } /* Only reset decoder if codec type changed */ @@ -960,8 +930,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode) decode->decoder = NULL; decode->decoder_caps = NULL; decode->allowed_caps = NULL; - decode->render_time_base = 0; - decode->last_buffer_time = 0; + decode->decoder_loop_status = GST_FLOW_OK; g_mutex_init(&decode->decoder_mutex); g_cond_init(&decode->decoder_ready); diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 161937bb6b..bf8b9fd6e0 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -72,12 +72,11 @@ struct _GstVaapiDecode { GstVaapiDecoder *decoder; GMutex decoder_mutex; GCond decoder_ready; + volatile gint decoder_loop_status; volatile gboolean decoder_finish; GCond decoder_finish_done; GstCaps *decoder_caps; GstCaps *allowed_caps; - gint64 render_time_base; - GstClockTime last_buffer_time; guint current_frame_size; guint has_texture_upload_meta : 1; }; From 6e85f08e33db4a227e4c9c373926a156698e5403 Mon Sep 17 00:00:00 2001 From: XuGuangxin Date: Thu, 29 Aug 2013 14:12:10 +0800 Subject: [PATCH 1377/3781] vaapidecode: fix hard reset for seek cases. Fix hard reset for seek cases by flushing the GstVaapiDecoder queue and completely purge any decoded output frame that may come out from it. At this stage, the GstVaapiDecoder shall be in a complete clean state to start decoding over new buffers. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d2c149f529..4f99170a58 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -639,6 +639,21 @@ gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) /* Reset timers if hard reset was requested (e.g. seek) */ if (hard) { + GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); + GstVideoCodecFrame *out_frame = NULL; + + gst_vaapi_decoder_flush(decode->decoder); + GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); + gst_pad_stop_task(decode->srcpad); + GST_VIDEO_DECODER_STREAM_LOCK(vdec); + decode->decoder_loop_status = GST_FLOW_OK; + + /* Purge all decoded frames as we don't need them (e.g. seek) */ + while (gst_vaapi_decoder_get_frame_with_timeout(decode->decoder, + &out_frame, 0) == GST_VAAPI_DECODER_STATUS_SUCCESS) { + gst_video_codec_frame_unref(out_frame); + out_frame = NULL; + } } /* Only reset decoder if codec type changed */ From af4785b722a0e844f7aee91407e08feba15abb70 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Nov 2013 19:21:05 +0100 Subject: [PATCH 1378/3781] vaapidecode: fix dead-locks with decoder task. Review all interactions between the main video decoder stream thread and the decode task to derive a correct sequence of operations for decoding. Also avoid extra atomic operations that become implicit under the GstVideoDecoder stream lock. --- gst/vaapi/gstvaapidecode.c | 50 +++++++++++++++++++++++++------------- gst/vaapi/gstvaapidecode.h | 2 +- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4f99170a58..b53f8fa804 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -238,10 +238,6 @@ gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) GstVaapiDecoderStatus status; GstFlowReturn ret; - ret = g_atomic_int_get(&decode->decoder_loop_status); - if (ret != GST_FLOW_OK) - return ret; - /* Decode current frame */ for (;;) { status = gst_vaapi_decoder_decode(decode->decoder, frame); @@ -251,6 +247,8 @@ gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) g_cond_wait(&decode->decoder_ready, &decode->decoder_mutex); g_mutex_unlock(&decode->decoder_mutex); GST_VIDEO_DECODER_STREAM_LOCK(vdec); + if (decode->decoder_loop_status < 0) + goto error_decode_loop; continue; } if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) @@ -259,10 +257,17 @@ gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) } /* Try to report back early any error that occured in the decode task */ - ret = g_atomic_int_get(&decode->decoder_loop_status); - return ret; + GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); + GST_VIDEO_DECODER_STREAM_LOCK(vdec); + return decode->decoder_loop_status; /* ERRORS */ +error_decode_loop: + { + GST_ERROR("decode loop error %d", decode->decoder_loop_status); + gst_video_decoder_drop_frame(vdec, frame); + return decode->decoder_loop_status; + } error_decode: { GST_ERROR("decode error %d", status); @@ -282,12 +287,11 @@ error_decode: } static GstFlowReturn -gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec) +gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec, + GstVideoCodecFrame *out_frame) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstVaapiSurfaceProxy *proxy; - GstVaapiDecoderStatus status; - GstVideoCodecFrame *out_frame; GstFlowReturn ret; #if GST_CHECK_VERSION(1,0,0) const GstVaapiRectangle *crop_rect; @@ -295,11 +299,6 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec) guint flags; #endif - status = gst_vaapi_decoder_get_frame_with_timeout(decode->decoder, - &out_frame, 100000); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return GST_VIDEO_DECODER_FLOW_NEED_DATA; - if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(out_frame)) { proxy = gst_video_codec_frame_get_user_data(out_frame); @@ -407,13 +406,30 @@ static void gst_vaapidecode_decode_loop(GstVaapiDecode *decode) { GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); + GstVaapiDecoderStatus status; + GstVideoCodecFrame *out_frame; GstFlowReturn ret; - ret = gst_vaapidecode_push_decoded_frame(vdec); + status = gst_vaapi_decoder_get_frame_with_timeout(decode->decoder, + &out_frame, 100000); + + GST_VIDEO_DECODER_STREAM_LOCK(vdec); + switch (status) { + case GST_VAAPI_DECODER_STATUS_SUCCESS: + ret = gst_vaapidecode_push_decoded_frame(vdec, out_frame); + break; + case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: + ret = GST_VIDEO_DECODER_FLOW_NEED_DATA; + break; + default: + ret = GST_FLOW_ERROR; + break; + } + decode->decoder_loop_status = ret; + GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); + if (ret == GST_FLOW_OK) return; - g_atomic_int_compare_and_exchange(&decode->decoder_loop_status, - GST_FLOW_OK, ret); /* If invoked from gst_vaapidecode_finish(), then return right away no matter the errors, or the GstVaapiDecoder needs further diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index bf8b9fd6e0..da4244b5a4 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -72,7 +72,7 @@ struct _GstVaapiDecode { GstVaapiDecoder *decoder; GMutex decoder_mutex; GCond decoder_ready; - volatile gint decoder_loop_status; + GstFlowReturn decoder_loop_status; volatile gboolean decoder_finish; GCond decoder_finish_done; GstCaps *decoder_caps; From a6436f27d5103cf01e180f1100a9ccc8a6bbaa87 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Nov 2013 11:01:41 +0100 Subject: [PATCH 1379/3781] vaapidecode: fix decoder flush. There are situations where gst_video_decoder_flush() is called, and this subsequently produces a gst_video_decoder_reset() that kills the currently active GstVideoCodecFrame. This means that it no longer exists by the time we reach GstVideoDecoder::finish() callback, thus possibly resulting in a crash if we assumed spare data was still available for decode (current_frame_size > 0). Try to honour GstVideoDecoder::reset() behaviour from GStreamer 1.0 that means a flush, thus performing the actual operations there like calling gst_video_decoder_have_frame() if pending data is available. --- gst/vaapi/gstvaapidecode.c | 44 ++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b53f8fa804..510866d78e 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -446,20 +446,40 @@ gst_vaapidecode_decode_loop(GstVaapiDecode *decode) gst_pad_pause_task(decode->srcpad); } -static GstFlowReturn -gst_vaapidecode_finish(GstVideoDecoder *vdec) +static gboolean +gst_vaapidecode_flush(GstVideoDecoder *vdec) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstVaapiDecoderStatus status; /* If there is something in GstVideoDecoder's output adapter, then submit the frame for decoding */ - if (decode->current_frame_size) + if (decode->current_frame_size) { gst_video_decoder_have_frame(vdec); + decode->current_frame_size = 0; + } status = gst_vaapi_decoder_flush(decode->decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto error_flush; + return TRUE; + + /* ERRORS */ +error_flush: + { + GST_ERROR("failed to flush decoder (status %d)", status); + return FALSE; + } +} + +static GstFlowReturn +gst_vaapidecode_finish(GstVideoDecoder *vdec) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + GstFlowReturn ret = GST_FLOW_OK; + + if (!gst_vaapidecode_flush(vdec)) + ret = GST_FLOW_OK; /* Make sure the decode loop function has a chance to return, thus possibly unlocking gst_video_decoder_finish_frame() */ @@ -470,14 +490,7 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) g_mutex_unlock(&decode->decoder_mutex); gst_pad_stop_task(decode->srcpad); GST_VIDEO_DECODER_STREAM_LOCK(vdec); - return GST_FLOW_OK; - - /* ERRORS */ -error_flush: - { - GST_ERROR("failed to flush decoder (status %d)", status); - return GST_FLOW_EOS; - } + return ret; } #if GST_CHECK_VERSION(1,0,0) @@ -653,6 +666,9 @@ gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) decode->has_texture_upload_meta = FALSE; + /* Reset tracked frame size */ + decode->current_frame_size = 0; + /* Reset timers if hard reset was requested (e.g. seek) */ if (hard) { GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); @@ -681,9 +697,6 @@ gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) return TRUE; } - /* Reset tracked frame size */ - decode->current_frame_size = 0; - gst_vaapidecode_destroy(decode); return gst_vaapidecode_create(decode, caps); } @@ -740,6 +753,9 @@ gst_vaapidecode_reset(GstVideoDecoder *vdec, gboolean hard) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + /* In GStreamer 1.0 context, this means a flush */ + if (decode->decoder && !hard && !gst_vaapidecode_flush(vdec)) + return FALSE; return gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, hard); } From f9d0d6e2720fa8b9004e839a5f9049c3d5cd3f32 Mon Sep 17 00:00:00 2001 From: XuGuangxin Date: Thu, 29 Aug 2013 14:04:06 +0800 Subject: [PATCH 1380/3781] libs: robustify decoder objects and surface proxy initialization. Fix GstVaapiPicture, GstVaapiSlice and GstVaapiSurfaceProxy initialization sequences to have the expected default values set beforehand in case of an error raising up further during creation. i.e. make it possible to cleanly destroy those partially initialized objects. https://bugzilla.gnome.org/show_bug.cgi?id=707108 Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 6 ++++-- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 218b51213e..225dcfbb71 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -103,6 +103,8 @@ gst_vaapi_picture_create( { 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); @@ -158,7 +160,6 @@ gst_vaapi_picture_create( picture->surface = GST_VAAPI_SURFACE_PROXY_SURFACE(picture->proxy); picture->surface_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID(picture->proxy); - picture->param_id = VA_INVALID_ID; success = vaapi_create_buffer( GET_VA_DISPLAY(picture), GET_VA_CONTEXT(picture), @@ -418,7 +419,9 @@ gst_vaapi_slice_create( 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), @@ -431,7 +434,6 @@ gst_vaapi_slice_create( if (!success) return FALSE; - slice->param_id = VA_INVALID_ID; success = vaapi_create_buffer( GET_VA_DISPLAY(slice), GET_VA_CONTEXT(slice), diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 9a7f2c4bc5..f6981038fe 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -70,13 +70,13 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) if (!proxy) return NULL; + proxy->destroy_func = NULL; proxy->pool = gst_vaapi_video_pool_ref(pool); proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool); if (!proxy->surface) goto error; proxy->timestamp = GST_CLOCK_TIME_NONE; proxy->duration = GST_CLOCK_TIME_NONE; - proxy->destroy_func = NULL; proxy->has_crop_rect = FALSE; gst_vaapi_object_ref(proxy->surface); return proxy; From f9ee8703cfdea8e9ac69dd957be20d6732a8615f Mon Sep 17 00:00:00 2001 From: XuGuangxin Date: Thu, 29 Aug 2013 13:44:22 +0800 Subject: [PATCH 1381/3781] libs: make GstVaapiVideoPool thread-safe. https://bugzilla.gnome.org/show_bug.cgi?id=707108 Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapivideopool.c | 114 ++++++++++++++++---- gst-libs/gst/vaapi/gstvaapivideopool_priv.h | 1 + 2 files changed, 93 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 4dc523b6c5..97e0bb2b14 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -64,6 +64,7 @@ gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display, pool->capacity = 0; g_queue_init(&pool->free_objects); + g_mutex_init(&pool->mutex); } void @@ -73,6 +74,7 @@ gst_vaapi_video_pool_finalize(GstVaapiVideoPool *pool) g_queue_foreach(&pool->free_objects, (GFunc)gst_vaapi_object_unref, NULL); g_queue_clear(&pool->free_objects); gst_vaapi_display_replace(&pool->display, NULL); + g_mutex_clear(&pool->mutex); } /** @@ -163,13 +165,11 @@ gst_vaapi_video_pool_get_object_type(GstVaapiVideoPool *pool) * * Return value: a possibly newly allocated object, or %NULL on error */ -gpointer -gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) +static gpointer +gst_vaapi_video_pool_get_object_unlocked(GstVaapiVideoPool *pool) { gpointer object; - g_return_val_if_fail(pool != NULL, NULL); - if (pool->capacity && pool->used_count >= pool->capacity) return NULL; @@ -185,6 +185,19 @@ gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) return gst_vaapi_object_ref(object); } +gpointer +gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) +{ + gpointer object; + + g_return_val_if_fail(pool != NULL, NULL); + + g_mutex_lock(&pool->mutex); + object = gst_vaapi_video_pool_get_object_unlocked(pool); + g_mutex_unlock(&pool->mutex); + return object; +} + /** * gst_vaapi_video_pool_put_object: * @pool: a #GstVaapiVideoPool @@ -195,14 +208,12 @@ gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) * Calling this function with an arbitrary object yields undefined * behaviour. */ -void -gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) +static void +gst_vaapi_video_pool_put_object_unlocked(GstVaapiVideoPool *pool, + gpointer object) { GList *elem; - g_return_if_fail(pool != NULL); - g_return_if_fail(object != NULL); - elem = g_list_find(pool->used_objects, object); if (!elem) return; @@ -213,6 +224,17 @@ gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) g_queue_push_tail(&pool->free_objects, object); } +void +gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) +{ + g_return_if_fail(pool != NULL); + g_return_if_fail(object != NULL); + + g_mutex_lock(&pool->mutex); + gst_vaapi_video_pool_put_object_unlocked(pool, object); + g_mutex_unlock(&pool->mutex); +} + /** * gst_vaapi_video_pool_add_object: * @pool: a #GstVaapiVideoPool @@ -224,14 +246,26 @@ gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) * * Return value: %TRUE on success. */ +static inline gboolean +gst_vaapi_video_pool_add_object_unlocked(GstVaapiVideoPool *pool, + gpointer object) +{ + g_queue_push_tail(&pool->free_objects, gst_vaapi_object_ref(object)); + return TRUE; +} + gboolean gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object) { + gboolean success; + g_return_val_if_fail(pool != NULL, FALSE); g_return_val_if_fail(object != NULL, FALSE); - g_queue_push_tail(&pool->free_objects, gst_vaapi_object_ref(object)); - return TRUE; + g_mutex_lock(&pool->mutex); + success = gst_vaapi_video_pool_add_object_unlocked(pool, object); + g_mutex_unlock(&pool->mutex); + return success; } /** @@ -245,21 +279,33 @@ gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object) * * Return value: %TRUE on success. */ -gboolean -gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects) +static gboolean +gst_vaapi_video_pool_add_objects_unlocked(GstVaapiVideoPool *pool, + GPtrArray *objects) { guint i; - g_return_val_if_fail(pool != NULL, FALSE); - for (i = 0; i < objects->len; i++) { gpointer const object = g_ptr_array_index(objects, i); - if (!gst_vaapi_video_pool_add_object(pool, object)) + if (!gst_vaapi_video_pool_add_object_unlocked(pool, object)) return FALSE; } return TRUE; } +gboolean +gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects) +{ + gboolean success; + + g_return_val_if_fail(pool != NULL, FALSE); + + g_mutex_lock(&pool->mutex); + success = gst_vaapi_video_pool_add_objects_unlocked(pool, objects); + g_mutex_unlock(&pool->mutex); + return success; +} + /** * gst_vaapi_video_pool_get_size: * @pool: a #GstVaapiVideoPool @@ -271,9 +317,14 @@ gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects) guint gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool) { + guint size; + g_return_val_if_fail(pool != NULL, 0); - return g_queue_get_length(&pool->free_objects); + g_mutex_lock(&pool->mutex); + size = g_queue_get_length(&pool->free_objects); + g_mutex_unlock(&pool->mutex); + return size; } /** @@ -288,13 +339,11 @@ gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool) * * Return value: %TRUE on success */ -gboolean -gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n) +static gboolean +gst_vaapi_video_pool_reserve_unlocked(GstVaapiVideoPool *pool, guint n) { guint i, num_allocated; - g_return_val_if_fail(pool != NULL, 0); - num_allocated = gst_vaapi_video_pool_get_size(pool) + pool->used_count; if (n < num_allocated) return TRUE; @@ -311,6 +360,19 @@ gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n) return TRUE; } +gboolean +gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n) +{ + gboolean success; + + g_return_val_if_fail(pool != NULL, 0); + + g_mutex_lock(&pool->mutex); + success = gst_vaapi_video_pool_reserve_unlocked(pool, n); + g_mutex_unlock(&pool->mutex); + return success; +} + /** * gst_vaapi_video_pool_get_capacity: * @pool: a #GstVaapiVideoPool @@ -323,9 +385,15 @@ gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n) guint gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool) { + guint capacity; + g_return_val_if_fail(pool != NULL, 0); - return pool->capacity; + g_mutex_lock(&pool->mutex); + capacity = pool->capacity; + g_mutex_unlock(&pool->mutex); + + return capacity; } /** @@ -340,5 +408,7 @@ gst_vaapi_video_pool_set_capacity(GstVaapiVideoPool *pool, guint capacity) { g_return_if_fail(pool != NULL); + g_mutex_lock(&pool->mutex); pool->capacity = capacity; + g_mutex_unlock(&pool->mutex); } diff --git a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h index 8da750e9be..36088b343b 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h @@ -50,6 +50,7 @@ struct _GstVaapiVideoPool { GList *used_objects; guint used_count; guint capacity; + GMutex mutex; }; /** From a1189301c9816936b070150691114dec2a053104 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Nov 2013 15:10:17 +0100 Subject: [PATCH 1382/3781] libs: fix GstVaapiSurfaceProxy destroy notify call site. The user-defined destroy notify function is meant to be called only when the surface proxy was fully released, i.e. once it actually released the VA surface back to the underlying pool. --- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index f6981038fe..f9e488a153 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -36,9 +36,6 @@ static void gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) { - if (proxy->destroy_func) - proxy->destroy_func(proxy->destroy_data); - if (proxy->surface) { if (proxy->pool) gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface); @@ -46,6 +43,10 @@ gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) proxy->surface = NULL; } gst_vaapi_video_pool_replace(&proxy->pool, 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 * From 152ffb52d2f85fc358f4c97ad061b4831611666a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Nov 2013 17:20:28 +0100 Subject: [PATCH 1383/3781] filter: add helpers to check for supported/active operation. Add a couple of helper functions: - gst_vaapi_filter_has_operation(): checks whether the VA driver advertises support for the supplied operation ; - gst_vaapi_filter_use_operation(): checks whether the supplied operation was already enabled to its non-default value. --- docs/reference/libs/libs-sections.txt | 2 ++ gst-libs/gst/vaapi/gstvaapifilter.c | 47 +++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 6 ++++ 3 files changed, 55 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index cc00f43012..e0752b73db 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -384,6 +384,8 @@ gst_vaapi_filter_unref gst_vaapi_filter_replace gst_vaapi_filter_get_operations gst_vaapi_filter_get_formats +gst_vaapi_filter_has_operation +gst_vaapi_filter_use_operation gst_vaapi_filter_set_operation gst_vaapi_filter_set_format gst_vaapi_filter_set_cropping_rectangle diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index e185f6ea24..b6e90733e0 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1116,6 +1116,53 @@ gst_vaapi_filter_get_operations(GstVaapiFilter *filter) return get_operations(filter); } +/** + * gst_vaapi_filter_has_operation: + * @filter: a #GstVaapiFilter + * @op: a #GstVaapiFilterOp + * + * Determines whether the underlying VA driver advertises support for + * the supplied operation @op. + * + * Return value: %TRUE if the specified operation may be supported by + * the underlying hardware, %FALSE otherwise + */ +gboolean +gst_vaapi_filter_has_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + return find_operation(filter, op) != NULL; +} + +/** + * gst_vaapi_filter_use_operation: + * @filter: a #GstVaapiFilter + * @op: a #GstVaapiFilterOp + * + * Determines whether the supplied operation @op was already enabled + * through a prior call to gst_vaapi_filter_set_operation() or any + * other operation-specific function. + * + * Note: should an operation be set to its default value, this means + * that it is actually not enabled. + * + * Return value: %TRUE if the specified operation was already enabled, + * %FALSE otherwise + */ +gboolean +gst_vaapi_filter_use_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) +{ + GstVaapiFilterOpData *op_data; + + g_return_val_if_fail(filter != NULL, FALSE); + + op_data = find_operation(filter, op); + if (!op_data) + return FALSE; + return op_data->is_enabled; +} + /** * gst_vaapi_filter_set_operation: * @filter: a #GstVaapiFilter diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 2ea44052b9..5d9ec6598a 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -149,6 +149,12 @@ gst_vaapi_filter_replace(GstVaapiFilter **old_filter_ptr, 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); From 06c7fde8e07958874214c33740f99912c646401d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Nov 2013 18:44:46 +0100 Subject: [PATCH 1384/3781] filter: fix semantics of deinterlacing flags. Fix deinterlacing flags to make more sense. The TFF (top-field-first) flag is meant to specify the organization of reference frames used in advanced deinterlacing modes. Introduce the more explicit flag TOPFIELD to specify that the top-field of the supplied input surface is to be used for deinterlacing. Conversely, if not set, this means that the bottom field of the supplied input surface will be used instead. --- gst-libs/gst/vaapi/gstvaapifilter.c | 2 ++ gst-libs/gst/vaapi/gstvaapifilter.h | 11 +++++++++-- gst-libs/gst/vaapi/gstvaapiutils.c | 8 ++++---- gst/vaapi/gstvaapipostproc.c | 4 ++-- tests/test-filter.c | 8 +++++--- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index b6e90733e0..697b8a1c6f 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -112,6 +112,8 @@ gst_vaapi_deinterlace_flags_get_type(void) "Top-field first", "top-field-first" }, { GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD, "One field", "one-field" }, + { GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD, + "Top field", "top-field" }, { 0, NULL, NULL } }; diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 5d9ec6598a..85bbe28ebb 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -109,16 +109,23 @@ typedef enum { /** * GstVaapiDeinterlaceFlags: * @GST_VAAPI_DEINTERLACE_FLAG_TFF: Top-field first. If this flag is - * not set, then bottom-field first order is assumed. + * 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 fields. + * 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_DEINTERLACE_METHOD \ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index a0b0d0a712..9fc4c68639 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -471,11 +471,11 @@ from_GstVaapiDeinterlaceFlags(guint flags) if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF)) va_flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST; - if (flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD) { + if (flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD) va_flags |= VA_DEINTERLACING_ONE_FIELD; - if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF)) - va_flags |= VA_DEINTERLACING_BOTTOM_FIELD; - } + + if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD)) + va_flags |= VA_DEINTERLACING_BOTTOM_FIELD; #endif return va_flags; } diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 99b400ccf6..69cfa11415 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -449,7 +449,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, if (deint) { GstVaapiDeinterlaceMethod deint_method; - deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TFF : 0); + deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD : 0); if (!set_best_deint_method(postproc, flags, &deint_method)) goto error_op_deinterlace; if (deint_method != postproc->deinterlace_method) { @@ -482,7 +482,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); if (deint) { - deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TFF); + deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD); if (!gst_vaapi_filter_set_deinterlacing(postproc->filter, postproc->deinterlace_method, deint_flags)) goto error_op_deinterlace; diff --git a/tests/test-filter.c b/tests/test-filter.c index a96c0335e8..7bb6219c1b 100755 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -291,7 +291,9 @@ end: static inline gboolean parse_deinterlace(const gchar *str, GstVaapiDeinterlaceMethod *deinterlace_ptr) { - return parse_enum(str, GST_VAAPI_TYPE_DEINTERLACE_METHOD, + g_return_val_if_fail(deinterlace_ptr != NULL, FALSE); + + return str && parse_enum(str, GST_VAAPI_TYPE_DEINTERLACE_METHOD, GST_VAAPI_DEINTERLACE_METHOD_NONE, (gint *)deinterlace_ptr); } @@ -390,7 +392,7 @@ main(int argc, char *argv[]) g_error("failed to set deinterlacing method"); } else if (deinterlace_flags) { - if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TFF) + if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD) filter_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; else filter_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; @@ -401,7 +403,7 @@ main(int argc, char *argv[]) if (!(deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD)) surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD | GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; - else if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TFF) + else if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD) surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; else surface_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; From 5a9e1695040f3f9cec6bb8cfb06bd83c2fd43b0a Mon Sep 17 00:00:00 2001 From: Halley Zhao Date: Fri, 1 Nov 2013 10:31:13 +0800 Subject: [PATCH 1385/3781] filter: add helper to specify references for deinterlacing. Add gst_vaapi_fitler_set_deinterlacing_references() API to submit the list of surfaces used for forward or backward reference in advanced deinterlacing mode, e.g. Motion-Adaptive, Motion-Compensated. The list of surfaces used as deinterlacing references shall be live until the next call to gst_vaapi_filter_process(). Signed-off-by: Gwenole Beauchesne --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapifilter.c | 136 ++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 5 + 3 files changed, 142 insertions(+) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index e0752b73db..b503d958a7 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -397,6 +397,7 @@ gst_vaapi_filter_set_saturation gst_vaapi_filter_set_brightness gst_vaapi_filter_set_saturation gst_vaapi_filter_set_deinterlacing +gst_vaapi_filter_set_deinterlacing_references GST_VAAPI_FILTER diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 697b8a1c6f..5ca28865ba 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -63,6 +63,8 @@ struct _GstVaapiFilter { GPtrArray *operations; GstVideoFormat format; GArray *formats; + GArray *forward_references; + GArray *backward_references; GstVaapiRectangle crop_rect; GstVaapiRectangle target_rect; guint use_crop_rect : 1; @@ -851,6 +853,33 @@ op_set_deinterlace(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, return success; } +static gboolean +deint_refs_set(GArray *refs, GstVaapiSurface **surfaces, guint num_surfaces) +{ + guint i; + + if (num_surfaces > 0 && !surfaces) + return FALSE; + + for (i = 0; i < num_surfaces; i++) + g_array_append_val(refs, GST_VAAPI_OBJECT_ID(surfaces[i])); + return TRUE; +} + +static void +deint_refs_clear(GArray *refs) +{ + if (refs->len > 0) + g_array_remove_range(refs, 0, refs->len); +} + +static inline void +deint_refs_clear_all(GstVaapiFilter *filter) +{ + deint_refs_clear(filter->forward_references); + deint_refs_clear(filter->backward_references); +} + /* ------------------------------------------------------------------------- */ /* --- Surface Formats --- */ /* ------------------------------------------------------------------------- */ @@ -952,6 +981,16 @@ gst_vaapi_filter_init(GstVaapiFilter *filter, GstVaapiDisplay *display) filter->va_context = VA_INVALID_ID; filter->format = DEFAULT_FORMAT; + filter->forward_references = + g_array_sized_new(FALSE, FALSE, sizeof(VASurfaceID), 4); + if (!filter->forward_references) + return FALSE; + + filter->backward_references = + g_array_sized_new(FALSE, FALSE, sizeof(VASurfaceID), 4); + if (!filter->backward_references) + return FALSE; + if (!GST_VAAPI_DISPLAY_HAS_VPP(display)) return FALSE; @@ -995,6 +1034,16 @@ gst_vaapi_filter_finalize(GstVaapiFilter *filter) GST_VAAPI_DISPLAY_UNLOCK(filter->display); gst_vaapi_display_replace(&filter->display, NULL); + if (filter->forward_references) { + g_array_unref(filter->forward_references); + filter->backward_references = NULL; + } + + if (filter->backward_references) { + g_array_unref(filter->backward_references); + filter->backward_references = NULL; + } + if (filter->formats) { g_array_unref(filter->formats); filter->formats = NULL; @@ -1252,6 +1301,7 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter, VAProcPipelineParameterBuffer *pipeline_param = NULL; VABufferID pipeline_param_buf_id; VABufferID filters[N_PROPERTIES]; + VAProcPipelineCaps pipeline_caps; guint i, num_filters = 0; VAStatus va_status; VARectangle src_rect, dst_rect; @@ -1316,6 +1366,12 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter, filters[num_filters++] = op_data->va_buffer; } + /* Validate pipeline caps */ + va_status = vaQueryVideoProcPipelineCaps(filter->va_display, + filter->va_context, filters, num_filters, &pipeline_caps); + if (!vaapi_check_status(va_status, "vaQueryVideoProcPipelineCaps()")) + goto error; + if (!vaapi_create_buffer(filter->va_display, filter->va_context, VAProcPipelineParameterBufferType, sizeof(*pipeline_param), NULL, &pipeline_param_buf_id, (gpointer *)&pipeline_param)) @@ -1332,6 +1388,31 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter, pipeline_param->filters = filters; pipeline_param->num_filters = num_filters; + // Reference frames for advanced deinterlacing + if (filter->forward_references->len > 0) { + pipeline_param->forward_references = (VASurfaceID *) + filter->forward_references->data; + pipeline_param->num_forward_references = + MIN(filter->forward_references->len, + pipeline_caps.num_forward_references); + } + else { + pipeline_param->forward_references = NULL; + pipeline_param->num_forward_references = 0; + } + + if (filter->backward_references->len > 0) { + pipeline_param->backward_references = (VASurfaceID *) + filter->backward_references->data; + pipeline_param->num_backward_references = + MIN(filter->backward_references->len, + pipeline_caps.num_backward_references); + } + else { + pipeline_param->backward_references = NULL; + pipeline_param->num_backward_references = 0; + } + vaapi_unmap_buffer(filter->va_display, pipeline_param_buf_id, NULL); va_status = vaBeginPicture(filter->va_display, filter->va_context, @@ -1347,10 +1428,13 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter, va_status = vaEndPicture(filter->va_display, filter->va_context); if (!vaapi_check_status(va_status, "vaEndPicture()")) goto error; + + deint_refs_clear_all(filter); return GST_VAAPI_FILTER_STATUS_SUCCESS; error: vaDestroyBuffer(filter->va_display, pipeline_param_buf_id); + deint_refs_clear_all(filter); return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED; #endif return GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_OPERATION; @@ -1605,3 +1689,55 @@ gst_vaapi_filter_set_deinterlacing(GstVaapiFilter *filter, find_operation(filter, GST_VAAPI_FILTER_OP_DEINTERLACING), method, flags); } + +/** + * gst_vaapi_filter_set_deinterlacing_references: + * @filter: a #GstVaapiFilter + * @forward_references: the set of #GstVaapiSurface objects used as + * forward references + * @num_forward_references: the number of elements in the + * @forward_references array + * @backward_references: the set of #GstVaapiSurface objects used as + * backward references + * @num_backward_references: the number of elements in the + * @backward_references array + * + * Specifies the list of surfaces used for forward or backward reference in + * advanced deinterlacing mode. The caller is responsible for maintaining + * the associated surfaces live until gst_vaapi_filter_process() completes. + * e.g. by holding an extra reference to the associated #GstVaapiSurfaceProxy. + * + * Temporal ordering is maintained as follows: the shorter index in + * either array is, the closest the matching surface is relatively to + * the current source surface to process. e.g. surface in + * @forward_references array index 0 represents the immediately + * preceding surface in display order, surface at index 1 is the one + * preceding surface at index 0, etc. + * + * The video processing filter will only use the recommended number of + * surfaces for backward and forward references. + * + * Note: the supplied lists of reference surfaces are not sticky. This + * means that they are only valid for the next gst_vaapi_filter_process() + * call, and thus needs to be submitted again for subsequent calls. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_deinterlacing_references(GstVaapiFilter *filter, + GstVaapiSurface **forward_references, guint num_forward_references, + GstVaapiSurface **backward_references, guint num_backward_references) +{ + g_return_val_if_fail(filter != NULL, FALSE); + + deint_refs_clear_all(filter); + + if (!deint_refs_set(filter->forward_references, forward_references, + num_forward_references)) + return FALSE; + + if (!deint_refs_set(filter->backward_references, backward_references, + num_backward_references)) + return FALSE; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 85bbe28ebb..9ed6436c9e 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -206,4 +206,9 @@ 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); + #endif /* GST_VAAPI_FILTER_H */ From a3af786c78080897b7811403429d7f0073f08a3b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Nov 2013 15:08:55 +0100 Subject: [PATCH 1386/3781] vaapipostproc: fix transform caps. Fix GstBaseTransform::transform_caps() implementation to always return the complete set of allowed sink pad caps (unfixated) even if the src pad caps we are getting are fixated. Rationale: there are just so many possible combinations, and it was wrong to provide a unique set anyway. As a side effect, this greatly simplifies the ability to derive src pad caps from fixated sink pad caps. --- gst/vaapi/gstvaapipostproc.c | 113 +++++++++++++++-------------------- 1 file changed, 47 insertions(+), 66 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 69cfa11415..acf32add65 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -905,80 +905,61 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, GstVideoFormat format; GstCaps *out_caps; guint width, height; - gint fps_n, fps_d, par_n, par_d; - if (!gst_caps_is_fixed(caps)) { - out_caps = NULL; - if (direction == GST_PAD_SINK) { - /* Generate the allowed set of caps on the src pad */ - if (ensure_allowed_srcpad_caps(postproc)) - out_caps = gst_caps_ref(postproc->allowed_srcpad_caps); - } - else { - /* Generate the allowed set of caps on the sink pad */ - if (ensure_allowed_sinkpad_caps(postproc)) - out_caps = gst_caps_ref(postproc->allowed_sinkpad_caps); - } - return out_caps; + /* Generate the sink pad caps, that could be fixated afterwards */ + if (direction == GST_PAD_SRC) { + if (!ensure_allowed_sinkpad_caps(postproc)) + return NULL; + return gst_caps_ref(postproc->allowed_sinkpad_caps); } - /* Generate the other pad caps, based on the current pad caps, as - specified by the direction argument */ + /* Generate complete set of src pad caps if non-fixated sink pad + caps are provided */ + if (!gst_caps_is_fixed(caps)) { + if (!ensure_allowed_srcpad_caps(postproc)) + return NULL; + return gst_caps_ref(postproc->allowed_srcpad_caps); + } + + /* Generate the expected src pad caps, from the current fixated + sink pad caps */ if (!gst_video_info_from_caps(&vi, caps)) return NULL; - format = GST_VIDEO_INFO_FORMAT(&vi); - if (format == GST_VIDEO_FORMAT_UNKNOWN) + // Set double framerate in interlaced mode + if (is_deinterlace_enabled(postproc, &vi)) { + gint fps_n = GST_VIDEO_INFO_FPS_N(&vi); + gint fps_d = GST_VIDEO_INFO_FPS_D(&vi); + if (!gst_util_fraction_multiply(fps_n, fps_d, 2, 1, &fps_n, &fps_d)) + return NULL; + GST_VIDEO_INFO_FPS_N(&vi) = fps_n; + GST_VIDEO_INFO_FPS_D(&vi) = fps_d; + } + + // Signal the other pad that we only generate progressive frames + GST_VIDEO_INFO_INTERLACE_MODE(&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; + + // Update size from user-specified parameters + format = GST_VIDEO_FORMAT_ENCODED; + find_best_size(postproc, &vi, &width, &height); + gst_video_info_set_format(&vi, format, width, height); + + /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not + reconstruct suitable caps for "encoded" video formats */ + out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); + if (!out_caps) return NULL; - fps_n = GST_VIDEO_INFO_FPS_N(&vi); - fps_d = GST_VIDEO_INFO_FPS_D(&vi); - if (direction == GST_PAD_SINK) { - if (is_deinterlace_enabled(postproc, &vi)) { - /* Set double framerate in interlaced mode */ - if (!gst_util_fraction_multiply(fps_n, fps_d, 2, 1, &fps_n, &fps_d)) - return NULL; - } - format = GST_VIDEO_FORMAT_ENCODED; - - /* Signal the other pad that we generate only progressive frames */ - GST_VIDEO_INFO_INTERLACE_MODE(&vi) = - GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; - - find_best_size(postproc, &vi, &width, &height); - gst_video_info_set_format(&vi, format, width, height); - } - else { - if (is_deinterlace_enabled(postproc, &vi)) { - /* Set half framerate in interlaced mode */ - if (!gst_util_fraction_multiply(fps_n, fps_d, 1, 2, &fps_n, &fps_d)) - return NULL; - } - } - - if (format != GST_VIDEO_FORMAT_ENCODED) { - out_caps = gst_video_info_to_caps(&vi); - if (!out_caps) - return NULL; - } - else { - /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not - reconstruct suitable caps for "encoded" video formats */ - out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); - if (!out_caps) - return NULL; - - par_n = GST_VIDEO_INFO_PAR_N(&vi); - par_d = GST_VIDEO_INFO_PAR_D(&vi); - gst_caps_set_simple(out_caps, - "type", G_TYPE_STRING, "vaapi", - "opengl", G_TYPE_BOOLEAN, USE_GLX, - "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH(&vi), - "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT(&vi), - "framerate", GST_TYPE_FRACTION, fps_n, fps_d, - "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, - NULL); - } + gst_caps_set_simple(out_caps, + "type", G_TYPE_STRING, "vaapi", + "opengl", G_TYPE_BOOLEAN, USE_GLX, + "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH(&vi), + "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT(&vi), + "framerate", GST_TYPE_FRACTION, GST_VIDEO_INFO_FPS_N(&vi), + GST_VIDEO_INFO_FPS_D(&vi), + "pixel-aspect-ratio", GST_TYPE_FRACTION, GST_VIDEO_INFO_PAR_N(&vi), + GST_VIDEO_INFO_PAR_D(&vi), + NULL); gst_caps_set_interlaced(out_caps, &vi); return out_caps; From 49e2d040fa74411660a771724b9e70d02f4647ab Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Nov 2013 22:32:03 +0100 Subject: [PATCH 1387/3781] vaapipostproc: fix deinterlacing with VPP. Fix basic deinterlacing flags provided to gst_vaapi_set_deinterlacing() for the first field. Render flags were supplied instead of the actual deinterlacing flags (deint_flags). --- gst/vaapi/gstvaapipostproc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index acf32add65..6bcda3ffda 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -415,6 +415,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, GstClockTime timestamp; GstFlowReturn ret; GstBuffer *fieldbuf; + GstVaapiDeinterlaceMethod deint_method; guint flags, deint_flags; gboolean tff, deint; @@ -437,6 +438,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); /* First field */ + deint_method = postproc->deinterlace_method; if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) { fieldbuf = create_output_buffer(postproc); if (!fieldbuf) @@ -448,9 +450,8 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); if (deint) { - GstVaapiDeinterlaceMethod deint_method; deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD : 0); - if (!set_best_deint_method(postproc, flags, &deint_method)) + if (!set_best_deint_method(postproc, deint_flags, &deint_method)) goto error_op_deinterlace; if (deint_method != postproc->deinterlace_method) { GST_DEBUG("unsupported deinterlace-method %u. Using %u instead", @@ -484,7 +485,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, if (deint) { deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD); if (!gst_vaapi_filter_set_deinterlacing(postproc->filter, - postproc->deinterlace_method, deint_flags)) + deint_method, deint_flags)) goto error_op_deinterlace; } From c8bea66d33175967834c417450a04f0d11c93a23 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Nov 2013 19:52:56 +0100 Subject: [PATCH 1388/3781] vaapipostproc: add support for advanced deinterlacing. Add initial support for advanced deinterlacing. The history buffer size is arbitrarily set to 3 references for now. --- gst/vaapi/gstvaapipostproc.c | 67 ++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipostproc.h | 34 ++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6bcda3ffda..06ea5286c4 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -371,6 +371,51 @@ append_output_buffer_metadata(GstBuffer *outbuf, GstBuffer *inbuf, guint flags) 0, -1); } +static void +ds_reset(GstVaapiDeinterlaceState *ds) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) + gst_buffer_replace(&ds->buffers[i], NULL); + ds->buffers_index = 0; + ds->num_surfaces = 0; + ds->deint = FALSE; + ds->tff = FALSE; +} + +static void +ds_add_buffer(GstVaapiDeinterlaceState *ds, GstBuffer *buf) +{ + gst_buffer_replace(&ds->buffers[ds->buffers_index], buf); + ds->buffers_index = (ds->buffers_index + 1) % G_N_ELEMENTS(ds->buffers); +} + +static inline GstBuffer * +ds_get_buffer(GstVaapiDeinterlaceState *ds, guint index) +{ + const guint n = ds->buffers_index + G_N_ELEMENTS(ds->buffers) - index - 1; + return ds->buffers[n % G_N_ELEMENTS(ds->buffers)]; +} + +static void +ds_set_surfaces(GstVaapiDeinterlaceState *ds) +{ + GstVaapiVideoMeta *meta; + guint i; + + ds->num_surfaces = 0; + for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) { + GstBuffer * const buf = ds_get_buffer(ds, i); + if (!buf) + break; + + meta = gst_buffer_get_vaapi_video_meta(buf); + ds->surfaces[ds->num_surfaces++] = + gst_vaapi_video_meta_get_surface(meta); + } +} + static GstVaapiDeinterlaceMethod get_next_deint_method(GstVaapiDeinterlaceMethod deint_method) { @@ -409,6 +454,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf) { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + GstVaapiDeinterlaceState * const ds = &postproc->deinterlace_state; GstVaapiVideoMeta *inbuf_meta, *outbuf_meta; GstVaapiSurface *inbuf_surface, *outbuf_surface; GstVaapiFilterStatus status; @@ -433,6 +479,12 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, tff = GST_BUFFER_FLAG_IS_SET(inbuf, GST_VIDEO_BUFFER_FLAG_TFF); deint = is_interlaced_buffer(postproc, inbuf); + /* Drop references if deinterlacing conditions changed */ + if (deint != ds->deint || (ds->num_surfaces > 0 && tff != ds->tff)) + ds_reset(ds); + ds->deint = deint; + ds->tff = tff; + flags = gst_vaapi_video_meta_get_render_flags(inbuf_meta) & ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); @@ -451,8 +503,16 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, if (deint) { deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD : 0); + if (tff) + deint_flags |= GST_VAAPI_DEINTERLACE_FLAG_TFF; if (!set_best_deint_method(postproc, deint_flags, &deint_method)) goto error_op_deinterlace; + + ds_set_surfaces(ds); + if (!gst_vaapi_filter_set_deinterlacing_references(postproc->filter, + ds->surfaces, ds->num_surfaces, NULL, 0)) + goto error_op_deinterlace; + if (deint_method != postproc->deinterlace_method) { GST_DEBUG("unsupported deinterlace-method %u. Using %u instead", postproc->deinterlace_method, deint_method); @@ -484,9 +544,15 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, if (deint) { deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD); + if (tff) + deint_flags |= GST_VAAPI_DEINTERLACE_FLAG_TFF; if (!gst_vaapi_filter_set_deinterlacing(postproc->filter, deint_method, deint_flags)) goto error_op_deinterlace; + + if (!gst_vaapi_filter_set_deinterlacing_references(postproc->filter, + ds->surfaces, ds->num_surfaces, NULL, 0)) + goto error_op_deinterlace; } status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, @@ -502,6 +568,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, } gst_buffer_set_vaapi_video_meta(outbuf, outbuf_meta); gst_vaapi_video_meta_unref(outbuf_meta); + ds_add_buffer(ds, inbuf); return GST_FLOW_OK; /* ERRORS */ diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index b82f751748..7340c3f23a 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -57,6 +57,7 @@ G_BEGIN_DECLS typedef struct _GstVaapiPostproc GstVaapiPostproc; typedef struct _GstVaapiPostprocClass GstVaapiPostprocClass; +typedef struct _GstVaapiDeinterlaceState GstVaapiDeinterlaceState; /** * GstVaapiDeinterlaceMode: @@ -70,6 +71,18 @@ typedef enum { GST_VAAPI_DEINTERLACE_MODE_DISABLED, } GstVaapiDeinterlaceMode; +/* + * GST_VAAPI_DEINTERLACE_MAX_REFERENCES: + * + * This represents the maximum number of VA surfaces we could keep as + * references for advanced deinterlacing. + * + * Note: if the upstream element is vaapidecode, then the maximum + * number of allowed surfaces used as references shall be less than + * the actual number of scratch surfaces used for decoding (4). + */ +#define GST_VAAPI_DEINTERLACE_MAX_REFERENCES 3 + /** * GstVaapiPostprocFlags: * @GST_VAAPI_POSTPROC_FLAG_FORMAT: Pixel format conversion. @@ -99,6 +112,26 @@ typedef enum { GST_VAAPI_POSTPROC_FLAG_SIZE = GST_VAAPI_POSTPROC_FLAG_CUSTOM, } GstVaapiPostprocFlags; +/* + * GstVaapiDeinterlaceState: + * @buffers: history buffer, maintained as a cyclic array + * @buffers_index: next free slot in the history buffer + * @surfaces: array of surfaces used as references + * @num_surfaces: number of active surfaces in that array + * @deint: flag: previous buffers were interlaced? + * @tff: flag: previous buffers were organized as top-field-first? + * + * Context used to maintain deinterlacing state. + */ +struct _GstVaapiDeinterlaceState { + GstBuffer *buffers[GST_VAAPI_DEINTERLACE_MAX_REFERENCES]; + guint buffers_index; + GstVaapiSurface *surfaces[GST_VAAPI_DEINTERLACE_MAX_REFERENCES]; + guint num_surfaces; + guint deint : 1; + guint tff : 1; +}; + struct _GstVaapiPostproc { /*< private >*/ GstBaseTransform parent_instance; @@ -129,6 +162,7 @@ struct _GstVaapiPostproc { /* Deinterlacing */ GstVaapiDeinterlaceMode deinterlace_mode; GstVaapiDeinterlaceMethod deinterlace_method; + GstVaapiDeinterlaceState deinterlace_state; GstClockTime field_duration; guint is_raw_yuv : 1; From ef8f5defd2ca3f2916b4d36902da6aa4f0b49998 Mon Sep 17 00:00:00 2001 From: Halley Zhao Date: Fri, 1 Nov 2013 10:22:17 +0800 Subject: [PATCH 1389/3781] vaapipostproc: add support for denoise and sharpen filters. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipostproc.c | 47 ++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipostproc.h | 4 +++ 2 files changed, 51 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 06ea5286c4..c3ead79a21 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -139,6 +139,8 @@ enum { PROP_FORCE_ASPECT_RATIO, PROP_DEINTERLACE_MODE, PROP_DEINTERLACE_METHOD, + PROP_DENOISE, + PROP_SHARPEN, }; #define DEFAULT_FORMAT GST_VIDEO_FORMAT_ENCODED @@ -470,6 +472,16 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, !gst_vaapi_filter_set_format(postproc->filter, postproc->format)) return GST_FLOW_NOT_SUPPORTED; + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_DENOISE) && + !gst_vaapi_filter_set_denoising_level(postproc->filter, + postproc->denoise_level)) + return GST_FLOW_NOT_SUPPORTED; + + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SHARPEN) && + !gst_vaapi_filter_set_denoising_level(postproc->filter, + postproc->sharpen_level)) + return GST_FLOW_NOT_SUPPORTED; + inbuf_meta = gst_buffer_get_vaapi_video_meta(inbuf); if (!inbuf_meta) goto error_invalid_buffer; @@ -1446,6 +1458,14 @@ gst_vaapipostproc_set_property( case PROP_DEINTERLACE_METHOD: postproc->deinterlace_method = g_value_get_enum(value); break; + case PROP_DENOISE: + postproc->denoise_level = g_value_get_float(value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_DENOISE; + break; + case PROP_SHARPEN: + postproc->sharpen_level = g_value_get_float(value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SHARPEN; + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1481,6 +1501,12 @@ gst_vaapipostproc_get_property( case PROP_DEINTERLACE_METHOD: g_value_set_enum(value, postproc->deinterlace_method); break; + case PROP_DENOISE: + g_value_set_float(value, postproc->denoise_level); + break; + case PROP_SHARPEN: + g_value_set_float(value, postproc->sharpen_level); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1626,6 +1652,27 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) TRUE, G_PARAM_READWRITE)); + /** + * GstVaapiPostproc:denoise: + * + * The level of noise reduction to apply. + */ + filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_DENOISE); + if (filter_op) + g_object_class_install_property(object_class, + PROP_DENOISE, filter_op->pspec); + + /** + * GstVaapiPostproc:sharpen: + * + * The level of sharpening to apply for positive values, or the + * level of blurring for negative values. + */ + filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_SHARPEN); + if (filter_op) + g_object_class_install_property(object_class, + PROP_SHARPEN, filter_op->pspec); + g_ptr_array_unref(filter_ops); } diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 7340c3f23a..6d3364db9c 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -165,6 +165,10 @@ struct _GstVaapiPostproc { GstVaapiDeinterlaceState deinterlace_state; GstClockTime field_duration; + /* Basic filter values */ + gfloat denoise_level; + gfloat sharpen_level; + guint is_raw_yuv : 1; guint use_vpp : 1; guint keep_aspect : 1; From 9968661ffd7c212f7ac91fe62c40c2dce31ed894 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 18 Nov 2013 16:20:43 +0100 Subject: [PATCH 1390/3781] vaapipostproc: add initial support for GStreamer 1.2. Port vaapipostproc element to GStreamer 1.2. Support is quite minimal right now so that to cope with auto-plugging issues/regressions. e.g. this happens when the correct set of expected caps are being exposed. This means that, currently, the proposed caps are not fully accurate. --- gst/vaapi/Makefile.am | 7 ++-- gst/vaapi/gstvaapi.c | 2 -- gst/vaapi/gstvaapipostproc.c | 62 +++++++++++++++++++++++++++++++++--- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 0b8a45e2e1..cb989935ad 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -33,6 +33,7 @@ libgstvaapi_source_c = \ gstvaapi.c \ gstvaapidecode.c \ gstvaapipluginutil.c \ + gstvaapipostproc.c \ gstvaapisink.c \ gstvaapiuploader.c \ gstvaapivideobuffer.c \ @@ -43,6 +44,7 @@ libgstvaapi_source_c = \ libgstvaapi_source_h = \ gstvaapidecode.h \ gstvaapipluginutil.h \ + gstvaapipostproc.h \ gstvaapisink.h \ gstvaapiuploader.h \ gstvaapivideobuffer.h \ @@ -50,11 +52,6 @@ libgstvaapi_source_h = \ gstvaapivideometa.h \ $(NULL) -if !USE_GST_API_1_2p -libgstvaapi_source_c += gstvaapipostproc.c -libgstvaapi_source_h += gstvaapipostproc.h -endif - libgstvaapi_x11_source_c = gstvaapivideoconverter_x11.c libgstvaapi_x11_source_h = gstvaapivideoconverter_x11.h diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 7d12a668b1..3000b2296f 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -47,11 +47,9 @@ plugin_init (GstPlugin *plugin) gst_element_register(plugin, "vaapidecode", GST_RANK_PRIMARY, GST_TYPE_VAAPIDECODE); -#if !GST_CHECK_VERSION(1,1,0) gst_element_register(plugin, "vaapipostproc", GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); -#endif gst_element_register(plugin, "vaapisink", GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index c3ead79a21..dfe75c2349 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -30,10 +30,10 @@ #include "gst/vaapi/sysdeps.h" #include -#include #include "gstvaapipostproc.h" #include "gstvaapipluginutil.h" +#include "gstvaapivideocontext.h" #include "gstvaapivideobuffer.h" #if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" @@ -48,7 +48,12 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapipostproc); /* Default templates */ static const char gst_vaapipostproc_sink_caps_str[] = +#if GST_CHECK_VERSION(1,1,0) + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ", " +#else GST_VAAPI_SURFACE_CAPS ", " +#endif GST_CAPS_INTERLACED_MODES "; " #if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) ", " @@ -61,7 +66,12 @@ static const char gst_vaapipostproc_sink_caps_str[] = GST_CAPS_INTERLACED_MODES; static const char gst_vaapipostproc_src_caps_str[] = +#if GST_CHECK_VERSION(1,1,0) + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ", " +#else GST_VAAPI_SURFACE_CAPS ", " +#endif GST_CAPS_INTERLACED_FALSE; static GstStaticPadTemplate gst_vaapipostproc_sink_factory = @@ -97,6 +107,7 @@ gst_vaapipostproc_implements_iface_init(GstImplementsInterfaceClass *iface) #endif /* GstVideoContext interface */ +#if !GST_CHECK_VERSION(1,1,0) static void gst_vaapipostproc_set_video_context( GstVideoContext *context, @@ -119,6 +130,8 @@ gst_video_context_interface_init(GstVideoContextInterface *iface) } #define GstVideoContextClass GstVideoContextInterface +#endif + G_DEFINE_TYPE_WITH_CODE( GstVaapiPostproc, gst_vaapipostproc, @@ -127,8 +140,11 @@ G_DEFINE_TYPE_WITH_CODE( G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapipostproc_implements_iface_init); #endif +#if !GST_CHECK_VERSION(1,1,0) G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init)) + gst_video_context_interface_init) +#endif + ) enum { PROP_0, @@ -188,6 +204,20 @@ find_filter_op(GPtrArray *filter_ops, GstVaapiFilterOp op) return NULL; } +#if GST_CHECK_VERSION(1,1,0) +static void +gst_vaapipostproc_set_context(GstElement *element, GstContext *context) +{ + GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(element); + GstVaapiDisplay *display = NULL; + + if (gst_vaapi_video_context_get_display(context, &display)) { + GST_INFO_OBJECT(element, "set display %p", display); + gst_vaapi_display_replace(&postproc->display, display); + } +} +#endif + static inline gboolean gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc) { @@ -824,8 +854,13 @@ ensure_allowed_sinkpad_caps(GstVaapiPostproc *postproc) return TRUE; /* Create VA caps */ +#if GST_CHECK_VERSION(1,1,0) + out_caps = gst_static_pad_template_get_caps( + &gst_vaapipostproc_sink_factory); +#else out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES); +#endif if (!out_caps) { GST_ERROR("failed to create VA sink caps"); return FALSE; @@ -834,8 +869,10 @@ ensure_allowed_sinkpad_caps(GstVaapiPostproc *postproc) /* Append YUV caps */ if (gst_vaapipostproc_ensure_uploader(postproc)) { yuv_caps = gst_vaapi_uploader_get_caps(postproc->uploader); - if (yuv_caps) - gst_caps_append(out_caps, gst_caps_ref(yuv_caps)); + if (yuv_caps) { + out_caps = gst_caps_make_writable(out_caps); + gst_caps_append(out_caps, gst_caps_copy(yuv_caps)); + } else GST_WARNING("failed to create YUV sink caps"); } @@ -1020,10 +1057,22 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, GST_VIDEO_INFO_INTERLACE_MODE(&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; // Update size from user-specified parameters +#if GST_CHECK_VERSION(1,1,0) + format = postproc->format; +#else format = GST_VIDEO_FORMAT_ENCODED; +#endif find_best_size(postproc, &vi, &width, &height); gst_video_info_set_format(&vi, format, width, height); +#if GST_CHECK_VERSION(1,1,0) + out_caps = gst_video_info_to_caps(&vi); + if (!out_caps) + return NULL; + + gst_caps_set_features(out_caps, 0, + gst_caps_features_new(GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL)); +#else /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not reconstruct suitable caps for "encoded" video formats */ out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); @@ -1042,6 +1091,7 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, NULL); gst_caps_set_interlaced(out_caps, &vi); +#endif return out_caps; } @@ -1544,6 +1594,10 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) trans_class->prepare_output_buffer = gst_vaapipostproc_prepare_output_buffer; +#if GST_CHECK_VERSION(1,1,0) + element_class->set_context = gst_vaapipostproc_set_context; +#endif + gst_element_class_set_static_metadata(element_class, "VA-API video postprocessing", "Filter/Converter/Video", From dc48509bad263b4eae78228116408c2ef9c1009a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Nov 2013 23:17:59 +0100 Subject: [PATCH 1391/3781] decoder: don't include obsolete headers. The header was removed from the public set of APIs. So, don't make public headers (gstvaapidecoder.h) depend on private files. --- gst-libs/gst/vaapi/gstvaapidecoder.h | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 6dbcb5b83d..40d6c587d8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -25,7 +25,6 @@ #include #include -#include #include #include From b85e8b74c20fba24edd2453b8a032a288f9beee7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Nov 2013 23:51:59 +0100 Subject: [PATCH 1392/3781] NEWS: updates. --- NEWS | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 86fafea4ff..f6b7d14bfd 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,22 @@ -gst-vaapi NEWS -- summary of changes. 2013-08-29 +gst-vaapi NEWS -- summary of changes. 2013-11-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora +Version 0.5.7 - DD.Nov.2013 +* Add support for GStreamer 1.2 (+Victor Jaquez, Sreerenj Balachandran) +* Add support for video processing (VA/VPP) (+Halley Zhao) + + Scaling and color conversion + + Image enhancement filters: Sharpening, Noise Reduction + + Advanced deinterlacing: Motion-Adaptive, Motion-Compensated +* Fix vaapidecode pause/resume/seek capabilities (+Guangxin Xu) +* JPEG decoder bug fixes and improvements + + Add support for multiscan images + + Improve overall performance by +12% + + Fix robustness and tolerance to missing packets + + Fix detection of image boundaries (Junfeng Xu) + + Fix decoding from Logitech Pro C920 cameras (Junfeng Xu) + Version 0.5.6 - 29.Aug.2013 * Add render-to-pixmap API to bypass VA/GLX in clutter-gst * Add initial support for video-processing APIs (+Halley Zhao) From e3bd3b1dd3b74013105111cb238a8f2c0d6228e8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Nov 2013 23:52:43 +0100 Subject: [PATCH 1393/3781] 0.5.7. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index f6b7d14bfd..600f716f9e 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2013-11-DD +gst-vaapi NEWS -- summary of changes. 2013-11-21 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora -Version 0.5.7 - DD.Nov.2013 +Version 0.5.7 - 21.Nov.2013 * Add support for GStreamer 1.2 (+Victor Jaquez, Sreerenj Balachandran) * Add support for video processing (VA/VPP) (+Halley Zhao) + Scaling and color conversion diff --git a/configure.ac b/configure.ac index 473e31b7a2..f1994c7b85 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [7]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 15519ebe3d91b338a983a5b3872b68df8284e25a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Nov 2013 05:57:18 +0100 Subject: [PATCH 1394/3781] legal: add per-file authorship information. Credit original authors on a per-file basis as we cannot expect people to know all country-specific rules, or bother browsing through the git history. --- gst-libs/gst/vaapi/glibcompat.h | 1 + gst-libs/gst/vaapi/gstcompat.h | 1 + gst-libs/gst/vaapi/gstvaapicodec_objects.c | 2 ++ gst-libs/gst/vaapi/gstvaapicodec_objects.h | 2 ++ gst-libs/gst/vaapi/gstvaapicompat.h | 2 ++ gst-libs/gst/vaapi/gstvaapicontext.c | 2 ++ gst-libs/gst/vaapi/gstvaapicontext.h | 2 ++ gst-libs/gst/vaapi/gstvaapidebug.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder.c | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_dpb.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_unit.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_unit.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_vc1.h | 1 + gst-libs/gst/vaapi/gstvaapidisplay.c | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay_drm.h | 1 + gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h | 1 + gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 1 + gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_wayland.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplaycache.c | 1 + gst-libs/gst/vaapi/gstvaapidisplaycache.h | 1 + gst-libs/gst/vaapi/gstvaapifilter.c | 1 + gst-libs/gst/vaapi/gstvaapifilter.h | 1 + gst-libs/gst/vaapi/gstvaapiimage.c | 2 ++ gst-libs/gst/vaapi/gstvaapiimage.h | 2 ++ gst-libs/gst/vaapi/gstvaapiimage_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapiimagepool.c | 2 ++ gst-libs/gst/vaapi/gstvaapiimagepool.h | 2 ++ gst-libs/gst/vaapi/gstvaapiminiobject.c | 1 + gst-libs/gst/vaapi/gstvaapiminiobject.h | 1 + gst-libs/gst/vaapi/gstvaapiobject.c | 2 ++ gst-libs/gst/vaapi/gstvaapiobject.h | 2 ++ gst-libs/gst/vaapi/gstvaapiobject_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapiparser_frame.c | 1 + gst-libs/gst/vaapi/gstvaapiparser_frame.h | 1 + gst-libs/gst/vaapi/gstvaapipixmap.c | 1 + gst-libs/gst/vaapi/gstvaapipixmap.h | 1 + gst-libs/gst/vaapi/gstvaapipixmap_priv.h | 1 + gst-libs/gst/vaapi/gstvaapipixmap_x11.c | 1 + gst-libs/gst/vaapi/gstvaapipixmap_x11.h | 1 + gst-libs/gst/vaapi/gstvaapiprofile.c | 2 ++ gst-libs/gst/vaapi/gstvaapiprofile.h | 2 ++ gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 ++ gst-libs/gst/vaapi/gstvaapisubpicture.h | 2 ++ gst-libs/gst/vaapi/gstvaapisurface.c | 2 ++ gst-libs/gst/vaapi/gstvaapisurface.h | 2 ++ gst-libs/gst/vaapi/gstvaapisurface_priv.h | 1 + gst-libs/gst/vaapi/gstvaapisurfacepool.c | 2 ++ gst-libs/gst/vaapi/gstvaapisurfacepool.h | 2 ++ gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 2 ++ gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 2 ++ gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapitexture.c | 2 ++ gst-libs/gst/vaapi/gstvaapitexture.h | 2 ++ gst-libs/gst/vaapi/gstvaapitypes.h | 2 ++ gst-libs/gst/vaapi/gstvaapiutils.c | 2 ++ gst-libs/gst/vaapi/gstvaapiutils.h | 2 ++ gst-libs/gst/vaapi/gstvaapiutils_glx.c | 2 ++ gst-libs/gst/vaapi/gstvaapiutils_glx.h | 2 ++ gst-libs/gst/vaapi/gstvaapiutils_x11.c | 2 ++ gst-libs/gst/vaapi/gstvaapiutils_x11.h | 2 ++ gst-libs/gst/vaapi/gstvaapivalue.c | 2 ++ gst-libs/gst/vaapi/gstvaapivalue.h | 2 ++ gst-libs/gst/vaapi/gstvaapivideopool.c | 2 ++ gst-libs/gst/vaapi/gstvaapivideopool.h | 2 ++ gst-libs/gst/vaapi/gstvaapivideopool_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow.c | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow.h | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 1 + gst-libs/gst/vaapi/gstvaapiwindow_drm.h | 1 + gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow_wayland.h | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapiworkarounds.h | 1 + gst-libs/gst/vaapi/sysdeps.h | 1 + gst-libs/gst/vaapi/video-format.c | 2 ++ gst-libs/gst/vaapi/video-format.h | 2 ++ gst/vaapi/gstvaapi.c | 1 + gst/vaapi/gstvaapidecode.c | 2 ++ gst/vaapi/gstvaapidecode.h | 2 ++ gst/vaapi/gstvaapidownload.c | 2 ++ gst/vaapi/gstvaapidownload.h | 2 ++ gst/vaapi/gstvaapipluginutil.c | 1 + gst/vaapi/gstvaapipluginutil.h | 1 + gst/vaapi/gstvaapipostproc.c | 1 + gst/vaapi/gstvaapipostproc.h | 1 + gst/vaapi/gstvaapisink.c | 2 ++ gst/vaapi/gstvaapisink.h | 2 ++ gst/vaapi/gstvaapiupload.c | 2 ++ gst/vaapi/gstvaapiupload.h | 2 ++ gst/vaapi/gstvaapiuploader.c | 2 ++ gst/vaapi/gstvaapiuploader.h | 2 ++ gst/vaapi/gstvaapivideobuffer.c | 2 ++ gst/vaapi/gstvaapivideobuffer.h | 2 ++ gst/vaapi/gstvaapivideobufferpool.c | 1 + gst/vaapi/gstvaapivideobufferpool.h | 1 + gst/vaapi/gstvaapivideocontext.c | 2 ++ gst/vaapi/gstvaapivideocontext.h | 3 +++ gst/vaapi/gstvaapivideoconverter_glx.c | 1 + gst/vaapi/gstvaapivideoconverter_glx.h | 1 + gst/vaapi/gstvaapivideoconverter_x11.c | 1 + gst/vaapi/gstvaapivideoconverter_x11.h | 1 + gst/vaapi/gstvaapivideomemory.c | 1 + gst/vaapi/gstvaapivideomemory.h | 1 + gst/vaapi/gstvaapivideometa.c | 2 ++ gst/vaapi/gstvaapivideometa.h | 2 ++ gst/vaapi/gstvaapivideometa_texture.c | 3 +++ gst/vaapi/gstvaapivideometa_texture.h | 3 +++ tests/codec.c | 1 + tests/codec.h | 1 + tests/decoder.c | 1 + tests/decoder.h | 1 + tests/image.c | 1 + tests/image.h | 1 + tests/output.c | 1 + tests/output.h | 1 + tests/simple-decoder.c | 1 + tests/test-decode.c | 2 ++ tests/test-decode.h | 1 + tests/test-display.c | 2 ++ tests/test-filter.c | 3 +++ tests/test-h264.c | 1 + tests/test-h264.h | 1 + tests/test-jpeg.c | 1 + tests/test-jpeg.h | 1 + tests/test-mpeg2.c | 1 + tests/test-mpeg2.h | 1 + tests/test-mpeg4.c | 1 + tests/test-mpeg4.h | 1 + tests/test-surfaces.c | 2 ++ tests/test-textures.c | 1 + tests/test-vc1.c | 1 + tests/test-vc1.h | 1 + tests/test-windows.c | 2 ++ 162 files changed, 257 insertions(+) diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 24057f82f5..85004877ea 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -2,6 +2,7 @@ * glibcompat.h - System-dependent definitions * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index c3a8ff8d00..f139739b45 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -2,6 +2,7 @@ * gstcompat.h - Compatibility glue for GStreamer * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index c910cf8036..1d287dfc0d 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -2,7 +2,9 @@ * gstvaapicodec_objects.c - VA codec objects abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index b6dc8aab08..6ca268e571 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -2,7 +2,9 @@ * gstvaapicodec_objects.h - VA codec objects abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 9e8ce5914b..f2d5b92776 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -2,7 +2,9 @@ * gstvapicompat.h - VA-API compatibility glue * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 6cdf1b39b6..dce82f4ebb 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -2,7 +2,9 @@ * gstvaapicontext.c - VA context abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 3803314e3c..95a8c0aefe 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -2,7 +2,9 @@ * gstvaapicontext.h - VA context abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidebug.h b/gst-libs/gst/vaapi/gstvaapidebug.h index d743c741fc..e386755503 100644 --- a/gst-libs/gst/vaapi/gstvaapidebug.h +++ b/gst-libs/gst/vaapi/gstvaapidebug.h @@ -2,6 +2,7 @@ * gstvaapidebug.h - VA-API debugging utilities * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 76a46ffb84..6df5ba84ed 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -2,7 +2,9 @@ * gstvaapidecoder.c - VA decoder abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 40d6c587d8..058255d3ce 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -2,7 +2,9 @@ * gstvaapidecoder.h - VA decoder abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index c8c2c78de0..d96186f753 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -2,6 +2,7 @@ * gstvaapidecoder_dpb.c - Decoded Picture Buffer * * Copyright (C) 2012-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h index 4fc1a20d97..fa52d41591 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.h @@ -2,6 +2,7 @@ * gstvaapidecoder_dpb.h - Decoded Picture Buffer * * Copyright (C) 2012-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index aad434cfac..ba4c0b5e9b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2,6 +2,7 @@ * gstvaapidecoder_h264.c - H.264 decoder * * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h index 2b318f02c3..772cf65f32 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -2,6 +2,7 @@ * gstvaapidecoder_h264.h - H.264 decoder * * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index c3655f08f3..5f680963fd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -2,6 +2,8 @@ * gstvaapidecoder_jpeg.c - JPEG decoder * * Copyright (C) 2011-2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h index 8c81de1c6d..165e43c5ba 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h @@ -2,6 +2,8 @@ * gstvaapidecoder_jpeg.h - JPEG decoder * * Copyright (C) 2011-2012 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 711755f328..39b6737ed2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -2,6 +2,7 @@ * gstvaapidecoder_mpeg2.c - MPEG-2 decoder * * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h index bdf40fb9b7..bde2f3c390 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h @@ -2,6 +2,7 @@ * gstvaapidecoder_mpeg2.h - MPEG-2 decoder * * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 71fdef6a0b..a4fd9eff07 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -2,6 +2,7 @@ * gstvaapidecoder_mpeg4.c - MPEG-4 decoder * * Copyright (C) 2011-2013 Intel Corporation + * Author: Halley Zhao * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h index 07134a75a2..3e6bd92db8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h @@ -2,6 +2,7 @@ * gstvaapidecoder_mpeg4.h - MPEG-4 decoder * * Copyright (C) 2011-2012 Intel Corporation + * Author: Halley Zhao * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 225dcfbb71..35a9ffb6a2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -2,7 +2,9 @@ * gstvaapidecoder_objects.c - VA decoder objects helpers * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 3d595ae0cb..5480ac553d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -2,7 +2,9 @@ * gstvaapidecoder_objects.h - VA decoder objects * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 8b6d8970c6..6a689fc99e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -2,7 +2,9 @@ * gstvaapidecoder_priv.h - VA decoder abstraction (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c index 57c4d2b3b5..8ffbf076ff 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c @@ -2,6 +2,7 @@ * gstvaapidecoder_unit.c - VA decoder units * * Copyright (C) 2012-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h index 717e805526..7ee77a05cf 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h @@ -2,6 +2,7 @@ * gstvaapidecoder_unit.h - VA decoder units * * Copyright (C) 2012-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index a2ee00234d..bdddbea00b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -2,6 +2,7 @@ * gstvaapidecoder_vc1.c - VC-1 decoder * * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h index 405b1e7cc1..12baa2e462 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h @@ -2,6 +2,7 @@ * gstvaapidecoder_vc1.h - VC-1 decoder * * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index ca8c6cb046..cb537d94c9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -2,7 +2,9 @@ * gstvaapidisplay.c - VA display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 1949b2497d..1d190679da 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -2,7 +2,9 @@ * gstvaapidisplay.h - VA display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 68cc119d6a..4f3fe67dff 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -2,6 +2,7 @@ * gstvaapidisplay_drm.c - VA/DRM display abstraction * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h index 0d946cc879..c35d815da3 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h @@ -2,6 +2,7 @@ * gstvaapidisplay_drm.h - VA/DRM display abstraction * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h index 8e40b22ca8..4aac6337ae 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h @@ -2,6 +2,7 @@ * gstvaapidisplay_drm_priv.h - Internal VA/DRM interface * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index f81f381d2b..3f8f8c882f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -2,7 +2,9 @@ * gstvaapidisplay_glx.c - VA/GLX display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index bd46a8c7b5..c3c9a4ddd7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -2,7 +2,9 @@ * gstvaapidisplay_glx.h - VA/GLX display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index e0cee01880..7386263981 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -2,6 +2,7 @@ * gstvaapidisplay_glx_priv.h - Internal VA/GLX interface * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 1f7f46ceff..88d2119da2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -2,7 +2,9 @@ * gstvaapidisplay_priv.h - Base VA display (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index b10165b6dc..04001a9f08 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -2,6 +2,8 @@ * gstvaapidisplay_wayland.c - VA/Wayland display abstraction * * Copyright (C) 2012-2013 Intel Corporation + * Author: Sreerenj Balachandran + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h index 730a434aef..cbb1bbf418 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h @@ -2,6 +2,8 @@ * gstvaapidisplay_wayland.h - VA/Wayland display abstraction * * Copyright (C) 2012 Intel Corporation + * Author: Sreerenj Balachandran + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index 313697a07c..df94231104 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -2,6 +2,8 @@ * gstvaapidisplay_wayland_priv.h - Internal VA/Wayland interface * * Copyright (C) 2012 Intel Corporation + * Author: Sreerenj Balachandran + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index b633b1a6cb..038b32f6ab 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -2,7 +2,9 @@ * gstvaapidisplay_x11.c - VA/X11 display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 5711095779..9fa8a19ac8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -2,7 +2,9 @@ * gstvaapidisplay_x11.h - VA/X11 display abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index 45494bc8aa..791a234d93 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -2,7 +2,9 @@ * gstvaapidisplay_x11_priv.h - Internal VA/X11 interface * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index baca686314..b39ea2f224 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -2,6 +2,7 @@ * gstvaapidisplaycache.c - VA display cache * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h index 4b0bb5e75f..ff679a400f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.h +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.h @@ -2,6 +2,7 @@ * gstvaapidisplaycache.h - VA display cache * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 5ca28865ba..8bccc3e127 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -2,6 +2,7 @@ * gstvaapifilter.c - Video processing abstraction * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 9ed6436c9e..a6ad56da74 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -2,6 +2,7 @@ * gstvaapifilter.h - Video processing abstraction * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 49107ba9a4..3edc05aa53 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -2,7 +2,9 @@ * gstvaapiimage.c - VA image abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index c5c3ed2280..19dd2f5374 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -2,7 +2,9 @@ * gstvaapiimage.h - VA image abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimage_priv.h b/gst-libs/gst/vaapi/gstvaapiimage_priv.h index bc99d0585e..bed4a9472a 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiimage_priv.h @@ -2,7 +2,9 @@ * gstvaapiimage_priv.h - VA image abstraction (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 3b5d4b775b..5f60e2b057 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -2,7 +2,9 @@ * gstvaapiimagepool.c - Gst VA image pool * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index 19677eb1c8..2dabdee699 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -2,7 +2,9 @@ * gstvaapiimagepool.h - Gst VA image pool * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.c b/gst-libs/gst/vaapi/gstvaapiminiobject.c index 477d00a3e7..f38bdf7298 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.c @@ -2,6 +2,7 @@ * gstvaapiminiobject.c - A lightweight reference counted object * * Copyright (C) 2012-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.h b/gst-libs/gst/vaapi/gstvaapiminiobject.h index 900b232d7d..2e05a0c1c6 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.h @@ -2,6 +2,7 @@ * gstvaapiminiobject.h - A lightweight reference counted object * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 2be82ceb05..b7a9f3aa46 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -2,7 +2,9 @@ * gstvaapiobject.c - Base VA object * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index 081b2c6751..883c898c20 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -2,7 +2,9 @@ * gstvaapiobject.h - Base VA object * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index f1e80590eb..ae35c9d602 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -2,7 +2,9 @@ * gstvaapiobject_priv.h - Base VA object (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiparser_frame.c b/gst-libs/gst/vaapi/gstvaapiparser_frame.c index 9c87300ce2..11bc2febbf 100644 --- a/gst-libs/gst/vaapi/gstvaapiparser_frame.c +++ b/gst-libs/gst/vaapi/gstvaapiparser_frame.c @@ -2,6 +2,7 @@ * gstvaapiparser_frame.c - VA parser frame * * Copyright (C) 2012-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiparser_frame.h b/gst-libs/gst/vaapi/gstvaapiparser_frame.h index b9b0b0b476..b8de9bc0d8 100644 --- a/gst-libs/gst/vaapi/gstvaapiparser_frame.h +++ b/gst-libs/gst/vaapi/gstvaapiparser_frame.h @@ -2,6 +2,7 @@ * gstvaapiparser_frame.h - VA parser frame * * Copyright (C) 2012-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapipixmap.c b/gst-libs/gst/vaapi/gstvaapipixmap.c index 5bb388c476..e01d033401 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap.c +++ b/gst-libs/gst/vaapi/gstvaapipixmap.c @@ -2,6 +2,7 @@ * gstvaapipixmap.c - Pixmap abstraction * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapipixmap.h b/gst-libs/gst/vaapi/gstvaapipixmap.h index fd2e138142..037a72f3ad 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap.h +++ b/gst-libs/gst/vaapi/gstvaapipixmap.h @@ -2,6 +2,7 @@ * gstvaapipixmap.h - Pixmap abstraction * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_priv.h b/gst-libs/gst/vaapi/gstvaapipixmap_priv.h index 6856c5236e..577fda884b 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_priv.h +++ b/gst-libs/gst/vaapi/gstvaapipixmap_priv.h @@ -2,6 +2,7 @@ * gstvaapipixmap_priv.h - Pixmap abstraction (private definitions) * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c index eed11dd997..8031383370 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c +++ b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c @@ -2,6 +2,7 @@ * gstvaapipixmap_x11.c - X11 pixmap abstraction * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.h b/gst-libs/gst/vaapi/gstvaapipixmap_x11.h index 2c27ad43be..814823b16c 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_x11.h +++ b/gst-libs/gst/vaapi/gstvaapipixmap_x11.h @@ -2,6 +2,7 @@ * gstvaapipixmap_x11.h - X11 pixmap abstraction * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 1c5c51544a..d29db11327 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -2,7 +2,9 @@ * gstvaapiprofile.c - VA profile abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 8663029a75..53a683aac1 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -2,7 +2,9 @@ * gstvaapiprofile.h - VA profile abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index a269df5a49..e8d28a470b 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -2,7 +2,9 @@ * gstvaapisubpicture.c - VA subpicture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 9a15efdf95..7bfef36ed4 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -2,7 +2,9 @@ * gstvaapisubpicture.h - VA subpicture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 1a094b7b38..564c3a97d0 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -2,7 +2,9 @@ * gstvaapisurface.c - VA surface abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 13dbf4f925..1932a01307 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -2,7 +2,9 @@ * gstvaapisurface.h - VA surface abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index 2114d721c1..c650d09537 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -2,6 +2,7 @@ * gstvaapisurface_priv.h - VA surface abstraction (private data) * * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index f185f00f07..58e2622ace 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -2,7 +2,9 @@ * gstvaapisurfacepool.c - Gst VA surface pool * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 7e47920651..296342fc6b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -2,7 +2,9 @@ * gstvaapisurfacepool.h - Gst VA surface pool * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index f9e488a153..0ed3fd1c46 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -2,7 +2,9 @@ * gstvaapisurfaceproxy.c - VA surface proxy * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 69ddbc490c..fb5f07c9c4 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -2,7 +2,9 @@ * gstvaapisurfaceproxy.h - VA surface proxy * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index 5ed0e701dd..dd22bb1bc0 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -2,7 +2,9 @@ * gstvaapisurfaceproxy_priv.h - VA surface proxy (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 4309f36297..7adb253e20 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -2,7 +2,9 @@ * gstvaapitexture.c - VA texture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index f70c89f294..dbfe6858a4 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -2,7 +2,9 @@ * gstvaapitexture.h - VA texture abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 81ef6fcfea..1725ff237a 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -2,7 +2,9 @@ * gstvaapitypes.h - Basic types * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 9fc4c68639..2536ad8512 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -2,7 +2,9 @@ * gstvaapiutils.c - VA-API utilities * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 0ab132bfc2..3355c7fdf4 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -2,7 +2,9 @@ * gstvaapiutils.h - VA-API utilities * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 4788c95b41..c47c9aaf66 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -2,7 +2,9 @@ * gstvaapiutils_glx.c - GLX utilties * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 12d2205868..5d4f75a727 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -2,7 +2,9 @@ * gstvaapiutils_glx.h - GLX utilties * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 2b7931b016..a657a70d1b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -2,7 +2,9 @@ * gstvaapiutils_x11.c - X11 utilties * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index 252b4ae689..47f93cfc22 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -2,7 +2,9 @@ * gstvaapiutils_x11.h - X11 utilties * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 2912cc9c5d..559d9ac464 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -2,7 +2,9 @@ * gstvaapivalue.c - GValue implementations specific to VA-API * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index 5ca8f5f916..f81162ce08 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -2,7 +2,9 @@ * gstvaapivalue.h - GValue implementations specific to VA-API * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 97e0bb2b14..624a5e0f58 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -2,7 +2,9 @@ * gstvaapivideopool.c - Video object pool abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 07ad7a35f3..5f94342a76 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -2,7 +2,9 @@ * gstvaapivideopool.h - Video object pool abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h index 36088b343b..35c0ee5fc7 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h @@ -2,7 +2,9 @@ * gstvaapivideopool_priv.h - Video object pool abstraction (private defs) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index d8f19723b5..ab0ce6db75 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -2,7 +2,9 @@ * gstvaapiwindow.c - VA window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 6d8a553da8..0481ead4f3 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -2,7 +2,9 @@ * gstvaapiwindow.h - VA window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c index b4a05c97c7..8a600a5b56 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -2,6 +2,7 @@ * gstvaapiwindow_drm.c - VA/DRM window abstraction * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h index fc155b89da..29cff2fa76 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h @@ -2,6 +2,7 @@ * gstvaapiwindow_drm.h - VA/DRM window abstraction * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index d725178dee..62a4816d5f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -2,7 +2,9 @@ * gstvaapiwindow_glx.c - VA/GLX window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index 9d0042f6c1..1d6bbbf58a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -2,7 +2,9 @@ * gstvaapiwindow_glx.h - VA/GLX window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index 6450d9587f..4e56d8007a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -2,7 +2,9 @@ * gstvaapiwindow_priv.h - VA window abstraction (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index bfb2f10d6e..64db3898ba 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -2,6 +2,8 @@ * gstvaapiwindow_wayland.c - VA/Wayland window abstraction * * Copyright (C) 2012-2013 Intel Corporation + * Author: Sreerenj Balachandran + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h index 5f285bef4b..d1dc4b85cc 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h @@ -2,6 +2,8 @@ * gstvaapiwindow_wayland.h - VA/Wayland window abstraction * * Copyright (C) 2012 Intel Corporation + * Author: Sreerenj Balachandran + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index df58ef20cf..8b5c73f3c5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -2,7 +2,9 @@ * gstvaapiwindow_x11.c - VA/X11 window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index 57c514347a..25ea25ff53 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -2,7 +2,9 @@ * gstvaapiwindow_x11.h - VA/X11 window abstraction * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index c5bebb64ce..9549c0395a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -2,7 +2,9 @@ * gstvaapiwindow_x11_priv.h - VA/X11 window abstraction (private definitions) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiworkarounds.h b/gst-libs/gst/vaapi/gstvaapiworkarounds.h index a7276f4a37..967ef3eb6a 100644 --- a/gst-libs/gst/vaapi/gstvaapiworkarounds.h +++ b/gst-libs/gst/vaapi/gstvaapiworkarounds.h @@ -2,6 +2,7 @@ * gstvaapiworkaround.h - GStreamer/VA workarounds * * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/sysdeps.h b/gst-libs/gst/vaapi/sysdeps.h index 467118e854..e17081f38f 100644 --- a/gst-libs/gst/vaapi/sysdeps.h +++ b/gst-libs/gst/vaapi/sysdeps.h @@ -2,6 +2,7 @@ * sysdeps.h - System-dependent definitions * * Copyright (C) 2012-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 523e6fc2ea..1d82c57851 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -2,7 +2,9 @@ * video-format.h - Video format helpers for VA-API * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index fb2bb186b4..69faa0a54e 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -2,7 +2,9 @@ * video-format.h - Video format helpers for VA-API * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 3000b2296f..3f2bc2b855 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -2,6 +2,7 @@ * gstvaapi.c - VA-API element registration * * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * Copyright (C) 2011 Collabora Ltd. * Author: Nicolas Dufresne * diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 510866d78e..67485990bb 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -2,7 +2,9 @@ * gstvaapidecode.c - VA-API video decoder * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index da4244b5a4..7d2d3392ec 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -2,7 +2,9 @@ * gstvaapidecode.h - VA-API video decoder * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index ccdfe9c7c8..8e5e0ce9ec 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -2,7 +2,9 @@ * gstvaapidownload.c - VA-API video downloader * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapidownload.h b/gst/vaapi/gstvaapidownload.h index 28b58e73c2..33e14468c7 100644 --- a/gst/vaapi/gstvaapidownload.h +++ b/gst/vaapi/gstvaapidownload.h @@ -2,7 +2,9 @@ * gstvaapidownload.h - VA-API video downloader * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index a0b78c9449..b0306aa576 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -2,6 +2,7 @@ * gstvaapipluginutil.h - VA-API plugin helpers * * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * Copyright (C) 2011 Collabora * Author: Nicolas Dufresne * diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 306ab4a5ce..3341d48690 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -2,6 +2,7 @@ * gstvaapipluginutil.h - VA-API plugins private helper * * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * Copyright (C) 2011 Collabora * Author: Nicolas Dufresne * diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index dfe75c2349..2ec839726d 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -2,6 +2,7 @@ * gstvaapipostproc.c - VA-API video postprocessing * * Copyright (C) 2012-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 6d3364db9c..378e2648a1 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -2,6 +2,7 @@ * gstvaapipostproc.h - VA-API video post processing * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index f92939051b..964dcdf085 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -2,7 +2,9 @@ * gstvaapisink.c - VA-API video sink * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index e732fc5801..ad482eaf17 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -2,7 +2,9 @@ * gstvaapisink.h - VA-API video sink * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 5c80c5a1bc..df63cff8ac 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -2,7 +2,9 @@ * gstvaapiupload.c - VA-API video upload element * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiupload.h b/gst/vaapi/gstvaapiupload.h index cb22036a33..41c1a2f299 100644 --- a/gst/vaapi/gstvaapiupload.h +++ b/gst/vaapi/gstvaapiupload.h @@ -2,7 +2,9 @@ * gstvaapiupload.h - VA-API video upload element * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index b26caa06b3..04de04c677 100755 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -2,7 +2,9 @@ * gstvaapiuploader.c - VA-API video upload helper * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiuploader.h b/gst/vaapi/gstvaapiuploader.h index db2dcdbc85..c52af73a79 100644 --- a/gst/vaapi/gstvaapiuploader.h +++ b/gst/vaapi/gstvaapiuploader.h @@ -2,7 +2,9 @@ * gstvaapiuploader.h - VA-API video upload helper * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index e03dd69c9c..760a765e57 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -2,7 +2,9 @@ * gstvaapivideobuffer.c - Gstreamer/VA video buffer * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideobuffer.h b/gst/vaapi/gstvaapivideobuffer.h index d172f449a0..dc8f174ff3 100644 --- a/gst/vaapi/gstvaapivideobuffer.h +++ b/gst/vaapi/gstvaapivideobuffer.h @@ -2,7 +2,9 @@ * gstvaapivideobuffer.h - Gstreamer/VA video buffer * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index c293ad1f28..f35dcbc67b 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -2,6 +2,7 @@ * gstvaapivideobufferpool.c - Gstreamer/VA video buffer pool * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index 1b97bb1b88..ae284f926d 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -2,6 +2,7 @@ * gstvaapivideobufferpool.h - Gstreamer/VA video buffer pool * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index c33cc635d0..e740983beb 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -2,7 +2,9 @@ * gstvaapivideocontext.c - GStreamer/VA video context * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * Copyright (C) 2013 Igalia * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index 3ef5849d55..096445564f 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -2,8 +2,11 @@ * gstvaapivideocontext.h - GStreamer/VA video context * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * Copyright (C) 2013 Igalia + * Author: Víctor Manuel Jáquez Leal * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index f2c5c5dae9..9aaaf368a1 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -2,6 +2,7 @@ * gstvaapivideoconverter_glx.c - Gst VA video converter * * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * Copyright (C) 2011 Collabora Ltd. * Author: Nicolas Dufresne * diff --git a/gst/vaapi/gstvaapivideoconverter_glx.h b/gst/vaapi/gstvaapivideoconverter_glx.h index 54ea70929e..6afa7335c3 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.h +++ b/gst/vaapi/gstvaapivideoconverter_glx.h @@ -2,6 +2,7 @@ * gstvaapivideoconverter_glx.h - Gstreamer/VA video converter * * Copyright (C) 2011-2012 Intel Corporation + * Author: Gwenole Beauchesne * Copyright (C) 2011 Collabora Ltd. * Author: Nicolas Dufresne * diff --git a/gst/vaapi/gstvaapivideoconverter_x11.c b/gst/vaapi/gstvaapivideoconverter_x11.c index 9de2df2bac..8a05bd20da 100644 --- a/gst/vaapi/gstvaapivideoconverter_x11.c +++ b/gst/vaapi/gstvaapivideoconverter_x11.c @@ -2,6 +2,7 @@ * gstvaapivideoconverter_x11.h - VA video converter to X11 pixmap * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideoconverter_x11.h b/gst/vaapi/gstvaapivideoconverter_x11.h index be991b3ab3..54618ebb6e 100644 --- a/gst/vaapi/gstvaapivideoconverter_x11.h +++ b/gst/vaapi/gstvaapivideoconverter_x11.h @@ -2,6 +2,7 @@ * gstvaapivideoconverter_x11.h - VA video converter to X11 pixmap * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 5e9179e269..0e3b794ce0 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -2,6 +2,7 @@ * gstvaapivideomemory.c - Gstreamer/VA video memory * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 72b34e391d..c28efb85de 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -2,6 +2,7 @@ * gstvaapivideomemory.h - Gstreamer/VA video memory * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index 4f98795c52..f770120a78 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -2,7 +2,9 @@ * gstvaapivideometa.c - Gst VA video meta * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideometa.h b/gst/vaapi/gstvaapivideometa.h index cb1dc2b61b..d436358700 100644 --- a/gst/vaapi/gstvaapivideometa.h +++ b/gst/vaapi/gstvaapivideometa.h @@ -2,7 +2,9 @@ * gstvaapivideometa.h - Gstreamer/VA video meta * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 17b19a0088..10c3b9ac68 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -2,8 +2,11 @@ * gstvaapivideometa_texture.c - GStreamer/VA video meta (GLTextureUpload) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * Copyright (C) 2013 Igalia + * Author: Víctor Manuel Jáquez Leal * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapivideometa_texture.h b/gst/vaapi/gstvaapivideometa_texture.h index 2f954344ca..289e98fe92 100644 --- a/gst/vaapi/gstvaapivideometa_texture.h +++ b/gst/vaapi/gstvaapivideometa_texture.h @@ -2,8 +2,11 @@ * gstvaapivideometa_texture.h - GStreamer/VA video meta (GLTextureUpload) * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * Copyright (C) 2013 Igalia + * Author: Víctor Manuel Jáquez Leal * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/codec.c b/tests/codec.c index ff9b1250b2..0269ae6c25 100644 --- a/tests/codec.c +++ b/tests/codec.c @@ -2,6 +2,7 @@ * codec.c - Codec utilities for the tests * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/codec.h b/tests/codec.h index fad160b241..6aaf5b8fc8 100644 --- a/tests/codec.h +++ b/tests/codec.h @@ -2,6 +2,7 @@ * codec.h - Codec utilities for the tests * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/decoder.c b/tests/decoder.c index f932658394..2ca72806e5 100644 --- a/tests/decoder.c +++ b/tests/decoder.c @@ -2,6 +2,7 @@ * decoder.h - Decoder utilities for the tests * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/decoder.h b/tests/decoder.h index b13712e514..68530009dd 100644 --- a/tests/decoder.h +++ b/tests/decoder.h @@ -2,6 +2,7 @@ * decoder.h - Decoder utilities for the tests * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/image.c b/tests/image.c index 53bb42f2d4..ff07888e40 100644 --- a/tests/image.c +++ b/tests/image.c @@ -2,6 +2,7 @@ * image.c - Image utilities for the tests * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/image.h b/tests/image.h index 8c1229f885..ef3210ad52 100644 --- a/tests/image.h +++ b/tests/image.h @@ -2,6 +2,7 @@ * image.h - Image utilities for the tests * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/output.c b/tests/output.c index 6a54f3b53d..d5396a7d34 100644 --- a/tests/output.c +++ b/tests/output.c @@ -2,6 +2,7 @@ * output.c - Video output helpers * * Copyright (C) 2012-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/output.h b/tests/output.h index 29339c5a7a..e08a0a432e 100644 --- a/tests/output.h +++ b/tests/output.h @@ -2,6 +2,7 @@ * output.h - Video output helpers * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index 3c434d0646..69c960beb8 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -2,6 +2,7 @@ * simple-decoder.c - Simple Decoder Application * * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-decode.c b/tests/test-decode.c index 8790a6e405..db75fd828d 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -2,7 +2,9 @@ * test-decode.c - Test GstVaapiDecoder * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-decode.h b/tests/test-decode.h index 147f51c9d9..fbe46a6dd3 100644 --- a/tests/test-decode.h +++ b/tests/test-decode.h @@ -2,6 +2,7 @@ * test-decode.h - Test GstVaapiDecoder * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-display.c b/tests/test-display.c index 07842a25c9..360ce82df8 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -2,7 +2,9 @@ * test-display.c - Test GstVaapiDisplayX11 * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-filter.c b/tests/test-filter.c index 7bb6219c1b..52452b3196 100755 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -2,7 +2,10 @@ * test-filter.c - Test GstVaapiFilter * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012-2013 Intel Corporation + * Author: Halley Zhao + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-h264.c b/tests/test-h264.c index 6a7fa84b60..d24889111a 100644 --- a/tests/test-h264.c +++ b/tests/test-h264.c @@ -2,6 +2,7 @@ * test-h264.c - H.264 test data * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-h264.h b/tests/test-h264.h index f960b6e7ff..d94df4e547 100644 --- a/tests/test-h264.h +++ b/tests/test-h264.h @@ -2,6 +2,7 @@ * test-h264.h - H.264 test data * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-jpeg.c b/tests/test-jpeg.c index 3a1879afeb..cacb0f5a39 100644 --- a/tests/test-jpeg.c +++ b/tests/test-jpeg.c @@ -2,6 +2,7 @@ * test-jpeg.c - JPEG test data * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-jpeg.h b/tests/test-jpeg.h index 673c9d14bf..6372583caf 100644 --- a/tests/test-jpeg.h +++ b/tests/test-jpeg.h @@ -2,6 +2,7 @@ * test-jpeg.h - JPEG test data * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-mpeg2.c b/tests/test-mpeg2.c index 294463858f..0e9de2075e 100644 --- a/tests/test-mpeg2.c +++ b/tests/test-mpeg2.c @@ -2,6 +2,7 @@ * test-mpeg2.c - MPEG-2 test data * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-mpeg2.h b/tests/test-mpeg2.h index 867bbac866..ba21d0f6f4 100644 --- a/tests/test-mpeg2.h +++ b/tests/test-mpeg2.h @@ -2,6 +2,7 @@ * test-mpeg2.h - MPEG-2 test data * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-mpeg4.c b/tests/test-mpeg4.c index e06e8e8361..19f5d5b53b 100644 --- a/tests/test-mpeg4.c +++ b/tests/test-mpeg4.c @@ -2,6 +2,7 @@ * test-mpeg4.c - MPEG-4 test data * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-mpeg4.h b/tests/test-mpeg4.h index 06a2b7ab77..fdbf9eac43 100644 --- a/tests/test-mpeg4.h +++ b/tests/test-mpeg4.h @@ -2,6 +2,7 @@ * test-mpeg4.h - MPEG-4 test data * * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index bc55dd7f8f..974746174b 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -2,7 +2,9 @@ * test-surfaces.c - Test GstVaapiSurface and GstVaapiSurfacePool * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-textures.c b/tests/test-textures.c index 14bb5151e3..9e608601a5 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -2,6 +2,7 @@ * test-textures.c - Test GstVaapiTexture * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-vc1.c b/tests/test-vc1.c index 7555214b76..f03b31f460 100644 --- a/tests/test-vc1.c +++ b/tests/test-vc1.c @@ -2,6 +2,7 @@ * test-vc1.c - VC-1 test data * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-vc1.h b/tests/test-vc1.h index 30c6ec8d8c..3b948640db 100644 --- a/tests/test-vc1.h +++ b/tests/test-vc1.h @@ -2,6 +2,7 @@ * test-vc1.h - VC-1 test data * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/test-windows.c b/tests/test-windows.c index fa5b40b010..2acb16ee9d 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -2,7 +2,9 @@ * test-windows.c - Test GstVaapiWindow * * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne * Copyright (C) 2012 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License From c516311a1a696ff940d9a797e534a8f7a325421a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Nov 2013 06:37:12 +0100 Subject: [PATCH 1395/3781] legal: update copyright notice dates. --- gst-libs/gst/vaapi/glibcompat.h | 2 +- gst-libs/gst/vaapi/gstvaapicontext.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_vc1.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_drm.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_wayland.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplaycache.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplaycache.h | 2 +- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapiimage.h | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.c | 2 +- gst-libs/gst/vaapi/gstvaapiimagepool.h | 2 +- gst-libs/gst/vaapi/gstvaapiminiobject.h | 2 +- gst-libs/gst/vaapi/gstvaapiobject.c | 2 +- gst-libs/gst/vaapi/gstvaapiobject.h | 2 +- gst-libs/gst/vaapi/gstvaapiobject_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- gst-libs/gst/vaapi/gstvaapisurface_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapitexture.c | 2 +- gst-libs/gst/vaapi/gstvaapitexture.h | 2 +- gst-libs/gst/vaapi/gstvaapitypes.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapivalue.c | 2 +- gst-libs/gst/vaapi/gstvaapivalue.h | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.h | 2 +- gst-libs/gst/vaapi/gstvaapivideopool_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_drm.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_wayland.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 2 +- gst/vaapi/gstvaapi.c | 2 +- gst/vaapi/gstvaapidecode.h | 2 +- gst/vaapi/gstvaapidownload.h | 2 +- gst/vaapi/gstvaapipluginutil.c | 2 +- gst/vaapi/gstvaapipluginutil.h | 2 +- gst/vaapi/gstvaapipostproc.h | 2 +- gst/vaapi/gstvaapisink.h | 2 +- gst/vaapi/gstvaapivideoconverter_glx.h | 2 +- tests/image.c | 2 ++ tests/image.h | 2 ++ tests/output.h | 2 +- tests/test-display.c | 2 +- tests/test-jpeg.c | 2 +- tests/test-jpeg.h | 2 +- tests/test-mpeg4.c | 2 +- tests/test-mpeg4.h | 2 +- tests/test-surfaces.c | 2 +- tests/test-windows.c | 2 +- 75 files changed, 77 insertions(+), 73 deletions(-) diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 85004877ea..66ee910cd1 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -1,7 +1,7 @@ /* * glibcompat.h - System-dependent definitions * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 95a8c0aefe..8260e14a3e 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h index 772cf65f32..05c010b685 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_h264.h - H.264 decoder * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h index 165e43c5ba..76a19cca53 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_jpeg.h - JPEG decoder * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Wind Yuan * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h index bde2f3c390..0fea920315 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_mpeg2.h - MPEG-2 decoder * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h index 3e6bd92db8..17537cbe69 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_mpeg4.h - MPEG-4 decoder * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Halley Zhao * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h index 12baa2e462..8817eac34b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h @@ -1,7 +1,7 @@ /* * gstvaapidecoder_vc1.h - VC-1 decoder * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 4f3fe67dff..46600a270d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -1,7 +1,7 @@ /* * gstvaapidisplay_drm.c - VA/DRM display abstraction * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h index c35d815da3..1fcbd677f5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_drm.h - VA/DRM display abstraction * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h index 4aac6337ae..a8cab20473 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_drm_priv.h - Internal VA/DRM interface * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 3f8f8c882f..a024fe90b1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index c3c9a4ddd7..c22f904aba 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 88d2119da2..e2d9bf2cfc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h index cbb1bbf418..25d6c006fc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_wayland.h - VA/Wayland display abstraction * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Sreerenj Balachandran * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index df94231104..83e2165ffa 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -1,7 +1,7 @@ /* * gstvaapidisplay_wayland_priv.h - Internal VA/Wayland interface * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Sreerenj Balachandran * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 038b32f6ab..ca34f9f876 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 9fa8a19ac8..a470b70648 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index 791a234d93..ff487e6a43 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index b39ea2f224..47fd6b8bd7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -1,7 +1,7 @@ /* * gstvaapidisplaycache.c - VA display cache * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h index ff679a400f..1964b6b8e6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.h +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.h @@ -1,7 +1,7 @@ /* * gstvaapidisplaycache.h - VA display cache * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 3edc05aa53..41d4a1c2fa 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 19dd2f5374..6e440ef706 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 5f60e2b057..40971c1e12 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index 2dabdee699..7bdadf3d44 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.h b/gst-libs/gst/vaapi/gstvaapiminiobject.h index 2e05a0c1c6..5f5ada948d 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.h @@ -1,7 +1,7 @@ /* * gstvaapiminiobject.h - A lightweight reference counted object * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index b7a9f3aa46..20b2fe5ebe 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index 883c898c20..384ad884b1 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index ae35c9d602..bd53684f61 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index d29db11327..6169c4d3e0 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 1932a01307..639ed2ac6b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index c650d09537..468226d981 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -1,7 +1,7 @@ /* * gstvaapisurface_priv.h - VA surface abstraction (private data) * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 58e2622ace..eb8aecb7a9 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 296342fc6b..bc7a3ed878 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 0ed3fd1c46..2d8fcfa6e6 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index fb5f07c9c4..c47143b25f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index dd22bb1bc0..d3674a7181 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 7adb253e20..0e4a76614c 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index dbfe6858a4..325957433f 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 1725ff237a..053e2e574b 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index a657a70d1b..f984fafd13 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index 47f93cfc22..1229b34cff 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 559d9ac464..92eb4c37d7 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index f81162ce08..05ccdc7af7 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 624a5e0f58..f10a28ccf6 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 5f94342a76..1942d6259a 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h index 35c0ee5fc7..1411952a60 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index ab0ce6db75..700ea6ebb3 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 0481ead4f3..6b8f94ff63 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c index 8a600a5b56..795856845e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -1,7 +1,7 @@ /* * gstvaapiwindow_drm.c - VA/DRM window abstraction * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h index 29cff2fa76..ac97556371 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h @@ -1,7 +1,7 @@ /* * gstvaapiwindow_drm.h - VA/DRM window abstraction * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 62a4816d5f..707a524cd4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index 1d6bbbf58a..307a975d3b 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index 4e56d8007a..f0dc9a51be 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h index d1dc4b85cc..3d0af50d32 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h @@ -1,7 +1,7 @@ /* * gstvaapiwindow_wayland.h - VA/Wayland window abstraction * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Sreerenj Balachandran * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 8b5c73f3c5..d399943482 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index 25ea25ff53..a6fcaf0416 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index 9549c0395a..a72bc88721 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 3f2bc2b855..49c322ec5a 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -1,7 +1,7 @@ /* * gstvaapi.c - VA-API element registration * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * Copyright (C) 2011 Collabora Ltd. * Author: Nicolas Dufresne diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 7d2d3392ec..e28266b0ab 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapidownload.h b/gst/vaapi/gstvaapidownload.h index 33e14468c7..28a93988a8 100644 --- a/gst/vaapi/gstvaapidownload.h +++ b/gst/vaapi/gstvaapidownload.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This program is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index b0306aa576..82349a82ed 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1,7 +1,7 @@ /* * gstvaapipluginutil.h - VA-API plugin helpers * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * Copyright (C) 2011 Collabora * Author: Nicolas Dufresne diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 3341d48690..76194d026b 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -1,7 +1,7 @@ /* * gstvaapipluginutil.h - VA-API plugins private helper * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * Copyright (C) 2011 Collabora * Author: Nicolas Dufresne diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 378e2648a1..c10801d1ae 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -1,7 +1,7 @@ /* * gstvaapipostproc.h - VA-API video post processing * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This program is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index ad482eaf17..fe2bf14de2 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapivideoconverter_glx.h b/gst/vaapi/gstvaapivideoconverter_glx.h index 6afa7335c3..991b67ff3e 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.h +++ b/gst/vaapi/gstvaapivideoconverter_glx.h @@ -1,7 +1,7 @@ /* * gstvaapivideoconverter_glx.h - Gstreamer/VA video converter * - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2013 Intel Corporation * Author: Gwenole Beauchesne * Copyright (C) 2011 Collabora Ltd. * Author: Nicolas Dufresne diff --git a/tests/image.c b/tests/image.c index ff07888e40..9a6b6e7fb6 100644 --- a/tests/image.c +++ b/tests/image.c @@ -3,6 +3,8 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne + * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/image.h b/tests/image.h index ef3210ad52..6abbdb0533 100644 --- a/tests/image.h +++ b/tests/image.h @@ -3,6 +3,8 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne + * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/tests/output.h b/tests/output.h index e08a0a432e..7d109f24f0 100644 --- a/tests/output.h +++ b/tests/output.h @@ -1,7 +1,7 @@ /* * output.h - Video output helpers * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/tests/test-display.c b/tests/test-display.c index 360ce82df8..43ccb10b35 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/tests/test-jpeg.c b/tests/test-jpeg.c index cacb0f5a39..3e4b11db0b 100644 --- a/tests/test-jpeg.c +++ b/tests/test-jpeg.c @@ -1,7 +1,7 @@ /* * test-jpeg.c - JPEG test data * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/tests/test-jpeg.h b/tests/test-jpeg.h index 6372583caf..9fa3ed1b29 100644 --- a/tests/test-jpeg.h +++ b/tests/test-jpeg.h @@ -1,7 +1,7 @@ /* * test-jpeg.h - JPEG test data * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/tests/test-mpeg4.c b/tests/test-mpeg4.c index 19f5d5b53b..240b86ea03 100644 --- a/tests/test-mpeg4.c +++ b/tests/test-mpeg4.c @@ -1,7 +1,7 @@ /* * test-mpeg4.c - MPEG-4 test data * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/tests/test-mpeg4.h b/tests/test-mpeg4.h index fdbf9eac43..aaa613dd1d 100644 --- a/tests/test-mpeg4.h +++ b/tests/test-mpeg4.h @@ -1,7 +1,7 @@ /* * test-mpeg4.h - MPEG-4 test data * - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index 974746174b..c958e0754e 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/tests/test-windows.c b/tests/test-windows.c index 2acb16ee9d..c050cd2421 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or From 370354e418f2b75eeddac1dc9fc6eb4c711e6735 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Nov 2013 06:45:22 +0100 Subject: [PATCH 1396/3781] README: update for GStreamer >= 1.0.x and VPP features. --- README | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README b/README index b9bc070254..f1677928c6 100644 --- a/README +++ b/README @@ -31,7 +31,7 @@ GStreamer and helper libraries. surfaces to video/x-raw-yuv pixels. * `vaapipostproc' is used to postprocess video/x-vaapi-surface - surfaces, for e.g. deinterlacing. + surfaces, for e.g. deinterlacing, denoising and sharpening. * `vaapisink' is used to display video/x-vaapi-surface surfaces to screen. @@ -87,17 +87,22 @@ Usage ----- VA elements are automatically plugged into GStreamer pipelines. So, - using playbin2 should work as is. However, here are a few alternate - pipelines constructed manually. + using playbin (or playbin2 with GStreamer 0.10) 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-0.10 -v filesrc location=/path/to/video.mp4 ! \ + $ gst-launch-1.0 -v filesrc location=/path/to/video.mp4 ! \ qtdemux ! vaapidecode ! vaapisink fullscreen=true * Play a raw MPEG-2 interlaced stream - $ gst-launch-0.10 -v filesrc location=/path/to/mpeg2.bits ! \ + $ gst-launch-1.0 -v filesrc location=/path/to/mpeg2.bits ! \ mpegvideoparse ! vaapidecode ! 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 Reporting Bugs -------------- From 7e1574b06102fee8ac2460a7a57679047a9fb329 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Nov 2013 06:59:51 +0100 Subject: [PATCH 1397/3781] README: updates. - GStreamer 1.2 APIs are supported ; - Video Processing (VA/VPP) features. --- README | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README b/README index f1677928c6..bfb7993ce0 100644 --- a/README +++ b/README @@ -46,6 +46,10 @@ Features * 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 VA Video Processing APIs (VA/VPP) + - Scaling and color conversion + - Image enhancement filters: Sharpening, Noise Reduction + - Advanced deinterlacing: Motion-Adaptive, Motion-Compensated Requirements @@ -61,7 +65,7 @@ Software requirements libgstreamer-plugins-bad0.10-dev (>= 0.10.22.1) or with GstVideoContext, GstSurfaceBuffer, codecparsers - * GStreamer 1.0.x: + * GStreamer 1.0.x (including GStreamer 1.2): libglib2.0-dev (>= 2.28) libgstreamer1.0-dev (>= 1.0.0) libgstreamer-plugins-base1.0-dev (>= 1.0.0) From 98ac557e876ee8e14f7155e50d314819310f2791 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Nov 2013 09:49:30 +0100 Subject: [PATCH 1398/3781] vaapipostproc: fix memory leaks with advanced deinterlacing. Fix memory leaks with advanced deinterlacing, i.e. when we keep track of past buffers. Completely reset the deinterlace state, thus destroying any buffer currently held, on _start(), _stop() and _destroy(). --- gst/vaapi/gstvaapipostproc.c | 97 +++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 2ec839726d..1bf66cb34d 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -189,6 +189,55 @@ gst_vaapi_deinterlace_mode_get_type(void) return deinterlace_mode_type; } +static void +ds_reset(GstVaapiDeinterlaceState *ds) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) + gst_buffer_replace(&ds->buffers[i], NULL); + ds->buffers_index = 0; + ds->num_surfaces = 0; + ds->deint = FALSE; + ds->tff = FALSE; +} + +static void +ds_add_buffer(GstVaapiDeinterlaceState *ds, GstBuffer *buf) +{ + gst_buffer_replace(&ds->buffers[ds->buffers_index], buf); + ds->buffers_index = (ds->buffers_index + 1) % G_N_ELEMENTS(ds->buffers); +} + +static inline GstBuffer * +ds_get_buffer(GstVaapiDeinterlaceState *ds, guint index) +{ + /* Note: the index increases towards older buffers. + i.e. buffer at index 0 means the immediately preceding buffer + in the history, buffer at index 1 means the one preceding the + surface at index 0, etc. */ + const guint n = ds->buffers_index + G_N_ELEMENTS(ds->buffers) - index - 1; + return ds->buffers[n % G_N_ELEMENTS(ds->buffers)]; +} + +static void +ds_set_surfaces(GstVaapiDeinterlaceState *ds) +{ + GstVaapiVideoMeta *meta; + guint i; + + ds->num_surfaces = 0; + for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) { + GstBuffer * const buf = ds_get_buffer(ds, i); + if (!buf) + break; + + meta = gst_buffer_get_vaapi_video_meta(buf); + ds->surfaces[ds->num_surfaces++] = + gst_vaapi_video_meta_get_surface(meta); + } +} + static GstVaapiFilterOpInfo * find_filter_op(GPtrArray *filter_ops, GstVaapiFilterOp op) { @@ -318,6 +367,7 @@ gst_vaapipostproc_destroy_filter(GstVaapiPostproc *postproc) static void gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) { + ds_reset(&postproc->deinterlace_state); #if GST_CHECK_VERSION(1,0,0) g_clear_object(&postproc->sinkpad_buffer_pool); #endif @@ -336,6 +386,7 @@ gst_vaapipostproc_start(GstBaseTransform *trans) { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + ds_reset(&postproc->deinterlace_state); if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; return TRUE; @@ -346,6 +397,7 @@ gst_vaapipostproc_stop(GstBaseTransform *trans) { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + ds_reset(&postproc->deinterlace_state); gst_vaapi_display_replace(&postproc->display, NULL); return TRUE; } @@ -404,51 +456,6 @@ append_output_buffer_metadata(GstBuffer *outbuf, GstBuffer *inbuf, guint flags) 0, -1); } -static void -ds_reset(GstVaapiDeinterlaceState *ds) -{ - guint i; - - for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) - gst_buffer_replace(&ds->buffers[i], NULL); - ds->buffers_index = 0; - ds->num_surfaces = 0; - ds->deint = FALSE; - ds->tff = FALSE; -} - -static void -ds_add_buffer(GstVaapiDeinterlaceState *ds, GstBuffer *buf) -{ - gst_buffer_replace(&ds->buffers[ds->buffers_index], buf); - ds->buffers_index = (ds->buffers_index + 1) % G_N_ELEMENTS(ds->buffers); -} - -static inline GstBuffer * -ds_get_buffer(GstVaapiDeinterlaceState *ds, guint index) -{ - const guint n = ds->buffers_index + G_N_ELEMENTS(ds->buffers) - index - 1; - return ds->buffers[n % G_N_ELEMENTS(ds->buffers)]; -} - -static void -ds_set_surfaces(GstVaapiDeinterlaceState *ds) -{ - GstVaapiVideoMeta *meta; - guint i; - - ds->num_surfaces = 0; - for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) { - GstBuffer * const buf = ds_get_buffer(ds, i); - if (!buf) - break; - - meta = gst_buffer_get_vaapi_video_meta(buf); - ds->surfaces[ds->num_surfaces++] = - gst_vaapi_video_meta_get_surface(meta); - } -} - static GstVaapiDeinterlaceMethod get_next_deint_method(GstVaapiDeinterlaceMethod deint_method) { From 1d1f18bcbe22071599075a7d7e39efa3f7d0c964 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Nov 2013 10:04:45 +0100 Subject: [PATCH 1399/3781] vaapipostproc: fix "mixed" mode deinterlacing. In "mixed" interlaced streams, the buffer contains additional flags that specify whether the frame contained herein is interlaced or not. This means that we can alternatively get progressive or interlaced frames. Make sure to disable deinterlacing at the VPP level when the source buffer is no longer interlaced. --- gst/vaapi/gstvaapipostproc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 1bf66cb34d..b8a7e12076 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -503,7 +503,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *fieldbuf; GstVaapiDeinterlaceMethod deint_method; guint flags, deint_flags; - gboolean tff, deint; + gboolean tff, deint, deint_changed; /* Validate filters */ if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) && @@ -530,7 +530,8 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, deint = is_interlaced_buffer(postproc, inbuf); /* Drop references if deinterlacing conditions changed */ - if (deint != ds->deint || (ds->num_surfaces > 0 && tff != ds->tff)) + deint_changed = deint != ds->deint; + if (deint_changed || (ds->num_surfaces > 0 && tff != ds->tff)) ds_reset(ds); ds->deint = deint; ds->tff = tff; @@ -569,6 +570,13 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, postproc->deinterlace_method = deint_method; } } + else if (deint_changed) { + // Reset internal filter to non-deinterlacing mode + deint_method = GST_VAAPI_DEINTERLACE_METHOD_NONE; + if (!gst_vaapi_filter_set_deinterlacing(postproc->filter, + deint_method, 0)) + goto error_op_deinterlace; + } status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, outbuf_surface, flags); @@ -604,6 +612,9 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, ds->surfaces, ds->num_surfaces, NULL, 0)) goto error_op_deinterlace; } + else if (deint_changed && !gst_vaapi_filter_set_deinterlacing( + postproc->filter, deint_method, 0)) + goto error_op_deinterlace; status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, outbuf_surface, flags); From 7a464ba015535854aa345628766f3014b245fca8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Nov 2013 10:19:06 +0100 Subject: [PATCH 1400/3781] vaapipostproc: fix and optimize advanced deinterlacing mode. Fix advanced deinterlacing modes with VPP to track only up to 2 past reference buffers. This used to be 3 past reference buffers but this doesn't fit with the existing decode pipeline that only has 4 extra scratch surfaces. Also optimize references tracking to be only enabled when needed, i.e. when advanced deinterlacing mode is used. This means that we don't need to track past references for basic bob or weave deinterlacing. --- gst/vaapi/gstvaapipostproc.c | 42 ++++++++++++++++++++++++++++-------- gst/vaapi/gstvaapipostproc.h | 2 +- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index b8a7e12076..27ab992f36 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -456,6 +456,23 @@ append_output_buffer_metadata(GstBuffer *outbuf, GstBuffer *inbuf, guint flags) 0, -1); } +static gboolean +deint_method_is_advanced(GstVaapiDeinterlaceMethod deint_method) +{ + gboolean is_advanced; + + switch (deint_method) { + case GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE: + case GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED: + is_advanced = TRUE; + break; + default: + is_advanced = FALSE; + break; + } + return is_advanced; +} + static GstVaapiDeinterlaceMethod get_next_deint_method(GstVaapiDeinterlaceMethod deint_method) { @@ -503,7 +520,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *fieldbuf; GstVaapiDeinterlaceMethod deint_method; guint flags, deint_flags; - gboolean tff, deint, deint_changed; + gboolean tff, deint, deint_refs, deint_changed; /* Validate filters */ if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) && @@ -542,6 +559,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, /* First field */ deint_method = postproc->deinterlace_method; + deint_refs = deint_method_is_advanced(deint_method); if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) { fieldbuf = create_output_buffer(postproc); if (!fieldbuf) @@ -559,15 +577,19 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, if (!set_best_deint_method(postproc, deint_flags, &deint_method)) goto error_op_deinterlace; - ds_set_surfaces(ds); - if (!gst_vaapi_filter_set_deinterlacing_references(postproc->filter, - ds->surfaces, ds->num_surfaces, NULL, 0)) - goto error_op_deinterlace; - if (deint_method != postproc->deinterlace_method) { GST_DEBUG("unsupported deinterlace-method %u. Using %u instead", postproc->deinterlace_method, deint_method); postproc->deinterlace_method = deint_method; + deint_refs = deint_method_is_advanced(deint_method); + } + + if (deint_refs) { + ds_set_surfaces(ds); + if (!gst_vaapi_filter_set_deinterlacing_references( + postproc->filter, ds->surfaces, ds->num_surfaces, + NULL, 0)) + goto error_op_deinterlace; } } else if (deint_changed) { @@ -608,8 +630,8 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, deint_method, deint_flags)) goto error_op_deinterlace; - if (!gst_vaapi_filter_set_deinterlacing_references(postproc->filter, - ds->surfaces, ds->num_surfaces, NULL, 0)) + if (deint_refs && !gst_vaapi_filter_set_deinterlacing_references( + postproc->filter, ds->surfaces, ds->num_surfaces, NULL, 0)) goto error_op_deinterlace; } else if (deint_changed && !gst_vaapi_filter_set_deinterlacing( @@ -629,7 +651,9 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, } gst_buffer_set_vaapi_video_meta(outbuf, outbuf_meta); gst_vaapi_video_meta_unref(outbuf_meta); - ds_add_buffer(ds, inbuf); + + if (deint && deint_refs) + ds_add_buffer(ds, inbuf); return GST_FLOW_OK; /* ERRORS */ diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index c10801d1ae..e15472e848 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -82,7 +82,7 @@ typedef enum { * number of allowed surfaces used as references shall be less than * the actual number of scratch surfaces used for decoding (4). */ -#define GST_VAAPI_DEINTERLACE_MAX_REFERENCES 3 +#define GST_VAAPI_DEINTERLACE_MAX_REFERENCES 2 /** * GstVaapiPostprocFlags: From 922a04b7347e56fcc8a517aa3f951de894a401b4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Nov 2013 11:15:57 +0100 Subject: [PATCH 1401/3781] vaapostproc: fix memory leaks. Destroy VPP output surface pool on exit. Also avoid a possible crash in double-free situation caused by insufficiently reference counted array of formats returned during initialization. --- gst-libs/gst/vaapi/gstvaapifilter.c | 25 ++++++++++++++----------- gst/vaapi/gstvaapipostproc.c | 1 + 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 8bccc3e127..098ef52ee5 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -885,7 +885,7 @@ deint_refs_clear_all(GstVaapiFilter *filter) /* --- Surface Formats --- */ /* ------------------------------------------------------------------------- */ -static GArray * +static gboolean ensure_formats(GstVaapiFilter *filter) { #if VA_CHECK_VERSION(0,34,0) @@ -894,25 +894,25 @@ ensure_formats(GstVaapiFilter *filter) VAStatus va_status; if (G_LIKELY(filter->formats)) - return filter->formats; + return TRUE; GST_VAAPI_DISPLAY_LOCK(filter->display); va_status = vaQuerySurfaceAttributes(filter->va_display, filter->va_config, NULL, &num_surface_attribs); GST_VAAPI_DISPLAY_UNLOCK(filter->display); if (!vaapi_check_status(va_status, "vaQuerySurfaceAttributes()")) - return NULL; + return FALSE; surface_attribs = g_malloc(num_surface_attribs * sizeof(*surface_attribs)); if (!surface_attribs) - return NULL; + return FALSE; GST_VAAPI_DISPLAY_LOCK(filter->display); va_status = vaQuerySurfaceAttributes(filter->va_display, filter->va_config, surface_attribs, &num_surface_attribs); GST_VAAPI_DISPLAY_UNLOCK(filter->display); if (!vaapi_check_status(va_status, "vaQuerySurfaceAttributes()")) - return NULL; + return FALSE; filter->formats = g_array_sized_new(FALSE, FALSE, sizeof(GstVideoFormat), num_surface_attribs); @@ -936,12 +936,12 @@ ensure_formats(GstVaapiFilter *filter) } g_free(surface_attribs); - return filter->formats; + return TRUE; error: g_free(surface_attribs); #endif - return NULL; + return FALSE; } static inline gboolean @@ -1037,7 +1037,7 @@ gst_vaapi_filter_finalize(GstVaapiFilter *filter) if (filter->forward_references) { g_array_unref(filter->forward_references); - filter->backward_references = NULL; + filter->forward_references = NULL; } if (filter->backward_references) { @@ -1300,7 +1300,7 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter, { #if USE_VA_VPP VAProcPipelineParameterBuffer *pipeline_param = NULL; - VABufferID pipeline_param_buf_id; + VABufferID pipeline_param_buf_id = VA_INVALID_ID; VABufferID filters[N_PROPERTIES]; VAProcPipelineCaps pipeline_caps; guint i, num_filters = 0; @@ -1431,11 +1431,12 @@ gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter, goto error; deint_refs_clear_all(filter); + vaapi_destroy_buffer(filter->va_display, &pipeline_param_buf_id); return GST_VAAPI_FILTER_STATUS_SUCCESS; error: - vaDestroyBuffer(filter->va_display, pipeline_param_buf_id); deint_refs_clear_all(filter); + vaapi_destroy_buffer(filter->va_display, &pipeline_param_buf_id); return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED; #endif return GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_OPERATION; @@ -1477,7 +1478,9 @@ gst_vaapi_filter_get_formats(GstVaapiFilter *filter) { g_return_val_if_fail(filter != NULL, NULL); - return ensure_formats(filter); + if (!ensure_formats(filter)) + return NULL; + return g_array_ref(filter->formats); } /** diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 27ab992f36..6ec3cc6860 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -362,6 +362,7 @@ gst_vaapipostproc_destroy_filter(GstVaapiPostproc *postproc) postproc->filter_ops = NULL; } gst_vaapi_filter_replace(&postproc->filter, NULL); + gst_vaapi_video_pool_replace(&postproc->filter_pool, NULL); } static void From bc8a87d8bb9996d32cd68784fb8a0c5e98210639 Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Thu, 14 Nov 2013 10:58:37 +0000 Subject: [PATCH 1402/3781] build: link libgstvaapi-wayland against videoutils. This library is using symbols that don't exist in GStreamer 0.10 so it needs to link to built-in implementation (libgstvaapi-videoutils). https://bugzilla.gnome.org/show_bug.cgi?id=712282 Signed-off-by: Ross Burton Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index ab605e1368..2429c474fe 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -366,6 +366,7 @@ libgstvaapi_wayland_@GST_API_VERSION@_la_CFLAGS = \ $(GST_BASE_CFLAGS) \ $(WAYLAND_CFLAGS) \ $(LIBVA_WAYLAND_CFLAGS) \ + $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la \ $(NULL) libgstvaapi_wayland_@GST_API_VERSION@_la_LIBADD = \ From e713d43379d9ca1d543bb37f6854f4ef7a03824b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Nov 2013 11:28:09 +0100 Subject: [PATCH 1403/3781] build: fix for Wayland headers not in standard include dirs. Fix build when Wayland headers don't live in plain system include dirs like /usr/include but rather in /usr/include/wayland for instance. Original patch written by Dominique Leuenberger https://bugzilla.gnome.org/show_bug.cgi?id=712282 --- gst/vaapi/Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index cb989935ad..99c2fac982 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -25,6 +25,10 @@ libgstvaapi_LIBS += \ endif if USE_WAYLAND +libgstvaapi_CFLAGS += \ + $(WAYLAND_CFLAGS) \ + $(NULL) + libgstvaapi_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-$(GST_API_VERSION).la endif From 24835654eed2327c5d395966c49c98e2dabcf459 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Nov 2013 11:56:51 +0100 Subject: [PATCH 1404/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index f1994c7b85..b60fd50bfd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [7]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [8]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 082fb3f1b4390aa1fc4c735e57b7ea1b0687b4a2 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 12 Jul 2013 21:33:32 +0800 Subject: [PATCH 1405/3781] libs: add rate-control attributes. Add GstVaapiRateControl types and GType values in view to supporting rate controls for encoding. This is meant to be used for instance in GstVaapiContext. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapitypes.h | 23 +++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.c | 45 ++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 12 ++++++++ gst-libs/gst/vaapi/gstvaapivalue.c | 31 ++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivalue.h | 12 ++++++++ 5 files changed, 123 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 053e2e574b..771ad75da8 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -121,6 +121,29 @@ typedef enum { GST_VAAPI_ROTATION_270 = 270, } GstVaapiRotation; +/** + * GstVaapiRateControl: + * @GST_VAAPI_RATECONTROL_NONE: No rate control performed by the + * underlying driver + * @GST_VAAPI_RATECONTROL_CQP: Constant QP + * @GST_VAAPI_RATECONTROL_CBR: Constant bitrate + * @GST_VAAPI_RATECONTROL_VCM: Video conference mode + * @GST_VAAPI_RATECONTROL_VBR: Variable bitrate + * @GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: Variable bitrate with peak + * rate higher than average bitrate + * + * The set of allowed rate control values for #GstVaapiRateControl. + * Note: this is only valid for encoders. + */ +typedef enum { + GST_VAAPI_RATECONTROL_NONE = 0, + GST_VAAPI_RATECONTROL_CQP, + GST_VAAPI_RATECONTROL_CBR, + GST_VAAPI_RATECONTROL_VCM, + GST_VAAPI_RATECONTROL_VBR, + GST_VAAPI_RATECONTROL_VBR_CONSTRAINED, +} GstVaapiRateControl; + G_END_DECLS #endif /* GST_VAAPI_TYPES_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 2536ad8512..90510e51de 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -210,6 +210,21 @@ string_of_VADisplayAttributeType(VADisplayAttribType attribute_type) return ""; } +const char * +string_of_VARateControl(guint rate_control) +{ + switch (rate_control) { + case VA_RC_NONE: return "None"; + case VA_RC_CQP: return "CQP"; + case VA_RC_CBR: return "CBR"; + case VA_RC_VCM: return "VCM"; + case VA_RC_VBR: return "VBR"; + case VA_RC_VBR_CONSTRAINED: return "VBR-Constrained"; + default: break; + } + return ""; +} + /** * from_GstVaapiChromaType: * @chroma_type: the #GstVaapiChromaType @@ -441,6 +456,36 @@ to_GstVaapiRotation(guint value) return GST_VAAPI_ROTATION_0; } +guint +from_GstVaapiRateControl(guint value) +{ + switch (value) { + case GST_VAAPI_RATECONTROL_NONE: return VA_RC_NONE; + case GST_VAAPI_RATECONTROL_CQP: return VA_RC_CQP; + case GST_VAAPI_RATECONTROL_CBR: return VA_RC_CBR; + case GST_VAAPI_RATECONTROL_VCM: return VA_RC_VCM; + case GST_VAAPI_RATECONTROL_VBR: return VA_RC_VBR; + case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: return VA_RC_VBR_CONSTRAINED; + } + GST_ERROR("unsupported GstVaapiRateControl value %u", value); + return VA_RC_NONE; +} + +guint +to_GstVaapiRateControl(guint value) +{ + switch (value) { + case VA_RC_NONE: return GST_VAAPI_RATECONTROL_NONE; + case VA_RC_CQP: return GST_VAAPI_RATECONTROL_CQP; + case VA_RC_CBR: return GST_VAAPI_RATECONTROL_CBR; + case VA_RC_VCM: return GST_VAAPI_RATECONTROL_VCM; + case VA_RC_VBR: return GST_VAAPI_RATECONTROL_VBR; + case VA_RC_VBR_CONSTRAINED: return GST_VAAPI_RATECONTROL_VBR_CONSTRAINED; + } + GST_ERROR("unsupported VA-API Rate Control value %u", value); + return GST_VAAPI_RATECONTROL_NONE; +} + /* VPP: translate GstVaapiDeinterlaceMethod to VA deinterlacing algorithm */ guint from_GstVaapiDeinterlaceMethod(guint value) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 3355c7fdf4..21d13c2665 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -75,6 +75,10 @@ G_GNUC_INTERNAL const char * string_of_VADisplayAttributeType(VADisplayAttribType attribute_type); +G_GNUC_INTERNAL +const char * +string_of_VARateControl(guint rate_control); + G_GNUC_INTERNAL guint from_GstVaapiChromaType(guint chroma_type); @@ -111,6 +115,14 @@ G_GNUC_INTERNAL guint to_GstVaapiRotation(guint value); +G_GNUC_INTERNAL +guint +from_GstVaapiRateControl(guint value); + +G_GNUC_INTERNAL +guint +to_GstVaapiRateControl(guint value); + G_GNUC_INTERNAL guint from_GstVaapiDeinterlaceMethod(guint value); diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 92eb4c37d7..2f4c239b27 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -119,3 +119,34 @@ gst_vaapi_rotation_get_type(void) g_type = g_enum_register_static("GstVaapiRotation", rotation_values); return g_type; } + +/* --- GstVaapiRateControl --- */ + +GType +gst_vaapi_rate_control_get_type(void) +{ + static volatile gsize g_type = 0; + + static const GEnumValue rate_control_values[] = { + { GST_VAAPI_RATECONTROL_NONE, + "None", "none" }, + { GST_VAAPI_RATECONTROL_CQP, + "Constant QP", "cqp" }, + { GST_VAAPI_RATECONTROL_CBR, + "Constant bitrate", "cbr" }, + { GST_VAAPI_RATECONTROL_VCM, + "Video conference", "vcm" }, + { GST_VAAPI_RATECONTROL_VBR, + "Variable bitrate", "vbr" }, + { GST_VAAPI_RATECONTROL_VBR_CONSTRAINED, + "Variable bitrate - Constrained", "vbr_constrained" }, + { 0, NULL, NULL }, + }; + + if (g_once_init_enter(&g_type)) { + GType type = g_enum_register_static("GstVaapiRateControl", + rate_control_values); + g_once_init_leave(&g_type, type); + } + return g_type; +} diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index 05ccdc7af7..4c4d7982d9 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -68,6 +68,15 @@ G_BEGIN_DECLS */ #define GST_VAAPI_TYPE_ROTATION gst_vaapi_rotation_get_type() +/** + * GST_VAAPI_TYPE_RATE_CONTROL: + * + * A type that represents the VA rate control. + * + * Return value: the #GType of GstVaapiRateControl + */ +#define GST_VAAPI_TYPE_RATE_CONTROL gst_vaapi_rate_control_get_type() + GType gst_vaapi_point_get_type(void) G_GNUC_CONST; @@ -80,6 +89,9 @@ gst_vaapi_render_mode_get_type(void) G_GNUC_CONST; GType gst_vaapi_rotation_get_type(void) G_GNUC_CONST; +GType +gst_vaapi_rate_control_get_type(void) G_GNUC_CONST; + G_END_DECLS #endif /* GST_VAAPI_VALUE_H */ From 02e174c8bc473c6c2fb8b6a5ecf288839537d27e Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 12 Jul 2013 22:07:59 +0800 Subject: [PATCH 1406/3781] libs: add support for rate-control to GstVaapiContext. Extend GstVaapiContextInfo structure to hold the desired rate control mode for encoding purposes. For decoding purposes, this field is not used and it is initialized to GST_VAAPI_RATECONTROL_NONE. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapicontext.c | 40 +++++++++++++++++++++++----- gst-libs/gst/vaapi/gstvaapicontext.h | 4 +++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index dce82f4ebb..0628224539 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -522,7 +522,9 @@ gst_vaapi_context_create(GstVaapiContext *context) GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context); VAProfile va_profile; VAEntrypoint va_entrypoint; - VAConfigAttrib attrib; + guint va_rate_control; + VAConfigAttrib attribs[2]; + guint num_attribs; VAContextID context_id; VASurfaceID surface_id; VAStatus status; @@ -557,26 +559,42 @@ gst_vaapi_context_create(GstVaapiContext *context) va_profile = gst_vaapi_profile_get_va_profile(cip->profile); va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint(cip->entrypoint); + num_attribs = 0; + attribs[num_attribs++].type = VAConfigAttribRTFormat; + if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) + attribs[num_attribs++].type = VAConfigAttribRateControl; + GST_VAAPI_DISPLAY_LOCK(display); - attrib.type = VAConfigAttribRTFormat; status = vaGetConfigAttributes( GST_VAAPI_DISPLAY_VADISPLAY(display), va_profile, va_entrypoint, - &attrib, 1 + attribs, num_attribs ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaGetConfigAttributes()")) goto end; - if (!(attrib.value & VA_RT_FORMAT_YUV420)) + if (!(attribs[0].value & VA_RT_FORMAT_YUV420)) goto end; + if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) { + va_rate_control = from_GstVaapiRateControl(cip->rc_mode); + if (va_rate_control == VA_RC_NONE) + attribs[1].value = VA_RC_NONE; + if ((attribs[1].value & va_rate_control) != va_rate_control) { + GST_ERROR("unsupported %s rate control", + string_of_VARateControl(va_rate_control)); + goto end; + } + attribs[1].value = va_rate_control; + } + GST_VAAPI_DISPLAY_LOCK(display); status = vaCreateConfig( GST_VAAPI_DISPLAY_VADISPLAY(display), va_profile, va_entrypoint, - &attrib, 1, + attribs, num_attribs, &context->config_id ); GST_VAAPI_DISPLAY_UNLOCK(display); @@ -651,6 +669,7 @@ gst_vaapi_context_new( info.profile = profile; info.entrypoint = entrypoint; + info.rc_mode = GST_VAAPI_RATECONTROL_NONE; info.width = width; info.height = height; info.ref_frames = get_max_ref_frames(profile); @@ -719,6 +738,7 @@ gst_vaapi_context_reset( info.profile = profile; info.entrypoint = entrypoint; + info.rc_mode = GST_VAAPI_RATECONTROL_NONE; info.width = width; info.height = height; info.ref_frames = context->info.ref_frames; @@ -742,7 +762,7 @@ gst_vaapi_context_reset_full(GstVaapiContext *context, const GstVaapiContextInfo *new_cip) { GstVaapiContextInfo * const cip = &context->info; - gboolean size_changed, codec_changed; + gboolean size_changed, codec_changed, rc_mode_changed; size_changed = cip->width != new_cip->width || cip->height != new_cip->height; @@ -760,6 +780,14 @@ gst_vaapi_context_reset_full(GstVaapiContext *context, cip->entrypoint = new_cip->entrypoint; } + if (new_cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) { + rc_mode_changed = cip->rc_mode != cip->rc_mode; + if (rc_mode_changed) { + gst_vaapi_context_destroy(context); + cip->rc_mode = new_cip->rc_mode; + } + } + if (size_changed && !gst_vaapi_context_create_surfaces(context)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 8260e14a3e..771f505469 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -45,10 +45,14 @@ typedef struct _GstVaapiContextInfo 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. + * + * Note: @rc_mode is only valid for VA context used for encoding, + * i.e. if @entrypoint is set to @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE. */ struct _GstVaapiContextInfo { GstVaapiProfile profile; GstVaapiEntrypoint entrypoint; + GstVaapiRateControl rc_mode; guint width; guint height; guint ref_frames; From 99947d05926a2d540b9b071e15b060ebe5411f7b Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Mon, 29 Jul 2013 15:41:23 +0800 Subject: [PATCH 1407/3781] libs: add generic bitstream writer. GstBitWriter provides a bit writer that can write any number of bits to a pre-allocated memory buffer. Helper functions are also provided to write any number of bits from 8, 16, 32 and 64 bit variables. Signed-off-by: Gwenole Beauchesne --- configure.ac | 1 + gst-libs/gst/Makefile.am | 2 +- gst-libs/gst/base/Makefile.am | 43 ++++ gst-libs/gst/base/gstbitwriter.c | 278 ++++++++++++++++++++++++ gst-libs/gst/base/gstbitwriter.h | 361 +++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/Makefile.am | 1 + 6 files changed, 685 insertions(+), 1 deletion(-) create mode 100644 gst-libs/gst/base/Makefile.am create mode 100644 gst-libs/gst/base/gstbitwriter.c create mode 100644 gst-libs/gst/base/gstbitwriter.h diff --git a/configure.ac b/configure.ac index b60fd50bfd..20162a3483 100644 --- a/configure.ac +++ b/configure.ac @@ -775,6 +775,7 @@ debian.upstream/libgstvaapi-x11.install.in ext/Makefile gst-libs/Makefile gst-libs/gst/Makefile + gst-libs/gst/base/Makefile gst-libs/gst/codecparsers/Makefile gst-libs/gst/vaapi/Makefile gst-libs/gst/video/Makefile diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 6d09e2b5ee..823fca438f 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = codecparsers video vaapi +SUBDIRS = base codecparsers video vaapi # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in $(gen_headers) diff --git a/gst-libs/gst/base/Makefile.am b/gst-libs/gst/base/Makefile.am new file mode 100644 index 0000000000..0520e64af1 --- /dev/null +++ b/gst-libs/gst/base/Makefile.am @@ -0,0 +1,43 @@ +noinst_LTLIBRARIES = \ + libgstvaapi-baseutils.la \ + $(NULL) + +source_c = \ + gstbitwriter.c \ + $(NULL) + +source_h = \ + gstbitwriter.h \ + $(NULL) + +libgstvaapi_baseutils_cflags = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + -I$(top_builddir)/gst-libs \ + $(GST_BASE_CFLAGS) \ + $(GST_CFLAGS) \ + $(NULL) + +libgstvaapi_baseutils_libs = \ + $(GST_BASE_LIBS) \ + $(GST_LIBS) \ + $(NULL) + +nodist_libgstvaapi_baseutils_la_SOURCES = \ + $(source_c) \ + $(NULL) + +libgstvaapi_baseutils_la_CFLAGS = \ + $(libgstvaapi_baseutils_cflags) \ + $(NULL) + +libgstvaapi_baseutils_la_LIBADD = \ + $(libgstvaapi_baseutils_libs) \ + $(NULL) + +libgstvaapi_baseutils_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(NULL) + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/gst-libs/gst/base/gstbitwriter.c b/gst-libs/gst/base/gstbitwriter.c new file mode 100644 index 0000000000..5fbb2faf39 --- /dev/null +++ b/gst-libs/gst/base/gstbitwriter.c @@ -0,0 +1,278 @@ +/* + * gstbitwriter.c - bitstream writer + * + * Copyright (C) 2013 Intel Corporation + * + * 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 + */ + +#define GST_BIT_WRITER_DISABLE_INLINES + +#include "gstbitwriter.h" + +/** + * gst_bit_writer_init: + * @bitwriter: a #GstBitWriter instance + * @reserved_bits: reserved bits to allocate data + * + * Initializes a #GstBitWriter instance and allocate @reserved_bits + * data inside. + * + * Cleanup function: gst_bit_writer_clear + */ +void +gst_bit_writer_init (GstBitWriter * bitwriter, guint32 reserved_bits) +{ + bitwriter->bit_size = 0; + bitwriter->data = NULL; + bitwriter->bit_capacity = 0; + bitwriter->auto_grow = TRUE; + if (reserved_bits) + _gst_bit_writer_check_space (bitwriter, reserved_bits); +} + +/** + * gst_bit_writer_init_fill: + * @bitwriter: a #GstBitWriter instance + * @data: allocated data + * @bits: size of allocated @data in bits + * + * Initializes a #GstBitWriter instance with alocated @data and @bit outside. + * + * Cleanup function: gst_bit_writer_clear + */ +void +gst_bit_writer_init_fill (GstBitWriter * bitwriter, guint8 * data, guint bits) +{ + bitwriter->bit_size = 0; + bitwriter->data = data; + bitwriter->bit_capacity = bits; + bitwriter->auto_grow = FALSE; +} + +/** + * gst_bit_writer_clear: + * @bitwriter: a #GstBitWriter instance + * @free_data: flag to free #GstBitWriter allocated data + * + * Clear a #GstBitWriter instance and destroy allocated data inside + * if @free_data is %TRUE. + */ +void +gst_bit_writer_clear (GstBitWriter * bitwriter, gboolean free_data) +{ + if (bitwriter->auto_grow && bitwriter->data && free_data) + g_free (bitwriter->data); + + bitwriter->data = NULL; + bitwriter->bit_size = 0; + bitwriter->bit_capacity = 0; +} + +/** + * gst_bit_writer_new: + * @bitwriter: a #GstBitWriter instance + * @reserved_bits: reserved bits to allocate data + * + * Create a #GstBitWriter instance and allocate @reserved_bits data inside. + * + * Free-function: gst_bit_writer_free + * + * Returns: a new #GstBitWriter instance + */ +GstBitWriter * +gst_bit_writer_new (guint32 reserved_bits) +{ + GstBitWriter *ret = g_slice_new0 (GstBitWriter); + + gst_bit_writer_init (ret, reserved_bits); + + return ret; +} + +/** + * gst_bit_writer_new_fill: + * @bitwriter: a #GstBitWriter instance + * @data: allocated data + * @bits: size of allocated @data in bits + * + * Create a #GstBitWriter instance with allocated @data and @bit outside. + * + * Free-function: gst_bit_writer_free + * + * Returns: a new #GstBitWriter instance + */ +GstBitWriter * +gst_bit_writer_new_fill (guint8 * data, guint bits) +{ + GstBitWriter *ret = g_slice_new0 (GstBitWriter); + + gst_bit_writer_init_fill (ret, data, bits); + + return ret; +} + +/** + * gst_bit_writer_free: + * @bitwriter: a #GstBitWriter instance + * @free_data: flag to free @data which is allocated inside + * + * Clear a #GstBitWriter instance and destroy allocated data inside if + * @free_data is %TRUE + */ +void +gst_bit_writer_free (GstBitWriter * writer, gboolean free_data) +{ + g_return_if_fail (writer != NULL); + + gst_bit_writer_clear (writer, free_data); + + g_slice_free (GstBitWriter, writer); +} + +/** + * gst_bit_writer_get_size: + * @bitwriter: a #GstBitWriter instance + * + * Get size of written @data + * + * Returns: size of bits written in @data + */ +guint +gst_bit_writer_get_size (GstBitWriter * bitwriter) +{ + return _gst_bit_writer_get_size_inline (bitwriter); +} + +/** + * gst_bit_writer_get_data: + * @bitwriter: a #GstBitWriter instance + * + * Get written @data pointer + * + * Returns: @data pointer + */ +guint8 * +gst_bit_writer_get_data (GstBitWriter * bitwriter) +{ + return _gst_bit_writer_get_data_inline (bitwriter); +} + +/** + * gst_bit_writer_get_data: + * @bitwriter: a #GstBitWriter instance + * @pos: new position of data end + * + * Set the new postion of data end which should be the new size of @data. + * + * Returns: %TRUE if successful, %FALSE otherwise + */ +gboolean +gst_bit_writer_set_pos (GstBitWriter * bitwriter, guint pos) +{ + return _gst_bit_writer_set_pos_inline (bitwriter, pos); +} + +/** + * gst_bit_writer_put_bits_uint8: + * @bitwriter: a #GstBitWriter instance + * @value: value of #guint8 to write + * @nbits: number of bits to write + * + * Write @nbits bits of @value to #GstBitWriter. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ + +/** + * gst_bit_writer_put_bits_uint16: + * @bitwriter: a #GstBitWriter instance + * @value: value of #guint16 to write + * @nbits: number of bits to write + * + * Write @nbits bits of @value to #GstBitWriter. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ + +/** + * gst_bit_writer_put_bits_uint32: + * @bitwriter: a #GstBitWriter instance + * @value: value of #guint32 to write + * @nbits: number of bits to write + * + * Write @nbits bits of @value to #GstBitWriter. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ + +/** + * gst_bit_writer_put_bits_uint64: + * @bitwriter: a #GstBitWriter instance + * @value: value of #guint64 to write + * @nbits: number of bits to write + * + * Write @nbits bits of @value to #GstBitWriter. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ + +#define GST_BIT_WRITER_WRITE_BITS(bits) \ +gboolean \ +gst_bit_writer_put_bits_uint##bits (GstBitWriter *bitwriter, guint##bits value, guint nbits) \ +{ \ + return _gst_bit_writer_put_bits_uint##bits##_inline (bitwriter, value, nbits); \ +} + +GST_BIT_WRITER_WRITE_BITS (8) +GST_BIT_WRITER_WRITE_BITS (16) +GST_BIT_WRITER_WRITE_BITS (32) +GST_BIT_WRITER_WRITE_BITS (64) + +#undef GST_BIT_WRITER_WRITE_BITS + +/** + * gst_bit_writer_put_bytes: + * @bitwriter: a #GstBitWriter instance + * @data: pointer of data to write + * @nbytes: number of bytes to write + * + * Write @nbytes bytes of @data to #GstBitWriter. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +gboolean +gst_bit_writer_put_bytes (GstBitWriter * bitwriter, + const guint8 * data, guint nbytes) +{ + return _gst_bit_writer_put_bytes_inline (bitwriter, data, nbytes); +} + +/** + * gst_bit_writer_align_bytes: + * @bitwriter: a #GstBitWriter instance + * @trailing_bit: trailing bits of last byte, 0 or 1 + * + * Write trailing bit to align last byte of @data. @trailing_bit can + * only be 1 or 0. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +gboolean +gst_bit_writer_align_bytes (GstBitWriter * bitwriter, guint8 trailing_bit) +{ + return _gst_bit_writer_align_bytes_inline (bitwriter, trailing_bit); +} diff --git a/gst-libs/gst/base/gstbitwriter.h b/gst-libs/gst/base/gstbitwriter.h new file mode 100644 index 0000000000..02ceeab9b5 --- /dev/null +++ b/gst-libs/gst/base/gstbitwriter.h @@ -0,0 +1,361 @@ +/* + * gstbitwriter.h - bitstream writer + * + * Copyright (C) 2013 Intel Corporation + * + * 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_BIT_WRITER_H +#define GST_BIT_WRITER_H + +#include +#include + +G_BEGIN_DECLS + +#define GST_BIT_WRITER_DATA(writer) ((writer)->data) +#define GST_BIT_WRITER_BIT_SIZE(writer) ((writer)->bit_size) +#define GST_BIT_WRITER(writer) ((GstBitWriter *) (writer)) + +typedef struct _GstBitWriter GstBitWriter; + +/** + * GstBitWriter: + * @data: Allocated @data for bit writer to write + * @bit_size: Size of written @data in bits + * + * Private: + * @bit_capacity: Capacity of the allocated @data + * @auto_grow: @data space can auto grow + * + * A bit writer instance. + */ +struct _GstBitWriter +{ + guint8 *data; + guint bit_size; + + /*< private >*/ + guint bit_capacity; + gboolean auto_grow; + gpointer _gst_reserved[GST_PADDING]; +}; + +GstBitWriter * +gst_bit_writer_new (guint32 reserved_bits) G_GNUC_MALLOC; + +GstBitWriter * +gst_bit_writer_new_fill (guint8 * data, guint bits) G_GNUC_MALLOC; + +void +gst_bit_writer_free (GstBitWriter * writer, gboolean free_data); + +void +gst_bit_writer_init (GstBitWriter * bitwriter, guint32 reserved_bits); + +void +gst_bit_writer_init_fill (GstBitWriter * bitwriter, guint8 * data, guint bits); + +void +gst_bit_writer_clear (GstBitWriter * bitwriter, gboolean free_data); + +guint +gst_bit_writer_get_size (GstBitWriter * bitwriter); + +guint8 * +gst_bit_writer_get_data (GstBitWriter * bitwriter); + +gboolean +gst_bit_writer_set_pos (GstBitWriter * bitwriter, guint pos); + +guint +gst_bit_writer_get_space (GstBitWriter * bitwriter); + +gboolean +gst_bit_writer_put_bits_uint8 (GstBitWriter * bitwriter, + guint8 value, guint nbits); + +gboolean +gst_bit_writer_put_bits_uint16 (GstBitWriter * bitwriter, + guint16 value, guint nbits); + +gboolean +gst_bit_writer_put_bits_uint32 (GstBitWriter * bitwriter, + guint32 value, guint nbits); + +gboolean +gst_bit_writer_put_bits_uint64 (GstBitWriter * bitwriter, + guint64 value, guint nbits); + +gboolean +gst_bit_writer_put_bytes (GstBitWriter * bitwriter, const guint8 * data, + guint nbytes); + +gboolean +gst_bit_writer_align_bytes (GstBitWriter * bitwriter, guint8 trailing_bit); + +static const guint8 _gst_bit_writer_bit_filling_mask[9] = { + 0x00, 0x01, 0x03, 0x07, + 0x0F, 0x1F, 0x3F, 0x7F, + 0xFF +}; + +/* Aligned to 256 bytes */ +#define __GST_BITS_WRITER_ALIGNMENT_MASK 2047 +#define __GST_BITS_WRITER_ALIGNED(bitsize) \ + (((bitsize) + __GST_BITS_WRITER_ALIGNMENT_MASK)&(~__GST_BITS_WRITER_ALIGNMENT_MASK)) + +static inline gboolean +_gst_bit_writer_check_space (GstBitWriter * bitwriter, guint32 bits) +{ + guint32 new_bit_size = bits + bitwriter->bit_size; + guint32 clear_pos; + + g_assert (bitwriter->bit_size <= bitwriter->bit_capacity); + if (new_bit_size <= bitwriter->bit_capacity) + return TRUE; + + if (!bitwriter->auto_grow) + return FALSE; + + /* auto grow space */ + new_bit_size = __GST_BITS_WRITER_ALIGNED (new_bit_size); + g_assert (new_bit_size + && ((new_bit_size & __GST_BITS_WRITER_ALIGNMENT_MASK) == 0)); + clear_pos = ((bitwriter->bit_size + 7) >> 3); + bitwriter->data = g_realloc (bitwriter->data, (new_bit_size >> 3)); + memset (bitwriter->data + clear_pos, 0, (new_bit_size >> 3) - clear_pos); + bitwriter->bit_capacity = new_bit_size; + return TRUE; +} + +#undef __GST_BITS_WRITER_ALIGNMENT_MASK +#undef __GST_BITS_WRITER_ALIGNED + +#define __GST_BIT_WRITER_WRITE_BITS_UNCHECKED(bits) \ +static inline void \ +gst_bit_writer_put_bits_uint##bits##_unchecked( \ + GstBitWriter *bitwriter, \ + guint##bits value, \ + guint nbits \ +) \ +{ \ + guint byte_pos, bit_offset; \ + guint8 *cur_byte; \ + guint fill_bits; \ + \ + byte_pos = (bitwriter->bit_size >> 3); \ + bit_offset = (bitwriter->bit_size & 0x07); \ + cur_byte = bitwriter->data + byte_pos; \ + g_assert (nbits <= bits); \ + g_assert( bit_offset < 8 && \ + bitwriter->bit_size <= bitwriter->bit_capacity); \ + \ + while (nbits) { \ + fill_bits = ((8 - bit_offset) < nbits ? (8 - bit_offset) : nbits); \ + nbits -= fill_bits; \ + bitwriter->bit_size += fill_bits; \ + \ + *cur_byte |= (((value >> nbits) & _gst_bit_writer_bit_filling_mask[fill_bits]) \ + << (8 - bit_offset - fill_bits)); \ + ++cur_byte; \ + bit_offset = 0; \ + } \ + g_assert(cur_byte <= \ + (bitwriter->data + (bitwriter->bit_capacity >> 3))); \ +} + +__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (8) +__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (16) +__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (32) +__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (64) +#undef __GST_BIT_WRITER_WRITE_BITS_UNCHECKED + +static inline guint +gst_bit_writer_get_size_unchecked (GstBitWriter * bitwriter) +{ + return GST_BIT_WRITER_BIT_SIZE (bitwriter); +} + +static inline guint8 * +gst_bit_writer_get_data_unchecked (GstBitWriter * bitwriter) +{ + return GST_BIT_WRITER_DATA (bitwriter); +} + +static inline gboolean +gst_bit_writer_set_pos_unchecked (GstBitWriter * bitwriter, guint pos) +{ + GST_BIT_WRITER_BIT_SIZE (bitwriter) = pos; + return TRUE; +} + +static inline guint +gst_bit_writer_get_space_unchecked (GstBitWriter * bitwriter) +{ + return bitwriter->bit_capacity - bitwriter->bit_size; +} + +static inline void +gst_bit_writer_put_bytes_unchecked (GstBitWriter * bitwriter, + const guint8 * data, guint nbytes) +{ + if ((bitwriter->bit_size & 0x07) == 0) { + memcpy (&bitwriter->data[bitwriter->bit_size >> 3], data, nbytes); + bitwriter->bit_size += (nbytes << 3); + } else { + g_assert (0); + while (nbytes) { + gst_bit_writer_put_bits_uint8_unchecked (bitwriter, *data, 8); + --nbytes; + ++data; + } + } +} + +static inline void +gst_bit_writer_align_bytes_unchecked (GstBitWriter * bitwriter, + guint8 trailing_bit) +{ + guint32 bit_offset, bit_left; + guint8 value = 0; + + bit_offset = (bitwriter->bit_size & 0x07); + if (!bit_offset) + return; + + bit_left = 8 - bit_offset; + if (trailing_bit) + value = _gst_bit_writer_bit_filling_mask[bit_left]; + return gst_bit_writer_put_bits_uint8_unchecked (bitwriter, value, bit_left); +} + +#define __GST_BIT_WRITER_WRITE_BITS_INLINE(bits) \ +static inline gboolean \ +_gst_bit_writer_put_bits_uint##bits##_inline( \ + GstBitWriter *bitwriter, \ + guint##bits value, \ + guint nbits \ +) \ +{ \ + g_return_val_if_fail(bitwriter != NULL, FALSE); \ + g_return_val_if_fail(nbits != 0, FALSE); \ + g_return_val_if_fail(nbits <= bits, FALSE); \ + \ + if (!_gst_bit_writer_check_space(bitwriter, nbits)) \ + return FALSE; \ + gst_bit_writer_put_bits_uint##bits##_unchecked(bitwriter, value, nbits); \ + return TRUE; \ +} + +__GST_BIT_WRITER_WRITE_BITS_INLINE (8) +__GST_BIT_WRITER_WRITE_BITS_INLINE (16) +__GST_BIT_WRITER_WRITE_BITS_INLINE (32) +__GST_BIT_WRITER_WRITE_BITS_INLINE (64) +#undef __GST_BIT_WRITER_WRITE_BITS_INLINE + +static inline guint +_gst_bit_writer_get_size_inline (GstBitWriter * bitwriter) +{ + g_return_val_if_fail (bitwriter != NULL, 0); + + return gst_bit_writer_get_size_unchecked (bitwriter); +} + +static inline guint8 * +_gst_bit_writer_get_data_inline (GstBitWriter * bitwriter) +{ + g_return_val_if_fail (bitwriter != NULL, NULL); + + return gst_bit_writer_get_data_unchecked (bitwriter); +} + +static inline gboolean +_gst_bit_writer_set_pos_inline (GstBitWriter * bitwriter, guint pos) +{ + g_return_val_if_fail (bitwriter != NULL, FALSE); + g_return_val_if_fail (pos <= bitwriter->bit_capacity, FALSE); + + return gst_bit_writer_set_pos_unchecked (bitwriter, pos); +} + +static inline guint +_gst_bit_writer_get_space_inline (GstBitWriter * bitwriter) +{ + g_return_val_if_fail (bitwriter != NULL, 0); + g_return_val_if_fail (bitwriter->bit_size < bitwriter->bit_capacity, 0); + + return gst_bit_writer_get_space_unchecked (bitwriter); +} + +static inline gboolean +_gst_bit_writer_put_bytes_inline (GstBitWriter * bitwriter, + const guint8 * data, guint nbytes) +{ + g_return_val_if_fail (bitwriter != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (nbytes, FALSE); + + if (!_gst_bit_writer_check_space (bitwriter, nbytes * 8)) + return FALSE; + + gst_bit_writer_put_bytes_unchecked (bitwriter, data, nbytes); + return TRUE; +} + +static inline gboolean +_gst_bit_writer_align_bytes_inline (GstBitWriter * bitwriter, + guint8 trailing_bit) +{ + g_return_val_if_fail (bitwriter != NULL, FALSE); + g_return_val_if_fail ((trailing_bit == 0 || trailing_bit == 1), FALSE); + g_return_val_if_fail (((bitwriter->bit_size + 7) & (~7)) <= + bitwriter->bit_capacity, FALSE); + + gst_bit_writer_align_bytes_unchecked (bitwriter, trailing_bit); + return TRUE; +} + +#ifndef GST_BIT_WRITER_DISABLE_INLINES +#define gst_bit_writer_get_size(bitwriter) \ + _gst_bit_writer_get_size_inline(bitwriter) +#define gst_bit_writer_get_data(bitwriter) \ + _gst_bit_writer_get_data_inline(bitwriter) +#define gst_bit_writer_set_pos(bitwriter, pos) \ + G_LIKELY (_gst_bit_writer_set_pos_inline (bitwriter, pos)) +#define gst_bit_writer_get_space(bitwriter) \ + _gst_bit_writer_get_space_inline(bitwriter) + +#define gst_bit_writer_put_bits_uint8(bitwriter, value, nbits) \ + G_LIKELY (_gst_bit_writer_put_bits_uint8_inline (bitwriter, value, nbits)) +#define gst_bit_writer_put_bits_uint16(bitwriter, value, nbits) \ + G_LIKELY (_gst_bit_writer_put_bits_uint16_inline (bitwriter, value, nbits)) +#define gst_bit_writer_put_bits_uint32(bitwriter, value, nbits) \ + G_LIKELY (_gst_bit_writer_put_bits_uint32_inline (bitwriter, value, nbits)) +#define gst_bit_writer_put_bits_uint64(bitwriter, value, nbits) \ + G_LIKELY (_gst_bit_writer_put_bits_uint64_inline (bitwriter, value, nbits)) + +#define gst_bit_writer_put_bytes(bitwriter, data, nbytes) \ + G_LIKELY (_gst_bit_writer_put_bytes_inline (bitwriter, data, nbytes)) + +#define gst_bit_writer_align_bytes(bitwriter, trailing_bit) \ + G_LIKELY (_gst_bit_writer_align_bytes_inline(bitwriter, trailing_bit)) +#endif + +G_END_DECLS + +#endif /* GST_BIT_WRITER_H */ diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 2429c474fe..208daece62 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -39,6 +39,7 @@ libgstvaapi_libs = \ $(GST_VIDEO_LIBS) \ $(GST_CODEC_PARSERS_LIBS) \ $(LIBVA_LIBS) \ + $(top_builddir)/gst-libs/gst/base/libgstvaapi-baseutils.la \ $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la \ $(top_builddir)/gst-libs/gst/codecparsers/libgstvaapi-codecparsers.la From 8174a3573771f8110b27892335ecee7bf8299f49 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Mon, 29 Jul 2013 13:34:06 +0800 Subject: [PATCH 1408/3781] Add initial infrastructure for video encoding. Add initial API for video encoding: only basic interfaces and small encoder objects are implemented so far. Signed-off-by: Gwenole Beauchesne --- configure.ac | 29 + gst-libs/gst/vaapi/Makefile.am | 20 + gst-libs/gst/vaapi/gstvaapiencoder.c | 688 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 91 +++ gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 598 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 379 ++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 188 +++++ 7 files changed, 1993 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder.c create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder.h create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_objects.c create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_objects.h create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_priv.h diff --git a/configure.ac b/configure.ac index 20162a3483..e8fcb85886 100644 --- a/configure.ac +++ b/configure.ac @@ -37,12 +37,14 @@ m4_define([wayland_api_version], [1.0.0]) # VA-API minimum version number m4_define([va_api_version], [0.30.4]) +m4_define([va_api_enc_version], [0.34.0]) m4_define([va_api_drm_version], [0.33.0]) m4_define([va_api_x11_version], [0.31.0]) m4_define([va_api_glx_version], [0.32.0]) m4_define([va_api_wld_version], [0.33.0]) # libva package version number +m4_define([libva_enc_package_version], [1.2.0]) m4_define([libva_drm_package_version], [1.1.0]) m4_define([libva_x11_package_version], [1.0.3]) m4_define([libva_glx_package_version], [1.0.9]) @@ -98,6 +100,11 @@ AC_ARG_ENABLE(builtin_codecparsers, [enable built-in codecparsers @<:@default=yes@:>@]), [], [enable_builtin_codecparsers="yes"]) +AC_ARG_ENABLE([encoders], + AS_HELP_STRING([--enable-encoders], + [enable video encoders @<:@default=yes@:>@]), + [], [enable_encoders="yes"]) + AC_ARG_ENABLE(drm, AS_HELP_STRING([--enable-drm], [enable DRM backend @<:@default=yes@:>@]), @@ -700,6 +707,23 @@ AC_CACHE_CHECK([for video post-postprocessing API], LIBS="$saved_LIBS" ]) +dnl Check for encoding support +USE_ENCODERS=0 +if test "$enable_encoders" = "yes"; then + PKG_CHECK_MODULES([LIBVA], [libva >= va_api_enc_version], + [HAVE_VA_ENC=1], [HAVE_VA_ENC=0]) + + if test $HAVE_VA_ENC -eq 1; then + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$LIBVA_CFLAGS" + AC_CHECK_HEADERS([va/va_enc_mpeg2.h va/va_enc_h264.h], + [USE_ENCODERS=1], [HAVE_VA_ENC=0 USE_ENCODERS=0], + [#include + ]) + CPPFLAGS="$saved_CPPFLAGS" + fi +fi + dnl VA/Wayland API if test "$enable_wayland" = "yes"; then PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= va_api_wld_version], @@ -718,6 +742,10 @@ case ":$USE_X11:$USE_GLX:$USE_WAYLAND:$USE_DRM:" in ;; esac +AC_DEFINE_UNQUOTED([USE_ENCODERS], $USE_ENCODERS, + [Defined to 1 if video encoders are used]) +AM_CONDITIONAL([USE_ENCODERS], [test $USE_ENCODERS -eq 1]) + AC_DEFINE_UNQUOTED(USE_VA_VPP, $USE_VA_VPP, [Defined to 1 if video post-processing is used]) AM_CONDITIONAL(USE_VA_VPP, test $USE_VA_VPP -eq 1) @@ -812,5 +840,6 @@ echo $PACKAGE configuration summary: echo echo GStreamer API version ............ : $GST_API_VERSION echo VA-API version ................... : $VA_VERSION_STR +echo Video encoding ................... : $(yesno $USE_ENCODERS) echo Video outputs .................... : $VIDEO_OUTPUTS echo diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 208daece62..52b4bf9aa0 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -134,6 +134,26 @@ libgstvaapi_source_c += $(libgstvaapi_jpegdec_source_c) libgstvaapi_source_h += $(libgstvaapi_jpegdec_source_h) endif +libgstvaapi_enc_source_c = \ + gstvaapiencoder.c \ + gstvaapiencoder_objects.c \ + $(NULL) + +libgstvaapi_enc_source_h = \ + gstvaapiencoder.h \ + $(NULL) + +libgstvaapi_enc_source_priv_h = \ + gstvaapiencoder_objects.h \ + gstvaapiencoder_priv.h \ + $(NULL) + +if USE_ENCODERS +libgstvaapi_source_c += $(libgstvaapi_enc_source_c) +libgstvaapi_source_h += $(libgstvaapi_enc_source_h) +libgstvaapi_source_priv_h += $(libgstvaapi_enc_source_priv_h) +endif + libgstvaapi_drm_source_c = \ gstvaapidisplay_drm.c \ gstvaapiwindow_drm.c \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c new file mode 100644 index 0000000000..519e8f7f18 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -0,0 +1,688 @@ +/* + * gstvaapiencoder.c - VA encoder abstraction + * + * Copyright (C) 2013 Intel Corporation + * + * 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 "gstvaapiencoder.h" +#include "gstvaapiencoder_priv.h" +#include "gstvaapicontext.h" +#include "gstvaapidisplay_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +typedef struct _GstVaapiCodedBufferProxyClass GstVaapiCodedBufferProxyClass; + +#define GST_VAAPI_ENCODER_LOCK(encoder) \ + G_STMT_START { \ + g_mutex_lock (&(GST_VAAPI_ENCODER_CAST(encoder))->lock); \ + } G_STMT_END + +#define GST_VAAPI_ENCODER_UNLOCK(encoder) \ + G_STMT_START { \ + g_mutex_unlock (&(GST_VAAPI_ENCODER_CAST(encoder))->lock); \ + } G_STMT_END + +#define GST_VAAPI_ENCODER_BUF_FREE_WAIT(encoder) \ + G_STMT_START { \ + g_cond_wait (&(GST_VAAPI_ENCODER_CAST(encoder))->codedbuf_free, \ + &(GST_VAAPI_ENCODER_CAST(encoder))->lock); \ + } G_STMT_END + +#define GST_VAAPI_ENCODER_BUF_FREE_SIGNAL(encoder) \ + G_STMT_START { \ + g_cond_signal (&(GST_VAAPI_ENCODER_CAST(encoder))->codedbuf_free); \ + } G_STMT_END + +#define GST_VAAPI_ENCODER_FREE_SURFACE_WAIT(encoder) \ + G_STMT_START { \ + g_cond_wait (&(GST_VAAPI_ENCODER_CAST(encoder))->surface_free, \ + &(GST_VAAPI_ENCODER_CAST(encoder))->lock); \ + } G_STMT_END + +#define GST_VAAPI_ENCODER_FREE_SURFACE_SIGNAL(encoder) \ + G_STMT_START { \ + g_cond_signal (&(GST_VAAPI_ENCODER_CAST(encoder))->surface_free); \ + } G_STMT_END + +#define GST_VAAPI_ENCODER_SYNC_SIGNAL(encoder) \ + G_STMT_START { \ + g_cond_signal (&(GST_VAAPI_ENCODER_CAST(encoder))->sync_ready); \ + } G_STMT_END + +static inline gboolean +GST_VAAPI_ENCODER_SYNC_WAIT_TIMEOUT (GstVaapiEncoder * encoder, gint64 timeout) +{ + gint64 end_time = g_get_monotonic_time () + timeout; + return g_cond_wait_until (&encoder->sync_ready, &encoder->lock, end_time); +} + +static GstVaapiCodedBuffer * +gst_vaapi_encoder_dequeue_coded_buffer (GstVaapiEncoder * encoder); + +static void +gst_vaapi_encoder_queue_coded_buffer (GstVaapiEncoder * encoder, + GstVaapiCodedBuffer * buf); + +typedef struct +{ + GstVaapiEncPicture *picture; + GstVaapiCodedBufferProxy *buf; +} GstVaapiEncoderSyncPic; + +static void +gst_vaapi_coded_buffer_proxy_finalize (GstVaapiCodedBufferProxy * proxy) +{ + if (proxy->buffer) { + gst_vaapi_coded_buffer_unmap (proxy->buffer); + if (proxy->encoder) + gst_vaapi_encoder_queue_coded_buffer (proxy->encoder, proxy->buffer); + else { + g_assert (FALSE); + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (proxy->buffer)); + } + proxy->buffer = NULL; + } + gst_vaapi_encoder_replace (&proxy->encoder, NULL); +} + +static void +gst_vaapi_coded_buffer_proxy_class_init (GstVaapiCodedBufferProxyClass * klass) +{ + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + + object_class->size = sizeof (GstVaapiCodedBufferProxy); + object_class->finalize = + (GDestroyNotify) gst_vaapi_coded_buffer_proxy_finalize; +} + +static inline const GstVaapiCodedBufferProxyClass * +gst_vaapi_coded_buffer_proxy_class (void) +{ + static GstVaapiCodedBufferProxyClass g_class; + static gsize g_class_init = FALSE; + + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_coded_buffer_proxy_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return (&g_class); +} + +GstVaapiCodedBufferProxy * +gst_vaapi_coded_buffer_proxy_new (GstVaapiEncoder * encoder) +{ + GstVaapiCodedBuffer *buf; + GstVaapiCodedBufferProxy *ret; + + g_assert (encoder); + buf = gst_vaapi_encoder_dequeue_coded_buffer (encoder); + if (!buf) + return NULL; + + ret = (GstVaapiCodedBufferProxy *) + gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS + (gst_vaapi_coded_buffer_proxy_class ())); + g_assert (ret); + ret->encoder = gst_vaapi_encoder_ref (encoder); + ret->buffer = buf; + return ret; +} + +GstVaapiCodedBufferProxy * +gst_vaapi_coded_buffer_proxy_ref (GstVaapiCodedBufferProxy * proxy) +{ + return (GstVaapiCodedBufferProxy *) + gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (proxy)); +} + +void +gst_vaapi_coded_buffer_proxy_unref (GstVaapiCodedBufferProxy * proxy) +{ + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (proxy)); +} + +void +gst_vaapi_coded_buffer_proxy_replace (GstVaapiCodedBufferProxy ** old_proxy_ptr, + GstVaapiCodedBufferProxy * new_proxy) +{ + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_proxy_ptr, + GST_VAAPI_MINI_OBJECT (new_proxy)); +} + +GstVaapiEncoder * +gst_vaapi_encoder_ref (GstVaapiEncoder * encoder) +{ + return gst_vaapi_object_ref (encoder); +} + +void +gst_vaapi_encoder_unref (GstVaapiEncoder * encoder) +{ + gst_vaapi_object_unref (encoder); +} + +void +gst_vaapi_encoder_replace (GstVaapiEncoder ** old_encoder_ptr, + GstVaapiEncoder * new_encoder) +{ + gst_vaapi_object_replace (old_encoder_ptr, new_encoder); +} + +static gboolean +gst_vaapi_encoder_init_coded_buffer_queue (GstVaapiEncoder * encoder, + guint count) +{ + GstVaapiCodedBuffer *buf; + guint i = 0; + + GST_VAAPI_ENCODER_LOCK (encoder); + if (count > encoder->max_buf_num) + count = encoder->max_buf_num; + + g_assert (encoder->buf_size); + for (i = 0; i < count; ++i) { + buf = GST_VAAPI_CODED_BUFFER_NEW (encoder, encoder->buf_size); + g_queue_push_tail (&encoder->coded_buffers, buf); + ++encoder->buf_count; + } + g_assert (encoder->buf_count <= encoder->max_buf_num); + + GST_VAAPI_ENCODER_UNLOCK (encoder); + return TRUE; +} + +static GstVaapiCodedBuffer * +gst_vaapi_encoder_dequeue_coded_buffer (GstVaapiEncoder * encoder) +{ + GstVaapiCodedBuffer *ret = NULL; + + GST_VAAPI_ENCODER_LOCK (encoder); + while (encoder->buf_count >= encoder->max_buf_num && + g_queue_is_empty (&encoder->coded_buffers)) { + GST_VAAPI_ENCODER_BUF_FREE_WAIT (encoder); + } + if (!g_queue_is_empty (&encoder->coded_buffers)) { + ret = (GstVaapiCodedBuffer *) g_queue_pop_head (&encoder->coded_buffers); + goto end; + } + + g_assert (encoder->buf_size); + ret = GST_VAAPI_CODED_BUFFER_NEW (encoder, encoder->buf_size); + if (ret) + ++encoder->buf_count; + +end: + GST_VAAPI_ENCODER_UNLOCK (encoder); + return ret; +} + +static void +gst_vaapi_encoder_queue_coded_buffer (GstVaapiEncoder * encoder, + GstVaapiCodedBuffer * buf) +{ + g_assert (buf); + g_return_if_fail (buf); + + GST_VAAPI_ENCODER_LOCK (encoder); + g_queue_push_tail (&encoder->coded_buffers, buf); + GST_VAAPI_ENCODER_BUF_FREE_SIGNAL (encoder); + GST_VAAPI_ENCODER_UNLOCK (encoder); +} + +static gboolean +gst_vaapi_encoder_free_coded_buffers (GstVaapiEncoder * encoder) +{ + GstVaapiCodedBuffer *buf; + guint count = 0; + gboolean ret; + + GST_VAAPI_ENCODER_LOCK (encoder); + while (!g_queue_is_empty (&encoder->coded_buffers)) { + buf = (GstVaapiCodedBuffer *) g_queue_pop_head (&encoder->coded_buffers); + g_assert (buf); + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (buf)); + ++count; + } + ret = (count == encoder->buf_count); + GST_VAAPI_ENCODER_UNLOCK (encoder); + + if (!ret) { + GST_ERROR ("coded buffer leak, freed count:%d, total buf:%d", + count, encoder->buf_count); + } + + return ret; +} + +static void +_surface_proxy_released_notify (GstVaapiEncoder * encoder) +{ + GST_VAAPI_ENCODER_FREE_SURFACE_SIGNAL (encoder); +} + +GstVaapiSurfaceProxy * +gst_vaapi_encoder_create_surface (GstVaapiEncoder * encoder) +{ + GstVaapiSurfaceProxy *proxy; + + g_assert (encoder && encoder->context); + g_return_val_if_fail (encoder->context, NULL); + + GST_VAAPI_ENCODER_LOCK (encoder); + while (!gst_vaapi_context_get_surface_count (encoder->context)) { + GST_VAAPI_ENCODER_FREE_SURFACE_WAIT (encoder); + } + proxy = gst_vaapi_context_get_surface_proxy (encoder->context); + GST_VAAPI_ENCODER_UNLOCK (encoder); + + gst_vaapi_surface_proxy_set_destroy_notify (proxy, + (GDestroyNotify) _surface_proxy_released_notify, encoder); + + return proxy; +} + +void +gst_vaapi_encoder_release_surface (GstVaapiEncoder * encoder, + GstVaapiSurfaceProxy * surface) +{ + GST_VAAPI_ENCODER_LOCK (encoder); + gst_vaapi_surface_proxy_unref (surface); + GST_VAAPI_ENCODER_UNLOCK (encoder); +} + +static GstVaapiEncoderSyncPic * +_create_sync_picture (GstVaapiEncPicture * picture, + GstVaapiCodedBufferProxy * coded_buf) +{ + GstVaapiEncoderSyncPic *sync = g_slice_new0 (GstVaapiEncoderSyncPic); + + g_assert (picture && coded_buf); + sync->picture = gst_vaapi_enc_picture_ref (picture); + sync->buf = gst_vaapi_coded_buffer_proxy_ref (coded_buf); + return sync; +} + +static void +_free_sync_picture (GstVaapiEncoder * encoder, + GstVaapiEncoderSyncPic * sync_pic) +{ + g_assert (sync_pic); + + if (sync_pic->picture) + gst_vaapi_enc_picture_unref (sync_pic->picture); + if (sync_pic->buf) + gst_vaapi_coded_buffer_proxy_unref (sync_pic->buf); + g_slice_free (GstVaapiEncoderSyncPic, sync_pic); +} + +static void +gst_vaapi_encoder_free_sync_pictures (GstVaapiEncoder * encoder) +{ + GstVaapiEncoderSyncPic *sync; + + GST_VAAPI_ENCODER_LOCK (encoder); + while (!g_queue_is_empty (&encoder->sync_pictures)) { + sync = + (GstVaapiEncoderSyncPic *) g_queue_pop_head (&encoder->sync_pictures); + _free_sync_picture (encoder, sync); + } + GST_VAAPI_ENCODER_UNLOCK (encoder); +} + +static gboolean +gst_vaapi_encoder_push_sync_picture (GstVaapiEncoder * encoder, + GstVaapiEncoderSyncPic * sync_pic) +{ + GST_VAAPI_ENCODER_LOCK (encoder); + g_queue_push_tail (&encoder->sync_pictures, sync_pic); + GST_VAAPI_ENCODER_SYNC_SIGNAL (encoder); + GST_VAAPI_ENCODER_UNLOCK (encoder); + return TRUE; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_pop_sync_picture (GstVaapiEncoder * encoder, + GstVaapiEncoderSyncPic ** sync_pic, guint64 timeout) +{ + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; + + *sync_pic = NULL; + + GST_VAAPI_ENCODER_LOCK (encoder); + if (g_queue_is_empty (&encoder->sync_pictures) && + !GST_VAAPI_ENCODER_SYNC_WAIT_TIMEOUT (encoder, timeout)) + goto timeout; + + if (g_queue_is_empty (&encoder->sync_pictures)) { + ret = GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR; + goto end; + } + + *sync_pic = + (GstVaapiEncoderSyncPic *) g_queue_pop_head (&encoder->sync_pictures); + g_assert (*sync_pic); + ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; + goto end; + +timeout: + ret = GST_VAAPI_ENCODER_STATUS_TIMEOUT; + +end: + GST_VAAPI_ENCODER_UNLOCK (encoder); + return ret; +} + +GstVaapiEncoderStatus +gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, + GstVideoCodecFrame * frame) +{ + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; + GstVaapiEncoderClass *klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + GstVaapiEncPicture *picture = NULL; + GstVaapiCodedBufferProxy *coded_buf = NULL; + GstVaapiEncoderSyncPic *sync_pic = NULL; + + if (!klass->reordering || !klass->encode) + goto error; + +again: + picture = NULL; + sync_pic = NULL; + ret = klass->reordering (encoder, frame, FALSE, &picture); + + if (ret == GST_VAAPI_ENCODER_STATUS_FRAME_NOT_READY) + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + g_assert (picture); + if (ret != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto error; + if (!picture) { + ret = GST_VAAPI_ENCODER_STATUS_PICTURE_ERR; + goto error; + } + + coded_buf = gst_vaapi_coded_buffer_proxy_new (encoder); + if (!coded_buf) { + ret = GST_VAAPI_ENCODER_STATUS_OBJECT_ERR; + goto error; + } + + ret = klass->encode (encoder, picture, coded_buf); + if (ret != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto error; + + /* another thread would sync and get coded buffer */ + sync_pic = _create_sync_picture (picture, coded_buf); + gst_vaapi_coded_buffer_proxy_replace (&coded_buf, NULL); + gst_vaapi_enc_picture_replace (&picture, NULL); + + if (!gst_vaapi_encoder_push_sync_picture (encoder, sync_pic)) { + ret = GST_VAAPI_ENCODER_STATUS_THREAD_ERR; + goto error; + } + + frame = NULL; + goto again; + +error: + gst_vaapi_enc_picture_replace (&picture, NULL); + gst_vaapi_coded_buffer_proxy_replace (&coded_buf, NULL); + if (sync_pic) + _free_sync_picture (encoder, sync_pic); + GST_ERROR ("encoding failed, error:%d", ret); + return ret; +} + +GstVaapiEncoderStatus +gst_vaapi_encoder_get_buffer (GstVaapiEncoder * encoder, + GstVideoCodecFrame ** frame, + GstVaapiCodedBufferProxy ** codedbuf, gint64 us_of_timeout) +{ + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; + GstVaapiEncoderSyncPic *sync_pic = NULL; + GstVaapiSurfaceStatus surface_status; + GstVaapiEncPicture *picture; + + ret = gst_vaapi_encoder_pop_sync_picture (encoder, &sync_pic, us_of_timeout); + if (ret != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto end; + + picture = sync_pic->picture; + + if (!picture->surface || !gst_vaapi_surface_sync (picture->surface)) { + ret = GST_VAAPI_ENCODER_STATUS_PARAM_ERR; + goto end; + } + if (!gst_vaapi_surface_query_status (picture->surface, &surface_status)) { + ret = GST_VAAPI_ENCODER_STATUS_PICTURE_ERR; + goto end; + } + if (frame) + *frame = gst_video_codec_frame_ref (picture->frame); + if (codedbuf) + *codedbuf = gst_vaapi_coded_buffer_proxy_ref (sync_pic->buf); + +end: + if (sync_pic) + _free_sync_picture (encoder, sync_pic); + return ret; +} + +GstVaapiEncoderStatus +gst_vaapi_encoder_flush (GstVaapiEncoder * encoder) +{ + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; + GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + + if (!klass->flush) + goto error; + + ret = klass->flush (encoder); + return ret; + +error: + GST_ERROR ("flush failed"); + return GST_VAAPI_ENCODER_STATUS_FUNC_PTR_ERR; +} + +GstVaapiEncoderStatus +gst_vaapi_encoder_get_codec_data (GstVaapiEncoder * encoder, + GstBuffer ** codec_data) +{ + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; + GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + + *codec_data = NULL; + if (!klass->get_codec_data) + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + ret = klass->get_codec_data (encoder, codec_data); + return ret; +} + +static gboolean +gst_vaapi_encoder_ensure_context (GstVaapiEncoder * encoder) +{ + GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + GstVaapiContextInfo info; + GstVaapiContext *context; + + if (GST_VAAPI_ENCODER_CONTEXT (encoder)) + return TRUE; + + memset (&info, 0, sizeof (info)); + if (!klass->get_context_info || !klass->get_context_info (encoder, &info)) { + return FALSE; + } + + context = gst_vaapi_context_new_full (GST_VAAPI_ENCODER_DISPLAY (encoder), + &info); + if (!context) + return FALSE; + + GST_VAAPI_ENCODER_CONTEXT (encoder) = context; + GST_VAAPI_ENCODER_VA_CONTEXT (encoder) = gst_vaapi_context_get_id (context); + return TRUE; +} + +GstCaps * +gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, + GstVideoCodecState * in_state, GstCaps * ref_caps) +{ + GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + GstCaps *out_caps = NULL; + + if (!GST_VIDEO_INFO_WIDTH (&in_state->info) || + !GST_VIDEO_INFO_HEIGHT (&in_state->info)) { + GST_WARNING ("encoder set format failed, width or height equal to 0."); + return NULL; + } + GST_VAAPI_ENCODER_VIDEO_INFO (encoder) = in_state->info; + + if (!klass->set_format) + goto error; + + out_caps = klass->set_format (encoder, in_state, ref_caps); + if (!out_caps) + goto error; + + if (GST_VAAPI_ENCODER_CAPS (encoder) && + gst_caps_is_equal (out_caps, GST_VAAPI_ENCODER_CAPS (encoder))) { + gst_caps_unref (out_caps); + return GST_VAAPI_ENCODER_CAPS (encoder); + } + gst_caps_replace (&GST_VAAPI_ENCODER_CAPS (encoder), out_caps); + g_assert (GST_VAAPI_ENCODER_CONTEXT (encoder) == NULL); + gst_vaapi_object_replace (&GST_VAAPI_ENCODER_CONTEXT (encoder), NULL); + + if (!gst_vaapi_encoder_ensure_context (encoder)) + goto error; + + encoder->buf_size = (GST_VAAPI_ENCODER_WIDTH (encoder) * + GST_VAAPI_ENCODER_HEIGHT (encoder) * 400) / (16 * 16); + + if (!gst_vaapi_encoder_init_coded_buffer_queue (encoder, 5)) { + GST_ERROR ("encoder init coded buffer failed"); + goto error; + } + + return out_caps; + +error: + gst_caps_replace (&GST_VAAPI_ENCODER_CAPS (encoder), NULL); + gst_caps_replace (&out_caps, NULL); + GST_ERROR ("encoder set format failed"); + return NULL; +} + +static gboolean +gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) +{ + GstVaapiEncoderClass *kclass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + + g_assert (kclass); + g_assert (display); + + g_return_val_if_fail (display, FALSE); + g_return_val_if_fail (encoder->display == NULL, FALSE); + + encoder->display = gst_vaapi_display_ref (display); + encoder->va_display = gst_vaapi_display_get_display (display); + encoder->context = NULL; + encoder->va_context = VA_INVALID_ID; + encoder->caps = NULL; + + gst_video_info_init (&encoder->video_info); + + encoder->buf_count = 0; + encoder->max_buf_num = 10; + encoder->buf_size = 0; + + g_mutex_init (&encoder->lock); + g_cond_init (&encoder->codedbuf_free); + g_cond_init (&encoder->surface_free); + g_queue_init (&encoder->coded_buffers); + g_queue_init (&encoder->sync_pictures); + g_cond_init (&encoder->sync_ready); + + if (kclass->init) + return kclass->init (encoder); + return TRUE; +} + +static void +gst_vaapi_encoder_destroy (GstVaapiEncoder * encoder) +{ + GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + + if (klass->destroy) + klass->destroy (encoder); + + gst_vaapi_encoder_free_coded_buffers (encoder); + gst_vaapi_encoder_free_sync_pictures (encoder); + + gst_vaapi_object_replace (&encoder->context, NULL); + gst_vaapi_display_replace (&encoder->display, NULL); + encoder->va_display = NULL; + g_mutex_clear (&encoder->lock); + g_cond_clear (&encoder->codedbuf_free); + g_cond_clear (&encoder->surface_free); + g_queue_clear (&encoder->coded_buffers); + g_queue_clear (&encoder->sync_pictures); + g_cond_clear (&encoder->sync_ready); +} + +void +gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) +{ + gst_vaapi_encoder_destroy (encoder); +} + +void +gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) +{ + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + + object_class->size = sizeof (GstVaapiEncoder); + object_class->finalize = (GDestroyNotify) gst_vaapi_encoder_finalize; +} + +GstVaapiEncoder * +gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass, + GstVaapiDisplay * display) +{ + GstVaapiEncoder *encoder; + + encoder = (GstVaapiEncoder *) + gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS (klass)); + if (!encoder) + return NULL; + + if (!gst_vaapi_encoder_init (encoder, display)) + goto error; + return encoder; + +error: + gst_vaapi_encoder_unref (encoder); + return NULL; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h new file mode 100644 index 0000000000..1779b59a13 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -0,0 +1,91 @@ +/* + * gstvaapiencoder.h - VA encoder abstraction + * + * Copyright (C) 2013 Intel Corporation + * + * 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 +#include +#include +#include + +G_BEGIN_DECLS + +typedef enum +{ + GST_VAAPI_ENCODER_STATUS_SUCCESS = 0, + GST_VAAPI_ENCODER_STATUS_FRAME_NOT_READY = 1, + GST_VAAPI_ENCODER_STATUS_NO_DATA = 2, + GST_VAAPI_ENCODER_STATUS_TIMEOUT = 3, + GST_VAAPI_ENCODER_STATUS_NOT_READY = 4, + GST_VAAPI_ENCODER_STATUS_FRAME_IN_ORDER = 5, + + GST_VAAPI_ENCODER_STATUS_PARAM_ERR = -1, + GST_VAAPI_ENCODER_STATUS_OBJECT_ERR = -2, + GST_VAAPI_ENCODER_STATUS_PICTURE_ERR = -3, + GST_VAAPI_ENCODER_STATUS_THREAD_ERR = -4, + GST_VAAPI_ENCODER_STATUS_PROFILE_ERR = -5, + GST_VAAPI_ENCODER_STATUS_FUNC_PTR_ERR = -6, + GST_VAAPI_ENCODER_STATUS_MEM_ERROR = -7, + GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR = -8, +} GstVaapiEncoderStatus; + +typedef struct _GstVaapiEncoder GstVaapiEncoder; +typedef struct _GstVaapiCodedBufferProxy GstVaapiCodedBufferProxy; + +#define GST_VAAPI_ENCODER(encoder) \ + ((GstVaapiEncoder *)(encoder)) + +#define GST_VAAPI_ENCODER_CAST(encoder) \ + ((GstVaapiEncoder *)(encoder)) + +GstVaapiEncoder * +gst_vaapi_encoder_ref (GstVaapiEncoder * encoder); + +void +gst_vaapi_encoder_unref (GstVaapiEncoder * encoder); + +void +gst_vaapi_encoder_replace (GstVaapiEncoder ** old_encoder_ptr, + GstVaapiEncoder * new_encoder); + +GstCaps *gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, + GstVideoCodecState * state, GstCaps * ref_caps); + +GstVaapiEncoderStatus +gst_vaapi_encoder_get_codec_data (GstVaapiEncoder * encoder, + GstBuffer ** codec_data_ptr); + +GstVaapiEncoderStatus +gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, + GstVideoCodecFrame * frame); + +GstVaapiEncoderStatus +gst_vaapi_encoder_get_buffer (GstVaapiEncoder * encoder, + GstVideoCodecFrame ** out_frame_ptr, + GstVaapiCodedBufferProxy ** out_codedbuf_ptr, gint64 timeout); + +GstVaapiEncoderStatus +gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); + +G_END_DECLS + +#endif /* GST_VAAPI_ENCODER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c new file mode 100644 index 0000000000..e87538ce17 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -0,0 +1,598 @@ +/* + * gstvaapiencoder_objects.c - VA encoder objects abstraction + * + * Copyright (C) 2013 Intel Corporation + * + * 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 "glibcompat.h" + +#include "gstvaapiencoder_objects.h" +#include "gstvaapiencoder.h" +#include "gstvaapiencoder_priv.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) GST_VAAPI_ENCODER_VA_DISPLAY(GET_ENCODER(obj)) +#define GET_VA_CONTEXT(obj) GST_VAAPI_ENCODER_VA_CONTEXT(GET_ENCODER(obj)) + +/* ------------------------------------------------------------------------- */ +/* --- Encoder Coded Data --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiCodedBuffer, gst_vaapi_coded_buffer); + +void +gst_vaapi_coded_buffer_destroy (GstVaapiCodedBuffer * buffer) +{ + gst_vaapi_coded_buffer_unmap (buffer); + vaapi_destroy_buffer (GET_VA_DISPLAY (buffer), &buffer->buf_id); + buffer->segment_list = NULL; +} + +gboolean +gst_vaapi_coded_buffer_create (GstVaapiCodedBuffer * codec_buffer, + const GstVaapiCodecObjectConstructorArgs * args) +{ + codec_buffer->buf_id = VA_INVALID_ID; + codec_buffer->segment_list = NULL; + return vaapi_create_buffer (GET_VA_DISPLAY (codec_buffer), + GET_VA_CONTEXT (codec_buffer), + VAEncCodedBufferType, + args->param_size, args->param, &codec_buffer->buf_id, NULL); +} + +GstVaapiCodedBuffer * +gst_vaapi_coded_buffer_new (GstVaapiEncoder * encoder, + gconstpointer param, guint param_size) +{ + GstVaapiCodecObject *object; + + object = gst_vaapi_codec_object_new (&GstVaapiCodedBufferClass, + GST_VAAPI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); + if (!object) + return NULL; + return GST_VAAPI_CODED_BUFFER_CAST (object); +} + +gboolean +gst_vaapi_coded_buffer_map (GstVaapiCodedBuffer * buf, void **data) +{ + g_return_val_if_fail (buf->buf_id != VA_INVALID_ID, FALSE); + + if (buf->segment_list) + goto end; + buf->segment_list = vaapi_map_buffer (GET_VA_DISPLAY (buf), buf->buf_id); + if (!buf->segment_list) + return FALSE; +end: + if (data) + *data = buf->segment_list; + return TRUE; +} + +void +gst_vaapi_coded_buffer_unmap (GstVaapiCodedBuffer * buf) +{ + if (buf->buf_id != VA_INVALID_ID && buf->segment_list) + vaapi_unmap_buffer (GET_VA_DISPLAY (buf), + buf->buf_id, (void **) (&buf->segment_list)); +} + +gint32 +gst_vaapi_coded_buffer_get_size (GstVaapiCodedBuffer * buf) +{ + gint32 size; + VACodedBufferSegment *segment; + if (!gst_vaapi_coded_buffer_map (buf, NULL)) + return -1; + + size = 0; + segment = buf->segment_list; + while (segment) { + size += segment->size; + segment = (VACodedBufferSegment *) segment->next; + } + return size; +} + +gboolean +gst_vaapi_coded_buffer_get_buffer (GstVaapiCodedBuffer * buf, + GstBuffer * output) +{ + gint32 offset; + VACodedBufferSegment *segment; + + g_assert (output); + g_return_val_if_fail (output, FALSE); + + offset = 0; + segment = buf->segment_list; + while (segment) { + if (gst_buffer_fill (output, offset, segment->buf, segment->size) + != segment->size) + return FALSE; + offset += segment->size; + segment = (VACodedBufferSegment *) segment->next; + } + return TRUE; +} + +/* ------------------------------------------------------------------------- */ +/* --- Encoder Packed Header --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncPackedHeader, + gst_vaapi_enc_packed_header); + +void +gst_vaapi_enc_packed_header_destroy (GstVaapiEncPackedHeader * packed_header) +{ + vaapi_destroy_buffer (GET_VA_DISPLAY (packed_header), + &packed_header->param_id); + vaapi_destroy_buffer (GET_VA_DISPLAY (packed_header), + &packed_header->data_id); + packed_header->param = NULL; + packed_header->data = NULL; +} + +gboolean +gst_vaapi_enc_packed_header_create (GstVaapiEncPackedHeader * packed_header, + const GstVaapiCodecObjectConstructorArgs * args) +{ + gboolean success; + + packed_header->param_id = VA_INVALID_ID; + packed_header->param = NULL; + packed_header->data_id = VA_INVALID_ID; + packed_header->data = NULL; + success = vaapi_create_buffer (GET_VA_DISPLAY (packed_header), + GET_VA_CONTEXT (packed_header), + VAEncPackedHeaderParameterBufferType, + args->param_size, + args->param, &packed_header->param_id, &packed_header->param); + if (!success) + return FALSE; + + if (!args->data_size) + return TRUE; + + success = vaapi_create_buffer (GET_VA_DISPLAY (packed_header), + GET_VA_CONTEXT (packed_header), + VAEncPackedHeaderDataBufferType, + args->data_size, + args->data, &packed_header->data_id, &packed_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 * packed_header, + gconstpointer data, guint data_size) +{ + gboolean success; + + g_assert (packed_header->data_id == VA_INVALID_ID); + if (packed_header->data_id != VA_INVALID_ID) { + vaapi_destroy_buffer (GET_VA_DISPLAY (packed_header), + &packed_header->data_id); + packed_header->data = NULL; + } + success = vaapi_create_buffer (GET_VA_DISPLAY (packed_header), + GET_VA_CONTEXT (packed_header), + VAEncPackedHeaderDataBufferType, + data_size, data, &packed_header->data_id, &packed_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_CAST (object); +} + +/* ------------------------------------------------------------------------- */ +/* --- Encoder Slice --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncSlice, gst_vaapi_enc_slice); + +void +gst_vaapi_enc_slice_destroy (GstVaapiEncSlice * slice) +{ + 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; + + 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_CAST (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->impl = 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 total_size) +{ + GstVaapiCodecObject *object; + GstVaapiEncMiscParam *misc_obj; + VAEncMiscParameterBuffer *misc; + + object = gst_vaapi_codec_object_new (&GstVaapiEncMiscParamClass, + GST_VAAPI_CODEC_BASE (encoder), NULL, total_size, NULL, 0, 0); + if (!object) + return NULL; + + misc_obj = GST_VAAPI_ENC_MISC_PARAM_CAST (object); + misc = misc_obj->param; + misc->type = type; + misc_obj->impl = misc->data; + g_assert (misc_obj->impl); + return misc_obj; +} + +/* ------------------------------------------------------------------------- */ +/* --- Encoder Picture --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncPicture, gst_vaapi_enc_picture); + +static void +destroy_vaapi_obj_cb (gpointer data, gpointer user_data) +{ + GstVaapiMiniObject *const object = data; + + gst_vaapi_mini_object_unref (object); +} + +void +gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture) +{ + if (picture->packed_headers) { + g_ptr_array_foreach (picture->packed_headers, destroy_vaapi_obj_cb, NULL); + g_ptr_array_free (picture->packed_headers, TRUE); + picture->packed_headers = NULL; + } + if (picture->misc_buffers) { + g_ptr_array_foreach (picture->misc_buffers, destroy_vaapi_obj_cb, NULL); + g_ptr_array_free (picture->misc_buffers, TRUE); + picture->misc_buffers = NULL; + } + if (picture->slices) { + g_ptr_array_foreach (picture->slices, destroy_vaapi_obj_cb, NULL); + g_ptr_array_free (picture->slices, TRUE); + picture->slices = NULL; + } + gst_vaapi_mini_object_replace ( + (GstVaapiMiniObject **) (&picture->sequence), NULL); + + g_assert (picture->surface); + picture->surface_id = VA_INVALID_ID; + picture->surface = NULL; + + vaapi_destroy_buffer (GET_VA_DISPLAY (picture), &picture->param_id); + picture->param = NULL; + 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 *frame; + GstVaapiSurface *surface; + GstVaapiEncObjUserDataHead *user_data; + gboolean success; + + g_assert (args->data); + g_return_val_if_fail (args->data, FALSE); + + frame = (GstVideoCodecFrame *) args->data; + user_data = gst_video_codec_frame_get_user_data (frame); + g_assert (user_data); + surface = user_data->surface; + g_return_val_if_fail (surface, FALSE); + + picture->sequence = NULL; + 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; + picture->param = NULL; + 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 (); + picture->misc_buffers = g_ptr_array_new (); + picture->slices = g_ptr_array_new (); + + g_assert (picture->packed_headers && picture->misc_buffers + && picture->slices); + if (!picture->packed_headers || !picture->misc_buffers || !picture->slices) + return FALSE; + + picture->frame = gst_video_codec_frame_ref (frame); + picture->surface = surface; + g_assert (picture->surface); + picture->surface_id = gst_vaapi_surface_get_id (picture->surface); + g_assert (picture->surface_id != VA_INVALID_SURFACE); + + return TRUE; +} + +GstVaapiEncPicture * +gst_vaapi_enc_picture_new (GstVaapiEncoder * encoder, + gconstpointer param, guint param_size, GstVideoCodecFrame * frame) +{ + GstVaapiCodecObject *object; + + object = gst_vaapi_codec_object_new (&GstVaapiEncPictureClass, + GST_VAAPI_CODEC_BASE (encoder), param, param_size, frame, 0, 0); + if (!object) + return NULL; + return GST_VAAPI_ENC_PICTURE_CAST (object); +} + +void +gst_vaapi_enc_picture_set_sequence (GstVaapiEncPicture * picture, + GstVaapiEncSequence * sequence) +{ + g_return_if_fail (GST_VAAPI_IS_ENC_PICTURE (picture)); + g_return_if_fail (GST_VAAPI_IS_ENC_SEQUENCE (sequence)); + + g_assert (sequence); + gst_vaapi_mini_object_replace ( + (GstVaapiMiniObject **) (&picture->sequence), + GST_VAAPI_MINI_OBJECT (sequence)); +} + +void +gst_vaapi_enc_picture_add_packed_header (GstVaapiEncPicture * picture, + GstVaapiEncPackedHeader * header) +{ + g_return_if_fail (GST_VAAPI_IS_ENC_PICTURE (picture)); + g_return_if_fail (GST_VAAPI_IS_ENC_PACKED_HEADER (header)); + + g_assert (picture->packed_headers); + g_ptr_array_add (picture->packed_headers, + gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (header))); +} + +void +gst_vaapi_enc_picture_add_misc_buffer (GstVaapiEncPicture * picture, + GstVaapiEncMiscParam * misc) +{ + g_return_if_fail (GST_VAAPI_IS_ENC_PICTURE (picture)); + g_return_if_fail (GST_VAAPI_IS_ENC_MISC_PARAM (misc)); + + g_assert (picture->misc_buffers); + g_ptr_array_add (picture->misc_buffers, + gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (misc))); +} + +void +gst_vaapi_enc_picture_add_slice (GstVaapiEncPicture * picture, + GstVaapiEncSlice * slice) +{ + g_return_if_fail (GST_VAAPI_IS_ENC_PICTURE (picture)); + g_return_if_fail (GST_VAAPI_IS_ENC_SLICE (slice)); + + g_ptr_array_add (picture->slices, + gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (slice))); +} + +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; + GstVaapiEncPackedHeader *packed_header; + GstVaapiEncMiscParam *misc; + GstVaapiEncSlice *slice; + VADisplay va_display; + VAContextID va_context; + VAStatus status; + guint i; + + g_return_val_if_fail (GST_VAAPI_IS_ENC_PICTURE (picture), 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; + + /* encode sequence parameter */ + sequence = picture->sequence; + if (sequence) { + if (!do_encode (va_display, va_context, + &sequence->param_id, &sequence->param)) + return FALSE; + } + + /* encode picture parameter */ + if (!do_encode (va_display, va_context, &picture->param_id, &picture->param)) + return FALSE; + + /* encode packed headers */ + for (i = 0; i < picture->packed_headers->len; i++) { + packed_header = g_ptr_array_index (picture->packed_headers, i); + if (!do_encode (va_display, va_context, + &packed_header->param_id, &packed_header->param) || + !do_encode (va_display, va_context, + &packed_header->data_id, &packed_header->data)) + return FALSE; + } + + /* encode misc buffers */ + for (i = 0; i < picture->misc_buffers->len; i++) { + misc = g_ptr_array_index (picture->misc_buffers, i); + if (!do_encode (va_display, va_context, &misc->param_id, &misc->param)) + return FALSE; + } + + /* encode slice parameters */ + for (i = 0; i < picture->slices->len; i++) { + slice = g_ptr_array_index (picture->slices, i); + 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; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h new file mode 100644 index 0000000000..240d55b521 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -0,0 +1,379 @@ +/* + * gstvaapiencoder_objects.h - VA encoder objects abstraction + * + * Copyright (C) 2013 Intel Corporation + * + * 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 +#include +#include + +G_BEGIN_DECLS + +typedef struct _GstVaapiEncPicture GstVaapiEncPicture; +typedef struct _GstVaapiEncSequence GstVaapiEncSequence; +typedef struct _GstVaapiEncMiscParam GstVaapiEncMiscParam; +typedef struct _GstVaapiEncSlice GstVaapiEncSlice; +typedef struct _GstVaapiCodedBuffer GstVaapiCodedBuffer; +typedef struct _GstVaapiEncPackedHeader GstVaapiEncPackedHeader; + +/* ------------------------------------------------------------------------- */ +/* --- Encoder Coded Buffer --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_CODED_BUFFER_CAST(obj) \ + ((GstVaapiCodedBuffer *)(obj)) + +#define GST_VAAPI_CODED_BUFFER(obj) \ + GST_VAAPI_CODED_BUFFER_CAST(obj) + +#define GST_VAAPI_IS_CODED_BUFFER(obj) \ + (GST_VAAPI_CODED_BUFFER(obj) != NULL) + +/** + * GstVaapiCodedBuffer: + * + * A #GstVaapiCodecObject holding an encoded buffer. + */ +struct _GstVaapiCodedBuffer +{ + /*< private > */ + GstVaapiCodecObject parent_instance; + VABufferID buf_id; + + /*< public > */ + VACodedBufferSegment *segment_list; +}; + +G_GNUC_INTERNAL +GstVaapiCodedBuffer * +gst_vaapi_coded_buffer_new (GstVaapiEncoder * encoder, + gconstpointer param, guint param_size); + +gboolean +gst_vaapi_coded_buffer_map (GstVaapiCodedBuffer * buf, void **data); + +void +gst_vaapi_coded_buffer_unmap (GstVaapiCodedBuffer * buf); + +gint32 +gst_vaapi_coded_buffer_get_size (GstVaapiCodedBuffer * buf); + +gboolean +gst_vaapi_coded_buffer_get_buffer (GstVaapiCodedBuffer * buf, + GstBuffer * output); + +/* ------------------------------------------------------------------------- */ +/* --- Encoder Packed Header --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENC_PACKED_HEADER_CAST(obj) \ + ((GstVaapiEncPackedHeader *)(obj)) + +#define GST_VAAPI_ENC_PACKED_HEADER(obj) \ + GST_VAAPI_ENC_PACKED_HEADER_CAST(obj) + +#define GST_VAAPI_IS_ENC_PACKED_HEADER(obj) \ + (GST_VAAPI_ENC_PACKED_HEADER(obj) != NULL) + +/** + * GstVaapiEncPackedHeader: + * + * A #GstVaapiCodecObject holding a encoder packed header + * parameter/data parameter. + */ +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 * packed_header, + gconstpointer data, guint data_size); + +/* ------------------------------------------------------------------------- */ +/* --- Encoder Sequence --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENC_SEQUENCE_CAST(obj) \ + ((GstVaapiEncSequence *)(obj)) + +#define GST_VAAPI_ENC_SEQUENCE(obj) \ + GST_VAAPI_ENC_SEQUENCE_CAST(obj) + +#define GST_VAAPI_IS_ENC_SEQUENCE(obj) \ + (GST_VAAPI_ENC_SEQUENCE(obj) != NULL) + +/** + * GstVaapiEncSequence: + * + * A #GstVaapiCodecObject holding a encoder sequence parameter. + */ +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_CAST(obj) \ + ((GstVaapiEncSlice *)(obj)) + +#define GST_VAAPI_ENC_SLICE(obj) \ + GST_VAAPI_ENC_SLICE_CAST(obj) + +#define GST_VAAPI_IS_ENC_SLICE(obj) \ + (GST_VAAPI_ENC_SLICE(obj) != NULL) + +/** + * GstVaapiEncSlice: + * + * A #GstVaapiCodecObject holding a encoder slice parameter. + */ +struct _GstVaapiEncSlice +{ + /*< private > */ + GstVaapiCodecObject parent_instance; + + /*< public > */ + VABufferID param_id; + gpointer param; +}; + +G_GNUC_INTERNAL +void +gst_vaapi_enc_slice_destroy (GstVaapiEncSlice * slice); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_enc_slice_create (GstVaapiEncSlice * slice, + const GstVaapiCodecObjectConstructorArgs * args); + +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_CAST(obj) \ + ((GstVaapiEncMiscParam *)(obj)) + +#define GST_VAAPI_ENC_MISC_PARAM(obj) \ + GST_VAAPI_ENC_MISC_PARAM_CAST(obj) + +#define GST_VAAPI_IS_ENC_MISC_PARAM(obj) \ + (GST_VAAPI_ENC_MISC_PARAM(obj) != NULL) + +/** + * GstVaapiEncMiscParam: + * + * A #GstVaapiCodecObject holding a encoder misc parameter. + */ +struct _GstVaapiEncMiscParam +{ + /*< private > */ + GstVaapiCodecObject parent_instance; + gpointer param; + + /*< public > */ + VABufferID param_id; + gpointer impl; +}; + +G_GNUC_INTERNAL +GstVaapiEncMiscParam * +gst_vaapi_enc_misc_param_new (GstVaapiEncoder * encoder, + VAEncMiscParameterType type, guint total_size); + +/* ------------------------------------------------------------------------- */ +/* --- Encoder Picture --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENC_PICTURE_CAST(obj) \ + ((GstVaapiEncPicture *)(obj)) + +#define GST_VAAPI_ENC_PICTURE(obj) \ + GST_VAAPI_ENC_PICTURE_CAST(obj) + +#define GST_VAAPI_IS_ENC_PICTURE(obj) \ + (GST_VAAPI_ENC_PICTURE(obj) != NULL) + +typedef enum +{ + GST_VAAPI_ENC_PICTURE_FLAG_IDR = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 0), + GST_VAAPI_ENC_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 1), +} 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_GET_FRAME(picture) \ + (picture)->frame + +typedef struct +{ + GstVaapiSurface *surface; +} GstVaapiEncObjUserDataHead; + +/** + * GstVaapiEncPicture: + * + * A #GstVaapiCodecObject holding a picture parameter. + */ +struct _GstVaapiEncPicture +{ + /*< private > */ + GstVaapiCodecObject parent_instance; + GstVideoCodecFrame *frame; + GstVaapiSurface *surface; + GstVaapiEncSequence *sequence; + /*< private >, picture packed header */ + GPtrArray *packed_headers; + GPtrArray *misc_buffers; + GPtrArray *slices; + VABufferID param_id; + guint param_size; + + /*< public > */ + GstVaapiPictureType type; + VASurfaceID surface_id; + gpointer param; + GstClockTime pts; + guint frame_num; + guint poc; +}; + +G_GNUC_INTERNAL +void +gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture, + const GstVaapiCodecObjectConstructorArgs * args); + +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_buffer (GstVaapiEncPicture * picture, + GstVaapiEncMiscParam * misc); + +G_GNUC_INTERNAL +void +gst_vaapi_enc_picture_add_slice (GstVaapiEncPicture * picture, + GstVaapiEncSlice * slice); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture); + +static inline gpointer +gst_vaapi_enc_picture_ref (gpointer ptr) +{ + return gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (ptr)); +} + +static inline void +gst_vaapi_enc_picture_unref (gpointer ptr) +{ + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (ptr)); +} + +#define gst_vaapi_enc_picture_replace(old_picture_p, new_picture) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_picture_p), \ + (GstVaapiMiniObject *)(new_picture)) + +/* GST_VAAPI_CODED_BUFFER_NEW */ +#define GST_VAAPI_CODED_BUFFER_NEW(encoder, size) \ + gst_vaapi_coded_buffer_new(GST_VAAPI_ENCODER_CAST(encoder), \ + NULL, size) + +/* GST_VAAPI_ENC_SEQUENCE_NEW */ +#define GST_VAAPI_ENC_SEQUENCE_NEW(codec, encoder) \ + gst_vaapi_enc_sequence_new(GST_VAAPI_ENCODER_CAST(encoder), \ + NULL, sizeof(VAEncSequenceParameterBuffer##codec)) + +/* GST_VAAPI_ENC_SLICE_NEW */ +#define GST_VAAPI_ENC_SLICE_NEW(codec, encoder) \ + gst_vaapi_enc_slice_new(GST_VAAPI_ENCODER_CAST(encoder), \ + NULL, sizeof(VAEncSliceParameterBuffer##codec)) + +/* GST_VAAPI_ENC_MISC_PARAM_NEW */ +#define GST_VAAPI_ENC_MISC_PARAM_NEW(type, encoder) \ + gst_vaapi_enc_misc_param_new(GST_VAAPI_ENCODER_CAST(encoder), \ + VAEncMiscParameterType##type, \ + (sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameter##type))) + +/* GST_VAAPI_ENC_PICTURE_NEW */ +#define GST_VAAPI_ENC_PICTURE_NEW(codec, encoder, frame) \ + gst_vaapi_enc_picture_new(GST_VAAPI_ENCODER_CAST(encoder), \ + NULL, sizeof(VAEncPictureParameterBuffer##codec), frame) + +G_END_DECLS + +#endif /* GST_VAAPI_ENCODER_OBJECTS_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h new file mode 100644 index 0000000000..71fff0cd92 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -0,0 +1,188 @@ +/* + * gstvaapiencoder_priv.h - VA encoder abstraction (private definitions) + * + * Copyright (C) 2013 Intel Corporation + * + * 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 +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_ENCODER_CLASS(klass) \ + ((GstVaapiEncoderClass *)(klass)) + +#define GST_IS_VAAPI_ENCODER_CLASS(klass) \ + ((klass) != NULL) + +#define GST_VAAPI_ENCODER_GET_CLASS(obj) \ + GST_VAAPI_ENCODER_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + +/* Get GstVaapiDisplay* */ +#define GST_VAAPI_ENCODER_DISPLAY(encoder) \ + (GST_VAAPI_ENCODER_CAST(encoder)->display) + +/* Get VADisplay */ +#define GST_VAAPI_ENCODER_VA_DISPLAY(encoder) \ + (GST_VAAPI_ENCODER_CAST(encoder)->va_display) + +/* Get GstVaapiContext* */ +#define GST_VAAPI_ENCODER_CONTEXT(encoder) \ + (GST_VAAPI_ENCODER_CAST(encoder)->context) + +/* Get VAContext */ +#define GST_VAAPI_ENCODER_VA_CONTEXT(encoder) \ + (GST_VAAPI_ENCODER_CAST(encoder)->va_context) + +#define GST_VAAPI_ENCODER_VIDEO_INFO(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info) +#define GST_VAAPI_ENCODER_CAPS(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->caps) +#define GST_VAAPI_ENCODER_WIDTH(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info.width) +#define GST_VAAPI_ENCODER_HEIGHT(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info.height) +#define GST_VAAPI_ENCODER_FPS_N(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info.fps_n) +#define GST_VAAPI_ENCODER_FPS_D(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info.fps_d) +#define GST_VAAPI_ENCODER_RATE_CONTROL(encoder) \ + (GST_VAAPI_ENCODER_CAST(encoder)->rate_control) + +#define GST_VAAPI_ENCODER_LOG_ERROR(...) GST_ERROR( __VA_ARGS__) +#define GST_VAAPI_ENCODER_LOG_WARNING(...) GST_WARNING( __VA_ARGS__) +#define GST_VAAPI_ENCODER_LOG_DEBUG(...) GST_DEBUG( __VA_ARGS__) +#define GST_VAAPI_ENCODER_LOG_INFO(...) GST_INFO( __VA_ARGS__) + +#define GST_VAAPI_ENCODER_CHECK_STATUS(exp, err_num, err_reason, ...) \ + if (!(exp)) { \ + ret = err_num; \ + GST_VAAPI_ENCODER_LOG_ERROR(err_reason, ## __VA_ARGS__); \ + goto end; \ + } + +typedef struct _GstVaapiCodedBufferProxyClass GstVaapiCodedBufferProxyClass; +typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass; + +struct _GstVaapiEncoder +{ + /*< private > */ + GstVaapiMiniObject parent_instance; + + GstVaapiDisplay *display; + GstVaapiContext *context; + GstCaps *caps; + + VADisplay va_display; + VAContextID va_context; + GstVideoInfo video_info; + GstVaapiRateControl rate_control; + + guint buf_count; + guint max_buf_num; + guint buf_size; + GMutex lock; + GCond codedbuf_free; + GCond surface_free; + GQueue coded_buffers; + + /* queue for sync */ + GQueue sync_pictures; + GCond sync_ready; +}; + +struct _GstVaapiEncoderClass +{ + GObjectClass parent_class; + + gboolean (*init) (GstVaapiEncoder * encoder); + void (*destroy) (GstVaapiEncoder * encoder); + + GstCaps * (*set_format) (GstVaapiEncoder * encoder, + GstVideoCodecState * in_state, + GstCaps * ref_caps); + + gboolean (*get_context_info) (GstVaapiEncoder * encoder, + GstVaapiContextInfo * info); + + GstVaapiEncoderStatus (*reordering) (GstVaapiEncoder * encoder, + GstVideoCodecFrame * in, + gboolean flush, + 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); +}; + +struct _GstVaapiCodedBufferProxy +{ + /*< private >*/ + GstVaapiMiniObject parent_instance; + GstVaapiEncoder *encoder; + + /*< public >*/ + GstVaapiCodedBuffer *buffer; +}; + +struct _GstVaapiCodedBufferProxyClass +{ + GstVaapiMiniObjectClass parent_class; +}; + +void +gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass); + +GstVaapiEncoder * +gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass, + GstVaapiDisplay * display); + +void +gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder); + +GstVaapiSurfaceProxy * +gst_vaapi_encoder_create_surface (GstVaapiEncoder * + encoder); + +void +gst_vaapi_encoder_release_surface (GstVaapiEncoder * encoder, + GstVaapiSurfaceProxy * surface); + +/* ------------------ GstVaapiCodedBufferProxy ---------------------------- */ + +GstVaapiCodedBufferProxy * +gst_vaapi_coded_buffer_proxy_new (GstVaapiEncoder * + encoder); + +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); + +G_END_DECLS + +#endif /* GST_VAAPI_ENCODER_PRIV_H */ From 652245fb87725f6ef2689a9568bc5c4a21bb0601 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Mon, 29 Jul 2013 15:46:11 +0800 Subject: [PATCH 1409/3781] encoder: add h264 encoder. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 1786 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 41 + .../gst/vaapi/gstvaapiencoder_h264_priv.h | 126 ++ 4 files changed, 1955 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_h264.c create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_h264.h create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 52b4bf9aa0..f147d99891 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -136,11 +136,13 @@ endif libgstvaapi_enc_source_c = \ gstvaapiencoder.c \ + gstvaapiencoder_h264.c \ gstvaapiencoder_objects.c \ $(NULL) libgstvaapi_enc_source_h = \ gstvaapiencoder.h \ + gstvaapiencoder_h264.h \ $(NULL) libgstvaapi_enc_source_priv_h = \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c new file mode 100644 index 0000000000..ddded58e15 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -0,0 +1,1786 @@ +/* + * gstvaapiencoder_h264.c - H.264 encoder + * + * Copyright (C) 2012 -2013 Intel Corporation + * + * 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 "gstvaapiencoder_h264.h" +#include "gstvaapiencoder_h264_priv.h" +#include "gstvaapiencoder_priv.h" + +#include +#include + +#include "gstvaapicontext.h" +#include "gstvaapisurface.h" +#include "gstvaapidisplay_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +#define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0 +#define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1 +#define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM 2 +#define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH 3 + +typedef enum +{ + GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CAVLC = 0, + GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CABAC = 1 +} GstVaapiEncoderH264EntropyMode; + +typedef enum +{ + GST_VAAPI_ENCODER_H264_NAL_UNKNOWN = 0, + GST_VAAPI_ENCODER_H264_NAL_NON_IDR = 1, + GST_VAAPI_ENCODER_H264_NAL_IDR = 5, /* ref_idc != 0 */ + GST_VAAPI_ENCODER_H264_NAL_SEI = 6, /* ref_idc == 0 */ + GST_VAAPI_ENCODER_H264_NAL_SPS = 7, + GST_VAAPI_ENCODER_H264_NAL_PPS = 8 +} GstVaapiEncoderH264NalType; + +typedef enum +{ + SLICE_TYPE_P = 0, + SLICE_TYPE_B = 1, + SLICE_TYPE_I = 2 +} H264_SLICE_TYPE; + +typedef struct +{ + GstVaapiSurfaceProxy *pic; + guint poc; + guint frame_num; +} GstVaapiEncoderH264Ref; + +#define GST_VAAPI_H264_CAPS \ + "video/x-h264, " \ + "framerate = (fraction) [0/1, MAX], " \ + "width = (int) [ 1, MAX ], " \ + "height = (int) [ 1, MAX ], " \ + "stream-format = (string) { avc, byte-stream }, " \ + "alignment = (string) { au } " + +typedef enum +{ + GST_VAAPI_ENC_H264_REORD_NONE = 0, + GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1, + GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2 +} GstVaapiEncH264ReorderState; + +static inline gboolean +_poc_greater_than (guint poc1, guint poc2, guint max_poc) +{ + return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2); +} + +static inline guint8 +_get_va_slice_type (GstVaapiPictureType type) +{ + switch (type) { + case GST_VAAPI_PICTURE_TYPE_I: + return 2; + case GST_VAAPI_PICTURE_TYPE_P: + return 0; + case GST_VAAPI_PICTURE_TYPE_B: + return 1; + default: + return -1; + } + return -1; +} + +static inline gboolean +_read_sps_attributes (const guint8 * sps_data, + guint32 sps_size, + guint32 * profile_idc, guint32 * profile_comp, guint32 * level_idc) +{ + g_assert (profile_idc && profile_comp && level_idc); + g_assert (sps_size >= 4); + if (sps_size < 4) { + return FALSE; + } + /* skip sps_data[0], nal_type */ + *profile_idc = sps_data[1]; + *profile_comp = sps_data[2]; + *level_idc = sps_data[3]; + return TRUE; +} + +static inline guint +_get_log2_max_frame_num (guint num) +{ + guint ret = 0; + + while (num) { + ++ret; + num >>= 1; + } + if (ret <= 4) + ret = 4; + else if (ret > 10) + ret = 10; + /* must greater than 4 */ + return ret; +} + +static inline guint +_profile_to_value (GstVaapiProfile profile) +{ + switch (profile) { + case GST_VAAPI_PROFILE_H264_BASELINE: + return 66; + case GST_VAAPI_PROFILE_H264_MAIN: + return 77; + case GST_VAAPI_PROFILE_H264_HIGH: + return 100; + default: + break; + } + return 0; +} + +static inline void +_check_sps_pps_status (GstVaapiEncoderH264 * encoder, + const guint8 * nal, guint32 size) +{ + guint8 nal_type; + gsize ret; + + g_assert (size); + + if (encoder->sps_data && encoder->pps_data) + return; + + nal_type = nal[0] & 0x1F; + switch (nal_type) { + case GST_VAAPI_ENCODER_H264_NAL_SPS: + encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (encoder->sps_data, 0, nal, size); + g_assert (ret == size); + break; + case GST_VAAPI_ENCODER_H264_NAL_PPS: + encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (encoder->pps_data, 0, nal, size); + g_assert (ret == size); + break; + default: + break; + } +} + +static void +_set_level (GstVaapiEncoderH264 * encoder) +{ + guint pic_mb_size; + guint MaxDpbMbs, MaxMBPS; + guint dbp_level, mbps_level, profile_level; + + if (encoder->level) { + if (encoder->level < GST_VAAPI_ENCODER_H264_LEVEL_10) + encoder->level = GST_VAAPI_ENCODER_H264_LEVEL_10; + else if (encoder->level > GST_VAAPI_ENCODER_H264_LEVEL_51) + encoder->level = GST_VAAPI_ENCODER_H264_LEVEL_51; + return; + } + + /* calculate level */ + pic_mb_size = ((GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16) * + ((GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16); + MaxDpbMbs = pic_mb_size * ((encoder->b_frame_num) ? 2 : 1); + MaxMBPS = pic_mb_size * GST_VAAPI_ENCODER_FPS_N (encoder) / + GST_VAAPI_ENCODER_FPS_D (encoder); + + /* calculate from MaxDbpMbs */ + if (MaxDpbMbs > 110400) + dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_51; + else if (MaxDpbMbs > 34816) + dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_50; + else if (MaxDpbMbs > 32768) + dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_42; + else if (MaxDpbMbs > 20480) /* 41 or 40 */ + dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_41; + else if (MaxDpbMbs > 18000) + dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_32; + else if (MaxDpbMbs > 8100) + dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_31; + else if (MaxDpbMbs > 4752) /* 30 or 22 */ + dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_30; + else if (MaxDpbMbs > 2376) + dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_21; + else if (MaxDpbMbs > 900) /* 20, 13, 12 */ + dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_20; + else if (MaxDpbMbs > 396) + dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_11; + else + dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_10; + + /* calculate from Max Mb processing rate */ + if (MaxMBPS > 589824) + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_51; + else if (MaxMBPS > 522240) + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_50; + else if (MaxMBPS > 245760) + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_42; + else if (MaxMBPS > 216000) /* 40 or 41 */ + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_41; + else if (MaxMBPS > 108000) + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_32; + else if (MaxMBPS > 40500) + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_31; + else if (MaxMBPS > 20250) + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_30; + else if (MaxMBPS > 19800) + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_22; + else if (MaxMBPS > 11800) + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_21; + else if (MaxMBPS > 6000) /*13 or 20 */ + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_20; + else if (MaxMBPS > 3000) + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_12; + else if (MaxMBPS > 1485) + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_11; + else + mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_10; + + if (encoder->profile == GST_VAAPI_PROFILE_H264_HIGH) + profile_level = GST_VAAPI_ENCODER_H264_LEVEL_41; + else if (encoder->profile == GST_VAAPI_PROFILE_H264_MAIN) + profile_level = GST_VAAPI_ENCODER_H264_LEVEL_30; + else + profile_level = GST_VAAPI_ENCODER_H264_LEVEL_20; + + encoder->level = (dbp_level > mbps_level ? dbp_level : mbps_level); + if (encoder->level < profile_level) + encoder->level = profile_level; +} + +static inline void +_reset_gop_start (GstVaapiEncoderH264 * encoder) +{ + ++encoder->idr_num; + encoder->frame_index = 1; + encoder->cur_frame_num = 0; + encoder->cur_present_index = 0; +} + +static void +_set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) +{ + g_assert (pic && encoder); + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_B; + pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num); +} + +static inline void +_set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) +{ + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_P; + pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num); +} + +static inline void +_set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) +{ + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_I; + pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num); + g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic)); + GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic)); +} + +static inline void +_set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) +{ + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_I; + pic->frame_num = 0; + pic->poc = 0; + GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR); + + g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic)); + GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic)); +} + +static inline void +_set_key_frame (GstVaapiEncPicture * picture, + GstVaapiEncoderH264 * encoder, gboolean is_idr) +{ + if (is_idr) { + _reset_gop_start (encoder); + _set_idr_frame (picture, encoder); + } else + _set_i_frame (picture, encoder); + +} + +gboolean +gst_bit_writer_put_ue (GstBitWriter * bitwriter, guint32 value) +{ + guint32 size_in_bits = 0; + guint32 tmp_value = ++value; + + while (tmp_value) { + ++size_in_bits; + tmp_value >>= 1; + } + if (size_in_bits > 1 + && !gst_bit_writer_put_bits_uint32 (bitwriter, 0, size_in_bits - 1)) + return FALSE; + if (!gst_bit_writer_put_bits_uint32 (bitwriter, value, size_in_bits)) + return FALSE; + return TRUE; +} + +gboolean +gst_bit_writer_put_se (GstBitWriter * bitwriter, gint32 value) +{ + guint32 new_val; + + if (value <= 0) + new_val = -(value << 1); + else + new_val = (value << 1) - 1; + + if (!gst_bit_writer_put_ue (bitwriter, new_val)) + return FALSE; + return TRUE; +} + + +static gboolean +gst_bit_writer_write_nal_header (GstBitWriter * bitwriter, + guint32 nal_ref_idc, guint32 nal_unit_type) +{ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, nal_ref_idc, 2); + gst_bit_writer_put_bits_uint32 (bitwriter, nal_unit_type, 5); + return TRUE; +} + +static gboolean +gst_bit_writer_write_trailing_bits (GstBitWriter * bitwriter) +{ + gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); + gst_bit_writer_align_bytes_unchecked (bitwriter, 0); + return TRUE; +} + +static gboolean +gst_bit_writer_write_sps (GstBitWriter * bitwriter, + VAEncSequenceParameterBufferH264 * seq, GstVaapiProfile profile) +{ + guint32 constraint_set0_flag, constraint_set1_flag; + guint32 constraint_set2_flag, constraint_set3_flag; + guint32 gaps_in_frame_num_value_allowed_flag = 0; // ?? + gboolean nal_hrd_parameters_present_flag; + + guint32 b_qpprime_y_zero_transform_bypass = 0; + guint32 residual_color_transform_flag = 0; + guint32 pic_height_in_map_units = + (seq->seq_fields.bits.frame_mbs_only_flag ? + seq->picture_height_in_mbs : seq->picture_height_in_mbs / 2); + guint32 mb_adaptive_frame_field = !seq->seq_fields.bits.frame_mbs_only_flag; + guint32 i = 0; + + constraint_set0_flag = profile == GST_VAAPI_PROFILE_H264_BASELINE; + constraint_set1_flag = profile <= GST_VAAPI_PROFILE_H264_MAIN; + constraint_set2_flag = 0; + constraint_set3_flag = 0; + + /* profile_idc */ + gst_bit_writer_put_bits_uint32 (bitwriter, _profile_to_value (profile), 8); + /* constraint_set0_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set0_flag, 1); + /* constraint_set1_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set1_flag, 1); + /* constraint_set2_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set2_flag, 1); + /* constraint_set3_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set3_flag, 1); + /* reserved_zero_4bits */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 4); + /* level_idc */ + gst_bit_writer_put_bits_uint32 (bitwriter, seq->level_idc, 8); + /* seq_parameter_set_id */ + gst_bit_writer_put_ue (bitwriter, seq->seq_parameter_set_id); + + if (profile == GST_VAAPI_PROFILE_H264_HIGH) { + /* for high profile */ + /* chroma_format_idc = 1, 4:2:0 */ + gst_bit_writer_put_ue (bitwriter, seq->seq_fields.bits.chroma_format_idc); + if (3 == seq->seq_fields.bits.chroma_format_idc) { + gst_bit_writer_put_bits_uint32 (bitwriter, residual_color_transform_flag, + 1); + } + /* bit_depth_luma_minus8 */ + gst_bit_writer_put_ue (bitwriter, seq->bit_depth_luma_minus8); + /* bit_depth_chroma_minus8 */ + gst_bit_writer_put_ue (bitwriter, seq->bit_depth_chroma_minus8); + /* b_qpprime_y_zero_transform_bypass */ + gst_bit_writer_put_bits_uint32 (bitwriter, + b_qpprime_y_zero_transform_bypass, 1); + g_assert (seq->seq_fields.bits.seq_scaling_matrix_present_flag == 0); + /*seq_scaling_matrix_present_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, + seq->seq_fields.bits.seq_scaling_matrix_present_flag, 1); + +#if 0 + if (seq->seq_fields.bits.seq_scaling_matrix_present_flag) { + for (i = 0; i < (seq->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); + i++) { + gst_bit_writer_put_bits_uint8 (bitwriter, + seq->seq_fields.bits.seq_scaling_list_present_flag, 1); + if (seq->seq_fields.bits.seq_scaling_list_present_flag) { + g_assert (0); + /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */ + } + } + } +#endif + } + + /* log2_max_frame_num_minus4 */ + gst_bit_writer_put_ue (bitwriter, + seq->seq_fields.bits.log2_max_frame_num_minus4); + /* pic_order_cnt_type */ + gst_bit_writer_put_ue (bitwriter, seq->seq_fields.bits.pic_order_cnt_type); + + if (seq->seq_fields.bits.pic_order_cnt_type == 0) { + /* log2_max_pic_order_cnt_lsb_minus4 */ + gst_bit_writer_put_ue (bitwriter, + seq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4); + } else if (seq->seq_fields.bits.pic_order_cnt_type == 1) { + g_assert (0); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq->seq_fields.bits.delta_pic_order_always_zero_flag, 1); + gst_bit_writer_put_se (bitwriter, seq->offset_for_non_ref_pic); + gst_bit_writer_put_se (bitwriter, seq->offset_for_top_to_bottom_field); + gst_bit_writer_put_ue (bitwriter, + seq->num_ref_frames_in_pic_order_cnt_cycle); + for (i = 0; i < seq->num_ref_frames_in_pic_order_cnt_cycle; i++) { + gst_bit_writer_put_se (bitwriter, seq->offset_for_ref_frame[i]); + } + } + + /* num_ref_frames */ + gst_bit_writer_put_ue (bitwriter, seq->max_num_ref_frames); + /* gaps_in_frame_num_value_allowed_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, + gaps_in_frame_num_value_allowed_flag, 1); + + /* pic_width_in_mbs_minus1 */ + gst_bit_writer_put_ue (bitwriter, seq->picture_width_in_mbs - 1); + /* pic_height_in_map_units_minus1 */ + gst_bit_writer_put_ue (bitwriter, pic_height_in_map_units - 1); + /* frame_mbs_only_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, + seq->seq_fields.bits.frame_mbs_only_flag, 1); + + if (!seq->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs + g_assert (0); + gst_bit_writer_put_bits_uint32 (bitwriter, mb_adaptive_frame_field, 1); + } + + /* direct_8x8_inference_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); + /* frame_cropping_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, seq->frame_cropping_flag, 1); + + if (seq->frame_cropping_flag) { + /* frame_crop_left_offset */ + gst_bit_writer_put_ue (bitwriter, seq->frame_crop_left_offset); + /* frame_crop_right_offset */ + gst_bit_writer_put_ue (bitwriter, seq->frame_crop_right_offset); + /* frame_crop_top_offset */ + gst_bit_writer_put_ue (bitwriter, seq->frame_crop_top_offset); + /* frame_crop_bottom_offset */ + gst_bit_writer_put_ue (bitwriter, seq->frame_crop_bottom_offset); + } + + /* vui_parameters_present_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, seq->vui_parameters_present_flag, + 1); + if (seq->vui_parameters_present_flag) { + /* aspect_ratio_info_present_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, + seq->vui_fields.bits.aspect_ratio_info_present_flag, 1); + if (seq->vui_fields.bits.aspect_ratio_info_present_flag) { + gst_bit_writer_put_bits_uint32 (bitwriter, seq->aspect_ratio_idc, 8); + if (seq->aspect_ratio_idc == 0xFF) { + gst_bit_writer_put_bits_uint32 (bitwriter, seq->sar_width, 16); + gst_bit_writer_put_bits_uint32 (bitwriter, seq->sar_height, 16); + } + } + + /* overscan_info_present_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); + /* video_signal_type_present_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); + /* chroma_loc_info_present_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); + + /* timing_info_present_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, + seq->vui_fields.bits.timing_info_present_flag, 1); + if (seq->vui_fields.bits.timing_info_present_flag) { + gst_bit_writer_put_bits_uint32 (bitwriter, seq->num_units_in_tick, 32); + gst_bit_writer_put_bits_uint32 (bitwriter, seq->time_scale, 32); + gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* fixed_frame_rate_flag */ + } + + nal_hrd_parameters_present_flag = (seq->bits_per_second > 0 ? TRUE : FALSE); + /* nal_hrd_parameters_present_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, nal_hrd_parameters_present_flag, + 1); + if (nal_hrd_parameters_present_flag) { + /* hrd_parameters */ + /* cpb_cnt_minus1 */ + gst_bit_writer_put_ue (bitwriter, 0); + gst_bit_writer_put_bits_uint32 (bitwriter, 4, 4); /* bit_rate_scale */ + gst_bit_writer_put_bits_uint32 (bitwriter, 6, 4); /* cpb_size_scale */ + + for (i = 0; i < 1; ++i) { + /* bit_rate_value_minus1[0] */ + gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1024 - 1); + /* cpb_size_value_minus1[0] */ + gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1024 * 8 - 1); + /* cbr_flag[0] */ + gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); + } + /* initial_cpb_removal_delay_length_minus1 */ + gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5); + /* cpb_removal_delay_length_minus1 */ + gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5); + /* dpb_output_delay_length_minus1 */ + gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5); + /* time_offset_length */ + gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5); + } + /* vcl_hrd_parameters_present_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); + if (nal_hrd_parameters_present_flag + || 0 /*vcl_hrd_parameters_present_flag */ ) { + /* low_delay_hrd_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); + } + /* pic_struct_present_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); + /* bitwriter_restriction_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); + } + + /* rbsp_trailing_bits */ + gst_bit_writer_write_trailing_bits (bitwriter); + return TRUE; +} + +static gboolean +gst_bit_writer_write_pps (GstBitWriter * bitwriter, + VAEncPictureParameterBufferH264 * pic) +{ + guint32 num_slice_groups_minus1 = 0; + guint32 pic_init_qs_minus26 = 0; + guint32 redundant_pic_cnt_present_flag = 0; + + /* pic_parameter_set_id */ + gst_bit_writer_put_ue (bitwriter, pic->pic_parameter_set_id); + /* seq_parameter_set_id */ + gst_bit_writer_put_ue (bitwriter, pic->seq_parameter_set_id); + /* entropy_coding_mode_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->pic_fields.bits.entropy_coding_mode_flag, 1); + /* pic_order_present_flag */ + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->pic_fields.bits.pic_order_present_flag, 1); + /*slice_groups-1 */ + gst_bit_writer_put_ue (bitwriter, num_slice_groups_minus1); + + if (num_slice_groups_minus1 > 0) { + /*FIXME*/ g_assert (0); + } + gst_bit_writer_put_ue (bitwriter, pic->num_ref_idx_l0_active_minus1); + gst_bit_writer_put_ue (bitwriter, pic->num_ref_idx_l1_active_minus1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->pic_fields.bits.weighted_pred_flag, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->pic_fields.bits.weighted_bipred_idc, 2); + /* pic_init_qp_minus26 */ + gst_bit_writer_put_se (bitwriter, pic->pic_init_qp - 26); + /* pic_init_qs_minus26 */ + gst_bit_writer_put_se (bitwriter, pic_init_qs_minus26); + /*chroma_qp_index_offset */ + gst_bit_writer_put_se (bitwriter, pic->chroma_qp_index_offset); + + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->pic_fields.bits.deblocking_filter_control_present_flag, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->pic_fields.bits.constrained_intra_pred_flag, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, redundant_pic_cnt_present_flag, 1); + + /*more_rbsp_data */ + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->pic_fields.bits.transform_8x8_mode_flag, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->pic_fields.bits.pic_scaling_matrix_present_flag, 1); + if (pic->pic_fields.bits.pic_scaling_matrix_present_flag) { + g_assert (0); + /* FIXME */ + /* + for (i = 0; i < + (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic->pic_fields.bits.transform_8x8_mode_flag)); + i++) { + gst_bit_writer_put_bits_uint8(bitwriter, pic->pic_fields.bits.pic_scaling_list_present_flag, 1); + } + */ + } + + gst_bit_writer_put_se (bitwriter, pic->second_chroma_qp_index_offset); + gst_bit_writer_write_trailing_bits (bitwriter); + + return TRUE; +} + +static gboolean +add_sequence_packed_header (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) +{ + GstVaapiEncPackedHeader *packed_seq; + GstBitWriter writer; + VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; + VAEncSequenceParameterBufferH264 *seq_param = sequence->param; + guint32 data_bit_size; + guint8 *data; + + gst_bit_writer_init (&writer, 128 * 8); + gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */ + gst_bit_writer_write_nal_header (&writer, + GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS); + gst_bit_writer_write_sps (&writer, seq_param, encoder->profile); + g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer); + data = GST_BIT_WRITER_DATA (&writer); + + packed_header_param_buffer.type = VAEncPackedHeaderSequence; + packed_header_param_buffer.bit_length = data_bit_size; + packed_header_param_buffer.has_emulation_bytes = 0; + + packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_header_param_buffer, sizeof (packed_header_param_buffer), + data, (data_bit_size + 7) / 8); + g_assert (packed_seq); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL); + + /* store sps data */ + _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); + + gst_bit_writer_clear (&writer, TRUE); + + return TRUE; +} + +static gboolean +add_picture_packed_header (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncPackedHeader *packed_pic; + GstBitWriter writer; + VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; + VAEncPictureParameterBufferH264 *pic_param = picture->param; + guint32 data_bit_size; + guint8 *data; + + gst_bit_writer_init (&writer, 128 * 8); + gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */ + gst_bit_writer_write_nal_header (&writer, + GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_PPS); + gst_bit_writer_write_pps (&writer, pic_param); + g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer); + data = GST_BIT_WRITER_DATA (&writer); + + packed_header_param_buffer.type = VAEncPackedHeaderPicture; + packed_header_param_buffer.bit_length = data_bit_size; + packed_header_param_buffer.has_emulation_bytes = 0; + + packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_header_param_buffer, sizeof (packed_header_param_buffer), + data, (data_bit_size + 7) / 8); + g_assert (packed_pic); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_pic); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_pic, NULL); + + /* store pps data */ + _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); + gst_bit_writer_clear (&writer, TRUE); + + return TRUE; +} + +/* reference picture management */ +static void +reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref) +{ + if (!ref) + return; + if (ref->pic) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic); + g_slice_free (GstVaapiEncoderH264Ref, ref); +} + +static inline GstVaapiEncoderH264Ref * +reference_pic_create (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) +{ + GstVaapiEncoderH264Ref *ref = g_slice_new0 (GstVaapiEncoderH264Ref); + + ref->pic = surface; + ref->frame_num = picture->frame_num; + ref->poc = picture->poc; + return ref; +} + +static gboolean +reference_list_update (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) +{ + GstVaapiEncoderH264Ref *ref; + + if (GST_VAAPI_PICTURE_TYPE_B == picture->type) { + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface); + return TRUE; + } + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { + while (!g_queue_is_empty (&encoder->ref_list)) + reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list)); + } else if (g_queue_get_length (&encoder->ref_list) >= encoder->max_ref_num) { + reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list)); + } + ref = reference_pic_create (encoder, picture, surface); + g_queue_push_tail (&encoder->ref_list, ref); + g_assert (g_queue_get_length (&encoder->ref_list) <= encoder->max_ref_num); + return TRUE; +} + +static gboolean +reference_list_init (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, + GstVaapiEncoderH264Ref ** reflist_0, + guint * reflist_0_count, + GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count) +{ + GstVaapiEncoderH264Ref *tmp; + GList *iter, *list_0_start = NULL, *list_1_start = NULL; + guint max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); + guint count; + + *reflist_0_count = 0; + *reflist_1_count = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_I) + return TRUE; + + iter = g_queue_peek_tail_link (&encoder->ref_list); + for (; iter; iter = g_list_previous (iter)) { + tmp = (GstVaapiEncoderH264Ref *) iter->data; + g_assert (tmp && tmp->poc != picture->poc); + if (_poc_greater_than (picture->poc, tmp->poc, max_pic_order_cnt)) { + list_0_start = iter; + list_1_start = g_list_next (iter); + break; + } + } + + /* order reflist_0 */ + g_assert (list_0_start); + iter = list_0_start; + count = 0; + for (; iter; iter = g_list_previous (iter)) { + reflist_0[count] = (GstVaapiEncoderH264Ref *) iter->data; + ++count; + } + *reflist_0_count = count; + + if (picture->type != GST_VAAPI_PICTURE_TYPE_B) + return TRUE; + + /* order reflist_1 */ + count = 0; + iter = list_1_start; + for (; iter; iter = g_list_next (iter)) { + reflist_1[count] = (GstVaapiEncoderH264Ref *) iter->data; + ++count; + } + *reflist_1_count = count; + return TRUE; +} + +/* fill the H264 VA encoding parameters */ +static gboolean +fill_va_sequence_param (GstVaapiEncoderH264 * encoder, + GstVaapiEncSequence * sequence) +{ + VAEncSequenceParameterBufferH264 *seq = sequence->param; + guint width_in_mbs, height_in_mbs; + + width_in_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; + height_in_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; + + memset (seq, 0, sizeof (VAEncSequenceParameterBufferH264)); + seq->seq_parameter_set_id = 0; + seq->level_idc = encoder->level; + seq->intra_period = encoder->intra_period; + seq->ip_period = 0; // ? + if (encoder->bitrate > 0) + seq->bits_per_second = encoder->bitrate * 1024; + else + seq->bits_per_second = 0; + + seq->max_num_ref_frames = encoder->max_ref_num; + seq->picture_width_in_mbs = width_in_mbs; + seq->picture_height_in_mbs = height_in_mbs; + + /*sequence field values */ + seq->seq_fields.value = 0; + seq->seq_fields.bits.chroma_format_idc = 1; + seq->seq_fields.bits.frame_mbs_only_flag = 1; + seq->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE; + seq->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE; + /* direct_8x8_inference_flag default false */ + seq->seq_fields.bits.direct_8x8_inference_flag = FALSE; + g_assert (encoder->log2_max_frame_num >= 4); + seq->seq_fields.bits.log2_max_frame_num_minus4 = + encoder->log2_max_frame_num - 4; + /* picture order count */ + seq->seq_fields.bits.pic_order_cnt_type = 0; + g_assert (encoder->log2_max_pic_order_cnt >= 4); + seq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = + encoder->log2_max_pic_order_cnt - 4; + + seq->bit_depth_luma_minus8 = 0; + seq->bit_depth_chroma_minus8 = 0; + + /* not used if pic_order_cnt_type == 0 */ + if (seq->seq_fields.bits.pic_order_cnt_type == 1) { + seq->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE; + seq->num_ref_frames_in_pic_order_cnt_cycle = 0; + seq->offset_for_non_ref_pic = 0; + seq->offset_for_top_to_bottom_field = 0; + memset (seq->offset_for_ref_frame, 0, sizeof (seq->offset_for_ref_frame)); + } + + if (height_in_mbs * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) { + seq->frame_cropping_flag = 1; + seq->frame_crop_left_offset = 0; + seq->frame_crop_right_offset = 0; + seq->frame_crop_top_offset = 0; + seq->frame_crop_bottom_offset = + ((height_in_mbs * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) / + (2 * (!seq->seq_fields.bits.frame_mbs_only_flag + 1))); + } + + /*vui not set */ + seq->vui_parameters_present_flag = (encoder->bitrate > 0 ? TRUE : FALSE); + if (seq->vui_parameters_present_flag) { + seq->vui_fields.bits.aspect_ratio_info_present_flag = FALSE; + seq->vui_fields.bits.bitstream_restriction_flag = FALSE; + seq->vui_fields.bits.timing_info_present_flag = + (encoder->bitrate > 0 ? TRUE : FALSE); + if (seq->vui_fields.bits.timing_info_present_flag) { + seq->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder); + seq->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2; + } + } + + return TRUE; +} + +static gboolean +fill_va_picture_param (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, + GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) +{ + VAEncPictureParameterBufferH264 *pic = picture->param; + GstVaapiEncoderH264Ref *ref_pic; + GList *reflist; + guint i; + + memset (pic, 0, sizeof (VAEncPictureParameterBufferH264)); + + /* reference list, */ + pic->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); + pic->CurrPic.TopFieldOrderCnt = picture->poc; + i = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (reflist = g_queue_peek_head_link (&encoder->ref_list); + reflist; reflist = g_list_next (reflist)) { + ref_pic = reflist->data; + g_assert (ref_pic && ref_pic->pic && + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID); + + pic->ReferenceFrames[i].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); + ++i; + } + g_assert (i <= 16 && i <= encoder->max_ref_num); + } + for (; i < 16; ++i) { + pic->ReferenceFrames[i].picture_id = VA_INVALID_ID; + } + pic->coded_buf = codedbuf->buf_id; + + pic->pic_parameter_set_id = 0; + pic->seq_parameter_set_id = 0; + pic->last_picture = 0; /* means last encoding picture */ + pic->frame_num = picture->frame_num; + pic->pic_init_qp = encoder->init_qp; + pic->num_ref_idx_l0_active_minus1 = + (encoder->max_reflist0_count ? (encoder->max_reflist0_count - 1) : 0); + pic->num_ref_idx_l1_active_minus1 = + (encoder->max_reflist1_count ? (encoder->max_reflist1_count - 1) : 0); + pic->chroma_qp_index_offset = 0; + pic->second_chroma_qp_index_offset = 0; + + /* set picture fields */ + pic->pic_fields.value = 0; + pic->pic_fields.bits.idr_pic_flag = GST_VAAPI_ENC_PICTURE_IS_IDR (picture); + pic->pic_fields.bits.reference_pic_flag = + (picture->type != GST_VAAPI_PICTURE_TYPE_B); + pic->pic_fields.bits.entropy_coding_mode_flag = + GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CABAC; + pic->pic_fields.bits.weighted_pred_flag = FALSE; + pic->pic_fields.bits.weighted_bipred_idc = 0; + pic->pic_fields.bits.constrained_intra_pred_flag = 0; + pic->pic_fields.bits.transform_8x8_mode_flag = (encoder->profile >= GST_VAAPI_PROFILE_H264_HIGH); /* enable 8x8 */ + /* enable debloking */ + pic->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; + pic->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE; + /* bottom_field_pic_order_in_frame_present_flag */ + pic->pic_fields.bits.pic_order_present_flag = FALSE; + pic->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE; + + return TRUE; +} + +static gboolean +fill_va_slices_param (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, + GstVaapiEncoderH264Ref ** reflist_0, + guint reflist_0_count, + GstVaapiEncoderH264Ref ** reflist_1, guint reflist_1_count) +{ + VAEncSliceParameterBufferH264 *slice_param; + GstVaapiEncSlice *slice; + guint width_in_mbs, height_in_mbs; + guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs; + guint total_mbs; + guint last_mb_index; + guint i_slice, i_ref; + + g_assert (picture); + + width_in_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; + height_in_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; + total_mbs = width_in_mbs * height_in_mbs; + + g_assert (encoder->slice_num && encoder->slice_num < total_mbs); + slice_of_mbs = total_mbs / encoder->slice_num; + slice_mod_mbs = total_mbs % encoder->slice_num; + last_mb_index = 0; + for (i_slice = 0; i_slice < encoder->slice_num; ++i_slice) { + cur_slice_mbs = slice_of_mbs; + if (slice_mod_mbs) { + ++cur_slice_mbs; + --slice_mod_mbs; + } + slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder); + g_assert (slice && slice->param_id != VA_INVALID_ID); + slice_param = slice->param; + + memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264)); + slice_param->macroblock_address = last_mb_index; + slice_param->num_macroblocks = cur_slice_mbs; + slice_param->macroblock_info = VA_INVALID_ID; + slice_param->slice_type = _get_va_slice_type (picture->type); + g_assert (slice_param->slice_type != -1); + slice_param->pic_parameter_set_id = 0; + slice_param->idr_pic_id = encoder->idr_num; + slice_param->pic_order_cnt_lsb = picture->poc; + + /* not used if pic_order_cnt_type = 0 */ + slice_param->delta_pic_order_cnt_bottom = 0; + memset (slice_param->delta_pic_order_cnt, + 0, sizeof (slice_param->delta_pic_order_cnt)); + + /*only works for B frames */ + slice_param->direct_spatial_mv_pred_flag = FALSE; + /* default equal to picture parameters */ + slice_param->num_ref_idx_active_override_flag = FALSE; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) + slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; + else + slice_param->num_ref_idx_l0_active_minus1 = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0) + slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; + else + slice_param->num_ref_idx_l1_active_minus1 = 0; + g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0); + g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0); + + i_ref = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (; i_ref < reflist_0_count; ++i_ref) { + slice_param->RefPicList0[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); + } + g_assert (i_ref == 1); + } + for (; + i_ref < + sizeof (slice_param->RefPicList0) / + sizeof (slice_param->RefPicList0[0]); ++i_ref) { + slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE; + } + + i_ref = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + for (; i_ref < reflist_1_count; ++i_ref) { + slice_param->RefPicList1[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); + } + g_assert (i_ref == 1); + } + for (; + i_ref < + sizeof (slice_param->RefPicList1) / + sizeof (slice_param->RefPicList1[0]); ++i_ref) { + slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE; + } + + /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */ + slice_param->luma_log2_weight_denom = 0; + slice_param->chroma_log2_weight_denom = 0; + slice_param->luma_weight_l0_flag = FALSE; + memset (slice_param->luma_weight_l0, 0, + sizeof (slice_param->luma_weight_l0)); + memset (slice_param->luma_offset_l0, 0, + sizeof (slice_param->luma_offset_l0)); + slice_param->chroma_weight_l0_flag = FALSE; + memset (slice_param->chroma_weight_l0, 0, + sizeof (slice_param->chroma_weight_l0)); + memset (slice_param->chroma_offset_l0, 0, + sizeof (slice_param->chroma_offset_l0)); + slice_param->luma_weight_l1_flag = FALSE; + memset (slice_param->luma_weight_l1, 0, + sizeof (slice_param->luma_weight_l1)); + memset (slice_param->luma_offset_l1, 0, + sizeof (slice_param->luma_offset_l1)); + slice_param->chroma_weight_l1_flag = FALSE; + memset (slice_param->chroma_weight_l1, 0, + sizeof (slice_param->chroma_weight_l1)); + memset (slice_param->chroma_offset_l1, 0, + sizeof (slice_param->chroma_offset_l1)); + + slice_param->cabac_init_idc = 0; + slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp; + if (slice_param->slice_qp_delta > 4) + slice_param->slice_qp_delta = 4; + slice_param->disable_deblocking_filter_idc = 0; + slice_param->slice_alpha_c0_offset_div2 = 2; + slice_param->slice_beta_offset_div2 = 2; + + /* set calculation for next slice */ + last_mb_index += cur_slice_mbs; + + gst_vaapi_enc_picture_add_slice (picture, slice); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & slice, NULL); + + } + g_assert (last_mb_index == total_mbs); + return TRUE; +} + +static gboolean +ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncSequence *sequence; + + g_assert (picture); + sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder); + g_assert (sequence); + if (!sequence) + goto error; + + if (!fill_va_sequence_param (encoder, sequence)) + goto error; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_I && + !add_sequence_packed_header (encoder, picture, sequence)) + goto error; + gst_vaapi_enc_picture_set_sequence (picture, sequence); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL); + return TRUE; + +error: + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL); + return FALSE; +} + +static gboolean +ensure_picture (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, + GstVaapiCodedBufferProxy * buf_proxy, GstVaapiSurfaceProxy * surface) +{ + GstVaapiCodedBuffer *codedbuf = buf_proxy->buffer; + + if (!fill_va_picture_param (encoder, picture, codedbuf, surface)) + return FALSE; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_I && + !add_picture_packed_header (encoder, picture)) { + GST_ERROR ("set picture packed header failed"); + return FALSE; + } + + return TRUE; +} + +static gboolean +ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncoderH264Ref *reflist_0[16]; + GstVaapiEncoderH264Ref *reflist_1[16]; + guint reflist_0_count = 0, reflist_1_count = 0; + + g_assert (picture); + + if (picture->type != GST_VAAPI_PICTURE_TYPE_I && + !reference_list_init (encoder, picture, + reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) { + GST_ERROR ("reference list reorder failed"); + return FALSE; + } + + g_assert (reflist_0_count + reflist_1_count <= encoder->max_ref_num); + if (reflist_0_count > encoder->max_reflist0_count) + reflist_0_count = encoder->max_reflist0_count; + if (reflist_1_count > encoder->max_reflist1_count) + reflist_1_count = encoder->max_reflist1_count; + + if (!fill_va_slices_param (encoder, picture, + reflist_0, reflist_0_count, reflist_1, reflist_1_count)) + return FALSE; + + return TRUE; +} + +static gboolean +ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncMiscParam *misc = NULL; + VAEncMiscParameterHRD *hrd; + VAEncMiscParameterRateControl *rate_control; + + /* add hrd */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); + g_assert (misc); + if (!misc) + return FALSE; + gst_vaapi_enc_picture_add_misc_buffer (picture, misc); + hrd = misc->impl; + if (encoder->bitrate > 0) { + hrd->initial_buffer_fullness = encoder->bitrate * 1024 * 4; + hrd->buffer_size = encoder->bitrate * 1024 * 8; + } else { + hrd->initial_buffer_fullness = 0; + hrd->buffer_size = 0; + } + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL); + + /* add ratecontrol */ + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR || + GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) { + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); + g_assert (misc); + if (!misc) + return FALSE; + gst_vaapi_enc_picture_add_misc_buffer (picture, misc); + rate_control = misc->impl; + memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); + if (encoder->bitrate) + rate_control->bits_per_second = encoder->bitrate * 1024; + else + rate_control->bits_per_second = 0; + rate_control->target_percentage = 70; + rate_control->window_size = 500; + rate_control->initial_qp = encoder->init_qp; + rate_control->min_qp = encoder->min_qp; + rate_control->basic_unit_size = 0; + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL); + } + + return TRUE; +} + +gboolean +init_encoder_public_attributes (GstVaapiEncoderH264 * encoder) +{ + guint width_mbs, height_mbs, total_mbs; + + if (!GST_VAAPI_ENCODER_WIDTH (encoder) || + !GST_VAAPI_ENCODER_HEIGHT (encoder) || + !GST_VAAPI_ENCODER_FPS_N (encoder) || + !GST_VAAPI_ENCODER_FPS_D (encoder)) { + return FALSE; + } + if (!encoder->profile) + encoder->profile = GST_VAAPI_ENCODER_H264_DEFAULT_PROFILE; + + _set_level (encoder); + + if (!encoder->intra_period) + encoder->intra_period = GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD; + else if (encoder->intra_period > GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD) + encoder->intra_period = GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD; + + if (encoder->idr_period < encoder->intra_period) + encoder->idr_period = encoder->intra_period; + if (encoder->idr_period > GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD) + encoder->idr_period = GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD; + + if (-1 == encoder->init_qp) + encoder->init_qp = GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP; + + if (-1 == encoder->min_qp) { + if (GST_VAAPI_RATECONTROL_CQP == GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) + encoder->min_qp = encoder->init_qp; + else + encoder->min_qp = GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP; + } + + if (encoder->min_qp > encoder->init_qp) + encoder->min_qp = encoder->init_qp; + + /* default compress ratio 1: (4*8*1.5) */ + if (GST_VAAPI_RATECONTROL_CBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) || + GST_VAAPI_RATECONTROL_VBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) || + GST_VAAPI_RATECONTROL_VBR_CONSTRAINED == + GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { + if (!encoder->bitrate) + encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * + GST_VAAPI_ENCODER_HEIGHT (encoder) * + GST_VAAPI_ENCODER_FPS_N (encoder) / + GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024; + } else + encoder->bitrate = 0; + + if (!encoder->slice_num) + encoder->slice_num = GST_VAAPI_ENCODER_H264_DEFAULT_SLICE_NUM; + + width_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; + height_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; + total_mbs = width_mbs * height_mbs; + + if (encoder->slice_num > (total_mbs + 1) / 2) + encoder->slice_num = (total_mbs + 1) / 2; + g_assert (encoder->slice_num); + + if (encoder->b_frame_num > (encoder->intra_period + 1) / 2) + encoder->b_frame_num = (encoder->intra_period + 1) / 2; + + if (encoder->b_frame_num > 50) + encoder->b_frame_num = 50; + + return TRUE; +} + +static gboolean +init_encoder_private_attributes (GstVaapiEncoderH264 * encoder, GstCaps * caps) +{ + if (encoder->b_frame_num) + encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) / + GST_VAAPI_ENCODER_FPS_N (encoder); + else + encoder->cts_offset = 0; + + /* init max_frame_num, max_poc */ + encoder->log2_max_frame_num = _get_log2_max_frame_num (encoder->idr_period); + g_assert (encoder->log2_max_frame_num >= 4); + encoder->max_frame_num = (1 << encoder->log2_max_frame_num); + encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1; + encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); + + encoder->frame_index = 0; + encoder->idr_num = 0; + encoder->max_reflist0_count = 1; + if (encoder->b_frame_num) + encoder->max_reflist1_count = 1; + else + encoder->max_reflist1_count = 0; + encoder->max_ref_num = + encoder->max_reflist0_count + encoder->max_reflist1_count; + return TRUE; +} + + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base, + GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) +{ + GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base); + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR; + GstVaapiSurfaceProxy *reconstruct = NULL; + + reconstruct = gst_vaapi_encoder_create_surface (base); + + g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct)); + + if (!ensure_sequence (encoder, picture)) + goto error; + if (!ensure_picture (encoder, picture, codedbuf, reconstruct)) + goto error; + if (!ensure_misc (encoder, picture)) + goto error; + if (!ensure_slices (encoder, picture)) + goto error; + if (!gst_vaapi_enc_picture_encode (picture)) + goto error; + + if (!reference_list_update (encoder, picture, reconstruct)) + goto error; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +error: + if (reconstruct) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); + return ret; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base) +{ + GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base); + GstVaapiEncPicture *pic; + + encoder->frame_index = 0; + encoder->cur_frame_num = 0; + encoder->cur_present_index = 0; + while (!g_queue_is_empty (&encoder->reorder_frame_list)) { + pic = + (GstVaapiEncPicture *) g_queue_pop_head (&encoder->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&encoder->reorder_frame_list); + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_get_avcC_codec_data (GstVaapiEncoderH264 * encoder, + GstBuffer ** buffer) +{ + GstBuffer *avc_codec; + const guint32 configuration_version = 0x01; + const guint32 length_size_minus_one = 0x03; + guint32 profile, profile_comp, level_idc; + GstMapInfo sps_info, pps_info; + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; + GstBitWriter writer; + + g_assert (buffer); + if (!encoder->sps_data || !encoder->pps_data) + return GST_VAAPI_ENCODER_STATUS_NOT_READY; + + if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ)) + return GST_VAAPI_ENCODER_STATUS_MEM_ERROR; + + if (FALSE == _read_sps_attributes (sps_info.data, sps_info.size, + &profile, &profile_comp, &level_idc)) { + ret = GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR; + goto end; + } + + if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ)) { + ret = GST_VAAPI_ENCODER_STATUS_MEM_ERROR; + goto end; + } + + gst_bit_writer_init (&writer, (sps_info.size + pps_info.size + 64) * 8); + /* codec_data */ + gst_bit_writer_put_bits_uint32 (&writer, configuration_version, 8); + gst_bit_writer_put_bits_uint32 (&writer, profile, 8); + gst_bit_writer_put_bits_uint32 (&writer, profile_comp, 8); + gst_bit_writer_put_bits_uint32 (&writer, level_idc, 8); + gst_bit_writer_put_bits_uint32 (&writer, 0x3F, 6); /*111111 */ + gst_bit_writer_put_bits_uint32 (&writer, length_size_minus_one, 2); + gst_bit_writer_put_bits_uint32 (&writer, 0x07, 3); /*111 */ + + /* write sps */ + gst_bit_writer_put_bits_uint32 (&writer, 1, 5); /* sps count = 1 */ + g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); + gst_bit_writer_put_bits_uint32 (&writer, sps_info.size, 16); + gst_bit_writer_put_bytes (&writer, sps_info.data, sps_info.size); + + /* write pps */ + gst_bit_writer_put_bits_uint32 (&writer, 1, 8); /*pps count = 1 */ + gst_bit_writer_put_bits_uint32 (&writer, pps_info.size, 16); + gst_bit_writer_put_bytes (&writer, pps_info.data, pps_info.size); + + avc_codec = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&writer), + GST_BIT_WRITER_BIT_SIZE (&writer) / 8); + g_assert (avc_codec); + if (!avc_codec) { + ret = GST_VAAPI_ENCODER_STATUS_MEM_ERROR; + goto clear_writer; + } + *buffer = avc_codec; + + gst_buffer_unmap (encoder->pps_data, &pps_info); + gst_bit_writer_clear (&writer, FALSE); + ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; + goto end; + +clear_writer: + gst_bit_writer_clear (&writer, TRUE); + +end: + gst_buffer_unmap (encoder->sps_data, &sps_info); + + return ret; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base, + GstBuffer ** buffer) +{ + GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base); + + *buffer = NULL; + + if (!encoder->is_avc) + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + return gst_vaapi_encoder_h264_get_avcC_codec_data (encoder, buffer); +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base, + GstVideoCodecFrame * frame, gboolean flush, GstVaapiEncPicture ** output) +{ + GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base); + GstVaapiEncPicture *picture; + gboolean is_idr = FALSE; + + *output = NULL; + + if (!frame) { + if (encoder->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES) + return GST_VAAPI_ENCODER_STATUS_FRAME_NOT_READY; + + /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES + dump B frames from queue, sometime, there may also have P frame or I frame */ + g_assert (encoder->b_frame_num > 0); + g_return_val_if_fail (!g_queue_is_empty (&encoder->reorder_frame_list), + GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR); + picture = g_queue_pop_head (&encoder->reorder_frame_list); + g_assert (picture); + if (g_queue_is_empty (&encoder->reorder_frame_list)) { + encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; + } + goto end; + } + + /* new frame coming */ + picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame); + if (!picture) { + GST_WARNING ("create H264 picture failed, frame timestamp:%" + GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); + return GST_VAAPI_ENCODER_STATUS_OBJECT_ERR; + } + ++encoder->cur_present_index; + picture->poc = ((encoder->cur_present_index * 2) % + encoder->max_pic_order_cnt); + + is_idr = (encoder->frame_index == 0 || + encoder->frame_index >= encoder->idr_period); + + /* check key frames */ + if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) || + (encoder->frame_index % encoder->intra_period) == 0) { + ++encoder->cur_frame_num; + ++encoder->frame_index; + + /* b frame enabled, check queue of reorder_frame_list */ + if (encoder->b_frame_num + && !g_queue_is_empty (&encoder->reorder_frame_list)) { + GstVaapiEncPicture *p_pic; + + p_pic = g_queue_pop_tail (&encoder->reorder_frame_list); + _set_p_frame (p_pic, encoder); + g_queue_foreach (&encoder->reorder_frame_list, + (GFunc) _set_b_frame, encoder); + ++encoder->cur_frame_num; + _set_key_frame (picture, encoder, is_idr); + g_queue_push_tail (&encoder->reorder_frame_list, picture); + picture = p_pic; + encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; + } else { /* no b frames in queue */ + _set_key_frame (picture, encoder, is_idr); + g_assert (g_queue_is_empty (&encoder->reorder_frame_list)); + if (encoder->b_frame_num) + encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; + } + goto end; + } + + /* new p/b frames coming */ + ++encoder->frame_index; + if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES && + g_queue_get_length (&encoder->reorder_frame_list) < + encoder->b_frame_num) { + g_queue_push_tail (&encoder->reorder_frame_list, picture); + return GST_VAAPI_ENCODER_STATUS_FRAME_NOT_READY; + } + + ++encoder->cur_frame_num; + _set_p_frame (picture, encoder); + + if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) { + g_queue_foreach (&encoder->reorder_frame_list, (GFunc) _set_b_frame, + encoder); + encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; + g_assert (!g_queue_is_empty (&encoder->reorder_frame_list)); + } + +end: + g_assert (picture); + frame = GST_VAAPI_ENC_PICTURE_GET_FRAME (picture); + if (GST_CLOCK_TIME_IS_VALID (frame->pts)) + frame->pts += encoder->cts_offset; + *output = picture; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static gboolean +gst_vaapi_encoder_h264_get_context_info (GstVaapiEncoder * base, + GstVaapiContextInfo * info) +{ + GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base); + const static guint default_surface_num = 3; + + g_return_val_if_fail (info, FALSE); + + info->profile = encoder->profile; + info->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + info->width = GST_VAAPI_ENCODER_WIDTH (encoder); + info->height = GST_VAAPI_ENCODER_HEIGHT (encoder); + info->ref_frames = (encoder->b_frame_num ? 2 : 1) + default_surface_num; + info->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); + + return TRUE; +} + +static GstCaps * +gst_vaapi_encoder_h264_set_format (GstVaapiEncoder * base, + GstVideoCodecState * in_state, GstCaps * ref_caps) +{ + GstVaapiEncoderH264 *encoder; + GstCaps *result = NULL, *tmp; + GstStructure *structure; + const GValue *value; + const gchar *stream_format; + + encoder = GST_VAAPI_ENCODER_H264 (base); + + tmp = gst_caps_from_string ("video/x-h264"); + gst_caps_set_simple (tmp, + "width", G_TYPE_INT, GST_VAAPI_ENCODER_WIDTH (encoder), + "height", G_TYPE_INT, GST_VAAPI_ENCODER_HEIGHT (encoder), + "framerate", GST_TYPE_FRACTION, + GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder), + NULL); + result = gst_caps_intersect (tmp, ref_caps); + gst_caps_unref (tmp); + + /* fixed stream-format and choose byte-stream first */ + structure = gst_caps_get_structure (result, 0); + value = gst_structure_get_value (structure, "stream-format"); + if (value) { + gst_structure_fixate_field_string (structure, "stream-format", + "byte-stream"); + stream_format = gst_structure_get_string (structure, "stream-format"); + } else { + stream_format = "byte-stream"; + gst_structure_set (structure, "stream-format", G_TYPE_STRING, stream_format, + NULL); + } + + if (strcmp (stream_format, "byte-stream") == 0) + encoder->is_avc = FALSE; + else /* need codec data later */ + encoder->is_avc = TRUE; + + result = gst_caps_fixate (result); + + if (!init_encoder_public_attributes (encoder)) { + GST_WARNING ("encoder ensure public attributes failed "); + goto error; + } + + if (!init_encoder_private_attributes (encoder, result)) { + GST_WARNING ("prepare encoding failed "); + goto error; + } + + return result; + +error: + gst_caps_unref (result); + return NULL; +} + +static gboolean +gst_vaapi_encoder_h264_init (GstVaapiEncoder * base) +{ + GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base); + + /* init attributes */ + encoder->profile = 0; + encoder->level = 0; + encoder->bitrate = 0; + encoder->idr_period = 0; + encoder->intra_period = 0; + encoder->init_qp = -1; + encoder->min_qp = -1; + encoder->slice_num = 0; + encoder->b_frame_num = 0; + //gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE); + + /* init private values */ + encoder->is_avc = FALSE; + /* re-ordering */ + g_queue_init (&encoder->reorder_frame_list); + encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE; + encoder->frame_index = 0; + encoder->cur_frame_num = 0; + encoder->cur_present_index = 0; + + g_queue_init (&encoder->ref_list); + encoder->max_ref_num = 0; + encoder->max_reflist0_count = 1; + encoder->max_reflist1_count = 1; + + encoder->sps_data = NULL; + encoder->pps_data = NULL; + + encoder->cts_offset = 0; + + encoder->max_frame_num = 0; + encoder->log2_max_frame_num = 0; + encoder->max_pic_order_cnt = 0; + encoder->log2_max_pic_order_cnt = 0; + encoder->idr_num = 0; + + return TRUE; +} + +static void +gst_vaapi_encoder_h264_destroy (GstVaapiEncoder * base) +{ + /*free private buffers */ + GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base); + GstVaapiEncPicture *pic; + GstVaapiEncoderH264Ref *ref; + + gst_buffer_replace (&encoder->sps_data, NULL); + gst_buffer_replace (&encoder->pps_data, NULL); + + while (!g_queue_is_empty (&encoder->ref_list)) { + ref = (GstVaapiEncoderH264Ref *) g_queue_pop_head (&encoder->ref_list); + reference_pic_free (encoder, ref); + } + g_queue_clear (&encoder->ref_list); + + while (!g_queue_is_empty (&encoder->reorder_frame_list)) { + pic = + (GstVaapiEncPicture *) g_queue_pop_head (&encoder->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&encoder->reorder_frame_list); + +} + +static void +gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) +{ + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass); + + gst_vaapi_encoder_class_init (encoder_class); + + object_class->size = sizeof (GstVaapiEncoderH264); + + encoder_class->init = gst_vaapi_encoder_h264_init; + encoder_class->destroy = gst_vaapi_encoder_h264_destroy; + encoder_class->set_format = gst_vaapi_encoder_h264_set_format; + encoder_class->get_context_info = gst_vaapi_encoder_h264_get_context_info; + encoder_class->reordering = gst_vaapi_encoder_h264_reordering; + encoder_class->encode = gst_vaapi_encoder_h264_encode; + encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data; + encoder_class->flush = gst_vaapi_encoder_h264_flush; +} + +static inline const GstVaapiEncoderClass * +gst_vaapi_encoder_h264_class () +{ + static GstVaapiEncoderH264Class g_class; + static gsize g_class_init = FALSE; + + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_encoder_h264_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_ENCODER_CLASS (&g_class); +} + +GstVaapiEncoder * +gst_vaapi_encoder_h264_new (GstVaapiDisplay * display) +{ + return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display); +} + +void +gst_vaapi_encoder_h264_set_avc (GstVaapiEncoderH264 * encoder, gboolean is_avc) +{ + encoder->is_avc = is_avc; +} + +gboolean +gst_vaapi_encoder_h264_is_avc (GstVaapiEncoderH264 * encoder) +{ + return encoder->is_avc; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h new file mode 100644 index 0000000000..2063f4aefe --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -0,0 +1,41 @@ +/* + * gstvaapiencoder_h264.h - H.264 encoder + * + * Copyright (C) 2011-2013 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; + +GstVaapiEncoder * +gst_vaapi_encoder_h264_new (GstVaapiDisplay * display); + +void +gst_vaapi_encoder_h264_set_avc (GstVaapiEncoderH264 * encoder, gboolean is_avc); + +gboolean +gst_vaapi_encoder_h264_is_avc (GstVaapiEncoderH264 * encoder); + +G_END_DECLS +#endif /*GST_VAAPI_ENCODER_H264_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h new file mode 100644 index 0000000000..a7027ae913 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h @@ -0,0 +1,126 @@ +/* + * gstvaapiencoder_h264_priv.h - H.264 encoder (private definitions) + * + * Copyright (C) 2013 Intel Corporation + * + * 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_PRIV_H +#define GST_VAAPI_ENCODER_H264_PRIV_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_ENCODER_H264(encoder) \ + ((GstVaapiEncoderH264 *)(encoder)) +#define GST_VAAPI_ENCODER_H264_CAST(encoder) \ + ((GstVaapiEncoderH264 *)(encoder)) +#define GST_VAAPI_ENCODER_H264_CLASS(klass) \ + ((GstVaapiEncoderH264Class *)(klass)) +#define GST_IS_VAAPI_ENCODER_H264_CLASS(klass) \ + ((klass) != NULL) +#define GST_VAAPI_ENCODER_H264_GET_CLASS(obj) \ + GST_VAAPI_ENCODER_H264_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + +typedef struct _GstVaapiEncoderH264Class GstVaapiEncoderH264Class; + +typedef enum +{ + GST_VAAPI_ENCODER_H264_LEVEL_10 = 10, /* QCIF format, < 380160 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_11 = 11, /* CIF format, < 768000 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_12 = 12, /* CIF format, < 1536000 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_13 = 13, /* CIF format, < 3041280 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_20 = 20, /* CIF format, < 3041280 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_21 = 21, /* HHR format, < 5068800 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_22 = 22, /* SD/4CIF format, < 5184000 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_30 = 30, /* SD/4CIF format, < 10368000 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_31 = 31, /* 720pHD format, < 27648000 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_32 = 32, /* SXGA format, < 55296000 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_40 = 40, /* 2Kx1K format, < 62914560 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_41 = 41, /* 2Kx1K format, < 62914560 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_42 = 42, /* 2Kx1K format, < 125829120 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_50 = 50, /* 3672x1536 format, < 150994944 samples/sec */ + GST_VAAPI_ENCODER_H264_LEVEL_51 = 51, /* 4096x2304 format, < 251658240 samples/sec */ +} GstVaapiEncoderH264Level; + +#define GST_VAAPI_ENCODER_H264_DEFAULT_PROFILE GST_VAAPI_PROFILE_H264_BASELINE +#define GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL GST_VAAPI_ENCODER_H264_LEVEL_31 +#define GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP 26 +#define GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP 1 +#define GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD 30 +#define GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD 512 +#define GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD 512 + +#define GST_VAAPI_ENCODER_H264_DEFAULT_SLICE_NUM 1 + +struct _GstVaapiEncoderH264 +{ + GstVaapiEncoder parent; + + /* public */ + guint32 profile; + guint32 level; + guint32 bitrate; /*kbps */ + guint32 intra_period; + guint32 idr_period; + guint32 init_qp; /*default 24 */ + guint32 min_qp; /*default 1 */ + guint32 slice_num; + guint32 b_frame_num; + + /* private */ + gboolean is_avc; /* avc or bytestream */ + /* re-ordering */ + GQueue reorder_frame_list; + guint reorder_state; + guint frame_index; + guint cur_frame_num; + guint cur_present_index; + GstClockTime cts_offset; + + /* reference list */ + GQueue ref_list; + guint max_ref_num; + /* max reflist count */ + guint max_reflist0_count; + guint max_reflist1_count; + + /* frame, poc */ + guint32 max_frame_num; + guint32 log2_max_frame_num; + guint32 max_pic_order_cnt; + guint32 log2_max_pic_order_cnt; + guint32 idr_num; + + GstBuffer *sps_data; + GstBuffer *pps_data; + +}; + +struct _GstVaapiEncoderH264Class +{ + /*< private > */ + GstVaapiEncoderClass parent_class; +}; + +G_END_DECLS + +#endif /*GST_VAAPI_ENCODER_H264_PRIV_H */ From d753c2226a42f30d44cbf074d0ba51c9b53ded0c Mon Sep 17 00:00:00 2001 From: XuGuangxin Date: Wed, 20 Nov 2013 16:20:15 +0800 Subject: [PATCH 1410/3781] encoder: add mpeg2 encoder. Add initial support for MPEG-2 encoding. I/P/B frames are supported. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 948 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 36 + .../gst/vaapi/gstvaapiencoder_mpeg2_priv.h | 116 +++ 4 files changed, 1102 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f147d99891..f2f9bbab31 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -137,12 +137,14 @@ endif libgstvaapi_enc_source_c = \ gstvaapiencoder.c \ gstvaapiencoder_h264.c \ + gstvaapiencoder_mpeg2.c \ gstvaapiencoder_objects.c \ $(NULL) libgstvaapi_enc_source_h = \ gstvaapiencoder.h \ gstvaapiencoder_h264.h \ + gstvaapiencoder_mpeg2.h \ $(NULL) libgstvaapi_enc_source_priv_h = \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c new file mode 100644 index 0000000000..2c6e682df1 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -0,0 +1,948 @@ +/* + * gstvaapiencoder_mpeg2.c - MPEG-2 encoder + * + * Copyright (C) 2012 -2013 Intel Corporation + * + * 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 +#include "gstvaapicompat.h" +#include "gstvaapiencoder_mpeg2.h" +#include "gstvaapiencoder_mpeg2_priv.h" +#include "gstvaapiencoder_priv.h" + +#include +#include + +#include "gstvaapicontext.h" +#include "gstvaapisurface.h" +#include "gstvaapidisplay_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + + +static gboolean +gst_bit_writer_write_sps (GstBitWriter * bitwriter, + VAEncSequenceParameterBufferMPEG2 * seq, GstVaapiEncoderMpeg2 * encoder); + +static gboolean +gst_bit_writer_write_pps (GstBitWriter * bitwriter, + VAEncPictureParameterBufferMPEG2 * pic); + + +static void clear_references (GstVaapiEncoderMpeg2 * encoder); + +static void push_reference (GstVaapiEncoderMpeg2 * encoder, + GstVaapiSurfaceProxy * ref;); + +static struct +{ + int samplers_per_line; + int line_per_frame; + int frame_per_sec; +} mpeg2_upper_samplings[2][3] = { + { { 0, 0, 0}, + { 720, 576, 30 }, + { 0, 0, 0 }, + }, + { { 352, 288, 30 }, + { 720, 576, 30 }, + { 1920, 1152, 60 }, + } +}; + +static gboolean +ensure_sampling_desity (GstVaapiEncoderMpeg2 * encoder) +{ + guint p, l; + float fps; + p = encoder->profile; + l = encoder->level; + fps = GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder); + if (mpeg2_upper_samplings[p][l].samplers_per_line < + GST_VAAPI_ENCODER_WIDTH (encoder) + || mpeg2_upper_samplings[p][l].line_per_frame < + GST_VAAPI_ENCODER_HEIGHT (encoder) + || mpeg2_upper_samplings[p][l].frame_per_sec < fps) { + GST_ERROR + ("acording to slected profile(%d) and level(%d) the max resolution is %dx%d@%d", + p, l, mpeg2_upper_samplings[p][l].samplers_per_line, + mpeg2_upper_samplings[p][l].line_per_frame, + mpeg2_upper_samplings[p][l].frame_per_sec); + return FALSE; + } + return TRUE; +} + +static gboolean +ensure_public_attributes (GstVaapiEncoderMpeg2 * encoder) +{ + if (!GST_VAAPI_ENCODER_WIDTH (encoder) || + !GST_VAAPI_ENCODER_HEIGHT (encoder) || + !GST_VAAPI_ENCODER_FPS_N (encoder) || + !GST_VAAPI_ENCODER_FPS_D (encoder)) { + return FALSE; + } + + if (encoder->ip_period > encoder->intra_period) { + encoder->ip_period = encoder->intra_period - 1; + } + + if (encoder->profile == GST_ENCODER_MPEG2_PROFILE_SIMPLE) { + /* no b frames */ + encoder->ip_period = 0; + /* only main level is defined in mpeg2 */ + encoder->level = GST_VAAPI_ENCODER_MPEG2_LEVEL_MAIN; + } + + if (!ensure_sampling_desity (encoder)) + return FALSE; + + /* default compress ratio 1: (4*8*1.5) */ + if (GST_VAAPI_RATECONTROL_CBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { + if (!encoder->bitrate) + encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * + GST_VAAPI_ENCODER_HEIGHT (encoder) * + GST_VAAPI_ENCODER_FPS_N (encoder) / + GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024; + } else + encoder->bitrate = 0; + + return TRUE; +} + +static unsigned char +make_profile_and_level_indication (guint32 profile, guint32 level) +{ + guint32 p = 4, l = 8; + switch (profile) { + case GST_ENCODER_MPEG2_PROFILE_SIMPLE: + p = 5; + break; + case GST_ENCODER_MPEG2_PROFILE_MAIN: + p = 4; + break; + default: + g_assert (0); + break; + } + + switch (level) { + case GST_VAAPI_ENCODER_MPEG2_LEVEL_LOW: + l = 10; + break; + case GST_VAAPI_ENCODER_MPEG2_LEVEL_MAIN: + l = 8; + break; + case GST_VAAPI_ENCODER_MPEG2_LEVEL_HIGH: + l = 4; + break; + default: + g_assert (0); + break; + } + return p << 4 | l; +} + +static gboolean +fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence) +{ + VAEncSequenceParameterBufferMPEG2 *seq = sequence->param; + + memset (seq, 0, sizeof (VAEncSequenceParameterBufferMPEG2)); + + seq->intra_period = encoder->intra_period; + seq->ip_period = encoder->ip_period; + seq->picture_width = GST_VAAPI_ENCODER_WIDTH (encoder); + seq->picture_height = GST_VAAPI_ENCODER_HEIGHT (encoder); + + if (encoder->bitrate > 0) + seq->bits_per_second = encoder->bitrate * 1024; + else + seq->bits_per_second = 0; + + if (GST_VAAPI_ENCODER_FPS_D (encoder)) + seq->frame_rate = + GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder); + else + seq->frame_rate = 0; + + seq->aspect_ratio_information = 1; + seq->vbv_buffer_size = 3; /* B = 16 * 1024 * vbv_buffer_size */ + + seq->sequence_extension.bits.profile_and_level_indication = + make_profile_and_level_indication (encoder->profile, encoder->level); + seq->sequence_extension.bits.progressive_sequence = 1; /* progressive frame-pictures */ + seq->sequence_extension.bits.chroma_format = CHROMA_FORMAT_420; /* 4:2:0 */ + seq->sequence_extension.bits.low_delay = 0; /* FIXME */ + seq->sequence_extension.bits.frame_rate_extension_n = 0; /*FIXME */ + seq->sequence_extension.bits.frame_rate_extension_d = 0; + + seq->gop_header.bits.time_code = (1 << 12); /* bit12: marker_bit */ + seq->gop_header.bits.closed_gop = 0; + seq->gop_header.bits.broken_link = 0; + + return TRUE; +} + +static VAEncPictureType +get_va_enc_picture_type (GstVaapiPictureType type) +{ + switch (type) { + case GST_VAAPI_PICTURE_TYPE_I: + return VAEncPictureTypeIntra; + case GST_VAAPI_PICTURE_TYPE_P: + return VAEncPictureTypePredictive; + case GST_VAAPI_PICTURE_TYPE_B: + return VAEncPictureTypeBidirectional; + default: + return -1; + } + return -1; +} + +static gboolean +fill_picture (GstVaapiEncoderMpeg2 * encoder, + GstVaapiEncPicture * picture, + GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) +{ + VAEncPictureParameterBufferMPEG2 *pic = picture->param; + uint8_t f_code_x, f_code_y; + + memset (pic, 0, sizeof (VAEncPictureParameterBufferMPEG2)); + + pic->reconstructed_picture = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); + pic->coded_buf = codedbuf->buf_id; + pic->picture_type = get_va_enc_picture_type (picture->type); + pic->temporal_reference = picture->frame_num & (1024 - 1); + pic->vbv_delay = 0xFFFF; + + f_code_x = 0xf; + f_code_y = 0xf; + if (pic->picture_type != VAEncPictureTypeIntra) { + if (encoder->level == GST_VAAPI_ENCODER_MPEG2_LEVEL_LOW) { + f_code_x = 7; + f_code_y = 4; + } else if (encoder->level == GST_VAAPI_ENCODER_MPEG2_LEVEL_MAIN) { + f_code_x = 8; + f_code_y = 5; + } else { + f_code_x = 9; + f_code_y = 5; + } + } + + if (pic->picture_type == VAEncPictureTypeIntra) { + pic->f_code[0][0] = 0xf; + pic->f_code[0][1] = 0xf; + pic->f_code[1][0] = 0xf; + pic->f_code[1][1] = 0xf; + pic->forward_reference_picture = VA_INVALID_SURFACE; + pic->backward_reference_picture = VA_INVALID_SURFACE; + + } else if (pic->picture_type == VAEncPictureTypePredictive) { + pic->f_code[0][0] = f_code_x; + pic->f_code[0][1] = f_code_y; + pic->f_code[1][0] = 0xf; + pic->f_code[1][1] = 0xf; + pic->forward_reference_picture = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->forward); + pic->backward_reference_picture = VA_INVALID_SURFACE; + } else if (pic->picture_type == VAEncPictureTypeBidirectional) { + pic->f_code[0][0] = f_code_x; + pic->f_code[0][1] = f_code_y; + pic->f_code[1][0] = f_code_x; + pic->f_code[1][1] = f_code_y; + pic->forward_reference_picture = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->forward);; + pic->backward_reference_picture = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->backward);; + } else { + g_assert (0); + } + + pic->picture_coding_extension.bits.intra_dc_precision = 0; /* 8bits */ + pic->picture_coding_extension.bits.picture_structure = 3; /* frame picture */ + pic->picture_coding_extension.bits.top_field_first = 0; + pic->picture_coding_extension.bits.frame_pred_frame_dct = 1; /* FIXME */ + pic->picture_coding_extension.bits.concealment_motion_vectors = 0; + pic->picture_coding_extension.bits.q_scale_type = 0; + pic->picture_coding_extension.bits.intra_vlc_format = 0; + pic->picture_coding_extension.bits.alternate_scan = 0; + pic->picture_coding_extension.bits.repeat_first_field = 0; + pic->picture_coding_extension.bits.progressive_frame = 1; + pic->picture_coding_extension.bits.composite_display_flag = 0; + + return TRUE; +} + +static gboolean +set_sequence_packed_header (GstVaapiEncoderMpeg2 * encoder, + GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) +{ + GstVaapiEncPackedHeader *packed_seq; + GstBitWriter writer; + VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; + VAEncSequenceParameterBufferMPEG2 *seq = sequence->param; + guint32 data_bit_size; + guint8 *data; + + gst_bit_writer_init (&writer, 128 * 8); + gst_bit_writer_write_sps (&writer, seq, encoder); + g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer); + data = GST_BIT_WRITER_DATA (&writer); + + packed_header_param_buffer.type = VAEncPackedHeaderSequence; + packed_header_param_buffer.bit_length = data_bit_size; + packed_header_param_buffer.has_emulation_bytes = 0; + + packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_header_param_buffer, sizeof (packed_header_param_buffer), + data, (data_bit_size + 7) / 8); + g_assert (packed_seq); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL); + gst_bit_writer_clear (&writer, TRUE); + + return TRUE; +} + +static gboolean +set_picture_packed_header (GstVaapiEncoderMpeg2 * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncPackedHeader *packed_pic; + GstBitWriter writer; + VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; + VAEncPictureParameterBufferMPEG2 *pic = picture->param; + guint32 data_bit_size; + guint8 *data; + + gst_bit_writer_init (&writer, 128 * 8); + gst_bit_writer_write_pps (&writer, pic); + g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer); + data = GST_BIT_WRITER_DATA (&writer); + + packed_header_param_buffer.type = VAEncPackedHeaderPicture; + packed_header_param_buffer.bit_length = data_bit_size; + packed_header_param_buffer.has_emulation_bytes = 0; + + packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_header_param_buffer, sizeof (packed_header_param_buffer), + data, (data_bit_size + 7) / 8); + g_assert (packed_pic); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_pic); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_pic, NULL); + gst_bit_writer_clear (&writer, TRUE); + + return TRUE; +} + +static gboolean +ensure_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncSequence *sequence; + + g_assert (picture); + sequence = GST_VAAPI_ENC_SEQUENCE_NEW (MPEG2, encoder); + g_assert (sequence); + if (!sequence) + goto error; + + if (!fill_sequence (encoder, sequence)) + goto error; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_I && + !set_sequence_packed_header (encoder, picture, sequence)) + goto error; + gst_vaapi_enc_picture_set_sequence (picture, sequence); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL); + return TRUE; + +error: + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL); + return FALSE; +} + +static gboolean +ensure_picture (GstVaapiEncoderMpeg2 * encoder, + GstVaapiEncPicture * picture, + GstVaapiCodedBufferProxy * buf_proxy, GstVaapiSurfaceProxy * surface) +{ + GstVaapiCodedBuffer *codedbuf = buf_proxy->buffer; + + if (!fill_picture (encoder, picture, codedbuf, surface)) + return FALSE; + + if (!set_picture_packed_header (encoder, picture)) { + GST_ERROR ("set picture packed header failed"); + return FALSE; + } + + return TRUE; +} + +static gboolean +set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncMiscParam *misc = NULL; + VAEncMiscParameterHRD *hrd; + VAEncMiscParameterRateControl *rate_control; + + /* add hrd */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); + g_assert (misc); + if (!misc) + return FALSE; + gst_vaapi_enc_picture_add_misc_buffer (picture, misc); + hrd = misc->impl; + if (encoder->bitrate > 0) { + hrd->initial_buffer_fullness = encoder->bitrate * 1024 * 4; + hrd->buffer_size = encoder->bitrate * 1024 * 8; + } else { + hrd->initial_buffer_fullness = 0; + hrd->buffer_size = 0; + } + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL); + + /* add ratecontrol */ + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) { + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); + g_assert (misc); + if (!misc) + return FALSE; + gst_vaapi_enc_picture_add_misc_buffer (picture, misc); + rate_control = misc->impl; + memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); + if (encoder->bitrate) + rate_control->bits_per_second = encoder->bitrate * 1024; + else + rate_control->bits_per_second = 0; + rate_control->target_percentage = 70; + rate_control->window_size = 500; + rate_control->initial_qp = encoder->cqp; + rate_control->min_qp = 0; + rate_control->basic_unit_size = 0; + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL); + } + + return TRUE; + +} + +static gboolean +fill_slices (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) +{ + VAEncSliceParameterBufferMPEG2 *slice_param; + GstVaapiEncSlice *slice; + guint width_in_mbs, height_in_mbs; + guint i_slice; + + g_assert (picture); + + width_in_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; + height_in_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; + + for (i_slice = 0; i_slice < height_in_mbs; ++i_slice) { + slice = GST_VAAPI_ENC_SLICE_NEW (MPEG2, encoder); + g_assert (slice && slice->param_id != VA_INVALID_ID); + slice_param = slice->param; + + memset (slice_param, 0, sizeof (VAEncSliceParameterBufferMPEG2)); + + slice_param->macroblock_address = i_slice * width_in_mbs; + slice_param->num_macroblocks = width_in_mbs; + slice_param->is_intra_slice = (picture->type == GST_VAAPI_PICTURE_TYPE_I); + slice_param->quantiser_scale_code = encoder->cqp / 2; + + gst_vaapi_enc_picture_add_slice (picture, slice); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & slice, NULL); + + } + + return TRUE; +} + +static gboolean +ensure_slices (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) +{ + g_assert (picture); + + if (!fill_slices (encoder, picture)) + return FALSE; + + return TRUE; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_mpeg2_encode (GstVaapiEncoder * base, + GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) +{ + GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2_CAST (base); + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR; + GstVaapiSurfaceProxy *reconstruct = NULL; + + reconstruct = gst_vaapi_encoder_create_surface (base); + + g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct)); + + if (!ensure_sequence (encoder, picture)) + goto error; + if (!ensure_picture (encoder, picture, codedbuf, reconstruct)) + goto error; + if (!set_misc_parameters (encoder, picture)) + goto error; + if (!ensure_slices (encoder, picture)) + goto error; + if (!gst_vaapi_enc_picture_encode (picture)) + goto error; + if (picture->type != GST_VAAPI_PICTURE_TYPE_B) { + if (encoder->new_gop) + clear_references (encoder); + push_reference (encoder, reconstruct); + } else if (reconstruct) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +error: + if (reconstruct) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); + return ret; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_mpeg2_flush (GstVaapiEncoder * base) +{ + GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2_CAST (base); + GstVaapiEncPicture *pic; + + while (!g_queue_is_empty (&encoder->b_frames)) { + pic = (GstVaapiEncPicture *) g_queue_pop_head (&encoder->b_frames); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&encoder->b_frames); + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base, + GstVideoCodecFrame * frame, gboolean flush, GstVaapiEncPicture ** output) +{ + GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); + GstVaapiEncPicture *picture = NULL; + GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS; + + + if (!frame) { + if (g_queue_is_empty (&encoder->b_frames) && encoder->dump_frames) { + push_reference (encoder, NULL); + encoder->dump_frames = FALSE; + } + if (!encoder->dump_frames) { + return GST_VAAPI_ENCODER_STATUS_FRAME_NOT_READY; + } + picture = g_queue_pop_head (&encoder->b_frames); + g_assert (picture); + goto end; + } + + picture = GST_VAAPI_ENC_PICTURE_NEW (MPEG2, encoder, frame); + if (!picture) { + GST_WARNING ("create MPEG2 picture failed, frame timestamp:%" + GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); + return GST_VAAPI_ENCODER_STATUS_OBJECT_ERR; + } + + if (encoder->frame_num >= encoder->intra_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); + encoder->new_gop = TRUE; + } else { + encoder->new_gop = FALSE; + if ((encoder->frame_num % (encoder->ip_period + 1)) == 0 || + encoder->frame_num == encoder->intra_period - 1) { + picture->type = GST_VAAPI_PICTURE_TYPE_P; + encoder->dump_frames = TRUE; + } else { + picture->type = GST_VAAPI_PICTURE_TYPE_B; + status = GST_VAAPI_ENCODER_STATUS_FRAME_NOT_READY; + } + + } + picture->frame_num = encoder->frame_num++; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + g_queue_push_tail (&encoder->b_frames, picture); + picture = NULL; + } + +end: + *output = picture; + return status; +} + +static GstVaapiProfile +to_vaapi_profile (guint32 profile) +{ + GstVaapiProfile p; + switch (profile) { + case GST_ENCODER_MPEG2_PROFILE_SIMPLE: + p = GST_VAAPI_PROFILE_MPEG2_SIMPLE; + break; + case GST_ENCODER_MPEG2_PROFILE_MAIN: + p = GST_VAAPI_PROFILE_MPEG2_MAIN; + break; + default: + g_assert (0); + } + return p; +} + +static gboolean +gst_vaapi_encoder_mpeg2_get_context_info (GstVaapiEncoder * base, + GstVaapiContextInfo * info) +{ + GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); + + g_return_val_if_fail (info, FALSE); + + info->profile = to_vaapi_profile (encoder->profile); + info->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + info->width = GST_VAAPI_ENCODER_WIDTH (encoder); + info->height = GST_VAAPI_ENCODER_HEIGHT (encoder); + info->ref_frames = 2; + info->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); + + return TRUE; +} + +static gboolean +prepare_encoding (GstVaapiEncoderMpeg2 * encoder, GstCaps * caps) +{ + return TRUE; +} + +static GstCaps * +gst_vaapi_encoder_mpeg2_set_format (GstVaapiEncoder * base, + GstVideoCodecState * in_state, GstCaps * ref_caps) +{ + GstVaapiEncoderMpeg2 *encoder; + GstCaps *result = NULL, *tmp; + encoder = GST_VAAPI_ENCODER_MPEG2 (base); + + tmp = gst_caps_from_string ("video/mpeg"); + gst_caps_set_simple (tmp, + "mpegversion", G_TYPE_INT, 2, + "systemstream", G_TYPE_BOOLEAN, FALSE, + "width", G_TYPE_INT, GST_VAAPI_ENCODER_WIDTH (encoder), + "height", G_TYPE_INT, GST_VAAPI_ENCODER_HEIGHT (encoder), + "framerate", GST_TYPE_FRACTION, + GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder), + NULL); + result = gst_caps_intersect (tmp, ref_caps); + gst_caps_unref (tmp); + + result = gst_caps_fixate (result); + + if (!ensure_public_attributes (encoder)) { + GST_WARNING ("encoder ensure public attributes failed "); + goto error; + } + + if (!prepare_encoding (encoder, result)) { + GST_WARNING ("prepare encoding failed "); + goto error; + } + + return result; + +error: + gst_caps_unref (result); + return NULL; + +} + +static gboolean +gst_vaapi_encoder_mpeg2_init (GstVaapiEncoder * base) +{ + GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); + + /* re-ordering */ + g_queue_init (&encoder->b_frames); + encoder->dump_frames = FALSE; + + encoder->forward = NULL; + encoder->backward = NULL; + + encoder->frame_num = 0; + + return TRUE; +} + +static void +clear_ref (GstVaapiEncoderMpeg2 * encoder, GstVaapiSurfaceProxy ** ref) +{ + if (*ref) { + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), *ref); + *ref = NULL; + } +} + +static void +clear_references (GstVaapiEncoderMpeg2 * encoder) +{ + clear_ref (encoder, &encoder->forward); + clear_ref (encoder, &encoder->backward); +} + +static void +push_reference (GstVaapiEncoderMpeg2 * encoder, GstVaapiSurfaceProxy * ref) +{ + if (encoder->backward) { + clear_ref (encoder, &encoder->forward); + encoder->forward = encoder->backward; + encoder->backward = NULL; + } + if (encoder->forward) + encoder->backward = ref; + else + encoder->forward = ref; +} + +static void +gst_vaapi_encoder_mpeg2_destroy (GstVaapiEncoder * base) +{ + /*free private buffers */ + GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); + GstVaapiEncPicture *pic; + + clear_references (encoder); + + while (!g_queue_is_empty (&encoder->b_frames)) { + pic = (GstVaapiEncPicture *) g_queue_pop_head (&encoder->b_frames); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&encoder->b_frames); +} + +static void +gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass) +{ + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass); + + gst_vaapi_encoder_class_init (encoder_class); + + object_class->size = sizeof (GstVaapiEncoderMpeg2); + + encoder_class->init = gst_vaapi_encoder_mpeg2_init; + encoder_class->destroy = gst_vaapi_encoder_mpeg2_destroy; + encoder_class->set_format = gst_vaapi_encoder_mpeg2_set_format; + encoder_class->get_context_info = gst_vaapi_encoder_mpeg2_get_context_info; + encoder_class->reordering = gst_vaapi_encoder_mpeg2_reordering; + encoder_class->encode = gst_vaapi_encoder_mpeg2_encode; + encoder_class->flush = gst_vaapi_encoder_mpeg2_flush; +} + +static inline const GstVaapiEncoderClass * +gst_vaapi_encoder_mpeg2_class () +{ + static GstVaapiEncoderMpeg2Class g_class; + static gsize g_class_init = FALSE; + + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_encoder_mpeg2_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_ENCODER_CLASS (&g_class); +} + +GstVaapiEncoder * +gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display) +{ + return gst_vaapi_encoder_new (gst_vaapi_encoder_mpeg2_class (), display); +} + +static struct +{ + int code; + float value; +} frame_rate_tab[] = { + { 1, 23.976 }, + { 2, 24.0 }, + { 3, 25.0 }, + { 4, 29.97 }, + { 5, 30 }, + { 6, 50 }, + { 7, 59.94 }, + { 8, 60 } +}; + +static int +find_frame_rate_code (const VAEncSequenceParameterBufferMPEG2 * seq_param) +{ + unsigned int delta = -1; + int code = 1, i; + float frame_rate_value = seq_param->frame_rate * + (seq_param->sequence_extension.bits.frame_rate_extension_d + 1) / + (seq_param->sequence_extension.bits.frame_rate_extension_n + 1); + + for (i = 0; i < sizeof (frame_rate_tab) / sizeof (frame_rate_tab[0]); i++) { + + if (abs (1000 * frame_rate_tab[i].value - 1000 * frame_rate_value) < delta) { + code = frame_rate_tab[i].code; + delta = abs (1000 * frame_rate_tab[i].value - 1000 * frame_rate_value); + } + } + return code; +} + +static gboolean +gst_bit_writer_write_sps (GstBitWriter * bitwriter, + VAEncSequenceParameterBufferMPEG2 * seq, GstVaapiEncoderMpeg2 * encoder) +{ + int frame_rate_code = find_frame_rate_code (seq); + + if (encoder->new_gop) { + gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_SEQ, 32); + gst_bit_writer_put_bits_uint32 (bitwriter, seq->picture_width, 12); + gst_bit_writer_put_bits_uint32 (bitwriter, seq->picture_height, 12); + gst_bit_writer_put_bits_uint32 (bitwriter, seq->aspect_ratio_information, + 4); + gst_bit_writer_put_bits_uint32 (bitwriter, frame_rate_code, 4); /* frame_rate_code */ + gst_bit_writer_put_bits_uint32 (bitwriter, (seq->bits_per_second + 399) / 400, 18); /* the low 18 bits of bit_rate */ + gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* marker_bit */ + gst_bit_writer_put_bits_uint32 (bitwriter, seq->vbv_buffer_size, 10); + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* constraint_parameter_flag, always 0 for MPEG-2 */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* load_intra_quantiser_matrix */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* load_non_intra_quantiser_matrix */ + + gst_bit_writer_align_bytes (bitwriter, 0); + + gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_EXT, 32); + gst_bit_writer_put_bits_uint32 (bitwriter, 1, 4); /* sequence_extension id */ + gst_bit_writer_put_bits_uint32 (bitwriter, + seq->sequence_extension.bits.profile_and_level_indication, 8); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq->sequence_extension.bits.progressive_sequence, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq->sequence_extension.bits.chroma_format, 2); + gst_bit_writer_put_bits_uint32 (bitwriter, seq->picture_width >> 12, 2); + gst_bit_writer_put_bits_uint32 (bitwriter, seq->picture_height >> 12, 2); + gst_bit_writer_put_bits_uint32 (bitwriter, ((seq->bits_per_second + 399) / 400) >> 18, 12); /* bit_rate_extension */ + gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* marker_bit */ + gst_bit_writer_put_bits_uint32 (bitwriter, seq->vbv_buffer_size >> 10, 8); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq->sequence_extension.bits.low_delay, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq->sequence_extension.bits.frame_rate_extension_n, 2); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq->sequence_extension.bits.frame_rate_extension_d, 5); + + gst_bit_writer_align_bytes (bitwriter, 0); + + /* gop header */ + gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_GOP, 32); + gst_bit_writer_put_bits_uint32 (bitwriter, seq->gop_header.bits.time_code, + 25); + gst_bit_writer_put_bits_uint32 (bitwriter, seq->gop_header.bits.closed_gop, + 1); + gst_bit_writer_put_bits_uint32 (bitwriter, seq->gop_header.bits.broken_link, + 1); + + gst_bit_writer_align_bytes (bitwriter, 0); + } + return TRUE; +} + +static gboolean +gst_bit_writer_write_pps (GstBitWriter * bitwriter, + VAEncPictureParameterBufferMPEG2 * pic) +{ + + gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_PICUTRE, 32); + gst_bit_writer_put_bits_uint32 (bitwriter, pic->temporal_reference, 10); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_type == VAEncPictureTypeIntra ? 1 : + pic->picture_type == VAEncPictureTypePredictive ? 2 : 3, 3); + gst_bit_writer_put_bits_uint32 (bitwriter, pic->vbv_delay, 16); + + if (pic->picture_type == VAEncPictureTypePredictive || + pic->picture_type == VAEncPictureTypeBidirectional) { + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* full_pel_forward_vector, always 0 for MPEG-2 */ + gst_bit_writer_put_bits_uint32 (bitwriter, 7, 3); /* forward_f_code, always 7 for MPEG-2 */ + } + + if (pic->picture_type == VAEncPictureTypeBidirectional) { + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* full_pel_backward_vector, always 0 for MPEG-2 */ + gst_bit_writer_put_bits_uint32 (bitwriter, 7, 3); /* backward_f_code, always 7 for MPEG-2 */ + } + + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* extra_bit_picture, 0 */ + + gst_bit_writer_align_bytes (bitwriter, 0); + + gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_EXT, 32); + gst_bit_writer_put_bits_uint32 (bitwriter, 8, 4); /* Picture Coding Extension ID: 8 */ + gst_bit_writer_put_bits_uint32 (bitwriter, pic->f_code[0][0], 4); + gst_bit_writer_put_bits_uint32 (bitwriter, pic->f_code[0][1], 4); + gst_bit_writer_put_bits_uint32 (bitwriter, pic->f_code[1][0], 4); + gst_bit_writer_put_bits_uint32 (bitwriter, pic->f_code[1][1], 4); + + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_coding_extension.bits.intra_dc_precision, 2); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_coding_extension.bits.picture_structure, 2); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_coding_extension.bits.top_field_first, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_coding_extension.bits.frame_pred_frame_dct, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_coding_extension.bits.concealment_motion_vectors, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_coding_extension.bits.q_scale_type, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_coding_extension.bits.intra_vlc_format, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_coding_extension.bits.alternate_scan, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_coding_extension.bits.repeat_first_field, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* always chroma 420 */ + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_coding_extension.bits.progressive_frame, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic->picture_coding_extension.bits.composite_display_flag, 1); + + gst_bit_writer_align_bytes (bitwriter, 0); + + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h new file mode 100644 index 0000000000..a880875133 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -0,0 +1,36 @@ +/* + * gstvaapiencoder_mpeg2.h - MPEG-2 encoder + * + * Copyright (C) 2011-2013 Intel Corporation + * + * 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 + +G_BEGIN_DECLS + +typedef struct _GstVaapiEncoderMpeg2 GstVaapiEncoderMpeg2; + +GstVaapiEncoder * +gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display); + +G_END_DECLS + +#endif /* GST_VAAPI_ENCODER_MPEG2_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h new file mode 100644 index 0000000000..c5da350e89 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h @@ -0,0 +1,116 @@ +/* + * gstvaapiencoder_mpeg2_priv.h - MPEG-2 encoder (private definitions) + * + * Copyright (C) 2013 Intel Corporation + * + * 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 +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_ENCODER_MPEG2(encoder) \ + ((GstVaapiEncoderMpeg2 *)(encoder)) +#define GST_VAAPI_ENCODER_MPEG2_CAST(encoder) \ + ((GstVaapiEncoderMpeg2 *)(encoder)) +#define GST_VAAPI_ENCODER_MPEG2_CLASS(klass) \ + ((GstVaapiEncoderMpeg2Class *)(klass)) +#define GST_IS_VAAPI_ENCODER_MPEG2_CLASS(klass) \ + ((klass) != NULL) +#define GST_VAAPI_ENCODER_MPEG2_GET_CLASS(obj) \ + GST_VAAPI_ENCODER_MPEG2_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + +typedef struct _GstVaapiEncoderMpeg2Class GstVaapiEncoderMpeg2Class; + +typedef enum +{ + GST_ENCODER_MPEG2_PROFILE_SIMPLE, + GST_ENCODER_MPEG2_PROFILE_MAIN, +} GstEncoderMpeg2Level; + +typedef enum +{ + GST_VAAPI_ENCODER_MPEG2_LEVEL_LOW, + GST_VAAPI_ENCODER_MPEG2_LEVEL_MAIN, + GST_VAAPI_ENCODER_MPEG2_LEVEL_HIGH +} GstVaapiEncoderMpeg2Level; + +#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE GST_ENCODER_MPEG2_PROFILE_MAIN +#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL GST_VAAPI_ENCODER_MPEG2_LEVEL_HIGH +#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_RATE_CONTROL GST_VAAPI_RATECONTROL_CQP + +#define GST_VAAPI_ENCODER_MPEG2_MIN_CQP 2 +#define GST_VAAPI_ENCODER_MPEG2_MAX_CQP 62 +#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP 8 + +#define GST_VAAPI_ENCODER_MPEG2_MAX_GOP_SIZE 512 +#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE 30 + +#define GST_VAAPI_ENCODER_MPEG2_MAX_MAX_BFRAMES 16 +#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES 2 + +#define GST_VAAPI_ENCODER_MPEG2_MAX_BITRATE 100*1024 + +#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 + +#define CHROMA_FORMAT_RESERVED 0 +#define CHROMA_FORMAT_420 1 +#define CHROMA_FORMAT_422 2 +#define CHROMA_FORMAT_444 3 + +struct _GstVaapiEncoderMpeg2 +{ + GstVaapiEncoder parent; + + /* public */ + guint32 profile; + guint32 level; + guint32 bitrate; /*kbps */ + guint32 cqp; + guint32 intra_period; + 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 */ +}; + +struct _GstVaapiEncoderMpeg2Class +{ + /*< private > */ + GstVaapiEncoderClass parent_class; +}; + +G_END_DECLS + +#endif /* GST_VAAPI_ENCODER_MPEG2_PRIV_H */ From 06ea8ba92b1151a1e603d965dc0e78361cc576c0 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Mon, 29 Jul 2013 13:44:48 +0800 Subject: [PATCH 1411/3781] plugins: add base encoder element. vaapiencode element is based on GstVideoEncoder APIs. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/Makefile.am | 13 + gst/vaapi/gstvaapiencode.c | 764 +++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode.h | 100 +++++ 3 files changed, 877 insertions(+) create mode 100644 gst/vaapi/gstvaapiencode.c create mode 100644 gst/vaapi/gstvaapiencode.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 99c2fac982..5c040ec4fb 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -56,6 +56,19 @@ libgstvaapi_source_h = \ gstvaapivideometa.h \ $(NULL) +libgstvaapi_enc_source_c = \ + gstvaapiencode.c \ + $(NULL) + +libgstvaapi_enc_source_h = \ + gstvaapiencode.h \ + $(NULL) + +if USE_ENCODERS +libgstvaapi_source_c += $(libgstvaapi_enc_source_c) +libgstvaapi_source_h += $(libgstvaapi_enc_source_h) +endif + libgstvaapi_x11_source_c = gstvaapivideoconverter_x11.c libgstvaapi_x11_source_h = gstvaapivideoconverter_x11.h diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c new file mode 100644 index 0000000000..b484db46cb --- /dev/null +++ b/gst/vaapi/gstvaapiencode.c @@ -0,0 +1,764 @@ +/* + * gstvaapiencode.c - VA-API video encoder + * + * Copyright (C) 2013 Intel Corporation + * + * 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 "gst/vaapi/sysdeps.h" +#include +#include +#include +#include +#include "gstvaapiencode.h" +#include "gstvaapipluginutil.h" +#include "gstvaapivideometa.h" +#include "gstvaapivideomemory.h" +#include "gstvaapivideobufferpool.h" + +#define GST_PLUGIN_NAME "vaapiencode" +#define GST_PLUGIN_DESC "A VA-API based video encoder" + +#define GST_VAAPI_ENCODE_FLOW_TIMEOUT GST_FLOW_CUSTOM_SUCCESS +#define GST_VAAPI_ENCODE_FLOW_MEM_ERROR GST_FLOW_CUSTOM_ERROR +#define GST_VAAPI_ENCODE_FLOW_CONVERT_ERROR GST_FLOW_CUSTOM_ERROR_1 +#define GST_VAAPI_ENCODE_FLOW_CODEC_DATA_ERROR GST_FLOW_CUSTOM_ERROR_2 + +typedef struct _GstVaapiEncodeFrameUserData +{ + GstVaapiEncObjUserDataHead head; + GstBuffer *vaapi_buf; +} GstVaapiEncodeFrameUserData; + +GST_DEBUG_CATEGORY_STATIC (gst_vaapiencode_debug); + +#define GST_CAT_DEFAULT gst_vaapiencode_debug + +#define GstVideoContextClass GstVideoContextInterface + +/* GstImplementsInterface interface */ +#if !GST_CHECK_VERSION(1,0,0) +static gboolean +gst_vaapiencode_implements_interface_supported (GstImplementsInterface * iface, + GType type) +{ + return (type == GST_TYPE_VIDEO_CONTEXT); +} + +static void +gst_vaapiencode_implements_iface_init (GstImplementsInterfaceClass * iface) +{ + iface->supported = gst_vaapiencode_implements_interface_supported; +} +#endif + +/* context(display) interface */ +static void +gst_vaapiencode_set_video_context (GstVideoContext * context, + const gchar * type, const GValue * value) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (context); + + gst_vaapi_set_display (type, value, &encode->display); +} + +static void +gst_video_context_interface_init (GstVideoContextInterface * iface) +{ + iface->set_context = gst_vaapiencode_set_video_context; +} + +G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode, + gst_vaapiencode, GST_TYPE_VIDEO_ENCODER, +#if !GST_CHECK_VERSION(1,0,0) + G_IMPLEMENT_INTERFACE (GST_TYPE_IMPLEMENTS_INTERFACE, + gst_vaapiencode_implements_iface_init); +#endif + G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_CONTEXT, + gst_video_context_interface_init)) + +static gboolean +gst_vaapiencode_query (GstPad * pad, GstObject * parent, + GstQuery * query) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (parent); + gboolean success; + + GST_DEBUG ("vaapiencode query %s", GST_QUERY_TYPE_NAME (query)); + + if (gst_vaapi_reply_to_query (query, encode->display)) + success = TRUE; + else if (GST_PAD_IS_SINK (pad)) + success = encode->sinkpad_query (pad, parent, query); + else + success = encode->srcpad_query (pad, parent, query);; + return success; +} + +static GstFlowReturn +gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode, + GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr) +{ + GstBuffer *buf; + gint32 buf_size; + + g_return_val_if_fail (coded_buf != NULL, GST_FLOW_ERROR); + g_return_val_if_fail (outbuf_ptr != NULL, GST_FLOW_ERROR); + + if (!gst_vaapi_coded_buffer_map (coded_buf, NULL)) + return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; + + buf_size = gst_vaapi_coded_buffer_get_size (coded_buf); + if (buf_size <= 0) { + GST_ERROR ("get GstVaapiCodedBuf buffer size:%d", buf_size); + return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; + } + + buf = + gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER_CAST (encode), + buf_size); + if (!buf) { + GST_ERROR ("failed to allocate output buffer of size %d", buf_size); + return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; + } + + if (!gst_vaapi_coded_buffer_get_buffer (coded_buf, buf)) { + GST_ERROR ("failed to get encoded buffer"); + gst_buffer_replace (&buf, NULL); + return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; + } + gst_vaapi_coded_buffer_unmap (coded_buf); + *outbuf_ptr = buf; + return GST_FLOW_OK; +} + +static GstFlowReturn +gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 ms_timeout) +{ + GstVideoEncoder *const venc = GST_VIDEO_ENCODER_CAST (encode); + GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode); + GstVideoCodecFrame *out_frame = NULL; + GstVaapiCodedBufferProxy *coded_buf_proxy = NULL; + GstVaapiCodedBuffer *coded_buf; + GstVaapiEncoderStatus encode_status; + GstBuffer *output_buf; + GstFlowReturn ret; + + g_return_val_if_fail (klass->allocate_buffer, GST_FLOW_ERROR); + + encode_status = gst_vaapi_encoder_get_buffer (encode->encoder, + &out_frame, &coded_buf_proxy, ms_timeout); + if (encode_status == GST_VAAPI_ENCODER_STATUS_TIMEOUT) + return GST_VAAPI_ENCODE_FLOW_TIMEOUT; + + if (encode_status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + GST_ERROR ("get encoded buffer failed, status:%d", encode_status); + ret = GST_FLOW_ERROR; + goto error; + } + + g_assert (out_frame); + gst_video_codec_frame_set_user_data (out_frame, NULL, NULL); + + coded_buf = coded_buf_proxy->buffer; + g_assert (coded_buf); + + /* alloc buffer */ + ret = klass->allocate_buffer (encode, coded_buf, &output_buf); + if (ret != GST_FLOW_OK) + goto error; + + out_frame->output_buffer = output_buf; + + gst_vaapi_coded_buffer_proxy_replace (&coded_buf_proxy, NULL); + + /* check out_caps, need lock first */ + GST_VIDEO_ENCODER_STREAM_LOCK (encode); + if (!encode->out_caps_done) { + GstVaapiEncoderStatus encoder_status; + GstVideoCodecState *old_state, *new_state; + GstBuffer *codec_data; + + encoder_status = + gst_vaapi_encoder_get_codec_data (encode->encoder, &codec_data); + if (encoder_status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + ret = GST_VAAPI_ENCODE_FLOW_CODEC_DATA_ERROR; + goto error_unlock; + } + if (codec_data) { + encode->srcpad_caps = gst_caps_make_writable (encode->srcpad_caps); + gst_caps_set_simple (encode->srcpad_caps, + "codec_data", GST_TYPE_BUFFER, codec_data, NULL); + gst_buffer_replace (&codec_data, NULL); + old_state = + gst_video_encoder_get_output_state (GST_VIDEO_ENCODER_CAST (encode)); + new_state = + gst_video_encoder_set_output_state (GST_VIDEO_ENCODER_CAST (encode), + gst_caps_ref (encode->srcpad_caps), old_state); + gst_video_codec_state_unref (old_state); + gst_video_codec_state_unref (new_state); + if (!gst_video_encoder_negotiate (GST_VIDEO_ENCODER_CAST (encode))) { + GST_ERROR ("failed to negotiate with caps %" GST_PTR_FORMAT, + encode->srcpad_caps); + ret = GST_FLOW_NOT_NEGOTIATED; + goto error_unlock; + } + GST_DEBUG ("updated srcpad caps to: %" GST_PTR_FORMAT, + encode->srcpad_caps); + } + encode->out_caps_done = TRUE; + } + GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); + + GST_DEBUG ("output:%" GST_TIME_FORMAT ", size:%d", + GST_TIME_ARGS (out_frame->pts), gst_buffer_get_size (output_buf)); + + ret = gst_video_encoder_finish_frame (venc, out_frame); + out_frame = NULL; + if (ret != GST_FLOW_OK) + goto error; + + return GST_FLOW_OK; + +error_unlock: + GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); +error: + gst_vaapi_coded_buffer_proxy_replace (&coded_buf_proxy, NULL); + if (out_frame) + gst_video_codec_frame_unref (out_frame); + + return ret; +} + +static void +gst_vaapiencode_buffer_loop (GstVaapiEncode * encode) +{ + GstFlowReturn ret; + const gint64 timeout = 50000; /* microseconds */ + + ret = gst_vaapiencode_push_frame (encode, timeout); + if (ret == GST_FLOW_OK || ret == GST_VAAPI_ENCODE_FLOW_TIMEOUT) + return; + + gst_pad_pause_task (encode->srcpad); +} + +static GstCaps * +gst_vaapiencode_get_caps (GstPad * pad) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (GST_OBJECT_PARENT (pad)); + GstCaps *caps; + + if (encode->sinkpad_caps) + caps = gst_caps_ref (encode->sinkpad_caps); + else + caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); + return caps; +} + +static gboolean +gst_vaapiencode_destroy (GstVaapiEncode * encode) +{ + gst_vaapi_encoder_replace (&encode->encoder, NULL); + g_clear_object (&encode->video_buffer_pool); + + if (encode->sinkpad_caps) { + gst_caps_unref (encode->sinkpad_caps); + encode->sinkpad_caps = NULL; + } + + if (encode->srcpad_caps) { + gst_caps_unref (encode->srcpad_caps); + encode->srcpad_caps = NULL; + } + + gst_vaapi_display_replace (&encode->display, NULL); + return TRUE; +} + +static inline gboolean +ensure_display (GstVaapiEncode * encode) +{ + return gst_vaapi_ensure_display (encode, + GST_VAAPI_DISPLAY_TYPE_ANY, &encode->display); +} + +static gboolean +ensure_encoder (GstVaapiEncode * encode) +{ + GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode); + + g_return_val_if_fail (klass->create_encoder, FALSE); + + if (!ensure_display (encode)) + return FALSE; + + encode->encoder = klass->create_encoder (encode, encode->display); + g_assert (encode->encoder); + return (encode->encoder ? TRUE : FALSE); +} + +static gboolean +gst_vaapiencode_open (GstVideoEncoder * venc) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + GstVaapiDisplay *const old_display = encode->display; + gboolean success; + + encode->display = NULL; + success = ensure_display (encode); + if (old_display) + gst_vaapi_display_unref (old_display); + + GST_DEBUG ("ensure display %s, display:%p", + (success ? "okay" : "failed"), encode->display); + return success; +} + +static gboolean +gst_vaapiencode_close (GstVideoEncoder * venc) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + + GST_DEBUG ("vaapiencode starting close"); + + return gst_vaapiencode_destroy (encode); +} + +static inline gboolean +gst_vaapiencode_update_sink_caps (GstVaapiEncode * encode, + GstVideoCodecState * state) +{ + gst_caps_replace (&encode->sinkpad_caps, state->caps); + encode->sink_video_info = state->info; + return TRUE; +} + +static gboolean +gst_vaapiencode_update_src_caps (GstVaapiEncode * encode, + GstVideoCodecState * in_state) +{ + GstVideoCodecState *out_state; + GstStructure *structure; + GstCaps *outcaps, *allowed_caps, *template_caps, *intersect; + GstVaapiEncoderStatus encoder_status; + GstBuffer *codec_data = NULL; + + g_return_val_if_fail (encode->encoder, FALSE); + + encode->out_caps_done = FALSE; + + /* get peer caps for stream-format avc/bytestream, codec_data */ + template_caps = gst_pad_get_pad_template_caps (encode->srcpad); + allowed_caps = gst_pad_get_allowed_caps (encode->srcpad); + intersect = gst_caps_intersect (template_caps, allowed_caps); + gst_caps_unref (template_caps); + gst_caps_unref (allowed_caps); + + /* codec data was not set */ + outcaps = gst_vaapi_encoder_set_format (encode->encoder, in_state, intersect); + gst_caps_unref (intersect); + g_return_val_if_fail (outcaps, FALSE); + + if (!gst_caps_is_fixed (outcaps)) { + GST_ERROR ("encoder output caps was not fixed"); + gst_caps_unref (outcaps); + return FALSE; + } + structure = gst_caps_get_structure (outcaps, 0); + if (!gst_structure_has_field (structure, "codec_data")) { + encoder_status = + gst_vaapi_encoder_get_codec_data (encode->encoder, &codec_data); + if (encoder_status == GST_VAAPI_ENCODER_STATUS_SUCCESS) { + if (codec_data) { + outcaps = gst_caps_make_writable (outcaps); + gst_caps_set_simple (outcaps, + "codec_data", GST_TYPE_BUFFER, codec_data, NULL); + gst_buffer_replace (&codec_data, NULL); + } + encode->out_caps_done = TRUE; + } + } else + encode->out_caps_done = TRUE; + + out_state = + gst_video_encoder_set_output_state (GST_VIDEO_ENCODER_CAST (encode), + outcaps, in_state); + + gst_caps_replace (&encode->srcpad_caps, out_state->caps); + gst_video_codec_state_unref (out_state); + + GST_DEBUG ("set srcpad caps to: %" GST_PTR_FORMAT, encode->srcpad_caps); + return TRUE; +} + +static gboolean +gst_vaapiencode_ensure_video_buffer_pool (GstVaapiEncode * encode, + GstCaps * caps) +{ + GstBufferPool *pool; + GstCaps *pool_caps; + GstStructure *config; + GstVideoInfo vi; + gboolean need_pool; + + if (!ensure_display (encode)) + return FALSE; + + if (encode->video_buffer_pool) { + config = gst_buffer_pool_get_config (encode->video_buffer_pool); + gst_buffer_pool_config_get_params (config, &pool_caps, NULL, NULL, NULL); + need_pool = !gst_caps_is_equal (caps, pool_caps); + gst_structure_free (config); + if (!need_pool) + return TRUE; + g_clear_object (&encode->video_buffer_pool); + encode->video_buffer_size = 0; + } + + pool = gst_vaapi_video_buffer_pool_new (encode->display); + if (!pool) + goto error_create_pool; + + gst_video_info_init (&vi); + gst_video_info_from_caps (&vi, caps); + if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) { + GST_DEBUG ("assume video buffer pool format is NV12"); + gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); + } + encode->video_buffer_size = vi.size; + + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set_params (config, caps, encode->video_buffer_size, + 0, 0); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); + gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); + if (!gst_buffer_pool_set_config (pool, config)) + goto error_pool_config; + encode->video_buffer_pool = pool; + return TRUE; + + /* ERRORS */ +error_create_pool: + { + GST_ERROR ("failed to create buffer pool"); + return FALSE; + } +error_pool_config: + { + GST_ERROR ("failed to reset buffer pool config"); + gst_object_unref (pool); + return FALSE; + } +} + +static gboolean +gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + + g_return_val_if_fail (state->caps != NULL, FALSE); + + if (!gst_vaapiencode_ensure_video_buffer_pool (encode, state->caps)) + return FALSE; + + if (!ensure_encoder (encode)) + return FALSE; + if (!gst_vaapiencode_update_sink_caps (encode, state)) + return FALSE; + if (!gst_vaapiencode_update_src_caps (encode, state)) + return FALSE; + + if (encode->out_caps_done && !gst_video_encoder_negotiate (venc)) { + GST_ERROR ("failed to negotiate with caps %" GST_PTR_FORMAT, + encode->srcpad_caps); + return FALSE; + } + + return gst_pad_start_task (encode->srcpad, + (GstTaskFunction) gst_vaapiencode_buffer_loop, encode, NULL); + return TRUE; +} + +static gboolean +gst_vaapiencode_reset (GstVideoEncoder * venc, gboolean hard) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + + GST_DEBUG ("vaapiencode starting reset"); + + /* FIXME: compare sink_caps with encoder */ + encode->is_running = FALSE; + encode->out_caps_done = FALSE; + return TRUE; +} + +static GstFlowReturn +gst_vaapiencode_get_vaapi_buffer (GstVaapiEncode * encode, + GstBuffer * src_buffer, GstBuffer ** out_buffer_ptr) +{ + GstVaapiVideoMeta *meta; + GstBuffer *out_buffer; + GstVideoFrame src_frame, out_frame; + GstFlowReturn ret; + + *out_buffer_ptr = NULL; + meta = gst_buffer_get_vaapi_video_meta (src_buffer); + if (meta) { + *out_buffer_ptr = gst_buffer_ref (src_buffer); + return GST_FLOW_OK; + } + + if (!GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) { + GST_ERROR ("unsupported video buffer"); + return GST_FLOW_EOS; + } + + GST_DEBUG ("buffer %p not from our pool, copying", src_buffer); + + if (!encode->video_buffer_pool) + goto error_no_pool; + + if (!gst_buffer_pool_set_active (encode->video_buffer_pool, TRUE)) + goto error_activate_pool; + + ret = gst_buffer_pool_acquire_buffer (encode->video_buffer_pool, + &out_buffer, NULL); + if (ret != GST_FLOW_OK) + goto error_create_buffer; + + if (!gst_video_frame_map (&src_frame, &encode->sink_video_info, src_buffer, + GST_MAP_READ)) + goto error_map_src_buffer; + + if (!gst_video_frame_map (&out_frame, &encode->sink_video_info, out_buffer, + GST_MAP_WRITE)) + goto error_map_dst_buffer; + + gst_video_frame_copy (&out_frame, &src_frame); + gst_video_frame_unmap (&out_frame); + gst_video_frame_unmap (&src_frame); + + *out_buffer_ptr = out_buffer; + return GST_FLOW_OK; + + /* ERRORS */ +error_no_pool: + GST_ERROR ("no buffer pool was negotiated"); + return GST_FLOW_ERROR; +error_activate_pool: + GST_ERROR ("failed to activate buffer pool"); + return GST_FLOW_ERROR; +error_create_buffer: + GST_WARNING ("failed to create image. Skipping this frame"); + return GST_FLOW_OK; +error_map_dst_buffer: + gst_video_frame_unmap (&src_frame); + // fall-through +error_map_src_buffer: + GST_WARNING ("failed to map buffer. Skipping this frame"); + gst_buffer_unref (out_buffer); + return GST_FLOW_OK; +} + +static inline gpointer +_create_user_data (GstBuffer * buf) +{ + GstVaapiVideoMeta *meta; + GstVaapiSurface *surface; + GstVaapiEncodeFrameUserData *user_data; + + meta = gst_buffer_get_vaapi_video_meta (buf); + if (!meta) { + GST_DEBUG ("convert to vaapi buffer failed"); + return NULL; + } + surface = gst_vaapi_video_meta_get_surface (meta); + if (!surface) { + GST_DEBUG ("vaapi_meta of codec frame doesn't have vaapisurfaceproxy"); + return NULL; + } + + user_data = g_slice_new0 (GstVaapiEncodeFrameUserData); + user_data->head.surface = surface; + user_data->vaapi_buf = gst_buffer_ref (buf); + return user_data; +} + +static void +_destroy_user_data (gpointer data) +{ + GstVaapiEncodeFrameUserData *user_data = (GstVaapiEncodeFrameUserData *) data; + + g_assert (data); + if (!user_data) + return; + gst_buffer_replace (&user_data->vaapi_buf, NULL); + g_slice_free (GstVaapiEncodeFrameUserData, user_data); +} + +static GstFlowReturn +gst_vaapiencode_handle_frame (GstVideoEncoder * venc, + GstVideoCodecFrame * frame) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + GstFlowReturn ret = GST_FLOW_OK; + GstVaapiEncoderStatus encoder_ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; + GstBuffer *vaapi_buf = NULL; + gpointer user_data; + + g_assert (encode && encode->encoder); + g_assert (frame && frame->input_buffer); + + ret = + gst_vaapiencode_get_vaapi_buffer (encode, frame->input_buffer, + &vaapi_buf); + GST_VAAPI_ENCODER_CHECK_STATUS (ret == GST_FLOW_OK, ret, + "convert to vaapi buffer failed"); + + user_data = _create_user_data (vaapi_buf); + GST_VAAPI_ENCODER_CHECK_STATUS (user_data, + ret, "create frame user data failed"); + + gst_video_codec_frame_set_user_data (frame, user_data, _destroy_user_data); + + GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); + /*encoding frames */ + encoder_ret = gst_vaapi_encoder_put_frame (encode->encoder, frame); + GST_VIDEO_ENCODER_STREAM_LOCK (encode); + + GST_VAAPI_ENCODER_CHECK_STATUS (GST_VAAPI_ENCODER_STATUS_SUCCESS <= + encoder_ret, GST_FLOW_ERROR, "gst_vaapiencoder_encode failed."); + +end: + gst_video_codec_frame_unref (frame); + gst_buffer_replace (&vaapi_buf, NULL); + return ret; +} + +static GstFlowReturn +gst_vaapiencode_finish (GstVideoEncoder * venc) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + GstVaapiEncoderStatus status; + GstFlowReturn ret = GST_FLOW_OK; + + GST_DEBUG ("vaapiencode starting finish"); + + status = gst_vaapi_encoder_flush (encode->encoder); + + GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); + gst_pad_stop_task (encode->srcpad); + GST_VIDEO_ENCODER_STREAM_LOCK (encode); + + while (status == GST_VAAPI_ENCODER_STATUS_SUCCESS && ret == GST_FLOW_OK) + ret = gst_vaapiencode_push_frame (encode, 0); + + if (ret == GST_VAAPI_ENCODE_FLOW_TIMEOUT); + ret = GST_FLOW_OK; + return ret; +} + +static gboolean +gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + GstCaps *caps = NULL; + gboolean need_pool; + + gst_query_parse_allocation (query, &caps, &need_pool); + + if (need_pool) { + if (!caps) + goto error_no_caps; + if (!gst_vaapiencode_ensure_video_buffer_pool (encode, caps)) + return FALSE; + gst_query_add_allocation_pool (query, encode->video_buffer_pool, + encode->video_buffer_size, 0, 0); + } + + gst_query_add_allocation_meta (query, GST_VAAPI_VIDEO_META_API_TYPE, NULL); + gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); + return TRUE; + + /* ERRORS */ +error_no_caps: + { + GST_ERROR ("no caps specified"); + return FALSE; + } +} + +static void +gst_vaapiencode_finalize (GObject * object) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (object); + + gst_vaapiencode_destroy (encode); + + encode->sinkpad = NULL; + encode->srcpad = NULL; + + G_OBJECT_CLASS (gst_vaapiencode_parent_class)->finalize (object); +} + +static void +gst_vaapiencode_init (GstVaapiEncode * encode) +{ + /* sink pad */ + encode->sinkpad = GST_VIDEO_ENCODER_SINK_PAD (encode); + encode->sinkpad_query = GST_PAD_QUERYFUNC (encode->sinkpad); + gst_pad_set_query_function (encode->sinkpad, gst_vaapiencode_query); + gst_video_info_init (&encode->sink_video_info); + + /* src pad */ + encode->srcpad = GST_VIDEO_ENCODER_SRC_PAD (encode); + encode->srcpad_query = GST_PAD_QUERYFUNC (encode->srcpad); + gst_pad_set_query_function (encode->srcpad, gst_vaapiencode_query); + + gst_pad_use_fixed_caps (encode->srcpad); +} + +static void +gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstVideoEncoderClass *const venc_class = GST_VIDEO_ENCODER_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_vaapiencode_debug, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + object_class->finalize = gst_vaapiencode_finalize; + + venc_class->open = GST_DEBUG_FUNCPTR (gst_vaapiencode_open); + venc_class->close = GST_DEBUG_FUNCPTR (gst_vaapiencode_close); + venc_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_format); + venc_class->reset = GST_DEBUG_FUNCPTR (gst_vaapiencode_reset); + venc_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapiencode_handle_frame); + venc_class->finish = GST_DEBUG_FUNCPTR (gst_vaapiencode_finish); + + venc_class->propose_allocation = + GST_DEBUG_FUNCPTR (gst_vaapiencode_propose_allocation); + + klass->allocate_buffer = gst_vaapiencode_default_allocate_buffer; + + /* Registering debug symbols for function pointers */ + GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_get_caps); + GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_query); +} diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h new file mode 100644 index 0000000000..87e1a8e1ab --- /dev/null +++ b/gst/vaapi/gstvaapiencode.h @@ -0,0 +1,100 @@ +/* + * gstvaapiencode.h - VA-API video encoder + * + * Copyright (C) 2013 Intel Corporation + * + * 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_VAAPIENCODE_H +#define GST_VAAPIENCODE_H + +#include +#include +#include +#include "gst/vaapi/gstvaapiencoder_objects.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIENCODE \ + (gst_vaapiencode_get_type ()) + +#define GST_IS_VAAPIENCODE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE)) + +#define GST_IS_VAAPIENCODE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE)) + +#define GST_VAAPIENCODE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GST_TYPE_VAAPIENCODE, \ + GstVaapiEncodeClass)) + +#define GST_VAAPIENCODE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GST_TYPE_VAAPIENCODE, \ + GstVaapiEncode)) + +#define GST_VAAPIENCODE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + GST_TYPE_VAAPIENCODE, \ + GstVaapiEncodeClass)) + +typedef struct _GstVaapiEncode GstVaapiEncode; +typedef struct _GstVaapiEncodeClass GstVaapiEncodeClass; + +struct _GstVaapiEncode +{ + /*< private > */ + GstVideoEncoder parent_instance; + + GstPad *sinkpad; + GstCaps *sinkpad_caps; + GstPadQueryFunction sinkpad_query; + GstVideoInfo sink_video_info; + + GstPad *srcpad; + GstCaps *srcpad_caps; + GstPadQueryFunction srcpad_query; + + GstVaapiDisplay *display; + GstVaapiEncoder *encoder; + + GstBufferPool *video_buffer_pool; + guint video_buffer_size; + + guint32 is_running:1; + guint32 out_caps_done:1; +}; + +struct _GstVaapiEncodeClass +{ + /*< private > */ + GstVideoEncoderClass parent_class; + + GstVaapiEncoder * (*create_encoder) (GstVaapiEncode * encode, + GstVaapiDisplay * display); + GstFlowReturn (*allocate_buffer) (GstVaapiEncode * encode, + GstVaapiCodedBuffer * coded_buf, + GstBuffer ** outbuf_ptr); +}; + +GType +gst_vaapiencode_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GST_VAAPIENCODE_H */ From f1c33feef98cc98edf780dcbecb7ebb13f7b2aca Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Mon, 29 Jul 2013 16:02:56 +0800 Subject: [PATCH 1412/3781] plugins: add h264 encoder element. Add GstVaapiEncodeH264 element object. The actual plug-in element is called "vaapiencode_h264". Valid properties: - rate-control: rate control mode (default: none) - bitrate: desired bitrate in kbps (default: auto-calculated) - key-period: maximal distance between two key frames (default: 30) - num-slices: number of slices per frame (default: 1) - max-bframes: number of B-frames between I and P (default: 0) - min-qp: minimal quantizer (default: 1) - init-qp: initial quantizer (default: 26) Signed-off-by: Gwenole Beauchesne --- gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapi.c | 10 + gst/vaapi/gstvaapiencode_h264.c | 378 ++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode_h264.h | 80 +++++++ 4 files changed, 470 insertions(+) create mode 100644 gst/vaapi/gstvaapiencode_h264.c create mode 100644 gst/vaapi/gstvaapiencode_h264.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 5c040ec4fb..15e8cb83f9 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -58,10 +58,12 @@ libgstvaapi_source_h = \ libgstvaapi_enc_source_c = \ gstvaapiencode.c \ + gstvaapiencode_h264.c \ $(NULL) libgstvaapi_enc_source_h = \ gstvaapiencode.h \ + gstvaapiencode_h264.h \ $(NULL) if USE_ENCODERS diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 49c322ec5a..07e98b6dbd 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -30,6 +30,10 @@ #include "gstvaapipostproc.h" #include "gstvaapisink.h" +#if USE_ENCODERS +#include "gstvaapiencode_h264.h" +#endif + #define PLUGIN_NAME "vaapi" #define PLUGIN_DESC "VA-API based elements" #define PLUGIN_LICENSE "LGPL" @@ -54,6 +58,12 @@ plugin_init (GstPlugin *plugin) gst_element_register(plugin, "vaapisink", GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); +#if USE_ENCODERS + gst_element_register(plugin, "vaapiencode_h264", + GST_RANK_PRIMARY, + GST_TYPE_VAAPIENCODE_H264); +#endif + return TRUE; } diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c new file mode 100644 index 0000000000..35f14ca6f3 --- /dev/null +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -0,0 +1,378 @@ +/* + * gstvaapiencode_h264.c - VA-API H.264 encoder + * + * Copyright (C) 2012-2013 Intel Corporation + * + * 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 "gst/vaapi/sysdeps.h" +#include "gst/vaapi/gstvaapicompat.h" + +#include "gstvaapiencode_h264.h" +#include "gstvaapipluginutil.h" +#include "gst/vaapi/gstvaapiencoder_h264.h" +#include "gst/vaapi/gstvaapiencoder_h264_priv.h" +#include "gst/vaapi/gstvaapidisplay.h" +#include "gst/vaapi/gstvaapivalue.h" +#include "gst/vaapi/gstvaapisurface.h" + +#include + +GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); +#define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug + +#define GST_CAPS_CODEC(CODEC) CODEC "; " + +static const char gst_vaapiencode_h264_sink_caps_str[] = + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE "; " + GST_VAAPI_SURFACE_CAPS ", " + GST_CAPS_INTERLACED_FALSE; + +static const char gst_vaapiencode_h264_src_caps_str[] = + GST_CAPS_CODEC ("video/x-h264"); + +static GstStaticPadTemplate gst_vaapiencode_h264_sink_factory = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_h264_sink_caps_str)); + +static GstStaticPadTemplate gst_vaapiencode_h264_src_factory = + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_h264_src_caps_str)); + +/* h264 encode */ +G_DEFINE_TYPE (GstVaapiEncodeH264, gst_vaapiencode_h264, GST_TYPE_VAAPIENCODE) + +enum +{ + H264_PROP_0, + H264_PROP_RATE_CONTROL, + H264_PROP_BITRATE, + H264_PROP_KEY_PERIOD, + H264_PROP_MAX_BFRAMES, + H264_PROP_INIT_QP, + H264_PROP_MIN_QP, + H264_PROP_NUM_SLICES, +}; + +static void +gst_vaapiencode_h264_init (GstVaapiEncodeH264 * encode) +{ +} + +static void +gst_vaapiencode_h264_finalize (GObject * object) +{ + G_OBJECT_CLASS (gst_vaapiencode_h264_parent_class)->finalize (object); +} + +static void +gst_vaapiencode_h264_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264 (object); + + switch (prop_id) { + case H264_PROP_RATE_CONTROL: + encode->rate_control = g_value_get_enum (value); + break; + case H264_PROP_BITRATE: + encode->bitrate = g_value_get_uint (value); + break; + case H264_PROP_KEY_PERIOD: + encode->intra_period = g_value_get_uint (value); + break; + case H264_PROP_INIT_QP: + encode->init_qp = g_value_get_uint (value); + break; + case H264_PROP_MIN_QP: + encode->min_qp = g_value_get_uint (value); + break; + case H264_PROP_NUM_SLICES: + encode->num_slices = g_value_get_uint (value); + break; + case H264_PROP_MAX_BFRAMES: + encode->max_bframes = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapiencode_h264_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264 (object); + + switch (prop_id) { + case H264_PROP_RATE_CONTROL: + g_value_set_enum (value, encode->rate_control); + break; + case H264_PROP_BITRATE: + g_value_set_uint (value, encode->bitrate); + break; + case H264_PROP_KEY_PERIOD: + g_value_set_uint (value, encode->intra_period); + break; + case H264_PROP_INIT_QP: + g_value_set_uint (value, encode->init_qp); + break; + case H264_PROP_MIN_QP: + g_value_set_uint (value, encode->min_qp); + break; + case H264_PROP_NUM_SLICES: + g_value_set_uint (value, encode->num_slices); + break; + case H264_PROP_MAX_BFRAMES: + g_value_set_uint (value, encode->max_bframes); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstVaapiEncoder * +gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base, + GstVaapiDisplay * display) +{ + GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264 (base); + GstVaapiEncoder *ret; + GstVaapiEncoderH264 *h264encoder; + + ret = gst_vaapi_encoder_h264_new (display); + h264encoder = GST_VAAPI_ENCODER_H264 (ret); + + h264encoder->profile = GST_VAAPI_PROFILE_UNKNOWN; + h264encoder->level = GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL; + GST_VAAPI_ENCODER_RATE_CONTROL (h264encoder) = encode->rate_control; + h264encoder->bitrate = encode->bitrate; + h264encoder->intra_period = encode->intra_period; + h264encoder->init_qp = encode->init_qp; + h264encoder->min_qp = encode->min_qp; + h264encoder->slice_num = encode->num_slices; + h264encoder->b_frame_num = encode->max_bframes; + return ret; +} + +/* h264 NAL byte stream operations */ +static guint8 * +_h264_byte_stream_next_nal (guint8 * buffer, guint32 len, guint32 * nal_size) +{ + const guint8 *cur = buffer; + const guint8 *end = buffer + len; + guint8 *nal_start = NULL; + guint32 flag = 0xFFFFFFFF; + guint32 nal_start_len = 0; + + g_assert (len >= 0 && buffer && nal_size); + if (len < 3) { + *nal_size = len; + nal_start = (len ? buffer : NULL); + return nal_start; + } + + /*locate head postion */ + if (!buffer[0] && !buffer[1]) { + if (buffer[2] == 1) { /* 0x000001 */ + nal_start_len = 3; + } else if (!buffer[2] && len >= 4 && buffer[3] == 1) { /* 0x00000001 */ + nal_start_len = 4; + } + } + nal_start = buffer + nal_start_len; + cur = nal_start; + + /*find next nal start position */ + while (cur < end) { + flag = ((flag << 8) | ((*cur++) & 0xFF)); + if ((flag & 0x00FFFFFF) == 0x00000001) { + if (flag == 0x00000001) + *nal_size = cur - 4 - nal_start; + else + *nal_size = cur - 3 - nal_start; + break; + } + } + if (cur >= end) { + *nal_size = end - nal_start; + if (nal_start >= end) { + nal_start = NULL; + } + } + return nal_start; +} + +static inline void +_start_code_to_size (guint8 nal_start_code[4], guint32 nal_size) +{ + nal_start_code[0] = ((nal_size >> 24) & 0xFF); + nal_start_code[1] = ((nal_size >> 16) & 0xFF); + nal_start_code[2] = ((nal_size >> 8) & 0xFF); + nal_start_code[3] = (nal_size & 0xFF); +} + +static gboolean +_h264_convert_byte_stream_to_avc (GstBuffer * buf) +{ + GstMapInfo info; + guint32 nal_size; + guint8 *nal_start_code, *nal_body; + guint8 *frame_end; + + g_assert (buf); + + if (!gst_buffer_map (buf, &info, GST_MAP_READ | GST_MAP_WRITE)) + return FALSE; + + nal_start_code = info.data; + frame_end = info.data + info.size; + nal_size = 0; + + while ((frame_end > nal_start_code) && + (nal_body = _h264_byte_stream_next_nal (nal_start_code, + frame_end - nal_start_code, &nal_size)) != NULL) { + if (!nal_size) + goto error; + + g_assert (nal_body - nal_start_code == 4); + _start_code_to_size (nal_start_code, nal_size); + nal_start_code = nal_body + nal_size; + } + gst_buffer_unmap (buf, &info); + return TRUE; + +error: + gst_buffer_unmap (buf, &info); + return FALSE; +} + +static GstFlowReturn +gst_vaapiencode_h264_alloc_buffer (GstVaapiEncode * encode, + GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buf) +{ + GstFlowReturn ret; + GstVaapiEncoderH264 *h264encoder; + + g_return_val_if_fail (encode->encoder, GST_FLOW_ERROR); + + ret = + GST_VAAPIENCODE_CLASS (gst_vaapiencode_h264_parent_class)->allocate_buffer + (encode, coded_buf, out_buf); + if (ret != GST_FLOW_OK) + return ret; + + h264encoder = GST_VAAPI_ENCODER_H264 (encode->encoder); + if (!gst_vaapi_encoder_h264_is_avc (h264encoder)) + return ret; + + /* convert to avc format */ + if (!_h264_convert_byte_stream_to_avc (*out_buf)) { + GST_ERROR ("convert H.264 bytestream to avc buf failed."); + gst_buffer_replace (out_buf, NULL); + } + return GST_FLOW_OK; +} + +static void +gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encode_debug, + "vaapih264encode", 0, "vaapih264encode element"); + + object_class->finalize = gst_vaapiencode_h264_finalize; + object_class->set_property = gst_vaapiencode_h264_set_property; + object_class->get_property = gst_vaapiencode_h264_get_property; + + encode_class->create_encoder = gst_vaapiencode_h264_create_encoder; + encode_class->allocate_buffer = gst_vaapiencode_h264_alloc_buffer; + + gst_element_class_set_static_metadata (element_class, + "VA-API h264 encoder", + "Codec/Encoder/Video", + "A VA-API based video encoder", "Wind Yuan "); + + /* sink pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_h264_sink_factory) + ); + + /* src pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_h264_src_factory) + ); + + g_object_class_install_property (object_class, + H264_PROP_RATE_CONTROL, + g_param_spec_enum ("rate-control", + "Rate Control", + "Rate control mode", + GST_VAAPI_TYPE_RATE_CONTROL, + GST_VAAPI_RATECONTROL_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, + H264_PROP_BITRATE, + g_param_spec_uint ("bitrate", + "Bitrate (kbps)", + "The desired bitrate expressed in kbps (0: auto-calculate)", + 0, 100 * 1024, 0, G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + H264_PROP_KEY_PERIOD, + g_param_spec_uint ("key-period", + "Key Period", + "Maximal distance between two key-frames", + 1, + 300, GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD, G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + H264_PROP_MAX_BFRAMES, + g_param_spec_uint ("max-bframes", + "Max B-Frames", + "Number of B-frames between I and P", 0, 10, 0, G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + H264_PROP_INIT_QP, + g_param_spec_uint ("init-qp", + "Initial QP", + "Initial quantizer value", + 1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP, G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + H264_PROP_MIN_QP, + g_param_spec_uint ("min-qp", + "Minimum QP", + "Minimum quantizer value", + 1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP, G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + H264_PROP_NUM_SLICES, + g_param_spec_uint ("num-slices", + "Number of Slices", "Number of slices per frame", 1, 200, + 1, G_PARAM_READWRITE)); +} diff --git a/gst/vaapi/gstvaapiencode_h264.h b/gst/vaapi/gstvaapiencode_h264.h new file mode 100644 index 0000000000..10fe3c876a --- /dev/null +++ b/gst/vaapi/gstvaapiencode_h264.h @@ -0,0 +1,80 @@ +/* + * gstvaapiencode_h264.h - VA-API H.264 encoder + * + * Copyright (C) 2012-2013 Intel Corporation + * + * 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_VAAPIENCODE_H264_H +#define GST_VAAPIENCODE_H264_H + +#include +#include "gstvaapiencode.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIENCODE_H264 \ + (gst_vaapiencode_h264_get_type ()) +#define GST_IS_VAAPIENCODE_H264(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_H264)) +#define GST_IS_VAAPIENCODE_H264_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_H264)) + +#define GST_VAAPIENCODE_H264_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GST_TYPE_VAAPIENCODE_H264, \ + GstVaapiEncodeH264Class)) + +#define GST_VAAPIENCODE_H264(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GST_TYPE_VAAPIENCODE_H264, \ + GstVaapiEncodeH264)) + +#define GST_VAAPIENCODE_H264_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + GST_TYPE_VAAPIENCODE_H264, \ + GstVaapiEncodeH264Class)) + +typedef struct _GstVaapiEncodeH264 GstVaapiEncodeH264; +typedef struct _GstVaapiEncodeH264Class GstVaapiEncodeH264Class; + +struct _GstVaapiEncodeH264 +{ + GstVaapiEncode parent; + + GstVaapiProfile profile; + guint32 level; + GstVaapiRateControl rate_control; + guint32 bitrate; /* kbps */ + guint32 intra_period; + guint32 init_qp; + guint32 min_qp; + guint32 num_slices; + guint32 max_bframes; +}; + +struct _GstVaapiEncodeH264Class +{ + GstVaapiEncodeClass parent_class; +}; + +GType +gst_vaapiencode_h264_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GST_VAAPIENCODE_H264_H */ From 2e356b0f7efae33fb943ad11204020dcdbf1b04f Mon Sep 17 00:00:00 2001 From: XuGuangxin Date: Wed, 20 Nov 2013 16:21:32 +0800 Subject: [PATCH 1413/3781] plugins: add mpeg2 encoder element. Add GstVaapiEncodeMPEG2 element object. The actual plug-in element is called "vaapiencode_mpeg2". Valid properties: - rate-control: rate control mode (default: cqp - constant QP) - bitrate: desired bitrate in kbps (default: auto-calculated) - key-period: maximal distance between two key frames (default: 30) - max-bframes: number of B-frames between I and P (default: 2) - quantizer: constant quantizer (default: 8) Signed-off-by: Gwenole Beauchesne --- gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapi.c | 4 + gst/vaapi/gstvaapiencode_mpeg2.c | 248 +++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode_mpeg2.h | 76 ++++++++++ 4 files changed, 330 insertions(+) create mode 100644 gst/vaapi/gstvaapiencode_mpeg2.c create mode 100644 gst/vaapi/gstvaapiencode_mpeg2.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 15e8cb83f9..9e57d0de5d 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -59,11 +59,13 @@ libgstvaapi_source_h = \ libgstvaapi_enc_source_c = \ gstvaapiencode.c \ gstvaapiencode_h264.c \ + gstvaapiencode_mpeg2.c \ $(NULL) libgstvaapi_enc_source_h = \ gstvaapiencode.h \ gstvaapiencode_h264.h \ + gstvaapiencode_mpeg2.h \ $(NULL) if USE_ENCODERS diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 07e98b6dbd..34358b8c44 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -32,6 +32,7 @@ #if USE_ENCODERS #include "gstvaapiencode_h264.h" +#include "gstvaapiencode_mpeg2.h" #endif #define PLUGIN_NAME "vaapi" @@ -62,6 +63,9 @@ plugin_init (GstPlugin *plugin) gst_element_register(plugin, "vaapiencode_h264", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_H264); + gst_element_register(plugin, "vaapiencode_mpeg2", + GST_RANK_PRIMARY, + GST_TYPE_VAAPIENCODE_MPEG2); #endif return TRUE; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c new file mode 100644 index 0000000000..4f0a5e8a2e --- /dev/null +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -0,0 +1,248 @@ +/* + * gstvaapiencode_mpeg2.c - VA-API MPEG2 encoder + * + * Copyright (C) 2012-2013 Intel Corporation + * + * 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 "gst/vaapi/sysdeps.h" +#include "gst/vaapi/gstvaapicompat.h" + +#include "gstvaapiencode_mpeg2.h" +#include "gstvaapipluginutil.h" +#include "gst/vaapi/gstvaapiencoder_mpeg2.h" +#include "gst/vaapi/gstvaapiencoder_mpeg2_priv.h" +#include "gst/vaapi/gstvaapidisplay.h" +#include "gst/vaapi/gstvaapivalue.h" +#include "gst/vaapi/gstvaapisurface.h" + +#include + +GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); +#define GST_CAT_DEFAULT gst_vaapi_mpeg2_encode_debug + +#define GST_CAPS_CODEC(CODEC) CODEC "; " + +static const char gst_vaapiencode_mpeg2_sink_caps_str[] = + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) "; " + GST_VAAPI_SURFACE_CAPS; + +static const char gst_vaapiencode_mpeg2_src_caps_str[] = + GST_CAPS_CODEC ("video/mpeg," + "mpegversion = (int) 2, " "systemstream = (boolean) false"); + +static GstStaticPadTemplate gst_vaapiencode_mpeg2_sink_factory = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_mpeg2_sink_caps_str)); + +static GstStaticPadTemplate gst_vaapiencode_mpeg2_src_factory = + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_mpeg2_src_caps_str)); + +/* mpeg2 encode */ +G_DEFINE_TYPE (GstVaapiEncodeMpeg2, gst_vaapiencode_mpeg2, GST_TYPE_VAAPIENCODE) + +enum +{ + PROP_0, + PROP_RATE_CONTROL, + PROP_BITRATE, + PROP_QUANTIZER, + PROP_KEY_PERIOD, + PROP_MAX_BFRAMES +}; + +static void +gst_vaapiencode_mpeg2_init (GstVaapiEncodeMpeg2 * mpeg2_encode) +{ + mpeg2_encode->rate_control = GST_VAAPI_ENCODER_MPEG2_DEFAULT_RATE_CONTROL; + mpeg2_encode->bitrate = 0; + mpeg2_encode->quantizer = GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP; + mpeg2_encode->intra_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE; + mpeg2_encode->ip_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES; +} + +static void +gst_vaapiencode_mpeg2_finalize (GObject * object) +{ + G_OBJECT_CLASS (gst_vaapiencode_mpeg2_parent_class)->finalize (object); +} + +static void +gst_vaapiencode_mpeg2_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2 (object); + + switch (prop_id) { + case PROP_RATE_CONTROL: + { + GstVaapiRateControl rate_control = g_value_get_enum (value); + if (rate_control == GST_VAAPI_RATECONTROL_CBR || + rate_control == GST_VAAPI_RATECONTROL_CQP) { + encode->rate_control = g_value_get_enum (value); + } else { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } + break; + } + case PROP_BITRATE: + encode->bitrate = g_value_get_uint (value); + break; + case PROP_QUANTIZER: + encode->quantizer = g_value_get_uint (value); + break; + case PROP_KEY_PERIOD: + encode->intra_period = g_value_get_uint (value); + break; + case PROP_MAX_BFRAMES: + encode->ip_period = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapiencode_mpeg2_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2 (object); + + switch (prop_id) { + case PROP_RATE_CONTROL: + g_value_set_enum (value, encode->rate_control); + break; + case PROP_BITRATE: + g_value_set_uint (value, encode->bitrate); + break; + case PROP_QUANTIZER: + g_value_set_uint (value, encode->quantizer); + break; + case PROP_KEY_PERIOD: + g_value_set_uint (value, encode->intra_period); + break; + case PROP_MAX_BFRAMES: + g_value_set_uint (value, encode->ip_period); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstVaapiEncoder * +gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, + GstVaapiDisplay * display) +{ + GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2 (base); + GstVaapiEncoder *ret; + GstVaapiEncoderMpeg2 *mpeg2encoder; + + ret = gst_vaapi_encoder_mpeg2_new (display); + mpeg2encoder = GST_VAAPI_ENCODER_MPEG2 (ret); + + mpeg2encoder->profile = GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE; + mpeg2encoder->level = GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL; + GST_VAAPI_ENCODER_RATE_CONTROL (mpeg2encoder) = encode->rate_control; + mpeg2encoder->bitrate = encode->bitrate; + mpeg2encoder->cqp = encode->quantizer; + mpeg2encoder->intra_period = encode->intra_period; + mpeg2encoder->ip_period = encode->ip_period; + + return ret; +} + +static void +gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_vaapi_mpeg2_encode_debug, + "vaapimpeg2encode", 0, "vaapimpeg2encode element"); + + object_class->finalize = gst_vaapiencode_mpeg2_finalize; + object_class->set_property = gst_vaapiencode_mpeg2_set_property; + object_class->get_property = gst_vaapiencode_mpeg2_get_property; + + encode_class->create_encoder = gst_vaapiencode_mpeg2_create_encoder; + + gst_element_class_set_static_metadata (element_class, + "VA-API mpeg2 encoder", + "Codec/Encoder/Video", + "A VA-API based video encoder", "Guangxin Xu "); + + /* sink pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_mpeg2_sink_factory) + ); + + /* src pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_mpeg2_src_factory) + ); + + g_object_class_install_property (object_class, + PROP_RATE_CONTROL, + g_param_spec_enum ("rate-control", + "Rate Control", + "Rate control mode (CQP or CBR only)", + GST_VAAPI_TYPE_RATE_CONTROL, + GST_VAAPI_RATECONTROL_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, + PROP_BITRATE, + g_param_spec_uint ("bitrate", + "Bitrate (kbps)", + "The desired bitrate expressed in kbps (0: auto-calculate)", + 0, GST_VAAPI_ENCODER_MPEG2_MAX_BITRATE, 0, G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_QUANTIZER, + g_param_spec_uint ("quantizer", + "Constant Quantizer", + "Constant quantizer (if rate-control mode is CQP)", + GST_VAAPI_ENCODER_MPEG2_MIN_CQP, + GST_VAAPI_ENCODER_MPEG2_MAX_CQP, + GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP, G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_KEY_PERIOD, + g_param_spec_uint ("key-period", + "Key Period", + "Maximal distance between two key-frames", + 1, + GST_VAAPI_ENCODER_MPEG2_MAX_GOP_SIZE, + GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE, G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_MAX_BFRAMES, + g_param_spec_uint ("max-bframes", + "Max B-Frames", + "Number of B-frames between I and P", + 0, + GST_VAAPI_ENCODER_MPEG2_MAX_MAX_BFRAMES, + GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES, G_PARAM_READWRITE)); +} diff --git a/gst/vaapi/gstvaapiencode_mpeg2.h b/gst/vaapi/gstvaapiencode_mpeg2.h new file mode 100644 index 0000000000..f6be3785cd --- /dev/null +++ b/gst/vaapi/gstvaapiencode_mpeg2.h @@ -0,0 +1,76 @@ +/* + * gstvaapiencode_mpeg2.h - VA-API MPEG2 encoder + * + * Copyright (C) 2012-2013 Intel Corporation + * + * 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_VAAPIENCODE_MPEG2_H +#define GST_VAAPIENCODE_MPEG2_H + +#include +#include "gstvaapiencode.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIENCODE_MPEG2 \ + (gst_vaapiencode_mpeg2_get_type()) +#define GST_IS_VAAPIENCODE_MPEG2(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_MPEG2)) +#define GST_IS_VAAPIENCODE_MPEG2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_MPEG2)) + +#define GST_VAAPIENCODE_MPEG2_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GST_TYPE_VAAPIENCODE_MPEG2, \ + GstVaapiEncodeMpeg2Class)) + +#define GST_VAAPIENCODE_MPEG2(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GST_TYPE_VAAPIENCODE_MPEG2, \ + GstVaapiEncodeMpeg2)) + +#define GST_VAAPIENCODE_MPEG2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + GST_TYPE_VAAPIENCODE_MPEG2, \ + GstVaapiEncodeMpeg2Class)) + +typedef struct _GstVaapiEncodeMpeg2 GstVaapiEncodeMpeg2; +typedef struct _GstVaapiEncodeMpeg2Class GstVaapiEncodeMpeg2Class; + +struct _GstVaapiEncodeMpeg2 +{ + GstVaapiEncode parent; + + GstVaapiRateControl rate_control; + guint32 bitrate; /* kbps */ + guint32 quantizer; + guint32 intra_period; + guint32 ip_period; +}; + +struct _GstVaapiEncodeMpeg2Class +{ + GstVaapiEncodeClass parent_class; +}; + +GType +gst_vaapiencode_mpeg2_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GST_VAAPIENCODE_MPEG2_H */ From 3e96f10cf29d0637cf2422552a94cafc7e8538f7 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Thu, 7 Nov 2013 17:42:21 +0800 Subject: [PATCH 1414/3781] vaapiencode: initial port to GStreamer 1.2. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapiencode.c | 26 ++++++++++++++++++++++++-- gst/vaapi/gstvaapiencode_h264.c | 6 ++++++ gst/vaapi/gstvaapiencode_mpeg2.c | 7 +++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index b484db46cb..1c847b279c 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -20,11 +20,11 @@ */ #include "gst/vaapi/sysdeps.h" -#include #include #include #include #include "gstvaapiencode.h" +#include "gstvaapivideocontext.h" #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" #include "gstvaapivideomemory.h" @@ -67,6 +67,19 @@ gst_vaapiencode_implements_iface_init (GstImplementsInterfaceClass * iface) #endif /* context(display) interface */ +#if GST_CHECK_VERSION(1,1,0) +static void +gst_vaapiencode_set_context (GstElement * element, GstContext * context) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE (element); + GstVaapiDisplay *display = NULL; + + if (gst_vaapi_video_context_get_display (context, &display)) { + GST_INFO_OBJECT (element, "set display %p", display); + gst_vaapi_display_replace (&encode->display, display); + } +} +#else static void gst_vaapiencode_set_video_context (GstVideoContext * context, const gchar * type, const GValue * value) @@ -81,6 +94,7 @@ gst_video_context_interface_init (GstVideoContextInterface * iface) { iface->set_context = gst_vaapiencode_set_video_context; } +#endif G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode, gst_vaapiencode, GST_TYPE_VIDEO_ENCODER, @@ -88,8 +102,11 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode, G_IMPLEMENT_INTERFACE (GST_TYPE_IMPLEMENTS_INTERFACE, gst_vaapiencode_implements_iface_init); #endif +#if !GST_CHECK_VERSION(1,1,0) G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init)) + gst_video_context_interface_init) +#endif + ) static gboolean gst_vaapiencode_query (GstPad * pad, GstObject * parent, @@ -739,6 +756,7 @@ static void gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVideoEncoderClass *const venc_class = GST_VIDEO_ENCODER_CLASS (klass); GST_DEBUG_CATEGORY_INIT (gst_vaapiencode_debug, @@ -758,6 +776,10 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) klass->allocate_buffer = gst_vaapiencode_default_allocate_buffer; +#if GST_CHECK_VERSION(1,1,0) + element_class->set_context = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_context); +#endif + /* Registering debug symbols for function pointers */ GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_get_caps); GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_query); diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 35f14ca6f3..221cfbfa5e 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -24,6 +24,7 @@ #include "gstvaapiencode_h264.h" #include "gstvaapipluginutil.h" +#include "gstvaapivideomemory.h" #include "gst/vaapi/gstvaapiencoder_h264.h" #include "gst/vaapi/gstvaapiencoder_h264_priv.h" #include "gst/vaapi/gstvaapidisplay.h" @@ -38,9 +39,14 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); #define GST_CAPS_CODEC(CODEC) CODEC "; " static const char gst_vaapiencode_h264_sink_caps_str[] = +#if GST_CHECK_VERSION(1,1,0) + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, + "{ ENCODED, NV12, I420, YV12 }") ", " +#else GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE "; " GST_VAAPI_SURFACE_CAPS ", " +#endif GST_CAPS_INTERLACED_FALSE; static const char gst_vaapiencode_h264_src_caps_str[] = diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 4f0a5e8a2e..46f501fb4f 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -24,6 +24,7 @@ #include "gstvaapiencode_mpeg2.h" #include "gstvaapipluginutil.h" +#include "gstvaapivideomemory.h" #include "gst/vaapi/gstvaapiencoder_mpeg2.h" #include "gst/vaapi/gstvaapiencoder_mpeg2_priv.h" #include "gst/vaapi/gstvaapidisplay.h" @@ -38,8 +39,14 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); #define GST_CAPS_CODEC(CODEC) CODEC "; " static const char gst_vaapiencode_mpeg2_sink_caps_str[] = +#if GST_CHECK_VERSION(1,1,0) + GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, + "{ ENCODED, NV12, I420, YV12 }") ", " + GST_CAPS_INTERLACED_FALSE; +#else GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) "; " GST_VAAPI_SURFACE_CAPS; +#endif static const char gst_vaapiencode_mpeg2_src_caps_str[] = GST_CAPS_CODEC ("video/mpeg," From 139c99bb772488cf263513e73e3f8f63ab87a06f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Nov 2013 15:12:59 +0100 Subject: [PATCH 1415/3781] vaapiencode: fix support for GStreamer 1.2. --- gst/vaapi/gstvaapiencode.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 1c847b279c..256883298c 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -275,18 +275,32 @@ gst_vaapiencode_buffer_loop (GstVaapiEncode * encode) } static GstCaps * -gst_vaapiencode_get_caps (GstPad * pad) +gst_vaapiencode_get_caps_impl (GstVideoEncoder * venc) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (GST_OBJECT_PARENT (pad)); + GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); GstCaps *caps; if (encode->sinkpad_caps) caps = gst_caps_ref (encode->sinkpad_caps); else - caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); + caps = gst_pad_get_pad_template_caps (encode->sinkpad); return caps; } +static GstCaps * +gst_vaapiencode_get_caps (GstVideoEncoder * venc, GstCaps * filter) +{ + GstCaps *caps, *out_caps; + + out_caps = gst_vaapiencode_get_caps_impl (venc); + if (out_caps && filter) { + caps = gst_caps_intersect_full (out_caps, filter, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (out_caps); + out_caps = caps; + } + return out_caps; +} + static gboolean gst_vaapiencode_destroy (GstVaapiEncode * encode) { @@ -770,6 +784,7 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) venc_class->reset = GST_DEBUG_FUNCPTR (gst_vaapiencode_reset); venc_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapiencode_handle_frame); venc_class->finish = GST_DEBUG_FUNCPTR (gst_vaapiencode_finish); + venc_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapiencode_get_caps); venc_class->propose_allocation = GST_DEBUG_FUNCPTR (gst_vaapiencode_propose_allocation); @@ -781,6 +796,5 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) #endif /* Registering debug symbols for function pointers */ - GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_get_caps); GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_query); } From 84af15179643b402530ad53d8ac7cd4e8636e2ea Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Nov 2013 15:31:03 +0100 Subject: [PATCH 1416/3781] vaapiencode: fix support for raw YUV sink buffers. Allow vaapiencode plug-in elements to encode from raw YUV buffers. The most efficient way to do so is to let the vaapiencode elements allocate a buffer pool, and subsequently buffers from it. This means that upstream elements are expected to honour downstream pools. If upstream elements insist on providing their own allocated buffers to the vaapiencode elements, then it possibly would be more efficient to insert a vaapipostproc element before the vaapiencode element. This is because vaapipostproc currently has better support than other elements for "foreign" raw YUV buffers. --- gst/vaapi/gstvaapiencode.c | 85 ++++++++++++++++++++------------ gst/vaapi/gstvaapiencode_h264.c | 4 +- gst/vaapi/gstvaapiencode_mpeg2.c | 7 +-- 3 files changed, 59 insertions(+), 37 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 256883298c..eea6abfee5 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -541,13 +541,13 @@ gst_vaapiencode_reset (GstVideoEncoder * venc, gboolean hard) } static GstFlowReturn -gst_vaapiencode_get_vaapi_buffer (GstVaapiEncode * encode, - GstBuffer * src_buffer, GstBuffer ** out_buffer_ptr) +get_source_buffer (GstVaapiEncode * encode, GstBuffer * src_buffer, + GstBuffer ** out_buffer_ptr) { GstVaapiVideoMeta *meta; GstBuffer *out_buffer; GstVideoFrame src_frame, out_frame; - GstFlowReturn ret; + gboolean success; *out_buffer_ptr = NULL; meta = gst_buffer_get_vaapi_video_meta (src_buffer); @@ -556,12 +556,8 @@ gst_vaapiencode_get_vaapi_buffer (GstVaapiEncode * encode, return GST_FLOW_OK; } - if (!GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) { - GST_ERROR ("unsupported video buffer"); - return GST_FLOW_EOS; - } - - GST_DEBUG ("buffer %p not from our pool, copying", src_buffer); + if (!GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) + goto error_invalid_buffer; if (!encode->video_buffer_pool) goto error_no_pool; @@ -569,9 +565,10 @@ gst_vaapiencode_get_vaapi_buffer (GstVaapiEncode * encode, if (!gst_buffer_pool_set_active (encode->video_buffer_pool, TRUE)) goto error_activate_pool; - ret = gst_buffer_pool_acquire_buffer (encode->video_buffer_pool, - &out_buffer, NULL); - if (ret != GST_FLOW_OK) + out_buffer = NULL; + success = gst_buffer_pool_acquire_buffer (encode->video_buffer_pool, + &out_buffer, NULL) == GST_FLOW_OK; + if (!success) goto error_create_buffer; if (!gst_video_frame_map (&src_frame, &encode->sink_video_info, src_buffer, @@ -582,30 +579,56 @@ gst_vaapiencode_get_vaapi_buffer (GstVaapiEncode * encode, GST_MAP_WRITE)) goto error_map_dst_buffer; - gst_video_frame_copy (&out_frame, &src_frame); + success = gst_video_frame_copy (&out_frame, &src_frame); gst_video_frame_unmap (&out_frame); gst_video_frame_unmap (&src_frame); + if (!success) + goto error_copy_buffer; + + gst_buffer_copy_into (out_buffer, src_buffer, GST_BUFFER_COPY_TIMESTAMPS, 0, + -1); *out_buffer_ptr = out_buffer; return GST_FLOW_OK; /* ERRORS */ +error_invalid_buffer: + { + GST_ERROR ("unsupported video buffer"); + return GST_FLOW_EOS; + } error_no_pool: - GST_ERROR ("no buffer pool was negotiated"); - return GST_FLOW_ERROR; + { + GST_ERROR ("no buffer pool was negotiated"); + return GST_FLOW_ERROR; + } error_activate_pool: - GST_ERROR ("failed to activate buffer pool"); - return GST_FLOW_ERROR; + { + GST_ERROR ("failed to activate buffer pool"); + return GST_FLOW_ERROR; + } error_create_buffer: - GST_WARNING ("failed to create image. Skipping this frame"); - return GST_FLOW_OK; + { + GST_WARNING ("failed to create buffer. Skipping this frame"); + return GST_FLOW_OK; + } error_map_dst_buffer: - gst_video_frame_unmap (&src_frame); - // fall-through + { + gst_video_frame_unmap (&src_frame); + // fall-through + } error_map_src_buffer: - GST_WARNING ("failed to map buffer. Skipping this frame"); - gst_buffer_unref (out_buffer); - return GST_FLOW_OK; + { + GST_WARNING ("failed to map buffer. Skipping this frame"); + gst_buffer_unref (out_buffer); + return GST_FLOW_OK; + } +error_copy_buffer: + { + GST_WARNING ("failed to upload buffer to VA surface. Skipping this frame"); + gst_buffer_unref (out_buffer); + return GST_FLOW_OK; + } } static inline gpointer @@ -651,19 +674,17 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); GstFlowReturn ret = GST_FLOW_OK; GstVaapiEncoderStatus encoder_ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; - GstBuffer *vaapi_buf = NULL; + GstBuffer *buf; gpointer user_data; g_assert (encode && encode->encoder); g_assert (frame && frame->input_buffer); - ret = - gst_vaapiencode_get_vaapi_buffer (encode, frame->input_buffer, - &vaapi_buf); - GST_VAAPI_ENCODER_CHECK_STATUS (ret == GST_FLOW_OK, ret, - "convert to vaapi buffer failed"); + ret = get_source_buffer (encode, frame->input_buffer, &buf); + if (ret != GST_FLOW_OK) + return ret; - user_data = _create_user_data (vaapi_buf); + user_data = _create_user_data (buf); GST_VAAPI_ENCODER_CHECK_STATUS (user_data, ret, "create frame user data failed"); @@ -679,7 +700,7 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, end: gst_video_codec_frame_unref (frame); - gst_buffer_replace (&vaapi_buf, NULL); + gst_buffer_replace (&buf, NULL); return ret; } diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 221cfbfa5e..2f9293c6e8 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -43,10 +43,10 @@ static const char gst_vaapiencode_h264_sink_caps_str[] = GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ", " #else - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " - GST_CAPS_INTERLACED_FALSE "; " GST_VAAPI_SURFACE_CAPS ", " #endif + GST_CAPS_INTERLACED_FALSE "; " + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; static const char gst_vaapiencode_h264_src_caps_str[] = diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 46f501fb4f..2bd9677a44 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -42,11 +42,12 @@ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = #if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ", " - GST_CAPS_INTERLACED_FALSE; #else - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) "; " - GST_VAAPI_SURFACE_CAPS; + GST_VAAPI_SURFACE_CAPS ", " #endif + GST_CAPS_INTERLACED_FALSE "; " + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE; static const char gst_vaapiencode_mpeg2_src_caps_str[] = GST_CAPS_CODEC ("video/mpeg," From e01d48febad35337505d134175435fa578b55f6a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Nov 2013 16:34:14 +0100 Subject: [PATCH 1417/3781] vaapiencode: minor clean-ups. Add a GST_VAAPIENCODE_CAST() helper to avoid run-time checks against the GObject type system. We are guaranteed to only deal with the same plug-in element object. --- gst/vaapi/gstvaapiencode.c | 69 ++++++++----------- gst/vaapi/gstvaapiencode.h | 35 ++++------ gst/vaapi/gstvaapiencode_h264.c | 109 +++++++++++++++---------------- gst/vaapi/gstvaapiencode_h264.h | 34 +++++----- gst/vaapi/gstvaapiencode_mpeg2.c | 46 ++++++------- gst/vaapi/gstvaapiencode_mpeg2.h | 36 +++++----- 6 files changed, 147 insertions(+), 182 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index eea6abfee5..facbbb2415 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -45,11 +45,8 @@ typedef struct _GstVaapiEncodeFrameUserData } GstVaapiEncodeFrameUserData; GST_DEBUG_CATEGORY_STATIC (gst_vaapiencode_debug); - #define GST_CAT_DEFAULT gst_vaapiencode_debug -#define GstVideoContextClass GstVideoContextInterface - /* GstImplementsInterface interface */ #if !GST_CHECK_VERSION(1,0,0) static gboolean @@ -66,12 +63,12 @@ gst_vaapiencode_implements_iface_init (GstImplementsInterfaceClass * iface) } #endif -/* context(display) interface */ +/* GstContext interface */ #if GST_CHECK_VERSION(1,1,0) static void gst_vaapiencode_set_context (GstElement * element, GstContext * context) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (element); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (element); GstVaapiDisplay *display = NULL; if (gst_vaapi_video_context_get_display (context, &display)) { @@ -84,7 +81,7 @@ static void gst_vaapiencode_set_video_context (GstVideoContext * context, const gchar * type, const GValue * value) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (context); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (context); gst_vaapi_set_display (type, value, &encode->display); } @@ -94,6 +91,8 @@ gst_video_context_interface_init (GstVideoContextInterface * iface) { iface->set_context = gst_vaapiencode_set_video_context; } + +#define GstVideoContextClass GstVideoContextInterface #endif G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode, @@ -112,10 +111,10 @@ static gboolean gst_vaapiencode_query (GstPad * pad, GstObject * parent, GstQuery * query) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (parent); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (parent); gboolean success; - GST_DEBUG ("vaapiencode query %s", GST_QUERY_TYPE_NAME (query)); + GST_INFO_OBJECT(encode, "query type %s", GST_QUERY_TYPE_NAME(query)); if (gst_vaapi_reply_to_query (query, encode->display)) success = TRUE; @@ -277,7 +276,7 @@ gst_vaapiencode_buffer_loop (GstVaapiEncode * encode) static GstCaps * gst_vaapiencode_get_caps_impl (GstVideoEncoder * venc) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); GstCaps *caps; if (encode->sinkpad_caps) @@ -306,17 +305,8 @@ gst_vaapiencode_destroy (GstVaapiEncode * encode) { gst_vaapi_encoder_replace (&encode->encoder, NULL); g_clear_object (&encode->video_buffer_pool); - - if (encode->sinkpad_caps) { - gst_caps_unref (encode->sinkpad_caps); - encode->sinkpad_caps = NULL; - } - - if (encode->srcpad_caps) { - gst_caps_unref (encode->srcpad_caps); - encode->srcpad_caps = NULL; - } - + gst_caps_replace (&encode->sinkpad_caps, NULL); + gst_caps_replace (&encode->srcpad_caps, NULL); gst_vaapi_display_replace (&encode->display, NULL); return TRUE; } @@ -339,14 +329,15 @@ ensure_encoder (GstVaapiEncode * encode) return FALSE; encode->encoder = klass->create_encoder (encode, encode->display); - g_assert (encode->encoder); - return (encode->encoder ? TRUE : FALSE); + if (!encode->encoder) + return FALSE; + return TRUE; } static gboolean gst_vaapiencode_open (GstVideoEncoder * venc) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); GstVaapiDisplay *const old_display = encode->display; gboolean success; @@ -354,18 +345,13 @@ gst_vaapiencode_open (GstVideoEncoder * venc) success = ensure_display (encode); if (old_display) gst_vaapi_display_unref (old_display); - - GST_DEBUG ("ensure display %s, display:%p", - (success ? "okay" : "failed"), encode->display); return success; } static gboolean gst_vaapiencode_close (GstVideoEncoder * venc) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); - - GST_DEBUG ("vaapiencode starting close"); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); return gst_vaapiencode_destroy (encode); } @@ -502,7 +488,7 @@ error_pool_config: static gboolean gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); g_return_val_if_fail (state->caps != NULL, FALSE); @@ -524,13 +510,12 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) return gst_pad_start_task (encode->srcpad, (GstTaskFunction) gst_vaapiencode_buffer_loop, encode, NULL); - return TRUE; } static gboolean gst_vaapiencode_reset (GstVideoEncoder * venc, gboolean hard) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); GST_DEBUG ("vaapiencode starting reset"); @@ -671,7 +656,7 @@ static GstFlowReturn gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GstVideoCodecFrame * frame) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); GstFlowReturn ret = GST_FLOW_OK; GstVaapiEncoderStatus encoder_ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; GstBuffer *buf; @@ -707,12 +692,10 @@ end: static GstFlowReturn gst_vaapiencode_finish (GstVideoEncoder * venc) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); GstVaapiEncoderStatus status; GstFlowReturn ret = GST_FLOW_OK; - GST_DEBUG ("vaapiencode starting finish"); - status = gst_vaapi_encoder_flush (encode->encoder); GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); @@ -730,7 +713,7 @@ gst_vaapiencode_finish (GstVideoEncoder * venc) static gboolean gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (venc); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); GstCaps *caps = NULL; gboolean need_pool; @@ -760,7 +743,7 @@ error_no_caps: static void gst_vaapiencode_finalize (GObject * object) { - GstVaapiEncode *const encode = GST_VAAPIENCODE (object); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (object); gst_vaapiencode_destroy (encode); @@ -791,7 +774,9 @@ static void gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); +#if GST_CHECK_VERSION(1,1,0) GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); +#endif GstVideoEncoderClass *const venc_class = GST_VIDEO_ENCODER_CLASS (klass); GST_DEBUG_CATEGORY_INIT (gst_vaapiencode_debug, @@ -799,6 +784,10 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) object_class->finalize = gst_vaapiencode_finalize; +#if GST_CHECK_VERSION(1,1,0) + element_class->set_context = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_context); +#endif + venc_class->open = GST_DEBUG_FUNCPTR (gst_vaapiencode_open); venc_class->close = GST_DEBUG_FUNCPTR (gst_vaapiencode_close); venc_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_format); @@ -812,10 +801,6 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) klass->allocate_buffer = gst_vaapiencode_default_allocate_buffer; -#if GST_CHECK_VERSION(1,1,0) - element_class->set_context = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_context); -#endif - /* Registering debug symbols for function pointers */ GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_query); } diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 87e1a8e1ab..e492acb701 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -30,35 +30,26 @@ G_BEGIN_DECLS #define GST_TYPE_VAAPIENCODE \ - (gst_vaapiencode_get_type ()) - + (gst_vaapiencode_get_type ()) +#define GST_VAAPIENCODE_CAST(obj) \ + ((GstVaapiEncode *)(obj)) +#define GST_VAAPIENCODE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPIENCODE, GstVaapiEncode)) +#define GST_VAAPIENCODE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPIENCODE, GstVaapiEncodeClass)) +#define GST_VAAPIENCODE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPIENCODE, GstVaapiEncodeClass)) #define GST_IS_VAAPIENCODE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE)) - + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE)) #define GST_IS_VAAPIENCODE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE)) - -#define GST_VAAPIENCODE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - GST_TYPE_VAAPIENCODE, \ - GstVaapiEncodeClass)) - -#define GST_VAAPIENCODE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - GST_TYPE_VAAPIENCODE, \ - GstVaapiEncode)) - -#define GST_VAAPIENCODE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - GST_TYPE_VAAPIENCODE, \ - GstVaapiEncodeClass)) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE)) typedef struct _GstVaapiEncode GstVaapiEncode; typedef struct _GstVaapiEncodeClass GstVaapiEncodeClass; struct _GstVaapiEncode { - /*< private > */ + /*< private >*/ GstVideoEncoder parent_instance; GstPad *sinkpad; @@ -82,7 +73,7 @@ struct _GstVaapiEncode struct _GstVaapiEncodeClass { - /*< private > */ + /*< private >*/ GstVideoEncoderClass parent_class; GstVaapiEncoder * (*create_encoder) (GstVaapiEncode * encode, diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 2f9293c6e8..d3d75153a5 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -20,18 +20,13 @@ */ #include "gst/vaapi/sysdeps.h" -#include "gst/vaapi/gstvaapicompat.h" - +#include +#include +#include +#include "gst/vaapi/gstvaapiencoder_h264_priv.h" #include "gstvaapiencode_h264.h" #include "gstvaapipluginutil.h" #include "gstvaapivideomemory.h" -#include "gst/vaapi/gstvaapiencoder_h264.h" -#include "gst/vaapi/gstvaapiencoder_h264_priv.h" -#include "gst/vaapi/gstvaapidisplay.h" -#include "gst/vaapi/gstvaapivalue.h" -#include "gst/vaapi/gstvaapisurface.h" - -#include GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); #define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug @@ -69,14 +64,14 @@ G_DEFINE_TYPE (GstVaapiEncodeH264, gst_vaapiencode_h264, GST_TYPE_VAAPIENCODE) enum { - H264_PROP_0, - H264_PROP_RATE_CONTROL, - H264_PROP_BITRATE, - H264_PROP_KEY_PERIOD, - H264_PROP_MAX_BFRAMES, - H264_PROP_INIT_QP, - H264_PROP_MIN_QP, - H264_PROP_NUM_SLICES, + PROP_0, + PROP_RATE_CONTROL, + PROP_BITRATE, + PROP_KEY_PERIOD, + PROP_MAX_BFRAMES, + PROP_INIT_QP, + PROP_MIN_QP, + PROP_NUM_SLICES, }; static void @@ -94,28 +89,28 @@ static void gst_vaapiencode_h264_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264 (object); + GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (object); switch (prop_id) { - case H264_PROP_RATE_CONTROL: + case PROP_RATE_CONTROL: encode->rate_control = g_value_get_enum (value); break; - case H264_PROP_BITRATE: + case PROP_BITRATE: encode->bitrate = g_value_get_uint (value); break; - case H264_PROP_KEY_PERIOD: + case PROP_KEY_PERIOD: encode->intra_period = g_value_get_uint (value); break; - case H264_PROP_INIT_QP: + case PROP_INIT_QP: encode->init_qp = g_value_get_uint (value); break; - case H264_PROP_MIN_QP: + case PROP_MIN_QP: encode->min_qp = g_value_get_uint (value); break; - case H264_PROP_NUM_SLICES: + case PROP_NUM_SLICES: encode->num_slices = g_value_get_uint (value); break; - case H264_PROP_MAX_BFRAMES: + case PROP_MAX_BFRAMES: encode->max_bframes = g_value_get_uint (value); break; default: @@ -128,28 +123,28 @@ static void gst_vaapiencode_h264_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264 (object); + GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (object); switch (prop_id) { - case H264_PROP_RATE_CONTROL: + case PROP_RATE_CONTROL: g_value_set_enum (value, encode->rate_control); break; - case H264_PROP_BITRATE: + case PROP_BITRATE: g_value_set_uint (value, encode->bitrate); break; - case H264_PROP_KEY_PERIOD: + case PROP_KEY_PERIOD: g_value_set_uint (value, encode->intra_period); break; - case H264_PROP_INIT_QP: + case PROP_INIT_QP: g_value_set_uint (value, encode->init_qp); break; - case H264_PROP_MIN_QP: + case PROP_MIN_QP: g_value_set_uint (value, encode->min_qp); break; - case H264_PROP_NUM_SLICES: + case PROP_NUM_SLICES: g_value_set_uint (value, encode->num_slices); break; - case H264_PROP_MAX_BFRAMES: + case PROP_MAX_BFRAMES: g_value_set_uint (value, encode->max_bframes); break; default: @@ -162,23 +157,25 @@ static GstVaapiEncoder * gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) { - GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264 (base); - GstVaapiEncoder *ret; - GstVaapiEncoderH264 *h264encoder; + GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base); + GstVaapiEncoder *base_encoder; + GstVaapiEncoderH264 *encoder; - ret = gst_vaapi_encoder_h264_new (display); - h264encoder = GST_VAAPI_ENCODER_H264 (ret); + base_encoder = gst_vaapi_encoder_h264_new (display); + if (!base_encoder) + return NULL; + encoder = GST_VAAPI_ENCODER_H264 (base_encoder); - h264encoder->profile = GST_VAAPI_PROFILE_UNKNOWN; - h264encoder->level = GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL; - GST_VAAPI_ENCODER_RATE_CONTROL (h264encoder) = encode->rate_control; - h264encoder->bitrate = encode->bitrate; - h264encoder->intra_period = encode->intra_period; - h264encoder->init_qp = encode->init_qp; - h264encoder->min_qp = encode->min_qp; - h264encoder->slice_num = encode->num_slices; - h264encoder->b_frame_num = encode->max_bframes; - return ret; + encoder->profile = GST_VAAPI_PROFILE_UNKNOWN; + encoder->level = GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL; + GST_VAAPI_ENCODER_RATE_CONTROL (encoder) = encode->rate_control; + encoder->bitrate = encode->bitrate; + encoder->intra_period = encode->intra_period; + encoder->init_qp = encode->init_qp; + encoder->min_qp = encode->min_qp; + encoder->slice_num = encode->num_slices; + encoder->b_frame_num = encode->max_bframes; + return base_encoder; } /* h264 NAL byte stream operations */ @@ -292,7 +289,7 @@ gst_vaapiencode_h264_alloc_buffer (GstVaapiEncode * encode, if (!gst_vaapi_encoder_h264_is_avc (h264encoder)) return ret; - /* convert to avc format */ + /* Convert to avcC format */ if (!_h264_convert_byte_stream_to_avc (*out_buf)) { GST_ERROR ("convert H.264 bytestream to avc buf failed."); gst_buffer_replace (out_buf, NULL); @@ -333,7 +330,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) ); g_object_class_install_property (object_class, - H264_PROP_RATE_CONTROL, + PROP_RATE_CONTROL, g_param_spec_enum ("rate-control", "Rate Control", "Rate control mode", @@ -342,14 +339,14 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, - H264_PROP_BITRATE, + PROP_BITRATE, g_param_spec_uint ("bitrate", "Bitrate (kbps)", "The desired bitrate expressed in kbps (0: auto-calculate)", 0, 100 * 1024, 0, G_PARAM_READWRITE)); g_object_class_install_property (object_class, - H264_PROP_KEY_PERIOD, + PROP_KEY_PERIOD, g_param_spec_uint ("key-period", "Key Period", "Maximal distance between two key-frames", @@ -357,27 +354,27 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) 300, GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD, G_PARAM_READWRITE)); g_object_class_install_property (object_class, - H264_PROP_MAX_BFRAMES, + PROP_MAX_BFRAMES, g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, G_PARAM_READWRITE)); g_object_class_install_property (object_class, - H264_PROP_INIT_QP, + PROP_INIT_QP, g_param_spec_uint ("init-qp", "Initial QP", "Initial quantizer value", 1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP, G_PARAM_READWRITE)); g_object_class_install_property (object_class, - H264_PROP_MIN_QP, + PROP_MIN_QP, g_param_spec_uint ("min-qp", "Minimum QP", "Minimum quantizer value", 1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP, G_PARAM_READWRITE)); g_object_class_install_property (object_class, - H264_PROP_NUM_SLICES, + PROP_NUM_SLICES, g_param_spec_uint ("num-slices", "Number of Slices", "Number of slices per frame", 1, 200, 1, G_PARAM_READWRITE)); diff --git a/gst/vaapi/gstvaapiencode_h264.h b/gst/vaapi/gstvaapiencode_h264.h index 10fe3c876a..e7b2cfaf6f 100644 --- a/gst/vaapi/gstvaapiencode_h264.h +++ b/gst/vaapi/gstvaapiencode_h264.h @@ -29,32 +29,29 @@ G_BEGIN_DECLS #define GST_TYPE_VAAPIENCODE_H264 \ (gst_vaapiencode_h264_get_type ()) +#define GST_VAAPIENCODE_H264_CAST(obj) \ + ((GstVaapiEncodeH264 *)(obj)) +#define GST_VAAPIENCODE_H264(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPIENCODE_H264, \ + GstVaapiEncodeH264)) +#define GST_VAAPIENCODE_H264_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPIENCODE_H264, \ + GstVaapiEncodeH264Class)) +#define GST_VAAPIENCODE_H264_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPIENCODE_H264, \ + GstVaapiEncodeH264Class)) #define GST_IS_VAAPIENCODE_H264(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_H264)) + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_H264)) #define GST_IS_VAAPIENCODE_H264_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_H264)) - -#define GST_VAAPIENCODE_H264_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - GST_TYPE_VAAPIENCODE_H264, \ - GstVaapiEncodeH264Class)) - -#define GST_VAAPIENCODE_H264(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - GST_TYPE_VAAPIENCODE_H264, \ - GstVaapiEncodeH264)) - -#define GST_VAAPIENCODE_H264_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - GST_TYPE_VAAPIENCODE_H264, \ - GstVaapiEncodeH264Class)) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_H264)) typedef struct _GstVaapiEncodeH264 GstVaapiEncodeH264; typedef struct _GstVaapiEncodeH264Class GstVaapiEncodeH264Class; struct _GstVaapiEncodeH264 { - GstVaapiEncode parent; + /*< private >*/ + GstVaapiEncode parent_instance; GstVaapiProfile profile; guint32 level; @@ -69,6 +66,7 @@ struct _GstVaapiEncodeH264 struct _GstVaapiEncodeH264Class { + /*< private >*/ GstVaapiEncodeClass parent_class; }; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 2bd9677a44..fa3e152417 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -20,18 +20,13 @@ */ #include "gst/vaapi/sysdeps.h" -#include "gst/vaapi/gstvaapicompat.h" - +#include +#include +#include +#include "gst/vaapi/gstvaapiencoder_mpeg2_priv.h" #include "gstvaapiencode_mpeg2.h" #include "gstvaapipluginutil.h" #include "gstvaapivideomemory.h" -#include "gst/vaapi/gstvaapiencoder_mpeg2.h" -#include "gst/vaapi/gstvaapiencoder_mpeg2_priv.h" -#include "gst/vaapi/gstvaapidisplay.h" -#include "gst/vaapi/gstvaapivalue.h" -#include "gst/vaapi/gstvaapisurface.h" - -#include GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); #define GST_CAT_DEFAULT gst_vaapi_mpeg2_encode_debug @@ -98,7 +93,7 @@ static void gst_vaapiencode_mpeg2_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2 (object); + GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2_CAST (object); switch (prop_id) { case PROP_RATE_CONTROL: @@ -134,7 +129,7 @@ static void gst_vaapiencode_mpeg2_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2 (object); + GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2_CAST (object); switch (prop_id) { case PROP_RATE_CONTROL: @@ -162,22 +157,23 @@ static GstVaapiEncoder * gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) { - GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2 (base); - GstVaapiEncoder *ret; - GstVaapiEncoderMpeg2 *mpeg2encoder; + GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2_CAST (base); + GstVaapiEncoder *base_encoder; + GstVaapiEncoderMpeg2 *encoder; - ret = gst_vaapi_encoder_mpeg2_new (display); - mpeg2encoder = GST_VAAPI_ENCODER_MPEG2 (ret); + base_encoder = gst_vaapi_encoder_mpeg2_new (display); + if (!base_encoder) + return NULL; + encoder = GST_VAAPI_ENCODER_MPEG2 (base_encoder); - mpeg2encoder->profile = GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE; - mpeg2encoder->level = GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL; - GST_VAAPI_ENCODER_RATE_CONTROL (mpeg2encoder) = encode->rate_control; - mpeg2encoder->bitrate = encode->bitrate; - mpeg2encoder->cqp = encode->quantizer; - mpeg2encoder->intra_period = encode->intra_period; - mpeg2encoder->ip_period = encode->ip_period; - - return ret; + encoder->profile = GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE; + encoder->level = GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL; + GST_VAAPI_ENCODER_RATE_CONTROL (encoder) = encode->rate_control; + encoder->bitrate = encode->bitrate; + encoder->cqp = encode->quantizer; + encoder->intra_period = encode->intra_period; + encoder->ip_period = encode->ip_period; + return base_encoder; } static void diff --git a/gst/vaapi/gstvaapiencode_mpeg2.h b/gst/vaapi/gstvaapiencode_mpeg2.h index f6be3785cd..6658e79fcb 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.h +++ b/gst/vaapi/gstvaapiencode_mpeg2.h @@ -28,33 +28,30 @@ G_BEGIN_DECLS #define GST_TYPE_VAAPIENCODE_MPEG2 \ - (gst_vaapiencode_mpeg2_get_type()) + (gst_vaapiencode_mpeg2_get_type ()) +#define GST_VAAPIENCODE_MPEG2_CAST(obj) \ + ((GstVaapiEncodeMpeg2 *)(obj)) +#define GST_VAAPIENCODE_MPEG2(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPIENCODE_MPEG2, \ + GstVaapiEncodeMpeg2)) +#define GST_VAAPIENCODE_MPEG2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPIENCODE_MPEG2, \ + GstVaapiEncodeMpeg2Class)) +#define GST_VAAPIENCODE_MPEG2_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPIENCODE_MPEG2, \ + GstVaapiEncodeMpeg2Class)) #define GST_IS_VAAPIENCODE_MPEG2(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_MPEG2)) + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_MPEG2)) #define GST_IS_VAAPIENCODE_MPEG2_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_MPEG2)) - -#define GST_VAAPIENCODE_MPEG2_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - GST_TYPE_VAAPIENCODE_MPEG2, \ - GstVaapiEncodeMpeg2Class)) - -#define GST_VAAPIENCODE_MPEG2(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - GST_TYPE_VAAPIENCODE_MPEG2, \ - GstVaapiEncodeMpeg2)) - -#define GST_VAAPIENCODE_MPEG2_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - GST_TYPE_VAAPIENCODE_MPEG2, \ - GstVaapiEncodeMpeg2Class)) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_MPEG2)) typedef struct _GstVaapiEncodeMpeg2 GstVaapiEncodeMpeg2; typedef struct _GstVaapiEncodeMpeg2Class GstVaapiEncodeMpeg2Class; struct _GstVaapiEncodeMpeg2 { - GstVaapiEncode parent; + /*< private >*/ + GstVaapiEncode parent_instance; GstVaapiRateControl rate_control; guint32 bitrate; /* kbps */ @@ -65,6 +62,7 @@ struct _GstVaapiEncodeMpeg2 struct _GstVaapiEncodeMpeg2Class { + /*< private >*/ GstVaapiEncodeClass parent_class; }; From a6b8f944705a6af3323828ab81de4f1a9ae5eb94 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Nov 2013 17:11:22 +0100 Subject: [PATCH 1418/3781] vaapiencode: fix error handling in _finish() hook. Fix GstVideoEncoder::finish() implementation to really return possible errors instead of GST_FLOW_OK. That is, fix check for timeout status. --- gst/vaapi/gstvaapiencode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index facbbb2415..060f0e744f 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -705,8 +705,8 @@ gst_vaapiencode_finish (GstVideoEncoder * venc) while (status == GST_VAAPI_ENCODER_STATUS_SUCCESS && ret == GST_FLOW_OK) ret = gst_vaapiencode_push_frame (encode, 0); - if (ret == GST_VAAPI_ENCODE_FLOW_TIMEOUT); - ret = GST_FLOW_OK; + if (ret == GST_VAAPI_ENCODE_FLOW_TIMEOUT) + ret = GST_FLOW_OK; return ret; } From 207264abc49430ea1747458a6f09a5acea393d45 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Nov 2013 17:26:44 +0100 Subject: [PATCH 1419/3781] vaapiencode: fix error handling while allocating output buffers. Fix default GstVideoEncoder::allocate_buffer() implementation to properly unmap the coded buffer prior to returning an error. --- gst/vaapi/gstvaapiencode.c | 45 ++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 060f0e744f..215be01b1b 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -129,6 +129,7 @@ static GstFlowReturn gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode, GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr) { + GstVideoEncoder *const venc = GST_VIDEO_ENCODER_CAST (encode); GstBuffer *buf; gint32 buf_size; @@ -139,27 +140,39 @@ gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode, return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; buf_size = gst_vaapi_coded_buffer_get_size (coded_buf); - if (buf_size <= 0) { - GST_ERROR ("get GstVaapiCodedBuf buffer size:%d", buf_size); - return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; - } + if (buf_size <= 0) + goto error_invalid_buffer; - buf = - gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER_CAST (encode), - buf_size); - if (!buf) { - GST_ERROR ("failed to allocate output buffer of size %d", buf_size); - return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; - } + buf = gst_video_encoder_allocate_output_buffer (venc, buf_size); + if (!buf) + goto error_create_buffer; + if (!gst_vaapi_coded_buffer_get_buffer (coded_buf, buf)) + goto error_copy_buffer; - if (!gst_vaapi_coded_buffer_get_buffer (coded_buf, buf)) { - GST_ERROR ("failed to get encoded buffer"); - gst_buffer_replace (&buf, NULL); - return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; - } gst_vaapi_coded_buffer_unmap (coded_buf); *outbuf_ptr = buf; return GST_FLOW_OK; + + /* ERRORS */ +error_invalid_buffer: + { + GST_ERROR ("invalid GstVaapiCodedBuffer size (%d)", buf_size); + gst_vaapi_coded_buffer_unmap (coded_buf); + return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; + } +error_create_buffer: + { + GST_ERROR ("failed to create output buffer of size %d", buf_size); + gst_vaapi_coded_buffer_unmap (coded_buf); + return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; + } +error_copy_buffer: + { + GST_ERROR ("failed to copy GstVaapiCodedBuffer data"); + gst_buffer_unref (buf); + gst_vaapi_coded_buffer_unmap (coded_buf); + return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; + } } static GstFlowReturn From 98fa9e7d5912d91cad541e31abf1074740b99e34 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 Nov 2013 17:56:59 +0100 Subject: [PATCH 1420/3781] configure: disable encoders with GStreamer 0.10. Don't try to build video encoders for GStreamer 0.10. Support code is not there yet, and probably will never for such an ancient version. --- configure.ac | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configure.ac b/configure.ac index e8fcb85886..d0bcb46a1e 100644 --- a/configure.ac +++ b/configure.ac @@ -722,6 +722,11 @@ if test "$enable_encoders" = "yes"; then ]) CPPFLAGS="$saved_CPPFLAGS" fi + + if test "$USE_GST_API_1_0p" != "yes"; then + AC_MSG_WARN([GStreamer API < 1.0, disabling encoders]) + USE_ENCODERS=0 + fi fi dnl VA/Wayland API From 76174922bc38d3e323079e6c39f838f200963618 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Tue, 26 Nov 2013 12:06:07 +0000 Subject: [PATCH 1421/3781] Fix build with GStreamer >= 1.3. http://bugzilla.gnome.org/show_bug.cgi?id=715183 Signed-off-by: Gwenole Beauchesne --- configure.ac | 14 ++++++++++++-- gst-libs/gst/vaapi/Makefile.am | 3 +++ tests/Makefile.am | 3 ++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index d0bcb46a1e..498fda7ab1 100644 --- a/configure.ac +++ b/configure.ac @@ -14,6 +14,7 @@ m4_define([gst_vaapi_lt_current], [4]) m4_define([gst0_vaapi_lt_current_bias], [0]) m4_define([gst1_vaapi_lt_current_bias], [2]) m4_define([gst2_vaapi_lt_current_bias], [4]) +m4_define([gst4_vaapi_lt_current_bias], [4]) m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [0]) @@ -31,6 +32,9 @@ m4_define([gst1_plugins_bad_version], [1.0.0]) m4_define([gst12_version], [1.1.90]) m4_define([gst12_plugins_base_version], [1.1.0]) m4_define([gst12_plugins_bad_version], [1.1.0]) +m4_define([gst14_version], [1.2.90]) +m4_define([gst14_plugins_base_version], [1.3.0]) +m4_define([gst14_plugins_bad_version], [1.3.0]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.0]) @@ -200,6 +204,11 @@ case $GST_API_VERSION in GST_PLUGINS_BASE_VERSION_REQUIRED=gst12_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst12_plugins_bad_version ;; +1.3) + GST_VERSION_REQUIRED=gst14_version + GST_PLUGINS_BASE_VERSION_REQUIRED=gst14_plugins_base_version + GST_PLUGINS_BAD_VERSION_REQUIRED=gst14_plugins_bad_version + ;; *) AC_MSG_ERROR([unsupported GStreamer API version $GST_API_VERSION]) ;; @@ -269,9 +278,9 @@ PKG_CHECK_MODULES([GST_VIDEO], AC_CACHE_CHECK([for GstVideoOverlayComposition], ac_cv_have_gst_video_overlay_composition, [ saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_CFLAGS" + CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_VIDEO_CFLAGS" saved_LIBS="$LIBS" - LIBS="$LIBS $GST_LIBS" + LIBS="$LIBS $GST_LIBS $GST_VIDEO_LIBS" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], @@ -434,6 +443,7 @@ case $GST_API_VERSION in 0.10) lt_bias=gst0_vaapi_lt_current_bias;; 1.0) lt_bias=gst1_vaapi_lt_current_bias;; 1.2) lt_bias=gst2_vaapi_lt_current_bias;; +1.3) lt_bias=gst4_vaapi_lt_current_bias;; esac GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - "$lt_bias"` AC_SUBST(GST_VAAPI_MAJOR_VERSION) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f2f9bbab31..0b5eb66f46 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -280,6 +280,7 @@ libgstvaapi_drm_@GST_API_VERSION@_la_CFLAGS = \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ $(UDEV_CFLAGS) \ $(DRM_CFLAGS) \ $(LIBVA_DRM_CFLAGS) \ @@ -315,6 +316,7 @@ libgstvaapi_x11_@GST_API_VERSION@_la_CFLAGS = \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ $(X11_CFLAGS) \ $(XRANDR_CFLAGS) \ $(XRENDER_CFLAGS) \ @@ -389,6 +391,7 @@ libgstvaapi_wayland_@GST_API_VERSION@_la_CFLAGS = \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ $(WAYLAND_CFLAGS) \ $(LIBVA_WAYLAND_CFLAGS) \ $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la \ diff --git a/tests/Makefile.am b/tests/Makefile.am index 2e7f191bb4..ec6863a6f0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -20,6 +20,7 @@ TEST_CFLAGS = \ -I$(top_builddir)/gst-libs \ $(LIBVA_CFLAGS) \ $(GST_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ $(NULL) TEST_LIBS = \ @@ -87,7 +88,7 @@ test_display_CFLAGS = $(TEST_CFLAGS) test_display_LDADD = libutils.la $(TEST_LIBS) test_filter_SOURCES = test-filter.c -test_filter_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) +test_filter_CFLAGS = $(TEST_CFLAGS) test_filter_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) \ $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la From d3f671a54dca935d432c538fdd983bcf2d7d9351 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 27 Nov 2013 15:47:38 +0100 Subject: [PATCH 1422/3781] videoutils: update to master commit d4a15a5. d4a15a5 video: fix compiler warning in header with C++11 / clang-3.1 86096cc videodecoder: minor cosmetic changes to align a bit more with master b4b8b52 videodecoder: allow parse function to not use all data on adapter 2145495 videodecoder: warn if frame list gets long 36c3753 videodecoder: Also use the object lock to protect the output_state 518c93d videodecoder: fix seeking again 185fb63 video: Correct usage of the base class stream lock 170e944 videodecoder: Expose _negotiate function --- ext/videoutils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/videoutils b/ext/videoutils index 251df2b095..f56f0ca70e 160000 --- a/ext/videoutils +++ b/ext/videoutils @@ -1 +1 @@ -Subproject commit 251df2b0958e6265cf5752fdfc82c69a2869eca7 +Subproject commit f56f0ca70eaa39dc8f66f61e991094b385ed71ff From f82deaf10c147e1e3a7b8ee5d17e423b3b824663 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 27 Nov 2013 15:56:51 +0100 Subject: [PATCH 1423/3781] libs: always use built-in videoutils for GStreamer 0.10. GStreamer 0.10.36 is the latest and ultimate version to be released from the GStreamer 0.10 branch. i.e. no further releases are to be made. So, we can safely enable the built-in videoutils replacement now that they are in sync with the 0.10 branch. --- configure.ac | 26 -------------------------- gst-libs/gst/video/Makefile.am | 2 +- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/configure.ac b/configure.ac index 498fda7ab1..39ac91301d 100644 --- a/configure.ac +++ b/configure.ac @@ -324,32 +324,6 @@ if test "$ac_cv_have_gst_video_overlay_hwcaps" = "yes"; then [Defined to 1 if GstVideoOverlayComposition API supports HW hints.]) fi -dnl ... GstVideoDecoder (gstreamer-video) -AC_CACHE_CHECK([for GstVideoDecoder], - ac_cv_have_gst_video_decoder, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_VIDEO_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $GST_LIBS $GST_VIDEO_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[GstVideoCodecFrame *f; - GstVideoDecoder vdec; - f = g_slice_new0(GstVideoCodecFrame); - f->ref_count = 1; - gst_video_decoder_have_frame(&vdec); - gst_video_decoder_finish_frame(&vdec, f); - gst_video_codec_frame_unref(f);]])], - [ac_cv_have_gst_video_decoder="yes"], - [ac_cv_have_gst_video_decoder="no"] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" -]) -AM_CONDITIONAL([USE_LOCAL_GST_VIDEO_DECODER], - [test "$ac_cv_have_gst_video_decoder" != "yes"]) - dnl GStreamer -bad plugins (deprecated in GStreamer v1.2) if test "$USE_GST_API_1_2p" != "yes"; then PKG_CHECK_MODULES([GST_BASEVIDEO], diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index a790e87798..3b6ceb459c 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -21,7 +21,7 @@ libgstvaapi_videoutils_libs = \ gen_source_c = gen_source_h = -if USE_LOCAL_GST_VIDEO_DECODER +if USE_GST_API_0_10 gen_source_c += gstvideodecoder.c gstvideoutils.c video.c gen_source_h += gstvideodecoder.h gstvideoutils.h video.h endif From e9e988fc71afd0add1da46270ce49dc824176838 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 27 Nov 2013 16:25:59 +0100 Subject: [PATCH 1424/3781] libs: add more GstBuffer compat glue for GStreamer 0.10. Add gst_buffer_new_allocate() and gst_buffer_fill() implementations. Fix gst_buffer_new_wrapped_full() implementation to handle the destroy notify function. --- gst-libs/gst/vaapi/gstcompat.h | 36 ++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index f139739b45..efb5c568c4 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -107,6 +107,9 @@ typedef struct { #undef gst_buffer_new_wrapped_full #define gst_buffer_new_wrapped_full(flags, data, maxsize, ofs, size, ud, udd) \ gst_compat_buffer_new_wrapped_full(flags, data, maxsize, ofs, size, ud, udd) +#undef gst_buffer_new_allocate +#define gst_buffer_new_allocate(allocator, size, params) \ + gst_compat_buffer_new_allocate((allocator), (size), (params)) #undef gst_buffer_get_size #define gst_buffer_get_size(buffer) gst_compat_buffer_get_size(buffer) #undef gst_buffer_map @@ -116,6 +119,9 @@ typedef struct { #undef gst_buffer_extract #define gst_buffer_extract(buffer, offset, dest, size) \ gst_compat_buffer_extract(buffer, offset, dest, size) +#undef gst_buffer_fill +#define gst_buffer_fill(buffer, offset, src, size) \ + gst_compat_buffer_fill((buffer), (offset), (src), (size)) #undef gst_buffer_copy_into #define gst_buffer_copy_into(dest, src, flags, offset, size) \ gst_compat_buffer_copy_into(dest, src, flags, offset, size) @@ -128,8 +134,6 @@ gst_compat_buffer_new_wrapped_full(GstMemoryFlags flags, gpointer data, GstBuffer *buffer; /* XXX: unsupported */ - g_return_val_if_fail(user_data == NULL, NULL); - g_return_val_if_fail(notify == NULL, NULL); g_return_val_if_fail(maxsize >= size, NULL); buffer = gst_buffer_new(); @@ -138,9 +142,23 @@ gst_compat_buffer_new_wrapped_full(GstMemoryFlags flags, gpointer data, GST_BUFFER_DATA(buffer) = data + offset; GST_BUFFER_SIZE(buffer) = size; + + if (notify) + gst_mini_object_weak_ref(GST_MINI_OBJECT_CAST(buffer), + (GstMiniObjectWeakNotify)notify, user_data); return buffer; } +static inline GstBuffer * +gst_compat_buffer_new_allocate(gpointer allocator, gsize size, gpointer params) +{ + /* XXX: unsupported */ + g_return_val_if_fail(allocator == NULL, NULL); + g_return_val_if_fail(params == NULL, NULL); + + return gst_buffer_new_and_alloc(size); +} + static inline gsize gst_compat_buffer_get_size(GstBuffer *buffer) { @@ -175,6 +193,20 @@ gst_compat_buffer_extract(GstBuffer *buffer, gsize offset, gpointer dest, return esize; } +static inline gsize +gst_compat_buffer_fill(GstBuffer *buffer, gsize offset, gconstpointer src, + gsize size) +{ + gsize fsize; + + if (!buffer || !src || offset >= GST_BUFFER_SIZE(buffer)) + return 0; + + fsize = MIN(size, GST_BUFFER_SIZE(buffer) - offset); + memcpy(GST_BUFFER_DATA(buffer) + offset, src, fsize); + return fsize; +} + static inline void gst_compat_buffer_copy_into(GstBuffer *dest, GstBuffer *src, GstBufferCopyFlags flags, gsize offset, gsize size) From bc020c05f988e15434d2501ffeaec32f97c4b527 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 27 Nov 2013 16:27:31 +0100 Subject: [PATCH 1425/3781] vaapiencode: add initial support for GStreamer 0.10. --- configure.ac | 5 - gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 + gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 2 + gst-libs/gst/video/Makefile.am | 4 +- gst/vaapi/gstvaapiencode.c | 149 ++++++++++++++++++--- gst/vaapi/gstvaapiencode.h | 4 + gst/vaapi/gstvaapiencode_h264.c | 8 ++ gst/vaapi/gstvaapiencode_mpeg2.c | 8 ++ 8 files changed, 154 insertions(+), 28 deletions(-) diff --git a/configure.ac b/configure.ac index 39ac91301d..3710658931 100644 --- a/configure.ac +++ b/configure.ac @@ -706,11 +706,6 @@ if test "$enable_encoders" = "yes"; then ]) CPPFLAGS="$saved_CPPFLAGS" fi - - if test "$USE_GST_API_1_0p" != "yes"; then - AC_MSG_WARN([GStreamer API < 1.0, disabling encoders]) - USE_ENCODERS=0 - fi fi dnl VA/Wayland API diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index ddded58e15..818bdf735c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1643,7 +1643,9 @@ gst_vaapi_encoder_h264_set_format (GstVaapiEncoder * base, else /* need codec data later */ encoder->is_avc = TRUE; +#if GST_CHECK_VERSION(1,0,0) result = gst_caps_fixate (result); +#endif if (!init_encoder_public_attributes (encoder)) { GST_WARNING ("encoder ensure public attributes failed "); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 2c6e682df1..4b5ae8ea57 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -670,7 +670,9 @@ gst_vaapi_encoder_mpeg2_set_format (GstVaapiEncoder * base, result = gst_caps_intersect (tmp, ref_caps); gst_caps_unref (tmp); +#if GST_CHECK_VERSION(1,0,0) result = gst_caps_fixate (result); +#endif if (!ensure_public_attributes (encoder)) { GST_WARNING ("encoder ensure public attributes failed "); diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index 3b6ceb459c..d890cae07e 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -22,8 +22,8 @@ gen_source_c = gen_source_h = if USE_GST_API_0_10 -gen_source_c += gstvideodecoder.c gstvideoutils.c video.c -gen_source_h += gstvideodecoder.h gstvideoutils.h video.h +gen_source_c += gstvideodecoder.c gstvideoencoder.c gstvideoutils.c video.c +gen_source_h += gstvideodecoder.h gstvideoencoder.h gstvideoutils.h video.h endif GENFILES = \ diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 215be01b1b..7a0da3b8f7 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -27,8 +27,10 @@ #include "gstvaapivideocontext.h" #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" +#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideomemory.h" #include "gstvaapivideobufferpool.h" +#endif #define GST_PLUGIN_NAME "vaapiencode" #define GST_PLUGIN_DESC "A VA-API based video encoder" @@ -107,11 +109,49 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode, #endif ) -static gboolean -gst_vaapiencode_query (GstPad * pad, GstObject * parent, - GstQuery * query) +static inline gboolean +ensure_display (GstVaapiEncode * encode) { - GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (parent); + return gst_vaapi_ensure_display (encode, + GST_VAAPI_DISPLAY_TYPE_ANY, &encode->display); +} + +static gboolean +ensure_uploader (GstVaapiEncode * encode) +{ +#if !GST_CHECK_VERSION(1,0,0) + if (!ensure_display (encode)) + return FALSE; + + if (!encode->uploader) { + encode->uploader = gst_vaapi_uploader_new (encode->display); + if (!encode->uploader) + return FALSE; + } + + if (!gst_vaapi_uploader_ensure_display (encode->uploader, encode->display)) + return FALSE; +#endif + return TRUE; +} + +static gboolean +ensure_uploader_caps (GstVaapiEncode * encode) +{ +#if !GST_CHECK_VERSION(1,0,0) + if (GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info) && + !gst_vaapi_uploader_ensure_caps (encode->uploader, encode->sinkpad_caps, + NULL)) + return FALSE; +#endif + return TRUE; +} + +static gboolean +gst_vaapiencode_query (GST_PAD_QUERY_FUNCTION_ARGS) +{ + GstVaapiEncode *const encode = + GST_VAAPIENCODE_CAST (gst_pad_get_parent_element (pad)); gboolean success; GST_INFO_OBJECT(encode, "query type %s", GST_QUERY_TYPE_NAME(query)); @@ -119,9 +159,13 @@ gst_vaapiencode_query (GstPad * pad, GstObject * parent, if (gst_vaapi_reply_to_query (query, encode->display)) success = TRUE; else if (GST_PAD_IS_SINK (pad)) - success = encode->sinkpad_query (pad, parent, query); + success = GST_PAD_QUERY_FUNCTION_CALL (encode->sinkpad_query, + encode->sinkpad, parent, query); else - success = encode->srcpad_query (pad, parent, query);; + success = GST_PAD_QUERY_FUNCTION_CALL (encode->srcpad_query, + encode->srcpad, parent, query); + + gst_object_unref (encode); return success; } @@ -129,7 +173,6 @@ static GstFlowReturn gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode, GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr) { - GstVideoEncoder *const venc = GST_VIDEO_ENCODER_CAST (encode); GstBuffer *buf; gint32 buf_size; @@ -143,7 +186,13 @@ gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode, if (buf_size <= 0) goto error_invalid_buffer; - buf = gst_video_encoder_allocate_output_buffer (venc, buf_size); +#if GST_CHECK_VERSION(1,0,0) + buf = + gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER_CAST (encode), + buf_size); +#else + buf = gst_buffer_new_and_alloc (buf_size); +#endif if (!buf) goto error_create_buffer; if (!gst_vaapi_coded_buffer_get_buffer (coded_buf, buf)) @@ -240,12 +289,14 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 ms_timeout) gst_caps_ref (encode->srcpad_caps), old_state); gst_video_codec_state_unref (old_state); gst_video_codec_state_unref (new_state); +#if GST_CHECK_VERSION(1,0,0) if (!gst_video_encoder_negotiate (GST_VIDEO_ENCODER_CAST (encode))) { GST_ERROR ("failed to negotiate with caps %" GST_PTR_FORMAT, encode->srcpad_caps); ret = GST_FLOW_NOT_NEGOTIATED; goto error_unlock; } +#endif GST_DEBUG ("updated srcpad caps to: %" GST_PTR_FORMAT, encode->srcpad_caps); } @@ -294,11 +345,25 @@ gst_vaapiencode_get_caps_impl (GstVideoEncoder * venc) if (encode->sinkpad_caps) caps = gst_caps_ref (encode->sinkpad_caps); - else + else { +#if GST_CHECK_VERSION(1,0,0) caps = gst_pad_get_pad_template_caps (encode->sinkpad); +#else + caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS); + + if (caps && ensure_uploader (encode)) { + GstCaps *const yuv_caps = gst_vaapi_uploader_get_caps (encode->uploader); + if (yuv_caps) { + caps = gst_caps_make_writable (caps); + gst_caps_append (caps, gst_caps_copy (yuv_caps)); + } + } +#endif + } return caps; } +#if GST_CHECK_VERSION(1,0,0) static GstCaps * gst_vaapiencode_get_caps (GstVideoEncoder * venc, GstCaps * filter) { @@ -312,25 +377,24 @@ gst_vaapiencode_get_caps (GstVideoEncoder * venc, GstCaps * filter) } return out_caps; } +#else +#define gst_vaapiencode_get_caps gst_vaapiencode_get_caps_impl +#endif static gboolean gst_vaapiencode_destroy (GstVaapiEncode * encode) { gst_vaapi_encoder_replace (&encode->encoder, NULL); +#if GST_CHECK_VERSION(1,0,0) g_clear_object (&encode->video_buffer_pool); +#endif + g_clear_object (&encode->uploader); gst_caps_replace (&encode->sinkpad_caps, NULL); gst_caps_replace (&encode->srcpad_caps, NULL); gst_vaapi_display_replace (&encode->display, NULL); return TRUE; } -static inline gboolean -ensure_display (GstVaapiEncode * encode) -{ - return gst_vaapi_ensure_display (encode, - GST_VAAPI_DISPLAY_TYPE_ANY, &encode->display); -} - static gboolean ensure_encoder (GstVaapiEncode * encode) { @@ -340,6 +404,10 @@ ensure_encoder (GstVaapiEncode * encode) if (!ensure_display (encode)) return FALSE; + if (!ensure_uploader (encode)) + return FALSE; + if (!ensure_uploader_caps (encode)) + return FALSE; encode->encoder = klass->create_encoder (encode, encode->display); if (!encode->encoder) @@ -375,6 +443,17 @@ gst_vaapiencode_update_sink_caps (GstVaapiEncode * encode, { gst_caps_replace (&encode->sinkpad_caps, state->caps); encode->sink_video_info = state->info; + +#if !GST_CHECK_VERSION(1,0,0) + if (GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) { + /* Ensure the uploader is set up for upstream allocated buffers */ + GstVaapiUploader *const uploader = encode->uploader; + if (!gst_vaapi_uploader_ensure_display (uploader, encode->display)) + return FALSE; + if (!gst_vaapi_uploader_ensure_caps (uploader, state->caps, NULL)) + return FALSE; + } +#endif return TRUE; } @@ -440,6 +519,7 @@ static gboolean gst_vaapiencode_ensure_video_buffer_pool (GstVaapiEncode * encode, GstCaps * caps) { +#if GST_CHECK_VERSION(1,0,0) GstBufferPool *pool; GstCaps *pool_caps; GstStructure *config; @@ -496,6 +576,9 @@ error_pool_config: gst_object_unref (pool); return FALSE; } +#else + return TRUE; +#endif } static gboolean @@ -515,11 +598,13 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) if (!gst_vaapiencode_update_src_caps (encode, state)) return FALSE; +#if GST_CHECK_VERSION(1,0,0) if (encode->out_caps_done && !gst_video_encoder_negotiate (venc)) { GST_ERROR ("failed to negotiate with caps %" GST_PTR_FORMAT, encode->srcpad_caps); return FALSE; } +#endif return gst_pad_start_task (encode->srcpad, (GstTaskFunction) gst_vaapiencode_buffer_loop, encode, NULL); @@ -544,8 +629,10 @@ get_source_buffer (GstVaapiEncode * encode, GstBuffer * src_buffer, { GstVaapiVideoMeta *meta; GstBuffer *out_buffer; +#if GST_CHECK_VERSION(1,0,0) GstVideoFrame src_frame, out_frame; gboolean success; +#endif *out_buffer_ptr = NULL; meta = gst_buffer_get_vaapi_video_meta (src_buffer); @@ -554,6 +641,7 @@ get_source_buffer (GstVaapiEncode * encode, GstBuffer * src_buffer, return GST_FLOW_OK; } +#if GST_CHECK_VERSION(1,0,0) if (!GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) goto error_invalid_buffer; @@ -605,11 +693,6 @@ error_activate_pool: GST_ERROR ("failed to activate buffer pool"); return GST_FLOW_ERROR; } -error_create_buffer: - { - GST_WARNING ("failed to create buffer. Skipping this frame"); - return GST_FLOW_OK; - } error_map_dst_buffer: { gst_video_frame_unmap (&src_frame); @@ -621,6 +704,26 @@ error_map_src_buffer: gst_buffer_unref (out_buffer); return GST_FLOW_OK; } +#else + out_buffer = gst_vaapi_uploader_get_buffer (encode->uploader); + if (!out_buffer) + goto error_create_buffer; + if (!gst_vaapi_uploader_process (encode->uploader, src_buffer, out_buffer)) + goto error_copy_buffer; + + gst_buffer_copy_metadata (out_buffer, src_buffer, + GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); + + *out_buffer_ptr = out_buffer; + return GST_FLOW_OK; +#endif + + /* ERRORS */ +error_create_buffer: + { + GST_WARNING ("failed to create buffer. Skipping this frame"); + return GST_FLOW_OK; + } error_copy_buffer: { GST_WARNING ("failed to upload buffer to VA surface. Skipping this frame"); @@ -723,6 +826,7 @@ gst_vaapiencode_finish (GstVideoEncoder * venc) return ret; } +#if GST_CHECK_VERSION(1,0,0) static gboolean gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query) { @@ -752,6 +856,7 @@ error_no_caps: return FALSE; } } +#endif static void gst_vaapiencode_finalize (GObject * object) @@ -809,8 +914,10 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) venc_class->finish = GST_DEBUG_FUNCPTR (gst_vaapiencode_finish); venc_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapiencode_get_caps); +#if GST_CHECK_VERSION(1,0,0) venc_class->propose_allocation = GST_DEBUG_FUNCPTR (gst_vaapiencode_propose_allocation); +#endif klass->allocate_buffer = gst_vaapiencode_default_allocate_buffer; diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index e492acb701..ee7176ee8d 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -26,6 +26,7 @@ #include #include #include "gst/vaapi/gstvaapiencoder_objects.h" +#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -63,8 +64,11 @@ struct _GstVaapiEncode GstVaapiDisplay *display; GstVaapiEncoder *encoder; + GstVaapiUploader *uploader; +#if GST_CHECK_VERSION(1,0,0) GstBufferPool *video_buffer_pool; +#endif guint video_buffer_size; guint32 is_running:1; diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index d3d75153a5..1c108abca5 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -26,7 +26,9 @@ #include "gst/vaapi/gstvaapiencoder_h264_priv.h" #include "gstvaapiencode_h264.h" #include "gstvaapipluginutil.h" +#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideomemory.h" +#endif GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); #define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug @@ -41,7 +43,13 @@ static const char gst_vaapiencode_h264_sink_caps_str[] = GST_VAAPI_SURFACE_CAPS ", " #endif GST_CAPS_INTERLACED_FALSE "; " +#if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " +#else + "video/x-raw-yuv, " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ], " +#endif GST_CAPS_INTERLACED_FALSE; static const char gst_vaapiencode_h264_src_caps_str[] = diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index fa3e152417..cfd6581c10 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -26,7 +26,9 @@ #include "gst/vaapi/gstvaapiencoder_mpeg2_priv.h" #include "gstvaapiencode_mpeg2.h" #include "gstvaapipluginutil.h" +#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideomemory.h" +#endif GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); #define GST_CAT_DEFAULT gst_vaapi_mpeg2_encode_debug @@ -41,7 +43,13 @@ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = GST_VAAPI_SURFACE_CAPS ", " #endif GST_CAPS_INTERLACED_FALSE "; " +#if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " +#else + "video/x-raw-yuv, " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ], " +#endif GST_CAPS_INTERLACED_FALSE; static const char gst_vaapiencode_mpeg2_src_caps_str[] = From 1a4b3c3b220fc2f2de0d898bca93562c4fad46db Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Nov 2013 10:54:36 +0100 Subject: [PATCH 1426/3781] vaapiencode: fix plugin description and debug name. Align the plug-in debug category to its actual name. i.e. enable debug logs through vaapiencode_ where is mpeg2, h264, etc. Fix the plug-in element description to make it more consistent with other VA-API plug-ins. --- gst/vaapi/gstvaapiencode_h264.c | 9 ++++++--- gst/vaapi/gstvaapiencode_mpeg2.c | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 1c108abca5..7fdd95cb93 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -30,6 +30,9 @@ #include "gstvaapivideomemory.h" #endif +#define GST_PLUGIN_NAME "vaapiencode_h264" +#define GST_PLUGIN_DESC "A VA-API based H.264 video encoder" + GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); #define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug @@ -313,7 +316,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encode_debug, - "vaapih264encode", 0, "vaapih264encode element"); + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapiencode_h264_finalize; object_class->set_property = gst_vaapiencode_h264_set_property; @@ -323,9 +326,9 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) encode_class->allocate_buffer = gst_vaapiencode_h264_alloc_buffer; gst_element_class_set_static_metadata (element_class, - "VA-API h264 encoder", + "VA-API H.264 encoder", "Codec/Encoder/Video", - "A VA-API based video encoder", "Wind Yuan "); + GST_PLUGIN_DESC, "Wind Yuan "); /* sink pad */ gst_element_class_add_pad_template (element_class, diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index cfd6581c10..aad93de9bb 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -30,6 +30,9 @@ #include "gstvaapivideomemory.h" #endif +#define GST_PLUGIN_NAME "vaapiencode_mpeg2" +#define GST_PLUGIN_DESC "A VA-API based MPEG-2 video encoder" + GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); #define GST_CAT_DEFAULT gst_vaapi_mpeg2_encode_debug @@ -192,7 +195,7 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GST_DEBUG_CATEGORY_INIT (gst_vaapi_mpeg2_encode_debug, - "vaapimpeg2encode", 0, "vaapimpeg2encode element"); + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapiencode_mpeg2_finalize; object_class->set_property = gst_vaapiencode_mpeg2_set_property; @@ -201,9 +204,9 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) encode_class->create_encoder = gst_vaapiencode_mpeg2_create_encoder; gst_element_class_set_static_metadata (element_class, - "VA-API mpeg2 encoder", + "VA-API MPEG-2 encoder", "Codec/Encoder/Video", - "A VA-API based video encoder", "Guangxin Xu "); + GST_PLUGIN_DESC, "Guangxin Xu "); /* sink pad */ gst_element_class_add_pad_template (element_class, From d759fe34e68bd03ee6e93acb76d12aefaa7aed75 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Nov 2013 13:26:40 +0100 Subject: [PATCH 1427/3781] vaapiencode: move common properties to base class. Move "rate-control" mode and "bitrate" properties to the GstVaapiEncode base class. The actual range of supported rate control modes is currently implemented as a plug-in element hook. This ought to be determined from the GstVaapiEncoder object instead, i.e. from libgstvaapi. --- gst/vaapi/gstvaapiencode.c | 80 ++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode.h | 5 ++ gst/vaapi/gstvaapiencode_h264.c | 36 ++------------ gst/vaapi/gstvaapiencode_h264.h | 2 - gst/vaapi/gstvaapiencode_mpeg2.c | 59 +++++++---------------- gst/vaapi/gstvaapiencode_mpeg2.h | 2 - 6 files changed, 104 insertions(+), 80 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 7a0da3b8f7..73dc7a6d81 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -20,6 +20,7 @@ */ #include "gst/vaapi/sysdeps.h" +#include #include #include #include @@ -109,6 +110,13 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode, #endif ) +enum +{ + PROP_0, + PROP_RATE_CONTROL, + PROP_BITRATE, +}; + static inline gboolean ensure_display (GstVaapiEncode * encode) { @@ -858,6 +866,60 @@ error_no_caps: } #endif +static inline gboolean +check_ratecontrol (GstVaapiEncode * encode, GstVaapiRateControl rate_control) +{ + GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (encode); + + return !klass->check_ratecontrol || klass->check_ratecontrol (encode, + rate_control); +} + +static void +gst_vaapiencode_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + case PROP_RATE_CONTROL: + { + GstVaapiRateControl rate_control = g_value_get_enum (value); + if (check_ratecontrol (encode, rate_control)) { + encode->rate_control = rate_control; + } else { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } + break; + } + case PROP_BITRATE: + encode->bitrate = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapiencode_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + case PROP_RATE_CONTROL: + g_value_set_enum (value, encode->rate_control); + break; + case PROP_BITRATE: + g_value_set_uint (value, encode->bitrate); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void gst_vaapiencode_finalize (GObject * object) { @@ -901,6 +963,8 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapiencode_finalize; + object_class->set_property = gst_vaapiencode_set_property; + object_class->get_property = gst_vaapiencode_get_property; #if GST_CHECK_VERSION(1,1,0) element_class->set_context = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_context); @@ -923,4 +987,20 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) /* Registering debug symbols for function pointers */ GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_query); + + g_object_class_install_property (object_class, + PROP_RATE_CONTROL, + g_param_spec_enum ("rate-control", + "Rate Control", + "Rate control mode", + GST_VAAPI_TYPE_RATE_CONTROL, + GST_VAAPI_RATECONTROL_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, + PROP_BITRATE, + g_param_spec_uint ("bitrate", + "Bitrate (kbps)", + "The desired bitrate expressed in kbps (0: auto-calculate)", + 0, 100 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index ee7176ee8d..8249523c95 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -71,6 +71,9 @@ struct _GstVaapiEncode #endif guint video_buffer_size; + GstVaapiRateControl rate_control; + guint32 bitrate; /* kbps */ + guint32 is_running:1; guint32 out_caps_done:1; }; @@ -80,6 +83,8 @@ struct _GstVaapiEncodeClass /*< private >*/ GstVideoEncoderClass parent_class; + gboolean (*check_ratecontrol) (GstVaapiEncode * encode, + GstVaapiRateControl rate_control); GstVaapiEncoder * (*create_encoder) (GstVaapiEncode * encode, GstVaapiDisplay * display); GstFlowReturn (*allocate_buffer) (GstVaapiEncode * encode, diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 7fdd95cb93..4ccb4a29ee 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -20,7 +20,6 @@ */ #include "gst/vaapi/sysdeps.h" -#include #include #include #include "gst/vaapi/gstvaapiencoder_h264_priv.h" @@ -76,8 +75,6 @@ G_DEFINE_TYPE (GstVaapiEncodeH264, gst_vaapiencode_h264, GST_TYPE_VAAPIENCODE) enum { PROP_0, - PROP_RATE_CONTROL, - PROP_BITRATE, PROP_KEY_PERIOD, PROP_MAX_BFRAMES, PROP_INIT_QP, @@ -103,12 +100,6 @@ gst_vaapiencode_h264_set_property (GObject * object, GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (object); switch (prop_id) { - case PROP_RATE_CONTROL: - encode->rate_control = g_value_get_enum (value); - break; - case PROP_BITRATE: - encode->bitrate = g_value_get_uint (value); - break; case PROP_KEY_PERIOD: encode->intra_period = g_value_get_uint (value); break; @@ -137,12 +128,6 @@ gst_vaapiencode_h264_get_property (GObject * object, GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (object); switch (prop_id) { - case PROP_RATE_CONTROL: - g_value_set_enum (value, encode->rate_control); - break; - case PROP_BITRATE: - g_value_set_uint (value, encode->bitrate); - break; case PROP_KEY_PERIOD: g_value_set_uint (value, encode->intra_period); break; @@ -169,6 +154,7 @@ gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) { GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (base); GstVaapiEncoder *base_encoder; GstVaapiEncoderH264 *encoder; @@ -179,8 +165,8 @@ gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base, encoder->profile = GST_VAAPI_PROFILE_UNKNOWN; encoder->level = GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL; - GST_VAAPI_ENCODER_RATE_CONTROL (encoder) = encode->rate_control; - encoder->bitrate = encode->bitrate; + GST_VAAPI_ENCODER_RATE_CONTROL (encoder) = base_encode->rate_control; + encoder->bitrate = base_encode->bitrate; encoder->intra_period = encode->intra_period; encoder->init_qp = encode->init_qp; encoder->min_qp = encode->min_qp; @@ -340,22 +326,6 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) gst_static_pad_template_get (&gst_vaapiencode_h264_src_factory) ); - g_object_class_install_property (object_class, - PROP_RATE_CONTROL, - g_param_spec_enum ("rate-control", - "Rate Control", - "Rate control mode", - GST_VAAPI_TYPE_RATE_CONTROL, - GST_VAAPI_RATECONTROL_NONE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_BITRATE, - g_param_spec_uint ("bitrate", - "Bitrate (kbps)", - "The desired bitrate expressed in kbps (0: auto-calculate)", - 0, 100 * 1024, 0, G_PARAM_READWRITE)); - g_object_class_install_property (object_class, PROP_KEY_PERIOD, g_param_spec_uint ("key-period", diff --git a/gst/vaapi/gstvaapiencode_h264.h b/gst/vaapi/gstvaapiencode_h264.h index e7b2cfaf6f..8d906106f2 100644 --- a/gst/vaapi/gstvaapiencode_h264.h +++ b/gst/vaapi/gstvaapiencode_h264.h @@ -55,8 +55,6 @@ struct _GstVaapiEncodeH264 GstVaapiProfile profile; guint32 level; - GstVaapiRateControl rate_control; - guint32 bitrate; /* kbps */ guint32 intra_period; guint32 init_qp; guint32 min_qp; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index aad93de9bb..7295a062b6 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -20,7 +20,6 @@ */ #include "gst/vaapi/sysdeps.h" -#include #include #include #include "gst/vaapi/gstvaapiencoder_mpeg2_priv.h" @@ -77,8 +76,6 @@ G_DEFINE_TYPE (GstVaapiEncodeMpeg2, gst_vaapiencode_mpeg2, GST_TYPE_VAAPIENCODE) enum { PROP_0, - PROP_RATE_CONTROL, - PROP_BITRATE, PROP_QUANTIZER, PROP_KEY_PERIOD, PROP_MAX_BFRAMES @@ -87,8 +84,9 @@ enum static void gst_vaapiencode_mpeg2_init (GstVaapiEncodeMpeg2 * mpeg2_encode) { - mpeg2_encode->rate_control = GST_VAAPI_ENCODER_MPEG2_DEFAULT_RATE_CONTROL; - mpeg2_encode->bitrate = 0; + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (mpeg2_encode); + + base_encode->rate_control = GST_VAAPI_ENCODER_MPEG2_DEFAULT_RATE_CONTROL; mpeg2_encode->quantizer = GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP; mpeg2_encode->intra_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE; mpeg2_encode->ip_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES; @@ -107,20 +105,6 @@ gst_vaapiencode_mpeg2_set_property (GObject * object, GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2_CAST (object); switch (prop_id) { - case PROP_RATE_CONTROL: - { - GstVaapiRateControl rate_control = g_value_get_enum (value); - if (rate_control == GST_VAAPI_RATECONTROL_CBR || - rate_control == GST_VAAPI_RATECONTROL_CQP) { - encode->rate_control = g_value_get_enum (value); - } else { - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } - break; - } - case PROP_BITRATE: - encode->bitrate = g_value_get_uint (value); - break; case PROP_QUANTIZER: encode->quantizer = g_value_get_uint (value); break; @@ -143,12 +127,6 @@ gst_vaapiencode_mpeg2_get_property (GObject * object, GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2_CAST (object); switch (prop_id) { - case PROP_RATE_CONTROL: - g_value_set_enum (value, encode->rate_control); - break; - case PROP_BITRATE: - g_value_set_uint (value, encode->bitrate); - break; case PROP_QUANTIZER: g_value_set_uint (value, encode->quantizer); break; @@ -169,6 +147,7 @@ gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) { GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2_CAST (base); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (base); GstVaapiEncoder *base_encoder; GstVaapiEncoderMpeg2 *encoder; @@ -179,14 +158,23 @@ gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, encoder->profile = GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE; encoder->level = GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL; - GST_VAAPI_ENCODER_RATE_CONTROL (encoder) = encode->rate_control; - encoder->bitrate = encode->bitrate; + GST_VAAPI_ENCODER_RATE_CONTROL (encoder) = base_encode->rate_control; + encoder->bitrate = base_encode->bitrate; encoder->cqp = encode->quantizer; encoder->intra_period = encode->intra_period; encoder->ip_period = encode->ip_period; return base_encoder; } +static gboolean +gst_vaapiencode_mpeg2_check_ratecontrol (GstVaapiEncode * encode, + GstVaapiRateControl rate_control) +{ + /* XXX: get information from GstVaapiEncoder object */ + return rate_control == GST_VAAPI_RATECONTROL_CQP || + rate_control == GST_VAAPI_RATECONTROL_CBR; +} + static void gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) { @@ -202,6 +190,7 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) object_class->get_property = gst_vaapiencode_mpeg2_get_property; encode_class->create_encoder = gst_vaapiencode_mpeg2_create_encoder; + encode_class->check_ratecontrol = gst_vaapiencode_mpeg2_check_ratecontrol; gst_element_class_set_static_metadata (element_class, "VA-API MPEG-2 encoder", @@ -218,22 +207,6 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) gst_static_pad_template_get (&gst_vaapiencode_mpeg2_src_factory) ); - g_object_class_install_property (object_class, - PROP_RATE_CONTROL, - g_param_spec_enum ("rate-control", - "Rate Control", - "Rate control mode (CQP or CBR only)", - GST_VAAPI_TYPE_RATE_CONTROL, - GST_VAAPI_RATECONTROL_NONE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_BITRATE, - g_param_spec_uint ("bitrate", - "Bitrate (kbps)", - "The desired bitrate expressed in kbps (0: auto-calculate)", - 0, GST_VAAPI_ENCODER_MPEG2_MAX_BITRATE, 0, G_PARAM_READWRITE)); - g_object_class_install_property (object_class, PROP_QUANTIZER, g_param_spec_uint ("quantizer", diff --git a/gst/vaapi/gstvaapiencode_mpeg2.h b/gst/vaapi/gstvaapiencode_mpeg2.h index 6658e79fcb..3904e985f9 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.h +++ b/gst/vaapi/gstvaapiencode_mpeg2.h @@ -53,8 +53,6 @@ struct _GstVaapiEncodeMpeg2 /*< private >*/ GstVaapiEncode parent_instance; - GstVaapiRateControl rate_control; - guint32 bitrate; /* kbps */ guint32 quantizer; guint32 intra_period; guint32 ip_period; From 8116d8a50ea8681d0e384198506e33879493f7e6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Nov 2013 13:57:54 +0100 Subject: [PATCH 1428/3781] vaapiencode: additional clean-ups. Constify pointers wherever possible. Drop unused variables, and use consistent variable names. Fix gst_vaapiencode_h264_allocate_buffer() to correctly report errors, especially when in-place conversion from bytestream to avcC format failed. --- gst/vaapi/gstvaapiencode.c | 42 +++++++++++++++----------------- gst/vaapi/gstvaapiencode.h | 1 - gst/vaapi/gstvaapiencode_h264.c | 33 ++++++++++++++----------- gst/vaapi/gstvaapiencode_h264.h | 2 -- gst/vaapi/gstvaapiencode_mpeg2.c | 16 ++++++------ 5 files changed, 46 insertions(+), 48 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 73dc7a6d81..0fc5154324 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -162,7 +162,7 @@ gst_vaapiencode_query (GST_PAD_QUERY_FUNCTION_ARGS) GST_VAAPIENCODE_CAST (gst_pad_get_parent_element (pad)); gboolean success; - GST_INFO_OBJECT(encode, "query type %s", GST_QUERY_TYPE_NAME(query)); + GST_INFO_OBJECT (encode, "query type %s", GST_QUERY_TYPE_NAME (query)); if (gst_vaapi_reply_to_query (query, encode->display)) success = TRUE; @@ -236,23 +236,23 @@ static GstFlowReturn gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 ms_timeout) { GstVideoEncoder *const venc = GST_VIDEO_ENCODER_CAST (encode); - GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode); + GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (encode); GstVideoCodecFrame *out_frame = NULL; GstVaapiCodedBufferProxy *coded_buf_proxy = NULL; GstVaapiCodedBuffer *coded_buf; - GstVaapiEncoderStatus encode_status; - GstBuffer *output_buf; + GstVaapiEncoderStatus status; + GstBuffer *out_buffer; GstFlowReturn ret; g_return_val_if_fail (klass->allocate_buffer, GST_FLOW_ERROR); - encode_status = gst_vaapi_encoder_get_buffer (encode->encoder, + status = gst_vaapi_encoder_get_buffer (encode->encoder, &out_frame, &coded_buf_proxy, ms_timeout); - if (encode_status == GST_VAAPI_ENCODER_STATUS_TIMEOUT) + if (status == GST_VAAPI_ENCODER_STATUS_TIMEOUT) return GST_VAAPI_ENCODE_FLOW_TIMEOUT; - if (encode_status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - GST_ERROR ("get encoded buffer failed, status:%d", encode_status); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + GST_ERROR ("get encoded buffer failed, status:%d", status); ret = GST_FLOW_ERROR; goto error; } @@ -264,24 +264,22 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 ms_timeout) g_assert (coded_buf); /* alloc buffer */ - ret = klass->allocate_buffer (encode, coded_buf, &output_buf); + ret = klass->allocate_buffer (encode, coded_buf, &out_buffer); if (ret != GST_FLOW_OK) goto error; - out_frame->output_buffer = output_buf; + out_frame->output_buffer = out_buffer; gst_vaapi_coded_buffer_proxy_replace (&coded_buf_proxy, NULL); /* check out_caps, need lock first */ GST_VIDEO_ENCODER_STREAM_LOCK (encode); if (!encode->out_caps_done) { - GstVaapiEncoderStatus encoder_status; GstVideoCodecState *old_state, *new_state; GstBuffer *codec_data; - encoder_status = - gst_vaapi_encoder_get_codec_data (encode->encoder, &codec_data); - if (encoder_status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + status = gst_vaapi_encoder_get_codec_data (encode->encoder, &codec_data); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { ret = GST_VAAPI_ENCODE_FLOW_CODEC_DATA_ERROR; goto error_unlock; } @@ -313,7 +311,7 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 ms_timeout) GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); GST_DEBUG ("output:%" GST_TIME_FORMAT ", size:%d", - GST_TIME_ARGS (out_frame->pts), gst_buffer_get_size (output_buf)); + GST_TIME_ARGS (out_frame->pts), gst_buffer_get_size (out_buffer)); ret = gst_video_encoder_finish_frame (venc, out_frame); out_frame = NULL; @@ -472,7 +470,7 @@ gst_vaapiencode_update_src_caps (GstVaapiEncode * encode, GstVideoCodecState *out_state; GstStructure *structure; GstCaps *outcaps, *allowed_caps, *template_caps, *intersect; - GstVaapiEncoderStatus encoder_status; + GstVaapiEncoderStatus status; GstBuffer *codec_data = NULL; g_return_val_if_fail (encode->encoder, FALSE); @@ -498,9 +496,8 @@ gst_vaapiencode_update_src_caps (GstVaapiEncode * encode, } structure = gst_caps_get_structure (outcaps, 0); if (!gst_structure_has_field (structure, "codec_data")) { - encoder_status = - gst_vaapi_encoder_get_codec_data (encode->encoder, &codec_data); - if (encoder_status == GST_VAAPI_ENCODER_STATUS_SUCCESS) { + status = gst_vaapi_encoder_get_codec_data (encode->encoder, &codec_data); + if (status == GST_VAAPI_ENCODER_STATUS_SUCCESS) { if (codec_data) { outcaps = gst_caps_make_writable (outcaps); gst_caps_set_simple (outcaps, @@ -626,7 +623,6 @@ gst_vaapiencode_reset (GstVideoEncoder * venc, gboolean hard) GST_DEBUG ("vaapiencode starting reset"); /* FIXME: compare sink_caps with encoder */ - encode->is_running = FALSE; encode->out_caps_done = FALSE; return TRUE; } @@ -782,7 +778,7 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); GstFlowReturn ret = GST_FLOW_OK; - GstVaapiEncoderStatus encoder_ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; + GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS; GstBuffer *buf; gpointer user_data; @@ -801,11 +797,11 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); /*encoding frames */ - encoder_ret = gst_vaapi_encoder_put_frame (encode->encoder, frame); + status = gst_vaapi_encoder_put_frame (encode->encoder, frame); GST_VIDEO_ENCODER_STREAM_LOCK (encode); GST_VAAPI_ENCODER_CHECK_STATUS (GST_VAAPI_ENCODER_STATUS_SUCCESS <= - encoder_ret, GST_FLOW_ERROR, "gst_vaapiencoder_encode failed."); + status, GST_FLOW_ERROR, "gst_vaapiencoder_encode failed."); end: gst_video_codec_frame_unref (frame); diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 8249523c95..6d59980db5 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -74,7 +74,6 @@ struct _GstVaapiEncode GstVaapiRateControl rate_control; guint32 bitrate; /* kbps */ - guint32 is_running:1; guint32 out_caps_done:1; }; diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 4ccb4a29ee..386f8b2b7d 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -180,7 +180,7 @@ static guint8 * _h264_byte_stream_next_nal (guint8 * buffer, guint32 len, guint32 * nal_size) { const guint8 *cur = buffer; - const guint8 *end = buffer + len; + const guint8 *const end = buffer + len; guint8 *nal_start = NULL; guint32 flag = 0xFFFFFFFF; guint32 nal_start_len = 0; @@ -268,30 +268,35 @@ error: } static GstFlowReturn -gst_vaapiencode_h264_alloc_buffer (GstVaapiEncode * encode, - GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buf) +gst_vaapiencode_h264_allocate_buffer (GstVaapiEncode * encode, + GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buffer_ptr) { + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (encode->encoder); GstFlowReturn ret; - GstVaapiEncoderH264 *h264encoder; - g_return_val_if_fail (encode->encoder, GST_FLOW_ERROR); + g_return_val_if_fail (encoder != NULL, GST_FLOW_ERROR); ret = GST_VAAPIENCODE_CLASS (gst_vaapiencode_h264_parent_class)->allocate_buffer - (encode, coded_buf, out_buf); + (encode, coded_buf, out_buffer_ptr); if (ret != GST_FLOW_OK) return ret; - h264encoder = GST_VAAPI_ENCODER_H264 (encode->encoder); - if (!gst_vaapi_encoder_h264_is_avc (h264encoder)) - return ret; + if (!gst_vaapi_encoder_h264_is_avc (encoder)) + return GST_FLOW_OK; /* Convert to avcC format */ - if (!_h264_convert_byte_stream_to_avc (*out_buf)) { - GST_ERROR ("convert H.264 bytestream to avc buf failed."); - gst_buffer_replace (out_buf, NULL); - } + if (!_h264_convert_byte_stream_to_avc (*out_buffer_ptr)) + goto error_convert_buffer; return GST_FLOW_OK; + + /* ERRORS */ +error_convert_buffer: + { + GST_ERROR ("failed to convert from bytestream format to avcC format"); + gst_buffer_replace (out_buffer_ptr, NULL); + return GST_FLOW_ERROR; + } } static void @@ -309,7 +314,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) object_class->get_property = gst_vaapiencode_h264_get_property; encode_class->create_encoder = gst_vaapiencode_h264_create_encoder; - encode_class->allocate_buffer = gst_vaapiencode_h264_alloc_buffer; + encode_class->allocate_buffer = gst_vaapiencode_h264_allocate_buffer; gst_element_class_set_static_metadata (element_class, "VA-API H.264 encoder", diff --git a/gst/vaapi/gstvaapiencode_h264.h b/gst/vaapi/gstvaapiencode_h264.h index 8d906106f2..d6dad76c5f 100644 --- a/gst/vaapi/gstvaapiencode_h264.h +++ b/gst/vaapi/gstvaapiencode_h264.h @@ -53,8 +53,6 @@ struct _GstVaapiEncodeH264 /*< private >*/ GstVaapiEncode parent_instance; - GstVaapiProfile profile; - guint32 level; guint32 intra_period; guint32 init_qp; guint32 min_qp; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 7295a062b6..6aebab304e 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -82,14 +82,14 @@ enum }; static void -gst_vaapiencode_mpeg2_init (GstVaapiEncodeMpeg2 * mpeg2_encode) +gst_vaapiencode_mpeg2_init (GstVaapiEncodeMpeg2 * encode) { - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (mpeg2_encode); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (encode); base_encode->rate_control = GST_VAAPI_ENCODER_MPEG2_DEFAULT_RATE_CONTROL; - mpeg2_encode->quantizer = GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP; - mpeg2_encode->intra_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE; - mpeg2_encode->ip_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES; + encode->quantizer = GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP; + encode->intra_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE; + encode->ip_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES; } static void @@ -102,7 +102,7 @@ static void gst_vaapiencode_mpeg2_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2_CAST (object); + GstVaapiEncodeMpeg2 *const encode = GST_VAAPIENCODE_MPEG2_CAST (object); switch (prop_id) { case PROP_QUANTIZER: @@ -124,7 +124,7 @@ static void gst_vaapiencode_mpeg2_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2_CAST (object); + GstVaapiEncodeMpeg2 *const encode = GST_VAAPIENCODE_MPEG2_CAST (object); switch (prop_id) { case PROP_QUANTIZER: @@ -146,7 +146,7 @@ static GstVaapiEncoder * gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) { - GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2_CAST (base); + GstVaapiEncodeMpeg2 *const encode = GST_VAAPIENCODE_MPEG2_CAST (base); GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (base); GstVaapiEncoder *base_encoder; GstVaapiEncoderMpeg2 *encoder; From 081ff63f9a7d13438414c2d96da4c261b2b030f6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Nov 2013 15:14:43 +0100 Subject: [PATCH 1429/3781] vaapiencode: fix memory leaks in _push_frame() on error. Simplify gst_vaapiencode_push_frame(), while also removing the call to gst_video_encoder_negotiate() since this is implicit in _finish() if caps changed. Also fixed memory leaks that occured on error. --- gst/vaapi/gstvaapiencode.c | 90 +++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 49 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 0fc5154324..86b630c9b5 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -233,61 +233,50 @@ error_copy_buffer: } static GstFlowReturn -gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 ms_timeout) +gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) { GstVideoEncoder *const venc = GST_VIDEO_ENCODER_CAST (encode); GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (encode); GstVideoCodecFrame *out_frame = NULL; GstVaapiCodedBufferProxy *coded_buf_proxy = NULL; - GstVaapiCodedBuffer *coded_buf; GstVaapiEncoderStatus status; GstBuffer *out_buffer; GstFlowReturn ret; - g_return_val_if_fail (klass->allocate_buffer, GST_FLOW_ERROR); - status = gst_vaapi_encoder_get_buffer (encode->encoder, - &out_frame, &coded_buf_proxy, ms_timeout); + &out_frame, &coded_buf_proxy, timeout); if (status == GST_VAAPI_ENCODER_STATUS_TIMEOUT) return GST_VAAPI_ENCODE_FLOW_TIMEOUT; + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto error_get_buffer; - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - GST_ERROR ("get encoded buffer failed, status:%d", status); - ret = GST_FLOW_ERROR; - goto error; - } - - g_assert (out_frame); gst_video_codec_frame_set_user_data (out_frame, NULL, NULL); - coded_buf = coded_buf_proxy->buffer; - g_assert (coded_buf); - - /* alloc buffer */ - ret = klass->allocate_buffer (encode, coded_buf, &out_buffer); - if (ret != GST_FLOW_OK) - goto error; - - out_frame->output_buffer = out_buffer; - + /* Allocate and copy buffer into system memory */ + out_buffer = NULL; + ret = klass->allocate_buffer (encode, coded_buf_proxy->buffer, &out_buffer); gst_vaapi_coded_buffer_proxy_replace (&coded_buf_proxy, NULL); + if (ret != GST_FLOW_OK) + goto error_allocate_buffer; - /* check out_caps, need lock first */ + gst_buffer_replace (&out_frame->output_buffer, out_buffer); + gst_buffer_unref (out_buffer); + + /* Check output caps */ GST_VIDEO_ENCODER_STREAM_LOCK (encode); if (!encode->out_caps_done) { GstVideoCodecState *old_state, *new_state; GstBuffer *codec_data; status = gst_vaapi_encoder_get_codec_data (encode->encoder, &codec_data); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - ret = GST_VAAPI_ENCODE_FLOW_CODEC_DATA_ERROR; - goto error_unlock; - } + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto error_codec_data; + if (codec_data) { encode->srcpad_caps = gst_caps_make_writable (encode->srcpad_caps); gst_caps_set_simple (encode->srcpad_caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL); - gst_buffer_replace (&codec_data, NULL); + gst_buffer_unref (codec_data); old_state = gst_video_encoder_get_output_state (GST_VIDEO_ENCODER_CAST (encode)); new_state = @@ -295,14 +284,6 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 ms_timeout) gst_caps_ref (encode->srcpad_caps), old_state); gst_video_codec_state_unref (old_state); gst_video_codec_state_unref (new_state); -#if GST_CHECK_VERSION(1,0,0) - if (!gst_video_encoder_negotiate (GST_VIDEO_ENCODER_CAST (encode))) { - GST_ERROR ("failed to negotiate with caps %" GST_PTR_FORMAT, - encode->srcpad_caps); - ret = GST_FLOW_NOT_NEGOTIATED; - goto error_unlock; - } -#endif GST_DEBUG ("updated srcpad caps to: %" GST_PTR_FORMAT, encode->srcpad_caps); } @@ -313,21 +294,32 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 ms_timeout) GST_DEBUG ("output:%" GST_TIME_FORMAT ", size:%d", GST_TIME_ARGS (out_frame->pts), gst_buffer_get_size (out_buffer)); - ret = gst_video_encoder_finish_frame (venc, out_frame); - out_frame = NULL; - if (ret != GST_FLOW_OK) - goto error; + return gst_video_encoder_finish_frame (venc, out_frame); - return GST_FLOW_OK; - -error_unlock: - GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); -error: - gst_vaapi_coded_buffer_proxy_replace (&coded_buf_proxy, NULL); - if (out_frame) + /* ERRORS */ +error_get_buffer: + { + GST_ERROR ("failed to get encoded buffer (status %d)", status); + if (out_frame) + gst_video_codec_frame_unref (out_frame); + if (coded_buf_proxy) + gst_vaapi_coded_buffer_proxy_unref (coded_buf_proxy); + return GST_FLOW_ERROR; + } +error_allocate_buffer: + { + GST_ERROR ("failed to allocate encoded buffer in system memory"); + if (out_buffer) + gst_buffer_unref (out_buffer); + return ret; + } +error_codec_data: + { + GST_ERROR ("failed to construct codec-data (status %d)", status); + GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); gst_video_codec_frame_unref (out_frame); - - return ret; + return GST_VAAPI_ENCODE_FLOW_CODEC_DATA_ERROR; + } } static void From 30f382fcdfb9ff790ce23aae7a076ad6fdf7b606 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Nov 2013 15:56:53 +0100 Subject: [PATCH 1430/3781] vaapiencode: optimize _handle_frame() to avoid extra allocation. Optimize gst_vaapiencode_handle_frame() to avoid extra memory allocation, and in particular the GstVaapiEncObjUserData object. i.e. directly use the VA surface proxy from the source buffer. This also makes the user data attached to the GstVideoCodecFrame more consistent between both the decoder and encoder plug-in elements. --- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 30 ++--- gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 6 +- gst/vaapi/gstvaapiencode.c | 111 +++++++++---------- 3 files changed, 66 insertions(+), 81 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index e87538ce17..2a6173625a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -25,6 +25,7 @@ #include "gstvaapiencoder_objects.h" #include "gstvaapiencoder.h" #include "gstvaapiencoder_priv.h" +#include "gstvaapisurfaceproxy_priv.h" #include "gstvaapiutils.h" #define DEBUG 1 @@ -387,7 +388,7 @@ gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture) gst_vaapi_mini_object_replace ( (GstVaapiMiniObject **) (&picture->sequence), NULL); - g_assert (picture->surface); + gst_vaapi_surface_proxy_replace (&picture->proxy, NULL); picture->surface_id = VA_INVALID_ID; picture->surface = NULL; @@ -405,19 +406,22 @@ gboolean gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture, const GstVaapiCodecObjectConstructorArgs * args) { - GstVideoCodecFrame *frame; - GstVaapiSurface *surface; - GstVaapiEncObjUserDataHead *user_data; + GstVideoCodecFrame *const frame = (GstVideoCodecFrame *)args->data; gboolean success; - g_assert (args->data); - g_return_val_if_fail (args->data, FALSE); + g_return_val_if_fail (frame != NULL, FALSE); - frame = (GstVideoCodecFrame *) args->data; - user_data = gst_video_codec_frame_get_user_data (frame); - g_assert (user_data); - surface = user_data->surface; - g_return_val_if_fail (surface, FALSE); + 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_OBJECT_ID (picture->surface); + if (picture->surface_id == VA_INVALID_ID) + return FALSE; picture->sequence = NULL; picture->type = GST_VAAPI_PICTURE_TYPE_NONE; @@ -446,10 +450,6 @@ gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture, return FALSE; picture->frame = gst_video_codec_frame_ref (frame); - picture->surface = surface; - g_assert (picture->surface); - picture->surface_id = gst_vaapi_surface_get_id (picture->surface); - g_assert (picture->surface_id != VA_INVALID_SURFACE); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index 240d55b521..fdc960ee24 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -261,11 +261,6 @@ typedef enum #define GST_VAAPI_ENC_PICTURE_GET_FRAME(picture) \ (picture)->frame -typedef struct -{ - GstVaapiSurface *surface; -} GstVaapiEncObjUserDataHead; - /** * GstVaapiEncPicture: * @@ -276,6 +271,7 @@ struct _GstVaapiEncPicture /*< private > */ GstVaapiCodecObject parent_instance; GstVideoCodecFrame *frame; + GstVaapiSurfaceProxy *proxy; GstVaapiSurface *surface; GstVaapiEncSequence *sequence; /*< private >, picture packed header */ diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 86b630c9b5..a6bab1360d 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -41,12 +41,6 @@ #define GST_VAAPI_ENCODE_FLOW_CONVERT_ERROR GST_FLOW_CUSTOM_ERROR_1 #define GST_VAAPI_ENCODE_FLOW_CODEC_DATA_ERROR GST_FLOW_CUSTOM_ERROR_2 -typedef struct _GstVaapiEncodeFrameUserData -{ - GstVaapiEncObjUserDataHead head; - GstBuffer *vaapi_buf; -} GstVaapiEncodeFrameUserData; - GST_DEBUG_CATEGORY_STATIC (gst_vaapiencode_debug); #define GST_CAT_DEFAULT gst_vaapiencode_debug @@ -630,7 +624,6 @@ get_source_buffer (GstVaapiEncode * encode, GstBuffer * src_buffer, gboolean success; #endif - *out_buffer_ptr = NULL; meta = gst_buffer_get_vaapi_video_meta (src_buffer); if (meta) { *out_buffer_ptr = gst_buffer_ref (src_buffer); @@ -728,77 +721,73 @@ error_copy_buffer: } } -static inline gpointer -_create_user_data (GstBuffer * buf) -{ - GstVaapiVideoMeta *meta; - GstVaapiSurface *surface; - GstVaapiEncodeFrameUserData *user_data; - - meta = gst_buffer_get_vaapi_video_meta (buf); - if (!meta) { - GST_DEBUG ("convert to vaapi buffer failed"); - return NULL; - } - surface = gst_vaapi_video_meta_get_surface (meta); - if (!surface) { - GST_DEBUG ("vaapi_meta of codec frame doesn't have vaapisurfaceproxy"); - return NULL; - } - - user_data = g_slice_new0 (GstVaapiEncodeFrameUserData); - user_data->head.surface = surface; - user_data->vaapi_buf = gst_buffer_ref (buf); - return user_data; -} - -static void -_destroy_user_data (gpointer data) -{ - GstVaapiEncodeFrameUserData *user_data = (GstVaapiEncodeFrameUserData *) data; - - g_assert (data); - if (!user_data) - return; - gst_buffer_replace (&user_data->vaapi_buf, NULL); - g_slice_free (GstVaapiEncodeFrameUserData, user_data); -} - static GstFlowReturn gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GstVideoCodecFrame * frame) { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); - GstFlowReturn ret = GST_FLOW_OK; - GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS; + GstVaapiEncoderStatus status; + GstVaapiVideoMeta *meta; + GstVaapiSurfaceProxy *proxy; + GstFlowReturn ret; GstBuffer *buf; - gpointer user_data; - - g_assert (encode && encode->encoder); - g_assert (frame && frame->input_buffer); + buf = NULL; ret = get_source_buffer (encode, frame->input_buffer, &buf); if (ret != GST_FLOW_OK) - return ret; + goto error_buffer_invalid; - user_data = _create_user_data (buf); - GST_VAAPI_ENCODER_CHECK_STATUS (user_data, - ret, "create frame user data failed"); + gst_buffer_replace (&frame->input_buffer, buf); + gst_buffer_unref (buf); - gst_video_codec_frame_set_user_data (frame, user_data, _destroy_user_data); + meta = gst_buffer_get_vaapi_video_meta (buf); + if (!meta) + goto error_buffer_no_meta; + + proxy = gst_vaapi_video_meta_get_surface_proxy (meta); + if (!proxy) + goto error_buffer_no_surface_proxy; + + gst_video_codec_frame_set_user_data (frame, + gst_vaapi_surface_proxy_ref (proxy), + (GDestroyNotify)gst_vaapi_surface_proxy_unref); GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); - /*encoding frames */ status = gst_vaapi_encoder_put_frame (encode->encoder, frame); GST_VIDEO_ENCODER_STREAM_LOCK (encode); + if (status < GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto error_encode_frame; - GST_VAAPI_ENCODER_CHECK_STATUS (GST_VAAPI_ENCODER_STATUS_SUCCESS <= - status, GST_FLOW_ERROR, "gst_vaapiencoder_encode failed."); - -end: gst_video_codec_frame_unref (frame); - gst_buffer_replace (&buf, NULL); - return ret; + return GST_FLOW_OK; + + /* ERRORS */ +error_buffer_invalid: + { + if (buf) + gst_buffer_unref (buf); + gst_video_codec_frame_unref (frame); + return ret; + } +error_buffer_no_meta: + { + GST_ERROR ("failed to get GstVaapiVideoMeta information"); + gst_video_codec_frame_unref (frame); + return GST_FLOW_ERROR; + } +error_buffer_no_surface_proxy: + { + GST_ERROR ("failed to get VA surface proxy"); + gst_video_codec_frame_unref (frame); + return GST_FLOW_ERROR; + } +error_encode_frame: + { + GST_ERROR ("failed to encode frame %d (status %d)", + frame->system_frame_number, status); + gst_video_codec_frame_unref (frame); + return GST_FLOW_ERROR; + } } static GstFlowReturn From 5e245ae2c257e331a24984f884d359dea53e20e3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Nov 2013 17:25:05 +0100 Subject: [PATCH 1431/3781] surfaceproxy: add copy function. Add gst_vaapi_surface_proxy_copy() function that creates a new surface proxy with the same information from the parent proxy, except that the user-defined destroy notify function is not copied over. The underlying VA surface is pushed back to the video pool only when the last reference to the parent surface proxy is released. --- docs/reference/libs/libs-sections.txt | 1 + gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 57 ++++++++++++++++++- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 3 + .../gst/vaapi/gstvaapisurfaceproxy_priv.h | 1 + 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index b503d958a7..aa7b472ef1 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -366,6 +366,7 @@ gst_vaapi_surface_proxy_get_surface gst_vaapi_surface_proxy_get_surface_id gst_vaapi_surface_proxy_get_timestamp gst_vaapi_surface_proxy_new_from_pool +gst_vaapi_surface_proxy_copy gst_vaapi_surface_proxy_ref gst_vaapi_surface_proxy_replace gst_vaapi_surface_proxy_set_destroy_notify diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 2d8fcfa6e6..82432f087b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -39,12 +39,13 @@ static void gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) { if (proxy->surface) { - if (proxy->pool) + if (proxy->pool && !proxy->parent) gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface); gst_vaapi_object_unref(proxy->surface); proxy->surface = NULL; } gst_vaapi_video_pool_replace(&proxy->pool, NULL); + gst_vaapi_surface_proxy_replace(&proxy->parent, NULL); /* Notify the user function that the object is now destroyed */ if (proxy->destroy_func) @@ -61,6 +62,17 @@ gst_vaapi_surface_proxy_class(void) return &GstVaapiSurfaceProxyClass; } +/** + * gst_vaapi_surface_proxy_new_from_pool: + * @pool: a #GstVaapiSurfacePool + * + * Allocates a new surface from the supplied surface @pool and creates + * the wrapped surface proxy object from it. When the last reference + * to the proxy object is released, then the underlying VA surface is + * pushed back to its parent pool. + * + * Returns: The same newly allocated @proxy object, or %NULL on error + */ GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) { @@ -73,6 +85,7 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) if (!proxy) return NULL; + proxy->parent = NULL; proxy->destroy_func = NULL; proxy->pool = gst_vaapi_video_pool_ref(pool); proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool); @@ -89,6 +102,48 @@ error: return NULL; } + +/** + * gst_vaapi_surface_proxy_copy: + * @proxy: the parent #GstVaapiSurfaceProxy + * + * Creates are new VA surface proxy object from the supplied parent + * @proxy object with the same initial information, e.g. timestamp, + * duration. + * + * Note: the destroy notify function is not copied into the new + * surface proxy object. + * + * Returns: The same newly allocated @proxy object, or %NULL on error + */ +GstVaapiSurfaceProxy * +gst_vaapi_surface_proxy_copy(GstVaapiSurfaceProxy *proxy) +{ + GstVaapiSurfaceProxy *copy; + + g_return_val_if_fail(proxy != NULL, NULL); + + copy = (GstVaapiSurfaceProxy *) + gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class()); + if (!copy) + return NULL; + + GST_VAAPI_SURFACE_PROXY_FLAGS(copy) = + GST_VAAPI_SURFACE_PROXY_FLAGS(proxy); + + copy->parent = gst_vaapi_surface_proxy_ref(proxy->parent ? + proxy->parent : proxy); + copy->pool = gst_vaapi_video_pool_ref(proxy->pool); + copy->surface = gst_vaapi_object_ref(proxy->surface); + copy->timestamp = proxy->timestamp; + copy->duration = proxy->duration; + copy->destroy_func = NULL; + copy->has_crop_rect = proxy->has_crop_rect; + if (copy->has_crop_rect) + copy->crop_rect = proxy->crop_rect; + return copy; +} + /** * gst_vaapi_surface_proxy_ref: * @proxy: a #GstVaapiSurfaceProxy diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index c47143b25f..1b05af0b94 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -90,6 +90,9 @@ typedef enum { GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool); +GstVaapiSurfaceProxy * +gst_vaapi_surface_proxy_copy(GstVaapiSurfaceProxy *proxy); + GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy); diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index d3674a7181..a74cddf768 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -36,6 +36,7 @@ struct _GstVaapiSurfaceProxy { /*< private >*/ GstVaapiMiniObject parent_instance; + GstVaapiSurfaceProxy *parent; GstVaapiVideoPool *pool; GstVaapiSurface *surface; From b04c75848a7f5f6191b02de713e53f49339fbc0a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Nov 2013 16:37:31 +0100 Subject: [PATCH 1432/3781] plugins: allow VA video meta to be allocated from surface proxy pools. Fix gst_vaapi_video_meta_new_from_pool() to allocate VA surface proxies from surface pools instead of plain VA surfaces. This is to simplify allocations now that surface proxies are created from a surface pool. --- gst/vaapi/gstvaapivideometa.c | 41 ++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index f770120a78..ce8c04dbb0 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -98,6 +98,39 @@ set_surface_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool) return TRUE; } +static gboolean +set_surface_proxy(GstVaapiVideoMeta *meta, GstVaapiSurfaceProxy *proxy) +{ + GstVaapiSurface *surface; + + surface = GST_VAAPI_SURFACE_PROXY_SURFACE(proxy); + if (!surface) + return FALSE; + + set_surface(meta, surface); + meta->proxy = gst_vaapi_surface_proxy_ref(proxy); + return TRUE; +} + +static gboolean +set_surface_proxy_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool) +{ + GstVaapiSurfaceProxy *proxy; + gboolean success; + + proxy = gst_vaapi_surface_proxy_new_from_pool(GST_VAAPI_SURFACE_POOL(pool)); + if (!proxy) + return FALSE; + + success = set_surface_proxy(meta, proxy); + gst_vaapi_surface_proxy_unref(proxy); + if (!success) + return FALSE; + + meta->surface_pool = gst_vaapi_video_pool_ref(pool); + return TRUE; +} + static void gst_vaapi_video_meta_destroy_image(GstVaapiVideoMeta *meta) { @@ -299,7 +332,7 @@ gst_vaapi_video_meta_new_from_pool(GstVaapiVideoPool *pool) goto error; break; case GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE: - if (!set_surface_from_pool(meta, pool)) + if (!set_surface_proxy_from_pool(meta, pool)) goto error; break; } @@ -638,7 +671,6 @@ void gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, GstVaapiSurfaceProxy *proxy) { - GstVaapiSurface *surface; const GstVaapiRectangle *crop_rect; g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); @@ -646,11 +678,8 @@ gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, gst_vaapi_video_meta_destroy_surface(meta); if (proxy) { - surface = GST_VAAPI_SURFACE_PROXY_SURFACE(proxy); - if (!surface) + if (!set_surface_proxy(meta, proxy)) return; - set_surface(meta, surface); - meta->proxy = gst_vaapi_surface_proxy_ref(proxy); crop_rect = gst_vaapi_surface_proxy_get_crop_rect(proxy); if (crop_rect) From d45658ba5a7e5dd8d8ae9e3b82b6c00d07bbd893 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Nov 2013 16:51:37 +0100 Subject: [PATCH 1433/3781] plugins: drop obsolete functions. Drop the following functions that are not longer used: - gst_vaapi_video_buffer_new_with_surface() - gst_vaapi_video_meta_new_with_surface() - gst_vaapi_video_meta_set_surface() - gst_vaapi_video_meta_set_surface_from_pool() --- gst/vaapi/gstvaapivideobuffer.c | 6 --- gst/vaapi/gstvaapivideobuffer.h | 4 -- gst/vaapi/gstvaapivideometa.c | 86 --------------------------------- gst/vaapi/gstvaapivideometa.h | 14 ------ 4 files changed, 110 deletions(-) diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 760a765e57..597689a4fc 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -339,12 +339,6 @@ gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) return new_vbuffer(gst_vaapi_video_meta_new_with_image(image)); } -GstBuffer * -gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface) -{ - return new_vbuffer(gst_vaapi_video_meta_new_with_surface(surface)); -} - GstBuffer * gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) { diff --git a/gst/vaapi/gstvaapivideobuffer.h b/gst/vaapi/gstvaapivideobuffer.h index dc8f174ff3..e22b6e0135 100644 --- a/gst/vaapi/gstvaapivideobuffer.h +++ b/gst/vaapi/gstvaapivideobuffer.h @@ -51,10 +51,6 @@ G_GNUC_INTERNAL GstBuffer * gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image); -G_GNUC_INTERNAL -GstBuffer * -gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface); - G_GNUC_INTERNAL GstBuffer * gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index ce8c04dbb0..3973b75443 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -85,19 +85,6 @@ set_surface(GstVaapiVideoMeta *meta, GstVaapiSurface *surface) set_display(meta, gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface))); } -static gboolean -set_surface_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool) -{ - GstVaapiSurface *surface; - - surface = gst_vaapi_video_pool_get_object(pool); - if (!surface) - return FALSE; - set_surface(meta, surface); - meta->surface_pool = gst_vaapi_video_pool_ref(pool); - return TRUE; -} - static gboolean set_surface_proxy(GstVaapiVideoMeta *meta, GstVaapiSurfaceProxy *proxy) { @@ -371,33 +358,6 @@ gst_vaapi_video_meta_new_with_image(GstVaapiImage *image) return meta; } -/** - * gst_vaapi_video_meta_new_with_surface: - * @surface: a #GstVaapiSurface - * - * Creates a #GstVaapiVideoMeta with the specified @surface. The resulting - * meta holds an additional reference to the @surface. - * - * This function shall only be called from within gstreamer-vaapi - * plugin elements. - * - * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL on error - */ -GstVaapiVideoMeta * -gst_vaapi_video_meta_new_with_surface(GstVaapiSurface *surface) -{ - GstVaapiVideoMeta *meta; - - g_return_val_if_fail(surface != NULL, NULL); - - meta = _gst_vaapi_video_meta_new(); - if (G_UNLIKELY(!meta)) - return NULL; - - gst_vaapi_video_meta_set_surface(meta, surface); - return meta; -} - /** * gst_vaapi_video_meta_new_with_surface_proxy: * @proxy: a #GstVaapiSurfaceProxy @@ -593,52 +553,6 @@ gst_vaapi_video_meta_get_surface(GstVaapiVideoMeta *meta) return meta->surface; } -/** - * gst_vaapi_video_meta_set_surface: - * @meta: a #GstVaapiVideoMeta - * @surface: a #GstVaapiSurface - * - * Binds @surface to the @meta. If the @meta contains another - * surface previously allocated from a pool, it's pushed back to its - * parent pool and the pool is also released. - */ -void -gst_vaapi_video_meta_set_surface(GstVaapiVideoMeta *meta, - GstVaapiSurface *surface) -{ - g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); - - gst_vaapi_video_meta_destroy_surface(meta); - - if (surface) - set_surface(meta, surface); -} - -/** - * gst_vaapi_video_meta_set_surface_from_pool - * @meta: a #GstVaapiVideoMeta - * @pool: a #GstVaapiVideoPool - * - * Binds a newly allocated video object from the @pool. The @pool - * shall be of type #GstVaapiSurfacePool. Previously allocated objects - * are released and returned to their parent pools, if any. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_video_meta_set_surface_from_pool(GstVaapiVideoMeta *meta, - GstVaapiVideoPool *pool) -{ - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), FALSE); - g_return_val_if_fail(pool != NULL, FALSE); - g_return_val_if_fail(gst_vaapi_video_pool_get_object_type(pool) == - GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE, FALSE); - - gst_vaapi_video_meta_destroy_surface(meta); - - return set_surface_from_pool(meta, pool); -} - /** * gst_vaapi_video_meta_get_surface_proxy: * @meta: a #GstVaapiVideoMeta diff --git a/gst/vaapi/gstvaapivideometa.h b/gst/vaapi/gstvaapivideometa.h index d436358700..403dbdf427 100644 --- a/gst/vaapi/gstvaapivideometa.h +++ b/gst/vaapi/gstvaapivideometa.h @@ -60,10 +60,6 @@ G_GNUC_INTERNAL GstVaapiVideoMeta * gst_vaapi_video_meta_new_with_image(GstVaapiImage *image); -G_GNUC_INTERNAL -GstVaapiVideoMeta * -gst_vaapi_video_meta_new_with_surface(GstVaapiSurface *surface); - G_GNUC_INTERNAL GstVaapiVideoMeta * gst_vaapi_video_meta_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); @@ -102,16 +98,6 @@ G_GNUC_INTERNAL GstVaapiSurface * gst_vaapi_video_meta_get_surface(GstVaapiVideoMeta *meta); -G_GNUC_INTERNAL -void -gst_vaapi_video_meta_set_surface(GstVaapiVideoMeta *meta, - GstVaapiSurface *surface); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_video_meta_set_surface_from_pool(GstVaapiVideoMeta *meta, - GstVaapiVideoPool *pool); - G_GNUC_INTERNAL GstVaapiSurfaceProxy * gst_vaapi_video_meta_get_surface_proxy(GstVaapiVideoMeta *meta); From 3324cdfb616b635e3d4363526ae0df6d7e0b635d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Nov 2013 17:28:11 +0100 Subject: [PATCH 1434/3781] plugins: simplify VA video meta to only reference surface proxies. Simplify GstVaapiVideoMeta to only hold a surface proxy, which is now allocated from a surface pool. This also means that the local reference to the VA surface is also gone, as it could be extracted from the associated surface proxy. --- gst/vaapi/gstvaapivideometa.c | 48 +++++++++-------------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index 3973b75443..b1d2462602 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -43,8 +43,6 @@ struct _GstVaapiVideoMeta { GstVaapiDisplay *display; GstVaapiVideoPool *image_pool; GstVaapiImage *image; - GstVaapiVideoPool *surface_pool; - GstVaapiSurface *surface; GstVaapiSurfaceProxy *proxy; GFunc converter; guint render_flags; @@ -73,18 +71,12 @@ set_image_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool) image = gst_vaapi_video_pool_get_object(pool); if (!image) return FALSE; + set_image(meta, image); meta->image_pool = gst_vaapi_video_pool_ref(pool); return TRUE; } -static inline void -set_surface(GstVaapiVideoMeta *meta, GstVaapiSurface *surface) -{ - meta->surface = gst_vaapi_object_ref(surface); - set_display(meta, gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface))); -} - static gboolean set_surface_proxy(GstVaapiVideoMeta *meta, GstVaapiSurfaceProxy *proxy) { @@ -94,8 +86,8 @@ set_surface_proxy(GstVaapiVideoMeta *meta, GstVaapiSurfaceProxy *proxy) if (!surface) return FALSE; - set_surface(meta, surface); meta->proxy = gst_vaapi_surface_proxy_ref(proxy); + set_display(meta, gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface))); return TRUE; } @@ -111,11 +103,7 @@ set_surface_proxy_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool) success = set_surface_proxy(meta, proxy); gst_vaapi_surface_proxy_unref(proxy); - if (!success) - return FALSE; - - meta->surface_pool = gst_vaapi_video_pool_ref(pool); - return TRUE; + return success; } static void @@ -130,18 +118,10 @@ gst_vaapi_video_meta_destroy_image(GstVaapiVideoMeta *meta) gst_vaapi_video_pool_replace(&meta->image_pool, NULL); } -static void -gst_vaapi_video_meta_destroy_surface(GstVaapiVideoMeta *meta) +static inline void +gst_vaapi_video_meta_destroy_proxy(GstVaapiVideoMeta *meta) { gst_vaapi_surface_proxy_replace(&meta->proxy, NULL); - - if (meta->surface) { - if (meta->surface_pool) - gst_vaapi_video_pool_put_object(meta->surface_pool, meta->surface); - gst_vaapi_object_unref(meta->surface); - meta->surface = NULL; - } - gst_vaapi_video_pool_replace(&meta->surface_pool, NULL); } #if !GST_CHECK_VERSION(1,0,0) @@ -166,7 +146,7 @@ static void gst_vaapi_video_meta_finalize(GstVaapiVideoMeta *meta) { gst_vaapi_video_meta_destroy_image(meta); - gst_vaapi_video_meta_destroy_surface(meta); + gst_vaapi_video_meta_destroy_proxy(meta); gst_vaapi_display_replace(&meta->display, NULL); } @@ -177,8 +157,6 @@ gst_vaapi_video_meta_init(GstVaapiVideoMeta *meta) meta->display = NULL; meta->image_pool = NULL; meta->image = NULL; - meta->surface_pool = NULL; - meta->surface = NULL; meta->proxy = NULL; meta->converter = NULL; meta->render_flags = 0; @@ -237,7 +215,7 @@ gst_vaapi_video_meta_copy(GstVaapiVideoMeta *meta) g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); - if (meta->image_pool || meta->surface_pool) + if (meta->image_pool) return NULL; copy = _gst_vaapi_video_meta_create(); @@ -248,10 +226,8 @@ gst_vaapi_video_meta_copy(GstVaapiVideoMeta *meta) copy->display = gst_vaapi_display_ref(meta->display); copy->image_pool = NULL; copy->image = meta->image ? gst_vaapi_object_ref(meta->image) : NULL; - copy->surface_pool = NULL; - copy->surface = meta->surface ? gst_vaapi_object_ref(meta->surface) : NULL; copy->proxy = meta->proxy ? - gst_vaapi_surface_proxy_ref(meta->proxy) : NULL; + gst_vaapi_surface_proxy_copy(meta->proxy) : NULL; copy->converter = meta->converter; copy->render_flags = meta->render_flags; @@ -550,7 +526,7 @@ gst_vaapi_video_meta_get_surface(GstVaapiVideoMeta *meta) { g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); - return meta->surface; + return meta->proxy ? GST_VAAPI_SURFACE_PROXY_SURFACE(meta->proxy) : NULL; } /** @@ -589,7 +565,7 @@ gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); - gst_vaapi_video_meta_destroy_surface(meta); + gst_vaapi_video_meta_destroy_proxy(meta); if (proxy) { if (!set_surface_proxy(meta, proxy)) @@ -644,7 +620,7 @@ guint gst_vaapi_video_meta_get_render_flags(GstVaapiVideoMeta *meta) { g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), 0); - g_return_val_if_fail(meta->surface != NULL, 0); + g_return_val_if_fail(meta->proxy != NULL, 0); return meta->render_flags; } @@ -660,7 +636,7 @@ void gst_vaapi_video_meta_set_render_flags(GstVaapiVideoMeta *meta, guint flags) { g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); - g_return_if_fail(meta->surface != NULL); + g_return_if_fail(meta->proxy != NULL); meta->render_flags = flags; } From 9ab6037847d516898cd30458d197f27d1596a18d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Nov 2013 14:15:44 +0100 Subject: [PATCH 1435/3781] plugins: use G_PARAM_STATIC_STRINGS. This avoids a few string copies during initialization. --- gst-libs/gst/vaapi/gstvaapifilter.c | 18 +++++++++--------- gst/vaapi/gstvaapiencode_h264.c | 20 +++++++++++++------- gst/vaapi/gstvaapiencode_mpeg2.c | 9 ++++++--- gst/vaapi/gstvaapipostproc.c | 6 +++--- gst/vaapi/gstvaapisink.c | 10 +++++----- gst/vaapi/gstvaapiuploader.c | 2 +- 6 files changed, 37 insertions(+), 28 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 098ef52ee5..68aeb8cbcb 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -271,7 +271,7 @@ init_properties(void) "The forced output pixel format", GST_TYPE_VIDEO_FORMAT, DEFAULT_FORMAT, - G_PARAM_READWRITE); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiFilter:crop-rect: @@ -283,7 +283,7 @@ init_properties(void) "Cropping Rectangle", "The cropping rectangle", GST_VAAPI_TYPE_RECTANGLE, - G_PARAM_READWRITE); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiFilter:denoise: @@ -295,7 +295,7 @@ init_properties(void) "Denoising Level", "The level of denoising to apply", 0.0, 1.0, 0.0, - G_PARAM_READWRITE); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiFilter:sharpen: @@ -308,7 +308,7 @@ init_properties(void) "Sharpening Level", "The level of sharpening/blurring to apply", -1.0, 1.0, 0.0, - G_PARAM_READWRITE); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiFilter:hue: @@ -321,7 +321,7 @@ init_properties(void) "Hue", "The color hue value", -180.0, 180.0, 0.0, - G_PARAM_READWRITE); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiFilter:saturation: @@ -334,7 +334,7 @@ init_properties(void) "Saturation", "The color saturation value", 0.0, 2.0, 1.0, - G_PARAM_READWRITE); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiFilter:brightness: @@ -347,7 +347,7 @@ init_properties(void) "Brightness", "The color brightness value", -1.0, 1.0, 0.0, - G_PARAM_READWRITE); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiFilter:contrast: @@ -360,7 +360,7 @@ init_properties(void) "Contrast", "The color contrast value", 0.0, 2.0, 1.0, - G_PARAM_READWRITE); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiFilter:deinterlace-method: @@ -374,7 +374,7 @@ init_properties(void) "Deinterlacing method to apply", GST_VAAPI_TYPE_DEINTERLACE_METHOD, GST_VAAPI_DEINTERLACE_METHOD_NONE, - G_PARAM_READWRITE); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); } static void diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 386f8b2b7d..09d5920f73 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -336,32 +336,38 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) g_param_spec_uint ("key-period", "Key Period", "Maximal distance between two key-frames", - 1, - 300, GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD, G_PARAM_READWRITE)); + 1, 300, GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MAX_BFRAMES, g_param_spec_uint ("max-bframes", "Max B-Frames", - "Number of B-frames between I and P", 0, 10, 0, G_PARAM_READWRITE)); + "Number of B-frames between I and P", + 0, 10, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_INIT_QP, g_param_spec_uint ("init-qp", "Initial QP", "Initial quantizer value", - 1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP, G_PARAM_READWRITE)); + 1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MIN_QP, g_param_spec_uint ("min-qp", "Minimum QP", "Minimum quantizer value", - 1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP, G_PARAM_READWRITE)); + 1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_NUM_SLICES, g_param_spec_uint ("num-slices", - "Number of Slices", "Number of slices per frame", 1, 200, - 1, G_PARAM_READWRITE)); + "Number of Slices", + "Number of slices per frame", + 1, 200, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 6aebab304e..3a437cb287 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -214,7 +214,8 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) "Constant quantizer (if rate-control mode is CQP)", GST_VAAPI_ENCODER_MPEG2_MIN_CQP, GST_VAAPI_ENCODER_MPEG2_MAX_CQP, - GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP, G_PARAM_READWRITE)); + GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_KEY_PERIOD, @@ -223,7 +224,8 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) "Maximal distance between two key-frames", 1, GST_VAAPI_ENCODER_MPEG2_MAX_GOP_SIZE, - GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE, G_PARAM_READWRITE)); + GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MAX_BFRAMES, @@ -232,5 +234,6 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) "Number of B-frames between I and P", 0, GST_VAAPI_ENCODER_MPEG2_MAX_MAX_BFRAMES, - GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES, G_PARAM_READWRITE)); + GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6ec3cc6860..6d2c1de138 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1716,7 +1716,7 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) "Width", "Forced output width", 0, G_MAXINT, 0, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiPostproc:height: @@ -1732,7 +1732,7 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) "Height", "Forced output height", 0, G_MAXINT, 0, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiPostproc:force-aspect-ratio: @@ -1748,7 +1748,7 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) "Force aspect ratio", "When enabled, scaling will respect original aspect ratio", TRUE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiPostproc:denoise: diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 964dcdf085..bf2074a97c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1514,7 +1514,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) "OpenGL rendering", "Enables OpenGL rendering", FALSE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, @@ -1523,7 +1523,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) "Reflection effect", "Enables OpenGL reflection effect", FALSE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); #endif g_object_class_install_property @@ -1533,7 +1533,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) "Fullscreen", "Requests window in fullscreen state", FALSE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiSink:synchronous: @@ -1548,7 +1548,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) "Synchronous mode", "Toggles X display synchronous mode", FALSE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiSink:rotation: @@ -1578,7 +1578,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) "Force aspect ratio", "When enabled, scaling will respect original aspect ratio", TRUE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 04de04c677..61b9ad49ad 100755 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -307,7 +307,7 @@ gst_vaapi_uploader_class_init(GstVaapiUploaderClass *klass) "display", "Display", "The GstVaapiDisplay this object is bound to", - G_PARAM_READWRITE)); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void From 84b3f84925cc3d12eb949a283534e3d1e0761902 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 28 Nov 2013 19:08:28 +0100 Subject: [PATCH 1436/3781] plugins: fix memory leaks through GstVideoMeta maps. When GstVideoMeta maps were used, the supporting functions incorrectly used gst_buffer_get_memory() instead of gst_buffer_peek_memory(), thus always increasing the associated GstMemory reference count and giving zero chance to actually release that, and subsequently the VA display. --- gst/vaapi/gstvaapivideomemory.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 0e3b794ce0..cb953c1a5f 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -123,7 +123,7 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, GstMapInfo *info, gpointer *data, gint *stride, GstMapFlags flags) { GstVaapiVideoMemory * const mem = - GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_get_memory(meta->buffer, 0)); + GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_peek_memory(meta->buffer, 0)); g_return_val_if_fail(mem, FALSE); g_return_val_if_fail(GST_VAAPI_IS_VIDEO_ALLOCATOR(mem->parent_instance. @@ -196,7 +196,7 @@ gst_video_meta_unmap_vaapi_memory(GstVideoMeta *meta, guint plane, GstMapInfo *info) { GstVaapiVideoMemory * const mem = - GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_get_memory(meta->buffer, 0)); + GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_peek_memory(meta->buffer, 0)); g_return_val_if_fail(mem, FALSE); g_return_val_if_fail(GST_VAAPI_IS_VIDEO_ALLOCATOR(mem->parent_instance. From 16751205a26f138396ded661227cc99c146572d1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 29 Nov 2013 13:56:12 +0100 Subject: [PATCH 1437/3781] plugins: simplify gst_vaapi_ensure_display(). Return earlier if the creation of a VA display failed. Likewise, simplify gst_vaapi_video_context_propagate() now that we are guaranteed to have a valid VA display. --- gst/vaapi/gstvaapipluginutil.c | 8 ++++---- gst/vaapi/gstvaapivideocontext.c | 5 ----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 82349a82ed..92f9ec58f9 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -139,12 +139,12 @@ gst_vaapi_ensure_display( /* If no neighboor, or application not interested, use system default */ display = gst_vaapi_create_display(&display_type); - - if (display_ptr) - *display_ptr = display; + if (!display) + return FALSE; gst_vaapi_video_context_propagate(context, display); - return display != NULL; + *display_ptr = display; + return TRUE; } void diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index e740983beb..551b79d89e 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -169,11 +169,6 @@ gst_vaapi_video_context_propagate(GstElement *element, GstVaapiDisplay *display) GstContext *context; GstMessage *msg; - if (!display) { - GST_ERROR_OBJECT(element, "failed to get VA-API display connection"); - return; - } - context = gst_vaapi_video_context_new_with_display(display, FALSE); GST_CAT_INFO_OBJECT(GST_CAT_CONTEXT, element, From 7a3316543610e0728272d7b1e6cb873c0c884426 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 29 Nov 2013 14:02:52 +0100 Subject: [PATCH 1438/3781] plugins: fix reference leaks of VA display objects. Fix GstElement::set_context() implementation for all plug-in elements to avoid leaking an extra reference to the VA display, thus preventing correct cleanup of VA resources in GStreamer 1.2 builds. --- gst/vaapi/gstvaapidecode.c | 1 + gst/vaapi/gstvaapiencode.c | 1 + gst/vaapi/gstvaapipostproc.c | 1 + gst/vaapi/gstvaapisink.c | 1 + 4 files changed, 4 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 67485990bb..3225a95b59 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -591,6 +591,7 @@ gst_vaapidecode_set_context(GstElement *element, GstContext *context) if (gst_vaapi_video_context_get_display(context, &display)) { GST_INFO_OBJECT(element, "set display %p", display); gst_vaapi_display_replace(&decode->display, display); + gst_vaapi_display_unref(display); } } #endif diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index a6bab1360d..c3b2f554a8 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -71,6 +71,7 @@ gst_vaapiencode_set_context (GstElement * element, GstContext * context) if (gst_vaapi_video_context_get_display (context, &display)) { GST_INFO_OBJECT (element, "set display %p", display); gst_vaapi_display_replace (&encode->display, display); + gst_vaapi_display_unref (display); } } #else diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6d2c1de138..292405f5e3 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -264,6 +264,7 @@ gst_vaapipostproc_set_context(GstElement *element, GstContext *context) if (gst_vaapi_video_context_get_display(context, &display)) { GST_INFO_OBJECT(element, "set display %p", display); gst_vaapi_display_replace(&postproc->display, display); + gst_vaapi_display_unref(display); } } #endif diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index bf2074a97c..74f584bc9d 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1351,6 +1351,7 @@ gst_vaapisink_set_context(GstElement *element, GstContext *context) if (gst_vaapi_video_context_get_display(context, &display)) { GST_INFO_OBJECT(element, "set display %p", display); gst_vaapi_display_replace(&sink->display, display); + gst_vaapi_display_unref(display); } } #endif From 0fb7c605080e926a4ff3a7b01337281d968148b5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 3 Dec 2013 16:11:46 +0100 Subject: [PATCH 1439/3781] encoder: rework GstVaapiCodedBuffer and related proxy. Refactor the GstVaapiCodedBuffer APIs so that to more clearly separate public and private interfaces. Besides, the map/unmap APIs should not be exposed as is but appropriate accessors should be provided instead. * GstVaapiCodedBuffer: VA coded buffer abstraction - gst_vaapi_coded_buffer_get_size(): get coded buffer size. - gst_vaapi_coded_buffer_copy_into(): copy coded buffer into GstBuffer * GstVaapiCodedBufferPool: pool of VA coded buffer objects - gst_vaapi_coded_buffer_pool_new(): create a pool of coded buffers of the specified max size, and bound to the supplied encoder * GstVaapiCodedBufferProxy: pool-allocated VA coded buffer object proxy - gst_vaapi_coded_buffer_proxy_new_from_pool(): create coded buf from pool - gst_vaapi_coded_buffer_proxy_get_buffer(): get underlying coded buffer - gst_vaapi_coded_buffer_proxy_get_buffer_size(): get coded buffer size Rationale: more optimized transfer functions might be provided in the future, thus rendering the map/unmap mechanism obsolete or sub-optimal. https://bugzilla.gnome.org/show_bug.cgi?id=719775 --- gst-libs/gst/vaapi/Makefile.am | 8 + gst-libs/gst/vaapi/gstvaapicodedbuffer.c | 232 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapicodedbuffer.h | 53 ++++ gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h | 78 ++++++ gst-libs/gst/vaapi/gstvaapicodedbufferpool.c | 113 ++++++++ gst-libs/gst/vaapi/gstvaapicodedbufferpool.h | 42 +++ gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c | 253 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h | 82 ++++++ .../gst/vaapi/gstvaapicodedbufferproxy_priv.h | 70 +++++ gst-libs/gst/vaapi/gstvaapiencoder.c | 203 +++----------- gst-libs/gst/vaapi/gstvaapiencoder.h | 5 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 11 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 11 +- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 102 ------- gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 46 ---- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 41 +-- gst-libs/gst/vaapi/gstvaapivideopool.h | 4 +- gst/vaapi/gstvaapiencode.c | 24 +- gst/vaapi/gstvaapiencode.h | 1 - gst/vaapi/gstvaapivideometa.c | 7 +- 20 files changed, 995 insertions(+), 391 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapicodedbuffer.c create mode 100644 gst-libs/gst/vaapi/gstvaapicodedbuffer.h create mode 100644 gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h create mode 100644 gst-libs/gst/vaapi/gstvaapicodedbufferpool.c create mode 100644 gst-libs/gst/vaapi/gstvaapicodedbufferpool.h create mode 100644 gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c create mode 100644 gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h create mode 100644 gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 0b5eb66f46..e402da0bd1 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -135,6 +135,9 @@ libgstvaapi_source_h += $(libgstvaapi_jpegdec_source_h) endif libgstvaapi_enc_source_c = \ + gstvaapicodedbuffer.c \ + gstvaapicodedbufferpool.c \ + gstvaapicodedbufferproxy.c \ gstvaapiencoder.c \ gstvaapiencoder_h264.c \ gstvaapiencoder_mpeg2.c \ @@ -142,12 +145,17 @@ libgstvaapi_enc_source_c = \ $(NULL) libgstvaapi_enc_source_h = \ + gstvaapicodedbuffer.h \ + gstvaapicodedbufferpool.h \ + gstvaapicodedbufferproxy.h \ gstvaapiencoder.h \ gstvaapiencoder_h264.h \ gstvaapiencoder_mpeg2.h \ $(NULL) libgstvaapi_enc_source_priv_h = \ + gstvaapicodedbuffer_priv.h \ + gstvaapicodedbufferpool_priv.h \ gstvaapiencoder_objects.h \ gstvaapiencoder_priv.h \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapicodedbuffer.c b/gst-libs/gst/vaapi/gstvaapicodedbuffer.c new file mode 100644 index 0000000000..acdc10632e --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicodedbuffer.c @@ -0,0 +1,232 @@ +/* + * gstvaapicodedbuffer.c - VA coded buffer abstraction + * + * Copyright (C) 2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne + * + * 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_OBJECT_DISPLAY (buf); + VABufferID buf_id; + gboolean success; + + GST_VAAPI_DISPLAY_LOCK (display); + success = vaapi_create_buffer (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_OBJECT_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_OBJECT_ID (buf) = buf_id; + return TRUE; +} + +static void +coded_buffer_destroy (GstVaapiCodedBuffer * buf) +{ + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (buf); + VABufferID buf_id; + + buf_id = GST_VAAPI_OBJECT_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_OBJECT_ID (buf) = VA_INVALID_ID; + } +} + +static gboolean +coded_buffer_map (GstVaapiCodedBuffer * buf) +{ + if (buf->segment_list) + return TRUE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (buf); + buf->segment_list = vaapi_map_buffer (GST_VAAPI_OBJECT_VADISPLAY (buf), + GST_VAAPI_OBJECT_ID (buf)); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (buf); + return buf->segment_list != NULL; +} + +static void +coded_buffer_unmap (GstVaapiCodedBuffer * buf) +{ + if (!buf->segment_list) + return; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (buf); + vaapi_unmap_buffer (GST_VAAPI_OBJECT_VADISPLAY (buf), + GST_VAAPI_OBJECT_ID (buf), (void **) &buf->segment_list); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (buf); +} + +#define gst_vaapi_coded_buffer_finalize coded_buffer_destroy +GST_VAAPI_OBJECT_DEFINE_CLASS (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_OBJECT_DISPLAY (context); + g_return_val_if_fail (display != NULL, NULL); + + buf = gst_vaapi_object_new (gst_vaapi_coded_buffer_class (), display); + if (!buf) + return NULL; + + if (!coded_buffer_create (buf, buf_size, context)) + goto error; + return buf; + +error: + gst_vaapi_object_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; +} diff --git a/gst-libs/gst/vaapi/gstvaapicodedbuffer.h b/gst-libs/gst/vaapi/gstvaapicodedbuffer.h new file mode 100644 index 0000000000..4980e9c3b3 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicodedbuffer.h @@ -0,0 +1,53 @@ +/* + * gstvaapicodedbuffer.h - VA coded buffer abstraction + * + * Copyright (C) 2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne + * + * 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; + +gssize +gst_vaapi_coded_buffer_get_size (GstVaapiCodedBuffer * buf); + +gboolean +gst_vaapi_coded_buffer_copy_into (GstBuffer * dest, GstVaapiCodedBuffer * src); + +G_END_DECLS + +#endif /* GST_VAAPI_CODED_BUFFER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h b/gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h new file mode 100644 index 0000000000..8d0de4d130 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h @@ -0,0 +1,78 @@ +/* + * gstvaapicodedbuffer_priv.h - VA coded buffer abstraction (private defs) + * + * Copyright (C) 2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne + * + * 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 +#include "gstvaapicodedbuffer.h" +#include "gstvaapiobject_priv.h" + +G_BEGIN_DECLS + +#define GST_VAAPI_CODED_BUFFER_CAST(obj) \ + ((GstVaapiCodedBuffer *)(obj)) + +typedef struct _GstVaapiCodedBufferClass GstVaapiCodedBufferClass; + +/** + * GstVaapiCodedBuffer: + * + * A VA coded buffer object wrapper. + */ +struct _GstVaapiCodedBuffer +{ + /*< private >*/ + GstVaapiObject parent_instance; + + GstVaapiContext *context; + VACodedBufferSegment *segment_list; +}; + +/** + * GstVaapiCodedBufferClass: + * + * A VA coded buffer object wrapper class. + */ +struct _GstVaapiCodedBufferClass +{ + /*< private >*/ + GstVaapiObjectClass parent_class; +}; + +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 */ diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c new file mode 100644 index 0000000000..c5a8acdefc --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c @@ -0,0 +1,113 @@ +/* + * gstvaapicodedbufferpool.c - VA coded buffer pool + * + * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_object_ref (context); + pool->buf_size = buf_size; +} + +static void +coded_buffer_pool_finalize (GstVaapiCodedBufferPool * pool) +{ + gst_vaapi_object_replace (&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_OBJECT_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; +} diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.h b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.h new file mode 100644 index 0000000000..3480d48677 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.h @@ -0,0 +1,42 @@ +/* + * gstvaapicodedbufferpool.h - VA coded buffer pool + * + * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 +#include + +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); + +G_END_DECLS + +#endif /* GST_VAAPI_CODED_BUFFER_POOL_H */ diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c new file mode 100644 index 0000000000..bf173ab971 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c @@ -0,0 +1,253 @@ +/* + * gstvaapicodedbufferproxy.c - VA coded buffer proxy + * + * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_object_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 (pool); + proxy->buffer = gst_vaapi_video_pool_get_object (proxy->pool); + if (!proxy->buffer) + goto error; + gst_vaapi_object_ref (proxy->buffer); + return proxy; + +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); +} diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h new file mode 100644 index 0000000000..4968c63075 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h @@ -0,0 +1,82 @@ +/* + * gstvaapicodedbufferproxy_priv.h - VA coded buffer proxy + * + * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 +#include + +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 */ diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h new file mode 100644 index 0000000000..6feb8f9c82 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h @@ -0,0 +1,70 @@ +/* + * gstvaapicodedbufferproxy_priv.h - VA coded buffer proxy (private defs) + * + * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 519e8f7f18..61f063a625 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -28,8 +28,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiCodedBufferProxyClass GstVaapiCodedBufferProxyClass; - #define GST_VAAPI_ENCODER_LOCK(encoder) \ G_STMT_START { \ g_mutex_lock (&(GST_VAAPI_ENCODER_CAST(encoder))->lock); \ @@ -74,100 +72,12 @@ GST_VAAPI_ENCODER_SYNC_WAIT_TIMEOUT (GstVaapiEncoder * encoder, gint64 timeout) return g_cond_wait_until (&encoder->sync_ready, &encoder->lock, end_time); } -static GstVaapiCodedBuffer * -gst_vaapi_encoder_dequeue_coded_buffer (GstVaapiEncoder * encoder); - -static void -gst_vaapi_encoder_queue_coded_buffer (GstVaapiEncoder * encoder, - GstVaapiCodedBuffer * buf); - typedef struct { GstVaapiEncPicture *picture; GstVaapiCodedBufferProxy *buf; } GstVaapiEncoderSyncPic; -static void -gst_vaapi_coded_buffer_proxy_finalize (GstVaapiCodedBufferProxy * proxy) -{ - if (proxy->buffer) { - gst_vaapi_coded_buffer_unmap (proxy->buffer); - if (proxy->encoder) - gst_vaapi_encoder_queue_coded_buffer (proxy->encoder, proxy->buffer); - else { - g_assert (FALSE); - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (proxy->buffer)); - } - proxy->buffer = NULL; - } - gst_vaapi_encoder_replace (&proxy->encoder, NULL); -} - -static void -gst_vaapi_coded_buffer_proxy_class_init (GstVaapiCodedBufferProxyClass * klass) -{ - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); - - object_class->size = sizeof (GstVaapiCodedBufferProxy); - object_class->finalize = - (GDestroyNotify) gst_vaapi_coded_buffer_proxy_finalize; -} - -static inline const GstVaapiCodedBufferProxyClass * -gst_vaapi_coded_buffer_proxy_class (void) -{ - static GstVaapiCodedBufferProxyClass g_class; - static gsize g_class_init = FALSE; - - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_coded_buffer_proxy_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return (&g_class); -} - -GstVaapiCodedBufferProxy * -gst_vaapi_coded_buffer_proxy_new (GstVaapiEncoder * encoder) -{ - GstVaapiCodedBuffer *buf; - GstVaapiCodedBufferProxy *ret; - - g_assert (encoder); - buf = gst_vaapi_encoder_dequeue_coded_buffer (encoder); - if (!buf) - return NULL; - - ret = (GstVaapiCodedBufferProxy *) - gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS - (gst_vaapi_coded_buffer_proxy_class ())); - g_assert (ret); - ret->encoder = gst_vaapi_encoder_ref (encoder); - ret->buffer = buf; - return ret; -} - -GstVaapiCodedBufferProxy * -gst_vaapi_coded_buffer_proxy_ref (GstVaapiCodedBufferProxy * proxy) -{ - return (GstVaapiCodedBufferProxy *) - gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (proxy)); -} - -void -gst_vaapi_coded_buffer_proxy_unref (GstVaapiCodedBufferProxy * proxy) -{ - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (proxy)); -} - -void -gst_vaapi_coded_buffer_proxy_replace (GstVaapiCodedBufferProxy ** old_proxy_ptr, - GstVaapiCodedBufferProxy * new_proxy) -{ - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_proxy_ptr, - GST_VAAPI_MINI_OBJECT (new_proxy)); -} - GstVaapiEncoder * gst_vaapi_encoder_ref (GstVaapiEncoder * encoder) { @@ -187,90 +97,38 @@ gst_vaapi_encoder_replace (GstVaapiEncoder ** old_encoder_ptr, gst_vaapi_object_replace (old_encoder_ptr, new_encoder); } -static gboolean -gst_vaapi_encoder_init_coded_buffer_queue (GstVaapiEncoder * encoder, - guint count) -{ - GstVaapiCodedBuffer *buf; - guint i = 0; - - GST_VAAPI_ENCODER_LOCK (encoder); - if (count > encoder->max_buf_num) - count = encoder->max_buf_num; - - g_assert (encoder->buf_size); - for (i = 0; i < count; ++i) { - buf = GST_VAAPI_CODED_BUFFER_NEW (encoder, encoder->buf_size); - g_queue_push_tail (&encoder->coded_buffers, buf); - ++encoder->buf_count; - } - g_assert (encoder->buf_count <= encoder->max_buf_num); - - GST_VAAPI_ENCODER_UNLOCK (encoder); - return TRUE; -} - -static GstVaapiCodedBuffer * -gst_vaapi_encoder_dequeue_coded_buffer (GstVaapiEncoder * encoder) -{ - GstVaapiCodedBuffer *ret = NULL; - - GST_VAAPI_ENCODER_LOCK (encoder); - while (encoder->buf_count >= encoder->max_buf_num && - g_queue_is_empty (&encoder->coded_buffers)) { - GST_VAAPI_ENCODER_BUF_FREE_WAIT (encoder); - } - if (!g_queue_is_empty (&encoder->coded_buffers)) { - ret = (GstVaapiCodedBuffer *) g_queue_pop_head (&encoder->coded_buffers); - goto end; - } - - g_assert (encoder->buf_size); - ret = GST_VAAPI_CODED_BUFFER_NEW (encoder, encoder->buf_size); - if (ret) - ++encoder->buf_count; - -end: - GST_VAAPI_ENCODER_UNLOCK (encoder); - return ret; -} - static void -gst_vaapi_encoder_queue_coded_buffer (GstVaapiEncoder * encoder, - GstVaapiCodedBuffer * buf) +_coded_buffer_proxy_released_notify (GstVaapiEncoder * encoder) { - g_assert (buf); - g_return_if_fail (buf); - GST_VAAPI_ENCODER_LOCK (encoder); - g_queue_push_tail (&encoder->coded_buffers, buf); GST_VAAPI_ENCODER_BUF_FREE_SIGNAL (encoder); GST_VAAPI_ENCODER_UNLOCK (encoder); } -static gboolean -gst_vaapi_encoder_free_coded_buffers (GstVaapiEncoder * encoder) +static GstVaapiCodedBufferProxy * +gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder) { - GstVaapiCodedBuffer *buf; - guint count = 0; - gboolean ret; + GstVaapiCodedBufferPool *const pool = + GST_VAAPI_CODED_BUFFER_POOL (encoder->codedbuf_pool); + GstVaapiCodedBufferProxy *codedbuf_proxy; GST_VAAPI_ENCODER_LOCK (encoder); - while (!g_queue_is_empty (&encoder->coded_buffers)) { - buf = (GstVaapiCodedBuffer *) g_queue_pop_head (&encoder->coded_buffers); - g_assert (buf); - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (buf)); - ++count; - } - ret = (count == encoder->buf_count); + do { + codedbuf_proxy = gst_vaapi_coded_buffer_proxy_new_from_pool (pool); + if (codedbuf_proxy) + break; + + /* Wait for a free coded buffer to become available */ + GST_VAAPI_ENCODER_BUF_FREE_WAIT (encoder); + codedbuf_proxy = gst_vaapi_coded_buffer_proxy_new_from_pool (pool); + } while (0); GST_VAAPI_ENCODER_UNLOCK (encoder); + if (!codedbuf_proxy) + return NULL; - if (!ret) { - GST_ERROR ("coded buffer leak, freed count:%d, total buf:%d", - count, encoder->buf_count); - } - - return ret; + gst_vaapi_coded_buffer_proxy_set_destroy_notify (codedbuf_proxy, + (GDestroyNotify)_coded_buffer_proxy_released_notify, encoder); + return codedbuf_proxy; } static void @@ -343,7 +201,9 @@ gst_vaapi_encoder_free_sync_pictures (GstVaapiEncoder * encoder) while (!g_queue_is_empty (&encoder->sync_pictures)) { sync = (GstVaapiEncoderSyncPic *) g_queue_pop_head (&encoder->sync_pictures); + GST_VAAPI_ENCODER_UNLOCK (encoder); _free_sync_picture (encoder, sync); + GST_VAAPI_ENCODER_LOCK (encoder); } GST_VAAPI_ENCODER_UNLOCK (encoder); } @@ -420,7 +280,7 @@ again: goto error; } - coded_buf = gst_vaapi_coded_buffer_proxy_new (encoder); + coded_buf = gst_vaapi_encoder_create_coded_buffer (encoder); if (!coded_buf) { ret = GST_VAAPI_ENCODER_STATUS_OBJECT_ERR; goto error; @@ -577,13 +437,16 @@ gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, if (!gst_vaapi_encoder_ensure_context (encoder)) goto error; - encoder->buf_size = (GST_VAAPI_ENCODER_WIDTH (encoder) * + encoder->codedbuf_size = (GST_VAAPI_ENCODER_WIDTH (encoder) * GST_VAAPI_ENCODER_HEIGHT (encoder) * 400) / (16 * 16); - if (!gst_vaapi_encoder_init_coded_buffer_queue (encoder, 5)) { - GST_ERROR ("encoder init coded buffer failed"); + encoder->codedbuf_pool = gst_vaapi_coded_buffer_pool_new (encoder, + encoder->codedbuf_size); + if (!encoder->codedbuf_pool) { + GST_ERROR ("failed to initialized coded buffer pool"); goto error; } + gst_vaapi_video_pool_set_capacity (encoder->codedbuf_pool, 5); return out_caps; @@ -613,14 +476,9 @@ gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) gst_video_info_init (&encoder->video_info); - encoder->buf_count = 0; - encoder->max_buf_num = 10; - encoder->buf_size = 0; - g_mutex_init (&encoder->lock); g_cond_init (&encoder->codedbuf_free); g_cond_init (&encoder->surface_free); - g_queue_init (&encoder->coded_buffers); g_queue_init (&encoder->sync_pictures); g_cond_init (&encoder->sync_ready); @@ -637,8 +495,8 @@ gst_vaapi_encoder_destroy (GstVaapiEncoder * encoder) if (klass->destroy) klass->destroy (encoder); - gst_vaapi_encoder_free_coded_buffers (encoder); gst_vaapi_encoder_free_sync_pictures (encoder); + gst_vaapi_video_pool_replace (&encoder->codedbuf_pool, NULL); gst_vaapi_object_replace (&encoder->context, NULL); gst_vaapi_display_replace (&encoder->display, NULL); @@ -646,7 +504,6 @@ gst_vaapi_encoder_destroy (GstVaapiEncoder * encoder) g_mutex_clear (&encoder->lock); g_cond_clear (&encoder->codedbuf_free); g_cond_clear (&encoder->surface_free); - g_queue_clear (&encoder->coded_buffers); g_queue_clear (&encoder->sync_pictures); g_cond_clear (&encoder->sync_ready); } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 1779b59a13..8741c9a752 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -22,10 +22,8 @@ #ifndef GST_VAAPI_ENCODER_H #define GST_VAAPI_ENCODER_H -#include #include -#include -#include +#include G_BEGIN_DECLS @@ -49,7 +47,6 @@ typedef enum } GstVaapiEncoderStatus; typedef struct _GstVaapiEncoder GstVaapiEncoder; -typedef struct _GstVaapiCodedBufferProxy GstVaapiCodedBufferProxy; #define GST_VAAPI_ENCODER(encoder) \ ((GstVaapiEncoder *)(encoder)) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 818bdf735c..a7fa921c28 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -24,6 +24,7 @@ #include "gstvaapiencoder_h264.h" #include "gstvaapiencoder_h264_priv.h" #include "gstvaapiencoder_priv.h" +#include "gstvaapicodedbufferproxy_priv.h" #include #include @@ -948,7 +949,7 @@ fill_va_picture_param (GstVaapiEncoderH264 * encoder, for (; i < 16; ++i) { pic->ReferenceFrames[i].picture_id = VA_INVALID_ID; } - pic->coded_buf = codedbuf->buf_id; + pic->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); pic->pic_parameter_set_id = 0; pic->seq_parameter_set_id = 0; @@ -1148,11 +1149,11 @@ error: } static gboolean -ensure_picture (GstVaapiEncoderH264 * encoder, - GstVaapiEncPicture * picture, - GstVaapiCodedBufferProxy * buf_proxy, GstVaapiSurfaceProxy * surface) +ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, + GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) { - GstVaapiCodedBuffer *codedbuf = buf_proxy->buffer; + GstVaapiCodedBuffer *const codedbuf = + GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); if (!fill_va_picture_param (encoder, picture, codedbuf, surface)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 4b5ae8ea57..70decdb33c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -25,6 +25,7 @@ #include "gstvaapiencoder_mpeg2.h" #include "gstvaapiencoder_mpeg2_priv.h" #include "gstvaapiencoder_priv.h" +#include "gstvaapicodedbufferproxy_priv.h" #include #include @@ -228,7 +229,7 @@ fill_picture (GstVaapiEncoderMpeg2 * encoder, memset (pic, 0, sizeof (VAEncPictureParameterBufferMPEG2)); pic->reconstructed_picture = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); - pic->coded_buf = codedbuf->buf_id; + pic->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); pic->picture_type = get_va_enc_picture_type (picture->type); pic->temporal_reference = picture->frame_num & (1024 - 1); pic->vbv_delay = 0xFFFF; @@ -385,11 +386,11 @@ error: } static gboolean -ensure_picture (GstVaapiEncoderMpeg2 * encoder, - GstVaapiEncPicture * picture, - GstVaapiCodedBufferProxy * buf_proxy, GstVaapiSurfaceProxy * surface) +ensure_picture (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture, + GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) { - GstVaapiCodedBuffer *codedbuf = buf_proxy->buffer; + GstVaapiCodedBuffer *const codedbuf = + GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); if (!fill_picture (encoder, picture, codedbuf, surface)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index 2a6173625a..5f730e36c3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -35,108 +35,6 @@ #define GET_VA_DISPLAY(obj) GST_VAAPI_ENCODER_VA_DISPLAY(GET_ENCODER(obj)) #define GET_VA_CONTEXT(obj) GST_VAAPI_ENCODER_VA_CONTEXT(GET_ENCODER(obj)) -/* ------------------------------------------------------------------------- */ -/* --- Encoder Coded Data --- */ -/* ------------------------------------------------------------------------- */ - -GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiCodedBuffer, gst_vaapi_coded_buffer); - -void -gst_vaapi_coded_buffer_destroy (GstVaapiCodedBuffer * buffer) -{ - gst_vaapi_coded_buffer_unmap (buffer); - vaapi_destroy_buffer (GET_VA_DISPLAY (buffer), &buffer->buf_id); - buffer->segment_list = NULL; -} - -gboolean -gst_vaapi_coded_buffer_create (GstVaapiCodedBuffer * codec_buffer, - const GstVaapiCodecObjectConstructorArgs * args) -{ - codec_buffer->buf_id = VA_INVALID_ID; - codec_buffer->segment_list = NULL; - return vaapi_create_buffer (GET_VA_DISPLAY (codec_buffer), - GET_VA_CONTEXT (codec_buffer), - VAEncCodedBufferType, - args->param_size, args->param, &codec_buffer->buf_id, NULL); -} - -GstVaapiCodedBuffer * -gst_vaapi_coded_buffer_new (GstVaapiEncoder * encoder, - gconstpointer param, guint param_size) -{ - GstVaapiCodecObject *object; - - object = gst_vaapi_codec_object_new (&GstVaapiCodedBufferClass, - GST_VAAPI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); - if (!object) - return NULL; - return GST_VAAPI_CODED_BUFFER_CAST (object); -} - -gboolean -gst_vaapi_coded_buffer_map (GstVaapiCodedBuffer * buf, void **data) -{ - g_return_val_if_fail (buf->buf_id != VA_INVALID_ID, FALSE); - - if (buf->segment_list) - goto end; - buf->segment_list = vaapi_map_buffer (GET_VA_DISPLAY (buf), buf->buf_id); - if (!buf->segment_list) - return FALSE; -end: - if (data) - *data = buf->segment_list; - return TRUE; -} - -void -gst_vaapi_coded_buffer_unmap (GstVaapiCodedBuffer * buf) -{ - if (buf->buf_id != VA_INVALID_ID && buf->segment_list) - vaapi_unmap_buffer (GET_VA_DISPLAY (buf), - buf->buf_id, (void **) (&buf->segment_list)); -} - -gint32 -gst_vaapi_coded_buffer_get_size (GstVaapiCodedBuffer * buf) -{ - gint32 size; - VACodedBufferSegment *segment; - if (!gst_vaapi_coded_buffer_map (buf, NULL)) - return -1; - - size = 0; - segment = buf->segment_list; - while (segment) { - size += segment->size; - segment = (VACodedBufferSegment *) segment->next; - } - return size; -} - -gboolean -gst_vaapi_coded_buffer_get_buffer (GstVaapiCodedBuffer * buf, - GstBuffer * output) -{ - gint32 offset; - VACodedBufferSegment *segment; - - g_assert (output); - g_return_val_if_fail (output, FALSE); - - offset = 0; - segment = buf->segment_list; - while (segment) { - if (gst_buffer_fill (output, offset, segment->buf, segment->size) - != segment->size) - return FALSE; - offset += segment->size; - segment = (VACodedBufferSegment *) segment->next; - } - return TRUE; -} - /* ------------------------------------------------------------------------- */ /* --- Encoder Packed Header --- */ /* ------------------------------------------------------------------------- */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index fdc960ee24..d57ad5080b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -35,52 +35,6 @@ typedef struct _GstVaapiEncSlice GstVaapiEncSlice; typedef struct _GstVaapiCodedBuffer GstVaapiCodedBuffer; typedef struct _GstVaapiEncPackedHeader GstVaapiEncPackedHeader; -/* ------------------------------------------------------------------------- */ -/* --- Encoder Coded Buffer --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_CODED_BUFFER_CAST(obj) \ - ((GstVaapiCodedBuffer *)(obj)) - -#define GST_VAAPI_CODED_BUFFER(obj) \ - GST_VAAPI_CODED_BUFFER_CAST(obj) - -#define GST_VAAPI_IS_CODED_BUFFER(obj) \ - (GST_VAAPI_CODED_BUFFER(obj) != NULL) - -/** - * GstVaapiCodedBuffer: - * - * A #GstVaapiCodecObject holding an encoded buffer. - */ -struct _GstVaapiCodedBuffer -{ - /*< private > */ - GstVaapiCodecObject parent_instance; - VABufferID buf_id; - - /*< public > */ - VACodedBufferSegment *segment_list; -}; - -G_GNUC_INTERNAL -GstVaapiCodedBuffer * -gst_vaapi_coded_buffer_new (GstVaapiEncoder * encoder, - gconstpointer param, guint param_size); - -gboolean -gst_vaapi_coded_buffer_map (GstVaapiCodedBuffer * buf, void **data); - -void -gst_vaapi_coded_buffer_unmap (GstVaapiCodedBuffer * buf); - -gint32 -gst_vaapi_coded_buffer_get_size (GstVaapiCodedBuffer * buf); - -gboolean -gst_vaapi_coded_buffer_get_buffer (GstVaapiCodedBuffer * buf, - GstBuffer * output); - /* ------------------------------------------------------------------------- */ /* --- Encoder Packed Header --- */ /* ------------------------------------------------------------------------- */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 71fff0cd92..8b78ac9509 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -25,6 +25,7 @@ #include #include #include +#include #include G_BEGIN_DECLS @@ -75,7 +76,6 @@ G_BEGIN_DECLS goto end; \ } -typedef struct _GstVaapiCodedBufferProxyClass GstVaapiCodedBufferProxyClass; typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass; struct _GstVaapiEncoder @@ -92,13 +92,11 @@ struct _GstVaapiEncoder GstVideoInfo video_info; GstVaapiRateControl rate_control; - guint buf_count; - guint max_buf_num; - guint buf_size; GMutex lock; - GCond codedbuf_free; GCond surface_free; - GQueue coded_buffers; + GCond codedbuf_free; + guint codedbuf_size; + GstVaapiVideoPool *codedbuf_pool; /* queue for sync */ GQueue sync_pictures; @@ -134,21 +132,6 @@ struct _GstVaapiEncoderClass GstBuffer ** codec_data); }; -struct _GstVaapiCodedBufferProxy -{ - /*< private >*/ - GstVaapiMiniObject parent_instance; - GstVaapiEncoder *encoder; - - /*< public >*/ - GstVaapiCodedBuffer *buffer; -}; - -struct _GstVaapiCodedBufferProxyClass -{ - GstVaapiMiniObjectClass parent_class; -}; - void gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass); @@ -167,22 +150,6 @@ void gst_vaapi_encoder_release_surface (GstVaapiEncoder * encoder, GstVaapiSurfaceProxy * surface); -/* ------------------ GstVaapiCodedBufferProxy ---------------------------- */ - -GstVaapiCodedBufferProxy * -gst_vaapi_coded_buffer_proxy_new (GstVaapiEncoder * - encoder); - -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); - G_END_DECLS #endif /* GST_VAAPI_ENCODER_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 1942d6259a..84210edd5b 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -39,12 +39,14 @@ typedef struct _GstVaapiVideoPool GstVaapiVideoPool; * GstVaapiVideoPoolObjectType: * @GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE: #GstVaapiImage objects. * @GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE: #GstVaapiSurface objects. + * @GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER: #GstVaapiCodedBuffer objects. * * The set of all supported #GstVaapiVideoPool object types. */ typedef enum { GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE = 1, - GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE, + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER } GstVaapiVideoPoolObjectType; GstVaapiVideoPool * diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index c3b2f554a8..adb24741f1 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -22,8 +22,6 @@ #include "gst/vaapi/sysdeps.h" #include #include -#include -#include #include "gstvaapiencode.h" #include "gstvaapivideocontext.h" #include "gstvaapipluginutil.h" @@ -182,9 +180,6 @@ gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode, g_return_val_if_fail (coded_buf != NULL, GST_FLOW_ERROR); g_return_val_if_fail (outbuf_ptr != NULL, GST_FLOW_ERROR); - if (!gst_vaapi_coded_buffer_map (coded_buf, NULL)) - return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; - buf_size = gst_vaapi_coded_buffer_get_size (coded_buf); if (buf_size <= 0) goto error_invalid_buffer; @@ -198,10 +193,9 @@ gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode, #endif if (!buf) goto error_create_buffer; - if (!gst_vaapi_coded_buffer_get_buffer (coded_buf, buf)) + if (!gst_vaapi_coded_buffer_copy_into (buf, coded_buf)) goto error_copy_buffer; - gst_vaapi_coded_buffer_unmap (coded_buf); *outbuf_ptr = buf; return GST_FLOW_OK; @@ -209,20 +203,17 @@ gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode, error_invalid_buffer: { GST_ERROR ("invalid GstVaapiCodedBuffer size (%d)", buf_size); - gst_vaapi_coded_buffer_unmap (coded_buf); return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; } error_create_buffer: { GST_ERROR ("failed to create output buffer of size %d", buf_size); - gst_vaapi_coded_buffer_unmap (coded_buf); return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; } error_copy_buffer: { GST_ERROR ("failed to copy GstVaapiCodedBuffer data"); gst_buffer_unref (buf); - gst_vaapi_coded_buffer_unmap (coded_buf); return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; } } @@ -233,13 +224,13 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) GstVideoEncoder *const venc = GST_VIDEO_ENCODER_CAST (encode); GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (encode); GstVideoCodecFrame *out_frame = NULL; - GstVaapiCodedBufferProxy *coded_buf_proxy = NULL; + GstVaapiCodedBufferProxy *codedbuf_proxy = NULL; GstVaapiEncoderStatus status; GstBuffer *out_buffer; GstFlowReturn ret; status = gst_vaapi_encoder_get_buffer (encode->encoder, - &out_frame, &coded_buf_proxy, timeout); + &out_frame, &codedbuf_proxy, timeout); if (status == GST_VAAPI_ENCODER_STATUS_TIMEOUT) return GST_VAAPI_ENCODE_FLOW_TIMEOUT; if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) @@ -249,8 +240,9 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) /* Allocate and copy buffer into system memory */ out_buffer = NULL; - ret = klass->allocate_buffer (encode, coded_buf_proxy->buffer, &out_buffer); - gst_vaapi_coded_buffer_proxy_replace (&coded_buf_proxy, NULL); + ret = klass->allocate_buffer (encode, + GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy), &out_buffer); + gst_vaapi_coded_buffer_proxy_replace (&codedbuf_proxy, NULL); if (ret != GST_FLOW_OK) goto error_allocate_buffer; @@ -297,8 +289,8 @@ error_get_buffer: GST_ERROR ("failed to get encoded buffer (status %d)", status); if (out_frame) gst_video_codec_frame_unref (out_frame); - if (coded_buf_proxy) - gst_vaapi_coded_buffer_proxy_unref (coded_buf_proxy); + if (codedbuf_proxy) + gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); return GST_FLOW_ERROR; } error_allocate_buffer: diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 6d59980db5..09a97c730d 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -25,7 +25,6 @@ #include #include #include -#include "gst/vaapi/gstvaapiencoder_objects.h" #include "gstvaapiuploader.h" G_BEGIN_DECLS diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index b1d2462602..7b4bc2d834 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -282,6 +282,7 @@ GstVaapiVideoMeta * gst_vaapi_video_meta_new_from_pool(GstVaapiVideoPool *pool) { GstVaapiVideoMeta *meta; + GstVaapiVideoPoolObjectType object_type; g_return_val_if_fail(pool != NULL, NULL); @@ -289,7 +290,8 @@ gst_vaapi_video_meta_new_from_pool(GstVaapiVideoPool *pool) if (G_UNLIKELY(!meta)) return NULL; - switch (gst_vaapi_video_pool_get_object_type(pool)) { + object_type = gst_vaapi_video_pool_get_object_type(pool); + switch (object_type) { case GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE: if (!set_image_from_pool(meta, pool)) goto error; @@ -298,6 +300,9 @@ gst_vaapi_video_meta_new_from_pool(GstVaapiVideoPool *pool) if (!set_surface_proxy_from_pool(meta, pool)) goto error; break; + default: + GST_ERROR("unsupported video buffer pool of type %d", object_type); + goto error; } set_display(meta, gst_vaapi_video_pool_get_display(pool)); return meta; From 8ecc35ecf203397d35c402083893f934345c99ff Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 4 Dec 2013 11:54:40 +0100 Subject: [PATCH 1440/3781] encoder: fix subclassing process. Fix the GstVaapiEncoderClass parent class type. Make sure to validate subclass hooks as early as possible, i.e. in gst_vaapi_encoder_init(), thus avoiding useless run-time checks. Also simplify the subclass initialization process to be less error prone. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 77 +++++++------------ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 38 ++------- .../gst/vaapi/gstvaapiencoder_h264_priv.h | 14 ---- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 34 ++------ .../gst/vaapi/gstvaapiencoder_mpeg2_priv.h | 14 ---- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 26 ++++++- 6 files changed, 63 insertions(+), 140 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 61f063a625..adb5b2cdb3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -261,9 +261,6 @@ gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, GstVaapiCodedBufferProxy *coded_buf = NULL; GstVaapiEncoderSyncPic *sync_pic = NULL; - if (!klass->reordering || !klass->encode) - goto error; - again: picture = NULL; sync_pic = NULL; @@ -350,18 +347,9 @@ end: GstVaapiEncoderStatus gst_vaapi_encoder_flush (GstVaapiEncoder * encoder) { - GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); - if (!klass->flush) - goto error; - - ret = klass->flush (encoder); - return ret; - -error: - GST_ERROR ("flush failed"); - return GST_VAAPI_ENCODER_STATUS_FUNC_PTR_ERR; + return klass->flush (encoder); } GstVaapiEncoderStatus @@ -390,9 +378,8 @@ gst_vaapi_encoder_ensure_context (GstVaapiEncoder * encoder) return TRUE; memset (&info, 0, sizeof (info)); - if (!klass->get_context_info || !klass->get_context_info (encoder, &info)) { + if (!klass->get_context_info (encoder, &info)) return FALSE; - } context = gst_vaapi_context_new_full (GST_VAAPI_ENCODER_DISPLAY (encoder), &info); @@ -418,9 +405,6 @@ gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, } GST_VAAPI_ENCODER_VIDEO_INFO (encoder) = in_state->info; - if (!klass->set_format) - goto error; - out_caps = klass->set_format (encoder, in_state, ref_caps); if (!out_caps) goto error; @@ -460,19 +444,28 @@ error: static gboolean gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) { - GstVaapiEncoderClass *kclass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); - g_assert (kclass); - g_assert (display); + g_return_val_if_fail (display != NULL, FALSE); - g_return_val_if_fail (display, FALSE); - g_return_val_if_fail (encoder->display == NULL, FALSE); +#define CHECK_VTABLE_HOOK(FUNC) do { \ + if (!klass->FUNC) \ + goto error_invalid_vtable; \ + } while (0) + + CHECK_VTABLE_HOOK (init); + CHECK_VTABLE_HOOK (finalize); + CHECK_VTABLE_HOOK (encode); + CHECK_VTABLE_HOOK (reordering); + CHECK_VTABLE_HOOK (flush); + CHECK_VTABLE_HOOK (get_context_info); + CHECK_VTABLE_HOOK (set_format); + +#undef CHECK_VTABLE_HOOK encoder->display = gst_vaapi_display_ref (display); encoder->va_display = gst_vaapi_display_get_display (display); - encoder->context = NULL; encoder->va_context = VA_INVALID_ID; - encoder->caps = NULL; gst_video_info_init (&encoder->video_info); @@ -482,18 +475,22 @@ gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) g_queue_init (&encoder->sync_pictures); g_cond_init (&encoder->sync_ready); - if (kclass->init) - return kclass->init (encoder); - return TRUE; + return klass->init (encoder); + + /* ERRORS */ +error_invalid_vtable: + { + GST_ERROR ("invalid subclass hook (internal error)"); + return FALSE; + } } -static void -gst_vaapi_encoder_destroy (GstVaapiEncoder * encoder) +void +gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); - if (klass->destroy) - klass->destroy (encoder); + klass->finalize (encoder); gst_vaapi_encoder_free_sync_pictures (encoder); gst_vaapi_video_pool_replace (&encoder->codedbuf_pool, NULL); @@ -508,22 +505,6 @@ gst_vaapi_encoder_destroy (GstVaapiEncoder * encoder) g_cond_clear (&encoder->sync_ready); } -void -gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) -{ - gst_vaapi_encoder_destroy (encoder); -} - -void -gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) -{ - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); - - object_class->size = sizeof (GstVaapiEncoder); - object_class->finalize = (GDestroyNotify) gst_vaapi_encoder_finalize; -} - GstVaapiEncoder * gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass, GstVaapiDisplay * display) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index a7fa921c28..01546dafba 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1711,10 +1711,10 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base) } static void -gst_vaapi_encoder_h264_destroy (GstVaapiEncoder * base) +gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base) { /*free private buffers */ - GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base); + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base); GstVaapiEncPicture *pic; GstVaapiEncoderH264Ref *ref; @@ -1736,38 +1736,14 @@ gst_vaapi_encoder_h264_destroy (GstVaapiEncoder * base) } -static void -gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) -{ - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); - GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass); - - gst_vaapi_encoder_class_init (encoder_class); - - object_class->size = sizeof (GstVaapiEncoderH264); - - encoder_class->init = gst_vaapi_encoder_h264_init; - encoder_class->destroy = gst_vaapi_encoder_h264_destroy; - encoder_class->set_format = gst_vaapi_encoder_h264_set_format; - encoder_class->get_context_info = gst_vaapi_encoder_h264_get_context_info; - encoder_class->reordering = gst_vaapi_encoder_h264_reordering; - encoder_class->encode = gst_vaapi_encoder_h264_encode; - encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data; - encoder_class->flush = gst_vaapi_encoder_h264_flush; -} - static inline const GstVaapiEncoderClass * gst_vaapi_encoder_h264_class () { - static GstVaapiEncoderH264Class g_class; - static gsize g_class_init = FALSE; - - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_encoder_h264_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_ENCODER_CLASS (&g_class); + static const GstVaapiEncoderClass GstVaapiEncoderH264Class = { + GST_VAAPI_ENCODER_CLASS_INIT (H264, h264), + .get_codec_data = gst_vaapi_encoder_h264_get_codec_data + }; + return &GstVaapiEncoderH264Class; } GstVaapiEncoder * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h index a7027ae913..3a60a6fc39 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h @@ -33,14 +33,6 @@ G_BEGIN_DECLS ((GstVaapiEncoderH264 *)(encoder)) #define GST_VAAPI_ENCODER_H264_CAST(encoder) \ ((GstVaapiEncoderH264 *)(encoder)) -#define GST_VAAPI_ENCODER_H264_CLASS(klass) \ - ((GstVaapiEncoderH264Class *)(klass)) -#define GST_IS_VAAPI_ENCODER_H264_CLASS(klass) \ - ((klass) != NULL) -#define GST_VAAPI_ENCODER_H264_GET_CLASS(obj) \ - GST_VAAPI_ENCODER_H264_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) - -typedef struct _GstVaapiEncoderH264Class GstVaapiEncoderH264Class; typedef enum { @@ -115,12 +107,6 @@ struct _GstVaapiEncoderH264 }; -struct _GstVaapiEncoderH264Class -{ - /*< private > */ - GstVaapiEncoderClass parent_class; -}; - G_END_DECLS #endif /*GST_VAAPI_ENCODER_H264_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 70decdb33c..10de5875f6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -741,7 +741,7 @@ push_reference (GstVaapiEncoderMpeg2 * encoder, GstVaapiSurfaceProxy * ref) } static void -gst_vaapi_encoder_mpeg2_destroy (GstVaapiEncoder * base) +gst_vaapi_encoder_mpeg2_finalize (GstVaapiEncoder * base) { /*free private buffers */ GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); @@ -756,37 +756,13 @@ gst_vaapi_encoder_mpeg2_destroy (GstVaapiEncoder * base) g_queue_clear (&encoder->b_frames); } -static void -gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass) -{ - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); - GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass); - - gst_vaapi_encoder_class_init (encoder_class); - - object_class->size = sizeof (GstVaapiEncoderMpeg2); - - encoder_class->init = gst_vaapi_encoder_mpeg2_init; - encoder_class->destroy = gst_vaapi_encoder_mpeg2_destroy; - encoder_class->set_format = gst_vaapi_encoder_mpeg2_set_format; - encoder_class->get_context_info = gst_vaapi_encoder_mpeg2_get_context_info; - encoder_class->reordering = gst_vaapi_encoder_mpeg2_reordering; - encoder_class->encode = gst_vaapi_encoder_mpeg2_encode; - encoder_class->flush = gst_vaapi_encoder_mpeg2_flush; -} - static inline const GstVaapiEncoderClass * gst_vaapi_encoder_mpeg2_class () { - static GstVaapiEncoderMpeg2Class g_class; - static gsize g_class_init = FALSE; - - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_encoder_mpeg2_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_ENCODER_CLASS (&g_class); + static const GstVaapiEncoderClass GstVaapiEncoderMpeg2Class = { + GST_VAAPI_ENCODER_CLASS_INIT (Mpeg2, mpeg2), + }; + return &GstVaapiEncoderMpeg2Class; } GstVaapiEncoder * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h index c5da350e89..ff20dbe5a1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h @@ -32,14 +32,6 @@ G_BEGIN_DECLS ((GstVaapiEncoderMpeg2 *)(encoder)) #define GST_VAAPI_ENCODER_MPEG2_CAST(encoder) \ ((GstVaapiEncoderMpeg2 *)(encoder)) -#define GST_VAAPI_ENCODER_MPEG2_CLASS(klass) \ - ((GstVaapiEncoderMpeg2Class *)(klass)) -#define GST_IS_VAAPI_ENCODER_MPEG2_CLASS(klass) \ - ((klass) != NULL) -#define GST_VAAPI_ENCODER_MPEG2_GET_CLASS(obj) \ - GST_VAAPI_ENCODER_MPEG2_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) - -typedef struct _GstVaapiEncoderMpeg2Class GstVaapiEncoderMpeg2Class; typedef enum { @@ -105,12 +97,6 @@ struct _GstVaapiEncoderMpeg2 guint32 frame_num; /* same value picture header, but it's not mod by 1024 */ }; -struct _GstVaapiEncoderMpeg2Class -{ - /*< private > */ - GstVaapiEncoderClass parent_class; -}; - G_END_DECLS #endif /* GST_VAAPI_ENCODER_MPEG2_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 8b78ac9509..e18fe58829 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -105,10 +105,10 @@ struct _GstVaapiEncoder struct _GstVaapiEncoderClass { - GObjectClass parent_class; + GstVaapiMiniObjectClass parent_class; gboolean (*init) (GstVaapiEncoder * encoder); - void (*destroy) (GstVaapiEncoder * encoder); + void (*finalize) (GstVaapiEncoder * encoder); GstCaps * (*set_format) (GstVaapiEncoder * encoder, GstVideoCodecState * in_state, @@ -132,13 +132,31 @@ struct _GstVaapiEncoderClass GstBuffer ** codec_data); }; -void -gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass); +#define GST_VAAPI_ENCODER_CLASS_HOOK(codec, func) \ + .func = G_PASTE (G_PASTE (G_PASTE (gst_vaapi_encoder_,codec),_), func) +#define GST_VAAPI_ENCODER_CLASS_INIT_BASE(CODEC) \ + .parent_class = { \ + .size = sizeof (G_PASTE (GstVaapiEncoder, CODEC)), \ + .finalize = (GDestroyNotify) gst_vaapi_encoder_finalize \ + } + +#define GST_VAAPI_ENCODER_CLASS_INIT(CODEC, codec) \ + GST_VAAPI_ENCODER_CLASS_INIT_BASE (CODEC), \ + GST_VAAPI_ENCODER_CLASS_HOOK (codec, init), \ + GST_VAAPI_ENCODER_CLASS_HOOK (codec, finalize), \ + GST_VAAPI_ENCODER_CLASS_HOOK (codec, set_format), \ + GST_VAAPI_ENCODER_CLASS_HOOK (codec, get_context_info), \ + GST_VAAPI_ENCODER_CLASS_HOOK (codec, reordering), \ + GST_VAAPI_ENCODER_CLASS_HOOK (codec, encode), \ + GST_VAAPI_ENCODER_CLASS_HOOK (codec, flush) + +G_GNUC_INTERNAL GstVaapiEncoder * gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass, GstVaapiDisplay * display); +G_GNUC_INTERNAL void gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder); From 038149b69b8ea628aa2e3c576f7117e70087f15f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 3 Dec 2013 17:04:43 +0100 Subject: [PATCH 1441/3781] encoder: refactor status codes. Drop obsolete or unused status codes. Align some status codes with the decoder counterparts. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 28 +++++------------ gst-libs/gst/vaapi/gstvaapiencoder.h | 35 ++++++++++++++-------- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 20 ++++++------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 8 ++--- gst/vaapi/gstvaapiencode.c | 2 +- 5 files changed, 45 insertions(+), 48 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index adb5b2cdb3..ddd2fc6cd1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -208,7 +208,7 @@ gst_vaapi_encoder_free_sync_pictures (GstVaapiEncoder * encoder) GST_VAAPI_ENCODER_UNLOCK (encoder); } -static gboolean +static void gst_vaapi_encoder_push_sync_picture (GstVaapiEncoder * encoder, GstVaapiEncoderSyncPic * sync_pic) { @@ -216,7 +216,6 @@ gst_vaapi_encoder_push_sync_picture (GstVaapiEncoder * encoder, g_queue_push_tail (&encoder->sync_pictures, sync_pic); GST_VAAPI_ENCODER_SYNC_SIGNAL (encoder); GST_VAAPI_ENCODER_UNLOCK (encoder); - return TRUE; } static GstVaapiEncoderStatus @@ -233,7 +232,7 @@ gst_vaapi_encoder_pop_sync_picture (GstVaapiEncoder * encoder, goto timeout; if (g_queue_is_empty (&encoder->sync_pictures)) { - ret = GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR; + ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; goto end; } @@ -244,7 +243,7 @@ gst_vaapi_encoder_pop_sync_picture (GstVaapiEncoder * encoder, goto end; timeout: - ret = GST_VAAPI_ENCODER_STATUS_TIMEOUT; + ret = GST_VAAPI_ENCODER_STATUS_NO_BUFFER; end: GST_VAAPI_ENCODER_UNLOCK (encoder); @@ -265,21 +264,14 @@ again: picture = NULL; sync_pic = NULL; ret = klass->reordering (encoder, frame, FALSE, &picture); - - if (ret == GST_VAAPI_ENCODER_STATUS_FRAME_NOT_READY) + if (ret == GST_VAAPI_ENCODER_STATUS_NO_SURFACE) return GST_VAAPI_ENCODER_STATUS_SUCCESS; - - g_assert (picture); if (ret != GST_VAAPI_ENCODER_STATUS_SUCCESS) goto error; - if (!picture) { - ret = GST_VAAPI_ENCODER_STATUS_PICTURE_ERR; - goto error; - } coded_buf = gst_vaapi_encoder_create_coded_buffer (encoder); if (!coded_buf) { - ret = GST_VAAPI_ENCODER_STATUS_OBJECT_ERR; + ret = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; goto error; } @@ -291,11 +283,7 @@ again: sync_pic = _create_sync_picture (picture, coded_buf); gst_vaapi_coded_buffer_proxy_replace (&coded_buf, NULL); gst_vaapi_enc_picture_replace (&picture, NULL); - - if (!gst_vaapi_encoder_push_sync_picture (encoder, sync_pic)) { - ret = GST_VAAPI_ENCODER_STATUS_THREAD_ERR; - goto error; - } + gst_vaapi_encoder_push_sync_picture (encoder, sync_pic); frame = NULL; goto again; @@ -326,11 +314,11 @@ gst_vaapi_encoder_get_buffer (GstVaapiEncoder * encoder, picture = sync_pic->picture; if (!picture->surface || !gst_vaapi_surface_sync (picture->surface)) { - ret = GST_VAAPI_ENCODER_STATUS_PARAM_ERR; + ret = GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; goto end; } if (!gst_vaapi_surface_query_status (picture->surface, &surface_status)) { - ret = GST_VAAPI_ENCODER_STATUS_PICTURE_ERR; + ret = GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_SURFACE; goto end; } if (frame) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 8741c9a752..99223662ca 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -27,23 +27,32 @@ G_BEGIN_DECLS +/** + * GstVaapiEncoderStatus: + * @GST_VAAPI_ENCODER_STATUS_SUCCESS: Success. + * @GST_VAAPI_ENCODER_STATUS_ERROR_NO_SURFACE: No surface left to encode. + * @GST_VAAPI_ENCODER_STATUS_ERROR_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_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_FRAME_NOT_READY = 1, - GST_VAAPI_ENCODER_STATUS_NO_DATA = 2, - GST_VAAPI_ENCODER_STATUS_TIMEOUT = 3, - GST_VAAPI_ENCODER_STATUS_NOT_READY = 4, - GST_VAAPI_ENCODER_STATUS_FRAME_IN_ORDER = 5, + GST_VAAPI_ENCODER_STATUS_NO_SURFACE = 1, + GST_VAAPI_ENCODER_STATUS_NO_BUFFER = 2, - GST_VAAPI_ENCODER_STATUS_PARAM_ERR = -1, - GST_VAAPI_ENCODER_STATUS_OBJECT_ERR = -2, - GST_VAAPI_ENCODER_STATUS_PICTURE_ERR = -3, - GST_VAAPI_ENCODER_STATUS_THREAD_ERR = -4, - GST_VAAPI_ENCODER_STATUS_PROFILE_ERR = -5, - GST_VAAPI_ENCODER_STATUS_FUNC_PTR_ERR = -6, - GST_VAAPI_ENCODER_STATUS_MEM_ERROR = -7, - GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR = -8, + GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN = -1, + GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED = -2, + 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; typedef struct _GstVaapiEncoder GstVaapiEncoder; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 01546dafba..28d948acc7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1350,7 +1350,7 @@ gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) { GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base); - GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR; + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; reconstruct = gst_vaapi_encoder_create_surface (base); @@ -1412,19 +1412,19 @@ gst_vaapi_encoder_h264_get_avcC_codec_data (GstVaapiEncoderH264 * encoder, g_assert (buffer); if (!encoder->sps_data || !encoder->pps_data) - return GST_VAAPI_ENCODER_STATUS_NOT_READY; + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER; if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ)) - return GST_VAAPI_ENCODER_STATUS_MEM_ERROR; + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; if (FALSE == _read_sps_attributes (sps_info.data, sps_info.size, &profile, &profile_comp, &level_idc)) { - ret = GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR; + ret = GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER; goto end; } if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ)) { - ret = GST_VAAPI_ENCODER_STATUS_MEM_ERROR; + ret = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; goto end; } @@ -1453,7 +1453,7 @@ gst_vaapi_encoder_h264_get_avcC_codec_data (GstVaapiEncoderH264 * encoder, GST_BIT_WRITER_BIT_SIZE (&writer) / 8); g_assert (avc_codec); if (!avc_codec) { - ret = GST_VAAPI_ENCODER_STATUS_MEM_ERROR; + ret = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; goto clear_writer; } *buffer = avc_codec; @@ -1498,13 +1498,13 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base, if (!frame) { if (encoder->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES) - return GST_VAAPI_ENCODER_STATUS_FRAME_NOT_READY; + return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES dump B frames from queue, sometime, there may also have P frame or I frame */ g_assert (encoder->b_frame_num > 0); g_return_val_if_fail (!g_queue_is_empty (&encoder->reorder_frame_list), - GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR); + GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN); picture = g_queue_pop_head (&encoder->reorder_frame_list); g_assert (picture); if (g_queue_is_empty (&encoder->reorder_frame_list)) { @@ -1518,7 +1518,7 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base, if (!picture) { GST_WARNING ("create H264 picture failed, frame timestamp:%" GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); - return GST_VAAPI_ENCODER_STATUS_OBJECT_ERR; + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; } ++encoder->cur_present_index; picture->poc = ((encoder->cur_present_index * 2) % @@ -1562,7 +1562,7 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base, g_queue_get_length (&encoder->reorder_frame_list) < encoder->b_frame_num) { g_queue_push_tail (&encoder->reorder_frame_list, picture); - return GST_VAAPI_ENCODER_STATUS_FRAME_NOT_READY; + return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; } ++encoder->cur_frame_num; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 10de5875f6..ec8d575be3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -501,7 +501,7 @@ gst_vaapi_encoder_mpeg2_encode (GstVaapiEncoder * base, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) { GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2_CAST (base); - GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_UNKNOWN_ERR; + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; reconstruct = gst_vaapi_encoder_create_surface (base); @@ -564,7 +564,7 @@ gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base, encoder->dump_frames = FALSE; } if (!encoder->dump_frames) { - return GST_VAAPI_ENCODER_STATUS_FRAME_NOT_READY; + return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; } picture = g_queue_pop_head (&encoder->b_frames); g_assert (picture); @@ -575,7 +575,7 @@ gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base, if (!picture) { GST_WARNING ("create MPEG2 picture failed, frame timestamp:%" GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); - return GST_VAAPI_ENCODER_STATUS_OBJECT_ERR; + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; } if (encoder->frame_num >= encoder->intra_period) { @@ -594,7 +594,7 @@ gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base, encoder->dump_frames = TRUE; } else { picture->type = GST_VAAPI_PICTURE_TYPE_B; - status = GST_VAAPI_ENCODER_STATUS_FRAME_NOT_READY; + status = GST_VAAPI_ENCODER_STATUS_NO_SURFACE; } } diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index adb24741f1..308aecf53b 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -231,7 +231,7 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) status = gst_vaapi_encoder_get_buffer (encode->encoder, &out_frame, &codedbuf_proxy, timeout); - if (status == GST_VAAPI_ENCODER_STATUS_TIMEOUT) + if (status == GST_VAAPI_ENCODER_STATUS_NO_BUFFER) return GST_VAAPI_ENCODE_FLOW_TIMEOUT; if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) goto error_get_buffer; From 26726b18fcdf3f4fac1cce7420c8a9715295cfb2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 4 Dec 2013 17:05:17 +0100 Subject: [PATCH 1442/3781] encoder: avoid extra allocations of GstVaapiEncoderSyncPic objects. Kill GstVaapiEncoderSyncPic objects that are internally and temporarily allocated. Rather, associate a GstVaapiEncPicture to a coded buffer through GstVaapiCodedBufferProxy user-data facility. Besides, use a GAsyncQueue to maintain a thread-safe queue object of coded buffers. Partial fix for the following report: https://bugzilla.gnome.org/show_bug.cgi?id=719530 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 327 +++++++--------------- gst-libs/gst/vaapi/gstvaapiencoder.h | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 7 +- 3 files changed, 107 insertions(+), 229 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index ddd2fc6cd1..f85ce0f100 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -28,56 +28,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -#define GST_VAAPI_ENCODER_LOCK(encoder) \ - G_STMT_START { \ - g_mutex_lock (&(GST_VAAPI_ENCODER_CAST(encoder))->lock); \ - } G_STMT_END - -#define GST_VAAPI_ENCODER_UNLOCK(encoder) \ - G_STMT_START { \ - g_mutex_unlock (&(GST_VAAPI_ENCODER_CAST(encoder))->lock); \ - } G_STMT_END - -#define GST_VAAPI_ENCODER_BUF_FREE_WAIT(encoder) \ - G_STMT_START { \ - g_cond_wait (&(GST_VAAPI_ENCODER_CAST(encoder))->codedbuf_free, \ - &(GST_VAAPI_ENCODER_CAST(encoder))->lock); \ - } G_STMT_END - -#define GST_VAAPI_ENCODER_BUF_FREE_SIGNAL(encoder) \ - G_STMT_START { \ - g_cond_signal (&(GST_VAAPI_ENCODER_CAST(encoder))->codedbuf_free); \ - } G_STMT_END - -#define GST_VAAPI_ENCODER_FREE_SURFACE_WAIT(encoder) \ - G_STMT_START { \ - g_cond_wait (&(GST_VAAPI_ENCODER_CAST(encoder))->surface_free, \ - &(GST_VAAPI_ENCODER_CAST(encoder))->lock); \ - } G_STMT_END - -#define GST_VAAPI_ENCODER_FREE_SURFACE_SIGNAL(encoder) \ - G_STMT_START { \ - g_cond_signal (&(GST_VAAPI_ENCODER_CAST(encoder))->surface_free); \ - } G_STMT_END - -#define GST_VAAPI_ENCODER_SYNC_SIGNAL(encoder) \ - G_STMT_START { \ - g_cond_signal (&(GST_VAAPI_ENCODER_CAST(encoder))->sync_ready); \ - } G_STMT_END - -static inline gboolean -GST_VAAPI_ENCODER_SYNC_WAIT_TIMEOUT (GstVaapiEncoder * encoder, gint64 timeout) -{ - gint64 end_time = g_get_monotonic_time () + timeout; - return g_cond_wait_until (&encoder->sync_ready, &encoder->lock, end_time); -} - -typedef struct -{ - GstVaapiEncPicture *picture; - GstVaapiCodedBufferProxy *buf; -} GstVaapiEncoderSyncPic; - GstVaapiEncoder * gst_vaapi_encoder_ref (GstVaapiEncoder * encoder) { @@ -100,9 +50,9 @@ gst_vaapi_encoder_replace (GstVaapiEncoder ** old_encoder_ptr, static void _coded_buffer_proxy_released_notify (GstVaapiEncoder * encoder) { - GST_VAAPI_ENCODER_LOCK (encoder); - GST_VAAPI_ENCODER_BUF_FREE_SIGNAL (encoder); - GST_VAAPI_ENCODER_UNLOCK (encoder); + g_mutex_lock (&encoder->mutex); + g_cond_signal (&encoder->codedbuf_free); + g_mutex_unlock (&encoder->mutex); } static GstVaapiCodedBufferProxy * @@ -112,17 +62,17 @@ gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder) GST_VAAPI_CODED_BUFFER_POOL (encoder->codedbuf_pool); GstVaapiCodedBufferProxy *codedbuf_proxy; - GST_VAAPI_ENCODER_LOCK (encoder); + g_mutex_lock (&encoder->mutex); do { codedbuf_proxy = gst_vaapi_coded_buffer_proxy_new_from_pool (pool); if (codedbuf_proxy) break; /* Wait for a free coded buffer to become available */ - GST_VAAPI_ENCODER_BUF_FREE_WAIT (encoder); + g_cond_wait (&encoder->codedbuf_free, &encoder->mutex); codedbuf_proxy = gst_vaapi_coded_buffer_proxy_new_from_pool (pool); } while (0); - GST_VAAPI_ENCODER_UNLOCK (encoder); + g_mutex_unlock (&encoder->mutex); if (!codedbuf_proxy) return NULL; @@ -134,7 +84,9 @@ gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder) static void _surface_proxy_released_notify (GstVaapiEncoder * encoder) { - GST_VAAPI_ENCODER_FREE_SURFACE_SIGNAL (encoder); + g_mutex_lock (&encoder->mutex); + g_cond_signal (&encoder->surface_free); + g_mutex_unlock (&encoder->mutex); } GstVaapiSurfaceProxy * @@ -142,19 +94,21 @@ gst_vaapi_encoder_create_surface (GstVaapiEncoder * encoder) { GstVaapiSurfaceProxy *proxy; - g_assert (encoder && encoder->context); - g_return_val_if_fail (encoder->context, NULL); + g_return_val_if_fail (encoder->context != NULL, NULL); - GST_VAAPI_ENCODER_LOCK (encoder); - while (!gst_vaapi_context_get_surface_count (encoder->context)) { - GST_VAAPI_ENCODER_FREE_SURFACE_WAIT (encoder); + g_mutex_lock (&encoder->mutex); + for (;;) { + proxy = gst_vaapi_context_get_surface_proxy (encoder->context); + if (proxy) + break; + + /* Wait for a free surface proxy to become available */ + g_cond_wait (&encoder->surface_free, &encoder->mutex); } - proxy = gst_vaapi_context_get_surface_proxy (encoder->context); - GST_VAAPI_ENCODER_UNLOCK (encoder); + g_mutex_unlock (&encoder->mutex); gst_vaapi_surface_proxy_set_destroy_notify (proxy, (GDestroyNotify) _surface_proxy_released_notify, encoder); - return proxy; } @@ -162,174 +116,97 @@ void gst_vaapi_encoder_release_surface (GstVaapiEncoder * encoder, GstVaapiSurfaceProxy * surface) { - GST_VAAPI_ENCODER_LOCK (encoder); gst_vaapi_surface_proxy_unref (surface); - GST_VAAPI_ENCODER_UNLOCK (encoder); -} - -static GstVaapiEncoderSyncPic * -_create_sync_picture (GstVaapiEncPicture * picture, - GstVaapiCodedBufferProxy * coded_buf) -{ - GstVaapiEncoderSyncPic *sync = g_slice_new0 (GstVaapiEncoderSyncPic); - - g_assert (picture && coded_buf); - sync->picture = gst_vaapi_enc_picture_ref (picture); - sync->buf = gst_vaapi_coded_buffer_proxy_ref (coded_buf); - return sync; -} - -static void -_free_sync_picture (GstVaapiEncoder * encoder, - GstVaapiEncoderSyncPic * sync_pic) -{ - g_assert (sync_pic); - - if (sync_pic->picture) - gst_vaapi_enc_picture_unref (sync_pic->picture); - if (sync_pic->buf) - gst_vaapi_coded_buffer_proxy_unref (sync_pic->buf); - g_slice_free (GstVaapiEncoderSyncPic, sync_pic); -} - -static void -gst_vaapi_encoder_free_sync_pictures (GstVaapiEncoder * encoder) -{ - GstVaapiEncoderSyncPic *sync; - - GST_VAAPI_ENCODER_LOCK (encoder); - while (!g_queue_is_empty (&encoder->sync_pictures)) { - sync = - (GstVaapiEncoderSyncPic *) g_queue_pop_head (&encoder->sync_pictures); - GST_VAAPI_ENCODER_UNLOCK (encoder); - _free_sync_picture (encoder, sync); - GST_VAAPI_ENCODER_LOCK (encoder); - } - GST_VAAPI_ENCODER_UNLOCK (encoder); -} - -static void -gst_vaapi_encoder_push_sync_picture (GstVaapiEncoder * encoder, - GstVaapiEncoderSyncPic * sync_pic) -{ - GST_VAAPI_ENCODER_LOCK (encoder); - g_queue_push_tail (&encoder->sync_pictures, sync_pic); - GST_VAAPI_ENCODER_SYNC_SIGNAL (encoder); - GST_VAAPI_ENCODER_UNLOCK (encoder); -} - -static GstVaapiEncoderStatus -gst_vaapi_encoder_pop_sync_picture (GstVaapiEncoder * encoder, - GstVaapiEncoderSyncPic ** sync_pic, guint64 timeout) -{ - GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; - - *sync_pic = NULL; - - GST_VAAPI_ENCODER_LOCK (encoder); - if (g_queue_is_empty (&encoder->sync_pictures) && - !GST_VAAPI_ENCODER_SYNC_WAIT_TIMEOUT (encoder, timeout)) - goto timeout; - - if (g_queue_is_empty (&encoder->sync_pictures)) { - ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; - goto end; - } - - *sync_pic = - (GstVaapiEncoderSyncPic *) g_queue_pop_head (&encoder->sync_pictures); - g_assert (*sync_pic); - ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; - goto end; - -timeout: - ret = GST_VAAPI_ENCODER_STATUS_NO_BUFFER; - -end: - GST_VAAPI_ENCODER_UNLOCK (encoder); - return ret; } GstVaapiEncoderStatus gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, GstVideoCodecFrame * frame) { - GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; - GstVaapiEncoderClass *klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); - GstVaapiEncPicture *picture = NULL; - GstVaapiCodedBufferProxy *coded_buf = NULL; - GstVaapiEncoderSyncPic *sync_pic = NULL; + GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + GstVaapiEncoderStatus status; + GstVaapiEncPicture *picture; + GstVaapiCodedBufferProxy *codedbuf_proxy; -again: - picture = NULL; - sync_pic = NULL; - ret = klass->reordering (encoder, frame, FALSE, &picture); - if (ret == GST_VAAPI_ENCODER_STATUS_NO_SURFACE) - return GST_VAAPI_ENCODER_STATUS_SUCCESS; - if (ret != GST_VAAPI_ENCODER_STATUS_SUCCESS) - goto error; + for (;;) { + picture = NULL; + status = klass->reordering (encoder, frame, FALSE, &picture); + if (status == GST_VAAPI_ENCODER_STATUS_NO_SURFACE) + break; + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto error_reorder_frame; - coded_buf = gst_vaapi_encoder_create_coded_buffer (encoder); - if (!coded_buf) { - ret = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - goto error; + codedbuf_proxy = gst_vaapi_encoder_create_coded_buffer (encoder); + if (!codedbuf_proxy) + goto error_create_coded_buffer; + + status = klass->encode (encoder, picture, codedbuf_proxy); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto error_encode; + + gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, + picture, (GDestroyNotify) gst_vaapi_enc_picture_unref); + g_async_queue_push (encoder->codedbuf_queue, codedbuf_proxy); + + /* Try again with any pending reordered frame now available for encoding */ + frame = NULL; } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; - ret = klass->encode (encoder, picture, coded_buf); - if (ret != GST_VAAPI_ENCODER_STATUS_SUCCESS) - goto error; - - /* another thread would sync and get coded buffer */ - sync_pic = _create_sync_picture (picture, coded_buf); - gst_vaapi_coded_buffer_proxy_replace (&coded_buf, NULL); - gst_vaapi_enc_picture_replace (&picture, NULL); - gst_vaapi_encoder_push_sync_picture (encoder, sync_pic); - - frame = NULL; - goto again; - -error: - gst_vaapi_enc_picture_replace (&picture, NULL); - gst_vaapi_coded_buffer_proxy_replace (&coded_buf, NULL); - if (sync_pic) - _free_sync_picture (encoder, sync_pic); - GST_ERROR ("encoding failed, error:%d", ret); - return ret; + /* ERRORS */ +error_reorder_frame: + { + GST_ERROR ("failed to process reordered frames"); + return status; + } +error_create_coded_buffer: + { + GST_ERROR ("failed to allocate coded buffer"); + gst_vaapi_enc_picture_unref (picture); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_encode: + { + GST_ERROR ("failed to encode frame (status = %d)", status); + gst_vaapi_enc_picture_unref (picture); + gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); + return status; + } } GstVaapiEncoderStatus gst_vaapi_encoder_get_buffer (GstVaapiEncoder * encoder, - GstVideoCodecFrame ** frame, - GstVaapiCodedBufferProxy ** codedbuf, gint64 us_of_timeout) + GstVideoCodecFrame ** out_frame_ptr, + GstVaapiCodedBufferProxy ** out_codedbuf_proxy_ptr, guint64 timeout) { - GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; - GstVaapiEncoderSyncPic *sync_pic = NULL; - GstVaapiSurfaceStatus surface_status; GstVaapiEncPicture *picture; + GstVaapiCodedBufferProxy *codedbuf_proxy; - ret = gst_vaapi_encoder_pop_sync_picture (encoder, &sync_pic, us_of_timeout); - if (ret != GST_VAAPI_ENCODER_STATUS_SUCCESS) - goto end; + codedbuf_proxy = g_async_queue_timeout_pop (encoder->codedbuf_queue, timeout); + if (!codedbuf_proxy) + return GST_VAAPI_ENCODER_STATUS_NO_BUFFER; - picture = sync_pic->picture; + /* Wait for completion of all operations and report any error that occurred */ + picture = gst_vaapi_coded_buffer_proxy_get_user_data (codedbuf_proxy); + if (!gst_vaapi_surface_sync (picture->surface)) + goto error_invalid_buffer; - if (!picture->surface || !gst_vaapi_surface_sync (picture->surface)) { - ret = GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - goto end; + if (out_frame_ptr) + *out_frame_ptr = gst_video_codec_frame_ref (picture->frame); + gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, NULL, NULL); + + if (out_codedbuf_proxy_ptr) + *out_codedbuf_proxy_ptr = gst_vaapi_coded_buffer_proxy_ref (codedbuf_proxy); + gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +error_invalid_buffer: + { + GST_ERROR ("failed to encode the frame"); + gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_SURFACE; } - if (!gst_vaapi_surface_query_status (picture->surface, &surface_status)) { - ret = GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_SURFACE; - goto end; - } - if (frame) - *frame = gst_video_codec_frame_ref (picture->frame); - if (codedbuf) - *codedbuf = gst_vaapi_coded_buffer_proxy_ref (sync_pic->buf); - -end: - if (sync_pic) - _free_sync_picture (encoder, sync_pic); - return ret; } GstVaapiEncoderStatus @@ -457,11 +334,14 @@ gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) gst_video_info_init (&encoder->video_info); - g_mutex_init (&encoder->lock); - g_cond_init (&encoder->codedbuf_free); + g_mutex_init (&encoder->mutex); g_cond_init (&encoder->surface_free); - g_queue_init (&encoder->sync_pictures); - g_cond_init (&encoder->sync_ready); + g_cond_init (&encoder->codedbuf_free); + + encoder->codedbuf_queue = g_async_queue_new_full ((GDestroyNotify) + gst_vaapi_coded_buffer_proxy_unref); + if (!encoder->codedbuf_queue) + return FALSE; return klass->init (encoder); @@ -480,17 +360,18 @@ gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) klass->finalize (encoder); - gst_vaapi_encoder_free_sync_pictures (encoder); - gst_vaapi_video_pool_replace (&encoder->codedbuf_pool, NULL); - gst_vaapi_object_replace (&encoder->context, NULL); gst_vaapi_display_replace (&encoder->display, NULL); encoder->va_display = NULL; - g_mutex_clear (&encoder->lock); - g_cond_clear (&encoder->codedbuf_free); + + gst_vaapi_video_pool_replace (&encoder->codedbuf_pool, NULL); + if (encoder->codedbuf_queue) { + g_async_queue_unref (encoder->codedbuf_queue); + encoder->codedbuf_queue = NULL; + } g_cond_clear (&encoder->surface_free); - g_queue_clear (&encoder->sync_pictures); - g_cond_clear (&encoder->sync_ready); + g_cond_clear (&encoder->codedbuf_free); + g_mutex_clear (&encoder->mutex); } GstVaapiEncoder * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 99223662ca..73870f95b8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -87,7 +87,7 @@ gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, GstVaapiEncoderStatus gst_vaapi_encoder_get_buffer (GstVaapiEncoder * encoder, GstVideoCodecFrame ** out_frame_ptr, - GstVaapiCodedBufferProxy ** out_codedbuf_ptr, gint64 timeout); + GstVaapiCodedBufferProxy ** out_codedbuf_proxy_ptr, guint64 timeout); GstVaapiEncoderStatus gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index e18fe58829..19ab7a68c2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -92,15 +92,12 @@ struct _GstVaapiEncoder GstVideoInfo video_info; GstVaapiRateControl rate_control; - GMutex lock; + GMutex mutex; GCond surface_free; GCond codedbuf_free; guint codedbuf_size; GstVaapiVideoPool *codedbuf_pool; - - /* queue for sync */ - GQueue sync_pictures; - GCond sync_ready; + GAsyncQueue *codedbuf_queue; }; struct _GstVaapiEncoderClass From 2f5e5f0784d6935212dfe5a77dc2a9faf594b554 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 4 Dec 2013 17:55:18 +0100 Subject: [PATCH 1443/3781] encoder: clean-ups and document public APIs. Clean public APIs up so that to better align with the decoder APIs. Most importantly, gst_vaapi_encoder_get_buffer() is changed to only return the VA coded buffer proxy. Also provide useful documentation for the public APIs. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 127 +++++++++++++++++---- gst-libs/gst/vaapi/gstvaapiencoder.h | 24 ++-- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 20 ++-- gst/vaapi/gstvaapiencode.c | 13 ++- 6 files changed, 135 insertions(+), 53 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index f85ce0f100..ef2675f17f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -18,6 +18,7 @@ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ + #include "sysdeps.h" #include "gstvaapicompat.h" #include "gstvaapiencoder.h" @@ -28,18 +29,42 @@ #define DEBUG 1 #include "gstvaapidebug.h" +/** + * gst_vaapi_encoder_ref: + * @encoder: a #GstVaapiEncoder + * + * Atomically increases the reference count of the given @encoder by one. + * + * Returns: The same @encoder argument + */ GstVaapiEncoder * gst_vaapi_encoder_ref (GstVaapiEncoder * encoder) { return gst_vaapi_object_ref (encoder); } +/** + * gst_vaapi_encoder_unref: + * @encoder: a #GstVaapiEncoder + * + * Atomically decreases the reference count of the @encoder by one. If + * the reference count reaches zero, the encoder will be free'd. + */ void gst_vaapi_encoder_unref (GstVaapiEncoder * encoder) { gst_vaapi_object_unref (encoder); } +/** + * gst_vaapi_encoder_replace: + * @old_encoder_ptr: a pointer to a #GstVaapiEncoder + * @new_encoder: a #GstVaapiEncoder + * + * Atomically replaces the encoder encoder held in @old_encoder_ptr + * with @new_encoder. This means that @old_encoder_ptr shall reference + * a valid encoder. However, @new_encoder can be NULL. + */ void gst_vaapi_encoder_replace (GstVaapiEncoder ** old_encoder_ptr, GstVaapiEncoder * new_encoder) @@ -47,6 +72,7 @@ gst_vaapi_encoder_replace (GstVaapiEncoder ** old_encoder_ptr, gst_vaapi_object_replace (old_encoder_ptr, new_encoder); } +/* Notifies gst_vaapi_encoder_create_coded_buffer() that a new buffer is free */ static void _coded_buffer_proxy_released_notify (GstVaapiEncoder * encoder) { @@ -55,6 +81,7 @@ _coded_buffer_proxy_released_notify (GstVaapiEncoder * encoder) g_mutex_unlock (&encoder->mutex); } +/* Creates a new VA coded buffer object proxy, backed from a pool */ static GstVaapiCodedBufferProxy * gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder) { @@ -81,6 +108,7 @@ gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder) return codedbuf_proxy; } +/* Notifies gst_vaapi_encoder_create_surface() that a new surface is free */ static void _surface_proxy_released_notify (GstVaapiEncoder * encoder) { @@ -89,6 +117,8 @@ _surface_proxy_released_notify (GstVaapiEncoder * encoder) g_mutex_unlock (&encoder->mutex); } +/* Creates a new VA surface object proxy, backed from a pool and + useful to allocate reconstructed surfaces */ GstVaapiSurfaceProxy * gst_vaapi_encoder_create_surface (GstVaapiEncoder * encoder) { @@ -112,13 +142,16 @@ gst_vaapi_encoder_create_surface (GstVaapiEncoder * encoder) return proxy; } -void -gst_vaapi_encoder_release_surface (GstVaapiEncoder * encoder, - GstVaapiSurfaceProxy * surface) -{ - gst_vaapi_surface_proxy_unref (surface); -} - +/** + * gst_vaapi_encoder_put_frame: + * @encoder: a #GstVaapiEncoder + * @frame: a #GstVideoCodecFrame + * + * Queues a #GstVideoCodedFrame to the HW encoder. The encoder holds + * an extra reference to the @frame. + * + * Return value: a #GstVaapiEncoderStatus + */ GstVaapiEncoderStatus gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, GstVideoCodecFrame * frame) @@ -130,7 +163,7 @@ gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, for (;;) { picture = NULL; - status = klass->reordering (encoder, frame, FALSE, &picture); + status = klass->reordering (encoder, frame, &picture); if (status == GST_VAAPI_ENCODER_STATUS_NO_SURFACE) break; if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) @@ -174,9 +207,26 @@ error_encode: } } +/** + * gst_vaapi_encoder_get_buffer_with_timeout: + * @encoder: a #GstVaapiEncoder + * @out_codedbuf_proxy_ptr: the next coded buffer as a #GstVaapiCodedBufferProxy + * @timeout: the number of microseconds to wait for the coded buffer, at most + * + * Upon successful return, *@out_codedbuf_proxy_ptr contains the next + * coded buffer as a #GstVaapiCodedBufferProxy. The caller owns this + * object, so gst_vaapi_coded_buffer_proxy_unref() shall be called + * after usage. Otherwise, @GST_VAAPI_DECODER_STATUS_ERROR_NO_BUFFER + * is returned if no coded buffer is available so far (timeout). + * + * The parent frame is available as a #GstVideoCodecFrame attached to + * the user-data anchor of the output coded buffer. Ownership of the + * frame is transferred to the coded buffer. + * + * Return value: a #GstVaapiEncoderStatus + */ GstVaapiEncoderStatus -gst_vaapi_encoder_get_buffer (GstVaapiEncoder * encoder, - GstVideoCodecFrame ** out_frame_ptr, +gst_vaapi_encoder_get_buffer_with_timeout (GstVaapiEncoder * encoder, GstVaapiCodedBufferProxy ** out_codedbuf_proxy_ptr, guint64 timeout) { GstVaapiEncPicture *picture; @@ -191,9 +241,9 @@ gst_vaapi_encoder_get_buffer (GstVaapiEncoder * encoder, if (!gst_vaapi_surface_sync (picture->surface)) goto error_invalid_buffer; - if (out_frame_ptr) - *out_frame_ptr = gst_video_codec_frame_ref (picture->frame); - gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, NULL, NULL); + gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, + gst_video_codec_frame_ref (picture->frame), + (GDestroyNotify) gst_video_codec_frame_unref); if (out_codedbuf_proxy_ptr) *out_codedbuf_proxy_ptr = gst_vaapi_coded_buffer_proxy_ref (codedbuf_proxy); @@ -209,6 +259,14 @@ error_invalid_buffer: } } +/** + * gst_vaapi_encoder_flush: + * @encoder: a #GstVaapiEncoder + * + * Submits any pending (reordered) frame for encoding. + * + * Return value: a #GstVaapiEncoderStatus + */ GstVaapiEncoderStatus gst_vaapi_encoder_flush (GstVaapiEncoder * encoder) { @@ -217,21 +275,34 @@ gst_vaapi_encoder_flush (GstVaapiEncoder * encoder) return klass->flush (encoder); } +/** + * gst_vaapi_encoder_get_codec_data: + * @encoder: a #GstVaapiEncoder + * @out_codec_data_ptr: the pointer to the resulting codec-data (#GstBuffer) + * + * Returns a codec-data buffer that best represents the encoded + * bitstream. Upon successful return, and if the @out_codec_data_ptr + * contents is not NULL, then the caller function shall deallocates + * that buffer with gst_buffer_unref(). + * + * Return value: a #GstVaapiEncoderStatus + */ GstVaapiEncoderStatus gst_vaapi_encoder_get_codec_data (GstVaapiEncoder * encoder, - GstBuffer ** codec_data) + GstBuffer ** out_codec_data_ptr) { GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); - *codec_data = NULL; + *out_codec_data_ptr = NULL; if (!klass->get_codec_data) return GST_VAAPI_ENCODER_STATUS_SUCCESS; - ret = klass->get_codec_data (encoder, codec_data); + ret = klass->get_codec_data (encoder, out_codec_data_ptr); return ret; } +/* Ensures the underlying VA context for encoding is created */ static gboolean gst_vaapi_encoder_ensure_context (GstVaapiEncoder * encoder) { @@ -256,21 +327,32 @@ gst_vaapi_encoder_ensure_context (GstVaapiEncoder * encoder) return TRUE; } +/** + * gst_vaapi_encoder_set_format: + * @encoder: a #GstVaapiEncoder + * @state : a #GstVideoCodecState + * @ref_caps: the set of reference caps (from pad template) + * + * Notifies the encoder of incoming data format (video resolution), + * and additional information like framerate. + * + * Return value: the newly allocated set of caps + */ GstCaps * gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, - GstVideoCodecState * in_state, GstCaps * ref_caps) + GstVideoCodecState * state, GstCaps * ref_caps) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); GstCaps *out_caps = NULL; - if (!GST_VIDEO_INFO_WIDTH (&in_state->info) || - !GST_VIDEO_INFO_HEIGHT (&in_state->info)) { + if (!GST_VIDEO_INFO_WIDTH (&state->info) || + !GST_VIDEO_INFO_HEIGHT (&state->info)) { GST_WARNING ("encoder set format failed, width or height equal to 0."); return NULL; } - GST_VAAPI_ENCODER_VIDEO_INFO (encoder) = in_state->info; + GST_VAAPI_ENCODER_VIDEO_INFO (encoder) = state->info; - out_caps = klass->set_format (encoder, in_state, ref_caps); + out_caps = klass->set_format (encoder, state, ref_caps); if (!out_caps) goto error; @@ -306,6 +388,7 @@ error: return NULL; } +/* Base encoder initialization (internal) */ static gboolean gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) { @@ -353,6 +436,7 @@ error_invalid_vtable: } } +/* Base encoder cleanup (internal) */ void gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) { @@ -374,6 +458,7 @@ gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) g_mutex_clear (&encoder->mutex); } +/* Helper function to create new GstVaapiEncoder instances (internal) */ GstVaapiEncoder * gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass, GstVaapiDisplay * display) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 73870f95b8..6b0a7ed27f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -27,6 +27,11 @@ G_BEGIN_DECLS +typedef struct _GstVaapiEncoder GstVaapiEncoder; + +#define GST_VAAPI_ENCODER(encoder) \ + ((GstVaapiEncoder *)(encoder)) + /** * GstVaapiEncoderStatus: * @GST_VAAPI_ENCODER_STATUS_SUCCESS: Success. @@ -55,14 +60,6 @@ typedef enum GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER = -103, } GstVaapiEncoderStatus; -typedef struct _GstVaapiEncoder GstVaapiEncoder; - -#define GST_VAAPI_ENCODER(encoder) \ - ((GstVaapiEncoder *)(encoder)) - -#define GST_VAAPI_ENCODER_CAST(encoder) \ - ((GstVaapiEncoder *)(encoder)) - GstVaapiEncoder * gst_vaapi_encoder_ref (GstVaapiEncoder * encoder); @@ -73,20 +70,19 @@ void gst_vaapi_encoder_replace (GstVaapiEncoder ** old_encoder_ptr, GstVaapiEncoder * new_encoder); -GstCaps *gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, - GstVideoCodecState * state, GstCaps * ref_caps); - GstVaapiEncoderStatus gst_vaapi_encoder_get_codec_data (GstVaapiEncoder * encoder, - GstBuffer ** codec_data_ptr); + GstBuffer ** out_codec_data_ptr); + +GstCaps *gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, + GstVideoCodecState * state, GstCaps * ref_caps); GstVaapiEncoderStatus gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, GstVideoCodecFrame * frame); GstVaapiEncoderStatus -gst_vaapi_encoder_get_buffer (GstVaapiEncoder * encoder, - GstVideoCodecFrame ** out_frame_ptr, +gst_vaapi_encoder_get_buffer_with_timeout (GstVaapiEncoder * encoder, GstVaapiCodedBufferProxy ** out_codedbuf_proxy_ptr, guint64 timeout); GstVaapiEncoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 28d948acc7..076273c870 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1488,7 +1488,7 @@ gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base, static GstVaapiEncoderStatus gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base, - GstVideoCodecFrame * frame, gboolean flush, GstVaapiEncPicture ** output) + GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) { GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base); GstVaapiEncPicture *picture; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index ec8d575be3..1af8f4d64a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -551,7 +551,7 @@ gst_vaapi_encoder_mpeg2_flush (GstVaapiEncoder * base) static GstVaapiEncoderStatus gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base, - GstVideoCodecFrame * frame, gboolean flush, GstVaapiEncPicture ** output) + GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) { GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); GstVaapiEncPicture *picture = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 19ab7a68c2..10b1ff9df9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -30,12 +30,12 @@ G_BEGIN_DECLS +#define GST_VAAPI_ENCODER_CAST(encoder) \ + ((GstVaapiEncoder *)(encoder)) + #define GST_VAAPI_ENCODER_CLASS(klass) \ ((GstVaapiEncoderClass *)(klass)) -#define GST_IS_VAAPI_ENCODER_CLASS(klass) \ - ((klass) != NULL) - #define GST_VAAPI_ENCODER_GET_CLASS(obj) \ GST_VAAPI_ENCODER_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) @@ -64,11 +64,6 @@ G_BEGIN_DECLS #define GST_VAAPI_ENCODER_RATE_CONTROL(encoder) \ (GST_VAAPI_ENCODER_CAST(encoder)->rate_control) -#define GST_VAAPI_ENCODER_LOG_ERROR(...) GST_ERROR( __VA_ARGS__) -#define GST_VAAPI_ENCODER_LOG_WARNING(...) GST_WARNING( __VA_ARGS__) -#define GST_VAAPI_ENCODER_LOG_DEBUG(...) GST_DEBUG( __VA_ARGS__) -#define GST_VAAPI_ENCODER_LOG_INFO(...) GST_INFO( __VA_ARGS__) - #define GST_VAAPI_ENCODER_CHECK_STATUS(exp, err_num, err_reason, ...) \ if (!(exp)) { \ ret = err_num; \ @@ -116,7 +111,6 @@ struct _GstVaapiEncoderClass GstVaapiEncoderStatus (*reordering) (GstVaapiEncoder * encoder, GstVideoCodecFrame * in, - gboolean flush, GstVaapiEncPicture ** out); GstVaapiEncoderStatus (*encode) (GstVaapiEncoder * encoder, GstVaapiEncPicture * picture, @@ -157,13 +151,17 @@ G_GNUC_INTERNAL void gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder); +G_GNUC_INTERNAL GstVaapiSurfaceProxy * gst_vaapi_encoder_create_surface (GstVaapiEncoder * encoder); -void +static inline void gst_vaapi_encoder_release_surface (GstVaapiEncoder * encoder, - GstVaapiSurfaceProxy * surface); + GstVaapiSurfaceProxy * proxy) +{ + gst_vaapi_surface_proxy_unref (proxy); +} G_END_DECLS diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 308aecf53b..bcb3f1d303 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -223,19 +223,23 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) { GstVideoEncoder *const venc = GST_VIDEO_ENCODER_CAST (encode); GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (encode); - GstVideoCodecFrame *out_frame = NULL; + GstVideoCodecFrame *out_frame; GstVaapiCodedBufferProxy *codedbuf_proxy = NULL; GstVaapiEncoderStatus status; GstBuffer *out_buffer; GstFlowReturn ret; - status = gst_vaapi_encoder_get_buffer (encode->encoder, - &out_frame, &codedbuf_proxy, timeout); + status = gst_vaapi_encoder_get_buffer_with_timeout (encode->encoder, + &codedbuf_proxy, timeout); if (status == GST_VAAPI_ENCODER_STATUS_NO_BUFFER) return GST_VAAPI_ENCODE_FLOW_TIMEOUT; if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) goto error_get_buffer; + out_frame = gst_vaapi_coded_buffer_proxy_get_user_data (codedbuf_proxy); + if (!out_frame) + goto error_get_buffer; + gst_video_codec_frame_ref (out_frame); gst_video_codec_frame_set_user_data (out_frame, NULL, NULL); /* Allocate and copy buffer into system memory */ @@ -287,8 +291,6 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) error_get_buffer: { GST_ERROR ("failed to get encoded buffer (status %d)", status); - if (out_frame) - gst_video_codec_frame_unref (out_frame); if (codedbuf_proxy) gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); return GST_FLOW_ERROR; @@ -298,6 +300,7 @@ error_allocate_buffer: GST_ERROR ("failed to allocate encoded buffer in system memory"); if (out_buffer) gst_buffer_unref (out_buffer); + gst_video_codec_frame_unref (out_frame); return ret; } error_codec_data: From fdddf83c71a59b395afe60a0483d3bb3e3231a7b Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 26 Nov 2013 14:38:23 +0800 Subject: [PATCH 1444/3781] encoder: fix mpeg2 compilation error. https://bugzilla.gnome.org/show_bug.cgi?id=719746 Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 1af8f4d64a..5bc01d55b2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -224,7 +224,7 @@ fill_picture (GstVaapiEncoderMpeg2 * encoder, GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) { VAEncPictureParameterBufferMPEG2 *pic = picture->param; - uint8_t f_code_x, f_code_y; + guint8 f_code_x, f_code_y; memset (pic, 0, sizeof (VAEncPictureParameterBufferMPEG2)); From fd9c855f140af83f34081403c09d6bfac005ca78 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 4 Dec 2013 18:48:35 +0100 Subject: [PATCH 1445/3781] encoder: simplify VA context initialization process. Change get_context_info() into a set_context_info() function that initializes common defaults into the base class, thus allowing the subclasses to specialize the context info further on. The set_context_info() hook is also the location where additional context specific data could be initialized. At this point, we are guaranteed to have valid video resolution size and framerate. i.e. gst_vaapi_encoder_set_format() was called beforehand. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 17 ++++++++++------- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 22 +++++++--------------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 20 ++++++-------------- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 6 +++--- 4 files changed, 26 insertions(+), 39 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index ef2675f17f..e56886fa12 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -307,18 +307,21 @@ static gboolean gst_vaapi_encoder_ensure_context (GstVaapiEncoder * encoder) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); - GstVaapiContextInfo info; + GstVaapiContextInfo *const cip = &encoder->context_info; GstVaapiContext *context; if (GST_VAAPI_ENCODER_CONTEXT (encoder)) return TRUE; - memset (&info, 0, sizeof (info)); - if (!klass->get_context_info (encoder, &info)) - return FALSE; + cip->profile = GST_VAAPI_PROFILE_UNKNOWN; + cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + cip->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); + cip->width = GST_VAAPI_ENCODER_WIDTH (encoder); + cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); + cip->ref_frames = 0; + klass->set_context_info (encoder); - context = gst_vaapi_context_new_full (GST_VAAPI_ENCODER_DISPLAY (encoder), - &info); + context = gst_vaapi_context_new_full (encoder->display, cip); if (!context) return FALSE; @@ -406,7 +409,7 @@ gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) CHECK_VTABLE_HOOK (encode); CHECK_VTABLE_HOOK (reordering); CHECK_VTABLE_HOOK (flush); - CHECK_VTABLE_HOOK (get_context_info); + CHECK_VTABLE_HOOK (set_context_info); CHECK_VTABLE_HOOK (set_format); #undef CHECK_VTABLE_HOOK diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 076273c870..d23646f216 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1585,23 +1585,15 @@ end: return GST_VAAPI_ENCODER_STATUS_SUCCESS; } -static gboolean -gst_vaapi_encoder_h264_get_context_info (GstVaapiEncoder * base, - GstVaapiContextInfo * info) +static void +gst_vaapi_encoder_h264_set_context_info (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base); - const static guint default_surface_num = 3; + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); + GstVaapiContextInfo *const cip = &base_encoder->context_info; + const guint DEFAULT_SURFACES_COUNT = 3; - g_return_val_if_fail (info, FALSE); - - info->profile = encoder->profile; - info->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; - info->width = GST_VAAPI_ENCODER_WIDTH (encoder); - info->height = GST_VAAPI_ENCODER_HEIGHT (encoder); - info->ref_frames = (encoder->b_frame_num ? 2 : 1) + default_surface_num; - info->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); - - return TRUE; + cip->profile = encoder->profile; + cip->ref_frames = (encoder->b_frame_num ? 2 : 1) + DEFAULT_SURFACES_COUNT; } static GstCaps * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 5bc01d55b2..876dc6d995 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -627,22 +627,14 @@ to_vaapi_profile (guint32 profile) return p; } -static gboolean -gst_vaapi_encoder_mpeg2_get_context_info (GstVaapiEncoder * base, - GstVaapiContextInfo * info) +static void +gst_vaapi_encoder_mpeg2_set_context_info (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); + GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2 (base_encoder); + GstVaapiContextInfo *const cip = &base_encoder->context_info; - g_return_val_if_fail (info, FALSE); - - info->profile = to_vaapi_profile (encoder->profile); - info->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; - info->width = GST_VAAPI_ENCODER_WIDTH (encoder); - info->height = GST_VAAPI_ENCODER_HEIGHT (encoder); - info->ref_frames = 2; - info->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); - - return TRUE; + cip->profile = to_vaapi_profile (encoder->profile); + cip->ref_frames = 2; } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 10b1ff9df9..e570602530 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -80,6 +80,7 @@ struct _GstVaapiEncoder GstVaapiDisplay *display; GstVaapiContext *context; + GstVaapiContextInfo context_info; GstCaps *caps; VADisplay va_display; @@ -106,8 +107,7 @@ struct _GstVaapiEncoderClass GstVideoCodecState * in_state, GstCaps * ref_caps); - gboolean (*get_context_info) (GstVaapiEncoder * encoder, - GstVaapiContextInfo * info); + void (*set_context_info) (GstVaapiEncoder * encoder); GstVaapiEncoderStatus (*reordering) (GstVaapiEncoder * encoder, GstVideoCodecFrame * in, @@ -137,7 +137,7 @@ struct _GstVaapiEncoderClass GST_VAAPI_ENCODER_CLASS_HOOK (codec, init), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, finalize), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, set_format), \ - GST_VAAPI_ENCODER_CLASS_HOOK (codec, get_context_info), \ + GST_VAAPI_ENCODER_CLASS_HOOK (codec, set_context_info), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, reordering), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, encode), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, flush) From b864d1f71acc47bd41b8e7171c4ad4d6628849f4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 4 Dec 2013 19:10:13 +0100 Subject: [PATCH 1446/3781] encoder: fix computation of max coded buffer size. Fix coded buffer size for each codec. A generic issue was that the number of macroblocks was incorrectly computed. The second issue was specific to MPEG-2 were the max number of bits per macroblock, and as defined by the standard, was incorrectly mapped to the (lower) H.264 requirement. i.e. 4608 bits vs. 3200 bits limit. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 3 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 ++++++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index e56886fa12..e0be314185 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -371,9 +371,6 @@ gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, if (!gst_vaapi_encoder_ensure_context (encoder)) goto error; - encoder->codedbuf_size = (GST_VAAPI_ENCODER_WIDTH (encoder) * - GST_VAAPI_ENCODER_HEIGHT (encoder) * 400) / (16 * 16); - encoder->codedbuf_pool = gst_vaapi_coded_buffer_pool_new (encoder, encoder->codedbuf_size); if (!encoder->codedbuf_pool) { diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index d23646f216..a9a9b136e2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1594,6 +1594,12 @@ gst_vaapi_encoder_h264_set_context_info (GstVaapiEncoder * base_encoder) cip->profile = encoder->profile; cip->ref_frames = (encoder->b_frame_num ? 2 : 1) + DEFAULT_SURFACES_COUNT; + + /* Only YUV 4:2:0 formats are supported for now. This means that we + have a limit of 3200 bits per macroblock. */ + /* XXX: check profile and compute RawMbBits */ + base_encoder->codedbuf_size = (GST_ROUND_UP_16 (cip->width) * + GST_ROUND_UP_16 (cip->height) / 256) * 400; } static GstCaps * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 876dc6d995..90a6e23d88 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -635,6 +635,11 @@ gst_vaapi_encoder_mpeg2_set_context_info (GstVaapiEncoder * base_encoder) cip->profile = to_vaapi_profile (encoder->profile); cip->ref_frames = 2; + + /* Only YUV 4:2:0 formats are supported for now. This means that we + have a limit of 4608 bits per macroblock. */ + base_encoder->codedbuf_size = (GST_ROUND_UP_16 (cip->width) * + GST_ROUND_UP_16 (cip->height) / 256) * 576; } static gboolean From 2940a74ea45956edb8ec3e94bb983e255fcf0dc1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 5 Dec 2013 18:13:54 +0100 Subject: [PATCH 1447/3781] encoder: fix computation of max coded buffer size (again). The previous fix was only valid to express the maximum size of the macroblock layer, i.e. without any headers. Now, also account for the slice headers and top picture header, but also any other header we might stuff into the VA coded buffer, e.g. sequence headers. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 22 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index a9a9b136e2..cc5dbcc70a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1592,6 +1592,15 @@ gst_vaapi_encoder_h264_set_context_info (GstVaapiEncoder * base_encoder) GstVaapiContextInfo *const cip = &base_encoder->context_info; const guint DEFAULT_SURFACES_COUNT = 3; + /* Maximum sizes for common headers (in bits) */ + enum { + MAX_SPS_HDR_SIZE = 16473, + MAX_VUI_PARAMS_SIZE = 210, + MAX_HRD_PARAMS_SIZE = 4103, + MAX_PPS_HDR_SIZE = 101, + MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402, + }; + cip->profile = encoder->profile; cip->ref_frames = (encoder->b_frame_num ? 2 : 1) + DEFAULT_SURFACES_COUNT; @@ -1600,6 +1609,19 @@ gst_vaapi_encoder_h264_set_context_info (GstVaapiEncoder * base_encoder) /* XXX: check profile and compute RawMbBits */ base_encoder->codedbuf_size = (GST_ROUND_UP_16 (cip->width) * GST_ROUND_UP_16 (cip->height) / 256) * 400; + + /* Account for SPS header */ + /* XXX: exclude scaling lists, MVC/SVC extensions */ + base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE + + MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8; + + /* Account for PPS header */ + /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */ + base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8; + + /* Account for slice header. At most 200 slices are supported */ + base_encoder->codedbuf_size += 200 * (4 + + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); } static GstCaps * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 90a6e23d88..62d98eff07 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -633,6 +633,16 @@ gst_vaapi_encoder_mpeg2_set_context_info (GstVaapiEncoder * base_encoder) GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2 (base_encoder); GstVaapiContextInfo *const cip = &base_encoder->context_info; + /* Maximum sizes for common headers (in bytes) */ + enum { + MAX_SEQ_HDR_SIZE = 140, + MAX_SEQ_EXT_SIZE = 10, + MAX_GOP_SIZE = 8, + MAX_PIC_HDR_SIZE = 10, + MAX_PIC_EXT_SIZE = 11, + MAX_SLICE_HDR_SIZE = 8, + }; + cip->profile = to_vaapi_profile (encoder->profile); cip->ref_frames = 2; @@ -640,6 +650,18 @@ gst_vaapi_encoder_mpeg2_set_context_info (GstVaapiEncoder * base_encoder) have a limit of 4608 bits per macroblock. */ base_encoder->codedbuf_size = (GST_ROUND_UP_16 (cip->width) * GST_ROUND_UP_16 (cip->height) / 256) * 576; + + /* Account for Sequence, GOP, and Picture headers */ + /* XXX: exclude unused Sequence Display Extension, Sequence Scalable + Extension, Quantization Matrix Extension, Picture Display Extension, + Picture Temporal Scalable Extension, Picture Spatial Scalable + Extension */ + base_encoder->codedbuf_size += MAX_SEQ_HDR_SIZE + MAX_SEQ_EXT_SIZE + + MAX_GOP_SIZE + MAX_PIC_HDR_SIZE + MAX_PIC_EXT_SIZE; + + /* Account for Slice headers. We use one slice per line of macroblock */ + base_encoder->codedbuf_size += (GST_ROUND_UP_16 (cip->height) / 16) * + MAX_SLICE_HDR_SIZE; } static gboolean From 44ead80f5f61a5cbe98efe396d2f76c2ac9785fc Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Tue, 3 Dec 2013 11:05:17 +0000 Subject: [PATCH 1448/3781] Fix missing files in distribution tarball. https://bugzilla.gnome.org/show_bug.cgi?id=719776 [Additional fixes and clean-ups] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/base/Makefile.am | 5 +++++ gst-libs/gst/vaapi/Makefile.am | 11 ++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/base/Makefile.am b/gst-libs/gst/base/Makefile.am index 0520e64af1..b3c1dada20 100644 --- a/gst-libs/gst/base/Makefile.am +++ b/gst-libs/gst/base/Makefile.am @@ -39,5 +39,10 @@ libgstvaapi_baseutils_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) +EXTRA_DIST = \ + $(source_c) \ + $(source_h) \ + $(NULL) + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index e402da0bd1..993c7626c3 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -155,7 +155,9 @@ libgstvaapi_enc_source_h = \ libgstvaapi_enc_source_priv_h = \ gstvaapicodedbuffer_priv.h \ - gstvaapicodedbufferpool_priv.h \ + gstvaapicodedbufferproxy_priv.h \ + gstvaapiencoder_h264_priv.h \ + gstvaapiencoder_mpeg2_priv.h \ gstvaapiencoder_objects.h \ gstvaapiencoder_priv.h \ $(NULL) @@ -448,8 +450,11 @@ BUILT_SOURCES = gstvaapiversion.h EXTRA_DIST = gstvaapiversion.h.in $(PKG_VERSION_FILE) EXTRA_DIST += \ - $(libgstvaapi_jpegdec_source_c) \ - $(libgstvaapi_jpegdec_source_h) \ + $(libgstvaapi_enc_source_c) \ + $(libgstvaapi_enc_source_h) \ + $(libgstvaapi_enc_source_priv_h) \ + $(libgstvaapi_jpegdec_source_c) \ + $(libgstvaapi_jpegdec_source_h) \ $(NULL) CLEANFILES = \ From 47dee4db9620877af21b1da948147ae7174f28ef Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 6 Dec 2013 17:21:52 +0100 Subject: [PATCH 1449/3781] utils: add new H.264 helper functions. * Profiles: - gst_vaapi_utils_h264_get_profile(): Returns GstVaapiProfile from H.264 profile_idc value - gst_vaapi_utils_h264_get_profile_idc(): Returns H.264 profile_idc value from GstVaapiProfile * Chroma formats: - gst_vaapi_utils_h264_get_chroma_type(): Returns GstVaapiChromaType from H.264 chroma_format_idc value - gst_vaapi_utils_h264_get_chroma_format_idc(): Returns H.264 chroma_format_idc value from GstVaapiChromaType --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 44 +------- gst-libs/gst/vaapi/gstvaapiutils_h264.c | 127 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_h264.h | 54 +++++++++ 4 files changed, 186 insertions(+), 41 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_h264.c create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_h264.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 993c7626c3..6fc45836fd 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -69,6 +69,7 @@ libgstvaapi_source_c = \ gstvaapisurfacepool.c \ gstvaapisurfaceproxy.c \ gstvaapiutils.c \ + gstvaapiutils_h264.c \ gstvaapivalue.c \ gstvaapivideopool.c \ gstvaapiwindow.c \ @@ -120,6 +121,7 @@ libgstvaapi_source_priv_h = \ gstvaapisurface_priv.h \ gstvaapisurfaceproxy_priv.h \ gstvaapiutils.h \ + gstvaapiutils_h264.h \ gstvaapiversion.h \ gstvaapivideopool_priv.h \ gstvaapiwindow_priv.h \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index ba4c0b5e9b..3b0af8a030 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -34,6 +34,7 @@ #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" +#include "gstvaapiutils_h264.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -762,45 +763,6 @@ gst_vaapi_decoder_h264_create(GstVaapiDecoder *base_decoder) return TRUE; } -static guint -h264_get_profile(GstH264SPS *sps) -{ - guint profile = 0; - - switch (sps->profile_idc) { - case GST_H264_PROFILE_BASELINE: - profile = GST_VAAPI_PROFILE_H264_BASELINE; - break; - case GST_H264_PROFILE_MAIN: - profile = GST_VAAPI_PROFILE_H264_MAIN; - break; - case GST_H264_PROFILE_HIGH: - profile = GST_VAAPI_PROFILE_H264_HIGH; - break; - } - return profile; -} - -static guint -h264_get_chroma_type(GstH264SPS *sps) -{ - guint chroma_type = 0; - - switch (sps->chroma_format_idc) { - case 1: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - break; - case 2: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; - break; - case 3: - if (!sps->separate_colour_plane_flag) - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; - break; - } - return chroma_type; -} - static GstVaapiProfile get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) { @@ -809,7 +771,7 @@ get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) GstVaapiProfile profile, profiles[2]; guint i, n_profiles = 0; - profile = h264_get_profile(sps); + profile = gst_vaapi_utils_h264_get_profile(sps->profile_idc); if (!profile) return GST_VAAPI_PROFILE_UNKNOWN; @@ -857,7 +819,7 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) priv->profile = profile; } - chroma_type = h264_get_chroma_type(sps); + chroma_type = gst_vaapi_utils_h264_get_chroma_type(sps->chroma_format_idc); if (!chroma_type || chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) { GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c new file mode 100644 index 0000000000..8ddc7fbaab --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -0,0 +1,127 @@ +/* + * gstvaapiutils_h264.c - H.264 related utilities + * + * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 +#include "gstvaapiutils_h264.h" + +/** Returns GstVaapiProfile from H.264 profile_idc value */ +GstVaapiProfile +gst_vaapi_utils_h264_get_profile (guint8 profile_idc) +{ + GstVaapiProfile profile; + + switch (profile_idc) { + case GST_H264_PROFILE_BASELINE: + profile = GST_VAAPI_PROFILE_H264_BASELINE; + break; + case GST_H264_PROFILE_MAIN: + profile = GST_VAAPI_PROFILE_H264_MAIN; + break; + case GST_H264_PROFILE_HIGH: + profile = GST_VAAPI_PROFILE_H264_HIGH; + break; + default: + g_assert (0 && "unsupported profile_idc value"); + profile = GST_VAAPI_PROFILE_UNKNOWN; + break; + } + return profile; +} + +/** Returns H.264 profile_idc value from GstVaapiProfile */ +guint8 +gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile) +{ + guint8 profile_idc; + + switch (profile) { + case GST_VAAPI_PROFILE_H264_BASELINE: + profile_idc = GST_H264_PROFILE_BASELINE; + break; + case GST_VAAPI_PROFILE_H264_MAIN: + profile_idc = GST_H264_PROFILE_MAIN; + break; + case GST_VAAPI_PROFILE_H264_HIGH: + profile_idc = GST_H264_PROFILE_HIGH; + break; + default: + g_assert (0 && "unsupported GstVaapiProfile value"); + profile_idc = 0; + break; + } + return profile_idc; +} + +/** Returns GstVaapiChromaType from H.264 chroma_format_idc value */ +GstVaapiChromaType +gst_vaapi_utils_h264_get_chroma_type (guint chroma_format_idc) +{ + GstVaapiChromaType chroma_type; + + switch (chroma_format_idc) { + case 0: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400; + break; + case 1: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + break; + case 2: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; + break; + case 3: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; + break; + default: + g_assert (0 && "unsupported chroma_format_idc value"); + chroma_type = (GstVaapiChromaType) 0; + break; + } + return chroma_type; +} + +/** Returns H.264 chroma_format_idc value from GstVaapiChromaType */ +guint +gst_vaapi_utils_h264_get_chroma_format_idc (GstVaapiChromaType chroma_type) +{ + guint chroma_format_idc; + + switch (chroma_type) { + case GST_VAAPI_CHROMA_TYPE_YUV400: + chroma_format_idc = 0; + break; + case GST_VAAPI_CHROMA_TYPE_YUV420: + chroma_format_idc = 1; + break; + case GST_VAAPI_CHROMA_TYPE_YUV422: + chroma_format_idc = 2; + break; + case GST_VAAPI_CHROMA_TYPE_YUV444: + chroma_format_idc = 3; + break; + default: + g_assert (0 && "unsupported GstVaapiChromaType value"); + chroma_format_idc = 1; + break; + } + return chroma_format_idc; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.h b/gst-libs/gst/vaapi/gstvaapiutils_h264.h new file mode 100644 index 0000000000..f1abf22452 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.h @@ -0,0 +1,54 @@ +/* + * gstvaapiutils_h264.h - H.264 related utilities + * + * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_UTILS_H264_H +#define GST_VAAPI_UTILS_H264_H + +#include +#include +#include + +G_BEGIN_DECLS + +/* Returns GstVaapiProfile from H.264 profile_idc value */ +G_GNUC_INTERNAL +GstVaapiProfile +gst_vaapi_utils_h264_get_profile (guint8 profile_idc); + +/* Returns H.264 profile_idc value from GstVaapiProfile */ +G_GNUC_INTERNAL +guint8 +gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile); + +/* Returns GstVaapiChromaType from H.264 chroma_format_idc value */ +G_GNUC_INTERNAL +GstVaapiChromaType +gst_vaapi_utils_h264_get_chroma_type (guint chroma_format_idc); + +/* Returns H.264 chroma_format_idc value from GstVaapiChromaType */ +G_GNUC_INTERNAL +guint +gst_vaapi_utils_h264_get_chroma_format_idc (GstVaapiChromaType chroma_type); + +G_END_DECLS + +#endif /* GST_VAAPI_UTILS_H264_H */ From 7f1f879e28a9776ddc001508c08d719c95a833f1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 6 Dec 2013 17:34:52 +0100 Subject: [PATCH 1450/3781] utils: add new H.264 profiles. Add "Constrained Baseline Profile" and "High 10 Profile" definitions and helper functiions. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 6 ++++++ gst-libs/gst/vaapi/gstvaapiprofile.h | 3 +++ gst-libs/gst/vaapi/gstvaapiutils_h264.c | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 6169c4d3e0..91c9fbd0d6 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -80,6 +80,12 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_H264_BASELINE, VAProfileH264Baseline, "video/x-h264", "baseline" }, +#if VA_CHECK_VERSION(0,31,1) + { GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE, + VAProfileH264ConstrainedBaseline, + "video/x-h264", "constrained-baseline" + }, +#endif { GST_VAAPI_PROFILE_H264_MAIN, VAProfileH264Main, "video/x-h264", "main" }, diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 53a683aac1..750249dc1f 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -112,8 +112,11 @@ typedef enum { GST_VAAPI_PROFILE_MPEG4_MAIN = GST_VAAPI_MAKE_PROFILE(MPEG4,3), GST_VAAPI_PROFILE_H263_BASELINE = GST_VAAPI_MAKE_PROFILE(H263,1), GST_VAAPI_PROFILE_H264_BASELINE = GST_VAAPI_MAKE_PROFILE(H264,1), + GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE = + GST_VAAPI_MAKE_PROFILE(H264,9), GST_VAAPI_PROFILE_H264_MAIN = GST_VAAPI_MAKE_PROFILE(H264,2), GST_VAAPI_PROFILE_H264_HIGH = GST_VAAPI_MAKE_PROFILE(H264,3), + GST_VAAPI_PROFILE_H264_HIGH10 = GST_VAAPI_MAKE_PROFILE(H264,7), GST_VAAPI_PROFILE_VC1_SIMPLE = GST_VAAPI_MAKE_PROFILE(VC1,1), GST_VAAPI_PROFILE_VC1_MAIN = GST_VAAPI_MAKE_PROFILE(VC1,2), GST_VAAPI_PROFILE_VC1_ADVANCED = GST_VAAPI_MAKE_PROFILE(VC1,3), diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index 8ddc7fbaab..b6d908594e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -40,6 +40,9 @@ gst_vaapi_utils_h264_get_profile (guint8 profile_idc) case GST_H264_PROFILE_HIGH: profile = GST_VAAPI_PROFILE_H264_HIGH; break; + case GST_H264_PROFILE_HIGH10: + profile = GST_VAAPI_PROFILE_H264_HIGH10; + break; default: g_assert (0 && "unsupported profile_idc value"); profile = GST_VAAPI_PROFILE_UNKNOWN; @@ -56,6 +59,7 @@ gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile) switch (profile) { case GST_VAAPI_PROFILE_H264_BASELINE: + case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE: profile_idc = GST_H264_PROFILE_BASELINE; break; case GST_VAAPI_PROFILE_H264_MAIN: @@ -64,6 +68,9 @@ gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile) case GST_VAAPI_PROFILE_H264_HIGH: profile_idc = GST_H264_PROFILE_HIGH; break; + case GST_VAAPI_PROFILE_H264_HIGH10: + profile_idc = GST_H264_PROFILE_HIGH10; + break; default: g_assert (0 && "unsupported GstVaapiProfile value"); profile_idc = 0; From e2f137f149f506e3e36381911901d5682cfa8969 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 6 Dec 2013 19:05:52 +0100 Subject: [PATCH 1451/3781] utils: add helpers for H.264 levels. - gst_vaapi_utils_h264_get_level(): Returns GstVaapiLevelH264 from H.264 level_idc value - gst_vaapi_utils_h264_get_level_idc(): Returns H.264 level_idc value from GstVaapiLevelH264 - gst_vaapi_utils_h264_get_level_limits(): Returns level limits as specified in Table A-1 of the H.264 standard - gst_vaapi_utils_h264_get_level_limits_table(): Returns the Table A-1 specification --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 33 +++------ gst-libs/gst/vaapi/gstvaapiutils_h264.c | 71 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_h264.h | 83 +++++++++++++++++++++++ 3 files changed, 165 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 3b0af8a030..04f21e452b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -417,34 +417,23 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) static guint get_max_dec_frame_buffering(GstH264SPS *sps) { - guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs; + guint max_dec_frame_buffering, PicSizeMbs; + GstVaapiLevelH264 level; + const GstVaapiH264LevelLimits *level_limits; /* Table A-1 - Level limits */ - switch (sps->level_idc) { - case 10: MaxDpbMbs = 396; break; - case 11: MaxDpbMbs = 900; break; - case 12: MaxDpbMbs = 2376; break; - case 13: MaxDpbMbs = 2376; break; - case 20: MaxDpbMbs = 2376; break; - case 21: MaxDpbMbs = 4752; break; - case 22: MaxDpbMbs = 8100; break; - case 30: MaxDpbMbs = 8100; break; - case 31: MaxDpbMbs = 18000; break; - case 32: MaxDpbMbs = 20480; break; - case 40: MaxDpbMbs = 32768; break; - case 41: MaxDpbMbs = 32768; break; - case 42: MaxDpbMbs = 34816; break; - case 50: MaxDpbMbs = 110400; break; - case 51: MaxDpbMbs = 184320; break; - default: - g_assert(0 && "unhandled level"); - break; - } + if (G_UNLIKELY(sps->level_idc == 11 && sps->constraint_set3_flag)) + level = GST_VAAPI_LEVEL_H264_L1b; + else + level = gst_vaapi_utils_h264_get_level(sps->level_idc); + level_limits = gst_vaapi_utils_h264_get_level_limits(level); + if (!level_limits) + return 16; PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) * (sps->pic_height_in_map_units_minus1 + 1) * (sps->frame_mbs_only_flag ? 1 : 2)); - max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs; + max_dec_frame_buffering = level_limits->MaxDpbMbs / PicSizeMbs; /* VUI parameters */ if (sps->vui_parameters_present_flag) { diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index b6d908594e..b7d2f43196 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -24,6 +24,31 @@ #include #include "gstvaapiutils_h264.h" +/* Table A-1 - Level limits */ +/* *INDENT-OFF* */ +static const GstVaapiH264LevelLimits gst_vaapi_h264_level_limits[] = { + /* level idc MaxMBPS MaxFS MaxDpbMbs MaxBR */ + { GST_VAAPI_LEVEL_H264_L1, 10, 1485, 99, 396, 64 }, + { GST_VAAPI_LEVEL_H264_L1b, 11, 1485, 99, 396, 128 }, + { GST_VAAPI_LEVEL_H264_L1_1, 11, 3000, 396, 900, 192 }, + { GST_VAAPI_LEVEL_H264_L1_2, 12, 6000, 396, 2376, 384 }, + { GST_VAAPI_LEVEL_H264_L1_3, 13, 11880, 396, 2376, 768 }, + { GST_VAAPI_LEVEL_H264_L2, 20, 11880, 396, 2376, 2000 }, + { GST_VAAPI_LEVEL_H264_L2_1, 21, 19800, 792, 4752, 4000 }, + { GST_VAAPI_LEVEL_H264_L2_2, 22, 20250, 1620, 8100, 4000 }, + { GST_VAAPI_LEVEL_H264_L3, 30, 40500, 1620, 8100, 10000 }, + { GST_VAAPI_LEVEL_H264_L3_1, 31, 108000, 3600, 18000, 14000 }, + { GST_VAAPI_LEVEL_H264_L3_2, 32, 216000, 5120, 20480, 20000 }, + { GST_VAAPI_LEVEL_H264_L4, 40, 245760, 8192, 32768, 20000 }, + { GST_VAAPI_LEVEL_H264_L4_1, 41, 245760, 8192, 32768, 50000 }, + { GST_VAAPI_LEVEL_H264_L4_2, 42, 522240, 8704, 34816, 50000 }, + { GST_VAAPI_LEVEL_H264_L5, 50, 589824, 22080, 110400, 135000 }, + { GST_VAAPI_LEVEL_H264_L5_1, 51, 983040, 36864, 184320, 240000 }, + { GST_VAAPI_LEVEL_H264_L5_2, 52, 2073600, 36864, 184320, 240000 }, + { 0, } +}; +/* *INDENT-ON* */ + /** Returns GstVaapiProfile from H.264 profile_idc value */ GstVaapiProfile gst_vaapi_utils_h264_get_profile (guint8 profile_idc) @@ -79,6 +104,52 @@ gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile) return profile_idc; } +/** Returns GstVaapiLevelH264 from H.264 level_idc value */ +GstVaapiLevelH264 +gst_vaapi_utils_h264_get_level (guint8 level_idc) +{ + const GstVaapiH264LevelLimits *llp; + + // Prefer Level 1.1 over level 1b + if (G_UNLIKELY (level_idc == 11)) + return GST_VAAPI_LEVEL_H264_L1_1; + + for (llp = gst_vaapi_h264_level_limits; llp->level != 0; llp++) { + if (llp->level_idc == level_idc) + return llp->level; + } + g_assert (0 && "unsupported level_idc value"); + return (GstVaapiLevelH264) 0; +} + +/** Returns H.264 level_idc value from GstVaapiLevelH264 */ +guint8 +gst_vaapi_utils_h264_get_level_idc (GstVaapiLevelH264 level) +{ + const GstVaapiH264LevelLimits *const llp = + gst_vaapi_utils_h264_get_level_limits (level); + + return llp ? llp->level_idc : 0; +} + +/** Returns level limits as specified in Table A-1 of the H.264 standard */ +const GstVaapiH264LevelLimits * +gst_vaapi_utils_h264_get_level_limits (GstVaapiLevelH264 level) +{ + if (level < GST_VAAPI_LEVEL_H264_L1 || level > GST_VAAPI_LEVEL_H264_L5_2) + return NULL; + return &gst_vaapi_h264_level_limits[level - GST_VAAPI_LEVEL_H264_L1]; +} + +/** Returns the Table A-1 specification */ +const GstVaapiH264LevelLimits * +gst_vaapi_utils_h264_get_level_limits_table (guint * out_length_ptr) +{ + if (out_length_ptr) + *out_length_ptr = G_N_ELEMENTS (gst_vaapi_h264_level_limits) - 1; + return gst_vaapi_h264_level_limits; +} + /** Returns GstVaapiChromaType from H.264 chroma_format_idc value */ GstVaapiChromaType gst_vaapi_utils_h264_get_chroma_type (guint chroma_format_idc) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.h b/gst-libs/gst/vaapi/gstvaapiutils_h264.h index f1abf22452..cbd7217982 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.h @@ -29,6 +29,69 @@ G_BEGIN_DECLS +/** + * GstVaapiLevelH264: + * @GST_VAAPI_LEVEL_H264_L1: H.264 level 1. + * @GST_VAAPI_LEVEL_H264_L1_1: H.264 level 1.1. + * @GST_VAAPI_LEVEL_H264_L1_2: H.264 level 1.2. + * @GST_VAAPI_LEVEL_H264_L1_3: H.264 level 1.3. + * @GST_VAAPI_LEVEL_H264_L2: H.264 level 2. + * @GST_VAAPI_LEVEL_H264_L2_1: H.264 level 2.1. + * @GST_VAAPI_LEVEL_H264_L2_2: H.264 level 2.2. + * @GST_VAAPI_LEVEL_H264_L3: H.264 level 3. + * @GST_VAAPI_LEVEL_H264_L3_1: H.264 level 3.1. + * @GST_VAAPI_LEVEL_H264_L3_2: H.264 level 3.2. + * @GST_VAAPI_LEVEL_H264_L4: H.264 level 4. + * @GST_VAAPI_LEVEL_H264_L4_1: H.264 level 4.1. + * @GST_VAAPI_LEVEL_H264_L4_2: H.264 level 4.2. + * @GST_VAAPI_LEVEL_H264_L5: H.264 level 5. + * @GST_VAAPI_LEVEL_H264_L5_1: H.264 level 5.1. + * @GST_VAAPI_LEVEL_H264_L5_2: H.264 level 5.2. + * + * The set of all levels for #GstVaapiLevelH264. + */ +typedef enum +{ + GST_VAAPI_LEVEL_H264_L1 = 1, + GST_VAAPI_LEVEL_H264_L1b, + GST_VAAPI_LEVEL_H264_L1_1, + GST_VAAPI_LEVEL_H264_L1_2, + GST_VAAPI_LEVEL_H264_L1_3, + GST_VAAPI_LEVEL_H264_L2, + GST_VAAPI_LEVEL_H264_L2_1, + GST_VAAPI_LEVEL_H264_L2_2, + GST_VAAPI_LEVEL_H264_L3, + GST_VAAPI_LEVEL_H264_L3_1, + GST_VAAPI_LEVEL_H264_L3_2, + GST_VAAPI_LEVEL_H264_L4, + GST_VAAPI_LEVEL_H264_L4_1, + GST_VAAPI_LEVEL_H264_L4_2, + GST_VAAPI_LEVEL_H264_L5, + GST_VAAPI_LEVEL_H264_L5_1, + GST_VAAPI_LEVEL_H264_L5_2, +} GstVaapiLevelH264; + +/** + * GstVaapiH264LevelLimits: + * @level: the #GstVaapiLevelH264 + * @level_idc: the H.264 level_idc value + * @MaxMBPS: the maximum macroblock processing rate (MB/sec) + * @MaxFS: the maximum frame size (MBs) + * @MaxDpbMbs: the maxium decoded picture buffer size (MBs) + * @MaxBR: the maximum video bit rate (kbps) + * + * The data structure that describes the limits of an H.264 level. + */ +typedef struct +{ + GstVaapiLevelH264 level; + guint8 level_idc; + guint32 MaxMBPS; + guint32 MaxFS; + guint32 MaxDpbMbs; + guint32 MaxBR; +} GstVaapiH264LevelLimits; + /* Returns GstVaapiProfile from H.264 profile_idc value */ G_GNUC_INTERNAL GstVaapiProfile @@ -39,6 +102,26 @@ G_GNUC_INTERNAL guint8 gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile); +/* Returns GstVaapiLevelH264 from H.264 level_idc value */ +G_GNUC_INTERNAL +GstVaapiLevelH264 +gst_vaapi_utils_h264_get_level (guint8 level_idc); + +/* Returns H.264 level_idc value from GstVaapiLevelH264 */ +G_GNUC_INTERNAL +guint8 +gst_vaapi_utils_h264_get_level_idc (GstVaapiLevelH264 level); + +/* Returns level limits as specified in Table A-1 of the H.264 standard */ +G_GNUC_INTERNAL +const GstVaapiH264LevelLimits * +gst_vaapi_utils_h264_get_level_limits (GstVaapiLevelH264 level); + +/* Returns the Table A-1 specification */ +G_GNUC_INTERNAL +const GstVaapiH264LevelLimits * +gst_vaapi_utils_h264_get_level_limits_table (guint *out_length_ptr); + /* Returns GstVaapiChromaType from H.264 chroma_format_idc value */ G_GNUC_INTERNAL GstVaapiChromaType From f870469b0a4451f885de5a1d0e81f31ac7687150 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 9 Dec 2013 12:07:28 +0100 Subject: [PATCH 1452/3781] codecparsers: update to gst-vaapi-branch commit 177c73b. a7e3255 add H.265 (HEVC) bitstream parser 177c73b h264: fix picture level scaling lists derivation (rule B) 14733f1 h264: fix parsing of VCL HRD parameters 59a0b47 h264: store quantization matrices in zig-zag order ffb6e26 h264: add helpers to convert quantization matrices c78a504 mpeg2: also initialize debug category in parse_sequence_header() 719d1b0 mpeg2: turn internal consistency check into a g_assert() 5241d8e all: remove some unused functions 18eb312 all: fix for GST_DISABLE_GST_DEBUG 963c04a all: make warnings more meaningful --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index b33bd3214e..177c73b924 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit b33bd3214e9780d75719099a7e32fa59a286541e +Subproject commit 177c73b9246c5305cacc2b00a0da88182577f817 From bd5ae1b2205edaaf5581463cab200d15d80e7fd5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 9 Dec 2013 12:46:45 +0100 Subject: [PATCH 1453/3781] decoder: h264: fix decoding of scaling lists. The GStreamer codecparser layer now parses the scaling lists in zigzag scan order, as expected, so that to match the original bitstream layout and specification. However, further convert the scaling lists into raster scan order to fit the existing practice in most VA drivers. https://bugzilla.gnome.org/show_bug.cgi?id=706406 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 31 +++++++---------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 04f21e452b..559cd38475 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -864,30 +864,22 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) static void fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps) { - const guint8 (* const ScalingList4x4)[6][16] = &pps->scaling_lists_4x4; - guint i, j; + guint i; /* There are always 6 4x4 scaling lists */ g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4) == 6); g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16); - if (sizeof(iq_matrix->ScalingList4x4[0][0]) == 1) - memcpy(iq_matrix->ScalingList4x4, *ScalingList4x4, - sizeof(iq_matrix->ScalingList4x4)); - else { - for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) { - for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList4x4[i]); j++) - iq_matrix->ScalingList4x4[i][j] = (*ScalingList4x4)[i][j]; - } - } + for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) + gst_h264_video_quant_matrix_4x4_get_raster_from_zigzag( + iq_matrix->ScalingList4x4[i], pps->scaling_lists_4x4[i]); } static void fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps) { - const guint8 (* const ScalingList8x8)[6][64] = &pps->scaling_lists_8x8; const GstH264SPS * const sps = pps->sequence; - guint i, j, n; + guint i, n; /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */ if (!pps->transform_8x8_mode_flag) @@ -896,15 +888,10 @@ fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps) g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8) >= 2); g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64); - if (sizeof(iq_matrix->ScalingList8x8[0][0]) == 1) - memcpy(iq_matrix->ScalingList8x8, *ScalingList8x8, - sizeof(iq_matrix->ScalingList8x8)); - else { - n = (sps->chroma_format_idc != 3) ? 2 : 6; - for (i = 0; i < n; i++) { - for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList8x8[i]); j++) - iq_matrix->ScalingList8x8[i][j] = (*ScalingList8x8)[i][j]; - } + n = (sps->chroma_format_idc != 3) ? 2 : 6; + for (i = 0; i < n; i++) { + gst_h264_video_quant_matrix_8x8_get_raster_from_zigzag( + iq_matrix->ScalingList8x8[i], pps->scaling_lists_8x8[i]); } } From 009e4522bf798d187d4f1b931873ddcfb710e6db Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 6 Dec 2013 15:08:26 +0800 Subject: [PATCH 1454/3781] decoder: h264: add support for constrained baseline profile. Recognize streams marked as conforming to the "Constrained Baseline Profile". If VA driver supports that as is, fine. Otherwise, fallback to baseline, main or high profile. Constrained Baseline Profile conveys coding tools that are common to baseline profile and main profile. https://bugzilla.gnome.org/show_bug.cgi?id=719947 [Added fallbacks to main and high profiles] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 9 ++++++++- gst-libs/gst/vaapi/gstvaapiprofile.c | 6 ++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 559cd38475..4fa8e50969 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -757,15 +757,22 @@ get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) { GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder); - GstVaapiProfile profile, profiles[2]; + GstVaapiProfile profile, profiles[4]; guint i, n_profiles = 0; profile = gst_vaapi_utils_h264_get_profile(sps->profile_idc); if (!profile) return GST_VAAPI_PROFILE_UNKNOWN; + if (sps->constraint_set1_flag && profile == GST_VAAPI_PROFILE_H264_BASELINE) + profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + profiles[n_profiles++] = profile; switch (profile) { + case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE: + profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE; + profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_MAIN; + // fall-through case GST_VAAPI_PROFILE_H264_MAIN: profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; break; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 91c9fbd0d6..b29c199684 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -176,7 +176,7 @@ static GstVaapiProfile gst_vaapi_profile_from_codec_data_h264(GstBuffer *buffer) { /* MPEG-4 Part 15: Advanced Video Coding (AVC) file format */ - guchar buf[2]; + guchar buf[3]; if (gst_buffer_extract(buffer, 0, buf, sizeof(buf)) != sizeof(buf)) return 0; @@ -185,7 +185,9 @@ gst_vaapi_profile_from_codec_data_h264(GstBuffer *buffer) return 0; switch (buf[1]) { /* AVCProfileIndication */ - case 66: return GST_VAAPI_PROFILE_H264_BASELINE; + case 66: return ((buf[2] & 0x40) ? + GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE : + GST_VAAPI_PROFILE_H264_BASELINE); case 77: return GST_VAAPI_PROFILE_H264_MAIN; case 100: return GST_VAAPI_PROFILE_H264_HIGH; } From 3d510745c160dfe325065865af003c18b972d0da Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 10 Dec 2013 15:21:51 +0100 Subject: [PATCH 1455/3781] codecparsers: update to gst-vaapi-branch commit e7d0e18. e7d0e18 h264: complete set of NAL unit types --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 177c73b924..e7d0e18bc3 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 177c73b9246c5305cacc2b00a0da88182577f817 +Subproject commit e7d0e18bc3f3a2db119a03430a833047e1cc10d4 From 416ab33e347c0cd011ec37bff5d6e0fca90afb0b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 10 Dec 2013 11:13:01 +0100 Subject: [PATCH 1456/3781] utils: h264: add more profiles. Add extended profile (A.2.3), high 4:2:2 profile (A.2.6), high 4:2:2 profiles (A.2.7, A.2.10), scalable profiles (G.10.1.1, G.10.1.2) and multiview profiles (H.10.1.1, H.10.1.2). Document "Constrained Baseline" and "High 10" profiles. --- gst-libs/gst/vaapi/gstvaapiprofile.h | 36 +++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiutils_h264.c | 42 +++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 750249dc1f..aa83e35662 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -85,11 +85,33 @@ typedef enum { * @GST_VAAPI_PROFILE_H263_BASELINE: * H.263 baseline profile * @GST_VAAPI_PROFILE_H264_BASELINE: - * H.264 (MPEG-4 Part-10) baseline profile + * H.264 (MPEG-4 Part-10) baseline profile [A.2.1] + * @GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE: + * H.264 (MPEG-4 Part-10) constrained baseline profile [A.2.1.1] * @GST_VAAPI_PROFILE_H264_MAIN: - * H.264 (MPEG-4 Part-10) main profile + * H.264 (MPEG-4 Part-10) main profile [A.2.2] + * @GST_VAAPI_PROFILE_H264_EXTENDED: + * H.264 (MPEG-4 Part 10) extended profile [A.2.3] * @GST_VAAPI_PROFILE_H264_HIGH: - * H.264 (MPEG-4 Part-10) high profile + * H.264 (MPEG-4 Part-10) high profile [A.2.4] + * @GST_VAAPI_PROFILE_H264_HIGH10: + * H.264 (MPEG-4 Part-10) high 10 profile [A.2.5], or high 10 intra + * profile [A.2.8], depending on constraint_set3_flag + * @GST_VAAPI_PROFILE_H264_HIGH_422: + * H.264 (MPEG-4 Part-10) high 4:2:2 profile [A.2.6], or high 4:2:2 + * intra profile [A.2.9], depending on constraint_set3_flag + * @GST_VAAPI_PROFILE_H264_HIGH_444: + * H.264 (MPEG-4 Part-10) high 4:4:4 predictive profile [A.2.7], or + * high 4:4:4 intra profile [A.2.10], depending on constraint_set3_flag + * @GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE: + * H.264 (MPEG-4 Part-10) scalable baseline profile [G.10.1.1] + * @GST_VAAPI_PROFILE_H264_SCALABLE_HIGH: + * H.264 (MPEG-4 Part-10) scalable high profile [G.10.1.2], or scalable + * high intra profile [G.10.1.3], depending on constraint_set3_flag + * @GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH: + * H.264 (MPEG-4 Part-10) multiview high profile [H.10.1.1] + * @GST_VAAPI_PROFILE_H264_STEREO_HIGH: + * H.264 (MPEG-4 Part-10) stereo high profile [H.10.1.2] * @GST_VAAPI_PROFILE_VC1_SIMPLE: * VC-1 simple profile * @GST_VAAPI_PROFILE_VC1_MAIN: @@ -115,8 +137,16 @@ typedef enum { GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE = GST_VAAPI_MAKE_PROFILE(H264,9), GST_VAAPI_PROFILE_H264_MAIN = GST_VAAPI_MAKE_PROFILE(H264,2), + GST_VAAPI_PROFILE_H264_EXTENDED = GST_VAAPI_MAKE_PROFILE(H264,10), GST_VAAPI_PROFILE_H264_HIGH = GST_VAAPI_MAKE_PROFILE(H264,3), GST_VAAPI_PROFILE_H264_HIGH10 = GST_VAAPI_MAKE_PROFILE(H264,7), + GST_VAAPI_PROFILE_H264_HIGH_422 = GST_VAAPI_MAKE_PROFILE(H264,4), + GST_VAAPI_PROFILE_H264_HIGH_444 = GST_VAAPI_MAKE_PROFILE(H264,8), + GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE = + GST_VAAPI_MAKE_PROFILE(H264,5), + GST_VAAPI_PROFILE_H264_SCALABLE_HIGH = GST_VAAPI_MAKE_PROFILE(H264,6), + GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH = GST_VAAPI_MAKE_PROFILE(H264,11), + GST_VAAPI_PROFILE_H264_STEREO_HIGH = GST_VAAPI_MAKE_PROFILE(H264,15), GST_VAAPI_PROFILE_VC1_SIMPLE = GST_VAAPI_MAKE_PROFILE(VC1,1), GST_VAAPI_PROFILE_VC1_MAIN = GST_VAAPI_MAKE_PROFILE(VC1,2), GST_VAAPI_PROFILE_VC1_ADVANCED = GST_VAAPI_MAKE_PROFILE(VC1,3), diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index b7d2f43196..54d8dd7e9a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -62,12 +62,33 @@ gst_vaapi_utils_h264_get_profile (guint8 profile_idc) case GST_H264_PROFILE_MAIN: profile = GST_VAAPI_PROFILE_H264_MAIN; break; + case GST_H264_PROFILE_EXTENDED: + profile = GST_VAAPI_PROFILE_H264_EXTENDED; + break; case GST_H264_PROFILE_HIGH: profile = GST_VAAPI_PROFILE_H264_HIGH; break; case GST_H264_PROFILE_HIGH10: profile = GST_VAAPI_PROFILE_H264_HIGH10; break; + case GST_H264_PROFILE_HIGH_422: + profile = GST_VAAPI_PROFILE_H264_HIGH_422; + break; + case GST_H264_PROFILE_HIGH_444: + profile = GST_VAAPI_PROFILE_H264_HIGH_444; + break; + case GST_H264_PROFILE_SCALABLE_BASELINE: + profile = GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE; + break; + case GST_H264_PROFILE_SCALABLE_HIGH: + profile = GST_VAAPI_PROFILE_H264_SCALABLE_HIGH; + break; + case GST_H264_PROFILE_MULTIVIEW_HIGH: + profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH; + break; + case GST_H264_PROFILE_STEREO_HIGH: + profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH; + break; default: g_assert (0 && "unsupported profile_idc value"); profile = GST_VAAPI_PROFILE_UNKNOWN; @@ -90,12 +111,33 @@ gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile) case GST_VAAPI_PROFILE_H264_MAIN: profile_idc = GST_H264_PROFILE_MAIN; break; + case GST_VAAPI_PROFILE_H264_EXTENDED: + profile_idc = GST_H264_PROFILE_EXTENDED; + break; case GST_VAAPI_PROFILE_H264_HIGH: profile_idc = GST_H264_PROFILE_HIGH; break; case GST_VAAPI_PROFILE_H264_HIGH10: profile_idc = GST_H264_PROFILE_HIGH10; break; + case GST_VAAPI_PROFILE_H264_HIGH_422: + profile_idc = GST_H264_PROFILE_HIGH_422; + break; + case GST_VAAPI_PROFILE_H264_HIGH_444: + profile_idc = GST_H264_PROFILE_HIGH_444; + break; + case GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE: + profile_idc = GST_H264_PROFILE_SCALABLE_BASELINE; + break; + case GST_VAAPI_PROFILE_H264_SCALABLE_HIGH: + profile_idc = GST_H264_PROFILE_SCALABLE_HIGH; + break; + case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH: + profile_idc = GST_H264_PROFILE_MULTIVIEW_HIGH; + break; + case GST_VAAPI_PROFILE_H264_STEREO_HIGH: + profile_idc = GST_H264_PROFILE_STEREO_HIGH; + break; default: g_assert (0 && "unsupported GstVaapiProfile value"); profile_idc = 0; From 1dd89800b0e895b0b699889c3ef4617dca95c6c5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 10 Dec 2013 14:20:55 +0100 Subject: [PATCH 1457/3781] decoder: h264: fix decoding of BA3_SVA_C.264. Conformance test Base_Ext_Main_profiles/BA3_SVA_C.264 complys with extended profile specifications. However, the SPS header has the constraint_set1_flag syntax element set to 1. This means that, if a Main profile compliant decoder is available, then it should be able to decode this stream. This changes makes it possible to fall-back from Extended profile to Main profile if constraint_set1_flag is set to 1. https://bugzilla.gnome.org/show_bug.cgi?id=720190 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 41 +++++++++++++++++------ 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 4fa8e50969..1d1be555ca 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -752,6 +752,23 @@ gst_vaapi_decoder_h264_create(GstVaapiDecoder *base_decoder) return TRUE; } +static void +fill_profiles(GstVaapiProfile profiles[16], guint *n_profiles_ptr, + GstVaapiProfile profile) +{ + guint n_profiles = *n_profiles_ptr; + + profiles[n_profiles++] = profile; + switch (profile) { + case GST_VAAPI_PROFILE_H264_MAIN: + profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; + break; + default: + break; + } + *n_profiles_ptr = n_profiles; +} + static GstVaapiProfile get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) { @@ -764,17 +781,21 @@ get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) if (!profile) return GST_VAAPI_PROFILE_UNKNOWN; - if (sps->constraint_set1_flag && profile == GST_VAAPI_PROFILE_H264_BASELINE) - profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; - - profiles[n_profiles++] = profile; + fill_profiles(profiles, &n_profiles, profile); switch (profile) { - case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE: - profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE; - profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_MAIN; - // fall-through - case GST_VAAPI_PROFILE_H264_MAIN: - profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; + case GST_VAAPI_PROFILE_H264_BASELINE: + if (sps->constraint_set1_flag) { // A.2.2 (main profile) + fill_profiles(profiles, &n_profiles, + GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE); + fill_profiles(profiles, &n_profiles, + GST_VAAPI_PROFILE_H264_MAIN); + } + break; + case GST_VAAPI_PROFILE_H264_EXTENDED: + if (sps->constraint_set1_flag) { // A.2.2 (main profile) + fill_profiles(profiles, &n_profiles, + GST_VAAPI_PROFILE_H264_MAIN); + } break; default: break; From 6fe54964bba22a415424839299ae5a2635f3d24e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 10 Dec 2013 16:14:27 +0100 Subject: [PATCH 1458/3781] h264: improve robustness when packets are missing. Improve robustness when some expected packets where not received yet or that were not correctly decoded. For example, don't try to decode a picture if there was no valid frame headers parsed so far. https://bugs.freedesktop.org/show_bug.cgi?id=57902 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 55 ++++++++++++++++++++--- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 1d1be555ca..8d8efa027a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -349,8 +349,23 @@ gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs) #define GST_VAAPI_DECODER_H264_CAST(decoder) \ ((GstVaapiDecoderH264 *)(decoder)) +typedef enum { + GST_H264_VIDEO_STATE_GOT_SPS = 1 << 0, + GST_H264_VIDEO_STATE_GOT_PPS = 1 << 1, + GST_H264_VIDEO_STATE_GOT_SLICE = 1 << 2, + + GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS = ( + GST_H264_VIDEO_STATE_GOT_SPS | + GST_H264_VIDEO_STATE_GOT_PPS), + GST_H264_VIDEO_STATE_VALID_PICTURE = ( + GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS | + GST_H264_VIDEO_STATE_GOT_SLICE) +} GstH264VideoState; + struct _GstVaapiDecoderH264Private { GstH264NalParser *parser; + guint parser_state; + guint decoder_state; GstVaapiPictureH264 *current_picture; GstVaapiParserInfoH264 *prev_slice_pi; GstVaapiFrameStore *prev_frame; @@ -383,8 +398,6 @@ struct _GstVaapiDecoderH264Private { gboolean prev_pic_structure; // previous picture structure guint is_opened : 1; guint is_avcC : 1; - guint got_sps : 1; - guint got_pps : 1; guint has_context : 1; guint progressive_sequence : 1; }; @@ -949,12 +962,22 @@ ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static inline gboolean +is_valid_state(guint state, guint ref_state) +{ + return (state & ref_state) == ref_state; +} + static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPictureH264 * const picture = priv->current_picture; + if (!is_valid_state(priv->decoder_state, GST_H264_VIDEO_STATE_VALID_PICTURE)) + goto drop_frame; + priv->decoder_state = 0; + if (!picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -972,6 +995,10 @@ 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; + +drop_frame: + priv->decoder_state = 0; + return GST_VAAPI_DECODER_STATUS_DROP_FRAME; } static GstVaapiDecoderStatus @@ -984,6 +1011,8 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GST_DEBUG("parse SPS"); + priv->parser_state = 0; + /* Variables that don't have inferred values per the H.264 standard but that should get a default value anyway */ sps->log2_max_pic_order_cnt_lsb_minus4 = 0; @@ -992,7 +1021,7 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) if (result != GST_H264_PARSER_OK) return get_status(result); - priv->got_sps = TRUE; + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1006,6 +1035,8 @@ parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GST_DEBUG("parse PPS"); + priv->parser_state &= GST_H264_VIDEO_STATE_GOT_SPS; + /* Variables that don't have inferred values per the H.264 standard but that should get a default value anyway */ pps->slice_group_map_type = 0; @@ -1015,7 +1046,7 @@ parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) if (result != GST_H264_PARSER_OK) return get_status(result); - priv->got_pps = TRUE; + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_PPS; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1049,6 +1080,9 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GST_DEBUG("parse slice"); + priv->parser_state &= (GST_H264_VIDEO_STATE_GOT_SPS| + GST_H264_VIDEO_STATE_GOT_PPS); + /* Variables that don't have inferred values per the H.264 standard but that should get a default value anyway */ slice_hdr->cabac_init_idc = 0; @@ -1059,6 +1093,7 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) if (result != GST_H264_PARSER_OK) return get_status(result); + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SLICE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2502,6 +2537,8 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; + priv->decoder_state = 0; + if (priv->current_picture) { /* Re-use current picture where the first field was decoded */ picture = gst_vaapi_picture_h264_new_field(priv->current_picture); @@ -2543,6 +2580,10 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; if (!fill_picture(decoder, picture, pi)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + priv->decoder_state = priv->parser_state & ( + GST_H264_VIDEO_STATE_GOT_SPS | + GST_H264_VIDEO_STATE_GOT_PPS); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2704,8 +2745,9 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GST_DEBUG("slice (%u bytes)", pi->nalu.size); - if (!priv->got_sps || !priv->got_pps) { - GST_ERROR("not initialized yet"); + if (!is_valid_state(priv->decoder_state, + GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS)) { + GST_WARNING("failed to receive enough headers to decode slice"); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2729,6 +2771,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) gst_vaapi_picture_add_slice(GST_VAAPI_PICTURE_CAST(picture), slice); picture->last_slice_hdr = slice_hdr; + priv->decoder_state |= GST_H264_VIDEO_STATE_GOT_SLICE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } From c7673f1cd6bad19d3292896eea4ad485710926c5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 11 Dec 2013 10:51:03 +0100 Subject: [PATCH 1459/3781] plugins: robustify GstVideoGLTextureUploadMeta implementation. Make GstVideoGLTextureUploadMeta::upload() implementation more robust when the GstVaapiTexture associated with the supplied texture id could not be created. --- gst/vaapi/gstvaapivideometa_texture.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 10c3b9ac68..593950ab48 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -55,14 +55,18 @@ gst_vaapi_texture_upload(GstVideoGLTextureUploadMeta *meta, guint texture_id[4]) if (texture) { GstVaapiDisplay * const tex_dpy = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(texture)); - if (tex_dpy != dpy) + if (tex_dpy != dpy) { gst_vaapi_texture_replace(&texture, NULL); + meta->user_data = NULL; + } } if (!texture) { /* FIXME: should we assume target? */ texture = gst_vaapi_texture_new_with_texture(dpy, texture_id[0], GL_TEXTURE_2D, GL_RGBA); + if (!texture) + return FALSE; meta->user_data = texture; } From 6b6c10d94d927602f7d47a0bec57cc64431a893f Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Wed, 20 Nov 2013 17:20:07 +0000 Subject: [PATCH 1460/3781] plugins: request GLTextureUpload meta on buffers in the buffer pool. Requesting the GLTextureUpload meta on buffers in the bufferpool prevents such metas from being de-allocated when buffers are released in the sink. This is particulary useful in terms of performance when using the GLTextureUploadMeta API since the GstVaapiTexture associated with the target texture is stored in the meta. https://bugzilla.gnome.org/show_bug.cgi?id=712558 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 7 +++++-- gst/vaapi/gstvaapivideobufferpool.c | 15 ++++++++++++++- gst/vaapi/gstvaapivideobufferpool.h | 15 +++++++++++++++ gst/vaapi/gstvaapivideometa_texture.c | 7 +++++++ gst/vaapi/gstvaapivideometa_texture.h | 4 ++++ 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3225a95b59..9f399b779b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -343,7 +343,7 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec, #if GST_CHECK_VERSION(1,1,0) if (decode->has_texture_upload_meta) - gst_buffer_add_texture_upload_meta(out_frame->output_buffer); + gst_buffer_ensure_texture_upload_meta(out_frame->output_buffer); #endif #else out_frame->output_buffer = @@ -552,11 +552,14 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) config = gst_buffer_pool_get_config(pool); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); - gst_buffer_pool_set_config(pool, config); #if GST_CHECK_VERSION(1,1,0) decode->has_texture_upload_meta = gst_query_find_allocation_meta(query, GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); + if (decode->has_texture_upload_meta) + gst_buffer_pool_config_add_option(config, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); #endif + gst_buffer_pool_set_config(pool, config); } if (update_pool) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index f35dcbc67b..e0bc98f3b3 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -24,6 +24,9 @@ #include "gstvaapivideobufferpool.h" #include "gstvaapivideobuffer.h" #include "gstvaapivideomemory.h" +#if GST_CHECK_VERSION(1,1,0) +#include "gstvaapivideometa_texture.h" +#endif GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideopool); #define GST_CAT_DEFAULT gst_debug_vaapivideopool @@ -43,7 +46,8 @@ struct _GstVaapiVideoBufferPoolPrivate { guint video_info_index; GstAllocator *allocator; GstVaapiDisplay *display; - guint has_video_meta : 1; + guint has_video_meta : 1; + guint has_texture_upload_meta : 1; }; #define GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(obj) \ @@ -103,6 +107,7 @@ gst_vaapi_video_buffer_pool_get_options(GstBufferPool *pool) static const gchar *g_options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META, NULL, }; return g_options; @@ -147,6 +152,9 @@ gst_vaapi_video_buffer_pool_set_config(GstBufferPool *pool, priv->has_video_meta = gst_buffer_pool_config_has_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); + priv->has_texture_upload_meta = gst_buffer_pool_config_has_option(config, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); + return GST_BUFFER_POOL_CLASS(gst_vaapi_video_buffer_pool_parent_class)-> set_config(pool, config); @@ -214,6 +222,11 @@ gst_vaapi_video_buffer_pool_alloc_buffer(GstBufferPool *pool, vmeta->unmap = gst_video_meta_unmap_vaapi_memory; } +#if GST_CHECK_VERSION(1,1,0) + if (priv->has_texture_upload_meta) + gst_buffer_add_texture_upload_meta(buffer); +#endif + *out_buffer_ptr = buffer; return GST_FLOW_OK; diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index ae284f926d..ed646c287a 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -59,6 +59,21 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; */ #define GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META "GstBufferPoolOptionVaapiVideoMeta" +/** + * + * GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META: + * + * An option that can be activated on bufferpool to request gl texture + * upload on buffers from the pool. + * + * When this option is enabled on the bufferpool, + * #GST_BUFFER_POOL_OPTION_VIDEO_META should also be enabled. + */ +#ifndef GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META +#define GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META \ + "GstBufferPoolOptionVideoGLTextureUploadMeta" +#endif + /** * GstVaapiVideoBufferPool: * diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 593950ab48..18eb3e755f 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -96,4 +96,11 @@ gst_buffer_add_texture_upload_meta(GstBuffer *buffer) #endif return meta != NULL; } + +gboolean +gst_buffer_ensure_texture_upload_meta(GstBuffer *buffer) +{ + return gst_buffer_get_video_gl_texture_upload_meta(buffer) || + gst_buffer_add_texture_upload_meta(buffer); +} #endif diff --git a/gst/vaapi/gstvaapivideometa_texture.h b/gst/vaapi/gstvaapivideometa_texture.h index 289e98fe92..a3367b4d34 100644 --- a/gst/vaapi/gstvaapivideometa_texture.h +++ b/gst/vaapi/gstvaapivideometa_texture.h @@ -35,6 +35,10 @@ G_GNUC_INTERNAL gboolean gst_buffer_add_texture_upload_meta(GstBuffer *buffer); +G_GNUC_INTERNAL +gboolean +gst_buffer_ensure_texture_upload_meta(GstBuffer *buffer); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_META_TEXTURE_H */ From c2eabc17dd5411095427723c4af9d4b481a935f0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 11 Dec 2013 13:25:51 +0100 Subject: [PATCH 1461/3781] plugins: allow builds without GLX enabled for GStreamer 1.2. Don't try to build GLTextureUploadMeta related code if GLX is not enabled during GStreamer >= 1.2 builds. --- gst/vaapi/gstvaapidecode.c | 6 +++--- gst/vaapi/gstvaapivideobufferpool.c | 4 ++-- gst/vaapi/gstvaapivideometa_texture.c | 4 ---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9f399b779b..763eace701 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -37,7 +37,7 @@ #include "gstvaapipluginutil.h" #include "gstvaapivideocontext.h" #include "gstvaapivideobuffer.h" -#if GST_CHECK_VERSION(1,1,0) +#if GST_CHECK_VERSION(1,1,0) && USE_GLX #include "gstvaapivideometa_texture.h" #endif #if GST_CHECK_VERSION(1,0,0) @@ -341,7 +341,7 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec, } } -#if GST_CHECK_VERSION(1,1,0) +#if GST_CHECK_VERSION(1,1,0) && USE_GLX if (decode->has_texture_upload_meta) gst_buffer_ensure_texture_upload_meta(out_frame->output_buffer); #endif @@ -552,7 +552,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) config = gst_buffer_pool_get_config(pool); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); -#if GST_CHECK_VERSION(1,1,0) +#if GST_CHECK_VERSION(1,1,0) && USE_GLX decode->has_texture_upload_meta = gst_query_find_allocation_meta(query, GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); if (decode->has_texture_upload_meta) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index e0bc98f3b3..894ba6beae 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -24,7 +24,7 @@ #include "gstvaapivideobufferpool.h" #include "gstvaapivideobuffer.h" #include "gstvaapivideomemory.h" -#if GST_CHECK_VERSION(1,1,0) +#if GST_CHECK_VERSION(1,1,0) && USE_GLX #include "gstvaapivideometa_texture.h" #endif @@ -222,7 +222,7 @@ gst_vaapi_video_buffer_pool_alloc_buffer(GstBufferPool *pool, vmeta->unmap = gst_video_meta_unmap_vaapi_memory; } -#if GST_CHECK_VERSION(1,1,0) +#if GST_CHECK_VERSION(1,1,0) && USE_GLX if (priv->has_texture_upload_meta) gst_buffer_add_texture_upload_meta(buffer); #endif diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 18eb3e755f..a27591d639 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -76,9 +76,7 @@ gst_vaapi_texture_upload(GstVideoGLTextureUploadMeta *meta, guint texture_id[4]) return gst_vaapi_texture_put_surface(texture, surface, gst_vaapi_video_meta_get_render_flags(vmeta)); } -#endif -#if GST_CHECK_VERSION(1,1,0) gboolean gst_buffer_add_texture_upload_meta(GstBuffer *buffer) { @@ -88,12 +86,10 @@ gst_buffer_add_texture_upload_meta(GstBuffer *buffer) if (!buffer) return FALSE; -#if USE_GLX meta = gst_buffer_add_video_gl_texture_upload_meta(buffer, GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, 1, tex_type, gst_vaapi_texture_upload, NULL, NULL, gst_vaapi_texure_upload_free); -#endif return meta != NULL; } From 61f6cbffc657fbe0287301018e365cd85607565c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 11 Dec 2013 14:04:27 +0100 Subject: [PATCH 1462/3781] plugins: fix GLTextureUploadMeta to work with different texture ids. The GLTextureUploadMeta implementation assumed that for each upload() sequence, the supplied texture id is always the same as the one that was previously cached into the underlying GstVaapiTexture. Cope with any texture id change the expense to recreate the underlying VA/GLX resources. https://bugzilla.gnome.org/show_bug.cgi?id=719643 --- gst-libs/gst/vaapi/gstvaapiobject.h | 18 ++++++ gst-libs/gst/vaapi/gstvaapiobject_priv.h | 2 + gst/vaapi/gstvaapivideometa_texture.c | 75 ++++++++++++++++-------- gst/vaapi/gstvaapivideometa_texture.h | 2 + 4 files changed, 72 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index 384ad884b1..ed76af1b8c 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -35,6 +35,24 @@ G_BEGIN_DECLS typedef struct _GstVaapiObject GstVaapiObject; +/** + * GST_VAAPI_OBJECT_DISPLAY: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the #GstVaapiDisplay the @object is bound to. + */ +#define GST_VAAPI_OBJECT_DISPLAY(object) \ + gst_vaapi_object_get_display(GST_VAAPI_OBJECT(object)) + +/** + * GST_VAAPI_OBJECT_ID: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the #GstVaapiID contained in @object. + */ +#define GST_VAAPI_OBJECT_ID(object) \ + gst_vaapi_object_get_id(GST_VAAPI_OBJECT(object)) + gpointer gst_vaapi_object_ref(gpointer object); diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index bd53684f61..4c91149c9f 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -73,6 +73,7 @@ G_PASTE(t_n,_class)(void) \ * Macro that evaluates to the #GstVaapiDisplay the @object is bound to. * This is an internal macro that does not do any run-time type check. */ +#undef GST_VAAPI_OBJECT_DISPLAY #define GST_VAAPI_OBJECT_DISPLAY(object) \ GST_VAAPI_OBJECT(object)->display @@ -83,6 +84,7 @@ G_PASTE(t_n,_class)(void) \ * Macro that evaluates to the #GstVaapiID contained in @object. * This is an internal macro that does not do any run-time type checks. */ +#undef GST_VAAPI_OBJECT_ID #define GST_VAAPI_OBJECT_ID(object) \ GST_VAAPI_OBJECT(object)->object_id diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index a27591d639..8a38be632e 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -30,13 +30,31 @@ #include "gstvaapipluginutil.h" #if GST_CHECK_VERSION(1,1,0) && USE_GLX -static void -gst_vaapi_texure_upload_free(gpointer data) -{ - GstVaapiTexture * const texture = data; +struct _GstVaapiVideoMetaTexture { + GstVaapiTexture *texture; +}; - if (texture) - gst_vaapi_texture_unref(texture); +static void +meta_texture_free(GstVaapiVideoMetaTexture *meta) +{ + if (G_UNLIKELY(!meta)) + return; + + gst_vaapi_texture_replace(&meta->texture, NULL); + g_slice_free(GstVaapiVideoMetaTexture, meta); +} + +static GstVaapiVideoMetaTexture * +meta_texture_new(void) +{ + GstVaapiVideoMetaTexture *meta; + + meta = g_slice_new(GstVaapiVideoMetaTexture); + if (!meta) + return NULL; + + meta->texture = NULL; + return meta; } static gboolean @@ -44,36 +62,32 @@ gst_vaapi_texture_upload(GstVideoGLTextureUploadMeta *meta, guint texture_id[4]) { GstVaapiVideoMeta * const vmeta = gst_buffer_get_vaapi_video_meta(meta->buffer); - GstVaapiTexture *texture = meta->user_data; + GstVaapiVideoMetaTexture * const meta_texture = meta->user_data; GstVaapiSurface * const surface = gst_vaapi_video_meta_get_surface(vmeta); - GstVaapiDisplay * const dpy = - gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); + GstVaapiDisplay * const dpy = GST_VAAPI_OBJECT_DISPLAY(surface); if (gst_vaapi_display_get_display_type(dpy) != GST_VAAPI_DISPLAY_TYPE_GLX) return FALSE; - if (texture) { - GstVaapiDisplay * const tex_dpy = - gst_vaapi_object_get_display(GST_VAAPI_OBJECT(texture)); - if (tex_dpy != dpy) { - gst_vaapi_texture_replace(&texture, NULL); - meta->user_data = NULL; - } - } - - if (!texture) { + if (!meta_texture->texture || + /* Check whether VA display changed */ + GST_VAAPI_OBJECT_DISPLAY(meta_texture->texture) != dpy || + /* Check whether texture id changed */ + gst_vaapi_texture_get_id(meta_texture->texture) != texture_id[0]) { /* FIXME: should we assume target? */ - texture = gst_vaapi_texture_new_with_texture(dpy, texture_id[0], - GL_TEXTURE_2D, GL_RGBA); + GstVaapiTexture * const texture = + gst_vaapi_texture_new_with_texture(dpy, texture_id[0], + GL_TEXTURE_2D, GL_RGBA); + gst_vaapi_texture_replace(&meta_texture->texture, texture); if (!texture) return FALSE; - meta->user_data = texture; + gst_vaapi_texture_unref(texture); } if (!gst_vaapi_apply_composition(surface, meta->buffer)) GST_WARNING("could not update subtitles"); - return gst_vaapi_texture_put_surface(texture, surface, + return gst_vaapi_texture_put_surface(meta_texture->texture, surface, gst_vaapi_video_meta_get_render_flags(vmeta)); } @@ -82,15 +96,26 @@ gst_buffer_add_texture_upload_meta(GstBuffer *buffer) { GstVideoGLTextureUploadMeta *meta = NULL; GstVideoGLTextureType tex_type[] = { GST_VIDEO_GL_TEXTURE_TYPE_RGBA }; + GstVaapiVideoMetaTexture *meta_texture; if (!buffer) return FALSE; + meta_texture = meta_texture_new(); + if (!meta_texture) + return FALSE; + meta = gst_buffer_add_video_gl_texture_upload_meta(buffer, GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, 1, tex_type, gst_vaapi_texture_upload, - NULL, NULL, gst_vaapi_texure_upload_free); - return meta != NULL; + meta_texture, NULL, (GBoxedFreeFunc)meta_texture_free); + if (!meta) + goto error; + return TRUE; + +error: + meta_texture_free(meta_texture); + return FALSE; } gboolean diff --git a/gst/vaapi/gstvaapivideometa_texture.h b/gst/vaapi/gstvaapivideometa_texture.h index a3367b4d34..c6e0e6bea6 100644 --- a/gst/vaapi/gstvaapivideometa_texture.h +++ b/gst/vaapi/gstvaapivideometa_texture.h @@ -31,6 +31,8 @@ G_BEGIN_DECLS +typedef struct _GstVaapiVideoMetaTexture GstVaapiVideoMetaTexture; + G_GNUC_INTERNAL gboolean gst_buffer_add_texture_upload_meta(GstBuffer *buffer); From 7e58d60854960d4d0561daeb88f575f1ddb656fd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Dec 2013 10:24:26 +0100 Subject: [PATCH 1463/3781] plugins: add new base object, store display in there. Introduce a new GstVaapiPluginBase object that will contain all common data structures and perform all common tasks. First step is to have a single place to hold VA displays. While we are at it, also make sure to store and subsequently release the appropriate debug category for the subclasses. --- gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapidecode.c | 37 ++++++---- gst/vaapi/gstvaapidecode.h | 10 +-- gst/vaapi/gstvaapidownload.c | 34 +++++---- gst/vaapi/gstvaapidownload.h | 3 +- gst/vaapi/gstvaapiencode.c | 38 ++++++---- gst/vaapi/gstvaapiencode.h | 8 +- gst/vaapi/gstvaapipluginbase.c | 76 +++++++++++++++++++ gst/vaapi/gstvaapipluginbase.h | 130 +++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipostproc.c | 40 ++++++---- gst/vaapi/gstvaapipostproc.h | 8 +- gst/vaapi/gstvaapisink.c | 94 ++++++++++++++---------- gst/vaapi/gstvaapisink.h | 8 +- gst/vaapi/gstvaapiupload.c | 32 +++++--- gst/vaapi/gstvaapiupload.h | 7 +- 15 files changed, 391 insertions(+), 136 deletions(-) create mode 100644 gst/vaapi/gstvaapipluginbase.c create mode 100644 gst/vaapi/gstvaapipluginbase.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 9e57d0de5d..9bef588ced 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -36,6 +36,7 @@ endif libgstvaapi_source_c = \ gstvaapi.c \ gstvaapidecode.c \ + gstvaapipluginbase.c \ gstvaapipluginutil.c \ gstvaapipostproc.c \ gstvaapisink.c \ @@ -47,6 +48,7 @@ libgstvaapi_source_c = \ libgstvaapi_source_h = \ gstvaapidecode.h \ + gstvaapipluginbase.h \ gstvaapipluginutil.h \ gstvaapipostproc.h \ gstvaapisink.h \ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 763eace701..102f0d42d7 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -120,7 +120,7 @@ gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type, const GValue *value) { GstVaapiDecode *decode = GST_VAAPIDECODE (context); - gst_vaapi_set_display (type, value, &decode->display); + gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); } static void @@ -518,7 +518,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12, GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); - g_return_val_if_fail(decode->display != NULL, FALSE); + g_return_val_if_fail(GST_VAAPI_PLUGIN_BASE_DISPLAY(decode) != NULL, FALSE); if (gst_query_get_n_allocation_pools(query) > 0) { gst_query_parse_nth_allocation_pool(query, 0, &pool, &size, &min, &max); @@ -536,7 +536,8 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) { GST_INFO("no pool or doesn't support GstVaapiVideoMeta, " "making new pool"); - pool = gst_vaapi_video_buffer_pool_new(decode->display); + pool = gst_vaapi_video_buffer_pool_new( + GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); if (!pool) goto error_create_pool; @@ -593,7 +594,7 @@ gst_vaapidecode_set_context(GstElement *element, GstContext *context) if (gst_vaapi_video_context_get_display(context, &display)) { GST_INFO_OBJECT(element, "set display %p", display); - gst_vaapi_display_replace(&decode->display, display); + GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(decode, display); gst_vaapi_display_unref(display); } } @@ -603,7 +604,7 @@ static inline gboolean gst_vaapidecode_ensure_display(GstVaapiDecode *decode) { return gst_vaapi_ensure_display(decode, GST_VAAPI_DISPLAY_TYPE_ANY, - &decode->display); + &GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); } static inline guint @@ -619,7 +620,7 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) if (!gst_vaapidecode_ensure_display(decode)) return FALSE; - dpy = decode->display; + dpy = GST_VAAPI_PLUGIN_BASE_DISPLAY(decode); switch (gst_vaapi_codec_from_caps(caps)) { case GST_VAAPI_CODEC_MPEG2: @@ -716,12 +717,11 @@ gst_vaapidecode_finalize(GObject *object) gst_caps_replace(&decode->srcpad_caps, NULL); gst_caps_replace(&decode->allowed_caps, NULL); - gst_vaapi_display_replace(&decode->display, NULL); - g_cond_clear(&decode->decoder_finish_done); g_cond_clear(&decode->decoder_ready); g_mutex_clear(&decode->decoder_mutex); + gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object)); G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object); } @@ -729,15 +729,18 @@ static gboolean gst_vaapidecode_open(GstVideoDecoder *vdec) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - GstVaapiDisplay * const old_display = decode->display; + GstVaapiDisplay * const old_display = GST_VAAPI_PLUGIN_BASE_DISPLAY(decode); gboolean success; + if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(decode))) + return FALSE; + /* Let GstVideoContext ask for a proper display to its neighbours */ /* Note: steal old display that may be allocated from get_caps() so that to retain a reference to it, thus avoiding extra initialization steps if we turn out to simply re-use the existing (cached) VA display */ - decode->display = NULL; + GST_VAAPI_PLUGIN_BASE_DISPLAY(decode) = NULL; success = gst_vaapidecode_ensure_display(decode); if (old_display) gst_vaapi_display_unref(old_display); @@ -750,7 +753,7 @@ gst_vaapidecode_close(GstVideoDecoder *vdec) GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); gst_vaapidecode_destroy(decode); - gst_vaapi_display_replace(&decode->display, NULL); + gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(decode)); return TRUE; } @@ -835,6 +838,8 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass)); + object_class->finalize = gst_vaapidecode_finalize; vdec_class->open = GST_DEBUG_FUNCPTR(gst_vaapidecode_open); @@ -881,7 +886,8 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) if (!gst_vaapidecode_ensure_display(decode)) goto error_no_display; - decode_caps = gst_vaapi_display_get_decode_caps(decode->display); + decode_caps = gst_vaapi_display_get_decode_caps( + GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); if (!decode_caps) goto error_no_decode_caps; n_decode_caps = gst_caps_get_size(decode_caps); @@ -945,8 +951,8 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) GST_INFO_OBJECT(decode, "query type %s", GST_QUERY_TYPE_NAME(query)); - if (gst_vaapi_reply_to_query(query, decode->display)) { - GST_DEBUG("sharing display %p", decode->display); + if (gst_vaapi_reply_to_query(query, GST_VAAPI_PLUGIN_BASE_DISPLAY(decode))) { + GST_DEBUG("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); res = TRUE; } else if (GST_PAD_IS_SINK(pad)) { @@ -979,7 +985,8 @@ gst_vaapidecode_init(GstVaapiDecode *decode) { GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); - decode->display = NULL; + gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(decode), GST_CAT_DEFAULT); + decode->decoder = NULL; decode->decoder_caps = NULL; decode->allowed_caps = NULL; diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index e28266b0ab..ed1e9bfa99 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -25,10 +25,7 @@ #ifndef GST_VAAPIDECODE_H #define GST_VAAPIDECODE_H -#include -#include -#include -#include +#include "gstvaapipluginbase.h" #include G_BEGIN_DECLS @@ -62,7 +59,7 @@ typedef struct _GstVaapiDecodeClass GstVaapiDecodeClass; struct _GstVaapiDecode { /*< private >*/ - GstVideoDecoder parent_instance; + GstVaapiPluginBase parent_instance; GstPad *sinkpad; GstCaps *sinkpad_caps; @@ -70,7 +67,6 @@ struct _GstVaapiDecode { GstPad *srcpad; GstCaps *srcpad_caps; GstPadQueryFunction srcpad_query; - GstVaapiDisplay *display; GstVaapiDecoder *decoder; GMutex decoder_mutex; GCond decoder_ready; @@ -85,7 +81,7 @@ struct _GstVaapiDecode { struct _GstVaapiDecodeClass { /*< private >*/ - GstVideoDecoderClass parent_class; + GstVaapiPluginBaseClass parent_class; }; GType diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 8e5e0ce9ec..c59662595b 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -75,9 +75,8 @@ struct _TransformSizeCache { struct _GstVaapiDownload { /*< private >*/ - GstBaseTransform parent_instance; + GstVaapiPluginBase parent_instance; - GstVaapiDisplay *display; GstCaps *allowed_caps; TransformSizeCache transform_size_cache[2]; GstVaapiVideoPool *images; @@ -89,7 +88,7 @@ struct _GstVaapiDownload { struct _GstVaapiDownloadClass { /*< private >*/ - GstBaseTransformClass parent_class; + GstVaapiPluginBaseClass parent_class; }; /* GstImplementsInterface interface */ @@ -114,7 +113,7 @@ gst_vaapidownload_set_video_context(GstVideoContext *context, const gchar *type, const GValue *value) { GstVaapiDownload *download = GST_VAAPIDOWNLOAD (context); - gst_vaapi_set_display (type, value, &download->display); + gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(download)); } static void @@ -199,7 +198,7 @@ gst_vaapidownload_destroy(GstVaapiDownload *download) } gst_vaapi_video_pool_replace(&download->images, NULL); - gst_vaapi_display_replace(&download->display, NULL); + GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(download, NULL); } static void @@ -207,6 +206,7 @@ gst_vaapidownload_finalize(GObject *object) { gst_vaapidownload_destroy(GST_VAAPIDOWNLOAD(object)); + gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object)); G_OBJECT_CLASS(gst_vaapidownload_parent_class)->finalize(object); } @@ -221,6 +221,8 @@ gst_vaapidownload_class_init(GstVaapiDownloadClass *klass) GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidownload, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass)); + object_class->finalize = gst_vaapidownload_finalize; trans_class->start = gst_vaapidownload_start; trans_class->stop = gst_vaapidownload_stop; @@ -250,7 +252,8 @@ gst_vaapidownload_init(GstVaapiDownload *download) { GstPad *sinkpad, *srcpad; - download->display = NULL; + gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(download), GST_CAT_DEFAULT); + download->allowed_caps = NULL; download->images = NULL; download->images_reset = FALSE; @@ -273,7 +276,7 @@ static inline gboolean gst_vaapidownload_ensure_display(GstVaapiDownload *download) { return gst_vaapi_ensure_display(download, GST_VAAPI_DISPLAY_TYPE_ANY, - &download->display); + &GST_VAAPI_PLUGIN_BASE_DISPLAY(download)); } static gboolean @@ -281,6 +284,8 @@ gst_vaapidownload_start(GstBaseTransform *trans) { GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); + if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(trans))) + return FALSE; if (!gst_vaapidownload_ensure_display(download)) return FALSE; return TRUE; @@ -289,9 +294,7 @@ gst_vaapidownload_start(GstBaseTransform *trans) static gboolean gst_vaapidownload_stop(GstBaseTransform *trans) { - GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - - gst_vaapi_display_replace(&download->display, NULL); + gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(trans)); return TRUE; } @@ -443,7 +446,8 @@ gst_vaapidownload_transform_caps( if (download->allowed_caps) allowed_caps = gst_caps_ref(download->allowed_caps); else { - allowed_caps = gst_vaapi_display_get_image_caps(download->display); + allowed_caps = gst_vaapi_display_get_image_caps( + GST_VAAPI_PLUGIN_BASE_DISPLAY(download)); if (!allowed_caps) return NULL; } @@ -504,7 +508,8 @@ gst_vaapidownload_ensure_image_pool(GstVaapiDownload *download, GstCaps *caps) download->image_width = width; download->image_height = height; gst_vaapi_video_pool_replace(&download->images, NULL); - download->images = gst_vaapi_image_pool_new(download->display, &vi); + download->images = gst_vaapi_image_pool_new( + GST_VAAPI_PLUGIN_BASE_DISPLAY(download), &vi); if (!download->images) return FALSE; download->images_reset = TRUE; @@ -587,11 +592,12 @@ static gboolean gst_vaapidownload_query(GstPad *pad, GstQuery *query) { GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(gst_pad_get_parent_element(pad)); + GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(download); gboolean res; - GST_DEBUG("sharing display %p", download->display); + GST_DEBUG("sharing display %p", display); - if (gst_vaapi_reply_to_query(query, download->display)) + if (gst_vaapi_reply_to_query(query, display)) res = TRUE; else res = gst_pad_query_default(pad, query); diff --git a/gst/vaapi/gstvaapidownload.h b/gst/vaapi/gstvaapidownload.h index 28a93988a8..bb29fca547 100644 --- a/gst/vaapi/gstvaapidownload.h +++ b/gst/vaapi/gstvaapidownload.h @@ -25,8 +25,7 @@ #ifndef GST_VAAPIDOWNLOAD_H #define GST_VAAPIDOWNLOAD_H -#include -#include +#include "gstvaapipluginbase.h" #include #include #include diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index bcb3f1d303..4227377b82 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -68,7 +68,7 @@ gst_vaapiencode_set_context (GstElement * element, GstContext * context) if (gst_vaapi_video_context_get_display (context, &display)) { GST_INFO_OBJECT (element, "set display %p", display); - gst_vaapi_display_replace (&encode->display, display); + GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE (encode, display); gst_vaapi_display_unref (display); } } @@ -79,7 +79,7 @@ gst_vaapiencode_set_video_context (GstVideoContext * context, { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (context); - gst_vaapi_set_display (type, value, &encode->display); + gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); } static void @@ -114,7 +114,7 @@ static inline gboolean ensure_display (GstVaapiEncode * encode) { return gst_vaapi_ensure_display (encode, - GST_VAAPI_DISPLAY_TYPE_ANY, &encode->display); + GST_VAAPI_DISPLAY_TYPE_ANY, &GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); } static gboolean @@ -125,12 +125,14 @@ ensure_uploader (GstVaapiEncode * encode) return FALSE; if (!encode->uploader) { - encode->uploader = gst_vaapi_uploader_new (encode->display); + encode->uploader = gst_vaapi_uploader_new ( + GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); if (!encode->uploader) return FALSE; } - if (!gst_vaapi_uploader_ensure_display (encode->uploader, encode->display)) + if (!gst_vaapi_uploader_ensure_display (encode->uploader, + GST_VAAPI_PLUGIN_BASE_DISPLAY (encode))) return FALSE; #endif return TRUE; @@ -157,7 +159,7 @@ gst_vaapiencode_query (GST_PAD_QUERY_FUNCTION_ARGS) GST_INFO_OBJECT (encode, "query type %s", GST_QUERY_TYPE_NAME (query)); - if (gst_vaapi_reply_to_query (query, encode->display)) + if (gst_vaapi_reply_to_query (query, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode))) success = TRUE; else if (GST_PAD_IS_SINK (pad)) success = GST_PAD_QUERY_FUNCTION_CALL (encode->sinkpad_query, @@ -379,7 +381,6 @@ gst_vaapiencode_destroy (GstVaapiEncode * encode) g_clear_object (&encode->uploader); gst_caps_replace (&encode->sinkpad_caps, NULL); gst_caps_replace (&encode->srcpad_caps, NULL); - gst_vaapi_display_replace (&encode->display, NULL); return TRUE; } @@ -397,7 +398,8 @@ ensure_encoder (GstVaapiEncode * encode) if (!ensure_uploader_caps (encode)) return FALSE; - encode->encoder = klass->create_encoder (encode, encode->display); + encode->encoder = klass->create_encoder (encode, + GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); if (!encode->encoder) return FALSE; return TRUE; @@ -407,10 +409,13 @@ static gboolean gst_vaapiencode_open (GstVideoEncoder * venc) { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); - GstVaapiDisplay *const old_display = encode->display; + GstVaapiDisplay *const old_display = GST_VAAPI_PLUGIN_BASE_DISPLAY (encode); gboolean success; - encode->display = NULL; + if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (encode))) + return FALSE; + + GST_VAAPI_PLUGIN_BASE_DISPLAY (encode) = NULL; success = ensure_display (encode); if (old_display) gst_vaapi_display_unref (old_display); @@ -422,7 +427,9 @@ gst_vaapiencode_close (GstVideoEncoder * venc) { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); - return gst_vaapiencode_destroy (encode); + gst_vaapiencode_destroy (encode); + gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (encode)); + return TRUE; } static inline gboolean @@ -436,7 +443,7 @@ gst_vaapiencode_update_sink_caps (GstVaapiEncode * encode, if (GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) { /* Ensure the uploader is set up for upstream allocated buffers */ GstVaapiUploader *const uploader = encode->uploader; - if (!gst_vaapi_uploader_ensure_display (uploader, encode->display)) + if (!gst_vaapi_uploader_ensure_display (uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode))) return FALSE; if (!gst_vaapi_uploader_ensure_caps (uploader, state->caps, NULL)) return FALSE; @@ -527,7 +534,7 @@ gst_vaapiencode_ensure_video_buffer_pool (GstVaapiEncode * encode, encode->video_buffer_size = 0; } - pool = gst_vaapi_video_buffer_pool_new (encode->display); + pool = gst_vaapi_video_buffer_pool_new (GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); if (!pool) goto error_create_pool; @@ -903,12 +910,15 @@ gst_vaapiencode_finalize (GObject * object) encode->sinkpad = NULL; encode->srcpad = NULL; + gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (object)); G_OBJECT_CLASS (gst_vaapiencode_parent_class)->finalize (object); } static void gst_vaapiencode_init (GstVaapiEncode * encode) { + gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (encode), GST_CAT_DEFAULT); + /* sink pad */ encode->sinkpad = GST_VIDEO_ENCODER_SINK_PAD (encode); encode->sinkpad_query = GST_PAD_QUERYFUNC (encode->sinkpad); @@ -935,6 +945,8 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) GST_DEBUG_CATEGORY_INIT (gst_vaapiencode_debug, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + gst_vaapi_plugin_base_class_init (GST_VAAPI_PLUGIN_BASE_CLASS (klass)); + object_class->finalize = gst_vaapiencode_finalize; object_class->set_property = gst_vaapiencode_set_property; object_class->get_property = gst_vaapiencode_get_property; diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 09a97c730d..1bf0dbc9cc 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -22,8 +22,7 @@ #ifndef GST_VAAPIENCODE_H #define GST_VAAPIENCODE_H -#include -#include +#include "gstvaapipluginbase.h" #include #include "gstvaapiuploader.h" @@ -50,7 +49,7 @@ typedef struct _GstVaapiEncodeClass GstVaapiEncodeClass; struct _GstVaapiEncode { /*< private >*/ - GstVideoEncoder parent_instance; + GstVaapiPluginBase parent_instance; GstPad *sinkpad; GstCaps *sinkpad_caps; @@ -61,7 +60,6 @@ struct _GstVaapiEncode GstCaps *srcpad_caps; GstPadQueryFunction srcpad_query; - GstVaapiDisplay *display; GstVaapiEncoder *encoder; GstVaapiUploader *uploader; @@ -79,7 +77,7 @@ struct _GstVaapiEncode struct _GstVaapiEncodeClass { /*< private >*/ - GstVideoEncoderClass parent_class; + GstVaapiPluginBaseClass parent_class; gboolean (*check_ratecontrol) (GstVaapiEncode * encode, GstVaapiRateControl rate_control); diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c new file mode 100644 index 0000000000..b2d7d80724 --- /dev/null +++ b/gst/vaapi/gstvaapipluginbase.c @@ -0,0 +1,76 @@ +/* + * gstvaapipluginbase.c - Base GStreamer VA-API Plugin element + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne + * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 "gst/vaapi/sysdeps.h" +#include "gstvaapipluginbase.h" + +#define GST_CAT_DEFAULT (plugin->debug_category) + +void +gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) +{ +} + +void +gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin, + GstDebugCategory * debug_category) +{ + plugin->debug_category = debug_category; +} + +void +gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin) +{ + gst_vaapi_plugin_base_close (plugin); + + gst_debug_category_free (plugin->debug_category); +} + +/** + * gst_vaapi_plugin_base_open: + * @plugin: a #GstVaapiPluginBase + * + * Allocates any internal resources needed for correct operation from + * the subclass. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +gboolean +gst_vaapi_plugin_base_open (GstVaapiPluginBase * plugin) +{ + return TRUE; +} + +/** + * gst_vaapi_plugin_base_close: + * @plugin: a #GstVaapiPluginBase + * + * Deallocates all internal resources that were allocated so + * far. i.e. put the base plugin object into a clean state. + */ +void +gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) +{ + gst_vaapi_display_replace (&plugin->display, NULL); +} diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h new file mode 100644 index 0000000000..2e3c27dd4f --- /dev/null +++ b/gst/vaapi/gstvaapipluginbase.h @@ -0,0 +1,130 @@ +/* + * gstvaapipluginbase.h - Base GStreamer VA-API Plugin element + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne + * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_PLUGIN_BASE_H +#define GST_VAAPI_PLUGIN_BASE_H + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _GstVaapiPluginBase GstVaapiPluginBase; +typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; + +#define GST_VAAPI_PLUGIN_BASE(plugin) \ + ((GstVaapiPluginBase *)(plugin)) +#define GST_VAAPI_PLUGIN_BASE_CLASS(plugin) \ + ((GstVaapiPluginBaseClass *)(plugin)) +#define GST_VAAPI_PLUGIN_BASE_GET_CLASS(plugin) \ + GST_VAAPI_PLUGIN_BASE_CLASS(GST_ELEMENT_GET_CLASS( \ + GST_VAAPI_PLUGIN_BASE_ELEMENT(plugin))) +#define GST_VAAPI_PLUGIN_BASE_PARENT(plugin) \ + (&GST_VAAPI_PLUGIN_BASE(plugin)->parent_instance) +#define GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin) \ + (&GST_VAAPI_PLUGIN_BASE_CLASS(plugin)->parent_class) +#define GST_VAAPI_PLUGIN_BASE_ELEMENT(plugin) \ + (&GST_VAAPI_PLUGIN_BASE_PARENT(plugin)->element) +#define GST_VAAPI_PLUGIN_BASE_ELEMENT_CLASS(plugin) \ + (&GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin)->element) +#define GST_VAAPI_PLUGIN_BASE_DECODER(plugin) \ + (&GST_VAAPI_PLUGIN_BASE_PARENT(plugin)->decoder) +#define GST_VAAPI_PLUGIN_BASE_DECODER_CLASS(plugin) \ + (&GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin)->decoder) +#define GST_VAAPI_PLUGIN_BASE_ENCODER(plugin) \ + (&GST_VAAPI_PLUGIN_BASE_PARENT(plugin)->encoder) +#define GST_VAAPI_PLUGIN_BASE_ENCODER_CLASS(plugin) \ + (&GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin)->encoder) +#define GST_VAAPI_PLUGIN_BASE_TRANSFORM(plugin) \ + (&GST_VAAPI_PLUGIN_BASE_PARENT(plugin)->transform) +#define GST_VAAPI_PLUGIN_BASE_TRANSFORM_CLASS(plugin) \ + (&GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin)->transform) +#define GST_VAAPI_PLUGIN_BASE_SINK(plugin) \ + (&GST_VAAPI_PLUGIN_BASE_PARENT(plugin)->sink) +#define GST_VAAPI_PLUGIN_BASE_SINK_CLASS(plugin) \ + (&GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin)->sink) + +#define GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->display) +#define GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(plugin, new_display) \ + (gst_vaapi_display_replace(&GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin), \ + (new_display))) + +struct _GstVaapiPluginBase +{ + /*< private >*/ + union + { + GstElement element; + GstVideoDecoder decoder; + GstVideoEncoder encoder; + GstBaseTransform transform; + GstVideoSink sink; + } parent_instance; + + GstDebugCategory *debug_category; + + GstVaapiDisplay *display; +}; + +struct _GstVaapiPluginBaseClass +{ + /*< private >*/ + union + { + GstElementClass element; + GstVideoDecoderClass decoder; + GstVideoEncoderClass encoder; + GstBaseTransformClass transform; + GstVideoSinkClass sink; + } parent_class; +}; + +G_GNUC_INTERNAL +void +gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass); + +G_GNUC_INTERNAL +void +gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin, + GstDebugCategory * debug_category); + +G_GNUC_INTERNAL +void +gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_open (GstVaapiPluginBase * plugin); + +G_GNUC_INTERNAL +void +gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin); + +G_END_DECLS + +#endif /* GST_VAAPI_PLUGIN_BASE_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 292405f5e3..97eea32ad7 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -118,10 +118,10 @@ gst_vaapipostproc_set_video_context( { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(context); - gst_vaapi_set_display(type, value, &postproc->display); + gst_vaapi_set_display(type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); if (postproc->uploader) - gst_vaapi_uploader_ensure_display(postproc->uploader, postproc->display); + gst_vaapi_uploader_ensure_display(postproc->uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); } static void @@ -263,7 +263,7 @@ gst_vaapipostproc_set_context(GstElement *element, GstContext *context) if (gst_vaapi_video_context_get_display(context, &display)) { GST_INFO_OBJECT(element, "set display %p", display); - gst_vaapi_display_replace(&postproc->display, display); + GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(postproc, display); gst_vaapi_display_unref(display); } } @@ -273,7 +273,7 @@ static inline gboolean gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc) { return gst_vaapi_ensure_display(postproc, GST_VAAPI_DISPLAY_TYPE_ANY, - &postproc->display); + &GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); } static gboolean @@ -283,13 +283,14 @@ gst_vaapipostproc_ensure_uploader(GstVaapiPostproc *postproc) return FALSE; if (!postproc->uploader) { - postproc->uploader = gst_vaapi_uploader_new(postproc->display); + postproc->uploader = gst_vaapi_uploader_new( + GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); if (!postproc->uploader) return FALSE; } if (!gst_vaapi_uploader_ensure_display(postproc->uploader, - postproc->display)) + GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc))) return FALSE; return TRUE; } @@ -314,7 +315,8 @@ gst_vaapipostproc_ensure_filter(GstVaapiPostproc *postproc) if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; - postproc->filter = gst_vaapi_filter_new(postproc->display); + postproc->filter = gst_vaapi_filter_new( + GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); if (!postproc->filter) return FALSE; return TRUE; @@ -339,6 +341,8 @@ gst_vaapipostproc_ensure_filter_caps(GstVaapiPostproc *postproc) static gboolean gst_vaapipostproc_create(GstVaapiPostproc *postproc) { + if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(postproc))) + return FALSE; if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; if (!gst_vaapipostproc_ensure_uploader(postproc)) @@ -375,12 +379,12 @@ gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) #endif g_clear_object(&postproc->uploader); gst_vaapipostproc_destroy_filter(postproc); - gst_vaapi_display_replace(&postproc->display, NULL); gst_caps_replace(&postproc->allowed_sinkpad_caps, NULL); gst_caps_replace(&postproc->sinkpad_caps, NULL); gst_caps_replace(&postproc->allowed_srcpad_caps, NULL); gst_caps_replace(&postproc->srcpad_caps, NULL); + gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(postproc)); } static gboolean @@ -389,6 +393,8 @@ gst_vaapipostproc_start(GstBaseTransform *trans) GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); ds_reset(&postproc->deinterlace_state); + if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(postproc))) + return FALSE; if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; return TRUE; @@ -400,7 +406,7 @@ gst_vaapipostproc_stop(GstBaseTransform *trans) GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); ds_reset(&postproc->deinterlace_state); - gst_vaapi_display_replace(&postproc->display, NULL); + gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(postproc)); return TRUE; } @@ -859,7 +865,7 @@ gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps, if (postproc->is_raw_yuv) { /* Ensure the uploader is set up for upstream allocated buffers */ GstVaapiUploader * const uploader = postproc->uploader; - if (!gst_vaapi_uploader_ensure_display(uploader, postproc->display)) + if (!gst_vaapi_uploader_ensure_display(uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc))) return FALSE; if (!gst_vaapi_uploader_ensure_caps(uploader, caps, NULL)) return FALSE; @@ -1360,7 +1366,8 @@ ensure_sinkpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps) postproc->sinkpad_buffer_size = 0; } - pool = gst_vaapi_video_buffer_pool_new(postproc->display); + pool = gst_vaapi_video_buffer_pool_new( + GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); if (!pool) goto error_create_pool; @@ -1417,7 +1424,7 @@ ensure_srcpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps) return TRUE; postproc->filter_pool_info = vi; - pool = gst_vaapi_surface_pool_new(postproc->display, + pool = gst_vaapi_surface_pool_new(GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc), &postproc->filter_pool_info); if (!pool) return FALSE; @@ -1462,8 +1469,8 @@ gst_vaapipostproc_query(GstBaseTransform *trans, GstPadDirection direction, GST_INFO_OBJECT(trans, "query type `%s'", GST_QUERY_TYPE_NAME(query)); - if (gst_vaapi_reply_to_query(query, postproc->display)) { - GST_DEBUG("sharing display %p", postproc->display); + if (gst_vaapi_reply_to_query(query, GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc))) { + GST_DEBUG("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); return TRUE; } @@ -1521,6 +1528,7 @@ gst_vaapipostproc_finalize(GObject *object) gst_vaapipostproc_destroy(postproc); + gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(postproc)); G_OBJECT_CLASS(gst_vaapipostproc_parent_class)->finalize(object); } @@ -1621,6 +1629,8 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) GST_DEBUG_CATEGORY_INIT(gst_debug_vaapipostproc, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass)); + object_class->finalize = gst_vaapipostproc_finalize; object_class->set_property = gst_vaapipostproc_set_property; object_class->get_property = gst_vaapipostproc_get_property; @@ -1778,6 +1788,8 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) static void gst_vaapipostproc_init(GstVaapiPostproc *postproc) { + gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(postproc), GST_CAT_DEFAULT); + postproc->format = DEFAULT_FORMAT; postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE; postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index e15472e848..55dabae82a 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -23,8 +23,7 @@ #ifndef GST_VAAPIPOSTPROC_H #define GST_VAAPIPOSTPROC_H -#include -#include +#include "gstvaapipluginbase.h" #include #include #include @@ -135,9 +134,8 @@ struct _GstVaapiDeinterlaceState { struct _GstVaapiPostproc { /*< private >*/ - GstBaseTransform parent_instance; + GstVaapiPluginBase parent_instance; - GstVaapiDisplay *display; GstVaapiUploader *uploader; GstVaapiFilter *filter; GPtrArray *filter_ops; @@ -177,7 +175,7 @@ struct _GstVaapiPostproc { struct _GstVaapiPostprocClass { /*< private >*/ - GstBaseTransformClass parent_class; + GstVaapiPluginBaseClass parent_class; }; GType diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 74f584bc9d..bb2f68a07c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -133,7 +133,7 @@ gst_vaapisink_set_video_context(GstVideoContext *context, const gchar *type, const GValue *value) { GstVaapiSink *sink = GST_VAAPISINK (context); - gst_vaapi_set_display (type, value, &sink->display); + gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); } static void @@ -272,10 +272,10 @@ gst_vaapisink_destroy(GstVaapiSink *sink) #if USE_GLX gst_vaapi_texture_replace(&sink->texture, NULL); #endif - gst_vaapi_display_replace(&sink->display, NULL); g_clear_object(&sink->uploader); gst_caps_replace(&sink->caps, NULL); + gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(sink)); } #if USE_X11 @@ -313,6 +313,8 @@ configure_notify_event_pending( guint height ) { + GstVaapiDisplayX11 * const display = + GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); ConfigureNotifyEventPendingArgs args; XEvent xev; @@ -323,7 +325,7 @@ configure_notify_event_pending( /* XXX: don't use XPeekIfEvent() because it might block */ XCheckIfEvent( - gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)), + gst_vaapi_display_x11_get_display(display), &xev, configure_notify_event_pending_cb, (XPointer)&args ); @@ -347,24 +349,24 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink) { GstVaapiDisplayType display_type; GstVaapiRenderMode render_mode; - const gboolean had_display = sink->display != NULL; + const gboolean had_display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink) != NULL; - if (!gst_vaapi_ensure_display(sink, sink->display_type, &sink->display)) + if (!gst_vaapi_ensure_display(sink, sink->display_type, &GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) return FALSE; - display_type = gst_vaapi_display_get_display_type(sink->display); - if (display_type != sink->display_type || (!had_display && sink->display)) { + display_type = gst_vaapi_display_get_display_type(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); + if (display_type != sink->display_type || (!had_display && GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) { GST_INFO("created %s %p", get_display_type_name(display_type), - sink->display); + GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); sink->display_type = display_type; sink->use_overlay = - gst_vaapi_display_get_render_mode(sink->display, &render_mode) && + gst_vaapi_display_get_render_mode(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink), &render_mode) && render_mode == GST_VAAPI_RENDER_MODE_OVERLAY; GST_DEBUG("use %s rendering mode", sink->use_overlay ? "overlay" : "texture"); sink->use_rotation = gst_vaapi_display_has_property( - sink->display, GST_VAAPI_DISPLAY_PROP_ROTATION); + GST_VAAPI_PLUGIN_BASE_DISPLAY(sink), GST_VAAPI_DISPLAY_PROP_ROTATION); } return TRUE; } @@ -376,7 +378,8 @@ gst_vaapisink_ensure_uploader(GstVaapiSink *sink) return FALSE; if (!sink->uploader) { - sink->uploader = gst_vaapi_uploader_new(sink->display); + sink->uploader = gst_vaapi_uploader_new( + GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); if (!sink->uploader) return FALSE; } @@ -410,7 +413,7 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) GST_DEBUG("ensure render rect within %ux%u bounds", width, height); gst_vaapi_display_get_pixel_aspect_ratio( - sink->display, + GST_VAAPI_PLUGIN_BASE_DISPLAY(sink), &display_par_n, &display_par_d ); GST_DEBUG("display pixel-aspect-ratio %d/%d", @@ -455,6 +458,7 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) static void gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheight) { + GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); GstVideoRectangle src_rect, dst_rect, out_rect; guint num, den, display_width, display_height, display_par_n, display_par_d; gboolean success, scale; @@ -465,7 +469,7 @@ gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheig return; } - gst_vaapi_display_get_size(sink->display, &display_width, &display_height); + gst_vaapi_display_get_size(display, &display_width, &display_height); if (sink->fullscreen) { *pwidth = display_width; *pheight = display_height; @@ -473,7 +477,7 @@ gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheig } gst_vaapi_display_get_pixel_aspect_ratio( - sink->display, + display, &display_par_n, &display_par_d ); @@ -505,7 +509,7 @@ gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheig static inline gboolean gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) { - GstVaapiDisplay * const display = sink->display; + GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); if (!sink->window) { switch (sink->display_type) { @@ -543,6 +547,7 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) static gboolean gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) { + GstVaapiDisplay *display; Window rootwin; unsigned int width, height, border_width, depth; int x, y; @@ -550,15 +555,16 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) if (!gst_vaapisink_ensure_display(sink)) return FALSE; + display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); - gst_vaapi_display_lock(sink->display); + gst_vaapi_display_lock(display); XGetGeometry( - gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)), + gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)), xid, &rootwin, &x, &y, &width, &height, &border_width, &depth ); - gst_vaapi_display_unlock(sink->display); + gst_vaapi_display_unlock(display); if ((width != sink->window_width || height != sink->window_height) && !configure_notify_event_pending(sink, xid, width, height)) { @@ -577,11 +583,11 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) switch (sink->display_type) { #if USE_GLX case GST_VAAPI_DISPLAY_TYPE_GLX: - sink->window = gst_vaapi_window_glx_new_with_xid(sink->display, xid); + sink->window = gst_vaapi_window_glx_new_with_xid(display, xid); break; #endif case GST_VAAPI_DISPLAY_TYPE_X11: - sink->window = gst_vaapi_window_x11_new_with_xid(sink->display, xid); + sink->window = gst_vaapi_window_x11_new_with_xid(display, xid); break; default: GST_ERROR("unsupported display type %d", sink->display_type); @@ -594,9 +600,10 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) static gboolean gst_vaapisink_ensure_rotation(GstVaapiSink *sink, gboolean recalc_display_rect) { + GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); gboolean success = FALSE; - g_return_val_if_fail(sink->display, FALSE); + g_return_val_if_fail(display, FALSE); if (sink->rotation == sink->rotation_req) return TRUE; @@ -606,9 +613,9 @@ gst_vaapisink_ensure_rotation(GstVaapiSink *sink, gboolean recalc_display_rect) goto end; } - gst_vaapi_display_lock(sink->display); - success = gst_vaapi_display_set_rotation(sink->display, sink->rotation_req); - gst_vaapi_display_unlock(sink->display); + gst_vaapi_display_lock(display); + success = gst_vaapi_display_set_rotation(display, sink->rotation_req); + gst_vaapi_display_unlock(display); if (!success) { GST_ERROR("failed to change VA display rotation mode"); goto end; @@ -654,7 +661,7 @@ gst_vaapisink_ensure_video_buffer_pool(GstVaapiSink *sink, GstCaps *caps) sink->video_buffer_size = 0; } - pool = gst_vaapi_video_buffer_pool_new(sink->display); + pool = gst_vaapi_video_buffer_pool_new(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); if (!pool) goto error_create_pool; @@ -701,6 +708,8 @@ gst_vaapisink_start(GstBaseSink *base_sink) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(sink))) + return FALSE; return gst_vaapisink_ensure_uploader(sink); } @@ -714,9 +723,8 @@ gst_vaapisink_stop(GstBaseSink *base_sink) g_clear_object(&sink->video_buffer_pool); #endif gst_vaapi_window_replace(&sink->window, NULL); - gst_vaapi_display_replace(&sink->display, NULL); g_clear_object(&sink->uploader); - + gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(sink)); return TRUE; } @@ -769,6 +777,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstVideoInfo * const vip = &sink->video_info; + GstVaapiDisplay *display; guint win_width, win_height; #if USE_DRM @@ -793,11 +802,12 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) if (!gst_vaapisink_ensure_display(sink)) return FALSE; + display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); #if !GST_CHECK_VERSION(1,0,0) if (sink->use_video_raw) { /* Ensure the uploader is set up for upstream allocated buffers */ - if (!gst_vaapi_uploader_ensure_display(sink->uploader, sink->display)) + if (!gst_vaapi_uploader_ensure_display(sink->uploader, display)) return FALSE; if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL)) return FALSE; @@ -812,9 +822,9 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) gst_vaapi_window_set_size(sink->window, win_width, win_height); } else { - gst_vaapi_display_lock(sink->display); + gst_vaapi_display_lock(display); gst_video_overlay_prepare_window_handle(GST_VIDEO_OVERLAY(sink)); - gst_vaapi_display_unlock(sink->display); + gst_vaapi_display_unlock(display); if (sink->window) return TRUE; if (!gst_vaapisink_ensure_window(sink, win_width, win_height)) @@ -935,6 +945,7 @@ render_reflection(GstVaapiSink *sink) static gboolean gst_vaapisink_ensure_texture(GstVaapiSink *sink, GstVaapiSurface *surface) { + GstVaapiDisplay * display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); GstVideoRectangle tex_rect, dis_rect, out_rect; guint width, height; @@ -947,7 +958,7 @@ gst_vaapisink_ensure_texture(GstVaapiSink *sink, GstVaapiSurface *surface) tex_rect.w = width; tex_rect.h = height; - gst_vaapi_display_get_size(sink->display, &width, &height); + gst_vaapi_display_get_size(display, &width, &height); dis_rect.x = 0; dis_rect.y = 0; dis_rect.w = width; @@ -963,7 +974,7 @@ gst_vaapisink_ensure_texture(GstVaapiSink *sink, GstVaapiSurface *surface) height = tex_rect.h; GST_INFO("texture size %ux%u", width, height); - sink->texture = gst_vaapi_texture_new(sink->display, + sink->texture = gst_vaapi_texture_new(display, GL_TEXTURE_2D, GL_BGRA, width, height); return sink->texture != NULL; } @@ -1188,9 +1199,8 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) return ret; meta = gst_buffer_get_vaapi_video_meta(buffer); - if (sink->display != gst_vaapi_video_meta_get_display(meta)) - gst_vaapi_display_replace(&sink->display, - gst_vaapi_video_meta_get_display(meta)); + GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(sink, + gst_vaapi_video_meta_get_display(meta)); if (!sink->window) goto error; @@ -1325,7 +1335,7 @@ gst_vaapisink_buffer_alloc( return GST_FLOW_OK; } - if (!gst_vaapi_uploader_ensure_display(sink->uploader, sink->display)) + if (!gst_vaapi_uploader_ensure_display(sink->uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) return GST_FLOW_NOT_SUPPORTED; if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL)) return GST_FLOW_NOT_SUPPORTED; @@ -1350,7 +1360,7 @@ gst_vaapisink_set_context(GstElement *element, GstContext *context) if (gst_vaapi_video_context_get_display(context, &display)) { GST_INFO_OBJECT(element, "set display %p", display); - gst_vaapi_display_replace(&sink->display, display); + GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(sink, display); gst_vaapi_display_unref(display); } } @@ -1363,8 +1373,8 @@ gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query) GST_INFO_OBJECT(sink, "query type %s", GST_QUERY_TYPE_NAME(query)); - if (gst_vaapi_reply_to_query(query, sink->display)) { - GST_DEBUG("sharing display %p", sink->display); + if (gst_vaapi_reply_to_query(query, GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) { + GST_DEBUG("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); return TRUE; } @@ -1377,6 +1387,7 @@ gst_vaapisink_finalize(GObject *object) { gst_vaapisink_destroy(GST_VAAPISINK(object)); + gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object)); G_OBJECT_CLASS(gst_vaapisink_parent_class)->finalize(object); } @@ -1467,6 +1478,8 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) GST_DEBUG_CATEGORY_INIT(gst_debug_vaapisink, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass)); + object_class->finalize = gst_vaapisink_finalize; object_class->set_property = gst_vaapisink_set_property; object_class->get_property = gst_vaapisink_get_property; @@ -1585,8 +1598,9 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) static void gst_vaapisink_init(GstVaapiSink *sink) { + gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(sink), GST_CAT_DEFAULT); + sink->caps = NULL; - sink->display = NULL; sink->window = NULL; sink->window_width = 0; sink->window_height = 0; diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index fe2bf14de2..491f1b4954 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -25,8 +25,7 @@ #ifndef GST_VAAPISINK_H #define GST_VAAPISINK_H -#include -#include +#include "gstvaapipluginbase.h" #include #if USE_GLX #include @@ -68,11 +67,10 @@ typedef struct _GstVaapiTexture GstVaapiTexture; struct _GstVaapiSink { /*< private >*/ - GstVideoSink parent_instance; + GstVaapiPluginBase parent_instance; GstVaapiUploader *uploader; GstCaps *caps; - GstVaapiDisplay *display; GstVaapiDisplayType display_type; GstVaapiWindow *window; guint window_width; @@ -104,7 +102,7 @@ struct _GstVaapiSink { struct _GstVaapiSinkClass { /*< private >*/ - GstVideoSinkClass parent_class; + GstVaapiPluginBaseClass parent_class; }; GType diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index df63cff8ac..ce84d2020b 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -92,10 +92,11 @@ gst_vaapiupload_set_video_context(GstVideoContext *context, const gchar *type, { GstVaapiUpload * const upload = GST_VAAPIUPLOAD(context); - gst_vaapi_set_display(type, value, &upload->display); + gst_vaapi_set_display(type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)); if (upload->uploader) - gst_vaapi_uploader_ensure_display(upload->uploader, upload->display); + gst_vaapi_uploader_ensure_display(upload->uploader, + GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)); } static void @@ -176,7 +177,6 @@ static void gst_vaapiupload_destroy(GstVaapiUpload *upload) { g_clear_object(&upload->uploader); - gst_vaapi_display_replace(&upload->display, NULL); } static void @@ -184,6 +184,7 @@ gst_vaapiupload_finalize(GObject *object) { gst_vaapiupload_destroy(GST_VAAPIUPLOAD(object)); + gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object)); G_OBJECT_CLASS(gst_vaapiupload_parent_class)->finalize(object); } @@ -198,6 +199,8 @@ gst_vaapiupload_class_init(GstVaapiUploadClass *klass) GST_DEBUG_CATEGORY_INIT(gst_debug_vaapiupload, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass)); + object_class->finalize = gst_vaapiupload_finalize; trans_class->start = gst_vaapiupload_start; @@ -228,6 +231,8 @@ gst_vaapiupload_init(GstVaapiUpload *upload) { GstPad *sinkpad, *srcpad; + gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(upload), GST_CAT_DEFAULT); + /* Override buffer allocator on sink pad */ sinkpad = gst_element_get_static_pad(GST_ELEMENT(upload), "sink"); gst_pad_set_bufferalloc_function( @@ -247,7 +252,7 @@ static inline gboolean gst_vaapiupload_ensure_display(GstVaapiUpload *upload) { return gst_vaapi_ensure_display(upload, GST_VAAPI_DISPLAY_TYPE_ANY, - &upload->display); + &GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)); } static gboolean @@ -257,11 +262,13 @@ gst_vaapiupload_ensure_uploader(GstVaapiUpload *upload) return FALSE; if (!upload->uploader) { - upload->uploader = gst_vaapi_uploader_new(upload->display); + upload->uploader = gst_vaapi_uploader_new( + GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)); if (!upload->uploader) return FALSE; } - if (!gst_vaapi_uploader_ensure_display(upload->uploader, upload->display)) + if (!gst_vaapi_uploader_ensure_display(upload->uploader, + GST_VAAPI_PLUGIN_BASE_DISPLAY(upload))) return FALSE; return TRUE; } @@ -271,6 +278,8 @@ gst_vaapiupload_start(GstBaseTransform *trans) { GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); + if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(trans))) + return FALSE; if (!gst_vaapiupload_ensure_uploader(upload)) return FALSE; return TRUE; @@ -279,9 +288,7 @@ gst_vaapiupload_start(GstBaseTransform *trans) static gboolean gst_vaapiupload_stop(GstBaseTransform *trans) { - GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - - gst_vaapi_display_replace(&upload->display, NULL); + gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(trans)); return TRUE; } @@ -396,7 +403,8 @@ gst_vaapiupload_buffer_alloc( *pbuf = NULL; - if (!gst_vaapi_uploader_ensure_display(upload->uploader, upload->display)) + if (!gst_vaapi_uploader_ensure_display(upload->uploader, + GST_VAAPI_PLUGIN_BASE_DISPLAY(upload))) return GST_FLOW_NOT_SUPPORTED; if (!gst_vaapi_uploader_ensure_caps(upload->uploader, caps, NULL)) return GST_FLOW_NOT_SUPPORTED; @@ -465,9 +473,9 @@ gst_vaapiupload_query(GstPad *pad, GstQuery *query) GstVaapiUpload *upload = GST_VAAPIUPLOAD (gst_pad_get_parent_element (pad)); gboolean res; - GST_DEBUG ("sharing display %p", upload->display); + GST_DEBUG ("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)); - if (gst_vaapi_reply_to_query (query, upload->display)) + if (gst_vaapi_reply_to_query (query, GST_VAAPI_PLUGIN_BASE_DISPLAY(upload))) res = TRUE; else res = gst_pad_query_default (pad, query); diff --git a/gst/vaapi/gstvaapiupload.h b/gst/vaapi/gstvaapiupload.h index 41c1a2f299..6a2c0776c6 100644 --- a/gst/vaapi/gstvaapiupload.h +++ b/gst/vaapi/gstvaapiupload.h @@ -25,7 +25,7 @@ #ifndef GST_VAAPIUPLOAD_H #define GST_VAAPIUPLOAD_H -#include +#include "gstvaapipluginbase.h" #include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -59,15 +59,14 @@ typedef struct _GstVaapiUploadClass GstVaapiUploadClass; struct _GstVaapiUpload { /*< private >*/ - GstBaseTransform parent_instance; + GstVaapiPluginBase parent_instance; - GstVaapiDisplay *display; GstVaapiUploader *uploader; }; struct _GstVaapiUploadClass { /*< private >*/ - GstBaseTransformClass parent_class; + GstVaapiPluginBaseClass parent_class; }; GType From 6f2dfb71e6a58c3988c1c8f3eeeeaea29973b656 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Dec 2013 11:52:47 +0100 Subject: [PATCH 1464/3781] plugins: factor out display creation process. Move common VA display creation code to GstVaapiPluginBase, with the default display type remaining "any". Also add a "display-changed" hook so that subclasses could perform additional tasks when/if the VA display changed, due to a new display type request for instance. All plug-ins are updated to cope with the new internal APIs. --- gst/vaapi/gstvaapidecode.c | 3 +- gst/vaapi/gstvaapidownload.c | 3 +- gst/vaapi/gstvaapiencode.c | 3 +- gst/vaapi/gstvaapipluginbase.c | 60 +++++++++++++++++++++++ gst/vaapi/gstvaapipluginbase.h | 15 ++++++ gst/vaapi/gstvaapipluginutil.c | 34 +++++-------- gst/vaapi/gstvaapipluginutil.h | 6 +-- gst/vaapi/gstvaapipostproc.c | 3 +- gst/vaapi/gstvaapisink.c | 89 +++++++++++++++++++--------------- gst/vaapi/gstvaapisink.h | 1 - gst/vaapi/gstvaapiupload.c | 3 +- 11 files changed, 143 insertions(+), 77 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 102f0d42d7..22281225f7 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -603,8 +603,7 @@ gst_vaapidecode_set_context(GstElement *element, GstContext *context) static inline gboolean gst_vaapidecode_ensure_display(GstVaapiDecode *decode) { - return gst_vaapi_ensure_display(decode, GST_VAAPI_DISPLAY_TYPE_ANY, - &GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); + return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(decode)); } static inline guint diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index c59662595b..ed33bc445a 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -275,8 +275,7 @@ gst_vaapidownload_init(GstVaapiDownload *download) static inline gboolean gst_vaapidownload_ensure_display(GstVaapiDownload *download) { - return gst_vaapi_ensure_display(download, GST_VAAPI_DISPLAY_TYPE_ANY, - &GST_VAAPI_PLUGIN_BASE_DISPLAY(download)); + return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(download)); } static gboolean diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 4227377b82..c8b670b34e 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -113,8 +113,7 @@ enum static inline gboolean ensure_display (GstVaapiEncode * encode) { - return gst_vaapi_ensure_display (encode, - GST_VAAPI_DISPLAY_TYPE_ANY, &GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); + return gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (encode)); } static gboolean diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index b2d7d80724..366d616bd5 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -24,12 +24,20 @@ #include "gst/vaapi/sysdeps.h" #include "gstvaapipluginbase.h" +#include "gstvaapipluginutil.h" +/* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) +static void +default_display_changed (GstVaapiPluginBase * plugin) +{ +} + void gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) { + klass->display_changed = default_display_changed; } void @@ -37,6 +45,9 @@ gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin, GstDebugCategory * debug_category) { plugin->debug_category = debug_category; + + plugin->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; + plugin->display_type_req = GST_VAAPI_DISPLAY_TYPE_ANY; } void @@ -74,3 +85,52 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) { gst_vaapi_display_replace (&plugin->display, NULL); } + +/** + * gst_vaapi_plugin_base_set_display_type: + * @plugin: a #GstVaapiPluginBase + * @display_type: the new request #GstVaapiDisplayType + * + * Requests a new display type. The change is effective at the next + * call to gst_vaapi_plugin_base_ensure_display(). + */ +void +gst_vaapi_plugin_base_set_display_type (GstVaapiPluginBase * plugin, + GstVaapiDisplayType display_type) +{ + plugin->display_type_req = display_type; +} + +/* Checks wether display type 1 is compatible with display type 2 */ +static gboolean +display_type_is_compatible (GstVaapiDisplayType type1, + GstVaapiDisplayType type2) +{ + return (type1 == type2 || type2 == GST_VAAPI_DISPLAY_TYPE_ANY); +} + +/** + * gst_vaapi_plugin_base_ensure_display: + * @plugin: a #GstVaapiPluginBase + * + * Ensures the display stored in @plugin complies with the requested + * display type constraints. + * + * Returns: %TRUE if the display was created to match the requested + * type, %FALSE otherwise. + */ +gboolean +gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) +{ + if (plugin->display && display_type_is_compatible (plugin->display_type, + plugin->display_type_req)) + return TRUE; + gst_vaapi_display_replace (&plugin->display, NULL); + + if (!gst_vaapi_ensure_display (plugin, plugin->display_type_req)) + return FALSE; + plugin->display_type = gst_vaapi_display_get_display_type (plugin->display); + + GST_VAAPI_PLUGIN_BASE_GET_CLASS (plugin)->display_changed (plugin); + return TRUE; +} diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 2e3c27dd4f..952d3091b3 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -70,6 +70,8 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; #define GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->display) +#define GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->display_type) #define GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(plugin, new_display) \ (gst_vaapi_display_replace(&GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin), \ (new_display))) @@ -89,6 +91,8 @@ struct _GstVaapiPluginBase GstDebugCategory *debug_category; GstVaapiDisplay *display; + GstVaapiDisplayType display_type; + GstVaapiDisplayType display_type_req; }; struct _GstVaapiPluginBaseClass @@ -102,6 +106,8 @@ struct _GstVaapiPluginBaseClass GstBaseTransformClass transform; GstVideoSinkClass sink; } parent_class; + + void (*display_changed) (GstVaapiPluginBase * plugin); }; G_GNUC_INTERNAL @@ -125,6 +131,15 @@ G_GNUC_INTERNAL void gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin); +G_GNUC_INTERNAL +void +gst_vaapi_plugin_base_set_display_type (GstVaapiPluginBase * plugin, + GstVaapiDisplayType display_type); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin); + G_END_DECLS #endif /* GST_VAAPI_PLUGIN_BASE_H */ diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 92f9ec58f9..2e4c97e3e0 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -37,6 +37,7 @@ # include #endif #include "gstvaapipluginutil.h" +#include "gstvaapipluginbase.h" /* Preferred first */ static const char *display_types[] = { @@ -88,45 +89,31 @@ static const DisplayMap g_display_map[] = { }; static GstVaapiDisplay * -gst_vaapi_create_display(GstVaapiDisplayType *display_type) +gst_vaapi_create_display(GstVaapiDisplayType display_type) { GstVaapiDisplay *display = NULL; const DisplayMap *m; for (m = g_display_map; m->type_str != NULL; m++) { - if (*display_type != GST_VAAPI_DISPLAY_TYPE_ANY && - *display_type != m->type) + if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY && + display_type != m->type) continue; display = m->create_display(NULL); - if (display) { - *display_type = m->type; - break; - } - - if (*display_type != GST_VAAPI_DISPLAY_TYPE_ANY) + if (display || display_type != GST_VAAPI_DISPLAY_TYPE_ANY) break; } return display; } gboolean -gst_vaapi_ensure_display( - gpointer element, - GstVaapiDisplayType display_type, - GstVaapiDisplay **display_ptr -) +gst_vaapi_ensure_display(gpointer element, GstVaapiDisplayType type) { + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(element); GstVaapiDisplay *display; GstVideoContext *context; g_return_val_if_fail(GST_IS_VIDEO_CONTEXT(element), FALSE); - g_return_val_if_fail(display_ptr != NULL, FALSE); - - /* Already exist ? */ - display = *display_ptr; - if (display) - return TRUE; context = GST_VIDEO_CONTEXT(element); g_return_val_if_fail(context != NULL, FALSE); @@ -134,16 +121,17 @@ gst_vaapi_ensure_display( gst_vaapi_video_context_prepare(context, display_types); /* Neighbour found and it updated the display */ - if (*display_ptr) + if (plugin->display) return TRUE; /* If no neighboor, or application not interested, use system default */ - display = gst_vaapi_create_display(&display_type); + display = gst_vaapi_create_display(type); if (!display) return FALSE; gst_vaapi_video_context_propagate(context, display); - *display_ptr = display; + GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(plugin, display); + gst_vaapi_display_unref(display); return TRUE; } diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 76194d026b..8336efb975 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -30,11 +30,7 @@ G_GNUC_INTERNAL gboolean -gst_vaapi_ensure_display( - gpointer element, - GstVaapiDisplayType display_type, - GstVaapiDisplay **display -); +gst_vaapi_ensure_display(gpointer element, GstVaapiDisplayType type); G_GNUC_INTERNAL void diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 97eea32ad7..f269b70eef 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -272,8 +272,7 @@ gst_vaapipostproc_set_context(GstElement *element, GstContext *context) static inline gboolean gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc) { - return gst_vaapi_ensure_display(postproc, GST_VAAPI_DISPLAY_TYPE_ANY, - &GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); + return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(postproc)); } static gboolean diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index bb2f68a07c..fd89804450 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -187,18 +187,23 @@ static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); static void -gst_vaapisink_video_overlay_set_window_handle(GstVideoOverlay *overlay, guintptr window) +gst_vaapisink_video_overlay_set_window_handle(GstVideoOverlay *overlay, + guintptr window) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); + GstVaapiDisplayType display_type = GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink); /* Disable GLX rendering when vaapisink is using a foreign X window. It's pretty much useless */ - if (sink->display_type == GST_VAAPI_DISPLAY_TYPE_GLX) - sink->display_type = GST_VAAPI_DISPLAY_TYPE_X11; + if (display_type == GST_VAAPI_DISPLAY_TYPE_GLX) { + display_type = GST_VAAPI_DISPLAY_TYPE_X11; + gst_vaapi_plugin_base_set_display_type(GST_VAAPI_PLUGIN_BASE(sink), + display_type); + } sink->foreign_window = TRUE; - switch (sink->display_type) { + switch (display_type) { #if USE_X11 case GST_VAAPI_DISPLAY_TYPE_X11: gst_vaapisink_ensure_window_xid(sink, window); @@ -347,28 +352,26 @@ get_display_type_name(GstVaapiDisplayType display_type) static inline gboolean gst_vaapisink_ensure_display(GstVaapiSink *sink) { - GstVaapiDisplayType display_type; + return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(sink)); +} + +static void +gst_vaapisink_display_changed(GstVaapiPluginBase *plugin) +{ + GstVaapiSink * const sink = GST_VAAPISINK(plugin); GstVaapiRenderMode render_mode; - const gboolean had_display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink) != NULL; - if (!gst_vaapi_ensure_display(sink, sink->display_type, &GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) - return FALSE; + GST_INFO("created %s %p", get_display_type_name(plugin->display_type), + plugin->display); - display_type = gst_vaapi_display_get_display_type(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - if (display_type != sink->display_type || (!had_display && GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) { - GST_INFO("created %s %p", get_display_type_name(display_type), - GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - sink->display_type = display_type; + sink->use_overlay = + gst_vaapi_display_get_render_mode(plugin->display, &render_mode) && + render_mode == GST_VAAPI_RENDER_MODE_OVERLAY; + GST_DEBUG("use %s rendering mode", + sink->use_overlay ? "overlay" : "texture"); - sink->use_overlay = - gst_vaapi_display_get_render_mode(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink), &render_mode) && - render_mode == GST_VAAPI_RENDER_MODE_OVERLAY; - GST_DEBUG("use %s rendering mode", sink->use_overlay ? "overlay" : "texture"); - - sink->use_rotation = gst_vaapi_display_has_property( - GST_VAAPI_PLUGIN_BASE_DISPLAY(sink), GST_VAAPI_DISPLAY_PROP_ROTATION); - } - return TRUE; + sink->use_rotation = gst_vaapi_display_has_property(plugin->display, + GST_VAAPI_DISPLAY_PROP_ROTATION); } static gboolean @@ -512,7 +515,9 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); if (!sink->window) { - switch (sink->display_type) { + const GstVaapiDisplayType display_type = + GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink); + switch (display_type) { #if USE_GLX case GST_VAAPI_DISPLAY_TYPE_GLX: sink->window = gst_vaapi_window_glx_new(display, width, height); @@ -536,7 +541,7 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) break; #endif default: - GST_ERROR("unsupported display type %d", sink->display_type); + GST_ERROR("unsupported display type %d", display_type); return FALSE; } } @@ -580,7 +585,7 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) gst_vaapi_window_replace(&sink->window, NULL); - switch (sink->display_type) { + switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { #if USE_GLX case GST_VAAPI_DISPLAY_TYPE_GLX: sink->window = gst_vaapi_window_glx_new_with_xid(display, xid); @@ -590,7 +595,8 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) sink->window = gst_vaapi_window_x11_new_with_xid(display, xid); break; default: - GST_ERROR("unsupported display type %d", sink->display_type); + GST_ERROR("unsupported display type %d", + GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)); return FALSE; } return sink->window != NULL; @@ -780,8 +786,12 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) GstVaapiDisplay *display; guint win_width, win_height; + if (!gst_vaapisink_ensure_display(sink)) + return FALSE; + display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); + #if USE_DRM - if (sink->display_type == GST_VAAPI_DISPLAY_TYPE_DRM) + if (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink) == GST_VAAPI_DISPLAY_TYPE_DRM) return TRUE; #endif @@ -800,10 +810,6 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) gst_caps_replace(&sink->caps, caps); - if (!gst_vaapisink_ensure_display(sink)) - return FALSE; - display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); - #if !GST_CHECK_VERSION(1,0,0) if (sink->use_video_raw) { /* Ensure the uploader is set up for upstream allocated buffers */ @@ -1228,7 +1234,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) if (!gst_vaapi_apply_composition(surface, src_buffer)) GST_WARNING("could not update subtitles"); - switch (sink->display_type) { + switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { #if USE_DRM case GST_VAAPI_DISPLAY_TYPE_DRM: success = TRUE; @@ -1254,7 +1260,8 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) break; #endif default: - GST_ERROR("unsupported display type %d", sink->display_type); + GST_ERROR("unsupported display type %d", + GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)); success = FALSE; break; } @@ -1403,7 +1410,8 @@ gst_vaapisink_set_property( switch (prop_id) { case PROP_DISPLAY_TYPE: - sink->display_type = g_value_get_enum(value); + gst_vaapi_plugin_base_set_display_type(GST_VAAPI_PLUGIN_BASE(sink), + g_value_get_enum(value)); break; case PROP_FULLSCREEN: sink->fullscreen = g_value_get_boolean(value); @@ -1441,7 +1449,7 @@ gst_vaapisink_get_property( switch (prop_id) { case PROP_DISPLAY_TYPE: - g_value_set_enum(value, sink->display_type); + g_value_set_enum(value, GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)); break; case PROP_FULLSCREEN: g_value_set_boolean(value, sink->fullscreen); @@ -1473,12 +1481,15 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass); + GstVaapiPluginBaseClass * const base_plugin_class = + GST_VAAPI_PLUGIN_BASE_CLASS(klass); GstPadTemplate *pad_template; GST_DEBUG_CATEGORY_INIT(gst_debug_vaapisink, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass)); + gst_vaapi_plugin_base_class_init(base_plugin_class); + base_plugin_class->display_changed = gst_vaapisink_display_changed; object_class->finalize = gst_vaapisink_finalize; object_class->set_property = gst_vaapisink_set_property; @@ -1598,7 +1609,10 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) static void gst_vaapisink_init(GstVaapiSink *sink) { - gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(sink), GST_CAT_DEFAULT); + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(sink); + + gst_vaapi_plugin_base_init(plugin, GST_CAT_DEFAULT); + gst_vaapi_plugin_base_set_display_type(plugin, DEFAULT_DISPLAY_TYPE); sink->caps = NULL; sink->window = NULL; @@ -1613,7 +1627,6 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->foreign_window = FALSE; sink->fullscreen = FALSE; sink->synchronous = FALSE; - sink->display_type = DEFAULT_DISPLAY_TYPE; sink->rotation = DEFAULT_ROTATION; sink->rotation_req = DEFAULT_ROTATION; sink->use_reflection = FALSE; diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 491f1b4954..8aae2ff3e6 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -71,7 +71,6 @@ struct _GstVaapiSink { GstVaapiUploader *uploader; GstCaps *caps; - GstVaapiDisplayType display_type; GstVaapiWindow *window; guint window_width; guint window_height; diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index ce84d2020b..25ebcd0fb2 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -251,8 +251,7 @@ gst_vaapiupload_init(GstVaapiUpload *upload) static inline gboolean gst_vaapiupload_ensure_display(GstVaapiUpload *upload) { - return gst_vaapi_ensure_display(upload, GST_VAAPI_DISPLAY_TYPE_ANY, - &GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)); + return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(upload)); } static gboolean From fad3f538bc3f4e27c82ba687c43b6ea5547983fb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Dec 2013 12:00:35 +0100 Subject: [PATCH 1465/3781] plugins: check type of display obtained from neighbours. Fix display creation code to check that any display obtained from a neighbour actually has the type we expect. Note: if display type is set to "any", we can then accept any VA display type. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 28 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 4 ++++ gst/vaapi/gstvaapipluginbase.c | 11 ++--------- gst/vaapi/gstvaapipluginutil.c | 3 ++- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index cb537d94c9..74a8eecb21 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -176,6 +176,34 @@ gst_vaapi_display_type_get_type(void) return g_type; } +/** + * gst_vaapi_display_type_is_compatible: + * @type1: the #GstVaapiDisplayType to test + * @type2: the reference #GstVaapiDisplayType + * + * Compares whether #GstVaapiDisplay @type1 is compatible with @type2. + * That is, if @type2 is in "any" category, or derived from @type1. + * + * Returns: %TRUE if @type1 is compatible with @type2, %FALSE otherwise. + */ +gboolean +gst_vaapi_display_type_is_compatible(GstVaapiDisplayType type1, + GstVaapiDisplayType type2) +{ + if (type1 == type2) + return TRUE; + + switch (type1) { + case GST_VAAPI_DISPLAY_TYPE_GLX: + if (type2 == GST_VAAPI_DISPLAY_TYPE_X11) + return TRUE; + break; + default: + break; + } + return type2 == GST_VAAPI_DISPLAY_TYPE_ANY; +} + /* Append GstVideoFormat to formats array */ static inline void append_format(GArray *formats, GstVideoFormat format, guint flags) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 1d190679da..75cdbd3e5a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -61,6 +61,10 @@ typedef enum { GType gst_vaapi_display_type_get_type(void) G_GNUC_CONST; +gboolean +gst_vaapi_display_type_is_compatible(GstVaapiDisplayType type1, + GstVaapiDisplayType type2); + /** * GstVaapiDisplayInfo: * diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 366d616bd5..1f106de998 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -101,14 +101,6 @@ gst_vaapi_plugin_base_set_display_type (GstVaapiPluginBase * plugin, plugin->display_type_req = display_type; } -/* Checks wether display type 1 is compatible with display type 2 */ -static gboolean -display_type_is_compatible (GstVaapiDisplayType type1, - GstVaapiDisplayType type2) -{ - return (type1 == type2 || type2 == GST_VAAPI_DISPLAY_TYPE_ANY); -} - /** * gst_vaapi_plugin_base_ensure_display: * @plugin: a #GstVaapiPluginBase @@ -122,7 +114,8 @@ display_type_is_compatible (GstVaapiDisplayType type1, gboolean gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) { - if (plugin->display && display_type_is_compatible (plugin->display_type, + if (plugin->display + && gst_vaapi_display_type_is_compatible (plugin->display_type, plugin->display_type_req)) return TRUE; gst_vaapi_display_replace (&plugin->display, NULL); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 2e4c97e3e0..55cbd7b86e 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -121,7 +121,8 @@ gst_vaapi_ensure_display(gpointer element, GstVaapiDisplayType type) gst_vaapi_video_context_prepare(context, display_types); /* Neighbour found and it updated the display */ - if (plugin->display) + if (plugin->display && gst_vaapi_display_type_is_compatible( + plugin->display_type, type)) return TRUE; /* If no neighboor, or application not interested, use system default */ From e5f066b719aad015bf76c93f0c7b6d0c3c7d5fa6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Dec 2013 13:24:24 +0100 Subject: [PATCH 1466/3781] plugins: factor out GstImplementsInterface. --- gst/vaapi/gstvaapidecode.c | 23 +---------------------- gst/vaapi/gstvaapidownload.c | 19 +------------------ gst/vaapi/gstvaapiencode.c | 21 +-------------------- gst/vaapi/gstvaapipluginbase.c | 34 +++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapipluginbase.h | 8 ++++++++ gst/vaapi/gstvaapipostproc.c | 23 +---------------------- gst/vaapi/gstvaapisink.c | 31 ++++++++----------------------- gst/vaapi/gstvaapiupload.c | 20 +------------------- 8 files changed, 54 insertions(+), 125 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 22281225f7..851659b3c1 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -95,24 +95,6 @@ static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapidecode_src_caps_str)); -/* GstImplementsInterface interface */ -#if !GST_CHECK_VERSION(1,0,0) -static gboolean -gst_vaapidecode_implements_interface_supported( - GstImplementsInterface *iface, - GType type -) -{ - return (type == GST_TYPE_VIDEO_CONTEXT); -} - -static void -gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface) -{ - iface->supported = gst_vaapidecode_implements_interface_supported; -} -#endif - /* GstVideoContext interface */ #if !GST_CHECK_VERSION(1,1,0) static void @@ -136,10 +118,7 @@ G_DEFINE_TYPE_WITH_CODE( GstVaapiDecode, gst_vaapidecode, GST_TYPE_VIDEO_DECODER, -#if !GST_CHECK_VERSION(1,0,0) - G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, - gst_vaapidecode_implements_iface_init); -#endif + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES #if !GST_CHECK_VERSION(1,1,0) G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init) diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index ed33bc445a..a7bb9f2310 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -91,22 +91,6 @@ struct _GstVaapiDownloadClass { GstVaapiPluginBaseClass parent_class; }; -/* GstImplementsInterface interface */ -static gboolean -gst_vaapidownload_implements_interface_supported( - GstImplementsInterface *iface, - GType type -) -{ - return (type == GST_TYPE_VIDEO_CONTEXT); -} - -static void -gst_vaapidownload_implements_iface_init(GstImplementsInterfaceClass *iface) -{ - iface->supported = gst_vaapidownload_implements_interface_supported; -} - /* GstVideoContext interface */ static void gst_vaapidownload_set_video_context(GstVideoContext *context, const gchar *type, @@ -127,8 +111,7 @@ G_DEFINE_TYPE_WITH_CODE( GstVaapiDownload, gst_vaapidownload, GST_TYPE_BASE_TRANSFORM, - G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, - gst_vaapidownload_implements_iface_init); + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init)) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index c8b670b34e..b4d49ef8e6 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -42,22 +42,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapiencode_debug); #define GST_CAT_DEFAULT gst_vaapiencode_debug -/* GstImplementsInterface interface */ -#if !GST_CHECK_VERSION(1,0,0) -static gboolean -gst_vaapiencode_implements_interface_supported (GstImplementsInterface * iface, - GType type) -{ - return (type == GST_TYPE_VIDEO_CONTEXT); -} - -static void -gst_vaapiencode_implements_iface_init (GstImplementsInterfaceClass * iface) -{ - iface->supported = gst_vaapiencode_implements_interface_supported; -} -#endif - /* GstContext interface */ #if GST_CHECK_VERSION(1,1,0) static void @@ -93,10 +77,7 @@ gst_video_context_interface_init (GstVideoContextInterface * iface) G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode, gst_vaapiencode, GST_TYPE_VIDEO_ENCODER, -#if !GST_CHECK_VERSION(1,0,0) - G_IMPLEMENT_INTERFACE (GST_TYPE_IMPLEMENTS_INTERFACE, - gst_vaapiencode_implements_iface_init); -#endif + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES #if !GST_CHECK_VERSION(1,1,0) G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 1f106de998..35fadf5376 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -29,6 +29,38 @@ /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) +/* GstImplementsInterface interface */ +#if !GST_CHECK_VERSION(1,0,0) +static gboolean +implements_interface_supported (GstImplementsInterface * iface, GType type) +{ + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (iface); + + return GST_VAAPI_PLUGIN_BASE_GET_CLASS (plugin)->has_interface (plugin, type); +} + +static void +implements_interface_init (GstImplementsInterfaceClass * iface) +{ + iface->supported = implements_interface_supported; +} +#endif + +void +gst_vaapi_plugin_base_init_interfaces (GType g_define_type_id) +{ +#if !GST_CHECK_VERSION(1,0,0) + G_IMPLEMENT_INTERFACE (GST_TYPE_IMPLEMENTS_INTERFACE, + implements_interface_init); +#endif +} + +static gboolean +default_has_interface (GstVaapiPluginBase * plugin, GType type) +{ + return FALSE; +} + static void default_display_changed (GstVaapiPluginBase * plugin) { @@ -37,6 +69,7 @@ default_display_changed (GstVaapiPluginBase * plugin) void gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) { + klass->has_interface = default_has_interface; klass->display_changed = default_display_changed; } @@ -45,7 +78,6 @@ gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin, GstDebugCategory * debug_category) { plugin->debug_category = debug_category; - plugin->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; plugin->display_type_req = GST_VAAPI_DISPLAY_TYPE_ANY; } diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 952d3091b3..0f80ea60d6 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -68,6 +68,9 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; #define GST_VAAPI_PLUGIN_BASE_SINK_CLASS(plugin) \ (&GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin)->sink) +#define GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES \ + gst_vaapi_plugin_base_init_interfaces(g_define_type_id); + #define GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->display) #define GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(plugin) \ @@ -107,9 +110,14 @@ struct _GstVaapiPluginBaseClass GstVideoSinkClass sink; } parent_class; + gboolean (*has_interface) (GstVaapiPluginBase * plugin, GType type); void (*display_changed) (GstVaapiPluginBase * plugin); }; +G_GNUC_INTERNAL +void +gst_vaapi_plugin_base_init_interfaces (GType type); + G_GNUC_INTERNAL void gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index f269b70eef..36afd2d641 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -89,24 +89,6 @@ static GstStaticPadTemplate gst_vaapipostproc_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapipostproc_src_caps_str)); -/* GstImplementsInterface interface */ -#if !GST_CHECK_VERSION(1,0,0) -static gboolean -gst_vaapipostproc_implements_interface_supported( - GstImplementsInterface *iface, - GType type -) -{ - return (type == GST_TYPE_VIDEO_CONTEXT); -} - -static void -gst_vaapipostproc_implements_iface_init(GstImplementsInterfaceClass *iface) -{ - iface->supported = gst_vaapipostproc_implements_interface_supported; -} -#endif - /* GstVideoContext interface */ #if !GST_CHECK_VERSION(1,1,0) static void @@ -137,10 +119,7 @@ G_DEFINE_TYPE_WITH_CODE( GstVaapiPostproc, gst_vaapipostproc, GST_TYPE_BASE_TRANSFORM, -#if !GST_CHECK_VERSION(1,0,0) - G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, - gst_vaapipostproc_implements_iface_init); -#endif + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES #if !GST_CHECK_VERSION(1,1,0) G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index fd89804450..86fd91bbdc 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -107,25 +107,6 @@ static GstStaticPadTemplate gst_vaapisink_sink_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapisink_sink_caps_str)); -/* GstImplementsInterface interface */ -#if !GST_CHECK_VERSION(1,0,0) -static gboolean -gst_vaapisink_implements_interface_supported( - GstImplementsInterface *iface, - GType type -) -{ - return (type == GST_TYPE_VIDEO_CONTEXT || - type == GST_TYPE_VIDEO_OVERLAY); -} - -static void -gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface) -{ - iface->supported = gst_vaapisink_implements_interface_supported; -} -#endif - /* GstVideoContext interface */ #if !GST_CHECK_VERSION(1,1,0) static void @@ -143,6 +124,12 @@ gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface) } #endif +static gboolean +gst_vaapisink_has_interface(GstVaapiPluginBase *plugin, GType type) +{ + return type == GST_TYPE_VIDEO_OVERLAY; +} + static void gst_vaapisink_video_overlay_iface_init(GstVideoOverlayInterface *iface); @@ -150,10 +137,7 @@ G_DEFINE_TYPE_WITH_CODE( GstVaapiSink, gst_vaapisink, GST_TYPE_VIDEO_SINK, -#if !GST_CHECK_VERSION(1,0,0) - G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, - gst_vaapisink_implements_iface_init); -#endif + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES #if !GST_CHECK_VERSION(1,1,0) G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_vaapisink_video_context_iface_init); @@ -1489,6 +1473,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); gst_vaapi_plugin_base_class_init(base_plugin_class); + base_plugin_class->has_interface = gst_vaapisink_has_interface; base_plugin_class->display_changed = gst_vaapisink_display_changed; object_class->finalize = gst_vaapisink_finalize; diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index 25ebcd0fb2..e74b0ca8d0 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -68,23 +68,6 @@ static GstStaticPadTemplate gst_vaapiupload_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapiupload_vaapi_caps_str)); - -/* GstImplementsInterface interface */ -static gboolean -gst_vaapiupload_implements_interface_supported( - GstImplementsInterface *iface, - GType type -) -{ - return (type == GST_TYPE_VIDEO_CONTEXT); -} - -static void -gst_vaapiupload_implements_iface_init(GstImplementsInterfaceClass *iface) -{ - iface->supported = gst_vaapiupload_implements_interface_supported; -} - /* GstVideoContext interface */ static void gst_vaapiupload_set_video_context(GstVideoContext *context, const gchar *type, @@ -110,8 +93,7 @@ G_DEFINE_TYPE_WITH_CODE( GstVaapiUpload, gst_vaapiupload, GST_TYPE_BASE_TRANSFORM, - G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE, - gst_vaapiupload_implements_iface_init); + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, gst_video_context_interface_init)) From 01a3fc44c01628ff854f10b3ee8e1f64cc9bf660 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Dec 2013 16:03:08 +0100 Subject: [PATCH 1467/3781] plugins: factor out video context sharing code. --- gst/vaapi/gstvaapidecode.c | 46 +---------------------------- gst/vaapi/gstvaapidownload.c | 21 +------------- gst/vaapi/gstvaapiencode.c | 48 +----------------------------- gst/vaapi/gstvaapipluginbase.c | 44 ++++++++++++++++++++++++++++ gst/vaapi/gstvaapipostproc.c | 53 +--------------------------------- gst/vaapi/gstvaapisink.c | 41 -------------------------- gst/vaapi/gstvaapiupload.c | 26 +---------------- 7 files changed, 49 insertions(+), 230 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 851659b3c1..9cc5f78f20 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -35,7 +35,6 @@ #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" -#include "gstvaapivideocontext.h" #include "gstvaapivideobuffer.h" #if GST_CHECK_VERSION(1,1,0) && USE_GLX #include "gstvaapivideometa_texture.h" @@ -95,35 +94,11 @@ static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapidecode_src_caps_str)); -/* GstVideoContext interface */ -#if !GST_CHECK_VERSION(1,1,0) -static void -gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type, - const GValue *value) -{ - GstVaapiDecode *decode = GST_VAAPIDECODE (context); - gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); -} - -static void -gst_video_context_interface_init(GstVideoContextInterface *iface) -{ - iface->set_context = gst_vaapidecode_set_video_context; -} - -#define GstVideoContextClass GstVideoContextInterface -#endif - G_DEFINE_TYPE_WITH_CODE( GstVaapiDecode, gst_vaapidecode, GST_TYPE_VIDEO_DECODER, - GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES -#if !GST_CHECK_VERSION(1,1,0) - G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init) -#endif - ) + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) static gboolean gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, @@ -564,21 +539,6 @@ error_create_pool: } #endif -#if GST_CHECK_VERSION(1,1,0) -static void -gst_vaapidecode_set_context(GstElement *element, GstContext *context) -{ - GstVaapiDecode * const decode = GST_VAAPIDECODE(element); - GstVaapiDisplay *display = NULL; - - if (gst_vaapi_video_context_get_display(context, &display)) { - GST_INFO_OBJECT(element, "set display %p", display); - GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(decode, display); - gst_vaapi_display_unref(display); - } -} -#endif - static inline gboolean gst_vaapidecode_ensure_display(GstVaapiDecode *decode) { @@ -833,10 +793,6 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) GST_DEBUG_FUNCPTR(gst_vaapidecode_decide_allocation); #endif -#if GST_CHECK_VERSION(1,1,0) - element_class->set_context = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_context); -#endif - gst_element_class_set_static_metadata(element_class, "VA-API decoder", "Codec/Decoder/Video", diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index a7bb9f2310..ff2a25a79e 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -32,7 +32,6 @@ #include "gst/vaapi/sysdeps.h" #include #include -#include #include "gstvaapidownload.h" #include "gstvaapipluginutil.h" @@ -91,29 +90,11 @@ struct _GstVaapiDownloadClass { GstVaapiPluginBaseClass parent_class; }; -/* GstVideoContext interface */ -static void -gst_vaapidownload_set_video_context(GstVideoContext *context, const gchar *type, - const GValue *value) -{ - GstVaapiDownload *download = GST_VAAPIDOWNLOAD (context); - gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(download)); -} - -static void -gst_video_context_interface_init(GstVideoContextInterface *iface) -{ - iface->set_context = gst_vaapidownload_set_video_context; -} - -#define GstVideoContextClass GstVideoContextInterface G_DEFINE_TYPE_WITH_CODE( GstVaapiDownload, gst_vaapidownload, GST_TYPE_BASE_TRANSFORM, - GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES - G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init)) + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) static gboolean gst_vaapidownload_start(GstBaseTransform *trans); diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index b4d49ef8e6..87fadc09f5 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -23,7 +23,6 @@ #include #include #include "gstvaapiencode.h" -#include "gstvaapivideocontext.h" #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" #if GST_CHECK_VERSION(1,0,0) @@ -42,47 +41,9 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapiencode_debug); #define GST_CAT_DEFAULT gst_vaapiencode_debug -/* GstContext interface */ -#if GST_CHECK_VERSION(1,1,0) -static void -gst_vaapiencode_set_context (GstElement * element, GstContext * context) -{ - GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (element); - GstVaapiDisplay *display = NULL; - - if (gst_vaapi_video_context_get_display (context, &display)) { - GST_INFO_OBJECT (element, "set display %p", display); - GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE (encode, display); - gst_vaapi_display_unref (display); - } -} -#else -static void -gst_vaapiencode_set_video_context (GstVideoContext * context, - const gchar * type, const GValue * value) -{ - GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (context); - - gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); -} - -static void -gst_video_context_interface_init (GstVideoContextInterface * iface) -{ - iface->set_context = gst_vaapiencode_set_video_context; -} - -#define GstVideoContextClass GstVideoContextInterface -#endif - G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode, gst_vaapiencode, GST_TYPE_VIDEO_ENCODER, - GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES -#if !GST_CHECK_VERSION(1,1,0) - G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init) -#endif - ) + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) enum { @@ -917,9 +878,6 @@ static void gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); -#if GST_CHECK_VERSION(1,1,0) - GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); -#endif GstVideoEncoderClass *const venc_class = GST_VIDEO_ENCODER_CLASS (klass); GST_DEBUG_CATEGORY_INIT (gst_vaapiencode_debug, @@ -931,10 +889,6 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) object_class->set_property = gst_vaapiencode_set_property; object_class->get_property = gst_vaapiencode_get_property; -#if GST_CHECK_VERSION(1,1,0) - element_class->set_context = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_context); -#endif - venc_class->open = GST_DEBUG_FUNCPTR (gst_vaapiencode_open); venc_class->close = GST_DEBUG_FUNCPTR (gst_vaapiencode_close); venc_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_format); diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 35fadf5376..09e6b4b42a 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -25,6 +25,7 @@ #include "gst/vaapi/sysdeps.h" #include "gstvaapipluginbase.h" #include "gstvaapipluginutil.h" +#include "gstvaapivideocontext.h" /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) @@ -36,6 +37,8 @@ implements_interface_supported (GstImplementsInterface * iface, GType type) { GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (iface); + if (type == GST_TYPE_VIDEO_CONTEXT) + return TRUE; return GST_VAAPI_PLUGIN_BASE_GET_CLASS (plugin)->has_interface (plugin, type); } @@ -46,6 +49,39 @@ implements_interface_init (GstImplementsInterfaceClass * iface) } #endif +/* GstVideoContext interface */ +#if GST_CHECK_VERSION(1,1,0) +static void +plugin_set_context (GstElement * element, GstContext * context) +{ + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); + GstVaapiDisplay *display = NULL; + + if (gst_vaapi_video_context_get_display (context, &display)) { + GST_INFO_OBJECT (element, "set display %p", display); + gst_vaapi_display_replace (&plugin->display, display); + gst_vaapi_display_unref (display); + } +} +#else +static void +plugin_set_context (GstVideoContext * context, const gchar * type, + const GValue * value) +{ + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (context); + + gst_vaapi_set_display (type, value, &plugin->display); +} + +static void +video_context_interface_init (GstVideoContextInterface * iface) +{ + iface->set_context = plugin_set_context; +} + +#define GstVideoContextClass GstVideoContextInterface +#endif + void gst_vaapi_plugin_base_init_interfaces (GType g_define_type_id) { @@ -53,6 +89,9 @@ gst_vaapi_plugin_base_init_interfaces (GType g_define_type_id) G_IMPLEMENT_INTERFACE (GST_TYPE_IMPLEMENTS_INTERFACE, implements_interface_init); #endif +#if !GST_CHECK_VERSION(1,1,0) + G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_CONTEXT, video_context_interface_init); +#endif } static gboolean @@ -71,6 +110,11 @@ gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) { klass->has_interface = default_has_interface; klass->display_changed = default_display_changed; + +#if GST_CHECK_VERSION(1,1,0) + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + element_class->set_context = GST_DEBUG_FUNCPTR (plugin_set_context); +#endif } void diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 36afd2d641..700c55e54e 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -34,7 +34,6 @@ #include "gstvaapipostproc.h" #include "gstvaapipluginutil.h" -#include "gstvaapivideocontext.h" #include "gstvaapivideobuffer.h" #if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" @@ -89,42 +88,11 @@ static GstStaticPadTemplate gst_vaapipostproc_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapipostproc_src_caps_str)); -/* GstVideoContext interface */ -#if !GST_CHECK_VERSION(1,1,0) -static void -gst_vaapipostproc_set_video_context( - GstVideoContext *context, - const gchar *type, - const GValue *value -) -{ - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(context); - - gst_vaapi_set_display(type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); - - if (postproc->uploader) - gst_vaapi_uploader_ensure_display(postproc->uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); -} - -static void -gst_video_context_interface_init(GstVideoContextInterface *iface) -{ - iface->set_context = gst_vaapipostproc_set_video_context; -} - -#define GstVideoContextClass GstVideoContextInterface -#endif - G_DEFINE_TYPE_WITH_CODE( GstVaapiPostproc, gst_vaapipostproc, GST_TYPE_BASE_TRANSFORM, - GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES -#if !GST_CHECK_VERSION(1,1,0) - G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init) -#endif - ) + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) enum { PROP_0, @@ -233,21 +201,6 @@ find_filter_op(GPtrArray *filter_ops, GstVaapiFilterOp op) return NULL; } -#if GST_CHECK_VERSION(1,1,0) -static void -gst_vaapipostproc_set_context(GstElement *element, GstContext *context) -{ - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(element); - GstVaapiDisplay *display = NULL; - - if (gst_vaapi_video_context_get_display(context, &display)) { - GST_INFO_OBJECT(element, "set display %p", display); - GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(postproc, display); - gst_vaapi_display_unref(display); - } -} -#endif - static inline gboolean gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc) { @@ -1627,10 +1580,6 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) trans_class->prepare_output_buffer = gst_vaapipostproc_prepare_output_buffer; -#if GST_CHECK_VERSION(1,1,0) - element_class->set_context = gst_vaapipostproc_set_context; -#endif - gst_element_class_set_static_metadata(element_class, "VA-API video postprocessing", "Filter/Converter/Video", diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 86fd91bbdc..2f081dff2c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -71,7 +71,6 @@ #include "gstvaapisink.h" #include "gstvaapipluginutil.h" -#include "gstvaapivideocontext.h" #include "gstvaapivideometa.h" #if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" @@ -107,23 +106,6 @@ static GstStaticPadTemplate gst_vaapisink_sink_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapisink_sink_caps_str)); -/* GstVideoContext interface */ -#if !GST_CHECK_VERSION(1,1,0) -static void -gst_vaapisink_set_video_context(GstVideoContext *context, const gchar *type, - const GValue *value) -{ - GstVaapiSink *sink = GST_VAAPISINK (context); - gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); -} - -static void -gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface) -{ - iface->set_context = gst_vaapisink_set_video_context; -} -#endif - static gboolean gst_vaapisink_has_interface(GstVaapiPluginBase *plugin, GType type) { @@ -138,10 +120,6 @@ G_DEFINE_TYPE_WITH_CODE( gst_vaapisink, GST_TYPE_VIDEO_SINK, GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES -#if !GST_CHECK_VERSION(1,1,0) - G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_vaapisink_video_context_iface_init); -#endif G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_OVERLAY, gst_vaapisink_video_overlay_iface_init)) @@ -1342,21 +1320,6 @@ gst_vaapisink_buffer_alloc( } #endif -#if GST_CHECK_VERSION(1,1,0) -static void -gst_vaapisink_set_context(GstElement *element, GstContext *context) -{ - GstVaapiSink * const sink = GST_VAAPISINK(element); - GstVaapiDisplay *display = NULL; - - if (gst_vaapi_video_context_get_display(context, &display)) { - GST_INFO_OBJECT(element, "set display %p", display); - GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(sink, display); - gst_vaapi_display_unref(display); - } -} -#endif - static gboolean gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query) { @@ -1493,10 +1456,6 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; #endif -#if GST_CHECK_VERSION(1,1,0) - element_class->set_context = gst_vaapisink_set_context; -#endif - gst_element_class_set_static_metadata(element_class, "VA-API sink", "Sink/Video", diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index e74b0ca8d0..d4b52b7f25 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -33,7 +33,6 @@ #include "gst/vaapi/sysdeps.h" #include #include -#include #include "gstvaapiupload.h" #include "gstvaapipluginutil.h" @@ -68,34 +67,11 @@ static GstStaticPadTemplate gst_vaapiupload_src_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapiupload_vaapi_caps_str)); -/* GstVideoContext interface */ -static void -gst_vaapiupload_set_video_context(GstVideoContext *context, const gchar *type, - const GValue *value) -{ - GstVaapiUpload * const upload = GST_VAAPIUPLOAD(context); - - gst_vaapi_set_display(type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)); - - if (upload->uploader) - gst_vaapi_uploader_ensure_display(upload->uploader, - GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)); -} - -static void -gst_video_context_interface_init(GstVideoContextInterface *iface) -{ - iface->set_context = gst_vaapiupload_set_video_context; -} - -#define GstVideoContextClass GstVideoContextInterface G_DEFINE_TYPE_WITH_CODE( GstVaapiUpload, gst_vaapiupload, GST_TYPE_BASE_TRANSFORM, - GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES - G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT, - gst_video_context_interface_init)) + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) static gboolean gst_vaapiupload_start(GstBaseTransform *trans); From b324fc6adddefe2749bc40f6116a755553ba22bf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 17 Dec 2013 18:46:07 +0100 Subject: [PATCH 1468/3781] plugins: factor out pad caps. --- gst-libs/gst/vaapi/gstcompat.h | 2 ++ gst/vaapi/gstvaapidecode.c | 40 +++++++++++++----------- gst/vaapi/gstvaapidecode.h | 4 --- gst/vaapi/gstvaapidownload.c | 3 ++ gst/vaapi/gstvaapipluginbase.c | 56 +++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapipluginbase.h | 34 +++++++++++++++++++++ gst/vaapi/gstvaapipostproc.c | 12 ++++---- gst/vaapi/gstvaapipostproc.h | 2 -- gst/vaapi/gstvaapisink.c | 4 +++ gst/vaapi/gstvaapiupload.c | 3 ++ 10 files changed, 129 insertions(+), 31 deletions(-) diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index efb5c568c4..9abc2fd37f 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -314,6 +314,8 @@ gst_compat_pad_start_task(GstPad *pad, GstTaskFunction func, gpointer user_data, gst_compat_pad_start_task(pad, func, user_data, notify) /* GstElement */ +#undef GST_ELEMENT_FLAG_SINK +#define GST_ELEMENT_FLAG_SINK GST_ELEMENT_IS_SINK #undef gst_element_class_set_static_metadata #define gst_element_class_set_static_metadata(klass, name, path, desc, author) \ gst_compat_element_class_set_static_metadata(klass, name, path, desc, author) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9cc5f78f20..8a6b31d212 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -399,7 +399,7 @@ gst_vaapidecode_decode_loop(GstVaapiDecode *decode) /* Suspend the task if an error occurred */ if (ret != GST_VIDEO_DECODER_FLOW_NEED_DATA) - gst_pad_pause_task(decode->srcpad); + gst_pad_pause_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); } static gboolean @@ -444,7 +444,7 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) decode->decoder_finish = TRUE; g_cond_wait(&decode->decoder_finish_done, &decode->decoder_mutex); g_mutex_unlock(&decode->decoder_mutex); - gst_pad_stop_task(decode->srcpad); + gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); GST_VIDEO_DECODER_STREAM_LOCK(vdec); return ret; } @@ -591,14 +591,14 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) gst_vaapi_decoder_state_changed, decode); decode->decoder_caps = gst_caps_ref(caps); - return gst_pad_start_task(decode->srcpad, + return gst_pad_start_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode), (GstTaskFunction)gst_vaapidecode_decode_loop, decode, NULL); } static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { - gst_pad_stop_task(decode->srcpad); + gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); gst_vaapi_decoder_replace(&decode->decoder, NULL); gst_caps_replace(&decode->decoder_caps, NULL); gst_vaapidecode_release(decode); @@ -621,7 +621,7 @@ gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) gst_vaapi_decoder_flush(decode->decoder); GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); - gst_pad_stop_task(decode->srcpad); + gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); GST_VIDEO_DECODER_STREAM_LOCK(vdec); decode->decoder_loop_status = GST_FLOW_OK; @@ -709,12 +709,16 @@ gst_vaapidecode_reset(GstVideoDecoder *vdec, gboolean hard) static gboolean gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) { + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec); GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); if (!gst_vaapidecode_update_sink_caps(decode, state->caps)) return FALSE; if (!gst_vaapidecode_update_src_caps(decode, state)) return FALSE; + if (!gst_vaapi_plugin_base_set_caps(plugin, decode->sinkpad_caps, + decode->srcpad_caps)) + return FALSE; if (!gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, FALSE)) return FALSE; return TRUE; @@ -881,12 +885,13 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) { GstVaapiDecode * const decode = GST_VAAPIDECODE(gst_pad_get_parent_element(pad)); + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(decode); gboolean res; GST_INFO_OBJECT(decode, "query type %s", GST_QUERY_TYPE_NAME(query)); - if (gst_vaapi_reply_to_query(query, GST_VAAPI_PLUGIN_BASE_DISPLAY(decode))) { - GST_DEBUG("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); + if (gst_vaapi_reply_to_query(query, plugin->display)) { + GST_DEBUG("sharing display %p", plugin->display); res = TRUE; } else if (GST_PAD_IS_SINK(pad)) { @@ -901,14 +906,14 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) } #endif default: - res = GST_PAD_QUERY_FUNCTION_CALL(decode->sinkpad_query, - decode->sinkpad, parent, query); + res = GST_PAD_QUERY_FUNCTION_CALL(plugin->sinkpad_query, pad, + parent, query); break; } } else - res = GST_PAD_QUERY_FUNCTION_CALL(decode->srcpad_query, - decode->srcpad, parent, query); + res = GST_PAD_QUERY_FUNCTION_CALL(plugin->srcpad_query, pad, + parent, query); gst_object_unref(decode); return res; @@ -918,6 +923,7 @@ static void gst_vaapidecode_init(GstVaapiDecode *decode) { GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); + GstPad *pad; gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(decode), GST_CAT_DEFAULT); @@ -933,15 +939,13 @@ gst_vaapidecode_init(GstVaapiDecode *decode) gst_video_decoder_set_packetized(vdec, FALSE); /* Pad through which data comes in to the element */ - decode->sinkpad = GST_VIDEO_DECODER_SINK_PAD(vdec); - decode->sinkpad_query = GST_PAD_QUERYFUNC(decode->sinkpad); - gst_pad_set_query_function(decode->sinkpad, gst_vaapidecode_query); + pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD(decode); + gst_pad_set_query_function(pad, gst_vaapidecode_query); #if !GST_CHECK_VERSION(1,0,0) - gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps); + gst_pad_set_getcaps_function(pad, gst_vaapidecode_get_caps); #endif /* Pad through which data goes out of the element */ - decode->srcpad = GST_VIDEO_DECODER_SRC_PAD(vdec); - decode->srcpad_query = GST_PAD_QUERYFUNC(decode->srcpad); - gst_pad_set_query_function(decode->srcpad, gst_vaapidecode_query); + pad = GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode); + gst_pad_set_query_function(pad, gst_vaapidecode_query); } diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index ed1e9bfa99..7128709deb 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -61,12 +61,8 @@ struct _GstVaapiDecode { /*< private >*/ GstVaapiPluginBase parent_instance; - GstPad *sinkpad; GstCaps *sinkpad_caps; - GstPadQueryFunction sinkpad_query; - GstPad *srcpad; GstCaps *srcpad_caps; - GstPadQueryFunction srcpad_query; GstVaapiDecoder *decoder; GMutex decoder_mutex; GCond decoder_ready; diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index ff2a25a79e..40df273c44 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -499,8 +499,11 @@ gst_vaapidownload_set_caps( GstCaps *outcaps ) { + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(trans); GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); + if (!gst_vaapi_plugin_base_set_caps(plugin, incaps, outcaps)) + return FALSE; if (!gst_vaapidownload_negotiate_buffers(download, incaps, outcaps)) return FALSE; return TRUE; diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 09e6b4b42a..733921037c 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -124,13 +124,28 @@ gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin, plugin->debug_category = debug_category; plugin->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; plugin->display_type_req = GST_VAAPI_DISPLAY_TYPE_ANY; + + /* sink pad */ + plugin->sinkpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "sink"); + plugin->sinkpad_query = GST_PAD_QUERYFUNC (plugin->sinkpad); + gst_video_info_init (&plugin->sinkpad_info); + + /* src pad */ + if (!(GST_OBJECT_FLAGS (plugin) & GST_ELEMENT_FLAG_SINK)) { + plugin->srcpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "src"); + plugin->srcpad_query = GST_PAD_QUERYFUNC (plugin->srcpad); + } + gst_video_info_init (&plugin->srcpad_info); } void gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin) { gst_vaapi_plugin_base_close (plugin); - + if (plugin->sinkpad) + gst_object_unref (plugin->sinkpad); + if (plugin->srcpad) + gst_object_unref (plugin->srcpad); gst_debug_category_free (plugin->debug_category); } @@ -160,6 +175,14 @@ void gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) { gst_vaapi_display_replace (&plugin->display, NULL); + + gst_caps_replace (&plugin->sinkpad_caps, NULL); + plugin->sinkpad_caps_changed = FALSE; + gst_video_info_init (&plugin->sinkpad_info); + + gst_caps_replace (&plugin->srcpad_caps, NULL); + plugin->srcpad_caps_changed = FALSE; + gst_video_info_init (&plugin->srcpad_info); } /** @@ -203,3 +226,34 @@ gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) GST_VAAPI_PLUGIN_BASE_GET_CLASS (plugin)->display_changed (plugin); return TRUE; } + +/** + * gst_vaapi_plugin_base_set_caps: + * @plugin: a #GstVaapiPluginBase + * @incaps: the sink pad (input) caps + * @outcaps: the src pad (output) caps + * + * Notifies the base plugin object of the new input and output caps, + * obtained from the subclass. + * + * Returns: %TRUE if the update of caps was successful, %FALSE otherwise. + */ +gboolean +gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, + GstCaps * outcaps) +{ + if (incaps && incaps != plugin->sinkpad_caps) { + gst_caps_replace (&plugin->sinkpad_caps, incaps); + if (!gst_video_info_from_caps (&plugin->sinkpad_info, incaps)) + return FALSE; + plugin->sinkpad_caps_changed = TRUE; + } + + if (outcaps && outcaps != plugin->srcpad_caps) { + gst_caps_replace (&plugin->srcpad_caps, outcaps); + if (!gst_video_info_from_caps (&plugin->srcpad_info, outcaps)) + return FALSE; + plugin->srcpad_caps_changed = TRUE; + } + return TRUE; +} diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 0f80ea60d6..68ed6c83f6 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -71,6 +71,23 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; #define GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES \ gst_vaapi_plugin_base_init_interfaces(g_define_type_id); +#define GST_VAAPI_PLUGIN_BASE_SINK_PAD(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad) +#define GST_VAAPI_PLUGIN_BASE_SINK_PAD_CAPS(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_caps) +#define GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO(plugin) \ + (&GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_info) +#define GST_VAAPI_PLUGIN_BASE_SINK_PAD_QUERYFUNC(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_query) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_caps) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO(plugin) \ + (&GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_info) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_QUERYFYNC(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_query) + #define GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->display) #define GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(plugin) \ @@ -93,6 +110,18 @@ struct _GstVaapiPluginBase GstDebugCategory *debug_category; + GstPad *sinkpad; + GstCaps *sinkpad_caps; + gboolean sinkpad_caps_changed; + GstVideoInfo sinkpad_info; + GstPadQueryFunction sinkpad_query; + + GstPad *srcpad; + GstCaps *srcpad_caps; + gboolean srcpad_caps_changed; + GstVideoInfo srcpad_info; + GstPadQueryFunction srcpad_query; + GstVaapiDisplay *display; GstVaapiDisplayType display_type; GstVaapiDisplayType display_type_req; @@ -148,6 +177,11 @@ G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, + GstCaps * outcaps); + G_END_DECLS #endif /* GST_VAAPI_PLUGIN_BASE_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 700c55e54e..fb61a0c55a 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -230,8 +230,9 @@ static gboolean gst_vaapipostproc_ensure_uploader_caps(GstVaapiPostproc *postproc) { #if !GST_CHECK_VERSION(1,0,0) + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(postproc); if (postproc->is_raw_yuv && !gst_vaapi_uploader_ensure_caps( - postproc->uploader, postproc->sinkpad_caps, NULL)) + postproc->uploader, plugin->sinkpad_caps, NULL)) return FALSE; #endif return TRUE; @@ -312,9 +313,7 @@ gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) gst_vaapipostproc_destroy_filter(postproc); gst_caps_replace(&postproc->allowed_sinkpad_caps, NULL); - gst_caps_replace(&postproc->sinkpad_caps, NULL); gst_caps_replace(&postproc->allowed_srcpad_caps, NULL); - gst_caps_replace(&postproc->srcpad_caps, NULL); gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(postproc)); } @@ -375,7 +374,7 @@ create_output_buffer(GstVaapiPostproc *postproc) goto error_create_buffer; #if !GST_CHECK_VERSION(1,0,0) - gst_buffer_set_caps(outbuf, postproc->srcpad_caps); + gst_buffer_set_caps(outbuf, GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS(postproc)); #endif return outbuf; @@ -1379,8 +1378,9 @@ gst_vaapipostproc_set_caps(GstBaseTransform *trans, GstCaps *caps, if (caps_changed) { gst_vaapipostproc_destroy(postproc); - gst_caps_replace(&postproc->sinkpad_caps, caps); - gst_caps_replace(&postproc->srcpad_caps, out_caps); + if (!gst_vaapi_plugin_base_set_caps(GST_VAAPI_PLUGIN_BASE(trans), + caps, out_caps)) + return FALSE; if (!gst_vaapipostproc_create(postproc)) return FALSE; } diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 55dabae82a..fe04947852 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -148,14 +148,12 @@ struct _GstVaapiPostproc { guint flags; GstCaps *allowed_sinkpad_caps; - GstCaps *sinkpad_caps; GstVideoInfo sinkpad_info; #if GST_CHECK_VERSION(1,0,0) GstBufferPool *sinkpad_buffer_pool; #endif guint sinkpad_buffer_size; GstCaps *allowed_srcpad_caps; - GstCaps *srcpad_caps; GstVideoInfo srcpad_info; /* Deinterlacing */ diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 2f081dff2c..e219753a27 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -743,6 +743,7 @@ gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter) static gboolean gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(base_sink); GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstVideoInfo * const vip = &sink->video_info; GstVaapiDisplay *display; @@ -757,6 +758,9 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return TRUE; #endif + if (!gst_vaapi_plugin_base_set_caps(plugin, caps, NULL)) + return FALSE; + if (!gst_vaapisink_ensure_video_buffer_pool(sink, caps)) return FALSE; diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c index d4b52b7f25..e90ef3034d 100644 --- a/gst/vaapi/gstvaapiupload.c +++ b/gst/vaapi/gstvaapiupload.c @@ -320,8 +320,11 @@ gst_vaapiupload_set_caps( GstCaps *outcaps ) { + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(trans); GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); + if (!gst_vaapi_plugin_base_set_caps(plugin, incaps, outcaps)) + return FALSE; if (!gst_vaapi_uploader_ensure_caps(upload->uploader, incaps, outcaps)) return FALSE; return TRUE; From e3dcd33114f260b5c88b3bd425529201a4b3755a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 17 Dec 2013 18:52:23 +0100 Subject: [PATCH 1469/3781] plugins: factor out support for raw YUV buffers on sink pads. Factor out propose_allocation() hooks, creation of video buffer pool for the sink pad, conversion from raw YUV buffers to VA surface backed buffers. Update vaapidecode, vaapiencode and vaapipostproc to cope with the new GstVaapiPluginBase abilities. --- gst/vaapi/gstvaapiencode.c | 258 ++----------------------- gst/vaapi/gstvaapiencode.h | 8 - gst/vaapi/gstvaapipluginbase.c | 331 +++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginbase.h | 34 ++++ gst/vaapi/gstvaapipostproc.c | 252 +------------------------ gst/vaapi/gstvaapipostproc.h | 6 - gst/vaapi/gstvaapisink.c | 286 ++-------------------------- gst/vaapi/gstvaapisink.h | 3 - 8 files changed, 402 insertions(+), 776 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 87fadc09f5..d1afc44247 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -61,33 +61,10 @@ ensure_display (GstVaapiEncode * encode) static gboolean ensure_uploader (GstVaapiEncode * encode) { -#if !GST_CHECK_VERSION(1,0,0) if (!ensure_display (encode)) return FALSE; - - if (!encode->uploader) { - encode->uploader = gst_vaapi_uploader_new ( - GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); - if (!encode->uploader) - return FALSE; - } - - if (!gst_vaapi_uploader_ensure_display (encode->uploader, - GST_VAAPI_PLUGIN_BASE_DISPLAY (encode))) + if (!gst_vaapi_plugin_base_ensure_uploader (GST_VAAPI_PLUGIN_BASE (encode))) return FALSE; -#endif - return TRUE; -} - -static gboolean -ensure_uploader_caps (GstVaapiEncode * encode) -{ -#if !GST_CHECK_VERSION(1,0,0) - if (GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info) && - !gst_vaapi_uploader_ensure_caps (encode->uploader, encode->sinkpad_caps, - NULL)) - return FALSE; -#endif return TRUE; } @@ -283,7 +260,7 @@ gst_vaapiencode_get_caps_impl (GstVideoEncoder * venc) caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS); if (caps && ensure_uploader (encode)) { - GstCaps *const yuv_caps = gst_vaapi_uploader_get_caps (encode->uploader); + GstCaps *const yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS (encode); if (yuv_caps) { caps = gst_caps_make_writable (caps); gst_caps_append (caps, gst_caps_copy (yuv_caps)); @@ -316,10 +293,6 @@ static gboolean gst_vaapiencode_destroy (GstVaapiEncode * encode) { gst_vaapi_encoder_replace (&encode->encoder, NULL); -#if GST_CHECK_VERSION(1,0,0) - g_clear_object (&encode->video_buffer_pool); -#endif - g_clear_object (&encode->uploader); gst_caps_replace (&encode->sinkpad_caps, NULL); gst_caps_replace (&encode->srcpad_caps, NULL); return TRUE; @@ -332,12 +305,8 @@ ensure_encoder (GstVaapiEncode * encode) g_return_val_if_fail (klass->create_encoder, FALSE); - if (!ensure_display (encode)) - return FALSE; if (!ensure_uploader (encode)) return FALSE; - if (!ensure_uploader_caps (encode)) - return FALSE; encode->encoder = klass->create_encoder (encode, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); @@ -378,18 +347,6 @@ gst_vaapiencode_update_sink_caps (GstVaapiEncode * encode, GstVideoCodecState * state) { gst_caps_replace (&encode->sinkpad_caps, state->caps); - encode->sink_video_info = state->info; - -#if !GST_CHECK_VERSION(1,0,0) - if (GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) { - /* Ensure the uploader is set up for upstream allocated buffers */ - GstVaapiUploader *const uploader = encode->uploader; - if (!gst_vaapi_uploader_ensure_display (uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode))) - return FALSE; - if (!gst_vaapi_uploader_ensure_caps (uploader, state->caps, NULL)) - return FALSE; - } -#endif return TRUE; } @@ -450,72 +407,6 @@ gst_vaapiencode_update_src_caps (GstVaapiEncode * encode, return TRUE; } -static gboolean -gst_vaapiencode_ensure_video_buffer_pool (GstVaapiEncode * encode, - GstCaps * caps) -{ -#if GST_CHECK_VERSION(1,0,0) - GstBufferPool *pool; - GstCaps *pool_caps; - GstStructure *config; - GstVideoInfo vi; - gboolean need_pool; - - if (!ensure_display (encode)) - return FALSE; - - if (encode->video_buffer_pool) { - config = gst_buffer_pool_get_config (encode->video_buffer_pool); - gst_buffer_pool_config_get_params (config, &pool_caps, NULL, NULL, NULL); - need_pool = !gst_caps_is_equal (caps, pool_caps); - gst_structure_free (config); - if (!need_pool) - return TRUE; - g_clear_object (&encode->video_buffer_pool); - encode->video_buffer_size = 0; - } - - pool = gst_vaapi_video_buffer_pool_new (GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); - if (!pool) - goto error_create_pool; - - gst_video_info_init (&vi); - gst_video_info_from_caps (&vi, caps); - if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) { - GST_DEBUG ("assume video buffer pool format is NV12"); - gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, - GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); - } - encode->video_buffer_size = vi.size; - - config = gst_buffer_pool_get_config (pool); - gst_buffer_pool_config_set_params (config, caps, encode->video_buffer_size, - 0, 0); - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); - if (!gst_buffer_pool_set_config (pool, config)) - goto error_pool_config; - encode->video_buffer_pool = pool; - return TRUE; - - /* ERRORS */ -error_create_pool: - { - GST_ERROR ("failed to create buffer pool"); - return FALSE; - } -error_pool_config: - { - GST_ERROR ("failed to reset buffer pool config"); - gst_object_unref (pool); - return FALSE; - } -#else - return TRUE; -#endif -} - static gboolean gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) { @@ -523,9 +414,6 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) g_return_val_if_fail (state->caps != NULL, FALSE); - if (!gst_vaapiencode_ensure_video_buffer_pool (encode, state->caps)) - return FALSE; - if (!ensure_encoder (encode)) return FALSE; if (!gst_vaapiencode_update_sink_caps (encode, state)) @@ -533,6 +421,10 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) if (!gst_vaapiencode_update_src_caps (encode, state)) return FALSE; + if (!gst_vaapi_plugin_base_set_caps (GST_VAAPI_PLUGIN_BASE (encode), + encode->sinkpad_caps, encode->srcpad_caps)) + return FALSE; + #if GST_CHECK_VERSION(1,0,0) if (encode->out_caps_done && !gst_video_encoder_negotiate (venc)) { GST_ERROR ("failed to negotiate with caps %" GST_PTR_FORMAT, @@ -557,114 +449,6 @@ gst_vaapiencode_reset (GstVideoEncoder * venc, gboolean hard) return TRUE; } -static GstFlowReturn -get_source_buffer (GstVaapiEncode * encode, GstBuffer * src_buffer, - GstBuffer ** out_buffer_ptr) -{ - GstVaapiVideoMeta *meta; - GstBuffer *out_buffer; -#if GST_CHECK_VERSION(1,0,0) - GstVideoFrame src_frame, out_frame; - gboolean success; -#endif - - meta = gst_buffer_get_vaapi_video_meta (src_buffer); - if (meta) { - *out_buffer_ptr = gst_buffer_ref (src_buffer); - return GST_FLOW_OK; - } - -#if GST_CHECK_VERSION(1,0,0) - if (!GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) - goto error_invalid_buffer; - - if (!encode->video_buffer_pool) - goto error_no_pool; - - if (!gst_buffer_pool_set_active (encode->video_buffer_pool, TRUE)) - goto error_activate_pool; - - out_buffer = NULL; - success = gst_buffer_pool_acquire_buffer (encode->video_buffer_pool, - &out_buffer, NULL) == GST_FLOW_OK; - if (!success) - goto error_create_buffer; - - if (!gst_video_frame_map (&src_frame, &encode->sink_video_info, src_buffer, - GST_MAP_READ)) - goto error_map_src_buffer; - - if (!gst_video_frame_map (&out_frame, &encode->sink_video_info, out_buffer, - GST_MAP_WRITE)) - goto error_map_dst_buffer; - - success = gst_video_frame_copy (&out_frame, &src_frame); - gst_video_frame_unmap (&out_frame); - gst_video_frame_unmap (&src_frame); - if (!success) - goto error_copy_buffer; - - gst_buffer_copy_into (out_buffer, src_buffer, GST_BUFFER_COPY_TIMESTAMPS, 0, - -1); - - *out_buffer_ptr = out_buffer; - return GST_FLOW_OK; - - /* ERRORS */ -error_invalid_buffer: - { - GST_ERROR ("unsupported video buffer"); - return GST_FLOW_EOS; - } -error_no_pool: - { - GST_ERROR ("no buffer pool was negotiated"); - return GST_FLOW_ERROR; - } -error_activate_pool: - { - GST_ERROR ("failed to activate buffer pool"); - return GST_FLOW_ERROR; - } -error_map_dst_buffer: - { - gst_video_frame_unmap (&src_frame); - // fall-through - } -error_map_src_buffer: - { - GST_WARNING ("failed to map buffer. Skipping this frame"); - gst_buffer_unref (out_buffer); - return GST_FLOW_OK; - } -#else - out_buffer = gst_vaapi_uploader_get_buffer (encode->uploader); - if (!out_buffer) - goto error_create_buffer; - if (!gst_vaapi_uploader_process (encode->uploader, src_buffer, out_buffer)) - goto error_copy_buffer; - - gst_buffer_copy_metadata (out_buffer, src_buffer, - GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); - - *out_buffer_ptr = out_buffer; - return GST_FLOW_OK; -#endif - - /* ERRORS */ -error_create_buffer: - { - GST_WARNING ("failed to create buffer. Skipping this frame"); - return GST_FLOW_OK; - } -error_copy_buffer: - { - GST_WARNING ("failed to upload buffer to VA surface. Skipping this frame"); - gst_buffer_unref (out_buffer); - return GST_FLOW_OK; - } -} - static GstFlowReturn gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GstVideoCodecFrame * frame) @@ -677,7 +461,8 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GstBuffer *buf; buf = NULL; - ret = get_source_buffer (encode, frame->input_buffer, &buf); + ret = gst_vaapi_plugin_base_get_input_buffer (GST_VAAPI_PLUGIN_BASE (encode), + frame->input_buffer, &buf); if (ret != GST_FLOW_OK) goto error_buffer_invalid; @@ -759,31 +544,11 @@ gst_vaapiencode_finish (GstVideoEncoder * venc) static gboolean gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query) { - GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); - GstCaps *caps = NULL; - gboolean need_pool; + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (venc); - gst_query_parse_allocation (query, &caps, &need_pool); - - if (need_pool) { - if (!caps) - goto error_no_caps; - if (!gst_vaapiencode_ensure_video_buffer_pool (encode, caps)) - return FALSE; - gst_query_add_allocation_pool (query, encode->video_buffer_pool, - encode->video_buffer_size, 0, 0); - } - - gst_query_add_allocation_meta (query, GST_VAAPI_VIDEO_META_API_TYPE, NULL); - gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); - return TRUE; - - /* ERRORS */ -error_no_caps: - { - GST_ERROR ("no caps specified"); + if (!gst_vaapi_plugin_base_propose_allocation (plugin, query)) return FALSE; - } + return TRUE; } #endif @@ -864,7 +629,6 @@ gst_vaapiencode_init (GstVaapiEncode * encode) encode->sinkpad = GST_VIDEO_ENCODER_SINK_PAD (encode); encode->sinkpad_query = GST_PAD_QUERYFUNC (encode->sinkpad); gst_pad_set_query_function (encode->sinkpad, gst_vaapiencode_query); - gst_video_info_init (&encode->sink_video_info); /* src pad */ encode->srcpad = GST_VIDEO_ENCODER_SRC_PAD (encode); diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 1bf0dbc9cc..401913ffb5 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -24,7 +24,6 @@ #include "gstvaapipluginbase.h" #include -#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -54,19 +53,12 @@ struct _GstVaapiEncode GstPad *sinkpad; GstCaps *sinkpad_caps; GstPadQueryFunction sinkpad_query; - GstVideoInfo sink_video_info; GstPad *srcpad; GstCaps *srcpad_caps; GstPadQueryFunction srcpad_query; GstVaapiEncoder *encoder; - GstVaapiUploader *uploader; - -#if GST_CHECK_VERSION(1,0,0) - GstBufferPool *video_buffer_pool; -#endif - guint video_buffer_size; GstVaapiRateControl rate_control; guint32 bitrate; /* kbps */ diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 733921037c..e1ff7400d2 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -26,6 +26,10 @@ #include "gstvaapipluginbase.h" #include "gstvaapipluginutil.h" #include "gstvaapivideocontext.h" +#include "gstvaapivideometa.h" +#if GST_CHECK_VERSION(1,0,0) +#include "gstvaapivideobufferpool.h" +#endif /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) @@ -174,11 +178,18 @@ gst_vaapi_plugin_base_open (GstVaapiPluginBase * plugin) void gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) { + g_clear_object (&plugin->uploader); gst_vaapi_display_replace (&plugin->display, NULL); gst_caps_replace (&plugin->sinkpad_caps, NULL); plugin->sinkpad_caps_changed = FALSE; gst_video_info_init (&plugin->sinkpad_info); +#if GST_CHECK_VERSION(1,0,0) + if (plugin->sinkpad_buffer_pool) { + gst_object_unref (plugin->sinkpad_buffer_pool); + plugin->sinkpad_buffer_pool = NULL; + } +#endif gst_caps_replace (&plugin->srcpad_caps, NULL); plugin->srcpad_caps_changed = FALSE; @@ -227,6 +238,104 @@ gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) return TRUE; } +/** + * gst_vaapi_plugin_base_ensure_uploader: + * @plugin: a #GstVaapiPluginBase + * + * Makes sure the built-in #GstVaapiUploader object is created, or + * that it was successfully notified of any VA display change. + * + * Returns: %TRUE if the uploader was successfully created, %FALSE otherwise. + */ +gboolean +gst_vaapi_plugin_base_ensure_uploader (GstVaapiPluginBase * plugin) +{ + if (plugin->uploader) { + if (!gst_vaapi_uploader_ensure_display (plugin->uploader, plugin->display)) + return FALSE; + } else { + plugin->uploader = gst_vaapi_uploader_new (plugin->display); + if (!plugin->uploader) + return FALSE; + } + return TRUE; +} + +/** + * ensure_sinkpad_buffer_pool: + * @plugin: a #GstVaapiPluginBase + * @caps: the initial #GstCaps for the resulting buffer pool + * + * Makes sure the sink pad video buffer pool is created with the + * appropriate @caps. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +static gboolean +ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) +{ +#if GST_CHECK_VERSION(1,0,0) + GstBufferPool *pool; + GstCaps *pool_caps; + GstStructure *config; + GstVideoInfo vi; + gboolean need_pool; + + if (!gst_vaapi_plugin_base_ensure_display (plugin)) + return FALSE; + + if (plugin->sinkpad_buffer_pool) { + config = gst_buffer_pool_get_config (plugin->sinkpad_buffer_pool); + gst_buffer_pool_config_get_params (config, &pool_caps, NULL, NULL, NULL); + need_pool = !gst_caps_is_equal (caps, pool_caps); + gst_structure_free (config); + if (!need_pool) + return TRUE; + g_clear_object (&plugin->sinkpad_buffer_pool); + plugin->sinkpad_buffer_size = 0; + } + + pool = gst_vaapi_video_buffer_pool_new (plugin->display); + if (!pool) + goto error_create_pool; + + gst_video_info_init (&vi); + gst_video_info_from_caps (&vi, caps); + if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) { + GST_DEBUG ("assume video buffer pool format is NV12"); + gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); + } + plugin->sinkpad_buffer_size = vi.size; + + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set_params (config, caps, + plugin->sinkpad_buffer_size, 0, 0); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); + gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); + if (!gst_buffer_pool_set_config (pool, config)) + goto error_pool_config; + plugin->sinkpad_buffer_pool = pool; + return TRUE; + + /* ERRORS */ +error_create_pool: + { + GST_ERROR ("failed to create buffer pool"); + return FALSE; + } +error_pool_config: + { + GST_ERROR ("failed to reset buffer pool config"); + gst_object_unref (pool); + return FALSE; + } +#else + return TRUE; +#endif +} + /** * gst_vaapi_plugin_base_set_caps: * @plugin: a #GstVaapiPluginBase @@ -255,5 +364,227 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, return FALSE; plugin->srcpad_caps_changed = TRUE; } + + if (plugin->uploader && GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) { + if (!gst_vaapi_uploader_ensure_display (plugin->uploader, plugin->display)) + return FALSE; + if (!gst_vaapi_uploader_ensure_caps (plugin->uploader, + plugin->sinkpad_caps, plugin->srcpad_caps)) + return FALSE; + } + + if (!ensure_sinkpad_buffer_pool (plugin, plugin->sinkpad_caps)) + return FALSE; return TRUE; } + +/** + * gst_vaapi_plugin_base_propose_allocation: + * @plugin: a #GstVaapiPluginBase + * @query: the allocation query to configure + * + * Proposes allocation parameters to the upstream elements. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +#if GST_CHECK_VERSION(1,0,0) +gboolean +gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, + GstQuery * query) +{ + GstCaps *caps = NULL; + gboolean need_pool; + + gst_query_parse_allocation (query, &caps, &need_pool); + + if (need_pool) { + if (!caps) + goto error_no_caps; + if (!ensure_sinkpad_buffer_pool (plugin, caps)) + return FALSE; + gst_query_add_allocation_pool (query, plugin->sinkpad_buffer_pool, + plugin->sinkpad_buffer_size, 0, 0); + } + + gst_query_add_allocation_meta (query, GST_VAAPI_VIDEO_META_API_TYPE, NULL); + gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); + return TRUE; + + /* ERRORS */ +error_no_caps: + { + GST_ERROR ("no caps specified"); + return FALSE; + } +} +#endif + +/** + * gst_vaapi_plugin_base_allocate_input_buffer: + * @plugin: a #GstVaapiPluginBase + * @caps: the buffer caps constraints to honour + * @outbuf_ptr: the pointer location to the newly allocated buffer + * + * Creates a buffer that holds a VA surface memory for the sink pad to + * use it as the result for buffer_alloc() impementations. + * + * Return: #GST_FLOW_OK if the buffer could be created. + */ +GstFlowReturn +gst_vaapi_plugin_base_allocate_input_buffer (GstVaapiPluginBase * plugin, + GstCaps * caps, GstBuffer ** outbuf_ptr) +{ + GstBuffer *outbuf; + + *outbuf_ptr = NULL; + + if (!plugin->sinkpad_caps_changed) { + if (!gst_video_info_from_caps (&plugin->sinkpad_info, caps)) + return GST_FLOW_NOT_SUPPORTED; + plugin->sinkpad_caps_changed = TRUE; + } + + if (!GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) + return GST_FLOW_OK; + + if (!gst_vaapi_uploader_ensure_display (plugin->uploader, plugin->display)) + return GST_FLOW_NOT_SUPPORTED; + if (!gst_vaapi_uploader_ensure_caps (plugin->uploader, caps, NULL)) + return GST_FLOW_NOT_SUPPORTED; + + outbuf = gst_vaapi_uploader_get_buffer (plugin->uploader); + if (!outbuf) { + GST_WARNING ("failed to allocate resources for raw YUV buffer"); + return GST_FLOW_NOT_SUPPORTED; + } + + *outbuf_ptr = outbuf; + return GST_FLOW_OK; +} + +/** + * gst_vaapi_plugin_base_get_input_buffer: + * @plugin: a #GstVaapiPluginBase + * @incaps: the sink pad (input) buffer + * @outbuf_ptr: the pointer to location to the VA surface backed buffer + * + * Acquires the sink pad (input) buffer as a VA surface backed + * buffer. This is mostly useful for raw YUV buffers, as source + * buffers that are already backed as a VA surface are passed + * verbatim. + * + * Returns: #GST_FLOW_OK if the buffer could be acquired + */ +GstFlowReturn +gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, + GstBuffer * inbuf, GstBuffer ** outbuf_ptr) +{ + GstVaapiVideoMeta *meta; + GstBuffer *outbuf; +#if GST_CHECK_VERSION(1,0,0) + GstVideoFrame src_frame, out_frame; + gboolean success; +#endif + + g_return_val_if_fail (inbuf != NULL, GST_FLOW_ERROR); + g_return_val_if_fail (outbuf_ptr != NULL, GST_FLOW_ERROR); + + meta = gst_buffer_get_vaapi_video_meta (inbuf); +#if GST_CHECK_VERSION(1,0,0) + if (meta) { + *outbuf_ptr = gst_buffer_ref (inbuf); + return GST_FLOW_OK; + } + + if (!GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) + goto error_invalid_buffer; + + if (!plugin->sinkpad_buffer_pool) + goto error_no_pool; + + if (!gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, TRUE)) + goto error_active_pool; + + outbuf = NULL; + if (gst_buffer_pool_acquire_buffer (plugin->sinkpad_buffer_pool, + &outbuf, NULL) != GST_FLOW_OK) + goto error_create_buffer; + + if (!gst_video_frame_map (&src_frame, &plugin->sinkpad_info, inbuf, + GST_MAP_READ)) + goto error_map_src_buffer; + + if (!gst_video_frame_map (&out_frame, &plugin->sinkpad_info, outbuf, + GST_MAP_WRITE)) + goto error_map_dst_buffer; + + success = gst_video_frame_copy (&out_frame, &src_frame); + gst_video_frame_unmap (&out_frame); + gst_video_frame_unmap (&src_frame); + if (!success) + goto error_copy_buffer; + + gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); + *outbuf_ptr = outbuf; + return GST_FLOW_OK; + + /* ERRORS */ +error_no_pool: + { + GST_ERROR ("no buffer pool was negotiated"); + return GST_FLOW_ERROR; + } +error_active_pool: + { + GST_ERROR ("failed to activate buffer pool"); + return GST_FLOW_ERROR; + } +error_map_dst_buffer: + { + gst_video_frame_unmap (&src_frame); + // fall-through + } +error_map_src_buffer: + { + GST_WARNING ("failed to map buffer"); + gst_buffer_unref (outbuf); + return GST_FLOW_NOT_SUPPORTED; + } +#else + if (meta) + outbuf = gst_buffer_ref (inbuf); + else if (GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) { + outbuf = gst_vaapi_uploader_get_buffer (plugin->uploader); + if (!outbuf) + goto error_create_buffer; + gst_buffer_copy_metadata (outbuf, inbuf, + GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); + } else + goto error_invalid_buffer; + + if (GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info) && + !gst_vaapi_uploader_process (plugin->uploader, inbuf, outbuf)) + goto error_copy_buffer; + + *outbuf_ptr = outbuf; + return GST_FLOW_OK; +#endif + + /* ERRORS */ +error_invalid_buffer: + { + GST_ERROR ("failed to validate source buffer"); + return GST_FLOW_ERROR; + } +error_create_buffer: + { + GST_ERROR ("failed to create buffer"); + return GST_FLOW_ERROR; + } +error_copy_buffer: + { + GST_WARNING ("failed to upload buffer to VA surface"); + gst_buffer_unref (outbuf); + return GST_FLOW_NOT_SUPPORTED; + } +} diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 68ed6c83f6..6c8abcf658 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -30,6 +30,7 @@ #include #include #include +#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -96,6 +97,13 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (gst_vaapi_display_replace(&GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin), \ (new_display))) +#define GST_VAAPI_PLUGIN_BASE_UPLOADER(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->uploader) +#define GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(plugin) \ + (gst_vaapi_uploader_get_caps(GST_VAAPI_PLUGIN_BASE_UPLOADER(plugin))) +#define GST_VAAPI_PLUGIN_BASE_UPLOADER_USED(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->uploader_used) + struct _GstVaapiPluginBase { /*< private >*/ @@ -115,6 +123,10 @@ struct _GstVaapiPluginBase gboolean sinkpad_caps_changed; GstVideoInfo sinkpad_info; GstPadQueryFunction sinkpad_query; +#if GST_CHECK_VERSION(1,0,0) + GstBufferPool *sinkpad_buffer_pool; + guint sinkpad_buffer_size; +#endif GstPad *srcpad; GstCaps *srcpad_caps; @@ -125,6 +137,9 @@ struct _GstVaapiPluginBase GstVaapiDisplay *display; GstVaapiDisplayType display_type; GstVaapiDisplayType display_type_req; + + GstVaapiUploader *uploader; + gboolean uploader_used; }; struct _GstVaapiPluginBaseClass @@ -177,11 +192,30 @@ G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_ensure_uploader (GstVaapiPluginBase * plugin); + G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, GstCaps * outcaps); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, + GstQuery * query); + +G_GNUC_INTERNAL +GstFlowReturn +gst_vaapi_plugin_base_allocate_input_buffer (GstVaapiPluginBase * plugin, + GstCaps * caps, GstBuffer ** outbuf_ptr); + +G_GNUC_INTERNAL +GstFlowReturn +gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, + GstBuffer * inbuf, GstBuffer ** outbuf_ptr); + G_END_DECLS #endif /* GST_VAAPI_PLUGIN_BASE_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index fb61a0c55a..58fff7a172 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -212,32 +212,11 @@ gst_vaapipostproc_ensure_uploader(GstVaapiPostproc *postproc) { if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; - - if (!postproc->uploader) { - postproc->uploader = gst_vaapi_uploader_new( - GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); - if (!postproc->uploader) - return FALSE; - } - - if (!gst_vaapi_uploader_ensure_display(postproc->uploader, - GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc))) + if (!gst_vaapi_plugin_base_ensure_uploader(GST_VAAPI_PLUGIN_BASE(postproc))) return FALSE; return TRUE; } -static gboolean -gst_vaapipostproc_ensure_uploader_caps(GstVaapiPostproc *postproc) -{ -#if !GST_CHECK_VERSION(1,0,0) - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(postproc); - if (postproc->is_raw_yuv && !gst_vaapi_uploader_ensure_caps( - postproc->uploader, plugin->sinkpad_caps, NULL)) - return FALSE; -#endif - return TRUE; -} - static gboolean gst_vaapipostproc_ensure_filter(GstVaapiPostproc *postproc) { @@ -279,8 +258,6 @@ gst_vaapipostproc_create(GstVaapiPostproc *postproc) return FALSE; if (!gst_vaapipostproc_ensure_uploader(postproc)) return FALSE; - if (!gst_vaapipostproc_ensure_uploader_caps(postproc)) - return FALSE; if (gst_vaapipostproc_ensure_filter(postproc)) postproc->use_vpp = TRUE; return TRUE; @@ -306,10 +283,6 @@ static void gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) { ds_reset(&postproc->deinterlace_state); -#if GST_CHECK_VERSION(1,0,0) - g_clear_object(&postproc->sinkpad_buffer_pool); -#endif - g_clear_object(&postproc->uploader); gst_vaapipostproc_destroy_filter(postproc); gst_caps_replace(&postproc->allowed_sinkpad_caps, NULL); @@ -791,16 +764,6 @@ gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps, (1 + deinterlace) * GST_VIDEO_INFO_FPS_N(&vi)); postproc->is_raw_yuv = GST_VIDEO_INFO_IS_YUV(&vi); -#if !GST_CHECK_VERSION(1,0,0) - if (postproc->is_raw_yuv) { - /* Ensure the uploader is set up for upstream allocated buffers */ - GstVaapiUploader * const uploader = postproc->uploader; - if (!gst_vaapi_uploader_ensure_display(uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc))) - return FALSE; - if (!gst_vaapi_uploader_ensure_caps(uploader, caps, NULL)) - return FALSE; - } -#endif return TRUE; } @@ -849,7 +812,7 @@ ensure_allowed_sinkpad_caps(GstVaapiPostproc *postproc) /* Append YUV caps */ if (gst_vaapipostproc_ensure_uploader(postproc)) { - yuv_caps = gst_vaapi_uploader_get_caps(postproc->uploader); + yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(postproc); if (yuv_caps) { out_caps = gst_caps_make_writable(out_caps); gst_caps_append(out_caps, gst_caps_copy(yuv_caps)); @@ -1117,107 +1080,6 @@ gst_vaapipostproc_transform_size(GstBaseTransform *trans, return TRUE; } -static GstBuffer * -get_source_buffer(GstVaapiPostproc *postproc, GstBuffer *inbuf) -{ - GstVaapiVideoMeta *meta; - GstBuffer *outbuf; -#if GST_CHECK_VERSION(1,0,0) - GstVideoFrame src_frame, out_frame; -#endif - - meta = gst_buffer_get_vaapi_video_meta(inbuf); - if (meta) - return gst_buffer_ref(inbuf); - -#if GST_CHECK_VERSION(1,0,0) - if (!postproc->is_raw_yuv) - goto error_invalid_buffer; - - if (!postproc->sinkpad_buffer_pool) - goto error_no_pool; - - if (!gst_buffer_pool_set_active(postproc->sinkpad_buffer_pool, TRUE)) - goto error_active_pool; - - outbuf = NULL; - if (gst_buffer_pool_acquire_buffer(postproc->sinkpad_buffer_pool, - &outbuf, NULL) != GST_FLOW_OK) - goto error_create_buffer; - - if (!gst_video_frame_map(&src_frame, &postproc->sinkpad_info, inbuf, - GST_MAP_READ)) - goto error_map_src_buffer; - - if (!gst_video_frame_map(&out_frame, &postproc->sinkpad_info, outbuf, - GST_MAP_WRITE)) - goto error_map_dst_buffer; - - if (!gst_video_frame_copy(&out_frame, &src_frame)) - goto error_copy_buffer; - - gst_video_frame_unmap(&out_frame); - gst_video_frame_unmap(&src_frame); - gst_buffer_copy_into(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); - return outbuf; - - /* ERRORS */ -error_invalid_buffer: - { - GST_ERROR("failed to validate source buffer"); - return NULL; - } -error_no_pool: - { - GST_ERROR("no buffer pool was negotiated"); - return NULL; - } -error_active_pool: - { - GST_ERROR("failed to activate buffer pool"); - return NULL; - } -error_map_dst_buffer: - { - gst_video_frame_unmap(&src_frame); - // fall-through - } -error_map_src_buffer: - { - GST_ERROR("failed to map buffer"); - gst_buffer_unref(outbuf); - return NULL; - } -#else - outbuf = gst_vaapi_uploader_get_buffer(postproc->uploader); - if (!outbuf) - goto error_create_buffer; - if (!gst_vaapi_uploader_process(postproc->uploader, inbuf, outbuf)) - goto error_copy_buffer; - - gst_buffer_copy_metadata(outbuf, inbuf, - GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); - return outbuf; -#endif - - /* ERRORS */ -error_create_buffer: - { - GST_ERROR("failed to create buffer"); - return NULL; - } -error_copy_buffer: - { - GST_ERROR("failed to upload buffer to VA surface"); -#if GST_CHECK_VERSION(1,0,0) - gst_video_frame_unmap(&out_frame); - gst_video_frame_unmap(&src_frame); -#endif - gst_buffer_unref(outbuf); - return NULL; - } -} - static GstFlowReturn gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf) @@ -1226,8 +1088,9 @@ gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *buf; GstFlowReturn ret; - buf = get_source_buffer(postproc, inbuf); - if (!buf) + ret = gst_vaapi_plugin_base_get_input_buffer( + GST_VAAPI_PLUGIN_BASE(postproc), inbuf, &buf); + if (ret != GST_FLOW_OK) return GST_FLOW_ERROR; ret = GST_FLOW_NOT_SUPPORTED; @@ -1272,73 +1135,6 @@ gst_vaapipostproc_prepare_output_buffer(GstBaseTransform *trans, return *outbuf_ptr ? GST_FLOW_OK : GST_FLOW_ERROR; } -static gboolean -ensure_sinkpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps) -{ -#if GST_CHECK_VERSION(1,0,0) - GstBufferPool *pool; - GstCaps *pool_caps; - GstStructure *config; - GstVideoInfo vi; - gboolean need_pool; - - if (!gst_vaapipostproc_ensure_display(postproc)) - return FALSE; - - if (postproc->sinkpad_buffer_pool) { - config = gst_buffer_pool_get_config(postproc->sinkpad_buffer_pool); - gst_buffer_pool_config_get_params(config, &pool_caps, NULL, NULL, NULL); - need_pool = !gst_caps_is_equal(caps, pool_caps); - gst_structure_free(config); - if (!need_pool) - return TRUE; - g_clear_object(&postproc->sinkpad_buffer_pool); - postproc->sinkpad_buffer_size = 0; - } - - pool = gst_vaapi_video_buffer_pool_new( - GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); - if (!pool) - goto error_create_pool; - - gst_video_info_init(&vi); - gst_video_info_from_caps(&vi, caps); - if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) { - GST_DEBUG("assume sink pad buffer pool format is NV12"); - gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12, - GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); - } - postproc->sinkpad_buffer_size = vi.size; - - config = gst_buffer_pool_get_config(pool); - gst_buffer_pool_config_set_params(config, caps, - postproc->sinkpad_buffer_size, 0, 0); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_META); - if (!gst_buffer_pool_set_config(pool, config)) - goto error_pool_config; - postproc->sinkpad_buffer_pool = pool; - return TRUE; - - /* ERRORS */ -error_create_pool: - { - GST_ERROR("failed to create buffer pool"); - return FALSE; - } -error_pool_config: - { - GST_ERROR("failed to reset buffer pool config"); - gst_object_unref(pool); - return FALSE; - } -#else - return TRUE; -#endif -} - static gboolean ensure_srcpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps) { @@ -1378,15 +1174,13 @@ gst_vaapipostproc_set_caps(GstBaseTransform *trans, GstCaps *caps, if (caps_changed) { gst_vaapipostproc_destroy(postproc); + if (!gst_vaapipostproc_create(postproc)) + return FALSE; if (!gst_vaapi_plugin_base_set_caps(GST_VAAPI_PLUGIN_BASE(trans), caps, out_caps)) return FALSE; - if (!gst_vaapipostproc_create(postproc)) - return FALSE; } - if (!ensure_sinkpad_buffer_pool(postproc, caps)) - return FALSE; if (!ensure_srcpad_buffer_pool(postproc, out_caps)) return FALSE; return TRUE; @@ -1415,40 +1209,14 @@ gst_vaapipostproc_propose_allocation(GstBaseTransform *trans, GstQuery *decide_query, GstQuery *query) { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); - GstCaps *caps = NULL; - gboolean need_pool; + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(trans); /* Let vaapidecode allocate the video buffers */ if (!postproc->is_raw_yuv) return FALSE; - - gst_query_parse_allocation(query, &caps, &need_pool); - - if (need_pool) { - if (!caps) - goto error_no_caps; - if (!ensure_sinkpad_buffer_pool(postproc, caps)) - return FALSE; - gst_query_add_allocation_pool(query, postproc->sinkpad_buffer_pool, - postproc->sinkpad_buffer_size, 0, 0); - } - - gst_query_add_allocation_meta(query, - GST_VAAPI_VIDEO_META_API_TYPE, NULL); - gst_query_add_allocation_meta(query, - GST_VIDEO_META_API_TYPE, NULL); - gst_query_add_allocation_meta(query, - GST_VIDEO_CROP_META_API_TYPE, NULL); - gst_query_add_allocation_meta(query, - GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL); - return TRUE; - - /* ERRORS */ -error_no_caps: - { - GST_ERROR("no caps specified"); + if (!gst_vaapi_plugin_base_propose_allocation(plugin, query)) return FALSE; - } + return TRUE; } #endif diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index fe04947852..93b4495d4d 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -27,7 +27,6 @@ #include #include #include -#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -136,7 +135,6 @@ struct _GstVaapiPostproc { /*< private >*/ GstVaapiPluginBase parent_instance; - GstVaapiUploader *uploader; GstVaapiFilter *filter; GPtrArray *filter_ops; GstVaapiVideoPool *filter_pool; @@ -149,10 +147,6 @@ struct _GstVaapiPostproc { GstCaps *allowed_sinkpad_caps; GstVideoInfo sinkpad_info; -#if GST_CHECK_VERSION(1,0,0) - GstBufferPool *sinkpad_buffer_pool; -#endif - guint sinkpad_buffer_size; GstCaps *allowed_srcpad_caps; GstVideoInfo srcpad_info; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index e219753a27..3b7f8d7d25 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -239,10 +239,7 @@ gst_vaapisink_destroy(GstVaapiSink *sink) #if USE_GLX gst_vaapi_texture_replace(&sink->texture, NULL); #endif - g_clear_object(&sink->uploader); - gst_caps_replace(&sink->caps, NULL); - gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(sink)); } #if USE_X11 @@ -341,13 +338,8 @@ gst_vaapisink_ensure_uploader(GstVaapiSink *sink) { if (!gst_vaapisink_ensure_display(sink)) return FALSE; - - if (!sink->uploader) { - sink->uploader = gst_vaapi_uploader_new( - GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - if (!sink->uploader) - return FALSE; - } + if (!gst_vaapi_plugin_base_ensure_uploader(GST_VAAPI_PLUGIN_BASE(sink))) + return FALSE; return TRUE; } @@ -605,72 +597,6 @@ end: return success; } -static gboolean -gst_vaapisink_ensure_video_buffer_pool(GstVaapiSink *sink, GstCaps *caps) -{ -#if GST_CHECK_VERSION(1,0,0) - GstBufferPool *pool; - GstCaps *pool_caps; - GstStructure *config; - GstVideoInfo vi; - gboolean need_pool; - - if (!gst_vaapisink_ensure_display(sink)) - return FALSE; - - if (sink->video_buffer_pool) { - config = gst_buffer_pool_get_config(sink->video_buffer_pool); - gst_buffer_pool_config_get_params(config, &pool_caps, NULL, NULL, NULL); - need_pool = !gst_caps_is_equal(caps, pool_caps); - gst_structure_free(config); - if (!need_pool) - return TRUE; - g_clear_object(&sink->video_buffer_pool); - sink->video_buffer_size = 0; - } - - pool = gst_vaapi_video_buffer_pool_new(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - if (!pool) - goto error_create_pool; - - gst_video_info_init(&vi); - gst_video_info_from_caps(&vi, caps); - if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) { - GST_DEBUG("assume video buffer pool format is NV12"); - gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12, - GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); - } - sink->video_buffer_size = vi.size; - - config = gst_buffer_pool_get_config(pool); - gst_buffer_pool_config_set_params(config, caps, sink->video_buffer_size, - 0, 0); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_META); - if (!gst_buffer_pool_set_config(pool, config)) - goto error_pool_config; - sink->video_buffer_pool = pool; - return TRUE; - - /* ERRORS */ -error_create_pool: - { - GST_ERROR("failed to create buffer pool"); - return FALSE; - } -error_pool_config: - { - GST_ERROR("failed to reset buffer pool config"); - gst_object_unref(pool); - return FALSE; - } -#else - return TRUE; -#endif -} - static gboolean gst_vaapisink_start(GstBaseSink *base_sink) { @@ -691,7 +617,7 @@ gst_vaapisink_stop(GstBaseSink *base_sink) g_clear_object(&sink->video_buffer_pool); #endif gst_vaapi_window_replace(&sink->window, NULL); - g_clear_object(&sink->uploader); + gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(sink)); return TRUE; } @@ -711,7 +637,7 @@ gst_vaapisink_get_caps_impl(GstBaseSink *base_sink) return NULL; if (gst_vaapisink_ensure_uploader(sink)) { - yuv_caps = gst_vaapi_uploader_get_caps(sink->uploader); + yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(sink); if (yuv_caps) { out_caps = gst_caps_make_writable(out_caps); gst_caps_append(out_caps, gst_caps_copy(yuv_caps)); @@ -745,7 +671,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(base_sink); GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstVideoInfo * const vip = &sink->video_info; + GstVideoInfo * const vip = GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO(sink); GstVaapiDisplay *display; guint win_width, win_height; @@ -761,12 +687,6 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) if (!gst_vaapi_plugin_base_set_caps(plugin, caps, NULL)) return FALSE; - if (!gst_vaapisink_ensure_video_buffer_pool(sink, caps)) - return FALSE; - - if (!gst_video_info_from_caps(vip, caps)) - return FALSE; - sink->use_video_raw = GST_VIDEO_INFO_IS_YUV(vip); sink->video_width = GST_VIDEO_INFO_WIDTH(vip); sink->video_height = GST_VIDEO_INFO_HEIGHT(vip); sink->video_par_n = GST_VIDEO_INFO_PAR_N(vip); @@ -776,16 +696,6 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) gst_caps_replace(&sink->caps, caps); -#if !GST_CHECK_VERSION(1,0,0) - if (sink->use_video_raw) { - /* Ensure the uploader is set up for upstream allocated buffers */ - if (!gst_vaapi_uploader_ensure_display(sink->uploader, display)) - return FALSE; - if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL)) - return FALSE; - } -#endif - gst_vaapisink_ensure_rotation(sink, FALSE); gst_vaapisink_ensure_window_size(sink, &win_width, &win_height); @@ -1029,116 +939,6 @@ gst_vaapisink_put_surface( return TRUE; } -#if GST_CHECK_VERSION(1,0,0) -static GstFlowReturn -gst_vaapisink_get_render_buffer(GstVaapiSink *sink, GstBuffer *src_buffer, - GstBuffer **out_buffer_ptr) -{ - GstVaapiVideoMeta *meta; - GstBuffer *out_buffer; - GstBufferPoolAcquireParams params = { 0, }; - GstVideoFrame src_frame, out_frame; - GstFlowReturn ret; - - meta = gst_buffer_get_vaapi_video_meta(src_buffer); - if (meta) { - *out_buffer_ptr = gst_buffer_ref(src_buffer); - return GST_FLOW_OK; - } - - if (!sink->use_video_raw) { - GST_ERROR("unsupported video buffer"); - return GST_FLOW_EOS; - } - - GST_DEBUG("buffer %p not from our pool, copying", src_buffer); - - *out_buffer_ptr = NULL; - if (!sink->video_buffer_pool) - goto error_no_pool; - - if (!gst_buffer_pool_set_active(sink->video_buffer_pool, TRUE)) - goto error_activate_pool; - - params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT; - ret = gst_buffer_pool_acquire_buffer(sink->video_buffer_pool, &out_buffer, - ¶ms); - if (ret != GST_FLOW_OK) - goto error_create_buffer; - - if (!gst_video_frame_map(&src_frame, &sink->video_info, src_buffer, - GST_MAP_READ)) - goto error_map_src_buffer; - - if (!gst_video_frame_map(&out_frame, &sink->video_info, out_buffer, - GST_MAP_WRITE)) - goto error_map_dst_buffer; - - gst_video_frame_copy(&out_frame, &src_frame); - gst_video_frame_unmap(&out_frame); - gst_video_frame_unmap(&src_frame); - - *out_buffer_ptr = out_buffer; - return GST_FLOW_OK; - - /* ERRORS */ -error_no_pool: - GST_ERROR("no buffer pool was negotiated"); - return GST_FLOW_ERROR; -error_activate_pool: - GST_ERROR("failed to activate buffer pool"); - return GST_FLOW_ERROR; -error_create_buffer: - GST_WARNING("failed to create image. Skipping this frame"); - return GST_FLOW_OK; -error_map_dst_buffer: - gst_video_frame_unmap(&src_frame); - // fall-through -error_map_src_buffer: - GST_WARNING("failed to map buffer. Skipping this frame"); - gst_buffer_unref(out_buffer); - return GST_FLOW_OK; -} -#else -static GstFlowReturn -gst_vaapisink_get_render_buffer(GstVaapiSink *sink, GstBuffer *src_buffer, - GstBuffer **out_buffer_ptr) -{ - GstVaapiVideoMeta *meta; - GstBuffer *out_buffer; - - *out_buffer_ptr = NULL; - meta = gst_buffer_get_vaapi_video_meta(src_buffer); - if (meta) - out_buffer = gst_buffer_ref(src_buffer); - else if (sink->use_video_raw) { - out_buffer = gst_vaapi_uploader_get_buffer(sink->uploader); - if (!out_buffer) - goto error_create_buffer; - } - else { - GST_ERROR("unsupported video buffer"); - return GST_FLOW_EOS; - } - - if (sink->use_video_raw && - !gst_vaapi_uploader_process(sink->uploader, src_buffer, out_buffer)) - goto error_copy_buffer; - - *out_buffer_ptr = out_buffer; - return GST_FLOW_OK; - - /* ERRORS */ -error_create_buffer: - GST_WARNING("failed to create buffer. Skipping this frame"); - return GST_FLOW_OK; -error_copy_buffer: - GST_WARNING("failed to copy buffers. Skipping this frame"); - gst_buffer_unref(out_buffer); - return GST_FLOW_OK; -} -#endif - static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) { @@ -1166,8 +966,9 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) } #endif - ret = gst_vaapisink_get_render_buffer(sink, src_buffer, &buffer); - if (ret != GST_FLOW_OK || !buffer) + ret = gst_vaapi_plugin_base_get_input_buffer(GST_VAAPI_PLUGIN_BASE(sink), + src_buffer, &buffer); + if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_SUPPORTED) return ret; meta = gst_buffer_get_vaapi_video_meta(buffer); @@ -1249,78 +1050,23 @@ error: static gboolean gst_vaapisink_propose_allocation(GstBaseSink *base_sink, GstQuery *query) { - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstCaps *caps = NULL; - gboolean need_pool; + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(base_sink); - gst_query_parse_allocation(query, &caps, &need_pool); + if (!gst_vaapi_plugin_base_propose_allocation(plugin, query)) + return FALSE; - if (need_pool) { - if (!caps) - goto error_no_caps; - if (!gst_vaapisink_ensure_video_buffer_pool(sink, caps)) - return FALSE; - gst_query_add_allocation_pool(query, sink->video_buffer_pool, - sink->video_buffer_size, 0, 0); - } - - gst_query_add_allocation_meta(query, - GST_VAAPI_VIDEO_META_API_TYPE, NULL); - gst_query_add_allocation_meta(query, - GST_VIDEO_META_API_TYPE, NULL); - gst_query_add_allocation_meta(query, - GST_VIDEO_CROP_META_API_TYPE, NULL); + gst_query_add_allocation_meta(query, GST_VIDEO_CROP_META_API_TYPE, NULL); gst_query_add_allocation_meta(query, GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL); return TRUE; - - /* ERRORS */ -error_no_caps: - { - GST_ERROR("no caps specified"); - return FALSE; - } } #else static GstFlowReturn -gst_vaapisink_buffer_alloc( - GstBaseSink *base_sink, - guint64 offset, - guint size, - GstCaps *caps, - GstBuffer **pbuf -) +gst_vaapisink_buffer_alloc(GstBaseSink *base_sink, guint64 offset, guint size, + GstCaps *caps, GstBuffer **outbuf_ptr) { - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstVideoInfo vi; - GstBuffer *buf; - - *pbuf = NULL; - - if (!sink->use_video_raw) { - /* Note: this code path is rarely used but for raw YUV formats - from custom pipeline. Otherwise, GstBaseSink::set_caps() is - called first, and GstBaseSink::buffer_alloc() is not called - in VA surface format mode */ - if (!gst_video_info_from_caps(&vi, caps)) - return GST_FLOW_NOT_SUPPORTED; - if (!GST_VIDEO_INFO_IS_YUV(&vi)) - return GST_FLOW_OK; - } - - if (!gst_vaapi_uploader_ensure_display(sink->uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) - return GST_FLOW_NOT_SUPPORTED; - if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL)) - return GST_FLOW_NOT_SUPPORTED; - - buf = gst_vaapi_uploader_get_buffer(sink->uploader); - if (!buf) { - GST_WARNING("failed to allocate resources for raw YUV buffer"); - return GST_FLOW_NOT_SUPPORTED; - } - - *pbuf = buf; - return GST_FLOW_OK; + return gst_vaapi_plugin_base_allocate_input_buffer( + GST_VAAPI_PLUGIN_BASE(base_sink), caps, outbuf_ptr); } #endif diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 8aae2ff3e6..bcabe089ec 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -31,7 +31,6 @@ #include #endif #include "gstvaapipluginutil.h" -#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -69,7 +68,6 @@ struct _GstVaapiSink { /*< private >*/ GstVaapiPluginBase parent_instance; - GstVaapiUploader *uploader; GstCaps *caps; GstVaapiWindow *window; guint window_width; @@ -96,7 +94,6 @@ struct _GstVaapiSink { guint use_overlay : 1; guint use_rotation : 1; guint keep_aspect : 1; - guint use_video_raw : 1; }; struct _GstVaapiSinkClass { From bf8f244de3262c782f425252afe919dbad0f554b Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Thu, 12 Dec 2013 17:01:29 +0000 Subject: [PATCH 1470/3781] plugins: implement GLTextureUploadMeta user data copy. Makes the copies of a buffer reference their own GLTextureUploadMeta user data and prevent the original buffer accessing already freed memory if its copies has been released and freed. https://bugzilla.gnome.org/show_bug.cgi?id=720336 [Propagate the original meta texture to the copy too] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapivideometa_texture.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 8a38be632e..8d96770748 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -57,6 +57,19 @@ meta_texture_new(void) return meta; } +static GstVaapiVideoMetaTexture * +meta_texture_copy(GstVaapiVideoMetaTexture *meta) +{ + GstVaapiVideoMetaTexture *copy; + + copy = meta_texture_new(); + if (!copy) + return NULL; + + gst_vaapi_texture_replace(©->texture, meta->texture); + return copy; +} + static gboolean gst_vaapi_texture_upload(GstVideoGLTextureUploadMeta *meta, guint texture_id[4]) { @@ -108,7 +121,8 @@ gst_buffer_add_texture_upload_meta(GstBuffer *buffer) meta = gst_buffer_add_video_gl_texture_upload_meta(buffer, GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, 1, tex_type, gst_vaapi_texture_upload, - meta_texture, NULL, (GBoxedFreeFunc)meta_texture_free); + meta_texture, (GBoxedCopyFunc)meta_texture_copy, + (GBoxedFreeFunc)meta_texture_free); if (!meta) goto error; return TRUE; From 690e85ff8ef80e7a27da2ff81813ae7f9d12b45b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Dec 2013 17:08:23 +0100 Subject: [PATCH 1471/3781] plugins: fix permissions for certain files. Drop the execute bit for gstvaapiuploader.c and gstvaapipostproc.[ch] files. --- gst/vaapi/gstvaapipostproc.c | 0 gst/vaapi/gstvaapipostproc.h | 0 gst/vaapi/gstvaapiuploader.c | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 gst/vaapi/gstvaapipostproc.c mode change 100755 => 100644 gst/vaapi/gstvaapipostproc.h mode change 100755 => 100644 gst/vaapi/gstvaapiuploader.c diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c old mode 100755 new mode 100644 diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h old mode 100755 new mode 100644 diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c old mode 100755 new mode 100644 From a6fe7698bc90610367a9f8be47154f850ddca442 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Dec 2013 16:04:19 +0100 Subject: [PATCH 1472/3781] utils: add helper functions to get codec or profile name. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 88 ++++++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiprofile.h | 9 +++ 2 files changed, 93 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index b29c199684..ad3441a10d 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -34,13 +34,19 @@ #include "gstvaapiprofile.h" #include "gstvaapiworkarounds.h" +typedef struct _GstVaapiCodecMap GstVaapiCodecMap; typedef struct _GstVaapiProfileMap GstVaapiProfileMap; typedef struct _GstVaapiEntrypointMap GstVaapiEntrypointMap; +struct _GstVaapiCodecMap { + GstVaapiCodec codec; + const gchar *name; +}; + struct _GstVaapiProfileMap { GstVaapiProfile profile; VAProfile va_profile; - const char *caps_str; + const char *media_str; const gchar *profile_str; }; @@ -49,6 +55,19 @@ struct _GstVaapiEntrypointMap { VAEntrypoint va_entrypoint; }; +/* Codecs */ +static const GstVaapiCodecMap gst_vaapi_codecs[] = { + { GST_VAAPI_CODEC_MPEG1, "mpeg1" }, + { GST_VAAPI_CODEC_MPEG2, "mpeg2" }, + { GST_VAAPI_CODEC_MPEG4, "mpeg4" }, + { GST_VAAPI_CODEC_H263, "h263" }, + { GST_VAAPI_CODEC_H264, "h264" }, + { GST_VAAPI_CODEC_WMV3, "wmv3" }, + { GST_VAAPI_CODEC_VC1, "vc1" }, + { GST_VAAPI_CODEC_JPEG, "jpeg" }, + { 0, } +}; + /* Profiles */ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_MPEG2_SIMPLE, VAProfileMPEG2Simple, @@ -120,6 +139,17 @@ static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = { { 0, } }; +static const GstVaapiCodecMap * +get_codecs_map(GstVaapiCodec codec) +{ + const GstVaapiCodecMap *m; + + for (m = gst_vaapi_codecs; m->codec; m++) + if (m->codec == codec) + return m; + return NULL; +} + static const GstVaapiProfileMap * get_profiles_map(GstVaapiProfile profile) { @@ -142,6 +172,22 @@ get_entrypoints_map(GstVaapiEntrypoint entrypoint) return NULL; } +/** + * gst_vaapi_codec_get_name: + * @codec: a #GstVaapiCodec + * + * Returns a string representation for the supplied @codec type. + * + * Return value: the statically allocated string representation of @codec + */ +const gchar * +gst_vaapi_codec_get_name(GstVaapiCodec codec) +{ + const GstVaapiCodecMap * const m = get_codecs_map(codec); + + return m ? m->name : NULL; +} + /** * gst_vaapi_profile: * @profile: a #VAProfile @@ -163,6 +209,40 @@ gst_vaapi_profile(VAProfile profile) return 0; } +/** + * gst_vaapi_profile_get_name: + * @profile: a #GstVaapiProfile + * + * Returns a string representation for the supplied @profile. + * + * Return value: the statically allocated string representation of @profile + */ +const gchar * +gst_vaapi_profile_get_name(GstVaapiProfile profile) +{ + const GstVaapiProfileMap * const m = get_profiles_map(profile); + + return m ? m->profile_str : NULL; +} + +/** + * gst_vaapi_profile_get_media_type_name: + * @profile: a #GstVaapiProfile + * + * Returns a string representation for the media type of the supplied + * @profile. + * + * Return value: the statically allocated string representation of + * @profile media type + */ +const gchar * +gst_vaapi_profile_get_media_type_name(GstVaapiProfile profile) +{ + const GstVaapiProfileMap * const m = get_profiles_map(profile); + + return m ? m->media_str : NULL; +} + /** * gst_vaapi_profile_from_codec_data: * @codec: a #GstVaapiCodec @@ -256,9 +336,9 @@ gst_vaapi_profile_from_caps(const GstCaps *caps) profile = 0; best_profile = 0; for (m = gst_vaapi_profiles; !profile && m->profile; m++) { - if (strncmp(name, m->caps_str, namelen) != 0) + if (strncmp(name, m->media_str, namelen) != 0) continue; - caps_test = gst_caps_from_string(m->caps_str);; + caps_test = gst_caps_from_string(m->media_str); if (gst_caps_is_always_compatible(caps, caps_test)) { best_profile = m->profile; if (profile_str && m->profile_str && @@ -322,7 +402,7 @@ gst_vaapi_profile_get_caps(GstVaapiProfile profile) for (m = gst_vaapi_profiles; m->profile; m++) { if (m->profile != profile) continue; - caps = gst_caps_from_string(m->caps_str); + caps = gst_caps_from_string(m->media_str); if (!caps) continue; gst_caps_set_simple( diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index aa83e35662..be74a0afe5 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -169,12 +169,21 @@ typedef enum { GST_VAAPI_ENTRYPOINT_SLICE_ENCODE } GstVaapiEntrypoint; +const gchar * +gst_vaapi_codec_get_name(GstVaapiCodec codec); + GstVaapiProfile gst_vaapi_profile(VAProfile profile); GstVaapiProfile gst_vaapi_profile_from_caps(const GstCaps *caps); +const gchar * +gst_vaapi_profile_get_name(GstVaapiProfile profile); + +const gchar * +gst_vaapi_profile_get_media_type_name(GstVaapiProfile profile); + VAProfile gst_vaapi_profile_get_va_profile(GstVaapiProfile profile); From ff0642efad6d695038b85f935af17bf7218317a4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Dec 2013 13:27:07 +0100 Subject: [PATCH 1473/3781] display: re-indent all GstVaapiDisplay related source code. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 2169 ++++++++--------- gst-libs/gst/vaapi/gstvaapidisplay.h | 131 +- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 490 ++-- gst-libs/gst/vaapi/gstvaapidisplay_drm.h | 9 +- gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h | 27 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 68 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 4 +- gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 16 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 134 +- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 480 ++-- gst-libs/gst/vaapi/gstvaapidisplay_wayland.h | 6 +- .../gst/vaapi/gstvaapidisplay_wayland_priv.h | 43 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 698 +++--- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 10 +- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 41 +- gst-libs/gst/vaapi/gstvaapidisplaycache.c | 320 ++- gst-libs/gst/vaapi/gstvaapidisplaycache.h | 54 +- 17 files changed, 2295 insertions(+), 2405 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 74a8eecb21..7aa28eb58d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -39,7 +39,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -GST_DEBUG_CATEGORY(gst_debug_vaapi); +GST_DEBUG_CATEGORY (gst_debug_vaapi); /* Ensure those symbols are actually defined in the resulting libraries */ #undef gst_vaapi_display_ref @@ -47,133 +47,137 @@ GST_DEBUG_CATEGORY(gst_debug_vaapi); #undef gst_vaapi_display_replace typedef struct _GstVaapiConfig GstVaapiConfig; -struct _GstVaapiConfig { - GstVaapiProfile profile; - GstVaapiEntrypoint entrypoint; +struct _GstVaapiConfig +{ + GstVaapiProfile profile; + GstVaapiEntrypoint entrypoint; }; typedef struct _GstVaapiProperty GstVaapiProperty; -struct _GstVaapiProperty { - const gchar *name; - VADisplayAttribute attribute; - gint old_value; +struct _GstVaapiProperty +{ + const gchar *name; + VADisplayAttribute attribute; + gint old_value; }; typedef struct _GstVaapiFormatInfo GstVaapiFormatInfo; -struct _GstVaapiFormatInfo { - GstVideoFormat format; - guint flags; +struct _GstVaapiFormatInfo +{ + GstVideoFormat format; + guint flags; }; #define DEFAULT_RENDER_MODE GST_VAAPI_RENDER_MODE_TEXTURE #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 -enum { - PROP_0, +enum +{ + PROP_0, - PROP_RENDER_MODE, - PROP_ROTATION, - PROP_HUE, - PROP_SATURATION, - PROP_BRIGHTNESS, - PROP_CONTRAST, + PROP_RENDER_MODE, + PROP_ROTATION, + PROP_HUE, + PROP_SATURATION, + PROP_BRIGHTNESS, + PROP_CONTRAST, - N_PROPERTIES + N_PROPERTIES }; static GstVaapiDisplayCache *g_display_cache = NULL; static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; -static void -gst_vaapi_display_properties_init(void); +static void gst_vaapi_display_properties_init (void); static gboolean -get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value); +get_attribute (GstVaapiDisplay * display, VADisplayAttribType type, + gint * value); static gboolean -set_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint value); +set_attribute (GstVaapiDisplay * display, VADisplayAttribType type, gint value); static gboolean -get_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat *v); +get_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat * v); static gboolean -set_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat v); +set_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat v); static void -libgstvaapi_init_once(void) +libgstvaapi_init_once (void) { - static gsize g_once = FALSE; + static gsize g_once = FALSE; - if (!g_once_init_enter(&g_once)) - return; + if (!g_once_init_enter (&g_once)) + return; - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapi, "vaapi", 0, "VA-API helper"); + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi, "vaapi", 0, "VA-API helper"); - /* Dump gstreamer-vaapi version for debugging purposes */ - GST_INFO("gstreamer-vaapi version %s", GST_VAAPI_VERSION_ID); + /* Dump gstreamer-vaapi version for debugging purposes */ + GST_INFO ("gstreamer-vaapi version %s", GST_VAAPI_VERSION_ID); - gst_vaapi_display_properties_init(); + gst_vaapi_display_properties_init (); - g_once_init_leave(&g_once, TRUE); + g_once_init_leave (&g_once, TRUE); } static inline GstVaapiDisplayCache * -get_display_cache(void) +get_display_cache (void) { - if (!g_display_cache) - g_display_cache = gst_vaapi_display_cache_new(); - return g_display_cache; + if (!g_display_cache) + g_display_cache = gst_vaapi_display_cache_new (); + return g_display_cache; } GstVaapiDisplayCache * -gst_vaapi_display_get_cache(void) +gst_vaapi_display_get_cache (void) { - return get_display_cache(); + return get_display_cache (); } static void -free_display_cache(void) +free_display_cache (void) { - if (!g_display_cache) - return; - if (gst_vaapi_display_cache_get_size(g_display_cache) > 0) - return; - gst_vaapi_display_cache_free(g_display_cache); - g_display_cache = NULL; + if (!g_display_cache) + return; + if (gst_vaapi_display_cache_get_size (g_display_cache) > 0) + return; + gst_vaapi_display_cache_free (g_display_cache); + g_display_cache = NULL; } /* GstVaapiDisplayType enumerations */ GType -gst_vaapi_display_type_get_type(void) +gst_vaapi_display_type_get_type (void) { - static GType g_type = 0; + static GType g_type = 0; - static const GEnumValue display_types[] = { - { GST_VAAPI_DISPLAY_TYPE_ANY, - "Auto detection", "any" }, + static const GEnumValue display_types[] = { + {GST_VAAPI_DISPLAY_TYPE_ANY, + "Auto detection", "any"}, #if USE_X11 - { GST_VAAPI_DISPLAY_TYPE_X11, - "VA/X11 display", "x11" }, + {GST_VAAPI_DISPLAY_TYPE_X11, + "VA/X11 display", "x11"}, #endif #if USE_GLX - { GST_VAAPI_DISPLAY_TYPE_GLX, - "VA/GLX display", "glx" }, + {GST_VAAPI_DISPLAY_TYPE_GLX, + "VA/GLX display", "glx"}, #endif #if USE_WAYLAND - { GST_VAAPI_DISPLAY_TYPE_WAYLAND, - "VA/Wayland display", "wayland" }, + {GST_VAAPI_DISPLAY_TYPE_WAYLAND, + "VA/Wayland display", "wayland"}, #endif #if USE_DRM - { GST_VAAPI_DISPLAY_TYPE_DRM, - "VA/DRM display", "drm" }, + {GST_VAAPI_DISPLAY_TYPE_DRM, + "VA/DRM display", "drm"}, #endif - { 0, NULL, NULL }, - }; + {0, NULL, NULL}, + }; - if (!g_type) - g_type = g_enum_register_static("GstVaapiDisplayType", display_types); - return g_type; + if (!g_type) + g_type = g_enum_register_static ("GstVaapiDisplayType", display_types); + return g_type; } /** @@ -187,848 +191,822 @@ gst_vaapi_display_type_get_type(void) * Returns: %TRUE if @type1 is compatible with @type2, %FALSE otherwise. */ gboolean -gst_vaapi_display_type_is_compatible(GstVaapiDisplayType type1, +gst_vaapi_display_type_is_compatible (GstVaapiDisplayType type1, GstVaapiDisplayType type2) { - if (type1 == type2) - return TRUE; + if (type1 == type2) + return TRUE; - switch (type1) { + switch (type1) { case GST_VAAPI_DISPLAY_TYPE_GLX: - if (type2 == GST_VAAPI_DISPLAY_TYPE_X11) - return TRUE; - break; + if (type2 == GST_VAAPI_DISPLAY_TYPE_X11) + return TRUE; + break; default: - break; - } - return type2 == GST_VAAPI_DISPLAY_TYPE_ANY; + break; + } + return type2 == GST_VAAPI_DISPLAY_TYPE_ANY; } /* Append GstVideoFormat to formats array */ static inline void -append_format(GArray *formats, GstVideoFormat format, guint flags) +append_format (GArray * formats, GstVideoFormat format, guint flags) { - GstVaapiFormatInfo fi; + GstVaapiFormatInfo fi; - fi.format = format; - fi.flags = flags; - g_array_append_val(formats, fi); + fi.format = format; + fi.flags = flags; + g_array_append_val (formats, fi); } /* Append VAImageFormats to formats array */ static void -append_formats(GArray *formats, const VAImageFormat *va_formats, - guint *flags, guint n) +append_formats (GArray * formats, const VAImageFormat * va_formats, + guint * flags, guint n) { - GstVideoFormat format; - const GstVaapiFormatInfo *YV12_fip = NULL; - const GstVaapiFormatInfo *I420_fip = NULL; - guint i; + GstVideoFormat format; + const GstVaapiFormatInfo *YV12_fip = NULL; + const GstVaapiFormatInfo *I420_fip = NULL; + guint i; - for (i = 0; i < n; i++) { - const VAImageFormat * const va_format = &va_formats[i]; - const GstVaapiFormatInfo **fipp; + for (i = 0; i < n; i++) { + const VAImageFormat *const va_format = &va_formats[i]; + const GstVaapiFormatInfo **fipp; - format = gst_vaapi_video_format_from_va_format(va_format); - if (format == GST_VIDEO_FORMAT_UNKNOWN) { - GST_DEBUG("unsupported format %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS(va_format->fourcc)); - continue; - } - append_format(formats, format, flags ? flags[i] : 0); - - switch (format) { - case GST_VIDEO_FORMAT_YV12: - fipp = &YV12_fip; - break; - case GST_VIDEO_FORMAT_I420: - fipp = &I420_fip; - break; - default: - fipp = NULL; - break; - } - if (fipp) - *fipp = &g_array_index(formats, GstVaapiFormatInfo, - formats->len - 1); + format = gst_vaapi_video_format_from_va_format (va_format); + if (format == GST_VIDEO_FORMAT_UNKNOWN) { + GST_DEBUG ("unsupported format %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (va_format->fourcc)); + continue; } + append_format (formats, format, flags ? flags[i] : 0); - /* Append I420 (resp. YV12) format if YV12 (resp. I420) is not - supported by the underlying driver */ - if (YV12_fip && !I420_fip) - append_format(formats, GST_VIDEO_FORMAT_I420, YV12_fip->flags); - else if (I420_fip && !YV12_fip) - append_format(formats, GST_VIDEO_FORMAT_YV12, I420_fip->flags); + switch (format) { + case GST_VIDEO_FORMAT_YV12: + fipp = &YV12_fip; + break; + case GST_VIDEO_FORMAT_I420: + fipp = &I420_fip; + break; + default: + fipp = NULL; + break; + } + if (fipp) + *fipp = &g_array_index (formats, GstVaapiFormatInfo, formats->len - 1); + } + + /* Append I420 (resp. YV12) format if YV12 (resp. I420) is not + supported by the underlying driver */ + if (YV12_fip && !I420_fip) + append_format (formats, GST_VIDEO_FORMAT_I420, YV12_fip->flags); + else if (I420_fip && !YV12_fip) + append_format (formats, GST_VIDEO_FORMAT_YV12, I420_fip->flags); } /* Sort image formats. Prefer YUV formats first */ static gint -compare_yuv_formats(gconstpointer a, gconstpointer b) +compare_yuv_formats (gconstpointer a, gconstpointer b) { - const GstVideoFormat fmt1 = ((GstVaapiFormatInfo *)a)->format; - const GstVideoFormat fmt2 = ((GstVaapiFormatInfo *)b)->format; + const GstVideoFormat fmt1 = ((GstVaapiFormatInfo *) a)->format; + const GstVideoFormat fmt2 = ((GstVaapiFormatInfo *) b)->format; - const gboolean is_fmt1_yuv = gst_vaapi_video_format_is_yuv(fmt1); - const gboolean is_fmt2_yuv = gst_vaapi_video_format_is_yuv(fmt2); + const gboolean is_fmt1_yuv = gst_vaapi_video_format_is_yuv (fmt1); + const gboolean is_fmt2_yuv = gst_vaapi_video_format_is_yuv (fmt2); - if (is_fmt1_yuv != is_fmt2_yuv) - return is_fmt1_yuv ? -1 : 1; + if (is_fmt1_yuv != is_fmt2_yuv) + return is_fmt1_yuv ? -1 : 1; - return ((gint)gst_vaapi_video_format_get_score(fmt1) - - (gint)gst_vaapi_video_format_get_score(fmt2)); + return ((gint) gst_vaapi_video_format_get_score (fmt1) - + (gint) gst_vaapi_video_format_get_score (fmt2)); } /* Sort subpicture formats. Prefer RGB formats first */ static gint -compare_rgb_formats(gconstpointer a, gconstpointer b) +compare_rgb_formats (gconstpointer a, gconstpointer b) { - const GstVideoFormat fmt1 = ((GstVaapiFormatInfo *)a)->format; - const GstVideoFormat fmt2 = ((GstVaapiFormatInfo *)b)->format; + const GstVideoFormat fmt1 = ((GstVaapiFormatInfo *) a)->format; + const GstVideoFormat fmt2 = ((GstVaapiFormatInfo *) b)->format; - const gboolean is_fmt1_rgb = gst_vaapi_video_format_is_rgb(fmt1); - const gboolean is_fmt2_rgb = gst_vaapi_video_format_is_rgb(fmt2); + const gboolean is_fmt1_rgb = gst_vaapi_video_format_is_rgb (fmt1); + const gboolean is_fmt2_rgb = gst_vaapi_video_format_is_rgb (fmt2); - if (is_fmt1_rgb != is_fmt2_rgb) - return is_fmt1_rgb ? -1 : 1; + if (is_fmt1_rgb != is_fmt2_rgb) + return is_fmt1_rgb ? -1 : 1; - return ((gint)gst_vaapi_video_format_get_score(fmt1) - - (gint)gst_vaapi_video_format_get_score(fmt2)); + return ((gint) gst_vaapi_video_format_get_score (fmt1) - + (gint) gst_vaapi_video_format_get_score (fmt2)); } /* Check if configs array contains profile at entrypoint */ static inline gboolean -find_config( - GArray *configs, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint -) +find_config (GArray * configs, + GstVaapiProfile profile, GstVaapiEntrypoint entrypoint) { - GstVaapiConfig *config; - guint i; + GstVaapiConfig *config; + guint i; - if (!configs) - return FALSE; - - for (i = 0; i < configs->len; i++) { - config = &g_array_index(configs, GstVaapiConfig, i); - if (config->profile == profile && config->entrypoint == entrypoint) - return TRUE; - } + if (!configs) return FALSE; + + for (i = 0; i < configs->len; i++) { + config = &g_array_index (configs, GstVaapiConfig, i); + if (config->profile == profile && config->entrypoint == entrypoint) + return TRUE; + } + return FALSE; } /* HACK: append H.263 Baseline profile if MPEG-4:2 Simple profile is supported */ static void -append_h263_config(GArray *configs) +append_h263_config (GArray * configs) { - GstVaapiConfig *config, tmp_config; - GstVaapiConfig *mpeg4_simple_config = NULL; - GstVaapiConfig *h263_baseline_config = NULL; - guint i; + GstVaapiConfig *config, tmp_config; + GstVaapiConfig *mpeg4_simple_config = NULL; + GstVaapiConfig *h263_baseline_config = NULL; + guint i; - if (!WORKAROUND_H263_BASELINE_DECODE_PROFILE) - return; + if (!WORKAROUND_H263_BASELINE_DECODE_PROFILE) + return; - if (!configs) - return; + if (!configs) + return; - for (i = 0; i < configs->len; i++) { - config = &g_array_index(configs, GstVaapiConfig, i); - if (config->profile == GST_VAAPI_PROFILE_MPEG4_SIMPLE) - mpeg4_simple_config = config; - else if (config->profile == GST_VAAPI_PROFILE_H263_BASELINE) - h263_baseline_config = config; - } + for (i = 0; i < configs->len; i++) { + config = &g_array_index (configs, GstVaapiConfig, i); + if (config->profile == GST_VAAPI_PROFILE_MPEG4_SIMPLE) + mpeg4_simple_config = config; + else if (config->profile == GST_VAAPI_PROFILE_H263_BASELINE) + h263_baseline_config = config; + } - if (mpeg4_simple_config && !h263_baseline_config) { - tmp_config = *mpeg4_simple_config; - tmp_config.profile = GST_VAAPI_PROFILE_H263_BASELINE; - g_array_append_val(configs, tmp_config); - } + if (mpeg4_simple_config && !h263_baseline_config) { + tmp_config = *mpeg4_simple_config; + tmp_config.profile = GST_VAAPI_PROFILE_H263_BASELINE; + g_array_append_val (configs, tmp_config); + } } /* Convert configs array to profiles as GstCaps */ static GstCaps * -get_profile_caps(GArray *configs) +get_profile_caps (GArray * configs) { - GstVaapiConfig *config; - GstCaps *out_caps, *caps; - guint i; + GstVaapiConfig *config; + GstCaps *out_caps, *caps; + guint i; - if (!configs) - return NULL; + if (!configs) + return NULL; - out_caps = gst_caps_new_empty(); - if (!out_caps) - return NULL; + out_caps = gst_caps_new_empty (); + if (!out_caps) + return NULL; - for (i = 0; i < configs->len; i++) { - config = &g_array_index(configs, GstVaapiConfig, i); - caps = gst_vaapi_profile_get_caps(config->profile); - if (caps) - out_caps = gst_caps_merge(out_caps, caps); - } - return out_caps; + for (i = 0; i < configs->len; i++) { + config = &g_array_index (configs, GstVaapiConfig, i); + caps = gst_vaapi_profile_get_caps (config->profile); + if (caps) + out_caps = gst_caps_merge (out_caps, caps); + } + return out_caps; } /* Find format info */ static const GstVaapiFormatInfo * -find_format_info(GArray *formats, GstVideoFormat format) +find_format_info (GArray * formats, GstVideoFormat format) { - const GstVaapiFormatInfo *fip; - guint i; + const GstVaapiFormatInfo *fip; + guint i; - for (i = 0; i < formats->len; i++) { - fip = &g_array_index(formats, GstVaapiFormatInfo, i); - if (fip->format == format) - return fip; - } - return NULL; + for (i = 0; i < formats->len; i++) { + fip = &g_array_index (formats, GstVaapiFormatInfo, i); + if (fip->format == format) + return fip; + } + return NULL; } /* Check if formats array contains format */ static inline gboolean -find_format(GArray *formats, GstVideoFormat format) +find_format (GArray * formats, GstVideoFormat format) { - return find_format_info(formats, format) != NULL; + return find_format_info (formats, format) != NULL; } /* Convert formats array to GstCaps */ static GstCaps * -get_format_caps(GArray *formats) +get_format_caps (GArray * formats) { - const GstVaapiFormatInfo *fip; - GstCaps *out_caps, *caps; - guint i; + const GstVaapiFormatInfo *fip; + GstCaps *out_caps, *caps; + guint i; - out_caps = gst_caps_new_empty(); - if (!out_caps) - return NULL; + out_caps = gst_caps_new_empty (); + if (!out_caps) + return NULL; - for (i = 0; i < formats->len; i++) { - fip = &g_array_index(formats, GstVaapiFormatInfo, i); - caps = gst_vaapi_video_format_to_caps(fip->format); - if (caps) - gst_caps_append(out_caps, caps); - } - return out_caps; + for (i = 0; i < formats->len; i++) { + fip = &g_array_index (formats, GstVaapiFormatInfo, i); + caps = gst_vaapi_video_format_to_caps (fip->format); + if (caps) + gst_caps_append (out_caps, caps); + } + return out_caps; } /* Find display attribute */ static const GstVaapiProperty * -find_property(GArray *properties, const gchar *name) +find_property (GArray * properties, const gchar * name) { - GstVaapiProperty *prop; - guint i; + GstVaapiProperty *prop; + guint i; - if (!name) - return NULL; - - for (i = 0; i < properties->len; i++) { - prop = &g_array_index(properties, GstVaapiProperty, i); - if (strcmp(prop->name, name) == 0) - return prop; - } + if (!name) return NULL; + + for (i = 0; i < properties->len; i++) { + prop = &g_array_index (properties, GstVaapiProperty, i); + if (strcmp (prop->name, name) == 0) + return prop; + } + return NULL; } #if 0 static const GstVaapiProperty * -find_property_by_type(GArray *properties, VADisplayAttribType type) +find_property_by_type (GArray * properties, VADisplayAttribType type) { - GstVaapiProperty *prop; - guint i; + GstVaapiProperty *prop; + guint i; - for (i = 0; i < properties->len; i++) { - prop = &g_array_index(properties, GstVaapiProperty, i); - if (prop->attribute.type == type) - return prop; - } - return NULL; + for (i = 0; i < properties->len; i++) { + prop = &g_array_index (properties, GstVaapiProperty, i); + if (prop->attribute.type == type) + return prop; + } + return NULL; } #endif static inline const GstVaapiProperty * -find_property_by_pspec(GstVaapiDisplay *display, GParamSpec *pspec) +find_property_by_pspec (GstVaapiDisplay * display, GParamSpec * pspec) { - GstVaapiDisplayPrivate * const priv = - GST_VAAPI_DISPLAY_GET_PRIVATE(display); + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - return find_property(priv->properties, pspec->name); + return find_property (priv->properties, pspec->name); } static guint -find_property_id(const gchar *name) +find_property_id (const gchar * name) { - typedef struct { - const gchar *name; - guint id; - } property_map; + typedef struct + { + const gchar *name; + guint id; + } property_map; - static const property_map g_property_map[] = { - { GST_VAAPI_DISPLAY_PROP_RENDER_MODE, PROP_RENDER_MODE }, - { GST_VAAPI_DISPLAY_PROP_ROTATION, PROP_ROTATION }, - { GST_VAAPI_DISPLAY_PROP_HUE, PROP_HUE }, - { GST_VAAPI_DISPLAY_PROP_SATURATION, PROP_SATURATION }, - { GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, PROP_BRIGHTNESS }, - { GST_VAAPI_DISPLAY_PROP_CONTRAST, PROP_CONTRAST }, - { NULL, } - }; + static const property_map g_property_map[] = { + {GST_VAAPI_DISPLAY_PROP_RENDER_MODE, PROP_RENDER_MODE}, + {GST_VAAPI_DISPLAY_PROP_ROTATION, PROP_ROTATION}, + {GST_VAAPI_DISPLAY_PROP_HUE, PROP_HUE}, + {GST_VAAPI_DISPLAY_PROP_SATURATION, PROP_SATURATION}, + {GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, PROP_BRIGHTNESS}, + {GST_VAAPI_DISPLAY_PROP_CONTRAST, PROP_CONTRAST}, + {NULL,} + }; - const property_map *m; - for (m = g_property_map; m->name != NULL; m++) { - if (strcmp(m->name, name) == 0) - return m->id; - } - return 0; + const property_map *m; + for (m = g_property_map; m->name != NULL; m++) { + if (strcmp (m->name, name) == 0) + return m->id; + } + return 0; } static void -gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display) +gst_vaapi_display_calculate_pixel_aspect_ratio (GstVaapiDisplay * display) { - GstVaapiDisplayPrivate * const priv = - GST_VAAPI_DISPLAY_GET_PRIVATE(display); - gdouble ratio, delta; - gint i, j, index, windex; + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + gdouble ratio, delta; + gint i, j, index, windex; - static const gint par[][2] = { - {1, 1}, /* regular screen */ - {16, 15}, /* PAL TV */ - {11, 10}, /* 525 line Rec.601 video */ - {54, 59}, /* 625 line Rec.601 video */ - {64, 45}, /* 1280x1024 on 16:9 display */ - {5, 3}, /* 1280x1024 on 4:3 display */ - {4, 3} /* 800x600 on 16:9 display */ - }; + static const gint par[][2] = { + {1, 1}, /* regular screen */ + {16, 15}, /* PAL TV */ + {11, 10}, /* 525 line Rec.601 video */ + {54, 59}, /* 625 line Rec.601 video */ + {64, 45}, /* 1280x1024 on 16:9 display */ + {5, 3}, /* 1280x1024 on 4:3 display */ + {4, 3} /* 800x600 on 16:9 display */ + }; - /* First, calculate the "real" ratio based on the X values; - * which is the "physical" w/h divided by the w/h in pixels of the - * display */ - if (!priv->width || !priv->height || !priv->width_mm || !priv->height_mm) - ratio = 1.0; - else - ratio = (gdouble)(priv->width_mm * priv->height) / - (priv->height_mm * priv->width); - GST_DEBUG("calculated pixel aspect ratio: %f", ratio); + /* First, calculate the "real" ratio based on the X values; + * which is the "physical" w/h divided by the w/h in pixels of the + * display */ + if (!priv->width || !priv->height || !priv->width_mm || !priv->height_mm) + ratio = 1.0; + else + ratio = (gdouble) (priv->width_mm * priv->height) / + (priv->height_mm * priv->width); + GST_DEBUG ("calculated pixel aspect ratio: %f", ratio); - /* Now, find the one from par[][2] with the lowest delta to the real one */ + /* Now, find the one from par[][2] with the lowest delta to the real one */ #define DELTA(idx, w) (ABS(ratio - ((gdouble)par[idx][w] / par[idx][!(w)]))) - delta = DELTA(0, 0); - index = 0; - windex = 0; + delta = DELTA (0, 0); + index = 0; + windex = 0; - for (i = 1; i < G_N_ELEMENTS(par); i++) { - for (j = 0; j < 2; j++) { - const gdouble this_delta = DELTA(i, j); - if (this_delta < delta) { - index = i; - windex = j; - delta = this_delta; - } - } + for (i = 1; i < G_N_ELEMENTS (par); i++) { + for (j = 0; j < 2; j++) { + const gdouble this_delta = DELTA (i, j); + if (this_delta < delta) { + index = i; + windex = j; + delta = this_delta; + } } + } #undef DELTA - priv->par_n = par[index][windex]; - priv->par_d = par[index][windex ^ 1]; + priv->par_n = par[index][windex]; + priv->par_d = par[index][windex ^ 1]; } static void -gst_vaapi_display_destroy(GstVaapiDisplay *display) +gst_vaapi_display_destroy (GstVaapiDisplay * display) { - GstVaapiDisplayPrivate * const priv = - GST_VAAPI_DISPLAY_GET_PRIVATE(display); + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - if (priv->decoders) { - g_array_free(priv->decoders, TRUE); - priv->decoders = NULL; - } + if (priv->decoders) { + g_array_free (priv->decoders, TRUE); + priv->decoders = NULL; + } - if (priv->encoders) { - g_array_free(priv->encoders, TRUE); - priv->encoders = NULL; - } + if (priv->encoders) { + g_array_free (priv->encoders, TRUE); + priv->encoders = NULL; + } - if (priv->image_formats) { - g_array_free(priv->image_formats, TRUE); - priv->image_formats = NULL; - } + if (priv->image_formats) { + g_array_free (priv->image_formats, TRUE); + priv->image_formats = NULL; + } - if (priv->subpicture_formats) { - g_array_free(priv->subpicture_formats, TRUE); - priv->subpicture_formats = NULL; - } + if (priv->subpicture_formats) { + g_array_free (priv->subpicture_formats, TRUE); + priv->subpicture_formats = NULL; + } - if (priv->properties) { - g_array_free(priv->properties, TRUE); - priv->properties = NULL; - } + if (priv->properties) { + g_array_free (priv->properties, TRUE); + priv->properties = NULL; + } - if (priv->display) { - if (!priv->parent) - vaTerminate(priv->display); - priv->display = NULL; - } + if (priv->display) { + if (!priv->parent) + vaTerminate (priv->display); + priv->display = NULL; + } - if (!priv->use_foreign_display) { - GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); - if (klass->close_display) - klass->close_display(display); - } + if (!priv->use_foreign_display) { + GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS (display); + if (klass->close_display) + klass->close_display (display); + } - gst_vaapi_display_replace_internal(&priv->parent, NULL); + gst_vaapi_display_replace_internal (&priv->parent, NULL); - if (g_display_cache) { - gst_vaapi_display_cache_remove(get_display_cache(), display); - free_display_cache(); - } + if (g_display_cache) { + gst_vaapi_display_cache_remove (get_display_cache (), display); + free_display_cache (); + } } static gboolean -gst_vaapi_display_create(GstVaapiDisplay *display, +gst_vaapi_display_create (GstVaapiDisplay * display, GstVaapiDisplayInitType init_type, gpointer init_value) { - GstVaapiDisplayPrivate * const priv = - GST_VAAPI_DISPLAY_GET_PRIVATE(display); - const GstVaapiDisplayClass * const klass = - GST_VAAPI_DISPLAY_GET_CLASS(display); - GstVaapiDisplayCache *cache; - gboolean has_errors = TRUE; - VADisplayAttribute *display_attrs = NULL; - VAProfile *profiles = NULL; - VAEntrypoint *entrypoints = NULL; - VAImageFormat *formats = NULL; - unsigned int *flags = NULL; - gint i, j, n, num_entrypoints, major_version, minor_version; - VAStatus status; - GstVaapiDisplayInfo info; - const GstVaapiDisplayInfo *cached_info = NULL; + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + const GstVaapiDisplayClass *const klass = + GST_VAAPI_DISPLAY_GET_CLASS (display); + GstVaapiDisplayCache *cache; + gboolean has_errors = TRUE; + VADisplayAttribute *display_attrs = NULL; + VAProfile *profiles = NULL; + VAEntrypoint *entrypoints = NULL; + VAImageFormat *formats = NULL; + unsigned int *flags = NULL; + gint i, j, n, num_entrypoints, major_version, minor_version; + VAStatus status; + GstVaapiDisplayInfo info; + const GstVaapiDisplayInfo *cached_info = NULL; - memset(&info, 0, sizeof(info)); - info.display = display; - info.display_type = priv->display_type; + memset (&info, 0, sizeof (info)); + info.display = display; + info.display_type = priv->display_type; - switch (init_type) { + switch (init_type) { case GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY: - info.va_display = init_value; - priv->display = init_value; - priv->use_foreign_display = TRUE; - break; + info.va_display = init_value; + priv->display = init_value; + priv->use_foreign_display = TRUE; + break; case GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME: - if (klass->open_display && !klass->open_display(display, init_value)) - return FALSE; - goto create_display; + if (klass->open_display && !klass->open_display (display, init_value)) + return FALSE; + goto create_display; case GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY: - if (klass->bind_display && !klass->bind_display(display, init_value)) - return FALSE; - // fall-through + if (klass->bind_display && !klass->bind_display (display, init_value)) + return FALSE; + // fall-through create_display: - if (!klass->get_display || !klass->get_display(display, &info)) - return FALSE; - priv->display = info.va_display; - priv->display_type = info.display_type; - if (klass->get_size) - klass->get_size(display, &priv->width, &priv->height); - if (klass->get_size_mm) - klass->get_size_mm(display, &priv->width_mm, &priv->height_mm); - gst_vaapi_display_calculate_pixel_aspect_ratio(display); + if (!klass->get_display || !klass->get_display (display, &info)) + return FALSE; + priv->display = info.va_display; + priv->display_type = info.display_type; + if (klass->get_size) + klass->get_size (display, &priv->width, &priv->height); + if (klass->get_size_mm) + klass->get_size_mm (display, &priv->width_mm, &priv->height_mm); + gst_vaapi_display_calculate_pixel_aspect_ratio (display); + break; + } + if (!priv->display) + return FALSE; + + cache = get_display_cache (); + if (!cache) + return FALSE; + cached_info = gst_vaapi_display_cache_lookup_by_va_display (cache, + info.va_display); + if (cached_info) { + gst_vaapi_display_replace_internal (&priv->parent, cached_info->display); + priv->display_type = cached_info->display_type; + } + + if (!priv->parent) { + status = vaInitialize (priv->display, &major_version, &minor_version); + if (!vaapi_check_status (status, "vaInitialize()")) + goto end; + GST_DEBUG ("VA-API version %d.%d", major_version, minor_version); + } + + /* VA profiles */ + profiles = g_new (VAProfile, vaMaxNumProfiles (priv->display)); + if (!profiles) + goto end; + entrypoints = g_new (VAEntrypoint, vaMaxNumEntrypoints (priv->display)); + if (!entrypoints) + goto end; + status = vaQueryConfigProfiles (priv->display, profiles, &n); + if (!vaapi_check_status (status, "vaQueryConfigProfiles()")) + goto end; + + GST_DEBUG ("%d profiles", n); + for (i = 0; i < n; i++) { +#if VA_CHECK_VERSION(0,34,0) + /* Introduced in VA/VPP API */ + if (profiles[i] == VAProfileNone) + continue; +#endif + GST_DEBUG (" %s", string_of_VAProfile (profiles[i])); + } + + priv->decoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig)); + if (!priv->decoders) + goto end; + priv->encoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig)); + if (!priv->encoders) + goto end; + + for (i = 0; i < n; i++) { + GstVaapiConfig config; + + config.profile = gst_vaapi_profile (profiles[i]); + if (!config.profile) + continue; + + status = vaQueryConfigEntrypoints (priv->display, + profiles[i], entrypoints, &num_entrypoints); + if (!vaapi_check_status (status, "vaQueryConfigEntrypoints()")) + continue; + + for (j = 0; j < num_entrypoints; j++) { + config.entrypoint = gst_vaapi_entrypoint (entrypoints[j]); + switch (config.entrypoint) { + case GST_VAAPI_ENTRYPOINT_VLD: + case GST_VAAPI_ENTRYPOINT_IDCT: + case GST_VAAPI_ENTRYPOINT_MOCO: + g_array_append_val (priv->decoders, config); + break; + case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: + g_array_append_val (priv->encoders, config); + break; + } + } + } + append_h263_config (priv->decoders); + + /* Video processing API */ +#if USE_VA_VPP + status = vaQueryConfigEntrypoints (priv->display, VAProfileNone, + entrypoints, &num_entrypoints); + if (vaapi_check_status (status, "vaQueryEntrypoints() [VAProfileNone]")) { + for (j = 0; j < num_entrypoints; j++) { + if (entrypoints[j] == VAEntrypointVideoProc) + priv->has_vpp = TRUE; + } + } +#endif + + /* VA display attributes */ + display_attrs = + g_new (VADisplayAttribute, vaMaxNumDisplayAttributes (priv->display)); + if (!display_attrs) + goto end; + + n = 0; /* XXX: workaround old GMA500 bug */ + status = vaQueryDisplayAttributes (priv->display, display_attrs, &n); + if (!vaapi_check_status (status, "vaQueryDisplayAttributes()")) + goto end; + + priv->properties = g_array_new (FALSE, FALSE, sizeof (GstVaapiProperty)); + if (!priv->properties) + goto end; + + GST_DEBUG ("%d display attributes", n); + for (i = 0; i < n; i++) { + VADisplayAttribute *const attr = &display_attrs[i]; + GstVaapiProperty prop; + gint value; + + GST_DEBUG (" %s", string_of_VADisplayAttributeType (attr->type)); + + switch (attr->type) { +#if !VA_CHECK_VERSION(0,34,0) + case VADisplayAttribDirectSurface: + prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; + break; +#endif + case VADisplayAttribRenderMode: + prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; + break; + case VADisplayAttribRotation: + prop.name = GST_VAAPI_DISPLAY_PROP_ROTATION; + break; + case VADisplayAttribHue: + prop.name = GST_VAAPI_DISPLAY_PROP_HUE; + break; + case VADisplayAttribSaturation: + prop.name = GST_VAAPI_DISPLAY_PROP_SATURATION; + break; + case VADisplayAttribBrightness: + prop.name = GST_VAAPI_DISPLAY_PROP_BRIGHTNESS; + break; + case VADisplayAttribContrast: + prop.name = GST_VAAPI_DISPLAY_PROP_CONTRAST; + break; + default: + prop.name = NULL; break; } - if (!priv->display) - return FALSE; + if (!prop.name) + continue; - cache = get_display_cache(); - if (!cache) - return FALSE; - cached_info = gst_vaapi_display_cache_lookup_by_va_display(cache, - info.va_display); - if (cached_info) { - gst_vaapi_display_replace_internal(&priv->parent, - cached_info->display); - priv->display_type = cached_info->display_type; - } + /* Assume the attribute is really supported if we can get the + * actual and current value */ + if (!get_attribute (display, attr->type, &value)) + continue; - if (!priv->parent) { - status = vaInitialize(priv->display, &major_version, &minor_version); - if (!vaapi_check_status(status, "vaInitialize()")) - goto end; - GST_DEBUG("VA-API version %d.%d", major_version, minor_version); - } + /* Some drivers (e.g. EMGD) have completely random initial + * values */ + if (value < attr->min_value || value > attr->max_value) + continue; - /* VA profiles */ - profiles = g_new(VAProfile, vaMaxNumProfiles(priv->display)); - if (!profiles) - goto end; - entrypoints = g_new(VAEntrypoint, vaMaxNumEntrypoints(priv->display)); - if (!entrypoints) - goto end; - status = vaQueryConfigProfiles(priv->display, profiles, &n); - if (!vaapi_check_status(status, "vaQueryConfigProfiles()")) - goto end; + prop.attribute = *attr; + prop.old_value = value; + g_array_append_val (priv->properties, prop); + } - GST_DEBUG("%d profiles", n); - for (i = 0; i < n; i++) { -#if VA_CHECK_VERSION(0,34,0) - /* Introduced in VA/VPP API */ - if (profiles[i] == VAProfileNone) - continue; -#endif - GST_DEBUG(" %s", string_of_VAProfile(profiles[i])); - } + /* VA image formats */ + formats = g_new (VAImageFormat, vaMaxNumImageFormats (priv->display)); + if (!formats) + goto end; + status = vaQueryImageFormats (priv->display, formats, &n); + if (!vaapi_check_status (status, "vaQueryImageFormats()")) + goto end; - priv->decoders = g_array_new(FALSE, FALSE, sizeof(GstVaapiConfig)); - if (!priv->decoders) - goto end; - priv->encoders = g_array_new(FALSE, FALSE, sizeof(GstVaapiConfig)); - if (!priv->encoders) - goto end; + GST_DEBUG ("%d image formats", n); + for (i = 0; i < n; i++) + GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc)); - for (i = 0; i < n; i++) { - GstVaapiConfig config; + priv->image_formats = g_array_new (FALSE, FALSE, sizeof (GstVaapiFormatInfo)); + if (!priv->image_formats) + goto end; + append_formats (priv->image_formats, formats, NULL, n); + g_array_sort (priv->image_formats, compare_yuv_formats); - config.profile = gst_vaapi_profile(profiles[i]); - if (!config.profile) - continue; + /* VA subpicture formats */ + n = vaMaxNumSubpictureFormats (priv->display); + formats = g_renew (VAImageFormat, formats, n); + flags = g_new (guint, n); + if (!formats || !flags) + goto end; + status = + vaQuerySubpictureFormats (priv->display, formats, flags, (guint *) & n); + if (!vaapi_check_status (status, "vaQuerySubpictureFormats()")) + goto end; - status = vaQueryConfigEntrypoints( - priv->display, - profiles[i], - entrypoints, &num_entrypoints - ); - if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()")) - continue; + GST_DEBUG ("%d subpicture formats", n); + for (i = 0; i < n; i++) { + GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc)); + flags[i] = to_GstVaapiSubpictureFlags (flags[i]); + } - for (j = 0; j < num_entrypoints; j++) { - config.entrypoint = gst_vaapi_entrypoint(entrypoints[j]); - switch (config.entrypoint) { - case GST_VAAPI_ENTRYPOINT_VLD: - case GST_VAAPI_ENTRYPOINT_IDCT: - case GST_VAAPI_ENTRYPOINT_MOCO: - g_array_append_val(priv->decoders, config); - break; - case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: - g_array_append_val(priv->encoders, config); - break; - } - } - } - append_h263_config(priv->decoders); + priv->subpicture_formats = + g_array_new (FALSE, FALSE, sizeof (GstVaapiFormatInfo)); + if (!priv->subpicture_formats) + goto end; + append_formats (priv->subpicture_formats, formats, flags, n); + g_array_sort (priv->subpicture_formats, compare_rgb_formats); - /* Video processing API */ -#if USE_VA_VPP - status = vaQueryConfigEntrypoints(priv->display, VAProfileNone, - entrypoints, &num_entrypoints); - if (vaapi_check_status(status, "vaQueryEntrypoints() [VAProfileNone]")) { - for (j = 0; j < num_entrypoints; j++) { - if (entrypoints[j] == VAEntrypointVideoProc) - priv->has_vpp = TRUE; - } - } -#endif + if (!cached_info) { + if (!gst_vaapi_display_cache_add (cache, &info)) + goto end; + } - /* VA display attributes */ - display_attrs = - g_new(VADisplayAttribute, vaMaxNumDisplayAttributes(priv->display)); - if (!display_attrs) - goto end; - - n = 0; /* XXX: workaround old GMA500 bug */ - status = vaQueryDisplayAttributes(priv->display, display_attrs, &n); - if (!vaapi_check_status(status, "vaQueryDisplayAttributes()")) - goto end; - - priv->properties = g_array_new(FALSE, FALSE, sizeof(GstVaapiProperty)); - if (!priv->properties) - goto end; - - GST_DEBUG("%d display attributes", n); - for (i = 0; i < n; i++) { - VADisplayAttribute * const attr = &display_attrs[i]; - GstVaapiProperty prop; - gint value; - - GST_DEBUG(" %s", string_of_VADisplayAttributeType(attr->type)); - - switch (attr->type) { -#if !VA_CHECK_VERSION(0,34,0) - case VADisplayAttribDirectSurface: - prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; - break; -#endif - case VADisplayAttribRenderMode: - prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; - break; - case VADisplayAttribRotation: - prop.name = GST_VAAPI_DISPLAY_PROP_ROTATION; - break; - case VADisplayAttribHue: - prop.name = GST_VAAPI_DISPLAY_PROP_HUE; - break; - case VADisplayAttribSaturation: - prop.name = GST_VAAPI_DISPLAY_PROP_SATURATION; - break; - case VADisplayAttribBrightness: - prop.name = GST_VAAPI_DISPLAY_PROP_BRIGHTNESS; - break; - case VADisplayAttribContrast: - prop.name = GST_VAAPI_DISPLAY_PROP_CONTRAST; - break; - default: - prop.name = NULL; - break; - } - if (!prop.name) - continue; - - /* Assume the attribute is really supported if we can get the - * actual and current value */ - if (!get_attribute(display, attr->type, &value)) - continue; - - /* Some drivers (e.g. EMGD) have completely random initial - * values */ - if (value < attr->min_value || value > attr->max_value) - continue; - - prop.attribute = *attr; - prop.old_value = value; - g_array_append_val(priv->properties, prop); - } - - /* VA image formats */ - formats = g_new(VAImageFormat, vaMaxNumImageFormats(priv->display)); - if (!formats) - goto end; - status = vaQueryImageFormats(priv->display, formats, &n); - if (!vaapi_check_status(status, "vaQueryImageFormats()")) - goto end; - - GST_DEBUG("%d image formats", n); - for (i = 0; i < n; i++) - GST_DEBUG(" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc)); - - priv->image_formats = - g_array_new(FALSE, FALSE, sizeof(GstVaapiFormatInfo)); - if (!priv->image_formats) - goto end; - append_formats(priv->image_formats, formats, NULL, n); - g_array_sort(priv->image_formats, compare_yuv_formats); - - /* VA subpicture formats */ - n = vaMaxNumSubpictureFormats(priv->display); - formats = g_renew(VAImageFormat, formats, n); - flags = g_new(guint, n); - if (!formats || !flags) - goto end; - status = vaQuerySubpictureFormats(priv->display, formats, flags, (guint *)&n); - if (!vaapi_check_status(status, "vaQuerySubpictureFormats()")) - goto end; - - GST_DEBUG("%d subpicture formats", n); - for (i = 0; i < n; i++) { - GST_DEBUG(" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc)); - flags[i] = to_GstVaapiSubpictureFlags(flags[i]); - } - - priv->subpicture_formats = - g_array_new(FALSE, FALSE, sizeof(GstVaapiFormatInfo)); - if (!priv->subpicture_formats) - goto end; - append_formats(priv->subpicture_formats, formats, flags, n); - g_array_sort(priv->subpicture_formats, compare_rgb_formats); - - if (!cached_info) { - if (!gst_vaapi_display_cache_add(cache, &info)) - goto end; - } - - has_errors = FALSE; + has_errors = FALSE; end: - g_free(display_attrs); - g_free(profiles); - g_free(entrypoints); - g_free(formats); - g_free(flags); - return !has_errors; + g_free (display_attrs); + g_free (profiles); + g_free (entrypoints); + g_free (formats); + g_free (flags); + return !has_errors; } static void -gst_vaapi_display_lock_default(GstVaapiDisplay *display) +gst_vaapi_display_lock_default (GstVaapiDisplay * display) { - GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); + GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - if (priv->parent) - priv = GST_VAAPI_DISPLAY_GET_PRIVATE(priv->parent); - g_rec_mutex_lock(&priv->mutex); + if (priv->parent) + priv = GST_VAAPI_DISPLAY_GET_PRIVATE (priv->parent); + g_rec_mutex_lock (&priv->mutex); } static void -gst_vaapi_display_unlock_default(GstVaapiDisplay *display) +gst_vaapi_display_unlock_default (GstVaapiDisplay * display) { - GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); + GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - if (priv->parent) - priv = GST_VAAPI_DISPLAY_GET_PRIVATE(priv->parent); - g_rec_mutex_unlock(&priv->mutex); + if (priv->parent) + priv = GST_VAAPI_DISPLAY_GET_PRIVATE (priv->parent); + g_rec_mutex_unlock (&priv->mutex); } static void -gst_vaapi_display_init(GstVaapiDisplay *display) +gst_vaapi_display_init (GstVaapiDisplay * display) { - GstVaapiDisplayPrivate * const priv = - GST_VAAPI_DISPLAY_GET_PRIVATE(display); - const GstVaapiDisplayClass * const dpy_class = - GST_VAAPI_DISPLAY_GET_CLASS(display); + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + const GstVaapiDisplayClass *const dpy_class = + GST_VAAPI_DISPLAY_GET_CLASS (display); - priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; - priv->par_n = 1; - priv->par_d = 1; + priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; + priv->par_n = 1; + priv->par_d = 1; - g_rec_mutex_init(&priv->mutex); + g_rec_mutex_init (&priv->mutex); - if (dpy_class->init) - dpy_class->init(display); + if (dpy_class->init) + dpy_class->init (display); } static void -gst_vaapi_display_finalize(GstVaapiDisplay *display) +gst_vaapi_display_finalize (GstVaapiDisplay * display) { - GstVaapiDisplayPrivate * const priv = - GST_VAAPI_DISPLAY_GET_PRIVATE(display); + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - gst_vaapi_display_destroy(display); - g_rec_mutex_clear(&priv->mutex); + gst_vaapi_display_destroy (display); + g_rec_mutex_clear (&priv->mutex); } void -gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) +gst_vaapi_display_class_init (GstVaapiDisplayClass * klass) { - GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); - GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); - libgstvaapi_init_once(); + libgstvaapi_init_once (); - object_class->size = sizeof(GstVaapiDisplay); - object_class->finalize = (GDestroyNotify)gst_vaapi_display_finalize; - dpy_class->lock = gst_vaapi_display_lock_default; - dpy_class->unlock = gst_vaapi_display_unlock_default; + object_class->size = sizeof (GstVaapiDisplay); + object_class->finalize = (GDestroyNotify) gst_vaapi_display_finalize; + dpy_class->lock = gst_vaapi_display_lock_default; + dpy_class->unlock = gst_vaapi_display_unlock_default; } static void -gst_vaapi_display_properties_init(void) +gst_vaapi_display_properties_init (void) { - /** - * GstVaapiDisplay:render-mode: - * - * The VA display rendering mode, expressed as a #GstVaapiRenderMode. - */ - g_properties[PROP_RENDER_MODE] = - g_param_spec_enum(GST_VAAPI_DISPLAY_PROP_RENDER_MODE, - "render mode", - "The display rendering mode", - GST_VAAPI_TYPE_RENDER_MODE, - DEFAULT_RENDER_MODE, - G_PARAM_READWRITE); + /** + * GstVaapiDisplay:render-mode: + * + * The VA display rendering mode, expressed as a #GstVaapiRenderMode. + */ + g_properties[PROP_RENDER_MODE] = + g_param_spec_enum (GST_VAAPI_DISPLAY_PROP_RENDER_MODE, + "render mode", + "The display rendering mode", + GST_VAAPI_TYPE_RENDER_MODE, DEFAULT_RENDER_MODE, G_PARAM_READWRITE); - /** - * GstVaapiDisplay:rotation: - * - * The VA display rotation mode, expressed as a #GstVaapiRotation. - */ - g_properties[PROP_ROTATION] = - g_param_spec_enum(GST_VAAPI_DISPLAY_PROP_ROTATION, - "rotation", - "The display rotation mode", - GST_VAAPI_TYPE_ROTATION, - DEFAULT_ROTATION, - G_PARAM_READWRITE); + /** + * GstVaapiDisplay:rotation: + * + * The VA display rotation mode, expressed as a #GstVaapiRotation. + */ + g_properties[PROP_ROTATION] = + g_param_spec_enum (GST_VAAPI_DISPLAY_PROP_ROTATION, + "rotation", + "The display rotation mode", + GST_VAAPI_TYPE_ROTATION, DEFAULT_ROTATION, G_PARAM_READWRITE); - /** - * GstVaapiDisplay:hue: - * - * The VA display hue, expressed as a float value. Range is -180.0 - * to 180.0. Default value is 0.0 and represents no modification. - */ - g_properties[PROP_HUE] = - g_param_spec_float(GST_VAAPI_DISPLAY_PROP_HUE, - "hue", - "The display hue value", - -180.0, 180.0, 0.0, - G_PARAM_READWRITE); + /** + * GstVaapiDisplay:hue: + * + * The VA display hue, expressed as a float value. Range is -180.0 + * to 180.0. Default value is 0.0 and represents no modification. + */ + g_properties[PROP_HUE] = + g_param_spec_float (GST_VAAPI_DISPLAY_PROP_HUE, + "hue", "The display hue value", -180.0, 180.0, 0.0, G_PARAM_READWRITE); - /** - * GstVaapiDisplay:saturation: - * - * The VA display saturation, expressed as a float value. Range is - * 0.0 to 2.0. Default value is 1.0 and represents no modification. - */ - g_properties[PROP_SATURATION] = - g_param_spec_float(GST_VAAPI_DISPLAY_PROP_SATURATION, - "saturation", - "The display saturation value", - 0.0, 2.0, 1.0, - G_PARAM_READWRITE); + /** + * GstVaapiDisplay:saturation: + * + * The VA display saturation, expressed as a float value. Range is + * 0.0 to 2.0. Default value is 1.0 and represents no modification. + */ + g_properties[PROP_SATURATION] = + g_param_spec_float (GST_VAAPI_DISPLAY_PROP_SATURATION, + "saturation", + "The display saturation value", 0.0, 2.0, 1.0, G_PARAM_READWRITE); - /** - * GstVaapiDisplay:brightness: - * - * The VA display brightness, expressed as a float value. Range is - * -1.0 to 1.0. Default value is 0.0 and represents no modification. - */ - g_properties[PROP_BRIGHTNESS] = - g_param_spec_float(GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, - "brightness", - "The display brightness value", - -1.0, 1.0, 0.0, - G_PARAM_READWRITE); + /** + * GstVaapiDisplay:brightness: + * + * The VA display brightness, expressed as a float value. Range is + * -1.0 to 1.0. Default value is 0.0 and represents no modification. + */ + g_properties[PROP_BRIGHTNESS] = + g_param_spec_float (GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, + "brightness", + "The display brightness value", -1.0, 1.0, 0.0, G_PARAM_READWRITE); - /** - * GstVaapiDisplay:contrast: - * - * The VA display contrast, expressed as a float value. Range is - * 0.0 to 2.0. Default value is 1.0 and represents no modification. - */ - g_properties[PROP_CONTRAST] = - g_param_spec_float(GST_VAAPI_DISPLAY_PROP_CONTRAST, - "contrast", - "The display contrast value", - 0.0, 2.0, 1.0, - G_PARAM_READWRITE); + /** + * GstVaapiDisplay:contrast: + * + * The VA display contrast, expressed as a float value. Range is 0.0 + * to 2.0. Default value is 1.0 and represents no modification. + */ + g_properties[PROP_CONTRAST] = + g_param_spec_float (GST_VAAPI_DISPLAY_PROP_CONTRAST, + "contrast", + "The display contrast value", 0.0, 2.0, 1.0, G_PARAM_READWRITE); } static inline const GstVaapiDisplayClass * -gst_vaapi_display_class(void) +gst_vaapi_display_class (void) { - static GstVaapiDisplayClass g_class; - static gsize g_class_init = FALSE; + static GstVaapiDisplayClass g_class; + static gsize g_class_init = FALSE; - if (g_once_init_enter(&g_class_init)) { - gst_vaapi_display_class_init(&g_class); - g_once_init_leave(&g_class_init, TRUE); - } - return &g_class; + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_display_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return &g_class; } GstVaapiDisplay * -gst_vaapi_display_new(const GstVaapiDisplayClass *klass, +gst_vaapi_display_new (const GstVaapiDisplayClass * klass, GstVaapiDisplayInitType init_type, gpointer init_value) { - GstVaapiDisplay *display; + GstVaapiDisplay *display; - display = (GstVaapiDisplay *) - gst_vaapi_mini_object_new0(GST_VAAPI_MINI_OBJECT_CLASS(klass)); - if (!display) - return NULL; + display = (GstVaapiDisplay *) + gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS (klass)); + if (!display) + return NULL; - gst_vaapi_display_init(display); - if (!gst_vaapi_display_create(display, init_type, init_value)) - goto error; - return display; + gst_vaapi_display_init (display); + if (!gst_vaapi_display_create (display, init_type, init_value)) + goto error; + return display; error: - gst_vaapi_display_unref_internal(display); - return NULL; + gst_vaapi_display_unref_internal (display); + return NULL; } /** @@ -1041,20 +1019,20 @@ error: * Return value: the newly created #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_display_new_with_display(VADisplay va_display) +gst_vaapi_display_new_with_display (VADisplay va_display) { - GstVaapiDisplayCache * const cache = get_display_cache(); - const GstVaapiDisplayInfo *info; + GstVaapiDisplayCache *const cache = get_display_cache (); + const GstVaapiDisplayInfo *info; - g_return_val_if_fail(va_display != NULL, NULL); - g_return_val_if_fail(cache != NULL, NULL); + g_return_val_if_fail (va_display != NULL, NULL); + g_return_val_if_fail (cache != NULL, NULL); - info = gst_vaapi_display_cache_lookup_by_va_display(cache, va_display); - if (info) - return gst_vaapi_display_ref_internal(info->display); + info = gst_vaapi_display_cache_lookup_by_va_display (cache, va_display); + if (info) + return gst_vaapi_display_ref_internal (info->display); - return gst_vaapi_display_new(gst_vaapi_display_class(), - GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, va_display); + return gst_vaapi_display_new (gst_vaapi_display_class (), + GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, va_display); } /** @@ -1066,9 +1044,9 @@ gst_vaapi_display_new_with_display(VADisplay va_display) * Returns: The same @display argument */ GstVaapiDisplay * -gst_vaapi_display_ref(GstVaapiDisplay *display) +gst_vaapi_display_ref (GstVaapiDisplay * display) { - return gst_vaapi_display_ref_internal(display); + return gst_vaapi_display_ref_internal (display); } /** @@ -1079,9 +1057,9 @@ gst_vaapi_display_ref(GstVaapiDisplay *display) * the reference count reaches zero, the display will be free'd. */ void -gst_vaapi_display_unref(GstVaapiDisplay *display) +gst_vaapi_display_unref (GstVaapiDisplay * display) { - gst_vaapi_display_unref_internal(display); + gst_vaapi_display_unref_internal (display); } /** @@ -1094,10 +1072,10 @@ gst_vaapi_display_unref(GstVaapiDisplay *display) * a valid display. However, @new_display can be NULL. */ void -gst_vaapi_display_replace(GstVaapiDisplay **old_display_ptr, - GstVaapiDisplay *new_display) +gst_vaapi_display_replace (GstVaapiDisplay ** old_display_ptr, + GstVaapiDisplay * new_display) { - gst_vaapi_display_replace_internal(old_display_ptr, new_display); + gst_vaapi_display_replace_internal (old_display_ptr, new_display); } /** @@ -1109,15 +1087,15 @@ gst_vaapi_display_replace(GstVaapiDisplay **old_display_ptr, * other thread. */ void -gst_vaapi_display_lock(GstVaapiDisplay *display) +gst_vaapi_display_lock (GstVaapiDisplay * display) { - GstVaapiDisplayClass *klass; + GstVaapiDisplayClass *klass; - g_return_if_fail(display != NULL); + g_return_if_fail (display != NULL); - klass = GST_VAAPI_DISPLAY_GET_CLASS(display); - if (klass->lock) - klass->lock(display); + klass = GST_VAAPI_DISPLAY_GET_CLASS (display); + if (klass->lock) + klass->lock (display); } /** @@ -1129,15 +1107,15 @@ gst_vaapi_display_lock(GstVaapiDisplay *display) * can lock @display itself. */ void -gst_vaapi_display_unlock(GstVaapiDisplay *display) +gst_vaapi_display_unlock (GstVaapiDisplay * display) { - GstVaapiDisplayClass *klass; + GstVaapiDisplayClass *klass; - g_return_if_fail(display != NULL); + g_return_if_fail (display != NULL); - klass = GST_VAAPI_DISPLAY_GET_CLASS(display); - if (klass->unlock) - klass->unlock(display); + klass = GST_VAAPI_DISPLAY_GET_CLASS (display); + if (klass->unlock) + klass->unlock (display); } /** @@ -1152,17 +1130,17 @@ gst_vaapi_display_unlock(GstVaapiDisplay *display) * handled synchronously, this function will do nothing. */ void -gst_vaapi_display_sync(GstVaapiDisplay *display) +gst_vaapi_display_sync (GstVaapiDisplay * display) { - GstVaapiDisplayClass *klass; + GstVaapiDisplayClass *klass; - g_return_if_fail(display != NULL); + g_return_if_fail (display != NULL); - klass = GST_VAAPI_DISPLAY_GET_CLASS(display); - if (klass->sync) - klass->sync(display); - else if (klass->flush) - klass->flush(display); + klass = GST_VAAPI_DISPLAY_GET_CLASS (display); + if (klass->sync) + klass->sync (display); + else if (klass->flush) + klass->flush (display); } /** @@ -1175,15 +1153,15 @@ gst_vaapi_display_sync(GstVaapiDisplay *display) * are handled synchronously, this function will do nothing. */ void -gst_vaapi_display_flush(GstVaapiDisplay *display) +gst_vaapi_display_flush (GstVaapiDisplay * display) { - GstVaapiDisplayClass *klass; + GstVaapiDisplayClass *klass; - g_return_if_fail(display != NULL); + g_return_if_fail (display != NULL); - klass = GST_VAAPI_DISPLAY_GET_CLASS(display); - if (klass->flush) - klass->flush(display); + klass = GST_VAAPI_DISPLAY_GET_CLASS (display); + if (klass->flush) + klass->flush (display); } /** @@ -1195,11 +1173,11 @@ gst_vaapi_display_flush(GstVaapiDisplay *display) * Return value: the #GstVaapiDisplayType */ GstVaapiDisplayType -gst_vaapi_display_get_display_type(GstVaapiDisplay *display) +gst_vaapi_display_get_display_type (GstVaapiDisplay * display) { - g_return_val_if_fail(display != NULL, GST_VAAPI_DISPLAY_TYPE_ANY); + g_return_val_if_fail (display != NULL, GST_VAAPI_DISPLAY_TYPE_ANY); - return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->display_type; + return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display_type; } /** @@ -1211,11 +1189,11 @@ gst_vaapi_display_get_display_type(GstVaapiDisplay *display) * Return value: the #VADisplay */ VADisplay -gst_vaapi_display_get_display(GstVaapiDisplay *display) +gst_vaapi_display_get_display (GstVaapiDisplay * display) { - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail (display != NULL, NULL); - return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->display; + return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display; } /** @@ -1227,11 +1205,11 @@ gst_vaapi_display_get_display(GstVaapiDisplay *display) * Return value: the width of the @display, in pixels */ guint -gst_vaapi_display_get_width(GstVaapiDisplay *display) +gst_vaapi_display_get_width (GstVaapiDisplay * display) { - g_return_val_if_fail(display != NULL, 0); + g_return_val_if_fail (display != NULL, 0); - return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->width; + return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->width; } /** @@ -1243,11 +1221,11 @@ gst_vaapi_display_get_width(GstVaapiDisplay *display) * Return value: the height of the @display, in pixels */ guint -gst_vaapi_display_get_height(GstVaapiDisplay *display) +gst_vaapi_display_get_height (GstVaapiDisplay * display) { - g_return_val_if_fail(display != NULL, 0); + g_return_val_if_fail (display != NULL, 0); - return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->height; + return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->height; } /** @@ -1259,15 +1237,16 @@ gst_vaapi_display_get_height(GstVaapiDisplay *display) * Retrieves the dimensions of a #GstVaapiDisplay. */ void -gst_vaapi_display_get_size(GstVaapiDisplay *display, guint *pwidth, guint *pheight) +gst_vaapi_display_get_size (GstVaapiDisplay * display, guint * pwidth, + guint * pheight) { - g_return_if_fail(GST_VAAPI_DISPLAY(display)); + g_return_if_fail (GST_VAAPI_DISPLAY (display)); - if (pwidth) - *pwidth = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->width; + if (pwidth) + *pwidth = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->width; - if (pheight) - *pheight = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->height; + if (pheight) + *pheight = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->height; } /** @@ -1279,19 +1258,16 @@ gst_vaapi_display_get_size(GstVaapiDisplay *display, guint *pwidth, guint *pheig * Retrieves the pixel aspect ratio of a #GstVaapiDisplay. */ void -gst_vaapi_display_get_pixel_aspect_ratio( - GstVaapiDisplay *display, - guint *par_n, - guint *par_d -) +gst_vaapi_display_get_pixel_aspect_ratio (GstVaapiDisplay * display, + guint * par_n, guint * par_d) { - g_return_if_fail(display != NULL); + g_return_if_fail (display != NULL); - if (par_n) - *par_n = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->par_n; + if (par_n) + *par_n = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->par_n; - if (par_d) - *par_d = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->par_d; + if (par_d) + *par_d = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->par_d; } /** @@ -1303,11 +1279,11 @@ gst_vaapi_display_get_pixel_aspect_ratio( * Return value: a newly allocated #GstCaps object, possibly empty */ GstCaps * -gst_vaapi_display_get_decode_caps(GstVaapiDisplay *display) +gst_vaapi_display_get_decode_caps (GstVaapiDisplay * display) { - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail (display != NULL, NULL); - return get_profile_caps(GST_VAAPI_DISPLAY_GET_PRIVATE(display)->decoders); + return get_profile_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders); } /** @@ -1322,16 +1298,13 @@ gst_vaapi_display_get_decode_caps(GstVaapiDisplay *display) * Return value: %TRUE if VA @display supports @profile for decoding. */ gboolean -gst_vaapi_display_has_decoder( - GstVaapiDisplay *display, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint -) +gst_vaapi_display_has_decoder (GstVaapiDisplay * display, + GstVaapiProfile profile, GstVaapiEntrypoint entrypoint) { - g_return_val_if_fail(display != NULL, FALSE); + g_return_val_if_fail (display != NULL, FALSE); - return find_config( - GST_VAAPI_DISPLAY_GET_PRIVATE(display)->decoders, profile, entrypoint); + return find_config (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders, + profile, entrypoint); } /** @@ -1343,11 +1316,11 @@ gst_vaapi_display_has_decoder( * Return value: a newly allocated #GstCaps object, possibly empty */ GstCaps * -gst_vaapi_display_get_encode_caps(GstVaapiDisplay *display) +gst_vaapi_display_get_encode_caps (GstVaapiDisplay * display) { - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail (display != NULL, NULL); - return get_profile_caps(GST_VAAPI_DISPLAY_GET_PRIVATE(display)->encoders); + return get_profile_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders); } /** @@ -1362,16 +1335,13 @@ gst_vaapi_display_get_encode_caps(GstVaapiDisplay *display) * Return value: %TRUE if VA @display supports @profile for encoding. */ gboolean -gst_vaapi_display_has_encoder( - GstVaapiDisplay *display, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint -) +gst_vaapi_display_has_encoder (GstVaapiDisplay * display, + GstVaapiProfile profile, GstVaapiEntrypoint entrypoint) { - g_return_val_if_fail(display != NULL, FALSE); + g_return_val_if_fail (display != NULL, FALSE); - return find_config( - GST_VAAPI_DISPLAY_GET_PRIVATE(display)->encoders, profile, entrypoint); + return find_config (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders, + profile, entrypoint); } /** @@ -1391,12 +1361,12 @@ gst_vaapi_display_has_encoder( * Return value: a newly allocated #GstCaps object, possibly empty */ GstCaps * -gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) +gst_vaapi_display_get_image_caps (GstVaapiDisplay * display) { - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail (display != NULL, NULL); - return get_format_caps( - GST_VAAPI_DISPLAY_GET_PRIVATE(display)->image_formats); + return get_format_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> + image_formats); } /** @@ -1409,24 +1379,22 @@ gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) * Return value: %TRUE if VA @display supports @format image format */ gboolean -gst_vaapi_display_has_image_format( - GstVaapiDisplay *display, - GstVideoFormat format -) +gst_vaapi_display_has_image_format (GstVaapiDisplay * display, + GstVideoFormat format) { - g_return_val_if_fail(display != NULL, FALSE); - g_return_val_if_fail(format, FALSE); + g_return_val_if_fail (display != NULL, FALSE); + g_return_val_if_fail (format, FALSE); - if (find_format( - GST_VAAPI_DISPLAY_GET_PRIVATE(display)->image_formats, format)) - return TRUE; + if (find_format (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->image_formats, + format)) + return TRUE; - /* XXX: try subpicture formats since some drivers could report a - * set of VA image formats that is not a superset of the set of VA - * subpicture formats - */ - return find_format( - GST_VAAPI_DISPLAY_GET_PRIVATE(display)->subpicture_formats, format); + /* XXX: try subpicture formats since some drivers could report a + * set of VA image formats that is not a superset of the set of VA + * subpicture formats + */ + return find_format (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> + subpicture_formats, format); } /** @@ -1443,12 +1411,12 @@ gst_vaapi_display_has_image_format( * Return value: a newly allocated #GstCaps object, possibly empty */ GstCaps * -gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) +gst_vaapi_display_get_subpicture_caps (GstVaapiDisplay * display) { - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail (display != NULL, NULL); - return get_format_caps( - GST_VAAPI_DISPLAY_GET_PRIVATE(display)->subpicture_formats); + return get_format_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> + subpicture_formats); } /** @@ -1463,25 +1431,23 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) * Return value: %TRUE if VA @display supports @format subpicture format */ gboolean -gst_vaapi_display_has_subpicture_format( - GstVaapiDisplay *display, - GstVideoFormat format, - guint *flags_ptr -) +gst_vaapi_display_has_subpicture_format (GstVaapiDisplay * display, + GstVideoFormat format, guint * flags_ptr) { - const GstVaapiFormatInfo *fip; + const GstVaapiFormatInfo *fip; - g_return_val_if_fail(display != NULL, FALSE); - g_return_val_if_fail(format, FALSE); + g_return_val_if_fail (display != NULL, FALSE); + g_return_val_if_fail (format, FALSE); - fip = find_format_info( - GST_VAAPI_DISPLAY_GET_PRIVATE(display)->subpicture_formats, format); - if (!fip) - return FALSE; + fip = + find_format_info (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> + subpicture_formats, format); + if (!fip) + return FALSE; - if (flags_ptr) - *flags_ptr = fip->flags; - return TRUE; + if (flags_ptr) + *flags_ptr = fip->flags; + return TRUE; } /** @@ -1497,219 +1463,210 @@ gst_vaapi_display_has_subpicture_format( * Return value: %TRUE if VA @display supports property @name */ gboolean -gst_vaapi_display_has_property(GstVaapiDisplay *display, const gchar *name) +gst_vaapi_display_has_property (GstVaapiDisplay * display, const gchar * name) { - g_return_val_if_fail(display != NULL, FALSE); - g_return_val_if_fail(name, FALSE); + g_return_val_if_fail (display != NULL, FALSE); + g_return_val_if_fail (name, FALSE); - return find_property( - GST_VAAPI_DISPLAY_GET_PRIVATE(display)->properties, name) != NULL; + return find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, + name) != NULL; } gboolean -gst_vaapi_display_get_property(GstVaapiDisplay *display, const gchar *name, - GValue *out_value) +gst_vaapi_display_get_property (GstVaapiDisplay * display, const gchar * name, + GValue * out_value) { - const GstVaapiProperty *prop; + const GstVaapiProperty *prop; - g_return_val_if_fail(display != NULL, FALSE); - g_return_val_if_fail(name != NULL, FALSE); - g_return_val_if_fail(out_value != NULL, FALSE); + g_return_val_if_fail (display != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + g_return_val_if_fail (out_value != NULL, FALSE); - prop = find_property( - GST_VAAPI_DISPLAY_GET_PRIVATE(display)->properties, name); - if (!prop) - return FALSE; - - switch (prop->attribute.type) { - case VADisplayAttribRenderMode: { - GstVaapiRenderMode mode; - if (!gst_vaapi_display_get_render_mode(display, &mode)) - return FALSE; - g_value_init(out_value, GST_VAAPI_TYPE_RENDER_MODE); - g_value_set_enum(out_value, mode); - break; - } - case VADisplayAttribRotation: { - GstVaapiRotation rotation; - rotation = gst_vaapi_display_get_rotation(display); - g_value_init(out_value, GST_VAAPI_TYPE_ROTATION); - g_value_set_enum(out_value, rotation); - break; - } - case VADisplayAttribHue: - case VADisplayAttribSaturation: - case VADisplayAttribBrightness: - case VADisplayAttribContrast: { - gfloat value; - if (!get_color_balance(display, find_property_id(name), &value)) - return FALSE; - g_value_init(out_value, G_TYPE_FLOAT); - g_value_set_float(out_value, value); - break; - } - default: - GST_WARNING("unsupported property '%s'", name); - return FALSE; - } - return TRUE; -} - -gboolean -gst_vaapi_display_set_property(GstVaapiDisplay *display, const gchar *name, - const GValue *value) -{ - const GstVaapiProperty *prop; - - g_return_val_if_fail(display != NULL, FALSE); - g_return_val_if_fail(name != NULL, FALSE); - g_return_val_if_fail(value != NULL, FALSE); - - prop = find_property( - GST_VAAPI_DISPLAY_GET_PRIVATE(display)->properties, name); - if (!prop) - return FALSE; - - switch (prop->attribute.type) { - case VADisplayAttribRenderMode: { - GstVaapiRenderMode mode; - if (!G_VALUE_HOLDS(value, GST_VAAPI_TYPE_RENDER_MODE)) - return FALSE; - mode = g_value_get_enum(value); - return gst_vaapi_display_set_render_mode(display, mode); - } - case VADisplayAttribRotation: { - GstVaapiRotation rotation; - if (!G_VALUE_HOLDS(value, GST_VAAPI_TYPE_ROTATION)) - return FALSE; - rotation = g_value_get_enum(value); - return gst_vaapi_display_set_rotation(display, rotation); - } - case VADisplayAttribHue: - case VADisplayAttribSaturation: - case VADisplayAttribBrightness: - case VADisplayAttribContrast: { - gfloat v; - if (!G_VALUE_HOLDS(value, G_TYPE_FLOAT)) - return FALSE; - v = g_value_get_float(value); - return set_color_balance(display, find_property_id(name), v); - } - default: - break; - } - - GST_WARNING("unsupported property '%s'", name); + prop = + find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, name); + if (!prop) return FALSE; + + switch (prop->attribute.type) { + case VADisplayAttribRenderMode:{ + GstVaapiRenderMode mode; + if (!gst_vaapi_display_get_render_mode (display, &mode)) + return FALSE; + g_value_init (out_value, GST_VAAPI_TYPE_RENDER_MODE); + g_value_set_enum (out_value, mode); + break; + } + case VADisplayAttribRotation:{ + GstVaapiRotation rotation; + rotation = gst_vaapi_display_get_rotation (display); + g_value_init (out_value, GST_VAAPI_TYPE_ROTATION); + g_value_set_enum (out_value, rotation); + break; + } + case VADisplayAttribHue: + case VADisplayAttribSaturation: + case VADisplayAttribBrightness: + case VADisplayAttribContrast:{ + gfloat value; + if (!get_color_balance (display, find_property_id (name), &value)) + return FALSE; + g_value_init (out_value, G_TYPE_FLOAT); + g_value_set_float (out_value, value); + break; + } + default: + GST_WARNING ("unsupported property '%s'", name); + return FALSE; + } + return TRUE; } -static gboolean -get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value) +gboolean +gst_vaapi_display_set_property (GstVaapiDisplay * display, const gchar * name, + const GValue * value) { - GstVaapiDisplayPrivate * const priv = - GST_VAAPI_DISPLAY_GET_PRIVATE(display); - VADisplayAttribute attr; - VAStatus status; + const GstVaapiProperty *prop; - attr.type = type; - attr.flags = VA_DISPLAY_ATTRIB_GETTABLE; - status = vaGetDisplayAttributes(priv->display, &attr, 1); - if (!vaapi_check_status(status, "vaGetDisplayAttributes()")) + g_return_val_if_fail (display != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + prop = + find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, name); + if (!prop) + return FALSE; + + switch (prop->attribute.type) { + case VADisplayAttribRenderMode:{ + GstVaapiRenderMode mode; + if (!G_VALUE_HOLDS (value, GST_VAAPI_TYPE_RENDER_MODE)) return FALSE; - *value = attr.value; - return TRUE; + mode = g_value_get_enum (value); + return gst_vaapi_display_set_render_mode (display, mode); + } + case VADisplayAttribRotation:{ + GstVaapiRotation rotation; + if (!G_VALUE_HOLDS (value, GST_VAAPI_TYPE_ROTATION)) + return FALSE; + rotation = g_value_get_enum (value); + return gst_vaapi_display_set_rotation (display, rotation); + } + case VADisplayAttribHue: + case VADisplayAttribSaturation: + case VADisplayAttribBrightness: + case VADisplayAttribContrast:{ + gfloat v; + if (!G_VALUE_HOLDS (value, G_TYPE_FLOAT)) + return FALSE; + v = g_value_get_float (value); + return set_color_balance (display, find_property_id (name), v); + } + default: + break; + } + + GST_WARNING ("unsupported property '%s'", name); + return FALSE; } static gboolean -set_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint value) +get_attribute (GstVaapiDisplay * display, VADisplayAttribType type, + gint * value) { - GstVaapiDisplayPrivate * const priv = - GST_VAAPI_DISPLAY_GET_PRIVATE(display); - VADisplayAttribute attr; - VAStatus status; + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + VADisplayAttribute attr; + VAStatus status; - attr.type = type; - attr.value = value; - attr.flags = VA_DISPLAY_ATTRIB_SETTABLE; - status = vaSetDisplayAttributes(priv->display, &attr, 1); - if (!vaapi_check_status(status, "vaSetDisplayAttributes()")) - return FALSE; - return TRUE; + attr.type = type; + attr.flags = VA_DISPLAY_ATTRIB_GETTABLE; + status = vaGetDisplayAttributes (priv->display, &attr, 1); + if (!vaapi_check_status (status, "vaGetDisplayAttributes()")) + return FALSE; + *value = attr.value; + return TRUE; } static gboolean -get_render_mode_VADisplayAttribRenderMode( - GstVaapiDisplay *display, - GstVaapiRenderMode *pmode -) +set_attribute (GstVaapiDisplay * display, VADisplayAttribType type, gint value) { - gint modes, devices; + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + VADisplayAttribute attr; + VAStatus status; - if (!get_attribute(display, VADisplayAttribRenderDevice, &devices)) - return FALSE; - if (!devices) - return FALSE; - if (!get_attribute(display, VADisplayAttribRenderMode, &modes)) - return FALSE; - - /* Favor "overlay" mode since it is the most restrictive one */ - if (modes & (VA_RENDER_MODE_LOCAL_OVERLAY|VA_RENDER_MODE_EXTERNAL_OVERLAY)) - *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; - else - *pmode = GST_VAAPI_RENDER_MODE_TEXTURE; - return TRUE; + attr.type = type; + attr.value = value; + attr.flags = VA_DISPLAY_ATTRIB_SETTABLE; + status = vaSetDisplayAttributes (priv->display, &attr, 1); + if (!vaapi_check_status (status, "vaSetDisplayAttributes()")) + return FALSE; + return TRUE; } static gboolean -get_render_mode_VADisplayAttribDirectSurface( - GstVaapiDisplay *display, - GstVaapiRenderMode *pmode -) +get_render_mode_VADisplayAttribRenderMode (GstVaapiDisplay * display, + GstVaapiRenderMode * pmode) +{ + gint modes, devices; + + if (!get_attribute (display, VADisplayAttribRenderDevice, &devices)) + return FALSE; + if (!devices) + return FALSE; + if (!get_attribute (display, VADisplayAttribRenderMode, &modes)) + return FALSE; + + /* Favor "overlay" mode since it is the most restrictive one */ + if (modes & (VA_RENDER_MODE_LOCAL_OVERLAY | VA_RENDER_MODE_EXTERNAL_OVERLAY)) + *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; + else + *pmode = GST_VAAPI_RENDER_MODE_TEXTURE; + return TRUE; +} + +static gboolean +get_render_mode_VADisplayAttribDirectSurface (GstVaapiDisplay * display, + GstVaapiRenderMode * pmode) { #if VA_CHECK_VERSION(0,34,0) - /* VADisplayAttribDirectsurface was removed in VA-API >= 0.34.0 */ - return FALSE; + /* VADisplayAttribDirectsurface was removed in VA-API >= 0.34.0 */ + return FALSE; #else - gint direct_surface; + gint direct_surface; - if (!get_attribute(display, VADisplayAttribDirectSurface, &direct_surface)) - return FALSE; - if (direct_surface) - *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; - else - *pmode = GST_VAAPI_RENDER_MODE_TEXTURE; - return TRUE; + if (!get_attribute (display, VADisplayAttribDirectSurface, &direct_surface)) + return FALSE; + if (direct_surface) + *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; + else + *pmode = GST_VAAPI_RENDER_MODE_TEXTURE; + return TRUE; #endif } static gboolean -get_render_mode_default( - GstVaapiDisplay *display, - GstVaapiRenderMode *pmode -) +get_render_mode_default (GstVaapiDisplay * display, GstVaapiRenderMode * pmode) { - GstVaapiDisplayPrivate * const priv = - GST_VAAPI_DISPLAY_GET_PRIVATE(display); + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - switch (priv->display_type) { + switch (priv->display_type) { #if USE_WAYLAND case GST_VAAPI_DISPLAY_TYPE_WAYLAND: - /* wl_buffer mapped from VA surface through vaGetSurfaceBufferWl() */ - *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; - break; + /* wl_buffer mapped from VA surface through vaGetSurfaceBufferWl() */ + *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; + break; #endif #if USE_DRM case GST_VAAPI_DISPLAY_TYPE_DRM: - /* vaGetSurfaceBufferDRM() returns the underlying DRM buffer handle */ - *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; - break; + /* vaGetSurfaceBufferDRM() returns the underlying DRM buffer handle */ + *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; + break; #endif default: - /* This includes VA/X11 and VA/GLX modes */ - *pmode = DEFAULT_RENDER_MODE; - break; - } - return TRUE; + /* This includes VA/X11 and VA/GLX modes */ + *pmode = DEFAULT_RENDER_MODE; + break; + } + return TRUE; } /** @@ -1722,23 +1679,21 @@ get_render_mode_default( * Return value: %TRUE if VA @display rendering mode could be determined */ gboolean -gst_vaapi_display_get_render_mode( - GstVaapiDisplay *display, - GstVaapiRenderMode *pmode -) +gst_vaapi_display_get_render_mode (GstVaapiDisplay * display, + GstVaapiRenderMode * pmode) { - g_return_val_if_fail(display != NULL, FALSE); + g_return_val_if_fail (display != NULL, FALSE); - /* Try with render-mode attribute */ - if (get_render_mode_VADisplayAttribRenderMode(display, pmode)) - return TRUE; + /* Try with render-mode attribute */ + if (get_render_mode_VADisplayAttribRenderMode (display, pmode)) + return TRUE; - /* Try with direct-surface attribute */ - if (get_render_mode_VADisplayAttribDirectSurface(display, pmode)) - return TRUE; + /* Try with direct-surface attribute */ + if (get_render_mode_VADisplayAttribDirectSurface (display, pmode)) + return TRUE; - /* Default: determine from the display type */ - return get_render_mode_default(display, pmode); + /* Default: determine from the display type */ + return get_render_mode_default (display, pmode); } /** @@ -1754,38 +1709,36 @@ gst_vaapi_display_get_render_mode( * to the requested value */ gboolean -gst_vaapi_display_set_render_mode( - GstVaapiDisplay *display, - GstVaapiRenderMode mode -) +gst_vaapi_display_set_render_mode (GstVaapiDisplay * display, + GstVaapiRenderMode mode) { - gint modes, devices; + gint modes, devices; - g_return_val_if_fail(display != NULL, FALSE); + g_return_val_if_fail (display != NULL, FALSE); - if (!get_attribute(display, VADisplayAttribRenderDevice, &devices)) - return FALSE; + if (!get_attribute (display, VADisplayAttribRenderDevice, &devices)) + return FALSE; - modes = 0; - switch (mode) { + modes = 0; + switch (mode) { case GST_VAAPI_RENDER_MODE_OVERLAY: - if (devices & VA_RENDER_DEVICE_LOCAL) - modes |= VA_RENDER_MODE_LOCAL_OVERLAY; - if (devices & VA_RENDER_DEVICE_EXTERNAL) - modes |= VA_RENDER_MODE_EXTERNAL_OVERLAY; - break; + if (devices & VA_RENDER_DEVICE_LOCAL) + modes |= VA_RENDER_MODE_LOCAL_OVERLAY; + if (devices & VA_RENDER_DEVICE_EXTERNAL) + modes |= VA_RENDER_MODE_EXTERNAL_OVERLAY; + break; case GST_VAAPI_RENDER_MODE_TEXTURE: - if (devices & VA_RENDER_DEVICE_LOCAL) - modes |= VA_RENDER_MODE_LOCAL_GPU; - if (devices & VA_RENDER_DEVICE_EXTERNAL) - modes |= VA_RENDER_MODE_EXTERNAL_GPU; - break; - } - if (!modes) - return FALSE; - if (!set_attribute(display, VADisplayAttribRenderMode, modes)) - return FALSE; - return TRUE; + if (devices & VA_RENDER_DEVICE_LOCAL) + modes |= VA_RENDER_MODE_LOCAL_GPU; + if (devices & VA_RENDER_DEVICE_EXTERNAL) + modes |= VA_RENDER_MODE_EXTERNAL_GPU; + break; + } + if (!modes) + return FALSE; + if (!set_attribute (display, VADisplayAttribRenderMode, modes)) + return FALSE; + return TRUE; } /** @@ -1799,15 +1752,15 @@ gst_vaapi_display_set_render_mode( * Return value: the current #GstVaapiRotation value */ GstVaapiRotation -gst_vaapi_display_get_rotation(GstVaapiDisplay *display) +gst_vaapi_display_get_rotation (GstVaapiDisplay * display) { - gint value; + gint value; - g_return_val_if_fail(display != NULL, DEFAULT_ROTATION); + g_return_val_if_fail (display != NULL, DEFAULT_ROTATION); - if (!get_attribute(display, VADisplayAttribRotation, &value)) - value = VA_ROTATION_NONE; - return to_GstVaapiRotation(value); + if (!get_attribute (display, VADisplayAttribRotation, &value)) + value = VA_ROTATION_NONE; + return to_GstVaapiRotation (value); } /** @@ -1824,84 +1777,82 @@ gst_vaapi_display_get_rotation(GstVaapiDisplay *display) * to the requested value */ gboolean -gst_vaapi_display_set_rotation( - GstVaapiDisplay *display, - GstVaapiRotation rotation -) +gst_vaapi_display_set_rotation (GstVaapiDisplay * display, + GstVaapiRotation rotation) { - guint value; + guint value; - g_return_val_if_fail(display != NULL, FALSE); + g_return_val_if_fail (display != NULL, FALSE); - value = from_GstVaapiRotation(rotation); - if (!set_attribute(display, VADisplayAttribRotation, value)) - return FALSE; - return TRUE; + value = from_GstVaapiRotation (rotation); + if (!set_attribute (display, VADisplayAttribRotation, value)) + return FALSE; + return TRUE; } /* Get color balance attributes */ static gboolean -get_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat *v) +get_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat * v) { - GParamSpecFloat * const pspec = G_PARAM_SPEC_FLOAT(g_properties[prop_id]); - const GstVaapiProperty *prop; - const VADisplayAttribute *attr; - gfloat out_value; - gint value; + GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (g_properties[prop_id]); + const GstVaapiProperty *prop; + const VADisplayAttribute *attr; + gfloat out_value; + gint value; - if (!pspec) - return FALSE; + if (!pspec) + return FALSE; - prop = find_property_by_pspec(display, &pspec->parent_instance); - if (!prop) - return FALSE; - attr = &prop->attribute; + prop = find_property_by_pspec (display, &pspec->parent_instance); + if (!prop) + return FALSE; + attr = &prop->attribute; - if (!get_attribute(display, attr->type, &value)) - return FALSE; + if (!get_attribute (display, attr->type, &value)) + return FALSE; - /* Scale wrt. the medium ("default") value */ - out_value = pspec->default_value; - if (value > attr->value) - out_value += ((gfloat)(value - attr->value) / - (attr->max_value - attr->value) * - (pspec->maximum - pspec->default_value)); - else if (value < attr->value) - out_value -= ((gfloat)(attr->value - value) / - (attr->value - attr->min_value) * - (pspec->default_value - pspec->minimum)); - *v = out_value; - return TRUE; + /* Scale wrt. the medium ("default") value */ + out_value = pspec->default_value; + if (value > attr->value) + out_value += ((gfloat) (value - attr->value) / + (attr->max_value - attr->value) * + (pspec->maximum - pspec->default_value)); + else if (value < attr->value) + out_value -= ((gfloat) (attr->value - value) / + (attr->value - attr->min_value) * + (pspec->default_value - pspec->minimum)); + *v = out_value; + return TRUE; } /* Set color balance attribute */ static gboolean -set_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat v) +set_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat v) { - GParamSpecFloat * const pspec = G_PARAM_SPEC_FLOAT(g_properties[prop_id]); - const GstVaapiProperty *prop; - const VADisplayAttribute *attr; - gint value; + GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (g_properties[prop_id]); + const GstVaapiProperty *prop; + const VADisplayAttribute *attr; + gint value; - if (!pspec) - return FALSE; + if (!pspec) + return FALSE; - prop = find_property_by_pspec(display, &pspec->parent_instance); - if (!prop) - return FALSE; - attr = &prop->attribute; + prop = find_property_by_pspec (display, &pspec->parent_instance); + if (!prop) + return FALSE; + attr = &prop->attribute; - /* Scale wrt. the medium ("default") value */ - value = attr->value; - if (v > pspec->default_value) - value += ((v - pspec->default_value) / - (pspec->maximum - pspec->default_value) * - (attr->max_value - attr->value)); - else if (v < pspec->default_value) - value -= ((pspec->default_value - v) / - (pspec->default_value - pspec->minimum) * - (attr->value - attr->min_value)); - if (!set_attribute(display, attr->type, value)) - return FALSE; - return TRUE; + /* Scale wrt. the medium ("default") value */ + value = attr->value; + if (v > pspec->default_value) + value += ((v - pspec->default_value) / + (pspec->maximum - pspec->default_value) * + (attr->max_value - attr->value)); + else if (v < pspec->default_value) + value -= ((pspec->default_value - v) / + (pspec->default_value - pspec->minimum) * + (attr->value - attr->min_value)); + if (!set_attribute (display, attr->type, value)) + return FALSE; + return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 75cdbd3e5a..6d2383762e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -47,22 +47,23 @@ typedef struct _GstVaapiDisplay GstVaapiDisplay; * @GST_VAAPI_DISPLAY_TYPE_WAYLAND: VA/Wayland display. * @GST_VAAPI_DISPLAY_TYPE_DRM: VA/DRM 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, +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, } GstVaapiDisplayType; #define GST_VAAPI_TYPE_DISPLAY_TYPE \ (gst_vaapi_display_type_get_type()) GType -gst_vaapi_display_type_get_type(void) G_GNUC_CONST; +gst_vaapi_display_type_get_type (void) G_GNUC_CONST; gboolean -gst_vaapi_display_type_is_compatible(GstVaapiDisplayType type1, +gst_vaapi_display_type_is_compatible (GstVaapiDisplayType type1, GstVaapiDisplayType type2); /** @@ -70,12 +71,13 @@ gst_vaapi_display_type_is_compatible(GstVaapiDisplayType type1, * * Generic class to retrieve VA display info */ -struct _GstVaapiDisplayInfo { - GstVaapiDisplay *display; - GstVaapiDisplayType display_type; - gchar *display_name; - VADisplay va_display; - gpointer native_display; +struct _GstVaapiDisplayInfo +{ + GstVaapiDisplay *display; + GstVaapiDisplayType display_type; + gchar *display_name; + VADisplay va_display; + gpointer native_display; }; /** @@ -95,122 +97,103 @@ struct _GstVaapiDisplayInfo { #define GST_VAAPI_DISPLAY_PROP_CONTRAST "contrast" GstVaapiDisplay * -gst_vaapi_display_new_with_display(VADisplay va_display); +gst_vaapi_display_new_with_display (VADisplay va_display); GstVaapiDisplay * -gst_vaapi_display_ref(GstVaapiDisplay *display); +gst_vaapi_display_ref (GstVaapiDisplay * display); void -gst_vaapi_display_unref(GstVaapiDisplay *display); +gst_vaapi_display_unref (GstVaapiDisplay * display); void -gst_vaapi_display_replace(GstVaapiDisplay **old_display_ptr, - GstVaapiDisplay *new_display); +gst_vaapi_display_replace (GstVaapiDisplay ** old_display_ptr, + GstVaapiDisplay * new_display); void -gst_vaapi_display_lock(GstVaapiDisplay *display); +gst_vaapi_display_lock (GstVaapiDisplay * display); void -gst_vaapi_display_unlock(GstVaapiDisplay *display); +gst_vaapi_display_unlock (GstVaapiDisplay * display); void -gst_vaapi_display_sync(GstVaapiDisplay *display); +gst_vaapi_display_sync (GstVaapiDisplay * display); void -gst_vaapi_display_flush(GstVaapiDisplay *display); +gst_vaapi_display_flush (GstVaapiDisplay * display); GstVaapiDisplayType -gst_vaapi_display_get_display_type(GstVaapiDisplay *display); +gst_vaapi_display_get_display_type (GstVaapiDisplay * display); VADisplay -gst_vaapi_display_get_display(GstVaapiDisplay *display); +gst_vaapi_display_get_display (GstVaapiDisplay * display); guint -gst_vaapi_display_get_width(GstVaapiDisplay *display); +gst_vaapi_display_get_width (GstVaapiDisplay * display); guint -gst_vaapi_display_get_height(GstVaapiDisplay *display); +gst_vaapi_display_get_height (GstVaapiDisplay * display); void -gst_vaapi_display_get_size(GstVaapiDisplay *display, guint *pwidth, guint *pheight); +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 -); +gst_vaapi_display_get_pixel_aspect_ratio (GstVaapiDisplay * display, + guint * par_n, guint * par_d); GstCaps * -gst_vaapi_display_get_decode_caps(GstVaapiDisplay *display); +gst_vaapi_display_get_decode_caps (GstVaapiDisplay * display); gboolean -gst_vaapi_display_has_decoder( - GstVaapiDisplay *display, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint -); +gst_vaapi_display_has_decoder (GstVaapiDisplay * display, + GstVaapiProfile profile, GstVaapiEntrypoint entrypoint); GstCaps * -gst_vaapi_display_get_encode_caps(GstVaapiDisplay *display); +gst_vaapi_display_get_encode_caps (GstVaapiDisplay * display); gboolean -gst_vaapi_display_has_encoder( - GstVaapiDisplay *display, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint -); +gst_vaapi_display_has_encoder (GstVaapiDisplay * display, + GstVaapiProfile profile, GstVaapiEntrypoint entrypoint); GstCaps * -gst_vaapi_display_get_image_caps(GstVaapiDisplay *display); +gst_vaapi_display_get_image_caps (GstVaapiDisplay * display); gboolean -gst_vaapi_display_has_image_format( - GstVaapiDisplay *display, - GstVideoFormat format -); +gst_vaapi_display_has_image_format (GstVaapiDisplay * display, + GstVideoFormat format); GstCaps * -gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display); +gst_vaapi_display_get_subpicture_caps (GstVaapiDisplay * display); gboolean -gst_vaapi_display_has_subpicture_format( - GstVaapiDisplay *display, - GstVideoFormat format, - guint *flags_ptr -); +gst_vaapi_display_has_subpicture_format (GstVaapiDisplay * display, + GstVideoFormat format, guint * flags_ptr); gboolean -gst_vaapi_display_has_property(GstVaapiDisplay *display, const gchar *name); +gst_vaapi_display_has_property (GstVaapiDisplay * display, const gchar * name); gboolean -gst_vaapi_display_get_property(GstVaapiDisplay *display, const gchar *name, - GValue *out_value); +gst_vaapi_display_get_property (GstVaapiDisplay * display, const gchar * name, + GValue * out_value); gboolean -gst_vaapi_display_set_property(GstVaapiDisplay *display, const gchar *name, - const GValue *value); +gst_vaapi_display_set_property (GstVaapiDisplay * display, const gchar * name, + const GValue * value); gboolean -gst_vaapi_display_get_render_mode( - GstVaapiDisplay *display, - GstVaapiRenderMode *pmode -); +gst_vaapi_display_get_render_mode (GstVaapiDisplay * display, + GstVaapiRenderMode * pmode); gboolean -gst_vaapi_display_set_render_mode( - GstVaapiDisplay *display, - GstVaapiRenderMode mode -); +gst_vaapi_display_set_render_mode (GstVaapiDisplay * display, + GstVaapiRenderMode mode); GstVaapiRotation -gst_vaapi_display_get_rotation(GstVaapiDisplay *display); +gst_vaapi_display_get_rotation (GstVaapiDisplay * display); gboolean -gst_vaapi_display_set_rotation( - GstVaapiDisplay *display, - GstVaapiRotation rotation -); +gst_vaapi_display_set_rotation (GstVaapiDisplay * display, + GstVaapiRotation rotation); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 46600a270d..da4fe2a1a9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -44,298 +44,298 @@ static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_DRM; /* Get default device path. Actually, the first match in the DRM subsystem */ static const gchar * -get_default_device_path(GstVaapiDisplay *display) +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; - int fd; + 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; + int fd; - if (!priv->device_path_default) { - udev = udev_new(); - if (!udev) - goto end; + if (!priv->device_path_default) { + udev = udev_new (); + if (!udev) + goto end; - e = udev_enumerate_new(udev); - if (!e) - goto end; + e = udev_enumerate_new (udev); + if (!e) + goto end; - udev_enumerate_add_match_subsystem(e, "drm"); - 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); - if (strcmp(udev_device_get_subsystem(parent), "pci") != 0) { - udev_device_unref(device); - continue; - } + udev_enumerate_add_match_subsystem (e, "drm"); + 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); + if (strcmp (udev_device_get_subsystem (parent), "pci") != 0) { + 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; - } + devpath = udev_device_get_devnode (device); + fd = open (devpath, O_RDWR | O_CLOEXEC); + if (fd < 0) { + udev_device_unref (device); + continue; + } - priv->device_path_default = g_strdup(devpath); - close(fd); - udev_device_unref(device); - break; - } - - end: - if (e) - udev_enumerate_unref(e); - if (udev) - udev_unref(udev); + priv->device_path_default = g_strdup (devpath); + close (fd); + udev_device_unref (device); + break; } - return priv->device_path_default; + + 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) +get_device_path (GstVaapiDisplay * display) { - GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM_PRIVATE(display); - const gchar *device_path = priv->device_path; + 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; + 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) +set_device_path (GstVaapiDisplay * display, const gchar * device_path) { - GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM_PRIVATE(display); + GstVaapiDisplayDRMPrivate *const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE (display); - g_free(priv->device_path); - priv->device_path = NULL; + 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; + 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) +set_device_path_from_fd (GstVaapiDisplay * display, gint drm_device) { - GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM_PRIVATE(display); - const gchar *busid, *path, *str; - gsize busid_length, path_length; - struct udev *udev = NULL; - struct udev_device *device; - struct udev_enumerate *e = NULL; - struct udev_list_entry *l; - gboolean success = FALSE; + GstVaapiDisplayDRMPrivate *const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE (display); + const gchar *busid, *path, *str; + gsize busid_length, path_length; + struct udev *udev = NULL; + struct udev_device *device; + struct udev_enumerate *e = NULL; + struct udev_list_entry *l; + gboolean success = FALSE; - g_free(priv->device_path); - priv->device_path = NULL; + g_free (priv->device_path); + priv->device_path = NULL; - if (drm_device < 0) - goto end; + if (drm_device < 0) + goto end; - busid = drmGetBusid(drm_device); - if (!busid) - goto end; - if (strncmp(busid, "pci:", 4) != 0) - goto end; - busid += 4; - busid_length = strlen(busid); + busid = drmGetBusid (drm_device); + if (!busid) + goto end; + if (strncmp (busid, "pci:", 4) != 0) + goto end; + busid += 4; + busid_length = strlen (busid); - udev = udev_new(); - if (!udev) - goto end; + udev = udev_new (); + if (!udev) + goto end; - e = udev_enumerate_new(udev); - if (!e) - goto end; + e = udev_enumerate_new (udev); + if (!e) + goto end; - udev_enumerate_add_match_subsystem(e, "drm"); - udev_enumerate_scan_devices(e); - udev_list_entry_foreach(l, udev_enumerate_get_list_entry(e)) { - path = udev_list_entry_get_name(l); - str = strstr(path, busid); - if (!str || str <= path || str[-1] != '/') - continue; + udev_enumerate_add_match_subsystem (e, "drm"); + udev_enumerate_scan_devices (e); + udev_list_entry_foreach (l, udev_enumerate_get_list_entry (e)) { + path = udev_list_entry_get_name (l); + str = strstr (path, busid); + if (!str || str <= path || str[-1] != '/') + continue; - path_length = strlen(path); - if (str + busid_length >= path + path_length) - continue; - if (strncmp(&str[busid_length], "/drm/card", 9) != 0) - continue; + path_length = strlen (path); + if (str + busid_length >= path + path_length) + continue; + if (strncmp (&str[busid_length], "/drm/card", 9) != 0) + continue; - device = udev_device_new_from_syspath(udev, path); - if (!device) - continue; + device = udev_device_new_from_syspath (udev, path); + if (!device) + continue; - path = udev_device_get_devnode(device); - priv->device_path = g_strdup(path); - udev_device_unref(device); - break; - } - success = TRUE; + path = udev_device_get_devnode (device); + priv->device_path = g_strdup (path); + udev_device_unref (device); + break; + } + success = TRUE; end: - if (e) - udev_enumerate_unref(e); - if (udev) - udev_unref(udev); - return success; + if (e) + udev_enumerate_unref (e); + if (udev) + udev_unref (udev); + return success; } static gboolean -gst_vaapi_display_drm_bind_display(GstVaapiDisplay *display, +gst_vaapi_display_drm_bind_display (GstVaapiDisplay * display, gpointer native_display) { - GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM_PRIVATE(display); + GstVaapiDisplayDRMPrivate *const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE (display); - priv->drm_device = GPOINTER_TO_INT(native_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); + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *info; + + cache = gst_vaapi_display_get_cache (); + g_return_val_if_fail (cache != NULL, FALSE); + + if (!set_device_path (display, name)) + return FALSE; + + info = gst_vaapi_display_cache_lookup_by_name (cache, priv->device_path, + GST_VAAPI_DISPLAY_TYPES (display)); + if (info) { + priv->drm_device = GPOINTER_TO_INT (info->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); - GstVaapiDisplayCache *cache; - const GstVaapiDisplayInfo *info; - - cache = gst_vaapi_display_get_cache(); - g_return_val_if_fail(cache != NULL, FALSE); - - if (!set_device_path(display, name)) - return FALSE; - - info = gst_vaapi_display_cache_lookup_by_name(cache, priv->device_path, - GST_VAAPI_DISPLAY_TYPES(display)); - if (info) { - priv->drm_device = GPOINTER_TO_INT(info->native_display); - priv->use_foreign_display = TRUE; - } - else { - 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; + } else { + 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) +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; - } - - if (priv->device_path) { - g_free(priv->device_path); - priv->device_path = NULL; - } - - if (priv->device_path_default) { - g_free(priv->device_path_default); - priv->device_path_default = NULL; - } -} - -static gboolean -gst_vaapi_display_drm_get_display_info(GstVaapiDisplay *display, - GstVaapiDisplayInfo *info) -{ - GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM_PRIVATE(display); - GstVaapiDisplayCache *cache; - const GstVaapiDisplayInfo *cached_info; - - /* Return any cached info even if child has its own VA display */ - cache = gst_vaapi_display_get_cache(); - if (!cache) - return FALSE; - cached_info = gst_vaapi_display_cache_lookup_by_native_display( - cache, GINT_TO_POINTER(priv->drm_device), - GST_VAAPI_DISPLAY_TYPES(display)); - if (cached_info) { - *info = *cached_info; - return TRUE; - } - - /* Otherwise, create VA display if there is none already */ - 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; - info->display_type = GST_VAAPI_DISPLAY_TYPE_DRM; - } - return TRUE; -} - -static void -gst_vaapi_display_drm_init(GstVaapiDisplay *display) -{ - GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM_PRIVATE(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; + } + + if (priv->device_path) { + g_free (priv->device_path); + priv->device_path = NULL; + } + + if (priv->device_path_default) { + g_free (priv->device_path_default); + priv->device_path_default = NULL; + } +} + +static gboolean +gst_vaapi_display_drm_get_display_info (GstVaapiDisplay * display, + GstVaapiDisplayInfo * info) +{ + GstVaapiDisplayDRMPrivate *const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE (display); + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *cached_info; + + /* Return any cached info even if child has its own VA display */ + cache = gst_vaapi_display_get_cache (); + if (!cache) + return FALSE; + cached_info = + gst_vaapi_display_cache_lookup_by_native_display (cache, + GINT_TO_POINTER (priv->drm_device), GST_VAAPI_DISPLAY_TYPES (display)); + if (cached_info) { + *info = *cached_info; + return TRUE; + } + + /* Otherwise, create VA display if there is none already */ + 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; + info->display_type = GST_VAAPI_DISPLAY_TYPE_DRM; + } + return TRUE; } static void -gst_vaapi_display_drm_class_init(GstVaapiDisplayDRMClass *klass) +gst_vaapi_display_drm_init (GstVaapiDisplay * display) { - GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); - GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); + GstVaapiDisplayDRMPrivate *const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE (display); - gst_vaapi_display_class_init(&klass->parent_class); + priv->drm_device = -1; +} - object_class->size = sizeof(GstVaapiDisplayDRM); - dpy_class->display_types = g_display_types; - dpy_class->init = gst_vaapi_display_drm_init; - 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; +static void +gst_vaapi_display_drm_class_init (GstVaapiDisplayDRMClass * klass) +{ + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); + + gst_vaapi_display_class_init (&klass->parent_class); + + object_class->size = sizeof (GstVaapiDisplayDRM); + dpy_class->display_types = g_display_types; + dpy_class->init = gst_vaapi_display_drm_init; + 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; } static inline const GstVaapiDisplayClass * -gst_vaapi_display_drm_class(void) +gst_vaapi_display_drm_class (void) { - static GstVaapiDisplayDRMClass g_class; - static gsize g_class_init = FALSE; + static GstVaapiDisplayDRMClass g_class; + static gsize g_class_init = FALSE; - if (g_once_init_enter(&g_class_init)) { - gst_vaapi_display_drm_class_init(&g_class); - g_once_init_leave(&g_class_init, TRUE); - } - return GST_VAAPI_DISPLAY_CLASS(&g_class); + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_display_drm_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS (&g_class); } /** @@ -353,10 +353,10 @@ gst_vaapi_display_drm_class(void) * Return value: a newly allocated #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_display_drm_new(const gchar *device_path) +gst_vaapi_display_drm_new (const gchar * device_path) { - return gst_vaapi_display_new(gst_vaapi_display_drm_class(), - GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)device_path); + return gst_vaapi_display_new (gst_vaapi_display_drm_class (), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) device_path); } /** @@ -371,12 +371,12 @@ gst_vaapi_display_drm_new(const gchar *device_path) * Return value: a newly allocated #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_display_drm_new_with_device(gint device) +gst_vaapi_display_drm_new_with_device (gint device) { - g_return_val_if_fail(device >= 0, NULL); + g_return_val_if_fail (device >= 0, NULL); - return gst_vaapi_display_new(gst_vaapi_display_drm_class(), - GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, GINT_TO_POINTER(device)); + return gst_vaapi_display_new (gst_vaapi_display_drm_class (), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, GINT_TO_POINTER (device)); } /** @@ -390,11 +390,11 @@ gst_vaapi_display_drm_new_with_device(gint device) * Return value: the DRM file descriptor attached to @display */ gint -gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display) +gst_vaapi_display_drm_get_device (GstVaapiDisplayDRM * display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), -1); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_DRM (display), -1); - return GST_VAAPI_DISPLAY_DRM_DEVICE(display); + return GST_VAAPI_DISPLAY_DRM_DEVICE (display); } /** @@ -411,9 +411,9 @@ gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display) * Return value: the DRM device path name attached to @display */ const gchar * -gst_vaapi_display_drm_get_device_path(GstVaapiDisplayDRM *display) +gst_vaapi_display_drm_get_device_path (GstVaapiDisplayDRM * display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_DRM (display), NULL); - return get_device_path(GST_VAAPI_DISPLAY_CAST(display)); + return get_device_path (GST_VAAPI_DISPLAY_CAST (display)); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h index 1fcbd677f5..88c7ca2a9b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h @@ -33,16 +33,17 @@ G_BEGIN_DECLS typedef struct _GstVaapiDisplayDRM GstVaapiDisplayDRM; GstVaapiDisplay * -gst_vaapi_display_drm_new(const gchar *device_path); +gst_vaapi_display_drm_new (const gchar * device_path); GstVaapiDisplay * -gst_vaapi_display_drm_new_with_device(gint device); +gst_vaapi_display_drm_new_with_device (gint device); gint -gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display); +gst_vaapi_display_drm_get_device (GstVaapiDisplayDRM * display); const gchar * -gst_vaapi_display_drm_get_device_path(GstVaapiDisplayDRM *display); +gst_vaapi_display_drm_get_device_path (GstVaapiDisplayDRM * + display); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h index a8cab20473..1e65fbbaaf 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h @@ -51,11 +51,12 @@ typedef struct _GstVaapiDisplayDRMClass GstVaapiDisplayDRMClass; #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? +struct _GstVaapiDisplayDRMPrivate +{ + gchar *device_path_default; + gchar *device_path; + gint drm_device; + guint use_foreign_display:1; // Foreign native_display? }; /** @@ -63,11 +64,12 @@ struct _GstVaapiDisplayDRMPrivate { * * VA/DRM display wrapper. */ -struct _GstVaapiDisplayDRM { - /*< private >*/ - GstVaapiDisplay parent_instance; +struct _GstVaapiDisplayDRM +{ + /*< private >*/ + GstVaapiDisplay parent_instance; - GstVaapiDisplayDRMPrivate priv; + GstVaapiDisplayDRMPrivate priv; }; /** @@ -75,9 +77,10 @@ struct _GstVaapiDisplayDRM { * * VA/DRM display wrapper clas. */ -struct _GstVaapiDisplayDRMClass { - /*< private >*/ - GstVaapiDisplayClass parent_class; +struct _GstVaapiDisplayDRMClass +{ + /*< private >*/ + GstVaapiDisplayClass parent_class; }; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index a024fe90b1..e80d7c2f24 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -42,47 +42,45 @@ static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_GLX; static gboolean -gst_vaapi_display_glx_get_display_info( - GstVaapiDisplay *display, - GstVaapiDisplayInfo *info -) +gst_vaapi_display_glx_get_display_info (GstVaapiDisplay * display, + GstVaapiDisplayInfo * info) { - const GstVaapiDisplayGLXClass * const klass = - GST_VAAPI_DISPLAY_GLX_GET_CLASS(display); + const GstVaapiDisplayGLXClass *const klass = + GST_VAAPI_DISPLAY_GLX_GET_CLASS (display); - info->va_display = vaGetDisplayGLX(GST_VAAPI_DISPLAY_XDISPLAY(display)); - if (!info->va_display) - return FALSE; - info->display_type = GST_VAAPI_DISPLAY_TYPE_GLX; - return klass->parent_get_display(display, info); + info->va_display = vaGetDisplayGLX (GST_VAAPI_DISPLAY_XDISPLAY (display)); + if (!info->va_display) + return FALSE; + info->display_type = GST_VAAPI_DISPLAY_TYPE_GLX; + return klass->parent_get_display (display, info); } static void -gst_vaapi_display_glx_class_init(GstVaapiDisplayGLXClass *klass) +gst_vaapi_display_glx_class_init (GstVaapiDisplayGLXClass * klass) { - GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); - GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); - gst_vaapi_display_x11_class_init(&klass->parent_class); + gst_vaapi_display_x11_class_init (&klass->parent_class); - object_class->size = sizeof(GstVaapiDisplayGLX); - klass->parent_get_display = dpy_class->get_display; - dpy_class->display_types = g_display_types; - dpy_class->get_display = gst_vaapi_display_glx_get_display_info; + object_class->size = sizeof (GstVaapiDisplayGLX); + klass->parent_get_display = dpy_class->get_display; + dpy_class->display_types = g_display_types; + dpy_class->get_display = gst_vaapi_display_glx_get_display_info; } static inline const GstVaapiDisplayClass * -gst_vaapi_display_glx_class(void) +gst_vaapi_display_glx_class (void) { - static GstVaapiDisplayGLXClass g_class; - static gsize g_class_init = FALSE; + static GstVaapiDisplayGLXClass g_class; + static gsize g_class_init = FALSE; - if (g_once_init_enter(&g_class_init)) { - gst_vaapi_display_glx_class_init(&g_class); - g_once_init_leave(&g_class_init, TRUE); - } - return GST_VAAPI_DISPLAY_CLASS(&g_class); + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_display_glx_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS (&g_class); } /** @@ -96,10 +94,10 @@ gst_vaapi_display_glx_class(void) * Return value: a newly allocated #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_display_glx_new(const gchar *display_name) +gst_vaapi_display_glx_new (const gchar * display_name) { - return gst_vaapi_display_new(gst_vaapi_display_glx_class(), - GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name); + return gst_vaapi_display_new (gst_vaapi_display_glx_class (), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) display_name); } /** @@ -114,10 +112,10 @@ gst_vaapi_display_glx_new(const gchar *display_name) * Return value: a newly allocated #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_display_glx_new_with_display(Display *x11_display) +gst_vaapi_display_glx_new_with_display (Display * x11_display) { - g_return_val_if_fail(x11_display != NULL, NULL); + g_return_val_if_fail (x11_display != NULL, NULL); - return gst_vaapi_display_new(gst_vaapi_display_glx_class(), - GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display); + return gst_vaapi_display_new (gst_vaapi_display_glx_class (), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index c22f904aba..8096cb2243 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -37,10 +37,10 @@ G_BEGIN_DECLS typedef struct _GstVaapiDisplayGLX GstVaapiDisplayGLX; GstVaapiDisplay * -gst_vaapi_display_glx_new(const gchar *display_name); +gst_vaapi_display_glx_new (const gchar * display_name); GstVaapiDisplay * -gst_vaapi_display_glx_new_with_display(Display *x11_display); +gst_vaapi_display_glx_new_with_display (Display * x11_display); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index 7386263981..12ee2f24e5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -49,9 +49,10 @@ typedef struct _GstVaapiDisplayGLXClass GstVaapiDisplayGLXClass; * * VA/GLX display wrapper. */ -struct _GstVaapiDisplayGLX { - /*< private >*/ - GstVaapiDisplayX11 parent_instance; +struct _GstVaapiDisplayGLX +{ + /*< private >*/ + GstVaapiDisplayX11 parent_instance; }; /** @@ -59,11 +60,12 @@ struct _GstVaapiDisplayGLX { * * VA/GLX display wrapper clas. */ -struct _GstVaapiDisplayGLXClass { - /*< private >*/ - GstVaapiDisplayX11Class parent_class; +struct _GstVaapiDisplayGLXClass +{ + /*< private >*/ + GstVaapiDisplayX11Class parent_class; - GstVaapiDisplayGetInfoFunc parent_get_display; + GstVaapiDisplayGetInfoFunc parent_get_display; }; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index e2d9bf2cfc..18626bdbb8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -50,22 +50,22 @@ typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; typedef enum _GstVaapiDisplayInitType GstVaapiDisplayInitType; -typedef void (*GstVaapiDisplayInitFunc) (GstVaapiDisplay *display); -typedef gboolean (*GstVaapiDisplayBindFunc) (GstVaapiDisplay *display, +typedef void (*GstVaapiDisplayInitFunc) (GstVaapiDisplay * display); +typedef gboolean (*GstVaapiDisplayBindFunc) (GstVaapiDisplay * display, gpointer native_dpy); -typedef gboolean (*GstVaapiDisplayOpenFunc) (GstVaapiDisplay *display, - const gchar *name); -typedef void (*GstVaapiDisplayCloseFunc) (GstVaapiDisplay *display); -typedef void (*GstVaapiDisplayLockFunc) (GstVaapiDisplay *display); -typedef void (*GstVaapiDisplayUnlockFunc) (GstVaapiDisplay *display); -typedef void (*GstVaapiDisplaySyncFunc) (GstVaapiDisplay *display); -typedef void (*GstVaapiDisplayFlushFunc) (GstVaapiDisplay *display); -typedef gboolean (*GstVaapiDisplayGetInfoFunc) (GstVaapiDisplay *display, - GstVaapiDisplayInfo *info); -typedef void (*GstVaapiDisplayGetSizeFunc) (GstVaapiDisplay *display, - guint *pwidth, guint *pheight); -typedef void (*GstVaapiDisplayGetSizeMFunc)(GstVaapiDisplay *display, - guint *pwidth, guint *pheight); +typedef gboolean (*GstVaapiDisplayOpenFunc) (GstVaapiDisplay * display, + const gchar * name); +typedef void (*GstVaapiDisplayCloseFunc) (GstVaapiDisplay * display); +typedef void (*GstVaapiDisplayLockFunc) (GstVaapiDisplay * display); +typedef void (*GstVaapiDisplayUnlockFunc) (GstVaapiDisplay * display); +typedef void (*GstVaapiDisplaySyncFunc) (GstVaapiDisplay * display); +typedef void (*GstVaapiDisplayFlushFunc) (GstVaapiDisplay * display); +typedef gboolean (*GstVaapiDisplayGetInfoFunc) (GstVaapiDisplay * display, + GstVaapiDisplayInfo * info); +typedef void (*GstVaapiDisplayGetSizeFunc) (GstVaapiDisplay * display, + guint * pwidth, guint * pheight); +typedef void (*GstVaapiDisplayGetSizeMFunc) (GstVaapiDisplay * display, + guint * pwidth, guint * pheight); /** * GST_VAAPI_DISPLAY_VADISPLAY: @@ -128,24 +128,25 @@ typedef void (*GstVaapiDisplayGetSizeMFunc)(GstVaapiDisplay *display, #define GST_VAAPI_DISPLAY_HAS_VPP(display) \ (GST_VAAPI_DISPLAY_GET_PRIVATE(display)->has_vpp) -struct _GstVaapiDisplayPrivate { - GstVaapiDisplay *parent; - GRecMutex mutex; - GstVaapiDisplayType display_type; - VADisplay display; - guint width; - guint height; - guint width_mm; - guint height_mm; - guint par_n; - guint par_d; - GArray *decoders; - GArray *encoders; - GArray *image_formats; - GArray *subpicture_formats; - GArray *properties; - guint use_foreign_display : 1; - guint has_vpp : 1; +struct _GstVaapiDisplayPrivate +{ + GstVaapiDisplay *parent; + GRecMutex mutex; + GstVaapiDisplayType display_type; + VADisplay display; + guint width; + guint height; + guint width_mm; + guint height_mm; + guint par_n; + guint par_d; + GArray *decoders; + GArray *encoders; + GArray *image_formats; + GArray *subpicture_formats; + GArray *properties; + guint use_foreign_display:1; + guint has_vpp:1; }; /** @@ -153,11 +154,12 @@ struct _GstVaapiDisplayPrivate { * * Base class for VA displays. */ -struct _GstVaapiDisplay { - /*< private >*/ - GstVaapiMiniObject parent_instance; +struct _GstVaapiDisplay +{ + /*< private >*/ + GstVaapiMiniObject parent_instance; - GstVaapiDisplayPrivate priv; + GstVaapiDisplayPrivate priv; }; /** @@ -174,51 +176,53 @@ struct _GstVaapiDisplay { * * Base class for VA displays. */ -struct _GstVaapiDisplayClass { - /*< private >*/ - GstVaapiMiniObjectClass parent_class; +struct _GstVaapiDisplayClass +{ + /*< private >*/ + GstVaapiMiniObjectClass parent_class; - /*< protected >*/ - guint display_types; + /*< protected >*/ + guint display_types; - /*< public >*/ - GstVaapiDisplayInitFunc init; - GstVaapiDisplayBindFunc bind_display; - GstVaapiDisplayOpenFunc open_display; - GstVaapiDisplayCloseFunc close_display; - GstVaapiDisplayLockFunc lock; - GstVaapiDisplayUnlockFunc unlock; - GstVaapiDisplaySyncFunc sync; - GstVaapiDisplayFlushFunc flush; - GstVaapiDisplayGetInfoFunc get_display; - GstVaapiDisplayGetSizeFunc get_size; - GstVaapiDisplayGetSizeMFunc get_size_mm; + /*< public >*/ + GstVaapiDisplayInitFunc init; + GstVaapiDisplayBindFunc bind_display; + GstVaapiDisplayOpenFunc open_display; + GstVaapiDisplayCloseFunc close_display; + GstVaapiDisplayLockFunc lock; + GstVaapiDisplayUnlockFunc unlock; + GstVaapiDisplaySyncFunc sync; + GstVaapiDisplayFlushFunc flush; + GstVaapiDisplayGetInfoFunc get_display; + GstVaapiDisplayGetSizeFunc get_size; + GstVaapiDisplayGetSizeMFunc get_size_mm; }; /* 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 +enum _GstVaapiDisplayInitType +{ + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME = 1, + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, + GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY }; void -gst_vaapi_display_class_init(GstVaapiDisplayClass *klass); +gst_vaapi_display_class_init (GstVaapiDisplayClass * klass); GstVaapiDisplay * -gst_vaapi_display_new(const GstVaapiDisplayClass *klass, +gst_vaapi_display_new (const GstVaapiDisplayClass * klass, GstVaapiDisplayInitType init_type, gpointer init_value); GstVaapiDisplayCache * -gst_vaapi_display_get_cache(void); +gst_vaapi_display_get_cache (void); static inline guint -gst_vaapi_display_get_display_types(GstVaapiDisplay *display) +gst_vaapi_display_get_display_types (GstVaapiDisplay * display) { - const GstVaapiDisplayClass * const dpy_class = - GST_VAAPI_DISPLAY_GET_CLASS(display); + const GstVaapiDisplayClass *const dpy_class = + GST_VAAPI_DISPLAY_GET_CLASS (display); - return dpy_class->display_types; + return dpy_class->display_types; } /* Inline reference counting for core libgstvaapi library */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 04001a9f08..4ed6dbe1d4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -38,348 +38,334 @@ static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_WAYLAND; static inline const gchar * -get_default_display_name(void) +get_default_display_name (void) { - static const gchar *g_display_name; + static const gchar *g_display_name; - if (!g_display_name) - g_display_name = getenv("WAYLAND_DISPLAY"); - return g_display_name; + if (!g_display_name) + g_display_name = getenv ("WAYLAND_DISPLAY"); + return g_display_name; } static inline guint -get_display_name_length(const gchar *display_name) +get_display_name_length (const gchar * display_name) { - const gchar *str; + const gchar *str; - str = strchr(display_name, '-'); - if (str) - return str - display_name; - return strlen(display_name); + str = strchr (display_name, '-'); + if (str) + return str - display_name; + return strlen (display_name); } static gint -compare_display_name(gconstpointer a, gconstpointer b) +compare_display_name (gconstpointer a, gconstpointer b) { - const GstVaapiDisplayInfo * const info = a; - const gchar *cached_name = info->display_name; - const gchar *tested_name = b; - guint cached_name_length, tested_name_length; + const GstVaapiDisplayInfo *const info = a; + const gchar *cached_name = info->display_name; + const gchar *tested_name = b; + guint cached_name_length, tested_name_length; - g_return_val_if_fail(cached_name, FALSE); - g_return_val_if_fail(tested_name, FALSE); + g_return_val_if_fail (cached_name, FALSE); + g_return_val_if_fail (tested_name, FALSE); - cached_name_length = get_display_name_length(cached_name); - tested_name_length = get_display_name_length(tested_name); + cached_name_length = get_display_name_length (cached_name); + tested_name_length = get_display_name_length (tested_name); - /* XXX: handle screen number and default WAYLAND_DISPLAY name */ - if (cached_name_length != tested_name_length) - return FALSE; - if (strncmp(cached_name, tested_name, cached_name_length) != 0) - return FALSE; - return TRUE; + /* XXX: handle screen number and default WAYLAND_DISPLAY name */ + if (cached_name_length != tested_name_length) + return FALSE; + if (strncmp (cached_name, tested_name, cached_name_length) != 0) + return FALSE; + return TRUE; } /* Mangle display name with our prefix */ static gboolean -set_display_name(GstVaapiDisplay *display, const gchar *display_name) +set_display_name (GstVaapiDisplay * display, const gchar * display_name) { - GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + GstVaapiDisplayWaylandPrivate *const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - g_free(priv->display_name); + 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; + 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) +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; + GstVaapiDisplayWaylandPrivate *const priv = data; - priv->phys_width = physical_width; - priv->phys_height = physical_height; + 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) +output_handle_mode (void *data, struct wl_output *wl_output, + uint32_t flags, int width, int height, int refresh) { - GstVaapiDisplayWaylandPrivate * const priv = data; + GstVaapiDisplayWaylandPrivate *const priv = data; - if (flags & WL_OUTPUT_MODE_CURRENT) { - priv->width = width; - priv->height = height; - } + 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, + output_handle_geometry, + output_handle_mode, }; static void -registry_handle_global( - void *data, +registry_handle_global (void *data, struct wl_registry *registry, - uint32_t id, - const char *interface, - uint32_t version -) + uint32_t id, const char *interface, uint32_t version) { - GstVaapiDisplayWaylandPrivate * const priv = data; + 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_shell") == 0) - priv->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1); - else if (strcmp(interface, "wl_output") == 0) { - priv->output = wl_registry_bind(registry, id, &wl_output_interface, 1); - wl_output_add_listener(priv->output, &output_listener, priv); - } + if (strcmp (interface, "wl_compositor") == 0) + priv->compositor = + wl_registry_bind (registry, id, &wl_compositor_interface, 1); + else if (strcmp (interface, "wl_shell") == 0) + priv->shell = wl_registry_bind (registry, id, &wl_shell_interface, 1); + else if (strcmp (interface, "wl_output") == 0) { + priv->output = wl_registry_bind (registry, id, &wl_output_interface, 1); + wl_output_add_listener (priv->output, &output_listener, priv); + } } static const struct wl_registry_listener registry_listener = { - registry_handle_global, - NULL, + registry_handle_global, + NULL, }; static gboolean -gst_vaapi_display_wayland_setup(GstVaapiDisplay *display) +gst_vaapi_display_wayland_setup (GstVaapiDisplay * display) { - GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(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); + 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) { - wl_display_roundtrip(priv->wl_display); - if (!priv->width || !priv->height) { - GST_ERROR("failed to determine the display size"); - return FALSE; - } + GST_ERROR ("failed to determine the display size"); + return FALSE; } + } - if (!priv->compositor) { - GST_ERROR("failed to bind compositor interface"); - return FALSE; - } + if (!priv->compositor) { + GST_ERROR ("failed to bind compositor interface"); + return FALSE; + } - if (!priv->shell) { - GST_ERROR("failed to bind shell interface"); - return FALSE; - } - return TRUE; + if (!priv->shell) { + GST_ERROR ("failed to bind shell interface"); + return FALSE; + } + return TRUE; } static gboolean -gst_vaapi_display_wayland_bind_display(GstVaapiDisplay *display, +gst_vaapi_display_wayland_bind_display (GstVaapiDisplay * display, gpointer native_display) { - GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + GstVaapiDisplayWaylandPrivate *const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - priv->wl_display = native_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); + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *info; + + cache = gst_vaapi_display_get_cache (); + g_return_val_if_fail (cache != NULL, FALSE); + + if (!set_display_name (display, name)) + return FALSE; + + info = gst_vaapi_display_cache_lookup_custom (cache, compare_display_name, + priv->display_name, GST_VAAPI_DISPLAY_TYPES (display)); + if (info) { + priv->wl_display = info->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); - GstVaapiDisplayCache *cache; - const GstVaapiDisplayInfo *info; - - cache = gst_vaapi_display_get_cache(); - g_return_val_if_fail(cache != NULL, FALSE); - - if (!set_display_name(display, name)) - return FALSE; - - info = gst_vaapi_display_cache_lookup_custom(cache, compare_display_name, - priv->display_name, GST_VAAPI_DISPLAY_TYPES(display)); - if (info) { - priv->wl_display = info->native_display; - priv->use_foreign_display = TRUE; - } - else { - 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); + } else { + 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) +gst_vaapi_display_wayland_close_display (GstVaapiDisplay * display) { - GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + GstVaapiDisplayWaylandPrivate *const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - if (priv->output) { - wl_output_destroy(priv->output); - priv->output = NULL; - } + if (priv->output) { + wl_output_destroy (priv->output); + priv->output = NULL; + } - if (priv->shell) { - wl_shell_destroy(priv->shell); - priv->shell = NULL; - } + if (priv->shell) { + wl_shell_destroy (priv->shell); + priv->shell = NULL; + } - if (priv->compositor) { - wl_compositor_destroy(priv->compositor); - priv->compositor = NULL; - } + if (priv->compositor) { + wl_compositor_destroy (priv->compositor); + priv->compositor = NULL; + } - if (priv->wl_display) { - if (!priv->use_foreign_display) - wl_display_disconnect(priv->wl_display); - priv->wl_display = NULL; - } + if (priv->wl_display) { + if (!priv->use_foreign_display) + wl_display_disconnect (priv->wl_display); + priv->wl_display = NULL; + } - if (priv->display_name) { - g_free(priv->display_name); - priv->display_name = NULL; - } + if (priv->display_name) { + g_free (priv->display_name); + priv->display_name = NULL; + } } static gboolean -gst_vaapi_display_wayland_get_display_info( - GstVaapiDisplay *display, - GstVaapiDisplayInfo *info -) +gst_vaapi_display_wayland_get_display_info (GstVaapiDisplay * display, + GstVaapiDisplayInfo * info) { - GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); - GstVaapiDisplayCache *cache; - const GstVaapiDisplayInfo *cached_info; + GstVaapiDisplayWaylandPrivate *const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *cached_info; - /* Return any cached info even if child has its own VA display */ - cache = gst_vaapi_display_get_cache(); - if (!cache) - return FALSE; - cached_info = gst_vaapi_display_cache_lookup_by_native_display(cache, - priv->wl_display, GST_VAAPI_DISPLAY_TYPES(display)); - if (cached_info) { - *info = *cached_info; - return TRUE; - } - - /* Otherwise, create VA display if there is none already */ - 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; - info->display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; - } + /* Return any cached info even if child has its own VA display */ + cache = gst_vaapi_display_get_cache (); + if (!cache) + return FALSE; + cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache, + priv->wl_display, GST_VAAPI_DISPLAY_TYPES (display)); + if (cached_info) { + *info = *cached_info; return TRUE; + } + + /* Otherwise, create VA display if there is none already */ + 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; + info->display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; + } + return TRUE; } static void -gst_vaapi_display_wayland_get_size( - GstVaapiDisplay *display, - guint *pwidth, - guint *pheight -) +gst_vaapi_display_wayland_get_size (GstVaapiDisplay * display, + guint * pwidth, guint * pheight) { - GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + GstVaapiDisplayWaylandPrivate *const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - if (!priv->output) - return; + if (!priv->output) + return; - if (pwidth) - *pwidth = priv->width; + if (pwidth) + *pwidth = priv->width; - if (pheight) - *pheight = priv->height; + if (pheight) + *pheight = priv->height; } static void -gst_vaapi_display_wayland_get_size_mm( - GstVaapiDisplay *display, - guint *pwidth, - guint *pheight -) +gst_vaapi_display_wayland_get_size_mm (GstVaapiDisplay * display, + guint * pwidth, guint * pheight) { - GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + GstVaapiDisplayWaylandPrivate *const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - if (!priv->output) - return; + if (!priv->output) + return; - if (pwidth) - *pwidth = priv->phys_width; + if (pwidth) + *pwidth = priv->phys_width; - if (pheight) - *pheight = priv->phys_height; + if (pheight) + *pheight = priv->phys_height; } static void -gst_vaapi_display_wayland_init(GstVaapiDisplay *display) +gst_vaapi_display_wayland_init (GstVaapiDisplay * display) { - GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + GstVaapiDisplayWaylandPrivate *const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - priv->event_fd = -1; + priv->event_fd = -1; } static void -gst_vaapi_display_wayland_class_init(GstVaapiDisplayWaylandClass * klass) +gst_vaapi_display_wayland_class_init (GstVaapiDisplayWaylandClass * klass) { - GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); - GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); - gst_vaapi_display_class_init(&klass->parent_class); + gst_vaapi_display_class_init (&klass->parent_class); - object_class->size = sizeof(GstVaapiDisplayWayland); - dpy_class->display_types = g_display_types; - dpy_class->init = gst_vaapi_display_wayland_init; - 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; + object_class->size = sizeof (GstVaapiDisplayWayland); + dpy_class->display_types = g_display_types; + dpy_class->init = gst_vaapi_display_wayland_init; + 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; } static inline const GstVaapiDisplayClass * -gst_vaapi_display_wayland_class(void) +gst_vaapi_display_wayland_class (void) { - static GstVaapiDisplayWaylandClass g_class; - static gsize g_class_init = FALSE; + static GstVaapiDisplayWaylandClass g_class; + static gsize g_class_init = FALSE; - if (g_once_init_enter(&g_class_init)) { - gst_vaapi_display_wayland_class_init(&g_class); - g_once_init_leave(&g_class_init, TRUE); - } - return GST_VAAPI_DISPLAY_CLASS(&g_class); + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_display_wayland_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS (&g_class); } /** @@ -393,10 +379,10 @@ gst_vaapi_display_wayland_class(void) * Return value: a newly allocated #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_display_wayland_new(const gchar *display_name) +gst_vaapi_display_wayland_new (const gchar * display_name) { - return gst_vaapi_display_new(gst_vaapi_display_wayland_class(), - GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name); + return gst_vaapi_display_new (gst_vaapi_display_wayland_class (), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) display_name); } /** @@ -411,12 +397,12 @@ gst_vaapi_display_wayland_new(const gchar *display_name) * Return value: a newly allocated #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_display_wayland_new_with_display(struct wl_display *wl_display) +gst_vaapi_display_wayland_new_with_display (struct wl_display * wl_display) { - g_return_val_if_fail(wl_display, NULL); + g_return_val_if_fail (wl_display, NULL); - return gst_vaapi_display_new(gst_vaapi_display_wayland_class(), - GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, wl_display); + return gst_vaapi_display_new (gst_vaapi_display_wayland_class (), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, wl_display); } /** @@ -430,9 +416,9 @@ gst_vaapi_display_wayland_new_with_display(struct wl_display *wl_display) * Return value: the Wayland #wl_display attached to @display */ struct wl_display * -gst_vaapi_display_wayland_get_display(GstVaapiDisplayWayland *display) +gst_vaapi_display_wayland_get_display (GstVaapiDisplayWayland * display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_WAYLAND(display), NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_WAYLAND (display), NULL); - return GST_VAAPI_DISPLAY_WL_DISPLAY(display); + return GST_VAAPI_DISPLAY_WL_DISPLAY (display); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h index 25d6c006fc..6a3fa90e29 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h @@ -35,13 +35,13 @@ G_BEGIN_DECLS typedef struct _GstVaapiDisplayWayland GstVaapiDisplayWayland; GstVaapiDisplay * -gst_vaapi_display_wayland_new(const gchar *display_name); +gst_vaapi_display_wayland_new (const gchar * display_name); GstVaapiDisplay * -gst_vaapi_display_wayland_new_with_display(struct wl_display *wl_display); +gst_vaapi_display_wayland_new_with_display (struct wl_display * wl_display); struct wl_display * -gst_vaapi_display_wayland_get_display(GstVaapiDisplayWayland *display); +gst_vaapi_display_wayland_get_display (GstVaapiDisplayWayland * display); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index 83e2165ffa..0a98ec7452 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -53,19 +53,20 @@ typedef struct _GstVaapiDisplayWaylandClass GstVaapiDisplayWaylandClass; #define GST_VAAPI_DISPLAY_WL_DISPLAY(display) \ GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display)->wl_display -struct _GstVaapiDisplayWaylandPrivate { - gchar *display_name; - struct wl_display *wl_display; - struct wl_compositor *compositor; - struct wl_shell *shell; - struct wl_output *output; - struct wl_registry *registry; - guint width; - guint height; - guint phys_width; - guint phys_height; - gint event_fd; - guint use_foreign_display : 1; +struct _GstVaapiDisplayWaylandPrivate +{ + gchar *display_name; + struct wl_display *wl_display; + struct wl_compositor *compositor; + struct wl_shell *shell; + struct wl_output *output; + struct wl_registry *registry; + guint width; + guint height; + guint phys_width; + guint phys_height; + gint event_fd; + guint use_foreign_display:1; }; /** @@ -73,11 +74,12 @@ struct _GstVaapiDisplayWaylandPrivate { * * VA/Wayland display wrapper. */ -struct _GstVaapiDisplayWayland { - /*< private >*/ - GstVaapiDisplay parent_instance; +struct _GstVaapiDisplayWayland +{ + /*< private >*/ + GstVaapiDisplay parent_instance; - GstVaapiDisplayWaylandPrivate priv; + GstVaapiDisplayWaylandPrivate priv; }; /** @@ -85,9 +87,10 @@ struct _GstVaapiDisplayWayland { * * VA/Wayland display wrapper clas. */ -struct _GstVaapiDisplayWaylandClass { - /*< private >*/ - GstVaapiDisplayClass parent_class; +struct _GstVaapiDisplayWaylandClass +{ + /*< private >*/ + GstVaapiDisplayClass parent_class; }; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index ca34f9f876..f97d79498d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -46,359 +46,348 @@ #include "gstvaapidebug.h" static const guint g_display_types = - (1U << GST_VAAPI_DISPLAY_TYPE_X11) | - (1U << GST_VAAPI_DISPLAY_TYPE_GLX); + (1U << GST_VAAPI_DISPLAY_TYPE_X11) | (1U << GST_VAAPI_DISPLAY_TYPE_GLX); static inline const gchar * -get_default_display_name(void) +get_default_display_name (void) { - static const gchar *g_display_name; + static const gchar *g_display_name; - if (!g_display_name) - g_display_name = getenv("DISPLAY"); - return g_display_name; + if (!g_display_name) + g_display_name = getenv ("DISPLAY"); + return g_display_name; } static gint -compare_display_name(gconstpointer a, gconstpointer b) +compare_display_name (gconstpointer a, gconstpointer b) { - const GstVaapiDisplayInfo * const info = a; - const gchar *cached_name = info->display_name, *cached_name_end; - const gchar *tested_name = b, *tested_name_end; - guint cached_name_length, tested_name_length; + const GstVaapiDisplayInfo *const info = a; + const gchar *cached_name = info->display_name, *cached_name_end; + const gchar *tested_name = b, *tested_name_end; + guint cached_name_length, tested_name_length; - g_return_val_if_fail(cached_name, FALSE); - g_return_val_if_fail(tested_name, FALSE); + g_return_val_if_fail (cached_name, FALSE); + g_return_val_if_fail (tested_name, FALSE); - cached_name_end = strchr(cached_name, ':'); - if (cached_name_end) - cached_name_length = cached_name_end - cached_name; - else - cached_name_length = strlen(cached_name); + cached_name_end = strchr (cached_name, ':'); + if (cached_name_end) + cached_name_length = cached_name_end - cached_name; + else + cached_name_length = strlen (cached_name); - tested_name_end = strchr(tested_name, ':'); - if (tested_name_end) - tested_name_length = tested_name_end - tested_name; - else - tested_name_length = strlen(tested_name); + tested_name_end = strchr (tested_name, ':'); + if (tested_name_end) + tested_name_length = tested_name_end - tested_name; + else + tested_name_length = strlen (tested_name); - if (cached_name_length != tested_name_length) - return FALSE; - if (strncmp(cached_name, tested_name, cached_name_length) != 0) - return FALSE; + if (cached_name_length != tested_name_length) + return FALSE; + if (strncmp (cached_name, tested_name, cached_name_length) != 0) + return FALSE; - /* XXX: handle screen number? */ - return TRUE; + /* XXX: handle screen number? */ + return TRUE; } /* Reconstruct a display name without our prefix */ static const gchar * -get_display_name(GstVaapiDisplayX11 *display) +get_display_name (GstVaapiDisplayX11 * display) { - GstVaapiDisplayX11Private * const priv = &display->priv; - const gchar *display_name = priv->display_name; + GstVaapiDisplayX11Private *const priv = &display->priv; + const gchar *display_name = priv->display_name; - if (!display_name || *display_name == '\0') - return NULL; - return 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) +set_display_name (GstVaapiDisplayX11 * display, const gchar * display_name) { - GstVaapiDisplayX11Private * const priv = &display->priv; + GstVaapiDisplayX11Private *const priv = &display->priv; - g_free(priv->display_name); + 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; + 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) +set_synchronous (GstVaapiDisplayX11 * display, gboolean synchronous) { - GstVaapiDisplayX11Private * const priv = &display->priv; + 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); - } + 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) +check_extensions (GstVaapiDisplayX11 * display) { - GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11_PRIVATE(display); - int evt_base, err_base; + GstVaapiDisplayX11Private *const priv = + GST_VAAPI_DISPLAY_X11_PRIVATE (display); + int evt_base, err_base; #ifdef HAVE_XRANDR - priv->use_xrandr = XRRQueryExtension(priv->x11_display, - &evt_base, &err_base); + priv->use_xrandr = XRRQueryExtension (priv->x11_display, + &evt_base, &err_base); #endif #ifdef HAVE_XRENDER - priv->has_xrender = XRenderQueryExtension(priv->x11_display, - &evt_base, &err_base); + priv->has_xrender = XRenderQueryExtension (priv->x11_display, + &evt_base, &err_base); #endif } static gboolean -gst_vaapi_display_x11_bind_display(GstVaapiDisplay *base_display, +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; + 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->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; + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *info; + + cache = gst_vaapi_display_get_cache (); + g_return_val_if_fail (cache != NULL, FALSE); + + if (!set_display_name (display, name)) + return FALSE; + + info = gst_vaapi_display_cache_lookup_custom (cache, compare_display_name, + priv->display_name, GST_VAAPI_DISPLAY_TYPES (display)); + if (info) { + priv->x11_display = info->native_display; priv->use_foreign_display = TRUE; + } else { + 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); + check_extensions (display); + return TRUE; +} - if (!set_display_name(display, XDisplayString(priv->x11_display))) - return FALSE; - return TRUE; +static void +gst_vaapi_display_x11_close_display (GstVaapiDisplay * display) +{ + GstVaapiDisplayX11Private *const priv = + GST_VAAPI_DISPLAY_X11_PRIVATE (display); + + if (priv->pixmap_formats) { + g_array_free (priv->pixmap_formats, TRUE); + priv->pixmap_formats = NULL; + } + + if (priv->x11_display) { + if (!priv->use_foreign_display) + XCloseDisplay (priv->x11_display); + priv->x11_display = NULL; + } + + if (priv->display_name) { + g_free (priv->display_name); + priv->display_name = NULL; + } +} + +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_open_display(GstVaapiDisplay *base_display, - const gchar *name) +gst_vaapi_display_x11_get_display_info (GstVaapiDisplay * display, + GstVaapiDisplayInfo * info) { - GstVaapiDisplayX11 * const display = - GST_VAAPI_DISPLAY_X11_CAST(base_display); - GstVaapiDisplayX11Private * const priv = &display->priv; - GstVaapiDisplayCache *cache; - const GstVaapiDisplayInfo *info; + GstVaapiDisplayX11Private *const priv = + GST_VAAPI_DISPLAY_X11_PRIVATE (display); + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *cached_info; - cache = gst_vaapi_display_get_cache(); - g_return_val_if_fail(cache != NULL, FALSE); - - if (!set_display_name(display, name)) - return FALSE; - - info = gst_vaapi_display_cache_lookup_custom(cache, compare_display_name, - priv->display_name, GST_VAAPI_DISPLAY_TYPES(display)); - if (info) { - priv->x11_display = info->native_display; - priv->use_foreign_display = TRUE; - } - else { - 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 any cached info even if child has its own VA display */ + cache = gst_vaapi_display_get_cache (); + if (!cache) + return FALSE; + cached_info = + gst_vaapi_display_cache_lookup_by_native_display (cache, + priv->x11_display, GST_VAAPI_DISPLAY_TYPES (display)); + if (cached_info) { + *info = *cached_info; return TRUE; + } + + /* Otherwise, create VA display if there is none already */ + 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; + info->display_type = GST_VAAPI_DISPLAY_TYPE_X11; + } + return TRUE; } static void -gst_vaapi_display_x11_close_display(GstVaapiDisplay *display) +gst_vaapi_display_x11_get_size (GstVaapiDisplay * display, + guint * pwidth, guint * pheight) { - GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11_PRIVATE(display); + GstVaapiDisplayX11Private *const priv = + GST_VAAPI_DISPLAY_X11_PRIVATE (display); - if (priv->pixmap_formats) { - g_array_free(priv->pixmap_formats, TRUE); - priv->pixmap_formats = NULL; - } + if (!priv->x11_display) + return; - if (priv->x11_display) { - if (!priv->use_foreign_display) - XCloseDisplay(priv->x11_display); - priv->x11_display = NULL; - } + if (pwidth) + *pwidth = DisplayWidth (priv->x11_display, priv->x11_screen); - if (priv->display_name) { - g_free(priv->display_name); - priv->display_name = NULL; - } + if (pheight) + *pheight = DisplayHeight (priv->x11_display, priv->x11_screen); } static void -gst_vaapi_display_x11_sync(GstVaapiDisplay *display) +gst_vaapi_display_x11_get_size_mm (GstVaapiDisplay * display, + guint * pwidth, guint * pheight) { - GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11_PRIVATE(display); + GstVaapiDisplayX11Private *const priv = + GST_VAAPI_DISPLAY_X11_PRIVATE (display); + guint width_mm, height_mm; - if (priv->x11_display) { - GST_VAAPI_DISPLAY_LOCK(display); - XSync(priv->x11_display, False); - GST_VAAPI_DISPLAY_UNLOCK(display); - } -} + if (!priv->x11_display) + return; -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); - GstVaapiDisplayCache *cache; - const GstVaapiDisplayInfo *cached_info; - - /* Return any cached info even if child has its own VA display */ - cache = gst_vaapi_display_get_cache(); - if (!cache) - return FALSE; - cached_info = gst_vaapi_display_cache_lookup_by_native_display( - cache, priv->x11_display, GST_VAAPI_DISPLAY_TYPES(display)); - if (cached_info) { - *info = *cached_info; - return TRUE; - } - - /* Otherwise, create VA display if there is none already */ - 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; - info->display_type = GST_VAAPI_DISPLAY_TYPE_X11; - } - 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); + width_mm = DisplayWidthMM (priv->x11_display, priv->x11_screen); + height_mm = DisplayHeightMM (priv->x11_display, priv->x11_screen); #ifdef 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; + /* 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); + do { + win = DefaultRootWindow (priv->x11_display); + screen = XRRRootToScreen (priv->x11_display, win); - xrr_config = XRRGetScreenInfo(priv->x11_display, win); - if (!xrr_config) - break; + 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; + 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; + 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); - } + 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 (pwidth) + *pwidth = width_mm; - if (pheight) - *pheight = height_mm; + if (pheight) + *pheight = height_mm; } void -gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) +gst_vaapi_display_x11_class_init (GstVaapiDisplayX11Class * klass) { - GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); - GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); - gst_vaapi_display_class_init(&klass->parent_class); + gst_vaapi_display_class_init (&klass->parent_class); - object_class->size = sizeof(GstVaapiDisplayX11); - dpy_class->display_types = g_display_types; - 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; + object_class->size = sizeof (GstVaapiDisplayX11); + dpy_class->display_types = g_display_types; + 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; } static inline const GstVaapiDisplayClass * -gst_vaapi_display_x11_class(void) +gst_vaapi_display_x11_class (void) { - static GstVaapiDisplayX11Class g_class; - static gsize g_class_init = FALSE; + static GstVaapiDisplayX11Class g_class; + static gsize g_class_init = FALSE; - if (g_once_init_enter(&g_class_init)) { - gst_vaapi_display_x11_class_init(&g_class); - g_once_init_leave(&g_class_init, TRUE); - } - return GST_VAAPI_DISPLAY_CLASS(&g_class); + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_display_x11_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS (&g_class); } /** @@ -412,10 +401,10 @@ gst_vaapi_display_x11_class(void) * Return value: a newly allocated #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_display_x11_new(const gchar *display_name) +gst_vaapi_display_x11_new (const gchar * display_name) { - return gst_vaapi_display_new(gst_vaapi_display_x11_class(), - GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name); + return gst_vaapi_display_new (gst_vaapi_display_x11_class (), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) display_name); } /** @@ -430,12 +419,12 @@ gst_vaapi_display_x11_new(const gchar *display_name) * Return value: a newly allocated #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_display_x11_new_with_display(Display *x11_display) +gst_vaapi_display_x11_new_with_display (Display * x11_display) { - g_return_val_if_fail(x11_display, NULL); + g_return_val_if_fail (x11_display, NULL); - return gst_vaapi_display_new(gst_vaapi_display_x11_class(), - GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display); + return gst_vaapi_display_new (gst_vaapi_display_x11_class (), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display); } /** @@ -449,11 +438,11 @@ gst_vaapi_display_x11_new_with_display(Display *x11_display) * Return value: the X11 #Display attached to @display */ Display * -gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) +gst_vaapi_display_x11_get_display (GstVaapiDisplayX11 * display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); - return GST_VAAPI_DISPLAY_XDISPLAY(display); + return GST_VAAPI_DISPLAY_XDISPLAY (display); } /** @@ -467,11 +456,11 @@ gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) * Return value: the X11 #Display attached to @display */ int -gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display) +gst_vaapi_display_x11_get_screen (GstVaapiDisplayX11 * display) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), -1); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), -1); - return GST_VAAPI_DISPLAY_XSCREEN(display); + return GST_VAAPI_DISPLAY_XSCREEN (display); } /** @@ -486,120 +475,121 @@ gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display) * @synchronous is %FALSE. */ void -gst_vaapi_display_x11_set_synchronous(GstVaapiDisplayX11 *display, +gst_vaapi_display_x11_set_synchronous (GstVaapiDisplayX11 * display, gboolean synchronous) { - g_return_if_fail(GST_VAAPI_IS_DISPLAY_X11(display)); + g_return_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display)); - set_synchronous(display, synchronous); + set_synchronous (display, synchronous); } typedef struct _GstVaapiPixmapFormatX11 GstVaapiPixmapFormatX11; -struct _GstVaapiPixmapFormatX11 { - GstVideoFormat format; - gint depth; - gint bpp; +struct _GstVaapiPixmapFormatX11 +{ + GstVideoFormat format; + gint depth; + gint bpp; }; static GstVideoFormat -pix_fmt_to_video_format(gint depth, gint bpp) +pix_fmt_to_video_format (gint depth, gint bpp) { - GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; + GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; - switch (bpp) { + switch (bpp) { case 16: - if (depth == 15) - format = GST_VIDEO_FORMAT_RGB15; - else if (depth == 16) - format = GST_VIDEO_FORMAT_RGB16; - break; + 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; + if (depth == 24) + format = GST_VIDEO_FORMAT_RGB; + break; case 32: - if (depth == 24 || depth == 32) - format = GST_VIDEO_FORMAT_xRGB; - break; - } - return format; + if (depth == 24 || depth == 32) + format = GST_VIDEO_FORMAT_xRGB; + break; + } + return format; } static gboolean -ensure_pix_fmts(GstVaapiDisplayX11 *display) +ensure_pix_fmts (GstVaapiDisplayX11 * display) { - GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11_PRIVATE(display); - XPixmapFormatValues *pix_fmts; - int i, n, num_pix_fmts; + 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; + 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; + return TRUE; } /* Determine the GstVideoFormat based on a supported Pixmap depth */ GstVideoFormat -gst_vaapi_display_x11_get_pixmap_format(GstVaapiDisplayX11 *display, +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; + 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; - } + 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; + } + return GST_VIDEO_FORMAT_UNKNOWN; } /* Determine the Pixmap depth based on a GstVideoFormat */ guint -gst_vaapi_display_x11_get_pixmap_depth(GstVaapiDisplayX11 *display, +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; + 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; - } + 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; + } + return 0; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index a470b70648..5eca2c2c61 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -36,19 +36,19 @@ G_BEGIN_DECLS typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11; GstVaapiDisplay * -gst_vaapi_display_x11_new(const gchar *display_name); +gst_vaapi_display_x11_new (const gchar * display_name); GstVaapiDisplay * -gst_vaapi_display_x11_new_with_display(Display *x11_display); +gst_vaapi_display_x11_new_with_display (Display * x11_display); Display * -gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display); +gst_vaapi_display_x11_get_display (GstVaapiDisplayX11 * display); int -gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display); +gst_vaapi_display_x11_get_screen (GstVaapiDisplayX11 * display); void -gst_vaapi_display_x11_set_synchronous(GstVaapiDisplayX11 *display, +gst_vaapi_display_x11_set_synchronous (GstVaapiDisplayX11 * display, gboolean synchronous); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index ff487e6a43..ca333df754 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -76,15 +76,16 @@ typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class; #define GST_VAAPI_DISPLAY_HAS_XRENDER(display) \ (GST_VAAPI_DISPLAY_X11_PRIVATE(display)->has_xrender) -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 has_xrender : 1; // Has XRender extension? - guint synchronous : 1; +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 has_xrender:1; // Has XRender extension? + guint synchronous:1; }; /** @@ -92,11 +93,12 @@ struct _GstVaapiDisplayX11Private { * * VA/X11 display wrapper. */ -struct _GstVaapiDisplayX11 { - /*< private >*/ - GstVaapiDisplay parent_instance; +struct _GstVaapiDisplayX11 +{ + /*< private >*/ + GstVaapiDisplay parent_instance; - GstVaapiDisplayX11Private priv; + GstVaapiDisplayX11Private priv; }; /** @@ -104,22 +106,23 @@ struct _GstVaapiDisplayX11 { * * VA/X11 display wrapper clas. */ -struct _GstVaapiDisplayX11Class { - /*< private >*/ - GstVaapiDisplayClass parent_class; +struct _GstVaapiDisplayX11Class +{ + /*< private >*/ + GstVaapiDisplayClass parent_class; }; void -gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass); +gst_vaapi_display_x11_class_init (GstVaapiDisplayX11Class * klass); G_GNUC_INTERNAL GstVideoFormat -gst_vaapi_display_x11_get_pixmap_format(GstVaapiDisplayX11 *display, +gst_vaapi_display_x11_get_pixmap_format (GstVaapiDisplayX11 * display, guint depth); G_GNUC_INTERNAL guint -gst_vaapi_display_x11_get_pixmap_depth(GstVaapiDisplayX11 *display, +gst_vaapi_display_x11_get_pixmap_depth (GstVaapiDisplayX11 * display, GstVideoFormat format); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index 47fd6b8bd7..29156c2366 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -29,134 +29,136 @@ #include "gstvaapidebug.h" typedef struct _CacheEntry CacheEntry; -struct _CacheEntry { - GstVaapiDisplayInfo info; +struct _CacheEntry +{ + GstVaapiDisplayInfo info; }; -struct _GstVaapiDisplayCache { - GMutex mutex; - GList *list; +struct _GstVaapiDisplayCache +{ + GMutex mutex; + GList *list; }; static void -cache_entry_free(CacheEntry *entry) +cache_entry_free (CacheEntry * entry) { - GstVaapiDisplayInfo *info; + GstVaapiDisplayInfo *info; - if (!entry) - return; + if (!entry) + return; - info = &entry->info; + info = &entry->info; - if (info->display_name) { - g_free(info->display_name); - info->display_name = NULL; - } - g_slice_free(CacheEntry, entry); + if (info->display_name) { + g_free (info->display_name); + info->display_name = NULL; + } + g_slice_free (CacheEntry, entry); } static CacheEntry * -cache_entry_new(const GstVaapiDisplayInfo *di) +cache_entry_new (const GstVaapiDisplayInfo * di) { - GstVaapiDisplayInfo *info; - CacheEntry *entry; + GstVaapiDisplayInfo *info; + CacheEntry *entry; - entry = g_slice_new(CacheEntry); - if (!entry) - return NULL; + entry = g_slice_new (CacheEntry); + if (!entry) + return NULL; - info = &entry->info; - info->display = di->display; - info->va_display = di->va_display; - info->native_display = di->native_display; - info->display_type = di->display_type; - info->display_name = NULL; + info = &entry->info; + info->display = di->display; + info->va_display = di->va_display; + info->native_display = di->native_display; + info->display_type = di->display_type; + info->display_name = NULL; - if (di->display_name) { - info->display_name = g_strdup(di->display_name); - if (!info->display_name) - goto error; - } - return entry; + if (di->display_name) { + info->display_name = g_strdup (di->display_name); + if (!info->display_name) + goto error; + } + return entry; error: - cache_entry_free(entry); - return NULL; + cache_entry_free (entry); + return NULL; } static inline gboolean -is_compatible_display_type(const GstVaapiDisplayType display_type, +is_compatible_display_type (const GstVaapiDisplayType display_type, guint display_types) { - if (display_type == GST_VAAPI_DISPLAY_TYPE_ANY) - return TRUE; - if (display_types == GST_VAAPI_DISPLAY_TYPE_ANY) - return TRUE; - return ((1U << display_type) & display_types) != 0; + if (display_type == GST_VAAPI_DISPLAY_TYPE_ANY) + return TRUE; + if (display_types == GST_VAAPI_DISPLAY_TYPE_ANY) + return TRUE; + return ((1U << display_type) & display_types) != 0; } static GList * -cache_lookup_1(GstVaapiDisplayCache *cache, GCompareFunc func, +cache_lookup_1 (GstVaapiDisplayCache * cache, GCompareFunc func, gconstpointer data, guint display_types) { - GList *l; + GList *l; - g_mutex_lock(&cache->mutex); - for (l = cache->list; l != NULL; l = l->next) { - GstVaapiDisplayInfo * const info = &((CacheEntry *)l->data)->info; - if (!is_compatible_display_type(info->display_type, display_types)) - continue; - if (func(info, data)) - break; - } - g_mutex_unlock(&cache->mutex); - return l; + g_mutex_lock (&cache->mutex); + for (l = cache->list; l != NULL; l = l->next) { + GstVaapiDisplayInfo *const info = &((CacheEntry *) l->data)->info; + if (!is_compatible_display_type (info->display_type, display_types)) + continue; + if (func (info, data)) + break; + } + g_mutex_unlock (&cache->mutex); + return l; } static inline const GstVaapiDisplayInfo * -cache_lookup(GstVaapiDisplayCache *cache, GCompareFunc func, +cache_lookup (GstVaapiDisplayCache * cache, GCompareFunc func, gconstpointer data, guint display_types) { - GList * const m = cache_lookup_1(cache, func, data, display_types); + GList *const m = cache_lookup_1 (cache, func, data, display_types); - return m ? &((CacheEntry *)m->data)->info : NULL; + return m ? &((CacheEntry *) m->data)->info : NULL; } static gint -compare_display(gconstpointer a, gconstpointer display) +compare_display (gconstpointer a, gconstpointer display) { - const GstVaapiDisplayInfo * const info = a; + const GstVaapiDisplayInfo *const info = a; - return info->display == display; + return info->display == display; } static gint -compare_va_display(gconstpointer a, gconstpointer va_display) +compare_va_display (gconstpointer a, gconstpointer va_display) { - const GstVaapiDisplayInfo * const info = a; + const GstVaapiDisplayInfo *const info = a; - return info->va_display == va_display; + return info->va_display == va_display; } static gint -compare_native_display(gconstpointer a, gconstpointer native_display) +compare_native_display (gconstpointer a, gconstpointer native_display) { - const GstVaapiDisplayInfo * const info = a; + const GstVaapiDisplayInfo *const info = a; - return info->native_display == native_display; + return info->native_display == native_display; } static gint -compare_display_name(gconstpointer a, gconstpointer b) +compare_display_name (gconstpointer a, gconstpointer b) { - const GstVaapiDisplayInfo * const info = a; - const gchar * const display_name = b; + const GstVaapiDisplayInfo *const info = a; + const gchar *const display_name = b; - if (info->display_name == NULL && display_name == NULL) - return TRUE; - if (!info->display_name || !display_name) - return FALSE; - return strcmp(info->display_name, display_name) == 0; + if (info->display_name == NULL && display_name == NULL) + return TRUE; + if (!info->display_name || !display_name) + return FALSE; + return strcmp (info->display_name, display_name) == 0; } /** @@ -167,16 +169,16 @@ compare_display_name(gconstpointer a, gconstpointer b) * Return value: the newly created #GstVaapiDisplayCache object */ GstVaapiDisplayCache * -gst_vaapi_display_cache_new(void) +gst_vaapi_display_cache_new (void) { - GstVaapiDisplayCache *cache; + GstVaapiDisplayCache *cache; - cache = g_slice_new0(GstVaapiDisplayCache); - if (!cache) - return NULL; + cache = g_slice_new0 (GstVaapiDisplayCache); + if (!cache) + return NULL; - g_mutex_init(&cache->mutex); - return cache; + g_mutex_init (&cache->mutex); + return cache; } /** @@ -186,21 +188,21 @@ gst_vaapi_display_cache_new(void) * Destroys a VA display cache. */ void -gst_vaapi_display_cache_free(GstVaapiDisplayCache *cache) +gst_vaapi_display_cache_free (GstVaapiDisplayCache * cache) { - GList *l; + GList *l; - if (!cache) - return; + if (!cache) + return; - if (cache->list) { - for (l = cache->list; l != NULL; l = l->next) - cache_entry_free(l->data); - g_list_free(cache->list); - cache->list = NULL; - } - g_mutex_clear(&cache->mutex); - g_slice_free(GstVaapiDisplayCache, cache); + if (cache->list) { + for (l = cache->list; l != NULL; l = l->next) + cache_entry_free (l->data); + g_list_free (cache->list); + cache->list = NULL; + } + g_mutex_clear (&cache->mutex); + g_slice_free (GstVaapiDisplayCache, cache); } /** @@ -212,16 +214,16 @@ gst_vaapi_display_cache_free(GstVaapiDisplayCache *cache) * Return value: the size of the display cache */ guint -gst_vaapi_display_cache_get_size(GstVaapiDisplayCache *cache) +gst_vaapi_display_cache_get_size (GstVaapiDisplayCache * cache) { - guint size; + guint size; - g_return_val_if_fail(cache != NULL, 0); + g_return_val_if_fail (cache != NULL, 0); - g_mutex_lock(&cache->mutex); - size = g_list_length(cache->list); - g_mutex_unlock(&cache->mutex); - return size; + g_mutex_lock (&cache->mutex); + size = g_list_length (cache->list); + g_mutex_unlock (&cache->mutex); + return size; } /** @@ -235,24 +237,22 @@ gst_vaapi_display_cache_get_size(GstVaapiDisplayCache *cache) * Return value: %TRUE on success */ gboolean -gst_vaapi_display_cache_add( - GstVaapiDisplayCache *cache, - GstVaapiDisplayInfo *info -) +gst_vaapi_display_cache_add (GstVaapiDisplayCache * cache, + GstVaapiDisplayInfo * info) { - CacheEntry *entry; + CacheEntry *entry; - g_return_val_if_fail(cache != NULL, FALSE); - g_return_val_if_fail(info != NULL, FALSE); + g_return_val_if_fail (cache != NULL, FALSE); + g_return_val_if_fail (info != NULL, FALSE); - entry = cache_entry_new(info); - if (!entry) - return FALSE; + entry = cache_entry_new (info); + if (!entry) + return FALSE; - g_mutex_lock(&cache->mutex); - cache->list = g_list_prepend(cache->list, entry); - g_mutex_unlock(&cache->mutex); - return TRUE; + g_mutex_lock (&cache->mutex); + cache->list = g_list_prepend (cache->list, entry); + g_mutex_unlock (&cache->mutex); + return TRUE; } /** @@ -263,22 +263,20 @@ gst_vaapi_display_cache_add( * Removes any cache entry that matches the specified #GstVaapiDisplay. */ void -gst_vaapi_display_cache_remove( - GstVaapiDisplayCache *cache, - GstVaapiDisplay *display -) +gst_vaapi_display_cache_remove (GstVaapiDisplayCache * cache, + GstVaapiDisplay * display) { - GList *m; + GList *m; - m = cache_lookup_1(cache, compare_display, display, - GST_VAAPI_DISPLAY_TYPE_ANY); - if (!m) - return; + m = cache_lookup_1 (cache, compare_display, display, + GST_VAAPI_DISPLAY_TYPE_ANY); + if (!m) + return; - cache_entry_free(m->data); - g_mutex_lock(&cache->mutex); - cache->list = g_list_delete_link(cache->list, m); - g_mutex_unlock(&cache->mutex); + cache_entry_free (m->data); + g_mutex_lock (&cache->mutex); + cache->list = g_list_delete_link (cache->list, m); + g_mutex_unlock (&cache->mutex); } /** @@ -292,16 +290,14 @@ gst_vaapi_display_cache_remove( * none was found */ const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup( - GstVaapiDisplayCache *cache, - GstVaapiDisplay *display -) +gst_vaapi_display_cache_lookup (GstVaapiDisplayCache * cache, + GstVaapiDisplay * display) { - g_return_val_if_fail(cache != NULL, NULL); - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail (cache != NULL, NULL); + g_return_val_if_fail (display != NULL, NULL); - return cache_lookup(cache, compare_display, display, - GST_VAAPI_DISPLAY_TYPE_ANY); + return cache_lookup (cache, compare_display, display, + GST_VAAPI_DISPLAY_TYPE_ANY); } /** @@ -324,17 +320,13 @@ gst_vaapi_display_cache_lookup( * (i.e. returning %TRUE), or %NULL if none was found */ const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_custom( - GstVaapiDisplayCache *cache, - GCompareFunc func, - gconstpointer data, - guint display_types -) +gst_vaapi_display_cache_lookup_custom (GstVaapiDisplayCache * cache, + GCompareFunc func, gconstpointer data, guint display_types) { - g_return_val_if_fail(cache != NULL, NULL); - g_return_val_if_fail(func != NULL, NULL); + g_return_val_if_fail (cache != NULL, NULL); + g_return_val_if_fail (func != NULL, NULL); - return cache_lookup(cache, func, data, display_types); + return cache_lookup (cache, func, data, display_types); } /** @@ -348,16 +340,14 @@ gst_vaapi_display_cache_lookup_custom( * if none was found */ const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_va_display( - GstVaapiDisplayCache *cache, - VADisplay va_display -) +gst_vaapi_display_cache_lookup_by_va_display (GstVaapiDisplayCache * cache, + VADisplay va_display) { - g_return_val_if_fail(cache != NULL, NULL); - g_return_val_if_fail(va_display != NULL, NULL); + g_return_val_if_fail (cache != NULL, NULL); + g_return_val_if_fail (va_display != NULL, NULL); - return cache_lookup(cache, compare_va_display, va_display, - GST_VAAPI_DISPLAY_TYPE_ANY); + return cache_lookup (cache, compare_va_display, va_display, + GST_VAAPI_DISPLAY_TYPE_ANY); } /** @@ -371,17 +361,14 @@ gst_vaapi_display_cache_lookup_by_va_display( * %NULL if none was found */ const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_native_display( - GstVaapiDisplayCache *cache, - gpointer native_display, - guint display_types -) +gst_vaapi_display_cache_lookup_by_native_display (GstVaapiDisplayCache * cache, + gpointer native_display, guint display_types) { - g_return_val_if_fail(cache != NULL, NULL); - g_return_val_if_fail(native_display != NULL, NULL); + g_return_val_if_fail (cache != NULL, NULL); + g_return_val_if_fail (native_display != NULL, NULL); - return cache_lookup(cache, compare_native_display, native_display, - display_types); + return cache_lookup (cache, compare_native_display, native_display, + display_types); } /** @@ -395,14 +382,11 @@ gst_vaapi_display_cache_lookup_by_native_display( * %NULL if none was found */ const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_name( - GstVaapiDisplayCache *cache, - const gchar *display_name, - guint display_types -) +gst_vaapi_display_cache_lookup_by_name (GstVaapiDisplayCache * cache, + const gchar * display_name, guint display_types) { - g_return_val_if_fail(cache != NULL, NULL); + g_return_val_if_fail (cache != NULL, NULL); - return cache_lookup(cache, compare_display_name, display_name, - display_types); + return cache_lookup (cache, compare_display_name, display_name, + display_types); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h index 1964b6b8e6..bbd2436735 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.h +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.h @@ -25,66 +25,48 @@ #include -typedef struct _GstVaapiDisplayCache GstVaapiDisplayCache; +typedef struct _GstVaapiDisplayCache GstVaapiDisplayCache; G_GNUC_INTERNAL GstVaapiDisplayCache * -gst_vaapi_display_cache_new(void); +gst_vaapi_display_cache_new (void); G_GNUC_INTERNAL void -gst_vaapi_display_cache_free(GstVaapiDisplayCache *cache); +gst_vaapi_display_cache_free (GstVaapiDisplayCache * cache); G_GNUC_INTERNAL guint -gst_vaapi_display_cache_get_size(GstVaapiDisplayCache *cache); +gst_vaapi_display_cache_get_size (GstVaapiDisplayCache * cache); G_GNUC_INTERNAL gboolean -gst_vaapi_display_cache_add( - GstVaapiDisplayCache *cache, - GstVaapiDisplayInfo *info -); +gst_vaapi_display_cache_add (GstVaapiDisplayCache * cache, + GstVaapiDisplayInfo * info); G_GNUC_INTERNAL void -gst_vaapi_display_cache_remove( - GstVaapiDisplayCache *cache, - GstVaapiDisplay *display -); +gst_vaapi_display_cache_remove (GstVaapiDisplayCache * cache, + GstVaapiDisplay * display); const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup( - GstVaapiDisplayCache *cache, - GstVaapiDisplay *display -); +gst_vaapi_display_cache_lookup (GstVaapiDisplayCache + * cache, GstVaapiDisplay * display); const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_custom( - GstVaapiDisplayCache *cache, - GCompareFunc func, - gconstpointer data, - guint display_types -); +gst_vaapi_display_cache_lookup_custom (GstVaapiDisplayCache * cache, + GCompareFunc func, gconstpointer data, guint display_types); const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_va_display( - GstVaapiDisplayCache *cache, - VADisplay va_display -); +gst_vaapi_display_cache_lookup_by_va_display (GstVaapiDisplayCache * cache, + VADisplay va_display); const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_native_display( - GstVaapiDisplayCache *cache, - gpointer native_display, - guint display_types -); +gst_vaapi_display_cache_lookup_by_native_display (GstVaapiDisplayCache * + cache, gpointer native_display, guint display_types); const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_name( - GstVaapiDisplayCache *cache, - const gchar *display_name, - guint display_types -); +gst_vaapi_display_cache_lookup_by_name (GstVaapiDisplayCache * cache, + const gchar * display_name, guint display_types); #endif /* GSTVAAPIDISPLAYCACHE_H */ From 446b060c7a3946c18d11e8301f820f87b8c3b8aa Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Dec 2013 14:01:45 +0100 Subject: [PATCH 1474/3781] display: allocate queried resources on-demand. Allocate the set of decoders or encoders on-demand, when they are queried. Likewise for VA display attributes, image and subpicture formats. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 539 ++++++++++++++-------- gst-libs/gst/vaapi/gstvaapidisplay.h | 3 + gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 3 +- 3 files changed, 340 insertions(+), 205 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 7aa28eb58d..fa949b5d9f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -483,6 +483,275 @@ find_property_id (const gchar * name) return 0; } +/* Initialize VA profiles (decoders, encoders) */ +static gboolean +ensure_profiles (GstVaapiDisplay * display) +{ + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + VAProfile *profiles = NULL; + VAEntrypoint *entrypoints = NULL; + gint i, j, n, num_entrypoints; + VAStatus status; + gboolean success = FALSE; + + if (priv->has_profiles) + return TRUE; + + priv->decoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig)); + if (!priv->decoders) + goto cleanup; + priv->encoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig)); + if (!priv->encoders) + goto cleanup; + priv->has_profiles = TRUE; + + /* VA profiles */ + profiles = g_new (VAProfile, vaMaxNumProfiles (priv->display)); + if (!profiles) + goto cleanup; + entrypoints = g_new (VAEntrypoint, vaMaxNumEntrypoints (priv->display)); + if (!entrypoints) + goto cleanup; + + n = 0; + status = vaQueryConfigProfiles (priv->display, profiles, &n); + if (!vaapi_check_status (status, "vaQueryConfigProfiles()")) + goto cleanup; + + GST_DEBUG ("%d profiles", n); + for (i = 0; i < n; i++) { +#if VA_CHECK_VERSION(0,34,0) + /* Introduced in VA/VPP API */ + if (profiles[i] == VAProfileNone) + continue; +#endif + GST_DEBUG (" %s", string_of_VAProfile (profiles[i])); + } + + for (i = 0; i < n; i++) { + GstVaapiConfig config; + + config.profile = gst_vaapi_profile (profiles[i]); + if (!config.profile) + continue; + + status = vaQueryConfigEntrypoints (priv->display, + profiles[i], entrypoints, &num_entrypoints); + if (!vaapi_check_status (status, "vaQueryConfigEntrypoints()")) + continue; + + for (j = 0; j < num_entrypoints; j++) { + config.entrypoint = gst_vaapi_entrypoint (entrypoints[j]); + switch (config.entrypoint) { + case GST_VAAPI_ENTRYPOINT_VLD: + case GST_VAAPI_ENTRYPOINT_IDCT: + case GST_VAAPI_ENTRYPOINT_MOCO: + g_array_append_val (priv->decoders, config); + break; + case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: + g_array_append_val (priv->encoders, config); + break; + } + } + } + append_h263_config (priv->decoders); + + /* Video processing API */ +#if USE_VA_VPP + status = vaQueryConfigEntrypoints (priv->display, VAProfileNone, + entrypoints, &num_entrypoints); + if (vaapi_check_status (status, "vaQueryEntrypoints() [VAProfileNone]")) { + for (j = 0; j < num_entrypoints; j++) { + if (entrypoints[j] == VAEntrypointVideoProc) + priv->has_vpp = TRUE; + } + } +#endif + success = TRUE; + +cleanup: + g_free (profiles); + g_free (entrypoints); + return success; +} + +/* Initialize VA display attributes */ +static gboolean +ensure_properties (GstVaapiDisplay * display) +{ + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + VADisplayAttribute *display_attrs = NULL; + VAStatus status; + gint i, n; + gboolean success = FALSE; + + if (priv->properties) + return TRUE; + + priv->properties = g_array_new (FALSE, FALSE, sizeof (GstVaapiProperty)); + if (!priv->properties) + goto cleanup; + + /* VA display attributes */ + display_attrs = + g_new (VADisplayAttribute, vaMaxNumDisplayAttributes (priv->display)); + if (!display_attrs) + goto cleanup; + + n = 0; + status = vaQueryDisplayAttributes (priv->display, display_attrs, &n); + if (!vaapi_check_status (status, "vaQueryDisplayAttributes()")) + goto cleanup; + + GST_DEBUG ("%d display attributes", n); + for (i = 0; i < n; i++) { + VADisplayAttribute *const attr = &display_attrs[i]; + GstVaapiProperty prop; + gint value; + + GST_DEBUG (" %s", string_of_VADisplayAttributeType (attr->type)); + + switch (attr->type) { +#if !VA_CHECK_VERSION(0,34,0) + case VADisplayAttribDirectSurface: + prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; + break; +#endif + case VADisplayAttribRenderMode: + prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; + break; + case VADisplayAttribRotation: + prop.name = GST_VAAPI_DISPLAY_PROP_ROTATION; + break; + case VADisplayAttribHue: + prop.name = GST_VAAPI_DISPLAY_PROP_HUE; + break; + case VADisplayAttribSaturation: + prop.name = GST_VAAPI_DISPLAY_PROP_SATURATION; + break; + case VADisplayAttribBrightness: + prop.name = GST_VAAPI_DISPLAY_PROP_BRIGHTNESS; + break; + case VADisplayAttribContrast: + prop.name = GST_VAAPI_DISPLAY_PROP_CONTRAST; + break; + default: + prop.name = NULL; + break; + } + if (!prop.name) + continue; + + /* Assume the attribute is really supported if we can get the + * actual and current value */ + if (!get_attribute (display, attr->type, &value)) + continue; + + /* Some drivers (e.g. EMGD) have completely random initial + * values */ + if (value < attr->min_value || value > attr->max_value) + continue; + + prop.attribute = *attr; + prop.old_value = value; + g_array_append_val (priv->properties, prop); + } + success = TRUE; + +cleanup: + g_free (display_attrs); + return success; +} + +/* Initialize VA image formats */ +static gboolean +ensure_image_formats (GstVaapiDisplay * display) +{ + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + VAImageFormat *formats = NULL; + VAStatus status; + gint i, n; + gboolean success = FALSE; + + if (priv->image_formats) + return TRUE; + + priv->image_formats = g_array_new (FALSE, FALSE, sizeof (GstVaapiFormatInfo)); + if (!priv->image_formats) + goto cleanup; + + /* VA image formats */ + formats = g_new (VAImageFormat, vaMaxNumImageFormats (priv->display)); + if (!formats) + goto cleanup; + + n = 0; + status = vaQueryImageFormats (priv->display, formats, &n); + if (!vaapi_check_status (status, "vaQueryImageFormats()")) + goto cleanup; + + GST_DEBUG ("%d image formats", n); + for (i = 0; i < n; i++) + GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc)); + + append_formats (priv->image_formats, formats, NULL, n); + g_array_sort (priv->image_formats, compare_yuv_formats); + success = TRUE; + +cleanup: + g_free (formats); + return success; +} + +/* Initialize VA subpicture formats */ +static gboolean +ensure_subpicture_formats (GstVaapiDisplay * display) +{ + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + VAImageFormat *formats = NULL; + unsigned int *flags = NULL; + VAStatus status; + guint i, n; + gboolean success = FALSE; + + if (priv->subpicture_formats) + return TRUE; + + priv->subpicture_formats = + g_array_new (FALSE, FALSE, sizeof (GstVaapiFormatInfo)); + if (!priv->subpicture_formats) + goto cleanup; + + /* VA subpicture formats */ + n = vaMaxNumSubpictureFormats (priv->display); + formats = g_new (VAImageFormat, n); + if (!formats) + goto cleanup; + flags = g_new (guint, n); + if (!flags) + goto cleanup; + + n = 0; + status = vaQuerySubpictureFormats (priv->display, formats, flags, &n); + if (!vaapi_check_status (status, "vaQuerySubpictureFormats()")) + goto cleanup; + + GST_DEBUG ("%d subpicture formats", n); + for (i = 0; i < n; i++) { + GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc)); + flags[i] = to_GstVaapiSubpictureFlags (flags[i]); + } + + append_formats (priv->subpicture_formats, formats, flags, n); + g_array_sort (priv->subpicture_formats, compare_rgb_formats); + success = TRUE; + +cleanup: + g_free (formats); + g_free (flags); + return success; +} + static void gst_vaapi_display_calculate_pixel_aspect_ratio (GstVaapiDisplay * display) { @@ -590,13 +859,7 @@ gst_vaapi_display_create (GstVaapiDisplay * display, const GstVaapiDisplayClass *const klass = GST_VAAPI_DISPLAY_GET_CLASS (display); GstVaapiDisplayCache *cache; - gboolean has_errors = TRUE; - VADisplayAttribute *display_attrs = NULL; - VAProfile *profiles = NULL; - VAEntrypoint *entrypoints = NULL; - VAImageFormat *formats = NULL; - unsigned int *flags = NULL; - gint i, j, n, num_entrypoints, major_version, minor_version; + gint major_version, minor_version; VAStatus status; GstVaapiDisplayInfo info; const GstVaapiDisplayInfo *cached_info = NULL; @@ -647,202 +910,15 @@ gst_vaapi_display_create (GstVaapiDisplay * display, if (!priv->parent) { status = vaInitialize (priv->display, &major_version, &minor_version); if (!vaapi_check_status (status, "vaInitialize()")) - goto end; + return FALSE; GST_DEBUG ("VA-API version %d.%d", major_version, minor_version); } - /* VA profiles */ - profiles = g_new (VAProfile, vaMaxNumProfiles (priv->display)); - if (!profiles) - goto end; - entrypoints = g_new (VAEntrypoint, vaMaxNumEntrypoints (priv->display)); - if (!entrypoints) - goto end; - status = vaQueryConfigProfiles (priv->display, profiles, &n); - if (!vaapi_check_status (status, "vaQueryConfigProfiles()")) - goto end; - - GST_DEBUG ("%d profiles", n); - for (i = 0; i < n; i++) { -#if VA_CHECK_VERSION(0,34,0) - /* Introduced in VA/VPP API */ - if (profiles[i] == VAProfileNone) - continue; -#endif - GST_DEBUG (" %s", string_of_VAProfile (profiles[i])); - } - - priv->decoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig)); - if (!priv->decoders) - goto end; - priv->encoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig)); - if (!priv->encoders) - goto end; - - for (i = 0; i < n; i++) { - GstVaapiConfig config; - - config.profile = gst_vaapi_profile (profiles[i]); - if (!config.profile) - continue; - - status = vaQueryConfigEntrypoints (priv->display, - profiles[i], entrypoints, &num_entrypoints); - if (!vaapi_check_status (status, "vaQueryConfigEntrypoints()")) - continue; - - for (j = 0; j < num_entrypoints; j++) { - config.entrypoint = gst_vaapi_entrypoint (entrypoints[j]); - switch (config.entrypoint) { - case GST_VAAPI_ENTRYPOINT_VLD: - case GST_VAAPI_ENTRYPOINT_IDCT: - case GST_VAAPI_ENTRYPOINT_MOCO: - g_array_append_val (priv->decoders, config); - break; - case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: - g_array_append_val (priv->encoders, config); - break; - } - } - } - append_h263_config (priv->decoders); - - /* Video processing API */ -#if USE_VA_VPP - status = vaQueryConfigEntrypoints (priv->display, VAProfileNone, - entrypoints, &num_entrypoints); - if (vaapi_check_status (status, "vaQueryEntrypoints() [VAProfileNone]")) { - for (j = 0; j < num_entrypoints; j++) { - if (entrypoints[j] == VAEntrypointVideoProc) - priv->has_vpp = TRUE; - } - } -#endif - - /* VA display attributes */ - display_attrs = - g_new (VADisplayAttribute, vaMaxNumDisplayAttributes (priv->display)); - if (!display_attrs) - goto end; - - n = 0; /* XXX: workaround old GMA500 bug */ - status = vaQueryDisplayAttributes (priv->display, display_attrs, &n); - if (!vaapi_check_status (status, "vaQueryDisplayAttributes()")) - goto end; - - priv->properties = g_array_new (FALSE, FALSE, sizeof (GstVaapiProperty)); - if (!priv->properties) - goto end; - - GST_DEBUG ("%d display attributes", n); - for (i = 0; i < n; i++) { - VADisplayAttribute *const attr = &display_attrs[i]; - GstVaapiProperty prop; - gint value; - - GST_DEBUG (" %s", string_of_VADisplayAttributeType (attr->type)); - - switch (attr->type) { -#if !VA_CHECK_VERSION(0,34,0) - case VADisplayAttribDirectSurface: - prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; - break; -#endif - case VADisplayAttribRenderMode: - prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; - break; - case VADisplayAttribRotation: - prop.name = GST_VAAPI_DISPLAY_PROP_ROTATION; - break; - case VADisplayAttribHue: - prop.name = GST_VAAPI_DISPLAY_PROP_HUE; - break; - case VADisplayAttribSaturation: - prop.name = GST_VAAPI_DISPLAY_PROP_SATURATION; - break; - case VADisplayAttribBrightness: - prop.name = GST_VAAPI_DISPLAY_PROP_BRIGHTNESS; - break; - case VADisplayAttribContrast: - prop.name = GST_VAAPI_DISPLAY_PROP_CONTRAST; - break; - default: - prop.name = NULL; - break; - } - if (!prop.name) - continue; - - /* Assume the attribute is really supported if we can get the - * actual and current value */ - if (!get_attribute (display, attr->type, &value)) - continue; - - /* Some drivers (e.g. EMGD) have completely random initial - * values */ - if (value < attr->min_value || value > attr->max_value) - continue; - - prop.attribute = *attr; - prop.old_value = value; - g_array_append_val (priv->properties, prop); - } - - /* VA image formats */ - formats = g_new (VAImageFormat, vaMaxNumImageFormats (priv->display)); - if (!formats) - goto end; - status = vaQueryImageFormats (priv->display, formats, &n); - if (!vaapi_check_status (status, "vaQueryImageFormats()")) - goto end; - - GST_DEBUG ("%d image formats", n); - for (i = 0; i < n; i++) - GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc)); - - priv->image_formats = g_array_new (FALSE, FALSE, sizeof (GstVaapiFormatInfo)); - if (!priv->image_formats) - goto end; - append_formats (priv->image_formats, formats, NULL, n); - g_array_sort (priv->image_formats, compare_yuv_formats); - - /* VA subpicture formats */ - n = vaMaxNumSubpictureFormats (priv->display); - formats = g_renew (VAImageFormat, formats, n); - flags = g_new (guint, n); - if (!formats || !flags) - goto end; - status = - vaQuerySubpictureFormats (priv->display, formats, flags, (guint *) & n); - if (!vaapi_check_status (status, "vaQuerySubpictureFormats()")) - goto end; - - GST_DEBUG ("%d subpicture formats", n); - for (i = 0; i < n; i++) { - GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc)); - flags[i] = to_GstVaapiSubpictureFlags (flags[i]); - } - - priv->subpicture_formats = - g_array_new (FALSE, FALSE, sizeof (GstVaapiFormatInfo)); - if (!priv->subpicture_formats) - goto end; - append_formats (priv->subpicture_formats, formats, flags, n); - g_array_sort (priv->subpicture_formats, compare_rgb_formats); - if (!cached_info) { if (!gst_vaapi_display_cache_add (cache, &info)) - goto end; + return FALSE; } - - has_errors = FALSE; -end: - g_free (display_attrs); - g_free (profiles); - g_free (entrypoints); - g_free (formats); - g_free (flags); - return !has_errors; + return TRUE; } static void @@ -1270,6 +1346,25 @@ gst_vaapi_display_get_pixel_aspect_ratio (GstVaapiDisplay * display, *par_d = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->par_d; } +/** + * gst_vaapi_display_has_video_processing: + * @display: a #GstVaapiDisplay + * + * Checks whether the underlying VA driver implementation supports + * video processing (VPP) acceleration. + * + * Returns: %TRUE if some VPP features are available + */ +gboolean +gst_vaapi_display_has_video_processing (GstVaapiDisplay * display) +{ + g_return_val_if_fail (display != NULL, FALSE); + + if (!ensure_profiles (display)) + return FALSE; + return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->has_vpp; +} + /** * gst_vaapi_display_get_decode_caps: * @display: a #GstVaapiDisplay @@ -1283,6 +1378,8 @@ gst_vaapi_display_get_decode_caps (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, NULL); + if (!ensure_profiles (display)) + return NULL; return get_profile_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders); } @@ -1303,6 +1400,8 @@ gst_vaapi_display_has_decoder (GstVaapiDisplay * display, { g_return_val_if_fail (display != NULL, FALSE); + if (!ensure_profiles (display)) + return FALSE; return find_config (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders, profile, entrypoint); } @@ -1320,6 +1419,8 @@ gst_vaapi_display_get_encode_caps (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, NULL); + if (!ensure_profiles (display)) + return NULL; return get_profile_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders); } @@ -1340,6 +1441,8 @@ gst_vaapi_display_has_encoder (GstVaapiDisplay * display, { g_return_val_if_fail (display != NULL, FALSE); + if (!ensure_profiles (display)) + return FALSE; return find_config (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders, profile, entrypoint); } @@ -1365,6 +1468,8 @@ gst_vaapi_display_get_image_caps (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, NULL); + if (!ensure_image_formats (display)) + return NULL; return get_format_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> image_formats); } @@ -1382,19 +1487,25 @@ gboolean gst_vaapi_display_has_image_format (GstVaapiDisplay * display, GstVideoFormat format) { + GstVaapiDisplayPrivate *priv; + g_return_val_if_fail (display != NULL, FALSE); g_return_val_if_fail (format, FALSE); - if (find_format (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->image_formats, - format)) + priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + + if (!ensure_image_formats (display)) + return FALSE; + if (find_format (priv->image_formats, format)) return TRUE; /* XXX: try subpicture formats since some drivers could report a * set of VA image formats that is not a superset of the set of VA * subpicture formats */ - return find_format (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> - subpicture_formats, format); + if (!ensure_subpicture_formats (display)) + return FALSE; + return find_format (priv->subpicture_formats, format); } /** @@ -1415,6 +1526,8 @@ gst_vaapi_display_get_subpicture_caps (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, NULL); + if (!ensure_subpicture_formats (display)) + return NULL; return get_format_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> subpicture_formats); } @@ -1434,14 +1547,18 @@ gboolean gst_vaapi_display_has_subpicture_format (GstVaapiDisplay * display, GstVideoFormat format, guint * flags_ptr) { + GstVaapiDisplayPrivate *priv; const GstVaapiFormatInfo *fip; g_return_val_if_fail (display != NULL, FALSE); g_return_val_if_fail (format, FALSE); - fip = - find_format_info (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> - subpicture_formats, format); + priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + + if (!ensure_subpicture_formats (display)) + return FALSE; + + fip = find_format_info (priv->subpicture_formats, format); if (!fip) return FALSE; @@ -1468,6 +1585,8 @@ gst_vaapi_display_has_property (GstVaapiDisplay * display, const gchar * name) g_return_val_if_fail (display != NULL, FALSE); g_return_val_if_fail (name, FALSE); + if (!ensure_properties (display)) + return FALSE; return find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, name) != NULL; } @@ -1482,6 +1601,9 @@ gst_vaapi_display_get_property (GstVaapiDisplay * display, const gchar * name, g_return_val_if_fail (name != NULL, FALSE); g_return_val_if_fail (out_value != NULL, FALSE); + if (!ensure_properties (display)) + return FALSE; + prop = find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, name); if (!prop) @@ -1531,6 +1653,9 @@ gst_vaapi_display_set_property (GstVaapiDisplay * display, const gchar * name, g_return_val_if_fail (name != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); + if (!ensure_properties (display)) + return FALSE; + prop = find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, name); if (!prop) @@ -1800,6 +1925,9 @@ get_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat * v) gfloat out_value; gint value; + if (!ensure_properties (display)) + return FALSE; + if (!pspec) return FALSE; @@ -1834,6 +1962,9 @@ set_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat v) const VADisplayAttribute *attr; gint value; + if (!ensure_properties (display)) + return FALSE; + if (!pspec) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 6d2383762e..2c28c268d0 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -141,6 +141,9 @@ 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); + GstCaps * gst_vaapi_display_get_decode_caps (GstVaapiDisplay * display); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 18626bdbb8..1d1396427b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -126,7 +126,7 @@ typedef void (*GstVaapiDisplayGetSizeMFunc) (GstVaapiDisplay * display, */ #undef GST_VAAPI_DISPLAY_HAS_VPP #define GST_VAAPI_DISPLAY_HAS_VPP(display) \ - (GST_VAAPI_DISPLAY_GET_PRIVATE(display)->has_vpp) + gst_vaapi_display_has_video_processing(GST_VAAPI_DISPLAY_CAST(display)) struct _GstVaapiDisplayPrivate { @@ -147,6 +147,7 @@ struct _GstVaapiDisplayPrivate GArray *properties; guint use_foreign_display:1; guint has_vpp:1; + guint has_profiles:1; }; /** From c4ca08a8d6e4427d723c420ef772250ac0b8916e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Dec 2013 15:15:05 +0100 Subject: [PATCH 1475/3781] display: don't use GstCaps for image or subpicture formats list. Replace gst_vaapi_display_get_{image,subpicture}_caps() APIs, that returned GstCaps, with more convenient APIs that return an array of GstVideoFormat: gst_vaapi_display_get_{image,subpicture}_formats(). --- gst-libs/gst/vaapi/gstvaapidisplay.c | 51 ++++++++++++++++------------ gst-libs/gst/vaapi/gstvaapidisplay.h | 8 ++--- gst/vaapi/gstvaapidownload.c | 17 ++++++++-- gst/vaapi/gstvaapiuploader.c | 23 ++++++------- tests/test-display.c | 49 ++++++++++++-------------- 5 files changed, 80 insertions(+), 68 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index fa949b5d9f..ec2dcdcd70 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -394,24 +394,22 @@ find_format (GArray * formats, GstVideoFormat format) } /* Convert formats array to GstCaps */ -static GstCaps * -get_format_caps (GArray * formats) +static GArray * +get_formats (GArray * formats) { const GstVaapiFormatInfo *fip; - GstCaps *out_caps, *caps; + GArray *out_formats; guint i; - out_caps = gst_caps_new_empty (); - if (!out_caps) + out_formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat)); + if (!out_formats) return NULL; for (i = 0; i < formats->len; i++) { fip = &g_array_index (formats, GstVaapiFormatInfo, i); - caps = gst_vaapi_video_format_to_caps (fip->format); - if (caps) - gst_caps_append (out_caps, caps); + g_array_append_val (out_formats, fip->format); } - return out_caps; + return out_formats; } /* Find display attribute */ @@ -1448,11 +1446,11 @@ gst_vaapi_display_has_encoder (GstVaapiDisplay * display, } /** - * gst_vaapi_display_get_image_caps: + * gst_vaapi_display_get_image_formats: * @display: a #GstVaapiDisplay * * Gets the supported image formats for gst_vaapi_surface_get_image() - * or gst_vaapi_surface_put_image() as #GstCaps capabilities. + * or gst_vaapi_surface_put_image(). * * Note that this method does not necessarily map image formats * returned by vaQueryImageFormats(). The set of capabilities can be @@ -1461,17 +1459,21 @@ gst_vaapi_display_has_encoder (GstVaapiDisplay * display, * driver. e.g. I420 can be supported even if the driver only exposes * YV12. * - * Return value: a newly allocated #GstCaps object, possibly empty + * Note: the caller owns an extra reference to the resulting array of + * #GstVideoFormat elements, so it shall be released with + * g_array_unref() after usage. + * + * Return value: a newly allocated #GArray, or %NULL on error or if + * the set is empty */ -GstCaps * -gst_vaapi_display_get_image_caps (GstVaapiDisplay * display) +GArray * +gst_vaapi_display_get_image_formats (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, NULL); if (!ensure_image_formats (display)) return NULL; - return get_format_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> - image_formats); + return get_formats (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->image_formats); } /** @@ -1509,26 +1511,31 @@ gst_vaapi_display_has_image_format (GstVaapiDisplay * display, } /** - * gst_vaapi_display_get_subpicture_caps: + * gst_vaapi_display_get_subpicture_formats: * @display: a #GstVaapiDisplay * - * Gets the supported subpicture formats as #GstCaps capabilities. + * Gets the supported subpicture formats. * * Note that this method does not necessarily map subpicture formats * returned by vaQuerySubpictureFormats(). The set of capabilities can * be stripped down if gstreamer-vaapi does not support the * format. e.g. this is the case for paletted formats like IA44. * - * Return value: a newly allocated #GstCaps object, possibly empty + * Note: the caller owns an extra reference to the resulting array of + * #GstVideoFormat elements, so it shall be released with + * g_array_unref() after usage. + * + * Return value: a newly allocated #GArray, or %NULL on error of if + * the set is empty */ -GstCaps * -gst_vaapi_display_get_subpicture_caps (GstVaapiDisplay * display) +GArray * +gst_vaapi_display_get_subpicture_formats (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, NULL); if (!ensure_subpicture_formats (display)) return NULL; - return get_format_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> + return get_formats (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> subpicture_formats); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 2c28c268d0..75518a0369 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -158,15 +158,15 @@ gboolean gst_vaapi_display_has_encoder (GstVaapiDisplay * display, GstVaapiProfile profile, GstVaapiEntrypoint entrypoint); -GstCaps * -gst_vaapi_display_get_image_caps (GstVaapiDisplay * display); +GArray * +gst_vaapi_display_get_image_formats (GstVaapiDisplay * display); gboolean gst_vaapi_display_has_image_format (GstVaapiDisplay * display, GstVideoFormat format); -GstCaps * -gst_vaapi_display_get_subpicture_caps (GstVaapiDisplay * display); +GArray * +gst_vaapi_display_get_subpicture_formats (GstVaapiDisplay * display); gboolean gst_vaapi_display_has_subpicture_format (GstVaapiDisplay * display, diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 40df273c44..904570bfc5 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -391,6 +391,8 @@ gst_vaapidownload_transform_caps( GstPad *srcpad; GstCaps *allowed_caps, *inter_caps, *out_caps = NULL; GstStructure *structure; + GArray *formats; + guint i; g_return_val_if_fail(GST_IS_CAPS(caps), NULL); @@ -409,10 +411,21 @@ gst_vaapidownload_transform_caps( if (download->allowed_caps) allowed_caps = gst_caps_ref(download->allowed_caps); else { - allowed_caps = gst_vaapi_display_get_image_caps( - GST_VAAPI_PLUGIN_BASE_DISPLAY(download)); + allowed_caps = gst_caps_new_empty(); if (!allowed_caps) return NULL; + + formats = gst_vaapi_display_get_image_formats( + GST_VAAPI_PLUGIN_BASE_DISPLAY(download)); + if (formats) { + for (i = 0; i < formats->len; i++) { + const GstVideoFormat format = + g_array_index(formats, GstVideoFormat, i); + gst_caps_merge(allowed_caps, + gst_vaapi_video_format_to_caps(format)); + } + g_array_unref(formats); + } } inter_caps = gst_caps_intersect(out_caps, allowed_caps); gst_caps_unref(allowed_caps); diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 61b9ad49ad..b28cfe8038 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -112,8 +112,9 @@ ensure_allowed_caps(GstVaapiUploader *uploader) { GstVaapiUploaderPrivate * const priv = uploader->priv; GstVaapiSurface *surface = NULL; - GstCaps *out_caps, *image_caps = NULL; - guint i, n_structures; + GArray *image_formats = NULL; + GstCaps *out_caps; + guint i; gboolean success = FALSE; enum { WIDTH = 64, HEIGHT = 64 }; @@ -125,8 +126,8 @@ ensure_allowed_caps(GstVaapiUploader *uploader) if (!out_caps) return FALSE; - image_caps = gst_vaapi_display_get_image_caps(priv->display); - if (!image_caps) + image_formats = gst_vaapi_display_get_image_formats(priv->display); + if (!image_formats) goto end; surface = gst_vaapi_surface_new(priv->display, @@ -134,20 +135,18 @@ ensure_allowed_caps(GstVaapiUploader *uploader) if (!surface) goto end; - n_structures = gst_caps_get_size(image_caps); - for (i = 0; i < n_structures; i++) { - GstStructure * const structure = gst_caps_get_structure(image_caps, i); + for (i = 0; i < image_formats->len; i++) { + const GstVideoFormat format = + g_array_index(image_formats, GstVideoFormat, i); GstVaapiImage *image; - GstVideoFormat format; - format = gst_vaapi_video_format_from_structure(structure); if (format == GST_VIDEO_FORMAT_UNKNOWN) continue; image = gst_vaapi_image_new(priv->display, format, WIDTH, HEIGHT); if (!image) continue; if (ensure_image(image) && gst_vaapi_surface_put_image(surface, image)) - gst_caps_append_structure(out_caps, gst_structure_copy(structure)); + gst_caps_append(out_caps, gst_vaapi_video_format_to_caps(format)); gst_vaapi_object_unref(image); } @@ -156,8 +155,8 @@ ensure_allowed_caps(GstVaapiUploader *uploader) end: gst_caps_unref(out_caps); - if (image_caps) - gst_caps_unref(image_caps); + if (image_formats) + g_array_unref(image_formats); if (surface) gst_vaapi_object_unref(surface); return success; diff --git a/tests/test-display.c b/tests/test-display.c index 43ccb10b35..163ab503ea 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -94,7 +94,7 @@ print_profile_caps(GstCaps *caps, const gchar *name) } static void -print_format_caps_yuv(const VAImageFormat *va_format) +print_format_yuv(const VAImageFormat *va_format) { const guint32 fourcc = va_format->fourcc; @@ -106,7 +106,7 @@ print_format_caps_yuv(const VAImageFormat *va_format) } static void -print_format_caps_rgb(const VAImageFormat *va_format) +print_format_rgb(const VAImageFormat *va_format) { g_print(" %d bits per pixel, %s endian,", va_format->bits_per_pixel, @@ -119,34 +119,26 @@ print_format_caps_rgb(const VAImageFormat *va_format) } static void -print_format_caps(GstCaps *caps, const gchar *name) +print_formats(GArray *formats, const gchar *name) { - guint i, n_caps = gst_caps_get_size(caps); + guint i; - g_print("%u %s caps\n", n_caps, name); + g_print("%u %s caps\n", formats->len, name); - for (i = 0; i < gst_caps_get_size(caps); i++) { - GstStructure * const structure = gst_caps_get_structure(caps, i); + for (i = 0; i < formats->len; i++) { + const GstVideoFormat format = g_array_index(formats, GstVideoFormat, i); const VAImageFormat *va_format; - GstVideoFormat format; - if (!structure) - g_error("could not get caps structure %d", i); - - g_print(" %s:", gst_structure_get_name(structure)); - - format = gst_vaapi_video_format_from_structure(structure); - if (format == GST_VIDEO_FORMAT_UNKNOWN) - g_error("could not determine format"); + g_print(" %s:", gst_vaapi_video_format_to_string(format)); va_format = gst_vaapi_video_format_to_va_format(format); if (!va_format) g_error("could not determine VA format"); if (gst_vaapi_video_format_is_yuv(format)) - print_format_caps_yuv(va_format); + print_format_yuv(va_format); else - print_format_caps_rgb(va_format); + print_format_rgb(va_format); g_print("\n"); } } @@ -240,6 +232,7 @@ end: static void dump_info(GstVaapiDisplay *display) { + GArray *formats; GstCaps *caps; caps = gst_vaapi_display_get_decode_caps(display); @@ -256,19 +249,19 @@ dump_info(GstVaapiDisplay *display) print_profile_caps(caps, "encoders"); gst_caps_unref(caps); - caps = gst_vaapi_display_get_image_caps(display); - if (!caps) - g_error("could not get VA image caps"); + formats = gst_vaapi_display_get_image_formats(display); + if (!formats) + g_error("could not get VA image formats"); - print_format_caps(caps, "image"); - gst_caps_unref(caps); + print_formats(formats, "image"); + g_array_unref(formats); - caps = gst_vaapi_display_get_subpicture_caps(display); - if (!caps) - g_error("could not get VA subpicture caps"); + formats = gst_vaapi_display_get_subpicture_formats(display); + if (!formats) + g_error("could not get VA subpicture formats"); - print_format_caps(caps, "subpicture"); - gst_caps_unref(caps); + print_formats(formats, "subpicture"); + g_array_unref(formats); dump_properties(display); } From c5581298fbf66f3a1d37014a0bf3d6178c7b5ee1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Dec 2013 15:31:14 +0100 Subject: [PATCH 1476/3781] display: don't use GstCaps for decode or encode profiles list. Replace gst_vaapi_display_get_{decode,encode}_caps() APIs with more more convenient APIs that return an array of GstVaapiProfile instead of GstCaps: gst_vaapi_display_get_{decode,encode}_profiles(). --- gst-libs/gst/vaapi/gstvaapidisplay.c | 62 +++++++++++++++++---------- gst-libs/gst/vaapi/gstvaapidisplay.h | 8 ++-- gst/vaapi/gstvaapidecode.c | 51 +++++++++++----------- tests/test-display.c | 63 +++++++++++++--------------- 4 files changed, 102 insertions(+), 82 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index ec2dcdcd70..6cdc9edb38 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -347,28 +347,39 @@ append_h263_config (GArray * configs) } } +/* Sort profiles. Group per codec */ +static gint +compare_profiles (gconstpointer a, gconstpointer b) +{ + const GstVaapiConfig *const config1 = (GstVaapiConfig *) a; + const GstVaapiConfig *const config2 = (GstVaapiConfig *) b; + + if (config1->profile == config2->profile) + return config1->entrypoint - config2->entrypoint; + + return config1->profile - config2->profile; +} + /* Convert configs array to profiles as GstCaps */ -static GstCaps * -get_profile_caps (GArray * configs) +static GArray * +get_profiles (GArray * configs) { GstVaapiConfig *config; - GstCaps *out_caps, *caps; + GArray *out_profiles; guint i; if (!configs) return NULL; - out_caps = gst_caps_new_empty (); - if (!out_caps) + out_profiles = g_array_new (FALSE, FALSE, sizeof (GstVaapiProfile)); + if (!out_profiles) return NULL; for (i = 0; i < configs->len; i++) { config = &g_array_index (configs, GstVaapiConfig, i); - caps = gst_vaapi_profile_get_caps (config->profile); - if (caps) - out_caps = gst_caps_merge (out_caps, caps); + g_array_append_val (out_profiles, config->profile); } - return out_caps; + return out_profiles; } /* Find format info */ @@ -554,6 +565,9 @@ ensure_profiles (GstVaapiDisplay * display) } append_h263_config (priv->decoders); + g_array_sort (priv->decoders, compare_profiles); + g_array_sort (priv->encoders, compare_profiles); + /* Video processing API */ #if USE_VA_VPP status = vaQueryConfigEntrypoints (priv->display, VAProfileNone, @@ -1364,21 +1378,24 @@ gst_vaapi_display_has_video_processing (GstVaapiDisplay * display) } /** - * gst_vaapi_display_get_decode_caps: + * gst_vaapi_display_get_decode_profiles: * @display: a #GstVaapiDisplay * - * Gets the supported profiles for decoding as #GstCaps capabilities. + * Gets the supported profiles for decoding. The caller owns an extra + * reference to the resulting array of #GstVaapiProfile elements, so + * it shall be released with g_array_unref() after usage. * - * Return value: a newly allocated #GstCaps object, possibly empty + * Return value: a newly allocated #GArray, or %NULL or error or if + * decoding is not supported at all */ -GstCaps * -gst_vaapi_display_get_decode_caps (GstVaapiDisplay * display) +GArray * +gst_vaapi_display_get_decode_profiles (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, NULL); if (!ensure_profiles (display)) return NULL; - return get_profile_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders); + return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders); } /** @@ -1405,21 +1422,24 @@ gst_vaapi_display_has_decoder (GstVaapiDisplay * display, } /** - * gst_vaapi_display_get_encode_caps: + * gst_vaapi_display_get_encode_profiles: * @display: a #GstVaapiDisplay * - * Gets the supported profiles for decoding as #GstCaps capabilities. + * Gets the supported profiles for encoding. The caller owns an extra + * reference to the resulting array of #GstVaapiProfile elements, so + * it shall be released with g_array_unref() after usage. * - * Return value: a newly allocated #GstCaps object, possibly empty + * Return value: a newly allocated #GArray, or %NULL or error or if + * encoding is not supported at all */ -GstCaps * -gst_vaapi_display_get_encode_caps (GstVaapiDisplay * display) +GArray * +gst_vaapi_display_get_encode_profiles (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, NULL); if (!ensure_profiles (display)) return NULL; - return get_profile_caps (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders); + return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 75518a0369..e925a185b7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -144,15 +144,15 @@ gst_vaapi_display_get_pixel_aspect_ratio (GstVaapiDisplay * display, gboolean gst_vaapi_display_has_video_processing (GstVaapiDisplay * display); -GstCaps * -gst_vaapi_display_get_decode_caps (GstVaapiDisplay * display); +GArray * +gst_vaapi_display_get_decode_profiles (GstVaapiDisplay * display); gboolean gst_vaapi_display_has_decoder (GstVaapiDisplay * display, GstVaapiProfile profile, GstVaapiEntrypoint entrypoint); -GstCaps * -gst_vaapi_display_get_encode_caps (GstVaapiDisplay * display); +GArray * +gst_vaapi_display_get_encode_profiles (GstVaapiDisplay * display); gboolean gst_vaapi_display_has_encoder (GstVaapiDisplay * display, diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 8a6b31d212..f31ad78dc5 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -815,8 +815,9 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) static gboolean gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) { - GstCaps *decode_caps; - guint i, n_decode_caps; + GstCaps *caps, *allowed_caps; + GArray *profiles; + guint i; if (decode->allowed_caps) return TRUE; @@ -824,30 +825,32 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) if (!gst_vaapidecode_ensure_display(decode)) goto error_no_display; - decode_caps = gst_vaapi_display_get_decode_caps( + profiles = gst_vaapi_display_get_decode_profiles( GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); - if (!decode_caps) - goto error_no_decode_caps; - n_decode_caps = gst_caps_get_size(decode_caps); + if (!profiles) + goto error_no_profiles; - decode->allowed_caps = gst_caps_new_empty(); - if (!decode->allowed_caps) + allowed_caps = gst_caps_new_empty(); + if (!allowed_caps) goto error_no_memory; - for (i = 0; i < n_decode_caps; i++) { - GstStructure *structure; - structure = gst_caps_get_structure(decode_caps, i); - if (!structure) - continue; - structure = gst_structure_copy(structure); - if (!structure) - continue; - gst_structure_remove_field(structure, "profile"); - decode->allowed_caps = - gst_caps_merge_structure(decode->allowed_caps, structure); - } + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index(profiles, GstVaapiProfile, i); + const gchar *media_type_name; - gst_caps_unref(decode_caps); + media_type_name = gst_vaapi_profile_get_media_type_name(profile); + if (!media_type_name) + continue; + + caps = gst_caps_from_string(media_type_name); + if (!caps) + continue; + allowed_caps = gst_caps_merge(allowed_caps, caps); + } + decode->allowed_caps = allowed_caps; + + g_array_unref(profiles); return TRUE; /* ERRORS */ @@ -856,15 +859,15 @@ error_no_display: GST_ERROR("failed to retrieve VA display"); return FALSE; } -error_no_decode_caps: +error_no_profiles: { - GST_ERROR("failed to retrieve VA decode caps"); + GST_ERROR("failed to retrieve VA decode profiles"); return FALSE; } error_no_memory: { GST_ERROR("failed to allocate allowed-caps set"); - gst_caps_unref(decode_caps); + g_array_unref(profiles); return FALSE; } } diff --git a/tests/test-display.c b/tests/test-display.c index 163ab503ea..22f5859a47 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -63,33 +63,31 @@ print_value(const GValue *value, const gchar *name) } static void -print_profile_caps(GstCaps *caps, const gchar *name) +print_profiles(GArray *profiles, const gchar *name) { - guint i, n_caps = gst_caps_get_size(caps); - gint version; - const gchar *profile; - gboolean has_version; + GstVaapiCodec codec; + const gchar *codec_name, *profile_name; + guint i; - g_print("%u %s caps\n", n_caps, name); + g_print("%u %s caps\n", profiles->len, name); - for (i = 0; i < gst_caps_get_size(caps); i++) { - GstStructure * const structure = gst_caps_get_structure(caps, i); - if (!structure) - g_error("could not get caps structure %d", i); + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index(profiles, GstVaapiProfile, i); - has_version = ( - gst_structure_get_int(structure, "version", &version) || - gst_structure_get_int(structure, "mpegversion", &version) - ); + codec = gst_vaapi_profile_get_codec(profile); + if (!codec) + continue; - g_print(" %s", gst_structure_get_name(structure)); - if (has_version) - g_print("%d", version); + codec_name = gst_vaapi_codec_get_name(codec); + if (!codec_name) + continue; - profile = gst_structure_get_string(structure, "profile"); - if (!profile) - g_error("could not get structure profile"); - g_print(": %s profile\n", profile); + profile_name = gst_vaapi_profile_get_name(profile); + if (!profile_name) + continue; + + g_print(" %s: %s profile\n", codec_name, profile_name); } } @@ -232,22 +230,21 @@ end: static void dump_info(GstVaapiDisplay *display) { - GArray *formats; - GstCaps *caps; + GArray *profiles, *formats; - caps = gst_vaapi_display_get_decode_caps(display); - if (!caps) - g_error("could not get VA decode caps"); + profiles = gst_vaapi_display_get_decode_profiles(display); + if (!profiles) + g_error("could not get VA decode profiles"); - print_profile_caps(caps, "decoders"); - gst_caps_unref(caps); + print_profiles(profiles, "decoders"); + g_array_unref(profiles); - caps = gst_vaapi_display_get_encode_caps(display); - if (!caps) - g_error("could not get VA encode caps"); + profiles = gst_vaapi_display_get_encode_profiles(display); + if (!profiles) + g_error("could not get VA encode profiles"); - print_profile_caps(caps, "encoders"); - gst_caps_unref(caps); + print_profiles(profiles, "encoders"); + g_array_unref(profiles); formats = gst_vaapi_display_get_image_formats(display); if (!formats) From b80257389d4c7ce2f1ea77de70f283c2f0bbcc3b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 21 Dec 2013 06:22:30 +0100 Subject: [PATCH 1477/3781] plugins: re-indent common and video context creation utils. --- gst/vaapi/gstvaapipluginutil.c | 506 +++++++++++++++---------------- gst/vaapi/gstvaapipluginutil.h | 17 +- gst/vaapi/gstvaapivideocontext.c | 214 ++++++------- gst/vaapi/gstvaapivideocontext.h | 21 +- 4 files changed, 373 insertions(+), 385 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 55cbd7b86e..33b74dab70 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -41,364 +41,354 @@ /* Preferred first */ static const char *display_types[] = { - "gst-vaapi-display", - "vaapi-display", + "gst-vaapi-display", + "vaapi-display", #if USE_WAYLAND - "wl-display", - "wl-display-name", + "wl-display", + "wl-display-name", #endif #if USE_X11 - "x11-display", - "x11-display-name", + "x11-display", + "x11-display-name", #endif #if USE_DRM - "drm-device", - "drm-device-path", + "drm-device", + "drm-device-path", #endif - NULL + NULL }; -typedef struct { - const gchar *type_str; - GstVaapiDisplayType type; - GstVaapiDisplay * (*create_display)(const gchar *); +typedef struct +{ + const gchar *type_str; + GstVaapiDisplayType type; + GstVaapiDisplay *(*create_display) (const gchar *); } DisplayMap; static const DisplayMap g_display_map[] = { #if USE_WAYLAND - { "wayland", - GST_VAAPI_DISPLAY_TYPE_WAYLAND, - gst_vaapi_display_wayland_new }, + {"wayland", + GST_VAAPI_DISPLAY_TYPE_WAYLAND, + gst_vaapi_display_wayland_new}, #endif #if USE_GLX - { "glx", - GST_VAAPI_DISPLAY_TYPE_GLX, - gst_vaapi_display_glx_new }, + {"glx", + GST_VAAPI_DISPLAY_TYPE_GLX, + gst_vaapi_display_glx_new}, #endif #if USE_X11 - { "x11", - GST_VAAPI_DISPLAY_TYPE_X11, - gst_vaapi_display_x11_new }, + {"x11", + GST_VAAPI_DISPLAY_TYPE_X11, + gst_vaapi_display_x11_new}, #endif #if USE_DRM - { "drm", - GST_VAAPI_DISPLAY_TYPE_DRM, - gst_vaapi_display_drm_new }, + {"drm", + GST_VAAPI_DISPLAY_TYPE_DRM, + gst_vaapi_display_drm_new}, #endif - { NULL, } + {NULL,} }; static GstVaapiDisplay * -gst_vaapi_create_display(GstVaapiDisplayType display_type) +gst_vaapi_create_display (GstVaapiDisplayType display_type) { - GstVaapiDisplay *display = NULL; - const DisplayMap *m; + GstVaapiDisplay *display = NULL; + const DisplayMap *m; - for (m = g_display_map; m->type_str != NULL; m++) { - if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY && - display_type != m->type) - continue; + for (m = g_display_map; m->type_str != NULL; m++) { + if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY && display_type != m->type) + continue; - display = m->create_display(NULL); - if (display || display_type != GST_VAAPI_DISPLAY_TYPE_ANY) - break; - } - return display; + display = m->create_display (NULL); + if (display || display_type != GST_VAAPI_DISPLAY_TYPE_ANY) + break; + } + return display; } gboolean -gst_vaapi_ensure_display(gpointer element, GstVaapiDisplayType type) +gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type) { - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(element); - GstVaapiDisplay *display; - GstVideoContext *context; + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); + GstVaapiDisplay *display; + GstVideoContext *context; - g_return_val_if_fail(GST_IS_VIDEO_CONTEXT(element), FALSE); + g_return_val_if_fail (GST_IS_VIDEO_CONTEXT (element), FALSE); - context = GST_VIDEO_CONTEXT(element); - g_return_val_if_fail(context != NULL, FALSE); + context = GST_VIDEO_CONTEXT (element); + g_return_val_if_fail (context != NULL, FALSE); - gst_vaapi_video_context_prepare(context, display_types); + gst_vaapi_video_context_prepare (context, display_types); - /* Neighbour found and it updated the display */ - if (plugin->display && gst_vaapi_display_type_is_compatible( - plugin->display_type, type)) - return TRUE; - - /* If no neighboor, or application not interested, use system default */ - display = gst_vaapi_create_display(type); - if (!display) - return FALSE; - - gst_vaapi_video_context_propagate(context, display); - GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(plugin, display); - gst_vaapi_display_unref(display); + /* Neighbour found and it updated the display */ + if (plugin->display + && gst_vaapi_display_type_is_compatible (plugin->display_type, type)) return TRUE; + + /* If no neighboor, or application not interested, use system default */ + display = gst_vaapi_create_display (type); + if (!display) + return FALSE; + + gst_vaapi_video_context_propagate (context, display); + GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE (plugin, display); + gst_vaapi_display_unref (display); + return TRUE; } void -gst_vaapi_set_display( - const gchar *type, - const GValue *value, - GstVaapiDisplay **display -) +gst_vaapi_set_display (const gchar * type, + const GValue * value, GstVaapiDisplay ** display_ptr) { - GstVaapiDisplay *dpy = NULL; + GstVaapiDisplay *display = NULL; - if (!strcmp(type, "vaapi-display")) { - g_return_if_fail(G_VALUE_HOLDS_POINTER(value)); - dpy = gst_vaapi_display_new_with_display(g_value_get_pointer(value)); - } - else if (!strcmp(type, "gst-vaapi-display")) { - g_return_if_fail(G_VALUE_HOLDS_POINTER(value)); - dpy = gst_vaapi_display_ref(g_value_get_pointer(value)); - } + if (!strcmp (type, "vaapi-display")) { + g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); + display = gst_vaapi_display_new_with_display (g_value_get_pointer (value)); + } else if (!strcmp (type, "gst-vaapi-display")) { + g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); + display = gst_vaapi_display_ref (g_value_get_pointer (value)); + } #if USE_DRM - else if (!strcmp(type, "drm-device")) { - gint device; - g_return_if_fail(G_VALUE_HOLDS_INT(value)); - device = g_value_get_int(value); - dpy = gst_vaapi_display_drm_new_with_device(device); - } - else if (!strcmp(type, "drm-device-path")) { - const gchar *device_path; - g_return_if_fail(G_VALUE_HOLDS_STRING(value)); - device_path = g_value_get_string(value); - dpy = gst_vaapi_display_drm_new(device_path); - } + else if (!strcmp (type, "drm-device")) { + gint device; + g_return_if_fail (G_VALUE_HOLDS_INT (value)); + device = g_value_get_int (value); + display = gst_vaapi_display_drm_new_with_device (device); + } else if (!strcmp (type, "drm-device-path")) { + const gchar *device_path; + g_return_if_fail (G_VALUE_HOLDS_STRING (value)); + device_path = g_value_get_string (value); + display = gst_vaapi_display_drm_new (device_path); + } #endif #if USE_X11 - else if (!strcmp(type, "x11-display-name")) { - g_return_if_fail(G_VALUE_HOLDS_STRING(value)); + else if (!strcmp (type, "x11-display-name")) { + g_return_if_fail (G_VALUE_HOLDS_STRING (value)); #if USE_GLX - dpy = gst_vaapi_display_glx_new(g_value_get_string(value)); + display = gst_vaapi_display_glx_new (g_value_get_string (value)); #endif - if (!dpy) - dpy = gst_vaapi_display_x11_new(g_value_get_string(value)); - } - else if (!strcmp(type, "x11-display")) { - g_return_if_fail(G_VALUE_HOLDS_POINTER(value)); + if (!display) + display = gst_vaapi_display_x11_new (g_value_get_string (value)); + } else if (!strcmp (type, "x11-display")) { + g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); #if USE_GLX - dpy = gst_vaapi_display_glx_new_with_display(g_value_get_pointer(value)); + display = + gst_vaapi_display_glx_new_with_display (g_value_get_pointer (value)); #endif - if (!dpy) - dpy = gst_vaapi_display_x11_new_with_display(g_value_get_pointer(value)); - } + if (!display) + display = + gst_vaapi_display_x11_new_with_display (g_value_get_pointer (value)); + } #endif #if USE_WAYLAND - else if (!strcmp(type, "wl-display")) { - struct wl_display *wl_display; - g_return_if_fail(G_VALUE_HOLDS_POINTER(value)); - wl_display = g_value_get_pointer(value); - dpy = gst_vaapi_display_wayland_new_with_display(wl_display); - } - else if (!strcmp(type, "wl-display-name")) { - const gchar *display_name; - g_return_if_fail(G_VALUE_HOLDS_STRING(value)); - display_name = g_value_get_string(value); - dpy = gst_vaapi_display_wayland_new(display_name); - } + else if (!strcmp (type, "wl-display")) { + struct wl_display *wl_display; + g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); + wl_display = g_value_get_pointer (value); + display = gst_vaapi_display_wayland_new_with_display (wl_display); + } else if (!strcmp (type, "wl-display-name")) { + const gchar *display_name; + g_return_if_fail (G_VALUE_HOLDS_STRING (value)); + display_name = g_value_get_string (value); + display = gst_vaapi_display_wayland_new (display_name); + } #endif - if (dpy) { - gst_vaapi_display_replace(display, dpy); - gst_vaapi_display_unref(dpy); - } + if (display) { + gst_vaapi_display_replace (display_ptr, display); + gst_vaapi_display_unref (display); + } } gboolean -gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display) +gst_vaapi_reply_to_query (GstQuery * query, GstVaapiDisplay * display) { #if GST_CHECK_VERSION(1,1,0) - const gchar *type = NULL; - GstContext *context; + const gchar *type = NULL; + GstContext *context; - if (GST_QUERY_TYPE(query) != GST_QUERY_CONTEXT) - return FALSE; + if (GST_QUERY_TYPE (query) != GST_QUERY_CONTEXT) + return FALSE; - if (!display) - return FALSE; + if (!display) + return FALSE; - if (!gst_query_parse_context_type(query, &type)) - return FALSE; + if (!gst_query_parse_context_type (query, &type)) + return FALSE; - if (g_strcmp0(type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME)) - return FALSE; + if (g_strcmp0 (type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME)) + return FALSE; - context = gst_vaapi_video_context_new_with_display(display, FALSE); - gst_query_set_context(query, context); - gst_context_unref(context); + context = gst_vaapi_video_context_new_with_display (display, FALSE); + gst_query_set_context (query, context); + gst_context_unref (context); - return TRUE; + return TRUE; #else - GstVaapiDisplayType display_type; - const gchar **types; - const gchar *type; - gint i; - gboolean res = FALSE; + GstVaapiDisplayType display_type; + const gchar **types; + const gchar *type; + gint i; + gboolean res = FALSE; - if (GST_QUERY_TYPE(query) != GST_QUERY_CUSTOM) - return FALSE; + if (GST_QUERY_TYPE (query) != GST_QUERY_CUSTOM) + return FALSE; - if (!display) - return FALSE; + if (!display) + return FALSE; - types = gst_video_context_query_get_supported_types(query); + types = gst_video_context_query_get_supported_types (query); - if (!types) - return FALSE; + if (!types) + return FALSE; - display_type = gst_vaapi_display_get_display_type(display); - for (i = 0; types[i] && !res; i++) { - type = types[i]; + display_type = gst_vaapi_display_get_display_type (display); + for (i = 0; types[i] && !res; i++) { + type = types[i]; - res = TRUE; - if (!strcmp(type, "gst-vaapi-display")) { - gst_video_context_query_set_pointer(query, type, display); - } - else if (!strcmp(type, "vaapi-display")) { - VADisplay vadpy = gst_vaapi_display_get_display(display); - gst_video_context_query_set_pointer(query, type, vadpy); - } - else { - switch (display_type) { + res = TRUE; + if (!strcmp (type, "gst-vaapi-display")) { + gst_video_context_query_set_pointer (query, type, display); + } else if (!strcmp (type, "vaapi-display")) { + VADisplay vadpy = gst_vaapi_display_get_display (display); + gst_video_context_query_set_pointer (query, type, vadpy); + } else { + switch (display_type) { #if USE_DRM - case GST_VAAPI_DISPLAY_TYPE_DRM: { - GstVaapiDisplayDRM * const drm_dpy = - GST_VAAPI_DISPLAY_DRM(display); - if (!strcmp(type, "drm-device-path")) - gst_video_context_query_set_string(query, type, - gst_vaapi_display_drm_get_device_path(drm_dpy)); + case GST_VAAPI_DISPLAY_TYPE_DRM:{ + GstVaapiDisplayDRM *const drm_dpy = GST_VAAPI_DISPLAY_DRM (display); + if (!strcmp (type, "drm-device-path")) + gst_video_context_query_set_string (query, type, + gst_vaapi_display_drm_get_device_path (drm_dpy)); #if 0 - /* XXX: gst_video_context_query_set_int() does not exist yet */ - else if (!strcmp(type, "drm-device")) - gst_video_context_query_set_int(query, type, - gst_vaapi_display_drm_get_device(drm_dpy)); + /* XXX: gst_video_context_query_set_int() does not exist yet */ + else if (!strcmp (type, "drm-device")) + gst_video_context_query_set_int (query, type, + gst_vaapi_display_drm_get_device (drm_dpy)); #endif - else - res = FALSE; - break; - } + else + res = FALSE; + break; + } #endif #if USE_X11 #if USE_GLX - case GST_VAAPI_DISPLAY_TYPE_GLX: + case GST_VAAPI_DISPLAY_TYPE_GLX: #endif - case GST_VAAPI_DISPLAY_TYPE_X11: { - GstVaapiDisplayX11 * const xvadpy = - GST_VAAPI_DISPLAY_X11(display); - Display * const x11dpy = - gst_vaapi_display_x11_get_display(xvadpy); - if (!strcmp(type, "x11-display")) - gst_video_context_query_set_pointer(query, type, x11dpy); - else if (!strcmp(type, "x11-display-name")) - gst_video_context_query_set_string(query, type, - DisplayString(x11dpy)); - else - res = FALSE; - break; - } + case GST_VAAPI_DISPLAY_TYPE_X11:{ + GstVaapiDisplayX11 *const xvadpy = GST_VAAPI_DISPLAY_X11 (display); + Display *const x11dpy = gst_vaapi_display_x11_get_display (xvadpy); + if (!strcmp (type, "x11-display")) + gst_video_context_query_set_pointer (query, type, x11dpy); + else if (!strcmp (type, "x11-display-name")) + gst_video_context_query_set_string (query, type, + DisplayString (x11dpy)); + else + res = FALSE; + break; + } #endif #if USE_WAYLAND - case GST_VAAPI_DISPLAY_TYPE_WAYLAND: { - GstVaapiDisplayWayland * const wlvadpy = - GST_VAAPI_DISPLAY_WAYLAND(display); - struct wl_display * const wldpy = - gst_vaapi_display_wayland_get_display(wlvadpy); - if (!strcmp(type, "wl-display")) - gst_video_context_query_set_pointer(query, type, wldpy); - else - res = FALSE; - break; - } -#endif - default: - res = FALSE; - break; - } + case GST_VAAPI_DISPLAY_TYPE_WAYLAND:{ + GstVaapiDisplayWayland *const wlvadpy = + GST_VAAPI_DISPLAY_WAYLAND (display); + struct wl_display *const wldpy = + gst_vaapi_display_wayland_get_display (wlvadpy); + if (!strcmp (type, "wl-display")) + gst_video_context_query_set_pointer (query, type, wldpy); + else + res = FALSE; + break; } +#endif + default: + res = FALSE; + break; + } } - return res; + } + return res; #endif /* !GST_CHECK_VERSION(1,1,0) */ } gboolean -gst_vaapi_append_surface_caps(GstCaps *out_caps, GstCaps *in_caps) +gst_vaapi_append_surface_caps (GstCaps * out_caps, GstCaps * in_caps) { - GstStructure *structure; - const GValue *v_width, *v_height, *v_framerate, *v_par; - guint i, n_structures; + GstStructure *structure; + const GValue *v_width, *v_height, *v_framerate, *v_par; + guint i, n_structures; - structure = gst_caps_get_structure(in_caps, 0); - v_width = gst_structure_get_value(structure, "width"); - v_height = gst_structure_get_value(structure, "height"); - v_framerate = gst_structure_get_value(structure, "framerate"); - v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); - if (!v_width || !v_height) - return FALSE; + structure = gst_caps_get_structure (in_caps, 0); + v_width = gst_structure_get_value (structure, "width"); + v_height = gst_structure_get_value (structure, "height"); + v_framerate = gst_structure_get_value (structure, "framerate"); + v_par = gst_structure_get_value (structure, "pixel-aspect-ratio"); + if (!v_width || !v_height) + return FALSE; - n_structures = gst_caps_get_size(out_caps); - for (i = 0; i < n_structures; i++) { - structure = gst_caps_get_structure(out_caps, i); - gst_structure_set_value(structure, "width", v_width); - gst_structure_set_value(structure, "height", v_height); - if (v_framerate) - gst_structure_set_value(structure, "framerate", v_framerate); - if (v_par) - gst_structure_set_value(structure, "pixel-aspect-ratio", v_par); - } + n_structures = gst_caps_get_size (out_caps); + for (i = 0; i < n_structures; i++) { + structure = gst_caps_get_structure (out_caps, i); + gst_structure_set_value (structure, "width", v_width); + gst_structure_set_value (structure, "height", v_height); + if (v_framerate) + gst_structure_set_value (structure, "framerate", v_framerate); + if (v_par) + gst_structure_set_value (structure, "pixel-aspect-ratio", v_par); + } + return TRUE; +} + +gboolean +gst_vaapi_apply_composition (GstVaapiSurface * surface, GstBuffer * buffer) +{ +#if GST_CHECK_VERSION(1,0,0) + GstVideoOverlayCompositionMeta *const cmeta = + gst_buffer_get_video_overlay_composition_meta (buffer); + GstVideoOverlayComposition *composition; + + if (!cmeta) return TRUE; -} - -gboolean -gst_vaapi_apply_composition(GstVaapiSurface *surface, GstBuffer *buffer) -{ -#if GST_CHECK_VERSION(1,0,0) - GstVideoOverlayCompositionMeta * const cmeta = - gst_buffer_get_video_overlay_composition_meta(buffer); - GstVideoOverlayComposition *composition; - - if (!cmeta) - return TRUE; - composition = cmeta->overlay; + composition = cmeta->overlay; #else - GstVideoOverlayComposition * const composition = - gst_video_buffer_get_overlay_composition(buffer); + GstVideoOverlayComposition *const composition = + gst_video_buffer_get_overlay_composition (buffer); #endif - if (!composition) - return TRUE; - return gst_vaapi_surface_set_subpictures_from_composition(surface, - composition, TRUE); + if (!composition) + return TRUE; + return gst_vaapi_surface_set_subpictures_from_composition (surface, + composition, TRUE); } gboolean -gst_caps_set_interlaced(GstCaps *caps, GstVideoInfo *vip) +gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip) { #if GST_CHECK_VERSION(1,0,0) - GstVideoInterlaceMode mode; - const gchar *mode_str; + GstVideoInterlaceMode mode; + const gchar *mode_str; - mode = vip ? GST_VIDEO_INFO_INTERLACE_MODE(vip) : - GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; - switch (mode) { + mode = vip ? GST_VIDEO_INFO_INTERLACE_MODE (vip) : + GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; + switch (mode) { case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE: - mode_str = "progressive"; - break; + mode_str = "progressive"; + break; case GST_VIDEO_INTERLACE_MODE_INTERLEAVED: - mode_str = "interleaved"; - break; + mode_str = "interleaved"; + break; case GST_VIDEO_INTERLACE_MODE_MIXED: - mode_str = "mixed"; - break; + mode_str = "mixed"; + break; default: - GST_ERROR("unsupported `interlace-mode' %d", mode); - return FALSE; - } + GST_ERROR ("unsupported `interlace-mode' %d", mode); + return FALSE; + } - gst_caps_set_simple(caps, "interlace-mode", G_TYPE_STRING, mode_str, NULL); + gst_caps_set_simple (caps, "interlace-mode", G_TYPE_STRING, mode_str, NULL); #else - gst_caps_set_simple(caps, "interlaced", G_TYPE_BOOLEAN, - vip ? GST_VIDEO_INFO_IS_INTERLACED(vip) : FALSE, NULL); + gst_caps_set_simple (caps, "interlaced", G_TYPE_BOOLEAN, + vip ? GST_VIDEO_INFO_IS_INTERLACED (vip) : FALSE, NULL); #endif - return TRUE; + return TRUE; } diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 8336efb975..31db3e414a 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -30,27 +30,24 @@ G_GNUC_INTERNAL gboolean -gst_vaapi_ensure_display(gpointer element, GstVaapiDisplayType type); +gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type); G_GNUC_INTERNAL void -gst_vaapi_set_display( - const gchar *type, - const GValue *value, - GstVaapiDisplay **display -); +gst_vaapi_set_display (const gchar * type, + const GValue * value, GstVaapiDisplay ** display_ptr); G_GNUC_INTERNAL gboolean -gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display); +gst_vaapi_reply_to_query (GstQuery * query, GstVaapiDisplay * display); G_GNUC_INTERNAL gboolean -gst_vaapi_append_surface_caps (GstCaps *out_caps, GstCaps *in_caps); +gst_vaapi_append_surface_caps (GstCaps * out_caps, GstCaps * in_caps); G_GNUC_INTERNAL gboolean -gst_vaapi_apply_composition(GstVaapiSurface *surface, GstBuffer *buffer); +gst_vaapi_apply_composition (GstVaapiSurface * surface, GstBuffer * buffer); #ifndef G_PRIMITIVE_SWAP #define G_PRIMITIVE_SWAP(type, a, b) do { \ @@ -73,6 +70,6 @@ gst_vaapi_apply_composition(GstVaapiSurface *surface, GstBuffer *buffer); G_GNUC_INTERNAL gboolean -gst_caps_set_interlaced(GstCaps *caps, GstVideoInfo *vip); +gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip); #endif /* GST_VAAPI_PLUGIN_UTIL_H */ diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 551b79d89e..fe475a9e0a 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -28,154 +28,154 @@ #if GST_CHECK_VERSION(1,1,0) -GST_DEBUG_CATEGORY_STATIC(GST_CAT_CONTEXT); +GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); #define GST_VAAPI_TYPE_DISPLAY \ gst_vaapi_display_get_type() GType -gst_vaapi_display_get_type(void) G_GNUC_CONST; +gst_vaapi_display_get_type (void) + G_GNUC_CONST; -G_DEFINE_BOXED_TYPE(GstVaapiDisplay, gst_vaapi_display, - (GBoxedCopyFunc)gst_vaapi_display_ref, - (GBoxedFreeFunc)gst_vaapi_display_unref) +G_DEFINE_BOXED_TYPE (GstVaapiDisplay, gst_vaapi_display, + (GBoxedCopyFunc) gst_vaapi_display_ref, + (GBoxedFreeFunc) gst_vaapi_display_unref) -GstContext * -gst_vaapi_video_context_new_with_display(GstVaapiDisplay *display, - gboolean persistent) + GstContext *gst_vaapi_video_context_new_with_display (GstVaapiDisplay * + display, gboolean persistent) { - GstContext *context; - GstStructure *structure; + GstContext *context; + GstStructure *structure; - context = gst_context_new(GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, persistent); - structure = gst_context_writable_structure(context); - gst_structure_set(structure, "display", GST_VAAPI_TYPE_DISPLAY, - display, NULL); - return context; + context = gst_context_new (GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, persistent); + structure = gst_context_writable_structure (context); + gst_structure_set (structure, "display", GST_VAAPI_TYPE_DISPLAY, + display, NULL); + return context; } gboolean -gst_vaapi_video_context_get_display(GstContext *context, - GstVaapiDisplay **display_ptr) +gst_vaapi_video_context_get_display (GstContext * context, + GstVaapiDisplay ** display_ptr) { - const GstStructure *structure; + const GstStructure *structure; - g_return_val_if_fail(GST_IS_CONTEXT(context), FALSE); - g_return_val_if_fail(g_strcmp0(gst_context_get_context_type(context), - GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) == 0, FALSE); + g_return_val_if_fail (GST_IS_CONTEXT (context), FALSE); + g_return_val_if_fail (g_strcmp0 (gst_context_get_context_type (context), + GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) == 0, FALSE); - structure = gst_context_get_structure(context); - return gst_structure_get(structure, "display", GST_VAAPI_TYPE_DISPLAY, - display_ptr, NULL); + structure = gst_context_get_structure (context); + return gst_structure_get (structure, "display", GST_VAAPI_TYPE_DISPLAY, + display_ptr, NULL); } static gboolean -context_pad_query(const GValue *item, GValue *value, gpointer user_data) +context_pad_query (const GValue * item, GValue * value, gpointer user_data) { - GstPad * const pad = g_value_get_object(item); - GstQuery * const query = user_data; + GstPad *const pad = g_value_get_object (item); + GstQuery *const query = user_data; - if (gst_pad_peer_query(pad, query)) { - g_value_set_boolean(value, TRUE); - return FALSE; - } + if (gst_pad_peer_query (pad, query)) { + g_value_set_boolean (value, TRUE); + return FALSE; + } - GST_CAT_INFO_OBJECT(GST_CAT_CONTEXT, pad, "context pad peer query failed"); + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, pad, "context pad peer query failed"); + return TRUE; +} + +static gboolean +run_context_query (GstElement * element, GstQuery * query) +{ + GstIteratorFoldFunction const func = context_pad_query; + GstIterator *it; + GValue res = { 0 }; + + g_value_init (&res, G_TYPE_BOOLEAN); + g_value_set_boolean (&res, FALSE); + + /* Ask downstream neighbour */ + it = gst_element_iterate_src_pads (element); + while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC) + gst_iterator_resync (it); + gst_iterator_free (it); + + if (g_value_get_boolean (&res)) return TRUE; -} -static gboolean -run_context_query(GstElement *element, GstQuery *query) -{ - GstIteratorFoldFunction const func = context_pad_query; - GstIterator *it; - GValue res = { 0 }; + /* If none, ask upstream neighbour (auto-plugged case) */ + it = gst_element_iterate_sink_pads (element); + while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC) + gst_iterator_resync (it); + gst_iterator_free (it); - g_value_init(&res, G_TYPE_BOOLEAN); - g_value_set_boolean(&res, FALSE); - - /* Ask downstream neighbour */ - it = gst_element_iterate_src_pads(element); - while (gst_iterator_fold(it, func, &res, query) == GST_ITERATOR_RESYNC) - gst_iterator_resync(it); - gst_iterator_free(it); - - if (g_value_get_boolean(&res)) - return TRUE; - - /* If none, ask upstream neighbour (auto-plugged case) */ - it = gst_element_iterate_sink_pads(element); - while (gst_iterator_fold(it, func, &res, query) == GST_ITERATOR_RESYNC) - gst_iterator_resync(it); - gst_iterator_free(it); - - return g_value_get_boolean(&res); + return g_value_get_boolean (&res); } void -gst_vaapi_video_context_prepare(GstElement *element, const gchar **types) +gst_vaapi_video_context_prepare (GstElement * element, const gchar ** types) { - GstContext *context; - GstQuery *query; - GstMessage *msg; + GstContext *context; + GstQuery *query; + GstMessage *msg; - if (!GST_CAT_CONTEXT) - GST_DEBUG_CATEGORY_GET(GST_CAT_CONTEXT, "GST_CONTEXT"); + if (!GST_CAT_CONTEXT) + GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"); - /* 1) Check if the element already has a context of the specific - * type, i.e. it was previously set via - * gst_element_set_context(). */ - /* This was already done by the caller of this function: - * gst_vaapi_ensure_display() */ + /* 1) Check if the element already has a context of the specific + * type, i.e. it was previously set via + * gst_element_set_context(). */ + /* This was already done by the caller of this function: + * gst_vaapi_ensure_display() */ - /* 2) Query downstream with GST_QUERY_CONTEXT for the context and - check if downstream already has a context of the specific - type */ - /* 3) Query upstream with GST_QUERY_CONTEXT for the context and - check if upstream already has a context of the specific - type */ - context = NULL; - query = gst_query_new_context(GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); - if (run_context_query(element, query)) { - gst_query_parse_context(query, &context); - GST_CAT_INFO_OBJECT(GST_CAT_CONTEXT, element, - "found context (%p) in query", context); - gst_element_set_context(element, context); - } - else { - /* 4) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with - the required context types and afterwards check if an - usable context was set now as in 1). The message could - be handled by the parent bins of the element and the - application. */ - GST_CAT_INFO_OBJECT(GST_CAT_CONTEXT, element, - "posting `need-context' message"); - msg = gst_message_new_need_context(GST_OBJECT_CAST(element), - GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); - gst_element_post_message(element, msg); + /* 2) Query downstream with GST_QUERY_CONTEXT for the context and + check if downstream already has a context of the specific + type */ + /* 3) Query upstream with GST_QUERY_CONTEXT for the context and + check if upstream already has a context of the specific + type */ + context = NULL; + query = gst_query_new_context (GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); + if (run_context_query (element, query)) { + gst_query_parse_context (query, &context); + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, + "found context (%p) in query", context); + gst_element_set_context (element, context); + } else { + /* 4) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with + the required context types and afterwards check if an + usable context was set now as in 1). The message could + be handled by the parent bins of the element and the + application. */ + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, + "posting `need-context' message"); + msg = gst_message_new_need_context (GST_OBJECT_CAST (element), + GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); + gst_element_post_message (element, msg); - /* The check of an usable context is done by the caller: - gst_vaapi_ensure_display() */ - } + /* The check of an usable context is done by the caller: + gst_vaapi_ensure_display() */ + } - gst_query_unref(query); + gst_query_unref (query); } /* 5) Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT message on the bus. */ void -gst_vaapi_video_context_propagate(GstElement *element, GstVaapiDisplay *display) +gst_vaapi_video_context_propagate (GstElement * element, + GstVaapiDisplay * display) { - GstContext *context; - GstMessage *msg; + GstContext *context; + GstMessage *msg; - context = gst_vaapi_video_context_new_with_display(display, FALSE); + context = gst_vaapi_video_context_new_with_display (display, FALSE); - GST_CAT_INFO_OBJECT(GST_CAT_CONTEXT, element, - "posting `have-context' (%p) message with display (%p)", - context, display); - msg = gst_message_new_have_context(GST_OBJECT_CAST(element), context); - gst_element_post_message(GST_ELEMENT_CAST(element), msg); + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, + "posting `have-context' (%p) message with display (%p)", + context, display); + msg = gst_message_new_have_context (GST_OBJECT_CAST (element), context); + gst_element_post_message (GST_ELEMENT_CAST (element), msg); } #endif diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index 096445564f..fd5cf6b5ef 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -41,35 +41,36 @@ G_GNUC_INTERNAL GstContext * -gst_vaapi_video_context_new_with_display(GstVaapiDisplay *display, +gst_vaapi_video_context_new_with_display (GstVaapiDisplay * display, gboolean persistent); G_GNUC_INTERNAL gboolean -gst_vaapi_video_context_get_display(GstContext *context, - GstVaapiDisplay **display_ptr); +gst_vaapi_video_context_get_display (GstContext * context, + GstVaapiDisplay ** display_ptr); G_GNUC_INTERNAL void -gst_vaapi_video_context_prepare(GstElement *element, const gchar **types); +gst_vaapi_video_context_prepare (GstElement * element, const gchar ** types); G_GNUC_INTERNAL void -gst_vaapi_video_context_propagate(GstElement *element, - GstVaapiDisplay *display); +gst_vaapi_video_context_propagate (GstElement * element, + GstVaapiDisplay * display); #else #include static inline void -gst_vaapi_video_context_prepare(GstVideoContext *context, const gchar **types) +gst_vaapi_video_context_prepare (GstVideoContext * context, + const gchar ** types) { - gst_video_context_prepare(context, types); + gst_video_context_prepare (context, types); } static inline void -gst_vaapi_video_context_propagate(GstVideoContext *context, - GstVaapiDisplay *display) +gst_vaapi_video_context_propagate (GstVideoContext * context, + GstVaapiDisplay * display) { } From 528b5adc5a488cf3175b5334062bf18bb91a77e1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 21 Dec 2013 06:41:34 +0100 Subject: [PATCH 1478/3781] plugins: factor out construction of GValue from GstVideoFormat. Add new helper functions to build GValues from GstVideoFormat: - gst_vaapi_value_set_format(): build a GValue from the supplied video format - gst_vaapi_value_set_format_list(): build a GValue list from the supplied array of video formats --- gst/vaapi/gstvaapipluginutil.c | 43 +++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 9 ++++++ gst/vaapi/gstvaapipostproc.c | 54 ++++------------------------------ 3 files changed, 58 insertions(+), 48 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 33b74dab70..c4652b839b 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -361,6 +361,49 @@ gst_vaapi_apply_composition (GstVaapiSurface * surface, GstBuffer * buffer) composition, TRUE); } +gboolean +gst_vaapi_value_set_format (GValue * value, GstVideoFormat format) +{ +#if GST_CHECK_VERSION(1,0,0) + const gchar *str; + + str = gst_video_format_to_string (format); + if (!str) + return FALSE; + + g_value_init (value, G_TYPE_STRING); + g_value_set_string (value, str); +#else + guint32 fourcc; + + fourcc = gst_video_format_to_fourcc (format); + if (!fourcc) + return FALSE; + + g_value_init (value, GST_TYPE_FOURCC); + gst_value_set_fourcc (value, fourcc); +#endif + return TRUE; +} + +gboolean +gst_vaapi_value_set_format_list (GValue * value, GArray * formats) +{ + GValue v_format = G_VALUE_INIT; + guint i; + + g_value_init (value, GST_TYPE_LIST); + for (i = 0; i < formats->len; i++) { + GstVideoFormat const format = g_array_index (formats, GstVideoFormat, i); + + if (!gst_vaapi_value_set_format (&v_format, format)) + continue; + gst_value_list_append_value (value, &v_format); + g_value_unset (&v_format); + } + return TRUE; +} + gboolean gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip) { diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 31db3e414a..3d04588c5c 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -55,6 +55,15 @@ gst_vaapi_apply_composition (GstVaapiSurface * surface, GstBuffer * buffer); } while (0) #endif +/* Helpers for GValue construction for video formats */ +G_GNUC_INTERNAL +gboolean +gst_vaapi_value_set_format (GValue * value, GstVideoFormat format); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_value_set_format_list (GValue * value, GArray * formats); + /* Helpers to handle interlaced contents */ #if GST_CHECK_VERSION(1,0,0) # define GST_CAPS_INTERLACED_MODES \ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 58fff7a172..d84ca3c123 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -826,57 +826,11 @@ ensure_allowed_sinkpad_caps(GstVaapiPostproc *postproc) return TRUE; } -/* Build list of supported formats */ -static gboolean -build_format_list_value(GArray *formats, GValue *out_value) -{ - GValue v_format = { 0, }; - guint i; -#if GST_CHECK_VERSION(1,0,0) - const gchar *str; - - g_value_init(out_value, GST_TYPE_LIST); - - g_value_init(&v_format, G_TYPE_STRING); - g_value_set_string(&v_format, "encoded"); - gst_value_list_append_value(out_value, &v_format); - - for (i = 0; i < formats->len; i++) { - GstVideoFormat const format = - g_array_index(formats, GstVideoFormat, i); - - str = gst_vaapi_video_format_to_string(format); - if (!str) - continue; - g_value_set_string(&v_format, str); - gst_value_list_append_value(out_value, &v_format); - } -#else - guint32 fourcc; - - g_value_init(out_value, GST_TYPE_LIST); - g_value_init(&v_format, GST_TYPE_FOURCC); - for (i = 0; i < formats->len; i++) { - GstVideoFormat const format = - g_array_index(formats, GstVideoFormat, i); - - fourcc = gst_video_format_to_fourcc(format); - if (!fourcc) - continue; - gst_value_set_fourcc(&v_format, fourcc); - gst_value_list_append_value(out_value, &v_format); - } -#endif - - g_value_unset(&v_format); - return TRUE; -} - /* Fixup output caps so that to reflect the supported set of pixel formats */ static GstCaps * expand_allowed_srcpad_caps(GstVaapiPostproc *postproc, GstCaps *caps) { - GValue value = { 0, }; + GValue value = G_VALUE_INIT, v_format = G_VALUE_INIT; guint i, num_structures; gboolean had_filter; @@ -887,8 +841,12 @@ expand_allowed_srcpad_caps(GstVaapiPostproc *postproc, GstCaps *caps) goto cleanup; /* Reset "format" field for each structure */ - if (!build_format_list_value(postproc->filter_formats, &value)) + if (!gst_vaapi_value_set_format_list(&value, postproc->filter_formats)) goto cleanup; + if (gst_vaapi_value_set_format(&v_format, GST_VIDEO_FORMAT_ENCODED)) { + gst_value_list_prepend_value(&value, &v_format); + g_value_unset(&v_format); + } num_structures = gst_caps_get_size(caps); for (i = 0; i < num_structures; i++) { From 113bd3a5f296086b618748950b36d51ff11efc98 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 21 Dec 2013 10:41:22 +0100 Subject: [PATCH 1479/3781] plugins: factor out construction of template caps. Add new helper functions to build video template caps. - gst_vaapi_video_format_new_template_caps(): create GstCaps with size, frame rate and PAR to full range - gst_vaapi_video_format_new_template_caps_from_list(): try to create a "simplified" list from the supplied formats --- gst/vaapi/gstvaapidownload.c | 29 ++++++-------- gst/vaapi/gstvaapipluginutil.c | 71 ++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 9 +++++ gst/vaapi/gstvaapiuploader.c | 38 +++++++++++------- 4 files changed, 115 insertions(+), 32 deletions(-) diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 904570bfc5..9a9a3ca5e2 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -389,10 +389,9 @@ gst_vaapidownload_transform_caps( { GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); GstPad *srcpad; - GstCaps *allowed_caps, *inter_caps, *out_caps = NULL; + GstCaps *allowed_caps, *tmp_caps, *out_caps = NULL; GstStructure *structure; GArray *formats; - guint i; g_return_val_if_fail(GST_IS_CAPS(caps), NULL); @@ -411,35 +410,31 @@ gst_vaapidownload_transform_caps( if (download->allowed_caps) allowed_caps = gst_caps_ref(download->allowed_caps); else { - allowed_caps = gst_caps_new_empty(); - if (!allowed_caps) - return NULL; - formats = gst_vaapi_display_get_image_formats( GST_VAAPI_PLUGIN_BASE_DISPLAY(download)); - if (formats) { - for (i = 0; i < formats->len; i++) { - const GstVideoFormat format = - g_array_index(formats, GstVideoFormat, i); - gst_caps_merge(allowed_caps, - gst_vaapi_video_format_to_caps(format)); - } + if (G_UNLIKELY(!formats)) + allowed_caps = gst_caps_new_empty(); + else { + allowed_caps = + gst_vaapi_video_format_new_template_caps_from_list(formats); g_array_unref(formats); } + if (!allowed_caps) + return NULL; } - inter_caps = gst_caps_intersect(out_caps, allowed_caps); + tmp_caps = gst_caps_intersect(out_caps, allowed_caps); gst_caps_unref(allowed_caps); gst_caps_unref(out_caps); - out_caps = inter_caps; + out_caps = tmp_caps; /* Intersect with allowed caps from the peer, if any */ srcpad = gst_element_get_static_pad(GST_ELEMENT(download), "src"); allowed_caps = gst_pad_peer_get_caps(srcpad); if (allowed_caps) { - inter_caps = gst_caps_intersect(out_caps, allowed_caps); + tmp_caps = gst_caps_intersect(out_caps, allowed_caps); gst_caps_unref(allowed_caps); gst_caps_unref(out_caps); - out_caps = inter_caps; + out_caps = tmp_caps; } } else { diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index c4652b839b..29711687c1 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -404,6 +404,77 @@ gst_vaapi_value_set_format_list (GValue * value, GArray * formats) return TRUE; } +void +set_video_template_caps (GstCaps * caps) +{ + GstStructure *const structure = gst_caps_get_structure (caps, 0); + + gst_structure_set (structure, + "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, + "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); +} + +GstCaps * +gst_vaapi_video_format_new_template_caps (GstVideoFormat format) +{ +#if GST_CHECK_VERSION(1,0,0) + GstCaps *caps; + + g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL); + + caps = gst_caps_new_empty_simple ("video/x-raw"); + if (!caps) + return NULL; + + gst_caps_set_simple (caps, + "format", G_TYPE_STRING, gst_video_format_to_string (format), NULL); + set_video_template_caps (caps); + return caps; +#else + return gst_video_format_new_template_caps (format); +#endif +} + +GstCaps * +gst_vaapi_video_format_new_template_caps_from_list (GArray * formats) +{ +#if GST_CHECK_VERSION(1,0,0) + GValue v_formats = G_VALUE_INIT; + GstCaps *caps; + + caps = gst_caps_new_empty_simple ("video/x-raw"); + if (!caps) + return NULL; + + if (!gst_vaapi_value_set_format_list (&v_formats, formats)) { + gst_caps_unref (caps); + return NULL; + } + + gst_caps_set_value (caps, "format", &v_formats); + set_video_template_caps (caps); +#else + GstCaps *caps, *tmp_caps; + guint i; + + g_return_val_if_fail (formats != NULL, NULL); + + caps = gst_caps_new_empty (); + if (!caps) + return NULL; + + for (i = 0; i < formats->len; i++) { + const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); + tmp_caps = gst_vaapi_video_format_new_template_caps (format); + if (tmp_caps) + gst_caps_append (caps, tmp_caps); + } +#endif + return caps; +} + gboolean gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip) { diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 3d04588c5c..0c6e55703c 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -64,6 +64,15 @@ G_GNUC_INTERNAL gboolean gst_vaapi_value_set_format_list (GValue * value, GArray * formats); +/* Helpers to build video caps */ +G_GNUC_INTERNAL +GstCaps * +gst_vaapi_video_format_new_template_caps (GstVideoFormat format); + +G_GNUC_INTERNAL +GstCaps * +gst_vaapi_video_format_new_template_caps_from_list (GArray * formats); + /* Helpers to handle interlaced contents */ #if GST_CHECK_VERSION(1,0,0) # define GST_CAPS_INTERLACED_MODES \ diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index b28cfe8038..6d99c855fd 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -30,6 +30,7 @@ #include #include "gstvaapiuploader.h" +#include "gstvaapipluginutil.h" #include "gstvaapivideobuffer.h" #define GST_HELPER_NAME "vaapiupload" @@ -112,7 +113,7 @@ ensure_allowed_caps(GstVaapiUploader *uploader) { GstVaapiUploaderPrivate * const priv = uploader->priv; GstVaapiSurface *surface = NULL; - GArray *image_formats = NULL; + GArray *formats = NULL, *out_formats = NULL; GstCaps *out_caps; guint i; gboolean success = FALSE; @@ -122,22 +123,23 @@ ensure_allowed_caps(GstVaapiUploader *uploader) if (priv->allowed_caps) return TRUE; - out_caps = gst_caps_new_empty(); - if (!out_caps) - return FALSE; + formats = gst_vaapi_display_get_image_formats(priv->display); + if (!formats) + goto cleanup; - image_formats = gst_vaapi_display_get_image_formats(priv->display); - if (!image_formats) - goto end; + out_formats = g_array_sized_new(FALSE, FALSE, sizeof(GstVideoFormat), + formats->len); + if (!out_formats) + goto cleanup; surface = gst_vaapi_surface_new(priv->display, GST_VAAPI_CHROMA_TYPE_YUV420, WIDTH, HEIGHT); if (!surface) - goto end; + goto cleanup; - for (i = 0; i < image_formats->len; i++) { + for (i = 0; i < formats->len; i++) { const GstVideoFormat format = - g_array_index(image_formats, GstVideoFormat, i); + g_array_index(formats, GstVideoFormat, i); GstVaapiImage *image; if (format == GST_VIDEO_FORMAT_UNKNOWN) @@ -146,17 +148,23 @@ ensure_allowed_caps(GstVaapiUploader *uploader) if (!image) continue; if (ensure_image(image) && gst_vaapi_surface_put_image(surface, image)) - gst_caps_append(out_caps, gst_vaapi_video_format_to_caps(format)); + g_array_append_val(out_formats, format); gst_vaapi_object_unref(image); } + out_caps = gst_vaapi_video_format_new_template_caps_from_list(out_formats); + if (!out_caps) + goto cleanup; + gst_caps_replace(&priv->allowed_caps, out_caps); + gst_caps_unref(out_caps); success = TRUE; -end: - gst_caps_unref(out_caps); - if (image_formats) - g_array_unref(image_formats); +cleanup: + if (out_formats) + g_array_unref(out_formats); + if (formats) + g_array_unref(formats); if (surface) gst_vaapi_object_unref(surface); return success; From 7f88fdcc03294ddf2785f5dac0c27c2f66f789f9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 21 Dec 2013 08:27:30 +0100 Subject: [PATCH 1480/3781] download: use GstVideoInfo facilities to build output caps. Use standard GstVideoInfo related functions to build the output caps, thus directly preserving additional fields as needed, instead of manually copying them over through gst_vaapi_append_surface_caps(). Also ensure that the input caps are fixated first. --- gst/vaapi/gstvaapidownload.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c index 9a9a3ca5e2..045a6de343 100644 --- a/gst/vaapi/gstvaapidownload.c +++ b/gst/vaapi/gstvaapidownload.c @@ -282,6 +282,7 @@ gst_vaapidownload_update_src_caps(GstVaapiDownload *download, GstBuffer *buffer) GstVaapiVideoMeta *meta; GstVaapiSurface *surface; GstVideoFormat format; + GstVideoInfo vi; GstPad *srcpad; GstCaps *in_caps, *out_caps; @@ -297,20 +298,22 @@ gst_vaapidownload_update_src_caps(GstVaapiDownload *download, GstBuffer *buffer) return TRUE; in_caps = GST_BUFFER_CAPS(buffer); - if (!in_caps) { + if (!in_caps || !gst_caps_is_fixed(in_caps)) { GST_WARNING("failed to retrieve caps from buffer"); return FALSE; } - out_caps = gst_vaapi_video_format_to_caps(download->image_format); - if (!out_caps) { - GST_WARNING("failed to create caps from format %s", - gst_video_format_to_string(download->image_format)); + if (!gst_video_info_from_caps(&vi, in_caps)) { + GST_WARNING("failed to parse caps %" GST_PTR_FORMAT, in_caps); return FALSE; } - if (!gst_vaapi_append_surface_caps(out_caps, in_caps)) { - gst_caps_unref(out_caps); + gst_video_info_set_format(&vi, download->image_format, + GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); + out_caps = gst_video_info_to_caps(&vi); + if (!out_caps) { + GST_WARNING("failed to create caps from format %s", + gst_video_format_to_string(download->image_format)); return FALSE; } From 52b6fc57d44cc0409c6cd856bb4f5b15009c8242 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 21 Dec 2013 07:29:50 +0100 Subject: [PATCH 1481/3781] utils: re-indent GstVideoFormat related helpers. --- gst-libs/gst/vaapi/video-format.c | 341 +++++++++++++++--------------- gst-libs/gst/vaapi/video-format.h | 26 +-- 2 files changed, 183 insertions(+), 184 deletions(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 1d82c57851..4929fe86fd 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -33,13 +33,13 @@ #include "gstvaapisurface.h" #include "video-format.h" -typedef struct _GstVideoFormatMap GstVideoFormatMap; -struct _GstVideoFormatMap { - GstVideoFormat format; - GstVaapiChromaType chroma_type; - const char *caps_str; - VAImageFormat va_format; -}; +typedef struct +{ + GstVideoFormat format; + GstVaapiChromaType chroma_type; + const gchar *caps_str; + VAImageFormat va_format; +} GstVideoFormatMap; #if GST_CHECK_VERSION(1,0,0) # define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \ @@ -54,91 +54,91 @@ struct _GstVideoFormatMap { #endif #define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP, SUB) \ - { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ - G_PASTE(GST_VAAPI_CHROMA_TYPE_YUV,SUB), \ - GST_VIDEO_CAPS_MAKE_YUV(FORMAT), \ - { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } + { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ + G_PASTE(GST_VAAPI_CHROMA_TYPE_YUV,SUB), \ + GST_VIDEO_CAPS_MAKE_YUV(FORMAT), \ + { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } #define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \ - { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ - G_PASTE(GST_VAAPI_CHROMA_TYPE_RGB,BPP), \ - GST_VIDEO_CAPS_MAKE_RGB(FORMAT), \ - { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } + { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ + G_PASTE(GST_VAAPI_CHROMA_TYPE_RGB,BPP), \ + GST_VIDEO_CAPS_MAKE_RGB(FORMAT), \ + { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } /* Image formats, listed in HW order preference */ static const GstVideoFormatMap gst_vaapi_video_formats[] = { - DEF_YUV(NV12, ('N','V','1','2'), LSB, 12, 420), - DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12, 420), - DEF_YUV(I420, ('I','4','2','0'), LSB, 12, 420), - DEF_YUV(YUY2, ('Y','U','Y','2'), LSB, 16, 422), - DEF_YUV(UYVY, ('U','Y','V','Y'), LSB, 16, 422), - DEF_YUV(AYUV, ('A','Y','U','V'), LSB, 32, 444), + DEF_YUV (NV12, ('N', 'V', '1', '2'), LSB, 12, 420), + DEF_YUV (YV12, ('Y', 'V', '1', '2'), LSB, 12, 420), + DEF_YUV (I420, ('I', '4', '2', '0'), LSB, 12, 420), + DEF_YUV (YUY2, ('Y', 'U', 'Y', '2'), LSB, 16, 422), + DEF_YUV (UYVY, ('U', 'Y', 'V', 'Y'), LSB, 16, 422), + DEF_YUV (AYUV, ('A', 'Y', 'U', 'V'), LSB, 32, 444), #if G_BYTE_ORDER == G_BIG_ENDIAN - DEF_RGB(ARGB, ('A','R','G','B'), MSB, 32, - 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), - DEF_RGB(ABGR, ('A','B','G','R'), MSB, 32, - 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), - DEF_RGB(xRGB, ('X','R','G','B'), MSB, 32, - 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), - DEF_RGB(xBGR, ('X','B','G','R'), MSB, 32, - 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), + DEF_RGB (ARGB, ('A', 'R', 'G', 'B'), MSB, 32, + 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), + DEF_RGB (ABGR, ('A', 'B', 'G', 'R'), MSB, 32, + 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), + DEF_RGB (xRGB, ('X', 'R', 'G', 'B'), MSB, 32, + 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), + DEF_RGB (xBGR, ('X', 'B', 'G', 'R'), MSB, 32, + 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), #elif G_BYTE_ORDER == G_LITTLE_ENDIAN - DEF_RGB(BGRA, ('B','G','R','A'), LSB, 32, - 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), - DEF_RGB(RGBA, ('R','G','B','A'), LSB, 32, - 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), - DEF_RGB(BGRx, ('B','G','R','X'), LSB, 32, - 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), - DEF_RGB(RGBx, ('R','G','B','X'), LSB, 32, - 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), + DEF_RGB (BGRA, ('B', 'G', 'R', 'A'), LSB, 32, + 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), + DEF_RGB (RGBA, ('R', 'G', 'B', 'A'), LSB, 32, + 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), + DEF_RGB (BGRx, ('B', 'G', 'R', 'X'), LSB, 32, + 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), + DEF_RGB (RGBx, ('R', 'G', 'B', 'X'), LSB, 32, + 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), #endif - DEF_YUV(GRAY8, ('Y','8','0','0'), LSB, 8, 400), - { 0, } + DEF_YUV (GRAY8, ('Y', '8', '0', '0'), LSB, 8, 400), + {0,} }; #undef DEF_RGB #undef DEF_YUV static inline gboolean -va_format_is_rgb(const VAImageFormat *va_format) +va_format_is_rgb (const VAImageFormat * va_format) { - return va_format->depth != 0; + return va_format->depth != 0; } static inline gboolean -va_format_is_yuv(const VAImageFormat *va_format) +va_format_is_yuv (const VAImageFormat * va_format) { - return va_format->depth == 0; + return va_format->depth == 0; } static inline gboolean -va_format_is_same_rgb(const VAImageFormat *fmt1, const VAImageFormat *fmt2) +va_format_is_same_rgb (const VAImageFormat * fmt1, const VAImageFormat * fmt2) { - return (fmt1->byte_order == fmt2->byte_order && - fmt1->red_mask == fmt2->red_mask && - fmt1->green_mask == fmt2->green_mask && - fmt1->blue_mask == fmt2->blue_mask && - fmt1->alpha_mask == fmt2->alpha_mask); + return (fmt1->byte_order == fmt2->byte_order && + fmt1->red_mask == fmt2->red_mask && + fmt1->green_mask == fmt2->green_mask && + fmt1->blue_mask == fmt2->blue_mask && + fmt1->alpha_mask == fmt2->alpha_mask); } static inline gboolean -va_format_is_same(const VAImageFormat *fmt1, const VAImageFormat *fmt2) +va_format_is_same (const VAImageFormat * fmt1, const VAImageFormat * fmt2) { - if (fmt1->fourcc != fmt2->fourcc) - return FALSE; - return va_format_is_rgb(fmt1) ? va_format_is_same_rgb(fmt1, fmt2) : TRUE; + if (fmt1->fourcc != fmt2->fourcc) + return FALSE; + return va_format_is_rgb (fmt1) ? va_format_is_same_rgb (fmt1, fmt2) : TRUE; } static const GstVideoFormatMap * -get_map(GstVideoFormat format) +get_map (GstVideoFormat format) { - const GstVideoFormatMap *m; + const GstVideoFormatMap *m; - for (m = gst_vaapi_video_formats; m->format; m++) { - if (m->format == format) - return m; - } - return NULL; + for (m = gst_vaapi_video_formats; m->format; m++) { + if (m->format == format) + return m; + } + return NULL; } /** @@ -151,43 +151,42 @@ get_map(GstVideoFormat format) * video format in @str. */ GstVideoFormat -gst_vaapi_video_format_from_string(const gchar *str) +gst_vaapi_video_format_from_string (const gchar * str) { #if GST_CHECK_VERSION(1,0,0) - return gst_video_format_from_string(str); + return gst_video_format_from_string (str); #else - GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; + GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; - do { - /* Validate input string */ - if (!str) - break; + do { + /* Validate input string */ + if (!str) + break; - /* Fast path: assume this represents a common fourcc value */ - const guint32 fourcc = GST_MAKE_FOURCC(str[0], str[1], str[2], str[3]); - format = gst_video_format_from_fourcc(fourcc); - if (format != GST_VIDEO_FORMAT_UNKNOWN) - break; + /* Fast path: assume this represents a common fourcc value */ + const guint32 fourcc = GST_MAKE_FOURCC (str[0], str[1], str[2], str[3]); + format = gst_video_format_from_fourcc (fourcc); + if (format != GST_VIDEO_FORMAT_UNKNOWN) + break; - /* Slow path: check through all registered enum values */ - GEnumClass * const enum_class = - g_type_class_ref(GST_TYPE_VIDEO_FORMAT); - if (!enum_class) - break; + /* Slow path: check through all registered enum values */ + GEnumClass *const enum_class = g_type_class_ref (GST_TYPE_VIDEO_FORMAT); + if (!enum_class) + break; - gchar * const video_format_str = - g_strdup_printf("GST_VIDEO_FORMAT_%s", str); - if (video_format_str) { - const GEnumValue * const enum_value = - g_enum_get_value_by_name(enum_class, video_format_str); + gchar *const video_format_str = + g_strdup_printf ("GST_VIDEO_FORMAT_%s", str); + if (video_format_str) { + const GEnumValue *const enum_value = + g_enum_get_value_by_name (enum_class, video_format_str); - if (enum_value) - format = enum_value->value; - g_free(video_format_str); - } - g_type_class_unref(enum_class); - } while (0); - return format; + if (enum_value) + format = enum_value->value; + g_free (video_format_str); + } + g_type_class_unref (enum_class); + } while (0); + return format; #endif } @@ -201,9 +200,9 @@ gst_vaapi_video_format_from_string(const gchar *str) * or unsupported. */ const gchar * -gst_vaapi_video_format_to_string(GstVideoFormat format) +gst_vaapi_video_format_to_string (GstVideoFormat format) { - return gst_video_format_to_string(format); + return gst_video_format_to_string (format); } /** @@ -215,11 +214,11 @@ gst_vaapi_video_format_to_string(GstVideoFormat format) * Return value: %TRUE if @format is RGB format */ gboolean -gst_vaapi_video_format_is_rgb(GstVideoFormat format) +gst_vaapi_video_format_is_rgb (GstVideoFormat format) { - const GstVideoFormatMap * const m = get_map(format); + const GstVideoFormatMap *const m = get_map (format); - return m && va_format_is_rgb(&m->va_format); + return m && va_format_is_rgb (&m->va_format); } /** @@ -231,11 +230,11 @@ gst_vaapi_video_format_is_rgb(GstVideoFormat format) * Return value: %TRUE if @format is YUV format */ gboolean -gst_vaapi_video_format_is_yuv(GstVideoFormat format) +gst_vaapi_video_format_is_yuv (GstVideoFormat format) { - const GstVideoFormatMap * const m = get_map(format); + const GstVideoFormatMap *const m = get_map (format); - return m && va_format_is_yuv(&m->va_format); + return m && va_format_is_yuv (&m->va_format); } /** @@ -249,17 +248,17 @@ gst_vaapi_video_format_is_yuv(GstVideoFormat format) * Return value: the #GstVideoFormat describing the @caps */ GstVideoFormat -gst_vaapi_video_format_from_caps(GstCaps *caps) +gst_vaapi_video_format_from_caps (GstCaps * caps) { - GstStructure *structure; + GstStructure *structure; - if (!caps) - return 0; + if (!caps) + return 0; - structure = gst_caps_get_structure(caps, 0); - if (!structure) - return 0; - return gst_vaapi_video_format_from_structure(structure); + structure = gst_caps_get_structure (caps, 0); + if (!structure) + return 0; + return gst_vaapi_video_format_from_structure (structure); } /** @@ -273,51 +272,51 @@ gst_vaapi_video_format_from_caps(GstCaps *caps) * Return value: the #GstVideoFormat describing the @structure */ GstVideoFormat -gst_vaapi_video_format_from_structure(GstStructure *structure) +gst_vaapi_video_format_from_structure (GstStructure * structure) { #if GST_CHECK_VERSION(1,0,0) - const gchar * format = gst_structure_get_string(structure, "format"); - if (format) - return gst_video_format_from_string(format); - return GST_VIDEO_FORMAT_UNKNOWN; + const gchar *format = gst_structure_get_string (structure, "format"); + if (format) + return gst_video_format_from_string (format); + return GST_VIDEO_FORMAT_UNKNOWN; #else - const GstVideoFormatMap *m; - VAImageFormat *va_format, va_formats[2]; - gint endian, rmask, gmask, bmask, amask = 0; - guint32 fourcc; + const GstVideoFormatMap *m; + VAImageFormat *va_format, va_formats[2]; + gint endian, rmask, gmask, bmask, amask = 0; + guint32 fourcc; - /* Check for YUV format */ - if (gst_structure_get_fourcc(structure, "format", &fourcc)) - return gst_video_format_from_fourcc(fourcc); + /* Check for YUV format */ + if (gst_structure_get_fourcc (structure, "format", &fourcc)) + return gst_video_format_from_fourcc (fourcc); - /* Check for RGB format */ - gst_structure_get_int(structure, "endianness", &endian); - gst_structure_get_int(structure, "red_mask", &rmask); - gst_structure_get_int(structure, "green_mask", &gmask); - gst_structure_get_int(structure, "blue_mask", &bmask); - gst_structure_get_int(structure, "alpha_mask", &amask); + /* Check for RGB format */ + gst_structure_get_int (structure, "endianness", &endian); + gst_structure_get_int (structure, "red_mask", &rmask); + gst_structure_get_int (structure, "green_mask", &gmask); + gst_structure_get_int (structure, "blue_mask", &bmask); + gst_structure_get_int (structure, "alpha_mask", &amask); - va_format = &va_formats[0]; - va_format->byte_order = endian == G_BIG_ENDIAN ? VA_MSB_FIRST : VA_LSB_FIRST; - va_format->red_mask = rmask; - va_format->green_mask = gmask; - va_format->blue_mask = bmask; - va_format->alpha_mask = amask; + va_format = &va_formats[0]; + va_format->byte_order = endian == G_BIG_ENDIAN ? VA_MSB_FIRST : VA_LSB_FIRST; + va_format->red_mask = rmask; + va_format->green_mask = gmask; + va_format->blue_mask = bmask; + va_format->alpha_mask = amask; - va_format = &va_formats[1]; - va_format->byte_order = endian == G_BIG_ENDIAN ? VA_LSB_FIRST : VA_MSB_FIRST; - va_format->red_mask = GUINT32_SWAP_LE_BE(rmask); - va_format->green_mask = GUINT32_SWAP_LE_BE(gmask); - va_format->blue_mask = GUINT32_SWAP_LE_BE(bmask); - va_format->alpha_mask = GUINT32_SWAP_LE_BE(amask); + va_format = &va_formats[1]; + va_format->byte_order = endian == G_BIG_ENDIAN ? VA_LSB_FIRST : VA_MSB_FIRST; + va_format->red_mask = GUINT32_SWAP_LE_BE (rmask); + va_format->green_mask = GUINT32_SWAP_LE_BE (gmask); + va_format->blue_mask = GUINT32_SWAP_LE_BE (bmask); + va_format->alpha_mask = GUINT32_SWAP_LE_BE (amask); - for (m = gst_vaapi_video_formats; m->format; m++) { - if (va_format_is_rgb(&m->va_format) && - (va_format_is_same_rgb(&m->va_format, &va_formats[0]) || - va_format_is_same_rgb(&m->va_format, &va_formats[1]))) - return m->format; - } - return GST_VIDEO_FORMAT_UNKNOWN; + for (m = gst_vaapi_video_formats; m->format; m++) { + if (va_format_is_rgb (&m->va_format) && + (va_format_is_same_rgb (&m->va_format, &va_formats[0]) || + va_format_is_same_rgb (&m->va_format, &va_formats[1]))) + return m->format; + } + return GST_VIDEO_FORMAT_UNKNOWN; #endif } @@ -331,11 +330,11 @@ gst_vaapi_video_format_from_structure(GstStructure *structure) * Return value: the newly allocated #GstCaps, or %NULL if none was found */ GstCaps * -gst_vaapi_video_format_to_caps(GstVideoFormat format) +gst_vaapi_video_format_to_caps (GstVideoFormat format) { - const GstVideoFormatMap * const m = get_map(format); + const GstVideoFormatMap *const m = get_map (format); - return m ? gst_caps_from_string(m->caps_str) : NULL; + return m ? gst_caps_from_string (m->caps_str) : NULL; } /** @@ -348,18 +347,18 @@ gst_vaapi_video_format_to_caps(GstVideoFormat format) * Return value: the #GstVideoFormat corresponding to the VA @fourcc */ GstVideoFormat -gst_vaapi_video_format_from_va_fourcc(guint32 fourcc) +gst_vaapi_video_format_from_va_fourcc (guint32 fourcc) { - const GstVideoFormatMap *m; + const GstVideoFormatMap *m; - /* Note: VA fourcc values are now standardized and shall represent - a unique format. The associated VAImageFormat is just a hint to - determine RGBA component ordering */ - for (m = gst_vaapi_video_formats; m->format; m++) { - if (m->va_format.fourcc == fourcc) - return m->format; - } - return GST_VIDEO_FORMAT_UNKNOWN; + /* Note: VA fourcc values are now standardized and shall represent + a unique format. The associated VAImageFormat is just a hint to + determine RGBA component ordering */ + for (m = gst_vaapi_video_formats; m->format; m++) { + if (m->va_format.fourcc == fourcc) + return m->format; + } + return GST_VIDEO_FORMAT_UNKNOWN; } /** @@ -373,15 +372,15 @@ gst_vaapi_video_format_from_va_fourcc(guint32 fourcc) * Return value: the #GstVideoFormat describing the @va_format */ GstVideoFormat -gst_vaapi_video_format_from_va_format(const VAImageFormat *va_format) +gst_vaapi_video_format_from_va_format (const VAImageFormat * va_format) { - const GstVideoFormatMap *m; + const GstVideoFormatMap *m; - for (m = gst_vaapi_video_formats; m->format; m++) { - if (va_format_is_same(&m->va_format, va_format)) - return m->format; - } - return GST_VIDEO_FORMAT_UNKNOWN; + for (m = gst_vaapi_video_formats; m->format; m++) { + if (va_format_is_same (&m->va_format, va_format)) + return m->format; + } + return GST_VIDEO_FORMAT_UNKNOWN; } /** @@ -395,11 +394,11 @@ gst_vaapi_video_format_from_va_format(const VAImageFormat *va_format) * Return value: the VA image format, or %NULL if none was found */ const VAImageFormat * -gst_vaapi_video_format_to_va_format(GstVideoFormat format) +gst_vaapi_video_format_to_va_format (GstVideoFormat format) { - const GstVideoFormatMap * const m = get_map(format); + const GstVideoFormatMap *const m = get_map (format); - return m ? &m->va_format : NULL; + return m ? &m->va_format : NULL; } /** @@ -413,11 +412,11 @@ gst_vaapi_video_format_to_va_format(GstVideoFormat format) * was found. */ guint -gst_vaapi_video_format_get_chroma_type(GstVideoFormat format) +gst_vaapi_video_format_get_chroma_type (GstVideoFormat format) { - const GstVideoFormatMap * const m = get_map(format); + const GstVideoFormatMap *const m = get_map (format); - return m ? m->chroma_type : 0; + return m ? m->chroma_type : 0; } /** @@ -430,9 +429,9 @@ gst_vaapi_video_format_get_chroma_type(GstVideoFormat format) * Return value: the @format score, or %G_MAXUINT if none was found */ guint -gst_vaapi_video_format_get_score(GstVideoFormat format) +gst_vaapi_video_format_get_score (GstVideoFormat format) { - const GstVideoFormatMap * const m = get_map(format); + const GstVideoFormatMap *const m = get_map (format); - return m ? (m - &gst_vaapi_video_formats[0]) : G_MAXUINT; + return m ? (m - &gst_vaapi_video_formats[0]) : G_MAXUINT; } diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index 69faa0a54e..e09f0ba66e 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -31,40 +31,40 @@ G_BEGIN_DECLS GstVideoFormat -gst_vaapi_video_format_from_string(const gchar *str); +gst_vaapi_video_format_from_string (const gchar * str); -const char * -gst_vaapi_video_format_to_string(GstVideoFormat format); +const gchar * +gst_vaapi_video_format_to_string (GstVideoFormat format); gboolean -gst_vaapi_video_format_is_rgb(GstVideoFormat format); +gst_vaapi_video_format_is_rgb (GstVideoFormat format); gboolean -gst_vaapi_video_format_is_yuv(GstVideoFormat format); +gst_vaapi_video_format_is_yuv (GstVideoFormat format); GstVideoFormat -gst_vaapi_video_format_from_structure(GstStructure *structure); +gst_vaapi_video_format_from_structure (GstStructure * structure); GstVideoFormat -gst_vaapi_video_format_from_caps(GstCaps *caps); +gst_vaapi_video_format_from_caps (GstCaps * caps); GstCaps * -gst_vaapi_video_format_to_caps(GstVideoFormat format); +gst_vaapi_video_format_to_caps (GstVideoFormat format); GstVideoFormat -gst_vaapi_video_format_from_va_fourcc(guint32 fourcc); +gst_vaapi_video_format_from_va_fourcc (guint32 fourcc); GstVideoFormat -gst_vaapi_video_format_from_va_format(const VAImageFormat *va_format); +gst_vaapi_video_format_from_va_format (const VAImageFormat * va_format); const VAImageFormat * -gst_vaapi_video_format_to_va_format(GstVideoFormat format); +gst_vaapi_video_format_to_va_format (GstVideoFormat format); guint -gst_vaapi_video_format_get_chroma_type(GstVideoFormat format); +gst_vaapi_video_format_get_chroma_type (GstVideoFormat format); guint -gst_vaapi_video_format_get_score(GstVideoFormat format); +gst_vaapi_video_format_get_score (GstVideoFormat format); G_END_DECLS From 4902df0e4048fe229c9bc52ba18f3e3a06e4025c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 21 Dec 2013 07:38:14 +0100 Subject: [PATCH 1482/3781] utils: format: drop unused helper functions. The following helper functions are no longer used, thus are removed: - gst_vaapi_video_format_from_structure() - gst_vaapi_video_format_from_caps() - gst_vaapi_video_format_to_caps() --- gst-libs/gst/vaapi/video-format.c | 116 ------------------------------ gst-libs/gst/vaapi/video-format.h | 10 --- 2 files changed, 126 deletions(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 4929fe86fd..88778790bf 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -28,7 +28,6 @@ */ #include "sysdeps.h" -#include #include "gstvaapicompat.h" #include "gstvaapisurface.h" #include "video-format.h" @@ -37,32 +36,17 @@ typedef struct { GstVideoFormat format; GstVaapiChromaType chroma_type; - const gchar *caps_str; VAImageFormat va_format; } GstVideoFormatMap; -#if GST_CHECK_VERSION(1,0,0) -# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \ - GST_VIDEO_CAPS_MAKE(#FORMAT) -# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \ - GST_VIDEO_CAPS_MAKE(#FORMAT) -#else -# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \ - GST_VIDEO_CAPS_YUV(#FORMAT) -# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \ - GST_VIDEO_CAPS_##FORMAT -#endif - #define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP, SUB) \ { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ G_PASTE(GST_VAAPI_CHROMA_TYPE_YUV,SUB), \ - GST_VIDEO_CAPS_MAKE_YUV(FORMAT), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } #define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \ { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ G_PASTE(GST_VAAPI_CHROMA_TYPE_RGB,BPP), \ - GST_VIDEO_CAPS_MAKE_RGB(FORMAT), \ { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } /* Image formats, listed in HW order preference */ @@ -237,106 +221,6 @@ gst_vaapi_video_format_is_yuv (GstVideoFormat format) return m && va_format_is_yuv (&m->va_format); } -/** - * gst_vaapi_video_format_from_caps: - * @caps: a #GstCaps - * - * Converts @caps into the corresponding #GstVideoFormat. If the - * image format cannot be represented by #GstVideoFormat, then - * zero is returned. - * - * Return value: the #GstVideoFormat describing the @caps - */ -GstVideoFormat -gst_vaapi_video_format_from_caps (GstCaps * caps) -{ - GstStructure *structure; - - if (!caps) - return 0; - - structure = gst_caps_get_structure (caps, 0); - if (!structure) - return 0; - return gst_vaapi_video_format_from_structure (structure); -} - -/** - * gst_vaapi_video_format_from_structure: - * @structure: a #GstStructure - * - * Converts @structure into the corresponding #GstVideoFormat. If - * the image format cannot be represented by #GstVideoFormat, - * then zero is returned. - * - * Return value: the #GstVideoFormat describing the @structure - */ -GstVideoFormat -gst_vaapi_video_format_from_structure (GstStructure * structure) -{ -#if GST_CHECK_VERSION(1,0,0) - const gchar *format = gst_structure_get_string (structure, "format"); - if (format) - return gst_video_format_from_string (format); - return GST_VIDEO_FORMAT_UNKNOWN; -#else - const GstVideoFormatMap *m; - VAImageFormat *va_format, va_formats[2]; - gint endian, rmask, gmask, bmask, amask = 0; - guint32 fourcc; - - /* Check for YUV format */ - if (gst_structure_get_fourcc (structure, "format", &fourcc)) - return gst_video_format_from_fourcc (fourcc); - - /* Check for RGB format */ - gst_structure_get_int (structure, "endianness", &endian); - gst_structure_get_int (structure, "red_mask", &rmask); - gst_structure_get_int (structure, "green_mask", &gmask); - gst_structure_get_int (structure, "blue_mask", &bmask); - gst_structure_get_int (structure, "alpha_mask", &amask); - - va_format = &va_formats[0]; - va_format->byte_order = endian == G_BIG_ENDIAN ? VA_MSB_FIRST : VA_LSB_FIRST; - va_format->red_mask = rmask; - va_format->green_mask = gmask; - va_format->blue_mask = bmask; - va_format->alpha_mask = amask; - - va_format = &va_formats[1]; - va_format->byte_order = endian == G_BIG_ENDIAN ? VA_LSB_FIRST : VA_MSB_FIRST; - va_format->red_mask = GUINT32_SWAP_LE_BE (rmask); - va_format->green_mask = GUINT32_SWAP_LE_BE (gmask); - va_format->blue_mask = GUINT32_SWAP_LE_BE (bmask); - va_format->alpha_mask = GUINT32_SWAP_LE_BE (amask); - - for (m = gst_vaapi_video_formats; m->format; m++) { - if (va_format_is_rgb (&m->va_format) && - (va_format_is_same_rgb (&m->va_format, &va_formats[0]) || - va_format_is_same_rgb (&m->va_format, &va_formats[1]))) - return m->format; - } - return GST_VIDEO_FORMAT_UNKNOWN; -#endif -} - -/** - * gst_vaapi_video_format_to_caps: - * @format: a #GstVideoFormat - * - * Converts a #GstVideoFormat into the corresponding #GstCaps. If - * no matching caps were found, %NULL is returned. - * - * Return value: the newly allocated #GstCaps, or %NULL if none was found - */ -GstCaps * -gst_vaapi_video_format_to_caps (GstVideoFormat format) -{ - const GstVideoFormatMap *const m = get_map (format); - - return m ? gst_caps_from_string (m->caps_str) : NULL; -} - /** * gst_vaapi_video_format_from_va_fourcc: * @fourcc: a FOURCC value diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index e09f0ba66e..acc333da43 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -25,7 +25,6 @@ #ifndef GST_VAAPI_VIDEO_FORMAT_H #define GST_VAAPI_VIDEO_FORMAT_H -#include #include G_BEGIN_DECLS @@ -42,15 +41,6 @@ gst_vaapi_video_format_is_rgb (GstVideoFormat format); gboolean gst_vaapi_video_format_is_yuv (GstVideoFormat format); -GstVideoFormat -gst_vaapi_video_format_from_structure (GstStructure * structure); - -GstVideoFormat -gst_vaapi_video_format_from_caps (GstCaps * caps); - -GstCaps * -gst_vaapi_video_format_to_caps (GstVideoFormat format); - GstVideoFormat gst_vaapi_video_format_from_va_fourcc (guint32 fourcc); From 33bb859228d1767573ed0bfdbdac92d69c29c98a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 2 Jan 2014 11:17:28 +0100 Subject: [PATCH 1483/3781] Fix printf()-like formats. Fix formts for various GST_DEBUG et al. invocations. More precisely, make size_t arguments use the %zu format specifier accordingly; force XID formats to be a 32-bit unsigned integer; and fix the format used for gst_vaapi_create_surface_with_format() error cases since we have been using strings nowadays. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 4 ++-- gst-libs/gst/vaapi/gstvaapipixmap_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- gst/vaapi/gstvaapiencode.c | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 6df5ba84ed..8a8fa4cef4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -101,7 +101,7 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_EOS); } - GST_DEBUG("queue encoded data buffer %p (%d bytes)", + GST_DEBUG("queue encoded data buffer %p (%zu bytes)", buffer, gst_buffer_get_size(buffer)); g_async_queue_push(decoder->buffers, buffer); @@ -117,7 +117,7 @@ pop_buffer(GstVaapiDecoder *decoder) if (!buffer) return NULL; - GST_DEBUG("dequeue buffer %p for decoding (%d bytes)", + GST_DEBUG("dequeue buffer %p for decoding (%zu bytes)", buffer, gst_buffer_get_size(buffer)); return buffer; diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c index 8031383370..ac84a76739 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c +++ b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c @@ -208,7 +208,7 @@ gst_vaapi_pixmap_x11_new(GstVaapiDisplay *display, GstVideoFormat format, GstVaapiPixmap * gst_vaapi_pixmap_x11_new_with_xid(GstVaapiDisplay *display, Pixmap xid) { - GST_DEBUG("new pixmap from xid 0x%08x", xid); + GST_DEBUG("new pixmap from xid 0x%08x", (guint)xid); g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); g_return_val_if_fail(xid != None, NULL); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 564c3a97d0..902926dd28 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -187,7 +187,7 @@ gst_vaapi_surface_create_with_format(GstVaapiSurface *surface, /* ERRORS */ error_unsupported_format: - GST_ERROR("unsupported format %u", gst_vaapi_video_format_to_string(format)); + GST_ERROR("unsupported format %s", gst_vaapi_video_format_to_string(format)); return FALSE; #else return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 707a524cd4..d027eaec59 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -400,7 +400,7 @@ gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid) { GstVaapiWindow *window; - GST_DEBUG("new window from xid 0x%08x", xid); + GST_DEBUG("new window from xid 0x%08x", (guint)xid); g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); g_return_val_if_fail(xid != None, NULL); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index d399943482..f0a51708a5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -626,7 +626,7 @@ gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) GstVaapiWindow * gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) { - GST_DEBUG("new window from xid 0x%08x", xid); + GST_DEBUG("new window from xid 0x%08x", (guint)xid); g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); g_return_val_if_fail(xid != None, NULL); diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index d1afc44247..32e01cb0ed 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -122,7 +122,7 @@ gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode, /* ERRORS */ error_invalid_buffer: { - GST_ERROR ("invalid GstVaapiCodedBuffer size (%d)", buf_size); + GST_ERROR ("invalid GstVaapiCodedBuffer size (%d bytes)", buf_size); return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; } error_create_buffer: @@ -202,7 +202,7 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) } GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); - GST_DEBUG ("output:%" GST_TIME_FORMAT ", size:%d", + GST_DEBUG ("output:%" GST_TIME_FORMAT ", size:%zu", GST_TIME_ARGS (out_frame->pts), gst_buffer_get_size (out_buffer)); return gst_video_encoder_finish_frame (venc, out_frame); From dd2ca582a150edd5c9c95a6ddde8960a204bfabe Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 2 Jan 2014 11:35:30 +0100 Subject: [PATCH 1484/3781] tests: simple-decoder: don't use deprecated g_thread_create(). Use g_thread_try_new() instead of the deprecated g_thread_create() function. Provide compatibility glue for any GLib version < 2.31.2. --- gst-libs/gst/vaapi/glibcompat.h | 11 +++++++++++ tests/simple-decoder.c | 6 ++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 66ee910cd1..34e4791467 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -134,6 +134,17 @@ g_cond_wait_until(GCompatCond *cond, GStaticMutex *mutex, gint64 end_time) #define g_cond_signal(cond) g_compat_cond_signal(cond) #undef g_cond_wait #define g_cond_wait(cond, mutex) g_compat_cond_wait(cond, mutex) + +#undef g_thread_try_new +#define g_thread_try_new(name, func, data, error) \ + g_compat_thread_try_new(name, func, data, error) + +static inline GThread * +g_compat_thread_try_new(const gchar *name, GThreadFunc func, gpointer data, + GError **error) +{ + return g_thread_create(func, data, TRUE, error); +} #endif #if !GLIB_CHECK_VERSION(2,31,18) diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index 69c960beb8..bba4f852f1 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -396,7 +396,8 @@ start_decoder(App *app) g_timer_start(app->timer); - app->decoder_thread = g_thread_create(decoder_thread, app, TRUE, NULL); + app->decoder_thread = g_thread_try_new("Decoder Thread", decoder_thread, + app, NULL); if (!app->decoder_thread) return FALSE; return TRUE; @@ -571,7 +572,8 @@ flush_decoder_queue(App *app) static gboolean start_renderer(App *app) { - app->render_thread = g_thread_create(renderer_thread, app, TRUE, NULL); + app->render_thread = g_thread_try_new("Renderer Thread", renderer_thread, + app, NULL); if (!app->render_thread) return FALSE; return TRUE; From 231a067cddc551955fadfb1021f8d6d2b0e1e1ca Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Fri, 3 Jan 2014 12:49:05 +0000 Subject: [PATCH 1485/3781] plugins: do not free debug category in finalize method. Fixes a crash when multiple vaapidecode elements are finalized since the debug category is created once in the class init method. This is a regression from git commit 7e58d60. https://bugzilla.gnome.org/show_bug.cgi?id=721390 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipluginbase.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e1ff7400d2..1c0bc1a41d 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -150,7 +150,6 @@ gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin) gst_object_unref (plugin->sinkpad); if (plugin->srcpad) gst_object_unref (plugin->srcpad); - gst_debug_category_free (plugin->debug_category); } /** From c010ce234014a830d83ed65d0bd739319df460ea Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 9 Jan 2014 09:10:21 +0100 Subject: [PATCH 1486/3781] codec: re-indent base codec objects. --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 224 +++++++++------------ gst-libs/gst/vaapi/gstvaapicodec_objects.h | 162 +++++++-------- 2 files changed, 174 insertions(+), 212 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 1d287dfc0d..f7204afd32 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -41,60 +41,60 @@ gst_vaapi_codec_object_get_class(object) const GstVaapiCodecObjectClass * -gst_vaapi_codec_object_get_class(GstVaapiCodecObject *object) +gst_vaapi_codec_object_get_class (GstVaapiCodecObject * object) { - return (const GstVaapiCodecObjectClass *) - GST_VAAPI_MINI_OBJECT_GET_CLASS(object); + return (const GstVaapiCodecObjectClass *) + GST_VAAPI_MINI_OBJECT_GET_CLASS (object); } static gboolean -gst_vaapi_codec_object_create(GstVaapiCodecObject *object, - const GstVaapiCodecObjectConstructorArgs *args) +gst_vaapi_codec_object_create (GstVaapiCodecObject * object, + const GstVaapiCodecObjectConstructorArgs * args) { - const GstVaapiCodecObjectClass *klass; + const GstVaapiCodecObjectClass *klass; - g_return_val_if_fail(args->param_size > 0, FALSE); + 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); + 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(const GstVaapiCodecObjectClass *object_class, - GstVaapiCodecBase *codec, gconstpointer param, guint param_size, +gst_vaapi_codec_object_new (const GstVaapiCodecObjectClass * object_class, + GstVaapiCodecBase * codec, gconstpointer param, guint param_size, gconstpointer data, guint data_size, guint flags) { - GstVaapiMiniObject *obj; - GstVaapiCodecObject *va_obj; - GstVaapiCodecObjectConstructorArgs args; + GstVaapiMiniObject *obj; + GstVaapiCodecObject *va_obj; + GstVaapiCodecObjectConstructorArgs args; - obj = gst_vaapi_mini_object_new0(&object_class->parent_class); - if (!obj) - return NULL; - - va_obj = GST_VAAPI_CODEC_OBJECT(obj); - va_obj->codec = codec; - - args.param = param; - args.param_size = param_size; - args.data = data; - args.data_size = data_size; - args.flags = flags; - - if (gst_vaapi_codec_object_create(va_obj, &args)) - return va_obj; - - gst_vaapi_mini_object_unref(obj); + obj = gst_vaapi_mini_object_new0 (&object_class->parent_class); + if (!obj) return NULL; + + va_obj = GST_VAAPI_CODEC_OBJECT (obj); + va_obj->codec = codec; + + args.param = param; + args.param_size = param_size; + args.data = data; + args.data_size = data_size; + args.flags = flags; + + if (gst_vaapi_codec_object_create (va_obj, &args)) + return va_obj; + + gst_vaapi_mini_object_unref (obj); + return NULL; } #define GET_DECODER(obj) GST_VAAPI_DECODER_CAST((obj)->parent_instance.codec) @@ -105,97 +105,73 @@ gst_vaapi_codec_object_new(const GstVaapiCodecObjectClass *object_class, /* --- Inverse Quantization Matrices --- */ /* ------------------------------------------------------------------------- */ -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiIqMatrix, gst_vaapi_iq_matrix); +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiIqMatrix, gst_vaapi_iq_matrix); void -gst_vaapi_iq_matrix_destroy(GstVaapiIqMatrix *iq_matrix) +gst_vaapi_iq_matrix_destroy (GstVaapiIqMatrix * iq_matrix) { - vaapi_destroy_buffer(GET_VA_DISPLAY(iq_matrix), &iq_matrix->param_id); - iq_matrix->param = NULL; + 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 -) +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); + 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 -) +gst_vaapi_iq_matrix_new (GstVaapiDecoder * decoder, + gconstpointer param, guint param_size) { - GstVaapiCodecObject *object; + 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); + 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); +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiBitPlane, gst_vaapi_bitplane); void -gst_vaapi_bitplane_destroy(GstVaapiBitPlane *bitplane) +gst_vaapi_bitplane_destroy (GstVaapiBitPlane * bitplane) { - vaapi_destroy_buffer(GET_VA_DISPLAY(bitplane), &bitplane->data_id); - bitplane->data = NULL; + vaapi_destroy_buffer (GET_VA_DISPLAY (bitplane), &bitplane->data_id); + bitplane->data = NULL; } gboolean -gst_vaapi_bitplane_create( - GstVaapiBitPlane *bitplane, - const GstVaapiCodecObjectConstructorArgs *args -) +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); + 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) +gst_vaapi_bitplane_new (GstVaapiDecoder * decoder, guint8 * data, + guint data_size) { - GstVaapiCodecObject *object; + 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); + 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); } /* ------------------------------------------------------------------------- */ @@ -203,49 +179,35 @@ gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size) /* ------------------------------------------------------------------------- */ #if USE_JPEG_DECODER -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiHuffmanTable, gst_vaapi_huffman_table); +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiHuffmanTable, gst_vaapi_huffman_table); void -gst_vaapi_huffman_table_destroy(GstVaapiHuffmanTable *huf_table) +gst_vaapi_huffman_table_destroy (GstVaapiHuffmanTable * huf_table) { - vaapi_destroy_buffer(GET_VA_DISPLAY(huf_table), &huf_table->param_id); - huf_table->param = NULL; + 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 -) +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); + 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 -) +gst_vaapi_huffman_table_new (GstVaapiDecoder * decoder, + guint8 * data, guint data_size) { - GstVaapiCodecObject *object; + 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); + 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); } #endif diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index 6ca268e571..576eea0aa7 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -43,27 +43,29 @@ typedef struct _GstVaapiHuffmanTable GstVaapiHuffmanTable; /* XXX: remove when a common base class for decoder and encoder is available */ #define GST_VAAPI_CODEC_BASE(obj) \ - ((GstVaapiCodecBase *)(obj)) + ((GstVaapiCodecBase *) (obj)) #define GST_VAAPI_CODEC_OBJECT(obj) \ - ((GstVaapiCodecObject *)(obj)) + ((GstVaapiCodecObject *) (obj)) -enum { - GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED = (1 << 0), - GST_VAAPI_CODEC_OBJECT_FLAG_LAST = (1 << 1) +enum +{ + GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED = (1 << 0), + GST_VAAPI_CODEC_OBJECT_FLAG_LAST = (1 << 1) }; -typedef struct { - gconstpointer param; - guint param_size; - gconstpointer data; - guint data_size; - guint flags; +typedef struct +{ + gconstpointer param; + guint param_size; + gconstpointer data; + guint data_size; + guint flags; } GstVaapiCodecObjectConstructorArgs; typedef gboolean -(*GstVaapiCodecObjectCreateFunc)(GstVaapiCodecObject *object, - const GstVaapiCodecObjectConstructorArgs *args); +(*GstVaapiCodecObjectCreateFunc)(GstVaapiCodecObject * object, + const GstVaapiCodecObjectConstructorArgs * args); typedef GDestroyNotify GstVaapiCodecObjectDestroyFunc; @@ -72,10 +74,11 @@ typedef GDestroyNotify GstVaapiCodecObjectDestroyFunc; * * A #GstVaapiMiniObject holding the base codec object data */ -struct _GstVaapiCodecObject { - /*< private >*/ - GstVaapiMiniObject parent_instance; - GstVaapiCodecBase *codec; +struct _GstVaapiCodecObject +{ + /*< private >*/ + GstVaapiMiniObject parent_instance; + GstVaapiCodecBase *codec; }; /** @@ -83,21 +86,22 @@ struct _GstVaapiCodecObject { * * The #GstVaapiCodecObject base class. */ -struct _GstVaapiCodecObjectClass { - /*< private >*/ - GstVaapiMiniObjectClass parent_class; +struct _GstVaapiCodecObjectClass +{ + /*< private >*/ + GstVaapiMiniObjectClass parent_class; - GstVaapiCodecObjectCreateFunc create; + GstVaapiCodecObjectCreateFunc create; }; G_GNUC_INTERNAL const GstVaapiCodecObjectClass * -gst_vaapi_codec_object_get_class(GstVaapiCodecObject *object) G_GNUC_CONST; +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, +gst_vaapi_codec_object_new (const GstVaapiCodecObjectClass * object_class, + GstVaapiCodecBase * codec, gconstpointer param, guint param_size, gconstpointer data, guint data_size, guint flags); /* ------------------------------------------------------------------------- */ @@ -105,120 +109,116 @@ gst_vaapi_codec_object_new(const GstVaapiCodecObjectClass *object_class, /* ------------------------------------------------------------------------- */ #define GST_VAAPI_IQ_MATRIX_CAST(obj) \ - ((GstVaapiIqMatrix *)(obj)) + ((GstVaapiIqMatrix *) (obj)) /** * GstVaapiIqMatrix: * * A #GstVaapiCodecObject holding an inverse quantization matrix parameter. */ -struct _GstVaapiIqMatrix { - /*< private >*/ - GstVaapiCodecObject parent_instance; - VABufferID param_id; +struct _GstVaapiIqMatrix +{ + /*< private >*/ + GstVaapiCodecObject parent_instance; + VABufferID param_id; - /*< public >*/ - gpointer param; + /*< public >*/ + gpointer param; }; G_GNUC_INTERNAL GstVaapiIqMatrix * -gst_vaapi_iq_matrix_new( - GstVaapiDecoder *decoder, - gconstpointer param, - guint param_size -); +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 *) (obj)) /** * GstVaapiBitPlane: * * A #GstVaapiCodecObject holding a VC-1 bit plane parameter. */ -struct _GstVaapiBitPlane { - /*< private >*/ - GstVaapiCodecObject parent_instance; - VABufferID data_id; +struct _GstVaapiBitPlane +{ + /*< private >*/ + GstVaapiCodecObject parent_instance; + VABufferID data_id; - /*< public >*/ - guint8 *data; + /*< public >*/ + guint8 *data; }; G_GNUC_INTERNAL GstVaapiBitPlane * -gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size); +gst_vaapi_bitplane_new (GstVaapiDecoder * decoder, guint8 * data, + guint data_size); /* ------------------------------------------------------------------------- */ /* --- JPEG Huffman Tables --- */ /* ------------------------------------------------------------------------- */ #define GST_VAAPI_HUFFMAN_TABLE_CAST(obj) \ - ((GstVaapiHuffmanTable *)(obj)) + ((GstVaapiHuffmanTable *) (obj)) /** * GstVaapiHuffmanTable: * * A #GstVaapiCodecObject holding huffman table. */ -struct _GstVaapiHuffmanTable { - /*< private >*/ - GstVaapiCodecObject parent_instance; - VABufferID param_id; +struct _GstVaapiHuffmanTable +{ + /*< private >*/ + GstVaapiCodecObject parent_instance; + VABufferID param_id; - /*< public >*/ - gpointer param; + /*< public >*/ + gpointer param; }; G_GNUC_INTERNAL GstVaapiHuffmanTable * -gst_vaapi_huffman_table_new( - GstVaapiDecoder *decoder, - guint8 *data, - guint data_size -); +gst_vaapi_huffman_table_new (GstVaapiDecoder * decoder, guint8 * data, + guint data_size); /* ------------------------------------------------------------------------- */ /* --- Helpers to create codec-dependent objects --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_CODEC_DEFINE_TYPE(type, prefix) \ -G_GNUC_INTERNAL \ -void \ -prefix##_destroy(type *); \ - \ -G_GNUC_INTERNAL \ -gboolean \ -prefix##_create( \ - type *, \ - const GstVaapiCodecObjectConstructorArgs *args \ -); \ - \ -static const GstVaapiCodecObjectClass type##Class = { \ - .parent_class = { \ - .size = sizeof(type), \ - .finalize = (GstVaapiCodecObjectDestroyFunc) \ - prefix##_destroy \ - }, \ - .create = (GstVaapiCodecObjectCreateFunc) \ - prefix##_create, \ +#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(VAIQMatrixBuffer##codec)) + 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) + 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(VAHuffmanTableBuffer##codec)) + gst_vaapi_huffman_table_new (GST_VAAPI_DECODER_CAST (decoder), \ + NULL, sizeof (G_PASTE (VAHuffmanTableBuffer, codec))) G_END_DECLS From caf13671bb59284e54f2d212646b3773ecddfa92 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 9 Jan 2014 09:30:49 +0100 Subject: [PATCH 1487/3781] codec: re-indent decoder objects. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 678 +++++++++---------- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 196 +++--- 2 files changed, 412 insertions(+), 462 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 35a9ffb6a2..b2f63199db 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -40,438 +40,392 @@ #define GET_VA_CONTEXT(obj) GET_DECODER(obj)->va_context static inline void -gst_video_codec_frame_clear(GstVideoCodecFrame **frame_ptr) +gst_video_codec_frame_clear (GstVideoCodecFrame ** frame_ptr) { - if (!*frame_ptr) - return; - gst_video_codec_frame_unref(*frame_ptr); - *frame_ptr = NULL; + if (!*frame_ptr) + return; + gst_video_codec_frame_unref (*frame_ptr); + *frame_ptr = NULL; } /* ------------------------------------------------------------------------- */ /* --- Pictures --- */ /* ------------------------------------------------------------------------- */ -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPicture, gst_vaapi_picture); +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, +enum +{ + GST_VAAPI_CREATE_PICTURE_FLAG_CLONE = 1 << 0, + GST_VAAPI_CREATE_PICTURE_FLAG_FIELD = 1 << 1, }; static void -destroy_slice_cb(gpointer data, gpointer user_data) +destroy_slice_cb (gpointer data, gpointer user_data) { - GstVaapiMiniObject * const object = data; + GstVaapiMiniObject *const object = data; - gst_vaapi_mini_object_unref(object); + gst_vaapi_mini_object_unref (object); } void -gst_vaapi_picture_destroy(GstVaapiPicture *picture) +gst_vaapi_picture_destroy (GstVaapiPicture * picture) { - if (picture->slices) { - g_ptr_array_foreach(picture->slices, destroy_slice_cb, NULL); - g_ptr_array_free(picture->slices, TRUE); - picture->slices = NULL; - } + if (picture->slices) { + g_ptr_array_foreach (picture->slices, destroy_slice_cb, NULL); + g_ptr_array_free (picture->slices, TRUE); + picture->slices = NULL; + } - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)&picture->iq_matrix, - NULL); - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)&picture->huf_table, - NULL); - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)&picture->bitplane, - NULL); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & picture->iq_matrix, + NULL); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & picture->huf_table, + NULL); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & picture->bitplane, + NULL); - if (picture->proxy) { - gst_vaapi_surface_proxy_unref(picture->proxy); - picture->proxy = NULL; - } - picture->surface_id = VA_INVALID_ID; - picture->surface = 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; + 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); + 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 -) +gst_vaapi_picture_create (GstVaapiPicture * picture, + const GstVaapiCodecObjectConstructorArgs * args) { - gboolean success; + gboolean success; - picture->param_id = VA_INVALID_ID; + picture->param_id = VA_INVALID_ID; - if (args->flags & GST_VAAPI_CREATE_PICTURE_FLAG_CLONE) { - GstVaapiPicture * const parent_picture = GST_VAAPI_PICTURE(args->data); + 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->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->proxy = gst_vaapi_surface_proxy_ref (parent_picture->proxy); + picture->type = parent_picture->type; + picture->pts = parent_picture->pts; + picture->poc = parent_picture->poc; - // 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) - ); + // 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)); - 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(); - 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); -} - -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(GstVaapiPicture *picture) -{ - GstVaapiIqMatrix *iq_matrix; - GstVaapiBitPlane *bitplane; - GstVaapiHuffmanTable *huf_table; - VADisplay va_display; - VAContextID va_context; - VAStatus status; - guint i; - - g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE); - - va_display = GET_VA_DISPLAY(picture); - va_context = GET_VA_CONTEXT(picture); - - GST_DEBUG("decode picture 0x%08x", picture->surface_id); - - status = vaBeginPicture(va_display, va_context, picture->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; - - 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; - - vaapi_destroy_buffer(va_display, &slice->param_id); - vaapi_destroy_buffer(va_display, &slice->data_id); + 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); } - status = vaEndPicture(va_display, va_context); - if (!vaapi_check_status(status, "vaEndPicture()")) - return FALSE; - return TRUE; -} - -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 (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; + return FALSE; - proxy = gst_vaapi_surface_proxy_ref(picture->proxy); + 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); - if (picture->has_crop_rect) - gst_vaapi_surface_proxy_set_crop_rect(proxy, &picture->crop_rect); + 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; - gst_video_codec_frame_set_user_data(out_frame, - proxy, (GDestroyNotify)gst_vaapi_mini_object_unref); + picture->slices = g_ptr_array_new (); + if (!picture->slices) + return FALSE; - 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_INTERLACED(picture)) { - flags |= GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED; - if (GST_VAAPI_PICTURE_IS_TFF(picture)) - flags |= GST_VAAPI_SURFACE_PROXY_FLAG_TFF; - } - 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; + picture->frame = + gst_video_codec_frame_ref (GST_VAAPI_DECODER_CODEC_FRAME (GET_DECODER + (picture))); + return TRUE; } -gboolean -gst_vaapi_picture_output(GstVaapiPicture *picture) +GstVaapiPicture * +gst_vaapi_picture_new (GstVaapiDecoder * decoder, + gconstpointer param, guint param_size) { - g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE); + GstVaapiCodecObject *object; - 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; - 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); + 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); } void -gst_vaapi_picture_set_crop_rect(GstVaapiPicture *picture, - const GstVaapiRectangle *crop_rect) +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_PICTURE (picture)); + g_return_if_fail (GST_VAAPI_IS_SLICE (slice)); - picture->has_crop_rect = crop_rect != NULL; - if (picture->has_crop_rect) - picture->crop_rect = *crop_rect; + 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 (GstVaapiPicture * picture) +{ + GstVaapiIqMatrix *iq_matrix; + GstVaapiBitPlane *bitplane; + GstVaapiHuffmanTable *huf_table; + VADisplay va_display; + VAContextID va_context; + VAStatus status; + guint i; + + g_return_val_if_fail (GST_VAAPI_IS_PICTURE (picture), FALSE); + + va_display = GET_VA_DISPLAY (picture); + va_context = GET_VA_CONTEXT (picture); + + GST_DEBUG ("decode picture 0x%08x", picture->surface_id); + + status = vaBeginPicture (va_display, va_context, picture->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; + + 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; + + vaapi_destroy_buffer (va_display, &slice->param_id); + vaapi_destroy_buffer (va_display, &slice->data_id); + } + + status = vaEndPicture (va_display, va_context); + if (!vaapi_check_status (status, "vaEndPicture()")) + return FALSE; + return TRUE; +} + +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_INTERLACED (picture)) { + flags |= GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED; + if (GST_VAAPI_PICTURE_IS_TFF (picture)) + flags |= GST_VAAPI_SURFACE_PROXY_FLAG_TFF; + } + 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; + 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); +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiSlice, gst_vaapi_slice); void -gst_vaapi_slice_destroy(GstVaapiSlice *slice) +gst_vaapi_slice_destroy (GstVaapiSlice * slice) { - VADisplay const va_display = GET_VA_DISPLAY(slice); + VADisplay const va_display = GET_VA_DISPLAY (slice); - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)&slice->huf_table, - NULL); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & slice->huf_table, + NULL); - vaapi_destroy_buffer(va_display, &slice->data_id); - vaapi_destroy_buffer(va_display, &slice->param_id); - slice->param = 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 -) +gst_vaapi_slice_create (GstVaapiSlice * slice, + const GstVaapiCodecObjectConstructorArgs * args) { - VASliceParameterBufferBase *slice_param; - gboolean success; + VASliceParameterBufferBase *slice_param; + gboolean success; - slice->param_id = VA_INVALID_ID; - slice->data_id = VA_INVALID_ID; + 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; + 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; - success = vaapi_create_buffer( - GET_VA_DISPLAY(slice), - GET_VA_CONTEXT(slice), - VASliceParameterBufferType, - args->param_size, - args->param, - &slice->param_id, - &slice->param - ); - if (!success) - return FALSE; + success = vaapi_create_buffer (GET_VA_DISPLAY (slice), GET_VA_CONTEXT (slice), + VASliceParameterBufferType, args->param_size, args->param, + &slice->param_id, &slice->param); + 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; + 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 -) +gst_vaapi_slice_new (GstVaapiDecoder * decoder, + gconstpointer param, guint param_size, const guchar * data, guint data_size) { - GstVaapiCodecObject *object; + 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); + 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); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 5480ac553d..ab3c1fda0f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -37,23 +37,24 @@ typedef struct _GstVaapiSlice GstVaapiSlice; /* ------------------------------------------------------------------------- */ #define GST_VAAPI_PICTURE_CAST(obj) \ - ((GstVaapiPicture *)(obj)) + ((GstVaapiPicture *) (obj)) #define GST_VAAPI_PICTURE(obj) \ - GST_VAAPI_PICTURE_CAST(obj) + GST_VAAPI_PICTURE_CAST (obj) #define GST_VAAPI_IS_PICTURE(obj) \ - (GST_VAAPI_PICTURE(obj) != NULL) + (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) +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; /** @@ -68,14 +69,15 @@ typedef enum { * * 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_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 6), +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_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 6), } GstVaapiPictureFlags; #define GST_VAAPI_PICTURE_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS @@ -84,176 +86,170 @@ typedef enum { #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) + 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) + 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) + 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) + 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) + 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) + GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_TFF) #define GST_VAAPI_PICTURE_IS_FRAME(picture) \ - (GST_VAAPI_PICTURE(picture)->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME) + (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_FIRST_FIELD(picture)) + (GST_VAAPI_PICTURE_IS_FRAME (picture) || \ + !GST_VAAPI_PICTURE_IS_FIRST_FIELD (picture)) /** * 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; +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; - GstClockTime pts; - gint32 poc; - guint structure; - GstVaapiRectangle crop_rect; - guint has_crop_rect : 1; + /*< public >*/ + GstVaapiPictureType type; + VASurfaceID surface_id; + gpointer param; + GPtrArray *slices; + GstVaapiIqMatrix *iq_matrix; + GstVaapiHuffmanTable *huf_table; + GstVaapiBitPlane *bitplane; + GstClockTime pts; + gint32 poc; + guint structure; + GstVaapiRectangle crop_rect; + guint has_crop_rect:1; }; G_GNUC_INTERNAL void -gst_vaapi_picture_destroy(GstVaapiPicture *picture); +gst_vaapi_picture_destroy (GstVaapiPicture * picture); G_GNUC_INTERNAL gboolean -gst_vaapi_picture_create(GstVaapiPicture *picture, - const GstVaapiCodecObjectConstructorArgs *args); +gst_vaapi_picture_create (GstVaapiPicture * picture, + const GstVaapiCodecObjectConstructorArgs * args); G_GNUC_INTERNAL GstVaapiPicture * -gst_vaapi_picture_new( - GstVaapiDecoder *decoder, - gconstpointer param, - guint param_size -); +gst_vaapi_picture_new (GstVaapiDecoder * decoder, + gconstpointer param, guint param_size); G_GNUC_INTERNAL GstVaapiPicture * -gst_vaapi_picture_new_field(GstVaapiPicture *picture); +gst_vaapi_picture_new_field (GstVaapiPicture * picture); G_GNUC_INTERNAL void -gst_vaapi_picture_add_slice(GstVaapiPicture *picture, GstVaapiSlice *slice); +gst_vaapi_picture_add_slice (GstVaapiPicture * picture, GstVaapiSlice * slice); G_GNUC_INTERNAL gboolean -gst_vaapi_picture_decode(GstVaapiPicture *picture); +gst_vaapi_picture_decode (GstVaapiPicture * picture); G_GNUC_INTERNAL gboolean -gst_vaapi_picture_output(GstVaapiPicture *picture); +gst_vaapi_picture_output (GstVaapiPicture * picture); G_GNUC_INTERNAL void -gst_vaapi_picture_set_crop_rect(GstVaapiPicture *picture, - const GstVaapiRectangle *crop_rect); +gst_vaapi_picture_set_crop_rect (GstVaapiPicture * picture, + const GstVaapiRectangle * crop_rect); static inline gpointer -gst_vaapi_picture_ref(gpointer ptr) +gst_vaapi_picture_ref (gpointer ptr) { - return gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(ptr)); + return gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (ptr)); } static inline void -gst_vaapi_picture_unref(gpointer ptr) +gst_vaapi_picture_unref (gpointer ptr) { - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(ptr)); + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (ptr)); } #define gst_vaapi_picture_replace(old_picture_p, new_picture) \ - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_picture_p), \ - (GstVaapiMiniObject *)(new_picture)) + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_picture_p), \ + (GstVaapiMiniObject *) (new_picture)) /* ------------------------------------------------------------------------- */ /* --- Slices --- */ /* ------------------------------------------------------------------------- */ #define GST_VAAPI_SLICE_CAST(obj) \ - ((GstVaapiSlice *)(obj)) + ((GstVaapiSlice *) (obj)) #define GST_VAAPI_SLICE(obj) \ - GST_VAAPI_SLICE_CAST(obj) + GST_VAAPI_SLICE_CAST (obj) #define GST_VAAPI_IS_SLICE(obj) \ - (GST_VAAPI_SLICE(obj) != NULL) + (GST_VAAPI_SLICE (obj) != NULL) /** * GstVaapiSlice: * * A #GstVaapiCodecObject holding a slice parameter. */ -struct _GstVaapiSlice { - /*< private >*/ - GstVaapiCodecObject parent_instance; +struct _GstVaapiSlice +{ + /*< private >*/ + GstVaapiCodecObject parent_instance; - /*< public >*/ - VABufferID param_id; - VABufferID data_id; - gpointer param; + /*< public >*/ + VABufferID param_id; + VABufferID data_id; + gpointer param; - /* Per-slice overrides */ - GstVaapiHuffmanTable *huf_table; + /* Per-slice overrides */ + GstVaapiHuffmanTable *huf_table; }; G_GNUC_INTERNAL void -gst_vaapi_slice_destroy(GstVaapiSlice *slice); +gst_vaapi_slice_destroy (GstVaapiSlice * slice); G_GNUC_INTERNAL gboolean -gst_vaapi_slice_create(GstVaapiSlice *slice, - const GstVaapiCodecObjectConstructorArgs *args); +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 -); +gst_vaapi_slice_new (GstVaapiDecoder * decoder, gconstpointer param, + guint param_size, 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(VAPictureParameterBuffer##codec)) +#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(VASliceParameterBuffer##codec), \ - buf, buf_size) +#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) G_END_DECLS From 39dda15f5fa7d3881a9f95d62970a52dd0c00ec1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 9 Jan 2014 09:27:40 +0100 Subject: [PATCH 1488/3781] codec: add helper macros to maintain object refcount. Add gst_vaapi_mini_object_{ref,unref,replace}() helper macros so that to avoid explicit casts to GstVaapiMiniObject in all caller sites. --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 17 +++++++------ gst-libs/gst/vaapi/gstvaapicodec_objects.h | 10 ++++++++ gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 26 ++++++-------------- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 19 +++++--------- 4 files changed, 32 insertions(+), 40 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index f7204afd32..26c0c04737 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -73,16 +73,17 @@ gst_vaapi_codec_object_new (const GstVaapiCodecObjectClass * object_class, GstVaapiCodecBase * codec, gconstpointer param, guint param_size, gconstpointer data, guint data_size, guint flags) { - GstVaapiMiniObject *obj; - GstVaapiCodecObject *va_obj; + GstVaapiCodecObject *obj; GstVaapiCodecObjectConstructorArgs args; - obj = gst_vaapi_mini_object_new0 (&object_class->parent_class); + obj = + (GstVaapiCodecObject *) + gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS (object_class)); if (!obj) return NULL; - va_obj = GST_VAAPI_CODEC_OBJECT (obj); - va_obj->codec = codec; + obj = GST_VAAPI_CODEC_OBJECT (obj); + obj->codec = codec; args.param = param; args.param_size = param_size; @@ -90,10 +91,10 @@ gst_vaapi_codec_object_new (const GstVaapiCodecObjectClass * object_class, args.data_size = data_size; args.flags = flags; - if (gst_vaapi_codec_object_create (va_obj, &args)) - return va_obj; + if (gst_vaapi_codec_object_create (obj, &args)) + return obj; - gst_vaapi_mini_object_unref (obj); + gst_vaapi_codec_object_unref (obj); return NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index 576eea0aa7..10d4582c9d 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -104,6 +104,16 @@ gst_vaapi_codec_object_new (const GstVaapiCodecObjectClass * object_class, GstVaapiCodecBase * codec, gconstpointer param, guint param_size, 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 --- */ /* ------------------------------------------------------------------------- */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index b2f63199db..33cbb92308 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -60,29 +60,17 @@ enum GST_VAAPI_CREATE_PICTURE_FLAG_FIELD = 1 << 1, }; -static void -destroy_slice_cb (gpointer data, gpointer user_data) -{ - GstVaapiMiniObject *const object = data; - - gst_vaapi_mini_object_unref (object); -} - void gst_vaapi_picture_destroy (GstVaapiPicture * picture) { if (picture->slices) { - g_ptr_array_foreach (picture->slices, destroy_slice_cb, NULL); - g_ptr_array_free (picture->slices, TRUE); + g_ptr_array_unref (picture->slices); picture->slices = NULL; } - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & picture->iq_matrix, - NULL); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & picture->huf_table, - NULL); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & picture->bitplane, - 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); if (picture->proxy) { gst_vaapi_surface_proxy_unref (picture->proxy); @@ -164,7 +152,8 @@ gst_vaapi_picture_create (GstVaapiPicture * picture, return FALSE; picture->param_size = args->param_size; - picture->slices = g_ptr_array_new (); + picture->slices = g_ptr_array_new_with_free_func ((GDestroyNotify) + gst_vaapi_mini_object_unref); if (!picture->slices) return FALSE; @@ -382,8 +371,7 @@ gst_vaapi_slice_destroy (GstVaapiSlice * slice) { VADisplay const va_display = GET_VA_DISPLAY (slice); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & slice->huf_table, - NULL); + 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); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index ab3c1fda0f..7908461081 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -176,21 +176,14 @@ void gst_vaapi_picture_set_crop_rect (GstVaapiPicture * picture, const GstVaapiRectangle * crop_rect); -static inline gpointer -gst_vaapi_picture_ref (gpointer ptr) -{ - return gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (ptr)); -} +#define gst_vaapi_picture_ref(picture) \ + gst_vaapi_codec_object_ref (picture) -static inline void -gst_vaapi_picture_unref (gpointer ptr) -{ - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (ptr)); -} +#define gst_vaapi_picture_unref(picture) \ + gst_vaapi_codec_object_unref (picture) -#define gst_vaapi_picture_replace(old_picture_p, new_picture) \ - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_picture_p), \ - (GstVaapiMiniObject *) (new_picture)) +#define gst_vaapi_picture_replace(old_picture_ptr, new_picture) \ + gst_vaapi_codec_object_replace (old_picture_ptr, new_picture) /* ------------------------------------------------------------------------- */ /* --- Slices --- */ From 589078f2a4390aefc1da25aed2709408a6d9c3ab Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 10 Jan 2014 18:27:20 +0100 Subject: [PATCH 1489/3781] utils: h264: expose levels in public header. Instal header but only expose the H.264 levels in there. The additional helper functions are meant to be private for now. --- gst-libs/gst/vaapi/Makefile.am | 3 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_h264.h | 61 ------------- gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h | 93 ++++++++++++++++++++ 5 files changed, 97 insertions(+), 64 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 6fc45836fd..f429c07309 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -94,6 +94,7 @@ libgstvaapi_source_h = \ gstvaapisurfacepool.h \ gstvaapisurfaceproxy.h \ gstvaapitypes.h \ + gstvaapiutils_h264.h \ gstvaapivalue.h \ gstvaapivideopool.h \ gstvaapiwindow.h \ @@ -121,7 +122,7 @@ libgstvaapi_source_priv_h = \ gstvaapisurface_priv.h \ gstvaapisurfaceproxy_priv.h \ gstvaapiutils.h \ - gstvaapiutils_h264.h \ + gstvaapiutils_h264_priv.h \ gstvaapiversion.h \ gstvaapivideopool_priv.h \ gstvaapiwindow_priv.h \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 8d8efa027a..b523cbccdd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -34,7 +34,7 @@ #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" -#include "gstvaapiutils_h264.h" +#include "gstvaapiutils_h264_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index 54d8dd7e9a..e78adda596 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -22,7 +22,7 @@ #include "sysdeps.h" #include -#include "gstvaapiutils_h264.h" +#include "gstvaapiutils_h264_priv.h" /* Table A-1 - Level limits */ /* *INDENT-OFF* */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.h b/gst-libs/gst/vaapi/gstvaapiutils_h264.h index cbd7217982..2aee036214 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.h @@ -71,67 +71,6 @@ typedef enum GST_VAAPI_LEVEL_H264_L5_2, } GstVaapiLevelH264; -/** - * GstVaapiH264LevelLimits: - * @level: the #GstVaapiLevelH264 - * @level_idc: the H.264 level_idc value - * @MaxMBPS: the maximum macroblock processing rate (MB/sec) - * @MaxFS: the maximum frame size (MBs) - * @MaxDpbMbs: the maxium decoded picture buffer size (MBs) - * @MaxBR: the maximum video bit rate (kbps) - * - * The data structure that describes the limits of an H.264 level. - */ -typedef struct -{ - GstVaapiLevelH264 level; - guint8 level_idc; - guint32 MaxMBPS; - guint32 MaxFS; - guint32 MaxDpbMbs; - guint32 MaxBR; -} GstVaapiH264LevelLimits; - -/* Returns GstVaapiProfile from H.264 profile_idc value */ -G_GNUC_INTERNAL -GstVaapiProfile -gst_vaapi_utils_h264_get_profile (guint8 profile_idc); - -/* Returns H.264 profile_idc value from GstVaapiProfile */ -G_GNUC_INTERNAL -guint8 -gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile); - -/* Returns GstVaapiLevelH264 from H.264 level_idc value */ -G_GNUC_INTERNAL -GstVaapiLevelH264 -gst_vaapi_utils_h264_get_level (guint8 level_idc); - -/* Returns H.264 level_idc value from GstVaapiLevelH264 */ -G_GNUC_INTERNAL -guint8 -gst_vaapi_utils_h264_get_level_idc (GstVaapiLevelH264 level); - -/* Returns level limits as specified in Table A-1 of the H.264 standard */ -G_GNUC_INTERNAL -const GstVaapiH264LevelLimits * -gst_vaapi_utils_h264_get_level_limits (GstVaapiLevelH264 level); - -/* Returns the Table A-1 specification */ -G_GNUC_INTERNAL -const GstVaapiH264LevelLimits * -gst_vaapi_utils_h264_get_level_limits_table (guint *out_length_ptr); - -/* Returns GstVaapiChromaType from H.264 chroma_format_idc value */ -G_GNUC_INTERNAL -GstVaapiChromaType -gst_vaapi_utils_h264_get_chroma_type (guint chroma_format_idc); - -/* Returns H.264 chroma_format_idc value from GstVaapiChromaType */ -G_GNUC_INTERNAL -guint -gst_vaapi_utils_h264_get_chroma_format_idc (GstVaapiChromaType chroma_type); - G_END_DECLS #endif /* GST_VAAPI_UTILS_H264_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h new file mode 100644 index 0000000000..1c7db35150 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h @@ -0,0 +1,93 @@ +/* + * gstvaapiutils_h264_priv.h - H.264 related utilities + * + * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_UTILS_H264_PRIV_H +#define GST_VAAPI_UTILS_H264_PRIV_H + +#include "gstvaapiutils_h264.h" + +G_BEGIN_DECLS + +/** + * GstVaapiH264LevelLimits: + * @level: the #GstVaapiLevelH264 + * @level_idc: the H.264 level_idc value + * @MaxMBPS: the maximum macroblock processing rate (MB/sec) + * @MaxFS: the maximum frame size (MBs) + * @MaxDpbMbs: the maxium decoded picture buffer size (MBs) + * @MaxBR: the maximum video bit rate (kbps) + * + * The data structure that describes the limits of an H.264 level. + */ +typedef struct +{ + GstVaapiLevelH264 level; + guint8 level_idc; + guint32 MaxMBPS; + guint32 MaxFS; + guint32 MaxDpbMbs; + guint32 MaxBR; +} GstVaapiH264LevelLimits; + +/* Returns GstVaapiProfile from H.264 profile_idc value */ +G_GNUC_INTERNAL +GstVaapiProfile +gst_vaapi_utils_h264_get_profile (guint8 profile_idc); + +/* Returns H.264 profile_idc value from GstVaapiProfile */ +G_GNUC_INTERNAL +guint8 +gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile); + +/* Returns GstVaapiLevelH264 from H.264 level_idc value */ +G_GNUC_INTERNAL +GstVaapiLevelH264 +gst_vaapi_utils_h264_get_level (guint8 level_idc); + +/* Returns H.264 level_idc value from GstVaapiLevelH264 */ +G_GNUC_INTERNAL +guint8 +gst_vaapi_utils_h264_get_level_idc (GstVaapiLevelH264 level); + +/* Returns level limits as specified in Table A-1 of the H.264 standard */ +G_GNUC_INTERNAL +const GstVaapiH264LevelLimits * +gst_vaapi_utils_h264_get_level_limits (GstVaapiLevelH264 level); + +/* Returns the Table A-1 specification */ +G_GNUC_INTERNAL +const GstVaapiH264LevelLimits * +gst_vaapi_utils_h264_get_level_limits_table (guint *out_length_ptr); + +/* Returns GstVaapiChromaType from H.264 chroma_format_idc value */ +G_GNUC_INTERNAL +GstVaapiChromaType +gst_vaapi_utils_h264_get_chroma_type (guint chroma_format_idc); + +/* Returns H.264 chroma_format_idc value from GstVaapiChromaType */ +G_GNUC_INTERNAL +guint +gst_vaapi_utils_h264_get_chroma_format_idc (GstVaapiChromaType chroma_type); + +G_END_DECLS + +#endif /* GST_VAAPI_UTILS_H264_PRIV_H */ From b0c2ac415941422fd8cefda2e1874b885b0cc330 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 10 Jan 2014 19:37:44 +0100 Subject: [PATCH 1490/3781] utils: h264: add helpers for profile and level string mappings. Add profile and level helper functions to convert to/from strings. --- gst-libs/gst/vaapi/gstvaapiutils_h264.c | 142 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_h264.h | 16 +++ 2 files changed, 158 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index e78adda596..20cc474463 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -24,6 +24,55 @@ #include #include "gstvaapiutils_h264_priv.h" +struct map +{ + guint value; + const gchar *name; +}; + +/* Profile string map */ +static const struct map gst_vaapi_h264_profile_map[] = { +/* *INDENT-OFF* */ + { GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE, "constrained-baseline" }, + { GST_VAAPI_PROFILE_H264_BASELINE, "baseline" }, + { GST_VAAPI_PROFILE_H264_MAIN, "main" }, + { GST_VAAPI_PROFILE_H264_EXTENDED, "extended" }, + { GST_VAAPI_PROFILE_H264_HIGH, "high" }, + { GST_VAAPI_PROFILE_H264_HIGH10, "high-10" }, + { GST_VAAPI_PROFILE_H264_HIGH_422, "high-4:2:2" }, + { GST_VAAPI_PROFILE_H264_HIGH_444, "high-4:4:4" }, + { GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE, "scalable-baseline" }, + { GST_VAAPI_PROFILE_H264_SCALABLE_HIGH, "scalable-high" }, + { GST_VAAPI_PROFILE_H264_STEREO_HIGH, "stereo-high" }, + { GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH, "multiview-high" }, + { 0, NULL } +/* *INDENT-ON* */ +}; + +/* Level string map */ +static const struct map gst_vaapi_h264_level_map[] = { +/* *INDENT-OFF* */ + { GST_VAAPI_LEVEL_H264_L1, "1" }, + { GST_VAAPI_LEVEL_H264_L1b, "1b" }, + { GST_VAAPI_LEVEL_H264_L1_1, "1.1" }, + { GST_VAAPI_LEVEL_H264_L1_2, "1.2" }, + { GST_VAAPI_LEVEL_H264_L1_3, "1.3" }, + { GST_VAAPI_LEVEL_H264_L2, "2" }, + { GST_VAAPI_LEVEL_H264_L2_1, "2.1" }, + { GST_VAAPI_LEVEL_H264_L2_2, "2.2" }, + { GST_VAAPI_LEVEL_H264_L3, "3" }, + { GST_VAAPI_LEVEL_H264_L3_1, "3.1" }, + { GST_VAAPI_LEVEL_H264_L3_2, "3.2" }, + { GST_VAAPI_LEVEL_H264_L4, "4" }, + { GST_VAAPI_LEVEL_H264_L4_1, "4.1" }, + { GST_VAAPI_LEVEL_H264_L4_2, "4.2" }, + { GST_VAAPI_LEVEL_H264_L5, "5" }, + { GST_VAAPI_LEVEL_H264_L5_1, "5.1" }, + { GST_VAAPI_LEVEL_H264_L5_2, "5.2" }, + { 0, NULL } +/* *INDENT-ON* */ +}; + /* Table A-1 - Level limits */ /* *INDENT-OFF* */ static const GstVaapiH264LevelLimits gst_vaapi_h264_level_limits[] = { @@ -49,6 +98,35 @@ static const GstVaapiH264LevelLimits gst_vaapi_h264_level_limits[] = { }; /* *INDENT-ON* */ +/* Lookup value in map */ +static const struct map * +map_lookup_value (const struct map *m, guint value) +{ + g_return_val_if_fail (m != NULL, NULL); + + for (; m->name != NULL; m++) { + if (m->value == value) + return m; + } + return NULL; +} + +/* Lookup name in map */ +static const struct map * +map_lookup_name (const struct map *m, const gchar * name) +{ + g_return_val_if_fail (m != NULL, NULL); + + if (!name) + return NULL; + + for (; m->name != NULL; m++) { + if (strcmp (m->name, name) == 0) + return m; + } + return NULL; +} + /** Returns GstVaapiProfile from H.264 profile_idc value */ GstVaapiProfile gst_vaapi_utils_h264_get_profile (guint8 profile_idc) @@ -146,6 +224,25 @@ gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile) return profile_idc; } +/** Returns GstVaapiProfile from a string representation */ +GstVaapiProfile +gst_vaapi_utils_h264_get_profile_from_string (const gchar * str) +{ + const struct map *const m = map_lookup_name (gst_vaapi_h264_profile_map, str); + + return m ? (GstVaapiProfile) m->value : GST_VAAPI_PROFILE_UNKNOWN; +} + +/** Returns a string representation for the supplied H.264 profile */ +const gchar * +gst_vaapi_utils_h264_get_profile_string (GstVaapiProfile profile) +{ + const struct map *const m = + map_lookup_value (gst_vaapi_h264_profile_map, profile); + + return m ? m->name : NULL; +} + /** Returns GstVaapiLevelH264 from H.264 level_idc value */ GstVaapiLevelH264 gst_vaapi_utils_h264_get_level (guint8 level_idc) @@ -174,6 +271,51 @@ gst_vaapi_utils_h264_get_level_idc (GstVaapiLevelH264 level) return llp ? llp->level_idc : 0; } +/** Returns GstVaapiLevelH264 from a string representation */ +GstVaapiLevelH264 +gst_vaapi_utils_h264_get_level_from_string (const gchar * str) +{ + gint v, level_idc = 0; + + if (!str || !str[0]) + goto not_found; + + v = g_ascii_digit_value (str[0]); + if (v < 0) + goto not_found; + level_idc = v * 10; + + switch (str[1]) { + case '\0': + break; + case '.': + v = g_ascii_digit_value (str[2]); + if (v < 0 || str[3] != '\0') + goto not_found; + level_idc += v; + break; + case 'b': + if (level_idc == 10 && str[2] == '\0') + return GST_VAAPI_LEVEL_H264_L1b; + // fall-trough + default: + goto not_found; + } + return gst_vaapi_utils_h264_get_level (level_idc); + +not_found: + return (GstVaapiLevelH264) 0; +} + +/** Returns a string representation for the supplied H.264 level */ +const gchar * +gst_vaapi_utils_h264_get_level_string (GstVaapiLevelH264 level) +{ + if (level < GST_VAAPI_LEVEL_H264_L1 || level > GST_VAAPI_LEVEL_H264_L5_2) + return NULL; + return gst_vaapi_h264_level_map[level - GST_VAAPI_LEVEL_H264_L1].name; +} + /** Returns level limits as specified in Table A-1 of the H.264 standard */ const GstVaapiH264LevelLimits * gst_vaapi_utils_h264_get_level_limits (GstVaapiLevelH264 level) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.h b/gst-libs/gst/vaapi/gstvaapiutils_h264.h index 2aee036214..400fc5c38b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.h @@ -71,6 +71,22 @@ typedef enum GST_VAAPI_LEVEL_H264_L5_2, } GstVaapiLevelH264; +/* Returns GstVaapiProfile from a string representation */ +GstVaapiProfile +gst_vaapi_utils_h264_get_profile_from_string (const gchar * str); + +/* Returns a string representation for the supplied H.264 profile */ +const gchar * +gst_vaapi_utils_h264_get_profile_string (GstVaapiProfile profile); + +/* Returns GstVaapiLevelH264 from a string representation */ +GstVaapiLevelH264 +gst_vaapi_utils_h264_get_level_from_string (const gchar * str); + +/* Returns a string representation for the supplied H.264 level */ +const gchar * +gst_vaapi_utils_h264_get_level_string (GstVaapiLevelH264 level); + G_END_DECLS #endif /* GST_VAAPI_UTILS_H264_H */ From 4a650e8e624a87c5808462d34d18f741eea1a5f9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 10 Jan 2014 19:49:52 +0100 Subject: [PATCH 1491/3781] utils: h264: don't use fatal asserts. Replace g_assert() with a g_debug() so that to not make the program abort when an unsupported value is supplied. --- gst-libs/gst/vaapi/gstvaapiutils_h264.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index 20cc474463..8c39437478 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -168,7 +168,7 @@ gst_vaapi_utils_h264_get_profile (guint8 profile_idc) profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH; break; default: - g_assert (0 && "unsupported profile_idc value"); + g_debug ("unsupported profile_idc value"); profile = GST_VAAPI_PROFILE_UNKNOWN; break; } @@ -217,7 +217,7 @@ gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile) profile_idc = GST_H264_PROFILE_STEREO_HIGH; break; default: - g_assert (0 && "unsupported GstVaapiProfile value"); + g_debug ("unsupported GstVaapiProfile value"); profile_idc = 0; break; } @@ -257,7 +257,7 @@ gst_vaapi_utils_h264_get_level (guint8 level_idc) if (llp->level_idc == level_idc) return llp->level; } - g_assert (0 && "unsupported level_idc value"); + g_debug ("unsupported level_idc value"); return (GstVaapiLevelH264) 0; } @@ -354,7 +354,7 @@ gst_vaapi_utils_h264_get_chroma_type (guint chroma_format_idc) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; break; default: - g_assert (0 && "unsupported chroma_format_idc value"); + g_debug ("unsupported chroma_format_idc value"); chroma_type = (GstVaapiChromaType) 0; break; } @@ -381,7 +381,7 @@ gst_vaapi_utils_h264_get_chroma_format_idc (GstVaapiChromaType chroma_type) chroma_format_idc = 3; break; default: - g_assert (0 && "unsupported GstVaapiChromaType value"); + g_debug ("unsupported GstVaapiChromaType value"); chroma_format_idc = 1; break; } From 9548e32cf4cce81e129d208eeff2b31eb023b6cd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 13 Jan 2014 16:20:06 +0100 Subject: [PATCH 1492/3781] utils: add new MPEG-2 helper functions. Add various helper functions to convert profile, level, chroma formats from gstreamer-vaapi world and the MPEG-2 specification world. --- gst-libs/gst/vaapi/Makefile.am | 3 + gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c | 284 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h | 71 +++++ gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h | 97 ++++++ 4 files changed, 455 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f429c07309..5fccc9316e 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -70,6 +70,7 @@ libgstvaapi_source_c = \ gstvaapisurfaceproxy.c \ gstvaapiutils.c \ gstvaapiutils_h264.c \ + gstvaapiutils_mpeg2.c \ gstvaapivalue.c \ gstvaapivideopool.c \ gstvaapiwindow.c \ @@ -95,6 +96,7 @@ libgstvaapi_source_h = \ gstvaapisurfaceproxy.h \ gstvaapitypes.h \ gstvaapiutils_h264.h \ + gstvaapiutils_mpeg2.h \ gstvaapivalue.h \ gstvaapivideopool.h \ gstvaapiwindow.h \ @@ -123,6 +125,7 @@ libgstvaapi_source_priv_h = \ gstvaapisurfaceproxy_priv.h \ gstvaapiutils.h \ gstvaapiutils_h264_priv.h \ + gstvaapiutils_mpeg2_priv.h \ gstvaapiversion.h \ gstvaapivideopool_priv.h \ gstvaapiwindow_priv.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c new file mode 100644 index 0000000000..35003ce38a --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c @@ -0,0 +1,284 @@ +/* + * gstvaapiutils_mpeg2.c - MPEG-2 related utilities + * + * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 +#include "gstvaapiutils_mpeg2_priv.h" + +struct map +{ + guint value; + const gchar *name; +}; + +/* Profile string map */ +static const struct map gst_vaapi_mpeg2_profile_map[] = { +/* *INDENT-OFF* */ + { GST_VAAPI_PROFILE_MPEG2_SIMPLE, "simple" }, + { GST_VAAPI_PROFILE_MPEG2_MAIN, "main" }, + { GST_VAAPI_PROFILE_MPEG2_HIGH, "high" }, + { 0, NULL } +/* *INDENT-ON* */ +}; + +/* Level string map */ +static const struct map gst_vaapi_mpeg2_level_map[] = { +/* *INDENT-OFF* */ + { GST_VAAPI_LEVEL_MPEG2_LOW, "low" }, + { GST_VAAPI_LEVEL_MPEG2_MAIN, "main" }, + { GST_VAAPI_LEVEL_MPEG2_HIGH_1440, "high-1440" }, + { GST_VAAPI_LEVEL_MPEG2_HIGH, "high" }, + { 0, NULL } +/* *INDENT-ON* */ +}; + +/* Table 8-10 to 8-13 (up to Main profile only) */ +/* *INDENT-OFF* */ +static const GstVaapiMPEG2LevelLimits gst_vaapi_mpeg2_level_limits[] = { + /* level h_size v_size fps samples kbps vbv_size */ + { GST_VAAPI_LEVEL_MPEG2_LOW, + 0x0a, 352, 288, 30, 3041280, 4000, 475136 }, + { GST_VAAPI_LEVEL_MPEG2_MAIN, + 0x08, 720, 576, 30, 1036800, 15000, 1835008 }, + { GST_VAAPI_LEVEL_MPEG2_HIGH_1440, + 0x06, 1440, 1152, 60, 47001600, 60000, 7340032 }, + { GST_VAAPI_LEVEL_MPEG2_HIGH, + 0x04, 1920, 1152, 60, 62668800, 80000, 9781248 }, + { 0, } +}; +/* *INDENT-ON* */ + +/* Lookup value in map */ +static const struct map * +map_lookup_value (const struct map *m, guint value) +{ + g_return_val_if_fail (m != NULL, NULL); + + for (; m->name != NULL; m++) { + if (m->value == value) + return m; + } + return NULL; +} + +/* Lookup name in map */ +static const struct map * +map_lookup_name (const struct map *m, const gchar * name) +{ + g_return_val_if_fail (m != NULL, NULL); + + if (!name) + return NULL; + + for (; m->name != NULL; m++) { + if (strcmp (m->name, name) == 0) + return m; + } + return NULL; +} + +/** Returns a relative score for the supplied GstVaapiProfile */ +guint +gst_vaapi_utils_mpeg2_get_profile_score (GstVaapiProfile profile) +{ + const struct map *const m = + map_lookup_value (gst_vaapi_mpeg2_profile_map, profile); + + return m ? 1 + (m - gst_vaapi_mpeg2_profile_map) : 0; +} + +/** Returns GstVaapiProfile from MPEG-2 profile_idc value */ +GstVaapiProfile +gst_vaapi_utils_mpeg2_get_profile (guint8 profile_idc) +{ + GstVaapiProfile profile; + + switch (profile_idc) { + case GST_MPEG_VIDEO_PROFILE_SIMPLE: + profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; + break; + case GST_MPEG_VIDEO_PROFILE_MAIN: + profile = GST_VAAPI_PROFILE_MPEG2_MAIN; + break; + case GST_MPEG_VIDEO_PROFILE_HIGH: + profile = GST_VAAPI_PROFILE_MPEG2_HIGH; + break; + default: + g_debug ("unsupported profile_idc value"); + profile = GST_VAAPI_PROFILE_UNKNOWN; + break; + } + return profile; +} + +/** Returns MPEG-2 profile_idc value from GstVaapiProfile */ +guint8 +gst_vaapi_utils_mpeg2_get_profile_idc (GstVaapiProfile profile) +{ + guint8 profile_idc; + + switch (profile) { + case GST_VAAPI_PROFILE_MPEG2_SIMPLE: + profile_idc = GST_MPEG_VIDEO_PROFILE_SIMPLE; + break; + case GST_VAAPI_PROFILE_MPEG2_MAIN: + profile_idc = GST_MPEG_VIDEO_PROFILE_MAIN; + break; + case GST_VAAPI_PROFILE_MPEG2_HIGH: + profile_idc = GST_MPEG_VIDEO_PROFILE_HIGH; + break; + default: + g_debug ("unsupported GstVaapiProfile value"); + profile_idc = 0; + break; + } + return profile_idc; +} + +/** Returns GstVaapiProfile from a string representation */ +GstVaapiProfile +gst_vaapi_utils_mpeg2_get_profile_from_string (const gchar * str) +{ + const struct map *const m = + map_lookup_name (gst_vaapi_mpeg2_profile_map, str); + + return m ? (GstVaapiProfile) m->value : GST_VAAPI_PROFILE_UNKNOWN; +} + +/** Returns a string representation for the supplied MPEG-2 profile */ +const gchar * +gst_vaapi_utils_mpeg2_get_profile_string (GstVaapiProfile profile) +{ + const struct map *const m = + map_lookup_value (gst_vaapi_mpeg2_profile_map, profile); + + return m ? m->name : NULL; +} + +/** Returns GstVaapiLevelMPEG2 from MPEG-2 level_idc value */ +GstVaapiLevelMPEG2 +gst_vaapi_utils_mpeg2_get_level (guint8 level_idc) +{ + const GstVaapiMPEG2LevelLimits *llp; + + for (llp = gst_vaapi_mpeg2_level_limits; llp->level != 0; llp++) { + if (llp->level_idc == level_idc) + return llp->level; + } + g_debug ("unsupported level_idc value"); + return (GstVaapiLevelMPEG2) 0; +} + +/** Returns MPEG-2 level_idc value from GstVaapiLevelMPEG2 */ +guint8 +gst_vaapi_utils_mpeg2_get_level_idc (GstVaapiLevelMPEG2 level) +{ + const GstVaapiMPEG2LevelLimits *const llp = + gst_vaapi_utils_mpeg2_get_level_limits (level); + + return llp ? llp->level_idc : 0; +} + +/** Returns GstVaapiLevelMPEG2 from a string representation */ +GstVaapiLevelMPEG2 +gst_vaapi_utils_mpeg2_get_level_from_string (const gchar * str) +{ + const struct map *const m = map_lookup_name (gst_vaapi_mpeg2_level_map, str); + + return (GstVaapiLevelMPEG2) (m ? m->value : 0); +} + +/** Returns a string representation for the supplied MPEG-2 level */ +const gchar * +gst_vaapi_utils_mpeg2_get_level_string (GstVaapiLevelMPEG2 level) +{ + if (level < GST_VAAPI_LEVEL_MPEG2_LOW || level > GST_VAAPI_LEVEL_MPEG2_HIGH) + return NULL; + return gst_vaapi_mpeg2_level_map[level - GST_VAAPI_LEVEL_MPEG2_LOW].name; +} + +/** Returns level limits as specified in Tables 8-10 to 8-13 of the + MPEG-2 standard */ +const GstVaapiMPEG2LevelLimits * +gst_vaapi_utils_mpeg2_get_level_limits (GstVaapiLevelMPEG2 level) +{ + if (level < GST_VAAPI_LEVEL_MPEG2_LOW || level > GST_VAAPI_LEVEL_MPEG2_HIGH) + return NULL; + return &gst_vaapi_mpeg2_level_limits[level - GST_VAAPI_LEVEL_MPEG2_LOW]; +} + +/** Returns Tables 8-10 to 8-13 from the specification (up to High profile) */ +const GstVaapiMPEG2LevelLimits * +gst_vaapi_utils_mpeg2_get_level_limits_table (guint * out_length_ptr) +{ + if (out_length_ptr) + *out_length_ptr = G_N_ELEMENTS (gst_vaapi_mpeg2_level_limits) - 1; + return gst_vaapi_mpeg2_level_limits; +} + +/** Returns GstVaapiChromaType from MPEG-2 chroma_format_idc value */ +GstVaapiChromaType +gst_vaapi_utils_mpeg2_get_chroma_type (guint chroma_format_idc) +{ + GstVaapiChromaType chroma_type; + + switch (chroma_format_idc) { + case GST_MPEG_VIDEO_CHROMA_420: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + break; + case GST_MPEG_VIDEO_CHROMA_422: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; + break; + case GST_MPEG_VIDEO_CHROMA_444: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; + break; + default: + g_debug ("unsupported chroma_format_idc value"); + chroma_type = (GstVaapiChromaType) 0; + break; + } + return chroma_type; +} + +/** Returns MPEG-2 chroma_format_idc value from GstVaapiChromaType */ +guint +gst_vaapi_utils_mpeg2_get_chroma_format_idc (GstVaapiChromaType chroma_type) +{ + guint chroma_format_idc; + + switch (chroma_type) { + case GST_VAAPI_CHROMA_TYPE_YUV420: + chroma_format_idc = GST_MPEG_VIDEO_CHROMA_420; + break; + case GST_VAAPI_CHROMA_TYPE_YUV422: + chroma_format_idc = GST_MPEG_VIDEO_CHROMA_422; + break; + case GST_VAAPI_CHROMA_TYPE_YUV444: + chroma_format_idc = GST_MPEG_VIDEO_CHROMA_444; + break; + default: + g_debug ("unsupported GstVaapiChromaType value"); + chroma_format_idc = 1; + break; + } + return chroma_format_idc; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h new file mode 100644 index 0000000000..8a3d8974b9 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h @@ -0,0 +1,71 @@ +/* + * gstvaapiutils_mpeg2.h - MPEG-2 related utilities + * + * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_UTILS_MPEG2_H +#define GST_VAAPI_UTILS_MPEG2_H + +#include +#include +#include + +G_BEGIN_DECLS + +/** + * GstVaapiLevelMPEG2: + * @GST_VAAPI_LEVEL_MPEG2_LOW: Low level. + * @GST_VAAPI_LEVEL_MPEG2_MAIN: Main level. + * @GST_VAAPI_LEVEL_MPEG2_HIGH_1440: High-1440 level. + * @GST_VAAPI_LEVEL_MPEG2_HIGH: High level. + * + * The set of all levels for #GstVaapiLevelMPEG2. + */ +typedef enum +{ + GST_VAAPI_LEVEL_MPEG2_LOW = 1, + GST_VAAPI_LEVEL_MPEG2_MAIN, + GST_VAAPI_LEVEL_MPEG2_HIGH_1440, + GST_VAAPI_LEVEL_MPEG2_HIGH, +} GstVaapiLevelMPEG2; + +/* Returns a relative score for the supplied GstVaapiProfile */ +guint +gst_vaapi_utils_mpeg2_get_profile_score (GstVaapiProfile profile); + +/* Returns GstVaapiProfile from a string representation */ +GstVaapiProfile +gst_vaapi_utils_mpeg2_get_profile_from_string (const gchar * str); + +/* Returns a string representation for the supplied MPEG-2 profile */ +const gchar * +gst_vaapi_utils_mpeg2_get_profile_string (GstVaapiProfile profile); + +/* Returns GstVaapiLevelMPEG2 from a string representation */ +GstVaapiLevelMPEG2 +gst_vaapi_utils_mpeg2_get_level_from_string (const gchar * str); + +/* Returns a string representation for the supplied MPEG-2 level */ +const gchar * +gst_vaapi_utils_mpeg2_get_level_string (GstVaapiLevelMPEG2 level); + +G_END_DECLS + +#endif /* GST_VAAPI_UTILS_MPEG2_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h new file mode 100644 index 0000000000..d29d2cbd89 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h @@ -0,0 +1,97 @@ +/* + * gstvaapiutils_mpeg2_priv.h - MPEG-2 related utilities + * + * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_UTILS_MPEG2_PRIV_H +#define GST_VAAPI_UTILS_MPEG2_PRIV_H + +#include "gstvaapiutils_mpeg2.h" + +G_BEGIN_DECLS + +/** + * GstVaapiMPEG2LevelLimits: + * @level: the #GstVaapiLevelMPEG2 + * @level_idc: the MPEG-2 level indication value + * @horizontal_size_value: the maximum number of samples per line + * @vertical_size_value: the maximum number of lines per frame + * @frame_rate_value: the maximum number of frames per second + * @sample_rate: the maximum number of samples per second (for luminance) + * @bit_rate: the maximum bit rate (kbps) + * @vbv_buffer_size: the VBV buffer size requirements (bits) + * + * The data structure that describes the limits of an MPEG-2 level. + */ +typedef struct +{ + GstVaapiLevelMPEG2 level; + guint8 level_idc; + guint16 horizontal_size_value; + guint16 vertical_size_value; + guint32 frame_rate_value; + guint32 sample_rate; + guint32 bit_rate; + guint32 vbv_buffer_size; +} GstVaapiMPEG2LevelLimits; + +/* Returns GstVaapiProfile from MPEG-2 profile_idc value */ +G_GNUC_INTERNAL +GstVaapiProfile +gst_vaapi_utils_mpeg2_get_profile (guint8 profile_idc); + +/* Returns MPEG-2 profile_idc value from GstVaapiProfile */ +G_GNUC_INTERNAL +guint8 +gst_vaapi_utils_mpeg2_get_profile_idc (GstVaapiProfile profile); + +/* Returns GstVaapiLevelMPEG2 from MPEG-2 level_idc value */ +G_GNUC_INTERNAL +GstVaapiLevelMPEG2 +gst_vaapi_utils_mpeg2_get_level (guint8 level_idc); + +/* Returns MPEG-2 level_idc value from GstVaapiLevelMPEG2 */ +G_GNUC_INTERNAL +guint8 +gst_vaapi_utils_mpeg2_get_level_idc (GstVaapiLevelMPEG2 level); + +/* Returns level limits as specified in Table A-1 of the MPEG-2 standard */ +G_GNUC_INTERNAL +const GstVaapiMPEG2LevelLimits * +gst_vaapi_utils_mpeg2_get_level_limits (GstVaapiLevelMPEG2 level); + +/* Returns the Table A-1 specification */ +G_GNUC_INTERNAL +const GstVaapiMPEG2LevelLimits * +gst_vaapi_utils_mpeg2_get_level_limits_table (guint * out_length_ptr); + +/* Returns GstVaapiChromaType from MPEG-2 chroma_format_idc value */ +G_GNUC_INTERNAL +GstVaapiChromaType +gst_vaapi_utils_mpeg2_get_chroma_type (guint chroma_format_idc); + +/* Returns MPEG-2 chroma_format_idc value from GstVaapiChromaType */ +G_GNUC_INTERNAL +guint +gst_vaapi_utils_mpeg2_get_chroma_format_idc (GstVaapiChromaType chroma_type); + +G_END_DECLS + +#endif /* GST_VAAPI_UTILS_MPEG2_PRIV_H */ From 01af353116bc3273222de5243d2ab2af8776f5be Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 3 Jan 2014 16:57:09 +0100 Subject: [PATCH 1493/3781] encoder: fix indentation. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiencoder.h | 6 ++++-- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 1 + .../gst/vaapi/gstvaapiencoder_h264_priv.h | 1 - gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 20 +++++++++++-------- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 3 ++- gst/vaapi/gstvaapiencode.h | 1 - 9 files changed, 26 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index e0be314185..a9cd85d86e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -86,7 +86,7 @@ static GstVaapiCodedBufferProxy * gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder) { GstVaapiCodedBufferPool *const pool = - GST_VAAPI_CODED_BUFFER_POOL (encoder->codedbuf_pool); + GST_VAAPI_CODED_BUFFER_POOL (encoder->codedbuf_pool); GstVaapiCodedBufferProxy *codedbuf_proxy; g_mutex_lock (&encoder->mutex); @@ -104,7 +104,7 @@ gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder) return NULL; gst_vaapi_coded_buffer_proxy_set_destroy_notify (codedbuf_proxy, - (GDestroyNotify)_coded_buffer_proxy_released_notify, encoder); + (GDestroyNotify) _coded_buffer_proxy_released_notify, encoder); return codedbuf_proxy; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 6b0a7ed27f..d548b5b18e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -36,7 +36,8 @@ typedef struct _GstVaapiEncoder GstVaapiEncoder; * GstVaapiEncoderStatus: * @GST_VAAPI_ENCODER_STATUS_SUCCESS: Success. * @GST_VAAPI_ENCODER_STATUS_ERROR_NO_SURFACE: No surface left to encode. - * @GST_VAAPI_ENCODER_STATUS_ERROR_NO_BUFFER: No coded buffer left to hold the encoded picture. + * @GST_VAAPI_ENCODER_STATUS_ERROR_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_INVALID_PARAMETER: Invalid parameter. @@ -74,7 +75,8 @@ GstVaapiEncoderStatus gst_vaapi_encoder_get_codec_data (GstVaapiEncoder * encoder, GstBuffer ** out_codec_data_ptr); -GstCaps *gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, +GstCaps * +gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, GstVideoCodecState * state, GstCaps * ref_caps); GstVaapiEncoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index cc5dbcc70a..d5bef53c83 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -331,7 +331,6 @@ _set_key_frame (GstVaapiEncPicture * picture, _set_idr_frame (picture, encoder); } else _set_i_frame (picture, encoder); - } gboolean @@ -1153,7 +1152,7 @@ ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) { GstVaapiCodedBuffer *const codedbuf = - GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); + GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); if (!fill_va_picture_param (encoder, picture, codedbuf, surface)) return FALSE; @@ -1593,7 +1592,8 @@ gst_vaapi_encoder_h264_set_context_info (GstVaapiEncoder * base_encoder) const guint DEFAULT_SURFACES_COUNT = 3; /* Maximum sizes for common headers (in bits) */ - enum { + enum + { MAX_SPS_HDR_SIZE = 16473, MAX_VUI_PARAMS_SIZE = 210, MAX_HRD_PARAMS_SIZE = 4103, @@ -1757,7 +1757,7 @@ gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base) } static inline const GstVaapiEncoderClass * -gst_vaapi_encoder_h264_class () +gst_vaapi_encoder_h264_class (void) { static const GstVaapiEncoderClass GstVaapiEncoderH264Class = { GST_VAAPI_ENCODER_CLASS_INIT (H264, h264), diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 2063f4aefe..3eee7c8f82 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -38,4 +38,5 @@ gboolean gst_vaapi_encoder_h264_is_avc (GstVaapiEncoderH264 * encoder); G_END_DECLS + #endif /*GST_VAAPI_ENCODER_H264_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h index 3a60a6fc39..177a528487 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h @@ -104,7 +104,6 @@ struct _GstVaapiEncoderH264 GstBuffer *sps_data; GstBuffer *pps_data; - }; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 62d98eff07..c4b6b20191 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -50,7 +50,7 @@ gst_bit_writer_write_pps (GstBitWriter * bitwriter, static void clear_references (GstVaapiEncoderMpeg2 * encoder); static void push_reference (GstVaapiEncoderMpeg2 * encoder, - GstVaapiSurfaceProxy * ref;); + GstVaapiSurfaceProxy * ref); static struct { @@ -58,6 +58,7 @@ static struct int line_per_frame; int frame_per_sec; } mpeg2_upper_samplings[2][3] = { + /* *INDENT-OFF* */ { { 0, 0, 0}, { 720, 576, 30 }, { 0, 0, 0 }, @@ -66,6 +67,7 @@ static struct { 720, 576, 30 }, { 1920, 1152, 60 }, } + /* *INDENT-ON* */ }; static gboolean @@ -73,6 +75,7 @@ ensure_sampling_desity (GstVaapiEncoderMpeg2 * encoder) { guint p, l; float fps; + p = encoder->profile; l = encoder->level; fps = GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder); @@ -132,6 +135,7 @@ static unsigned char make_profile_and_level_indication (guint32 profile, guint32 level) { guint32 p = 4, l = 8; + switch (profile) { case GST_ENCODER_MPEG2_PROFILE_SIMPLE: p = 5; @@ -256,7 +260,6 @@ fill_picture (GstVaapiEncoderMpeg2 * encoder, pic->f_code[1][1] = 0xf; pic->forward_reference_picture = VA_INVALID_SURFACE; pic->backward_reference_picture = VA_INVALID_SURFACE; - } else if (pic->picture_type == VAEncPictureTypePredictive) { pic->f_code[0][0] = f_code_x; pic->f_code[0][1] = f_code_y; @@ -390,7 +393,7 @@ ensure_picture (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) { GstVaapiCodedBuffer *const codedbuf = - GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); + GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); if (!fill_picture (encoder, picture, codedbuf, surface)) return FALSE; @@ -596,7 +599,6 @@ gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base, picture->type = GST_VAAPI_PICTURE_TYPE_B; status = GST_VAAPI_ENCODER_STATUS_NO_SURFACE; } - } picture->frame_num = encoder->frame_num++; @@ -614,6 +616,7 @@ static GstVaapiProfile to_vaapi_profile (guint32 profile) { GstVaapiProfile p; + switch (profile) { case GST_ENCODER_MPEG2_PROFILE_SIMPLE: p = GST_VAAPI_PROFILE_MPEG2_SIMPLE; @@ -634,7 +637,8 @@ gst_vaapi_encoder_mpeg2_set_context_info (GstVaapiEncoder * base_encoder) GstVaapiContextInfo *const cip = &base_encoder->context_info; /* Maximum sizes for common headers (in bytes) */ - enum { + enum + { MAX_SEQ_HDR_SIZE = 140, MAX_SEQ_EXT_SIZE = 10, MAX_GOP_SIZE = 8, @@ -709,7 +713,6 @@ gst_vaapi_encoder_mpeg2_set_format (GstVaapiEncoder * base, error: gst_caps_unref (result); return NULL; - } static gboolean @@ -776,7 +779,7 @@ gst_vaapi_encoder_mpeg2_finalize (GstVaapiEncoder * base) } static inline const GstVaapiEncoderClass * -gst_vaapi_encoder_mpeg2_class () +gst_vaapi_encoder_mpeg2_class (void) { static const GstVaapiEncoderClass GstVaapiEncoderMpeg2Class = { GST_VAAPI_ENCODER_CLASS_INIT (Mpeg2, mpeg2), @@ -795,6 +798,7 @@ static struct int code; float value; } frame_rate_tab[] = { + /* *INDENT-OFF* */ { 1, 23.976 }, { 2, 24.0 }, { 3, 25.0 }, @@ -803,6 +807,7 @@ static struct { 6, 50 }, { 7, 59.94 }, { 8, 60 } + /* *INDENT-ON* */ }; static int @@ -886,7 +891,6 @@ static gboolean gst_bit_writer_write_pps (GstBitWriter * bitwriter, VAEncPictureParameterBufferMPEG2 * pic) { - gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_PICUTRE, 32); gst_bit_writer_put_bits_uint32 (bitwriter, pic->temporal_reference, 10); gst_bit_writer_put_bits_uint32 (bitwriter, diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index 5f730e36c3..b75bb95da8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -304,7 +304,7 @@ gboolean gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture, const GstVaapiCodecObjectConstructorArgs * args) { - GstVideoCodecFrame *const frame = (GstVideoCodecFrame *)args->data; + GstVideoCodecFrame *const frame = (GstVideoCodecFrame *) args->data; gboolean success; g_return_val_if_fail (frame != NULL, FALSE); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index e570602530..bd17c8f4af 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -75,7 +75,7 @@ typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass; struct _GstVaapiEncoder { - /*< private > */ + /*< private >*/ GstVaapiMiniObject parent_instance; GstVaapiDisplay *display; @@ -98,6 +98,7 @@ struct _GstVaapiEncoder struct _GstVaapiEncoderClass { + /*< private >*/ GstVaapiMiniObjectClass parent_class; gboolean (*init) (GstVaapiEncoder * encoder); diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 401913ffb5..c2beec1995 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -59,7 +59,6 @@ struct _GstVaapiEncode GstPadQueryFunction srcpad_query; GstVaapiEncoder *encoder; - GstVaapiRateControl rate_control; guint32 bitrate; /* kbps */ From 076d75aeb89b2b7cc09a2297f8fa6ebecab6cf68 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 3 Jan 2014 16:57:25 +0100 Subject: [PATCH 1494/3781] vaapiencode: fix indentation. --- gst/vaapi/gstvaapiencode.c | 4 ++-- gst/vaapi/gstvaapiencode_h264.c | 34 +++++++++++++++++-------------- gst/vaapi/gstvaapiencode_mpeg2.c | 35 +++++++++++++++++++------------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 32e01cb0ed..99c4d3c42c 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -43,7 +43,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapiencode_debug); G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode, gst_vaapiencode, GST_TYPE_VIDEO_ENCODER, - GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) + GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES); enum { @@ -479,7 +479,7 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, gst_video_codec_frame_set_user_data (frame, gst_vaapi_surface_proxy_ref (proxy), - (GDestroyNotify)gst_vaapi_surface_proxy_unref); + (GDestroyNotify) gst_vaapi_surface_proxy_unref); GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); status = gst_vaapi_encoder_put_frame (encode->encoder, frame); diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 09d5920f73..6a5d0cb53d 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -37,6 +37,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); #define GST_CAPS_CODEC(CODEC) CODEC "; " +/* *INDENT-OFF* */ static const char gst_vaapiencode_h264_sink_caps_str[] = #if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, @@ -53,24 +54,31 @@ static const char gst_vaapiencode_h264_sink_caps_str[] = "height = (int) [ 1, MAX ], " #endif GST_CAPS_INTERLACED_FALSE; +/* *INDENT-ON* */ +/* *INDENT-OFF* */ static const char gst_vaapiencode_h264_src_caps_str[] = GST_CAPS_CODEC ("video/x-h264"); +/* *INDENT-ON* */ +/* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapiencode_h264_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_h264_sink_caps_str)); + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_h264_sink_caps_str)); +/* *INDENT-ON* */ +/* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapiencode_h264_src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_h264_src_caps_str)); + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_h264_src_caps_str)); +/* *INDENT-ON* */ /* h264 encode */ -G_DEFINE_TYPE (GstVaapiEncodeH264, gst_vaapiencode_h264, GST_TYPE_VAAPIENCODE) +G_DEFINE_TYPE (GstVaapiEncodeH264, gst_vaapiencode_h264, GST_TYPE_VAAPIENCODE); enum { @@ -323,13 +331,11 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) /* sink pad */ gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_h264_sink_factory) - ); + gst_static_pad_template_get (&gst_vaapiencode_h264_sink_factory)); /* src pad */ gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_h264_src_factory) - ); + gst_static_pad_template_get (&gst_vaapiencode_h264_src_factory)); g_object_class_install_property (object_class, PROP_KEY_PERIOD, @@ -344,8 +350,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", - 0, 10, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + 0, 10, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_INIT_QP, @@ -368,6 +373,5 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) g_param_spec_uint ("num-slices", "Number of Slices", "Number of slices per frame", - 1, 200, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 3a437cb287..c6b646d3c6 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -37,9 +37,10 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); #define GST_CAPS_CODEC(CODEC) CODEC "; " +/* *INDENT-OFF* */ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = #if GST_CHECK_VERSION(1,1,0) - GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ", " #else GST_VAAPI_SURFACE_CAPS ", " @@ -53,25 +54,33 @@ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = "height = (int) [ 1, MAX ], " #endif GST_CAPS_INTERLACED_FALSE; +/* *INDENT-ON* */ +/* *INDENT-OFF* */ static const char gst_vaapiencode_mpeg2_src_caps_str[] = - GST_CAPS_CODEC ("video/mpeg," - "mpegversion = (int) 2, " "systemstream = (boolean) false"); + GST_CAPS_CODEC ("video/mpeg, mpegversion = (int) 2, " + "systemstream = (boolean) false"); +/* *INDENT-ON* */ +/* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapiencode_mpeg2_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_mpeg2_sink_caps_str)); + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_mpeg2_sink_caps_str)); +/* *INDENT-ON* */ +/* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapiencode_mpeg2_src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_mpeg2_src_caps_str)); + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_mpeg2_src_caps_str)); +/* *INDENT-ON* */ /* mpeg2 encode */ -G_DEFINE_TYPE (GstVaapiEncodeMpeg2, gst_vaapiencode_mpeg2, GST_TYPE_VAAPIENCODE) +G_DEFINE_TYPE (GstVaapiEncodeMpeg2, gst_vaapiencode_mpeg2, + GST_TYPE_VAAPIENCODE); enum { @@ -199,13 +208,11 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) /* sink pad */ gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_mpeg2_sink_factory) - ); + gst_static_pad_template_get (&gst_vaapiencode_mpeg2_sink_factory)); /* src pad */ gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_mpeg2_src_factory) - ); + gst_static_pad_template_get (&gst_vaapiencode_mpeg2_src_factory)); g_object_class_install_property (object_class, PROP_QUANTIZER, From a24c52e4d0b3d0c168b30939aae406879c6c6a94 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 6 Jan 2014 15:10:36 +0100 Subject: [PATCH 1495/3781] encoder: add rate control API. Add gst_vaapi_encoder_set_rate_control() interface to request a new rate control mode for encoding. Changing the rate control mode is only valid prior to encoding the very first frame. Afterwards, an error ("operation-failed") is issued. https://bugzilla.gnome.org/show_bug.cgi?id=719529 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 103 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 11 ++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 15 +++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 12 ++ .../gst/vaapi/gstvaapiencoder_mpeg2_priv.h | 1 - gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 35 +++++- gst-libs/gst/vaapi/gstvaapitypes.h | 4 + gst/vaapi/gstvaapiencode.c | 26 ++--- gst/vaapi/gstvaapiencode.h | 2 - gst/vaapi/gstvaapiencode_h264.c | 1 - gst/vaapi/gstvaapiencode_mpeg2.c | 14 --- 11 files changed, 186 insertions(+), 38 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index a9cd85d86e..05f9b3d2b5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -25,6 +25,7 @@ #include "gstvaapiencoder_priv.h" #include "gstvaapicontext.h" #include "gstvaapidisplay_priv.h" +#include "gstvaapiutils.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -180,6 +181,7 @@ gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, picture, (GDestroyNotify) gst_vaapi_enc_picture_unref); g_async_queue_push (encoder->codedbuf_queue, codedbuf_proxy); + encoder->num_codedbuf_queued++; /* Try again with any pending reordered frame now available for encoding */ frame = NULL; @@ -388,6 +390,107 @@ error: return NULL; } +/* Determine the supported rate control modes */ +static gboolean +get_rate_control_mask (GstVaapiEncoder * encoder) +{ + const GstVaapiEncoderClassData *const cdata = + GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; + GstVaapiProfile profile; + GArray *profiles; + guint i, rate_control_mask = 0; + + if (encoder->rate_control_mask) + return encoder->rate_control_mask; + + profiles = gst_vaapi_display_get_encode_profiles (encoder->display); + if (!profiles) + goto cleanup; + + // Pick a profile matching the class codec + for (i = 0; i < profiles->len; i++) { + profile = g_array_index (profiles, GstVaapiProfile, i); + if (gst_vaapi_profile_get_codec (profile) == cdata->codec) + break; + } + + if (i != profiles->len) { + VAConfigAttrib attrib; + VAStatus status; + + attrib.type = VAConfigAttribRateControl; + GST_VAAPI_DISPLAY_LOCK (encoder->display); + status = + vaGetConfigAttributes (GST_VAAPI_DISPLAY_VADISPLAY (encoder->display), + gst_vaapi_profile_get_va_profile (profile), VAEntrypointEncSlice, + &attrib, 1); + GST_VAAPI_DISPLAY_UNLOCK (encoder->display); + if (vaapi_check_status (status, "vaGetConfigAttributes()")) { + for (i = 0; i < 32; i++) { + if (!(attrib.value & (1 << i))) + continue; + rate_control_mask |= 1 << to_GstVaapiRateControl (1 << i); + } + } + } + g_array_unref (profiles); + GST_INFO ("supported rate controls: 0x%08x", rate_control_mask); + +cleanup: + encoder->rate_control_mask = cdata->rate_control_mask & rate_control_mask; + return encoder->rate_control_mask; +} + +/** + * gst_vaapi_encoder_set_rate_control: + * @encoder: a #GstVaapiEncoder + * @rate_control: the requested rate control + * + * Notifies the @encoder to use the supplied @rate_control mode. + * + * If the underlying encoder does not support that rate control mode, + * then @GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_RATE_CONTROL is + * returned. + * + * The rate control mode can only be specified before the first frame + * is to be encoded. Afterwards, any change to this parameter is + * invalid and @GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED is + * returned. + * + * Return value: a #GstVaapiEncoderStatus + */ +GstVaapiEncoderStatus +gst_vaapi_encoder_set_rate_control (GstVaapiEncoder * encoder, + GstVaapiRateControl rate_control) +{ + guint32 rate_control_mask; + + g_return_val_if_fail (encoder != NULL, + GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER); + + if (encoder->rate_control != rate_control && encoder->num_codedbuf_queued > 0) + goto error_operation_failed; + + rate_control_mask = get_rate_control_mask (encoder); + if (!(rate_control_mask & (1U << rate_control))) + goto error_unsupported_rate_control; + + encoder->rate_control = rate_control; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +error_operation_failed: + { + GST_ERROR ("could not change rate control mode after encoding started"); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } +error_unsupported_rate_control: + { + GST_ERROR ("unsupported rate control mode (%d)", rate_control); + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_RATE_CONTROL; + } +} + /* Base encoder initialization (internal) */ static gboolean gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index d548b5b18e..033054145b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -40,6 +40,11 @@ typedef struct _GstVaapiEncoder GstVaapiEncoder; * 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_INVALID_PARAMETER: Invalid parameter. * @GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_BUFFER: Invalid buffer. * @GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_SURFACE: Invalid surface. @@ -55,6 +60,8 @@ typedef enum 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_INVALID_PARAMETER = -100, GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_BUFFER = -101, GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_SURFACE = -102, @@ -79,6 +86,10 @@ GstCaps * gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, GstVideoCodecState * state, GstCaps * ref_caps); +GstVaapiEncoderStatus +gst_vaapi_encoder_set_rate_control (GstVaapiEncoder * encoder, + GstVaapiRateControl rate_control); + GstVaapiEncoderStatus gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, GstVideoCodecFrame * frame); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index d5bef53c83..2da7f5d460 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -36,6 +36,17 @@ #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 (NONE) | \ + GST_VAAPI_RATECONTROL_MASK (CQP) | \ + GST_VAAPI_RATECONTROL_MASK (CBR) | \ + GST_VAAPI_RATECONTROL_MASK (VBR) | \ + GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) + #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM 2 @@ -1690,6 +1701,8 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base) { GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base); + base->rate_control = DEFAULT_RATECONTROL; + /* init attributes */ encoder->profile = 0; encoder->level = 0; @@ -1756,6 +1769,8 @@ gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base) } +GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H264); + static inline const GstVaapiEncoderClass * gst_vaapi_encoder_h264_class (void) { diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index c4b6b20191..3c1c34b6a6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -37,6 +37,14 @@ #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 (NONE) | \ + GST_VAAPI_RATECONTROL_MASK (CQP) | \ + GST_VAAPI_RATECONTROL_MASK (CBR)) static gboolean gst_bit_writer_write_sps (GstBitWriter * bitwriter, @@ -720,6 +728,8 @@ gst_vaapi_encoder_mpeg2_init (GstVaapiEncoder * base) { GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); + base->rate_control = DEFAULT_RATECONTROL; + /* re-ordering */ g_queue_init (&encoder->b_frames); encoder->dump_frames = FALSE; @@ -778,6 +788,8 @@ gst_vaapi_encoder_mpeg2_finalize (GstVaapiEncoder * base) g_queue_clear (&encoder->b_frames); } +GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (MPEG2); + static inline const GstVaapiEncoderClass * gst_vaapi_encoder_mpeg2_class (void) { diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h index ff20dbe5a1..71e14041e0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h @@ -48,7 +48,6 @@ typedef enum #define GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE GST_ENCODER_MPEG2_PROFILE_MAIN #define GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL GST_VAAPI_ENCODER_MPEG2_LEVEL_HIGH -#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_RATE_CONTROL GST_VAAPI_RATECONTROL_CQP #define GST_VAAPI_ENCODER_MPEG2_MIN_CQP 2 #define GST_VAAPI_ENCODER_MPEG2_MAX_CQP 62 diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index bd17c8f4af..a3ec6db503 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -61,8 +61,17 @@ G_BEGIN_DECLS #define GST_VAAPI_ENCODER_HEIGHT(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info.height) #define GST_VAAPI_ENCODER_FPS_N(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info.fps_n) #define GST_VAAPI_ENCODER_FPS_D(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info.fps_d) -#define GST_VAAPI_ENCODER_RATE_CONTROL(encoder) \ - (GST_VAAPI_ENCODER_CAST(encoder)->rate_control) + +/** + * 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) #define GST_VAAPI_ENCODER_CHECK_STATUS(exp, err_num, err_reason, ...) \ if (!(exp)) { \ @@ -72,6 +81,7 @@ G_BEGIN_DECLS } typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass; +typedef struct _GstVaapiEncoderClassData GstVaapiEncoderClassData; struct _GstVaapiEncoder { @@ -87,6 +97,7 @@ struct _GstVaapiEncoder VAContextID va_context; GstVideoInfo video_info; GstVaapiRateControl rate_control; + guint32 rate_control_mask; GMutex mutex; GCond surface_free; @@ -94,13 +105,32 @@ struct _GstVaapiEncoder guint codedbuf_size; GstVaapiVideoPool *codedbuf_pool; GAsyncQueue *codedbuf_queue; + guint32 num_codedbuf_queued; }; +struct _GstVaapiEncoderClassData +{ + /*< private >*/ + GstVaapiCodec codec; + + GstVaapiRateControl default_rate_control; + guint32 rate_control_mask; +}; + +#define GST_VAAPI_ENCODER_DEFINE_CLASS_DATA(CODEC) \ + static const GstVaapiEncoderClassData g_class_data = { \ + .codec = G_PASTE (GST_VAAPI_CODEC_, CODEC), \ + .default_rate_control = DEFAULT_RATECONTROL, \ + .rate_control_mask = SUPPORTED_RATECONTROLS, \ + } + struct _GstVaapiEncoderClass { /*< private >*/ GstVaapiMiniObjectClass parent_class; + const GstVaapiEncoderClassData *class_data; + gboolean (*init) (GstVaapiEncoder * encoder); void (*finalize) (GstVaapiEncoder * encoder); @@ -135,6 +165,7 @@ struct _GstVaapiEncoderClass #define GST_VAAPI_ENCODER_CLASS_INIT(CODEC, codec) \ GST_VAAPI_ENCODER_CLASS_INIT_BASE (CODEC), \ + .class_data = &g_class_data, \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, init), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, finalize), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, set_format), \ diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 771ad75da8..159b85b31b 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -144,6 +144,10 @@ typedef enum { GST_VAAPI_RATECONTROL_VBR_CONSTRAINED, } GstVaapiRateControl; +/* Define a mask for GstVaapiRateControl */ +#define GST_VAAPI_RATECONTROL_MASK(RC) \ + (1 << G_PASTE(GST_VAAPI_RATECONTROL_,RC)) + G_END_DECLS #endif /* GST_VAAPI_TYPES_H */ diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 99c4d3c42c..64840a5381 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -302,6 +302,7 @@ static gboolean ensure_encoder (GstVaapiEncode * encode) { GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode); + GstVaapiEncoderStatus status; g_return_val_if_fail (klass->create_encoder, FALSE); @@ -312,6 +313,11 @@ ensure_encoder (GstVaapiEncode * encode) GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); if (!encode->encoder) return FALSE; + + status = gst_vaapi_encoder_set_rate_control (encode->encoder, + encode->rate_control); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return FALSE; return TRUE; } @@ -552,15 +558,6 @@ gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query) } #endif -static inline gboolean -check_ratecontrol (GstVaapiEncode * encode, GstVaapiRateControl rate_control) -{ - GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (encode); - - return !klass->check_ratecontrol || klass->check_ratecontrol (encode, - rate_control); -} - static void gst_vaapiencode_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -569,15 +566,8 @@ gst_vaapiencode_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_RATE_CONTROL: - { - GstVaapiRateControl rate_control = g_value_get_enum (value); - if (check_ratecontrol (encode, rate_control)) { - encode->rate_control = rate_control; - } else { - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + encode->rate_control = g_value_get_enum (value); break; - } case PROP_BITRATE: encode->bitrate = g_value_get_uint (value); break; @@ -677,7 +667,7 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) "Rate Control", "Rate control mode", GST_VAAPI_TYPE_RATE_CONTROL, - GST_VAAPI_RATECONTROL_NONE, + GST_VAAPI_RATECONTROL_CQP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index c2beec1995..e930cbe116 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -70,8 +70,6 @@ struct _GstVaapiEncodeClass /*< private >*/ GstVaapiPluginBaseClass parent_class; - gboolean (*check_ratecontrol) (GstVaapiEncode * encode, - GstVaapiRateControl rate_control); GstVaapiEncoder * (*create_encoder) (GstVaapiEncode * encode, GstVaapiDisplay * display); GstFlowReturn (*allocate_buffer) (GstVaapiEncode * encode, diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 6a5d0cb53d..445437dcd4 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -173,7 +173,6 @@ gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base, encoder->profile = GST_VAAPI_PROFILE_UNKNOWN; encoder->level = GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL; - GST_VAAPI_ENCODER_RATE_CONTROL (encoder) = base_encode->rate_control; encoder->bitrate = base_encode->bitrate; encoder->intra_period = encode->intra_period; encoder->init_qp = encode->init_qp; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index c6b646d3c6..4182910360 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -93,9 +93,6 @@ enum static void gst_vaapiencode_mpeg2_init (GstVaapiEncodeMpeg2 * encode) { - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (encode); - - base_encode->rate_control = GST_VAAPI_ENCODER_MPEG2_DEFAULT_RATE_CONTROL; encode->quantizer = GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP; encode->intra_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE; encode->ip_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES; @@ -167,7 +164,6 @@ gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, encoder->profile = GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE; encoder->level = GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL; - GST_VAAPI_ENCODER_RATE_CONTROL (encoder) = base_encode->rate_control; encoder->bitrate = base_encode->bitrate; encoder->cqp = encode->quantizer; encoder->intra_period = encode->intra_period; @@ -175,15 +171,6 @@ gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, return base_encoder; } -static gboolean -gst_vaapiencode_mpeg2_check_ratecontrol (GstVaapiEncode * encode, - GstVaapiRateControl rate_control) -{ - /* XXX: get information from GstVaapiEncoder object */ - return rate_control == GST_VAAPI_RATECONTROL_CQP || - rate_control == GST_VAAPI_RATECONTROL_CBR; -} - static void gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) { @@ -199,7 +186,6 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) object_class->get_property = gst_vaapiencode_mpeg2_get_property; encode_class->create_encoder = gst_vaapiencode_mpeg2_create_encoder; - encode_class->check_ratecontrol = gst_vaapiencode_mpeg2_check_ratecontrol; gst_element_class_set_static_metadata (element_class, "VA-API MPEG-2 encoder", From 70b3600f115d737df876c6fab36319759b070000 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 6 Jan 2014 18:01:33 +0100 Subject: [PATCH 1496/3781] encoder: add bitrate API. Add gst_vaapi_encoder_set_bitrate() interface to allow the user control the bitrate for encoding. Currently, changing this parameter is only valid before the first frame is encoded. Should the value be modified afterwards, then GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED is returned. https://bugzilla.gnome.org/show_bug.cgi?id=719529 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 33 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 3 ++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 28 ++++++++-------- .../gst/vaapi/gstvaapiencoder_h264_priv.h | 1 - gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 24 ++++++++------ .../gst/vaapi/gstvaapiencoder_mpeg2_priv.h | 1 - gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 1 + gst/vaapi/gstvaapiencode.c | 4 +++ gst/vaapi/gstvaapiencode_h264.c | 2 -- gst/vaapi/gstvaapiencode_mpeg2.c | 2 -- 10 files changed, 70 insertions(+), 29 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 05f9b3d2b5..fc00261c83 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -491,6 +491,39 @@ error_unsupported_rate_control: } } +/** + * gst_vaapi_encoder_set_bitrate: + * @encoder: a #GstVaapiEncoder + * @bitrate: the requested bitrate (in kbps) + * + * Notifies the @encoder to use the supplied @bitrate value. + * + * Note: currently, the bitrate can only be specified before the first + * frame is encoded. Afterwards, any change to this parameter is + * invalid and @GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED is + * returned. + * + * Return value: a #GstVaapiEncoderStatus + */ +GstVaapiEncoderStatus +gst_vaapi_encoder_set_bitrate (GstVaapiEncoder * encoder, guint bitrate) +{ + g_return_val_if_fail (encoder != NULL, 0); + + if (encoder->bitrate != bitrate && encoder->num_codedbuf_queued > 0) + goto error_operation_failed; + + encoder->bitrate = bitrate; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +error_operation_failed: + { + GST_ERROR ("could not change bitrate value after encoding started"); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } +} + /* Base encoder initialization (internal) */ static gboolean gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 033054145b..2fc3e74a44 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -90,6 +90,9 @@ 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_put_frame (GstVaapiEncoder * encoder, GstVideoCodecFrame * frame); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 2da7f5d460..121c0d3a56 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -852,6 +852,7 @@ static gboolean fill_va_sequence_param (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); VAEncSequenceParameterBufferH264 *seq = sequence->param; guint width_in_mbs, height_in_mbs; @@ -863,8 +864,8 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder, seq->level_idc = encoder->level; seq->intra_period = encoder->intra_period; seq->ip_period = 0; // ? - if (encoder->bitrate > 0) - seq->bits_per_second = encoder->bitrate * 1024; + if (base_encoder->bitrate > 0) + seq->bits_per_second = base_encoder->bitrate * 1024; else seq->bits_per_second = 0; @@ -912,12 +913,12 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder, } /*vui not set */ - seq->vui_parameters_present_flag = (encoder->bitrate > 0 ? TRUE : FALSE); + seq->vui_parameters_present_flag = (base_encoder->bitrate > 0 ? TRUE : FALSE); if (seq->vui_parameters_present_flag) { seq->vui_fields.bits.aspect_ratio_info_present_flag = FALSE; seq->vui_fields.bits.bitstream_restriction_flag = FALSE; seq->vui_fields.bits.timing_info_present_flag = - (encoder->bitrate > 0 ? TRUE : FALSE); + (base_encoder->bitrate > 0 ? TRUE : FALSE); if (seq->vui_fields.bits.timing_info_present_flag) { seq->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder); seq->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2; @@ -1209,6 +1210,7 @@ ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) static gboolean ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncMiscParam *misc = NULL; VAEncMiscParameterHRD *hrd; VAEncMiscParameterRateControl *rate_control; @@ -1220,9 +1222,9 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) return FALSE; gst_vaapi_enc_picture_add_misc_buffer (picture, misc); hrd = misc->impl; - if (encoder->bitrate > 0) { - hrd->initial_buffer_fullness = encoder->bitrate * 1024 * 4; - hrd->buffer_size = encoder->bitrate * 1024 * 8; + if (base_encoder->bitrate > 0) { + hrd->initial_buffer_fullness = base_encoder->bitrate * 1024 * 4; + hrd->buffer_size = base_encoder->bitrate * 1024 * 8; } else { hrd->initial_buffer_fullness = 0; hrd->buffer_size = 0; @@ -1239,8 +1241,8 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) gst_vaapi_enc_picture_add_misc_buffer (picture, misc); rate_control = misc->impl; memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); - if (encoder->bitrate) - rate_control->bits_per_second = encoder->bitrate * 1024; + if (base_encoder->bitrate) + rate_control->bits_per_second = base_encoder->bitrate * 1024; else rate_control->bits_per_second = 0; rate_control->target_percentage = 70; @@ -1257,6 +1259,7 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) gboolean init_encoder_public_attributes (GstVaapiEncoderH264 * encoder) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); guint width_mbs, height_mbs, total_mbs; if (!GST_VAAPI_ENCODER_WIDTH (encoder) || @@ -1298,13 +1301,13 @@ init_encoder_public_attributes (GstVaapiEncoderH264 * encoder) GST_VAAPI_RATECONTROL_VBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) || GST_VAAPI_RATECONTROL_VBR_CONSTRAINED == GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { - if (!encoder->bitrate) - encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * + if (!base_encoder->bitrate) + base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * GST_VAAPI_ENCODER_HEIGHT (encoder) * GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024; } else - encoder->bitrate = 0; + base_encoder->bitrate = 0; if (!encoder->slice_num) encoder->slice_num = GST_VAAPI_ENCODER_H264_DEFAULT_SLICE_NUM; @@ -1706,7 +1709,6 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base) /* init attributes */ encoder->profile = 0; encoder->level = 0; - encoder->bitrate = 0; encoder->idr_period = 0; encoder->intra_period = 0; encoder->init_qp = -1; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h index 177a528487..fd4cd292b2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h @@ -70,7 +70,6 @@ struct _GstVaapiEncoderH264 /* public */ guint32 profile; guint32 level; - guint32 bitrate; /*kbps */ guint32 intra_period; guint32 idr_period; guint32 init_qp; /*default 24 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 3c1c34b6a6..9104eafe87 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -105,6 +105,8 @@ ensure_sampling_desity (GstVaapiEncoderMpeg2 * encoder) static gboolean ensure_public_attributes (GstVaapiEncoderMpeg2 * encoder) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + if (!GST_VAAPI_ENCODER_WIDTH (encoder) || !GST_VAAPI_ENCODER_HEIGHT (encoder) || !GST_VAAPI_ENCODER_FPS_N (encoder) || @@ -128,13 +130,13 @@ ensure_public_attributes (GstVaapiEncoderMpeg2 * encoder) /* default compress ratio 1: (4*8*1.5) */ if (GST_VAAPI_RATECONTROL_CBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { - if (!encoder->bitrate) - encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * + if (!base_encoder->bitrate) + base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * GST_VAAPI_ENCODER_HEIGHT (encoder) * GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024; } else - encoder->bitrate = 0; + base_encoder->bitrate = 0; return TRUE; } @@ -176,6 +178,7 @@ make_profile_and_level_indication (guint32 profile, guint32 level) static gboolean fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); VAEncSequenceParameterBufferMPEG2 *seq = sequence->param; memset (seq, 0, sizeof (VAEncSequenceParameterBufferMPEG2)); @@ -185,8 +188,8 @@ fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence) seq->picture_width = GST_VAAPI_ENCODER_WIDTH (encoder); seq->picture_height = GST_VAAPI_ENCODER_HEIGHT (encoder); - if (encoder->bitrate > 0) - seq->bits_per_second = encoder->bitrate * 1024; + if (base_encoder->bitrate > 0) + seq->bits_per_second = base_encoder->bitrate * 1024; else seq->bits_per_second = 0; @@ -418,6 +421,7 @@ static gboolean set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncMiscParam *misc = NULL; VAEncMiscParameterHRD *hrd; VAEncMiscParameterRateControl *rate_control; @@ -429,9 +433,9 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, return FALSE; gst_vaapi_enc_picture_add_misc_buffer (picture, misc); hrd = misc->impl; - if (encoder->bitrate > 0) { - hrd->initial_buffer_fullness = encoder->bitrate * 1024 * 4; - hrd->buffer_size = encoder->bitrate * 1024 * 8; + if (base_encoder->bitrate > 0) { + hrd->initial_buffer_fullness = base_encoder->bitrate * 1024 * 4; + hrd->buffer_size = base_encoder->bitrate * 1024 * 8; } else { hrd->initial_buffer_fullness = 0; hrd->buffer_size = 0; @@ -447,8 +451,8 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, gst_vaapi_enc_picture_add_misc_buffer (picture, misc); rate_control = misc->impl; memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); - if (encoder->bitrate) - rate_control->bits_per_second = encoder->bitrate * 1024; + if (base_encoder->bitrate) + rate_control->bits_per_second = base_encoder->bitrate * 1024; else rate_control->bits_per_second = 0; rate_control->target_percentage = 70; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h index 71e14041e0..df94ab6b2b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h @@ -80,7 +80,6 @@ struct _GstVaapiEncoderMpeg2 /* public */ guint32 profile; guint32 level; - guint32 bitrate; /*kbps */ guint32 cqp; guint32 intra_period; guint32 ip_period; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index a3ec6db503..dd0a41e69b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -98,6 +98,7 @@ struct _GstVaapiEncoder GstVideoInfo video_info; GstVaapiRateControl rate_control; guint32 rate_control_mask; + guint bitrate; /* kbps */ GMutex mutex; GCond surface_free; diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 64840a5381..c66488e363 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -318,6 +318,10 @@ ensure_encoder (GstVaapiEncode * encode) encode->rate_control); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return FALSE; + + status = gst_vaapi_encoder_set_bitrate (encode->encoder, encode->bitrate); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return FALSE; return TRUE; } diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 445437dcd4..40d286664a 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -162,7 +162,6 @@ gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) { GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (base); GstVaapiEncoder *base_encoder; GstVaapiEncoderH264 *encoder; @@ -173,7 +172,6 @@ gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base, encoder->profile = GST_VAAPI_PROFILE_UNKNOWN; encoder->level = GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL; - encoder->bitrate = base_encode->bitrate; encoder->intra_period = encode->intra_period; encoder->init_qp = encode->init_qp; encoder->min_qp = encode->min_qp; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 4182910360..0daccba98b 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -153,7 +153,6 @@ gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) { GstVaapiEncodeMpeg2 *const encode = GST_VAAPIENCODE_MPEG2_CAST (base); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (base); GstVaapiEncoder *base_encoder; GstVaapiEncoderMpeg2 *encoder; @@ -164,7 +163,6 @@ gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, encoder->profile = GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE; encoder->level = GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL; - encoder->bitrate = base_encode->bitrate; encoder->cqp = encode->quantizer; encoder->intra_period = encode->intra_period; encoder->ip_period = encode->ip_period; From dcc7a94408f8fd4b06c097909c8da1df6858ed96 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 6 Jan 2014 17:46:40 +0100 Subject: [PATCH 1497/3781] encoder: add properties API. Add interface to communicate configurable properties to the encoder. This covers both the common ones (rate-control, bitrate), and the codec specific properties. https://bugzilla.gnome.org/show_bug.cgi?id=719529 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 234 ++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiencoder.h | 28 +++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 137 +++++++++--- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 23 ++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 74 ++++++- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 19 ++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 28 +++ 7 files changed, 516 insertions(+), 27 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index fc00261c83..2e6def042b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -26,10 +26,122 @@ #include "gstvaapicontext.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiutils.h" +#include "gstvaapivalue.h" #define DEBUG 1 #include "gstvaapidebug.h" +/* Helper function to create a new encoder property object */ +static GstVaapiEncoderPropData * +prop_new (gint id, GParamSpec * pspec) +{ + GstVaapiEncoderPropData *prop; + + if (!id || !pspec) + return NULL; + + prop = g_slice_new (GstVaapiEncoderPropData); + if (!prop) + return NULL; + + prop->prop = id; + prop->pspec = g_param_spec_ref_sink (pspec); + return prop; +} + +/* Helper function to release a property object and any memory held herein */ +static void +prop_free (GstVaapiEncoderPropData * prop) +{ + if (!prop) + return; + + if (prop->pspec) { + g_param_spec_unref (prop->pspec); + prop->pspec = NULL; + } + g_slice_free (GstVaapiEncoderPropData, prop); +} + +/* Helper function to lookup the supplied property specification */ +static GParamSpec * +prop_find_pspec (GstVaapiEncoder * encoder, gint prop_id) +{ + GPtrArray *const props = encoder->properties; + guint i; + + if (props) { + for (i = 0; i < props->len; i++) { + GstVaapiEncoderPropInfo *const prop = g_ptr_array_index (props, i); + if (prop->prop == prop_id) + return prop->pspec; + } + } + return NULL; +} + +/* Create a new array of properties, or NULL on error */ +GPtrArray * +gst_vaapi_encoder_properties_append (GPtrArray * props, gint prop_id, + GParamSpec * pspec) +{ + GstVaapiEncoderPropData *prop; + + if (!props) { + props = g_ptr_array_new_with_free_func ((GDestroyNotify) prop_free); + if (!props) + return NULL; + } + + prop = prop_new (prop_id, pspec); + if (!prop) + goto error_allocation_failed; + g_ptr_array_add (props, prop); + return props; + + /* ERRORS */ +error_allocation_failed: + { + GST_ERROR ("failed to allocate encoder property info structure"); + g_ptr_array_unref (props); + return NULL; + } +} + +/* Generate the common set of encoder properties */ +GPtrArray * +gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) +{ + const GstVaapiEncoderClassData *const cdata = klass->class_data; + GPtrArray *props = NULL; + + /** + * GstVaapiEncoder:rate-control: + * + * The desired rate control mode, expressed as a #GstVaapiRateControl. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_PROP_RATECONTROL, + g_param_spec_enum ("rate-control", + "Rate Control", "Rate control mode", + GST_VAAPI_TYPE_RATE_CONTROL, cdata->default_rate_control, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoder:bitrate: + * + * The desired bitrate, expressed in kbps. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_PROP_BITRATE, + g_param_spec_uint ("bitrate", + "Bitrate (kbps)", + "The desired bitrate expressed in kbps (0: auto-calculate)", + 0, 100 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + return props; +} + /** * gst_vaapi_encoder_ref: * @encoder: a #GstVaapiEncoder @@ -390,6 +502,93 @@ error: return NULL; } +/** + * gst_vaapi_encoder_set_property: + * @encoder: a #GstVaapiEncoder + * @prop_id: the id of the property to change + * @value: the new value to set + * + * Update the requested property, designed by @prop_id, with the + * supplied @value. A @NULL value argument resets the property to its + * default value. + * + * Return value: a #GstVaapiEncoderStatus + */ +static GstVaapiEncoderStatus +set_property (GstVaapiEncoder * encoder, gint prop_id, const GValue * value) +{ + GstVaapiEncoderStatus status = + GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + + g_assert (value != NULL); + + /* Handle codec-specific properties */ + if (prop_id < 0) { + GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + + if (klass->set_property) { + if (encoder->num_codedbuf_queued > 0) + goto error_operation_failed; + status = klass->set_property (encoder, prop_id, value); + } + return status; + } + + /* Handle common properties */ + switch (prop_id) { + case GST_VAAPI_ENCODER_PROP_RATECONTROL: + status = gst_vaapi_encoder_set_rate_control (encoder, + g_value_get_enum (value)); + break; + case GST_VAAPI_ENCODER_PROP_BITRATE: + status = gst_vaapi_encoder_set_bitrate (encoder, + g_value_get_uint (value)); + break; + } + return status; + + /* ERRORS */ +error_operation_failed: + { + GST_ERROR ("could not change codec state after encoding started"); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } +} + +GstVaapiEncoderStatus +gst_vaapi_encoder_set_property (GstVaapiEncoder * encoder, gint prop_id, + const GValue * value) +{ + GstVaapiEncoderStatus status; + GValue default_value = G_VALUE_INIT; + + g_return_val_if_fail (encoder != NULL, + GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER); + + if (!value) { + GParamSpec *const pspec = prop_find_pspec (encoder, prop_id); + if (!pspec) + goto error_invalid_property; + + g_value_init (&default_value, pspec->value_type); + g_param_value_set_default (pspec, &default_value); + value = &default_value; + } + + status = set_property (encoder, prop_id, value); + + if (default_value.g_type) + g_value_unset (&default_value); + return status; + + /* ERRORS */ +error_invalid_property: + { + GST_ERROR ("unsupported property (%d)", prop_id); + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } +} + /* Determine the supported rate control modes */ static gboolean get_rate_control_mask (GstVaapiEncoder * encoder) @@ -524,6 +723,29 @@ error_operation_failed: } } +/* Initialize default values for configurable properties */ +static gboolean +gst_vaapi_encoder_init_properties (GstVaapiEncoder * encoder) +{ + GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + GPtrArray *props; + guint i; + + props = klass->get_default_properties (); + if (!props) + return FALSE; + + encoder->properties = props; + for (i = 0; i < props->len; i++) { + GstVaapiEncoderPropInfo *const prop = g_ptr_array_index (props, i); + + if (gst_vaapi_encoder_set_property (encoder, prop->prop, + NULL) != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return FALSE; + } + return TRUE; +} + /* Base encoder initialization (internal) */ static gboolean gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) @@ -539,6 +761,7 @@ gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) CHECK_VTABLE_HOOK (init); CHECK_VTABLE_HOOK (finalize); + CHECK_VTABLE_HOOK (get_default_properties); CHECK_VTABLE_HOOK (encode); CHECK_VTABLE_HOOK (reordering); CHECK_VTABLE_HOOK (flush); @@ -562,7 +785,11 @@ gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) if (!encoder->codedbuf_queue) return FALSE; - return klass->init (encoder); + if (!klass->init (encoder)) + return FALSE; + if (!gst_vaapi_encoder_init_properties (encoder)) + return FALSE; + return TRUE; /* ERRORS */ error_invalid_vtable: @@ -584,6 +811,11 @@ gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) gst_vaapi_display_replace (&encoder->display, NULL); encoder->va_display = NULL; + if (encoder->properties) { + g_ptr_array_unref (encoder->properties); + encoder->properties = NULL; + } + gst_vaapi_video_pool_replace (&encoder->codedbuf_pool, NULL); if (encoder->codedbuf_queue) { g_async_queue_unref (encoder->codedbuf_queue); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 2fc3e74a44..a4dbe3ad16 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -68,6 +68,30 @@ typedef enum GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER = -103, } GstVaapiEncoderStatus; +/** + * GstVaapiEncoderProp: + * @GST_VAAPI_ENCODER_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). + * @GST_VAAPI_ENCODER_PROP_BITRATE: Bitrate expressed in kbps (uint). + * + * The set of configurable properties for the encoder. + */ +typedef enum { + GST_VAAPI_ENCODER_PROP_RATECONTROL = 1, + GST_VAAPI_ENCODER_PROP_BITRATE, +} GstVaapiEncoderProp; + +/** + * GstVaapiEncoderPropInfo: + * @prop: the #GstVaapiEncoderProp + * @pspec: the #GParamSpec describing the associated configurable value + * + * A #GstVaapiEncoderProp descriptor. + */ +typedef struct { + const gint prop; + GParamSpec *const pspec; +} GstVaapiEncoderPropInfo; + GstVaapiEncoder * gst_vaapi_encoder_ref (GstVaapiEncoder * encoder); @@ -86,6 +110,10 @@ GstCaps * gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, GstVideoCodecState * state, GstCaps * ref_caps); +GstVaapiEncoderStatus +gst_vaapi_encoder_set_property (GstVaapiEncoder * encoder, gint prop_id, + const GValue * value); + GstVaapiEncoderStatus gst_vaapi_encoder_set_rate_control (GstVaapiEncoder * encoder, GstVaapiRateControl rate_control); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 121c0d3a56..420a0e35f8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1273,9 +1273,7 @@ init_encoder_public_attributes (GstVaapiEncoderH264 * encoder) _set_level (encoder); - if (!encoder->intra_period) - encoder->intra_period = GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD; - else if (encoder->intra_period > GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD) + if (encoder->intra_period > GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD) encoder->intra_period = GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD; if (encoder->idr_period < encoder->intra_period) @@ -1283,17 +1281,9 @@ init_encoder_public_attributes (GstVaapiEncoderH264 * encoder) if (encoder->idr_period > GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD) encoder->idr_period = GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD; - if (-1 == encoder->init_qp) - encoder->init_qp = GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP; - - if (-1 == encoder->min_qp) { - if (GST_VAAPI_RATECONTROL_CQP == GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) - encoder->min_qp = encoder->init_qp; - else - encoder->min_qp = GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP; - } - - if (encoder->min_qp > encoder->init_qp) + if (encoder->min_qp > encoder->init_qp || + (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP && + encoder->min_qp < encoder->init_qp)) encoder->min_qp = encoder->init_qp; /* default compress ratio 1: (4*8*1.5) */ @@ -1309,9 +1299,6 @@ init_encoder_public_attributes (GstVaapiEncoderH264 * encoder) } else base_encoder->bitrate = 0; - if (!encoder->slice_num) - encoder->slice_num = GST_VAAPI_ENCODER_H264_DEFAULT_SLICE_NUM; - width_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; height_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; total_mbs = width_mbs * height_mbs; @@ -1704,17 +1691,10 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base) { GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base); - base->rate_control = DEFAULT_RATECONTROL; - /* init attributes */ encoder->profile = 0; encoder->level = 0; encoder->idr_period = 0; - encoder->intra_period = 0; - encoder->init_qp = -1; - encoder->min_qp = -1; - encoder->slice_num = 0; - encoder->b_frame_num = 0; //gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE); /* init private values */ @@ -1771,6 +1751,34 @@ gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base) } +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, + gint prop_id, const GValue * value) +{ + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); + + switch (prop_id) { + case GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD: + encoder->intra_period = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES: + encoder->b_frame_num = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_INIT_QP: + encoder->init_qp = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_MIN_QP: + encoder->min_qp = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES: + encoder->slice_num = g_value_get_uint (value); + break; + default: + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H264); static inline const GstVaapiEncoderClass * @@ -1778,6 +1786,7 @@ gst_vaapi_encoder_h264_class (void) { static const GstVaapiEncoderClass GstVaapiEncoderH264Class = { GST_VAAPI_ENCODER_CLASS_INIT (H264, h264), + .set_property = gst_vaapi_encoder_h264_set_property, .get_codec_data = gst_vaapi_encoder_h264_get_codec_data }; return &GstVaapiEncoderH264Class; @@ -1789,6 +1798,86 @@ gst_vaapi_encoder_h264_new (GstVaapiDisplay * display) return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display); } +/** + * gst_vaapi_encoder_h264_get_default_properties: + * + * Determines the set of common and H.264 specific encoder properties. + * The caller owns an extra reference to the resulting array of + * #GstVaapiEncoderPropInfo elements, so it shall be released with + * g_ptr_array_unref() after usage. + * + * Return value: the set of encoder properties for #GstVaapiEncoderH264, + * or %NULL if an error occurred. + */ +GPtrArray * +gst_vaapi_encoder_h264_get_default_properties (void) +{ + const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h264_class (); + GPtrArray *props; + + props = gst_vaapi_encoder_properties_get_default (klass); + if (!props) + return NULL; + + /** + * GstVaapiEncoderH264:key-period + * + * The maximal distance between two keyframes. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD, + g_param_spec_uint ("key-period", + "Key Period", "Maximal distance between two key-frames", 1, 300, 30, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:max-bframes: + * + * The number of B-frames between I and P. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES, + g_param_spec_uint ("max-bframes", + "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:init-qp: + * + * The initial quantizer value. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_INIT_QP, + g_param_spec_uint ("init-qp", + "Initial QP", "Initial quantizer value", 1, 51, 26, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:min-qp: + * + * The minimum quantizer value. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_MIN_QP, + g_param_spec_uint ("min-qp", + "Minimum QP", "Minimum quantizer value", 1, 51, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:num-slices: + * + * The number of slices per frame. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES, + g_param_spec_uint ("num-slices", + "Number of Slices", + "Number of slices per frame", + 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + return props; +} + void gst_vaapi_encoder_h264_set_avc (GstVaapiEncoderH264 * encoder, gboolean is_avc) { diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 3eee7c8f82..b6c4a1ce30 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -28,9 +28,32 @@ G_BEGIN_DECLS typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; +/** + * GstVaapiEncoderH264Prop: + * @GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD: Maximal distance between two + * keyframes (uint). + * @GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES: Number of B-frames between I + * and P (uint). + * @GST_VAAPI_ENCODER_H264_PROP_INIT_QP: Initial quantizer value (uint). + * @GST_VAAPI_ENCODER_H264_PROP_MIN_QP: Minimal quantizer value (uint). + * @GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES: Number of slices per frame (uint). + * + * The set of H.264 encoder specific configurable properties. + */ +typedef enum { + GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD = -1, + GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES = -2, + GST_VAAPI_ENCODER_H264_PROP_INIT_QP = -3, + GST_VAAPI_ENCODER_H264_PROP_MIN_QP = -4, + GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES = -5, +} GstVaapiEncoderH264Prop; + GstVaapiEncoder * gst_vaapi_encoder_h264_new (GstVaapiDisplay * display); +GPtrArray * +gst_vaapi_encoder_h264_get_default_properties (void); + void gst_vaapi_encoder_h264_set_avc (GstVaapiEncoderH264 * encoder, gboolean is_avc); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 9104eafe87..fb7e042eff 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -732,8 +732,6 @@ gst_vaapi_encoder_mpeg2_init (GstVaapiEncoder * base) { GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); - base->rate_control = DEFAULT_RATECONTROL; - /* re-ordering */ g_queue_init (&encoder->b_frames); encoder->dump_frames = FALSE; @@ -792,6 +790,28 @@ gst_vaapi_encoder_mpeg2_finalize (GstVaapiEncoder * base) g_queue_clear (&encoder->b_frames); } +static GstVaapiEncoderStatus +gst_vaapi_encoder_mpeg2_set_property (GstVaapiEncoder * base_encoder, + gint prop_id, const GValue * value) +{ + GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2 (base_encoder); + + switch (prop_id) { + case GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER: + encoder->cqp = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD: + encoder->intra_period = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES: + encoder->ip_period = g_value_get_uint (value); + break; + default: + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (MPEG2); static inline const GstVaapiEncoderClass * @@ -799,6 +819,7 @@ gst_vaapi_encoder_mpeg2_class (void) { static const GstVaapiEncoderClass GstVaapiEncoderMpeg2Class = { GST_VAAPI_ENCODER_CLASS_INIT (Mpeg2, mpeg2), + .set_property = gst_vaapi_encoder_mpeg2_set_property, }; return &GstVaapiEncoderMpeg2Class; } @@ -809,6 +830,55 @@ gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display) return gst_vaapi_encoder_new (gst_vaapi_encoder_mpeg2_class (), display); } +/** + * gst_vaapi_encoder_mpeg2_get_default_properties: + * + * Determines the set of common and MPEG-2 specific encoder properties. + * The caller owns an extra reference to the resulting array of + * #GstVaapiEncoderPropInfo elements, so it shall be released with + * g_ptr_array_unref() after usage. + * + * Return value: the set of encoder properties for #GstVaapiEncoderMpeg2, + * or %NULL if an error occurred. + */ +GPtrArray * +gst_vaapi_encoder_mpeg2_get_default_properties (void) +{ + const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_mpeg2_class (); + GPtrArray *props; + + props = gst_vaapi_encoder_properties_get_default (klass); + if (!props) + return NULL; + + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER, + g_param_spec_uint ("quantizer", + "Constant Quantizer", + "Constant quantizer (if rate-control mode is CQP)", + GST_VAAPI_ENCODER_MPEG2_MIN_CQP, GST_VAAPI_ENCODER_MPEG2_MAX_CQP, + GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD, + g_param_spec_uint ("key-period", + "Key Period", "Maximal distance between two key-frames", 1, + GST_VAAPI_ENCODER_MPEG2_MAX_GOP_SIZE, + GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES, + g_param_spec_uint ("max-bframes", "Max B-Frames", + "Number of B-frames between I and P", 0, + GST_VAAPI_ENCODER_MPEG2_MAX_MAX_BFRAMES, + GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + return props; +} + static struct { int code; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h index a880875133..bd6d1a7cbf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -28,9 +28,28 @@ G_BEGIN_DECLS typedef struct _GstVaapiEncoderMpeg2 GstVaapiEncoderMpeg2; +/** + * GstVaapiEncoderMpeg2Prop: + * @GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER: Constant quantizer value (uint). + * @GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD: Maximal distance between two + * keyframes (uint). + * @GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES: Number of B-frames between I + * and P (uint). + * + * The set of MPEG-2 encoder specific configurable properties. + */ +typedef enum { + GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER = -1, + GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD = -2, + GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES = -3, +} GstVaapiEncoderMpeg2Prop; + GstVaapiEncoder * gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display); +GPtrArray * +gst_vaapi_encoder_mpeg2_get_default_properties (void); + G_END_DECLS #endif /* GST_VAAPI_ENCODER_MPEG2_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index dd0a41e69b..0238ac1b02 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -83,11 +83,33 @@ G_BEGIN_DECLS typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass; typedef struct _GstVaapiEncoderClassData GstVaapiEncoderClassData; +/* Private GstVaapiEncoderPropInfo definition */ +typedef struct { + gint prop; + GParamSpec *pspec; +} GstVaapiEncoderPropData; + +#define GST_VAAPI_ENCODER_PROPERTIES_APPEND(props, id, pspec) do { \ + props = gst_vaapi_encoder_properties_append (props, id, pspec); \ + if (!props) \ + return NULL; \ + } while (0) + +G_GNUC_INTERNAL +GPtrArray * +gst_vaapi_encoder_properties_append (GPtrArray * props, gint prop_id, + GParamSpec *pspec); + +G_GNUC_INTERNAL +GPtrArray * +gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass); + struct _GstVaapiEncoder { /*< private >*/ GstVaapiMiniObject parent_instance; + GPtrArray *properties; GstVaapiDisplay *display; GstVaapiContext *context; GstVaapiContextInfo context_info; @@ -141,6 +163,11 @@ struct _GstVaapiEncoderClass void (*set_context_info) (GstVaapiEncoder * encoder); + GPtrArray * (*get_default_properties) (void); + GstVaapiEncoderStatus (*set_property) (GstVaapiEncoder * encoder, + gint prop_id, + const GValue * value); + GstVaapiEncoderStatus (*reordering) (GstVaapiEncoder * encoder, GstVideoCodecFrame * in, GstVaapiEncPicture ** out); @@ -169,6 +196,7 @@ struct _GstVaapiEncoderClass .class_data = &g_class_data, \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, init), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, finalize), \ + GST_VAAPI_ENCODER_CLASS_HOOK (codec, get_default_properties), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, set_format), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, set_context_info), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, reordering), \ From a43d06dcf5b109165ba39c8214124433c4d4a5ee Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 8 Jan 2014 18:36:46 +0100 Subject: [PATCH 1498/3781] vaapiencode: update for new properties API. Update MPEG-2 and H.264 encode elements to cope with the new core libgstvaapi properties API. i.e. all configurable properties are now directly handled at the GstVaapiEncoder level. Besides, this also makes sure to not use or modify the GstVaapiEncoder private definitions directly. Private data need to remain private. https://bugzilla.gnome.org/show_bug.cgi?id=719529 --- gst/vaapi/gstvaapiencode.c | 219 +++++++++++++++++++++---------- gst/vaapi/gstvaapiencode.h | 17 ++- gst/vaapi/gstvaapiencode_h264.c | 113 ++-------------- gst/vaapi/gstvaapiencode_h264.h | 6 - gst/vaapi/gstvaapiencode_mpeg2.c | 90 ++----------- 5 files changed, 193 insertions(+), 252 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index c66488e363..7c797d62a5 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -48,8 +48,8 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode, enum { PROP_0, - PROP_RATE_CONTROL, - PROP_BITRATE, + + PROP_BASE, }; static inline gboolean @@ -90,6 +90,88 @@ gst_vaapiencode_query (GST_PAD_QUERY_FUNCTION_ARGS) return success; } +typedef struct +{ + GstVaapiEncoderProp id; + GParamSpec *pspec; + GValue value; +} PropValue; + +static PropValue * +prop_value_new (GstVaapiEncoderPropInfo * prop) +{ + static const GValue default_value = G_VALUE_INIT; + PropValue *prop_value; + + if (!prop || !prop->pspec) + return NULL; + + prop_value = g_slice_new (PropValue); + if (!prop_value) + return NULL; + + prop_value->id = prop->prop; + prop_value->pspec = g_param_spec_ref (prop->pspec); + + memcpy (&prop_value->value, &default_value, sizeof (prop_value->value)); + g_value_init (&prop_value->value, prop->pspec->value_type); + g_param_value_set_default (prop->pspec, &prop_value->value); + return prop_value; +} + +static void +prop_value_free (PropValue * prop_value) +{ + if (!prop_value) + return; + + if (G_VALUE_TYPE (&prop_value->value)) + g_value_unset (&prop_value->value); + + if (prop_value->pspec) { + g_param_spec_unref (prop_value->pspec); + prop_value->pspec = NULL; + } + g_slice_free (PropValue, prop_value); +} + +static inline PropValue * +prop_value_lookup (GstVaapiEncode * encode, guint prop_id) +{ + GPtrArray *const prop_values = encode->prop_values; + + if (prop_values && + (prop_id >= PROP_BASE && prop_id < PROP_BASE + prop_values->len)) + return g_ptr_array_index (prop_values, prop_id - PROP_BASE); + return NULL; +} + +static gboolean +gst_vaapiencode_default_get_property (GstVaapiEncode * encode, guint prop_id, + GValue * value) +{ + PropValue *const prop_value = prop_value_lookup (encode, prop_id); + + if (prop_value) { + g_value_copy (&prop_value->value, value); + return TRUE; + } + return FALSE; +} + +static gboolean +gst_vaapiencode_default_set_property (GstVaapiEncode * encode, guint prop_id, + const GValue * value) +{ + PropValue *const prop_value = prop_value_lookup (encode, prop_id); + + if (prop_value) { + g_value_copy (value, &prop_value->value); + return TRUE; + } + return FALSE; +} + static GstFlowReturn gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode, GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr) @@ -303,6 +385,8 @@ ensure_encoder (GstVaapiEncode * encode) { GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode); GstVaapiEncoderStatus status; + GPtrArray *const prop_values = encode->prop_values; + guint i; g_return_val_if_fail (klass->create_encoder, FALSE); @@ -314,14 +398,15 @@ ensure_encoder (GstVaapiEncode * encode) if (!encode->encoder) return FALSE; - status = gst_vaapi_encoder_set_rate_control (encode->encoder, - encode->rate_control); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return FALSE; - - status = gst_vaapi_encoder_set_bitrate (encode->encoder, encode->bitrate); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return FALSE; + if (prop_values) { + for (i = 0; i < prop_values->len; i++) { + PropValue *const prop_value = g_ptr_array_index (prop_values, i); + status = gst_vaapi_encoder_set_property (encode->encoder, prop_value->id, + &prop_value->value); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return FALSE; + } + } return TRUE; } @@ -562,44 +647,6 @@ gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query) } #endif -static void -gst_vaapiencode_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - case PROP_RATE_CONTROL: - encode->rate_control = g_value_get_enum (value); - break; - case PROP_BITRATE: - encode->bitrate = g_value_get_uint (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vaapiencode_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - case PROP_RATE_CONTROL: - g_value_set_enum (value, encode->rate_control); - break; - case PROP_BITRATE: - g_value_set_uint (value, encode->bitrate); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static void gst_vaapiencode_finalize (GObject * object) { @@ -607,6 +654,11 @@ gst_vaapiencode_finalize (GObject * object) gst_vaapiencode_destroy (encode); + if (encode->prop_values) { + g_ptr_array_unref (encode->prop_values); + encode->prop_values = NULL; + } + encode->sinkpad = NULL; encode->srcpad = NULL; @@ -644,8 +696,6 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) gst_vaapi_plugin_base_class_init (GST_VAAPI_PLUGIN_BASE_CLASS (klass)); object_class->finalize = gst_vaapiencode_finalize; - object_class->set_property = gst_vaapiencode_set_property; - object_class->get_property = gst_vaapiencode_get_property; venc_class->open = GST_DEBUG_FUNCPTR (gst_vaapiencode_open); venc_class->close = GST_DEBUG_FUNCPTR (gst_vaapiencode_close); @@ -660,24 +710,61 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) GST_DEBUG_FUNCPTR (gst_vaapiencode_propose_allocation); #endif + klass->get_property = gst_vaapiencode_default_get_property; + klass->set_property = gst_vaapiencode_default_set_property; klass->allocate_buffer = gst_vaapiencode_default_allocate_buffer; /* Registering debug symbols for function pointers */ GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_query); - - g_object_class_install_property (object_class, - PROP_RATE_CONTROL, - g_param_spec_enum ("rate-control", - "Rate Control", - "Rate control mode", - GST_VAAPI_TYPE_RATE_CONTROL, - GST_VAAPI_RATECONTROL_CQP, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_BITRATE, - g_param_spec_uint ("bitrate", - "Bitrate (kbps)", - "The desired bitrate expressed in kbps (0: auto-calculate)", - 0, 100 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static inline GPtrArray * +get_properties (GstVaapiEncodeClass * klass) +{ + return klass->get_properties ? klass->get_properties () : NULL; +} + +gboolean +gst_vaapiencode_init_properties (GstVaapiEncode * encode) +{ + GPtrArray *const props = get_properties (GST_VAAPIENCODE_GET_CLASS (encode)); + guint i; + + /* XXX: use base_init()/base_finalize() to avoid multiple initializations */ + if (!props) + return FALSE; + + encode->prop_values = + g_ptr_array_new_full (props->len, (GDestroyNotify) prop_value_free); + if (!encode->prop_values) { + g_ptr_array_unref (props); + return FALSE; + } + + for (i = 0; i < props->len; i++) { + PropValue *const prop_value = prop_value_new ((GstVaapiEncoderPropInfo *) + g_ptr_array_index (props, i)); + if (!prop_value) + return FALSE; + g_ptr_array_add (encode->prop_values, prop_value); + } + return TRUE; +} + +gboolean +gst_vaapiencode_class_init_properties (GstVaapiEncodeClass * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GPtrArray *const props = get_properties (klass); + guint i; + + if (!props) + return FALSE; + + for (i = 0; i < props->len; i++) { + GstVaapiEncoderPropInfo *const prop = g_ptr_array_index (props, i); + g_object_class_install_property (object_class, PROP_BASE + i, prop->pspec); + } + g_ptr_array_unref (props); + return TRUE; } diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index e930cbe116..7eeabc4f5d 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -59,8 +59,7 @@ struct _GstVaapiEncode GstPadQueryFunction srcpad_query; GstVaapiEncoder *encoder; - GstVaapiRateControl rate_control; - guint32 bitrate; /* kbps */ + GPtrArray *prop_values; guint32 out_caps_done:1; }; @@ -70,6 +69,12 @@ struct _GstVaapiEncodeClass /*< private >*/ GstVaapiPluginBaseClass parent_class; + GPtrArray * (*get_properties) (void); + gboolean (*get_property) (GstVaapiEncode * encode, + guint prop_id, GValue * value); + gboolean (*set_property) (GstVaapiEncode * encode, + guint prop_id, const GValue * value); + GstVaapiEncoder * (*create_encoder) (GstVaapiEncode * encode, GstVaapiDisplay * display); GstFlowReturn (*allocate_buffer) (GstVaapiEncode * encode, @@ -80,6 +85,14 @@ struct _GstVaapiEncodeClass GType gst_vaapiencode_get_type (void) G_GNUC_CONST; +G_GNUC_INTERNAL +gboolean +gst_vaapiencode_init_properties (GstVaapiEncode * encode); + +G_GNUC_INTERNAL +gboolean +gst_vaapiencode_class_init_properties (GstVaapiEncodeClass * encode_class); + G_END_DECLS #endif /* GST_VAAPIENCODE_H */ diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 40d286664a..b559e3b1b8 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -22,7 +22,6 @@ #include "gst/vaapi/sysdeps.h" #include #include -#include "gst/vaapi/gstvaapiencoder_h264_priv.h" #include "gstvaapiencode_h264.h" #include "gstvaapipluginutil.h" #if GST_CHECK_VERSION(1,0,0) @@ -80,19 +79,10 @@ static GstStaticPadTemplate gst_vaapiencode_h264_src_factory = /* h264 encode */ G_DEFINE_TYPE (GstVaapiEncodeH264, gst_vaapiencode_h264, GST_TYPE_VAAPIENCODE); -enum -{ - PROP_0, - PROP_KEY_PERIOD, - PROP_MAX_BFRAMES, - PROP_INIT_QP, - PROP_MIN_QP, - PROP_NUM_SLICES, -}; - static void gst_vaapiencode_h264_init (GstVaapiEncodeH264 * encode) { + gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); } static void @@ -105,26 +95,13 @@ static void gst_vaapiencode_h264_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (object); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); switch (prop_id) { - case PROP_KEY_PERIOD: - encode->intra_period = g_value_get_uint (value); - break; - case PROP_INIT_QP: - encode->init_qp = g_value_get_uint (value); - break; - case PROP_MIN_QP: - encode->min_qp = g_value_get_uint (value); - break; - case PROP_NUM_SLICES: - encode->num_slices = g_value_get_uint (value); - break; - case PROP_MAX_BFRAMES: - encode->max_bframes = g_value_get_uint (value); - break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + if (!encode_class->set_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } @@ -133,26 +110,13 @@ static void gst_vaapiencode_h264_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (object); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); switch (prop_id) { - case PROP_KEY_PERIOD: - g_value_set_uint (value, encode->intra_period); - break; - case PROP_INIT_QP: - g_value_set_uint (value, encode->init_qp); - break; - case PROP_MIN_QP: - g_value_set_uint (value, encode->min_qp); - break; - case PROP_NUM_SLICES: - g_value_set_uint (value, encode->num_slices); - break; - case PROP_MAX_BFRAMES: - g_value_set_uint (value, encode->max_bframes); - break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + if (!encode_class->get_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } @@ -161,23 +125,7 @@ static GstVaapiEncoder * gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) { - GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base); - GstVaapiEncoder *base_encoder; - GstVaapiEncoderH264 *encoder; - - base_encoder = gst_vaapi_encoder_h264_new (display); - if (!base_encoder) - return NULL; - encoder = GST_VAAPI_ENCODER_H264 (base_encoder); - - encoder->profile = GST_VAAPI_PROFILE_UNKNOWN; - encoder->level = GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL; - encoder->intra_period = encode->intra_period; - encoder->init_qp = encode->init_qp; - encoder->min_qp = encode->min_qp; - encoder->slice_num = encode->num_slices; - encoder->b_frame_num = encode->max_bframes; - return base_encoder; + return gst_vaapi_encoder_h264_new (display); } /* h264 NAL byte stream operations */ @@ -276,7 +224,7 @@ static GstFlowReturn gst_vaapiencode_h264_allocate_buffer (GstVaapiEncode * encode, GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buffer_ptr) { - GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (encode->encoder); + GstVaapiEncoderH264 *const encoder = (GstVaapiEncoderH264 *) encode->encoder; GstFlowReturn ret; g_return_val_if_fail (encoder != NULL, GST_FLOW_ERROR); @@ -318,6 +266,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) object_class->set_property = gst_vaapiencode_h264_set_property; object_class->get_property = gst_vaapiencode_h264_get_property; + encode_class->get_properties = gst_vaapi_encoder_h264_get_default_properties; encode_class->create_encoder = gst_vaapiencode_h264_create_encoder; encode_class->allocate_buffer = gst_vaapiencode_h264_allocate_buffer; @@ -334,41 +283,5 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_vaapiencode_h264_src_factory)); - g_object_class_install_property (object_class, - PROP_KEY_PERIOD, - g_param_spec_uint ("key-period", - "Key Period", - "Maximal distance between two key-frames", - 1, 300, GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_MAX_BFRAMES, - g_param_spec_uint ("max-bframes", - "Max B-Frames", - "Number of B-frames between I and P", - 0, 10, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_INIT_QP, - g_param_spec_uint ("init-qp", - "Initial QP", - "Initial quantizer value", - 1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_MIN_QP, - g_param_spec_uint ("min-qp", - "Minimum QP", - "Minimum quantizer value", - 1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_NUM_SLICES, - g_param_spec_uint ("num-slices", - "Number of Slices", - "Number of slices per frame", - 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_vaapiencode_class_init_properties (encode_class); } diff --git a/gst/vaapi/gstvaapiencode_h264.h b/gst/vaapi/gstvaapiencode_h264.h index d6dad76c5f..bf440bfd68 100644 --- a/gst/vaapi/gstvaapiencode_h264.h +++ b/gst/vaapi/gstvaapiencode_h264.h @@ -52,12 +52,6 @@ struct _GstVaapiEncodeH264 { /*< private >*/ GstVaapiEncode parent_instance; - - guint32 intra_period; - guint32 init_qp; - guint32 min_qp; - guint32 num_slices; - guint32 max_bframes; }; struct _GstVaapiEncodeH264Class diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 0daccba98b..90c513abf1 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -22,7 +22,6 @@ #include "gst/vaapi/sysdeps.h" #include #include -#include "gst/vaapi/gstvaapiencoder_mpeg2_priv.h" #include "gstvaapiencode_mpeg2.h" #include "gstvaapipluginutil.h" #if GST_CHECK_VERSION(1,0,0) @@ -82,20 +81,10 @@ static GstStaticPadTemplate gst_vaapiencode_mpeg2_src_factory = G_DEFINE_TYPE (GstVaapiEncodeMpeg2, gst_vaapiencode_mpeg2, GST_TYPE_VAAPIENCODE); -enum -{ - PROP_0, - PROP_QUANTIZER, - PROP_KEY_PERIOD, - PROP_MAX_BFRAMES -}; - static void gst_vaapiencode_mpeg2_init (GstVaapiEncodeMpeg2 * encode) { - encode->quantizer = GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP; - encode->intra_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE; - encode->ip_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES; + gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); } static void @@ -108,20 +97,13 @@ static void gst_vaapiencode_mpeg2_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVaapiEncodeMpeg2 *const encode = GST_VAAPIENCODE_MPEG2_CAST (object); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); switch (prop_id) { - case PROP_QUANTIZER: - encode->quantizer = g_value_get_uint (value); - break; - case PROP_KEY_PERIOD: - encode->intra_period = g_value_get_uint (value); - break; - case PROP_MAX_BFRAMES: - encode->ip_period = g_value_get_uint (value); - break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + if (!encode_class->set_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } @@ -130,20 +112,13 @@ static void gst_vaapiencode_mpeg2_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVaapiEncodeMpeg2 *const encode = GST_VAAPIENCODE_MPEG2_CAST (object); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); switch (prop_id) { - case PROP_QUANTIZER: - g_value_set_uint (value, encode->quantizer); - break; - case PROP_KEY_PERIOD: - g_value_set_uint (value, encode->intra_period); - break; - case PROP_MAX_BFRAMES: - g_value_set_uint (value, encode->ip_period); - break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + if (!encode_class->get_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } @@ -152,21 +127,7 @@ static GstVaapiEncoder * gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) { - GstVaapiEncodeMpeg2 *const encode = GST_VAAPIENCODE_MPEG2_CAST (base); - GstVaapiEncoder *base_encoder; - GstVaapiEncoderMpeg2 *encoder; - - base_encoder = gst_vaapi_encoder_mpeg2_new (display); - if (!base_encoder) - return NULL; - encoder = GST_VAAPI_ENCODER_MPEG2 (base_encoder); - - encoder->profile = GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE; - encoder->level = GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL; - encoder->cqp = encode->quantizer; - encoder->intra_period = encode->intra_period; - encoder->ip_period = encode->ip_period; - return base_encoder; + return gst_vaapi_encoder_mpeg2_new (display); } static void @@ -183,6 +144,7 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) object_class->set_property = gst_vaapiencode_mpeg2_set_property; object_class->get_property = gst_vaapiencode_mpeg2_get_property; + encode_class->get_properties = gst_vaapi_encoder_mpeg2_get_default_properties; encode_class->create_encoder = gst_vaapiencode_mpeg2_create_encoder; gst_element_class_set_static_metadata (element_class, @@ -198,33 +160,5 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_vaapiencode_mpeg2_src_factory)); - g_object_class_install_property (object_class, - PROP_QUANTIZER, - g_param_spec_uint ("quantizer", - "Constant Quantizer", - "Constant quantizer (if rate-control mode is CQP)", - GST_VAAPI_ENCODER_MPEG2_MIN_CQP, - GST_VAAPI_ENCODER_MPEG2_MAX_CQP, - GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_KEY_PERIOD, - g_param_spec_uint ("key-period", - "Key Period", - "Maximal distance between two key-frames", - 1, - GST_VAAPI_ENCODER_MPEG2_MAX_GOP_SIZE, - GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_MAX_BFRAMES, - g_param_spec_uint ("max-bframes", - "Max B-Frames", - "Number of B-frames between I and P", - 0, - GST_VAAPI_ENCODER_MPEG2_MAX_MAX_BFRAMES, - GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_vaapiencode_class_init_properties (encode_class); } From 85ce893faa9e30eaacc98ab794fd790f77cc349c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 9 Jan 2014 10:09:38 +0100 Subject: [PATCH 1499/3781] vaapiencode: rename a few member functions. Rename a few member functions to make them more consistent: - alloc_encoder(): now reduced to allocate the encoder object only; - alloc_buffer(): allocate buffer from srcpad, and copy bitstream. --- gst/vaapi/gstvaapiencode.c | 10 +++++----- gst/vaapi/gstvaapiencode.h | 10 +++++----- gst/vaapi/gstvaapiencode_h264.c | 10 +++++----- gst/vaapi/gstvaapiencode_mpeg2.c | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 7c797d62a5..2276b11765 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -173,7 +173,7 @@ gst_vaapiencode_default_set_property (GstVaapiEncode * encode, guint prop_id, } static GstFlowReturn -gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode, +gst_vaapiencode_default_alloc_buffer (GstVaapiEncode * encode, GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr) { GstBuffer *buf; @@ -246,7 +246,7 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) /* Allocate and copy buffer into system memory */ out_buffer = NULL; - ret = klass->allocate_buffer (encode, + ret = klass->alloc_buffer (encode, GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy), &out_buffer); gst_vaapi_coded_buffer_proxy_replace (&codedbuf_proxy, NULL); if (ret != GST_FLOW_OK) @@ -388,12 +388,12 @@ ensure_encoder (GstVaapiEncode * encode) GPtrArray *const prop_values = encode->prop_values; guint i; - g_return_val_if_fail (klass->create_encoder, FALSE); + g_return_val_if_fail (klass->alloc_encoder, FALSE); if (!ensure_uploader (encode)) return FALSE; - encode->encoder = klass->create_encoder (encode, + encode->encoder = klass->alloc_encoder (encode, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); if (!encode->encoder) return FALSE; @@ -712,7 +712,7 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) klass->get_property = gst_vaapiencode_default_get_property; klass->set_property = gst_vaapiencode_default_set_property; - klass->allocate_buffer = gst_vaapiencode_default_allocate_buffer; + klass->alloc_buffer = gst_vaapiencode_default_alloc_buffer; /* Registering debug symbols for function pointers */ GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_query); diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 7eeabc4f5d..91712af339 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -75,11 +75,11 @@ struct _GstVaapiEncodeClass gboolean (*set_property) (GstVaapiEncode * encode, guint prop_id, const GValue * value); - GstVaapiEncoder * (*create_encoder) (GstVaapiEncode * encode, - GstVaapiDisplay * display); - GstFlowReturn (*allocate_buffer) (GstVaapiEncode * encode, - GstVaapiCodedBuffer * coded_buf, - GstBuffer ** outbuf_ptr); + GstVaapiEncoder * (*alloc_encoder) (GstVaapiEncode * encode, + GstVaapiDisplay * display); + GstFlowReturn (*alloc_buffer) (GstVaapiEncode * encode, + GstVaapiCodedBuffer * coded_buf, + GstBuffer ** outbuf_ptr); }; GType diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index b559e3b1b8..0d222b50dc 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -122,7 +122,7 @@ gst_vaapiencode_h264_get_property (GObject * object, } static GstVaapiEncoder * -gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base, +gst_vaapiencode_h264_alloc_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) { return gst_vaapi_encoder_h264_new (display); @@ -221,7 +221,7 @@ error: } static GstFlowReturn -gst_vaapiencode_h264_allocate_buffer (GstVaapiEncode * encode, +gst_vaapiencode_h264_alloc_buffer (GstVaapiEncode * encode, GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buffer_ptr) { GstVaapiEncoderH264 *const encoder = (GstVaapiEncoderH264 *) encode->encoder; @@ -230,7 +230,7 @@ gst_vaapiencode_h264_allocate_buffer (GstVaapiEncode * encode, g_return_val_if_fail (encoder != NULL, GST_FLOW_ERROR); ret = - GST_VAAPIENCODE_CLASS (gst_vaapiencode_h264_parent_class)->allocate_buffer + GST_VAAPIENCODE_CLASS (gst_vaapiencode_h264_parent_class)->alloc_buffer (encode, coded_buf, out_buffer_ptr); if (ret != GST_FLOW_OK) return ret; @@ -267,8 +267,8 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) object_class->get_property = gst_vaapiencode_h264_get_property; encode_class->get_properties = gst_vaapi_encoder_h264_get_default_properties; - encode_class->create_encoder = gst_vaapiencode_h264_create_encoder; - encode_class->allocate_buffer = gst_vaapiencode_h264_allocate_buffer; + encode_class->alloc_encoder = gst_vaapiencode_h264_alloc_encoder; + encode_class->alloc_buffer = gst_vaapiencode_h264_alloc_buffer; gst_element_class_set_static_metadata (element_class, "VA-API H.264 encoder", diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 90c513abf1..7579b2ac06 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -124,7 +124,7 @@ gst_vaapiencode_mpeg2_get_property (GObject * object, } static GstVaapiEncoder * -gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, +gst_vaapiencode_mpeg2_alloc_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) { return gst_vaapi_encoder_mpeg2_new (display); @@ -145,7 +145,7 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) object_class->get_property = gst_vaapiencode_mpeg2_get_property; encode_class->get_properties = gst_vaapi_encoder_mpeg2_get_default_properties; - encode_class->create_encoder = gst_vaapiencode_mpeg2_create_encoder; + encode_class->alloc_encoder = gst_vaapiencode_mpeg2_alloc_encoder; gst_element_class_set_static_metadata (element_class, "VA-API MPEG-2 encoder", From 37fa6a8a3db67ea661ff4d514e233c2e5337f8db Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 8 Jan 2014 18:56:23 +0100 Subject: [PATCH 1500/3781] vaapiencode: make GstVaapiEncode an abstract type. Make base GstVaapiEncode class an abstract type so that we cannot create an instance from it without going through any of the codec specific derived class. --- gst/vaapi/gstvaapiencode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 2276b11765..f5b0606a7d 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -41,7 +41,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapiencode_debug); #define GST_CAT_DEFAULT gst_vaapiencode_debug -G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode, +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstVaapiEncode, gst_vaapiencode, GST_TYPE_VIDEO_ENCODER, GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES); From 449ac54348e8816a927b56a285e3b277272226ac Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 9 Jan 2014 18:10:35 +0100 Subject: [PATCH 1501/3781] vaapiencode: fix negotiation process of output caps. The specified caps in gst_video_encoder_set_output_state() function arguments should not contain any resolution, pixel-aspect-ratio, framerate, codec-data et al. Those rather should be set through the returned GstVideoCodecState. This means that output caps creation could be delayed until before gst_video_encoder_finish_frame() is called. This greatly simplifies the GstVideoEncoder::set_format() callback by the way. --- gst/vaapi/gstvaapiencode.c | 160 +++++++++++++------------------ gst/vaapi/gstvaapiencode.h | 6 +- gst/vaapi/gstvaapiencode_h264.c | 50 ++++++++-- gst/vaapi/gstvaapiencode_h264.h | 2 + gst/vaapi/gstvaapiencode_mpeg2.c | 19 +++- 5 files changed, 135 insertions(+), 102 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index f5b0606a7d..fdb18cef0b 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -36,7 +36,6 @@ #define GST_VAAPI_ENCODE_FLOW_TIMEOUT GST_FLOW_CUSTOM_SUCCESS #define GST_VAAPI_ENCODE_FLOW_MEM_ERROR GST_FLOW_CUSTOM_ERROR #define GST_VAAPI_ENCODE_FLOW_CONVERT_ERROR GST_FLOW_CUSTOM_ERROR_1 -#define GST_VAAPI_ENCODE_FLOW_CODEC_DATA_ERROR GST_FLOW_CUSTOM_ERROR_2 GST_DEBUG_CATEGORY_STATIC (gst_vaapiencode_debug); #define GST_CAT_DEFAULT gst_vaapiencode_debug @@ -220,6 +219,40 @@ error_copy_buffer: } } +static gboolean +ensure_output_state (GstVaapiEncode * encode) +{ + GstVideoEncoder *const venc = GST_VIDEO_ENCODER_CAST (encode); + GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (encode); + GstVaapiEncoderStatus status; + GstCaps *out_caps; + + if (!encode->input_state_changed) + return TRUE; + + out_caps = klass->get_caps (encode); + if (!out_caps) + return FALSE; + + if (encode->output_state) + gst_video_codec_state_unref (encode->output_state); + encode->output_state = gst_video_encoder_set_output_state (venc, out_caps, + encode->input_state); + + status = gst_vaapi_encoder_get_codec_data (encode->encoder, + &encode->output_state->codec_data); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return FALSE; + +#if GST_CHECK_VERSION(1,0,0) + if (!gst_video_encoder_negotiate (venc)) + return FALSE; +#endif + + encode->input_state_changed = FALSE; + return TRUE; +} + static GstFlowReturn gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) { @@ -244,6 +277,12 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) gst_video_codec_frame_ref (out_frame); gst_video_codec_frame_set_user_data (out_frame, NULL, NULL); + /* Update output state */ + GST_VIDEO_ENCODER_STREAM_LOCK (encode); + if (!ensure_output_state (encode)) + goto error_output_state; + GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); + /* Allocate and copy buffer into system memory */ out_buffer = NULL; ret = klass->alloc_buffer (encode, @@ -255,35 +294,6 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) gst_buffer_replace (&out_frame->output_buffer, out_buffer); gst_buffer_unref (out_buffer); - /* Check output caps */ - GST_VIDEO_ENCODER_STREAM_LOCK (encode); - if (!encode->out_caps_done) { - GstVideoCodecState *old_state, *new_state; - GstBuffer *codec_data; - - status = gst_vaapi_encoder_get_codec_data (encode->encoder, &codec_data); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - goto error_codec_data; - - if (codec_data) { - encode->srcpad_caps = gst_caps_make_writable (encode->srcpad_caps); - gst_caps_set_simple (encode->srcpad_caps, - "codec_data", GST_TYPE_BUFFER, codec_data, NULL); - gst_buffer_unref (codec_data); - old_state = - gst_video_encoder_get_output_state (GST_VIDEO_ENCODER_CAST (encode)); - new_state = - gst_video_encoder_set_output_state (GST_VIDEO_ENCODER_CAST (encode), - gst_caps_ref (encode->srcpad_caps), old_state); - gst_video_codec_state_unref (old_state); - gst_video_codec_state_unref (new_state); - GST_DEBUG ("updated srcpad caps to: %" GST_PTR_FORMAT, - encode->srcpad_caps); - } - encode->out_caps_done = TRUE; - } - GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); - GST_DEBUG ("output:%" GST_TIME_FORMAT ", size:%zu", GST_TIME_ARGS (out_frame->pts), gst_buffer_get_size (out_buffer)); @@ -305,12 +315,12 @@ error_allocate_buffer: gst_video_codec_frame_unref (out_frame); return ret; } -error_codec_data: +error_output_state: { - GST_ERROR ("failed to construct codec-data (status %d)", status); + GST_ERROR ("failed to negotiate output state", status); GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); gst_video_codec_frame_unref (out_frame); - return GST_VAAPI_ENCODE_FLOW_CODEC_DATA_ERROR; + return GST_FLOW_NOT_NEGOTIATED; } } @@ -374,6 +384,15 @@ gst_vaapiencode_get_caps (GstVideoEncoder * venc, GstCaps * filter) static gboolean gst_vaapiencode_destroy (GstVaapiEncode * encode) { + if (encode->input_state) { + gst_video_codec_state_unref (encode->input_state); + encode->input_state = NULL; + } + + if (encode->output_state) { + gst_video_codec_state_unref (encode->output_state); + encode->output_state = NULL; + } gst_vaapi_encoder_replace (&encode->encoder, NULL); gst_caps_replace (&encode->sinkpad_caps, NULL); gst_caps_replace (&encode->srcpad_caps, NULL); @@ -446,19 +465,12 @@ gst_vaapiencode_update_sink_caps (GstVaapiEncode * encode, } static gboolean -gst_vaapiencode_update_src_caps (GstVaapiEncode * encode, - GstVideoCodecState * in_state) +set_codec_state (GstVaapiEncode * encode, GstVideoCodecState * state) { - GstVideoCodecState *out_state; - GstStructure *structure; - GstCaps *outcaps, *allowed_caps, *template_caps, *intersect; - GstVaapiEncoderStatus status; - GstBuffer *codec_data = NULL; + GstCaps *out_caps, *allowed_caps, *template_caps, *intersect; g_return_val_if_fail (encode->encoder, FALSE); - encode->out_caps_done = FALSE; - /* get peer caps for stream-format avc/bytestream, codec_data */ template_caps = gst_pad_get_pad_template_caps (encode->srcpad); allowed_caps = gst_pad_get_allowed_caps (encode->srcpad); @@ -467,38 +479,19 @@ gst_vaapiencode_update_src_caps (GstVaapiEncode * encode, gst_caps_unref (allowed_caps); /* codec data was not set */ - outcaps = gst_vaapi_encoder_set_format (encode->encoder, in_state, intersect); + out_caps = gst_vaapi_encoder_set_format (encode->encoder, state, intersect); gst_caps_unref (intersect); - g_return_val_if_fail (outcaps, FALSE); + g_return_val_if_fail (out_caps, FALSE); - if (!gst_caps_is_fixed (outcaps)) { + if (!gst_caps_is_fixed (out_caps)) { GST_ERROR ("encoder output caps was not fixed"); - gst_caps_unref (outcaps); + gst_caps_unref (out_caps); return FALSE; } - structure = gst_caps_get_structure (outcaps, 0); - if (!gst_structure_has_field (structure, "codec_data")) { - status = gst_vaapi_encoder_get_codec_data (encode->encoder, &codec_data); - if (status == GST_VAAPI_ENCODER_STATUS_SUCCESS) { - if (codec_data) { - outcaps = gst_caps_make_writable (outcaps); - gst_caps_set_simple (outcaps, - "codec_data", GST_TYPE_BUFFER, codec_data, NULL); - gst_buffer_replace (&codec_data, NULL); - } - encode->out_caps_done = TRUE; - } - } else - encode->out_caps_done = TRUE; - out_state = - gst_video_encoder_set_output_state (GST_VIDEO_ENCODER_CAST (encode), - outcaps, in_state); - - gst_caps_replace (&encode->srcpad_caps, out_state->caps); - gst_video_codec_state_unref (out_state); - - GST_DEBUG ("set srcpad caps to: %" GST_PTR_FORMAT, encode->srcpad_caps); + GST_DEBUG ("set srcpad caps to: %" GST_PTR_FORMAT, out_caps); + gst_caps_replace (&encode->srcpad_caps, out_caps); + gst_caps_unref (out_caps); return TRUE; } @@ -511,39 +504,25 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) if (!ensure_encoder (encode)) return FALSE; - if (!gst_vaapiencode_update_sink_caps (encode, state)) + if (!set_codec_state (encode, state)) return FALSE; - if (!gst_vaapiencode_update_src_caps (encode, state)) + + if (!gst_vaapiencode_update_sink_caps (encode, state)) return FALSE; if (!gst_vaapi_plugin_base_set_caps (GST_VAAPI_PLUGIN_BASE (encode), - encode->sinkpad_caps, encode->srcpad_caps)) + state->caps, NULL)) return FALSE; -#if GST_CHECK_VERSION(1,0,0) - if (encode->out_caps_done && !gst_video_encoder_negotiate (venc)) { - GST_ERROR ("failed to negotiate with caps %" GST_PTR_FORMAT, - encode->srcpad_caps); - return FALSE; - } -#endif + if (encode->input_state) + gst_video_codec_state_unref (encode->input_state); + encode->input_state = gst_video_codec_state_ref (state); + encode->input_state_changed = TRUE; return gst_pad_start_task (encode->srcpad, (GstTaskFunction) gst_vaapiencode_buffer_loop, encode, NULL); } -static gboolean -gst_vaapiencode_reset (GstVideoEncoder * venc, gboolean hard) -{ - GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); - - GST_DEBUG ("vaapiencode starting reset"); - - /* FIXME: compare sink_caps with encoder */ - encode->out_caps_done = FALSE; - return TRUE; -} - static GstFlowReturn gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GstVideoCodecFrame * frame) @@ -700,7 +679,6 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) venc_class->open = GST_DEBUG_FUNCPTR (gst_vaapiencode_open); venc_class->close = GST_DEBUG_FUNCPTR (gst_vaapiencode_close); venc_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_format); - venc_class->reset = GST_DEBUG_FUNCPTR (gst_vaapiencode_reset); venc_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapiencode_handle_frame); venc_class->finish = GST_DEBUG_FUNCPTR (gst_vaapiencode_finish); venc_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapiencode_get_caps); diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 91712af339..7ceffa314d 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -59,9 +59,10 @@ struct _GstVaapiEncode GstPadQueryFunction srcpad_query; GstVaapiEncoder *encoder; + GstVideoCodecState *input_state; + gboolean input_state_changed; + GstVideoCodecState *output_state; GPtrArray *prop_values; - - guint32 out_caps_done:1; }; struct _GstVaapiEncodeClass @@ -75,6 +76,7 @@ struct _GstVaapiEncodeClass gboolean (*set_property) (GstVaapiEncode * encode, guint prop_id, const GValue * value); + GstCaps * (*get_caps) (GstVaapiEncode * encode); GstVaapiEncoder * (*alloc_encoder) (GstVaapiEncode * encode, GstVaapiDisplay * display); GstFlowReturn (*alloc_buffer) (GstVaapiEncode * encode, diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 0d222b50dc..f64db7fc76 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -34,7 +34,9 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); #define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug -#define GST_CAPS_CODEC(CODEC) CODEC "; " +#define GST_CODEC_CAPS \ + "video/x-h264, " \ + "alignment = (string) au" /* *INDENT-OFF* */ static const char gst_vaapiencode_h264_sink_caps_str[] = @@ -57,7 +59,7 @@ static const char gst_vaapiencode_h264_sink_caps_str[] = /* *INDENT-OFF* */ static const char gst_vaapiencode_h264_src_caps_str[] = - GST_CAPS_CODEC ("video/x-h264"); + GST_CODEC_CAPS; /* *INDENT-ON* */ /* *INDENT-OFF* */ @@ -121,6 +123,39 @@ gst_vaapiencode_h264_get_property (GObject * object, } } +static GstCaps * +gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) +{ + GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base_encode); + GstCaps *caps, *allowed_caps; + + caps = gst_caps_from_string (GST_CODEC_CAPS); + + /* Check whether "stream-format" is avcC mode */ + allowed_caps = gst_pad_get_allowed_caps (base_encode->srcpad); + if (allowed_caps) { + const char *stream_format = NULL; + GstStructure *structure; + guint i, num_structures; + + num_structures = gst_caps_get_size (allowed_caps); + for (i = 0; !stream_format && i < num_structures; i++) { + structure = gst_caps_get_structure (allowed_caps, i); + if (!gst_structure_has_field_typed (structure, "stream-format", + G_TYPE_STRING)) + continue; + stream_format = gst_structure_get_string (structure, "stream-format"); + } + encode->is_avc = stream_format && strcmp (stream_format, "avc") == 0; + gst_caps_unref (allowed_caps); + } + gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, + encode->is_avc ? "avc" : "byte-stream", NULL); + + /* XXX: update profile and level information */ + return caps; +} + static GstVaapiEncoder * gst_vaapiencode_h264_alloc_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) @@ -221,21 +256,23 @@ error: } static GstFlowReturn -gst_vaapiencode_h264_alloc_buffer (GstVaapiEncode * encode, +gst_vaapiencode_h264_alloc_buffer (GstVaapiEncode * base_encode, GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buffer_ptr) { - GstVaapiEncoderH264 *const encoder = (GstVaapiEncoderH264 *) encode->encoder; + GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base_encode); + GstVaapiEncoderH264 *const encoder = (GstVaapiEncoderH264 *) + base_encode->encoder; GstFlowReturn ret; g_return_val_if_fail (encoder != NULL, GST_FLOW_ERROR); ret = GST_VAAPIENCODE_CLASS (gst_vaapiencode_h264_parent_class)->alloc_buffer - (encode, coded_buf, out_buffer_ptr); + (base_encode, coded_buf, out_buffer_ptr); if (ret != GST_FLOW_OK) return ret; - if (!gst_vaapi_encoder_h264_is_avc (encoder)) + if (!encode->is_avc) return GST_FLOW_OK; /* Convert to avcC format */ @@ -267,6 +304,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) object_class->get_property = gst_vaapiencode_h264_get_property; encode_class->get_properties = gst_vaapi_encoder_h264_get_default_properties; + encode_class->get_caps = gst_vaapiencode_h264_get_caps; encode_class->alloc_encoder = gst_vaapiencode_h264_alloc_encoder; encode_class->alloc_buffer = gst_vaapiencode_h264_alloc_buffer; diff --git a/gst/vaapi/gstvaapiencode_h264.h b/gst/vaapi/gstvaapiencode_h264.h index bf440bfd68..d30c065f80 100644 --- a/gst/vaapi/gstvaapiencode_h264.h +++ b/gst/vaapi/gstvaapiencode_h264.h @@ -52,6 +52,8 @@ struct _GstVaapiEncodeH264 { /*< private >*/ GstVaapiEncode parent_instance; + + guint is_avc:1; /* [FALSE]=byte-stream (default); [TRUE]=avcC */ }; struct _GstVaapiEncodeH264Class diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 7579b2ac06..b84821c2c7 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -34,7 +34,9 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); #define GST_CAT_DEFAULT gst_vaapi_mpeg2_encode_debug -#define GST_CAPS_CODEC(CODEC) CODEC "; " +#define GST_CODEC_CAPS \ + "video/mpeg, mpegversion = (int) 2, " \ + "systemstream = (boolean) false" /* *INDENT-OFF* */ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = @@ -57,8 +59,7 @@ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = /* *INDENT-OFF* */ static const char gst_vaapiencode_mpeg2_src_caps_str[] = - GST_CAPS_CODEC ("video/mpeg, mpegversion = (int) 2, " - "systemstream = (boolean) false"); + GST_CODEC_CAPS; /* *INDENT-ON* */ /* *INDENT-OFF* */ @@ -123,6 +124,17 @@ gst_vaapiencode_mpeg2_get_property (GObject * object, } } +static GstCaps * +gst_vaapiencode_mpeg2_get_caps (GstVaapiEncode * base_encode) +{ + GstCaps *caps; + + caps = gst_caps_from_string (GST_CODEC_CAPS); + + /* XXX: update profile and level information */ + return caps; +} + static GstVaapiEncoder * gst_vaapiencode_mpeg2_alloc_encoder (GstVaapiEncode * base, GstVaapiDisplay * display) @@ -145,6 +157,7 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) object_class->get_property = gst_vaapiencode_mpeg2_get_property; encode_class->get_properties = gst_vaapi_encoder_mpeg2_get_default_properties; + encode_class->get_caps = gst_vaapiencode_mpeg2_get_caps; encode_class->alloc_encoder = gst_vaapiencode_mpeg2_alloc_encoder; gst_element_class_set_static_metadata (element_class, From ea7c1d87c5e578adf6e1ac24fe136f453134049d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 9 Jan 2014 18:20:24 +0100 Subject: [PATCH 1502/3781] vaapiencode: use more GstVaapiPluginBase facilities. Avoid duplication of pad references or query functions since they are provided through the GstVaapiPluginBase object. --- gst/vaapi/gstvaapiencode.c | 74 ++++++++++++--------------------- gst/vaapi/gstvaapiencode.h | 8 ---- gst/vaapi/gstvaapiencode_h264.c | 3 +- 3 files changed, 28 insertions(+), 57 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index fdb18cef0b..b482aefbfa 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -70,22 +70,22 @@ ensure_uploader (GstVaapiEncode * encode) static gboolean gst_vaapiencode_query (GST_PAD_QUERY_FUNCTION_ARGS) { - GstVaapiEncode *const encode = - GST_VAAPIENCODE_CAST (gst_pad_get_parent_element (pad)); + GstVaapiPluginBase *const plugin = + GST_VAAPI_PLUGIN_BASE (gst_pad_get_parent_element (pad)); gboolean success; - GST_INFO_OBJECT (encode, "query type %s", GST_QUERY_TYPE_NAME (query)); + GST_INFO_OBJECT (plugin, "query type %s", GST_QUERY_TYPE_NAME (query)); - if (gst_vaapi_reply_to_query (query, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode))) + if (gst_vaapi_reply_to_query (query, plugin->display)) success = TRUE; else if (GST_PAD_IS_SINK (pad)) - success = GST_PAD_QUERY_FUNCTION_CALL (encode->sinkpad_query, - encode->sinkpad, parent, query); + success = GST_PAD_QUERY_FUNCTION_CALL (plugin->sinkpad_query, + plugin->sinkpad, parent, query); else - success = GST_PAD_QUERY_FUNCTION_CALL (encode->srcpad_query, - encode->srcpad, parent, query); + success = GST_PAD_QUERY_FUNCTION_CALL (plugin->srcpad_query, + plugin->srcpad, parent, query); - gst_object_unref (encode); + gst_object_unref (plugin); return success; } @@ -334,25 +334,25 @@ gst_vaapiencode_buffer_loop (GstVaapiEncode * encode) if (ret == GST_FLOW_OK || ret == GST_VAAPI_ENCODE_FLOW_TIMEOUT) return; - gst_pad_pause_task (encode->srcpad); + gst_pad_pause_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); } static GstCaps * gst_vaapiencode_get_caps_impl (GstVideoEncoder * venc) { - GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (venc); GstCaps *caps; - if (encode->sinkpad_caps) - caps = gst_caps_ref (encode->sinkpad_caps); + if (plugin->sinkpad_caps) + caps = gst_caps_ref (plugin->sinkpad_caps); else { #if GST_CHECK_VERSION(1,0,0) - caps = gst_pad_get_pad_template_caps (encode->sinkpad); + caps = gst_pad_get_pad_template_caps (plugin->sinkpad); #else caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS); - if (caps && ensure_uploader (encode)) { - GstCaps *const yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS (encode); + if (caps && ensure_uploader (GST_VAAPIENCODE_CAST (plugin))) { + GstCaps *const yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS (plugin); if (yuv_caps) { caps = gst_caps_make_writable (caps); gst_caps_append (caps, gst_caps_copy (yuv_caps)); @@ -394,8 +394,6 @@ gst_vaapiencode_destroy (GstVaapiEncode * encode) encode->output_state = NULL; } gst_vaapi_encoder_replace (&encode->encoder, NULL); - gst_caps_replace (&encode->sinkpad_caps, NULL); - gst_caps_replace (&encode->srcpad_caps, NULL); return TRUE; } @@ -456,24 +454,17 @@ gst_vaapiencode_close (GstVideoEncoder * venc) return TRUE; } -static inline gboolean -gst_vaapiencode_update_sink_caps (GstVaapiEncode * encode, - GstVideoCodecState * state) -{ - gst_caps_replace (&encode->sinkpad_caps, state->caps); - return TRUE; -} - static gboolean set_codec_state (GstVaapiEncode * encode, GstVideoCodecState * state) { + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (encode); GstCaps *out_caps, *allowed_caps, *template_caps, *intersect; g_return_val_if_fail (encode->encoder, FALSE); /* get peer caps for stream-format avc/bytestream, codec_data */ - template_caps = gst_pad_get_pad_template_caps (encode->srcpad); - allowed_caps = gst_pad_get_allowed_caps (encode->srcpad); + template_caps = gst_pad_get_pad_template_caps (plugin->srcpad); + allowed_caps = gst_pad_get_allowed_caps (plugin->srcpad); intersect = gst_caps_intersect (template_caps, allowed_caps); gst_caps_unref (template_caps); gst_caps_unref (allowed_caps); @@ -490,7 +481,6 @@ set_codec_state (GstVaapiEncode * encode, GstVideoCodecState * state) } GST_DEBUG ("set srcpad caps to: %" GST_PTR_FORMAT, out_caps); - gst_caps_replace (&encode->srcpad_caps, out_caps); gst_caps_unref (out_caps); return TRUE; } @@ -507,9 +497,6 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) if (!set_codec_state (encode, state)) return FALSE; - if (!gst_vaapiencode_update_sink_caps (encode, state)) - return FALSE; - if (!gst_vaapi_plugin_base_set_caps (GST_VAAPI_PLUGIN_BASE (encode), state->caps, NULL)) return FALSE; @@ -519,7 +506,7 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) encode->input_state = gst_video_codec_state_ref (state); encode->input_state_changed = TRUE; - return gst_pad_start_task (encode->srcpad, + return gst_pad_start_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode), (GstTaskFunction) gst_vaapiencode_buffer_loop, encode, NULL); } @@ -603,7 +590,7 @@ gst_vaapiencode_finish (GstVideoEncoder * venc) status = gst_vaapi_encoder_flush (encode->encoder); GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); - gst_pad_stop_task (encode->srcpad); + gst_pad_stop_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); GST_VIDEO_ENCODER_STREAM_LOCK (encode); while (status == GST_VAAPI_ENCODER_STATUS_SUCCESS && ret == GST_FLOW_OK) @@ -638,9 +625,6 @@ gst_vaapiencode_finalize (GObject * object) encode->prop_values = NULL; } - encode->sinkpad = NULL; - encode->srcpad = NULL; - gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (object)); G_OBJECT_CLASS (gst_vaapiencode_parent_class)->finalize (object); } @@ -648,19 +632,13 @@ gst_vaapiencode_finalize (GObject * object) static void gst_vaapiencode_init (GstVaapiEncode * encode) { + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (encode); + gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (encode), GST_CAT_DEFAULT); - /* sink pad */ - encode->sinkpad = GST_VIDEO_ENCODER_SINK_PAD (encode); - encode->sinkpad_query = GST_PAD_QUERYFUNC (encode->sinkpad); - gst_pad_set_query_function (encode->sinkpad, gst_vaapiencode_query); - - /* src pad */ - encode->srcpad = GST_VIDEO_ENCODER_SRC_PAD (encode); - encode->srcpad_query = GST_PAD_QUERYFUNC (encode->srcpad); - gst_pad_set_query_function (encode->srcpad, gst_vaapiencode_query); - - gst_pad_use_fixed_caps (encode->srcpad); + gst_pad_set_query_function (plugin->sinkpad, gst_vaapiencode_query); + gst_pad_set_query_function (plugin->srcpad, gst_vaapiencode_query); + gst_pad_use_fixed_caps (plugin->srcpad); } static void diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 7ceffa314d..8f78a75e5f 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -50,14 +50,6 @@ struct _GstVaapiEncode /*< private >*/ GstVaapiPluginBase parent_instance; - GstPad *sinkpad; - GstCaps *sinkpad_caps; - GstPadQueryFunction sinkpad_query; - - GstPad *srcpad; - GstCaps *srcpad_caps; - GstPadQueryFunction srcpad_query; - GstVaapiEncoder *encoder; GstVideoCodecState *input_state; gboolean input_state_changed; diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index f64db7fc76..3e525d30e9 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -132,7 +132,8 @@ gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) caps = gst_caps_from_string (GST_CODEC_CAPS); /* Check whether "stream-format" is avcC mode */ - allowed_caps = gst_pad_get_allowed_caps (base_encode->srcpad); + allowed_caps = + gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); if (allowed_caps) { const char *stream_format = NULL; GstStructure *structure; From 2c4fde0eae02383a9780e8e87ce1e3d442bf80ce Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 13 Jan 2014 17:18:42 +0100 Subject: [PATCH 1503/3781] vaapiencode: don't crash on NULL encoder on _finish(). Don't try to destroy an encoder, in GstVideoEncoder::finish() handler, if it was not created in the first place. Return "not-negotiated" error since this means we did not even reach GstVideoEncoder::set_format(), where the encoder could have been created. This fixes a crash when the vaapiencode_* plug-in elements get deallocated and that we failed to negotiate either pad. https://bugzilla.gnome.org/show_bug.cgi?id=719704 --- gst/vaapi/gstvaapiencode.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index b482aefbfa..e4b52f4a33 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -587,6 +587,13 @@ gst_vaapiencode_finish (GstVideoEncoder * venc) GstVaapiEncoderStatus status; GstFlowReturn ret = GST_FLOW_OK; + /* Don't try to destroy encoder if none was created in the first place. + Return "not-negotiated" error since this means we did not even reach + GstVideoEncoder::set_format() state, where the encoder could have + been created */ + if (!encode->encoder) + return GST_FLOW_NOT_NEGOTIATED; + status = gst_vaapi_encoder_flush (encode->encoder); GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); From 5394c75461073a83f28bc92060977f334f034191 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 10 Jan 2014 10:54:22 +0100 Subject: [PATCH 1504/3781] encoder: add video codec-state API. Add interface to communicate the encoder resolution and related info like framerate, interlaced vs. progressive, etc. This new interface supersedes gst_vaapi_encoder_set_format() and doesn't use any GstCaps but rather use GstVideoCodecState. Note that gst_vaapi_encoder_set_codec_state() is also a synchronization point for codec config. This means that the encoder is reconfigured there to match the latest properties. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 170 ++++++++++++++------- gst-libs/gst/vaapi/gstvaapiencoder.h | 6 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 70 +-------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 50 +----- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 69 +++++++-- gst/vaapi/gstvaapiencode.c | 27 +--- gst/vaapi/gstvaapiencode.h | 1 + 7 files changed, 194 insertions(+), 199 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 2e6def042b..555eaf0b03 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -416,16 +416,35 @@ gst_vaapi_encoder_get_codec_data (GstVaapiEncoder * encoder, return ret; } -/* Ensures the underlying VA context for encoding is created */ -static gboolean -gst_vaapi_encoder_ensure_context (GstVaapiEncoder * encoder) +/* Checks video info */ +static GstVaapiEncoderStatus +check_video_info (GstVaapiEncoder * encoder, const GstVideoInfo * vip) +{ + if (!vip->width || !vip->height) + goto error_invalid_resolution; + if (!vip->fps_n || !vip->fps_d) + goto error_invalid_framerate; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +error_invalid_resolution: + { + GST_ERROR ("invalid resolution (%dx%d)", vip->width, vip->height); + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } +error_invalid_framerate: + { + GST_ERROR ("invalid framerate (%d/%d)", vip->fps_n, vip->fps_d); + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } +} + +/* Updates video context */ +static void +set_context_info (GstVaapiEncoder * encoder) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); GstVaapiContextInfo *const cip = &encoder->context_info; - GstVaapiContext *context; - - if (GST_VAAPI_ENCODER_CONTEXT (encoder)) - return TRUE; cip->profile = GST_VAAPI_PROFILE_UNKNOWN; cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; @@ -434,72 +453,107 @@ gst_vaapi_encoder_ensure_context (GstVaapiEncoder * encoder) cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); cip->ref_frames = 0; klass->set_context_info (encoder); +} - context = gst_vaapi_context_new_full (encoder->display, cip); - if (!context) - return FALSE; +/* Ensures the underlying VA context for encoding is created */ +static gboolean +gst_vaapi_encoder_ensure_context (GstVaapiEncoder * encoder) +{ + GstVaapiContextInfo *const cip = &encoder->context_info; - GST_VAAPI_ENCODER_CONTEXT (encoder) = context; - GST_VAAPI_ENCODER_VA_CONTEXT (encoder) = gst_vaapi_context_get_id (context); + set_context_info (encoder); + + if (encoder->context) { + if (!gst_vaapi_context_reset_full (encoder->context, cip)) + return FALSE; + } else { + encoder->context = gst_vaapi_context_new_full (encoder->display, cip); + if (!encoder->context) + return FALSE; + } + encoder->va_context = gst_vaapi_context_get_id (encoder->context); return TRUE; } -/** - * gst_vaapi_encoder_set_format: - * @encoder: a #GstVaapiEncoder - * @state : a #GstVideoCodecState - * @ref_caps: the set of reference caps (from pad template) - * - * Notifies the encoder of incoming data format (video resolution), - * and additional information like framerate. - * - * Return value: the newly allocated set of caps - */ -GstCaps * -gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, - GstVideoCodecState * state, GstCaps * ref_caps) +/* Reconfigures the encoder with the new properties */ +static GstVaapiEncoderStatus +gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); - GstCaps *out_caps = NULL; + GstVaapiEncoderStatus status; - if (!GST_VIDEO_INFO_WIDTH (&state->info) || - !GST_VIDEO_INFO_HEIGHT (&state->info)) { - GST_WARNING ("encoder set format failed, width or height equal to 0."); - return NULL; - } - GST_VAAPI_ENCODER_VIDEO_INFO (encoder) = state->info; - - out_caps = klass->set_format (encoder, state, ref_caps); - if (!out_caps) - goto error; - - if (GST_VAAPI_ENCODER_CAPS (encoder) && - gst_caps_is_equal (out_caps, GST_VAAPI_ENCODER_CAPS (encoder))) { - gst_caps_unref (out_caps); - return GST_VAAPI_ENCODER_CAPS (encoder); - } - gst_caps_replace (&GST_VAAPI_ENCODER_CAPS (encoder), out_caps); - g_assert (GST_VAAPI_ENCODER_CONTEXT (encoder) == NULL); - gst_vaapi_object_replace (&GST_VAAPI_ENCODER_CONTEXT (encoder), NULL); + status = klass->reconfigure (encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; if (!gst_vaapi_encoder_ensure_context (encoder)) - goto error; + goto error_reset_context; encoder->codedbuf_pool = gst_vaapi_coded_buffer_pool_new (encoder, encoder->codedbuf_size); - if (!encoder->codedbuf_pool) { - GST_ERROR ("failed to initialized coded buffer pool"); - goto error; - } + if (!encoder->codedbuf_pool) + goto error_codedbuf_pool_allocation_failed; + gst_vaapi_video_pool_set_capacity (encoder->codedbuf_pool, 5); + return GST_VAAPI_ENCODER_STATUS_SUCCESS; - return out_caps; + /* ERRORS */ +error_codedbuf_pool_allocation_failed: + { + GST_ERROR ("failed to initialize coded buffer pool"); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_reset_context: + { + GST_ERROR ("failed to update VA context"); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } +} -error: - gst_caps_replace (&GST_VAAPI_ENCODER_CAPS (encoder), NULL); - gst_caps_replace (&out_caps, NULL); - GST_ERROR ("encoder set format failed"); - return NULL; +/** + * gst_vaapi_encoder_set_codec_state: + * @encoder: a #GstVaapiEncoder + * @state : a #GstVideoCodecState + * + * Notifies the encoder about the source surface properties. The + * accepted set of properties is: video resolution, colorimetry, + * pixel-aspect-ratio and framerate. + * + * This function is a synchronization point for codec configuration. + * This means that, at this point, the encoder is reconfigured to + * match the new properties and any other change beyond this point has + * zero effect. + * + * Return value: a #GstVaapiEncoderStatus + */ +GstVaapiEncoderStatus +gst_vaapi_encoder_set_codec_state (GstVaapiEncoder * encoder, + GstVideoCodecState * state) +{ + GstVaapiEncoderStatus status; + + g_return_val_if_fail (encoder != NULL, + GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (state != NULL, + GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER); + + if (encoder->num_codedbuf_queued > 0) + goto error_operation_failed; + + if (!gst_video_info_is_equal (&state->info, &encoder->video_info)) { + status = check_video_info (encoder, &state->info); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + encoder->video_info = state->info; + } + return gst_vaapi_encoder_reconfigure_internal (encoder); + + /* ERRORS */ +error_operation_failed: + { + GST_ERROR ("could not change codec state after encoding started"); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } } /** @@ -762,11 +816,11 @@ gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) CHECK_VTABLE_HOOK (init); CHECK_VTABLE_HOOK (finalize); CHECK_VTABLE_HOOK (get_default_properties); + CHECK_VTABLE_HOOK (reconfigure); CHECK_VTABLE_HOOK (encode); CHECK_VTABLE_HOOK (reordering); CHECK_VTABLE_HOOK (flush); CHECK_VTABLE_HOOK (set_context_info); - CHECK_VTABLE_HOOK (set_format); #undef CHECK_VTABLE_HOOK diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index a4dbe3ad16..8f6e6ae1e0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -106,9 +106,9 @@ GstVaapiEncoderStatus gst_vaapi_encoder_get_codec_data (GstVaapiEncoder * encoder, GstBuffer ** out_codec_data_ptr); -GstCaps * -gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder, - GstVideoCodecState * state, GstCaps * ref_caps); +GstVaapiEncoderStatus +gst_vaapi_encoder_set_codec_state (GstVaapiEncoder * encoder, + GstVideoCodecState * state); GstVaapiEncoderStatus gst_vaapi_encoder_set_property (GstVaapiEncoder * encoder, gint prop_id, diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 420a0e35f8..e2323a78ee 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -82,14 +82,6 @@ typedef struct guint frame_num; } GstVaapiEncoderH264Ref; -#define GST_VAAPI_H264_CAPS \ - "video/x-h264, " \ - "framerate = (fraction) [0/1, MAX], " \ - "width = (int) [ 1, MAX ], " \ - "height = (int) [ 1, MAX ], " \ - "stream-format = (string) { avc, byte-stream }, " \ - "alignment = (string) { au } " - typedef enum { GST_VAAPI_ENC_H264_REORD_NONE = 0, @@ -1262,12 +1254,6 @@ init_encoder_public_attributes (GstVaapiEncoderH264 * encoder) GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); guint width_mbs, height_mbs, total_mbs; - if (!GST_VAAPI_ENCODER_WIDTH (encoder) || - !GST_VAAPI_ENCODER_HEIGHT (encoder) || - !GST_VAAPI_ENCODER_FPS_N (encoder) || - !GST_VAAPI_ENCODER_FPS_D (encoder)) { - return FALSE; - } if (!encoder->profile) encoder->profile = GST_VAAPI_ENCODER_H264_DEFAULT_PROFILE; @@ -1317,7 +1303,7 @@ init_encoder_public_attributes (GstVaapiEncoderH264 * encoder) } static gboolean -init_encoder_private_attributes (GstVaapiEncoderH264 * encoder, GstCaps * caps) +init_encoder_private_attributes (GstVaapiEncoderH264 * encoder) { if (encoder->b_frame_num) encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) / @@ -1625,65 +1611,25 @@ gst_vaapi_encoder_h264_set_context_info (GstVaapiEncoder * base_encoder) GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); } -static GstCaps * -gst_vaapi_encoder_h264_set_format (GstVaapiEncoder * base, - GstVideoCodecState * in_state, GstCaps * ref_caps) +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH264 *encoder; - GstCaps *result = NULL, *tmp; - GstStructure *structure; - const GValue *value; - const gchar *stream_format; - - encoder = GST_VAAPI_ENCODER_H264 (base); - - tmp = gst_caps_from_string ("video/x-h264"); - gst_caps_set_simple (tmp, - "width", G_TYPE_INT, GST_VAAPI_ENCODER_WIDTH (encoder), - "height", G_TYPE_INT, GST_VAAPI_ENCODER_HEIGHT (encoder), - "framerate", GST_TYPE_FRACTION, - GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder), - NULL); - result = gst_caps_intersect (tmp, ref_caps); - gst_caps_unref (tmp); - - /* fixed stream-format and choose byte-stream first */ - structure = gst_caps_get_structure (result, 0); - value = gst_structure_get_value (structure, "stream-format"); - if (value) { - gst_structure_fixate_field_string (structure, "stream-format", - "byte-stream"); - stream_format = gst_structure_get_string (structure, "stream-format"); - } else { - stream_format = "byte-stream"; - gst_structure_set (structure, "stream-format", G_TYPE_STRING, stream_format, - NULL); - } - - if (strcmp (stream_format, "byte-stream") == 0) - encoder->is_avc = FALSE; - else /* need codec data later */ - encoder->is_avc = TRUE; - -#if GST_CHECK_VERSION(1,0,0) - result = gst_caps_fixate (result); -#endif + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264_CAST (base_encoder); if (!init_encoder_public_attributes (encoder)) { GST_WARNING ("encoder ensure public attributes failed "); goto error; } - if (!init_encoder_private_attributes (encoder, result)) { + if (!init_encoder_private_attributes (encoder)) { GST_WARNING ("prepare encoding failed "); goto error; } - - return result; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; error: - gst_caps_unref (result); - return NULL; + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index fb7e042eff..047289b4b8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -107,13 +107,6 @@ ensure_public_attributes (GstVaapiEncoderMpeg2 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - if (!GST_VAAPI_ENCODER_WIDTH (encoder) || - !GST_VAAPI_ENCODER_HEIGHT (encoder) || - !GST_VAAPI_ENCODER_FPS_N (encoder) || - !GST_VAAPI_ENCODER_FPS_D (encoder)) { - return FALSE; - } - if (encoder->ip_period > encoder->intra_period) { encoder->ip_period = encoder->intra_period - 1; } @@ -680,51 +673,20 @@ gst_vaapi_encoder_mpeg2_set_context_info (GstVaapiEncoder * base_encoder) MAX_SLICE_HDR_SIZE; } -static gboolean -prepare_encoding (GstVaapiEncoderMpeg2 * encoder, GstCaps * caps) +static GstVaapiEncoderStatus +gst_vaapi_encoder_mpeg2_reconfigure (GstVaapiEncoder * base_encoder) { - return TRUE; -} - -static GstCaps * -gst_vaapi_encoder_mpeg2_set_format (GstVaapiEncoder * base, - GstVideoCodecState * in_state, GstCaps * ref_caps) -{ - GstVaapiEncoderMpeg2 *encoder; - GstCaps *result = NULL, *tmp; - encoder = GST_VAAPI_ENCODER_MPEG2 (base); - - tmp = gst_caps_from_string ("video/mpeg"); - gst_caps_set_simple (tmp, - "mpegversion", G_TYPE_INT, 2, - "systemstream", G_TYPE_BOOLEAN, FALSE, - "width", G_TYPE_INT, GST_VAAPI_ENCODER_WIDTH (encoder), - "height", G_TYPE_INT, GST_VAAPI_ENCODER_HEIGHT (encoder), - "framerate", GST_TYPE_FRACTION, - GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder), - NULL); - result = gst_caps_intersect (tmp, ref_caps); - gst_caps_unref (tmp); - -#if GST_CHECK_VERSION(1,0,0) - result = gst_caps_fixate (result); -#endif + GstVaapiEncoderMpeg2 *const encoder = + GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); if (!ensure_public_attributes (encoder)) { GST_WARNING ("encoder ensure public attributes failed "); goto error; } - - if (!prepare_encoding (encoder, result)) { - GST_WARNING ("prepare encoding failed "); - goto error; - } - - return result; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; error: - gst_caps_unref (result); - return NULL; + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 0238ac1b02..98bbee3874 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -55,12 +55,60 @@ G_BEGIN_DECLS #define GST_VAAPI_ENCODER_VA_CONTEXT(encoder) \ (GST_VAAPI_ENCODER_CAST(encoder)->va_context) -#define GST_VAAPI_ENCODER_VIDEO_INFO(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info) -#define GST_VAAPI_ENCODER_CAPS(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->caps) -#define GST_VAAPI_ENCODER_WIDTH(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info.width) -#define GST_VAAPI_ENCODER_HEIGHT(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info.height) -#define GST_VAAPI_ENCODER_FPS_N(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info.fps_n) -#define GST_VAAPI_ENCODER_FPS_D(encoder) (GST_VAAPI_ENCODER_CAST(encoder)->video_info.fps_d) +/** + * 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: @@ -113,7 +161,6 @@ struct _GstVaapiEncoder GstVaapiDisplay *display; GstVaapiContext *context; GstVaapiContextInfo context_info; - GstCaps *caps; VADisplay va_display; VAContextID va_context; @@ -157,12 +204,10 @@ struct _GstVaapiEncoderClass gboolean (*init) (GstVaapiEncoder * encoder); void (*finalize) (GstVaapiEncoder * encoder); - GstCaps * (*set_format) (GstVaapiEncoder * encoder, - GstVideoCodecState * in_state, - GstCaps * ref_caps); - void (*set_context_info) (GstVaapiEncoder * encoder); + GstVaapiEncoderStatus (*reconfigure) (GstVaapiEncoder * encoder); + GPtrArray * (*get_default_properties) (void); GstVaapiEncoderStatus (*set_property) (GstVaapiEncoder * encoder, gint prop_id, @@ -196,8 +241,8 @@ struct _GstVaapiEncoderClass .class_data = &g_class_data, \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, init), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, finalize), \ + GST_VAAPI_ENCODER_CLASS_HOOK (codec, reconfigure), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, get_default_properties), \ - GST_VAAPI_ENCODER_CLASS_HOOK (codec, set_format), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, set_context_info), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, reordering), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, encode), \ diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index e4b52f4a33..0782ca18c9 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -457,31 +457,18 @@ gst_vaapiencode_close (GstVideoEncoder * venc) static gboolean set_codec_state (GstVaapiEncode * encode, GstVideoCodecState * state) { - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (encode); - GstCaps *out_caps, *allowed_caps, *template_caps, *intersect; + GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (encode); + GstVaapiEncoderStatus status; g_return_val_if_fail (encode->encoder, FALSE); - /* get peer caps for stream-format avc/bytestream, codec_data */ - template_caps = gst_pad_get_pad_template_caps (plugin->srcpad); - allowed_caps = gst_pad_get_allowed_caps (plugin->srcpad); - intersect = gst_caps_intersect (template_caps, allowed_caps); - gst_caps_unref (template_caps); - gst_caps_unref (allowed_caps); - - /* codec data was not set */ - out_caps = gst_vaapi_encoder_set_format (encode->encoder, state, intersect); - gst_caps_unref (intersect); - g_return_val_if_fail (out_caps, FALSE); - - if (!gst_caps_is_fixed (out_caps)) { - GST_ERROR ("encoder output caps was not fixed"); - gst_caps_unref (out_caps); + /* Initialize codec specific parameters */ + if (klass->set_config && !klass->set_config (encode)) return FALSE; - } - GST_DEBUG ("set srcpad caps to: %" GST_PTR_FORMAT, out_caps); - gst_caps_unref (out_caps); + status = gst_vaapi_encoder_set_codec_state (encode->encoder, state); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return FALSE; return TRUE; } diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 8f78a75e5f..cab65c0629 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -68,6 +68,7 @@ struct _GstVaapiEncodeClass gboolean (*set_property) (GstVaapiEncode * encode, guint prop_id, const GValue * value); + gboolean (*set_config) (GstVaapiEncode * encode); GstCaps * (*get_caps) (GstVaapiEncode * encode); GstVaapiEncoder * (*alloc_encoder) (GstVaapiEncode * encode, GstVaapiDisplay * display); From 20ab910d15b4d748ed747ebbdedfbfa2d5f9bf9f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 10 Jan 2014 11:30:25 +0100 Subject: [PATCH 1505/3781] encoder: fix possible memory leak of coded buffer pools. Fix gst_vaapi_encoder_reconfigure_internal() to re-/allocate the coded buffer pool only if the coded buffer size actually changed. --- gst-libs/gst/vaapi/gstvaapicodedbufferpool.c | 17 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapicodedbufferpool.h | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder.c | 21 +++++++++++++------- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c index c5a8acdefc..44b2e3d7b6 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c @@ -111,3 +111,20 @@ gst_vaapi_coded_buffer_pool_new (GstVaapiEncoder * encoder, gsize buf_size) 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; +} diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.h b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.h index 3480d48677..0185ee3806 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.h +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.h @@ -37,6 +37,9 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 555eaf0b03..7d194580ac 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -481,6 +481,8 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); GstVaapiEncoderStatus status; + GstVaapiVideoPool *pool; + guint codedbuf_size; status = klass->reconfigure (encoder); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) @@ -489,16 +491,21 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) if (!gst_vaapi_encoder_ensure_context (encoder)) goto error_reset_context; - encoder->codedbuf_pool = gst_vaapi_coded_buffer_pool_new (encoder, - encoder->codedbuf_size); - if (!encoder->codedbuf_pool) - goto error_codedbuf_pool_allocation_failed; - - gst_vaapi_video_pool_set_capacity (encoder->codedbuf_pool, 5); + codedbuf_size = encoder->codedbuf_pool ? + gst_vaapi_coded_buffer_pool_get_buffer_size (GST_VAAPI_CODED_BUFFER_POOL + (encoder)) : 0; + if (codedbuf_size != encoder->codedbuf_size) { + pool = gst_vaapi_coded_buffer_pool_new (encoder, encoder->codedbuf_size); + if (!pool) + goto error_alloc_codedbuf_pool; + gst_vaapi_video_pool_set_capacity (pool, 5); + gst_vaapi_video_pool_replace (&encoder->codedbuf_pool, pool); + gst_vaapi_video_pool_unref (pool); + } return GST_VAAPI_ENCODER_STATUS_SUCCESS; /* ERRORS */ -error_codedbuf_pool_allocation_failed: +error_alloc_codedbuf_pool: { GST_ERROR ("failed to initialize coded buffer pool"); return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; From 8788ea99a87c61d48ce1f411f49b4b9c1489fc66 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 10 Jan 2014 12:01:51 +0100 Subject: [PATCH 1506/3781] encoder: improve codec reconfiguration. Improve codec reconfiguration to be performed only through a single function. That is, remove the _set_context_info() hook as subclass should not alter the parent GstVaapiContextInfo itself. Besides, the VA context is constructed only at the final stages of reconfigure(). --- gst-libs/gst/vaapi/gstvaapiencoder.c | 7 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 82 ++++++++++++---------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 67 ++++++++++-------- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 5 +- 4 files changed, 86 insertions(+), 75 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 7d194580ac..d629da1ade 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -443,16 +443,14 @@ error_invalid_framerate: static void set_context_info (GstVaapiEncoder * encoder) { - GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); GstVaapiContextInfo *const cip = &encoder->context_info; - cip->profile = GST_VAAPI_PROFILE_UNKNOWN; + cip->profile = encoder->profile; cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; cip->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); cip->width = GST_VAAPI_ENCODER_WIDTH (encoder); cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); - cip->ref_frames = 0; - klass->set_context_info (encoder); + cip->ref_frames = encoder->num_ref_frames; } /* Ensures the underlying VA context for encoding is created */ @@ -827,7 +825,6 @@ gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) CHECK_VTABLE_HOOK (encode); CHECK_VTABLE_HOOK (reordering); CHECK_VTABLE_HOOK (flush); - CHECK_VTABLE_HOOK (set_context_info); #undef CHECK_VTABLE_HOOK diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index e2323a78ee..ad79f7c54c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1248,16 +1248,43 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) return TRUE; } -gboolean -init_encoder_public_attributes (GstVaapiEncoderH264 * encoder) +static gboolean +ensure_profile_and_level (GstVaapiEncoderH264 * encoder) { - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - guint width_mbs, height_mbs, total_mbs; - if (!encoder->profile) encoder->profile = GST_VAAPI_ENCODER_H264_DEFAULT_PROFILE; _set_level (encoder); + return TRUE; +} + +static gboolean +ensure_bitrate (GstVaapiEncoderH264 * 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: + case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: + if (!base_encoder->bitrate) + base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * + GST_VAAPI_ENCODER_HEIGHT (encoder) * + GST_VAAPI_ENCODER_FPS_N (encoder) / + GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024; + break; + default: + base_encoder->bitrate = 0; + break; + } + return TRUE; +} + +static void +reset_properties (GstVaapiEncoderH264 * encoder) +{ + guint width_mbs, height_mbs, total_mbs; if (encoder->intra_period > GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD) encoder->intra_period = GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD; @@ -1272,19 +1299,6 @@ init_encoder_public_attributes (GstVaapiEncoderH264 * encoder) encoder->min_qp < encoder->init_qp)) encoder->min_qp = encoder->init_qp; - /* default compress ratio 1: (4*8*1.5) */ - if (GST_VAAPI_RATECONTROL_CBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) || - GST_VAAPI_RATECONTROL_VBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) || - GST_VAAPI_RATECONTROL_VBR_CONSTRAINED == - GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { - if (!base_encoder->bitrate) - base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * - GST_VAAPI_ENCODER_HEIGHT (encoder) * - GST_VAAPI_ENCODER_FPS_N (encoder) / - GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024; - } else - base_encoder->bitrate = 0; - width_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; height_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; total_mbs = width_mbs * height_mbs; @@ -1299,12 +1313,6 @@ init_encoder_public_attributes (GstVaapiEncoderH264 * encoder) if (encoder->b_frame_num > 50) encoder->b_frame_num = 50; - return TRUE; -} - -static gboolean -init_encoder_private_attributes (GstVaapiEncoderH264 * encoder) -{ if (encoder->b_frame_num) encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) / GST_VAAPI_ENCODER_FPS_N (encoder); @@ -1327,7 +1335,6 @@ init_encoder_private_attributes (GstVaapiEncoderH264 * encoder) encoder->max_reflist1_count = 0; encoder->max_ref_num = encoder->max_reflist0_count + encoder->max_reflist1_count; - return TRUE; } @@ -1572,10 +1579,10 @@ end: } static void -gst_vaapi_encoder_h264_set_context_info (GstVaapiEncoder * base_encoder) +set_context_info (GstVaapiEncoder * base_encoder) { GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); - GstVaapiContextInfo *const cip = &base_encoder->context_info; + GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); const guint DEFAULT_SURFACES_COUNT = 3; /* Maximum sizes for common headers (in bits) */ @@ -1588,14 +1595,15 @@ gst_vaapi_encoder_h264_set_context_info (GstVaapiEncoder * base_encoder) MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402, }; - cip->profile = encoder->profile; - cip->ref_frames = (encoder->b_frame_num ? 2 : 1) + DEFAULT_SURFACES_COUNT; + base_encoder->profile = encoder->profile; + base_encoder->num_ref_frames = + (encoder->b_frame_num ? 2 : 1) + DEFAULT_SURFACES_COUNT; /* Only YUV 4:2:0 formats are supported for now. This means that we have a limit of 3200 bits per macroblock. */ /* XXX: check profile and compute RawMbBits */ - base_encoder->codedbuf_size = (GST_ROUND_UP_16 (cip->width) * - GST_ROUND_UP_16 (cip->height) / 256) * 400; + base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) * + GST_ROUND_UP_16 (vip->height) / 256) * 400; /* Account for SPS header */ /* XXX: exclude scaling lists, MVC/SVC extensions */ @@ -1617,15 +1625,13 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264_CAST (base_encoder); - if (!init_encoder_public_attributes (encoder)) { - GST_WARNING ("encoder ensure public attributes failed "); + if (!ensure_profile_and_level (encoder)) + goto error; + if (!ensure_bitrate (encoder)) goto error; - } - if (!init_encoder_private_attributes (encoder)) { - GST_WARNING ("prepare encoding failed "); - goto error; - } + reset_properties (encoder); + set_context_info (base_encoder); return GST_VAAPI_ENCODER_STATUS_SUCCESS; error: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 047289b4b8..1c9f6a229f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -103,34 +103,35 @@ ensure_sampling_desity (GstVaapiEncoderMpeg2 * encoder) } static gboolean -ensure_public_attributes (GstVaapiEncoderMpeg2 * encoder) +ensure_profile_and_level (GstVaapiEncoderMpeg2 * encoder) { - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - - if (encoder->ip_period > encoder->intra_period) { - encoder->ip_period = encoder->intra_period - 1; - } - if (encoder->profile == GST_ENCODER_MPEG2_PROFILE_SIMPLE) { /* no b frames */ encoder->ip_period = 0; /* only main level is defined in mpeg2 */ encoder->level = GST_VAAPI_ENCODER_MPEG2_LEVEL_MAIN; } + return TRUE; +} - if (!ensure_sampling_desity (encoder)) - return FALSE; - - /* default compress ratio 1: (4*8*1.5) */ - if (GST_VAAPI_RATECONTROL_CBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { - if (!base_encoder->bitrate) - base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * - GST_VAAPI_ENCODER_HEIGHT (encoder) * - GST_VAAPI_ENCODER_FPS_N (encoder) / - GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024; - } else - base_encoder->bitrate = 0; +static gboolean +ensure_bitrate (GstVaapiEncoderMpeg2 * 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: + if (!base_encoder->bitrate) + base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * + GST_VAAPI_ENCODER_HEIGHT (encoder) * + GST_VAAPI_ENCODER_FPS_N (encoder) / + GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024; + break; + default: + base_encoder->bitrate = 0; + break; + } return TRUE; } @@ -636,10 +637,10 @@ to_vaapi_profile (guint32 profile) } static void -gst_vaapi_encoder_mpeg2_set_context_info (GstVaapiEncoder * base_encoder) +set_context_info (GstVaapiEncoder * base_encoder) { GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2 (base_encoder); - GstVaapiContextInfo *const cip = &base_encoder->context_info; + GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); /* Maximum sizes for common headers (in bytes) */ enum @@ -652,13 +653,13 @@ gst_vaapi_encoder_mpeg2_set_context_info (GstVaapiEncoder * base_encoder) MAX_SLICE_HDR_SIZE = 8, }; - cip->profile = to_vaapi_profile (encoder->profile); - cip->ref_frames = 2; + base_encoder->profile = to_vaapi_profile (encoder->profile); + base_encoder->num_ref_frames = 2; /* Only YUV 4:2:0 formats are supported for now. This means that we have a limit of 4608 bits per macroblock. */ - base_encoder->codedbuf_size = (GST_ROUND_UP_16 (cip->width) * - GST_ROUND_UP_16 (cip->height) / 256) * 576; + base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) * + GST_ROUND_UP_16 (vip->height) / 256) * 576; /* Account for Sequence, GOP, and Picture headers */ /* XXX: exclude unused Sequence Display Extension, Sequence Scalable @@ -669,7 +670,7 @@ gst_vaapi_encoder_mpeg2_set_context_info (GstVaapiEncoder * base_encoder) MAX_GOP_SIZE + MAX_PIC_HDR_SIZE + MAX_PIC_EXT_SIZE; /* Account for Slice headers. We use one slice per line of macroblock */ - base_encoder->codedbuf_size += (GST_ROUND_UP_16 (cip->height) / 16) * + base_encoder->codedbuf_size += (GST_ROUND_UP_16 (vip->height) / 16) * MAX_SLICE_HDR_SIZE; } @@ -679,10 +680,18 @@ gst_vaapi_encoder_mpeg2_reconfigure (GstVaapiEncoder * base_encoder) GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); - if (!ensure_public_attributes (encoder)) { - GST_WARNING ("encoder ensure public attributes failed "); - goto error; + if (encoder->ip_period > encoder->intra_period) { + encoder->ip_period = encoder->intra_period - 1; } + + if (!ensure_profile_and_level (encoder)) + goto error; + if (!ensure_bitrate (encoder)) + goto error; + if (!ensure_sampling_desity (encoder)) + goto error; + + set_context_info (base_encoder); return GST_VAAPI_ENCODER_STATUS_SUCCESS; error: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 98bbee3874..c469deb3c5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -165,6 +165,8 @@ struct _GstVaapiEncoder 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 */ @@ -204,8 +206,6 @@ struct _GstVaapiEncoderClass gboolean (*init) (GstVaapiEncoder * encoder); void (*finalize) (GstVaapiEncoder * encoder); - void (*set_context_info) (GstVaapiEncoder * encoder); - GstVaapiEncoderStatus (*reconfigure) (GstVaapiEncoder * encoder); GPtrArray * (*get_default_properties) (void); @@ -243,7 +243,6 @@ struct _GstVaapiEncoderClass GST_VAAPI_ENCODER_CLASS_HOOK (codec, finalize), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, reconfigure), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, get_default_properties), \ - GST_VAAPI_ENCODER_CLASS_HOOK (codec, set_context_info), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, reordering), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, encode), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, flush) From 59229b20a5965081a210296122efe34e71d9d79f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 10 Jan 2014 13:23:48 +0100 Subject: [PATCH 1507/3781] encoder: add keyframe period API. Add gst_vaapi_encoder_set_keyframe_period() interface to allow the user control the maximum distance between two keyframes. This new property can only be set prior to gst_vaapi_encoder_set_codec_state(). A value of zero for "keyframe-period" gets it re-evaluated to the actual framerate during encoder reconfiguration. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 57 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 7 +++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 31 +++------- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 11 ++-- .../gst/vaapi/gstvaapiencoder_h264_priv.h | 3 - gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 21 ++----- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 5 +- .../gst/vaapi/gstvaapiencoder_mpeg2_priv.h | 4 -- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 12 ++++ 9 files changed, 94 insertions(+), 57 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index d629da1ade..f222361211 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -139,6 +139,18 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) "The desired bitrate expressed in kbps (0: auto-calculate)", 0, 100 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoder:keyframe-period: + * + * The maximal distance between two keyframes. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, + g_param_spec_uint ("keyframe-period", + "Keyframe Period", + "Maximal distance between two keyframes (0: auto-calculate)", 1, 300, + 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } @@ -478,10 +490,15 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); GstVaapiEncoderStatus status; GstVaapiVideoPool *pool; guint codedbuf_size; + /* Generate a keyframe every second */ + if (!encoder->keyframe_period) + encoder->keyframe_period = (vip->fps_n + vip->fps_d - 1) / vip->fps_d; + status = klass->reconfigure (encoder); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; @@ -603,6 +620,10 @@ set_property (GstVaapiEncoder * encoder, gint prop_id, const GValue * value) status = gst_vaapi_encoder_set_bitrate (encoder, g_value_get_uint (value)); break; + case GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD: + status = gst_vaapi_encoder_set_keyframe_period (encoder, + g_value_get_uint (value)); + break; } return status; @@ -782,6 +803,42 @@ error_operation_failed: } } +/** + * gst_vaapi_encoder_set_keyframe_period: + * @encoder: a #GstVaapiEncoder + * @keyframe_period: the maximal distance between two keyframes + * + * Notifies the @encoder to use the supplied @keyframe_period value. + * + * Note: currently, the keyframe period can only be specified before + * the last call to gst_vaapi_encoder_set_codec_state(), which shall + * occur before the first frame is encoded. Afterwards, any change to + * this parameter causes gst_vaapi_encoder_set_keyframe_period() to + * return @GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED. + * + * Return value: a #GstVaapiEncoderStatus + */ +GstVaapiEncoderStatus +gst_vaapi_encoder_set_keyframe_period (GstVaapiEncoder * encoder, + guint keyframe_period) +{ + g_return_val_if_fail (encoder != NULL, 0); + + if (encoder->keyframe_period != keyframe_period + && encoder->num_codedbuf_queued > 0) + goto error_operation_failed; + + encoder->keyframe_period = keyframe_period; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +error_operation_failed: + { + GST_ERROR ("could not change keyframe period after encoding started"); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } +} + /* Initialize default values for configurable properties */ static gboolean gst_vaapi_encoder_init_properties (GstVaapiEncoder * encoder) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 8f6e6ae1e0..1c3c86b0e8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -72,12 +72,15 @@ typedef enum * GstVaapiEncoderProp: * @GST_VAAPI_ENCODER_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). * @GST_VAAPI_ENCODER_PROP_BITRATE: Bitrate expressed in kbps (uint). + * @GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD: The maximal distance + * between two keyframes (uint). * * The set of configurable properties for the encoder. */ typedef enum { GST_VAAPI_ENCODER_PROP_RATECONTROL = 1, GST_VAAPI_ENCODER_PROP_BITRATE, + GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, } GstVaapiEncoderProp; /** @@ -125,6 +128,10 @@ 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_get_buffer_with_timeout (GstVaapiEncoder * encoder, GstVaapiCodedBufferProxy ** out_codedbuf_proxy_ptr, guint64 timeout); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index ad79f7c54c..4cd102189e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -854,7 +854,7 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder, memset (seq, 0, sizeof (VAEncSequenceParameterBufferH264)); seq->seq_parameter_set_id = 0; seq->level_idc = encoder->level; - seq->intra_period = encoder->intra_period; + seq->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq->ip_period = 0; // ? if (base_encoder->bitrate > 0) seq->bits_per_second = base_encoder->bitrate * 1024; @@ -1284,13 +1284,11 @@ ensure_bitrate (GstVaapiEncoderH264 * encoder) static void reset_properties (GstVaapiEncoderH264 * encoder) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); guint width_mbs, height_mbs, total_mbs; - if (encoder->intra_period > GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD) - encoder->intra_period = GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD; - - if (encoder->idr_period < encoder->intra_period) - encoder->idr_period = encoder->intra_period; + if (encoder->idr_period < base_encoder->keyframe_period) + encoder->idr_period = base_encoder->keyframe_period; if (encoder->idr_period > GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD) encoder->idr_period = GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD; @@ -1307,8 +1305,8 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->slice_num = (total_mbs + 1) / 2; g_assert (encoder->slice_num); - if (encoder->b_frame_num > (encoder->intra_period + 1) / 2) - encoder->b_frame_num = (encoder->intra_period + 1) / 2; + if (encoder->b_frame_num > (base_encoder->keyframe_period + 1) / 2) + encoder->b_frame_num = (base_encoder->keyframe_period + 1) / 2; if (encoder->b_frame_num > 50) encoder->b_frame_num = 50; @@ -1522,7 +1520,8 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base, /* check key frames */ if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) || - (encoder->frame_index % encoder->intra_period) == 0) { + (encoder->frame_index % GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == + 0) { ++encoder->cur_frame_num; ++encoder->frame_index; @@ -1710,9 +1709,6 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); switch (prop_id) { - case GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD: - encoder->intra_period = g_value_get_uint (value); - break; case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES: encoder->b_frame_num = g_value_get_uint (value); break; @@ -1771,17 +1767,6 @@ gst_vaapi_encoder_h264_get_default_properties (void) if (!props) return NULL; - /** - * GstVaapiEncoderH264:key-period - * - * The maximal distance between two keyframes. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD, - g_param_spec_uint ("key-period", - "Key Period", "Maximal distance between two key-frames", 1, 300, 30, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** * GstVaapiEncoderH264:max-bframes: * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index b6c4a1ce30..9b3eb4981e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -30,8 +30,6 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; /** * GstVaapiEncoderH264Prop: - * @GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD: Maximal distance between two - * keyframes (uint). * @GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES: Number of B-frames between I * and P (uint). * @GST_VAAPI_ENCODER_H264_PROP_INIT_QP: Initial quantizer value (uint). @@ -41,11 +39,10 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * The set of H.264 encoder specific configurable properties. */ typedef enum { - GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD = -1, - GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES = -2, - GST_VAAPI_ENCODER_H264_PROP_INIT_QP = -3, - GST_VAAPI_ENCODER_H264_PROP_MIN_QP = -4, - GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES = -5, + GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES = -1, + GST_VAAPI_ENCODER_H264_PROP_INIT_QP = -2, + GST_VAAPI_ENCODER_H264_PROP_MIN_QP = -3, + GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES = -4, } GstVaapiEncoderH264Prop; GstVaapiEncoder * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h index fd4cd292b2..f2b3a8e316 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h @@ -57,8 +57,6 @@ typedef enum #define GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL GST_VAAPI_ENCODER_H264_LEVEL_31 #define GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP 26 #define GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP 1 -#define GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD 30 -#define GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD 512 #define GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD 512 #define GST_VAAPI_ENCODER_H264_DEFAULT_SLICE_NUM 1 @@ -70,7 +68,6 @@ struct _GstVaapiEncoderH264 /* public */ guint32 profile; guint32 level; - guint32 intra_period; guint32 idr_period; guint32 init_qp; /*default 24 */ guint32 min_qp; /*default 1 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 1c9f6a229f..7b88128b96 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -177,7 +177,7 @@ fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence) memset (seq, 0, sizeof (VAEncSequenceParameterBufferMPEG2)); - seq->intra_period = encoder->intra_period; + seq->intra_period = base_encoder->keyframe_period; seq->ip_period = encoder->ip_period; seq->picture_width = GST_VAAPI_ENCODER_WIDTH (encoder); seq->picture_height = GST_VAAPI_ENCODER_HEIGHT (encoder); @@ -587,7 +587,7 @@ gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base, return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; } - if (encoder->frame_num >= encoder->intra_period) { + if (encoder->frame_num >= base->keyframe_period) { encoder->frame_num = 0; clear_references (encoder); } @@ -598,7 +598,7 @@ gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base, } else { encoder->new_gop = FALSE; if ((encoder->frame_num % (encoder->ip_period + 1)) == 0 || - encoder->frame_num == encoder->intra_period - 1) { + encoder->frame_num == base->keyframe_period - 1) { picture->type = GST_VAAPI_PICTURE_TYPE_P; encoder->dump_frames = TRUE; } else { @@ -680,8 +680,8 @@ gst_vaapi_encoder_mpeg2_reconfigure (GstVaapiEncoder * base_encoder) GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); - if (encoder->ip_period > encoder->intra_period) { - encoder->ip_period = encoder->intra_period - 1; + if (encoder->ip_period > base_encoder->keyframe_period) { + encoder->ip_period = base_encoder->keyframe_period - 1; } if (!ensure_profile_and_level (encoder)) @@ -771,9 +771,6 @@ gst_vaapi_encoder_mpeg2_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER: encoder->cqp = g_value_get_uint (value); break; - case GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD: - encoder->intra_period = g_value_get_uint (value); - break; case GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES: encoder->ip_period = g_value_get_uint (value); break; @@ -831,14 +828,6 @@ gst_vaapi_encoder_mpeg2_get_default_properties (void) GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD, - g_param_spec_uint ("key-period", - "Key Period", "Maximal distance between two key-frames", 1, - GST_VAAPI_ENCODER_MPEG2_MAX_GOP_SIZE, - GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES, g_param_spec_uint ("max-bframes", "Max B-Frames", diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h index bd6d1a7cbf..e4a547daec 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -31,8 +31,6 @@ typedef struct _GstVaapiEncoderMpeg2 GstVaapiEncoderMpeg2; /** * GstVaapiEncoderMpeg2Prop: * @GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER: Constant quantizer value (uint). - * @GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD: Maximal distance between two - * keyframes (uint). * @GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES: Number of B-frames between I * and P (uint). * @@ -40,8 +38,7 @@ typedef struct _GstVaapiEncoderMpeg2 GstVaapiEncoderMpeg2; */ typedef enum { GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER = -1, - GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD = -2, - GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES = -3, + GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES = -2, } GstVaapiEncoderMpeg2Prop; GstVaapiEncoder * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h index df94ab6b2b..b3159bd06f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h @@ -53,9 +53,6 @@ typedef enum #define GST_VAAPI_ENCODER_MPEG2_MAX_CQP 62 #define GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP 8 -#define GST_VAAPI_ENCODER_MPEG2_MAX_GOP_SIZE 512 -#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE 30 - #define GST_VAAPI_ENCODER_MPEG2_MAX_MAX_BFRAMES 16 #define GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES 2 @@ -81,7 +78,6 @@ struct _GstVaapiEncoderMpeg2 guint32 profile; guint32 level; guint32 cqp; - guint32 intra_period; guint32 ip_period; /* re-ordering */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index c469deb3c5..d473a0508a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -121,6 +121,17 @@ G_BEGIN_DECLS #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) + #define GST_VAAPI_ENCODER_CHECK_STATUS(exp, err_num, err_reason, ...) \ if (!(exp)) { \ ret = err_num; \ @@ -170,6 +181,7 @@ struct _GstVaapiEncoder GstVaapiRateControl rate_control; guint32 rate_control_mask; guint bitrate; /* kbps */ + guint keyframe_period; GMutex mutex; GCond surface_free; From 850a637d0f21b750a37fe836f0dc123c4a826dd9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sun, 12 Jan 2014 18:52:14 +0100 Subject: [PATCH 1508/3781] encoder: filter out the supported set of rate-control properties. Only expose the exact static set of supported rate-control properties to the upper layer. For instance, if the GstVaapiEncoderXXX class does only support CQP rate control, then only add it the the exposed enum type. Add helper macros and functions to build a GType for an enum subset. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 4 +- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 9 ++++ gst-libs/gst/vaapi/gstvaapivalue.c | 51 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivalue.h | 65 +++++++++++++++++++++++ 4 files changed, 128 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index f222361211..1a99147185 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -115,6 +115,8 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) const GstVaapiEncoderClassData *const cdata = klass->class_data; GPtrArray *props = NULL; + g_assert (cdata->rate_control_get_type != NULL); + /** * GstVaapiEncoder:rate-control: * @@ -124,7 +126,7 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) GST_VAAPI_ENCODER_PROP_RATECONTROL, g_param_spec_enum ("rate-control", "Rate Control", "Rate control mode", - GST_VAAPI_TYPE_RATE_CONTROL, cdata->default_rate_control, + cdata->rate_control_get_type (), cdata->default_rate_control, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index d473a0508a..81549d58cf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -27,6 +27,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -197,13 +198,21 @@ struct _GstVaapiEncoderClassData /*< private >*/ GstVaapiCodec codec; + GType (*rate_control_get_type)(void); GstVaapiRateControl default_rate_control; guint32 rate_control_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); \ + \ static const GstVaapiEncoderClassData g_class_data = { \ .codec = G_PASTE (GST_VAAPI_CODEC_, CODEC), \ + .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, \ } diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 2f4c239b27..07d99233b4 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -150,3 +150,54 @@ gst_vaapi_rate_control_get_type(void) } return g_type; } + +static gboolean +build_enum_subset_values_from_mask (GstVaapiEnumSubset *subset, guint32 mask) +{ + GEnumClass *enum_class; + const GEnumValue *value; + guint i, n; + + enum_class = g_type_class_ref(subset->parent_type); + if (!enum_class) + return FALSE; + + for (i = 0, n = 0; i < 32 && n < subset->num_values; i++) { + if (!(mask & (1U << i))) + continue; + value = g_enum_get_value(enum_class, i); + if (!value) + continue; + subset->values[n++] = *value; + } + g_type_class_unref(enum_class); + if (n != subset->num_values - 1) + goto error_invalid_num_values; + return TRUE; + + /* ERRORS */ +error_invalid_num_values: + { + g_error("invalid number of static values for `%s'", subset->type_name); + return FALSE; + } +} + +GType +gst_vaapi_type_define_enum_subset_from_mask(GstVaapiEnumSubset *subset, + guint32 mask) +{ + if (g_once_init_enter(&subset->type)) { + GType type; + + build_enum_subset_values_from_mask(subset, mask); + memset(&subset->type_info, 0, sizeof(subset->type_info)); + g_enum_complete_type_info(subset->parent_type, &subset->type_info, + subset->values); + + type = g_type_register_static (G_TYPE_ENUM, subset->type_name, + &subset->type_info, 0); + g_once_init_leave(&subset->type, type); + } + return subset->type; +} diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index 4c4d7982d9..2f6f431b54 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -92,6 +92,71 @@ gst_vaapi_rotation_get_type(void) G_GNUC_CONST; GType gst_vaapi_rate_control_get_type(void) G_GNUC_CONST; +/** + * GST_VAAPI_POPCOUNT32: + * @x: the value from which to compute population count + * + * Computes the number of bits set in the supplied 32-bit value @x. + * + * Return value: the number of bits set in @x + */ +#define GST_VAAPI_POPCOUNT32(x) \ + GST_VAAPI_POPCOUNT32_0(x) +#define GST_VAAPI_POPCOUNT32_0(x) \ + GST_VAAPI_POPCOUNT32_1((x) - (((x) >> 1) & 0x55555555)) +#define GST_VAAPI_POPCOUNT32_1(x) \ + GST_VAAPI_POPCOUNT32_2(((x) & 0x33333333) + (((x) >> 2) & 0x33333333)) +#define GST_VAAPI_POPCOUNT32_2(x) \ + GST_VAAPI_POPCOUNT32_3((x) + ((x) >> 4)) +#define GST_VAAPI_POPCOUNT32_3(x) \ + GST_VAAPI_POPCOUNT32_4((x) & 0x0f0f0f0f) +#define GST_VAAPI_POPCOUNT32_4(x) \ + (((x) * 0x01010101) >> 24) + +/* --- GstVaapiEnumSubset --- */ + +/** + * GstVaapiEnumSubset: + * @name: name of the enum subset + * @parent_type: parent enum type + * @type: registered #GType + * @type_info: #GTypeInfo used to build the @type + * @values: pointer to a static array of #GEnumValue elements + * @num_values: number of elements in the @values array, including the + * terminator + * + * Structure that holds the required information to build a GEnum + * subset from the supplied @parent_type, i.e. a subset of its values. + */ +typedef struct { + GType parent_type; + GType type; + GTypeInfo type_info; + const gchar *type_name; + GEnumValue *values; + guint num_values; +} GstVaapiEnumSubset; + +G_GNUC_INTERNAL +GType +gst_vaapi_type_define_enum_subset_from_mask(GstVaapiEnumSubset *subset, + guint32 mask); + +#define GST_VAAPI_TYPE_DEFINE_ENUM_SUBSET_FROM_MASK(NAME, name, TYPE, MASK) \ +static GType \ +G_PASTE(name,_get_type)(void) \ +{ \ + static GEnumValue enum_values[GST_VAAPI_POPCOUNT32(MASK) + 1]; \ + static GstVaapiEnumSubset subset = { \ + .type_name = G_STRINGIFY(NAME), \ + .values = enum_values, \ + .num_values = G_N_ELEMENTS(enum_values), \ + }; \ + if (g_once_init_enter(&subset.parent_type)) \ + g_once_init_leave(&subset.parent_type, TYPE); \ + return gst_vaapi_type_define_enum_subset_from_mask(&subset, MASK); \ +} + G_END_DECLS #endif /* GST_VAAPI_VALUE_H */ From 4a6fbddad64798012f623b92d40a7af84704eba9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sun, 12 Jan 2014 21:57:20 +0100 Subject: [PATCH 1509/3781] encoder: clean-ups. Drop obsolete and unused macros. Add a few doc comments. Slightly improve indentation of a few leftovers. --- gst-libs/gst/vaapi/gstvaapiencoder.h | 6 ++-- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 4 +-- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 37 ++++++++++---------- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 1c3c86b0e8..5df548e7c0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -27,10 +27,10 @@ G_BEGIN_DECLS -typedef struct _GstVaapiEncoder GstVaapiEncoder; +#define GST_VAAPI_ENCODER(encoder) \ + ((GstVaapiEncoder *) (encoder)) -#define GST_VAAPI_ENCODER(encoder) \ - ((GstVaapiEncoder *)(encoder)) +typedef struct _GstVaapiEncoder GstVaapiEncoder; /** * GstVaapiEncoderStatus: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index b75bb95da8..b4bdbd9bc2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -32,8 +32,8 @@ #include "gstvaapidebug.h" #define GET_ENCODER(obj) GST_VAAPI_ENCODER_CAST((obj)->parent_instance.codec) -#define GET_VA_DISPLAY(obj) GST_VAAPI_ENCODER_VA_DISPLAY(GET_ENCODER(obj)) -#define GET_VA_CONTEXT(obj) GST_VAAPI_ENCODER_VA_CONTEXT(GET_ENCODER(obj)) +#define GET_VA_DISPLAY(obj) GET_ENCODER(obj)->va_display +#define GET_VA_CONTEXT(obj) GET_ENCODER(obj)->va_context /* ------------------------------------------------------------------------- */ /* --- Encoder Packed Header --- */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 81549d58cf..78d9da0194 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -40,21 +40,27 @@ G_BEGIN_DECLS #define GST_VAAPI_ENCODER_GET_CLASS(obj) \ GST_VAAPI_ENCODER_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) -/* Get GstVaapiDisplay* */ +/** + * 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_CAST(encoder)->display -/* Get VADisplay */ -#define GST_VAAPI_ENCODER_VA_DISPLAY(encoder) \ - (GST_VAAPI_ENCODER_CAST(encoder)->va_display) - -/* Get GstVaapiContext* */ +/** + * 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) - -/* Get VAContext */ -#define GST_VAAPI_ENCODER_VA_CONTEXT(encoder) \ - (GST_VAAPI_ENCODER_CAST(encoder)->va_context) + GST_VAAPI_ENCODER_CAST(encoder)->context /** * GST_VAAPI_ENCODER_VIDEO_INFO: @@ -133,13 +139,6 @@ G_BEGIN_DECLS #define GST_VAAPI_ENCODER_KEYFRAME_PERIOD(encoder) \ (GST_VAAPI_ENCODER_CAST (encoder)->keyframe_period) -#define GST_VAAPI_ENCODER_CHECK_STATUS(exp, err_num, err_reason, ...) \ - if (!(exp)) { \ - ret = err_num; \ - GST_VAAPI_ENCODER_LOG_ERROR(err_reason, ## __VA_ARGS__); \ - goto end; \ - } - typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass; typedef struct _GstVaapiEncoderClassData GstVaapiEncoderClassData; From 368caf22da7cdd2f6b6e29fd20ca40616ca98bc2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sun, 12 Jan 2014 23:17:14 +0100 Subject: [PATCH 1510/3781] encoder: fix bitrate units to match kbps. Bitrate is expressed in kilobits per second (kbps). So, this exactly means in multiple of 1000 bits, not 1024 bits. https://bugzilla.gnome.org/show_bug.cgi?id=722086 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 14 +++++++------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 4cd102189e..28bccd890c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -564,9 +564,9 @@ gst_bit_writer_write_sps (GstBitWriter * bitwriter, for (i = 0; i < 1; ++i) { /* bit_rate_value_minus1[0] */ - gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1024 - 1); + gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1000 - 1); /* cpb_size_value_minus1[0] */ - gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1024 * 8 - 1); + gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1000 * 8 - 1); /* cbr_flag[0] */ gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); } @@ -857,7 +857,7 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder, seq->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq->ip_period = 0; // ? if (base_encoder->bitrate > 0) - seq->bits_per_second = base_encoder->bitrate * 1024; + seq->bits_per_second = base_encoder->bitrate * 1000; else seq->bits_per_second = 0; @@ -1215,8 +1215,8 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) gst_vaapi_enc_picture_add_misc_buffer (picture, misc); hrd = misc->impl; if (base_encoder->bitrate > 0) { - hrd->initial_buffer_fullness = base_encoder->bitrate * 1024 * 4; - hrd->buffer_size = base_encoder->bitrate * 1024 * 8; + hrd->initial_buffer_fullness = base_encoder->bitrate * 1000 * 4; + hrd->buffer_size = base_encoder->bitrate * 1000 * 8; } else { hrd->initial_buffer_fullness = 0; hrd->buffer_size = 0; @@ -1234,7 +1234,7 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) rate_control = misc->impl; memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); if (base_encoder->bitrate) - rate_control->bits_per_second = base_encoder->bitrate * 1024; + rate_control->bits_per_second = base_encoder->bitrate * 1000; else rate_control->bits_per_second = 0; rate_control->target_percentage = 70; @@ -1272,7 +1272,7 @@ ensure_bitrate (GstVaapiEncoderH264 * encoder) base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * GST_VAAPI_ENCODER_HEIGHT (encoder) * GST_VAAPI_ENCODER_FPS_N (encoder) / - GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024; + GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1000; break; default: base_encoder->bitrate = 0; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 7b88128b96..6f5ca72d7c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -126,7 +126,7 @@ ensure_bitrate (GstVaapiEncoderMpeg2 * encoder) base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * GST_VAAPI_ENCODER_HEIGHT (encoder) * GST_VAAPI_ENCODER_FPS_N (encoder) / - GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024; + GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1000; break; default: base_encoder->bitrate = 0; @@ -183,7 +183,7 @@ fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence) seq->picture_height = GST_VAAPI_ENCODER_HEIGHT (encoder); if (base_encoder->bitrate > 0) - seq->bits_per_second = base_encoder->bitrate * 1024; + seq->bits_per_second = base_encoder->bitrate * 1000; else seq->bits_per_second = 0; @@ -428,8 +428,8 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, gst_vaapi_enc_picture_add_misc_buffer (picture, misc); hrd = misc->impl; if (base_encoder->bitrate > 0) { - hrd->initial_buffer_fullness = base_encoder->bitrate * 1024 * 4; - hrd->buffer_size = base_encoder->bitrate * 1024 * 8; + hrd->initial_buffer_fullness = base_encoder->bitrate * 1000 * 4; + hrd->buffer_size = base_encoder->bitrate * 1000 * 8; } else { hrd->initial_buffer_fullness = 0; hrd->buffer_size = 0; @@ -446,7 +446,7 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, rate_control = misc->impl; memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); if (base_encoder->bitrate) - rate_control->bits_per_second = base_encoder->bitrate * 1024; + rate_control->bits_per_second = base_encoder->bitrate * 1000; else rate_control->bits_per_second = 0; rate_control->target_percentage = 70; From 21c95dbc4281f123f096e8d956d8f2fa4f285f2f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 13 Jan 2014 10:48:25 +0100 Subject: [PATCH 1511/3781] encoder: add tuning options API. Add encoder "tune" option to override the default behaviour that is to favor maximum decoder compatibility at the expense of lower compression ratios. Expected tuning options to be developed are: - "high-compression": improve compression, target best-in-class decoders; - "low-latency": tune for low-latency decoding; - "low-power": tune for encoding in low power / resources conditions. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 79 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 30 ++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 4 ++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 4 ++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 32 +++++++++ 5 files changed, 149 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 1a99147185..89b77e5d3c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -153,6 +153,19 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) "Maximal distance between two keyframes (0: auto-calculate)", 1, 300, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoder:tune: + * + * The desired encoder tuning option. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_PROP_TUNE, + g_param_spec_enum ("tune", + "Encoder Tuning", + "Encoder tuning option", + cdata->encoder_tune_get_type (), cdata->default_encoder_tune, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } @@ -626,6 +639,9 @@ set_property (GstVaapiEncoder * encoder, gint prop_id, const GValue * value) status = gst_vaapi_encoder_set_keyframe_period (encoder, g_value_get_uint (value)); break; + case GST_VAAPI_ENCODER_PROP_TUNE: + status = gst_vaapi_encoder_set_tuning (encoder, g_value_get_enum (value)); + break; } return status; @@ -841,6 +857,41 @@ error_operation_failed: } } +/** + * gst_vaapi_encoder_set_tuning: + * @encoder: a #GstVaapiEncoder + * @tuning: the #GstVaapiEncoderTune option + * + * Notifies the @encoder to use the supplied @tuning option. + * + * Note: currently, the tuning option can only be specified before the + * last call to gst_vaapi_encoder_set_codec_state(), which shall occur + * before the first frame is encoded. Afterwards, any change to this + * parameter causes gst_vaapi_encoder_set_tuning() to return + * @GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED. + * + * Return value: a #GstVaapiEncoderStatus + */ +GstVaapiEncoderStatus +gst_vaapi_encoder_set_tuning (GstVaapiEncoder * encoder, + GstVaapiEncoderTune tuning) +{ + g_return_val_if_fail (encoder != NULL, 0); + + if (encoder->tune != tuning && encoder->num_codedbuf_queued > 0) + goto error_operation_failed; + + encoder->tune = tuning; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +error_operation_failed: + { + GST_ERROR ("could not change tuning options after encoding started"); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } +} + /* Initialize default values for configurable properties */ static gboolean gst_vaapi_encoder_init_properties (GstVaapiEncoder * encoder) @@ -963,3 +1014,31 @@ error: gst_vaapi_encoder_unref (encoder); return NULL; } + +/** Returns a GType for the #GstVaapiEncoderTune set */ +GType +gst_vaapi_encoder_tune_get_type (void) +{ + static volatile gsize g_type = 0; + + static const GEnumValue encoder_tune_values[] = { + /* *INDENT-OFF* */ + { GST_VAAPI_ENCODER_TUNE_NONE, + "None", "none" }, + { GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION, + "High compression", "high-compression" }, + { GST_VAAPI_ENCODER_TUNE_LOW_LATENCY, + "Low latency", "low-latency" }, + { GST_VAAPI_ENCODER_TUNE_LOW_POWER, + "Low power mode", "low-power" }, + { 0, NULL, NULL }, + /* *INDENT-ON* */ + }; + + if (g_once_init_enter (&g_type)) { + GType type = + g_enum_register_static ("GstVaapiEncoderTune", encoder_tune_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 5df548e7c0..4b07700ef7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -68,12 +68,34 @@ typedef enum 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; + /** * GstVaapiEncoderProp: * @GST_VAAPI_ENCODER_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). * @GST_VAAPI_ENCODER_PROP_BITRATE: Bitrate expressed in kbps (uint). * @GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD: The maximal distance * between two keyframes (uint). + * @GST_VAAPI_ENCODER_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). * * The set of configurable properties for the encoder. */ @@ -81,6 +103,7 @@ typedef enum { GST_VAAPI_ENCODER_PROP_RATECONTROL = 1, GST_VAAPI_ENCODER_PROP_BITRATE, GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, + GST_VAAPI_ENCODER_PROP_TUNE, } GstVaapiEncoderProp; /** @@ -95,6 +118,9 @@ typedef struct { GParamSpec *const pspec; } GstVaapiEncoderPropInfo; +GType +gst_vaapi_encoder_tune_get_type (void) G_GNUC_CONST; + GstVaapiEncoder * gst_vaapi_encoder_ref (GstVaapiEncoder * encoder); @@ -132,6 +158,10 @@ 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_get_buffer_with_timeout (GstVaapiEncoder * encoder, GstVaapiCodedBufferProxy ** out_codedbuf_proxy_ptr, guint64 timeout); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 28bccd890c..050c144176 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -47,6 +47,10 @@ GST_VAAPI_RATECONTROL_MASK (VBR) | \ GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) +/* Supported set of tuning options, within this implementation */ +#define SUPPORTED_TUNE_OPTIONS \ + (GST_VAAPI_ENCODER_TUNE_MASK (NONE)) + #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM 2 diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 6f5ca72d7c..4f252181b1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -46,6 +46,10 @@ GST_VAAPI_RATECONTROL_MASK (CQP) | \ GST_VAAPI_RATECONTROL_MASK (CBR)) +/* Supported set of tuning options, within this implementation */ +#define SUPPORTED_TUNE_OPTIONS \ + (GST_VAAPI_ENCODER_TUNE_MASK (NONE)) + static gboolean gst_bit_writer_write_sps (GstBitWriter * bitwriter, VAEncSequenceParameterBufferMPEG2 * seq, GstVaapiEncoderMpeg2 * encoder); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 78d9da0194..abe3309a4d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -139,6 +139,24 @@ G_BEGIN_DECLS #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) + +/* 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 ()) + typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass; typedef struct _GstVaapiEncoderClassData GstVaapiEncoderClassData; @@ -172,6 +190,7 @@ struct _GstVaapiEncoder GstVaapiDisplay *display; GstVaapiContext *context; GstVaapiContextInfo context_info; + GstVaapiEncoderTune tune; VADisplay va_display; VAContextID va_context; @@ -200,6 +219,10 @@ struct _GstVaapiEncoderClassData 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) \ @@ -208,12 +231,21 @@ struct _GstVaapiEncoderClassData 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), \ .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 From 1edeb6ec080da2d5761e4859fa277344e87d5cda Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 13 Jan 2014 14:41:15 +0100 Subject: [PATCH 1512/3781] encoder: mpeg2: clean-ups. Various clean-ups to improve consistency and readability: drop unused macro definitions, drop initialization of vars that are zero-initialized from the base class, drop un-necessary casts. --- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 376 +++++++++--------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 3 + .../gst/vaapi/gstvaapiencoder_mpeg2_priv.h | 31 +- 3 files changed, 196 insertions(+), 214 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 4f252181b1..6d85f92858 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -1,7 +1,7 @@ /* * gstvaapiencoder_mpeg2.c - MPEG-2 encoder * - * Copyright (C) 2012 -2013 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -20,16 +20,15 @@ */ #include "sysdeps.h" +#include +#include #include #include "gstvaapicompat.h" #include "gstvaapiencoder_mpeg2.h" #include "gstvaapiencoder_mpeg2_priv.h" -#include "gstvaapiencoder_priv.h" +#include "gstvaapiutils_mpeg2_priv.h" #include "gstvaapicodedbufferproxy_priv.h" -#include -#include - #include "gstvaapicontext.h" #include "gstvaapisurface.h" #include "gstvaapidisplay_priv.h" @@ -52,12 +51,11 @@ static gboolean gst_bit_writer_write_sps (GstBitWriter * bitwriter, - VAEncSequenceParameterBufferMPEG2 * seq, GstVaapiEncoderMpeg2 * encoder); + const VAEncSequenceParameterBufferMPEG2 * seq_param); static gboolean gst_bit_writer_write_pps (GstBitWriter * bitwriter, - VAEncPictureParameterBufferMPEG2 * pic); - + const VAEncPictureParameterBufferMPEG2 * pic_param); static void clear_references (GstVaapiEncoderMpeg2 * encoder); @@ -177,40 +175,42 @@ static gboolean fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - VAEncSequenceParameterBufferMPEG2 *seq = sequence->param; + VAEncSequenceParameterBufferMPEG2 *const seq_param = sequence->param; - memset (seq, 0, sizeof (VAEncSequenceParameterBufferMPEG2)); + memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferMPEG2)); - seq->intra_period = base_encoder->keyframe_period; - seq->ip_period = encoder->ip_period; - seq->picture_width = GST_VAAPI_ENCODER_WIDTH (encoder); - seq->picture_height = GST_VAAPI_ENCODER_HEIGHT (encoder); + seq_param->intra_period = base_encoder->keyframe_period; + seq_param->ip_period = encoder->ip_period; + seq_param->picture_width = GST_VAAPI_ENCODER_WIDTH (encoder); + seq_param->picture_height = GST_VAAPI_ENCODER_HEIGHT (encoder); if (base_encoder->bitrate > 0) - seq->bits_per_second = base_encoder->bitrate * 1000; + seq_param->bits_per_second = base_encoder->bitrate * 1000; else - seq->bits_per_second = 0; + seq_param->bits_per_second = 0; if (GST_VAAPI_ENCODER_FPS_D (encoder)) - seq->frame_rate = + seq_param->frame_rate = GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder); else - seq->frame_rate = 0; + seq_param->frame_rate = 0; - seq->aspect_ratio_information = 1; - seq->vbv_buffer_size = 3; /* B = 16 * 1024 * vbv_buffer_size */ + seq_param->aspect_ratio_information = 1; + seq_param->vbv_buffer_size = 3; /* B = 16 * 1024 * vbv_buffer_size */ - seq->sequence_extension.bits.profile_and_level_indication = + seq_param->sequence_extension.bits.profile_and_level_indication = make_profile_and_level_indication (encoder->profile, encoder->level); - seq->sequence_extension.bits.progressive_sequence = 1; /* progressive frame-pictures */ - seq->sequence_extension.bits.chroma_format = CHROMA_FORMAT_420; /* 4:2:0 */ - seq->sequence_extension.bits.low_delay = 0; /* FIXME */ - seq->sequence_extension.bits.frame_rate_extension_n = 0; /*FIXME */ - seq->sequence_extension.bits.frame_rate_extension_d = 0; + seq_param->sequence_extension.bits.progressive_sequence = 1; /* progressive frame-pictures */ + seq_param->sequence_extension.bits.chroma_format = + gst_vaapi_utils_mpeg2_get_chroma_format_idc + (GST_VAAPI_CHROMA_TYPE_YUV420); + seq_param->sequence_extension.bits.low_delay = 0; /* FIXME */ + seq_param->sequence_extension.bits.frame_rate_extension_n = 0; /* FIXME */ + seq_param->sequence_extension.bits.frame_rate_extension_d = 0; - seq->gop_header.bits.time_code = (1 << 12); /* bit12: marker_bit */ - seq->gop_header.bits.closed_gop = 0; - seq->gop_header.bits.broken_link = 0; + seq_param->gop_header.bits.time_code = (1 << 12); /* bit12: marker_bit */ + seq_param->gop_header.bits.closed_gop = 0; + seq_param->gop_header.bits.broken_link = 0; return TRUE; } @@ -236,20 +236,21 @@ fill_picture (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) { - VAEncPictureParameterBufferMPEG2 *pic = picture->param; + VAEncPictureParameterBufferMPEG2 *const pic_param = picture->param; guint8 f_code_x, f_code_y; - memset (pic, 0, sizeof (VAEncPictureParameterBufferMPEG2)); + memset (pic_param, 0, sizeof (VAEncPictureParameterBufferMPEG2)); - pic->reconstructed_picture = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); - pic->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); - pic->picture_type = get_va_enc_picture_type (picture->type); - pic->temporal_reference = picture->frame_num & (1024 - 1); - pic->vbv_delay = 0xFFFF; + pic_param->reconstructed_picture = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); + pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + pic_param->picture_type = get_va_enc_picture_type (picture->type); + pic_param->temporal_reference = picture->frame_num & (1024 - 1); + pic_param->vbv_delay = 0xFFFF; f_code_x = 0xf; f_code_y = 0xf; - if (pic->picture_type != VAEncPictureTypeIntra) { + if (pic_param->picture_type != VAEncPictureTypeIntra) { if (encoder->level == GST_VAAPI_ENCODER_MPEG2_LEVEL_LOW) { f_code_x = 7; f_code_y = 4; @@ -262,45 +263,45 @@ fill_picture (GstVaapiEncoderMpeg2 * encoder, } } - if (pic->picture_type == VAEncPictureTypeIntra) { - pic->f_code[0][0] = 0xf; - pic->f_code[0][1] = 0xf; - pic->f_code[1][0] = 0xf; - pic->f_code[1][1] = 0xf; - pic->forward_reference_picture = VA_INVALID_SURFACE; - pic->backward_reference_picture = VA_INVALID_SURFACE; - } else if (pic->picture_type == VAEncPictureTypePredictive) { - pic->f_code[0][0] = f_code_x; - pic->f_code[0][1] = f_code_y; - pic->f_code[1][0] = 0xf; - pic->f_code[1][1] = 0xf; - pic->forward_reference_picture = + if (pic_param->picture_type == VAEncPictureTypeIntra) { + pic_param->f_code[0][0] = 0xf; + pic_param->f_code[0][1] = 0xf; + pic_param->f_code[1][0] = 0xf; + pic_param->f_code[1][1] = 0xf; + pic_param->forward_reference_picture = VA_INVALID_SURFACE; + pic_param->backward_reference_picture = VA_INVALID_SURFACE; + } else if (pic_param->picture_type == VAEncPictureTypePredictive) { + pic_param->f_code[0][0] = f_code_x; + pic_param->f_code[0][1] = f_code_y; + pic_param->f_code[1][0] = 0xf; + pic_param->f_code[1][1] = 0xf; + pic_param->forward_reference_picture = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->forward); - pic->backward_reference_picture = VA_INVALID_SURFACE; - } else if (pic->picture_type == VAEncPictureTypeBidirectional) { - pic->f_code[0][0] = f_code_x; - pic->f_code[0][1] = f_code_y; - pic->f_code[1][0] = f_code_x; - pic->f_code[1][1] = f_code_y; - pic->forward_reference_picture = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->forward);; - pic->backward_reference_picture = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->backward);; + pic_param->backward_reference_picture = VA_INVALID_SURFACE; + } else if (pic_param->picture_type == VAEncPictureTypeBidirectional) { + pic_param->f_code[0][0] = f_code_x; + pic_param->f_code[0][1] = f_code_y; + pic_param->f_code[1][0] = f_code_x; + pic_param->f_code[1][1] = f_code_y; + pic_param->forward_reference_picture = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->forward); + pic_param->backward_reference_picture = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->backward); } else { g_assert (0); } - pic->picture_coding_extension.bits.intra_dc_precision = 0; /* 8bits */ - pic->picture_coding_extension.bits.picture_structure = 3; /* frame picture */ - pic->picture_coding_extension.bits.top_field_first = 0; - pic->picture_coding_extension.bits.frame_pred_frame_dct = 1; /* FIXME */ - pic->picture_coding_extension.bits.concealment_motion_vectors = 0; - pic->picture_coding_extension.bits.q_scale_type = 0; - pic->picture_coding_extension.bits.intra_vlc_format = 0; - pic->picture_coding_extension.bits.alternate_scan = 0; - pic->picture_coding_extension.bits.repeat_first_field = 0; - pic->picture_coding_extension.bits.progressive_frame = 1; - pic->picture_coding_extension.bits.composite_display_flag = 0; + pic_param->picture_coding_extension.bits.intra_dc_precision = 0; /* 8bits */ + pic_param->picture_coding_extension.bits.picture_structure = 3; /* frame picture */ + pic_param->picture_coding_extension.bits.top_field_first = 0; + pic_param->picture_coding_extension.bits.frame_pred_frame_dct = 1; /* FIXME */ + pic_param->picture_coding_extension.bits.concealment_motion_vectors = 0; + pic_param->picture_coding_extension.bits.q_scale_type = 0; + pic_param->picture_coding_extension.bits.intra_vlc_format = 0; + pic_param->picture_coding_extension.bits.alternate_scan = 0; + pic_param->picture_coding_extension.bits.repeat_first_field = 0; + pic_param->picture_coding_extension.bits.progressive_frame = 1; + pic_param->picture_coding_extension.bits.composite_display_flag = 0; return TRUE; } @@ -312,12 +313,13 @@ set_sequence_packed_header (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPackedHeader *packed_seq; GstBitWriter writer; VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; - VAEncSequenceParameterBufferMPEG2 *seq = sequence->param; + const VAEncSequenceParameterBufferMPEG2 *const seq_param = sequence->param; guint32 data_bit_size; guint8 *data; gst_bit_writer_init (&writer, 128 * 8); - gst_bit_writer_write_sps (&writer, seq, encoder); + if (encoder->new_gop) + gst_bit_writer_write_sps (&writer, seq_param); g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer); data = GST_BIT_WRITER_DATA (&writer); @@ -332,7 +334,7 @@ set_sequence_packed_header (GstVaapiEncoderMpeg2 * encoder, g_assert (packed_seq); gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL); + gst_vaapi_codec_object_replace (&packed_seq, NULL); gst_bit_writer_clear (&writer, TRUE); return TRUE; @@ -345,12 +347,12 @@ set_picture_packed_header (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPackedHeader *packed_pic; GstBitWriter writer; VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; - VAEncPictureParameterBufferMPEG2 *pic = picture->param; + const VAEncPictureParameterBufferMPEG2 *const pic_param = picture->param; guint32 data_bit_size; guint8 *data; gst_bit_writer_init (&writer, 128 * 8); - gst_bit_writer_write_pps (&writer, pic); + gst_bit_writer_write_pps (&writer, pic_param); g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer); data = GST_BIT_WRITER_DATA (&writer); @@ -365,7 +367,7 @@ set_picture_packed_header (GstVaapiEncoderMpeg2 * encoder, g_assert (packed_pic); gst_vaapi_enc_picture_add_packed_header (picture, packed_pic); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_pic, NULL); + gst_vaapi_codec_object_replace (&packed_pic, NULL); gst_bit_writer_clear (&writer, TRUE); return TRUE; @@ -389,11 +391,11 @@ ensure_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) !set_sequence_packed_header (encoder, picture, sequence)) goto error; gst_vaapi_enc_picture_set_sequence (picture, sequence); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL); + gst_vaapi_codec_object_replace (&sequence, NULL); return TRUE; error: - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL); + gst_vaapi_codec_object_replace (&sequence, NULL); return FALSE; } @@ -411,7 +413,6 @@ ensure_picture (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture, GST_ERROR ("set picture packed header failed"); return FALSE; } - return TRUE; } @@ -438,7 +439,7 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, hrd->initial_buffer_fullness = 0; hrd->buffer_size = 0; } - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL); + gst_vaapi_codec_object_replace (&misc, NULL); /* add ratecontrol */ if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) { @@ -458,11 +459,9 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, rate_control->initial_qp = encoder->cqp; rate_control->min_qp = 0; rate_control->basic_unit_size = 0; - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL); + gst_vaapi_codec_object_replace (&misc, NULL); } - return TRUE; - } static gboolean @@ -491,10 +490,8 @@ fill_slices (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) slice_param->quantiser_scale_code = encoder->cqp / 2; gst_vaapi_enc_picture_add_slice (picture, slice); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & slice, NULL); - + gst_vaapi_codec_object_replace (&slice, NULL); } - return TRUE; } @@ -510,14 +507,15 @@ ensure_slices (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) } static GstVaapiEncoderStatus -gst_vaapi_encoder_mpeg2_encode (GstVaapiEncoder * base, +gst_vaapi_encoder_mpeg2_encode (GstVaapiEncoder * base_encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) { - GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2_CAST (base); + GstVaapiEncoderMpeg2 *const encoder = + GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; - reconstruct = gst_vaapi_encoder_create_surface (base); + reconstruct = gst_vaapi_encoder_create_surface (base_encoder); g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct)); @@ -548,13 +546,14 @@ error: } static GstVaapiEncoderStatus -gst_vaapi_encoder_mpeg2_flush (GstVaapiEncoder * base) +gst_vaapi_encoder_mpeg2_flush (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2_CAST (base); + GstVaapiEncoderMpeg2 *const encoder = + GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); GstVaapiEncPicture *pic; while (!g_queue_is_empty (&encoder->b_frames)) { - pic = (GstVaapiEncPicture *) g_queue_pop_head (&encoder->b_frames); + pic = g_queue_pop_head (&encoder->b_frames); gst_vaapi_enc_picture_unref (pic); } g_queue_clear (&encoder->b_frames); @@ -563,14 +562,14 @@ gst_vaapi_encoder_mpeg2_flush (GstVaapiEncoder * base) } static GstVaapiEncoderStatus -gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base, +gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) { - GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); + GstVaapiEncoderMpeg2 *const encoder = + GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); GstVaapiEncPicture *picture = NULL; GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS; - if (!frame) { if (g_queue_is_empty (&encoder->b_frames) && encoder->dump_frames) { push_reference (encoder, NULL); @@ -591,7 +590,7 @@ gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base, return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; } - if (encoder->frame_num >= base->keyframe_period) { + if (encoder->frame_num >= base_encoder->keyframe_period) { encoder->frame_num = 0; clear_references (encoder); } @@ -602,7 +601,7 @@ gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base, } else { encoder->new_gop = FALSE; if ((encoder->frame_num % (encoder->ip_period + 1)) == 0 || - encoder->frame_num == base->keyframe_period - 1) { + encoder->frame_num == base_encoder->keyframe_period - 1) { picture->type = GST_VAAPI_PICTURE_TYPE_P; encoder->dump_frames = TRUE; } else { @@ -643,7 +642,8 @@ to_vaapi_profile (guint32 profile) static void set_context_info (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2 (base_encoder); + GstVaapiEncoderMpeg2 *const encoder = + GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); /* Maximum sizes for common headers (in bytes) */ @@ -703,18 +703,13 @@ error: } static gboolean -gst_vaapi_encoder_mpeg2_init (GstVaapiEncoder * base) +gst_vaapi_encoder_mpeg2_init (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); + GstVaapiEncoderMpeg2 *const encoder = + GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); /* re-ordering */ g_queue_init (&encoder->b_frames); - encoder->dump_frames = FALSE; - - encoder->forward = NULL; - encoder->backward = NULL; - - encoder->frame_num = 0; return TRUE; } @@ -750,16 +745,17 @@ push_reference (GstVaapiEncoderMpeg2 * encoder, GstVaapiSurfaceProxy * ref) } static void -gst_vaapi_encoder_mpeg2_finalize (GstVaapiEncoder * base) +gst_vaapi_encoder_mpeg2_finalize (GstVaapiEncoder * base_encoder) { - /*free private buffers */ - GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base); + /* free private buffers */ + GstVaapiEncoderMpeg2 *const encoder = + GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); GstVaapiEncPicture *pic; clear_references (encoder); while (!g_queue_is_empty (&encoder->b_frames)) { - pic = (GstVaapiEncPicture *) g_queue_pop_head (&encoder->b_frames); + pic = g_queue_pop_head (&encoder->b_frames); gst_vaapi_enc_picture_unref (pic); } g_queue_clear (&encoder->b_frames); @@ -769,7 +765,8 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_mpeg2_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { - GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2 (base_encoder); + GstVaapiEncoderMpeg2 *const encoder = + GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); switch (prop_id) { case GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER: @@ -796,6 +793,14 @@ gst_vaapi_encoder_mpeg2_class (void) return &GstVaapiEncoderMpeg2Class; } +/** + * gst_vaapi_encoder_mpeg2_new: + * @display: a #GstVaapiDisplay + * + * Creates a new #GstVaapiEncoder for MPEG-2 encoding. + * + * Return value: the newly allocated #GstVaapiEncoder object + */ GstVaapiEncoder * gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display) { @@ -828,17 +833,13 @@ gst_vaapi_encoder_mpeg2_get_default_properties (void) g_param_spec_uint ("quantizer", "Constant Quantizer", "Constant quantizer (if rate-control mode is CQP)", - GST_VAAPI_ENCODER_MPEG2_MIN_CQP, GST_VAAPI_ENCODER_MPEG2_MAX_CQP, - GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + 2, 62, 8, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES, g_param_spec_uint ("max-bframes", "Max B-Frames", - "Number of B-frames between I and P", 0, - GST_VAAPI_ENCODER_MPEG2_MAX_MAX_BFRAMES, - GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Number of B-frames between I and P", + 0, 16, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); return props; } @@ -881,80 +882,79 @@ find_frame_rate_code (const VAEncSequenceParameterBufferMPEG2 * seq_param) static gboolean gst_bit_writer_write_sps (GstBitWriter * bitwriter, - VAEncSequenceParameterBufferMPEG2 * seq, GstVaapiEncoderMpeg2 * encoder) + const VAEncSequenceParameterBufferMPEG2 * seq_param) { - int frame_rate_code = find_frame_rate_code (seq); + gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_SEQ, 32); + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->picture_width, 12); + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->picture_height, 12); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq_param->aspect_ratio_information, 4); + gst_bit_writer_put_bits_uint32 (bitwriter, find_frame_rate_code (seq_param), 4); /* frame_rate_code */ + gst_bit_writer_put_bits_uint32 (bitwriter, (seq_param->bits_per_second + 399) / 400, 18); /* the low 18 bits of bit_rate */ + gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* marker_bit */ + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->vbv_buffer_size, 10); + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* constraint_parameter_flag, always 0 for MPEG-2 */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* load_intra_quantiser_matrix */ + gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* load_non_intra_quantiser_matrix */ - if (encoder->new_gop) { - gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_SEQ, 32); - gst_bit_writer_put_bits_uint32 (bitwriter, seq->picture_width, 12); - gst_bit_writer_put_bits_uint32 (bitwriter, seq->picture_height, 12); - gst_bit_writer_put_bits_uint32 (bitwriter, seq->aspect_ratio_information, - 4); - gst_bit_writer_put_bits_uint32 (bitwriter, frame_rate_code, 4); /* frame_rate_code */ - gst_bit_writer_put_bits_uint32 (bitwriter, (seq->bits_per_second + 399) / 400, 18); /* the low 18 bits of bit_rate */ - gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* marker_bit */ - gst_bit_writer_put_bits_uint32 (bitwriter, seq->vbv_buffer_size, 10); - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* constraint_parameter_flag, always 0 for MPEG-2 */ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* load_intra_quantiser_matrix */ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* load_non_intra_quantiser_matrix */ + gst_bit_writer_align_bytes (bitwriter, 0); - gst_bit_writer_align_bytes (bitwriter, 0); + gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_EXT, 32); + gst_bit_writer_put_bits_uint32 (bitwriter, 1, 4); /* sequence_extension id */ + gst_bit_writer_put_bits_uint32 (bitwriter, + seq_param->sequence_extension.bits.profile_and_level_indication, 8); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq_param->sequence_extension.bits.progressive_sequence, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq_param->sequence_extension.bits.chroma_format, 2); + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->picture_width >> 12, 2); + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->picture_height >> 12, + 2); + gst_bit_writer_put_bits_uint32 (bitwriter, ((seq_param->bits_per_second + 399) / 400) >> 18, 12); /* bit_rate_extension */ + gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* marker_bit */ + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->vbv_buffer_size >> 10, + 8); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq_param->sequence_extension.bits.low_delay, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq_param->sequence_extension.bits.frame_rate_extension_n, 2); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq_param->sequence_extension.bits.frame_rate_extension_d, 5); - gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_EXT, 32); - gst_bit_writer_put_bits_uint32 (bitwriter, 1, 4); /* sequence_extension id */ - gst_bit_writer_put_bits_uint32 (bitwriter, - seq->sequence_extension.bits.profile_and_level_indication, 8); - gst_bit_writer_put_bits_uint32 (bitwriter, - seq->sequence_extension.bits.progressive_sequence, 1); - gst_bit_writer_put_bits_uint32 (bitwriter, - seq->sequence_extension.bits.chroma_format, 2); - gst_bit_writer_put_bits_uint32 (bitwriter, seq->picture_width >> 12, 2); - gst_bit_writer_put_bits_uint32 (bitwriter, seq->picture_height >> 12, 2); - gst_bit_writer_put_bits_uint32 (bitwriter, ((seq->bits_per_second + 399) / 400) >> 18, 12); /* bit_rate_extension */ - gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* marker_bit */ - gst_bit_writer_put_bits_uint32 (bitwriter, seq->vbv_buffer_size >> 10, 8); - gst_bit_writer_put_bits_uint32 (bitwriter, - seq->sequence_extension.bits.low_delay, 1); - gst_bit_writer_put_bits_uint32 (bitwriter, - seq->sequence_extension.bits.frame_rate_extension_n, 2); - gst_bit_writer_put_bits_uint32 (bitwriter, - seq->sequence_extension.bits.frame_rate_extension_d, 5); + gst_bit_writer_align_bytes (bitwriter, 0); - gst_bit_writer_align_bytes (bitwriter, 0); + /* gop header */ + gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_GOP, 32); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq_param->gop_header.bits.time_code, 25); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq_param->gop_header.bits.closed_gop, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + seq_param->gop_header.bits.broken_link, 1); - /* gop header */ - gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_GOP, 32); - gst_bit_writer_put_bits_uint32 (bitwriter, seq->gop_header.bits.time_code, - 25); - gst_bit_writer_put_bits_uint32 (bitwriter, seq->gop_header.bits.closed_gop, - 1); - gst_bit_writer_put_bits_uint32 (bitwriter, seq->gop_header.bits.broken_link, - 1); + gst_bit_writer_align_bytes (bitwriter, 0); - gst_bit_writer_align_bytes (bitwriter, 0); - } return TRUE; } static gboolean gst_bit_writer_write_pps (GstBitWriter * bitwriter, - VAEncPictureParameterBufferMPEG2 * pic) + const VAEncPictureParameterBufferMPEG2 * pic_param) { gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_PICUTRE, 32); - gst_bit_writer_put_bits_uint32 (bitwriter, pic->temporal_reference, 10); + gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->temporal_reference, 10); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_type == VAEncPictureTypeIntra ? 1 : - pic->picture_type == VAEncPictureTypePredictive ? 2 : 3, 3); - gst_bit_writer_put_bits_uint32 (bitwriter, pic->vbv_delay, 16); + pic_param->picture_type == VAEncPictureTypeIntra ? 1 : + pic_param->picture_type == VAEncPictureTypePredictive ? 2 : 3, 3); + gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->vbv_delay, 16); - if (pic->picture_type == VAEncPictureTypePredictive || - pic->picture_type == VAEncPictureTypeBidirectional) { + if (pic_param->picture_type == VAEncPictureTypePredictive || + pic_param->picture_type == VAEncPictureTypeBidirectional) { gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* full_pel_forward_vector, always 0 for MPEG-2 */ gst_bit_writer_put_bits_uint32 (bitwriter, 7, 3); /* forward_f_code, always 7 for MPEG-2 */ } - if (pic->picture_type == VAEncPictureTypeBidirectional) { + if (pic_param->picture_type == VAEncPictureTypeBidirectional) { gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* full_pel_backward_vector, always 0 for MPEG-2 */ gst_bit_writer_put_bits_uint32 (bitwriter, 7, 3); /* backward_f_code, always 7 for MPEG-2 */ } @@ -965,34 +965,34 @@ gst_bit_writer_write_pps (GstBitWriter * bitwriter, gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_EXT, 32); gst_bit_writer_put_bits_uint32 (bitwriter, 8, 4); /* Picture Coding Extension ID: 8 */ - gst_bit_writer_put_bits_uint32 (bitwriter, pic->f_code[0][0], 4); - gst_bit_writer_put_bits_uint32 (bitwriter, pic->f_code[0][1], 4); - gst_bit_writer_put_bits_uint32 (bitwriter, pic->f_code[1][0], 4); - gst_bit_writer_put_bits_uint32 (bitwriter, pic->f_code[1][1], 4); + gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->f_code[0][0], 4); + gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->f_code[0][1], 4); + gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->f_code[1][0], 4); + gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->f_code[1][1], 4); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_coding_extension.bits.intra_dc_precision, 2); + pic_param->picture_coding_extension.bits.intra_dc_precision, 2); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_coding_extension.bits.picture_structure, 2); + pic_param->picture_coding_extension.bits.picture_structure, 2); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_coding_extension.bits.top_field_first, 1); + pic_param->picture_coding_extension.bits.top_field_first, 1); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_coding_extension.bits.frame_pred_frame_dct, 1); + pic_param->picture_coding_extension.bits.frame_pred_frame_dct, 1); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_coding_extension.bits.concealment_motion_vectors, 1); + pic_param->picture_coding_extension.bits.concealment_motion_vectors, 1); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_coding_extension.bits.q_scale_type, 1); + pic_param->picture_coding_extension.bits.q_scale_type, 1); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_coding_extension.bits.intra_vlc_format, 1); + pic_param->picture_coding_extension.bits.intra_vlc_format, 1); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_coding_extension.bits.alternate_scan, 1); + pic_param->picture_coding_extension.bits.alternate_scan, 1); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_coding_extension.bits.repeat_first_field, 1); + pic_param->picture_coding_extension.bits.repeat_first_field, 1); gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* always chroma 420 */ gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_coding_extension.bits.progressive_frame, 1); + pic_param->picture_coding_extension.bits.progressive_frame, 1); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->picture_coding_extension.bits.composite_display_flag, 1); + pic_param->picture_coding_extension.bits.composite_display_flag, 1); gst_bit_writer_align_bytes (bitwriter, 0); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h index e4a547daec..8392d1e3f1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -26,6 +26,9 @@ G_BEGIN_DECLS +#define GST_VAAPI_ENCODER_MPEG2(encoder) \ + ((GstVaapiEncoderMpeg2 *) (encoder)) + typedef struct _GstVaapiEncoderMpeg2 GstVaapiEncoderMpeg2; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h index b3159bd06f..d36a3e5ea3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h @@ -22,16 +22,13 @@ #ifndef GST_VAAPI_ENCODER_MPEG2_PRIV_H #define GST_VAAPI_ENCODER_MPEG2_PRIV_H -#include -#include -#include +#include "gstvaapiencoder_priv.h" +#include "gstvaapiutils_mpeg2.h" G_BEGIN_DECLS -#define GST_VAAPI_ENCODER_MPEG2(encoder) \ - ((GstVaapiEncoderMpeg2 *)(encoder)) #define GST_VAAPI_ENCODER_MPEG2_CAST(encoder) \ - ((GstVaapiEncoderMpeg2 *)(encoder)) + ((GstVaapiEncoderMpeg2 *) (encoder)) typedef enum { @@ -46,18 +43,6 @@ typedef enum GST_VAAPI_ENCODER_MPEG2_LEVEL_HIGH } GstVaapiEncoderMpeg2Level; -#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE GST_ENCODER_MPEG2_PROFILE_MAIN -#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL GST_VAAPI_ENCODER_MPEG2_LEVEL_HIGH - -#define GST_VAAPI_ENCODER_MPEG2_MIN_CQP 2 -#define GST_VAAPI_ENCODER_MPEG2_MAX_CQP 62 -#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP 8 - -#define GST_VAAPI_ENCODER_MPEG2_MAX_MAX_BFRAMES 16 -#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES 2 - -#define GST_VAAPI_ENCODER_MPEG2_MAX_BITRATE 100*1024 - #define START_CODE_PICUTRE 0x00000100 #define START_CODE_SLICE 0x00000101 #define START_CODE_USER 0x000001B2 @@ -65,19 +50,13 @@ typedef enum #define START_CODE_EXT 0x000001B5 #define START_CODE_GOP 0x000001B8 -#define CHROMA_FORMAT_RESERVED 0 -#define CHROMA_FORMAT_420 1 -#define CHROMA_FORMAT_422 2 -#define CHROMA_FORMAT_444 3 - struct _GstVaapiEncoderMpeg2 { - GstVaapiEncoder parent; + GstVaapiEncoder parent_instance; - /* public */ guint32 profile; guint32 level; - guint32 cqp; + guint32 cqp; /* quantizer value for CQP mode */ guint32 ip_period; /* re-ordering */ From e311d53c8a18eb6b3fff2648a42d17c2e87d7b35 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 13 Jan 2014 16:56:04 +0100 Subject: [PATCH 1513/3781] encoder: mpeg2: derive profile and level from active coding tools. Automatically derive the minimum profile and level to be used for encoding, based on the activated coding tools. Improve lookup for the best suitable level with the new MPEG-2 helper functions. Also change the default profile to "simple" so that to ensure maximum compatibility when the stream is decoded. https://bugzilla.gnome.org/show_bug.cgi?id=719703 --- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 188 ++++++++---------- .../gst/vaapi/gstvaapiencoder_mpeg2_priv.h | 19 +- 2 files changed, 82 insertions(+), 125 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 6d85f92858..db0f447786 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -62,58 +62,73 @@ static void clear_references (GstVaapiEncoderMpeg2 * encoder); static void push_reference (GstVaapiEncoderMpeg2 * encoder, GstVaapiSurfaceProxy * ref); -static struct -{ - int samplers_per_line; - int line_per_frame; - int frame_per_sec; -} mpeg2_upper_samplings[2][3] = { - /* *INDENT-OFF* */ - { { 0, 0, 0}, - { 720, 576, 30 }, - { 0, 0, 0 }, - }, - { { 352, 288, 30 }, - { 720, 576, 30 }, - { 1920, 1152, 60 }, - } - /* *INDENT-ON* */ -}; - +/* Derives the minimum profile from the active coding tools */ static gboolean -ensure_sampling_desity (GstVaapiEncoderMpeg2 * encoder) +ensure_profile (GstVaapiEncoderMpeg2 * encoder) { - guint p, l; - float fps; + GstVaapiProfile profile; - p = encoder->profile; - l = encoder->level; - fps = GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder); - if (mpeg2_upper_samplings[p][l].samplers_per_line < - GST_VAAPI_ENCODER_WIDTH (encoder) - || mpeg2_upper_samplings[p][l].line_per_frame < - GST_VAAPI_ENCODER_HEIGHT (encoder) - || mpeg2_upper_samplings[p][l].frame_per_sec < fps) { - GST_ERROR - ("acording to slected profile(%d) and level(%d) the max resolution is %dx%d@%d", - p, l, mpeg2_upper_samplings[p][l].samplers_per_line, - mpeg2_upper_samplings[p][l].line_per_frame, - mpeg2_upper_samplings[p][l].frame_per_sec); - return FALSE; - } + /* Always start from "simple" profile for maximum compatibility */ + profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; + + /* Main profile coding tools */ + if (encoder->ip_period > 0) + profile = GST_VAAPI_PROFILE_MPEG2_MAIN; + + encoder->profile = profile; + encoder->profile_idc = gst_vaapi_utils_mpeg2_get_profile_idc (profile); return TRUE; } +/* Derives the minimum level from the current configuration */ static gboolean +ensure_level (GstVaapiEncoderMpeg2 * encoder) +{ + const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); + const guint fps = (vip->fps_n + vip->fps_d - 1) / vip->fps_d; + const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate; + const GstVaapiMPEG2LevelLimits *limits_table; + guint i, num_limits, num_samples; + + num_samples = gst_util_uint64_scale_int_ceil (vip->width * vip->height, + vip->fps_n, vip->fps_d); + + limits_table = gst_vaapi_utils_mpeg2_get_level_limits_table (&num_limits); + for (i = 0; i < num_limits; i++) { + const GstVaapiMPEG2LevelLimits *const limits = &limits_table[i]; + if (vip->width <= limits->horizontal_size_value && + vip->height <= limits->vertical_size_value && + fps <= limits->frame_rate_value && + num_samples <= limits->sample_rate && + (!bitrate || bitrate <= limits->bit_rate)) + break; + } + if (i == num_limits) + goto error_unsupported_level; + + encoder->level = limits_table[i].level; + encoder->level_idc = limits_table[i].level_idc; + return TRUE; + + /* ERRORS */ +error_unsupported_level: + { + GST_ERROR ("failed to find a suitable level matching codec config"); + return FALSE; + } +} + +/* Derives the profile and level that suits best to the configuration */ +static GstVaapiEncoderStatus ensure_profile_and_level (GstVaapiEncoderMpeg2 * encoder) { - if (encoder->profile == GST_ENCODER_MPEG2_PROFILE_SIMPLE) { - /* no b frames */ - encoder->ip_period = 0; - /* only main level is defined in mpeg2 */ - encoder->level = GST_VAAPI_ENCODER_MPEG2_LEVEL_MAIN; - } - return TRUE; + if (!ensure_profile (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + if (!ensure_level (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } static gboolean @@ -137,40 +152,6 @@ ensure_bitrate (GstVaapiEncoderMpeg2 * encoder) return TRUE; } -static unsigned char -make_profile_and_level_indication (guint32 profile, guint32 level) -{ - guint32 p = 4, l = 8; - - switch (profile) { - case GST_ENCODER_MPEG2_PROFILE_SIMPLE: - p = 5; - break; - case GST_ENCODER_MPEG2_PROFILE_MAIN: - p = 4; - break; - default: - g_assert (0); - break; - } - - switch (level) { - case GST_VAAPI_ENCODER_MPEG2_LEVEL_LOW: - l = 10; - break; - case GST_VAAPI_ENCODER_MPEG2_LEVEL_MAIN: - l = 8; - break; - case GST_VAAPI_ENCODER_MPEG2_LEVEL_HIGH: - l = 4; - break; - default: - g_assert (0); - break; - } - return p << 4 | l; -} - static gboolean fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence) { @@ -199,7 +180,7 @@ fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence) seq_param->vbv_buffer_size = 3; /* B = 16 * 1024 * vbv_buffer_size */ seq_param->sequence_extension.bits.profile_and_level_indication = - make_profile_and_level_indication (encoder->profile, encoder->level); + (encoder->profile_idc << 4) | encoder->level_idc; seq_param->sequence_extension.bits.progressive_sequence = 1; /* progressive frame-pictures */ seq_param->sequence_extension.bits.chroma_format = gst_vaapi_utils_mpeg2_get_chroma_format_idc @@ -251,15 +232,19 @@ fill_picture (GstVaapiEncoderMpeg2 * encoder, f_code_x = 0xf; f_code_y = 0xf; if (pic_param->picture_type != VAEncPictureTypeIntra) { - if (encoder->level == GST_VAAPI_ENCODER_MPEG2_LEVEL_LOW) { - f_code_x = 7; - f_code_y = 4; - } else if (encoder->level == GST_VAAPI_ENCODER_MPEG2_LEVEL_MAIN) { - f_code_x = 8; - f_code_y = 5; - } else { - f_code_x = 9; - f_code_y = 5; + switch (encoder->level) { + case GST_VAAPI_LEVEL_MPEG2_LOW: + f_code_x = 7; + f_code_y = 4; + break; + case GST_VAAPI_LEVEL_MPEG2_MAIN: + f_code_x = 8; + f_code_y = 5; + break; + default: /* High-1440 and High levels */ + f_code_x = 9; + f_code_y = 5; + break; } } @@ -621,24 +606,6 @@ end: return status; } -static GstVaapiProfile -to_vaapi_profile (guint32 profile) -{ - GstVaapiProfile p; - - switch (profile) { - case GST_ENCODER_MPEG2_PROFILE_SIMPLE: - p = GST_VAAPI_PROFILE_MPEG2_SIMPLE; - break; - case GST_ENCODER_MPEG2_PROFILE_MAIN: - p = GST_VAAPI_PROFILE_MPEG2_MAIN; - break; - default: - g_assert (0); - } - return p; -} - static void set_context_info (GstVaapiEncoder * base_encoder) { @@ -657,7 +624,7 @@ set_context_info (GstVaapiEncoder * base_encoder) MAX_SLICE_HDR_SIZE = 8, }; - base_encoder->profile = to_vaapi_profile (encoder->profile); + base_encoder->profile = encoder->profile; base_encoder->num_ref_frames = 2; /* Only YUV 4:2:0 formats are supported for now. This means that we @@ -683,17 +650,18 @@ gst_vaapi_encoder_mpeg2_reconfigure (GstVaapiEncoder * base_encoder) { GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); + GstVaapiEncoderStatus status; if (encoder->ip_period > base_encoder->keyframe_period) { encoder->ip_period = base_encoder->keyframe_period - 1; } - if (!ensure_profile_and_level (encoder)) - goto error; + status = ensure_profile_and_level (encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + if (!ensure_bitrate (encoder)) goto error; - if (!ensure_sampling_desity (encoder)) - goto error; set_context_info (base_encoder); return GST_VAAPI_ENCODER_STATUS_SUCCESS; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h index d36a3e5ea3..f2e02dfaf3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h @@ -30,19 +30,6 @@ G_BEGIN_DECLS #define GST_VAAPI_ENCODER_MPEG2_CAST(encoder) \ ((GstVaapiEncoderMpeg2 *) (encoder)) -typedef enum -{ - GST_ENCODER_MPEG2_PROFILE_SIMPLE, - GST_ENCODER_MPEG2_PROFILE_MAIN, -} GstEncoderMpeg2Level; - -typedef enum -{ - GST_VAAPI_ENCODER_MPEG2_LEVEL_LOW, - GST_VAAPI_ENCODER_MPEG2_LEVEL_MAIN, - GST_VAAPI_ENCODER_MPEG2_LEVEL_HIGH -} GstVaapiEncoderMpeg2Level; - #define START_CODE_PICUTRE 0x00000100 #define START_CODE_SLICE 0x00000101 #define START_CODE_USER 0x000001B2 @@ -54,8 +41,10 @@ struct _GstVaapiEncoderMpeg2 { GstVaapiEncoder parent_instance; - guint32 profile; - guint32 level; + GstVaapiProfile profile; + GstVaapiLevelMPEG2 level; + guint8 profile_idc; + guint8 level_idc; guint32 cqp; /* quantizer value for CQP mode */ guint32 ip_period; From 0c5f69e0d9b9e27c9d6f3d78b6384b98ddc70530 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 13 Jan 2014 17:11:15 +0100 Subject: [PATCH 1514/3781] encoder: mpeg2: fix hardware profile lookup. Fix lookup for a suitable HW profile, as to be used by the underlying hardware, based on heuristics that lead to characterize the SW profile, i.e. the one used by the SW level encoding logic. --- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 51 +++++++++++++++++++--- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index db0f447786..958dd6e983 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -62,6 +62,45 @@ static void clear_references (GstVaapiEncoderMpeg2 * encoder); static void push_reference (GstVaapiEncoderMpeg2 * encoder, GstVaapiSurfaceProxy * ref); +/* Derives the profile supported by the underlying hardware */ +static gboolean +ensure_hw_profile (GstVaapiEncoderMpeg2 * 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; + switch (encoder->profile) { + case GST_VAAPI_PROFILE_MPEG2_SIMPLE: + profiles[num_profiles++] = GST_VAAPI_PROFILE_MPEG2_MAIN; + break; + default: + break; + } + + 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 (0x%08x)", encoder->profile); + return FALSE; + } +} + /* Derives the minimum profile from the active coding tools */ static gboolean ensure_profile (GstVaapiEncoderMpeg2 * encoder) @@ -606,7 +645,7 @@ end: return status; } -static void +static GstVaapiEncoderStatus set_context_info (GstVaapiEncoder * base_encoder) { GstVaapiEncoderMpeg2 *const encoder = @@ -624,7 +663,9 @@ set_context_info (GstVaapiEncoder * base_encoder) MAX_SLICE_HDR_SIZE = 8, }; - base_encoder->profile = encoder->profile; + if (!ensure_hw_profile (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + base_encoder->num_ref_frames = 2; /* Only YUV 4:2:0 formats are supported for now. This means that we @@ -643,6 +684,8 @@ set_context_info (GstVaapiEncoder * base_encoder) /* Account for Slice headers. We use one slice per line of macroblock */ base_encoder->codedbuf_size += (GST_ROUND_UP_16 (vip->height) / 16) * MAX_SLICE_HDR_SIZE; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } static GstVaapiEncoderStatus @@ -662,9 +705,7 @@ gst_vaapi_encoder_mpeg2_reconfigure (GstVaapiEncoder * base_encoder) if (!ensure_bitrate (encoder)) goto error; - - set_context_info (base_encoder); - return GST_VAAPI_ENCODER_STATUS_SUCCESS; + return set_context_info (base_encoder); error: return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; From 45732dcc831e20349d2b7d3c8600a604c079ceb1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 10 Jan 2014 14:05:40 +0100 Subject: [PATCH 1515/3781] encoder: h264: clean-ups. Various clean-ups to improve consistency and readability: rename some variables, drop unused macro definitions, drop initialization of vars that are zero-initialized from the base class, drop un-necessary casts. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 551 +++++++++--------- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 3 + .../gst/vaapi/gstvaapiencoder_h264_priv.h | 33 +- gst/vaapi/gstvaapiencode_h264.c | 4 +- 4 files changed, 286 insertions(+), 305 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 050c144176..7e4b6fd8f3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1,7 +1,7 @@ /* * gstvaapiencoder_h264.c - H.264 encoder * - * Copyright (C) 2012 -2013 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -20,18 +20,14 @@ */ #include "sysdeps.h" +#include +#include +#include #include "gstvaapicompat.h" #include "gstvaapiencoder_h264.h" #include "gstvaapiencoder_h264_priv.h" -#include "gstvaapiencoder_priv.h" #include "gstvaapicodedbufferproxy_priv.h" - -#include -#include - -#include "gstvaapicontext.h" #include "gstvaapisurface.h" -#include "gstvaapidisplay_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -99,8 +95,9 @@ _poc_greater_than (guint poc1, guint poc2, guint max_poc) return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2); } -static inline guint8 -_get_va_slice_type (GstVaapiPictureType type) +/* Get slice_type value for H.264 specification */ +static guint8 +h264_get_slice_type (GstVaapiPictureType type) { switch (type) { case GST_VAAPI_PICTURE_TYPE_I: @@ -132,8 +129,9 @@ _read_sps_attributes (const guint8 * sps_data, return TRUE; } -static inline guint -_get_log2_max_frame_num (guint num) +/* Get log2_max_frame_num value for H.264 specification */ +static guint +h264_get_log2_max_frame_num (guint num) { guint ret = 0; @@ -201,18 +199,18 @@ _set_level (GstVaapiEncoderH264 * encoder) guint MaxDpbMbs, MaxMBPS; guint dbp_level, mbps_level, profile_level; - if (encoder->level) { - if (encoder->level < GST_VAAPI_ENCODER_H264_LEVEL_10) - encoder->level = GST_VAAPI_ENCODER_H264_LEVEL_10; - else if (encoder->level > GST_VAAPI_ENCODER_H264_LEVEL_51) - encoder->level = GST_VAAPI_ENCODER_H264_LEVEL_51; + if (encoder->level_idc) { + if (encoder->level_idc < GST_VAAPI_ENCODER_H264_LEVEL_10) + encoder->level_idc = GST_VAAPI_ENCODER_H264_LEVEL_10; + else if (encoder->level_idc > GST_VAAPI_ENCODER_H264_LEVEL_51) + encoder->level_idc = GST_VAAPI_ENCODER_H264_LEVEL_51; return; } /* calculate level */ pic_mb_size = ((GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16) * ((GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16); - MaxDpbMbs = pic_mb_size * ((encoder->b_frame_num) ? 2 : 1); + MaxDpbMbs = pic_mb_size * ((encoder->num_bframes) ? 2 : 1); MaxMBPS = pic_mb_size * GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder); @@ -275,9 +273,9 @@ _set_level (GstVaapiEncoderH264 * encoder) else profile_level = GST_VAAPI_ENCODER_H264_LEVEL_20; - encoder->level = (dbp_level > mbps_level ? dbp_level : mbps_level); - if (encoder->level < profile_level) - encoder->level = profile_level; + encoder->level_idc = (dbp_level > mbps_level ? dbp_level : mbps_level); + if (encoder->level_idc < profile_level) + encoder->level_idc = profile_level; } static inline void @@ -394,7 +392,7 @@ gst_bit_writer_write_trailing_bits (GstBitWriter * bitwriter) static gboolean gst_bit_writer_write_sps (GstBitWriter * bitwriter, - VAEncSequenceParameterBufferH264 * seq, GstVaapiProfile profile) + const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile) { guint32 constraint_set0_flag, constraint_set1_flag; guint32 constraint_set2_flag, constraint_set3_flag; @@ -404,9 +402,10 @@ gst_bit_writer_write_sps (GstBitWriter * bitwriter, guint32 b_qpprime_y_zero_transform_bypass = 0; guint32 residual_color_transform_flag = 0; guint32 pic_height_in_map_units = - (seq->seq_fields.bits.frame_mbs_only_flag ? - seq->picture_height_in_mbs : seq->picture_height_in_mbs / 2); - guint32 mb_adaptive_frame_field = !seq->seq_fields.bits.frame_mbs_only_flag; + (seq_param->seq_fields.bits.frame_mbs_only_flag ? + seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2); + guint32 mb_adaptive_frame_field = + !seq_param->seq_fields.bits.frame_mbs_only_flag; guint32 i = 0; constraint_set0_flag = profile == GST_VAAPI_PROFILE_H264_BASELINE; @@ -427,37 +426,39 @@ gst_bit_writer_write_sps (GstBitWriter * bitwriter, /* reserved_zero_4bits */ gst_bit_writer_put_bits_uint32 (bitwriter, 0, 4); /* level_idc */ - gst_bit_writer_put_bits_uint32 (bitwriter, seq->level_idc, 8); + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->level_idc, 8); /* seq_parameter_set_id */ - gst_bit_writer_put_ue (bitwriter, seq->seq_parameter_set_id); + gst_bit_writer_put_ue (bitwriter, seq_param->seq_parameter_set_id); if (profile == GST_VAAPI_PROFILE_H264_HIGH) { /* for high profile */ /* chroma_format_idc = 1, 4:2:0 */ - gst_bit_writer_put_ue (bitwriter, seq->seq_fields.bits.chroma_format_idc); - if (3 == seq->seq_fields.bits.chroma_format_idc) { + gst_bit_writer_put_ue (bitwriter, + seq_param->seq_fields.bits.chroma_format_idc); + if (3 == seq_param->seq_fields.bits.chroma_format_idc) { gst_bit_writer_put_bits_uint32 (bitwriter, residual_color_transform_flag, 1); } /* bit_depth_luma_minus8 */ - gst_bit_writer_put_ue (bitwriter, seq->bit_depth_luma_minus8); + gst_bit_writer_put_ue (bitwriter, seq_param->bit_depth_luma_minus8); /* bit_depth_chroma_minus8 */ - gst_bit_writer_put_ue (bitwriter, seq->bit_depth_chroma_minus8); + gst_bit_writer_put_ue (bitwriter, seq_param->bit_depth_chroma_minus8); /* b_qpprime_y_zero_transform_bypass */ gst_bit_writer_put_bits_uint32 (bitwriter, b_qpprime_y_zero_transform_bypass, 1); - g_assert (seq->seq_fields.bits.seq_scaling_matrix_present_flag == 0); - /*seq_scaling_matrix_present_flag */ + g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0); + /* seq_scaling_matrix_present_flag */ gst_bit_writer_put_bits_uint32 (bitwriter, - seq->seq_fields.bits.seq_scaling_matrix_present_flag, 1); + seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1); #if 0 - if (seq->seq_fields.bits.seq_scaling_matrix_present_flag) { - for (i = 0; i < (seq->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); + if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) { + for (i = 0; + i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); i++) { gst_bit_writer_put_bits_uint8 (bitwriter, - seq->seq_fields.bits.seq_scaling_list_present_flag, 1); - if (seq->seq_fields.bits.seq_scaling_list_present_flag) { + seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1); + if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) { g_assert (0); /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */ } @@ -468,42 +469,44 @@ gst_bit_writer_write_sps (GstBitWriter * bitwriter, /* log2_max_frame_num_minus4 */ gst_bit_writer_put_ue (bitwriter, - seq->seq_fields.bits.log2_max_frame_num_minus4); + seq_param->seq_fields.bits.log2_max_frame_num_minus4); /* pic_order_cnt_type */ - gst_bit_writer_put_ue (bitwriter, seq->seq_fields.bits.pic_order_cnt_type); + gst_bit_writer_put_ue (bitwriter, + seq_param->seq_fields.bits.pic_order_cnt_type); - if (seq->seq_fields.bits.pic_order_cnt_type == 0) { + if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) { /* log2_max_pic_order_cnt_lsb_minus4 */ gst_bit_writer_put_ue (bitwriter, - seq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4); - } else if (seq->seq_fields.bits.pic_order_cnt_type == 1) { + seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4); + } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { g_assert (0); gst_bit_writer_put_bits_uint32 (bitwriter, - seq->seq_fields.bits.delta_pic_order_always_zero_flag, 1); - gst_bit_writer_put_se (bitwriter, seq->offset_for_non_ref_pic); - gst_bit_writer_put_se (bitwriter, seq->offset_for_top_to_bottom_field); + seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1); + gst_bit_writer_put_se (bitwriter, seq_param->offset_for_non_ref_pic); + gst_bit_writer_put_se (bitwriter, + seq_param->offset_for_top_to_bottom_field); gst_bit_writer_put_ue (bitwriter, - seq->num_ref_frames_in_pic_order_cnt_cycle); - for (i = 0; i < seq->num_ref_frames_in_pic_order_cnt_cycle; i++) { - gst_bit_writer_put_se (bitwriter, seq->offset_for_ref_frame[i]); + seq_param->num_ref_frames_in_pic_order_cnt_cycle); + for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) { + gst_bit_writer_put_se (bitwriter, seq_param->offset_for_ref_frame[i]); } } /* num_ref_frames */ - gst_bit_writer_put_ue (bitwriter, seq->max_num_ref_frames); + gst_bit_writer_put_ue (bitwriter, seq_param->max_num_ref_frames); /* gaps_in_frame_num_value_allowed_flag */ gst_bit_writer_put_bits_uint32 (bitwriter, gaps_in_frame_num_value_allowed_flag, 1); /* pic_width_in_mbs_minus1 */ - gst_bit_writer_put_ue (bitwriter, seq->picture_width_in_mbs - 1); + gst_bit_writer_put_ue (bitwriter, seq_param->picture_width_in_mbs - 1); /* pic_height_in_map_units_minus1 */ gst_bit_writer_put_ue (bitwriter, pic_height_in_map_units - 1); /* frame_mbs_only_flag */ gst_bit_writer_put_bits_uint32 (bitwriter, - seq->seq_fields.bits.frame_mbs_only_flag, 1); + seq_param->seq_fields.bits.frame_mbs_only_flag, 1); - if (!seq->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs + if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs g_assert (0); gst_bit_writer_put_bits_uint32 (bitwriter, mb_adaptive_frame_field, 1); } @@ -511,31 +514,32 @@ gst_bit_writer_write_sps (GstBitWriter * bitwriter, /* direct_8x8_inference_flag */ gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); /* frame_cropping_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, seq->frame_cropping_flag, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->frame_cropping_flag, 1); - if (seq->frame_cropping_flag) { + if (seq_param->frame_cropping_flag) { /* frame_crop_left_offset */ - gst_bit_writer_put_ue (bitwriter, seq->frame_crop_left_offset); + gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_left_offset); /* frame_crop_right_offset */ - gst_bit_writer_put_ue (bitwriter, seq->frame_crop_right_offset); + gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_right_offset); /* frame_crop_top_offset */ - gst_bit_writer_put_ue (bitwriter, seq->frame_crop_top_offset); + gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_top_offset); /* frame_crop_bottom_offset */ - gst_bit_writer_put_ue (bitwriter, seq->frame_crop_bottom_offset); + gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_bottom_offset); } /* vui_parameters_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, seq->vui_parameters_present_flag, - 1); - if (seq->vui_parameters_present_flag) { + gst_bit_writer_put_bits_uint32 (bitwriter, + seq_param->vui_parameters_present_flag, 1); + if (seq_param->vui_parameters_present_flag) { /* aspect_ratio_info_present_flag */ gst_bit_writer_put_bits_uint32 (bitwriter, - seq->vui_fields.bits.aspect_ratio_info_present_flag, 1); - if (seq->vui_fields.bits.aspect_ratio_info_present_flag) { - gst_bit_writer_put_bits_uint32 (bitwriter, seq->aspect_ratio_idc, 8); - if (seq->aspect_ratio_idc == 0xFF) { - gst_bit_writer_put_bits_uint32 (bitwriter, seq->sar_width, 16); - gst_bit_writer_put_bits_uint32 (bitwriter, seq->sar_height, 16); + seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1); + if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->aspect_ratio_idc, + 8); + if (seq_param->aspect_ratio_idc == 0xFF) { + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->sar_width, 16); + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->sar_height, 16); } } @@ -548,14 +552,16 @@ gst_bit_writer_write_sps (GstBitWriter * bitwriter, /* timing_info_present_flag */ gst_bit_writer_put_bits_uint32 (bitwriter, - seq->vui_fields.bits.timing_info_present_flag, 1); - if (seq->vui_fields.bits.timing_info_present_flag) { - gst_bit_writer_put_bits_uint32 (bitwriter, seq->num_units_in_tick, 32); - gst_bit_writer_put_bits_uint32 (bitwriter, seq->time_scale, 32); + seq_param->vui_fields.bits.timing_info_present_flag, 1); + if (seq_param->vui_fields.bits.timing_info_present_flag) { + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->num_units_in_tick, + 32); + gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->time_scale, 32); gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* fixed_frame_rate_flag */ } - nal_hrd_parameters_present_flag = (seq->bits_per_second > 0 ? TRUE : FALSE); + nal_hrd_parameters_present_flag = + (seq_param->bits_per_second > 0 ? TRUE : FALSE); /* nal_hrd_parameters_present_flag */ gst_bit_writer_put_bits_uint32 (bitwriter, nal_hrd_parameters_present_flag, 1); @@ -568,9 +574,11 @@ gst_bit_writer_write_sps (GstBitWriter * bitwriter, for (i = 0; i < 1; ++i) { /* bit_rate_value_minus1[0] */ - gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1000 - 1); + gst_bit_writer_put_ue (bitwriter, + seq_param->bits_per_second / 1000 - 1); /* cpb_size_value_minus1[0] */ - gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1000 * 8 - 1); + gst_bit_writer_put_ue (bitwriter, + seq_param->bits_per_second / 1000 * 8 - 1); /* cbr_flag[0] */ gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); } @@ -603,65 +611,65 @@ gst_bit_writer_write_sps (GstBitWriter * bitwriter, static gboolean gst_bit_writer_write_pps (GstBitWriter * bitwriter, - VAEncPictureParameterBufferH264 * pic) + const VAEncPictureParameterBufferH264 * pic_param) { guint32 num_slice_groups_minus1 = 0; guint32 pic_init_qs_minus26 = 0; guint32 redundant_pic_cnt_present_flag = 0; /* pic_parameter_set_id */ - gst_bit_writer_put_ue (bitwriter, pic->pic_parameter_set_id); + gst_bit_writer_put_ue (bitwriter, pic_param->pic_parameter_set_id); /* seq_parameter_set_id */ - gst_bit_writer_put_ue (bitwriter, pic->seq_parameter_set_id); + gst_bit_writer_put_ue (bitwriter, pic_param->seq_parameter_set_id); /* entropy_coding_mode_flag */ gst_bit_writer_put_bits_uint32 (bitwriter, - pic->pic_fields.bits.entropy_coding_mode_flag, 1); + pic_param->pic_fields.bits.entropy_coding_mode_flag, 1); /* pic_order_present_flag */ gst_bit_writer_put_bits_uint32 (bitwriter, - pic->pic_fields.bits.pic_order_present_flag, 1); - /*slice_groups-1 */ + pic_param->pic_fields.bits.pic_order_present_flag, 1); + /* slice_groups-1 */ gst_bit_writer_put_ue (bitwriter, num_slice_groups_minus1); if (num_slice_groups_minus1 > 0) { /*FIXME*/ g_assert (0); } - gst_bit_writer_put_ue (bitwriter, pic->num_ref_idx_l0_active_minus1); - gst_bit_writer_put_ue (bitwriter, pic->num_ref_idx_l1_active_minus1); + gst_bit_writer_put_ue (bitwriter, pic_param->num_ref_idx_l0_active_minus1); + gst_bit_writer_put_ue (bitwriter, pic_param->num_ref_idx_l1_active_minus1); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->pic_fields.bits.weighted_pred_flag, 1); + pic_param->pic_fields.bits.weighted_pred_flag, 1); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->pic_fields.bits.weighted_bipred_idc, 2); + pic_param->pic_fields.bits.weighted_bipred_idc, 2); /* pic_init_qp_minus26 */ - gst_bit_writer_put_se (bitwriter, pic->pic_init_qp - 26); + gst_bit_writer_put_se (bitwriter, pic_param->pic_init_qp - 26); /* pic_init_qs_minus26 */ gst_bit_writer_put_se (bitwriter, pic_init_qs_minus26); - /*chroma_qp_index_offset */ - gst_bit_writer_put_se (bitwriter, pic->chroma_qp_index_offset); + /* chroma_qp_index_offset */ + gst_bit_writer_put_se (bitwriter, pic_param->chroma_qp_index_offset); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->pic_fields.bits.deblocking_filter_control_present_flag, 1); + pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->pic_fields.bits.constrained_intra_pred_flag, 1); + pic_param->pic_fields.bits.constrained_intra_pred_flag, 1); gst_bit_writer_put_bits_uint32 (bitwriter, redundant_pic_cnt_present_flag, 1); - /*more_rbsp_data */ + /* more_rbsp_data */ gst_bit_writer_put_bits_uint32 (bitwriter, - pic->pic_fields.bits.transform_8x8_mode_flag, 1); + pic_param->pic_fields.bits.transform_8x8_mode_flag, 1); gst_bit_writer_put_bits_uint32 (bitwriter, - pic->pic_fields.bits.pic_scaling_matrix_present_flag, 1); - if (pic->pic_fields.bits.pic_scaling_matrix_present_flag) { + pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1); + if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) { g_assert (0); /* FIXME */ /* for (i = 0; i < - (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic->pic_fields.bits.transform_8x8_mode_flag)); + (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag)); i++) { - gst_bit_writer_put_bits_uint8(bitwriter, pic->pic_fields.bits.pic_scaling_list_present_flag, 1); + gst_bit_writer_put_bits_uint8(bitwriter, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1); } */ } - gst_bit_writer_put_se (bitwriter, pic->second_chroma_qp_index_offset); + gst_bit_writer_put_se (bitwriter, pic_param->second_chroma_qp_index_offset); gst_bit_writer_write_trailing_bits (bitwriter); return TRUE; @@ -674,7 +682,7 @@ add_sequence_packed_header (GstVaapiEncoderH264 * encoder, GstVaapiEncPackedHeader *packed_seq; GstBitWriter writer; VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; - VAEncSequenceParameterBufferH264 *seq_param = sequence->param; + const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; guint32 data_bit_size; guint8 *data; @@ -697,11 +705,10 @@ add_sequence_packed_header (GstVaapiEncoderH264 * encoder, g_assert (packed_seq); gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL); + gst_vaapi_codec_object_replace (&packed_seq, NULL); /* store sps data */ _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&writer, TRUE); return TRUE; @@ -714,7 +721,7 @@ add_picture_packed_header (GstVaapiEncoderH264 * encoder, GstVaapiEncPackedHeader *packed_pic; GstBitWriter writer; VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; - VAEncPictureParameterBufferH264 *pic_param = picture->param; + const VAEncPictureParameterBufferH264 *const pic_param = picture->param; guint32 data_bit_size; guint8 *data; @@ -737,7 +744,7 @@ add_picture_packed_header (GstVaapiEncoderH264 * encoder, g_assert (packed_pic); gst_vaapi_enc_picture_add_packed_header (picture, packed_pic); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_pic, NULL); + gst_vaapi_codec_object_replace (&packed_pic, NULL); /* store pps data */ _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); @@ -761,7 +768,7 @@ static inline GstVaapiEncoderH264Ref * reference_pic_create (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) { - GstVaapiEncoderH264Ref *ref = g_slice_new0 (GstVaapiEncoderH264Ref); + GstVaapiEncoderH264Ref *const ref = g_slice_new0 (GstVaapiEncoderH264Ref); ref->pic = surface; ref->frame_num = picture->frame_num; @@ -782,12 +789,12 @@ reference_list_update (GstVaapiEncoderH264 * encoder, if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { while (!g_queue_is_empty (&encoder->ref_list)) reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list)); - } else if (g_queue_get_length (&encoder->ref_list) >= encoder->max_ref_num) { + } else if (g_queue_get_length (&encoder->ref_list) >= encoder->max_ref_frames) { reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list)); } ref = reference_pic_create (encoder, picture, surface); g_queue_push_tail (&encoder->ref_list, ref); - g_assert (g_queue_get_length (&encoder->ref_list) <= encoder->max_ref_num); + g_assert (g_queue_get_length (&encoder->ref_list) <= encoder->max_ref_frames); return TRUE; } @@ -849,75 +856,73 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - VAEncSequenceParameterBufferH264 *seq = sequence->param; - guint width_in_mbs, height_in_mbs; + VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; - width_in_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; - height_in_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; - - memset (seq, 0, sizeof (VAEncSequenceParameterBufferH264)); - seq->seq_parameter_set_id = 0; - seq->level_idc = encoder->level; - seq->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); - seq->ip_period = 0; // ? + memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264)); + seq_param->seq_parameter_set_id = 0; + seq_param->level_idc = encoder->level_idc; + seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); + seq_param->ip_period = 0; // ? if (base_encoder->bitrate > 0) - seq->bits_per_second = base_encoder->bitrate * 1000; + seq_param->bits_per_second = base_encoder->bitrate * 1000; else - seq->bits_per_second = 0; + seq_param->bits_per_second = 0; - seq->max_num_ref_frames = encoder->max_ref_num; - seq->picture_width_in_mbs = width_in_mbs; - seq->picture_height_in_mbs = height_in_mbs; + seq_param->max_num_ref_frames = encoder->max_ref_frames; + seq_param->picture_width_in_mbs = encoder->mb_width; + seq_param->picture_height_in_mbs = encoder->mb_height; /*sequence field values */ - seq->seq_fields.value = 0; - seq->seq_fields.bits.chroma_format_idc = 1; - seq->seq_fields.bits.frame_mbs_only_flag = 1; - seq->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE; - seq->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE; + seq_param->seq_fields.value = 0; + seq_param->seq_fields.bits.chroma_format_idc = 1; + seq_param->seq_fields.bits.frame_mbs_only_flag = 1; + seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE; + seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE; /* direct_8x8_inference_flag default false */ - seq->seq_fields.bits.direct_8x8_inference_flag = FALSE; + seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE; g_assert (encoder->log2_max_frame_num >= 4); - seq->seq_fields.bits.log2_max_frame_num_minus4 = + seq_param->seq_fields.bits.log2_max_frame_num_minus4 = encoder->log2_max_frame_num - 4; /* picture order count */ - seq->seq_fields.bits.pic_order_cnt_type = 0; + seq_param->seq_fields.bits.pic_order_cnt_type = 0; g_assert (encoder->log2_max_pic_order_cnt >= 4); - seq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = + seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = encoder->log2_max_pic_order_cnt - 4; - seq->bit_depth_luma_minus8 = 0; - seq->bit_depth_chroma_minus8 = 0; + seq_param->bit_depth_luma_minus8 = 0; + seq_param->bit_depth_chroma_minus8 = 0; /* not used if pic_order_cnt_type == 0 */ - if (seq->seq_fields.bits.pic_order_cnt_type == 1) { - seq->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE; - seq->num_ref_frames_in_pic_order_cnt_cycle = 0; - seq->offset_for_non_ref_pic = 0; - seq->offset_for_top_to_bottom_field = 0; - memset (seq->offset_for_ref_frame, 0, sizeof (seq->offset_for_ref_frame)); + if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { + seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE; + seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0; + seq_param->offset_for_non_ref_pic = 0; + seq_param->offset_for_top_to_bottom_field = 0; + memset (seq_param->offset_for_ref_frame, 0, + sizeof (seq_param->offset_for_ref_frame)); } - if (height_in_mbs * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) { - seq->frame_cropping_flag = 1; - seq->frame_crop_left_offset = 0; - seq->frame_crop_right_offset = 0; - seq->frame_crop_top_offset = 0; - seq->frame_crop_bottom_offset = - ((height_in_mbs * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) / - (2 * (!seq->seq_fields.bits.frame_mbs_only_flag + 1))); + if (encoder->mb_height * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) { + seq_param->frame_cropping_flag = 1; + seq_param->frame_crop_left_offset = 0; + seq_param->frame_crop_right_offset = 0; + seq_param->frame_crop_top_offset = 0; + seq_param->frame_crop_bottom_offset = + ((encoder->mb_height * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) / + (2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1))); } - /*vui not set */ - seq->vui_parameters_present_flag = (base_encoder->bitrate > 0 ? TRUE : FALSE); - if (seq->vui_parameters_present_flag) { - seq->vui_fields.bits.aspect_ratio_info_present_flag = FALSE; - seq->vui_fields.bits.bitstream_restriction_flag = FALSE; - seq->vui_fields.bits.timing_info_present_flag = + /* vui not set */ + seq_param->vui_parameters_present_flag = + (base_encoder->bitrate > 0 ? TRUE : FALSE); + if (seq_param->vui_parameters_present_flag) { + seq_param->vui_fields.bits.aspect_ratio_info_present_flag = FALSE; + seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE; + seq_param->vui_fields.bits.timing_info_present_flag = (base_encoder->bitrate > 0 ? TRUE : FALSE); - if (seq->vui_fields.bits.timing_info_present_flag) { - seq->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder); - seq->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2; + if (seq_param->vui_fields.bits.timing_info_present_flag) { + seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder); + seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2; } } @@ -929,16 +934,16 @@ fill_va_picture_param (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) { - VAEncPictureParameterBufferH264 *pic = picture->param; + VAEncPictureParameterBufferH264 *const pic_param = picture->param; GstVaapiEncoderH264Ref *ref_pic; GList *reflist; guint i; - memset (pic, 0, sizeof (VAEncPictureParameterBufferH264)); + memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264)); /* reference list, */ - pic->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); - pic->CurrPic.TopFieldOrderCnt = picture->poc; + pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); + pic_param->CurrPic.TopFieldOrderCnt = picture->poc; i = 0; if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { for (reflist = g_queue_peek_head_link (&encoder->ref_list); @@ -947,46 +952,47 @@ fill_va_picture_param (GstVaapiEncoderH264 * encoder, g_assert (ref_pic && ref_pic->pic && GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID); - pic->ReferenceFrames[i].picture_id = + pic_param->ReferenceFrames[i].picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); ++i; } - g_assert (i <= 16 && i <= encoder->max_ref_num); + g_assert (i <= 16 && i <= encoder->max_ref_frames); } for (; i < 16; ++i) { - pic->ReferenceFrames[i].picture_id = VA_INVALID_ID; + pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID; } - pic->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); - pic->pic_parameter_set_id = 0; - pic->seq_parameter_set_id = 0; - pic->last_picture = 0; /* means last encoding picture */ - pic->frame_num = picture->frame_num; - pic->pic_init_qp = encoder->init_qp; - pic->num_ref_idx_l0_active_minus1 = + pic_param->pic_parameter_set_id = 0; + pic_param->seq_parameter_set_id = 0; + pic_param->last_picture = 0; /* means last encoding picture */ + pic_param->frame_num = picture->frame_num; + pic_param->pic_init_qp = encoder->init_qp; + pic_param->num_ref_idx_l0_active_minus1 = (encoder->max_reflist0_count ? (encoder->max_reflist0_count - 1) : 0); - pic->num_ref_idx_l1_active_minus1 = + pic_param->num_ref_idx_l1_active_minus1 = (encoder->max_reflist1_count ? (encoder->max_reflist1_count - 1) : 0); - pic->chroma_qp_index_offset = 0; - pic->second_chroma_qp_index_offset = 0; + pic_param->chroma_qp_index_offset = 0; + pic_param->second_chroma_qp_index_offset = 0; /* set picture fields */ - pic->pic_fields.value = 0; - pic->pic_fields.bits.idr_pic_flag = GST_VAAPI_ENC_PICTURE_IS_IDR (picture); - pic->pic_fields.bits.reference_pic_flag = + pic_param->pic_fields.value = 0; + pic_param->pic_fields.bits.idr_pic_flag = + GST_VAAPI_ENC_PICTURE_IS_IDR (picture); + pic_param->pic_fields.bits.reference_pic_flag = (picture->type != GST_VAAPI_PICTURE_TYPE_B); - pic->pic_fields.bits.entropy_coding_mode_flag = + pic_param->pic_fields.bits.entropy_coding_mode_flag = GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CABAC; - pic->pic_fields.bits.weighted_pred_flag = FALSE; - pic->pic_fields.bits.weighted_bipred_idc = 0; - pic->pic_fields.bits.constrained_intra_pred_flag = 0; - pic->pic_fields.bits.transform_8x8_mode_flag = (encoder->profile >= GST_VAAPI_PROFILE_H264_HIGH); /* enable 8x8 */ + pic_param->pic_fields.bits.weighted_pred_flag = FALSE; + pic_param->pic_fields.bits.weighted_bipred_idc = 0; + pic_param->pic_fields.bits.constrained_intra_pred_flag = 0; + pic_param->pic_fields.bits.transform_8x8_mode_flag = (encoder->profile >= GST_VAAPI_PROFILE_H264_HIGH); /* enable 8x8 */ /* enable debloking */ - pic->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; - pic->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE; + pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; + pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE; /* bottom_field_pic_order_in_frame_present_flag */ - pic->pic_fields.bits.pic_order_present_flag = FALSE; - pic->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE; + pic_param->pic_fields.bits.pic_order_present_flag = FALSE; + pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE; return TRUE; } @@ -1000,23 +1006,20 @@ fill_va_slices_param (GstVaapiEncoderH264 * encoder, { VAEncSliceParameterBufferH264 *slice_param; GstVaapiEncSlice *slice; - guint width_in_mbs, height_in_mbs; guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs; - guint total_mbs; + guint mb_size; guint last_mb_index; guint i_slice, i_ref; g_assert (picture); - width_in_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; - height_in_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; - total_mbs = width_in_mbs * height_in_mbs; + mb_size = encoder->mb_width * encoder->mb_height; - g_assert (encoder->slice_num && encoder->slice_num < total_mbs); - slice_of_mbs = total_mbs / encoder->slice_num; - slice_mod_mbs = total_mbs % encoder->slice_num; + g_assert (encoder->num_slices && encoder->num_slices < mb_size); + slice_of_mbs = mb_size / encoder->num_slices; + slice_mod_mbs = mb_size % encoder->num_slices; last_mb_index = 0; - for (i_slice = 0; i_slice < encoder->slice_num; ++i_slice) { + for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) { cur_slice_mbs = slice_of_mbs; if (slice_mod_mbs) { ++cur_slice_mbs; @@ -1030,7 +1033,7 @@ fill_va_slices_param (GstVaapiEncoderH264 * encoder, slice_param->macroblock_address = last_mb_index; slice_param->num_macroblocks = cur_slice_mbs; slice_param->macroblock_info = VA_INVALID_ID; - slice_param->slice_type = _get_va_slice_type (picture->type); + slice_param->slice_type = h264_get_slice_type (picture->type); g_assert (slice_param->slice_type != -1); slice_param->pic_parameter_set_id = 0; slice_param->idr_pic_id = encoder->idr_num; @@ -1038,10 +1041,10 @@ fill_va_slices_param (GstVaapiEncoderH264 * encoder, /* not used if pic_order_cnt_type = 0 */ slice_param->delta_pic_order_cnt_bottom = 0; - memset (slice_param->delta_pic_order_cnt, - 0, sizeof (slice_param->delta_pic_order_cnt)); + memset (slice_param->delta_pic_order_cnt, 0, + sizeof (slice_param->delta_pic_order_cnt)); - /*only works for B frames */ + /* only works for B frames */ slice_param->direct_spatial_mv_pred_flag = FALSE; /* default equal to picture parameters */ slice_param->num_ref_idx_active_override_flag = FALSE; @@ -1064,10 +1067,7 @@ fill_va_slices_param (GstVaapiEncoderH264 * encoder, } g_assert (i_ref == 1); } - for (; - i_ref < - sizeof (slice_param->RefPicList0) / - sizeof (slice_param->RefPicList0[0]); ++i_ref) { + for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) { slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE; } @@ -1079,10 +1079,7 @@ fill_va_slices_param (GstVaapiEncoderH264 * encoder, } g_assert (i_ref == 1); } - for (; - i_ref < - sizeof (slice_param->RefPicList1) / - sizeof (slice_param->RefPicList1[0]); ++i_ref) { + for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) { slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE; } @@ -1122,10 +1119,9 @@ fill_va_slices_param (GstVaapiEncoderH264 * encoder, last_mb_index += cur_slice_mbs; gst_vaapi_enc_picture_add_slice (picture, slice); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & slice, NULL); - + gst_vaapi_codec_object_replace (&slice, NULL); } - g_assert (last_mb_index == total_mbs); + g_assert (last_mb_index == mb_size); return TRUE; } @@ -1147,11 +1143,11 @@ ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) !add_sequence_packed_header (encoder, picture, sequence)) goto error; gst_vaapi_enc_picture_set_sequence (picture, sequence); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL); + gst_vaapi_codec_object_replace (&sequence, NULL); return TRUE; error: - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL); + gst_vaapi_codec_object_replace (&sequence, NULL); return FALSE; } @@ -1190,7 +1186,7 @@ ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) return FALSE; } - g_assert (reflist_0_count + reflist_1_count <= encoder->max_ref_num); + g_assert (reflist_0_count + reflist_1_count <= encoder->max_ref_frames); if (reflist_0_count > encoder->max_reflist0_count) reflist_0_count = encoder->max_reflist0_count; if (reflist_1_count > encoder->max_reflist1_count) @@ -1225,7 +1221,7 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) hrd->initial_buffer_fullness = 0; hrd->buffer_size = 0; } - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL); + gst_vaapi_codec_object_replace (&misc, NULL); /* add ratecontrol */ if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR || @@ -1246,7 +1242,7 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) rate_control->initial_qp = encoder->init_qp; rate_control->min_qp = encoder->min_qp; rate_control->basic_unit_size = 0; - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL); + gst_vaapi_codec_object_replace (&misc, NULL); } return TRUE; @@ -1289,7 +1285,7 @@ static void reset_properties (GstVaapiEncoderH264 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - guint width_mbs, height_mbs, total_mbs; + guint mb_size; if (encoder->idr_period < base_encoder->keyframe_period) encoder->idr_period = base_encoder->keyframe_period; @@ -1301,28 +1297,26 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->min_qp < encoder->init_qp)) encoder->min_qp = encoder->init_qp; - width_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; - height_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; - total_mbs = width_mbs * height_mbs; + mb_size = encoder->mb_width * encoder->mb_height; + if (encoder->num_slices > (mb_size + 1) / 2) + encoder->num_slices = (mb_size + 1) / 2; + g_assert (encoder->num_slices); - if (encoder->slice_num > (total_mbs + 1) / 2) - encoder->slice_num = (total_mbs + 1) / 2; - g_assert (encoder->slice_num); + if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) + encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; - if (encoder->b_frame_num > (base_encoder->keyframe_period + 1) / 2) - encoder->b_frame_num = (base_encoder->keyframe_period + 1) / 2; + if (encoder->num_bframes > 50) + encoder->num_bframes = 50; - if (encoder->b_frame_num > 50) - encoder->b_frame_num = 50; - - if (encoder->b_frame_num) + if (encoder->num_bframes) encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) / GST_VAAPI_ENCODER_FPS_N (encoder); else encoder->cts_offset = 0; /* init max_frame_num, max_poc */ - encoder->log2_max_frame_num = _get_log2_max_frame_num (encoder->idr_period); + encoder->log2_max_frame_num = + h264_get_log2_max_frame_num (encoder->idr_period); g_assert (encoder->log2_max_frame_num >= 4); encoder->max_frame_num = (1 << encoder->log2_max_frame_num); encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1; @@ -1331,24 +1325,21 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->frame_index = 0; encoder->idr_num = 0; encoder->max_reflist0_count = 1; - if (encoder->b_frame_num) - encoder->max_reflist1_count = 1; - else - encoder->max_reflist1_count = 0; - encoder->max_ref_num = + encoder->max_reflist1_count = encoder->num_bframes > 0; + encoder->max_ref_frames = encoder->max_reflist0_count + encoder->max_reflist1_count; } - static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base, +gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base_encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) { - GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base); + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264_CAST (base_encoder); GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; - reconstruct = gst_vaapi_encoder_create_surface (base); + reconstruct = gst_vaapi_encoder_create_surface (base_encoder); g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct)); @@ -1375,17 +1366,17 @@ error: } static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base) +gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base); + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264_CAST (base_encoder); GstVaapiEncPicture *pic; encoder->frame_index = 0; encoder->cur_frame_num = 0; encoder->cur_present_index = 0; while (!g_queue_is_empty (&encoder->reorder_frame_list)) { - pic = - (GstVaapiEncPicture *) g_queue_pop_head (&encoder->reorder_frame_list); + pic = g_queue_pop_head (&encoder->reorder_frame_list); gst_vaapi_enc_picture_unref (pic); } g_queue_clear (&encoder->reorder_frame_list); @@ -1468,10 +1459,11 @@ end: } static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base, +gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder, GstBuffer ** buffer) { - GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base); + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264_CAST (base_encoder); *buffer = NULL; @@ -1482,10 +1474,11 @@ gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base, } static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base, +gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) { - GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base); + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264_CAST (base_encoder); GstVaapiEncPicture *picture; gboolean is_idr = FALSE; @@ -1497,7 +1490,7 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base, /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES dump B frames from queue, sometime, there may also have P frame or I frame */ - g_assert (encoder->b_frame_num > 0); + g_assert (encoder->num_bframes > 0); g_return_val_if_fail (!g_queue_is_empty (&encoder->reorder_frame_list), GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN); picture = g_queue_pop_head (&encoder->reorder_frame_list); @@ -1530,7 +1523,7 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base, ++encoder->frame_index; /* b frame enabled, check queue of reorder_frame_list */ - if (encoder->b_frame_num + if (encoder->num_bframes && !g_queue_is_empty (&encoder->reorder_frame_list)) { GstVaapiEncPicture *p_pic; @@ -1546,7 +1539,7 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base, } else { /* no b frames in queue */ _set_key_frame (picture, encoder, is_idr); g_assert (g_queue_is_empty (&encoder->reorder_frame_list)); - if (encoder->b_frame_num) + if (encoder->num_bframes) encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; } goto end; @@ -1556,7 +1549,7 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base, ++encoder->frame_index; if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES && g_queue_get_length (&encoder->reorder_frame_list) < - encoder->b_frame_num) { + encoder->num_bframes) { g_queue_push_tail (&encoder->reorder_frame_list, picture); return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; } @@ -1584,7 +1577,8 @@ end: static void set_context_info (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264_CAST (base_encoder); GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); const guint DEFAULT_SURFACES_COUNT = 3; @@ -1600,7 +1594,7 @@ set_context_info (GstVaapiEncoder * base_encoder) base_encoder->profile = encoder->profile; base_encoder->num_ref_frames = - (encoder->b_frame_num ? 2 : 1) + DEFAULT_SURFACES_COUNT; + (encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT; /* Only YUV 4:2:0 formats are supported for now. This means that we have a limit of 3200 bits per macroblock. */ @@ -1628,6 +1622,9 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264_CAST (base_encoder); + encoder->mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; + encoder->mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; + if (!ensure_profile_and_level (encoder)) goto error; if (!ensure_bitrate (encoder)) @@ -1642,49 +1639,30 @@ error: } static gboolean -gst_vaapi_encoder_h264_init (GstVaapiEncoder * base) +gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base); + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264_CAST (base_encoder); - /* init attributes */ - encoder->profile = 0; - encoder->level = 0; - encoder->idr_period = 0; - //gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE); - - /* init private values */ - encoder->is_avc = FALSE; /* re-ordering */ g_queue_init (&encoder->reorder_frame_list); encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE; - encoder->frame_index = 0; - encoder->cur_frame_num = 0; - encoder->cur_present_index = 0; + /* reference frames */ g_queue_init (&encoder->ref_list); - encoder->max_ref_num = 0; + encoder->max_ref_frames = 0; encoder->max_reflist0_count = 1; encoder->max_reflist1_count = 1; - encoder->sps_data = NULL; - encoder->pps_data = NULL; - - encoder->cts_offset = 0; - - encoder->max_frame_num = 0; - encoder->log2_max_frame_num = 0; - encoder->max_pic_order_cnt = 0; - encoder->log2_max_pic_order_cnt = 0; - encoder->idr_num = 0; - return TRUE; } static void -gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base) +gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder) { /*free private buffers */ - GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base); + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264_CAST (base_encoder); GstVaapiEncPicture *pic; GstVaapiEncoderH264Ref *ref; @@ -1692,14 +1670,13 @@ gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base) gst_buffer_replace (&encoder->pps_data, NULL); while (!g_queue_is_empty (&encoder->ref_list)) { - ref = (GstVaapiEncoderH264Ref *) g_queue_pop_head (&encoder->ref_list); + ref = g_queue_pop_head (&encoder->ref_list); reference_pic_free (encoder, ref); } g_queue_clear (&encoder->ref_list); while (!g_queue_is_empty (&encoder->reorder_frame_list)) { - pic = - (GstVaapiEncPicture *) g_queue_pop_head (&encoder->reorder_frame_list); + pic = g_queue_pop_head (&encoder->reorder_frame_list); gst_vaapi_enc_picture_unref (pic); } g_queue_clear (&encoder->reorder_frame_list); @@ -1710,11 +1687,12 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { - GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264_CAST (base_encoder); switch (prop_id) { case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES: - encoder->b_frame_num = g_value_get_uint (value); + encoder->num_bframes = g_value_get_uint (value); break; case GST_VAAPI_ENCODER_H264_PROP_INIT_QP: encoder->init_qp = g_value_get_uint (value); @@ -1723,7 +1701,7 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, encoder->min_qp = g_value_get_uint (value); break; case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES: - encoder->slice_num = g_value_get_uint (value); + encoder->num_slices = g_value_get_uint (value); break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; @@ -1744,6 +1722,15 @@ gst_vaapi_encoder_h264_class (void) return &GstVaapiEncoderH264Class; } +/** + * gst_vaapi_encoder_h264_new: + * @display: a #GstVaapiDisplay + * + * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the + * only supported output stream format is "byte-stream" format. + * + * Return value: the newly allocated #GstVaapiEncoder object + */ GstVaapiEncoder * gst_vaapi_encoder_h264_new (GstVaapiDisplay * display) { diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 9b3eb4981e..0c64e0f341 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -26,6 +26,9 @@ G_BEGIN_DECLS +#define GST_VAAPI_ENCODER_H264(encoder) \ + ((GstVaapiEncoderH264 *) (encoder)) + typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h index f2b3a8e316..6d8ef763d4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h @@ -22,15 +22,10 @@ #ifndef GST_VAAPI_ENCODER_H264_PRIV_H #define GST_VAAPI_ENCODER_H264_PRIV_H -#include -#include -#include -#include +#include "gstvaapiencoder_priv.h" G_BEGIN_DECLS -#define GST_VAAPI_ENCODER_H264(encoder) \ - ((GstVaapiEncoderH264 *)(encoder)) #define GST_VAAPI_ENCODER_H264_CAST(encoder) \ ((GstVaapiEncoderH264 *)(encoder)) @@ -55,26 +50,22 @@ typedef enum #define GST_VAAPI_ENCODER_H264_DEFAULT_PROFILE GST_VAAPI_PROFILE_H264_BASELINE #define GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL GST_VAAPI_ENCODER_H264_LEVEL_31 -#define GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP 26 -#define GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP 1 #define GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD 512 -#define GST_VAAPI_ENCODER_H264_DEFAULT_SLICE_NUM 1 - struct _GstVaapiEncoderH264 { - GstVaapiEncoder parent; + GstVaapiEncoder parent_instance; - /* public */ - guint32 profile; - guint32 level; + GstVaapiProfile profile; + guint32 level_idc; guint32 idr_period; - guint32 init_qp; /*default 24 */ - guint32 min_qp; /*default 1 */ - guint32 slice_num; - guint32 b_frame_num; + guint32 init_qp; + guint32 min_qp; + guint32 num_slices; + guint32 num_bframes; + guint32 mb_width; + guint32 mb_height; - /* private */ gboolean is_avc; /* avc or bytestream */ /* re-ordering */ GQueue reorder_frame_list; @@ -86,7 +77,7 @@ struct _GstVaapiEncoderH264 /* reference list */ GQueue ref_list; - guint max_ref_num; + guint max_ref_frames; /* max reflist count */ guint max_reflist0_count; guint max_reflist1_count; @@ -104,4 +95,4 @@ struct _GstVaapiEncoderH264 G_END_DECLS -#endif /*GST_VAAPI_ENCODER_H264_PRIV_H */ +#endif /* GST_VAAPI_ENCODER_H264_PRIV_H */ diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 3e525d30e9..f16620b6d9 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -261,8 +261,8 @@ gst_vaapiencode_h264_alloc_buffer (GstVaapiEncode * base_encode, GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buffer_ptr) { GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base_encode); - GstVaapiEncoderH264 *const encoder = (GstVaapiEncoderH264 *) - base_encode->encoder; + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264 (base_encode->encoder); GstFlowReturn ret; g_return_val_if_fail (encoder != NULL, GST_FLOW_ERROR); From e2f8c059a55331cab1c667d8b6a2acf01d4cf5f7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 10 Jan 2014 14:46:15 +0100 Subject: [PATCH 1516/3781] encoder: h264: support only the byte-stream format. The libgstvaapi core encoders are meant to support raw bitstreams only. Henceforth, we are always producing a stream in "byte-stream" format. However, the "codec-data" buffer which holds SPS and PPS headers is always available. The "lengthSizeMinusOne" field is always set to 3 so that in-place "byte-stream" format to "avc" format conversion could be performed. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 137 +++++++----------- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 6 - .../gst/vaapi/gstvaapiencoder_h264_priv.h | 1 - 3 files changed, 51 insertions(+), 93 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 7e4b6fd8f3..5d180799af 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -112,23 +112,6 @@ h264_get_slice_type (GstVaapiPictureType type) return -1; } -static inline gboolean -_read_sps_attributes (const guint8 * sps_data, - guint32 sps_size, - guint32 * profile_idc, guint32 * profile_comp, guint32 * level_idc) -{ - g_assert (profile_idc && profile_comp && level_idc); - g_assert (sps_size >= 4); - if (sps_size < 4) { - return FALSE; - } - /* skip sps_data[0], nal_type */ - *profile_idc = sps_data[1]; - *profile_comp = sps_data[2]; - *level_idc = sps_data[3]; - return TRUE; -} - /* Get log2_max_frame_num value for H.264 specification */ static guint h264_get_log2_max_frame_num (guint num) @@ -1384,93 +1367,87 @@ gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder) return GST_VAAPI_ENCODER_STATUS_SUCCESS; } +/* Generate "codec-data" buffer */ static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_get_avcC_codec_data (GstVaapiEncoderH264 * encoder, - GstBuffer ** buffer) +gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder, + GstBuffer ** out_buffer_ptr) { - GstBuffer *avc_codec; + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264_CAST (base_encoder); const guint32 configuration_version = 0x01; - const guint32 length_size_minus_one = 0x03; - guint32 profile, profile_comp, level_idc; + const guint32 nal_length_size = 4; + guint8 profile_idc, profile_comp, level_idc; GstMapInfo sps_info, pps_info; - GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; GstBitWriter writer; + GstBuffer *buffer; - g_assert (buffer); if (!encoder->sps_data || !encoder->pps_data) return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER; + if (gst_buffer_get_size (encoder->sps_data) < 4) + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER; if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ)) - return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + goto error_map_sps_buffer; - if (FALSE == _read_sps_attributes (sps_info.data, sps_info.size, - &profile, &profile_comp, &level_idc)) { - ret = GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER; - goto end; - } + if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ)) + goto error_map_pps_buffer; - if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ)) { - ret = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - goto end; - } + /* skip sps_data[0], which is the nal_unit_type */ + profile_idc = sps_info.data[1]; + profile_comp = sps_info.data[2]; + level_idc = sps_info.data[3]; + /* Header */ gst_bit_writer_init (&writer, (sps_info.size + pps_info.size + 64) * 8); - /* codec_data */ gst_bit_writer_put_bits_uint32 (&writer, configuration_version, 8); - gst_bit_writer_put_bits_uint32 (&writer, profile, 8); + gst_bit_writer_put_bits_uint32 (&writer, profile_idc, 8); gst_bit_writer_put_bits_uint32 (&writer, profile_comp, 8); gst_bit_writer_put_bits_uint32 (&writer, level_idc, 8); - gst_bit_writer_put_bits_uint32 (&writer, 0x3F, 6); /*111111 */ - gst_bit_writer_put_bits_uint32 (&writer, length_size_minus_one, 2); - gst_bit_writer_put_bits_uint32 (&writer, 0x07, 3); /*111 */ + gst_bit_writer_put_bits_uint32 (&writer, 0x3f, 6); /* 111111 */ + gst_bit_writer_put_bits_uint32 (&writer, nal_length_size - 1, 2); + gst_bit_writer_put_bits_uint32 (&writer, 0x07, 3); /* 111 */ - /* write sps */ - gst_bit_writer_put_bits_uint32 (&writer, 1, 5); /* sps count = 1 */ + /* Write SPS */ + gst_bit_writer_put_bits_uint32 (&writer, 1, 5); /* SPS count = 1 */ g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); gst_bit_writer_put_bits_uint32 (&writer, sps_info.size, 16); gst_bit_writer_put_bytes (&writer, sps_info.data, sps_info.size); - /* write pps */ - gst_bit_writer_put_bits_uint32 (&writer, 1, 8); /*pps count = 1 */ + /* Write PPS */ + gst_bit_writer_put_bits_uint32 (&writer, 1, 8); /* PPS count = 1 */ gst_bit_writer_put_bits_uint32 (&writer, pps_info.size, 16); gst_bit_writer_put_bytes (&writer, pps_info.data, pps_info.size); - avc_codec = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&writer), - GST_BIT_WRITER_BIT_SIZE (&writer) / 8); - g_assert (avc_codec); - if (!avc_codec) { - ret = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - goto clear_writer; - } - *buffer = avc_codec; - gst_buffer_unmap (encoder->pps_data, &pps_info); - gst_bit_writer_clear (&writer, FALSE); - ret = GST_VAAPI_ENCODER_STATUS_SUCCESS; - goto end; - -clear_writer: - gst_bit_writer_clear (&writer, TRUE); - -end: gst_buffer_unmap (encoder->sps_data, &sps_info); - return ret; -} + buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&writer), + GST_BIT_WRITER_BIT_SIZE (&writer) / 8); + if (!buffer) + goto error_alloc_buffer; + *out_buffer_ptr = buffer; -static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder, - GstBuffer ** buffer) -{ - GstVaapiEncoderH264 *const encoder = - GST_VAAPI_ENCODER_H264_CAST (base_encoder); + gst_bit_writer_clear (&writer, FALSE); + return GST_VAAPI_ENCODER_STATUS_SUCCESS; - *buffer = NULL; - - if (!encoder->is_avc) - return GST_VAAPI_ENCODER_STATUS_SUCCESS; - - return gst_vaapi_encoder_h264_get_avcC_codec_data (encoder, buffer); + /* ERRORS */ +error_map_sps_buffer: + { + GST_ERROR ("failed to map SPS packed header"); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_map_pps_buffer: + { + GST_ERROR ("failed to map PPS packed header"); + gst_buffer_unmap (encoder->sps_data, &sps_info); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_alloc_buffer: + { + GST_ERROR ("failed to allocate codec-data buffer"); + gst_bit_writer_clear (&writer, TRUE); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } } static GstVaapiEncoderStatus @@ -1805,15 +1782,3 @@ gst_vaapi_encoder_h264_get_default_properties (void) return props; } - -void -gst_vaapi_encoder_h264_set_avc (GstVaapiEncoderH264 * encoder, gboolean is_avc) -{ - encoder->is_avc = is_avc; -} - -gboolean -gst_vaapi_encoder_h264_is_avc (GstVaapiEncoderH264 * encoder) -{ - return encoder->is_avc; -} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 0c64e0f341..f02e40e7c6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -54,12 +54,6 @@ gst_vaapi_encoder_h264_new (GstVaapiDisplay * display); GPtrArray * gst_vaapi_encoder_h264_get_default_properties (void); -void -gst_vaapi_encoder_h264_set_avc (GstVaapiEncoderH264 * encoder, gboolean is_avc); - -gboolean -gst_vaapi_encoder_h264_is_avc (GstVaapiEncoderH264 * encoder); - G_END_DECLS #endif /*GST_VAAPI_ENCODER_H264_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h index 6d8ef763d4..3951916b96 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h @@ -66,7 +66,6 @@ struct _GstVaapiEncoderH264 guint32 mb_width; guint32 mb_height; - gboolean is_avc; /* avc or bytestream */ /* re-ordering */ GQueue reorder_frame_list; guint reorder_state; From 2b482e8e4bcae0807e672acb9c309a0e9037773c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 10 Jan 2014 17:02:44 +0100 Subject: [PATCH 1517/3781] encoder: h264: fix hardware profile lookup. Fix lookup for a suitable HW profile, as to be used by the underlying hardware, based on heuristics that lead to characterize the SW profile, i.e. the one used by the SW level encoding logic. Also fix constraint_set0_flag (A.2.1) and constraint_set1_flag (A.2.2) as they should respectively match the baseline and main profile. https://bugzilla.gnome.org/show_bug.cgi?id=719827 --- gst-libs/gst/vaapi/gstvaapiencoder.h | 2 + gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 99 ++++++++++++++----- .../gst/vaapi/gstvaapiencoder_h264_priv.h | 1 - 3 files changed, 76 insertions(+), 26 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 4b07700ef7..e68925f7dd 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -45,6 +45,7 @@ typedef struct _GstVaapiEncoder GstVaapiEncoder; * 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. @@ -62,6 +63,7 @@ typedef enum 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, diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 5d180799af..16dcb640b9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -26,6 +26,7 @@ #include "gstvaapicompat.h" #include "gstvaapiencoder_h264.h" #include "gstvaapiencoder_h264_priv.h" +#include "gstvaapiutils_h264_priv.h" #include "gstvaapicodedbufferproxy_priv.h" #include "gstvaapisurface.h" @@ -130,22 +131,6 @@ h264_get_log2_max_frame_num (guint num) return ret; } -static inline guint -_profile_to_value (GstVaapiProfile profile) -{ - switch (profile) { - case GST_VAAPI_PROFILE_H264_BASELINE: - return 66; - case GST_VAAPI_PROFILE_H264_MAIN: - return 77; - case GST_VAAPI_PROFILE_H264_HIGH: - return 100; - default: - break; - } - return 0; -} - static inline void _check_sps_pps_status (GstVaapiEncoderH264 * encoder, const guint8 * nal, guint32 size) @@ -175,6 +160,61 @@ _check_sps_pps_status (GstVaapiEncoderH264 * encoder, } } +/* Derives the profile supported by the underlying hardware */ +static gboolean +ensure_hw_profile (GstVaapiEncoderH264 * encoder) +{ + GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); + GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + GstVaapiProfile profile, profiles[4]; + guint i, num_profiles = 0; + + profiles[num_profiles++] = encoder->profile; + switch (encoder->profile) { + case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE: + profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE; + profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN; + // fall-through + case GST_VAAPI_PROFILE_H264_MAIN: + profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; + break; + default: + break; + } + + 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 (0x%08x)", encoder->profile); + return FALSE; + } +} + +/* Derives the minimum profile from the active coding tools */ +static gboolean +ensure_profile (GstVaapiEncoderH264 * encoder) +{ + GstVaapiProfile profile; + + profile = GST_VAAPI_PROFILE_H264_BASELINE; + + encoder->profile = profile; + return TRUE; +} + static void _set_level (GstVaapiEncoderH264 * encoder) { @@ -377,6 +417,7 @@ static gboolean gst_bit_writer_write_sps (GstBitWriter * bitwriter, const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile) { + guint8 profile_idc; guint32 constraint_set0_flag, constraint_set1_flag; guint32 constraint_set2_flag, constraint_set3_flag; guint32 gaps_in_frame_num_value_allowed_flag = 0; // ?? @@ -391,13 +432,18 @@ gst_bit_writer_write_sps (GstBitWriter * bitwriter, !seq_param->seq_fields.bits.frame_mbs_only_flag; guint32 i = 0; - constraint_set0_flag = profile == GST_VAAPI_PROFILE_H264_BASELINE; - constraint_set1_flag = profile <= GST_VAAPI_PROFILE_H264_MAIN; + profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + constraint_set0_flag = /* A.2.1 (baseline profile constraints) */ + profile == GST_VAAPI_PROFILE_H264_BASELINE || + profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + constraint_set1_flag = /* A.2.2 (main profile constraints) */ + profile == GST_VAAPI_PROFILE_H264_MAIN || + profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; constraint_set2_flag = 0; constraint_set3_flag = 0; /* profile_idc */ - gst_bit_writer_put_bits_uint32 (bitwriter, _profile_to_value (profile), 8); + gst_bit_writer_put_bits_uint32 (bitwriter, profile_idc, 8); /* constraint_set0_flag */ gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set0_flag, 1); /* constraint_set1_flag */ @@ -1234,8 +1280,8 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) static gboolean ensure_profile_and_level (GstVaapiEncoderH264 * encoder) { - if (!encoder->profile) - encoder->profile = GST_VAAPI_ENCODER_H264_DEFAULT_PROFILE; + if (!ensure_profile (encoder)) + return FALSE; _set_level (encoder); return TRUE; @@ -1551,7 +1597,7 @@ end: return GST_VAAPI_ENCODER_STATUS_SUCCESS; } -static void +static GstVaapiEncoderStatus set_context_info (GstVaapiEncoder * base_encoder) { GstVaapiEncoderH264 *const encoder = @@ -1569,7 +1615,9 @@ set_context_info (GstVaapiEncoder * base_encoder) MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402, }; - base_encoder->profile = encoder->profile; + if (!ensure_hw_profile (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + base_encoder->num_ref_frames = (encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT; @@ -1591,6 +1639,8 @@ set_context_info (GstVaapiEncoder * base_encoder) /* Account for slice header. At most 200 slices are supported */ base_encoder->codedbuf_size += 200 * (4 + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } static GstVaapiEncoderStatus @@ -1608,8 +1658,7 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) goto error; reset_properties (encoder); - set_context_info (base_encoder); - return GST_VAAPI_ENCODER_STATUS_SUCCESS; + return set_context_info (base_encoder); error: return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h index 3951916b96..a2eb65bbe8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h @@ -48,7 +48,6 @@ typedef enum GST_VAAPI_ENCODER_H264_LEVEL_51 = 51, /* 4096x2304 format, < 251658240 samples/sec */ } GstVaapiEncoderH264Level; -#define GST_VAAPI_ENCODER_H264_DEFAULT_PROFILE GST_VAAPI_PROFILE_H264_BASELINE #define GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL GST_VAAPI_ENCODER_H264_LEVEL_31 #define GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD 512 From b59a5572af08c1ce504232d3a9eed0cbf0cecec5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 10 Jan 2014 18:18:25 +0100 Subject: [PATCH 1518/3781] encoder: h264: derive profile and level from active coding tools. Automatically derive the minimum profile and level to be used for encoding, based on the activated coding tools. The encoder will be trying to generate a bitstream that has the best chances to be decoded on most platforms by default. Also change the default profile to "constrained-baseline" so that to ensure maximum compatibility when the stream is decoded. https://bugzilla.gnome.org/show_bug.cgi?id=719691 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 151 ++++++++---------- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 5 + .../gst/vaapi/gstvaapiencoder_h264_priv.h | 25 +-- 3 files changed, 77 insertions(+), 104 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 16dcb640b9..2f4ed921cf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -209,96 +209,52 @@ ensure_profile (GstVaapiEncoderH264 * encoder) { GstVaapiProfile profile; - profile = GST_VAAPI_PROFILE_H264_BASELINE; + /* Always start from "constrained-baseline" profile for maximum + compatibility */ + profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + + /* Main profile coding tools */ + if (encoder->num_bframes > 0) + profile = GST_VAAPI_PROFILE_H264_MAIN; encoder->profile = profile; + encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); return TRUE; } -static void -_set_level (GstVaapiEncoderH264 * encoder) +static gboolean +ensure_level (GstVaapiEncoderH264 * encoder) { - guint pic_mb_size; - guint MaxDpbMbs, MaxMBPS; - guint dbp_level, mbps_level, profile_level; + const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate; + const GstVaapiH264LevelLimits *limits_table; + guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS; - if (encoder->level_idc) { - if (encoder->level_idc < GST_VAAPI_ENCODER_H264_LEVEL_10) - encoder->level_idc = GST_VAAPI_ENCODER_H264_LEVEL_10; - else if (encoder->level_idc > GST_VAAPI_ENCODER_H264_LEVEL_51) - encoder->level_idc = GST_VAAPI_ENCODER_H264_LEVEL_51; - return; + PicSizeMbs = encoder->mb_width * encoder->mb_height; + MaxDpbMbs = PicSizeMbs * ((encoder->num_bframes) ? 2 : 1); + MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs, + GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder)); + + limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits); + for (i = 0; i < num_limits; i++) { + const GstVaapiH264LevelLimits *const limits = &limits_table[i]; + if (PicSizeMbs <= limits->MaxFS && + MaxDpbMbs <= limits->MaxDpbMbs && + MaxMBPS <= limits->MaxMBPS && (!bitrate || bitrate <= limits->MaxBR)) + break; } + if (i == num_limits) + goto error_unsupported_level; - /* calculate level */ - pic_mb_size = ((GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16) * - ((GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16); - MaxDpbMbs = pic_mb_size * ((encoder->num_bframes) ? 2 : 1); - MaxMBPS = pic_mb_size * GST_VAAPI_ENCODER_FPS_N (encoder) / - GST_VAAPI_ENCODER_FPS_D (encoder); + encoder->level = limits_table[i].level; + encoder->level_idc = limits_table[i].level_idc; + return TRUE; - /* calculate from MaxDbpMbs */ - if (MaxDpbMbs > 110400) - dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_51; - else if (MaxDpbMbs > 34816) - dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_50; - else if (MaxDpbMbs > 32768) - dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_42; - else if (MaxDpbMbs > 20480) /* 41 or 40 */ - dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_41; - else if (MaxDpbMbs > 18000) - dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_32; - else if (MaxDpbMbs > 8100) - dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_31; - else if (MaxDpbMbs > 4752) /* 30 or 22 */ - dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_30; - else if (MaxDpbMbs > 2376) - dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_21; - else if (MaxDpbMbs > 900) /* 20, 13, 12 */ - dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_20; - else if (MaxDpbMbs > 396) - dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_11; - else - dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_10; - - /* calculate from Max Mb processing rate */ - if (MaxMBPS > 589824) - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_51; - else if (MaxMBPS > 522240) - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_50; - else if (MaxMBPS > 245760) - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_42; - else if (MaxMBPS > 216000) /* 40 or 41 */ - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_41; - else if (MaxMBPS > 108000) - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_32; - else if (MaxMBPS > 40500) - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_31; - else if (MaxMBPS > 20250) - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_30; - else if (MaxMBPS > 19800) - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_22; - else if (MaxMBPS > 11800) - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_21; - else if (MaxMBPS > 6000) /*13 or 20 */ - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_20; - else if (MaxMBPS > 3000) - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_12; - else if (MaxMBPS > 1485) - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_11; - else - mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_10; - - if (encoder->profile == GST_VAAPI_PROFILE_H264_HIGH) - profile_level = GST_VAAPI_ENCODER_H264_LEVEL_41; - else if (encoder->profile == GST_VAAPI_PROFILE_H264_MAIN) - profile_level = GST_VAAPI_ENCODER_H264_LEVEL_30; - else - profile_level = GST_VAAPI_ENCODER_H264_LEVEL_20; - - encoder->level_idc = (dbp_level > mbps_level ? dbp_level : mbps_level); - if (encoder->level_idc < profile_level) - encoder->level_idc = profile_level; + /* ERRORS */ +error_unsupported_level: + { + GST_ERROR ("failed to find a suitable level matching codec config"); + return FALSE; + } } static inline void @@ -1015,7 +971,7 @@ fill_va_picture_param (GstVaapiEncoderH264 * encoder, pic_param->pic_fields.bits.weighted_pred_flag = FALSE; pic_param->pic_fields.bits.weighted_bipred_idc = 0; pic_param->pic_fields.bits.constrained_intra_pred_flag = 0; - pic_param->pic_fields.bits.transform_8x8_mode_flag = (encoder->profile >= GST_VAAPI_PROFILE_H264_HIGH); /* enable 8x8 */ + pic_param->pic_fields.bits.transform_8x8_mode_flag = (encoder->profile_idc >= 100); /* enable 8x8 */ /* enable debloking */ pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE; @@ -1282,8 +1238,8 @@ ensure_profile_and_level (GstVaapiEncoderH264 * encoder) { if (!ensure_profile (encoder)) return FALSE; - - _set_level (encoder); + if (!ensure_level (encoder)) + return FALSE; return TRUE; } @@ -1831,3 +1787,32 @@ gst_vaapi_encoder_h264_get_default_properties (void) return props; } + +/** + * gst_vaapi_encoder_h264_get_profile_and_level: + * @encoder: a #GstVaapiEncoderH264 + * @out_profile_ptr: return location for the #GstVaapiProfile + * @out_level_ptr: return location for the #GstVaapiLevelH264 + * + * Queries the H.264 @encoder for the active profile and level. That + * information is only constructed and valid after the encoder is + * configured, i.e. after the gst_vaapi_encoder_set_codec_state() + * function is called. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder, + GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr) +{ + g_return_val_if_fail (encoder != NULL, FALSE); + + if (!encoder->profile || !encoder->level) + return FALSE; + + if (out_profile_ptr) + *out_profile_ptr = encoder->profile; + if (out_level_ptr) + *out_level_ptr = encoder->level; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index f02e40e7c6..7d5f053c79 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -23,6 +23,7 @@ #define GST_VAAPI_ENCODER_H264_H #include +#include G_BEGIN_DECLS @@ -54,6 +55,10 @@ gst_vaapi_encoder_h264_new (GstVaapiDisplay * display); GPtrArray * gst_vaapi_encoder_h264_get_default_properties (void); +gboolean +gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder, + GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr); + G_END_DECLS #endif /*GST_VAAPI_ENCODER_H264_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h index a2eb65bbe8..bf9958a425 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h @@ -23,32 +23,13 @@ #define GST_VAAPI_ENCODER_H264_PRIV_H #include "gstvaapiencoder_priv.h" +#include "gstvaapiutils_h264.h" G_BEGIN_DECLS #define GST_VAAPI_ENCODER_H264_CAST(encoder) \ ((GstVaapiEncoderH264 *)(encoder)) -typedef enum -{ - GST_VAAPI_ENCODER_H264_LEVEL_10 = 10, /* QCIF format, < 380160 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_11 = 11, /* CIF format, < 768000 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_12 = 12, /* CIF format, < 1536000 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_13 = 13, /* CIF format, < 3041280 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_20 = 20, /* CIF format, < 3041280 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_21 = 21, /* HHR format, < 5068800 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_22 = 22, /* SD/4CIF format, < 5184000 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_30 = 30, /* SD/4CIF format, < 10368000 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_31 = 31, /* 720pHD format, < 27648000 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_32 = 32, /* SXGA format, < 55296000 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_40 = 40, /* 2Kx1K format, < 62914560 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_41 = 41, /* 2Kx1K format, < 62914560 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_42 = 42, /* 2Kx1K format, < 125829120 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_50 = 50, /* 3672x1536 format, < 150994944 samples/sec */ - GST_VAAPI_ENCODER_H264_LEVEL_51 = 51, /* 4096x2304 format, < 251658240 samples/sec */ -} GstVaapiEncoderH264Level; - -#define GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL GST_VAAPI_ENCODER_H264_LEVEL_31 #define GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD 512 struct _GstVaapiEncoderH264 @@ -56,7 +37,9 @@ struct _GstVaapiEncoderH264 GstVaapiEncoder parent_instance; GstVaapiProfile profile; - guint32 level_idc; + GstVaapiLevelH264 level; + guint8 profile_idc; + guint8 level_idc; guint32 idr_period; guint32 init_qp; guint32 min_qp; From 8df97cf9ec600d8920de43dbaa75be940c669f05 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 13 Dec 2013 17:36:08 +0800 Subject: [PATCH 1519/3781] encoder: h264: expose more coding tools. Add new H.264 coding tools to improve compression: - "cabac": enable CABAC entropy coding (default: FALSE); - "dct8x8": enable spatial transform 8x8 (default: FALSE). https://bugzilla.gnome.org/show_bug.cgi?id=719693 Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 51 +++++++++++++++---- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 5 ++ .../gst/vaapi/gstvaapiencoder_h264_priv.h | 2 + 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 2f4ed921cf..af548d6da3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -53,12 +53,6 @@ #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM 2 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH 3 -typedef enum -{ - GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CAVLC = 0, - GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CABAC = 1 -} GstVaapiEncoderH264EntropyMode; - typedef enum { GST_VAAPI_ENCODER_H264_NAL_UNKNOWN = 0, @@ -214,9 +208,13 @@ ensure_profile (GstVaapiEncoderH264 * encoder) profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; /* Main profile coding tools */ - if (encoder->num_bframes > 0) + if (encoder->num_bframes > 0 || encoder->use_cabac) profile = GST_VAAPI_PROFILE_H264_MAIN; + /* High profile coding tools */ + if (encoder->use_dct8x8) + profile = GST_VAAPI_PROFILE_H264_HIGH; + encoder->profile = profile; encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); return TRUE; @@ -966,12 +964,11 @@ fill_va_picture_param (GstVaapiEncoderH264 * encoder, GST_VAAPI_ENC_PICTURE_IS_IDR (picture); pic_param->pic_fields.bits.reference_pic_flag = (picture->type != GST_VAAPI_PICTURE_TYPE_B); - pic_param->pic_fields.bits.entropy_coding_mode_flag = - GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CABAC; + pic_param->pic_fields.bits.entropy_coding_mode_flag = encoder->use_cabac; pic_param->pic_fields.bits.weighted_pred_flag = FALSE; pic_param->pic_fields.bits.weighted_bipred_idc = 0; pic_param->pic_fields.bits.constrained_intra_pred_flag = 0; - pic_param->pic_fields.bits.transform_8x8_mode_flag = (encoder->profile_idc >= 100); /* enable 8x8 */ + pic_param->pic_fields.bits.transform_8x8_mode_flag = encoder->use_dct8x8; /* enable debloking */ pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE; @@ -1685,6 +1682,12 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES: encoder->num_slices = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_H264_PROP_CABAC: + encoder->use_cabac = g_value_get_boolean (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_DCT8X8: + encoder->use_dct8x8 = g_value_get_boolean (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -1785,6 +1788,34 @@ gst_vaapi_encoder_h264_get_default_properties (void) "Number of slices per frame", 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:cabac: + * + * Enable CABAC entropy coding mode for improved compression ratio, + * at the expense that the minimum target profile is Main. Default + * is CAVLC entropy coding mode. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_CABAC, + g_param_spec_boolean ("cabac", + "Enable CABAC", + "Enable CABAC entropy coding mode", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:dct8x8: + * + * Enable adaptive use of 8x8 transforms in I-frames. This improves + * the compression ratio by the minimum target profile is High. + * Default is to use 4x4 DCT only. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_DCT8X8, + g_param_spec_boolean ("dct8x8", + "Enable 8x8 DCT", + "Enable adaptive use of 8x8 transforms in I-frames", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 7d5f053c79..951beadc83 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -39,6 +39,9 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * @GST_VAAPI_ENCODER_H264_PROP_INIT_QP: Initial quantizer value (uint). * @GST_VAAPI_ENCODER_H264_PROP_MIN_QP: Minimal quantizer value (uint). * @GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES: Number of slices per frame (uint). + * @GST_VAAPI_ENCODER_H264_PROP_CABAC: Enable CABAC entropy coding mode (bool). + * @GST_VAAPI_ENCODER_H264_PROP_DCT8X8: Enable adaptive use of 8x8 + * transforms in I-frames (bool). * * The set of H.264 encoder specific configurable properties. */ @@ -47,6 +50,8 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_INIT_QP = -2, GST_VAAPI_ENCODER_H264_PROP_MIN_QP = -3, GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES = -4, + GST_VAAPI_ENCODER_H264_PROP_CABAC = -5, + GST_VAAPI_ENCODER_H264_PROP_DCT8X8 = -6, } GstVaapiEncoderH264Prop; GstVaapiEncoder * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h index bf9958a425..2deafe797d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h @@ -47,6 +47,8 @@ struct _GstVaapiEncoderH264 guint32 num_bframes; guint32 mb_width; guint32 mb_height; + gboolean use_cabac; + gboolean use_dct8x8; /* re-ordering */ GQueue reorder_frame_list; From 00e0af9a7c471fc59c6cb33589b5462c98cd79f8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sun, 12 Jan 2014 22:14:11 +0100 Subject: [PATCH 1520/3781] encoder: h264: refine size of coded buffer. Refine the heuristic to determine the maximum size of a coded buffer to account for the exact number of slices. set_context_info() is the last step during codec reconfiguration, no additional change is done afterwards, so re-using the num_slices field here is fine. https://bugzilla.gnome.org/show_bug.cgi?id=719953 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index af548d6da3..ace259ae23 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1589,8 +1589,8 @@ set_context_info (GstVaapiEncoder * base_encoder) /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */ base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8; - /* Account for slice header. At most 200 slices are supported */ - base_encoder->codedbuf_size += 200 * (4 + + /* Account for slice header */ + base_encoder->codedbuf_size += encoder->num_slices * (4 + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); return GST_VAAPI_ENCODER_STATUS_SUCCESS; From bdf91aa765a781dba35606b63aff8264edd203ad Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sun, 12 Jan 2014 22:24:04 +0100 Subject: [PATCH 1521/3781] encoder: h264: allow target decoder constraints. Allow user to precise the largest profile to use for encoding due to target decoder constraints. For instance, if CABAC entropy coding mode is requested by "constrained-baseline" profile only is desired, then an error is returned during codec configuration. Also make sure that the suitable profile we derived actually matches what the HW can cope with. https://bugzilla.gnome.org/show_bug.cgi?id=719694 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 119 ++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 4 + .../gst/vaapi/gstvaapiencoder_h264_priv.h | 2 + gst-libs/gst/vaapi/gstvaapiutils_h264.c | 10 ++ gst-libs/gst/vaapi/gstvaapiutils_h264.h | 4 + gst/vaapi/gstvaapiencode_h264.c | 86 ++++++++++++- 6 files changed, 217 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index ace259ae23..7f0362fe6a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -154,6 +154,37 @@ _check_sps_pps_status (GstVaapiEncoderH264 * encoder, } } +/* Determines the largest supported profile by the underlying hardware */ +static gboolean +ensure_hw_profile_limits (GstVaapiEncoderH264 * encoder) +{ + GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); + GArray *profiles; + guint i, profile_idc, max_profile_idc; + + if (encoder->hw_max_profile_idc) + return TRUE; + + profiles = gst_vaapi_display_get_encode_profiles (display); + if (!profiles) + return FALSE; + + max_profile_idc = 0; + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index (profiles, GstVaapiProfile, i); + profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + if (!profile_idc) + continue; + if (max_profile_idc < profile_idc) + max_profile_idc = profile_idc; + } + g_array_unref (profiles); + + encoder->hw_max_profile_idc = max_profile_idc; + return TRUE; +} + /* Derives the profile supported by the underlying hardware */ static gboolean ensure_hw_profile (GstVaapiEncoderH264 * encoder) @@ -197,6 +228,36 @@ error_unsupported_profile: } } +/* Check target decoder constraints */ +static gboolean +ensure_profile_limits (GstVaapiEncoderH264 * encoder) +{ + GstVaapiProfile profile; + + if (!encoder->max_profile_idc + || encoder->profile_idc <= encoder->max_profile_idc) + return TRUE; + + GST_WARNING ("lowering coding tools to meet target decoder constraints"); + + /* Try Main profile coding tools */ + if (encoder->max_profile_idc < 100) { + encoder->use_dct8x8 = FALSE; + profile = GST_VAAPI_PROFILE_H264_MAIN; + } + + /* Try Constrained Baseline profile coding tools */ + if (encoder->max_profile_idc < 77) { + encoder->num_bframes = 0; + encoder->use_cabac = FALSE; + profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + } + + encoder->profile = profile; + encoder->profile_idc = encoder->max_profile_idc; + return TRUE; +} + /* Derives the minimum profile from the active coding tools */ static gboolean ensure_profile (GstVaapiEncoderH264 * encoder) @@ -1230,14 +1291,21 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) return TRUE; } -static gboolean +static GstVaapiEncoderStatus ensure_profile_and_level (GstVaapiEncoderH264 * encoder) { - if (!ensure_profile (encoder)) - return FALSE; + if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + if (!ensure_level (encoder)) - return FALSE; - return TRUE; + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + + /* Check HW constraints */ + if (!ensure_hw_profile_limits (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + if (encoder->profile_idc > encoder->hw_max_profile_idc) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } static gboolean @@ -1601,12 +1669,15 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) { GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiEncoderStatus status; encoder->mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; encoder->mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; - if (!ensure_profile_and_level (encoder)) - goto error; + status = ensure_profile_and_level (encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + if (!ensure_bitrate (encoder)) goto error; @@ -1819,6 +1890,40 @@ gst_vaapi_encoder_h264_get_default_properties (void) return props; } +/** + * gst_vaapi_encoder_h264_set_max_profile: + * @encoder: a #GstVaapiEncoderH264 + * @profile: an H.264 #GstVaapiProfile + * + * Notifies the @encoder to use coding tools from the supplied + * @profile at most. + * + * This means that if the minimal profile derived to + * support the specified coding tools is greater than this @profile, + * then an error is returned when the @encoder is configured. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_encoder_h264_set_max_profile (GstVaapiEncoderH264 * encoder, + GstVaapiProfile profile) +{ + guint8 profile_idc; + + g_return_val_if_fail (encoder != NULL, FALSE); + g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE); + + if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264) + return FALSE; + + profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + if (!profile_idc) + return FALSE; + + encoder->max_profile_idc = profile_idc; + return TRUE; +} + /** * gst_vaapi_encoder_h264_get_profile_and_level: * @encoder: a #GstVaapiEncoderH264 diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 951beadc83..95a0a9a026 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -60,6 +60,10 @@ gst_vaapi_encoder_h264_new (GstVaapiDisplay * display); GPtrArray * gst_vaapi_encoder_h264_get_default_properties (void); +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); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h index 2deafe797d..ea65456e59 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h @@ -39,6 +39,8 @@ struct _GstVaapiEncoderH264 GstVaapiProfile profile; GstVaapiLevelH264 level; guint8 profile_idc; + guint8 max_profile_idc; + guint8 hw_max_profile_idc; guint8 level_idc; guint32 idr_period; guint32 init_qp; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index 8c39437478..c72e017eb1 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -127,6 +127,16 @@ map_lookup_name (const struct map *m, const gchar * name) return NULL; } +/** Returns a relative score for the supplied GstVaapiProfile */ +guint +gst_vaapi_utils_h264_get_profile_score (GstVaapiProfile profile) +{ + const struct map *const m = + map_lookup_value (gst_vaapi_h264_profile_map, profile); + + return m ? 1 + (m - gst_vaapi_h264_profile_map) : 0; +} + /** Returns GstVaapiProfile from H.264 profile_idc value */ GstVaapiProfile gst_vaapi_utils_h264_get_profile (guint8 profile_idc) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.h b/gst-libs/gst/vaapi/gstvaapiutils_h264.h index 400fc5c38b..3f2867d01e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.h @@ -71,6 +71,10 @@ typedef enum GST_VAAPI_LEVEL_H264_L5_2, } GstVaapiLevelH264; +/* Returns a relative score for the supplied GstVaapiProfile */ +guint +gst_vaapi_utils_h264_get_profile_score (GstVaapiProfile profile); + /* Returns GstVaapiProfile from a string representation */ GstVaapiProfile gst_vaapi_utils_h264_get_profile_from_string (const gchar * str); diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index f16620b6d9..05edb447e6 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -22,6 +22,7 @@ #include "gst/vaapi/sysdeps.h" #include #include +#include #include "gstvaapiencode_h264.h" #include "gstvaapipluginutil.h" #if GST_CHECK_VERSION(1,0,0) @@ -59,7 +60,8 @@ static const char gst_vaapiencode_h264_sink_caps_str[] = /* *INDENT-OFF* */ static const char gst_vaapiencode_h264_src_caps_str[] = - GST_CODEC_CAPS; + GST_CODEC_CAPS ", " + "profile = (string) { constrained-baseline, baseline, main, high }"; /* *INDENT-ON* */ /* *INDENT-OFF* */ @@ -123,6 +125,87 @@ gst_vaapiencode_h264_get_property (GObject * object, } } +typedef struct +{ + GstVaapiProfile best_profile; + guint best_score; +} FindBestProfileData; + +static void +find_best_profile_value (FindBestProfileData * data, const GValue * value) +{ + const gchar *str; + GstVaapiProfile profile; + guint score; + + if (!value || !G_VALUE_HOLDS_STRING (value)) + return; + + str = g_value_get_string (value); + if (!str) + return; + profile = gst_vaapi_utils_h264_get_profile_from_string (str); + if (!profile) + return; + score = gst_vaapi_utils_h264_get_profile_score (profile); + if (score < data->best_score) + return; + data->best_profile = profile; + data->best_score = score; +} + +static GstVaapiProfile +find_best_profile (GstCaps * caps) +{ + FindBestProfileData data; + guint i, j, num_structures, num_values; + + data.best_profile = GST_VAAPI_PROFILE_UNKNOWN; + data.best_score = 0; + + num_structures = gst_caps_get_size (caps); + for (i = 0; i < num_structures; i++) { + GstStructure *const structure = gst_caps_get_structure (caps, i); + const GValue *const value = gst_structure_get_value (structure, "profile"); + + if (!value) + continue; + if (G_VALUE_HOLDS_STRING (value)) + find_best_profile_value (&data, value); + else if (GST_VALUE_HOLDS_LIST (value)) { + num_values = gst_value_list_get_size (value); + for (j = 0; j < num_values; j++) + find_best_profile_value (&data, gst_value_list_get_value (value, j)); + } + } + return data.best_profile; +} + +static gboolean +gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) +{ + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264 (base_encode->encoder); + GstCaps *allowed_caps; + GstVaapiProfile profile; + + /* Check for the largest profile that is supported */ + allowed_caps = + gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (base_encode)); + if (!allowed_caps) + return TRUE; + + profile = find_best_profile (allowed_caps); + gst_caps_unref (allowed_caps); + if (profile) { + GST_INFO ("using %s profile as target decoder constraints", + gst_vaapi_utils_h264_get_profile_string (profile)); + if (!gst_vaapi_encoder_h264_set_max_profile (encoder, profile)) + return FALSE; + } + return TRUE; +} + static GstCaps * gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) { @@ -305,6 +388,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) object_class->get_property = gst_vaapiencode_h264_get_property; encode_class->get_properties = gst_vaapi_encoder_h264_get_default_properties; + encode_class->set_config = gst_vaapiencode_h264_set_config; encode_class->get_caps = gst_vaapiencode_h264_get_caps; encode_class->alloc_encoder = gst_vaapiencode_h264_alloc_encoder; encode_class->alloc_buffer = gst_vaapiencode_h264_alloc_buffer; From 7b1233faa8bb12b4ecb2e9e6dcdee72f94b468f4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 13 Jan 2014 11:11:25 +0100 Subject: [PATCH 1522/3781] encoder: h264: support "high-compression" tuning option. Add support for "high-compression" tuning option. First, determine the largest supported profile by the hardware. Next, check any target limit set by the user. Then, enable each individual coding tool based on the resulting profile_idc value to use. https://bugzilla.gnome.org/show_bug.cgi?id=719696 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 51 ++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 7f0362fe6a..0362f8493c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -45,8 +45,9 @@ GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) /* Supported set of tuning options, within this implementation */ -#define SUPPORTED_TUNE_OPTIONS \ - (GST_VAAPI_ENCODER_TUNE_MASK (NONE)) +#define SUPPORTED_TUNE_OPTIONS \ + (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \ + GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION)) #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1 @@ -316,6 +317,50 @@ error_unsupported_level: } } +/* Enable "high-compression" tuning options */ +static gboolean +ensure_tuning_high_compression (GstVaapiEncoderH264 * encoder) +{ + guint8 profile_idc; + + if (!ensure_hw_profile_limits (encoder)) + return FALSE; + + profile_idc = encoder->hw_max_profile_idc; + if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc) + profile_idc = encoder->max_profile_idc; + + /* Tuning options to enable Main profile */ + if (profile_idc >= 77) { + encoder->use_cabac = TRUE; + if (!encoder->num_bframes) + encoder->num_bframes = 1; + } + + /* Tuning options to enable High profile */ + if (profile_idc >= 100) { + encoder->use_dct8x8 = TRUE; + } + return TRUE; +} + +/* Ensure tuning options */ +static gboolean +ensure_tuning (GstVaapiEncoderH264 * encoder) +{ + gboolean success; + + switch (GST_VAAPI_ENCODER_TUNE (encoder)) { + case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: + success = ensure_tuning_high_compression (encoder); + break; + default: + success = TRUE; + break; + } + return success; +} + static inline void _reset_gop_start (GstVaapiEncoderH264 * encoder) { @@ -1294,6 +1339,8 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) static GstVaapiEncoderStatus ensure_profile_and_level (GstVaapiEncoderH264 * encoder) { + ensure_tuning (encoder); + if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; From c7a2095b78f9b543b9e97b8556d1d67f2e23487b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 13 Jan 2014 11:49:14 +0100 Subject: [PATCH 1523/3781] encoder: h264: improve automatic bitrate calculation. For non "Constant-QP" modes, we could provide more reasonable heuristics for the target bitrate. In general, 48 bits per macroblock with all the useful coding tools enable looks safe enough. Then, this rate is raised by +10% to +15% for each coding tool that is disabled. https://bugzilla.gnome.org/show_bug.cgi?id=719699 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 0362f8493c..4d98c55833 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1360,16 +1360,28 @@ ensure_bitrate (GstVaapiEncoderH264 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - /* Default compression: 64 bits per macroblock */ + /* Default compression: 48 bits per macroblock in "high-compression" mode */ switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { case GST_VAAPI_RATECONTROL_CBR: case GST_VAAPI_RATECONTROL_VBR: case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: - if (!base_encoder->bitrate) - base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * - GST_VAAPI_ENCODER_HEIGHT (encoder) * + if (!base_encoder->bitrate) { + /* According to the literature and testing, CABAC entropy coding + mode could provide for +10% to +18% improvement in general, + thus estimating +15% here ; and using adaptive 8x8 transforms + in I-frames could bring up to +10% improvement. */ + guint bits_per_mb = 48; + if (!encoder->use_cabac) + bits_per_mb += (bits_per_mb * 15) / 100; + if (!encoder->use_dct8x8) + bits_per_mb += (bits_per_mb * 10) / 100; + + base_encoder->bitrate = + encoder->mb_width * encoder->mb_height * bits_per_mb * GST_VAAPI_ENCODER_FPS_N (encoder) / - GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1000; + GST_VAAPI_ENCODER_FPS_D (encoder) / 1000; + GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate); + } break; default: base_encoder->bitrate = 0; From 78bf2c01ccaf716da2179cb15f3438f1d544f12c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 13 Jan 2014 13:41:35 +0100 Subject: [PATCH 1524/3781] encoder: h264: fix frame cropping rectangle calculation. Fix frame cropping rectangle calculation to handle horizontal resolutions that don't match a multiple of 16 pixels, but also the vertical resolution that was incorrectly computed for progressive sequences too. https://bugzilla.gnome.org/show_bug.cgi?id=722089 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 4d98c55833..ff160981fe 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -991,14 +991,17 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder, sizeof (seq_param->offset_for_ref_frame)); } - if (encoder->mb_height * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) { + /* frame_cropping_flag */ + if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) || + (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) { seq_param->frame_cropping_flag = 1; seq_param->frame_crop_left_offset = 0; - seq_param->frame_crop_right_offset = 0; + seq_param->frame_crop_right_offset = + 16 * encoder->mb_width - GST_VAAPI_ENCODER_WIDTH (encoder); seq_param->frame_crop_top_offset = 0; seq_param->frame_crop_bottom_offset = - ((encoder->mb_height * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) / - (2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1))); + (16 * encoder->mb_height - GST_VAAPI_ENCODER_HEIGHT (encoder)) / + (2 - seq_param->seq_fields.bits.frame_mbs_only_flag); } /* vui not set */ From d45c6a486f7e12235c9d514b7303f5f8257e1bff Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 14 Jan 2014 12:01:11 +0100 Subject: [PATCH 1525/3781] encoder: clean-up objects. Various clean-ups to improve consistency and readability: rename some variables, drop unused macro definitions, drop initialization of vars that are zero-initialized from the base class, drop un-necessary casts, allocate GPtrArrays with a destroy function. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 19 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 8 +- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 211 ++++++++----------- gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 179 ++++++---------- 5 files changed, 162 insertions(+), 257 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 89b77e5d3c..b9767f1543 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -318,7 +318,7 @@ gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, goto error_encode; gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, - picture, (GDestroyNotify) gst_vaapi_enc_picture_unref); + picture, (GDestroyNotify) gst_vaapi_mini_object_unref); g_async_queue_push (encoder->codedbuf_queue, codedbuf_proxy); encoder->num_codedbuf_queued++; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index ff160981fe..63385226ca 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -393,8 +393,9 @@ _set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_I; pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num); - g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic)); - GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic)); + + g_assert (pic->frame); + GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); } static inline void @@ -406,8 +407,8 @@ _set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) pic->poc = 0; GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR); - g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic)); - GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic)); + g_assert (pic->frame); + GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); } static inline void @@ -1303,8 +1304,8 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) g_assert (misc); if (!misc) return FALSE; - gst_vaapi_enc_picture_add_misc_buffer (picture, misc); - hrd = misc->impl; + gst_vaapi_enc_picture_add_misc_param (picture, misc); + hrd = misc->data; if (base_encoder->bitrate > 0) { hrd->initial_buffer_fullness = base_encoder->bitrate * 1000 * 4; hrd->buffer_size = base_encoder->bitrate * 1000 * 8; @@ -1321,8 +1322,8 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) g_assert (misc); if (!misc) return FALSE; - gst_vaapi_enc_picture_add_misc_buffer (picture, misc); - rate_control = misc->impl; + gst_vaapi_enc_picture_add_misc_param (picture, misc); + rate_control = misc->data; memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); if (base_encoder->bitrate) rate_control->bits_per_second = base_encoder->bitrate * 1000; @@ -1672,7 +1673,7 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, end: g_assert (picture); - frame = GST_VAAPI_ENC_PICTURE_GET_FRAME (picture); + frame = picture->frame; if (GST_CLOCK_TIME_IS_VALID (frame->pts)) frame->pts += encoder->cts_offset; *output = picture; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 958dd6e983..943325cbdc 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -454,8 +454,8 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, g_assert (misc); if (!misc) return FALSE; - gst_vaapi_enc_picture_add_misc_buffer (picture, misc); - hrd = misc->impl; + gst_vaapi_enc_picture_add_misc_param (picture, misc); + hrd = misc->data; if (base_encoder->bitrate > 0) { hrd->initial_buffer_fullness = base_encoder->bitrate * 1000 * 4; hrd->buffer_size = base_encoder->bitrate * 1000 * 8; @@ -471,8 +471,8 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, g_assert (misc); if (!misc) return FALSE; - gst_vaapi_enc_picture_add_misc_buffer (picture, misc); - rate_control = misc->impl; + gst_vaapi_enc_picture_add_misc_param (picture, misc); + rate_control = misc->data; memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); if (base_encoder->bitrate) rate_control->bits_per_second = base_encoder->bitrate * 1000; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index b4bdbd9bc2..3702318f03 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -20,12 +20,10 @@ */ #include "sysdeps.h" -#include "glibcompat.h" - #include "gstvaapiencoder_objects.h" -#include "gstvaapiencoder.h" #include "gstvaapiencoder_priv.h" #include "gstvaapisurfaceproxy_priv.h" +#include "gstvaapicompat.h" #include "gstvaapiutils.h" #define DEBUG 1 @@ -43,45 +41,39 @@ GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncPackedHeader, gst_vaapi_enc_packed_header); void -gst_vaapi_enc_packed_header_destroy (GstVaapiEncPackedHeader * packed_header) +gst_vaapi_enc_packed_header_destroy (GstVaapiEncPackedHeader * header) { - vaapi_destroy_buffer (GET_VA_DISPLAY (packed_header), - &packed_header->param_id); - vaapi_destroy_buffer (GET_VA_DISPLAY (packed_header), - &packed_header->data_id); - packed_header->param = NULL; - packed_header->data = NULL; + 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 * packed_header, +gst_vaapi_enc_packed_header_create (GstVaapiEncPackedHeader * header, const GstVaapiCodecObjectConstructorArgs * args) { gboolean success; - packed_header->param_id = VA_INVALID_ID; - packed_header->param = NULL; - packed_header->data_id = VA_INVALID_ID; - packed_header->data = NULL; - success = vaapi_create_buffer (GET_VA_DISPLAY (packed_header), - GET_VA_CONTEXT (packed_header), + 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, &packed_header->param_id, &packed_header->param); + 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 (packed_header), - GET_VA_CONTEXT (packed_header), + success = vaapi_create_buffer (GET_VA_DISPLAY (header), + GET_VA_CONTEXT (header), VAEncPackedHeaderDataBufferType, - args->data_size, - args->data, &packed_header->data_id, &packed_header->data); + args->data_size, args->data, &header->data_id, &header->data); if (!success) return FALSE; - return TRUE; } @@ -97,21 +89,18 @@ gst_vaapi_enc_packed_header_new (GstVaapiEncoder * encoder, } gboolean -gst_vaapi_enc_packed_header_set_data (GstVaapiEncPackedHeader * packed_header, +gst_vaapi_enc_packed_header_set_data (GstVaapiEncPackedHeader * header, gconstpointer data, guint data_size) { gboolean success; - g_assert (packed_header->data_id == VA_INVALID_ID); - if (packed_header->data_id != VA_INVALID_ID) { - vaapi_destroy_buffer (GET_VA_DISPLAY (packed_header), - &packed_header->data_id); - packed_header->data = NULL; - } - success = vaapi_create_buffer (GET_VA_DISPLAY (packed_header), - GET_VA_CONTEXT (packed_header), + 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, &packed_header->data_id, &packed_header->data); + data_size, data, &header->data_id, &header->data); if (!success) return FALSE; return TRUE; @@ -143,7 +132,6 @@ gst_vaapi_enc_sequence_create (GstVaapiEncSequence * sequence, args->param_size, args->param, &sequence->param_id, &sequence->param); if (!success) return FALSE; - return TRUE; } @@ -155,7 +143,7 @@ gst_vaapi_enc_sequence_new (GstVaapiEncoder * encoder, object = gst_vaapi_codec_object_new (&GstVaapiEncSequenceClass, GST_VAAPI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); - return GST_VAAPI_ENC_SEQUENCE_CAST (object); + return GST_VAAPI_ENC_SEQUENCE (object); } /* ------------------------------------------------------------------------- */ @@ -184,7 +172,6 @@ gst_vaapi_enc_slice_create (GstVaapiEncSlice * slice, args->param_size, args->param, &slice->param_id, &slice->param); if (!success) return FALSE; - return TRUE; } @@ -196,7 +183,7 @@ gst_vaapi_enc_slice_new (GstVaapiEncoder * encoder, object = gst_vaapi_codec_object_new (&GstVaapiEncSliceClass, GST_VAAPI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); - return GST_VAAPI_ENC_SLICE_CAST (object); + return GST_VAAPI_ENC_SLICE (object); } /* ------------------------------------------------------------------------- */ @@ -210,7 +197,7 @@ gst_vaapi_enc_misc_param_destroy (GstVaapiEncMiscParam * misc) { vaapi_destroy_buffer (GET_VA_DISPLAY (misc), &misc->param_id); misc->param = NULL; - misc->impl = NULL; + misc->data = NULL; } gboolean @@ -226,29 +213,28 @@ gst_vaapi_enc_misc_param_create (GstVaapiEncMiscParam * misc, 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 total_size) + VAEncMiscParameterType type, guint data_size) { GstVaapiCodecObject *object; - GstVaapiEncMiscParam *misc_obj; - VAEncMiscParameterBuffer *misc; + GstVaapiEncMiscParam *misc; + VAEncMiscParameterBuffer *va_misc; object = gst_vaapi_codec_object_new (&GstVaapiEncMiscParamClass, - GST_VAAPI_CODEC_BASE (encoder), NULL, total_size, NULL, 0, 0); + GST_VAAPI_CODEC_BASE (encoder), + NULL, sizeof (VAEncMiscParameterBuffer) + data_size, NULL, 0, 0); if (!object) return NULL; - misc_obj = GST_VAAPI_ENC_MISC_PARAM_CAST (object); - misc = misc_obj->param; - misc->type = type; - misc_obj->impl = misc->data; - g_assert (misc_obj->impl); - return misc_obj; + misc = GST_VAAPI_ENC_MISC_PARAM (object); + va_misc = misc->param; + va_misc->type = type; + misc->data = va_misc->data; + return misc; } /* ------------------------------------------------------------------------- */ @@ -257,34 +243,22 @@ gst_vaapi_enc_misc_param_new (GstVaapiEncoder * encoder, GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncPicture, gst_vaapi_enc_picture); -static void -destroy_vaapi_obj_cb (gpointer data, gpointer user_data) -{ - GstVaapiMiniObject *const object = data; - - gst_vaapi_mini_object_unref (object); -} - void gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture) { if (picture->packed_headers) { - g_ptr_array_foreach (picture->packed_headers, destroy_vaapi_obj_cb, NULL); - g_ptr_array_free (picture->packed_headers, TRUE); + g_ptr_array_unref (picture->packed_headers); picture->packed_headers = NULL; } - if (picture->misc_buffers) { - g_ptr_array_foreach (picture->misc_buffers, destroy_vaapi_obj_cb, NULL); - g_ptr_array_free (picture->misc_buffers, TRUE); - picture->misc_buffers = NULL; + if (picture->misc_params) { + g_ptr_array_unref (picture->misc_params); + picture->misc_params = NULL; } if (picture->slices) { - g_ptr_array_foreach (picture->slices, destroy_vaapi_obj_cb, NULL); - g_ptr_array_free (picture->slices, TRUE); + g_ptr_array_unref (picture->slices); picture->slices = NULL; } - gst_vaapi_mini_object_replace ( - (GstVaapiMiniObject **) (&picture->sequence), NULL); + gst_vaapi_codec_object_replace (&picture->sequence, NULL); gst_vaapi_surface_proxy_replace (&picture->proxy, NULL); picture->surface_id = VA_INVALID_ID; @@ -292,7 +266,6 @@ gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture) vaapi_destroy_buffer (GET_VA_DISPLAY (picture), &picture->param_id); picture->param = NULL; - picture->param = NULL; if (picture->frame) { gst_video_codec_frame_unref (picture->frame); @@ -307,8 +280,6 @@ gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture, GstVideoCodecFrame *const frame = (GstVideoCodecFrame *) args->data; gboolean success; - g_return_val_if_fail (frame != NULL, FALSE); - picture->proxy = gst_video_codec_frame_get_user_data (frame); if (!gst_vaapi_surface_proxy_ref (picture->proxy)) return FALSE; @@ -321,7 +292,6 @@ gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture, if (picture->surface_id == VA_INVALID_ID) return FALSE; - picture->sequence = NULL; picture->type = GST_VAAPI_PICTURE_TYPE_NONE; picture->pts = GST_CLOCK_TIME_NONE; picture->frame_num = 0; @@ -329,7 +299,6 @@ gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture, picture->param_id = VA_INVALID_ID; picture->param_size = args->param_size; - picture->param = NULL; success = vaapi_create_buffer (GET_VA_DISPLAY (picture), GET_VA_CONTEXT (picture), VAEncPictureParameterBufferType, @@ -338,17 +307,22 @@ gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture, return FALSE; picture->param_size = args->param_size; - picture->packed_headers = g_ptr_array_new (); - picture->misc_buffers = g_ptr_array_new (); - picture->slices = g_ptr_array_new (); + picture->packed_headers = g_ptr_array_new_with_free_func ((GDestroyNotify) + gst_vaapi_mini_object_unref); + if (!picture->packed_headers) + return FALSE; - g_assert (picture->packed_headers && picture->misc_buffers - && picture->slices); - if (!picture->packed_headers || !picture->misc_buffers || !picture->slices) + 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; } @@ -358,59 +332,52 @@ gst_vaapi_enc_picture_new (GstVaapiEncoder * encoder, { 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); - if (!object) - return NULL; - return GST_VAAPI_ENC_PICTURE_CAST (object); + return GST_VAAPI_ENC_PICTURE (object); } void gst_vaapi_enc_picture_set_sequence (GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) { - g_return_if_fail (GST_VAAPI_IS_ENC_PICTURE (picture)); - g_return_if_fail (GST_VAAPI_IS_ENC_SEQUENCE (sequence)); + g_return_if_fail (picture != NULL); + g_return_if_fail (sequence != NULL); - g_assert (sequence); - gst_vaapi_mini_object_replace ( - (GstVaapiMiniObject **) (&picture->sequence), - GST_VAAPI_MINI_OBJECT (sequence)); + gst_vaapi_codec_object_replace (&picture->sequence, sequence); } void gst_vaapi_enc_picture_add_packed_header (GstVaapiEncPicture * picture, GstVaapiEncPackedHeader * header) { - g_return_if_fail (GST_VAAPI_IS_ENC_PICTURE (picture)); - g_return_if_fail (GST_VAAPI_IS_ENC_PACKED_HEADER (header)); + g_return_if_fail (picture != NULL); + g_return_if_fail (header != NULL); - g_assert (picture->packed_headers); g_ptr_array_add (picture->packed_headers, - gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (header))); + gst_vaapi_codec_object_ref (header)); } void -gst_vaapi_enc_picture_add_misc_buffer (GstVaapiEncPicture * picture, +gst_vaapi_enc_picture_add_misc_param (GstVaapiEncPicture * picture, GstVaapiEncMiscParam * misc) { - g_return_if_fail (GST_VAAPI_IS_ENC_PICTURE (picture)); - g_return_if_fail (GST_VAAPI_IS_ENC_MISC_PARAM (misc)); + g_return_if_fail (picture != NULL); + g_return_if_fail (misc != NULL); - g_assert (picture->misc_buffers); - g_ptr_array_add (picture->misc_buffers, - gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (misc))); + 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 (GST_VAAPI_IS_ENC_PICTURE (picture)); - g_return_if_fail (GST_VAAPI_IS_ENC_SLICE (slice)); + g_return_if_fail (picture != NULL); + g_return_if_fail (slice != NULL); - g_ptr_array_add (picture->slices, - gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (slice))); + g_ptr_array_add (picture->slices, gst_vaapi_codec_object_ref (slice)); } static gboolean @@ -433,15 +400,12 @@ gboolean gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture) { GstVaapiEncSequence *sequence; - GstVaapiEncPackedHeader *packed_header; - GstVaapiEncMiscParam *misc; - GstVaapiEncSlice *slice; VADisplay va_display; VAContextID va_context; VAStatus status; guint i; - g_return_val_if_fail (GST_VAAPI_IS_ENC_PICTURE (picture), FALSE); + 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); @@ -453,38 +417,37 @@ gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture) if (!vaapi_check_status (status, "vaBeginPicture()")) return FALSE; - /* encode sequence parameter */ + /* Submit Sequence parameter */ sequence = picture->sequence; - if (sequence) { - if (!do_encode (va_display, va_context, - &sequence->param_id, &sequence->param)) - return FALSE; - } + if (sequence && !do_encode (va_display, va_context, + &sequence->param_id, &sequence->param)) + return FALSE; - /* encode picture parameter */ + /* Submit Picture parameter */ if (!do_encode (va_display, va_context, &picture->param_id, &picture->param)) return FALSE; - /* encode packed headers */ + /* Submit Packed Headers */ for (i = 0; i < picture->packed_headers->len; i++) { - packed_header = g_ptr_array_index (picture->packed_headers, i); + GstVaapiEncPackedHeader *const header = + g_ptr_array_index (picture->packed_headers, i); if (!do_encode (va_display, va_context, - &packed_header->param_id, &packed_header->param) || - !do_encode (va_display, va_context, - &packed_header->data_id, &packed_header->data)) + &header->param_id, &header->param) || + !do_encode (va_display, va_context, &header->data_id, &header->data)) return FALSE; } - /* encode misc buffers */ - for (i = 0; i < picture->misc_buffers->len; i++) { - misc = g_ptr_array_index (picture->misc_buffers, i); + /* 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; } - /* encode slice parameters */ + /* Submit Slice parameters */ for (i = 0; i < picture->slices->len; i++) { - slice = g_ptr_array_index (picture->slices, i); + GstVaapiEncSlice *const slice = g_ptr_array_index (picture->slices, i); if (!do_encode (va_display, va_context, &slice->param_id, &slice->param)) return FALSE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index d57ad5080b..f97d4afabe 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -39,27 +39,21 @@ typedef struct _GstVaapiEncPackedHeader GstVaapiEncPackedHeader; /* --- Encoder Packed Header --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_ENC_PACKED_HEADER_CAST(obj) \ - ((GstVaapiEncPackedHeader *)(obj)) - -#define GST_VAAPI_ENC_PACKED_HEADER(obj) \ - GST_VAAPI_ENC_PACKED_HEADER_CAST(obj) - -#define GST_VAAPI_IS_ENC_PACKED_HEADER(obj) \ - (GST_VAAPI_ENC_PACKED_HEADER(obj) != NULL) +#define GST_VAAPI_ENC_PACKED_HEADER(obj) \ + ((GstVaapiEncPackedHeader *) (obj)) /** * GstVaapiEncPackedHeader: * - * A #GstVaapiCodecObject holding a encoder packed header - * parameter/data parameter. + * A #GstVaapiCodecObject holding a packed header (param/data) for the + * encoder. */ struct _GstVaapiEncPackedHeader { - /*< private > */ + /*< private >*/ GstVaapiCodecObject parent_instance; - /*< public > */ + /*< public >*/ VABufferID param_id; gpointer param; VABufferID data_id; @@ -73,33 +67,27 @@ gst_vaapi_enc_packed_header_new (GstVaapiEncoder * encoder, G_GNUC_INTERNAL gboolean -gst_vaapi_enc_packed_header_set_data (GstVaapiEncPackedHeader * packed_header, +gst_vaapi_enc_packed_header_set_data (GstVaapiEncPackedHeader * header, gconstpointer data, guint data_size); /* ------------------------------------------------------------------------- */ /* --- Encoder Sequence --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_ENC_SEQUENCE_CAST(obj) \ - ((GstVaapiEncSequence *)(obj)) - -#define GST_VAAPI_ENC_SEQUENCE(obj) \ - GST_VAAPI_ENC_SEQUENCE_CAST(obj) - -#define GST_VAAPI_IS_ENC_SEQUENCE(obj) \ - (GST_VAAPI_ENC_SEQUENCE(obj) != NULL) +#define GST_VAAPI_ENC_SEQUENCE(obj) \ + ((GstVaapiEncSequence *) (obj)) /** * GstVaapiEncSequence: * - * A #GstVaapiCodecObject holding a encoder sequence parameter. + * A #GstVaapiCodecObject holding a sequence parameter for encoding. */ struct _GstVaapiEncSequence { - /*< private > */ + /*< private >*/ GstVaapiCodecObject parent_instance; - /*< public > */ + /*< public >*/ VABufferID param_id; gpointer param; }; @@ -113,39 +101,24 @@ gst_vaapi_enc_sequence_new (GstVaapiEncoder * encoder, /* --- Encoder Slice --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_ENC_SLICE_CAST(obj) \ - ((GstVaapiEncSlice *)(obj)) - -#define GST_VAAPI_ENC_SLICE(obj) \ - GST_VAAPI_ENC_SLICE_CAST(obj) - -#define GST_VAAPI_IS_ENC_SLICE(obj) \ - (GST_VAAPI_ENC_SLICE(obj) != NULL) +#define GST_VAAPI_ENC_SLICE(obj) \ + ((GstVaapiEncSlice *) (obj)) /** * GstVaapiEncSlice: * - * A #GstVaapiCodecObject holding a encoder slice parameter. + * A #GstVaapiCodecObject holding a slice parameter used for encoding. */ struct _GstVaapiEncSlice { - /*< private > */ + /*< private >*/ GstVaapiCodecObject parent_instance; - /*< public > */ + /*< public >*/ VABufferID param_id; gpointer param; }; -G_GNUC_INTERNAL -void -gst_vaapi_enc_slice_destroy (GstVaapiEncSlice * slice); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_enc_slice_create (GstVaapiEncSlice * slice, - const GstVaapiCodecObjectConstructorArgs * args); - G_GNUC_INTERNAL GstVaapiEncSlice * gst_vaapi_enc_slice_new (GstVaapiEncoder * encoder, @@ -155,48 +128,37 @@ gst_vaapi_enc_slice_new (GstVaapiEncoder * encoder, /* --- Encoder Misc Parameter Buffer --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_ENC_MISC_PARAM_CAST(obj) \ - ((GstVaapiEncMiscParam *)(obj)) - -#define GST_VAAPI_ENC_MISC_PARAM(obj) \ - GST_VAAPI_ENC_MISC_PARAM_CAST(obj) - -#define GST_VAAPI_IS_ENC_MISC_PARAM(obj) \ - (GST_VAAPI_ENC_MISC_PARAM(obj) != NULL) +#define GST_VAAPI_ENC_MISC_PARAM(obj) \ + ((GstVaapiEncMiscParam *) (obj)) /** * GstVaapiEncMiscParam: * - * A #GstVaapiCodecObject holding a encoder misc parameter. + * A #GstVaapiCodecObject holding a misc parameter and associated data + * used for controlling the encoder dynamically. */ struct _GstVaapiEncMiscParam { - /*< private > */ + /*< private >*/ GstVaapiCodecObject parent_instance; gpointer param; - /*< public > */ + /*< public >*/ VABufferID param_id; - gpointer impl; + gpointer data; }; G_GNUC_INTERNAL GstVaapiEncMiscParam * gst_vaapi_enc_misc_param_new (GstVaapiEncoder * encoder, - VAEncMiscParameterType type, guint total_size); + VAEncMiscParameterType type, guint data_size); /* ------------------------------------------------------------------------- */ /* --- Encoder Picture --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_ENC_PICTURE_CAST(obj) \ - ((GstVaapiEncPicture *)(obj)) - #define GST_VAAPI_ENC_PICTURE(obj) \ - GST_VAAPI_ENC_PICTURE_CAST(obj) - -#define GST_VAAPI_IS_ENC_PICTURE(obj) \ - (GST_VAAPI_ENC_PICTURE(obj) != NULL) + ((GstVaapiEncPicture *) (obj)) typedef enum { @@ -212,47 +174,36 @@ typedef enum #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_GET_FRAME(picture) \ - (picture)->frame - /** * GstVaapiEncPicture: * - * A #GstVaapiCodecObject holding a picture parameter. + * A #GstVaapiCodecObject holding a picture parameter for encoding. */ struct _GstVaapiEncPicture { - /*< private > */ + /*< private >*/ GstVaapiCodecObject parent_instance; GstVideoCodecFrame *frame; GstVaapiSurfaceProxy *proxy; GstVaapiSurface *surface; - GstVaapiEncSequence *sequence; - /*< private >, picture packed header */ - GPtrArray *packed_headers; - GPtrArray *misc_buffers; - GPtrArray *slices; VABufferID param_id; guint param_size; - /*< public > */ + /* Additional data to pass down */ + GstVaapiEncSequence *sequence; + GPtrArray *packed_headers; + GPtrArray *misc_params; + + /*< public >*/ GstVaapiPictureType type; VASurfaceID surface_id; gpointer param; + GPtrArray *slices; GstClockTime pts; guint frame_num; guint poc; }; -G_GNUC_INTERNAL -void -gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture, - const GstVaapiCodecObjectConstructorArgs * args); - G_GNUC_INTERNAL GstVaapiEncPicture * gst_vaapi_enc_picture_new (GstVaapiEncoder * encoder, @@ -270,7 +221,7 @@ gst_vaapi_enc_picture_add_packed_header (GstVaapiEncPicture * picture, G_GNUC_INTERNAL void -gst_vaapi_enc_picture_add_misc_buffer (GstVaapiEncPicture * picture, +gst_vaapi_enc_picture_add_misc_param (GstVaapiEncPicture * picture, GstVaapiEncMiscParam * misc); G_GNUC_INTERNAL @@ -282,47 +233,37 @@ G_GNUC_INTERNAL gboolean gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture); -static inline gpointer -gst_vaapi_enc_picture_ref (gpointer ptr) -{ - return gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (ptr)); -} +#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) -static inline void -gst_vaapi_enc_picture_unref (gpointer ptr) -{ - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (ptr)); -} +/* ------------------------------------------------------------------------- */ +/* --- Helpers to create codec-dependent objects --- */ +/* ------------------------------------------------------------------------- */ -#define gst_vaapi_enc_picture_replace(old_picture_p, new_picture) \ - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_picture_p), \ - (GstVaapiMiniObject *)(new_picture)) - -/* GST_VAAPI_CODED_BUFFER_NEW */ -#define GST_VAAPI_CODED_BUFFER_NEW(encoder, size) \ - gst_vaapi_coded_buffer_new(GST_VAAPI_ENCODER_CAST(encoder), \ - NULL, size) - -/* GST_VAAPI_ENC_SEQUENCE_NEW */ +/* GstVaapiEncSequence */ #define GST_VAAPI_ENC_SEQUENCE_NEW(codec, encoder) \ - gst_vaapi_enc_sequence_new(GST_VAAPI_ENCODER_CAST(encoder), \ - NULL, sizeof(VAEncSequenceParameterBuffer##codec)) + gst_vaapi_enc_sequence_new (GST_VAAPI_ENCODER_CAST (encoder), \ + NULL, sizeof (G_PASTE (VAEncSequenceParameterBuffer, codec))) -/* GST_VAAPI_ENC_SLICE_NEW */ -#define GST_VAAPI_ENC_SLICE_NEW(codec, encoder) \ - gst_vaapi_enc_slice_new(GST_VAAPI_ENCODER_CAST(encoder), \ - NULL, sizeof(VAEncSliceParameterBuffer##codec)) - -/* GST_VAAPI_ENC_MISC_PARAM_NEW */ +/* GstVaapiEncMiscParam */ #define GST_VAAPI_ENC_MISC_PARAM_NEW(type, encoder) \ - gst_vaapi_enc_misc_param_new(GST_VAAPI_ENCODER_CAST(encoder), \ - VAEncMiscParameterType##type, \ - (sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameter##type))) + gst_vaapi_enc_misc_param_new (GST_VAAPI_ENCODER_CAST (encoder), \ + G_PASTE (VAEncMiscParameterType, type), \ + sizeof (G_PASTE (VAEncMiscParameter, type))) -/* GST_VAAPI_ENC_PICTURE_NEW */ +/* GstVaapiEncPicture */ #define GST_VAAPI_ENC_PICTURE_NEW(codec, encoder, frame) \ - gst_vaapi_enc_picture_new(GST_VAAPI_ENCODER_CAST(encoder), \ - NULL, sizeof(VAEncPictureParameterBuffer##codec), 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))) G_END_DECLS From c03682ecc1ad88321422008746a94ae4286816ff Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 14 Jan 2014 13:47:52 +0100 Subject: [PATCH 1526/3781] encoder: re-order submission of VA objects. Change the submission order of VA objects so that to make that process more logical. i.e. submit sequence parameter first, if any; next the packed headers associated to sequece, picture or slices; and finally the actual picture and associated slices. --- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index 3702318f03..558356132f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -423,10 +423,6 @@ gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture) &sequence->param_id, &sequence->param)) return FALSE; - /* Submit Picture parameter */ - if (!do_encode (va_display, va_context, &picture->param_id, &picture->param)) - return FALSE; - /* Submit Packed Headers */ for (i = 0; i < picture->packed_headers->len; i++) { GstVaapiEncPackedHeader *const header = @@ -445,6 +441,10 @@ gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture) return FALSE; } + /* Submit Picture parameter */ + if (!do_encode (va_display, va_context, &picture->param_id, &picture->param)) + return FALSE; + /* Submit Slice parameters */ for (i = 0; i < picture->slices->len; i++) { GstVaapiEncSlice *const slice = g_ptr_array_index (picture->slices, i); From b065ae7d7fb998833f1c44d6e46356e8c5c913b8 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Thu, 9 Jan 2014 11:54:11 +0000 Subject: [PATCH 1527/3781] plugins: don't apply overlay composition in GLTextureUpload function. The GLTextureUpload function is not in charge of doing the overlay composition if any. https://bugzilla.gnome.org/show_bug.cgi?id=721859 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapivideometa_texture.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 8d96770748..bb7bcea826 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -96,10 +96,6 @@ gst_vaapi_texture_upload(GstVideoGLTextureUploadMeta *meta, guint texture_id[4]) return FALSE; gst_vaapi_texture_unref(texture); } - - if (!gst_vaapi_apply_composition(surface, meta->buffer)) - GST_WARNING("could not update subtitles"); - return gst_vaapi_texture_put_surface(meta_texture->texture, surface, gst_vaapi_video_meta_get_render_flags(vmeta)); } From ef9819ecf4cf50bd030129d66d7a02d6bb39f0ae Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 14 Jan 2014 19:08:36 +0100 Subject: [PATCH 1528/3781] plugins: add helpers to create video caps with features. Add gst_vaapi_video_format_new_template_caps_with_features() helper function to add the supplied caps feature string on GStreamer >= 1.2. Add gst_vaapi_find_preferred_caps_feature() helper function to discover the "best" caps feature to use for the supplied pad. In practice, we will always favor memory:VASurface first, then meta:GLTextureUploadMeta, and finally the system memory caps. https://bugzilla.gnome.org/show_bug.cgi?id=719372 --- gst/vaapi/gstvaapipluginutil.c | 92 ++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 19 +++++++ 2 files changed, 111 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 29711687c1..e9790eef9f 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -475,6 +475,98 @@ gst_vaapi_video_format_new_template_caps_from_list (GArray * formats) return caps; } +GstCaps * +gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, + const gchar * features_string) +{ + GstCaps *caps; + + caps = gst_vaapi_video_format_new_template_caps (format); + if (!caps) + return NULL; + +#if GST_CHECK_VERSION(1,1,0) + GstCapsFeatures *const features = + gst_caps_features_new (features_string, NULL); + if (!features) { + gst_caps_unref (caps); + return NULL; + } + gst_caps_set_features (caps, 0, features); +#endif + return caps; +} + +GstVaapiCapsFeature +gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format) +{ + GstVaapiCapsFeature feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; +#if GST_CHECK_VERSION(1,1,0) + guint i, num_structures; + GstCaps *caps = NULL; + GstCaps *gl_texture_upload_caps = NULL; + GstCaps *sysmem_caps = NULL; + GstCaps *vaapi_caps = NULL; + GstCaps *out_caps; + + out_caps = gst_pad_peer_query_caps (pad, NULL); + if (!out_caps) + goto cleanup; + + gl_texture_upload_caps = + gst_vaapi_video_format_new_template_caps_with_features + (GST_VIDEO_FORMAT_RGBA, + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META); + if (!gl_texture_upload_caps) + goto cleanup; + + if (format == GST_VIDEO_FORMAT_ENCODED) + format = GST_VIDEO_FORMAT_NV12; + + vaapi_caps = + gst_vaapi_video_format_new_template_caps_with_features (format, + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE); + if (!vaapi_caps) + goto cleanup; + + sysmem_caps = + gst_vaapi_video_format_new_template_caps_with_features (format, + GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY); + if (!sysmem_caps) + goto cleanup; + + num_structures = gst_caps_get_size (out_caps); + for (i = 0; i < num_structures; i++) { + GstCapsFeatures *const features = gst_caps_get_features (out_caps, i); + GstStructure *const structure = gst_caps_get_structure (out_caps, i); + + caps = gst_caps_new_full (gst_structure_copy (structure), NULL); + if (!caps) + continue; + gst_caps_set_features (caps, 0, gst_caps_features_copy (features)); + + if (gst_caps_can_intersect (caps, vaapi_caps) && + feature < GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) + feature = GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE; + else if (gst_caps_can_intersect (caps, gl_texture_upload_caps) && + feature < GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) + feature = GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META; + else if (gst_caps_can_intersect (caps, sysmem_caps) && + feature < GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) + feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; + gst_caps_replace (&caps, NULL); + } + +cleanup: + gst_caps_replace (&gl_texture_upload_caps, NULL); + gst_caps_replace (&sysmem_caps, NULL); + gst_caps_replace (&vaapi_caps, NULL); + gst_caps_replace (&caps, NULL); + gst_caps_replace (&out_caps, NULL); +#endif + return feature; +} + gboolean gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip) { diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 0c6e55703c..0276998057 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -27,6 +27,9 @@ #include #include +#if GST_CHECK_VERSION(1,0,0) +#include "gstvaapivideomemory.h" +#endif G_GNUC_INTERNAL gboolean @@ -65,6 +68,13 @@ gboolean gst_vaapi_value_set_format_list (GValue * value, GArray * formats); /* Helpers to build video caps */ +typedef enum +{ + GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY = 1, + GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META, + GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE, +} GstVaapiCapsFeature; + G_GNUC_INTERNAL GstCaps * gst_vaapi_video_format_new_template_caps (GstVideoFormat format); @@ -73,6 +83,15 @@ G_GNUC_INTERNAL GstCaps * gst_vaapi_video_format_new_template_caps_from_list (GArray * formats); +G_GNUC_INTERNAL +GstCaps * +gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, + const gchar * features_string); + +G_GNUC_INTERNAL +GstVaapiCapsFeature +gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format); + /* Helpers to handle interlaced contents */ #if GST_CHECK_VERSION(1,0,0) # define GST_CAPS_INTERLACED_MODES \ From d3b672411d2161f4ef0703ea4ae4f33e42cd6d56 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 14 Jan 2014 16:33:04 +0100 Subject: [PATCH 1529/3781] vaapiencode: fix typo in error message. Fix incomplete error message in gst_vaapiencode_push_frame(). --- gst/vaapi/gstvaapiencode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 0782ca18c9..2ac023d610 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -317,7 +317,7 @@ error_allocate_buffer: } error_output_state: { - GST_ERROR ("failed to negotiate output state", status); + GST_ERROR ("failed to negotiate output state (status %d)", status); GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); gst_video_codec_frame_unref (out_frame); return GST_FLOW_NOT_NEGOTIATED; From 830566c17e3e2be79a2bbc6caf5b8e53643b3be8 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 17 Dec 2013 04:23:42 -0500 Subject: [PATCH 1530/3781] vaapiencode: fix possible hang on SIGINT. vaapiencode might hang when the pipeline is stopped without any EOS, e.g. when +C is pressed, thus causing the srcpad task to keep running and locked. This fixes a possible deadlock on state change from PAUSED to READY. https://bugzilla.gnome.org/show_bug.cgi?id=720584 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapiencode.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 2ac023d610..9344f97af5 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -595,6 +595,22 @@ gst_vaapiencode_finish (GstVideoEncoder * venc) return ret; } +static GstStateChangeReturn +gst_vaapiencode_change_state (GstElement * element, GstStateChange transition) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (element); + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_pad_stop_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); + break; + default: + break; + } + return GST_ELEMENT_CLASS (gst_vaapiencode_parent_class)-> + change_state (element, transition); +} + #if GST_CHECK_VERSION(1,0,0) static gboolean gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query) @@ -639,6 +655,7 @@ static void gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVideoEncoderClass *const venc_class = GST_VIDEO_ENCODER_CLASS (klass); GST_DEBUG_CATEGORY_INIT (gst_vaapiencode_debug, @@ -648,6 +665,9 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) object_class->finalize = gst_vaapiencode_finalize; + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_vaapiencode_change_state); + venc_class->open = GST_DEBUG_FUNCPTR (gst_vaapiencode_open); venc_class->close = GST_DEBUG_FUNCPTR (gst_vaapiencode_close); venc_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_format); From d2f6274f31100e9a41dfc91a9064ee1a3c1b5e29 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 17 Dec 2013 10:26:03 +0800 Subject: [PATCH 1531/3781] vaapidecode: fix hang on SIGINT. vaapidecode hangs when pipeline is stopped without any EOS, e.g. when +C is pressed, thus causing the srcpad task to keep running and locked. This fixes a deadlock on state change from PAUSED to READY. https://bugzilla.gnome.org/show_bug.cgi?id=720584 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f31ad78dc5..8d4e4753b8 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -769,6 +769,22 @@ gst_vaapidecode_parse(GstVideoDecoder *vdec, return ret; } +static GstStateChangeReturn +gst_vaapidecode_change_state (GstElement * element, GstStateChange transition) +{ + GstVaapiDecode * const decode = GST_VAAPIDECODE(element); + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); + break; + default: + break; + } + return GST_ELEMENT_CLASS(gst_vaapidecode_parent_class)->change_state( + element, transition); +} + static void gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) { @@ -784,6 +800,9 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) object_class->finalize = gst_vaapidecode_finalize; + element_class->change_state = + GST_DEBUG_FUNCPTR(gst_vaapidecode_change_state); + vdec_class->open = GST_DEBUG_FUNCPTR(gst_vaapidecode_open); vdec_class->close = GST_DEBUG_FUNCPTR(gst_vaapidecode_close); vdec_class->set_format = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_format); From cb81acd48ce04ae94757e6ec81a915863d51872e Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Tue, 17 Dec 2013 15:27:10 +0000 Subject: [PATCH 1532/3781] vaapidecode: add system memory caps to template caps. Since vaapidecode provides buffer that can be mapped as regular memory, those caps should be added to the template caps. That only applies to GStreamer >= 1.2. https://bugzilla.gnome.org/show_bug.cgi?id=720608 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 8d4e4753b8..b3519a9761 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -75,7 +75,8 @@ static const char gst_vaapidecode_src_caps_str[] = GST_VIDEO_CAPS_MAKE_WITH_FEATURES( GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ";" GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA"); + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA") ";" + GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12 }"); #else GST_VAAPI_SURFACE_CAPS; #endif From a674d9eff2665327fa534c2edbcb2cb8ed71d815 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Wed, 11 Dec 2013 18:08:26 +0000 Subject: [PATCH 1533/3781] vaapidecode: query downstream caps features like GLTextureUploadMeta. Fix vaapidecode to correctly report caps features downstream, when a custom pipeline is built manually. https://bugzilla.gnome.org/show_bug.cgi?id=719372 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 72 ++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b3519a9761..5d45b025a0 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -110,10 +110,12 @@ gst_vaapi_decoder_state_changed(GstVaapiDecoder *decoder, const GstVideoCodecState *codec_state, gpointer user_data) { GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data); + GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); g_assert(decode->decoder == decoder); gst_vaapidecode_update_src_caps(decode, codec_state); + gst_video_decoder_negotiate(vdec); } static inline gboolean @@ -130,6 +132,14 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); GstVideoCodecState *state; GstVideoInfo *vi, vis; +#if GST_CHECK_VERSION(1,1,0) + GstCapsFeatures *features = NULL; + GstVaapiCapsFeature feature; + + feature = gst_vaapi_find_preferred_caps_feature( + GST_VIDEO_DECODER_SRC_PAD(vdec), + GST_VIDEO_INFO_FORMAT(&ref_state->info)); +#endif state = gst_video_decoder_set_output_state(vdec, GST_VIDEO_INFO_FORMAT(&ref_state->info), @@ -149,15 +159,32 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, #if GST_CHECK_VERSION(1,1,0) vis = *vi; - if (GST_VIDEO_INFO_FORMAT(vi) == GST_VIDEO_FORMAT_ENCODED) { - /* XXX: this is a workaround until auto-plugging is fixed when - format=ENCODED + memory:VASurface caps feature are provided. - Meanwhile, providing a random format here works but this is - a terribly wrong thing per se. */ - gst_video_info_set_format(&vis, GST_VIDEO_FORMAT_NV12, + switch (feature) { + case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: + gst_video_info_set_format(&vis, GST_VIDEO_FORMAT_RGBA, GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); + features = gst_caps_features_new( + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); + break; + default: + if (GST_VIDEO_INFO_FORMAT(vi) == GST_VIDEO_FORMAT_ENCODED) { + /* XXX: this is a workaround until auto-plugging is fixed when + format=ENCODED + memory:VASurface caps feature are provided. + Meanwhile, providing a random format here works but this is + a terribly wrong thing per se. */ + gst_video_info_set_format(&vis, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); +#if GST_CHECK_VERSION(1,3,0) + if (feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) + features = gst_caps_features_new( + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL); +#endif + } + break; } state->caps = gst_video_info_to_caps(&vis); + if (features) + gst_caps_set_features(state->caps, 0, features); #else /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not reconstruct suitable caps for "encoded" video formats */ @@ -461,12 +488,38 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) GstVideoInfo vi; guint size, min, max; gboolean need_pool, update_pool; + gboolean has_video_meta = FALSE; + GstVideoCodecState *state; +#if GST_CHECK_VERSION(1,1,0) && USE_GLX + GstCapsFeatures *features, *features2; +#endif gst_query_parse_allocation(query, &caps, &need_pool); if (!caps) goto error_no_caps; + state = gst_video_decoder_get_output_state(vdec); + + decode->has_texture_upload_meta = FALSE; + has_video_meta = gst_query_find_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL); +#if GST_CHECK_VERSION(1,1,0) && USE_GLX + if (has_video_meta) + decode->has_texture_upload_meta = gst_query_find_allocation_meta(query, + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); + + features = gst_caps_get_features(state->caps, 0); + features2 = gst_caps_features_new(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); + + /* Update src caps if feature is not handled downstream */ + if (!decode->has_texture_upload_meta && + gst_caps_features_is_equal(features, features2)) + gst_vaapidecode_update_src_caps (decode, state); + gst_caps_features_free(features2); +#endif + + gst_video_codec_state_unref(state); + gst_video_info_init(&vi); gst_video_info_from_caps(&vi, caps); if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) @@ -503,14 +556,11 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gst_buffer_pool_set_config(pool, config); } - decode->has_texture_upload_meta = FALSE; - if (gst_query_find_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL)) { + if (has_video_meta) { config = gst_buffer_pool_get_config(pool); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); #if GST_CHECK_VERSION(1,1,0) && USE_GLX - decode->has_texture_upload_meta = gst_query_find_allocation_meta(query, - GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); if (decode->has_texture_upload_meta) gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); @@ -717,6 +767,8 @@ gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) return FALSE; if (!gst_vaapidecode_update_src_caps(decode, state)) return FALSE; + if (!gst_video_decoder_negotiate(vdec)) + return FALSE; if (!gst_vaapi_plugin_base_set_caps(plugin, decode->sinkpad_caps, decode->srcpad_caps)) return FALSE; From dd6751ed47c8c7c2d69c25cbeb2d064d8fa96d66 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Oct 2013 13:47:54 +0300 Subject: [PATCH 1534/3781] vaapisink: expose the raw video formats in static caps template. Expose all raw video formats in the static caps template since the vaapisink is supporting raw data. We will get the exact set of formats supported by the driver dynamically through the _get_caps() routine. https://bugzilla.gnome.org/show_bug.cgi?id=703271 https://bugzilla.gnome.org/show_bug.cgi?id=720737 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 3b7f8d7d25..09d6d54954 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -87,7 +87,8 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink); static const char gst_vaapisink_sink_caps_str[] = #if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }"); + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ";" + GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL); #else #if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) "; " From f8666e2cae518c0514c3b2944e4607502f7ba350 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Wed, 15 Jan 2014 10:05:45 +0100 Subject: [PATCH 1535/3781] vaapisink: fix display initialization in GstVideoOverlay implementation. When gst_vaapisink_video_overlay_set_window_handle() is called early, before the pipeline has been set to PLAYING, the display has not yet been initialized and _PLUGIN_BASE_DISPLAY_TYPE() is not yet up-to-date. For this reason the foreign XID is not attached. Now _ensure_display() is called earlier. https://bugzilla.gnome.org/show_bug.cgi?id=722244 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 09d6d54954..9c5ecd2a43 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -139,6 +139,9 @@ enum { #define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 +static inline gboolean +gst_vaapisink_ensure_display(GstVaapiSink *sink); + /* GstVideoOverlay interface */ #if USE_X11 @@ -154,7 +157,11 @@ gst_vaapisink_video_overlay_set_window_handle(GstVideoOverlay *overlay, guintptr window) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); - GstVaapiDisplayType display_type = GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink); + GstVaapiDisplayType display_type; + + if (!gst_vaapisink_ensure_display(sink)) + return; + display_type = GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink); /* Disable GLX rendering when vaapisink is using a foreign X window. It's pretty much useless */ From e66179dffbe4bc95adfba6ed7631c0357bb233ad Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Fri, 20 Dec 2013 12:05:42 +0000 Subject: [PATCH 1536/3781] pkgconfig: plugin dir should use PKG version not API version. Fix the pluginsdir and includedir variables in the generated pkgconfig (.pc) files. The location needs to be built with the PKG version in mind instead of the API version. While we are at it, also fix the PKG version for GStreamer >= 1.3. https://bugzilla.gnome.org/show_bug.cgi?id=720820 [additional fixes for includedir and pkg requirements] Signed-off-by: Gwenole Beauchesne --- configure.ac | 3 +-- pkgconfig/gstreamer-vaapi-drm.pc.in | 4 ++-- pkgconfig/gstreamer-vaapi-glx.pc.in | 4 ++-- pkgconfig/gstreamer-vaapi-wayland.pc.in | 4 ++-- pkgconfig/gstreamer-vaapi-x11.pc.in | 4 ++-- pkgconfig/gstreamer-vaapi.pc.in | 6 +++--- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index 3710658931..db40b5eb8a 100644 --- a/configure.ac +++ b/configure.ac @@ -447,10 +447,9 @@ dnl Check for the GStreamer plugins directory AC_ARG_VAR([GST_PLUGIN_PATH], [installation path for gstreamer-vaapi plugin elements for GStreamer 0.10]) AC_ARG_VAR([GST_PLUGIN_PATH_1_0], [installation path for gstreamer-vaapi plugin elements for GStreamer 1.0]) AC_MSG_CHECKING([for GStreamer plugins directory]) -case $GST_API_VERSION in +case $GST_PKG_VERSION in 0.10) _gst_plugin_path="$GST_PLUGIN_PATH";; 1.0) _gst_plugin_path="$GST_PLUGIN_PATH_1_0";; -1.2) _gst_plugin_path="$GST_PLUGIN_PATH_1_0";; esac if test -d "$_gst_plugin_path"; then GST_PLUGINS_DIR="$_gst_plugin_path" diff --git a/pkgconfig/gstreamer-vaapi-drm.pc.in b/pkgconfig/gstreamer-vaapi-drm.pc.in index b7f3d917f3..799592bbb7 100644 --- a/pkgconfig/gstreamer-vaapi-drm.pc.in +++ b/pkgconfig/gstreamer-vaapi-drm.pc.in @@ -1,8 +1,8 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_API_VERSION@ -pluginsdir=@libdir@/gstreamer-@GST_API_VERSION@ +includedir=@includedir@/gstreamer-@GST_PKG_VERSION@ +pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ Name: GStreamer VA-API (DRM) Plugins Libraries Description: Streaming media framework, VA-API (DRM) plugins libraries diff --git a/pkgconfig/gstreamer-vaapi-glx.pc.in b/pkgconfig/gstreamer-vaapi-glx.pc.in index 789a2e176c..7a71b14d60 100644 --- a/pkgconfig/gstreamer-vaapi-glx.pc.in +++ b/pkgconfig/gstreamer-vaapi-glx.pc.in @@ -1,8 +1,8 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_API_VERSION@ -pluginsdir=@libdir@/gstreamer-@GST_API_VERSION@ +includedir=@includedir@/gstreamer-@GST_PKG_VERSION@ +pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ Name: GStreamer VA-API (GLX) Plugins Libraries Description: Streaming media framework, VA-API (GLX) plugins libraries diff --git a/pkgconfig/gstreamer-vaapi-wayland.pc.in b/pkgconfig/gstreamer-vaapi-wayland.pc.in index 90492084e9..05f5128d69 100644 --- a/pkgconfig/gstreamer-vaapi-wayland.pc.in +++ b/pkgconfig/gstreamer-vaapi-wayland.pc.in @@ -1,8 +1,8 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_API_VERSION@ -pluginsdir=@libdir@/gstreamer-@GST_API_VERSION@ +includedir=@includedir@/gstreamer-@GST_PKG_VERSION@ +pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ Name: GStreamer VA-API (Wayland) Plugins Libraries Description: Streaming media framework, VA-API (Wayland) plugins libraries diff --git a/pkgconfig/gstreamer-vaapi-x11.pc.in b/pkgconfig/gstreamer-vaapi-x11.pc.in index fd968b682c..acdbb51147 100644 --- a/pkgconfig/gstreamer-vaapi-x11.pc.in +++ b/pkgconfig/gstreamer-vaapi-x11.pc.in @@ -1,8 +1,8 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_API_VERSION@ -pluginsdir=@libdir@/gstreamer-@GST_API_VERSION@ +includedir=@includedir@/gstreamer-@GST_PKG_VERSION@ +pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ Name: GStreamer VA-API (X11) Plugins Libraries Description: Streaming media framework, VA-API (X11) plugins libraries diff --git a/pkgconfig/gstreamer-vaapi.pc.in b/pkgconfig/gstreamer-vaapi.pc.in index a33fc513c0..af6706bd67 100644 --- a/pkgconfig/gstreamer-vaapi.pc.in +++ b/pkgconfig/gstreamer-vaapi.pc.in @@ -1,12 +1,12 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_API_VERSION@ -pluginsdir=@libdir@/gstreamer-@GST_API_VERSION@ +includedir=@includedir@/gstreamer-@GST_PKG_VERSION@ +pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ Name: GStreamer VA-API Plugins Libraries Description: Streaming media framework, VA-API plugins libraries -Requires: gstreamer-@GST_API_VERSION@ gstreamer-base-@GST_API_VERSION@ @LIBVA_PKGNAME@ +Requires: gstreamer-@GST_PKG_VERSION@ gstreamer-base-@GST_PKG_VERSION@ @LIBVA_PKGNAME@ Version: @VERSION@ Libs: -L${libdir} -lgstvaapi-@GST_API_VERSION@ Cflags: -I${includedir} From db5465c2d6627766184c767adfc4f69e815366c9 Mon Sep 17 00:00:00 2001 From: "Zhao, Halley" Date: Thu, 12 Dec 2013 08:38:12 +0800 Subject: [PATCH 1537/3781] vaapipostproc: fix support for "sharpen" filter. Fix copy/paste error when submitting the "sharpen" value to the GstVaapiFilter instance. https://bugzilla.gnome.org/show_bug.cgi?id=720375 Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipostproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index d84ca3c123..ace0e61490 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -444,7 +444,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, return GST_FLOW_NOT_SUPPORTED; if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SHARPEN) && - !gst_vaapi_filter_set_denoising_level(postproc->filter, + !gst_vaapi_filter_set_sharpening_level(postproc->filter, postproc->sharpen_level)) return GST_FLOW_NOT_SUPPORTED; From 467bf95c0906098f848a7aa81416c3a16760dad8 Mon Sep 17 00:00:00 2001 From: "Zhao, Halley" Date: Fri, 13 Dec 2013 04:14:41 +0800 Subject: [PATCH 1538/3781] vaapipostproc: add support for colorbalance filters. Add support for hue, saturation, brightness and constrat adjustments. Also fix cap info local copy to match the really expected cap subtype of interest. https://bugzilla.gnome.org/show_bug.cgi?id=720376 Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapifilter.c | 8 +-- gst/vaapi/gstvaapipostproc.c | 96 +++++++++++++++++++++++++++++ gst/vaapi/gstvaapipostproc.h | 6 ++ 3 files changed, 106 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 68aeb8cbcb..c6e02fa07b 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -483,14 +483,14 @@ op_data_ensure_caps(GstVaapiFilterOpData *op_data, gpointer filter_caps, guint num_filter_caps) { guchar *filter_cap = filter_caps; - guint i; + guint i, va_num_caps = num_filter_caps; // Find the VA filter cap matching the op info sub-type if (op_data->va_subtype) { for (i = 0; i < num_filter_caps; i++) { /* XXX: sub-type shall always be the first field */ if (op_data->va_subtype == *(guint *)filter_cap) { - num_filter_caps = 1; + va_num_caps= 1; break; } filter_cap += op_data->va_cap_size; @@ -500,11 +500,11 @@ op_data_ensure_caps(GstVaapiFilterOpData *op_data, gpointer filter_caps, } op_data->va_caps = g_memdup(filter_cap, - op_data->va_cap_size * num_filter_caps); + op_data->va_cap_size * va_num_caps); if (!op_data->va_caps) return FALSE; - op_data->va_num_caps = num_filter_caps; + op_data->va_num_caps = va_num_caps; return TRUE; } diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index ace0e61490..2194252306 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -105,6 +105,10 @@ enum { PROP_DEINTERLACE_METHOD, PROP_DENOISE, PROP_SHARPEN, + PROP_HUE, + PROP_SATURATION, + PROP_BRIGHTNESS, + PROP_CONTRAST, }; #define DEFAULT_FORMAT GST_VIDEO_FORMAT_ENCODED @@ -448,6 +452,26 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, postproc->sharpen_level)) return GST_FLOW_NOT_SUPPORTED; + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_HUE) && + !gst_vaapi_filter_set_hue(postproc->filter, + postproc->hue)) + return GST_FLOW_NOT_SUPPORTED; + + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SATURATION) && + !gst_vaapi_filter_set_saturation(postproc->filter, + postproc->saturation)) + return GST_FLOW_NOT_SUPPORTED; + + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS) && + !gst_vaapi_filter_set_brightness(postproc->filter, + postproc->brightness)) + return GST_FLOW_NOT_SUPPORTED; + + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_CONTRAST) && + !gst_vaapi_filter_set_contrast(postproc->filter, + postproc->contrast)) + return GST_FLOW_NOT_SUPPORTED; + inbuf_meta = gst_buffer_get_vaapi_video_meta(inbuf); if (!inbuf_meta) goto error_invalid_buffer; @@ -1226,6 +1250,22 @@ gst_vaapipostproc_set_property( postproc->sharpen_level = g_value_get_float(value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SHARPEN; break; + case PROP_HUE: + postproc->hue = g_value_get_float(value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_HUE; + break; + case PROP_SATURATION: + postproc->saturation = g_value_get_float(value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SATURATION; + break; + case PROP_BRIGHTNESS: + postproc->brightness = g_value_get_float(value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS; + break; + case PROP_CONTRAST: + postproc->contrast = g_value_get_float(value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CONTRAST; + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1267,6 +1307,18 @@ gst_vaapipostproc_get_property( case PROP_SHARPEN: g_value_set_float(value, postproc->sharpen_level); break; + case PROP_HUE: + g_value_set_float(value, postproc->hue); + break; + case PROP_SATURATION: + g_value_set_float(value, postproc->saturation); + break; + case PROP_BRIGHTNESS: + g_value_set_float(value, postproc->brightness); + break; + case PROP_CONTRAST: + g_value_set_float(value, postproc->contrast); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1435,6 +1487,50 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) g_object_class_install_property(object_class, PROP_SHARPEN, filter_op->pspec); + /** + * GstVaapiPostproc:hue: + * + * The color hue, expressed as a float value. Range is -180.0 to + * 180.0. Default value is 0.0 and represents no modification. + */ + filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_HUE); + if (filter_op) + g_object_class_install_property(object_class, + PROP_HUE, filter_op->pspec); + + /** + * GstVaapiPostproc:saturation: + * + * The color saturation, expressed as a float value. Range is 0.0 + * to 2.0. Default value is 1.0 and represents no modification. + */ + filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_SATURATION); + if (filter_op) + g_object_class_install_property(object_class, + PROP_SATURATION, filter_op->pspec); + + /** + * GstVaapiPostproc:brightness: + * + * The color brightness, expressed as a float value. Range is -1.0 + * to 1.0. Default value is 0.0 and represents no modification. + */ + filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_BRIGHTNESS); + if (filter_op) + g_object_class_install_property(object_class, + PROP_BRIGHTNESS, filter_op->pspec); + + /** + * GstVaapiPostproc:contrast: + * + * The color contrast, expressed as a float value. Range is 0.0 to + * 2.0. Default value is 1.0 and represents no modification. + */ + filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_CONTRAST); + if (filter_op) + g_object_class_install_property(object_class, + PROP_CONTRAST, filter_op->pspec); + g_ptr_array_unref(filter_ops); } diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 93b4495d4d..7159b53375 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -160,6 +160,12 @@ struct _GstVaapiPostproc { gfloat denoise_level; gfloat sharpen_level; + /* Color balance filter values */ + gfloat hue; + gfloat saturation; + gfloat brightness; + gfloat contrast; + guint is_raw_yuv : 1; guint use_vpp : 1; guint keep_aspect : 1; From 751aa05937d736503fce22ba784820f7184f0b40 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 28 Mar 2012 15:05:26 +0200 Subject: [PATCH 1539/3781] surface: rework render flags. Pack render flags per category and provide more flags into the color standard category. In particular, cover for SMPTE-240M. --- gst-libs/gst/vaapi/gstvaapisurface.h | 31 ++++++++++++++++------- gst-libs/gst/vaapi/gstvaapiutils.c | 38 ++++++++++++++++++++-------- gst/vaapi/gstvaapipostproc.c | 6 ++--- 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 639ed2ac6b..5ddfd0116c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -110,19 +110,32 @@ typedef enum { * uses ITU-R BT.601 standard for color space conversion * @GST_VAAPI_COLOR_STANDARD_ITUR_BT_709: * uses ITU-R BT.709 standard for color space conversion + * @GST_VAAPI_COLOR_STANDARD_ITUR_BT_470M: + * uses ITU-R BT.470-2 System M standard for color space conversion + * @GST_VAAPI_COLOR_STANDARD_ITUR_BT_470BG: + * uses ITU-R BT.470-2 System B, G standard for color space conversion + * @GST_VAAPI_COLOR_STANDARD_SMPTE_170M: + * uses SMPTE-170M standard for color space conversion + * @GST_VAAPI_COLOR_STANDARD_SMPTE_240M: + * uses SMPTE-240M standard for color space conversion * * The set of all render flags for gst_vaapi_window_put_surface(). */ typedef enum { - GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD = 1 << 0, - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD = 1 << 1, - GST_VAAPI_PICTURE_STRUCTURE_FRAME = - ( - GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD | - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD - ), - GST_VAAPI_COLOR_STANDARD_ITUR_BT_601 = 1 << 2, - GST_VAAPI_COLOR_STANDARD_ITUR_BT_709 = 1 << 3, + /* Picture structure */ + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD = 0x01 << 0, + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD = 0x02 << 0, + GST_VAAPI_PICTURE_STRUCTURE_FRAME = 0x03 << 0, + GST_VAAPI_PICTURE_STRUCTURE_MASK = 0x00000003, /* 2 bits */ + + /* Color standard */ + GST_VAAPI_COLOR_STANDARD_ITUR_BT_601 = 0x01 << 2, + GST_VAAPI_COLOR_STANDARD_ITUR_BT_709 = 0x02 << 2, + GST_VAAPI_COLOR_STANDARD_ITUR_BT_470M = 0x03 << 2, + GST_VAAPI_COLOR_STANDARD_ITUR_BT_470BG = 0x04 << 2, + GST_VAAPI_COLOR_STANDARD_SMPTE_170M = 0x05 << 2, + GST_VAAPI_COLOR_STANDARD_SMPTE_240M = 0x06 << 2, + GST_VAAPI_COLOR_STANDARD_MASK = 0x0000003c, /* 4 bits */ } GstVaapiSurfaceRenderFlags; #define GST_VAAPI_SURFACE(obj) \ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 90510e51de..daa9fc28b2 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -366,24 +366,42 @@ to_GstVideoOverlayFormatFlags(guint flags) guint from_GstVaapiSurfaceRenderFlags(guint flags) { - guint va_fields = 0, va_csc = 0; + guint va_fields, va_csc; - if (flags & GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) - va_fields |= VA_TOP_FIELD; - if (flags & GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) - va_fields |= VA_BOTTOM_FIELD; - if ((va_fields ^ (VA_TOP_FIELD|VA_BOTTOM_FIELD)) == 0) - va_fields = VA_FRAME_PICTURE; + /* Picture structure */ + switch (flags & GST_VAAPI_PICTURE_STRUCTURE_MASK) { + case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: + va_fields = VA_TOP_FIELD; + break; + case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: + va_fields = VA_BOTTOM_FIELD; + break; + default: + va_fields = VA_FRAME_PICTURE; + break; + } + /* Color standard */ + switch (flags & GST_VAAPI_COLOR_STANDARD_MASK) { #ifdef VA_SRC_BT601 - if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_601) + case GST_VAAPI_COLOR_STANDARD_ITUR_BT_601: va_csc = VA_SRC_BT601; + break; #endif #ifdef VA_SRC_BT709 - if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_709) + case GST_VAAPI_COLOR_STANDARD_ITUR_BT_709: va_csc = VA_SRC_BT709; + break; #endif - +#ifdef VA_SRC_SMPTE_240 + case GST_VAAPI_COLOR_STANDARD_SMPTE_240M: + va_csc = VA_SRC_SMPTE_240; + break; +#endif + default: + va_csc = 0; + break; + } return va_fields|va_csc; } diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 2194252306..6abcfb88c0 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -489,8 +489,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, ds->tff = tff; flags = gst_vaapi_video_meta_get_render_flags(inbuf_meta) & - ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); + ~GST_VAAPI_PICTURE_STRUCTURE_MASK; /* First field */ deint_method = postproc->deinterlace_method; @@ -652,8 +651,7 @@ gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf, deint = is_interlaced_buffer(postproc, inbuf); flags = gst_vaapi_video_meta_get_render_flags(meta) & - ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD); + ~GST_VAAPI_PICTURE_STRUCTURE_MASK; /* First field */ fieldbuf = create_output_buffer(postproc); From b1d3f7d4c0f3be8ec1f82aa00516596cafb7a0a2 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Wed, 15 Jan 2014 12:09:14 +0100 Subject: [PATCH 1540/3781] vaapisink: set csc render flags from sinkpad caps. This maps GstVideoColorimetry information in vaapisink's sinkpad caps to GST_VAAPI_COLOR_STANDARD_* flags, if per-buffer information was not available. https://bugzilla.gnome.org/show_bug.cgi?id=722255 [factored out code, added SMPTE240M, handle per-buffer flags] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 26 ++++++++++++++++++++++++++ gst/vaapi/gstvaapisink.h | 1 + 2 files changed, 27 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 9c5ecd2a43..36c35bd894 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -674,6 +674,26 @@ gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter) #define gst_vaapisink_get_caps gst_vaapisink_get_caps_impl #endif +static void +update_colorimetry(GstVaapiSink *sink, GstVideoColorimetry *cinfo) +{ +#if GST_CHECK_VERSION(1,0,0) + if (gst_video_colorimetry_matches(cinfo, + GST_VIDEO_COLORIMETRY_BT601)) + sink->color_standard = GST_VAAPI_COLOR_STANDARD_ITUR_BT_601; + else if (gst_video_colorimetry_matches(cinfo, + GST_VIDEO_COLORIMETRY_BT709)) + sink->color_standard = GST_VAAPI_COLOR_STANDARD_ITUR_BT_709; + else if (gst_video_colorimetry_matches(cinfo, + GST_VIDEO_COLORIMETRY_SMPTE240M)) + sink->color_standard = GST_VAAPI_COLOR_STANDARD_SMPTE_240M; + else + sink->color_standard = 0; + + GST_DEBUG("colorimetry %s", gst_video_colorimetry_to_string(cinfo)); +#endif +} + static gboolean gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { @@ -702,6 +722,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) GST_DEBUG("video pixel-aspect-ratio %d/%d", sink->video_par_n, sink->video_par_d); + update_colorimetry(sink, &vip->colorimetry); gst_caps_replace(&sink->caps, caps); gst_vaapisink_ensure_rotation(sink, FALSE); @@ -1006,6 +1027,11 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) flags = gst_vaapi_video_meta_get_render_flags(meta); + /* Append default color standard obtained from caps if none was + available on a per-buffer basis */ + if (!(flags & GST_VAAPI_COLOR_STANDARD_MASK)) + flags |= sink->color_standard; + if (!gst_vaapi_apply_composition(surface, src_buffer)) GST_WARNING("could not update subtitles"); diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index bcabe089ec..832689e3d4 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -86,6 +86,7 @@ struct _GstVaapiSink { GstVaapiRectangle display_rect; GstVaapiRotation rotation; GstVaapiRotation rotation_req; + guint color_standard; guint foreign_window : 1; guint fullscreen : 1; guint synchronous : 1; From 5f5df3f723a6ea4314e539c41e22c82da70b53e4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 15 Jan 2014 15:10:48 +0100 Subject: [PATCH 1541/3781] encoder: h264: really fix frame cropping rectangle calculation. Make frame cropping rectangle calculation future proof, i.e. exactly follow the specification (7-18) to (7-21), and subsampling definitions from Table 6-1. https://bugzilla.gnome.org/show_bug.cgi?id=722089 https://bugzilla.gnome.org/show_bug.cgi?id=722238 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 63385226ca..d4aafa1eaf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -995,14 +995,23 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder, /* frame_cropping_flag */ if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) || (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) { + static const guint SubWidthC[] = { 1, 2, 2, 1 }; + static const guint SubHeightC[] = { 1, 2, 1, 1 }; + const guint CropUnitX = + SubWidthC[seq_param->seq_fields.bits.chroma_format_idc]; + const guint CropUnitY = + SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] * + (2 - seq_param->seq_fields.bits.frame_mbs_only_flag); + seq_param->frame_cropping_flag = 1; seq_param->frame_crop_left_offset = 0; seq_param->frame_crop_right_offset = - 16 * encoder->mb_width - GST_VAAPI_ENCODER_WIDTH (encoder); + (16 * encoder->mb_width - + GST_VAAPI_ENCODER_WIDTH (encoder)) / CropUnitX; seq_param->frame_crop_top_offset = 0; seq_param->frame_crop_bottom_offset = - (16 * encoder->mb_height - GST_VAAPI_ENCODER_HEIGHT (encoder)) / - (2 - seq_param->seq_fields.bits.frame_mbs_only_flag); + (16 * encoder->mb_height - + GST_VAAPI_ENCODER_HEIGHT (encoder)) / CropUnitY; } /* vui not set */ From 391ad15ba0a056d6acb11d76f6166b19c6e950b2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 15 Jan 2014 15:46:19 +0100 Subject: [PATCH 1542/3781] encoder: h264: always emit VUI parameters for framerate. Always emit VUI parameters for timing_info, which includes framerate information. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index d4aafa1eaf..cfa6547861 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1014,14 +1014,12 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder, GST_VAAPI_ENCODER_HEIGHT (encoder)) / CropUnitY; } - /* vui not set */ - seq_param->vui_parameters_present_flag = - (base_encoder->bitrate > 0 ? TRUE : FALSE); + /* VUI parameters are always set, at least for timing_info (framerate) */ + seq_param->vui_parameters_present_flag = TRUE; if (seq_param->vui_parameters_present_flag) { seq_param->vui_fields.bits.aspect_ratio_info_present_flag = FALSE; seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE; - seq_param->vui_fields.bits.timing_info_present_flag = - (base_encoder->bitrate > 0 ? TRUE : FALSE); + seq_param->vui_fields.bits.timing_info_present_flag = TRUE; if (seq_param->vui_fields.bits.timing_info_present_flag) { seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder); seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2; From 7e6f7f384a8c0c16219414403490e9148060aa5b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 15 Jan 2014 15:54:32 +0100 Subject: [PATCH 1543/3781] encoder: h264: fix PPS header packing with profile < high. Fix PPS header packing when profile is below High since 8x8 transform mode and scaling lists are High Profile features. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 38 ++++++++++++----------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index cfa6547861..ffbd485af2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -701,7 +701,7 @@ gst_bit_writer_write_sps (GstBitWriter * bitwriter, static gboolean gst_bit_writer_write_pps (GstBitWriter * bitwriter, - const VAEncPictureParameterBufferH264 * pic_param) + const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile) { guint32 num_slice_groups_minus1 = 0; guint32 pic_init_qs_minus26 = 0; @@ -743,25 +743,27 @@ gst_bit_writer_write_pps (GstBitWriter * bitwriter, gst_bit_writer_put_bits_uint32 (bitwriter, redundant_pic_cnt_present_flag, 1); /* more_rbsp_data */ - gst_bit_writer_put_bits_uint32 (bitwriter, - pic_param->pic_fields.bits.transform_8x8_mode_flag, 1); - gst_bit_writer_put_bits_uint32 (bitwriter, - pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1); - if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) { - g_assert (0); - /* FIXME */ - /* - for (i = 0; i < - (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag)); - i++) { - gst_bit_writer_put_bits_uint8(bitwriter, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1); - } - */ + if (profile == GST_VAAPI_PROFILE_H264_HIGH) { + gst_bit_writer_put_bits_uint32 (bitwriter, + pic_param->pic_fields.bits.transform_8x8_mode_flag, 1); + gst_bit_writer_put_bits_uint32 (bitwriter, + pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1); + if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) { + g_assert (0 && "unsupported scaling lists"); + /* FIXME */ + /* + for (i = 0; i < + (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag)); + i++) { + gst_bit_writer_put_bits_uint8(bitwriter, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1); + } + */ + } + gst_bit_writer_put_se (bitwriter, pic_param->second_chroma_qp_index_offset); } - gst_bit_writer_put_se (bitwriter, pic_param->second_chroma_qp_index_offset); + /* rbsp_trailing_bits */ gst_bit_writer_write_trailing_bits (bitwriter); - return TRUE; } @@ -819,7 +821,7 @@ add_picture_packed_header (GstVaapiEncoderH264 * encoder, gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */ gst_bit_writer_write_nal_header (&writer, GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_PPS); - gst_bit_writer_write_pps (&writer, pic_param); + gst_bit_writer_write_pps (&writer, pic_param, encoder->profile); g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer); data = GST_BIT_WRITER_DATA (&writer); From 8e6216416088dac68ed2f17b9f6ea6644ef5b0ee Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 21 Jan 2014 15:23:01 +0100 Subject: [PATCH 1544/3781] encoder: h264: completely remove private headers. Drop private header since it was originally used to expose internals to the plugin element. The proper interface is now the properties API, thus rendering private headers totally obsolete. --- gst-libs/gst/vaapi/Makefile.am | 1 - gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 82 ++++++++++++++---- .../gst/vaapi/gstvaapiencoder_h264_priv.h | 83 ------------------- 3 files changed, 66 insertions(+), 100 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 5fccc9316e..390d91eb92 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -162,7 +162,6 @@ libgstvaapi_enc_source_h = \ libgstvaapi_enc_source_priv_h = \ gstvaapicodedbuffer_priv.h \ gstvaapicodedbufferproxy_priv.h \ - gstvaapiencoder_h264_priv.h \ gstvaapiencoder_mpeg2_priv.h \ gstvaapiencoder_objects.h \ gstvaapiencoder_priv.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index ffbd485af2..b43c9092df 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -24,8 +24,9 @@ #include #include #include "gstvaapicompat.h" +#include "gstvaapiencoder_priv.h" #include "gstvaapiencoder_h264.h" -#include "gstvaapiencoder_h264_priv.h" +#include "gstvaapiutils_h264.h" #include "gstvaapiutils_h264_priv.h" #include "gstvaapicodedbufferproxy_priv.h" #include "gstvaapisurface.h" @@ -33,6 +34,9 @@ #define DEBUG 1 #include "gstvaapidebug.h" +/* Define the maximum IDR period */ +#define MAX_IDR_PERIOD 512 + /* Define default rate control mode ("constant-qp") */ #define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP @@ -64,13 +68,6 @@ typedef enum GST_VAAPI_ENCODER_H264_NAL_PPS = 8 } GstVaapiEncoderH264NalType; -typedef enum -{ - SLICE_TYPE_P = 0, - SLICE_TYPE_B = 1, - SLICE_TYPE_I = 2 -} H264_SLICE_TYPE; - typedef struct { GstVaapiSurfaceProxy *pic; @@ -126,6 +123,59 @@ h264_get_log2_max_frame_num (guint num) return ret; } +/* ------------------------------------------------------------------------- */ +/* --- H.264 Encoder --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENCODER_H264_CAST(encoder) \ + ((GstVaapiEncoderH264 *)(encoder)) + +struct _GstVaapiEncoderH264 +{ + GstVaapiEncoder parent_instance; + + GstVaapiProfile profile; + GstVaapiLevelH264 level; + guint8 profile_idc; + guint8 max_profile_idc; + guint8 hw_max_profile_idc; + guint8 level_idc; + guint32 idr_period; + guint32 init_qp; + guint32 min_qp; + guint32 num_slices; + guint32 num_bframes; + guint32 mb_width; + guint32 mb_height; + gboolean use_cabac; + gboolean use_dct8x8; + + /* re-ordering */ + GQueue reorder_frame_list; + guint reorder_state; + guint frame_index; + guint cur_frame_num; + guint cur_present_index; + GstClockTime cts_offset; + + /* reference list */ + GQueue ref_list; + guint max_ref_frames; + /* max reflist count */ + guint max_reflist0_count; + guint max_reflist1_count; + + /* frame, poc */ + guint32 max_frame_num; + guint32 log2_max_frame_num; + guint32 max_pic_order_cnt; + guint32 log2_max_pic_order_cnt; + guint32 idr_num; + + GstBuffer *sps_data; + GstBuffer *pps_data; +}; + static inline void _check_sps_pps_status (GstVaapiEncoderH264 * encoder, const guint8 * nal, guint32 size) @@ -752,12 +802,12 @@ gst_bit_writer_write_pps (GstBitWriter * bitwriter, g_assert (0 && "unsupported scaling lists"); /* FIXME */ /* - for (i = 0; i < - (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag)); - i++) { - gst_bit_writer_put_bits_uint8(bitwriter, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1); - } - */ + for (i = 0; i < + (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag)); + i++) { + gst_bit_writer_put_bits_uint8(bitwriter, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1); + } + */ } gst_bit_writer_put_se (bitwriter, pic_param->second_chroma_qp_index_offset); } @@ -1411,8 +1461,8 @@ reset_properties (GstVaapiEncoderH264 * encoder) if (encoder->idr_period < base_encoder->keyframe_period) encoder->idr_period = base_encoder->keyframe_period; - if (encoder->idr_period > GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD) - encoder->idr_period = GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD; + if (encoder->idr_period > MAX_IDR_PERIOD) + encoder->idr_period = MAX_IDR_PERIOD; if (encoder->min_qp > encoder->init_qp || (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP && diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h deleted file mode 100644 index ea65456e59..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * gstvaapiencoder_h264_priv.h - H.264 encoder (private definitions) - * - * Copyright (C) 2013 Intel Corporation - * - * 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_PRIV_H -#define GST_VAAPI_ENCODER_H264_PRIV_H - -#include "gstvaapiencoder_priv.h" -#include "gstvaapiutils_h264.h" - -G_BEGIN_DECLS - -#define GST_VAAPI_ENCODER_H264_CAST(encoder) \ - ((GstVaapiEncoderH264 *)(encoder)) - -#define GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD 512 - -struct _GstVaapiEncoderH264 -{ - GstVaapiEncoder parent_instance; - - GstVaapiProfile profile; - GstVaapiLevelH264 level; - guint8 profile_idc; - guint8 max_profile_idc; - guint8 hw_max_profile_idc; - guint8 level_idc; - guint32 idr_period; - guint32 init_qp; - guint32 min_qp; - guint32 num_slices; - guint32 num_bframes; - guint32 mb_width; - guint32 mb_height; - gboolean use_cabac; - gboolean use_dct8x8; - - /* re-ordering */ - GQueue reorder_frame_list; - guint reorder_state; - guint frame_index; - guint cur_frame_num; - guint cur_present_index; - GstClockTime cts_offset; - - /* reference list */ - GQueue ref_list; - guint max_ref_frames; - /* max reflist count */ - guint max_reflist0_count; - guint max_reflist1_count; - - /* frame, poc */ - guint32 max_frame_num; - guint32 log2_max_frame_num; - guint32 max_pic_order_cnt; - guint32 log2_max_pic_order_cnt; - guint32 idr_num; - - GstBuffer *sps_data; - GstBuffer *pps_data; -}; - -G_END_DECLS - -#endif /* GST_VAAPI_ENCODER_H264_PRIV_H */ From c48e769e08a2edcfabce7619511f6bbaebd2f7d5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 21 Jan 2014 15:28:34 +0100 Subject: [PATCH 1545/3781] encoder: h264: clean-up bitwriter related utilities. Clean-up GstBitWriter related utility functions and simplify notations. While we are at it, also make bitstream writing more robust should an overflow occur. We could later optimize for writing headers capped to their maximum possible size by using the _unchecked() helper variants. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 828 ++++++++++++---------- 1 file changed, 443 insertions(+), 385 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index b43c9092df..eb037c40f3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -123,6 +123,387 @@ h264_get_log2_max_frame_num (guint num) return ret; } +/* ------------------------------------------------------------------------- */ +/* --- H.264 Bitstream Writer --- */ +/* ------------------------------------------------------------------------- */ + +#define WRITE_UINT32(bs, val, nbits) do { \ + if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \ + GST_WARNING ("failed to write uint32, nbits: %d", nbits); \ + goto bs_error; \ + } \ + } while (0) + +#define WRITE_UE(bs, val) do { \ + if (!bs_write_ue (bs, val)) { \ + GST_WARNING ("failed to write ue(v)"); \ + goto bs_error; \ + } \ + } while (0) + +#define WRITE_SE(bs, val) do { \ + if (!bs_write_se (bs, val)) { \ + GST_WARNING ("failed to write se(v)"); \ + goto bs_error; \ + } \ + } while (0) + +/* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */ +static gboolean +bs_write_ue (GstBitWriter * bs, guint32 value) +{ + guint32 size_in_bits = 0; + guint32 tmp_value = ++value; + + while (tmp_value) { + ++size_in_bits; + tmp_value >>= 1; + } + if (size_in_bits > 1 + && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1)) + return FALSE; + if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits)) + return FALSE; + return TRUE; +} + +/* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */ +static gboolean +bs_write_se (GstBitWriter * bs, gint32 value) +{ + guint32 new_val; + + if (value <= 0) + new_val = -(value << 1); + else + new_val = (value << 1) - 1; + + if (!bs_write_ue (bs, new_val)) + return FALSE; + return TRUE; +} + +/* Write the NAL unit header */ +static gboolean +bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc, + guint32 nal_unit_type) +{ + WRITE_UINT32 (bs, 0, 1); + WRITE_UINT32 (bs, nal_ref_idc, 2); + WRITE_UINT32 (bs, nal_unit_type, 5); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write NAL unit header"); + return FALSE; + } +} + +/* Write the NAL unit trailing bits */ +static gboolean +bs_write_trailing_bits (GstBitWriter * bs) +{ + if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1)) + goto bs_error; + gst_bit_writer_align_bytes_unchecked (bs, 0); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write NAL unit trailing bits"); + return FALSE; + } +} + +/* Write an SPS NAL unit */ +static gboolean +bs_write_sps (GstBitWriter * bs, + const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile) +{ + guint8 profile_idc; + guint32 constraint_set0_flag, constraint_set1_flag; + guint32 constraint_set2_flag, constraint_set3_flag; + guint32 gaps_in_frame_num_value_allowed_flag = 0; // ?? + gboolean nal_hrd_parameters_present_flag; + + guint32 b_qpprime_y_zero_transform_bypass = 0; + guint32 residual_color_transform_flag = 0; + guint32 pic_height_in_map_units = + (seq_param->seq_fields.bits.frame_mbs_only_flag ? + seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2); + guint32 mb_adaptive_frame_field = + !seq_param->seq_fields.bits.frame_mbs_only_flag; + guint32 i = 0; + + profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + constraint_set0_flag = /* A.2.1 (baseline profile constraints) */ + profile == GST_VAAPI_PROFILE_H264_BASELINE || + profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + constraint_set1_flag = /* A.2.2 (main profile constraints) */ + profile == GST_VAAPI_PROFILE_H264_MAIN || + profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + constraint_set2_flag = 0; + constraint_set3_flag = 0; + + /* profile_idc */ + WRITE_UINT32 (bs, profile_idc, 8); + /* constraint_set0_flag */ + WRITE_UINT32 (bs, constraint_set0_flag, 1); + /* constraint_set1_flag */ + WRITE_UINT32 (bs, constraint_set1_flag, 1); + /* constraint_set2_flag */ + WRITE_UINT32 (bs, constraint_set2_flag, 1); + /* constraint_set3_flag */ + WRITE_UINT32 (bs, constraint_set3_flag, 1); + /* reserved_zero_4bits */ + WRITE_UINT32 (bs, 0, 4); + /* level_idc */ + WRITE_UINT32 (bs, seq_param->level_idc, 8); + /* seq_parameter_set_id */ + WRITE_UE (bs, seq_param->seq_parameter_set_id); + + if (profile == GST_VAAPI_PROFILE_H264_HIGH) { + /* for high profile */ + /* chroma_format_idc = 1, 4:2:0 */ + WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc); + if (3 == seq_param->seq_fields.bits.chroma_format_idc) { + WRITE_UINT32 (bs, residual_color_transform_flag, 1); + } + /* bit_depth_luma_minus8 */ + WRITE_UE (bs, seq_param->bit_depth_luma_minus8); + /* bit_depth_chroma_minus8 */ + WRITE_UE (bs, seq_param->bit_depth_chroma_minus8); + /* b_qpprime_y_zero_transform_bypass */ + WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1); + g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0); + /* seq_scaling_matrix_present_flag */ + WRITE_UINT32 (bs, + seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1); + +#if 0 + if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) { + for (i = 0; + i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); + i++) { + gst_bit_writer_put_bits_uint8 (bs, + seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1); + if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) { + g_assert (0); + /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */ + } + } + } +#endif + } + + /* log2_max_frame_num_minus4 */ + WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4); + /* pic_order_cnt_type */ + WRITE_UE (bs, seq_param->seq_fields.bits.pic_order_cnt_type); + + if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) { + /* log2_max_pic_order_cnt_lsb_minus4 */ + WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4); + } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { + g_assert (0); + WRITE_UINT32 (bs, + seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1); + WRITE_SE (bs, seq_param->offset_for_non_ref_pic); + WRITE_SE (bs, seq_param->offset_for_top_to_bottom_field); + WRITE_UE (bs, seq_param->num_ref_frames_in_pic_order_cnt_cycle); + for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) { + WRITE_SE (bs, seq_param->offset_for_ref_frame[i]); + } + } + + /* num_ref_frames */ + WRITE_UE (bs, seq_param->max_num_ref_frames); + /* gaps_in_frame_num_value_allowed_flag */ + WRITE_UINT32 (bs, gaps_in_frame_num_value_allowed_flag, 1); + + /* pic_width_in_mbs_minus1 */ + WRITE_UE (bs, seq_param->picture_width_in_mbs - 1); + /* pic_height_in_map_units_minus1 */ + WRITE_UE (bs, pic_height_in_map_units - 1); + /* frame_mbs_only_flag */ + WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1); + + if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs + g_assert (0); + WRITE_UINT32 (bs, mb_adaptive_frame_field, 1); + } + + /* direct_8x8_inference_flag */ + WRITE_UINT32 (bs, 0, 1); + /* frame_cropping_flag */ + WRITE_UINT32 (bs, seq_param->frame_cropping_flag, 1); + + if (seq_param->frame_cropping_flag) { + /* frame_crop_left_offset */ + WRITE_UE (bs, seq_param->frame_crop_left_offset); + /* frame_crop_right_offset */ + WRITE_UE (bs, seq_param->frame_crop_right_offset); + /* frame_crop_top_offset */ + WRITE_UE (bs, seq_param->frame_crop_top_offset); + /* frame_crop_bottom_offset */ + WRITE_UE (bs, seq_param->frame_crop_bottom_offset); + } + + /* vui_parameters_present_flag */ + WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1); + if (seq_param->vui_parameters_present_flag) { + /* aspect_ratio_info_present_flag */ + WRITE_UINT32 (bs, + seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1); + if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { + WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8); + if (seq_param->aspect_ratio_idc == 0xFF) { + WRITE_UINT32 (bs, seq_param->sar_width, 16); + WRITE_UINT32 (bs, seq_param->sar_height, 16); + } + } + + /* overscan_info_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* video_signal_type_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* chroma_loc_info_present_flag */ + WRITE_UINT32 (bs, 0, 1); + + /* timing_info_present_flag */ + WRITE_UINT32 (bs, seq_param->vui_fields.bits.timing_info_present_flag, 1); + if (seq_param->vui_fields.bits.timing_info_present_flag) { + WRITE_UINT32 (bs, seq_param->num_units_in_tick, 32); + WRITE_UINT32 (bs, seq_param->time_scale, 32); + WRITE_UINT32 (bs, 1, 1); /* fixed_frame_rate_flag */ + } + + nal_hrd_parameters_present_flag = + (seq_param->bits_per_second > 0 ? TRUE : FALSE); + /* nal_hrd_parameters_present_flag */ + WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1); + if (nal_hrd_parameters_present_flag) { + /* hrd_parameters */ + /* cpb_cnt_minus1 */ + WRITE_UE (bs, 0); + WRITE_UINT32 (bs, 4, 4); /* bit_rate_scale */ + WRITE_UINT32 (bs, 6, 4); /* cpb_size_scale */ + + for (i = 0; i < 1; ++i) { + /* bit_rate_value_minus1[0] */ + WRITE_UE (bs, seq_param->bits_per_second / 1000 - 1); + /* cpb_size_value_minus1[0] */ + WRITE_UE (bs, seq_param->bits_per_second / 1000 * 8 - 1); + /* cbr_flag[0] */ + WRITE_UINT32 (bs, 1, 1); + } + /* initial_cpb_removal_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + /* cpb_removal_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + /* dpb_output_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + /* time_offset_length */ + WRITE_UINT32 (bs, 23, 5); + } + /* vcl_hrd_parameters_present_flag */ + WRITE_UINT32 (bs, 0, 1); + if (nal_hrd_parameters_present_flag + || 0 /*vcl_hrd_parameters_present_flag */ ) { + /* low_delay_hrd_flag */ + WRITE_UINT32 (bs, 0, 1); + } + /* pic_struct_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* bs_restriction_flag */ + WRITE_UINT32 (bs, 0, 1); + } + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SPS NAL unit"); + return FALSE; + } +} + +/* Write a PPS NAL unit */ +static gboolean +bs_write_pps (GstBitWriter * bs, + const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile) +{ + guint32 num_slice_groups_minus1 = 0; + guint32 pic_init_qs_minus26 = 0; + guint32 redundant_pic_cnt_present_flag = 0; + + /* pic_parameter_set_id */ + WRITE_UE (bs, pic_param->pic_parameter_set_id); + /* seq_parameter_set_id */ + WRITE_UE (bs, pic_param->seq_parameter_set_id); + /* entropy_coding_mode_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1); + /* pic_order_present_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_order_present_flag, 1); + /* slice_groups-1 */ + WRITE_UE (bs, num_slice_groups_minus1); + + if (num_slice_groups_minus1 > 0) { + /*FIXME*/ g_assert (0); + } + WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1); + WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1); + WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1); + WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2); + /* pic_init_qp_minus26 */ + WRITE_SE (bs, pic_param->pic_init_qp - 26); + /* pic_init_qs_minus26 */ + WRITE_SE (bs, pic_init_qs_minus26); + /* chroma_qp_index_offset */ + WRITE_SE (bs, pic_param->chroma_qp_index_offset); + + WRITE_UINT32 (bs, + pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1); + WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1); + WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1); + + /* more_rbsp_data */ + if (profile == GST_VAAPI_PROFILE_H264_HIGH) { + WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1); + WRITE_UINT32 (bs, + pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1); + if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) { + g_assert (0 && "unsupported scaling lists"); + /* FIXME */ + /* + for (i = 0; i < + (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag)); + i++) { + gst_bit_writer_put_bits_uint8(bs, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1); + } + */ + } + WRITE_SE (bs, pic_param->second_chroma_qp_index_offset); + } + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write PPS NAL unit"); + return FALSE; + } +} + /* ------------------------------------------------------------------------- */ /* --- H.264 Encoder --- */ /* ------------------------------------------------------------------------- */ @@ -472,370 +853,25 @@ _set_key_frame (GstVaapiEncPicture * picture, _set_i_frame (picture, encoder); } -gboolean -gst_bit_writer_put_ue (GstBitWriter * bitwriter, guint32 value) -{ - guint32 size_in_bits = 0; - guint32 tmp_value = ++value; - - while (tmp_value) { - ++size_in_bits; - tmp_value >>= 1; - } - if (size_in_bits > 1 - && !gst_bit_writer_put_bits_uint32 (bitwriter, 0, size_in_bits - 1)) - return FALSE; - if (!gst_bit_writer_put_bits_uint32 (bitwriter, value, size_in_bits)) - return FALSE; - return TRUE; -} - -gboolean -gst_bit_writer_put_se (GstBitWriter * bitwriter, gint32 value) -{ - guint32 new_val; - - if (value <= 0) - new_val = -(value << 1); - else - new_val = (value << 1) - 1; - - if (!gst_bit_writer_put_ue (bitwriter, new_val)) - return FALSE; - return TRUE; -} - - -static gboolean -gst_bit_writer_write_nal_header (GstBitWriter * bitwriter, - guint32 nal_ref_idc, guint32 nal_unit_type) -{ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); - gst_bit_writer_put_bits_uint32 (bitwriter, nal_ref_idc, 2); - gst_bit_writer_put_bits_uint32 (bitwriter, nal_unit_type, 5); - return TRUE; -} - -static gboolean -gst_bit_writer_write_trailing_bits (GstBitWriter * bitwriter) -{ - gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); - gst_bit_writer_align_bytes_unchecked (bitwriter, 0); - return TRUE; -} - -static gboolean -gst_bit_writer_write_sps (GstBitWriter * bitwriter, - const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile) -{ - guint8 profile_idc; - guint32 constraint_set0_flag, constraint_set1_flag; - guint32 constraint_set2_flag, constraint_set3_flag; - guint32 gaps_in_frame_num_value_allowed_flag = 0; // ?? - gboolean nal_hrd_parameters_present_flag; - - guint32 b_qpprime_y_zero_transform_bypass = 0; - guint32 residual_color_transform_flag = 0; - guint32 pic_height_in_map_units = - (seq_param->seq_fields.bits.frame_mbs_only_flag ? - seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2); - guint32 mb_adaptive_frame_field = - !seq_param->seq_fields.bits.frame_mbs_only_flag; - guint32 i = 0; - - profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); - constraint_set0_flag = /* A.2.1 (baseline profile constraints) */ - profile == GST_VAAPI_PROFILE_H264_BASELINE || - profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; - constraint_set1_flag = /* A.2.2 (main profile constraints) */ - profile == GST_VAAPI_PROFILE_H264_MAIN || - profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; - constraint_set2_flag = 0; - constraint_set3_flag = 0; - - /* profile_idc */ - gst_bit_writer_put_bits_uint32 (bitwriter, profile_idc, 8); - /* constraint_set0_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set0_flag, 1); - /* constraint_set1_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set1_flag, 1); - /* constraint_set2_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set2_flag, 1); - /* constraint_set3_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set3_flag, 1); - /* reserved_zero_4bits */ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 4); - /* level_idc */ - gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->level_idc, 8); - /* seq_parameter_set_id */ - gst_bit_writer_put_ue (bitwriter, seq_param->seq_parameter_set_id); - - if (profile == GST_VAAPI_PROFILE_H264_HIGH) { - /* for high profile */ - /* chroma_format_idc = 1, 4:2:0 */ - gst_bit_writer_put_ue (bitwriter, - seq_param->seq_fields.bits.chroma_format_idc); - if (3 == seq_param->seq_fields.bits.chroma_format_idc) { - gst_bit_writer_put_bits_uint32 (bitwriter, residual_color_transform_flag, - 1); - } - /* bit_depth_luma_minus8 */ - gst_bit_writer_put_ue (bitwriter, seq_param->bit_depth_luma_minus8); - /* bit_depth_chroma_minus8 */ - gst_bit_writer_put_ue (bitwriter, seq_param->bit_depth_chroma_minus8); - /* b_qpprime_y_zero_transform_bypass */ - gst_bit_writer_put_bits_uint32 (bitwriter, - b_qpprime_y_zero_transform_bypass, 1); - g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0); - /* seq_scaling_matrix_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, - seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1); - -#if 0 - if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) { - for (i = 0; - i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); - i++) { - gst_bit_writer_put_bits_uint8 (bitwriter, - seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1); - if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) { - g_assert (0); - /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */ - } - } - } -#endif - } - - /* log2_max_frame_num_minus4 */ - gst_bit_writer_put_ue (bitwriter, - seq_param->seq_fields.bits.log2_max_frame_num_minus4); - /* pic_order_cnt_type */ - gst_bit_writer_put_ue (bitwriter, - seq_param->seq_fields.bits.pic_order_cnt_type); - - if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) { - /* log2_max_pic_order_cnt_lsb_minus4 */ - gst_bit_writer_put_ue (bitwriter, - seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4); - } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { - g_assert (0); - gst_bit_writer_put_bits_uint32 (bitwriter, - seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1); - gst_bit_writer_put_se (bitwriter, seq_param->offset_for_non_ref_pic); - gst_bit_writer_put_se (bitwriter, - seq_param->offset_for_top_to_bottom_field); - gst_bit_writer_put_ue (bitwriter, - seq_param->num_ref_frames_in_pic_order_cnt_cycle); - for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) { - gst_bit_writer_put_se (bitwriter, seq_param->offset_for_ref_frame[i]); - } - } - - /* num_ref_frames */ - gst_bit_writer_put_ue (bitwriter, seq_param->max_num_ref_frames); - /* gaps_in_frame_num_value_allowed_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, - gaps_in_frame_num_value_allowed_flag, 1); - - /* pic_width_in_mbs_minus1 */ - gst_bit_writer_put_ue (bitwriter, seq_param->picture_width_in_mbs - 1); - /* pic_height_in_map_units_minus1 */ - gst_bit_writer_put_ue (bitwriter, pic_height_in_map_units - 1); - /* frame_mbs_only_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, - seq_param->seq_fields.bits.frame_mbs_only_flag, 1); - - if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs - g_assert (0); - gst_bit_writer_put_bits_uint32 (bitwriter, mb_adaptive_frame_field, 1); - } - - /* direct_8x8_inference_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); - /* frame_cropping_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->frame_cropping_flag, 1); - - if (seq_param->frame_cropping_flag) { - /* frame_crop_left_offset */ - gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_left_offset); - /* frame_crop_right_offset */ - gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_right_offset); - /* frame_crop_top_offset */ - gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_top_offset); - /* frame_crop_bottom_offset */ - gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_bottom_offset); - } - - /* vui_parameters_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, - seq_param->vui_parameters_present_flag, 1); - if (seq_param->vui_parameters_present_flag) { - /* aspect_ratio_info_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, - seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1); - if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { - gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->aspect_ratio_idc, - 8); - if (seq_param->aspect_ratio_idc == 0xFF) { - gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->sar_width, 16); - gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->sar_height, 16); - } - } - - /* overscan_info_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); - /* video_signal_type_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); - /* chroma_loc_info_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); - - /* timing_info_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, - seq_param->vui_fields.bits.timing_info_present_flag, 1); - if (seq_param->vui_fields.bits.timing_info_present_flag) { - gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->num_units_in_tick, - 32); - gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->time_scale, 32); - gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* fixed_frame_rate_flag */ - } - - nal_hrd_parameters_present_flag = - (seq_param->bits_per_second > 0 ? TRUE : FALSE); - /* nal_hrd_parameters_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, nal_hrd_parameters_present_flag, - 1); - if (nal_hrd_parameters_present_flag) { - /* hrd_parameters */ - /* cpb_cnt_minus1 */ - gst_bit_writer_put_ue (bitwriter, 0); - gst_bit_writer_put_bits_uint32 (bitwriter, 4, 4); /* bit_rate_scale */ - gst_bit_writer_put_bits_uint32 (bitwriter, 6, 4); /* cpb_size_scale */ - - for (i = 0; i < 1; ++i) { - /* bit_rate_value_minus1[0] */ - gst_bit_writer_put_ue (bitwriter, - seq_param->bits_per_second / 1000 - 1); - /* cpb_size_value_minus1[0] */ - gst_bit_writer_put_ue (bitwriter, - seq_param->bits_per_second / 1000 * 8 - 1); - /* cbr_flag[0] */ - gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); - } - /* initial_cpb_removal_delay_length_minus1 */ - gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5); - /* cpb_removal_delay_length_minus1 */ - gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5); - /* dpb_output_delay_length_minus1 */ - gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5); - /* time_offset_length */ - gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5); - } - /* vcl_hrd_parameters_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); - if (nal_hrd_parameters_present_flag - || 0 /*vcl_hrd_parameters_present_flag */ ) { - /* low_delay_hrd_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); - } - /* pic_struct_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); - /* bitwriter_restriction_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1); - } - - /* rbsp_trailing_bits */ - gst_bit_writer_write_trailing_bits (bitwriter); - return TRUE; -} - -static gboolean -gst_bit_writer_write_pps (GstBitWriter * bitwriter, - const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile) -{ - guint32 num_slice_groups_minus1 = 0; - guint32 pic_init_qs_minus26 = 0; - guint32 redundant_pic_cnt_present_flag = 0; - - /* pic_parameter_set_id */ - gst_bit_writer_put_ue (bitwriter, pic_param->pic_parameter_set_id); - /* seq_parameter_set_id */ - gst_bit_writer_put_ue (bitwriter, pic_param->seq_parameter_set_id); - /* entropy_coding_mode_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, - pic_param->pic_fields.bits.entropy_coding_mode_flag, 1); - /* pic_order_present_flag */ - gst_bit_writer_put_bits_uint32 (bitwriter, - pic_param->pic_fields.bits.pic_order_present_flag, 1); - /* slice_groups-1 */ - gst_bit_writer_put_ue (bitwriter, num_slice_groups_minus1); - - if (num_slice_groups_minus1 > 0) { - /*FIXME*/ g_assert (0); - } - gst_bit_writer_put_ue (bitwriter, pic_param->num_ref_idx_l0_active_minus1); - gst_bit_writer_put_ue (bitwriter, pic_param->num_ref_idx_l1_active_minus1); - gst_bit_writer_put_bits_uint32 (bitwriter, - pic_param->pic_fields.bits.weighted_pred_flag, 1); - gst_bit_writer_put_bits_uint32 (bitwriter, - pic_param->pic_fields.bits.weighted_bipred_idc, 2); - /* pic_init_qp_minus26 */ - gst_bit_writer_put_se (bitwriter, pic_param->pic_init_qp - 26); - /* pic_init_qs_minus26 */ - gst_bit_writer_put_se (bitwriter, pic_init_qs_minus26); - /* chroma_qp_index_offset */ - gst_bit_writer_put_se (bitwriter, pic_param->chroma_qp_index_offset); - - gst_bit_writer_put_bits_uint32 (bitwriter, - pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1); - gst_bit_writer_put_bits_uint32 (bitwriter, - pic_param->pic_fields.bits.constrained_intra_pred_flag, 1); - gst_bit_writer_put_bits_uint32 (bitwriter, redundant_pic_cnt_present_flag, 1); - - /* more_rbsp_data */ - if (profile == GST_VAAPI_PROFILE_H264_HIGH) { - gst_bit_writer_put_bits_uint32 (bitwriter, - pic_param->pic_fields.bits.transform_8x8_mode_flag, 1); - gst_bit_writer_put_bits_uint32 (bitwriter, - pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1); - if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) { - g_assert (0 && "unsupported scaling lists"); - /* FIXME */ - /* - for (i = 0; i < - (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag)); - i++) { - gst_bit_writer_put_bits_uint8(bitwriter, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1); - } - */ - } - gst_bit_writer_put_se (bitwriter, pic_param->second_chroma_qp_index_offset); - } - - /* rbsp_trailing_bits */ - gst_bit_writer_write_trailing_bits (bitwriter); - return TRUE; -} - static gboolean add_sequence_packed_header (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) { GstVaapiEncPackedHeader *packed_seq; - GstBitWriter writer; + GstBitWriter bs; VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; guint32 data_bit_size; guint8 *data; - gst_bit_writer_init (&writer, 128 * 8); - gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */ - gst_bit_writer_write_nal_header (&writer, + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS); - gst_bit_writer_write_sps (&writer, seq_param, encoder->profile); - g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer); - data = GST_BIT_WRITER_DATA (&writer); + bs_write_sps (&bs, seq_param, encoder->profile); + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); packed_header_param_buffer.type = VAEncPackedHeaderSequence; packed_header_param_buffer.bit_length = data_bit_size; @@ -851,9 +887,16 @@ add_sequence_packed_header (GstVaapiEncoderH264 * encoder, /* store sps data */ _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&writer, TRUE); - + gst_bit_writer_clear (&bs, TRUE); return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } } static gboolean @@ -861,20 +904,20 @@ add_picture_packed_header (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncPackedHeader *packed_pic; - GstBitWriter writer; + GstBitWriter bs; VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; const VAEncPictureParameterBufferH264 *const pic_param = picture->param; guint32 data_bit_size; guint8 *data; - gst_bit_writer_init (&writer, 128 * 8); - gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */ - gst_bit_writer_write_nal_header (&writer, + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_PPS); - gst_bit_writer_write_pps (&writer, pic_param, encoder->profile); - g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer); - data = GST_BIT_WRITER_DATA (&writer); + bs_write_pps (&bs, pic_param, encoder->profile); + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); packed_header_param_buffer.type = VAEncPackedHeaderPicture; packed_header_param_buffer.bit_length = data_bit_size; @@ -890,9 +933,16 @@ add_picture_packed_header (GstVaapiEncoderH264 * encoder, /* store pps data */ _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&writer, TRUE); - + gst_bit_writer_clear (&bs, TRUE); return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write PPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } } /* reference picture management */ @@ -1567,7 +1617,7 @@ gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder, const guint32 nal_length_size = 4; guint8 profile_idc, profile_comp, level_idc; GstMapInfo sps_info, pps_info; - GstBitWriter writer; + GstBitWriter bs; GstBuffer *buffer; if (!encoder->sps_data || !encoder->pps_data) @@ -1587,39 +1637,47 @@ gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder, level_idc = sps_info.data[3]; /* Header */ - gst_bit_writer_init (&writer, (sps_info.size + pps_info.size + 64) * 8); - gst_bit_writer_put_bits_uint32 (&writer, configuration_version, 8); - gst_bit_writer_put_bits_uint32 (&writer, profile_idc, 8); - gst_bit_writer_put_bits_uint32 (&writer, profile_comp, 8); - gst_bit_writer_put_bits_uint32 (&writer, level_idc, 8); - gst_bit_writer_put_bits_uint32 (&writer, 0x3f, 6); /* 111111 */ - gst_bit_writer_put_bits_uint32 (&writer, nal_length_size - 1, 2); - gst_bit_writer_put_bits_uint32 (&writer, 0x07, 3); /* 111 */ + gst_bit_writer_init (&bs, (sps_info.size + pps_info.size + 64) * 8); + WRITE_UINT32 (&bs, configuration_version, 8); + WRITE_UINT32 (&bs, profile_idc, 8); + WRITE_UINT32 (&bs, profile_comp, 8); + WRITE_UINT32 (&bs, level_idc, 8); + WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */ + WRITE_UINT32 (&bs, nal_length_size - 1, 2); + WRITE_UINT32 (&bs, 0x07, 3); /* 111 */ /* Write SPS */ - gst_bit_writer_put_bits_uint32 (&writer, 1, 5); /* SPS count = 1 */ - g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); - gst_bit_writer_put_bits_uint32 (&writer, sps_info.size, 16); - gst_bit_writer_put_bytes (&writer, sps_info.data, sps_info.size); + WRITE_UINT32 (&bs, 1, 5); /* SPS count = 1 */ + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + WRITE_UINT32 (&bs, sps_info.size, 16); + gst_bit_writer_put_bytes (&bs, sps_info.data, sps_info.size); /* Write PPS */ - gst_bit_writer_put_bits_uint32 (&writer, 1, 8); /* PPS count = 1 */ - gst_bit_writer_put_bits_uint32 (&writer, pps_info.size, 16); - gst_bit_writer_put_bytes (&writer, pps_info.data, pps_info.size); + WRITE_UINT32 (&bs, 1, 8); /* PPS count = 1 */ + WRITE_UINT32 (&bs, pps_info.size, 16); + gst_bit_writer_put_bytes (&bs, pps_info.data, pps_info.size); gst_buffer_unmap (encoder->pps_data, &pps_info); gst_buffer_unmap (encoder->sps_data, &sps_info); - buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&writer), - GST_BIT_WRITER_BIT_SIZE (&writer) / 8); + buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&bs), + GST_BIT_WRITER_BIT_SIZE (&bs) / 8); if (!buffer) goto error_alloc_buffer; *out_buffer_ptr = buffer; - gst_bit_writer_clear (&writer, FALSE); + gst_bit_writer_clear (&bs, FALSE); return GST_VAAPI_ENCODER_STATUS_SUCCESS; /* ERRORS */ +bs_error: + { + GST_ERROR ("failed to write codec-data"); + gst_buffer_unmap (encoder->sps_data, &sps_info); + gst_buffer_unmap (encoder->pps_data, &pps_info); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } error_map_sps_buffer: { GST_ERROR ("failed to map SPS packed header"); @@ -1634,7 +1692,7 @@ error_map_pps_buffer: error_alloc_buffer: { GST_ERROR ("failed to allocate codec-data buffer"); - gst_bit_writer_clear (&writer, TRUE); + gst_bit_writer_clear (&bs, TRUE); return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; } } From 54d1900e1dda33b3e63aff123c9d1180896e2646 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 21 Jan 2014 16:05:22 +0100 Subject: [PATCH 1546/3781] encoder: h264: clean-ups. Document and rename a few functions here and there. Drop code that caps num_bframes variable in reset_properties() since they shall have been checked beforehand, during properties initialization. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 280 +++++++++++----------- 1 file changed, 146 insertions(+), 134 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index eb037c40f3..57b004bfb9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -119,7 +119,7 @@ h264_get_log2_max_frame_num (guint num) ret = 4; else if (ret > 10) ret = 10; - /* must greater than 4 */ + /* must be greater than 4 */ return ret; } @@ -278,8 +278,9 @@ bs_write_sps (GstBitWriter * bs, WRITE_UE (bs, seq_param->bit_depth_chroma_minus8); /* b_qpprime_y_zero_transform_bypass */ WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1); - g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0); + /* seq_scaling_matrix_present_flag */ + g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0); WRITE_UINT32 (bs, seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1); @@ -308,7 +309,7 @@ bs_write_sps (GstBitWriter * bs, /* log2_max_pic_order_cnt_lsb_minus4 */ WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4); } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { - g_assert (0); + g_assert (0 && "only POC type 0 is supported"); WRITE_UINT32 (bs, seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1); WRITE_SE (bs, seq_param->offset_for_non_ref_pic); @@ -332,7 +333,7 @@ bs_write_sps (GstBitWriter * bs, WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1); if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs - g_assert (0); + g_assert (0 && "only progressive frames encoding is supported"); WRITE_UINT32 (bs, mb_adaptive_frame_field, 1); } @@ -455,7 +456,7 @@ bs_write_pps (GstBitWriter * bs, WRITE_UE (bs, num_slice_groups_minus1); if (num_slice_groups_minus1 > 0) { - /*FIXME*/ g_assert (0); + /*FIXME*/ g_assert (0 && "unsupported arbitrary slice ordering (ASO)"); } WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1); WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1); @@ -713,6 +714,7 @@ ensure_profile (GstVaapiEncoderH264 * encoder) return TRUE; } +/* Derives the level from the currently set limits */ static gboolean ensure_level (GstVaapiEncoderH264 * encoder) { @@ -792,8 +794,9 @@ ensure_tuning (GstVaapiEncoderH264 * encoder) return success; } -static inline void -_reset_gop_start (GstVaapiEncoderH264 * encoder) +/* Handle new GOP starts */ +static void +reset_gop_start (GstVaapiEncoderH264 * encoder) { ++encoder->idr_num; encoder->frame_index = 1; @@ -801,8 +804,9 @@ _reset_gop_start (GstVaapiEncoderH264 * encoder) encoder->cur_present_index = 0; } +/* Marks the supplied picture as a B-frame */ static void -_set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) +set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { g_assert (pic && encoder); g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); @@ -810,16 +814,18 @@ _set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num); } -static inline void -_set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) +/* Marks the supplied picture as a P-frame */ +static void +set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_P; pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num); } -static inline void -_set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) +/* Marks the supplied picture as an I-frame */ +static void +set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_I; @@ -829,8 +835,9 @@ _set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); } -static inline void -_set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) +/* Marks the supplied picture as an IDR frame */ +static void +set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_I; @@ -842,24 +849,42 @@ _set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); } -static inline void -_set_key_frame (GstVaapiEncPicture * picture, +/* Marks the supplied picture a a key-frame */ +static void +set_key_frame (GstVaapiEncPicture * picture, GstVaapiEncoderH264 * encoder, gboolean is_idr) { if (is_idr) { - _reset_gop_start (encoder); - _set_idr_frame (picture, encoder); + reset_gop_start (encoder); + set_idr_frame (picture, encoder); } else - _set_i_frame (picture, encoder); + set_i_frame (picture, encoder); } +/* Fills in VA HRD parameters */ +static void +fill_hrd_params (GstVaapiEncoderH264 * encoder, VAEncMiscParameterHRD * hrd) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + + if (base_encoder->bitrate > 0) { + hrd->buffer_size = base_encoder->bitrate * 1000 * 8; + hrd->initial_buffer_fullness = hrd->buffer_size / 2; + } else { + hrd->buffer_size = 0; + hrd->initial_buffer_fullness = 0; + } +} + +/* Adds the supplied sequence header (SPS) to the list of packed + headers to pass down as-is to the encoder */ static gboolean -add_sequence_packed_header (GstVaapiEncoderH264 * encoder, +add_packed_sequence_header (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) { GstVaapiEncPackedHeader *packed_seq; GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; + VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 }; const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; guint32 data_bit_size; guint8 *data; @@ -873,12 +898,12 @@ add_sequence_packed_header (GstVaapiEncoderH264 * encoder, data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); data = GST_BIT_WRITER_DATA (&bs); - packed_header_param_buffer.type = VAEncPackedHeaderSequence; - packed_header_param_buffer.bit_length = data_bit_size; - packed_header_param_buffer.has_emulation_bytes = 0; + packed_seq_param.type = VAEncPackedHeaderSequence; + packed_seq_param.bit_length = data_bit_size; + packed_seq_param.has_emulation_bytes = 0; packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), - &packed_header_param_buffer, sizeof (packed_header_param_buffer), + &packed_seq_param, sizeof (packed_seq_param), data, (data_bit_size + 7) / 8); g_assert (packed_seq); @@ -899,13 +924,15 @@ bs_error: } } +/* Adds the supplied picture header (PPS) to the list of packed + headers to pass down as-is to the encoder */ static gboolean -add_picture_packed_header (GstVaapiEncoderH264 * encoder, +add_packed_picture_header (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncPackedHeader *packed_pic; GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; + VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 }; const VAEncPictureParameterBufferH264 *const pic_param = picture->param; guint32 data_bit_size; guint8 *data; @@ -919,12 +946,12 @@ add_picture_packed_header (GstVaapiEncoderH264 * encoder, data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); data = GST_BIT_WRITER_DATA (&bs); - packed_header_param_buffer.type = VAEncPackedHeaderPicture; - packed_header_param_buffer.bit_length = data_bit_size; - packed_header_param_buffer.has_emulation_bytes = 0; + packed_pic_param.type = VAEncPackedHeaderPicture; + packed_pic_param.bit_length = data_bit_size; + packed_pic_param.has_emulation_bytes = 0; packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), - &packed_header_param_buffer, sizeof (packed_header_param_buffer), + &packed_pic_param, sizeof (packed_pic_param), data, (data_bit_size + 7) / 8); g_assert (packed_pic); @@ -945,7 +972,7 @@ bs_error: } } -/* reference picture management */ +/* Reference picture management */ static void reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref) { @@ -1042,10 +1069,9 @@ reference_list_init (GstVaapiEncoderH264 * encoder, return TRUE; } -/* fill the H264 VA encoding parameters */ +/* Fills in VA sequence parameter buffer */ static gboolean -fill_va_sequence_param (GstVaapiEncoderH264 * encoder, - GstVaapiEncSequence * sequence) +fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; @@ -1127,13 +1153,12 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder, seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2; } } - return TRUE; } +/* Fills in VA picture parameter buffer */ static gboolean -fill_va_picture_param (GstVaapiEncoderH264 * encoder, - GstVaapiEncPicture * picture, +fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) { VAEncPictureParameterBufferH264 *const pic_param = picture->param; @@ -1198,11 +1223,10 @@ fill_va_picture_param (GstVaapiEncoderH264 * encoder, return TRUE; } +/* Adds slice headers to picture */ static gboolean -fill_va_slices_param (GstVaapiEncoderH264 * encoder, - GstVaapiEncPicture * picture, - GstVaapiEncoderH264Ref ** reflist_0, - guint reflist_0_count, +add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, + GstVaapiEncoderH264Ref ** reflist_0, guint reflist_0_count, GstVaapiEncoderH264Ref ** reflist_1, guint reflist_1_count) { VAEncSliceParameterBufferH264 *slice_param; @@ -1326,6 +1350,7 @@ fill_va_slices_param (GstVaapiEncoderH264 * encoder, return TRUE; } +/* Generates and submits SPS header accordingly into the bitstream */ static gboolean ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { @@ -1337,11 +1362,11 @@ ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) if (!sequence) goto error; - if (!fill_va_sequence_param (encoder, sequence)) + if (!fill_sequence (encoder, sequence)) goto error; if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - !add_sequence_packed_header (encoder, picture, sequence)) + !add_packed_sequence_header (encoder, picture, sequence)) goto error; gst_vaapi_enc_picture_set_sequence (picture, sequence); gst_vaapi_codec_object_replace (&sequence, NULL); @@ -1352,6 +1377,48 @@ error: return FALSE; } +/* Generates additional control parameters */ +static gboolean +ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + GstVaapiEncMiscParam *misc = NULL; + VAEncMiscParameterRateControl *rate_control; + + /* HRD params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); + g_assert (misc); + if (!misc) + return FALSE; + fill_hrd_params (encoder, misc->data); + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + /* RateControl params */ + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR || + GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) { + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); + g_assert (misc); + if (!misc) + return FALSE; + rate_control = misc->data; + memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); + if (base_encoder->bitrate) + rate_control->bits_per_second = base_encoder->bitrate * 1000; + else + rate_control->bits_per_second = 0; + rate_control->target_percentage = 70; + rate_control->window_size = 500; + rate_control->initial_qp = encoder->init_qp; + rate_control->min_qp = encoder->min_qp; + rate_control->basic_unit_size = 0; + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + } + return TRUE; +} + +/* Generates and submits PPS header accordingly into the bitstream */ static gboolean ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) @@ -1359,18 +1426,18 @@ ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBuffer *const codedbuf = GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); - if (!fill_va_picture_param (encoder, picture, codedbuf, surface)) + if (!fill_picture (encoder, picture, codedbuf, surface)) return FALSE; if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - !add_picture_packed_header (encoder, picture)) { + !add_packed_picture_header (encoder, picture)) { GST_ERROR ("set picture packed header failed"); return FALSE; } - return TRUE; } +/* Generates slice headers */ static gboolean ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { @@ -1393,82 +1460,15 @@ ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) if (reflist_1_count > encoder->max_reflist1_count) reflist_1_count = encoder->max_reflist1_count; - if (!fill_va_slices_param (encoder, picture, + if (!add_slice_headers (encoder, picture, reflist_0, reflist_0_count, reflist_1, reflist_1_count)) return FALSE; return TRUE; } -static gboolean -ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) -{ - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - GstVaapiEncMiscParam *misc = NULL; - VAEncMiscParameterHRD *hrd; - VAEncMiscParameterRateControl *rate_control; - - /* add hrd */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - g_assert (misc); - if (!misc) - return FALSE; - gst_vaapi_enc_picture_add_misc_param (picture, misc); - hrd = misc->data; - if (base_encoder->bitrate > 0) { - hrd->initial_buffer_fullness = base_encoder->bitrate * 1000 * 4; - hrd->buffer_size = base_encoder->bitrate * 1000 * 8; - } else { - hrd->initial_buffer_fullness = 0; - hrd->buffer_size = 0; - } - gst_vaapi_codec_object_replace (&misc, NULL); - - /* add ratecontrol */ - if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR || - GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) { - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); - g_assert (misc); - if (!misc) - return FALSE; - gst_vaapi_enc_picture_add_misc_param (picture, misc); - rate_control = misc->data; - memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); - if (base_encoder->bitrate) - rate_control->bits_per_second = base_encoder->bitrate * 1000; - else - rate_control->bits_per_second = 0; - rate_control->target_percentage = 70; - rate_control->window_size = 500; - rate_control->initial_qp = encoder->init_qp; - rate_control->min_qp = encoder->min_qp; - rate_control->basic_unit_size = 0; - gst_vaapi_codec_object_replace (&misc, NULL); - } - - return TRUE; -} - -static GstVaapiEncoderStatus -ensure_profile_and_level (GstVaapiEncoderH264 * encoder) -{ - ensure_tuning (encoder); - - if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - - if (!ensure_level (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; - - /* Check HW constraints */ - if (!ensure_hw_profile_limits (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - if (encoder->profile_idc > encoder->hw_max_profile_idc) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -static gboolean +/* Estimates a good enough bitrate if none was supplied */ +static void ensure_bitrate (GstVaapiEncoderH264 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); @@ -1500,7 +1500,26 @@ ensure_bitrate (GstVaapiEncoderH264 * encoder) base_encoder->bitrate = 0; break; } - return TRUE; +} + +/* Constructs profile and level information based on user-defined limits */ +static GstVaapiEncoderStatus +ensure_profile_and_level (GstVaapiEncoderH264 * encoder) +{ + ensure_tuning (encoder); + + if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + if (!ensure_level (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + + /* Check HW constraints */ + if (!ensure_hw_profile_limits (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + if (encoder->profile_idc > encoder->hw_max_profile_idc) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } static void @@ -1527,9 +1546,6 @@ reset_properties (GstVaapiEncoderH264 * encoder) if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; - if (encoder->num_bframes > 50) - encoder->num_bframes = 50; - if (encoder->num_bframes) encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) / GST_VAAPI_ENCODER_FPS_N (encoder); @@ -1567,9 +1583,9 @@ gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base_encoder, if (!ensure_sequence (encoder, picture)) goto error; - if (!ensure_picture (encoder, picture, codedbuf, reconstruct)) + if (!ensure_misc_params (encoder, picture)) goto error; - if (!ensure_misc (encoder, picture)) + if (!ensure_picture (encoder, picture, codedbuf, reconstruct)) goto error; if (!ensure_slices (encoder, picture)) goto error; @@ -1752,16 +1768,16 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, GstVaapiEncPicture *p_pic; p_pic = g_queue_pop_tail (&encoder->reorder_frame_list); - _set_p_frame (p_pic, encoder); + set_p_frame (p_pic, encoder); g_queue_foreach (&encoder->reorder_frame_list, - (GFunc) _set_b_frame, encoder); + (GFunc) set_b_frame, encoder); ++encoder->cur_frame_num; - _set_key_frame (picture, encoder, is_idr); + set_key_frame (picture, encoder, is_idr); g_queue_push_tail (&encoder->reorder_frame_list, picture); picture = p_pic; encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; } else { /* no b frames in queue */ - _set_key_frame (picture, encoder, is_idr); + set_key_frame (picture, encoder, is_idr); g_assert (g_queue_is_empty (&encoder->reorder_frame_list)); if (encoder->num_bframes) encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; @@ -1779,10 +1795,10 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, } ++encoder->cur_frame_num; - _set_p_frame (picture, encoder); + set_p_frame (picture, encoder); if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) { - g_queue_foreach (&encoder->reorder_frame_list, (GFunc) _set_b_frame, + g_queue_foreach (&encoder->reorder_frame_list, (GFunc) set_b_frame, encoder); encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; g_assert (!g_queue_is_empty (&encoder->reorder_frame_list)); @@ -1858,14 +1874,10 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; - if (!ensure_bitrate (encoder)) - goto error; + ensure_bitrate (encoder); reset_properties (encoder); return set_context_info (base_encoder); - -error: - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } static gboolean From 586f872085cc1c4e5722b225de3ba0170fe53efa Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 21 Jan 2014 17:04:40 +0100 Subject: [PATCH 1547/3781] encoder: h264: fix level when bitrate is automatically computed. Fix level characterisation when the bitrate is automatically computed from the active coding tools. i.e. ensure the bitrate once the profile is completely characterized but before the level calculation process. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 57b004bfb9..e8008f4f7f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1511,14 +1511,16 @@ ensure_profile_and_level (GstVaapiEncoderH264 * encoder) if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - if (!ensure_level (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; - /* Check HW constraints */ if (!ensure_hw_profile_limits (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; if (encoder->profile_idc > encoder->hw_max_profile_idc) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + /* Ensure bitrate if not set already and derive the right level to use */ + ensure_bitrate (encoder); + if (!ensure_level (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; return GST_VAAPI_ENCODER_STATUS_SUCCESS; } @@ -1874,8 +1876,6 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; - ensure_bitrate (encoder); - reset_properties (encoder); return set_context_info (base_encoder); } From d9cf58e88a88a44168044c5f0a5a9da9943ec523 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 21 Jan 2014 17:35:24 +0100 Subject: [PATCH 1548/3781] encoder: h264: fix ip_period value in sequence parameter. The VAEncSequenceParameterBuffer.ip_period value reprents the distance between the I-frame and the next P-frame. So, this also accounts for any additional B-frame in the middle of it. This fixes rate control heuristics for certain VA drivers. https://bugzilla.gnome.org/show_bug.cgi?id=722735 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index e8008f4f7f..1fc440e724 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1080,7 +1080,7 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) seq_param->seq_parameter_set_id = 0; seq_param->level_idc = encoder->level_idc; seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); - seq_param->ip_period = 0; // ? + seq_param->ip_period = 1 + encoder->num_bframes; if (base_encoder->bitrate > 0) seq_param->bits_per_second = base_encoder->bitrate * 1000; else From 71113e4999328bde8b34b0cf713f80e7e106cf43 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 21 Jan 2014 18:35:17 +0100 Subject: [PATCH 1549/3781] encoder: h264: only submit packed headers when required. Make sure to submit the packed headers only if the underlying VA driver requires those. Currently, only handle packed sequence and picture headers. https://bugzilla.gnome.org/show_bug.cgi?id=722737 --- gst-libs/gst/vaapi/gstvaapicontext.c | 40 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapicontext.h | 5 +++ gst-libs/gst/vaapi/gstvaapiencoder.c | 11 +++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 ++-- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 13 ++++++++ 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 0628224539..52e9317da1 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -1005,3 +1005,43 @@ error: gst_vaapi_context_clear_overlay(context); return FALSE; } + + +/** + * gst_vaapi_context_get_attribute: + * @context: a #GstVaapiContext + * @type: a VA config attribute type + * @out_value_ptr: return location for the config attribute value + * + * Determines the value for the VA config attribute @type. + * + * Note: this function only returns success if the VA driver does + * actually know about this config attribute type and that it returned + * a valid value for it. + * + * Return value: %TRUE if the VA driver knows about the requested + * config attribute and returned a valid value, %FALSE otherwise + */ +gboolean +gst_vaapi_context_get_attribute(GstVaapiContext *context, + VAConfigAttribType type, guint *out_value_ptr) +{ + VAConfigAttrib attrib; + VAStatus status; + + g_return_val_if_fail(context != NULL, FALSE); + + GST_VAAPI_OBJECT_LOCK_DISPLAY(context); + attrib.type = type; + status = vaGetConfigAttributes(GST_VAAPI_OBJECT_VADISPLAY(context), + gst_vaapi_profile_get_va_profile(context->info.profile), + gst_vaapi_entrypoint_get_va_entrypoint(context->info.entrypoint), + &attrib, 1); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(context); + if (!vaapi_check_status(status, "vaGetConfiAttributes()")) + return FALSE; + + if (out_value_ptr) + *out_value_ptr = attrib.value; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 771f505469..22ce752786 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -127,6 +127,11 @@ gst_vaapi_context_apply_composition( GstVideoOverlayComposition *composition ); +G_GNUC_INTERNAL +gboolean +gst_vaapi_context_get_attribute(GstVaapiContext *context, + VAConfigAttribType type, guint *out_value_ptr); + G_END_DECLS #endif /* GST_VAAPI_CONTEXT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index b9767f1543..7b3d00965b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -466,6 +466,16 @@ error_invalid_framerate: } } +/* Determines the set of required packed headers */ +static void +ensure_packed_headers (GstVaapiEncoder * encoder) +{ + if (!gst_vaapi_context_get_attribute (encoder->context, + VAConfigAttribEncPackedHeaders, &encoder->packed_headers)) + encoder->packed_headers = 0; + GST_INFO ("packed headers mask: 0x%08x", encoder->packed_headers); +} + /* Updates video context */ static void set_context_info (GstVaapiEncoder * encoder) @@ -520,6 +530,7 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) if (!gst_vaapi_encoder_ensure_context (encoder)) goto error_reset_context; + ensure_packed_headers (encoder); codedbuf_size = encoder->codedbuf_pool ? gst_vaapi_coded_buffer_pool_get_buffer_size (GST_VAAPI_CODED_BUFFER_POOL diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 1fc440e724..8b7f2834f1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1366,7 +1366,8 @@ ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) goto error; if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - !add_packed_sequence_header (encoder, picture, sequence)) + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS) + && !add_packed_sequence_header (encoder, picture, sequence)) goto error; gst_vaapi_enc_picture_set_sequence (picture, sequence); gst_vaapi_codec_object_replace (&sequence, NULL); @@ -1430,7 +1431,8 @@ ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, return FALSE; if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - !add_packed_picture_header (encoder, picture)) { + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_PPS) + && !add_packed_picture_header (encoder, picture)) { GST_ERROR ("set picture packed header failed"); return FALSE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index abe3309a4d..43e5ad2c7d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -40,6 +40,18 @@ G_BEGIN_DECLS #define GST_VAAPI_ENCODER_GET_CLASS(obj) \ GST_VAAPI_ENCODER_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) +/** + * 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 @@ -191,6 +203,7 @@ struct _GstVaapiEncoder GstVaapiContext *context; GstVaapiContextInfo context_info; GstVaapiEncoderTune tune; + guint packed_headers; VADisplay va_display; VAContextID va_context; From 1e502d63d5a5634e2de986a6d749c8e659d0e959 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 21 Jan 2014 18:01:20 +0100 Subject: [PATCH 1550/3781] encoder: h264: submit sequence parameter only once. Submit sequence parameter buffers only once, or when the bitstream was reconfigured in a way that requires such. Always submit packed sequence parameter buffers at I-frame period, if the VA driver needs those. https://bugzilla.gnome.org/show_bug.cgi?id=722737 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 35 ++++++++++++++--------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 8b7f2834f1..d4b2253b70 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1356,26 +1356,35 @@ ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncSequence *sequence; - g_assert (picture); + // Submit an SPS header before every new I-frame + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) + return TRUE; + sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder); - g_assert (sequence); - if (!sequence) - goto error; + if (!sequence || !fill_sequence (encoder, sequence)) + goto error_create_seq_param; - if (!fill_sequence (encoder, sequence)) - goto error; - - if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS) + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS) && !add_packed_sequence_header (encoder, picture, sequence)) - goto error; + goto error_create_packed_seq_hdr; + gst_vaapi_enc_picture_set_sequence (picture, sequence); gst_vaapi_codec_object_replace (&sequence, NULL); return TRUE; -error: - gst_vaapi_codec_object_replace (&sequence, NULL); - return FALSE; + /* ERRORS */ +error_create_seq_param: + { + GST_ERROR ("failed to create sequence parameter buffer (SPS)"); + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; + } +error_create_packed_seq_hdr: + { + GST_ERROR ("failed to create packed sequence header buffer"); + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; + } } /* Generates additional control parameters */ From 4c04a1bc8803ca40ecc2ef60a5324e1094ed0069 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 22 Jan 2014 11:25:13 +0100 Subject: [PATCH 1551/3781] encoder: h264: fix level lookup constraints wrt. bitrate. Fix the level calculation involving bitrate limits. Since we are targetting NAL HRD conformance, the check against MaxBR from the Table A-1 limits shall involve cpbBrNalFactor depending on the active profile. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 31 +++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index d4b2253b70..0046f96b20 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -123,6 +123,31 @@ h264_get_log2_max_frame_num (guint num) return ret; } +/* Determines the cpbBrNalFactor based on the supplied profile */ +static guint +h264_get_cpb_nal_factor (GstVaapiProfile profile) +{ + guint f; + + /* Table A-2 */ + switch (profile) { + case GST_VAAPI_PROFILE_H264_HIGH: + f = 1500; + break; + case GST_VAAPI_PROFILE_H264_HIGH10: + f = 3600; + break; + case GST_VAAPI_PROFILE_H264_HIGH_422: + case GST_VAAPI_PROFILE_H264_HIGH_444: + f = 4800; + break; + default: + f = 1200; + break; + } + return f; +} + /* ------------------------------------------------------------------------- */ /* --- H.264 Bitstream Writer --- */ /* ------------------------------------------------------------------------- */ @@ -718,7 +743,8 @@ ensure_profile (GstVaapiEncoderH264 * encoder) static gboolean ensure_level (GstVaapiEncoderH264 * encoder) { - const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate; + const guint cpb_factor = h264_get_cpb_nal_factor (encoder->profile); + const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate * 1000; const GstVaapiH264LevelLimits *limits_table; guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS; @@ -732,7 +758,8 @@ ensure_level (GstVaapiEncoderH264 * encoder) const GstVaapiH264LevelLimits *const limits = &limits_table[i]; if (PicSizeMbs <= limits->MaxFS && MaxDpbMbs <= limits->MaxDpbMbs && - MaxMBPS <= limits->MaxMBPS && (!bitrate || bitrate <= limits->MaxBR)) + MaxMBPS <= limits->MaxMBPS && (!bitrate + || bitrate <= (limits->MaxBR * cpb_factor))) break; } if (i == num_limits) From 9d42c864229b9f03ec3f21a838c7b7a73325c11a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 22 Jan 2014 14:43:24 +0100 Subject: [PATCH 1552/3781] encoder: h264: fix bitrate encoding for HRD conformance. Round down the calculated, or supplied, bitrate (kbps) into a multiple of the HRD bitrate scale factor. Use a bitrate scale factor of 64 so that to have less losses in precision. Likewise, don't round up because that could be a strict constraint imposed by the user. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 52 ++++++++++++++--------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 0046f96b20..bc07711df0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -37,6 +37,9 @@ /* Define the maximum IDR period */ #define MAX_IDR_PERIOD 512 +/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ +#define SX_BITRATE 6 + /* Define default rate control mode ("constant-qp") */ #define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP @@ -415,12 +418,12 @@ bs_write_sps (GstBitWriter * bs, /* hrd_parameters */ /* cpb_cnt_minus1 */ WRITE_UE (bs, 0); - WRITE_UINT32 (bs, 4, 4); /* bit_rate_scale */ + WRITE_UINT32 (bs, SX_BITRATE - 6, 4); /* bit_rate_scale */ WRITE_UINT32 (bs, 6, 4); /* cpb_size_scale */ for (i = 0; i < 1; ++i) { /* bit_rate_value_minus1[0] */ - WRITE_UE (bs, seq_param->bits_per_second / 1000 - 1); + WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1); /* cpb_size_value_minus1[0] */ WRITE_UE (bs, seq_param->bits_per_second / 1000 * 8 - 1); /* cbr_flag[0] */ @@ -581,6 +584,8 @@ struct _GstVaapiEncoderH264 GstBuffer *sps_data; GstBuffer *pps_data; + + guint bitrate_bits; // bitrate (bits) }; static inline void @@ -744,7 +749,6 @@ static gboolean ensure_level (GstVaapiEncoderH264 * encoder) { const guint cpb_factor = h264_get_cpb_nal_factor (encoder->profile); - const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate * 1000; const GstVaapiH264LevelLimits *limits_table; guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS; @@ -758,8 +762,8 @@ ensure_level (GstVaapiEncoderH264 * encoder) const GstVaapiH264LevelLimits *const limits = &limits_table[i]; if (PicSizeMbs <= limits->MaxFS && MaxDpbMbs <= limits->MaxDpbMbs && - MaxMBPS <= limits->MaxMBPS && (!bitrate - || bitrate <= (limits->MaxBR * cpb_factor))) + MaxMBPS <= limits->MaxMBPS && (!encoder->bitrate_bits + || encoder->bitrate_bits <= (limits->MaxBR * cpb_factor))) break; } if (i == num_limits) @@ -892,10 +896,8 @@ set_key_frame (GstVaapiEncPicture * picture, static void fill_hrd_params (GstVaapiEncoderH264 * encoder, VAEncMiscParameterHRD * hrd) { - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - - if (base_encoder->bitrate > 0) { - hrd->buffer_size = base_encoder->bitrate * 1000 * 8; + if (encoder->bitrate_bits > 0) { + hrd->buffer_size = encoder->bitrate_bits * 8; hrd->initial_buffer_fullness = hrd->buffer_size / 2; } else { hrd->buffer_size = 0; @@ -1100,7 +1102,6 @@ reference_list_init (GstVaapiEncoderH264 * encoder, static gboolean fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) { - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264)); @@ -1108,10 +1109,7 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) seq_param->level_idc = encoder->level_idc; seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq_param->ip_period = 1 + encoder->num_bframes; - if (base_encoder->bitrate > 0) - seq_param->bits_per_second = base_encoder->bitrate * 1000; - else - seq_param->bits_per_second = 0; + seq_param->bits_per_second = encoder->bitrate_bits; seq_param->max_num_ref_frames = encoder->max_ref_frames; seq_param->picture_width_in_mbs = encoder->mb_width; @@ -1418,7 +1416,6 @@ error_create_packed_seq_hdr: static gboolean ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncMiscParam *misc = NULL; VAEncMiscParameterRateControl *rate_control; @@ -1440,10 +1437,7 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) return FALSE; rate_control = misc->data; memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); - if (base_encoder->bitrate) - rate_control->bits_per_second = base_encoder->bitrate * 1000; - else - rate_control->bits_per_second = 0; + rate_control->bits_per_second = encoder->bitrate_bits; rate_control->target_percentage = 70; rate_control->window_size = 500; rate_control->initial_qp = encoder->init_qp; @@ -1505,6 +1499,25 @@ ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) return TRUE; } +/* Normalizes bitrate (and CPB size) for HRD conformance */ +static void +ensure_bitrate_hrd (GstVaapiEncoderH264 * encoder) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + guint bitrate; + + if (!base_encoder->bitrate) { + encoder->bitrate_bits = 0; + return; + } + + /* Round down bitrate. This is a hard limit mandated by the user */ + g_assert (SX_BITRATE >= 6); + bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1); + GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate); + encoder->bitrate_bits = bitrate; +} + /* Estimates a good enough bitrate if none was supplied */ static void ensure_bitrate (GstVaapiEncoderH264 * encoder) @@ -1538,6 +1551,7 @@ ensure_bitrate (GstVaapiEncoderH264 * encoder) base_encoder->bitrate = 0; break; } + ensure_bitrate_hrd (encoder); } /* Constructs profile and level information based on user-defined limits */ From 9d5fc53899fc05eecc4d7202946e0098427ba8a5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 21 Jan 2014 19:04:41 +0100 Subject: [PATCH 1553/3781] encoder: h264: fix default CPB buffer size. Fix default CPB buffer size to something more reasonable (1500 ms) and that still fits the level limits. This is a non configurable property for now. The initial CPB removal delay is also fixed to 750 ms. https://bugzilla.gnome.org/show_bug.cgi?id=722087 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 52 +++++++++++++++++--- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 3 ++ gst-libs/gst/vaapi/gstvaapiutils_h264.c | 36 +++++++------- gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h | 2 + 4 files changed, 67 insertions(+), 26 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index bc07711df0..c4421d929d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -37,6 +37,12 @@ /* Define the maximum IDR period */ #define MAX_IDR_PERIOD 512 +/* Default CPB length (in milliseconds) */ +#define DEFAULT_CPB_LENGTH 1500 + +/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */ +#define SX_CPB_SIZE 4 + /* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ #define SX_BITRATE 6 @@ -249,7 +255,8 @@ bs_error: /* Write an SPS NAL unit */ static gboolean bs_write_sps (GstBitWriter * bs, - const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile) + const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, + const VAEncMiscParameterHRD * hrd_params) { guint8 profile_idc; guint32 constraint_set0_flag, constraint_set1_flag; @@ -419,13 +426,13 @@ bs_write_sps (GstBitWriter * bs, /* cpb_cnt_minus1 */ WRITE_UE (bs, 0); WRITE_UINT32 (bs, SX_BITRATE - 6, 4); /* bit_rate_scale */ - WRITE_UINT32 (bs, 6, 4); /* cpb_size_scale */ + WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4); /* cpb_size_scale */ for (i = 0; i < 1; ++i) { /* bit_rate_value_minus1[0] */ WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1); /* cpb_size_value_minus1[0] */ - WRITE_UE (bs, seq_param->bits_per_second / 1000 * 8 - 1); + WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1); /* cbr_flag[0] */ WRITE_UINT32 (bs, 1, 1); } @@ -586,6 +593,8 @@ struct _GstVaapiEncoderH264 GstBuffer *pps_data; guint bitrate_bits; // bitrate (bits) + guint cpb_length; // length of CPB buffer (ms) + guint cpb_length_bits; // length of CPB buffer (bits) }; static inline void @@ -763,7 +772,9 @@ ensure_level (GstVaapiEncoderH264 * encoder) if (PicSizeMbs <= limits->MaxFS && MaxDpbMbs <= limits->MaxDpbMbs && MaxMBPS <= limits->MaxMBPS && (!encoder->bitrate_bits - || encoder->bitrate_bits <= (limits->MaxBR * cpb_factor))) + || encoder->bitrate_bits <= (limits->MaxBR * cpb_factor)) && + (!encoder->cpb_length_bits || + encoder->cpb_length_bits <= (limits->MaxCPB * cpb_factor))) break; } if (i == num_limits) @@ -897,7 +908,7 @@ static void fill_hrd_params (GstVaapiEncoderH264 * encoder, VAEncMiscParameterHRD * hrd) { if (encoder->bitrate_bits > 0) { - hrd->buffer_size = encoder->bitrate_bits * 8; + hrd->buffer_size = encoder->cpb_length_bits; hrd->initial_buffer_fullness = hrd->buffer_size / 2; } else { hrd->buffer_size = 0; @@ -915,14 +926,17 @@ add_packed_sequence_header (GstVaapiEncoderH264 * encoder, GstBitWriter bs; VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 }; const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; + VAEncMiscParameterHRD hrd_params; guint32 data_bit_size; guint8 *data; + fill_hrd_params (encoder, &hrd_params); + gst_bit_writer_init (&bs, 128 * 8); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS); - bs_write_sps (&bs, seq_param, encoder->profile); + bs_write_sps (&bs, seq_param, encoder->profile, &hrd_params); g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); data = GST_BIT_WRITER_DATA (&bs); @@ -1439,7 +1453,7 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); rate_control->bits_per_second = encoder->bitrate_bits; rate_control->target_percentage = 70; - rate_control->window_size = 500; + rate_control->window_size = encoder->cpb_length; rate_control->initial_qp = encoder->init_qp; rate_control->min_qp = encoder->min_qp; rate_control->basic_unit_size = 0; @@ -1504,7 +1518,7 @@ static void ensure_bitrate_hrd (GstVaapiEncoderH264 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - guint bitrate; + guint bitrate, cpb_size; if (!base_encoder->bitrate) { encoder->bitrate_bits = 0; @@ -1516,6 +1530,13 @@ ensure_bitrate_hrd (GstVaapiEncoderH264 * encoder) bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1); GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate); encoder->bitrate_bits = bitrate; + + /* Round up CPB size. This is an HRD compliance detail */ + g_assert (SX_CPB_SIZE >= 4); + cpb_size = gst_util_uint64_scale (bitrate, encoder->cpb_length, 1000) & + ~((1U << SX_CPB_SIZE) - 1); + GST_DEBUG ("HRD CPB size: %u bits", cpb_size); + encoder->cpb_length_bits = cpb_size; } /* Estimates a good enough bitrate if none was supplied */ @@ -2003,6 +2024,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_DCT8X8: encoder->use_dct8x8 = g_value_get_boolean (value); break; + case GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH: + encoder->cpb_length = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -2131,6 +2155,18 @@ gst_vaapi_encoder_h264_get_default_properties (void) "Enable adaptive use of 8x8 transforms in I-frames", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:cpb-length: + * + * The size of the CPB buffer in milliseconds. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH, + g_param_spec_uint ("cpb-length", + "CPB Length", "Length of the CPB buffer in milliseconds", + 1, 10000, DEFAULT_CPB_LENGTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 95a0a9a026..d4a8a7c374 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -42,6 +42,8 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * @GST_VAAPI_ENCODER_H264_PROP_CABAC: Enable CABAC entropy coding mode (bool). * @GST_VAAPI_ENCODER_H264_PROP_DCT8X8: Enable adaptive use of 8x8 * transforms in I-frames (bool). + * @GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH: Length of the CPB buffer + * in milliseconds (uint). * * The set of H.264 encoder specific configurable properties. */ @@ -52,6 +54,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES = -4, GST_VAAPI_ENCODER_H264_PROP_CABAC = -5, GST_VAAPI_ENCODER_H264_PROP_DCT8X8 = -6, + GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH = -7, } GstVaapiEncoderH264Prop; GstVaapiEncoder * diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index c72e017eb1..20da57ceef 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -76,24 +76,24 @@ static const struct map gst_vaapi_h264_level_map[] = { /* Table A-1 - Level limits */ /* *INDENT-OFF* */ static const GstVaapiH264LevelLimits gst_vaapi_h264_level_limits[] = { - /* level idc MaxMBPS MaxFS MaxDpbMbs MaxBR */ - { GST_VAAPI_LEVEL_H264_L1, 10, 1485, 99, 396, 64 }, - { GST_VAAPI_LEVEL_H264_L1b, 11, 1485, 99, 396, 128 }, - { GST_VAAPI_LEVEL_H264_L1_1, 11, 3000, 396, 900, 192 }, - { GST_VAAPI_LEVEL_H264_L1_2, 12, 6000, 396, 2376, 384 }, - { GST_VAAPI_LEVEL_H264_L1_3, 13, 11880, 396, 2376, 768 }, - { GST_VAAPI_LEVEL_H264_L2, 20, 11880, 396, 2376, 2000 }, - { GST_VAAPI_LEVEL_H264_L2_1, 21, 19800, 792, 4752, 4000 }, - { GST_VAAPI_LEVEL_H264_L2_2, 22, 20250, 1620, 8100, 4000 }, - { GST_VAAPI_LEVEL_H264_L3, 30, 40500, 1620, 8100, 10000 }, - { GST_VAAPI_LEVEL_H264_L3_1, 31, 108000, 3600, 18000, 14000 }, - { GST_VAAPI_LEVEL_H264_L3_2, 32, 216000, 5120, 20480, 20000 }, - { GST_VAAPI_LEVEL_H264_L4, 40, 245760, 8192, 32768, 20000 }, - { GST_VAAPI_LEVEL_H264_L4_1, 41, 245760, 8192, 32768, 50000 }, - { GST_VAAPI_LEVEL_H264_L4_2, 42, 522240, 8704, 34816, 50000 }, - { GST_VAAPI_LEVEL_H264_L5, 50, 589824, 22080, 110400, 135000 }, - { GST_VAAPI_LEVEL_H264_L5_1, 51, 983040, 36864, 184320, 240000 }, - { GST_VAAPI_LEVEL_H264_L5_2, 52, 2073600, 36864, 184320, 240000 }, + /* level idc MaxMBPS MaxFS MaxDpbMbs MaxBR MaxCPB */ + { GST_VAAPI_LEVEL_H264_L1, 10, 1485, 99, 396, 64, 175 }, + { GST_VAAPI_LEVEL_H264_L1b, 11, 1485, 99, 396, 128, 350 }, + { GST_VAAPI_LEVEL_H264_L1_1, 11, 3000, 396, 900, 192, 500 }, + { GST_VAAPI_LEVEL_H264_L1_2, 12, 6000, 396, 2376, 384, 1000 }, + { GST_VAAPI_LEVEL_H264_L1_3, 13, 11880, 396, 2376, 768, 2000 }, + { GST_VAAPI_LEVEL_H264_L2, 20, 11880, 396, 2376, 2000, 2000 }, + { GST_VAAPI_LEVEL_H264_L2_1, 21, 19800, 792, 4752, 4000, 4000 }, + { GST_VAAPI_LEVEL_H264_L2_2, 22, 20250, 1620, 8100, 4000, 4000 }, + { GST_VAAPI_LEVEL_H264_L3, 30, 40500, 1620, 8100, 10000, 10000 }, + { GST_VAAPI_LEVEL_H264_L3_1, 31, 108000, 3600, 18000, 14000, 14000 }, + { GST_VAAPI_LEVEL_H264_L3_2, 32, 216000, 5120, 20480, 20000, 20000 }, + { GST_VAAPI_LEVEL_H264_L4, 40, 245760, 8192, 32768, 20000, 25000 }, + { GST_VAAPI_LEVEL_H264_L4_1, 41, 245760, 8192, 32768, 50000, 62500 }, + { GST_VAAPI_LEVEL_H264_L4_2, 42, 522240, 8704, 34816, 50000, 62500 }, + { GST_VAAPI_LEVEL_H264_L5, 50, 589824, 22080, 110400, 135000, 135000 }, + { GST_VAAPI_LEVEL_H264_L5_1, 51, 983040, 36864, 184320, 240000, 240000 }, + { GST_VAAPI_LEVEL_H264_L5_2, 52, 2073600, 36864, 184320, 240000, 240000 }, { 0, } }; /* *INDENT-ON* */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h index 1c7db35150..83957600dd 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h @@ -35,6 +35,7 @@ G_BEGIN_DECLS * @MaxFS: the maximum frame size (MBs) * @MaxDpbMbs: the maxium decoded picture buffer size (MBs) * @MaxBR: the maximum video bit rate (kbps) + * @MaxCPB: the maximum CPB size (kbits) * * The data structure that describes the limits of an H.264 level. */ @@ -46,6 +47,7 @@ typedef struct guint32 MaxFS; guint32 MaxDpbMbs; guint32 MaxBR; + guint32 MaxCPB; } GstVaapiH264LevelLimits; /* Returns GstVaapiProfile from H.264 profile_idc value */ From deff9c775c477ff80112ae11d080dea9a7f43c9d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 22 Jan 2014 17:07:24 +0100 Subject: [PATCH 1554/3781] encoder: h264: disable NAL HRD parameters for now. Don't emit NAL HRD parameters for now in the SPS headers because the SEI buffering_period() and picture_timing() messages are not handled yet. Some additional changes are necessary to get it right. https://bugzilla.gnome.org/show_bug.cgi?id=722734 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index c4421d929d..9b79455162 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -417,9 +417,9 @@ bs_write_sps (GstBitWriter * bs, WRITE_UINT32 (bs, 1, 1); /* fixed_frame_rate_flag */ } - nal_hrd_parameters_present_flag = - (seq_param->bits_per_second > 0 ? TRUE : FALSE); /* nal_hrd_parameters_present_flag */ + nal_hrd_parameters_present_flag = seq_param->bits_per_second > 0; + nal_hrd_parameters_present_flag = FALSE; /* XXX: disabled for now */ WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1); if (nal_hrd_parameters_present_flag) { /* hrd_parameters */ @@ -445,8 +445,10 @@ bs_write_sps (GstBitWriter * bs, /* time_offset_length */ WRITE_UINT32 (bs, 23, 5); } + /* vcl_hrd_parameters_present_flag */ WRITE_UINT32 (bs, 0, 1); + if (nal_hrd_parameters_present_flag || 0 /*vcl_hrd_parameters_present_flag */ ) { /* low_delay_hrd_flag */ From 0e8afe1c22d6fe942c3ed452761bae445af3da9c Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Fri, 17 Jan 2014 16:56:53 +0800 Subject: [PATCH 1555/3781] decoder: fix crash on invalid pointer for GST_DEBUG(). When decoding failed, or that the frame was dropped, the associated surface proxy is not guaranteed to be present. Thus, the GST_DEBUG() message needs to check whether the proxy is actually present or not. https://bugzilla.gnome.org/show_bug.cgi?id=722403 [fixed gst_vaapi_surface_proxy_get_surface_id() to return VA_INVALID_ID] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 8a8fa4cef4..8b05f7b820 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -394,7 +394,7 @@ pop_frame(GstVaapiDecoder *decoder, guint64 timeout) proxy = frame->user_data; GST_DEBUG("dequeue decoded surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy))); + GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id(proxy))); return frame; } diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 82432f087b..516cb13380 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -239,8 +239,8 @@ gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy) GstVaapiID gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) { - g_return_val_if_fail(proxy != NULL, 0); - g_return_val_if_fail(proxy->surface != NULL, 0); + g_return_val_if_fail(proxy != NULL, VA_INVALID_ID); + g_return_val_if_fail(proxy->surface != NULL, VA_INVALID_ID); return GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy); } From 387371b19fe1d7d19cfda68a8a5f6d8e619c20a9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 22 Jan 2014 18:11:26 +0100 Subject: [PATCH 1556/3781] decoder: fix video codec frame number in standalone mode. Set a valid GstVideoCodecFrame.system_frame_number when decoding a stream in standalone mode. While we are at it, improve the debugging messages to also include that frame number. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 9 +++++---- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 8b05f7b820..ac23127e94 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -315,6 +315,7 @@ decode_step(GstVaapiDecoder *decoder) if (!ps->current_frame) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; ps->current_frame->ref_count = 1; + ps->current_frame->system_frame_number = ps->current_frame_number++; } status = do_parse(decoder, ps->current_frame, ps->input_adapter, @@ -373,8 +374,8 @@ push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) { GstVaapiSurfaceProxy * const proxy = frame->user_data; - GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy))); + GST_DEBUG("push frame %d (surface 0x%08x)", frame->system_frame_number, + GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy)); g_async_queue_push(decoder->frames, gst_video_codec_frame_ref(frame)); } @@ -393,8 +394,8 @@ pop_frame(GstVaapiDecoder *decoder, guint64 timeout) return NULL; proxy = frame->user_data; - GST_DEBUG("dequeue decoded surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id(proxy))); + GST_DEBUG("pop frame %d (surface 0x%08x)", frame->system_frame_number, + proxy ? GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) : VA_INVALID_ID); return frame; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 6a689fc99e..e9b3fd3be7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -168,6 +168,7 @@ typedef enum { typedef struct _GstVaapiParserState GstVaapiParserState; struct _GstVaapiParserState { GstVideoCodecFrame *current_frame; + guint32 current_frame_number; GstAdapter *current_adapter; GstAdapter *input_adapter; gint input_offset1; From 1c95903b9800ee7ee614ca085f54ce9147d7f7e4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 22 Jan 2014 18:49:20 +0100 Subject: [PATCH 1557/3781] legal: add per-file authorship information. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 1 + gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 1 + gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 2 ++ gst/vaapi/gstvaapiencode.c | 2 ++ gst/vaapi/gstvaapiencode.h | 2 ++ gst/vaapi/gstvaapiencode_h264.c | 2 ++ gst/vaapi/gstvaapiencode_h264.h | 2 ++ gst/vaapi/gstvaapiencode_mpeg2.c | 2 ++ gst/vaapi/gstvaapiencode_mpeg2.h | 2 ++ 16 files changed, 30 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 7b3d00965b..a7d180baa3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -2,6 +2,8 @@ * gstvaapiencoder.c - VA encoder abstraction * * Copyright (C) 2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index e68925f7dd..e56ac2d3b2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -2,6 +2,8 @@ * gstvaapiencoder.h - VA encoder abstraction * * Copyright (C) 2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 9b79455162..0a92a9a702 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2,6 +2,8 @@ * gstvaapiencoder_h264.c - H.264 encoder * * Copyright (C) 2012-2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index d4a8a7c374..12fe0eb1de 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -2,6 +2,8 @@ * gstvaapiencoder_h264.h - H.264 encoder * * Copyright (C) 2011-2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 943325cbdc..484eb51c3f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -2,6 +2,8 @@ * gstvaapiencoder_mpeg2.c - MPEG-2 encoder * * Copyright (C) 2012-2013 Intel Corporation + * Author: Guangxin Xu + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h index 8392d1e3f1..d44d445f4b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -2,6 +2,8 @@ * gstvaapiencoder_mpeg2.h - MPEG-2 encoder * * Copyright (C) 2011-2013 Intel Corporation + * Author: Guangxin Xu + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h index f2e02dfaf3..275ee91306 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h @@ -2,6 +2,8 @@ * gstvaapiencoder_mpeg2_priv.h - MPEG-2 encoder (private definitions) * * Copyright (C) 2013 Intel Corporation + * Author: Guangxin Xu + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index 558356132f..00268e1918 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -2,6 +2,7 @@ * gstvaapiencoder_objects.c - VA encoder objects abstraction * * Copyright (C) 2013 Intel Corporation + * Author: Wind Yuan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index f97d4afabe..fe64239749 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -2,6 +2,7 @@ * gstvaapiencoder_objects.h - VA encoder objects abstraction * * Copyright (C) 2013 Intel Corporation + * Author: Wind Yuan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 43e5ad2c7d..8d7d4a559f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -2,6 +2,8 @@ * gstvaapiencoder_priv.h - VA encoder abstraction (private definitions) * * Copyright (C) 2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 9344f97af5..d9d09dc099 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -2,6 +2,8 @@ * gstvaapiencode.c - VA-API video encoder * * Copyright (C) 2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index cab65c0629..7500a3244e 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -2,6 +2,8 @@ * gstvaapiencode.h - VA-API video encoder * * Copyright (C) 2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 05edb447e6..930288d77f 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -2,6 +2,8 @@ * gstvaapiencode_h264.c - VA-API H.264 encoder * * Copyright (C) 2012-2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiencode_h264.h b/gst/vaapi/gstvaapiencode_h264.h index d30c065f80..32e94ab0ba 100644 --- a/gst/vaapi/gstvaapiencode_h264.h +++ b/gst/vaapi/gstvaapiencode_h264.h @@ -2,6 +2,8 @@ * gstvaapiencode_h264.h - VA-API H.264 encoder * * Copyright (C) 2012-2013 Intel Corporation + * Author: Wind Yuan + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index b84821c2c7..ea42ffb1f7 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -2,6 +2,8 @@ * gstvaapiencode_mpeg2.c - VA-API MPEG2 encoder * * Copyright (C) 2012-2013 Intel Corporation + * Author: Guangxin Xu + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/gst/vaapi/gstvaapiencode_mpeg2.h b/gst/vaapi/gstvaapiencode_mpeg2.h index 3904e985f9..c4b561ef3f 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.h +++ b/gst/vaapi/gstvaapiencode_mpeg2.h @@ -2,6 +2,8 @@ * gstvaapiencode_mpeg2.h - VA-API MPEG2 encoder * * Copyright (C) 2012-2013 Intel Corporation + * Author: Guangxin Xu + * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License From 6bf3c1863c4e4e51f17acbb63ca761d592025328 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 22 Jan 2014 18:54:14 +0100 Subject: [PATCH 1558/3781] legal: update copyright notice dates. --- gst-libs/gst/vaapi/glibcompat.h | 2 +- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 2 +- gst-libs/gst/vaapi/gstvaapicodec_objects.h | 2 +- gst-libs/gst/vaapi/gstvaapicodedbufferpool.c | 2 +- gst-libs/gst/vaapi/gstvaapicodedbufferpool.h | 2 +- gst-libs/gst/vaapi/gstvaapicontext.c | 2 +- gst-libs/gst/vaapi/gstvaapicontext.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder.h | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapifilter.c | 2 +- gst-libs/gst/vaapi/gstvaapipixmap_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 2 +- gst-libs/gst/vaapi/gstvaapitypes.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_h264.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapivalue.c | 2 +- gst-libs/gst/vaapi/gstvaapivalue.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 2 +- gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapiencode.c | 2 +- gst/vaapi/gstvaapiencode.h | 2 +- gst/vaapi/gstvaapiencode_h264.c | 2 +- gst/vaapi/gstvaapiencode_h264.h | 2 +- gst/vaapi/gstvaapiencode_mpeg2.c | 2 +- gst/vaapi/gstvaapiencode_mpeg2.h | 2 +- gst/vaapi/gstvaapipluginbase.c | 2 +- gst/vaapi/gstvaapipluginutil.c | 2 +- gst/vaapi/gstvaapipluginutil.h | 2 +- gst/vaapi/gstvaapipostproc.c | 2 +- gst/vaapi/gstvaapipostproc.h | 2 +- gst/vaapi/gstvaapisink.c | 2 +- gst/vaapi/gstvaapisink.h | 2 +- gst/vaapi/gstvaapivideometa_texture.c | 2 +- tests/simple-decoder.c | 2 +- 55 files changed, 55 insertions(+), 55 deletions(-) diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 34e4791467..734d6e4824 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -1,7 +1,7 @@ /* * glibcompat.h - System-dependent definitions * - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 26c0c04737..d72c176f9b 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index 10d4582c9d..c7b7902015 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c index 44b2e3d7b6..ef12849574 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c @@ -1,7 +1,7 @@ /* * gstvaapicodedbufferpool.c - VA coded buffer pool * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.h b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.h index 0185ee3806..c8b9e1ba10 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.h +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.h @@ -1,7 +1,7 @@ /* * gstvaapicodedbufferpool.h - VA coded buffer pool * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 52e9317da1..2af1a84f6e 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 22ce752786..a5a5c07ea2 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index ac23127e94..1cd81ee479 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index b523cbccdd..94ebae9cae 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1,7 +1,7 @@ /* * gstvaapidecoder_h264.c - H.264 decoder * - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 33cbb92308..f3fb782990 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 7908461081..91e73214e8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index e9b3fd3be7..5590d82f39 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index a7d180baa3..3af06ea3a2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1,7 +1,7 @@ /* * gstvaapiencoder.c - VA encoder abstraction * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Wind Yuan * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index e56ac2d3b2..0ae80b69fb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -1,7 +1,7 @@ /* * gstvaapiencoder.h - VA encoder abstraction * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Wind Yuan * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 0a92a9a702..ec544daf77 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1,7 +1,7 @@ /* * gstvaapiencoder_h264.c - H.264 encoder * - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Wind Yuan * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 12fe0eb1de..3eaa3cb1e8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -1,7 +1,7 @@ /* * gstvaapiencoder_h264.h - H.264 encoder * - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Wind Yuan * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 484eb51c3f..95c864de40 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -1,7 +1,7 @@ /* * gstvaapiencoder_mpeg2.c - MPEG-2 encoder * - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Guangxin Xu * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h index d44d445f4b..923ad1d85a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -1,7 +1,7 @@ /* * gstvaapiencoder_mpeg2.h - MPEG-2 encoder * - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Guangxin Xu * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h index 275ee91306..cded80d40d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h @@ -1,7 +1,7 @@ /* * gstvaapiencoder_mpeg2_priv.h - MPEG-2 encoder (private definitions) * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Guangxin Xu * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index 00268e1918..a9ed0fa813 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -1,7 +1,7 @@ /* * gstvaapiencoder_objects.c - VA encoder objects abstraction * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Wind Yuan * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index fe64239749..dca1cda01c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -1,7 +1,7 @@ /* * gstvaapiencoder_objects.h - VA encoder objects abstraction * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Wind Yuan * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 8d7d4a559f..6106758813 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -1,7 +1,7 @@ /* * gstvaapiencoder_priv.h - VA encoder abstraction (private definitions) * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Wind Yuan * Author: Gwenole Beauchesne * diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index c6e02fa07b..c201643563 100755 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1,7 +1,7 @@ /* * gstvaapifilter.c - Video processing abstraction * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c index ac84a76739..044feaa346 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c +++ b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c @@ -1,7 +1,7 @@ /* * gstvaapipixmap_x11.c - X11 pixmap abstraction * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 902926dd28..40745ba429 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 5ddfd0116c..48f86622e3 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 516cb13380..cb014dae68 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 159b85b31b..ccdddbfa06 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index daa9fc28b2..a74da40468 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index 20da57ceef..118895d910 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -1,7 +1,7 @@ /* * gstvaapiutils_h264.c - H.264 related utilities * - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.h b/gst-libs/gst/vaapi/gstvaapiutils_h264.h index 3f2867d01e..785f169dc6 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.h @@ -1,7 +1,7 @@ /* * gstvaapiutils_h264.h - H.264 related utilities * - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h index 83957600dd..5bfbf874b0 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h @@ -1,7 +1,7 @@ /* * gstvaapiutils_h264_priv.h - H.264 related utilities * - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c index 35003ce38a..de170e8e41 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c @@ -1,7 +1,7 @@ /* * gstvaapiutils_mpeg2.c - MPEG-2 related utilities * - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h index 8a3d8974b9..76c3bd8c7f 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h @@ -1,7 +1,7 @@ /* * gstvaapiutils_mpeg2.h - MPEG-2 related utilities * - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h index d29d2cbd89..179fed3e2b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h @@ -1,7 +1,7 @@ /* * gstvaapiutils_mpeg2_priv.h - MPEG-2 related utilities * - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 07d99233b4..fa825fd60d 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index 2f6f431b54..e7d445a1a2 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index d027eaec59..24cd29b554 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index f0a51708a5..482033ee6b 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 5d45b025a0..98d7916838 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index d9d09dc099..28f4fada5d 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -1,7 +1,7 @@ /* * gstvaapiencode.c - VA-API video encoder * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Wind Yuan * Author: Gwenole Beauchesne * diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 7500a3244e..a4208a2044 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -1,7 +1,7 @@ /* * gstvaapiencode.h - VA-API video encoder * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Wind Yuan * Author: Gwenole Beauchesne * diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 930288d77f..6a36e61d64 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -1,7 +1,7 @@ /* * gstvaapiencode_h264.c - VA-API H.264 encoder * - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Wind Yuan * Author: Gwenole Beauchesne * diff --git a/gst/vaapi/gstvaapiencode_h264.h b/gst/vaapi/gstvaapiencode_h264.h index 32e94ab0ba..cab73d77ec 100644 --- a/gst/vaapi/gstvaapiencode_h264.h +++ b/gst/vaapi/gstvaapiencode_h264.h @@ -1,7 +1,7 @@ /* * gstvaapiencode_h264.h - VA-API H.264 encoder * - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Wind Yuan * Author: Gwenole Beauchesne * diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index ea42ffb1f7..95c0edc145 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -1,7 +1,7 @@ /* * gstvaapiencode_mpeg2.c - VA-API MPEG2 encoder * - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Guangxin Xu * Author: Gwenole Beauchesne * diff --git a/gst/vaapi/gstvaapiencode_mpeg2.h b/gst/vaapi/gstvaapiencode_mpeg2.h index c4b561ef3f..a2038df62a 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.h +++ b/gst/vaapi/gstvaapiencode_mpeg2.h @@ -1,7 +1,7 @@ /* * gstvaapiencode_mpeg2.h - VA-API MPEG2 encoder * - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Guangxin Xu * Author: Gwenole Beauchesne * diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 1c0bc1a41d..a637b36c7a 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index e9790eef9f..b53e3596ce 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1,7 +1,7 @@ /* * gstvaapipluginutil.h - VA-API plugin helpers * - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * Copyright (C) 2011 Collabora * Author: Nicolas Dufresne diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 0276998057..4fc7450417 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -1,7 +1,7 @@ /* * gstvaapipluginutil.h - VA-API plugins private helper * - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * Copyright (C) 2011 Collabora * Author: Nicolas Dufresne diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6abcfb88c0..f1be89c68f 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1,7 +1,7 @@ /* * gstvaapipostproc.c - VA-API video postprocessing * - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 7159b53375..5b23c36910 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -1,7 +1,7 @@ /* * gstvaapipostproc.h - VA-API video post processing * - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Gwenole Beauchesne * * This program is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 36c35bd894..d9fd70371e 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 832689e3d4..edd9c1487d 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index bb7bcea826..371927d0cd 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation + * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne * Copyright (C) 2013 Igalia * Author: Víctor Manuel Jáquez Leal diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index bba4f852f1..b8af44d7cd 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -1,7 +1,7 @@ /* * simple-decoder.c - Simple Decoder Application * - * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or From ed302d091e9b28b68ca1b7c2cee8ecdbc4e7608e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 22 Jan 2014 19:04:58 +0100 Subject: [PATCH 1559/3781] Bump library major version. Bump the library major version due to API/ABI changes that occurred in the imaging API. In particular, GstVaapiDisplay interfaces no longer expose any GstCaps but provide GArray based ones e.g. to determine the set of supported decode/encode profiles. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index db40b5eb8a..3726f1e73f 100644 --- a/configure.ac +++ b/configure.ac @@ -10,11 +10,11 @@ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) ]) # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [4]) +m4_define([gst_vaapi_lt_current], [5]) m4_define([gst0_vaapi_lt_current_bias], [0]) m4_define([gst1_vaapi_lt_current_bias], [2]) m4_define([gst2_vaapi_lt_current_bias], [4]) -m4_define([gst4_vaapi_lt_current_bias], [4]) +m4_define([gst4_vaapi_lt_current_bias], [5]) m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [0]) From c5bdeb698018f72ef2a4855a0ef2e5a906ec6c74 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 10:20:40 +0100 Subject: [PATCH 1560/3781] libs: check that private headers remain private. Make sure that libgstvaapi private headers remain internally used to build libgstvaapi libraries only. All header dependencies were reviewed and checks for IN_LIBGSTVAAPI definition were added accordingly. Also rename GST_VAAPI_CORE definition to IN_LIBGSTVAAPI_CORE to keep consistency. --- gst-libs/gst/vaapi/Makefile.am | 8 +++++++- gst-libs/gst/vaapi/gstvaapidecoder_unit.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplaycache.h | 1 + gst-libs/gst/vaapi/gstvaapiminiobject.h | 1 + gst-libs/gst/vaapi/gstvaapiobject_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapipixmap_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiutils.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_glx.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_x11.h | 1 + gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 2 +- 13 files changed, 20 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 390d91eb92..11efb4b63e 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -20,7 +20,8 @@ libgstvaapi_includedir = \ $(includedir)/gstreamer-$(GST_API_VERSION)/gst/vaapi libgstvaapi_cflags = \ - -DGST_VAAPI_CORE \ + -DIN_LIBGSTVAAPI \ + -DIN_LIBGSTVAAPI_CORE \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ -I$(top_builddir)/gst-libs \ @@ -130,6 +131,7 @@ libgstvaapi_source_priv_h = \ gstvaapivideopool_priv.h \ gstvaapiwindow_priv.h \ gstvaapiworkarounds.h \ + libgstvaapi_priv_check.h \ sysdeps.h \ $(NULL) @@ -291,6 +293,7 @@ libgstvaapi_drm_@GST_API_VERSION@includedir = \ $(libgstvaapi_includedir) libgstvaapi_drm_@GST_API_VERSION@_la_CFLAGS = \ + -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ @@ -327,6 +330,7 @@ libgstvaapi_x11_@GST_API_VERSION@includedir = \ $(libgstvaapi_includedir) libgstvaapi_x11_@GST_API_VERSION@_la_CFLAGS = \ + -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ @@ -365,6 +369,7 @@ libgstvaapi_glx_@GST_API_VERSION@includedir = \ $(libgstvaapi_includedir) libgstvaapi_glx_@GST_API_VERSION@_la_CFLAGS = \ + -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ @@ -402,6 +407,7 @@ libgstvaapi_wayland_@GST_API_VERSION@includedir = \ $(libgstvaapi_includedir) libgstvaapi_wayland_@GST_API_VERSION@_la_CFLAGS = \ + -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h index 7ee77a05cf..32fa9bb458 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h @@ -23,6 +23,8 @@ #ifndef GST_VAAPI_DECODER_UNIT_H #define GST_VAAPI_DECODER_UNIT_H +#include "libgstvaapi_priv_check.h" + G_BEGIN_DECLS typedef struct _GstVaapiDecoderUnit GstVaapiDecoderUnit; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 1d1396427b..92d466aa8c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -227,7 +227,7 @@ gst_vaapi_display_get_display_types (GstVaapiDisplay * display) } /* Inline reference counting for core libgstvaapi library */ -#ifdef GST_VAAPI_CORE +#ifdef IN_LIBGSTVAAPI_CORE #define gst_vaapi_display_ref_internal(display) \ ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(display))) diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h index bbd2436735..62f7b901c3 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.h +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.h @@ -23,6 +23,7 @@ #ifndef GSTVAAPIDISPLAYCACHE_H #define GSTVAAPIDISPLAYCACHE_H +#include "libgstvaapi_priv_check.h" #include typedef struct _GstVaapiDisplayCache GstVaapiDisplayCache; diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.h b/gst-libs/gst/vaapi/gstvaapiminiobject.h index 5f5ada948d..058378d470 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.h @@ -24,6 +24,7 @@ #define GST_VAAPI_MINI_OBJECT_H #include +#include "libgstvaapi_priv_check.h" G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 4c91149c9f..f6f3a5860c 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -219,7 +219,7 @@ gst_vaapi_object_new(const GstVaapiObjectClass *klass, GstVaapiDisplay *display); /* Inline reference counting for core libgstvaapi library */ -#ifdef GST_VAAPI_CORE +#ifdef IN_LIBGSTVAAPI_CORE static inline gpointer gst_vaapi_object_ref_internal(gpointer object) { diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_priv.h b/gst-libs/gst/vaapi/gstvaapipixmap_priv.h index 577fda884b..9219bf6596 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_priv.h +++ b/gst-libs/gst/vaapi/gstvaapipixmap_priv.h @@ -109,7 +109,7 @@ gst_vaapi_pixmap_new_from_native(const GstVaapiPixmapClass *pixmap_class, GstVaapiDisplay *display, gpointer native_pixmap); /* Inline reference counting for core libgstvaapi library */ -#ifdef GST_VAAPI_CORE +#ifdef IN_LIBGSTVAAPI_CORE #define gst_vaapi_pixmap_ref_internal(pixmap) \ ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pixmap))) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 21d13c2665..9fcab47146 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -26,6 +26,7 @@ #define GST_VAAPI_UTILS_H #include "config.h" +#include "libgstvaapi_priv_check.h" #include #include diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 5d4f75a727..3df92ae8e4 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -26,6 +26,7 @@ #define GST_VAAPI_UTILS_GLX_H #include "config.h" +#include "libgstvaapi_priv_check.h" #include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h index 5bfbf874b0..85eb184c9e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h @@ -24,6 +24,7 @@ #define GST_VAAPI_UTILS_H264_PRIV_H #include "gstvaapiutils_h264.h" +#include "libgstvaapi_priv_check.h" G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h index 179fed3e2b..3f96eca6ac 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h @@ -24,6 +24,7 @@ #define GST_VAAPI_UTILS_MPEG2_PRIV_H #include "gstvaapiutils_mpeg2.h" +#include "libgstvaapi_priv_check.h" G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index 1229b34cff..f6faf257fc 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -26,6 +26,7 @@ #define GST_VAAPI_UTILS_X11_H #include "config.h" +#include "libgstvaapi_priv_check.h" #include #include diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index f0dc9a51be..3abf421e02 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -108,7 +108,7 @@ gst_vaapi_window_new_from_native(const GstVaapiWindowClass *window_class, GstVaapiDisplay *display, gpointer native_window); /* Inline reference counting for core libgstvaapi library */ -#ifdef GST_VAAPI_CORE +#ifdef IN_LIBGSTVAAPI_CORE #define gst_vaapi_window_ref_internal(window) \ ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(window))) From 1ffdc010ad0186d11c80fbc4913834cdd1bdaf45 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 09:27:38 +0100 Subject: [PATCH 1561/3781] context: re-indent all GstVaapiContext related source code. --- gst-libs/gst/vaapi/gstvaapicontext.c | 1136 +++++++++++++------------- gst-libs/gst/vaapi/gstvaapicontext.h | 77 +- 2 files changed, 584 insertions(+), 629 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 2af1a84f6e..50baafd3c9 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -44,23 +44,24 @@ #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiContextClass GstVaapiContextClass; +typedef struct _GstVaapiContextClass GstVaapiContextClass; /** * GstVaapiContext: * * A VA context wrapper. */ -struct _GstVaapiContext { - /*< private >*/ - GstVaapiObject parent_instance; +struct _GstVaapiContext +{ + /*< private >*/ + GstVaapiObject parent_instance; - GstVaapiContextInfo info; - VAConfigID config_id; - GPtrArray *surfaces; - GstVaapiVideoPool *surfaces_pool; - GPtrArray *overlays[2]; - guint overlay_id; + GstVaapiContextInfo info; + VAConfigID config_id; + GPtrArray *surfaces; + GstVaapiVideoPool *surfaces_pool; + GPtrArray *overlays[2]; + guint overlay_id; }; /** @@ -68,42 +69,50 @@ struct _GstVaapiContext { * * A VA context wrapper class. */ -struct _GstVaapiContextClass { - /*< private >*/ - GstVaapiObjectClass parent_class; +struct _GstVaapiContextClass +{ + /*< private >*/ + GstVaapiObjectClass parent_class; }; typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle; -struct _GstVaapiOverlayRectangle { - GstVaapiContext *context; - GstVaapiSubpicture *subpicture; - GstVaapiRectangle render_rect; - guint seq_num; - guint layer_id; - GstBuffer *rect_buffer; - GstVideoOverlayRectangle *rect; - guint is_associated : 1; +struct _GstVaapiOverlayRectangle +{ + GstVaapiContext *context; + GstVaapiSubpicture *subpicture; + GstVaapiRectangle render_rect; + guint seq_num; + guint layer_id; + GstBuffer *rect_buffer; + GstVideoOverlayRectangle *rect; + guint is_associated:1; }; static guint -get_max_ref_frames(GstVaapiProfile profile) +get_max_ref_frames (GstVaapiProfile profile) { - guint ref_frames; + guint ref_frames; - switch (gst_vaapi_profile_get_codec(profile)) { - case GST_VAAPI_CODEC_H264: ref_frames = 16; break; - case GST_VAAPI_CODEC_JPEG: ref_frames = 0; break; - default: ref_frames = 2; break; - } - return ref_frames; + switch (gst_vaapi_profile_get_codec (profile)) { + case GST_VAAPI_CODEC_H264: + ref_frames = 16; + break; + case GST_VAAPI_CODEC_JPEG: + ref_frames = 0; + break; + default: + ref_frames = 2; + break; + } + return ref_frames; } static inline void -gst_video_overlay_rectangle_replace(GstVideoOverlayRectangle **old_rect_ptr, - GstVideoOverlayRectangle *new_rect) +gst_video_overlay_rectangle_replace (GstVideoOverlayRectangle ** old_rect_ptr, + GstVideoOverlayRectangle * new_rect) { - gst_mini_object_replace((GstMiniObject **)old_rect_ptr, - GST_MINI_OBJECT_CAST(new_rect)); + gst_mini_object_replace ((GstMiniObject **) old_rect_ptr, + GST_MINI_OBJECT_CAST (new_rect)); } #define overlay_rectangle_ref(overlay) \ @@ -116,532 +125,507 @@ gst_video_overlay_rectangle_replace(GstVideoOverlayRectangle **old_rect_ptr, gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_overlay_ptr), \ (GstVaapiMiniObject *)(new_overlay)) -static void -overlay_rectangle_finalize(GstVaapiOverlayRectangle *overlay); +static void overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay); static gboolean -overlay_rectangle_associate(GstVaapiOverlayRectangle *overlay); +overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay); static gboolean -overlay_rectangle_deassociate(GstVaapiOverlayRectangle *overlay); +overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay); static inline const GstVaapiMiniObjectClass * -overlay_rectangle_class(void) +overlay_rectangle_class (void) { - static const GstVaapiMiniObjectClass GstVaapiOverlayRectangleClass = { - sizeof(GstVaapiOverlayRectangle), - (GDestroyNotify)overlay_rectangle_finalize - }; - return &GstVaapiOverlayRectangleClass; + static const GstVaapiMiniObjectClass GstVaapiOverlayRectangleClass = { + sizeof (GstVaapiOverlayRectangle), + (GDestroyNotify) overlay_rectangle_finalize + }; + return &GstVaapiOverlayRectangleClass; } static GstVaapiOverlayRectangle * -overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context, - guint layer_id) +overlay_rectangle_new (GstVideoOverlayRectangle * rect, + GstVaapiContext * context, guint layer_id) { - GstVaapiOverlayRectangle *overlay; - GstVaapiRectangle *render_rect; - guint width, height, flags; - gint x, y; + GstVaapiOverlayRectangle *overlay; + GstVaapiRectangle *render_rect; + guint width, height, flags; + gint x, y; - overlay = (GstVaapiOverlayRectangle *) - gst_vaapi_mini_object_new0(overlay_rectangle_class()); - if (!overlay) - return NULL; + overlay = (GstVaapiOverlayRectangle *) + gst_vaapi_mini_object_new0 (overlay_rectangle_class ()); + if (!overlay) + return NULL; - overlay->context = context; - overlay->seq_num = gst_video_overlay_rectangle_get_seqnum(rect); - overlay->layer_id = layer_id; - overlay->rect = gst_video_overlay_rectangle_ref(rect); + overlay->context = context; + overlay->seq_num = gst_video_overlay_rectangle_get_seqnum (rect); + overlay->layer_id = layer_id; + overlay->rect = gst_video_overlay_rectangle_ref (rect); - flags = gst_video_overlay_rectangle_get_flags(rect); - gst_buffer_replace(&overlay->rect_buffer, - gst_video_overlay_rectangle_get_pixels_unscaled_raw(rect, flags)); - if (!overlay->rect_buffer) - goto error; + flags = gst_video_overlay_rectangle_get_flags (rect); + gst_buffer_replace (&overlay->rect_buffer, + gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags)); + if (!overlay->rect_buffer) + goto error; - overlay->subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle( - GST_VAAPI_OBJECT_DISPLAY(context), rect); - if (!overlay->subpicture) - goto error; + overlay->subpicture = + gst_vaapi_subpicture_new_from_overlay_rectangle (GST_VAAPI_OBJECT_DISPLAY + (context), rect); + if (!overlay->subpicture) + goto error; - gst_video_overlay_rectangle_get_render_rectangle(rect, - &x, &y, &width, &height); - render_rect = &overlay->render_rect; - render_rect->x = x; - render_rect->y = y; - render_rect->width = width; - render_rect->height = height; - return overlay; + gst_video_overlay_rectangle_get_render_rectangle (rect, + &x, &y, &width, &height); + render_rect = &overlay->render_rect; + render_rect->x = x; + render_rect->y = y; + render_rect->width = width; + render_rect->height = height; + return overlay; error: - overlay_rectangle_unref(overlay); - return NULL; + overlay_rectangle_unref (overlay); + return NULL; } static void -overlay_rectangle_finalize(GstVaapiOverlayRectangle *overlay) +overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay) { - gst_buffer_replace(&overlay->rect_buffer, NULL); - gst_video_overlay_rectangle_unref(overlay->rect); + gst_buffer_replace (&overlay->rect_buffer, NULL); + gst_video_overlay_rectangle_unref (overlay->rect); - if (overlay->subpicture) { - overlay_rectangle_deassociate(overlay); - gst_vaapi_object_unref(overlay->subpicture); - overlay->subpicture = NULL; - } + if (overlay->subpicture) { + overlay_rectangle_deassociate (overlay); + gst_vaapi_object_unref (overlay->subpicture); + overlay->subpicture = NULL; + } } static gboolean -overlay_rectangle_associate(GstVaapiOverlayRectangle *overlay) +overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay) { - GstVaapiSubpicture * const subpicture = overlay->subpicture; - GPtrArray * const surfaces = overlay->context->surfaces; - guint i, n_associated; + GstVaapiSubpicture *const subpicture = overlay->subpicture; + GPtrArray *const surfaces = overlay->context->surfaces; + guint i, n_associated; - if (overlay->is_associated) - return TRUE; + if (overlay->is_associated) + return TRUE; - n_associated = 0; - for (i = 0; i < surfaces->len; i++) { - GstVaapiSurface * const surface = g_ptr_array_index(surfaces, i); - if (gst_vaapi_surface_associate_subpicture(surface, subpicture, - NULL, &overlay->render_rect)) - n_associated++; - } + n_associated = 0; + for (i = 0; i < surfaces->len; i++) { + GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i); + if (gst_vaapi_surface_associate_subpicture (surface, subpicture, + NULL, &overlay->render_rect)) + n_associated++; + } - overlay->is_associated = TRUE; - return n_associated == surfaces->len; + overlay->is_associated = TRUE; + return n_associated == surfaces->len; } static gboolean -overlay_rectangle_deassociate(GstVaapiOverlayRectangle *overlay) +overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay) { - GstVaapiSubpicture * const subpicture = overlay->subpicture; - GPtrArray * const surfaces = overlay->context->surfaces; - guint i, n_associated; + GstVaapiSubpicture *const subpicture = overlay->subpicture; + GPtrArray *const surfaces = overlay->context->surfaces; + guint i, n_associated; - if (!overlay->is_associated) - return TRUE; + if (!overlay->is_associated) + return TRUE; - n_associated = surfaces->len; - for (i = 0; i < surfaces->len; i++) { - GstVaapiSurface * const surface = g_ptr_array_index(surfaces, i); - if (gst_vaapi_surface_deassociate_subpicture(surface, subpicture)) - n_associated--; - } + n_associated = surfaces->len; + for (i = 0; i < surfaces->len; i++) { + GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i); + if (gst_vaapi_surface_deassociate_subpicture (surface, subpicture)) + n_associated--; + } - overlay->is_associated = FALSE; - return n_associated == 0; + overlay->is_associated = FALSE; + return n_associated == 0; } static gboolean -overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay, - GstVideoOverlayRectangle *rect) +overlay_rectangle_changed_pixels (GstVaapiOverlayRectangle * overlay, + GstVideoOverlayRectangle * rect) { - guint flags; - GstBuffer *buffer; + guint flags; + GstBuffer *buffer; - if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum(rect)) - return FALSE; + if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum (rect)) + return FALSE; - flags = to_GstVideoOverlayFormatFlags( - gst_vaapi_subpicture_get_flags(overlay->subpicture)); + flags = + to_GstVideoOverlayFormatFlags (gst_vaapi_subpicture_get_flags + (overlay->subpicture)); - buffer = gst_video_overlay_rectangle_get_pixels_unscaled_raw(rect, flags); - if (!buffer) - return FALSE; + buffer = gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags); + if (!buffer) + return FALSE; #if GST_CHECK_VERSION(1,0,0) - { - const guint n_blocks = gst_buffer_n_memory(buffer); - gsize ofs; - guint i; + { + const guint n_blocks = gst_buffer_n_memory (buffer); + gsize ofs; + guint i; - if (buffer == overlay->rect_buffer) - return TRUE; + if (buffer == overlay->rect_buffer) + return TRUE; - if (n_blocks != gst_buffer_n_memory(overlay->rect_buffer)) - return FALSE; + if (n_blocks != gst_buffer_n_memory (overlay->rect_buffer)) + return FALSE; - for (i = 0; i < n_blocks; i++) { - GstMemory * const mem1 = gst_buffer_peek_memory(buffer, i); - GstMemory * const mem2 = - gst_buffer_peek_memory(overlay->rect_buffer, i); - if (!gst_memory_is_span(mem1, mem2, &ofs)) - return FALSE; - } - } -#else - if (GST_BUFFER_DATA(overlay->rect_buffer) != GST_BUFFER_DATA(buffer)) + for (i = 0; i < n_blocks; i++) { + GstMemory *const mem1 = gst_buffer_peek_memory (buffer, i); + GstMemory *const mem2 = gst_buffer_peek_memory (overlay->rect_buffer, i); + if (!gst_memory_is_span (mem1, mem2, &ofs)) return FALSE; + } + } +#else + if (GST_BUFFER_DATA (overlay->rect_buffer) != GST_BUFFER_DATA (buffer)) + return FALSE; #endif - return TRUE; + return TRUE; } static gboolean -overlay_rectangle_changed_render_rect(GstVaapiOverlayRectangle *overlay, - GstVideoOverlayRectangle *rect) +overlay_rectangle_changed_render_rect (GstVaapiOverlayRectangle * overlay, + GstVideoOverlayRectangle * rect) { - GstVaapiRectangle * const render_rect = &overlay->render_rect; - guint width, height; - gint x, y; + GstVaapiRectangle *const render_rect = &overlay->render_rect; + guint width, height; + gint x, y; - gst_video_overlay_rectangle_get_render_rectangle(rect, - &x, &y, &width, &height); + gst_video_overlay_rectangle_get_render_rectangle (rect, + &x, &y, &width, &height); - if (x == render_rect->x && - y == render_rect->y && - width == render_rect->width && - height == render_rect->height) - return FALSE; + if (x == render_rect->x && + y == render_rect->y && + width == render_rect->width && height == render_rect->height) + return FALSE; - render_rect->x = x; - render_rect->y = y; - render_rect->width = width; - render_rect->height = height; - return TRUE; + render_rect->x = x; + render_rect->y = y; + render_rect->width = width; + render_rect->height = height; + return TRUE; } static inline gboolean -overlay_rectangle_update_global_alpha(GstVaapiOverlayRectangle *overlay, - GstVideoOverlayRectangle *rect) +overlay_rectangle_update_global_alpha (GstVaapiOverlayRectangle * overlay, + GstVideoOverlayRectangle * rect) { #ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS - const guint flags = gst_video_overlay_rectangle_get_flags(rect); - if (!(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)) - return TRUE; + const guint flags = gst_video_overlay_rectangle_get_flags (rect); + if (!(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)) + return TRUE; #endif - return gst_vaapi_subpicture_set_global_alpha(overlay->subpicture, - gst_video_overlay_rectangle_get_global_alpha(rect)); + return gst_vaapi_subpicture_set_global_alpha (overlay->subpicture, + gst_video_overlay_rectangle_get_global_alpha (rect)); } static gboolean -overlay_rectangle_update(GstVaapiOverlayRectangle *overlay, - GstVideoOverlayRectangle *rect, gboolean *reassociate_ptr) +overlay_rectangle_update (GstVaapiOverlayRectangle * overlay, + GstVideoOverlayRectangle * rect, gboolean * reassociate_ptr) { - if (overlay_rectangle_changed_pixels(overlay, rect)) - return FALSE; - if (overlay_rectangle_changed_render_rect(overlay, rect)) - *reassociate_ptr = TRUE; - if (!overlay_rectangle_update_global_alpha(overlay, rect)) - return FALSE; - gst_video_overlay_rectangle_replace(&overlay->rect, rect); - return TRUE; + if (overlay_rectangle_changed_pixels (overlay, rect)) + return FALSE; + if (overlay_rectangle_changed_render_rect (overlay, rect)) + *reassociate_ptr = TRUE; + if (!overlay_rectangle_update_global_alpha (overlay, rect)) + return FALSE; + gst_video_overlay_rectangle_replace (&overlay->rect, rect); + return TRUE; } static inline GPtrArray * -overlay_new(void) +overlay_new (void) { - return g_ptr_array_new_with_free_func( - (GDestroyNotify)gst_vaapi_mini_object_unref); + return g_ptr_array_new_with_free_func ( + (GDestroyNotify) gst_vaapi_mini_object_unref); } static void -overlay_destroy(GPtrArray **overlay_ptr) +overlay_destroy (GPtrArray ** overlay_ptr) { - GPtrArray * const overlay = *overlay_ptr; + GPtrArray *const overlay = *overlay_ptr; - if (!overlay) - return; - g_ptr_array_unref(overlay); - *overlay_ptr = NULL; + if (!overlay) + return; + g_ptr_array_unref (overlay); + *overlay_ptr = NULL; } static void -overlay_clear(GPtrArray *overlay) +overlay_clear (GPtrArray * overlay) { - if (overlay && overlay->len > 0) - g_ptr_array_remove_range(overlay, 0, overlay->len); + if (overlay && overlay->len > 0) + g_ptr_array_remove_range (overlay, 0, overlay->len); } static GstVaapiOverlayRectangle * -overlay_lookup(GPtrArray *overlays, GstVideoOverlayRectangle *rect) +overlay_lookup (GPtrArray * overlays, GstVideoOverlayRectangle * rect) { - guint i; + guint i; - for (i = 0; i < overlays->len; i++) { - GstVaapiOverlayRectangle * const overlay = - g_ptr_array_index(overlays, i); + for (i = 0; i < overlays->len; i++) { + GstVaapiOverlayRectangle *const overlay = g_ptr_array_index (overlays, i); - if (overlay->rect == rect) - return overlay; - } - return NULL; + if (overlay->rect == rect) + return overlay; + } + return NULL; } static gboolean -overlay_reassociate(GPtrArray *overlays) +overlay_reassociate (GPtrArray * overlays) { - guint i; + guint i; - for (i = 0; i < overlays->len; i++) - overlay_rectangle_deassociate(g_ptr_array_index(overlays, i)); + for (i = 0; i < overlays->len; i++) + overlay_rectangle_deassociate (g_ptr_array_index (overlays, i)); - for (i = 0; i < overlays->len; i++) { - if (!overlay_rectangle_associate(g_ptr_array_index(overlays, i))) - return FALSE; - } - return TRUE; + for (i = 0; i < overlays->len; i++) { + if (!overlay_rectangle_associate (g_ptr_array_index (overlays, i))) + return FALSE; + } + return TRUE; } static void -gst_vaapi_context_clear_overlay(GstVaapiContext *context) +gst_vaapi_context_clear_overlay (GstVaapiContext * context) { - overlay_clear(context->overlays[0]); - overlay_clear(context->overlays[1]); - context->overlay_id = 0; + overlay_clear (context->overlays[0]); + overlay_clear (context->overlays[1]); + context->overlay_id = 0; } static inline void -gst_vaapi_context_destroy_overlay(GstVaapiContext *context) +gst_vaapi_context_destroy_overlay (GstVaapiContext * context) { - gst_vaapi_context_clear_overlay(context); + gst_vaapi_context_clear_overlay (context); } static void -unref_surface_cb(gpointer data, gpointer user_data) +unref_surface_cb (gpointer data, gpointer user_data) { - GstVaapiSurface * const surface = GST_VAAPI_SURFACE(data); + GstVaapiSurface *const surface = GST_VAAPI_SURFACE (data); - gst_vaapi_surface_set_parent_context(surface, NULL); - gst_vaapi_object_unref(surface); + gst_vaapi_surface_set_parent_context (surface, NULL); + gst_vaapi_object_unref (surface); } static void -gst_vaapi_context_destroy_surfaces(GstVaapiContext *context) +gst_vaapi_context_destroy_surfaces (GstVaapiContext * context) { - gst_vaapi_context_destroy_overlay(context); + gst_vaapi_context_destroy_overlay (context); - if (context->surfaces) { - g_ptr_array_foreach(context->surfaces, unref_surface_cb, NULL); - g_ptr_array_free(context->surfaces, TRUE); - context->surfaces = NULL; - } - gst_vaapi_video_pool_replace(&context->surfaces_pool, NULL); + if (context->surfaces) { + g_ptr_array_foreach (context->surfaces, unref_surface_cb, NULL); + g_ptr_array_free (context->surfaces, TRUE); + context->surfaces = NULL; + } + gst_vaapi_video_pool_replace (&context->surfaces_pool, NULL); } static void -gst_vaapi_context_destroy(GstVaapiContext *context) +gst_vaapi_context_destroy (GstVaapiContext * context) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context); - VAContextID context_id; - VAStatus status; + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); + VAContextID context_id; + VAStatus status; - context_id = GST_VAAPI_OBJECT_ID(context); - GST_DEBUG("context %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(context_id)); + context_id = GST_VAAPI_OBJECT_ID (context); + GST_DEBUG ("context %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (context_id)); - 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()")) - g_warning("failed to destroy context %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(context_id)); - GST_VAAPI_OBJECT_ID(context) = VA_INVALID_ID; - } + 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()")) + g_warning ("failed to destroy context %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (context_id)); + GST_VAAPI_OBJECT_ID (context) = VA_INVALID_ID; + } - if (context->config_id != VA_INVALID_ID) { - GST_VAAPI_DISPLAY_LOCK(display); - status = vaDestroyConfig( - GST_VAAPI_DISPLAY_VADISPLAY(display), - context->config_id - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaDestroyConfig()")) - g_warning("failed to destroy config %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(context->config_id)); - context->config_id = VA_INVALID_ID; - } + if (context->config_id != VA_INVALID_ID) { + GST_VAAPI_DISPLAY_LOCK (display); + status = vaDestroyConfig (GST_VAAPI_DISPLAY_VADISPLAY (display), + context->config_id); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaDestroyConfig()")) + g_warning ("failed to destroy config %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (context->config_id)); + context->config_id = VA_INVALID_ID; + } } static gboolean -gst_vaapi_context_create_overlay(GstVaapiContext *context) +gst_vaapi_context_create_overlay (GstVaapiContext * context) { - if (!context->overlays[0] || !context->overlays[1]) - return FALSE; + if (!context->overlays[0] || !context->overlays[1]) + return FALSE; - gst_vaapi_context_clear_overlay(context); - return TRUE; + gst_vaapi_context_clear_overlay (context); + return TRUE; } static gboolean -gst_vaapi_context_create_surfaces(GstVaapiContext *context) +gst_vaapi_context_create_surfaces (GstVaapiContext * context) { - const GstVaapiContextInfo * const cip = &context->info; - GstVideoInfo vi; - GstVaapiSurface *surface; - guint i, num_surfaces; + const GstVaapiContextInfo *const cip = &context->info; + GstVideoInfo vi; + GstVaapiSurface *surface; + guint i, num_surfaces; - /* Number of scratch surfaces beyond those used as reference */ - const guint SCRATCH_SURFACES_COUNT = 4; + /* Number of scratch surfaces beyond those used as reference */ + const guint SCRATCH_SURFACES_COUNT = 4; - if (!gst_vaapi_context_create_overlay(context)) - return FALSE; + if (!gst_vaapi_context_create_overlay (context)) + return FALSE; - if (!context->surfaces) { - context->surfaces = g_ptr_array_new(); - if (!context->surfaces) - return FALSE; - } + if (!context->surfaces) { + context->surfaces = g_ptr_array_new (); + if (!context->surfaces) + return FALSE; + } - if (!context->surfaces_pool) { - gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_ENCODED, - cip->width, cip->height); - context->surfaces_pool = gst_vaapi_surface_pool_new( - GST_VAAPI_OBJECT_DISPLAY(context), &vi); - if (!context->surfaces_pool) - return FALSE; - } + if (!context->surfaces_pool) { + gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_ENCODED, + cip->width, cip->height); + context->surfaces_pool = + gst_vaapi_surface_pool_new (GST_VAAPI_OBJECT_DISPLAY (context), &vi); + if (!context->surfaces_pool) + return FALSE; + } - num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; - gst_vaapi_video_pool_set_capacity(context->surfaces_pool, num_surfaces); + num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; + gst_vaapi_video_pool_set_capacity (context->surfaces_pool, num_surfaces); - for (i = context->surfaces->len; i < num_surfaces; i++) { - surface = gst_vaapi_surface_new( - GST_VAAPI_OBJECT_DISPLAY(context), - GST_VAAPI_CHROMA_TYPE_YUV420, - cip->width, cip->height - ); - if (!surface) - return FALSE; - gst_vaapi_surface_set_parent_context(surface, context); - g_ptr_array_add(context->surfaces, surface); - if (!gst_vaapi_video_pool_add_object(context->surfaces_pool, surface)) - return FALSE; - } - return TRUE; + for (i = context->surfaces->len; i < num_surfaces; i++) { + surface = gst_vaapi_surface_new (GST_VAAPI_OBJECT_DISPLAY (context), + GST_VAAPI_CHROMA_TYPE_YUV420, cip->width, cip->height); + if (!surface) + return FALSE; + gst_vaapi_surface_set_parent_context (surface, context); + g_ptr_array_add (context->surfaces, surface); + if (!gst_vaapi_video_pool_add_object (context->surfaces_pool, surface)) + return FALSE; + } + return TRUE; } static gboolean -gst_vaapi_context_create(GstVaapiContext *context) +gst_vaapi_context_create (GstVaapiContext * context) { - const GstVaapiContextInfo * const cip = &context->info; - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context); - VAProfile va_profile; - VAEntrypoint va_entrypoint; - guint va_rate_control; - VAConfigAttrib attribs[2]; - guint num_attribs; - VAContextID context_id; - VASurfaceID surface_id; - VAStatus status; - GArray *surfaces = NULL; - gboolean success = FALSE; - guint i; + const GstVaapiContextInfo *const cip = &context->info; + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); + VAProfile va_profile; + VAEntrypoint va_entrypoint; + guint va_rate_control; + VAConfigAttrib attribs[2]; + guint num_attribs; + VAContextID context_id; + VASurfaceID surface_id; + VAStatus status; + GArray *surfaces = NULL; + gboolean success = FALSE; + guint i; - if (!context->surfaces && !gst_vaapi_context_create_surfaces(context)) - goto end; + if (!context->surfaces && !gst_vaapi_context_create_surfaces (context)) + goto end; - surfaces = g_array_sized_new( - FALSE, - FALSE, - sizeof(VASurfaceID), - context->surfaces->len - ); - if (!surfaces) - goto end; + surfaces = g_array_sized_new (FALSE, + FALSE, sizeof (VASurfaceID), context->surfaces->len); + if (!surfaces) + goto end; - for (i = 0; i < context->surfaces->len; i++) { - GstVaapiSurface * const surface = - g_ptr_array_index(context->surfaces, i); - if (!surface) - goto end; - surface_id = GST_VAAPI_OBJECT_ID(surface); - g_array_append_val(surfaces, surface_id); + for (i = 0; i < context->surfaces->len; i++) { + GstVaapiSurface *const surface = g_ptr_array_index (context->surfaces, i); + if (!surface) + goto end; + surface_id = GST_VAAPI_OBJECT_ID (surface); + g_array_append_val (surfaces, surface_id); + } + assert (surfaces->len == context->surfaces->len); + + if (!cip->profile || !cip->entrypoint) + goto end; + va_profile = gst_vaapi_profile_get_va_profile (cip->profile); + va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint (cip->entrypoint); + + num_attribs = 0; + attribs[num_attribs++].type = VAConfigAttribRTFormat; + if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) + attribs[num_attribs++].type = VAConfigAttribRateControl; + + GST_VAAPI_DISPLAY_LOCK (display); + status = vaGetConfigAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display), + va_profile, va_entrypoint, attribs, num_attribs); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaGetConfigAttributes()")) + goto end; + if (!(attribs[0].value & VA_RT_FORMAT_YUV420)) + goto end; + + if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) { + va_rate_control = from_GstVaapiRateControl (cip->rc_mode); + if (va_rate_control == VA_RC_NONE) + attribs[1].value = VA_RC_NONE; + if ((attribs[1].value & va_rate_control) != va_rate_control) { + GST_ERROR ("unsupported %s rate control", + string_of_VARateControl (va_rate_control)); + goto end; } - assert(surfaces->len == context->surfaces->len); + attribs[1].value = va_rate_control; + } - if (!cip->profile || !cip->entrypoint) - goto end; - va_profile = gst_vaapi_profile_get_va_profile(cip->profile); - va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint(cip->entrypoint); + GST_VAAPI_DISPLAY_LOCK (display); + status = vaCreateConfig (GST_VAAPI_DISPLAY_VADISPLAY (display), + va_profile, va_entrypoint, attribs, num_attribs, &context->config_id); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaCreateConfig()")) + goto end; - num_attribs = 0; - attribs[num_attribs++].type = VAConfigAttribRTFormat; - if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) - attribs[num_attribs++].type = VAConfigAttribRateControl; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaCreateContext (GST_VAAPI_DISPLAY_VADISPLAY (display), + context->config_id, + cip->width, cip->height, + VA_PROGRESSIVE, + (VASurfaceID *) surfaces->data, surfaces->len, &context_id); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaCreateContext()")) + goto end; - GST_VAAPI_DISPLAY_LOCK(display); - status = vaGetConfigAttributes( - GST_VAAPI_DISPLAY_VADISPLAY(display), - va_profile, - va_entrypoint, - attribs, num_attribs - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaGetConfigAttributes()")) - goto end; - if (!(attribs[0].value & VA_RT_FORMAT_YUV420)) - goto end; - - if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) { - va_rate_control = from_GstVaapiRateControl(cip->rc_mode); - if (va_rate_control == VA_RC_NONE) - attribs[1].value = VA_RC_NONE; - if ((attribs[1].value & va_rate_control) != va_rate_control) { - GST_ERROR("unsupported %s rate control", - string_of_VARateControl(va_rate_control)); - goto end; - } - attribs[1].value = va_rate_control; - } - - GST_VAAPI_DISPLAY_LOCK(display); - status = vaCreateConfig( - GST_VAAPI_DISPLAY_VADISPLAY(display), - va_profile, - va_entrypoint, - attribs, num_attribs, - &context->config_id - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaCreateConfig()")) - goto end; - - GST_VAAPI_DISPLAY_LOCK(display); - status = vaCreateContext( - GST_VAAPI_DISPLAY_VADISPLAY(display), - context->config_id, - cip->width, cip->height, - VA_PROGRESSIVE, - (VASurfaceID *)surfaces->data, surfaces->len, - &context_id - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaCreateContext()")) - goto end; - - GST_DEBUG("context %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(context_id)); - GST_VAAPI_OBJECT_ID(context) = context_id; - success = TRUE; + GST_DEBUG ("context %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (context_id)); + GST_VAAPI_OBJECT_ID (context) = context_id; + success = TRUE; end: - if (surfaces) - g_array_free(surfaces, TRUE); - return success; + if (surfaces) + g_array_free (surfaces, TRUE); + return success; } static inline void -gst_vaapi_context_init(GstVaapiContext *context, const GstVaapiContextInfo *cip) +gst_vaapi_context_init (GstVaapiContext * context, + const GstVaapiContextInfo * cip) { - context->info = *cip; - context->config_id = VA_INVALID_ID; - context->overlays[0] = overlay_new(); - context->overlays[1] = overlay_new(); + context->info = *cip; + context->config_id = VA_INVALID_ID; + context->overlays[0] = overlay_new (); + context->overlays[1] = overlay_new (); } static void -gst_vaapi_context_finalize(GstVaapiContext *context) +gst_vaapi_context_finalize (GstVaapiContext * context) { - overlay_destroy(&context->overlays[0]); - overlay_destroy(&context->overlays[1]); - gst_vaapi_context_destroy(context); - gst_vaapi_context_destroy_surfaces(context); + overlay_destroy (&context->overlays[0]); + overlay_destroy (&context->overlays[1]); + gst_vaapi_context_destroy (context); + gst_vaapi_context_destroy_surfaces (context); } -GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiContext, gst_vaapi_context) +GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiContext, gst_vaapi_context) /** * gst_vaapi_context_new: @@ -656,24 +640,19 @@ GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiContext, gst_vaapi_context) * * Return value: the newly allocated #GstVaapiContext object */ -GstVaapiContext * -gst_vaapi_context_new( - GstVaapiDisplay *display, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, - guint width, - guint height -) + GstVaapiContext *gst_vaapi_context_new (GstVaapiDisplay * display, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint, guint width, guint height) { - GstVaapiContextInfo info; + GstVaapiContextInfo info; - info.profile = profile; - info.entrypoint = entrypoint; - info.rc_mode = GST_VAAPI_RATECONTROL_NONE; - info.width = width; - info.height = height; - info.ref_frames = get_max_ref_frames(profile); - return gst_vaapi_context_new_full(display, &info); + info.profile = profile; + info.entrypoint = entrypoint; + info.rc_mode = GST_VAAPI_RATECONTROL_NONE; + info.width = width; + info.height = height; + info.ref_frames = get_max_ref_frames (profile); + return gst_vaapi_context_new_full (display, &info); } /** @@ -688,28 +667,28 @@ gst_vaapi_context_new( * Return value: the newly allocated #GstVaapiContext object */ GstVaapiContext * -gst_vaapi_context_new_full(GstVaapiDisplay *display, - const GstVaapiContextInfo *cip) +gst_vaapi_context_new_full (GstVaapiDisplay * display, + const GstVaapiContextInfo * cip) { - GstVaapiContext *context; + GstVaapiContext *context; - g_return_val_if_fail(cip->profile, NULL); - g_return_val_if_fail(cip->entrypoint, NULL); - g_return_val_if_fail(cip->width > 0, NULL); - g_return_val_if_fail(cip->height > 0, NULL); + g_return_val_if_fail (cip->profile, NULL); + g_return_val_if_fail (cip->entrypoint, NULL); + g_return_val_if_fail (cip->width > 0, NULL); + g_return_val_if_fail (cip->height > 0, NULL); - context = gst_vaapi_object_new(gst_vaapi_context_class(), display); - if (!context) - return NULL; + context = gst_vaapi_object_new (gst_vaapi_context_class (), display); + if (!context) + return NULL; - gst_vaapi_context_init(context, cip); - if (!gst_vaapi_context_create(context)) - goto error; - return context; + gst_vaapi_context_init (context, cip); + if (!gst_vaapi_context_create (context)) + goto error; + return context; error: - gst_vaapi_object_unref(context); - return NULL; + gst_vaapi_object_unref (context); + return NULL; } /** @@ -726,24 +705,20 @@ error: * Return value: %TRUE on success */ gboolean -gst_vaapi_context_reset( - GstVaapiContext *context, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, - unsigned int width, - unsigned int height -) +gst_vaapi_context_reset (GstVaapiContext * context, + GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint, unsigned int width, unsigned int height) { - GstVaapiContextInfo info; + GstVaapiContextInfo info; - info.profile = profile; - info.entrypoint = entrypoint; - info.rc_mode = GST_VAAPI_RATECONTROL_NONE; - info.width = width; - info.height = height; - info.ref_frames = context->info.ref_frames; + info.profile = profile; + info.entrypoint = entrypoint; + info.rc_mode = GST_VAAPI_RATECONTROL_NONE; + info.width = width; + info.height = height; + info.ref_frames = context->info.ref_frames; - return gst_vaapi_context_reset_full(context, &info); + return gst_vaapi_context_reset_full (context, &info); } /** @@ -758,43 +733,42 @@ gst_vaapi_context_reset( * Return value: %TRUE on success */ gboolean -gst_vaapi_context_reset_full(GstVaapiContext *context, - const GstVaapiContextInfo *new_cip) +gst_vaapi_context_reset_full (GstVaapiContext * context, + const GstVaapiContextInfo * new_cip) { - GstVaapiContextInfo * const cip = &context->info; - gboolean size_changed, codec_changed, rc_mode_changed; + GstVaapiContextInfo *const cip = &context->info; + gboolean size_changed, codec_changed, rc_mode_changed; - size_changed = cip->width != new_cip->width || - cip->height != new_cip->height; - if (size_changed) { - gst_vaapi_context_destroy_surfaces(context); - cip->width = new_cip->width; - cip->height = new_cip->height; + size_changed = cip->width != new_cip->width || cip->height != new_cip->height; + if (size_changed) { + gst_vaapi_context_destroy_surfaces (context); + cip->width = new_cip->width; + cip->height = new_cip->height; + } + + codec_changed = cip->profile != new_cip->profile || + cip->entrypoint != new_cip->entrypoint; + if (codec_changed) { + gst_vaapi_context_destroy (context); + cip->profile = new_cip->profile; + cip->entrypoint = new_cip->entrypoint; + } + + if (new_cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) { + rc_mode_changed = cip->rc_mode != cip->rc_mode; + if (rc_mode_changed) { + gst_vaapi_context_destroy (context); + cip->rc_mode = new_cip->rc_mode; } + } - codec_changed = cip->profile != new_cip->profile || - cip->entrypoint != new_cip->entrypoint; - if (codec_changed) { - gst_vaapi_context_destroy(context); - cip->profile = new_cip->profile; - cip->entrypoint = new_cip->entrypoint; - } + if (size_changed && !gst_vaapi_context_create_surfaces (context)) + return FALSE; - if (new_cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) { - rc_mode_changed = cip->rc_mode != cip->rc_mode; - if (rc_mode_changed) { - gst_vaapi_context_destroy(context); - cip->rc_mode = new_cip->rc_mode; - } - } + if (codec_changed && !gst_vaapi_context_create (context)) + return FALSE; - if (size_changed && !gst_vaapi_context_create_surfaces(context)) - return FALSE; - - if (codec_changed && !gst_vaapi_context_create(context)) - return FALSE; - - return TRUE; + return TRUE; } /** @@ -806,11 +780,11 @@ gst_vaapi_context_reset_full(GstVaapiContext *context, * Return value: the underlying VA context id */ GstVaapiID -gst_vaapi_context_get_id(GstVaapiContext *context) +gst_vaapi_context_get_id (GstVaapiContext * context) { - g_return_val_if_fail(context != NULL, VA_INVALID_ID); + g_return_val_if_fail (context != NULL, VA_INVALID_ID); - return GST_VAAPI_OBJECT_ID(context); + return GST_VAAPI_OBJECT_ID (context); } /** @@ -822,11 +796,11 @@ gst_vaapi_context_get_id(GstVaapiContext *context) * Return value: the VA profile used by the @context */ GstVaapiProfile -gst_vaapi_context_get_profile(GstVaapiContext *context) +gst_vaapi_context_get_profile (GstVaapiContext * context) { - g_return_val_if_fail(context != NULL, 0); + g_return_val_if_fail (context != NULL, 0); - return context->info.profile; + return context->info.profile; } /** @@ -842,16 +816,15 @@ gst_vaapi_context_get_profile(GstVaapiContext *context) * Return value: %TRUE on success */ gboolean -gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile) +gst_vaapi_context_set_profile (GstVaapiContext * context, + GstVaapiProfile profile) { - g_return_val_if_fail(context != NULL, FALSE); - g_return_val_if_fail(profile, FALSE); + g_return_val_if_fail (context != NULL, FALSE); + g_return_val_if_fail (profile, FALSE); - return gst_vaapi_context_reset(context, - profile, - context->info.entrypoint, - context->info.width, - context->info.height); + return gst_vaapi_context_reset (context, + profile, + context->info.entrypoint, context->info.width, context->info.height); } /** @@ -863,11 +836,11 @@ gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile) * Return value: the VA entrypoint used by the @context */ GstVaapiEntrypoint -gst_vaapi_context_get_entrypoint(GstVaapiContext *context) +gst_vaapi_context_get_entrypoint (GstVaapiContext * context) { - g_return_val_if_fail(context != NULL, 0); + g_return_val_if_fail (context != NULL, 0); - return context->info.entrypoint; + return context->info.entrypoint; } /** @@ -879,19 +852,16 @@ gst_vaapi_context_get_entrypoint(GstVaapiContext *context) * Retrieves the size of the surfaces attached to @context. */ void -gst_vaapi_context_get_size( - GstVaapiContext *context, - guint *pwidth, - guint *pheight -) +gst_vaapi_context_get_size (GstVaapiContext * context, + guint * pwidth, guint * pheight) { - g_return_if_fail(context != NULL); + g_return_if_fail (context != NULL); - if (pwidth) - *pwidth = context->info.width; + if (pwidth) + *pwidth = context->info.width; - if (pheight) - *pheight = context->info.height; + if (pheight) + *pheight = context->info.height; } /** @@ -910,12 +880,13 @@ gst_vaapi_context_get_size( * Return value: a free surface, or %NULL if none is available */ GstVaapiSurfaceProxy * -gst_vaapi_context_get_surface_proxy(GstVaapiContext *context) +gst_vaapi_context_get_surface_proxy (GstVaapiContext * context) { - g_return_val_if_fail(context != NULL, NULL); + g_return_val_if_fail (context != NULL, NULL); - return gst_vaapi_surface_proxy_new_from_pool( - GST_VAAPI_SURFACE_POOL(context->surfaces_pool)); + return + gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL (context-> + surfaces_pool)); } /** @@ -927,11 +898,11 @@ gst_vaapi_context_get_surface_proxy(GstVaapiContext *context) * Return value: the number of free surfaces available in the pool */ guint -gst_vaapi_context_get_surface_count(GstVaapiContext *context) +gst_vaapi_context_get_surface_count (GstVaapiContext * context) { - g_return_val_if_fail(context != NULL, 0); + g_return_val_if_fail (context != NULL, 0); - return gst_vaapi_video_pool_get_size(context->surfaces_pool); + return gst_vaapi_video_pool_get_size (context->surfaces_pool); } /** @@ -948,62 +919,59 @@ gst_vaapi_context_get_surface_count(GstVaapiContext *context) * %FALSE otherwise */ gboolean -gst_vaapi_context_apply_composition( - GstVaapiContext *context, - GstVideoOverlayComposition *composition -) +gst_vaapi_context_apply_composition (GstVaapiContext * context, + GstVideoOverlayComposition * composition) { - GPtrArray *curr_overlay, *next_overlay; - guint i, n_rectangles; - gboolean reassociate = FALSE; + GPtrArray *curr_overlay, *next_overlay; + guint i, n_rectangles; + gboolean reassociate = FALSE; - g_return_val_if_fail(context != NULL, FALSE); + g_return_val_if_fail (context != NULL, FALSE); - if (!context->surfaces) - return FALSE; + if (!context->surfaces) + return FALSE; - if (!composition) { - gst_vaapi_context_clear_overlay(context); - return TRUE; - } - - curr_overlay = context->overlays[context->overlay_id]; - next_overlay = context->overlays[context->overlay_id ^ 1]; - overlay_clear(next_overlay); - - n_rectangles = gst_video_overlay_composition_n_rectangles(composition); - for (i = 0; i < n_rectangles; i++) { - GstVideoOverlayRectangle * const rect = - gst_video_overlay_composition_get_rectangle(composition, i); - GstVaapiOverlayRectangle *overlay; - - overlay = overlay_lookup(curr_overlay, rect); - if (overlay && overlay_rectangle_update(overlay, rect, &reassociate)) { - overlay_rectangle_ref(overlay); - if (overlay->layer_id != i) - reassociate = TRUE; - } - else { - overlay = overlay_rectangle_new(rect, context, i); - if (!overlay) { - GST_WARNING("could not create VA overlay rectangle"); - goto error; - } - reassociate = TRUE; - } - g_ptr_array_add(next_overlay, overlay); - } - - overlay_clear(curr_overlay); - context->overlay_id ^= 1; - - if (reassociate && !overlay_reassociate(next_overlay)) - return FALSE; + if (!composition) { + gst_vaapi_context_clear_overlay (context); return TRUE; + } + + curr_overlay = context->overlays[context->overlay_id]; + next_overlay = context->overlays[context->overlay_id ^ 1]; + overlay_clear (next_overlay); + + n_rectangles = gst_video_overlay_composition_n_rectangles (composition); + for (i = 0; i < n_rectangles; i++) { + GstVideoOverlayRectangle *const rect = + gst_video_overlay_composition_get_rectangle (composition, i); + GstVaapiOverlayRectangle *overlay; + + overlay = overlay_lookup (curr_overlay, rect); + if (overlay && overlay_rectangle_update (overlay, rect, &reassociate)) { + overlay_rectangle_ref (overlay); + if (overlay->layer_id != i) + reassociate = TRUE; + } else { + overlay = overlay_rectangle_new (rect, context, i); + if (!overlay) { + GST_WARNING ("could not create VA overlay rectangle"); + goto error; + } + reassociate = TRUE; + } + g_ptr_array_add (next_overlay, overlay); + } + + overlay_clear (curr_overlay); + context->overlay_id ^= 1; + + if (reassociate && !overlay_reassociate (next_overlay)) + return FALSE; + return TRUE; error: - gst_vaapi_context_clear_overlay(context); - return FALSE; + gst_vaapi_context_clear_overlay (context); + return FALSE; } @@ -1023,25 +991,25 @@ error: * config attribute and returned a valid value, %FALSE otherwise */ gboolean -gst_vaapi_context_get_attribute(GstVaapiContext *context, - VAConfigAttribType type, guint *out_value_ptr) +gst_vaapi_context_get_attribute (GstVaapiContext * context, + VAConfigAttribType type, guint * out_value_ptr) { - VAConfigAttrib attrib; - VAStatus status; + VAConfigAttrib attrib; + VAStatus status; - g_return_val_if_fail(context != NULL, FALSE); + g_return_val_if_fail (context != NULL, FALSE); - GST_VAAPI_OBJECT_LOCK_DISPLAY(context); - attrib.type = type; - status = vaGetConfigAttributes(GST_VAAPI_OBJECT_VADISPLAY(context), - gst_vaapi_profile_get_va_profile(context->info.profile), - gst_vaapi_entrypoint_get_va_entrypoint(context->info.entrypoint), - &attrib, 1); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(context); - if (!vaapi_check_status(status, "vaGetConfiAttributes()")) - return FALSE; + GST_VAAPI_OBJECT_LOCK_DISPLAY (context); + attrib.type = type; + status = vaGetConfigAttributes (GST_VAAPI_OBJECT_VADISPLAY (context), + gst_vaapi_profile_get_va_profile (context->info.profile), + gst_vaapi_entrypoint_get_va_entrypoint (context->info.entrypoint), + &attrib, 1); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (context); + if (!vaapi_check_status (status, "vaGetConfiAttributes()")) + return FALSE; - if (out_value_ptr) - *out_value_ptr = attrib.value; - return TRUE; + if (out_value_ptr) + *out_value_ptr = attrib.value; + return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index a5a5c07ea2..c996e02134 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -34,10 +34,10 @@ G_BEGIN_DECLS #define GST_VAAPI_CONTEXT(obj) \ - ((GstVaapiContext *)(obj)) + ((GstVaapiContext *) (obj)) -typedef struct _GstVaapiContext GstVaapiContext; -typedef struct _GstVaapiContextInfo GstVaapiContextInfo; +typedef struct _GstVaapiContext GstVaapiContext; +typedef struct _GstVaapiContextInfo GstVaapiContextInfo; /** * GstVaapiContextInfo: @@ -49,88 +49,75 @@ typedef struct _GstVaapiContextInfo GstVaapiContextInfo; * Note: @rc_mode is only valid for VA context used for encoding, * i.e. if @entrypoint is set to @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE. */ -struct _GstVaapiContextInfo { - GstVaapiProfile profile; - GstVaapiEntrypoint entrypoint; - GstVaapiRateControl rc_mode; - guint width; - guint height; - guint ref_frames; +struct _GstVaapiContextInfo +{ + GstVaapiProfile profile; + GstVaapiEntrypoint entrypoint; + GstVaapiRateControl rc_mode; + guint width; + guint height; + guint ref_frames; }; G_GNUC_INTERNAL GstVaapiContext * -gst_vaapi_context_new( - GstVaapiDisplay *display, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, - guint width, - guint height -); +gst_vaapi_context_new (GstVaapiDisplay * display, GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint, guint width, guint height); G_GNUC_INTERNAL GstVaapiContext * -gst_vaapi_context_new_full(GstVaapiDisplay *display, - const GstVaapiContextInfo *cip); +gst_vaapi_context_new_full (GstVaapiDisplay * display, + const GstVaapiContextInfo * cip); G_GNUC_INTERNAL gboolean -gst_vaapi_context_reset( - GstVaapiContext *context, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, - guint width, - guint height -); +gst_vaapi_context_reset (GstVaapiContext * context, GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint, guint width, guint height); G_GNUC_INTERNAL gboolean -gst_vaapi_context_reset_full(GstVaapiContext *context, - const GstVaapiContextInfo *new_cip); +gst_vaapi_context_reset_full (GstVaapiContext * context, + const GstVaapiContextInfo * new_cip); G_GNUC_INTERNAL GstVaapiID -gst_vaapi_context_get_id(GstVaapiContext *context); +gst_vaapi_context_get_id (GstVaapiContext * context); G_GNUC_INTERNAL GstVaapiProfile -gst_vaapi_context_get_profile(GstVaapiContext *context); +gst_vaapi_context_get_profile (GstVaapiContext * context); G_GNUC_INTERNAL gboolean -gst_vaapi_context_set_profile(GstVaapiContext *context, GstVaapiProfile profile); +gst_vaapi_context_set_profile (GstVaapiContext * context, + GstVaapiProfile profile); G_GNUC_INTERNAL GstVaapiEntrypoint -gst_vaapi_context_get_entrypoint(GstVaapiContext *context); +gst_vaapi_context_get_entrypoint (GstVaapiContext * context); G_GNUC_INTERNAL void -gst_vaapi_context_get_size( - GstVaapiContext *context, - guint *pwidth, - guint *pheight -); +gst_vaapi_context_get_size (GstVaapiContext * context, + guint * pwidth, guint * pheight); G_GNUC_INTERNAL GstVaapiSurfaceProxy * -gst_vaapi_context_get_surface_proxy(GstVaapiContext *context); +gst_vaapi_context_get_surface_proxy (GstVaapiContext * context); G_GNUC_INTERNAL guint -gst_vaapi_context_get_surface_count(GstVaapiContext *context); +gst_vaapi_context_get_surface_count (GstVaapiContext * context); G_GNUC_INTERNAL gboolean -gst_vaapi_context_apply_composition( - GstVaapiContext *context, - GstVideoOverlayComposition *composition -); +gst_vaapi_context_apply_composition (GstVaapiContext * context, + GstVideoOverlayComposition * composition); G_GNUC_INTERNAL gboolean -gst_vaapi_context_get_attribute(GstVaapiContext *context, - VAConfigAttribType type, guint *out_value_ptr); +gst_vaapi_context_get_attribute (GstVaapiContext * context, + VAConfigAttribType type, guint * out_value_ptr); G_END_DECLS From c85b0806886d96ecd4f9fd5a42721fd22f22abcd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 09:41:07 +0100 Subject: [PATCH 1562/3781] context: clean-ups. Strip down APIs. Improve documentation and debug messages. Clean-up APIs, i.e. strip them down to the minimal set of interfaces. They are private, so no need expose getters for instance. --- gst-libs/gst/vaapi/gstvaapicontext.c | 342 ++++++--------------------- gst-libs/gst/vaapi/gstvaapicontext.h | 76 +++--- gst-libs/gst/vaapi/gstvaapidecoder.c | 4 +- gst-libs/gst/vaapi/gstvaapiencoder.c | 4 +- 4 files changed, 121 insertions(+), 305 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 50baafd3c9..a4cc1fb841 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -28,9 +28,9 @@ */ #include "sysdeps.h" -#include #include "gstvaapicompat.h" #include "gstvaapicontext.h" +#include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" #include "gstvaapisurface.h" #include "gstvaapisurface_priv.h" @@ -44,37 +44,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiContextClass GstVaapiContextClass; - -/** - * GstVaapiContext: - * - * A VA context wrapper. - */ -struct _GstVaapiContext -{ - /*< private >*/ - GstVaapiObject parent_instance; - - GstVaapiContextInfo info; - VAConfigID config_id; - GPtrArray *surfaces; - GstVaapiVideoPool *surfaces_pool; - GPtrArray *overlays[2]; - guint overlay_id; -}; - -/** - * GstVaapiContextClass: - * - * A VA context wrapper class. - */ -struct _GstVaapiContextClass -{ - /*< private >*/ - GstVaapiObjectClass parent_class; -}; - typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle; struct _GstVaapiOverlayRectangle { @@ -88,25 +57,6 @@ struct _GstVaapiOverlayRectangle guint is_associated:1; }; -static guint -get_max_ref_frames (GstVaapiProfile profile) -{ - guint ref_frames; - - switch (gst_vaapi_profile_get_codec (profile)) { - case GST_VAAPI_CODEC_H264: - ref_frames = 16; - break; - case GST_VAAPI_CODEC_JPEG: - ref_frames = 0; - break; - default: - ref_frames = 2; - break; - } - return ref_frames; -} - static inline void gst_video_overlay_rectangle_replace (GstVideoOverlayRectangle ** old_rect_ptr, GstVideoOverlayRectangle * new_rect) @@ -392,7 +342,7 @@ overlay_reassociate (GPtrArray * overlays) } static void -gst_vaapi_context_clear_overlay (GstVaapiContext * context) +context_clear_overlay (GstVaapiContext * context) { overlay_clear (context->overlays[0]); overlay_clear (context->overlays[1]); @@ -400,42 +350,39 @@ gst_vaapi_context_clear_overlay (GstVaapiContext * context) } static inline void -gst_vaapi_context_destroy_overlay (GstVaapiContext * context) +context_destroy_overlay (GstVaapiContext * context) { - gst_vaapi_context_clear_overlay (context); + context_clear_overlay (context); } static void -unref_surface_cb (gpointer data, gpointer user_data) +unref_surface_cb (GstVaapiSurface * surface) { - GstVaapiSurface *const surface = GST_VAAPI_SURFACE (data); - gst_vaapi_surface_set_parent_context (surface, NULL); gst_vaapi_object_unref (surface); } static void -gst_vaapi_context_destroy_surfaces (GstVaapiContext * context) +context_destroy_surfaces (GstVaapiContext * context) { - gst_vaapi_context_destroy_overlay (context); + context_destroy_overlay (context); if (context->surfaces) { - g_ptr_array_foreach (context->surfaces, unref_surface_cb, NULL); - g_ptr_array_free (context->surfaces, TRUE); + g_ptr_array_unref (context->surfaces); context->surfaces = NULL; } gst_vaapi_video_pool_replace (&context->surfaces_pool, NULL); } static void -gst_vaapi_context_destroy (GstVaapiContext * context) +context_destroy (GstVaapiContext * context) { GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); VAContextID context_id; VAStatus status; context_id = GST_VAAPI_OBJECT_ID (context); - GST_DEBUG ("context %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (context_id)); + GST_DEBUG ("context 0x%08x", context_id); if (context_id != VA_INVALID_ID) { GST_VAAPI_DISPLAY_LOCK (display); @@ -443,35 +390,33 @@ gst_vaapi_context_destroy (GstVaapiContext * context) context_id); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaDestroyContext()")) - g_warning ("failed to destroy context %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS (context_id)); + GST_WARNING ("failed to destroy context 0x%08x", context_id); GST_VAAPI_OBJECT_ID (context) = VA_INVALID_ID; } - if (context->config_id != VA_INVALID_ID) { + if (context->va_config != VA_INVALID_ID) { GST_VAAPI_DISPLAY_LOCK (display); status = vaDestroyConfig (GST_VAAPI_DISPLAY_VADISPLAY (display), - context->config_id); + context->va_config); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaDestroyConfig()")) - g_warning ("failed to destroy config %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS (context->config_id)); - context->config_id = VA_INVALID_ID; + GST_WARNING ("failed to destroy config 0x%08x", context->va_config); + context->va_config = VA_INVALID_ID; } } static gboolean -gst_vaapi_context_create_overlay (GstVaapiContext * context) +context_create_overlay (GstVaapiContext * context) { if (!context->overlays[0] || !context->overlays[1]) return FALSE; - gst_vaapi_context_clear_overlay (context); + context_clear_overlay (context); return TRUE; } static gboolean -gst_vaapi_context_create_surfaces (GstVaapiContext * context) +context_create_surfaces (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; GstVideoInfo vi; @@ -481,11 +426,13 @@ gst_vaapi_context_create_surfaces (GstVaapiContext * context) /* Number of scratch surfaces beyond those used as reference */ const guint SCRATCH_SURFACES_COUNT = 4; - if (!gst_vaapi_context_create_overlay (context)) + if (!context_create_overlay (context)) return FALSE; + num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; if (!context->surfaces) { - context->surfaces = g_ptr_array_new (); + context->surfaces = g_ptr_array_new_full (num_surfaces, + (GDestroyNotify) unref_surface_cb); if (!context->surfaces) return FALSE; } @@ -498,8 +445,6 @@ gst_vaapi_context_create_surfaces (GstVaapiContext * context) if (!context->surfaces_pool) return FALSE; } - - num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; gst_vaapi_video_pool_set_capacity (context->surfaces_pool, num_surfaces); for (i = context->surfaces->len; i < num_surfaces; i++) { @@ -516,12 +461,10 @@ gst_vaapi_context_create_surfaces (GstVaapiContext * context) } static gboolean -gst_vaapi_context_create (GstVaapiContext * context) +context_create (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); - VAProfile va_profile; - VAEntrypoint va_entrypoint; guint va_rate_control; VAConfigAttrib attribs[2]; guint num_attribs; @@ -532,27 +475,28 @@ gst_vaapi_context_create (GstVaapiContext * context) gboolean success = FALSE; guint i; - if (!context->surfaces && !gst_vaapi_context_create_surfaces (context)) - goto end; + if (!context->surfaces && !context_create_surfaces (context)) + goto cleanup; surfaces = g_array_sized_new (FALSE, FALSE, sizeof (VASurfaceID), context->surfaces->len); if (!surfaces) - goto end; + goto cleanup; for (i = 0; i < context->surfaces->len; i++) { GstVaapiSurface *const surface = g_ptr_array_index (context->surfaces, i); if (!surface) - goto end; + goto cleanup; surface_id = GST_VAAPI_OBJECT_ID (surface); g_array_append_val (surfaces, surface_id); } - assert (surfaces->len == context->surfaces->len); + g_assert (surfaces->len == context->surfaces->len); if (!cip->profile || !cip->entrypoint) - goto end; - va_profile = gst_vaapi_profile_get_va_profile (cip->profile); - va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint (cip->entrypoint); + goto cleanup; + context->va_profile = gst_vaapi_profile_get_va_profile (cip->profile); + context->va_entrypoint = + gst_vaapi_entrypoint_get_va_entrypoint (cip->entrypoint); num_attribs = 0; attribs[num_attribs++].type = VAConfigAttribRTFormat; @@ -561,12 +505,12 @@ gst_vaapi_context_create (GstVaapiContext * context) GST_VAAPI_DISPLAY_LOCK (display); status = vaGetConfigAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display), - va_profile, va_entrypoint, attribs, num_attribs); + context->va_profile, context->va_entrypoint, attribs, num_attribs); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaGetConfigAttributes()")) - goto end; + goto cleanup; if (!(attribs[0].value & VA_RT_FORMAT_YUV420)) - goto end; + goto cleanup; if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) { va_rate_control = from_GstVaapiRateControl (cip->rc_mode); @@ -575,32 +519,32 @@ gst_vaapi_context_create (GstVaapiContext * context) if ((attribs[1].value & va_rate_control) != va_rate_control) { GST_ERROR ("unsupported %s rate control", string_of_VARateControl (va_rate_control)); - goto end; + goto cleanup; } attribs[1].value = va_rate_control; } GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateConfig (GST_VAAPI_DISPLAY_VADISPLAY (display), - va_profile, va_entrypoint, attribs, num_attribs, &context->config_id); + context->va_profile, context->va_entrypoint, attribs, num_attribs, + &context->va_config); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateConfig()")) - goto end; + goto cleanup; GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateContext (GST_VAAPI_DISPLAY_VADISPLAY (display), - context->config_id, - cip->width, cip->height, - VA_PROGRESSIVE, + context->va_config, cip->width, cip->height, VA_PROGRESSIVE, (VASurfaceID *) surfaces->data, surfaces->len, &context_id); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateContext()")) - goto end; + goto cleanup; - GST_DEBUG ("context %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (context_id)); + GST_DEBUG ("context 0x%08x", context_id); GST_VAAPI_OBJECT_ID (context) = context_id; success = TRUE; -end: + +cleanup: if (surfaces) g_array_free (surfaces, TRUE); return success; @@ -611,7 +555,7 @@ gst_vaapi_context_init (GstVaapiContext * context, const GstVaapiContextInfo * cip) { context->info = *cip; - context->config_id = VA_INVALID_ID; + context->va_config = VA_INVALID_ID; context->overlays[0] = overlay_new (); context->overlays[1] = overlay_new (); } @@ -621,43 +565,15 @@ gst_vaapi_context_finalize (GstVaapiContext * context) { overlay_destroy (&context->overlays[0]); overlay_destroy (&context->overlays[1]); - gst_vaapi_context_destroy (context); - gst_vaapi_context_destroy_surfaces (context); + context_destroy (context); + context_destroy_surfaces (context); } -GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiContext, gst_vaapi_context) +GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiContext, gst_vaapi_context); /** * gst_vaapi_context_new: * @display: a #GstVaapiDisplay - * @profile: a #GstVaapiProfile - * @entrypoint: a #GstVaapiEntrypoint - * @width: coded width from the bitstream - * @height: coded height from the bitstream - * - * Creates a new #GstVaapiContext with the specified codec @profile - * and @entrypoint. - * - * Return value: the newly allocated #GstVaapiContext object - */ - GstVaapiContext *gst_vaapi_context_new (GstVaapiDisplay * display, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, guint width, guint height) -{ - GstVaapiContextInfo info; - - info.profile = profile; - info.entrypoint = entrypoint; - info.rc_mode = GST_VAAPI_RATECONTROL_NONE; - info.width = width; - info.height = height; - info.ref_frames = get_max_ref_frames (profile); - return gst_vaapi_context_new_full (display, &info); -} - -/** - * gst_vaapi_context_new_full: - * @display: a #GstVaapiDisplay * @cip: a pointer to the #GstVaapiContextInfo * * Creates a new #GstVaapiContext with the configuration specified by @@ -667,7 +583,7 @@ GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiContext, gst_vaapi_context) * Return value: the newly allocated #GstVaapiContext object */ GstVaapiContext * -gst_vaapi_context_new_full (GstVaapiDisplay * display, +gst_vaapi_context_new (GstVaapiDisplay * display, const GstVaapiContextInfo * cip) { GstVaapiContext *context; @@ -682,7 +598,7 @@ gst_vaapi_context_new_full (GstVaapiDisplay * display, return NULL; gst_vaapi_context_init (context, cip); - if (!gst_vaapi_context_create (context)) + if (!context_create (context)) goto error; return context; @@ -694,36 +610,6 @@ error: /** * gst_vaapi_context_reset: * @context: a #GstVaapiContext - * @profile: a #GstVaapiProfile - * @entrypoint: a #GstVaapiEntrypoint - * @width: coded width from the bitstream - * @height: coded height from the bitstream - * - * Resets @context to the specified codec @profile and @entrypoint. - * The surfaces will be reallocated if the coded size changed. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_context_reset (GstVaapiContext * context, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, unsigned int width, unsigned int height) -{ - GstVaapiContextInfo info; - - info.profile = profile; - info.entrypoint = entrypoint; - info.rc_mode = GST_VAAPI_RATECONTROL_NONE; - info.width = width; - info.height = height; - info.ref_frames = context->info.ref_frames; - - return gst_vaapi_context_reset_full (context, &info); -} - -/** - * gst_vaapi_context_reset_full: - * @context: a #GstVaapiContext * @new_cip: a pointer to the new #GstVaapiContextInfo details * * Resets @context to the configuration specified by @new_cip, thus @@ -733,41 +619,45 @@ gst_vaapi_context_reset (GstVaapiContext * context, * Return value: %TRUE on success */ gboolean -gst_vaapi_context_reset_full (GstVaapiContext * context, +gst_vaapi_context_reset (GstVaapiContext * context, const GstVaapiContextInfo * new_cip) { GstVaapiContextInfo *const cip = &context->info; - gboolean size_changed, codec_changed, rc_mode_changed; + gboolean size_changed, config_changed; size_changed = cip->width != new_cip->width || cip->height != new_cip->height; if (size_changed) { - gst_vaapi_context_destroy_surfaces (context); cip->width = new_cip->width; cip->height = new_cip->height; } - codec_changed = cip->profile != new_cip->profile || + config_changed = cip->profile != new_cip->profile || cip->entrypoint != new_cip->entrypoint; - if (codec_changed) { - gst_vaapi_context_destroy (context); + if (config_changed) { cip->profile = new_cip->profile; cip->entrypoint = new_cip->entrypoint; } - if (new_cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) { - rc_mode_changed = cip->rc_mode != cip->rc_mode; - if (rc_mode_changed) { - gst_vaapi_context_destroy (context); - cip->rc_mode = new_cip->rc_mode; - } + switch (new_cip->entrypoint) { + case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: + if (cip->rc_mode != new_cip->rc_mode) { + cip->rc_mode = new_cip->rc_mode; + config_changed = TRUE; + } + break; + default: + break; } - if (size_changed && !gst_vaapi_context_create_surfaces (context)) - return FALSE; + if (size_changed) + context_destroy_surfaces (context); + if (config_changed) + context_destroy (context); - if (codec_changed && !gst_vaapi_context_create (context)) + if (size_changed && !context_create_surfaces (context)) + return FALSE; + if (config_changed && !context_create (context)) return FALSE; - return TRUE; } @@ -787,83 +677,6 @@ gst_vaapi_context_get_id (GstVaapiContext * context) return GST_VAAPI_OBJECT_ID (context); } -/** - * gst_vaapi_context_get_profile: - * @context: a #GstVaapiContext - * - * Returns the VA profile used by the @context. - * - * Return value: the VA profile used by the @context - */ -GstVaapiProfile -gst_vaapi_context_get_profile (GstVaapiContext * context) -{ - g_return_val_if_fail (context != NULL, 0); - - return context->info.profile; -} - -/** - * gst_vaapi_context_set_profile: - * @context: a #GstVaapiContext - * @profile: the new #GstVaapiProfile to use - * - * Sets the new @profile to use with the @context. If @profile matches - * the previous profile, this call has no effect. Otherwise, the - * underlying VA context is recreated, while keeping the previously - * allocated surfaces. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_context_set_profile (GstVaapiContext * context, - GstVaapiProfile profile) -{ - g_return_val_if_fail (context != NULL, FALSE); - g_return_val_if_fail (profile, FALSE); - - return gst_vaapi_context_reset (context, - profile, - context->info.entrypoint, context->info.width, context->info.height); -} - -/** - * gst_vaapi_context_get_entrypoint: - * @context: a #GstVaapiContext - * - * Returns the VA entrypoint used by the @context - * - * Return value: the VA entrypoint used by the @context - */ -GstVaapiEntrypoint -gst_vaapi_context_get_entrypoint (GstVaapiContext * context) -{ - g_return_val_if_fail (context != NULL, 0); - - return context->info.entrypoint; -} - -/** - * gst_vaapi_context_get_size: - * @context: a #GstVaapiContext - * @pwidth: return location for the width, or %NULL - * @pheight: return location for the height, or %NULL - * - * Retrieves the size of the surfaces attached to @context. - */ -void -gst_vaapi_context_get_size (GstVaapiContext * context, - guint * pwidth, guint * pheight) -{ - g_return_if_fail (context != NULL); - - if (pwidth) - *pwidth = context->info.width; - - if (pheight) - *pheight = context->info.height; -} - /** * gst_vaapi_context_get_surface_proxy: * @context: a #GstVaapiContext @@ -885,8 +698,8 @@ 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_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL + (context->surfaces_pool)); } /** @@ -932,7 +745,7 @@ gst_vaapi_context_apply_composition (GstVaapiContext * context, return FALSE; if (!composition) { - gst_vaapi_context_clear_overlay (context); + context_clear_overlay (context); return TRUE; } @@ -970,11 +783,10 @@ gst_vaapi_context_apply_composition (GstVaapiContext * context, return TRUE; error: - gst_vaapi_context_clear_overlay (context); + context_clear_overlay (context); return FALSE; } - /** * gst_vaapi_context_get_attribute: * @context: a #GstVaapiContext @@ -1002,11 +814,9 @@ gst_vaapi_context_get_attribute (GstVaapiContext * context, GST_VAAPI_OBJECT_LOCK_DISPLAY (context); attrib.type = type; status = vaGetConfigAttributes (GST_VAAPI_OBJECT_VADISPLAY (context), - gst_vaapi_profile_get_va_profile (context->info.profile), - gst_vaapi_entrypoint_get_va_entrypoint (context->info.entrypoint), - &attrib, 1); + context->va_profile, context->va_entrypoint, &attrib, 1); GST_VAAPI_OBJECT_UNLOCK_DISPLAY (context); - if (!vaapi_check_status (status, "vaGetConfiAttributes()")) + if (!vaapi_check_status (status, "vaGetConfigAttributes()")) return FALSE; if (out_value_ptr) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index c996e02134..4888a837b6 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -1,5 +1,5 @@ /* - * gstvaapicontext.h - VA context abstraction + * gstvaapicontext.h - VA context abstraction (private) * * Copyright (C) 2010-2011 Splitted-Desktop Systems * Author: Gwenole Beauchesne @@ -25,19 +25,22 @@ #ifndef GST_VAAPI_CONTEXT_H #define GST_VAAPI_CONTEXT_H -#include -#include -#include -#include #include +#include "gstvaapiobject.h" +#include "gstvaapiobject_priv.h" +#include "gstvaapiprofile.h" +#include "gstvaapidisplay.h" +#include "gstvaapisurface.h" +#include "gstvaapivideopool.h" G_BEGIN_DECLS #define GST_VAAPI_CONTEXT(obj) \ ((GstVaapiContext *) (obj)) -typedef struct _GstVaapiContext GstVaapiContext; typedef struct _GstVaapiContextInfo GstVaapiContextInfo; +typedef struct _GstVaapiContext GstVaapiContext; +typedef struct _GstVaapiContextClass GstVaapiContextClass; /** * GstVaapiContextInfo: @@ -59,48 +62,51 @@ struct _GstVaapiContextInfo guint ref_frames; }; -G_GNUC_INTERNAL -GstVaapiContext * -gst_vaapi_context_new (GstVaapiDisplay * display, GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, guint width, guint height); +/** + * GstVaapiContext: + * + * A VA context wrapper. + */ +struct _GstVaapiContext +{ + /*< private >*/ + GstVaapiObject parent_instance; + + GstVaapiContextInfo info; + VAProfile va_profile; + VAEntrypoint va_entrypoint; + VAConfigID va_config; + GPtrArray *surfaces; + GstVaapiVideoPool *surfaces_pool; + GPtrArray *overlays[2]; + guint overlay_id; +}; + +/** + * GstVaapiContextClass: + * + * A VA context wrapper class. + */ +struct _GstVaapiContextClass +{ + /*< private >*/ + GstVaapiObjectClass parent_class; +}; G_GNUC_INTERNAL GstVaapiContext * -gst_vaapi_context_new_full (GstVaapiDisplay * display, +gst_vaapi_context_new (GstVaapiDisplay * display, const GstVaapiContextInfo * cip); G_GNUC_INTERNAL gboolean -gst_vaapi_context_reset (GstVaapiContext * context, GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, guint width, guint height); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_context_reset_full (GstVaapiContext * context, +gst_vaapi_context_reset (GstVaapiContext * context, const GstVaapiContextInfo * new_cip); G_GNUC_INTERNAL GstVaapiID gst_vaapi_context_get_id (GstVaapiContext * context); -G_GNUC_INTERNAL -GstVaapiProfile -gst_vaapi_context_get_profile (GstVaapiContext * context); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_context_set_profile (GstVaapiContext * context, - GstVaapiProfile profile); - -G_GNUC_INTERNAL -GstVaapiEntrypoint -gst_vaapi_context_get_entrypoint (GstVaapiContext * context); - -G_GNUC_INTERNAL -void -gst_vaapi_context_get_size (GstVaapiContext * context, - guint * pwidth, guint * pheight); - G_GNUC_INTERNAL GstVaapiSurfaceProxy * gst_vaapi_context_get_surface_proxy (GstVaapiContext * context); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 1cd81ee479..c724017876 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -953,11 +953,11 @@ gst_vaapi_decoder_ensure_context( gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height); if (decoder->context) { - if (!gst_vaapi_context_reset_full(decoder->context, cip)) + if (!gst_vaapi_context_reset(decoder->context, cip)) return FALSE; } else { - decoder->context = gst_vaapi_context_new_full(decoder->display, cip); + decoder->context = gst_vaapi_context_new(decoder->display, cip); if (!decoder->context) return FALSE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 3af06ea3a2..a0729dd8b8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -501,10 +501,10 @@ gst_vaapi_encoder_ensure_context (GstVaapiEncoder * encoder) set_context_info (encoder); if (encoder->context) { - if (!gst_vaapi_context_reset_full (encoder->context, cip)) + if (!gst_vaapi_context_reset (encoder->context, cip)) return FALSE; } else { - encoder->context = gst_vaapi_context_new_full (encoder->display, cip); + encoder->context = gst_vaapi_context_new (encoder->display, cip); if (!encoder->context) return FALSE; } From 3b714c8913ff43370f7d7bd6ec0fdb85ef72328d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 10:59:20 +0100 Subject: [PATCH 1563/3781] context: move overlay composition to separate files. Move GstVideoOverlayComposition handling to separate source files. This helps keeing GstVaapiContext core implementation to the bare minimal, i.e. simpy helpers to create a VA context and handle pool of associated VA surfaces. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapicontext.c | 403 +---------------- gst-libs/gst/vaapi/gstvaapicontext.h | 6 - gst-libs/gst/vaapi/gstvaapicontext_overlay.c | 451 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapicontext_overlay.h | 52 +++ gst-libs/gst/vaapi/gstvaapisurface.c | 1 + 6 files changed, 511 insertions(+), 404 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapicontext_overlay.c create mode 100644 gst-libs/gst/vaapi/gstvaapicontext_overlay.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 11efb4b63e..92b875aaa6 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -47,6 +47,7 @@ libgstvaapi_libs = \ libgstvaapi_source_c = \ gstvaapicodec_objects.c \ gstvaapicontext.c \ + gstvaapicontext_overlay.c \ gstvaapidecoder.c \ gstvaapidecoder_dpb.c \ gstvaapidecoder_h264.c \ @@ -110,6 +111,7 @@ libgstvaapi_source_priv_h = \ gstvaapicodec_objects.h \ gstvaapicompat.h \ gstvaapicontext.h \ + gstvaapicontext_overlay.h \ gstvaapidebug.h \ gstvaapidecoder_dpb.h \ gstvaapidecoder_objects.h \ diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index a4cc1fb841..8651e90ad6 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -30,6 +30,7 @@ #include "sysdeps.h" #include "gstvaapicompat.h" #include "gstvaapicontext.h" +#include "gstvaapicontext_overlay.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" #include "gstvaapisurface.h" @@ -37,324 +38,11 @@ #include "gstvaapisurfacepool.h" #include "gstvaapisurfaceproxy.h" #include "gstvaapivideopool_priv.h" -#include "gstvaapiimage.h" -#include "gstvaapisubpicture.h" #include "gstvaapiutils.h" #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle; -struct _GstVaapiOverlayRectangle -{ - GstVaapiContext *context; - GstVaapiSubpicture *subpicture; - GstVaapiRectangle render_rect; - guint seq_num; - guint layer_id; - GstBuffer *rect_buffer; - GstVideoOverlayRectangle *rect; - guint is_associated:1; -}; - -static inline void -gst_video_overlay_rectangle_replace (GstVideoOverlayRectangle ** old_rect_ptr, - GstVideoOverlayRectangle * new_rect) -{ - gst_mini_object_replace ((GstMiniObject **) old_rect_ptr, - GST_MINI_OBJECT_CAST (new_rect)); -} - -#define overlay_rectangle_ref(overlay) \ - gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(overlay)) - -#define overlay_rectangle_unref(overlay) \ - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(overlay)) - -#define overlay_rectangle_replace(old_overlay_ptr, new_overlay) \ - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_overlay_ptr), \ - (GstVaapiMiniObject *)(new_overlay)) - -static void overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay); - -static gboolean -overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay); - -static gboolean -overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay); - -static inline const GstVaapiMiniObjectClass * -overlay_rectangle_class (void) -{ - static const GstVaapiMiniObjectClass GstVaapiOverlayRectangleClass = { - sizeof (GstVaapiOverlayRectangle), - (GDestroyNotify) overlay_rectangle_finalize - }; - return &GstVaapiOverlayRectangleClass; -} - -static GstVaapiOverlayRectangle * -overlay_rectangle_new (GstVideoOverlayRectangle * rect, - GstVaapiContext * context, guint layer_id) -{ - GstVaapiOverlayRectangle *overlay; - GstVaapiRectangle *render_rect; - guint width, height, flags; - gint x, y; - - overlay = (GstVaapiOverlayRectangle *) - gst_vaapi_mini_object_new0 (overlay_rectangle_class ()); - if (!overlay) - return NULL; - - overlay->context = context; - overlay->seq_num = gst_video_overlay_rectangle_get_seqnum (rect); - overlay->layer_id = layer_id; - overlay->rect = gst_video_overlay_rectangle_ref (rect); - - flags = gst_video_overlay_rectangle_get_flags (rect); - gst_buffer_replace (&overlay->rect_buffer, - gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags)); - if (!overlay->rect_buffer) - goto error; - - overlay->subpicture = - gst_vaapi_subpicture_new_from_overlay_rectangle (GST_VAAPI_OBJECT_DISPLAY - (context), rect); - if (!overlay->subpicture) - goto error; - - gst_video_overlay_rectangle_get_render_rectangle (rect, - &x, &y, &width, &height); - render_rect = &overlay->render_rect; - render_rect->x = x; - render_rect->y = y; - render_rect->width = width; - render_rect->height = height; - return overlay; - -error: - overlay_rectangle_unref (overlay); - return NULL; -} - -static void -overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay) -{ - gst_buffer_replace (&overlay->rect_buffer, NULL); - gst_video_overlay_rectangle_unref (overlay->rect); - - if (overlay->subpicture) { - overlay_rectangle_deassociate (overlay); - gst_vaapi_object_unref (overlay->subpicture); - overlay->subpicture = NULL; - } -} - -static gboolean -overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay) -{ - GstVaapiSubpicture *const subpicture = overlay->subpicture; - GPtrArray *const surfaces = overlay->context->surfaces; - guint i, n_associated; - - if (overlay->is_associated) - return TRUE; - - n_associated = 0; - for (i = 0; i < surfaces->len; i++) { - GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i); - if (gst_vaapi_surface_associate_subpicture (surface, subpicture, - NULL, &overlay->render_rect)) - n_associated++; - } - - overlay->is_associated = TRUE; - return n_associated == surfaces->len; -} - -static gboolean -overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay) -{ - GstVaapiSubpicture *const subpicture = overlay->subpicture; - GPtrArray *const surfaces = overlay->context->surfaces; - guint i, n_associated; - - if (!overlay->is_associated) - return TRUE; - - n_associated = surfaces->len; - for (i = 0; i < surfaces->len; i++) { - GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i); - if (gst_vaapi_surface_deassociate_subpicture (surface, subpicture)) - n_associated--; - } - - overlay->is_associated = FALSE; - return n_associated == 0; -} - -static gboolean -overlay_rectangle_changed_pixels (GstVaapiOverlayRectangle * overlay, - GstVideoOverlayRectangle * rect) -{ - guint flags; - GstBuffer *buffer; - - if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum (rect)) - return FALSE; - - flags = - to_GstVideoOverlayFormatFlags (gst_vaapi_subpicture_get_flags - (overlay->subpicture)); - - buffer = gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags); - if (!buffer) - return FALSE; -#if GST_CHECK_VERSION(1,0,0) - { - const guint n_blocks = gst_buffer_n_memory (buffer); - gsize ofs; - guint i; - - if (buffer == overlay->rect_buffer) - return TRUE; - - if (n_blocks != gst_buffer_n_memory (overlay->rect_buffer)) - return FALSE; - - for (i = 0; i < n_blocks; i++) { - GstMemory *const mem1 = gst_buffer_peek_memory (buffer, i); - GstMemory *const mem2 = gst_buffer_peek_memory (overlay->rect_buffer, i); - if (!gst_memory_is_span (mem1, mem2, &ofs)) - return FALSE; - } - } -#else - if (GST_BUFFER_DATA (overlay->rect_buffer) != GST_BUFFER_DATA (buffer)) - return FALSE; -#endif - return TRUE; -} - -static gboolean -overlay_rectangle_changed_render_rect (GstVaapiOverlayRectangle * overlay, - GstVideoOverlayRectangle * rect) -{ - GstVaapiRectangle *const render_rect = &overlay->render_rect; - guint width, height; - gint x, y; - - gst_video_overlay_rectangle_get_render_rectangle (rect, - &x, &y, &width, &height); - - if (x == render_rect->x && - y == render_rect->y && - width == render_rect->width && height == render_rect->height) - return FALSE; - - render_rect->x = x; - render_rect->y = y; - render_rect->width = width; - render_rect->height = height; - return TRUE; -} - -static inline gboolean -overlay_rectangle_update_global_alpha (GstVaapiOverlayRectangle * overlay, - GstVideoOverlayRectangle * rect) -{ -#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS - const guint flags = gst_video_overlay_rectangle_get_flags (rect); - if (!(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)) - return TRUE; -#endif - return gst_vaapi_subpicture_set_global_alpha (overlay->subpicture, - gst_video_overlay_rectangle_get_global_alpha (rect)); -} - -static gboolean -overlay_rectangle_update (GstVaapiOverlayRectangle * overlay, - GstVideoOverlayRectangle * rect, gboolean * reassociate_ptr) -{ - if (overlay_rectangle_changed_pixels (overlay, rect)) - return FALSE; - if (overlay_rectangle_changed_render_rect (overlay, rect)) - *reassociate_ptr = TRUE; - if (!overlay_rectangle_update_global_alpha (overlay, rect)) - return FALSE; - gst_video_overlay_rectangle_replace (&overlay->rect, rect); - return TRUE; -} - -static inline GPtrArray * -overlay_new (void) -{ - return g_ptr_array_new_with_free_func ( - (GDestroyNotify) gst_vaapi_mini_object_unref); -} - -static void -overlay_destroy (GPtrArray ** overlay_ptr) -{ - GPtrArray *const overlay = *overlay_ptr; - - if (!overlay) - return; - g_ptr_array_unref (overlay); - *overlay_ptr = NULL; -} - -static void -overlay_clear (GPtrArray * overlay) -{ - if (overlay && overlay->len > 0) - g_ptr_array_remove_range (overlay, 0, overlay->len); -} - -static GstVaapiOverlayRectangle * -overlay_lookup (GPtrArray * overlays, GstVideoOverlayRectangle * rect) -{ - guint i; - - for (i = 0; i < overlays->len; i++) { - GstVaapiOverlayRectangle *const overlay = g_ptr_array_index (overlays, i); - - if (overlay->rect == rect) - return overlay; - } - return NULL; -} - -static gboolean -overlay_reassociate (GPtrArray * overlays) -{ - guint i; - - for (i = 0; i < overlays->len; i++) - overlay_rectangle_deassociate (g_ptr_array_index (overlays, i)); - - for (i = 0; i < overlays->len; i++) { - if (!overlay_rectangle_associate (g_ptr_array_index (overlays, i))) - return FALSE; - } - return TRUE; -} - -static void -context_clear_overlay (GstVaapiContext * context) -{ - overlay_clear (context->overlays[0]); - overlay_clear (context->overlays[1]); - context->overlay_id = 0; -} - -static inline void -context_destroy_overlay (GstVaapiContext * context) -{ - context_clear_overlay (context); -} - static void unref_surface_cb (GstVaapiSurface * surface) { @@ -365,7 +53,7 @@ unref_surface_cb (GstVaapiSurface * surface) static void context_destroy_surfaces (GstVaapiContext * context) { - context_destroy_overlay (context); + gst_vaapi_context_overlay_reset (context); if (context->surfaces) { g_ptr_array_unref (context->surfaces); @@ -405,16 +93,6 @@ context_destroy (GstVaapiContext * context) } } -static gboolean -context_create_overlay (GstVaapiContext * context) -{ - if (!context->overlays[0] || !context->overlays[1]) - return FALSE; - - context_clear_overlay (context); - return TRUE; -} - static gboolean context_create_surfaces (GstVaapiContext * context) { @@ -426,7 +104,7 @@ context_create_surfaces (GstVaapiContext * context) /* Number of scratch surfaces beyond those used as reference */ const guint SCRATCH_SURFACES_COUNT = 4; - if (!context_create_overlay (context)) + if (!gst_vaapi_context_overlay_reset (context)) return FALSE; num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; @@ -556,17 +234,15 @@ gst_vaapi_context_init (GstVaapiContext * context, { context->info = *cip; context->va_config = VA_INVALID_ID; - context->overlays[0] = overlay_new (); - context->overlays[1] = overlay_new (); + gst_vaapi_context_overlay_init (context); } static void gst_vaapi_context_finalize (GstVaapiContext * context) { - overlay_destroy (&context->overlays[0]); - overlay_destroy (&context->overlays[1]); context_destroy (context); context_destroy_surfaces (context); + gst_vaapi_context_overlay_finalize (context); } GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiContext, gst_vaapi_context); @@ -718,75 +394,6 @@ gst_vaapi_context_get_surface_count (GstVaapiContext * context) return gst_vaapi_video_pool_get_size (context->surfaces_pool); } -/** - * gst_vaapi_context_apply_composition: - * @context: a #GstVaapiContext - * @composition: a #GstVideoOverlayComposition - * - * Applies video composition planes to all surfaces bound to @context. - * This helper function resets any additional subpictures the user may - * have associated himself. A %NULL @composition will also clear all - * the existing subpictures. - * - * Return value: %TRUE if all composition planes could be applied, - * %FALSE otherwise - */ -gboolean -gst_vaapi_context_apply_composition (GstVaapiContext * context, - GstVideoOverlayComposition * composition) -{ - GPtrArray *curr_overlay, *next_overlay; - guint i, n_rectangles; - gboolean reassociate = FALSE; - - g_return_val_if_fail (context != NULL, FALSE); - - if (!context->surfaces) - return FALSE; - - if (!composition) { - context_clear_overlay (context); - return TRUE; - } - - curr_overlay = context->overlays[context->overlay_id]; - next_overlay = context->overlays[context->overlay_id ^ 1]; - overlay_clear (next_overlay); - - n_rectangles = gst_video_overlay_composition_n_rectangles (composition); - for (i = 0; i < n_rectangles; i++) { - GstVideoOverlayRectangle *const rect = - gst_video_overlay_composition_get_rectangle (composition, i); - GstVaapiOverlayRectangle *overlay; - - overlay = overlay_lookup (curr_overlay, rect); - if (overlay && overlay_rectangle_update (overlay, rect, &reassociate)) { - overlay_rectangle_ref (overlay); - if (overlay->layer_id != i) - reassociate = TRUE; - } else { - overlay = overlay_rectangle_new (rect, context, i); - if (!overlay) { - GST_WARNING ("could not create VA overlay rectangle"); - goto error; - } - reassociate = TRUE; - } - g_ptr_array_add (next_overlay, overlay); - } - - overlay_clear (curr_overlay); - context->overlay_id ^= 1; - - if (reassociate && !overlay_reassociate (next_overlay)) - return FALSE; - return TRUE; - -error: - context_clear_overlay (context); - return FALSE; -} - /** * gst_vaapi_context_get_attribute: * @context: a #GstVaapiContext diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 4888a837b6..8112fd4948 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -25,7 +25,6 @@ #ifndef GST_VAAPI_CONTEXT_H #define GST_VAAPI_CONTEXT_H -#include #include "gstvaapiobject.h" #include "gstvaapiobject_priv.h" #include "gstvaapiprofile.h" @@ -115,11 +114,6 @@ G_GNUC_INTERNAL guint gst_vaapi_context_get_surface_count (GstVaapiContext * context); -G_GNUC_INTERNAL -gboolean -gst_vaapi_context_apply_composition (GstVaapiContext * context, - GstVideoOverlayComposition * composition); - G_GNUC_INTERNAL gboolean gst_vaapi_context_get_attribute (GstVaapiContext * context, diff --git a/gst-libs/gst/vaapi/gstvaapicontext_overlay.c b/gst-libs/gst/vaapi/gstvaapicontext_overlay.c new file mode 100644 index 0000000000..b38e62e795 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicontext_overlay.c @@ -0,0 +1,451 @@ +/* + * gstvaapicontext_overlay.c - VA context abstraction (overlay composition) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne + * Copyright (C) 2011-2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 "gstvaapicontext_overlay.h" +#include "gstvaapiutils.h" +#include "gstvaapiimage.h" +#include "gstvaapisubpicture.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle; +struct _GstVaapiOverlayRectangle +{ + GstVaapiContext *context; + GstVaapiSubpicture *subpicture; + GstVaapiRectangle render_rect; + guint seq_num; + guint layer_id; + GstBuffer *rect_buffer; + GstVideoOverlayRectangle *rect; + guint is_associated:1; +}; + +static inline void +gst_video_overlay_rectangle_replace (GstVideoOverlayRectangle ** old_rect_ptr, + GstVideoOverlayRectangle * new_rect) +{ + gst_mini_object_replace ((GstMiniObject **) old_rect_ptr, + GST_MINI_OBJECT_CAST (new_rect)); +} + +#define overlay_rectangle_ref(overlay) \ + gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(overlay)) + +#define overlay_rectangle_unref(overlay) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(overlay)) + +#define overlay_rectangle_replace(old_overlay_ptr, new_overlay) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_overlay_ptr), \ + (GstVaapiMiniObject *)(new_overlay)) + +static void overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay); + +static gboolean +overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay); + +static gboolean +overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay); + +static inline const GstVaapiMiniObjectClass * +overlay_rectangle_class (void) +{ + static const GstVaapiMiniObjectClass GstVaapiOverlayRectangleClass = { + sizeof (GstVaapiOverlayRectangle), + (GDestroyNotify) overlay_rectangle_finalize + }; + return &GstVaapiOverlayRectangleClass; +} + +static GstVaapiOverlayRectangle * +overlay_rectangle_new (GstVideoOverlayRectangle * rect, + GstVaapiContext * context, guint layer_id) +{ + GstVaapiOverlayRectangle *overlay; + GstVaapiRectangle *render_rect; + guint width, height, flags; + gint x, y; + + overlay = (GstVaapiOverlayRectangle *) + gst_vaapi_mini_object_new0 (overlay_rectangle_class ()); + if (!overlay) + return NULL; + + overlay->context = context; + overlay->seq_num = gst_video_overlay_rectangle_get_seqnum (rect); + overlay->layer_id = layer_id; + overlay->rect = gst_video_overlay_rectangle_ref (rect); + + flags = gst_video_overlay_rectangle_get_flags (rect); + gst_buffer_replace (&overlay->rect_buffer, + gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags)); + if (!overlay->rect_buffer) + goto error; + + overlay->subpicture = + gst_vaapi_subpicture_new_from_overlay_rectangle (GST_VAAPI_OBJECT_DISPLAY + (context), rect); + if (!overlay->subpicture) + goto error; + + gst_video_overlay_rectangle_get_render_rectangle (rect, + &x, &y, &width, &height); + render_rect = &overlay->render_rect; + render_rect->x = x; + render_rect->y = y; + render_rect->width = width; + render_rect->height = height; + return overlay; + +error: + overlay_rectangle_unref (overlay); + return NULL; +} + +static void +overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay) +{ + gst_buffer_replace (&overlay->rect_buffer, NULL); + gst_video_overlay_rectangle_unref (overlay->rect); + + if (overlay->subpicture) { + overlay_rectangle_deassociate (overlay); + gst_vaapi_object_unref (overlay->subpicture); + overlay->subpicture = NULL; + } +} + +static gboolean +overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay) +{ + GstVaapiSubpicture *const subpicture = overlay->subpicture; + GPtrArray *const surfaces = overlay->context->surfaces; + guint i, n_associated; + + if (overlay->is_associated) + return TRUE; + + n_associated = 0; + for (i = 0; i < surfaces->len; i++) { + GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i); + if (gst_vaapi_surface_associate_subpicture (surface, subpicture, + NULL, &overlay->render_rect)) + n_associated++; + } + + overlay->is_associated = TRUE; + return n_associated == surfaces->len; +} + +static gboolean +overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay) +{ + GstVaapiSubpicture *const subpicture = overlay->subpicture; + GPtrArray *const surfaces = overlay->context->surfaces; + guint i, n_associated; + + if (!overlay->is_associated) + return TRUE; + + n_associated = surfaces->len; + for (i = 0; i < surfaces->len; i++) { + GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i); + if (gst_vaapi_surface_deassociate_subpicture (surface, subpicture)) + n_associated--; + } + + overlay->is_associated = FALSE; + return n_associated == 0; +} + +static gboolean +overlay_rectangle_changed_pixels (GstVaapiOverlayRectangle * overlay, + GstVideoOverlayRectangle * rect) +{ + guint flags; + GstBuffer *buffer; + + if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum (rect)) + return FALSE; + + flags = + to_GstVideoOverlayFormatFlags (gst_vaapi_subpicture_get_flags + (overlay->subpicture)); + + buffer = gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags); + if (!buffer) + return FALSE; +#if GST_CHECK_VERSION(1,0,0) + { + const guint n_blocks = gst_buffer_n_memory (buffer); + gsize ofs; + guint i; + + if (buffer == overlay->rect_buffer) + return TRUE; + + if (n_blocks != gst_buffer_n_memory (overlay->rect_buffer)) + return FALSE; + + for (i = 0; i < n_blocks; i++) { + GstMemory *const mem1 = gst_buffer_peek_memory (buffer, i); + GstMemory *const mem2 = gst_buffer_peek_memory (overlay->rect_buffer, i); + if (!gst_memory_is_span (mem1, mem2, &ofs)) + return FALSE; + } + } +#else + if (GST_BUFFER_DATA (overlay->rect_buffer) != GST_BUFFER_DATA (buffer)) + return FALSE; +#endif + return TRUE; +} + +static gboolean +overlay_rectangle_changed_render_rect (GstVaapiOverlayRectangle * overlay, + GstVideoOverlayRectangle * rect) +{ + GstVaapiRectangle *const render_rect = &overlay->render_rect; + guint width, height; + gint x, y; + + gst_video_overlay_rectangle_get_render_rectangle (rect, + &x, &y, &width, &height); + + if (x == render_rect->x && + y == render_rect->y && + width == render_rect->width && height == render_rect->height) + return FALSE; + + render_rect->x = x; + render_rect->y = y; + render_rect->width = width; + render_rect->height = height; + return TRUE; +} + +static inline gboolean +overlay_rectangle_update_global_alpha (GstVaapiOverlayRectangle * overlay, + GstVideoOverlayRectangle * rect) +{ +#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS + const guint flags = gst_video_overlay_rectangle_get_flags (rect); + if (!(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)) + return TRUE; +#endif + return gst_vaapi_subpicture_set_global_alpha (overlay->subpicture, + gst_video_overlay_rectangle_get_global_alpha (rect)); +} + +static gboolean +overlay_rectangle_update (GstVaapiOverlayRectangle * overlay, + GstVideoOverlayRectangle * rect, gboolean * reassociate_ptr) +{ + if (overlay_rectangle_changed_pixels (overlay, rect)) + return FALSE; + if (overlay_rectangle_changed_render_rect (overlay, rect)) + *reassociate_ptr = TRUE; + if (!overlay_rectangle_update_global_alpha (overlay, rect)) + return FALSE; + gst_video_overlay_rectangle_replace (&overlay->rect, rect); + return TRUE; +} + +static inline GPtrArray * +overlay_new (void) +{ + return g_ptr_array_new_with_free_func ( + (GDestroyNotify) gst_vaapi_mini_object_unref); +} + +static void +overlay_destroy (GPtrArray ** overlay_ptr) +{ + GPtrArray *const overlay = *overlay_ptr; + + if (!overlay) + return; + g_ptr_array_unref (overlay); + *overlay_ptr = NULL; +} + +static void +overlay_clear (GPtrArray * overlay) +{ + if (overlay && overlay->len > 0) + g_ptr_array_remove_range (overlay, 0, overlay->len); +} + +static GstVaapiOverlayRectangle * +overlay_lookup (GPtrArray * overlays, GstVideoOverlayRectangle * rect) +{ + guint i; + + for (i = 0; i < overlays->len; i++) { + GstVaapiOverlayRectangle *const overlay = g_ptr_array_index (overlays, i); + + if (overlay->rect == rect) + return overlay; + } + return NULL; +} + +static gboolean +overlay_reassociate (GPtrArray * overlays) +{ + guint i; + + for (i = 0; i < overlays->len; i++) + overlay_rectangle_deassociate (g_ptr_array_index (overlays, i)); + + for (i = 0; i < overlays->len; i++) { + if (!overlay_rectangle_associate (g_ptr_array_index (overlays, i))) + return FALSE; + } + return TRUE; +} + +static gboolean +overlay_ensure (GPtrArray ** overlay_ptr) +{ + GPtrArray *overlay = *overlay_ptr; + + if (!overlay) { + overlay = overlay_new (); + if (!overlay) + return FALSE; + *overlay_ptr = overlay; + } + return TRUE; +} + +/** Initializes overlay resources */ +gboolean +gst_vaapi_context_overlay_init (GstVaapiContext * context) +{ + if (!overlay_ensure (&context->overlays[0])) + return FALSE; + if (!overlay_ensure (&context->overlays[1])) + return FALSE; + return TRUE; +} + +/** Destroys overlay resources */ +void +gst_vaapi_context_overlay_finalize (GstVaapiContext * context) +{ + overlay_destroy (&context->overlays[0]); + overlay_destroy (&context->overlays[1]); +} + +/** Resets overlay resources to a clean state */ +gboolean +gst_vaapi_context_overlay_reset (GstVaapiContext * context) +{ + guint num_errors = 0; + + if (overlay_ensure (&context->overlays[0])) + overlay_clear (context->overlays[0]); + else + num_errors++; + + if (overlay_ensure (&context->overlays[1])) + overlay_clear (context->overlays[1]); + else + num_errors++; + + context->overlay_id = 0; + return num_errors == 0; +} + +/** + * gst_vaapi_context_apply_composition: + * @context: a #GstVaapiContext + * @composition: a #GstVideoOverlayComposition + * + * Applies video composition planes to all surfaces bound to @context. + * This helper function resets any additional subpictures the user may + * have associated himself. A %NULL @composition will also clear all + * the existing subpictures. + * + * Return value: %TRUE if all composition planes could be applied, + * %FALSE otherwise + */ +gboolean +gst_vaapi_context_apply_composition (GstVaapiContext * context, + GstVideoOverlayComposition * composition) +{ + GPtrArray *curr_overlay, *next_overlay; + guint i, n_rectangles; + gboolean reassociate = FALSE; + + g_return_val_if_fail (context != NULL, FALSE); + + if (!context->surfaces) + return FALSE; + + if (!composition) { + gst_vaapi_context_overlay_reset (context); + return TRUE; + } + + curr_overlay = context->overlays[context->overlay_id]; + next_overlay = context->overlays[context->overlay_id ^ 1]; + overlay_clear (next_overlay); + + n_rectangles = gst_video_overlay_composition_n_rectangles (composition); + for (i = 0; i < n_rectangles; i++) { + GstVideoOverlayRectangle *const rect = + gst_video_overlay_composition_get_rectangle (composition, i); + GstVaapiOverlayRectangle *overlay; + + overlay = overlay_lookup (curr_overlay, rect); + if (overlay && overlay_rectangle_update (overlay, rect, &reassociate)) { + overlay_rectangle_ref (overlay); + if (overlay->layer_id != i) + reassociate = TRUE; + } else { + overlay = overlay_rectangle_new (rect, context, i); + if (!overlay) { + GST_WARNING ("could not create VA overlay rectangle"); + goto error; + } + reassociate = TRUE; + } + g_ptr_array_add (next_overlay, overlay); + } + + overlay_clear (curr_overlay); + context->overlay_id ^= 1; + + if (reassociate && !overlay_reassociate (next_overlay)) + return FALSE; + return TRUE; + +error: + gst_vaapi_context_overlay_reset (context); + return FALSE; +} diff --git a/gst-libs/gst/vaapi/gstvaapicontext_overlay.h b/gst-libs/gst/vaapi/gstvaapicontext_overlay.h new file mode 100644 index 0000000000..85440e9d4c --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapicontext_overlay.h @@ -0,0 +1,52 @@ +/* + * gstvaapicontext_overlay.h - VA context abstraction (overlay composition) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne + * Copyright (C) 2011-2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_OVERLAY_H +#define GST_VAAPI_CONTEXT_OVERLAY_H + +#include +#include "gstvaapicontext.h" + +G_BEGIN_DECLS + +G_GNUC_INTERNAL +gboolean +gst_vaapi_context_overlay_init (GstVaapiContext * context); + +G_GNUC_INTERNAL +void +gst_vaapi_context_overlay_finalize (GstVaapiContext * context); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_context_overlay_reset (GstVaapiContext * context); + +G_GNUC_INTERNAL +gboolean +gst_vaapi_context_apply_composition (GstVaapiContext * context, + GstVideoOverlayComposition * composition); + +G_END_DECLS + +#endif /* GST_VAAPI_CONTEXT_OVERLAY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 40745ba429..ba848cb774 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -35,6 +35,7 @@ #include "gstvaapicontext.h" #include "gstvaapiimage.h" #include "gstvaapiimage_priv.h" +#include "gstvaapicontext_overlay.h" #define DEBUG 1 #include "gstvaapidebug.h" From e3ed05bc525ce331b3a98d1248a5127fa81a76f0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 11:44:12 +0100 Subject: [PATCH 1564/3781] context: fix get_attribute() value result. Unknown attributes, or attributes that are not supported for the given profile/entrypoint pair have a return value of VA_ATTRIB_NOT_SUPPORTED. So, return failure in this case. --- gst-libs/gst/vaapi/gstvaapicontext.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 8651e90ad6..7524b518ff 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -425,6 +425,8 @@ gst_vaapi_context_get_attribute (GstVaapiContext * context, GST_VAAPI_OBJECT_UNLOCK_DISPLAY (context); if (!vaapi_check_status (status, "vaGetConfigAttributes()")) return FALSE; + if (attrib.value == VA_ATTRIB_NOT_SUPPORTED) + return FALSE; if (out_value_ptr) *out_value_ptr = attrib.value; From 0eb40709779b4f0df27d2799eae83cff116248a9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 13:30:41 +0100 Subject: [PATCH 1565/3781] context: introduce concept of usage. Introduce GstVaapiContextUsage so that to explicitly determine the usage of a VA context. This is useful in view to simplifying the creation of VA context for VPP too. --- gst-libs/gst/vaapi/gstvaapicontext.c | 71 +++++++++++++++------------- gst-libs/gst/vaapi/gstvaapicontext.h | 15 ++++++ gst-libs/gst/vaapi/gstvaapidecoder.c | 1 + gst-libs/gst/vaapi/gstvaapiencoder.c | 1 + 4 files changed, 55 insertions(+), 33 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 7524b518ff..f09e289bb8 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -144,18 +144,18 @@ context_create (GstVaapiContext * context) const GstVaapiContextInfo *const cip = &context->info; GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); guint va_rate_control; - VAConfigAttrib attribs[2]; - guint num_attribs; + VAConfigAttrib attribs[2], *attrib = attribs; VAContextID context_id; VASurfaceID surface_id; VAStatus status; GArray *surfaces = NULL; gboolean success = FALSE; - guint i; + guint i, value; 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) @@ -170,41 +170,47 @@ context_create (GstVaapiContext * context) } g_assert (surfaces->len == context->surfaces->len); + /* Reset profile and entrypoint */ if (!cip->profile || !cip->entrypoint) goto cleanup; context->va_profile = gst_vaapi_profile_get_va_profile (cip->profile); context->va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint (cip->entrypoint); - num_attribs = 0; - attribs[num_attribs++].type = VAConfigAttribRTFormat; - if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) - attribs[num_attribs++].type = VAConfigAttribRateControl; - - GST_VAAPI_DISPLAY_LOCK (display); - status = vaGetConfigAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display), - context->va_profile, context->va_entrypoint, attribs, num_attribs); - GST_VAAPI_DISPLAY_UNLOCK (display); - if (!vaapi_check_status (status, "vaGetConfigAttributes()")) + /* Validate VA surface format */ + attrib->type = VAConfigAttribRTFormat; + if (!gst_vaapi_context_get_attribute (context, attrib->type, &value)) goto cleanup; - if (!(attribs[0].value & VA_RT_FORMAT_YUV420)) + if (!(value & VA_RT_FORMAT_YUV420)) goto cleanup; + attrib->value = VA_RT_FORMAT_YUV420; + attrib++; - if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) { - va_rate_control = from_GstVaapiRateControl (cip->rc_mode); - if (va_rate_control == VA_RC_NONE) - attribs[1].value = VA_RC_NONE; - if ((attribs[1].value & va_rate_control) != va_rate_control) { - GST_ERROR ("unsupported %s rate control", - string_of_VARateControl (va_rate_control)); - goto cleanup; + switch (cip->usage) { + case GST_VAAPI_CONTEXT_USAGE_ENCODE: + { + /* Rate control */ + attrib->type = VAConfigAttribRateControl; + if (!gst_vaapi_context_get_attribute (context, attrib->type, &value)) + goto cleanup; + + va_rate_control = from_GstVaapiRateControl (cip->rc_mode); + 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++; + break; } - attribs[1].value = va_rate_control; + default: + break; } GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateConfig (GST_VAAPI_DISPLAY_VADISPLAY (display), - context->va_profile, context->va_entrypoint, attribs, num_attribs, + context->va_profile, context->va_entrypoint, attribs, attrib - attribs, &context->va_config); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateConfig()")) @@ -314,15 +320,14 @@ gst_vaapi_context_reset (GstVaapiContext * context, cip->entrypoint = new_cip->entrypoint; } - switch (new_cip->entrypoint) { - case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: - if (cip->rc_mode != new_cip->rc_mode) { - cip->rc_mode = new_cip->rc_mode; - config_changed = TRUE; - } - break; - default: - break; + if (cip->usage != new_cip->usage) { + cip->usage = new_cip->usage; + config_changed = TRUE; + } else if (new_cip->usage == GST_VAAPI_CONTEXT_USAGE_ENCODE) { + if (cip->rc_mode != new_cip->rc_mode) { + cip->rc_mode = new_cip->rc_mode; + config_changed = TRUE; + } } if (size_changed) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 8112fd4948..f19dca57f0 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -41,6 +41,20 @@ typedef struct _GstVaapiContextInfo GstVaapiContextInfo; typedef struct _GstVaapiContext GstVaapiContext; typedef struct _GstVaapiContextClass GstVaapiContextClass; +/** + * 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; + /** * GstVaapiContextInfo: * @@ -53,6 +67,7 @@ typedef struct _GstVaapiContextClass GstVaapiContextClass; */ struct _GstVaapiContextInfo { + GstVaapiContextUsage usage; GstVaapiProfile profile; GstVaapiEntrypoint entrypoint; GstVaapiRateControl rc_mode; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index c724017876..9224b1a241 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -952,6 +952,7 @@ gst_vaapi_decoder_ensure_context( { gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height); + cip->usage = GST_VAAPI_CONTEXT_USAGE_DECODE; if (decoder->context) { if (!gst_vaapi_context_reset(decoder->context, cip)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index a0729dd8b8..23f60d2bab 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -484,6 +484,7 @@ set_context_info (GstVaapiEncoder * encoder) { GstVaapiContextInfo *const cip = &encoder->context_info; + cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; cip->profile = encoder->profile; cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; cip->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); From 14ad694fdcd10035f4e62714d322d1f2beb59f19 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 14:01:33 +0100 Subject: [PATCH 1566/3781] context: move rate-control mode to encoder specific config. Move usage-specific config out of the common GstVaapiContextInfo. Create a specialized config for encoding and move rate-control mode to there. --- gst-libs/gst/vaapi/gstvaapicontext.c | 26 ++++++++++++++++++++++---- gst-libs/gst/vaapi/gstvaapicontext.h | 19 +++++++++++++++---- gst-libs/gst/vaapi/gstvaapiencoder.c | 5 ++++- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index f09e289bb8..92a591ef0c 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -189,12 +189,14 @@ context_create (GstVaapiContext * context) switch (cip->usage) { case GST_VAAPI_CONTEXT_USAGE_ENCODE: { + const GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; + /* Rate control */ attrib->type = VAConfigAttribRateControl; if (!gst_vaapi_context_get_attribute (context, attrib->type, &value)) goto cleanup; - va_rate_control = from_GstVaapiRateControl (cip->rc_mode); + va_rate_control = from_GstVaapiRateControl (config->rc_mode); if ((value & va_rate_control) != va_rate_control) { GST_ERROR ("unsupported %s rate control", string_of_VARateControl (va_rate_control)); @@ -234,6 +236,23 @@ cleanup: return success; } +/** 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; + } + return config_changed; +} + static inline void gst_vaapi_context_init (GstVaapiContext * context, const GstVaapiContextInfo * cip) @@ -323,11 +342,10 @@ gst_vaapi_context_reset (GstVaapiContext * context, if (cip->usage != new_cip->usage) { cip->usage = new_cip->usage; config_changed = TRUE; + memcpy (&cip->config, &new_cip->config, sizeof (cip->config)); } else if (new_cip->usage == GST_VAAPI_CONTEXT_USAGE_ENCODE) { - if (cip->rc_mode != new_cip->rc_mode) { - cip->rc_mode = new_cip->rc_mode; + if (context_update_config_encoder (context, &new_cip->config.encoder)) config_changed = TRUE; - } } if (size_changed) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index f19dca57f0..680dc3e1f6 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -37,6 +37,7 @@ G_BEGIN_DECLS #define GST_VAAPI_CONTEXT(obj) \ ((GstVaapiContext *) (obj)) +typedef struct _GstVaapiConfigInfoEncoder GstVaapiConfigInfoEncoder; typedef struct _GstVaapiContextInfo GstVaapiContextInfo; typedef struct _GstVaapiContext GstVaapiContext; typedef struct _GstVaapiContextClass GstVaapiContextClass; @@ -55,25 +56,35 @@ typedef enum { GST_VAAPI_CONTEXT_USAGE_VPP, } GstVaapiContextUsage; +/** + * GstVaapiConfigInfoEncoder: + * @rc_mode: rate-control mode (#GstVaapiRateControl). + * + * Extra configuration for encoding. + */ +struct _GstVaapiConfigInfoEncoder +{ + GstVaapiRateControl rc_mode; +}; + /** * 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. - * - * Note: @rc_mode is only valid for VA context used for encoding, - * i.e. if @entrypoint is set to @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE. */ struct _GstVaapiContextInfo { GstVaapiContextUsage usage; GstVaapiProfile profile; GstVaapiEntrypoint entrypoint; - GstVaapiRateControl rc_mode; guint width; guint height; guint ref_frames; + union _GstVaapiConfigInfo { + GstVaapiConfigInfoEncoder encoder; + } config; }; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 23f60d2bab..8ec052c29c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -483,14 +483,17 @@ static void set_context_info (GstVaapiEncoder * encoder) { GstVaapiContextInfo *const cip = &encoder->context_info; + GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; cip->profile = encoder->profile; cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; - cip->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); cip->width = GST_VAAPI_ENCODER_WIDTH (encoder); cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); cip->ref_frames = encoder->num_ref_frames; + + memset (config, 0, sizeof (*config)); + config->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); } /* Ensures the underlying VA context for encoding is created */ From 1dc9837dd99e0418c083d9bd358d488ded40ba94 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 15:10:11 +0100 Subject: [PATCH 1567/3781] encoder: fix and factor out check for supported rate-control modes. Cache the first compatible GstVaapiProfile found if the encoder is not configured yet. Next, factor out the code to check for the supported rate-control modes by moving out vaGetConfigAttributes() to a separate function, while also making sure that the attribute type is actually supported by the encoder. Also fix the default set of supported rate control modes to not the "none" variant. It's totally useless to expose it at this point. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 110 ++++++++++++++------- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 3 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 3 +- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 2 + 4 files changed, 79 insertions(+), 39 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 8ec052c29c..550e3fa8b5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -468,6 +468,72 @@ error_invalid_framerate: } } +/* Gets a compatible profile for the active codec */ +static GstVaapiProfile +get_compatible_profile (GstVaapiEncoder * encoder) +{ + const GstVaapiEncoderClassData *const cdata = + GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; + GstVaapiProfile profile; + GArray *profiles; + guint i; + + profiles = gst_vaapi_display_get_encode_profiles (encoder->display); + if (!profiles) + return GST_VAAPI_PROFILE_UNKNOWN; + + // Pick a profile matching the class codec + for (i = 0; i < profiles->len; i++) { + profile = g_array_index (profiles, GstVaapiProfile, i); + if (gst_vaapi_profile_get_codec (profile) == cdata->codec) + break; + } + if (i == profiles->len) + profile = GST_VAAPI_PROFILE_UNKNOWN; + + g_array_unref (profiles); + return profile; +} + +/* Gets a supported profile for the active codec */ +static GstVaapiProfile +get_profile (GstVaapiEncoder * encoder) +{ + if (!encoder->profile) + encoder->profile = get_compatible_profile (encoder); + return encoder->profile; +} + +/* Gets config attribute for the supplied profile */ +static gboolean +get_config_attribute (GstVaapiEncoder * encoder, VAConfigAttribType type, + guint32 * out_value_ptr) +{ + GstVaapiProfile profile; + VAConfigAttrib attrib; + VAStatus status; + + profile = get_profile (encoder); + if (!profile) + return FALSE; + + GST_VAAPI_DISPLAY_LOCK (encoder->display); + attrib.type = type; + status = + vaGetConfigAttributes (GST_VAAPI_DISPLAY_VADISPLAY (encoder->display), + gst_vaapi_profile_get_va_profile (profile), VAEntrypointEncSlice, + &attrib, 1); + GST_VAAPI_DISPLAY_UNLOCK (encoder->display); + if (!vaapi_check_status (status, "vaGetConfigAttributes()")) + return FALSE; + if (attrib.value == VA_ATTRIB_NOT_SUPPORTED) + return FALSE; + + if (out_value_ptr) + *out_value_ptr = attrib.value; + return TRUE; +} + /* Determines the set of required packed headers */ static void ensure_packed_headers (GstVaapiEncoder * encoder) @@ -705,52 +771,26 @@ error_invalid_property: } /* Determine the supported rate control modes */ -static gboolean +static guint32 get_rate_control_mask (GstVaapiEncoder * encoder) { const GstVaapiEncoderClassData *const cdata = GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; - GstVaapiProfile profile; - GArray *profiles; - guint i, rate_control_mask = 0; + guint i, value, rate_control_mask = 0; - if (encoder->rate_control_mask) + if (encoder->got_rate_control_mask) return encoder->rate_control_mask; - profiles = gst_vaapi_display_get_encode_profiles (encoder->display); - if (!profiles) - goto cleanup; - - // Pick a profile matching the class codec - for (i = 0; i < profiles->len; i++) { - profile = g_array_index (profiles, GstVaapiProfile, i); - if (gst_vaapi_profile_get_codec (profile) == cdata->codec) - break; - } - - if (i != profiles->len) { - VAConfigAttrib attrib; - VAStatus status; - - attrib.type = VAConfigAttribRateControl; - GST_VAAPI_DISPLAY_LOCK (encoder->display); - status = - vaGetConfigAttributes (GST_VAAPI_DISPLAY_VADISPLAY (encoder->display), - gst_vaapi_profile_get_va_profile (profile), VAEntrypointEncSlice, - &attrib, 1); - GST_VAAPI_DISPLAY_UNLOCK (encoder->display); - if (vaapi_check_status (status, "vaGetConfigAttributes()")) { - for (i = 0; i < 32; i++) { - if (!(attrib.value & (1 << i))) - continue; - rate_control_mask |= 1 << to_GstVaapiRateControl (1 << i); - } + if (get_config_attribute (encoder, VAConfigAttribRateControl, &value)) { + for (i = 0; i < 32; i++) { + if (!(value & (1U << i))) + continue; + rate_control_mask |= 1 << to_GstVaapiRateControl (1 << i); } } - g_array_unref (profiles); GST_INFO ("supported rate controls: 0x%08x", rate_control_mask); -cleanup: + encoder->got_rate_control_mask = TRUE; encoder->rate_control_mask = cdata->rate_control_mask & rate_control_mask; return encoder->rate_control_mask; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index ec544daf77..22845e6a26 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -53,8 +53,7 @@ /* Supported set of VA rate controls, within this implementation */ #define SUPPORTED_RATECONTROLS \ - (GST_VAAPI_RATECONTROL_MASK (NONE) | \ - GST_VAAPI_RATECONTROL_MASK (CQP) | \ + (GST_VAAPI_RATECONTROL_MASK (CQP) | \ GST_VAAPI_RATECONTROL_MASK (CBR) | \ GST_VAAPI_RATECONTROL_MASK (VBR) | \ GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 95c864de40..d9938cb184 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -43,8 +43,7 @@ /* Supported set of VA rate controls, within this implementation */ #define SUPPORTED_RATECONTROLS \ - (GST_VAAPI_RATECONTROL_MASK (NONE) | \ - GST_VAAPI_RATECONTROL_MASK (CQP) | \ + (GST_VAAPI_RATECONTROL_MASK (CQP) | \ GST_VAAPI_RATECONTROL_MASK (CBR)) /* Supported set of tuning options, within this implementation */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 6106758813..96b0d1e402 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -224,6 +224,8 @@ struct _GstVaapiEncoder GstVaapiVideoPool *codedbuf_pool; GAsyncQueue *codedbuf_queue; guint32 num_codedbuf_queued; + + guint got_rate_control_mask:1; }; struct _GstVaapiEncoderClassData From 4481c155b8726190dfb466dc0b9d2fb41d92ae12 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 15:13:06 +0100 Subject: [PATCH 1568/3781] encoder: notify the encoder of the submitted packed headers. Make sure to configure the encoder with the set of packed headers we intend to generate and submit. i.e. make selection of packed headers to submit more robust. --- gst-libs/gst/vaapi/gstvaapicontext.c | 22 +++++++++++++++++- gst-libs/gst/vaapi/gstvaapicontext.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder.c | 26 +++++++++++++++------- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 5 +++++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 5 +++++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 3 +++ 6 files changed, 54 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 92a591ef0c..96f1499b55 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -144,7 +144,7 @@ context_create (GstVaapiContext * context) const GstVaapiContextInfo *const cip = &context->info; GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); guint va_rate_control; - VAConfigAttrib attribs[2], *attrib = attribs; + VAConfigAttrib attribs[3], *attrib = attribs; VAContextID context_id; VASurfaceID surface_id; VAStatus status; @@ -204,6 +204,21 @@ context_create (GstVaapiContext * context) } attrib->value = va_rate_control; attrib++; + + /* Packed headers */ + if (config->packed_headers) { + attrib->type = VAConfigAttribEncPackedHeaders; + if (!gst_vaapi_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++; + } break; } default: @@ -250,6 +265,11 @@ context_update_config_encoder (GstVaapiContext * context, 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; + } return config_changed; } diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 680dc3e1f6..24ba69777b 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -59,12 +59,14 @@ typedef enum { /** * GstVaapiConfigInfoEncoder: * @rc_mode: rate-control mode (#GstVaapiRateControl). + * @packed_headers: notify encoder that packed headers are submitted (mask). * * Extra configuration for encoding. */ struct _GstVaapiConfigInfoEncoder { GstVaapiRateControl rc_mode; + guint packed_headers; }; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 550e3fa8b5..89eb579818 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -534,14 +534,24 @@ get_config_attribute (GstVaapiEncoder * encoder, VAConfigAttribType type, return TRUE; } -/* Determines the set of required packed headers */ -static void -ensure_packed_headers (GstVaapiEncoder * encoder) +/* Determines the set of supported packed headers */ +static guint +get_packed_headers (GstVaapiEncoder * encoder) { - if (!gst_vaapi_context_get_attribute (encoder->context, - VAConfigAttribEncPackedHeaders, &encoder->packed_headers)) - encoder->packed_headers = 0; - GST_INFO ("packed headers mask: 0x%08x", encoder->packed_headers); + const GstVaapiEncoderClassData *const cdata = + GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; + guint value; + + if (encoder->got_packed_headers) + return encoder->packed_headers; + + if (!get_config_attribute (encoder, VAConfigAttribEncPackedHeaders, &value)) + value = 0; + GST_INFO ("supported packed headers: 0x%08x", value); + + encoder->got_packed_headers = TRUE; + encoder->packed_headers = cdata->packed_headers & value; + return encoder->packed_headers; } /* Updates video context */ @@ -560,6 +570,7 @@ set_context_info (GstVaapiEncoder * encoder) memset (config, 0, sizeof (*config)); config->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); + config->packed_headers = get_packed_headers (encoder); } /* Ensures the underlying VA context for encoding is created */ @@ -602,7 +613,6 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) if (!gst_vaapi_encoder_ensure_context (encoder)) goto error_reset_context; - ensure_packed_headers (encoder); codedbuf_size = encoder->codedbuf_pool ? gst_vaapi_coded_buffer_pool_get_buffer_size (GST_VAAPI_CODED_BUFFER_POOL diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 22845e6a26..9f90ea292d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -63,6 +63,11 @@ (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \ GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION)) +/* Supported set of VA packed headers, within this implementation */ +#define SUPPORTED_PACKED_HEADERS \ + (VA_ENC_PACKED_HEADER_SEQUENCE | \ + VA_ENC_PACKED_HEADER_PICTURE) + #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM 2 diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index d9938cb184..453636538a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -50,6 +50,11 @@ #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_SEQUENCE | \ + VA_ENC_PACKED_HEADER_PICTURE) + static gboolean gst_bit_writer_write_sps (GstBitWriter * bitwriter, const VAEncSequenceParameterBufferMPEG2 * seq_param); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 96b0d1e402..5cf748a7e2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -225,6 +225,7 @@ struct _GstVaapiEncoder GAsyncQueue *codedbuf_queue; guint32 num_codedbuf_queued; + guint got_packed_headers:1; guint got_rate_control_mask:1; }; @@ -232,6 +233,7 @@ struct _GstVaapiEncoderClassData { /*< private >*/ GstVaapiCodec codec; + guint32 packed_headers; GType (*rate_control_get_type)(void); GstVaapiRateControl default_rate_control; @@ -255,6 +257,7 @@ struct _GstVaapiEncoderClassData \ 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, \ From 84044f28f714379497282aa95d98ea560045cec3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 17:06:08 +0100 Subject: [PATCH 1569/3781] libs: add missing file (libgstvaapi_priv_check.h). --- gst-libs/gst/vaapi/libgstvaapi_priv_check.h | 25 +++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 gst-libs/gst/vaapi/libgstvaapi_priv_check.h diff --git a/gst-libs/gst/vaapi/libgstvaapi_priv_check.h b/gst-libs/gst/vaapi/libgstvaapi_priv_check.h new file mode 100644 index 0000000000..e7cf0e1f08 --- /dev/null +++ b/gst-libs/gst/vaapi/libgstvaapi_priv_check.h @@ -0,0 +1,25 @@ +/* + * libgstvaapi_priv_check.h - Check file is included from within libgstvaapi + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 IN_LIBGSTVAAPI +# error "This file is only meant to be included from within libgstvaapi" +#endif From 449727ea312e180e967e60fc01edc045b1987243 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 17:41:02 +0100 Subject: [PATCH 1570/3781] libs: re-indent all source code related to VA utilities. --- gst-libs/gst/vaapi/gstvaapiutils.c | 560 ++++---- gst-libs/gst/vaapi/gstvaapiutils.h | 61 +- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 1220 ++++++++--------- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 159 +-- gst-libs/gst/vaapi/gstvaapiutils_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_h264.h | 3 +- gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h | 5 +- gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h | 3 +- gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h | 3 +- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 156 +-- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 18 +- 11 files changed, 1069 insertions(+), 1121 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index a74da40468..10bc606e77 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -47,182 +47,187 @@ /* Check VA status for success or print out an error */ gboolean -vaapi_check_status(VAStatus status, const char *msg) +vaapi_check_status (VAStatus status, const gchar * msg) { - if (status != VA_STATUS_SUCCESS) { - GST_DEBUG("%s: %s", msg, vaErrorStr(status)); - return FALSE; - } - return TRUE; + if (status != VA_STATUS_SUCCESS) { + GST_DEBUG ("%s: %s", msg, vaErrorStr (status)); + return FALSE; + } + return TRUE; } /* Maps VA buffer */ -void * -vaapi_map_buffer(VADisplay dpy, VABufferID buf_id) +gpointer +vaapi_map_buffer (VADisplay dpy, VABufferID buf_id) { - VAStatus status; - void *data = NULL; + VAStatus status; + gpointer data = NULL; - status = vaMapBuffer(dpy, buf_id, &data); - if (!vaapi_check_status(status, "vaMapBuffer()")) - return NULL; - return data; + status = vaMapBuffer (dpy, buf_id, &data); + if (!vaapi_check_status (status, "vaMapBuffer()")) + return NULL; + return data; } /* Unmaps VA buffer */ void -vaapi_unmap_buffer(VADisplay dpy, VABufferID buf_id, void **pbuf) +vaapi_unmap_buffer (VADisplay dpy, VABufferID buf_id, gpointer * pbuf) { - VAStatus status; + VAStatus status; - if (pbuf) - *pbuf = NULL; + if (pbuf) + *pbuf = NULL; - status = vaUnmapBuffer(dpy, buf_id); - if (!vaapi_check_status(status, "vaUnmapBuffer()")) - return; + status = vaUnmapBuffer (dpy, buf_id); + if (!vaapi_check_status (status, "vaUnmapBuffer()")) + return; } /* Creates and maps VA buffer */ gboolean -vaapi_create_buffer( - VADisplay dpy, - VAContextID ctx, - int type, - unsigned int size, - gconstpointer buf, - VABufferID *buf_id_ptr, - gpointer *mapped_data -) +vaapi_create_buffer (VADisplay dpy, VAContextID ctx, int type, guint size, + gconstpointer buf, VABufferID * buf_id_ptr, gpointer * mapped_data) { - VABufferID buf_id; - VAStatus status; - gpointer data = (gpointer)buf; + VABufferID buf_id; + VAStatus status; + gpointer data = (gpointer) buf; - status = vaCreateBuffer(dpy, ctx, type, size, 1, data, &buf_id); - if (!vaapi_check_status(status, "vaCreateBuffer()")) - return FALSE; + status = vaCreateBuffer (dpy, ctx, type, size, 1, data, &buf_id); + if (!vaapi_check_status (status, "vaCreateBuffer()")) + return FALSE; - if (mapped_data) { - data = vaapi_map_buffer(dpy, buf_id); - if (!data) - goto error; - *mapped_data = data; - } + if (mapped_data) { + data = vaapi_map_buffer (dpy, buf_id); + if (!data) + goto error; + *mapped_data = data; + } - *buf_id_ptr = buf_id; - return TRUE; + *buf_id_ptr = buf_id; + return TRUE; error: - vaapi_destroy_buffer(dpy, &buf_id); - return FALSE; + vaapi_destroy_buffer (dpy, &buf_id); + return FALSE; } /* Destroy VA buffer */ void -vaapi_destroy_buffer(VADisplay dpy, VABufferID *buf_id_ptr) +vaapi_destroy_buffer (VADisplay dpy, VABufferID * buf_id_ptr) { - if (!buf_id_ptr || *buf_id_ptr == VA_INVALID_ID) - return; + if (!buf_id_ptr || *buf_id_ptr == VA_INVALID_ID) + return; - vaDestroyBuffer(dpy, *buf_id_ptr); - *buf_id_ptr = VA_INVALID_ID; + vaDestroyBuffer (dpy, *buf_id_ptr); + *buf_id_ptr = VA_INVALID_ID; } /* Return a string representation of a VAProfile */ -const char *string_of_VAProfile(VAProfile profile) +const gchar * +string_of_VAProfile (VAProfile profile) { - switch (profile) { + switch (profile) { #define MAP(profile) \ STRCASEP(VAProfile, profile) - MAP(MPEG2Simple); - MAP(MPEG2Main); - MAP(MPEG4Simple); - MAP(MPEG4AdvancedSimple); - MAP(MPEG4Main); + MAP (MPEG2Simple); + MAP (MPEG2Main); + MAP (MPEG4Simple); + MAP (MPEG4AdvancedSimple); + MAP (MPEG4Main); #if VA_CHECK_VERSION(0,32,0) - MAP(JPEGBaseline); - MAP(H263Baseline); - MAP(H264ConstrainedBaseline); + MAP (JPEGBaseline); + MAP (H263Baseline); + MAP (H264ConstrainedBaseline); #endif - MAP(H264Baseline); - MAP(H264Main); - MAP(H264High); - MAP(VC1Simple); - MAP(VC1Main); - MAP(VC1Advanced); + MAP (H264Baseline); + MAP (H264Main); + MAP (H264High); + MAP (VC1Simple); + MAP (VC1Main); + MAP (VC1Advanced); #undef MAP - default: break; - } - return ""; + default: + break; + } + return ""; } /* Return a string representation of a VAEntrypoint */ -const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) +const gchar * +string_of_VAEntrypoint (VAEntrypoint entrypoint) { - switch (entrypoint) { + switch (entrypoint) { #define MAP(entrypoint) \ STRCASEP(VAEntrypoint, entrypoint) - MAP(VLD); - MAP(IZZ); - MAP(IDCT); - MAP(MoComp); - MAP(Deblocking); + MAP (VLD); + MAP (IZZ); + MAP (IDCT); + MAP (MoComp); + MAP (Deblocking); #undef MAP - default: break; - } - return ""; + default: + break; + } + return ""; } /* Return a string representation of a VADisplayAttributeType */ -const char * -string_of_VADisplayAttributeType(VADisplayAttribType attribute_type) +const gchar * +string_of_VADisplayAttributeType (VADisplayAttribType attribute_type) { - switch (attribute_type) { + switch (attribute_type) { #define MAP(attribute_type) \ STRCASEP(VADisplayAttrib, attribute_type) - MAP(Brightness); - MAP(Contrast); - MAP(Hue); - MAP(Saturation); - MAP(BackgroundColor); + MAP (Brightness); + MAP (Contrast); + MAP (Hue); + MAP (Saturation); + MAP (BackgroundColor); #if !VA_CHECK_VERSION(0,34,0) - MAP(DirectSurface); + MAP (DirectSurface); #endif - MAP(Rotation); - MAP(OutofLoopDeblock); + MAP (Rotation); + MAP (OutofLoopDeblock); #if VA_CHECK_VERSION(0,31,1) && !VA_CHECK_VERSION(0,34,0) - MAP(BLEBlackMode); - MAP(BLEWhiteMode); - MAP(BlueStretch); - MAP(SkinColorCorrection); + MAP (BLEBlackMode); + MAP (BLEWhiteMode); + MAP (BlueStretch); + MAP (SkinColorCorrection); #endif - MAP(CSCMatrix); - MAP(BlendColor); - MAP(OverlayAutoPaintColorKey); - MAP(OverlayColorKey); - MAP(RenderMode); - MAP(RenderDevice); - MAP(RenderRect); + MAP (CSCMatrix); + MAP (BlendColor); + MAP (OverlayAutoPaintColorKey); + MAP (OverlayColorKey); + MAP (RenderMode); + MAP (RenderDevice); + MAP (RenderRect); #undef MAP - default: break; - } - return ""; + default: + break; + } + return ""; } -const char * -string_of_VARateControl(guint rate_control) +const gchar * +string_of_VARateControl (guint rate_control) { - switch (rate_control) { - case VA_RC_NONE: return "None"; - case VA_RC_CQP: return "CQP"; - case VA_RC_CBR: return "CBR"; - case VA_RC_VCM: return "VCM"; - case VA_RC_VBR: return "VBR"; - case VA_RC_VBR_CONSTRAINED: return "VBR-Constrained"; - default: break; - } - return ""; + switch (rate_control) { + case VA_RC_NONE: + return "None"; + case VA_RC_CQP: + return "CQP"; + case VA_RC_CBR: + return "CBR"; + case VA_RC_VCM: + return "VCM"; + case VA_RC_VBR: + return "VBR"; + case VA_RC_VBR_CONSTRAINED: + return "VBR-Constrained"; + default: + break; + } + return ""; } /** @@ -233,39 +238,39 @@ string_of_VARateControl(guint rate_control) * vaCreateSurfaces(). */ guint -from_GstVaapiChromaType(guint chroma_type) +from_GstVaapiChromaType (guint chroma_type) { - guint format; + guint format; - switch (chroma_type) { + switch (chroma_type) { case GST_VAAPI_CHROMA_TYPE_YUV420: - format = VA_RT_FORMAT_YUV420; - break; + format = VA_RT_FORMAT_YUV420; + break; case GST_VAAPI_CHROMA_TYPE_YUV422: - format = VA_RT_FORMAT_YUV422; - break; + format = VA_RT_FORMAT_YUV422; + break; case GST_VAAPI_CHROMA_TYPE_YUV444: - format = VA_RT_FORMAT_YUV444; - break; + format = VA_RT_FORMAT_YUV444; + break; #if VA_CHECK_VERSION(0,34,0) case GST_VAAPI_CHROMA_TYPE_YUV411: - format = VA_RT_FORMAT_YUV411; - break; + format = VA_RT_FORMAT_YUV411; + break; case GST_VAAPI_CHROMA_TYPE_YUV400: - format = VA_RT_FORMAT_YUV400; - break; + format = VA_RT_FORMAT_YUV400; + break; case GST_VAAPI_CHROMA_TYPE_RGB32: - format = VA_RT_FORMAT_RGB32; - break; + format = VA_RT_FORMAT_RGB32; + break; case GST_VAAPI_CHROMA_TYPE_RGB16: - format = VA_RT_FORMAT_RGB16; - break; + format = VA_RT_FORMAT_RGB16; + break; #endif default: - format = 0; - break; - } - return format; + format = 0; + break; + } + return format; } /** @@ -276,17 +281,17 @@ from_GstVaapiChromaType(guint chroma_type) * vaAssociateSubpicture(). */ guint -from_GstVaapiSubpictureFlags(guint flags) +from_GstVaapiSubpictureFlags (guint flags) { - guint va_flags = 0; + guint va_flags = 0; - if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) - va_flags |= VA_SUBPICTURE_GLOBAL_ALPHA; + if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) + va_flags |= VA_SUBPICTURE_GLOBAL_ALPHA; #ifdef VA_SUBPICTURE_PREMULTIPLIED_ALPHA - if (flags & GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA) - flags |= VA_SUBPICTURE_PREMULTIPLIED_ALPHA; + if (flags & GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA) + flags |= VA_SUBPICTURE_PREMULTIPLIED_ALPHA; #endif - return va_flags; + return va_flags; } /** @@ -299,17 +304,17 @@ from_GstVaapiSubpictureFlags(guint flags) * Return value: the #GstVaapiSubpictureFlags flags */ guint -to_GstVaapiSubpictureFlags(guint va_flags) +to_GstVaapiSubpictureFlags (guint va_flags) { - guint flags = 0; + guint flags = 0; - if (va_flags & VA_SUBPICTURE_GLOBAL_ALPHA) - flags |= GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA; + if (va_flags & VA_SUBPICTURE_GLOBAL_ALPHA) + flags |= GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA; #ifdef VA_SUBPICTURE_PREMULTIPLIED_ALPHA - if (va_flags & VA_SUBPICTURE_PREMULTIPLIED_ALPHA) - flags |= GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA; + if (va_flags & VA_SUBPICTURE_PREMULTIPLIED_ALPHA) + flags |= GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA; #endif - return flags; + return flags; } /** @@ -321,17 +326,17 @@ to_GstVaapiSubpictureFlags(guint va_flags) * Return value: the #GstVaapiSubpictureFlags flags */ guint -from_GstVideoOverlayFormatFlags(guint ovl_flags) +from_GstVideoOverlayFormatFlags (guint ovl_flags) { - guint flags = 0; + guint flags = 0; #ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS - if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA) - flags |= GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA; - if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA) - flags |= GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA; + if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA) + flags |= GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA; + if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA) + flags |= GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA; #endif - return flags; + return flags; } /** @@ -343,17 +348,17 @@ from_GstVideoOverlayFormatFlags(guint ovl_flags) * Return value: the #GstVideoOverlayFormatFlags flags */ guint -to_GstVideoOverlayFormatFlags(guint flags) +to_GstVideoOverlayFormatFlags (guint flags) { - guint ovl_flags = 0; + guint ovl_flags = 0; #ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS - if (flags & GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA) - ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA; - if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) - ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA; + if (flags & GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA) + ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA; + if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) + ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA; #endif - return ovl_flags; + return ovl_flags; } /** @@ -364,45 +369,45 @@ to_GstVideoOverlayFormatFlags(guint flags) * vaPutSurface(). */ guint -from_GstVaapiSurfaceRenderFlags(guint flags) +from_GstVaapiSurfaceRenderFlags (guint flags) { - guint va_fields, va_csc; + guint va_fields, va_csc; - /* Picture structure */ - switch (flags & GST_VAAPI_PICTURE_STRUCTURE_MASK) { + /* Picture structure */ + switch (flags & GST_VAAPI_PICTURE_STRUCTURE_MASK) { case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: - va_fields = VA_TOP_FIELD; - break; + va_fields = VA_TOP_FIELD; + break; case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: - va_fields = VA_BOTTOM_FIELD; - break; + va_fields = VA_BOTTOM_FIELD; + break; default: - va_fields = VA_FRAME_PICTURE; - break; - } + va_fields = VA_FRAME_PICTURE; + break; + } - /* Color standard */ - switch (flags & GST_VAAPI_COLOR_STANDARD_MASK) { + /* Color standard */ + switch (flags & GST_VAAPI_COLOR_STANDARD_MASK) { #ifdef VA_SRC_BT601 case GST_VAAPI_COLOR_STANDARD_ITUR_BT_601: - va_csc = VA_SRC_BT601; - break; + va_csc = VA_SRC_BT601; + break; #endif #ifdef VA_SRC_BT709 case GST_VAAPI_COLOR_STANDARD_ITUR_BT_709: - va_csc = VA_SRC_BT709; - break; + va_csc = VA_SRC_BT709; + break; #endif #ifdef VA_SRC_SMPTE_240 case GST_VAAPI_COLOR_STANDARD_SMPTE_240M: - va_csc = VA_SRC_SMPTE_240; - break; + va_csc = VA_SRC_SMPTE_240; + break; #endif default: - va_csc = 0; - break; - } - return va_fields|va_csc; + va_csc = 0; + break; + } + return va_fields | va_csc; } /** @@ -415,132 +420,151 @@ from_GstVaapiSurfaceRenderFlags(guint flags) * Return value: the #GstVaapiSurfaceStatus flags */ guint -to_GstVaapiSurfaceStatus(guint va_flags) +to_GstVaapiSurfaceStatus (guint va_flags) { - guint flags; - const guint va_flags_mask = (VASurfaceReady| - VASurfaceRendering| - VASurfaceDisplaying); + guint flags; + const guint va_flags_mask = (VASurfaceReady | + VASurfaceRendering | VASurfaceDisplaying); - /* Check for core status */ - switch (va_flags & va_flags_mask) { + /* Check for core status */ + switch (va_flags & va_flags_mask) { case VASurfaceReady: - flags = GST_VAAPI_SURFACE_STATUS_IDLE; - break; + flags = GST_VAAPI_SURFACE_STATUS_IDLE; + break; case VASurfaceRendering: - flags = GST_VAAPI_SURFACE_STATUS_RENDERING; - break; + flags = GST_VAAPI_SURFACE_STATUS_RENDERING; + break; case VASurfaceDisplaying: - flags = GST_VAAPI_SURFACE_STATUS_DISPLAYING; - break; + flags = GST_VAAPI_SURFACE_STATUS_DISPLAYING; + break; default: - flags = 0; - break; - } + flags = 0; + break; + } - /* Check for encoder status */ + /* Check for encoder status */ #if VA_CHECK_VERSION(0,30,0) - if (va_flags & VASurfaceSkipped) - flags |= GST_VAAPI_SURFACE_STATUS_SKIPPED; + if (va_flags & VASurfaceSkipped) + flags |= GST_VAAPI_SURFACE_STATUS_SKIPPED; #endif - return flags; + return flags; } /* Translate GstVaapiRotation value to VA-API rotation value */ guint -from_GstVaapiRotation(guint value) +from_GstVaapiRotation (guint value) { - switch (value) { - case GST_VAAPI_ROTATION_0: return VA_ROTATION_NONE; - case GST_VAAPI_ROTATION_90: return VA_ROTATION_90; - case GST_VAAPI_ROTATION_180: return VA_ROTATION_180; - case GST_VAAPI_ROTATION_270: return VA_ROTATION_270; - } - GST_ERROR("unsupported GstVaapiRotation value %d", value); - return VA_ROTATION_NONE; + switch (value) { + case GST_VAAPI_ROTATION_0: + return VA_ROTATION_NONE; + case GST_VAAPI_ROTATION_90: + return VA_ROTATION_90; + case GST_VAAPI_ROTATION_180: + return VA_ROTATION_180; + case GST_VAAPI_ROTATION_270: + return VA_ROTATION_270; + } + GST_ERROR ("unsupported GstVaapiRotation value %d", value); + return VA_ROTATION_NONE; } /* Translate VA-API rotation value to GstVaapiRotation value */ guint -to_GstVaapiRotation(guint value) +to_GstVaapiRotation (guint value) { - switch (value) { - case VA_ROTATION_NONE: return GST_VAAPI_ROTATION_0; - case VA_ROTATION_90: return GST_VAAPI_ROTATION_90; - case VA_ROTATION_180: return GST_VAAPI_ROTATION_180; - case VA_ROTATION_270: return GST_VAAPI_ROTATION_270; - } - GST_ERROR("unsupported VA-API rotation value %d", value); - return GST_VAAPI_ROTATION_0; + switch (value) { + case VA_ROTATION_NONE: + return GST_VAAPI_ROTATION_0; + case VA_ROTATION_90: + return GST_VAAPI_ROTATION_90; + case VA_ROTATION_180: + return GST_VAAPI_ROTATION_180; + case VA_ROTATION_270: + return GST_VAAPI_ROTATION_270; + } + GST_ERROR ("unsupported VA-API rotation value %d", value); + return GST_VAAPI_ROTATION_0; } guint -from_GstVaapiRateControl(guint value) +from_GstVaapiRateControl (guint value) { - switch (value) { - case GST_VAAPI_RATECONTROL_NONE: return VA_RC_NONE; - case GST_VAAPI_RATECONTROL_CQP: return VA_RC_CQP; - case GST_VAAPI_RATECONTROL_CBR: return VA_RC_CBR; - case GST_VAAPI_RATECONTROL_VCM: return VA_RC_VCM; - case GST_VAAPI_RATECONTROL_VBR: return VA_RC_VBR; - case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: return VA_RC_VBR_CONSTRAINED; - } - GST_ERROR("unsupported GstVaapiRateControl value %u", value); - return VA_RC_NONE; + switch (value) { + case GST_VAAPI_RATECONTROL_NONE: + return VA_RC_NONE; + case GST_VAAPI_RATECONTROL_CQP: + return VA_RC_CQP; + case GST_VAAPI_RATECONTROL_CBR: + return VA_RC_CBR; + case GST_VAAPI_RATECONTROL_VCM: + return VA_RC_VCM; + case GST_VAAPI_RATECONTROL_VBR: + return VA_RC_VBR; + case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: + return VA_RC_VBR_CONSTRAINED; + } + GST_ERROR ("unsupported GstVaapiRateControl value %u", value); + return VA_RC_NONE; } guint -to_GstVaapiRateControl(guint value) +to_GstVaapiRateControl (guint value) { - switch (value) { - case VA_RC_NONE: return GST_VAAPI_RATECONTROL_NONE; - case VA_RC_CQP: return GST_VAAPI_RATECONTROL_CQP; - case VA_RC_CBR: return GST_VAAPI_RATECONTROL_CBR; - case VA_RC_VCM: return GST_VAAPI_RATECONTROL_VCM; - case VA_RC_VBR: return GST_VAAPI_RATECONTROL_VBR; - case VA_RC_VBR_CONSTRAINED: return GST_VAAPI_RATECONTROL_VBR_CONSTRAINED; - } - GST_ERROR("unsupported VA-API Rate Control value %u", value); - return GST_VAAPI_RATECONTROL_NONE; + switch (value) { + case VA_RC_NONE: + return GST_VAAPI_RATECONTROL_NONE; + case VA_RC_CQP: + return GST_VAAPI_RATECONTROL_CQP; + case VA_RC_CBR: + return GST_VAAPI_RATECONTROL_CBR; + case VA_RC_VCM: + return GST_VAAPI_RATECONTROL_VCM; + case VA_RC_VBR: + return GST_VAAPI_RATECONTROL_VBR; + case VA_RC_VBR_CONSTRAINED: + return GST_VAAPI_RATECONTROL_VBR_CONSTRAINED; + } + GST_ERROR ("unsupported VA-API Rate Control value %u", value); + return GST_VAAPI_RATECONTROL_NONE; } /* VPP: translate GstVaapiDeinterlaceMethod to VA deinterlacing algorithm */ guint -from_GstVaapiDeinterlaceMethod(guint value) +from_GstVaapiDeinterlaceMethod (guint value) { - switch (value) { + switch (value) { case GST_VAAPI_DEINTERLACE_METHOD_NONE: - return 0; + return 0; #if USE_VA_VPP case GST_VAAPI_DEINTERLACE_METHOD_BOB: - return VAProcDeinterlacingBob; + return VAProcDeinterlacingBob; case GST_VAAPI_DEINTERLACE_METHOD_WEAVE: - return VAProcDeinterlacingWeave; + return VAProcDeinterlacingWeave; case GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE: - return VAProcDeinterlacingMotionAdaptive; + return VAProcDeinterlacingMotionAdaptive; case GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED: - return VAProcDeinterlacingMotionCompensated; + return VAProcDeinterlacingMotionCompensated; #endif - } - GST_ERROR("unsupported GstVaapiDeinterlaceMethod value %d", value); - return 0; + } + GST_ERROR ("unsupported GstVaapiDeinterlaceMethod value %d", value); + return 0; } /* VPP: translate GstVaapiDeinterlaceFlags into VA deinterlacing flags */ guint -from_GstVaapiDeinterlaceFlags(guint flags) +from_GstVaapiDeinterlaceFlags (guint flags) { - guint va_flags = 0; + guint va_flags = 0; #if USE_VA_VPP - if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF)) - va_flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST; + if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF)) + va_flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST; - if (flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD) - va_flags |= VA_DEINTERLACING_ONE_FIELD; + if (flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD) + va_flags |= VA_DEINTERLACING_ONE_FIELD; - if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD)) - va_flags |= VA_DEINTERLACING_BOTTOM_FIELD; + if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD)) + va_flags |= VA_DEINTERLACING_BOTTOM_FIELD; #endif - return va_flags; + return va_flags; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 9fcab47146..fb5b1e49c1 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -33,103 +33,98 @@ /** Check VA status for success or print out an error */ G_GNUC_INTERNAL gboolean -vaapi_check_status(VAStatus status, const char *msg); +vaapi_check_status (VAStatus status, const gchar *msg); /** Maps VA buffer */ G_GNUC_INTERNAL -void * -vaapi_map_buffer(VADisplay dpy, VABufferID buf_id); +gpointer +vaapi_map_buffer (VADisplay dpy, VABufferID buf_id); /** Unmaps VA buffer */ G_GNUC_INTERNAL void -vaapi_unmap_buffer(VADisplay dpy, VABufferID buf_id, void **pbuf); +vaapi_unmap_buffer (VADisplay dpy, VABufferID buf_id, void **pbuf); /** Creates and maps VA buffer */ G_GNUC_INTERNAL gboolean -vaapi_create_buffer( - VADisplay dpy, - VAContextID ctx, - int type, - unsigned int size, - gconstpointer data, - VABufferID *buf_id, - gpointer *mapped_data -); +vaapi_create_buffer (VADisplay dpy, VAContextID ctx, int type, guint size, + gconstpointer data, VABufferID * buf_id, gpointer * mapped_data); /** Destroy VA buffer */ G_GNUC_INTERNAL void -vaapi_destroy_buffer(VADisplay dpy, VABufferID *buf_id); +vaapi_destroy_buffer (VADisplay dpy, VABufferID * buf_id); /** Return a string representation of a VAProfile */ G_GNUC_INTERNAL -const char *string_of_VAProfile(VAProfile profile); +const gchar * +string_of_VAProfile (VAProfile profile); /** Return a string representation of a VAEntrypoint */ G_GNUC_INTERNAL -const char *string_of_VAEntrypoint(VAEntrypoint entrypoint); +const gchar * +string_of_VAEntrypoint (VAEntrypoint entrypoint); /* Return a string representation of a VADisplayAttributeType */ G_GNUC_INTERNAL -const char * -string_of_VADisplayAttributeType(VADisplayAttribType attribute_type); +const gchar * +string_of_VADisplayAttributeType (VADisplayAttribType attribute_type); G_GNUC_INTERNAL -const char * -string_of_VARateControl(guint rate_control); +const gchar * +string_of_VARateControl (guint rate_control); G_GNUC_INTERNAL guint -from_GstVaapiChromaType(guint chroma_type); +from_GstVaapiChromaType (guint chroma_type); G_GNUC_INTERNAL guint -from_GstVaapiSubpictureFlags(guint flags); +from_GstVaapiSubpictureFlags (guint flags); G_GNUC_INTERNAL guint -to_GstVaapiSubpictureFlags(guint va_flags); +to_GstVaapiSubpictureFlags (guint va_flags); G_GNUC_INTERNAL guint -from_GstVideoOverlayFormatFlags(guint ovl_flags); +from_GstVideoOverlayFormatFlags (guint ovl_flags); G_GNUC_INTERNAL guint -to_GstVideoOverlayFormatFlags(guint flags); +to_GstVideoOverlayFormatFlags (guint flags); G_GNUC_INTERNAL guint -from_GstVaapiSurfaceRenderFlags(guint flags); +from_GstVaapiSurfaceRenderFlags (guint flags); G_GNUC_INTERNAL guint -to_GstVaapiSurfaceStatus(guint va_flags); +to_GstVaapiSurfaceStatus (guint va_flags); G_GNUC_INTERNAL guint -from_GstVaapiRotation(guint value); +from_GstVaapiRotation (guint value); G_GNUC_INTERNAL guint -to_GstVaapiRotation(guint value); +to_GstVaapiRotation (guint value); G_GNUC_INTERNAL guint -from_GstVaapiRateControl(guint value); +from_GstVaapiRateControl (guint value); G_GNUC_INTERNAL guint -to_GstVaapiRateControl(guint value); +to_GstVaapiRateControl (guint value); G_GNUC_INTERNAL guint -from_GstVaapiDeinterlaceMethod(guint value); +from_GstVaapiDeinterlaceMethod (guint value); G_GNUC_INTERNAL guint -from_GstVaapiDeinterlaceFlags(guint flags); +from_GstVaapiDeinterlaceFlags (guint flags); #endif /* GST_VAAPI_UTILS_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index c47c9aaf66..b21cb6c961 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -22,7 +22,7 @@ * Boston, MA 02110-1301 USA */ -#define _GNU_SOURCE 1 /* RTLD_DEFAULT */ +#define _GNU_SOURCE 1 /* RTLD_DEFAULT */ #include "sysdeps.h" #include #include @@ -35,23 +35,23 @@ /** Lookup for substring NAME in string EXT using SEP as separators */ static gboolean -find_string(const char *name, const char *ext, const char *sep) +find_string (const gchar *name, const gchar *ext, const gchar *sep) { - const char *end; - int name_len, n; + const gchar *end; + int name_len, n; - if (!name || !ext) - return FALSE; - - end = ext + strlen(ext); - name_len = strlen(name); - while (ext < end) { - n = strcspn(ext, sep); - if (n == name_len && strncmp(name, ext, n) == 0) - return TRUE; - ext += (n + 1); - } + if (!name || !ext) return FALSE; + + end = ext + strlen (ext); + name_len = strlen (name); + while (ext < end) { + n = strcspn (ext, sep); + if (n == name_len && strncmp (name, ext, n) == 0) + return TRUE; + ext += (n + 1); + } + return FALSE; } /** @@ -62,27 +62,28 @@ find_string(const char *name, const char *ext, const char *sep) * * Return error: the static string representing the OpenGL @error */ -const char * -gl_get_error_string(GLenum error) +const gchar * +gl_get_error_string (GLenum error) { - switch (error) { + switch (error) { #define MAP(id, str) \ case id: return str " (" #id ")" - MAP(GL_NO_ERROR, "no error"); - MAP(GL_INVALID_ENUM, "invalid enumerant"); - MAP(GL_INVALID_VALUE, "invalid value"); - MAP(GL_INVALID_OPERATION, "invalid operation"); - MAP(GL_STACK_OVERFLOW, "stack overflow"); - MAP(GL_STACK_UNDERFLOW, "stack underflow"); - MAP(GL_OUT_OF_MEMORY, "out of memory"); + MAP (GL_NO_ERROR, "no error"); + MAP (GL_INVALID_ENUM, "invalid enumerant"); + MAP (GL_INVALID_VALUE, "invalid value"); + MAP (GL_INVALID_OPERATION, "invalid operation"); + MAP (GL_STACK_OVERFLOW, "stack overflow"); + MAP (GL_STACK_UNDERFLOW, "stack underflow"); + MAP (GL_OUT_OF_MEMORY, "out of memory"); #ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT - MAP(GL_INVALID_FRAMEBUFFER_OPERATION_EXT, - "invalid framebuffer operation"); + MAP (GL_INVALID_FRAMEBUFFER_OPERATION_EXT, + "invalid framebuffer operation"); #endif #undef MAP - default: break; - }; - return ""; + default: + break; + }; + return ""; } /** @@ -92,10 +93,9 @@ gl_get_error_string(GLenum error) * clear up the pending errors prior to calling gl_check_error(). */ void -gl_purge_errors(void) +gl_purge_errors (void) { - while (glGetError() != GL_NO_ERROR) - ; /* nothing */ + while (glGetError () != GL_NO_ERROR); /* nothing */ } /** @@ -106,16 +106,16 @@ gl_purge_errors(void) * Return value: %TRUE if an error was encountered */ gboolean -gl_check_error(void) +gl_check_error (void) { - GLenum error; - gboolean has_errors = FALSE; + GLenum error; + gboolean has_errors = FALSE; - while ((error = glGetError()) != GL_NO_ERROR) { - GST_DEBUG("glError: %s caught", gl_get_error_string(error)); - has_errors = TRUE; - } - return has_errors; + while ((error = glGetError ()) != GL_NO_ERROR) { + GST_DEBUG ("glError: %s caught", gl_get_error_string (error)); + has_errors = TRUE; + } + return has_errors; } /** @@ -129,18 +129,18 @@ gl_check_error(void) * Return value: %TRUE on success */ gboolean -gl_get_param(GLenum param, guint *pval) +gl_get_param (GLenum param, guint * pval) { - GLint val; + GLint val; - gl_purge_errors(); - glGetIntegerv(param, &val); - if (gl_check_error()) - return FALSE; + gl_purge_errors (); + glGetIntegerv (param, &val); + if (gl_check_error ()) + return FALSE; - if (pval) - *pval = val; - return TRUE; + if (pval) + *pval = val; + return TRUE; } /** @@ -155,18 +155,18 @@ gl_get_param(GLenum param, guint *pval) * Return value: %TRUE on success */ gboolean -gl_get_texture_param(GLenum target, GLenum param, guint *pval) +gl_get_texture_param (GLenum target, GLenum param, guint * pval) { - GLint val; + GLint val; - gl_purge_errors(); - glGetTexLevelParameteriv(target, 0, param, &val); - if (gl_check_error()) - return FALSE; + gl_purge_errors (); + glGetTexLevelParameteriv (target, 0, param, &val); + if (gl_check_error ()) + return FALSE; - if (pval) - *pval = val; - return TRUE; + if (pval) + *pval = val; + return TRUE; } /** @@ -178,28 +178,28 @@ gl_get_texture_param(GLenum target, GLenum param, guint *pval) * Return value: texture binding type for @target */ static GLenum -gl_get_texture_binding(GLenum target) +gl_get_texture_binding (GLenum target) { - GLenum binding; + GLenum binding; - switch (target) { + switch (target) { case GL_TEXTURE_1D: - binding = GL_TEXTURE_BINDING_1D; - break; + binding = GL_TEXTURE_BINDING_1D; + break; case GL_TEXTURE_2D: - binding = GL_TEXTURE_BINDING_2D; - break; + binding = GL_TEXTURE_BINDING_2D; + break; case GL_TEXTURE_3D: - binding = GL_TEXTURE_BINDING_3D; - break; + binding = GL_TEXTURE_BINDING_3D; + break; case GL_TEXTURE_RECTANGLE_ARB: - binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; - break; + binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; + break; default: - binding = 0; - break; - } - return binding; + binding = 0; + break; + } + return binding; } /** @@ -210,14 +210,11 @@ gl_get_texture_binding(GLenum target) * wrapper around glClearColor(). */ void -gl_set_bgcolor(guint32 color) +gl_set_bgcolor (guint32 color) { - glClearColor( - ((color >> 16) & 0xff) / 255.0f, - ((color >> 8) & 0xff) / 255.0f, - ( color & 0xff) / 255.0f, - 1.0f - ); + glClearColor ( + ((color >> 16) & 0xff) / 255.0f, + ((color >> 8) & 0xff) / 255.0f, (color & 0xff) / 255.0f, 1.0f); } /** @@ -235,17 +232,18 @@ gl_set_bgcolor(guint32 color) * basically is the Mesa implementation of gluPerspective(). */ static void -gl_perspective(GLdouble fovy, GLdouble aspect, GLdouble near_val, GLdouble far_val) +gl_perspective (GLdouble fovy, GLdouble aspect, GLdouble near_val, + GLdouble far_val) { - GLdouble left, right, top, bottom; + GLdouble left, right, top, bottom; - /* Source (Q 9.085): - */ - top = tan(fovy * M_PI / 360.0) * near_val; - bottom = -top; - left = aspect * bottom; - right = aspect * top; - glFrustum(left, right, bottom, top, near_val, far_val); + /* Source (Q 9.085): + */ + top = tan (fovy * M_PI / 360.0) * near_val; + bottom = -top; + left = aspect * bottom; + right = aspect * top; + glFrustum (left, right, bottom, top, near_val, far_val); } /** @@ -258,7 +256,7 @@ gl_perspective(GLdouble fovy, GLdouble aspect, GLdouble near_val, GLdouble far_v * window. */ void -gl_resize(guint width, guint height) +gl_resize (guint width, guint height) { #define FOVY 60.0f #define ASPECT 1.0f @@ -266,16 +264,16 @@ gl_resize(guint width, guint height) #define Z_FAR 100.0f #define Z_CAMERA 0.869f - glViewport(0, 0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gl_perspective(FOVY, ASPECT, Z_NEAR, Z_FAR); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + glViewport (0, 0, width, height); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + gl_perspective (FOVY, ASPECT, Z_NEAR, Z_FAR); + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); - glTranslatef(-0.5f, -0.5f, -Z_CAMERA); - glScalef(1.0f/width, -1.0f/height, 1.0f/width); - glTranslatef(0.0f, -1.0f*height, 0.0f); + glTranslatef (-0.5f, -0.5f, -Z_CAMERA); + glScalef (1.0f / width, -1.0f / height, 1.0f / width); + glTranslatef (0.0f, -1.0f * height, 0.0f); } /** @@ -290,101 +288,85 @@ gl_resize(guint width, guint height) * Return value: the newly created GLX context */ GLContextState * -gl_create_context(Display *dpy, int screen, GLContextState *parent) +gl_create_context (Display * dpy, int screen, GLContextState * parent) { - GLContextState *cs; - GLXFBConfig *fbconfigs = NULL; - int fbconfig_id, val, n, n_fbconfigs; - Status status; + GLContextState *cs; + GLXFBConfig *fbconfigs = NULL; + int fbconfig_id, val, n, n_fbconfigs; + Status status; - static GLint fbconfig_attrs[] = { - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_DOUBLEBUFFER, True, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - None - }; + static GLint fbconfig_attrs[] = { + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DOUBLEBUFFER, True, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + None + }; - cs = malloc(sizeof(*cs)); - if (!cs) - goto error; + cs = malloc (sizeof (*cs)); + if (!cs) + goto error; - if (parent) { - cs->display = parent->display; - cs->window = parent->window; - screen = DefaultScreen(parent->display); + if (parent) { + cs->display = parent->display; + cs->window = parent->window; + screen = DefaultScreen (parent->display); + } else { + cs->display = dpy; + cs->window = None; + } + cs->visual = NULL; + cs->context = NULL; + cs->swapped_buffers = FALSE; + + if (parent && parent->context) { + status = glXQueryContext (parent->display, + parent->context, GLX_FBCONFIG_ID, &fbconfig_id); + if (status != Success) + goto error; + + if (fbconfig_id == GLX_DONT_CARE) + goto choose_fbconfig; + + fbconfigs = glXGetFBConfigs (parent->display, screen, &n_fbconfigs); + if (!fbconfigs) + goto error; + + /* Find out a GLXFBConfig compatible with the parent context */ + for (n = 0; n < n_fbconfigs; n++) { + status = glXGetFBConfigAttrib (parent->display, + fbconfigs[n], GLX_FBCONFIG_ID, &val); + if (status == Success && val == fbconfig_id) + break; } - else { - cs->display = dpy; - cs->window = None; - } - cs->visual = NULL; - cs->context = NULL; - cs->swapped_buffers = FALSE; + if (n == n_fbconfigs) + goto error; + } else { + choose_fbconfig: + fbconfigs = glXChooseFBConfig (cs->display, + screen, fbconfig_attrs, &n_fbconfigs); + if (!fbconfigs) + goto error; - if (parent && parent->context) { - status = glXQueryContext( - parent->display, - parent->context, - GLX_FBCONFIG_ID, &fbconfig_id - ); - if (status != Success) - goto error; + /* Select the first one */ + n = 0; + } - if (fbconfig_id == GLX_DONT_CARE) - goto choose_fbconfig; - - fbconfigs = glXGetFBConfigs(parent->display, screen, &n_fbconfigs); - if (!fbconfigs) - goto error; - - /* Find out a GLXFBConfig compatible with the parent context */ - for (n = 0; n < n_fbconfigs; n++) { - status = glXGetFBConfigAttrib( - parent->display, - fbconfigs[n], - GLX_FBCONFIG_ID, &val - ); - if (status == Success && val == fbconfig_id) - break; - } - if (n == n_fbconfigs) - goto error; - } - else { - choose_fbconfig: - fbconfigs = glXChooseFBConfig( - cs->display, - screen, - fbconfig_attrs, &n_fbconfigs - ); - if (!fbconfigs) - goto error; - - /* Select the first one */ - n = 0; - } - - cs->visual = glXGetVisualFromFBConfig(cs->display, fbconfigs[n]); - cs->context = glXCreateNewContext( - cs->display, - fbconfigs[n], - GLX_RGBA_TYPE, - parent ? parent->context : NULL, - True - ); - if (cs->context) - goto end; + cs->visual = glXGetVisualFromFBConfig (cs->display, fbconfigs[n]); + cs->context = glXCreateNewContext (cs->display, + fbconfigs[n], GLX_RGBA_TYPE, parent ? parent->context : NULL, True); + if (cs->context) + goto end; error: - gl_destroy_context(cs); - cs = NULL; + gl_destroy_context (cs); + cs = NULL; end: - if (fbconfigs) - XFree(fbconfigs); - return cs; + if (fbconfigs) + XFree (fbconfigs); + return cs; } /** @@ -394,29 +376,29 @@ end: * Destroys the GLX context @cs */ void -gl_destroy_context(GLContextState *cs) +gl_destroy_context (GLContextState * cs) { - if (!cs) - return; + if (!cs) + return; - if (cs->visual) { - XFree(cs->visual); - cs->visual = NULL; - } + if (cs->visual) { + XFree (cs->visual); + cs->visual = NULL; + } - if (cs->display && cs->context) { - if (glXGetCurrentContext() == cs->context) { - /* XXX: if buffers were never swapped, the application - will crash later with the NVIDIA driver */ - if (!cs->swapped_buffers) - gl_swap_buffers(cs); - glXMakeCurrent(cs->display, None, NULL); - } - glXDestroyContext(cs->display, cs->context); - cs->display = NULL; - cs->context = NULL; + if (cs->display && cs->context) { + if (glXGetCurrentContext () == cs->context) { + /* XXX: if buffers were never swapped, the application + will crash later with the NVIDIA driver */ + if (!cs->swapped_buffers) + gl_swap_buffers (cs); + glXMakeCurrent (cs->display, None, NULL); } - free(cs); + glXDestroyContext (cs->display, cs->context); + cs->display = NULL; + cs->context = NULL; + } + free (cs); } /** @@ -427,11 +409,11 @@ gl_destroy_context(GLContextState *cs) * the #GLContextState struct. */ void -gl_get_current_context(GLContextState *cs) +gl_get_current_context (GLContextState * cs) { - cs->display = glXGetCurrentDisplay(); - cs->window = glXGetCurrentDrawable(); - cs->context = glXGetCurrentContext(); + cs->display = glXGetCurrentDisplay (); + cs->window = glXGetCurrentDrawable (); + cs->context = glXGetCurrentContext (); } /** @@ -449,24 +431,23 @@ gl_get_current_context(GLContextState *cs) * Return value: %TRUE on success */ gboolean -gl_set_current_context(GLContextState *new_cs, GLContextState *old_cs) +gl_set_current_context (GLContextState * new_cs, GLContextState * old_cs) { - /* If display is NULL, this could be that new_cs was retrieved from - gl_get_current_context() with none set previously. If that case, - the other fields are also NULL and we don't return an error */ - if (!new_cs->display) - return !new_cs->window && !new_cs->context; + /* If display is NULL, this could be that new_cs was retrieved from + gl_get_current_context() with none set previously. If that case, + the other fields are also NULL and we don't return an error */ + if (!new_cs->display) + return !new_cs->window && !new_cs->context; - if (old_cs) { - if (old_cs == new_cs) - return TRUE; - gl_get_current_context(old_cs); - if (old_cs->display == new_cs->display && - old_cs->window == new_cs->window && - old_cs->context == new_cs->context) - return TRUE; - } - return glXMakeCurrent(new_cs->display, new_cs->window, new_cs->context); + if (old_cs) { + if (old_cs == new_cs) + return TRUE; + gl_get_current_context (old_cs); + if (old_cs->display == new_cs->display && + old_cs->window == new_cs->window && old_cs->context == new_cs->context) + return TRUE; + } + return glXMakeCurrent (new_cs->display, new_cs->window, new_cs->context); } /** @@ -478,10 +459,10 @@ gl_set_current_context(GLContextState *new_cs, GLContextState *old_cs) * around glXSwapBuffers(). */ void -gl_swap_buffers(GLContextState *cs) +gl_swap_buffers (GLContextState * cs) { - glXSwapBuffers(cs->display, cs->window); - cs->swapped_buffers = TRUE; + glXSwapBuffers (cs->display, cs->window); + cs->swapped_buffers = TRUE; } /** @@ -496,35 +477,34 @@ gl_swap_buffers(GLContextState *cs) * Return value: %TRUE on success */ gboolean -gl_bind_texture(GLTextureState *ts, GLenum target, GLuint texture) +gl_bind_texture (GLTextureState * ts, GLenum target, GLuint texture) { - GLenum binding; + GLenum binding; - ts->target = target; + ts->target = target; - if (glIsEnabled(target)) { - binding = gl_get_texture_binding(target); - if (!binding) - return FALSE; - if (!gl_get_param(binding, &ts->old_texture)) - return FALSE; - ts->was_enabled = TRUE; - ts->was_bound = texture == ts->old_texture; - if (ts->was_bound) - return TRUE; - } - else { - glEnable(target); - ts->old_texture = 0; - ts->was_enabled = FALSE; - ts->was_bound = FALSE; - } + if (glIsEnabled (target)) { + binding = gl_get_texture_binding (target); + if (!binding) + return FALSE; + if (!gl_get_param (binding, &ts->old_texture)) + return FALSE; + ts->was_enabled = TRUE; + ts->was_bound = texture == ts->old_texture; + if (ts->was_bound) + return TRUE; + } else { + glEnable (target); + ts->old_texture = 0; + ts->was_enabled = FALSE; + ts->was_bound = FALSE; + } - gl_purge_errors(); - glBindTexture(target, texture); - if (gl_check_error()) - return FALSE; - return TRUE; + gl_purge_errors (); + glBindTexture (target, texture); + if (gl_check_error ()) + return FALSE; + return TRUE; } /** @@ -534,12 +514,12 @@ gl_bind_texture(GLTextureState *ts, GLenum target, GLuint texture) * Rebinds the texture that was previously bound and recorded in @ts. */ void -gl_unbind_texture(GLTextureState *ts) +gl_unbind_texture (GLTextureState * ts) { - if (!ts->was_bound && ts->old_texture) - glBindTexture(ts->target, ts->old_texture); - if (!ts->was_enabled) - glDisable(ts->target); + if (!ts->was_bound && ts->old_texture) + glBindTexture (ts->target, ts->old_texture); + if (!ts->was_enabled) + glDisable (ts->target); } /** @@ -555,52 +535,44 @@ gl_unbind_texture(GLTextureState *ts) * Return value: the newly created texture name */ GLuint -gl_create_texture(GLenum target, GLenum format, guint width, guint height) +gl_create_texture (GLenum target, GLenum format, guint width, guint height) { - GLenum internal_format; - GLuint texture; - GLTextureState ts; - guint bytes_per_component; + GLenum internal_format; + GLuint texture; + GLTextureState ts; + guint bytes_per_component; - internal_format = format; - switch (format) { + internal_format = format; + switch (format) { case GL_LUMINANCE: - bytes_per_component = 1; - break; + bytes_per_component = 1; + break; case GL_LUMINANCE_ALPHA: - bytes_per_component = 2; - break; + bytes_per_component = 2; + break; case GL_RGBA: case GL_BGRA: - internal_format = GL_RGBA; - bytes_per_component = 4; - break; + internal_format = GL_RGBA; + bytes_per_component = 4; + break; default: - bytes_per_component = 0; - break; - } - g_assert(bytes_per_component > 0); + bytes_per_component = 0; + break; + } + g_assert (bytes_per_component > 0); - glGenTextures(1, &texture); - if (!gl_bind_texture(&ts, target, texture)) - return 0; - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glPixelStorei(GL_UNPACK_ALIGNMENT, bytes_per_component); - glTexImage2D( - target, - 0, - internal_format, - width, height, - 0, - format, - GL_UNSIGNED_BYTE, - NULL - ); - gl_unbind_texture(&ts); - return texture; + glGenTextures (1, &texture); + if (!gl_bind_texture (&ts, target, texture)) + return 0; + glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glPixelStorei (GL_UNPACK_ALIGNMENT, bytes_per_component); + glTexImage2D (target, + 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL); + gl_unbind_texture (&ts); + return texture; } /** @@ -612,39 +584,39 @@ gl_create_texture(GLenum target, GLenum format, guint width, guint height) * Return value: the OpenGL extension matching @name, or %NULL if none * was found */ -typedef void (*GLFuncPtr)(void); -typedef GLFuncPtr (*GLXGetProcAddressProc)(const char *); +typedef void (*GLFuncPtr) (void); +typedef GLFuncPtr (*GLXGetProcAddressProc) (const gchar *); static GLFuncPtr -get_proc_address_default(const char *name) +get_proc_address_default (const gchar *name) { - return NULL; + return NULL; } static GLXGetProcAddressProc -get_proc_address_func(void) +get_proc_address_func (void) { - GLXGetProcAddressProc get_proc_func; + GLXGetProcAddressProc get_proc_func; - dlerror(); - *(void **)(&get_proc_func) = dlsym(RTLD_DEFAULT, "glXGetProcAddress"); - if (!dlerror()) - return get_proc_func; + dlerror (); + *(void **) (&get_proc_func) = dlsym (RTLD_DEFAULT, "glXGetProcAddress"); + if (!dlerror ()) + return get_proc_func; - *(void **)(&get_proc_func) = dlsym(RTLD_DEFAULT, "glXGetProcAddressARB"); - if (!dlerror()) - return get_proc_func; + *(void **) (&get_proc_func) = dlsym (RTLD_DEFAULT, "glXGetProcAddressARB"); + if (!dlerror ()) + return get_proc_func; - return get_proc_address_default; + return get_proc_address_default; } static inline GLFuncPtr -get_proc_address(const char *name) +get_proc_address (const gchar *name) { - static GLXGetProcAddressProc get_proc_func = NULL; - if (!get_proc_func) - get_proc_func = get_proc_address_func(); - return get_proc_func(name); + static GLXGetProcAddressProc get_proc_func = NULL; + if (!get_proc_func) + get_proc_func = get_proc_address_func (); + return get_proc_func (name); } /** @@ -658,79 +630,80 @@ get_proc_address(const char *name) static GLVTable gl_vtable_static; static GLVTable * -gl_init_vtable(void) +gl_init_vtable (void) { - GLVTable * const gl_vtable = &gl_vtable_static; - const gchar *gl_extensions = (const gchar *)glGetString(GL_EXTENSIONS); - gboolean has_extension; + GLVTable *const gl_vtable = &gl_vtable_static; + const gchar *gl_extensions = (const gchar *) glGetString (GL_EXTENSIONS); + gboolean has_extension; - /* GLX_EXT_texture_from_pixmap */ - gl_vtable->glx_create_pixmap = (PFNGLXCREATEPIXMAPPROC) - get_proc_address("glXCreatePixmap"); - if (!gl_vtable->glx_create_pixmap) - return NULL; - gl_vtable->glx_destroy_pixmap = (PFNGLXDESTROYPIXMAPPROC) - get_proc_address("glXDestroyPixmap"); - if (!gl_vtable->glx_destroy_pixmap) - return NULL; - gl_vtable->glx_bind_tex_image = (PFNGLXBINDTEXIMAGEEXTPROC) - get_proc_address("glXBindTexImageEXT"); - if (!gl_vtable->glx_bind_tex_image) - return NULL; - gl_vtable->glx_release_tex_image = (PFNGLXRELEASETEXIMAGEEXTPROC) - get_proc_address("glXReleaseTexImageEXT"); - if (!gl_vtable->glx_release_tex_image) - return NULL; + /* GLX_EXT_texture_from_pixmap */ + gl_vtable->glx_create_pixmap = (PFNGLXCREATEPIXMAPPROC) + get_proc_address ("glXCreatePixmap"); + if (!gl_vtable->glx_create_pixmap) + return NULL; + gl_vtable->glx_destroy_pixmap = (PFNGLXDESTROYPIXMAPPROC) + get_proc_address ("glXDestroyPixmap"); + if (!gl_vtable->glx_destroy_pixmap) + return NULL; + gl_vtable->glx_bind_tex_image = (PFNGLXBINDTEXIMAGEEXTPROC) + get_proc_address ("glXBindTexImageEXT"); + if (!gl_vtable->glx_bind_tex_image) + return NULL; + gl_vtable->glx_release_tex_image = (PFNGLXRELEASETEXIMAGEEXTPROC) + get_proc_address ("glXReleaseTexImageEXT"); + if (!gl_vtable->glx_release_tex_image) + return NULL; - /* GL_ARB_framebuffer_object */ - has_extension = ( - find_string("GL_ARB_framebuffer_object", gl_extensions, " ") || - find_string("GL_EXT_framebuffer_object", gl_extensions, " ") - ); - if (has_extension) { - gl_vtable->gl_gen_framebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC) - get_proc_address("glGenFramebuffersEXT"); - if (!gl_vtable->gl_gen_framebuffers) - return NULL; - gl_vtable->gl_delete_framebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC) - get_proc_address("glDeleteFramebuffersEXT"); - if (!gl_vtable->gl_delete_framebuffers) - return NULL; - gl_vtable->gl_bind_framebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC) - get_proc_address("glBindFramebufferEXT"); - if (!gl_vtable->gl_bind_framebuffer) - return NULL; - gl_vtable->gl_gen_renderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC) - get_proc_address("glGenRenderbuffersEXT"); - if (!gl_vtable->gl_gen_renderbuffers) - return NULL; - gl_vtable->gl_delete_renderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC) - get_proc_address("glDeleteRenderbuffersEXT"); - if (!gl_vtable->gl_delete_renderbuffers) - return NULL; - gl_vtable->gl_bind_renderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC) - get_proc_address("glBindRenderbufferEXT"); - if (!gl_vtable->gl_bind_renderbuffer) - return NULL; - gl_vtable->gl_renderbuffer_storage = (PFNGLRENDERBUFFERSTORAGEEXTPROC) - get_proc_address("glRenderbufferStorageEXT"); - if (!gl_vtable->gl_renderbuffer_storage) - return NULL; - gl_vtable->gl_framebuffer_renderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) - get_proc_address("glFramebufferRenderbufferEXT"); - if (!gl_vtable->gl_framebuffer_renderbuffer) - return NULL; - gl_vtable->gl_framebuffer_texture_2d = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) - get_proc_address("glFramebufferTexture2DEXT"); - if (!gl_vtable->gl_framebuffer_texture_2d) - return NULL; - gl_vtable->gl_check_framebuffer_status = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) - get_proc_address("glCheckFramebufferStatusEXT"); - if (!gl_vtable->gl_check_framebuffer_status) - return NULL; - gl_vtable->has_framebuffer_object = TRUE; - } - return gl_vtable; + /* GL_ARB_framebuffer_object */ + has_extension = (find_string ("GL_ARB_framebuffer_object", gl_extensions, " ") + || find_string ("GL_EXT_framebuffer_object", gl_extensions, " ") + ); + if (has_extension) { + gl_vtable->gl_gen_framebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC) + get_proc_address ("glGenFramebuffersEXT"); + if (!gl_vtable->gl_gen_framebuffers) + return NULL; + gl_vtable->gl_delete_framebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC) + get_proc_address ("glDeleteFramebuffersEXT"); + if (!gl_vtable->gl_delete_framebuffers) + return NULL; + gl_vtable->gl_bind_framebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC) + get_proc_address ("glBindFramebufferEXT"); + if (!gl_vtable->gl_bind_framebuffer) + return NULL; + gl_vtable->gl_gen_renderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC) + get_proc_address ("glGenRenderbuffersEXT"); + if (!gl_vtable->gl_gen_renderbuffers) + return NULL; + gl_vtable->gl_delete_renderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC) + get_proc_address ("glDeleteRenderbuffersEXT"); + if (!gl_vtable->gl_delete_renderbuffers) + return NULL; + gl_vtable->gl_bind_renderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC) + get_proc_address ("glBindRenderbufferEXT"); + if (!gl_vtable->gl_bind_renderbuffer) + return NULL; + gl_vtable->gl_renderbuffer_storage = (PFNGLRENDERBUFFERSTORAGEEXTPROC) + get_proc_address ("glRenderbufferStorageEXT"); + if (!gl_vtable->gl_renderbuffer_storage) + return NULL; + gl_vtable->gl_framebuffer_renderbuffer = + (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) + get_proc_address ("glFramebufferRenderbufferEXT"); + if (!gl_vtable->gl_framebuffer_renderbuffer) + return NULL; + gl_vtable->gl_framebuffer_texture_2d = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) + get_proc_address ("glFramebufferTexture2DEXT"); + if (!gl_vtable->gl_framebuffer_texture_2d) + return NULL; + gl_vtable->gl_check_framebuffer_status = + (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) + get_proc_address ("glCheckFramebufferStatusEXT"); + if (!gl_vtable->gl_check_framebuffer_status) + return NULL; + gl_vtable->has_framebuffer_object = TRUE; + } + return gl_vtable; } /** @@ -741,16 +714,16 @@ gl_init_vtable(void) * Return value: VTable for OpenGL extensions */ GLVTable * -gl_get_vtable(void) +gl_get_vtable (void) { - static gsize gl_vtable_init = FALSE; - static GLVTable *gl_vtable = NULL; + static gsize gl_vtable_init = FALSE; + static GLVTable *gl_vtable = NULL; - if (g_once_init_enter(&gl_vtable_init)) { - gl_vtable = gl_init_vtable(); - g_once_init_leave(&gl_vtable_init, TRUE); - } - return gl_vtable; + if (g_once_init_enter (&gl_vtable_init)) { + gl_vtable = gl_init_vtable (); + g_once_init_leave (&gl_vtable_init, TRUE); + } + return gl_vtable; } /** @@ -765,121 +738,114 @@ gl_get_vtable(void) * Return value: the newly created #GLPixmapObject object */ GLPixmapObject * -gl_create_pixmap_object(Display *dpy, guint width, guint height) +gl_create_pixmap_object (Display * dpy, guint width, guint height) { - GLVTable * const gl_vtable = gl_get_vtable(); - GLPixmapObject *pixo; - GLXFBConfig *fbconfig; - int screen; - Window rootwin; - XWindowAttributes wattr; - int *attr; - int n_fbconfig_attrs; + GLVTable *const gl_vtable = gl_get_vtable (); + GLPixmapObject *pixo; + GLXFBConfig *fbconfig; + int screen; + Window rootwin; + XWindowAttributes wattr; + int *attr; + int n_fbconfig_attrs; - int fbconfig_attrs[32] = { - GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, - GLX_DOUBLEBUFFER, GL_FALSE, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_X_RENDERABLE, GL_TRUE, - GLX_Y_INVERTED_EXT, GL_TRUE, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GL_NONE, - }; + int fbconfig_attrs[32] = { + GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, + GLX_DOUBLEBUFFER, GL_FALSE, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_X_RENDERABLE, GL_TRUE, + GLX_Y_INVERTED_EXT, GL_TRUE, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GL_NONE, + }; - int pixmap_attrs[10] = { - GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, - GLX_MIPMAP_TEXTURE_EXT, GL_FALSE, - GL_NONE, - }; + int pixmap_attrs[10] = { + GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, + GLX_MIPMAP_TEXTURE_EXT, GL_FALSE, + GL_NONE, + }; - if (!gl_vtable) - return NULL; + if (!gl_vtable) + return NULL; - screen = DefaultScreen(dpy); - rootwin = RootWindow(dpy, screen); + screen = DefaultScreen (dpy); + rootwin = RootWindow (dpy, screen); - /* XXX: this won't work for different displays */ - if (!gl_vtable->has_texture_from_pixmap) { - const char *glx_extensions = glXQueryExtensionsString(dpy, screen); - if (!glx_extensions) - return NULL; - if (!find_string("GLX_EXT_texture_from_pixmap", glx_extensions, " ")) - return NULL; - gl_vtable->has_texture_from_pixmap = TRUE; - } + /* XXX: this won't work for different displays */ + if (!gl_vtable->has_texture_from_pixmap) { + const gchar *glx_extensions = glXQueryExtensionsString (dpy, screen); + if (!glx_extensions) + return NULL; + if (!find_string ("GLX_EXT_texture_from_pixmap", glx_extensions, " ")) + return NULL; + gl_vtable->has_texture_from_pixmap = TRUE; + } - pixo = calloc(1, sizeof(*pixo)); - if (!pixo) - return NULL; + pixo = calloc (1, sizeof (*pixo)); + if (!pixo) + return NULL; - pixo->dpy = dpy; - pixo->width = width; - pixo->height = height; - pixo->pixmap = None; - pixo->glx_pixmap = None; - pixo->is_bound = FALSE; + pixo->dpy = dpy; + pixo->width = width; + pixo->height = height; + pixo->pixmap = None; + pixo->glx_pixmap = None; + pixo->is_bound = FALSE; - XGetWindowAttributes(dpy, rootwin, &wattr); - pixo->pixmap = XCreatePixmap(dpy, rootwin, width, height, wattr.depth); - if (!pixo->pixmap) - goto error; + XGetWindowAttributes (dpy, rootwin, &wattr); + pixo->pixmap = XCreatePixmap (dpy, rootwin, width, height, wattr.depth); + if (!pixo->pixmap) + goto error; - /* Initialize FBConfig attributes */ - for (attr = fbconfig_attrs; *attr != GL_NONE; attr += 2) - ; - *attr++ = GLX_DEPTH_SIZE; *attr++ = wattr.depth; - if (wattr.depth == 32) { - *attr++ = GLX_ALPHA_SIZE; *attr++ = 8; - *attr++ = GLX_BIND_TO_TEXTURE_RGBA_EXT; *attr++ = GL_TRUE; - } - else { - *attr++ = GLX_BIND_TO_TEXTURE_RGB_EXT; *attr++ = GL_TRUE; - } - *attr++ = GL_NONE; + /* Initialize FBConfig attributes */ + for (attr = fbconfig_attrs; *attr != GL_NONE; attr += 2); + *attr++ = GLX_DEPTH_SIZE; + *attr++ = wattr.depth; + if (wattr.depth == 32) { + *attr++ = GLX_ALPHA_SIZE; + *attr++ = 8; + *attr++ = GLX_BIND_TO_TEXTURE_RGBA_EXT; + *attr++ = GL_TRUE; + } else { + *attr++ = GLX_BIND_TO_TEXTURE_RGB_EXT; + *attr++ = GL_TRUE; + } + *attr++ = GL_NONE; - fbconfig = glXChooseFBConfig( - dpy, - screen, - fbconfig_attrs, &n_fbconfig_attrs - ); - if (!fbconfig) - goto error; + fbconfig = glXChooseFBConfig (dpy, screen, fbconfig_attrs, &n_fbconfig_attrs); + if (!fbconfig) + goto error; - /* Initialize GLX Pixmap attributes */ - for (attr = pixmap_attrs; *attr != GL_NONE; attr += 2) - ; - *attr++ = GLX_TEXTURE_FORMAT_EXT; - if (wattr.depth == 32) + /* Initialize GLX Pixmap attributes */ + for (attr = pixmap_attrs; *attr != GL_NONE; attr += 2); + *attr++ = GLX_TEXTURE_FORMAT_EXT; + if (wattr.depth == 32) *attr++ = GLX_TEXTURE_FORMAT_RGBA_EXT; - else + else *attr++ = GLX_TEXTURE_FORMAT_RGB_EXT; - *attr++ = GL_NONE; + *attr++ = GL_NONE; - x11_trap_errors(); - pixo->glx_pixmap = gl_vtable->glx_create_pixmap( - dpy, - fbconfig[0], - pixo->pixmap, - pixmap_attrs - ); - free(fbconfig); - if (x11_untrap_errors() != 0) - goto error; + x11_trap_errors (); + pixo->glx_pixmap = gl_vtable->glx_create_pixmap (dpy, + fbconfig[0], pixo->pixmap, pixmap_attrs); + free (fbconfig); + if (x11_untrap_errors () != 0) + goto error; - pixo->target = GL_TEXTURE_2D; - glGenTextures(1, &pixo->texture); - if (!gl_bind_texture(&pixo->old_texture, pixo->target, pixo->texture)) - goto error; - glTexParameteri(pixo->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(pixo->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gl_unbind_texture(&pixo->old_texture); - return pixo; + pixo->target = GL_TEXTURE_2D; + glGenTextures (1, &pixo->texture); + if (!gl_bind_texture (&pixo->old_texture, pixo->target, pixo->texture)) + goto error; + glTexParameteri (pixo->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (pixo->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl_unbind_texture (&pixo->old_texture); + return pixo; error: - gl_destroy_pixmap_object(pixo); - return NULL; + gl_destroy_pixmap_object (pixo); + return NULL; } /** @@ -889,30 +855,30 @@ error: * Destroys the #GLPixmapObject object. */ void -gl_destroy_pixmap_object(GLPixmapObject *pixo) +gl_destroy_pixmap_object (GLPixmapObject * pixo) { - GLVTable * const gl_vtable = gl_get_vtable(); + GLVTable *const gl_vtable = gl_get_vtable (); - if (!pixo) - return; + if (!pixo) + return; - gl_unbind_pixmap_object(pixo); + gl_unbind_pixmap_object (pixo); - if (pixo->texture) { - glDeleteTextures(1, &pixo->texture); - pixo->texture = 0; - } + if (pixo->texture) { + glDeleteTextures (1, &pixo->texture); + pixo->texture = 0; + } - if (pixo->glx_pixmap) { - gl_vtable->glx_destroy_pixmap(pixo->dpy, pixo->glx_pixmap); - pixo->glx_pixmap = None; - } + if (pixo->glx_pixmap) { + gl_vtable->glx_destroy_pixmap (pixo->dpy, pixo->glx_pixmap); + pixo->glx_pixmap = None; + } - if (pixo->pixmap) { - XFreePixmap(pixo->dpy, pixo->pixmap); - pixo->pixmap = None; - } - free(pixo); + if (pixo->pixmap) { + XFreePixmap (pixo->dpy, pixo->pixmap); + pixo->pixmap = None; + } + free (pixo); } /** @@ -926,31 +892,27 @@ gl_destroy_pixmap_object(GLPixmapObject *pixo) * Return value: %TRUE on success */ gboolean -gl_bind_pixmap_object(GLPixmapObject *pixo) +gl_bind_pixmap_object (GLPixmapObject * pixo) { - GLVTable * const gl_vtable = gl_get_vtable(); + GLVTable *const gl_vtable = gl_get_vtable (); - if (pixo->is_bound) - return TRUE; - - if (!gl_bind_texture(&pixo->old_texture, pixo->target, pixo->texture)) - return FALSE; - - x11_trap_errors(); - gl_vtable->glx_bind_tex_image( - pixo->dpy, - pixo->glx_pixmap, - GLX_FRONT_LEFT_EXT, - NULL - ); - XSync(pixo->dpy, False); - if (x11_untrap_errors() != 0) { - GST_DEBUG("failed to bind pixmap"); - return FALSE; - } - - pixo->is_bound = TRUE; + if (pixo->is_bound) return TRUE; + + if (!gl_bind_texture (&pixo->old_texture, pixo->target, pixo->texture)) + return FALSE; + + x11_trap_errors (); + gl_vtable->glx_bind_tex_image (pixo->dpy, + pixo->glx_pixmap, GLX_FRONT_LEFT_EXT, NULL); + XSync (pixo->dpy, False); + if (x11_untrap_errors () != 0) { + GST_DEBUG ("failed to bind pixmap"); + return FALSE; + } + + pixo->is_bound = TRUE; + return TRUE; } /** @@ -962,29 +924,26 @@ gl_bind_pixmap_object(GLPixmapObject *pixo) * Return value: %TRUE on success */ gboolean -gl_unbind_pixmap_object(GLPixmapObject *pixo) +gl_unbind_pixmap_object (GLPixmapObject * pixo) { - GLVTable * const gl_vtable = gl_get_vtable(); + GLVTable *const gl_vtable = gl_get_vtable (); - if (!pixo->is_bound) - return TRUE; - - x11_trap_errors(); - gl_vtable->glx_release_tex_image( - pixo->dpy, - pixo->glx_pixmap, - GLX_FRONT_LEFT_EXT - ); - XSync(pixo->dpy, False); - if (x11_untrap_errors() != 0) { - GST_DEBUG("failed to release pixmap"); - return FALSE; - } - - gl_unbind_texture(&pixo->old_texture); - - pixo->is_bound = FALSE; + if (!pixo->is_bound) return TRUE; + + x11_trap_errors (); + gl_vtable->glx_release_tex_image (pixo->dpy, + pixo->glx_pixmap, GLX_FRONT_LEFT_EXT); + XSync (pixo->dpy, False); + if (x11_untrap_errors () != 0) { + GST_DEBUG ("failed to release pixmap"); + return FALSE; + } + + gl_unbind_texture (&pixo->old_texture); + + pixo->is_bound = FALSE; + return TRUE; } /** @@ -1000,53 +959,45 @@ gl_unbind_pixmap_object(GLPixmapObject *pixo) * an error occurred */ GLFramebufferObject * -gl_create_framebuffer_object( - GLenum target, - GLuint texture, - guint width, - guint height -) +gl_create_framebuffer_object (GLenum target, + GLuint texture, guint width, guint height) { - GLVTable * const gl_vtable = gl_get_vtable(); - GLFramebufferObject *fbo; - GLenum status; + GLVTable *const gl_vtable = gl_get_vtable (); + GLFramebufferObject *fbo; + GLenum status; - if (!gl_vtable || !gl_vtable->has_framebuffer_object) - return NULL; + if (!gl_vtable || !gl_vtable->has_framebuffer_object) + return NULL; - /* XXX: we only support GL_TEXTURE_2D at this time */ - if (target != GL_TEXTURE_2D) - return NULL; + /* XXX: we only support GL_TEXTURE_2D at this time */ + if (target != GL_TEXTURE_2D) + return NULL; - fbo = calloc(1, sizeof(*fbo)); - if (!fbo) - return NULL; + fbo = calloc (1, sizeof (*fbo)); + if (!fbo) + return NULL; - fbo->width = width; - fbo->height = height; - fbo->fbo = 0; - fbo->old_fbo = 0; - fbo->is_bound = FALSE; + fbo->width = width; + fbo->height = height; + fbo->fbo = 0; + fbo->old_fbo = 0; + fbo->is_bound = FALSE; - gl_get_param(GL_FRAMEBUFFER_BINDING, &fbo->old_fbo); - gl_vtable->gl_gen_framebuffers(1, &fbo->fbo); - gl_vtable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo->fbo); - gl_vtable->gl_framebuffer_texture_2d( - GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, texture, - 0 - ); + gl_get_param (GL_FRAMEBUFFER_BINDING, &fbo->old_fbo); + gl_vtable->gl_gen_framebuffers (1, &fbo->fbo); + gl_vtable->gl_bind_framebuffer (GL_FRAMEBUFFER_EXT, fbo->fbo); + gl_vtable->gl_framebuffer_texture_2d (GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, target, texture, 0); - status = gl_vtable->gl_check_framebuffer_status(GL_DRAW_FRAMEBUFFER_EXT); - gl_vtable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo->old_fbo); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) - goto error; - return fbo; + status = gl_vtable->gl_check_framebuffer_status (GL_DRAW_FRAMEBUFFER_EXT); + gl_vtable->gl_bind_framebuffer (GL_FRAMEBUFFER_EXT, fbo->old_fbo); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + goto error; + return fbo; error: - gl_destroy_framebuffer_object(fbo); - return NULL; + gl_destroy_framebuffer_object (fbo); + return NULL; } /** @@ -1056,20 +1007,20 @@ error: * Destroys the @fbo object. */ void -gl_destroy_framebuffer_object(GLFramebufferObject *fbo) +gl_destroy_framebuffer_object (GLFramebufferObject * fbo) { - GLVTable * const gl_vtable = gl_get_vtable(); + GLVTable *const gl_vtable = gl_get_vtable (); - if (!fbo) - return; + if (!fbo) + return; - gl_unbind_framebuffer_object(fbo); + gl_unbind_framebuffer_object (fbo); - if (fbo->fbo) { - gl_vtable->gl_delete_framebuffers(1, &fbo->fbo); - fbo->fbo = 0; - } - free(fbo); + if (fbo->fbo) { + gl_vtable->gl_delete_framebuffers (1, &fbo->fbo); + fbo->fbo = 0; + } + free (fbo); } /** @@ -1081,36 +1032,33 @@ gl_destroy_framebuffer_object(GLFramebufferObject *fbo) * Return value: %TRUE on success */ gboolean -gl_bind_framebuffer_object(GLFramebufferObject *fbo) +gl_bind_framebuffer_object (GLFramebufferObject * fbo) { - GLVTable * const gl_vtable = gl_get_vtable(); - const guint width = fbo->width; - const guint height = fbo->height; + GLVTable *const gl_vtable = gl_get_vtable (); + const guint width = fbo->width; + const guint height = fbo->height; - const guint attribs = (GL_VIEWPORT_BIT| - GL_CURRENT_BIT| - GL_ENABLE_BIT| - GL_TEXTURE_BIT| - GL_COLOR_BUFFER_BIT); + const guint attribs = (GL_VIEWPORT_BIT | + GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT); - if (fbo->is_bound) - return TRUE; - - gl_get_param(GL_FRAMEBUFFER_BINDING, &fbo->old_fbo); - gl_vtable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo->fbo); - glPushAttrib(attribs); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glViewport(0, 0, width, height); - glTranslatef(-1.0f, -1.0f, 0.0f); - glScalef(2.0f / width, 2.0f / height, 1.0f); - - fbo->is_bound = TRUE; + if (fbo->is_bound) return TRUE; + + gl_get_param (GL_FRAMEBUFFER_BINDING, &fbo->old_fbo); + gl_vtable->gl_bind_framebuffer (GL_FRAMEBUFFER_EXT, fbo->fbo); + glPushAttrib (attribs); + glMatrixMode (GL_PROJECTION); + glPushMatrix (); + glLoadIdentity (); + glMatrixMode (GL_MODELVIEW); + glPushMatrix (); + glLoadIdentity (); + glViewport (0, 0, width, height); + glTranslatef (-1.0f, -1.0f, 0.0f); + glScalef (2.0f / width, 2.0f / height, 1.0f); + + fbo->is_bound = TRUE; + return TRUE; } /** @@ -1122,20 +1070,20 @@ gl_bind_framebuffer_object(GLFramebufferObject *fbo) * Return value: %TRUE on success */ gboolean -gl_unbind_framebuffer_object(GLFramebufferObject *fbo) +gl_unbind_framebuffer_object (GLFramebufferObject * fbo) { - GLVTable * const gl_vtable = gl_get_vtable(); + GLVTable *const gl_vtable = gl_get_vtable (); - if (!fbo->is_bound) - return TRUE; - - glPopAttrib(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - gl_vtable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo->old_fbo); - - fbo->is_bound = FALSE; + if (!fbo->is_bound) return TRUE; + + glPopAttrib (); + glMatrixMode (GL_PROJECTION); + glPopMatrix (); + glMatrixMode (GL_MODELVIEW); + glPopMatrix (); + gl_vtable->gl_bind_framebuffer (GL_FRAMEBUFFER_EXT, fbo->old_fbo); + + fbo->is_bound = FALSE; + return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 3df92ae8e4..c89c85f409 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -34,15 +34,17 @@ #include #if GLX_GLXEXT_VERSION < 18 -typedef void (*PFNGLXBINDTEXIMAGEEXTPROC)(Display *, GLXDrawable, int, const int *); -typedef void (*PFNGLXRELEASETEXIMAGEEXTPROC)(Display *, GLXDrawable, int); +typedef void (*PFNGLXBINDTEXIMAGEEXTPROC) (Display *, GLXDrawable, int, + const int *); +typedef void (*PFNGLXRELEASETEXIMAGEEXTPROC) (Display *, GLXDrawable, int); #endif #if GLX_GLXEXT_VERSION < 27 /* XXX: this is not exactly that version but this is the only means to make sure we have the correct with those signatures */ -typedef GLXPixmap (*PFNGLXCREATEPIXMAPPROC)(Display *, GLXFBConfig, Pixmap, const int *); -typedef void (*PFNGLXDESTROYPIXMAPPROC)(Display *, GLXPixmap); +typedef GLXPixmap (*PFNGLXCREATEPIXMAPPROC) (Display *, GLXFBConfig, Pixmap, + const int *); +typedef void (*PFNGLXDESTROYPIXMAPPROC) (Display *, GLXPixmap); #endif #ifndef GL_FRAMEBUFFER_BINDING @@ -50,163 +52,164 @@ typedef void (*PFNGLXDESTROYPIXMAPPROC)(Display *, GLXPixmap); #endif G_GNUC_INTERNAL -const char * -gl_get_error_string(GLenum error); +const gchar * +gl_get_error_string (GLenum error); G_GNUC_INTERNAL void -gl_purge_errors(void); +gl_purge_errors (void); G_GNUC_INTERNAL gboolean -gl_check_error(void); +gl_check_error (void); G_GNUC_INTERNAL gboolean -gl_get_param(GLenum param, guint *pval); +gl_get_param (GLenum param, guint * pval); G_GNUC_INTERNAL gboolean -gl_get_texture_param(GLenum target, GLenum param, guint *pval); +gl_get_texture_param (GLenum target, GLenum param, guint * pval); G_GNUC_INTERNAL void -gl_set_bgcolor(guint32 color); +gl_set_bgcolor (guint32 color); G_GNUC_INTERNAL void -gl_resize(guint width, guint height); +gl_resize (guint width, guint height); typedef struct _GLContextState GLContextState; -struct _GLContextState { - Display *display; - Window window; - XVisualInfo *visual; - GLXContext context; - guint swapped_buffers : 1; +struct _GLContextState +{ + Display *display; + Window window; + XVisualInfo *visual; + GLXContext context; + guint swapped_buffers:1; }; G_GNUC_INTERNAL GLContextState * -gl_create_context(Display *dpy, int screen, GLContextState *parent); +gl_create_context (Display * dpy, int screen, GLContextState * parent); G_GNUC_INTERNAL void -gl_destroy_context(GLContextState *cs); +gl_destroy_context (GLContextState * cs); G_GNUC_INTERNAL void -gl_get_current_context(GLContextState *cs); +gl_get_current_context (GLContextState * cs); G_GNUC_INTERNAL gboolean -gl_set_current_context(GLContextState *new_cs, GLContextState *old_cs); +gl_set_current_context (GLContextState * new_cs, GLContextState * old_cs); G_GNUC_INTERNAL void -gl_swap_buffers(GLContextState *cs); +gl_swap_buffers (GLContextState * cs); typedef struct _GLTextureState GLTextureState; -struct _GLTextureState { - GLenum target; - GLuint old_texture; - guint was_enabled : 1; - guint was_bound : 1; +struct _GLTextureState +{ + GLenum target; + GLuint old_texture; + guint was_enabled:1; + guint was_bound:1; }; G_GNUC_INTERNAL gboolean -gl_bind_texture(GLTextureState *ts, GLenum target, GLuint texture); +gl_bind_texture (GLTextureState * ts, GLenum target, GLuint texture); G_GNUC_INTERNAL void -gl_unbind_texture(GLTextureState *ts); +gl_unbind_texture (GLTextureState * ts); G_GNUC_INTERNAL GLuint -gl_create_texture(GLenum target, GLenum format, guint width, guint height); +gl_create_texture (GLenum target, GLenum format, guint width, guint height); typedef struct _GLVTable GLVTable; -struct _GLVTable { - PFNGLXCREATEPIXMAPPROC glx_create_pixmap; - PFNGLXDESTROYPIXMAPPROC glx_destroy_pixmap; - PFNGLXBINDTEXIMAGEEXTPROC glx_bind_tex_image; - PFNGLXRELEASETEXIMAGEEXTPROC glx_release_tex_image; - PFNGLGENFRAMEBUFFERSEXTPROC gl_gen_framebuffers; - PFNGLDELETEFRAMEBUFFERSEXTPROC gl_delete_framebuffers; - PFNGLBINDFRAMEBUFFEREXTPROC gl_bind_framebuffer; - PFNGLGENRENDERBUFFERSEXTPROC gl_gen_renderbuffers; - PFNGLDELETERENDERBUFFERSEXTPROC gl_delete_renderbuffers; - PFNGLBINDRENDERBUFFEREXTPROC gl_bind_renderbuffer; - PFNGLRENDERBUFFERSTORAGEEXTPROC gl_renderbuffer_storage; - PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC gl_framebuffer_renderbuffer; - PFNGLFRAMEBUFFERTEXTURE2DEXTPROC gl_framebuffer_texture_2d; - PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC gl_check_framebuffer_status; - guint has_texture_from_pixmap : 1; - guint has_framebuffer_object : 1; +struct _GLVTable +{ + PFNGLXCREATEPIXMAPPROC glx_create_pixmap; + PFNGLXDESTROYPIXMAPPROC glx_destroy_pixmap; + PFNGLXBINDTEXIMAGEEXTPROC glx_bind_tex_image; + PFNGLXRELEASETEXIMAGEEXTPROC glx_release_tex_image; + PFNGLGENFRAMEBUFFERSEXTPROC gl_gen_framebuffers; + PFNGLDELETEFRAMEBUFFERSEXTPROC gl_delete_framebuffers; + PFNGLBINDFRAMEBUFFEREXTPROC gl_bind_framebuffer; + PFNGLGENRENDERBUFFERSEXTPROC gl_gen_renderbuffers; + PFNGLDELETERENDERBUFFERSEXTPROC gl_delete_renderbuffers; + PFNGLBINDRENDERBUFFEREXTPROC gl_bind_renderbuffer; + PFNGLRENDERBUFFERSTORAGEEXTPROC gl_renderbuffer_storage; + PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC gl_framebuffer_renderbuffer; + PFNGLFRAMEBUFFERTEXTURE2DEXTPROC gl_framebuffer_texture_2d; + PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC gl_check_framebuffer_status; + guint has_texture_from_pixmap:1; + guint has_framebuffer_object:1; }; G_GNUC_INTERNAL GLVTable * -gl_get_vtable(void); +gl_get_vtable (void); typedef struct _GLPixmapObject GLPixmapObject; -struct _GLPixmapObject { - Display *dpy; - GLenum target; - GLuint texture; - GLTextureState old_texture; - guint width; - guint height; - Pixmap pixmap; - GLXPixmap glx_pixmap; - guint is_bound : 1; +struct _GLPixmapObject +{ + Display *dpy; + GLenum target; + GLuint texture; + GLTextureState old_texture; + guint width; + guint height; + Pixmap pixmap; + GLXPixmap glx_pixmap; + guint is_bound:1; }; G_GNUC_INTERNAL GLPixmapObject * -gl_create_pixmap_object(Display *dpy, guint width, guint height); +gl_create_pixmap_object (Display * dpy, guint width, guint height); G_GNUC_INTERNAL void -gl_destroy_pixmap_object(GLPixmapObject *pixo); +gl_destroy_pixmap_object (GLPixmapObject * pixo); G_GNUC_INTERNAL gboolean -gl_bind_pixmap_object(GLPixmapObject *pixo); +gl_bind_pixmap_object (GLPixmapObject * pixo); G_GNUC_INTERNAL gboolean -gl_unbind_pixmap_object(GLPixmapObject *pixo); +gl_unbind_pixmap_object (GLPixmapObject * pixo); typedef struct _GLFramebufferObject GLFramebufferObject; -struct _GLFramebufferObject { - guint width; - guint height; - GLuint fbo; - GLuint old_fbo; - guint is_bound : 1; +struct _GLFramebufferObject +{ + guint width; + guint height; + GLuint fbo; + GLuint old_fbo; + guint is_bound:1; }; G_GNUC_INTERNAL GLFramebufferObject * -gl_create_framebuffer_object( - GLenum target, - GLuint texture, - guint width, - guint height -); +gl_create_framebuffer_object (GLenum target, + GLuint texture, guint width, guint height); G_GNUC_INTERNAL void -gl_destroy_framebuffer_object(GLFramebufferObject *fbo); +gl_destroy_framebuffer_object (GLFramebufferObject * fbo); G_GNUC_INTERNAL gboolean -gl_bind_framebuffer_object(GLFramebufferObject *fbo); +gl_bind_framebuffer_object (GLFramebufferObject * fbo); G_GNUC_INTERNAL gboolean -gl_unbind_framebuffer_object(GLFramebufferObject *fbo); +gl_unbind_framebuffer_object (GLFramebufferObject * fbo); #endif /* GST_VAAPI_UTILS_GLX_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index 118895d910..48a3d12072 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -276,7 +276,7 @@ guint8 gst_vaapi_utils_h264_get_level_idc (GstVaapiLevelH264 level) { const GstVaapiH264LevelLimits *const llp = - gst_vaapi_utils_h264_get_level_limits (level); + gst_vaapi_utils_h264_get_level_limits (level); return llp ? llp->level_idc : 0; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.h b/gst-libs/gst/vaapi/gstvaapiutils_h264.h index 785f169dc6..16db4ea7fe 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.h @@ -50,8 +50,7 @@ G_BEGIN_DECLS * * The set of all levels for #GstVaapiLevelH264. */ -typedef enum -{ +typedef enum { GST_VAAPI_LEVEL_H264_L1 = 1, GST_VAAPI_LEVEL_H264_L1b, GST_VAAPI_LEVEL_H264_L1_1, diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h index 85eb184c9e..0ca552a807 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h @@ -40,8 +40,7 @@ G_BEGIN_DECLS * * The data structure that describes the limits of an H.264 level. */ -typedef struct -{ +typedef struct { GstVaapiLevelH264 level; guint8 level_idc; guint32 MaxMBPS; @@ -79,7 +78,7 @@ gst_vaapi_utils_h264_get_level_limits (GstVaapiLevelH264 level); /* Returns the Table A-1 specification */ G_GNUC_INTERNAL const GstVaapiH264LevelLimits * -gst_vaapi_utils_h264_get_level_limits_table (guint *out_length_ptr); +gst_vaapi_utils_h264_get_level_limits_table (guint * out_length_ptr); /* Returns GstVaapiChromaType from H.264 chroma_format_idc value */ G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h index 76c3bd8c7f..4820a4703e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h @@ -38,8 +38,7 @@ G_BEGIN_DECLS * * The set of all levels for #GstVaapiLevelMPEG2. */ -typedef enum -{ +typedef enum { GST_VAAPI_LEVEL_MPEG2_LOW = 1, GST_VAAPI_LEVEL_MPEG2_MAIN, GST_VAAPI_LEVEL_MPEG2_HIGH_1440, diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h index 3f96eca6ac..e6507faa4b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h @@ -41,8 +41,7 @@ G_BEGIN_DECLS * * The data structure that describes the limits of an MPEG-2 level. */ -typedef struct -{ +typedef struct { GstVaapiLevelMPEG2 level; guint8 level_idc; guint16 horizontal_size_value; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index f984fafd13..0b22aaef43 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -29,35 +29,39 @@ // X error trap static int x11_error_code = 0; -static int (*old_error_handler)(Display *, XErrorEvent *); +static int (*old_error_handler) (Display *, XErrorEvent *); -static int error_handler(Display *dpy, XErrorEvent *error) +static int +error_handler (Display * dpy, XErrorEvent * error) { - x11_error_code = error->error_code; - return 0; + x11_error_code = error->error_code; + return 0; } -void x11_trap_errors(void) +void +x11_trap_errors (void) { - x11_error_code = 0; - old_error_handler = XSetErrorHandler(error_handler); + x11_error_code = 0; + old_error_handler = XSetErrorHandler (error_handler); } -int x11_untrap_errors(void) +int +x11_untrap_errors (void) { - XSetErrorHandler(old_error_handler); - return x11_error_code; + XSetErrorHandler (old_error_handler); + return x11_error_code; } // X window management -static const int x11_event_mask = (KeyPressMask | - KeyReleaseMask | - ButtonPressMask | - ButtonReleaseMask | - PointerMotionMask | - EnterWindowMask | - ExposureMask | - StructureNotifyMask); +static const int x11_event_mask = + (KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask | + EnterWindowMask | + ExposureMask | + StructureNotifyMask); /** * x11_create_window: @@ -75,84 +79,68 @@ static const int x11_event_mask = (KeyPressMask | * Return value: the newly created X #Window. */ Window -x11_create_window(Display *dpy, guint w, guint h, Visual *vis, Colormap cmap) +x11_create_window (Display * dpy, guint w, guint h, Visual * vis, Colormap cmap) { - Window rootwin, win; - int screen, depth; - XSetWindowAttributes xswa; - unsigned long xswa_mask; - XWindowAttributes wattr; - unsigned long black_pixel; + Window rootwin, win; + int screen, depth; + XSetWindowAttributes xswa; + unsigned long xswa_mask; + XWindowAttributes wattr; + unsigned long black_pixel; - screen = DefaultScreen(dpy); - rootwin = RootWindow(dpy, screen); - black_pixel = BlackPixel(dpy, screen); + screen = DefaultScreen (dpy); + rootwin = RootWindow (dpy, screen); + black_pixel = BlackPixel (dpy, screen); - if (!vis) - vis = DefaultVisual(dpy, screen); + if (!vis) + vis = DefaultVisual (dpy, screen); - XGetWindowAttributes(dpy, rootwin, &wattr); - depth = wattr.depth; - if (depth != 15 && depth != 16 && depth != 24 && depth != 32) - depth = 24; + XGetWindowAttributes (dpy, rootwin, &wattr); + depth = wattr.depth; + if (depth != 15 && depth != 16 && depth != 24 && depth != 32) + depth = 24; - xswa_mask = CWBorderPixel | CWBackPixel; - xswa.border_pixel = black_pixel; - xswa.background_pixel = black_pixel; + xswa_mask = CWBorderPixel | CWBackPixel; + xswa.border_pixel = black_pixel; + xswa.background_pixel = black_pixel; - if (cmap) { - xswa_mask |= CWColormap; - xswa.colormap = cmap; - } + if (cmap) { + xswa_mask |= CWColormap; + xswa.colormap = cmap; + } - win = XCreateWindow( - dpy, - rootwin, - 0, 0, w, h, - 0, - depth, - InputOutput, - vis, - xswa_mask, &xswa - ); - if (!win) - return None; + win = XCreateWindow (dpy, rootwin, 0, 0, w, h, 0, depth, InputOutput, vis, + xswa_mask, &xswa); + if (!win) + return None; - XSelectInput(dpy, win, x11_event_mask); - return win; + XSelectInput (dpy, win, x11_event_mask); + return win; } gboolean -x11_get_geometry( - Display *dpy, - Drawable drawable, - gint *px, - gint *py, - guint *pwidth, - guint *pheight, - guint *pdepth -) +x11_get_geometry (Display * dpy, Drawable drawable, gint * px, gint * py, + guint * pwidth, guint * pheight, guint * pdepth) { - Window rootwin; - int x, y; - guint width, height, border_width, depth; + Window rootwin; + int x, y; + guint width, height, border_width, depth; - x11_trap_errors(); - XGetGeometry( - dpy, - drawable, - &rootwin, - &x, &y, &width, &height, - &border_width, - &depth - ); - if (x11_untrap_errors()) - return FALSE; + x11_trap_errors (); + XGetGeometry (dpy, drawable, &rootwin, &x, &y, &width, &height, + &border_width, &depth); + if (x11_untrap_errors ()) + return FALSE; - if (px) *px = x; - if (py) *py = y; - if (pwidth) *pwidth = width; - if (pheight) *pheight = height; - if (pdepth) *pdepth = depth; - return TRUE; + if (px) + *px = x; + if (py) + *py = y; + if (pwidth) + *pwidth = width; + if (pheight) + *pheight = height; + if (pdepth) + *pdepth = depth; + return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index f6faf257fc..ebc7380370 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -32,26 +32,20 @@ G_GNUC_INTERNAL void -x11_trap_errors(void); +x11_trap_errors (void); G_GNUC_INTERNAL int -x11_untrap_errors(void); +x11_untrap_errors (void); G_GNUC_INTERNAL Window -x11_create_window(Display *dpy, guint w, guint h, Visual *vis, Colormap cmap); +x11_create_window (Display * dpy, guint w, guint h, Visual * vis, + Colormap cmap); G_GNUC_INTERNAL gboolean -x11_get_geometry( - Display *dpy, - Drawable drawable, - gint *px, - gint *py, - guint *pwidth, - guint *pheight, - guint *pdepth -); +x11_get_geometry (Display * dpy, Drawable drawable, gint * px, gint * py, + guint * pwidth, guint * pheight, guint * pdepth); #endif /* GST_VAAPI_UTILS_X11_H */ From db7a3b8d3e179b055ca1b793d711e12ba6cee025 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 18:41:24 +0100 Subject: [PATCH 1571/3781] libs: factor out usages of vaGetConfigAttributes(). Add gst_vaapi_get_config_attribute() helper function that takes a GstVaapiDisplay and the rest of the arguments with VA types. The aim is to have thread-safe VA helpers by default. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapicontext.c | 54 ++++------------- gst-libs/gst/vaapi/gstvaapicontext.h | 5 -- gst-libs/gst/vaapi/gstvaapiencoder.c | 26 +++------ gst-libs/gst/vaapi/gstvaapiutils_core.c | 77 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_core.h | 40 +++++++++++++ 6 files changed, 138 insertions(+), 66 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_core.c create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_core.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 92b875aaa6..69eda14746 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -71,6 +71,7 @@ libgstvaapi_source_c = \ gstvaapisurfacepool.c \ gstvaapisurfaceproxy.c \ gstvaapiutils.c \ + gstvaapiutils_core.c \ gstvaapiutils_h264.c \ gstvaapiutils_mpeg2.c \ gstvaapivalue.c \ @@ -127,6 +128,7 @@ libgstvaapi_source_priv_h = \ gstvaapisurface_priv.h \ gstvaapisurfaceproxy_priv.h \ gstvaapiutils.h \ + gstvaapiutils_core.h \ gstvaapiutils_h264_priv.h \ gstvaapiutils_mpeg2_priv.h \ gstvaapiversion.h \ diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 96f1499b55..236f891083 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -39,6 +39,7 @@ #include "gstvaapisurfaceproxy.h" #include "gstvaapivideopool_priv.h" #include "gstvaapiutils.h" +#include "gstvaapiutils_core.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -50,6 +51,14 @@ unref_surface_cb (GstVaapiSurface * surface) gst_vaapi_object_unref (surface); } +static inline gboolean +context_get_attribute (GstVaapiContext * context, VAConfigAttribType type, + guint * out_value_ptr) +{ + return gst_vaapi_get_config_attribute (GST_VAAPI_OBJECT_DISPLAY (context), + context->va_profile, context->va_entrypoint, type, out_value_ptr); +} + static void context_destroy_surfaces (GstVaapiContext * context) { @@ -179,7 +188,7 @@ context_create (GstVaapiContext * context) /* Validate VA surface format */ attrib->type = VAConfigAttribRTFormat; - if (!gst_vaapi_context_get_attribute (context, attrib->type, &value)) + if (!context_get_attribute (context, attrib->type, &value)) goto cleanup; if (!(value & VA_RT_FORMAT_YUV420)) goto cleanup; @@ -193,7 +202,7 @@ context_create (GstVaapiContext * context) /* Rate control */ attrib->type = VAConfigAttribRateControl; - if (!gst_vaapi_context_get_attribute (context, attrib->type, &value)) + if (!context_get_attribute (context, attrib->type, &value)) goto cleanup; va_rate_control = from_GstVaapiRateControl (config->rc_mode); @@ -208,7 +217,7 @@ context_create (GstVaapiContext * context) /* Packed headers */ if (config->packed_headers) { attrib->type = VAConfigAttribEncPackedHeaders; - if (!gst_vaapi_context_get_attribute (context, attrib->type, &value)) + if (!context_get_attribute (context, attrib->type, &value)) goto cleanup; if ((value & config->packed_headers) != config->packed_headers) { @@ -436,42 +445,3 @@ gst_vaapi_context_get_surface_count (GstVaapiContext * context) return gst_vaapi_video_pool_get_size (context->surfaces_pool); } - -/** - * gst_vaapi_context_get_attribute: - * @context: a #GstVaapiContext - * @type: a VA config attribute type - * @out_value_ptr: return location for the config attribute value - * - * Determines the value for the VA config attribute @type. - * - * Note: this function only returns success if the VA driver does - * actually know about this config attribute type and that it returned - * a valid value for it. - * - * Return value: %TRUE if the VA driver knows about the requested - * config attribute and returned a valid value, %FALSE otherwise - */ -gboolean -gst_vaapi_context_get_attribute (GstVaapiContext * context, - VAConfigAttribType type, guint * out_value_ptr) -{ - VAConfigAttrib attrib; - VAStatus status; - - g_return_val_if_fail (context != NULL, FALSE); - - GST_VAAPI_OBJECT_LOCK_DISPLAY (context); - attrib.type = type; - status = vaGetConfigAttributes (GST_VAAPI_OBJECT_VADISPLAY (context), - context->va_profile, context->va_entrypoint, &attrib, 1); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (context); - if (!vaapi_check_status (status, "vaGetConfigAttributes()")) - return FALSE; - if (attrib.value == VA_ATTRIB_NOT_SUPPORTED) - return FALSE; - - if (out_value_ptr) - *out_value_ptr = attrib.value; - return TRUE; -} diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 24ba69777b..64e758fbfd 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -142,11 +142,6 @@ G_GNUC_INTERNAL guint gst_vaapi_context_get_surface_count (GstVaapiContext * context); -G_GNUC_INTERNAL -gboolean -gst_vaapi_context_get_attribute (GstVaapiContext * context, - VAConfigAttribType type, guint * out_value_ptr); - G_END_DECLS #endif /* GST_VAAPI_CONTEXT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 89eb579818..b055ef5ae0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -28,6 +28,7 @@ #include "gstvaapicontext.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiutils.h" +#include "gstvaapiutils_core.h" #include "gstvaapivalue.h" #define DEBUG 1 @@ -507,31 +508,18 @@ get_profile (GstVaapiEncoder * encoder) /* Gets config attribute for the supplied profile */ static gboolean get_config_attribute (GstVaapiEncoder * encoder, VAConfigAttribType type, - guint32 * out_value_ptr) + guint * out_value_ptr) { GstVaapiProfile profile; - VAConfigAttrib attrib; - VAStatus status; + VAProfile va_profile; profile = get_profile (encoder); if (!profile) return FALSE; - GST_VAAPI_DISPLAY_LOCK (encoder->display); - attrib.type = type; - status = - vaGetConfigAttributes (GST_VAAPI_DISPLAY_VADISPLAY (encoder->display), - gst_vaapi_profile_get_va_profile (profile), VAEntrypointEncSlice, - &attrib, 1); - GST_VAAPI_DISPLAY_UNLOCK (encoder->display); - if (!vaapi_check_status (status, "vaGetConfigAttributes()")) - return FALSE; - if (attrib.value == VA_ATTRIB_NOT_SUPPORTED) - return FALSE; - - if (out_value_ptr) - *out_value_ptr = attrib.value; - return TRUE; + va_profile = gst_vaapi_profile_get_va_profile (profile); + return gst_vaapi_get_config_attribute (encoder->display, va_profile, + VAEntrypointEncSlice, type, out_value_ptr); } /* Determines the set of supported packed headers */ @@ -781,7 +769,7 @@ error_invalid_property: } /* Determine the supported rate control modes */ -static guint32 +static guint get_rate_control_mask (GstVaapiEncoder * encoder) { const GstVaapiEncoderClassData *const cdata = diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.c b/gst-libs/gst/vaapi/gstvaapiutils_core.c new file mode 100644 index 0000000000..fe0832654f --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.c @@ -0,0 +1,77 @@ +/* + * gstvaapiutils_core.c - VA-API utilities (Core, MT-safe) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne + * Copyright (C) 2011-2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 "gstvaapiutils.h" +#include "gstvaapiutils_core.h" +#include "gstvaapidisplay_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +/** + * gst_vaapi_get_config_attribute: + * @display: a #GstVaapiDisplay + * @profile: a VA profile + * @entrypoint: a VA entrypoint + * @type: a VA config attribute type + * @out_value_ptr: return location for the config attribute value + * + * Determines the value for the VA config attribute @type and the + * given @profile/@entrypoint pair. If @out_value_ptr is %NULL, then + * this functions acts as a way to query whether the underlying VA + * driver supports the specified attribute @type, no matter the + * returned value. + * + * Note: this function only returns success if the VA driver does + * actually know about this config attribute type and that it returned + * a valid value for it. + * + * Return value: %TRUE if the VA driver knows about the requested + * config attribute and returned a valid value, %FALSE otherwise + */ +gboolean +gst_vaapi_get_config_attribute (GstVaapiDisplay * display, VAProfile profile, + VAEntrypoint entrypoint, VAConfigAttribType type, guint * out_value_ptr) +{ + VAConfigAttrib attrib; + VAStatus status; + + g_return_val_if_fail (display != NULL, FALSE); + + GST_VAAPI_DISPLAY_LOCK (display); + attrib.type = type; + status = vaGetConfigAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display), + profile, entrypoint, &attrib, 1); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaGetConfigAttributes()")) + return FALSE; + if (attrib.value == VA_ATTRIB_NOT_SUPPORTED) + return FALSE; + + if (out_value_ptr) + *out_value_ptr = attrib.value; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.h b/gst-libs/gst/vaapi/gstvaapiutils_core.h new file mode 100644 index 0000000000..7f9dcf9b59 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.h @@ -0,0 +1,40 @@ +/* + * gstvaapiutils_core.h - VA-API utilities (Core, MT-safe) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne + * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_UTILS_CORE_H +#define GST_VAAPI_UTILS_CORE_H + +#include + +G_BEGIN_DECLS + +/* Gets attribute value for the supplied profile/entrypoint pair (MT-safe) */ +G_GNUC_INTERNAL +gboolean +gst_vaapi_get_config_attribute (GstVaapiDisplay * display, VAProfile profile, + VAEntrypoint entrypoint, VAConfigAttribType type, guint * out_value_ptr); + +G_END_DECLS + +#endif /* GST_VAAPI_UTILS_CORE_H */ From e6fb4c1cdc727c8f737979995cf51ad12ba5887a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 20 Jan 2014 14:16:56 +0100 Subject: [PATCH 1572/3781] tests: test-filter: fix "deinterlace" option parse. Default to GST_VAAPI_DEINTERLACE_METHOD_NONE if no "deinterlace" option string was provided, i.e. if it remained set to NULL. --- tests/test-filter.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test-filter.c b/tests/test-filter.c index 52452b3196..8e19fab778 100755 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -296,7 +296,11 @@ parse_deinterlace(const gchar *str, GstVaapiDeinterlaceMethod *deinterlace_ptr) { g_return_val_if_fail(deinterlace_ptr != NULL, FALSE); - return str && parse_enum(str, GST_VAAPI_TYPE_DEINTERLACE_METHOD, + if (!str) { + *deinterlace_ptr = GST_VAAPI_DEINTERLACE_METHOD_NONE; + return TRUE; + } + return parse_enum(str, GST_VAAPI_TYPE_DEINTERLACE_METHOD, GST_VAAPI_DEINTERLACE_METHOD_NONE, (gint *)deinterlace_ptr); } From 0b176dea0f7bedf84dd17ff5a2d50bc069c06027 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 19:18:13 +0100 Subject: [PATCH 1573/3781] NEWS: updates. --- NEWS | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 600f716f9e..720272e274 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,22 @@ -gst-vaapi NEWS -- summary of changes. 2013-11-21 +gst-vaapi NEWS -- summary of changes. 2014-01-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora +Version 0.5.8 - DD.Jan.2014 +* Add H.264 video encoding (+Feng Yuan) +* Add MPEG-2 video encoding (+Guangxin Xu) +* Add initial support for GStreamer 1.3 (Matthieu Bouron) +* Add support for H.264 Constrained Baseline profile (Feng Yuan) +* Add support for colorbalance adjustment in vaapipostproc (Halley Zhao) +* Add color space conversion in vaapisink (Holger Kaelberer) [#722255] +* Fix OpenGL interop with clutter-gst and glimagesink elements (Matthieu Bouron) +* Fix decoding of H.264 quantization matrices (+Cong Zhong) [#706406] +* Fix robustness of H.264 decoder when packets are missing +* Fix hang in vaapidecode on SIGINT [+C] (Fen Yuan) [#720584] +* Fix vaapisink initialization with foreign window (Holger Kaelberer) [#722244] +* Fix Sharpening filter in vaapipostproc (Halley Zhao) [#720375] + Version 0.5.7 - 21.Nov.2013 * Add support for GStreamer 1.2 (+Victor Jaquez, Sreerenj Balachandran) * Add support for video processing (VA/VPP) (+Halley Zhao) From 271fb8298d2fa3371b5013fefa9b4b2e458032ca Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 19:32:28 +0100 Subject: [PATCH 1574/3781] README: updates. VA-API up to 0.34.0 is actually supported. Mention new video encoding support. Update copyright years, list of supported Intel HD Graphics hardware. --- README | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/README b/README index bfb7993ce0..69c841358b 100644 --- a/README +++ b/README @@ -3,7 +3,7 @@ VA-API support to GStreamer Copyright (C) 2010-2011 Splitted-Desktop Systems - Copyright (C) 2011-2013 Intel Corporation + Copyright (C) 2011-2014 Intel Corporation Copyright (C) 2011 Collabora Ltd. @@ -24,6 +24,11 @@ GStreamer and helper libraries. WMV3 videos to video/x-vaapi-surfaces surfaces, depending on the underlying HW capabilities. + * `vaapiencode_' is used to encode into MPEG-2, H.264 videos, + depending on the actual value of (mpeg2, h264, etc.). By + default, raw format bitstreams are generated, so the result may be + piped to an actual muxer like qtmux for MP4 containers. + * `vaapiupload' is used to convert from video/x-raw-yuv pixels to video/x-vaapi-surface surfaces. @@ -40,12 +45,14 @@ GStreamer and helper libraries. Features -------- - * VA-API support from 0.29 to 0.32 + * VA-API support from 0.29 to 0.34 * JPEG, MPEG-2, MPEG-4, H.264 and VC-1 ad-hoc decoders + * MPEG-2, H.264 ad-hoc encoders * OpenGL rendering through VA/GLX or GLX texture-from-pixmap + FBO * 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 Reduction @@ -65,7 +72,7 @@ Software requirements libgstreamer-plugins-bad0.10-dev (>= 0.10.22.1) or with GstVideoContext, GstSurfaceBuffer, codecparsers - * GStreamer 1.0.x (including GStreamer 1.2): + * GStreamer 1.0.x (including GStreamer 1.2, 1.3): libglib2.0-dev (>= 2.28) libgstreamer1.0-dev (>= 1.0.0) libgstreamer-plugins-base1.0-dev (>= 1.0.0) @@ -81,7 +88,7 @@ Hardware requirements * AMD platforms with UVD2 (XvBA supported) * Intel Eaglelake (G45) - * Intel Ironlake, Sandy Bridge and Ivy Bridge (HD Graphics) + * Intel Ironlake, Sandybridge, Ivybridge and Haswell (HD Graphics) * Intel Poulsbo (US15W) * Intel Medfield or Cedar Trail * NVIDIA platforms with PureVideo (VDPAU supported) @@ -108,6 +115,26 @@ Usage 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 ! \ + vaapiencode_h264 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: + + + Git repository for work-in-progress changes is available at: + + + Reporting Bugs -------------- From b545c6fcbcfc582abc6efe40e0409501886ffbbf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 19:36:14 +0100 Subject: [PATCH 1575/3781] 0.5.8. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 720272e274..8ffad08387 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2014-01-DD +gst-vaapi NEWS -- summary of changes. 2014-01-23 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora -Version 0.5.8 - DD.Jan.2014 +Version 0.5.8 - 23.Jan.2014 * Add H.264 video encoding (+Feng Yuan) * Add MPEG-2 video encoding (+Guangxin Xu) * Add initial support for GStreamer 1.3 (Matthieu Bouron) diff --git a/configure.ac b/configure.ac index 3726f1e73f..61c2f6c778 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [8]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 614aa4ac95f6ddc5103ca4f6e2098b23cd9f8334 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 22:44:09 +0100 Subject: [PATCH 1576/3781] build: fix for older versions of VA-API (< 0.34.0). Fix build with older versions of VA-API (< 0.34.0), or versions without good enough headers for encoding support for instance. --- gst-libs/gst/vaapi/gstvaapicontext.c | 4 +++- gst-libs/gst/vaapi/gstvaapiutils.c | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 236f891083..b306a6f4ee 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -152,7 +152,6 @@ context_create (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); - guint va_rate_control; VAConfigAttrib attribs[3], *attrib = attribs; VAContextID context_id; VASurfaceID surface_id; @@ -196,9 +195,11 @@ context_create (GstVaapiContext * context) attrib++; 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 */ attrib->type = VAConfigAttribRateControl; @@ -230,6 +231,7 @@ context_create (GstVaapiContext * context) } break; } +#endif default: break; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 10bc606e77..87923cc49b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -214,16 +214,20 @@ string_of_VARateControl (guint rate_control) switch (rate_control) { case VA_RC_NONE: return "None"; +#ifdef VA_RC_CQP case VA_RC_CQP: return "CQP"; +#endif case VA_RC_CBR: return "CBR"; case VA_RC_VCM: return "VCM"; case VA_RC_VBR: return "VBR"; +#ifdef VA_RC_VBR_CONSTRAINED case VA_RC_VBR_CONSTRAINED: return "VBR-Constrained"; +#endif default: break; } @@ -492,16 +496,20 @@ from_GstVaapiRateControl (guint value) switch (value) { case GST_VAAPI_RATECONTROL_NONE: return VA_RC_NONE; +#ifdef VA_RC_CQP case GST_VAAPI_RATECONTROL_CQP: return VA_RC_CQP; +#endif case GST_VAAPI_RATECONTROL_CBR: return VA_RC_CBR; case GST_VAAPI_RATECONTROL_VCM: return VA_RC_VCM; case GST_VAAPI_RATECONTROL_VBR: return VA_RC_VBR; +#ifdef VA_RC_VBR_CONSTRAINED case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: return VA_RC_VBR_CONSTRAINED; +#endif } GST_ERROR ("unsupported GstVaapiRateControl value %u", value); return VA_RC_NONE; @@ -513,16 +521,20 @@ to_GstVaapiRateControl (guint value) switch (value) { case VA_RC_NONE: return GST_VAAPI_RATECONTROL_NONE; +#ifdef VA_RC_CQP case VA_RC_CQP: return GST_VAAPI_RATECONTROL_CQP; +#endif case VA_RC_CBR: return GST_VAAPI_RATECONTROL_CBR; case VA_RC_VCM: return GST_VAAPI_RATECONTROL_VCM; case VA_RC_VBR: return GST_VAAPI_RATECONTROL_VBR; +#ifdef VA_RC_VBR_CONSTRAINED case VA_RC_VBR_CONSTRAINED: return GST_VAAPI_RATECONTROL_VBR_CONSTRAINED; +#endif } GST_ERROR ("unsupported VA-API Rate Control value %u", value); return GST_VAAPI_RATECONTROL_NONE; From cab11ef609622097052b9b4d5b854a73ce6c4fa1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 22:47:19 +0100 Subject: [PATCH 1577/3781] build: fix warnings on 64-bit platforms. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 9224b1a241..aeb5d05073 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -375,7 +375,7 @@ push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) GstVaapiSurfaceProxy * const proxy = frame->user_data; GST_DEBUG("push frame %d (surface 0x%08x)", frame->system_frame_number, - GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy)); + (guint32) GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy)); g_async_queue_push(decoder->frames, gst_video_codec_frame_ref(frame)); } @@ -395,7 +395,8 @@ pop_frame(GstVaapiDecoder *decoder, guint64 timeout) proxy = frame->user_data; GST_DEBUG("pop frame %d (surface 0x%08x)", frame->system_frame_number, - proxy ? GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) : VA_INVALID_ID); + (proxy ? (guint32) GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) : + VA_INVALID_ID)); return frame; } From 183897d4aed709d665405a4e10f693b7bedc88b4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Jan 2014 23:24:55 +0100 Subject: [PATCH 1578/3781] debian: fix package description. Try to improve package description for the compiled plug-in elements available in there. e.g. only display vaapidownload and vaapiupload for GStreamer 0.10 builds, display vaapiencode_* elements when VA encoding is enabled, etc. Also increase the copyright notice date. --- debian.upstream/control.in | 8 +++++--- debian.upstream/copyright | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 9897e9d9da..021f5fbcda 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -24,9 +24,11 @@ Suggests: gstreamer@GST_API_VERSION@-vaapi-doc Description: VA-API plugins for GStreamer This package contains GStreamer plugins for VA-API support: - `vaapidecode': decode bitstreams using VA-API - - `vaapiupload': converts from YUV pixels to VA surfaces - - `vaapidownload': convert from VA surfaces to YUV pixels - - `vaapipostproc': postprocess VA surfaces, e.g. deinterlacing +@USE_ENCODERS_TRUE@ - `vaapiencode_mpeg2': encode bitstreams using VA-API (MPEG-2 codec) +@USE_ENCODERS_TRUE@ - `vaapiencode_h264': encode bitstreams using VA-API (H.264 codec) +@USE_GST_API_0_10_TRUE@ - `vaapiupload': convert from YUV pixels to VA surfaces +@USE_GST_API_0_10_TRUE@ - `vaapidownload': convert from VA surfaces to YUV pixels + - `vaapipostproc': postprocess VA surfaces, e.g. for deinterlacing - `vaapisink': a VA-API based video sink Package: gstreamer@GST_API_VERSION@-vaapi-doc diff --git a/debian.upstream/copyright b/debian.upstream/copyright index 083ce8634e..4ebb78e8cc 100644 --- a/debian.upstream/copyright +++ b/debian.upstream/copyright @@ -9,7 +9,7 @@ Copyright: License: Copyright (C) 2010-2011, Splitted-Desktop Systems. - Copyright (C) 2011-2013, Intel Corporation. + Copyright (C) 2011-2014, Intel Corporation. Copyright (C) 2011, Collabora Ltd. gstreamer-vaapi helper libraries and plugins elements are available under From c9af9a86088fa6d943bec91005d4c58f37f69a05 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 24 Jan 2014 10:55:39 +0100 Subject: [PATCH 1579/3781] debian: fix trailing whitespace in description. --- debian.upstream/control.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 021f5fbcda..0d0f140000 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -26,7 +26,7 @@ Description: VA-API plugins for GStreamer - `vaapidecode': decode bitstreams using VA-API @USE_ENCODERS_TRUE@ - `vaapiencode_mpeg2': encode bitstreams using VA-API (MPEG-2 codec) @USE_ENCODERS_TRUE@ - `vaapiencode_h264': encode bitstreams using VA-API (H.264 codec) -@USE_GST_API_0_10_TRUE@ - `vaapiupload': convert from YUV pixels to VA surfaces +@USE_GST_API_0_10_TRUE@ - `vaapiupload': convert from YUV pixels to VA surfaces @USE_GST_API_0_10_TRUE@ - `vaapidownload': convert from VA surfaces to YUV pixels - `vaapipostproc': postprocess VA surfaces, e.g. for deinterlacing - `vaapisink': a VA-API based video sink From b763fdac2cd621e10f0d44f56f8c245c378d0b22 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 24 Jan 2014 11:27:30 +0100 Subject: [PATCH 1580/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 61c2f6c778..762f0c6dda 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [8]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [9]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 6e621413ab9f7b37b8c53a62f6183d3ed55b7a8e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Feb 2014 09:43:51 +0100 Subject: [PATCH 1581/3781] build: fix packaging for GStreamer 1.2. Fix gstreamer-vaapi includedir for GStreamer 1.2 setups. i.e. use the pkgconfig version (1.0) instead of the intended API version (1.2). libgstvaapi1.0-dev and libgstvaapi1.2-dev packages will now conflict, as would core GStreamer 1.0 and GStreamer 1.2 dev packages anyway. --- debian.upstream/libgstvaapi-dev.install.in | 2 +- gst-libs/gst/vaapi/Makefile.am | 2 +- pkgconfig/gstreamer-vaapi.pc.in | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/debian.upstream/libgstvaapi-dev.install.in b/debian.upstream/libgstvaapi-dev.install.in index 764bc3ac0d..33d178a05a 100644 --- a/debian.upstream/libgstvaapi-dev.install.in +++ b/debian.upstream/libgstvaapi-dev.install.in @@ -1,3 +1,3 @@ debian/tmp/usr/lib/libgstvaapi*.so debian/tmp/usr/lib/pkgconfig/gstreamer-vaapi*.pc -debian/tmp/usr/include/gstreamer-@GST_API_VERSION@/gst/vaapi/*.h +debian/tmp/usr/include/gstreamer-@GST_PKG_VERSION@/gst/vaapi/*.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 69eda14746..4d617137f8 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -17,7 +17,7 @@ lib_LTLIBRARIES += libgstvaapi-wayland-@GST_API_VERSION@.la endif libgstvaapi_includedir = \ - $(includedir)/gstreamer-$(GST_API_VERSION)/gst/vaapi + $(includedir)/gstreamer-$(GST_PKG_VERSION)/gst/vaapi libgstvaapi_cflags = \ -DIN_LIBGSTVAAPI \ diff --git a/pkgconfig/gstreamer-vaapi.pc.in b/pkgconfig/gstreamer-vaapi.pc.in index af6706bd67..57c56095b3 100644 --- a/pkgconfig/gstreamer-vaapi.pc.in +++ b/pkgconfig/gstreamer-vaapi.pc.in @@ -6,7 +6,7 @@ pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ Name: GStreamer VA-API Plugins Libraries Description: Streaming media framework, VA-API plugins libraries -Requires: gstreamer-@GST_PKG_VERSION@ gstreamer-base-@GST_PKG_VERSION@ @LIBVA_PKGNAME@ +Requires: gstreamer-@GST_PKG_VERSION@ >= @GST_VERSION_REQUIRED@ gstreamer-base-@GST_PKG_VERSION@ >= @GST_PLUGINS_BASE_VERSION_REQUIRED@ @LIBVA_PKGNAME@ Version: @VERSION@ Libs: -L${libdir} -lgstvaapi-@GST_API_VERSION@ Cflags: -I${includedir} From b024e6940bf1e92e4e8717c61a8ea07f3b3e42b8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 18 Feb 2014 06:56:51 +0100 Subject: [PATCH 1582/3781] build: fix pkgconfig file names (again). It turns out it is more convenient to have only pkgconfig files named after the installed GStreamer API version (1.0) instead of using all possible subsequent names from that (1.0, 1.2, 1.4). i.e. they conflict altogether anyway, so align pkgconfig file names to that. --- configure.ac | 10 +++++----- pkgconfig/Makefile.am | 4 ++-- pkgconfig/gstreamer-vaapi-drm.pc.in | 2 +- pkgconfig/gstreamer-vaapi-glx.pc.in | 2 +- pkgconfig/gstreamer-vaapi-wayland.pc.in | 2 +- pkgconfig/gstreamer-vaapi-x11.pc.in | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 762f0c6dda..bb194aa414 100644 --- a/configure.ac +++ b/configure.ac @@ -793,15 +793,15 @@ debian.upstream/libgstvaapi-x11.install.in gst/Makefile gst/vaapi/Makefile pkgconfig/Makefile - pkgconfig/gstreamer-vaapi-$GST_API_VERSION.pc:\ + pkgconfig/gstreamer-vaapi-$GST_PKG_VERSION.pc:\ pkgconfig/gstreamer-vaapi.pc.in - pkgconfig/gstreamer-vaapi-drm-$GST_API_VERSION.pc:\ + pkgconfig/gstreamer-vaapi-drm-$GST_PKG_VERSION.pc:\ pkgconfig/gstreamer-vaapi-drm.pc.in - pkgconfig/gstreamer-vaapi-glx-$GST_API_VERSION.pc:\ + pkgconfig/gstreamer-vaapi-glx-$GST_PKG_VERSION.pc:\ pkgconfig/gstreamer-vaapi-glx.pc.in - pkgconfig/gstreamer-vaapi-wayland-$GST_API_VERSION.pc:\ + pkgconfig/gstreamer-vaapi-wayland-$GST_PKG_VERSION.pc:\ pkgconfig/gstreamer-vaapi-wayland.pc.in - pkgconfig/gstreamer-vaapi-x11-$GST_API_VERSION.pc:\ + pkgconfig/gstreamer-vaapi-x11-$GST_PKG_VERSION.pc:\ pkgconfig/gstreamer-vaapi-x11.pc.in tests/Makefile ]) diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index c6339977ad..25c3cb227f 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -12,7 +12,7 @@ if USE_WAYLAND pcfiles_in += gstreamer-vaapi-wayland.pc.in endif -pcfiles = $(pcfiles_in:%.pc.in=%-$(GST_API_VERSION).pc) +pcfiles = $(pcfiles_in:%.pc.in=%-$(GST_PKG_VERSION).pc) all_pcfiles_in = gstreamer-vaapi.pc.in all_pcfiles_in += gstreamer-vaapi-drm.pc.in @@ -20,7 +20,7 @@ all_pcfiles_in += gstreamer-vaapi-x11.pc.in all_pcfiles_in += gstreamer-vaapi-glx.pc.in all_pcfiles_in += gstreamer-vaapi-wayland.pc.in -all_pcfiles = $(all_pcfiles_in:%.pc.in=%-$(GST_API_VERSION).pc) +all_pcfiles = $(all_pcfiles_in:%.pc.in=%-$(GST_PKG_VERSION).pc) pkgconfigdir = @pkgconfigdir@ pkgconfig_DATA = $(pcfiles) diff --git a/pkgconfig/gstreamer-vaapi-drm.pc.in b/pkgconfig/gstreamer-vaapi-drm.pc.in index 799592bbb7..f5f44d3d75 100644 --- a/pkgconfig/gstreamer-vaapi-drm.pc.in +++ b/pkgconfig/gstreamer-vaapi-drm.pc.in @@ -6,7 +6,7 @@ pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ Name: GStreamer VA-API (DRM) Plugins Libraries Description: Streaming media framework, VA-API (DRM) plugins libraries -Requires: gstreamer-vaapi-@GST_API_VERSION@ libva-drm +Requires: gstreamer-vaapi-@GST_PKG_VERSION@ libva-drm Version: @VERSION@ Libs: -L${libdir} -lgstvaapi-drm-@GST_API_VERSION@ Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi-glx.pc.in b/pkgconfig/gstreamer-vaapi-glx.pc.in index 7a71b14d60..4ac3d11cf7 100644 --- a/pkgconfig/gstreamer-vaapi-glx.pc.in +++ b/pkgconfig/gstreamer-vaapi-glx.pc.in @@ -6,7 +6,7 @@ pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ Name: GStreamer VA-API (GLX) Plugins Libraries Description: Streaming media framework, VA-API (GLX) plugins libraries -Requires: gstreamer-vaapi-@GST_API_VERSION@ @LIBVA_GLX_PKGNAME@ +Requires: gstreamer-vaapi-@GST_PKG_VERSION@ @LIBVA_GLX_PKGNAME@ Version: @VERSION@ Libs: -L${libdir} -lgstvaapi-glx-@GST_API_VERSION@ Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi-wayland.pc.in b/pkgconfig/gstreamer-vaapi-wayland.pc.in index 05f5128d69..2ec0a87ad5 100644 --- a/pkgconfig/gstreamer-vaapi-wayland.pc.in +++ b/pkgconfig/gstreamer-vaapi-wayland.pc.in @@ -6,7 +6,7 @@ pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ Name: GStreamer VA-API (Wayland) Plugins Libraries Description: Streaming media framework, VA-API (Wayland) plugins libraries -Requires: gstreamer-vaapi-@GST_API_VERSION@ libva-wayland +Requires: gstreamer-vaapi-@GST_PKG_VERSION@ libva-wayland Version: @VERSION@ Libs: -L${libdir} -lgstvaapi-wayland-@GST_API_VERSION@ Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi-x11.pc.in b/pkgconfig/gstreamer-vaapi-x11.pc.in index acdbb51147..7c0eb6db37 100644 --- a/pkgconfig/gstreamer-vaapi-x11.pc.in +++ b/pkgconfig/gstreamer-vaapi-x11.pc.in @@ -6,7 +6,7 @@ pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ Name: GStreamer VA-API (X11) Plugins Libraries Description: Streaming media framework, VA-API (X11) plugins libraries -Requires: gstreamer-vaapi-@GST_API_VERSION@ @LIBVA_X11_PKGNAME@ +Requires: gstreamer-vaapi-@GST_PKG_VERSION@ @LIBVA_X11_PKGNAME@ Version: @VERSION@ Libs: -L${libdir} -lgstvaapi-x11-@GST_API_VERSION@ Cflags: -I${includedir} From e52d394b9e1e7124a141cc26675068e6fc2446a9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 4 Feb 2014 18:35:28 +0100 Subject: [PATCH 1583/3781] decoder: h264: fix robustness patch for bytestream format. Fix parser and decoder state to sync at the right locations. This is because we could reset the parser state, while the decoder state was not copied yet, e.g. when parsing several NAL units from multiple frames whereas the current frame was not decoded yet. This is a regression brought in by commit 6fe5496. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 94ebae9cae..ba38d54efd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -68,6 +68,7 @@ struct _GstVaapiParserInfoH264 { GstH264PPS pps; GstH264SliceHdr slice_hdr; } data; + guint state; }; static inline const GstVaapiMiniObjectClass * @@ -2581,9 +2582,7 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) if (!fill_picture(decoder, picture, pi)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - priv->decoder_state = priv->parser_state & ( - GST_H264_VIDEO_STATE_GOT_SPS | - GST_H264_VIDEO_STATE_GOT_PPS); + priv->decoder_state = pi->state; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2745,7 +2744,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GST_DEBUG("slice (%u bytes)", pi->nalu.size); - if (!is_valid_state(priv->decoder_state, + if (!is_valid_state(pi->state, GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS)) { GST_WARNING("failed to receive enough headers to decode slice"); return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -2787,9 +2786,11 @@ scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) static GstVaapiDecoderStatus decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstVaapiDecoderStatus status; + priv->decoder_state |= pi->state; switch (pi->nalu.type) { case GST_H264_NAL_SLICE_IDR: /* fall-through. IDR specifics are handled in init_picture() */ @@ -3044,6 +3045,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); pi->nalu.data = NULL; + pi->state = priv->parser_state; return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 100f56eedf32c3a780b9d9f0e09435aad2912bd6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 21 Mar 2014 15:09:14 +0100 Subject: [PATCH 1584/3781] codecparsers: update to gst-vaapi-branch commit 8fadf40. 8fadf40 h264: Fix multiple SEI messages in one SEI RBSP parsing. 644825f h265: remove trailling 0x00 bytes as the spec doesn't allow them 95f9f0f h264: remove trailling 0x00 bytes as the spec doesn't allow them 766007b h265: Initialize pointer correctly that is never assigned but freed in error cases 8ec5816 h265: Fix segfault when parsing HRD parameter 5b1730f h265: Fix segfault when parsing VPS 983b7f7 h265: prevent to overrun chroma_weight_l0_flag 7ba641d h265: Fix debug output d9f9f9b h264: not all startcodes should have 3-byte 0 prefix --- ext/codecparsers | 2 +- gst-libs/gst/codecparsers/Makefile.am | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/codecparsers b/ext/codecparsers index e7d0e18bc3..98dee13220 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit e7d0e18bc3f3a2db119a03430a833047e1cc10d4 +Subproject commit 98dee1322049fe172b0bd90d3143e0d6a29d3fd4 diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index c0581e3cbe..1da2217df0 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -18,8 +18,8 @@ libgstvaapi_codecparsers_libs = \ $(GST_LIBS) \ $(NULL) -gen_source_c = parserutils.c -gen_source_h = parserutils.h +gen_source_c = parserutils.c nalutils.c +gen_source_h = parserutils.h nalutils.h # Always build VC-1 and MPEG-4 parsers for now gen_source_c += gstvc1parser.c gstmpeg4parser.c From 1a5918b1d7bd0863ccb802b4f334e854a6a7ca00 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Apr 2014 19:16:56 +0200 Subject: [PATCH 1585/3781] codecparsers: update to gst-vaapi-branch commit d459bc5. d459bc5 h264: set framerate even for interlaced videos c78b82c h264: add support for Recovery Point SEI message 7693bac h264: add support for Frame Packing Arrangement SEI message 31fafa7 h264: add support for Stereo Video Information SEI message 8b113a6 h264: parse seq_parameter_set_mvc_extension() 040f9b8 h264: parse MVC syntax elements cc18ef3 h264: add nal_reader_skip_long() helper 7e76a48 h264: fix slice_header() parsing for MVC caf46d8 h264: add gst_h264_parse_nalu_header() helper f75074e h264: add gst_h264_parse_sps_data() helper 798c397 h264: clean-up gst_h264_parser_parse_sei_message() 4e36737 h264: fix skipping of unsupported SEI messages 5300766 h264: fix SEI buffering_period() parsing --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 98dee13220..d459bc5091 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 98dee1322049fe172b0bd90d3143e0d6a29d3fd4 +Subproject commit d459bc5091bc0ab27991f62d491cdc290331e496 From 095ac1b378e7902e4e9d7faccb9971d1ae065b54 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Apr 2014 19:36:16 +0200 Subject: [PATCH 1586/3781] codecparsers: update to gst-vaapi-branch commit a454f86. b2eb5f6 vp8: rename dboolhuff symbols b74a881 vp8: add GStreamer native utilities 2940ac6 add VP8 bitstream parser --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index d459bc5091..a454f86018 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit d459bc5091bc0ab27991f62d491cdc290331e496 +Subproject commit a454f860186efe61c874cc938aecd7818d2935d1 From 450092e37115199867892520b3c1eddeeb101ce7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 21 Mar 2014 15:15:37 +0100 Subject: [PATCH 1587/3781] decoder: h264: cope with new gst_h264_parser_parse_sei() interface. The gst_h264_parse_parse_sei() function now returns an array of SEI messages, instead of a single SEI message. Reason: it is allowed to have several SEI messages packed into a single SEI NAL unit, instead of multiple NAL units. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index ba38d54efd..69bef667ac 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1056,18 +1056,19 @@ parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GstH264SEIMessage sei; + GArray *sei_messages = NULL; GstH264ParserResult result; GST_DEBUG("parse SEI"); - memset(&sei, 0, sizeof(sei)); - result = gst_h264_parser_parse_sei(priv->parser, &pi->nalu, &sei); + result = gst_h264_parser_parse_sei(priv->parser, &pi->nalu, &sei_messages); if (result != GST_H264_PARSER_OK) { - GST_WARNING("failed to parse SEI, payload type:%d", sei.payloadType); + GST_WARNING("failed to parse SEI messages"); + g_array_unref(sei_messages); return get_status(result); } + g_array_unref(sei_messages); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 029bae0b6a62a5bf46116ec73c2747f4692f5c51 Mon Sep 17 00:00:00 2001 From: "Zhao, Halley" Date: Fri, 27 Dec 2013 07:18:24 +0800 Subject: [PATCH 1588/3781] Add initial VP8 decoder. https://bugzilla.gnome.org/show_bug.cgi?id=722761 [complete overhaul, fixed support for resolution changes] Signed-off-by: Gwenole Beauchesne --- configure.ac | 50 ++ ext/Makefile.am | 2 + gst-libs/gst/codecparsers/Makefile.am | 8 + gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapicodec_objects.c | 36 + gst-libs/gst/vaapi/gstvaapicodec_objects.h | 35 + gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 7 + gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 664 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_vp8.h | 38 ++ gst-libs/gst/vaapi/gstvaapiprofile.c | 3 + gst-libs/gst/vaapi/gstvaapiprofile.h | 2 + gst/vaapi/gstvaapidecode.c | 5 + 13 files changed, 853 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_vp8.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_vp8.h diff --git a/configure.ac b/configure.ac index bb194aa414..52d268d4ea 100644 --- a/configure.ac +++ b/configure.ac @@ -335,6 +335,7 @@ if test "$enable_builtin_codecparsers" = "yes"; then ac_cv_have_gst_mpeg2_parser="no" ac_cv_have_gst_h264_parser="no" ac_cv_have_gst_jpeg_parser="no" + ac_cv_have_gst_vp8_parser="no" else PKG_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) @@ -413,6 +414,26 @@ AC_CACHE_CHECK([for JPEG parser], AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_JPEG], [test "$ac_cv_have_gst_jpeg_parser" != "yes"]) +dnl ... VP8 parser, not upstream yet +AC_CACHE_CHECK([for VP8 parser], + ac_cv_have_gst_vp8_parser, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[GstVp8FrameHdr frame_hdr;]])], + [ac_cv_have_gst_vp8_parser="yes"], + [ac_cv_have_gst_vp8_parser="no"] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +]) +AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_VP8], + [test "$ac_cv_have_gst_vp8_parser" != "yes"]) + case $GST_API_VERSION in 0.10) lt_bias=gst0_vaapi_lt_current_bias;; 1.0) lt_bias=gst1_vaapi_lt_current_bias;; @@ -665,6 +686,31 @@ AC_CACHE_CHECK([for JPEG decoding API], LIBS="$saved_LIBS" ]) +dnl Check for VP8 decoding API (0.34+) +USE_VP8_DECODER=0 +AC_CACHE_CHECK([for VP8 decoding API], + ac_cv_have_vp8_decoding_api, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include + ]], + [[VAPictureParameterBufferVP8 pic_param; + VASliceParameterBufferVP8 slice_param; + VAProbabilityDataBufferVP8 prob_data; + VAIQMatrixBufferVP8 iq_matrix;]])], + [ac_cv_have_vp8_decoding_api="yes" USE_VP8_DECODER=1], + [ac_cv_have_vp8_decoding_api="no"] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +]) + + dnl Check for vpp (video post-processing) support USE_VA_VPP=0 AC_CACHE_CHECK([for video post-postprocessing API], @@ -737,6 +783,10 @@ AC_DEFINE_UNQUOTED(USE_JPEG_DECODER, $USE_JPEG_DECODER, [Defined to 1 if JPEG decoder is used]) AM_CONDITIONAL(USE_JPEG_DECODER, test $USE_JPEG_DECODER -eq 1) +AC_DEFINE_UNQUOTED(USE_VP8_DECODER, $USE_VP8_DECODER, + [Defined to 1 if JPEG decoder is used]) +AM_CONDITIONAL(USE_VP8_DECODER, test $USE_VP8_DECODER -eq 1) + AC_DEFINE_UNQUOTED(USE_DRM, $USE_DRM, [Defined to 1 if DRM is enabled]) AM_CONDITIONAL(USE_DRM, test $USE_DRM -eq 1) diff --git a/ext/Makefile.am b/ext/Makefile.am index cfb2bc0300..62f3ec4cb0 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -9,6 +9,7 @@ codecparsers_source_c = \ gstmpeg4parser.c \ gstmpegvideoparser.c \ gstvc1parser.c \ + gstvp8parser.c \ parserutils.c \ $(NULL) @@ -20,6 +21,7 @@ codecparsers_source_h = \ gstmpeg4parser.h \ gstmpegvideoparser.h \ gstvc1parser.h \ + gstvp8parser.h \ parserutils.h \ $(NULL) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 1da2217df0..3d414d9514 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -40,6 +40,14 @@ gen_source_c += gsth264parser.c gen_source_h += gsth264parser.h endif +if USE_LOCAL_CODEC_PARSERS_VP8 +gen_source_c += gstvp8parser.c +gen_source_h += gstvp8parser.h gstvp8rangedecoder.h vp8utils.h + +gen_source_c += dboolhuff.c gstvp8rangedecoder.c vp8utils.c +gen_source_h += dboolhuff.h +endif + GENFILES = \ $(gen_source_c) \ $(gen_source_h) \ diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 4d617137f8..402fff2788 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -56,6 +56,7 @@ libgstvaapi_source_c = \ gstvaapidecoder_objects.c \ gstvaapidecoder_unit.c \ gstvaapidecoder_vc1.c \ + gstvaapidecoder_vp8.c \ gstvaapidisplay.c \ gstvaapidisplaycache.c \ gstvaapifilter.c \ @@ -86,6 +87,7 @@ libgstvaapi_source_h = \ gstvaapidecoder_mpeg2.h \ gstvaapidecoder_mpeg4.h \ gstvaapidecoder_vc1.h \ + gstvaapidecoder_vp8.h \ gstvaapidisplay.h \ gstvaapifilter.h \ gstvaapiimage.h \ diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index d72c176f9b..edf4b35e42 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -212,3 +212,39 @@ gst_vaapi_huffman_table_new (GstVaapiDecoder * decoder, return GST_VAAPI_HUFFMAN_TABLE_CAST (object); } #endif +#if USE_VP8_DECODER +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); +} + +#endif diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index c7b7902015..163ebf773f 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -27,6 +27,9 @@ #include #include +#if USE_VP8_DECODER +#include +#endif G_BEGIN_DECLS @@ -36,6 +39,7 @@ typedef struct _GstVaapiCodecObjectClass GstVaapiCodecObjectClass; typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix; typedef struct _GstVaapiBitPlane GstVaapiBitPlane; typedef struct _GstVaapiHuffmanTable GstVaapiHuffmanTable; +typedef struct _GstVaapiProbabilityTable GstVaapiProbabilityTable; /* ------------------------------------------------------------------------- */ /* --- Base Codec Object --- */ @@ -195,6 +199,33 @@ 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 --- */ /* ------------------------------------------------------------------------- */ @@ -230,6 +261,10 @@ static const GstVaapiCodecObjectClass G_PASTE (type, Class) = { \ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index f3fb782990..5f8c0f0e2a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -71,6 +71,7 @@ gst_vaapi_picture_destroy (GstVaapiPicture * picture) 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); @@ -223,6 +224,7 @@ gst_vaapi_picture_decode (GstVaapiPicture * picture) GstVaapiIqMatrix *iq_matrix; GstVaapiBitPlane *bitplane; GstVaapiHuffmanTable *huf_table; + GstVaapiProbabilityTable *prob_table; VADisplay va_display; VAContextID va_context; VAStatus status; @@ -257,6 +259,11 @@ gst_vaapi_picture_decode (GstVaapiPicture * picture) &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]; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 91e73214e8..5a36f6318e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -134,6 +134,7 @@ struct _GstVaapiPicture GstVaapiIqMatrix *iq_matrix; GstVaapiHuffmanTable *huf_table; GstVaapiBitPlane *bitplane; + GstVaapiProbabilityTable *prob_table; GstClockTime pts; gint32 poc; guint structure; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c new file mode 100644 index 0000000000..40bf4db473 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -0,0 +1,664 @@ +/* + * gstvaapidecoder_vp8.c - VP8 decoder + * + * Copyright (C) 2013-2014 Intel Corporation + * Author: Halley Zhao + * Author: Gwenole Beauchesne + * + * 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 +#include "gstvaapidecoder_vp8.h" +#include "gstvaapidecoder_objects.h" +#include "gstvaapidecoder_priv.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapiobject_priv.h" + +#include "gstvaapicompat.h" +#include + +#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; + GstClockTime pts; + 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; +}; + +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; + priv->pts = GST_CLOCK_TIME_NONE; + return TRUE; +} + +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.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 = priv->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++) { + if (seg->segmentation_enabled) { + pic_param->loop_filter_level[i] = seg->lf_update_value[i]; + if (!seg->segment_feature_mode) + pic_param->loop_filter_level[i] += frame_hdr->loop_filter_level; + } else + pic_param->loop_filter_level[i] = frame_hdr->loop_filter_level; + + 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]; + } + if ((pic_param->pic_fields.bits.version == 0) + || (pic_param->pic_fields.bits.version == 1)) { + pic_param->pic_fields.bits.loop_filter_disable = + pic_param->loop_filter_level[0] == 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; + +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) +{ + GstVaapiDecoderVp8 *const decoder = GST_VAAPI_DECODER_VP8_CAST (base_decoder); + GstVaapiDecoderVp8Private *const priv = &decoder->priv; + guint flags = 0; + + priv->pts = gst_adapter_prev_pts (adapter, NULL); + 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); +} + +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_class_init (GstVaapiDecoderVp8Class * klass) +{ + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); + + object_class->size = sizeof (GstVaapiDecoderVp8); + object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; + + decoder_class->create = gst_vaapi_decoder_vp8_create; + decoder_class->destroy = gst_vaapi_decoder_vp8_destroy; + 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 inline const GstVaapiDecoderClass * +gst_vaapi_decoder_vp8_class (void) +{ + static GstVaapiDecoderVp8Class g_class; + static gsize g_class_init = FALSE; + + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_decoder_vp8_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS (&g_class); +} + +/** + * 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 gst_vaapi_decoder_new (gst_vaapi_decoder_vp8_class (), display, caps); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.h b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.h new file mode 100644 index 0000000000..43a88fdc85 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.h @@ -0,0 +1,38 @@ +/* + * gstvaapidecoder_vp8.h - VP8 decoder + * + * Copyright (C) 2013-2014 Intel Corporation + * Author: Halley Zhao + * Author: Gwenole Beauchesne + * + * 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 + +G_BEGIN_DECLS + +typedef struct _GstVaapiDecoderVp8 GstVaapiDecoderVp8; + +GstVaapiDecoder * +gst_vaapi_decoder_vp8_new (GstVaapiDisplay * display, GstCaps * caps); + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_VP8_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index ad3441a10d..76e5d0e0a3 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -65,6 +65,7 @@ static const GstVaapiCodecMap gst_vaapi_codecs[] = { { GST_VAAPI_CODEC_WMV3, "wmv3" }, { GST_VAAPI_CODEC_VC1, "vc1" }, { GST_VAAPI_CODEC_JPEG, "jpeg" }, + { GST_VAAPI_CODEC_VP8, "vp8" }, { 0, } }; @@ -125,6 +126,8 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "image/jpeg", "baseline" }, #endif + {GST_VAAPI_PROFILE_VP8, VAProfileVP8Version0_3, + "video/x-vp8", "Version0_3"}, { 0, } }; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index be74a0afe5..24dde8988a 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -51,6 +51,7 @@ typedef enum { GST_VAAPI_CODEC_WMV3 = GST_MAKE_FOURCC('W','M','V',0), GST_VAAPI_CODEC_VC1 = GST_MAKE_FOURCC('V','C','1',0), GST_VAAPI_CODEC_JPEG = GST_MAKE_FOURCC('J','P','G',0), + GST_VAAPI_CODEC_VP8 = GST_MAKE_FOURCC('V','P','8',0), } GstVaapiCodec; /** @@ -151,6 +152,7 @@ typedef enum { GST_VAAPI_PROFILE_VC1_MAIN = GST_VAAPI_MAKE_PROFILE(VC1,2), GST_VAAPI_PROFILE_VC1_ADVANCED = GST_VAAPI_MAKE_PROFILE(VC1,3), GST_VAAPI_PROFILE_JPEG_BASELINE = GST_VAAPI_MAKE_PROFILE(JPEG,1), + GST_VAAPI_PROFILE_VP8 = GST_VAAPI_MAKE_PROFILE(VP8,1), } GstVaapiProfile; /** diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 98d7916838..9b57480884 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -49,6 +49,7 @@ #include #include #include +#include #define GST_PLUGIN_NAME "vaapidecode" #define GST_PLUGIN_DESC "A VA-API based video decoder" @@ -67,6 +68,7 @@ static const char gst_vaapidecode_sink_caps_str[] = GST_CAPS_CODEC("video/x-h263") GST_CAPS_CODEC("video/x-h264") GST_CAPS_CODEC("video/x-wmv") + GST_CAPS_CODEC("video/x-vp8") GST_CAPS_CODEC("image/jpeg") ; @@ -631,6 +633,9 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps); break; #endif + case GST_VAAPI_CODEC_VP8: + decode->decoder = gst_vaapi_decoder_vp8_new(dpy, caps); + break; default: decode->decoder = NULL; break; From c9299bf18bd222cc7c54d381b196fd22254cff6d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 4 Apr 2014 19:17:17 +0200 Subject: [PATCH 1589/3781] vp8: fix check for disabling the loop filter. --- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index 40bf4db473..364fafb37f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -275,7 +275,7 @@ fill_picture (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture) GstVp8Parser *const parser = &priv->parser; GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr; GstVp8Segmentation *const seg = &parser->segmentation; - gint i; + gint i, filter_levels; /* Fill in VAPictureParameterBufferVP8 */ pic_param->frame_width = priv->width; @@ -329,11 +329,15 @@ fill_picture (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture) pic_param->loop_filter_deltas_mode[i] = parser->mb_lf_adjust.mb_mode_delta[i]; } - if ((pic_param->pic_fields.bits.version == 0) - || (pic_param->pic_fields.bits.version == 1)) { - pic_param->pic_fields.bits.loop_filter_disable = - pic_param->loop_filter_level[0] == 0; + + /* In decoding, the only loop filter settings that matter are those + in the frame header (9.1) */ + filter_levels = pic_param->loop_filter_level[0]; + if (seg->segmentation_enabled) { + for (i = 1; i < 4; i++) + filter_levels |= pic_param->loop_filter_level[i]; } + pic_param->pic_fields.bits.loop_filter_disable = filter_levels == 0; pic_param->prob_skip_false = frame_hdr->prob_skip_false; pic_param->prob_intra = frame_hdr->prob_intra; From b36eade7f3203630738fa44f00d415e805077dde Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Feb 2014 21:17:23 +0100 Subject: [PATCH 1590/3781] vp8: use range decoder from libvpx. Add libvpx submodule that tracks the upstream version 1.3.0. This is needed to build a libgstcodecparsers_vpx.so library with all symbols placed into the GSTREAMER namespace. --- .gitmodules | 3 + autogen.sh | 1 + configure.ac | 7 + ext/Makefile.am | 2 + ext/libvpx/Makefile.am | 141 +++++++++++ ext/libvpx/gstlibvpx.c | 119 +++++++++ ext/libvpx/gstlibvpx.h | 65 +++++ ext/libvpx/libgstcodecparsers_vpx.vers | 16 ++ ext/libvpx/sources.frag | 278 +++++++++++++++++++++ ext/libvpx/upstream | 1 + gst-libs/gst/codecparsers/Makefile.am | 21 +- gst-libs/gst/codecparsers/gstvaapilibvpx.c | 104 ++++++++ 12 files changed, 756 insertions(+), 2 deletions(-) create mode 100644 ext/libvpx/Makefile.am create mode 100644 ext/libvpx/gstlibvpx.c create mode 100644 ext/libvpx/gstlibvpx.h create mode 100644 ext/libvpx/libgstcodecparsers_vpx.vers create mode 100644 ext/libvpx/sources.frag create mode 160000 ext/libvpx/upstream create mode 100644 gst-libs/gst/codecparsers/gstvaapilibvpx.c diff --git a/.gitmodules b/.gitmodules index bad3c46dea..b4b4ef78dd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "ext/videoutils"] path = ext/videoutils url = git://gitorious.org/vaapi/gstreamer-videoutils.git +[submodule "ext/libvpx/upstream"] + path = ext/libvpx/upstream + url = https://chromium.googlesource.com/webm/libvpx diff --git a/autogen.sh b/autogen.sh index b4a63f367b..d7213afcac 100755 --- a/autogen.sh +++ b/autogen.sh @@ -26,6 +26,7 @@ else submodule_init="yes" fi done + [ -f ext/libvpx/upstream/configure ] || submodule_init="yes" if test "$submodule_init" = "yes"; then $GIT submodule init fi diff --git a/configure.ac b/configure.ac index 52d268d4ea..d6928f1e21 100644 --- a/configure.ac +++ b/configure.ac @@ -95,6 +95,12 @@ AC_ARG_VAR([GIT], [Path to git program, if any]) AC_PATH_PROG([GIT], [git]) AM_CONDITIONAL([HAVE_GIT], [test -n "$GIT"]) +AC_ARG_VAR([YASM], [Path to yasm program, if any]) +AC_PATH_PROG([YASM], [yasm]) +if test -z "$YASM"; then + AC_MSG_ERROR([yasm is needed to build libvpx sources]) +fi + dnl Initialize libtool LT_PREREQ([2.2]) LT_INIT @@ -834,6 +840,7 @@ debian.upstream/libgstvaapi-x11.install.in docs/reference/plugins/Makefile docs/reference/plugins/plugins-docs.xml ext/Makefile + ext/libvpx/Makefile gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/base/Makefile diff --git a/ext/Makefile.am b/ext/Makefile.am index 62f3ec4cb0..9c20bcdcc5 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = libvpx + EXTRA_DIST = codecparsers_srcdir = \ diff --git a/ext/libvpx/Makefile.am b/ext/libvpx/Makefile.am new file mode 100644 index 0000000000..9211a2117e --- /dev/null +++ b/ext/libvpx/Makefile.am @@ -0,0 +1,141 @@ +# Makefile.am - Rules for the built-in libvpx sources +# +# INTEL CONFIDENTIAL, FOR INTERNAL USE ONLY +# Copyright (C) 2014 Intel Corporation +# Author: Gwenole Beauchesne +# +# @BEGIN_LICENSE@ +# The source code contained or described herein and all documents +# related to the source code ("Material") are owned by Intel +# Corporation or its suppliers or licensors. Title to the Material +# remains with Intel Corporation or its suppliers and licensors. The +# Material contains trade secrets and proprietary and confidential +# information of Intel or its suppliers and licensors. The Material +# is protected by worldwide copyright and trade secret laws and +# treaty provisions. No part of the Material may be used, copied, +# reproduced, modified, published, uploaded, posted, transmitted, +# distributed, or disclosed in any way without Intel’s prior express +# written permission. +# +# No license under any patent, copyright, trade secret or other +# intellectual property right is granted to or conferred upon you by +# disclosure or delivery of the Materials, either expressly, by +# implication, inducement, estoppel or otherwise. Any license under +# such intellectual property rights must be express and approved by +# Intel in writing. +# @END_LICENSE@ + +lib_LTLIBRARIES = +if USE_LOCAL_CODEC_PARSERS_VP8 +lib_LTLIBRARIES += libgstcodecparsers_vpx.la +endif + +gst_vpx_source_c = gstlibvpx.c +gst_vpx_source_h = gstlibvpx.h + +vpx_upstream = upstream +vpx_srcdir = $(srcdir)/$(vpx_upstream) +vpx_builddir = $(builddir)/$(vpx_upstream) +vpx_versions = libgstcodecparsers_vpx.vers + +vpx_cflags = \ + -I$(vpx_srcdir) \ + -I$(vpx_builddir) \ + $(NULL) + +vpx_libs = \ + -Wl,-Bsymbolic \ + -Wl,--whole-archive \ + -Wl,$(vpx_builddir)/libvpx.a \ + -Wl,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/$(vpx_versions) \ + -Wl,-lpthread \ + -Wl,-lm \ + $(NULL) + +libgstcodecparsers_vpx_la_SOURCES = $(gst_vpx_source_c) +libgstcodecparsers_vpx_la_CFLAGS = $(vpx_cflags) +libgstcodecparsers_vpx_la_DEPENDENCIES = vpx.build +libgstcodecparsers_vpx_la_LINK = $(LINK) $(vpx_libs) +EXTRA_libgstcodecparsers_vpx_la_DEPENDENCIES = $(srcdir)/$(vpx_versions) + +VPX_DEBUG = yes + +# Codecs +VP8_DECODER = enable +VP8_ENCODER = disable +VP9_DECODER = disable +VP9_ENCODER = disable + +clean-local: vpx.clean +maintainer-clean-local: vpx.maintainer.clean + +vpx.build: vpx.configure.stamp + @$(MAKE) -C $(vpx_builddir) + +vpx.clean: + @[ -d $(vpx_builddir) ] && \ + $(MAKE) -C $(vpx_builddir) clean || : + rm -f vpx.build.stamp vpx.configure.stamp + +vpx.maintainer.clean: vpx.clean + rm -rf $(vpx_builddir) + +vpx.configure.stamp: + @[ -d $(vpx_builddir) ] || mkdir $(vpx_builddir); \ + cd $(vpx_builddir) ; \ + test "$(VPX_DEBUG)" = "yes" && \ + CONFIGURE_FLAGS="$$CONFIGURE_FLAGS --enable-debug" ; \ + $(abs_srcdir)/$(vpx_upstream)/configure $$CONFIGURE_FLAGS \ + --enable-static \ + --enable-pic \ + --disable-shared \ + --$(VP8_DECODER)-vp8-decoder \ + --$(VP8_ENCODER)-vp8-encoder \ + --$(VP9_DECODER)-vp9-decoder \ + --$(VP9_ENCODER)-vp9-encoder \ + --enable-runtime-cpu-detect \ + --disable-md5 \ + --disable-examples \ + --disable-docs \ + --disable-unit-tests && \ + cd .. && \ + touch $@ + +CLEANFILES = vpx.build.stamp + +# Files for packaging +include $(srcdir)/sources.frag + +vpx_sources = \ + $(vpx_srcdir)/AUTHORS \ + $(vpx_srcdir)/CHANGELOG \ + $(vpx_srcdir)/LICENSE \ + $(vpx_srcdir)/PATENTS \ + $(vpx_srcdir)/build/make/Makefile \ + $(vpx_srcdir)/build/make/ads2gas.pl \ + $(vpx_srcdir)/build/make/ads2gas_apple.pl \ + $(vpx_srcdir)/build/make/configure.sh \ + $(vpx_srcdir)/build/make/gen_asm_deps.sh \ + $(vpx_srcdir)/build/make/obj_int_extract.c \ + $(vpx_srcdir)/build/make/rtcd.sh \ + $(vpx_srcdir)/build/make/version.sh \ + $(vpx_srcdir)/configure \ + $(vpx_srcdir)/vp8/common/rtcd_defs.sh \ + $(vpx_srcdir)/vp9/common/vp9_rtcd_defs.sh \ + $(vpx_srcdir)/vpx_scale/vpx_scale_rtcd.sh \ + $(vpx_source_mak:%.mk=$(vpx_srcdir)/%.mk) \ + $(vpx_source_c:%.c=$(vpx_srcdir)/%.c) \ + $(vpx_source_h:%.h=$(vpx_srcdir)/%.h) \ + $(vpx_source_asm:%.asm=$(vpx_srcdir)/%.asm) \ + $(NULL) + +EXTRA_DIST = \ + sources.frag \ + $(gst_vpx_source_h) \ + $(vpx_sources) \ + $(vpx_versions) \ + $(NULL) + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in vpx.configure.stamp diff --git a/ext/libvpx/gstlibvpx.c b/ext/libvpx/gstlibvpx.c new file mode 100644 index 0000000000..fc376e12ca --- /dev/null +++ b/ext/libvpx/gstlibvpx.c @@ -0,0 +1,119 @@ +/* + * gstlibvpx.c - GStreamer/libvpx glue + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include +#include +#include +#include +#include +#include +#include "gstlibvpx.h" + +#define BOOL_DECODER_CAST(bd) \ + ((BOOL_DECODER *)(&(bd)->private[1])) + +bool +vp8_bool_decoder_init (vp8_bool_decoder * bd, const uint8_t * buf, + unsigned int buf_size) +{ + assert ((sizeof (*bd) - sizeof (bd->private[0])) >= sizeof (BOOL_DECODER)); + + bd->private[0] = (uintptr_t)buf; + return vp8dx_start_decode (BOOL_DECODER_CAST (bd), buf, buf_size, + NULL, NULL) == 0; +} + +int +vp8_bool_decoder_read (vp8_bool_decoder * bd, uint8_t prob) +{ + return vp8dx_decode_bool (BOOL_DECODER_CAST (bd), prob); +} + +int +vp8_bool_decoder_read_literal (vp8_bool_decoder * bd, int bits) +{ + return vp8_decode_value (BOOL_DECODER_CAST (bd), bits); +} + +unsigned int +vp8_bool_decoder_get_pos (vp8_bool_decoder * bd_) +{ + BOOL_DECODER *const bd = BOOL_DECODER_CAST (bd_); + + return ((uintptr_t)bd->user_buffer - bd_->private[0]) * 8 - (8 + bd->count); +} + +void +vp8_bool_decoder_get_state (vp8_bool_decoder * bd_, + vp8_bool_decoder_state * state) +{ + BOOL_DECODER *const bd = BOOL_DECODER_CAST (bd_); + + if (bd->count < 0) + vp8dx_bool_decoder_fill (bd); + + state->range = bd->range; + state->value = (uint8_t) ((bd->value) >> (VP8_BD_VALUE_SIZE - 8)); + state->count = (8 + bd->count) % 8; +} + +void +vp8_init_token_update_probs (uint8_t + probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]) +{ + memcpy (probs, vp8_coef_update_probs, sizeof (vp8_coef_update_probs)); +} + +void +vp8_init_default_token_probs (uint8_t + probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]) +{ + memcpy (probs, default_coef_probs, sizeof (default_coef_probs)); +} + +void +vp8_init_mv_update_probs (uint8_t probs[2][MVPcount]) +{ + memcpy (probs[0], vp8_mv_update_probs[0].prob, + sizeof (vp8_mv_update_probs[0].prob)); + memcpy (probs[1], vp8_mv_update_probs[1].prob, + sizeof (vp8_mv_update_probs[1].prob)); +} + +void +vp8_init_default_mv_probs (uint8_t probs[2][MVPcount]) +{ + memcpy (probs[0], vp8_default_mv_context[0].prob, + sizeof (vp8_default_mv_context[0].prob)); + memcpy (probs[1], vp8_default_mv_context[1].prob, + sizeof (vp8_default_mv_context[1].prob)); +} + +void +vp8_init_default_intra_mode_probs (uint8_t y_probs[VP8_YMODES-1], + uint8_t uv_probs[VP8_UV_MODES-1]) +{ + extern const uint8_t vp8_kf_ymode_prob[VP8_YMODES-1]; + extern const uint8_t vp8_kf_uv_mode_prob[VP8_UV_MODES-1]; + + memcpy (y_probs, vp8_kf_ymode_prob, sizeof (vp8_kf_ymode_prob)); + memcpy (uv_probs, vp8_kf_uv_mode_prob, sizeof (vp8_kf_uv_mode_prob)); +} + +void +vp8_init_default_inter_mode_probs (uint8_t y_probs[VP8_YMODES-1], + uint8_t uv_probs[VP8_UV_MODES-1]) +{ + extern const uint8_t vp8_ymode_prob[VP8_YMODES-1]; + extern const uint8_t vp8_uv_mode_prob[VP8_UV_MODES-1]; + + memcpy (y_probs, vp8_ymode_prob, sizeof (vp8_ymode_prob)); + memcpy (uv_probs, vp8_uv_mode_prob, sizeof (vp8_uv_mode_prob)); +} diff --git a/ext/libvpx/gstlibvpx.h b/ext/libvpx/gstlibvpx.h new file mode 100644 index 0000000000..d4bd7845aa --- /dev/null +++ b/ext/libvpx/gstlibvpx.h @@ -0,0 +1,65 @@ +/* + * gstlibvpx.h - GStreamer/libvpx glue + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef GST_LIBVPX_H +#define GST_LIBVPX_H + +#include +#include + +typedef struct _vp8_bool_decoder vp8_bool_decoder; +typedef struct _vp8_bool_decoder_state vp8_bool_decoder_state; + +struct _vp8_bool_decoder { + uintptr_t private[16]; +}; + +struct _vp8_bool_decoder_state { + uint8_t range; /* Current "range" value (<= 255) */ + uint8_t value; /* Current "value" value */ + uint8_t count; /* Number of bits shifted out of value (<= 7) */ +}; + +bool +vp8_bool_decoder_init (vp8_bool_decoder * bd, const uint8_t * buf, + unsigned int buf_size); + +int +vp8_bool_decoder_read (vp8_bool_decoder * bd, uint8_t prob); + +int +vp8_bool_decoder_read_literal (vp8_bool_decoder * bd, int bits); + +unsigned int +vp8_bool_decoder_get_pos (vp8_bool_decoder * bd); + +void +vp8_bool_decoder_get_state (vp8_bool_decoder * bd, + vp8_bool_decoder_state * state); + +void +vp8_init_token_update_probs (uint8_t probs[4][8][3][11]); + +void +vp8_init_default_token_probs (uint8_t probs[4][8][3][11]); + +void +vp8_init_mv_update_probs (uint8_t probs[2][19]); + +void +vp8_init_default_mv_probs (uint8_t probs[2][19]); + +void +vp8_init_default_intra_mode_probs (uint8_t y_probs[4], uint8_t uv_probs[3]); + +void +vp8_init_default_inter_mode_probs (uint8_t y_probs[4], uint8_t uv_probs[3]); + +#endif /* GST_LIBVPX_H */ diff --git a/ext/libvpx/libgstcodecparsers_vpx.vers b/ext/libvpx/libgstcodecparsers_vpx.vers new file mode 100644 index 0000000000..6c178e72b9 --- /dev/null +++ b/ext/libvpx/libgstcodecparsers_vpx.vers @@ -0,0 +1,16 @@ +GSTREAMER { +global: + vp8_bool_decoder_init; + vp8_bool_decoder_read; + vp8_bool_decoder_read_literal; + vp8_bool_decoder_get_pos; + vp8_bool_decoder_get_state; + vp8_init_token_update_probs; + vp8_init_default_token_probs; + vp8_init_mv_update_probs; + vp8_init_default_mv_probs; + vp8_init_default_intra_mode_probs; + vp8_init_default_inter_mode_probs; +local: + *; +}; diff --git a/ext/libvpx/sources.frag b/ext/libvpx/sources.frag new file mode 100644 index 0000000000..d96f6d286f --- /dev/null +++ b/ext/libvpx/sources.frag @@ -0,0 +1,278 @@ +# sources.frag - Generated list of source files for libvpx (-*- makefile -*-) +# +# INTEL CONFIDENTIAL, FOR INTERNAL USE ONLY +# Copyright (C) 2014 Intel Corporation +# Author: Gwenole Beauchesne +# +# @BEGIN_LICENSE@ +# The source code contained or described herein and all documents +# related to the source code ("Material") are owned by Intel +# Corporation or its suppliers or licensors. Title to the Material +# remains with Intel Corporation or its suppliers and licensors. The +# Material contains trade secrets and proprietary and confidential +# information of Intel or its suppliers and licensors. The Material +# is protected by worldwide copyright and trade secret laws and +# treaty provisions. No part of the Material may be used, copied, +# reproduced, modified, published, uploaded, posted, transmitted, +# distributed, or disclosed in any way without Intel’s prior express +# written permission. +# +# No license under any patent, copyright, trade secret or other +# intellectual property right is granted to or conferred upon you by +# disclosure or delivery of the Materials, either expressly, by +# implication, inducement, estoppel or otherwise. Any license under +# such intellectual property rights must be express and approved by +# Intel in writing. +# @END_LICENSE@ + +vpx_source_mak = \ + docs.mk \ + examples.mk \ + libs.mk \ + solution.mk \ + test/test.mk \ + vp8/vp8_common.mk \ + vp8/vp8cx.mk \ + vp8/vp8cx_arm.mk \ + vp8/vp8dx.mk \ + vp9/vp9_common.mk \ + vp9/vp9cx.mk \ + vp9/vp9dx.mk \ + vpx/vpx_codec.mk \ + vpx_mem/vpx_mem.mk \ + vpx_ports/vpx_ports.mk \ + vpx_scale/vpx_scale.mk \ + $(NULL) + +vpx_source_c = \ + vp8/common/alloccommon.c \ + vp8/common/blockd.c \ + vp8/common/debugmodes.c \ + vp8/common/dequantize.c \ + vp8/common/entropy.c \ + vp8/common/entropymode.c \ + vp8/common/entropymv.c \ + vp8/common/extend.c \ + vp8/common/filter.c \ + vp8/common/findnearmv.c \ + vp8/common/generic/systemdependent.c \ + vp8/common/idct_blk.c \ + vp8/common/idctllm.c \ + vp8/common/loopfilter.c \ + vp8/common/loopfilter_filters.c \ + vp8/common/mbpitch.c \ + vp8/common/mfqe.c \ + vp8/common/modecont.c \ + vp8/common/postproc.c \ + vp8/common/quant_common.c \ + vp8/common/reconinter.c \ + vp8/common/reconintra.c \ + vp8/common/reconintra4x4.c \ + vp8/common/rtcd.c \ + vp8/common/sad_c.c \ + vp8/common/setupintrarecon.c \ + vp8/common/swapyv12buffer.c \ + vp8/common/treecoder.c \ + vp8/common/variance_c.c \ + vp8/common/x86/filter_x86.c \ + vp8/common/x86/idct_blk_mmx.c \ + vp8/common/x86/idct_blk_sse2.c \ + vp8/common/x86/loopfilter_x86.c \ + vp8/common/x86/postproc_x86.c \ + vp8/common/x86/recon_wrapper_sse2.c \ + vp8/common/x86/variance_mmx.c \ + vp8/common/x86/variance_sse2.c \ + vp8/common/x86/variance_ssse3.c \ + vp8/common/x86/vp8_asm_stubs.c \ + vp8/decoder/dboolhuff.c \ + vp8/decoder/decodemv.c \ + vp8/decoder/decodframe.c \ + vp8/decoder/detokenize.c \ + vp8/decoder/onyxd_if.c \ + vp8/decoder/threading.c \ + vp8/vp8_dx_iface.c \ + vp9/common/generic/vp9_systemdependent.c \ + vp9/common/vp9_alloccommon.c \ + vp9/common/vp9_common_data.c \ + vp9/common/vp9_convolve.c \ + vp9/common/vp9_debugmodes.c \ + vp9/common/vp9_entropy.c \ + vp9/common/vp9_entropymode.c \ + vp9/common/vp9_entropymv.c \ + vp9/common/vp9_extend.c \ + vp9/common/vp9_filter.c \ + vp9/common/vp9_findnearmv.c \ + vp9/common/vp9_idct.c \ + vp9/common/vp9_loopfilter.c \ + vp9/common/vp9_loopfilter_filters.c \ + vp9/common/vp9_mvref_common.c \ + vp9/common/vp9_pred_common.c \ + vp9/common/vp9_quant_common.c \ + vp9/common/vp9_reconinter.c \ + vp9/common/vp9_reconintra.c \ + vp9/common/vp9_rtcd.c \ + vp9/common/vp9_scale.c \ + vp9/common/vp9_scan.c \ + vp9/common/vp9_seg_common.c \ + vp9/common/vp9_tile_common.c \ + vp9/common/vp9_treecoder.c \ + vp9/common/x86/vp9_asm_stubs.c \ + vp9/common/x86/vp9_idct_intrin_sse2.c \ + vp9/common/x86/vp9_loopfilter_intrin_sse2.c \ + vp9/decoder/vp9_dboolhuff.c \ + vp9/decoder/vp9_decodemv.c \ + vp9/decoder/vp9_decodframe.c \ + vp9/decoder/vp9_detokenize.c \ + vp9/decoder/vp9_dsubexp.c \ + vp9/decoder/vp9_onyxd_if.c \ + vp9/decoder/vp9_thread.c \ + vp9/vp9_dx_iface.c \ + vpx/src/vpx_codec.c \ + vpx/src/vpx_decoder.c \ + vpx/src/vpx_encoder.c \ + vpx/src/vpx_image.c \ + vpx_mem/vpx_mem.c \ + vpx_ports/x86_cpuid.c \ + vpx_scale/generic/gen_scalers.c \ + vpx_scale/generic/vpx_scale.c \ + vpx_scale/generic/yv12config.c \ + vpx_scale/generic/yv12extend.c \ + vpx_scale/vpx_scale_asm_offsets.c \ + vpx_scale/vpx_scale_rtcd.c \ + $(NULL) + +vpx_source_h = \ + vp8/common/alloccommon.h \ + vp8/common/blockd.h \ + vp8/common/coefupdateprobs.h \ + vp8/common/common.h \ + vp8/common/default_coef_probs.h \ + vp8/common/entropy.h \ + vp8/common/entropymode.h \ + vp8/common/entropymv.h \ + vp8/common/extend.h \ + vp8/common/filter.h \ + vp8/common/findnearmv.h \ + vp8/common/header.h \ + vp8/common/invtrans.h \ + vp8/common/loopfilter.h \ + vp8/common/modecont.h \ + vp8/common/mv.h \ + vp8/common/onyxc_int.h \ + vp8/common/onyxd.h \ + vp8/common/postproc.h \ + vp8/common/ppflags.h \ + vp8/common/pragmas.h \ + vp8/common/quant_common.h \ + vp8/common/reconinter.h \ + vp8/common/reconintra4x4.h \ + vp8/common/setupintrarecon.h \ + vp8/common/swapyv12buffer.h \ + vp8/common/systemdependent.h \ + vp8/common/threading.h \ + vp8/common/treecoder.h \ + vp8/common/variance.h \ + vp8/common/vp8_entropymodedata.h \ + vp8/common/x86/filter_x86.h \ + vp8/decoder/dboolhuff.h \ + vp8/decoder/decodemv.h \ + vp8/decoder/decoderthreading.h \ + vp8/decoder/detokenize.h \ + vp8/decoder/onyxd_int.h \ + vp8/decoder/treereader.h \ + vp9/common/vp9_alloccommon.h \ + vp9/common/vp9_blockd.h \ + vp9/common/vp9_common.h \ + vp9/common/vp9_common_data.h \ + vp9/common/vp9_convolve.h \ + vp9/common/vp9_default_coef_probs.h \ + vp9/common/vp9_entropy.h \ + vp9/common/vp9_entropymode.h \ + vp9/common/vp9_entropymv.h \ + vp9/common/vp9_enums.h \ + vp9/common/vp9_extend.h \ + vp9/common/vp9_filter.h \ + vp9/common/vp9_findnearmv.h \ + vp9/common/vp9_idct.h \ + vp9/common/vp9_loopfilter.h \ + vp9/common/vp9_mv.h \ + vp9/common/vp9_mvref_common.h \ + vp9/common/vp9_onyxc_int.h \ + vp9/common/vp9_ppflags.h \ + vp9/common/vp9_pred_common.h \ + vp9/common/vp9_quant_common.h \ + vp9/common/vp9_reconinter.h \ + vp9/common/vp9_reconintra.h \ + vp9/common/vp9_scale.h \ + vp9/common/vp9_scan.h \ + vp9/common/vp9_seg_common.h \ + vp9/common/vp9_systemdependent.h \ + vp9/common/vp9_tile_common.h \ + vp9/common/vp9_treecoder.h \ + vp9/decoder/vp9_dboolhuff.h \ + vp9/decoder/vp9_decodemv.h \ + vp9/decoder/vp9_decodframe.h \ + vp9/decoder/vp9_detokenize.h \ + vp9/decoder/vp9_dsubexp.h \ + vp9/decoder/vp9_onyxd.h \ + vp9/decoder/vp9_onyxd_int.h \ + vp9/decoder/vp9_read_bit_buffer.h \ + vp9/decoder/vp9_thread.h \ + vp9/decoder/vp9_thread.h \ + vp9/decoder/vp9_treereader.h \ + vp9/vp9_iface_common.h \ + vpx/internal/vpx_codec_internal.h \ + vpx/vp8.h \ + vpx/vp8dx.h \ + vpx/vpx_codec.h \ + vpx/vpx_decoder.h \ + vpx/vpx_encoder.h \ + vpx/vpx_image.h \ + vpx/vpx_integer.h \ + vpx_mem/include/vpx_mem_intrnl.h \ + vpx_mem/vpx_mem.h \ + vpx_ports/asm_offsets.h \ + vpx_ports/emmintrin_compat.h \ + vpx_ports/mem.h \ + vpx_ports/vpx_once.h \ + vpx_ports/vpx_timer.h \ + vpx_ports/x86.h \ + vpx_scale/vpx_scale.h \ + vpx_scale/yv12config.h \ + $(NULL) + +vpx_source_asm = \ + third_party/x86inc/x86inc.asm \ + vp8/common/x86/dequantize_mmx.asm \ + vp8/common/x86/idctllm_mmx.asm \ + vp8/common/x86/idctllm_sse2.asm \ + vp8/common/x86/iwalsh_mmx.asm \ + vp8/common/x86/iwalsh_sse2.asm \ + vp8/common/x86/loopfilter_block_sse2.asm \ + vp8/common/x86/loopfilter_mmx.asm \ + vp8/common/x86/loopfilter_sse2.asm \ + vp8/common/x86/mfqe_sse2.asm \ + vp8/common/x86/postproc_mmx.asm \ + vp8/common/x86/postproc_sse2.asm \ + vp8/common/x86/recon_mmx.asm \ + vp8/common/x86/recon_sse2.asm \ + vp8/common/x86/sad_mmx.asm \ + vp8/common/x86/sad_sse2.asm \ + vp8/common/x86/sad_sse3.asm \ + vp8/common/x86/sad_sse4.asm \ + vp8/common/x86/sad_ssse3.asm \ + vp8/common/x86/subpixel_mmx.asm \ + vp8/common/x86/subpixel_sse2.asm \ + vp8/common/x86/subpixel_ssse3.asm \ + vp8/common/x86/variance_impl_mmx.asm \ + vp8/common/x86/variance_impl_sse2.asm \ + vp8/common/x86/variance_impl_ssse3.asm \ + vp9/common/x86/vp9_copy_sse2.asm \ + vp9/common/x86/vp9_intrapred_sse2.asm \ + vp9/common/x86/vp9_intrapred_ssse3.asm \ + vp9/common/x86/vp9_loopfilter_mmx.asm \ + vp9/common/x86/vp9_subpixel_8t_sse2.asm \ + vp9/common/x86/vp9_subpixel_8t_ssse3.asm \ + vpx_ports/emms.asm \ + vpx_ports/x86_abi_support.asm \ + $(NULL) diff --git a/ext/libvpx/upstream b/ext/libvpx/upstream new file mode 160000 index 0000000000..2e88f2f2ec --- /dev/null +++ b/ext/libvpx/upstream @@ -0,0 +1 @@ +Subproject commit 2e88f2f2ec777259bda1714e72f1ecd2519bceb5 diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 3d414d9514..ece46eff50 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -18,6 +18,8 @@ libgstvaapi_codecparsers_libs = \ $(GST_LIBS) \ $(NULL) +add_source_c = +add_source_h = gen_source_c = parserutils.c nalutils.c gen_source_h = parserutils.h nalutils.h @@ -43,9 +45,17 @@ endif if USE_LOCAL_CODEC_PARSERS_VP8 gen_source_c += gstvp8parser.c gen_source_h += gstvp8parser.h gstvp8rangedecoder.h vp8utils.h +#gen_source_c += dboolhuff.c gstvp8rangedecoder.c vp8utils.c +#gen_source_h += dboolhuff.h +add_source_c += gstvaapilibvpx.c -gen_source_c += dboolhuff.c gstvp8rangedecoder.c vp8utils.c -gen_source_h += dboolhuff.h +libgstvaapi_codecparsers_cflags += \ + -I$(top_srcdir)/ext/libvpx \ + -I$(top_srcdir)/ext/libvpx/upstream \ + -I$(top_builddir)/ext/libvpx/upstream + +libgstvaapi_codecparsers_libs += \ + $(top_builddir)/ext/libvpx/libgstcodecparsers_vpx.la endif GENFILES = \ @@ -57,6 +67,7 @@ nodist_EXTRA_libgstvaapi_codecparsers_la_SOURCES = dummy.c nodist_libgstvaapi_codecparsers_la_SOURCES = \ $(gen_source_c) \ + $(add_source_c) \ $(NULL) libgstvaapi_codecparsers_la_CFLAGS = \ @@ -80,6 +91,12 @@ $(gen_source_c): %.c: $(local_codecparsers_srcdir)/%.c $(gen_source_h) $(LN_S) -f $< $@ $(gen_source_h): %.h: $(local_codecparsers_srcdir)/%.h $(LN_S) -f $< $@ +$(top_builddir)/ext/libvpx/libgstcodecparsers_vpx.la: + $(MAKE) -C $(top_builddir)/ext/libvpx + +EXTRA_DIST = \ + $(add_source_c) \ + $(NULL) DISTCLEANFILES = $(GENFILES) .timestamp.symlinks diff --git a/gst-libs/gst/codecparsers/gstvaapilibvpx.c b/gst-libs/gst/codecparsers/gstvaapilibvpx.c new file mode 100644 index 0000000000..81baeb048a --- /dev/null +++ b/gst-libs/gst/codecparsers/gstvaapilibvpx.c @@ -0,0 +1,104 @@ +/* + * gstvaapilibvpx.c - libvpx wrapper for gstreamer-vaapi + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "gstvp8rangedecoder.h" +#include "vp8utils.h" +#include "gstlibvpx.h" + +#define BOOL_DECODER_CAST(rd) \ + ((vp8_bool_decoder *)(&(rd)->_gst_reserved[0])) + +#define BOOL_DECODER_STATE_CAST(s) \ + ((vp8_bool_decoder_state *)(s)) + +gboolean +gst_vp8_range_decoder_init (GstVp8RangeDecoder * rd, const guchar * buf, + guint buf_size) +{ + vp8_bool_decoder *const bd = BOOL_DECODER_CAST (rd); + + g_return_val_if_fail (sizeof (rd->_gst_reserved) >= sizeof (*bd), FALSE); + + rd->buf = buf; + rd->buf_size = buf_size; + return vp8_bool_decoder_init (bd, buf, buf_size); +} + +gint +gst_vp8_range_decoder_read (GstVp8RangeDecoder * rd, guint8 prob) +{ + return vp8_bool_decoder_read (BOOL_DECODER_CAST (rd), prob); +} + +gint +gst_vp8_range_decoder_read_literal (GstVp8RangeDecoder * rd, gint bits) +{ + return vp8_bool_decoder_read_literal (BOOL_DECODER_CAST (rd), bits); +} + +guint +gst_vp8_range_decoder_get_pos (GstVp8RangeDecoder * rd) +{ + return vp8_bool_decoder_get_pos (BOOL_DECODER_CAST (rd)); +} + +void +gst_vp8_range_decoder_get_state (GstVp8RangeDecoder * rd, + GstVp8RangeDecoderState * state) +{ + vp8_bool_decoder_get_state (BOOL_DECODER_CAST (rd), + BOOL_DECODER_STATE_CAST (state)); +} + +void +gst_vp8_token_update_probs_init (GstVp8TokenProbs * probs) +{ + vp8_init_token_update_probs (probs->prob); +} + +void +gst_vp8_token_probs_init_defaults (GstVp8TokenProbs * probs) +{ + vp8_init_default_token_probs (probs->prob); +} + +void +gst_vp8_mv_update_probs_init (GstVp8MvProbs * probs) +{ + vp8_init_mv_update_probs (probs->prob); +} + +void +gst_vp8_mv_probs_init_defaults (GstVp8MvProbs * probs) +{ + vp8_init_default_mv_probs (probs->prob); +} + +void +gst_vp8_mode_probs_init_defaults (GstVp8ModeProbs * probs, gboolean key_frame) +{ + if (key_frame) { + vp8_init_default_intra_mode_probs (probs->y_prob, probs->uv_prob); + } else { + vp8_init_default_inter_mode_probs (probs->y_prob, probs->uv_prob); + } +} From 1ceef7d5b992585c8fee82d76336e3bff321ead5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 19 Apr 2014 07:49:30 +0200 Subject: [PATCH 1591/3781] vp8: fix compilation with built-in libvpx. Apply correct patch from fd.o #722760 to fix several issues: update the license terms to LGPLv2.1+, fix dependencies to built-in libvpx and fix make dist. --- Makefile.am | 2 +- debian.upstream/libgstvaapi.install.in | 1 + ext/libvpx/Makefile.am | 43 +++++++++++++------------- ext/libvpx/sources.frag | 33 ++++++++------------ gst-libs/gst/codecparsers/Makefile.am | 1 + 5 files changed, 38 insertions(+), 42 deletions(-) diff --git a/Makefile.am b/Makefile.am index 70cb5eea90..1d08eba0e7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} AUTOMAKE_OPTIONS = foreign -SUBDIRS = debian.upstream gst-libs gst pkgconfig tests docs ext +SUBDIRS = debian.upstream ext gst-libs gst pkgconfig tests docs # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ diff --git a/debian.upstream/libgstvaapi.install.in b/debian.upstream/libgstvaapi.install.in index f719a6f347..afb5221421 100644 --- a/debian.upstream/libgstvaapi.install.in +++ b/debian.upstream/libgstvaapi.install.in @@ -1 +1,2 @@ +debian/tmp/usr/lib/libgstcodecparsers_vpx.so.* debian/tmp/usr/lib/libgstvaapi-@GST_API_VERSION@.so.* diff --git a/ext/libvpx/Makefile.am b/ext/libvpx/Makefile.am index 9211a2117e..4f54b93c15 100644 --- a/ext/libvpx/Makefile.am +++ b/ext/libvpx/Makefile.am @@ -1,29 +1,22 @@ # Makefile.am - Rules for the built-in libvpx sources # -# INTEL CONFIDENTIAL, FOR INTERNAL USE ONLY # Copyright (C) 2014 Intel Corporation # Author: Gwenole Beauchesne # -# @BEGIN_LICENSE@ -# The source code contained or described herein and all documents -# related to the source code ("Material") are owned by Intel -# Corporation or its suppliers or licensors. Title to the Material -# remains with Intel Corporation or its suppliers and licensors. The -# Material contains trade secrets and proprietary and confidential -# information of Intel or its suppliers and licensors. The Material -# is protected by worldwide copyright and trade secret laws and -# treaty provisions. No part of the Material may be used, copied, -# reproduced, modified, published, uploaded, posted, transmitted, -# distributed, or disclosed in any way without Intel’s prior express -# written permission. +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. # -# No license under any patent, copyright, trade secret or other -# intellectual property right is granted to or conferred upon you by -# disclosure or delivery of the Materials, either expressly, by -# implication, inducement, estoppel or otherwise. Any license under -# such intellectual property rights must be express and approved by -# Intel in writing. -# @END_LICENSE@ +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301, USA. lib_LTLIBRARIES = if USE_LOCAL_CODEC_PARSERS_VP8 @@ -102,6 +95,8 @@ vpx.configure.stamp: cd .. && \ touch $@ +$(gst_vpx_source_c): vpx.build + CLEANFILES = vpx.build.stamp # Files for packaging @@ -127,7 +122,6 @@ vpx_sources = \ $(vpx_source_mak:%.mk=$(vpx_srcdir)/%.mk) \ $(vpx_source_c:%.c=$(vpx_srcdir)/%.c) \ $(vpx_source_h:%.h=$(vpx_srcdir)/%.h) \ - $(vpx_source_asm:%.asm=$(vpx_srcdir)/%.asm) \ $(NULL) EXTRA_DIST = \ @@ -137,5 +131,12 @@ EXTRA_DIST = \ $(vpx_versions) \ $(NULL) +# Avoid implicit rule that tries to compile .asm.o to .asm +dist-hook: + for f in $(vpx_source_asm); do \ + mkdir -p $(distdir)/$(vpx_upstream)/$$(dirname $$f); \ + cp -fpR $(vpx_srcdir)/$$f $(distdir)/$(vpx_upstream)/$$f; \ + done + # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in vpx.configure.stamp diff --git a/ext/libvpx/sources.frag b/ext/libvpx/sources.frag index d96f6d286f..02eb45d381 100644 --- a/ext/libvpx/sources.frag +++ b/ext/libvpx/sources.frag @@ -1,29 +1,22 @@ # sources.frag - Generated list of source files for libvpx (-*- makefile -*-) # -# INTEL CONFIDENTIAL, FOR INTERNAL USE ONLY # Copyright (C) 2014 Intel Corporation # Author: Gwenole Beauchesne # -# @BEGIN_LICENSE@ -# The source code contained or described herein and all documents -# related to the source code ("Material") are owned by Intel -# Corporation or its suppliers or licensors. Title to the Material -# remains with Intel Corporation or its suppliers and licensors. The -# Material contains trade secrets and proprietary and confidential -# information of Intel or its suppliers and licensors. The Material -# is protected by worldwide copyright and trade secret laws and -# treaty provisions. No part of the Material may be used, copied, -# reproduced, modified, published, uploaded, posted, transmitted, -# distributed, or disclosed in any way without Intel’s prior express -# written permission. +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. # -# No license under any patent, copyright, trade secret or other -# intellectual property right is granted to or conferred upon you by -# disclosure or delivery of the Materials, either expressly, by -# implication, inducement, estoppel or otherwise. Any license under -# such intellectual property rights must be express and approved by -# Intel in writing. -# @END_LICENSE@ +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301, USA. vpx_source_mak = \ docs.mk \ diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index ece46eff50..d7c9dd8305 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -96,6 +96,7 @@ $(top_builddir)/ext/libvpx/libgstcodecparsers_vpx.la: EXTRA_DIST = \ $(add_source_c) \ + $(add_source_h) \ $(NULL) DISTCLEANFILES = $(GENFILES) .timestamp.symlinks From 746ac17f59f12c48534ea0d135f50d36683706c7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 21 Apr 2014 17:28:27 +0200 Subject: [PATCH 1592/3781] vp8: propagate PTS from demux frame. gst_adapter_prev_pts() is forbidden within libgstvaapi. Besides, the demuxer or parser would already have determined the PTS from a previous stage. --- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index 364fafb37f..07816de46c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -57,7 +57,6 @@ struct _GstVaapiDecoderVp8Private GstVaapiPicture *golden_ref_picture; GstVaapiPicture *alt_ref_picture; GstVaapiPicture *current_picture; - GstClockTime pts; guint size_changed:1; }; @@ -143,7 +142,6 @@ gst_vaapi_decoder_vp8_create (GstVaapiDecoder * base_decoder) return FALSE; priv->profile = GST_VAAPI_PROFILE_UNKNOWN; - priv->pts = GST_CLOCK_TIME_NONE; return TRUE; } @@ -261,7 +259,7 @@ init_picture (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture) 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 = priv->pts; + 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); @@ -547,11 +545,8 @@ static GstVaapiDecoderStatus gst_vaapi_decoder_vp8_parse (GstVaapiDecoder * base_decoder, GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderVp8 *const decoder = GST_VAAPI_DECODER_VP8_CAST (base_decoder); - GstVaapiDecoderVp8Private *const priv = &decoder->priv; guint flags = 0; - priv->pts = gst_adapter_prev_pts (adapter, NULL); unit->size = gst_adapter_available (adapter); /* The whole frame is available */ From de6a9800658c17c0921a1f7cdd6e1e4f00150b5a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 21 Apr 2014 17:49:38 +0200 Subject: [PATCH 1593/3781] vp8: allow compilation without the built-in libvpx. The built-in libvpx serves multiple purposes, among which the most important ones could be: track the most up-to-date, and optimized, range decoder; allow for future hybrid implementations (non-VLD); and have a completely independent range decoder implementation. --- configure.ac | 11 ++++++++++- ext/libvpx/Makefile.am | 2 +- gst-libs/gst/codecparsers/Makefile.am | 8 ++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index d6928f1e21..12b1d17642 100644 --- a/configure.ac +++ b/configure.ac @@ -97,7 +97,7 @@ AM_CONDITIONAL([HAVE_GIT], [test -n "$GIT"]) AC_ARG_VAR([YASM], [Path to yasm program, if any]) AC_PATH_PROG([YASM], [yasm]) -if test -z "$YASM"; then +if test -z "$YASM" -a "$enable_builtin_libvpx" = "yes"; then AC_MSG_ERROR([yasm is needed to build libvpx sources]) fi @@ -110,6 +110,11 @@ AC_ARG_ENABLE(builtin_codecparsers, [enable built-in codecparsers @<:@default=yes@:>@]), [], [enable_builtin_codecparsers="yes"]) +AC_ARG_ENABLE(builtin_libvpx, + AS_HELP_STRING([--enable-builtin-libvpx], + [enable built-in libvpx @<:@default=yes@:>@]), + [], [enable_builtin_libvpx="yes"]) + AC_ARG_ENABLE([encoders], AS_HELP_STRING([--enable-encoders], [enable video encoders @<:@default=yes@:>@]), @@ -421,6 +426,9 @@ AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_JPEG], [test "$ac_cv_have_gst_jpeg_parser" != "yes"]) dnl ... VP8 parser, not upstream yet +if test "$enable_builtin_libvpx" = "yes"; then + ac_cv_have_gst_vp8_parser="no" +fi AC_CACHE_CHECK([for VP8 parser], ac_cv_have_gst_vp8_parser, [ saved_CPPFLAGS="$CPPFLAGS" @@ -439,6 +447,7 @@ AC_CACHE_CHECK([for VP8 parser], ]) AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_VP8], [test "$ac_cv_have_gst_vp8_parser" != "yes"]) +AM_CONDITIONAL([USE_BUILTIN_LIBVPX], [test "$enable_builtin_libvpx" = "yes"]) case $GST_API_VERSION in 0.10) lt_bias=gst0_vaapi_lt_current_bias;; diff --git a/ext/libvpx/Makefile.am b/ext/libvpx/Makefile.am index 4f54b93c15..f945dce608 100644 --- a/ext/libvpx/Makefile.am +++ b/ext/libvpx/Makefile.am @@ -19,7 +19,7 @@ # Boston, MA 02110-1301, USA. lib_LTLIBRARIES = -if USE_LOCAL_CODEC_PARSERS_VP8 +if USE_BUILTIN_LIBVPX lib_LTLIBRARIES += libgstcodecparsers_vpx.la endif diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index d7c9dd8305..ecd2f5e923 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -45,8 +45,8 @@ endif if USE_LOCAL_CODEC_PARSERS_VP8 gen_source_c += gstvp8parser.c gen_source_h += gstvp8parser.h gstvp8rangedecoder.h vp8utils.h -#gen_source_c += dboolhuff.c gstvp8rangedecoder.c vp8utils.c -#gen_source_h += dboolhuff.h + +if USE_BUILTIN_LIBVPX add_source_c += gstvaapilibvpx.c libgstvaapi_codecparsers_cflags += \ @@ -56,6 +56,10 @@ libgstvaapi_codecparsers_cflags += \ libgstvaapi_codecparsers_libs += \ $(top_builddir)/ext/libvpx/libgstcodecparsers_vpx.la +else +gen_source_c += dboolhuff.c gstvp8rangedecoder.c vp8utils.c +gen_source_h += dboolhuff.h +endif endif GENFILES = \ From 03f4071721a611fe3f82b24e21d1c92f7df3e45d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 19 Apr 2014 10:17:20 +0200 Subject: [PATCH 1594/3781] build: add missing files for VP8 bitstream parser. Fix make dist for building the VP8 bitstream parser. --- ext/Makefile.am | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ext/Makefile.am b/ext/Makefile.am index 9c20bcdcc5..1c5100e826 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -6,25 +6,33 @@ codecparsers_srcdir = \ $(top_srcdir)/ext/codecparsers/gst-libs/gst/codecparsers codecparsers_source_c = \ + dboolhuff.c \ gsth264parser.c \ gstjpegparser.c \ gstmpeg4parser.c \ gstmpegvideoparser.c \ gstvc1parser.c \ gstvp8parser.c \ + gstvp8rangedecoder.c \ + nalutils.c \ parserutils.c \ + vp8utils.c \ $(NULL) EXTRA_DIST += $(codecparsers_source_c:%.c=$(codecparsers_srcdir)/%.c) codecparsers_source_h = \ + dboolhuff.h \ gsth264parser.h \ gstjpegparser.h \ gstmpeg4parser.h \ gstmpegvideoparser.h \ gstvc1parser.h \ gstvp8parser.h \ + gstvp8rangedecoder.h \ + nalutils.h \ parserutils.h \ + vp8utils.h \ $(NULL) EXTRA_DIST += $(codecparsers_source_h:%.h=$(codecparsers_srcdir)/%.h) From fff4facb909c33bd56761dd90ded454ac41bf135 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 21 Apr 2014 17:34:59 +0200 Subject: [PATCH 1595/3781] build: add missing files for GStreamer 0.10. Add missing GstVideoEncoder implementation files to fix build with ancient GStreamer 0.10 stack. https://bugzilla.gnome.org/show_bug.cgi?id=723964 --- ext/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/Makefile.am b/ext/Makefile.am index 1c5100e826..7aea0dd79c 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -42,6 +42,7 @@ videoutils_srcdir = \ videoutils_source_c = \ gstvideodecoder.c \ + gstvideoencoder.c \ gstvideoutils.c \ video.c \ $(NULL) @@ -50,6 +51,7 @@ EXTRA_DIST += $(videoutils_source_c:%.c=$(videoutils_srcdir)/%.c) videoutils_source_h = \ gstvideodecoder.h \ + gstvideoencoder.h \ gstvideoutils.h \ video.h \ $(NULL) From de02a5c1906b4dbc6b2ba33972b482d213292e2a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 21 Apr 2014 18:02:21 +0200 Subject: [PATCH 1596/3781] build: fix make dist with certain conditionals not met. Fix generation of source tarballs when certain conditionals are not met. e.g. always include all buildable codecparsers sources in the distribution tarball, fix plug-in element sources set to include X11 and encoder bits. --- gst-libs/gst/codecparsers/Makefile.am | 34 +++++++++++++++++++++++++-- gst/vaapi/Makefile.am | 6 +++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index ecd2f5e923..1feb24151a 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -98,9 +98,39 @@ $(gen_source_h): %.h: $(local_codecparsers_srcdir)/%.h $(top_builddir)/ext/libvpx/libgstcodecparsers_vpx.la: $(MAKE) -C $(top_builddir)/ext/libvpx +# All sources and headers that could be used here +all_source_c = \ + dboolhuff.c \ + gsth264parser.c \ + gstjpegparser.c \ + gstmpeg4parser.c \ + gstmpegvideoparser.c \ + gstvaapilibvpx.c \ + gstvc1parser.c \ + gstvp8parser.c \ + gstvp8rangedecoder.c \ + nalutils.c \ + parserutils.c \ + vp8utils.c \ + $(NULL) + +all_source_h = \ + dboolhuff.h \ + gsth264parser.h \ + gstjpegparser.h \ + gstmpeg4parser.h \ + gstmpegvideoparser.h \ + gstvc1parser.h \ + gstvp8parser.h \ + gstvp8rangedecoder.h \ + nalutils.h \ + parserutils.h \ + vp8utils.h \ + $(NULL) + EXTRA_DIST = \ - $(add_source_c) \ - $(add_source_h) \ + $(all_source_c) \ + $(all_source_h) \ $(NULL) DISTCLEANFILES = $(GENFILES) .timestamp.symlinks diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 9bef588ced..5f0c659bce 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -123,7 +123,6 @@ libgstvaapi_source_c += $(libgstvaapi_1_0p_source_c) libgstvaapi_source_h += $(libgstvaapi_1_0p_source_h) endif -if USE_GST_API_0_10 libgstvaapi_0_10_source_c = \ gstvaapidownload.c \ gstvaapiupload.c \ @@ -133,7 +132,6 @@ libgstvaapi_0_10_source_h = \ gstvaapidownload.h \ gstvaapiupload.h \ $(NULL) -endif if USE_GST_API_0_10 libgstvaapi_source_c += $(libgstvaapi_0_10_source_c) @@ -166,6 +164,10 @@ libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvaapi_la_LIBTOOLFLAGS = --tag=disable-static EXTRA_DIST = \ + $(libgstvaapi_enc_source_c) \ + $(libgstvaapi_enc_source_h) \ + $(libgstvaapi_x11_source_c) \ + $(libgstvaapi_x11_source_h) \ $(libgstvaapi_glx_source_c) \ $(libgstvaapi_glx_source_h) \ $(libgstvaapi_1_2p_source_c) \ From 01c78c4b20a0d00034dc7e5c976ee87fa1226d7e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 22 Apr 2014 17:25:15 +0200 Subject: [PATCH 1597/3781] vp8: fix check for disabling the loop filter (again). Improve condition to disable the loop filter. The previous heuristic used to check all filter levels, for all segments. It turns out that only the base filter_level value defined in the frame header needs to be checked. This fixes 00-comprehensive-013. --- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index 07816de46c..7b828548f5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -273,7 +273,7 @@ fill_picture (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture) GstVp8Parser *const parser = &priv->parser; GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr; GstVp8Segmentation *const seg = &parser->segmentation; - gint i, filter_levels; + gint i; /* Fill in VAPictureParameterBufferVP8 */ pic_param->frame_width = priv->width; @@ -330,12 +330,8 @@ fill_picture (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture) /* In decoding, the only loop filter settings that matter are those in the frame header (9.1) */ - filter_levels = pic_param->loop_filter_level[0]; - if (seg->segmentation_enabled) { - for (i = 1; i < 4; i++) - filter_levels |= pic_param->loop_filter_level[i]; - } - pic_param->pic_fields.bits.loop_filter_disable = filter_levels == 0; + 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; From f2b0d02168e73feaae0023ccf864cea4805a0b88 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 22 Apr 2014 19:53:50 +0200 Subject: [PATCH 1598/3781] vp8: fix per-segment deblocking filter level in relative mode. Fix possible bug when a per-segment deblocking filter level value needs to be set in non-absolute mode, i.e. when the loop filter update value is negative in delta mode. Also clamp the resulting filter level value to 0..63 range. --- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index 7b828548f5..c7d22858a0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -315,12 +315,14 @@ fill_picture (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture) pic_param->mb_segment_tree_probs[i] = seg->segment_prob[i]; for (i = 0; i < 4; i++) { + gint8 level; if (seg->segmentation_enabled) { - pic_param->loop_filter_level[i] = seg->lf_update_value[i]; - if (!seg->segment_feature_mode) - pic_param->loop_filter_level[i] += frame_hdr->loop_filter_level; + level = seg->lf_update_value[i]; + if (!seg->segment_feature_mode) // 0 means delta update + level += frame_hdr->loop_filter_level; } else - pic_param->loop_filter_level[i] = frame_hdr->loop_filter_level; + 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]; From 519f0e6b8adb76ffeaac51bd98f694e294484290 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Apr 2014 13:45:31 +0200 Subject: [PATCH 1599/3781] context: add support for non-YUV 4:2:0 formats. Don't force allocation of VA surfaces in YUV 4:2:0 format. Rather, allow for the upper layer to specify the desired chroma type. If the chroma type field is not set (or yields zero), then YUV 4:2:0 format is used by default. --- gst-libs/gst/vaapi/gstvaapicontext.c | 59 ++++++++++++++++++---------- gst-libs/gst/vaapi/gstvaapicontext.h | 1 + 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index b306a6f4ee..45ecf9c9c4 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -44,6 +44,9 @@ #define DEBUG 1 #include "gstvaapidebug.h" +/* Define default VA surface chroma format to YUV 4:2:0 */ +#define DEFAULT_CHROMA_TYPE (GST_VAAPI_CHROMA_TYPE_YUV420) + static void unref_surface_cb (GstVaapiSurface * surface) { @@ -136,7 +139,7 @@ context_create_surfaces (GstVaapiContext * context) for (i = context->surfaces->len; i < num_surfaces; i++) { surface = gst_vaapi_surface_new (GST_VAAPI_OBJECT_DISPLAY (context), - GST_VAAPI_CHROMA_TYPE_YUV420, cip->width, cip->height); + cip->chroma_type, cip->width, cip->height); if (!surface) return FALSE; gst_vaapi_surface_set_parent_context (surface, context); @@ -158,7 +161,7 @@ context_create (GstVaapiContext * context) VAStatus status; GArray *surfaces = NULL; gboolean success = FALSE; - guint i, value; + guint i, value, va_chroma_format; if (!context->surfaces && !context_create_surfaces (context)) goto cleanup; @@ -186,12 +189,15 @@ context_create (GstVaapiContext * context) gst_vaapi_entrypoint_get_va_entrypoint (cip->entrypoint); /* 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_RT_FORMAT_YUV420)) + if (!(value & va_chroma_format)) goto cleanup; - attrib->value = VA_RT_FORMAT_YUV420; + attrib->value = va_chroma_format; attrib++; switch (cip->usage) { @@ -286,9 +292,14 @@ context_update_config_encoder (GstVaapiContext * context, static inline void gst_vaapi_context_init (GstVaapiContext * context, - const GstVaapiContextInfo * cip) + const GstVaapiContextInfo * new_cip) { - context->info = *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; gst_vaapi_context_overlay_init (context); } @@ -355,38 +366,46 @@ gst_vaapi_context_reset (GstVaapiContext * context, const GstVaapiContextInfo * new_cip) { GstVaapiContextInfo *const cip = &context->info; - gboolean size_changed, config_changed; + gboolean reset_surfaces = FALSE, reset_config = FALSE; + GstVaapiChromaType chroma_type; - size_changed = cip->width != new_cip->width || cip->height != new_cip->height; - if (size_changed) { - cip->width = new_cip->width; - cip->height = new_cip->height; + 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; } - config_changed = cip->profile != new_cip->profile || - cip->entrypoint != new_cip->entrypoint; - if (config_changed) { + 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->usage != new_cip->usage) { cip->usage = new_cip->usage; - config_changed = TRUE; + 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)) - config_changed = TRUE; + reset_config = TRUE; } - if (size_changed) + if (reset_surfaces) context_destroy_surfaces (context); - if (config_changed) + if (reset_config) context_destroy (context); - if (size_changed && !context_create_surfaces (context)) + if (reset_surfaces && !context_create_surfaces (context)) return FALSE; - if (config_changed && !context_create (context)) + if (reset_config && !context_create (context)) return FALSE; return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 64e758fbfd..d3010c106b 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -81,6 +81,7 @@ struct _GstVaapiContextInfo GstVaapiContextUsage usage; GstVaapiProfile profile; GstVaapiEntrypoint entrypoint; + GstVaapiChromaType chroma_type; guint width; guint height; guint ref_frames; From 14e9d383e3ccfede18084da96243e769f3ec381d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Apr 2014 13:47:53 +0200 Subject: [PATCH 1600/3781] encoder: derive chroma type from video format. Cope with previous VA context change to derive the correct surface chroma type from the input video format. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index b055ef5ae0..520bea4e36 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -543,22 +543,37 @@ get_packed_headers (GstVaapiEncoder * encoder) } /* Updates video context */ -static void +static gboolean set_context_info (GstVaapiEncoder * encoder) { GstVaapiContextInfo *const cip = &encoder->context_info; GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; + const GstVideoFormat format = + GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; cip->profile = encoder->profile; cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + cip->chroma_type = gst_vaapi_video_format_get_chroma_type (format); cip->width = GST_VAAPI_ENCODER_WIDTH (encoder); cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); cip->ref_frames = encoder->num_ref_frames; + if (!cip->chroma_type) + goto error_unsupported_format; + memset (config, 0, sizeof (*config)); config->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); config->packed_headers = get_packed_headers (encoder); + return TRUE; + + /* ERRORS */ +error_unsupported_format: + { + GST_ERROR ("failed to determine chroma type for format %s", + gst_vaapi_video_format_to_string (format)); + return FALSE; + } } /* Ensures the underlying VA context for encoding is created */ @@ -567,7 +582,8 @@ gst_vaapi_encoder_ensure_context (GstVaapiEncoder * encoder) { GstVaapiContextInfo *const cip = &encoder->context_info; - set_context_info (encoder); + if (!set_context_info (encoder)) + return FALSE; if (encoder->context) { if (!gst_vaapi_context_reset (encoder->context, cip)) From 1b7904931725a8e6fd2ade5c94aeb9b83cb2e465 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Apr 2014 13:57:02 +0200 Subject: [PATCH 1601/3781] decoder: re-indent GstVaapiDecoder base object. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 1242 ++++++++++----------- gst-libs/gst/vaapi/gstvaapidecoder.h | 77 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 139 ++- 3 files changed, 721 insertions(+), 737 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index aeb5d05073..fde845086b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -39,503 +39,503 @@ #include "gstvaapidebug.h" static void -drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame); +drop_frame (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame); static void -parser_state_finalize(GstVaapiParserState *ps) +parser_state_finalize (GstVaapiParserState * ps) { - if (ps->input_adapter) { - gst_adapter_clear(ps->input_adapter); - g_object_unref(ps->input_adapter); - ps->input_adapter = NULL; - } + if (ps->input_adapter) { + gst_adapter_clear (ps->input_adapter); + g_object_unref (ps->input_adapter); + ps->input_adapter = NULL; + } - if (ps->output_adapter) { - gst_adapter_clear(ps->output_adapter); - g_object_unref(ps->output_adapter); - ps->output_adapter = NULL; - } + if (ps->output_adapter) { + gst_adapter_clear (ps->output_adapter); + g_object_unref (ps->output_adapter); + ps->output_adapter = NULL; + } - if (ps->next_unit_pending) { - gst_vaapi_decoder_unit_clear(&ps->next_unit); - ps->next_unit_pending = FALSE; - } + if (ps->next_unit_pending) { + gst_vaapi_decoder_unit_clear (&ps->next_unit); + ps->next_unit_pending = FALSE; + } } static gboolean -parser_state_init(GstVaapiParserState *ps) +parser_state_init (GstVaapiParserState * ps) { - memset(ps, 0, sizeof(*ps)); + memset (ps, 0, sizeof (*ps)); - ps->input_adapter = gst_adapter_new(); - if (!ps->input_adapter) - return FALSE; + ps->input_adapter = gst_adapter_new (); + if (!ps->input_adapter) + return FALSE; - ps->output_adapter = gst_adapter_new(); - if (!ps->output_adapter) - return FALSE; - return TRUE; + ps->output_adapter = gst_adapter_new (); + if (!ps->output_adapter) + return FALSE; + return TRUE; } static void -parser_state_prepare(GstVaapiParserState *ps, GstAdapter *adapter) +parser_state_prepare (GstVaapiParserState * ps, GstAdapter * adapter) { - /* XXX: check we really have a continuity from the previous call */ - if (ps->current_adapter != adapter) - goto reset; - return; + /* XXX: check we really have a continuity from the previous call */ + if (ps->current_adapter != adapter) + goto reset; + return; reset: - ps->current_adapter = adapter; - ps->input_offset1 = -1; - ps->input_offset2 = -1; + ps->current_adapter = adapter; + ps->input_offset1 = -1; + ps->input_offset2 = -1; } static gboolean -push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer) +push_buffer (GstVaapiDecoder * decoder, GstBuffer * buffer) { - if (!buffer) { - buffer = gst_buffer_new(); - if (!buffer) - return FALSE; - GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_EOS); - } + if (!buffer) { + buffer = gst_buffer_new (); + if (!buffer) + return FALSE; + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_EOS); + } - GST_DEBUG("queue encoded data buffer %p (%zu bytes)", - buffer, gst_buffer_get_size(buffer)); + GST_DEBUG ("queue encoded data buffer %p (%zu bytes)", + buffer, gst_buffer_get_size (buffer)); - g_async_queue_push(decoder->buffers, buffer); - return TRUE; + g_async_queue_push (decoder->buffers, buffer); + return TRUE; } static GstBuffer * -pop_buffer(GstVaapiDecoder *decoder) +pop_buffer (GstVaapiDecoder * decoder) { - GstBuffer *buffer; + GstBuffer *buffer; - buffer = g_async_queue_try_pop(decoder->buffers); - if (!buffer) - return NULL; + buffer = g_async_queue_try_pop (decoder->buffers); + if (!buffer) + return NULL; - GST_DEBUG("dequeue buffer %p for decoding (%zu bytes)", - buffer, gst_buffer_get_size(buffer)); + GST_DEBUG ("dequeue buffer %p for decoding (%zu bytes)", + buffer, gst_buffer_get_size (buffer)); - return buffer; + return buffer; } static GstVaapiDecoderStatus -do_parse(GstVaapiDecoder *decoder, - GstVideoCodecFrame *base_frame, GstAdapter *adapter, gboolean at_eos, - guint *got_unit_size_ptr, gboolean *got_frame_ptr) +do_parse (GstVaapiDecoder * decoder, + GstVideoCodecFrame * base_frame, GstAdapter * adapter, gboolean at_eos, + guint * got_unit_size_ptr, gboolean * got_frame_ptr) { - GstVaapiParserState * const ps = &decoder->parser_state; - GstVaapiParserFrame *frame; - GstVaapiDecoderUnit *unit; - GstVaapiDecoderStatus status; + GstVaapiParserState *const ps = &decoder->parser_state; + GstVaapiParserFrame *frame; + GstVaapiDecoderUnit *unit; + GstVaapiDecoderStatus status; - *got_unit_size_ptr = 0; - *got_frame_ptr = FALSE; + *got_unit_size_ptr = 0; + *got_frame_ptr = FALSE; - frame = gst_video_codec_frame_get_user_data(base_frame); - if (!frame) { - GstVideoCodecState * const codec_state = decoder->codec_state; - frame = gst_vaapi_parser_frame_new(codec_state->info.width, - codec_state->info.height); - if (!frame) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - gst_video_codec_frame_set_user_data(base_frame, - frame, (GDestroyNotify)gst_vaapi_mini_object_unref); + frame = gst_video_codec_frame_get_user_data (base_frame); + if (!frame) { + GstVideoCodecState *const codec_state = decoder->codec_state; + frame = gst_vaapi_parser_frame_new (codec_state->info.width, + codec_state->info.height); + if (!frame) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + gst_video_codec_frame_set_user_data (base_frame, + frame, (GDestroyNotify) gst_vaapi_mini_object_unref); + } + + parser_state_prepare (ps, adapter); + + unit = &ps->next_unit; + if (ps->next_unit_pending) { + ps->next_unit_pending = FALSE; + goto got_unit; + } + gst_vaapi_decoder_unit_init (unit); + + ps->current_frame = base_frame; + status = GST_VAAPI_DECODER_GET_CLASS (decoder)->parse (decoder, + adapter, at_eos, unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + if (at_eos && frame->units->len > 0 && + status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) { + /* XXX: assume the frame is complete at */ + *got_frame_ptr = TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } + return status; + } - parser_state_prepare(ps, adapter); - - unit = &ps->next_unit; - if (ps->next_unit_pending) { - ps->next_unit_pending = FALSE; - goto got_unit; - } - gst_vaapi_decoder_unit_init(unit); - - ps->current_frame = base_frame; - status = GST_VAAPI_DECODER_GET_CLASS(decoder)->parse(decoder, - adapter, at_eos, unit); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - if (at_eos && frame->units->len > 0 && - status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) { - /* XXX: assume the frame is complete at */ - *got_frame_ptr = TRUE; - return GST_VAAPI_DECODER_STATUS_SUCCESS; - } - return status; - } - - if (GST_VAAPI_DECODER_UNIT_IS_FRAME_START(unit) && frame->units->len > 0) { - ps->next_unit_pending = TRUE; - *got_frame_ptr = TRUE; - return GST_VAAPI_DECODER_STATUS_SUCCESS; - } + if (GST_VAAPI_DECODER_UNIT_IS_FRAME_START (unit) && frame->units->len > 0) { + ps->next_unit_pending = TRUE; + *got_frame_ptr = TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; + } got_unit: - gst_vaapi_parser_frame_append_unit(frame, unit); - *got_unit_size_ptr = unit->size; - *got_frame_ptr = GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_vaapi_parser_frame_append_unit (frame, unit); + *got_unit_size_ptr = unit->size; + *got_frame_ptr = GST_VAAPI_DECODER_UNIT_IS_FRAME_END (unit); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -do_decode_units(GstVaapiDecoder *decoder, GArray *units) +do_decode_units (GstVaapiDecoder * decoder, GArray * units) { - GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); - GstVaapiDecoderStatus status; - guint i; + GstVaapiDecoderClass *const klass = GST_VAAPI_DECODER_GET_CLASS (decoder); + GstVaapiDecoderStatus status; + guint i; - for (i = 0; i < units->len; i++) { - GstVaapiDecoderUnit * const unit = - &g_array_index(units, GstVaapiDecoderUnit, i); - if (GST_VAAPI_DECODER_UNIT_IS_SKIPPED(unit)) - continue; - status = klass->decode(decoder, unit); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -do_decode_1(GstVaapiDecoder *decoder, GstVaapiParserFrame *frame) -{ - GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); - GstVaapiDecoderStatus status; - - if (frame->pre_units->len > 0) { - status = do_decode_units(decoder, frame->pre_units); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - - if (frame->units->len > 0) { - if (klass->start_frame) { - GstVaapiDecoderUnit * const unit = - &g_array_index(frame->units, GstVaapiDecoderUnit, 0); - status = klass->start_frame(decoder, unit); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - - status = do_decode_units(decoder, frame->units); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - - if (klass->end_frame) { - status = klass->end_frame(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - } - - if (frame->post_units->len > 0) { - status = do_decode_units(decoder, frame->post_units); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - - /* Drop frame if there is no slice data unit in there */ - if (G_UNLIKELY(frame->units->len == 0)) - return GST_VAAPI_DECODER_STATUS_DROP_FRAME; - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static inline GstVaapiDecoderStatus -do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame) -{ - GstVaapiParserState * const ps = &decoder->parser_state; - GstVaapiParserFrame * const frame = base_frame->user_data; - GstVaapiDecoderStatus status; - - ps->current_frame = base_frame; - - gst_vaapi_parser_frame_ref(frame); - status = do_decode_1(decoder, frame); - gst_vaapi_parser_frame_unref(frame); - - switch ((guint)status) { - case GST_VAAPI_DECODER_STATUS_DROP_FRAME: - drop_frame(decoder, base_frame); - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } - return status; -} - -static inline GstVaapiDecoderStatus -do_flush(GstVaapiDecoder *decoder) -{ - GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); - - if (klass->flush) - return klass->flush(decoder); - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -decode_step(GstVaapiDecoder *decoder) -{ - GstVaapiParserState * const ps = &decoder->parser_state; - GstVaapiDecoderStatus status; - GstBuffer *buffer; - gboolean got_frame; - guint got_unit_size, input_size; - - status = gst_vaapi_decoder_check_status(decoder); + for (i = 0; i < units->len; i++) { + GstVaapiDecoderUnit *const unit = + &g_array_index (units, GstVaapiDecoderUnit, i); + if (GST_VAAPI_DECODER_UNIT_IS_SKIPPED (unit)) + continue; + status = klass->decode (decoder, unit); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +do_decode_1 (GstVaapiDecoder * decoder, GstVaapiParserFrame * frame) +{ + GstVaapiDecoderClass *const klass = GST_VAAPI_DECODER_GET_CLASS (decoder); + GstVaapiDecoderStatus status; + + if (frame->pre_units->len > 0) { + status = do_decode_units (decoder, frame->pre_units); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + + if (frame->units->len > 0) { + if (klass->start_frame) { + GstVaapiDecoderUnit *const unit = + &g_array_index (frame->units, GstVaapiDecoderUnit, 0); + status = klass->start_frame (decoder, unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - - /* Fill adapter with all buffers we have in the queue */ - for (;;) { - buffer = pop_buffer(decoder); - if (!buffer) - break; - - ps->at_eos = GST_BUFFER_IS_EOS(buffer); - if (!ps->at_eos) - gst_adapter_push(ps->input_adapter, buffer); } - /* Parse and decode all decode units */ - input_size = gst_adapter_available(ps->input_adapter); - if (input_size == 0) { - if (ps->at_eos) - return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + status = do_decode_units (decoder, frame->units); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + if (klass->end_frame) { + status = klass->end_frame (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; } + } - do { - if (!ps->current_frame) { - ps->current_frame = g_slice_new0(GstVideoCodecFrame); - if (!ps->current_frame) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - ps->current_frame->ref_count = 1; - ps->current_frame->system_frame_number = ps->current_frame_number++; - } + if (frame->post_units->len > 0) { + status = do_decode_units (decoder, frame->post_units); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } - status = do_parse(decoder, ps->current_frame, ps->input_adapter, - ps->at_eos, &got_unit_size, &got_frame); - GST_DEBUG("parse frame (status = %d)", status); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA && ps->at_eos) - status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM; - break; - } + /* Drop frame if there is no slice data unit in there */ + if (G_UNLIKELY (frame->units->len == 0)) + return GST_VAAPI_DECODER_STATUS_DROP_FRAME; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} - if (got_unit_size > 0) { - buffer = gst_adapter_take_buffer(ps->input_adapter, got_unit_size); - input_size -= got_unit_size; +static inline GstVaapiDecoderStatus +do_decode (GstVaapiDecoder * decoder, GstVideoCodecFrame * base_frame) +{ + GstVaapiParserState *const ps = &decoder->parser_state; + GstVaapiParserFrame *const frame = base_frame->user_data; + GstVaapiDecoderStatus status; - if (gst_adapter_available(ps->output_adapter) == 0) { - ps->current_frame->pts = - gst_adapter_prev_timestamp(ps->input_adapter, NULL); - } - gst_adapter_push(ps->output_adapter, buffer); - } + ps->current_frame = base_frame; - if (got_frame) { - ps->current_frame->input_buffer = gst_adapter_take_buffer( - ps->output_adapter, - gst_adapter_available(ps->output_adapter)); + gst_vaapi_parser_frame_ref (frame); + status = do_decode_1 (decoder, frame); + gst_vaapi_parser_frame_unref (frame); - status = do_decode(decoder, ps->current_frame); - GST_DEBUG("decode frame (status = %d)", status); + switch ((guint) status) { + case GST_VAAPI_DECODER_STATUS_DROP_FRAME: + drop_frame (decoder, base_frame); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + return status; +} - gst_video_codec_frame_unref(ps->current_frame); - ps->current_frame = NULL; - break; - } - } while (input_size > 0); +static inline GstVaapiDecoderStatus +do_flush (GstVaapiDecoder * decoder) +{ + GstVaapiDecoderClass *const klass = GST_VAAPI_DECODER_GET_CLASS (decoder); + + if (klass->flush) + return klass->flush (decoder); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_step (GstVaapiDecoder * decoder) +{ + GstVaapiParserState *const ps = &decoder->parser_state; + GstVaapiDecoderStatus status; + GstBuffer *buffer; + gboolean got_frame; + guint got_unit_size, input_size; + + status = gst_vaapi_decoder_check_status (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; + + /* Fill adapter with all buffers we have in the queue */ + for (;;) { + buffer = pop_buffer (decoder); + if (!buffer) + break; + + ps->at_eos = GST_BUFFER_IS_EOS (buffer); + if (!ps->at_eos) + gst_adapter_push (ps->input_adapter, buffer); + } + + /* Parse and decode all decode units */ + input_size = gst_adapter_available (ps->input_adapter); + if (input_size == 0) { + if (ps->at_eos) + return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } + + do { + if (!ps->current_frame) { + ps->current_frame = g_slice_new0 (GstVideoCodecFrame); + if (!ps->current_frame) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + ps->current_frame->ref_count = 1; + ps->current_frame->system_frame_number = ps->current_frame_number++; + } + + status = do_parse (decoder, ps->current_frame, ps->input_adapter, + ps->at_eos, &got_unit_size, &got_frame); + GST_DEBUG ("parse frame (status = %d)", status); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA && ps->at_eos) + status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + break; + } + + if (got_unit_size > 0) { + buffer = gst_adapter_take_buffer (ps->input_adapter, got_unit_size); + input_size -= got_unit_size; + + if (gst_adapter_available (ps->output_adapter) == 0) { + ps->current_frame->pts = + gst_adapter_prev_timestamp (ps->input_adapter, NULL); + } + gst_adapter_push (ps->output_adapter, buffer); + } + + if (got_frame) { + ps->current_frame->input_buffer = + gst_adapter_take_buffer (ps->output_adapter, + gst_adapter_available (ps->output_adapter)); + + status = do_decode (decoder, ps->current_frame); + GST_DEBUG ("decode frame (status = %d)", status); + + gst_video_codec_frame_unref (ps->current_frame); + ps->current_frame = NULL; + break; + } + } while (input_size > 0); + return status; } static void -drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) +drop_frame (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame) { - GST_DEBUG("drop frame %d", frame->system_frame_number); + GST_DEBUG ("drop frame %d", frame->system_frame_number); - /* no surface proxy */ - gst_video_codec_frame_set_user_data(frame, NULL, NULL); + /* no surface proxy */ + gst_video_codec_frame_set_user_data (frame, NULL, NULL); - frame->pts = GST_CLOCK_TIME_NONE; - GST_VIDEO_CODEC_FRAME_FLAG_SET(frame, - GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); + frame->pts = GST_CLOCK_TIME_NONE; + GST_VIDEO_CODEC_FRAME_FLAG_SET (frame, + GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); - g_async_queue_push(decoder->frames, gst_video_codec_frame_ref(frame)); + g_async_queue_push (decoder->frames, gst_video_codec_frame_ref (frame)); } static inline void -push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) +push_frame (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame) { - GstVaapiSurfaceProxy * const proxy = frame->user_data; + GstVaapiSurfaceProxy *const proxy = frame->user_data; - GST_DEBUG("push frame %d (surface 0x%08x)", frame->system_frame_number, - (guint32) GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy)); + GST_DEBUG ("push frame %d (surface 0x%08x)", frame->system_frame_number, + (guint32) GST_VAAPI_SURFACE_PROXY_SURFACE_ID (proxy)); - g_async_queue_push(decoder->frames, gst_video_codec_frame_ref(frame)); + g_async_queue_push (decoder->frames, gst_video_codec_frame_ref (frame)); } static inline GstVideoCodecFrame * -pop_frame(GstVaapiDecoder *decoder, guint64 timeout) +pop_frame (GstVaapiDecoder * decoder, guint64 timeout) { - GstVideoCodecFrame *frame; - GstVaapiSurfaceProxy *proxy; + GstVideoCodecFrame *frame; + GstVaapiSurfaceProxy *proxy; - if (G_LIKELY(timeout > 0)) - frame = g_async_queue_timeout_pop(decoder->frames, timeout); - else - frame = g_async_queue_try_pop(decoder->frames); - if (!frame) - return NULL; + if (G_LIKELY (timeout > 0)) + frame = g_async_queue_timeout_pop (decoder->frames, timeout); + else + frame = g_async_queue_try_pop (decoder->frames); + if (!frame) + return NULL; - proxy = frame->user_data; - GST_DEBUG("pop frame %d (surface 0x%08x)", frame->system_frame_number, - (proxy ? (guint32) GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) : - VA_INVALID_ID)); + proxy = frame->user_data; + GST_DEBUG ("pop frame %d (surface 0x%08x)", frame->system_frame_number, + (proxy ? (guint32) GST_VAAPI_SURFACE_PROXY_SURFACE_ID (proxy) : + VA_INVALID_ID)); - return frame; + return frame; } static gboolean -set_caps(GstVaapiDecoder *decoder, const GstCaps *caps) +set_caps (GstVaapiDecoder * decoder, const GstCaps * caps) { - GstVideoCodecState * const codec_state = decoder->codec_state; - GstStructure * const structure = gst_caps_get_structure(caps, 0); - GstVaapiProfile profile; - const GValue *v_codec_data; + GstVideoCodecState *const codec_state = decoder->codec_state; + GstStructure *const structure = gst_caps_get_structure (caps, 0); + GstVaapiProfile profile; + const GValue *v_codec_data; - profile = gst_vaapi_profile_from_caps(caps); - if (!profile) - return FALSE; + profile = gst_vaapi_profile_from_caps (caps); + if (!profile) + return FALSE; - decoder->codec = gst_vaapi_profile_get_codec(profile); - if (!decoder->codec) - return FALSE; + decoder->codec = gst_vaapi_profile_get_codec (profile); + if (!decoder->codec) + return FALSE; - if (!gst_video_info_from_caps(&codec_state->info, caps)) - return FALSE; + if (!gst_video_info_from_caps (&codec_state->info, caps)) + return FALSE; - codec_state->caps = gst_caps_copy(caps); + codec_state->caps = gst_caps_copy (caps); - v_codec_data = gst_structure_get_value(structure, "codec_data"); - if (v_codec_data) - gst_buffer_replace(&codec_state->codec_data, - gst_value_get_buffer(v_codec_data)); - return TRUE; + v_codec_data = gst_structure_get_value (structure, "codec_data"); + if (v_codec_data) + gst_buffer_replace (&codec_state->codec_data, + gst_value_get_buffer (v_codec_data)); + return TRUE; } static inline GstCaps * -get_caps(GstVaapiDecoder *decoder) +get_caps (GstVaapiDecoder * decoder) { - return GST_VAAPI_DECODER_CODEC_STATE(decoder)->caps; + return GST_VAAPI_DECODER_CODEC_STATE (decoder)->caps; } static void -notify_codec_state_changed(GstVaapiDecoder *decoder) +notify_codec_state_changed (GstVaapiDecoder * decoder) { - if (decoder->codec_state_changed_func) - decoder->codec_state_changed_func(decoder, decoder->codec_state, - decoder->codec_state_changed_data); + if (decoder->codec_state_changed_func) + decoder->codec_state_changed_func (decoder, decoder->codec_state, + decoder->codec_state_changed_data); } void -gst_vaapi_decoder_finalize(GstVaapiDecoder *decoder) +gst_vaapi_decoder_finalize (GstVaapiDecoder * decoder) { - const GstVaapiDecoderClass * const klass = - GST_VAAPI_DECODER_GET_CLASS(decoder); + const GstVaapiDecoderClass *const klass = + GST_VAAPI_DECODER_GET_CLASS (decoder); - if (klass->destroy) - klass->destroy(decoder); + if (klass->destroy) + klass->destroy (decoder); - gst_video_codec_state_unref(decoder->codec_state); - decoder->codec_state = NULL; + gst_video_codec_state_unref (decoder->codec_state); + decoder->codec_state = NULL; - parser_state_finalize(&decoder->parser_state); - - if (decoder->buffers) { - g_async_queue_unref(decoder->buffers); - decoder->buffers = NULL; - } + parser_state_finalize (&decoder->parser_state); - if (decoder->frames) { - g_async_queue_unref(decoder->frames); - decoder->frames = NULL; - } + if (decoder->buffers) { + g_async_queue_unref (decoder->buffers); + decoder->buffers = NULL; + } - gst_vaapi_object_replace(&decoder->context, NULL); - decoder->va_context = VA_INVALID_ID; + if (decoder->frames) { + g_async_queue_unref (decoder->frames); + decoder->frames = NULL; + } - gst_vaapi_display_replace(&decoder->display, NULL); - decoder->va_display = NULL; + gst_vaapi_object_replace (&decoder->context, NULL); + decoder->va_context = VA_INVALID_ID; + + gst_vaapi_display_replace (&decoder->display, NULL); + decoder->va_display = NULL; } static gboolean -gst_vaapi_decoder_init(GstVaapiDecoder *decoder, GstVaapiDisplay *display, - GstCaps *caps) +gst_vaapi_decoder_init (GstVaapiDecoder * decoder, GstVaapiDisplay * display, + GstCaps * caps) { - const GstVaapiDecoderClass * const klass = - GST_VAAPI_DECODER_GET_CLASS(decoder); - GstVideoCodecState *codec_state; - guint sub_size; + const GstVaapiDecoderClass *const klass = + GST_VAAPI_DECODER_GET_CLASS (decoder); + GstVideoCodecState *codec_state; + guint sub_size; - parser_state_init(&decoder->parser_state); + parser_state_init (&decoder->parser_state); - codec_state = g_slice_new0(GstVideoCodecState); - codec_state->ref_count = 1; - gst_video_info_init(&codec_state->info); + codec_state = g_slice_new0 (GstVideoCodecState); + codec_state->ref_count = 1; + gst_video_info_init (&codec_state->info); - decoder->user_data = NULL; - decoder->display = gst_vaapi_display_ref(display); - decoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY(display); - decoder->context = NULL; - decoder->va_context = VA_INVALID_ID; - decoder->codec = 0; - decoder->codec_state = codec_state; - decoder->codec_state_changed_func = NULL; - decoder->codec_state_changed_data = NULL; + decoder->user_data = NULL; + decoder->display = gst_vaapi_display_ref (display); + decoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY (display); + decoder->context = NULL; + decoder->va_context = VA_INVALID_ID; + decoder->codec = 0; + decoder->codec_state = codec_state; + decoder->codec_state_changed_func = NULL; + decoder->codec_state_changed_data = NULL; - decoder->buffers = g_async_queue_new_full((GDestroyNotify)gst_buffer_unref); - decoder->frames = g_async_queue_new_full((GDestroyNotify) - gst_video_codec_frame_unref); + decoder->buffers = g_async_queue_new_full ((GDestroyNotify) gst_buffer_unref); + decoder->frames = g_async_queue_new_full ((GDestroyNotify) + gst_video_codec_frame_unref); - if (!set_caps(decoder, caps)) - return FALSE; + if (!set_caps (decoder, caps)) + return FALSE; - sub_size = GST_VAAPI_MINI_OBJECT_CLASS(klass)->size - sizeof(*decoder); - if (sub_size > 0) - memset(((guchar *)decoder) + sizeof(*decoder), 0, sub_size); + sub_size = GST_VAAPI_MINI_OBJECT_CLASS (klass)->size - sizeof (*decoder); + if (sub_size > 0) + memset (((guchar *) decoder) + sizeof (*decoder), 0, sub_size); - if (klass->create && !klass->create(decoder)) - return FALSE; - return TRUE; + if (klass->create && !klass->create (decoder)) + return FALSE; + return TRUE; } GstVaapiDecoder * -gst_vaapi_decoder_new(const GstVaapiDecoderClass *klass, - GstVaapiDisplay *display, GstCaps *caps) +gst_vaapi_decoder_new (const GstVaapiDecoderClass * klass, + GstVaapiDisplay * display, GstCaps * caps) { - GstVaapiDecoder *decoder; + GstVaapiDecoder *decoder; - g_return_val_if_fail(display != NULL, NULL); - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (GST_IS_CAPS (caps), NULL); - decoder = (GstVaapiDecoder *) - gst_vaapi_mini_object_new(GST_VAAPI_MINI_OBJECT_CLASS(klass)); - if (!decoder) - return NULL; + decoder = (GstVaapiDecoder *) + gst_vaapi_mini_object_new (GST_VAAPI_MINI_OBJECT_CLASS (klass)); + if (!decoder) + return NULL; - if (!gst_vaapi_decoder_init(decoder, display, caps)) - goto error; - return decoder; + if (!gst_vaapi_decoder_init (decoder, display, caps)) + goto error; + return decoder; error: - gst_vaapi_decoder_unref(decoder); - return NULL; + gst_vaapi_decoder_unref (decoder); + return NULL; } /** @@ -547,9 +547,9 @@ error: * Returns: The same @decoder argument */ GstVaapiDecoder * -gst_vaapi_decoder_ref(GstVaapiDecoder *decoder) +gst_vaapi_decoder_ref (GstVaapiDecoder * decoder) { - return gst_vaapi_object_ref(decoder); + return gst_vaapi_object_ref (decoder); } /** @@ -560,9 +560,9 @@ gst_vaapi_decoder_ref(GstVaapiDecoder *decoder) * the reference count reaches zero, the decoder will be free'd. */ void -gst_vaapi_decoder_unref(GstVaapiDecoder *decoder) +gst_vaapi_decoder_unref (GstVaapiDecoder * decoder) { - gst_vaapi_object_unref(decoder); + gst_vaapi_object_unref (decoder); } /** @@ -575,10 +575,10 @@ gst_vaapi_decoder_unref(GstVaapiDecoder *decoder) * a valid decoder. However, @new_decoder can be NULL. */ void -gst_vaapi_decoder_replace(GstVaapiDecoder **old_decoder_ptr, - GstVaapiDecoder *new_decoder) +gst_vaapi_decoder_replace (GstVaapiDecoder ** old_decoder_ptr, + GstVaapiDecoder * new_decoder) { - gst_vaapi_object_replace(old_decoder_ptr, new_decoder); + gst_vaapi_object_replace (old_decoder_ptr, new_decoder); } /** @@ -590,11 +590,11 @@ gst_vaapi_decoder_replace(GstVaapiDecoder **old_decoder_ptr, * Return value: the user-defined data associated with the @decoder */ gpointer -gst_vaapi_decoder_get_user_data(GstVaapiDecoder *decoder) +gst_vaapi_decoder_get_user_data (GstVaapiDecoder * decoder) { - g_return_val_if_fail(decoder != NULL, NULL); + g_return_val_if_fail (decoder != NULL, NULL); - return decoder->user_data; + return decoder->user_data; } /** @@ -606,11 +606,11 @@ gst_vaapi_decoder_get_user_data(GstVaapiDecoder *decoder) * attached value with gst_vaapi_decoder_get_user_data() function. */ void -gst_vaapi_decoder_set_user_data(GstVaapiDecoder *decoder, gpointer user_data) +gst_vaapi_decoder_set_user_data (GstVaapiDecoder * decoder, gpointer user_data) { - g_return_if_fail(decoder != NULL); + g_return_if_fail (decoder != NULL); - decoder->user_data = user_data; + decoder->user_data = user_data; } /** @@ -622,11 +622,11 @@ gst_vaapi_decoder_set_user_data(GstVaapiDecoder *decoder, gpointer user_data) * Return value: the #GstVaapiCodec type for @decoder */ GstVaapiCodec -gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder) +gst_vaapi_decoder_get_codec (GstVaapiDecoder * decoder) { - g_return_val_if_fail(decoder != NULL, (GstVaapiCodec)0); + g_return_val_if_fail (decoder != NULL, (GstVaapiCodec) 0); - return decoder->codec; + return decoder->codec; } /** @@ -640,11 +640,11 @@ gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder) * Return value: the #GstVideoCodecState object for @decoder */ GstVideoCodecState * -gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder) +gst_vaapi_decoder_get_codec_state (GstVaapiDecoder * decoder) { - g_return_val_if_fail(decoder != NULL, NULL); + g_return_val_if_fail (decoder != NULL, NULL); - return GST_VAAPI_DECODER_CODEC_STATE(decoder); + return GST_VAAPI_DECODER_CODEC_STATE (decoder); } /** @@ -657,13 +657,13 @@ gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder) * state changes. */ void -gst_vaapi_decoder_set_codec_state_changed_func(GstVaapiDecoder *decoder, +gst_vaapi_decoder_set_codec_state_changed_func (GstVaapiDecoder * decoder, GstVaapiDecoderStateChangedFunc func, gpointer user_data) { - g_return_if_fail(decoder != NULL); + g_return_if_fail (decoder != NULL); - decoder->codec_state_changed_func = func; - decoder->codec_state_changed_data = user_data; + decoder->codec_state_changed_func = func; + decoder->codec_state_changed_data = user_data; } /** @@ -676,9 +676,9 @@ gst_vaapi_decoder_set_codec_state_changed_func(GstVaapiDecoder *decoder, * Return value: the @decoder caps */ GstCaps * -gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder) +gst_vaapi_decoder_get_caps (GstVaapiDecoder * decoder) { - return get_caps(decoder); + return get_caps (decoder); } /** @@ -697,16 +697,16 @@ gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder) * Return value: %TRUE on success */ gboolean -gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf) +gst_vaapi_decoder_put_buffer (GstVaapiDecoder * decoder, GstBuffer * buf) { - g_return_val_if_fail(decoder != NULL, FALSE); + g_return_val_if_fail (decoder != NULL, FALSE); - if (buf) { - if (gst_buffer_get_size(buf) == 0) - return TRUE; - buf = gst_buffer_ref(buf); - } - return push_buffer(decoder, buf); + if (buf) { + if (gst_buffer_get_size (buf) == 0) + return TRUE; + buf = gst_buffer_ref (buf); + } + return push_buffer (decoder, buf); } /** @@ -724,36 +724,36 @@ gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf) * Return value: a #GstVaapiDecoderStatus */ GstVaapiDecoderStatus -gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, - GstVaapiSurfaceProxy **out_proxy_ptr) +gst_vaapi_decoder_get_surface (GstVaapiDecoder * decoder, + GstVaapiSurfaceProxy ** out_proxy_ptr) { - GstVideoCodecFrame *frame; - GstVaapiDecoderStatus status; + GstVideoCodecFrame *frame; + GstVaapiDecoderStatus status; - g_return_val_if_fail(decoder != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(out_proxy_ptr != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (decoder != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (out_proxy_ptr != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - do { - frame = pop_frame(decoder, 0); - while (frame) { - if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(frame)) { - GstVaapiSurfaceProxy * const proxy = frame->user_data; - proxy->timestamp = frame->pts; - proxy->duration = frame->duration; - *out_proxy_ptr = gst_vaapi_surface_proxy_ref(proxy); - gst_video_codec_frame_unref(frame); - return GST_VAAPI_DECODER_STATUS_SUCCESS; - } - gst_video_codec_frame_unref(frame); - frame = pop_frame(decoder, 0); - } - status = decode_step(decoder); - } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); + do { + frame = pop_frame (decoder, 0); + while (frame) { + if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (frame)) { + GstVaapiSurfaceProxy *const proxy = frame->user_data; + proxy->timestamp = frame->pts; + proxy->duration = frame->duration; + *out_proxy_ptr = gst_vaapi_surface_proxy_ref (proxy); + gst_video_codec_frame_unref (frame); + return GST_VAAPI_DECODER_STATUS_SUCCESS; + } + gst_video_codec_frame_unref (frame); + frame = pop_frame (decoder, 0); + } + status = decode_step (decoder); + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); - *out_proxy_ptr = NULL; - return status; + *out_proxy_ptr = NULL; + return status; } /** @@ -777,10 +777,10 @@ gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, * Return value: a #GstVaapiDecoderStatus */ GstVaapiDecoderStatus -gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder, - GstVideoCodecFrame **out_frame_ptr) +gst_vaapi_decoder_get_frame (GstVaapiDecoder * decoder, + GstVideoCodecFrame ** out_frame_ptr) { - return gst_vaapi_decoder_get_frame_with_timeout(decoder, out_frame_ptr, 0); + return gst_vaapi_decoder_get_frame_with_timeout (decoder, out_frame_ptr, 0); } /** @@ -802,262 +802,252 @@ gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder, * Return value: a #GstVaapiDecoderStatus */ GstVaapiDecoderStatus -gst_vaapi_decoder_get_frame_with_timeout(GstVaapiDecoder *decoder, - GstVideoCodecFrame **out_frame_ptr, guint64 timeout) +gst_vaapi_decoder_get_frame_with_timeout (GstVaapiDecoder * decoder, + GstVideoCodecFrame ** out_frame_ptr, guint64 timeout) { - GstVideoCodecFrame *out_frame; + GstVideoCodecFrame *out_frame; - g_return_val_if_fail(decoder != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(out_frame_ptr != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (decoder != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (out_frame_ptr != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - out_frame = pop_frame(decoder, timeout); - if (!out_frame) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + out_frame = pop_frame (decoder, timeout); + if (!out_frame) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; #if !GST_CHECK_VERSION(1,0,0) - if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(out_frame)) { - const guint flags = GST_VAAPI_SURFACE_PROXY_FLAGS(out_frame->user_data); - guint out_flags = 0; + if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) { + const guint flags = GST_VAAPI_SURFACE_PROXY_FLAGS (out_frame->user_data); + guint out_flags = 0; - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF) - out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_TFF; - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF) - out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_RFF; - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) - out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_ONEFIELD; - GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame, out_flags); - } + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF) + out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_TFF; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF) + out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_RFF; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) + out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_ONEFIELD; + GST_VIDEO_CODEC_FRAME_FLAG_SET (out_frame, out_flags); + } #endif - *out_frame_ptr = out_frame; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + *out_frame_ptr = out_frame; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } void -gst_vaapi_decoder_set_picture_size( - GstVaapiDecoder *decoder, - guint width, - guint height -) +gst_vaapi_decoder_set_picture_size (GstVaapiDecoder * decoder, + guint width, guint height) { - GstVideoCodecState * const codec_state = decoder->codec_state; - gboolean size_changed = FALSE; + GstVideoCodecState *const codec_state = decoder->codec_state; + gboolean size_changed = FALSE; - if (codec_state->info.width != width) { - GST_DEBUG("picture width changed to %d", width); - codec_state->info.width = width; - gst_caps_set_simple(codec_state->caps, - "width", G_TYPE_INT, width, NULL); - size_changed = TRUE; - } + if (codec_state->info.width != width) { + GST_DEBUG ("picture width changed to %d", width); + codec_state->info.width = width; + gst_caps_set_simple (codec_state->caps, "width", G_TYPE_INT, width, NULL); + size_changed = TRUE; + } - if (codec_state->info.height != height) { - GST_DEBUG("picture height changed to %d", height); - codec_state->info.height = height; - gst_caps_set_simple(codec_state->caps, - "height", G_TYPE_INT, height, NULL); - size_changed = TRUE; - } + if (codec_state->info.height != height) { + GST_DEBUG ("picture height changed to %d", height); + codec_state->info.height = height; + gst_caps_set_simple (codec_state->caps, "height", G_TYPE_INT, height, NULL); + size_changed = TRUE; + } - if (size_changed) - notify_codec_state_changed(decoder); + if (size_changed) + notify_codec_state_changed (decoder); } void -gst_vaapi_decoder_set_framerate( - GstVaapiDecoder *decoder, - guint fps_n, - guint fps_d -) +gst_vaapi_decoder_set_framerate (GstVaapiDecoder * decoder, + guint fps_n, guint fps_d) { - GstVideoCodecState * const codec_state = decoder->codec_state; + GstVideoCodecState *const codec_state = decoder->codec_state; - if (!fps_n || !fps_d) - return; + if (!fps_n || !fps_d) + return; - if (codec_state->info.fps_n != fps_n || codec_state->info.fps_d != fps_d) { - GST_DEBUG("framerate changed to %u/%u", fps_n, fps_d); - codec_state->info.fps_n = fps_n; - codec_state->info.fps_d = fps_d; - gst_caps_set_simple(codec_state->caps, - "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); - notify_codec_state_changed(decoder); - } + if (codec_state->info.fps_n != fps_n || codec_state->info.fps_d != fps_d) { + GST_DEBUG ("framerate changed to %u/%u", fps_n, fps_d); + codec_state->info.fps_n = fps_n; + codec_state->info.fps_d = fps_d; + gst_caps_set_simple (codec_state->caps, + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); + notify_codec_state_changed (decoder); + } } void -gst_vaapi_decoder_set_pixel_aspect_ratio( - GstVaapiDecoder *decoder, - guint par_n, - guint par_d -) +gst_vaapi_decoder_set_pixel_aspect_ratio (GstVaapiDecoder * decoder, + guint par_n, guint par_d) { - GstVideoCodecState * const codec_state = decoder->codec_state; + GstVideoCodecState *const codec_state = decoder->codec_state; - if (!par_n || !par_d) - return; + if (!par_n || !par_d) + return; - if (codec_state->info.par_n != par_n || codec_state->info.par_d != par_d) { - GST_DEBUG("pixel-aspect-ratio changed to %u/%u", par_n, par_d); - codec_state->info.par_n = par_n; - codec_state->info.par_d = par_d; - gst_caps_set_simple(codec_state->caps, - "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL); - notify_codec_state_changed(decoder); - } + if (codec_state->info.par_n != par_n || codec_state->info.par_d != par_d) { + GST_DEBUG ("pixel-aspect-ratio changed to %u/%u", par_n, par_d); + codec_state->info.par_n = par_n; + codec_state->info.par_d = par_d; + gst_caps_set_simple (codec_state->caps, + "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL); + notify_codec_state_changed (decoder); + } } static const gchar * -gst_interlace_mode_to_string(GstVideoInterlaceMode mode) +gst_interlace_mode_to_string (GstVideoInterlaceMode mode) { - switch (mode) { - case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE: return "progressive"; - case GST_VIDEO_INTERLACE_MODE_INTERLEAVED: return "interleaved"; - case GST_VIDEO_INTERLACE_MODE_MIXED: return "mixed"; - } - return ""; + switch (mode) { + case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE: + return "progressive"; + case GST_VIDEO_INTERLACE_MODE_INTERLEAVED: + return "interleaved"; + case GST_VIDEO_INTERLACE_MODE_MIXED: + return "mixed"; + } + return ""; } void -gst_vaapi_decoder_set_interlace_mode(GstVaapiDecoder *decoder, +gst_vaapi_decoder_set_interlace_mode (GstVaapiDecoder * decoder, GstVideoInterlaceMode mode) { - GstVideoCodecState * const codec_state = decoder->codec_state; + GstVideoCodecState *const codec_state = decoder->codec_state; - if (codec_state->info.interlace_mode != mode) { - GST_DEBUG("interlace mode changed to %s", - gst_interlace_mode_to_string(mode)); - codec_state->info.interlace_mode = mode; - gst_caps_set_simple(codec_state->caps, "interlaced", - G_TYPE_BOOLEAN, mode != GST_VIDEO_INTERLACE_MODE_PROGRESSIVE, NULL); - notify_codec_state_changed(decoder); - } + if (codec_state->info.interlace_mode != mode) { + GST_DEBUG ("interlace mode changed to %s", + gst_interlace_mode_to_string (mode)); + codec_state->info.interlace_mode = mode; + gst_caps_set_simple (codec_state->caps, "interlaced", + G_TYPE_BOOLEAN, mode != GST_VIDEO_INTERLACE_MODE_PROGRESSIVE, NULL); + notify_codec_state_changed (decoder); + } } void -gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced) +gst_vaapi_decoder_set_interlaced (GstVaapiDecoder * decoder, + gboolean interlaced) { - gst_vaapi_decoder_set_interlace_mode(decoder, - (interlaced ? - GST_VIDEO_INTERLACE_MODE_INTERLEAVED : - GST_VIDEO_INTERLACE_MODE_PROGRESSIVE)); + gst_vaapi_decoder_set_interlace_mode (decoder, + (interlaced ? + GST_VIDEO_INTERLACE_MODE_INTERLEAVED : + GST_VIDEO_INTERLACE_MODE_PROGRESSIVE)); } gboolean -gst_vaapi_decoder_ensure_context( - GstVaapiDecoder *decoder, - GstVaapiContextInfo *cip -) +gst_vaapi_decoder_ensure_context (GstVaapiDecoder * decoder, + GstVaapiContextInfo * cip) { - gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height); + gst_vaapi_decoder_set_picture_size (decoder, cip->width, cip->height); - cip->usage = GST_VAAPI_CONTEXT_USAGE_DECODE; - if (decoder->context) { - if (!gst_vaapi_context_reset(decoder->context, cip)) - return FALSE; - } - else { - decoder->context = gst_vaapi_context_new(decoder->display, cip); - if (!decoder->context) - return FALSE; - } - decoder->va_context = gst_vaapi_context_get_id(decoder->context); - return TRUE; + cip->usage = GST_VAAPI_CONTEXT_USAGE_DECODE; + if (decoder->context) { + if (!gst_vaapi_context_reset (decoder->context, cip)) + return FALSE; + } else { + decoder->context = gst_vaapi_context_new (decoder->display, cip); + if (!decoder->context) + return FALSE; + } + decoder->va_context = gst_vaapi_context_get_id (decoder->context); + return TRUE; } void -gst_vaapi_decoder_push_frame(GstVaapiDecoder *decoder, - GstVideoCodecFrame *frame) +gst_vaapi_decoder_push_frame (GstVaapiDecoder * decoder, + GstVideoCodecFrame * frame) { - push_frame(decoder, frame); + push_frame (decoder, frame); } GstVaapiDecoderStatus -gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder) +gst_vaapi_decoder_check_status (GstVaapiDecoder * decoder) { - if (decoder->context && - gst_vaapi_context_get_surface_count(decoder->context) < 1) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (decoder->context && + gst_vaapi_context_get_surface_count (decoder->context) < 1) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } GstVaapiDecoderStatus -gst_vaapi_decoder_parse(GstVaapiDecoder *decoder, - GstVideoCodecFrame *base_frame, GstAdapter *adapter, gboolean at_eos, - guint *got_unit_size_ptr, gboolean *got_frame_ptr) +gst_vaapi_decoder_parse (GstVaapiDecoder * decoder, + GstVideoCodecFrame * base_frame, GstAdapter * adapter, gboolean at_eos, + guint * got_unit_size_ptr, gboolean * got_frame_ptr) { - g_return_val_if_fail(decoder != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(base_frame != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(adapter != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(got_unit_size_ptr != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(got_frame_ptr != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (decoder != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (base_frame != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (adapter != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (got_unit_size_ptr != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (got_frame_ptr != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - return do_parse(decoder, base_frame, adapter, at_eos, - got_unit_size_ptr, got_frame_ptr); + return do_parse (decoder, base_frame, adapter, at_eos, + got_unit_size_ptr, got_frame_ptr); } GstVaapiDecoderStatus -gst_vaapi_decoder_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame) +gst_vaapi_decoder_decode (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame) { - GstVaapiDecoderStatus status; + GstVaapiDecoderStatus status; - g_return_val_if_fail(decoder != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(frame != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(frame->user_data != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (decoder != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (frame != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (frame->user_data != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - status = gst_vaapi_decoder_check_status(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - return do_decode(decoder, frame); -} - -GstVaapiDecoderStatus -gst_vaapi_decoder_flush(GstVaapiDecoder *decoder) -{ - g_return_val_if_fail(decoder != NULL, - GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - - return do_flush(decoder); -} - -GstVaapiDecoderStatus -gst_vaapi_decoder_decode_codec_data(GstVaapiDecoder *decoder) -{ - GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder); - GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder); - GstVaapiDecoderStatus status; - GstMapInfo map_info; - const guchar *buf; - guint buf_size; - - if (!codec_data) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - /* FIXME: add a meaningful error code? */ - if (!klass->decode_codec_data) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - if (!gst_buffer_map(codec_data, &map_info, GST_MAP_READ)) { - GST_ERROR("failed to map buffer"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - - buf = map_info.data; - buf_size = map_info.size; - if (G_LIKELY(buf && buf_size > 0)) - status = klass->decode_codec_data(decoder, buf, buf_size); - else - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - gst_buffer_unmap(codec_data, &map_info); + status = gst_vaapi_decoder_check_status (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; + return do_decode (decoder, frame); +} + +GstVaapiDecoderStatus +gst_vaapi_decoder_flush (GstVaapiDecoder * decoder) +{ + g_return_val_if_fail (decoder != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + + return do_flush (decoder); +} + +GstVaapiDecoderStatus +gst_vaapi_decoder_decode_codec_data (GstVaapiDecoder * decoder) +{ + GstVaapiDecoderClass *const klass = GST_VAAPI_DECODER_GET_CLASS (decoder); + GstBuffer *const codec_data = GST_VAAPI_DECODER_CODEC_DATA (decoder); + GstVaapiDecoderStatus status; + GstMapInfo map_info; + const guchar *buf; + guint buf_size; + + if (!codec_data) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + /* FIXME: add a meaningful error code? */ + if (!klass->decode_codec_data) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (!gst_buffer_map (codec_data, &map_info, GST_MAP_READ)) { + GST_ERROR ("failed to map buffer"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + buf = map_info.data; + buf_size = map_info.size; + if (G_LIKELY (buf && buf_size > 0)) + status = klass->decode_codec_data (decoder, buf, buf_size); + else + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_buffer_unmap (codec_data, &map_info); + return status; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 058255d3ce..f98b345e83 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -35,9 +35,9 @@ G_BEGIN_DECLS #define GST_VAAPI_DECODER(obj) \ ((GstVaapiDecoder *)(obj)) -typedef struct _GstVaapiDecoder GstVaapiDecoder; -typedef void (*GstVaapiDecoderStateChangedFunc)(GstVaapiDecoder *decoder, - const GstVideoCodecState *codec_state, gpointer user_data); +typedef struct _GstVaapiDecoder GstVaapiDecoder; +typedef void (*GstVaapiDecoderStateChangedFunc) (GstVaapiDecoder * decoder, + const GstVideoCodecState * codec_state, gpointer user_data); /** * GstVaapiDecoderStatus: @@ -58,75 +58,76 @@ typedef void (*GstVaapiDecoderStateChangedFunc)(GstVaapiDecoder *decoder, * 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 + 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; GstVaapiDecoder * -gst_vaapi_decoder_ref(GstVaapiDecoder *decoder); +gst_vaapi_decoder_ref (GstVaapiDecoder * decoder); void -gst_vaapi_decoder_unref(GstVaapiDecoder *decoder); +gst_vaapi_decoder_unref (GstVaapiDecoder * decoder); void -gst_vaapi_decoder_replace(GstVaapiDecoder **old_decoder_ptr, - GstVaapiDecoder *new_decoder); +gst_vaapi_decoder_replace (GstVaapiDecoder ** old_decoder_ptr, + GstVaapiDecoder * new_decoder); gpointer -gst_vaapi_decoder_get_user_data(GstVaapiDecoder *decoder); +gst_vaapi_decoder_get_user_data (GstVaapiDecoder * decoder); void -gst_vaapi_decoder_set_user_data(GstVaapiDecoder *decoder, gpointer user_data); +gst_vaapi_decoder_set_user_data (GstVaapiDecoder * decoder, gpointer user_data); GstVaapiCodec -gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder); +gst_vaapi_decoder_get_codec (GstVaapiDecoder * decoder); GstVideoCodecState * -gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder); +gst_vaapi_decoder_get_codec_state (GstVaapiDecoder * decoder); void -gst_vaapi_decoder_set_codec_state_changed_func(GstVaapiDecoder *decoder, +gst_vaapi_decoder_set_codec_state_changed_func (GstVaapiDecoder * decoder, GstVaapiDecoderStateChangedFunc func, gpointer user_data); GstCaps * -gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder); +gst_vaapi_decoder_get_caps (GstVaapiDecoder * decoder); gboolean -gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf); +gst_vaapi_decoder_put_buffer (GstVaapiDecoder * decoder, GstBuffer * buf); GstVaapiDecoderStatus -gst_vaapi_decoder_get_surface(GstVaapiDecoder *decoder, - GstVaapiSurfaceProxy **out_proxy_ptr); +gst_vaapi_decoder_get_surface (GstVaapiDecoder * decoder, + GstVaapiSurfaceProxy ** out_proxy_ptr); GstVaapiDecoderStatus -gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder, - GstVideoCodecFrame **out_frame_ptr); +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); +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); +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); +gst_vaapi_decoder_decode (GstVaapiDecoder * decoder, + GstVideoCodecFrame * frame); GstVaapiDecoderStatus -gst_vaapi_decoder_flush(GstVaapiDecoder *decoder); +gst_vaapi_decoder_flush (GstVaapiDecoder * decoder); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 5590d82f39..5a5cde4dc5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -45,8 +45,8 @@ G_BEGIN_DECLS #define GST_VAAPI_DECODER_GET_CLASS(obj) \ GST_VAAPI_DECODER_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) -typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; - struct _GstVaapiDecoderUnit; +typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; +struct _GstVaapiDecoderUnit; /** * GST_VAAPI_PARSER_STATE: @@ -162,21 +162,22 @@ typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; GstVaapiDecoderPrivate)) typedef enum { - GST_VAAPI_DECODER_STATUS_DROP_FRAME = -2 + 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; +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; }; /** @@ -184,22 +185,23 @@ struct _GstVaapiParserState { * * A VA decoder base instance. */ -struct _GstVaapiDecoder { - /*< private >*/ - GstVaapiMiniObject parent_instance; +struct _GstVaapiDecoder +{ + /*< private >*/ + GstVaapiMiniObject 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; + 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; }; /** @@ -207,86 +209,77 @@ struct _GstVaapiDecoder { * * A VA decoder base class. */ -struct _GstVaapiDecoderClass { - /*< private >*/ - GstVaapiMiniObjectClass parent_class; +struct _GstVaapiDecoderClass +{ + /*< private >*/ + GstVaapiMiniObjectClass parent_class; - gboolean (*create)(GstVaapiDecoder *decoder); - void (*destroy)(GstVaapiDecoder *decoder); - 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 (*decode_codec_data)(GstVaapiDecoder *decoder, - const guchar *buf, guint buf_size); + gboolean (*create) (GstVaapiDecoder * decoder); + void (*destroy) (GstVaapiDecoder * decoder); + 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 (*decode_codec_data) (GstVaapiDecoder * decoder, + const guchar * buf, guint buf_size); }; G_GNUC_INTERNAL GstVaapiDecoder * -gst_vaapi_decoder_new(const GstVaapiDecoderClass *klass, - GstVaapiDisplay *display, GstCaps *caps); +gst_vaapi_decoder_new (const GstVaapiDecoderClass * klass, + GstVaapiDisplay * display, GstCaps * caps); G_GNUC_INTERNAL void -gst_vaapi_decoder_finalize(GstVaapiDecoder *decoder); +gst_vaapi_decoder_finalize (GstVaapiDecoder * decoder); G_GNUC_INTERNAL void -gst_vaapi_decoder_set_picture_size( - GstVaapiDecoder *decoder, - guint width, - guint height -); +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 -); +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 -); +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, +gst_vaapi_decoder_set_interlace_mode (GstVaapiDecoder * decoder, GstVideoInterlaceMode mode); G_GNUC_INTERNAL void -gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced); +gst_vaapi_decoder_set_interlaced (GstVaapiDecoder * decoder, + gboolean interlaced); G_GNUC_INTERNAL gboolean -gst_vaapi_decoder_ensure_context( - GstVaapiDecoder *decoder, - GstVaapiContextInfo *cip -); +gst_vaapi_decoder_ensure_context (GstVaapiDecoder * decoder, + GstVaapiContextInfo * cip); G_GNUC_INTERNAL void -gst_vaapi_decoder_push_frame(GstVaapiDecoder *decoder, - GstVideoCodecFrame *frame); +gst_vaapi_decoder_push_frame (GstVaapiDecoder * decoder, + GstVideoCodecFrame * frame); G_GNUC_INTERNAL GstVaapiDecoderStatus -gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder); +gst_vaapi_decoder_check_status (GstVaapiDecoder * decoder); G_GNUC_INTERNAL GstVaapiDecoderStatus -gst_vaapi_decoder_decode_codec_data(GstVaapiDecoder *decoder); +gst_vaapi_decoder_decode_codec_data (GstVaapiDecoder * decoder); G_END_DECLS From dbf32a25210b1f8443947353704b797dd20e17ee Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Apr 2014 14:16:24 +0200 Subject: [PATCH 1602/3781] decoder: default to YUV 4:2:0 VA surfaces. Cope with context changes to support non-YUV 4:2:0 VA surfaces. Still, make sure all codecs use YUV 4:2:0 output format for now, by default. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 1 + 6 files changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 69bef667ac..71979a6a87 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -890,6 +890,7 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) /* XXX: fix surface size when cropping is implemented */ info.profile = priv->profile; info.entrypoint = priv->entrypoint; + info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; info.width = sps->width; info.height = sps->height; info.ref_frames = get_max_dec_frame_buffering(sps); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 5f680963fd..a45ab8f792 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -191,6 +191,7 @@ ensure_context(GstVaapiDecoderJpeg *decoder) 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 = 2; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 39b6737ed2..3f30f0bf73 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -435,6 +435,7 @@ ensure_context(GstVaapiDecoderMpeg2 *decoder) info.profile = priv->hw_profile; info.entrypoint = entrypoint; + info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; info.width = priv->width; info.height = priv->height; info.ref_frames = 2; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index a4fd9eff07..b461877488 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -222,6 +222,7 @@ ensure_context(GstVaapiDecoderMpeg4 *decoder) 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 = 2; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index bdddbea00b..780e15d600 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -215,6 +215,7 @@ ensure_context(GstVaapiDecoderVC1 *decoder) 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 = 2; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index c7d22858a0..0b371b38df 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -173,6 +173,7 @@ ensure_context (GstVaapiDecoderVp8 * decoder) 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; From fa7f9cd08ca31b594a7c6eddb21601f7567b8d9b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Apr 2014 14:23:11 +0200 Subject: [PATCH 1603/3781] decoder: h264: add support for grayscale encoded clips. Fix support for grayscale encoded video clips, and possibly others if the underlying driver supports the non-YUV 4:2:0 formats. i.e. defer the decision that a surface with the desired chroma format is not supported to the actual VA driver implementation. https://bugzilla.gnome.org/show_bug.cgi?id=728144 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 71979a6a87..f26c9410b8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -851,7 +851,7 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) } chroma_type = gst_vaapi_utils_h264_get_chroma_type(sps->chroma_format_idc); - if (!chroma_type || chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) { + if (!chroma_type) { GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; } From a365dfd269ed79504a5c8b24a6807a793cd3944e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Apr 2014 16:24:01 +0200 Subject: [PATCH 1604/3781] decoder: h264: retain SEI messages until the end of frame. Retain the SEI messages that were parsed from the access unit until we have completely decoded the current frame. This is done so that we can peek at that data whenever necessary during decoding. e.g. for exposing 3D stereoscopic information at a later stage. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 25 ++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index f26c9410b8..6dfcef5a51 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -66,17 +66,31 @@ struct _GstVaapiParserInfoH264 { union { GstH264SPS sps; GstH264PPS pps; + GArray *sei; GstH264SliceHdr slice_hdr; } data; guint state; }; +static void +gst_vaapi_parser_info_h264_finalize(GstVaapiParserInfoH264 *pi) +{ + switch (pi->nalu.type) { + case GST_H264_NAL_SEI: + if (pi->data.sei) { + g_array_unref(pi->data.sei); + pi->data.sei = NULL; + } + break; + } +} + static inline const GstVaapiMiniObjectClass * gst_vaapi_parser_info_h264_class(void) { static const GstVaapiMiniObjectClass GstVaapiParserInfoH264Class = { - sizeof(GstVaapiParserInfoH264), - NULL + .size = sizeof(GstVaapiParserInfoH264), + .finalize = (GDestroyNotify)gst_vaapi_parser_info_h264_finalize }; return &GstVaapiParserInfoH264Class; } @@ -1057,19 +1071,16 @@ parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GArray *sei_messages = NULL; + GArray ** const sei_ptr = &pi->data.sei; GstH264ParserResult result; GST_DEBUG("parse SEI"); - result = gst_h264_parser_parse_sei(priv->parser, &pi->nalu, &sei_messages); + result = gst_h264_parser_parse_sei(priv->parser, &pi->nalu, sei_ptr); if (result != GST_H264_PARSER_OK) { GST_WARNING("failed to parse SEI messages"); - g_array_unref(sei_messages); return get_status(result); } - - g_array_unref(sei_messages); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 5a3e51472d7dd8fd1c5d1e87cf0c73c58a476498 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Apr 2014 19:11:03 +0200 Subject: [PATCH 1605/3781] decoder: h264: fix activation of picture and sequence parameters. At the time the first VCL NAL unit of a primary coded picture is found, and if that NAL unit was parsed to be an SPS or PPS, then the entries in the parser may have been overriden. This means that, when the picture is to be decoded, slice_hdr->pps could point to an invalid (the next) PPS entry. So, one way to solve this problem is to not use the parser PPS and SPS info but rather maintain our own activation chain in the decoder. https://bugzilla.gnome.org/show_bug.cgi?id=724519 https://bugzilla.gnome.org/show_bug.cgi?id=724518 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 214 +++++++++++++++++----- 1 file changed, 164 insertions(+), 50 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 6dfcef5a51..bb6cf8a07a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -154,7 +154,6 @@ enum { struct _GstVaapiPictureH264 { GstVaapiPicture base; - GstH264PPS *pps; GstH264SliceHdr *last_slice_hdr; guint structure; gint32 field_poc[2]; @@ -382,6 +381,10 @@ struct _GstVaapiDecoderH264Private { guint parser_state; guint decoder_state; GstVaapiPictureH264 *current_picture; + GstVaapiParserInfoH264 *sps[GST_H264_MAX_SPS_COUNT]; + GstVaapiParserInfoH264 *active_sps; + GstVaapiParserInfoH264 *pps[GST_H264_MAX_PPS_COUNT]; + GstVaapiParserInfoH264 *active_pps; GstVaapiParserInfoH264 *prev_slice_pi; GstVaapiFrameStore *prev_frame; GstVaapiFrameStore *dpb[16]; @@ -761,8 +764,18 @@ gst_vaapi_decoder_h264_destroy(GstVaapiDecoder *base_decoder) { GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(base_decoder); + GstVaapiDecoderH264Private * const priv = &decoder->priv; + guint i; gst_vaapi_decoder_h264_close(decoder); + + for (i = 0; i < G_N_ELEMENTS(priv->pps); i++) + gst_vaapi_parser_info_h264_replace(&priv->pps[i], NULL); + gst_vaapi_parser_info_h264_replace(&priv->active_pps, NULL); + + for (i = 0; i < G_N_ELEMENTS(priv->sps); i++) + gst_vaapi_parser_info_h264_replace(&priv->sps[i], NULL); + gst_vaapi_parser_info_h264_replace(&priv->active_sps, NULL); } static gboolean @@ -780,6 +793,46 @@ gst_vaapi_decoder_h264_create(GstVaapiDecoder *base_decoder) return TRUE; } +/* Activates the supplied PPS */ +static GstH264PPS * +ensure_pps(GstVaapiDecoderH264 *decoder, GstH264PPS *pps) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiParserInfoH264 * const pi = priv->pps[pps->id]; + + gst_vaapi_parser_info_h264_replace(&priv->active_pps, pi); + return pi ? &pi->data.pps : NULL; +} + +/* Returns the active PPS */ +static inline GstH264PPS * +get_pps(GstVaapiDecoderH264 *decoder) +{ + GstVaapiParserInfoH264 * const pi = decoder->priv.active_pps; + + return pi ? &pi->data.pps : NULL; +} + +/* Activate the supplied SPS */ +static GstH264SPS * +ensure_sps(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiParserInfoH264 * const pi = priv->sps[sps->id]; + + gst_vaapi_parser_info_h264_replace(&priv->active_sps, pi); + return pi ? &pi->data.sps : NULL; +} + +/* Returns the active SPS */ +static inline GstH264SPS * +get_sps(GstVaapiDecoderH264 *decoder) +{ + GstVaapiParserInfoH264 * const pi = decoder->priv.active_sps; + + return pi ? &pi->data.sps : NULL; +} + static void fill_profiles(GstVaapiProfile profiles[16], guint *n_profiles_ptr, GstVaapiProfile profile) @@ -919,7 +972,8 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) } static void -fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps) +fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps, + const GstH264SPS *sps) { guint i; @@ -933,9 +987,9 @@ fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps) } static void -fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps) +fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps, + const GstH264SPS *sps) { - const GstH264SPS * const sps = pps->sequence; guint i, n; /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */ @@ -956,8 +1010,8 @@ static GstVaapiDecoderStatus ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { GstVaapiPicture * const base_picture = &picture->base; - GstH264PPS * const pps = picture->pps; - GstH264SPS * const sps = pps->sequence; + GstH264PPS * const pps = get_pps(decoder); + GstH264SPS * const sps = get_sps(decoder); VAIQMatrixBufferH264 *iq_matrix; base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder); @@ -972,8 +1026,8 @@ ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (sps->chroma_format_idc == 3) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; - fill_iq_matrix_4x4(iq_matrix, pps); - fill_iq_matrix_8x8(iq_matrix, pps); + fill_iq_matrix_4x4(iq_matrix, pps, sps); + fill_iq_matrix_8x8(iq_matrix, pps, sps); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1111,6 +1165,32 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static GstVaapiDecoderStatus +decode_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiParserInfoH264 * const pi = unit->parsed_info; + GstH264SPS * const sps = &pi->data.sps; + + GST_DEBUG("decode SPS"); + + gst_vaapi_parser_info_h264_replace(&priv->sps[sps->id], pi); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiParserInfoH264 * const pi = unit->parsed_info; + GstH264PPS * const pps = &pi->data.pps; + + GST_DEBUG("decode PPS"); + + gst_vaapi_parser_info_h264_replace(&priv->pps[pps->id], pi); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderH264 *decoder) { @@ -1135,8 +1215,7 @@ init_picture_poc_0( ) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264PPS * const pps = slice_hdr->pps; - GstH264SPS * const sps = pps->sequence; + GstH264SPS * const sps = get_sps(decoder); const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); gint32 temp_poc; @@ -1196,8 +1275,7 @@ init_picture_poc_1( ) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264PPS * const pps = slice_hdr->pps; - GstH264SPS * const sps = pps->sequence; + GstH264SPS * const sps = get_sps(decoder); const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); gint32 prev_frame_num_offset, abs_frame_num, expected_poc; guint i; @@ -1279,8 +1357,7 @@ init_picture_poc_2( ) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264PPS * const pps = slice_hdr->pps; - GstH264SPS * const sps = pps->sequence; + GstH264SPS * const sps = get_sps(decoder); const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); gint32 prev_frame_num_offset, temp_poc; @@ -1323,8 +1400,7 @@ init_picture_poc( ) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264PPS * const pps = slice_hdr->pps; - GstH264SPS * const sps = pps->sequence; + GstH264SPS * const sps = get_sps(decoder); switch (sps->pic_order_cnt_type) { case 0: @@ -1408,8 +1484,7 @@ init_picture_refs_pic_num( ) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264PPS * const pps = slice_hdr->pps; - GstH264SPS * const sps = pps->sequence; + GstH264SPS * const sps = get_sps(decoder); const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); guint i; @@ -1764,8 +1839,7 @@ exec_picture_refs_modification_1( ) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264PPS * const pps = slice_hdr->pps; - GstH264SPS * const sps = pps->sequence; + GstH264SPS * const sps = get_sps(decoder); GstH264RefPicListModification *ref_pic_list_modification; guint num_ref_pic_list_modifications; GstVaapiPictureH264 **ref_list; @@ -2080,8 +2154,7 @@ static gboolean exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264PPS * const pps = priv->current_picture->pps; - GstH264SPS * const sps = pps->sequence; + GstH264SPS * const sps = get_sps(decoder); GstVaapiPictureH264 *ref_picture; guint i, m, max_num_ref_frames; @@ -2396,14 +2469,12 @@ vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture, } static gboolean -fill_picture(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi) +fill_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPicture * const base_picture = &picture->base; - GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; - GstH264PPS * const pps = picture->pps; - GstH264SPS * const sps = pps->sequence; + GstH264PPS * const pps = get_pps(decoder); + GstH264SPS * const sps = get_sps(decoder); VAPictureParameterBufferH264 * const pic_param = base_picture->param; guint i, n; @@ -2455,7 +2526,7 @@ fill_picture(GstVaapiDecoderH264 *decoder, COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag); pic_param->pic_fields.value = 0; /* reset all bits */ - pic_param->pic_fields.bits.field_pic_flag = slice_hdr->field_pic_flag; + pic_param->pic_fields.bits.field_pic_flag = GST_VAAPI_PICTURE_IS_INTERLACED(picture); pic_param->pic_fields.bits.reference_pic_flag = GST_VAAPI_PICTURE_IS_REFERENCE(picture); COPY_BFM(pic_fields, pps, entropy_coding_mode_flag); @@ -2542,11 +2613,14 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; - GstH264PPS * const pps = slice_hdr->pps; - GstH264SPS * const sps = pps->sequence; + GstH264PPS * const pps = ensure_pps(decoder, slice_hdr->pps); + GstH264SPS * const sps = ensure_sps(decoder, slice_hdr->pps->sequence); GstVaapiPictureH264 *picture; GstVaapiDecoderStatus status; + g_return_val_if_fail(pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); + g_return_val_if_fail(sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); + status = ensure_context(decoder, sps); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; @@ -2582,8 +2656,6 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) gst_vaapi_picture_set_crop_rect(&picture->base, &crop_rect); } - picture->pps = pps; - status = ensure_quant_matrix(decoder, picture); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { GST_ERROR("failed to reset quantizer matrix"); @@ -2592,7 +2664,7 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) if (!init_picture(decoder, picture, pi)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - if (!fill_picture(decoder, picture, pi)) + if (!fill_picture(decoder, picture)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; priv->decoder_state = pi->state; @@ -2613,8 +2685,8 @@ fill_pred_weight_table(GstVaapiDecoderH264 *decoder, GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr) { VASliceParameterBufferH264 * const slice_param = slice->param; - GstH264PPS * const pps = slice_hdr->pps; - GstH264SPS * const sps = pps->sequence; + GstH264PPS * const pps = get_pps(decoder); + GstH264SPS * const sps = get_sps(decoder); GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table; guint num_weight_tables = 0; gint i, j; @@ -2763,6 +2835,16 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; } + if (!ensure_pps(decoder, slice_hdr->pps)) { + GST_ERROR("failed to activate PPS"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!ensure_sps(decoder, slice_hdr->pps->sequence)) { + GST_ERROR("failed to activate SPS"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + if (!gst_buffer_map(buffer, &map_info, GST_MAP_READ)) { GST_ERROR("failed to map buffer"); return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; @@ -2805,6 +2887,12 @@ decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) priv->decoder_state |= pi->state; switch (pi->nalu.type) { + case GST_H264_NAL_SPS: + status = decode_sps(decoder, unit); + break; + case GST_H264_NAL_PPS: + status = decode_pps(decoder, unit); + break; case GST_H264_NAL_SLICE_IDR: /* fall-through. IDR specifics are handled in init_picture() */ case GST_H264_NAL_SLICE: @@ -2834,11 +2922,11 @@ gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder, GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; GstVaapiDecoderUnit unit; - GstVaapiParserInfoH264 pi; + GstVaapiParserInfoH264 *pi = NULL; GstH264ParserResult result; guint i, ofs, num_sps, num_pps; - unit.parsed_info = π + unit.parsed_info = NULL; if (buf_size < 8) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; @@ -2854,40 +2942,68 @@ gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder, ofs = 6; for (i = 0; i < num_sps; i++) { + pi = gst_vaapi_parser_info_h264_new(); + if (!pi) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + unit.parsed_info = pi; + result = gst_h264_parser_identify_nalu_avc( priv->parser, buf, ofs, buf_size, 2, - &pi.nalu + &pi->nalu ); - if (result != GST_H264_PARSER_OK) - return get_status(result); + if (result != GST_H264_PARSER_OK) { + status = get_status(result); + goto cleanup; + } status = parse_sps(decoder, &unit); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - ofs = pi.nalu.offset + pi.nalu.size; + goto cleanup; + ofs = pi->nalu.offset + pi->nalu.size; + + status = decode_sps(decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + gst_vaapi_parser_info_h264_replace(&pi, NULL); } num_pps = buf[ofs]; ofs++; for (i = 0; i < num_pps; i++) { + pi = gst_vaapi_parser_info_h264_new(); + if (!pi) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + unit.parsed_info = pi; + result = gst_h264_parser_identify_nalu_avc( priv->parser, buf, ofs, buf_size, 2, - &pi.nalu + &pi->nalu ); - if (result != GST_H264_PARSER_OK) - return get_status(result); + if (result != GST_H264_PARSER_OK) { + status = get_status(result); + goto cleanup; + } status = parse_pps(decoder, &unit); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - ofs = pi.nalu.offset + pi.nalu.size; + goto cleanup; + ofs = pi->nalu.offset + pi->nalu.size; + + status = decode_pps(decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + gst_vaapi_parser_info_h264_replace(&pi, NULL); } priv->is_avcC = TRUE; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + +cleanup: + gst_vaapi_parser_info_h264_replace(&pi, NULL); + return status; } static GstVaapiDecoderStatus @@ -3038,8 +3154,6 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, break; case GST_H264_NAL_SPS: case GST_H264_NAL_PPS: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; - /* fall-through */ case GST_H264_NAL_SEI: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; From 3f14745d61ae9b0cbdc5d0493accf32be39773c9 Mon Sep 17 00:00:00 2001 From: Li Xiaowei Date: Thu, 7 Mar 2013 11:32:20 +0800 Subject: [PATCH 1606/3781] decoder: h264: fix slice data bit offset with MVC NAL units. When MVC slice NAL units (coded slice extension and prefix NAL) are present, the number of NAL header bytes is 3, not 1 as usual. Signed-off-by: Li Xiaowei Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index bb6cf8a07a..368eed8ec6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2672,12 +2672,12 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) } static inline guint -get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr) +get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, guint nal_header_bytes) { guint epb_count; epb_count = slice_hdr->n_emulation_prevention_bytes; - return 8 /* nal_unit_type */ + slice_hdr->header_size - epb_count * 8; + return 8 * nal_header_bytes + slice_hdr->header_size - epb_count * 8; } static gboolean @@ -2793,12 +2793,14 @@ fill_RefPicList(GstVaapiDecoderH264 *decoder, static gboolean fill_slice(GstVaapiDecoderH264 *decoder, - GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr) + GstVaapiSlice *slice, GstVaapiParserInfoH264 *pi) { VASliceParameterBufferH264 * const slice_param = slice->param; + GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; /* Fill in VASliceParameterBufferH264 */ - slice_param->slice_data_bit_offset = get_slice_data_bit_offset(slice_hdr); + slice_param->slice_data_bit_offset = + get_slice_data_bit_offset(slice_hdr, pi->nalu.header_bytes); slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice; slice_param->slice_type = slice_hdr->type % 5; slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag; @@ -2858,7 +2860,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } - if (!fill_slice(decoder, slice, slice_hdr)) { + if (!fill_slice(decoder, slice, pi)) { gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(slice)); return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } From 3a6f6f97ab956709d2dfa1b12ea221ecabdcb1ce Mon Sep 17 00:00:00 2001 From: Zhong Cong Date: Tue, 4 Jun 2013 15:01:46 +0800 Subject: [PATCH 1607/3781] decoder: h264: skip SPS extension and auxiliary slice NALs. When NAL units of type 13 (SPS extension) or type 19 (auxiliary slice) are present in a video, decoders shall perform the (optional) decoding process specified for these NAL units or shall ignore them (7.4.1). Implement option 2 (skip) for now, as alpha composition is not supported yet during the decoding process. This fixes decoding of the primary coded video in alphaconformanceG. https://bugzilla.gnome.org/show_bug.cgi?id=703928 https://bugzilla.gnome.org/show_bug.cgi?id=728869 https://bugzilla.gnome.org/show_bug.cgi?id=724518 [skip NAL units earlier, i.e. at parsing time] Signed-off-by: Gwenole Beauchesne --- ext/codecparsers | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index a454f86018..7eb3458a16 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit a454f860186efe61c874cc938aecd7818d2935d1 +Subproject commit 7eb3458a1629bf9d959b0957ffe4363a258fe86f diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 368eed8ec6..c238061380 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -3166,6 +3166,11 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, pi); break; + case GST_H264_NAL_SPS_EXT: + case GST_H264_NAL_SLICE_AUX: + /* skip SPS extension and auxiliary slice for now */ + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + break; default: if (pi->nalu.type >= 14 && pi->nalu.type <= 18) flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; From fac59d6fcfed35ea0ff400ec33d0001172057c06 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 26 Apr 2014 20:21:46 +0200 Subject: [PATCH 1608/3781] decoder: h264: fix initialization of RefPicLists for multiple slices. The initialization of reference picture lists (8.2.4.2) applies to all slices. So, the RefPicList0/1 lists need to be constructed prior to each slice submission to the HW decoder. This fixes decoding of video sequences where frames are encoded with multiple slices of different types, e.g. 4 slices in this order I, P, I, and P. More precisely, CABAST3_Sony_E and CABASTBR3_Sony_B. https://bugzilla.gnome.org/show_bug.cgi?id=724518 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 39 ++++++----------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index c238061380..d392a42659 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2033,7 +2033,6 @@ init_picture_refs( ) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPicture * const base_picture = &picture->base; guint i, num_refs; init_picture_ref_lists(decoder); @@ -2042,12 +2041,12 @@ init_picture_refs( priv->RefPicList0_count = 0; priv->RefPicList1_count = 0; - switch (base_picture->type) { - case GST_VAAPI_PICTURE_TYPE_P: - case GST_VAAPI_PICTURE_TYPE_SP: + switch (slice_hdr->type % 5) { + case GST_H264_P_SLICE: + case GST_H264_SP_SLICE: init_picture_refs_p_slice(decoder, picture, slice_hdr); break; - case GST_VAAPI_PICTURE_TYPE_B: + case GST_H264_B_SLICE: init_picture_refs_b_slice(decoder, picture, slice_hdr); break; default: @@ -2056,16 +2055,16 @@ init_picture_refs( exec_picture_refs_modification(decoder, picture, slice_hdr); - switch (base_picture->type) { - case GST_VAAPI_PICTURE_TYPE_B: + switch (slice_hdr->type % 5) { + case GST_H264_B_SLICE: num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1; for (i = priv->RefPicList1_count; i < num_refs; i++) priv->RefPicList1[i] = NULL; priv->RefPicList1_count = num_refs; // fall-through - case GST_VAAPI_PICTURE_TYPE_P: - case GST_VAAPI_PICTURE_TYPE_SP: + case GST_H264_P_SLICE: + case GST_H264_SP_SLICE: num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1; for (i = priv->RefPicList0_count; i < num_refs; i++) priv->RefPicList0[i] = NULL; @@ -2091,6 +2090,7 @@ init_picture( picture->frame_num_wrap = priv->frame_num; picture->output_flag = TRUE; /* XXX: conformant to Annex A only */ base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; + base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE; /* Reset decoder state for IDR pictures */ if (pi->nalu.type == GST_H264_NAL_SLICE_IDR) { @@ -2099,25 +2099,6 @@ init_picture( dpb_flush(decoder); } - /* Initialize slice type */ - switch (slice_hdr->type % 5) { - case GST_H264_P_SLICE: - base_picture->type = GST_VAAPI_PICTURE_TYPE_P; - break; - case GST_H264_B_SLICE: - base_picture->type = GST_VAAPI_PICTURE_TYPE_B; - break; - case GST_H264_I_SLICE: - base_picture->type = GST_VAAPI_PICTURE_TYPE_I; - break; - case GST_H264_SP_SLICE: - base_picture->type = GST_VAAPI_PICTURE_TYPE_SP; - break; - case GST_H264_SI_SLICE: - base_picture->type = GST_VAAPI_PICTURE_TYPE_SI; - break; - } - /* Initialize picture structure */ if (!slice_hdr->field_pic_flag) base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; @@ -2145,7 +2126,6 @@ init_picture( } init_picture_poc(decoder, picture, slice_hdr); - init_picture_refs(decoder, picture, slice_hdr); return TRUE; } @@ -2860,6 +2840,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } + init_picture_refs(decoder, picture, slice_hdr); if (!fill_slice(decoder, slice, pi)) { gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(slice)); return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; From e95a42ea6e9e7235623c71ea2aa2b13c92380ac2 Mon Sep 17 00:00:00 2001 From: Cong Zhong Date: Fri, 24 May 2013 19:00:54 +0800 Subject: [PATCH 1609/3781] decoder: h264: fix long-term reference picture marking process. Fix reference picture marking process with memory_management_control_op set to 3 and 6, i.e. assign LongTermFrameIdx to a short-term reference picture, or the current picture. This fixes decoding of FRExt_MMCO4_Sony_B. https://bugs.freedesktop.org/show_bug.cgi?id=64624 https://bugzilla.gnome.org/show_bug.cgi?id=724518 [squashed, edited to use GST_VAAPI_PICTURE_IS_COMPLETE() macro] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index d392a42659..b870c92c1a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2264,7 +2264,7 @@ exec_ref_pic_marking_adaptive_mmco_3( ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; gst_vaapi_picture_h264_set_reference(ref_picture, GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, - GST_VAAPI_PICTURE_IS_FRAME(picture)); + GST_VAAPI_PICTURE_IS_COMPLETE(picture)); } /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx @@ -2325,9 +2325,22 @@ exec_ref_pic_marking_adaptive_mmco_6( GstH264RefPicMarking *ref_pic_marking ) { + GstVaapiDecoderH264Private * const priv = &decoder->priv; + guint i; + + for (i = 0; i < priv->long_ref_count; i++) { + if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx) + break; + } + if (i != priv->long_ref_count) { + gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE); + ARRAY_REMOVE_INDEX(priv->long_ref, i); + } + picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; gst_vaapi_picture_h264_set_reference(picture, - GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, FALSE); + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, + GST_VAAPI_PICTURE_IS_COMPLETE(picture)); } /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */ From 72accf53b26a75a2cf9ba14f0a0b66cde69f2b58 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 26 Apr 2014 22:35:49 +0200 Subject: [PATCH 1610/3781] codecparsers: update to gst-vaapi branch commit f44edfc. h264: fix derivation of default scaling lists --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 7eb3458a16..f44edfccf3 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 7eb3458a1629bf9d959b0957ffe4363a258fe86f +Subproject commit f44edfccf3d2dc19e461bdc74a93ad9d808988b0 From 7f5b9edb14245abba7cc1dad430876bee0c2ca75 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Apr 2014 09:42:13 +0200 Subject: [PATCH 1611/3781] codecparsers: update to gst-vaapi-branch commit eaa3f7e. h264: fix parsing of slice groups for map type = 2 --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index f44edfccf3..eaa3f7e72c 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit f44edfccf3d2dc19e461bdc74a93ad9d808988b0 +Subproject commit eaa3f7e72c4e9d8d6ae83b354942d1fcf46aef49 From 8d16aa87b29d397e4ea38009dd35655f5a32e10e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sun, 27 Apr 2014 08:55:24 +0200 Subject: [PATCH 1612/3781] build: fix make dist for codecparsers. --- gst-libs/gst/codecparsers/Makefile.am | 35 +-------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 1feb24151a..56102ed697 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -98,40 +98,7 @@ $(gen_source_h): %.h: $(local_codecparsers_srcdir)/%.h $(top_builddir)/ext/libvpx/libgstcodecparsers_vpx.la: $(MAKE) -C $(top_builddir)/ext/libvpx -# All sources and headers that could be used here -all_source_c = \ - dboolhuff.c \ - gsth264parser.c \ - gstjpegparser.c \ - gstmpeg4parser.c \ - gstmpegvideoparser.c \ - gstvaapilibvpx.c \ - gstvc1parser.c \ - gstvp8parser.c \ - gstvp8rangedecoder.c \ - nalutils.c \ - parserutils.c \ - vp8utils.c \ - $(NULL) - -all_source_h = \ - dboolhuff.h \ - gsth264parser.h \ - gstjpegparser.h \ - gstmpeg4parser.h \ - gstmpegvideoparser.h \ - gstvc1parser.h \ - gstvp8parser.h \ - gstvp8rangedecoder.h \ - nalutils.h \ - parserutils.h \ - vp8utils.h \ - $(NULL) - -EXTRA_DIST = \ - $(all_source_c) \ - $(all_source_h) \ - $(NULL) +EXTRA_DIST = gstvaapilibvpx.c DISTCLEANFILES = $(GENFILES) .timestamp.symlinks From ee6d1b7bd19c2f4dc3793acf0407b554750a4c0f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 29 Apr 2014 13:22:47 +0300 Subject: [PATCH 1613/3781] build: fix conditional compilation of VP8 decoder. https://bugzilla.gnome.org/show_bug.cgi?id=729170 [added check for VASliceParameterBufferBase fields] Signed-off-by: Gwenole Beauchesne --- configure.ac | 14 ++++++++++++-- gst-libs/gst/vaapi/Makefile.am | 11 +++++++++-- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 2 ++ gst/vaapi/gstvaapidecode.c | 2 ++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 12b1d17642..8bcea9f7c5 100644 --- a/configure.ac +++ b/configure.ac @@ -701,6 +701,12 @@ AC_CACHE_CHECK([for JPEG decoding API], LIBS="$saved_LIBS" ]) +dnl Check for va_dec_vp8.h header +saved_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" +AC_CHECK_HEADERS([va/va_dec_vp8.h], [], [], [#include ]) +CPPFLAGS="$saved_CPPFLAGS" + dnl Check for VP8 decoding API (0.34+) USE_VP8_DECODER=0 AC_CACHE_CHECK([for VP8 decoding API], @@ -712,12 +718,16 @@ AC_CACHE_CHECK([for VP8 decoding API], AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include + #ifdef HAVE_VA_VA_DEC_VP8_H #include + #endif ]], [[VAPictureParameterBufferVP8 pic_param; VASliceParameterBufferVP8 slice_param; VAProbabilityDataBufferVP8 prob_data; - VAIQMatrixBufferVP8 iq_matrix;]])], + VAIQMatrixBufferVP8 iq_matrix; + slice_param.slice_data_offset = 0; + slice_param.slice_data_flag = 0;]])], [ac_cv_have_vp8_decoding_api="yes" USE_VP8_DECODER=1], [ac_cv_have_vp8_decoding_api="no"] ) @@ -799,7 +809,7 @@ AC_DEFINE_UNQUOTED(USE_JPEG_DECODER, $USE_JPEG_DECODER, AM_CONDITIONAL(USE_JPEG_DECODER, test $USE_JPEG_DECODER -eq 1) AC_DEFINE_UNQUOTED(USE_VP8_DECODER, $USE_VP8_DECODER, - [Defined to 1 if JPEG decoder is used]) + [Defined to 1 if VP8 decoder is used]) AM_CONDITIONAL(USE_VP8_DECODER, test $USE_VP8_DECODER -eq 1) AC_DEFINE_UNQUOTED(USE_DRM, $USE_DRM, diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 402fff2788..b88f1db6cb 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -56,7 +56,6 @@ libgstvaapi_source_c = \ gstvaapidecoder_objects.c \ gstvaapidecoder_unit.c \ gstvaapidecoder_vc1.c \ - gstvaapidecoder_vp8.c \ gstvaapidisplay.c \ gstvaapidisplaycache.c \ gstvaapifilter.c \ @@ -87,7 +86,6 @@ libgstvaapi_source_h = \ gstvaapidecoder_mpeg2.h \ gstvaapidecoder_mpeg4.h \ gstvaapidecoder_vc1.h \ - gstvaapidecoder_vp8.h \ gstvaapidisplay.h \ gstvaapifilter.h \ gstvaapiimage.h \ @@ -148,6 +146,13 @@ libgstvaapi_source_c += $(libgstvaapi_jpegdec_source_c) libgstvaapi_source_h += $(libgstvaapi_jpegdec_source_h) endif +libgstvaapi_vp8dec_source_c = gstvaapidecoder_vp8.c +libgstvaapi_vp8dec_source_h = gstvaapidecoder_vp8.h +if USE_VP8_DECODER +libgstvaapi_source_c += $(libgstvaapi_vp8dec_source_c) +libgstvaapi_source_h += $(libgstvaapi_vp8dec_source_h) +endif + libgstvaapi_enc_source_c = \ gstvaapicodedbuffer.c \ gstvaapicodedbufferpool.c \ @@ -472,6 +477,8 @@ EXTRA_DIST += \ $(libgstvaapi_enc_source_priv_h) \ $(libgstvaapi_jpegdec_source_c) \ $(libgstvaapi_jpegdec_source_h) \ + $(libgstvaapi_vp8dec_source_c) \ + $(libgstvaapi_vp8dec_source_h) \ $(NULL) CLEANFILES = \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index 0b371b38df..3e078b02f7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -35,7 +35,9 @@ #include "gstvaapiobject_priv.h" #include "gstvaapicompat.h" +#ifdef HAVE_VA_VA_DEC_VP8_H #include +#endif #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9b57480884..aef4864874 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -633,9 +633,11 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps); break; #endif +#if USE_VP8_DECODER case GST_VAAPI_CODEC_VP8: decode->decoder = gst_vaapi_decoder_vp8_new(dpy, caps); break; +#endif default: decode->decoder = NULL; break; From c4cd8e2b36ddf28412a517d94c158c958869be2c Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Thu, 6 Feb 2014 11:14:09 +0000 Subject: [PATCH 1614/3781] build: fix source file modes. A few source files are marked executable in error - fix them https://bugzilla.gnome.org/show_bug.cgi?id=723748 Signed-off-by: Simon Farnsworth --- gst-libs/gst/vaapi/gstvaapifilter.c | 0 gst-libs/gst/vaapi/gstvaapifilter.h | 0 tests/test-filter.c | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 gst-libs/gst/vaapi/gstvaapifilter.c mode change 100755 => 100644 gst-libs/gst/vaapi/gstvaapifilter.h mode change 100755 => 100644 tests/test-filter.c diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c old mode 100755 new mode 100644 diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h old mode 100755 new mode 100644 diff --git a/tests/test-filter.c b/tests/test-filter.c old mode 100755 new mode 100644 From 85a60441fa240a0cf884fcb91bb296636a22efe7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 10 May 2014 06:23:29 +0200 Subject: [PATCH 1615/3781] decoder: h264: properly support grayscale formats. Request the correct chroma format for decoding grayscale streams. i.e. make lookups of the VA chroma format more generic, thus possibly supporting more formats in the future. This means that, if a VA driver doesn't support grayscale formats, it is now going to fail. We cannot safely assume that maybe grayscale was implemented on top of some YUV 4:2:0 with the chroma components all set to 0x80. --- gst-libs/gst/vaapi/gstvaapicontext.c | 5 ++++- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils.c | 23 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 5 +++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 45ecf9c9c4..e79c30f3f9 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -195,8 +195,11 @@ context_create (GstVaapiContext * context) attrib->type = VAConfigAttribRTFormat; if (!context_get_attribute (context, attrib->type, &value)) goto cleanup; - if (!(value & va_chroma_format)) + 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++; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index b870c92c1a..d12cbca462 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -957,7 +957,7 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) /* XXX: fix surface size when cropping is implemented */ info.profile = priv->profile; info.entrypoint = priv->entrypoint; - info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + info.chroma_type = priv->chroma_type; info.width = sps->width; info.height = sps->height; info.ref_frames = get_max_dec_frame_buffering(sps); diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 87923cc49b..63e46910a3 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -208,6 +208,29 @@ string_of_VADisplayAttributeType (VADisplayAttribType attribute_type) return ""; } +/* Return a string representation of a VA chroma format */ +const gchar * +string_of_va_chroma_format (guint chroma_format) +{ + switch (chroma_format) { +#define MAP(value) \ + STRCASEP(VA_RT_FORMAT_, value) + MAP (YUV420); + MAP (YUV422); + MAP (YUV444); +#if VA_CHECK_VERSION(0,34,0) + MAP (YUV400); + MAP (RGB16); + MAP (RGB32); + MAP (RGBP); +#endif +#undef MAP + default: + break; + } + return ""; +} + const gchar * string_of_VARateControl (guint rate_control) { diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index fb5b1e49c1..e5f85037ce 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -71,6 +71,11 @@ G_GNUC_INTERNAL const gchar * string_of_VADisplayAttributeType (VADisplayAttribType attribute_type); +/* Return a string representation of a VA chroma format */ +G_GNUC_INTERNAL +const gchar * +string_of_va_chroma_format (guint chroma_format); + G_GNUC_INTERNAL const gchar * string_of_VARateControl (guint rate_control); From c12d80eb88359a4a5babe8ca3a7fd82397c7838a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 12 May 2014 19:23:04 +0200 Subject: [PATCH 1616/3781] decoder: h264: fix assignment of LongTermFrameIdx. Complement fix committed as e95a42e. The H.264 AVC standard has to say: if the field is part of a reference frame or a complementary reference field pair, and the other field of the same reference frame or complementary reference field pair is also marked as "used for long-term reference", the reference frame or complementary reference field pair is also marked as "used for long-term reference" and assigned LongTermFrameIdx equal to long_term_frame_idx. This fixes decoding of MR9_BT_B in strict mode. https://bugs.freedesktop.org/show_bug.cgi?id=64624 https://bugzilla.gnome.org/show_bug.cgi?id=724518 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index d12cbca462..0f10b9eeea 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2240,7 +2240,7 @@ exec_ref_pic_marking_adaptive_mmco_3( ) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 *ref_picture; + GstVaapiPictureH264 *ref_picture, *other_field; gint32 i, picNumX; for (i = 0; i < priv->long_ref_count; i++) { @@ -2265,6 +2265,12 @@ exec_ref_pic_marking_adaptive_mmco_3( gst_vaapi_picture_h264_set_reference(ref_picture, GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, GST_VAAPI_PICTURE_IS_COMPLETE(picture)); + + /* Assign LongTermFrameIdx to the other field if it was also + marked as "used for long-term reference */ + other_field = ref_picture->other_field; + if (other_field && GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(other_field)) + other_field->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; } /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx @@ -2326,6 +2332,7 @@ exec_ref_pic_marking_adaptive_mmco_6( ) { GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiPictureH264 *other_field; guint i; for (i = 0; i < priv->long_ref_count; i++) { @@ -2341,6 +2348,12 @@ exec_ref_pic_marking_adaptive_mmco_6( gst_vaapi_picture_h264_set_reference(picture, GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, GST_VAAPI_PICTURE_IS_COMPLETE(picture)); + + /* Assign LongTermFrameIdx to the other field if it was also + marked as "used for long-term reference */ + other_field = (GstVaapiPictureH264 *)picture->base.parent_picture; + if (other_field && GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(other_field)) + other_field->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; } /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */ From 906a561c26578e17cae77be665934b498a814695 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 3 May 2014 15:47:53 +0200 Subject: [PATCH 1617/3781] context: reset VA context if VA surfaces set changed. It is a requirement from VA-API specification that the VA context got from vaCreateContext(), for decoding purposes, binds the supplied set of VA surfaces. This means that if the set of VA surfaces is to be changed for the current decode session, then the VA context needs to be recreated with the new set of VA surfaces. --- gst-libs/gst/vaapi/gstvaapicontext.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index e79c30f3f9..27efdd9ad2 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -399,6 +399,9 @@ gst_vaapi_context_reset (GstVaapiContext * context, } 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) + reset_config = TRUE; } if (reset_surfaces) From 446aa9acf8eb2b142121e7b3be65fd35df324724 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 3 May 2014 15:56:51 +0200 Subject: [PATCH 1618/3781] context: allow dynamic growth of VA surfaces pool. Add support for dynamic growth of the VA surfaces pool. For decoding, this implies the recreation of the underlying VA context, as per the requirement from VA-API. Besides, only increases are supported, not shrinks. --- gst-libs/gst/vaapi/gstvaapicontext.c | 55 ++++++++++++++++++---------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 27efdd9ad2..185ed7fdb8 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -47,6 +47,9 @@ /* 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) + static void unref_surface_cb (GstVaapiSurface * surface) { @@ -105,16 +108,34 @@ context_destroy (GstVaapiContext * context) } } +static gboolean +context_ensure_surfaces (GstVaapiContext * context) +{ + const GstVaapiContextInfo *const cip = &context->info; + const guint num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; + GstVaapiSurface *surface; + guint i; + + for (i = context->surfaces->len; i < num_surfaces; i++) { + surface = gst_vaapi_surface_new (GST_VAAPI_OBJECT_DISPLAY (context), + cip->chroma_type, cip->width, cip->height); + if (!surface) + return FALSE; + gst_vaapi_surface_set_parent_context (surface, context); + g_ptr_array_add (context->surfaces, surface); + if (!gst_vaapi_video_pool_add_object (context->surfaces_pool, surface)) + return FALSE; + } + gst_vaapi_video_pool_set_capacity (context->surfaces_pool, num_surfaces); + return TRUE; +} + static gboolean context_create_surfaces (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; GstVideoInfo vi; - GstVaapiSurface *surface; - guint i, num_surfaces; - - /* Number of scratch surfaces beyond those used as reference */ - const guint SCRATCH_SURFACES_COUNT = 4; + guint num_surfaces; if (!gst_vaapi_context_overlay_reset (context)) return FALSE; @@ -135,19 +156,7 @@ context_create_surfaces (GstVaapiContext * context) if (!context->surfaces_pool) return FALSE; } - gst_vaapi_video_pool_set_capacity (context->surfaces_pool, num_surfaces); - - for (i = context->surfaces->len; i < num_surfaces; i++) { - surface = gst_vaapi_surface_new (GST_VAAPI_OBJECT_DISPLAY (context), - cip->chroma_type, cip->width, cip->height); - if (!surface) - return FALSE; - gst_vaapi_surface_set_parent_context (surface, context); - g_ptr_array_add (context->surfaces, surface); - if (!gst_vaapi_video_pool_add_object (context->surfaces_pool, surface)) - return FALSE; - } - return TRUE; + return context_ensure_surfaces (context); } static gboolean @@ -370,6 +379,7 @@ gst_vaapi_context_reset (GstVaapiContext * context, { GstVaapiContextInfo *const cip = &context->info; gboolean reset_surfaces = FALSE, reset_config = FALSE; + gboolean grow_surfaces = FALSE; GstVaapiChromaType chroma_type; chroma_type = new_cip->chroma_type ? new_cip->chroma_type : @@ -392,6 +402,11 @@ gst_vaapi_context_reset (GstVaapiContext * context, 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; @@ -400,7 +415,7 @@ gst_vaapi_context_reset (GstVaapiContext * context, 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) + if (reset_surfaces || grow_surfaces) reset_config = TRUE; } @@ -411,6 +426,8 @@ gst_vaapi_context_reset (GstVaapiContext * context, if (reset_surfaces && !context_create_surfaces (context)) return FALSE; + else if (grow_surfaces && !context_ensure_surfaces (context)) + return FALSE; if (reset_config && !context_create (context)) return FALSE; return TRUE; From 71053228b3dc9292130c0108ea2004cd40d8e0bc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Mar 2014 14:50:14 +0100 Subject: [PATCH 1619/3781] display: make cache maintenance really MT-safe. Make sure to initialize one GstVaapiDisplay at a time, even in threaded environments. This makes sure the display cache is also consistent during the whole display creation process. In the former implementation, there were risks that display cache got updated in another thread. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 69 ++++++++++------ gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 13 +-- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 14 +++- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 10 +-- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 13 +-- gst-libs/gst/vaapi/gstvaapidisplaycache.c | 83 ++++++++------------ gst-libs/gst/vaapi/gstvaapidisplaycache.h | 16 ++-- 7 files changed, 106 insertions(+), 112 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 6cdc9edb38..776ab68b8f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -85,7 +85,8 @@ enum N_PROPERTIES }; -static GstVaapiDisplayCache *g_display_cache = NULL; +static GstVaapiDisplayCache *g_display_cache; +static GMutex g_display_cache_lock; static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; @@ -122,29 +123,27 @@ libgstvaapi_init_once (void) g_once_init_leave (&g_once, TRUE); } -static inline GstVaapiDisplayCache * +static GstVaapiDisplayCache * get_display_cache (void) { + GstVaapiDisplayCache *cache = NULL; + + g_mutex_lock (&g_display_cache_lock); if (!g_display_cache) g_display_cache = gst_vaapi_display_cache_new (); - return g_display_cache; -} - -GstVaapiDisplayCache * -gst_vaapi_display_get_cache (void) -{ - return get_display_cache (); + if (g_display_cache) + cache = gst_vaapi_display_cache_ref (g_display_cache); + g_mutex_unlock (&g_display_cache_lock); + return cache; } static void free_display_cache (void) { - if (!g_display_cache) - return; - if (gst_vaapi_display_cache_get_size (g_display_cache) > 0) - return; - gst_vaapi_display_cache_free (g_display_cache); - g_display_cache = NULL; + g_mutex_lock (&g_display_cache_lock); + if (g_display_cache && gst_vaapi_display_cache_is_empty (g_display_cache)) + gst_vaapi_display_cache_replace (&g_display_cache, NULL); + g_mutex_unlock (&g_display_cache_lock); } /* GstVaapiDisplayType enumerations */ @@ -857,20 +856,21 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) gst_vaapi_display_replace_internal (&priv->parent, NULL); - if (g_display_cache) { - gst_vaapi_display_cache_remove (get_display_cache (), display); - free_display_cache (); - } + g_mutex_lock (&g_display_cache_lock); + if (priv->cache) + gst_vaapi_display_cache_remove (priv->cache, display); + g_mutex_unlock (&g_display_cache_lock); + gst_vaapi_display_cache_replace (&priv->cache, NULL); + free_display_cache (); } static gboolean -gst_vaapi_display_create (GstVaapiDisplay * display, +gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, GstVaapiDisplayInitType init_type, gpointer init_value) { GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); const GstVaapiDisplayClass *const klass = GST_VAAPI_DISPLAY_GET_CLASS (display); - GstVaapiDisplayCache *cache; gint major_version, minor_version; VAStatus status; GstVaapiDisplayInfo info; @@ -909,10 +909,7 @@ gst_vaapi_display_create (GstVaapiDisplay * display, if (!priv->display) return FALSE; - cache = get_display_cache (); - if (!cache) - return FALSE; - cached_info = gst_vaapi_display_cache_lookup_by_va_display (cache, + cached_info = gst_vaapi_display_cache_lookup_by_va_display (priv->cache, info.va_display); if (cached_info) { gst_vaapi_display_replace_internal (&priv->parent, cached_info->display); @@ -927,12 +924,32 @@ gst_vaapi_display_create (GstVaapiDisplay * display, } if (!cached_info) { - if (!gst_vaapi_display_cache_add (cache, &info)) + if (!gst_vaapi_display_cache_add (priv->cache, &info)) return FALSE; } return TRUE; } +static gboolean +gst_vaapi_display_create (GstVaapiDisplay * display, + GstVaapiDisplayInitType init_type, gpointer init_value) +{ + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + GstVaapiDisplayCache *cache; + gboolean success; + + cache = get_display_cache (); + if (!cache) + return FALSE; + gst_vaapi_display_cache_replace (&priv->cache, cache); + gst_vaapi_display_cache_unref (cache); + + g_mutex_lock (&g_display_cache_lock); + success = gst_vaapi_display_create_unlocked (display, init_type, init_value); + g_mutex_unlock (&g_display_cache_lock); + return success; +} + static void gst_vaapi_display_lock_default (GstVaapiDisplay * display) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index da4fe2a1a9..9114bfc478 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -219,12 +219,9 @@ gst_vaapi_display_drm_open_display (GstVaapiDisplay * display, { GstVaapiDisplayDRMPrivate *const priv = GST_VAAPI_DISPLAY_DRM_PRIVATE (display); - GstVaapiDisplayCache *cache; + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); const GstVaapiDisplayInfo *info; - cache = gst_vaapi_display_get_cache (); - g_return_val_if_fail (cache != NULL, FALSE); - if (!set_device_path (display, name)) return FALSE; @@ -271,15 +268,11 @@ gst_vaapi_display_drm_get_display_info (GstVaapiDisplay * display, { GstVaapiDisplayDRMPrivate *const priv = GST_VAAPI_DISPLAY_DRM_PRIVATE (display); - GstVaapiDisplayCache *cache; + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); const GstVaapiDisplayInfo *cached_info; /* Return any cached info even if child has its own VA display */ - cache = gst_vaapi_display_get_cache (); - if (!cache) - return FALSE; - cached_info = - gst_vaapi_display_cache_lookup_by_native_display (cache, + cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache, GINT_TO_POINTER (priv->drm_device), GST_VAAPI_DISPLAY_TYPES (display)); if (cached_info) { *info = *cached_info; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 92d466aa8c..35f911320c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -128,9 +128,20 @@ typedef void (*GstVaapiDisplayGetSizeMFunc) (GstVaapiDisplay * display, #define GST_VAAPI_DISPLAY_HAS_VPP(display) \ gst_vaapi_display_has_video_processing(GST_VAAPI_DISPLAY_CAST(display)) +/** + * GST_VAAPI_DISPLAY_CACHE: + * @display: a @GstVaapiDisplay + * + * Returns the #GstVaapiDisplayCache attached to the supplied @display object. + */ +#undef GST_VAAPI_DISPLAY_GET_CACHE +#define GST_VAAPI_DISPLAY_GET_CACHE(display) \ + (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->cache) + struct _GstVaapiDisplayPrivate { GstVaapiDisplay *parent; + GstVaapiDisplayCache *cache; GRecMutex mutex; GstVaapiDisplayType display_type; VADisplay display; @@ -214,9 +225,6 @@ GstVaapiDisplay * gst_vaapi_display_new (const GstVaapiDisplayClass * klass, GstVaapiDisplayInitType init_type, gpointer init_value); -GstVaapiDisplayCache * -gst_vaapi_display_get_cache (void); - static inline guint gst_vaapi_display_get_display_types (GstVaapiDisplay * display) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 4ed6dbe1d4..d7c5c1ffb3 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -204,12 +204,9 @@ gst_vaapi_display_wayland_open_display (GstVaapiDisplay * display, { GstVaapiDisplayWaylandPrivate *const priv = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - GstVaapiDisplayCache *cache; + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); const GstVaapiDisplayInfo *info; - cache = gst_vaapi_display_get_cache (); - g_return_val_if_fail (cache != NULL, FALSE); - if (!set_display_name (display, name)) return FALSE; @@ -266,13 +263,10 @@ gst_vaapi_display_wayland_get_display_info (GstVaapiDisplay * display, { GstVaapiDisplayWaylandPrivate *const priv = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - GstVaapiDisplayCache *cache; + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); const GstVaapiDisplayInfo *cached_info; /* Return any cached info even if child has its own VA display */ - cache = gst_vaapi_display_get_cache (); - if (!cache) - return FALSE; cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache, priv->wl_display, GST_VAAPI_DISPLAY_TYPES (display)); if (cached_info) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index f97d79498d..ba9ea26417 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -177,12 +177,9 @@ gst_vaapi_display_x11_open_display (GstVaapiDisplay * base_display, { GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11_CAST (base_display); GstVaapiDisplayX11Private *const priv = &display->priv; - GstVaapiDisplayCache *cache; + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); const GstVaapiDisplayInfo *info; - cache = gst_vaapi_display_get_cache (); - g_return_val_if_fail (cache != NULL, FALSE); - if (!set_display_name (display, name)) return FALSE; @@ -258,15 +255,11 @@ gst_vaapi_display_x11_get_display_info (GstVaapiDisplay * display, { GstVaapiDisplayX11Private *const priv = GST_VAAPI_DISPLAY_X11_PRIVATE (display); - GstVaapiDisplayCache *cache; + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); const GstVaapiDisplayInfo *cached_info; /* Return any cached info even if child has its own VA display */ - cache = gst_vaapi_display_get_cache (); - if (!cache) - return FALSE; - cached_info = - gst_vaapi_display_cache_lookup_by_native_display (cache, + cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache, priv->x11_display, GST_VAAPI_DISPLAY_TYPES (display)); if (cached_info) { *info = *cached_info; diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index 29156c2366..e8c08ac4e9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -36,7 +36,7 @@ struct _CacheEntry struct _GstVaapiDisplayCache { - GMutex mutex; + GstVaapiMiniObject parent_instance; GList *list; }; @@ -103,7 +103,6 @@ cache_lookup_1 (GstVaapiDisplayCache * cache, GCompareFunc func, { GList *l; - g_mutex_lock (&cache->mutex); for (l = cache->list; l != NULL; l = l->next) { GstVaapiDisplayInfo *const info = &((CacheEntry *) l->data)->info; if (!is_compatible_display_type (info->display_type, display_types)) @@ -111,7 +110,6 @@ cache_lookup_1 (GstVaapiDisplayCache * cache, GCompareFunc func, if (func (info, data)) break; } - g_mutex_unlock (&cache->mutex); return l; } @@ -161,6 +159,30 @@ compare_display_name (gconstpointer a, gconstpointer b) return strcmp (info->display_name, display_name) == 0; } +static void +gst_vaapi_display_cache_finalize (GstVaapiDisplayCache * cache) +{ + GList *l; + + if (!cache->list) + return; + + for (l = cache->list; l != NULL; l = l->next) + cache_entry_free (l->data); + g_list_free (cache->list); + cache->list = NULL; +} + +static const GstVaapiMiniObjectClass * +gst_vaapi_display_cache_class (void) +{ + static const GstVaapiMiniObjectClass GstVaapiDisplayCacheClass = { + .size = sizeof (GstVaapiDisplayCache), + .finalize = (GDestroyNotify) gst_vaapi_display_cache_finalize + }; + return &GstVaapiDisplayCacheClass; +} + /** * gst_vaapi_display_cache_new: * @@ -171,59 +193,24 @@ compare_display_name (gconstpointer a, gconstpointer b) GstVaapiDisplayCache * gst_vaapi_display_cache_new (void) { - GstVaapiDisplayCache *cache; - - cache = g_slice_new0 (GstVaapiDisplayCache); - if (!cache) - return NULL; - - g_mutex_init (&cache->mutex); - return cache; + return (GstVaapiDisplayCache *) + gst_vaapi_mini_object_new0 (gst_vaapi_display_cache_class ()); } /** - * gst_vaapi_display_cache_new: - * @cache: the #GstVaapiDisplayCache to destroy - * - * Destroys a VA display cache. - */ -void -gst_vaapi_display_cache_free (GstVaapiDisplayCache * cache) -{ - GList *l; - - if (!cache) - return; - - if (cache->list) { - for (l = cache->list; l != NULL; l = l->next) - cache_entry_free (l->data); - g_list_free (cache->list); - cache->list = NULL; - } - g_mutex_clear (&cache->mutex); - g_slice_free (GstVaapiDisplayCache, cache); -} - -/** - * gst_vaapi_display_cache_get_size: + * gst_vaapi_display_cache_is_empty: * @cache: the #GstVaapiDisplayCache * - * Gets the size of the display cache @cache. + * Checks whether the display cache @cache is empty. * - * Return value: the size of the display cache + * Return value: %TRUE if the display @cache is empty, %FALSE otherwise. */ -guint -gst_vaapi_display_cache_get_size (GstVaapiDisplayCache * cache) +gboolean +gst_vaapi_display_cache_is_empty (GstVaapiDisplayCache * cache) { - guint size; - g_return_val_if_fail (cache != NULL, 0); - g_mutex_lock (&cache->mutex); - size = g_list_length (cache->list); - g_mutex_unlock (&cache->mutex); - return size; + return cache->list == NULL; } /** @@ -249,9 +236,7 @@ gst_vaapi_display_cache_add (GstVaapiDisplayCache * cache, if (!entry) return FALSE; - g_mutex_lock (&cache->mutex); cache->list = g_list_prepend (cache->list, entry); - g_mutex_unlock (&cache->mutex); return TRUE; } @@ -274,9 +259,7 @@ gst_vaapi_display_cache_remove (GstVaapiDisplayCache * cache, return; cache_entry_free (m->data); - g_mutex_lock (&cache->mutex); cache->list = g_list_delete_link (cache->list, m); - g_mutex_unlock (&cache->mutex); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h index 62f7b901c3..f7274327f1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.h +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.h @@ -25,6 +25,7 @@ #include "libgstvaapi_priv_check.h" #include +#include "gstvaapiminiobject.h" typedef struct _GstVaapiDisplayCache GstVaapiDisplayCache; @@ -32,13 +33,18 @@ G_GNUC_INTERNAL GstVaapiDisplayCache * gst_vaapi_display_cache_new (void); -G_GNUC_INTERNAL -void -gst_vaapi_display_cache_free (GstVaapiDisplayCache * cache); +#define gst_vaapi_display_cache_ref(cache) \ + ((GstVaapiDisplayCache *) gst_vaapi_mini_object_ref ( \ + GST_VAAPI_MINI_OBJECT (cache))) +#define gst_vaapi_display_cache_unref(cache) \ + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (cache)) +#define gst_vaapi_display_cache_replace(old_cache_ptr, new_cache) \ + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_cache_ptr), \ + GST_VAAPI_MINI_OBJECT (new_cache)) G_GNUC_INTERNAL -guint -gst_vaapi_display_cache_get_size (GstVaapiDisplayCache * cache); +gboolean +gst_vaapi_display_cache_is_empty (GstVaapiDisplayCache * cache); G_GNUC_INTERNAL gboolean From c0993182bd13afbf1362d1a7407effd01cbfcaa2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 20 May 2014 11:36:40 +0200 Subject: [PATCH 1620/3781] display: add utility function to query VA driver name. Add gst_vaapi_display_get_vendor_string() helper function to query the underlying VA driver name. The display object owns the resulting string, so it shall not be deallocated. That function is thread-safe. It could be used for debugging purposes, for instance. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 41 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 3 ++ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 1 + 3 files changed, 45 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 776ab68b8f..64f02455d5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -854,6 +854,9 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) klass->close_display (display); } + g_free (priv->vendor_string); + priv->vendor_string = NULL; + gst_vaapi_display_replace_internal (&priv->parent, NULL); g_mutex_lock (&g_display_cache_lock); @@ -2031,3 +2034,41 @@ set_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat v) return FALSE; return TRUE; } + +/* Ensures the VA driver vendor string was copied */ +static gboolean +ensure_vendor_string (GstVaapiDisplay * display) +{ + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + const gchar *vendor_string; + + GST_VAAPI_DISPLAY_LOCK (display); + if (!priv->vendor_string) { + vendor_string = vaQueryVendorString (priv->display); + if (vendor_string) + priv->vendor_string = g_strdup (vendor_string); + } + GST_VAAPI_DISPLAY_UNLOCK (display); + return priv->vendor_string != NULL; +} + +/** + * gst_vaapi_display_get_vendor_string: + * @display: a #GstVaapiDisplay + * + * Returns the VA driver vendor string attached to the supplied VA @display. + * The @display owns the vendor string, do *not* de-allocate it. + * + * This function is thread safe. + * + * Return value: the current #GstVaapiRotation value + */ +const gchar * +gst_vaapi_display_get_vendor_string (GstVaapiDisplay * display) +{ + g_return_val_if_fail (display != NULL, NULL); + + if (!ensure_vendor_string (display)) + return NULL; + return display->priv.vendor_string; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index e925a185b7..182350eae0 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -198,6 +198,9 @@ gboolean gst_vaapi_display_set_rotation (GstVaapiDisplay * display, GstVaapiRotation rotation); +const gchar * +gst_vaapi_display_get_vendor_string (GstVaapiDisplay * display); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 35f911320c..747387a27d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -156,6 +156,7 @@ struct _GstVaapiDisplayPrivate GArray *image_formats; GArray *subpicture_formats; GArray *properties; + gchar *vendor_string; guint use_foreign_display:1; guint has_vpp:1; guint has_profiles:1; From a571350dee5ac24f69120adfc91f785e0eeb603a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 2 May 2014 22:40:16 +0200 Subject: [PATCH 1621/3781] decoder: h264: minor clean-ups. Make init_picture_ref_lists() more consistent with other functions related to the reference marking process by supplying the current picture as argument. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 49 +++++++++++++---------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 0f10b9eeea..2c8ce8d7ce 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -128,12 +128,13 @@ gst_vaapi_parser_info_h264_new(void) * reference picture (short-term reference or long-term reference) */ enum { - GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0), + GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0), + GST_VAAPI_PICTURE_FLAG_REFERENCE2 = (GST_VAAPI_PICTURE_FLAG_LAST << 1), GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = ( GST_VAAPI_PICTURE_FLAG_REFERENCE), GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = ( - GST_VAAPI_PICTURE_FLAG_REFERENCE | (GST_VAAPI_PICTURE_FLAG_LAST << 1)), + GST_VAAPI_PICTURE_FLAG_REFERENCE | GST_VAAPI_PICTURE_FLAG_REFERENCE2), GST_VAAPI_PICTURE_FLAGS_REFERENCE = ( GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE | GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE), @@ -152,6 +153,9 @@ enum { GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \ GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE) +#define GST_VAAPI_PICTURE_H264(picture) \ + ((GstVaapiPictureH264 *)(picture)) + struct _GstVaapiPictureH264 { GstVaapiPicture base; GstH264SliceHdr *last_slice_hdr; @@ -1927,7 +1931,7 @@ exec_picture_refs_modification_1( } /* 8.2.4.3.2 - Long-term reference pictures */ - else { + else if (l->modification_of_pic_nums_idc == 2) { for (j = num_refs; j > ref_list_idx; j--) ref_list[j] = ref_list[j - 1]; @@ -1979,39 +1983,40 @@ exec_picture_refs_modification( } static void -init_picture_ref_lists(GstVaapiDecoderH264 *decoder) +init_picture_ref_lists(GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture) { GstVaapiDecoderH264Private * const priv = &decoder->priv; guint i, j, short_ref_count, long_ref_count; short_ref_count = 0; long_ref_count = 0; - if (GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) { + if (GST_VAAPI_PICTURE_IS_FRAME(picture)) { for (i = 0; i < priv->dpb_count; i++) { GstVaapiFrameStore * const fs = priv->dpb[i]; - GstVaapiPictureH264 *picture; + GstVaapiPictureH264 *pic; if (!gst_vaapi_frame_store_has_frame(fs)) continue; - picture = fs->buffers[0]; - if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) - priv->short_ref[short_ref_count++] = picture; - else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) - priv->long_ref[long_ref_count++] = picture; - picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - picture->other_field = fs->buffers[1]; + pic = fs->buffers[0]; + if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(pic)) + priv->short_ref[short_ref_count++] = pic; + else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(pic)) + priv->long_ref[long_ref_count++] = pic; + pic->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + pic->other_field = fs->buffers[1]; } } else { for (i = 0; i < priv->dpb_count; i++) { GstVaapiFrameStore * const fs = priv->dpb[i]; for (j = 0; j < fs->num_buffers; j++) { - GstVaapiPictureH264 * const picture = fs->buffers[j]; - if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) - priv->short_ref[short_ref_count++] = picture; - else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) - priv->long_ref[long_ref_count++] = picture; - picture->structure = picture->base.structure; - picture->other_field = fs->buffers[j ^ 1]; + GstVaapiPictureH264 * const pic = fs->buffers[j]; + if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(pic)) + priv->short_ref[short_ref_count++] = pic; + else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(pic)) + priv->long_ref[long_ref_count++] = pic; + pic->structure = pic->base.structure; + pic->other_field = fs->buffers[j ^ 1]; } } } @@ -2035,7 +2040,7 @@ init_picture_refs( GstVaapiDecoderH264Private * const priv = &decoder->priv; guint i, num_refs; - init_picture_ref_lists(decoder); + init_picture_ref_lists(decoder, picture); init_picture_refs_pic_num(decoder, picture, slice_hdr); priv->RefPicList0_count = 0; @@ -2351,7 +2356,7 @@ exec_ref_pic_marking_adaptive_mmco_6( /* Assign LongTermFrameIdx to the other field if it was also marked as "used for long-term reference */ - other_field = (GstVaapiPictureH264 *)picture->base.parent_picture; + other_field = GST_VAAPI_PICTURE_H264(picture->base.parent_picture); if (other_field && GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(other_field)) other_field->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; } From 1c46990ecd18cf33e5411205f37ffd1be6c9318b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sun, 4 May 2014 14:49:28 +0200 Subject: [PATCH 1622/3781] decoder: h264: simplify storage of decoded picture into DPB. Factor out process by which the decoded picture with the lowest POC is found, and possibly output. Likewise, the storage and marking of a reference decoded, or non-reference decoded picture, into the DPB could also be simplified as they mostly share the same operations. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 77 ++++++++++++----------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 2c8ce8d7ce..75edc07079 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -579,27 +579,43 @@ dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i) dpb_remove_index(decoder, i); } -static gboolean -dpb_bump(GstVaapiDecoderH264 *decoder) +/* Finds the picture with the lowest POC that needs to be output */ +static gint +dpb_find_lowest_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, + GstVaapiPictureH264 **found_picture_ptr) { GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPictureH264 *found_picture = NULL; guint i, j, found_index; - gboolean success; for (i = 0; i < priv->dpb_count; i++) { GstVaapiFrameStore * const fs = priv->dpb[i]; if (!fs->output_needed) continue; for (j = 0; j < fs->num_buffers; j++) { - GstVaapiPictureH264 * const picture = fs->buffers[j]; - if (!picture->output_needed) + GstVaapiPictureH264 * const pic = fs->buffers[j]; + if (!pic->output_needed) continue; - if (!found_picture || found_picture->base.poc > picture->base.poc) - found_picture = picture, found_index = i; + if (!found_picture || found_picture->base.poc > pic->base.poc) + found_picture = pic, found_index = i; } } - if (!found_picture) + + if (found_picture_ptr) + *found_picture_ptr = found_picture; + return found_picture ? found_index : -1; +} + +static gboolean +dpb_bump(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiPictureH264 *found_picture; + gint found_index; + gboolean success; + + found_index = dpb_find_lowest_poc(decoder, picture, &found_picture); + if (found_index < 0) return FALSE; success = dpb_output(decoder, priv->dpb[found_index], found_picture); @@ -608,7 +624,7 @@ dpb_bump(GstVaapiDecoderH264 *decoder) } static void -dpb_clear(GstVaapiDecoderH264 *decoder) +dpb_clear(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { GstVaapiDecoderH264Private * const priv = &decoder->priv; guint i; @@ -621,11 +637,11 @@ dpb_clear(GstVaapiDecoderH264 *decoder) } static void -dpb_flush(GstVaapiDecoderH264 *decoder) +dpb_flush(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { - while (dpb_bump(decoder)) + while (dpb_bump(decoder, picture)) ; - dpb_clear(decoder); + dpb_clear(decoder, picture); } static gboolean @@ -633,7 +649,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiFrameStore *fs; - guint i, j; + guint i; // Remove all unused pictures if (!GST_VAAPI_PICTURE_IS_IDR(picture)) { @@ -667,14 +683,9 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { while (priv->dpb_count == priv->dpb_size) { - if (!dpb_bump(decoder)) + if (!dpb_bump(decoder, picture)) return FALSE; } - gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs); - if (picture->output_flag) { - picture->output_needed = TRUE; - fs->output_needed++; - } } // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB @@ -682,21 +693,15 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (!picture->output_flag) return TRUE; while (priv->dpb_count == priv->dpb_size) { - gboolean found_picture = FALSE; - for (i = 0; !found_picture && i < priv->dpb_count; i++) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - if (!fs->output_needed) - continue; - for (j = 0; !found_picture && j < fs->num_buffers; j++) - found_picture = fs->buffers[j]->output_needed && - fs->buffers[j]->base.poc < picture->base.poc; - } - if (!found_picture) + if (dpb_find_lowest_poc(decoder, picture, NULL) < 0) return dpb_output(decoder, NULL, picture); - if (!dpb_bump(decoder)) + if (!dpb_bump(decoder, picture)) return FALSE; } - gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs); + } + + gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs); + if (picture->output_flag) { picture->output_needed = TRUE; fs->output_needed++; } @@ -742,7 +747,7 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) gst_vaapi_picture_replace(&priv->current_picture, NULL); gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL); - dpb_clear(decoder); + dpb_clear(decoder, NULL); if (priv->parser) { gst_h264_nal_parser_free(priv->parser); @@ -1206,7 +1211,7 @@ decode_sequence_end(GstVaapiDecoderH264 *decoder) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - dpb_flush(decoder); + dpb_flush(decoder, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2101,7 +2106,7 @@ init_picture( if (pi->nalu.type == GST_H264_NAL_SLICE_IDR) { GST_DEBUG(""); GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR); - dpb_flush(decoder); + dpb_flush(decoder, picture); } /* Initialize picture structure */ @@ -2311,7 +2316,7 @@ exec_ref_pic_marking_adaptive_mmco_5( { GstVaapiDecoderH264Private * const priv = &decoder->priv; - dpb_flush(decoder); + dpb_flush(decoder, picture); priv->prev_pic_has_mmco5 = TRUE; @@ -3234,7 +3239,7 @@ gst_vaapi_decoder_h264_flush(GstVaapiDecoder *base_decoder) GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(base_decoder); - dpb_flush(decoder); + dpb_flush(decoder, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 79118904a07031acef6116df2885ec30dcbad231 Mon Sep 17 00:00:00 2001 From: Xiaowei Li Date: Thu, 28 Feb 2013 15:59:55 +0800 Subject: [PATCH 1623/3781] decoder: h264: add support for MVC base views. Allow decoding for base views of MVC encoded streams. For now, just skip the slice extension and prefix NAL units, and skip non-base view frames. Signed-off-by: Xiaowei Li [fixed memory leak, improved check for MVC NAL units] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 76 +++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 75edc07079..d0a6217ca6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -76,6 +76,10 @@ static void gst_vaapi_parser_info_h264_finalize(GstVaapiParserInfoH264 *pi) { switch (pi->nalu.type) { + case GST_H264_NAL_SPS: + case GST_H264_NAL_SUBSET_SPS: + gst_h264_sps_clear(&pi->data.sps); + break; case GST_H264_NAL_SEI: if (pi->data.sei) { g_array_unref(pi->data.sei); @@ -1104,6 +1108,29 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static GstVaapiDecoderStatus +parse_subset_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiParserInfoH264 * const pi = unit->parsed_info; + GstH264SPS * const sps = &pi->data.sps; + GstH264ParserResult result; + + GST_DEBUG("parse subset SPS"); + + /* Variables that don't have inferred values per the H.264 + standard but that should get a default value anyway */ + sps->log2_max_pic_order_cnt_lsb_minus4 = 0; + + result = gst_h264_parser_parse_subset_sps(priv->parser, &pi->nalu, sps, + TRUE); + if (result != GST_H264_PARSER_OK) + return get_status(result); + + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { @@ -1187,6 +1214,19 @@ decode_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static GstVaapiDecoderStatus +decode_subset_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiParserInfoH264 * const pi = unit->parsed_info; + GstH264SPS * const sps = &pi->data.sps; + + GST_DEBUG("decode subset SPS"); + + gst_vaapi_parser_info_h264_replace(&priv->sps[sps->id], pi); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus decode_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { @@ -2637,6 +2677,17 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) g_return_val_if_fail(pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); g_return_val_if_fail(sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); + /* Only decode base stream for MVC */ + switch (sps->profile_idc) { + case GST_H264_PROFILE_MULTIVIEW_HIGH: + case GST_H264_PROFILE_STEREO_HIGH: + if (1) { + GST_DEBUG("drop picture from substream"); + return GST_VAAPI_DECODER_STATUS_DROP_FRAME; + } + break; + } + status = ensure_context(decoder, sps); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; @@ -2909,9 +2960,13 @@ decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) case GST_H264_NAL_SPS: status = decode_sps(decoder, unit); break; + case GST_H264_NAL_SUBSET_SPS: + status = decode_subset_sps(decoder, unit); + break; case GST_H264_NAL_PPS: status = decode_pps(decoder, unit); break; + case GST_H264_NAL_SLICE_EXT: case GST_H264_NAL_SLICE_IDR: /* fall-through. IDR specifics are handled in init_picture() */ case GST_H264_NAL_SLICE: @@ -3140,12 +3195,21 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, case GST_H264_NAL_SPS: status = parse_sps(decoder, unit); break; + case GST_H264_NAL_SUBSET_SPS: + status = parse_subset_sps(decoder, unit); + break; case GST_H264_NAL_PPS: status = parse_pps(decoder, unit); break; case GST_H264_NAL_SEI: status = parse_sei(decoder, unit); break; + case GST_H264_NAL_SLICE_EXT: + if (!GST_H264_IS_MVC_NALU(&pi->nalu)) { + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + /* fall-through */ case GST_H264_NAL_SLICE_IDR: case GST_H264_NAL_SLICE: status = parse_slice(decoder, unit); @@ -3172,10 +3236,17 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; break; case GST_H264_NAL_SPS: + case GST_H264_NAL_SUBSET_SPS: case GST_H264_NAL_PPS: case GST_H264_NAL_SEI: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; + case GST_H264_NAL_SLICE_EXT: + if (!GST_H264_IS_MVC_NALU(&pi->nalu)) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + break; + } + /* fall-through */ case GST_H264_NAL_SLICE_IDR: case GST_H264_NAL_SLICE: flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; @@ -3188,6 +3259,11 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, /* skip SPS extension and auxiliary slice for now */ flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; break; + case GST_H264_NAL_PREFIX_UNIT: + /* skip Prefix NAL units for now */ + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP | + GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; default: if (pi->nalu.type >= 14 && pi->nalu.type <= 18) flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; From e4166f5a919fe90839333d2dda1138f44af33ffe Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 31 Oct 2013 19:32:55 +0800 Subject: [PATCH 1624/3781] decoder: h264: properly handle Prefix NAL units. Always cache the previous NAL unit so that we could check whether there is a Prefix NAL unit immediately preceding the current slice or IDR NAL unit. In that case, the NAL unit metadata is copied into the current NAL unit. Otherwise, some default values are inferred, tentatively. e.g. view_id shall be set to 0 and inter_view_flag to 1. [infer default values for slice if previous NAL was not a Prefix] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index d0a6217ca6..e44a7efb88 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -393,6 +393,7 @@ struct _GstVaapiDecoderH264Private { GstVaapiParserInfoH264 *active_sps; GstVaapiParserInfoH264 *pps[GST_H264_MAX_PPS_COUNT]; GstVaapiParserInfoH264 *active_pps; + GstVaapiParserInfoH264 *prev_pi; GstVaapiParserInfoH264 *prev_slice_pi; GstVaapiFrameStore *prev_frame; GstVaapiFrameStore *dpb[16]; @@ -750,6 +751,7 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) gst_vaapi_picture_replace(&priv->current_picture, NULL); gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL); + gst_vaapi_parser_info_h264_replace(&priv->prev_pi, NULL); dpb_clear(decoder, NULL); @@ -1180,6 +1182,7 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; + GstH264NalUnit * const nalu = &pi->nalu; GstH264ParserResult result; GST_DEBUG("parse slice"); @@ -1187,6 +1190,34 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) priv->parser_state &= (GST_H264_VIDEO_STATE_GOT_SPS| GST_H264_VIDEO_STATE_GOT_PPS); + /* Propagate Prefix NAL unit info, if necessary */ + switch (nalu->type) { + case GST_H264_NAL_SLICE: + case GST_H264_NAL_SLICE_IDR: { + GstVaapiParserInfoH264 * const prev_pi = priv->prev_pi; + if (prev_pi && prev_pi->nalu.type == GST_H264_NAL_PREFIX_UNIT) { + /* MVC sequences shall have a Prefix NAL unit immediately + preceding this NAL unit */ + pi->nalu.extension_type = prev_pi->nalu.extension_type; + pi->nalu.extension = prev_pi->nalu.extension; + } + else { + /* In the very unlikely case there is no Prefix NAL unit + immediately preceding this NAL unit, try to infer some + defaults (H.7.4.1.1) */ + GstH264NalUnitExtensionMVC * const mvc = &pi->nalu.extension.mvc; + mvc->non_idr_flag = !(nalu->type == GST_H264_NAL_SLICE_IDR); + nalu->idr_pic_flag = !mvc->non_idr_flag; + mvc->priority_id = 0; + mvc->view_id = 0; + mvc->temporal_id = 0; + mvc->anchor_pic_flag = 0; + mvc->inter_view_flag = 1; + } + break; + } + } + /* Variables that don't have inferred values per the H.264 standard but that should get a default value anyway */ slice_hdr->cabac_init_idc = 0; @@ -3273,6 +3304,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, pi->nalu.data = NULL; pi->state = priv->parser_state; + gst_vaapi_parser_info_h264_replace(&priv->prev_pi, pi); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From a6215a0757fd8e1321dae8c9b3a34f7a9c220420 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 13 Mar 2013 11:44:38 +0200 Subject: [PATCH 1625/3781] decoder: h264: detect the first VCL NAL unit of a picture for MVC. Detect the first VCL NAL unit of a picture for MVC, based on the view_id as per H.7.4.1.2.4. Note that we only need to detect new view components. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index e44a7efb88..7953675c44 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2650,6 +2650,10 @@ is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) #define CHECK_VALUE(new_slice_hdr, old_slice_hdr, field) \ CHECK_EXPR(((new_slice_hdr)->field == (old_slice_hdr)->field), #field) + /* view_id differs in value and VOIdx of current slice_hdr is less + than the VOIdx of the prev_slice_hdr */ + CHECK_VALUE(&pi->nalu.extension.mvc, &prev_pi->nalu.extension.mvc, view_id); + /* frame_num differs in value, regardless of inferred values to 0 */ CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num); From ae1d8267d9830487d6868db6f12aebde1c1c5068 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 1 May 2014 19:33:40 +0200 Subject: [PATCH 1626/3781] decoder: h264: fix detection of access unit boundaries. In order to have a stricter conforming implementation, we need to carefully detect access unit boundaries. Additional operations could be necessary to perform at those boundaries. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 95 ++++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 7953675c44..27924420b2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -57,6 +57,27 @@ typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; /* --- H.264 Parser Info --- */ /* ------------------------------------------------------------------------- */ +/* + * Extended decoder unit flags: + * + * @GST_VAAPI_DECODER_UNIT_AU_START: marks the start of an access unit. + * @GST_VAAPI_DECODER_UNIT_AU_END: marks the end of an access unit. + */ +enum { + /* This flag does not strictly follow the definitions (7.4.1.2.3) + for detecting the start of an access unit as we are only + interested in knowing if the current slice is the first one or + the last one in the current access unit */ + GST_VAAPI_DECODER_UNIT_FLAG_AU_START = ( + GST_VAAPI_DECODER_UNIT_FLAG_LAST << 0), + GST_VAAPI_DECODER_UNIT_FLAG_AU_END = ( + GST_VAAPI_DECODER_UNIT_FLAG_LAST << 1), + + GST_VAAPI_DECODER_UNIT_FLAGS_AU = ( + GST_VAAPI_DECODER_UNIT_FLAG_AU_START | + GST_VAAPI_DECODER_UNIT_FLAG_AU_END), +}; + #define GST_VAAPI_PARSER_INFO_H264(obj) \ ((GstVaapiParserInfoH264 *)(obj)) @@ -70,6 +91,7 @@ struct _GstVaapiParserInfoH264 { GstH264SliceHdr slice_hdr; } data; guint state; + guint flags; // Same as decoder unit flags (persistent) }; static void @@ -124,6 +146,10 @@ gst_vaapi_parser_info_h264_new(void) * Extended picture flags: * * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture + * @GST_VAAPI_PICTURE_FLAG_AU_START: flag that marks the start of an + * access unit (AU) + * @GST_VAAPI_PICTURE_FLAG_AU_END: flag that marks the end of an + * access unit (AU) * @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies * "used for short-term reference" * @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies @@ -134,6 +160,8 @@ gst_vaapi_parser_info_h264_new(void) enum { GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0), GST_VAAPI_PICTURE_FLAG_REFERENCE2 = (GST_VAAPI_PICTURE_FLAG_LAST << 1), + GST_VAAPI_PICTURE_FLAG_AU_START = (GST_VAAPI_PICTURE_FLAG_LAST << 4), + GST_VAAPI_PICTURE_FLAG_AU_END = (GST_VAAPI_PICTURE_FLAG_LAST << 5), GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = ( GST_VAAPI_PICTURE_FLAG_REFERENCE), @@ -453,6 +481,25 @@ struct _GstVaapiDecoderH264Class { static gboolean exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture); +/* Determines the view order index (VOIdx) from the supplied view_id */ +static gint +get_view_order_index(GstH264SPS *sps, guint16 view_id) +{ + GstH264SPSExtMVC *mvc; + gint i; + + if (!sps || sps->extension_type != GST_H264_NAL_EXTENSION_MVC) + return 0; + + mvc = &sps->extension.mvc; + for (i = 0; i <= mvc->num_views_minus1; i++) { + if (mvc->view[i].view_id == view_id) + return i; + } + GST_ERROR("failed to find VOIdx from view_id (%d)", view_id); + return -1; +} + /* Get number of reference frames to use */ static guint get_max_dec_frame_buffering(GstH264SPS *sps) @@ -2698,6 +2745,33 @@ is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) return FALSE; } +/* Detection of a new access unit, assuming we are already in presence + of a new picture */ +static gboolean +is_new_access_unit(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) +{ + GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; + GstH264SliceHdr *prev_slice_hdr; + GstH264NalUnitExtensionMVC *mvc, *prev_mvc; + gint voc, prev_voc; + + g_return_val_if_fail(is_new_picture(pi, prev_pi), FALSE); + + if (!prev_pi) + return TRUE; + prev_slice_hdr = &prev_pi->data.slice_hdr; + + mvc = &pi->nalu.extension.mvc; + prev_mvc = &prev_pi->nalu.extension.mvc; + if (mvc->view_id == prev_mvc->view_id) + return TRUE; + + voc = get_view_order_index(slice_hdr->pps->sequence, mvc->view_id); + prev_voc = get_view_order_index(prev_slice_hdr->pps->sequence, + prev_mvc->view_id); + return voc < prev_voc; +} + static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { @@ -2954,6 +3028,12 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } + /* Check wether this is the first/last slice in the current access unit */ + if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_START) + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_AU_START); + if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END) + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_AU_END); + slice = GST_VAAPI_SLICE_NEW(H264, decoder, (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size); gst_buffer_unmap(buffer, &map_info); @@ -3259,6 +3339,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, flags = 0; switch (pi->nalu.type) { case GST_H264_NAL_AU_DELIMITER: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; /* fall-through */ case GST_H264_NAL_FILLER_DATA: @@ -3269,11 +3350,13 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, /* fall-through */ case GST_H264_NAL_SEQ_END: flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END; break; case GST_H264_NAL_SPS: case GST_H264_NAL_SUBSET_SPS: case GST_H264_NAL_PPS: case GST_H264_NAL_SEI: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; case GST_H264_NAL_SLICE_EXT: @@ -3285,8 +3368,11 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, case GST_H264_NAL_SLICE_IDR: case GST_H264_NAL_SLICE: flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; - if (is_new_picture(pi, priv->prev_slice_pi)) + if (is_new_picture(pi, priv->prev_slice_pi)) { flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + if (is_new_access_unit(pi, priv->prev_slice_pi)) + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; + } gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, pi); break; case GST_H264_NAL_SPS_EXT: @@ -3297,17 +3383,22 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, case GST_H264_NAL_PREFIX_UNIT: /* skip Prefix NAL units for now */ flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP | + GST_VAAPI_DECODER_UNIT_FLAG_AU_START | GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; default: if (pi->nalu.type >= 14 && pi->nalu.type <= 18) - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START | + GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; break; } + if ((flags & GST_VAAPI_DECODER_UNIT_FLAGS_AU) && priv->prev_slice_pi) + priv->prev_slice_pi->flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END; GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); pi->nalu.data = NULL; pi->state = priv->parser_state; + pi->flags = flags; gst_vaapi_parser_info_h264_replace(&priv->prev_pi, pi); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 42b112f8bd7cd8fedc1b57e4b1b5e3f4142e23fd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 1 May 2014 19:16:09 +0200 Subject: [PATCH 1627/3781] decoder: h264: dynamically allocate the DPB. Dynamically allocate the Decoded Picture Buffer (DPB) and add provisions for supporting the MVC allocation requirements. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 96 +++++++++++++++++++---- 1 file changed, 80 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 27924420b2..a9ee127d19 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -424,9 +424,11 @@ struct _GstVaapiDecoderH264Private { GstVaapiParserInfoH264 *prev_pi; GstVaapiParserInfoH264 *prev_slice_pi; GstVaapiFrameStore *prev_frame; - GstVaapiFrameStore *dpb[16]; + GstVaapiFrameStore **dpb; guint dpb_count; guint dpb_size; + guint dpb_size_max; + guint max_views; GstVaapiProfile profile; GstVaapiEntrypoint entrypoint; GstVaapiChromaType chroma_type; @@ -481,6 +483,14 @@ struct _GstVaapiDecoderH264Class { static gboolean exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture); +/* Determines if the supplied profile is one of the MVC set */ +static gboolean +is_mvc_profile(GstH264Profile profile) +{ + return profile == GST_H264_PROFILE_MULTIVIEW_HIGH || + profile == GST_H264_PROFILE_STEREO_HIGH; +} + /* Determines the view order index (VOIdx) from the supplied view_id */ static gint get_view_order_index(GstH264SPS *sps, guint16 view_id) @@ -500,10 +510,19 @@ get_view_order_index(GstH264SPS *sps, guint16 view_id) return -1; } +/* Determines NumViews */ +static guint +get_num_views(GstH264SPS *sps) +{ + return 1 + (sps->extension_type == GST_H264_NAL_EXTENSION_MVC ? + sps->extension.mvc.num_views_minus1 : 0); +} + /* Get number of reference frames to use */ static guint get_max_dec_frame_buffering(GstH264SPS *sps) { + guint num_views, max_dpb_frames; guint max_dec_frame_buffering, PicSizeMbs; GstVaapiLevelH264 level; const GstVaapiH264LevelLimits *level_limits; @@ -514,13 +533,18 @@ get_max_dec_frame_buffering(GstH264SPS *sps) else level = gst_vaapi_utils_h264_get_level(sps->level_idc); level_limits = gst_vaapi_utils_h264_get_level_limits(level); - if (!level_limits) - return 16; - - PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) * - (sps->pic_height_in_map_units_minus1 + 1) * - (sps->frame_mbs_only_flag ? 1 : 2)); - max_dec_frame_buffering = level_limits->MaxDpbMbs / PicSizeMbs; + if (G_UNLIKELY(!level_limits)) { + GST_FIXME("unsupported level_idc value (%d)", sps->level_idc); + max_dec_frame_buffering = 16; + } + else { + PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) * + (sps->pic_height_in_map_units_minus1 + 1) * + (sps->frame_mbs_only_flag ? 1 : 2)); + max_dec_frame_buffering = level_limits->MaxDpbMbs / PicSizeMbs; + } + if (is_mvc_profile(sps->profile_idc)) + max_dec_frame_buffering <<= 1; /* VUI parameters */ if (sps->vui_parameters_present_flag) { @@ -542,8 +566,10 @@ get_max_dec_frame_buffering(GstH264SPS *sps) } } - if (max_dec_frame_buffering > 16) - max_dec_frame_buffering = 16; + num_views = get_num_views(sps); + max_dpb_frames = 16 * (num_views > 1 ? g_bit_storage(num_views - 1) : 1); + if (max_dec_frame_buffering > max_dpb_frames) + max_dec_frame_buffering = max_dpb_frames; else if (max_dec_frame_buffering < sps->num_ref_frames) max_dec_frame_buffering = sps->num_ref_frames; return MAX(1, max_dec_frame_buffering); @@ -760,13 +786,30 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return TRUE; } -static inline void -dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) +static gboolean +dpb_reset(GstVaapiDecoderH264 *decoder, guint dpb_size) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - priv->dpb_size = get_max_dec_frame_buffering(sps); + if (dpb_size < priv->dpb_count) + return FALSE; + + if (dpb_size > priv->dpb_size_max) { + priv->dpb = g_try_realloc_n(priv->dpb, dpb_size, sizeof(*priv->dpb)); + if (!priv->dpb) + return FALSE; + memset(&priv->dpb[priv->dpb_size_max], 0, + (dpb_size - priv->dpb_size_max) * sizeof(*priv->dpb)); + priv->dpb_size_max = dpb_size; + } + + if (priv->dpb_size < dpb_size) + priv->dpb_size = dpb_size; + else if (dpb_size < priv->dpb_count) + return FALSE; + GST_DEBUG("DPB size %u", priv->dpb_size); + return TRUE; } static GstVaapiDecoderStatus @@ -831,6 +874,10 @@ gst_vaapi_decoder_h264_destroy(GstVaapiDecoder *base_decoder) gst_vaapi_decoder_h264_close(decoder); + g_free(priv->dpb); + priv->dpb = NULL; + priv->dpb_size = 0; + for (i = 0; i < G_N_ELEMENTS(priv->pps); i++) gst_vaapi_parser_info_h264_replace(&priv->pps[i], NULL); gst_vaapi_parser_info_h264_replace(&priv->active_pps, NULL); @@ -965,7 +1012,13 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) GstVaapiProfile profile; GstVaapiChromaType chroma_type; gboolean reset_context = FALSE; - guint mb_width, mb_height; + guint mb_width, mb_height, dpb_size; + + dpb_size = get_max_dec_frame_buffering(sps); + if (priv->dpb_size < dpb_size) { + GST_DEBUG("DPB size increased"); + reset_context = TRUE; + } profile = get_profile(decoder, sps); if (!profile) { @@ -1022,14 +1075,15 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) info.chroma_type = priv->chroma_type; info.width = sps->width; info.height = sps->height; - info.ref_frames = get_max_dec_frame_buffering(sps); + info.ref_frames = dpb_size; if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; priv->has_context = TRUE; /* Reset DPB */ - dpb_reset(decoder, sps); + if (!dpb_reset(decoder, dpb_size)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1153,6 +1207,9 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) if (result != GST_H264_PARSER_OK) return get_status(result); + /* Reset defaults */ + priv->max_views = 1; + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1231,6 +1288,7 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstH264NalUnit * const nalu = &pi->nalu; GstH264ParserResult result; + guint num_views; GST_DEBUG("parse slice"); @@ -1275,6 +1333,12 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) if (result != GST_H264_PARSER_OK) return get_status(result); + num_views = get_num_views(slice_hdr->pps->sequence); + if (priv->max_views < num_views) { + priv->max_views = num_views; + GST_DEBUG("maximum number of views changed to %u", num_views); + } + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SLICE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 8c5e89c29801e5c0b7d4bc2d2dc86f0dd1df3e5d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 2 May 2014 14:58:45 +0200 Subject: [PATCH 1628/3781] decoder: h264: add initial support for MVC. https://bugzilla.gnome.org/show_bug.cgi?id=721772 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 381 ++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 5 +- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 9 +- 3 files changed, 378 insertions(+), 17 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index a9ee127d19..dc7e86ba1e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -146,6 +146,11 @@ gst_vaapi_parser_info_h264_new(void) * Extended picture flags: * * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture + * @GST_VAAPI_PICTURE_FLAG_INTER_VIEW: flag that indicates the picture + * may be used for inter-view prediction + * @GST_VAAPI_PICTURE_FLAG_ANCHOR: flag that specifies an anchor picture, + * i.e. a picture that is decoded with only inter-view prediction, + * and not inter prediction * @GST_VAAPI_PICTURE_FLAG_AU_START: flag that marks the start of an * access unit (AU) * @GST_VAAPI_PICTURE_FLAG_AU_END: flag that marks the end of an @@ -160,6 +165,8 @@ gst_vaapi_parser_info_h264_new(void) enum { GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0), GST_VAAPI_PICTURE_FLAG_REFERENCE2 = (GST_VAAPI_PICTURE_FLAG_LAST << 1), + GST_VAAPI_PICTURE_FLAG_INTER_VIEW = (GST_VAAPI_PICTURE_FLAG_LAST << 2), + GST_VAAPI_PICTURE_FLAG_ANCHOR = (GST_VAAPI_PICTURE_FLAG_LAST << 3), GST_VAAPI_PICTURE_FLAG_AU_START = (GST_VAAPI_PICTURE_FLAG_LAST << 4), GST_VAAPI_PICTURE_FLAG_AU_END = (GST_VAAPI_PICTURE_FLAG_LAST << 5), @@ -185,6 +192,12 @@ enum { GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \ GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE) +#define GST_VAAPI_PICTURE_IS_INTER_VIEW(picture) \ + (GST_VAAPI_PICTURE_FLAGS(picture) & GST_VAAPI_PICTURE_FLAG_INTER_VIEW) + +#define GST_VAAPI_PICTURE_IS_ANCHOR(picture) \ + (GST_VAAPI_PICTURE_FLAGS(picture) & GST_VAAPI_PICTURE_FLAG_ANCHOR) + #define GST_VAAPI_PICTURE_H264(picture) \ ((GstVaapiPictureH264 *)(picture)) @@ -271,6 +284,7 @@ struct _GstVaapiFrameStore { /*< private >*/ GstVaapiMiniObject parent_instance; + guint view_id; guint structure; GstVaapiPictureH264 *buffers[2]; guint num_buffers; @@ -302,6 +316,7 @@ gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture) if (!fs) return NULL; + fs->view_id = picture->base.view_id; fs->structure = picture->structure; fs->buffers[0] = gst_vaapi_picture_ref(picture); fs->buffers[1] = NULL; @@ -382,6 +397,18 @@ gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs) return FALSE; } +static gboolean +gst_vaapi_frame_store_has_inter_view(GstVaapiFrameStore *fs) +{ + guint i; + + for (i = 0; i < fs->num_buffers; i++) { + if (GST_VAAPI_PICTURE_IS_INTER_VIEW(fs->buffers[i])) + return TRUE; + } + return FALSE; +} + #define gst_vaapi_frame_store_ref(fs) \ gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(fs)) @@ -432,6 +459,7 @@ struct _GstVaapiDecoderH264Private { GstVaapiProfile profile; GstVaapiEntrypoint entrypoint; GstVaapiChromaType chroma_type; + GPtrArray *inter_views; GstVaapiPictureH264 *short_ref[32]; guint short_ref_count; GstVaapiPictureH264 *long_ref[32]; @@ -670,11 +698,42 @@ dpb_find_lowest_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, GstVaapiFrameStore * const fs = priv->dpb[i]; if (!fs->output_needed) continue; + if (picture && picture->base.view_id != fs->view_id) + continue; for (j = 0; j < fs->num_buffers; j++) { GstVaapiPictureH264 * const pic = fs->buffers[j]; if (!pic->output_needed) continue; - if (!found_picture || found_picture->base.poc > pic->base.poc) + if (!found_picture || found_picture->base.poc > pic->base.poc || + (found_picture->base.poc == pic->base.poc && + found_picture->base.voc > pic->base.voc)) + found_picture = pic, found_index = i; + } + } + + if (found_picture_ptr) + *found_picture_ptr = found_picture; + return found_picture ? found_index : -1; +} + +/* Finds the picture with the lowest VOC that needs to be output */ +static gint +dpb_find_lowest_voc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, + GstVaapiPictureH264 **found_picture_ptr) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiPictureH264 *found_picture = NULL; + guint i, j, found_index; + + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + if (!fs->output_needed || fs->view_id == picture->base.view_id) + continue; + for (j = 0; j < fs->num_buffers; j++) { + GstVaapiPictureH264 * const pic = fs->buffers[j]; + if (!pic->output_needed || pic->base.poc != picture->base.poc) + continue; + if (!found_picture || found_picture->base.voc > pic->base.voc) found_picture = pic, found_index = i; } } @@ -698,6 +757,19 @@ dpb_bump(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) success = dpb_output(decoder, priv->dpb[found_index], found_picture); dpb_evict(decoder, found_picture, found_index); + if (priv->max_views == 1) + return success; + + /* Emit all other view components that were in the same access + unit than the picture we have just found */ + for (;;) { + found_index = dpb_find_lowest_voc(decoder, found_picture, + &found_picture); + if (found_index < 0) + break; + dpb_output(decoder, priv->dpb[found_index], found_picture); + dpb_evict(decoder, found_picture, found_index); + } return success; } @@ -705,11 +777,19 @@ static void dpb_clear(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - guint i; + guint i, n; - for (i = 0; i < priv->dpb_count; i++) + for (i = 0; i < priv->dpb_count; i++) { + if (picture && picture->base.view_id != priv->dpb[i]->view_id) + continue; gst_vaapi_frame_store_replace(&priv->dpb[i], NULL); - priv->dpb_count = 0; + } + + for (i = 0, n = 0; i < priv->dpb_count; i++) { + if (priv->dpb[i]) + priv->dpb[n++] = priv->dpb[i]; + } + priv->dpb_count = n; gst_vaapi_frame_store_replace(&priv->prev_frame, NULL); } @@ -722,6 +802,26 @@ dpb_flush(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) dpb_clear(decoder, picture); } +static void +dpb_prune_mvc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + guint i; + + // Remove all unused inter-view pictures + if (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_AU_END)) { + i = 0; + while (i < priv->dpb_count) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + if (fs->view_id != picture->base.view_id && + !fs->output_needed && !gst_vaapi_frame_store_has_reference(fs)) + dpb_remove_index(decoder, i); + else + i++; + } + } +} + static gboolean dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { @@ -729,12 +829,16 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) GstVaapiFrameStore *fs; guint i; + if (priv->max_views > 1) + dpb_prune_mvc(decoder, picture); + // Remove all unused pictures if (!GST_VAAPI_PICTURE_IS_IDR(picture)) { i = 0; while (i < priv->dpb_count) { GstVaapiFrameStore * const fs = priv->dpb[i]; - if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs)) + if (fs->view_id == picture->base.view_id && + !fs->output_needed && !gst_vaapi_frame_store_has_reference(fs)) dpb_remove_index(decoder, i); else i++; @@ -768,11 +872,18 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB else { - if (!picture->output_flag) + const gboolean StoreInterViewOnlyRefFlag = + !GST_VAAPI_PICTURE_FLAG_IS_SET(picture, + GST_VAAPI_PICTURE_FLAG_AU_END) && + GST_VAAPI_PICTURE_FLAG_IS_SET(picture, + GST_VAAPI_PICTURE_FLAG_INTER_VIEW); + if (!picture->output_flag && !StoreInterViewOnlyRefFlag) return TRUE; while (priv->dpb_count == priv->dpb_size) { - if (dpb_find_lowest_poc(decoder, picture, NULL) < 0) - return dpb_output(decoder, NULL, picture); + if (!StoreInterViewOnlyRefFlag) { + if (dpb_find_lowest_poc(decoder, picture, NULL) < 0) + return dpb_output(decoder, NULL, picture); + } if (!dpb_bump(decoder, picture)) return FALSE; } @@ -812,6 +923,33 @@ dpb_reset(GstVaapiDecoderH264 *decoder, guint dpb_size) return TRUE; } +static void +unref_inter_view(GstVaapiPictureH264 *picture) +{ + if (!picture) + return; + GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAG_INTER_VIEW); + gst_vaapi_picture_unref(picture); +} + +/* Resets MVC resources */ +static gboolean +mvc_reset(GstVaapiDecoderH264 *decoder) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + + // Resize array of inter-view references + if (priv->inter_views) + g_ptr_array_set_size(priv->inter_views, priv->max_views); + else { + priv->inter_views = g_ptr_array_new_full(priv->max_views, + (GDestroyNotify)unref_inter_view); + if (!priv->inter_views) + return FALSE; + } + return TRUE; +} + static GstVaapiDecoderStatus get_status(GstH264ParserResult result) { @@ -845,6 +983,11 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) dpb_clear(decoder, NULL); + if (priv->inter_views) { + g_ptr_array_unref(priv->inter_views); + priv->inter_views = NULL; + } + if (priv->parser) { gst_h264_nal_parser_free(priv->parser); priv->parser = NULL; @@ -1084,6 +1227,10 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) /* Reset DPB */ if (!dpb_reset(decoder, dpb_size)) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + /* Reset MVC data */ + if (!mvc_reset(decoder)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1684,6 +1831,10 @@ init_picture_refs_pic_num( for (i = 0; i < priv->short_ref_count; i++) { GstVaapiPictureH264 * const pic = priv->short_ref[i]; + // (H.8.2) + if (pic->base.view_id != picture->base.view_id) + continue; + // (8-27) if (pic->frame_num > priv->frame_num) pic->frame_num_wrap = pic->frame_num - MaxFrameNum; @@ -1704,6 +1855,10 @@ init_picture_refs_pic_num( for (i = 0; i < priv->long_ref_count; i++) { GstVaapiPictureH264 * const pic = priv->long_ref[i]; + // (H.8.2) + if (pic->base.view_id != picture->base.view_id) + continue; + // (8-29, 8-32, 8-33) if (GST_VAAPI_PICTURE_IS_FRAME(picture)) pic->long_term_pic_num = pic->long_term_frame_idx; @@ -1772,6 +1927,81 @@ init_picture_refs_fields( *RefPicList_count = n; } +/* Finds the inter-view reference picture with the supplied view id */ +static GstVaapiPictureH264 * +find_inter_view_reference(GstVaapiDecoderH264 *decoder, guint16 view_id) +{ + GPtrArray * const inter_views = decoder->priv.inter_views; + guint i; + + for (i = 0; i < inter_views->len; i++) { + GstVaapiPictureH264 * const picture = g_ptr_array_index(inter_views, i); + if (picture->base.view_id == view_id) + return picture; + } + + GST_WARNING("failed to find inter-view reference picture for view_id: %d", + view_id); + return NULL; +} + +/* H.8.2.1 - Initialization process for inter-view prediction references */ +static void +init_picture_refs_mvc_1(GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 **ref_list, guint *ref_list_count_ptr, guint num_refs, + const guint16 *view_ids, guint num_view_ids) +{ + guint j, n; + + n = *ref_list_count_ptr; + for (j = 0; j < num_view_ids && n < num_refs; j++) { + GstVaapiPictureH264 * const pic = + find_inter_view_reference(decoder, view_ids[j]); + if (pic) + ref_list[n++] = pic; + } + *ref_list_count_ptr = n; +} + +static inline void +init_picture_refs_mvc(GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, GstH264SliceHdr *slice_hdr, guint list) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + const GstH264SPS * const sps = get_sps(decoder); + const GstH264SPSExtMVCView *view; + + GST_DEBUG("initialize reference picture list for inter-view prediction"); + + if (sps->extension_type != GST_H264_NAL_EXTENSION_MVC) + return; + view = &sps->extension.mvc.view[picture->base.voc]; + +#define INVOKE_INIT_PICTURE_REFS_MVC(ref_list, view_list) do { \ + init_picture_refs_mvc_1(decoder, \ + priv->RefPicList##ref_list, \ + &priv->RefPicList##ref_list##_count, \ + slice_hdr->num_ref_idx_l##ref_list##_active_minus1 + 1, \ + view->view_list##_l##ref_list, \ + view->num_##view_list##s_l##ref_list); \ + } while (0) + + if (list == 0) { + if (GST_VAAPI_PICTURE_IS_ANCHOR(picture)) + INVOKE_INIT_PICTURE_REFS_MVC(0, anchor_ref); + else + INVOKE_INIT_PICTURE_REFS_MVC(0, non_anchor_ref); + } + else { + if (GST_VAAPI_PICTURE_IS_ANCHOR(picture)) + INVOKE_INIT_PICTURE_REFS_MVC(1, anchor_ref); + else + INVOKE_INIT_PICTURE_REFS_MVC(1, non_anchor_ref); + } + +#undef INVOKE_INIT_PICTURE_REFS_MVC +} + static void init_picture_refs_p_slice( GstVaapiDecoderH264 *decoder, @@ -1831,6 +2061,11 @@ init_picture_refs_p_slice( long_ref, long_ref_count ); } + + if (GST_VAAPI_PICTURE_IS_MVC(picture)) { + /* RefPicList0 */ + init_picture_refs_mvc(decoder, picture, slice_hdr, 0); + } } static void @@ -1987,6 +2222,14 @@ init_picture_refs_b_slice( priv->RefPicList1[0] = priv->RefPicList1[1]; priv->RefPicList1[1] = tmp; } + + if (GST_VAAPI_PICTURE_IS_MVC(picture)) { + /* RefPicList0 */ + init_picture_refs_mvc(decoder, picture, slice_hdr, 0); + + /* RefPicList1 */ + init_picture_refs_mvc(decoder, picture, slice_hdr, 1); + } } #undef SORT_REF_LIST @@ -2035,9 +2278,10 @@ exec_picture_refs_modification_1( guint num_ref_pic_list_modifications; GstVaapiPictureH264 **ref_list; guint *ref_list_count_ptr, ref_list_count, ref_list_idx = 0; - guint i, j, n, num_refs; + const guint16 *view_ids = NULL; + guint i, j, n, num_refs, num_view_ids = 0; gint found_ref_idx; - gint32 MaxPicNum, CurrPicNum, picNumPred; + gint32 MaxPicNum, CurrPicNum, picNumPred, picViewIdxPred; GST_DEBUG("modification process of reference picture list %u", list); @@ -2047,6 +2291,20 @@ exec_picture_refs_modification_1( ref_list = priv->RefPicList0; ref_list_count_ptr = &priv->RefPicList0_count; num_refs = slice_hdr->num_ref_idx_l0_active_minus1 + 1; + + if (GST_VAAPI_PICTURE_IS_MVC(picture) && + sps->extension_type == GST_H264_NAL_EXTENSION_MVC) { + const GstH264SPSExtMVCView * const view = + &sps->extension.mvc.view[picture->base.voc]; + if (GST_VAAPI_PICTURE_IS_ANCHOR(picture)) { + view_ids = view->anchor_ref_l0; + num_view_ids = view->num_anchor_refs_l0; + } + else { + view_ids = view->non_anchor_ref_l0; + num_view_ids = view->num_non_anchor_refs_l0; + } + } } else { ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l1; @@ -2054,6 +2312,20 @@ exec_picture_refs_modification_1( ref_list = priv->RefPicList1; ref_list_count_ptr = &priv->RefPicList1_count; num_refs = slice_hdr->num_ref_idx_l1_active_minus1 + 1; + + if (GST_VAAPI_PICTURE_IS_MVC(picture) && + sps->extension_type == GST_H264_NAL_EXTENSION_MVC) { + const GstH264SPSExtMVCView * const view = + &sps->extension.mvc.view[picture->base.voc]; + if (GST_VAAPI_PICTURE_IS_ANCHOR(picture)) { + view_ids = view->anchor_ref_l1; + num_view_ids = view->num_anchor_refs_l1; + } + else { + view_ids = view->non_anchor_ref_l1; + num_view_ids = view->num_non_anchor_refs_l1; + } + } } ref_list_count = *ref_list_count_ptr; @@ -2067,6 +2339,7 @@ exec_picture_refs_modification_1( } picNumPred = CurrPicNum; + picViewIdxPred = -1; for (i = 0; i < num_ref_pic_list_modifications; i++) { GstH264RefPicListModification * const l = &ref_pic_list_modification[i]; @@ -2112,7 +2385,8 @@ exec_picture_refs_modification_1( PicNumF = GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(ref_list[j]) ? ref_list[j]->pic_num : MaxPicNum; - if (PicNumF != picNum) + if (PicNumF != picNum || + ref_list[j]->base.view_id != picture->base.view_id) ref_list[n++] = ref_list[j]; } } @@ -2134,7 +2408,49 @@ exec_picture_refs_modification_1( LongTermPicNumF = GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(ref_list[j]) ? ref_list[j]->long_term_pic_num : INT_MAX; - if (LongTermPicNumF != l->value.long_term_pic_num) + if (LongTermPicNumF != l->value.long_term_pic_num || + ref_list[j]->base.view_id != picture->base.view_id) + ref_list[n++] = ref_list[j]; + } + } + + /* H.8.2.2.3 - Inter-view prediction reference pictures */ + else if ((GST_VAAPI_PICTURE_IS_MVC(picture) && + sps->extension_type == GST_H264_NAL_EXTENSION_MVC) && + (l->modification_of_pic_nums_idc == 4 || + l->modification_of_pic_nums_idc == 5)) { + gint32 abs_diff_view_idx = l->value.abs_diff_view_idx_minus1 + 1; + gint32 picViewIdx, targetViewId; + + // (H-6) + if (l->modification_of_pic_nums_idc == 4) { + picViewIdx = picViewIdxPred - abs_diff_view_idx; + if (picViewIdx < 0) + picViewIdx += num_view_ids; + } + + // (H-7) + else { + picViewIdx = picViewIdxPred + abs_diff_view_idx; + if (picViewIdx >= num_view_ids) + picViewIdx -= num_view_ids; + } + picViewIdxPred = picViewIdx; + + // (H-8, H-9) + targetViewId = view_ids[picViewIdx]; + + // (H-10) + for (j = num_refs; j > ref_list_idx; j--) + ref_list[j] = ref_list[j - 1]; + ref_list[ref_list_idx++] = + find_inter_view_reference(decoder, targetViewId); + n = ref_list_idx; + for (j = ref_list_idx; j <= num_refs; j++) { + if (!ref_list[j]) + continue; + if (ref_list[j]->base.view_id != targetViewId || + ref_list[j]->base.poc != picture->base.poc) ref_list[n++] = ref_list[j]; } } @@ -2185,6 +2501,8 @@ init_picture_ref_lists(GstVaapiDecoderH264 *decoder, if (!gst_vaapi_frame_store_has_frame(fs)) continue; pic = fs->buffers[0]; + if (pic->base.view_id != picture->base.view_id) + continue; if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(pic)) priv->short_ref[short_ref_count++] = pic; else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(pic)) @@ -2198,6 +2516,8 @@ init_picture_ref_lists(GstVaapiDecoderH264 *decoder, GstVaapiFrameStore * const fs = priv->dpb[i]; for (j = 0; j < fs->num_buffers; j++) { GstVaapiPictureH264 * const pic = fs->buffers[j]; + if (pic->base.view_id != picture->base.view_id) + continue; if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(pic)) priv->short_ref[short_ref_count++] = pic; else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(pic)) @@ -2284,8 +2604,27 @@ init_picture( base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE; + /* Initialize extensions */ + switch (pi->nalu.extension_type) { + case GST_H264_NAL_EXTENSION_MVC: { + GstH264NalUnitExtensionMVC * const mvc = &pi->nalu.extension.mvc; + base_picture->view_id = mvc->view_id; + base_picture->voc = get_view_order_index(get_sps(decoder), + base_picture->view_id); + + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_MVC); + if (mvc->inter_view_flag) + GST_VAAPI_PICTURE_FLAG_SET(picture, + GST_VAAPI_PICTURE_FLAG_INTER_VIEW); + if (mvc->anchor_pic_flag) + GST_VAAPI_PICTURE_FLAG_SET(picture, + GST_VAAPI_PICTURE_FLAG_ANCHOR); + break; + } + } + /* Reset decoder state for IDR pictures */ - if (pi->nalu.type == GST_H264_NAL_SLICE_IDR) { + if (pi->nalu.idr_pic_flag) { GST_DEBUG(""); GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR); dpb_flush(decoder, picture); @@ -2600,6 +2939,9 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) priv->prev_pic_has_mmco5 = FALSE; priv->prev_pic_structure = picture->structure; + if (GST_VAAPI_PICTURE_IS_INTER_VIEW(picture)) + g_ptr_array_add(priv->inter_views, gst_vaapi_picture_ref(picture)); + if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) return TRUE; @@ -2681,9 +3023,13 @@ fill_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) for (i = 0, n = 0; i < priv->dpb_count; i++) { GstVaapiFrameStore * const fs = priv->dpb[i]; - if (gst_vaapi_frame_store_has_reference(fs)) + if ((gst_vaapi_frame_store_has_reference(fs) && + fs->view_id == picture->base.view_id) || + gst_vaapi_frame_store_has_inter_view(fs)) vaapi_fill_picture(&pic_param->ReferenceFrames[n++], fs->buffers[0], fs->structure); + if (n >= G_N_ELEMENTS(pic_param->ReferenceFrames)) + break; } for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++) vaapi_init_picture(&pic_param->ReferenceFrames[n]); @@ -2854,7 +3200,7 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) switch (sps->profile_idc) { case GST_H264_PROFILE_MULTIVIEW_HIGH: case GST_H264_PROFILE_STEREO_HIGH: - if (1) { + if (0) { GST_DEBUG("drop picture from substream"); return GST_VAAPI_DECODER_STATUS_DROP_FRAME; } @@ -2886,6 +3232,11 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) gst_vaapi_picture_replace(&priv->current_picture, picture); gst_vaapi_picture_unref(picture); + /* Clear inter-view references list if this is the primary coded + picture of the current access unit */ + if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_START) + g_ptr_array_set_size(priv->inter_views, 0); + /* Update cropping rectangle */ if (sps->frame_cropping_flag) { GstVaapiRectangle crop_rect; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 5f8c0f0e2a..5277fbc635 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -104,6 +104,8 @@ gst_vaapi_picture_create (GstVaapiPicture * picture, 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, @@ -111,7 +113,8 @@ gst_vaapi_picture_create (GstVaapiPicture * 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_FF | GST_VAAPI_PICTURE_FLAG_TFF | + GST_VAAPI_PICTURE_FLAG_MVC)); picture->structure = parent_picture->structure; if ((args->flags & GST_VAAPI_CREATE_PICTURE_FLAG_FIELD) && diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 5a36f6318e..e2790cb138 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -65,6 +65,7 @@ typedef enum * @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_MVC: multiview component * @GST_VAAPI_PICTURE_FLAG_LAST: first flag that can be used by subclasses * * Enum values used for #GstVaapiPicture flags. @@ -77,7 +78,8 @@ typedef enum 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_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 6), + GST_VAAPI_PICTURE_FLAG_MVC = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 6), + GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 7), } GstVaapiPictureFlags; #define GST_VAAPI_PICTURE_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS @@ -110,6 +112,9 @@ typedef enum (GST_VAAPI_PICTURE_IS_FRAME (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)) + /** * GstVaapiPicture: * @@ -137,6 +142,8 @@ struct _GstVaapiPicture GstVaapiProbabilityTable *prob_table; GstClockTime pts; gint32 poc; + guint16 voc; + guint16 view_id; guint structure; GstVaapiRectangle crop_rect; guint has_crop_rect:1; From 5d76afb40d0eaea34331278dfc4b44120f6013cb Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 20 May 2014 18:08:15 +0200 Subject: [PATCH 1629/3781] decoder: h264: add MVC profiles compatibility logic. Add safe fallbacks for MVC profiles: - all MultiView High profile streams with 2 views at most can be decoded with a Stereo High profile compliant decoder ; - all Stereo High profile streams with only progressive views can be decoded with a MultiView High profile compliant decoder ; - all drivers that support slice-level decoding could normally support MVC profiles when the DPB holds at most 16 frames. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 49 ++++++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index dc7e86ba1e..c6f3c7f55a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1102,8 +1102,39 @@ fill_profiles(GstVaapiProfile profiles[16], guint *n_profiles_ptr, *n_profiles_ptr = n_profiles; } +/* Fills in compatible profiles for MVC decoding */ +static void +fill_profiles_mvc(GstVaapiDecoderH264 *decoder, GstVaapiProfile profiles[16], + guint *n_profiles_ptr, guint dpb_size) +{ + const gchar * const vendor_string = + gst_vaapi_display_get_vendor_string(GST_VAAPI_DECODER_DISPLAY(decoder)); + + gboolean add_high_profile = FALSE; + struct map { + const gchar *str; + guint str_len; + }; + const struct map *m; + + // Drivers that support slice level decoding + if (vendor_string && dpb_size <= 16) { + static const struct map drv_names[] = { + { "Intel i965 driver", 17 }, + { NULL, 0 } + }; + for (m = drv_names; m->str != NULL && !add_high_profile; m++) { + if (g_ascii_strncasecmp(vendor_string, m->str, m->str_len) == 0) + add_high_profile = TRUE; + } + } + + if (add_high_profile) + fill_profiles(profiles, n_profiles_ptr, GST_VAAPI_PROFILE_H264_HIGH); +} + static GstVaapiProfile -get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) +get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps, guint dpb_size) { GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder); @@ -1130,6 +1161,20 @@ get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) GST_VAAPI_PROFILE_H264_MAIN); } break; + case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH: + if (priv->max_views == 2) { + fill_profiles(profiles, &n_profiles, + GST_VAAPI_PROFILE_H264_STEREO_HIGH); + } + fill_profiles_mvc(decoder, profiles, &n_profiles, dpb_size); + break; + case GST_VAAPI_PROFILE_H264_STEREO_HIGH: + if (sps->frame_mbs_only_flag) { + fill_profiles(profiles, &n_profiles, + GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH); + } + fill_profiles_mvc(decoder, profiles, &n_profiles, dpb_size); + break; default: break; } @@ -1163,7 +1208,7 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) reset_context = TRUE; } - profile = get_profile(decoder, sps); + profile = get_profile(decoder, sps, dpb_size); if (!profile) { GST_ERROR("unsupported profile_idc %u", sps->profile_idc); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; From abcc8bb7a2f45852af6957af91a656a65a46fc50 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 21 May 2014 17:57:00 +0200 Subject: [PATCH 1630/3781] decoder: h264: add support for MVC interlaced streams. Fix support for MVC Stereo High profile streams with interlaced frames. Also improve the detection logic of the first field. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 101 +++++++++++++++++++--- 1 file changed, 90 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index c6f3c7f55a..d25994fa32 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -450,7 +450,8 @@ struct _GstVaapiDecoderH264Private { GstVaapiParserInfoH264 *active_pps; GstVaapiParserInfoH264 *prev_pi; GstVaapiParserInfoH264 *prev_slice_pi; - GstVaapiFrameStore *prev_frame; + GstVaapiFrameStore **prev_frames; + guint prev_frames_alloc; GstVaapiFrameStore **dpb; guint dpb_count; guint dpb_size; @@ -519,6 +520,13 @@ is_mvc_profile(GstH264Profile profile) profile == GST_H264_PROFILE_STEREO_HIGH; } +/* Determines the view_id from the supplied NAL unit */ +static inline guint +get_view_id(GstH264NalUnit *nalu) +{ + return GST_H264_IS_MVC_NALU(nalu) ? nalu->extension.mvc.view_id : 0; +} + /* Determines the view order index (VOIdx) from the supplied view_id */ static gint get_view_order_index(GstH264SPS *sps, guint16 view_id) @@ -685,6 +693,23 @@ dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i) dpb_remove_index(decoder, i); } +/* Finds the frame store holding the supplied picture */ +static gint +dpb_find_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + gint i, j; + + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + for (j = 0; j < fs->num_buffers; j++) { + if (fs->buffers[j] == picture) + return i; + } + } + return -1; +} + /* Finds the picture with the lowest POC that needs to be output */ static gint dpb_find_lowest_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, @@ -791,7 +816,13 @@ dpb_clear(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) } priv->dpb_count = n; - gst_vaapi_frame_store_replace(&priv->prev_frame, NULL); + /* Clear previous frame buffers only if this is a "flush-all" operation, + or if the picture is the first one in the access unit */ + if (!picture || GST_VAAPI_PICTURE_FLAG_IS_SET(picture, + GST_VAAPI_PICTURE_FLAG_AU_START)) { + for (i = 0; i < priv->max_views; i++) + gst_vaapi_picture_replace(&priv->prev_frames[i], NULL); + } } static void @@ -846,15 +877,19 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) } // Check if picture is the second field and the first field is still in DPB - fs = priv->prev_frame; - if (fs && !gst_vaapi_frame_store_has_frame(fs)) - return gst_vaapi_frame_store_add(fs, picture); + if (GST_VAAPI_PICTURE_IS_INTERLACED(picture) && + !GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture)) { + const gint found_index = dpb_find_picture(decoder, + GST_VAAPI_PICTURE_H264(picture->base.parent_picture)); + if (found_index >= 0) + return gst_vaapi_frame_store_add(priv->dpb[found_index], picture); + } // Create new frame store, and split fields if necessary fs = gst_vaapi_frame_store_new(picture); if (!fs) return FALSE; - gst_vaapi_frame_store_replace(&priv->prev_frame, fs); + gst_vaapi_frame_store_replace(&priv->prev_frames[picture->base.voc], fs); gst_vaapi_frame_store_unref(fs); if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) { @@ -937,6 +972,7 @@ static gboolean mvc_reset(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = &decoder->priv; + guint i; // Resize array of inter-view references if (priv->inter_views) @@ -947,6 +983,20 @@ mvc_reset(GstVaapiDecoderH264 *decoder) if (!priv->inter_views) return FALSE; } + + // Resize array of previous frame buffers + for (i = priv->max_views; i < priv->prev_frames_alloc; i++) + gst_vaapi_picture_replace(&priv->prev_frames[i], NULL); + + priv->prev_frames = g_try_realloc_n(priv->prev_frames, priv->max_views, + sizeof(*priv->prev_frames)); + if (!priv->prev_frames) { + priv->prev_frames_alloc = 0; + return FALSE; + } + for (i = priv->prev_frames_alloc; i < priv->max_views; i++) + priv->prev_frames[i] = NULL; + priv->prev_frames_alloc = priv->max_views; return TRUE; } @@ -1021,6 +1071,10 @@ gst_vaapi_decoder_h264_destroy(GstVaapiDecoder *base_decoder) priv->dpb = NULL; priv->dpb_size = 0; + g_free(priv->prev_frames); + priv->prev_frames = NULL; + priv->prev_frames_alloc = 0; + for (i = 0; i < G_N_ELEMENTS(priv->pps); i++) gst_vaapi_parser_info_h264_replace(&priv->pps[i], NULL); gst_vaapi_parser_info_h264_replace(&priv->active_pps, NULL); @@ -1365,8 +1419,7 @@ decode_current_picture(GstVaapiDecoderH264 *decoder) goto error; if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture))) goto error; - if (priv->prev_frame && gst_vaapi_frame_store_has_frame(priv->prev_frame)) - gst_vaapi_picture_replace(&priv->current_picture, NULL); + gst_vaapi_picture_replace(&priv->current_picture, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; error: @@ -3227,6 +3280,31 @@ is_new_access_unit(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) return voc < prev_voc; } +/* Finds the first field picture corresponding to the supplied picture */ +static GstVaapiPictureH264 * +find_first_field(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, + GstH264SliceHdr *slice_hdr) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiFrameStore *fs; + gint voc; + + if (!slice_hdr->field_pic_flag) + return NULL; + + voc = get_view_order_index(get_sps(decoder), get_view_id(nalu)); + if (voc < 0) + return NULL; + + fs = priv->prev_frames[voc]; + if (!fs || gst_vaapi_frame_store_has_frame(fs)) + return NULL; + + if (fs->buffers[0]->frame_num == slice_hdr->frame_num) + return fs->buffers[0]; + return NULL; +} + static GstVaapiDecoderStatus decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) { @@ -3235,7 +3313,7 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstH264PPS * const pps = ensure_pps(decoder, slice_hdr->pps); GstH264SPS * const sps = ensure_sps(decoder, slice_hdr->pps->sequence); - GstVaapiPictureH264 *picture; + GstVaapiPictureH264 *picture, *first_field; GstVaapiDecoderStatus status; g_return_val_if_fail(pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); @@ -3258,9 +3336,10 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) priv->decoder_state = 0; - if (priv->current_picture) { + first_field = find_first_field(decoder, &pi->nalu, slice_hdr); + if (first_field) { /* Re-use current picture where the first field was decoded */ - picture = gst_vaapi_picture_h264_new_field(priv->current_picture); + picture = gst_vaapi_picture_h264_new_field(first_field); if (!picture) { GST_ERROR("failed to allocate field picture"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; From f0d3d9cd3c2fa852e71198184336b31259762a25 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 22 May 2014 10:04:46 +0200 Subject: [PATCH 1631/3781] decoder: h264: compute view ids only once per slice. Optimize lookups of view ids / view order indices by caching the result of the calculatiosn right into the GstVaapiParserInfoH264 struct. This terribly simplifies is_new_access_unit() and find_first_field() functions. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 55 +++++++++-------------- 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index d25994fa32..e04c2d733f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -91,7 +91,9 @@ struct _GstVaapiParserInfoH264 { GstH264SliceHdr slice_hdr; } data; guint state; - guint flags; // Same as decoder unit flags (persistent) + guint flags; // Same as decoder unit flags (persistent) + guint view_id; // View ID of slice + guint voc; // View order index (VOIdx) of slice }; static void @@ -1532,6 +1534,7 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GstVaapiParserInfoH264 * const pi = unit->parsed_info; GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstH264NalUnit * const nalu = &pi->nalu; + GstH264SPS *sps; GstH264ParserResult result; guint num_views; @@ -1578,11 +1581,16 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) if (result != GST_H264_PARSER_OK) return get_status(result); - num_views = get_num_views(slice_hdr->pps->sequence); + sps = slice_hdr->pps->sequence; + + /* Update MVC data */ + num_views = get_num_views(sps); if (priv->max_views < num_views) { priv->max_views = num_views; GST_DEBUG("maximum number of views changed to %u", num_views); } + pi->view_id = get_view_id(&pi->nalu); + pi->voc = get_view_order_index(sps, pi->view_id); priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SLICE; return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -2701,14 +2709,13 @@ init_picture( picture->output_flag = TRUE; /* XXX: conformant to Annex A only */ base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE; + base_picture->view_id = pi->view_id; + base_picture->voc = pi->voc; /* Initialize extensions */ switch (pi->nalu.extension_type) { case GST_H264_NAL_EXTENSION_MVC: { GstH264NalUnitExtensionMVC * const mvc = &pi->nalu.extension.mvc; - base_picture->view_id = mvc->view_id; - base_picture->voc = get_view_order_index(get_sps(decoder), - base_picture->view_id); GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_MVC); if (mvc->inter_view_flag) @@ -3207,7 +3214,7 @@ is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) /* view_id differs in value and VOIdx of current slice_hdr is less than the VOIdx of the prev_slice_hdr */ - CHECK_VALUE(&pi->nalu.extension.mvc, &prev_pi->nalu.extension.mvc, view_id); + CHECK_VALUE(pi, prev_pi, view_id); /* frame_num differs in value, regardless of inferred values to 0 */ CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num); @@ -3255,48 +3262,26 @@ is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) /* Detection of a new access unit, assuming we are already in presence of a new picture */ -static gboolean +static inline gboolean is_new_access_unit(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) { - GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; - GstH264SliceHdr *prev_slice_hdr; - GstH264NalUnitExtensionMVC *mvc, *prev_mvc; - gint voc, prev_voc; - - g_return_val_if_fail(is_new_picture(pi, prev_pi), FALSE); - - if (!prev_pi) + if (!prev_pi || prev_pi->view_id == pi->view_id) return TRUE; - prev_slice_hdr = &prev_pi->data.slice_hdr; - - mvc = &pi->nalu.extension.mvc; - prev_mvc = &prev_pi->nalu.extension.mvc; - if (mvc->view_id == prev_mvc->view_id) - return TRUE; - - voc = get_view_order_index(slice_hdr->pps->sequence, mvc->view_id); - prev_voc = get_view_order_index(prev_slice_hdr->pps->sequence, - prev_mvc->view_id); - return voc < prev_voc; + return pi->voc < prev_pi->voc; } /* Finds the first field picture corresponding to the supplied picture */ static GstVaapiPictureH264 * -find_first_field(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, - GstH264SliceHdr *slice_hdr) +find_first_field(GstVaapiDecoderH264 *decoder, GstVaapiParserInfoH264 *pi) { GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstVaapiFrameStore *fs; - gint voc; if (!slice_hdr->field_pic_flag) return NULL; - voc = get_view_order_index(get_sps(decoder), get_view_id(nalu)); - if (voc < 0) - return NULL; - - fs = priv->prev_frames[voc]; + fs = priv->prev_frames[pi->voc]; if (!fs || gst_vaapi_frame_store_has_frame(fs)) return NULL; @@ -3336,7 +3321,7 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) priv->decoder_state = 0; - first_field = find_first_field(decoder, &pi->nalu, slice_hdr); + first_field = find_first_field(decoder, pi); if (first_field) { /* Re-use current picture where the first field was decoded */ picture = gst_vaapi_picture_h264_new_field(first_field); From 800bfc1add898afa26e4095cc126985815ec4dc5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Jun 2014 16:25:03 +0200 Subject: [PATCH 1632/3781] utils: only enable VP8 profiles for newer VA-API versions. VP8 decoding API appeared in VA-API >= 0.35.0. So, disable mappings involving VP8 codec on earlier versions of the API. --- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 ++ gst-libs/gst/vaapi/gstvaapiutils.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 76e5d0e0a3..5b3640ce0e 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -126,8 +126,10 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "image/jpeg", "baseline" }, #endif +#if VA_CHECK_VERSION(0,35,0) {GST_VAAPI_PROFILE_VP8, VAProfileVP8Version0_3, "video/x-vp8", "Version0_3"}, +#endif { 0, } }; diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 63e46910a3..d7f1d852f3 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -145,6 +145,9 @@ string_of_VAProfile (VAProfile profile) MAP (VC1Simple); MAP (VC1Main); MAP (VC1Advanced); +#if VA_CHECK_VERSION(0,35,0) + MAP (VP8Version0_3); +#endif #undef MAP default: break; From fb7ecb15e27a89525569503d627478f9d90df561 Mon Sep 17 00:00:00 2001 From: Li Xiaowei Date: Wed, 18 Dec 2013 13:47:32 +0800 Subject: [PATCH 1633/3781] utils: add H.264 MVC profiles. Add "MultiView High" and "Stereo High" definitions. Signed-off-by: Li Xiaowei [require VA-API >= 0.35.2 for MVC profiles] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiprofile.c | 11 +++++++++++ gst-libs/gst/vaapi/gstvaapiutils.c | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 5b3640ce0e..c50ca2b5b7 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -112,6 +112,14 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_H264_HIGH, VAProfileH264High, "video/x-h264", "high" }, +#if VA_CHECK_VERSION(0,35,2) + { GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH, VAProfileH264MultiviewHigh, + "video/x-h264", "multiview-high" + }, + { GST_VAAPI_PROFILE_H264_STEREO_HIGH, VAProfileH264StereoHigh, + "video/x-h264", "stereo-high" + }, +#endif { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, "video/x-wmv, wmvversion=3", "simple" }, @@ -275,6 +283,9 @@ gst_vaapi_profile_from_codec_data_h264(GstBuffer *buffer) GST_VAAPI_PROFILE_H264_BASELINE); case 77: return GST_VAAPI_PROFILE_H264_MAIN; case 100: return GST_VAAPI_PROFILE_H264_HIGH; + case 118: return GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH; + case 128: return GST_VAAPI_PROFILE_H264_STEREO_HIGH; + } return 0; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index d7f1d852f3..18987f642b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -142,6 +142,10 @@ string_of_VAProfile (VAProfile profile) MAP (H264Baseline); MAP (H264Main); MAP (H264High); +#if VA_CHECK_VERSION(0,35,2) + MAP (H264MultiviewHigh); + MAP (H264StereoHigh); +#endif MAP (VC1Simple); MAP (VC1Main); MAP (VC1Advanced); From 4beee390e5a1bbf04f4bfe710ef044dd1e0c52e7 Mon Sep 17 00:00:00 2001 From: Li Xiaowei Date: Fri, 14 Feb 2014 15:33:15 +0800 Subject: [PATCH 1634/3781] encoder: h264: add provisional support for subset SPS headers. Add provisions to write subset SPS headers to the bitstream in view to supporting the H.264 MVC specification. This assumes the libva "staging" branch is in use. Signed-off-by: Li Xiaowei --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 116 +++++++++++++++++++++- 1 file changed, 111 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 9f90ea292d..ff9a947b2b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -260,7 +260,7 @@ bs_error: /* Write an SPS NAL unit */ static gboolean -bs_write_sps (GstBitWriter * bs, +bs_write_sps_data (GstBitWriter * bs, const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, const VAEncMiscParameterHRD * hrd_params) { @@ -306,7 +306,9 @@ bs_write_sps (GstBitWriter * bs, /* seq_parameter_set_id */ WRITE_UE (bs, seq_param->seq_parameter_set_id); - if (profile == GST_VAAPI_PROFILE_H264_HIGH) { + if (profile == GST_VAAPI_PROFILE_H264_HIGH || + profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH || + profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { /* for high profile */ /* chroma_format_idc = 1, 4:2:0 */ WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc); @@ -465,9 +467,6 @@ bs_write_sps (GstBitWriter * bs, /* bs_restriction_flag */ WRITE_UINT32 (bs, 0, 1); } - - /* rbsp_trailing_bits */ - bs_write_trailing_bits (bs); return TRUE; /* ERRORS */ @@ -478,6 +477,113 @@ bs_error: } } +static gboolean +bs_write_sps (GstBitWriter * bs, + const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, + const VAEncMiscParameterHRD * hrd_params) +{ + if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) + return FALSE; + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + + return FALSE; +} + +static gboolean +bs_write_subset_sps (GstBitWriter * bs, + const VAEncSequenceParameterBufferH264_MVC * seq_param, + GstVaapiProfile profile, const VAEncMiscParameterHRD * hrd_params) +{ + guint32 i, j, k; + + if (!bs_write_sps_data (bs, &seq_param->base, profile, hrd_params)) + return FALSE; + + if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH || + profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH) { + + guint32 num_views_minus1 = seq_param->num_views_minus1; + + /* bit equal to one */ + WRITE_UINT32 (bs, 1, 1); + + WRITE_UE (bs, seq_param->num_views_minus1); + + for (i = 0; i <= num_views_minus1; i++) + WRITE_UE (bs, seq_param->view_list[i].view_id); + + for (i = 1; i <= num_views_minus1; i++) { + guint num_anchor_refs_l0 = seq_param->view_list[i].num_anchor_refs_l0; + WRITE_UE (bs, num_anchor_refs_l0); + for (j = 0; j < num_anchor_refs_l0; j++) + WRITE_UE (bs, seq_param->view_list[i].anchor_ref_l0[j]); + + guint num_anchor_refs_l1 = seq_param->view_list[i].num_anchor_refs_l1; + WRITE_UE (bs, num_anchor_refs_l1); + for (j = 0; j < num_anchor_refs_l1; j++) + WRITE_UE (bs, seq_param->view_list[i].anchor_ref_l1[j]); + } + + for (i = 1; i <= num_views_minus1; i++) { + guint num_non_anchor_refs_l0 = + seq_param->view_list[i].num_non_anchor_refs_l0; + WRITE_UE (bs, num_non_anchor_refs_l0); + for (j = 0; j < num_non_anchor_refs_l0; j++) + WRITE_UE (bs, seq_param->view_list[i].non_anchor_ref_l0[i]); + + guint num_non_anchor_refs_l1 = + seq_param->view_list[i].num_non_anchor_refs_l1; + WRITE_UE (bs, num_non_anchor_refs_l1); + for (j = 0; j < num_non_anchor_refs_l1; j++) + WRITE_UE (bs, seq_param->view_list[i].non_anchor_ref_l1[j]); + } + + /* num level values signalled minus1 */ + WRITE_UE (bs, seq_param->num_level_values_signalled_minus1); + + for (i = 0; i <= seq_param->num_level_values_signalled_minus1; i++) { + struct H264SPSExtMVCLevelValue *level_value = + &(seq_param->level_value_list[i]); + + WRITE_UINT32 (bs, level_value->level_idc, 8); + WRITE_UE (bs, level_value->num_applicable_ops_minus1); + + for (j = 0; j <= level_value->num_applicable_ops_minus1; j++) { + struct H264SPSExtMVCLevelValueOps *level_value_ops = + &(level_value->level_value_ops_list[j]); + + WRITE_UINT32 (bs, level_value_ops->temporal_id, 3); + WRITE_UE (bs, level_value_ops->num_target_views_minus1); + + for (k = 0; k <= level_value_ops->num_target_views_minus1; k++) + WRITE_UE (bs, level_value_ops->target_view_id_list[k]); + + WRITE_UE (bs, level_value_ops->num_views_minus1); + } + } + + /* mvc_vui_parameters_present_flag */ + WRITE_UINT32 (bs, 0, 1); + } + + /* additional_extension2_flag */ + WRITE_UINT32 (bs, 0, 1); + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write subset SPS NAL unit"); + return FALSE; + } + return FALSE; +} + /* Write a PPS NAL unit */ static gboolean bs_write_pps (GstBitWriter * bs, From 5323570a353425930596755dbaf20af6b063e9a7 Mon Sep 17 00:00:00 2001 From: Li Xiaowei Date: Mon, 17 Feb 2014 11:10:26 +0800 Subject: [PATCH 1635/3781] encoder: h264: wrap pools for refs and frames reordering. Create structures to maintain the reference frames list (RefPool) and frames reordering (ReorderPool) logic. This is a prerequisite for H.264 MVC support. Signed-off-by: Li Xiaowei --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 274 ++++++++++++++-------- 1 file changed, 176 insertions(+), 98 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index ff9a947b2b..5ea9638ad8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -36,6 +36,9 @@ #define DEBUG 1 #include "gstvaapidebug.h" +/* Define the maximum number of views supported */ +#define MAX_NUM_VIEWS 2 + /* Define the maximum IDR period */ #define MAX_IDR_PERIOD 512 @@ -97,6 +100,23 @@ typedef enum GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2 } GstVaapiEncH264ReorderState; +typedef struct _GstVaapiH264ViewRefPool +{ + GQueue ref_list; + guint max_ref_frames; + guint max_reflist0_count; + guint max_reflist1_count; +} GstVaapiH264ViewRefPool; + +typedef struct _GstVaapiH264ViewReorderPool +{ + GQueue reorder_frame_list; + guint reorder_state; + guint frame_index; + guint cur_frame_num; + guint cur_present_index; +} GstVaapiH264ViewReorderPool; + static inline gboolean _poc_greater_than (guint poc1, guint poc2, guint max_poc) { @@ -680,22 +700,8 @@ struct _GstVaapiEncoderH264 guint32 mb_height; gboolean use_cabac; gboolean use_dct8x8; - - /* re-ordering */ - GQueue reorder_frame_list; - guint reorder_state; - guint frame_index; - guint cur_frame_num; - guint cur_present_index; GstClockTime cts_offset; - /* reference list */ - GQueue ref_list; - guint max_ref_frames; - /* max reflist count */ - guint max_reflist0_count; - guint max_reflist1_count; - /* frame, poc */ guint32 max_frame_num; guint32 log2_max_frame_num; @@ -709,6 +715,13 @@ struct _GstVaapiEncoderH264 guint bitrate_bits; // bitrate (bits) guint cpb_length; // length of CPB buffer (ms) guint cpb_length_bits; // length of CPB buffer (bits) + + /* MVC */ + gboolean is_mvc; + guint32 view_idx; + guint32 num_views; + GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS]; + GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS]; }; static inline void @@ -954,38 +967,50 @@ ensure_tuning (GstVaapiEncoderH264 * encoder) static void reset_gop_start (GstVaapiEncoderH264 * encoder) { + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[encoder->view_idx]; + + reorder_pool->frame_index = 1; + reorder_pool->cur_frame_num = 0; + reorder_pool->cur_present_index = 0; ++encoder->idr_num; - encoder->frame_index = 1; - encoder->cur_frame_num = 0; - encoder->cur_present_index = 0; } /* Marks the supplied picture as a B-frame */ static void set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[encoder->view_idx]; + g_assert (pic && encoder); g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_B; - pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num); + pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); } /* Marks the supplied picture as a P-frame */ static void set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[encoder->view_idx]; + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_P; - pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num); + pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); } /* Marks the supplied picture as an I-frame */ static void set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[encoder->view_idx]; + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_I; - pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num); + pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); g_assert (pic->frame); GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); @@ -1157,20 +1182,24 @@ reference_list_update (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) { GstVaapiEncoderH264Ref *ref; + GstVaapiH264ViewRefPool *const ref_pool = + &encoder->ref_pools[encoder->view_idx]; if (GST_VAAPI_PICTURE_TYPE_B == picture->type) { gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface); return TRUE; } if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { - while (!g_queue_is_empty (&encoder->ref_list)) - reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list)); - } else if (g_queue_get_length (&encoder->ref_list) >= encoder->max_ref_frames) { - reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list)); + while (!g_queue_is_empty (&ref_pool->ref_list)) + reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list)); + } else if (g_queue_get_length (&ref_pool->ref_list) >= + ref_pool->max_ref_frames) { + reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list)); } ref = reference_pic_create (encoder, picture, surface); - g_queue_push_tail (&encoder->ref_list, ref); - g_assert (g_queue_get_length (&encoder->ref_list) <= encoder->max_ref_frames); + g_queue_push_tail (&ref_pool->ref_list, ref); + g_assert (g_queue_get_length (&ref_pool->ref_list) <= + ref_pool->max_ref_frames); return TRUE; } @@ -1182,6 +1211,8 @@ reference_list_init (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count) { GstVaapiEncoderH264Ref *tmp; + GstVaapiH264ViewRefPool *const ref_pool = + &encoder->ref_pools[encoder->view_idx]; GList *iter, *list_0_start = NULL, *list_1_start = NULL; guint max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); guint count; @@ -1191,7 +1222,7 @@ reference_list_init (GstVaapiEncoderH264 * encoder, if (picture->type == GST_VAAPI_PICTURE_TYPE_I) return TRUE; - iter = g_queue_peek_tail_link (&encoder->ref_list); + iter = g_queue_peek_tail_link (&ref_pool->ref_list); for (; iter; iter = g_list_previous (iter)) { tmp = (GstVaapiEncoderH264Ref *) iter->data; g_assert (tmp && tmp->poc != picture->poc); @@ -1231,6 +1262,8 @@ static gboolean fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) { VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; + GstVaapiH264ViewRefPool *const ref_pool = + &encoder->ref_pools[encoder->view_idx]; memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264)); seq_param->seq_parameter_set_id = 0; @@ -1239,7 +1272,7 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) seq_param->ip_period = 1 + encoder->num_bframes; seq_param->bits_per_second = encoder->bitrate_bits; - seq_param->max_num_ref_frames = encoder->max_ref_frames; + seq_param->max_num_ref_frames = ref_pool->max_ref_frames; seq_param->picture_width_in_mbs = encoder->mb_width; seq_param->picture_height_in_mbs = encoder->mb_height; @@ -1315,6 +1348,8 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) { VAEncPictureParameterBufferH264 *const pic_param = picture->param; + GstVaapiH264ViewRefPool *const ref_pool = + &encoder->ref_pools[encoder->view_idx]; GstVaapiEncoderH264Ref *ref_pic; GList *reflist; guint i; @@ -1326,7 +1361,7 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, pic_param->CurrPic.TopFieldOrderCnt = picture->poc; i = 0; if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { - for (reflist = g_queue_peek_head_link (&encoder->ref_list); + for (reflist = g_queue_peek_head_link (&ref_pool->ref_list); reflist; reflist = g_list_next (reflist)) { ref_pic = reflist->data; g_assert (ref_pic && ref_pic->pic && @@ -1336,7 +1371,7 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); ++i; } - g_assert (i <= 16 && i <= encoder->max_ref_frames); + g_assert (i <= 16 && i <= ref_pool->max_ref_frames); } for (; i < 16; ++i) { pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID; @@ -1349,9 +1384,9 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, pic_param->frame_num = picture->frame_num; pic_param->pic_init_qp = encoder->init_qp; pic_param->num_ref_idx_l0_active_minus1 = - (encoder->max_reflist0_count ? (encoder->max_reflist0_count - 1) : 0); + (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0); pic_param->num_ref_idx_l1_active_minus1 = - (encoder->max_reflist1_count ? (encoder->max_reflist1_count - 1) : 0); + (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0); pic_param->chroma_qp_index_offset = 0; pic_param->second_chroma_qp_index_offset = 0; @@ -1603,6 +1638,8 @@ ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoderH264Ref *reflist_0[16]; GstVaapiEncoderH264Ref *reflist_1[16]; + GstVaapiH264ViewRefPool *const ref_pool = + &encoder->ref_pools[encoder->view_idx]; guint reflist_0_count = 0, reflist_1_count = 0; g_assert (picture); @@ -1614,11 +1651,11 @@ ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) return FALSE; } - g_assert (reflist_0_count + reflist_1_count <= encoder->max_ref_frames); - if (reflist_0_count > encoder->max_reflist0_count) - reflist_0_count = encoder->max_reflist0_count; - if (reflist_1_count > encoder->max_reflist1_count) - reflist_1_count = encoder->max_reflist1_count; + g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames); + if (reflist_0_count > ref_pool->max_reflist0_count) + reflist_0_count = ref_pool->max_reflist0_count; + if (reflist_1_count > ref_pool->max_reflist1_count) + reflist_1_count = ref_pool->max_reflist1_count; if (!add_slice_headers (encoder, picture, reflist_0, reflist_0_count, reflist_1, reflist_1_count)) @@ -1715,7 +1752,7 @@ static void reset_properties (GstVaapiEncoderH264 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - guint mb_size; + guint mb_size, i; if (encoder->idr_period < base_encoder->keyframe_period) encoder->idr_period = base_encoder->keyframe_period; @@ -1748,13 +1785,19 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->max_frame_num = (1 << encoder->log2_max_frame_num); encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1; encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); - - encoder->frame_index = 0; encoder->idr_num = 0; - encoder->max_reflist0_count = 1; - encoder->max_reflist1_count = encoder->num_bframes > 0; - encoder->max_ref_frames = - encoder->max_reflist0_count + encoder->max_reflist1_count; + + for (i = 0; i < encoder->num_views; i++) { + GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; + ref_pool->max_reflist0_count = 1; + ref_pool->max_reflist1_count = encoder->num_bframes > 0; + ref_pool->max_ref_frames = ref_pool->max_reflist0_count + + ref_pool->max_reflist1_count; + + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[i]; + reorder_pool->frame_index = 0; + } } static GstVaapiEncoderStatus @@ -1797,16 +1840,23 @@ gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder) { GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiH264ViewReorderPool *reorder_pool; GstVaapiEncPicture *pic; + guint i; - encoder->frame_index = 0; - encoder->cur_frame_num = 0; - encoder->cur_present_index = 0; - while (!g_queue_is_empty (&encoder->reorder_frame_list)) { - pic = g_queue_pop_head (&encoder->reorder_frame_list); - gst_vaapi_enc_picture_unref (pic); + for (i = 0; i < encoder->num_views; i++) { + reorder_pool = &encoder->reorder_pools[i]; + reorder_pool->frame_index = 0; + reorder_pool->cur_frame_num = 0; + reorder_pool->cur_present_index = 0; + + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&reorder_pool->reorder_frame_list); } - g_queue_clear (&encoder->reorder_frame_list); return GST_VAAPI_ENCODER_STATUS_SUCCESS; } @@ -1908,24 +1958,26 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, { GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiH264ViewReorderPool *reorder_pool = + &encoder->reorder_pools[encoder->view_idx]; GstVaapiEncPicture *picture; gboolean is_idr = FALSE; *output = NULL; if (!frame) { - if (encoder->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES) + if (reorder_pool->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES) return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES dump B frames from queue, sometime, there may also have P frame or I frame */ g_assert (encoder->num_bframes > 0); - g_return_val_if_fail (!g_queue_is_empty (&encoder->reorder_frame_list), + g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list), GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN); - picture = g_queue_pop_head (&encoder->reorder_frame_list); + picture = g_queue_pop_head (&reorder_pool->reorder_frame_list); g_assert (picture); - if (g_queue_is_empty (&encoder->reorder_frame_list)) { - encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; + if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; } goto end; } @@ -1937,60 +1989,60 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; } - ++encoder->cur_present_index; - picture->poc = ((encoder->cur_present_index * 2) % + ++reorder_pool->cur_present_index; + picture->poc = ((reorder_pool->cur_present_index * 2) % encoder->max_pic_order_cnt); - is_idr = (encoder->frame_index == 0 || - encoder->frame_index >= encoder->idr_period); + is_idr = (reorder_pool->frame_index == 0 || + reorder_pool->frame_index >= encoder->idr_period); /* check key frames */ if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) || - (encoder->frame_index % GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == - 0) { - ++encoder->cur_frame_num; - ++encoder->frame_index; + (reorder_pool->frame_index % + GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == 0) { + ++reorder_pool->cur_frame_num; + ++reorder_pool->frame_index; /* b frame enabled, check queue of reorder_frame_list */ if (encoder->num_bframes - && !g_queue_is_empty (&encoder->reorder_frame_list)) { + && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) { GstVaapiEncPicture *p_pic; - p_pic = g_queue_pop_tail (&encoder->reorder_frame_list); + p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list); set_p_frame (p_pic, encoder); - g_queue_foreach (&encoder->reorder_frame_list, + g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame, encoder); - ++encoder->cur_frame_num; + ++reorder_pool->cur_frame_num; set_key_frame (picture, encoder, is_idr); - g_queue_push_tail (&encoder->reorder_frame_list, picture); + g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); picture = p_pic; - encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; } else { /* no b frames in queue */ set_key_frame (picture, encoder, is_idr); - g_assert (g_queue_is_empty (&encoder->reorder_frame_list)); + g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list)); if (encoder->num_bframes) - encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; } goto end; } /* new p/b frames coming */ - ++encoder->frame_index; - if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES && - g_queue_get_length (&encoder->reorder_frame_list) < + ++reorder_pool->frame_index; + if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES && + g_queue_get_length (&reorder_pool->reorder_frame_list) < encoder->num_bframes) { - g_queue_push_tail (&encoder->reorder_frame_list, picture); + g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; } - ++encoder->cur_frame_num; + ++reorder_pool->cur_frame_num; set_p_frame (picture, encoder); - if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) { - g_queue_foreach (&encoder->reorder_frame_list, (GFunc) set_b_frame, + if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) { + g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame, encoder); - encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; - g_assert (!g_queue_is_empty (&encoder->reorder_frame_list)); + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; + g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list)); } end: @@ -2072,16 +2124,32 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder) { GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264_CAST (base_encoder); + guint32 i; - /* re-ordering */ - g_queue_init (&encoder->reorder_frame_list); - encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE; + /* Multi-view coding information */ + encoder->is_mvc = FALSE; + encoder->num_views = 1; + encoder->view_idx = 0; - /* reference frames */ - g_queue_init (&encoder->ref_list); - encoder->max_ref_frames = 0; - encoder->max_reflist0_count = 1; - encoder->max_reflist1_count = 1; + /* re-ordering list initialize */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[i]; + g_queue_init (&reorder_pool->reorder_frame_list); + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE; + reorder_pool->frame_index = 0; + reorder_pool->cur_frame_num = 0; + reorder_pool->cur_present_index = 0; + } + + /* reference list info initialize */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; + g_queue_init (&ref_pool->ref_list); + ref_pool->max_ref_frames = 0; + ref_pool->max_reflist0_count = 1; + ref_pool->max_reflist1_count = 1; + } return TRUE; } @@ -2094,22 +2162,32 @@ gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder) GST_VAAPI_ENCODER_H264_CAST (base_encoder); GstVaapiEncPicture *pic; GstVaapiEncoderH264Ref *ref; + guint32 i; gst_buffer_replace (&encoder->sps_data, NULL); gst_buffer_replace (&encoder->pps_data, NULL); - while (!g_queue_is_empty (&encoder->ref_list)) { - ref = g_queue_pop_head (&encoder->ref_list); - reference_pic_free (encoder, ref); + /* reference list info de-init */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; + while (!g_queue_is_empty (&ref_pool->ref_list)) { + ref = (GstVaapiEncoderH264Ref *) g_queue_pop_head (&ref_pool->ref_list); + reference_pic_free (encoder, ref); + } + g_queue_clear (&ref_pool->ref_list); } - g_queue_clear (&encoder->ref_list); - while (!g_queue_is_empty (&encoder->reorder_frame_list)) { - pic = g_queue_pop_head (&encoder->reorder_frame_list); - gst_vaapi_enc_picture_unref (pic); + /* re-ordering list initialize */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[i]; + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&reorder_pool->reorder_frame_list); } - g_queue_clear (&encoder->reorder_frame_list); - } static GstVaapiEncoderStatus From 7bdf3fa177dffa5be4c5dd079aace0c5368d5277 Mon Sep 17 00:00:00 2001 From: Li Xiaowei Date: Mon, 17 Feb 2014 15:51:43 +0800 Subject: [PATCH 1636/3781] encoder: h264: add initial support for H.264 Stereo High profile. Add initial support for Subset SPS, Prefix NAL and Slice Extension NAL for non-base-view streams encoding, and the usual SPS, PPS and Slice NALs for base-view encoding. The H.264 Stereo High profile encoding mode will be turned on when the "num-views" parameter is set to 2. The source (raw) YUV frames will be considered as Left/Right view, alternatively. Each of the two views has its own frames reordering pool and reference frames list management system. Inter-view references are not supported yet, so the views are encoded independently from each other. Signed-off-by: Li Xiaowei [limited to Stereo High profile per the definition of MAX_NUM_VIEWS] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 299 ++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 + gst-libs/gst/vaapi/gstvaapiutils_h264.c | 2 +- gst/vaapi/gstvaapiencode_h264.c | 2 +- 4 files changed, 283 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 5ea9638ad8..cb88c975a0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -83,7 +83,10 @@ typedef enum GST_VAAPI_ENCODER_H264_NAL_IDR = 5, /* ref_idc != 0 */ GST_VAAPI_ENCODER_H264_NAL_SEI = 6, /* ref_idc == 0 */ GST_VAAPI_ENCODER_H264_NAL_SPS = 7, - GST_VAAPI_ENCODER_H264_NAL_PPS = 8 + GST_VAAPI_ENCODER_H264_NAL_PPS = 8, + GST_VAAPI_ENCODER_H264_NAL_PREFIX = 14, /* mvc nal prefix */ + GST_VAAPI_ENCODER_H264_NAL_SUBSET_SPS = 15, + GST_VAAPI_ENCODER_H264_NAL_SLICE_EXT = 20 } GstVaapiEncoderH264NalType; typedef struct @@ -875,6 +878,12 @@ ensure_profile (GstVaapiEncoderH264 * encoder) if (encoder->use_dct8x8) profile = GST_VAAPI_PROFILE_H264_HIGH; + /* MVC profiles coding tools */ + if (encoder->num_views == 2) + profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH; + else if (encoder->num_views > 2) + profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH; + encoder->profile = profile; encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); return TRUE; @@ -1065,6 +1074,8 @@ add_packed_sequence_header (GstVaapiEncoderH264 * encoder, GstBitWriter bs; VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 }; const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; + GstVaapiProfile profile = encoder->profile; + VAEncMiscParameterHRD hrd_params; guint32 data_bit_size; guint8 *data; @@ -1075,7 +1086,16 @@ add_packed_sequence_header (GstVaapiEncoderH264 * encoder, WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS); - bs_write_sps (&bs, seq_param, encoder->profile, &hrd_params); + + /* Set High profile for encoding the MVC base view. Otherwise, some + traditional decoder cannot recognize MVC profile streams with + only the base view in there */ + if (profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH || + profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) + profile = GST_VAAPI_PROFILE_H264_HIGH; + + bs_write_sps (&bs, seq_param, profile, &hrd_params); + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); data = GST_BIT_WRITER_DATA (&bs); @@ -1106,6 +1126,56 @@ bs_error: } } +static gboolean +add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) +{ + GstVaapiEncPackedHeader *packed_seq; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; + VAEncSequenceParameterBufferH264_MVC *mvc_seq_param = sequence->param; + VAEncMiscParameterHRD hrd_params; + guint32 data_bit_size; + guint8 *data; + + fill_hrd_params (encoder, &hrd_params); + + /* non-base layer, pack one subset sps */ + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, + GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, + GST_VAAPI_ENCODER_H264_NAL_SUBSET_SPS); + + bs_write_subset_sps (&bs, mvc_seq_param, encoder->profile, &hrd_params); + + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_header_param_buffer.type = VAEncPackedHeaderSequence; + packed_header_param_buffer.bit_length = data_bit_size; + packed_header_param_buffer.has_emulation_bytes = 0; + + packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_header_param_buffer, sizeof (packed_header_param_buffer), + data, (data_bit_size + 7) / 8); + g_assert (packed_seq); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + /* Adds the supplied picture header (PPS) to the list of packed headers to pass down as-is to the encoder */ static gboolean @@ -1266,7 +1336,7 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) &encoder->ref_pools[encoder->view_idx]; memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264)); - seq_param->seq_parameter_set_id = 0; + seq_param->seq_parameter_set_id = encoder->view_idx; seq_param->level_idc = encoder->level_idc; seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq_param->ip_period = 1 + encoder->num_bframes; @@ -1342,6 +1412,125 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) return TRUE; } +/* Free MVC sequence parameters used for encoding */ +static void +free_sequence_mvc (GstVaapiEncSequence * sequence) +{ + guint i, j; + VAEncSequenceParameterBufferH264_MVC *mvc_seq = sequence->param; + + if (mvc_seq->view_list) { + g_free (mvc_seq->view_list); + mvc_seq->view_list = NULL; + } + + if (mvc_seq->level_value_list) { + for (i = 0; i <= mvc_seq->num_level_values_signalled_minus1; i++) { + struct H264SPSExtMVCLevelValue *level_value = + &(mvc_seq->level_value_list[i]); + for (j = 0; j < level_value->num_applicable_ops_minus1 + 1; j++) { + struct H264SPSExtMVCLevelValueOps *level_value_ops = + &(level_value->level_value_ops_list[j]); + if (level_value_ops->target_view_id_list) { + g_free (level_value_ops->target_view_id_list); + level_value_ops->target_view_id_list = NULL; + } + } + + g_free (level_value->level_value_ops_list); + level_value->level_value_ops_list = NULL; + } + + g_free (mvc_seq->level_value_list); + mvc_seq->level_value_list = NULL; + } +} + +/* Fills in VA sequence parameter buffer for MVC encoding */ +static gboolean +fill_sequence_mvc (GstVaapiEncoderH264 * encoder, + GstVaapiEncSequence * sequence) +{ + guint i, j, k; + VAEncSequenceParameterBufferH264_MVC *mvc_seq = sequence->param; + guint16 num_views_minus1, num_level_values_signalled_minus1; + struct H264SPSExtMVCViewInfo *view = NULL; + struct H264SPSExtMVCLevelValue *level_value = NULL; + struct H264SPSExtMVCLevelValueOps *level_value_ops = NULL; + + memset (mvc_seq, 0, sizeof (VAEncSequenceParameterBufferH264_MVC)); + + if (!fill_sequence (encoder, sequence)) + return FALSE; + + num_views_minus1 = encoder->num_views - 1; + g_assert (num_views_minus1 < 1024); + mvc_seq->num_views_minus1 = num_views_minus1; + + if (!mvc_seq->view_list) + mvc_seq->view_list = + g_new0 (struct H264SPSExtMVCViewInfo, num_views_minus1 + 1); + + for (i = 0; i <= num_views_minus1; i++) { + view = &(mvc_seq->view_list[i]); + view->view_id = i; + + view->num_anchor_refs_l0 = 15; + for (j = 0; j < view->num_anchor_refs_l0; j++) + view->anchor_ref_l0[j] = 0; + + view->num_anchor_refs_l1 = 15; + for (j = 0; j < view->num_anchor_refs_l1; j++) + view->anchor_ref_l1[j] = 0; + + view->num_non_anchor_refs_l0 = 15; + for (j = 0; j < view->num_non_anchor_refs_l0; j++) + view->non_anchor_ref_l0[j] = 0; + + view->num_non_anchor_refs_l1 = 15; + for (j = 0; j < view->num_non_anchor_refs_l1; j++) + view->non_anchor_ref_l1[j] = 0; + } + + num_level_values_signalled_minus1 = 0; + g_assert (num_level_values_signalled_minus1 < 64); + mvc_seq->num_level_values_signalled_minus1 = + num_level_values_signalled_minus1; + + if (!mvc_seq->level_value_list) + mvc_seq->level_value_list = g_new0 (struct H264SPSExtMVCLevelValue, + num_level_values_signalled_minus1 + 1); + + for (i = 0; i <= num_level_values_signalled_minus1; i++) { + level_value = &(mvc_seq->level_value_list[i]); + + guint16 num_applicable_ops_minus1 = 0; + g_assert (num_applicable_ops_minus1 < 1024); + level_value->num_applicable_ops_minus1 = num_applicable_ops_minus1; + level_value->level_idc = encoder->level; + + if (!level_value->level_value_ops_list) + level_value->level_value_ops_list = + g_new0 (struct H264SPSExtMVCLevelValueOps, + num_applicable_ops_minus1 + 1); + for (j = 0; j <= num_applicable_ops_minus1; j++) { + level_value_ops = &(level_value->level_value_ops_list[j]); + + guint16 num_target_views_minus1 = 1; + level_value_ops->num_target_views_minus1 = num_target_views_minus1; + level_value_ops->num_views_minus1 = num_views_minus1; + + if (!level_value_ops->target_view_id_list) + level_value_ops->target_view_id_list = + g_new0 (guint16, num_views_minus1 + 1); + + for (k = 0; k <= num_target_views_minus1; k++) + level_value_ops->target_view_id_list[k] = k; + } + } + return TRUE; +} + /* Fills in VA picture parameter buffer */ static gboolean fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, @@ -1378,8 +1567,8 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, } pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); - pic_param->pic_parameter_set_id = 0; - pic_param->seq_parameter_set_id = 0; + pic_param->pic_parameter_set_id = encoder->view_idx; + pic_param->seq_parameter_set_id = encoder->view_idx; pic_param->last_picture = 0; /* means last encoding picture */ pic_param->frame_num = picture->frame_num; pic_param->pic_init_qp = encoder->init_qp; @@ -1411,6 +1600,25 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, return TRUE; } +static gboolean +fill_mvc_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, + GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) +{ + VAEncPictureParameterBufferH264_MVC *const mvc_pic = picture->param; + + if (!fill_picture (encoder, picture, codedbuf, surface)) + return FALSE; + + mvc_pic->view_id = encoder->view_idx; + mvc_pic->inter_view_flag = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_I) + mvc_pic->anchor_pic_flag = 1; + else + mvc_pic->anchor_pic_flag = 0; + + return TRUE; +} + /* Adds slice headers to picture */ static gboolean add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, @@ -1448,7 +1656,7 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, slice_param->macroblock_info = VA_INVALID_ID; slice_param->slice_type = h264_get_slice_type (picture->type); g_assert (slice_param->slice_type != -1); - slice_param->pic_parameter_set_id = 0; + slice_param->pic_parameter_set_id = encoder->view_idx; slice_param->idr_pic_id = encoder->idr_num; slice_param->pic_order_cnt_lsb = picture->poc; @@ -1542,22 +1750,38 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, static gboolean ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { - GstVaapiEncSequence *sequence; + GstVaapiEncSequence *sequence = NULL; // Submit an SPS header before every new I-frame if (picture->type != GST_VAAPI_PICTURE_TYPE_I) return TRUE; - sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder); - if (!sequence || !fill_sequence (encoder, sequence)) - goto error_create_seq_param; + /* add subset sps for non-base view and sps for base view */ + if (encoder->is_mvc && encoder->view_idx) { + sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264_MVC, encoder); + if (!sequence || !fill_sequence_mvc (encoder, sequence)) + goto error_create_seq_param; - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS) - && !add_packed_sequence_header (encoder, picture, sequence)) - goto error_create_packed_seq_hdr; + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS) + && !add_packed_sequence_header_mvc (encoder, picture, sequence)) + goto error_create_packed_seq_hdr; - gst_vaapi_enc_picture_set_sequence (picture, sequence); - gst_vaapi_codec_object_replace (&sequence, NULL); + free_sequence_mvc (sequence); + + } else { + sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder); + if (!sequence || !fill_sequence (encoder, sequence)) + goto error_create_seq_param; + + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS) + && !add_packed_sequence_header (encoder, picture, sequence)) + goto error_create_packed_seq_hdr; + } + + if (sequence) { + gst_vaapi_enc_picture_set_sequence (picture, sequence); + gst_vaapi_codec_object_replace (&sequence, NULL); + } return TRUE; /* ERRORS */ @@ -1619,8 +1843,14 @@ ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, { GstVaapiCodedBuffer *const codedbuf = GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); + gboolean res = FALSE; - if (!fill_picture (encoder, picture, codedbuf, surface)) + if (encoder->is_mvc) + res = fill_mvc_picture (encoder, picture, codedbuf, surface); + else + res = fill_picture (encoder, picture, codedbuf, surface); + + if (!res) return FALSE; if (picture->type == GST_VAAPI_PICTURE_TYPE_I && @@ -1787,6 +2017,7 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); encoder->idr_num = 0; + encoder->is_mvc = encoder->num_views > 1; for (i = 0; i < encoder->num_views; i++) { GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; ref_pool->max_reflist0_count = 1; @@ -1958,13 +2189,21 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, { GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264_CAST (base_encoder); - GstVaapiH264ViewReorderPool *reorder_pool = - &encoder->reorder_pools[encoder->view_idx]; + GstVaapiH264ViewReorderPool *reorder_pool = NULL; GstVaapiEncPicture *picture; gboolean is_idr = FALSE; *output = NULL; + /* encoding views alternatively for MVC */ + if (encoder->is_mvc) { + if (frame) + encoder->view_idx = frame->system_frame_number % MAX_NUM_VIEWS; + else + encoder->view_idx = (encoder->view_idx + 1) % MAX_NUM_VIEWS; + } + reorder_pool = &encoder->reorder_pools[encoder->view_idx]; + if (!frame) { if (reorder_pool->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES) return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; @@ -1983,7 +2222,11 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, } /* new frame coming */ - picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame); + if (encoder->is_mvc) + picture = GST_VAAPI_ENC_PICTURE_NEW (H264_MVC, encoder, frame); + else + picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame); + if (!picture) { GST_WARNING ("create H264 picture failed, frame timestamp:%" GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); @@ -2077,7 +2320,8 @@ set_context_info (GstVaapiEncoder * base_encoder) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; base_encoder->num_ref_frames = - (encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT; + ((encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT) + * encoder->view_idx; /* Only YUV 4:2:0 formats are supported for now. This means that we have a limit of 3200 bits per macroblock. */ @@ -2219,6 +2463,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH: encoder->cpb_length = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: + encoder->num_views = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -2359,6 +2606,18 @@ gst_vaapi_encoder_h264_get_default_properties (void) 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:num-views: + * + * The number of views for MVC encoding . + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS, + g_param_spec_uint ("num-views", + "Number of Views", + "Number of Views for MVC encoding", + 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 3eaa3cb1e8..77d7f0a42b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -46,6 +46,7 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * transforms in I-frames (bool). * @GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH: Length of the CPB buffer * in milliseconds (uint). + * @GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: Number of views per frame. * * The set of H.264 encoder specific configurable properties. */ @@ -57,6 +58,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_CABAC = -5, GST_VAAPI_ENCODER_H264_PROP_DCT8X8 = -6, GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH = -7, + GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS = -8, } GstVaapiEncoderH264Prop; GstVaapiEncoder * diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index 48a3d12072..f8d95feeac 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -43,8 +43,8 @@ static const struct map gst_vaapi_h264_profile_map[] = { { GST_VAAPI_PROFILE_H264_HIGH_444, "high-4:4:4" }, { GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE, "scalable-baseline" }, { GST_VAAPI_PROFILE_H264_SCALABLE_HIGH, "scalable-high" }, - { GST_VAAPI_PROFILE_H264_STEREO_HIGH, "stereo-high" }, { GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH, "multiview-high" }, + { GST_VAAPI_PROFILE_H264_STEREO_HIGH, "stereo-high" }, { 0, NULL } /* *INDENT-ON* */ }; diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 6a36e61d64..815f2a610d 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -63,7 +63,7 @@ static const char gst_vaapiencode_h264_sink_caps_str[] = /* *INDENT-OFF* */ static const char gst_vaapiencode_h264_src_caps_str[] = GST_CODEC_CAPS ", " - "profile = (string) { constrained-baseline, baseline, main, high }"; + "profile = (string) { constrained-baseline, baseline, main, high, multiview-high, stereo-high }"; /* *INDENT-ON* */ /* *INDENT-OFF* */ From f0924ba0d1839405f8a5dfdda6ff7e29379a20ec Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 7 May 2014 00:08:33 +0300 Subject: [PATCH 1637/3781] encoder: h264: fix MVC pipeline hang while encoding with B-frames. Since we are encoding each view independently from each other, we need a higher number of pre-allocated surfaces to be used as the reconstructed frames. For Stereo High profile encoding, this means to effectively double the number of frames to be stored in the DPB. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index cb88c975a0..6930ec3fa4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2321,7 +2321,7 @@ set_context_info (GstVaapiEncoder * base_encoder) base_encoder->num_ref_frames = ((encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT) - * encoder->view_idx; + * encoder->num_views; /* Only YUV 4:2:0 formats are supported for now. This means that we have a limit of 3200 bits per macroblock. */ From 73355a680f87d9cc56e7c165fb4e1904c5feb166 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 7 May 2014 00:09:19 +0300 Subject: [PATCH 1638/3781] encoder: h264: store subset sps to generate the codec-data Store the SubsetSPS nal unit which we need for MVC specific codec_data generation. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 6930ec3fa4..9140c7513c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -713,6 +713,7 @@ struct _GstVaapiEncoderH264 guint32 idr_num; GstBuffer *sps_data; + GstBuffer *subset_sps_data; GstBuffer *pps_data; guint bitrate_bits; // bitrate (bits) @@ -733,10 +734,12 @@ _check_sps_pps_status (GstVaapiEncoderH264 * encoder, { guint8 nal_type; gsize ret; + gboolean has_subset_sps; g_assert (size); - if (encoder->sps_data && encoder->pps_data) + has_subset_sps = !encoder->is_mvc || (encoder->subset_sps_data != NULL); + if (encoder->sps_data && encoder->pps_data && has_subset_sps) return; nal_type = nal[0] & 0x1F; @@ -746,6 +749,11 @@ _check_sps_pps_status (GstVaapiEncoderH264 * encoder, ret = gst_buffer_fill (encoder->sps_data, 0, nal, size); g_assert (ret == size); break; + case GST_VAAPI_ENCODER_H264_NAL_SUBSET_SPS: + encoder->subset_sps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (encoder->subset_sps_data, 0, nal, size); + g_assert (ret == size); + break; case GST_VAAPI_ENCODER_H264_NAL_PPS: encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL); ret = gst_buffer_fill (encoder->pps_data, 0, nal, size); @@ -1164,6 +1172,9 @@ add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder, gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL); + + /* store subset sps data */ + _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); gst_bit_writer_clear (&bs, TRUE); return TRUE; @@ -2409,6 +2420,7 @@ gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder) guint32 i; gst_buffer_replace (&encoder->sps_data, NULL); + gst_buffer_replace (&encoder->subset_sps_data, NULL); gst_buffer_replace (&encoder->pps_data, NULL); /* reference list info de-init */ From 0de9fd634747339ccd4aa53bdd697f9aabe9fdfb Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 7 May 2014 00:09:45 +0300 Subject: [PATCH 1639/3781] encoder: h264: add support for packed slice headers. https://bugzilla.gnome.org/show_bug.cgi?id=722905 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 216 +++++++++++++++++++++- 1 file changed, 213 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 9140c7513c..be56bd0eda 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -69,7 +69,8 @@ /* Supported set of VA packed headers, within this implementation */ #define SUPPORTED_PACKED_HEADERS \ (VA_ENC_PACKED_HEADER_SEQUENCE | \ - VA_ENC_PACKED_HEADER_PICTURE) + VA_ENC_PACKED_HEADER_PICTURE | \ + VA_ENC_PACKED_HEADER_SLICE) #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1 @@ -711,6 +712,8 @@ struct _GstVaapiEncoderH264 guint32 max_pic_order_cnt; guint32 log2_max_pic_order_cnt; guint32 idr_num; + guint8 pic_order_cnt_type; + guint8 delta_pic_order_always_zero_flag; GstBuffer *sps_data; GstBuffer *subset_sps_data; @@ -728,6 +731,124 @@ struct _GstVaapiEncoderH264 GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS]; }; +/* Write a Slice NAL unit */ +static gboolean +bs_write_slice (GstBitWriter * bs, + const VAEncSliceParameterBufferH264 * slice_param, + GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) +{ + const VAEncPictureParameterBufferH264 *const pic_param = picture->param; + guint32 field_pic_flag = 0; + guint32 ref_pic_list_modification_flag_l0 = 0; + guint32 ref_pic_list_modification_flag_l1 = 0; + guint32 no_output_of_prior_pics_flag = 0; + guint32 long_term_reference_flag = 0; + guint32 adaptive_ref_pic_marking_mode_flag = 0; + + /* first_mb_in_slice */ + WRITE_UE (bs, slice_param->macroblock_address); + /* slice_type */ + WRITE_UE (bs, slice_param->slice_type); + /* pic_parameter_set_id */ + WRITE_UE (bs, slice_param->pic_parameter_set_id); + /* frame_num */ + WRITE_UINT32 (bs, picture->frame_num, encoder->log2_max_frame_num); + + /* XXX: only frames (i.e. non-interlaced) are supported for now */ + /* frame_mbs_only_flag == 0 */ + + /* idr_pic_id */ + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + WRITE_UE (bs, slice_param->idr_pic_id); + + /* XXX: only POC type 0 is supported */ + if (!encoder->pic_order_cnt_type) { + WRITE_UINT32 (bs, slice_param->pic_order_cnt_lsb, + encoder->log2_max_pic_order_cnt); + /* bottom_field_pic_order_in_frame_present_flag is FALSE */ + if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag) + WRITE_SE (bs, slice_param->delta_pic_order_cnt_bottom); + } else if (encoder->pic_order_cnt_type == 1 && + !encoder->delta_pic_order_always_zero_flag) { + WRITE_SE (bs, slice_param->delta_pic_order_cnt[0]); + if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag) + WRITE_SE (bs, slice_param->delta_pic_order_cnt[1]); + } + /* redundant_pic_cnt_present_flag is FALSE, no redundant coded pictures */ + + /* only works for B-frames */ + if (slice_param->slice_type == 1) + WRITE_UINT32 (bs, slice_param->direct_spatial_mv_pred_flag, 1); + + /* not supporting SP slices */ + if (slice_param->slice_type == 0 || slice_param->slice_type == 1) { + WRITE_UINT32 (bs, slice_param->num_ref_idx_active_override_flag, 1); + if (slice_param->num_ref_idx_active_override_flag) { + WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1); + if (slice_param->slice_type == 1) + WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1); + } + } + /* XXX: not supporting custom reference picture list modifications */ + if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4)) + WRITE_UINT32 (bs, ref_pic_list_modification_flag_l0, 1); + if (slice_param->slice_type == 1) + WRITE_UINT32 (bs, ref_pic_list_modification_flag_l1, 1); + + /* we have: weighted_pred_flag == FALSE and */ + /* : weighted_bipred_idc == FALSE */ + if ((pic_param->pic_fields.bits.weighted_pred_flag && + (slice_param->slice_type == 0)) || + ((pic_param->pic_fields.bits.weighted_bipred_idc == 1) && + (slice_param->slice_type == 1))) { + /* XXXX: add pred_weight_table() */ + } + + /* dec_ref_pic_marking() */ + if (slice_param->slice_type == 0 || slice_param->slice_type == 2) { + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { + /* no_output_of_prior_pics_flag = 0 */ + WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1); + /* long_term_reference_flag = 0 */ + WRITE_UINT32 (bs, long_term_reference_flag, 1); + } else { + /* only sliding_window reference picture marking mode is supported */ + /* adpative_ref_pic_marking_mode_flag = 0 */ + WRITE_UINT32 (bs, adaptive_ref_pic_marking_mode_flag, 1); + } + } + + /* cabac_init_idc */ + if (pic_param->pic_fields.bits.entropy_coding_mode_flag && + slice_param->slice_type != 2) + WRITE_UE (bs, slice_param->cabac_init_idc); + /*slice_qp_delta */ + WRITE_SE (bs, slice_param->slice_qp_delta); + + /* XXX: only supporting I, P and B type slices */ + /* no sp_for_switch_flag and no slice_qs_delta */ + + if (pic_param->pic_fields.bits.deblocking_filter_control_present_flag) { + /* disable_deblocking_filter_idc */ + WRITE_UE (bs, slice_param->disable_deblocking_filter_idc); + if (slice_param->disable_deblocking_filter_idc != 1) { + WRITE_SE (bs, slice_param->slice_alpha_c0_offset_div2); + WRITE_SE (bs, slice_param->slice_beta_offset_div2); + } + } + + /* XXX: unsupported arbitrary slice ordering (ASO) */ + /* num_slic_groups_minus1 should be zero */ + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Slice NAL unit"); + return FALSE; + } +} + static inline void _check_sps_pps_status (GstVaapiEncoderH264 * encoder, const guint8 * nal, guint32 size) @@ -1235,6 +1356,81 @@ bs_error: } } +static gboolean +get_nal_hdr_attributes (GstVaapiEncPicture * picture, + guint8 * nal_ref_idc, guint8 * nal_unit_type) +{ + switch (picture->type) { + case GST_VAAPI_PICTURE_TYPE_I: + *nal_ref_idc = GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH; + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + *nal_unit_type = GST_VAAPI_ENCODER_H264_NAL_IDR; + else + *nal_unit_type = GST_VAAPI_ENCODER_H264_NAL_NON_IDR; + break; + case GST_VAAPI_PICTURE_TYPE_P: + *nal_ref_idc = GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM; + *nal_unit_type = GST_VAAPI_ENCODER_H264_NAL_NON_IDR; + break; + case GST_VAAPI_PICTURE_TYPE_B: + *nal_ref_idc = GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE; + *nal_unit_type = GST_VAAPI_ENCODER_H264_NAL_NON_IDR; + break; + default: + return FALSE; + } + return TRUE; +} + +/* Adds the supplied slice header to the list of packed + headers to pass down as-is to the encoder */ +static gboolean +add_packed_slice_header (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, GstVaapiEncSlice * slice) +{ + GstVaapiEncPackedHeader *packed_slice; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 }; + const VAEncSliceParameterBufferH264 *const slice_param = slice->param; + guint32 data_bit_size; + guint8 *data; + guint8 nal_ref_idc, nal_unit_type; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + + if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) + goto bs_error; + bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); + + bs_write_slice (&bs, slice_param, encoder, picture); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_slice_param.type = VAEncPackedHeaderSlice; + packed_slice_param.bit_length = data_bit_size; + packed_slice_param.has_emulation_bytes = 0; + + packed_slice = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_slice_param, sizeof (packed_slice_param), + data, (data_bit_size + 7) / 8); + g_assert (packed_slice); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_slice); + gst_vaapi_codec_object_replace (&packed_slice, NULL); + + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Slice NAL unit header"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + /* Reference picture management */ static void reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref) @@ -1369,7 +1565,8 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) seq_param->seq_fields.bits.log2_max_frame_num_minus4 = encoder->log2_max_frame_num - 4; /* picture order count */ - seq_param->seq_fields.bits.pic_order_cnt_type = 0; + encoder->pic_order_cnt_type = seq_param->seq_fields.bits.pic_order_cnt_type = + 0; g_assert (encoder->log2_max_pic_order_cnt >= 4); seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = encoder->log2_max_pic_order_cnt - 4; @@ -1379,7 +1576,8 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) /* not used if pic_order_cnt_type == 0 */ if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { - seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE; + encoder->delta_pic_order_always_zero_flag = + seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE; seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0; seq_param->offset_for_non_ref_pic = 0; seq_param->offset_for_top_to_bottom_field = 0; @@ -1750,11 +1948,23 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, /* set calculation for next slice */ last_mb_index += cur_slice_mbs; + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VAEncPackedHeaderH264_Slice) + && !add_packed_slice_header (encoder, picture, slice)) + goto error_create_packed_slice_hdr; + gst_vaapi_enc_picture_add_slice (picture, slice); gst_vaapi_codec_object_replace (&slice, NULL); } g_assert (last_mb_index == mb_size); return TRUE; + +error_create_packed_slice_hdr: + { + GST_ERROR ("failed to create packed slice header buffer"); + gst_vaapi_codec_object_replace (&slice, NULL); + return FALSE; + } } /* Generates and submits SPS header accordingly into the bitstream */ From dba440b164751bc3350cb9fee1e9ab8c3ba55664 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 7 May 2014 00:12:39 +0300 Subject: [PATCH 1640/3781] encoder: h264: use packed headers mode for MVC encoding. Exclusively use VA drivers that support raw packed headers for encoding. i.e. simply submit packed headers Subset SPS and Prefix NAL units. This provides for better compatibility accross the various VA drivers and HW generations since no particular API is needed beyond what readily exists. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 333 +++++++++------------- 1 file changed, 142 insertions(+), 191 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index be56bd0eda..a668906a24 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -70,7 +70,8 @@ #define SUPPORTED_PACKED_HEADERS \ (VA_ENC_PACKED_HEADER_SEQUENCE | \ VA_ENC_PACKED_HEADER_PICTURE | \ - VA_ENC_PACKED_HEADER_SLICE) + VA_ENC_PACKED_HEADER_SLICE | \ + VA_ENC_PACKED_HEADER_RAW_DATA) #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1 @@ -265,6 +266,44 @@ bs_error: } } +/* Write the MVC NAL unit header extension */ +static gboolean +bs_write_nal_header_mvc_extension (GstBitWriter * bs, + GstVaapiEncPicture * picture, guint32 view_id) +{ + guint32 svc_extension_flag = 0; + guint32 non_idr_flag = 1; + guint32 priority_id = 0; + guint32 temporal_id = 0; + guint32 anchor_pic_flag = 0; + guint32 inter_view_flag = 0; + + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + non_idr_flag = 0; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_I) + anchor_pic_flag = 1; + /* svc_extension_flag == 0 for mvc stream */ + WRITE_UINT32 (bs, svc_extension_flag, 1); + + WRITE_UINT32 (bs, non_idr_flag, 1); + WRITE_UINT32 (bs, priority_id, 6); + WRITE_UINT32 (bs, view_id, 10); + WRITE_UINT32 (bs, temporal_id, 3); + WRITE_UINT32 (bs, anchor_pic_flag, 1); + WRITE_UINT32 (bs, inter_view_flag, 1); + WRITE_UINT32 (bs, 1, 1); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write NAL unit header"); + return FALSE; + } +} + /* Write the NAL unit trailing bits */ static gboolean bs_write_trailing_bits (GstBitWriter * bs) @@ -517,74 +556,75 @@ bs_write_sps (GstBitWriter * bs, static gboolean bs_write_subset_sps (GstBitWriter * bs, - const VAEncSequenceParameterBufferH264_MVC * seq_param, - GstVaapiProfile profile, const VAEncMiscParameterHRD * hrd_params) + const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, + guint num_views, const VAEncMiscParameterHRD * hrd_params) { guint32 i, j, k; - if (!bs_write_sps_data (bs, &seq_param->base, profile, hrd_params)) + if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) return FALSE; if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH || profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH) { + guint32 num_views_minus1, num_level_values_signalled_minus1; - guint32 num_views_minus1 = seq_param->num_views_minus1; + num_views_minus1 = num_views - 1; + g_assert (num_views_minus1 < 1024); /* bit equal to one */ WRITE_UINT32 (bs, 1, 1); - WRITE_UE (bs, seq_param->num_views_minus1); + WRITE_UE (bs, num_views_minus1); for (i = 0; i <= num_views_minus1; i++) - WRITE_UE (bs, seq_param->view_list[i].view_id); + WRITE_UE (bs, i); for (i = 1; i <= num_views_minus1; i++) { - guint num_anchor_refs_l0 = seq_param->view_list[i].num_anchor_refs_l0; + guint32 num_anchor_refs_l0 = 15; WRITE_UE (bs, num_anchor_refs_l0); for (j = 0; j < num_anchor_refs_l0; j++) - WRITE_UE (bs, seq_param->view_list[i].anchor_ref_l0[j]); + WRITE_UE (bs, 0); - guint num_anchor_refs_l1 = seq_param->view_list[i].num_anchor_refs_l1; + guint32 num_anchor_refs_l1 = 15; WRITE_UE (bs, num_anchor_refs_l1); for (j = 0; j < num_anchor_refs_l1; j++) - WRITE_UE (bs, seq_param->view_list[i].anchor_ref_l1[j]); + WRITE_UE (bs, 0); } for (i = 1; i <= num_views_minus1; i++) { - guint num_non_anchor_refs_l0 = - seq_param->view_list[i].num_non_anchor_refs_l0; + guint num_non_anchor_refs_l0 = 15; WRITE_UE (bs, num_non_anchor_refs_l0); for (j = 0; j < num_non_anchor_refs_l0; j++) - WRITE_UE (bs, seq_param->view_list[i].non_anchor_ref_l0[i]); + WRITE_UE (bs, 0); - guint num_non_anchor_refs_l1 = - seq_param->view_list[i].num_non_anchor_refs_l1; + guint num_non_anchor_refs_l1 = 15; WRITE_UE (bs, num_non_anchor_refs_l1); for (j = 0; j < num_non_anchor_refs_l1; j++) - WRITE_UE (bs, seq_param->view_list[i].non_anchor_ref_l1[j]); + WRITE_UE (bs, 0); } /* num level values signalled minus1 */ - WRITE_UE (bs, seq_param->num_level_values_signalled_minus1); + num_level_values_signalled_minus1 = 0; + g_assert (num_level_values_signalled_minus1 < 64); - for (i = 0; i <= seq_param->num_level_values_signalled_minus1; i++) { - struct H264SPSExtMVCLevelValue *level_value = - &(seq_param->level_value_list[i]); + for (i = 0; i <= num_level_values_signalled_minus1; i++) { + guint16 num_applicable_ops_minus1 = 0; + g_assert (num_applicable_ops_minus1 < 1024); - WRITE_UINT32 (bs, level_value->level_idc, 8); - WRITE_UE (bs, level_value->num_applicable_ops_minus1); + WRITE_UINT32 (bs, seq_param->level_idc, 8); + WRITE_UE (bs, num_applicable_ops_minus1); - for (j = 0; j <= level_value->num_applicable_ops_minus1; j++) { - struct H264SPSExtMVCLevelValueOps *level_value_ops = - &(level_value->level_value_ops_list[j]); + for (j = 0; j <= num_applicable_ops_minus1; j++) { + guint8 temporal_id = 0; + guint16 num_target_views_minus1 = 1; - WRITE_UINT32 (bs, level_value_ops->temporal_id, 3); - WRITE_UE (bs, level_value_ops->num_target_views_minus1); + WRITE_UINT32 (bs, temporal_id, 3); + WRITE_UE (bs, num_target_views_minus1); - for (k = 0; k <= level_value_ops->num_target_views_minus1; k++) - WRITE_UE (bs, level_value_ops->target_view_id_list[k]); + for (k = 0; k <= num_target_views_minus1; k++) + WRITE_UE (bs, k); - WRITE_UE (bs, level_value_ops->num_views_minus1); + WRITE_UE (bs, num_views_minus1); } } @@ -1262,7 +1302,7 @@ add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder, GstVaapiEncPackedHeader *packed_seq; GstBitWriter bs; VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; - VAEncSequenceParameterBufferH264_MVC *mvc_seq_param = sequence->param; + const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; VAEncMiscParameterHRD hrd_params; guint32 data_bit_size; guint8 *data; @@ -1276,7 +1316,8 @@ add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder, GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SUBSET_SPS); - bs_write_subset_sps (&bs, mvc_seq_param, encoder->profile, &hrd_params); + bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views, + &hrd_params); g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); @@ -1382,6 +1423,58 @@ get_nal_hdr_attributes (GstVaapiEncPicture * picture, return TRUE; } +/* Adds the supplied prefix nal header to the list of packed + headers to pass down as-is to the encoder */ +static gboolean +add_packed_prefix_nal_header (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncPackedHeader *packed_prefix_nal; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_prefix_nal_param = { 0 }; + guint32 data_bit_size; + guint8 *data; + guint8 nal_ref_idc, nal_unit_type; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + + if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) + goto bs_error; + nal_unit_type = GST_VAAPI_ENCODER_H264_NAL_PREFIX; + + bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); + bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_idx); + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_prefix_nal_param.type = VAEncPackedHeaderRawData; + packed_prefix_nal_param.bit_length = data_bit_size; + packed_prefix_nal_param.has_emulation_bytes = 0; + + packed_prefix_nal = + gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_prefix_nal_param, sizeof (packed_prefix_nal_param), data, + (data_bit_size + 7) / 8); + g_assert (packed_prefix_nal); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_prefix_nal); + gst_vaapi_codec_object_replace (&packed_prefix_nal, NULL); + + gst_bit_writer_clear (&bs, TRUE); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Prefix NAL unit header"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + /* Adds the supplied slice header to the list of packed headers to pass down as-is to the encoder */ static gboolean @@ -1621,125 +1714,6 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) return TRUE; } -/* Free MVC sequence parameters used for encoding */ -static void -free_sequence_mvc (GstVaapiEncSequence * sequence) -{ - guint i, j; - VAEncSequenceParameterBufferH264_MVC *mvc_seq = sequence->param; - - if (mvc_seq->view_list) { - g_free (mvc_seq->view_list); - mvc_seq->view_list = NULL; - } - - if (mvc_seq->level_value_list) { - for (i = 0; i <= mvc_seq->num_level_values_signalled_minus1; i++) { - struct H264SPSExtMVCLevelValue *level_value = - &(mvc_seq->level_value_list[i]); - for (j = 0; j < level_value->num_applicable_ops_minus1 + 1; j++) { - struct H264SPSExtMVCLevelValueOps *level_value_ops = - &(level_value->level_value_ops_list[j]); - if (level_value_ops->target_view_id_list) { - g_free (level_value_ops->target_view_id_list); - level_value_ops->target_view_id_list = NULL; - } - } - - g_free (level_value->level_value_ops_list); - level_value->level_value_ops_list = NULL; - } - - g_free (mvc_seq->level_value_list); - mvc_seq->level_value_list = NULL; - } -} - -/* Fills in VA sequence parameter buffer for MVC encoding */ -static gboolean -fill_sequence_mvc (GstVaapiEncoderH264 * encoder, - GstVaapiEncSequence * sequence) -{ - guint i, j, k; - VAEncSequenceParameterBufferH264_MVC *mvc_seq = sequence->param; - guint16 num_views_minus1, num_level_values_signalled_minus1; - struct H264SPSExtMVCViewInfo *view = NULL; - struct H264SPSExtMVCLevelValue *level_value = NULL; - struct H264SPSExtMVCLevelValueOps *level_value_ops = NULL; - - memset (mvc_seq, 0, sizeof (VAEncSequenceParameterBufferH264_MVC)); - - if (!fill_sequence (encoder, sequence)) - return FALSE; - - num_views_minus1 = encoder->num_views - 1; - g_assert (num_views_minus1 < 1024); - mvc_seq->num_views_minus1 = num_views_minus1; - - if (!mvc_seq->view_list) - mvc_seq->view_list = - g_new0 (struct H264SPSExtMVCViewInfo, num_views_minus1 + 1); - - for (i = 0; i <= num_views_minus1; i++) { - view = &(mvc_seq->view_list[i]); - view->view_id = i; - - view->num_anchor_refs_l0 = 15; - for (j = 0; j < view->num_anchor_refs_l0; j++) - view->anchor_ref_l0[j] = 0; - - view->num_anchor_refs_l1 = 15; - for (j = 0; j < view->num_anchor_refs_l1; j++) - view->anchor_ref_l1[j] = 0; - - view->num_non_anchor_refs_l0 = 15; - for (j = 0; j < view->num_non_anchor_refs_l0; j++) - view->non_anchor_ref_l0[j] = 0; - - view->num_non_anchor_refs_l1 = 15; - for (j = 0; j < view->num_non_anchor_refs_l1; j++) - view->non_anchor_ref_l1[j] = 0; - } - - num_level_values_signalled_minus1 = 0; - g_assert (num_level_values_signalled_minus1 < 64); - mvc_seq->num_level_values_signalled_minus1 = - num_level_values_signalled_minus1; - - if (!mvc_seq->level_value_list) - mvc_seq->level_value_list = g_new0 (struct H264SPSExtMVCLevelValue, - num_level_values_signalled_minus1 + 1); - - for (i = 0; i <= num_level_values_signalled_minus1; i++) { - level_value = &(mvc_seq->level_value_list[i]); - - guint16 num_applicable_ops_minus1 = 0; - g_assert (num_applicable_ops_minus1 < 1024); - level_value->num_applicable_ops_minus1 = num_applicable_ops_minus1; - level_value->level_idc = encoder->level; - - if (!level_value->level_value_ops_list) - level_value->level_value_ops_list = - g_new0 (struct H264SPSExtMVCLevelValueOps, - num_applicable_ops_minus1 + 1); - for (j = 0; j <= num_applicable_ops_minus1; j++) { - level_value_ops = &(level_value->level_value_ops_list[j]); - - guint16 num_target_views_minus1 = 1; - level_value_ops->num_target_views_minus1 = num_target_views_minus1; - level_value_ops->num_views_minus1 = num_views_minus1; - - if (!level_value_ops->target_view_id_list) - level_value_ops->target_view_id_list = - g_new0 (guint16, num_views_minus1 + 1); - - for (k = 0; k <= num_target_views_minus1; k++) - level_value_ops->target_view_id_list[k] = k; - } - } - return TRUE; -} - /* Fills in VA picture parameter buffer */ static gboolean fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, @@ -1809,25 +1783,6 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, return TRUE; } -static gboolean -fill_mvc_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, - GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) -{ - VAEncPictureParameterBufferH264_MVC *const mvc_pic = picture->param; - - if (!fill_picture (encoder, picture, codedbuf, surface)) - return FALSE; - - mvc_pic->view_id = encoder->view_idx; - mvc_pic->inter_view_flag = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_I) - mvc_pic->anchor_pic_flag = 1; - else - mvc_pic->anchor_pic_flag = 0; - - return TRUE; -} - /* Adds slice headers to picture */ static gboolean add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, @@ -1948,6 +1903,10 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, /* set calculation for next slice */ last_mb_index += cur_slice_mbs; + if (encoder->is_mvc && + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderRawData) + && !add_packed_prefix_nal_header (encoder, picture)) + goto error_create_packed_prefix_nal_hdr; if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_Slice) && !add_packed_slice_header (encoder, picture, slice)) @@ -1965,6 +1924,12 @@ error_create_packed_slice_hdr: gst_vaapi_codec_object_replace (&slice, NULL); return FALSE; } +error_create_packed_prefix_nal_hdr: + { + GST_ERROR ("failed to create packed prefix nal header buffer"); + gst_vaapi_codec_object_replace (&slice, NULL); + return FALSE; + } } /* Generates and submits SPS header accordingly into the bitstream */ @@ -1977,23 +1942,16 @@ ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) if (picture->type != GST_VAAPI_PICTURE_TYPE_I) return TRUE; + sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder); + if (!sequence || !fill_sequence (encoder, sequence)) + goto error_create_seq_param; + /* add subset sps for non-base view and sps for base view */ if (encoder->is_mvc && encoder->view_idx) { - sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264_MVC, encoder); - if (!sequence || !fill_sequence_mvc (encoder, sequence)) - goto error_create_seq_param; - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS) && !add_packed_sequence_header_mvc (encoder, picture, sequence)) goto error_create_packed_seq_hdr; - - free_sequence_mvc (sequence); - } else { - sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder); - if (!sequence || !fill_sequence (encoder, sequence)) - goto error_create_seq_param; - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS) && !add_packed_sequence_header (encoder, picture, sequence)) goto error_create_packed_seq_hdr; @@ -2066,10 +2024,7 @@ ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); gboolean res = FALSE; - if (encoder->is_mvc) - res = fill_mvc_picture (encoder, picture, codedbuf, surface); - else - res = fill_picture (encoder, picture, codedbuf, surface); + res = fill_picture (encoder, picture, codedbuf, surface); if (!res) return FALSE; @@ -2443,11 +2398,7 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, } /* new frame coming */ - if (encoder->is_mvc) - picture = GST_VAAPI_ENC_PICTURE_NEW (H264_MVC, encoder, frame); - else - picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame); - + picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame); if (!picture) { GST_WARNING ("create H264 picture failed, frame timestamp:%" GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); From 6df5c7408133fdfec5eee5cf5d82039d2c418f3b Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 1 Apr 2014 14:23:56 +0300 Subject: [PATCH 1641/3781] encoder: h264: don't allow CABAC with Extended profile. The H.264 specification does not support CABAC entropy coding for the Extended profile. https://bugzilla.gnome.org/show_bug.cgi?id=727418 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index a668906a24..56618658e8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1111,7 +1111,7 @@ ensure_tuning_high_compression (GstVaapiEncoderH264 * encoder) profile_idc = encoder->max_profile_idc; /* Tuning options to enable Main profile */ - if (profile_idc >= 77) { + if (profile_idc >= 77 && profile_idc != 88) { encoder->use_cabac = TRUE; if (!encoder->num_bframes) encoder->num_bframes = 1; From e1976df1a13e5f6bd3c7d07c8700f065bcb2663e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 1 Apr 2014 11:26:04 +0300 Subject: [PATCH 1642/3781] encoder: h264: remove unnecessary calcualtion of max_pic_order_cnt. https://bugzilla.gnome.org/show_bug.cgi?id=727418 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 56618658e8..d7574e3cde 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1584,7 +1584,6 @@ reference_list_init (GstVaapiEncoderH264 * encoder, GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[encoder->view_idx]; GList *iter, *list_0_start = NULL, *list_1_start = NULL; - guint max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); guint count; *reflist_0_count = 0; @@ -1596,7 +1595,7 @@ reference_list_init (GstVaapiEncoderH264 * encoder, for (; iter; iter = g_list_previous (iter)) { tmp = (GstVaapiEncoderH264Ref *) iter->data; g_assert (tmp && tmp->poc != picture->poc); - if (_poc_greater_than (picture->poc, tmp->poc, max_pic_order_cnt)) { + if (_poc_greater_than (picture->poc, tmp->poc, encoder->max_pic_order_cnt)) { list_0_start = iter; list_1_start = g_list_next (iter); break; From 885ebf4c726fc06dcfbfdc4723b767ffeb4df5d0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 3 Jun 2014 14:30:39 +0200 Subject: [PATCH 1643/3781] encoder: h264: drop extraneous definitions. Re-use definitions from the codecparser headers instead of duplicating them here again. That covers NALU definitions and slice types. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 62 +++++++++-------------- 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index d7574e3cde..94f8af7eb5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "gstvaapicompat.h" #include "gstvaapiencoder_priv.h" #include "gstvaapiencoder_h264.h" @@ -73,23 +74,10 @@ VA_ENC_PACKED_HEADER_SLICE | \ VA_ENC_PACKED_HEADER_RAW_DATA) -#define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0 -#define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1 -#define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM 2 -#define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH 3 - -typedef enum -{ - GST_VAAPI_ENCODER_H264_NAL_UNKNOWN = 0, - GST_VAAPI_ENCODER_H264_NAL_NON_IDR = 1, - GST_VAAPI_ENCODER_H264_NAL_IDR = 5, /* ref_idc != 0 */ - GST_VAAPI_ENCODER_H264_NAL_SEI = 6, /* ref_idc == 0 */ - GST_VAAPI_ENCODER_H264_NAL_SPS = 7, - GST_VAAPI_ENCODER_H264_NAL_PPS = 8, - GST_VAAPI_ENCODER_H264_NAL_PREFIX = 14, /* mvc nal prefix */ - GST_VAAPI_ENCODER_H264_NAL_SUBSET_SPS = 15, - GST_VAAPI_ENCODER_H264_NAL_SLICE_EXT = 20 -} GstVaapiEncoderH264NalType; +#define GST_H264_NAL_REF_IDC_NONE 0 +#define GST_H264_NAL_REF_IDC_LOW 1 +#define GST_H264_NAL_REF_IDC_MEDIUM 2 +#define GST_H264_NAL_REF_IDC_HIGH 3 typedef struct { @@ -134,13 +122,13 @@ h264_get_slice_type (GstVaapiPictureType type) { switch (type) { case GST_VAAPI_PICTURE_TYPE_I: - return 2; + return GST_H264_I_SLICE; case GST_VAAPI_PICTURE_TYPE_P: - return 0; + return GST_H264_P_SLICE; case GST_VAAPI_PICTURE_TYPE_B: - return 1; + return GST_H264_B_SLICE; default: - return -1; + break; } return -1; } @@ -905,17 +893,17 @@ _check_sps_pps_status (GstVaapiEncoderH264 * encoder, nal_type = nal[0] & 0x1F; switch (nal_type) { - case GST_VAAPI_ENCODER_H264_NAL_SPS: + case GST_H264_NAL_SPS: encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL); ret = gst_buffer_fill (encoder->sps_data, 0, nal, size); g_assert (ret == size); break; - case GST_VAAPI_ENCODER_H264_NAL_SUBSET_SPS: + case GST_H264_NAL_SUBSET_SPS: encoder->subset_sps_data = gst_buffer_new_allocate (NULL, size, NULL); ret = gst_buffer_fill (encoder->subset_sps_data, 0, nal, size); g_assert (ret == size); break; - case GST_VAAPI_ENCODER_H264_NAL_PPS: + case GST_H264_NAL_PPS: encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL); ret = gst_buffer_fill (encoder->pps_data, 0, nal, size); g_assert (ret == size); @@ -1253,8 +1241,7 @@ add_packed_sequence_header (GstVaapiEncoderH264 * encoder, gst_bit_writer_init (&bs, 128 * 8); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - bs_write_nal_header (&bs, - GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS); + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS); /* Set High profile for encoding the MVC base view. Otherwise, some traditional decoder cannot recognize MVC profile streams with @@ -1312,9 +1299,7 @@ add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder, /* non-base layer, pack one subset sps */ gst_bit_writer_init (&bs, 128 * 8); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - bs_write_nal_header (&bs, - GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, - GST_VAAPI_ENCODER_H264_NAL_SUBSET_SPS); + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS); bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views, &hrd_params); @@ -1364,8 +1349,7 @@ add_packed_picture_header (GstVaapiEncoderH264 * encoder, gst_bit_writer_init (&bs, 128 * 8); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - bs_write_nal_header (&bs, - GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_PPS); + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS); bs_write_pps (&bs, pic_param, encoder->profile); g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); @@ -1403,19 +1387,19 @@ get_nal_hdr_attributes (GstVaapiEncPicture * picture, { switch (picture->type) { case GST_VAAPI_PICTURE_TYPE_I: - *nal_ref_idc = GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH; + *nal_ref_idc = GST_H264_NAL_REF_IDC_HIGH; if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) - *nal_unit_type = GST_VAAPI_ENCODER_H264_NAL_IDR; + *nal_unit_type = GST_H264_NAL_SLICE_IDR; else - *nal_unit_type = GST_VAAPI_ENCODER_H264_NAL_NON_IDR; + *nal_unit_type = GST_H264_NAL_SLICE; break; case GST_VAAPI_PICTURE_TYPE_P: - *nal_ref_idc = GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM; - *nal_unit_type = GST_VAAPI_ENCODER_H264_NAL_NON_IDR; + *nal_ref_idc = GST_H264_NAL_REF_IDC_MEDIUM; + *nal_unit_type = GST_H264_NAL_SLICE; break; case GST_VAAPI_PICTURE_TYPE_B: - *nal_ref_idc = GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE; - *nal_unit_type = GST_VAAPI_ENCODER_H264_NAL_NON_IDR; + *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE; + *nal_unit_type = GST_H264_NAL_SLICE; break; default: return FALSE; @@ -1441,7 +1425,7 @@ add_packed_prefix_nal_header (GstVaapiEncoderH264 * encoder, if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) goto bs_error; - nal_unit_type = GST_VAAPI_ENCODER_H264_NAL_PREFIX; + nal_unit_type = GST_H264_NAL_PREFIX_UNIT; bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_idx); From f36486a1e2dce8c2acc442a17a4452e72a419080 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 4 Jun 2014 19:03:18 +0200 Subject: [PATCH 1644/3781] decoder: h264: fix detection of profile changes for MVC. If the VA driver exposes ad-hoc H.264 MVC profiles, then we have to be careful to detect profiles changes and not reset the underlying VA context erroneously. In MVC situations, we could indeed get a profile_idc change for every SPS that gets activated, alternatively (base-view -> non-base view -> base-view, etc.). An improved fix would be to characterize the exact profile to use once and for all when SPS NAL units are parsed. This would also allow for fallbacks to a base-view decoding only mode. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index e04c2d733f..44f486e31e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1270,7 +1270,7 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } - if (priv->profile != profile) { + if (!priv->profile || (priv->profile != profile && priv->max_views == 1)) { GST_DEBUG("profile changed"); reset_context = TRUE; priv->profile = profile; From e670e3600709602ddc6a9db651cc18e91dba4a09 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 4 Jun 2014 19:10:44 +0200 Subject: [PATCH 1645/3781] decoder: h264: fix MVC inter-view prediction process. The inter-view reference components and inter-view only reference components that are included in the reference picture lists shall be considered as not being marked as "used for short-term reference" or "used for long-term reference". This means that reference flags should all be removed from VAPictureH264.flags. This fixes decoding of MVCNV-2.264. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 44f486e31e..f5c1c8e353 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -3113,6 +3113,23 @@ vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture, } } +static void +vaapi_fill_picture_for_RefPicListX(VAPictureH264 *pic, + GstVaapiPictureH264 *picture) +{ + vaapi_fill_picture(pic, picture, 0); + + /* H.8.4 - MVC inter prediction and inter-view prediction process */ + if (GST_VAAPI_PICTURE_IS_INTER_VIEW(picture)) { + /* The inter-view reference components and inter-view only + reference components that are included in the reference + picture lists are considered as not being marked as "used for + short-term reference" or "used for long-term reference" */ + pic->flags &= ~(VA_PICTURE_H264_SHORT_TERM_REFERENCE| + VA_PICTURE_H264_LONG_TERM_REFERENCE); + } +} + static gboolean fill_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { @@ -3474,7 +3491,8 @@ fill_RefPicList(GstVaapiDecoderH264 *decoder, slice_hdr->num_ref_idx_l0_active_minus1; for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++) - vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i], 0); + vaapi_fill_picture_for_RefPicListX(&slice_param->RefPicList0[i], + priv->RefPicList0[i]); for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++) vaapi_init_picture(&slice_param->RefPicList0[i]); @@ -3485,7 +3503,8 @@ fill_RefPicList(GstVaapiDecoderH264 *decoder, slice_hdr->num_ref_idx_l1_active_minus1; for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++) - vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i], 0); + vaapi_fill_picture_for_RefPicListX(&slice_param->RefPicList1[i], + priv->RefPicList1[i]); for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++) vaapi_init_picture(&slice_param->RefPicList1[i]); return TRUE; From 60af04901f770ea0b89dff678d61ef6af19ee776 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 3 Jun 2014 17:36:38 +0200 Subject: [PATCH 1646/3781] decoder: h264: reduce ReferenceFrames entries to the essential set. When decoding Multiview High profile streams with a large number of views, it is not possible to make the VAPictureParameterBufferH264. ReferenceFrames[] array hold the complete DPB, with all possibly active pictures to be used for inter-view prediction in the current access unit. So reduce the scope of the ReferenceFrames[] array to only include the set of reference pictures that are going to be used for decoding the current picture. Basically, this is a union of all RefPicListX[] array, for all slices constituting the decoded picture. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 42 ++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index f5c1c8e353..cfe7b026cd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2051,6 +2051,45 @@ find_inter_view_reference(GstVaapiDecoderH264 *decoder, guint16 view_id) return NULL; } +/* Checks whether the view id exists in the supplied list of view ids */ +static gboolean +find_view_id(guint16 view_id, const guint16 *view_ids, guint num_view_ids) +{ + guint i; + + for (i = 0; i < num_view_ids; i++) { + if (view_ids[i] == view_id) + return TRUE; + } + return FALSE; +} + +/* Checks whether the inter-view reference picture with the supplied + view id is used for decoding the current view component picture */ +static gboolean +is_inter_view_reference_for_picture(GstVaapiDecoderH264 *decoder, + guint16 view_id, GstVaapiPictureH264 *picture) +{ + const GstH264SPS * const sps = get_sps(decoder); + const GstH264SPSExtMVCView *view; + + if (!GST_VAAPI_PICTURE_IS_MVC(picture) || + sps->extension_type != GST_H264_NAL_EXTENSION_MVC) + return FALSE; + + view = &sps->extension.mvc.view[picture->base.voc]; + if (GST_VAAPI_PICTURE_IS_ANCHOR(picture)) + return (find_view_id(view_id, view->anchor_ref_l0, + view->num_anchor_refs_l0) || + find_view_id(view_id, view->anchor_ref_l1, + view->num_anchor_refs_l1)); + + return (find_view_id(view_id, view->non_anchor_ref_l0, + view->num_non_anchor_refs_l0) || + find_view_id(view_id, view->non_anchor_ref_l1, + view->num_non_anchor_refs_l1)); +} + /* H.8.2.1 - Initialization process for inter-view prediction references */ static void init_picture_refs_mvc_1(GstVaapiDecoderH264 *decoder, @@ -3147,7 +3186,8 @@ fill_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) GstVaapiFrameStore * const fs = priv->dpb[i]; if ((gst_vaapi_frame_store_has_reference(fs) && fs->view_id == picture->base.view_id) || - gst_vaapi_frame_store_has_inter_view(fs)) + (gst_vaapi_frame_store_has_inter_view(fs) && + is_inter_view_reference_for_picture(decoder, fs->view_id, picture))) vaapi_fill_picture(&pic_param->ReferenceFrames[n++], fs->buffers[0], fs->structure); if (n >= G_N_ELEMENTS(pic_param->ReferenceFrames)) From e8fe78824bc65a2b1f5166d2aa34099af6aaec4b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 6 Jun 2014 17:56:06 +0200 Subject: [PATCH 1647/3781] decoder: h264: fix inter-view references array growth. Let the utility layer handle dynamic growth of the inter-view pictures array. By definition, setting a new size to the array will effectively grow the array, but would also fill in the newly created elements with empty entries (NULL), thus also increasing the reported length, which is not correct. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index cfe7b026cd..1ce29833fd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -977,9 +977,7 @@ mvc_reset(GstVaapiDecoderH264 *decoder) guint i; // Resize array of inter-view references - if (priv->inter_views) - g_ptr_array_set_size(priv->inter_views, priv->max_views); - else { + if (!priv->inter_views) { priv->inter_views = g_ptr_array_new_full(priv->max_views, (GDestroyNotify)unref_inter_view); if (!priv->inter_views) From 42ab3e066988109d89c2b1210bb6f02bcb44e97d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 3 Jun 2014 17:36:38 +0200 Subject: [PATCH 1648/3781] decoder: h264: improve DPB bumping process for MVC. While invoking the DPB bumping process in presence of many views, it could be necessary to output previous pictures that are ready, in a whole. i.e. emitting all view components from the very first view order index zero to the very last one in its original access unit; and not starting from the view order index of the picture that caused the DPB bumping process to be invoked. As a reminder, the maximum number of frames in DPB for MultiView High profile with more than 2 views is not necessarily a multiple of the number of views. This fixes decoding of MVCNV-4.264. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 43 +++++++++++++++++------ 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 1ce29833fd..340f7e15b7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -770,6 +770,34 @@ dpb_find_lowest_voc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, return found_picture ? found_index : -1; } +static gboolean +dpb_output_other_views(GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, guint voc) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiPictureH264 *found_picture; + gint found_index; + gboolean success; + + if (priv->max_views == 1) + return TRUE; + + /* Emit all other view components that were in the same access + unit than the picture we have just found */ + found_picture = picture; + for (;;) { + found_index = dpb_find_lowest_voc(decoder, found_picture, + &found_picture); + if (found_index < 0 || found_picture->base.voc >= voc) + break; + success = dpb_output(decoder, priv->dpb[found_index], found_picture); + dpb_evict(decoder, found_picture, found_index); + if (!success) + return FALSE; + } + return TRUE; +} + static gboolean dpb_bump(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { @@ -782,21 +810,16 @@ dpb_bump(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (found_index < 0) return FALSE; + if (picture && picture->base.poc != found_picture->base.poc) + dpb_output_other_views(decoder, found_picture, found_picture->base.voc); + success = dpb_output(decoder, priv->dpb[found_index], found_picture); dpb_evict(decoder, found_picture, found_index); if (priv->max_views == 1) return success; - /* Emit all other view components that were in the same access - unit than the picture we have just found */ - for (;;) { - found_index = dpb_find_lowest_voc(decoder, found_picture, - &found_picture); - if (found_index < 0) - break; - dpb_output(decoder, priv->dpb[found_index], found_picture); - dpb_evict(decoder, found_picture, found_index); - } + if (picture && picture->base.poc != found_picture->base.poc) + dpb_output_other_views(decoder, found_picture, G_MAXUINT32); return success; } From 428b038dbaf90d257f35ee4e3be35eb63183b27f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 10 Jun 2014 16:07:51 +0200 Subject: [PATCH 1649/3781] decoder: h264: improve pruning of unused MVC inter-view frames. Improve process for the removal of pictures from DPB before possible insertion of the current picture (C.4.4) for H.264 MVC inter-view only reference components. In particular, handle cases where picture to be inserted is not the last one of the access unit and if it was already output and is no longer marked as used for reference, including for decoding next view components within the same access unit. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 83 +++++++++++++++++++---- 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 340f7e15b7..557f6dc996 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -514,6 +514,17 @@ struct _GstVaapiDecoderH264Class { static gboolean exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture); +static gboolean +is_inter_view_reference_for_next_pictures(GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture); + +static inline gboolean +is_inter_view_reference_for_next_frames(GstVaapiDecoderH264 *decoder, + GstVaapiFrameStore *fs) +{ + return is_inter_view_reference_for_next_pictures(decoder, fs->buffers[0]); +} + /* Determines if the supplied profile is one of the MVC set */ static gboolean is_mvc_profile(GstH264Profile profile) @@ -864,7 +875,7 @@ dpb_prune_mvc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) GstVaapiDecoderH264Private * const priv = &decoder->priv; guint i; - // Remove all unused inter-view pictures + // Remove all unused inter-view only reference components of the current AU if (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_AU_END)) { i = 0; while (i < priv->dpb_count) { @@ -876,6 +887,18 @@ dpb_prune_mvc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) i++; } } + else { + i = 0; + while (i < priv->dpb_count) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + if (fs->view_id != picture->base.view_id && + !fs->output_needed && !gst_vaapi_frame_store_has_reference(fs) && + !is_inter_view_reference_for_next_frames(decoder, fs)) + dpb_remove_index(decoder, i); + else + i++; + } + } } static gboolean @@ -2085,21 +2108,11 @@ find_view_id(guint16 view_id, const guint16 *view_ids, guint num_view_ids) return FALSE; } -/* Checks whether the inter-view reference picture with the supplied - view id is used for decoding the current view component picture */ static gboolean -is_inter_view_reference_for_picture(GstVaapiDecoderH264 *decoder, - guint16 view_id, GstVaapiPictureH264 *picture) +find_view_id_in_view(guint16 view_id, const GstH264SPSExtMVCView *view, + gboolean is_anchor) { - const GstH264SPS * const sps = get_sps(decoder); - const GstH264SPSExtMVCView *view; - - if (!GST_VAAPI_PICTURE_IS_MVC(picture) || - sps->extension_type != GST_H264_NAL_EXTENSION_MVC) - return FALSE; - - view = &sps->extension.mvc.view[picture->base.voc]; - if (GST_VAAPI_PICTURE_IS_ANCHOR(picture)) + if (is_anchor) return (find_view_id(view_id, view->anchor_ref_l0, view->num_anchor_refs_l0) || find_view_id(view_id, view->anchor_ref_l1, @@ -2111,6 +2124,48 @@ is_inter_view_reference_for_picture(GstVaapiDecoderH264 *decoder, view->num_non_anchor_refs_l1)); } +/* Checks whether the inter-view reference picture with the supplied + view id is used for decoding the current view component picture */ +static gboolean +is_inter_view_reference_for_picture(GstVaapiDecoderH264 *decoder, + guint16 view_id, GstVaapiPictureH264 *picture) +{ + const GstH264SPS * const sps = get_sps(decoder); + gboolean is_anchor; + + if (!GST_VAAPI_PICTURE_IS_MVC(picture) || + sps->extension_type != GST_H264_NAL_EXTENSION_MVC) + return FALSE; + + is_anchor = GST_VAAPI_PICTURE_IS_ANCHOR(picture); + return find_view_id_in_view(view_id, + &sps->extension.mvc.view[picture->base.voc], is_anchor); +} + +/* Checks whether the supplied inter-view reference picture is used + for decoding the next view component pictures */ +static gboolean +is_inter_view_reference_for_next_pictures(GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture) +{ + const GstH264SPS * const sps = get_sps(decoder); + gboolean is_anchor; + guint i, num_views; + + if (!GST_VAAPI_PICTURE_IS_MVC(picture) || + sps->extension_type != GST_H264_NAL_EXTENSION_MVC) + return FALSE; + + is_anchor = GST_VAAPI_PICTURE_IS_ANCHOR(picture); + num_views = sps->extension.mvc.num_views_minus1 + 1; + for (i = picture->base.voc + 1; i < num_views; i++) { + const GstH264SPSExtMVCView * const view = &sps->extension.mvc.view[i]; + if (find_view_id_in_view(picture->base.view_id, view, is_anchor)) + return TRUE; + } + return FALSE; +} + /* H.8.2.1 - Initialization process for inter-view prediction references */ static void init_picture_refs_mvc_1(GstVaapiDecoderH264 *decoder, From 63fde28dfd498062ab82afa77de40495419d6b72 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 10 Jun 2014 17:42:58 +0200 Subject: [PATCH 1650/3781] decoder: h264: clean-ups. Fix GST_VAAPI_PICTURE_IS_{INTER_VIEW,ANCHOR}() definitions to use the base GST_VAAPI_PICTURE_FLAG_IS_SET() macro. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 557f6dc996..5cea09963a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -195,10 +195,10 @@ enum { GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE) #define GST_VAAPI_PICTURE_IS_INTER_VIEW(picture) \ - (GST_VAAPI_PICTURE_FLAGS(picture) & GST_VAAPI_PICTURE_FLAG_INTER_VIEW) + (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_INTER_VIEW)) #define GST_VAAPI_PICTURE_IS_ANCHOR(picture) \ - (GST_VAAPI_PICTURE_FLAGS(picture) & GST_VAAPI_PICTURE_FLAG_ANCHOR) + (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_ANCHOR)) #define GST_VAAPI_PICTURE_H264(picture) \ ((GstVaapiPictureH264 *)(picture)) From c65aec1aa6ee943abac99f454f7d3914e3297a21 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 10 Jun 2014 18:30:21 +0200 Subject: [PATCH 1651/3781] decoder: h264: factor out DPB pruning for MVC. Factor out the removal process of unused inter-view only reference pictures from the DPB, prior to the possible insertion of the current picture. Ideally, the compiler could still opt for generating two loops. But at least, the code is now clearer for maintenance. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 34 ++++++++--------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 5cea09963a..d8219e873f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -873,31 +873,21 @@ static void dpb_prune_mvc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { GstVaapiDecoderH264Private * const priv = &decoder->priv; + const gboolean is_last_picture = /* in the access unit */ + GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_AU_END); guint i; // Remove all unused inter-view only reference components of the current AU - if (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_AU_END)) { - i = 0; - while (i < priv->dpb_count) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - if (fs->view_id != picture->base.view_id && - !fs->output_needed && !gst_vaapi_frame_store_has_reference(fs)) - dpb_remove_index(decoder, i); - else - i++; - } - } - else { - i = 0; - while (i < priv->dpb_count) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - if (fs->view_id != picture->base.view_id && - !fs->output_needed && !gst_vaapi_frame_store_has_reference(fs) && - !is_inter_view_reference_for_next_frames(decoder, fs)) - dpb_remove_index(decoder, i); - else - i++; - } + i = 0; + while (i < priv->dpb_count) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + if (fs->view_id != picture->base.view_id && + !fs->output_needed && !gst_vaapi_frame_store_has_reference(fs) && + (is_last_picture || + !is_inter_view_reference_for_next_frames(decoder, fs))) + dpb_remove_index(decoder, i); + else + i++; } } From 7fd8aa3ed0c8d51833b37b87afb677840e65fe61 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Jun 2014 11:34:07 +0200 Subject: [PATCH 1652/3781] codecparsers: update to gst-vaapi-branch commit d6325ac. 7d8d045 h264parse: use new gst_h264_video_calculate_framerate() d2f965a h264parse: set field_pic_flag when parsing a slice header 24c15b8 Import h264parse a9283e5 bytereader: Use concistant derefence method a8252c6 bytereader: Use pointer instead of index access b1bebfc Import GstBitReader and GstByteReader 2f58788 h264: recognize SVC NAL units 4335da5 h264: fix SPS copy code for MVC cf9b6dc h264: fix quantization matrix conversion routine names b11ce2a h264: add gst_h264_video_calculate_framerate() 126dc6f add C++ guards for MPEG-4 and VP8 parsers --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index eaa3f7e72c..d6325ac0f1 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit eaa3f7e72c4e9d8d6ae83b354942d1fcf46aef49 +Subproject commit d6325ac0f17df46140355d3a43e54319e7bb2e36 From 799d7b7d0e931e7b0f478821ee31a0c6442bb510 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Jun 2014 11:36:56 +0200 Subject: [PATCH 1653/3781] decoder: h264: cope with new gst_h264_quant_matrix_*() interfaces. New gst_h264_quant_matrix_*_get_raster_from_zigzag() were renamed from gst_h264_video_quant_matrix_*_get_raster_from_zigzag(). --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index d8219e873f..82b8d1520a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1380,7 +1380,7 @@ fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps, g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16); for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) - gst_h264_video_quant_matrix_4x4_get_raster_from_zigzag( + gst_h264_quant_matrix_4x4_get_raster_from_zigzag( iq_matrix->ScalingList4x4[i], pps->scaling_lists_4x4[i]); } @@ -1399,7 +1399,7 @@ fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps, n = (sps->chroma_format_idc != 3) ? 2 : 6; for (i = 0; i < n; i++) { - gst_h264_video_quant_matrix_8x8_get_raster_from_zigzag( + gst_h264_quant_matrix_8x8_get_raster_from_zigzag( iq_matrix->ScalingList8x8[i], pps->scaling_lists_8x8[i]); } } From 3af6b0b8a0a0a46d100cf016cb00ccdacc18aa08 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Apr 2014 17:44:03 +0200 Subject: [PATCH 1654/3781] plugins: add built-in video parsers as "vaapiparse" element. The built-in video parsers elements are built into a single DSO named libgstvaapi_parse.so. The various video parsers could be accessed as vaapiparse_CODEC. For now, this only includes a modified version of h264parse so that to support H.264 MVC encoded streams. --- Makefile.am | 2 +- configure.ac | 11 +++ ext/Makefile.am | 15 +++ gst/vaapi/Makefile.am | 69 +++++++++++++ gst/vaapi/gstvaapiparse.c | 53 ++++++++++ gst/vaapi/gstvaapiparse.h | 36 +++++++ patches/Makefile.am | 4 + ...the-built-in-video-parsers-as-vaapip.patch | 41 ++++++++ ...64parse-fix-build-with-GStreamer-1.2.patch | 26 +++++ ...dd-initial-support-for-MVC-NAL-units.patch | 99 +++++++++++++++++++ patches/videoparsers/Makefile.am | 6 ++ patches/videoparsers/series.frag | 7 ++ 12 files changed, 368 insertions(+), 1 deletion(-) create mode 100644 gst/vaapi/gstvaapiparse.c create mode 100644 gst/vaapi/gstvaapiparse.h create mode 100644 patches/Makefile.am create mode 100644 patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch create mode 100644 patches/videoparsers/0002-h264parse-fix-build-with-GStreamer-1.2.patch create mode 100644 patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch create mode 100644 patches/videoparsers/Makefile.am create mode 100644 patches/videoparsers/series.frag diff --git a/Makefile.am b/Makefile.am index 1d08eba0e7..b3332012b6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} AUTOMAKE_OPTIONS = foreign -SUBDIRS = debian.upstream ext gst-libs gst pkgconfig tests docs +SUBDIRS = debian.upstream ext gst-libs gst pkgconfig tests docs patches # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ diff --git a/configure.ac b/configure.ac index 8bcea9f7c5..e383de44de 100644 --- a/configure.ac +++ b/configure.ac @@ -105,6 +105,11 @@ dnl Initialize libtool LT_PREREQ([2.2]) LT_INIT +AC_ARG_ENABLE(builtin_videoparsers, + AS_HELP_STRING([--enable-builtin-videoparsers], + [enable built-in videoparsers @<:@default=yes@:>@]), + [], [enable_builtin_videoparsers="yes"]) + AC_ARG_ENABLE(builtin_codecparsers, AS_HELP_STRING([--enable-builtin-codecparsers], [enable built-in codecparsers @<:@default=yes@:>@]), @@ -449,6 +454,10 @@ AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_VP8], [test "$ac_cv_have_gst_vp8_parser" != "yes"]) AM_CONDITIONAL([USE_BUILTIN_LIBVPX], [test "$enable_builtin_libvpx" = "yes"]) +dnl ... video parsers +AM_CONDITIONAL([USE_LOCAL_VIDEO_PARSERS], + [test "$enable_builtin_videoparsers" = "yes"]) + case $GST_API_VERSION in 0.10) lt_bias=gst0_vaapi_lt_current_bias;; 1.0) lt_bias=gst1_vaapi_lt_current_bias;; @@ -868,6 +877,8 @@ debian.upstream/libgstvaapi-x11.install.in gst-libs/gst/video/Makefile gst/Makefile gst/vaapi/Makefile + patches/Makefile + patches/videoparsers/Makefile pkgconfig/Makefile pkgconfig/gstreamer-vaapi-$GST_PKG_VERSION.pc:\ pkgconfig/gstreamer-vaapi.pc.in diff --git a/ext/Makefile.am b/ext/Makefile.am index 7aea0dd79c..9915e4a6e7 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -37,6 +37,21 @@ codecparsers_source_h = \ EXTRA_DIST += $(codecparsers_source_h:%.h=$(codecparsers_srcdir)/%.h) +videoparsers_srcdir = \ + $(top_srcdir)/ext/codecparsers/gst/videoparsers + +videoparsers_source_c = \ + gsth264parse.c \ + $(NULL) + +EXTRA_DIST += $(videoparsers_source_c:%.c=$(videoparsers_srcdir)/%.c) + +videoparsers_source_h = \ + gsth264parse.h \ + $(NULL) + +EXTRA_DIST += $(videoparsers_source_h:%.h=$(videoparsers_srcdir)/%.h) + videoutils_srcdir = \ $(top_srcdir)/ext/videoutils/gst-libs/gst/video diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 5f0c659bce..a52bc2fe1e 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -163,6 +163,73 @@ libgstvaapi_la_LIBADD = \ libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvaapi_la_LIBTOOLFLAGS = --tag=disable-static +BUILT_SOURCES = + +if USE_LOCAL_VIDEO_PARSERS +plugin_LTLIBRARIES += libgstvaapi_parse.la + +libgstvaapi_parse_gen_source_c = \ + gsth264parse.c \ + $(NULL) + +libgstvaapi_parse_gen_source_h = \ + gsth264parse.h \ + $(NULL) + +libgstvaapi_parse_gen_sources = \ + $(libgstvaapi_parse_gen_source_c) \ + $(libgstvaapi_parse_gen_source_h) \ + $(NUL) + +libgstvaapi_parse_source_c = gstvaapiparse.c $(libgstvaapi_parse_gen_source_c) +libgstvaapi_parse_source_h = gstvaapiparse.h $(libgstvaapi_parse_gen_source_h) + +libgstvaapi_parse_la_SOURCES = $(libgstvaapi_parse_source_c) +noinst_HEADERS += $(libgstvaapi_parse_source_h) + +libgstvaapi_parse_la_CFLAGS = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + -I$(top_builddir)/gst-libs \ + $(GST_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_VIDEO_CFLAGS) + +libgstvaapi_parse_la_LIBADD = \ + $(top_builddir)/gst-libs/gst/codecparsers/libgstvaapi-codecparsers.la \ + $(GST_LIBS) \ + $(GST_BASE_LIBS) \ + $(GST_PLUGINS_BASE_LIBS) \ + $(GST_VIDEO_LIBS) -lgstpbutils-$(GST_PKG_VERSION) + +libgstvaapi_parse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstvaapi_parse_la_LIBTOOLFLAGS = --tag=disable-static + +videoparsers_sources_dir = \ + $(top_srcdir)/ext/codecparsers/gst/videoparsers +videoparsers_patches_dir = \ + $(top_srcdir)/patches/videoparsers +include $(videoparsers_patches_dir)/series.frag +videoparsers_patches = \ + $(videoparsers_patches_base:%=$(top_srcdir)/patches/videoparsers/%) + +videoparsers.prepare.stamp: $(videoparsers_patches) + @for f in $(libgstvaapi_parse_gen_sources); do \ + cp -f $(videoparsers_sources_dir)/$$f $$f; \ + done + @for f in $(videoparsers_patches); do \ + patch -p3 < $$f; \ + done + @touch $@ + +BUILT_SOURCES += videoparsers.prepare.stamp +endif + +CLEANFILES = \ + videoparsers.prepare.stamp \ + $(libgstvaapi_parse_gen_sources) + EXTRA_DIST = \ $(libgstvaapi_enc_source_c) \ $(libgstvaapi_enc_source_h) \ @@ -176,6 +243,8 @@ EXTRA_DIST = \ $(libgstvaapi_1_0p_source_h) \ $(libgstvaapi_0_10_source_c) \ $(libgstvaapi_0_10_source_h) \ + $(libgstvaapi_parse_source_c) \ + $(libgstvaapi_parse_source_h) \ $(NULL) # Extra clean files so that maintainer-clean removes *everything* diff --git a/gst/vaapi/gstvaapiparse.c b/gst/vaapi/gstvaapiparse.c new file mode 100644 index 0000000000..3b1e9fcd7f --- /dev/null +++ b/gst/vaapi/gstvaapiparse.c @@ -0,0 +1,53 @@ +/* + * gstvaapiparse.c - Recent enough GStreamer video parsers + * + * Copyright (C) 2011 Mark Nauwelaerts + * Copyright (C) 2009 Tim-Philipp Müller + * + * 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 "gst/vaapi/sysdeps.h" +#include +#include "gstvaapiparse.h" +#include "gsth264parse.h" + +#define PLUGIN_NAME "vaapiparse" +#define PLUGIN_DESC "VA-API based elements" +#define PLUGIN_LICENSE "LGPL" + +static gboolean +plugin_init (GstPlugin * plugin) +{ + gboolean failure = FALSE; + + failure |= !gst_element_register (plugin, "vaapiparse_h264", + GST_RANK_PRIMARY + 2, GST_TYPE_H264_PARSE); + + return !failure; +} + +#if GST_CHECK_VERSION(1,0,0) +/* XXX: use PLUGIN_NAME when GST_PLUGIN_DEFINE is fixed to use + G_STRINGIFY() for name argument, instead of plain #name */ +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, + vaapiparse, PLUGIN_DESC, plugin_init, + PACKAGE_VERSION, PLUGIN_LICENSE, PACKAGE, PACKAGE_BUGREPORT) +#else +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, + PLUGIN_NAME, PLUGIN_DESC, plugin_init, + PACKAGE_VERSION, PLUGIN_LICENSE, PACKAGE, PACKAGE_BUGREPORT) +#endif diff --git a/gst/vaapi/gstvaapiparse.h b/gst/vaapi/gstvaapiparse.h new file mode 100644 index 0000000000..03e74d9656 --- /dev/null +++ b/gst/vaapi/gstvaapiparse.h @@ -0,0 +1,36 @@ +/* + * gstvaapiparse.h - Recent enough GStreamer video parsers + * + * Copyright (C) 2014 Intel Corporation + * + * 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_PARSE_H +#define GST_VAAPI_PARSE_H + +/* vaapiparse_h264 */ +#define _GstH264Parse _GstVaapiH264Parse +#define GstH264Parse GstVaapiH264Parse +#define _GstH264ParseClass _GstVaapiH264ParseClass +#define GstH264ParseClass GstVaapiH264ParseClass +#define gst_h264_parse gst_vaapi_h264_parse +#define gst_h264_parse_init gst_vaapi_h264_parse_init +#define gst_h264_parse_class_init gst_vaapi_h264_parse_class_init +#define gst_h264_parse_parent_class gst_vaapi_h264_parse_parent_class +#define gst_h264_parse_get_type gst_vaapi_h264_parse_get_type + +#endif /* GST_VAAPI_PARSE_H */ diff --git a/patches/Makefile.am b/patches/Makefile.am new file mode 100644 index 0000000000..0512fcaeb2 --- /dev/null +++ b/patches/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = videoparsers + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch b/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch new file mode 100644 index 0000000000..978cf3130d --- /dev/null +++ b/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch @@ -0,0 +1,41 @@ +From c78b4c043dc41f071bdf170ecb001dc1aef8f5f6 Mon Sep 17 00:00:00 2001 +From: Gwenole Beauchesne +Date: Mon, 28 Apr 2014 17:44:03 +0200 +Subject: [PATCH 1/3] plugins: compile the built-in video parsers as + "vaapiparse" element. + +The built-in video parsers elements are built into a single DSO named +libgstvaapi_parse.so. The various video parsers could be accessed as +vaapiparse_CODEC. +--- + configure.ac | 9 ++++++++ + gst/vaapi/Makefile.am | 35 ++++++++++++++++++++++++++++++ + gst/vaapi/gsth264parse.c | 4 +++- + gst/vaapi/gstvaapiparse.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ + gst/vaapi/gstvaapiparse.h | 36 ++++++++++++++++++++++++++++++ + 5 files changed, 136 insertions(+), 1 deletion(-) + create mode 100644 gst/vaapi/gstvaapiparse.c + create mode 100644 gst/vaapi/gstvaapiparse.h + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index 9105d7f..4246b6e 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -26,6 +26,7 @@ + # include "config.h" + #endif + ++#include "gstvaapiparse.h" + #include + #include + #include +@@ -105,7 +106,8 @@ gst_h264_parse_class_init (GstH264ParseClass * klass) + GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); + +- GST_DEBUG_CATEGORY_INIT (h264_parse_debug, "h264parse", 0, "h264 parser"); ++ GST_DEBUG_CATEGORY_INIT (h264_parse_debug, "vaapiparse_h264", 0, ++ "h264 parser"); + + gobject_class->finalize = gst_h264_parse_finalize; + gobject_class->set_property = gst_h264_parse_set_property; diff --git a/patches/videoparsers/0002-h264parse-fix-build-with-GStreamer-1.2.patch b/patches/videoparsers/0002-h264parse-fix-build-with-GStreamer-1.2.patch new file mode 100644 index 0000000000..29f979ed6f --- /dev/null +++ b/patches/videoparsers/0002-h264parse-fix-build-with-GStreamer-1.2.patch @@ -0,0 +1,26 @@ +From 4a209977a61d156433dddbf21bddc0b1e89098e1 Mon Sep 17 00:00:00 2001 +From: Gwenole Beauchesne +Date: Mon, 28 Apr 2014 17:17:04 +0200 +Subject: [PATCH 2/3] h264parse: fix build with GStreamer 1.2. + +--- + gst/vaapi/gsth264parse.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index 4246b6e..7c970ee 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -148,7 +148,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) + { + h264parse->frame_out = gst_adapter_new (); + gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h264parse), FALSE); ++#if GST_CHECK_VERSION(1,3,0) + GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h264parse)); ++#endif + } + + +-- +1.7.9.5 + diff --git a/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch b/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch new file mode 100644 index 0000000000..9316510565 --- /dev/null +++ b/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch @@ -0,0 +1,99 @@ +From 3ef58fae7a578f72c4607b57434ed54a0ee9ee1d Mon Sep 17 00:00:00 2001 +From: Sreerenj Balachandran +Date: Tue, 19 Mar 2013 14:23:00 +0200 +Subject: [PATCH 3/3] h264parse: add initial support for MVC NAL units. + +Initial support for MVC NAL units. It is only needed to propagate the +complete set of NAL units downstream at this time. + +https://bugzilla.gnome.org/show_bug.cgi?id=696135 + +Signed-off-by: Sreerenj Balachandran +Signed-off-by: Gwenole Beauchesne +--- + gst/vaapi/gsth264parse.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index 7c970ee..e9b9481 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -415,7 +415,7 @@ gst_h264_parser_store_nal (GstH264Parse * h264parse, guint id, + GstBuffer *buf, **store; + guint size = nalu->size, store_size; + +- if (naltype == GST_H264_NAL_SPS) { ++ if (naltype == GST_H264_NAL_SPS || naltype == GST_H264_NAL_SUBSET_SPS) { + store_size = GST_H264_MAX_SPS_COUNT; + store = h264parse->sps_nals; + GST_DEBUG_OBJECT (h264parse, "storing sps %u", id); +@@ -534,6 +534,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + + switch (nal_type) { + case GST_H264_NAL_SPS: ++ case GST_H264_NAL_SUBSET_SPS: + pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps, TRUE); + /* arranged for a fallback sps.id, so use that one and only warn */ + if (pres != GST_H264_PARSER_OK) +@@ -594,14 +595,17 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + case GST_H264_NAL_SLICE_DPB: + case GST_H264_NAL_SLICE_DPC: + case GST_H264_NAL_SLICE_IDR: ++ case GST_H264_NAL_SLICE_EXT: + /* don't need to parse the whole slice (header) here */ +- if (*(nalu->data + nalu->offset + 1) & 0x80) { ++ if (*(nalu->data + nalu->offset + nalu->header_bytes) & 0x80) { + /* means first_mb_in_slice == 0 */ + /* real frame data */ + GST_DEBUG_OBJECT (h264parse, "first_mb_in_slice = 0"); + h264parse->frame_start = TRUE; + } + GST_DEBUG_OBJECT (h264parse, "frame start: %i", h264parse->frame_start); ++ if (nal_type == GST_H264_NAL_SLICE_EXT && !GST_H264_IS_MVC_NALU (nalu)) ++ break; + { + GstH264SliceHdr slice; + +@@ -677,7 +681,8 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data, + /* coded slice NAL starts a picture, + * i.e. other types become aggregated in front of it */ + h264parse->picture_start |= (nal_type == GST_H264_NAL_SLICE || +- nal_type == GST_H264_NAL_SLICE_DPA || nal_type == GST_H264_NAL_SLICE_IDR); ++ nal_type == GST_H264_NAL_SLICE_DPA || nal_type == GST_H264_NAL_SLICE_IDR ++ || nal_type == GST_H264_NAL_SLICE_EXT); + + /* consider a coded slices (IDR or not) to start a picture, + * (so ending the previous one) if first_mb_in_slice == 0 +@@ -687,16 +692,18 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data, + * and also works with broken frame_num in NAL + * (where spec-wise would fail) */ + nal_type = nnalu.type; +- complete = h264parse->picture_start && (nal_type >= GST_H264_NAL_SEI && +- nal_type <= GST_H264_NAL_AU_DELIMITER); ++ complete = h264parse->picture_start && ((nal_type >= GST_H264_NAL_SEI && ++ nal_type <= GST_H264_NAL_AU_DELIMITER) || ++ (nal_type >= 14 && nal_type <= 18)); + + GST_LOG_OBJECT (h264parse, "next nal type: %d %s", nal_type, + _nal_name (nal_type)); + complete |= h264parse->picture_start && (nal_type == GST_H264_NAL_SLICE + || nal_type == GST_H264_NAL_SLICE_DPA ++ || nal_type == GST_H264_NAL_SLICE_EXT + || nal_type == GST_H264_NAL_SLICE_IDR) && + /* first_mb_in_slice == 0 considered start of frame */ +- (nnalu.data[nnalu.offset + 1] & 0x80); ++ (nnalu.data[nnalu.offset + nnalu.header_bytes] & 0x80); + + GST_LOG_OBJECT (h264parse, "au complete: %d", complete); + +@@ -960,6 +967,7 @@ gst_h264_parse_handle_frame (GstBaseParse * parse, + } + + if (nalu.type == GST_H264_NAL_SPS || ++ nalu.type == GST_H264_NAL_SUBSET_SPS || + nalu.type == GST_H264_NAL_PPS || + (h264parse->have_sps && h264parse->have_pps)) { + gst_h264_parse_process_nal (h264parse, &nalu); +-- +1.7.9.5 + diff --git a/patches/videoparsers/Makefile.am b/patches/videoparsers/Makefile.am new file mode 100644 index 0000000000..ec3b761285 --- /dev/null +++ b/patches/videoparsers/Makefile.am @@ -0,0 +1,6 @@ +include series.frag + +EXTRA_DIST = series.frag $(videoparsers_patches_base) + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = Makefile.in diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag new file mode 100644 index 0000000000..13612c58ea --- /dev/null +++ b/patches/videoparsers/series.frag @@ -0,0 +1,7 @@ +# sources.frag - Generated list of patches for videoparsers (-*- makefile -*-) + +videoparsers_patches_base = \ + 0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch \ + 0002-h264parse-fix-build-with-GStreamer-1.2.patch \ + 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch \ + $(NULL) From eef863f82faa7d3559cf1071ef84ec9c866e724d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Mar 2014 17:38:14 +0100 Subject: [PATCH 1655/3781] plugins: fix initialization with foreign context. When a new display is settled through GstElement::set_context() (>= 1.2), or GstVideoContext::set_context() (<= 1.0), then we shall also update the associated display type. --- gst/vaapi/gstvaapipluginbase.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index a637b36c7a..5cb2796176 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -65,6 +65,7 @@ plugin_set_context (GstElement * element, GstContext * context) GST_INFO_OBJECT (element, "set display %p", display); gst_vaapi_display_replace (&plugin->display, display); gst_vaapi_display_unref (display); + plugin->display_type = gst_vaapi_display_get_display_type (display); } } #else @@ -75,6 +76,7 @@ plugin_set_context (GstVideoContext * context, const gchar * type, GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (context); gst_vaapi_set_display (type, value, &plugin->display); + plugin->display_type = gst_vaapi_display_get_display_type (plugin->display); } static void From 5e5d62cac79754ba60057fc2516135aad8d7de35 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 7 Mar 2014 17:40:34 +0100 Subject: [PATCH 1656/3781] vaapisink: fix initialization with "drm" display type. Force early initializatin of the GstVaapiDisplay so that to make sure that the sink element display object is presented first to upstream elements, as it will be correctly featuring the requested display type by the user. Otherwise, we might end up in situations where a VA/X11 display is initialized in vaapidecode, then we try VA/DRM display in vaapisink (as requested by the "display" property), but this would cause a failure because we cannot acquire a DRM display that was previously acquired through another backend (e.g. VA/X11). --- gst/vaapi/gstvaapisink.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index d9fd70371e..ad4d8d7f77 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -898,10 +898,14 @@ gst_vaapisink_show_frame_glx( guint flags ) { - GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window); + GstVaapiWindowGLX *window; GLenum target; GLuint texture; + if (!sink->window) + return FALSE; + window = GST_VAAPI_WINDOW_GLX(sink->window); + gst_vaapi_window_glx_make_current(window); if (!gst_vaapisink_ensure_texture(sink, surface)) goto error_create_texture; @@ -960,6 +964,9 @@ gst_vaapisink_put_surface( guint flags ) { + if (!sink->window) + return FALSE; + if (!gst_vaapi_window_put_surface(sink->window, surface, surface_rect, &sink->display_rect, flags)) { GST_DEBUG("could not render VA surface"); @@ -1004,9 +1011,6 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(sink, gst_vaapi_video_meta_get_display(meta)); - if (!sink->window) - goto error; - gst_vaapisink_ensure_rotation(sink, TRUE); surface = gst_vaapi_video_meta_get_surface(meta); @@ -1206,6 +1210,19 @@ gst_vaapisink_get_property( } } +static void +gst_vaapisink_set_bus(GstElement *element, GstBus *bus) +{ + /* Make sure to allocate a VA display in the sink element first, + so that upstream elements could query a display that was + allocated here, and that exactly matches what the user + requested through the "display" property */ + if (!GST_ELEMENT_BUS(element) && bus) + gst_vaapisink_ensure_display(GST_VAAPISINK(element)); + + GST_ELEMENT_CLASS(gst_vaapisink_parent_class)->set_bus(element, bus); +} + static void gst_vaapisink_class_init(GstVaapiSinkClass *klass) { @@ -1240,6 +1257,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; #endif + element_class->set_bus = gst_vaapisink_set_bus; gst_element_class_set_static_metadata(element_class, "VA-API sink", "Sink/Video", From 786b68ac21a919db59a3dc73b00be37d133b2d39 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 5 Jun 2014 15:30:38 +0300 Subject: [PATCH 1657/3781] encoder: add infrastructure for per-slice handling of packed headers. The packed slice header and packed raw data need to be paired with the submission of VAEncSliceHeaderParameterBuffer. So handle them on a per-slice basis insted of a per-picture basis. [removed useless initializer] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 32 ++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 6 ++++ 2 files changed, 38 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index a9ed0fa813..f022264b92 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -156,6 +156,11 @@ 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; } @@ -173,6 +178,12 @@ gst_vaapi_enc_slice_create (GstVaapiEncSlice * slice, 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; } @@ -381,6 +392,16 @@ gst_vaapi_enc_picture_add_slice (GstVaapiEncPicture * picture, 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) { @@ -449,6 +470,17 @@ gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture) /* 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; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index dca1cda01c..aa1ccbf258 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -118,6 +118,7 @@ struct _GstVaapiEncSlice /*< public >*/ VABufferID param_id; gpointer param; + GPtrArray *packed_headers; }; G_GNUC_INTERNAL @@ -230,6 +231,11 @@ 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); From 781abad2c7730bddc4ccc2b4fc837d42c2881248 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 5 Jun 2014 15:32:29 +0300 Subject: [PATCH 1658/3781] encoder: h264: fix multiple slices support in packed headers mode. Handle packedi slice headers and packed raw data on a per-slice basis, which is necessary for multi slice encoding. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 94f8af7eb5..0af8e9457b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1411,7 +1411,7 @@ get_nal_hdr_attributes (GstVaapiEncPicture * picture, headers to pass down as-is to the encoder */ static gboolean add_packed_prefix_nal_header (GstVaapiEncoderH264 * encoder, - GstVaapiEncPicture * picture) + GstVaapiEncPicture * picture, GstVaapiEncSlice * slice) { GstVaapiEncPackedHeader *packed_prefix_nal; GstBitWriter bs; @@ -1443,7 +1443,7 @@ add_packed_prefix_nal_header (GstVaapiEncoderH264 * encoder, (data_bit_size + 7) / 8); g_assert (packed_prefix_nal); - gst_vaapi_enc_picture_add_packed_header (picture, packed_prefix_nal); + gst_vaapi_enc_slice_add_packed_header (slice, packed_prefix_nal); gst_vaapi_codec_object_replace (&packed_prefix_nal, NULL); gst_bit_writer_clear (&bs, TRUE); @@ -1493,7 +1493,7 @@ add_packed_slice_header (GstVaapiEncoderH264 * encoder, data, (data_bit_size + 7) / 8); g_assert (packed_slice); - gst_vaapi_enc_picture_add_packed_header (picture, packed_slice); + gst_vaapi_enc_slice_add_packed_header (slice, packed_slice); gst_vaapi_codec_object_replace (&packed_slice, NULL); gst_bit_writer_clear (&bs, TRUE); @@ -1887,11 +1887,11 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, last_mb_index += cur_slice_mbs; if (encoder->is_mvc && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderRawData) - && !add_packed_prefix_nal_header (encoder, picture)) + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_RAW_DATA) + && !add_packed_prefix_nal_header (encoder, picture, slice)) goto error_create_packed_prefix_nal_hdr; if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & - VAEncPackedHeaderH264_Slice) + VA_ENC_PACKED_HEADER_SLICE) && !add_packed_slice_header (encoder, picture, slice)) goto error_create_packed_slice_hdr; From abfb5dd06cc7cdfa920707fc8f5553f81014e5e3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 18 Jun 2014 13:47:36 +0200 Subject: [PATCH 1659/3781] vaapidecode: parse source data until a frame is obtained. Parse any pending data until a complete frame is obtained. This is a memory optimization to avoid expansion of video packets stuffed into the GstAdapter, and a fix to EOS condition to detect there is actually pending data that needs to be decoded, and subsequently output. https://bugzilla.gnome.org/show_bug.cgi?id=731831 --- gst/vaapi/gstvaapidecode.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index aef4864874..2d2e319b17 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -54,6 +54,8 @@ #define GST_PLUGIN_NAME "vaapidecode" #define GST_PLUGIN_DESC "A VA-API based video decoder" +#define GST_VAAPI_DECODE_FLOW_PARSE_DATA GST_FLOW_CUSTOM_SUCCESS_2 + GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapidecode); #define GST_CAT_DEFAULT gst_debug_vaapidecode @@ -785,7 +787,7 @@ gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) } static GstFlowReturn -gst_vaapidecode_parse(GstVideoDecoder *vdec, +gst_vaapidecode_parse_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame, GstAdapter *adapter, gboolean at_eos) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); @@ -808,7 +810,7 @@ gst_vaapidecode_parse(GstVideoDecoder *vdec, decode->current_frame_size = 0; } else - ret = GST_FLOW_OK; + ret = GST_VAAPI_DECODE_FLOW_PARSE_DATA; break; case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: ret = GST_VIDEO_DECODER_FLOW_NEED_DATA; @@ -829,6 +831,18 @@ gst_vaapidecode_parse(GstVideoDecoder *vdec, return ret; } +static GstFlowReturn +gst_vaapidecode_parse(GstVideoDecoder *vdec, + GstVideoCodecFrame *frame, GstAdapter *adapter, gboolean at_eos) +{ + GstFlowReturn ret; + + do { + ret = gst_vaapidecode_parse_frame(vdec, frame, adapter, at_eos); + } while (ret == GST_VAAPI_DECODE_FLOW_PARSE_DATA); + return ret; +} + static GstStateChangeReturn gst_vaapidecode_change_state (GstElement * element, GstStateChange transition) { From 3fbef25e13e231b34e4d50823c86bb28240f1318 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Sun, 23 Feb 2014 01:43:39 +1100 Subject: [PATCH 1660/3781] vaapidecode: plug a memory leak. It can happen that there is a pool provided that does not advertise the vappivideometa. We should unref that pool before using our own. Discovered with vaapidecode ! {glimagesink,cluttersink} https://bugzilla.gnome.org/show_bug.cgi?id=724957 [fixed compilation by adding the missing semi-colon] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 2d2e319b17..da422e23c4 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -548,6 +548,8 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) { GST_INFO("no pool or doesn't support GstVaapiVideoMeta, " "making new pool"); + if (pool) + gst_object_unref(pool); pool = gst_vaapi_video_buffer_pool_new( GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); if (!pool) From ead38a4d77d38bdc89c76e7856cb17bb73c698d2 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Wed, 15 Jan 2014 16:36:29 +0000 Subject: [PATCH 1661/3781] vaapidecode: do not discard video info props when the format changed. gst_video_info_set_format() does not preserve video info properties. In order to keep important information in the caps such as interlace mode, framerate, pixel aspect ratio, ... we need to manually copy back those properties after setting the new video format. https://bugzilla.gnome.org/show_bug.cgi?id=722276 --- gst/vaapi/gstvaapidecode.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index da422e23c4..8ccc169d21 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -129,6 +129,23 @@ gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps) return TRUE; } +static void +gst_vaapidecode_video_info_change_format(GstVideoInfo *info, + GstVideoFormat format, guint width, guint height) +{ + GstVideoInfo vi = *info; + + gst_video_info_set_format (info, format, width, height); + + info->interlace_mode = vi.interlace_mode; + info->flags = vi.flags; + info->views = vi.views; + info->par_n = vi.par_n; + info->par_d = vi.par_d; + info->fps_n = vi.fps_n; + info->fps_d = vi.fps_d; +} + static gboolean gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, const GstVideoCodecState *ref_state) @@ -165,7 +182,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, vis = *vi; switch (feature) { case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: - gst_video_info_set_format(&vis, GST_VIDEO_FORMAT_RGBA, + gst_vaapidecode_video_info_change_format(&vis, GST_VIDEO_FORMAT_RGBA, GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); features = gst_caps_features_new( GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); @@ -176,7 +193,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, format=ENCODED + memory:VASurface caps feature are provided. Meanwhile, providing a random format here works but this is a terribly wrong thing per se. */ - gst_video_info_set_format(&vis, GST_VIDEO_FORMAT_NV12, + gst_vaapidecode_video_info_change_format(&vis, GST_VIDEO_FORMAT_NV12, GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); #if GST_CHECK_VERSION(1,3,0) if (feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) From 927fd2e1a80018138b2d4ed51f75e43370234f68 Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Fri, 14 Mar 2014 17:49:40 +0000 Subject: [PATCH 1662/3781] vaapipostproc: make deinterlace-mode behave as expected. deinterlace-mode didn't behave in the way you'd expect if you have past experience of the deinterlace element. There were two bugs: 1. "auto" mode wouldn't deinterlace "interleaved" buffers, only "mixed". 2. "force" mode wouldn't deinterlace "mixed" buffers flagged as progressive. Fix these up, and add assertions and error messages to detect cases that aren't handled. https://bugzilla.gnome.org/show_bug.cgi?id=726361 Signed-off-by: Simon Farnsworth Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipostproc.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index f1be89c68f..6bee16a62a 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -318,25 +318,36 @@ gst_vaapipostproc_stop(GstBaseTransform *trans) } static gboolean -is_interlaced_buffer(GstVaapiPostproc *postproc, GstBuffer *buf) +should_deinterlace_buffer(GstVaapiPostproc *postproc, GstBuffer *buf) { - if (!(postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE)) + if (!(postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) || + postproc->deinterlace_mode == GST_VAAPI_DEINTERLACE_MODE_DISABLED) return FALSE; + if (postproc->deinterlace_mode == GST_VAAPI_DEINTERLACE_MODE_INTERLACED) + return TRUE; + + g_assert(postproc->deinterlace_mode == GST_VAAPI_DEINTERLACE_MODE_AUTO); + switch (GST_VIDEO_INFO_INTERLACE_MODE(&postproc->sinkpad_info)) { + case GST_VIDEO_INTERLACE_MODE_INTERLEAVED: + return TRUE; + case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE: + return FALSE; case GST_VIDEO_INTERLACE_MODE_MIXED: #if GST_CHECK_VERSION(1,0,0) - if (!GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_FLAG_INTERLACED)) - return FALSE; + if (GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_FLAG_INTERLACED)) + return TRUE; #else - if (GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_PROGRESSIVE)) - return FALSE; + if (!GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_PROGRESSIVE)) + return TRUE; #endif break; default: + GST_ERROR("unhandled \"interlace-mode\", disabling deinterlacing" ); break; } - return TRUE; + return FALSE; } static GstBuffer * @@ -479,7 +490,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, timestamp = GST_BUFFER_TIMESTAMP(inbuf); tff = GST_BUFFER_FLAG_IS_SET(inbuf, GST_VIDEO_BUFFER_FLAG_TFF); - deint = is_interlaced_buffer(postproc, inbuf); + deint = should_deinterlace_buffer(postproc, inbuf); /* Drop references if deinterlacing conditions changed */ deint_changed = deint != ds->deint; @@ -648,7 +659,7 @@ gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf, timestamp = GST_BUFFER_TIMESTAMP(inbuf); tff = GST_BUFFER_FLAG_IS_SET(inbuf, GST_VIDEO_BUFFER_FLAG_TFF); - deint = is_interlaced_buffer(postproc, inbuf); + deint = should_deinterlace_buffer(postproc, inbuf); flags = gst_vaapi_video_meta_get_render_flags(meta) & ~GST_VAAPI_PICTURE_STRUCTURE_MASK; From b3401dbb294eac4bd91d8d92c1f1ecafe72d8c59 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 18 Jun 2014 16:16:34 +0200 Subject: [PATCH 1663/3781] vaapipostproc: add support for crop regions in VPP mode. Apply video cropping regions stored in GstVideoCropMeta, or in older GstVaapiSurfaceProxy representation, to VPP pipelines. In non-VPP modes, the crop meta are already propagated to the output buffers. https://bugzilla.gnome.org/show_bug.cgi?id=720730 --- gst/vaapi/gstvaapipostproc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6bee16a62a..f670c557d9 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -447,6 +447,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, GstVaapiDeinterlaceMethod deint_method; guint flags, deint_flags; gboolean tff, deint, deint_refs, deint_changed; + GstVaapiRectangle *crop_rect = NULL; /* Validate filters */ if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) && @@ -488,6 +489,22 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, goto error_invalid_buffer; inbuf_surface = gst_vaapi_video_meta_get_surface(inbuf_meta); +#if GST_CHECK_VERSION(1,0,0) + GstVideoCropMeta * const crop_meta = + gst_buffer_get_video_crop_meta(inbuf); + if (crop_meta) { + GstVaapiRectangle tmp_rect; + crop_rect = &tmp_rect; + crop_rect->x = crop_meta->x; + crop_rect->y = crop_meta->y; + crop_rect->width = crop_meta->width; + crop_rect->height = crop_meta->height; + } +#endif + if (!crop_rect) + crop_rect = (GstVaapiRectangle *) + gst_vaapi_video_meta_get_render_rect(inbuf_meta); + timestamp = GST_BUFFER_TIMESTAMP(inbuf); tff = GST_BUFFER_FLAG_IS_SET(inbuf, GST_VIDEO_BUFFER_FLAG_TFF); deint = should_deinterlace_buffer(postproc, inbuf); @@ -545,6 +562,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, goto error_op_deinterlace; } + gst_vaapi_filter_set_cropping_rectangle(postproc->filter, crop_rect); status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, outbuf_surface, flags); if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) @@ -583,6 +601,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, postproc->filter, deint_method, 0)) goto error_op_deinterlace; + gst_vaapi_filter_set_cropping_rectangle(postproc->filter, crop_rect); status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, outbuf_surface, flags); if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) From faefd62e9be3e36cc0465f5e66e1711d7b5d7a03 Mon Sep 17 00:00:00 2001 From: "Zhao, Halley" Date: Thu, 12 Dec 2013 10:01:13 +0800 Subject: [PATCH 1664/3781] vaapipostproc: reset deinterlacer state when there is a discontinuity. Reset deinterlacer state, i.e. past reference frames used for advanced deinterlacing, when there is some discontinuity detected in the course of processing source buffers. This fixes support for advanced deinterlacing when a seek occurred. https://bugzilla.gnome.org/show_bug.cgi?id=720375 [fixed type of pts_diff variable, fetch previous buffer PTS from the history buffer, reduce heuristic for detecting discontinuity] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipostproc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index f670c557d9..428cba4b30 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -513,6 +513,20 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, deint_changed = deint != ds->deint; if (deint_changed || (ds->num_surfaces > 0 && tff != ds->tff)) ds_reset(ds); + + deint_method = postproc->deinterlace_method; + deint_refs = deint_method_is_advanced(deint_method); + if (deint_refs) { + GstBuffer * const prev_buf = ds_get_buffer(ds, 0); + GstClockTime prev_pts, pts = GST_BUFFER_TIMESTAMP(inbuf); + /* Reset deinterlacing state when there is a discontinuity */ + if (prev_buf && (prev_pts = GST_BUFFER_TIMESTAMP(prev_buf)) != pts) { + const GstClockTimeDiff pts_diff = GST_CLOCK_DIFF(prev_pts, pts); + if (pts_diff < 0 || pts_diff > postproc->field_duration * 2) + ds_reset(ds); + } + } + ds->deint = deint; ds->tff = tff; @@ -520,8 +534,6 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, ~GST_VAAPI_PICTURE_STRUCTURE_MASK; /* First field */ - deint_method = postproc->deinterlace_method; - deint_refs = deint_method_is_advanced(deint_method); if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) { fieldbuf = create_output_buffer(postproc); if (!fieldbuf) From 1a2c06a81cb7d78609b99b5906f528070da9cad6 Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Fri, 7 Feb 2014 12:27:50 +0000 Subject: [PATCH 1665/3781] vaapipostproc: create filter surface pool if it does not exist yet. ensure_srcpad_buffer_pool() tries to avoid unnecessarily deleting and recreating filter_pool. Unfortunately, this also meant it didn't create it if it did not exist. Fix it to always create the buffer pool if it does not exist. https://bugzilla.gnome.org/show_bug.cgi?id=723834 Signed-off-by: Simon Farnsworth --- gst/vaapi/gstvaapipostproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 428cba4b30..73e1ea3af7 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1168,7 +1168,7 @@ ensure_srcpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps) gst_video_info_set_format(&vi, postproc->format, GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); - if (!video_info_changed(&vi, &postproc->filter_pool_info)) + if (postproc->filter_pool && !video_info_changed(&vi, &postproc->filter_pool_info)) return TRUE; postproc->filter_pool_info = vi; From 9d417815abec6b96b952d162b8eb2a1a2c2b4f4f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jun 2014 13:35:23 +0200 Subject: [PATCH 1666/3781] vaapipostproc: don't crash with dynamic framerate (0/1). Avoid reaching an assert if dynamic framerates (0/1) are used. One way to solve this problem is to just stick field_duration to zero. However, this means that, in presence of interlaced streams, the very first field will never be displayed if precise presentation timestamps are honoured. https://bugzilla.gnome.org/show_bug.cgi?id=729604 --- gst/vaapi/gstvaapipostproc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 73e1ea3af7..aa0cb9893c 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -522,7 +522,8 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, /* Reset deinterlacing state when there is a discontinuity */ if (prev_buf && (prev_pts = GST_BUFFER_TIMESTAMP(prev_buf)) != pts) { const GstClockTimeDiff pts_diff = GST_CLOCK_DIFF(prev_pts, pts); - if (pts_diff < 0 || pts_diff > postproc->field_duration * 2) + if (pts_diff < 0 || (postproc->field_duration > 0 && + pts_diff > postproc->field_duration * 2)) ds_reset(ds); } } @@ -823,9 +824,9 @@ gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps, deinterlace = is_deinterlace_enabled(postproc, &vi); if (deinterlace) postproc->flags |= GST_VAAPI_POSTPROC_FLAG_DEINTERLACE; - postproc->field_duration = gst_util_uint64_scale( - GST_SECOND, GST_VIDEO_INFO_FPS_D(&vi), - (1 + deinterlace) * GST_VIDEO_INFO_FPS_N(&vi)); + postproc->field_duration = GST_VIDEO_INFO_FPS_N(&vi) > 0 ? + gst_util_uint64_scale(GST_SECOND, GST_VIDEO_INFO_FPS_D(&vi), + (1 + deinterlace) * GST_VIDEO_INFO_FPS_N(&vi)) : 0; postproc->is_raw_yuv = GST_VIDEO_INFO_IS_YUV(&vi); return TRUE; From 95c781c34fad757eb820429604fbd4e3d921960a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 18 Jun 2014 18:53:51 +0200 Subject: [PATCH 1667/3781] decoder: h264: fix caps to report interlace-mode accordingly. The `vaapipostproc' element could never determine if the H.264 stream was interlaced, and thus always assumed it to be progressive. Fix the H.264 decoder to report interlace-mode accordingly, thus allowing the vaapipostproc element to automatically enable deinterlacing. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 82b8d1520a..1e709b5952 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1333,10 +1333,7 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) } priv->progressive_sequence = sps->frame_mbs_only_flag; -#if 0 - /* XXX: we only output complete frames for now */ gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence); -#endif gst_vaapi_decoder_set_pixel_aspect_ratio( base_decoder, From cb9f98f0d5501f7f700e33bbc969d0ce420c2601 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 6 Feb 2014 08:30:10 +0200 Subject: [PATCH 1668/3781] decoder: h264: add support for NALU "alignment" optimization. We can avoid scanning for start codes again if the bitstream is fed in NALU chunks. Currently, we always scan for start codes, and keep track of remaining bits in a GstAdapter, even if, in practice, we are likely receiving one GstBuffer per NAL unit. i.e. h264parse with "nal" alignment. https://bugzilla.gnome.org/show_bug.cgi?id=723284 [use gst_adapter_available_fast() to determine the top buffer size] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 74 ++++++++++++++++------- gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 23 +++++++ gst/vaapi/gstvaapidecode.c | 18 ++++++ 3 files changed, 93 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 1e709b5952..68c2b8192a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -445,6 +445,7 @@ struct _GstVaapiDecoderH264Private { GstH264NalParser *parser; guint parser_state; guint decoder_state; + GstVaapiStreamAlignH264 stream_alignment; GstVaapiPictureH264 *current_picture; GstVaapiParserInfoH264 *sps[GST_H264_MAX_SPS_COUNT]; GstVaapiParserInfoH264 *active_sps; @@ -3880,7 +3881,14 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - size = gst_adapter_available(adapter); + switch (priv->stream_alignment) { + case GST_VAAPI_STREAM_ALIGN_H264_NALU: + size = gst_adapter_available_fast(adapter); + break; + default: + size = gst_adapter_available(adapter); + break; + } if (priv->is_avcC) { if (size < priv->nal_length_size) @@ -3902,30 +3910,34 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, if (size < 4) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - ofs = scan_for_start_code(adapter, 0, size, NULL); - if (ofs < 0) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - - if (ofs > 0) { - gst_adapter_flush(adapter, ofs); - size -= ofs; - } - - ofs2 = ps->input_offset2 - ofs - 4; - if (ofs2 < 4) - ofs2 = 4; - - ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 : - scan_for_start_code(adapter, ofs2, size - ofs2, NULL); - if (ofs < 0) { - // Assume the whole NAL unit is present if end-of-stream - if (!at_eos) { - ps->input_offset2 = size; + if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_NALU) + buf_size = size; + else { + ofs = scan_for_start_code(adapter, 0, size, NULL); + if (ofs < 0) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + if (ofs > 0) { + gst_adapter_flush(adapter, ofs); + size -= ofs; } - ofs = size; + + ofs2 = ps->input_offset2 - ofs - 4; + if (ofs2 < 4) + ofs2 = 4; + + ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 : + scan_for_start_code(adapter, ofs2, size - ofs2, NULL); + if (ofs < 0) { + // Assume the whole NAL unit is present if end-of-stream + if (!at_eos) { + ps->input_offset2 = size; + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } + ofs = size; + } + buf_size = ofs; } - buf_size = ofs; } ps->input_offset2 = 0; @@ -4127,6 +4139,24 @@ gst_vaapi_decoder_h264_class(void) return GST_VAAPI_DECODER_CLASS(&g_class); } +/** + * gst_vaapi_decoder_h264_set_alignment: + * @decoder: a #GstVaapiDecoderH264 + * @alignment: the #GstVaapiStreamAlignH264 + * + * Specifies how stream buffers are aligned / fed, i.e. the boundaries + * of each buffer that is supplied to the decoder. This could be no + * specific alignment, NAL unit boundaries, or access unit boundaries. + */ +void +gst_vaapi_decoder_h264_set_alignment(GstVaapiDecoderH264 *decoder, + GstVaapiStreamAlignH264 alignment) +{ + g_return_if_fail(decoder != NULL); + + decoder->priv.stream_alignment = alignment; +} + /** * gst_vaapi_decoder_h264_new: * @display: a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h index 05c010b685..f9949dd126 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -27,11 +27,34 @@ G_BEGIN_DECLS +#define GST_VAAPI_DECODER_H264(decoder) \ + ((GstVaapiDecoderH264 *)(decoder)) + 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; + GstVaapiDecoder * gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps); +void +gst_vaapi_decoder_h264_set_alignment(GstVaapiDecoderH264 *decoder, + GstVaapiStreamAlignH264 alignment); + G_END_DECLS #endif /* GST_VAAPI_DECODER_H264_H */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 8ccc169d21..49df98422d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -644,6 +644,24 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) break; case GST_VAAPI_CODEC_H264: decode->decoder = gst_vaapi_decoder_h264_new(dpy, caps); + + /* Set the stream buffer alignment for better optimizations */ + if (decode->decoder && caps) { + GstStructure * const structure = gst_caps_get_structure(caps, 0); + const gchar *str = NULL; + + if ((str = gst_structure_get_string(structure, "alignment"))) { + GstVaapiStreamAlignH264 alignment; + if (g_strcmp0(str, "au") == 0) + alignment = GST_VAAPI_STREAM_ALIGN_H264_AU; + else if (g_strcmp0(str, "nal") == 0) + alignment = GST_VAAPI_STREAM_ALIGN_H264_NALU; + else + alignment = GST_VAAPI_STREAM_ALIGN_H264_NONE; + gst_vaapi_decoder_h264_set_alignment( + GST_VAAPI_DECODER_H264(decode->decoder), alignment); + } + } break; case GST_VAAPI_CODEC_WMV3: case GST_VAAPI_CODEC_VC1: From 8db72147c7737eecfe3cdc57940840b45fd3261f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 19 Jun 2014 17:08:47 +0200 Subject: [PATCH 1669/3781] decoder: h264: fix DPB clear when no decoding actually started. Fix dpb_clear() to clear previous frame buffers only if they actually exist to begin with. If the decoder bailed out early, e.g. when it does not support a specific profile, that array of previous frames might not be allocated beforehand. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 68c2b8192a..03dd51b3b0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -855,8 +855,9 @@ dpb_clear(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) /* Clear previous frame buffers only if this is a "flush-all" operation, or if the picture is the first one in the access unit */ - if (!picture || GST_VAAPI_PICTURE_FLAG_IS_SET(picture, - GST_VAAPI_PICTURE_FLAG_AU_START)) { + if (priv->prev_frames && (!picture || + GST_VAAPI_PICTURE_FLAG_IS_SET(picture, + GST_VAAPI_PICTURE_FLAG_AU_START))) { for (i = 0; i < priv->max_views; i++) gst_vaapi_picture_replace(&priv->prev_frames[i], NULL); } From bea0d07042862be1fb741647bb5a7a3b8b014bce Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 25 Jun 2014 22:26:32 +0200 Subject: [PATCH 1670/3781] decoder: h264: fix marking of non-reference picture into DPB. Fix search for a picture in the DPB that has a lower POC value than the current picture. The dpb_find_lowest_poc() function will return a picture with the lowest POC in DPB and that is marked as "needed for output", but an additional check against the actual POC value of the current picture is needed. This is a regression from 1c46990. https://bugzilla.gnome.org/show_bug.cgi?id=732130 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 03dd51b3b0..e223318d40 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -955,8 +955,10 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (!picture->output_flag && !StoreInterViewOnlyRefFlag) return TRUE; while (priv->dpb_count == priv->dpb_size) { + GstVaapiPictureH264 *found_picture; if (!StoreInterViewOnlyRefFlag) { - if (dpb_find_lowest_poc(decoder, picture, NULL) < 0) + if (dpb_find_lowest_poc(decoder, picture, &found_picture) < 0 || + found_picture->base.poc > picture->base.poc) return dpb_output(decoder, NULL, picture); } if (!dpb_bump(decoder, picture)) From a7c27bb7d50262d3a9878ffe226b738f508038b4 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 25 Jun 2014 22:05:52 +0300 Subject: [PATCH 1671/3781] encoder: h264: add missing field in packed Subset SPS header. Write the missing num_level_values_signalled_minus1 syntax element into the packed header for subset sequence parameter set. https://bugzilla.gnome.org/show_bug.cgi?id=732083 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 0af8e9457b..0802143cdf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -594,6 +594,7 @@ bs_write_subset_sps (GstBitWriter * bs, /* num level values signalled minus1 */ num_level_values_signalled_minus1 = 0; g_assert (num_level_values_signalled_minus1 < 64); + WRITE_UE (bs, num_level_values_signalled_minus1); for (i = 0; i <= num_level_values_signalled_minus1; i++) { guint16 num_applicable_ops_minus1 = 0; From 173f32d8e5cb40616e8eeb2f63a4c8a11c91c158 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 26 Jun 2014 11:39:38 +0300 Subject: [PATCH 1672/3781] encoder: h264: fix NAL unit types in packed headers. Submit Prefix NAL headers (nal_unit_type = 14) before every packed slice header (nal_unit_type = 1 or 5) only for the base view. In non base views, a Coded Slice Extension NAL header (nal_unit_type = 20) is required, with an appropriate nal_unit_header_mvc_extension() in the NAL header bytes. https://bugzilla.gnome.org/show_bug.cgi?id=732083 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 0802143cdf..cf0428be61 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1479,7 +1479,12 @@ add_packed_slice_header (GstVaapiEncoderH264 * encoder, if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) goto bs_error; - bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); + /* pack nal_unit_header_mvc_extension() for the non base view */ + if (encoder->is_mvc && encoder->view_idx) { + bs_write_nal_header (&bs, nal_ref_idc, GST_H264_NAL_SLICE_EXT); + bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_idx); + } else + bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); bs_write_slice (&bs, slice_param, encoder, picture); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); @@ -1887,8 +1892,10 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, /* set calculation for next slice */ last_mb_index += cur_slice_mbs; - if (encoder->is_mvc && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_RAW_DATA) + /* add packed Prefix NAL unit before each Coded slice NAL in base view */ + if (encoder->is_mvc && !encoder->view_idx && + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_RAW_DATA) && !add_packed_prefix_nal_header (encoder, picture, slice)) goto error_create_packed_prefix_nal_hdr; if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & From 8b473972e05d7040efb6605cce617a4fc7e4801c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jun 2014 14:37:58 +0200 Subject: [PATCH 1673/3781] h264parse: fix and optimize NAL collection function. Use gst_h264_parser_identify_nalu_unchecked() to identify the next NAL unit. We don't want to parse the full NAL unit, but only the header bytes and possibly the first RBSP byte for identifying the first_mb_in_slice syntax element. Also fix check for failure when returning from that function. The only success condition for that is GST_H264_PARSER_OK, so use it. https://bugzilla.gnome.org/show_bug.cgi?id=732154 --- ...and-optimize-NAL-collection-function.patch | 41 +++++++++++++++++++ patches/videoparsers/series.frag | 1 + 2 files changed, 42 insertions(+) create mode 100644 patches/videoparsers/0003-h264parse-fix-and-optimize-NAL-collection-function.patch diff --git a/patches/videoparsers/0003-h264parse-fix-and-optimize-NAL-collection-function.patch b/patches/videoparsers/0003-h264parse-fix-and-optimize-NAL-collection-function.patch new file mode 100644 index 0000000000..014a2f7e1d --- /dev/null +++ b/patches/videoparsers/0003-h264parse-fix-and-optimize-NAL-collection-function.patch @@ -0,0 +1,41 @@ +From cf890efdb44feb4cfc728756bcf0ce1df17b8e9d Mon Sep 17 00:00:00 2001 +From: Gwenole Beauchesne +Date: Tue, 24 Jun 2014 13:55:13 +0200 +Subject: [PATCH 3/8] h264parse: fix and optimize NAL collection function. + +Use gst_h264_parser_identify_nalu_unchecked() to identify the next +NAL unit. We don't want to parse the full NAL unit, but only the +header bytes and possibly the first RBSP byte for identifying the +first_mb_in_slice syntax element. + +Also fix check for failure when returning from that function. The +only success condition for that is GST_H264_PARSER_OK, so use it. + +https://bugzilla.gnome.org/show_bug.cgi?id=732154 + +Signed-off-by: Gwenole Beauchesne +--- + gst/vaapi/gsth264parse.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index fff1d48..7a88a07 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -668,10 +668,10 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data, + GstH264NalUnit nnalu; + + GST_DEBUG_OBJECT (h264parse, "parsing collected nal"); +- parse_res = gst_h264_parser_identify_nalu (h264parse->nalparser, data, +- nalu->offset + nalu->size, size, &nnalu); ++ parse_res = gst_h264_parser_identify_nalu_unchecked (h264parse->nalparser, ++ data, nalu->offset + nalu->size, size, &nnalu); + +- if (parse_res == GST_H264_PARSER_ERROR) ++ if (parse_res != GST_H264_PARSER_OK) + return FALSE; + + /* determine if AU complete */ +-- +1.7.9.5 + diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index 13612c58ea..14864ac96e 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -3,5 +3,6 @@ videoparsers_patches_base = \ 0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch \ 0002-h264parse-fix-build-with-GStreamer-1.2.patch \ + 0003-h264parse-fix-and-optimize-NAL-collection-function.patch \ 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch \ $(NULL) From c767be53d6aa73bb396fd500a02fe19cf1f2c12d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jun 2014 14:39:30 +0200 Subject: [PATCH 1674/3781] h264parse: default to byte-stream/nalu format (Annex B). Always default to stream-format=byte-stream,alignment=nalu if avcC format was not detected. This is the natural stream format specified in the standard (Annex.B): a series of NAL units prefixed with the usual start code. https://bugzilla.gnome.org/show_bug.cgi?id=732167 --- ...t-to-byte-stream-nalu-format-Annex-B.patch | 43 +++++++++++++++++++ patches/videoparsers/series.frag | 1 + 2 files changed, 44 insertions(+) create mode 100644 patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch diff --git a/patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch b/patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch new file mode 100644 index 0000000000..c86b3c9c0b --- /dev/null +++ b/patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch @@ -0,0 +1,43 @@ +From 3885faab12f7bbcc862a3da191161bf91b0b8bd9 Mon Sep 17 00:00:00 2001 +From: Gwenole Beauchesne +Date: Tue, 24 Jun 2014 17:27:12 +0200 +Subject: [PATCH 4/8] h264parse: default to byte-stream/nalu format (Annex B). + +Always default to stream-format=byte-stream,alignment=nalu if avcC +format was not detected. This is the natural stream format specified +in the standard (Annex.B): a series of NAL units prefixed with the +usual start code. + +https://bugzilla.gnome.org/show_bug.cgi?id=732167 + +Signed-off-by: Gwenole Beauchesne +--- + gst/vaapi/gsth264parse.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index 7a88a07..4800c2b 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -367,7 +367,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, + if (!format) + format = GST_H264_PARSE_FORMAT_BYTE; + if (!align) +- align = GST_H264_PARSE_ALIGN_AU; ++ align = format == GST_H264_PARSE_FORMAT_BYTE ? GST_H264_PARSE_ALIGN_NAL : ++ GST_H264_PARSE_ALIGN_AU; + + GST_DEBUG_OBJECT (h264parse, "selected format %s, alignment %s", + gst_h264_parse_get_string (h264parse, TRUE, format), +@@ -1893,7 +1894,7 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) + + if (format == GST_H264_PARSE_FORMAT_NONE) { + format = GST_H264_PARSE_FORMAT_BYTE; +- align = GST_H264_PARSE_ALIGN_AU; ++ align = GST_H264_PARSE_ALIGN_NAL; + } + } + +-- +1.7.9.5 + diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index 14864ac96e..778bd50434 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -4,5 +4,6 @@ videoparsers_patches_base = \ 0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch \ 0002-h264parse-fix-build-with-GStreamer-1.2.patch \ 0003-h264parse-fix-and-optimize-NAL-collection-function.patch \ + 0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch \ $(NULL) From 6d6caf17c965295419d7d9e21645760e05a43c1c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jun 2014 14:45:34 +0200 Subject: [PATCH 1675/3781] h264parse: introduce new state tracking variables. Improve parser state tracking by introducing new flags reflecting it: "got-sps", "got-pps" and "got-slice". This is an addition for robustness purposes. Older have_sps and have_pps variables are kept because they have a different meaning. i.e. they are used for deciding on when to submit updated caps or not, and rather mean "have new SPS/PPS to be submitted?" --- ...dd-initial-support-for-MVC-NAL-units.patch | 23 ++- ...troduce-new-state-tracking-variables.patch | 135 ++++++++++++++++++ patches/videoparsers/series.frag | 1 + 3 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch diff --git a/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch b/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch index 9316510565..656349bad8 100644 --- a/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch +++ b/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch @@ -27,19 +27,34 @@ index 7c970ee..e9b9481 100644 store_size = GST_H264_MAX_SPS_COUNT; store = h264parse->sps_nals; GST_DEBUG_OBJECT (h264parse, "storing sps %u", id); -@@ -534,6 +534,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) +@@ -551,10 +551,16 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + nal_type, _nal_name (nal_type), nalu->size); switch (nal_type) { - case GST_H264_NAL_SPS: + case GST_H264_NAL_SUBSET_SPS: ++ if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS)) ++ return FALSE; ++ goto process_sps; ++ + case GST_H264_NAL_SPS: + /* reset state, everything else is obsolete */ + h264parse->state = 0; + ++ process_sps: pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps, TRUE); /* arranged for a fallback sps.id, so use that one and only warn */ - if (pres != GST_H264_PARSER_OK) -@@ -594,14 +595,17 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + if (pres != GST_H264_PARSER_OK) { +@@ -631,6 +637,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) case GST_H264_NAL_SLICE_DPB: case GST_H264_NAL_SLICE_DPC: case GST_H264_NAL_SLICE_IDR: + case GST_H264_NAL_SLICE_EXT: + h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; + + /* don't need to parse the whole slice (header) here */ +@@ -638,13 +645,15 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + return FALSE; + /* don't need to parse the whole slice (header) here */ - if (*(nalu->data + nalu->offset + 1) & 0x80) { + if (*(nalu->data + nalu->offset + nalu->header_bytes) & 0x80) { diff --git a/patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch b/patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch new file mode 100644 index 0000000000..772aa381db --- /dev/null +++ b/patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch @@ -0,0 +1,135 @@ +From fcdf7736ca43b9847b22100042e19bf64005ee39 Mon Sep 17 00:00:00 2001 +From: Gwenole Beauchesne +Date: Wed, 25 Jun 2014 11:06:41 +0200 +Subject: [PATCH 5/8] h264parse: introduce new state tracking variables. + +Improve parser state tracking by introducing new flags reflecting +it: "got-sps", "got-pps" and "got-slice". This is an addition for +robustness purposes. + +Older have_sps and have_pps variables are kept because they have +a different meaning. i.e. they are used for deciding on when to +submit updated caps or not, and rather mean "have new SPS/PPS to +be submitted?" + +Signed-off-by: Gwenole Beauchesne +--- + gst/vaapi/gsth264parse.c | 30 +++++++++++++++++++++++++++++- + gst/vaapi/gsth264parse.h | 3 +++ + 2 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index 4800c2b..1542a82 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -61,6 +61,22 @@ enum + GST_H264_PARSE_ALIGN_AU + }; + ++enum ++{ ++ GST_H264_PARSE_STATE_GOT_SPS = 1 << 0, ++ GST_H264_PARSE_STATE_GOT_PPS = 1 << 1, ++ GST_H264_PARSE_STATE_GOT_SLICE = 1 << 2, ++ ++ GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS = (GST_H264_PARSE_STATE_GOT_SPS | ++ GST_H264_PARSE_STATE_GOT_PPS), ++ GST_H264_PARSE_STATE_VALID_PICTURE = ++ (GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS | ++ GST_H264_PARSE_STATE_GOT_SLICE) ++}; ++ ++#define GST_H264_PARSE_STATE_VALID(parse, expected_state) \ ++ (((parse)->state & (expected_state)) == (expected_state)) ++ + static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, +@@ -535,6 +551,9 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + + switch (nal_type) { + case GST_H264_NAL_SPS: ++ /* reset state, everything else is obsolete */ ++ h264parse->state = 0; ++ + pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps, TRUE); + /* arranged for a fallback sps.id, so use that one and only warn */ + if (pres != GST_H264_PARSER_OK) +@@ -553,8 +572,11 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + } + + gst_h264_parser_store_nal (h264parse, sps.id, nal_type, nalu); ++ h264parse->state |= GST_H264_PARSE_STATE_GOT_SPS; + break; + case GST_H264_NAL_PPS: ++ h264parse->state &= GST_H264_PARSE_STATE_GOT_SPS; ++ + pres = gst_h264_parser_parse_pps (nalparser, nalu, &pps); + /* arranged for a fallback pps.id, so use that one and only warn */ + if (pres != GST_H264_PARSER_OK) +@@ -576,6 +598,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + } + + gst_h264_parser_store_nal (h264parse, pps.id, nal_type, nalu); ++ h264parse->state |= GST_H264_PARSE_STATE_GOT_PPS; + break; + case GST_H264_NAL_SEI: + gst_h264_parse_process_sei (h264parse, nalu); +@@ -595,6 +618,8 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + case GST_H264_NAL_SLICE_DPB: + case GST_H264_NAL_SLICE_DPC: + case GST_H264_NAL_SLICE_IDR: ++ h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; ++ + /* don't need to parse the whole slice (header) here */ + if (*(nalu->data + nalu->offset + 1) & 0x80) { + /* means first_mb_in_slice == 0 */ +@@ -615,6 +640,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + if (GST_H264_IS_I_SLICE (&slice) || GST_H264_IS_SI_SLICE (&slice)) + h264parse->keyframe |= TRUE; + ++ h264parse->state |= GST_H264_PARSE_STATE_GOT_SLICE; + h264parse->field_pic_flag = slice.field_pic_flag; + } + } +@@ -964,7 +990,8 @@ gst_h264_parse_handle_frame (GstBaseParse * parse, + + if (nalu.type == GST_H264_NAL_SPS || + nalu.type == GST_H264_NAL_PPS || +- (h264parse->have_sps && h264parse->have_pps)) { ++ GST_H264_PARSE_STATE_VALID (h264parse, ++ GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS)) { + gst_h264_parse_process_nal (h264parse, &nalu); + } else { + GST_WARNING_OBJECT (h264parse, +@@ -1761,6 +1788,7 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) + h264parse->push_codec = FALSE; + h264parse->have_sps = FALSE; + h264parse->have_pps = FALSE; ++ h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; + } + } + +diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h +index 4c3fdd4..c9d188b 100644 +--- a/gst/vaapi/gsth264parse.h ++++ b/gst/vaapi/gsth264parse.h +@@ -69,12 +69,15 @@ struct _GstH264Parse + + /* state */ + GstH264NalParser *nalparser; ++ guint state; + guint align; + guint format; + gint current_off; + + GstClockTime last_report; + gboolean push_codec; ++ /* The following variables have a meaning in context of "have ++ * SPS/PPS to push downstream", e.g. to update caps */ + gboolean have_sps; + gboolean have_pps; + +-- +1.7.9.5 + diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index 778bd50434..44a77d64a3 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -5,5 +5,6 @@ videoparsers_patches_base = \ 0002-h264parse-fix-build-with-GStreamer-1.2.patch \ 0003-h264parse-fix-and-optimize-NAL-collection-function.patch \ 0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ + 0005-h264parse-introduce-new-state-tracking-variables.patch \ 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch \ $(NULL) From 2905209d9b5e8f157c97ee6135c3cb650a812e20 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jun 2014 14:48:08 +0200 Subject: [PATCH 1676/3781] h264parse: improve conditions for skipping NAL units. Carefully track cases when skipping broken or invalid NAL units is necessary. In particular, always allow NAL units to be processed and let that gst_h264_parse_process_nal() function decide on whether the current NAL needs to be dropped or not. This fixes parsing of streams with SEI NAL buffering_period() message inserted between SPS and PPS, or SPS-Ext NAL following a traditional SPS NAL unit, among other cases too. Practical examples from the H.264 AVC conformance suite include alphaconformanceG, CVSE2_Sony_B, CVSE3_Sony_H, CVSEFDFT3_Sony_E when parsing in stream-format=byte-stream,alignment=au mode. https://bugzilla.gnome.org/show_bug.cgi?id=732203 --- ...dd-initial-support-for-MVC-NAL-units.patch | 12 +- ...ve-conditions-for-skipping-NAL-units.patch | 146 ++++++++++++++++++ patches/videoparsers/series.frag | 1 + 3 files changed, 149 insertions(+), 10 deletions(-) create mode 100644 patches/videoparsers/0006-h264parse-improve-conditions-for-skipping-NAL-units.patch diff --git a/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch b/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch index 656349bad8..a62d8eec45 100644 --- a/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch +++ b/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch @@ -49,9 +49,9 @@ index 7c970ee..e9b9481 100644 case GST_H264_NAL_SLICE_DPC: case GST_H264_NAL_SLICE_IDR: + case GST_H264_NAL_SLICE_EXT: + /* expected state: got-sps|got-pps (valid picture headers) */ h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; - - /* don't need to parse the whole slice (header) here */ + if (!GST_H264_PARSE_STATE_VALID (h264parse, @@ -638,13 +645,15 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) return FALSE; @@ -101,14 +101,6 @@ index 7c970ee..e9b9481 100644 GST_LOG_OBJECT (h264parse, "au complete: %d", complete); -@@ -960,6 +967,7 @@ gst_h264_parse_handle_frame (GstBaseParse * parse, - } - - if (nalu.type == GST_H264_NAL_SPS || -+ nalu.type == GST_H264_NAL_SUBSET_SPS || - nalu.type == GST_H264_NAL_PPS || - (h264parse->have_sps && h264parse->have_pps)) { - gst_h264_parse_process_nal (h264parse, &nalu); -- 1.7.9.5 diff --git a/patches/videoparsers/0006-h264parse-improve-conditions-for-skipping-NAL-units.patch b/patches/videoparsers/0006-h264parse-improve-conditions-for-skipping-NAL-units.patch new file mode 100644 index 0000000000..912cd0ee7a --- /dev/null +++ b/patches/videoparsers/0006-h264parse-improve-conditions-for-skipping-NAL-units.patch @@ -0,0 +1,146 @@ +From 2b3680eeaff91f611d8c8b0e74efc66b0d874c66 Mon Sep 17 00:00:00 2001 +From: Gwenole Beauchesne +Date: Wed, 25 Jun 2014 13:14:10 +0200 +Subject: [PATCH 6/8] h264parse: improve conditions for skipping NAL units. + +Carefully track cases when skipping broken or invalid NAL units is +necessary. In particular, always allow NAL units to be processed +and let that gst_h264_parse_process_nal() function decide on whether +the current NAL needs to be dropped or not. + +This fixes parsing of streams with SEI NAL buffering_period() message +inserted between SPS and PPS, or SPS-Ext NAL following a traditional +SPS NAL unit, among other cases too. + +Practical examples from the H.264 AVC conformance suite include +alphaconformanceG, CVSE2_Sony_B, CVSE3_Sony_H, CVSEFDFT3_Sony_E +when parsing in stream-format=byte-stream,alignment=au mode. + +https://bugzilla.gnome.org/show_bug.cgi?id=732203 + +Signed-off-by: Gwenole Beauchesne +--- + gst/vaapi/gsth264parse.c | 43 +++++++++++++++++++++++++++++++------------ + 1 file changed, 31 insertions(+), 12 deletions(-) + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index 1542a82..805c55f 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -528,7 +528,7 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) + } + + /* caller guarantees 2 bytes of nal payload */ +-static void ++static gboolean + gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + { + guint nal_type; +@@ -540,7 +540,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + /* nothing to do for broken input */ + if (G_UNLIKELY (nalu->size < 2)) { + GST_DEBUG_OBJECT (h264parse, "not processing nal size %u", nalu->size); +- return; ++ return TRUE; + } + + /* we have a peek as well */ +@@ -556,8 +556,10 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + + pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps, TRUE); + /* arranged for a fallback sps.id, so use that one and only warn */ +- if (pres != GST_H264_PARSER_OK) ++ if (pres != GST_H264_PARSER_OK) { + GST_WARNING_OBJECT (h264parse, "failed to parse SPS:"); ++ return FALSE; ++ } + + GST_DEBUG_OBJECT (h264parse, "triggering src caps check"); + h264parse->update_caps = TRUE; +@@ -575,12 +577,18 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + h264parse->state |= GST_H264_PARSE_STATE_GOT_SPS; + break; + case GST_H264_NAL_PPS: ++ /* expected state: got-sps */ + h264parse->state &= GST_H264_PARSE_STATE_GOT_SPS; ++ if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS)) ++ return FALSE; + + pres = gst_h264_parser_parse_pps (nalparser, nalu, &pps); + /* arranged for a fallback pps.id, so use that one and only warn */ +- if (pres != GST_H264_PARSER_OK) ++ if (pres != GST_H264_PARSER_OK) { + GST_WARNING_OBJECT (h264parse, "failed to parse PPS:"); ++ if (pres != GST_H264_PARSER_BROKEN_LINK) ++ return FALSE; ++ } + + /* parameters might have changed, force caps check */ + if (!h264parse->have_pps) { +@@ -601,6 +609,10 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + h264parse->state |= GST_H264_PARSE_STATE_GOT_PPS; + break; + case GST_H264_NAL_SEI: ++ /* expected state: got-sps */ ++ if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS)) ++ return FALSE; ++ + gst_h264_parse_process_sei (h264parse, nalu); + /* mark SEI pos */ + if (h264parse->sei_pos == -1) { +@@ -618,7 +630,11 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + case GST_H264_NAL_SLICE_DPB: + case GST_H264_NAL_SLICE_DPC: + case GST_H264_NAL_SLICE_IDR: ++ /* expected state: got-sps|got-pps (valid picture headers) */ + h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; ++ if (!GST_H264_PARSE_STATE_VALID (h264parse, ++ GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS)) ++ return FALSE; + + /* don't need to parse the whole slice (header) here */ + if (*(nalu->data + nalu->offset + 1) & 0x80) { +@@ -668,7 +684,14 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + } + break; + default: +- gst_h264_parser_parse_nal (nalparser, nalu); ++ /* drop anything before the initial SPS */ ++ if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS)) ++ return FALSE; ++ ++ pres = gst_h264_parser_parse_nal (nalparser, nalu); ++ if (pres != GST_H264_PARSER_OK) ++ return FALSE; ++ break; + } + + /* if AVC output needed, collect properly prefixed nal in adapter, +@@ -681,6 +704,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + nalu->data + nalu->offset, nalu->size); + gst_adapter_push (h264parse->frame_out, buf); + } ++ return TRUE; + } + + /* caller guarantees at least 2 bytes of nal payload for each nal +@@ -988,14 +1012,9 @@ gst_h264_parse_handle_frame (GstBaseParse * parse, + } + } + +- if (nalu.type == GST_H264_NAL_SPS || +- nalu.type == GST_H264_NAL_PPS || +- GST_H264_PARSE_STATE_VALID (h264parse, +- GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS)) { +- gst_h264_parse_process_nal (h264parse, &nalu); +- } else { ++ if (!gst_h264_parse_process_nal (h264parse, &nalu)) { + GST_WARNING_OBJECT (h264parse, +- "no SPS/PPS yet, nal Type: %d %s, Size: %u will be dropped", ++ "broken/invalid nal Type: %d %s, Size: %u will be dropped", + nalu.type, _nal_name (nalu.type), nalu.size); + *skipsize = nalu.size; + goto skip; +-- +1.7.9.5 + diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index 44a77d64a3..b2a86ff604 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -6,5 +6,6 @@ videoparsers_patches_base = \ 0003-h264parse-fix-and-optimize-NAL-collection-function.patch \ 0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ 0005-h264parse-introduce-new-state-tracking-variables.patch \ + 0006-h264parse-improve-conditions-for-skipping-NAL-units.patch \ 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch \ $(NULL) From 92c7d9e6a5f6a2f7d51f5e888c364037c0b2be8c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jun 2014 14:49:53 +0200 Subject: [PATCH 1677/3781] h264parse: fix collection of access units to preserve config headers. Always use a GstAdapter when collecting access units (alignment="au") in either byte-stream or avcC format. This is required to properly preserve config headers like SPS and PPS when invalid or broken NAL units are subsequently parsed. More precisely, this fixes scenario like: where we used to reset the output frame buffer when an invalid or broken NAL is parsed, i.e. SPS and PPS NAL units were lost, thus preventing the next slice unit to be decoded, should this also represent any valid data. https://bugzilla.gnome.org/show_bug.cgi?id=732203 --- ...llection-of-access-units-to-preserve.patch | 58 +++++++++++++++++++ patches/videoparsers/series.frag | 1 + 2 files changed, 59 insertions(+) create mode 100644 patches/videoparsers/0007-h264parse-fix-collection-of-access-units-to-preserve.patch diff --git a/patches/videoparsers/0007-h264parse-fix-collection-of-access-units-to-preserve.patch b/patches/videoparsers/0007-h264parse-fix-collection-of-access-units-to-preserve.patch new file mode 100644 index 0000000000..7326d27d00 --- /dev/null +++ b/patches/videoparsers/0007-h264parse-fix-collection-of-access-units-to-preserve.patch @@ -0,0 +1,58 @@ +From def7c6b2a0fcd08969940349e458248dd0c7b3da Mon Sep 17 00:00:00 2001 +From: Gwenole Beauchesne +Date: Thu, 26 Jun 2014 09:44:26 +0200 +Subject: [PATCH 7/8] h264parse: fix collection of access units to preserve + config headers. + +Always use a GstAdapter when collecting access units (alignment="au") +in either byte-stream or avcC format. This is required to properly +preserve config headers like SPS and PPS when invalid or broken NAL +units are subsequently parsed. + +More precisely, this fixes scenario like: + + +where we used to reset the output frame buffer when an invalid or +broken NAL is parsed, i.e. SPS and PPS NAL units were lost, thus +preventing the next slice unit to be decoded, should this also +represent any valid data. + +https://bugzilla.gnome.org/show_bug.cgi?id=732203 + +Signed-off-by: Gwenole Beauchesne +--- + gst/vaapi/gsth264parse.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index 805c55f..413a227 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -393,7 +393,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, + h264parse->format = format; + h264parse->align = align; + +- h264parse->transform = (in_format != h264parse->format); ++ h264parse->transform = in_format != h264parse->format || ++ align == GST_H264_PARSE_ALIGN_AU; + } + + static GstBuffer * +@@ -1054,7 +1055,13 @@ out: + + skip: + GST_DEBUG_OBJECT (h264parse, "skipping %d", *skipsize); +- gst_h264_parse_reset_frame (h264parse); ++ /* If we are collecting access units, we need to preserve the initial ++ * config headers (SPS, PPS et al.) and only reset the frame if another ++ * slice NAL was received. This means that broken pictures are discarded */ ++ if (h264parse->align != GST_H264_PARSE_ALIGN_AU || ++ !(h264parse->state & GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS) || ++ (h264parse->state & GST_H264_PARSE_STATE_GOT_SLICE)) ++ gst_h264_parse_reset_frame (h264parse); + goto out; + + invalid_stream: +-- +1.7.9.5 + diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index b2a86ff604..46a7f5f9ed 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -7,5 +7,6 @@ videoparsers_patches_base = \ 0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ 0005-h264parse-introduce-new-state-tracking-variables.patch \ 0006-h264parse-improve-conditions-for-skipping-NAL-units.patch \ + 0007-h264parse-fix-collection-of-access-units-to-preserve.patch \ 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch \ $(NULL) From 1650471da36445a89f72ea86f65e1c7fcb4f5a74 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jun 2014 14:51:32 +0200 Subject: [PATCH 1678/3781] h264parse: fix detection of access unit boundaries for MVC. The gst_h264_parse_collect_nal() function is a misnomer. In reality, this function is used to determine access unit boundaries, i.e. that is the key function for alignment=au output format generation. --- ...dd-initial-support-for-MVC-NAL-units.patch | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch b/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch index a62d8eec45..e66d947bb4 100644 --- a/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch +++ b/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch @@ -1,7 +1,7 @@ -From 3ef58fae7a578f72c4607b57434ed54a0ee9ee1d Mon Sep 17 00:00:00 2001 +From b1974b68fac0dad1c76ab74f0b6b3d9ff99b6f27 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 19 Mar 2013 14:23:00 +0200 -Subject: [PATCH 3/3] h264parse: add initial support for MVC NAL units. +Subject: [PATCH 8/8] h264parse: add initial support for MVC NAL units. Initial support for MVC NAL units. It is only needed to propagate the complete set of NAL units downstream at this time. @@ -11,14 +11,14 @@ https://bugzilla.gnome.org/show_bug.cgi?id=696135 Signed-off-by: Sreerenj Balachandran Signed-off-by: Gwenole Beauchesne --- - gst/vaapi/gsth264parse.c | 20 ++++++++++++++------ - 1 file changed, 14 insertions(+), 6 deletions(-) + gst/vaapi/gsth264parse.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 7c970ee..e9b9481 100644 +index 413a227..b4f20f7 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c -@@ -415,7 +415,7 @@ gst_h264_parser_store_nal (GstH264Parse * h264parse, guint id, +@@ -433,7 +433,7 @@ gst_h264_parser_store_nal (GstH264Parse * h264parse, guint id, GstBuffer *buf, **store; guint size = nalu->size, store_size; @@ -69,17 +69,7 @@ index 7c970ee..e9b9481 100644 { GstH264SliceHdr slice; -@@ -677,7 +681,8 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data, - /* coded slice NAL starts a picture, - * i.e. other types become aggregated in front of it */ - h264parse->picture_start |= (nal_type == GST_H264_NAL_SLICE || -- nal_type == GST_H264_NAL_SLICE_DPA || nal_type == GST_H264_NAL_SLICE_IDR); -+ nal_type == GST_H264_NAL_SLICE_DPA || nal_type == GST_H264_NAL_SLICE_IDR -+ || nal_type == GST_H264_NAL_SLICE_EXT); - - /* consider a coded slices (IDR or not) to start a picture, - * (so ending the previous one) if first_mb_in_slice == 0 -@@ -687,16 +692,18 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data, +@@ -741,8 +750,9 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data, * and also works with broken frame_num in NAL * (where spec-wise would fail) */ nal_type = nnalu.type; @@ -91,9 +81,8 @@ index 7c970ee..e9b9481 100644 GST_LOG_OBJECT (h264parse, "next nal type: %d %s", nal_type, _nal_name (nal_type)); - complete |= h264parse->picture_start && (nal_type == GST_H264_NAL_SLICE +@@ -750,7 +760,7 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data, || nal_type == GST_H264_NAL_SLICE_DPA -+ || nal_type == GST_H264_NAL_SLICE_EXT || nal_type == GST_H264_NAL_SLICE_IDR) && /* first_mb_in_slice == 0 considered start of frame */ - (nnalu.data[nnalu.offset + 1] & 0x80); From 619a79943a579d30eaf44d562ca61b9f06ab3bad Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 26 Jun 2014 14:39:52 +0300 Subject: [PATCH 1679/3781] encoder: h264: add cpbBrNalFactor values for MVC profiles. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index cf0428be61..8eee95dae2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -169,6 +169,10 @@ h264_get_cpb_nal_factor (GstVaapiProfile profile) case GST_VAAPI_PROFILE_H264_HIGH_444: f = 4800; break; + case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH: + case GST_VAAPI_PROFILE_H264_STEREO_HIGH: + f = 1500; /* H.10.2.1 (r) */ + break; default: f = 1200; break; From 8ebf60124a5a7e695bfab3eb7596bb76ad5e4b33 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 27 Jun 2014 10:37:38 +0300 Subject: [PATCH 1680/3781] encoder: h264: fix timing_info_present_flag value in subset SPS. When the seq_parameter_set_data() syntax structure is present in a subset sequence parameter set and vui_parameters_present_flag is equal to 1, then timing_info_present_flag shall be equal to 0 (H.7.4.2.1.1). --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 8eee95dae2..f986d5e50f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1698,7 +1698,9 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) if (seq_param->vui_parameters_present_flag) { seq_param->vui_fields.bits.aspect_ratio_info_present_flag = FALSE; seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE; - seq_param->vui_fields.bits.timing_info_present_flag = TRUE; + /* if vui_parameters_present_flag is TRUE and sps data belongs to + * subset sps, timing_info_preset_flag should be zero (H.7.4.2.1.1) */ + seq_param->vui_fields.bits.timing_info_present_flag = !encoder->view_idx; if (seq_param->vui_fields.bits.timing_info_present_flag) { seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder); seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2; From a4bd8450f73b6ab0ae2afce497cb12850ac9702c Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 27 Jun 2014 00:49:34 +0300 Subject: [PATCH 1681/3781] encoder: h264: fix number of anchor and non-anchor reference pictures. Set the value of num_anchor_refs_l0, num_anchor_refs_l1, num_non_anchor_refs_l0, and num_non_anchor_refs_l1 to zero since the inter-view prediction is not yet supported. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index f986d5e50f..ac6e41f95b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -572,24 +572,24 @@ bs_write_subset_sps (GstBitWriter * bs, WRITE_UE (bs, i); for (i = 1; i <= num_views_minus1; i++) { - guint32 num_anchor_refs_l0 = 15; + guint32 num_anchor_refs_l0 = 0; WRITE_UE (bs, num_anchor_refs_l0); for (j = 0; j < num_anchor_refs_l0; j++) WRITE_UE (bs, 0); - guint32 num_anchor_refs_l1 = 15; + guint32 num_anchor_refs_l1 = 0; WRITE_UE (bs, num_anchor_refs_l1); for (j = 0; j < num_anchor_refs_l1; j++) WRITE_UE (bs, 0); } for (i = 1; i <= num_views_minus1; i++) { - guint num_non_anchor_refs_l0 = 15; + guint32 num_non_anchor_refs_l0 = 0; WRITE_UE (bs, num_non_anchor_refs_l0); for (j = 0; j < num_non_anchor_refs_l0; j++) WRITE_UE (bs, 0); - guint num_non_anchor_refs_l1 = 15; + guint32 num_non_anchor_refs_l1 = 0; WRITE_UE (bs, num_non_anchor_refs_l1); for (j = 0; j < num_non_anchor_refs_l1; j++) WRITE_UE (bs, 0); From a12662fd3e881fe13cf3587b4101f7f53c538136 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 27 Jun 2014 13:15:13 +0200 Subject: [PATCH 1682/3781] encoder: h264: add pixel-aspect-ratio to VUI parameters. Report sample aspect ratio (SAR) as present, and make it match what we have obtained from the user as pixel-aspect-ratio (PAR). i.e. the VUI parameter aspect_ratio_info_present_flag now defaults to TRUE. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index ac6e41f95b..7f6df3fd04 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1697,6 +1697,11 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) seq_param->vui_parameters_present_flag = TRUE; if (seq_param->vui_parameters_present_flag) { seq_param->vui_fields.bits.aspect_ratio_info_present_flag = FALSE; + if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { + const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); + seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip); + seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip); + } seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE; /* if vui_parameters_present_flag is TRUE and sps data belongs to * subset sps, timing_info_preset_flag should be zero (H.7.4.2.1.1) */ From 0d971bce26a2c91eaec229849b5bfc0c4019b0da Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 27 Jun 2014 18:43:27 +0200 Subject: [PATCH 1683/3781] encoder: h264: track encoder config changes. Track and report when encoder configuration changed. For now, this covers resolution, profile/level and bitrate changes. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 37 +++++++++++++++++++---- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 7f6df3fd04..c955d95968 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -738,6 +738,7 @@ struct _GstVaapiEncoderH264 gboolean use_cabac; gboolean use_dct8x8; GstClockTime cts_offset; + gboolean config_changed; /* frame, poc */ guint32 max_frame_num; @@ -2087,15 +2088,21 @@ ensure_bitrate_hrd (GstVaapiEncoderH264 * encoder) /* Round down bitrate. This is a hard limit mandated by the user */ g_assert (SX_BITRATE >= 6); bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1); - GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate); - encoder->bitrate_bits = bitrate; + if (bitrate != encoder->bitrate_bits) { + GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate); + encoder->bitrate_bits = bitrate; + encoder->config_changed = TRUE; + } /* Round up CPB size. This is an HRD compliance detail */ g_assert (SX_CPB_SIZE >= 4); cpb_size = gst_util_uint64_scale (bitrate, encoder->cpb_length, 1000) & ~((1U << SX_CPB_SIZE) - 1); - GST_DEBUG ("HRD CPB size: %u bits", cpb_size); - encoder->cpb_length_bits = cpb_size; + if (cpb_size != encoder->cpb_length_bits) { + GST_DEBUG ("HRD CPB size: %u bits", cpb_size); + encoder->cpb_length_bits = cpb_size; + encoder->config_changed = TRUE; + } } /* Estimates a good enough bitrate if none was supplied */ @@ -2138,6 +2145,9 @@ ensure_bitrate (GstVaapiEncoderH264 * encoder) static GstVaapiEncoderStatus ensure_profile_and_level (GstVaapiEncoderH264 * encoder) { + const GstVaapiProfile profile = encoder->profile; + const GstVaapiLevelH264 level = encoder->level; + ensure_tuning (encoder); if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) @@ -2153,6 +2163,13 @@ ensure_profile_and_level (GstVaapiEncoderH264 * encoder) ensure_bitrate (encoder); if (!ensure_level (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + + if (encoder->profile != profile || encoder->level != level) { + GST_DEBUG ("selected %s profile at level %s", + gst_vaapi_utils_h264_get_profile_string (encoder->profile), + gst_vaapi_utils_h264_get_level_string (encoder->level)); + encoder->config_changed = TRUE; + } return GST_VAAPI_ENCODER_STATUS_SUCCESS; } @@ -2525,9 +2542,17 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264_CAST (base_encoder); GstVaapiEncoderStatus status; + guint mb_width, mb_height; - encoder->mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; - encoder->mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; + mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; + mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; + if (mb_width != encoder->mb_width || mb_height != encoder->mb_height) { + GST_DEBUG ("resolution: %dx%d", GST_VAAPI_ENCODER_WIDTH (encoder), + GST_VAAPI_ENCODER_HEIGHT (encoder)); + encoder->mb_width = mb_width; + encoder->mb_height = mb_height; + encoder->config_changed = TRUE; + } status = ensure_profile_and_level (encoder); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) From 95d7f95971467bc7af75f8be4b68d5d7c8df4f99 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 27 Jun 2014 16:38:03 +0300 Subject: [PATCH 1684/3781] encoder: h264: generate new SPS only when codec config changed. It is not necessary to periodically send SPS or subset SPS headers. This is up to the upper layer (e.g. transport layer) to decide on if/how to periodically submit those. For now, only generate new SPS or subset SPS headers when the codec config changed. Note: the upper layer could readily determine the config headers (SPS/PPS) through the gst_vaapi_encoder_h264_get_codec_data() function. https://bugzilla.gnome.org/show_bug.cgi?id=732083 Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index c955d95968..3277f00017 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1941,8 +1941,8 @@ ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncSequence *sequence = NULL; - // Submit an SPS header before every new I-frame - if (picture->type != GST_VAAPI_PICTURE_TYPE_I) + /* submit an SPS header before every new I-frame, if codec config changed */ + if (!encoder->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I) return TRUE; sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder); @@ -1964,6 +1964,9 @@ ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) gst_vaapi_enc_picture_set_sequence (picture, sequence); gst_vaapi_codec_object_replace (&sequence, NULL); } + + if (!encoder->is_mvc || encoder->view_idx > 0) + encoder->config_changed = FALSE; return TRUE; /* ERRORS */ From 9169c520cb6b84ba3f80e1ec38d60e461267646a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 27 Jun 2014 20:44:24 +0200 Subject: [PATCH 1685/3781] decoder: h264: fix the DPB compaction process. Fix the compaction process when the DPB is cleared for a specific view, i.e. fix the process of filling in the holes resulting from removing frame buffers matching the current picture. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index e223318d40..24d1aaebf4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -847,9 +847,15 @@ dpb_clear(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) gst_vaapi_frame_store_replace(&priv->dpb[i], NULL); } + /* Compact the resulting DPB, i.e. remove holes */ for (i = 0, n = 0; i < priv->dpb_count; i++) { - if (priv->dpb[i]) - priv->dpb[n++] = priv->dpb[i]; + if (priv->dpb[i]) { + if (i != n) { + priv->dpb[n] = priv->dpb[i]; + priv->dpb[i] = NULL; + } + n++; + } } priv->dpb_count = n; @@ -859,7 +865,7 @@ dpb_clear(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_AU_START))) { for (i = 0; i < priv->max_views; i++) - gst_vaapi_picture_replace(&priv->prev_frames[i], NULL); + gst_vaapi_frame_store_replace(&priv->prev_frames[i], NULL); } } @@ -1026,7 +1032,7 @@ mvc_reset(GstVaapiDecoderH264 *decoder) // Resize array of previous frame buffers for (i = priv->max_views; i < priv->prev_frames_alloc; i++) - gst_vaapi_picture_replace(&priv->prev_frames[i], NULL); + gst_vaapi_frame_store_replace(&priv->prev_frames[i], NULL); priv->prev_frames = g_try_realloc_n(priv->prev_frames, priv->max_views, sizeof(*priv->prev_frames)); From 850d3d6a4d7579716b8f2beadf66b67be4574675 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 28 Jun 2014 07:25:35 +0200 Subject: [PATCH 1686/3781] decoder: h264: fix tracking of DPB size changes. Add support for MVC streams with multiple SPS and subset SPS headers emitted regularly, e.g. at around every I-frame. Track the maximum number of views in ensure_context() and really reset the DPB size to the expected value, always. i.e. even if it decreased. dpb_reset() only cares of ensuring the DPB allocation. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 30 +++++++++-------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 24d1aaebf4..2db507330f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -985,9 +985,6 @@ dpb_reset(GstVaapiDecoderH264 *decoder, guint dpb_size) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - if (dpb_size < priv->dpb_count) - return FALSE; - if (dpb_size > priv->dpb_size_max) { priv->dpb = g_try_realloc_n(priv->dpb, dpb_size, sizeof(*priv->dpb)); if (!priv->dpb) @@ -996,11 +993,7 @@ dpb_reset(GstVaapiDecoderH264 *decoder, guint dpb_size) (dpb_size - priv->dpb_size_max) * sizeof(*priv->dpb)); priv->dpb_size_max = dpb_size; } - - if (priv->dpb_size < dpb_size) - priv->dpb_size = dpb_size; - else if (dpb_size < priv->dpb_count) - return FALSE; + priv->dpb_size = dpb_size; GST_DEBUG("DPB size %u", priv->dpb_size); return TRUE; @@ -1300,7 +1293,13 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) GstVaapiProfile profile; GstVaapiChromaType chroma_type; gboolean reset_context = FALSE; - guint mb_width, mb_height, dpb_size; + guint mb_width, mb_height, dpb_size, num_views; + + num_views = get_num_views(sps); + if (priv->max_views < num_views) { + priv->max_views = num_views; + GST_DEBUG("maximum number of views changed to %u", num_views); + } dpb_size = get_max_dec_frame_buffering(sps); if (priv->dpb_size < dpb_size) { @@ -1495,9 +1494,6 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) if (result != GST_H264_PARSER_OK) return get_status(result); - /* Reset defaults */ - priv->max_views = 1; - priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1577,7 +1573,6 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GstH264NalUnit * const nalu = &pi->nalu; GstH264SPS *sps; GstH264ParserResult result; - guint num_views; GST_DEBUG("parse slice"); @@ -1625,11 +1620,6 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) sps = slice_hdr->pps->sequence; /* Update MVC data */ - num_views = get_num_views(sps); - if (priv->max_views < num_views) { - priv->max_views = num_views; - GST_DEBUG("maximum number of views changed to %u", num_views); - } pi->view_id = get_view_id(&pi->nalu); pi->voc = get_view_order_index(sps, pi->view_id); @@ -1679,6 +1669,7 @@ decode_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderH264 *decoder) { + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; GST_DEBUG("decode sequence-end"); @@ -1688,6 +1679,9 @@ decode_sequence_end(GstVaapiDecoderH264 *decoder) return status; dpb_flush(decoder, NULL); + + /* Reset defaults, should there be a new sequence available next */ + priv->max_views = 1; return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 8ed129b8bd5301aa080990a77a45b5f24e541255 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 13 Jun 2014 15:42:53 +0200 Subject: [PATCH 1687/3781] decoder: h264: handle access unit ("au") optimization. Optimize parsing when buffers are supplied with access unit alignment. This helps determining faster when the end of an access unit is reached. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 2db507330f..2dbe8f15bd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -3879,6 +3879,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, guint i, size, buf_size, nalu_size, flags; guint32 start_code; gint ofs, ofs2; + gboolean at_au_end = FALSE; status = ensure_decoder(decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) @@ -3886,6 +3887,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, switch (priv->stream_alignment) { case GST_VAAPI_STREAM_ALIGN_H264_NALU: + case GST_VAAPI_STREAM_ALIGN_H264_AU: size = gst_adapter_available_fast(adapter); break; default: @@ -3908,6 +3910,8 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, buf_size = priv->nal_length_size + nalu_size; if (size < buf_size) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + else if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_AU) + at_au_end = (buf_size == size); } else { if (size < 4) @@ -3933,7 +3937,10 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, scan_for_start_code(adapter, ofs2, size - ofs2, NULL); if (ofs < 0) { // Assume the whole NAL unit is present if end-of-stream - if (!at_eos) { + // or stream buffers aligned on access unit boundaries + if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_AU) + at_au_end = TRUE; + else if (!at_eos) { ps->input_offset2 = size; return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; } @@ -3998,6 +4005,10 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, return status; flags = 0; + if (at_au_end) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END | + GST_VAAPI_DECODER_UNIT_FLAG_AU_END; + } switch (pi->nalu.type) { case GST_H264_NAL_AU_DELIMITER: flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; From a208a80c2989dd4c5c81d4c1603c0ad52a9f430c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 30 Jun 2014 11:06:29 +0200 Subject: [PATCH 1688/3781] decoder: h264: slightly optimize the process to detect new pictures. Optimize the process to detect new pictures or start of new access units by checking if the previous NAL unit was the end of a picture, or the end of the previous access unit. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 2dbe8f15bd..a51595b7b0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4040,7 +4040,12 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, case GST_H264_NAL_SLICE_IDR: case GST_H264_NAL_SLICE: flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; - if (is_new_picture(pi, priv->prev_slice_pi)) { + if (priv->prev_pi && + (priv->prev_pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END)) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START | + GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + } + else if (is_new_picture(pi, priv->prev_slice_pi)) { flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; if (is_new_access_unit(pi, priv->prev_slice_pi)) flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; From f48b1e0cd6eb42d9260bb50318b44cdc2fbb8629 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 30 Jun 2014 16:09:17 +0200 Subject: [PATCH 1689/3781] decoder: h264: fix output of second field when first field is not in DPB. Fix decoding of interlaced streams where a first field (e.g. B-slice) was immediately output and the current decoded field is to be paired with that former frame, which is no longer in DPB. https://bugzilla.gnome.org/show_bug.cgi?id=701340 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 30 ++++++++++++++--------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index a51595b7b0..0b3d0c66e7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -689,11 +689,11 @@ dpb_output( { picture->output_needed = FALSE; - if (fs) { - if (--fs->output_needed > 0) - return TRUE; - picture = fs->buffers[0]; - } + if (--fs->output_needed > 0) + return TRUE; + + if (!GST_VAAPI_PICTURE_IS_COMPLETE(picture)) + return TRUE; return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture)); } @@ -929,6 +929,14 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) GST_VAAPI_PICTURE_H264(picture->base.parent_picture)); if (found_index >= 0) return gst_vaapi_frame_store_add(priv->dpb[found_index], picture); + + // ... also check the previous picture that was immediately output + fs = priv->prev_frames[picture->base.voc]; + if (fs && &fs->buffers[0]->base == picture->base.parent_picture) { + if (!gst_vaapi_frame_store_add(fs, picture)) + return FALSE; + return dpb_output(decoder, fs, picture); + } } // Create new frame store, and split fields if necessary @@ -938,6 +946,11 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) gst_vaapi_frame_store_replace(&priv->prev_frames[picture->base.voc], fs); gst_vaapi_frame_store_unref(fs); + if (picture->output_flag) { + picture->output_needed = TRUE; + fs->output_needed++; + } + if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) { if (!gst_vaapi_frame_store_split_fields(fs)) return FALSE; @@ -965,18 +978,13 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (!StoreInterViewOnlyRefFlag) { if (dpb_find_lowest_poc(decoder, picture, &found_picture) < 0 || found_picture->base.poc > picture->base.poc) - return dpb_output(decoder, NULL, picture); + return dpb_output(decoder, fs, picture); } if (!dpb_bump(decoder, picture)) return FALSE; } } - gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs); - if (picture->output_flag) { - picture->output_needed = TRUE; - fs->output_needed++; - } return TRUE; } From 8bdef56cd42d920bcfd81ebe3273d15e02d15c13 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 30 Jun 2014 16:12:52 +0200 Subject: [PATCH 1690/3781] decoder: h264: decode current picture earlier. Slightly optimize decoding process by submitting the current VA surface for decoding earlier to the hardware, and perform the reference picture marking process and DPB update process afterwards. This is a minor optimization to let the video decode engine kick in work earlier, thus improving parallel resources utilization. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 0b3d0c66e7..fe3f628b5b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1463,12 +1463,12 @@ decode_current_picture(GstVaapiDecoderH264 *decoder) if (!picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture))) + goto error; if (!exec_ref_pic_marking(decoder, picture)) goto error; if (!dpb_add(decoder, picture)) goto error; - if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture))) - goto error; gst_vaapi_picture_replace(&priv->current_picture, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; From f040f4f8b4d3ecdc995f1401fe13cd222def95e9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 30 Jun 2014 18:34:45 +0200 Subject: [PATCH 1691/3781] decoder: output decoded frames only once. Make sure to output the decoded picture, and push the associated GstVideoCodecFrame, only once. The frame fully represents what needs to be output, included for interlaced streams. Otherwise, the base GstVideoDecoder class would release the frame twice. Anyway, the general process is to output decoded frames only when they are complete. By complete, we mean a full frame was decoded or both fields of a frame were decoded. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 23 ++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 5277fbc635..edd9a62c65 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -294,6 +294,17 @@ gst_vaapi_picture_decode (GstVaapiPicture * picture) return TRUE; } +/* 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) { @@ -350,10 +361,14 @@ gst_vaapi_picture_output (GstVaapiPicture * picture) break; if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD (parent_picture)) break; - GST_VAAPI_PICTURE_FLAG_SET (parent_picture, - GST_VAAPI_PICTURE_FLAG_SKIPPED); - if (!do_output (parent_picture)) - return FALSE; + 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); From 70a48e09624b8fb5d1c6f7e539f6150f13eeec20 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 30 Jun 2014 18:46:45 +0200 Subject: [PATCH 1692/3781] decoder: propagate "one-field" flags. Allow decoders to set the "one-field" attribute when the decoded frame genuinely has a single field, or if the second field was mis-decoded but we still want to display the first field. --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index edd9a62c65..76bc79df44 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -336,6 +336,8 @@ do_output (GstVaapiPicture * 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_ONEFIELD (picture)) + flags |= GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD; } GST_VAAPI_SURFACE_PROXY_FLAG_SET (proxy, flags); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index e2790cb138..6499574891 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -65,6 +65,7 @@ typedef enum * @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_LAST: first flag that can be used by subclasses * @@ -78,8 +79,9 @@ typedef enum 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_MVC = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 6), - GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 7), + 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_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 8), } GstVaapiPictureFlags; #define GST_VAAPI_PICTURE_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS @@ -105,12 +107,16 @@ typedef enum #define GST_VAAPI_PICTURE_IS_TFF(picture) \ GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_TFF) +#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_FIRST_FIELD (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)) From 702de9ad2fcd1b26e06c044a28ef62b0508ee621 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 30 Jun 2014 19:01:35 +0200 Subject: [PATCH 1693/3781] decoder: propagate MVC metadata ("view-id", head of multiview set). Add new GstVaapiSurfaceProxy flag FFB, which means "first frame in bundle", and really expresses the first view component of a multi view coded frame. e.g. in H.264 MVC, the surface proxy has flag FFB set if VOIdx = 0. Likewise, new API is exposed to retrieve the associated "view-id". --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 6 ++++++ gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 17 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 16 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h | 14 ++++++++++++++ 4 files changed, 53 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 76bc79df44..516ff69cb0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -332,6 +332,12 @@ do_output (GstVaapiPicture * picture) GST_VIDEO_CODEC_FRAME_FLAG_SET (out_frame, GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); + 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)) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index cb014dae68..ab8f508a73 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -91,6 +91,7 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool); if (!proxy->surface) goto error; + proxy->view_id = 0; proxy->timestamp = GST_CLOCK_TIME_NONE; proxy->duration = GST_CLOCK_TIME_NONE; proxy->has_crop_rect = FALSE; @@ -245,6 +246,22 @@ gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) return GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy); } +/** + * gst_vaapi_surface_proxy_get_view_id: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the decoded view-id stored in the @proxy. + * + * Return value: the #GstVaapiID + */ +guintptr +gst_vaapi_surface_proxy_get_view_id(GstVaapiSurfaceProxy *proxy) +{ + g_return_val_if_fail(proxy != NULL, 0); + + return GST_VAAPI_SURFACE_PROXY_VIEW_ID(proxy); +} + /** * gst_vaapi_surface_proxy_get_timestamp: * @proxy: a #GstVaapiSurfaceProxy diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 1b05af0b94..b36be5db43 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -36,6 +36,8 @@ G_BEGIN_DECLS * @GST_VAAPI_SURFACE_PROXY_FLAG_TFF: top-field-first * @GST_VAAPI_SURFACE_PROXY_FLAG_RFF: repeat-field-first * @GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD: only one field is available + * @GST_VAAPI_SURFACE_PROXY_FLAG_FFB: first frame in bundle, e.g. the first + * view component of a MultiView Coded (MVC) frame * @GST_VAAPI_SURFACE_PROXY_FLAG_LAST: first flag that can be used by subclasses * * Flags for #GstVaapiDecoderFrame. @@ -45,6 +47,7 @@ typedef enum { GST_VAAPI_SURFACE_PROXY_FLAG_TFF = (1 << 1), GST_VAAPI_SURFACE_PROXY_FLAG_RFF = (1 << 2), GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD = (1 << 3), + GST_VAAPI_SURFACE_PROXY_FLAG_FFB = (1 << 4), GST_VAAPI_SURFACE_PROXY_FLAG_LAST = (1 << 8) } GstVaapiSurfaceProxyFlags; @@ -67,6 +70,16 @@ typedef enum { #define GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) \ gst_vaapi_surface_proxy_get_surface_id(proxy) +/** + * GST_VAAPI_SURFACE_PROXY_VIEW_ID: + * @proxy: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the decoded view ID of the underlying @proxy + * surface. + */ +#define GST_VAAPI_SURFACE_PROXY_VIEW_ID(proxy) \ + gst_vaapi_surface_proxy_get_view_id(proxy) + /** * GST_VAAPI_SURFACE_PROXY_TIMESTAMP: * @proxy: a #GstVaapiSurfaceProxy @@ -112,6 +125,9 @@ gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy); GstVaapiID gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy); +guintptr +gst_vaapi_surface_proxy_get_view_id(GstVaapiSurfaceProxy *proxy); + GstClockTime gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy); diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index a74cddf768..24043994dc 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -40,6 +40,7 @@ struct _GstVaapiSurfaceProxy { GstVaapiVideoPool *pool; GstVaapiSurface *surface; + guintptr view_id; GstClockTime timestamp; GstClockTime duration; GDestroyNotify destroy_func; @@ -77,6 +78,19 @@ struct _GstVaapiSurfaceProxy { #define GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) \ GST_VAAPI_OBJECT_ID(GST_VAAPI_SURFACE_PROXY(proxy)->surface) +/** + * GST_VAAPI_SURFACE_PROXY_VIEW_ID: + * @proxy: a #GstVaapiSurfaceProxy + * + * Macro that evaluates to the decoded view ID of the underlying @proxy + * surface. + * + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_SURFACE_PROXY_VIEW_ID +#define GST_VAAPI_SURFACE_PROXY_VIEW_ID(proxy) \ + GST_VAAPI_SURFACE_PROXY(proxy)->view_id + /** * GST_VAAPI_SURFACE_PROXY_TIMESTAMP: * @proxy: a #GstVaapiSurfaceProxy From 4263effee560044a6cdffb36d1763acd9026241e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 1 Jul 2014 17:13:56 +0200 Subject: [PATCH 1694/3781] codecparsers: update to gst-vaapi-branch commit 2d53b69. c4ace00 h264parse: fix collection of access units to preserve config headers 0f9f7c9 h264parse: improve conditions for skipping NAL units 9ffb25c h264parse: introduce new state tracking variables 64955d3 h264parse: fix and optimize NAL collection function 13cd2a3 h264: clarifications and documentation fixes 53e7dd1 h264: fix identification of EOSEQ and EOS NALs 18f0de0 h264: fix memory leak in GstH264PPS fdcb54c h264: fix typo in GstH264VUIParams description fd4dae9 vp8: move up built-in range decoder private data --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index d6325ac0f1..2d53b693e8 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit d6325ac0f17df46140355d3a43e54319e7bb2e36 +Subproject commit 2d53b693e8c0cce8f395bce0cb1817c51db345af From cba9b973006b9f59046578a195ead1c23262a509 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 1 Jul 2014 17:18:08 +0200 Subject: [PATCH 1695/3781] decoder: h264: fix memory leak in PPS. Cope with latest changes from codecparsers/h264. It is now required to explicitly clear the GstH264PPS structure as it could contain additional allocations (slice_group_ids). --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index fe3f628b5b..7caabfbd89 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -104,6 +104,9 @@ gst_vaapi_parser_info_h264_finalize(GstVaapiParserInfoH264 *pi) case GST_H264_NAL_SUBSET_SPS: gst_h264_sps_clear(&pi->data.sps); break; + case GST_H264_NAL_PPS: + gst_h264_pps_clear(&pi->data.pps); + break; case GST_H264_NAL_SEI: if (pi->data.sei) { g_array_unref(pi->data.sei); From e6cdacee65f221e4c464cff5cc5f2bbb74a75146 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 1 Jul 2014 17:20:44 +0200 Subject: [PATCH 1696/3781] h264parse: drop patches merged upstream. 0003-h264parse-fix-and-optimize-NAL-collection-function.patch 0005-h264parse-introduce-new-state-tracking-variables.patch 0006-h264parse-improve-conditions-for-skipping-NAL-units.patch 0007-h264parse-fix-collection-of-access-units-to-preserve.patch --- ...and-optimize-NAL-collection-function.patch | 41 ----- ...troduce-new-state-tracking-variables.patch | 135 ---------------- ...ve-conditions-for-skipping-NAL-units.patch | 146 ------------------ ...llection-of-access-units-to-preserve.patch | 58 ------- patches/videoparsers/series.frag | 4 - 5 files changed, 384 deletions(-) delete mode 100644 patches/videoparsers/0003-h264parse-fix-and-optimize-NAL-collection-function.patch delete mode 100644 patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch delete mode 100644 patches/videoparsers/0006-h264parse-improve-conditions-for-skipping-NAL-units.patch delete mode 100644 patches/videoparsers/0007-h264parse-fix-collection-of-access-units-to-preserve.patch diff --git a/patches/videoparsers/0003-h264parse-fix-and-optimize-NAL-collection-function.patch b/patches/videoparsers/0003-h264parse-fix-and-optimize-NAL-collection-function.patch deleted file mode 100644 index 014a2f7e1d..0000000000 --- a/patches/videoparsers/0003-h264parse-fix-and-optimize-NAL-collection-function.patch +++ /dev/null @@ -1,41 +0,0 @@ -From cf890efdb44feb4cfc728756bcf0ce1df17b8e9d Mon Sep 17 00:00:00 2001 -From: Gwenole Beauchesne -Date: Tue, 24 Jun 2014 13:55:13 +0200 -Subject: [PATCH 3/8] h264parse: fix and optimize NAL collection function. - -Use gst_h264_parser_identify_nalu_unchecked() to identify the next -NAL unit. We don't want to parse the full NAL unit, but only the -header bytes and possibly the first RBSP byte for identifying the -first_mb_in_slice syntax element. - -Also fix check for failure when returning from that function. The -only success condition for that is GST_H264_PARSER_OK, so use it. - -https://bugzilla.gnome.org/show_bug.cgi?id=732154 - -Signed-off-by: Gwenole Beauchesne ---- - gst/vaapi/gsth264parse.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index fff1d48..7a88a07 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -668,10 +668,10 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data, - GstH264NalUnit nnalu; - - GST_DEBUG_OBJECT (h264parse, "parsing collected nal"); -- parse_res = gst_h264_parser_identify_nalu (h264parse->nalparser, data, -- nalu->offset + nalu->size, size, &nnalu); -+ parse_res = gst_h264_parser_identify_nalu_unchecked (h264parse->nalparser, -+ data, nalu->offset + nalu->size, size, &nnalu); - -- if (parse_res == GST_H264_PARSER_ERROR) -+ if (parse_res != GST_H264_PARSER_OK) - return FALSE; - - /* determine if AU complete */ --- -1.7.9.5 - diff --git a/patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch b/patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch deleted file mode 100644 index 772aa381db..0000000000 --- a/patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch +++ /dev/null @@ -1,135 +0,0 @@ -From fcdf7736ca43b9847b22100042e19bf64005ee39 Mon Sep 17 00:00:00 2001 -From: Gwenole Beauchesne -Date: Wed, 25 Jun 2014 11:06:41 +0200 -Subject: [PATCH 5/8] h264parse: introduce new state tracking variables. - -Improve parser state tracking by introducing new flags reflecting -it: "got-sps", "got-pps" and "got-slice". This is an addition for -robustness purposes. - -Older have_sps and have_pps variables are kept because they have -a different meaning. i.e. they are used for deciding on when to -submit updated caps or not, and rather mean "have new SPS/PPS to -be submitted?" - -Signed-off-by: Gwenole Beauchesne ---- - gst/vaapi/gsth264parse.c | 30 +++++++++++++++++++++++++++++- - gst/vaapi/gsth264parse.h | 3 +++ - 2 files changed, 32 insertions(+), 1 deletion(-) - -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 4800c2b..1542a82 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -61,6 +61,22 @@ enum - GST_H264_PARSE_ALIGN_AU - }; - -+enum -+{ -+ GST_H264_PARSE_STATE_GOT_SPS = 1 << 0, -+ GST_H264_PARSE_STATE_GOT_PPS = 1 << 1, -+ GST_H264_PARSE_STATE_GOT_SLICE = 1 << 2, -+ -+ GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS = (GST_H264_PARSE_STATE_GOT_SPS | -+ GST_H264_PARSE_STATE_GOT_PPS), -+ GST_H264_PARSE_STATE_VALID_PICTURE = -+ (GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS | -+ GST_H264_PARSE_STATE_GOT_SLICE) -+}; -+ -+#define GST_H264_PARSE_STATE_VALID(parse, expected_state) \ -+ (((parse)->state & (expected_state)) == (expected_state)) -+ - static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, -@@ -535,6 +551,9 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - - switch (nal_type) { - case GST_H264_NAL_SPS: -+ /* reset state, everything else is obsolete */ -+ h264parse->state = 0; -+ - pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps, TRUE); - /* arranged for a fallback sps.id, so use that one and only warn */ - if (pres != GST_H264_PARSER_OK) -@@ -553,8 +572,11 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - } - - gst_h264_parser_store_nal (h264parse, sps.id, nal_type, nalu); -+ h264parse->state |= GST_H264_PARSE_STATE_GOT_SPS; - break; - case GST_H264_NAL_PPS: -+ h264parse->state &= GST_H264_PARSE_STATE_GOT_SPS; -+ - pres = gst_h264_parser_parse_pps (nalparser, nalu, &pps); - /* arranged for a fallback pps.id, so use that one and only warn */ - if (pres != GST_H264_PARSER_OK) -@@ -576,6 +598,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - } - - gst_h264_parser_store_nal (h264parse, pps.id, nal_type, nalu); -+ h264parse->state |= GST_H264_PARSE_STATE_GOT_PPS; - break; - case GST_H264_NAL_SEI: - gst_h264_parse_process_sei (h264parse, nalu); -@@ -595,6 +618,8 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - case GST_H264_NAL_SLICE_DPB: - case GST_H264_NAL_SLICE_DPC: - case GST_H264_NAL_SLICE_IDR: -+ h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; -+ - /* don't need to parse the whole slice (header) here */ - if (*(nalu->data + nalu->offset + 1) & 0x80) { - /* means first_mb_in_slice == 0 */ -@@ -615,6 +640,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - if (GST_H264_IS_I_SLICE (&slice) || GST_H264_IS_SI_SLICE (&slice)) - h264parse->keyframe |= TRUE; - -+ h264parse->state |= GST_H264_PARSE_STATE_GOT_SLICE; - h264parse->field_pic_flag = slice.field_pic_flag; - } - } -@@ -964,7 +990,8 @@ gst_h264_parse_handle_frame (GstBaseParse * parse, - - if (nalu.type == GST_H264_NAL_SPS || - nalu.type == GST_H264_NAL_PPS || -- (h264parse->have_sps && h264parse->have_pps)) { -+ GST_H264_PARSE_STATE_VALID (h264parse, -+ GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS)) { - gst_h264_parse_process_nal (h264parse, &nalu); - } else { - GST_WARNING_OBJECT (h264parse, -@@ -1761,6 +1788,7 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) - h264parse->push_codec = FALSE; - h264parse->have_sps = FALSE; - h264parse->have_pps = FALSE; -+ h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; - } - } - -diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h -index 4c3fdd4..c9d188b 100644 ---- a/gst/vaapi/gsth264parse.h -+++ b/gst/vaapi/gsth264parse.h -@@ -69,12 +69,15 @@ struct _GstH264Parse - - /* state */ - GstH264NalParser *nalparser; -+ guint state; - guint align; - guint format; - gint current_off; - - GstClockTime last_report; - gboolean push_codec; -+ /* The following variables have a meaning in context of "have -+ * SPS/PPS to push downstream", e.g. to update caps */ - gboolean have_sps; - gboolean have_pps; - --- -1.7.9.5 - diff --git a/patches/videoparsers/0006-h264parse-improve-conditions-for-skipping-NAL-units.patch b/patches/videoparsers/0006-h264parse-improve-conditions-for-skipping-NAL-units.patch deleted file mode 100644 index 912cd0ee7a..0000000000 --- a/patches/videoparsers/0006-h264parse-improve-conditions-for-skipping-NAL-units.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 2b3680eeaff91f611d8c8b0e74efc66b0d874c66 Mon Sep 17 00:00:00 2001 -From: Gwenole Beauchesne -Date: Wed, 25 Jun 2014 13:14:10 +0200 -Subject: [PATCH 6/8] h264parse: improve conditions for skipping NAL units. - -Carefully track cases when skipping broken or invalid NAL units is -necessary. In particular, always allow NAL units to be processed -and let that gst_h264_parse_process_nal() function decide on whether -the current NAL needs to be dropped or not. - -This fixes parsing of streams with SEI NAL buffering_period() message -inserted between SPS and PPS, or SPS-Ext NAL following a traditional -SPS NAL unit, among other cases too. - -Practical examples from the H.264 AVC conformance suite include -alphaconformanceG, CVSE2_Sony_B, CVSE3_Sony_H, CVSEFDFT3_Sony_E -when parsing in stream-format=byte-stream,alignment=au mode. - -https://bugzilla.gnome.org/show_bug.cgi?id=732203 - -Signed-off-by: Gwenole Beauchesne ---- - gst/vaapi/gsth264parse.c | 43 +++++++++++++++++++++++++++++++------------ - 1 file changed, 31 insertions(+), 12 deletions(-) - -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 1542a82..805c55f 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -528,7 +528,7 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) - } - - /* caller guarantees 2 bytes of nal payload */ --static void -+static gboolean - gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - { - guint nal_type; -@@ -540,7 +540,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - /* nothing to do for broken input */ - if (G_UNLIKELY (nalu->size < 2)) { - GST_DEBUG_OBJECT (h264parse, "not processing nal size %u", nalu->size); -- return; -+ return TRUE; - } - - /* we have a peek as well */ -@@ -556,8 +556,10 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - - pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps, TRUE); - /* arranged for a fallback sps.id, so use that one and only warn */ -- if (pres != GST_H264_PARSER_OK) -+ if (pres != GST_H264_PARSER_OK) { - GST_WARNING_OBJECT (h264parse, "failed to parse SPS:"); -+ return FALSE; -+ } - - GST_DEBUG_OBJECT (h264parse, "triggering src caps check"); - h264parse->update_caps = TRUE; -@@ -575,12 +577,18 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - h264parse->state |= GST_H264_PARSE_STATE_GOT_SPS; - break; - case GST_H264_NAL_PPS: -+ /* expected state: got-sps */ - h264parse->state &= GST_H264_PARSE_STATE_GOT_SPS; -+ if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS)) -+ return FALSE; - - pres = gst_h264_parser_parse_pps (nalparser, nalu, &pps); - /* arranged for a fallback pps.id, so use that one and only warn */ -- if (pres != GST_H264_PARSER_OK) -+ if (pres != GST_H264_PARSER_OK) { - GST_WARNING_OBJECT (h264parse, "failed to parse PPS:"); -+ if (pres != GST_H264_PARSER_BROKEN_LINK) -+ return FALSE; -+ } - - /* parameters might have changed, force caps check */ - if (!h264parse->have_pps) { -@@ -601,6 +609,10 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - h264parse->state |= GST_H264_PARSE_STATE_GOT_PPS; - break; - case GST_H264_NAL_SEI: -+ /* expected state: got-sps */ -+ if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS)) -+ return FALSE; -+ - gst_h264_parse_process_sei (h264parse, nalu); - /* mark SEI pos */ - if (h264parse->sei_pos == -1) { -@@ -618,7 +630,11 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - case GST_H264_NAL_SLICE_DPB: - case GST_H264_NAL_SLICE_DPC: - case GST_H264_NAL_SLICE_IDR: -+ /* expected state: got-sps|got-pps (valid picture headers) */ - h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; -+ if (!GST_H264_PARSE_STATE_VALID (h264parse, -+ GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS)) -+ return FALSE; - - /* don't need to parse the whole slice (header) here */ - if (*(nalu->data + nalu->offset + 1) & 0x80) { -@@ -668,7 +684,14 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - } - break; - default: -- gst_h264_parser_parse_nal (nalparser, nalu); -+ /* drop anything before the initial SPS */ -+ if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS)) -+ return FALSE; -+ -+ pres = gst_h264_parser_parse_nal (nalparser, nalu); -+ if (pres != GST_H264_PARSER_OK) -+ return FALSE; -+ break; - } - - /* if AVC output needed, collect properly prefixed nal in adapter, -@@ -681,6 +704,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - nalu->data + nalu->offset, nalu->size); - gst_adapter_push (h264parse->frame_out, buf); - } -+ return TRUE; - } - - /* caller guarantees at least 2 bytes of nal payload for each nal -@@ -988,14 +1012,9 @@ gst_h264_parse_handle_frame (GstBaseParse * parse, - } - } - -- if (nalu.type == GST_H264_NAL_SPS || -- nalu.type == GST_H264_NAL_PPS || -- GST_H264_PARSE_STATE_VALID (h264parse, -- GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS)) { -- gst_h264_parse_process_nal (h264parse, &nalu); -- } else { -+ if (!gst_h264_parse_process_nal (h264parse, &nalu)) { - GST_WARNING_OBJECT (h264parse, -- "no SPS/PPS yet, nal Type: %d %s, Size: %u will be dropped", -+ "broken/invalid nal Type: %d %s, Size: %u will be dropped", - nalu.type, _nal_name (nalu.type), nalu.size); - *skipsize = nalu.size; - goto skip; --- -1.7.9.5 - diff --git a/patches/videoparsers/0007-h264parse-fix-collection-of-access-units-to-preserve.patch b/patches/videoparsers/0007-h264parse-fix-collection-of-access-units-to-preserve.patch deleted file mode 100644 index 7326d27d00..0000000000 --- a/patches/videoparsers/0007-h264parse-fix-collection-of-access-units-to-preserve.patch +++ /dev/null @@ -1,58 +0,0 @@ -From def7c6b2a0fcd08969940349e458248dd0c7b3da Mon Sep 17 00:00:00 2001 -From: Gwenole Beauchesne -Date: Thu, 26 Jun 2014 09:44:26 +0200 -Subject: [PATCH 7/8] h264parse: fix collection of access units to preserve - config headers. - -Always use a GstAdapter when collecting access units (alignment="au") -in either byte-stream or avcC format. This is required to properly -preserve config headers like SPS and PPS when invalid or broken NAL -units are subsequently parsed. - -More precisely, this fixes scenario like: - - -where we used to reset the output frame buffer when an invalid or -broken NAL is parsed, i.e. SPS and PPS NAL units were lost, thus -preventing the next slice unit to be decoded, should this also -represent any valid data. - -https://bugzilla.gnome.org/show_bug.cgi?id=732203 - -Signed-off-by: Gwenole Beauchesne ---- - gst/vaapi/gsth264parse.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 805c55f..413a227 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -393,7 +393,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, - h264parse->format = format; - h264parse->align = align; - -- h264parse->transform = (in_format != h264parse->format); -+ h264parse->transform = in_format != h264parse->format || -+ align == GST_H264_PARSE_ALIGN_AU; - } - - static GstBuffer * -@@ -1054,7 +1055,13 @@ out: - - skip: - GST_DEBUG_OBJECT (h264parse, "skipping %d", *skipsize); -- gst_h264_parse_reset_frame (h264parse); -+ /* If we are collecting access units, we need to preserve the initial -+ * config headers (SPS, PPS et al.) and only reset the frame if another -+ * slice NAL was received. This means that broken pictures are discarded */ -+ if (h264parse->align != GST_H264_PARSE_ALIGN_AU || -+ !(h264parse->state & GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS) || -+ (h264parse->state & GST_H264_PARSE_STATE_GOT_SLICE)) -+ gst_h264_parse_reset_frame (h264parse); - goto out; - - invalid_stream: --- -1.7.9.5 - diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index 46a7f5f9ed..b929daf850 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -3,10 +3,6 @@ videoparsers_patches_base = \ 0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch \ 0002-h264parse-fix-build-with-GStreamer-1.2.patch \ - 0003-h264parse-fix-and-optimize-NAL-collection-function.patch \ 0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ - 0005-h264parse-introduce-new-state-tracking-variables.patch \ - 0006-h264parse-improve-conditions-for-skipping-NAL-units.patch \ - 0007-h264parse-fix-collection-of-access-units-to-preserve.patch \ 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch \ $(NULL) From a3e49d6d13681e205191933fa8fe275e3e6af900 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jul 2014 11:13:33 +0200 Subject: [PATCH 1697/3781] decoder: h264: simplify the DPB output process. Simplify the dpb_output() function to exclusively rely on the frame store buffer to output, since this is now always provided. Besides, also fix cases where split fields would not be displayed. This is a regression from f48b1e0. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 52 ++++++++++++++--------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 7caabfbd89..8297e780eb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -326,7 +326,12 @@ gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture) fs->buffers[0] = gst_vaapi_picture_ref(picture); fs->buffers[1] = NULL; fs->num_buffers = 1; - fs->output_needed = picture->output_needed; + fs->output_needed = 0; + + if (picture->output_flag) { + picture->output_needed = TRUE; + fs->output_needed++; + } return fs; } @@ -390,6 +395,13 @@ gst_vaapi_frame_store_has_frame(GstVaapiFrameStore *fs) return fs->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME; } +static inline gboolean +gst_vaapi_frame_store_is_complete(GstVaapiFrameStore *fs) +{ + return gst_vaapi_frame_store_has_frame(fs) || + GST_VAAPI_PICTURE_IS_ONEFIELD(fs->buffers[0]); +} + static inline gboolean gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs) { @@ -684,19 +696,26 @@ dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index) } static gboolean -dpb_output( - GstVaapiDecoderH264 *decoder, - GstVaapiFrameStore *fs, - GstVaapiPictureH264 *picture -) +dpb_output(GstVaapiDecoderH264 *decoder, GstVaapiFrameStore *fs) { + GstVaapiPictureH264 *picture; + + g_return_val_if_fail(fs != NULL, FALSE); + + if (!gst_vaapi_frame_store_is_complete(fs)) + return TRUE; + + picture = fs->buffers[0]; + g_return_val_if_fail(picture != NULL, FALSE); picture->output_needed = FALSE; - if (--fs->output_needed > 0) - return TRUE; + if (fs->num_buffers > 1) { + picture = fs->buffers[1]; + g_return_val_if_fail(picture != NULL, FALSE); + picture->output_needed = FALSE; + } - if (!GST_VAAPI_PICTURE_IS_COMPLETE(picture)) - return TRUE; + fs->output_needed = 0; return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture)); } @@ -805,7 +824,7 @@ dpb_output_other_views(GstVaapiDecoderH264 *decoder, &found_picture); if (found_index < 0 || found_picture->base.voc >= voc) break; - success = dpb_output(decoder, priv->dpb[found_index], found_picture); + success = dpb_output(decoder, priv->dpb[found_index]); dpb_evict(decoder, found_picture, found_index); if (!success) return FALSE; @@ -828,7 +847,7 @@ dpb_bump(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (picture && picture->base.poc != found_picture->base.poc) dpb_output_other_views(decoder, found_picture, found_picture->base.voc); - success = dpb_output(decoder, priv->dpb[found_index], found_picture); + success = dpb_output(decoder, priv->dpb[found_index]); dpb_evict(decoder, found_picture, found_index); if (priv->max_views == 1) return success; @@ -938,7 +957,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (fs && &fs->buffers[0]->base == picture->base.parent_picture) { if (!gst_vaapi_frame_store_add(fs, picture)) return FALSE; - return dpb_output(decoder, fs, picture); + return dpb_output(decoder, fs); } } @@ -949,11 +968,6 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) gst_vaapi_frame_store_replace(&priv->prev_frames[picture->base.voc], fs); gst_vaapi_frame_store_unref(fs); - if (picture->output_flag) { - picture->output_needed = TRUE; - fs->output_needed++; - } - if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) { if (!gst_vaapi_frame_store_split_fields(fs)) return FALSE; @@ -981,7 +995,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (!StoreInterViewOnlyRefFlag) { if (dpb_find_lowest_poc(decoder, picture, &found_picture) < 0 || found_picture->base.poc > picture->base.poc) - return dpb_output(decoder, fs, picture); + return dpb_output(decoder, fs); } if (!dpb_bump(decoder, picture)) return FALSE; From b5f1bdd59af69ce7eac569df8f7d474c4f8060bd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jul 2014 13:48:48 +0200 Subject: [PATCH 1698/3781] decoder: h264: detect incorrectly paired fields in frames. When a DPB flush is required, e.g. at a natural and of stream or issued explicitly through an IDR, try to detect any frame left in the DPB that is interlaced but does not contain two decoded fields. In that case, mark the picture as having a single field only. This avoids a hang while decoding tv_cut.mkv. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 8297e780eb..6b57fa6ac8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -894,6 +894,20 @@ dpb_clear(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) static void dpb_flush(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { + GstVaapiDecoderH264Private * const priv = &decoder->priv; + guint i; + + /* Detect broken frames and mark them as having a single field if + needed */ + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + if (!fs->output_needed || gst_vaapi_frame_store_is_complete(fs)) + continue; + GST_VAAPI_PICTURE_FLAG_SET(fs->buffers[0], + GST_VAAPI_PICTURE_FLAG_ONEFIELD); + } + + /* Output any frame remaining in DPB */ while (dpb_bump(decoder, picture)) ; dpb_clear(decoder, picture); From 65f897df6afc15095ef49d874cc1fe0f8e3e277f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jul 2014 18:01:09 +0200 Subject: [PATCH 1699/3781] build: fix for GStreamer 1.0.x. --- ...64parse-fix-build-with-GStreamer-1.2.patch | 26 ---------- ...uild-with-older-GStreamer-1.x-stacks.patch | 48 +++++++++++++++++++ patches/videoparsers/series.frag | 2 +- 3 files changed, 49 insertions(+), 27 deletions(-) delete mode 100644 patches/videoparsers/0002-h264parse-fix-build-with-GStreamer-1.2.patch create mode 100644 patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch diff --git a/patches/videoparsers/0002-h264parse-fix-build-with-GStreamer-1.2.patch b/patches/videoparsers/0002-h264parse-fix-build-with-GStreamer-1.2.patch deleted file mode 100644 index 29f979ed6f..0000000000 --- a/patches/videoparsers/0002-h264parse-fix-build-with-GStreamer-1.2.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 4a209977a61d156433dddbf21bddc0b1e89098e1 Mon Sep 17 00:00:00 2001 -From: Gwenole Beauchesne -Date: Mon, 28 Apr 2014 17:17:04 +0200 -Subject: [PATCH 2/3] h264parse: fix build with GStreamer 1.2. - ---- - gst/vaapi/gsth264parse.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 4246b6e..7c970ee 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -148,7 +148,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) - { - h264parse->frame_out = gst_adapter_new (); - gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h264parse), FALSE); -+#if GST_CHECK_VERSION(1,3,0) - GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h264parse)); -+#endif - } - - --- -1.7.9.5 - diff --git a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch new file mode 100644 index 0000000000..02f17bf1e3 --- /dev/null +++ b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch @@ -0,0 +1,48 @@ +From 92908c46e7dd90063a613742f285e9c494c90d6f Mon Sep 17 00:00:00 2001 +From: Gwenole Beauchesne +Date: Mon, 28 Apr 2014 17:17:04 +0200 +Subject: [PATCH 2/3] h264parse: fix build with older GStreamer 1.x stacks. + +--- + gst/vaapi/gsth264parse.c | 4 +++- + gst/vaapi/gsth264parse.h | 1 + + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index 678c7f7..37ce228 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -27,7 +27,7 @@ + #endif + + #include "gstvaapiparse.h" +-#include ++#include + #include + #include + #include "gsth264parse.h" +@@ -148,7 +148,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) + { + h264parse->frame_out = gst_adapter_new (); + gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h264parse), FALSE); ++#if GST_CHECK_VERSION(1,3,0) + GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h264parse)); ++#endif + } + + +diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h +index 4c3fdd4..3db8f21 100644 +--- a/gst/vaapi/gsth264parse.h ++++ b/gst/vaapi/gsth264parse.h +@@ -27,6 +27,7 @@ + + #include + #include ++#include + #include + + G_BEGIN_DECLS +-- +1.7.9.5 + diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index b929daf850..f9aac326de 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -2,7 +2,7 @@ videoparsers_patches_base = \ 0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch \ - 0002-h264parse-fix-build-with-GStreamer-1.2.patch \ + 0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch \ 0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch \ $(NULL) From 700fd242cc46b4189359687136b89eeef612f9ff Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jul 2014 17:17:00 +0200 Subject: [PATCH 1700/3781] build: fix for GStreamer 0.10. --- configure.ac | 8 ++++++++ gst/vaapi/gstvaapidecode.c | 2 ++ 2 files changed, 10 insertions(+) diff --git a/configure.ac b/configure.ac index e383de44de..7bba4ba796 100644 --- a/configure.ac +++ b/configure.ac @@ -254,6 +254,14 @@ if test "$USE_GST_API_1_2p" = "yes"; then fi AC_SUBST([GST_PKG_VERSION]) +dnl Validate certain features +if test "$USE_GST_API_0_10" = "yes"; then + if test "$enable_builtin_videoparsers" = "yes"; then + AC_MSG_WARN([disabled built-in videoparsers (unsupported)]) + enable_builtin_videoparsers="no" + fi +fi + dnl GStreamer Core PKG_CHECK_MODULES([GST], [gstreamer-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 49df98422d..0ec280da40 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -129,6 +129,7 @@ gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps) return TRUE; } +#if GST_CHECK_VERSION(1,1,0) static void gst_vaapidecode_video_info_change_format(GstVideoInfo *info, GstVideoFormat format, guint width, guint height) @@ -145,6 +146,7 @@ gst_vaapidecode_video_info_change_format(GstVideoInfo *info, info->fps_n = vi.fps_n; info->fps_d = vi.fps_d; } +#endif static gboolean gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, From 1175ecb4127a77bd3a6c1c6190bcbac10cab14dd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jul 2014 19:42:02 +0200 Subject: [PATCH 1701/3781] build: mention that support for GStreamer 0.10 is deprecated. --- README | 2 +- configure.ac | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README b/README index 69c841358b..bb5b6d38b8 100644 --- a/README +++ b/README @@ -64,7 +64,7 @@ Requirements Software requirements - * GStreamer 0.10.x: + * GStreamer 0.10.x [DEPRECATED]: libglib2.0-dev (>= 2.28) libgstreamer0.10-dev (>= 0.10.36) or with GstBaseSink::query() diff --git a/configure.ac b/configure.ac index 7bba4ba796..3e36f0f4fa 100644 --- a/configure.ac +++ b/configure.ac @@ -256,6 +256,7 @@ AC_SUBST([GST_PKG_VERSION]) dnl Validate certain features if test "$USE_GST_API_0_10" = "yes"; then + AC_MSG_WARN([support for GStreamer 0.10 is deprecated, and will be removed]) if test "$enable_builtin_videoparsers" = "yes"; then AC_MSG_WARN([disabled built-in videoparsers (unsupported)]) enable_builtin_videoparsers="no" From 9a3e4f9d3e82d9454f6a6aad76a756514b3f0916 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jul 2014 22:21:39 +0200 Subject: [PATCH 1702/3781] NEWS: updates. --- NEWS | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 8ffad08387..ae45bc7e99 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,24 @@ -gst-vaapi NEWS -- summary of changes. 2014-01-23 +gst-vaapi NEWS -- summary of changes. 2014-07-DD Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora +Version 0.5.9 - DD.Jul.2014 +* Add VP8 decoder (+Halley Zhao) +* Add H.264 MVC decoder and encoder (+Sreerenj Balachandran, Xiaowei Li) +* Improvements to H.264 decoder + + Add support for grayscale encoded clips + + Add minor optimizations to the parsing process + + Make support for interlaced streams more robust [#701340] + + Fix multiple slices decoding with varying slice types [#724518] + + Fix parsing of multiple SEI messages in single NAL units (Aurelien Zanelli) +* Improvements to plugin elements + + Add support for crop regions in VPP mode [#720730] + + Fix support for headless pipelines, e.g. vaapisink display="drm" mode + + Fix creation of output surface pool for vaapipostproc (Simon Farnsworth) + + Fix vaapipostproc "deinterlace-mode" semantics (Simon Farnsworth) [#726361] + + Fix memory leak in vaapidecode ! {glimagesink,cluttersink} (Matthew Waters) + Version 0.5.8 - 23.Jan.2014 * Add H.264 video encoding (+Feng Yuan) * Add MPEG-2 video encoding (+Guangxin Xu) From 5fe46af4d3ff177f30604d35c82b347df726c086 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jul 2014 22:34:35 +0200 Subject: [PATCH 1703/3781] README: updates. Drop references to deprecated plugins (vaapiupload, vaapidownload), mention that support for GStreamer 0.10 is deprecated, make overview more descriptive in certain aspects. --- README | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/README b/README index bb5b6d38b8..beb9a7e6dd 100644 --- a/README +++ b/README @@ -20,34 +20,32 @@ Overview gstreamer-vaapi consists in a collection of VA-API based plugins for GStreamer and helper libraries. - * `vaapidecode' is used to decode JPEG, MPEG-2, MPEG-4, H.264, VC-1, - WMV3 videos to video/x-vaapi-surfaces surfaces, depending on the - underlying HW capabilities. + * `vaapidecode' is used to decode JPEG, MPEG-2, MPEG-4:2, H.264 AVC, + H.264 MVC, VP8, VC-1, WMV3 videos to VA surfaces, depending on the + underlying hardware capabilities. This plugin is also able to + implicitly download the decoded surface to raw YUV buffers. - * `vaapiencode_' is used to encode into MPEG-2, H.264 videos, - depending on the actual value of (mpeg2, h264, etc.). By - default, raw format bitstreams are generated, so the result may be - piped to an actual muxer like qtmux for MP4 containers. + * `vaapiencode_' is used to encode into MPEG-2, H.264 AVC, + H.264 MVC videos, depending on the actual value of (mpeg2, + h264, etc.). By default, raw format bitstreams are generated, so + the result may be piped to a muxer. e.g. qtmux for MP4 containers. - * `vaapiupload' is used to convert from video/x-raw-yuv pixels to - video/x-vaapi-surface surfaces. + * `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. - * `vaapidownload' is used to convert from video/x-vaapi-surface - surfaces to video/x-raw-yuv pixels. - - * `vaapipostproc' is used to postprocess video/x-vaapi-surface - surfaces, for e.g. deinterlacing, denoising and sharpening. - - * `vaapisink' is used to display video/x-vaapi-surface surfaces to - screen. + * `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. Features -------- - * VA-API support from 0.29 to 0.34 - * JPEG, MPEG-2, MPEG-4, H.264 and VC-1 ad-hoc decoders - * MPEG-2, H.264 ad-hoc encoders + * VA-API support from 0.29 to 0.35 + * JPEG, MPEG-2, MPEG-4, H.264 AVC, H.264 MVC, VP8 and VC-1 ad-hoc decoders + * MPEG-2, H.264 AVC and H.264 MVC ad-hoc encoders * OpenGL rendering through VA/GLX or GLX texture-from-pixmap + FBO * Support for the Wayland display server * Support for headless decode pipelines with VA/DRM @@ -72,7 +70,10 @@ Software requirements libgstreamer-plugins-bad0.10-dev (>= 0.10.22.1) or with GstVideoContext, GstSurfaceBuffer, codecparsers - * GStreamer 1.0.x (including GStreamer 1.2, 1.3): + Note: support for GStreamer 0.10 APIs is deprecated and will be + removed in a future release. + + * GStreamer 1.0.x (up to including GStreamer 1.4): libglib2.0-dev (>= 2.28) libgstreamer1.0-dev (>= 1.0.0) libgstreamer-plugins-base1.0-dev (>= 1.0.0) From 04b82421e5ed249bccde218b71c27572ae95b829 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 3 Jul 2014 22:44:40 +0200 Subject: [PATCH 1704/3781] AUTHORS: updates. --- AUTHORS | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/AUTHORS b/AUTHORS index 96d5fc7955..81068dcac7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -7,8 +7,25 @@ This project is maintained by Intel Corporation. Contributors (sorted by first name): +Cong Zhong +Emilio Lopez Feng Yuan +Guangxin Xu +Haihao Xiang Holger Kaelberer +Javier Jardon +Junfeng Xu +Kristian Hogsberg +Lionel Landwerlin +Matthew Waters +Matthieu Bouron Nicolas Dufresne +Philip Lorenz +Robert Bradford +Ross Burton +Simon Farnsworth Sreerenj Balachandran Thibault Saunier +Victor Manuel Jaquez Leal +Xiaowei Li +Yan Yin From 4d2de696a99201d53371fbe3c0dcb51d33404a9a Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Fri, 27 Jun 2014 11:57:11 +0100 Subject: [PATCH 1705/3781] vaapipostproc: don't let tmp_rect go out of scope. A compiler change showed me that tmp_rect went out of scope before it was used. Move it to the beginning of the function instead. https://bugzilla.gnome.org/show_bug.cgi?id=726363 Signed-off-by: Simon Farnsworth [added guards for GStreamer 0.10 builds] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipostproc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index aa0cb9893c..e692f54a34 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -448,6 +448,9 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, guint flags, deint_flags; gboolean tff, deint, deint_refs, deint_changed; GstVaapiRectangle *crop_rect = NULL; +#if GST_CHECK_VERSION(1,0,0) + GstVaapiRectangle tmp_rect; +#endif /* Validate filters */ if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) && @@ -493,7 +496,6 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, GstVideoCropMeta * const crop_meta = gst_buffer_get_video_crop_meta(inbuf); if (crop_meta) { - GstVaapiRectangle tmp_rect; crop_rect = &tmp_rect; crop_rect->x = crop_meta->x; crop_rect->y = crop_meta->y; From 334a0ca8bd20181bcb66ce910c36a54886f99d56 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Fri, 13 Jun 2014 21:45:04 +0100 Subject: [PATCH 1706/3781] vaapidecode: make decoder work with playbin When playbin/decodebin builds the pipeline, it puts decoders and sinks into different bins and forwards the queries from bins to bins. So in the initials steps the pipeline is built iteratively by playbin and looks like this : [filesrc] [filesrc] -> [typefind] [filesrc] -> [typefind] -> [demuxer] [filesrc] -> [typefind] -> [demuxer] -> [decoder] At this point the decoder is asked for its SRC caps and it will make a choice based on what gst_pad_peer_query_caps() returns. The problem is that the caps returns at that point includes caps features like ANY, essentially because playbin can plug in additional elements like videoscale, videoconv or deinterlace. This patch adds a another call to gst_vaapi_find_preferred_caps_feature() when the decoder decides its allocation, to make sure we asks the downstream elements when the entire pipeline has been built. https://bugzilla.gnome.org/show_bug.cgi?id=731645 --- gst/vaapi/gstvaapidecode.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 0ec280da40..1d97c62537 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -514,6 +514,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gboolean has_video_meta = FALSE; GstVideoCodecState *state; #if GST_CHECK_VERSION(1,1,0) && USE_GLX + gboolean has_texture_upload_meta = FALSE; GstCapsFeatures *features, *features2; #endif @@ -534,10 +535,22 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) features = gst_caps_get_features(state->caps, 0); features2 = gst_caps_features_new(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); + has_texture_upload_meta = + gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec), + GST_VIDEO_FORMAT_ENCODED) == + GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META; + /* Update src caps if feature is not handled downstream */ if (!decode->has_texture_upload_meta && gst_caps_features_is_equal(features, features2)) gst_vaapidecode_update_src_caps (decode, state); + else if (has_texture_upload_meta && + !gst_caps_features_is_equal(features, features2)) { + gst_video_info_set_format(&state->info, GST_VIDEO_FORMAT_RGBA, + state->info.width, + state->info.height); + gst_vaapidecode_update_src_caps(decode, state); + } gst_caps_features_free(features2); #endif From 502952d080f8608cca54cae7f5497cb39354da4a Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 21 Jan 2014 15:43:57 +0200 Subject: [PATCH 1707/3781] GstVaapiObject: initialize the derived object data with init() hook. Call the subclass .init() function in gst_vaapi_object_new(), if needed. The default behaviour is to zero initialize the subclass object data, then the .init() function can be used to initialize fields to non-default values, e.g. VA object ids to VA_INVALID_ID. Also fix the gst_vaapi_object_new() description, which was merely copied from GstVaapiMiniObject. https://bugzilla.gnome.org/show_bug.cgi?id=722757 [changed to always zero initialize the subclass] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiobject.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 20b2fe5ebe..5069dbfca3 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -64,11 +64,12 @@ gst_vaapi_object_class_init(GstVaapiObjectClass *klass, guint size) /** * gst_vaapi_object_new: - * @object_class: The object class + * @klass: The object class + * @display: The #GstVaapiDisplay * - * Creates a new #GstVaapiObject. If @object_class is NULL, then the - * size of the allocated object is the same as sizeof(GstVaapiObject). - * If @object_class is not NULL, typically when a sub-class is implemented, + * Creates a new #GstVaapiObject. If @klass is NULL, then the size of + * the allocated object is the same as sizeof(GstVaapiObject). + * If @klass is not NULL, typically when a sub-class is implemented, * that pointer shall reference a statically allocated descriptor. * * This function zero-initializes the derived object data. Also note @@ -97,6 +98,9 @@ gst_vaapi_object_new(const GstVaapiObjectClass *klass, GstVaapiDisplay *display) sub_size = object_class->size - sizeof(*object); if (sub_size > 0) memset(((guchar *)object) + sizeof(*object), 0, sub_size); + + if (klass && klass->init) + klass->init (object); return object; } From 99bf1b1f9874f09a5c93f125f8f9a28faa2025a3 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 22 Jan 2014 08:20:59 +0200 Subject: [PATCH 1708/3781] GstVaapiObject: make gst_vaapi_object_new() more robust. Forbid GstVaapiObject to be created without an associated klass spec. It is mandatory that the subclass implements an adequate .finalize() hook, so it shall provide a valid GstVaapiObjectClass. https://bugzilla.gnome.org/show_bug.cgi?id=722757 [made non-NULL klass argument to gst_vaapi_object_new() a requirement] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiobject.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 5069dbfca3..0d8856aa4c 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -67,10 +67,8 @@ gst_vaapi_object_class_init(GstVaapiObjectClass *klass, guint size) * @klass: The object class * @display: The #GstVaapiDisplay * - * Creates a new #GstVaapiObject. If @klass is NULL, then the size of - * the allocated object is the same as sizeof(GstVaapiObject). - * If @klass is not NULL, typically when a sub-class is implemented, - * that pointer shall reference a statically allocated descriptor. + * Creates a new #GstVaapiObject. The @klass argument shall not be + * %NULL, and it must reference a statically allocated descriptor. * * This function zero-initializes the derived object data. Also note * that this is an internal function that shall not be used outside of @@ -86,6 +84,7 @@ gst_vaapi_object_new(const GstVaapiObjectClass *klass, GstVaapiDisplay *display) GstVaapiObject *object; guint sub_size; + g_return_val_if_fail(klass != NULL, NULL); g_return_val_if_fail(display != NULL, NULL); object = (GstVaapiObject *)gst_vaapi_mini_object_new(object_class); From 22dc8c42514e1d5d3f89d064e52b252f01fce54b Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 4 Jul 2014 15:13:32 +1000 Subject: [PATCH 1709/3781] decoder: mpeg2: respect any input PTS provided for a frame. The timestamp generator in gstvaapidecoder_mpeg2.c always interpolated frame timestamps within a GOP, even when it's been fed input PTS for every frame. That leads to incorrect output timestamps in some situations - for example live playback where input timestamps have been scaled based on arrival time from the network and don't exactly match the framerate. https://bugzilla.gnome.org/show_bug.cgi?id=732719 --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 3f30f0bf73..c3ab7a68a3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -130,7 +130,9 @@ pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn) if (!GST_CLOCK_TIME_IS_VALID(tsg->gop_pts)) tsg->gop_pts = 0; - pts = tsg->gop_pts + pts_get_duration(tsg, tsg->ovl_tsn * 1024 + pic_tsn); + pts = pic_pts; + if (!GST_CLOCK_TIME_IS_VALID (pts)) + pts = tsg->gop_pts + pts_get_duration(tsg, tsg->ovl_tsn * 1024 + pic_tsn); if (!GST_CLOCK_TIME_IS_VALID(tsg->max_pts) || tsg->max_pts < pts) tsg->max_pts = pts; @@ -142,6 +144,7 @@ pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn) tsg->ovl_tsn++; } tsg->lst_tsn = pic_tsn; + return pts; } From 00ca734ebf4ea554588ff067f364ad4d3e383e42 Mon Sep 17 00:00:00 2001 From: Fabrice Bellet Date: Thu, 17 Jul 2014 01:51:36 +0200 Subject: [PATCH 1710/3781] decoder: mpeg4: fix picture decoder return value for skipped frames. The picture decoder should return GST_VAAPI_DECODER_STATUS_DROP_FRAME when a frame should be skipped, so the stream processing is not stalled. https://bugzilla.gnome.org/show_bug.cgi?id=733324 --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index b461877488..4f80f7f9b6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -518,7 +518,7 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) parser_result = gst_mpeg4_parse_video_object_plane(vop_hdr, sprite_trajectory, vol_hdr, buf, buf_size); /* Need to skip this frame if VOP was not coded */ if (GST_MPEG4_PARSER_OK == parser_result && !vop_hdr->coded) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + return GST_VAAPI_DECODER_STATUS_DROP_FRAME; } if (parser_result != GST_MPEG4_PARSER_OK) { From dc6d529830b185b557b86a78268becc61f3d2864 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 22 Jul 2014 18:54:29 +0200 Subject: [PATCH 1711/3781] plugins: allow download capability to vaapidecode element. Fix support for VA surface download capability in vaapidecode element for GStreamer >= 1.2. This is a fix to supporting libva-vdpau-driver, but also the libva-intel-driver while performing hardware accelerated conversions from the native VA surface format (NV12) to the desired output VA image format. For instance, this fixes pipelines involving vaapidecode ! xvimagesink. https://bugzilla.gnome.org/show_bug.cgi?id=733243 --- gst/vaapi/gstvaapidecode.c | 24 ++++++++++++++++++------ gst/vaapi/gstvaapivideomemory.c | 11 ++++++++++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1d97c62537..1e94561acf 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -155,6 +155,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); GstVideoCodecState *state; GstVideoInfo *vi, vis; + GstVideoFormat format, out_format; #if GST_CHECK_VERSION(1,1,0) GstCapsFeatures *features = NULL; GstVaapiCapsFeature feature; @@ -164,17 +165,28 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GST_VIDEO_INFO_FORMAT(&ref_state->info)); #endif - state = gst_video_decoder_set_output_state(vdec, - GST_VIDEO_INFO_FORMAT(&ref_state->info), + format = GST_VIDEO_INFO_FORMAT(&ref_state->info); + + state = gst_video_decoder_set_output_state(vdec, format, ref_state->info.width, ref_state->info.height, (GstVideoCodecState *)ref_state); if (!state) return FALSE; vi = &state->info; - if (GST_VIDEO_INFO_FORMAT(vi) == GST_VIDEO_FORMAT_ENCODED) { + out_format = format; + if (format == GST_VIDEO_FORMAT_ENCODED) { +#if GST_CHECK_VERSION(1,1,0) + out_format = GST_VIDEO_FORMAT_NV12; + if (feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) { + /* XXX: intercept with the preferred output format. + Anyway, I420 is the minimum format that drivers + should support to be useful */ + out_format = GST_VIDEO_FORMAT_I420; + } +#endif gst_video_info_init(&vis); - gst_video_info_set_format(&vis, GST_VIDEO_FORMAT_NV12, + gst_video_info_set_format(&vis, out_format, GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); vi->size = vis.size; } @@ -190,12 +202,12 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); break; default: - if (GST_VIDEO_INFO_FORMAT(vi) == GST_VIDEO_FORMAT_ENCODED) { + if (format == GST_VIDEO_FORMAT_ENCODED) { /* XXX: this is a workaround until auto-plugging is fixed when format=ENCODED + memory:VASurface caps feature are provided. Meanwhile, providing a random format here works but this is a terribly wrong thing per se. */ - gst_vaapidecode_video_info_change_format(&vis, GST_VIDEO_FORMAT_NV12, + gst_vaapidecode_video_info_change_format(&vis, out_format, GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); #if GST_CHECK_VERSION(1,3,0) if (feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index cb953c1a5f..38049b0d15 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -51,6 +51,11 @@ ensure_image(GstVaapiVideoMemory *mem) GST_WARNING("failed to derive image, fallbacking to copy"); mem->use_direct_rendering = FALSE; } + else if (gst_vaapi_surface_get_format(mem->surface) != + GST_VIDEO_INFO_FORMAT(mem->image_info)) { + gst_vaapi_object_replace(&mem->image, NULL); + mem->use_direct_rendering = FALSE; + } } if (!mem->image) { @@ -142,10 +147,14 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, goto error_ensure_image; // Check that we can actually map the surface, or image - if ((flags & GST_MAP_READWRITE) != GST_MAP_WRITE && + if ((flags & GST_MAP_READWRITE) == GST_MAP_WRITE && !mem->use_direct_rendering) goto error_unsupported_map; + // Load VA image from surface + if ((flags & GST_MAP_READ) && !mem->use_direct_rendering) + gst_vaapi_surface_get_image(mem->surface, mem->image); + if (!gst_vaapi_image_map(mem->image)) goto error_map_image; mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR; From dac20cecb4e2c2ebccaf5c75e48999bb8ccbb53e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 23 Jul 2014 10:23:06 +0200 Subject: [PATCH 1712/3781] plugins: expose I420 format for interop with SW elements. Always expose I420 format by default when the VA surface could be mapped for interoperability with non harware accelerated elements. However, the default behaviour remains the auto-plugging of vaapi elements, down to the sink. Side effect: "direct-rendering" mode is also disabled most of the times as plain memcpy() from uncached speculative write combining memory is not going to be efficient enough. --- gst/vaapi/gstvaapidecode.c | 16 ++++------------ gst/vaapi/gstvaapipluginutil.c | 2 +- gst/vaapi/gstvaapivideomemory.c | 2 +- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1e94561acf..848290fc33 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -77,10 +77,10 @@ static const char gst_vaapidecode_sink_caps_str[] = static const char gst_vaapidecode_src_caps_str[] = #if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ";" + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") ";" GST_VIDEO_CAPS_MAKE_WITH_FEATURES( GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA") ";" - GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12 }"); + GST_VIDEO_CAPS_MAKE("{ I420, YV12, NV12 }"); #else GST_VAAPI_SURFACE_CAPS; #endif @@ -176,15 +176,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, vi = &state->info; out_format = format; if (format == GST_VIDEO_FORMAT_ENCODED) { -#if GST_CHECK_VERSION(1,1,0) - out_format = GST_VIDEO_FORMAT_NV12; - if (feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) { - /* XXX: intercept with the preferred output format. - Anyway, I420 is the minimum format that drivers - should support to be useful */ - out_format = GST_VIDEO_FORMAT_I420; - } -#endif + out_format = GST_VIDEO_FORMAT_I420; gst_video_info_init(&vis); gst_video_info_set_format(&vis, out_format, GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); @@ -571,7 +563,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gst_video_info_init(&vi); gst_video_info_from_caps(&vi, caps); if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) - gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12, + gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_I420, GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); g_return_val_if_fail(GST_VAAPI_PLUGIN_BASE_DISPLAY(decode) != NULL, FALSE); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index b53e3596ce..fe84771839 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -521,7 +521,7 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format) goto cleanup; if (format == GST_VIDEO_FORMAT_ENCODED) - format = GST_VIDEO_FORMAT_NV12; + format = GST_VIDEO_FORMAT_I420; vaapi_caps = gst_vaapi_video_format_new_template_caps_with_features (format, diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 38049b0d15..b3f702a52d 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -540,7 +540,7 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, const GstVideoInfo *vip) allocator->image_info = *vip; if (GST_VIDEO_INFO_FORMAT(vip) == GST_VIDEO_FORMAT_ENCODED) - gst_video_info_set_format(&allocator->image_info, GST_VIDEO_FORMAT_NV12, + gst_video_info_set_format(&allocator->image_info, GST_VIDEO_FORMAT_I420, GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); if (allocator->has_direct_rendering) From b07de8a7f986275599db4a0177d659a3e882bcff Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 23 Jul 2014 18:01:21 +0200 Subject: [PATCH 1713/3781] vaapivideomemory: fix association of surface to proxy. Make sure to always update the VA surface pointer whenever the proxy changes. This used to only work when the VA surface is written to, in interop with SW element ("upload" feature), and this now fixes cases when the VA surface is needed for reading, in interop with SW element ("download" feature). --- gst/vaapi/gstvaapivideomemory.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index b3f702a52d..0400fefb95 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -117,10 +117,9 @@ ensure_surface(GstVaapiVideoMemory *mem) return FALSE; gst_vaapi_video_meta_set_surface_proxy(mem->meta, mem->proxy); } - mem->surface = GST_VAAPI_SURFACE_PROXY_SURFACE(mem->proxy); } - g_return_val_if_fail(mem->surface != NULL, FALSE); - return TRUE; + mem->surface = GST_VAAPI_SURFACE_PROXY_SURFACE(mem->proxy); + return mem->surface != NULL; } gboolean From 9cb3acc813320aad072672296b5af168badf82a0 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 3 Jul 2014 18:41:11 +0300 Subject: [PATCH 1714/3781] vaapivideomemory: fix determination of the surface pool format. While creating the vaapi video allocator, make sure the associated surface pool has correct format instead of defaulting to NV12 video format even though there is no direct rendering support. https://bugzilla.gnome.org/show_bug.cgi?id=732691 --- gst/vaapi/gstvaapivideomemory.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 0400fefb95..9c0b5b92b0 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -515,12 +515,12 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, const GstVideoInfo *vip) image = gst_vaapi_surface_derive_image(surface); if (!image) break; - if (GST_VAAPI_IMAGE_FORMAT(image) != GST_VIDEO_INFO_FORMAT(vip)) - break; if (!gst_vaapi_image_map(image)) break; allocator->has_direct_rendering = gst_video_info_update_from_image( &allocator->surface_info, image); + if (GST_VAAPI_IMAGE_FORMAT(image) != GST_VIDEO_INFO_FORMAT(vip)) + allocator->has_direct_rendering = FALSE; gst_vaapi_image_unmap(image); GST_INFO("has direct-rendering for %s surfaces: %s", GST_VIDEO_INFO_FORMAT_STRING(&allocator->surface_info), From 9cad85a93649b1b6da6084b85f807139e84a41a4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 23 Jul 2014 18:54:13 +0200 Subject: [PATCH 1715/3781] vaapivideomemory: add support for raw pixels mappings. Allow raw pixels of the whole frame to be mapped read-only. i.e. in cases where the buffer pool is allocated without VideoMeta API, thus individual planes cannot be mapped. This is initial support for Firefox >= 30. https://bugzilla.gnome.org/show_bug.cgi?id=731886 --- gst/vaapi/gstvaapivideomemory.c | 102 +++++++++++++++++++++++++++----- gst/vaapi/gstvaapivideomemory.h | 7 ++- 2 files changed, 92 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 9c0b5b92b0..ee85eead3c 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -35,6 +35,20 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideomemory); /* --- GstVaapiVideoMemory --- */ /* ------------------------------------------------------------------------ */ +static guchar * +get_image_data(GstVaapiImage *image) +{ + guchar *data; + VAImage va_image; + + data = gst_vaapi_image_get_plane(image, 0); + if (!data || !gst_vaapi_image_get_image(image, &va_image)) + return NULL; + + data -= va_image.offsets[0]; + return data; +} + static GstVaapiImage * new_image(GstVaapiDisplay *display, const GstVideoInfo *vip) { @@ -289,40 +303,98 @@ gst_vaapi_video_memory_reset_surface(GstVaapiVideoMemory *mem) static gpointer gst_vaapi_video_memory_map(GstVaapiVideoMemory *mem, gsize maxsize, guint flags) { - if (mem->map_type && - mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE) - goto error_incompatible_map; + gpointer data; if (mem->map_count == 0) { - gst_vaapi_surface_proxy_replace(&mem->proxy, - gst_vaapi_video_meta_get_surface_proxy(mem->meta)); + switch (flags & GST_MAP_READWRITE) { + case 0: + // No flags set: return a GstVaapiSurfaceProxy + gst_vaapi_surface_proxy_replace(&mem->proxy, + gst_vaapi_video_meta_get_surface_proxy(mem->meta)); + if (!mem->proxy) + goto error_no_surface_proxy; + mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE; + break; + case GST_MAP_READ: + // Only read flag set: return raw pixels + if (!ensure_surface(mem)) + return NULL; + if (!ensure_image(mem)) + goto error_ensure_image; + if (!mem->use_direct_rendering) + gst_vaapi_surface_get_image(mem->surface, mem->image); + if (!gst_vaapi_image_map(mem->image)) + goto error_map_image; + mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR; + break; + default: + goto error_unsupported_map; + } + } + + switch (mem->map_type) { + case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: if (!mem->proxy) goto error_no_surface_proxy; - mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE; + data = mem->proxy; + break; + case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR: + if (!mem->image) + goto error_no_image; + data = get_image_data(mem->image); + break; + default: + goto error_unsupported_map_type; } mem->map_count++; - return mem->proxy; + return data; /* ERRORS */ -error_incompatible_map: - GST_ERROR("failed to map memory to a GstVaapiSurfaceProxy"); +error_unsupported_map: + GST_ERROR("unsupported map flags (0x%x)", flags); + return NULL; +error_unsupported_map_type: + GST_ERROR("unsupported map type (%d)", mem->map_type); return NULL; error_no_surface_proxy: GST_ERROR("failed to extract GstVaapiSurfaceProxy from video meta"); return NULL; +error_no_image: + GST_ERROR("failed to extract raw pixels from mapped VA image"); + return NULL; +error_ensure_image: + { + const GstVideoInfo * const vip = mem->image_info; + GST_ERROR("failed to create %s image of size %ux%u", + GST_VIDEO_INFO_FORMAT_STRING(vip), + GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + return FALSE; + } +error_map_image: + { + GST_ERROR("failed to map image %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS(gst_vaapi_image_get_id(mem->image))); + return FALSE; + } } static void gst_vaapi_video_memory_unmap(GstVaapiVideoMemory *mem) { - if (mem->map_type && - mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE) - goto error_incompatible_map; - - if (--mem->map_count == 0) { - gst_vaapi_surface_proxy_replace(&mem->proxy, NULL); + if (mem->map_count == 1) { + switch (mem->map_type) { + case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: + gst_vaapi_surface_proxy_replace(&mem->proxy, NULL); + break; + case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR: + gst_vaapi_image_unmap(mem->image); + break; + default: + goto error_incompatible_map; + } mem->map_type = 0; } + mem->map_count--; return; /* ERRORS */ diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index c28efb85de..d58501d14a 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -51,15 +51,18 @@ typedef struct _GstVaapiVideoAllocatorClass GstVaapiVideoAllocatorClass; /** * GstVaapiVideoMemoryMapType: * @GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: map with gst_buffer_map() - * as a whole and return a #GstVaapiSurfaceProxy + * and flags = 0x00 to return a #GstVaapiSurfaceProxy * @GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR: map individual plane with * gst_video_frame_map() + * @GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR: map with gst_buffer_map() + * and flags = GST_MAP_READ to return the raw pixels of the whole image * * The set of all #GstVaapiVideoMemory map types. */ typedef enum { GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE = 1, - GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR + GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR, + GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR } GstVaapiVideoMemoryMapType; /** From f2ce28e4b78afc37da0771bda3830eaa02adef85 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 23 Jul 2014 23:49:53 +0200 Subject: [PATCH 1716/3781] vaapivideomemory: minor code clean-ups. Fix error messages introduced in the previous commit for the _map() imaplementation. Also use the new get_image_data() helper function to determine the base pixels data buffer from a GstVaapiImage when updating the video info structure from it. --- gst/vaapi/gstvaapivideomemory.c | 34 +++++++++++---------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index ee85eead3c..98d5004e1d 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -318,9 +318,9 @@ gst_vaapi_video_memory_map(GstVaapiVideoMemory *mem, gsize maxsize, guint flags) case GST_MAP_READ: // Only read flag set: return raw pixels if (!ensure_surface(mem)) - return NULL; + goto error_no_surface; if (!ensure_image(mem)) - goto error_ensure_image; + goto error_no_image; if (!mem->use_direct_rendering) gst_vaapi_surface_get_image(mem->surface, mem->image); if (!gst_vaapi_image_map(mem->image)) @@ -359,23 +359,15 @@ error_unsupported_map_type: error_no_surface_proxy: GST_ERROR("failed to extract GstVaapiSurfaceProxy from video meta"); return NULL; -error_no_image: - GST_ERROR("failed to extract raw pixels from mapped VA image"); +error_no_surface: + GST_ERROR("failed to extract VA surface from video buffer"); + return NULL; +error_no_image: + GST_ERROR("failed to extract VA image from video buffer"); return NULL; -error_ensure_image: - { - const GstVideoInfo * const vip = mem->image_info; - GST_ERROR("failed to create %s image of size %ux%u", - GST_VIDEO_INFO_FORMAT_STRING(vip), - GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); - return FALSE; - } error_map_image: - { - GST_ERROR("failed to map image %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(gst_vaapi_image_get_id(mem->image))); - return FALSE; - } + GST_ERROR("failed to map VA image"); + return NULL; } static void @@ -534,12 +526,8 @@ gst_video_info_update_from_image(GstVideoInfo *vip, GstVaapiImage *image) g_return_val_if_fail(num_planes == GST_VIDEO_INFO_N_PLANES(vip), FALSE); /* Determine the base data pointer */ - data = gst_vaapi_image_get_plane(image, 0); - for (i = 1; i < num_planes; i++) { - const guchar * const plane = gst_vaapi_image_get_plane(image, i); - if (data > plane) - data = plane; - } + data = get_image_data(image); + g_return_val_if_fail(data != NULL, FALSE); data_size = gst_vaapi_image_get_data_size(image); /* Check that we don't have disjoint planes */ From c3643b42a44f57b76af95596383e3ff2f88c24be Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 24 Jul 2014 00:14:04 +0200 Subject: [PATCH 1717/3781] vaapivideomemory: forbid R/W mappings if non direct-rendering mode. Disable read-write mappings if "direct-rendering" is not supported. Since the ordering of read and write operations is not specified, this would require to always download the VA surface on _map(), then commit the temporary VA image back to the VA surface on _unmap(). Some SW decoding plug-in elements still use R/W mappings though. https://bugzilla.gnome.org/show_bug.cgi?id=733242 --- gst/vaapi/gstvaapivideomemory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 98d5004e1d..1788125573 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -160,7 +160,7 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, goto error_ensure_image; // Check that we can actually map the surface, or image - if ((flags & GST_MAP_READWRITE) == GST_MAP_WRITE && + if ((flags & GST_MAP_READWRITE) == GST_MAP_READWRITE && !mem->use_direct_rendering) goto error_unsupported_map; From 3a762284a26b8aa91226e27459176876655330ae Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 24 Jul 2014 06:46:22 +0200 Subject: [PATCH 1718/3781] vaapivideomemory: use an image pool to cache objects. Use an image pool to hold VA images to be used for downloads/uploads of contents for the associated surface. This is an optmization for size. So, instead of creating as many VA images as there are buffers (then VA surfaces) allocated, we only maintain a minimal set of live VA images, thus preserving memory resources. --- gst/vaapi/gstvaapivideomemory.c | 46 +++++++++++++++++++++++++++------ gst/vaapi/gstvaapivideomemory.h | 3 ++- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 1788125573..dfbb9c5619 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -21,6 +21,8 @@ */ #include "gst/vaapi/sysdeps.h" +#include +#include #include "gstvaapivideomemory.h" GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideomemory); @@ -35,6 +37,9 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideomemory); /* --- GstVaapiVideoMemory --- */ /* ------------------------------------------------------------------------ */ +static void +gst_vaapi_video_memory_reset_image(GstVaapiVideoMemory *mem); + static guchar * get_image_data(GstVaapiImage *image) { @@ -73,10 +78,10 @@ ensure_image(GstVaapiVideoMemory *mem) } if (!mem->image) { - GstVaapiDisplay * const display = - gst_vaapi_video_meta_get_display(mem->meta); + GstVaapiVideoAllocator * const allocator = + GST_VAAPI_VIDEO_ALLOCATOR_CAST(GST_MEMORY_CAST(mem)->allocator); - mem->image = new_image(display, mem->image_info); + mem->image = gst_vaapi_video_pool_get_object(allocator->image_pool); if (!mem->image) return FALSE; } @@ -283,20 +288,33 @@ static void gst_vaapi_video_memory_free(GstVaapiVideoMemory *mem) { mem->surface = NULL; + gst_vaapi_video_memory_reset_image(mem); gst_vaapi_surface_proxy_replace(&mem->proxy, NULL); - gst_vaapi_object_replace(&mem->image, NULL); gst_vaapi_video_meta_unref(mem->meta); gst_object_unref(GST_MEMORY_CAST(mem)->allocator); g_slice_free(GstVaapiVideoMemory, mem); } +void +gst_vaapi_video_memory_reset_image(GstVaapiVideoMemory *mem) +{ + GstVaapiVideoAllocator * const allocator = + GST_VAAPI_VIDEO_ALLOCATOR_CAST(GST_MEMORY_CAST(mem)->allocator); + + if (mem->use_direct_rendering) + gst_vaapi_object_replace(&mem->image, NULL); + else if (mem->image) { + gst_vaapi_video_pool_put_object(allocator->image_pool, mem->image); + mem->image = NULL; + } +} + void gst_vaapi_video_memory_reset_surface(GstVaapiVideoMemory *mem) { mem->surface = NULL; + gst_vaapi_video_memory_reset_image(mem); gst_vaapi_surface_proxy_replace(&mem->proxy, NULL); - if (mem->use_direct_rendering) - gst_vaapi_object_replace(&mem->image, NULL); gst_vaapi_video_meta_set_surface_proxy(mem->meta, NULL); } @@ -474,6 +492,7 @@ gst_vaapi_video_allocator_finalize(GObject *object) GST_VAAPI_VIDEO_ALLOCATOR_CAST(object); gst_vaapi_video_pool_replace(&allocator->surface_pool, NULL); + gst_vaapi_video_pool_replace(&allocator->image_pool, NULL); G_OBJECT_CLASS(gst_vaapi_video_allocator_parent_class)->finalize(object); } @@ -595,7 +614,7 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, const GstVideoInfo *vip) allocator->surface_pool = gst_vaapi_surface_pool_new(display, &allocator->surface_info); if (!allocator->surface_pool) - goto error_create_pool; + goto error_create_surface_pool; allocator->image_info = *vip; if (GST_VIDEO_INFO_FORMAT(vip) == GST_VIDEO_FORMAT_ENCODED) @@ -616,13 +635,24 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, const GstVideoInfo *vip) } while (0); gst_vaapi_object_unref(image); } + + allocator->image_pool = gst_vaapi_image_pool_new(display, + &allocator->image_info); + if (!allocator->image_pool) + goto error_create_image_pool; return GST_ALLOCATOR_CAST(allocator); /* ERRORS */ -error_create_pool: +error_create_surface_pool: { GST_ERROR("failed to allocate VA surface pool"); gst_object_unref(allocator); return NULL; } +error_create_image_pool: + { + GST_ERROR("failed to allocate VA image pool"); + gst_object_unref(allocator); + return NULL; + } } diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index d58501d14a..587d44314a 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include "gstvaapivideometa.h" G_BEGIN_DECLS @@ -137,6 +137,7 @@ struct _GstVaapiVideoAllocator { GstVideoInfo surface_info; GstVaapiVideoPool *surface_pool; GstVideoInfo image_info; + GstVaapiVideoPool *image_pool; gboolean has_direct_rendering; }; From e0e869f536a888191225249b3ade5979516c29d8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 24 Jul 2014 11:58:29 +0200 Subject: [PATCH 1719/3781] vaapivideomemory: disallow memory shares across buffers, use a copy. Forbid shares of GstMemory instances, and rather make copy of it. This effectively copies the GstMemory structure and enclosed metadata, but this does not copy the VA surface contents itself. It should though. This fixes preroll and makes sure to not download garbage for the first frame when a SW rendering sink is used. --- gst/vaapi/gstvaapivideomemory.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index dfbb9c5619..5033b934a3 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -269,8 +269,9 @@ gst_vaapi_video_memory_new(GstAllocator *base_allocator, return NULL; vip = &allocator->image_info; - gst_memory_init(&mem->parent_instance, 0, gst_object_ref(allocator), NULL, - GST_VIDEO_INFO_SIZE(vip), 0, 0, GST_VIDEO_INFO_SIZE(vip)); + gst_memory_init(&mem->parent_instance, GST_MEMORY_FLAG_NO_SHARE, + gst_object_ref(allocator), NULL, GST_VIDEO_INFO_SIZE(vip), 0, + 0, GST_VIDEO_INFO_SIZE(vip)); mem->proxy = NULL; mem->surface_info = &allocator->surface_info; @@ -417,13 +418,22 @@ static GstVaapiVideoMemory * gst_vaapi_video_memory_copy(GstVaapiVideoMemory *mem, gssize offset, gssize size) { + GstVaapiVideoMeta *meta; GstMemory *out_mem; + gsize maxsize; - if (offset != 0 || size != -1) + /* XXX: this implements a soft-copy, i.e. underlying VA surfaces + are not copied */ + (void)gst_memory_get_sizes(GST_MEMORY_CAST(mem), NULL, &maxsize); + if (offset != 0 || (size != -1 && (gsize)size != maxsize)) goto error_unsupported; - out_mem = gst_vaapi_video_memory_new(mem->parent_instance.allocator, - mem->meta); + meta = gst_vaapi_video_meta_copy(mem->meta); + if (!meta) + goto error_allocate_memory; + + out_mem = gst_vaapi_video_memory_new(GST_MEMORY_CAST(mem)->allocator, meta); + gst_vaapi_video_meta_unref(meta); if (!out_mem) goto error_allocate_memory; return GST_VAAPI_VIDEO_MEMORY_CAST(out_mem); From 1d1be0ae76d92babf8ffd9fd8d1d2bff48996ddd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Jul 2014 15:44:58 +0200 Subject: [PATCH 1720/3781] vaapivideomemory: always prefer native VA surface formats. Make sure to always prefer native internal formats for the VA surfaces that get allocated. Also disable "direct-rendering" mode in this case. This is needed so that to make sure that anything that gets out of the decoder, or anything that gets into the encoder, is in native format for the hardware, and thus the driver doesn't need to perform implicit conversions in there. Interop with SW elements is still available with fast implementations of VA imaging APIs. --- gst/vaapi/gstvaapivideomemory.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 5033b934a3..c6247e248f 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -33,6 +33,9 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideomemory); gst_video_format_to_string(GST_VIDEO_INFO_FORMAT(vip)) #endif +/* Defined if native VA surface formats are preferred over direct rendering */ +#define USE_NATIVE_FORMATS 1 + /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoMemory --- */ /* ------------------------------------------------------------------------ */ @@ -96,7 +99,8 @@ new_surface(GstVaapiDisplay *display, const GstVideoInfo *vip) GstVaapiChromaType chroma_type; /* Try with explicit format first */ - if (GST_VIDEO_INFO_FORMAT(vip) != GST_VIDEO_FORMAT_ENCODED) { + if (!USE_NATIVE_FORMATS && + GST_VIDEO_INFO_FORMAT(vip) != GST_VIDEO_FORMAT_ENCODED) { surface = gst_vaapi_surface_new_with_format(display, GST_VIDEO_INFO_FORMAT(vip), GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); @@ -610,6 +614,8 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, const GstVideoInfo *vip) &allocator->surface_info, image); if (GST_VAAPI_IMAGE_FORMAT(image) != GST_VIDEO_INFO_FORMAT(vip)) allocator->has_direct_rendering = FALSE; + if (USE_NATIVE_FORMATS) + allocator->has_direct_rendering = FALSE; gst_vaapi_image_unmap(image); GST_INFO("has direct-rendering for %s surfaces: %s", GST_VIDEO_INFO_FORMAT_STRING(&allocator->surface_info), From cafb25c4d1e7f6203a8756227eb4e24f524d3959 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Jul 2014 15:52:06 +0200 Subject: [PATCH 1721/3781] vaapidecode: add support for VideoAlignment bufferpool option. Always add VideoAlignment bufferpool option if the downstream element expects its own pool to be used but does not offer it through a proper propose_allocation() implementation for instance, and that the ALLOCATION query does not expose the availability of the Video Meta API. This fixes propagation of video buffer stride information to Firefox. --- gst/vaapi/gstvaapidecode.c | 12 ++++++++++++ gst/vaapi/gstvaapivideobufferpool.c | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 848290fc33..b5f7a40dc9 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -516,6 +516,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) guint size, min, max; gboolean need_pool, update_pool; gboolean has_video_meta = FALSE; + gboolean has_video_alignment = FALSE; GstVideoCodecState *state; #if GST_CHECK_VERSION(1,1,0) && USE_GLX gboolean has_texture_upload_meta = FALSE; @@ -572,6 +573,11 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gst_query_parse_nth_allocation_pool(query, 0, &pool, &size, &min, &max); size = MAX(size, vi.size); update_pool = TRUE; + + /* Check whether downstream element proposed a bufferpool but did + not provide a correct propose_allocation() implementation */ + has_video_alignment = gst_buffer_pool_has_option(pool, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); } else { pool = NULL; @@ -609,6 +615,12 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) #endif gst_buffer_pool_set_config(pool, config); } + else if (has_video_alignment) { + config = gst_buffer_pool_get_config(pool); + gst_buffer_pool_config_add_option(config, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + gst_buffer_pool_set_config(pool, config); + } if (update_pool) gst_query_set_nth_allocation_pool(query, 0, pool, size, min, max); diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 894ba6beae..fe5c2a3b38 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -47,6 +47,7 @@ struct _GstVaapiVideoBufferPoolPrivate { GstAllocator *allocator; GstVaapiDisplay *display; guint has_video_meta : 1; + guint has_video_alignment : 1; guint has_texture_upload_meta : 1; }; @@ -101,6 +102,19 @@ gst_vaapi_video_buffer_pool_get_property(GObject *object, guint prop_id, } } +static void +fill_video_alignment(GstVaapiVideoBufferPool *pool, GstVideoAlignment *align) +{ + GstVideoInfo * const vip = + &GST_VAAPI_VIDEO_ALLOCATOR_CAST(pool->priv->allocator)->image_info; + guint i; + + gst_video_alignment_reset(align); + for (i = 0; i < GST_VIDEO_INFO_N_PLANES(vip); i++) + align->stride_align[i] = + (1U << g_bit_nth_lsf(GST_VIDEO_INFO_PLANE_STRIDE(vip, i), 0)) - 1; +} + static const gchar ** gst_vaapi_video_buffer_pool_get_options(GstBufferPool *pool) { @@ -108,6 +122,7 @@ gst_vaapi_video_buffer_pool_get_options(GstBufferPool *pool) GST_BUFFER_POOL_OPTION_VIDEO_META, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT, NULL, }; return g_options; @@ -122,6 +137,7 @@ gst_vaapi_video_buffer_pool_set_config(GstBufferPool *pool, GstCaps *caps = NULL; GstVideoInfo * const cur_vip = &priv->video_info[priv->video_info_index]; GstVideoInfo * const new_vip = &priv->video_info[!priv->video_info_index]; + GstVideoAlignment align; GstAllocator *allocator; gboolean changed_caps; @@ -152,6 +168,13 @@ gst_vaapi_video_buffer_pool_set_config(GstBufferPool *pool, priv->has_video_meta = gst_buffer_pool_config_has_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); + priv->has_video_alignment = gst_buffer_pool_config_has_option(config, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + if (priv->has_video_alignment) { + fill_video_alignment(GST_VAAPI_VIDEO_BUFFER_POOL(pool), &align); + gst_buffer_pool_config_set_video_alignment(config, &align); + } + priv->has_texture_upload_meta = gst_buffer_pool_config_has_option(config, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); From 39ab75becd530d5879d2c985c8ec1f9010ad973d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Jul 2014 10:55:53 +0200 Subject: [PATCH 1722/3781] display: fix comparison of X11 display names. Make sure to not only compare display host names, but also the actual display number. The screen number does not need to be checked at this time. --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 84 +++++++++++++++--------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index ba9ea26417..9d4dfd0553 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -48,6 +48,58 @@ static const guint g_display_types = (1U << GST_VAAPI_DISPLAY_TYPE_X11) | (1U << GST_VAAPI_DISPLAY_TYPE_GLX); +static gboolean +parse_display_name (const gchar * name, guint * len_ptr, guint * id_ptr, + guint * screen_ptr) +{ + gulong len, id = 0, screen = 0; + gchar *end; + + end = strchr (name, ':'); + len = end ? end - name : strlen (name); + + if (end) { + id = strtoul (&end[1], &end, 10); + if (*end == '.') + screen = strtoul (&end[1], &end, 10); + if (*end != '\0') + return FALSE; + } + + if (len_ptr) + *len_ptr = len; + if (id_ptr) + *id_ptr = id; + if (screen_ptr) + *screen_ptr = screen; + return TRUE; +} + +static gint +compare_display_name (gconstpointer a, gconstpointer b) +{ + const GstVaapiDisplayInfo *const info = a; + const gchar *const cached_name = info->display_name; + const gchar *const tested_name = b; + guint cached_name_length, cached_id; + guint tested_name_length, tested_id; + + g_return_val_if_fail (cached_name, FALSE); + g_return_val_if_fail (tested_name, FALSE); + + if (!parse_display_name (cached_name, &cached_name_length, &cached_id, NULL)) + return FALSE; + if (!parse_display_name (tested_name, &tested_name_length, &tested_id, NULL)) + return FALSE; + if (cached_name_length != tested_name_length) + return FALSE; + if (strncmp (cached_name, tested_name, cached_name_length) != 0) + return FALSE; + if (cached_id != tested_id) + return FALSE; + return TRUE; +} + static inline const gchar * get_default_display_name (void) { @@ -58,38 +110,6 @@ get_default_display_name (void) return g_display_name; } -static gint -compare_display_name (gconstpointer a, gconstpointer b) -{ - const GstVaapiDisplayInfo *const info = a; - const gchar *cached_name = info->display_name, *cached_name_end; - const gchar *tested_name = b, *tested_name_end; - guint cached_name_length, tested_name_length; - - g_return_val_if_fail (cached_name, FALSE); - g_return_val_if_fail (tested_name, FALSE); - - cached_name_end = strchr (cached_name, ':'); - if (cached_name_end) - cached_name_length = cached_name_end - cached_name; - else - cached_name_length = strlen (cached_name); - - tested_name_end = strchr (tested_name, ':'); - if (tested_name_end) - tested_name_length = tested_name_end - tested_name; - else - tested_name_length = strlen (tested_name); - - if (cached_name_length != tested_name_length) - return FALSE; - if (strncmp (cached_name, tested_name, cached_name_length) != 0) - return FALSE; - - /* XXX: handle screen number? */ - return TRUE; -} - /* Reconstruct a display name without our prefix */ static const gchar * get_display_name (GstVaapiDisplayX11 * display) From 7c2c4c7a971680309c0b479b496a2e210e7149fd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Jul 2014 11:24:39 +0200 Subject: [PATCH 1723/3781] display: add interface to retrieve the display name. Add gst_vaapi_display_get_display_name() helper function to determine the name associated with the underlying native display. Note that for raw DRM backends, the display name is actually the device path. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 22 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 3 +++ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 1 + 3 files changed, 26 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 64f02455d5..a3b8a8ddd2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -854,6 +854,9 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) klass->close_display (display); } + g_free (priv->display_name); + priv->display_name = NULL; + g_free (priv->vendor_string); priv->vendor_string = NULL; @@ -930,6 +933,9 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, if (!gst_vaapi_display_cache_add (priv->cache, &info)) return FALSE; } + + g_free (priv->display_name); + priv->display_name = g_strdup (info.display_name); return TRUE; } @@ -1288,6 +1294,22 @@ gst_vaapi_display_get_display_type (GstVaapiDisplay * display) return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display_type; } +/** + * gst_vaapi_display_get_display_type: + * @display: a #GstVaapiDisplay + * + * Returns the @display name. + * + * Return value: the display name + */ +const gchar * +gst_vaapi_display_get_display_name (GstVaapiDisplay * display) +{ + g_return_val_if_fail (display != NULL, NULL); + + return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display_name; +} + /** * gst_vaapi_display_get_display: * @display: a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 182350eae0..e7e1935be5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -124,6 +124,9 @@ gst_vaapi_display_flush (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); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 747387a27d..b1e116051c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -144,6 +144,7 @@ struct _GstVaapiDisplayPrivate GstVaapiDisplayCache *cache; GRecMutex mutex; GstVaapiDisplayType display_type; + gchar *display_name; VADisplay display; guint width; guint height; From 3490212988d42b7d35c72893b3f37c7c0c79065d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Jul 2014 16:53:41 +0200 Subject: [PATCH 1724/3781] window: re-indent all GstVaapiWindow related source code. --- gst-libs/gst/vaapi/gstvaapiwindow.c | 348 ++++---- gst-libs/gst/vaapi/gstvaapiwindow.h | 53 +- gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 92 +- gst-libs/gst/vaapi/gstvaapiwindow_drm.h | 4 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 587 ++++++------- gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 23 +- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 84 +- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 703 ++++++++------- gst-libs/gst/vaapi/gstvaapiwindow_wayland.h | 5 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 865 +++++++++---------- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 10 +- gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 41 +- 12 files changed, 1351 insertions(+), 1464 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 700ea6ebb3..b9a668abd5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -41,87 +41,82 @@ #undef gst_vaapi_window_replace static void -gst_vaapi_window_ensure_size(GstVaapiWindow *window) +gst_vaapi_window_ensure_size (GstVaapiWindow * window) { - const GstVaapiWindowClass * const klass = - GST_VAAPI_WINDOW_GET_CLASS(window); + const GstVaapiWindowClass *const klass = GST_VAAPI_WINDOW_GET_CLASS (window); - if (!window->check_geometry) - return; + if (!window->check_geometry) + return; - if (klass->get_geometry) - klass->get_geometry(window, NULL, NULL, - &window->width, &window->height); + if (klass->get_geometry) + klass->get_geometry (window, NULL, NULL, &window->width, &window->height); - window->check_geometry = FALSE; - window->is_fullscreen = (window->width == window->display_width && - window->height == window->display_height); + window->check_geometry = FALSE; + window->is_fullscreen = (window->width == window->display_width && + window->height == window->display_height); } static gboolean -gst_vaapi_window_create(GstVaapiWindow *window, guint width, guint height) +gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height) { - gst_vaapi_display_get_size( - GST_VAAPI_OBJECT_DISPLAY(window), - &window->display_width, - &window->display_height - ); + gst_vaapi_display_get_size (GST_VAAPI_OBJECT_DISPLAY (window), + &window->display_width, &window->display_height); - if (!GST_VAAPI_WINDOW_GET_CLASS(window)->create(window, &width, &height)) - return FALSE; + if (!GST_VAAPI_WINDOW_GET_CLASS (window)->create (window, &width, &height)) + return FALSE; - if (width != window->width || height != window->height) { - GST_DEBUG("backend resized window to %ux%u", width, height); - window->width = width; - window->height = height; - } - return TRUE; + if (width != window->width || height != window->height) { + GST_DEBUG ("backend resized window to %ux%u", width, height); + window->width = width; + window->height = height; + } + return TRUE; } GstVaapiWindow * -gst_vaapi_window_new(const GstVaapiWindowClass *window_class, - GstVaapiDisplay *display, guint width, guint height) +gst_vaapi_window_new (const GstVaapiWindowClass * window_class, + GstVaapiDisplay * display, guint width, guint height) { - GstVaapiWindow *window; + GstVaapiWindow *window; - g_return_val_if_fail(width > 0, NULL); - g_return_val_if_fail(height > 0, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); - window = gst_vaapi_object_new(GST_VAAPI_OBJECT_CLASS(window_class), - display); - if (!window) - return NULL; + window = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (window_class), + display); + if (!window) + return NULL; - GST_VAAPI_OBJECT_ID(window) = 0; - if (!gst_vaapi_window_create(window, width, height)) - goto error; - return window; + GST_VAAPI_OBJECT_ID (window) = 0; + if (!gst_vaapi_window_create (window, width, height)) + goto error; + return window; error: - gst_vaapi_window_unref_internal(window); - return NULL; + gst_vaapi_window_unref_internal (window); + return NULL; } GstVaapiWindow * -gst_vaapi_window_new_from_native(const GstVaapiWindowClass *window_class, - GstVaapiDisplay *display, gpointer native_window) +gst_vaapi_window_new_from_native (const GstVaapiWindowClass * window_class, + GstVaapiDisplay * display, gpointer native_window) { - GstVaapiWindow *window; + GstVaapiWindow *window; - window = gst_vaapi_object_new(GST_VAAPI_OBJECT_CLASS(window_class), - display); - if (!window) - return NULL; + window = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (window_class), + display); + if (!window) + return NULL; - GST_VAAPI_OBJECT_ID(window) = GPOINTER_TO_SIZE(native_window); - window->use_foreign_window = TRUE; - if (!gst_vaapi_window_create(window, 0, 0)) - goto error; - return window; + GST_VAAPI_OBJECT_ID (window) = GPOINTER_TO_SIZE (native_window); + window->use_foreign_window = TRUE; + if (!gst_vaapi_window_create (window, 0, 0)) + goto error; + return window; error: - gst_vaapi_window_unref_internal(window); - return NULL; + gst_vaapi_window_unref_internal (window); + return NULL; } /** @@ -133,9 +128,9 @@ error: * Returns: The same @window argument */ GstVaapiWindow * -gst_vaapi_window_ref(GstVaapiWindow *window) +gst_vaapi_window_ref (GstVaapiWindow * window) { - return gst_vaapi_window_ref_internal(window); + return gst_vaapi_window_ref_internal (window); } /** @@ -146,9 +141,9 @@ gst_vaapi_window_ref(GstVaapiWindow *window) * the reference count reaches zero, the window will be free'd. */ void -gst_vaapi_window_unref(GstVaapiWindow *window) +gst_vaapi_window_unref (GstVaapiWindow * window) { - gst_vaapi_window_unref_internal(window); + gst_vaapi_window_unref_internal (window); } /** @@ -161,10 +156,10 @@ gst_vaapi_window_unref(GstVaapiWindow *window) * valid window. However, @new_window can be NULL. */ void -gst_vaapi_window_replace(GstVaapiWindow **old_window_ptr, - GstVaapiWindow *new_window) +gst_vaapi_window_replace (GstVaapiWindow ** old_window_ptr, + GstVaapiWindow * new_window) { - gst_vaapi_window_replace_internal(old_window_ptr, new_window); + gst_vaapi_window_replace_internal (old_window_ptr, new_window); } /** @@ -176,11 +171,11 @@ gst_vaapi_window_replace(GstVaapiWindow **old_window_ptr, * Return value: the parent #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_window_get_display(GstVaapiWindow *window) +gst_vaapi_window_get_display (GstVaapiWindow * window) { - g_return_val_if_fail(window != NULL, NULL); + g_return_val_if_fail (window != NULL, NULL); - return GST_VAAPI_OBJECT_DISPLAY(window); + return GST_VAAPI_OBJECT_DISPLAY (window); } /** @@ -191,12 +186,12 @@ gst_vaapi_window_get_display(GstVaapiWindow *window) * not appear on the screen. */ void -gst_vaapi_window_show(GstVaapiWindow *window) +gst_vaapi_window_show (GstVaapiWindow * window) { - g_return_if_fail(window != NULL); + g_return_if_fail (window != NULL); - GST_VAAPI_WINDOW_GET_CLASS(window)->show(window); - window->check_geometry = TRUE; + GST_VAAPI_WINDOW_GET_CLASS (window)->show (window); + window->check_geometry = TRUE; } /** @@ -207,11 +202,11 @@ gst_vaapi_window_show(GstVaapiWindow *window) * to be hidden (invisible to the user). */ void -gst_vaapi_window_hide(GstVaapiWindow *window) +gst_vaapi_window_hide (GstVaapiWindow * window) { - g_return_if_fail(window != NULL); + g_return_if_fail (window != NULL); - GST_VAAPI_WINDOW_GET_CLASS(window)->hide(window); + GST_VAAPI_WINDOW_GET_CLASS (window)->hide (window); } /** @@ -223,13 +218,13 @@ gst_vaapi_window_hide(GstVaapiWindow *window) * Return value: %TRUE if the window is fullscreen */ gboolean -gst_vaapi_window_get_fullscreen(GstVaapiWindow *window) +gst_vaapi_window_get_fullscreen (GstVaapiWindow * window) { - g_return_val_if_fail(window != NULL, FALSE); + g_return_val_if_fail (window != NULL, FALSE); - gst_vaapi_window_ensure_size(window); + gst_vaapi_window_ensure_size (window); - return window->is_fullscreen; + return window->is_fullscreen; } /** @@ -240,19 +235,19 @@ gst_vaapi_window_get_fullscreen(GstVaapiWindow *window) * Requests to place the @window in fullscreen or unfullscreen states. */ void -gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) +gst_vaapi_window_set_fullscreen (GstVaapiWindow * window, gboolean fullscreen) { - const GstVaapiWindowClass *klass; + const GstVaapiWindowClass *klass; - g_return_if_fail(window != NULL); + g_return_if_fail (window != NULL); - klass = GST_VAAPI_WINDOW_GET_CLASS(window); + klass = GST_VAAPI_WINDOW_GET_CLASS (window); - if (window->is_fullscreen != fullscreen && - klass->set_fullscreen && klass->set_fullscreen(window, fullscreen)) { - window->is_fullscreen = fullscreen; - window->check_geometry = TRUE; - } + if (window->is_fullscreen != fullscreen && + klass->set_fullscreen && klass->set_fullscreen (window, fullscreen)) { + window->is_fullscreen = fullscreen; + window->check_geometry = TRUE; + } } /** @@ -264,13 +259,13 @@ gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) * Return value: the width of the @window, in pixels */ guint -gst_vaapi_window_get_width(GstVaapiWindow *window) +gst_vaapi_window_get_width (GstVaapiWindow * window) { - g_return_val_if_fail(window != NULL, 0); + g_return_val_if_fail (window != NULL, 0); - gst_vaapi_window_ensure_size(window); + gst_vaapi_window_ensure_size (window); - return window->width; + return window->width; } /** @@ -282,35 +277,36 @@ gst_vaapi_window_get_width(GstVaapiWindow *window) * Return value: the height of the @window, in pixels */ guint -gst_vaapi_window_get_height(GstVaapiWindow *window) +gst_vaapi_window_get_height (GstVaapiWindow * window) { - g_return_val_if_fail(window != NULL, 0); + g_return_val_if_fail (window != NULL, 0); - gst_vaapi_window_ensure_size(window); + gst_vaapi_window_ensure_size (window); - return window->height; + return window->height; } /** * gst_vaapi_window_get_size: * @window: a #GstVaapiWindow - * @pwidth: return location for the width, or %NULL - * @pheight: return location for the height, or %NULL + * @width_ptr: return location for the width, or %NULL + * @height_ptr: return location for the height, or %NULL * * Retrieves the dimensions of a #GstVaapiWindow. */ void -gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight) +gst_vaapi_window_get_size (GstVaapiWindow * window, guint * width_ptr, + guint * height_ptr) { - g_return_if_fail(window != NULL); + g_return_if_fail (window != NULL); - gst_vaapi_window_ensure_size(window); + gst_vaapi_window_ensure_size (window); - if (pwidth) - *pwidth = window->width; + if (width_ptr) + *width_ptr = window->width; - if (pheight) - *pheight = window->height; + if (height_ptr) + *height_ptr = window->height; } /** @@ -321,11 +317,11 @@ gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight) * Resizes the @window to match the specified @width. */ void -gst_vaapi_window_set_width(GstVaapiWindow *window, guint width) +gst_vaapi_window_set_width (GstVaapiWindow * window, guint width) { - g_return_if_fail(window != NULL); + g_return_if_fail (window != NULL); - gst_vaapi_window_set_size(window, width, window->height); + gst_vaapi_window_set_size (window, width, window->height); } /** @@ -336,11 +332,11 @@ gst_vaapi_window_set_width(GstVaapiWindow *window, guint width) * Resizes the @window to match the specified @height. */ void -gst_vaapi_window_set_height(GstVaapiWindow *window, guint height) +gst_vaapi_window_set_height (GstVaapiWindow * window, guint height) { - g_return_if_fail(window != NULL); + g_return_if_fail (window != NULL); - gst_vaapi_window_set_size(window, window->width, height); + gst_vaapi_window_set_size (window, window->width, height); } /** @@ -352,39 +348,39 @@ gst_vaapi_window_set_height(GstVaapiWindow *window, guint height) * Resizes the @window to match the specified @width and @height. */ void -gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height) +gst_vaapi_window_set_size (GstVaapiWindow * window, guint width, guint height) { - g_return_if_fail(window != NULL); + g_return_if_fail (window != NULL); - if (width == window->width && height == window->height) - return; + if (width == window->width && height == window->height) + return; - if (!GST_VAAPI_WINDOW_GET_CLASS(window)->resize(window, width, height)) - return; + if (!GST_VAAPI_WINDOW_GET_CLASS (window)->resize (window, width, height)) + return; - window->width = width; - window->height = height; + window->width = width; + window->height = height; } static inline void -get_surface_rect(GstVaapiSurface *surface, GstVaapiRectangle *rect) +get_surface_rect (GstVaapiSurface * surface, GstVaapiRectangle * rect) { - rect->x = 0; - rect->y = 0; - rect->width = GST_VAAPI_SURFACE_WIDTH(surface); - rect->height = GST_VAAPI_SURFACE_HEIGHT(surface); + rect->x = 0; + rect->y = 0; + rect->width = GST_VAAPI_SURFACE_WIDTH (surface); + rect->height = GST_VAAPI_SURFACE_HEIGHT (surface); } static inline void -get_window_rect(GstVaapiWindow *window, GstVaapiRectangle *rect) +get_window_rect (GstVaapiWindow * window, GstVaapiRectangle * rect) { - guint width, height; + guint width, height; - gst_vaapi_window_get_size(window, &width, &height); - rect->x = 0; - rect->y = 0; - rect->width = width; - rect->height = height; + gst_vaapi_window_get_size (window, &width, &height); + rect->x = 0; + rect->y = 0; + rect->width = width; + rect->height = height; } /** @@ -406,47 +402,44 @@ get_window_rect(GstVaapiWindow *window, GstVaapiRectangle *rect) * Return value: %TRUE on success */ gboolean -gst_vaapi_window_put_surface( - GstVaapiWindow *window, - GstVaapiSurface *surface, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect, - guint flags -) +gst_vaapi_window_put_surface (GstVaapiWindow * window, + GstVaapiSurface * surface, + const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags) { - const GstVaapiWindowClass *klass; - GstVaapiRectangle src_rect_default, dst_rect_default; + const GstVaapiWindowClass *klass; + GstVaapiRectangle src_rect_default, dst_rect_default; - g_return_val_if_fail(window != NULL, FALSE); - g_return_val_if_fail(surface != NULL, FALSE); + g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); - klass = GST_VAAPI_WINDOW_GET_CLASS(window); - if (!klass->render) - return FALSE; + klass = GST_VAAPI_WINDOW_GET_CLASS (window); + if (!klass->render) + return FALSE; - if (!src_rect) { - src_rect = &src_rect_default; - get_surface_rect(surface, &src_rect_default); - } + if (!src_rect) { + src_rect = &src_rect_default; + get_surface_rect (surface, &src_rect_default); + } - if (!dst_rect) { - dst_rect = &dst_rect_default; - get_window_rect(window, &dst_rect_default); - } + if (!dst_rect) { + dst_rect = &dst_rect_default; + get_window_rect (window, &dst_rect_default); + } - return klass->render(window, surface, src_rect, dst_rect, flags); + return klass->render (window, surface, src_rect, dst_rect, flags); } static inline void -get_pixmap_rect(GstVaapiPixmap *pixmap, GstVaapiRectangle *rect) +get_pixmap_rect (GstVaapiPixmap * pixmap, GstVaapiRectangle * rect) { - guint width, height; + guint width, height; - gst_vaapi_pixmap_get_size(pixmap, &width, &height); - rect->x = 0; - rect->y = 0; - rect->width = width; - rect->height = height; + gst_vaapi_pixmap_get_size (pixmap, &width, &height); + rect->x = 0; + rect->y = 0; + rect->width = width; + rect->height = height; } /** @@ -465,31 +458,28 @@ get_pixmap_rect(GstVaapiPixmap *pixmap, GstVaapiRectangle *rect) * Return value: %TRUE on success */ gboolean -gst_vaapi_window_put_pixmap( - GstVaapiWindow *window, - GstVaapiPixmap *pixmap, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect -) +gst_vaapi_window_put_pixmap (GstVaapiWindow * window, + GstVaapiPixmap * pixmap, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) { - const GstVaapiWindowClass *klass; - GstVaapiRectangle src_rect_default, dst_rect_default; + const GstVaapiWindowClass *klass; + GstVaapiRectangle src_rect_default, dst_rect_default; - g_return_val_if_fail(window != NULL, FALSE); - g_return_val_if_fail(pixmap != NULL, FALSE); + g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (pixmap != NULL, FALSE); - klass = GST_VAAPI_WINDOW_GET_CLASS(window); - if (!klass->render_pixmap) - return FALSE; + klass = GST_VAAPI_WINDOW_GET_CLASS (window); + if (!klass->render_pixmap) + return FALSE; - if (!src_rect) { - src_rect = &src_rect_default; - get_pixmap_rect(pixmap, &src_rect_default); - } + if (!src_rect) { + src_rect = &src_rect_default; + get_pixmap_rect (pixmap, &src_rect_default); + } - if (!dst_rect) { - dst_rect = &dst_rect_default; - get_window_rect(window, &dst_rect_default); - } - return klass->render_pixmap(window, pixmap, src_rect, dst_rect); + if (!dst_rect) { + dst_rect = &dst_rect_default; + get_window_rect (window, &dst_rect_default); + } + return klass->render_pixmap (window, pixmap, src_rect, dst_rect); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 6b8f94ff63..7b7cbfee26 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -37,68 +37,61 @@ G_BEGIN_DECLS #define GST_VAAPI_WINDOW(obj) \ ((GstVaapiWindow *)(obj)) -typedef struct _GstVaapiWindow GstVaapiWindow; -typedef struct _GstVaapiWindowClass GstVaapiWindowClass; +typedef struct _GstVaapiWindow GstVaapiWindow; +typedef struct _GstVaapiWindowClass GstVaapiWindowClass; GstVaapiWindow * -gst_vaapi_window_ref(GstVaapiWindow *window); +gst_vaapi_window_ref (GstVaapiWindow * window); void -gst_vaapi_window_unref(GstVaapiWindow *window); +gst_vaapi_window_unref (GstVaapiWindow * window); void -gst_vaapi_window_replace(GstVaapiWindow **old_window_ptr, - GstVaapiWindow *new_window); +gst_vaapi_window_replace (GstVaapiWindow ** old_window_ptr, + GstVaapiWindow * new_window); GstVaapiDisplay * -gst_vaapi_window_get_display(GstVaapiWindow *window); +gst_vaapi_window_get_display (GstVaapiWindow * window); void -gst_vaapi_window_show(GstVaapiWindow *window); +gst_vaapi_window_show (GstVaapiWindow * window); void -gst_vaapi_window_hide(GstVaapiWindow *window); +gst_vaapi_window_hide (GstVaapiWindow * window); gboolean -gst_vaapi_window_get_fullscreen(GstVaapiWindow *window); +gst_vaapi_window_get_fullscreen (GstVaapiWindow * window); void -gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen); +gst_vaapi_window_set_fullscreen (GstVaapiWindow * window, gboolean fullscreen); guint -gst_vaapi_window_get_width(GstVaapiWindow *window); +gst_vaapi_window_get_width (GstVaapiWindow * window); guint -gst_vaapi_window_get_height(GstVaapiWindow *window); +gst_vaapi_window_get_height (GstVaapiWindow * window); void -gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight); +gst_vaapi_window_get_size (GstVaapiWindow * window, guint * width_ptr, + guint * height_ptr); void -gst_vaapi_window_set_width(GstVaapiWindow *window, guint width); +gst_vaapi_window_set_width (GstVaapiWindow * window, guint width); void -gst_vaapi_window_set_height(GstVaapiWindow *window, guint height); +gst_vaapi_window_set_height (GstVaapiWindow * window, guint height); void -gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height); +gst_vaapi_window_set_size (GstVaapiWindow * window, guint width, guint height); gboolean -gst_vaapi_window_put_surface( - GstVaapiWindow *window, - GstVaapiSurface *surface, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect, - guint flags -); +gst_vaapi_window_put_surface (GstVaapiWindow * window, + GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags); gboolean -gst_vaapi_window_put_pixmap( - GstVaapiWindow *window, - GstVaapiPixmap *pixmap, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect -); +gst_vaapi_window_put_pixmap (GstVaapiWindow * window, GstVaapiPixmap * pixmap, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c index 795856845e..510ae3b605 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -33,16 +33,17 @@ #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiWindowDRMClass GstVaapiWindowDRMClass; +typedef struct _GstVaapiWindowDRMClass GstVaapiWindowDRMClass; /** * GstVaapiWindowDRM: * * A dummy DRM window abstraction. */ -struct _GstVaapiWindowDRM { - /*< private >*/ - GstVaapiWindow parent_instance; +struct _GstVaapiWindowDRM +{ + /*< private >*/ + GstVaapiWindow parent_instance; }; /** @@ -50,77 +51,65 @@ struct _GstVaapiWindowDRM { * * A dummy DRM window abstraction class. */ -struct _GstVaapiWindowDRMClass { - /*< private >*/ - GstVaapiWindowClass parent_instance; +struct _GstVaapiWindowDRMClass +{ + /*< private >*/ + GstVaapiWindowClass parent_instance; }; static gboolean -gst_vaapi_window_drm_show(GstVaapiWindow *window) +gst_vaapi_window_drm_show (GstVaapiWindow * window) { - return TRUE; + return TRUE; } static gboolean -gst_vaapi_window_drm_hide(GstVaapiWindow *window) +gst_vaapi_window_drm_hide (GstVaapiWindow * window) { - return TRUE; + return TRUE; } static gboolean -gst_vaapi_window_drm_create( - GstVaapiWindow *window, - guint *width, - guint *height -) +gst_vaapi_window_drm_create (GstVaapiWindow * window, + guint * width, guint * height) { - return TRUE; + return TRUE; } static gboolean -gst_vaapi_window_drm_resize( - GstVaapiWindow * window, - guint width, - guint height -) +gst_vaapi_window_drm_resize (GstVaapiWindow * window, guint width, guint height) { - return TRUE; + return TRUE; } static gboolean -gst_vaapi_window_drm_render( - GstVaapiWindow *window, - GstVaapiSurface *surface, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect, - guint flags -) +gst_vaapi_window_drm_render (GstVaapiWindow * window, + GstVaapiSurface * surface, + const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags) { - return TRUE; + return TRUE; } void -gst_vaapi_window_drm_class_init(GstVaapiWindowDRMClass *klass) +gst_vaapi_window_drm_class_init (GstVaapiWindowDRMClass * klass) { - GstVaapiWindowClass * const window_class = - GST_VAAPI_WINDOW_CLASS(klass); + GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); - window_class->create = gst_vaapi_window_drm_create; - window_class->show = gst_vaapi_window_drm_show; - window_class->hide = gst_vaapi_window_drm_hide; - window_class->resize = gst_vaapi_window_drm_resize; - window_class->render = gst_vaapi_window_drm_render; + window_class->create = gst_vaapi_window_drm_create; + window_class->show = gst_vaapi_window_drm_show; + window_class->hide = gst_vaapi_window_drm_hide; + window_class->resize = gst_vaapi_window_drm_resize; + window_class->render = gst_vaapi_window_drm_render; } static void -gst_vaapi_window_drm_finalize(GstVaapiWindowDRM *window) +gst_vaapi_window_drm_finalize (GstVaapiWindowDRM * window) { } -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( - GstVaapiWindowDRM, - gst_vaapi_window_drm, - gst_vaapi_window_drm_class_init(&g_class)) +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowDRM, + gst_vaapi_window_drm, gst_vaapi_window_drm_class_init (&g_class)); /** * gst_vaapi_window_drm_new: @@ -141,16 +130,13 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( * Return value: the newly allocated #GstVaapiWindow object */ GstVaapiWindow * -gst_vaapi_window_drm_new( - GstVaapiDisplay *display, - guint width, - guint height -) +gst_vaapi_window_drm_new (GstVaapiDisplay * display, guint width, guint height) { - GST_DEBUG("new window, size %ux%u", width, height); + GST_DEBUG ("new window, size %ux%u", width, height); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_DRM (display), NULL); - return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( - gst_vaapi_window_drm_class()), display, width, height); + return + gst_vaapi_window_new (GST_VAAPI_WINDOW_CLASS (gst_vaapi_window_drm_class + ()), display, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h index ac97556371..60e942dda0 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h @@ -31,10 +31,10 @@ G_BEGIN_DECLS #define GST_VAAPI_WINDOW_DRM(obj) \ ((GstVaapiWindowDRM *)(obj)) -typedef struct _GstVaapiWindowDRM GstVaapiWindowDRM; +typedef struct _GstVaapiWindowDRM GstVaapiWindowDRM; GstVaapiWindow * -gst_vaapi_window_drm_new(GstVaapiDisplay *display, guint width, guint height); +gst_vaapi_window_drm_new (GstVaapiDisplay * display, guint width, guint height); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 24cd29b554..1107902437 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -48,12 +48,13 @@ #define GST_VAAPI_WINDOW_GLX_GET_CLASS(obj) \ GST_VAAPI_WINDOW_GLX_CLASS(GST_VAAPI_OBJECT_GET_CLASS(obj)) -typedef struct _GstVaapiWindowGLXPrivate GstVaapiWindowGLXPrivate; -typedef struct _GstVaapiWindowGLXClass GstVaapiWindowGLXClass; +typedef struct _GstVaapiWindowGLXPrivate GstVaapiWindowGLXPrivate; +typedef struct _GstVaapiWindowGLXClass GstVaapiWindowGLXClass; -struct _GstVaapiWindowGLXPrivate { - Colormap cmap; - GLContextState *gl_context; +struct _GstVaapiWindowGLXPrivate +{ + Colormap cmap; + GLContextState *gl_context; }; /** @@ -61,11 +62,12 @@ struct _GstVaapiWindowGLXPrivate { * * An X11 #Window suitable for GLX rendering. */ -struct _GstVaapiWindowGLX { - /*< private >*/ - GstVaapiWindowX11 parent_instance; +struct _GstVaapiWindowGLX +{ + /*< private >*/ + GstVaapiWindowX11 parent_instance; - GstVaapiWindowGLXPrivate priv; + GstVaapiWindowGLXPrivate priv; }; /** @@ -73,282 +75,261 @@ struct _GstVaapiWindowGLX { * * An X11 #Window suitable for GLX rendering. */ -struct _GstVaapiWindowGLXClass { - /*< private >*/ - GstVaapiWindowX11Class parent_class; +struct _GstVaapiWindowGLXClass +{ + /*< private >*/ + GstVaapiWindowX11Class parent_class; - GstVaapiObjectFinalizeFunc parent_finalize; - GstVaapiWindowResizeFunc parent_resize; + GstVaapiObjectFinalizeFunc parent_finalize; + GstVaapiWindowResizeFunc parent_resize; }; /* Fill rectangle coords with capped bounds */ static inline void -fill_rect( - GstVaapiRectangle *dst_rect, - const GstVaapiRectangle *src_rect, - guint width, - guint height -) +fill_rect (GstVaapiRectangle * dst_rect, + const GstVaapiRectangle * src_rect, guint width, guint height) { - if (src_rect) { - dst_rect->x = src_rect->x > 0 ? src_rect->x : 0; - dst_rect->y = src_rect->y > 0 ? src_rect->y : 0; - if (src_rect->x + src_rect->width < width) - dst_rect->width = src_rect->width; - else - dst_rect->width = width - dst_rect->x; - if (src_rect->y + src_rect->height < height) - dst_rect->height = src_rect->height; - else - dst_rect->height = height - dst_rect->y; - } - else { - dst_rect->x = 0; - dst_rect->y = 0; - dst_rect->width = width; - dst_rect->height = height; - } + if (src_rect) { + dst_rect->x = src_rect->x > 0 ? src_rect->x : 0; + dst_rect->y = src_rect->y > 0 ? src_rect->y : 0; + if (src_rect->x + src_rect->width < width) + dst_rect->width = src_rect->width; + else + dst_rect->width = width - dst_rect->x; + if (src_rect->y + src_rect->height < height) + dst_rect->height = src_rect->height; + else + dst_rect->height = height - dst_rect->y; + } else { + dst_rect->x = 0; + dst_rect->y = 0; + dst_rect->width = width; + dst_rect->height = height; + } } static void -_gst_vaapi_window_glx_destroy_context(GstVaapiWindow *window) +_gst_vaapi_window_glx_destroy_context (GstVaapiWindow * window) { - GstVaapiWindowGLXPrivate * const priv = - GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); + GstVaapiWindowGLXPrivate *const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - if (priv->gl_context) { - gl_destroy_context(priv->gl_context); - priv->gl_context = NULL; - } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + if (priv->gl_context) { + gl_destroy_context (priv->gl_context); + priv->gl_context = NULL; + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); } static gboolean -_gst_vaapi_window_glx_create_context( - GstVaapiWindow *window, - GLXContext foreign_context -) +_gst_vaapi_window_glx_create_context (GstVaapiWindow * window, + GLXContext foreign_context) { - GstVaapiWindowGLXPrivate * const priv = - GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - GLContextState parent_cs; + GstVaapiWindowGLXPrivate *const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + GLContextState parent_cs; - parent_cs.display = dpy; - parent_cs.window = None; - parent_cs.context = foreign_context; + parent_cs.display = dpy; + parent_cs.window = None; + parent_cs.context = foreign_context; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - priv->gl_context = gl_create_context( - dpy, - GST_VAAPI_OBJECT_XSCREEN(window), - &parent_cs - ); - if (!priv->gl_context) { - GST_DEBUG("could not create GLX context"); - goto end; - } - - if (!glXIsDirect(dpy, priv->gl_context->context)) { - GST_DEBUG("could not create a direct-rendering GLX context"); - goto out_destroy_context; - } + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + priv->gl_context = gl_create_context (dpy, + GST_VAAPI_OBJECT_XSCREEN (window), &parent_cs); + if (!priv->gl_context) { + GST_DEBUG ("could not create GLX context"); goto end; + } + + if (!glXIsDirect (dpy, priv->gl_context->context)) { + GST_DEBUG ("could not create a direct-rendering GLX context"); + goto out_destroy_context; + } + goto end; out_destroy_context: - gl_destroy_context(priv->gl_context); - priv->gl_context = NULL; + gl_destroy_context (priv->gl_context); + priv->gl_context = NULL; end: - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - return priv->gl_context != NULL; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + return priv->gl_context != NULL; } static gboolean -_gst_vaapi_window_glx_ensure_context( - GstVaapiWindow *window, - GLXContext foreign_context -) +_gst_vaapi_window_glx_ensure_context (GstVaapiWindow * window, + GLXContext foreign_context) { - GstVaapiWindowGLXPrivate * const priv = - GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); + GstVaapiWindowGLXPrivate *const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); - if (priv->gl_context) { - if (!foreign_context || foreign_context == priv->gl_context->context) - return TRUE; - _gst_vaapi_window_glx_destroy_context(window); - } - return _gst_vaapi_window_glx_create_context(window, foreign_context); + if (priv->gl_context) { + if (!foreign_context || foreign_context == priv->gl_context->context) + return TRUE; + _gst_vaapi_window_glx_destroy_context (window); + } + return _gst_vaapi_window_glx_create_context (window, foreign_context); } static gboolean -gst_vaapi_window_glx_ensure_context( - GstVaapiWindow *window, - GLXContext foreign_context -) +gst_vaapi_window_glx_ensure_context (GstVaapiWindow * window, + GLXContext foreign_context) { - GstVaapiWindowGLXPrivate * const priv = - GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); - GLContextState old_cs; - guint width, height; + GstVaapiWindowGLXPrivate *const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); + GLContextState old_cs; + guint width, height; - if (!_gst_vaapi_window_glx_ensure_context(window, foreign_context)) - return FALSE; + if (!_gst_vaapi_window_glx_ensure_context (window, foreign_context)) + return FALSE; - priv->gl_context->window = GST_VAAPI_OBJECT_ID(window); - if (!gl_set_current_context(priv->gl_context, &old_cs)) { - GST_DEBUG("could not make newly created GLX context current"); - return FALSE; - } + priv->gl_context->window = GST_VAAPI_OBJECT_ID (window); + if (!gl_set_current_context (priv->gl_context, &old_cs)) { + GST_DEBUG ("could not make newly created GLX context current"); + return FALSE; + } - glDisable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - glDisable(GL_CULL_FACE); - glDrawBuffer(GL_BACK); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable (GL_DEPTH_TEST); + glDepthMask (GL_FALSE); + glDisable (GL_CULL_FACE); + glDrawBuffer (GL_BACK); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gst_vaapi_window_get_size(window, &width, &height); - gl_resize(width, height); + gst_vaapi_window_get_size (window, &width, &height); + gl_resize (width, height); - gl_set_bgcolor(0); - glClear(GL_COLOR_BUFFER_BIT); - gl_set_current_context(&old_cs, NULL); - return TRUE; + gl_set_bgcolor (0); + glClear (GL_COLOR_BUFFER_BIT); + gl_set_current_context (&old_cs, NULL); + return TRUE; } static Visual * -gst_vaapi_window_glx_get_visual(GstVaapiWindow *window) +gst_vaapi_window_glx_get_visual (GstVaapiWindow * window) { - GstVaapiWindowGLXPrivate * const priv = - GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); + GstVaapiWindowGLXPrivate *const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); - if (!_gst_vaapi_window_glx_ensure_context(window, NULL)) - return NULL; - return priv->gl_context->visual->visual; + if (!_gst_vaapi_window_glx_ensure_context (window, NULL)) + return NULL; + return priv->gl_context->visual->visual; } static void -gst_vaapi_window_glx_destroy_colormap(GstVaapiWindow *window) +gst_vaapi_window_glx_destroy_colormap (GstVaapiWindow * window) { - GstVaapiWindowGLXPrivate * const priv = - GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); + GstVaapiWindowGLXPrivate *const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); - if (priv->cmap) { - if (!window->use_foreign_window) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - XFreeColormap(dpy, priv->cmap); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - } - priv->cmap = None; + if (priv->cmap) { + if (!window->use_foreign_window) { + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + XFreeColormap (dpy, priv->cmap); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); } + priv->cmap = None; + } } static Colormap -gst_vaapi_window_glx_create_colormap(GstVaapiWindow *window) +gst_vaapi_window_glx_create_colormap (GstVaapiWindow * window) { - GstVaapiWindowGLXPrivate * const priv = - GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - int screen; - XWindowAttributes wattr; - gboolean success = FALSE; + GstVaapiWindowGLXPrivate *const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + int screen; + XWindowAttributes wattr; + gboolean success = FALSE; - if (!priv->cmap) { - if (!window->use_foreign_window) { - if (!_gst_vaapi_window_glx_ensure_context(window, NULL)) - return None; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - x11_trap_errors(); - /* XXX: add a GstVaapiDisplayX11:x11-screen property? */ - screen = GST_VAAPI_OBJECT_XSCREEN(window); - priv->cmap = XCreateColormap( - dpy, - RootWindow(dpy, screen), - priv->gl_context->visual->visual, - AllocNone - ); - success = x11_untrap_errors() == 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - } - else { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - x11_trap_errors(); - XGetWindowAttributes(dpy, GST_VAAPI_OBJECT_ID(window), &wattr); - priv->cmap = wattr.colormap; - success = x11_untrap_errors() == 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - } - if (!success) - return None; + if (!priv->cmap) { + if (!window->use_foreign_window) { + if (!_gst_vaapi_window_glx_ensure_context (window, NULL)) + return None; + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + x11_trap_errors (); + /* XXX: add a GstVaapiDisplayX11:x11-screen property? */ + screen = GST_VAAPI_OBJECT_XSCREEN (window); + priv->cmap = XCreateColormap (dpy, + RootWindow (dpy, screen), + priv->gl_context->visual->visual, AllocNone); + success = x11_untrap_errors () == 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + } else { + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + x11_trap_errors (); + XGetWindowAttributes (dpy, GST_VAAPI_OBJECT_ID (window), &wattr); + priv->cmap = wattr.colormap; + success = x11_untrap_errors () == 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); } - return priv->cmap; + if (!success) + return None; + } + return priv->cmap; } static Colormap -gst_vaapi_window_glx_get_colormap(GstVaapiWindow *window) +gst_vaapi_window_glx_get_colormap (GstVaapiWindow * window) { - return gst_vaapi_window_glx_create_colormap(window); + return gst_vaapi_window_glx_create_colormap (window); } static gboolean -gst_vaapi_window_glx_resize(GstVaapiWindow *window, - guint width, guint height) +gst_vaapi_window_glx_resize (GstVaapiWindow * window, guint width, guint height) { - GstVaapiWindowGLXPrivate * const priv = - GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window); - const GstVaapiWindowGLXClass * const klass = - GST_VAAPI_WINDOW_GLX_GET_CLASS(window); - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - GLContextState old_cs; + GstVaapiWindowGLXPrivate *const priv = + GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); + const GstVaapiWindowGLXClass *const klass = + GST_VAAPI_WINDOW_GLX_GET_CLASS (window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + GLContextState old_cs; - if (!klass->parent_resize(window, width, height)) - return FALSE; + if (!klass->parent_resize (window, width, height)) + return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - XSync(dpy, False); /* make sure resize completed */ - if (gl_set_current_context(priv->gl_context, &old_cs)) { - gl_resize(width, height); - gl_set_current_context(&old_cs, NULL); - } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - return TRUE; + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + XSync (dpy, False); /* make sure resize completed */ + if (gl_set_current_context (priv->gl_context, &old_cs)) { + gl_resize (width, height); + gl_set_current_context (&old_cs, NULL); + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + return TRUE; } static void -gst_vaapi_window_glx_finalize(GstVaapiWindowGLX *window) +gst_vaapi_window_glx_finalize (GstVaapiWindowGLX * window) { - GstVaapiWindow * const base_window = GST_VAAPI_WINDOW(window); + GstVaapiWindow *const base_window = GST_VAAPI_WINDOW (window); - _gst_vaapi_window_glx_destroy_context(base_window); - gst_vaapi_window_glx_destroy_colormap(base_window); + _gst_vaapi_window_glx_destroy_context (base_window); + gst_vaapi_window_glx_destroy_colormap (base_window); - GST_VAAPI_WINDOW_GLX_GET_CLASS(window)->parent_finalize( - GST_VAAPI_OBJECT(window)); + GST_VAAPI_WINDOW_GLX_GET_CLASS (window)->parent_finalize (GST_VAAPI_OBJECT + (window)); } static void -gst_vaapi_window_glx_class_init(GstVaapiWindowGLXClass *klass) +gst_vaapi_window_glx_class_init (GstVaapiWindowGLXClass * klass) { - GstVaapiWindowClass * const window_class = - GST_VAAPI_WINDOW_CLASS(klass); - GstVaapiWindowX11Class * const xwindow_class = - GST_VAAPI_WINDOW_X11_CLASS(klass); + GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); + GstVaapiWindowX11Class *const xwindow_class = + GST_VAAPI_WINDOW_X11_CLASS (klass); - gst_vaapi_window_x11_class_init(xwindow_class); - klass->parent_resize = window_class->resize; - klass->parent_finalize = GST_VAAPI_OBJECT_CLASS(klass)->finalize; - window_class->resize = gst_vaapi_window_glx_resize; - xwindow_class->get_visual = gst_vaapi_window_glx_get_visual; - xwindow_class->get_colormap = gst_vaapi_window_glx_get_colormap; + gst_vaapi_window_x11_class_init (xwindow_class); + klass->parent_resize = window_class->resize; + klass->parent_finalize = GST_VAAPI_OBJECT_CLASS (klass)->finalize; + window_class->resize = gst_vaapi_window_glx_resize; + xwindow_class->get_visual = gst_vaapi_window_glx_get_visual; + xwindow_class->get_colormap = gst_vaapi_window_glx_get_colormap; } -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( - GstVaapiWindowGLX, - gst_vaapi_window_glx, - gst_vaapi_window_glx_class_init(&g_class)) +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowGLX, + gst_vaapi_window_glx, gst_vaapi_window_glx_class_init (&g_class)); /** * gst_vaapi_window_glx_new: @@ -363,24 +344,25 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( * Return value: the newly allocated #GstVaapiWindow object */ GstVaapiWindow * -gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height) +gst_vaapi_window_glx_new (GstVaapiDisplay * display, guint width, guint height) { - GstVaapiWindow *window; + GstVaapiWindow *window; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); - window = gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( - gst_vaapi_window_glx_class()), display, width, height); - if (!window) - return NULL; + window = + gst_vaapi_window_new (GST_VAAPI_WINDOW_CLASS (gst_vaapi_window_glx_class + ()), display, width, height); + if (!window) + return NULL; - if (!gst_vaapi_window_glx_ensure_context(window, NULL)) - goto error; - return window; + if (!gst_vaapi_window_glx_ensure_context (window, NULL)) + goto error; + return window; error: - gst_vaapi_window_unref(window); - return NULL; + gst_vaapi_window_unref (window); + return NULL; } /** @@ -396,27 +378,28 @@ error: * Return value: the newly allocated #GstVaapiWindow object */ GstVaapiWindow * -gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid) +gst_vaapi_window_glx_new_with_xid (GstVaapiDisplay * display, Window xid) { - GstVaapiWindow *window; + GstVaapiWindow *window; - GST_DEBUG("new window from xid 0x%08x", (guint)xid); + GST_DEBUG ("new window from xid 0x%08x", (guint) xid); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); - g_return_val_if_fail(xid != None, NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); + g_return_val_if_fail (xid != None, NULL); - window = gst_vaapi_window_new_from_native(GST_VAAPI_WINDOW_CLASS( - gst_vaapi_window_glx_class()), display, GINT_TO_POINTER(xid)); - if (!window) - return NULL; + window = + gst_vaapi_window_new_from_native (GST_VAAPI_WINDOW_CLASS + (gst_vaapi_window_glx_class ()), display, GINT_TO_POINTER (xid)); + if (!window) + return NULL; - if (!gst_vaapi_window_glx_ensure_context(window, NULL)) - goto error; - return window; + if (!gst_vaapi_window_glx_ensure_context (window, NULL)) + goto error; + return window; error: - gst_vaapi_window_unref(window); - return NULL; + gst_vaapi_window_unref (window); + return NULL; } /** @@ -428,11 +411,11 @@ error: * Return value: the #GLXContext bound to the @window */ GLXContext -gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window) +gst_vaapi_window_glx_get_context (GstVaapiWindowGLX * window) { - g_return_val_if_fail(window != NULL, NULL); + g_return_val_if_fail (window != NULL, NULL); - return GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window)->gl_context->context; + return GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window)->gl_context->context; } /** @@ -448,11 +431,11 @@ gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window) * Return value: %TRUE on success */ gboolean -gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx) +gst_vaapi_window_glx_set_context (GstVaapiWindowGLX * window, GLXContext ctx) { - g_return_val_if_fail(window != NULL, FALSE); + g_return_val_if_fail (window != NULL, FALSE); - return gst_vaapi_window_glx_ensure_context(GST_VAAPI_WINDOW(window), ctx); + return gst_vaapi_window_glx_ensure_context (GST_VAAPI_WINDOW (window), ctx); } /** @@ -466,16 +449,16 @@ gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx) * Return value: %TRUE on success */ gboolean -gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window) +gst_vaapi_window_glx_make_current (GstVaapiWindowGLX * window) { - gboolean success; + gboolean success; - g_return_val_if_fail(window != NULL, FALSE); + g_return_val_if_fail (window != NULL, FALSE); - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - success = gl_set_current_context(window->priv.gl_context, NULL); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - return success; + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + success = gl_set_current_context (window->priv.gl_context, NULL); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + return success; } /** @@ -487,13 +470,13 @@ gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window) * around glXSwapBuffers(). */ void -gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window) +gst_vaapi_window_glx_swap_buffers (GstVaapiWindowGLX * window) { - g_return_if_fail(window != NULL); + g_return_if_fail (window != NULL); - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - gl_swap_buffers(window->priv.gl_context); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + gl_swap_buffers (window->priv.gl_context); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); } /** @@ -514,57 +497,59 @@ gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window) * Return value: %TRUE on success */ gboolean -gst_vaapi_window_glx_put_texture( - GstVaapiWindowGLX *window, - GstVaapiTexture *texture, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect -) +gst_vaapi_window_glx_put_texture (GstVaapiWindowGLX * window, + GstVaapiTexture * texture, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) { - GstVaapiRectangle tmp_src_rect, tmp_dst_rect; - GLTextureState ts; - GLenum tex_target; - GLuint tex_id; - guint tex_width, tex_height; - guint win_width, win_height; + GstVaapiRectangle tmp_src_rect, tmp_dst_rect; + GLTextureState ts; + GLenum tex_target; + GLuint tex_id; + guint tex_width, tex_height; + guint win_width, win_height; - g_return_val_if_fail(window != NULL, FALSE); - g_return_val_if_fail(texture != NULL, FALSE); + g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (texture != NULL, FALSE); - gst_vaapi_texture_get_size(texture, &tex_width, &tex_height); - fill_rect(&tmp_src_rect, src_rect, tex_width, tex_height); - src_rect = &tmp_src_rect; + gst_vaapi_texture_get_size (texture, &tex_width, &tex_height); + fill_rect (&tmp_src_rect, src_rect, tex_width, tex_height); + src_rect = &tmp_src_rect; - gst_vaapi_window_get_size(GST_VAAPI_WINDOW(window), &win_width, &win_height); - fill_rect(&tmp_dst_rect, dst_rect, win_width, win_height); - dst_rect = &tmp_dst_rect; + gst_vaapi_window_get_size (GST_VAAPI_WINDOW (window), &win_width, + &win_height); + fill_rect (&tmp_dst_rect, dst_rect, win_width, win_height); + dst_rect = &tmp_dst_rect; - /* XXX: only GL_TEXTURE_2D textures are supported at this time */ - tex_target = gst_vaapi_texture_get_target(texture); - if (tex_target != GL_TEXTURE_2D) - return FALSE; + /* XXX: only GL_TEXTURE_2D textures are supported at this time */ + tex_target = gst_vaapi_texture_get_target (texture); + if (tex_target != GL_TEXTURE_2D) + return FALSE; - tex_id = gst_vaapi_texture_get_id(texture); - if (!gl_bind_texture(&ts, tex_target, tex_id)) - return FALSE; - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glPushMatrix(); - glTranslatef((GLfloat)dst_rect->x, (GLfloat)dst_rect->y, 0.0f); - glBegin(GL_QUADS); - { - const float tx1 = (float)src_rect->x / tex_width; - const float tx2 = (float)(src_rect->x + src_rect->width) / tex_width; - const float ty1 = (float)src_rect->y / tex_height; - const float ty2 = (float)(src_rect->y + src_rect->height) / tex_height; - const guint w = dst_rect->width; - const guint h = dst_rect->height; - glTexCoord2f(tx1, ty1); glVertex2i(0, 0); - glTexCoord2f(tx1, ty2); glVertex2i(0, h); - glTexCoord2f(tx2, ty2); glVertex2i(w, h); - glTexCoord2f(tx2, ty1); glVertex2i(w, 0); - } - glEnd(); - glPopMatrix(); - gl_unbind_texture(&ts); - return TRUE; + tex_id = gst_vaapi_texture_get_id (texture); + if (!gl_bind_texture (&ts, tex_target, tex_id)) + return FALSE; + glColor4f (1.0f, 1.0f, 1.0f, 1.0f); + glPushMatrix (); + glTranslatef ((GLfloat) dst_rect->x, (GLfloat) dst_rect->y, 0.0f); + glBegin (GL_QUADS); + { + const float tx1 = (float) src_rect->x / tex_width; + const float tx2 = (float) (src_rect->x + src_rect->width) / tex_width; + const float ty1 = (float) src_rect->y / tex_height; + const float ty2 = (float) (src_rect->y + src_rect->height) / tex_height; + const guint w = dst_rect->width; + const guint h = dst_rect->height; + glTexCoord2f (tx1, ty1); + glVertex2i (0, 0); + glTexCoord2f (tx1, ty2); + glVertex2i (0, h); + glTexCoord2f (tx2, ty2); + glVertex2i (w, h); + glTexCoord2f (tx2, ty1); + glVertex2i (w, 0); + } + glEnd (); + glPopMatrix (); + gl_unbind_texture (&ts); + return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index 307a975d3b..5179146011 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -35,33 +35,30 @@ G_BEGIN_DECLS #define GST_VAAPI_WINDOW_GLX(obj) \ ((GstVaapiWindowGLX *)(obj)) -typedef struct _GstVaapiWindowGLX GstVaapiWindowGLX; +typedef struct _GstVaapiWindowGLX GstVaapiWindowGLX; GstVaapiWindow * -gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height); +gst_vaapi_window_glx_new (GstVaapiDisplay * display, guint width, guint height); GstVaapiWindow * -gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid); +gst_vaapi_window_glx_new_with_xid (GstVaapiDisplay * display, Window xid); GLXContext -gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window); +gst_vaapi_window_glx_get_context (GstVaapiWindowGLX * window); gboolean -gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx); +gst_vaapi_window_glx_set_context (GstVaapiWindowGLX * window, GLXContext ctx); gboolean -gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window); +gst_vaapi_window_glx_make_current (GstVaapiWindowGLX * window); void -gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window); +gst_vaapi_window_glx_swap_buffers (GstVaapiWindowGLX * window); gboolean -gst_vaapi_window_glx_put_texture( - GstVaapiWindowGLX *window, - GstVaapiTexture *texture, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect -); +gst_vaapi_window_glx_put_texture (GstVaapiWindowGLX * window, + GstVaapiTexture * texture, const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index 3abf421e02..fdc0937003 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -36,40 +36,41 @@ G_BEGIN_DECLS GST_VAAPI_WINDOW_CLASS(GST_VAAPI_OBJECT_GET_CLASS(obj)) /* GstVaapiWindowClass hooks */ -typedef gboolean (*GstVaapiWindowCreateFunc) (GstVaapiWindow *window, - guint *width, guint *height); -typedef gboolean (*GstVaapiWindowShowFunc) (GstVaapiWindow *window); -typedef gboolean (*GstVaapiWindowHideFunc) (GstVaapiWindow *window); -typedef gboolean (*GstVaapiWindowGetGeometryFunc)(GstVaapiWindow *window, - gint *px, gint *py, guint *pwidth, guint *pheight); -typedef gboolean (*GstVaapiWindowSetFullscreenFunc)(GstVaapiWindow *window, +typedef gboolean (*GstVaapiWindowCreateFunc) (GstVaapiWindow * window, + guint * width, guint * height); +typedef gboolean (*GstVaapiWindowShowFunc) (GstVaapiWindow * window); +typedef gboolean (*GstVaapiWindowHideFunc) (GstVaapiWindow * window); +typedef gboolean (*GstVaapiWindowGetGeometryFunc) (GstVaapiWindow * window, + gint * px, gint * py, guint * pwidth, guint * pheight); +typedef gboolean (*GstVaapiWindowSetFullscreenFunc) (GstVaapiWindow * window, gboolean fullscreen); -typedef gboolean (*GstVaapiWindowResizeFunc) (GstVaapiWindow *window, +typedef gboolean (*GstVaapiWindowResizeFunc) (GstVaapiWindow * window, guint width, guint height); -typedef gboolean (*GstVaapiWindowRenderFunc) (GstVaapiWindow *window, - GstVaapiSurface *surface, const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect, guint flags); -typedef gboolean (*GstVaapiWindowRenderPixmapFunc)(GstVaapiWindow *window, - GstVaapiPixmap *pixmap, const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect); +typedef gboolean (*GstVaapiWindowRenderFunc) (GstVaapiWindow * window, + GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags); +typedef gboolean (*GstVaapiWindowRenderPixmapFunc) (GstVaapiWindow * window, + GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect); /** * GstVaapiWindow: * * Base class for system-dependent windows. */ -struct _GstVaapiWindow { - /*< private >*/ - GstVaapiObject parent_instance; +struct _GstVaapiWindow +{ + /*< private >*/ + GstVaapiObject parent_instance; - /*< protected >*/ - guint width; - guint height; - guint display_width; - guint display_height; - guint use_foreign_window : 1; - guint is_fullscreen : 1; - guint check_geometry : 1; + /*< protected >*/ + guint width; + guint height; + guint display_width; + guint display_height; + guint use_foreign_window:1; + guint is_fullscreen:1; + guint check_geometry:1; }; /** @@ -84,28 +85,29 @@ struct _GstVaapiWindow { * * Base class for system-dependent windows. */ -struct _GstVaapiWindowClass { - /*< private >*/ - GstVaapiObjectClass parent_class; +struct _GstVaapiWindowClass +{ + /*< private >*/ + GstVaapiObjectClass parent_class; - /*< protected >*/ - GstVaapiWindowCreateFunc create; - GstVaapiWindowShowFunc show; - GstVaapiWindowHideFunc hide; - GstVaapiWindowGetGeometryFunc get_geometry; - GstVaapiWindowSetFullscreenFunc set_fullscreen; - GstVaapiWindowResizeFunc resize; - GstVaapiWindowRenderFunc render; - GstVaapiWindowRenderPixmapFunc render_pixmap; + /*< protected >*/ + GstVaapiWindowCreateFunc create; + GstVaapiWindowShowFunc show; + GstVaapiWindowHideFunc hide; + GstVaapiWindowGetGeometryFunc get_geometry; + GstVaapiWindowSetFullscreenFunc set_fullscreen; + GstVaapiWindowResizeFunc resize; + GstVaapiWindowRenderFunc render; + GstVaapiWindowRenderPixmapFunc render_pixmap; }; GstVaapiWindow * -gst_vaapi_window_new(const GstVaapiWindowClass *window_class, - GstVaapiDisplay *display, guint width, guint height); +gst_vaapi_window_new (const GstVaapiWindowClass * window_class, + GstVaapiDisplay * display, guint width, guint height); GstVaapiWindow * -gst_vaapi_window_new_from_native(const GstVaapiWindowClass *window_class, - GstVaapiDisplay *display, gpointer native_window); +gst_vaapi_window_new_from_native (const GstVaapiWindowClass * + window_class, GstVaapiDisplay * display, gpointer native_window); /* Inline reference counting for core libgstvaapi library */ #ifdef IN_LIBGSTVAAPI_CORE diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 64db3898ba..e5c91392fe 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -46,73 +46,74 @@ #define GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(obj) \ (&GST_VAAPI_WINDOW_WAYLAND_CAST(obj)->priv) -typedef struct _GstVaapiWindowWaylandPrivate GstVaapiWindowWaylandPrivate; -typedef struct _GstVaapiWindowWaylandClass GstVaapiWindowWaylandClass; -typedef struct _FrameState FrameState; +typedef struct _GstVaapiWindowWaylandPrivate GstVaapiWindowWaylandPrivate; +typedef struct _GstVaapiWindowWaylandClass GstVaapiWindowWaylandClass; +typedef struct _FrameState FrameState; -struct _FrameState { - GstVaapiWindow *window; - GstVaapiSurface *surface; - GstVaapiVideoPool *surface_pool; - struct wl_buffer *buffer; - struct wl_callback *callback; +struct _FrameState +{ + GstVaapiWindow *window; + GstVaapiSurface *surface; + GstVaapiVideoPool *surface_pool; + struct wl_buffer *buffer; + struct wl_callback *callback; }; static FrameState * -frame_state_new(GstVaapiWindow *window) +frame_state_new (GstVaapiWindow * window) { - FrameState *frame; + FrameState *frame; - frame = g_slice_new(FrameState); - if (!frame) - return NULL; + frame = g_slice_new (FrameState); + if (!frame) + return NULL; - frame->window = window; - frame->surface = NULL; - frame->surface_pool = NULL; - frame->buffer = NULL; - frame->callback = NULL; - return frame; + frame->window = window; + frame->surface = NULL; + frame->surface_pool = NULL; + frame->buffer = NULL; + frame->callback = NULL; + return frame; } static void -frame_state_free(FrameState *frame) +frame_state_free (FrameState * frame) { - if (!frame) - return; + if (!frame) + return; - if (frame->surface) { - if (frame->surface_pool) - gst_vaapi_video_pool_put_object(frame->surface_pool, - frame->surface); - frame->surface = NULL; - } - gst_vaapi_video_pool_replace(&frame->surface_pool, NULL); + if (frame->surface) { + if (frame->surface_pool) + gst_vaapi_video_pool_put_object (frame->surface_pool, frame->surface); + frame->surface = NULL; + } + gst_vaapi_video_pool_replace (&frame->surface_pool, NULL); - if (frame->buffer) { - wl_buffer_destroy(frame->buffer); - frame->buffer = NULL; - } + if (frame->buffer) { + wl_buffer_destroy (frame->buffer); + frame->buffer = NULL; + } - if (frame->callback) { - wl_callback_destroy(frame->callback); - frame->callback = NULL; - } - g_slice_free(FrameState, frame); + if (frame->callback) { + wl_callback_destroy (frame->callback); + frame->callback = NULL; + } + g_slice_free (FrameState, frame); } -struct _GstVaapiWindowWaylandPrivate { - struct wl_shell_surface *shell_surface; - struct wl_surface *surface; - struct wl_region *opaque_region; - struct wl_event_queue *event_queue; - FrameState *frame; - GstVideoFormat surface_format; - GstVaapiVideoPool *surface_pool; - GstVaapiFilter *filter; - guint is_shown : 1; - guint fullscreen_on_show : 1; - guint use_vpp : 1; +struct _GstVaapiWindowWaylandPrivate +{ + struct wl_shell_surface *shell_surface; + struct wl_surface *surface; + struct wl_region *opaque_region; + struct wl_event_queue *event_queue; + FrameState *frame; + GstVideoFormat surface_format; + GstVaapiVideoPool *surface_pool; + GstVaapiFilter *filter; + guint is_shown:1; + guint fullscreen_on_show:1; + guint use_vpp:1; }; /** @@ -120,11 +121,12 @@ struct _GstVaapiWindowWaylandPrivate { * * A Wayland window abstraction. */ -struct _GstVaapiWindowWayland { - /*< private >*/ - GstVaapiWindow parent_instance; +struct _GstVaapiWindowWayland +{ + /*< private >*/ + GstVaapiWindow parent_instance; - GstVaapiWindowWaylandPrivate priv; + GstVaapiWindowWaylandPrivate priv; }; /** @@ -132,419 +134,394 @@ struct _GstVaapiWindowWayland { * * An Wayland #Window wrapper class. */ -struct _GstVaapiWindowWaylandClass { - /*< private >*/ - GstVaapiWindowClass parent_class; +struct _GstVaapiWindowWaylandClass +{ + /*< private >*/ + GstVaapiWindowClass parent_class; }; static gboolean -gst_vaapi_window_wayland_show(GstVaapiWindow *window) +gst_vaapi_window_wayland_show (GstVaapiWindow * window) { - GST_WARNING("unimplemented GstVaapiWindowWayland::show()"); + GST_WARNING ("unimplemented GstVaapiWindowWayland::show()"); - return TRUE; + return TRUE; } static gboolean -gst_vaapi_window_wayland_hide(GstVaapiWindow *window) +gst_vaapi_window_wayland_hide (GstVaapiWindow * window) { - GST_WARNING("unimplemented GstVaapiWindowWayland::hide()"); + GST_WARNING ("unimplemented GstVaapiWindowWayland::hide()"); - return TRUE; + return TRUE; } static gboolean -gst_vaapi_window_wayland_sync(GstVaapiWindow *window) +gst_vaapi_window_wayland_sync (GstVaapiWindow * window) { - GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); - if (priv->frame) { - struct wl_display * const wl_display = - GST_VAAPI_OBJECT_WL_DISPLAY(window); + if (priv->frame) { + struct wl_display *const wl_display = GST_VAAPI_OBJECT_WL_DISPLAY (window); - do { - if (wl_display_dispatch_queue(wl_display, priv->event_queue) < 0) - return FALSE; - } while (priv->frame); - } - return TRUE; + do { + if (wl_display_dispatch_queue (wl_display, priv->event_queue) < 0) + return FALSE; + } while (priv->frame); + } + return TRUE; } static void -handle_ping(void *data, struct wl_shell_surface *shell_surface, - uint32_t serial) +handle_ping (void *data, struct wl_shell_surface *shell_surface, + uint32_t serial) { - wl_shell_surface_pong(shell_surface, serial); + wl_shell_surface_pong (shell_surface, serial); } static void -handle_configure(void *data, struct wl_shell_surface *shell_surface, - uint32_t edges, int32_t width, int32_t height) +handle_configure (void *data, struct wl_shell_surface *shell_surface, + uint32_t edges, int32_t width, int32_t height) { } static void -handle_popup_done(void *data, struct wl_shell_surface *shell_surface) +handle_popup_done (void *data, struct wl_shell_surface *shell_surface) { } static const struct wl_shell_surface_listener shell_surface_listener = { - handle_ping, - handle_configure, - handle_popup_done + handle_ping, + handle_configure, + handle_popup_done }; static gboolean -gst_vaapi_window_wayland_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) +gst_vaapi_window_wayland_set_fullscreen (GstVaapiWindow * window, + gboolean fullscreen) { - GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); - - if (!priv->is_shown) { - priv->fullscreen_on_show = fullscreen; - return TRUE; - } - - if (!fullscreen) - wl_shell_surface_set_toplevel(priv->shell_surface); - else { - wl_shell_surface_set_fullscreen( - priv->shell_surface, - WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, - 0, - NULL - ); - } + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + if (!priv->is_shown) { + priv->fullscreen_on_show = fullscreen; return TRUE; + } + + if (!fullscreen) + wl_shell_surface_set_toplevel (priv->shell_surface); + else { + wl_shell_surface_set_fullscreen (priv->shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL); + } + + return TRUE; } static gboolean -gst_vaapi_window_wayland_create( - GstVaapiWindow *window, - guint *width, - guint *height -) +gst_vaapi_window_wayland_create (GstVaapiWindow * window, + guint * width, guint * height) { - GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); - GstVaapiDisplayWaylandPrivate * const priv_display = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(GST_VAAPI_OBJECT_DISPLAY(window)); + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + GstVaapiDisplayWaylandPrivate *const priv_display = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_OBJECT_DISPLAY (window)); - GST_DEBUG("create window, size %ux%u", *width, *height); + GST_DEBUG ("create window, size %ux%u", *width, *height); - g_return_val_if_fail(priv_display->compositor != NULL, FALSE); - g_return_val_if_fail(priv_display->shell != NULL, FALSE); + g_return_val_if_fail (priv_display->compositor != NULL, FALSE); + g_return_val_if_fail (priv_display->shell != NULL, FALSE); - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - priv->event_queue = wl_display_create_queue(priv_display->wl_display); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - if (!priv->event_queue) - return FALSE; + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + priv->event_queue = wl_display_create_queue (priv_display->wl_display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + if (!priv->event_queue) + return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - priv->surface = wl_compositor_create_surface(priv_display->compositor); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - if (!priv->surface) - return FALSE; - wl_proxy_set_queue((struct wl_proxy *)priv->surface, priv->event_queue); + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + priv->surface = wl_compositor_create_surface (priv_display->compositor); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + if (!priv->surface) + return FALSE; + wl_proxy_set_queue ((struct wl_proxy *) priv->surface, priv->event_queue); - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - priv->shell_surface = - wl_shell_get_shell_surface(priv_display->shell, priv->surface); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - if (!priv->shell_surface) - return FALSE; - wl_proxy_set_queue((struct wl_proxy *)priv->shell_surface, - priv->event_queue); + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + priv->shell_surface = + wl_shell_get_shell_surface (priv_display->shell, priv->surface); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + if (!priv->shell_surface) + return FALSE; + wl_proxy_set_queue ((struct wl_proxy *) priv->shell_surface, + priv->event_queue); - wl_shell_surface_add_listener(priv->shell_surface, - &shell_surface_listener, priv); - wl_shell_surface_set_toplevel(priv->shell_surface); + wl_shell_surface_add_listener (priv->shell_surface, + &shell_surface_listener, priv); + wl_shell_surface_set_toplevel (priv->shell_surface); - if (priv->fullscreen_on_show) - gst_vaapi_window_wayland_set_fullscreen(window, TRUE); + if (priv->fullscreen_on_show) + gst_vaapi_window_wayland_set_fullscreen (window, TRUE); - priv->surface_format = GST_VIDEO_FORMAT_ENCODED; - priv->use_vpp = GST_VAAPI_DISPLAY_HAS_VPP(GST_VAAPI_OBJECT_DISPLAY(window)); - priv->is_shown = TRUE; + priv->surface_format = GST_VIDEO_FORMAT_ENCODED; + priv->use_vpp = GST_VAAPI_DISPLAY_HAS_VPP (GST_VAAPI_OBJECT_DISPLAY (window)); + priv->is_shown = TRUE; - return TRUE; + return TRUE; } static void -gst_vaapi_window_wayland_destroy(GstVaapiWindow * window) +gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) { - GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); - if (priv->frame) { - frame_state_free(priv->frame); - priv->frame = NULL; - } + if (priv->frame) { + frame_state_free (priv->frame); + priv->frame = NULL; + } - if (priv->shell_surface) { - wl_shell_surface_destroy(priv->shell_surface); - priv->shell_surface = NULL; - } + if (priv->shell_surface) { + wl_shell_surface_destroy (priv->shell_surface); + priv->shell_surface = NULL; + } - if (priv->surface) { - wl_surface_destroy(priv->surface); - priv->surface = NULL; - } + if (priv->surface) { + wl_surface_destroy (priv->surface); + priv->surface = NULL; + } - if (priv->event_queue) { - wl_event_queue_destroy(priv->event_queue); - priv->event_queue = NULL; - } + if (priv->event_queue) { + wl_event_queue_destroy (priv->event_queue); + priv->event_queue = NULL; + } - gst_vaapi_filter_replace(&priv->filter, NULL); - gst_vaapi_video_pool_replace(&priv->surface_pool, NULL); + gst_vaapi_filter_replace (&priv->filter, NULL); + gst_vaapi_video_pool_replace (&priv->surface_pool, NULL); } static gboolean -gst_vaapi_window_wayland_resize( - GstVaapiWindow * window, - guint width, - guint height -) +gst_vaapi_window_wayland_resize (GstVaapiWindow * window, + guint width, guint height) { - GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); - GstVaapiDisplayWaylandPrivate * const priv_display = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(GST_VAAPI_OBJECT_DISPLAY(window)); + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + GstVaapiDisplayWaylandPrivate *const priv_display = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_OBJECT_DISPLAY (window)); - GST_DEBUG("resize window, new size %ux%u", width, height); + GST_DEBUG ("resize window, new size %ux%u", width, height); - if (priv->opaque_region) - wl_region_destroy(priv->opaque_region); - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - priv->opaque_region = wl_compositor_create_region(priv_display->compositor); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - wl_region_add(priv->opaque_region, 0, 0, width, height); + if (priv->opaque_region) + wl_region_destroy (priv->opaque_region); + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + priv->opaque_region = wl_compositor_create_region (priv_display->compositor); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + wl_region_add (priv->opaque_region, 0, 0, width, height); - return TRUE; + return TRUE; } static void -frame_redraw_callback(void *data, struct wl_callback *callback, uint32_t time) +frame_redraw_callback (void *data, struct wl_callback *callback, uint32_t time) { - FrameState * const frame = data; - GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(frame->window); + FrameState *const frame = data; + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); - frame_state_free(frame); - if (priv->frame == frame) - priv->frame = NULL; + frame_state_free (frame); + if (priv->frame == frame) + priv->frame = NULL; } static const struct wl_callback_listener frame_callback_listener = { - frame_redraw_callback + frame_redraw_callback }; static GstVaapiSurface * -vpp_convert( - GstVaapiWindow *window, - GstVaapiSurface *surface, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect, - guint flags -) +vpp_convert (GstVaapiWindow * window, + GstVaapiSurface * surface, + const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags) { - GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(window); - GstVaapiSurface *vpp_surface = NULL; - GstVaapiFilterStatus status; - GstVideoInfo vi; + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); + GstVaapiSurface *vpp_surface = NULL; + GstVaapiFilterStatus status; + GstVideoInfo vi; - /* Ensure VA surface pool is created */ - /* XXX: optimize the surface format to use. e.g. YUY2 */ - if (!priv->surface_pool) { - gst_video_info_set_format(&vi, priv->surface_format, - window->width, window->height); - priv->surface_pool = gst_vaapi_surface_pool_new(display, &vi); - if (!priv->surface_pool) - return NULL; - gst_vaapi_filter_replace(&priv->filter, NULL); - } + /* Ensure VA surface pool is created */ + /* XXX: optimize the surface format to use. e.g. YUY2 */ + if (!priv->surface_pool) { + gst_video_info_set_format (&vi, priv->surface_format, + window->width, window->height); + priv->surface_pool = gst_vaapi_surface_pool_new (display, &vi); + if (!priv->surface_pool) + return NULL; + gst_vaapi_filter_replace (&priv->filter, NULL); + } - /* Ensure VPP pipeline is built */ - if (!priv->filter) { - priv->filter = gst_vaapi_filter_new(display); - if (!priv->filter) - goto error_create_filter; - if (!gst_vaapi_filter_set_format(priv->filter, priv->surface_format)) - goto error_unsupported_format; - } - if (!gst_vaapi_filter_set_cropping_rectangle(priv->filter, src_rect)) - return NULL; - if (!gst_vaapi_filter_set_target_rectangle(priv->filter, dst_rect)) - return NULL; + /* Ensure VPP pipeline is built */ + if (!priv->filter) { + priv->filter = gst_vaapi_filter_new (display); + if (!priv->filter) + goto error_create_filter; + if (!gst_vaapi_filter_set_format (priv->filter, priv->surface_format)) + goto error_unsupported_format; + } + if (!gst_vaapi_filter_set_cropping_rectangle (priv->filter, src_rect)) + return NULL; + if (!gst_vaapi_filter_set_target_rectangle (priv->filter, dst_rect)) + return NULL; - /* Post-process the decoded source surface */ - vpp_surface = gst_vaapi_video_pool_get_object(priv->surface_pool); - if (!vpp_surface) - return NULL; + /* Post-process the decoded source surface */ + vpp_surface = gst_vaapi_video_pool_get_object (priv->surface_pool); + if (!vpp_surface) + return NULL; - status = gst_vaapi_filter_process(priv->filter, surface, vpp_surface, - flags); - if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) - goto error_process_filter; - return vpp_surface; + status = gst_vaapi_filter_process (priv->filter, surface, vpp_surface, flags); + if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) + goto error_process_filter; + return vpp_surface; - /* ERRORS */ + /* ERRORS */ error_create_filter: - GST_WARNING("failed to create VPP filter. Disabling"); - priv->use_vpp = FALSE; - return NULL; + GST_WARNING ("failed to create VPP filter. Disabling"); + priv->use_vpp = FALSE; + return NULL; error_unsupported_format: - GST_ERROR("unsupported render target format %s", - gst_vaapi_video_format_to_string(priv->surface_format)); - priv->use_vpp = FALSE; - return NULL; + GST_ERROR ("unsupported render target format %s", + gst_vaapi_video_format_to_string (priv->surface_format)); + priv->use_vpp = FALSE; + return NULL; error_process_filter: - GST_ERROR("failed to process surface %" GST_VAAPI_ID_FORMAT " (error %d)", - GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface)), status); - gst_vaapi_video_pool_put_object(priv->surface_pool, vpp_surface); - return NULL; + GST_ERROR ("failed to process surface %" GST_VAAPI_ID_FORMAT " (error %d)", + GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (surface)), status); + gst_vaapi_video_pool_put_object (priv->surface_pool, vpp_surface); + return NULL; } static gboolean -gst_vaapi_window_wayland_render( - GstVaapiWindow *window, - GstVaapiSurface *surface, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect, - guint flags -) +gst_vaapi_window_wayland_render (GstVaapiWindow * window, + GstVaapiSurface * surface, + const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags) { - GstVaapiWindowWaylandPrivate * const priv = - GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(window); - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(window); - struct wl_display * const wl_display = GST_VAAPI_OBJECT_WL_DISPLAY(window); - struct wl_buffer *buffer; - FrameState *frame; - guint width, height, va_flags; - VAStatus status; - gboolean need_vpp = FALSE; + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); + struct wl_display *const wl_display = GST_VAAPI_OBJECT_WL_DISPLAY (window); + struct wl_buffer *buffer; + FrameState *frame; + guint width, height, va_flags; + VAStatus status; + gboolean need_vpp = FALSE; - /* Check that we don't need to crop source VA surface */ - gst_vaapi_surface_get_size(surface, &width, &height); - if (src_rect->x != 0 || src_rect->y != 0) - need_vpp = TRUE; - if (src_rect->width != width || src_rect->height != height) - need_vpp = TRUE; + /* Check that we don't need to crop source VA surface */ + gst_vaapi_surface_get_size (surface, &width, &height); + if (src_rect->x != 0 || src_rect->y != 0) + need_vpp = TRUE; + if (src_rect->width != width || src_rect->height != height) + need_vpp = TRUE; - /* Check that we don't render to a subregion of this window */ - if (dst_rect->x != 0 || dst_rect->y != 0) - need_vpp = TRUE; - if (dst_rect->width != window->width || dst_rect->height != window->height) - need_vpp = TRUE; + /* Check that we don't render to a subregion of this window */ + if (dst_rect->x != 0 || dst_rect->y != 0) + need_vpp = TRUE; + if (dst_rect->width != window->width || dst_rect->height != window->height) + need_vpp = TRUE; - /* Try to construct a Wayland buffer from VA surface as is (without VPP) */ - if (!need_vpp) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - va_flags = from_GstVaapiSurfaceRenderFlags(flags); - status = vaGetSurfaceBufferWl( - GST_VAAPI_DISPLAY_VADISPLAY(display), - GST_VAAPI_OBJECT_ID(surface), - va_flags & (VA_TOP_FIELD|VA_BOTTOM_FIELD), - &buffer - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED) - need_vpp = TRUE; - else if (!vaapi_check_status(status, "vaGetSurfaceBufferWl()")) - return FALSE; + /* Try to construct a Wayland buffer from VA surface as is (without VPP) */ + if (!need_vpp) { + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + va_flags = from_GstVaapiSurfaceRenderFlags (flags); + status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_OBJECT_ID (surface), + va_flags & (VA_TOP_FIELD | VA_BOTTOM_FIELD), &buffer); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED) + need_vpp = TRUE; + else if (!vaapi_check_status (status, "vaGetSurfaceBufferWl()")) + return FALSE; + } + + /* Try to construct a Wayland buffer with VPP */ + if (need_vpp) { + if (priv->use_vpp) { + GstVaapiSurface *const vpp_surface = + vpp_convert (window, surface, src_rect, dst_rect, flags); + if (G_UNLIKELY (!vpp_surface)) + need_vpp = FALSE; + else { + surface = vpp_surface; + width = window->width; + height = window->height; + } } - /* Try to construct a Wayland buffer with VPP */ - if (need_vpp) { - if (priv->use_vpp) { - GstVaapiSurface * const vpp_surface = - vpp_convert(window, surface, src_rect, dst_rect, flags); - if (G_UNLIKELY(!vpp_surface)) - need_vpp = FALSE; - else { - surface = vpp_surface; - width = window->width; - height = window->height; - } - } + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_OBJECT_ID (surface), VA_FRAME_PICTURE, &buffer); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + if (!vaapi_check_status (status, "vaGetSurfaceBufferWl()")) + return FALSE; + } - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - status = vaGetSurfaceBufferWl( - GST_VAAPI_DISPLAY_VADISPLAY(display), - GST_VAAPI_OBJECT_ID(surface), - VA_FRAME_PICTURE, - &buffer - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - if (!vaapi_check_status(status, "vaGetSurfaceBufferWl()")) - return FALSE; - } + /* Wait for the previous frame to complete redraw */ + if (!gst_vaapi_window_wayland_sync (window)) + return FALSE; - /* Wait for the previous frame to complete redraw */ - if (!gst_vaapi_window_wayland_sync(window)) - return FALSE; + frame = frame_state_new (window); + if (!frame) + return FALSE; + priv->frame = frame; - frame = frame_state_new(window); - if (!frame) - return FALSE; - priv->frame = frame; + if (need_vpp && priv->use_vpp) { + frame->surface = surface; + frame->surface_pool = gst_vaapi_video_pool_ref (priv->surface_pool); + } - if (need_vpp && priv->use_vpp) { - frame->surface = surface; - frame->surface_pool = gst_vaapi_video_pool_ref(priv->surface_pool); - } + /* XXX: attach to the specified target rectangle */ + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + wl_surface_attach (priv->surface, buffer, 0, 0); + wl_surface_damage (priv->surface, 0, 0, width, height); - /* XXX: attach to the specified target rectangle */ - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - wl_surface_attach(priv->surface, buffer, 0, 0); - wl_surface_damage(priv->surface, 0, 0, width, height); + if (priv->opaque_region) { + wl_surface_set_opaque_region (priv->surface, priv->opaque_region); + wl_region_destroy (priv->opaque_region); + priv->opaque_region = NULL; + } - if (priv->opaque_region) { - wl_surface_set_opaque_region(priv->surface, priv->opaque_region); - wl_region_destroy(priv->opaque_region); - priv->opaque_region = NULL; - } + frame->buffer = buffer; + frame->callback = wl_surface_frame (priv->surface); + wl_callback_add_listener (frame->callback, &frame_callback_listener, frame); - frame->buffer = buffer; - frame->callback = wl_surface_frame(priv->surface); - wl_callback_add_listener(frame->callback, &frame_callback_listener, frame); - - wl_surface_commit(priv->surface); - wl_display_flush(wl_display); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - return TRUE; + wl_surface_commit (priv->surface); + wl_display_flush (wl_display); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + return TRUE; } static void -gst_vaapi_window_wayland_class_init(GstVaapiWindowWaylandClass * klass) +gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass) { - GstVaapiObjectClass * const object_class = GST_VAAPI_OBJECT_CLASS(klass); - GstVaapiWindowClass * const window_class = GST_VAAPI_WINDOW_CLASS(klass); + GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); + GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); - object_class->finalize = (GstVaapiObjectFinalizeFunc) - gst_vaapi_window_wayland_destroy; + object_class->finalize = (GstVaapiObjectFinalizeFunc) + gst_vaapi_window_wayland_destroy; - window_class->create = gst_vaapi_window_wayland_create; - window_class->show = gst_vaapi_window_wayland_show; - window_class->hide = gst_vaapi_window_wayland_hide; - window_class->render = gst_vaapi_window_wayland_render; - window_class->resize = gst_vaapi_window_wayland_resize; - window_class->set_fullscreen = gst_vaapi_window_wayland_set_fullscreen; + window_class->create = gst_vaapi_window_wayland_create; + window_class->show = gst_vaapi_window_wayland_show; + window_class->hide = gst_vaapi_window_wayland_hide; + window_class->render = gst_vaapi_window_wayland_render; + window_class->resize = gst_vaapi_window_wayland_resize; + window_class->set_fullscreen = gst_vaapi_window_wayland_set_fullscreen; } #define gst_vaapi_window_wayland_finalize \ gst_vaapi_window_wayland_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( - GstVaapiWindowWayland, - gst_vaapi_window_wayland, - gst_vaapi_window_wayland_class_init(&g_class)) +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowWayland, + gst_vaapi_window_wayland, gst_vaapi_window_wayland_class_init (&g_class)); /** * gst_vaapi_window_wayland_new: @@ -559,16 +536,14 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( * Return value: the newly allocated #GstVaapiWindow object */ GstVaapiWindow * -gst_vaapi_window_wayland_new( - GstVaapiDisplay *display, - guint width, - guint height -) +gst_vaapi_window_wayland_new (GstVaapiDisplay * display, + guint width, guint height) { - GST_DEBUG("new window, size %ux%u", width, height); + GST_DEBUG ("new window, size %ux%u", width, height); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_WAYLAND(display), NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_WAYLAND (display), NULL); - return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( - gst_vaapi_window_wayland_class()), display, width, height); + return + gst_vaapi_window_new (GST_VAAPI_WINDOW_CLASS + (gst_vaapi_window_wayland_class ()), display, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h index 3d0af50d32..304ecf053f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h @@ -30,10 +30,11 @@ G_BEGIN_DECLS -typedef struct _GstVaapiWindowWayland GstVaapiWindowWayland; +typedef struct _GstVaapiWindowWayland GstVaapiWindowWayland; GstVaapiWindow * -gst_vaapi_window_wayland_new(GstVaapiDisplay *display, guint width, guint height); +gst_vaapi_window_wayland_new (GstVaapiDisplay * display, guint width, + guint height); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 482033ee6b..20470edc5d 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -43,550 +43,503 @@ #define DEBUG 1 #include "gstvaapidebug.h" -#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ -#define _NET_WM_STATE_ADD 1 /* add/set property */ -#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ +#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ +#define _NET_WM_STATE_ADD 1 /* add/set property */ +#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ static void -send_wmspec_change_state(GstVaapiWindow *window, Atom state, gboolean add) +send_wmspec_change_state (GstVaapiWindow * window, Atom state, gboolean add) { - GstVaapiWindowX11Private * const priv = - GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - XClientMessageEvent xclient; + GstVaapiWindowX11Private *const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + XClientMessageEvent xclient; - memset(&xclient, 0, sizeof(xclient)); + memset (&xclient, 0, sizeof (xclient)); - xclient.type = ClientMessage; - xclient.window = GST_VAAPI_OBJECT_ID(window); - xclient.message_type = priv->atom_NET_WM_STATE; - xclient.format = 32; + xclient.type = ClientMessage; + xclient.window = GST_VAAPI_OBJECT_ID (window); + xclient.message_type = priv->atom_NET_WM_STATE; + xclient.format = 32; - xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; - xclient.data.l[1] = state; - xclient.data.l[2] = 0; - xclient.data.l[3] = 0; - xclient.data.l[4] = 0; + xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + xclient.data.l[1] = state; + xclient.data.l[2] = 0; + xclient.data.l[3] = 0; + xclient.data.l[4] = 0; - XSendEvent( - dpy, - DefaultRootWindow(dpy), - False, - SubstructureRedirectMask|SubstructureNotifyMask, - (XEvent *)&xclient - ); + XSendEvent (dpy, + DefaultRootWindow (dpy), + False, + SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *) & xclient); } static void -wait_event(GstVaapiWindow *window, int type) +wait_event (GstVaapiWindow * window, int type) { - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - const Window xid = GST_VAAPI_OBJECT_ID(window); - XEvent e; - Bool got_event; + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + const Window xid = GST_VAAPI_OBJECT_ID (window); + XEvent e; + Bool got_event; - for (;;) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - got_event = XCheckTypedWindowEvent(dpy, xid, type, &e); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - if (got_event) - break; - g_usleep(10); - } -} - -static gboolean -timed_wait_event(GstVaapiWindow *window, int type, guint64 end_time, XEvent *e) -{ - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - const Window xid = GST_VAAPI_OBJECT_ID(window); - XEvent tmp_event; - GTimeVal now; - guint64 now_time; - Bool got_event; - - if (!e) - e = &tmp_event; - - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - got_event = XCheckTypedWindowEvent(dpy, xid, type, e); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + for (;;) { + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + got_event = XCheckTypedWindowEvent (dpy, xid, type, &e); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); if (got_event) - return TRUE; - - do { - g_usleep(10); - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - got_event = XCheckTypedWindowEvent(dpy, xid, type, e); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - if (got_event) - return TRUE; - g_get_current_time(&now); - now_time = (guint64)now.tv_sec * 1000000 + now.tv_usec; - } while (now_time < end_time); - return FALSE; + break; + g_usleep (10); + } } static gboolean -gst_vaapi_window_x11_show(GstVaapiWindow *window) +timed_wait_event (GstVaapiWindow * window, int type, guint64 end_time, + XEvent * e) { - GstVaapiWindowX11Private * const priv = - GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - const Window xid = GST_VAAPI_OBJECT_ID(window); - XWindowAttributes wattr; - gboolean has_errors; + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + const Window xid = GST_VAAPI_OBJECT_ID (window); + XEvent tmp_event; + GTimeVal now; + guint64 now_time; + Bool got_event; - if (priv->is_mapped) - return TRUE; + if (!e) + e = &tmp_event; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - x11_trap_errors(); - if (window->use_foreign_window) { - XGetWindowAttributes(dpy, xid, &wattr); - if (!(wattr.your_event_mask & StructureNotifyMask)) - XSelectInput(dpy, xid, StructureNotifyMask); - } - XMapWindow(dpy, xid); - has_errors = x11_untrap_errors() != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + got_event = XCheckTypedWindowEvent (dpy, xid, type, e); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + if (got_event) + return TRUE; - if (!has_errors) { - wait_event(window, MapNotify); - if (window->use_foreign_window && - !(wattr.your_event_mask & StructureNotifyMask)) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - x11_trap_errors(); - XSelectInput(dpy, xid, wattr.your_event_mask); - has_errors = x11_untrap_errors() != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - } - priv->is_mapped = TRUE; - - if (priv->fullscreen_on_map) - gst_vaapi_window_set_fullscreen(window, TRUE); - } - return !has_errors; + do { + g_usleep (10); + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + got_event = XCheckTypedWindowEvent (dpy, xid, type, e); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + if (got_event) + return TRUE; + g_get_current_time (&now); + now_time = (guint64) now.tv_sec * 1000000 + now.tv_usec; + } while (now_time < end_time); + return FALSE; } static gboolean -gst_vaapi_window_x11_hide(GstVaapiWindow *window) +gst_vaapi_window_x11_show (GstVaapiWindow * window) { - GstVaapiWindowX11Private * const priv = - GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - const Window xid = GST_VAAPI_OBJECT_ID(window); - XWindowAttributes wattr; - gboolean has_errors; + GstVaapiWindowX11Private *const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + const Window xid = GST_VAAPI_OBJECT_ID (window); + XWindowAttributes wattr; + gboolean has_errors; - if (!priv->is_mapped) - return TRUE; + if (priv->is_mapped) + return TRUE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - x11_trap_errors(); - if (window->use_foreign_window) { - XGetWindowAttributes(dpy, xid, &wattr); - if (!(wattr.your_event_mask & StructureNotifyMask)) - XSelectInput(dpy, xid, StructureNotifyMask); + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + x11_trap_errors (); + if (window->use_foreign_window) { + XGetWindowAttributes (dpy, xid, &wattr); + if (!(wattr.your_event_mask & StructureNotifyMask)) + XSelectInput (dpy, xid, StructureNotifyMask); + } + XMapWindow (dpy, xid); + has_errors = x11_untrap_errors () != 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + + if (!has_errors) { + wait_event (window, MapNotify); + if (window->use_foreign_window && + !(wattr.your_event_mask & StructureNotifyMask)) { + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + x11_trap_errors (); + XSelectInput (dpy, xid, wattr.your_event_mask); + has_errors = x11_untrap_errors () != 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); } - XUnmapWindow(dpy, xid); - has_errors = x11_untrap_errors() != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + priv->is_mapped = TRUE; - if (!has_errors) { - wait_event(window, UnmapNotify); - if (window->use_foreign_window && - !(wattr.your_event_mask & StructureNotifyMask)) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - x11_trap_errors(); - XSelectInput(dpy, xid, wattr.your_event_mask); - has_errors = x11_untrap_errors() != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - } - priv->is_mapped = FALSE; - } - return !has_errors; + if (priv->fullscreen_on_map) + gst_vaapi_window_set_fullscreen (window, TRUE); + } + return !has_errors; } static gboolean -gst_vaapi_window_x11_create(GstVaapiWindow *window, guint *width, guint *height) +gst_vaapi_window_x11_hide (GstVaapiWindow * window) { - GstVaapiWindowX11Private * const priv = - GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - Window xid = GST_VAAPI_OBJECT_ID(window); - Visual *vis = NULL; - Colormap cmap = None; - const GstVaapiWindowX11Class *klass; - XWindowAttributes wattr; - Atom atoms[2]; - gboolean ok; + GstVaapiWindowX11Private *const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + const Window xid = GST_VAAPI_OBJECT_ID (window); + XWindowAttributes wattr; + gboolean has_errors; - static const char *atom_names[2] = { - "_NET_WM_STATE", - "_NET_WM_STATE_FULLSCREEN", - }; + if (!priv->is_mapped) + return TRUE; - priv->has_xrender = GST_VAAPI_DISPLAY_HAS_XRENDER( - GST_VAAPI_OBJECT_DISPLAY(window)); + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + x11_trap_errors (); + if (window->use_foreign_window) { + XGetWindowAttributes (dpy, xid, &wattr); + if (!(wattr.your_event_mask & StructureNotifyMask)) + XSelectInput (dpy, xid, StructureNotifyMask); + } + XUnmapWindow (dpy, xid); + has_errors = x11_untrap_errors () != 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); - if (window->use_foreign_window && xid) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - XGetWindowAttributes(dpy, xid, &wattr); - priv->is_mapped = wattr.map_state == IsViewable; - ok = x11_get_geometry(dpy, xid, NULL, NULL, width, height, NULL); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - return ok; + if (!has_errors) { + wait_event (window, UnmapNotify); + if (window->use_foreign_window && + !(wattr.your_event_mask & StructureNotifyMask)) { + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + x11_trap_errors (); + XSelectInput (dpy, xid, wattr.your_event_mask); + has_errors = x11_untrap_errors () != 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); } + priv->is_mapped = FALSE; + } + return !has_errors; +} - klass = GST_VAAPI_WINDOW_X11_GET_CLASS(window); - if (klass) { - if (klass->get_visual) - vis = klass->get_visual(window); - if (klass->get_colormap) - cmap = klass->get_colormap(window); - } +static gboolean +gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, + guint * height) +{ + GstVaapiWindowX11Private *const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Window xid = GST_VAAPI_OBJECT_ID (window); + Visual *vis = NULL; + Colormap cmap = None; + const GstVaapiWindowX11Class *klass; + XWindowAttributes wattr; + Atom atoms[2]; + gboolean ok; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - XInternAtoms( - dpy, - (char **)atom_names, G_N_ELEMENTS(atom_names), - False, - atoms - ); - priv->atom_NET_WM_STATE = atoms[0]; - priv->atom_NET_WM_STATE_FULLSCREEN = atoms[1]; + static const char *atom_names[2] = { + "_NET_WM_STATE", + "_NET_WM_STATE_FULLSCREEN", + }; - xid = x11_create_window(dpy, *width, *height, vis, cmap); - if (xid) - XRaiseWindow(dpy, xid); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); + priv->has_xrender = + GST_VAAPI_DISPLAY_HAS_XRENDER (GST_VAAPI_OBJECT_DISPLAY (window)); - GST_DEBUG("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(xid)); - GST_VAAPI_OBJECT_ID(window) = xid; - return xid != None; + if (window->use_foreign_window && xid) { + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + XGetWindowAttributes (dpy, xid, &wattr); + priv->is_mapped = wattr.map_state == IsViewable; + ok = x11_get_geometry (dpy, xid, NULL, NULL, width, height, NULL); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + return ok; + } + + klass = GST_VAAPI_WINDOW_X11_GET_CLASS (window); + if (klass) { + if (klass->get_visual) + vis = klass->get_visual (window); + if (klass->get_colormap) + cmap = klass->get_colormap (window); + } + + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + XInternAtoms (dpy, + (char **) atom_names, G_N_ELEMENTS (atom_names), False, atoms); + priv->atom_NET_WM_STATE = atoms[0]; + priv->atom_NET_WM_STATE_FULLSCREEN = atoms[1]; + + xid = x11_create_window (dpy, *width, *height, vis, cmap); + if (xid) + XRaiseWindow (dpy, xid); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + + GST_DEBUG ("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (xid)); + GST_VAAPI_OBJECT_ID (window) = xid; + return xid != None; } static void -gst_vaapi_window_x11_destroy(GstVaapiWindow *window) +gst_vaapi_window_x11_destroy (GstVaapiWindow * window) { - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - const Window xid = GST_VAAPI_OBJECT_ID(window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + const Window xid = GST_VAAPI_OBJECT_ID (window); #ifdef HAVE_XRENDER - GstVaapiWindowX11Private * const priv = - GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); - if (priv->picture) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - XRenderFreePicture(dpy, priv->picture); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - priv->picture = None; - } + GstVaapiWindowX11Private *const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); + if (priv->picture) { + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + XRenderFreePicture (dpy, priv->picture); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + priv->picture = None; + } #endif - if (xid) { - if (!window->use_foreign_window) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - XDestroyWindow(dpy, xid); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - } - GST_VAAPI_OBJECT_ID(window) = None; + if (xid) { + if (!window->use_foreign_window) { + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + XDestroyWindow (dpy, xid); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); } + GST_VAAPI_OBJECT_ID (window) = None; + } } static gboolean -gst_vaapi_window_x11_get_geometry( - GstVaapiWindow *window, - gint *px, - gint *py, - guint *pwidth, - guint *pheight) +gst_vaapi_window_x11_get_geometry (GstVaapiWindow * window, + gint * px, gint * py, guint * pwidth, guint * pheight) { - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - const Window xid = GST_VAAPI_OBJECT_ID(window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + const Window xid = GST_VAAPI_OBJECT_ID (window); - return x11_get_geometry(dpy, xid, px, py, pwidth, pheight, NULL); + return x11_get_geometry (dpy, xid, px, py, pwidth, pheight, NULL); } static gboolean -gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen) +gst_vaapi_window_x11_set_fullscreen (GstVaapiWindow * window, + gboolean fullscreen) { - GstVaapiWindowX11Private * const priv = - GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - const Window xid = GST_VAAPI_OBJECT_ID(window); - XEvent e; - guint width, height; - gboolean has_errors; - GTimeVal now; - guint64 end_time; + GstVaapiWindowX11Private *const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + const Window xid = GST_VAAPI_OBJECT_ID (window); + XEvent e; + guint width, height; + gboolean has_errors; + GTimeVal now; + guint64 end_time; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - x11_trap_errors(); - if (fullscreen) { - if (!priv->is_mapped) { - priv->fullscreen_on_map = TRUE; + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + x11_trap_errors (); + if (fullscreen) { + if (!priv->is_mapped) { + priv->fullscreen_on_map = TRUE; - XChangeProperty( - dpy, - xid, - priv->atom_NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, - (unsigned char *)&priv->atom_NET_WM_STATE_FULLSCREEN, 1 - ); - } - else { - send_wmspec_change_state( - window, - priv->atom_NET_WM_STATE_FULLSCREEN, - TRUE - ); - } + XChangeProperty (dpy, + xid, + priv->atom_NET_WM_STATE, XA_ATOM, 32, + PropModeReplace, + (unsigned char *) &priv->atom_NET_WM_STATE_FULLSCREEN, 1); + } else { + send_wmspec_change_state (window, + priv->atom_NET_WM_STATE_FULLSCREEN, TRUE); } - else { - if (!priv->is_mapped) { - priv->fullscreen_on_map = FALSE; + } else { + if (!priv->is_mapped) { + priv->fullscreen_on_map = FALSE; - XDeleteProperty( - dpy, - xid, - priv->atom_NET_WM_STATE - ); - } - else { - send_wmspec_change_state( - window, - priv->atom_NET_WM_STATE_FULLSCREEN, - FALSE - ); - } - } - XSync(dpy, False); - has_errors = x11_untrap_errors() != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - if (has_errors) - return FALSE; - - /* Try to wait for the completion of the fullscreen mode switch */ - if (!window->use_foreign_window && priv->is_mapped) { - const guint DELAY = 100000; /* 100 ms */ - g_get_current_time(&now); - end_time = DELAY + ((guint64)now.tv_sec * 1000000 + now.tv_usec); - while (timed_wait_event(window, ConfigureNotify, end_time, &e)) { - if (fullscreen) { - gst_vaapi_display_get_size( - GST_VAAPI_OBJECT_DISPLAY(window), - &width, - &height - ); - if (e.xconfigure.width == width && e.xconfigure.height == height) - return TRUE; - } - else { - gst_vaapi_window_get_size(window, &width, &height); - if (e.xconfigure.width != width || e.xconfigure.height != height) - return TRUE; - } - } + XDeleteProperty (dpy, xid, priv->atom_NET_WM_STATE); + } else { + send_wmspec_change_state (window, + priv->atom_NET_WM_STATE_FULLSCREEN, FALSE); } + } + XSync (dpy, False); + has_errors = x11_untrap_errors () != 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + if (has_errors) return FALSE; + + /* Try to wait for the completion of the fullscreen mode switch */ + if (!window->use_foreign_window && priv->is_mapped) { + const guint DELAY = 100000; /* 100 ms */ + g_get_current_time (&now); + end_time = DELAY + ((guint64) now.tv_sec * 1000000 + now.tv_usec); + while (timed_wait_event (window, ConfigureNotify, end_time, &e)) { + if (fullscreen) { + gst_vaapi_display_get_size (GST_VAAPI_OBJECT_DISPLAY (window), + &width, &height); + if (e.xconfigure.width == width && e.xconfigure.height == height) + return TRUE; + } else { + gst_vaapi_window_get_size (window, &width, &height); + if (e.xconfigure.width != width || e.xconfigure.height != height) + return TRUE; + } + } + } + return FALSE; } static gboolean -gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height) +gst_vaapi_window_x11_resize (GstVaapiWindow * window, guint width, guint height) { - gboolean has_errors; + gboolean has_errors; - if (!GST_VAAPI_OBJECT_ID(window)) - return FALSE; + if (!GST_VAAPI_OBJECT_ID (window)) + return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - x11_trap_errors(); - XResizeWindow( - GST_VAAPI_OBJECT_XDISPLAY(window), - GST_VAAPI_OBJECT_ID(window), - width, - height - ); - has_errors = x11_untrap_errors() != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - return !has_errors; + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + x11_trap_errors (); + XResizeWindow (GST_VAAPI_OBJECT_XDISPLAY (window), + GST_VAAPI_OBJECT_ID (window), width, height); + has_errors = x11_untrap_errors () != 0; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + return !has_errors; } static gboolean -gst_vaapi_window_x11_render( - GstVaapiWindow *window, - GstVaapiSurface *surface, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect, - guint flags -) +gst_vaapi_window_x11_render (GstVaapiWindow * window, + GstVaapiSurface * surface, + const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags) { - VASurfaceID surface_id; - VAStatus status; + VASurfaceID surface_id; + VAStatus status; - surface_id = GST_VAAPI_OBJECT_ID(surface); - if (surface_id == VA_INVALID_ID) - return FALSE; + surface_id = GST_VAAPI_OBJECT_ID (surface); + if (surface_id == VA_INVALID_ID) + return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - status = vaPutSurface( - GST_VAAPI_OBJECT_VADISPLAY(window), - surface_id, - GST_VAAPI_OBJECT_ID(window), - src_rect->x, - src_rect->y, - src_rect->width, - src_rect->height, - dst_rect->x, - dst_rect->y, - dst_rect->width, - dst_rect->height, - NULL, 0, - from_GstVaapiSurfaceRenderFlags(flags) - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - if (!vaapi_check_status(status, "vaPutSurface()")) - return FALSE; + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (window), + surface_id, + GST_VAAPI_OBJECT_ID (window), + src_rect->x, + src_rect->y, + src_rect->width, + src_rect->height, + dst_rect->x, + dst_rect->y, + dst_rect->width, + dst_rect->height, NULL, 0, from_GstVaapiSurfaceRenderFlags (flags) + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + if (!vaapi_check_status (status, "vaPutSurface()")) + return FALSE; - return TRUE; + return TRUE; } static gboolean -gst_vaapi_window_x11_render_pixmap_xrender( - GstVaapiWindow *window, - GstVaapiPixmap *pixmap, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect -) +gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window, + GstVaapiPixmap * pixmap, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) { #ifdef HAVE_XRENDER - GstVaapiWindowX11Private * const priv = - GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window); - const Window win = GST_VAAPI_OBJECT_ID(window); - const Pixmap pix = GST_VAAPI_OBJECT_ID(pixmap); - Picture picture; - XRenderPictFormat *pic_fmt; - XWindowAttributes wattr; - int fmt, op; - gboolean success = FALSE; + GstVaapiWindowX11Private *const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); + Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + const Window win = GST_VAAPI_OBJECT_ID (window); + const Pixmap pix = GST_VAAPI_OBJECT_ID (pixmap); + Picture picture; + XRenderPictFormat *pic_fmt; + XWindowAttributes wattr; + int fmt, op; + gboolean success = FALSE; - /* Ensure Picture for window is created */ - if (!priv->picture) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - XGetWindowAttributes(dpy, win, &wattr); - pic_fmt = XRenderFindVisualFormat(dpy, wattr.visual); - if (pic_fmt) - priv->picture = XRenderCreatePicture(dpy, win, pic_fmt, 0, NULL); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - if (!priv->picture) - return FALSE; - } + /* Ensure Picture for window is created */ + if (!priv->picture) { + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + XGetWindowAttributes (dpy, win, &wattr); + pic_fmt = XRenderFindVisualFormat (dpy, wattr.visual); + if (pic_fmt) + priv->picture = XRenderCreatePicture (dpy, win, pic_fmt, 0, NULL); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + if (!priv->picture) + return FALSE; + } - /* Check pixmap format */ - switch (GST_VAAPI_PIXMAP_FORMAT(pixmap)) { + /* Check pixmap format */ + switch (GST_VAAPI_PIXMAP_FORMAT (pixmap)) { case GST_VIDEO_FORMAT_xRGB: - fmt = PictStandardRGB24; - op = PictOpSrc; - goto get_pic_fmt; + fmt = PictStandardRGB24; + op = PictOpSrc; + goto get_pic_fmt; case GST_VIDEO_FORMAT_ARGB: - fmt = PictStandardARGB32; - op = PictOpOver; + fmt = PictStandardARGB32; + op = PictOpOver; get_pic_fmt: - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - pic_fmt = XRenderFindStandardFormat(dpy, fmt); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - break; + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + pic_fmt = XRenderFindStandardFormat (dpy, fmt); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + break; default: - pic_fmt = NULL; - break; - } - if (!pic_fmt) - return FALSE; - - GST_VAAPI_OBJECT_LOCK_DISPLAY(window); - do { - const double sx = (double)src_rect->width / dst_rect->width; - const double sy = (double)src_rect->height / dst_rect->height; - XTransform xform; - - picture = XRenderCreatePicture(dpy, pix, pic_fmt, 0, NULL); - if (!picture) - break; - - xform.matrix[0][0] = XDoubleToFixed(sx); - xform.matrix[0][1] = XDoubleToFixed(0.0); - xform.matrix[0][2] = XDoubleToFixed(src_rect->x); - xform.matrix[1][0] = XDoubleToFixed(0.0); - xform.matrix[1][1] = XDoubleToFixed(sy); - xform.matrix[1][2] = XDoubleToFixed(src_rect->y); - xform.matrix[2][0] = XDoubleToFixed(0.0); - xform.matrix[2][1] = XDoubleToFixed(0.0); - xform.matrix[2][2] = XDoubleToFixed(1.0); - XRenderSetPictureTransform(dpy, picture, &xform); - - XRenderComposite(dpy, op, picture, None, priv->picture, - 0, 0, 0, 0, dst_rect->x, dst_rect->y, - dst_rect->width, dst_rect->height); - XSync(dpy, False); - success = TRUE; - } while (0); - if (picture) - XRenderFreePicture(dpy, picture); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - return success; -#endif + pic_fmt = NULL; + break; + } + if (!pic_fmt) return FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + do { + const double sx = (double) src_rect->width / dst_rect->width; + const double sy = (double) src_rect->height / dst_rect->height; + XTransform xform; + + picture = XRenderCreatePicture (dpy, pix, pic_fmt, 0, NULL); + if (!picture) + break; + + xform.matrix[0][0] = XDoubleToFixed (sx); + xform.matrix[0][1] = XDoubleToFixed (0.0); + xform.matrix[0][2] = XDoubleToFixed (src_rect->x); + xform.matrix[1][0] = XDoubleToFixed (0.0); + xform.matrix[1][1] = XDoubleToFixed (sy); + xform.matrix[1][2] = XDoubleToFixed (src_rect->y); + xform.matrix[2][0] = XDoubleToFixed (0.0); + xform.matrix[2][1] = XDoubleToFixed (0.0); + xform.matrix[2][2] = XDoubleToFixed (1.0); + XRenderSetPictureTransform (dpy, picture, &xform); + + XRenderComposite (dpy, op, picture, None, priv->picture, + 0, 0, 0, 0, dst_rect->x, dst_rect->y, + dst_rect->width, dst_rect->height); + XSync (dpy, False); + success = TRUE; + } while (0); + if (picture) + XRenderFreePicture (dpy, picture); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + return success; +#endif + return FALSE; } static gboolean -gst_vaapi_window_x11_render_pixmap( - GstVaapiWindow *window, - GstVaapiPixmap *pixmap, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect -) +gst_vaapi_window_x11_render_pixmap (GstVaapiWindow * window, + GstVaapiPixmap * pixmap, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) { - GstVaapiWindowX11Private * const priv = - GST_VAAPI_WINDOW_X11_GET_PRIVATE(window); + GstVaapiWindowX11Private *const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - if (priv->has_xrender) - return gst_vaapi_window_x11_render_pixmap_xrender(window, pixmap, - src_rect, dst_rect); + if (priv->has_xrender) + return gst_vaapi_window_x11_render_pixmap_xrender (window, pixmap, + src_rect, dst_rect); - /* XXX: only X RENDER extension is supported for now */ - return FALSE; + /* XXX: only X RENDER extension is supported for now */ + return FALSE; } void -gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass) +gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass) { - GstVaapiObjectClass * const object_class = - GST_VAAPI_OBJECT_CLASS(klass); - GstVaapiWindowClass * const window_class = - GST_VAAPI_WINDOW_CLASS(klass); + GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); + GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); - object_class->finalize = (GstVaapiObjectFinalizeFunc) - gst_vaapi_window_x11_destroy; + object_class->finalize = (GstVaapiObjectFinalizeFunc) + gst_vaapi_window_x11_destroy; - window_class->create = gst_vaapi_window_x11_create; - window_class->show = gst_vaapi_window_x11_show; - window_class->hide = gst_vaapi_window_x11_hide; - window_class->get_geometry = gst_vaapi_window_x11_get_geometry; - window_class->set_fullscreen = gst_vaapi_window_x11_set_fullscreen; - window_class->resize = gst_vaapi_window_x11_resize; - window_class->render = gst_vaapi_window_x11_render; - window_class->render_pixmap = gst_vaapi_window_x11_render_pixmap; + window_class->create = gst_vaapi_window_x11_create; + window_class->show = gst_vaapi_window_x11_show; + window_class->hide = gst_vaapi_window_x11_hide; + window_class->get_geometry = gst_vaapi_window_x11_get_geometry; + window_class->set_fullscreen = gst_vaapi_window_x11_set_fullscreen; + window_class->resize = gst_vaapi_window_x11_resize; + window_class->render = gst_vaapi_window_x11_render; + window_class->render_pixmap = gst_vaapi_window_x11_render_pixmap; } #define gst_vaapi_window_x11_finalize \ gst_vaapi_window_x11_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( - GstVaapiWindowX11, - gst_vaapi_window_x11, - gst_vaapi_window_x11_class_init(&g_class)) +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowX11, + gst_vaapi_window_x11, gst_vaapi_window_x11_class_init (&g_class)); /** * gst_vaapi_window_x11_new: @@ -601,14 +554,15 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( * Return value: the newly allocated #GstVaapiWindow object */ GstVaapiWindow * -gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) +gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height) { - GST_DEBUG("new window, size %ux%u", width, height); + GST_DEBUG ("new window, size %ux%u", width, height); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); - return gst_vaapi_window_new(GST_VAAPI_WINDOW_CLASS( - gst_vaapi_window_x11_class()), display, width, height); + return + gst_vaapi_window_new (GST_VAAPI_WINDOW_CLASS (gst_vaapi_window_x11_class + ()), display, width, height); } /** @@ -624,15 +578,16 @@ gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height) * Return value: the newly allocated #GstVaapiWindow object */ GstVaapiWindow * -gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) +gst_vaapi_window_x11_new_with_xid (GstVaapiDisplay * display, Window xid) { - GST_DEBUG("new window from xid 0x%08x", (guint)xid); + GST_DEBUG ("new window from xid 0x%08x", (guint) xid); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); - g_return_val_if_fail(xid != None, NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); + g_return_val_if_fail (xid != None, NULL); - return gst_vaapi_window_new_from_native(GST_VAAPI_WINDOW_CLASS( - gst_vaapi_window_x11_class()), display, GINT_TO_POINTER(xid)); + return + gst_vaapi_window_new_from_native (GST_VAAPI_WINDOW_CLASS + (gst_vaapi_window_x11_class ()), display, GINT_TO_POINTER (xid)); } /** @@ -646,11 +601,11 @@ gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid) * Return value: the underlying X11 #Window bound to @window. */ Window -gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window) +gst_vaapi_window_x11_get_xid (GstVaapiWindowX11 * window) { - g_return_val_if_fail(window != NULL, None); + g_return_val_if_fail (window != NULL, None); - return GST_VAAPI_OBJECT_ID(window); + return GST_VAAPI_OBJECT_ID (window); } /** @@ -663,9 +618,9 @@ gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window) * caller (foreign window) */ gboolean -gst_vaapi_window_x11_is_foreign_xid(GstVaapiWindowX11 *window) +gst_vaapi_window_x11_is_foreign_xid (GstVaapiWindowX11 * window) { - g_return_val_if_fail(window != NULL, FALSE); + g_return_val_if_fail (window != NULL, FALSE); - return GST_VAAPI_WINDOW(window)->use_foreign_window; + return GST_VAAPI_WINDOW (window)->use_foreign_window; } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index a6fcaf0416..8b32e33b7d 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -43,19 +43,19 @@ G_BEGIN_DECLS #define GST_VAAPI_WINDOW_XWINDOW(window) \ gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(window)) -typedef struct _GstVaapiWindowX11 GstVaapiWindowX11; +typedef struct _GstVaapiWindowX11 GstVaapiWindowX11; GstVaapiWindow * -gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height); +gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height); GstVaapiWindow * -gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid); +gst_vaapi_window_x11_new_with_xid (GstVaapiDisplay * display, Window xid); Window -gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window); +gst_vaapi_window_x11_get_xid (GstVaapiWindowX11 * window); gboolean -gst_vaapi_window_x11_is_foreign_xid(GstVaapiWindowX11 *window); +gst_vaapi_window_x11_is_foreign_xid (GstVaapiWindowX11 * window); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index a72bc88721..c14191f99a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -42,18 +42,19 @@ G_BEGIN_DECLS #define GST_VAAPI_WINDOW_X11_GET_CLASS(obj) \ GST_VAAPI_WINDOW_X11_CLASS(GST_VAAPI_WINDOW_GET_CLASS(obj)) -typedef struct _GstVaapiWindowX11Private GstVaapiWindowX11Private; -typedef struct _GstVaapiWindowX11Class GstVaapiWindowX11Class; +typedef struct _GstVaapiWindowX11Private GstVaapiWindowX11Private; +typedef struct _GstVaapiWindowX11Class GstVaapiWindowX11Class; -struct _GstVaapiWindowX11Private { - Atom atom_NET_WM_STATE; - Atom atom_NET_WM_STATE_FULLSCREEN; +struct _GstVaapiWindowX11Private +{ + Atom atom_NET_WM_STATE; + Atom atom_NET_WM_STATE_FULLSCREEN; #ifdef HAVE_XRENDER - Picture picture; + Picture picture; #endif - guint is_mapped : 1; - guint fullscreen_on_map : 1; - guint has_xrender : 1; + guint is_mapped:1; + guint fullscreen_on_map:1; + guint has_xrender:1; }; /** @@ -61,11 +62,12 @@ struct _GstVaapiWindowX11Private { * * An X11 #Window wrapper. */ -struct _GstVaapiWindowX11 { - /*< private >*/ - GstVaapiWindow parent_instance; +struct _GstVaapiWindowX11 +{ + /*< private >*/ + GstVaapiWindow parent_instance; - GstVaapiWindowX11Private priv; + GstVaapiWindowX11Private priv; }; /** @@ -77,16 +79,17 @@ struct _GstVaapiWindowX11 { * * An X11 #Window wrapper class. */ -struct _GstVaapiWindowX11Class { - /*< private >*/ - GstVaapiWindowClass parent_class; +struct _GstVaapiWindowX11Class +{ + /*< private >*/ + GstVaapiWindowClass parent_class; - Visual * (*get_visual) (GstVaapiWindow *window); - Colormap (*get_colormap) (GstVaapiWindow *window); + Visual *(*get_visual) (GstVaapiWindow * window); + Colormap (*get_colormap) (GstVaapiWindow * window); }; void -gst_vaapi_window_x11_class_init(GstVaapiWindowX11Class *klass); +gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass); G_END_DECLS From 08dc3036f45fa9222b531f68e8913a52edb5d821 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Mon, 29 Jul 2013 09:28:28 +0200 Subject: [PATCH 1725/3781] window: allow for updating size from current geometry. Add gst_vaapi_window_reconfigure() interface to force an update of the GstVaapiWindow "soft" size, based on the current geometry of the underlying native window. This can be useful for instance to synchronize the window size when the user changed it. Thanks to Fabrice Bellet for rebasing the patch. [changed interface to gst_vaapi_window_reconfigure()] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapiwindow.c | 16 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index b9a668abd5..7ebbdac9fe 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -483,3 +483,19 @@ gst_vaapi_window_put_pixmap (GstVaapiWindow * window, } return klass->render_pixmap (window, pixmap, src_rect, dst_rect); } + +/** + * gst_vaapi_window_reconfigure: + * @window: a #GstVaapiWindow + * + * Updates internal window size from geometry of the underlying window + * implementation if necessary. + */ +void +gst_vaapi_window_reconfigure (GstVaapiWindow * window) +{ + g_return_if_fail (window != NULL); + + window->check_geometry = TRUE; + gst_vaapi_window_ensure_size (window); +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 7b7cbfee26..84a6ef8db2 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -93,6 +93,9 @@ gboolean gst_vaapi_window_put_pixmap (GstVaapiWindow * window, GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect); +void +gst_vaapi_window_reconfigure (GstVaapiWindow * window); + G_END_DECLS #endif /* GST_VAAPI_WINDOW_H */ From b8040b35c1a465d189f1573bc3521d4faaf70621 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Jul 2014 17:29:40 +0200 Subject: [PATCH 1726/3781] window: make gst_vaapi_window_reconfigure() thread-safe. Ensure the X11 implementation for GstVaapiWindow::get_geometry() is thread-safe by default, so that upper layer users don't need to handle that explicitly. --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 20470edc5d..776c7d8784 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -295,8 +295,12 @@ gst_vaapi_window_x11_get_geometry (GstVaapiWindow * window, { Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); const Window xid = GST_VAAPI_OBJECT_ID (window); + gboolean success; - return x11_get_geometry (dpy, xid, px, py, pwidth, pheight, NULL); + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + success = x11_get_geometry (dpy, xid, px, py, pwidth, pheight, NULL); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + return success; } static gboolean From 5ffa82b64cd1a45794d66fcd09b7ccc65eeec787 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 25 Jul 2014 11:13:29 +0200 Subject: [PATCH 1727/3781] vaapisink: add support for "display-name" property. Add a "display-name" property to vaapisink so that the end user could select the desired output. Keep "display-name" in-line with the existing "display" (GstVaapiDisplayXXX type). So, for X11 or GLX, the "display-name" is the usual display name as we know for XOpenDisplay(); for Wayland, the "display-name" is the name used for wl_display_connect(); and for DRM, the "display-name" is actually the DRI device name. https://bugzilla.gnome.org/show_bug.cgi?id=722247 --- gst/vaapi/gstvaapipluginbase.c | 48 ++++++++++++++++++++++++++++------ gst/vaapi/gstvaapipluginbase.h | 8 ++++++ gst/vaapi/gstvaapipluginutil.c | 7 ++--- gst/vaapi/gstvaapisink.c | 17 ++++++++++++ 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 5cb2796176..c5689e3637 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -54,6 +54,25 @@ implements_interface_init (GstImplementsInterfaceClass * iface) #endif /* GstVideoContext interface */ +static void +plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) +{ + const gchar *const display_name = + gst_vaapi_display_get_display_name (display); + + if (plugin->display_name && g_strcmp0 (plugin->display_name, display_name)) { + GST_DEBUG_OBJECT (plugin, "incompatible display name '%s', requested '%s'", + display_name, plugin->display_name); + gst_vaapi_display_replace (&plugin->display, NULL); + } else { + GST_INFO_OBJECT (plugin, "set display %p", display); + gst_vaapi_display_replace (&plugin->display, display); + plugin->display_type = gst_vaapi_display_get_display_type (display); + gst_vaapi_plugin_base_set_display_name (plugin, display_name); + } + gst_vaapi_display_unref (display); +} + #if GST_CHECK_VERSION(1,1,0) static void plugin_set_context (GstElement * element, GstContext * context) @@ -61,12 +80,8 @@ plugin_set_context (GstElement * element, GstContext * context) GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); GstVaapiDisplay *display = NULL; - if (gst_vaapi_video_context_get_display (context, &display)) { - GST_INFO_OBJECT (element, "set display %p", display); - gst_vaapi_display_replace (&plugin->display, display); - gst_vaapi_display_unref (display); - plugin->display_type = gst_vaapi_display_get_display_type (display); - } + if (gst_vaapi_video_context_get_display (context, &display)) + plugin_set_display (plugin, display); } #else static void @@ -74,9 +89,10 @@ plugin_set_context (GstVideoContext * context, const gchar * type, const GValue * value) { GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (context); + GstVaapiDisplay *display = NULL; - gst_vaapi_set_display (type, value, &plugin->display); - plugin->display_type = gst_vaapi_display_get_display_type (plugin->display); + gst_vaapi_set_display (type, value, &display); + plugin_set_display (plugin, display); } static void @@ -212,6 +228,22 @@ gst_vaapi_plugin_base_set_display_type (GstVaapiPluginBase * plugin, plugin->display_type_req = display_type; } +/** + * gst_vaapi_plugin_base_set_display_name: + * @plugin: a #GstVaapiPluginBase + * @display_name: the new display name to match + * + * Sets the name of the display to look for. The change is effective + * at the next call to gst_vaapi_plugin_base_ensure_display(). + */ +void +gst_vaapi_plugin_base_set_display_name (GstVaapiPluginBase * plugin, + const gchar * display_name) +{ + g_free (plugin->display_name); + plugin->display_name = g_strdup (display_name); +} + /** * gst_vaapi_plugin_base_ensure_display: * @plugin: a #GstVaapiPluginBase diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 6c8abcf658..f0ee4295c9 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -93,6 +93,8 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (GST_VAAPI_PLUGIN_BASE(plugin)->display) #define GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->display_type) +#define GST_VAAPI_PLUGIN_BASE_DISPLAY_NAME(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->display_name) #define GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(plugin, new_display) \ (gst_vaapi_display_replace(&GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin), \ (new_display))) @@ -137,6 +139,7 @@ struct _GstVaapiPluginBase GstVaapiDisplay *display; GstVaapiDisplayType display_type; GstVaapiDisplayType display_type_req; + gchar *display_name; GstVaapiUploader *uploader; gboolean uploader_used; @@ -188,6 +191,11 @@ void gst_vaapi_plugin_base_set_display_type (GstVaapiPluginBase * plugin, GstVaapiDisplayType display_type); +G_GNUC_INTERNAL +void +gst_vaapi_plugin_base_set_display_name (GstVaapiPluginBase * plugin, + const gchar * display_name); + G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index fe84771839..8d0b186c1f 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -90,7 +90,8 @@ static const DisplayMap g_display_map[] = { }; static GstVaapiDisplay * -gst_vaapi_create_display (GstVaapiDisplayType display_type) +gst_vaapi_create_display (GstVaapiDisplayType display_type, + const gchar * display_name) { GstVaapiDisplay *display = NULL; const DisplayMap *m; @@ -99,7 +100,7 @@ gst_vaapi_create_display (GstVaapiDisplayType display_type) if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY && display_type != m->type) continue; - display = m->create_display (NULL); + display = m->create_display (display_name); if (display || display_type != GST_VAAPI_DISPLAY_TYPE_ANY) break; } @@ -126,7 +127,7 @@ gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type) return TRUE; /* If no neighboor, or application not interested, use system default */ - display = gst_vaapi_create_display (type); + display = gst_vaapi_create_display (type, plugin->display_name); if (!display) return FALSE; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index ad4d8d7f77..8225fda175 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -128,6 +128,7 @@ enum { PROP_0, PROP_DISPLAY_TYPE, + PROP_DISPLAY_NAME, PROP_FULLSCREEN, PROP_SYNCHRONOUS, PROP_USE_GLX, @@ -1148,6 +1149,10 @@ gst_vaapisink_set_property( gst_vaapi_plugin_base_set_display_type(GST_VAAPI_PLUGIN_BASE(sink), g_value_get_enum(value)); break; + case PROP_DISPLAY_NAME: + gst_vaapi_plugin_base_set_display_name(GST_VAAPI_PLUGIN_BASE(sink), + g_value_get_string(value)); + break; case PROP_FULLSCREEN: sink->fullscreen = g_value_get_boolean(value); break; @@ -1186,6 +1191,9 @@ gst_vaapisink_get_property( case PROP_DISPLAY_TYPE: g_value_set_enum(value, GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)); break; + case PROP_DISPLAY_NAME: + g_value_set_string(value, GST_VAAPI_PLUGIN_BASE_DISPLAY_NAME(sink)); + break; case PROP_FULLSCREEN: g_value_set_boolean(value, sink->fullscreen); break; @@ -1277,6 +1285,15 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) GST_VAAPI_DISPLAY_TYPE_ANY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, + PROP_DISPLAY_NAME, + g_param_spec_string("display-name", + "display name", + "display name to use", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + #if USE_GLX g_object_class_install_property (object_class, From a26df804a6140be72fe9b75533530171235b7b6d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jul 2014 10:09:34 +0200 Subject: [PATCH 1728/3781] vaapisink: always keep the last displayed buffer around. Always record the VA surface that is currently being rendered, no matter the fact we are using texturedblit or overlay. That's because in some occasions, we need to refresh or resize the displayed contents based on new events. e.g. user-resized window. Besides, it's simpler to track the last video buffer in GstVaapiSink than through the base sink "last-sample". --- gst/vaapi/gstvaapisink.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 8225fda175..61d92ac892 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -211,26 +211,10 @@ static void gst_vaapisink_video_overlay_expose(GstVideoOverlay *overlay) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); - GstBaseSink * const base_sink = GST_BASE_SINK(overlay); - GstBuffer *buffer; - if (sink->use_overlay) - buffer = sink->video_buffer ? gst_buffer_ref(sink->video_buffer) : NULL; - else { -#if GST_CHECK_VERSION(1,0,0) - GstSample * const sample = gst_base_sink_get_last_sample(base_sink); - if (!sample) - return; - buffer = gst_buffer_ref(gst_sample_get_buffer(sample)); - gst_sample_unref(sample); -#else - buffer = gst_base_sink_get_last_buffer(base_sink); -#endif - } - if (buffer) { - gst_vaapisink_show_frame(base_sink, buffer); - gst_buffer_unref(buffer); - } + if (sink->video_buffer) + gst_vaapisink_show_frame(GST_BASE_SINK_CAST(sink), + gst_buffer_ref(sink->video_buffer)); } static void @@ -1075,8 +1059,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) goto error; /* Retain VA surface until the next one is displayed */ - if (sink->use_overlay) - gst_buffer_replace(&sink->video_buffer, buffer); + gst_buffer_replace(&sink->video_buffer, buffer); gst_buffer_unref(buffer); return GST_FLOW_OK; From aa2fab43bd8062de9671c8b74ed66d349fd3b8d6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jul 2014 10:25:26 +0200 Subject: [PATCH 1729/3781] vaapisink: allow a specific view component to be displayed. If a multiview stream is decoded, multiple view components are submitted as is downstream. It is the responsibility of the sink element to display the required view components. By default, always select the frame buffer that matches the view-id of the very first frame to be displayed. However, introduce a "view-id" property to allow the selection of a specific view component of interest to display. --- gst/vaapi/gstvaapisink.c | 40 ++++++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapisink.h | 1 + 2 files changed, 41 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 61d92ac892..76d8f47d03 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -135,6 +135,7 @@ enum { PROP_USE_REFLECTION, PROP_ROTATION, PROP_FORCE_ASPECT_RATIO, + PROP_VIEW_ID, }; #define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY @@ -965,6 +966,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstVaapiVideoMeta *meta; + GstVaapiSurfaceProxy *proxy; GstVaapiSurface *surface; GstBuffer *buffer; guint flags; @@ -974,6 +976,7 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) GstVaapiRectangle tmp_rect; #endif GstFlowReturn ret; + gint32 view_id; #if GST_CHECK_VERSION(1,0,0) GstVideoCropMeta * const crop_meta = @@ -998,6 +1001,19 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) gst_vaapisink_ensure_rotation(sink, TRUE); + proxy = gst_vaapi_video_meta_get_surface_proxy(meta); + if (!proxy) + goto error; + + /* Valide view component to display */ + view_id = GST_VAAPI_SURFACE_PROXY_VIEW_ID(proxy); + if (G_UNLIKELY(sink->view_id == -1)) + sink->view_id = view_id; + else if (sink->view_id != view_id) { + gst_buffer_unref(buffer); + return GST_FLOW_OK; + } + surface = gst_vaapi_video_meta_get_surface(meta); if (!surface) goto error; @@ -1142,6 +1158,9 @@ gst_vaapisink_set_property( case PROP_SYNCHRONOUS: sink->synchronous = g_value_get_boolean(value); break; + case PROP_VIEW_ID: + sink->view_id = g_value_get_int(value); + break; case PROP_USE_GLX: sink->use_glx = g_value_get_boolean(value); break; @@ -1183,6 +1202,9 @@ gst_vaapisink_get_property( case PROP_SYNCHRONOUS: g_value_set_boolean(value, sink->synchronous); break; + case PROP_VIEW_ID: + g_value_set_int(value, sink->view_id); + break; case PROP_USE_GLX: g_value_set_boolean(value, sink->use_glx); break; @@ -1350,6 +1372,23 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) "When enabled, scaling will respect original aspect ratio", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiSink:view-id: + * + * When not set to -1, the displayed frame will always be the one + * that matches the view-id of the very first displayed frame. Any + * other number will indicate the desire to display the supplied + * view-id only. + */ + g_object_class_install_property + (object_class, + PROP_VIEW_ID, + g_param_spec_int("view-id", + "View ID", + "ID of the view component of interest to display", + -1, G_MAXINT32, -1, + G_PARAM_READWRITE)); } static void @@ -1370,6 +1409,7 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->video_height = 0; sink->video_par_n = 1; sink->video_par_d = 1; + sink->view_id = -1; sink->foreign_window = FALSE; sink->fullscreen = FALSE; sink->synchronous = FALSE; diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index edd9c1487d..a41e740949 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -87,6 +87,7 @@ struct _GstVaapiSink { GstVaapiRotation rotation; GstVaapiRotation rotation_req; guint color_standard; + gint32 view_id; guint foreign_window : 1; guint fullscreen : 1; guint synchronous : 1; From f79337c7149322440c3c6702a17cfe9ba34e7fcf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jul 2014 11:35:24 +0200 Subject: [PATCH 1730/3781] configure: mark support for GStreamer 0.10 as obsolete. Support for GStreamer 0.10 is obsolete. i.e. it is no longer supported and may actually be removed altogether for a future release. There is no real point to maintain a build for such an ancient GStreamer version that is not even supported upstream. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 3e36f0f4fa..eaeaba8abe 100644 --- a/configure.ac +++ b/configure.ac @@ -256,7 +256,7 @@ AC_SUBST([GST_PKG_VERSION]) dnl Validate certain features if test "$USE_GST_API_0_10" = "yes"; then - AC_MSG_WARN([support for GStreamer 0.10 is deprecated, and will be removed]) + AC_MSG_WARN([support for GStreamer 0.10 is obsolete, and will be removed]) if test "$enable_builtin_videoparsers" = "yes"; then AC_MSG_WARN([disabled built-in videoparsers (unsupported)]) enable_builtin_videoparsers="no" From a6737ad43a09ecece53912c3e7dfdd672fa36c49 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jul 2014 11:39:11 +0200 Subject: [PATCH 1731/3781] configure: mark support for GStreamer < 1.2 as deprecated. Supporting anything thing below GStreamer 1.2 is asking for trouble for keeping up with the required facilities to make efficient pipelines. Users are invited to upgrade to the very latest GStreamer 1.2.x release, at the minimum. --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.ac b/configure.ac index eaeaba8abe..8e88ab068d 100644 --- a/configure.ac +++ b/configure.ac @@ -261,6 +261,8 @@ if test "$USE_GST_API_0_10" = "yes"; then AC_MSG_WARN([disabled built-in videoparsers (unsupported)]) enable_builtin_videoparsers="no" fi +elif test "$USE_GST_API_1_2p" != "yes"; then + AC_MSG_WARN([support for GStreamer < 1.2 is deprecated, please upgrade]) fi dnl GStreamer Core From 5c0ba60f6988e4da023a71b5122ba8d8e935be52 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jul 2014 11:52:06 +0200 Subject: [PATCH 1732/3781] NEWS: updates. --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index ae45bc7e99..f6d1481923 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ Copyright (C) 2011 Collabora Version 0.5.9 - DD.Jul.2014 * Add VP8 decoder (+Halley Zhao) * Add H.264 MVC decoder and encoder (+Sreerenj Balachandran, Xiaowei Li) +* Fix support for Firefox >= 30 when built with GStreamer 1.0 APIs * Improvements to H.264 decoder + Add support for grayscale encoded clips + Add minor optimizations to the parsing process @@ -13,7 +14,9 @@ Version 0.5.9 - DD.Jul.2014 + Fix multiple slices decoding with varying slice types [#724518] + Fix parsing of multiple SEI messages in single NAL units (Aurelien Zanelli) * Improvements to plugin elements + + Add download capability to vaapidecode [#733243] + Add support for crop regions in VPP mode [#720730] + + Allow selection of a particular "display-name" for vaapisink [#722247] + Fix support for headless pipelines, e.g. vaapisink display="drm" mode + Fix creation of output surface pool for vaapipostproc (Simon Farnsworth) + Fix vaapipostproc "deinterlace-mode" semantics (Simon Farnsworth) [#726361] From 690183a8fb9d693fb4ffcbb3994fee6206af20a3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 4 Mar 2014 19:40:59 +0100 Subject: [PATCH 1733/3781] debian: fix packaging for new naming scheme. --- configure.ac | 2 +- debian.upstream/Makefile.am | 2 +- debian.upstream/control.in | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 8e88ab068d..c98d08cebd 100644 --- a/configure.ac +++ b/configure.ac @@ -860,7 +860,7 @@ AC_CONFIG_FILES([ debian.upstream/gstreamer-vaapi-doc.install.in debian.upstream/gstreamer$GST_API_VERSION-vaapi.install:\ debian.upstream/gstreamer-vaapi.install.in - debian.upstream/libgstvaapi$GST_API_VERSION-dev.install:\ + debian.upstream/libgstvaapi$GST_PKG_VERSION-dev.install:\ debian.upstream/libgstvaapi-dev.install.in debian.upstream/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:\ debian.upstream/libgstvaapi.install.in diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index e4e606a193..455ed08217 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -26,7 +26,7 @@ DEBIANGENFILES = \ control \ gstreamer$(GST_API_VERSION)-vaapi-doc.install \ gstreamer$(GST_API_VERSION)-vaapi.install \ - libgstvaapi$(GST_API_VERSION)-dev.install \ + libgstvaapi$(GST_PKG_VERSION)-dev.install \ libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-drm-$(GST_VAAPI_MAJOR_VERSION).install \ libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 0d0f140000..0c1fadcdf4 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -92,7 +92,7 @@ Description: GStreamer libraries from the "vaapi" set @USE_WAYLAND_TRUE@ . @USE_WAYLAND_TRUE@ This package contains Wayland libraries for the "vaapi" set. -Package: libgstvaapi@GST_API_VERSION@-dev +Package: libgstvaapi@GST_PKG_VERSION@-dev Architecture: any Section: libdevel Depends: ${shlibs:Depends}, ${misc:Depends}, From 580100d7498f861b04e6e727a4fc71bd29df46b6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jul 2014 14:20:33 +0200 Subject: [PATCH 1734/3781] configure: fix build with GStreamer 1.4.0 release. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index c98d08cebd..b41d483f87 100644 --- a/configure.ac +++ b/configure.ac @@ -220,7 +220,7 @@ case $GST_API_VERSION in GST_PLUGINS_BASE_VERSION_REQUIRED=gst12_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst12_plugins_bad_version ;; -1.3) +1.[[3-4]]) GST_VERSION_REQUIRED=gst14_version GST_PLUGINS_BASE_VERSION_REQUIRED=gst14_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst14_plugins_bad_version @@ -473,7 +473,7 @@ case $GST_API_VERSION in 0.10) lt_bias=gst0_vaapi_lt_current_bias;; 1.0) lt_bias=gst1_vaapi_lt_current_bias;; 1.2) lt_bias=gst2_vaapi_lt_current_bias;; -1.3) lt_bias=gst4_vaapi_lt_current_bias;; +1.[[3-4]]) lt_bias=gst4_vaapi_lt_current_bias;; esac GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - "$lt_bias"` AC_SUBST(GST_VAAPI_MAJOR_VERSION) From 883ef9d436cc31eca6cd3a5ba84673fc7aecd805 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 28 Jul 2014 15:54:46 +0300 Subject: [PATCH 1735/3781] configure: allow builds against GStreamer git (1.5.x). https://bugzilla.gnome.org/show_bug.cgi?id=733688 --- configure.ac | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/configure.ac b/configure.ac index b41d483f87..1327806e35 100644 --- a/configure.ac +++ b/configure.ac @@ -15,6 +15,7 @@ m4_define([gst0_vaapi_lt_current_bias], [0]) m4_define([gst1_vaapi_lt_current_bias], [2]) m4_define([gst2_vaapi_lt_current_bias], [4]) m4_define([gst4_vaapi_lt_current_bias], [5]) +m4_define([gst6_vaapi_lt_current_bias], [5]) m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [0]) @@ -35,6 +36,9 @@ m4_define([gst12_plugins_bad_version], [1.1.0]) m4_define([gst14_version], [1.2.90]) m4_define([gst14_plugins_base_version], [1.3.0]) m4_define([gst14_plugins_bad_version], [1.3.0]) +m4_define([gst16_version], [1.5.0]) +m4_define([gst16_plugins_base_version], [1.5.0]) +m4_define([gst16_plugins_bad_version], [1.5.0]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.0]) @@ -225,6 +229,11 @@ case $GST_API_VERSION in GST_PLUGINS_BASE_VERSION_REQUIRED=gst14_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst14_plugins_bad_version ;; +1.5) + GST_VERSION_REQUIRED=gst16_version + GST_PLUGINS_BASE_VERSION_REQUIRED=gst16_plugins_base_version + GST_PLUGINS_BAD_VERSION_REQUIRED=gst16_plugins_bad_version + ;; *) AC_MSG_ERROR([unsupported GStreamer API version $GST_API_VERSION]) ;; @@ -474,6 +483,7 @@ case $GST_API_VERSION in 1.0) lt_bias=gst1_vaapi_lt_current_bias;; 1.2) lt_bias=gst2_vaapi_lt_current_bias;; 1.[[3-4]]) lt_bias=gst4_vaapi_lt_current_bias;; +1.5) lt_bias=gst6_vaapi_lt_current_bias;; esac GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - "$lt_bias"` AC_SUBST(GST_VAAPI_MAJOR_VERSION) From c5102c72af9df7f508fe278054c45409c15ead24 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jul 2014 16:43:47 +0200 Subject: [PATCH 1736/3781] vaapidecode: fix auto-plugging of vaapisink element. Make sure to propagate memory:VASurface capsfeature to srcpad caps only for GStreamer >= 1.5 as the plug-in elements in GStreamer 1.4 core currently miss additional patches available in 1.5-git (1.6). This is a temporary workaround. --- gst/vaapi/gstvaapidecode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b5f7a40dc9..cc934e4f7c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -196,12 +196,12 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, default: if (format == GST_VIDEO_FORMAT_ENCODED) { /* XXX: this is a workaround until auto-plugging is fixed when - format=ENCODED + memory:VASurface caps feature are provided. - Meanwhile, providing a random format here works but this is - a terribly wrong thing per se. */ + format=ENCODED + memory:VASurface caps feature are provided. + Meanwhile, providing a random format here works but this is + a terribly wrong thing per se. */ gst_vaapidecode_video_info_change_format(&vis, out_format, GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); -#if GST_CHECK_VERSION(1,3,0) +#if GST_CHECK_VERSION(1,5,0) if (feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) features = gst_caps_features_new( GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL); From 0607898019b95b28a5edda2273831ec0d60ede6c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jul 2014 18:00:19 +0200 Subject: [PATCH 1737/3781] vaapidecode: simplify bufferpool configuration. Rework the logics behind the configuration of an adequate bufferpool, especially when OpenGL meta or additional capsfeatures are needed. Besides, for GStreamer >= 1.4, the first capsfeatures that gets matched, and that is not system memory, is now selected by default. --- gst/vaapi/gstvaapidecode.c | 49 +++++++++++++++++----------------- gst/vaapi/gstvaapipluginutil.c | 13 +++++++++ 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index cc934e4f7c..49dd455e1f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -517,11 +517,10 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gboolean need_pool, update_pool; gboolean has_video_meta = FALSE; gboolean has_video_alignment = FALSE; - GstVideoCodecState *state; #if GST_CHECK_VERSION(1,1,0) && USE_GLX gboolean has_texture_upload_meta = FALSE; - GstCapsFeatures *features, *features2; #endif + GstVideoCodecState *state; gst_query_parse_allocation(query, &caps, &need_pool); @@ -531,34 +530,27 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) state = gst_video_decoder_get_output_state(vdec); decode->has_texture_upload_meta = FALSE; - has_video_meta = gst_query_find_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL); + has_video_meta = gst_query_find_allocation_meta(query, + GST_VIDEO_META_API_TYPE, NULL); + #if GST_CHECK_VERSION(1,1,0) && USE_GLX - if (has_video_meta) - decode->has_texture_upload_meta = gst_query_find_allocation_meta(query, - GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); + has_texture_upload_meta = gst_query_find_allocation_meta(query, + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); - features = gst_caps_get_features(state->caps, 0); - features2 = gst_caps_features_new(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); - - has_texture_upload_meta = + decode->has_texture_upload_meta = gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec), GST_VIDEO_FORMAT_ENCODED) == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META; - - /* Update src caps if feature is not handled downstream */ - if (!decode->has_texture_upload_meta && - gst_caps_features_is_equal(features, features2)) - gst_vaapidecode_update_src_caps (decode, state); - else if (has_texture_upload_meta && - !gst_caps_features_is_equal(features, features2)) { - gst_video_info_set_format(&state->info, GST_VIDEO_FORMAT_RGBA, - state->info.width, - state->info.height); - gst_vaapidecode_update_src_caps(decode, state); - } - gst_caps_features_free(features2); #endif + /* Update src caps if feature is not handled downstream */ + if (!gst_caps_is_always_compatible(caps, state->caps)) { + if (decode->has_texture_upload_meta) + gst_video_info_set_format(&state->info, GST_VIDEO_FORMAT_RGBA, + GST_VIDEO_INFO_WIDTH(&state->info), + GST_VIDEO_INFO_HEIGHT(&state->info)); + gst_vaapidecode_update_src_caps(decode, state); + } gst_video_codec_state_unref(state); gst_video_info_init(&vi); @@ -609,7 +601,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); #if GST_CHECK_VERSION(1,1,0) && USE_GLX - if (decode->has_texture_upload_meta) + if (has_texture_upload_meta) gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); #endif @@ -622,6 +614,15 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gst_buffer_pool_set_config(pool, config); } +#if GST_CHECK_VERSION(1,1,0) && USE_GLX + if (decode->has_texture_upload_meta && !has_texture_upload_meta) { + config = gst_buffer_pool_get_config(pool); + gst_buffer_pool_config_add_option(config, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); + gst_buffer_pool_set_config(pool, config); + } +#endif + if (update_pool) gst_query_set_nth_allocation_pool(query, 0, pool, size, min, max); else diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 8d0b186c1f..7c3e35424a 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -541,6 +541,12 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format) GstCapsFeatures *const features = gst_caps_get_features (out_caps, i); GstStructure *const structure = gst_caps_get_structure (out_caps, i); +#if GST_CHECK_VERSION(1,3,0) + /* Skip ANY features, we need an exact match for correct evaluation */ + if (gst_caps_features_is_any (features)) + continue; +#endif + caps = gst_caps_new_full (gst_structure_copy (structure), NULL); if (!caps) continue; @@ -556,6 +562,13 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format) feature < GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; gst_caps_replace (&caps, NULL); + +#if GST_CHECK_VERSION(1,3,0) + /* Stop at the first match, the caps should already be sorted out + by preference order from downstream elements */ + if (feature != GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) + break; +#endif } cleanup: From b8601cf4c5cf87f178628207e4cee194d6e6ba02 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jul 2014 18:31:09 +0200 Subject: [PATCH 1738/3781] vaapisink: fix GstVideoOverlay::expose() implementation. Now that we always track the currently active video buffer, it is not necessary to automatically increase its reference since this is implicitly performed in ::show_frame() through the get_input_buffer() helper from GstVaapiPluginBase class. This is a regression from a26df80. --- gst/vaapi/gstvaapisink.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 76d8f47d03..3753d77527 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -214,8 +214,7 @@ gst_vaapisink_video_overlay_expose(GstVideoOverlay *overlay) GstVaapiSink * const sink = GST_VAAPISINK(overlay); if (sink->video_buffer) - gst_vaapisink_show_frame(GST_BASE_SINK_CAST(sink), - gst_buffer_ref(sink->video_buffer)); + gst_vaapisink_show_frame(GST_BASE_SINK_CAST(sink), sink->video_buffer); } static void From 1afcede093297173d75720e3f5551e1fa8dda2b5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Jul 2014 18:45:49 +0200 Subject: [PATCH 1739/3781] 0.5.9. --- NEWS | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index f6d1481923..344ad964d3 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ -gst-vaapi NEWS -- summary of changes. 2014-07-DD +gst-vaapi NEWS -- summary of changes. 2014-07-29 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora -Version 0.5.9 - DD.Jul.2014 +Version 0.5.9 - 29.Jul.2014 * Add VP8 decoder (+Halley Zhao) * Add H.264 MVC decoder and encoder (+Sreerenj Balachandran, Xiaowei Li) * Fix support for Firefox >= 30 when built with GStreamer 1.0 APIs diff --git a/configure.ac b/configure.ac index 1327806e35..774c7c9944 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [9]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 6003596e82b9aaaa699135f89bd7839ae7792cb7 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Tue, 29 Jul 2014 16:22:01 +1000 Subject: [PATCH 1740/3781] vaapidecode: properly return from decode loop on downstream errors. Fixes a hang/race on shutdown where _decode_loop() had already completed its execution and _finish() was waiting on a GCond for decode_loop() to complete. Also fixes the possible race where _finish() is called but _decode_loop() endlessly returns before signalling completion iff the decoder instance returns GST_FLOW_OK. Found with: ... ! vaapidecode ! {glimagesink,cluttersink} https://bugzilla.gnome.org/show_bug.cgi?id=733897 [factored out GST_VIDEO_DECODER_STREAM_UNLOCK() call] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapidecode.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 49dd455e1f..6d93f33d99 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -439,19 +439,20 @@ gst_vaapidecode_decode_loop(GstVaapiDecode *decode) decode->decoder_loop_status = ret; GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); - if (ret == GST_FLOW_OK) - return; - /* If invoked from gst_vaapidecode_finish(), then return right away no matter the errors, or the GstVaapiDecoder needs further data to complete decoding (there no more data to feed in) */ if (decode->decoder_finish) { g_mutex_lock(&decode->decoder_mutex); + decode->decoder_loop_status = GST_FLOW_EOS; g_cond_signal(&decode->decoder_finish_done); g_mutex_unlock(&decode->decoder_mutex); return; } + if (ret == GST_FLOW_OK) + return; + /* Suspend the task if an error occurred */ if (ret != GST_VIDEO_DECODER_FLOW_NEED_DATA) gst_pad_pause_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); @@ -494,13 +495,16 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) /* Make sure the decode loop function has a chance to return, thus possibly unlocking gst_video_decoder_finish_frame() */ - GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); - g_mutex_lock(&decode->decoder_mutex); decode->decoder_finish = TRUE; - g_cond_wait(&decode->decoder_finish_done, &decode->decoder_mutex); - g_mutex_unlock(&decode->decoder_mutex); - gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); - GST_VIDEO_DECODER_STREAM_LOCK(vdec); + if (decode->decoder_loop_status == GST_FLOW_OK) { + GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); + g_mutex_lock(&decode->decoder_mutex); + while (decode->decoder_loop_status != GST_FLOW_OK) + g_cond_wait(&decode->decoder_finish_done, &decode->decoder_mutex); + g_mutex_unlock(&decode->decoder_mutex); + gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); + GST_VIDEO_DECODER_STREAM_LOCK(vdec); + } return ret; } From 61dfd24ca1010c22a254c3071eb07eb2e18cad81 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 29 Jul 2014 10:31:15 +0200 Subject: [PATCH 1741/3781] NEWS: updates. --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 344ad964d3..e412563cc4 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ Version 0.5.9 - 29.Jul.2014 * Add VP8 decoder (+Halley Zhao) * Add H.264 MVC decoder and encoder (+Sreerenj Balachandran, Xiaowei Li) * Fix support for Firefox >= 30 when built with GStreamer 1.0 APIs +* Fix MPEG-4:2 decoder hang on skipped frames (Fabrice Bellet) [#733324] +* Fix MPEG-2 decoder to propagate PTS from demuxer (Jan Schmidt) [#732719] * Improvements to H.264 decoder + Add support for grayscale encoded clips + Add minor optimizations to the parsing process @@ -21,6 +23,7 @@ Version 0.5.9 - 29.Jul.2014 + Fix creation of output surface pool for vaapipostproc (Simon Farnsworth) + Fix vaapipostproc "deinterlace-mode" semantics (Simon Farnsworth) [#726361] + Fix memory leak in vaapidecode ! {glimagesink,cluttersink} (Matthew Waters) + + Fix vaapidecode hang when downstream errors out (Matthew Waters) [#733897] Version 0.5.8 - 23.Jan.2014 * Add H.264 video encoding (+Feng Yuan) From 49870b55fbb79e1b6f54236e2f832142808eda5b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 29 Jul 2014 10:31:58 +0200 Subject: [PATCH 1742/3781] AUTHORS: updates. --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index 81068dcac7..6eda1a05f1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -9,10 +9,12 @@ Contributors (sorted by first name): Cong Zhong Emilio Lopez +Fabrice Bellet Feng Yuan Guangxin Xu Haihao Xiang Holger Kaelberer +Jan Schmidt Javier Jardon Junfeng Xu Kristian Hogsberg From 05049864089a28a5ffbe8b8871d41cc61e2ce6b6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 29 Jul 2014 13:24:52 +0200 Subject: [PATCH 1743/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 774c7c9944..36285dc458 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [9]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [10]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 528f486513d406c45f1e30436f391f726bbb3b3d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 29 Jul 2014 15:47:46 +0200 Subject: [PATCH 1744/3781] vaapidecode: decode and output all pending frames on normal EOS. The gst_vaapidecode_decode_loop() function is called within a separate task to fetch and output all frames that were decoded so far. So, if the decoder_loop_status is forcibly set to EOS when _finish() is called, then we are bound to exist the task without submitting the pending frames. If the downstream element error'ed out, then the gst_pad_push() would propagate up an error and so we will get it right for cutting off _finish() early in that case. This is a regression from 6003596. https://bugzilla.gnome.org/show_bug.cgi?id=733897 --- gst/vaapi/gstvaapidecode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6d93f33d99..3891729e9a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -444,7 +444,6 @@ gst_vaapidecode_decode_loop(GstVaapiDecode *decode) data to complete decoding (there no more data to feed in) */ if (decode->decoder_finish) { g_mutex_lock(&decode->decoder_mutex); - decode->decoder_loop_status = GST_FLOW_EOS; g_cond_signal(&decode->decoder_finish_done); g_mutex_unlock(&decode->decoder_mutex); return; @@ -499,7 +498,7 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) if (decode->decoder_loop_status == GST_FLOW_OK) { GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); g_mutex_lock(&decode->decoder_mutex); - while (decode->decoder_loop_status != GST_FLOW_OK) + while (decode->decoder_loop_status == GST_FLOW_OK) g_cond_wait(&decode->decoder_finish_done, &decode->decoder_mutex); g_mutex_unlock(&decode->decoder_mutex); gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); From 4b61cc3cd71dcb7671faf43636010fd3b58404fb Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Tue, 5 Nov 2013 14:01:11 +0100 Subject: [PATCH 1745/3781] vaapisink: listen to window size changes on X11. Allow dynamic changes to the window, e.g. performed by the user, and make sure to refresh its contents, while preserving aspect ratio. In practice, Expose and ConfigureNotify events are tracked in X11 display mode by default. This occurs in a separte event thread, and this is similar to what xvimagesink does. Any of those events will trigger a reconfiguration of the window "soft" size, subsequently the render-rect when necessary, and finally _expose() the result. The default of handle_events=true can be changed programatically via gst_x_overlay_handle_events(). Thanks to Fabrice Bellet for rebasing the patch. https://bugzilla.gnome.org/show_bug.cgi?id=711478 [dropped XInitThreads(), cleaned up the code a little] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 197 ++++++++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapisink.h | 3 + 2 files changed, 197 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 3753d77527..341c23b3cf 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -146,14 +146,23 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink); /* GstVideoOverlay interface */ +static void +gst_vaapisink_video_overlay_expose(GstVideoOverlay *overlay); + #if USE_X11 static gboolean gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id); #endif +static void +gst_vaapisink_set_event_handling(GstVideoOverlay *overlay, gboolean handle_events); + static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); +static gboolean +gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height); + static void gst_vaapisink_video_overlay_set_window_handle(GstVideoOverlay *overlay, guintptr window) @@ -179,6 +188,7 @@ gst_vaapisink_video_overlay_set_window_handle(GstVideoOverlay *overlay, #if USE_X11 case GST_VAAPI_DISPLAY_TYPE_X11: gst_vaapisink_ensure_window_xid(sink, window); + gst_vaapisink_set_event_handling(GST_VIDEO_OVERLAY(sink), sink->handle_events); break; #endif default: @@ -208,13 +218,175 @@ gst_vaapisink_video_overlay_set_render_rectangle( display_rect->width, display_rect->height); } +static gboolean +gst_vaapisink_reconfigure_window(GstVaapiSink * sink) +{ + guint win_width, win_height; + + gst_vaapi_window_reconfigure(sink->window); + gst_vaapi_window_get_size(sink->window, &win_width, &win_height); + if (win_width != sink->window_width || win_height != sink->window_height) { + if (!gst_vaapisink_ensure_render_rect(sink, win_width, win_height)) + return FALSE; + GST_INFO("window was resized from %ux%u to %ux%u", + sink->window_width, sink->window_height, win_width, win_height); + sink->window_width = win_width; + sink->window_height = win_height; + return TRUE; + } + return FALSE; +} + +#if USE_X11 +static void +gst_vaapisink_event_thread_loop_x11(GstVaapiSink *sink) +{ + GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); + gboolean has_events, do_expose = FALSE; + XEvent e; + + if (sink->window) { + Display * const x11_dpy = + gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)); + Window x11_win = + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)); + + /* Handle Expose + ConfigureNotify */ + /* Need to lock whole loop or we corrupt the XEvent queue: */ + for (;;) { + gst_vaapi_display_lock(display); + has_events = XCheckWindowEvent(x11_dpy, x11_win, + StructureNotifyMask | ExposureMask, &e); + gst_vaapi_display_unlock(display); + if (!has_events) + break; + + switch (e.type) { + case Expose: + do_expose = TRUE; + break; + case ConfigureNotify: + if (gst_vaapisink_reconfigure_window(sink)) + do_expose = TRUE; + break; + default: + break; + } + } + if (do_expose) + gst_vaapisink_video_overlay_expose(GST_VIDEO_OVERLAY(sink)); + /* FIXME: handle mouse and key events */ + } +} +#endif + +static void +gst_vaapisink_event_thread_loop_default(GstVaapiSink *sink) +{ +} + +static gpointer +gst_vaapisink_event_thread (GstVaapiSink *sink) +{ + void (*thread_loop)(GstVaapiSink *sink); + + switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { +#if USE_X11 + case GST_VAAPI_DISPLAY_TYPE_X11: + case GST_VAAPI_DISPLAY_TYPE_GLX: + thread_loop = gst_vaapisink_event_thread_loop_x11; + break; +#endif + default: + thread_loop = gst_vaapisink_event_thread_loop_default; + break; + } + + GST_OBJECT_LOCK(sink); + while (!sink->event_thread_cancel) { + GST_OBJECT_UNLOCK(sink); + thread_loop(sink); + g_usleep(G_USEC_PER_SEC / 20); + GST_OBJECT_LOCK(sink); + } + GST_OBJECT_UNLOCK(sink); + + return NULL; +} + static void gst_vaapisink_video_overlay_expose(GstVideoOverlay *overlay) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); - if (sink->video_buffer) + if (sink->video_buffer) { + gst_vaapisink_reconfigure_window(sink); gst_vaapisink_show_frame(GST_BASE_SINK_CAST(sink), sink->video_buffer); + } +} + +static void +gst_vaapisink_set_event_handling(GstVideoOverlay *overlay, + gboolean handle_events) +{ + GThread *thread = NULL; + GstVaapiSink * const sink = GST_VAAPISINK(overlay); +#if USE_X11 + GstVaapiDisplayX11 * const display = + GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); +#endif + + GST_OBJECT_LOCK(sink); + sink->handle_events = handle_events; + if (handle_events && !sink->event_thread) { + /* Setup our event listening thread */ + GST_DEBUG("starting xevent thread"); + switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { +#if USE_X11 + case GST_VAAPI_DISPLAY_TYPE_X11: + case GST_VAAPI_DISPLAY_TYPE_GLX: + XSelectInput(gst_vaapi_display_x11_get_display(display), + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)), + StructureNotifyMask | ExposureMask); + break; +#endif + default: + break; + } + + sink->event_thread_cancel = FALSE; + sink->event_thread = g_thread_try_new("vaapisink-events", + (GThreadFunc) gst_vaapisink_event_thread, sink, NULL); + } + else if (!handle_events && sink->event_thread) { + GST_DEBUG("stopping xevent thread"); + if (sink->window) { + switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { +#if USE_X11 + case GST_VAAPI_DISPLAY_TYPE_X11: + case GST_VAAPI_DISPLAY_TYPE_GLX: + XSelectInput(gst_vaapi_display_x11_get_display(display), + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)), + 0); + break; +#endif + default: + break; + } + } + + /* grab thread and mark it as NULL */ + thread = sink->event_thread; + sink->event_thread = NULL; + sink->event_thread_cancel = TRUE; + } + GST_OBJECT_UNLOCK(sink); + + /* Wait for our event thread to finish */ + if (thread) { + g_thread_join(thread); + GST_DEBUG("xevent thread stopped"); + } } static void @@ -223,11 +395,14 @@ gst_vaapisink_video_overlay_iface_init(GstVideoOverlayInterface *iface) iface->set_window_handle = gst_vaapisink_video_overlay_set_window_handle; iface->set_render_rectangle = gst_vaapisink_video_overlay_set_render_rectangle; iface->expose = gst_vaapisink_video_overlay_expose; + iface->handle_events = gst_vaapisink_set_event_handling; } static void gst_vaapisink_destroy(GstVaapiSink *sink) { + gst_vaapisink_set_event_handling(GST_VIDEO_OVERLAY(sink), FALSE); + gst_buffer_replace(&sink->video_buffer, NULL); #if USE_GLX gst_vaapi_texture_replace(&sink->texture, NULL); @@ -728,6 +903,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) gst_vaapi_window_set_fullscreen(sink->window, sink->fullscreen); gst_vaapi_window_show(sink->window); gst_vaapi_window_get_size(sink->window, &win_width, &win_height); + gst_vaapisink_set_event_handling(GST_VIDEO_OVERLAY(sink), sink->handle_events); } sink->window_width = win_width; sink->window_height = win_height; @@ -961,9 +1137,8 @@ gst_vaapisink_put_surface( } static GstFlowReturn -gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) +gst_vaapisink_show_frame_unlocked(GstVaapiSink *sink, GstBuffer *src_buffer) { - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); GstVaapiVideoMeta *meta; GstVaapiSurfaceProxy *proxy; GstVaapiSurface *surface; @@ -1083,6 +1258,21 @@ error: return GST_FLOW_EOS; } +static GstFlowReturn +gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) +{ + GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + GstFlowReturn ret; + + /* At least we need at least to protect the _set_subpictures_() + * call to prevent a race during subpicture desctruction. + * FIXME: Could use a less coarse grained lock, though: */ + gst_vaapi_display_lock(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); + ret = gst_vaapisink_show_frame_unlocked(sink, src_buffer); + gst_vaapi_display_unlock(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); + return ret; +} + #if GST_CHECK_VERSION(1,0,0) static gboolean gst_vaapisink_propose_allocation(GstBaseSink *base_sink, GstQuery *query) @@ -1409,6 +1599,7 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->video_par_n = 1; sink->video_par_d = 1; sink->view_id = -1; + sink->handle_events = TRUE; sink->foreign_window = FALSE; sink->fullscreen = FALSE; sink->synchronous = FALSE; diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index a41e740949..a4d5c28723 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -88,6 +88,9 @@ struct _GstVaapiSink { GstVaapiRotation rotation_req; guint color_standard; gint32 view_id; + GThread *event_thread; + volatile gboolean event_thread_cancel; + guint handle_events : 1; guint foreign_window : 1; guint fullscreen : 1; guint synchronous : 1; From 8298d64aad23125d1809f4799d3f669677a3cb86 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jul 2014 16:35:32 +0200 Subject: [PATCH 1746/3781] vaapisink: drop GLX rendering and fancy effects. Rendering with GLX in vaapisink is kind of useless nowadays, including OpenGL related fancy effects. Plain VA/GLX interfaces are also getting deprecated in favor of EGL, or more direct buffer sharing with actual GL textures. Should testing of interop with GLX be needed, one could still be using the modern cluttersink or glimagesink elements. https://bugzilla.gnome.org/show_bug.cgi?id=733984 --- gst/vaapi/gstvaapisink.c | 280 +-------------------------------------- gst/vaapi/gstvaapisink.h | 9 -- 2 files changed, 3 insertions(+), 286 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 341c23b3cf..9614f4234c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -43,10 +43,6 @@ # include # include #endif -#if USE_GLX -# include -# include -#endif #if USE_WAYLAND # include # include @@ -131,8 +127,6 @@ enum { PROP_DISPLAY_NAME, PROP_FULLSCREEN, PROP_SYNCHRONOUS, - PROP_USE_GLX, - PROP_USE_REFLECTION, PROP_ROTATION, PROP_FORCE_ASPECT_RATIO, PROP_VIEW_ID, @@ -404,9 +398,6 @@ gst_vaapisink_destroy(GstVaapiSink *sink) gst_vaapisink_set_event_handling(GST_VIDEO_OVERLAY(sink), FALSE); gst_buffer_replace(&sink->video_buffer, NULL); -#if USE_GLX - gst_vaapi_texture_replace(&sink->texture, NULL); -#endif gst_caps_replace(&sink->caps, NULL); } @@ -640,15 +631,10 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) const GstVaapiDisplayType display_type = GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink); switch (display_type) { -#if USE_GLX - case GST_VAAPI_DISPLAY_TYPE_GLX: - sink->window = gst_vaapi_window_glx_new(display, width, height); - goto notify_video_overlay_interface; -#endif #if USE_X11 + case GST_VAAPI_DISPLAY_TYPE_GLX: case GST_VAAPI_DISPLAY_TYPE_X11: sink->window = gst_vaapi_window_x11_new(display, width, height); - notify_video_overlay_interface: if (!sink->window) break; gst_video_overlay_got_window_handle( @@ -707,20 +693,7 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) gst_vaapi_window_replace(&sink->window, NULL); - switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { -#if USE_GLX - case GST_VAAPI_DISPLAY_TYPE_GLX: - sink->window = gst_vaapi_window_glx_new_with_xid(display, xid); - break; -#endif - case GST_VAAPI_DISPLAY_TYPE_X11: - sink->window = gst_vaapi_window_x11_new_with_xid(display, xid); - break; - default: - GST_ERROR("unsupported display type %d", - GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)); - return FALSE; - } + sink->window = gst_vaapi_window_x11_new_with_xid(display, xid); return sink->window != NULL; } #endif @@ -912,211 +885,6 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return gst_vaapisink_ensure_render_rect(sink, win_width, win_height); } -#if USE_GLX -static void -render_background(GstVaapiSink *sink) -{ - /* Original code from Mirco Muller (MacSlow): - */ - GLfloat fStartX = 0.0f; - GLfloat fStartY = 0.0f; - GLfloat fWidth = (GLfloat)sink->window_width; - GLfloat fHeight = (GLfloat)sink->window_height; - - glClear(GL_COLOR_BUFFER_BIT); - glBegin(GL_QUADS); - { - /* top third, darker grey to white */ - glColor3f(0.85f, 0.85f, 0.85f); - glVertex3f(fStartX, fStartY, 0.0f); - glColor3f(0.85f, 0.85f, 0.85f); - glVertex3f(fStartX + fWidth, fStartY, 0.0f); - glColor3f(1.0f, 1.0f, 1.0f); - glVertex3f(fStartX + fWidth, fStartY + fHeight / 3.0f, 0.0f); - glColor3f(1.0f, 1.0f, 1.0f); - glVertex3f(fStartX, fStartY + fHeight / 3.0f, 0.0f); - - /* middle third, just plain white */ - glColor3f(1.0f, 1.0f, 1.0f); - glVertex3f(fStartX, fStartY + fHeight / 3.0f, 0.0f); - glVertex3f(fStartX + fWidth, fStartY + fHeight / 3.0f, 0.0f); - glVertex3f(fStartX + fWidth, fStartY + 2.0f * fHeight / 3.0f, 0.0f); - glVertex3f(fStartX, fStartY + 2.0f * fHeight / 3.0f, 0.0f); - - /* bottom third, white to lighter grey */ - glColor3f(1.0f, 1.0f, 1.0f); - glVertex3f(fStartX, fStartY + 2.0f * fHeight / 3.0f, 0.0f); - glColor3f(1.0f, 1.0f, 1.0f); - glVertex3f(fStartX + fWidth, fStartY + 2.0f * fHeight / 3.0f, 0.0f); - glColor3f(0.62f, 0.66f, 0.69f); - glVertex3f(fStartX + fWidth, fStartY + fHeight, 0.0f); - glColor3f(0.62f, 0.66f, 0.69f); - glVertex3f(fStartX, fStartY + fHeight, 0.0f); - } - glEnd(); -} - -static void -render_frame(GstVaapiSink *sink, GstVaapiSurface *surface, - const GstVaapiRectangle *surface_rect) -{ - const guint x1 = sink->display_rect.x; - const guint x2 = sink->display_rect.x + sink->display_rect.width; - const guint y1 = sink->display_rect.y; - const guint y2 = sink->display_rect.y + sink->display_rect.height; - gfloat tx1, tx2, ty1, ty2; - guint width, height; - - if (surface_rect) { - gst_vaapi_surface_get_size(surface, &width, &height); - tx1 = (gfloat)surface_rect->x / width; - ty1 = (gfloat)surface_rect->y / height; - tx2 = (gfloat)(surface_rect->x + surface_rect->width) / width; - ty2 = (gfloat)(surface_rect->y + surface_rect->height) / height; - } - else { - tx1 = 0.0f; - ty1 = 0.0f; - tx2 = 1.0f; - ty2 = 1.0f; - } - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glBegin(GL_QUADS); - { - glTexCoord2f(tx1, ty1); glVertex2i(x1, y1); - glTexCoord2f(tx1, ty2); glVertex2i(x1, y2); - glTexCoord2f(tx2, ty2); glVertex2i(x2, y2); - glTexCoord2f(tx2, ty1); glVertex2i(x2, y1); - } - glEnd(); -} - -static void -render_reflection(GstVaapiSink *sink) -{ - const guint x1 = sink->display_rect.x; - const guint x2 = sink->display_rect.x + sink->display_rect.width; - const guint y1 = sink->display_rect.y; - const guint rh = sink->display_rect.height / 5; - GLfloat ry = 1.0f - (GLfloat)rh / (GLfloat)sink->display_rect.height; - - glBegin(GL_QUADS); - { - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glTexCoord2f(0.0f, 1.0f); glVertex2i(x1, y1); - glTexCoord2f(1.0f, 1.0f); glVertex2i(x2, y1); - - glColor4f(1.0f, 1.0f, 1.0f, 0.0f); - glTexCoord2f(1.0f, ry); glVertex2i(x2, y1 + rh); - glTexCoord2f(0.0f, ry); glVertex2i(x1, y1 + rh); - } - glEnd(); -} - -static gboolean -gst_vaapisink_ensure_texture(GstVaapiSink *sink, GstVaapiSurface *surface) -{ - GstVaapiDisplay * display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); - GstVideoRectangle tex_rect, dis_rect, out_rect; - guint width, height; - - if (sink->texture) - return TRUE; - - gst_vaapi_surface_get_size(surface, &width, &height); - tex_rect.x = 0; - tex_rect.y = 0; - tex_rect.w = width; - tex_rect.h = height; - - gst_vaapi_display_get_size(display, &width, &height); - dis_rect.x = 0; - dis_rect.y = 0; - dis_rect.w = width; - dis_rect.h = height; - - gst_video_sink_center_rect(tex_rect, dis_rect, &out_rect, TRUE); - - /* XXX: use surface size for now since some VA drivers have issues - with downscaling to the provided texture size. i.e. we should be - using the resulting out_rect size, which preserves the aspect - ratio of the surface */ - width = tex_rect.w; - height = tex_rect.h; - GST_INFO("texture size %ux%u", width, height); - - sink->texture = gst_vaapi_texture_new(display, - GL_TEXTURE_2D, GL_BGRA, width, height); - return sink->texture != NULL; -} - -static gboolean -gst_vaapisink_show_frame_glx( - GstVaapiSink *sink, - GstVaapiSurface *surface, - const GstVaapiRectangle *surface_rect, - guint flags -) -{ - GstVaapiWindowGLX *window; - GLenum target; - GLuint texture; - - if (!sink->window) - return FALSE; - window = GST_VAAPI_WINDOW_GLX(sink->window); - - gst_vaapi_window_glx_make_current(window); - if (!gst_vaapisink_ensure_texture(sink, surface)) - goto error_create_texture; - if (!gst_vaapi_texture_put_surface(sink->texture, surface, flags)) - goto error_transfer_surface; - - target = gst_vaapi_texture_get_target(sink->texture); - texture = gst_vaapi_texture_get_id(sink->texture); - if (target != GL_TEXTURE_2D || !texture) - return FALSE; - - if (sink->use_reflection) - render_background(sink); - - glEnable(target); - glBindTexture(target, texture); - { - if (sink->use_reflection) { - glPushMatrix(); - glRotatef(20.0f, 0.0f, 1.0f, 0.0f); - glTranslatef(50.0f, 0.0f, 0.0f); - } - render_frame(sink, surface, surface_rect); - if (sink->use_reflection) { - glPushMatrix(); - glTranslatef(0.0, (GLfloat)sink->display_rect.height + 5.0f, 0.0f); - render_reflection(sink); - glPopMatrix(); - glPopMatrix(); - } - } - glBindTexture(target, 0); - glDisable(target); - gst_vaapi_window_glx_swap_buffers(window); - return TRUE; - - /* ERRORS */ -error_create_texture: - { - GST_DEBUG("could not create VA/GLX texture"); - return FALSE; - } -error_transfer_surface: - { - GST_DEBUG("could not transfer VA surface to texture"); - return FALSE; - } -} -#endif - static inline gboolean gst_vaapisink_put_surface( GstVaapiSink *sink, @@ -1220,17 +988,9 @@ gst_vaapisink_show_frame_unlocked(GstVaapiSink *sink, GstBuffer *src_buffer) success = TRUE; break; #endif -#if USE_GLX - case GST_VAAPI_DISPLAY_TYPE_GLX: - if (!sink->use_glx) - goto put_surface_x11; - success = gst_vaapisink_show_frame_glx(sink, surface, surface_rect, - flags); - break; -#endif #if USE_X11 + case GST_VAAPI_DISPLAY_TYPE_GLX: case GST_VAAPI_DISPLAY_TYPE_X11: - put_surface_x11: success = gst_vaapisink_put_surface(sink, surface, surface_rect, flags); break; #endif @@ -1350,12 +1110,6 @@ gst_vaapisink_set_property( case PROP_VIEW_ID: sink->view_id = g_value_get_int(value); break; - case PROP_USE_GLX: - sink->use_glx = g_value_get_boolean(value); - break; - case PROP_USE_REFLECTION: - sink->use_reflection = g_value_get_boolean(value); - break; case PROP_ROTATION: sink->rotation_req = g_value_get_enum(value); break; @@ -1394,12 +1148,6 @@ gst_vaapisink_get_property( case PROP_VIEW_ID: g_value_set_int(value, sink->view_id); break; - case PROP_USE_GLX: - g_value_set_boolean(value, sink->use_glx); - break; - case PROP_USE_REFLECTION: - g_value_set_boolean(value, sink->use_reflection); - break; case PROP_ROTATION: g_value_set_enum(value, sink->rotation); break; @@ -1488,26 +1236,6 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); -#if USE_GLX - g_object_class_install_property - (object_class, - PROP_USE_GLX, - g_param_spec_boolean("use-glx", - "OpenGL rendering", - "Enables OpenGL rendering", - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, - PROP_USE_REFLECTION, - g_param_spec_boolean("use-reflection", - "Reflection effect", - "Enables OpenGL reflection effect", - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); -#endif - g_object_class_install_property (object_class, PROP_FULLSCREEN, @@ -1592,7 +1320,6 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->window = NULL; sink->window_width = 0; sink->window_height = 0; - sink->texture = NULL; sink->video_buffer = NULL; sink->video_width = 0; sink->video_height = 0; @@ -1605,7 +1332,6 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->synchronous = FALSE; sink->rotation = DEFAULT_ROTATION; sink->rotation_req = DEFAULT_ROTATION; - sink->use_reflection = FALSE; sink->use_overlay = FALSE; sink->use_rotation = FALSE; sink->keep_aspect = TRUE; diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index a4d5c28723..96ac865b5f 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -27,9 +27,6 @@ #include "gstvaapipluginbase.h" #include -#if USE_GLX -#include -#endif #include "gstvaapipluginutil.h" G_BEGIN_DECLS @@ -60,9 +57,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiSink GstVaapiSink; typedef struct _GstVaapiSinkClass GstVaapiSinkClass; -#if !USE_GLX -typedef struct _GstVaapiTexture GstVaapiTexture; -#endif struct _GstVaapiSink { /*< private >*/ @@ -72,7 +66,6 @@ struct _GstVaapiSink { GstVaapiWindow *window; guint window_width; guint window_height; - GstVaapiTexture *texture; #if GST_CHECK_VERSION(1,0,0) GstBufferPool *video_buffer_pool; #endif @@ -94,8 +87,6 @@ struct _GstVaapiSink { guint foreign_window : 1; guint fullscreen : 1; guint synchronous : 1; - guint use_glx : 1; - guint use_reflection : 1; guint use_overlay : 1; guint use_rotation : 1; guint keep_aspect : 1; From 81b5ad85b5fb3e979a72fcfcecbb60bf02b55226 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jul 2014 17:32:29 +0200 Subject: [PATCH 1747/3781] vaapisink: drop unused variables. Drop obsolete, and now unused, video_buffer_pool and video_buffer_size variables. They got merged into the GstVaapiPluginBase object. --- gst/vaapi/gstvaapisink.c | 3 --- gst/vaapi/gstvaapisink.h | 4 ---- 2 files changed, 7 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 9614f4234c..49146df207 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -754,9 +754,6 @@ gst_vaapisink_stop(GstBaseSink *base_sink) GstVaapiSink * const sink = GST_VAAPISINK(base_sink); gst_buffer_replace(&sink->video_buffer, NULL); -#if GST_CHECK_VERSION(1,0,0) - g_clear_object(&sink->video_buffer_pool); -#endif gst_vaapi_window_replace(&sink->window, NULL); gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(sink)); diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 96ac865b5f..b286530f79 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -66,10 +66,6 @@ struct _GstVaapiSink { GstVaapiWindow *window; guint window_width; guint window_height; -#if GST_CHECK_VERSION(1,0,0) - GstBufferPool *video_buffer_pool; -#endif - guint video_buffer_size; GstBuffer *video_buffer; guint video_width; guint video_height; From 24673dc3a446718e769b020de065700020329bea Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jul 2014 16:47:20 +0200 Subject: [PATCH 1748/3781] vaapisink: drop unused "synchronous" mode. Support for X11 "synchronous" mode was never implemented, and was only to be useful for debugging. Drop that altogether, that's not going to be useful in practice. https://bugzilla.gnome.org/show_bug.cgi?id=733985 --- gst/vaapi/gstvaapisink.c | 23 ----------------------- gst/vaapi/gstvaapisink.h | 1 - 2 files changed, 24 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 49146df207..7f6f2e59c5 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -126,7 +126,6 @@ enum { PROP_DISPLAY_TYPE, PROP_DISPLAY_NAME, PROP_FULLSCREEN, - PROP_SYNCHRONOUS, PROP_ROTATION, PROP_FORCE_ASPECT_RATIO, PROP_VIEW_ID, @@ -1101,9 +1100,6 @@ gst_vaapisink_set_property( case PROP_FULLSCREEN: sink->fullscreen = g_value_get_boolean(value); break; - case PROP_SYNCHRONOUS: - sink->synchronous = g_value_get_boolean(value); - break; case PROP_VIEW_ID: sink->view_id = g_value_get_int(value); break; @@ -1139,9 +1135,6 @@ gst_vaapisink_get_property( case PROP_FULLSCREEN: g_value_set_boolean(value, sink->fullscreen); break; - case PROP_SYNCHRONOUS: - g_value_set_boolean(value, sink->synchronous); - break; case PROP_VIEW_ID: g_value_set_int(value, sink->view_id); break; @@ -1242,21 +1235,6 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiSink:synchronous: - * - * When enabled, runs the X display in synchronous mode. Note that - * this is used only for debugging. - */ - g_object_class_install_property - (object_class, - PROP_SYNCHRONOUS, - g_param_spec_boolean("synchronous", - "Synchronous mode", - "Toggles X display synchronous mode", - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** * GstVaapiSink:rotation: * @@ -1326,7 +1304,6 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->handle_events = TRUE; sink->foreign_window = FALSE; sink->fullscreen = FALSE; - sink->synchronous = FALSE; sink->rotation = DEFAULT_ROTATION; sink->rotation_req = DEFAULT_ROTATION; sink->use_overlay = FALSE; diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index b286530f79..5dc51012e8 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -82,7 +82,6 @@ struct _GstVaapiSink { guint handle_events : 1; guint foreign_window : 1; guint fullscreen : 1; - guint synchronous : 1; guint use_overlay : 1; guint use_rotation : 1; guint keep_aspect : 1; From 30c59af0a012ce2c75ce45bbe47b303f40f04ebe Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 30 Jul 2014 17:27:50 +0200 Subject: [PATCH 1749/3781] vaapisink: introduce separate backends. Introduce new backends vtable so that to have clean separation between display dependent code and common base code. That's a "soft" separation, we don't really need dedicated objects. https://bugzilla.gnome.org/show_bug.cgi?id=722248 --- gst/vaapi/gstvaapisink.c | 591 +++++++++++++++++++++------------------ gst/vaapi/gstvaapisink.h | 25 ++ 2 files changed, 345 insertions(+), 271 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 7f6f2e59c5..fd2e3813e1 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -36,17 +36,6 @@ #include #include -#if USE_DRM -# include -#endif -#if USE_X11 -# include -# include -#endif -#if USE_WAYLAND -# include -# include -#endif /* Supported interfaces */ #if GST_CHECK_VERSION(1,0,0) @@ -142,10 +131,8 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink); static void gst_vaapisink_video_overlay_expose(GstVideoOverlay *overlay); -#if USE_X11 static gboolean -gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id); -#endif +gst_vaapisink_reconfigure_window(GstVaapiSink * sink); static void gst_vaapisink_set_event_handling(GstVideoOverlay *overlay, gboolean handle_events); @@ -153,18 +140,298 @@ gst_vaapisink_set_event_handling(GstVideoOverlay *overlay, gboolean handle_event static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); +static gboolean +gst_vaapisink_put_surface(GstVaapiSink *sink, GstVaapiSurface *surface, + const GstVaapiRectangle *surface_rect, guint flags); + static gboolean gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height); +/* ------------------------------------------------------------------------ */ +/* --- DRM Backend --- */ +/* ------------------------------------------------------------------------ */ + +#if USE_DRM +#include + +static gboolean +gst_vaapisink_drm_create_window(GstVaapiSink *sink, guint width, guint height) +{ + g_return_val_if_fail(sink->window == NULL, FALSE); + + GST_ERROR("failed to create a window for VA/DRM display"); + return FALSE; +} + +static gboolean +gst_vaapisink_drm_render_surface(GstVaapiSink *sink, GstVaapiSurface *surface, + const GstVaapiRectangle *surface_rect, guint flags) +{ + return TRUE; +} + +static const inline GstVaapiSinkBackend * +gst_vaapisink_backend_drm(void) +{ + static const GstVaapiSinkBackend GstVaapiSinkBackendDRM = { + .create_window = gst_vaapisink_drm_create_window, + .render_surface = gst_vaapisink_drm_render_surface, + }; + return &GstVaapiSinkBackendDRM; +} +#endif + +/* ------------------------------------------------------------------------ */ +/* --- X11 Backend --- */ +/* ------------------------------------------------------------------------ */ + +#if USE_X11 +#include +#include + +/* Checks whether a ConfigureNotify event is in the queue */ +typedef struct _ConfigureNotifyEventPendingArgs ConfigureNotifyEventPendingArgs; +struct _ConfigureNotifyEventPendingArgs { + Window window; + guint width; + guint height; + gboolean match; +}; + +static Bool +configure_notify_event_pending_cb(Display *dpy, XEvent *xev, XPointer arg) +{ + ConfigureNotifyEventPendingArgs * const args = + (ConfigureNotifyEventPendingArgs *)arg; + + if (xev->type == ConfigureNotify && + xev->xconfigure.window == args->window && + xev->xconfigure.width == args->width && + xev->xconfigure.height == args->height) + args->match = TRUE; + + /* XXX: this is a hack to traverse the whole queue because we + can't use XPeekIfEvent() since it could block */ + return False; +} + +static gboolean +configure_notify_event_pending(GstVaapiSink *sink, Window window, + guint width, guint height) +{ + GstVaapiDisplayX11 * const display = + GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); + ConfigureNotifyEventPendingArgs args; + XEvent xev; + + args.window = window; + args.width = width; + args.height = height; + args.match = FALSE; + + /* XXX: don't use XPeekIfEvent() because it might block */ + XCheckIfEvent( + gst_vaapi_display_x11_get_display(display), + &xev, + configure_notify_event_pending_cb, (XPointer)&args + ); + return args.match; +} + +static gboolean +gst_vaapisink_x11_create_window(GstVaapiSink *sink, guint width, guint height) +{ + GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); + + g_return_val_if_fail(sink->window == NULL, FALSE); + + sink->window = gst_vaapi_window_x11_new(display, width, height); + if (!sink->window) + return FALSE; + + gst_video_overlay_got_window_handle(GST_VIDEO_OVERLAY(sink), + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window))); + return TRUE; +} + +static gboolean +gst_vaapisink_x11_create_window_from_handle(GstVaapiSink *sink, guintptr window) +{ + GstVaapiDisplay *display; + Window rootwin; + unsigned int width, height, border_width, depth; + int x, y; + XID xid = window; + + if (!gst_vaapisink_ensure_display(sink)) + return FALSE; + display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); + + gst_vaapi_display_lock(display); + XGetGeometry( + gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)), + xid, + &rootwin, + &x, &y, &width, &height, &border_width, &depth + ); + gst_vaapi_display_unlock(display); + + if ((width != sink->window_width || height != sink->window_height) && + !configure_notify_event_pending(sink, xid, width, height)) { + if (!gst_vaapisink_ensure_render_rect(sink, width, height)) + return FALSE; + sink->window_width = width; + sink->window_height = height; + } + + if (!sink->window || gst_vaapi_window_x11_get_xid( + GST_VAAPI_WINDOW_X11(sink->window)) != xid) { + gst_vaapi_window_replace(&sink->window, NULL); + sink->window = gst_vaapi_window_x11_new_with_xid(display, xid); + if (!sink->window) + return FALSE; + } + + gst_vaapisink_set_event_handling(GST_VIDEO_OVERLAY(sink), + sink->handle_events); + return TRUE; +} + +static gboolean +gst_vaapisink_x11_handle_events(GstVaapiSink *sink) +{ + GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); + gboolean has_events, do_expose = FALSE; + XEvent e; + + if (sink->window) { + Display * const x11_dpy = + gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)); + Window x11_win = + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)); + + /* Handle Expose + ConfigureNotify */ + /* Need to lock whole loop or we corrupt the XEvent queue: */ + for (;;) { + gst_vaapi_display_lock(display); + has_events = XCheckWindowEvent(x11_dpy, x11_win, + StructureNotifyMask | ExposureMask, &e); + gst_vaapi_display_unlock(display); + if (!has_events) + break; + + switch (e.type) { + case Expose: + do_expose = TRUE; + break; + case ConfigureNotify: + if (gst_vaapisink_reconfigure_window(sink)) + do_expose = TRUE; + break; + default: + break; + } + } + if (do_expose) + gst_vaapisink_video_overlay_expose(GST_VIDEO_OVERLAY(sink)); + /* FIXME: handle mouse and key events */ + } + return TRUE; +} + +static gboolean +gst_vaapisink_x11_pre_start_event_thread(GstVaapiSink *sink) +{ + GstVaapiDisplayX11 * const display = + GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); + + if (sink->window) { + XSelectInput(gst_vaapi_display_x11_get_display(display), + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)), + StructureNotifyMask | ExposureMask); + } + return TRUE; +} + +static gboolean +gst_vaapisink_x11_pre_stop_event_thread(GstVaapiSink *sink) +{ + GstVaapiDisplayX11 * const display = + GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); + + if (sink->window) { + XSelectInput(gst_vaapi_display_x11_get_display(display), + gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)), + 0); + } + return TRUE; +} + +static const inline GstVaapiSinkBackend * +gst_vaapisink_backend_x11(void) +{ + static const GstVaapiSinkBackend GstVaapiSinkBackendX11 = { + .create_window = gst_vaapisink_x11_create_window, + .create_window_from_handle = gst_vaapisink_x11_create_window_from_handle, + .render_surface = gst_vaapisink_put_surface, + + .event_thread_needed = TRUE, + .handle_events = gst_vaapisink_x11_handle_events, + .pre_start_event_thread = gst_vaapisink_x11_pre_start_event_thread, + .pre_stop_event_thread = gst_vaapisink_x11_pre_stop_event_thread, + }; + return &GstVaapiSinkBackendX11; +} +#endif + +/* ------------------------------------------------------------------------ */ +/* --- Wayland Backend --- */ +/* ------------------------------------------------------------------------ */ + +#if USE_WAYLAND +#include +#include + +static gboolean +gst_vaapisink_wayland_create_window(GstVaapiSink *sink, guint width, + guint height) +{ + GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); + + g_return_val_if_fail(sink->window == NULL, FALSE); + + sink->window = gst_vaapi_window_wayland_new(display, width, height); + if (!sink->window) + return FALSE; + return TRUE; +} + +static const inline GstVaapiSinkBackend * +gst_vaapisink_backend_wayland(void) +{ + static const GstVaapiSinkBackend GstVaapiSinkBackendWayland = { + .create_window = gst_vaapisink_wayland_create_window, + .render_surface = gst_vaapisink_put_surface, + }; + return &GstVaapiSinkBackendWayland; +} +#endif + +/* ------------------------------------------------------------------------ */ +/* --- Common implementation --- */ +/* ------------------------------------------------------------------------ */ + static void gst_vaapisink_video_overlay_set_window_handle(GstVideoOverlay *overlay, guintptr window) { GstVaapiSink * const sink = GST_VAAPISINK(overlay); + const GstVaapiSinkBackend * const backend = sink->backend; GstVaapiDisplayType display_type; if (!gst_vaapisink_ensure_display(sink)) return; + display_type = GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink); /* Disable GLX rendering when vaapisink is using a foreign X @@ -176,17 +443,8 @@ gst_vaapisink_video_overlay_set_window_handle(GstVideoOverlay *overlay, } sink->foreign_window = TRUE; - - switch (display_type) { -#if USE_X11 - case GST_VAAPI_DISPLAY_TYPE_X11: - gst_vaapisink_ensure_window_xid(sink, window); - gst_vaapisink_set_event_handling(GST_VIDEO_OVERLAY(sink), sink->handle_events); - break; -#endif - default: - break; - } + if (backend->create_window_from_handle) + backend->create_window_from_handle(sink, window); } static void @@ -230,75 +488,13 @@ gst_vaapisink_reconfigure_window(GstVaapiSink * sink) return FALSE; } -#if USE_X11 -static void -gst_vaapisink_event_thread_loop_x11(GstVaapiSink *sink) -{ - GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); - gboolean has_events, do_expose = FALSE; - XEvent e; - - if (sink->window) { - Display * const x11_dpy = - gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)); - Window x11_win = - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)); - - /* Handle Expose + ConfigureNotify */ - /* Need to lock whole loop or we corrupt the XEvent queue: */ - for (;;) { - gst_vaapi_display_lock(display); - has_events = XCheckWindowEvent(x11_dpy, x11_win, - StructureNotifyMask | ExposureMask, &e); - gst_vaapi_display_unlock(display); - if (!has_events) - break; - - switch (e.type) { - case Expose: - do_expose = TRUE; - break; - case ConfigureNotify: - if (gst_vaapisink_reconfigure_window(sink)) - do_expose = TRUE; - break; - default: - break; - } - } - if (do_expose) - gst_vaapisink_video_overlay_expose(GST_VIDEO_OVERLAY(sink)); - /* FIXME: handle mouse and key events */ - } -} -#endif - -static void -gst_vaapisink_event_thread_loop_default(GstVaapiSink *sink) -{ -} - static gpointer gst_vaapisink_event_thread (GstVaapiSink *sink) { - void (*thread_loop)(GstVaapiSink *sink); - - switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { -#if USE_X11 - case GST_VAAPI_DISPLAY_TYPE_X11: - case GST_VAAPI_DISPLAY_TYPE_GLX: - thread_loop = gst_vaapisink_event_thread_loop_x11; - break; -#endif - default: - thread_loop = gst_vaapisink_event_thread_loop_default; - break; - } - GST_OBJECT_LOCK(sink); while (!sink->event_thread_cancel) { GST_OBJECT_UNLOCK(sink); - thread_loop(sink); + sink->backend->handle_events(sink); g_usleep(G_USEC_PER_SEC / 20); GST_OBJECT_LOCK(sink); } @@ -324,28 +520,17 @@ gst_vaapisink_set_event_handling(GstVideoOverlay *overlay, { GThread *thread = NULL; GstVaapiSink * const sink = GST_VAAPISINK(overlay); -#if USE_X11 - GstVaapiDisplayX11 * const display = - GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); -#endif + + if (!sink->backend->event_thread_needed) + return; GST_OBJECT_LOCK(sink); sink->handle_events = handle_events; if (handle_events && !sink->event_thread) { /* Setup our event listening thread */ GST_DEBUG("starting xevent thread"); - switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { -#if USE_X11 - case GST_VAAPI_DISPLAY_TYPE_X11: - case GST_VAAPI_DISPLAY_TYPE_GLX: - XSelectInput(gst_vaapi_display_x11_get_display(display), - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)), - StructureNotifyMask | ExposureMask); - break; -#endif - default: - break; - } + if (sink->backend->pre_start_event_thread) + sink->backend->pre_start_event_thread(sink); sink->event_thread_cancel = FALSE; sink->event_thread = g_thread_try_new("vaapisink-events", @@ -353,20 +538,8 @@ gst_vaapisink_set_event_handling(GstVideoOverlay *overlay, } else if (!handle_events && sink->event_thread) { GST_DEBUG("stopping xevent thread"); - if (sink->window) { - switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { -#if USE_X11 - case GST_VAAPI_DISPLAY_TYPE_X11: - case GST_VAAPI_DISPLAY_TYPE_GLX: - XSelectInput(gst_vaapi_display_x11_get_display(display), - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)), - 0); - break; -#endif - default: - break; - } - } + if (sink->backend->pre_stop_event_thread) + sink->backend->pre_stop_event_thread(sink); /* grab thread and mark it as NULL */ thread = sink->event_thread; @@ -400,61 +573,6 @@ gst_vaapisink_destroy(GstVaapiSink *sink) gst_caps_replace(&sink->caps, NULL); } -#if USE_X11 -/* Checks whether a ConfigureNotify event is in the queue */ -typedef struct _ConfigureNotifyEventPendingArgs ConfigureNotifyEventPendingArgs; -struct _ConfigureNotifyEventPendingArgs { - Window window; - guint width; - guint height; - gboolean match; -}; - -static Bool -configure_notify_event_pending_cb(Display *dpy, XEvent *xev, XPointer arg) -{ - ConfigureNotifyEventPendingArgs * const args = - (ConfigureNotifyEventPendingArgs *)arg; - - if (xev->type == ConfigureNotify && - xev->xconfigure.window == args->window && - xev->xconfigure.width == args->width && - xev->xconfigure.height == args->height) - args->match = TRUE; - - /* XXX: this is a hack to traverse the whole queue because we - can't use XPeekIfEvent() since it could block */ - return False; -} - -static gboolean -configure_notify_event_pending( - GstVaapiSink *sink, - Window window, - guint width, - guint height -) -{ - GstVaapiDisplayX11 * const display = - GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - ConfigureNotifyEventPendingArgs args; - XEvent xev; - - args.window = window; - args.width = width; - args.height = height; - args.match = FALSE; - - /* XXX: don't use XPeekIfEvent() because it might block */ - XCheckIfEvent( - gst_vaapi_display_x11_get_display(display), - &xev, - configure_notify_event_pending_cb, (XPointer)&args - ); - return args.match; -} -#endif - static const gchar * get_display_type_name(GstVaapiDisplayType display_type) { @@ -481,6 +599,33 @@ gst_vaapisink_display_changed(GstVaapiPluginBase *plugin) GST_INFO("created %s %p", get_display_type_name(plugin->display_type), plugin->display); + switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { +#if USE_DRM + case GST_VAAPI_DISPLAY_TYPE_DRM: + sink->backend = gst_vaapisink_backend_drm(); + break; +#endif +#if USE_X11 + case GST_VAAPI_DISPLAY_TYPE_X11: + sink->backend = gst_vaapisink_backend_x11(); + break; +#endif +#if USE_GLX + case GST_VAAPI_DISPLAY_TYPE_GLX: + sink->backend = gst_vaapisink_backend_x11(); + break; +#endif +#if USE_WAYLAND + case GST_VAAPI_DISPLAY_TYPE_WAYLAND: + sink->backend = gst_vaapisink_backend_wayland(); + break; +#endif + default: + GST_ERROR("failed to initialize GstVaapiSink backend"); + g_assert_not_reached(); + break; + } + sink->use_overlay = gst_vaapi_display_get_render_mode(plugin->display, &render_mode) && render_mode == GST_VAAPI_RENDER_MODE_OVERLAY; @@ -624,79 +769,9 @@ gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheig static inline gboolean gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) { - GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); - - if (!sink->window) { - const GstVaapiDisplayType display_type = - GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink); - switch (display_type) { -#if USE_X11 - case GST_VAAPI_DISPLAY_TYPE_GLX: - case GST_VAAPI_DISPLAY_TYPE_X11: - sink->window = gst_vaapi_window_x11_new(display, width, height); - if (!sink->window) - break; - gst_video_overlay_got_window_handle( - GST_VIDEO_OVERLAY(sink), - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) - ); - break; -#endif -#if USE_WAYLAND - case GST_VAAPI_DISPLAY_TYPE_WAYLAND: - sink->window = gst_vaapi_window_wayland_new(display, width, height); - break; -#endif - default: - GST_ERROR("unsupported display type %d", display_type); - return FALSE; - } - } - return sink->window != NULL; + return sink->window || sink->backend->create_window(sink, width, height); } -#if USE_X11 -static gboolean -gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) -{ - GstVaapiDisplay *display; - Window rootwin; - unsigned int width, height, border_width, depth; - int x, y; - XID xid = window_id; - - if (!gst_vaapisink_ensure_display(sink)) - return FALSE; - display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); - - gst_vaapi_display_lock(display); - XGetGeometry( - gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)), - xid, - &rootwin, - &x, &y, &width, &height, &border_width, &depth - ); - gst_vaapi_display_unlock(display); - - if ((width != sink->window_width || height != sink->window_height) && - !configure_notify_event_pending(sink, xid, width, height)) { - if (!gst_vaapisink_ensure_render_rect(sink, width, height)) - return FALSE; - sink->window_width = width; - sink->window_height = height; - } - - if (sink->window && - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) == xid) - return TRUE; - - gst_vaapi_window_replace(&sink->window, NULL); - - sink->window = gst_vaapi_window_x11_new_with_xid(display, xid); - return sink->window != NULL; -} -#endif - static gboolean gst_vaapisink_ensure_rotation(GstVaapiSink *sink, gboolean recalc_display_rect) { @@ -836,10 +911,8 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) return FALSE; display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); -#if USE_DRM if (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink) == GST_VAAPI_DISPLAY_TYPE_DRM) return TRUE; -#endif if (!gst_vaapi_plugin_base_set_caps(plugin, caps, NULL)) return FALSE; @@ -908,7 +981,6 @@ gst_vaapisink_show_frame_unlocked(GstVaapiSink *sink, GstBuffer *src_buffer) GstVaapiSurface *surface; GstBuffer *buffer; guint flags; - gboolean success; GstVaapiRectangle *surface_rect = NULL; #if GST_CHECK_VERSION(1,0,0) GstVaapiRectangle tmp_rect; @@ -978,30 +1050,7 @@ gst_vaapisink_show_frame_unlocked(GstVaapiSink *sink, GstBuffer *src_buffer) if (!gst_vaapi_apply_composition(surface, src_buffer)) GST_WARNING("could not update subtitles"); - switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { -#if USE_DRM - case GST_VAAPI_DISPLAY_TYPE_DRM: - success = TRUE; - break; -#endif -#if USE_X11 - case GST_VAAPI_DISPLAY_TYPE_GLX: - case GST_VAAPI_DISPLAY_TYPE_X11: - success = gst_vaapisink_put_surface(sink, surface, surface_rect, flags); - break; -#endif -#if USE_WAYLAND - case GST_VAAPI_DISPLAY_TYPE_WAYLAND: - success = gst_vaapisink_put_surface(sink, surface, surface_rect, flags); - break; -#endif - default: - GST_ERROR("unsupported display type %d", - GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)); - success = FALSE; - break; - } - if (!success) + if (!sink->backend->render_surface(sink, surface, surface_rect, flags)) goto error; /* Retain VA surface until the next one is displayed */ diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 5dc51012e8..f55dbf53db 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -57,11 +57,36 @@ G_BEGIN_DECLS typedef struct _GstVaapiSink GstVaapiSink; typedef struct _GstVaapiSinkClass GstVaapiSinkClass; +typedef struct _GstVaapiSinkBackend GstVaapiSinkBackend; + +typedef gboolean (*GstVaapiSinkCreateWindowFunc)(GstVaapiSink *sink, + guint width, guint height); +typedef gboolean (*GstVaapiSinkCreateWindowFromHandleFunc)(GstVaapiSink *sink, + guintptr window); +typedef gboolean (*GstVaapiSinkRenderSurfaceFunc)(GstVaapiSink *sink, + GstVaapiSurface *surface, const GstVaapiRectangle *surface_rect, guint flags); +typedef gboolean (*GstVaapiSinkHandleEventsFunc)(GstVaapiSink *sink); +typedef gboolean (*GstVaapiSinkPreStartEventThreadFunc)(GstVaapiSink *sink); +typedef gboolean (*GstVaapiSinkPreStopEventThreadFunc)(GstVaapiSink *sink); + +struct _GstVaapiSinkBackend { + GstVaapiSinkCreateWindowFunc create_window; + GstVaapiSinkCreateWindowFromHandleFunc create_window_from_handle; + GstVaapiSinkRenderSurfaceFunc render_surface; + + /* Event threads handling */ + gboolean event_thread_needed; + GstVaapiSinkHandleEventsFunc handle_events; + GstVaapiSinkPreStartEventThreadFunc pre_start_event_thread; + GstVaapiSinkPreStopEventThreadFunc pre_stop_event_thread; +}; struct _GstVaapiSink { /*< private >*/ GstVaapiPluginBase parent_instance; + const GstVaapiSinkBackend *backend; + GstCaps *caps; GstVaapiWindow *window; guint window_width; From 1824a80957c821c340f17694a1e759c11891f357 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 31 Jul 2014 10:37:57 +0200 Subject: [PATCH 1750/3781] vaapisink: re-indent all GstVaapiSink related source code. --- gst/vaapi/gstvaapisink.c | 1735 +++++++++++++++++++------------------- gst/vaapi/gstvaapisink.h | 129 ++- 2 files changed, 907 insertions(+), 957 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index fd2e3813e1..90470006cf 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -65,18 +65,18 @@ #define GST_PLUGIN_NAME "vaapisink" #define GST_PLUGIN_DESC "A VA-API based videosink" -GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink); +GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapisink); #define GST_CAT_DEFAULT gst_debug_vaapisink /* Default template */ static const char gst_vaapisink_sink_caps_str[] = #if GST_CHECK_VERSION(1,1,0) - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ";" - GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL); + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, + "{ ENCODED, NV12, I420, YV12 }") ";" + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL); #else #if GST_CHECK_VERSION(1,0,0) - GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) "; " + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) "; " #else "video/x-raw-yuv, " "width = (int) [ 1, MAX ], " @@ -86,66 +86,67 @@ static const char gst_vaapisink_sink_caps_str[] = #endif static GstStaticPadTemplate gst_vaapisink_sink_factory = - GST_STATIC_PAD_TEMPLATE( - "sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS(gst_vaapisink_sink_caps_str)); +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapisink_sink_caps_str)); static gboolean -gst_vaapisink_has_interface(GstVaapiPluginBase *plugin, GType type) +gst_vaapisink_has_interface (GstVaapiPluginBase * plugin, GType type) { - return type == GST_TYPE_VIDEO_OVERLAY; + return type == GST_TYPE_VIDEO_OVERLAY; } static void -gst_vaapisink_video_overlay_iface_init(GstVideoOverlayInterface *iface); +gst_vaapisink_video_overlay_iface_init (GstVideoOverlayInterface * iface); -G_DEFINE_TYPE_WITH_CODE( - GstVaapiSink, +G_DEFINE_TYPE_WITH_CODE (GstVaapiSink, gst_vaapisink, GST_TYPE_VIDEO_SINK, GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES - G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_OVERLAY, - gst_vaapisink_video_overlay_iface_init)) + G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY, + gst_vaapisink_video_overlay_iface_init)); -enum { - PROP_0, +enum +{ + PROP_0, - PROP_DISPLAY_TYPE, - PROP_DISPLAY_NAME, - PROP_FULLSCREEN, - PROP_ROTATION, - PROP_FORCE_ASPECT_RATIO, - PROP_VIEW_ID, + PROP_DISPLAY_TYPE, + PROP_DISPLAY_NAME, + PROP_FULLSCREEN, + PROP_ROTATION, + PROP_FORCE_ASPECT_RATIO, + PROP_VIEW_ID, }; #define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 -static inline gboolean -gst_vaapisink_ensure_display(GstVaapiSink *sink); +static gboolean +gst_vaapisink_ensure_display (GstVaapiSink * sink); /* GstVideoOverlay interface */ static void -gst_vaapisink_video_overlay_expose(GstVideoOverlay *overlay); +gst_vaapisink_video_overlay_expose (GstVideoOverlay * overlay); static gboolean -gst_vaapisink_reconfigure_window(GstVaapiSink * sink); +gst_vaapisink_reconfigure_window (GstVaapiSink * sink); static void -gst_vaapisink_set_event_handling(GstVideoOverlay *overlay, gboolean handle_events); +gst_vaapisink_set_event_handling (GstVideoOverlay * overlay, + gboolean handle_events); static GstFlowReturn -gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer); +gst_vaapisink_show_frame (GstBaseSink * base_sink, GstBuffer * buffer); static gboolean -gst_vaapisink_put_surface(GstVaapiSink *sink, GstVaapiSurface *surface, - const GstVaapiRectangle *surface_rect, guint flags); +gst_vaapisink_put_surface (GstVaapiSink * sink, GstVaapiSurface * surface, + const GstVaapiRectangle * surface_rect, guint flags); static gboolean -gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height); +gst_vaapisink_ensure_render_rect (GstVaapiSink * sink, guint width, + guint height); /* ------------------------------------------------------------------------ */ /* --- DRM Backend --- */ @@ -155,29 +156,30 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height); #include static gboolean -gst_vaapisink_drm_create_window(GstVaapiSink *sink, guint width, guint height) +gst_vaapisink_drm_create_window (GstVaapiSink * sink, guint width, guint height) { - g_return_val_if_fail(sink->window == NULL, FALSE); + g_return_val_if_fail (sink->window == NULL, FALSE); - GST_ERROR("failed to create a window for VA/DRM display"); - return FALSE; + GST_ERROR ("failed to create a window for VA/DRM display"); + return FALSE; } static gboolean -gst_vaapisink_drm_render_surface(GstVaapiSink *sink, GstVaapiSurface *surface, - const GstVaapiRectangle *surface_rect, guint flags) +gst_vaapisink_drm_render_surface (GstVaapiSink * sink, + GstVaapiSurface * surface, const GstVaapiRectangle * surface_rect, + guint flags) { - return TRUE; + return TRUE; } static const inline GstVaapiSinkBackend * -gst_vaapisink_backend_drm(void) +gst_vaapisink_backend_drm (void) { - static const GstVaapiSinkBackend GstVaapiSinkBackendDRM = { - .create_window = gst_vaapisink_drm_create_window, - .render_surface = gst_vaapisink_drm_render_surface, - }; - return &GstVaapiSinkBackendDRM; + static const GstVaapiSinkBackend GstVaapiSinkBackendDRM = { + .create_window = gst_vaapisink_drm_create_window, + .render_surface = gst_vaapisink_drm_render_surface, + }; + return &GstVaapiSinkBackendDRM; } #endif @@ -191,196 +193,192 @@ gst_vaapisink_backend_drm(void) /* Checks whether a ConfigureNotify event is in the queue */ typedef struct _ConfigureNotifyEventPendingArgs ConfigureNotifyEventPendingArgs; -struct _ConfigureNotifyEventPendingArgs { - Window window; - guint width; - guint height; - gboolean match; +struct _ConfigureNotifyEventPendingArgs +{ + Window window; + guint width; + guint height; + gboolean match; }; static Bool -configure_notify_event_pending_cb(Display *dpy, XEvent *xev, XPointer arg) +configure_notify_event_pending_cb (Display * dpy, XEvent * xev, XPointer arg) { - ConfigureNotifyEventPendingArgs * const args = - (ConfigureNotifyEventPendingArgs *)arg; + ConfigureNotifyEventPendingArgs *const args = + (ConfigureNotifyEventPendingArgs *) arg; - if (xev->type == ConfigureNotify && - xev->xconfigure.window == args->window && - xev->xconfigure.width == args->width && - xev->xconfigure.height == args->height) - args->match = TRUE; + if (xev->type == ConfigureNotify && + xev->xconfigure.window == args->window && + xev->xconfigure.width == args->width && + xev->xconfigure.height == args->height) + args->match = TRUE; - /* XXX: this is a hack to traverse the whole queue because we - can't use XPeekIfEvent() since it could block */ - return False; + /* XXX: this is a hack to traverse the whole queue because we + can't use XPeekIfEvent() since it could block */ + return False; } static gboolean -configure_notify_event_pending(GstVaapiSink *sink, Window window, +configure_notify_event_pending (GstVaapiSink * sink, Window window, guint width, guint height) { - GstVaapiDisplayX11 * const display = - GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - ConfigureNotifyEventPendingArgs args; - XEvent xev; + GstVaapiDisplayX11 *const display = + GST_VAAPI_DISPLAY_X11 (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); + ConfigureNotifyEventPendingArgs args; + XEvent xev; - args.window = window; - args.width = width; - args.height = height; - args.match = FALSE; + args.window = window; + args.width = width; + args.height = height; + args.match = FALSE; - /* XXX: don't use XPeekIfEvent() because it might block */ - XCheckIfEvent( - gst_vaapi_display_x11_get_display(display), - &xev, - configure_notify_event_pending_cb, (XPointer)&args - ); - return args.match; + /* XXX: don't use XPeekIfEvent() because it might block */ + XCheckIfEvent (gst_vaapi_display_x11_get_display (display), + &xev, configure_notify_event_pending_cb, (XPointer) & args); + return args.match; } static gboolean -gst_vaapisink_x11_create_window(GstVaapiSink *sink, guint width, guint height) +gst_vaapisink_x11_create_window (GstVaapiSink * sink, guint width, guint height) { - GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); + GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); - g_return_val_if_fail(sink->window == NULL, FALSE); + g_return_val_if_fail (sink->window == NULL, FALSE); - sink->window = gst_vaapi_window_x11_new(display, width, height); + sink->window = gst_vaapi_window_x11_new (display, width, height); + if (!sink->window) + return FALSE; + + gst_video_overlay_got_window_handle (GST_VIDEO_OVERLAY (sink), + gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (sink->window))); + return TRUE; +} + +static gboolean +gst_vaapisink_x11_create_window_from_handle (GstVaapiSink * sink, + guintptr window) +{ + GstVaapiDisplay *display; + Window rootwin; + unsigned int width, height, border_width, depth; + int x, y; + XID xid = window; + + if (!gst_vaapisink_ensure_display (sink)) + return FALSE; + display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); + + gst_vaapi_display_lock (display); + XGetGeometry (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 + (display)), xid, &rootwin, &x, &y, &width, &height, &border_width, + &depth); + gst_vaapi_display_unlock (display); + + if ((width != sink->window_width || height != sink->window_height) && + !configure_notify_event_pending (sink, xid, width, height)) { + if (!gst_vaapisink_ensure_render_rect (sink, width, height)) + return FALSE; + sink->window_width = width; + sink->window_height = height; + } + + if (!sink->window + || gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (sink->window)) != + xid) { + gst_vaapi_window_replace (&sink->window, NULL); + sink->window = gst_vaapi_window_x11_new_with_xid (display, xid); if (!sink->window) - return FALSE; + return FALSE; + } - gst_video_overlay_got_window_handle(GST_VIDEO_OVERLAY(sink), - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window))); - return TRUE; + gst_vaapisink_set_event_handling (GST_VIDEO_OVERLAY (sink), + sink->handle_events); + return TRUE; } static gboolean -gst_vaapisink_x11_create_window_from_handle(GstVaapiSink *sink, guintptr window) +gst_vaapisink_x11_handle_events (GstVaapiSink * sink) { - GstVaapiDisplay *display; - Window rootwin; - unsigned int width, height, border_width, depth; - int x, y; - XID xid = window; + GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); + gboolean has_events, do_expose = FALSE; + XEvent e; - if (!gst_vaapisink_ensure_display(sink)) - return FALSE; - display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); + if (sink->window) { + Display *const x11_dpy = + gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display)); + Window x11_win = + gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (sink->window)); - gst_vaapi_display_lock(display); - XGetGeometry( - gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)), - xid, - &rootwin, - &x, &y, &width, &height, &border_width, &depth - ); - gst_vaapi_display_unlock(display); + /* Handle Expose + ConfigureNotify */ + /* Need to lock whole loop or we corrupt the XEvent queue: */ + for (;;) { + gst_vaapi_display_lock (display); + has_events = XCheckWindowEvent (x11_dpy, x11_win, + StructureNotifyMask | ExposureMask, &e); + gst_vaapi_display_unlock (display); + if (!has_events) + break; - if ((width != sink->window_width || height != sink->window_height) && - !configure_notify_event_pending(sink, xid, width, height)) { - if (!gst_vaapisink_ensure_render_rect(sink, width, height)) - return FALSE; - sink->window_width = width; - sink->window_height = height; + switch (e.type) { + case Expose: + do_expose = TRUE; + break; + case ConfigureNotify: + if (gst_vaapisink_reconfigure_window (sink)) + do_expose = TRUE; + break; + default: + break; + } } - - if (!sink->window || gst_vaapi_window_x11_get_xid( - GST_VAAPI_WINDOW_X11(sink->window)) != xid) { - gst_vaapi_window_replace(&sink->window, NULL); - sink->window = gst_vaapi_window_x11_new_with_xid(display, xid); - if (!sink->window) - return FALSE; - } - - gst_vaapisink_set_event_handling(GST_VIDEO_OVERLAY(sink), - sink->handle_events); - return TRUE; + if (do_expose) + gst_vaapisink_video_overlay_expose (GST_VIDEO_OVERLAY (sink)); + /* FIXME: handle mouse and key events */ + } + return TRUE; } static gboolean -gst_vaapisink_x11_handle_events(GstVaapiSink *sink) +gst_vaapisink_x11_pre_start_event_thread (GstVaapiSink * sink) { - GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); - gboolean has_events, do_expose = FALSE; - XEvent e; + GstVaapiDisplayX11 *const display = + GST_VAAPI_DISPLAY_X11 (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); - if (sink->window) { - Display * const x11_dpy = - gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)); - Window x11_win = - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)); - - /* Handle Expose + ConfigureNotify */ - /* Need to lock whole loop or we corrupt the XEvent queue: */ - for (;;) { - gst_vaapi_display_lock(display); - has_events = XCheckWindowEvent(x11_dpy, x11_win, - StructureNotifyMask | ExposureMask, &e); - gst_vaapi_display_unlock(display); - if (!has_events) - break; - - switch (e.type) { - case Expose: - do_expose = TRUE; - break; - case ConfigureNotify: - if (gst_vaapisink_reconfigure_window(sink)) - do_expose = TRUE; - break; - default: - break; - } - } - if (do_expose) - gst_vaapisink_video_overlay_expose(GST_VIDEO_OVERLAY(sink)); - /* FIXME: handle mouse and key events */ - } - return TRUE; + if (sink->window) { + XSelectInput (gst_vaapi_display_x11_get_display (display), + gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (sink->window)), + StructureNotifyMask | ExposureMask); + } + return TRUE; } static gboolean -gst_vaapisink_x11_pre_start_event_thread(GstVaapiSink *sink) +gst_vaapisink_x11_pre_stop_event_thread (GstVaapiSink * sink) { - GstVaapiDisplayX11 * const display = - GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); + GstVaapiDisplayX11 *const display = + GST_VAAPI_DISPLAY_X11 (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); - if (sink->window) { - XSelectInput(gst_vaapi_display_x11_get_display(display), - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)), - StructureNotifyMask | ExposureMask); - } - return TRUE; -} - -static gboolean -gst_vaapisink_x11_pre_stop_event_thread(GstVaapiSink *sink) -{ - GstVaapiDisplayX11 * const display = - GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - - if (sink->window) { - XSelectInput(gst_vaapi_display_x11_get_display(display), - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)), - 0); - } - return TRUE; + if (sink->window) { + XSelectInput (gst_vaapi_display_x11_get_display (display), + gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (sink->window)), 0); + } + return TRUE; } static const inline GstVaapiSinkBackend * -gst_vaapisink_backend_x11(void) +gst_vaapisink_backend_x11 (void) { - static const GstVaapiSinkBackend GstVaapiSinkBackendX11 = { - .create_window = gst_vaapisink_x11_create_window, - .create_window_from_handle = gst_vaapisink_x11_create_window_from_handle, - .render_surface = gst_vaapisink_put_surface, + static const GstVaapiSinkBackend GstVaapiSinkBackendX11 = { + .create_window = gst_vaapisink_x11_create_window, + .create_window_from_handle = gst_vaapisink_x11_create_window_from_handle, + .render_surface = gst_vaapisink_put_surface, - .event_thread_needed = TRUE, - .handle_events = gst_vaapisink_x11_handle_events, - .pre_start_event_thread = gst_vaapisink_x11_pre_start_event_thread, - .pre_stop_event_thread = gst_vaapisink_x11_pre_stop_event_thread, - }; - return &GstVaapiSinkBackendX11; + .event_thread_needed = TRUE, + .handle_events = gst_vaapisink_x11_handle_events, + .pre_start_event_thread = gst_vaapisink_x11_pre_start_event_thread, + .pre_stop_event_thread = gst_vaapisink_x11_pre_stop_event_thread, + }; + return &GstVaapiSinkBackendX11; } #endif @@ -393,27 +391,27 @@ gst_vaapisink_backend_x11(void) #include static gboolean -gst_vaapisink_wayland_create_window(GstVaapiSink *sink, guint width, +gst_vaapisink_wayland_create_window (GstVaapiSink * sink, guint width, guint height) { - GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); + GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); - g_return_val_if_fail(sink->window == NULL, FALSE); + g_return_val_if_fail (sink->window == NULL, FALSE); - sink->window = gst_vaapi_window_wayland_new(display, width, height); - if (!sink->window) - return FALSE; - return TRUE; + sink->window = gst_vaapi_window_wayland_new (display, width, height); + if (!sink->window) + return FALSE; + return TRUE; } static const inline GstVaapiSinkBackend * -gst_vaapisink_backend_wayland(void) +gst_vaapisink_backend_wayland (void) { - static const GstVaapiSinkBackend GstVaapiSinkBackendWayland = { - .create_window = gst_vaapisink_wayland_create_window, - .render_surface = gst_vaapisink_put_surface, - }; - return &GstVaapiSinkBackendWayland; + static const GstVaapiSinkBackend GstVaapiSinkBackendWayland = { + .create_window = gst_vaapisink_wayland_create_window, + .render_surface = gst_vaapisink_put_surface, + }; + return &GstVaapiSinkBackendWayland; } #endif @@ -422,941 +420,900 @@ gst_vaapisink_backend_wayland(void) /* ------------------------------------------------------------------------ */ static void -gst_vaapisink_video_overlay_set_window_handle(GstVideoOverlay *overlay, +gst_vaapisink_video_overlay_set_window_handle (GstVideoOverlay * overlay, guintptr window) { - GstVaapiSink * const sink = GST_VAAPISINK(overlay); - const GstVaapiSinkBackend * const backend = sink->backend; - GstVaapiDisplayType display_type; + GstVaapiSink *const sink = GST_VAAPISINK (overlay); + const GstVaapiSinkBackend *const backend = sink->backend; + GstVaapiDisplayType display_type; - if (!gst_vaapisink_ensure_display(sink)) - return; + if (!gst_vaapisink_ensure_display (sink)) + return; - display_type = GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink); + display_type = GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE (sink); - /* Disable GLX rendering when vaapisink is using a foreign X - window. It's pretty much useless */ - if (display_type == GST_VAAPI_DISPLAY_TYPE_GLX) { - display_type = GST_VAAPI_DISPLAY_TYPE_X11; - gst_vaapi_plugin_base_set_display_type(GST_VAAPI_PLUGIN_BASE(sink), - display_type); - } + /* Disable GLX rendering when vaapisink is using a foreign X + window. It's pretty much useless */ + if (display_type == GST_VAAPI_DISPLAY_TYPE_GLX) { + display_type = GST_VAAPI_DISPLAY_TYPE_X11; + gst_vaapi_plugin_base_set_display_type (GST_VAAPI_PLUGIN_BASE (sink), + display_type); + } - sink->foreign_window = TRUE; - if (backend->create_window_from_handle) - backend->create_window_from_handle(sink, window); + sink->foreign_window = TRUE; + if (backend->create_window_from_handle) + backend->create_window_from_handle (sink, window); } static void -gst_vaapisink_video_overlay_set_render_rectangle( - GstVideoOverlay *overlay, - gint x, - gint y, - gint width, - gint height -) +gst_vaapisink_video_overlay_set_render_rectangle (GstVideoOverlay * overlay, + gint x, gint y, gint width, gint height) { - GstVaapiSink * const sink = GST_VAAPISINK(overlay); - GstVaapiRectangle * const display_rect = &sink->display_rect; + GstVaapiSink *const sink = GST_VAAPISINK (overlay); + GstVaapiRectangle *const display_rect = &sink->display_rect; - display_rect->x = x; - display_rect->y = y; - display_rect->width = width; - display_rect->height = height; - - GST_DEBUG("render rect (%d,%d):%ux%u", - display_rect->x, display_rect->y, - display_rect->width, display_rect->height); + display_rect->x = x; + display_rect->y = y; + display_rect->width = width; + display_rect->height = height; + + GST_DEBUG ("render rect (%d,%d):%ux%u", + display_rect->x, display_rect->y, + display_rect->width, display_rect->height); } static gboolean -gst_vaapisink_reconfigure_window(GstVaapiSink * sink) +gst_vaapisink_reconfigure_window (GstVaapiSink * sink) { - guint win_width, win_height; + guint win_width, win_height; - gst_vaapi_window_reconfigure(sink->window); - gst_vaapi_window_get_size(sink->window, &win_width, &win_height); - if (win_width != sink->window_width || win_height != sink->window_height) { - if (!gst_vaapisink_ensure_render_rect(sink, win_width, win_height)) - return FALSE; - GST_INFO("window was resized from %ux%u to %ux%u", - sink->window_width, sink->window_height, win_width, win_height); - sink->window_width = win_width; - sink->window_height = win_height; - return TRUE; - } - return FALSE; + gst_vaapi_window_reconfigure (sink->window); + gst_vaapi_window_get_size (sink->window, &win_width, &win_height); + if (win_width != sink->window_width || win_height != sink->window_height) { + if (!gst_vaapisink_ensure_render_rect (sink, win_width, win_height)) + return FALSE; + GST_INFO ("window was resized from %ux%u to %ux%u", + sink->window_width, sink->window_height, win_width, win_height); + sink->window_width = win_width; + sink->window_height = win_height; + return TRUE; + } + return FALSE; } static gpointer -gst_vaapisink_event_thread (GstVaapiSink *sink) +gst_vaapisink_event_thread (GstVaapiSink * sink) { - GST_OBJECT_LOCK(sink); - while (!sink->event_thread_cancel) { - GST_OBJECT_UNLOCK(sink); - sink->backend->handle_events(sink); - g_usleep(G_USEC_PER_SEC / 20); - GST_OBJECT_LOCK(sink); - } - GST_OBJECT_UNLOCK(sink); + GST_OBJECT_LOCK (sink); + while (!sink->event_thread_cancel) { + GST_OBJECT_UNLOCK (sink); + sink->backend->handle_events (sink); + g_usleep (G_USEC_PER_SEC / 20); + GST_OBJECT_LOCK (sink); + } + GST_OBJECT_UNLOCK (sink); return NULL; } static void -gst_vaapisink_video_overlay_expose(GstVideoOverlay *overlay) +gst_vaapisink_video_overlay_expose (GstVideoOverlay * overlay) { - GstVaapiSink * const sink = GST_VAAPISINK(overlay); + GstVaapiSink *const sink = GST_VAAPISINK (overlay); - if (sink->video_buffer) { - gst_vaapisink_reconfigure_window(sink); - gst_vaapisink_show_frame(GST_BASE_SINK_CAST(sink), sink->video_buffer); - } + if (sink->video_buffer) { + gst_vaapisink_reconfigure_window (sink); + gst_vaapisink_show_frame (GST_BASE_SINK_CAST (sink), sink->video_buffer); + } } static void -gst_vaapisink_set_event_handling(GstVideoOverlay *overlay, +gst_vaapisink_set_event_handling (GstVideoOverlay * overlay, gboolean handle_events) { - GThread *thread = NULL; - GstVaapiSink * const sink = GST_VAAPISINK(overlay); + GThread *thread = NULL; + GstVaapiSink *const sink = GST_VAAPISINK (overlay); - if (!sink->backend->event_thread_needed) - return; + if (!sink->backend->event_thread_needed) + return; - GST_OBJECT_LOCK(sink); - sink->handle_events = handle_events; - if (handle_events && !sink->event_thread) { - /* Setup our event listening thread */ - GST_DEBUG("starting xevent thread"); - if (sink->backend->pre_start_event_thread) - sink->backend->pre_start_event_thread(sink); + GST_OBJECT_LOCK (sink); + sink->handle_events = handle_events; + if (handle_events && !sink->event_thread) { + /* Setup our event listening thread */ + GST_DEBUG ("starting xevent thread"); + if (sink->backend->pre_start_event_thread) + sink->backend->pre_start_event_thread (sink); - sink->event_thread_cancel = FALSE; - sink->event_thread = g_thread_try_new("vaapisink-events", - (GThreadFunc) gst_vaapisink_event_thread, sink, NULL); - } - else if (!handle_events && sink->event_thread) { - GST_DEBUG("stopping xevent thread"); - if (sink->backend->pre_stop_event_thread) - sink->backend->pre_stop_event_thread(sink); + sink->event_thread_cancel = FALSE; + sink->event_thread = g_thread_try_new ("vaapisink-events", + (GThreadFunc) gst_vaapisink_event_thread, sink, NULL); + } else if (!handle_events && sink->event_thread) { + GST_DEBUG ("stopping xevent thread"); + if (sink->backend->pre_stop_event_thread) + sink->backend->pre_stop_event_thread (sink); - /* grab thread and mark it as NULL */ - thread = sink->event_thread; - sink->event_thread = NULL; - sink->event_thread_cancel = TRUE; - } - GST_OBJECT_UNLOCK(sink); + /* grab thread and mark it as NULL */ + thread = sink->event_thread; + sink->event_thread = NULL; + sink->event_thread_cancel = TRUE; + } + GST_OBJECT_UNLOCK (sink); - /* Wait for our event thread to finish */ - if (thread) { - g_thread_join(thread); - GST_DEBUG("xevent thread stopped"); - } + /* Wait for our event thread to finish */ + if (thread) { + g_thread_join (thread); + GST_DEBUG ("xevent thread stopped"); + } } static void -gst_vaapisink_video_overlay_iface_init(GstVideoOverlayInterface *iface) +gst_vaapisink_video_overlay_iface_init (GstVideoOverlayInterface * iface) { - iface->set_window_handle = gst_vaapisink_video_overlay_set_window_handle; - iface->set_render_rectangle = gst_vaapisink_video_overlay_set_render_rectangle; - iface->expose = gst_vaapisink_video_overlay_expose; - iface->handle_events = gst_vaapisink_set_event_handling; + iface->set_window_handle = gst_vaapisink_video_overlay_set_window_handle; + iface->set_render_rectangle = + gst_vaapisink_video_overlay_set_render_rectangle; + iface->expose = gst_vaapisink_video_overlay_expose; + iface->handle_events = gst_vaapisink_set_event_handling; } static void -gst_vaapisink_destroy(GstVaapiSink *sink) +gst_vaapisink_destroy (GstVaapiSink * sink) { - gst_vaapisink_set_event_handling(GST_VIDEO_OVERLAY(sink), FALSE); + gst_vaapisink_set_event_handling (GST_VIDEO_OVERLAY (sink), FALSE); - gst_buffer_replace(&sink->video_buffer, NULL); - gst_caps_replace(&sink->caps, NULL); + gst_buffer_replace (&sink->video_buffer, NULL); + gst_caps_replace (&sink->caps, NULL); } static const gchar * -get_display_type_name(GstVaapiDisplayType display_type) +get_display_type_name (GstVaapiDisplayType display_type) { - gpointer const klass = g_type_class_peek(GST_VAAPI_TYPE_DISPLAY_TYPE); - GEnumValue * const e = g_enum_get_value(klass, display_type); + gpointer const klass = g_type_class_peek (GST_VAAPI_TYPE_DISPLAY_TYPE); + GEnumValue *const e = g_enum_get_value (klass, display_type); - if (e) - return e->value_name; - return ""; + if (e) + return e->value_name; + return ""; } -static inline gboolean -gst_vaapisink_ensure_display(GstVaapiSink *sink) +static gboolean +gst_vaapisink_ensure_display (GstVaapiSink * sink) { - return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(sink)); + return gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (sink)); } static void -gst_vaapisink_display_changed(GstVaapiPluginBase *plugin) +gst_vaapisink_display_changed (GstVaapiPluginBase * plugin) { - GstVaapiSink * const sink = GST_VAAPISINK(plugin); - GstVaapiRenderMode render_mode; + GstVaapiSink *const sink = GST_VAAPISINK (plugin); + GstVaapiRenderMode render_mode; - GST_INFO("created %s %p", get_display_type_name(plugin->display_type), - plugin->display); + GST_INFO ("created %s %p", get_display_type_name (plugin->display_type), + plugin->display); - switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) { + switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE (sink)) { #if USE_DRM case GST_VAAPI_DISPLAY_TYPE_DRM: - sink->backend = gst_vaapisink_backend_drm(); - break; + sink->backend = gst_vaapisink_backend_drm (); + break; #endif #if USE_X11 case GST_VAAPI_DISPLAY_TYPE_X11: - sink->backend = gst_vaapisink_backend_x11(); - break; + sink->backend = gst_vaapisink_backend_x11 (); + break; #endif #if USE_GLX case GST_VAAPI_DISPLAY_TYPE_GLX: - sink->backend = gst_vaapisink_backend_x11(); - break; + sink->backend = gst_vaapisink_backend_x11 (); + break; #endif #if USE_WAYLAND case GST_VAAPI_DISPLAY_TYPE_WAYLAND: - sink->backend = gst_vaapisink_backend_wayland(); - break; + sink->backend = gst_vaapisink_backend_wayland (); + break; #endif default: - GST_ERROR("failed to initialize GstVaapiSink backend"); - g_assert_not_reached(); - break; - } + GST_ERROR ("failed to initialize GstVaapiSink backend"); + g_assert_not_reached (); + break; + } - sink->use_overlay = - gst_vaapi_display_get_render_mode(plugin->display, &render_mode) && - render_mode == GST_VAAPI_RENDER_MODE_OVERLAY; - GST_DEBUG("use %s rendering mode", - sink->use_overlay ? "overlay" : "texture"); + sink->use_overlay = + gst_vaapi_display_get_render_mode (plugin->display, &render_mode) && + render_mode == GST_VAAPI_RENDER_MODE_OVERLAY; + GST_DEBUG ("use %s rendering mode", + sink->use_overlay ? "overlay" : "texture"); - sink->use_rotation = gst_vaapi_display_has_property(plugin->display, - GST_VAAPI_DISPLAY_PROP_ROTATION); + sink->use_rotation = gst_vaapi_display_has_property (plugin->display, + GST_VAAPI_DISPLAY_PROP_ROTATION); } static gboolean -gst_vaapisink_ensure_uploader(GstVaapiSink *sink) +gst_vaapisink_ensure_uploader (GstVaapiSink * sink) { - if (!gst_vaapisink_ensure_display(sink)) - return FALSE; - if (!gst_vaapi_plugin_base_ensure_uploader(GST_VAAPI_PLUGIN_BASE(sink))) - return FALSE; - return TRUE; + if (!gst_vaapisink_ensure_display (sink)) + return FALSE; + if (!gst_vaapi_plugin_base_ensure_uploader (GST_VAAPI_PLUGIN_BASE (sink))) + return FALSE; + return TRUE; } static gboolean -gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height) +gst_vaapisink_ensure_render_rect (GstVaapiSink * sink, guint width, + guint height) { - GstVaapiRectangle * const display_rect = &sink->display_rect; - guint num, den, display_par_n, display_par_d; - gboolean success; + GstVaapiRectangle *const display_rect = &sink->display_rect; + guint num, den, display_par_n, display_par_d; + gboolean success; - /* Return success if caps are not set yet */ - if (!sink->caps) - return TRUE; - - if (!sink->keep_aspect) { - display_rect->width = width; - display_rect->height = height; - display_rect->x = 0; - display_rect->y = 0; - - GST_DEBUG("force-aspect-ratio is false; distorting while scaling video"); - GST_DEBUG("render rect (%d,%d):%ux%u", - display_rect->x, display_rect->y, - display_rect->width, display_rect->height); - return TRUE; - } - - GST_DEBUG("ensure render rect within %ux%u bounds", width, height); - - gst_vaapi_display_get_pixel_aspect_ratio( - GST_VAAPI_PLUGIN_BASE_DISPLAY(sink), - &display_par_n, &display_par_d - ); - GST_DEBUG("display pixel-aspect-ratio %d/%d", - display_par_n, display_par_d); - - success = gst_video_calculate_display_ratio( - &num, &den, - sink->video_width, sink->video_height, - sink->video_par_n, sink->video_par_d, - display_par_n, display_par_d - ); - if (!success) - return FALSE; - GST_DEBUG("video size %dx%d, calculated ratio %d/%d", - sink->video_width, sink->video_height, num, den); - - display_rect->width = gst_util_uint64_scale_int(height, num, den); - if (display_rect->width <= width) { - GST_DEBUG("keeping window height"); - display_rect->height = height; - } - else { - GST_DEBUG("keeping window width"); - display_rect->width = width; - display_rect->height = - gst_util_uint64_scale_int(width, den, num); - } - GST_DEBUG("scaling video to %ux%u", display_rect->width, display_rect->height); - - g_assert(display_rect->width <= width); - g_assert(display_rect->height <= height); - - display_rect->x = (width - display_rect->width) / 2; - display_rect->y = (height - display_rect->height) / 2; - - GST_DEBUG("render rect (%d,%d):%ux%u", - display_rect->x, display_rect->y, - display_rect->width, display_rect->height); + /* Return success if caps are not set yet */ + if (!sink->caps) return TRUE; + + if (!sink->keep_aspect) { + display_rect->width = width; + display_rect->height = height; + display_rect->x = 0; + display_rect->y = 0; + + GST_DEBUG ("force-aspect-ratio is false; distorting while scaling video"); + GST_DEBUG ("render rect (%d,%d):%ux%u", + display_rect->x, display_rect->y, + display_rect->width, display_rect->height); + return TRUE; + } + + GST_DEBUG ("ensure render rect within %ux%u bounds", width, height); + + gst_vaapi_display_get_pixel_aspect_ratio (GST_VAAPI_PLUGIN_BASE_DISPLAY + (sink), &display_par_n, &display_par_d); + GST_DEBUG ("display pixel-aspect-ratio %d/%d", display_par_n, display_par_d); + + success = gst_video_calculate_display_ratio (&num, &den, + sink->video_width, sink->video_height, + sink->video_par_n, sink->video_par_d, display_par_n, display_par_d); + if (!success) + return FALSE; + GST_DEBUG ("video size %dx%d, calculated ratio %d/%d", + sink->video_width, sink->video_height, num, den); + + display_rect->width = gst_util_uint64_scale_int (height, num, den); + if (display_rect->width <= width) { + GST_DEBUG ("keeping window height"); + display_rect->height = height; + } else { + GST_DEBUG ("keeping window width"); + display_rect->width = width; + display_rect->height = gst_util_uint64_scale_int (width, den, num); + } + GST_DEBUG ("scaling video to %ux%u", display_rect->width, + display_rect->height); + + g_assert (display_rect->width <= width); + g_assert (display_rect->height <= height); + + display_rect->x = (width - display_rect->width) / 2; + display_rect->y = (height - display_rect->height) / 2; + + GST_DEBUG ("render rect (%d,%d):%ux%u", + display_rect->x, display_rect->y, + display_rect->width, display_rect->height); + return TRUE; } static void -gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheight) +gst_vaapisink_ensure_window_size (GstVaapiSink * sink, guint * pwidth, + guint * pheight) { - GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); - GstVideoRectangle src_rect, dst_rect, out_rect; - guint num, den, display_width, display_height, display_par_n, display_par_d; - gboolean success, scale; + GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); + GstVideoRectangle src_rect, dst_rect, out_rect; + guint num, den, display_width, display_height, display_par_n, display_par_d; + gboolean success, scale; - if (sink->foreign_window) { - *pwidth = sink->window_width; - *pheight = sink->window_height; - return; - } + if (sink->foreign_window) { + *pwidth = sink->window_width; + *pheight = sink->window_height; + return; + } - gst_vaapi_display_get_size(display, &display_width, &display_height); - if (sink->fullscreen) { - *pwidth = display_width; - *pheight = display_height; - return; - } + gst_vaapi_display_get_size (display, &display_width, &display_height); + if (sink->fullscreen) { + *pwidth = display_width; + *pheight = display_height; + return; + } - gst_vaapi_display_get_pixel_aspect_ratio( - display, - &display_par_n, &display_par_d - ); + gst_vaapi_display_get_pixel_aspect_ratio (display, + &display_par_n, &display_par_d); - success = gst_video_calculate_display_ratio( - &num, &den, - sink->video_width, sink->video_height, - sink->video_par_n, sink->video_par_d, - display_par_n, display_par_d - ); - if (!success) { - num = sink->video_par_n; - den = sink->video_par_d; - } + success = gst_video_calculate_display_ratio (&num, &den, + sink->video_width, sink->video_height, + sink->video_par_n, sink->video_par_d, display_par_n, display_par_d); + if (!success) { + num = sink->video_par_n; + den = sink->video_par_d; + } - src_rect.x = 0; - src_rect.y = 0; - src_rect.w = gst_util_uint64_scale_int(sink->video_height, num, den); - src_rect.h = sink->video_height; - dst_rect.x = 0; - dst_rect.y = 0; - dst_rect.w = display_width; - dst_rect.h = display_height; - scale = (src_rect.w > dst_rect.w || src_rect.h > dst_rect.h); - gst_video_sink_center_rect(src_rect, dst_rect, &out_rect, scale); - *pwidth = out_rect.w; - *pheight = out_rect.h; + src_rect.x = 0; + src_rect.y = 0; + src_rect.w = gst_util_uint64_scale_int (sink->video_height, num, den); + src_rect.h = sink->video_height; + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.w = display_width; + dst_rect.h = display_height; + scale = (src_rect.w > dst_rect.w || src_rect.h > dst_rect.h); + gst_video_sink_center_rect (src_rect, dst_rect, &out_rect, scale); + *pwidth = out_rect.w; + *pheight = out_rect.h; } static inline gboolean -gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height) +gst_vaapisink_ensure_window (GstVaapiSink * sink, guint width, guint height) { - return sink->window || sink->backend->create_window(sink, width, height); + return sink->window || sink->backend->create_window (sink, width, height); } static gboolean -gst_vaapisink_ensure_rotation(GstVaapiSink *sink, gboolean recalc_display_rect) +gst_vaapisink_ensure_rotation (GstVaapiSink * sink, + gboolean recalc_display_rect) { - GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); - gboolean success = FALSE; + GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); + gboolean success = FALSE; - g_return_val_if_fail(display, FALSE); + g_return_val_if_fail (display, FALSE); - if (sink->rotation == sink->rotation_req) - return TRUE; + if (sink->rotation == sink->rotation_req) + return TRUE; - if (!sink->use_rotation) { - GST_WARNING("VA display does not support rotation"); - goto end; - } + if (!sink->use_rotation) { + GST_WARNING ("VA display does not support rotation"); + goto end; + } - gst_vaapi_display_lock(display); - success = gst_vaapi_display_set_rotation(display, sink->rotation_req); - gst_vaapi_display_unlock(display); - if (!success) { - GST_ERROR("failed to change VA display rotation mode"); - goto end; - } + gst_vaapi_display_lock (display); + success = gst_vaapi_display_set_rotation (display, sink->rotation_req); + gst_vaapi_display_unlock (display); + if (!success) { + GST_ERROR ("failed to change VA display rotation mode"); + goto end; + } - if (((sink->rotation + sink->rotation_req) % 180) == 90) { - /* Orientation changed */ - G_PRIMITIVE_SWAP(guint, sink->video_width, sink->video_height); - G_PRIMITIVE_SWAP(gint, sink->video_par_n, sink->video_par_d); - } + if (((sink->rotation + sink->rotation_req) % 180) == 90) { + /* Orientation changed */ + G_PRIMITIVE_SWAP (guint, sink->video_width, sink->video_height); + G_PRIMITIVE_SWAP (gint, sink->video_par_n, sink->video_par_d); + } - if (recalc_display_rect && !sink->foreign_window) - gst_vaapisink_ensure_render_rect(sink, sink->window_width, - sink->window_height); - success = TRUE; + if (recalc_display_rect && !sink->foreign_window) + gst_vaapisink_ensure_render_rect (sink, sink->window_width, + sink->window_height); + success = TRUE; end: - sink->rotation = sink->rotation_req; - return success; + sink->rotation = sink->rotation_req; + return success; } static gboolean -gst_vaapisink_start(GstBaseSink *base_sink) +gst_vaapisink_start (GstBaseSink * base_sink) { - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + GstVaapiSink *const sink = GST_VAAPISINK (base_sink); - if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(sink))) - return FALSE; - return gst_vaapisink_ensure_uploader(sink); + if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (sink))) + return FALSE; + return gst_vaapisink_ensure_uploader (sink); } static gboolean -gst_vaapisink_stop(GstBaseSink *base_sink) +gst_vaapisink_stop (GstBaseSink * base_sink) { - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); + GstVaapiSink *const sink = GST_VAAPISINK (base_sink); - gst_buffer_replace(&sink->video_buffer, NULL); - gst_vaapi_window_replace(&sink->window, NULL); + gst_buffer_replace (&sink->video_buffer, NULL); + gst_vaapi_window_replace (&sink->window, NULL); - gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(sink)); - return TRUE; + gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (sink)); + return TRUE; } static GstCaps * -gst_vaapisink_get_caps_impl(GstBaseSink *base_sink) +gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) { - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstCaps *out_caps, *yuv_caps; + GstVaapiSink *const sink = GST_VAAPISINK (base_sink); + GstCaps *out_caps, *yuv_caps; #if GST_CHECK_VERSION(1,1,0) - out_caps = gst_static_pad_template_get_caps(&gst_vaapisink_sink_factory); + out_caps = gst_static_pad_template_get_caps (&gst_vaapisink_sink_factory); #else - out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS); + out_caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS); #endif - if (!out_caps) - return NULL; + if (!out_caps) + return NULL; - if (gst_vaapisink_ensure_uploader(sink)) { - yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(sink); - if (yuv_caps) { - out_caps = gst_caps_make_writable(out_caps); - gst_caps_append(out_caps, gst_caps_copy(yuv_caps)); - } + if (gst_vaapisink_ensure_uploader (sink)) { + yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS (sink); + if (yuv_caps) { + out_caps = gst_caps_make_writable (out_caps); + gst_caps_append (out_caps, gst_caps_copy (yuv_caps)); } - return out_caps; + } + return out_caps; } #if GST_CHECK_VERSION(1,0,0) static inline GstCaps * -gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter) +gst_vaapisink_get_caps (GstBaseSink * base_sink, GstCaps * filter) { - GstCaps *caps, *out_caps; + GstCaps *caps, *out_caps; - caps = gst_vaapisink_get_caps_impl(base_sink); - if (caps && filter) { - out_caps = gst_caps_intersect_full(caps, filter, - GST_CAPS_INTERSECT_FIRST); - gst_caps_unref(caps); - } - else - out_caps = caps; - return out_caps; + caps = gst_vaapisink_get_caps_impl (base_sink); + if (caps && filter) { + out_caps = gst_caps_intersect_full (caps, filter, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (caps); + } else + out_caps = caps; + return out_caps; } #else #define gst_vaapisink_get_caps gst_vaapisink_get_caps_impl #endif static void -update_colorimetry(GstVaapiSink *sink, GstVideoColorimetry *cinfo) +update_colorimetry (GstVaapiSink * sink, GstVideoColorimetry * cinfo) { #if GST_CHECK_VERSION(1,0,0) - if (gst_video_colorimetry_matches(cinfo, - GST_VIDEO_COLORIMETRY_BT601)) - sink->color_standard = GST_VAAPI_COLOR_STANDARD_ITUR_BT_601; - else if (gst_video_colorimetry_matches(cinfo, - GST_VIDEO_COLORIMETRY_BT709)) - sink->color_standard = GST_VAAPI_COLOR_STANDARD_ITUR_BT_709; - else if (gst_video_colorimetry_matches(cinfo, - GST_VIDEO_COLORIMETRY_SMPTE240M)) - sink->color_standard = GST_VAAPI_COLOR_STANDARD_SMPTE_240M; - else - sink->color_standard = 0; + if (gst_video_colorimetry_matches (cinfo, GST_VIDEO_COLORIMETRY_BT601)) + sink->color_standard = GST_VAAPI_COLOR_STANDARD_ITUR_BT_601; + else if (gst_video_colorimetry_matches (cinfo, GST_VIDEO_COLORIMETRY_BT709)) + sink->color_standard = GST_VAAPI_COLOR_STANDARD_ITUR_BT_709; + else if (gst_video_colorimetry_matches (cinfo, + GST_VIDEO_COLORIMETRY_SMPTE240M)) + sink->color_standard = GST_VAAPI_COLOR_STANDARD_SMPTE_240M; + else + sink->color_standard = 0; - GST_DEBUG("colorimetry %s", gst_video_colorimetry_to_string(cinfo)); + GST_DEBUG ("colorimetry %s", gst_video_colorimetry_to_string (cinfo)); #endif } static gboolean -gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) +gst_vaapisink_set_caps (GstBaseSink * base_sink, GstCaps * caps) { - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(base_sink); - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstVideoInfo * const vip = GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO(sink); - GstVaapiDisplay *display; - guint win_width, win_height; + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (base_sink); + GstVaapiSink *const sink = GST_VAAPISINK (base_sink); + GstVideoInfo *const vip = GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO (sink); + GstVaapiDisplay *display; + guint win_width, win_height; - if (!gst_vaapisink_ensure_display(sink)) - return FALSE; - display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink); + if (!gst_vaapisink_ensure_display (sink)) + return FALSE; + display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); - if (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink) == GST_VAAPI_DISPLAY_TYPE_DRM) - return TRUE; + if (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE (sink) == GST_VAAPI_DISPLAY_TYPE_DRM) + return TRUE; - if (!gst_vaapi_plugin_base_set_caps(plugin, caps, NULL)) - return FALSE; + if (!gst_vaapi_plugin_base_set_caps (plugin, caps, NULL)) + return FALSE; - sink->video_width = GST_VIDEO_INFO_WIDTH(vip); - sink->video_height = GST_VIDEO_INFO_HEIGHT(vip); - sink->video_par_n = GST_VIDEO_INFO_PAR_N(vip); - sink->video_par_d = GST_VIDEO_INFO_PAR_D(vip); - GST_DEBUG("video pixel-aspect-ratio %d/%d", - sink->video_par_n, sink->video_par_d); + sink->video_width = GST_VIDEO_INFO_WIDTH (vip); + sink->video_height = GST_VIDEO_INFO_HEIGHT (vip); + sink->video_par_n = GST_VIDEO_INFO_PAR_N (vip); + sink->video_par_d = GST_VIDEO_INFO_PAR_D (vip); + GST_DEBUG ("video pixel-aspect-ratio %d/%d", + sink->video_par_n, sink->video_par_d); - update_colorimetry(sink, &vip->colorimetry); - gst_caps_replace(&sink->caps, caps); + update_colorimetry (sink, &vip->colorimetry); + gst_caps_replace (&sink->caps, caps); - gst_vaapisink_ensure_rotation(sink, FALSE); + gst_vaapisink_ensure_rotation (sink, FALSE); - gst_vaapisink_ensure_window_size(sink, &win_width, &win_height); - if (sink->window) { - if (!sink->foreign_window || sink->fullscreen) - gst_vaapi_window_set_size(sink->window, win_width, win_height); - } - else { - gst_vaapi_display_lock(display); - gst_video_overlay_prepare_window_handle(GST_VIDEO_OVERLAY(sink)); - gst_vaapi_display_unlock(display); - if (sink->window) - return TRUE; - if (!gst_vaapisink_ensure_window(sink, win_width, win_height)) - return FALSE; - gst_vaapi_window_set_fullscreen(sink->window, sink->fullscreen); - gst_vaapi_window_show(sink->window); - gst_vaapi_window_get_size(sink->window, &win_width, &win_height); - gst_vaapisink_set_event_handling(GST_VIDEO_OVERLAY(sink), sink->handle_events); - } - sink->window_width = win_width; - sink->window_height = win_height; - GST_DEBUG("window size %ux%u", win_width, win_height); + gst_vaapisink_ensure_window_size (sink, &win_width, &win_height); + if (sink->window) { + if (!sink->foreign_window || sink->fullscreen) + gst_vaapi_window_set_size (sink->window, win_width, win_height); + } else { + gst_vaapi_display_lock (display); + gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink)); + gst_vaapi_display_unlock (display); + if (sink->window) + return TRUE; + if (!gst_vaapisink_ensure_window (sink, win_width, win_height)) + return FALSE; + gst_vaapi_window_set_fullscreen (sink->window, sink->fullscreen); + gst_vaapi_window_show (sink->window); + gst_vaapi_window_get_size (sink->window, &win_width, &win_height); + gst_vaapisink_set_event_handling (GST_VIDEO_OVERLAY (sink), + sink->handle_events); + } + sink->window_width = win_width; + sink->window_height = win_height; + GST_DEBUG ("window size %ux%u", win_width, win_height); - return gst_vaapisink_ensure_render_rect(sink, win_width, win_height); + return gst_vaapisink_ensure_render_rect (sink, win_width, win_height); } static inline gboolean -gst_vaapisink_put_surface( - GstVaapiSink *sink, - GstVaapiSurface *surface, - const GstVaapiRectangle *surface_rect, - guint flags -) +gst_vaapisink_put_surface (GstVaapiSink * sink, + GstVaapiSurface * surface, + const GstVaapiRectangle * surface_rect, guint flags) { - if (!sink->window) - return FALSE; + if (!sink->window) + return FALSE; - if (!gst_vaapi_window_put_surface(sink->window, surface, - surface_rect, &sink->display_rect, flags)) { - GST_DEBUG("could not render VA surface"); - return FALSE; - } - return TRUE; + if (!gst_vaapi_window_put_surface (sink->window, surface, + surface_rect, &sink->display_rect, flags)) { + GST_DEBUG ("could not render VA surface"); + return FALSE; + } + return TRUE; } static GstFlowReturn -gst_vaapisink_show_frame_unlocked(GstVaapiSink *sink, GstBuffer *src_buffer) +gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) { - GstVaapiVideoMeta *meta; - GstVaapiSurfaceProxy *proxy; - GstVaapiSurface *surface; - GstBuffer *buffer; - guint flags; - GstVaapiRectangle *surface_rect = NULL; + GstVaapiVideoMeta *meta; + GstVaapiSurfaceProxy *proxy; + GstVaapiSurface *surface; + GstBuffer *buffer; + guint flags; + GstVaapiRectangle *surface_rect = NULL; #if GST_CHECK_VERSION(1,0,0) - GstVaapiRectangle tmp_rect; + GstVaapiRectangle tmp_rect; #endif - GstFlowReturn ret; - gint32 view_id; + GstFlowReturn ret; + gint32 view_id; #if GST_CHECK_VERSION(1,0,0) - GstVideoCropMeta * const crop_meta = - gst_buffer_get_video_crop_meta(src_buffer); - if (crop_meta) { - surface_rect = &tmp_rect; - surface_rect->x = crop_meta->x; - surface_rect->y = crop_meta->y; - surface_rect->width = crop_meta->width; - surface_rect->height = crop_meta->height; - } + GstVideoCropMeta *const crop_meta = + gst_buffer_get_video_crop_meta (src_buffer); + if (crop_meta) { + surface_rect = &tmp_rect; + surface_rect->x = crop_meta->x; + surface_rect->y = crop_meta->y; + surface_rect->width = crop_meta->width; + surface_rect->height = crop_meta->height; + } #endif - ret = gst_vaapi_plugin_base_get_input_buffer(GST_VAAPI_PLUGIN_BASE(sink), - src_buffer, &buffer); - if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_SUPPORTED) - return ret; + ret = gst_vaapi_plugin_base_get_input_buffer (GST_VAAPI_PLUGIN_BASE (sink), + src_buffer, &buffer); + if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_SUPPORTED) + return ret; - meta = gst_buffer_get_vaapi_video_meta(buffer); - GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(sink, - gst_vaapi_video_meta_get_display(meta)); + meta = gst_buffer_get_vaapi_video_meta (buffer); + GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE (sink, + gst_vaapi_video_meta_get_display (meta)); - gst_vaapisink_ensure_rotation(sink, TRUE); + gst_vaapisink_ensure_rotation (sink, TRUE); - proxy = gst_vaapi_video_meta_get_surface_proxy(meta); - if (!proxy) - goto error; + proxy = gst_vaapi_video_meta_get_surface_proxy (meta); + if (!proxy) + goto error; - /* Valide view component to display */ - view_id = GST_VAAPI_SURFACE_PROXY_VIEW_ID(proxy); - if (G_UNLIKELY(sink->view_id == -1)) - sink->view_id = view_id; - else if (sink->view_id != view_id) { - gst_buffer_unref(buffer); - return GST_FLOW_OK; - } - - surface = gst_vaapi_video_meta_get_surface(meta); - if (!surface) - goto error; - - GST_DEBUG("render surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); - - if (!surface_rect) - surface_rect = (GstVaapiRectangle *) - gst_vaapi_video_meta_get_render_rect(meta); - - if (surface_rect) - GST_DEBUG("render rect (%d,%d), size %ux%u", - surface_rect->x, surface_rect->y, - surface_rect->width, surface_rect->height); - - flags = gst_vaapi_video_meta_get_render_flags(meta); - - /* Append default color standard obtained from caps if none was - available on a per-buffer basis */ - if (!(flags & GST_VAAPI_COLOR_STANDARD_MASK)) - flags |= sink->color_standard; - - if (!gst_vaapi_apply_composition(surface, src_buffer)) - GST_WARNING("could not update subtitles"); - - if (!sink->backend->render_surface(sink, surface, surface_rect, flags)) - goto error; - - /* Retain VA surface until the next one is displayed */ - gst_buffer_replace(&sink->video_buffer, buffer); - gst_buffer_unref(buffer); + /* Valide view component to display */ + view_id = GST_VAAPI_SURFACE_PROXY_VIEW_ID (proxy); + if (G_UNLIKELY (sink->view_id == -1)) + sink->view_id = view_id; + else if (sink->view_id != view_id) { + gst_buffer_unref (buffer); return GST_FLOW_OK; + } + + surface = gst_vaapi_video_meta_get_surface (meta); + if (!surface) + goto error; + + GST_DEBUG ("render surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (gst_vaapi_surface_get_id (surface))); + + if (!surface_rect) + surface_rect = (GstVaapiRectangle *) + gst_vaapi_video_meta_get_render_rect (meta); + + if (surface_rect) + GST_DEBUG ("render rect (%d,%d), size %ux%u", + surface_rect->x, surface_rect->y, + surface_rect->width, surface_rect->height); + + flags = gst_vaapi_video_meta_get_render_flags (meta); + + /* Append default color standard obtained from caps if none was + available on a per-buffer basis */ + if (!(flags & GST_VAAPI_COLOR_STANDARD_MASK)) + flags |= sink->color_standard; + + if (!gst_vaapi_apply_composition (surface, src_buffer)) + GST_WARNING ("could not update subtitles"); + + if (!sink->backend->render_surface (sink, surface, surface_rect, flags)) + goto error; + + /* Retain VA surface until the next one is displayed */ + gst_buffer_replace (&sink->video_buffer, buffer); + gst_buffer_unref (buffer); + return GST_FLOW_OK; error: - gst_buffer_unref(buffer); - return GST_FLOW_EOS; + gst_buffer_unref (buffer); + return GST_FLOW_EOS; } static GstFlowReturn -gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) +gst_vaapisink_show_frame (GstBaseSink * base_sink, GstBuffer * src_buffer) { - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstFlowReturn ret; + GstVaapiSink *const sink = GST_VAAPISINK (base_sink); + GstFlowReturn ret; - /* At least we need at least to protect the _set_subpictures_() - * call to prevent a race during subpicture desctruction. - * FIXME: Could use a less coarse grained lock, though: */ - gst_vaapi_display_lock(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - ret = gst_vaapisink_show_frame_unlocked(sink, src_buffer); - gst_vaapi_display_unlock(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - return ret; + /* At least we need at least to protect the _set_subpictures_() + * call to prevent a race during subpicture desctruction. + * FIXME: Could use a less coarse grained lock, though: */ + gst_vaapi_display_lock (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); + ret = gst_vaapisink_show_frame_unlocked (sink, src_buffer); + gst_vaapi_display_unlock (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); + return ret; } #if GST_CHECK_VERSION(1,0,0) static gboolean -gst_vaapisink_propose_allocation(GstBaseSink *base_sink, GstQuery *query) +gst_vaapisink_propose_allocation (GstBaseSink * base_sink, GstQuery * query) { - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(base_sink); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (base_sink); - if (!gst_vaapi_plugin_base_propose_allocation(plugin, query)) - return FALSE; + if (!gst_vaapi_plugin_base_propose_allocation (plugin, query)) + return FALSE; - gst_query_add_allocation_meta(query, GST_VIDEO_CROP_META_API_TYPE, NULL); - gst_query_add_allocation_meta(query, - GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL); + gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL); + gst_query_add_allocation_meta (query, + GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL); + return TRUE; +} +#else +static GstFlowReturn +gst_vaapisink_buffer_alloc (GstBaseSink * base_sink, guint64 offset, guint size, + GstCaps * caps, GstBuffer ** outbuf_ptr) +{ + return + gst_vaapi_plugin_base_allocate_input_buffer (GST_VAAPI_PLUGIN_BASE + (base_sink), caps, outbuf_ptr); +} +#endif + +static gboolean +gst_vaapisink_query (GstBaseSink * base_sink, GstQuery * query) +{ + GstVaapiSink *const sink = GST_VAAPISINK (base_sink); + + GST_INFO_OBJECT (sink, "query type %s", GST_QUERY_TYPE_NAME (query)); + + if (gst_vaapi_reply_to_query (query, GST_VAAPI_PLUGIN_BASE_DISPLAY (sink))) { + GST_DEBUG ("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); return TRUE; -} -#else -static GstFlowReturn -gst_vaapisink_buffer_alloc(GstBaseSink *base_sink, guint64 offset, guint size, - GstCaps *caps, GstBuffer **outbuf_ptr) -{ - return gst_vaapi_plugin_base_allocate_input_buffer( - GST_VAAPI_PLUGIN_BASE(base_sink), caps, outbuf_ptr); -} -#endif + } -static gboolean -gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query) -{ - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - - GST_INFO_OBJECT(sink, "query type %s", GST_QUERY_TYPE_NAME(query)); - - if (gst_vaapi_reply_to_query(query, GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) { - GST_DEBUG("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - return TRUE; - } - - return GST_BASE_SINK_CLASS(gst_vaapisink_parent_class)->query(base_sink, - query); + return GST_BASE_SINK_CLASS (gst_vaapisink_parent_class)->query (base_sink, + query); } static void -gst_vaapisink_finalize(GObject *object) +gst_vaapisink_finalize (GObject * object) { - gst_vaapisink_destroy(GST_VAAPISINK(object)); + gst_vaapisink_destroy (GST_VAAPISINK (object)); - gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object)); - G_OBJECT_CLASS(gst_vaapisink_parent_class)->finalize(object); + gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (object)); + G_OBJECT_CLASS (gst_vaapisink_parent_class)->finalize (object); } static void -gst_vaapisink_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) +gst_vaapisink_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVaapiSink * const sink = GST_VAAPISINK(object); + GstVaapiSink *const sink = GST_VAAPISINK (object); - switch (prop_id) { + switch (prop_id) { case PROP_DISPLAY_TYPE: - gst_vaapi_plugin_base_set_display_type(GST_VAAPI_PLUGIN_BASE(sink), - g_value_get_enum(value)); - break; + gst_vaapi_plugin_base_set_display_type (GST_VAAPI_PLUGIN_BASE (sink), + g_value_get_enum (value)); + break; case PROP_DISPLAY_NAME: - gst_vaapi_plugin_base_set_display_name(GST_VAAPI_PLUGIN_BASE(sink), - g_value_get_string(value)); - break; + gst_vaapi_plugin_base_set_display_name (GST_VAAPI_PLUGIN_BASE (sink), + g_value_get_string (value)); + break; case PROP_FULLSCREEN: - sink->fullscreen = g_value_get_boolean(value); - break; + sink->fullscreen = g_value_get_boolean (value); + break; case PROP_VIEW_ID: - sink->view_id = g_value_get_int(value); - break; + sink->view_id = g_value_get_int (value); + break; case PROP_ROTATION: - sink->rotation_req = g_value_get_enum(value); - break; + sink->rotation_req = g_value_get_enum (value); + break; case PROP_FORCE_ASPECT_RATIO: - sink->keep_aspect = g_value_get_boolean(value); - break; + sink->keep_aspect = g_value_get_boolean (value); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -gst_vaapisink_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) +gst_vaapisink_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) { - GstVaapiSink * const sink = GST_VAAPISINK(object); + GstVaapiSink *const sink = GST_VAAPISINK (object); - switch (prop_id) { + switch (prop_id) { case PROP_DISPLAY_TYPE: - g_value_set_enum(value, GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)); - break; + g_value_set_enum (value, GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE (sink)); + break; case PROP_DISPLAY_NAME: - g_value_set_string(value, GST_VAAPI_PLUGIN_BASE_DISPLAY_NAME(sink)); - break; + g_value_set_string (value, GST_VAAPI_PLUGIN_BASE_DISPLAY_NAME (sink)); + break; case PROP_FULLSCREEN: - g_value_set_boolean(value, sink->fullscreen); - break; + g_value_set_boolean (value, sink->fullscreen); + break; case PROP_VIEW_ID: - g_value_set_int(value, sink->view_id); - break; + g_value_set_int (value, sink->view_id); + break; case PROP_ROTATION: - g_value_set_enum(value, sink->rotation); - break; + g_value_set_enum (value, sink->rotation); + break; case PROP_FORCE_ASPECT_RATIO: - g_value_set_boolean(value, sink->keep_aspect); - break; + g_value_set_boolean (value, sink->keep_aspect); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -gst_vaapisink_set_bus(GstElement *element, GstBus *bus) +gst_vaapisink_set_bus (GstElement * element, GstBus * bus) { - /* Make sure to allocate a VA display in the sink element first, - so that upstream elements could query a display that was - allocated here, and that exactly matches what the user - requested through the "display" property */ - if (!GST_ELEMENT_BUS(element) && bus) - gst_vaapisink_ensure_display(GST_VAAPISINK(element)); + /* Make sure to allocate a VA display in the sink element first, + so that upstream elements could query a display that was + allocated here, and that exactly matches what the user + requested through the "display" property */ + if (!GST_ELEMENT_BUS (element) && bus) + gst_vaapisink_ensure_display (GST_VAAPISINK (element)); - GST_ELEMENT_CLASS(gst_vaapisink_parent_class)->set_bus(element, bus); + GST_ELEMENT_CLASS (gst_vaapisink_parent_class)->set_bus (element, bus); } static void -gst_vaapisink_class_init(GstVaapiSinkClass *klass) +gst_vaapisink_class_init (GstVaapiSinkClass * klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass); - GstVaapiPluginBaseClass * const base_plugin_class = - GST_VAAPI_PLUGIN_BASE_CLASS(klass); - GstPadTemplate *pad_template; + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstBaseSinkClass *const basesink_class = GST_BASE_SINK_CLASS (klass); + GstVaapiPluginBaseClass *const base_plugin_class = + GST_VAAPI_PLUGIN_BASE_CLASS (klass); + GstPadTemplate *pad_template; - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapisink, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapisink, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - gst_vaapi_plugin_base_class_init(base_plugin_class); - base_plugin_class->has_interface = gst_vaapisink_has_interface; - base_plugin_class->display_changed = gst_vaapisink_display_changed; + gst_vaapi_plugin_base_class_init (base_plugin_class); + base_plugin_class->has_interface = gst_vaapisink_has_interface; + base_plugin_class->display_changed = gst_vaapisink_display_changed; - object_class->finalize = gst_vaapisink_finalize; - object_class->set_property = gst_vaapisink_set_property; - object_class->get_property = gst_vaapisink_get_property; + object_class->finalize = gst_vaapisink_finalize; + object_class->set_property = gst_vaapisink_set_property; + object_class->get_property = gst_vaapisink_get_property; - basesink_class->start = gst_vaapisink_start; - basesink_class->stop = gst_vaapisink_stop; - basesink_class->get_caps = gst_vaapisink_get_caps; - basesink_class->set_caps = gst_vaapisink_set_caps; - basesink_class->preroll = gst_vaapisink_show_frame; - basesink_class->render = gst_vaapisink_show_frame; - basesink_class->query = gst_vaapisink_query; + basesink_class->start = gst_vaapisink_start; + basesink_class->stop = gst_vaapisink_stop; + basesink_class->get_caps = gst_vaapisink_get_caps; + basesink_class->set_caps = gst_vaapisink_set_caps; + basesink_class->preroll = gst_vaapisink_show_frame; + basesink_class->render = gst_vaapisink_show_frame; + basesink_class->query = gst_vaapisink_query; #if GST_CHECK_VERSION(1,0,0) - basesink_class->propose_allocation = gst_vaapisink_propose_allocation; + basesink_class->propose_allocation = gst_vaapisink_propose_allocation; #else - basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; + basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; #endif - element_class->set_bus = gst_vaapisink_set_bus; - gst_element_class_set_static_metadata(element_class, - "VA-API sink", - "Sink/Video", - GST_PLUGIN_DESC, - "Gwenole Beauchesne "); + element_class->set_bus = gst_vaapisink_set_bus; + gst_element_class_set_static_metadata (element_class, + "VA-API sink", "Sink/Video", GST_PLUGIN_DESC, + "Gwenole Beauchesne "); - pad_template = gst_static_pad_template_get(&gst_vaapisink_sink_factory); - gst_element_class_add_pad_template(element_class, pad_template); + pad_template = gst_static_pad_template_get (&gst_vaapisink_sink_factory); + gst_element_class_add_pad_template (element_class, pad_template); - g_object_class_install_property - (object_class, - PROP_DISPLAY_TYPE, - g_param_spec_enum("display", - "display type", - "display type to use", - GST_VAAPI_TYPE_DISPLAY_TYPE, - GST_VAAPI_DISPLAY_TYPE_ANY, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_DISPLAY_TYPE, + g_param_spec_enum ("display", + "display type", + "display type to use", + GST_VAAPI_TYPE_DISPLAY_TYPE, + GST_VAAPI_DISPLAY_TYPE_ANY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property - (object_class, - PROP_DISPLAY_NAME, - g_param_spec_string("display-name", - "display name", - "display name to use", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_DISPLAY_NAME, + g_param_spec_string ("display-name", + "display name", + "display name to use", + NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property - (object_class, - PROP_FULLSCREEN, - g_param_spec_boolean("fullscreen", - "Fullscreen", - "Requests window in fullscreen state", - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_FULLSCREEN, + g_param_spec_boolean ("fullscreen", + "Fullscreen", + "Requests window in fullscreen state", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiSink:rotation: - * - * The VA display rotation mode, expressed as a #GstVaapiRotation. - */ - g_object_class_install_property - (object_class, - PROP_ROTATION, - g_param_spec_enum(GST_VAAPI_DISPLAY_PROP_ROTATION, - "rotation", - "The display rotation mode", - GST_VAAPI_TYPE_ROTATION, - DEFAULT_ROTATION, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiSink:rotation: + * + * The VA display rotation mode, expressed as a #GstVaapiRotation. + */ + g_object_class_install_property (object_class, + PROP_ROTATION, + g_param_spec_enum (GST_VAAPI_DISPLAY_PROP_ROTATION, + "rotation", + "The display rotation mode", + GST_VAAPI_TYPE_ROTATION, + DEFAULT_ROTATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiSink:force-aspect-ratio: - * - * When enabled, scaling respects video aspect ratio; when disabled, the - * video is distorted to fit the window. - */ - g_object_class_install_property - (object_class, - PROP_FORCE_ASPECT_RATIO, - g_param_spec_boolean("force-aspect-ratio", - "Force aspect ratio", - "When enabled, scaling will respect original aspect ratio", - TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiSink:force-aspect-ratio: + * + * When enabled, scaling respects video aspect ratio; when disabled, + * the video is distorted to fit the window. + */ + g_object_class_install_property (object_class, + PROP_FORCE_ASPECT_RATIO, + g_param_spec_boolean ("force-aspect-ratio", + "Force aspect ratio", + "When enabled, scaling will respect original aspect ratio", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiSink:view-id: - * - * When not set to -1, the displayed frame will always be the one - * that matches the view-id of the very first displayed frame. Any - * other number will indicate the desire to display the supplied - * view-id only. - */ - g_object_class_install_property - (object_class, - PROP_VIEW_ID, - g_param_spec_int("view-id", - "View ID", - "ID of the view component of interest to display", - -1, G_MAXINT32, -1, - G_PARAM_READWRITE)); + /** + * GstVaapiSink:view-id: + * + * When not set to -1, the displayed frame will always be the one + * that matches the view-id of the very first displayed frame. Any + * other number will indicate the desire to display the supplied + * view-id only. + */ + g_object_class_install_property (object_class, + PROP_VIEW_ID, + g_param_spec_int ("view-id", + "View ID", + "ID of the view component of interest to display", + -1, G_MAXINT32, -1, G_PARAM_READWRITE)); } static void -gst_vaapisink_init(GstVaapiSink *sink) +gst_vaapisink_init (GstVaapiSink * sink) { - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(sink); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (sink); - gst_vaapi_plugin_base_init(plugin, GST_CAT_DEFAULT); - gst_vaapi_plugin_base_set_display_type(plugin, DEFAULT_DISPLAY_TYPE); + gst_vaapi_plugin_base_init (plugin, GST_CAT_DEFAULT); + gst_vaapi_plugin_base_set_display_type (plugin, DEFAULT_DISPLAY_TYPE); - sink->caps = NULL; - sink->window = NULL; - sink->window_width = 0; - sink->window_height = 0; - sink->video_buffer = NULL; - sink->video_width = 0; - sink->video_height = 0; - sink->video_par_n = 1; - sink->video_par_d = 1; - sink->view_id = -1; - sink->handle_events = TRUE; - sink->foreign_window = FALSE; - sink->fullscreen = FALSE; - sink->rotation = DEFAULT_ROTATION; - sink->rotation_req = DEFAULT_ROTATION; - sink->use_overlay = FALSE; - sink->use_rotation = FALSE; - sink->keep_aspect = TRUE; - gst_video_info_init(&sink->video_info); + sink->caps = NULL; + sink->window = NULL; + sink->window_width = 0; + sink->window_height = 0; + sink->video_buffer = NULL; + sink->video_width = 0; + sink->video_height = 0; + sink->video_par_n = 1; + sink->video_par_d = 1; + sink->view_id = -1; + sink->handle_events = TRUE; + sink->foreign_window = FALSE; + sink->fullscreen = FALSE; + sink->rotation = DEFAULT_ROTATION; + sink->rotation_req = DEFAULT_ROTATION; + sink->use_overlay = FALSE; + sink->use_rotation = FALSE; + sink->keep_aspect = TRUE; + gst_video_info_init (&sink->video_info); } diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index f55dbf53db..573f168360 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -20,7 +20,7 @@ * 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_VAAPISINK_H #define GST_VAAPISINK_H @@ -32,93 +32,86 @@ G_BEGIN_DECLS #define GST_TYPE_VAAPISINK \ - (gst_vaapisink_get_type()) - -#define GST_VAAPISINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_TYPE_VAAPISINK, \ - GstVaapiSink)) - -#define GST_VAAPISINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_TYPE_VAAPISINK, \ - GstVaapiSinkClass)) - + (gst_vaapisink_get_type ()) +#define GST_VAAPISINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPISINK, GstVaapiSink)) +#define GST_VAAPISINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPISINK, GstVaapiSinkClass)) #define GST_IS_VAAPISINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPISINK)) - + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPISINK)) #define GST_IS_VAAPISINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPISINK)) - -#define GST_VAAPISINK_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_TYPE_VAAPISINK, \ - GstVaapiSinkClass)) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPISINK)) +#define GST_VAAPISINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPISINK, GstVaapiSinkClass)) typedef struct _GstVaapiSink GstVaapiSink; typedef struct _GstVaapiSinkClass GstVaapiSinkClass; typedef struct _GstVaapiSinkBackend GstVaapiSinkBackend; -typedef gboolean (*GstVaapiSinkCreateWindowFunc)(GstVaapiSink *sink, +typedef gboolean (*GstVaapiSinkCreateWindowFunc) (GstVaapiSink * sink, guint width, guint height); -typedef gboolean (*GstVaapiSinkCreateWindowFromHandleFunc)(GstVaapiSink *sink, +typedef gboolean (*GstVaapiSinkCreateWindowFromHandleFunc) (GstVaapiSink * sink, guintptr window); -typedef gboolean (*GstVaapiSinkRenderSurfaceFunc)(GstVaapiSink *sink, - GstVaapiSurface *surface, const GstVaapiRectangle *surface_rect, guint flags); -typedef gboolean (*GstVaapiSinkHandleEventsFunc)(GstVaapiSink *sink); -typedef gboolean (*GstVaapiSinkPreStartEventThreadFunc)(GstVaapiSink *sink); -typedef gboolean (*GstVaapiSinkPreStopEventThreadFunc)(GstVaapiSink *sink); +typedef gboolean (*GstVaapiSinkRenderSurfaceFunc) (GstVaapiSink * sink, + GstVaapiSurface * surface, const GstVaapiRectangle * surface_rect, + guint flags); +typedef gboolean (*GstVaapiSinkHandleEventsFunc) (GstVaapiSink * sink); +typedef gboolean (*GstVaapiSinkPreStartEventThreadFunc) (GstVaapiSink * sink); +typedef gboolean (*GstVaapiSinkPreStopEventThreadFunc) (GstVaapiSink * sink); -struct _GstVaapiSinkBackend { - GstVaapiSinkCreateWindowFunc create_window; - GstVaapiSinkCreateWindowFromHandleFunc create_window_from_handle; - GstVaapiSinkRenderSurfaceFunc render_surface; +struct _GstVaapiSinkBackend +{ + GstVaapiSinkCreateWindowFunc create_window; + GstVaapiSinkCreateWindowFromHandleFunc create_window_from_handle; + GstVaapiSinkRenderSurfaceFunc render_surface; - /* Event threads handling */ - gboolean event_thread_needed; - GstVaapiSinkHandleEventsFunc handle_events; - GstVaapiSinkPreStartEventThreadFunc pre_start_event_thread; - GstVaapiSinkPreStopEventThreadFunc pre_stop_event_thread; + /* Event threads handling */ + gboolean event_thread_needed; + GstVaapiSinkHandleEventsFunc handle_events; + GstVaapiSinkPreStartEventThreadFunc pre_start_event_thread; + GstVaapiSinkPreStopEventThreadFunc pre_stop_event_thread; }; -struct _GstVaapiSink { - /*< private >*/ - GstVaapiPluginBase parent_instance; +struct _GstVaapiSink +{ + /*< private >*/ + GstVaapiPluginBase parent_instance; - const GstVaapiSinkBackend *backend; + const GstVaapiSinkBackend *backend; - GstCaps *caps; - GstVaapiWindow *window; - guint window_width; - guint window_height; - GstBuffer *video_buffer; - guint video_width; - guint video_height; - gint video_par_n; - gint video_par_d; - GstVideoInfo video_info; - GstVaapiRectangle display_rect; - GstVaapiRotation rotation; - GstVaapiRotation rotation_req; - guint color_standard; - gint32 view_id; - GThread *event_thread; - volatile gboolean event_thread_cancel; - guint handle_events : 1; - guint foreign_window : 1; - guint fullscreen : 1; - guint use_overlay : 1; - guint use_rotation : 1; - guint keep_aspect : 1; + GstCaps *caps; + GstVaapiWindow *window; + guint window_width; + guint window_height; + GstBuffer *video_buffer; + guint video_width; + guint video_height; + gint video_par_n; + gint video_par_d; + GstVideoInfo video_info; + GstVaapiRectangle display_rect; + GstVaapiRotation rotation; + GstVaapiRotation rotation_req; + guint color_standard; + gint32 view_id; + GThread *event_thread; + volatile gboolean event_thread_cancel; + guint handle_events : 1; + guint foreign_window : 1; + guint fullscreen : 1; + guint use_overlay : 1; + guint use_rotation : 1; + guint keep_aspect : 1; }; -struct _GstVaapiSinkClass { - /*< private >*/ - GstVaapiPluginBaseClass parent_class; +struct _GstVaapiSinkClass +{ + /*< private >*/ + GstVaapiPluginBaseClass parent_class; }; GType -gst_vaapisink_get_type(void) G_GNUC_CONST; +gst_vaapisink_get_type (void) G_GNUC_CONST; G_END_DECLS From d1f83b45705689fd534f8f4c3cae90b275c556f6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 31 Jul 2014 10:48:15 +0200 Subject: [PATCH 1751/3781] vaapisink: code clean-ups. Move code around in a more logical way. Introduce GST_VAAPISINK_CAST() helper macro and use it wherever we know the object is a GstBaseSink or any base class. Drop explicit initializers for values that have defaults set to zero. --- gst/vaapi/gstvaapisink.c | 285 ++++++++++++++++++--------------------- gst/vaapi/gstvaapisink.h | 2 + 2 files changed, 136 insertions(+), 151 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 90470006cf..5cbfbf0fde 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -122,11 +122,6 @@ enum #define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 -static gboolean -gst_vaapisink_ensure_display (GstVaapiSink * sink); - -/* GstVideoOverlay interface */ - static void gst_vaapisink_video_overlay_expose (GstVideoOverlay * overlay); @@ -134,20 +129,29 @@ static gboolean gst_vaapisink_reconfigure_window (GstVaapiSink * sink); static void -gst_vaapisink_set_event_handling (GstVideoOverlay * overlay, - gboolean handle_events); +gst_vaapisink_set_event_handling (GstVaapiSink * sink, gboolean handle_events); static GstFlowReturn gst_vaapisink_show_frame (GstBaseSink * base_sink, GstBuffer * buffer); -static gboolean -gst_vaapisink_put_surface (GstVaapiSink * sink, GstVaapiSurface * surface, - const GstVaapiRectangle * surface_rect, guint flags); - static gboolean gst_vaapisink_ensure_render_rect (GstVaapiSink * sink, guint width, guint height); +static inline gboolean +gst_vaapisink_ensure_display (GstVaapiSink * sink) +{ + return gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (sink)); +} + +static inline gboolean +gst_vaapisink_render_surface (GstVaapiSink * sink, GstVaapiSurface * surface, + const GstVaapiRectangle * surface_rect, guint flags) +{ + return sink->window && gst_vaapi_window_put_surface (sink->window, surface, + surface_rect, &sink->display_rect, flags); +} + /* ------------------------------------------------------------------------ */ /* --- DRM Backend --- */ /* ------------------------------------------------------------------------ */ @@ -291,8 +295,7 @@ gst_vaapisink_x11_create_window_from_handle (GstVaapiSink * sink, return FALSE; } - gst_vaapisink_set_event_handling (GST_VIDEO_OVERLAY (sink), - sink->handle_events); + gst_vaapisink_set_event_handling (sink, sink->handle_events); return TRUE; } @@ -371,7 +374,7 @@ gst_vaapisink_backend_x11 (void) static const GstVaapiSinkBackend GstVaapiSinkBackendX11 = { .create_window = gst_vaapisink_x11_create_window, .create_window_from_handle = gst_vaapisink_x11_create_window_from_handle, - .render_surface = gst_vaapisink_put_surface, + .render_surface = gst_vaapisink_render_surface, .event_thread_needed = TRUE, .handle_events = gst_vaapisink_x11_handle_events, @@ -409,14 +412,14 @@ gst_vaapisink_backend_wayland (void) { static const GstVaapiSinkBackend GstVaapiSinkBackendWayland = { .create_window = gst_vaapisink_wayland_create_window, - .render_surface = gst_vaapisink_put_surface, + .render_surface = gst_vaapisink_render_surface, }; return &GstVaapiSinkBackendWayland; } #endif /* ------------------------------------------------------------------------ */ -/* --- Common implementation --- */ +/* --- GstVideoOverlay interface --- */ /* ------------------------------------------------------------------------ */ static void @@ -424,7 +427,6 @@ gst_vaapisink_video_overlay_set_window_handle (GstVideoOverlay * overlay, guintptr window) { GstVaapiSink *const sink = GST_VAAPISINK (overlay); - const GstVaapiSinkBackend *const backend = sink->backend; GstVaapiDisplayType display_type; if (!gst_vaapisink_ensure_display (sink)) @@ -441,8 +443,8 @@ gst_vaapisink_video_overlay_set_window_handle (GstVideoOverlay * overlay, } sink->foreign_window = TRUE; - if (backend->create_window_from_handle) - backend->create_window_from_handle (sink, window); + if (sink->backend->create_window_from_handle) + sink->backend->create_window_from_handle (sink, window); } static void @@ -462,6 +464,40 @@ gst_vaapisink_video_overlay_set_render_rectangle (GstVideoOverlay * overlay, display_rect->width, display_rect->height); } +static void +gst_vaapisink_video_overlay_expose (GstVideoOverlay * overlay) +{ + GstVaapiSink *const sink = GST_VAAPISINK (overlay); + + if (sink->video_buffer) { + gst_vaapisink_reconfigure_window (sink); + gst_vaapisink_show_frame (GST_BASE_SINK_CAST (sink), sink->video_buffer); + } +} + +static void +gst_vaapisink_video_overlay_set_event_handling (GstVideoOverlay * overlay, + gboolean handle_events) +{ + GstVaapiSink *const sink = GST_VAAPISINK (overlay); + + gst_vaapisink_set_event_handling (sink, handle_events); +} + +static void +gst_vaapisink_video_overlay_iface_init (GstVideoOverlayInterface * iface) +{ + iface->set_window_handle = gst_vaapisink_video_overlay_set_window_handle; + iface->set_render_rectangle = + gst_vaapisink_video_overlay_set_render_rectangle; + iface->expose = gst_vaapisink_video_overlay_expose; + iface->handle_events = gst_vaapisink_video_overlay_set_event_handling; +} + +/* ------------------------------------------------------------------------ */ +/* --- Common implementation --- */ +/* ------------------------------------------------------------------------ */ + static gboolean gst_vaapisink_reconfigure_window (GstVaapiSink * sink) { @@ -492,29 +528,15 @@ gst_vaapisink_event_thread (GstVaapiSink * sink) GST_OBJECT_LOCK (sink); } GST_OBJECT_UNLOCK (sink); - return NULL; } static void -gst_vaapisink_video_overlay_expose (GstVideoOverlay * overlay) -{ - GstVaapiSink *const sink = GST_VAAPISINK (overlay); - - if (sink->video_buffer) { - gst_vaapisink_reconfigure_window (sink); - gst_vaapisink_show_frame (GST_BASE_SINK_CAST (sink), sink->video_buffer); - } -} - -static void -gst_vaapisink_set_event_handling (GstVideoOverlay * overlay, - gboolean handle_events) +gst_vaapisink_set_event_handling (GstVaapiSink * sink, gboolean handle_events) { GThread *thread = NULL; - GstVaapiSink *const sink = GST_VAAPISINK (overlay); - if (!sink->backend->event_thread_needed) + if (!sink->backend || !sink->backend->event_thread_needed) return; GST_OBJECT_LOCK (sink); @@ -533,7 +555,7 @@ gst_vaapisink_set_event_handling (GstVideoOverlay * overlay, if (sink->backend->pre_stop_event_thread) sink->backend->pre_stop_event_thread (sink); - /* grab thread and mark it as NULL */ + /* Grab thread and mark it as NULL */ thread = sink->event_thread; sink->event_thread = NULL; sink->event_thread_cancel = TRUE; @@ -548,50 +570,8 @@ gst_vaapisink_set_event_handling (GstVideoOverlay * overlay, } static void -gst_vaapisink_video_overlay_iface_init (GstVideoOverlayInterface * iface) +gst_vaapisink_ensure_backend (GstVaapiSink * sink) { - iface->set_window_handle = gst_vaapisink_video_overlay_set_window_handle; - iface->set_render_rectangle = - gst_vaapisink_video_overlay_set_render_rectangle; - iface->expose = gst_vaapisink_video_overlay_expose; - iface->handle_events = gst_vaapisink_set_event_handling; -} - -static void -gst_vaapisink_destroy (GstVaapiSink * sink) -{ - gst_vaapisink_set_event_handling (GST_VIDEO_OVERLAY (sink), FALSE); - - gst_buffer_replace (&sink->video_buffer, NULL); - gst_caps_replace (&sink->caps, NULL); -} - -static const gchar * -get_display_type_name (GstVaapiDisplayType display_type) -{ - gpointer const klass = g_type_class_peek (GST_VAAPI_TYPE_DISPLAY_TYPE); - GEnumValue *const e = g_enum_get_value (klass, display_type); - - if (e) - return e->value_name; - return ""; -} - -static gboolean -gst_vaapisink_ensure_display (GstVaapiSink * sink) -{ - return gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (sink)); -} - -static void -gst_vaapisink_display_changed (GstVaapiPluginBase * plugin) -{ - GstVaapiSink *const sink = GST_VAAPISINK (plugin); - GstVaapiRenderMode render_mode; - - GST_INFO ("created %s %p", get_display_type_name (plugin->display_type), - plugin->display); - switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE (sink)) { #if USE_DRM case GST_VAAPI_DISPLAY_TYPE_DRM: @@ -618,15 +598,6 @@ gst_vaapisink_display_changed (GstVaapiPluginBase * plugin) g_assert_not_reached (); break; } - - sink->use_overlay = - gst_vaapi_display_get_render_mode (plugin->display, &render_mode) && - render_mode == GST_VAAPI_RENDER_MODE_OVERLAY; - GST_DEBUG ("use %s rendering mode", - sink->use_overlay ? "overlay" : "texture"); - - sink->use_rotation = gst_vaapi_display_has_property (plugin->display, - GST_VAAPI_DISPLAY_PROP_ROTATION); } static gboolean @@ -702,9 +673,15 @@ gst_vaapisink_ensure_render_rect (GstVaapiSink * sink, guint width, return TRUE; } +static inline gboolean +gst_vaapisink_ensure_window (GstVaapiSink * sink, guint width, guint height) +{ + return sink->window || sink->backend->create_window (sink, width, height); +} + static void -gst_vaapisink_ensure_window_size (GstVaapiSink * sink, guint * pwidth, - guint * pheight) +gst_vaapisink_ensure_window_size (GstVaapiSink * sink, guint * width_ptr, + guint * height_ptr) { GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); GstVideoRectangle src_rect, dst_rect, out_rect; @@ -712,15 +689,15 @@ gst_vaapisink_ensure_window_size (GstVaapiSink * sink, guint * pwidth, gboolean success, scale; if (sink->foreign_window) { - *pwidth = sink->window_width; - *pheight = sink->window_height; + *width_ptr = sink->window_width; + *height_ptr = sink->window_height; return; } gst_vaapi_display_get_size (display, &display_width, &display_height); if (sink->fullscreen) { - *pwidth = display_width; - *pheight = display_height; + *width_ptr = display_width; + *height_ptr = display_height; return; } @@ -745,14 +722,8 @@ gst_vaapisink_ensure_window_size (GstVaapiSink * sink, guint * pwidth, dst_rect.h = display_height; scale = (src_rect.w > dst_rect.w || src_rect.h > dst_rect.h); gst_video_sink_center_rect (src_rect, dst_rect, &out_rect, scale); - *pwidth = out_rect.w; - *pheight = out_rect.h; -} - -static inline gboolean -gst_vaapisink_ensure_window (GstVaapiSink * sink, guint width, guint height) -{ - return sink->window || sink->backend->create_window (sink, width, height); + *width_ptr = out_rect.w; + *height_ptr = out_rect.h; } static gboolean @@ -796,10 +767,42 @@ end: return success; } +static const gchar * +get_display_type_name (GstVaapiDisplayType display_type) +{ + gpointer const klass = g_type_class_peek (GST_VAAPI_TYPE_DISPLAY_TYPE); + GEnumValue *const e = g_enum_get_value (klass, display_type); + + if (e) + return e->value_name; + return ""; +} + +static void +gst_vaapisink_display_changed (GstVaapiPluginBase * plugin) +{ + GstVaapiSink *const sink = GST_VAAPISINK_CAST (plugin); + GstVaapiRenderMode render_mode; + + GST_INFO ("created %s %p", get_display_type_name (plugin->display_type), + plugin->display); + + gst_vaapisink_ensure_backend (sink); + + sink->use_overlay = + gst_vaapi_display_get_render_mode (plugin->display, &render_mode) && + render_mode == GST_VAAPI_RENDER_MODE_OVERLAY; + GST_DEBUG ("use %s rendering mode", + sink->use_overlay ? "overlay" : "texture"); + + sink->use_rotation = gst_vaapi_display_has_property (plugin->display, + GST_VAAPI_DISPLAY_PROP_ROTATION); +} + static gboolean gst_vaapisink_start (GstBaseSink * base_sink) { - GstVaapiSink *const sink = GST_VAAPISINK (base_sink); + GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (sink))) return FALSE; @@ -809,7 +812,7 @@ gst_vaapisink_start (GstBaseSink * base_sink) static gboolean gst_vaapisink_stop (GstBaseSink * base_sink) { - GstVaapiSink *const sink = GST_VAAPISINK (base_sink); + GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); gst_buffer_replace (&sink->video_buffer, NULL); gst_vaapi_window_replace (&sink->window, NULL); @@ -821,7 +824,7 @@ gst_vaapisink_stop (GstBaseSink * base_sink) static GstCaps * gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) { - GstVaapiSink *const sink = GST_VAAPISINK (base_sink); + GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); GstCaps *out_caps, *yuv_caps; #if GST_CHECK_VERSION(1,1,0) @@ -882,7 +885,7 @@ static gboolean gst_vaapisink_set_caps (GstBaseSink * base_sink, GstCaps * caps) { GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (base_sink); - GstVaapiSink *const sink = GST_VAAPISINK (base_sink); + GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); GstVideoInfo *const vip = GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO (sink); GstVaapiDisplay *display; guint win_width, win_height; @@ -924,8 +927,7 @@ gst_vaapisink_set_caps (GstBaseSink * base_sink, GstCaps * caps) gst_vaapi_window_set_fullscreen (sink->window, sink->fullscreen); gst_vaapi_window_show (sink->window); gst_vaapi_window_get_size (sink->window, &win_width, &win_height); - gst_vaapisink_set_event_handling (GST_VIDEO_OVERLAY (sink), - sink->handle_events); + gst_vaapisink_set_event_handling (sink, sink->handle_events); } sink->window_width = win_width; sink->window_height = win_height; @@ -934,22 +936,6 @@ gst_vaapisink_set_caps (GstBaseSink * base_sink, GstCaps * caps) return gst_vaapisink_ensure_render_rect (sink, win_width, win_height); } -static inline gboolean -gst_vaapisink_put_surface (GstVaapiSink * sink, - GstVaapiSurface * surface, - const GstVaapiRectangle * surface_rect, guint flags) -{ - if (!sink->window) - return FALSE; - - if (!gst_vaapi_window_put_surface (sink->window, surface, - surface_rect, &sink->display_rect, flags)) { - GST_DEBUG ("could not render VA surface"); - return FALSE; - } - return TRUE; -} - static GstFlowReturn gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) { @@ -986,13 +972,15 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE (sink, gst_vaapi_video_meta_get_display (meta)); - gst_vaapisink_ensure_rotation (sink, TRUE); - proxy = gst_vaapi_video_meta_get_surface_proxy (meta); if (!proxy) goto error; - /* Valide view component to display */ + surface = gst_vaapi_video_meta_get_surface (meta); + if (!surface) + goto error; + + /* Validate view component to display */ view_id = GST_VAAPI_SURFACE_PROXY_VIEW_ID (proxy); if (G_UNLIKELY (sink->view_id == -1)) sink->view_id = view_id; @@ -1001,9 +989,7 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) return GST_FLOW_OK; } - surface = gst_vaapi_video_meta_get_surface (meta); - if (!surface) - goto error; + gst_vaapisink_ensure_rotation (sink, TRUE); GST_DEBUG ("render surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (gst_vaapi_surface_get_id (surface))); @@ -1043,12 +1029,12 @@ error: static GstFlowReturn gst_vaapisink_show_frame (GstBaseSink * base_sink, GstBuffer * src_buffer) { - GstVaapiSink *const sink = GST_VAAPISINK (base_sink); + GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); GstFlowReturn ret; - /* At least we need at least to protect the _set_subpictures_() - * call to prevent a race during subpicture desctruction. - * FIXME: Could use a less coarse grained lock, though: */ + /* We need at least to protect the gst_vaapi_aplpy_composition() + * call to prevent a race during subpicture destruction. + * FIXME: a less coarse grained lock could be used, though */ gst_vaapi_display_lock (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); ret = gst_vaapisink_show_frame_unlocked (sink, src_buffer); gst_vaapi_display_unlock (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); @@ -1083,7 +1069,7 @@ gst_vaapisink_buffer_alloc (GstBaseSink * base_sink, guint64 offset, guint size, static gboolean gst_vaapisink_query (GstBaseSink * base_sink, GstQuery * query) { - GstVaapiSink *const sink = GST_VAAPISINK (base_sink); + GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); GST_INFO_OBJECT (sink, "query type %s", GST_QUERY_TYPE_NAME (query)); @@ -1091,15 +1077,23 @@ gst_vaapisink_query (GstBaseSink * base_sink, GstQuery * query) GST_DEBUG ("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); return TRUE; } - return GST_BASE_SINK_CLASS (gst_vaapisink_parent_class)->query (base_sink, query); } +static void +gst_vaapisink_destroy (GstVaapiSink * sink) +{ + gst_vaapisink_set_event_handling (sink, FALSE); + + gst_buffer_replace (&sink->video_buffer, NULL); + gst_caps_replace (&sink->caps, NULL); +} + static void gst_vaapisink_finalize (GObject * object) { - gst_vaapisink_destroy (GST_VAAPISINK (object)); + gst_vaapisink_destroy (GST_VAAPISINK_CAST (object)); gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (object)); G_OBJECT_CLASS (gst_vaapisink_parent_class)->finalize (object); @@ -1109,7 +1103,7 @@ static void gst_vaapisink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVaapiSink *const sink = GST_VAAPISINK (object); + GstVaapiSink *const sink = GST_VAAPISINK_CAST (object); switch (prop_id) { case PROP_DISPLAY_TYPE: @@ -1142,7 +1136,7 @@ static void gst_vaapisink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVaapiSink *const sink = GST_VAAPISINK (object); + GstVaapiSink *const sink = GST_VAAPISINK_CAST (object); switch (prop_id) { case PROP_DISPLAY_TYPE: @@ -1177,7 +1171,7 @@ gst_vaapisink_set_bus (GstElement * element, GstBus * bus) allocated here, and that exactly matches what the user requested through the "display" property */ if (!GST_ELEMENT_BUS (element) && bus) - gst_vaapisink_ensure_display (GST_VAAPISINK (element)); + gst_vaapisink_ensure_display (GST_VAAPISINK_CAST (element)); GST_ELEMENT_CLASS (gst_vaapisink_parent_class)->set_bus (element, bus); } @@ -1297,23 +1291,12 @@ gst_vaapisink_init (GstVaapiSink * sink) gst_vaapi_plugin_base_init (plugin, GST_CAT_DEFAULT); gst_vaapi_plugin_base_set_display_type (plugin, DEFAULT_DISPLAY_TYPE); - sink->caps = NULL; - sink->window = NULL; - sink->window_width = 0; - sink->window_height = 0; - sink->video_buffer = NULL; - sink->video_width = 0; - sink->video_height = 0; sink->video_par_n = 1; sink->video_par_d = 1; sink->view_id = -1; sink->handle_events = TRUE; - sink->foreign_window = FALSE; - sink->fullscreen = FALSE; sink->rotation = DEFAULT_ROTATION; sink->rotation_req = DEFAULT_ROTATION; - sink->use_overlay = FALSE; - sink->use_rotation = FALSE; sink->keep_aspect = TRUE; gst_video_info_init (&sink->video_info); } diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 573f168360..6879d9845d 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -33,6 +33,8 @@ G_BEGIN_DECLS #define GST_TYPE_VAAPISINK \ (gst_vaapisink_get_type ()) +#define GST_VAAPISINK_CAST(obj) \ + ((GstVaapiSink *)(obj)) #define GST_VAAPISINK(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPISINK, GstVaapiSink)) #define GST_VAAPISINK_CLASS(klass) \ From 6e92a82138343774788931eeb117a82eb85c5748 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 31 Jul 2014 13:18:21 +0200 Subject: [PATCH 1752/3781] vaapisink: improve installation of properties. Simplify the creation and installation process of properties, by first accumulating them into a g_properties[] array, and next calling into g_object_class_install_properties(). Also add missing docs and flags to some properties. --- gst/vaapi/gstvaapisink.c | 79 +++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 5cbfbf0fde..cdf039d7a2 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -117,11 +117,15 @@ enum PROP_ROTATION, PROP_FORCE_ASPECT_RATIO, PROP_VIEW_ID, + + N_PROPERTIES }; #define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 +static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; + static void gst_vaapisink_video_overlay_expose (GstVideoOverlay * overlay); @@ -1218,41 +1222,50 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) pad_template = gst_static_pad_template_get (&gst_vaapisink_sink_factory); gst_element_class_add_pad_template (element_class, pad_template); - g_object_class_install_property (object_class, - PROP_DISPLAY_TYPE, + /** + * GstVaapiSink:display: + * + * The type of display to use. + */ + g_properties[PROP_DISPLAY_TYPE] = g_param_spec_enum ("display", - "display type", - "display type to use", - GST_VAAPI_TYPE_DISPLAY_TYPE, - GST_VAAPI_DISPLAY_TYPE_ANY, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "display type", + "display type to use", + GST_VAAPI_TYPE_DISPLAY_TYPE, + GST_VAAPI_DISPLAY_TYPE_ANY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_DISPLAY_NAME, + /** + * GstVaapiSink:display-name: + * + * The native display name. + */ + g_properties[PROP_DISPLAY_NAME] = g_param_spec_string ("display-name", - "display name", - "display name to use", - NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "display name", + "display name to use", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_FULLSCREEN, + /** + * GstVaapiSink:fullscreen: + * + * Selects whether fullscreen mode is enabled or not. + */ + g_properties[PROP_FULLSCREEN] = g_param_spec_boolean ("fullscreen", - "Fullscreen", - "Requests window in fullscreen state", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Fullscreen", + "Requests window in fullscreen state", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiSink:rotation: * * The VA display rotation mode, expressed as a #GstVaapiRotation. */ - g_object_class_install_property (object_class, - PROP_ROTATION, + g_properties[PROP_ROTATION] = g_param_spec_enum (GST_VAAPI_DISPLAY_PROP_ROTATION, - "rotation", - "The display rotation mode", - GST_VAAPI_TYPE_ROTATION, - DEFAULT_ROTATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "rotation", + "The display rotation mode", + GST_VAAPI_TYPE_ROTATION, + DEFAULT_ROTATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiSink:force-aspect-ratio: @@ -1260,12 +1273,11 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) * When enabled, scaling respects video aspect ratio; when disabled, * the video is distorted to fit the window. */ - g_object_class_install_property (object_class, - PROP_FORCE_ASPECT_RATIO, + g_properties[PROP_FORCE_ASPECT_RATIO] = g_param_spec_boolean ("force-aspect-ratio", - "Force aspect ratio", - "When enabled, scaling will respect original aspect ratio", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Force aspect ratio", + "When enabled, scaling will respect original aspect ratio", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiSink:view-id: @@ -1275,12 +1287,13 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) * other number will indicate the desire to display the supplied * view-id only. */ - g_object_class_install_property (object_class, - PROP_VIEW_ID, + g_properties[PROP_VIEW_ID] = g_param_spec_int ("view-id", - "View ID", - "ID of the view component of interest to display", - -1, G_MAXINT32, -1, G_PARAM_READWRITE)); + "View ID", + "ID of the view component of interest to display", + -1, G_MAXINT32, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, g_properties); } static void From 5a95cd564562974a3d65b2605a7bb26441ecf322 Mon Sep 17 00:00:00 2001 From: Changzhi Wei Date: Thu, 23 Jan 2014 15:23:00 +0000 Subject: [PATCH 1753/3781] vaapisink: add support for colorbalance adjustment. https://bugzilla.gnome.org/show_bug.cgi?id=722390 [fixed and simplified tracking of colorbalance value changes] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 184 +++++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapisink.h | 5 ++ 2 files changed, 189 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index cdf039d7a2..f6ce385fe2 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -117,6 +117,10 @@ enum PROP_ROTATION, PROP_FORCE_ASPECT_RATIO, PROP_VIEW_ID, + PROP_HUE, + PROP_SATURATION, + PROP_BRIGHTNESS, + PROP_CONTRAST, N_PROPERTIES }; @@ -498,6 +502,110 @@ gst_vaapisink_video_overlay_iface_init (GstVideoOverlayInterface * iface) iface->handle_events = gst_vaapisink_video_overlay_set_event_handling; } +enum +{ + CB_HUE = 1, + CB_SATURATION, + CB_BRIGHTNESS, + CB_CONTRAST +}; + +typedef struct +{ + guint cb_id; + const gchar *prop_name; +} ColorBalanceMap; + +static const ColorBalanceMap cb_map[4] = { + {CB_HUE, GST_VAAPI_DISPLAY_PROP_HUE}, + {CB_SATURATION, GST_VAAPI_DISPLAY_PROP_SATURATION}, + {CB_BRIGHTNESS, GST_VAAPI_DISPLAY_PROP_BRIGHTNESS}, + {CB_CONTRAST, GST_VAAPI_DISPLAY_PROP_CONTRAST} +}; + +static inline GValue * +cb_get_gvalue (GstVaapiSink * sink, guint id) +{ + g_return_val_if_fail ((guint) (id - CB_HUE) < G_N_ELEMENTS (sink->cb_values), + NULL); + + return &sink->cb_values[id - CB_HUE]; +} + +static gboolean +cb_set_gvalue (GstVaapiSink * sink, guint id, const GValue * value) +{ + GValue *const v_value = cb_get_gvalue (sink, id); + + if (!v_value) + return FALSE; + + g_value_set_float (v_value, g_value_get_float (value)); + sink->cb_changed |= (1U << id); + return TRUE; +} + +static inline gfloat +cb_get_value (GstVaapiSink * sink, guint id) +{ + const GValue *const v_value = cb_get_gvalue (sink, id); + + return v_value ? g_value_get_float (v_value) : 0.0; +} + +static gboolean +cb_set_value (GstVaapiSink * sink, guint id, gfloat value) +{ + GValue v_value = G_VALUE_INIT; + gboolean success; + + g_value_init (&v_value, G_TYPE_FLOAT); + g_value_set_float (&v_value, value); + success = cb_set_gvalue (sink, id, &v_value); + g_value_unset (&v_value); + return success; +} + +static gboolean +cb_sync_values_from_display (GstVaapiSink * sink, GstVaapiDisplay * display) +{ + GValue v_value = G_VALUE_INIT; + guint i, failures = 0; + + for (i = 0; i < G_N_ELEMENTS (sink->cb_values); i++) { + const guint cb_id = CB_HUE + i; + if (!gst_vaapi_display_has_property (display, cb_map[i].prop_name)) + continue; + + if (G_IS_VALUE (&v_value)) + g_value_unset (&v_value); + if (gst_vaapi_display_get_property (display, cb_map[i].prop_name, &v_value)) + cb_set_gvalue (sink, cb_id, &v_value); + else + failures++; + } + sink->cb_changed = 0; + return failures == 0; +} + +static gboolean +cb_sync_values_to_display (GstVaapiSink * sink, GstVaapiDisplay * display) +{ + guint i, failures = 0; + + for (i = 0; i < G_N_ELEMENTS (sink->cb_values); i++) { + const guint cb_id = CB_HUE + i; + if (!(sink->cb_changed & (1U << cb_id))) + continue; + + if (!gst_vaapi_display_set_property (display, cb_map[i].prop_name, + cb_get_gvalue (sink, cb_id))) + failures++; + } + sink->cb_changed = 0; + return failures == 0; +} + /* ------------------------------------------------------------------------ */ /* --- Common implementation --- */ /* ------------------------------------------------------------------------ */ @@ -730,6 +838,12 @@ gst_vaapisink_ensure_window_size (GstVaapiSink * sink, guint * width_ptr, *height_ptr = out_rect.h; } +static inline gboolean +gst_vaapisink_ensure_colorbalance (GstVaapiSink * sink) +{ + return cb_sync_values_to_display (sink, GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); +} + static gboolean gst_vaapisink_ensure_rotation (GstVaapiSink * sink, gboolean recalc_display_rect) @@ -799,6 +913,10 @@ gst_vaapisink_display_changed (GstVaapiPluginBase * plugin) GST_DEBUG ("use %s rendering mode", sink->use_overlay ? "overlay" : "texture"); + /* Keep our own colorbalance values, should we have any change pending */ + if (!sink->cb_changed) + cb_sync_values_from_display (sink, plugin->display); + sink->use_rotation = gst_vaapi_display_has_property (plugin->display, GST_VAAPI_DISPLAY_PROP_ROTATION); } @@ -914,6 +1032,7 @@ gst_vaapisink_set_caps (GstBaseSink * base_sink, GstCaps * caps) update_colorimetry (sink, &vip->colorimetry); gst_caps_replace (&sink->caps, caps); + gst_vaapisink_ensure_colorbalance (sink); gst_vaapisink_ensure_rotation (sink, FALSE); gst_vaapisink_ensure_window_size (sink, &win_width, &win_height); @@ -993,6 +1112,7 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) return GST_FLOW_OK; } + gst_vaapisink_ensure_colorbalance (sink); gst_vaapisink_ensure_rotation (sink, TRUE); GST_DEBUG ("render surface %" GST_VAAPI_ID_FORMAT, @@ -1130,6 +1250,12 @@ gst_vaapisink_set_property (GObject * object, case PROP_FORCE_ASPECT_RATIO: sink->keep_aspect = g_value_get_boolean (value); break; + case PROP_HUE: + case PROP_SATURATION: + case PROP_BRIGHTNESS: + case PROP_CONTRAST: + cb_set_gvalue (sink, (prop_id - PROP_HUE) + CB_HUE, value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1161,6 +1287,13 @@ gst_vaapisink_get_property (GObject * object, case PROP_FORCE_ASPECT_RATIO: g_value_set_boolean (value, sink->keep_aspect); break; + case PROP_HUE: + case PROP_SATURATION: + case PROP_BRIGHTNESS: + case PROP_CONTRAST: + g_value_set_float (value, cb_get_value (sink, + (prop_id - PROP_HUE) + CB_HUE)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1293,6 +1426,53 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) "ID of the view component of interest to display", -1, G_MAXINT32, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiSink:hue: + * + * The VA display hue, expressed as a float value. Range is -180.0 + * to 180.0. Default value is 0.0 and represents no modification. + */ + g_properties[PROP_HUE] = + g_param_spec_float (GST_VAAPI_DISPLAY_PROP_HUE, + "hue", "The display hue value", -180.0, 180.0, 0.0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT); + + /** + * GstVaapiSink:saturation: + * + * The VA display saturation, expressed as a float value. Range is + * 0.0 to 2.0. Default value is 1.0 and represents no modification. + */ + g_properties[PROP_SATURATION] = + g_param_spec_float (GST_VAAPI_DISPLAY_PROP_SATURATION, + "saturation", + "The display saturation value", 0.0, 2.0, 1.0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT); + + /** + * GstVaapiSink:brightness: + * + * The VA display brightness, expressed as a float value. Range is + * -1.0 to 1.0. Default value is 0.0 and represents no modification. + */ + g_properties[PROP_BRIGHTNESS] = + g_param_spec_float (GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, + "brightness", + "The display brightness value", -1.0, 1.0, 0.0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT); + + /** + * GstVaapiSink:contrast: + * + * The VA display contrast, expressed as a float value. Range is 0.0 + * to 2.0. Default value is 1.0 and represents no modification. + */ + g_properties[PROP_CONTRAST] = + g_param_spec_float (GST_VAAPI_DISPLAY_PROP_CONTRAST, + "contrast", + "The display contrast value", 0.0, 2.0, 1.0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT); + g_object_class_install_properties (object_class, N_PROPERTIES, g_properties); } @@ -1300,6 +1480,7 @@ static void gst_vaapisink_init (GstVaapiSink * sink) { GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (sink); + guint i; gst_vaapi_plugin_base_init (plugin, GST_CAT_DEFAULT); gst_vaapi_plugin_base_set_display_type (plugin, DEFAULT_DISPLAY_TYPE); @@ -1312,4 +1493,7 @@ gst_vaapisink_init (GstVaapiSink * sink) sink->rotation_req = DEFAULT_ROTATION; sink->keep_aspect = TRUE; gst_video_info_init (&sink->video_info); + + for (i = 0; i < G_N_ELEMENTS (sink->cb_values); i++) + g_value_init (&sink->cb_values[i], G_TYPE_FLOAT); } diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 6879d9845d..125de2e276 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -98,6 +98,11 @@ struct _GstVaapiSink gint32 view_id; GThread *event_thread; volatile gboolean event_thread_cancel; + + /* Color balance values */ + guint cb_changed; + GValue cb_values[4]; + guint handle_events : 1; guint foreign_window : 1; guint fullscreen : 1; From c201f738fe535d94c6526c38d1a7f205c3f32241 Mon Sep 17 00:00:00 2001 From: Changzhi Wei Date: Thu, 23 Jan 2014 15:44:09 +0000 Subject: [PATCH 1754/3781] vaapisink: add support for GstColorBalance interface. https://bugzilla.gnome.org/show_bug.cgi?id=722390 [fixed channel names, simplified range factor, fixed memory leak] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 150 +++++++++++++++++++++++++++++++++++++-- gst/vaapi/gstvaapisink.h | 1 + 2 files changed, 145 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index f6ce385fe2..2462737f8e 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -40,8 +40,10 @@ /* Supported interfaces */ #if GST_CHECK_VERSION(1,0,0) # include +# include #else # include +# include # define GST_TYPE_VIDEO_OVERLAY GST_TYPE_X_OVERLAY # define GST_VIDEO_OVERLAY GST_X_OVERLAY @@ -52,6 +54,8 @@ gst_x_overlay_prepare_xwindow_id(sink) # define gst_video_overlay_got_window_handle(sink, window_handle) \ gst_x_overlay_got_window_handle(sink, window_handle) + +# define GstColorBalanceInterface GstColorBalanceClass #endif #include "gstvaapisink.h" @@ -94,18 +98,23 @@ GST_STATIC_PAD_TEMPLATE ("sink", static gboolean gst_vaapisink_has_interface (GstVaapiPluginBase * plugin, GType type) { - return type == GST_TYPE_VIDEO_OVERLAY; + return type == GST_TYPE_VIDEO_OVERLAY || type == GST_TYPE_COLOR_BALANCE; } static void gst_vaapisink_video_overlay_iface_init (GstVideoOverlayInterface * iface); +static void +gst_vaapisink_color_balance_iface_init (GstColorBalanceInterface * iface); + G_DEFINE_TYPE_WITH_CODE (GstVaapiSink, gst_vaapisink, GST_TYPE_VIDEO_SINK, GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY, - gst_vaapisink_video_overlay_iface_init)); + gst_vaapisink_video_overlay_iface_init); + G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE, + gst_vaapisink_color_balance_iface_init)); enum { @@ -502,6 +511,10 @@ gst_vaapisink_video_overlay_iface_init (GstVideoOverlayInterface * iface) iface->handle_events = gst_vaapisink_video_overlay_set_event_handling; } +/* ------------------------------------------------------------------------ */ +/* --- GstColorBalance interface --- */ +/* ------------------------------------------------------------------------ */ + enum { CB_HUE = 1, @@ -514,15 +527,30 @@ typedef struct { guint cb_id; const gchar *prop_name; + const gchar *channel_name; } ColorBalanceMap; static const ColorBalanceMap cb_map[4] = { - {CB_HUE, GST_VAAPI_DISPLAY_PROP_HUE}, - {CB_SATURATION, GST_VAAPI_DISPLAY_PROP_SATURATION}, - {CB_BRIGHTNESS, GST_VAAPI_DISPLAY_PROP_BRIGHTNESS}, - {CB_CONTRAST, GST_VAAPI_DISPLAY_PROP_CONTRAST} + {CB_HUE, GST_VAAPI_DISPLAY_PROP_HUE, "VA_HUE"}, + {CB_SATURATION, GST_VAAPI_DISPLAY_PROP_SATURATION, "VA_SATURATION"}, + {CB_BRIGHTNESS, GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, "VA_BRIGHTNESS"}, + {CB_CONTRAST, GST_VAAPI_DISPLAY_PROP_CONTRAST, "VA_CONTRAST"} }; +static guint +cb_get_id_from_channel_name (GstVaapiSink * sink, const gchar * name) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (sink->cb_values); i++) { + if (g_ascii_strcasecmp (cb_map[i].channel_name, name) == 0) + return cb_map[i].cb_id; + } + + GST_WARNING ("got an unknown channel %s", name); + return 0; +} + static inline GValue * cb_get_gvalue (GstVaapiSink * sink, guint id) { @@ -606,6 +634,115 @@ cb_sync_values_to_display (GstVaapiSink * sink, GstVaapiDisplay * display) return failures == 0; } +#define CB_CHANNEL_FACTOR (1000.0) + +static void +cb_channels_init (GstVaapiSink * sink) +{ + GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); + GstColorBalanceChannel *channel; + GParamSpecFloat *pspec; + guint i; + + for (i = 0; i < G_N_ELEMENTS (sink->cb_values); i++) { + if (!gst_vaapi_display_has_property (display, cb_map[i].prop_name)) + continue; + + pspec = G_PARAM_SPEC_FLOAT (g_properties[PROP_HUE + i]); + if (!pspec) + continue; + + channel = g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL, NULL); + channel->label = g_strdup (cb_map[i].channel_name); + channel->min_value = pspec->minimum * CB_CHANNEL_FACTOR; + channel->max_value = pspec->maximum * CB_CHANNEL_FACTOR; + + sink->cb_channels = g_list_prepend (sink->cb_channels, channel); + } + + if (sink->cb_channels) + sink->cb_channels = g_list_reverse (sink->cb_channels); +} + +static void +cb_channels_finalize (GstVaapiSink * sink) +{ + if (sink->cb_channels) { + g_list_free_full (sink->cb_channels, g_object_unref); + sink->cb_channels = NULL; + } +} + +static const GList * +gst_vaapisink_color_balance_list_channels (GstColorBalance * cb) +{ + GstVaapiSink *const sink = GST_VAAPISINK (cb); + + if (!gst_vaapisink_ensure_display (sink)) + return NULL; + + if (!sink->cb_channels) + cb_channels_init (sink); + return sink->cb_channels; +} + +static void +gst_vaapisink_color_balance_set_value (GstColorBalance * cb, + GstColorBalanceChannel * channel, gint value) +{ + GstVaapiSink *const sink = GST_VAAPISINK (cb); + guint cb_id; + + g_return_if_fail (channel->label != NULL); + + if (!gst_vaapisink_ensure_display (sink)) + return; + + cb_id = cb_get_id_from_channel_name (sink, channel->label); + if (!cb_id) + return; + + cb_set_value (sink, cb_id, value / CB_CHANNEL_FACTOR); +} + +static gint +gst_vaapisink_color_balance_get_value (GstColorBalance * cb, + GstColorBalanceChannel * channel) +{ + GstVaapiSink *const sink = GST_VAAPISINK (cb); + guint cb_id; + + g_return_val_if_fail (channel->label != NULL, 0); + + if (!gst_vaapisink_ensure_display (sink)) + return 0; + + cb_id = cb_get_id_from_channel_name (sink, channel->label); + if (!cb_id) + return 0; + + return cb_get_value (sink, cb_id) * CB_CHANNEL_FACTOR; +} + +static GstColorBalanceType +gst_vaapisink_color_balance_get_type (GstColorBalance * cb) +{ + return GST_COLOR_BALANCE_HARDWARE; +} + +static void +gst_vaapisink_color_balance_iface_init (GstColorBalanceInterface * iface) +{ + iface->list_channels = gst_vaapisink_color_balance_list_channels; + iface->set_value = gst_vaapisink_color_balance_set_value; + iface->get_value = gst_vaapisink_color_balance_get_value; +#if GST_CHECK_VERSION(1,0,0) + iface->get_balance_type = gst_vaapisink_color_balance_get_type; +#else + iface->balance_type = gst_vaapisink_color_balance_get_type (NULL); +#endif +} + /* ------------------------------------------------------------------------ */ /* --- Common implementation --- */ /* ------------------------------------------------------------------------ */ @@ -1210,6 +1347,7 @@ gst_vaapisink_destroy (GstVaapiSink * sink) { gst_vaapisink_set_event_handling (sink, FALSE); + cb_channels_finalize (sink); gst_buffer_replace (&sink->video_buffer, NULL); gst_caps_replace (&sink->caps, NULL); } diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 125de2e276..958d6cc17a 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -102,6 +102,7 @@ struct _GstVaapiSink /* Color balance values */ guint cb_changed; GValue cb_values[4]; + GList *cb_channels; guint handle_events : 1; guint foreign_window : 1; From 7ac501d026036887c114b28bc9fb4aabc557e91a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 1 Aug 2014 06:32:32 +0200 Subject: [PATCH 1755/3781] build: fix with --no-undefined linker flags. https://bugzilla.gnome.org/show_bug.cgi?id=729352 --- gst-libs/gst/vaapi/Makefile.am | 7 +++++++ gst/vaapi/Makefile.am | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index b88f1db6cb..9d90f71ed0 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -317,6 +317,7 @@ libgstvaapi_drm_@GST_API_VERSION@_la_CFLAGS = \ libgstvaapi_drm_@GST_API_VERSION@_la_LIBADD = \ $(GLIB_LIBS) \ + $(GST_LIBS) \ $(UDEV_LIBS) \ $(DRM_LIBS) \ $(LIBVA_DRM_LIBS) \ @@ -355,6 +356,7 @@ libgstvaapi_x11_@GST_API_VERSION@_la_CFLAGS = \ libgstvaapi_x11_@GST_API_VERSION@_la_LIBADD = \ $(GLIB_LIBS) \ + $(GST_LIBS) \ $(X11_LIBS) \ $(XRANDR_LIBS) \ $(XRENDER_LIBS) \ @@ -392,11 +394,14 @@ libgstvaapi_glx_@GST_API_VERSION@_la_CFLAGS = \ libgstvaapi_glx_@GST_API_VERSION@_la_LIBADD = \ $(GLIB_LIBS) \ + $(GST_LIBS) \ $(GST_BASE_LIBS) \ $(GST_VIDEO_LIBS) \ + $(X11_LIBS) \ $(GL_LIBS) \ $(LIBVA_GLX_LIBS) \ libgstvaapi-x11-$(GST_API_VERSION).la \ + libgstvaapi-$(GST_API_VERSION).la \ $(DLOPEN_LIBS) \ $(NULL) @@ -431,6 +436,8 @@ libgstvaapi_wayland_@GST_API_VERSION@_la_CFLAGS = \ libgstvaapi_wayland_@GST_API_VERSION@_la_LIBADD = \ $(GLIB_LIBS) \ + $(GST_LIBS) \ + $(GST_VIDEO_LIBS) \ $(WAYLAND_LIBS) \ $(LIBVA_WAYLAND_LIBS) \ libgstvaapi-$(GST_API_VERSION).la \ diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index a52bc2fe1e..58800db59c 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -7,7 +7,8 @@ libgstvaapi_CFLAGS = \ -I$(top_builddir)/gst-libs \ $(NULL) -libgstvaapi_LIBS = +libgstvaapi_LIBS = \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_API_VERSION).la if USE_DRM libgstvaapi_LIBS += \ @@ -16,6 +17,7 @@ endif if USE_X11 libgstvaapi_LIBS += \ + $(X11_LIBS) \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la endif From 4ff4563a471e3a0a089648a539084ee220483e88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 11 Aug 2014 17:14:53 +0300 Subject: [PATCH 1756/3781] vaapidecode: don't try flushing the decoder instance if we didn't create one yet This otherwise results in unnecessary error messages. https://bugzilla.gnome.org/show_bug.cgi?id=734616 --- gst/vaapi/gstvaapidecode.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3891729e9a..11951d469f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -463,6 +463,9 @@ gst_vaapidecode_flush(GstVideoDecoder *vdec) GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstVaapiDecoderStatus status; + if (!decode->decoder) + return TRUE; + /* If there is something in GstVideoDecoder's output adapter, then submit the frame for decoding */ if (decode->current_frame_size) { @@ -489,6 +492,9 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstFlowReturn ret = GST_FLOW_OK; + if (!decode->decoder) + return GST_FLOW_OK; + if (!gst_vaapidecode_flush(vdec)) ret = GST_FLOW_OK; From c551cc7cc347f279474ddc427930f206f898167a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 11 Aug 2014 17:15:24 +0300 Subject: [PATCH 1757/3781] vaapidecode: reset decoder_finish variable after stopping the decoder thread Otherwise the element is not usable again after draining/EOS. https://bugzilla.gnome.org/show_bug.cgi?id=734616 --- gst/vaapi/gstvaapidecode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 11951d469f..15620a2d29 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -510,6 +510,7 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); GST_VIDEO_DECODER_STREAM_LOCK(vdec); } + decode->decoder_finish = FALSE; return ret; } From 2af44842c6d3cde3d3a6788bdcd149802fb75908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 12 Aug 2014 13:00:03 +0300 Subject: [PATCH 1758/3781] vaapidecode: unlock condition variables before shutting down the element Otherwise threads might wait for them, causing the shutdown of the element to deadlock on the streaming thread. https://bugzilla.gnome.org/show_bug.cgi?id=734616 --- gst/vaapi/gstvaapidecode.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 15620a2d29..aab99ade5c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -929,7 +929,13 @@ gst_vaapidecode_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: + g_mutex_lock(&decode->decoder_mutex); + decode->decoder_finish = TRUE; + g_cond_signal(&decode->decoder_finish_done); + g_cond_signal(&decode->decoder_ready); + g_mutex_unlock(&decode->decoder_mutex); gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); + decode->decoder_finish = FALSE; break; default: break; From 3b2e06be6cd5d42a9961c0a0c635289c54f48d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 12 Aug 2014 13:01:57 +0300 Subject: [PATCH 1759/3781] vaapidecode: start the decoder task again after finishing This allows the element to accept data again after draining without a hard reset or caps change happening in between. https://bugzilla.gnome.org/show_bug.cgi?id=734616 --- gst/vaapi/gstvaapidecode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index aab99ade5c..4f716c6a78 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -500,8 +500,8 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) /* Make sure the decode loop function has a chance to return, thus possibly unlocking gst_video_decoder_finish_frame() */ - decode->decoder_finish = TRUE; if (decode->decoder_loop_status == GST_FLOW_OK) { + decode->decoder_finish = TRUE; GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); g_mutex_lock(&decode->decoder_mutex); while (decode->decoder_loop_status == GST_FLOW_OK) @@ -509,8 +509,10 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) g_mutex_unlock(&decode->decoder_mutex); gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); GST_VIDEO_DECODER_STREAM_LOCK(vdec); + decode->decoder_finish = FALSE; + gst_pad_start_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode), + (GstTaskFunction)gst_vaapidecode_decode_loop, decode, NULL); } - decode->decoder_finish = FALSE; return ret; } From 95d1826dca82025c51a3e524f404bd15fc753da4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Aug 2014 11:30:41 +0200 Subject: [PATCH 1760/3781] plugins: add helper for detecting VA surfaces in caps. Introduce new gst_caps_has_vaapi_surface() helper function to detect whether the supplied caps has VA surfaces. With GStreamer >= 1.2, this implies a check for memory:VASurface caps features, and format=ENCODED for earlier versions of GStreamer. --- gst/vaapi/gstvaapipluginutil.c | 44 ++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 4 ++++ 2 files changed, 48 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 7c3e35424a..2c3a3cd00e 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -612,3 +612,47 @@ gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip) #endif return TRUE; } + +/* Checks whether the supplied caps contain VA surfaces */ +gboolean +gst_caps_has_vaapi_surface (GstCaps * caps) +{ + gboolean found_caps = FALSE; + guint i, num_structures; + + g_return_val_if_fail (caps != NULL, FALSE); + + num_structures = gst_caps_get_size (caps); + if (num_structures < 1) + return FALSE; + +#if GST_CHECK_VERSION(1,1,0) + for (i = 0; i < num_structures && !found_caps; i++) { + GstCapsFeatures *const features = gst_caps_get_features (caps, i); + +#if GST_CHECK_VERSION(1,3,0) + /* Skip ANY features, we need an exact match for correct evaluation */ + if (gst_caps_features_is_any (features)) + continue; +#endif + + found_caps = gst_caps_features_contains (features, + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE); + } +#else + for (i = 0; i < num_structures && !found_caps; i++) { + GstStructure *const structure = gst_caps_get_structure (caps, i); + GstCaps *test_caps; + GstVideoInfo vi; + + test_caps = gst_caps_new_full (gst_structure_copy (structure), NULL); + if (!test_caps) + continue; + + found_caps = gst_video_info_from_caps (&vi, test_caps) && + GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED; + gst_caps_unref (test_caps); + } +#endif + return found_caps; +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 4fc7450417..6380a11a44 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -109,4 +109,8 @@ G_GNUC_INTERNAL gboolean gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip); +G_GNUC_INTERNAL +gboolean +gst_caps_has_vaapi_surface (GstCaps * caps); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ From 7e9ac1cb980eb441c0669d81d2ca2f9a1f698d80 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Aug 2014 11:43:08 +0200 Subject: [PATCH 1761/3781] plugins: fix detection of raw video caps. Use the new gst_caps_has_vaapi_surface() helper function to better detect raw video caps, and in particular those from RGB colorspace. https://bugzilla.gnome.org/show_bug.cgi?id=734665 --- gst/vaapi/gstvaapipluginbase.c | 11 ++++++----- gst/vaapi/gstvaapipluginbase.h | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index c5689e3637..ad254f2bd1 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -389,6 +389,7 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, if (!gst_video_info_from_caps (&plugin->sinkpad_info, incaps)) return FALSE; plugin->sinkpad_caps_changed = TRUE; + plugin->sinkpad_caps_is_raw = !gst_caps_has_vaapi_surface (incaps); } if (outcaps && outcaps != plugin->srcpad_caps) { @@ -398,7 +399,7 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, plugin->srcpad_caps_changed = TRUE; } - if (plugin->uploader && GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) { + if (plugin->uploader && plugin->sinkpad_caps_is_raw) { if (!gst_vaapi_uploader_ensure_display (plugin->uploader, plugin->display)) return FALSE; if (!gst_vaapi_uploader_ensure_caps (plugin->uploader, @@ -477,7 +478,7 @@ gst_vaapi_plugin_base_allocate_input_buffer (GstVaapiPluginBase * plugin, plugin->sinkpad_caps_changed = TRUE; } - if (!GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) + if (!plugin->sinkpad_caps_is_raw) return GST_FLOW_OK; if (!gst_vaapi_uploader_ensure_display (plugin->uploader, plugin->display)) @@ -529,7 +530,7 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, return GST_FLOW_OK; } - if (!GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) + if (!plugin->sinkpad_caps_is_raw) goto error_invalid_buffer; if (!plugin->sinkpad_buffer_pool) @@ -586,7 +587,7 @@ error_map_src_buffer: #else if (meta) outbuf = gst_buffer_ref (inbuf); - else if (GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) { + else if (plugin->sinkpad_caps_is_raw) { outbuf = gst_vaapi_uploader_get_buffer (plugin->uploader); if (!outbuf) goto error_create_buffer; @@ -595,7 +596,7 @@ error_map_src_buffer: } else goto error_invalid_buffer; - if (GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info) && + if (plugin->sinkpad_caps_is_raw && !gst_vaapi_uploader_process (plugin->uploader, inbuf, outbuf)) goto error_copy_buffer; diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index f0ee4295c9..76413b3d18 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -123,6 +123,7 @@ struct _GstVaapiPluginBase GstPad *sinkpad; GstCaps *sinkpad_caps; gboolean sinkpad_caps_changed; + gboolean sinkpad_caps_is_raw; GstVideoInfo sinkpad_info; GstPadQueryFunction sinkpad_query; #if GST_CHECK_VERSION(1,0,0) From 197001768b96cfb382cfd4ab52ee200986c6a31d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 7 Aug 2014 14:57:26 +0200 Subject: [PATCH 1762/3781] vaapipostproc: fix heuristic for detecting discontinuity. In order to make the discontinuity detection code useful, we need to detect the lost frames in the history as early as the previous frame. This is because some VA implementations only support one reference frame for advanced deinterlacing. In practice, turn the condition for detecting new frame that is beyond the previous frame from field_duration*2 to field_duration*3, i.e. nothing received for the past frame and a half because of possible rounding errors when calculating the field-duration either in this element (vaapipostproc), or from the upstream element (parser element). This is a regression introduced with commit faefd62. https://bugzilla.gnome.org/show_bug.cgi?id=734135 --- gst/vaapi/gstvaapipostproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index e692f54a34..56646b057e 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -525,7 +525,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, if (prev_buf && (prev_pts = GST_BUFFER_TIMESTAMP(prev_buf)) != pts) { const GstClockTimeDiff pts_diff = GST_CLOCK_DIFF(prev_pts, pts); if (pts_diff < 0 || (postproc->field_duration > 0 && - pts_diff > postproc->field_duration * 2)) + pts_diff >= postproc->field_duration * 3 - 1)) ds_reset(ds); } } From 6d8c5221b2da641cbd474d7bbc6bf7f995f7643a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 12 Aug 2014 18:33:25 +0200 Subject: [PATCH 1763/3781] vaapipostproc: disable discontinuity detection code. The "discontinuity" tracking code, whereby lost frames are tentatively detected, is inoperant if the sink pad buffer timestamps are not right to begin with. This is a temporary workaround until the following bug is fixed: https://bugzilla.gnome.org/show_bug.cgi?id=734386 --- gst/vaapi/gstvaapipostproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 56646b057e..664cd0e496 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -518,7 +518,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, deint_method = postproc->deinterlace_method; deint_refs = deint_method_is_advanced(deint_method); - if (deint_refs) { + if (deint_refs && 0) { GstBuffer * const prev_buf = ds_get_buffer(ds, 0); GstClockTime prev_pts, pts = GST_BUFFER_TIMESTAMP(inbuf); /* Reset deinterlacing state when there is a discontinuity */ From d82e6a8866be7d92a4e144fc256bec4ed7dcd8d2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Aug 2014 10:37:02 +0200 Subject: [PATCH 1764/3781] vaapipostproc: improve heuristics for detecting native VA surfaces. Use the new gst_caps_has_vaapi_surface() helper function to detect whether the sink pad caps contain native VA surfaces, or not, i.e. no raw video caps. Also rename is_raw_yuv to get_va_surfaces to make the variable more explicit as we just want a way to differentiate raw video caps from VA surfaces actually. --- gst/vaapi/gstvaapipostproc.c | 7 ++++--- gst/vaapi/gstvaapipostproc.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 664cd0e496..b7feb90f21 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -830,7 +830,7 @@ gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps, gst_util_uint64_scale(GST_SECOND, GST_VIDEO_INFO_FPS_D(&vi), (1 + deinterlace) * GST_VIDEO_INFO_FPS_N(&vi)) : 0; - postproc->is_raw_yuv = GST_VIDEO_INFO_IS_YUV(&vi); + postproc->get_va_surfaces = gst_caps_has_vaapi_surface(caps); return TRUE; } @@ -1098,7 +1098,7 @@ gst_vaapipostproc_transform_size(GstBaseTransform *trans, { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); - if (direction == GST_PAD_SINK || !postproc->is_raw_yuv) + if (direction == GST_PAD_SINK || postproc->get_va_surfaces) *othersize = 0; else *othersize = size; @@ -1237,7 +1237,7 @@ gst_vaapipostproc_propose_allocation(GstBaseTransform *trans, GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(trans); /* Let vaapidecode allocate the video buffers */ - if (!postproc->is_raw_yuv) + if (postproc->get_va_surfaces) return FALSE; if (!gst_vaapi_plugin_base_propose_allocation(plugin, query)) return FALSE; @@ -1587,6 +1587,7 @@ gst_vaapipostproc_init(GstVaapiPostproc *postproc) postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; postproc->field_duration = GST_CLOCK_TIME_NONE; postproc->keep_aspect = TRUE; + postproc->get_va_surfaces = TRUE; gst_video_info_init(&postproc->sinkpad_info); gst_video_info_init(&postproc->srcpad_info); diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 5b23c36910..1154d3fe23 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -166,7 +166,7 @@ struct _GstVaapiPostproc { gfloat brightness; gfloat contrast; - guint is_raw_yuv : 1; + guint get_va_surfaces : 1; guint use_vpp : 1; guint keep_aspect : 1; }; From 913f2ef68c2887a9d9d0cdaf9da5098f45e7b446 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Aug 2014 10:59:53 +0200 Subject: [PATCH 1765/3781] vaapipostproc: fix construction of allowed sink pad caps. Fix construction of the set of caps allowed on the sink pad to filter out unsupported raw video caps with GStreamer >= 1.2. --- gst/vaapi/gstvaapipostproc.c | 40 +++++++++++++++--------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index b7feb90f21..73fafc1d94 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -46,14 +46,18 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapipostproc); #define GST_CAT_DEFAULT gst_debug_vaapipostproc +#if GST_CHECK_VERSION(1,1,0) +# define GST_VAAPIPOSTPROC_SURFACE_CAPS \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") +#else +# define GST_VAAPIPOSTPROC_SURFACE_CAPS \ + GST_VAAPI_SURFACE_CAPS +#endif + /* Default templates */ static const char gst_vaapipostproc_sink_caps_str[] = -#if GST_CHECK_VERSION(1,1,0) - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ", " -#else - GST_VAAPI_SURFACE_CAPS ", " -#endif + GST_VAAPIPOSTPROC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES "; " #if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) ", " @@ -66,12 +70,7 @@ static const char gst_vaapipostproc_sink_caps_str[] = GST_CAPS_INTERLACED_MODES; static const char gst_vaapipostproc_src_caps_str[] = -#if GST_CHECK_VERSION(1,1,0) - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ", " -#else - GST_VAAPI_SURFACE_CAPS ", " -#endif + GST_VAAPIPOSTPROC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE; static GstStaticPadTemplate gst_vaapipostproc_sink_factory = @@ -859,30 +858,25 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps, static gboolean ensure_allowed_sinkpad_caps(GstVaapiPostproc *postproc) { - GstCaps *out_caps, *yuv_caps; + GstCaps *out_caps, *raw_caps; if (postproc->allowed_sinkpad_caps) return TRUE; /* Create VA caps */ -#if GST_CHECK_VERSION(1,1,0) - out_caps = gst_static_pad_template_get_caps( - &gst_vaapipostproc_sink_factory); -#else - out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS ", " + out_caps = gst_caps_from_string(GST_VAAPIPOSTPROC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES); -#endif if (!out_caps) { GST_ERROR("failed to create VA sink caps"); return FALSE; } - /* Append YUV caps */ + /* Append raw video caps */ if (gst_vaapipostproc_ensure_uploader(postproc)) { - yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(postproc); - if (yuv_caps) { + raw_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(postproc); + if (raw_caps) { out_caps = gst_caps_make_writable(out_caps); - gst_caps_append(out_caps, gst_caps_copy(yuv_caps)); + gst_caps_append(out_caps, gst_caps_copy(raw_caps)); } else GST_WARNING("failed to create YUV sink caps"); From dfa70b9e8504049ffc3374f0342d01ca2770a203 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 20 Aug 2014 16:38:45 +0200 Subject: [PATCH 1766/3781] vaapipostproc: fix detection of output surface format changes. Default to I420 format for output surfaces so that to match the usual GStreamer pipelines. Though, internally, we could still opt for NV12 surface formats, i.e. default format=ENCODED is a hint for that, thus delegating the decision to the VA driver. --- gst/vaapi/gstvaapipostproc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 73fafc1d94..805e354807 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -49,7 +49,7 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapipostproc); #if GST_CHECK_VERSION(1,1,0) # define GST_VAAPIPOSTPROC_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") #else # define GST_VAAPIPOSTPROC_SURFACE_CAPS \ GST_VAAPI_SURFACE_CAPS @@ -845,7 +845,8 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps, if (video_info_changed(&vi, &postproc->srcpad_info)) postproc->srcpad_info = vi, *caps_changed_ptr = TRUE; - if (postproc->format != GST_VIDEO_INFO_FORMAT(&postproc->sinkpad_info)) + if (postproc->format != GST_VIDEO_INFO_FORMAT(&postproc->sinkpad_info) || + postproc->format != DEFAULT_FORMAT) postproc->flags |= GST_VAAPI_POSTPROC_FLAG_FORMAT; if ((postproc->width || postproc->height) && From 97d7f21575531a840c254e7179b1c6f6a3cfb49c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Aug 2014 15:12:46 +0200 Subject: [PATCH 1767/3781] surfaceproxy: fix copy to propagate view_id. Fix gst_vaapi_surface_proxy_copy() to copy the view-id element, thus fixing random frames skipped when vaapipostproc element is used in passthrough mode. In that mode, GstMemory is copied, thus including the underlying GstVaapiVideoMeta and associated GstVaapiSurfaceProxy. --- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index ab8f508a73..1b817553c0 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -136,6 +136,7 @@ gst_vaapi_surface_proxy_copy(GstVaapiSurfaceProxy *proxy) proxy->parent : proxy); copy->pool = gst_vaapi_video_pool_ref(proxy->pool); copy->surface = gst_vaapi_object_ref(proxy->surface); + copy->view_id = proxy->view_id; copy->timestamp = proxy->timestamp; copy->duration = proxy->duration; copy->destroy_func = NULL; From 038d56bdcadabf7e020f0bbd06c0d57ea14d042d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Aug 2014 10:45:31 +0200 Subject: [PATCH 1768/3781] plugins: re-indent all GstVaapiVideo* related source code. --- gst/vaapi/gstvaapivideobuffer.c | 303 +++++---- gst/vaapi/gstvaapivideobuffer.h | 14 +- gst/vaapi/gstvaapivideobufferpool.c | 438 ++++++------ gst/vaapi/gstvaapivideobufferpool.h | 53 +- gst/vaapi/gstvaapivideocontext.c | 12 +- gst/vaapi/gstvaapivideocontext.h | 4 +- gst/vaapi/gstvaapivideoconverter_glx.c | 130 ++-- gst/vaapi/gstvaapivideoconverter_glx.h | 61 +- gst/vaapi/gstvaapivideoconverter_x11.c | 180 ++--- gst/vaapi/gstvaapivideoconverter_x11.h | 61 +- gst/vaapi/gstvaapivideomemory.c | 900 ++++++++++++------------- gst/vaapi/gstvaapivideomemory.h | 99 +-- gst/vaapi/gstvaapivideometa.c | 674 +++++++++--------- gst/vaapi/gstvaapivideometa.h | 62 +- gst/vaapi/gstvaapivideometa_texture.c | 136 ++-- gst/vaapi/gstvaapivideometa_texture.h | 6 +- 16 files changed, 1561 insertions(+), 1572 deletions(-) diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 597689a4fc..a36846db93 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -38,174 +38,171 @@ #if GST_CHECK_VERSION(1,1,0) static inline GstBuffer * -gst_surface_buffer_new(void) +gst_surface_buffer_new (void) { - return gst_buffer_new(); + return gst_buffer_new (); } #elif GST_CHECK_VERSION(1,0,0) #include #define GST_VAAPI_SURFACE_META_CAST(obj) \ - ((GstVaapiSurfaceMeta *)(obj)) + ((GstVaapiSurfaceMeta *) (obj)) typedef struct _GstVaapiSurfaceMeta GstVaapiSurfaceMeta; -struct _GstVaapiSurfaceMeta { - GstSurfaceMeta base; - GstBuffer *buffer; +struct _GstVaapiSurfaceMeta +{ + GstSurfaceMeta base; + GstBuffer *buffer; }; -#define GST_VAAPI_SURFACE_META_INFO gst_vaapi_surface_meta_get_info() -static const GstMetaInfo * -gst_vaapi_surface_meta_get_info(void); +#define GST_VAAPI_SURFACE_META_INFO \ + gst_vaapi_surface_meta_get_info () -typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc)( - GstSurfaceMeta *meta, const gchar *type, GValue *dest); +static const GstMetaInfo * +gst_vaapi_surface_meta_get_info (void); + +typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc) (GstSurfaceMeta * + meta, const gchar * type, GValue * dest); #if USE_X11 static GstSurfaceConverter * -gst_vaapi_surface_create_converter_x11(GstSurfaceMeta *base_meta, - const gchar *type, GValue *dest) +gst_vaapi_surface_create_converter_x11 (GstSurfaceMeta * base_meta, + const gchar * type, GValue * dest) { - GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta); + GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta); - return gst_vaapi_video_converter_x11_new(meta->buffer, type, dest); + return gst_vaapi_video_converter_x11_new (meta->buffer, type, dest); } #undef gst_vaapi_video_converter_x11_new #define gst_vaapi_video_converter_x11_new \ - gst_vaapi_surface_create_converter_x11 + gst_vaapi_surface_create_converter_x11 #endif #if USE_GLX static GstSurfaceConverter * -gst_vaapi_surface_create_converter_glx(GstSurfaceMeta *base_meta, - const gchar *type, GValue *dest) +gst_vaapi_surface_create_converter_glx (GstSurfaceMeta * base_meta, + const gchar * type, GValue * dest) { - GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta); + GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta); - return gst_vaapi_video_converter_glx_new(meta->buffer, type, dest); + return gst_vaapi_video_converter_glx_new (meta->buffer, type, dest); } #undef gst_vaapi_video_converter_glx_new #define gst_vaapi_video_converter_glx_new \ - gst_vaapi_surface_create_converter_glx + gst_vaapi_surface_create_converter_glx #endif static GstSurfaceConverter * -gst_vaapi_surface_create_converter(GstSurfaceMeta *base_meta, - const gchar *type, GValue *dest) +gst_vaapi_surface_create_converter (GstSurfaceMeta * base_meta, + const gchar * type, GValue * dest) { - GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta); - GstVaapiVideoMeta * const vmeta = - gst_buffer_get_vaapi_video_meta(meta->buffer); - GstSurfaceConverterCreateFunc func; + GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta); + GstVaapiVideoMeta *const vmeta = + gst_buffer_get_vaapi_video_meta (meta->buffer); + GstSurfaceConverterCreateFunc func; - if (G_UNLIKELY(!vmeta)) - return NULL; + if (G_UNLIKELY (!vmeta)) + return NULL; - func = (GstSurfaceConverterCreateFunc) - gst_vaapi_video_meta_get_surface_converter(vmeta); + func = (GstSurfaceConverterCreateFunc) + gst_vaapi_video_meta_get_surface_converter (vmeta); - return func ? func(base_meta, type, dest) : NULL; + return func ? func (base_meta, type, dest) : NULL; } static gboolean -gst_vaapi_surface_meta_init(GstVaapiSurfaceMeta *meta, gpointer params, - GstBuffer *buffer) +gst_vaapi_surface_meta_init (GstVaapiSurfaceMeta * meta, gpointer params, + GstBuffer * buffer) { - meta->base.create_converter = gst_vaapi_surface_create_converter; - meta->buffer = buffer; - return TRUE; + meta->base.create_converter = gst_vaapi_surface_create_converter; + meta->buffer = buffer; + return TRUE; } static void -gst_vaapi_surface_meta_free(GstVaapiSurfaceMeta *meta, GstBuffer *buffer) +gst_vaapi_surface_meta_free (GstVaapiSurfaceMeta * meta, GstBuffer * buffer) { } static gboolean -gst_vaapi_surface_meta_transform(GstBuffer *dst_buffer, GstMeta *meta, - GstBuffer *src_buffer, GQuark type, gpointer data) +gst_vaapi_surface_meta_transform (GstBuffer * dst_buffer, GstMeta * meta, + GstBuffer * src_buffer, GQuark type, gpointer data) { - GstVaapiVideoMeta * const src_vmeta = - gst_buffer_get_vaapi_video_meta(src_buffer); + GstVaapiVideoMeta *const src_vmeta = + gst_buffer_get_vaapi_video_meta (src_buffer); - if (GST_META_TRANSFORM_IS_COPY(type)) { - GstVaapiSurfaceMeta * const dst_smeta = GST_VAAPI_SURFACE_META_CAST( - gst_buffer_add_meta(dst_buffer, GST_VAAPI_SURFACE_META_INFO, NULL)); + if (GST_META_TRANSFORM_IS_COPY (type)) { + GstVaapiSurfaceMeta *const dst_smeta = + GST_VAAPI_SURFACE_META_CAST (gst_buffer_add_meta (dst_buffer, + GST_VAAPI_SURFACE_META_INFO, NULL)); - /* Note: avoid meta lookups in gst_vaapi_surface_create_converter() - by directly calling the GstVaapiVideoMeta::surface_converter hook */ - dst_smeta->base.create_converter = (GstSurfaceConverterCreateFunc) - gst_vaapi_video_meta_get_surface_converter(src_vmeta); - return TRUE; - } - return FALSE; + /* Note: avoid meta lookups in gst_vaapi_surface_create_converter() + by directly calling the GstVaapiVideoMeta::surface_converter hook */ + dst_smeta->base.create_converter = (GstSurfaceConverterCreateFunc) + gst_vaapi_video_meta_get_surface_converter (src_vmeta); + return TRUE; + } + return FALSE; } const GstMetaInfo * -gst_vaapi_surface_meta_get_info(void) +gst_vaapi_surface_meta_get_info (void) { - static gsize g_meta_info; + static gsize g_meta_info; - if (g_once_init_enter(&g_meta_info)) { - gsize meta_info = GPOINTER_TO_SIZE(gst_meta_register( - GST_SURFACE_META_API_TYPE, - "GstVaapiSurfaceMeta", sizeof(GstVaapiSurfaceMeta), - (GstMetaInitFunction)gst_vaapi_surface_meta_init, - (GstMetaFreeFunction)gst_vaapi_surface_meta_free, - (GstMetaTransformFunction)gst_vaapi_surface_meta_transform)); - g_once_init_leave(&g_meta_info, meta_info); - } - return GSIZE_TO_POINTER(g_meta_info); + if (g_once_init_enter (&g_meta_info)) { + gsize meta_info = + GPOINTER_TO_SIZE (gst_meta_register (GST_SURFACE_META_API_TYPE, + "GstVaapiSurfaceMeta", sizeof (GstVaapiSurfaceMeta), + (GstMetaInitFunction) gst_vaapi_surface_meta_init, + (GstMetaFreeFunction) gst_vaapi_surface_meta_free, + (GstMetaTransformFunction) gst_vaapi_surface_meta_transform)); + g_once_init_leave (&g_meta_info, meta_info); + } + return GSIZE_TO_POINTER (g_meta_info); } static GstBuffer * -gst_surface_buffer_new(void) +gst_surface_buffer_new (void) { - GstBuffer * const buffer = gst_buffer_new(); + GstBuffer *const buffer = gst_buffer_new (); - if (buffer) - gst_buffer_add_meta(buffer, GST_VAAPI_SURFACE_META_INFO, NULL); - return buffer; + if (buffer) + gst_buffer_add_meta (buffer, GST_VAAPI_SURFACE_META_INFO, NULL); + return buffer; } #else #include #define GST_VAAPI_TYPE_VIDEO_BUFFER \ - (gst_vaapi_video_buffer_get_type()) - -#define GST_VAAPI_VIDEO_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_VIDEO_BUFFER, \ - GstVaapiVideoBuffer)) - -#define GST_VAAPI_VIDEO_BUFFER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_VIDEO_BUFFER, \ - GstVaapiVideoBufferClass)) - + (gst_vaapi_video_buffer_get_type ()) +#define GST_VAAPI_VIDEO_BUFFER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER, \ + GstVaapiVideoBuffer)) +#define GST_VAAPI_VIDEO_BUFFER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_BUFFER, \ + GstVaapiVideoBufferClass)) #define GST_VAAPI_IS_VIDEO_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_BUFFER)) - + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER)) #define GST_VAAPI_IS_VIDEO_BUFFER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_BUFFER)) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_BUFFER)) +#define GST_VAAPI_VIDEO_BUFFER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER, \ + GstVaapiVideoBufferClass)) -#define GST_VAAPI_VIDEO_BUFFER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_VIDEO_BUFFER, \ - GstVaapiVideoBufferClass)) - -typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass; +typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass; /** * GstVaapiVideoBuffer: * * A #GstBuffer holding video objects (#GstVaapiSurface and #GstVaapiImage). */ -struct _GstVaapiVideoBuffer { - /*< private >*/ - GstSurfaceBuffer parent_instance; +struct _GstVaapiVideoBuffer +{ + /*< private >*/ + GstSurfaceBuffer parent_instance; }; /** @@ -213,134 +210,134 @@ struct _GstVaapiVideoBuffer { * * A #GstBuffer holding video objects */ -struct _GstVaapiVideoBufferClass { - /*< private >*/ - GstSurfaceBufferClass parent_class; +struct _GstVaapiVideoBufferClass +{ + /*< private >*/ + GstSurfaceBufferClass parent_class; }; GType -gst_vaapi_video_buffer_get_type(void) G_GNUC_CONST; +gst_vaapi_video_buffer_get_type (void) G_GNUC_CONST; -G_DEFINE_TYPE(GstVaapiVideoBuffer, - gst_vaapi_video_buffer, - GST_TYPE_SURFACE_BUFFER) +G_DEFINE_TYPE (GstVaapiVideoBuffer, + gst_vaapi_video_buffer, GST_TYPE_SURFACE_BUFFER); -typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc)( - GstSurfaceBuffer *surface, const gchar *type, GValue *dest); +typedef GstSurfaceConverter * +(*GstSurfaceConverterCreateFunc) (GstSurfaceBuffer * surface, + const gchar * type, GValue * dest); static GstSurfaceConverter * -gst_vaapi_video_buffer_create_converter(GstSurfaceBuffer *surface, - const gchar *type, GValue *dest) +gst_vaapi_video_buffer_create_converter (GstSurfaceBuffer * surface, + const gchar * type, GValue * dest) { - GstVaapiVideoMeta * const meta = - gst_buffer_get_vaapi_video_meta(GST_BUFFER(surface)); - GstSurfaceConverterCreateFunc func; + GstVaapiVideoMeta *const meta = + gst_buffer_get_vaapi_video_meta (GST_BUFFER (surface)); + GstSurfaceConverterCreateFunc func; - g_return_val_if_fail(meta != NULL, NULL); + g_return_val_if_fail (meta != NULL, NULL); - func = (GstSurfaceConverterCreateFunc) - gst_vaapi_video_meta_get_surface_converter(meta); + func = (GstSurfaceConverterCreateFunc) + gst_vaapi_video_meta_get_surface_converter (meta); - return func ? func(surface, type, dest) : NULL; + return func ? func (surface, type, dest) : NULL; } static void -gst_vaapi_video_buffer_class_init(GstVaapiVideoBufferClass *klass) +gst_vaapi_video_buffer_class_init (GstVaapiVideoBufferClass * klass) { - GstSurfaceBufferClass * const surface_class = - GST_SURFACE_BUFFER_CLASS(klass); + GstSurfaceBufferClass *const surface_class = GST_SURFACE_BUFFER_CLASS (klass); - surface_class->create_converter = gst_vaapi_video_buffer_create_converter; + surface_class->create_converter = gst_vaapi_video_buffer_create_converter; } static void -gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer) +gst_vaapi_video_buffer_init (GstVaapiVideoBuffer * buffer) { } static inline GstBuffer * -gst_surface_buffer_new(void) +gst_surface_buffer_new (void) { - return GST_BUFFER_CAST(gst_mini_object_new(GST_VAAPI_TYPE_VIDEO_BUFFER)); + return GST_BUFFER_CAST (gst_mini_object_new (GST_VAAPI_TYPE_VIDEO_BUFFER)); } #endif static GFunc -get_surface_converter(GstVaapiDisplay *display) +get_surface_converter (GstVaapiDisplay * display) { - GFunc func; + GFunc func; - switch (gst_vaapi_display_get_display_type(display)) { + switch (gst_vaapi_display_get_display_type (display)) { #if USE_X11 && !GST_CHECK_VERSION(1,1,0) case GST_VAAPI_DISPLAY_TYPE_X11: - func = (GFunc)gst_vaapi_video_converter_x11_new; - break; + func = (GFunc) gst_vaapi_video_converter_x11_new; + break; #endif #if USE_GLX && !GST_CHECK_VERSION(1,1,0) case GST_VAAPI_DISPLAY_TYPE_GLX: - func = (GFunc)gst_vaapi_video_converter_glx_new; - break; + func = (GFunc) gst_vaapi_video_converter_glx_new; + break; #endif default: - func = NULL; - break; - } - return func; + func = NULL; + break; + } + return func; } static GstBuffer * -new_vbuffer(GstVaapiVideoMeta *meta) +new_vbuffer (GstVaapiVideoMeta * meta) { - GstBuffer *buffer; + GstBuffer *buffer; - g_return_val_if_fail(meta != NULL, NULL); + g_return_val_if_fail (meta != NULL, NULL); - gst_vaapi_video_meta_set_surface_converter(meta, - get_surface_converter(gst_vaapi_video_meta_get_display(meta))); + gst_vaapi_video_meta_set_surface_converter (meta, + get_surface_converter (gst_vaapi_video_meta_get_display (meta))); - buffer = gst_surface_buffer_new(); - if (buffer) - gst_buffer_set_vaapi_video_meta(buffer, meta); - gst_vaapi_video_meta_unref(meta); - return buffer; + buffer = gst_surface_buffer_new (); + if (buffer) + gst_buffer_set_vaapi_video_meta (buffer, meta); + gst_vaapi_video_meta_unref (meta); + return buffer; } GstBuffer * -gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta) +gst_vaapi_video_buffer_new (GstVaapiVideoMeta * meta) { - g_return_val_if_fail(meta != NULL, NULL); + g_return_val_if_fail (meta != NULL, NULL); - return new_vbuffer(gst_vaapi_video_meta_ref(meta)); + return new_vbuffer (gst_vaapi_video_meta_ref (meta)); } GstBuffer * -gst_vaapi_video_buffer_new_empty(void) +gst_vaapi_video_buffer_new_empty (void) { - return gst_surface_buffer_new(); + return gst_surface_buffer_new (); } GstBuffer * -gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool) +gst_vaapi_video_buffer_new_from_pool (GstVaapiVideoPool * pool) { - return new_vbuffer(gst_vaapi_video_meta_new_from_pool(pool)); + return new_vbuffer (gst_vaapi_video_meta_new_from_pool (pool)); } GstBuffer * -gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer) +gst_vaapi_video_buffer_new_from_buffer (GstBuffer * buffer) { - GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); + GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); - return meta ? new_vbuffer(gst_vaapi_video_meta_ref(meta)) : NULL; + return meta ? new_vbuffer (gst_vaapi_video_meta_ref (meta)) : NULL; } GstBuffer * -gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image) +gst_vaapi_video_buffer_new_with_image (GstVaapiImage * image) { - return new_vbuffer(gst_vaapi_video_meta_new_with_image(image)); + return new_vbuffer (gst_vaapi_video_meta_new_with_image (image)); } GstBuffer * -gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) +gst_vaapi_video_buffer_new_with_surface_proxy (GstVaapiSurfaceProxy * proxy) { - return new_vbuffer(gst_vaapi_video_meta_new_with_surface_proxy(proxy)); + return new_vbuffer (gst_vaapi_video_meta_new_with_surface_proxy (proxy)); } diff --git a/gst/vaapi/gstvaapivideobuffer.h b/gst/vaapi/gstvaapivideobuffer.h index e22b6e0135..f751bc3e6e 100644 --- a/gst/vaapi/gstvaapivideobuffer.h +++ b/gst/vaapi/gstvaapivideobuffer.h @@ -29,31 +29,31 @@ G_BEGIN_DECLS -typedef struct _GstVaapiVideoBuffer GstVaapiVideoBuffer; +typedef struct _GstVaapiVideoBuffer GstVaapiVideoBuffer; G_GNUC_INTERNAL GstBuffer * -gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta); +gst_vaapi_video_buffer_new (GstVaapiVideoMeta * meta); G_GNUC_INTERNAL GstBuffer * -gst_vaapi_video_buffer_new_empty(void); +gst_vaapi_video_buffer_new_empty (void); G_GNUC_INTERNAL GstBuffer * -gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool); +gst_vaapi_video_buffer_new_from_pool (GstVaapiVideoPool * pool); G_GNUC_INTERNAL GstBuffer * -gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer); +gst_vaapi_video_buffer_new_from_buffer (GstBuffer * buffer); G_GNUC_INTERNAL GstBuffer * -gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image); +gst_vaapi_video_buffer_new_with_image (GstVaapiImage * image); G_GNUC_INTERNAL GstBuffer * -gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); +gst_vaapi_video_buffer_new_with_surface_proxy (GstVaapiSurfaceProxy * proxy); G_END_DECLS diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index fe5c2a3b38..6e08ce1013 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -28,317 +28,319 @@ #include "gstvaapivideometa_texture.h" #endif -GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideopool); +GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapivideopool); #define GST_CAT_DEFAULT gst_debug_vaapivideopool -G_DEFINE_TYPE(GstVaapiVideoBufferPool, - gst_vaapi_video_buffer_pool, - GST_TYPE_BUFFER_POOL) +G_DEFINE_TYPE (GstVaapiVideoBufferPool, + gst_vaapi_video_buffer_pool, GST_TYPE_BUFFER_POOL); -enum { - PROP_0, +enum +{ + PROP_0, - PROP_DISPLAY, + PROP_DISPLAY, }; -struct _GstVaapiVideoBufferPoolPrivate { - GstVideoInfo video_info[2]; - guint video_info_index; - GstAllocator *allocator; - GstVaapiDisplay *display; - guint has_video_meta : 1; - guint has_video_alignment : 1; - guint has_texture_upload_meta : 1; +struct _GstVaapiVideoBufferPoolPrivate +{ + GstVideoInfo video_info[2]; + guint video_info_index; + GstAllocator *allocator; + GstVaapiDisplay *display; + guint has_video_meta:1; + guint has_video_alignment:1; + guint has_texture_upload_meta:1; }; -#define GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, \ - GstVaapiVideoBufferPoolPrivate)) +#define GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, \ + GstVaapiVideoBufferPoolPrivate)) static void -gst_vaapi_video_buffer_pool_finalize(GObject *object) +gst_vaapi_video_buffer_pool_finalize (GObject * object) { - GstVaapiVideoBufferPoolPrivate * const priv = - GST_VAAPI_VIDEO_BUFFER_POOL(object)->priv; + GstVaapiVideoBufferPoolPrivate *const priv = + GST_VAAPI_VIDEO_BUFFER_POOL (object)->priv; - G_OBJECT_CLASS(gst_vaapi_video_buffer_pool_parent_class)->finalize(object); + G_OBJECT_CLASS (gst_vaapi_video_buffer_pool_parent_class)->finalize (object); - gst_vaapi_display_replace(&priv->display, NULL); - g_clear_object(&priv->allocator); + gst_vaapi_display_replace (&priv->display, NULL); + g_clear_object (&priv->allocator); } static void -gst_vaapi_video_buffer_pool_set_property(GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +gst_vaapi_video_buffer_pool_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) { - GstVaapiVideoBufferPoolPrivate * const priv = - GST_VAAPI_VIDEO_BUFFER_POOL(object)->priv; + GstVaapiVideoBufferPoolPrivate *const priv = + GST_VAAPI_VIDEO_BUFFER_POOL (object)->priv; - switch (prop_id) { + switch (prop_id) { case PROP_DISPLAY: - priv->display = gst_vaapi_display_ref(g_value_get_pointer(value)); - break; + priv->display = gst_vaapi_display_ref (g_value_get_pointer (value)); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -gst_vaapi_video_buffer_pool_get_property(GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +gst_vaapi_video_buffer_pool_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) { - GstVaapiVideoBufferPoolPrivate * const priv = - GST_VAAPI_VIDEO_BUFFER_POOL(object)->priv; + GstVaapiVideoBufferPoolPrivate *const priv = + GST_VAAPI_VIDEO_BUFFER_POOL (object)->priv; - switch (prop_id) { + switch (prop_id) { case PROP_DISPLAY: - g_value_set_pointer(value, priv->display); - break; + g_value_set_pointer (value, priv->display); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -fill_video_alignment(GstVaapiVideoBufferPool *pool, GstVideoAlignment *align) +fill_video_alignment (GstVaapiVideoBufferPool * pool, GstVideoAlignment * align) { - GstVideoInfo * const vip = - &GST_VAAPI_VIDEO_ALLOCATOR_CAST(pool->priv->allocator)->image_info; - guint i; + GstVideoInfo *const vip = + &GST_VAAPI_VIDEO_ALLOCATOR_CAST (pool->priv->allocator)->image_info; + guint i; - gst_video_alignment_reset(align); - for (i = 0; i < GST_VIDEO_INFO_N_PLANES(vip); i++) - align->stride_align[i] = - (1U << g_bit_nth_lsf(GST_VIDEO_INFO_PLANE_STRIDE(vip, i), 0)) - 1; + gst_video_alignment_reset (align); + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (vip); i++) + align->stride_align[i] = + (1U << g_bit_nth_lsf (GST_VIDEO_INFO_PLANE_STRIDE (vip, i), 0)) - 1; } static const gchar ** -gst_vaapi_video_buffer_pool_get_options(GstBufferPool *pool) +gst_vaapi_video_buffer_pool_get_options (GstBufferPool * pool) { - static const gchar *g_options[] = { - GST_BUFFER_POOL_OPTION_VIDEO_META, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META, - GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT, - NULL, - }; - return g_options; + static const gchar *g_options[] = { + GST_BUFFER_POOL_OPTION_VIDEO_META, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT, + NULL, + }; + + return g_options; } static gboolean -gst_vaapi_video_buffer_pool_set_config(GstBufferPool *pool, - GstStructure *config) +gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, + GstStructure * config) { - GstVaapiVideoBufferPoolPrivate * const priv = - GST_VAAPI_VIDEO_BUFFER_POOL(pool)->priv; - GstCaps *caps = NULL; - GstVideoInfo * const cur_vip = &priv->video_info[priv->video_info_index]; - GstVideoInfo * const new_vip = &priv->video_info[!priv->video_info_index]; - GstVideoAlignment align; - GstAllocator *allocator; - gboolean changed_caps; + GstVaapiVideoBufferPoolPrivate *const priv = + GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv; + GstCaps *caps = NULL; + GstVideoInfo *const cur_vip = &priv->video_info[priv->video_info_index]; + GstVideoInfo *const new_vip = &priv->video_info[!priv->video_info_index]; + GstVideoAlignment align; + GstAllocator *allocator; + gboolean changed_caps; - if (!gst_buffer_pool_config_get_params(config, &caps, NULL, NULL, NULL)) - goto error_invalid_config; - if (!caps || !gst_video_info_from_caps(new_vip, caps)) - goto error_no_caps; + if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) + goto error_invalid_config; + if (!caps || !gst_video_info_from_caps (new_vip, caps)) + goto error_no_caps; - changed_caps = !priv->allocator || - GST_VIDEO_INFO_FORMAT(cur_vip) != GST_VIDEO_INFO_FORMAT(new_vip) || - GST_VIDEO_INFO_WIDTH(cur_vip) != GST_VIDEO_INFO_WIDTH(new_vip) || - GST_VIDEO_INFO_HEIGHT(cur_vip) != GST_VIDEO_INFO_HEIGHT(new_vip); + changed_caps = !priv->allocator || + GST_VIDEO_INFO_FORMAT (cur_vip) != GST_VIDEO_INFO_FORMAT (new_vip) || + GST_VIDEO_INFO_WIDTH (cur_vip) != GST_VIDEO_INFO_WIDTH (new_vip) || + GST_VIDEO_INFO_HEIGHT (cur_vip) != GST_VIDEO_INFO_HEIGHT (new_vip); - if (changed_caps) { - allocator = gst_vaapi_video_allocator_new(priv->display, new_vip); - if (!allocator) - goto error_create_allocator; - gst_object_replace((GstObject **)&priv->allocator, - GST_OBJECT_CAST(allocator)); - gst_object_unref(allocator); - priv->video_info_index ^= 1; - } + if (changed_caps) { + allocator = gst_vaapi_video_allocator_new (priv->display, new_vip); + if (!allocator) + goto error_create_allocator; + gst_object_replace ((GstObject **) & priv->allocator, + GST_OBJECT_CAST (allocator)); + gst_object_unref (allocator); + priv->video_info_index ^= 1; + } - if (!gst_buffer_pool_config_has_option(config, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) - goto error_no_vaapi_video_meta_option; + if (!gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) + goto error_no_vaapi_video_meta_option; - priv->has_video_meta = gst_buffer_pool_config_has_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_META); + priv->has_video_meta = gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); - priv->has_video_alignment = gst_buffer_pool_config_has_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); - if (priv->has_video_alignment) { - fill_video_alignment(GST_VAAPI_VIDEO_BUFFER_POOL(pool), &align); - gst_buffer_pool_config_set_video_alignment(config, &align); - } + priv->has_video_alignment = gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + if (priv->has_video_alignment) { + fill_video_alignment (GST_VAAPI_VIDEO_BUFFER_POOL (pool), &align); + gst_buffer_pool_config_set_video_alignment (config, &align); + } - priv->has_texture_upload_meta = gst_buffer_pool_config_has_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); + priv->has_texture_upload_meta = gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); - return GST_BUFFER_POOL_CLASS(gst_vaapi_video_buffer_pool_parent_class)-> - set_config(pool, config); + return + GST_BUFFER_POOL_CLASS + (gst_vaapi_video_buffer_pool_parent_class)->set_config (pool, config); - /* ERRORS */ + /* ERRORS */ error_invalid_config: - { - GST_ERROR("invalid config"); - return FALSE; - } + { + GST_ERROR ("invalid config"); + return FALSE; + } error_no_caps: - { - GST_ERROR("no valid caps in config"); - return FALSE; - } + { + GST_ERROR ("no valid caps in config"); + return FALSE; + } error_create_allocator: - { - GST_ERROR("failed to create GstVaapiVideoAllocator object"); - return FALSE; - } + { + GST_ERROR ("failed to create GstVaapiVideoAllocator object"); + return FALSE; + } error_no_vaapi_video_meta_option: - { - GST_ERROR("no GstVaapiVideoMeta option"); - return FALSE; - } + { + GST_ERROR ("no GstVaapiVideoMeta option"); + return FALSE; + } } static GstFlowReturn -gst_vaapi_video_buffer_pool_alloc_buffer(GstBufferPool *pool, - GstBuffer **out_buffer_ptr, GstBufferPoolAcquireParams *params) +gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, + GstBuffer ** out_buffer_ptr, GstBufferPoolAcquireParams * params) { - GstVaapiVideoBufferPoolPrivate * const priv = - GST_VAAPI_VIDEO_BUFFER_POOL(pool)->priv; - GstVaapiVideoMeta *meta; - GstMemory *mem; - GstBuffer *buffer; + GstVaapiVideoBufferPoolPrivate *const priv = + GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv; + GstVaapiVideoMeta *meta; + GstMemory *mem; + GstBuffer *buffer; - if (!priv->allocator) - goto error_no_allocator; + if (!priv->allocator) + goto error_no_allocator; - meta = gst_vaapi_video_meta_new(priv->display); - if (!meta) - goto error_create_meta; + meta = gst_vaapi_video_meta_new (priv->display); + if (!meta) + goto error_create_meta; - buffer = gst_vaapi_video_buffer_new(meta); - if (!buffer) - goto error_create_buffer; + buffer = gst_vaapi_video_buffer_new (meta); + if (!buffer) + goto error_create_buffer; - mem = gst_vaapi_video_memory_new(priv->allocator, meta); - if (!mem) - goto error_create_memory; - gst_vaapi_video_meta_unref(meta); - gst_buffer_append_memory(buffer, mem); + mem = gst_vaapi_video_memory_new (priv->allocator, meta); + if (!mem) + goto error_create_memory; + gst_vaapi_video_meta_unref (meta); + gst_buffer_append_memory (buffer, mem); - if (priv->has_video_meta) { - GstVideoInfo * const vip = - &GST_VAAPI_VIDEO_ALLOCATOR_CAST(priv->allocator)->image_info; - GstVideoMeta *vmeta; - - vmeta = gst_buffer_add_video_meta_full(buffer, 0, - GST_VIDEO_INFO_FORMAT(vip), GST_VIDEO_INFO_WIDTH(vip), - GST_VIDEO_INFO_HEIGHT(vip), GST_VIDEO_INFO_N_PLANES(vip), - &GST_VIDEO_INFO_PLANE_OFFSET(vip, 0), - &GST_VIDEO_INFO_PLANE_STRIDE(vip, 0)); - vmeta->map = gst_video_meta_map_vaapi_memory; - vmeta->unmap = gst_video_meta_unmap_vaapi_memory; - } + if (priv->has_video_meta) { + GstVideoInfo *const vip = + &GST_VAAPI_VIDEO_ALLOCATOR_CAST (priv->allocator)->image_info; + GstVideoMeta *vmeta; + vmeta = gst_buffer_add_video_meta_full (buffer, 0, + GST_VIDEO_INFO_FORMAT (vip), GST_VIDEO_INFO_WIDTH (vip), + GST_VIDEO_INFO_HEIGHT (vip), GST_VIDEO_INFO_N_PLANES (vip), + &GST_VIDEO_INFO_PLANE_OFFSET (vip, 0), + &GST_VIDEO_INFO_PLANE_STRIDE (vip, 0)); + vmeta->map = gst_video_meta_map_vaapi_memory; + vmeta->unmap = gst_video_meta_unmap_vaapi_memory; + } #if GST_CHECK_VERSION(1,1,0) && USE_GLX - if (priv->has_texture_upload_meta) - gst_buffer_add_texture_upload_meta(buffer); + if (priv->has_texture_upload_meta) + gst_buffer_add_texture_upload_meta (buffer); #endif - *out_buffer_ptr = buffer; - return GST_FLOW_OK; + *out_buffer_ptr = buffer; + return GST_FLOW_OK; - /* ERRORS */ + /* ERRORS */ error_no_allocator: - { - GST_ERROR("no GstAllocator in buffer pool"); - return GST_FLOW_ERROR; - } + { + GST_ERROR ("no GstAllocator in buffer pool"); + return GST_FLOW_ERROR; + } error_create_meta: - { - GST_ERROR("failed to allocate vaapi video meta"); - return GST_FLOW_ERROR; - } + { + GST_ERROR ("failed to allocate vaapi video meta"); + return GST_FLOW_ERROR; + } error_create_buffer: - { - GST_ERROR("failed to create video buffer"); - gst_vaapi_video_meta_unref(meta); - return GST_FLOW_ERROR; - } + { + GST_ERROR ("failed to create video buffer"); + gst_vaapi_video_meta_unref (meta); + return GST_FLOW_ERROR; + } error_create_memory: - { - GST_ERROR("failed to create video memory"); - gst_buffer_unref(buffer); - gst_vaapi_video_meta_unref(meta); - return GST_FLOW_ERROR; - } + { + GST_ERROR ("failed to create video memory"); + gst_buffer_unref (buffer); + gst_vaapi_video_meta_unref (meta); + return GST_FLOW_ERROR; + } } static void -gst_vaapi_video_buffer_pool_reset_buffer(GstBufferPool *pool, GstBuffer *buffer) +gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool, + GstBuffer * buffer) { - GstMemory * const mem = gst_buffer_peek_memory(buffer, 0); + GstMemory *const mem = gst_buffer_peek_memory (buffer, 0); - /* Release the underlying surface proxy */ - gst_vaapi_video_memory_reset_surface(GST_VAAPI_VIDEO_MEMORY_CAST(mem)); + /* Release the underlying surface proxy */ + gst_vaapi_video_memory_reset_surface (GST_VAAPI_VIDEO_MEMORY_CAST (mem)); - GST_BUFFER_POOL_CLASS(gst_vaapi_video_buffer_pool_parent_class)-> - reset_buffer(pool, buffer); + GST_BUFFER_POOL_CLASS (gst_vaapi_video_buffer_pool_parent_class)->reset_buffer + (pool, buffer); } static void -gst_vaapi_video_buffer_pool_class_init(GstVaapiVideoBufferPoolClass *klass) +gst_vaapi_video_buffer_pool_class_init (GstVaapiVideoBufferPoolClass * klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstBufferPoolClass * const pool_class = GST_BUFFER_POOL_CLASS(klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstBufferPoolClass *const pool_class = GST_BUFFER_POOL_CLASS (klass); - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapivideopool, - "vaapivideopool", 0, "VA-API video pool"); + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapivideopool, + "vaapivideopool", 0, "VA-API video pool"); - g_type_class_add_private(klass, sizeof(GstVaapiVideoBufferPoolPrivate)); + g_type_class_add_private (klass, sizeof (GstVaapiVideoBufferPoolPrivate)); - object_class->finalize = gst_vaapi_video_buffer_pool_finalize; - object_class->set_property = gst_vaapi_video_buffer_pool_set_property; - object_class->get_property = gst_vaapi_video_buffer_pool_get_property; - pool_class->get_options = gst_vaapi_video_buffer_pool_get_options; - pool_class->set_config = gst_vaapi_video_buffer_pool_set_config; - pool_class->alloc_buffer = gst_vaapi_video_buffer_pool_alloc_buffer; - pool_class->reset_buffer = gst_vaapi_video_buffer_pool_reset_buffer; + object_class->finalize = gst_vaapi_video_buffer_pool_finalize; + object_class->set_property = gst_vaapi_video_buffer_pool_set_property; + object_class->get_property = gst_vaapi_video_buffer_pool_get_property; + pool_class->get_options = gst_vaapi_video_buffer_pool_get_options; + pool_class->set_config = gst_vaapi_video_buffer_pool_set_config; + pool_class->alloc_buffer = gst_vaapi_video_buffer_pool_alloc_buffer; + pool_class->reset_buffer = gst_vaapi_video_buffer_pool_reset_buffer; - /** - * GstVaapiVideoBufferPool:display: - * - * The #GstVaapiDisplay this object is bound to. - */ - g_object_class_install_property - (object_class, - PROP_DISPLAY, - g_param_spec_pointer("display", - "Display", - "The GstVaapiDisplay to use for this video pool", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + /** + * GstVaapiVideoBufferPool:display: + * + * The #GstVaapiDisplay this object is bound to. + */ + g_object_class_install_property + (object_class, + PROP_DISPLAY, + g_param_spec_pointer ("display", + "Display", + "The GstVaapiDisplay to use for this video pool", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void -gst_vaapi_video_buffer_pool_init(GstVaapiVideoBufferPool *pool) +gst_vaapi_video_buffer_pool_init (GstVaapiVideoBufferPool * pool) { - GstVaapiVideoBufferPoolPrivate * const priv = - GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(pool); + GstVaapiVideoBufferPoolPrivate *const priv = + GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE (pool); - pool->priv = priv; + pool->priv = priv; - gst_video_info_init(&priv->video_info[0]); - gst_video_info_init(&priv->video_info[1]); + gst_video_info_init (&priv->video_info[0]); + gst_video_info_init (&priv->video_info[1]); } GstBufferPool * -gst_vaapi_video_buffer_pool_new(GstVaapiDisplay *display) +gst_vaapi_video_buffer_pool_new (GstVaapiDisplay * display) { - return g_object_new(GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, - "display", display, NULL); + return g_object_new (GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, + "display", display, NULL); } diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index ed646c287a..ed8e1c7e07 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -29,27 +29,21 @@ G_BEGIN_DECLS #define GST_VAAPI_TYPE_VIDEO_BUFFER_POOL \ - (gst_vaapi_video_buffer_pool_get_type()) - -#define GST_VAAPI_VIDEO_BUFFER_POOL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, \ - GstVaapiVideoBufferPool)) - -#define GST_VAAPI_VIDEO_BUFFER_POOL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, \ - GstVaapiVideoBufferPoolClass)) - + (gst_vaapi_video_buffer_pool_get_type ()) +#define GST_VAAPI_VIDEO_BUFFER_POOL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, \ + GstVaapiVideoBufferPool)) +#define GST_VAAPI_VIDEO_BUFFER_POOL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, \ + GstVaapiVideoBufferPoolClass)) #define GST_VAAPI_IS_VIDEO_BUFFER_POOL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_BUFFER_POOL)) - + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER_POOL)) #define GST_VAAPI_IS_VIDEO_BUFFER_POOL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_BUFFER_POOL)) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_BUFFER_POOL)) -typedef struct _GstVaapiVideoBufferPool GstVaapiVideoBufferPool; -typedef struct _GstVaapiVideoBufferPoolClass GstVaapiVideoBufferPoolClass; -typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; +typedef struct _GstVaapiVideoBufferPool GstVaapiVideoBufferPool; +typedef struct _GstVaapiVideoBufferPoolClass GstVaapiVideoBufferPoolClass; +typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; /** * GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META: @@ -57,7 +51,8 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; * An option that can be activated on bufferpool to request vaapi * video metadata on buffers from the pool. */ -#define GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META "GstBufferPoolOptionVaapiVideoMeta" +#define GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META \ + "GstBufferPoolOptionVaapiVideoMeta" /** * @@ -71,7 +66,7 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; */ #ifndef GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META #define GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META \ - "GstBufferPoolOptionVideoGLTextureUploadMeta" + "GstBufferPoolOptionVideoGLTextureUploadMeta" #endif /** @@ -79,11 +74,12 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; * * A VA video buffer pool object. */ -struct _GstVaapiVideoBufferPool { - GstBufferPool parent_instance; +struct _GstVaapiVideoBufferPool +{ + GstBufferPool parent_instance; - /*< private >*/ - GstVaapiVideoBufferPoolPrivate *priv; + /*< private >*/ + GstVaapiVideoBufferPoolPrivate *priv; }; /** @@ -91,17 +87,18 @@ struct _GstVaapiVideoBufferPool { * * A VA video buffer pool class. */ -struct _GstVaapiVideoBufferPoolClass { - GstBufferPoolClass parent_class; +struct _GstVaapiVideoBufferPoolClass +{ + GstBufferPoolClass parent_class; }; G_GNUC_INTERNAL GType -gst_vaapi_video_buffer_pool_get_type(void) G_GNUC_CONST; +gst_vaapi_video_buffer_pool_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstBufferPool * -gst_vaapi_video_buffer_pool_new(GstVaapiDisplay *display) G_GNUC_CONST; +gst_vaapi_video_buffer_pool_new (GstVaapiDisplay * display) G_GNUC_CONST; G_END_DECLS diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index fe475a9e0a..54645c325f 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -31,18 +31,18 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); #define GST_VAAPI_TYPE_DISPLAY \ - gst_vaapi_display_get_type() + gst_vaapi_display_get_type () GType -gst_vaapi_display_get_type (void) - G_GNUC_CONST; +gst_vaapi_display_get_type (void) G_GNUC_CONST; G_DEFINE_BOXED_TYPE (GstVaapiDisplay, gst_vaapi_display, (GBoxedCopyFunc) gst_vaapi_display_ref, - (GBoxedFreeFunc) gst_vaapi_display_unref) + (GBoxedFreeFunc) gst_vaapi_display_unref); - GstContext *gst_vaapi_video_context_new_with_display (GstVaapiDisplay * - display, gboolean persistent) +GstContext * +gst_vaapi_video_context_new_with_display (GstVaapiDisplay * display, + gboolean persistent) { GstContext *context; GstStructure *structure; diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index fd5cf6b5ef..47de0e0f23 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -34,8 +34,8 @@ #define GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME "gst.vaapi.Display" /* Fake GstVideoContext symbols */ -#define GST_VIDEO_CONTEXT(obj) (GST_ELEMENT(obj)) -#define GST_IS_VIDEO_CONTEXT(obj) (GST_IS_ELEMENT(obj)) +#define GST_VIDEO_CONTEXT(obj) (GST_ELEMENT (obj)) +#define GST_IS_VIDEO_CONTEXT(obj) (GST_IS_ELEMENT (obj)) #define GstVideoContext GstElement #define gst_video_context_prepare gst_vaapi_video_context_prepare diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index 9aaaf368a1..162bf6fcf5 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -30,68 +30,68 @@ #include "gstvaapivideometa.h" #if GST_CHECK_VERSION(1,0,0) -typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *, +typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *, GstBuffer *); #else -typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *, +typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *, GstSurfaceBuffer *); #endif static void -gst_vaapi_video_converter_glx_iface_init(GstSurfaceConverterInterface *iface); +gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface * iface); -G_DEFINE_TYPE_WITH_CODE( - GstVaapiVideoConverterGLX, +G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoConverterGLX, gst_vaapi_video_converter_glx, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE(GST_TYPE_SURFACE_CONVERTER, - gst_vaapi_video_converter_glx_iface_init)) + G_IMPLEMENT_INTERFACE (GST_TYPE_SURFACE_CONVERTER, + gst_vaapi_video_converter_glx_iface_init)); -#define GST_VAAPI_VIDEO_CONVERTER_GLX_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ - GstVaapiVideoConverterGLXPrivate)) +#define GST_VAAPI_VIDEO_CONVERTER_GLX_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ + GstVaapiVideoConverterGLXPrivate)) -struct _GstVaapiVideoConverterGLXPrivate { - GstVaapiTexture *texture; +struct _GstVaapiVideoConverterGLXPrivate +{ + GstVaapiTexture *texture; }; static gboolean -gst_vaapi_video_converter_glx_upload(GstSurfaceConverter *self, - GstBuffer *buffer); +gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self, + GstBuffer * buffer); static void -gst_vaapi_video_converter_glx_dispose(GObject *object) +gst_vaapi_video_converter_glx_dispose (GObject * object) { - GstVaapiVideoConverterGLXPrivate * const priv = - GST_VAAPI_VIDEO_CONVERTER_GLX(object)->priv; + GstVaapiVideoConverterGLXPrivate *const priv = + GST_VAAPI_VIDEO_CONVERTER_GLX (object)->priv; - gst_vaapi_texture_replace(&priv->texture, NULL); + gst_vaapi_texture_replace (&priv->texture, NULL); - G_OBJECT_CLASS(gst_vaapi_video_converter_glx_parent_class)->dispose(object); + G_OBJECT_CLASS (gst_vaapi_video_converter_glx_parent_class)->dispose (object); } static void -gst_vaapi_video_converter_glx_class_init(GstVaapiVideoConverterGLXClass *klass) +gst_vaapi_video_converter_glx_class_init (GstVaapiVideoConverterGLXClass * + klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); - g_type_class_add_private(klass, sizeof(GstVaapiVideoConverterGLXPrivate)); + g_type_class_add_private (klass, sizeof (GstVaapiVideoConverterGLXPrivate)); - object_class->dispose = gst_vaapi_video_converter_glx_dispose; + object_class->dispose = gst_vaapi_video_converter_glx_dispose; } static void -gst_vaapi_video_converter_glx_init(GstVaapiVideoConverterGLX *buffer) +gst_vaapi_video_converter_glx_init (GstVaapiVideoConverterGLX * buffer) { - buffer->priv = GST_VAAPI_VIDEO_CONVERTER_GLX_GET_PRIVATE(buffer); + buffer->priv = GST_VAAPI_VIDEO_CONVERTER_GLX_GET_PRIVATE (buffer); } static void -gst_vaapi_video_converter_glx_iface_init(GstSurfaceConverterInterface *iface) +gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface * iface) { - iface->upload = (GstSurfaceUploadFunction) - gst_vaapi_video_converter_glx_upload; + iface->upload = (GstSurfaceUploadFunction) + gst_vaapi_video_converter_glx_upload; } /** @@ -107,53 +107,53 @@ gst_vaapi_video_converter_glx_iface_init(GstSurfaceConverterInterface *iface) * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstSurfaceConverter * -gst_vaapi_video_converter_glx_new(GstBuffer *buffer, const gchar *type, - GValue *dest) +gst_vaapi_video_converter_glx_new (GstBuffer * buffer, const gchar * type, + GValue * dest) { - GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); - GstVaapiTexture *texture; - GstVaapiVideoConverterGLX *converter; + GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); + GstVaapiTexture *texture; + GstVaapiVideoConverterGLX *converter; - /* Check for "opengl" request, or chain up to X11 converter */ - if (strcmp(type, "opengl") != 0 || !G_VALUE_HOLDS_UINT(dest)) - return gst_vaapi_video_converter_x11_new(buffer, type, dest); + /* Check for "opengl" request, or chain up to X11 converter */ + if (strcmp (type, "opengl") != 0 || !G_VALUE_HOLDS_UINT (dest)) + return gst_vaapi_video_converter_x11_new (buffer, type, dest); - /* FIXME Should we assume target and format ? */ - texture = gst_vaapi_texture_new_with_texture( - gst_vaapi_video_meta_get_display(meta), - g_value_get_uint(dest), GL_TEXTURE_2D, GL_BGRA); - if (!texture) - return NULL; + /* FIXME Should we assume target and format ? */ + texture = + gst_vaapi_texture_new_with_texture (gst_vaapi_video_meta_get_display + (meta), g_value_get_uint (dest), GL_TEXTURE_2D, GL_BGRA); + if (!texture) + return NULL; - converter = g_object_new(GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, NULL); - converter->priv->texture = texture; - return GST_SURFACE_CONVERTER(converter); + converter = g_object_new (GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, NULL); + converter->priv->texture = texture; + return GST_SURFACE_CONVERTER (converter); } gboolean -gst_vaapi_video_converter_glx_upload(GstSurfaceConverter *self, - GstBuffer *buffer) +gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self, + GstBuffer * buffer) { - GstVaapiVideoConverterGLXPrivate * const priv = - GST_VAAPI_VIDEO_CONVERTER_GLX(self)->priv; - GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); - GstVaapiSurface * const surface = gst_vaapi_video_meta_get_surface(meta); - GstVaapiDisplay *new_dpy, *old_dpy; + GstVaapiVideoConverterGLXPrivate *const priv = + GST_VAAPI_VIDEO_CONVERTER_GLX (self)->priv; + GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); + GstVaapiSurface *const surface = gst_vaapi_video_meta_get_surface (meta); + GstVaapiDisplay *new_dpy, *old_dpy; - new_dpy = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); - old_dpy = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(priv->texture)); + new_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); + old_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (priv->texture)); - if (old_dpy != new_dpy) { - const guint texture = gst_vaapi_texture_get_id(priv->texture); + if (old_dpy != new_dpy) { + const guint texture = gst_vaapi_texture_get_id (priv->texture); - gst_vaapi_texture_replace(&priv->texture, NULL); - priv->texture = gst_vaapi_texture_new_with_texture(new_dpy, - texture, GL_TEXTURE_2D, GL_BGRA); - } + gst_vaapi_texture_replace (&priv->texture, NULL); + priv->texture = gst_vaapi_texture_new_with_texture (new_dpy, + texture, GL_TEXTURE_2D, GL_BGRA); + } - if (!gst_vaapi_apply_composition(surface, buffer)) - GST_WARNING("could not update subtitles"); + if (!gst_vaapi_apply_composition (surface, buffer)) + GST_WARNING ("could not update subtitles"); - return gst_vaapi_texture_put_surface(priv->texture, surface, - gst_vaapi_video_meta_get_render_flags(meta)); + return gst_vaapi_texture_put_surface (priv->texture, surface, + gst_vaapi_video_meta_get_render_flags (meta)); } diff --git a/gst/vaapi/gstvaapivideoconverter_glx.h b/gst/vaapi/gstvaapivideoconverter_glx.h index 991b67ff3e..35ed4df0ae 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.h +++ b/gst/vaapi/gstvaapivideoconverter_glx.h @@ -31,43 +31,37 @@ G_BEGIN_DECLS #define GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX \ - (gst_vaapi_video_converter_glx_get_type ()) - -#define GST_VAAPI_VIDEO_CONVERTER_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ - GstVaapiVideoConverterGLX)) - -#define GST_VAAPI_VIDEO_CONVERTER_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ - GstVaapiVideoConverterGLXClass)) - + (gst_vaapi_video_converter_glx_get_type ()) +#define GST_VAAPI_VIDEO_CONVERTER_GLX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ + GstVaapiVideoConverterGLX)) +#define GST_VAAPI_VIDEO_CONVERTER_GLX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ + GstVaapiVideoConverterGLXClass)) #define GST_VAAPI_IS_VIDEO_CONVERTER_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX)) - + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX)) #define GST_VAAPI_IS_VIDEO_CONVERTER_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX)) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX)) +#define GST_VAAPI_VIDEO_CONVERTER_GLX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ + GstVaapiVideoConverterGLXClass)) -#define GST_VAAPI_VIDEO_CONVERTER_GLX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ - GstVaapiVideoConverterGLXClass)) - -typedef struct _GstVaapiVideoConverterGLX GstVaapiVideoConverterGLX; -typedef struct _GstVaapiVideoConverterGLXPrivate GstVaapiVideoConverterGLXPrivate; -typedef struct _GstVaapiVideoConverterGLXClass GstVaapiVideoConverterGLXClass; +typedef struct _GstVaapiVideoConverterGLX GstVaapiVideoConverterGLX; +typedef struct _GstVaapiVideoConverterGLXPrivate + GstVaapiVideoConverterGLXPrivate; +typedef struct _GstVaapiVideoConverterGLXClass GstVaapiVideoConverterGLXClass; /** * GstVaapiVideoConverterGLX: * * Converter to transform VA buffers into GL textures. */ -struct _GstVaapiVideoConverterGLX { - /*< private >*/ - GObject parent_instance; +struct _GstVaapiVideoConverterGLX +{ + /*< private >*/ + GObject parent_instance; - GstVaapiVideoConverterGLXPrivate *priv; + GstVaapiVideoConverterGLXPrivate *priv; }; /** @@ -75,19 +69,20 @@ struct _GstVaapiVideoConverterGLX { * * Converter class to transform VA buffers into GL textures. */ -struct _GstVaapiVideoConverterGLXClass { - /*< private >*/ - GObjectClass parent_class; +struct _GstVaapiVideoConverterGLXClass +{ + /*< private >*/ + GObjectClass parent_class; }; G_GNUC_INTERNAL GType -gst_vaapi_video_converter_glx_get_type(void) G_GNUC_CONST; +gst_vaapi_video_converter_glx_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstSurfaceConverter * -gst_vaapi_video_converter_glx_new(GstBuffer *buffer, const gchar *type, - GValue *dest); +gst_vaapi_video_converter_glx_new (GstBuffer * buffer, const gchar * type, + GValue * dest); G_END_DECLS diff --git a/gst/vaapi/gstvaapivideoconverter_x11.c b/gst/vaapi/gstvaapivideoconverter_x11.c index 8a05bd20da..0855562605 100644 --- a/gst/vaapi/gstvaapivideoconverter_x11.c +++ b/gst/vaapi/gstvaapivideoconverter_x11.c @@ -27,86 +27,86 @@ #include "gstvaapivideometa.h" #if GST_CHECK_VERSION(1,0,0) -typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *, +typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *, GstBuffer *); #else -typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *, +typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *, GstSurfaceBuffer *); #endif static void -gst_vaapi_video_converter_x11_iface_init(GstSurfaceConverterInterface *iface); +gst_vaapi_video_converter_x11_iface_init (GstSurfaceConverterInterface * iface); -G_DEFINE_TYPE_WITH_CODE( - GstVaapiVideoConverterX11, +G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoConverterX11, gst_vaapi_video_converter_x11, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE(GST_TYPE_SURFACE_CONVERTER, - gst_vaapi_video_converter_x11_iface_init)) + G_IMPLEMENT_INTERFACE (GST_TYPE_SURFACE_CONVERTER, + gst_vaapi_video_converter_x11_iface_init)); -#define GST_VAAPI_VIDEO_CONVERTER_X11_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ - GstVaapiVideoConverterX11Private)) +#define GST_VAAPI_VIDEO_CONVERTER_X11_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ + GstVaapiVideoConverterX11Private)) -struct _GstVaapiVideoConverterX11Private { - GstVaapiPixmap *pixmap; - XID pixmap_id; +struct _GstVaapiVideoConverterX11Private +{ + GstVaapiPixmap *pixmap; + XID pixmap_id; }; static gboolean -gst_vaapi_video_converter_x11_upload(GstSurfaceConverter *self, - GstBuffer *buffer); +gst_vaapi_video_converter_x11_upload (GstSurfaceConverter * self, + GstBuffer * buffer); static void -gst_vaapi_video_converter_x11_dispose(GObject *object) +gst_vaapi_video_converter_x11_dispose (GObject * object) { - GstVaapiVideoConverterX11Private * const priv = - GST_VAAPI_VIDEO_CONVERTER_X11(object)->priv; + GstVaapiVideoConverterX11Private *const priv = + GST_VAAPI_VIDEO_CONVERTER_X11 (object)->priv; - gst_vaapi_pixmap_replace(&priv->pixmap, NULL); + gst_vaapi_pixmap_replace (&priv->pixmap, NULL); - G_OBJECT_CLASS(gst_vaapi_video_converter_x11_parent_class)->dispose(object); + G_OBJECT_CLASS (gst_vaapi_video_converter_x11_parent_class)->dispose (object); } static void -gst_vaapi_video_converter_x11_class_init(GstVaapiVideoConverterX11Class *klass) +gst_vaapi_video_converter_x11_class_init (GstVaapiVideoConverterX11Class * + klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); - g_type_class_add_private(klass, sizeof(GstVaapiVideoConverterX11Private)); + g_type_class_add_private (klass, sizeof (GstVaapiVideoConverterX11Private)); - object_class->dispose = gst_vaapi_video_converter_x11_dispose; + object_class->dispose = gst_vaapi_video_converter_x11_dispose; } static void -gst_vaapi_video_converter_x11_init(GstVaapiVideoConverterX11 *buffer) +gst_vaapi_video_converter_x11_init (GstVaapiVideoConverterX11 * buffer) { - buffer->priv = GST_VAAPI_VIDEO_CONVERTER_X11_GET_PRIVATE(buffer); + buffer->priv = GST_VAAPI_VIDEO_CONVERTER_X11_GET_PRIVATE (buffer); } static void -gst_vaapi_video_converter_x11_iface_init(GstSurfaceConverterInterface *iface) +gst_vaapi_video_converter_x11_iface_init (GstSurfaceConverterInterface * iface) { - iface->upload = (GstSurfaceUploadFunction) - gst_vaapi_video_converter_x11_upload; + iface->upload = (GstSurfaceUploadFunction) + gst_vaapi_video_converter_x11_upload; } static gboolean -set_pixmap(GstVaapiVideoConverterX11 *converter, GstVaapiDisplay *display, +set_pixmap (GstVaapiVideoConverterX11 * converter, GstVaapiDisplay * display, XID pixmap_id) { - GstVaapiVideoConverterX11Private * const priv = converter->priv; - GstVaapiPixmap *pixmap; + GstVaapiVideoConverterX11Private *const priv = converter->priv; + GstVaapiPixmap *pixmap; - pixmap = gst_vaapi_pixmap_x11_new_with_xid(display, pixmap_id); - if (!pixmap) - return FALSE; + pixmap = gst_vaapi_pixmap_x11_new_with_xid (display, pixmap_id); + if (!pixmap) + return FALSE; - gst_vaapi_pixmap_replace(&priv->pixmap, pixmap); - gst_vaapi_pixmap_unref(pixmap); - priv->pixmap_id = pixmap_id; - return TRUE; + gst_vaapi_pixmap_replace (&priv->pixmap, pixmap); + gst_vaapi_pixmap_unref (pixmap); + priv->pixmap_id = pixmap_id; + return TRUE; } /** @@ -122,73 +122,73 @@ set_pixmap(GstVaapiVideoConverterX11 *converter, GstVaapiDisplay *display, * Return value: the newly allocated #GstBuffer, or %NULL on error */ GstSurfaceConverter * -gst_vaapi_video_converter_x11_new(GstBuffer *buffer, const gchar *type, - GValue *dest) +gst_vaapi_video_converter_x11_new (GstBuffer * buffer, const gchar * type, + GValue * dest) { - GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); - GstVaapiVideoConverterX11 *converter; + GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); + GstVaapiVideoConverterX11 *converter; - /* We only support X11 pixmap conversion */ - if (strcmp(type, "x11-pixmap") != 0 || !G_VALUE_HOLDS_UINT(dest)) - return NULL; + /* We only support X11 pixmap conversion */ + if (strcmp (type, "x11-pixmap") != 0 || !G_VALUE_HOLDS_UINT (dest)) + return NULL; - converter = g_object_new(GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, NULL); - if (!converter) - return NULL; + converter = g_object_new (GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, NULL); + if (!converter) + return NULL; - if (!set_pixmap(converter, gst_vaapi_video_meta_get_display(meta), - g_value_get_uint(dest))) - goto error; - return GST_SURFACE_CONVERTER(converter); + if (!set_pixmap (converter, gst_vaapi_video_meta_get_display (meta), + g_value_get_uint (dest))) + goto error; + return GST_SURFACE_CONVERTER (converter); error: - g_object_unref(converter); - return NULL; + g_object_unref (converter); + return NULL; } gboolean -gst_vaapi_video_converter_x11_upload(GstSurfaceConverter *self, - GstBuffer *buffer) +gst_vaapi_video_converter_x11_upload (GstSurfaceConverter * self, + GstBuffer * buffer) { - GstVaapiVideoConverterX11 * const converter = - GST_VAAPI_VIDEO_CONVERTER_X11(self); - GstVaapiVideoConverterX11Private * const priv = converter->priv; - GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer); - const GstVaapiRectangle *crop_rect = NULL; - GstVaapiSurface *surface; - GstVaapiDisplay *old_display, *new_display; + GstVaapiVideoConverterX11 *const converter = + GST_VAAPI_VIDEO_CONVERTER_X11 (self); + GstVaapiVideoConverterX11Private *const priv = converter->priv; + GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); + const GstVaapiRectangle *crop_rect = NULL; + GstVaapiSurface *surface; + GstVaapiDisplay *old_display, *new_display; - g_return_val_if_fail(meta != NULL, FALSE); + g_return_val_if_fail (meta != NULL, FALSE); - surface = gst_vaapi_video_meta_get_surface(meta); - if (!surface) - return FALSE; + surface = gst_vaapi_video_meta_get_surface (meta); + if (!surface) + return FALSE; - old_display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(priv->pixmap)); - new_display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); + old_display = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (priv->pixmap)); + new_display = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); - if (old_display != new_display) { - if (!set_pixmap(converter, new_display, priv->pixmap_id)) - return FALSE; - } + if (old_display != new_display) { + if (!set_pixmap (converter, new_display, priv->pixmap_id)) + return FALSE; + } - if (!gst_vaapi_apply_composition(surface, buffer)) - GST_WARNING("could not update subtitles"); + if (!gst_vaapi_apply_composition (surface, buffer)) + GST_WARNING ("could not update subtitles"); #if GST_CHECK_VERSION(1,0,0) - GstVideoCropMeta * const crop_meta = gst_buffer_get_video_crop_meta(buffer); - if (crop_meta) { - GstVaapiRectangle crop_rect_tmp; - crop_rect = &crop_rect_tmp; - crop_rect_tmp.x = crop_meta->x; - crop_rect_tmp.y = crop_meta->y; - crop_rect_tmp.width = crop_meta->width; - crop_rect_tmp.height = crop_meta->height; - } + GstVideoCropMeta *const crop_meta = gst_buffer_get_video_crop_meta (buffer); + if (crop_meta) { + GstVaapiRectangle crop_rect_tmp; + crop_rect = &crop_rect_tmp; + crop_rect_tmp.x = crop_meta->x; + crop_rect_tmp.y = crop_meta->y; + crop_rect_tmp.width = crop_meta->width; + crop_rect_tmp.height = crop_meta->height; + } #endif - if (!crop_rect) - crop_rect = gst_vaapi_video_meta_get_render_rect(meta); + if (!crop_rect) + crop_rect = gst_vaapi_video_meta_get_render_rect (meta); - return gst_vaapi_pixmap_put_surface(priv->pixmap, surface, crop_rect, - gst_vaapi_video_meta_get_render_flags(meta)); + return gst_vaapi_pixmap_put_surface (priv->pixmap, surface, crop_rect, + gst_vaapi_video_meta_get_render_flags (meta)); } diff --git a/gst/vaapi/gstvaapivideoconverter_x11.h b/gst/vaapi/gstvaapivideoconverter_x11.h index 54618ebb6e..abf9211ac1 100644 --- a/gst/vaapi/gstvaapivideoconverter_x11.h +++ b/gst/vaapi/gstvaapivideoconverter_x11.h @@ -29,43 +29,37 @@ G_BEGIN_DECLS #define GST_VAAPI_TYPE_VIDEO_CONVERTER_X11 \ - (gst_vaapi_video_converter_x11_get_type ()) - -#define GST_VAAPI_VIDEO_CONVERTER_X11(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ - GstVaapiVideoConverterX11)) - -#define GST_VAAPI_VIDEO_CONVERTER_X11_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ - GstVaapiVideoConverterX11Class)) - + (gst_vaapi_video_converter_x11_get_type ()) +#define GST_VAAPI_VIDEO_CONVERTER_X11(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ + GstVaapiVideoConverterX11)) +#define GST_VAAPI_VIDEO_CONVERTER_X11_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ + GstVaapiVideoConverterX11Class)) #define GST_VAAPI_IS_VIDEO_CONVERTER_X11(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11)) - + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11)) #define GST_VAAPI_IS_VIDEO_CONVERTER_X11_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11)) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11)) +#define GST_VAAPI_VIDEO_CONVERTER_X11_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ + GstVaapiVideoConverterX11Class)) -#define GST_VAAPI_VIDEO_CONVERTER_X11_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ - GstVaapiVideoConverterX11Class)) - -typedef struct _GstVaapiVideoConverterX11 GstVaapiVideoConverterX11; -typedef struct _GstVaapiVideoConverterX11Private GstVaapiVideoConverterX11Private; -typedef struct _GstVaapiVideoConverterX11Class GstVaapiVideoConverterX11Class; +typedef struct _GstVaapiVideoConverterX11 GstVaapiVideoConverterX11; +typedef struct _GstVaapiVideoConverterX11Private + GstVaapiVideoConverterX11Private; +typedef struct _GstVaapiVideoConverterX11Class GstVaapiVideoConverterX11Class; /** * GstVaapiVideoConverterX11: * * Converter to transform VA buffers into GL textures. */ -struct _GstVaapiVideoConverterX11 { - /*< private >*/ - GObject parent_instance; +struct _GstVaapiVideoConverterX11 +{ + /*< private >*/ + GObject parent_instance; - GstVaapiVideoConverterX11Private *priv; + GstVaapiVideoConverterX11Private *priv; }; /** @@ -73,19 +67,20 @@ struct _GstVaapiVideoConverterX11 { * * Converter class to transform VA buffers into GL textures. */ -struct _GstVaapiVideoConverterX11Class { - /*< private >*/ - GObjectClass parent_class; +struct _GstVaapiVideoConverterX11Class +{ + /*< private >*/ + GObjectClass parent_class; }; G_GNUC_INTERNAL GType -gst_vaapi_video_converter_x11_get_type(void) G_GNUC_CONST; +gst_vaapi_video_converter_x11_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstSurfaceConverter * -gst_vaapi_video_converter_x11_new(GstBuffer *buffer, const gchar *type, - GValue *dest); +gst_vaapi_video_converter_x11_new (GstBuffer * buffer, const gchar * type, + GValue * dest); G_END_DECLS diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index c6247e248f..fa368bdaf6 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -25,12 +25,12 @@ #include #include "gstvaapivideomemory.h" -GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideomemory); +GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapivideomemory); #define GST_CAT_DEFAULT gst_debug_vaapivideomemory #ifndef GST_VIDEO_INFO_FORMAT_STRING #define GST_VIDEO_INFO_FORMAT_STRING(vip) \ - gst_video_format_to_string(GST_VIDEO_INFO_FORMAT(vip)) + gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)) #endif /* Defined if native VA surface formats are preferred over direct rendering */ @@ -41,634 +41,632 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideomemory); /* ------------------------------------------------------------------------ */ static void -gst_vaapi_video_memory_reset_image(GstVaapiVideoMemory *mem); +gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem); static guchar * -get_image_data(GstVaapiImage *image) +get_image_data (GstVaapiImage * image) { - guchar *data; - VAImage va_image; + guchar *data; + VAImage va_image; - data = gst_vaapi_image_get_plane(image, 0); - if (!data || !gst_vaapi_image_get_image(image, &va_image)) - return NULL; + data = gst_vaapi_image_get_plane (image, 0); + if (!data || !gst_vaapi_image_get_image (image, &va_image)) + return NULL; - data -= va_image.offsets[0]; - return data; + data -= va_image.offsets[0]; + return data; } static GstVaapiImage * -new_image(GstVaapiDisplay *display, const GstVideoInfo *vip) +new_image (GstVaapiDisplay * display, const GstVideoInfo * vip) { - return gst_vaapi_image_new(display, GST_VIDEO_INFO_FORMAT(vip), - GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + return gst_vaapi_image_new (display, GST_VIDEO_INFO_FORMAT (vip), + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); } static gboolean -ensure_image(GstVaapiVideoMemory *mem) +ensure_image (GstVaapiVideoMemory * mem) { - if (!mem->image && mem->use_direct_rendering) { - mem->image = gst_vaapi_surface_derive_image(mem->surface); - if (!mem->image) { - GST_WARNING("failed to derive image, fallbacking to copy"); - mem->use_direct_rendering = FALSE; - } - else if (gst_vaapi_surface_get_format(mem->surface) != - GST_VIDEO_INFO_FORMAT(mem->image_info)) { - gst_vaapi_object_replace(&mem->image, NULL); - mem->use_direct_rendering = FALSE; - } - } - + if (!mem->image && mem->use_direct_rendering) { + mem->image = gst_vaapi_surface_derive_image (mem->surface); if (!mem->image) { - GstVaapiVideoAllocator * const allocator = - GST_VAAPI_VIDEO_ALLOCATOR_CAST(GST_MEMORY_CAST(mem)->allocator); - - mem->image = gst_vaapi_video_pool_get_object(allocator->image_pool); - if (!mem->image) - return FALSE; + GST_WARNING ("failed to derive image, fallbacking to copy"); + mem->use_direct_rendering = FALSE; + } else if (gst_vaapi_surface_get_format (mem->surface) != + GST_VIDEO_INFO_FORMAT (mem->image_info)) { + gst_vaapi_object_replace (&mem->image, NULL); + mem->use_direct_rendering = FALSE; } - gst_vaapi_video_meta_set_image(mem->meta, mem->image); - return TRUE; + } + + if (!mem->image) { + GstVaapiVideoAllocator *const allocator = + GST_VAAPI_VIDEO_ALLOCATOR_CAST (GST_MEMORY_CAST (mem)->allocator); + + mem->image = gst_vaapi_video_pool_get_object (allocator->image_pool); + if (!mem->image) + return FALSE; + } + gst_vaapi_video_meta_set_image (mem->meta, mem->image); + return TRUE; } static GstVaapiSurface * -new_surface(GstVaapiDisplay *display, const GstVideoInfo *vip) +new_surface (GstVaapiDisplay * display, const GstVideoInfo * vip) { - GstVaapiSurface *surface; - GstVaapiChromaType chroma_type; + GstVaapiSurface *surface; + GstVaapiChromaType chroma_type; - /* Try with explicit format first */ - if (!USE_NATIVE_FORMATS && - GST_VIDEO_INFO_FORMAT(vip) != GST_VIDEO_FORMAT_ENCODED) { - surface = gst_vaapi_surface_new_with_format(display, - GST_VIDEO_INFO_FORMAT(vip), GST_VIDEO_INFO_WIDTH(vip), - GST_VIDEO_INFO_HEIGHT(vip)); - if (surface) - return surface; - } + /* Try with explicit format first */ + if (!USE_NATIVE_FORMATS && + GST_VIDEO_INFO_FORMAT (vip) != GST_VIDEO_FORMAT_ENCODED) { + surface = gst_vaapi_surface_new_with_format (display, + GST_VIDEO_INFO_FORMAT (vip), GST_VIDEO_INFO_WIDTH (vip), + GST_VIDEO_INFO_HEIGHT (vip)); + if (surface) + return surface; + } - /* Try to pick something compatible, i.e. with same chroma type */ - chroma_type = gst_vaapi_video_format_get_chroma_type( - GST_VIDEO_INFO_FORMAT(vip)); - if (!chroma_type) - return NULL; - return gst_vaapi_surface_new(display, chroma_type, - GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + /* Try to pick something compatible, i.e. with same chroma type */ + chroma_type = + gst_vaapi_video_format_get_chroma_type (GST_VIDEO_INFO_FORMAT (vip)); + if (!chroma_type) + return NULL; + return gst_vaapi_surface_new (display, chroma_type, + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); } static GstVaapiSurfaceProxy * -new_surface_proxy(GstVaapiVideoMemory *mem) +new_surface_proxy (GstVaapiVideoMemory * mem) { - GstVaapiVideoAllocator * const allocator = - GST_VAAPI_VIDEO_ALLOCATOR_CAST(GST_MEMORY_CAST(mem)->allocator); + GstVaapiVideoAllocator *const allocator = + GST_VAAPI_VIDEO_ALLOCATOR_CAST (GST_MEMORY_CAST (mem)->allocator); - return gst_vaapi_surface_proxy_new_from_pool( - GST_VAAPI_SURFACE_POOL(allocator->surface_pool)); + return + gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL + (allocator->surface_pool)); } static gboolean -ensure_surface(GstVaapiVideoMemory *mem) +ensure_surface (GstVaapiVideoMemory * mem) { + if (!mem->proxy) { + gst_vaapi_surface_proxy_replace (&mem->proxy, + gst_vaapi_video_meta_get_surface_proxy (mem->meta)); + if (!mem->proxy) { - gst_vaapi_surface_proxy_replace(&mem->proxy, - gst_vaapi_video_meta_get_surface_proxy(mem->meta)); - - if (!mem->proxy) { - mem->proxy = new_surface_proxy(mem); - if (!mem->proxy) - return FALSE; - gst_vaapi_video_meta_set_surface_proxy(mem->meta, mem->proxy); - } + mem->proxy = new_surface_proxy (mem); + if (!mem->proxy) + return FALSE; + gst_vaapi_video_meta_set_surface_proxy (mem->meta, mem->proxy); } - mem->surface = GST_VAAPI_SURFACE_PROXY_SURFACE(mem->proxy); - return mem->surface != NULL; + } + mem->surface = GST_VAAPI_SURFACE_PROXY_SURFACE (mem->proxy); + return mem->surface != NULL; } gboolean -gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, - GstMapInfo *info, gpointer *data, gint *stride, GstMapFlags flags) +gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, + GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags) { - GstVaapiVideoMemory * const mem = - GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_peek_memory(meta->buffer, 0)); + GstVaapiVideoMemory *const mem = + GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0)); - g_return_val_if_fail(mem, FALSE); - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_ALLOCATOR(mem->parent_instance. - allocator), FALSE); - g_return_val_if_fail(mem->meta, FALSE); + g_return_val_if_fail (mem, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (mem->parent_instance. + allocator), FALSE); + g_return_val_if_fail (mem->meta, FALSE); - if (mem->map_type && - mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR) - goto error_incompatible_map; + if (mem->map_type && mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR) + goto error_incompatible_map; - /* Map for writing */ - if (++mem->map_count == 1) { - if (!ensure_surface(mem)) - goto error_ensure_surface; - if (!ensure_image(mem)) - goto error_ensure_image; + /* Map for writing */ + if (++mem->map_count == 1) { + if (!ensure_surface (mem)) + goto error_ensure_surface; + if (!ensure_image (mem)) + goto error_ensure_image; - // Check that we can actually map the surface, or image - if ((flags & GST_MAP_READWRITE) == GST_MAP_READWRITE && - !mem->use_direct_rendering) - goto error_unsupported_map; + // Check that we can actually map the surface, or image + if ((flags & GST_MAP_READWRITE) == GST_MAP_READWRITE && + !mem->use_direct_rendering) + goto error_unsupported_map; - // Load VA image from surface - if ((flags & GST_MAP_READ) && !mem->use_direct_rendering) - gst_vaapi_surface_get_image(mem->surface, mem->image); + // Load VA image from surface + if ((flags & GST_MAP_READ) && !mem->use_direct_rendering) + gst_vaapi_surface_get_image (mem->surface, mem->image); - if (!gst_vaapi_image_map(mem->image)) - goto error_map_image; - mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR; - } + if (!gst_vaapi_image_map (mem->image)) + goto error_map_image; + mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR; + } - *data = gst_vaapi_image_get_plane(mem->image, plane); - *stride = gst_vaapi_image_get_pitch(mem->image, plane); - info->flags = flags; - return TRUE; + *data = gst_vaapi_image_get_plane (mem->image, plane); + *stride = gst_vaapi_image_get_pitch (mem->image, plane); + info->flags = flags; + return TRUE; - /* ERRORS */ + /* ERRORS */ error_incompatible_map: - { - GST_ERROR("incompatible map type (%d)", mem->map_type); - return FALSE; - } + { + GST_ERROR ("incompatible map type (%d)", mem->map_type); + return FALSE; + } error_unsupported_map: - { - GST_ERROR("unsupported map flags (0x%x)", flags); - return FALSE; - } + { + GST_ERROR ("unsupported map flags (0x%x)", flags); + return FALSE; + } error_ensure_surface: - { - const GstVideoInfo * const vip = mem->surface_info; - GST_ERROR("failed to create %s surface of size %ux%u", - GST_VIDEO_INFO_FORMAT_STRING(vip), - GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); - return FALSE; - } + { + const GstVideoInfo *const vip = mem->surface_info; + GST_ERROR ("failed to create %s surface of size %ux%u", + GST_VIDEO_INFO_FORMAT_STRING (vip), + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); + return FALSE; + } error_ensure_image: - { - const GstVideoInfo * const vip = mem->image_info; - GST_ERROR("failed to create %s image of size %ux%u", - GST_VIDEO_INFO_FORMAT_STRING(vip), - GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); - return FALSE; - } + { + const GstVideoInfo *const vip = mem->image_info; + GST_ERROR ("failed to create %s image of size %ux%u", + GST_VIDEO_INFO_FORMAT_STRING (vip), + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); + return FALSE; + } error_map_image: - { - GST_ERROR("failed to map image %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(gst_vaapi_image_get_id(mem->image))); - return FALSE; - } + { + GST_ERROR ("failed to map image %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (gst_vaapi_image_get_id (mem->image))); + return FALSE; + } } gboolean -gst_video_meta_unmap_vaapi_memory(GstVideoMeta *meta, guint plane, - GstMapInfo *info) +gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane, + GstMapInfo * info) { - GstVaapiVideoMemory * const mem = - GST_VAAPI_VIDEO_MEMORY_CAST(gst_buffer_peek_memory(meta->buffer, 0)); + GstVaapiVideoMemory *const mem = + GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0)); - g_return_val_if_fail(mem, FALSE); - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_ALLOCATOR(mem->parent_instance. - allocator), FALSE); - g_return_val_if_fail(mem->meta, FALSE); - g_return_val_if_fail(mem->surface, FALSE); - g_return_val_if_fail(mem->image, FALSE); + g_return_val_if_fail (mem, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (mem->parent_instance. + allocator), FALSE); + g_return_val_if_fail (mem->meta, FALSE); + g_return_val_if_fail (mem->surface, FALSE); + g_return_val_if_fail (mem->image, FALSE); - if (--mem->map_count == 0) { - mem->map_type = 0; + if (--mem->map_count == 0) { + mem->map_type = 0; - /* Unmap VA image used for read/writes */ - if (info->flags & GST_MAP_READWRITE) - gst_vaapi_image_unmap(mem->image); + /* Unmap VA image used for read/writes */ + if (info->flags & GST_MAP_READWRITE) + gst_vaapi_image_unmap (mem->image); - /* Commit VA image to surface */ - if ((info->flags & GST_MAP_WRITE) && !mem->use_direct_rendering) { - if (!gst_vaapi_surface_put_image(mem->surface, mem->image)) - goto error_upload_image; - } + /* Commit VA image to surface */ + if ((info->flags & GST_MAP_WRITE) && !mem->use_direct_rendering) { + if (!gst_vaapi_surface_put_image (mem->surface, mem->image)) + goto error_upload_image; } - return TRUE; + } + return TRUE; - /* ERRORS */ + /* ERRORS */ error_upload_image: - { - GST_ERROR("failed to upload image"); - return FALSE; - } + { + GST_ERROR ("failed to upload image"); + return FALSE; + } } GstMemory * -gst_vaapi_video_memory_new(GstAllocator *base_allocator, - GstVaapiVideoMeta *meta) +gst_vaapi_video_memory_new (GstAllocator * base_allocator, + GstVaapiVideoMeta * meta) { - GstVaapiVideoAllocator * const allocator = - GST_VAAPI_VIDEO_ALLOCATOR_CAST(base_allocator); - const GstVideoInfo *vip; - GstVaapiVideoMemory *mem; + GstVaapiVideoAllocator *const allocator = + GST_VAAPI_VIDEO_ALLOCATOR_CAST (base_allocator); + const GstVideoInfo *vip; + GstVaapiVideoMemory *mem; - mem = g_slice_new(GstVaapiVideoMemory); - if (!mem) - return NULL; + mem = g_slice_new (GstVaapiVideoMemory); + if (!mem) + return NULL; - vip = &allocator->image_info; - gst_memory_init(&mem->parent_instance, GST_MEMORY_FLAG_NO_SHARE, - gst_object_ref(allocator), NULL, GST_VIDEO_INFO_SIZE(vip), 0, - 0, GST_VIDEO_INFO_SIZE(vip)); + vip = &allocator->image_info; + gst_memory_init (&mem->parent_instance, GST_MEMORY_FLAG_NO_SHARE, + gst_object_ref (allocator), NULL, GST_VIDEO_INFO_SIZE (vip), 0, + 0, GST_VIDEO_INFO_SIZE (vip)); - mem->proxy = NULL; - mem->surface_info = &allocator->surface_info; - mem->surface = NULL; - mem->image_info = &allocator->image_info; - mem->image = NULL; - mem->meta = gst_vaapi_video_meta_ref(meta); - mem->map_type = 0; - mem->map_count = 0; - mem->use_direct_rendering = allocator->has_direct_rendering; - return GST_MEMORY_CAST(mem); + mem->proxy = NULL; + mem->surface_info = &allocator->surface_info; + mem->surface = NULL; + mem->image_info = &allocator->image_info; + mem->image = NULL; + mem->meta = gst_vaapi_video_meta_ref (meta); + mem->map_type = 0; + mem->map_count = 0; + mem->use_direct_rendering = allocator->has_direct_rendering; + return GST_MEMORY_CAST (mem); } static void -gst_vaapi_video_memory_free(GstVaapiVideoMemory *mem) +gst_vaapi_video_memory_free (GstVaapiVideoMemory * mem) { - mem->surface = NULL; - gst_vaapi_video_memory_reset_image(mem); - gst_vaapi_surface_proxy_replace(&mem->proxy, NULL); - gst_vaapi_video_meta_unref(mem->meta); - gst_object_unref(GST_MEMORY_CAST(mem)->allocator); - g_slice_free(GstVaapiVideoMemory, mem); + mem->surface = NULL; + gst_vaapi_video_memory_reset_image (mem); + gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); + gst_vaapi_video_meta_unref (mem->meta); + gst_object_unref (GST_MEMORY_CAST (mem)->allocator); + g_slice_free (GstVaapiVideoMemory, mem); } void -gst_vaapi_video_memory_reset_image(GstVaapiVideoMemory *mem) +gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem) { - GstVaapiVideoAllocator * const allocator = - GST_VAAPI_VIDEO_ALLOCATOR_CAST(GST_MEMORY_CAST(mem)->allocator); + GstVaapiVideoAllocator *const allocator = + GST_VAAPI_VIDEO_ALLOCATOR_CAST (GST_MEMORY_CAST (mem)->allocator); - if (mem->use_direct_rendering) - gst_vaapi_object_replace(&mem->image, NULL); - else if (mem->image) { - gst_vaapi_video_pool_put_object(allocator->image_pool, mem->image); - mem->image = NULL; - } + if (mem->use_direct_rendering) + gst_vaapi_object_replace (&mem->image, NULL); + else if (mem->image) { + gst_vaapi_video_pool_put_object (allocator->image_pool, mem->image); + mem->image = NULL; + } } void -gst_vaapi_video_memory_reset_surface(GstVaapiVideoMemory *mem) +gst_vaapi_video_memory_reset_surface (GstVaapiVideoMemory * mem) { - mem->surface = NULL; - gst_vaapi_video_memory_reset_image(mem); - gst_vaapi_surface_proxy_replace(&mem->proxy, NULL); - gst_vaapi_video_meta_set_surface_proxy(mem->meta, NULL); + mem->surface = NULL; + gst_vaapi_video_memory_reset_image (mem); + gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); + gst_vaapi_video_meta_set_surface_proxy (mem->meta, NULL); } static gpointer -gst_vaapi_video_memory_map(GstVaapiVideoMemory *mem, gsize maxsize, guint flags) +gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize, + guint flags) { - gpointer data; + gpointer data; - if (mem->map_count == 0) { - switch (flags & GST_MAP_READWRITE) { - case 0: - // No flags set: return a GstVaapiSurfaceProxy - gst_vaapi_surface_proxy_replace(&mem->proxy, - gst_vaapi_video_meta_get_surface_proxy(mem->meta)); - if (!mem->proxy) - goto error_no_surface_proxy; - mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE; - break; - case GST_MAP_READ: - // Only read flag set: return raw pixels - if (!ensure_surface(mem)) - goto error_no_surface; - if (!ensure_image(mem)) - goto error_no_image; - if (!mem->use_direct_rendering) - gst_vaapi_surface_get_image(mem->surface, mem->image); - if (!gst_vaapi_image_map(mem->image)) - goto error_map_image; - mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR; - break; - default: - goto error_unsupported_map; - } - } - - switch (mem->map_type) { - case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: + if (mem->map_count == 0) { + switch (flags & GST_MAP_READWRITE) { + case 0: + // No flags set: return a GstVaapiSurfaceProxy + gst_vaapi_surface_proxy_replace (&mem->proxy, + gst_vaapi_video_meta_get_surface_proxy (mem->meta)); if (!mem->proxy) - goto error_no_surface_proxy; - data = mem->proxy; + goto error_no_surface_proxy; + mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE; break; - case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR: - if (!mem->image) - goto error_no_image; - data = get_image_data(mem->image); + case GST_MAP_READ: + // Only read flag set: return raw pixels + if (!ensure_surface (mem)) + goto error_no_surface; + if (!ensure_image (mem)) + goto error_no_image; + if (!mem->use_direct_rendering) + gst_vaapi_surface_get_image (mem->surface, mem->image); + if (!gst_vaapi_image_map (mem->image)) + goto error_map_image; + mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR; break; - default: - goto error_unsupported_map_type; + default: + goto error_unsupported_map; } - mem->map_count++; - return data; + } - /* ERRORS */ + switch (mem->map_type) { + case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: + if (!mem->proxy) + goto error_no_surface_proxy; + data = mem->proxy; + break; + case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR: + if (!mem->image) + goto error_no_image; + data = get_image_data (mem->image); + break; + default: + goto error_unsupported_map_type; + } + mem->map_count++; + return data; + + /* ERRORS */ error_unsupported_map: - GST_ERROR("unsupported map flags (0x%x)", flags); - return NULL; + GST_ERROR ("unsupported map flags (0x%x)", flags); + return NULL; error_unsupported_map_type: - GST_ERROR("unsupported map type (%d)", mem->map_type); - return NULL; + GST_ERROR ("unsupported map type (%d)", mem->map_type); + return NULL; error_no_surface_proxy: - GST_ERROR("failed to extract GstVaapiSurfaceProxy from video meta"); - return NULL; + GST_ERROR ("failed to extract GstVaapiSurfaceProxy from video meta"); + return NULL; error_no_surface: - GST_ERROR("failed to extract VA surface from video buffer"); - return NULL; + GST_ERROR ("failed to extract VA surface from video buffer"); + return NULL; error_no_image: - GST_ERROR("failed to extract VA image from video buffer"); - return NULL; + GST_ERROR ("failed to extract VA image from video buffer"); + return NULL; error_map_image: - GST_ERROR("failed to map VA image"); - return NULL; + GST_ERROR ("failed to map VA image"); + return NULL; } static void -gst_vaapi_video_memory_unmap(GstVaapiVideoMemory *mem) +gst_vaapi_video_memory_unmap (GstVaapiVideoMemory * mem) { - if (mem->map_count == 1) { - switch (mem->map_type) { - case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: - gst_vaapi_surface_proxy_replace(&mem->proxy, NULL); - break; - case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR: - gst_vaapi_image_unmap(mem->image); - break; - default: - goto error_incompatible_map; - } - mem->map_type = 0; + if (mem->map_count == 1) { + switch (mem->map_type) { + case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: + gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); + break; + case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR: + gst_vaapi_image_unmap (mem->image); + break; + default: + goto error_incompatible_map; } - mem->map_count--; - return; + mem->map_type = 0; + } + mem->map_count--; + return; - /* ERRORS */ + /* ERRORS */ error_incompatible_map: - GST_ERROR("incompatible map type (%d)", mem->map_type); - return; + GST_ERROR ("incompatible map type (%d)", mem->map_type); + return; } static GstVaapiVideoMemory * -gst_vaapi_video_memory_copy(GstVaapiVideoMemory *mem, +gst_vaapi_video_memory_copy (GstVaapiVideoMemory * mem, gssize offset, gssize size) { - GstVaapiVideoMeta *meta; - GstMemory *out_mem; - gsize maxsize; + GstVaapiVideoMeta *meta; + GstMemory *out_mem; + gsize maxsize; - /* XXX: this implements a soft-copy, i.e. underlying VA surfaces - are not copied */ - (void)gst_memory_get_sizes(GST_MEMORY_CAST(mem), NULL, &maxsize); - if (offset != 0 || (size != -1 && (gsize)size != maxsize)) - goto error_unsupported; + /* XXX: this implements a soft-copy, i.e. underlying VA surfaces + are not copied */ + (void) gst_memory_get_sizes (GST_MEMORY_CAST (mem), NULL, &maxsize); + if (offset != 0 || (size != -1 && (gsize) size != maxsize)) + goto error_unsupported; - meta = gst_vaapi_video_meta_copy(mem->meta); - if (!meta) - goto error_allocate_memory; + meta = gst_vaapi_video_meta_copy (mem->meta); + if (!meta) + goto error_allocate_memory; - out_mem = gst_vaapi_video_memory_new(GST_MEMORY_CAST(mem)->allocator, meta); - gst_vaapi_video_meta_unref(meta); - if (!out_mem) - goto error_allocate_memory; - return GST_VAAPI_VIDEO_MEMORY_CAST(out_mem); + out_mem = gst_vaapi_video_memory_new (GST_MEMORY_CAST (mem)->allocator, meta); + gst_vaapi_video_meta_unref (meta); + if (!out_mem) + goto error_allocate_memory; + return GST_VAAPI_VIDEO_MEMORY_CAST (out_mem); - /* ERRORS */ + /* ERRORS */ error_unsupported: - GST_ERROR("failed to copy partial memory (unsupported operation)"); - return NULL; + GST_ERROR ("failed to copy partial memory (unsupported operation)"); + return NULL; error_allocate_memory: - GST_ERROR("failed to allocate GstVaapiVideoMemory copy"); - return NULL; + GST_ERROR ("failed to allocate GstVaapiVideoMemory copy"); + return NULL; } static GstVaapiVideoMemory * -gst_vaapi_video_memory_share(GstVaapiVideoMemory *mem, +gst_vaapi_video_memory_share (GstVaapiVideoMemory * mem, gssize offset, gssize size) { - GST_FIXME("unimplemented GstVaapiVideoAllocator::mem_share() hook"); - return NULL; + GST_FIXME ("unimplemented GstVaapiVideoAllocator::mem_share() hook"); + return NULL; } static gboolean -gst_vaapi_video_memory_is_span(GstVaapiVideoMemory *mem1, - GstVaapiVideoMemory *mem2, gsize *offset_ptr) +gst_vaapi_video_memory_is_span (GstVaapiVideoMemory * mem1, + GstVaapiVideoMemory * mem2, gsize * offset_ptr) { - GST_FIXME("unimplemented GstVaapiVideoAllocator::mem_is_span() hook"); - return FALSE; + GST_FIXME ("unimplemented GstVaapiVideoAllocator::mem_is_span() hook"); + return FALSE; } /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoAllocator --- */ /* ------------------------------------------------------------------------ */ -#define GST_VAAPI_VIDEO_ALLOCATOR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_VIDEO_ALLOCATOR, \ - GstVaapiVideoAllocatorClass)) +#define GST_VAAPI_VIDEO_ALLOCATOR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_ALLOCATOR, \ + GstVaapiVideoAllocatorClass)) #define GST_VAAPI_IS_VIDEO_ALLOCATOR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_ALLOCATOR)) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_ALLOCATOR)) -G_DEFINE_TYPE(GstVaapiVideoAllocator, - gst_vaapi_video_allocator, - GST_TYPE_ALLOCATOR) +G_DEFINE_TYPE (GstVaapiVideoAllocator, + gst_vaapi_video_allocator, GST_TYPE_ALLOCATOR); static GstMemory * -gst_vaapi_video_allocator_alloc(GstAllocator *allocator, gsize size, - GstAllocationParams *params) +gst_vaapi_video_allocator_alloc (GstAllocator * allocator, gsize size, + GstAllocationParams * params) { - g_warning("use gst_vaapi_video_memory_new() to allocate from " - "GstVaapiVideoMemory allocator"); + g_warning ("use gst_vaapi_video_memory_new() to allocate from " + "GstVaapiVideoMemory allocator"); - return NULL; + return NULL; } static void -gst_vaapi_video_allocator_free(GstAllocator *allocator, GstMemory *mem) +gst_vaapi_video_allocator_free (GstAllocator * allocator, GstMemory * mem) { - gst_vaapi_video_memory_free(GST_VAAPI_VIDEO_MEMORY_CAST(mem)); + gst_vaapi_video_memory_free (GST_VAAPI_VIDEO_MEMORY_CAST (mem)); } static void -gst_vaapi_video_allocator_finalize(GObject *object) +gst_vaapi_video_allocator_finalize (GObject * object) { - GstVaapiVideoAllocator * const allocator = - GST_VAAPI_VIDEO_ALLOCATOR_CAST(object); + GstVaapiVideoAllocator *const allocator = + GST_VAAPI_VIDEO_ALLOCATOR_CAST (object); - gst_vaapi_video_pool_replace(&allocator->surface_pool, NULL); - gst_vaapi_video_pool_replace(&allocator->image_pool, NULL); + gst_vaapi_video_pool_replace (&allocator->surface_pool, NULL); + gst_vaapi_video_pool_replace (&allocator->image_pool, NULL); - G_OBJECT_CLASS(gst_vaapi_video_allocator_parent_class)->finalize(object); + G_OBJECT_CLASS (gst_vaapi_video_allocator_parent_class)->finalize (object); } static void -gst_vaapi_video_allocator_class_init(GstVaapiVideoAllocatorClass *klass) +gst_vaapi_video_allocator_class_init (GstVaapiVideoAllocatorClass * klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstAllocatorClass * const allocator_class = GST_ALLOCATOR_CLASS(klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstAllocatorClass *const allocator_class = GST_ALLOCATOR_CLASS (klass); - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapivideomemory, - "vaapivideomemory", 0, "VA-API video memory allocator"); + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapivideomemory, + "vaapivideomemory", 0, "VA-API video memory allocator"); - object_class->finalize = gst_vaapi_video_allocator_finalize; - allocator_class->alloc = gst_vaapi_video_allocator_alloc; - allocator_class->free = gst_vaapi_video_allocator_free; + object_class->finalize = gst_vaapi_video_allocator_finalize; + allocator_class->alloc = gst_vaapi_video_allocator_alloc; + allocator_class->free = gst_vaapi_video_allocator_free; } static void -gst_vaapi_video_allocator_init(GstVaapiVideoAllocator *allocator) +gst_vaapi_video_allocator_init (GstVaapiVideoAllocator * allocator) { - GstAllocator * const base_allocator = GST_ALLOCATOR_CAST(allocator); + GstAllocator *const base_allocator = GST_ALLOCATOR_CAST (allocator); - base_allocator->mem_type = GST_VAAPI_VIDEO_MEMORY_NAME; - base_allocator->mem_map = (GstMemoryMapFunction) - gst_vaapi_video_memory_map; - base_allocator->mem_unmap = (GstMemoryUnmapFunction) - gst_vaapi_video_memory_unmap; - base_allocator->mem_copy = (GstMemoryCopyFunction) - gst_vaapi_video_memory_copy; - base_allocator->mem_share = (GstMemoryShareFunction) - gst_vaapi_video_memory_share; - base_allocator->mem_is_span = (GstMemoryIsSpanFunction) - gst_vaapi_video_memory_is_span; + base_allocator->mem_type = GST_VAAPI_VIDEO_MEMORY_NAME; + base_allocator->mem_map = (GstMemoryMapFunction) + gst_vaapi_video_memory_map; + base_allocator->mem_unmap = (GstMemoryUnmapFunction) + gst_vaapi_video_memory_unmap; + base_allocator->mem_copy = (GstMemoryCopyFunction) + gst_vaapi_video_memory_copy; + base_allocator->mem_share = (GstMemoryShareFunction) + gst_vaapi_video_memory_share; + base_allocator->mem_is_span = (GstMemoryIsSpanFunction) + gst_vaapi_video_memory_is_span; } static gboolean -gst_video_info_update_from_image(GstVideoInfo *vip, GstVaapiImage *image) +gst_video_info_update_from_image (GstVideoInfo * vip, GstVaapiImage * image) { - GstVideoFormat format; - const guchar *data; - guint i, num_planes, data_size, width, height; + GstVideoFormat format; + const guchar *data; + guint i, num_planes, data_size, width, height; - /* Reset format from image */ - format = gst_vaapi_image_get_format(image); - gst_vaapi_image_get_size(image, &width, &height); - gst_video_info_set_format(vip, format, width, height); + /* Reset format from image */ + format = gst_vaapi_image_get_format (image); + gst_vaapi_image_get_size (image, &width, &height); + gst_video_info_set_format (vip, format, width, height); - num_planes = gst_vaapi_image_get_plane_count(image); - g_return_val_if_fail(num_planes == GST_VIDEO_INFO_N_PLANES(vip), FALSE); + num_planes = gst_vaapi_image_get_plane_count (image); + g_return_val_if_fail (num_planes == GST_VIDEO_INFO_N_PLANES (vip), FALSE); - /* Determine the base data pointer */ - data = get_image_data(image); - g_return_val_if_fail(data != NULL, FALSE); - data_size = gst_vaapi_image_get_data_size(image); + /* Determine the base data pointer */ + data = get_image_data (image); + g_return_val_if_fail (data != NULL, FALSE); + data_size = gst_vaapi_image_get_data_size (image); - /* Check that we don't have disjoint planes */ - for (i = 0; i < num_planes; i++) { - const guchar * const plane = gst_vaapi_image_get_plane(image, i); - if (plane - data > data_size) - return FALSE; - } + /* Check that we don't have disjoint planes */ + for (i = 0; i < num_planes; i++) { + const guchar *const plane = gst_vaapi_image_get_plane (image, i); + if (plane - data > data_size) + return FALSE; + } - /* Update GstVideoInfo structure */ - for (i = 0; i < num_planes; i++) { - const guchar * const plane = gst_vaapi_image_get_plane(image, i); - GST_VIDEO_INFO_PLANE_OFFSET(vip, i) = plane - data; - GST_VIDEO_INFO_PLANE_STRIDE(vip, i) = - gst_vaapi_image_get_pitch(image, i); - } - GST_VIDEO_INFO_SIZE(vip) = data_size; - return TRUE; + /* Update GstVideoInfo structure */ + for (i = 0; i < num_planes; i++) { + const guchar *const plane = gst_vaapi_image_get_plane (image, i); + GST_VIDEO_INFO_PLANE_OFFSET (vip, i) = plane - data; + GST_VIDEO_INFO_PLANE_STRIDE (vip, i) = gst_vaapi_image_get_pitch (image, i); + } + GST_VIDEO_INFO_SIZE (vip) = data_size; + return TRUE; } GstAllocator * -gst_vaapi_video_allocator_new(GstVaapiDisplay *display, const GstVideoInfo *vip) +gst_vaapi_video_allocator_new (GstVaapiDisplay * display, + const GstVideoInfo * vip) { - GstVaapiVideoAllocator *allocator; - GstVaapiSurface *surface; - GstVaapiImage *image; + GstVaapiVideoAllocator *allocator; + GstVaapiSurface *surface; + GstVaapiImage *image; - g_return_val_if_fail(display != NULL, NULL); - g_return_val_if_fail(vip != NULL, NULL); + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (vip != NULL, NULL); - allocator = g_object_new(GST_VAAPI_TYPE_VIDEO_ALLOCATOR, NULL); - if (!allocator) - return NULL; + allocator = g_object_new (GST_VAAPI_TYPE_VIDEO_ALLOCATOR, NULL); + if (!allocator) + return NULL; - allocator->video_info = *vip; - gst_video_info_set_format(&allocator->surface_info, GST_VIDEO_FORMAT_NV12, - GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + allocator->video_info = *vip; + gst_video_info_set_format (&allocator->surface_info, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); - if (GST_VIDEO_INFO_FORMAT(vip) != GST_VIDEO_FORMAT_ENCODED) { - image = NULL; - do { - surface = new_surface(display, vip); - if (!surface) - break; - image = gst_vaapi_surface_derive_image(surface); - if (!image) - break; - if (!gst_vaapi_image_map(image)) - break; - allocator->has_direct_rendering = gst_video_info_update_from_image( - &allocator->surface_info, image); - if (GST_VAAPI_IMAGE_FORMAT(image) != GST_VIDEO_INFO_FORMAT(vip)) - allocator->has_direct_rendering = FALSE; - if (USE_NATIVE_FORMATS) - allocator->has_direct_rendering = FALSE; - gst_vaapi_image_unmap(image); - GST_INFO("has direct-rendering for %s surfaces: %s", - GST_VIDEO_INFO_FORMAT_STRING(&allocator->surface_info), - allocator->has_direct_rendering ? "yes" : "no"); - } while (0); - if (surface) - gst_vaapi_object_unref(surface); - if (image) - gst_vaapi_object_unref(image); - } + if (GST_VIDEO_INFO_FORMAT (vip) != GST_VIDEO_FORMAT_ENCODED) { + image = NULL; + do { + surface = new_surface (display, vip); + if (!surface) + break; + image = gst_vaapi_surface_derive_image (surface); + if (!image) + break; + if (!gst_vaapi_image_map (image)) + break; + allocator->has_direct_rendering = + gst_video_info_update_from_image (&allocator->surface_info, image); + if (GST_VAAPI_IMAGE_FORMAT (image) != GST_VIDEO_INFO_FORMAT (vip)) + allocator->has_direct_rendering = FALSE; + if (USE_NATIVE_FORMATS) + allocator->has_direct_rendering = FALSE; + gst_vaapi_image_unmap (image); + GST_INFO ("has direct-rendering for %s surfaces: %s", + GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info), + allocator->has_direct_rendering ? "yes" : "no"); + } while (0); + if (surface) + gst_vaapi_object_unref (surface); + if (image) + gst_vaapi_object_unref (image); + } - allocator->surface_pool = gst_vaapi_surface_pool_new(display, - &allocator->surface_info); - if (!allocator->surface_pool) - goto error_create_surface_pool; + allocator->surface_pool = gst_vaapi_surface_pool_new (display, + &allocator->surface_info); + if (!allocator->surface_pool) + goto error_create_surface_pool; - allocator->image_info = *vip; - if (GST_VIDEO_INFO_FORMAT(vip) == GST_VIDEO_FORMAT_ENCODED) - gst_video_info_set_format(&allocator->image_info, GST_VIDEO_FORMAT_I420, - GST_VIDEO_INFO_WIDTH(vip), GST_VIDEO_INFO_HEIGHT(vip)); + allocator->image_info = *vip; + if (GST_VIDEO_INFO_FORMAT (vip) == GST_VIDEO_FORMAT_ENCODED) + gst_video_info_set_format (&allocator->image_info, GST_VIDEO_FORMAT_I420, + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); - if (allocator->has_direct_rendering) - allocator->image_info = allocator->surface_info; - else { - do { - image = new_image(display, &allocator->image_info); - if (!image) - break; - if (!gst_vaapi_image_map(image)) - break; - gst_video_info_update_from_image(&allocator->image_info, image); - gst_vaapi_image_unmap(image); - } while (0); - gst_vaapi_object_unref(image); - } + if (allocator->has_direct_rendering) + allocator->image_info = allocator->surface_info; + else { + do { + image = new_image (display, &allocator->image_info); + if (!image) + break; + if (!gst_vaapi_image_map (image)) + break; + gst_video_info_update_from_image (&allocator->image_info, image); + gst_vaapi_image_unmap (image); + } while (0); + gst_vaapi_object_unref (image); + } - allocator->image_pool = gst_vaapi_image_pool_new(display, - &allocator->image_info); - if (!allocator->image_pool) - goto error_create_image_pool; - return GST_ALLOCATOR_CAST(allocator); + allocator->image_pool = gst_vaapi_image_pool_new (display, + &allocator->image_info); + if (!allocator->image_pool) + goto error_create_image_pool; + return GST_ALLOCATOR_CAST (allocator); - /* ERRORS */ + /* ERRORS */ error_create_surface_pool: - { - GST_ERROR("failed to allocate VA surface pool"); - gst_object_unref(allocator); - return NULL; - } + { + GST_ERROR ("failed to allocate VA surface pool"); + gst_object_unref (allocator); + return NULL; + } error_create_image_pool: - { - GST_ERROR("failed to allocate VA image pool"); - gst_object_unref(allocator); - return NULL; - } + { + GST_ERROR ("failed to allocate VA image pool"); + gst_object_unref (allocator); + return NULL; + } } diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 587d44314a..74af3681e4 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -31,16 +31,16 @@ G_BEGIN_DECLS -typedef struct _GstVaapiVideoMemory GstVaapiVideoMemory; -typedef struct _GstVaapiVideoAllocator GstVaapiVideoAllocator; -typedef struct _GstVaapiVideoAllocatorClass GstVaapiVideoAllocatorClass; +typedef struct _GstVaapiVideoMemory GstVaapiVideoMemory; +typedef struct _GstVaapiVideoAllocator GstVaapiVideoAllocator; +typedef struct _GstVaapiVideoAllocatorClass GstVaapiVideoAllocatorClass; /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoMemory --- */ /* ------------------------------------------------------------------------ */ #define GST_VAAPI_VIDEO_MEMORY_CAST(mem) \ - ((GstVaapiVideoMemory *)(mem)) + ((GstVaapiVideoMemory *) (mem)) #define GST_VAAPI_VIDEO_MEMORY_NAME "GstVaapiVideoMemory" @@ -59,10 +59,11 @@ typedef struct _GstVaapiVideoAllocatorClass GstVaapiVideoAllocatorClass; * * The set of all #GstVaapiVideoMemory map types. */ -typedef enum { - GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE = 1, - GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR, - GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR +typedef enum +{ + GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE = 1, + GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR, + GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR } GstVaapiVideoMemoryMapType; /** @@ -71,56 +72,54 @@ typedef enum { * A VA video memory object holder, including VA surfaces, images and * proxies. */ -struct _GstVaapiVideoMemory { - GstMemory parent_instance; +struct _GstVaapiVideoMemory +{ + GstMemory parent_instance; - /*< private >*/ - GstVaapiSurfaceProxy *proxy; - const GstVideoInfo *surface_info; - GstVaapiSurface *surface; - const GstVideoInfo *image_info; - GstVaapiImage *image; - GstVaapiVideoMeta *meta; - guint map_type; - gint map_count; - gboolean use_direct_rendering; + /*< private >*/ + GstVaapiSurfaceProxy *proxy; + const GstVideoInfo *surface_info; + GstVaapiSurface *surface; + const GstVideoInfo *image_info; + GstVaapiImage *image; + GstVaapiVideoMeta *meta; + guint map_type; + gint map_count; + gboolean use_direct_rendering; }; G_GNUC_INTERNAL GstMemory * -gst_vaapi_video_memory_new(GstAllocator *allocator, GstVaapiVideoMeta *meta); +gst_vaapi_video_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta); G_GNUC_INTERNAL gboolean -gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane, - GstMapInfo *info, gpointer *data, gint *stride, GstMapFlags flags); +gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, + GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags); G_GNUC_INTERNAL gboolean -gst_video_meta_unmap_vaapi_memory(GstVideoMeta *meta, guint plane, - GstMapInfo *info); +gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane, + GstMapInfo * info); G_GNUC_INTERNAL void -gst_vaapi_video_memory_reset_surface(GstVaapiVideoMemory *mem); +gst_vaapi_video_memory_reset_surface (GstVaapiVideoMemory * mem); /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoAllocator --- */ /* ------------------------------------------------------------------------ */ #define GST_VAAPI_VIDEO_ALLOCATOR_CAST(allocator) \ - ((GstVaapiVideoAllocator *)(allocator)) + ((GstVaapiVideoAllocator *) (allocator)) #define GST_VAAPI_TYPE_VIDEO_ALLOCATOR \ - (gst_vaapi_video_allocator_get_type()) - -#define GST_VAAPI_VIDEO_ALLOCATOR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_VIDEO_ALLOCATOR, \ - GstVaapiVideoAllocator)) - + (gst_vaapi_video_allocator_get_type ()) +#define GST_VAAPI_VIDEO_ALLOCATOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_ALLOCATOR, \ + GstVaapiVideoAllocator)) #define GST_VAAPI_IS_VIDEO_ALLOCATOR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_ALLOCATOR)) + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_ALLOCATOR)) #define GST_VAAPI_VIDEO_ALLOCATOR_NAME "GstVaapiVideoAllocator" @@ -129,16 +128,17 @@ gst_vaapi_video_memory_reset_surface(GstVaapiVideoMemory *mem); * * A VA video memory allocator object. */ -struct _GstVaapiVideoAllocator { - GstAllocator parent_instance; +struct _GstVaapiVideoAllocator +{ + GstAllocator parent_instance; - /*< private >*/ - GstVideoInfo video_info; - GstVideoInfo surface_info; - GstVaapiVideoPool *surface_pool; - GstVideoInfo image_info; - GstVaapiVideoPool *image_pool; - gboolean has_direct_rendering; + /*< private >*/ + GstVideoInfo video_info; + GstVideoInfo surface_info; + GstVaapiVideoPool *surface_pool; + GstVideoInfo image_info; + GstVaapiVideoPool *image_pool; + gboolean has_direct_rendering; }; /** @@ -146,18 +146,19 @@ struct _GstVaapiVideoAllocator { * * A VA video memory allocator class. */ -struct _GstVaapiVideoAllocatorClass { - GstAllocatorClass parent_class; +struct _GstVaapiVideoAllocatorClass +{ + GstAllocatorClass parent_class; }; G_GNUC_INTERNAL GType -gst_vaapi_video_allocator_get_type(void) G_GNUC_CONST; +gst_vaapi_video_allocator_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstAllocator * -gst_vaapi_video_allocator_new(GstVaapiDisplay *display, - const GstVideoInfo *vip); +gst_vaapi_video_allocator_new (GstVaapiDisplay * display, + const GstVideoInfo * vip); G_END_DECLS diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index 7b4bc2d834..d67f458c26 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -33,169 +33,169 @@ #include "gstvaapivideometa.h" #define GST_VAAPI_VIDEO_META(obj) \ - ((GstVaapiVideoMeta *)(obj)) - + ((GstVaapiVideoMeta *) (obj)) #define GST_VAAPI_IS_VIDEO_META(obj) \ - (GST_VAAPI_VIDEO_META(obj) != NULL) + (GST_VAAPI_VIDEO_META (obj) != NULL) -struct _GstVaapiVideoMeta { - gint ref_count; - GstVaapiDisplay *display; - GstVaapiVideoPool *image_pool; - GstVaapiImage *image; - GstVaapiSurfaceProxy *proxy; - GFunc converter; - guint render_flags; - GstVaapiRectangle render_rect; - guint has_render_rect : 1; +struct _GstVaapiVideoMeta +{ + gint ref_count; + GstVaapiDisplay *display; + GstVaapiVideoPool *image_pool; + GstVaapiImage *image; + GstVaapiSurfaceProxy *proxy; + GFunc converter; + guint render_flags; + GstVaapiRectangle render_rect; + guint has_render_rect:1; }; static inline void -set_display(GstVaapiVideoMeta *meta, GstVaapiDisplay *display) +set_display (GstVaapiVideoMeta * meta, GstVaapiDisplay * display) { - gst_vaapi_display_replace(&meta->display, display); + gst_vaapi_display_replace (&meta->display, display); } static inline void -set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image) +set_image (GstVaapiVideoMeta * meta, GstVaapiImage * image) { - meta->image = gst_vaapi_object_ref(image); - set_display(meta, gst_vaapi_object_get_display(GST_VAAPI_OBJECT(image))); + meta->image = gst_vaapi_object_ref (image); + set_display (meta, gst_vaapi_object_get_display (GST_VAAPI_OBJECT (image))); } static gboolean -set_image_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool) +set_image_from_pool (GstVaapiVideoMeta * meta, GstVaapiVideoPool * pool) { - GstVaapiImage *image; + GstVaapiImage *image; - image = gst_vaapi_video_pool_get_object(pool); - if (!image) - return FALSE; + image = gst_vaapi_video_pool_get_object (pool); + if (!image) + return FALSE; - set_image(meta, image); - meta->image_pool = gst_vaapi_video_pool_ref(pool); - return TRUE; + set_image (meta, image); + meta->image_pool = gst_vaapi_video_pool_ref (pool); + return TRUE; } static gboolean -set_surface_proxy(GstVaapiVideoMeta *meta, GstVaapiSurfaceProxy *proxy) +set_surface_proxy (GstVaapiVideoMeta * meta, GstVaapiSurfaceProxy * proxy) { - GstVaapiSurface *surface; + GstVaapiSurface *surface; - surface = GST_VAAPI_SURFACE_PROXY_SURFACE(proxy); - if (!surface) - return FALSE; + surface = GST_VAAPI_SURFACE_PROXY_SURFACE (proxy); + if (!surface) + return FALSE; - meta->proxy = gst_vaapi_surface_proxy_ref(proxy); - set_display(meta, gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface))); - return TRUE; + meta->proxy = gst_vaapi_surface_proxy_ref (proxy); + set_display (meta, gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface))); + return TRUE; } static gboolean -set_surface_proxy_from_pool(GstVaapiVideoMeta *meta, GstVaapiVideoPool *pool) +set_surface_proxy_from_pool (GstVaapiVideoMeta * meta, GstVaapiVideoPool * pool) { - GstVaapiSurfaceProxy *proxy; - gboolean success; + GstVaapiSurfaceProxy *proxy; + gboolean success; - proxy = gst_vaapi_surface_proxy_new_from_pool(GST_VAAPI_SURFACE_POOL(pool)); - if (!proxy) - return FALSE; + proxy = gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL (pool)); + if (!proxy) + return FALSE; - success = set_surface_proxy(meta, proxy); - gst_vaapi_surface_proxy_unref(proxy); - return success; + success = set_surface_proxy (meta, proxy); + gst_vaapi_surface_proxy_unref (proxy); + return success; } static void -gst_vaapi_video_meta_destroy_image(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_destroy_image (GstVaapiVideoMeta * meta) { - if (meta->image) { - if (meta->image_pool) - gst_vaapi_video_pool_put_object(meta->image_pool, meta->image); - gst_vaapi_object_unref(meta->image); - meta->image = NULL; - } - gst_vaapi_video_pool_replace(&meta->image_pool, NULL); + if (meta->image) { + if (meta->image_pool) + gst_vaapi_video_pool_put_object (meta->image_pool, meta->image); + gst_vaapi_object_unref (meta->image); + meta->image = NULL; + } + gst_vaapi_video_pool_replace (&meta->image_pool, NULL); } static inline void -gst_vaapi_video_meta_destroy_proxy(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_destroy_proxy (GstVaapiVideoMeta * meta) { - gst_vaapi_surface_proxy_replace(&meta->proxy, NULL); + gst_vaapi_surface_proxy_replace (&meta->proxy, NULL); } #if !GST_CHECK_VERSION(1,0,0) -#define GST_VAAPI_TYPE_VIDEO_META gst_vaapi_video_meta_get_type() +#define GST_VAAPI_TYPE_VIDEO_META gst_vaapi_video_meta_get_type () static GType -gst_vaapi_video_meta_get_type(void) +gst_vaapi_video_meta_get_type (void) { - static gsize g_type; + static gsize g_type; - if (g_once_init_enter(&g_type)) { - GType type; - type = g_boxed_type_register_static("GstVaapiVideoMeta", - (GBoxedCopyFunc)gst_vaapi_video_meta_ref, - (GBoxedFreeFunc)gst_vaapi_video_meta_unref); - g_once_init_leave(&g_type, type); - } - return (GType)g_type; + if (g_once_init_enter (&g_type)) { + GType type; + type = g_boxed_type_register_static ("GstVaapiVideoMeta", + (GBoxedCopyFunc) gst_vaapi_video_meta_ref, + (GBoxedFreeFunc) gst_vaapi_video_meta_unref); + g_once_init_leave (&g_type, type); + } + return (GType) g_type; } #endif static void -gst_vaapi_video_meta_finalize(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_finalize (GstVaapiVideoMeta * meta) { - gst_vaapi_video_meta_destroy_image(meta); - gst_vaapi_video_meta_destroy_proxy(meta); - gst_vaapi_display_replace(&meta->display, NULL); + gst_vaapi_video_meta_destroy_image (meta); + gst_vaapi_video_meta_destroy_proxy (meta); + gst_vaapi_display_replace (&meta->display, NULL); } static void -gst_vaapi_video_meta_init(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_init (GstVaapiVideoMeta * meta) { - meta->ref_count = 1; - meta->display = NULL; - meta->image_pool = NULL; - meta->image = NULL; - meta->proxy = NULL; - meta->converter = NULL; - meta->render_flags = 0; - meta->has_render_rect = FALSE; + meta->ref_count = 1; + meta->display = NULL; + meta->image_pool = NULL; + meta->image = NULL; + meta->proxy = NULL; + meta->converter = NULL; + meta->render_flags = 0; + meta->has_render_rect = FALSE; } static inline GstVaapiVideoMeta * -_gst_vaapi_video_meta_create(void) +_gst_vaapi_video_meta_create (void) { - return g_slice_new(GstVaapiVideoMeta); + return g_slice_new (GstVaapiVideoMeta); } static inline void -_gst_vaapi_video_meta_destroy(GstVaapiVideoMeta *meta) +_gst_vaapi_video_meta_destroy (GstVaapiVideoMeta * meta) { - g_slice_free1(sizeof(*meta), meta); + g_slice_free1 (sizeof (*meta), meta); } static inline GstVaapiVideoMeta * -_gst_vaapi_video_meta_new(void) +_gst_vaapi_video_meta_new (void) { - GstVaapiVideoMeta *meta; + GstVaapiVideoMeta *meta; - meta = _gst_vaapi_video_meta_create(); - if (!meta) - return NULL; - gst_vaapi_video_meta_init(meta); - return meta; + meta = _gst_vaapi_video_meta_create (); + if (!meta) + return NULL; + gst_vaapi_video_meta_init (meta); + return meta; } static inline void -_gst_vaapi_video_meta_free(GstVaapiVideoMeta *meta) +_gst_vaapi_video_meta_free (GstVaapiVideoMeta * meta) { - g_atomic_int_inc(&meta->ref_count); + g_atomic_int_inc (&meta->ref_count); - gst_vaapi_video_meta_finalize(meta); + gst_vaapi_video_meta_finalize (meta); - if (G_LIKELY(g_atomic_int_dec_and_test(&meta->ref_count))) - _gst_vaapi_video_meta_destroy(meta); + if (G_LIKELY (g_atomic_int_dec_and_test (&meta->ref_count))) + _gst_vaapi_video_meta_destroy (meta); } /** @@ -209,32 +209,31 @@ _gst_vaapi_video_meta_free(GstVaapiVideoMeta *meta) * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL on error */ GstVaapiVideoMeta * -gst_vaapi_video_meta_copy(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_copy (GstVaapiVideoMeta * meta) { - GstVaapiVideoMeta *copy; + GstVaapiVideoMeta *copy; - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); - if (meta->image_pool) - return NULL; + if (meta->image_pool) + return NULL; - copy = _gst_vaapi_video_meta_create(); - if (!copy) - return NULL; + copy = _gst_vaapi_video_meta_create (); + if (!copy) + return NULL; - copy->ref_count = 1; - copy->display = gst_vaapi_display_ref(meta->display); - copy->image_pool = NULL; - copy->image = meta->image ? gst_vaapi_object_ref(meta->image) : NULL; - copy->proxy = meta->proxy ? - gst_vaapi_surface_proxy_copy(meta->proxy) : NULL; - copy->converter = meta->converter; - copy->render_flags = meta->render_flags; + copy->ref_count = 1; + copy->display = gst_vaapi_display_ref (meta->display); + copy->image_pool = NULL; + copy->image = meta->image ? gst_vaapi_object_ref (meta->image) : NULL; + copy->proxy = meta->proxy ? gst_vaapi_surface_proxy_copy (meta->proxy) : NULL; + copy->converter = meta->converter; + copy->render_flags = meta->render_flags; - copy->has_render_rect = meta->has_render_rect; - if (copy->has_render_rect) - copy->render_rect = meta->render_rect; - return copy; + copy->has_render_rect = meta->has_render_rect; + if (copy->has_render_rect) + copy->render_rect = meta->render_rect; + return copy; } /** @@ -251,18 +250,18 @@ gst_vaapi_video_meta_copy(GstVaapiVideoMeta *meta) * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL or error */ GstVaapiVideoMeta * -gst_vaapi_video_meta_new(GstVaapiDisplay *display) +gst_vaapi_video_meta_new (GstVaapiDisplay * display) { - GstVaapiVideoMeta *meta; + GstVaapiVideoMeta *meta; - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail (display != NULL, NULL); - meta = _gst_vaapi_video_meta_new(); - if (G_UNLIKELY(!meta)) - return NULL; + meta = _gst_vaapi_video_meta_new (); + if (G_UNLIKELY (!meta)) + return NULL; - set_display(meta, display); - return meta; + set_display (meta, display); + return meta; } /** @@ -279,37 +278,37 @@ gst_vaapi_video_meta_new(GstVaapiDisplay *display) * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL on error */ GstVaapiVideoMeta * -gst_vaapi_video_meta_new_from_pool(GstVaapiVideoPool *pool) +gst_vaapi_video_meta_new_from_pool (GstVaapiVideoPool * pool) { - GstVaapiVideoMeta *meta; - GstVaapiVideoPoolObjectType object_type; + GstVaapiVideoMeta *meta; + GstVaapiVideoPoolObjectType object_type; - g_return_val_if_fail(pool != NULL, NULL); + g_return_val_if_fail (pool != NULL, NULL); - meta = _gst_vaapi_video_meta_new(); - if (G_UNLIKELY(!meta)) - return NULL; + meta = _gst_vaapi_video_meta_new (); + if (G_UNLIKELY (!meta)) + return NULL; - object_type = gst_vaapi_video_pool_get_object_type(pool); - switch (object_type) { + object_type = gst_vaapi_video_pool_get_object_type (pool); + switch (object_type) { case GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE: - if (!set_image_from_pool(meta, pool)) - goto error; - break; - case GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE: - if (!set_surface_proxy_from_pool(meta, pool)) - goto error; - break; - default: - GST_ERROR("unsupported video buffer pool of type %d", object_type); + if (!set_image_from_pool (meta, pool)) goto error; - } - set_display(meta, gst_vaapi_video_pool_get_display(pool)); - return meta; + break; + case GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE: + if (!set_surface_proxy_from_pool (meta, pool)) + goto error; + break; + default: + GST_ERROR ("unsupported video buffer pool of type %d", object_type); + goto error; + } + set_display (meta, gst_vaapi_video_pool_get_display (pool)); + return meta; error: - gst_vaapi_video_meta_unref(meta); - return NULL; + gst_vaapi_video_meta_unref (meta); + return NULL; } /** @@ -325,18 +324,18 @@ error: * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL on error */ GstVaapiVideoMeta * -gst_vaapi_video_meta_new_with_image(GstVaapiImage *image) +gst_vaapi_video_meta_new_with_image (GstVaapiImage * image) { - GstVaapiVideoMeta *meta; + GstVaapiVideoMeta *meta; - g_return_val_if_fail(image != NULL, NULL); + g_return_val_if_fail (image != NULL, NULL); - meta = _gst_vaapi_video_meta_new(); - if (G_UNLIKELY(!meta)) - return NULL; + meta = _gst_vaapi_video_meta_new (); + if (G_UNLIKELY (!meta)) + return NULL; - gst_vaapi_video_meta_set_image(meta, image); - return meta; + gst_vaapi_video_meta_set_image (meta, image); + return meta; } /** @@ -352,18 +351,18 @@ gst_vaapi_video_meta_new_with_image(GstVaapiImage *image) * Return value: the newly allocated #GstVaapiVideoMeta, or %NULL on error */ GstVaapiVideoMeta * -gst_vaapi_video_meta_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) +gst_vaapi_video_meta_new_with_surface_proxy (GstVaapiSurfaceProxy * proxy) { - GstVaapiVideoMeta *meta; + GstVaapiVideoMeta *meta; - g_return_val_if_fail(proxy != NULL, NULL); + g_return_val_if_fail (proxy != NULL, NULL); - meta = _gst_vaapi_video_meta_new(); - if (G_UNLIKELY(!meta)) - return NULL; + meta = _gst_vaapi_video_meta_new (); + if (G_UNLIKELY (!meta)) + return NULL; - gst_vaapi_video_meta_set_surface_proxy(meta, proxy); - return meta; + gst_vaapi_video_meta_set_surface_proxy (meta, proxy); + return meta; } /** @@ -375,12 +374,12 @@ gst_vaapi_video_meta_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy) * Returns: The same @meta argument */ GstVaapiVideoMeta * -gst_vaapi_video_meta_ref(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_ref (GstVaapiVideoMeta * meta) { - g_return_val_if_fail(meta != NULL, NULL); + g_return_val_if_fail (meta != NULL, NULL); - g_atomic_int_inc(&meta->ref_count); - return meta; + g_atomic_int_inc (&meta->ref_count); + return meta; } /** @@ -391,13 +390,13 @@ gst_vaapi_video_meta_ref(GstVaapiVideoMeta *meta) * the reference count reaches zero, the object will be free'd. */ void -gst_vaapi_video_meta_unref(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_unref (GstVaapiVideoMeta * meta) { - g_return_if_fail(meta != NULL); - g_return_if_fail(meta->ref_count > 0); + g_return_if_fail (meta != NULL); + g_return_if_fail (meta->ref_count > 0); - if (g_atomic_int_dec_and_test(&meta->ref_count)) - _gst_vaapi_video_meta_free(meta); + if (g_atomic_int_dec_and_test (&meta->ref_count)) + _gst_vaapi_video_meta_free (meta); } /** @@ -410,27 +409,27 @@ gst_vaapi_video_meta_unref(GstVaapiVideoMeta *meta) * object. However, @new_meta can be NULL. */ void -gst_vaapi_video_meta_replace(GstVaapiVideoMeta **old_meta_ptr, - GstVaapiVideoMeta *new_meta) +gst_vaapi_video_meta_replace (GstVaapiVideoMeta ** old_meta_ptr, + GstVaapiVideoMeta * new_meta) { - GstVaapiVideoMeta *old_meta; + GstVaapiVideoMeta *old_meta; - g_return_if_fail(old_meta_ptr != NULL); + g_return_if_fail (old_meta_ptr != NULL); - old_meta = g_atomic_pointer_get((gpointer *)old_meta_ptr); + old_meta = g_atomic_pointer_get ((gpointer *) old_meta_ptr); - if (old_meta == new_meta) - return; + if (old_meta == new_meta) + return; - if (new_meta) - gst_vaapi_video_meta_ref(new_meta); + if (new_meta) + gst_vaapi_video_meta_ref (new_meta); - while (!g_atomic_pointer_compare_and_exchange((gpointer *)old_meta_ptr, - old_meta, new_meta)) - old_meta = g_atomic_pointer_get((gpointer *)old_meta_ptr); + while (!g_atomic_pointer_compare_and_exchange ((gpointer *) old_meta_ptr, + old_meta, new_meta)) + old_meta = g_atomic_pointer_get ((gpointer *) old_meta_ptr); - if (old_meta) - gst_vaapi_video_meta_unref(old_meta); + if (old_meta) + gst_vaapi_video_meta_unref (old_meta); } /** @@ -444,11 +443,11 @@ gst_vaapi_video_meta_replace(GstVaapiVideoMeta **old_meta_ptr, * Return value: the #GstVaapiDisplay the @meta is bound to */ GstVaapiDisplay * -gst_vaapi_video_meta_get_display(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_get_display (GstVaapiVideoMeta * meta) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); - return meta->display; + return meta->display; } /** @@ -463,11 +462,11 @@ gst_vaapi_video_meta_get_display(GstVaapiVideoMeta *meta) * there is none */ GstVaapiImage * -gst_vaapi_video_meta_get_image(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_get_image (GstVaapiVideoMeta * meta) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); - return meta->image; + return meta->image; } /** @@ -480,14 +479,14 @@ gst_vaapi_video_meta_get_image(GstVaapiVideoMeta *meta) * pool and the pool is also released. */ void -gst_vaapi_video_meta_set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image) +gst_vaapi_video_meta_set_image (GstVaapiVideoMeta * meta, GstVaapiImage * image) { - g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + g_return_if_fail (GST_VAAPI_IS_VIDEO_META (meta)); - gst_vaapi_video_meta_destroy_image(meta); + gst_vaapi_video_meta_destroy_image (meta); - if (image) - set_image(meta, image); + if (image) + set_image (meta, image); } /** @@ -502,17 +501,17 @@ gst_vaapi_video_meta_set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image) * Return value: %TRUE on success */ gboolean -gst_vaapi_video_meta_set_image_from_pool(GstVaapiVideoMeta *meta, - GstVaapiVideoPool *pool) +gst_vaapi_video_meta_set_image_from_pool (GstVaapiVideoMeta * meta, + GstVaapiVideoPool * pool) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), FALSE); - g_return_val_if_fail(pool != NULL, FALSE); - g_return_val_if_fail(gst_vaapi_video_pool_get_object_type(pool) == - GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), FALSE); + g_return_val_if_fail (pool != NULL, FALSE); + g_return_val_if_fail (gst_vaapi_video_pool_get_object_type (pool) == + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE, FALSE); - gst_vaapi_video_meta_destroy_image(meta); + gst_vaapi_video_meta_destroy_image (meta); - return set_image_from_pool(meta, pool); + return set_image_from_pool (meta, pool); } /** @@ -527,11 +526,11 @@ gst_vaapi_video_meta_set_image_from_pool(GstVaapiVideoMeta *meta, * there is none */ GstVaapiSurface * -gst_vaapi_video_meta_get_surface(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_get_surface (GstVaapiVideoMeta * meta) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); - return meta->proxy ? GST_VAAPI_SURFACE_PROXY_SURFACE(meta->proxy) : NULL; + return meta->proxy ? GST_VAAPI_SURFACE_PROXY_SURFACE (meta->proxy) : NULL; } /** @@ -546,11 +545,11 @@ gst_vaapi_video_meta_get_surface(GstVaapiVideoMeta *meta) * %NULL if there is none */ GstVaapiSurfaceProxy * -gst_vaapi_video_meta_get_surface_proxy(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_get_surface_proxy (GstVaapiVideoMeta * meta) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); - return meta->proxy; + return meta->proxy; } /** @@ -563,23 +562,23 @@ gst_vaapi_video_meta_get_surface_proxy(GstVaapiVideoMeta *meta) * parent pool and the pool is also released. */ void -gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, - GstVaapiSurfaceProxy *proxy) +gst_vaapi_video_meta_set_surface_proxy (GstVaapiVideoMeta * meta, + GstVaapiSurfaceProxy * proxy) { - const GstVaapiRectangle *crop_rect; + const GstVaapiRectangle *crop_rect; - g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + g_return_if_fail (GST_VAAPI_IS_VIDEO_META (meta)); - gst_vaapi_video_meta_destroy_proxy(meta); + gst_vaapi_video_meta_destroy_proxy (meta); - if (proxy) { - if (!set_surface_proxy(meta, proxy)) - return; + if (proxy) { + if (!set_surface_proxy (meta, proxy)) + return; - crop_rect = gst_vaapi_surface_proxy_get_crop_rect(proxy); - if (crop_rect) - gst_vaapi_video_meta_set_render_rect(meta, crop_rect); - } + crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy); + if (crop_rect) + gst_vaapi_video_meta_set_render_rect (meta, crop_rect); + } } /** @@ -591,11 +590,11 @@ gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, * Return value: the surface converter associated with the video @meta */ GFunc -gst_vaapi_video_meta_get_surface_converter(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_get_surface_converter (GstVaapiVideoMeta * meta) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); - return meta->converter; + return meta->converter; } /** @@ -606,11 +605,12 @@ gst_vaapi_video_meta_get_surface_converter(GstVaapiVideoMeta *meta) * Sets the @meta surface converter function to @func. */ void -gst_vaapi_video_meta_set_surface_converter(GstVaapiVideoMeta *meta, GFunc func) +gst_vaapi_video_meta_set_surface_converter (GstVaapiVideoMeta * meta, + GFunc func) { - g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + g_return_if_fail (GST_VAAPI_IS_VIDEO_META (meta)); - meta->converter = func; + meta->converter = func; } /** @@ -622,12 +622,12 @@ gst_vaapi_video_meta_set_surface_converter(GstVaapiVideoMeta *meta, GFunc func) * Return value: a combination for #GstVaapiSurfaceRenderFlags */ guint -gst_vaapi_video_meta_get_render_flags(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_get_render_flags (GstVaapiVideoMeta * meta) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), 0); - g_return_val_if_fail(meta->proxy != NULL, 0); + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), 0); + g_return_val_if_fail (meta->proxy != NULL, 0); - return meta->render_flags; + return meta->render_flags; } /** @@ -638,12 +638,12 @@ gst_vaapi_video_meta_get_render_flags(GstVaapiVideoMeta *meta) * Sets #GstVaapiSurfaceRenderFlags to the @meta. */ void -gst_vaapi_video_meta_set_render_flags(GstVaapiVideoMeta *meta, guint flags) +gst_vaapi_video_meta_set_render_flags (GstVaapiVideoMeta * meta, guint flags) { - g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); - g_return_if_fail(meta->proxy != NULL); + g_return_if_fail (GST_VAAPI_IS_VIDEO_META (meta)); + g_return_if_fail (meta->proxy != NULL); - meta->render_flags = flags; + meta->render_flags = flags; } /** @@ -655,13 +655,13 @@ gst_vaapi_video_meta_set_render_flags(GstVaapiVideoMeta *meta, guint flags) * Return value: render rectangle associated with the video meta. */ const GstVaapiRectangle * -gst_vaapi_video_meta_get_render_rect(GstVaapiVideoMeta *meta) +gst_vaapi_video_meta_get_render_rect (GstVaapiVideoMeta * meta) { - g_return_val_if_fail(GST_VAAPI_IS_VIDEO_META(meta), NULL); + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); - if (!meta->has_render_rect) - return NULL; - return &meta->render_rect; + if (!meta->has_render_rect) + return NULL; + return &meta->render_rect; } /** @@ -672,171 +672,171 @@ gst_vaapi_video_meta_get_render_rect(GstVaapiVideoMeta *meta) * Sets the render rectangle @rect to the @meta. */ void -gst_vaapi_video_meta_set_render_rect(GstVaapiVideoMeta *meta, - const GstVaapiRectangle *rect) +gst_vaapi_video_meta_set_render_rect (GstVaapiVideoMeta * meta, + const GstVaapiRectangle * rect) { - g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + g_return_if_fail (GST_VAAPI_IS_VIDEO_META (meta)); - meta->has_render_rect = rect != NULL; - if (meta->has_render_rect) - meta->render_rect = *rect; + meta->has_render_rect = rect != NULL; + if (meta->has_render_rect) + meta->render_rect = *rect; } #if GST_CHECK_VERSION(1,0,0) #define GST_VAAPI_VIDEO_META_HOLDER(meta) \ - ((GstVaapiVideoMetaHolder *)(meta)) + ((GstVaapiVideoMetaHolder *) (meta)) typedef struct _GstVaapiVideoMetaHolder GstVaapiVideoMetaHolder; -struct _GstVaapiVideoMetaHolder { - GstMeta base; - GstVaapiVideoMeta *meta; +struct _GstVaapiVideoMetaHolder +{ + GstMeta base; + GstVaapiVideoMeta *meta; }; static gboolean -gst_vaapi_video_meta_holder_init(GstVaapiVideoMetaHolder *meta, - gpointer params, GstBuffer *buffer) +gst_vaapi_video_meta_holder_init (GstVaapiVideoMetaHolder * meta, + gpointer params, GstBuffer * buffer) { - meta->meta = NULL; - return TRUE; + meta->meta = NULL; + return TRUE; } static void -gst_vaapi_video_meta_holder_free(GstVaapiVideoMetaHolder *meta, - GstBuffer *buffer) +gst_vaapi_video_meta_holder_free (GstVaapiVideoMetaHolder * meta, + GstBuffer * buffer) { - if (meta->meta) - gst_vaapi_video_meta_unref(meta->meta); + if (meta->meta) + gst_vaapi_video_meta_unref (meta->meta); } static gboolean -gst_vaapi_video_meta_holder_transform(GstBuffer *dst_buffer, GstMeta *meta, - GstBuffer *src_buffer, GQuark type, gpointer data) +gst_vaapi_video_meta_holder_transform (GstBuffer * dst_buffer, GstMeta * meta, + GstBuffer * src_buffer, GQuark type, gpointer data) { - GstVaapiVideoMetaHolder * const src_meta = - GST_VAAPI_VIDEO_META_HOLDER(meta); + GstVaapiVideoMetaHolder *const src_meta = GST_VAAPI_VIDEO_META_HOLDER (meta); - if (GST_META_TRANSFORM_IS_COPY(type)) { - GstVaapiVideoMeta * const dst_meta = - gst_vaapi_video_meta_copy(src_meta->meta); - gst_buffer_set_vaapi_video_meta(dst_buffer, dst_meta); - gst_vaapi_video_meta_unref(dst_meta); - return TRUE; - } - return FALSE; + if (GST_META_TRANSFORM_IS_COPY (type)) { + GstVaapiVideoMeta *const dst_meta = + gst_vaapi_video_meta_copy (src_meta->meta); + gst_buffer_set_vaapi_video_meta (dst_buffer, dst_meta); + gst_vaapi_video_meta_unref (dst_meta); + return TRUE; + } + return FALSE; } GType -gst_vaapi_video_meta_api_get_type(void) +gst_vaapi_video_meta_api_get_type (void) { - static gsize g_type; - static const gchar *tags[] = { "memory", NULL }; + static gsize g_type; + static const gchar *tags[] = { "memory", NULL }; - if (g_once_init_enter(&g_type)) { - GType type = gst_meta_api_type_register("GstVaapiVideoMetaAPI", tags); - g_once_init_leave(&g_type, type); - } - return g_type; + if (g_once_init_enter (&g_type)) { + GType type = gst_meta_api_type_register ("GstVaapiVideoMetaAPI", tags); + g_once_init_leave (&g_type, type); + } + return g_type; } -#define GST_VAAPI_VIDEO_META_INFO gst_vaapi_video_meta_info_get() +#define GST_VAAPI_VIDEO_META_INFO gst_vaapi_video_meta_info_get () static const GstMetaInfo * -gst_vaapi_video_meta_info_get(void) +gst_vaapi_video_meta_info_get (void) { - static gsize g_meta_info; + static gsize g_meta_info; - if (g_once_init_enter(&g_meta_info)) { - gsize meta_info = GPOINTER_TO_SIZE(gst_meta_register( - GST_VAAPI_VIDEO_META_API_TYPE, - "GstVaapiVideoMeta", sizeof(GstVaapiVideoMetaHolder), - (GstMetaInitFunction)gst_vaapi_video_meta_holder_init, - (GstMetaFreeFunction)gst_vaapi_video_meta_holder_free, - (GstMetaTransformFunction)gst_vaapi_video_meta_holder_transform)); - g_once_init_leave(&g_meta_info, meta_info); - } - return GSIZE_TO_POINTER(g_meta_info); + if (g_once_init_enter (&g_meta_info)) { + gsize meta_info = + GPOINTER_TO_SIZE (gst_meta_register (GST_VAAPI_VIDEO_META_API_TYPE, + "GstVaapiVideoMeta", sizeof (GstVaapiVideoMetaHolder), + (GstMetaInitFunction) gst_vaapi_video_meta_holder_init, + (GstMetaFreeFunction) gst_vaapi_video_meta_holder_free, + (GstMetaTransformFunction) gst_vaapi_video_meta_holder_transform)); + g_once_init_leave (&g_meta_info, meta_info); + } + return GSIZE_TO_POINTER (g_meta_info); } GstVaapiVideoMeta * -gst_buffer_get_vaapi_video_meta(GstBuffer *buffer) +gst_buffer_get_vaapi_video_meta (GstBuffer * buffer) { - GstMeta *m; + GstMeta *m; - g_return_val_if_fail(GST_IS_BUFFER(buffer), NULL); + g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); - m = gst_buffer_get_meta(buffer, GST_VAAPI_VIDEO_META_API_TYPE); - if (!m) - return NULL; - return GST_VAAPI_VIDEO_META_HOLDER(m)->meta; + m = gst_buffer_get_meta (buffer, GST_VAAPI_VIDEO_META_API_TYPE); + if (!m) + return NULL; + return GST_VAAPI_VIDEO_META_HOLDER (m)->meta; } void -gst_buffer_set_vaapi_video_meta(GstBuffer *buffer, GstVaapiVideoMeta *meta) +gst_buffer_set_vaapi_video_meta (GstBuffer * buffer, GstVaapiVideoMeta * meta) { - GstMeta *m; + GstMeta *m; - g_return_if_fail(GST_IS_BUFFER(buffer)); - g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + g_return_if_fail (GST_IS_BUFFER (buffer)); + g_return_if_fail (GST_VAAPI_IS_VIDEO_META (meta)); - m = gst_buffer_add_meta(buffer, GST_VAAPI_VIDEO_META_INFO, NULL); - if (m) - GST_VAAPI_VIDEO_META_HOLDER(m)->meta = gst_vaapi_video_meta_ref(meta); + m = gst_buffer_add_meta (buffer, GST_VAAPI_VIDEO_META_INFO, NULL); + if (m) + GST_VAAPI_VIDEO_META_HOLDER (m)->meta = gst_vaapi_video_meta_ref (meta); } #else -#define GST_VAAPI_VIDEO_META_QUARK gst_vaapi_video_meta_quark_get() +#define GST_VAAPI_VIDEO_META_QUARK gst_vaapi_video_meta_quark_get () static GQuark -gst_vaapi_video_meta_quark_get(void) +gst_vaapi_video_meta_quark_get (void) { - static gsize g_quark; + static gsize g_quark; - if (g_once_init_enter(&g_quark)) { - gsize quark = (gsize)g_quark_from_static_string("GstVaapiVideoMeta"); - g_once_init_leave(&g_quark, quark); - } - return g_quark; + if (g_once_init_enter (&g_quark)) { + gsize quark = (gsize) g_quark_from_static_string ("GstVaapiVideoMeta"); + g_once_init_leave (&g_quark, quark); + } + return g_quark; } -#define META_QUARK meta_quark_get() +#define META_QUARK meta_quark_get () static GQuark -meta_quark_get(void) +meta_quark_get (void) { - static gsize g_quark; + static gsize g_quark; - if (g_once_init_enter(&g_quark)) { - gsize quark = (gsize)g_quark_from_static_string("meta"); - g_once_init_leave(&g_quark, quark); - } - return g_quark; + if (g_once_init_enter (&g_quark)) { + gsize quark = (gsize) g_quark_from_static_string ("meta"); + g_once_init_leave (&g_quark, quark); + } + return g_quark; } GstVaapiVideoMeta * -gst_buffer_get_vaapi_video_meta(GstBuffer *buffer) +gst_buffer_get_vaapi_video_meta (GstBuffer * buffer) { - const GstStructure *structure; - const GValue *value; + const GstStructure *structure; + const GValue *value; - g_return_val_if_fail(GST_IS_BUFFER(buffer), NULL); + g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); - structure = gst_buffer_get_qdata(buffer, GST_VAAPI_VIDEO_META_QUARK); - if (!structure) - return NULL; + structure = gst_buffer_get_qdata (buffer, GST_VAAPI_VIDEO_META_QUARK); + if (!structure) + return NULL; - value = gst_structure_id_get_value(structure, META_QUARK); - if (!value) - return NULL; + value = gst_structure_id_get_value (structure, META_QUARK); + if (!value) + return NULL; - return GST_VAAPI_VIDEO_META(g_value_get_boxed(value)); + return GST_VAAPI_VIDEO_META (g_value_get_boxed (value)); } void -gst_buffer_set_vaapi_video_meta(GstBuffer *buffer, GstVaapiVideoMeta *meta) +gst_buffer_set_vaapi_video_meta (GstBuffer * buffer, GstVaapiVideoMeta * meta) { - g_return_if_fail(GST_IS_BUFFER(buffer)); - g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta)); + g_return_if_fail (GST_IS_BUFFER (buffer)); + g_return_if_fail (GST_VAAPI_IS_VIDEO_META (meta)); - gst_buffer_set_qdata(buffer, GST_VAAPI_VIDEO_META_QUARK, - gst_structure_id_new(GST_VAAPI_VIDEO_META_QUARK, - META_QUARK, GST_VAAPI_TYPE_VIDEO_META, meta, NULL)); + gst_buffer_set_qdata (buffer, GST_VAAPI_VIDEO_META_QUARK, + gst_structure_id_new (GST_VAAPI_VIDEO_META_QUARK, + META_QUARK, GST_VAAPI_TYPE_VIDEO_META, meta, NULL)); } #endif diff --git a/gst/vaapi/gstvaapivideometa.h b/gst/vaapi/gstvaapivideometa.h index 403dbdf427..21fd35a4c6 100644 --- a/gst/vaapi/gstvaapivideometa.h +++ b/gst/vaapi/gstvaapivideometa.h @@ -33,112 +33,114 @@ G_BEGIN_DECLS -typedef struct _GstVaapiVideoMeta GstVaapiVideoMeta; +typedef struct _GstVaapiVideoMeta GstVaapiVideoMeta; #if GST_CHECK_VERSION(1,0,0) #define GST_VAAPI_VIDEO_META_API_TYPE \ - gst_vaapi_video_meta_api_get_type() + gst_vaapi_video_meta_api_get_type () G_GNUC_INTERNAL GType -gst_vaapi_video_meta_api_get_type(void) G_GNUC_CONST; +gst_vaapi_video_meta_api_get_type (void) G_GNUC_CONST; #endif G_GNUC_INTERNAL GstVaapiVideoMeta * -gst_vaapi_video_meta_copy(GstVaapiVideoMeta *meta); +gst_vaapi_video_meta_copy (GstVaapiVideoMeta * meta); G_GNUC_INTERNAL GstVaapiVideoMeta * -gst_vaapi_video_meta_new(GstVaapiDisplay *display); +gst_vaapi_video_meta_new (GstVaapiDisplay * display); G_GNUC_INTERNAL GstVaapiVideoMeta * -gst_vaapi_video_meta_new_from_pool(GstVaapiVideoPool *pool); +gst_vaapi_video_meta_new_from_pool (GstVaapiVideoPool * pool); G_GNUC_INTERNAL GstVaapiVideoMeta * -gst_vaapi_video_meta_new_with_image(GstVaapiImage *image); +gst_vaapi_video_meta_new_with_image (GstVaapiImage * image); G_GNUC_INTERNAL GstVaapiVideoMeta * -gst_vaapi_video_meta_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy); +gst_vaapi_video_meta_new_with_surface_proxy (GstVaapiSurfaceProxy * proxy); G_GNUC_INTERNAL GstVaapiVideoMeta * -gst_vaapi_video_meta_ref(GstVaapiVideoMeta *meta); +gst_vaapi_video_meta_ref (GstVaapiVideoMeta * meta); G_GNUC_INTERNAL void -gst_vaapi_video_meta_unref(GstVaapiVideoMeta *meta); +gst_vaapi_video_meta_unref (GstVaapiVideoMeta * meta); G_GNUC_INTERNAL void -gst_vaapi_video_meta_replace(GstVaapiVideoMeta **old_meta_ptr, - GstVaapiVideoMeta *new_meta); +gst_vaapi_video_meta_replace (GstVaapiVideoMeta ** old_meta_ptr, + GstVaapiVideoMeta * new_meta); G_GNUC_INTERNAL GstVaapiDisplay * -gst_vaapi_video_meta_get_display(GstVaapiVideoMeta *meta); +gst_vaapi_video_meta_get_display (GstVaapiVideoMeta * meta); G_GNUC_INTERNAL GstVaapiImage * -gst_vaapi_video_meta_get_image(GstVaapiVideoMeta *meta); +gst_vaapi_video_meta_get_image (GstVaapiVideoMeta * meta); G_GNUC_INTERNAL void -gst_vaapi_video_meta_set_image(GstVaapiVideoMeta *meta, GstVaapiImage *image); +gst_vaapi_video_meta_set_image (GstVaapiVideoMeta * meta, + GstVaapiImage * image); G_GNUC_INTERNAL gboolean -gst_vaapi_video_meta_set_image_from_pool(GstVaapiVideoMeta *meta, - GstVaapiVideoPool *pool); +gst_vaapi_video_meta_set_image_from_pool (GstVaapiVideoMeta * meta, + GstVaapiVideoPool * pool); G_GNUC_INTERNAL GstVaapiSurface * -gst_vaapi_video_meta_get_surface(GstVaapiVideoMeta *meta); +gst_vaapi_video_meta_get_surface (GstVaapiVideoMeta * meta); G_GNUC_INTERNAL GstVaapiSurfaceProxy * -gst_vaapi_video_meta_get_surface_proxy(GstVaapiVideoMeta *meta); +gst_vaapi_video_meta_get_surface_proxy (GstVaapiVideoMeta * meta); G_GNUC_INTERNAL void -gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta, - GstVaapiSurfaceProxy *proxy); +gst_vaapi_video_meta_set_surface_proxy (GstVaapiVideoMeta * meta, + GstVaapiSurfaceProxy * proxy); G_GNUC_INTERNAL GFunc -gst_vaapi_video_meta_get_surface_converter(GstVaapiVideoMeta *meta); +gst_vaapi_video_meta_get_surface_converter (GstVaapiVideoMeta * meta); G_GNUC_INTERNAL void -gst_vaapi_video_meta_set_surface_converter(GstVaapiVideoMeta *meta, GFunc func); +gst_vaapi_video_meta_set_surface_converter (GstVaapiVideoMeta * meta, + GFunc func); G_GNUC_INTERNAL guint -gst_vaapi_video_meta_get_render_flags(GstVaapiVideoMeta *meta); +gst_vaapi_video_meta_get_render_flags (GstVaapiVideoMeta * meta); G_GNUC_INTERNAL void -gst_vaapi_video_meta_set_render_flags(GstVaapiVideoMeta *meta, guint flags); +gst_vaapi_video_meta_set_render_flags (GstVaapiVideoMeta * meta, guint flags); G_GNUC_INTERNAL const GstVaapiRectangle * -gst_vaapi_video_meta_get_render_rect(GstVaapiVideoMeta *meta); +gst_vaapi_video_meta_get_render_rect (GstVaapiVideoMeta * meta); G_GNUC_INTERNAL void -gst_vaapi_video_meta_set_render_rect(GstVaapiVideoMeta *meta, - const GstVaapiRectangle *rect); +gst_vaapi_video_meta_set_render_rect (GstVaapiVideoMeta * meta, + const GstVaapiRectangle * rect); G_GNUC_INTERNAL GstVaapiVideoMeta * -gst_buffer_get_vaapi_video_meta(GstBuffer *buffer); +gst_buffer_get_vaapi_video_meta (GstBuffer * buffer); G_GNUC_INTERNAL void -gst_buffer_set_vaapi_video_meta(GstBuffer *buffer, GstVaapiVideoMeta *meta); +gst_buffer_set_vaapi_video_meta (GstBuffer * buffer, GstVaapiVideoMeta * meta); G_END_DECLS diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 371927d0cd..de36bb864c 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -30,108 +30,110 @@ #include "gstvaapipluginutil.h" #if GST_CHECK_VERSION(1,1,0) && USE_GLX -struct _GstVaapiVideoMetaTexture { - GstVaapiTexture *texture; +struct _GstVaapiVideoMetaTexture +{ + GstVaapiTexture *texture; }; static void -meta_texture_free(GstVaapiVideoMetaTexture *meta) +meta_texture_free (GstVaapiVideoMetaTexture * meta) { - if (G_UNLIKELY(!meta)) - return; + if (G_UNLIKELY (!meta)) + return; - gst_vaapi_texture_replace(&meta->texture, NULL); - g_slice_free(GstVaapiVideoMetaTexture, meta); + gst_vaapi_texture_replace (&meta->texture, NULL); + g_slice_free (GstVaapiVideoMetaTexture, meta); } static GstVaapiVideoMetaTexture * -meta_texture_new(void) +meta_texture_new (void) { - GstVaapiVideoMetaTexture *meta; + GstVaapiVideoMetaTexture *meta; - meta = g_slice_new(GstVaapiVideoMetaTexture); - if (!meta) - return NULL; + meta = g_slice_new (GstVaapiVideoMetaTexture); + if (!meta) + return NULL; - meta->texture = NULL; - return meta; + meta->texture = NULL; + return meta; } static GstVaapiVideoMetaTexture * -meta_texture_copy(GstVaapiVideoMetaTexture *meta) +meta_texture_copy (GstVaapiVideoMetaTexture * meta) { - GstVaapiVideoMetaTexture *copy; + GstVaapiVideoMetaTexture *copy; - copy = meta_texture_new(); - if (!copy) - return NULL; + copy = meta_texture_new (); + if (!copy) + return NULL; - gst_vaapi_texture_replace(©->texture, meta->texture); - return copy; + gst_vaapi_texture_replace (©->texture, meta->texture); + return copy; } static gboolean -gst_vaapi_texture_upload(GstVideoGLTextureUploadMeta *meta, guint texture_id[4]) +gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, + guint texture_id[4]) { - GstVaapiVideoMeta * const vmeta = - gst_buffer_get_vaapi_video_meta(meta->buffer); - GstVaapiVideoMetaTexture * const meta_texture = meta->user_data; - GstVaapiSurface * const surface = gst_vaapi_video_meta_get_surface(vmeta); - GstVaapiDisplay * const dpy = GST_VAAPI_OBJECT_DISPLAY(surface); + GstVaapiVideoMeta *const vmeta = + gst_buffer_get_vaapi_video_meta (meta->buffer); + GstVaapiVideoMetaTexture *const meta_texture = meta->user_data; + GstVaapiSurface *const surface = gst_vaapi_video_meta_get_surface (vmeta); + GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface); - if (gst_vaapi_display_get_display_type(dpy) != GST_VAAPI_DISPLAY_TYPE_GLX) - return FALSE; + if (gst_vaapi_display_get_display_type (dpy) != GST_VAAPI_DISPLAY_TYPE_GLX) + return FALSE; - if (!meta_texture->texture || - /* Check whether VA display changed */ - GST_VAAPI_OBJECT_DISPLAY(meta_texture->texture) != dpy || - /* Check whether texture id changed */ - gst_vaapi_texture_get_id(meta_texture->texture) != texture_id[0]) { - /* FIXME: should we assume target? */ - GstVaapiTexture * const texture = - gst_vaapi_texture_new_with_texture(dpy, texture_id[0], - GL_TEXTURE_2D, GL_RGBA); - gst_vaapi_texture_replace(&meta_texture->texture, texture); - if (!texture) - return FALSE; - gst_vaapi_texture_unref(texture); - } - return gst_vaapi_texture_put_surface(meta_texture->texture, surface, - gst_vaapi_video_meta_get_render_flags(vmeta)); + if (!meta_texture->texture || + /* Check whether VA display changed */ + GST_VAAPI_OBJECT_DISPLAY (meta_texture->texture) != dpy || + /* Check whether texture id changed */ + gst_vaapi_texture_get_id (meta_texture->texture) != texture_id[0]) { + /* FIXME: should we assume target? */ + GstVaapiTexture *const texture = + gst_vaapi_texture_new_with_texture (dpy, texture_id[0], + GL_TEXTURE_2D, GL_RGBA); + gst_vaapi_texture_replace (&meta_texture->texture, texture); + if (!texture) + return FALSE; + gst_vaapi_texture_unref (texture); + } + return gst_vaapi_texture_put_surface (meta_texture->texture, surface, + gst_vaapi_video_meta_get_render_flags (vmeta)); } gboolean -gst_buffer_add_texture_upload_meta(GstBuffer *buffer) +gst_buffer_add_texture_upload_meta (GstBuffer * buffer) { - GstVideoGLTextureUploadMeta *meta = NULL; - GstVideoGLTextureType tex_type[] = { GST_VIDEO_GL_TEXTURE_TYPE_RGBA }; - GstVaapiVideoMetaTexture *meta_texture; + GstVideoGLTextureUploadMeta *meta = NULL; + GstVideoGLTextureType tex_type[] = { GST_VIDEO_GL_TEXTURE_TYPE_RGBA }; + GstVaapiVideoMetaTexture *meta_texture; - if (!buffer) - return FALSE; + if (!buffer) + return FALSE; - meta_texture = meta_texture_new(); - if (!meta_texture) - return FALSE; + meta_texture = meta_texture_new (); + if (!meta_texture) + return FALSE; - meta = gst_buffer_add_video_gl_texture_upload_meta(buffer, - GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, - 1, tex_type, gst_vaapi_texture_upload, - meta_texture, (GBoxedCopyFunc)meta_texture_copy, - (GBoxedFreeFunc)meta_texture_free); - if (!meta) - goto error; - return TRUE; + meta = gst_buffer_add_video_gl_texture_upload_meta (buffer, + GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, + 1, tex_type, gst_vaapi_texture_upload, + meta_texture, (GBoxedCopyFunc) meta_texture_copy, + (GBoxedFreeFunc) meta_texture_free); + if (!meta) + goto error; + return TRUE; error: - meta_texture_free(meta_texture); - return FALSE; + meta_texture_free (meta_texture); + return FALSE; } gboolean -gst_buffer_ensure_texture_upload_meta(GstBuffer *buffer) +gst_buffer_ensure_texture_upload_meta (GstBuffer * buffer) { - return gst_buffer_get_video_gl_texture_upload_meta(buffer) || - gst_buffer_add_texture_upload_meta(buffer); + return gst_buffer_get_video_gl_texture_upload_meta (buffer) || + gst_buffer_add_texture_upload_meta (buffer); } #endif diff --git a/gst/vaapi/gstvaapivideometa_texture.h b/gst/vaapi/gstvaapivideometa_texture.h index c6e0e6bea6..c334145292 100644 --- a/gst/vaapi/gstvaapivideometa_texture.h +++ b/gst/vaapi/gstvaapivideometa_texture.h @@ -31,15 +31,15 @@ G_BEGIN_DECLS -typedef struct _GstVaapiVideoMetaTexture GstVaapiVideoMetaTexture; +typedef struct _GstVaapiVideoMetaTexture GstVaapiVideoMetaTexture; G_GNUC_INTERNAL gboolean -gst_buffer_add_texture_upload_meta(GstBuffer *buffer); +gst_buffer_add_texture_upload_meta (GstBuffer * buffer); G_GNUC_INTERNAL gboolean -gst_buffer_ensure_texture_upload_meta(GstBuffer *buffer); +gst_buffer_ensure_texture_upload_meta (GstBuffer * buffer); G_END_DECLS From 1ef5a3a2003bc2071a30c08d457345ae005d61fd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Aug 2014 11:12:39 +0200 Subject: [PATCH 1769/3781] plugins: allow bufferpool to not allocate vaapi video meta. Add GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC params flag that can be used to disable early allocations of vaapi video metas on buffers, thus delagating that to the bufferpool user. --- gst/vaapi/gstvaapivideobufferpool.c | 18 +++++++++++++----- gst/vaapi/gstvaapivideobufferpool.h | 14 ++++++++++++++ gst/vaapi/gstvaapivideomemory.c | 13 ++++++++++--- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 6e08ce1013..4c642e7d50 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -216,21 +216,29 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, GstMemory *mem; GstBuffer *buffer; + const gboolean alloc_vaapi_video_meta = !params || + !(params->flags & GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC); + if (!priv->allocator) goto error_no_allocator; - meta = gst_vaapi_video_meta_new (priv->display); - if (!meta) - goto error_create_meta; + if (alloc_vaapi_video_meta) { + meta = gst_vaapi_video_meta_new (priv->display); + if (!meta) + goto error_create_meta; - buffer = gst_vaapi_video_buffer_new (meta); + buffer = gst_vaapi_video_buffer_new (meta); + } else { + meta = NULL; + buffer = gst_vaapi_video_buffer_new_empty (); + } if (!buffer) goto error_create_buffer; mem = gst_vaapi_video_memory_new (priv->allocator, meta); if (!mem) goto error_create_memory; - gst_vaapi_video_meta_unref (meta); + gst_vaapi_video_meta_replace (&meta, NULL); gst_buffer_append_memory (buffer, mem); if (priv->has_video_meta) { diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index ed8e1c7e07..7ced82bade 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -69,6 +69,20 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; "GstBufferPoolOptionVideoGLTextureUploadMeta" #endif +/** + * GstVaapiVideoBufferPoolAcquireFlags: + * @GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC: option to + * request that vaapi video metadata are not initially allocated, + * but are subsequently provided by the user. + * + * The set of #GstVaapiVideoBufferPool specific flags for + * gst_buffer_pool_acquire_buffer(). + */ +typedef enum { + GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC = + GST_BUFFER_POOL_ACQUIRE_FLAG_LAST << 0, +} GstVaapiVideoBufferPoolAcquireFlags; + /** * GstVaapiVideoBufferPool: * diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index fa368bdaf6..528e217126 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -281,7 +281,7 @@ gst_vaapi_video_memory_new (GstAllocator * base_allocator, mem->surface = NULL; mem->image_info = &allocator->image_info; mem->image = NULL; - mem->meta = gst_vaapi_video_meta_ref (meta); + mem->meta = meta ? gst_vaapi_video_meta_ref (meta) : NULL; mem->map_type = 0; mem->map_count = 0; mem->use_direct_rendering = allocator->has_direct_rendering; @@ -294,7 +294,7 @@ gst_vaapi_video_memory_free (GstVaapiVideoMemory * mem) mem->surface = NULL; gst_vaapi_video_memory_reset_image (mem); gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); - gst_vaapi_video_meta_unref (mem->meta); + gst_vaapi_video_meta_replace (&mem->meta, NULL); gst_object_unref (GST_MEMORY_CAST (mem)->allocator); g_slice_free (GstVaapiVideoMemory, mem); } @@ -319,7 +319,8 @@ gst_vaapi_video_memory_reset_surface (GstVaapiVideoMemory * mem) mem->surface = NULL; gst_vaapi_video_memory_reset_image (mem); gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); - gst_vaapi_video_meta_set_surface_proxy (mem->meta, NULL); + if (mem->meta) + gst_vaapi_video_meta_set_surface_proxy (mem->meta, NULL); } static gpointer @@ -328,6 +329,9 @@ gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize, { gpointer data; + g_return_val_if_fail (mem, NULL); + g_return_val_if_fail (mem->meta, NULL); + if (mem->map_count == 0) { switch (flags & GST_MAP_READWRITE) { case 0: @@ -426,6 +430,9 @@ gst_vaapi_video_memory_copy (GstVaapiVideoMemory * mem, GstMemory *out_mem; gsize maxsize; + g_return_val_if_fail (mem, NULL); + g_return_val_if_fail (mem->meta, NULL); + /* XXX: this implements a soft-copy, i.e. underlying VA surfaces are not copied */ (void) gst_memory_get_sizes (GST_MEMORY_CAST (mem), NULL, &maxsize); From d0a9575fc22701a68abb790d13524edb86e47f6d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Aug 2014 14:10:36 +0200 Subject: [PATCH 1770/3781] plugins: factor out decide_allocation() hook. Add a default decide_allocation() hook to GstVaapiPluginBase. The caps feature argument can be used to force a bufferpool with a specific kind of memory. --- gst/vaapi/gstvaapidecode.c | 119 +++------------------------- gst/vaapi/gstvaapipluginbase.c | 141 +++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginbase.h | 8 ++ 3 files changed, 158 insertions(+), 110 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4f716c6a78..989f7a19c8 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -522,40 +522,26 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstCaps *caps = NULL; - GstBufferPool *pool; - GstStructure *config; - GstVideoInfo vi; - guint size, min, max; - gboolean need_pool, update_pool; - gboolean has_video_meta = FALSE; - gboolean has_video_alignment = FALSE; -#if GST_CHECK_VERSION(1,1,0) && USE_GLX - gboolean has_texture_upload_meta = FALSE; -#endif + gboolean need_pool; GstVideoCodecState *state; + GstVaapiCapsFeature feature; gst_query_parse_allocation(query, &caps, &need_pool); - if (!caps) - goto error_no_caps; - - state = gst_video_decoder_get_output_state(vdec); - decode->has_texture_upload_meta = FALSE; - has_video_meta = gst_query_find_allocation_meta(query, - GST_VIDEO_META_API_TYPE, NULL); - #if GST_CHECK_VERSION(1,1,0) && USE_GLX - has_texture_upload_meta = gst_query_find_allocation_meta(query, - GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); - decode->has_texture_upload_meta = gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec), GST_VIDEO_FORMAT_ENCODED) == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META; #endif + feature = decode->has_texture_upload_meta ? + GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META : + GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE; + /* Update src caps if feature is not handled downstream */ + state = gst_video_decoder_get_output_state(vdec); if (!gst_caps_is_always_compatible(caps, state->caps)) { if (decode->has_texture_upload_meta) gst_video_info_set_format(&state->info, GST_VIDEO_FORMAT_RGBA, @@ -565,95 +551,8 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) } gst_video_codec_state_unref(state); - gst_video_info_init(&vi); - gst_video_info_from_caps(&vi, caps); - if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) - gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_I420, - GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); - - g_return_val_if_fail(GST_VAAPI_PLUGIN_BASE_DISPLAY(decode) != NULL, FALSE); - - if (gst_query_get_n_allocation_pools(query) > 0) { - gst_query_parse_nth_allocation_pool(query, 0, &pool, &size, &min, &max); - size = MAX(size, vi.size); - update_pool = TRUE; - - /* Check whether downstream element proposed a bufferpool but did - not provide a correct propose_allocation() implementation */ - has_video_alignment = gst_buffer_pool_has_option(pool, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); - } - else { - pool = NULL; - size = vi.size; - min = max = 0; - update_pool = FALSE; - } - - if (!pool || !gst_buffer_pool_has_option(pool, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) { - GST_INFO("no pool or doesn't support GstVaapiVideoMeta, " - "making new pool"); - if (pool) - gst_object_unref(pool); - pool = gst_vaapi_video_buffer_pool_new( - GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); - if (!pool) - goto error_create_pool; - - config = gst_buffer_pool_get_config(pool); - gst_buffer_pool_config_set_params(config, caps, size, min, max); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - gst_buffer_pool_set_config(pool, config); - } - - if (has_video_meta) { - config = gst_buffer_pool_get_config(pool); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_META); -#if GST_CHECK_VERSION(1,1,0) && USE_GLX - if (has_texture_upload_meta) - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); -#endif - gst_buffer_pool_set_config(pool, config); - } - else if (has_video_alignment) { - config = gst_buffer_pool_get_config(pool); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); - gst_buffer_pool_set_config(pool, config); - } - -#if GST_CHECK_VERSION(1,1,0) && USE_GLX - if (decode->has_texture_upload_meta && !has_texture_upload_meta) { - config = gst_buffer_pool_get_config(pool); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); - gst_buffer_pool_set_config(pool, config); - } -#endif - - if (update_pool) - gst_query_set_nth_allocation_pool(query, 0, pool, size, min, max); - else - gst_query_add_allocation_pool(query, pool, size, min, max); - if (pool) - gst_object_unref(pool); - return TRUE; - - /* ERRORS */ -error_no_caps: - { - GST_ERROR("no caps specified"); - return FALSE; - } -error_create_pool: - { - GST_ERROR("failed to create buffer pool"); - return FALSE; - } + return gst_vaapi_plugin_base_decide_allocation(GST_VAAPI_PLUGIN_BASE(vdec), + query, feature); } #endif diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index ad254f2bd1..f69f84b14f 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -206,6 +206,7 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) gst_object_unref (plugin->sinkpad_buffer_pool); plugin->sinkpad_buffer_pool = NULL; } + g_clear_object (&plugin->srcpad_buffer_pool); #endif gst_caps_replace (&plugin->srcpad_caps, NULL); @@ -453,6 +454,146 @@ error_no_caps: } #endif +/** + * gst_vaapi_plugin_base_decide_allocation: + * @plugin: a #GstVaapiPluginBase + * @query: the allocation query to parse + * @feature: the desired #GstVaapiCapsFeature, or zero to find the + * preferred one + * + * Decides allocation parameters for the downstream elements. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +#if GST_CHECK_VERSION(1,0,0) +gboolean +gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, + GstQuery * query, guint feature) +{ + GstCaps *caps = NULL; + GstBufferPool *pool; + GstStructure *config; + GstVideoInfo vi; + guint size, min, max; + gboolean need_pool, update_pool; + gboolean has_video_meta = FALSE; + gboolean has_video_alignment = FALSE; +#if GST_CHECK_VERSION(1,1,0) && USE_GLX + gboolean has_texture_upload_meta = FALSE; +#endif + + g_return_val_if_fail (plugin->display != NULL, FALSE); + + gst_query_parse_allocation (query, &caps, &need_pool); + + if (!caps) + goto error_no_caps; + + if (!feature) + feature = + gst_vaapi_find_preferred_caps_feature (plugin->srcpad, + GST_VIDEO_FORMAT_ENCODED); + + has_video_meta = gst_query_find_allocation_meta (query, + GST_VIDEO_META_API_TYPE, NULL); + +#if GST_CHECK_VERSION(1,1,0) && USE_GLX + has_texture_upload_meta = gst_query_find_allocation_meta (query, + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); +#endif + + gst_video_info_init (&vi); + gst_video_info_from_caps (&vi, caps); + if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) + gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_I420, + GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); + + if (gst_query_get_n_allocation_pools (query) > 0) { + gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); + size = MAX (size, vi.size); + update_pool = TRUE; + + /* Check whether downstream element proposed a bufferpool but did + not provide a correct propose_allocation() implementation */ + has_video_alignment = gst_buffer_pool_has_option (pool, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + } else { + pool = NULL; + size = vi.size; + min = max = 0; + update_pool = FALSE; + } + + /* GstVaapiVideoMeta is mandatory, and this implies VA surface memory */ + if (!pool || !gst_buffer_pool_has_option (pool, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) { + GST_INFO_OBJECT (plugin, "no pool or doesn't support GstVaapiVideoMeta, " + "making new pool"); + if (pool) + gst_object_unref (pool); + pool = gst_vaapi_video_buffer_pool_new (plugin->display); + if (!pool) + goto error_create_pool; + + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set_params (config, caps, size, min, max); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); + gst_buffer_pool_set_config (pool, config); + } + + /* Check whether GstVideoMeta, or GstVideoAlignment, is needed (raw video) */ + if (has_video_meta) { + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); +#if GST_CHECK_VERSION(1,1,0) && USE_GLX + if (has_texture_upload_meta) + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); +#endif + gst_buffer_pool_set_config (pool, config); + } else if (has_video_alignment) { + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + gst_buffer_pool_set_config (pool, config); + } + + /* GstVideoGLTextureUploadMeta (OpenGL) */ +#if GST_CHECK_VERSION(1,1,0) && USE_GLX + if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META + && !has_texture_upload_meta) { + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); + gst_buffer_pool_set_config (pool, config); + } +#endif + + if (update_pool) + gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); + else + gst_query_add_allocation_pool (query, pool, size, min, max); + + g_clear_object (&plugin->srcpad_buffer_pool); + plugin->srcpad_buffer_pool = pool; + return TRUE; + + /* ERRORS */ +error_no_caps: + { + GST_ERROR_OBJECT (plugin, "no caps specified"); + return FALSE; + } +error_create_pool: + { + GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); + return FALSE; + } +} +#endif + /** * gst_vaapi_plugin_base_allocate_input_buffer: * @plugin: a #GstVaapiPluginBase diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 76413b3d18..e7426cba20 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -136,6 +136,9 @@ struct _GstVaapiPluginBase gboolean srcpad_caps_changed; GstVideoInfo srcpad_info; GstPadQueryFunction srcpad_query; +#if GST_CHECK_VERSION(1,0,0) + GstBufferPool *srcpad_buffer_pool; +#endif GstVaapiDisplay *display; GstVaapiDisplayType display_type; @@ -215,6 +218,11 @@ gboolean gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, GstQuery * query); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, + GstQuery * query, guint feature); + G_GNUC_INTERNAL GstFlowReturn gst_vaapi_plugin_base_allocate_input_buffer (GstVaapiPluginBase * plugin, From c257c3232a4e87295e72431a38494ae4c5e915ec Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Aug 2014 13:25:03 +0200 Subject: [PATCH 1771/3781] plugins: fix memory leaks. --- gst/vaapi/gstvaapipluginbase.c | 1 + gst/vaapi/gstvaapipluginutil.c | 1 + 2 files changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index f69f84b14f..504fd8e0e4 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -164,6 +164,7 @@ void gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin) { gst_vaapi_plugin_base_close (plugin); + g_free (plugin->display_name); if (plugin->sinkpad) gst_object_unref (plugin->sinkpad); if (plugin->srcpad) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 2c3a3cd00e..3d0c3cf294 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -456,6 +456,7 @@ gst_vaapi_video_format_new_template_caps_from_list (GArray * formats) gst_caps_set_value (caps, "format", &v_formats); set_video_template_caps (caps); + g_value_unset (&v_formats); #else GstCaps *caps, *tmp_caps; guint i; From aa4d1f5a1e2d939c3c00fd7ae4a6c39f51cd495a Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 21 Aug 2014 15:04:20 +0300 Subject: [PATCH 1772/3781] vaapivideomemory: avoid NULL pointer unref if GstVaapiImage creation failed. https://bugzilla.gnome.org/show_bug.cgi?id=735156 --- gst/vaapi/gstvaapivideomemory.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 528e217126..176e7f6c81 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -654,7 +654,8 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display, gst_video_info_update_from_image (&allocator->image_info, image); gst_vaapi_image_unmap (image); } while (0); - gst_vaapi_object_unref (image); + if (image) + gst_vaapi_object_unref (image); } allocator->image_pool = gst_vaapi_image_pool_new (display, From bc8e7a673471d07c16a880075d11ed49af60d51f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Aug 2014 11:13:36 +0200 Subject: [PATCH 1773/3781] vaapipostproc: enable advanced deinterlacing with same format. If only advanced deinterlacing is requested, i.e. deinterlacing is the only active algorithm to apply with source and output surface formats being the same, then make sure to enable VPP processing. Otherwise, allow fallback to bob-deinterlacing with simple rendering flags alteration. --- gst/vaapi/gstvaapipostproc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 805e354807..91f12b99f5 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1117,7 +1117,8 @@ gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf, if (postproc->flags) { /* Use VA/VPP extensions to process this frame */ if (postproc->use_vpp && - postproc->flags != GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) { + (postproc->flags != GST_VAAPI_POSTPROC_FLAG_DEINTERLACE || + deint_method_is_advanced(postproc->deinterlace_method))) { ret = gst_vaapipostproc_process_vpp(trans, buf, outbuf); if (ret != GST_FLOW_NOT_SUPPORTED) goto done; From db111fe72a7ae0592f398307f95ba328e6a6be09 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Sat, 5 Jul 2014 21:00:34 +0300 Subject: [PATCH 1774/3781] vaapipostproc: fix output buffer to have a GstVaapiVideoMemory. https://bugzilla.gnome.org/show_bug.cgi?id=720311 [used new infrastructure through base decide_allocation() impl] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipostproc.c | 38 +++++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapipostproc.h | 1 + 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 91f12b99f5..ecd7a03577 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -280,6 +280,7 @@ gst_vaapipostproc_destroy_filter(GstVaapiPostproc *postproc) } gst_vaapi_filter_replace(&postproc->filter, NULL); gst_vaapi_video_pool_replace(&postproc->filter_pool, NULL); + postproc->filter_pool_active = FALSE; } static void @@ -313,6 +314,7 @@ gst_vaapipostproc_stop(GstBaseTransform *trans) ds_reset(&postproc->deinterlace_state); gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(postproc)); + postproc->filter_pool_active = FALSE; return TRUE; } @@ -354,18 +356,44 @@ create_output_buffer(GstVaapiPostproc *postproc) { GstBuffer *outbuf; +#if GST_CHECK_VERSION(1,0,0) + GstBufferPool * const pool = + GST_VAAPI_PLUGIN_BASE(postproc)->srcpad_buffer_pool; + GstBufferPoolAcquireParams params = { 0, }; + GstFlowReturn ret; + + g_return_val_if_fail(pool != NULL, NULL); + + if (!postproc->filter_pool_active) { + if (!gst_buffer_pool_set_active(pool, TRUE)) + goto error_activate_pool; + postproc->filter_pool_active = TRUE; + } + + outbuf = NULL; + params.flags = GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC; + ret = gst_buffer_pool_acquire_buffer(pool, &outbuf, ¶ms); + if (ret != GST_FLOW_OK || !outbuf) + goto error_create_buffer; +#else /* Create a raw VA video buffer without GstVaapiVideoMeta attached to it yet, as this will be done next in the transform() hook */ outbuf = gst_vaapi_video_buffer_new_empty(); if (!outbuf) goto error_create_buffer; -#if !GST_CHECK_VERSION(1,0,0) gst_buffer_set_caps(outbuf, GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS(postproc)); #endif return outbuf; /* ERRORS */ +#if GST_CHECK_VERSION(1,0,0) +error_activate_pool: + { + GST_ERROR("failed to activate output video buffer pool"); + return NULL; + } +#endif error_create_buffer: { GST_ERROR("failed to create output video buffer"); @@ -1239,6 +1267,13 @@ gst_vaapipostproc_propose_allocation(GstBaseTransform *trans, return FALSE; return TRUE; } + +static gboolean +gst_vaapipostproc_decide_allocation(GstBaseTransform *trans, GstQuery *query) +{ + return gst_vaapi_plugin_base_decide_allocation(GST_VAAPI_PLUGIN_BASE(trans), + query, 0); +} #endif static void @@ -1392,6 +1427,7 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) #if GST_CHECK_VERSION(1,0,0) trans_class->propose_allocation = gst_vaapipostproc_propose_allocation; + trans_class->decide_allocation = gst_vaapipostproc_decide_allocation; #endif trans_class->prepare_output_buffer = diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 1154d3fe23..8dc3c8f95f 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -139,6 +139,7 @@ struct _GstVaapiPostproc { GPtrArray *filter_ops; GstVaapiVideoPool *filter_pool; GstVideoInfo filter_pool_info; + gboolean filter_pool_active; GArray *filter_formats; GstVideoFormat format; /* output video format (encoded) */ guint width; From 92fcb38ba67e5f91577b5d0b7392767b61df84a4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Aug 2014 15:17:29 +0200 Subject: [PATCH 1775/3781] vaapipostproc: fix passthrough mode. If no explicit output surface format is supplied try to keep the one supplied through the sink pad caps. This avoids a useless copy, even if things are kept in GPU memory. This is a performance regression from git commit dfa70b9. --- gst/vaapi/gstvaapipostproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index ecd7a03577..ce2413122e 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -873,7 +873,7 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps, if (video_info_changed(&vi, &postproc->srcpad_info)) postproc->srcpad_info = vi, *caps_changed_ptr = TRUE; - if (postproc->format != GST_VIDEO_INFO_FORMAT(&postproc->sinkpad_info) || + if (postproc->format != GST_VIDEO_INFO_FORMAT(&postproc->sinkpad_info) && postproc->format != DEFAULT_FORMAT) postproc->flags |= GST_VAAPI_POSTPROC_FLAG_FORMAT; From 9ee46ab32e559f1029cc0b9764006e79c3eea4dc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Aug 2014 18:10:54 +0200 Subject: [PATCH 1776/3781] vaapipostproc: use pooled vaapi video meta. Use pooled GstVaapiVideoMeta information, i.e. always allocate that on video buffer allocation. Also optimize copy of additional metadata info into the resulting video buffer: only copy the video cropping info and the source surface proxy. https://bugzilla.gnome.org/show_bug.cgi?id=720311 Signed-off-by: Sreerenj Balachandran [fixed proxy leak, fixed double free on error, optimized meta copy] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipostproc.c | 98 ++++++++++++++++++++++++++---------- gst/vaapi/gstvaapipostproc.h | 1 + 2 files changed, 72 insertions(+), 27 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index ce2413122e..fbebab96c0 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -261,8 +261,9 @@ gst_vaapipostproc_create(GstVaapiPostproc *postproc) return FALSE; if (!gst_vaapipostproc_ensure_uploader(postproc)) return FALSE; - if (gst_vaapipostproc_ensure_filter(postproc)) - postproc->use_vpp = TRUE; + + postproc->use_vpp = FALSE; + postproc->has_vpp = gst_vaapipostproc_ensure_filter(postproc); return TRUE; } @@ -359,7 +360,6 @@ create_output_buffer(GstVaapiPostproc *postproc) #if GST_CHECK_VERSION(1,0,0) GstBufferPool * const pool = GST_VAAPI_PLUGIN_BASE(postproc)->srcpad_buffer_pool; - GstBufferPoolAcquireParams params = { 0, }; GstFlowReturn ret; g_return_val_if_fail(pool != NULL, NULL); @@ -371,8 +371,7 @@ create_output_buffer(GstVaapiPostproc *postproc) } outbuf = NULL; - params.flags = GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC; - ret = gst_buffer_pool_acquire_buffer(pool, &outbuf, ¶ms); + ret = gst_buffer_pool_acquire_buffer(pool, &outbuf, NULL); if (ret != GST_FLOW_OK || !outbuf) goto error_create_buffer; #else @@ -401,12 +400,43 @@ error_create_buffer: } } -static inline void -append_output_buffer_metadata(GstBuffer *outbuf, GstBuffer *inbuf, guint flags) +static gboolean +append_output_buffer_metadata(GstVaapiPostproc *postproc, GstBuffer *outbuf, + GstBuffer *inbuf, guint flags) { - gst_buffer_copy_into(outbuf, inbuf, flags | - GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META | GST_BUFFER_COPY_MEMORY, - 0, -1); + GstVaapiVideoMeta *inbuf_meta, *outbuf_meta; + GstVaapiSurfaceProxy *proxy; + + gst_buffer_copy_into(outbuf, inbuf, flags | GST_BUFFER_COPY_FLAGS, 0, -1); + + /* GstVideoCropMeta */ +#if GST_CHECK_VERSION(1,0,0) + if (!postproc->use_vpp) { + GstVideoCropMeta * const crop_meta = + gst_buffer_get_video_crop_meta(inbuf); + if (crop_meta) { + GstVideoCropMeta * const out_crop_meta = + gst_buffer_add_video_crop_meta(outbuf); + if (out_crop_meta) + *out_crop_meta = *crop_meta; + } + } +#endif + + /* GstVaapiVideoMeta */ + inbuf_meta = gst_buffer_get_vaapi_video_meta(inbuf); + g_return_val_if_fail(inbuf_meta != NULL, FALSE); + proxy = gst_vaapi_video_meta_get_surface_proxy(inbuf_meta); + + outbuf_meta = gst_buffer_get_vaapi_video_meta(outbuf); + g_return_val_if_fail(outbuf_meta != NULL, FALSE); + proxy = gst_vaapi_surface_proxy_copy(proxy); + if (!proxy) + return FALSE; + + gst_vaapi_video_meta_set_surface_proxy(outbuf_meta, proxy); + gst_vaapi_surface_proxy_unref(proxy); + return TRUE; } static gboolean @@ -467,6 +497,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, GstVaapiDeinterlaceState * const ds = &postproc->deinterlace_state; GstVaapiVideoMeta *inbuf_meta, *outbuf_meta; GstVaapiSurface *inbuf_surface, *outbuf_surface; + GstVaapiSurfaceProxy *proxy; GstVaapiFilterStatus status; GstClockTime timestamp; GstFlowReturn ret; @@ -569,10 +600,16 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, if (!fieldbuf) goto error_create_buffer; - outbuf_meta = gst_vaapi_video_meta_new_from_pool(postproc->filter_pool); + outbuf_meta = gst_buffer_get_vaapi_video_meta(fieldbuf); if (!outbuf_meta) goto error_create_meta; - outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); + + proxy = gst_vaapi_surface_proxy_new_from_pool( + GST_VAAPI_SURFACE_POOL(postproc->filter_pool)); + if (!proxy) + goto error_create_proxy; + gst_vaapi_video_meta_set_surface_proxy(outbuf_meta, proxy); + gst_vaapi_surface_proxy_unref(proxy); if (deint) { deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD : 0); @@ -604,15 +641,13 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, goto error_op_deinterlace; } + outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); gst_vaapi_filter_set_cropping_rectangle(postproc->filter, crop_rect); status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, outbuf_surface, flags); if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) goto error_process_vpp; - gst_buffer_set_vaapi_video_meta(fieldbuf, outbuf_meta); - gst_vaapi_video_meta_unref(outbuf_meta); - GST_BUFFER_TIMESTAMP(fieldbuf) = timestamp; GST_BUFFER_DURATION(fieldbuf) = postproc->field_duration; ret = gst_pad_push(trans->srcpad, fieldbuf); @@ -622,10 +657,16 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, fieldbuf = NULL; /* Second field */ - outbuf_meta = gst_vaapi_video_meta_new_from_pool(postproc->filter_pool); + outbuf_meta = gst_buffer_get_vaapi_video_meta(outbuf); if (!outbuf_meta) goto error_create_meta; - outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); + + proxy = gst_vaapi_surface_proxy_new_from_pool( + GST_VAAPI_SURFACE_POOL(postproc->filter_pool)); + if (!proxy) + goto error_create_proxy; + gst_vaapi_video_meta_set_surface_proxy(outbuf_meta, proxy); + gst_vaapi_surface_proxy_unref(proxy); if (deint) { deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD); @@ -643,6 +684,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, postproc->filter, deint_method, 0)) goto error_op_deinterlace; + outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); gst_vaapi_filter_set_cropping_rectangle(postproc->filter, crop_rect); status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, outbuf_surface, flags); @@ -655,11 +697,10 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration; GST_BUFFER_DURATION(outbuf) = postproc->field_duration; } - gst_buffer_set_vaapi_video_meta(outbuf, outbuf_meta); - gst_vaapi_video_meta_unref(outbuf_meta); if (deint && deint_refs) ds_add_buffer(ds, inbuf); + postproc->use_vpp = TRUE; return GST_FLOW_OK; /* ERRORS */ @@ -677,21 +718,24 @@ error_create_meta: { GST_ERROR("failed to create new output buffer meta"); gst_buffer_replace(&fieldbuf, NULL); - gst_vaapi_video_meta_unref(outbuf_meta); + return GST_FLOW_ERROR; + } +error_create_proxy: + { + GST_ERROR("failed to create surface proxy from pool"); + gst_buffer_replace(&fieldbuf, NULL); return GST_FLOW_ERROR; } error_op_deinterlace: { GST_ERROR("failed to apply deinterlacing filter"); gst_buffer_replace(&fieldbuf, NULL); - gst_vaapi_video_meta_unref(outbuf_meta); return GST_FLOW_NOT_SUPPORTED; } error_process_vpp: { GST_ERROR("failed to apply VPP filters (error %d)", status); gst_buffer_replace(&fieldbuf, NULL); - gst_vaapi_video_meta_unref(outbuf_meta); return GST_FLOW_ERROR; } error_push_buffer: @@ -729,7 +773,7 @@ gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf, fieldbuf = create_output_buffer(postproc); if (!fieldbuf) goto error_create_buffer; - append_output_buffer_metadata(fieldbuf, inbuf, 0); + append_output_buffer_metadata(postproc, fieldbuf, inbuf, 0); meta = gst_buffer_get_vaapi_video_meta(fieldbuf); fieldbuf_flags = flags; @@ -747,7 +791,7 @@ gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf, goto error_push_buffer; /* Second field */ - append_output_buffer_metadata(outbuf, inbuf, 0); + append_output_buffer_metadata(postproc, outbuf, inbuf, 0); meta = gst_buffer_get_vaapi_video_meta(outbuf); outbuf_flags = flags; @@ -792,7 +836,8 @@ gst_vaapipostproc_passthrough(GstBaseTransform *trans, GstBuffer *inbuf, if (!meta) goto error_invalid_buffer; - append_output_buffer_metadata(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS); + append_output_buffer_metadata(GST_VAAPIPOSTPROC(trans), outbuf, inbuf, + GST_BUFFER_COPY_TIMESTAMPS); return GST_FLOW_OK; /* ERRORS */ @@ -1144,14 +1189,13 @@ gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf, ret = GST_FLOW_NOT_SUPPORTED; if (postproc->flags) { /* Use VA/VPP extensions to process this frame */ - if (postproc->use_vpp && + if (postproc->has_vpp && (postproc->flags != GST_VAAPI_POSTPROC_FLAG_DEINTERLACE || deint_method_is_advanced(postproc->deinterlace_method))) { ret = gst_vaapipostproc_process_vpp(trans, buf, outbuf); if (ret != GST_FLOW_NOT_SUPPORTED) goto done; GST_WARNING("unsupported VPP filters. Disabling"); - postproc->use_vpp = FALSE; } /* Only append picture structure meta data (top/bottom field) */ diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 8dc3c8f95f..c27b29a1d0 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -168,6 +168,7 @@ struct _GstVaapiPostproc { gfloat contrast; guint get_va_surfaces : 1; + guint has_vpp : 1; guint use_vpp : 1; guint keep_aspect : 1; }; From 493337c4b154a789b5f5e9d86f95b4015d07b57e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Aug 2014 15:22:32 +0200 Subject: [PATCH 1777/3781] vaapipostproc: add support for "download" capability. Allow implicit conversions to raw video formats, while still keeping VA surfaces underneath. This allows for chaining the vaapipostproc element to a software-only element that takes care of maps/unmaps. e.g. xvimagesink. https://bugzilla.gnome.org/show_bug.cgi?id=720174 --- gst/vaapi/gstvaapipluginutil.c | 24 +++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 4 +++ gst/vaapi/gstvaapipostproc.c | 49 +++++++++++++++++++++++++++++----- 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 3d0c3cf294..40f5588633 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -582,6 +582,30 @@ cleanup: return feature; } +const gchar * +gst_vaapi_caps_feature_to_string (GstVaapiCapsFeature feature) +{ + const gchar *str; + + switch (feature) { +#if GST_CHECK_VERSION(1,1,0) + case GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY: + str = GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY; + break; + case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: + str = GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META; + break; + case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE: + str = GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE; + break; +#endif + default: + str = NULL; + break; + } + return str; +} + gboolean gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip) { diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 6380a11a44..1849f54e9f 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -92,6 +92,10 @@ G_GNUC_INTERNAL GstVaapiCapsFeature gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format); +G_GNUC_INTERNAL +const gchar * +gst_vaapi_caps_feature_to_string (GstVaapiCapsFeature feature); + /* Helpers to handle interlaced contents */ #if GST_CHECK_VERSION(1,0,0) # define GST_CAPS_INTERLACED_MODES \ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index fbebab96c0..b7dfebfa91 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -71,6 +71,15 @@ static const char gst_vaapipostproc_sink_caps_str[] = static const char gst_vaapipostproc_src_caps_str[] = GST_VAAPIPOSTPROC_SURFACE_CAPS ", " + GST_CAPS_INTERLACED_FALSE "; " +#if GST_CHECK_VERSION(1,0,0) + GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) ", " +#else + "video/x-raw-yuv, " + "width = " GST_VIDEO_SIZE_RANGE ", " + "height = " GST_VIDEO_SIZE_RANGE ", " + "framerate = " GST_VIDEO_FPS_RANGE ", " +#endif GST_CAPS_INTERLACED_FALSE; static GstStaticPadTemplate gst_vaapipostproc_sink_factory = @@ -1056,8 +1065,12 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); GstVideoInfo vi; - GstVideoFormat format; + GstVideoFormat format, out_format; GstCaps *out_caps; +#if GST_CHECK_VERSION(1,1,0) + GstVaapiCapsFeature feature; + const gchar *feature_str; +#endif guint width, height; /* Generate the sink pad caps, that could be fixated afterwards */ @@ -1094,21 +1107,45 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, GST_VIDEO_INFO_INTERLACE_MODE(&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; // Update size from user-specified parameters + format = GST_VIDEO_INFO_FORMAT(&vi); #if GST_CHECK_VERSION(1,1,0) - format = postproc->format; + out_format = postproc->format; #else - format = GST_VIDEO_FORMAT_ENCODED; + out_format = GST_VIDEO_FORMAT_ENCODED; #endif find_best_size(postproc, &vi, &width, &height); - gst_video_info_set_format(&vi, format, width, height); + gst_video_info_set_format(&vi, out_format, width, height); #if GST_CHECK_VERSION(1,1,0) out_caps = gst_video_info_to_caps(&vi); if (!out_caps) return NULL; - gst_caps_set_features(out_caps, 0, - gst_caps_features_new(GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL)); + feature = gst_vaapi_find_preferred_caps_feature( + GST_BASE_TRANSFORM_SRC_PAD(trans), out_format); + if (feature) { + if (out_format == GST_VIDEO_FORMAT_ENCODED && + feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) { + GstCaps *sink_caps, *peer_caps = + gst_pad_peer_query_caps(GST_BASE_TRANSFORM_SRC_PAD(trans), + postproc->allowed_srcpad_caps); + + gst_video_info_set_format(&vi, format, width, height); + sink_caps = gst_video_info_to_caps(&vi); + if (sink_caps) { + if (gst_caps_can_intersect(peer_caps, sink_caps)) + gst_caps_set_simple(out_caps, "format", G_TYPE_STRING, + gst_video_format_to_string(format), NULL); + gst_caps_unref(sink_caps); + } + gst_caps_unref(peer_caps); + } + + feature_str = gst_vaapi_caps_feature_to_string(feature); + if (feature_str) + gst_caps_set_features(out_caps, 0, + gst_caps_features_new(feature_str, NULL)); + } #else /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not reconstruct suitable caps for "encoded" video formats */ From b61d993e7d1372da37a7a93dfd9ca93d2afe80b4 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Aug 2014 15:22:32 +0200 Subject: [PATCH 1778/3781] vaapipostproc: add support for GLTextureUploadMeta output. This allows for vaapipostproc to be chained to the glimagesink element for instance. https://bugzilla.gnome.org/show_bug.cgi?id=735231 --- gst/vaapi/gstvaapipostproc.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index b7dfebfa91..fa6ffe5d0e 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -72,6 +72,11 @@ static const char gst_vaapipostproc_sink_caps_str[] = static const char gst_vaapipostproc_src_caps_str[] = GST_VAAPIPOSTPROC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " +#if GST_CHECK_VERSION(1,1,0) + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA") ", " + GST_CAPS_INTERLACED_FALSE "; " +#endif #if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) ", " #else @@ -994,6 +999,13 @@ expand_allowed_srcpad_caps(GstVaapiPostproc *postproc, GstCaps *caps) num_structures = gst_caps_get_size(caps); for (i = 0; i < num_structures; i++) { +#if GST_CHECK_VERSION(1,1,0) + GstCapsFeatures * const features = gst_caps_get_features (caps, i); + if (gst_caps_features_contains(features, + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META)) + continue; +#endif + GstStructure * const structure = gst_caps_get_structure(caps, i); if (!structure) continue; @@ -1124,15 +1136,26 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, feature = gst_vaapi_find_preferred_caps_feature( GST_BASE_TRANSFORM_SRC_PAD(trans), out_format); if (feature) { + feature_str = gst_vaapi_caps_feature_to_string(feature); + if (feature_str) + gst_caps_set_features(out_caps, 0, + gst_caps_features_new(feature_str, NULL)); + if (out_format == GST_VIDEO_FORMAT_ENCODED && - feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) { + feature != GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) { GstCaps *sink_caps, *peer_caps = gst_pad_peer_query_caps(GST_BASE_TRANSFORM_SRC_PAD(trans), postproc->allowed_srcpad_caps); + if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) + format = GST_VIDEO_FORMAT_RGBA; + gst_video_info_set_format(&vi, format, width, height); sink_caps = gst_video_info_to_caps(&vi); if (sink_caps) { + if (feature_str) + gst_caps_set_features(sink_caps, 0, + gst_caps_features_new(feature_str, NULL)); if (gst_caps_can_intersect(peer_caps, sink_caps)) gst_caps_set_simple(out_caps, "format", G_TYPE_STRING, gst_video_format_to_string(format), NULL); @@ -1140,11 +1163,6 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, } gst_caps_unref(peer_caps); } - - feature_str = gst_vaapi_caps_feature_to_string(feature); - if (feature_str) - gst_caps_set_features(out_caps, 0, - gst_caps_features_new(feature_str, NULL)); } #else /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not From 406aa37373e2b9917714eccd2834a45d18b61fd1 Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Thu, 13 Mar 2014 18:38:33 +0000 Subject: [PATCH 1779/3781] vaapipostproc: fix deinterlacing from non VA memory buffers. When we copy a buffer because we're moving it into VA-API memory, we need to copy flags. Otherwise, interlaced YUV buffers from a capture source (e.g. V4L2) don't get flagged as interlaced. https://bugzilla.gnome.org/show_bug.cgi?id=726270 Signed-off-by: Simon Farnsworth [reversed order of gst_buffer_copy_into() flags to match <1.0 code] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipluginbase.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 504fd8e0e4..922260fa61 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -700,7 +700,8 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, if (!success) goto error_copy_buffer; - gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); + gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_FLAGS | + GST_BUFFER_COPY_TIMESTAMPS, 0, -1); *outbuf_ptr = outbuf; return GST_FLOW_OK; From 33212d96346e25726da59a533ed5f0af89cfd568 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 16 Sep 2014 14:25:40 +0300 Subject: [PATCH 1780/3781] vaapisink: implement the GstNavigation interface This is useful for things like DVD menus, where key/mouse events would need to be forwarded from the upstream sink element. https://bugzilla.gnome.org/show_bug.cgi?id=711479 --- gst/vaapi/gstvaapisink.c | 139 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 2462737f8e..824c5e5121 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -41,6 +41,7 @@ #if GST_CHECK_VERSION(1,0,0) # include # include +# include #else # include # include @@ -107,6 +108,9 @@ gst_vaapisink_video_overlay_iface_init (GstVideoOverlayInterface * iface); static void gst_vaapisink_color_balance_iface_init (GstColorBalanceInterface * iface); +static void +gst_vaapisink_navigation_iface_init (GstNavigationInterface *iface); + G_DEFINE_TYPE_WITH_CODE (GstVaapiSink, gst_vaapisink, GST_TYPE_VIDEO_SINK, @@ -114,7 +118,9 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiSink, G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY, gst_vaapisink_video_overlay_iface_init); G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE, - gst_vaapisink_color_balance_iface_init)); + gst_vaapisink_color_balance_iface_init); + G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION, + gst_vaapisink_navigation_iface_init)); enum { @@ -321,6 +327,8 @@ gst_vaapisink_x11_handle_events (GstVaapiSink * sink) { GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); gboolean has_events, do_expose = FALSE; + guint pointer_x = 0, pointer_y = 0; + gboolean pointer_moved = FALSE; XEvent e; if (sink->window) { @@ -329,6 +337,72 @@ gst_vaapisink_x11_handle_events (GstVaapiSink * sink) Window x11_win = gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (sink->window)); + /* Track MousePointer interaction */ + for (;;) { + gst_vaapi_display_lock (display); + has_events = XCheckWindowEvent (x11_dpy, x11_win, + PointerMotionMask, &e); + gst_vaapi_display_unlock (display); + if (!has_events) + break; + + switch (e.type) { + case MotionNotify: + pointer_x = e.xmotion.x; + pointer_y = e.xmotion.y; + pointer_moved = TRUE; + break; + default: + break; + } + } + if (pointer_moved) { + gst_vaapi_display_lock (display); + gst_navigation_send_mouse_event (GST_NAVIGATION (sink), + "mouse-move", 0, e.xbutton.x, e.xbutton.y); + gst_vaapi_display_unlock (display); + } + + /* Track KeyPress, KeyRelease, ButtonPress, ButtonRelease */ + for (;;) { + KeySym keysym; + const char *key_str = NULL; + gst_vaapi_display_lock (display); + has_events = XCheckWindowEvent (x11_dpy, x11_win, + KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask + , &e); + gst_vaapi_display_unlock (display); + if (!has_events) + break; + + switch (e.type) { + case ButtonPress: + gst_navigation_send_mouse_event (GST_NAVIGATION (sink), + "mouse-button-press", e.xbutton.button, e.xbutton.x, e.xbutton.y); + break; + case ButtonRelease: + gst_navigation_send_mouse_event (GST_NAVIGATION (sink), + "mouse-button-release", e.xbutton.button, e.xbutton.x, e.xbutton.y); + break; + case KeyPress: + case KeyRelease: + gst_vaapi_display_lock (display); + keysym = XkbKeycodeToKeysym (x11_dpy, x11_win, + e.xkey.keycode, 0, 0); + if (keysym != NoSymbol) { + key_str = XKeysymToString (keysym); + } else { + key_str = "unknown"; + } + gst_vaapi_display_unlock (display); + gst_navigation_send_key_event (GST_NAVIGATION (sink), + e.type == KeyPress ? "key-press" : "key-release", key_str); + break; + default: + break; + } + } + /* Handle Expose + ConfigureNotify */ /* Need to lock whole loop or we corrupt the XEvent queue: */ for (;;) { @@ -353,7 +427,6 @@ gst_vaapisink_x11_handle_events (GstVaapiSink * sink) } if (do_expose) gst_vaapisink_video_overlay_expose (GST_VIDEO_OVERLAY (sink)); - /* FIXME: handle mouse and key events */ } return TRUE; } @@ -363,11 +436,19 @@ gst_vaapisink_x11_pre_start_event_thread (GstVaapiSink * sink) { GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11 (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); + static const int x11_event_mask = + (KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask | + ExposureMask | + StructureNotifyMask); if (sink->window) { XSelectInput (gst_vaapi_display_x11_get_display (display), gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (sink->window)), - StructureNotifyMask | ExposureMask); + x11_event_mask); } return TRUE; } @@ -743,6 +824,58 @@ gst_vaapisink_color_balance_iface_init (GstColorBalanceInterface * iface) #endif } +/* ------------------------------------------------------------------------ */ +/* --- GstNavigation interface --- */ +/* ------------------------------------------------------------------------ */ + +static void +gst_vaapisink_navigation_send_event (GstNavigation * navigation, + GstStructure * structure) +{ + GstVaapiSink *const sink = GST_VAAPISINK (navigation); + GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); + GstPad *peer; + + if ((peer = gst_pad_get_peer (GST_VAAPI_PLUGIN_BASE_SINK_PAD (sink)))) { + GstEvent *event; + GstVaapiRectangle *disp_rect = &sink->display_rect; + gdouble x, y, xscale = 1.0, yscale = 1.0; + + event = gst_event_new_navigation (structure); + + if (!sink->window) + return; + + /* We calculate scaling using the original video frames geometry to include + pixel aspect ratio scaling. */ + xscale = (gdouble) sink->video_width / disp_rect->width; + yscale = (gdouble) sink->video_height / disp_rect->height; + + /* Converting pointer coordinates to the non scaled geometry */ + if (gst_structure_get_double (structure, "pointer_x", &x)) { + x = MIN (x, disp_rect->x + disp_rect->width); + x = MAX (x - disp_rect->x, 0); + gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, + (gdouble) x * xscale, NULL); + } + if (gst_structure_get_double (structure, "pointer_y", &y)) { + y = MIN (y, disp_rect->y + disp_rect->height); + y = MAX (y - disp_rect->y, 0); + gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, + (gdouble) y * yscale, NULL); + } + + gst_pad_send_event (peer, event); + gst_object_unref (peer); + } +} + +static void +gst_vaapisink_navigation_iface_init (GstNavigationInterface * iface) +{ + iface->send_event = gst_vaapisink_navigation_send_event; +} + /* ------------------------------------------------------------------------ */ /* --- Common implementation --- */ /* ------------------------------------------------------------------------ */ From 039244bf771c5b0d0520f3ba59b0559497779517 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Sep 2014 13:23:17 +0200 Subject: [PATCH 1781/3781] vaapisink: fix GstNavigation "mouse-move" event. Really use the motion event coordinates to propagate the "mouse-move" event to upper layer, instead of those from a button event. Those are technically the same though. --- gst/vaapi/gstvaapisink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 824c5e5121..4bac224ba2 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -359,7 +359,7 @@ gst_vaapisink_x11_handle_events (GstVaapiSink * sink) if (pointer_moved) { gst_vaapi_display_lock (display); gst_navigation_send_mouse_event (GST_NAVIGATION (sink), - "mouse-move", 0, e.xbutton.x, e.xbutton.y); + "mouse-move", 0, pointer_x, pointer_y); gst_vaapi_display_unlock (display); } From 48e5bcbe7b37711247c96691666523f3b1f7452d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Sep 2014 13:39:55 +0200 Subject: [PATCH 1782/3781] vaapisink: fix GstNavigation "key-press" / "key-release" events. Fix arguments to XkbKeycodeToKeysym() for converting an X11 keycode to a KeySym. In particular, there is no such Window argument. Also make sure to check for, and use, the correct header where that new function is defined. Otherwise, default to the older XKeycodeToKeysym() function. --- configure.ac | 10 ++++++++++ gst/vaapi/gstvaapisink.c | 17 +++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 36285dc458..4cbfffd38a 100644 --- a/configure.ac +++ b/configure.ac @@ -559,6 +559,16 @@ if test "$enable_x11" = "yes"; then fi fi +dnl Check for XKB library +HAVE_XKBLIB=0 +if test $USE_X11 -eq 1; then + AC_CHECK_HEADERS([X11/XKBlib.h], [HAVE_XKBLIB=1], [:]) +fi +if test $HAVE_XKBLIB -eq 1; then + AC_DEFINE_UNQUOTED([HAVE_XKBLIB], 1, + [Defined to 1 if the XKB extension exists.]) +fi + dnl Check for XRandR HAVE_XRANDR=0 if test $USE_X11 -eq 1; then diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 4bac224ba2..99791c9e37 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -218,6 +218,20 @@ gst_vaapisink_backend_drm (void) #include #include +#if HAVE_XKBLIB +# include +#endif + +static inline KeySym +x11_keycode_to_keysym (Display * dpy, unsigned int kc) +{ +#if HAVE_XKBLIB + return XkbKeycodeToKeysym (dpy, kc, 0, 0); +#else + return XKeycodeToKeysym (dpy, kc, 0); +#endif +} + /* Checks whether a ConfigureNotify event is in the queue */ typedef struct _ConfigureNotifyEventPendingArgs ConfigureNotifyEventPendingArgs; struct _ConfigureNotifyEventPendingArgs @@ -387,8 +401,7 @@ gst_vaapisink_x11_handle_events (GstVaapiSink * sink) case KeyPress: case KeyRelease: gst_vaapi_display_lock (display); - keysym = XkbKeycodeToKeysym (x11_dpy, x11_win, - e.xkey.keycode, 0, 0); + keysym = x11_keycode_to_keysym (x11_dpy, e.xkey.keycode); if (keysym != NoSymbol) { key_str = XKeysymToString (keysym); } else { From 0b6d6d956ec5ae0993a3d7c17538efe7ea919dc6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Sep 2014 13:44:43 +0200 Subject: [PATCH 1783/3781] vaapisink: clean-ups (indentation, drop unused variables). --- gst/vaapi/gstvaapisink.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 99791c9e37..a1e1616397 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -74,6 +74,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapisink); #define GST_CAT_DEFAULT gst_debug_vaapisink /* Default template */ +/* *INDENT-OFF* */ static const char gst_vaapisink_sink_caps_str[] = #if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, @@ -89,6 +90,7 @@ static const char gst_vaapisink_sink_caps_str[] = #endif GST_VAAPI_SURFACE_CAPS; #endif +/* *INDENT-ON* */ static GstStaticPadTemplate gst_vaapisink_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", @@ -109,7 +111,7 @@ static void gst_vaapisink_color_balance_iface_init (GstColorBalanceInterface * iface); static void -gst_vaapisink_navigation_iface_init (GstNavigationInterface *iface); +gst_vaapisink_navigation_iface_init (GstNavigationInterface * iface); G_DEFINE_TYPE_WITH_CODE (GstVaapiSink, gst_vaapisink, @@ -354,8 +356,7 @@ gst_vaapisink_x11_handle_events (GstVaapiSink * sink) /* Track MousePointer interaction */ for (;;) { gst_vaapi_display_lock (display); - has_events = XCheckWindowEvent (x11_dpy, x11_win, - PointerMotionMask, &e); + has_events = XCheckWindowEvent (x11_dpy, x11_win, PointerMotionMask, &e); gst_vaapi_display_unlock (display); if (!has_events) break; @@ -373,7 +374,7 @@ gst_vaapisink_x11_handle_events (GstVaapiSink * sink) if (pointer_moved) { gst_vaapi_display_lock (display); gst_navigation_send_mouse_event (GST_NAVIGATION (sink), - "mouse-move", 0, pointer_x, pointer_y); + "mouse-move", 0, pointer_x, pointer_y); gst_vaapi_display_unlock (display); } @@ -383,8 +384,8 @@ gst_vaapisink_x11_handle_events (GstVaapiSink * sink) const char *key_str = NULL; gst_vaapi_display_lock (display); has_events = XCheckWindowEvent (x11_dpy, x11_win, - KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask - , &e); + KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask, + &e); gst_vaapi_display_unlock (display); if (!has_events) break; @@ -392,11 +393,12 @@ gst_vaapisink_x11_handle_events (GstVaapiSink * sink) switch (e.type) { case ButtonPress: gst_navigation_send_mouse_event (GST_NAVIGATION (sink), - "mouse-button-press", e.xbutton.button, e.xbutton.x, e.xbutton.y); + "mouse-button-press", e.xbutton.button, e.xbutton.x, e.xbutton.y); break; case ButtonRelease: gst_navigation_send_mouse_event (GST_NAVIGATION (sink), - "mouse-button-release", e.xbutton.button, e.xbutton.x, e.xbutton.y); + "mouse-button-release", e.xbutton.button, e.xbutton.x, + e.xbutton.y); break; case KeyPress: case KeyRelease: @@ -409,7 +411,7 @@ gst_vaapisink_x11_handle_events (GstVaapiSink * sink) } gst_vaapi_display_unlock (display); gst_navigation_send_key_event (GST_NAVIGATION (sink), - e.type == KeyPress ? "key-press" : "key-release", key_str); + e.type == KeyPress ? "key-press" : "key-release", key_str); break; default: break; @@ -449,14 +451,9 @@ gst_vaapisink_x11_pre_start_event_thread (GstVaapiSink * sink) { GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11 (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); - static const int x11_event_mask = - (KeyPressMask | - KeyReleaseMask | - ButtonPressMask | - ButtonReleaseMask | - PointerMotionMask | - ExposureMask | - StructureNotifyMask); + static const int x11_event_mask = (KeyPressMask | KeyReleaseMask | + ButtonPressMask | ButtonReleaseMask | PointerMotionMask | + ExposureMask | StructureNotifyMask); if (sink->window) { XSelectInput (gst_vaapi_display_x11_get_display (display), @@ -846,7 +843,6 @@ gst_vaapisink_navigation_send_event (GstNavigation * navigation, GstStructure * structure) { GstVaapiSink *const sink = GST_VAAPISINK (navigation); - GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); GstPad *peer; if ((peer = gst_pad_get_peer (GST_VAAPI_PLUGIN_BASE_SINK_PAD (sink)))) { @@ -871,7 +867,7 @@ gst_vaapisink_navigation_send_event (GstNavigation * navigation, gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, (gdouble) x * xscale, NULL); } - if (gst_structure_get_double (structure, "pointer_y", &y)) { + if (gst_structure_get_double (structure, "pointer_y", &y)) { y = MIN (y, disp_rect->y + disp_rect->height); y = MAX (y - disp_rect->y, 0); gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, From 541f721fabfcc321dacbedad75047e8b2e96c985 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Sep 2014 10:14:24 +0200 Subject: [PATCH 1784/3781] display: add support for DRM Render-Nodes. Add support for DRM Render-Nodes. This is a new feature that appeared in kernel 3.12 for experimentation purposes, but was later declared stable enough in kernel 3.15 for getting enabled by default. This allows headless usages without authentication at all, i.e. usages through plain ssh connections is possible. --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 47 ++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 9114bfc478..be748b9f0d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -42,6 +42,15 @@ static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_DRM; +typedef enum +{ + DRM_DEVICE_LEGACY = 1, + DRM_DEVICE_RENDERNODES, +} DRMDeviceType; + +static DRMDeviceType g_drm_device_type; +static GMutex g_drm_device_type_lock; + /* Get default device path. Actually, the first match in the DRM subsystem */ static const gchar * get_default_device_path (GstVaapiDisplay * display) @@ -65,6 +74,17 @@ get_default_device_path (GstVaapiDisplay * display) 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); @@ -176,7 +196,8 @@ set_device_path_from_fd (GstVaapiDisplay * display, gint drm_device) path_length = strlen (path); if (str + busid_length >= path + path_length) continue; - if (strncmp (&str[busid_length], "/drm/card", 9) != 0) + if (strncmp (&str[busid_length], "/drm/card", 9) != 0 && + strncmp (&str[busid_length], "/drm/renderD", 12) != 0) continue; device = udev_device_new_from_syspath (udev, path); @@ -348,8 +369,28 @@ gst_vaapi_display_drm_class (void) GstVaapiDisplay * gst_vaapi_display_drm_new (const gchar * device_path) { - return gst_vaapi_display_new (gst_vaapi_display_drm_class (), - GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) device_path); + GstVaapiDisplay *display; + guint types[2], i, num_types = 0; + + if (device_path) + types[num_types++] = 0; + else if (g_drm_device_type) + types[num_types++] = g_drm_device_type; + else { + types[num_types++] = DRM_DEVICE_RENDERNODES; + types[num_types++] = DRM_DEVICE_LEGACY; + } + + g_mutex_lock (&g_drm_device_type_lock); + for (i = 0; i < num_types; i++) { + g_drm_device_type = types[i]; + display = gst_vaapi_display_new (gst_vaapi_display_drm_class (), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) device_path); + if (display || device_path) + break; + } + g_mutex_unlock (&g_drm_device_type_lock); + return display; } /** From 58eefcac9a1f70b3e412fb380247f63873391745 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 29 Oct 2014 15:45:44 +0200 Subject: [PATCH 1785/3781] configure: echoing installation prefix path --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 4cbfffd38a..6d6fdca181 100644 --- a/configure.ac +++ b/configure.ac @@ -939,6 +939,7 @@ AS_IF([test $USE_WAYLAND -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS wayland"]) echo echo $PACKAGE configuration summary: echo +echo Installation Prefix .............. : ${prefix} echo GStreamer API version ............ : $GST_API_VERSION echo VA-API version ................... : $VA_VERSION_STR echo Video encoding ................... : $(yesno $USE_ENCODERS) From 7f3795c9fb8b974082cead5a18713df9e2060cba Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 29 Oct 2014 15:46:12 +0200 Subject: [PATCH 1786/3781] encode: Attach the codec-data to out caps only based on negotiated caps Attach the codec_data to out_caps only if downstream needed. For eg: h264 encoder doesn't need to stuff codec_data to the src caps if the negotiated caps has a stream format of byte-stream. https://bugzilla.gnome.org/show_bug.cgi?id=734902 --- gst/vaapi/gstvaapiencode.c | 10 ++++++---- gst/vaapi/gstvaapiencode.h | 2 ++ gst/vaapi/gstvaapiencode_h264.c | 7 +++++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 28f4fada5d..6209f369e5 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -241,10 +241,12 @@ ensure_output_state (GstVaapiEncode * encode) encode->output_state = gst_video_encoder_set_output_state (venc, out_caps, encode->input_state); - status = gst_vaapi_encoder_get_codec_data (encode->encoder, - &encode->output_state->codec_data); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return FALSE; + if (encode->need_codec_data) { + status = gst_vaapi_encoder_get_codec_data (encode->encoder, + &encode->output_state->codec_data); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return FALSE; + } #if GST_CHECK_VERSION(1,0,0) if (!gst_video_encoder_negotiate (venc)) diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index a4208a2044..03c6a104c5 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -55,6 +55,8 @@ struct _GstVaapiEncode GstVaapiEncoder *encoder; GstVideoCodecState *input_state; gboolean input_state_changed; + /* needs to be set by the subclass implementation */ + gboolean need_codec_data; GstVideoCodecState *output_state; GPtrArray *prop_values; }; diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 815f2a610d..93d6288c19 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -37,8 +37,9 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); #define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug -#define GST_CODEC_CAPS \ - "video/x-h264, " \ +#define GST_CODEC_CAPS \ + "video/x-h264, " \ + "stream-format = (string) { avc, byte-stream }, " \ "alignment = (string) au" /* *INDENT-OFF* */ @@ -238,6 +239,8 @@ gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, encode->is_avc ? "avc" : "byte-stream", NULL); + base_encode->need_codec_data = encode->is_avc; + /* XXX: update profile and level information */ return caps; } From b58bdd1a1239c2996c42b417db31632d596de9c4 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 29 Oct 2014 15:46:47 +0200 Subject: [PATCH 1787/3781] vaapidecode: Expose the supported profiles as caps to upstream This will allows the playbin to fallback to Software Decoder if the Hardware Decoder does not support a particular profile. https://bugzilla.gnome.org/show_bug.cgi?id=730997 --- gst/vaapi/gstvaapidecode.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 989f7a19c8..11ae6bb743 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -917,17 +917,26 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) const GstVaapiProfile profile = g_array_index(profiles, GstVaapiProfile, i); const gchar *media_type_name; + const gchar *profile_name; + GstStructure *structure; media_type_name = gst_vaapi_profile_get_media_type_name(profile); if (!media_type_name) continue; + profile_name = gst_vaapi_profile_get_name(profile); + if (!profile_name) + continue; + caps = gst_caps_from_string(media_type_name); if (!caps) continue; + structure = gst_caps_get_structure (caps, 0); + gst_structure_set (structure, "profile", G_TYPE_STRING, profile_name, NULL); + allowed_caps = gst_caps_merge(allowed_caps, caps); } - decode->allowed_caps = allowed_caps; + decode->allowed_caps = gst_caps_simplify (allowed_caps); g_array_unref(profiles); return TRUE; From c472403bb4380b9bdb70ee9205758cd0cae570ed Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 29 Oct 2014 15:45:50 +0100 Subject: [PATCH 1788/3781] codecparsers: update to gst-vaapi-branch commit f9d3bde. 2218b02 h264parse: expose parsed profile and level to downstream 3dbfab4 h264parse: return flushing if we get chained while being set to READY d40fa8b h264: fix frame packing SEI parsing 32d40be h264: Use proper bit_reader api while parsing buffering_period SEI b3e022e h264: initialize some fields of pic_timing structure a70661d vc1: fix expected level in sequence-layer parsing unit test 6cee88d vc1: fix level values for simple/main profile 356c189 vc1: add unit test for sequence-layer parsing ab9f641 vc1: take care of endianness when parsing sequence-layer 8dc8e35 mpeg4: fix vlc table used for sprite trajectory --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 2d53b693e8..f9d3bde2cb 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 2d53b693e8c0cce8f395bce0cb1817c51db345af +Subproject commit f9d3bde2cb4eabedadf2442a4a68d7215ccd173b From c537648c5b7d7f4041101f4f3ce175adb021315c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 29 Oct 2014 16:35:46 +0100 Subject: [PATCH 1789/3781] filter: re-indent all GstVaapiFilter related source code. --- gst-libs/gst/vaapi/gstvaapifilter.c | 1920 +++++++++++++-------------- gst-libs/gst/vaapi/gstvaapifilter.h | 113 +- 2 files changed, 1008 insertions(+), 1025 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index c201643563..68d27f8540 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -39,37 +39,39 @@ ((GstVaapiFilter *)(obj)) typedef struct _GstVaapiFilterOpData GstVaapiFilterOpData; -struct _GstVaapiFilterOpData { - GstVaapiFilterOp op; - GParamSpec *pspec; - volatile gint ref_count; - guint va_type; - guint va_subtype; - gpointer va_caps; - guint va_num_caps; - guint va_cap_size; - VABufferID va_buffer; - guint va_buffer_size; - guint is_enabled : 1; +struct _GstVaapiFilterOpData +{ + GstVaapiFilterOp op; + GParamSpec *pspec; + volatile gint ref_count; + guint va_type; + guint va_subtype; + gpointer va_caps; + guint va_num_caps; + guint va_cap_size; + VABufferID va_buffer; + guint va_buffer_size; + guint is_enabled:1; }; -struct _GstVaapiFilter { - /*< private >*/ - GstVaapiMiniObject parent_instance; +struct _GstVaapiFilter +{ + /*< private > */ + GstVaapiMiniObject parent_instance; - GstVaapiDisplay *display; - VADisplay va_display; - VAConfigID va_config; - VAContextID va_context; - GPtrArray *operations; - GstVideoFormat format; - GArray *formats; - GArray *forward_references; - GArray *backward_references; - GstVaapiRectangle crop_rect; - GstVaapiRectangle target_rect; - guint use_crop_rect : 1; - guint use_target_rect : 1; + GstVaapiDisplay *display; + VADisplay va_display; + VAConfigID va_config; + VAContextID va_context; + GPtrArray *operations; + GstVideoFormat format; + GArray *formats; + GArray *forward_references; + GArray *backward_references; + GstVaapiRectangle crop_rect; + GstVaapiRectangle target_rect; + guint use_crop_rect:1; + guint use_target_rect:1; }; /* ------------------------------------------------------------------------- */ @@ -77,55 +79,55 @@ struct _GstVaapiFilter { /* ------------------------------------------------------------------------- */ GType -gst_vaapi_deinterlace_method_get_type(void) +gst_vaapi_deinterlace_method_get_type (void) { - static gsize g_type = 0; + static gsize g_type = 0; - static const GEnumValue enum_values[] = { - { GST_VAAPI_DEINTERLACE_METHOD_NONE, - "Disable deinterlacing", "none" }, - { GST_VAAPI_DEINTERLACE_METHOD_BOB, - "Bob deinterlacing", "bob" }, + static const GEnumValue enum_values[] = { + {GST_VAAPI_DEINTERLACE_METHOD_NONE, + "Disable deinterlacing", "none"}, + {GST_VAAPI_DEINTERLACE_METHOD_BOB, + "Bob deinterlacing", "bob"}, #if USE_VA_VPP - { GST_VAAPI_DEINTERLACE_METHOD_WEAVE, - "Weave deinterlacing", "weave" }, - { GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE, - "Motion adaptive deinterlacing", "motion-adaptive" }, - { GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED, - "Motion compensated deinterlacing", "motion-compensated" }, + {GST_VAAPI_DEINTERLACE_METHOD_WEAVE, + "Weave deinterlacing", "weave"}, + {GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE, + "Motion adaptive deinterlacing", "motion-adaptive"}, + {GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED, + "Motion compensated deinterlacing", "motion-compensated"}, #endif - { 0, NULL, NULL }, - }; + {0, NULL, NULL}, + }; - if (g_once_init_enter(&g_type)) { - const GType type = - g_enum_register_static("GstVaapiDeinterlaceMethod", enum_values); - g_once_init_leave(&g_type, type); - } - return g_type; + if (g_once_init_enter (&g_type)) { + const GType type = + g_enum_register_static ("GstVaapiDeinterlaceMethod", enum_values); + g_once_init_leave (&g_type, type); + } + return g_type; } GType -gst_vaapi_deinterlace_flags_get_type(void) +gst_vaapi_deinterlace_flags_get_type (void) { - static gsize g_type = 0; + static gsize g_type = 0; - static const GEnumValue enum_values[] = { - { GST_VAAPI_DEINTERLACE_FLAG_TFF, - "Top-field first", "top-field-first" }, - { GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD, - "One field", "one-field" }, - { GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD, - "Top field", "top-field" }, - { 0, NULL, NULL } - }; + static const GEnumValue enum_values[] = { + {GST_VAAPI_DEINTERLACE_FLAG_TFF, + "Top-field first", "top-field-first"}, + {GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD, + "One field", "one-field"}, + {GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD, + "Top field", "top-field"}, + {0, NULL, NULL} + }; - if (g_once_init_enter(&g_type)) { - const GType type = - g_enum_register_static("GstVaapiDeinterlaceFlags", enum_values); - g_once_init_leave(&g_type, type); - } - return g_type; + if (g_once_init_enter (&g_type)) { + const GType type = + g_enum_register_static ("GstVaapiDeinterlaceFlags", enum_values); + g_once_init_leave (&g_type, type); + } + return g_type; } /* ------------------------------------------------------------------------- */ @@ -134,100 +136,99 @@ gst_vaapi_deinterlace_flags_get_type(void) #if USE_VA_VPP static VAProcFilterType * -vpp_get_filters_unlocked(GstVaapiFilter *filter, guint *num_filters_ptr) +vpp_get_filters_unlocked (GstVaapiFilter * filter, guint * num_filters_ptr) { - VAProcFilterType *filters = NULL; - guint num_filters = 0; - VAStatus va_status; + VAProcFilterType *filters = NULL; + guint num_filters = 0; + VAStatus va_status; - num_filters = VAProcFilterCount; - filters = g_malloc_n(num_filters, sizeof(*filters)); - if (!filters) - goto error; + num_filters = VAProcFilterCount; + filters = g_malloc_n (num_filters, sizeof (*filters)); + if (!filters) + goto error; - va_status = vaQueryVideoProcFilters(filter->va_display, filter->va_context, - filters, &num_filters); + va_status = vaQueryVideoProcFilters (filter->va_display, filter->va_context, + filters, &num_filters); - // Try to reallocate to the expected number of filters - if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) { - VAProcFilterType * const new_filters = - g_try_realloc_n(filters, num_filters, sizeof(*new_filters)); - if (!new_filters) - goto error; - filters = new_filters; + // Try to reallocate to the expected number of filters + if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) { + VAProcFilterType *const new_filters = + g_try_realloc_n (filters, num_filters, sizeof (*new_filters)); + if (!new_filters) + goto error; + filters = new_filters; - va_status = vaQueryVideoProcFilters(filter->va_display, - filter->va_context, filters, &num_filters); - } - if (!vaapi_check_status(va_status, "vaQueryVideoProcFilters()")) - goto error; + va_status = vaQueryVideoProcFilters (filter->va_display, + filter->va_context, filters, &num_filters); + } + if (!vaapi_check_status (va_status, "vaQueryVideoProcFilters()")) + goto error; - *num_filters_ptr = num_filters; - return filters; + *num_filters_ptr = num_filters; + return filters; error: - g_free(filters); - return NULL; + g_free (filters); + return NULL; } static VAProcFilterType * -vpp_get_filters(GstVaapiFilter *filter, guint *num_filters_ptr) +vpp_get_filters (GstVaapiFilter * filter, guint * num_filters_ptr) { - VAProcFilterType *filters; + VAProcFilterType *filters; - GST_VAAPI_DISPLAY_LOCK(filter->display); - filters = vpp_get_filters_unlocked(filter, num_filters_ptr); - GST_VAAPI_DISPLAY_UNLOCK(filter->display); - return filters; + GST_VAAPI_DISPLAY_LOCK (filter->display); + filters = vpp_get_filters_unlocked (filter, num_filters_ptr); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); + return filters; } static gpointer -vpp_get_filter_caps_unlocked( - GstVaapiFilter *filter, VAProcFilterType type, - guint cap_size, guint *num_caps_ptr) +vpp_get_filter_caps_unlocked (GstVaapiFilter * filter, VAProcFilterType type, + guint cap_size, guint * num_caps_ptr) { - gpointer caps; - guint num_caps = 1; - VAStatus va_status; + gpointer caps; + guint num_caps = 1; + VAStatus va_status; - caps = g_malloc(cap_size); - if (!caps) - goto error; + caps = g_malloc (cap_size); + if (!caps) + goto error; - va_status = vaQueryVideoProcFilterCaps(filter->va_display, + va_status = vaQueryVideoProcFilterCaps (filter->va_display, + filter->va_context, type, caps, &num_caps); + + // Try to reallocate to the expected number of filters + if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) { + gpointer const new_caps = g_try_realloc_n (caps, num_caps, cap_size); + if (!new_caps) + goto error; + caps = new_caps; + + va_status = vaQueryVideoProcFilterCaps (filter->va_display, filter->va_context, type, caps, &num_caps); + } + if (!vaapi_check_status (va_status, "vaQueryVideoProcFilterCaps()")) + goto error; - // Try to reallocate to the expected number of filters - if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) { - gpointer const new_caps = g_try_realloc_n(caps, num_caps, cap_size); - if (!new_caps) - goto error; - caps = new_caps; - - va_status = vaQueryVideoProcFilterCaps(filter->va_display, - filter->va_context, type, caps, &num_caps); - } - if (!vaapi_check_status(va_status, "vaQueryVideoProcFilterCaps()")) - goto error; - - *num_caps_ptr = num_caps; - return caps; + *num_caps_ptr = num_caps; + return caps; error: - g_free(caps); - return NULL; + g_free (caps); + return NULL; } static gpointer -vpp_get_filter_caps(GstVaapiFilter *filter, VAProcFilterType type, - guint cap_size, guint *num_caps_ptr) +vpp_get_filter_caps (GstVaapiFilter * filter, VAProcFilterType type, + guint cap_size, guint * num_caps_ptr) { - gpointer caps; + gpointer caps; - GST_VAAPI_DISPLAY_LOCK(filter->display); - caps = vpp_get_filter_caps_unlocked(filter, type, cap_size, num_caps_ptr); - GST_VAAPI_DISPLAY_UNLOCK(filter->display); - return caps; + GST_VAAPI_DISPLAY_LOCK (filter->display); + caps = vpp_get_filter_caps_unlocked (filter, type, cap_size, num_caps_ptr); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); + return caps; } #endif @@ -238,647 +239,631 @@ vpp_get_filter_caps(GstVaapiFilter *filter, VAProcFilterType type, #if USE_VA_VPP #define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN -enum { - PROP_0, +enum +{ + PROP_0, - PROP_FORMAT = GST_VAAPI_FILTER_OP_FORMAT, - PROP_CROP = GST_VAAPI_FILTER_OP_CROP, - PROP_DENOISE = GST_VAAPI_FILTER_OP_DENOISE, - PROP_SHARPEN = GST_VAAPI_FILTER_OP_SHARPEN, - PROP_HUE = GST_VAAPI_FILTER_OP_HUE, - PROP_SATURATION = GST_VAAPI_FILTER_OP_SATURATION, - PROP_BRIGHTNESS = GST_VAAPI_FILTER_OP_BRIGHTNESS, - PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST, - PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING, + PROP_FORMAT = GST_VAAPI_FILTER_OP_FORMAT, + PROP_CROP = GST_VAAPI_FILTER_OP_CROP, + PROP_DENOISE = GST_VAAPI_FILTER_OP_DENOISE, + PROP_SHARPEN = GST_VAAPI_FILTER_OP_SHARPEN, + PROP_HUE = GST_VAAPI_FILTER_OP_HUE, + PROP_SATURATION = GST_VAAPI_FILTER_OP_SATURATION, + PROP_BRIGHTNESS = GST_VAAPI_FILTER_OP_BRIGHTNESS, + PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST, + PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING, - N_PROPERTIES + N_PROPERTIES }; static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; + static gsize g_properties_initialized = FALSE; static void -init_properties(void) +init_properties (void) { - /** - * GstVaapiFilter:format: - * - * The forced output pixel format, expressed as a #GstVideoFormat. - */ - g_properties[PROP_FORMAT] = - g_param_spec_enum("format", - "Format", - "The forced output pixel format", - GST_TYPE_VIDEO_FORMAT, - DEFAULT_FORMAT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFilter:format: + * + * The forced output pixel format, expressed as a #GstVideoFormat. + */ + g_properties[PROP_FORMAT] = g_param_spec_enum ("format", + "Format", + "The forced output pixel format", + GST_TYPE_VIDEO_FORMAT, + DEFAULT_FORMAT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - /** - * GstVaapiFilter:crop-rect: - * - * The cropping rectangle, expressed as a #GstVaapiRectangle. - */ - g_properties[PROP_CROP] = - g_param_spec_boxed("crop-rect", - "Cropping Rectangle", - "The cropping rectangle", - GST_VAAPI_TYPE_RECTANGLE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFilter:crop-rect: + * + * The cropping rectangle, expressed as a #GstVaapiRectangle. + */ + g_properties[PROP_CROP] = g_param_spec_boxed ("crop-rect", + "Cropping Rectangle", + "The cropping rectangle", + GST_VAAPI_TYPE_RECTANGLE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - /** - * GstVaapiFilter:denoise: - * - * The level of noise reduction to apply. - */ - g_properties[PROP_DENOISE] = - g_param_spec_float("denoise", - "Denoising Level", - "The level of denoising to apply", - 0.0, 1.0, 0.0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFilter:denoise: + * + * The level of noise reduction to apply. + */ + g_properties[PROP_DENOISE] = g_param_spec_float ("denoise", + "Denoising Level", + "The level of denoising to apply", + 0.0, 1.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - /** - * GstVaapiFilter:sharpen: - * - * The level of sharpening to apply for positive values, or the - * level of blurring for negative values. - */ - g_properties[PROP_SHARPEN] = - g_param_spec_float("sharpen", - "Sharpening Level", - "The level of sharpening/blurring to apply", - -1.0, 1.0, 0.0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFilter:sharpen: + * + * The level of sharpening to apply for positive values, or the + * level of blurring for negative values. + */ + g_properties[PROP_SHARPEN] = g_param_spec_float ("sharpen", + "Sharpening Level", + "The level of sharpening/blurring to apply", + -1.0, 1.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - /** - * GstVaapiFilter:hue: - * - * The color hue, expressed as a float value. Range is -180.0 to - * 180.0. Default value is 0.0 and represents no modification. - */ - g_properties[PROP_HUE] = - g_param_spec_float("hue", - "Hue", - "The color hue value", - -180.0, 180.0, 0.0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFilter:hue: + * + * The color hue, expressed as a float value. Range is -180.0 to + * 180.0. Default value is 0.0 and represents no modification. + */ + g_properties[PROP_HUE] = g_param_spec_float ("hue", + "Hue", + "The color hue value", + -180.0, 180.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - /** - * GstVaapiFilter:saturation: - * - * The color saturation, expressed as a float value. Range is 0.0 - * to 2.0. Default value is 1.0 and represents no modification. - */ - g_properties[PROP_SATURATION] = - g_param_spec_float("saturation", - "Saturation", - "The color saturation value", - 0.0, 2.0, 1.0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFilter:saturation: + * + * The color saturation, expressed as a float value. Range is 0.0 to + * 2.0. Default value is 1.0 and represents no modification. + */ + g_properties[PROP_SATURATION] = g_param_spec_float ("saturation", + "Saturation", + "The color saturation value", + 0.0, 2.0, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - /** - * GstVaapiFilter:brightness: - * - * The color brightness, expressed as a float value. Range is -1.0 - * to 1.0. Default value is 0.0 and represents no modification. - */ - g_properties[PROP_BRIGHTNESS] = - g_param_spec_float("brightness", - "Brightness", - "The color brightness value", - -1.0, 1.0, 0.0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFilter:brightness: + * + * The color brightness, expressed as a float value. Range is -1.0 + * to 1.0. Default value is 0.0 and represents no modification. + */ + g_properties[PROP_BRIGHTNESS] = g_param_spec_float ("brightness", + "Brightness", + "The color brightness value", + -1.0, 1.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - /** - * GstVaapiFilter:contrast: - * - * The color contrast, expressed as a float value. Range is 0.0 to - * 2.0. Default value is 1.0 and represents no modification. - */ - g_properties[PROP_CONTRAST] = - g_param_spec_float("contrast", - "Contrast", - "The color contrast value", - 0.0, 2.0, 1.0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFilter:contrast: + * + * The color contrast, expressed as a float value. Range is 0.0 to + * 2.0. Default value is 1.0 and represents no modification. + */ + g_properties[PROP_CONTRAST] = g_param_spec_float ("contrast", + "Contrast", + "The color contrast value", + 0.0, 2.0, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - /** - * GstVaapiFilter:deinterlace-method: - * - * The deinterlacing algorithm to apply, expressed a an enum - * value. See #GstVaapiDeinterlaceMethod. - */ - g_properties[PROP_DEINTERLACING] = - g_param_spec_enum("deinterlace", - "Deinterlacing Method", - "Deinterlacing method to apply", - GST_VAAPI_TYPE_DEINTERLACE_METHOD, - GST_VAAPI_DEINTERLACE_METHOD_NONE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFilter:deinterlace-method: + * + * The deinterlacing algorithm to apply, expressed a an enum + * value. See #GstVaapiDeinterlaceMethod. + */ + g_properties[PROP_DEINTERLACING] = g_param_spec_enum ("deinterlace", + "Deinterlacing Method", + "Deinterlacing method to apply", + GST_VAAPI_TYPE_DEINTERLACE_METHOD, + GST_VAAPI_DEINTERLACE_METHOD_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); } static void -ensure_properties(void) +ensure_properties (void) { - if (g_once_init_enter(&g_properties_initialized)) { - init_properties(); - g_once_init_leave(&g_properties_initialized, TRUE); - } + if (g_once_init_enter (&g_properties_initialized)) { + init_properties (); + g_once_init_leave (&g_properties_initialized, TRUE); + } } static void -op_data_free(GstVaapiFilterOpData *op_data) +op_data_free (GstVaapiFilterOpData * op_data) { - g_free(op_data->va_caps); - g_slice_free(GstVaapiFilterOpData, op_data); + g_free (op_data->va_caps); + g_slice_free (GstVaapiFilterOpData, op_data); } static inline gpointer -op_data_new(GstVaapiFilterOp op, GParamSpec *pspec) +op_data_new (GstVaapiFilterOp op, GParamSpec * pspec) { - GstVaapiFilterOpData *op_data; + GstVaapiFilterOpData *op_data; - op_data = g_slice_new0(GstVaapiFilterOpData); - if (!op_data) - return NULL; + op_data = g_slice_new0 (GstVaapiFilterOpData); + if (!op_data) + return NULL; - op_data->op = op; - op_data->pspec = pspec; - op_data->ref_count = 1; - op_data->va_buffer = VA_INVALID_ID; + op_data->op = op; + op_data->pspec = pspec; + op_data->ref_count = 1; + op_data->va_buffer = VA_INVALID_ID; - switch (op) { + switch (op) { case GST_VAAPI_FILTER_OP_FORMAT: case GST_VAAPI_FILTER_OP_CROP: - op_data->va_type = VAProcFilterNone; - break; + op_data->va_type = VAProcFilterNone; + break; case GST_VAAPI_FILTER_OP_DENOISE: - op_data->va_type = VAProcFilterNoiseReduction; - op_data->va_cap_size = sizeof(VAProcFilterCap); - op_data->va_buffer_size = sizeof(VAProcFilterParameterBuffer); - break; + op_data->va_type = VAProcFilterNoiseReduction; + op_data->va_cap_size = sizeof (VAProcFilterCap); + op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer); + break; case GST_VAAPI_FILTER_OP_SHARPEN: - op_data->va_type = VAProcFilterSharpening; - op_data->va_cap_size = sizeof(VAProcFilterCap); - op_data->va_buffer_size = sizeof(VAProcFilterParameterBuffer); - break; + op_data->va_type = VAProcFilterSharpening; + op_data->va_cap_size = sizeof (VAProcFilterCap); + op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer); + break; case GST_VAAPI_FILTER_OP_HUE: - op_data->va_subtype = VAProcColorBalanceHue; - goto op_colorbalance; + op_data->va_subtype = VAProcColorBalanceHue; + goto op_colorbalance; case GST_VAAPI_FILTER_OP_SATURATION: - op_data->va_subtype = VAProcColorBalanceSaturation; - goto op_colorbalance; + op_data->va_subtype = VAProcColorBalanceSaturation; + goto op_colorbalance; case GST_VAAPI_FILTER_OP_BRIGHTNESS: - op_data->va_subtype = VAProcColorBalanceBrightness; - goto op_colorbalance; + op_data->va_subtype = VAProcColorBalanceBrightness; + goto op_colorbalance; case GST_VAAPI_FILTER_OP_CONTRAST: - op_data->va_subtype = VAProcColorBalanceContrast; + op_data->va_subtype = VAProcColorBalanceContrast; op_colorbalance: - op_data->va_type = VAProcFilterColorBalance; - op_data->va_cap_size = sizeof(VAProcFilterCapColorBalance); - op_data->va_buffer_size = sizeof(VAProcFilterParameterBufferColorBalance); - break; + op_data->va_type = VAProcFilterColorBalance; + op_data->va_cap_size = sizeof (VAProcFilterCapColorBalance); + op_data->va_buffer_size = + sizeof (VAProcFilterParameterBufferColorBalance); + break; case GST_VAAPI_FILTER_OP_DEINTERLACING: - op_data->va_type = VAProcFilterDeinterlacing; - op_data->va_cap_size = sizeof(VAProcFilterCapDeinterlacing); - op_data->va_buffer_size = sizeof(VAProcFilterParameterBufferDeinterlacing); - break; + op_data->va_type = VAProcFilterDeinterlacing; + op_data->va_cap_size = sizeof (VAProcFilterCapDeinterlacing); + op_data->va_buffer_size = + sizeof (VAProcFilterParameterBufferDeinterlacing); + break; default: - g_assert(0 && "unsupported operation"); - goto error; - } - return op_data; + g_assert (0 && "unsupported operation"); + goto error; + } + return op_data; error: - op_data_free(op_data); - return NULL; + op_data_free (op_data); + return NULL; } static inline gpointer -op_data_ref(gpointer data) +op_data_ref (gpointer data) { - GstVaapiFilterOpData * const op_data = data; + GstVaapiFilterOpData *const op_data = data; - g_return_val_if_fail(op_data != NULL, NULL); + g_return_val_if_fail (op_data != NULL, NULL); - g_atomic_int_inc(&op_data->ref_count); - return op_data; + g_atomic_int_inc (&op_data->ref_count); + return op_data; } static void -op_data_unref(gpointer data) +op_data_unref (gpointer data) { - GstVaapiFilterOpData * const op_data = data; + GstVaapiFilterOpData *const op_data = data; - g_return_if_fail(op_data != NULL); - g_return_if_fail(op_data->ref_count > 0); + g_return_if_fail (op_data != NULL); + g_return_if_fail (op_data->ref_count > 0); - if (g_atomic_int_dec_and_test(&op_data->ref_count)) - op_data_free(op_data); + if (g_atomic_int_dec_and_test (&op_data->ref_count)) + op_data_free (op_data); } /* Ensure capability info is set up for the VA filter we are interested in */ static gboolean -op_data_ensure_caps(GstVaapiFilterOpData *op_data, gpointer filter_caps, +op_data_ensure_caps (GstVaapiFilterOpData * op_data, gpointer filter_caps, guint num_filter_caps) { - guchar *filter_cap = filter_caps; - guint i, va_num_caps = num_filter_caps; + guchar *filter_cap = filter_caps; + guint i, va_num_caps = num_filter_caps; - // Find the VA filter cap matching the op info sub-type - if (op_data->va_subtype) { - for (i = 0; i < num_filter_caps; i++) { - /* XXX: sub-type shall always be the first field */ - if (op_data->va_subtype == *(guint *)filter_cap) { - va_num_caps= 1; - break; - } - filter_cap += op_data->va_cap_size; - } - if (i == num_filter_caps) - return FALSE; + // Find the VA filter cap matching the op info sub-type + if (op_data->va_subtype) { + for (i = 0; i < num_filter_caps; i++) { + /* XXX: sub-type shall always be the first field */ + if (op_data->va_subtype == *(guint *) filter_cap) { + va_num_caps = 1; + break; + } + filter_cap += op_data->va_cap_size; } + if (i == num_filter_caps) + return FALSE; + } - op_data->va_caps = g_memdup(filter_cap, - op_data->va_cap_size * va_num_caps); - if (!op_data->va_caps) - return FALSE; + op_data->va_caps = g_memdup (filter_cap, op_data->va_cap_size * va_num_caps); + if (!op_data->va_caps) + return FALSE; - op_data->va_num_caps = va_num_caps; - return TRUE; + op_data->va_num_caps = va_num_caps; + return TRUE; } /* Scale the filter value wrt. library spec and VA driver spec */ static gboolean -op_data_get_value_float(GstVaapiFilterOpData *op_data, - const VAProcFilterValueRange *range, gfloat value, gfloat *out_value_ptr) +op_data_get_value_float (GstVaapiFilterOpData * op_data, + const VAProcFilterValueRange * range, gfloat value, gfloat * out_value_ptr) { - GParamSpecFloat * const pspec = G_PARAM_SPEC_FLOAT(op_data->pspec); - gfloat out_value; + GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (op_data->pspec); + gfloat out_value; - g_return_val_if_fail(range != NULL, FALSE); - g_return_val_if_fail(out_value_ptr != NULL, FALSE); + g_return_val_if_fail (range != NULL, FALSE); + g_return_val_if_fail (out_value_ptr != NULL, FALSE); - if (value < pspec->minimum || value > pspec->maximum) - return FALSE; + if (value < pspec->minimum || value > pspec->maximum) + return FALSE; - // Scale wrt. the medium ("default") value - out_value = range->default_value; - if (value > pspec->default_value) - out_value += ((value - pspec->default_value) / - (pspec->maximum - pspec->default_value) * - (range->max_value - range->default_value)); - else if (value < pspec->default_value) - out_value -= ((pspec->default_value - value) / - (pspec->default_value - pspec->minimum) * - (range->default_value - range->min_value)); + // Scale wrt. the medium ("default") value + out_value = range->default_value; + if (value > pspec->default_value) + out_value += ((value - pspec->default_value) / + (pspec->maximum - pspec->default_value) * + (range->max_value - range->default_value)); + else if (value < pspec->default_value) + out_value -= ((pspec->default_value - value) / + (pspec->default_value - pspec->minimum) * + (range->default_value - range->min_value)); - *out_value_ptr = out_value; - return TRUE; + *out_value_ptr = out_value; + return TRUE; } /* Get default list of operations supported by the library */ static GPtrArray * -get_operations_default(void) +get_operations_default (void) { - GPtrArray *ops; - guint i; + GPtrArray *ops; + guint i; - ops = g_ptr_array_new_full(N_PROPERTIES, op_data_unref); - if (!ops) - return NULL; + ops = g_ptr_array_new_full (N_PROPERTIES, op_data_unref); + if (!ops) + return NULL; - ensure_properties(); + ensure_properties (); - for (i = 0; i < N_PROPERTIES; i++) { - GParamSpec * const pspec = g_properties[i]; - if (!pspec) - continue; + for (i = 0; i < N_PROPERTIES; i++) { + GParamSpec *const pspec = g_properties[i]; + if (!pspec) + continue; - GstVaapiFilterOpData * const op_data = op_data_new(i, pspec); - if (!op_data) - goto error; - g_ptr_array_add(ops, op_data); - } - return ops; + GstVaapiFilterOpData *const op_data = op_data_new (i, pspec); + if (!op_data) + goto error; + g_ptr_array_add (ops, op_data); + } + return ops; error: - g_ptr_array_unref(ops); - return NULL; + g_ptr_array_unref (ops); + return NULL; } /* Get the ordered list of operations, based on VA/VPP queries */ static GPtrArray * -get_operations_ordered(GstVaapiFilter *filter, GPtrArray *default_ops) +get_operations_ordered (GstVaapiFilter * filter, GPtrArray * default_ops) { - GPtrArray *ops; - VAProcFilterType *filters; - gpointer filter_caps = NULL; - guint i, j, num_filters, num_filter_caps = 0; + GPtrArray *ops; + VAProcFilterType *filters; + gpointer filter_caps = NULL; + guint i, j, num_filters, num_filter_caps = 0; - ops = g_ptr_array_new_full(default_ops->len, op_data_unref); - if (!ops) - return NULL; + ops = g_ptr_array_new_full (default_ops->len, op_data_unref); + if (!ops) + return NULL; - filters = vpp_get_filters(filter, &num_filters); - if (!filters) + filters = vpp_get_filters (filter, &num_filters); + if (!filters) + goto error; + + // Append virtual ops first, i.e. those without an associated VA filter + for (i = 0; i < default_ops->len; i++) { + GstVaapiFilterOpData *const op_data = g_ptr_array_index (default_ops, i); + if (op_data->va_type == VAProcFilterNone) + g_ptr_array_add (ops, op_data_ref (op_data)); + } + + // Append ops, while preserving the VA filters ordering + for (i = 0; i < num_filters; i++) { + const VAProcFilterType va_type = filters[i]; + if (va_type == VAProcFilterNone) + continue; + + for (j = 0; j < default_ops->len; j++) { + GstVaapiFilterOpData *const op_data = g_ptr_array_index (default_ops, j); + if (op_data->va_type != va_type) + continue; + + if (!filter_caps) { + filter_caps = vpp_get_filter_caps (filter, va_type, + op_data->va_cap_size, &num_filter_caps); + if (!filter_caps) + goto error; + } + if (!op_data_ensure_caps (op_data, filter_caps, num_filter_caps)) goto error; - - // Append virtual ops first, i.e. those without an associated VA filter - for (i = 0; i < default_ops->len; i++) { - GstVaapiFilterOpData * const op_data = - g_ptr_array_index(default_ops, i); - if (op_data->va_type == VAProcFilterNone) - g_ptr_array_add(ops, op_data_ref(op_data)); + g_ptr_array_add (ops, op_data_ref (op_data)); } + free (filter_caps); + filter_caps = NULL; + } - // Append ops, while preserving the VA filters ordering - for (i = 0; i < num_filters; i++) { - const VAProcFilterType va_type = filters[i]; - if (va_type == VAProcFilterNone) - continue; + if (filter->operations) + g_ptr_array_unref (filter->operations); + filter->operations = g_ptr_array_ref (ops); - for (j = 0; j < default_ops->len; j++) { - GstVaapiFilterOpData * const op_data = - g_ptr_array_index(default_ops, j); - if (op_data->va_type != va_type) - continue; - - if (!filter_caps) { - filter_caps = vpp_get_filter_caps(filter, va_type, - op_data->va_cap_size, &num_filter_caps); - if (!filter_caps) - goto error; - } - if (!op_data_ensure_caps(op_data, filter_caps, num_filter_caps)) - goto error; - g_ptr_array_add(ops, op_data_ref(op_data)); - } - free(filter_caps); - filter_caps = NULL; - } - - if (filter->operations) - g_ptr_array_unref(filter->operations); - filter->operations = g_ptr_array_ref(ops); - - g_free(filters); - g_ptr_array_unref(default_ops); - return ops; + g_free (filters); + g_ptr_array_unref (default_ops); + return ops; error: - g_free(filter_caps); - g_free(filters); - g_ptr_array_unref(ops); - g_ptr_array_unref(default_ops); - return NULL; + g_free (filter_caps); + g_free (filters); + g_ptr_array_unref (ops); + g_ptr_array_unref (default_ops); + return NULL; } #endif /* Determine the set of supported VPP operations by the specific filter, or known to this library if filter is NULL */ static GPtrArray * -get_operations(GstVaapiFilter *filter) +get_operations (GstVaapiFilter * filter) { #if USE_VA_VPP - GPtrArray *ops; + GPtrArray *ops; - if (filter && filter->operations) - return g_ptr_array_ref(filter->operations); + if (filter && filter->operations) + return g_ptr_array_ref (filter->operations); - ops = get_operations_default(); - if (!ops) - return NULL; - return filter ? get_operations_ordered(filter, ops) : ops; -#endif + ops = get_operations_default (); + if (!ops) return NULL; + return filter ? get_operations_ordered (filter, ops) : ops; +#endif + return NULL; } /* Ensure the set of supported VPP operations is cached into the GstVaapiFilter::operations member */ static inline gboolean -ensure_operations(GstVaapiFilter *filter) +ensure_operations (GstVaapiFilter * filter) { - GPtrArray *ops; + GPtrArray *ops; - if (!filter) - return FALSE; + if (!filter) + return FALSE; - if (filter->operations) - return TRUE; - - ops = get_operations(filter); - if (!ops) - return FALSE; - - g_ptr_array_unref(ops); + if (filter->operations) return TRUE; + + ops = get_operations (filter); + if (!ops) + return FALSE; + + g_ptr_array_unref (ops); + return TRUE; } /* Find whether the VPP operation is supported or not */ GstVaapiFilterOpData * -find_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) +find_operation (GstVaapiFilter * filter, GstVaapiFilterOp op) { - guint i; + guint i; - if (!ensure_operations(filter)) - return NULL; - - for (i = 0; i < filter->operations->len; i++) { - GstVaapiFilterOpData * const op_data = - g_ptr_array_index(filter->operations, i); - if (op_data->op == op) - return op_data; - } + if (!ensure_operations (filter)) return NULL; + + for (i = 0; i < filter->operations->len; i++) { + GstVaapiFilterOpData *const op_data = + g_ptr_array_index (filter->operations, i); + if (op_data->op == op) + return op_data; + } + return NULL; } /* Ensure the operation's VA buffer is allocated */ #if USE_VA_VPP static inline gboolean -op_ensure_buffer(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data) +op_ensure_buffer (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data) { - if (G_LIKELY(op_data->va_buffer != VA_INVALID_ID)) - return TRUE; - return vaapi_create_buffer(filter->va_display, filter->va_context, - VAProcFilterParameterBufferType, op_data->va_buffer_size, NULL, - &op_data->va_buffer, NULL); + if (G_LIKELY (op_data->va_buffer != VA_INVALID_ID)) + return TRUE; + return vaapi_create_buffer (filter->va_display, filter->va_context, + VAProcFilterParameterBufferType, op_data->va_buffer_size, NULL, + &op_data->va_buffer, NULL); } #endif /* Update a generic filter (float value) */ #if USE_VA_VPP static gboolean -op_set_generic_unlocked(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, - gfloat value) +op_set_generic_unlocked (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data, gfloat value) { - VAProcFilterParameterBuffer *buf; - VAProcFilterCap *filter_cap; - gfloat va_value; + VAProcFilterParameterBuffer *buf; + VAProcFilterCap *filter_cap; + gfloat va_value; - if (!op_data || !op_ensure_buffer(filter, op_data)) - return FALSE; + if (!op_data || !op_ensure_buffer (filter, op_data)) + return FALSE; - op_data->is_enabled = - (value != G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value); - if (!op_data->is_enabled) - return TRUE; - - filter_cap = op_data->va_caps; - if (!op_data_get_value_float(op_data, &filter_cap->range, value, &va_value)) - return FALSE; - - buf = vaapi_map_buffer(filter->va_display, op_data->va_buffer); - if (!buf) - return FALSE; - - buf->type = op_data->va_type; - buf->value = va_value; - vaapi_unmap_buffer(filter->va_display, op_data->va_buffer, NULL); + op_data->is_enabled = + (value != G_PARAM_SPEC_FLOAT (op_data->pspec)->default_value); + if (!op_data->is_enabled) return TRUE; + + filter_cap = op_data->va_caps; + if (!op_data_get_value_float (op_data, &filter_cap->range, value, &va_value)) + return FALSE; + + buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer); + if (!buf) + return FALSE; + + buf->type = op_data->va_type; + buf->value = va_value; + vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL); + return TRUE; } #endif static inline gboolean -op_set_generic(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, +op_set_generic (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, gfloat value) { - gboolean success = FALSE; + gboolean success = FALSE; #if USE_VA_VPP - GST_VAAPI_DISPLAY_LOCK(filter->display); - success = op_set_generic_unlocked(filter, op_data, value); - GST_VAAPI_DISPLAY_UNLOCK(filter->display); + GST_VAAPI_DISPLAY_LOCK (filter->display); + success = op_set_generic_unlocked (filter, op_data, value); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); #endif - return success; + return success; } /* Update the color balance filter */ #if USE_VA_VPP static gboolean -op_set_color_balance_unlocked(GstVaapiFilter *filter, - GstVaapiFilterOpData *op_data, gfloat value) +op_set_color_balance_unlocked (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data, gfloat value) { - VAProcFilterParameterBufferColorBalance *buf; - VAProcFilterCapColorBalance *filter_cap; - gfloat va_value; + VAProcFilterParameterBufferColorBalance *buf; + VAProcFilterCapColorBalance *filter_cap; + gfloat va_value; - if (!op_data || !op_ensure_buffer(filter, op_data)) - return FALSE; + if (!op_data || !op_ensure_buffer (filter, op_data)) + return FALSE; - op_data->is_enabled = - (value != G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value); - if (!op_data->is_enabled) - return TRUE; - - filter_cap = op_data->va_caps; - if (!op_data_get_value_float(op_data, &filter_cap->range, value, &va_value)) - return FALSE; - - buf = vaapi_map_buffer(filter->va_display, op_data->va_buffer); - if (!buf) - return FALSE; - - buf->type = op_data->va_type; - buf->attrib = op_data->va_subtype; - buf->value = va_value; - vaapi_unmap_buffer(filter->va_display, op_data->va_buffer, NULL); + op_data->is_enabled = + (value != G_PARAM_SPEC_FLOAT (op_data->pspec)->default_value); + if (!op_data->is_enabled) return TRUE; + + filter_cap = op_data->va_caps; + if (!op_data_get_value_float (op_data, &filter_cap->range, value, &va_value)) + return FALSE; + + buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer); + if (!buf) + return FALSE; + + buf->type = op_data->va_type; + buf->attrib = op_data->va_subtype; + buf->value = va_value; + vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL); + return TRUE; } #endif static inline gboolean -op_set_color_balance(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, +op_set_color_balance (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, gfloat value) { - gboolean success = FALSE; + gboolean success = FALSE; #if USE_VA_VPP - GST_VAAPI_DISPLAY_LOCK(filter->display); - success = op_set_color_balance_unlocked(filter, op_data, value); - GST_VAAPI_DISPLAY_UNLOCK(filter->display); + GST_VAAPI_DISPLAY_LOCK (filter->display); + success = op_set_color_balance_unlocked (filter, op_data, value); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); #endif - return success; + return success; } /* Update deinterlace filter */ #if USE_VA_VPP static gboolean -op_set_deinterlace_unlocked(GstVaapiFilter *filter, - GstVaapiFilterOpData *op_data, GstVaapiDeinterlaceMethod method, +op_set_deinterlace_unlocked (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data, GstVaapiDeinterlaceMethod method, guint flags) { - VAProcFilterParameterBufferDeinterlacing *buf; - const VAProcFilterCapDeinterlacing *filter_caps; - VAProcDeinterlacingType algorithm; - guint i; + VAProcFilterParameterBufferDeinterlacing *buf; + const VAProcFilterCapDeinterlacing *filter_caps; + VAProcDeinterlacingType algorithm; + guint i; - if (!op_data || !op_ensure_buffer(filter, op_data)) - return FALSE; + if (!op_data || !op_ensure_buffer (filter, op_data)) + return FALSE; - op_data->is_enabled = (method != GST_VAAPI_DEINTERLACE_METHOD_NONE); - if (!op_data->is_enabled) - return TRUE; - - algorithm = from_GstVaapiDeinterlaceMethod(method); - for (i = 0, filter_caps = op_data->va_caps; i < op_data->va_num_caps; i++) { - if (filter_caps[i].type == algorithm) - break; - } - if (i == op_data->va_num_caps) - return FALSE; - - buf = vaapi_map_buffer(filter->va_display, op_data->va_buffer); - if (!buf) - return FALSE; - - buf->type = op_data->va_type; - buf->algorithm = algorithm; - buf->flags = from_GstVaapiDeinterlaceFlags(flags); - vaapi_unmap_buffer(filter->va_display, op_data->va_buffer, NULL); + op_data->is_enabled = (method != GST_VAAPI_DEINTERLACE_METHOD_NONE); + if (!op_data->is_enabled) return TRUE; + + algorithm = from_GstVaapiDeinterlaceMethod (method); + for (i = 0, filter_caps = op_data->va_caps; i < op_data->va_num_caps; i++) { + if (filter_caps[i].type == algorithm) + break; + } + if (i == op_data->va_num_caps) + return FALSE; + + buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer); + if (!buf) + return FALSE; + + buf->type = op_data->va_type; + buf->algorithm = algorithm; + buf->flags = from_GstVaapiDeinterlaceFlags (flags); + vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL); + return TRUE; } #endif static inline gboolean -op_set_deinterlace(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data, +op_set_deinterlace (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, GstVaapiDeinterlaceMethod method, guint flags) { - gboolean success = FALSE; + gboolean success = FALSE; #if USE_VA_VPP - GST_VAAPI_DISPLAY_LOCK(filter->display); - success = op_set_deinterlace_unlocked(filter, op_data, method, flags); - GST_VAAPI_DISPLAY_UNLOCK(filter->display); + GST_VAAPI_DISPLAY_LOCK (filter->display); + success = op_set_deinterlace_unlocked (filter, op_data, method, flags); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); #endif - return success; + return success; } static gboolean -deint_refs_set(GArray *refs, GstVaapiSurface **surfaces, guint num_surfaces) +deint_refs_set (GArray * refs, GstVaapiSurface ** surfaces, guint num_surfaces) { - guint i; + guint i; - if (num_surfaces > 0 && !surfaces) - return FALSE; + if (num_surfaces > 0 && !surfaces) + return FALSE; - for (i = 0; i < num_surfaces; i++) - g_array_append_val(refs, GST_VAAPI_OBJECT_ID(surfaces[i])); - return TRUE; + for (i = 0; i < num_surfaces; i++) + g_array_append_val (refs, GST_VAAPI_OBJECT_ID (surfaces[i])); + return TRUE; } static void -deint_refs_clear(GArray *refs) +deint_refs_clear (GArray * refs) { - if (refs->len > 0) - g_array_remove_range(refs, 0, refs->len); + if (refs->len > 0) + g_array_remove_range (refs, 0, refs->len); } static inline void -deint_refs_clear_all(GstVaapiFilter *filter) +deint_refs_clear_all (GstVaapiFilter * filter) { - deint_refs_clear(filter->forward_references); - deint_refs_clear(filter->backward_references); + deint_refs_clear (filter->forward_references); + deint_refs_clear (filter->backward_references); } /* ------------------------------------------------------------------------- */ @@ -886,84 +871,84 @@ deint_refs_clear_all(GstVaapiFilter *filter) /* ------------------------------------------------------------------------- */ static gboolean -ensure_formats(GstVaapiFilter *filter) +ensure_formats (GstVaapiFilter * filter) { #if VA_CHECK_VERSION(0,34,0) - VASurfaceAttrib *surface_attribs = NULL; - guint i, num_surface_attribs = 0; - VAStatus va_status; + VASurfaceAttrib *surface_attribs = NULL; + guint i, num_surface_attribs = 0; + VAStatus va_status; - if (G_LIKELY(filter->formats)) - return TRUE; - - GST_VAAPI_DISPLAY_LOCK(filter->display); - va_status = vaQuerySurfaceAttributes(filter->va_display, filter->va_config, - NULL, &num_surface_attribs); - GST_VAAPI_DISPLAY_UNLOCK(filter->display); - if (!vaapi_check_status(va_status, "vaQuerySurfaceAttributes()")) - return FALSE; - - surface_attribs = g_malloc(num_surface_attribs * sizeof(*surface_attribs)); - if (!surface_attribs) - return FALSE; - - GST_VAAPI_DISPLAY_LOCK(filter->display); - va_status = vaQuerySurfaceAttributes(filter->va_display, filter->va_config, - surface_attribs, &num_surface_attribs); - GST_VAAPI_DISPLAY_UNLOCK(filter->display); - if (!vaapi_check_status(va_status, "vaQuerySurfaceAttributes()")) - return FALSE; - - filter->formats = g_array_sized_new(FALSE, FALSE, sizeof(GstVideoFormat), - num_surface_attribs); - if (!filter->formats) - goto error; - - for (i = 0; i < num_surface_attribs; i++) { - const VASurfaceAttrib * const surface_attrib = &surface_attribs[i]; - GstVideoFormat format; - - if (surface_attrib->type != VASurfaceAttribPixelFormat) - continue; - if (!(surface_attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) - continue; - - format = gst_vaapi_video_format_from_va_fourcc( - surface_attrib->value.value.i); - if (format == GST_VIDEO_FORMAT_UNKNOWN) - continue; - g_array_append_val(filter->formats, format); - } - - g_free(surface_attribs); + if (G_LIKELY (filter->formats)) return TRUE; -error: - g_free(surface_attribs); -#endif + GST_VAAPI_DISPLAY_LOCK (filter->display); + va_status = vaQuerySurfaceAttributes (filter->va_display, filter->va_config, + NULL, &num_surface_attribs); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); + if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()")) return FALSE; + + surface_attribs = g_malloc (num_surface_attribs * sizeof (*surface_attribs)); + if (!surface_attribs) + return FALSE; + + GST_VAAPI_DISPLAY_LOCK (filter->display); + va_status = vaQuerySurfaceAttributes (filter->va_display, filter->va_config, + surface_attribs, &num_surface_attribs); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); + if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()")) + return FALSE; + + filter->formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), + num_surface_attribs); + if (!filter->formats) + goto error; + + for (i = 0; i < num_surface_attribs; i++) { + const VASurfaceAttrib *const surface_attrib = &surface_attribs[i]; + GstVideoFormat format; + + if (surface_attrib->type != VASurfaceAttribPixelFormat) + continue; + if (!(surface_attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) + continue; + + format = + gst_vaapi_video_format_from_va_fourcc (surface_attrib->value.value.i); + if (format == GST_VIDEO_FORMAT_UNKNOWN) + continue; + g_array_append_val (filter->formats, format); + } + + g_free (surface_attribs); + return TRUE; + +error: + g_free (surface_attribs); +#endif + return FALSE; } static inline gboolean -is_special_format(GstVideoFormat format) +is_special_format (GstVideoFormat format) { - return format == GST_VIDEO_FORMAT_UNKNOWN || - format == GST_VIDEO_FORMAT_ENCODED; + return format == GST_VIDEO_FORMAT_UNKNOWN || + format == GST_VIDEO_FORMAT_ENCODED; } static gboolean -find_format(GstVaapiFilter *filter, GstVideoFormat format) +find_format (GstVaapiFilter * filter, GstVideoFormat format) { - guint i; + guint i; - if (is_special_format(format) || !filter->formats) - return FALSE; - - for (i = 0; i < filter->formats->len; i++) { - if (g_array_index(filter->formats, GstVideoFormat, i) == format) - return TRUE; - } + if (is_special_format (format) || !filter->formats) return FALSE; + + for (i = 0; i < filter->formats->len; i++) { + if (g_array_index (filter->formats, GstVideoFormat, i) == format) + return TRUE; + } + return FALSE; } /* ------------------------------------------------------------------------- */ @@ -972,93 +957,93 @@ find_format(GstVaapiFilter *filter, GstVideoFormat format) #if USE_VA_VPP static gboolean -gst_vaapi_filter_init(GstVaapiFilter *filter, GstVaapiDisplay *display) +gst_vaapi_filter_init (GstVaapiFilter * filter, GstVaapiDisplay * display) { - VAStatus va_status; + VAStatus va_status; - filter->display = gst_vaapi_display_ref(display); - filter->va_display = GST_VAAPI_DISPLAY_VADISPLAY(display); - filter->va_config = VA_INVALID_ID; - filter->va_context = VA_INVALID_ID; - filter->format = DEFAULT_FORMAT; + filter->display = gst_vaapi_display_ref (display); + filter->va_display = GST_VAAPI_DISPLAY_VADISPLAY (display); + filter->va_config = VA_INVALID_ID; + filter->va_context = VA_INVALID_ID; + filter->format = DEFAULT_FORMAT; - filter->forward_references = - g_array_sized_new(FALSE, FALSE, sizeof(VASurfaceID), 4); - if (!filter->forward_references) - return FALSE; + filter->forward_references = + g_array_sized_new (FALSE, FALSE, sizeof (VASurfaceID), 4); + if (!filter->forward_references) + return FALSE; - filter->backward_references = - g_array_sized_new(FALSE, FALSE, sizeof(VASurfaceID), 4); - if (!filter->backward_references) - return FALSE; + filter->backward_references = + g_array_sized_new (FALSE, FALSE, sizeof (VASurfaceID), 4); + if (!filter->backward_references) + return FALSE; - if (!GST_VAAPI_DISPLAY_HAS_VPP(display)) - return FALSE; + if (!GST_VAAPI_DISPLAY_HAS_VPP (display)) + return FALSE; - va_status = vaCreateConfig(filter->va_display, VAProfileNone, - VAEntrypointVideoProc, NULL, 0, &filter->va_config); - if (!vaapi_check_status(va_status, "vaCreateConfig() [VPP]")) - return FALSE; + va_status = vaCreateConfig (filter->va_display, VAProfileNone, + VAEntrypointVideoProc, NULL, 0, &filter->va_config); + if (!vaapi_check_status (va_status, "vaCreateConfig() [VPP]")) + return FALSE; - va_status = vaCreateContext(filter->va_display, filter->va_config, 0, 0, 0, - NULL, 0, &filter->va_context); - if (!vaapi_check_status(va_status, "vaCreateContext() [VPP]")) - return FALSE; - return TRUE; + va_status = vaCreateContext (filter->va_display, filter->va_config, 0, 0, 0, + NULL, 0, &filter->va_context); + if (!vaapi_check_status (va_status, "vaCreateContext() [VPP]")) + return FALSE; + return TRUE; } static void -gst_vaapi_filter_finalize(GstVaapiFilter *filter) +gst_vaapi_filter_finalize (GstVaapiFilter * filter) { - guint i; + guint i; - GST_VAAPI_DISPLAY_LOCK(filter->display); - if (filter->operations) { - for (i = 0; i < filter->operations->len; i++) { - GstVaapiFilterOpData * const op_data = - g_ptr_array_index(filter->operations, i); - vaapi_destroy_buffer(filter->va_display, &op_data->va_buffer); - } - g_ptr_array_unref(filter->operations); - filter->operations = NULL; + GST_VAAPI_DISPLAY_LOCK (filter->display); + if (filter->operations) { + for (i = 0; i < filter->operations->len; i++) { + GstVaapiFilterOpData *const op_data = + g_ptr_array_index (filter->operations, i); + vaapi_destroy_buffer (filter->va_display, &op_data->va_buffer); } + g_ptr_array_unref (filter->operations); + filter->operations = NULL; + } - if (filter->va_context != VA_INVALID_ID) { - vaDestroyContext(filter->va_display, filter->va_context); - filter->va_context = VA_INVALID_ID; - } + if (filter->va_context != VA_INVALID_ID) { + vaDestroyContext (filter->va_display, filter->va_context); + filter->va_context = VA_INVALID_ID; + } - if (filter->va_config != VA_INVALID_ID) { - vaDestroyConfig(filter->va_display, filter->va_config); - filter->va_config = VA_INVALID_ID; - } - GST_VAAPI_DISPLAY_UNLOCK(filter->display); - gst_vaapi_display_replace(&filter->display, NULL); + if (filter->va_config != VA_INVALID_ID) { + vaDestroyConfig (filter->va_display, filter->va_config); + filter->va_config = VA_INVALID_ID; + } + GST_VAAPI_DISPLAY_UNLOCK (filter->display); + gst_vaapi_display_replace (&filter->display, NULL); - if (filter->forward_references) { - g_array_unref(filter->forward_references); - filter->forward_references = NULL; - } + if (filter->forward_references) { + g_array_unref (filter->forward_references); + filter->forward_references = NULL; + } - if (filter->backward_references) { - g_array_unref(filter->backward_references); - filter->backward_references = NULL; - } + if (filter->backward_references) { + g_array_unref (filter->backward_references); + filter->backward_references = NULL; + } - if (filter->formats) { - g_array_unref(filter->formats); - filter->formats = NULL; - } + if (filter->formats) { + g_array_unref (filter->formats); + filter->formats = NULL; + } } static inline const GstVaapiMiniObjectClass * -gst_vaapi_filter_class(void) +gst_vaapi_filter_class (void) { - static const GstVaapiMiniObjectClass GstVaapiFilterClass = { - sizeof(GstVaapiFilter), - (GDestroyNotify)gst_vaapi_filter_finalize - }; - return &GstVaapiFilterClass; + static const GstVaapiMiniObjectClass GstVaapiFilterClass = { + sizeof (GstVaapiFilter), + (GDestroyNotify) gst_vaapi_filter_finalize + }; + return &GstVaapiFilterClass; } #endif @@ -1072,27 +1057,27 @@ gst_vaapi_filter_class(void) * Return value: the newly created #GstVaapiFilter object */ GstVaapiFilter * -gst_vaapi_filter_new(GstVaapiDisplay *display) +gst_vaapi_filter_new (GstVaapiDisplay * display) { #if USE_VA_VPP - GstVaapiFilter *filter; + GstVaapiFilter *filter; - filter = (GstVaapiFilter *) - gst_vaapi_mini_object_new0(gst_vaapi_filter_class()); - if (!filter) - return NULL; + filter = (GstVaapiFilter *) + gst_vaapi_mini_object_new0 (gst_vaapi_filter_class ()); + if (!filter) + return NULL; - if (!gst_vaapi_filter_init(filter, display)) - goto error; - return filter; + if (!gst_vaapi_filter_init (filter, display)) + goto error; + return filter; error: - gst_vaapi_filter_unref(filter); - return NULL; + gst_vaapi_filter_unref (filter); + return NULL; #else - GST_WARNING("video processing is not supported, " - "please consider an upgrade to VA-API >= 0.34"); - return NULL; + GST_WARNING ("video processing is not supported, " + "please consider an upgrade to VA-API >= 0.34"); + return NULL; #endif } @@ -1105,12 +1090,13 @@ error: * Returns: The same @filter argument */ GstVaapiFilter * -gst_vaapi_filter_ref(GstVaapiFilter *filter) +gst_vaapi_filter_ref (GstVaapiFilter * filter) { - g_return_val_if_fail(filter != NULL, NULL); + g_return_val_if_fail (filter != NULL, NULL); - return GST_VAAPI_FILTER(gst_vaapi_mini_object_ref( - GST_VAAPI_MINI_OBJECT(filter))); + return + GST_VAAPI_FILTER (gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT + (filter))); } /** @@ -1121,11 +1107,11 @@ gst_vaapi_filter_ref(GstVaapiFilter *filter) * the reference count reaches zero, the filter will be free'd. */ void -gst_vaapi_filter_unref(GstVaapiFilter *filter) +gst_vaapi_filter_unref (GstVaapiFilter * filter) { - g_return_if_fail(filter != NULL); + g_return_if_fail (filter != NULL); - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(filter)); + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (filter)); } /** @@ -1138,13 +1124,13 @@ gst_vaapi_filter_unref(GstVaapiFilter *filter) * valid filter. However, @new_filter can be NULL. */ void -gst_vaapi_filter_replace(GstVaapiFilter **old_filter_ptr, - GstVaapiFilter *new_filter) +gst_vaapi_filter_replace (GstVaapiFilter ** old_filter_ptr, + GstVaapiFilter * new_filter) { - g_return_if_fail(old_filter_ptr != NULL); + g_return_if_fail (old_filter_ptr != NULL); - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)old_filter_ptr, - GST_VAAPI_MINI_OBJECT(new_filter)); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_filter_ptr, + GST_VAAPI_MINI_OBJECT (new_filter)); } /** @@ -1163,9 +1149,9 @@ gst_vaapi_filter_replace(GstVaapiFilter **old_filter_ptr, * occurred. */ GPtrArray * -gst_vaapi_filter_get_operations(GstVaapiFilter *filter) +gst_vaapi_filter_get_operations (GstVaapiFilter * filter) { - return get_operations(filter); + return get_operations (filter); } /** @@ -1180,11 +1166,11 @@ gst_vaapi_filter_get_operations(GstVaapiFilter *filter) * the underlying hardware, %FALSE otherwise */ gboolean -gst_vaapi_filter_has_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) +gst_vaapi_filter_has_operation (GstVaapiFilter * filter, GstVaapiFilterOp op) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - return find_operation(filter, op) != NULL; + return find_operation (filter, op) != NULL; } /** @@ -1203,16 +1189,16 @@ gst_vaapi_filter_has_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) * %FALSE otherwise */ gboolean -gst_vaapi_filter_use_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) +gst_vaapi_filter_use_operation (GstVaapiFilter * filter, GstVaapiFilterOp op) { - GstVaapiFilterOpData *op_data; + GstVaapiFilterOpData *op_data; - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - op_data = find_operation(filter, op); - if (!op_data) - return FALSE; - return op_data->is_enabled; + op_data = find_operation (filter, op); + if (!op_data) + return FALSE; + return op_data->is_enabled; } /** @@ -1233,50 +1219,50 @@ gst_vaapi_filter_use_operation(GstVaapiFilter *filter, GstVaapiFilterOp op) * %FALSE otherwise */ gboolean -gst_vaapi_filter_set_operation(GstVaapiFilter *filter, GstVaapiFilterOp op, - const GValue *value) +gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, + const GValue * value) { #if USE_VA_VPP - GstVaapiFilterOpData *op_data; + GstVaapiFilterOpData *op_data; - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - op_data = find_operation(filter, op); - if (!op_data) - return FALSE; + op_data = find_operation (filter, op); + if (!op_data) + return FALSE; - if (value && !G_VALUE_HOLDS(value, G_PARAM_SPEC_VALUE_TYPE(op_data->pspec))) - return FALSE; + if (value && !G_VALUE_HOLDS (value, G_PARAM_SPEC_VALUE_TYPE (op_data->pspec))) + return FALSE; - switch (op) { + switch (op) { case GST_VAAPI_FILTER_OP_FORMAT: - return gst_vaapi_filter_set_format(filter, value ? - g_value_get_enum(value) : DEFAULT_FORMAT); + return gst_vaapi_filter_set_format (filter, value ? + g_value_get_enum (value) : DEFAULT_FORMAT); case GST_VAAPI_FILTER_OP_CROP: - return gst_vaapi_filter_set_cropping_rectangle(filter, value ? - g_value_get_boxed(value) : NULL); + return gst_vaapi_filter_set_cropping_rectangle (filter, value ? + g_value_get_boxed (value) : NULL); case GST_VAAPI_FILTER_OP_DENOISE: case GST_VAAPI_FILTER_OP_SHARPEN: - return op_set_generic(filter, op_data, - (value ? g_value_get_float(value) : - G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value)); + return op_set_generic (filter, op_data, + (value ? g_value_get_float (value) : + G_PARAM_SPEC_FLOAT (op_data->pspec)->default_value)); case GST_VAAPI_FILTER_OP_HUE: case GST_VAAPI_FILTER_OP_SATURATION: case GST_VAAPI_FILTER_OP_BRIGHTNESS: case GST_VAAPI_FILTER_OP_CONTRAST: - return op_set_color_balance(filter, op_data, - (value ? g_value_get_float(value) : - G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value)); + return op_set_color_balance (filter, op_data, + (value ? g_value_get_float (value) : + G_PARAM_SPEC_FLOAT (op_data->pspec)->default_value)); case GST_VAAPI_FILTER_OP_DEINTERLACING: - return op_set_deinterlace(filter, op_data, - (value ? g_value_get_enum(value) : - G_PARAM_SPEC_ENUM(op_data->pspec)->default_value), 0); - break; + return op_set_deinterlace (filter, op_data, + (value ? g_value_get_enum (value) : + G_PARAM_SPEC_ENUM (op_data->pspec)->default_value), 0); + break; default: - break; - } + break; + } #endif - return FALSE; + return FALSE; } /** @@ -1295,171 +1281,167 @@ gst_vaapi_filter_set_operation(GstVaapiFilter *filter, GstVaapiFilterOp op, * Return value: a #GstVaapiFilterStatus */ static GstVaapiFilterStatus -gst_vaapi_filter_process_unlocked(GstVaapiFilter *filter, - GstVaapiSurface *src_surface, GstVaapiSurface *dst_surface, guint flags) +gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, + GstVaapiSurface * src_surface, GstVaapiSurface * dst_surface, guint flags) { #if USE_VA_VPP - VAProcPipelineParameterBuffer *pipeline_param = NULL; - VABufferID pipeline_param_buf_id = VA_INVALID_ID; - VABufferID filters[N_PROPERTIES]; - VAProcPipelineCaps pipeline_caps; - guint i, num_filters = 0; - VAStatus va_status; - VARectangle src_rect, dst_rect; + VAProcPipelineParameterBuffer *pipeline_param = NULL; + VABufferID pipeline_param_buf_id = VA_INVALID_ID; + VABufferID filters[N_PROPERTIES]; + VAProcPipelineCaps pipeline_caps; + guint i, num_filters = 0; + VAStatus va_status; + VARectangle src_rect, dst_rect; - if (!ensure_operations(filter)) - return GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED; + if (!ensure_operations (filter)) + return GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED; - /* Build surface region (source) */ - if (filter->use_crop_rect) { - const GstVaapiRectangle * const crop_rect = &filter->crop_rect; + /* Build surface region (source) */ + if (filter->use_crop_rect) { + const GstVaapiRectangle *const crop_rect = &filter->crop_rect; - if ((crop_rect->x + crop_rect->width > - GST_VAAPI_SURFACE_WIDTH(src_surface)) || - (crop_rect->y + crop_rect->height > - GST_VAAPI_SURFACE_HEIGHT(src_surface))) - goto error; + if ((crop_rect->x + crop_rect->width > + GST_VAAPI_SURFACE_WIDTH (src_surface)) || + (crop_rect->y + crop_rect->height > + GST_VAAPI_SURFACE_HEIGHT (src_surface))) + goto error; - src_rect.x = crop_rect->x; - src_rect.y = crop_rect->y; - src_rect.width = crop_rect->width; - src_rect.height = crop_rect->height; - } - else { - src_rect.x = 0; - src_rect.y = 0; - src_rect.width = GST_VAAPI_SURFACE_WIDTH(src_surface); - src_rect.height = GST_VAAPI_SURFACE_HEIGHT(src_surface); + src_rect.x = crop_rect->x; + src_rect.y = crop_rect->y; + src_rect.width = crop_rect->width; + src_rect.height = crop_rect->height; + } else { + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = GST_VAAPI_SURFACE_WIDTH (src_surface); + src_rect.height = GST_VAAPI_SURFACE_HEIGHT (src_surface); + } + + /* Build output region (target) */ + if (filter->use_target_rect) { + const GstVaapiRectangle *const target_rect = &filter->target_rect; + + if ((target_rect->x + target_rect->width > + GST_VAAPI_SURFACE_WIDTH (dst_surface)) || + (target_rect->y + target_rect->height > + GST_VAAPI_SURFACE_HEIGHT (dst_surface))) + goto error; + + dst_rect.x = target_rect->x; + dst_rect.y = target_rect->y; + dst_rect.width = target_rect->width; + dst_rect.height = target_rect->height; + } else { + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = GST_VAAPI_SURFACE_WIDTH (dst_surface); + dst_rect.height = GST_VAAPI_SURFACE_HEIGHT (dst_surface); + } + + for (i = 0, num_filters = 0; i < filter->operations->len; i++) { + GstVaapiFilterOpData *const op_data = + g_ptr_array_index (filter->operations, i); + if (!op_data->is_enabled) + continue; + if (op_data->va_buffer == VA_INVALID_ID) { + GST_ERROR ("invalid VA buffer for operation %s", + g_param_spec_get_name (op_data->pspec)); + goto error; } + filters[num_filters++] = op_data->va_buffer; + } - /* Build output region (target) */ - if (filter->use_target_rect) { - const GstVaapiRectangle * const target_rect = &filter->target_rect; + /* Validate pipeline caps */ + va_status = vaQueryVideoProcPipelineCaps (filter->va_display, + filter->va_context, filters, num_filters, &pipeline_caps); + if (!vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()")) + goto error; - if ((target_rect->x + target_rect->width > - GST_VAAPI_SURFACE_WIDTH(dst_surface)) || - (target_rect->y + target_rect->height > - GST_VAAPI_SURFACE_HEIGHT(dst_surface))) - goto error; + if (!vaapi_create_buffer (filter->va_display, filter->va_context, + VAProcPipelineParameterBufferType, sizeof (*pipeline_param), + NULL, &pipeline_param_buf_id, (gpointer *) & pipeline_param)) + goto error; - dst_rect.x = target_rect->x; - dst_rect.y = target_rect->y; - dst_rect.width = target_rect->width; - dst_rect.height = target_rect->height; - } - else { - dst_rect.x = 0; - dst_rect.y = 0; - dst_rect.width = GST_VAAPI_SURFACE_WIDTH(dst_surface); - dst_rect.height = GST_VAAPI_SURFACE_HEIGHT(dst_surface); - } + memset (pipeline_param, 0, sizeof (*pipeline_param)); + pipeline_param->surface = GST_VAAPI_OBJECT_ID (src_surface); + pipeline_param->surface_region = &src_rect; + pipeline_param->surface_color_standard = VAProcColorStandardNone; + pipeline_param->output_region = &dst_rect; + pipeline_param->output_color_standard = VAProcColorStandardNone; + pipeline_param->output_background_color = 0xff000000; + pipeline_param->filter_flags = from_GstVaapiSurfaceRenderFlags (flags); + pipeline_param->filters = filters; + pipeline_param->num_filters = num_filters; - for (i = 0, num_filters = 0; i < filter->operations->len; i++) { - GstVaapiFilterOpData * const op_data = - g_ptr_array_index(filter->operations, i); - if (!op_data->is_enabled) - continue; - if (op_data->va_buffer == VA_INVALID_ID) { - GST_ERROR("invalid VA buffer for operation %s", - g_param_spec_get_name(op_data->pspec)); - goto error; - } - filters[num_filters++] = op_data->va_buffer; - } + // Reference frames for advanced deinterlacing + if (filter->forward_references->len > 0) { + pipeline_param->forward_references = (VASurfaceID *) + filter->forward_references->data; + pipeline_param->num_forward_references = + MIN (filter->forward_references->len, + pipeline_caps.num_forward_references); + } else { + pipeline_param->forward_references = NULL; + pipeline_param->num_forward_references = 0; + } - /* Validate pipeline caps */ - va_status = vaQueryVideoProcPipelineCaps(filter->va_display, - filter->va_context, filters, num_filters, &pipeline_caps); - if (!vaapi_check_status(va_status, "vaQueryVideoProcPipelineCaps()")) - goto error; + if (filter->backward_references->len > 0) { + pipeline_param->backward_references = (VASurfaceID *) + filter->backward_references->data; + pipeline_param->num_backward_references = + MIN (filter->backward_references->len, + pipeline_caps.num_backward_references); + } else { + pipeline_param->backward_references = NULL; + pipeline_param->num_backward_references = 0; + } - if (!vaapi_create_buffer(filter->va_display, filter->va_context, - VAProcPipelineParameterBufferType, sizeof(*pipeline_param), - NULL, &pipeline_param_buf_id, (gpointer *)&pipeline_param)) - goto error; + vaapi_unmap_buffer (filter->va_display, pipeline_param_buf_id, NULL); - memset(pipeline_param, 0, sizeof(*pipeline_param)); - pipeline_param->surface = GST_VAAPI_OBJECT_ID(src_surface); - pipeline_param->surface_region = &src_rect; - pipeline_param->surface_color_standard = VAProcColorStandardNone; - pipeline_param->output_region = &dst_rect; - pipeline_param->output_color_standard = VAProcColorStandardNone; - pipeline_param->output_background_color = 0xff000000; - pipeline_param->filter_flags = from_GstVaapiSurfaceRenderFlags(flags); - pipeline_param->filters = filters; - pipeline_param->num_filters = num_filters; + va_status = vaBeginPicture (filter->va_display, filter->va_context, + GST_VAAPI_OBJECT_ID (dst_surface)); + if (!vaapi_check_status (va_status, "vaBeginPicture()")) + goto error; - // Reference frames for advanced deinterlacing - if (filter->forward_references->len > 0) { - pipeline_param->forward_references = (VASurfaceID *) - filter->forward_references->data; - pipeline_param->num_forward_references = - MIN(filter->forward_references->len, - pipeline_caps.num_forward_references); - } - else { - pipeline_param->forward_references = NULL; - pipeline_param->num_forward_references = 0; - } + va_status = vaRenderPicture (filter->va_display, filter->va_context, + &pipeline_param_buf_id, 1); + if (!vaapi_check_status (va_status, "vaRenderPicture()")) + goto error; - if (filter->backward_references->len > 0) { - pipeline_param->backward_references = (VASurfaceID *) - filter->backward_references->data; - pipeline_param->num_backward_references = - MIN(filter->backward_references->len, - pipeline_caps.num_backward_references); - } - else { - pipeline_param->backward_references = NULL; - pipeline_param->num_backward_references = 0; - } + va_status = vaEndPicture (filter->va_display, filter->va_context); + if (!vaapi_check_status (va_status, "vaEndPicture()")) + goto error; - vaapi_unmap_buffer(filter->va_display, pipeline_param_buf_id, NULL); - - va_status = vaBeginPicture(filter->va_display, filter->va_context, - GST_VAAPI_OBJECT_ID(dst_surface)); - if (!vaapi_check_status(va_status, "vaBeginPicture()")) - goto error; - - va_status = vaRenderPicture(filter->va_display, filter->va_context, - &pipeline_param_buf_id, 1); - if (!vaapi_check_status(va_status, "vaRenderPicture()")) - goto error; - - va_status = vaEndPicture(filter->va_display, filter->va_context); - if (!vaapi_check_status(va_status, "vaEndPicture()")) - goto error; - - deint_refs_clear_all(filter); - vaapi_destroy_buffer(filter->va_display, &pipeline_param_buf_id); - return GST_VAAPI_FILTER_STATUS_SUCCESS; + deint_refs_clear_all (filter); + vaapi_destroy_buffer (filter->va_display, &pipeline_param_buf_id); + return GST_VAAPI_FILTER_STATUS_SUCCESS; error: - deint_refs_clear_all(filter); - vaapi_destroy_buffer(filter->va_display, &pipeline_param_buf_id); - return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED; + deint_refs_clear_all (filter); + vaapi_destroy_buffer (filter->va_display, &pipeline_param_buf_id); + return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED; #endif - return GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_OPERATION; + return GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_OPERATION; } GstVaapiFilterStatus -gst_vaapi_filter_process(GstVaapiFilter *filter, GstVaapiSurface *src_surface, - GstVaapiSurface *dst_surface, guint flags) +gst_vaapi_filter_process (GstVaapiFilter * filter, + GstVaapiSurface * src_surface, GstVaapiSurface * dst_surface, guint flags) { - GstVaapiFilterStatus status; + GstVaapiFilterStatus status; - g_return_val_if_fail(filter != NULL, - GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(src_surface != NULL, - GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER); - g_return_val_if_fail(dst_surface != NULL, - GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (filter != NULL, + GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (src_surface != NULL, + GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER); + g_return_val_if_fail (dst_surface != NULL, + GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER); - GST_VAAPI_DISPLAY_LOCK(filter->display); - status = gst_vaapi_filter_process_unlocked(filter, - src_surface, dst_surface, flags); - GST_VAAPI_DISPLAY_UNLOCK(filter->display); - return status; + GST_VAAPI_DISPLAY_LOCK (filter->display); + status = gst_vaapi_filter_process_unlocked (filter, + src_surface, dst_surface, flags); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); + return status; } /** @@ -1474,13 +1456,13 @@ gst_vaapi_filter_process(GstVaapiFilter *filter, GstVaapiSurface *src_surface, * Return value: the set of supported target formats for video processing. */ GArray * -gst_vaapi_filter_get_formats(GstVaapiFilter *filter) +gst_vaapi_filter_get_formats (GstVaapiFilter * filter) { - g_return_val_if_fail(filter != NULL, NULL); + g_return_val_if_fail (filter != NULL, NULL); - if (!ensure_formats(filter)) - return NULL; - return g_array_ref(filter->formats); + if (!ensure_formats (filter)) + return NULL; + return g_array_ref (filter->formats); } /** @@ -1502,18 +1484,18 @@ gst_vaapi_filter_get_formats(GstVaapiFilter *filter) * may be supported, %FALSE otherwise. */ gboolean -gst_vaapi_filter_set_format(GstVaapiFilter *filter, GstVideoFormat format) +gst_vaapi_filter_set_format (GstVaapiFilter * filter, GstVideoFormat format) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - if (!ensure_formats(filter)) - return FALSE; + if (!ensure_formats (filter)) + return FALSE; - if (!is_special_format(format) && !find_format(filter, format)) - return FALSE; + if (!is_special_format (format) && !find_format (filter, format)) + return FALSE; - filter->format = format; - return TRUE; + filter->format = format; + return TRUE; } /** @@ -1527,15 +1509,15 @@ gst_vaapi_filter_set_format(GstVaapiFilter *filter, GstVideoFormat format) * Return value: %TRUE if the operation is supported, %FALSE otherwise. */ gboolean -gst_vaapi_filter_set_cropping_rectangle(GstVaapiFilter *filter, - const GstVaapiRectangle *rect) +gst_vaapi_filter_set_cropping_rectangle (GstVaapiFilter * filter, + const GstVaapiRectangle * rect) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - filter->use_crop_rect = rect != NULL; - if (filter->use_crop_rect) - filter->crop_rect = *rect; - return TRUE; + filter->use_crop_rect = rect != NULL; + if (filter->use_crop_rect) + filter->crop_rect = *rect; + return TRUE; } /** @@ -1551,15 +1533,15 @@ gst_vaapi_filter_set_cropping_rectangle(GstVaapiFilter *filter, * Return value: %TRUE if the operation is supported, %FALSE otherwise. */ gboolean -gst_vaapi_filter_set_target_rectangle(GstVaapiFilter *filter, - const GstVaapiRectangle *rect) +gst_vaapi_filter_set_target_rectangle (GstVaapiFilter * filter, + const GstVaapiRectangle * rect) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - filter->use_target_rect = rect != NULL; - if (filter->use_target_rect) - filter->target_rect = *rect; - return TRUE; + filter->use_target_rect = rect != NULL; + if (filter->use_target_rect) + filter->target_rect = *rect; + return TRUE; } /** @@ -1573,12 +1555,12 @@ gst_vaapi_filter_set_target_rectangle(GstVaapiFilter *filter, * Return value: %TRUE if the operation is supported, %FALSE otherwise. */ gboolean -gst_vaapi_filter_set_denoising_level(GstVaapiFilter *filter, gfloat level) +gst_vaapi_filter_set_denoising_level (GstVaapiFilter * filter, gfloat level) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - return op_set_generic(filter, - find_operation(filter, GST_VAAPI_FILTER_OP_DENOISE), level); + return op_set_generic (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_DENOISE), level); } /** @@ -1591,12 +1573,12 @@ gst_vaapi_filter_set_denoising_level(GstVaapiFilter *filter, gfloat level) * Return value: %TRUE if the operation is supported, %FALSE otherwise. */ gboolean -gst_vaapi_filter_set_sharpening_level(GstVaapiFilter *filter, gfloat level) +gst_vaapi_filter_set_sharpening_level (GstVaapiFilter * filter, gfloat level) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - return op_set_generic(filter, - find_operation(filter, GST_VAAPI_FILTER_OP_SHARPEN), level); + return op_set_generic (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_SHARPEN), level); } /** @@ -1609,12 +1591,12 @@ gst_vaapi_filter_set_sharpening_level(GstVaapiFilter *filter, gfloat level) * Return value: %TRUE if the operation is supported, %FALSE otherwise. */ gboolean -gst_vaapi_filter_set_hue(GstVaapiFilter *filter, gfloat value) +gst_vaapi_filter_set_hue (GstVaapiFilter * filter, gfloat value) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - return op_set_color_balance(filter, - find_operation(filter, GST_VAAPI_FILTER_OP_HUE), value); + return op_set_color_balance (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_HUE), value); } /** @@ -1627,12 +1609,12 @@ gst_vaapi_filter_set_hue(GstVaapiFilter *filter, gfloat value) * Return value: %TRUE if the operation is supported, %FALSE otherwise. */ gboolean -gst_vaapi_filter_set_saturation(GstVaapiFilter *filter, gfloat value) +gst_vaapi_filter_set_saturation (GstVaapiFilter * filter, gfloat value) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - return op_set_color_balance(filter, - find_operation(filter, GST_VAAPI_FILTER_OP_SATURATION), value); + return op_set_color_balance (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_SATURATION), value); } /** @@ -1645,12 +1627,12 @@ gst_vaapi_filter_set_saturation(GstVaapiFilter *filter, gfloat value) * Return value: %TRUE if the operation is supported, %FALSE otherwise. */ gboolean -gst_vaapi_filter_set_brightness(GstVaapiFilter *filter, gfloat value) +gst_vaapi_filter_set_brightness (GstVaapiFilter * filter, gfloat value) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - return op_set_color_balance(filter, - find_operation(filter, GST_VAAPI_FILTER_OP_BRIGHTNESS), value); + return op_set_color_balance (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_BRIGHTNESS), value); } /** @@ -1663,12 +1645,12 @@ gst_vaapi_filter_set_brightness(GstVaapiFilter *filter, gfloat value) * Return value: %TRUE if the operation is supported, %FALSE otherwise. */ gboolean -gst_vaapi_filter_set_contrast(GstVaapiFilter *filter, gfloat value) +gst_vaapi_filter_set_contrast (GstVaapiFilter * filter, gfloat value) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - return op_set_color_balance(filter, - find_operation(filter, GST_VAAPI_FILTER_OP_CONTRAST), value); + return op_set_color_balance (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_CONTRAST), value); } /** @@ -1684,14 +1666,14 @@ gst_vaapi_filter_set_contrast(GstVaapiFilter *filter, gfloat value) * Return value: %TRUE if the operation is supported, %FALSE otherwise. */ gboolean -gst_vaapi_filter_set_deinterlacing(GstVaapiFilter *filter, +gst_vaapi_filter_set_deinterlacing (GstVaapiFilter * filter, GstVaapiDeinterlaceMethod method, guint flags) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - return op_set_deinterlace(filter, - find_operation(filter, GST_VAAPI_FILTER_OP_DEINTERLACING), method, - flags); + return op_set_deinterlace (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_DEINTERLACING), method, + flags); } /** @@ -1728,20 +1710,20 @@ gst_vaapi_filter_set_deinterlacing(GstVaapiFilter *filter, * Return value: %TRUE if the operation is supported, %FALSE otherwise. */ gboolean -gst_vaapi_filter_set_deinterlacing_references(GstVaapiFilter *filter, - GstVaapiSurface **forward_references, guint num_forward_references, - GstVaapiSurface **backward_references, guint num_backward_references) +gst_vaapi_filter_set_deinterlacing_references (GstVaapiFilter * filter, + GstVaapiSurface ** forward_references, guint num_forward_references, + GstVaapiSurface ** backward_references, guint num_backward_references) { - g_return_val_if_fail(filter != NULL, FALSE); + g_return_val_if_fail (filter != NULL, FALSE); - deint_refs_clear_all(filter); + deint_refs_clear_all (filter); - if (!deint_refs_set(filter->forward_references, forward_references, - num_forward_references)) - return FALSE; + if (!deint_refs_set (filter->forward_references, forward_references, + num_forward_references)) + return FALSE; - if (!deint_refs_set(filter->backward_references, backward_references, - num_backward_references)) - return FALSE; - return TRUE; + if (!deint_refs_set (filter->backward_references, backward_references, + num_backward_references)) + return FALSE; + return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index a6ad56da74..2be711df33 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -44,15 +44,15 @@ typedef struct _GstVaapiFilterOpInfo GstVaapiFilterOpInfo; * 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_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, } GstVaapiFilterOp; /** @@ -62,9 +62,10 @@ typedef enum { * * A #GstVaapiFilterOp descriptor. */ -struct _GstVaapiFilterOpInfo { - const GstVaapiFilterOp op; - GParamSpec * const pspec; +struct _GstVaapiFilterOpInfo +{ + const GstVaapiFilterOp op; + GParamSpec *const pspec; }; /** @@ -79,12 +80,12 @@ struct _GstVaapiFilterOpInfo { * 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, + 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; /** @@ -100,11 +101,11 @@ typedef enum { * 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, + 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; /** @@ -124,9 +125,9 @@ typedef enum { * 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, + 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_DEINTERLACE_METHOD \ @@ -136,80 +137,80 @@ typedef enum { gst_vaapi_deinterlace_flags_get_type() GType -gst_vaapi_deinterlace_method_get_type(void) G_GNUC_CONST; +gst_vaapi_deinterlace_method_get_type (void) G_GNUC_CONST; GType -gst_vaapi_deinterlace_flags_get_type(void) G_GNUC_CONST; +gst_vaapi_deinterlace_flags_get_type (void) G_GNUC_CONST; GstVaapiFilter * -gst_vaapi_filter_new(GstVaapiDisplay *display); +gst_vaapi_filter_new (GstVaapiDisplay * display); GstVaapiFilter * -gst_vaapi_filter_ref(GstVaapiFilter *filter); +gst_vaapi_filter_ref (GstVaapiFilter * filter); void -gst_vaapi_filter_unref(GstVaapiFilter *filter); +gst_vaapi_filter_unref (GstVaapiFilter * filter); void -gst_vaapi_filter_replace(GstVaapiFilter **old_filter_ptr, - GstVaapiFilter *new_filter); +gst_vaapi_filter_replace (GstVaapiFilter ** old_filter_ptr, + GstVaapiFilter * new_filter); GPtrArray * -gst_vaapi_filter_get_operations(GstVaapiFilter *filter); +gst_vaapi_filter_get_operations (GstVaapiFilter * filter); gboolean -gst_vaapi_filter_has_operation(GstVaapiFilter *filter, GstVaapiFilterOp op); +gst_vaapi_filter_has_operation (GstVaapiFilter * filter, GstVaapiFilterOp op); gboolean -gst_vaapi_filter_use_operation(GstVaapiFilter *filter, GstVaapiFilterOp op); +gst_vaapi_filter_use_operation (GstVaapiFilter * filter, GstVaapiFilterOp op); gboolean -gst_vaapi_filter_set_operation(GstVaapiFilter *filter, GstVaapiFilterOp op, - const GValue *value); +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); +gst_vaapi_filter_process (GstVaapiFilter * filter, + GstVaapiSurface * src_surface, GstVaapiSurface * dst_surface, guint flags); GArray * -gst_vaapi_filter_get_formats(GstVaapiFilter *filter); +gst_vaapi_filter_get_formats (GstVaapiFilter * filter); gboolean -gst_vaapi_filter_set_format(GstVaapiFilter *filter, GstVideoFormat format); +gst_vaapi_filter_set_format (GstVaapiFilter * filter, GstVideoFormat format); gboolean -gst_vaapi_filter_set_cropping_rectangle(GstVaapiFilter *filter, - const GstVaapiRectangle *rect); +gst_vaapi_filter_set_cropping_rectangle (GstVaapiFilter * filter, + const GstVaapiRectangle * rect); gboolean -gst_vaapi_filter_set_target_rectangle(GstVaapiFilter *filter, - const GstVaapiRectangle *rect); +gst_vaapi_filter_set_target_rectangle (GstVaapiFilter * filter, + const GstVaapiRectangle * rect); gboolean -gst_vaapi_filter_set_denoising_level(GstVaapiFilter *filter, gfloat level); +gst_vaapi_filter_set_denoising_level (GstVaapiFilter * filter, gfloat level); gboolean -gst_vaapi_filter_set_sharpening_level(GstVaapiFilter *filter, gfloat level); +gst_vaapi_filter_set_sharpening_level (GstVaapiFilter * filter, gfloat level); gboolean -gst_vaapi_filter_set_hue(GstVaapiFilter *filter, gfloat value); +gst_vaapi_filter_set_hue (GstVaapiFilter * filter, gfloat value); gboolean -gst_vaapi_filter_set_saturation(GstVaapiFilter *filter, gfloat value); +gst_vaapi_filter_set_saturation (GstVaapiFilter * filter, gfloat value); gboolean -gst_vaapi_filter_set_brightness(GstVaapiFilter *filter, gfloat value); +gst_vaapi_filter_set_brightness (GstVaapiFilter * filter, gfloat value); gboolean -gst_vaapi_filter_set_contrast(GstVaapiFilter *filter, gfloat value); +gst_vaapi_filter_set_contrast (GstVaapiFilter * filter, gfloat value); gboolean -gst_vaapi_filter_set_deinterlacing(GstVaapiFilter *filter, +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); +gst_vaapi_filter_set_deinterlacing_references (GstVaapiFilter * filter, + GstVaapiSurface ** forward_references, guint num_forward_references, + GstVaapiSurface ** backward_references, guint num_backward_references); #endif /* GST_VAAPI_FILTER_H */ From 3656659d1c91f6c7e8c5ccfc1f9ae3be84aaa51c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 29 Oct 2014 16:57:12 +0100 Subject: [PATCH 1790/3781] filter: add initial support for high quality scaling. Add support for video scaling options in VPP pipelines. Only the DEFAULT mode is bound to exist. Others might be folded into that mode. --- gst-libs/gst/vaapi/gstvaapifilter.c | 64 ++++++++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapifilter.h | 27 ++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.c | 43 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 8 ++++ 4 files changed, 141 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 68d27f8540..67cd539418 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -65,6 +65,7 @@ struct _GstVaapiFilter VAContextID va_context; GPtrArray *operations; GstVideoFormat format; + GstVaapiScaleMethod scale_method; GArray *formats; GArray *forward_references; GArray *backward_references; @@ -78,6 +79,29 @@ struct _GstVaapiFilter /* --- VPP Types --- */ /* ------------------------------------------------------------------------- */ +GType +gst_vaapi_scale_method_get_type (void) +{ + static gsize g_type = 0; + + static const GEnumValue enum_values[] = { + {GST_VAAPI_SCALE_METHOD_DEFAULT, + "Default scaling mode", "default"}, + {GST_VAAPI_SCALE_METHOD_FAST, + "Fast scaling mode", "fast"}, + {GST_VAAPI_SCALE_METHOD_HQ, + "High quality scaling mode", "hq"}, + {0, NULL, NULL}, + }; + + if (g_once_init_enter (&g_type)) { + const GType type = + g_enum_register_static ("GstVaapiScaleMethod", enum_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} + GType gst_vaapi_deinterlace_method_get_type (void) { @@ -238,6 +262,7 @@ vpp_get_filter_caps (GstVaapiFilter * filter, VAProcFilterType type, #if USE_VA_VPP #define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN +#define DEFAULT_SCALING GST_VAAPI_SCALE_METHOD_DEFAULT enum { @@ -252,6 +277,7 @@ enum PROP_BRIGHTNESS = GST_VAAPI_FILTER_OP_BRIGHTNESS, PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST, PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING, + PROP_SCALING = GST_VAAPI_FILTER_OP_SCALING, N_PROPERTIES }; @@ -361,6 +387,18 @@ init_properties (void) GST_VAAPI_TYPE_DEINTERLACE_METHOD, GST_VAAPI_DEINTERLACE_METHOD_NONE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFilter:scale-method: + * + * The scaling method to use, expressed as an enum value. See + * #GstVaapiScaleMethod. + */ + g_properties[PROP_SCALING] = g_param_spec_enum ("scale-method", + "Scaling Method", + "Scaling method to use", + GST_VAAPI_TYPE_SCALE_METHOD, + DEFAULT_SCALING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); } static void @@ -396,6 +434,7 @@ op_data_new (GstVaapiFilterOp op, GParamSpec * pspec) switch (op) { case GST_VAAPI_FILTER_OP_FORMAT: case GST_VAAPI_FILTER_OP_CROP: + case GST_VAAPI_FILTER_OP_SCALING: op_data->va_type = VAProcFilterNone; break; case GST_VAAPI_FILTER_OP_DENOISE: @@ -1258,6 +1297,9 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, (value ? g_value_get_enum (value) : G_PARAM_SPEC_ENUM (op_data->pspec)->default_value), 0); break; + case GST_VAAPI_FILTER_OP_SCALING: + return gst_vaapi_filter_set_scaling (filter, value ? + g_value_get_enum (value) : DEFAULT_SCALING); default: break; } @@ -1369,7 +1411,8 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, pipeline_param->output_region = &dst_rect; pipeline_param->output_color_standard = VAProcColorStandardNone; pipeline_param->output_background_color = 0xff000000; - pipeline_param->filter_flags = from_GstVaapiSurfaceRenderFlags (flags); + pipeline_param->filter_flags = from_GstVaapiSurfaceRenderFlags (flags) | + from_GstVaapiScaleMethod (filter->scale_method); pipeline_param->filters = filters; pipeline_param->num_filters = num_filters; @@ -1727,3 +1770,22 @@ gst_vaapi_filter_set_deinterlacing_references (GstVaapiFilter * filter, return FALSE; return TRUE; } + +/** + * gst_vaapi_filter_set_scaling: + * @filter: a #GstVaapiFilter + * @method: the scaling algorithm (see #GstVaapiScaleMethod) + * + * Applies scaling algorithm to the video processing pipeline. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_scaling (GstVaapiFilter * filter, + GstVaapiScaleMethod method) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + filter->scale_method = method; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 2be711df33..0f25a86b0c 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -40,6 +40,7 @@ typedef struct _GstVaapiFilterOpInfo GstVaapiFilterOpInfo; * @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). * * The set of operations that could be applied to the filter. */ @@ -53,6 +54,7 @@ typedef enum { GST_VAAPI_FILTER_OP_BRIGHTNESS, GST_VAAPI_FILTER_OP_CONTRAST, GST_VAAPI_FILTER_OP_DEINTERLACING, + GST_VAAPI_FILTER_OP_SCALING, } GstVaapiFilterOp; /** @@ -88,6 +90,21 @@ typedef enum { 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. @@ -130,12 +147,18 @@ typedef enum { 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; @@ -213,4 +236,8 @@ 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); + #endif /* GST_VAAPI_FILTER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 18987f642b..6c6a5fb46d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -610,3 +610,46 @@ from_GstVaapiDeinterlaceFlags (guint flags) #endif return va_flags; } + +/* VPP: translate GstVaapiScaleMethod into VA scaling flags */ +guint +from_GstVaapiScaleMethod (guint value) +{ + guint va_flags; + + switch (value) { + case GST_VAAPI_SCALE_METHOD_DEFAULT: + va_flags = VA_FILTER_SCALING_DEFAULT; + break; + case GST_VAAPI_SCALE_METHOD_FAST: + va_flags = VA_FILTER_SCALING_FAST; + break; + case GST_VAAPI_SCALE_METHOD_HQ: + va_flags = VA_FILTER_SCALING_HQ; + break; + default: + va_flags = 0; + break; + } + return va_flags; +} + +/* VPP: translate VA scaling flags into GstVaapiScale Method */ +guint +to_GstVaapiScaleMethod (guint flags) +{ + GstVaapiScaleMethod method; + + switch (flags) { + case VA_FILTER_SCALING_FAST: + method = GST_VAAPI_SCALE_METHOD_FAST; + break; + case VA_FILTER_SCALING_HQ: + method = GST_VAAPI_SCALE_METHOD_HQ; + break; + default: + method = GST_VAAPI_SCALE_METHOD_DEFAULT; + break; + } + return method; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index e5f85037ce..979a9ed785 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -132,4 +132,12 @@ G_GNUC_INTERNAL guint from_GstVaapiDeinterlaceFlags (guint flags); +G_GNUC_INTERNAL +guint +from_GstVaapiScaleMethod (guint value); + +G_GNUC_INTERNAL +guint +to_GstVaapiScaleMethod (guint flags); + #endif /* GST_VAAPI_UTILS_H */ From eeb43989c1cf92aa3bd88e330ecea95bb8ab3319 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 29 Oct 2014 17:30:30 +0100 Subject: [PATCH 1791/3781] vaapipostproc: allow user defined scaling mode. Add new "scale-method" property to expose the scaling mode to use during video processing. Note that this is only a hint, and the actual behaviour may differ from implementation (VA driver) to implementation. --- gst/vaapi/gstvaapipostproc.c | 24 ++++++++++++++++++++++++ gst/vaapi/gstvaapipostproc.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index fa6ffe5d0e..bcddea6e99 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -122,6 +122,7 @@ enum { PROP_SATURATION, PROP_BRIGHTNESS, PROP_CONTRAST, + PROP_SCALE_METHOD, }; #define DEFAULT_FORMAT GST_VIDEO_FORMAT_ENCODED @@ -559,6 +560,11 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, postproc->contrast)) return GST_FLOW_NOT_SUPPORTED; + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SCALE) && + !gst_vaapi_filter_set_scaling(postproc->filter, + postproc->scale_method)) + return GST_FLOW_NOT_SUPPORTED; + inbuf_meta = gst_buffer_get_vaapi_video_meta(inbuf); if (!inbuf_meta) goto error_invalid_buffer; @@ -1439,6 +1445,10 @@ gst_vaapipostproc_set_property( postproc->contrast = g_value_get_float(value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CONTRAST; break; + case PROP_SCALE_METHOD: + postproc->scale_method = g_value_get_enum(value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SCALE; + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1492,6 +1502,9 @@ gst_vaapipostproc_get_property( case PROP_CONTRAST: g_value_set_float(value, postproc->contrast); break; + case PROP_SCALE_METHOD: + g_value_set_enum(value, postproc->scale_method); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1705,6 +1718,17 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) g_object_class_install_property(object_class, PROP_CONTRAST, filter_op->pspec); + /** + * GstVaapiPostproc:scale-method: + * + * The scaling method to use, expressed as an enum value. See + * #GstVaapiScaleMethod. + */ + filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_SCALING); + if (filter_op) + g_object_class_install_property(object_class, + PROP_SCALE_METHOD, filter_op->pspec); + g_ptr_array_unref(filter_ops); } diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index c27b29a1d0..af6fdf9dc1 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -93,6 +93,7 @@ typedef enum { * @GST_VAAPI_POSTPROC_FLAG_CONTRAST: Change contrast. * @GST_VAAPI_POSTPROC_FLAG_DEINTERLACE: Deinterlacing. * @GST_VAAPI_POSTPROC_FLAG_SIZE: Video scaling. + * @GST_VAAPI_POSTPROC_FLAG_SCALE: Video scaling mode. * * The set of operations that are to be performed for each frame. */ @@ -105,6 +106,7 @@ typedef enum { GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS = 1 << GST_VAAPI_FILTER_OP_BRIGHTNESS, GST_VAAPI_POSTPROC_FLAG_CONTRAST = 1 << GST_VAAPI_FILTER_OP_CONTRAST, GST_VAAPI_POSTPROC_FLAG_DEINTERLACE = 1 << GST_VAAPI_FILTER_OP_DEINTERLACING, + GST_VAAPI_POSTPROC_FLAG_SCALE = 1 << GST_VAAPI_FILTER_OP_SCALING, /* Additional custom flags */ GST_VAAPI_POSTPROC_FLAG_CUSTOM = 1 << 20, @@ -162,6 +164,7 @@ struct _GstVaapiPostproc { gfloat sharpen_level; /* Color balance filter values */ + GstVaapiScaleMethod scale_method; gfloat hue; gfloat saturation; gfloat brightness; From 626e180fef9da611b2faa7a700599ed348b28d61 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 3 Nov 2014 19:19:20 +0200 Subject: [PATCH 1792/3781] vaapipostproc: Tweak the output video format setting to enable the autoplugging This is a workaround until auto-plugging is fixed when format=ENCODED + memory:VASurface caps feature are provided. Use the downstream negotiated video format as the output video format if the user didn't ask for the colorspace conversion explicitly. Usecase: This will help to connect elements like videoscale, videorate etc to vaapipostproc. https://bugzilla.gnome.org/show_bug.cgi?id=739443 --- gst/vaapi/gstvaapipostproc.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index bcddea6e99..2664b617b5 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1127,7 +1127,28 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, // Update size from user-specified parameters format = GST_VIDEO_INFO_FORMAT(&vi); #if GST_CHECK_VERSION(1,1,0) - out_format = postproc->format; + /* XXX: this is a workaround until auto-plugging is fixed when + * format=ENCODED + memory:VASurface caps feature are provided. + * use the downstream negotiated video format as the output format + * if the user didn't explicitly ask for colorspace conversion. + * Use a filter caps which contain all raw video formats, (excluding + * GST_VIDEO_FORMAT_ENCODED) */ + if (postproc->format != DEFAULT_FORMAT) + out_format = postproc->format; + else { + GstCaps *peer_caps, *filter_caps; + GstVideoInfo peer_vi; + filter_caps = gst_caps_from_string (GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL)); + peer_caps = gst_pad_peer_query_caps( + GST_BASE_TRANSFORM_SRC_PAD(trans), filter_caps); + if (!gst_caps_is_fixed(peer_caps)) + peer_caps = gst_caps_fixate (peer_caps); + gst_video_info_from_caps(&peer_vi, peer_caps); + out_format = GST_VIDEO_INFO_FORMAT (&peer_vi); + gst_caps_unref (filter_caps); + if (peer_caps) + gst_caps_unref (peer_caps); + } #else out_format = GST_VIDEO_FORMAT_ENCODED; #endif From 08bbab889bdd4f793455516a9f4e1e0e9a4a48a1 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 3 Nov 2014 19:20:43 +0200 Subject: [PATCH 1793/3781] vaapipostproc: Add string representation of VPP functions to ElementFactoy Klass Added the same Klass specifications used in other upstream video postprocessing elements like videoconvert, videoscale, videobalance and deinterlace. An example use case is for this is to help the playsink to autoplug the hardware accelerated deinterlacer. --- gst/vaapi/gstvaapipostproc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 2664b617b5..482d5b7937 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1568,7 +1568,8 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) gst_element_class_set_static_metadata(element_class, "VA-API video postprocessing", - "Filter/Converter/Video", + "Filter/Converter/Video;Filter/Converter/Video/Scaler;" + "Filter/Effect/Video;Filter/Effect/Video/Deinterlace", GST_PLUGIN_DESC, "Gwenole Beauchesne "); From c4f42114b41bd5ae78b79d529fc617e2906e4a96 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 14 Nov 2014 09:54:02 +0100 Subject: [PATCH 1794/3781] codecparsers: update to gst-vaapi-branch commit 3d05d9f. 1241840 h264: fix derivation of MaxPicNum variable 3bd718e h264: fix GstH264ParserResult documentation typo b021609 h264parse: set the HEADER flag on buffers containing SPS or PPS b08e4be h264parse: don't unnecesarily set src_caps --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index f9d3bde2cb..3d05d9f272 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit f9d3bde2cb4eabedadf2442a4a68d7215ccd173b +Subproject commit 3d05d9f272c4a851d199732b8d47afbf3e6e83ea From 415d5df7ee716fc5d8b652b359dc16187ab0e905 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Nov 2014 15:00:21 +0100 Subject: [PATCH 1795/3781] decoder: h264: fix detection of top-field-first (TFF) flag. Use the SEI pic_timing() message to track the pic_struct variable when present, or infer it from the regular slice header flags field_pic_flag and bottom_field_flag. This fixes temporal sequence ordering when the output pictures are to be displayed. https://bugzilla.gnome.org/show_bug.cgi?id=739291 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 65 +++++++++++++++++++---- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 6b57fa6ac8..ac1e835c8d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -369,7 +369,9 @@ gst_vaapi_frame_store_split_fields(GstVaapiFrameStore *fs) g_return_val_if_fail(fs->num_buffers == 1, FALSE); - first_field->base.structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + first_field->base.structure = GST_VAAPI_PICTURE_IS_TFF(first_field) ? + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; GST_VAAPI_PICTURE_FLAG_SET(first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED); second_field = gst_vaapi_picture_h264_new_field(first_field); @@ -490,6 +492,7 @@ struct _GstVaapiDecoderH264Private { guint nal_length_size; guint mb_width; guint mb_height; + guint pic_structure; // pic_struct (from SEI pic_timing() or inferred) gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt gint32 poc_msb; // PicOrderCntMsb gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header()) @@ -1490,6 +1493,7 @@ decode_current_picture(GstVaapiDecoderH264 *decoder) if (!is_valid_state(priv->decoder_state, GST_H264_VIDEO_STATE_VALID_PICTURE)) goto drop_frame; priv->decoder_state = 0; + priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME; if (!picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -1510,6 +1514,7 @@ error: drop_frame: priv->decoder_state = 0; + priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME; return GST_VAAPI_DECODER_STATUS_DROP_FRAME; } @@ -1705,6 +1710,34 @@ decode_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static GstVaapiDecoderStatus +decode_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiParserInfoH264 * const pi = unit->parsed_info; + guint i; + + GST_DEBUG("decode SEI messages"); + + for (i = 0; i < pi->data.sei->len; i++) { + const GstH264SEIMessage * const sei = + &g_array_index(pi->data.sei, GstH264SEIMessage, i); + + switch (sei->payloadType) { + case GST_H264_SEI_PIC_TIMING: { + const GstH264PicTiming * const pic_timing = + &sei->payload.pic_timing; + if (pic_timing->pic_struct_present_flag) + priv->pic_structure = pic_timing->pic_struct; + break; + } + default: + break; + } + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderH264 *decoder) { @@ -2881,14 +2914,28 @@ init_picture( } /* Initialize picture structure */ - if (!slice_hdr->field_pic_flag) - base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - else { + if (slice_hdr->field_pic_flag) { GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED); - if (!slice_hdr->bottom_field_flag) - base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; - else - base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + priv->pic_structure = slice_hdr->bottom_field_flag ? + GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD : + GST_H264_SEI_PIC_STRUCT_TOP_FIELD; + } + + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + switch (priv->pic_structure) { + case GST_H264_SEI_PIC_STRUCT_TOP_FIELD: + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + if (GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture)) + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF); + break; + case GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD: + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + break; + case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP: + case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM: + if (GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture)) + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF); + break; } picture->structure = base_picture->structure; @@ -3781,7 +3828,7 @@ decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) status = decode_sequence_end(decoder); break; case GST_H264_NAL_SEI: - status = GST_VAAPI_DECODER_STATUS_SUCCESS; + status = decode_sei(decoder, unit); break; default: GST_WARNING("unsupported NAL unit type %d", pi->nalu.type); From a4048a9d6bc689f50b4b940782aa6a7c7740f772 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Nov 2014 15:05:19 +0100 Subject: [PATCH 1796/3781] decoder: h264: fix picture ordering count type 0 with previous MMCO5. Fix the decoding process for picture order count type 0 when the previous picture had a memory_management_control_operation = 5. In particular, fix the actual variable type for prev_pic_structure to hold the full bits of the picture structure. In practice, this used to work though, due to the underlying type used to express a gboolean. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index ac1e835c8d..c8bbc03389 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -502,7 +502,7 @@ struct _GstVaapiDecoderH264Private { gint32 frame_num; // frame_num (from slice_header()) gint32 prev_frame_num; // prevFrameNum gboolean prev_pic_has_mmco5; // prevMmco5Pic - gboolean prev_pic_structure; // previous picture structure + guint prev_pic_structure; // previous picture structure guint is_opened : 1; guint is_avcC : 1; guint has_context : 1; From 8f71f74c5d67079c5addc3ecd99278bd413248f1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 13 Nov 2014 15:13:24 +0100 Subject: [PATCH 1797/3781] decoder: h264: add initial support for repeat-first-field (RFF) flag. Use the SEI pic_timing() message to track and propagate down the repeat first field (RFF) flag. This is only initial support as there is one other condition that could induce the RFF flag, which is not handled yet. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 5 +++++ gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 4 +++- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 7 ++++++- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index c8bbc03389..9730e124ab 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2932,10 +2932,15 @@ init_picture( base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; break; case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP: + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_RFF); + // fall-through case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM: if (GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture)) GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF); break; + case GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_RFF); + break; } picture->structure = base_picture->structure; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 516ff69cb0..c8cbfbe31a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -114,7 +114,7 @@ gst_vaapi_picture_create (GstVaapiPicture * picture, GST_VAAPI_PICTURE_FLAG_REFERENCE | GST_VAAPI_PICTURE_FLAG_INTERLACED | GST_VAAPI_PICTURE_FLAG_FF | GST_VAAPI_PICTURE_FLAG_TFF | - GST_VAAPI_PICTURE_FLAG_MVC)); + GST_VAAPI_PICTURE_FLAG_RFF | GST_VAAPI_PICTURE_FLAG_MVC)); picture->structure = parent_picture->structure; if ((args->flags & GST_VAAPI_CREATE_PICTURE_FLAG_FIELD) && @@ -342,6 +342,8 @@ do_output (GstVaapiPicture * 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; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 6499574891..9edb449634 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -67,6 +67,7 @@ typedef enum * @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_LAST: first flag that can be used by subclasses * * Enum values used for #GstVaapiPicture flags. @@ -81,7 +82,8 @@ typedef enum 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_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 8), + GST_VAAPI_PICTURE_FLAG_RFF = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 8), + GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 9), } GstVaapiPictureFlags; #define GST_VAAPI_PICTURE_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS @@ -107,6 +109,9 @@ typedef enum #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) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index b36be5db43..e0e358f64a 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -34,7 +34,7 @@ G_BEGIN_DECLS * GstVaapiSurfaceProxyFlags: * @GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED: interlaced frame * @GST_VAAPI_SURFACE_PROXY_FLAG_TFF: top-field-first - * @GST_VAAPI_SURFACE_PROXY_FLAG_RFF: repeat-field-first + * @GST_VAAPI_SURFACE_PROXY_FLAG_RFF: repeat-first-field * @GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD: only one field is available * @GST_VAAPI_SURFACE_PROXY_FLAG_FFB: first frame in bundle, e.g. the first * view component of a MultiView Coded (MVC) frame From d1b7dc21f82124718da5f8560319b43d190f3fdd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 12 Nov 2014 07:46:53 +0100 Subject: [PATCH 1798/3781] vaapidecode: only expose supported profiles when needed. JPEG and VP8 codecs do not really support the concept of "profile". So, don't try to expose any set that wouldn't be supported by jpegparse, or ivfparse for instance. https://bugzilla.gnome.org/show_bug.cgi?id=739713 https://bugzilla.gnome.org/show_bug.cgi?id=739714 --- gst-libs/gst/vaapi/gstvaapiprofile.c | 7 ++++--- gst/vaapi/gstvaapidecode.c | 10 +++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index c50ca2b5b7..6337fe99e2 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -131,12 +131,13 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { }, #if VA_CHECK_VERSION(0,32,0) { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline, - "image/jpeg", "baseline" + "image/jpeg", NULL }, #endif #if VA_CHECK_VERSION(0,35,0) - {GST_VAAPI_PROFILE_VP8, VAProfileVP8Version0_3, - "video/x-vp8", "Version0_3"}, + { GST_VAAPI_PROFILE_VP8, VAProfileVP8Version0_3, + "video/x-vp8", NULL + }, #endif { 0, } }; diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 11ae6bb743..deef49a0b7 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -924,15 +924,15 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) if (!media_type_name) continue; - profile_name = gst_vaapi_profile_get_name(profile); - if (!profile_name) - continue; - caps = gst_caps_from_string(media_type_name); if (!caps) continue; structure = gst_caps_get_structure (caps, 0); - gst_structure_set (structure, "profile", G_TYPE_STRING, profile_name, NULL); + + profile_name = gst_vaapi_profile_get_name(profile); + if (profile_name) + gst_structure_set(structure, "profile", G_TYPE_STRING, + profile_name, NULL); allowed_caps = gst_caps_merge(allowed_caps, caps); } From 0ddf6b21b960c43e11e196322ae709ad84ea8124 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 18 Nov 2014 14:07:57 +0200 Subject: [PATCH 1799/3781] vaapidecode: increase the rank to GST_RANK_PRIMARY + 1 This is for helping decodebin to autoplug the vaapidecode element. Decodebin is selecting decoder elements only based on rank and caps. Without overriding the autoplug-* signals there is no way to autoplug HW decoders inside decodebin. An easier soulution is to raise the rank of vaapidecode, so that it gets selected first. https://bugzilla.gnome.org/show_bug.cgi?id=739332 --- gst/vaapi/gstvaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 34358b8c44..abe9da4d0a 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -51,7 +51,7 @@ plugin_init (GstPlugin *plugin) GST_TYPE_VAAPIUPLOAD); #endif gst_element_register(plugin, "vaapidecode", - GST_RANK_PRIMARY, + GST_RANK_PRIMARY + 1, GST_TYPE_VAAPIDECODE); gst_element_register(plugin, "vaapipostproc", GST_RANK_PRIMARY, From a4d88db0fdf208bb5c999cf2cca2742993b17cd8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 18 Nov 2014 14:57:02 +0100 Subject: [PATCH 1800/3781] plugins: preserve framerate when updating src caps video format. In the current implementation, gst_video_info_set_format() would reset the whole GstVideoInfo structure first, prior to setting video format and size. So, coleteral information like framerate or pixel-aspect- ratio are lost. Provide and use a unique gst_video_info_change_format() for overcome this issue, i.e. only have it change the format and video size, and copy over the rest of the fields. https://bugzilla.gnome.org/show_bug.cgi?id=734665 --- gst/vaapi/gstvaapidecode.c | 25 +++---------------------- gst/vaapi/gstvaapipluginutil.c | 17 +++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 5 +++++ gst/vaapi/gstvaapipostproc.c | 6 +++--- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index deef49a0b7..db67323844 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -129,25 +129,6 @@ gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps) return TRUE; } -#if GST_CHECK_VERSION(1,1,0) -static void -gst_vaapidecode_video_info_change_format(GstVideoInfo *info, - GstVideoFormat format, guint width, guint height) -{ - GstVideoInfo vi = *info; - - gst_video_info_set_format (info, format, width, height); - - info->interlace_mode = vi.interlace_mode; - info->flags = vi.flags; - info->views = vi.views; - info->par_n = vi.par_n; - info->par_d = vi.par_d; - info->fps_n = vi.fps_n; - info->fps_d = vi.fps_d; -} -#endif - static gboolean gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, const GstVideoCodecState *ref_state) @@ -188,7 +169,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, vis = *vi; switch (feature) { case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: - gst_vaapidecode_video_info_change_format(&vis, GST_VIDEO_FORMAT_RGBA, + gst_video_info_change_format(&vis, GST_VIDEO_FORMAT_RGBA, GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); features = gst_caps_features_new( GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); @@ -199,7 +180,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, format=ENCODED + memory:VASurface caps feature are provided. Meanwhile, providing a random format here works but this is a terribly wrong thing per se. */ - gst_vaapidecode_video_info_change_format(&vis, out_format, + gst_video_info_change_format(&vis, out_format, GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); #if GST_CHECK_VERSION(1,5,0) if (feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) @@ -544,7 +525,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) state = gst_video_decoder_get_output_state(vdec); if (!gst_caps_is_always_compatible(caps, state->caps)) { if (decode->has_texture_upload_meta) - gst_video_info_set_format(&state->info, GST_VIDEO_FORMAT_RGBA, + gst_video_info_change_format(&state->info, GST_VIDEO_FORMAT_RGBA, GST_VIDEO_INFO_WIDTH(&state->info), GST_VIDEO_INFO_HEIGHT(&state->info)); gst_vaapidecode_update_src_caps(decode, state); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 40f5588633..7b0ced4c8b 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -681,3 +681,20 @@ gst_caps_has_vaapi_surface (GstCaps * caps) #endif return found_caps; } + +void +gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, + guint width, guint height) +{ + GstVideoInfo vi = *vip; + + gst_video_info_set_format (vip, format, width, height); + + vip->interlace_mode = vi.interlace_mode; + vip->flags = vi.flags; + vip->views = vi.views; + vip->par_n = vi.par_n; + vip->par_d = vi.par_d; + vip->fps_n = vi.fps_n; + vip->fps_d = vi.fps_d; +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 1849f54e9f..0f6490ef2f 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -117,4 +117,9 @@ G_GNUC_INTERNAL gboolean gst_caps_has_vaapi_surface (GstCaps * caps); +G_GNUC_INTERNAL +void +gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, + guint width, guint height); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 482d5b7937..2dd9ce3dfd 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1153,7 +1153,7 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, out_format = GST_VIDEO_FORMAT_ENCODED; #endif find_best_size(postproc, &vi, &width, &height); - gst_video_info_set_format(&vi, out_format, width, height); + gst_video_info_change_format(&vi, out_format, width, height); #if GST_CHECK_VERSION(1,1,0) out_caps = gst_video_info_to_caps(&vi); @@ -1177,7 +1177,7 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) format = GST_VIDEO_FORMAT_RGBA; - gst_video_info_set_format(&vi, format, width, height); + gst_video_info_change_format(&vi, format, width, height); sink_caps = gst_video_info_to_caps(&vi); if (sink_caps) { if (feature_str) @@ -1318,7 +1318,7 @@ ensure_srcpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps) gst_video_info_init(&vi); gst_video_info_from_caps(&vi, caps); - gst_video_info_set_format(&vi, postproc->format, + gst_video_info_change_format(&vi, postproc->format, GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); if (postproc->filter_pool && !video_info_changed(&vi, &postproc->filter_pool_info)) From 0e87abc574427c6f1d702492fd71d7723a06ff4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 12 Jul 2013 06:34:15 -0400 Subject: [PATCH 1801/3781] plugins: enable memory maps for read & write. Hence vaapisink can display buffers decoded by gst-libav, or HW decoded buffers can be further processed in-place, e.g. with a textoverlay. https://bugzilla.gnome.org/show_bug.cgi?id=704078 [ported to current git master branch, amended commit message] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapivideomemory.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 176e7f6c81..73cd0003a0 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -167,11 +167,6 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, if (!ensure_image (mem)) goto error_ensure_image; - // Check that we can actually map the surface, or image - if ((flags & GST_MAP_READWRITE) == GST_MAP_READWRITE && - !mem->use_direct_rendering) - goto error_unsupported_map; - // Load VA image from surface if ((flags & GST_MAP_READ) && !mem->use_direct_rendering) gst_vaapi_surface_get_image (mem->surface, mem->image); @@ -192,11 +187,6 @@ error_incompatible_map: GST_ERROR ("incompatible map type (%d)", mem->map_type); return FALSE; } -error_unsupported_map: - { - GST_ERROR ("unsupported map flags (0x%x)", flags); - return FALSE; - } error_ensure_surface: { const GstVideoInfo *const vip = mem->surface_info; From ceb60285ea35699111ba56ec1b1bc8a8d1273545 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 21 Nov 2014 15:23:13 +0100 Subject: [PATCH 1802/3781] plugins: ensure VA surface is current prior to using it. When interacting with SW elements, the buffers and underlying video memory could be mapped as read/write. However, we need to use those buffers again as plain VA surfaces, we have to make sure the VA image is thus committed back to VA surface memory. This fixes pipelines involving avdec_* and vaapi{postproc,sink}. --- gst/vaapi/gstvaapivideomemory.c | 94 +++++++++++++++++++++++++++------ gst/vaapi/gstvaapivideomemory.h | 29 ++++++++++ gst/vaapi/gstvaapivideometa.c | 41 ++++++++++++-- 3 files changed, 144 insertions(+), 20 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 73cd0003a0..d287a75483 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -91,6 +91,23 @@ ensure_image (GstVaapiVideoMemory * mem) return TRUE; } +static gboolean +ensure_image_is_current (GstVaapiVideoMemory * mem) +{ + if (mem->use_direct_rendering) + return TRUE; + + if (!GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT)) { + if (!gst_vaapi_surface_get_image (mem->surface, mem->image)) + return FALSE; + + GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); + } + return TRUE; +} + static GstVaapiSurface * new_surface (GstVaapiDisplay * display, const GstVideoInfo * vip) { @@ -145,6 +162,23 @@ ensure_surface (GstVaapiVideoMemory * mem) return mem->surface != NULL; } +static gboolean +ensure_surface_is_current (GstVaapiVideoMemory * mem) +{ + if (mem->use_direct_rendering) + return TRUE; + + if (!GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT)) { + if (!gst_vaapi_surface_put_image (mem->surface, mem->image)) + return FALSE; + + GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); + } + return TRUE; +} + gboolean gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags) @@ -168,12 +202,17 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, goto error_ensure_image; // Load VA image from surface - if ((flags & GST_MAP_READ) && !mem->use_direct_rendering) - gst_vaapi_surface_get_image (mem->surface, mem->image); + if ((flags & GST_MAP_READ) && !ensure_image_is_current (mem)) + goto error_no_current_image; if (!gst_vaapi_image_map (mem->image)) goto error_map_image; mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR; + + // Mark surface as dirty and expect updates from image + if (flags & GST_MAP_WRITE) + GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); } *data = gst_vaapi_image_get_plane (mem->image, plane); @@ -209,6 +248,11 @@ error_map_image: GST_VAAPI_ID_ARGS (gst_vaapi_image_get_id (mem->image))); return FALSE; } +error_no_current_image: + { + GST_ERROR ("failed to make image current"); + return FALSE; + } } gboolean @@ -229,23 +273,16 @@ gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane, mem->map_type = 0; /* Unmap VA image used for read/writes */ - if (info->flags & GST_MAP_READWRITE) + if (info->flags & GST_MAP_READWRITE) { gst_vaapi_image_unmap (mem->image); - /* Commit VA image to surface */ - if ((info->flags & GST_MAP_WRITE) && !mem->use_direct_rendering) { - if (!gst_vaapi_surface_put_image (mem->surface, mem->image)) - goto error_upload_image; + if (info->flags & GST_MAP_WRITE) { + GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); + } } } return TRUE; - - /* ERRORS */ -error_upload_image: - { - GST_ERROR ("failed to upload image"); - return FALSE; - } } GstMemory * @@ -275,6 +312,9 @@ gst_vaapi_video_memory_new (GstAllocator * base_allocator, mem->map_type = 0; mem->map_count = 0; mem->use_direct_rendering = allocator->has_direct_rendering; + + GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); return GST_MEMORY_CAST (mem); } @@ -313,6 +353,14 @@ gst_vaapi_video_memory_reset_surface (GstVaapiVideoMemory * mem) gst_vaapi_video_meta_set_surface_proxy (mem->meta, NULL); } +gboolean +gst_vaapi_video_memory_sync (GstVaapiVideoMemory * mem) +{ + g_return_val_if_fail (mem, NULL); + + return ensure_surface_is_current (mem); +} + static gpointer gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize, guint flags) @@ -330,6 +378,8 @@ gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize, gst_vaapi_video_meta_get_surface_proxy (mem->meta)); if (!mem->proxy) goto error_no_surface_proxy; + if (!ensure_surface_is_current (mem)) + goto error_no_current_surface; mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE; break; case GST_MAP_READ: @@ -338,8 +388,8 @@ gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize, goto error_no_surface; if (!ensure_image (mem)) goto error_no_image; - if (!mem->use_direct_rendering) - gst_vaapi_surface_get_image (mem->surface, mem->image); + if (!ensure_image_is_current (mem)) + goto error_no_current_image; if (!gst_vaapi_image_map (mem->image)) goto error_map_image; mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR; @@ -379,9 +429,15 @@ error_no_surface_proxy: error_no_surface: GST_ERROR ("failed to extract VA surface from video buffer"); return NULL; +error_no_current_surface: + GST_ERROR ("failed to make surface current"); + return NULL; error_no_image: GST_ERROR ("failed to extract VA image from video buffer"); return NULL; +error_no_current_image: + GST_ERROR ("failed to make image current"); + return NULL; error_map_image: GST_ERROR ("failed to map VA image"); return NULL; @@ -429,6 +485,9 @@ gst_vaapi_video_memory_copy (GstVaapiVideoMemory * mem, if (offset != 0 || (size != -1 && (gsize) size != maxsize)) goto error_unsupported; + if (!ensure_surface_is_current (mem)) + goto error_no_current_surface; + meta = gst_vaapi_video_meta_copy (mem->meta); if (!meta) goto error_allocate_memory; @@ -440,6 +499,9 @@ gst_vaapi_video_memory_copy (GstVaapiVideoMemory * mem, return GST_VAAPI_VIDEO_MEMORY_CAST (out_mem); /* ERRORS */ +error_no_current_surface: + GST_ERROR ("failed to make surface current"); + return NULL; error_unsupported: GST_ERROR ("failed to copy partial memory (unsupported operation)"); return NULL; diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 74af3681e4..5681a1c065 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -42,12 +42,22 @@ typedef struct _GstVaapiVideoAllocatorClass GstVaapiVideoAllocatorClass; #define GST_VAAPI_VIDEO_MEMORY_CAST(mem) \ ((GstVaapiVideoMemory *) (mem)) +#define GST_VAAPI_IS_VIDEO_MEMORY(mem) \ + ((mem) && (mem)->allocator && GST_VAAPI_IS_VIDEO_ALLOCATOR((mem)->allocator)) + #define GST_VAAPI_VIDEO_MEMORY_NAME "GstVaapiVideoMemory" #if GST_CHECK_VERSION(1,1,0) #define GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "memory:VASurface" #endif +#define GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET(mem, flag) \ + GST_MEMORY_FLAG_IS_SET (mem, flag) +#define GST_VAAPI_VIDEO_MEMORY_FLAG_SET(mem, flag) \ + GST_MINI_OBJECT_FLAG_SET (mem, flag) +#define GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET(mem, flag) \ + GST_MEMORY_FLAG_UNSET (mem, flag) + /** * GstVaapiVideoMemoryMapType: * @GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: map with gst_buffer_map() @@ -66,6 +76,21 @@ typedef enum GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR } GstVaapiVideoMemoryMapType; +/** + * GstVaapiVideoMemoryFlags: + * @GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT: The embedded + * #GstVaapiSurface has the up-to-date video frame contents. + * @GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT: The embedded + * #GstVaapiImage has the up-to-date video frame contents. + * + * The set of extended #GstMemory flags. + */ +typedef enum +{ + GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT = GST_MEMORY_FLAG_LAST << 0, + GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT = GST_MEMORY_FLAG_LAST << 1, +} GstVaapiVideoMemoryFlags; + /** * GstVaapiVideoMemory: * @@ -106,6 +131,10 @@ G_GNUC_INTERNAL void gst_vaapi_video_memory_reset_surface (GstVaapiVideoMemory * mem); +G_GNUC_INTERNAL +gboolean +gst_vaapi_video_memory_sync (GstVaapiVideoMemory * mem); + /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoAllocator --- */ /* ------------------------------------------------------------------------ */ diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index d67f458c26..ab97be5f65 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -32,6 +32,10 @@ #include #include "gstvaapivideometa.h" +#if GST_CHECK_VERSION(1,0,0) +# include "gstvaapivideomemory.h" +#endif + #define GST_VAAPI_VIDEO_META(obj) \ ((GstVaapiVideoMeta *) (obj)) #define GST_VAAPI_IS_VIDEO_META(obj) \ @@ -39,6 +43,7 @@ struct _GstVaapiVideoMeta { + GstBuffer *buffer; gint ref_count; GstVaapiDisplay *display; GstVaapiVideoPool *image_pool; @@ -50,6 +55,23 @@ struct _GstVaapiVideoMeta guint has_render_rect:1; }; +static gboolean +ensure_surface_proxy (GstVaapiVideoMeta * meta) +{ + if (!meta->proxy) + return FALSE; + +#if GST_CHECK_VERSION(1,0,0) + if (meta->buffer) { + GstMemory *const mem = gst_buffer_peek_memory (meta->buffer, 0); + + if (GST_VAAPI_IS_VIDEO_MEMORY (mem)) + return gst_vaapi_video_memory_sync (GST_VAAPI_VIDEO_MEMORY_CAST (mem)); + } +#endif + return TRUE; +} + static inline void set_display (GstVaapiVideoMeta * meta, GstVaapiDisplay * display) { @@ -153,6 +175,7 @@ gst_vaapi_video_meta_finalize (GstVaapiVideoMeta * meta) static void gst_vaapi_video_meta_init (GstVaapiVideoMeta * meta) { + meta->buffer = NULL; meta->ref_count = 1; meta->display = NULL; meta->image_pool = NULL; @@ -222,6 +245,7 @@ gst_vaapi_video_meta_copy (GstVaapiVideoMeta * meta) if (!copy) return NULL; + copy->buffer = NULL; copy->ref_count = 1; copy->display = gst_vaapi_display_ref (meta->display); copy->image_pool = NULL; @@ -530,7 +554,8 @@ gst_vaapi_video_meta_get_surface (GstVaapiVideoMeta * meta) { g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); - return meta->proxy ? GST_VAAPI_SURFACE_PROXY_SURFACE (meta->proxy) : NULL; + return ensure_surface_proxy (meta) ? GST_VAAPI_SURFACE_PROXY_SURFACE (meta-> + proxy) : NULL; } /** @@ -549,7 +574,7 @@ gst_vaapi_video_meta_get_surface_proxy (GstVaapiVideoMeta * meta) { g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); - return meta->proxy; + return ensure_surface_proxy (meta) ? meta->proxy : NULL; } /** @@ -760,6 +785,7 @@ gst_vaapi_video_meta_info_get (void) GstVaapiVideoMeta * gst_buffer_get_vaapi_video_meta (GstBuffer * buffer) { + GstVaapiVideoMeta *meta; GstMeta *m; g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); @@ -767,7 +793,11 @@ gst_buffer_get_vaapi_video_meta (GstBuffer * buffer) m = gst_buffer_get_meta (buffer, GST_VAAPI_VIDEO_META_API_TYPE); if (!m) return NULL; - return GST_VAAPI_VIDEO_META_HOLDER (m)->meta; + + meta = GST_VAAPI_VIDEO_META_HOLDER (m)->meta; + if (meta) + meta->buffer = buffer; + return meta; } void @@ -813,6 +843,7 @@ meta_quark_get (void) GstVaapiVideoMeta * gst_buffer_get_vaapi_video_meta (GstBuffer * buffer) { + GstVaapiVideoMeta *meta; const GstStructure *structure; const GValue *value; @@ -826,7 +857,9 @@ gst_buffer_get_vaapi_video_meta (GstBuffer * buffer) if (!value) return NULL; - return GST_VAAPI_VIDEO_META (g_value_get_boxed (value)); + meta = GST_VAAPI_VIDEO_META (g_value_get_boxed (value)); + meta->buffer = buffer; + return meta; } void From 5fd643bf49760fca8cec748f47db96af8673d7e0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 21 Nov 2014 15:43:35 +0100 Subject: [PATCH 1803/3781] plugins: fix "current" video memory flags. If the surface proxy is updated into the GstVaapiVideoMemory, then it is assumed it is the most current representation of the current video frame. Likewise, make a few more arrangements to have the "current " flags set more consistently. --- gst/vaapi/gstvaapivideomemory.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index d287a75483..7ab18cb49c 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -86,6 +86,11 @@ ensure_image (GstVaapiVideoMemory * mem) mem->image = gst_vaapi_video_pool_get_object (allocator->image_pool); if (!mem->image) return FALSE; + + GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); + GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); } gst_vaapi_video_meta_set_image (mem->meta, mem->image); return TRUE; @@ -157,6 +162,11 @@ ensure_surface (GstVaapiVideoMemory * mem) return FALSE; gst_vaapi_video_meta_set_surface_proxy (mem->meta, mem->proxy); } + + GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); + GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); } mem->surface = GST_VAAPI_SURFACE_PROXY_SURFACE (mem->proxy); return mem->surface != NULL; @@ -341,6 +351,9 @@ gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem) gst_vaapi_video_pool_put_object (allocator->image_pool, mem->image); mem->image = NULL; } + + GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); } void @@ -351,6 +364,9 @@ gst_vaapi_video_memory_reset_surface (GstVaapiVideoMemory * mem) gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); if (mem->meta) gst_vaapi_video_meta_set_surface_proxy (mem->meta, NULL); + + GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); } gboolean From cf352336b38d4c86b5375ed69bfd975978ac1714 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 24 Nov 2014 13:20:33 +0100 Subject: [PATCH 1804/3781] plugins: further fixes to the new "current" storage tracker. The ensure_surface() and ensure_image() functions shall only relate to the underlying backing store. The actual current flags are to be updated only through ensure_{surface,image}_is_current() or very other particular cases in GstMemory hooks. --- gst/vaapi/gstvaapivideomemory.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 7ab18cb49c..454851a359 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -86,11 +86,6 @@ ensure_image (GstVaapiVideoMemory * mem) mem->image = gst_vaapi_video_pool_get_object (allocator->image_pool); if (!mem->image) return FALSE; - - GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, - GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); - GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, - GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); } gst_vaapi_video_meta_set_image (mem->meta, mem->image); return TRUE; @@ -162,11 +157,6 @@ ensure_surface (GstVaapiVideoMemory * mem) return FALSE; gst_vaapi_video_meta_set_surface_proxy (mem->meta, mem->proxy); } - - GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, - GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); - GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, - GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); } mem->surface = GST_VAAPI_SURFACE_PROXY_SURFACE (mem->proxy); return mem->surface != NULL; @@ -180,7 +170,9 @@ ensure_surface_is_current (GstVaapiVideoMemory * mem) if (!GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET (mem, GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT)) { - if (!gst_vaapi_surface_put_image (mem->surface, mem->image)) + if (GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT) + && !gst_vaapi_surface_put_image (mem->surface, mem->image)) return FALSE; GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, @@ -352,6 +344,7 @@ gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem) mem->image = NULL; } + /* Don't synchronize to surface, this shall have happened during unmaps */ GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); } From 9c888b8b8eed57acbd92f8fc840e3e6cac1b1ea0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 24 Nov 2014 14:10:11 +0100 Subject: [PATCH 1805/3781] plugins: re-indent all video processing related source code. --- gst/vaapi/gstvaapipostproc.c | 2588 +++++++++++++++++----------------- gst/vaapi/gstvaapipostproc.h | 168 ++- gst/vaapi/gstvaapiuploader.c | 701 +++++---- gst/vaapi/gstvaapiuploader.h | 84 +- 4 files changed, 1747 insertions(+), 1794 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 2dd9ce3dfd..fb014d16f5 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -43,7 +43,7 @@ #define GST_PLUGIN_NAME "vaapipostproc" #define GST_PLUGIN_DESC "A video postprocessing filter" -GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapipostproc); +GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapipostproc); #define GST_CAT_DEFAULT gst_debug_vaapipostproc #if GST_CHECK_VERSION(1,1,0) @@ -56,73 +56,77 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapipostproc); #endif /* Default templates */ +/* *INDENT-OFF* */ static const char gst_vaapipostproc_sink_caps_str[] = - GST_VAAPIPOSTPROC_SURFACE_CAPS ", " - GST_CAPS_INTERLACED_MODES "; " + GST_VAAPIPOSTPROC_SURFACE_CAPS ", " + GST_CAPS_INTERLACED_MODES "; " #if GST_CHECK_VERSION(1,0,0) - GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) ", " + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " #else - "video/x-raw-yuv, " - "width = " GST_VIDEO_SIZE_RANGE ", " - "height = " GST_VIDEO_SIZE_RANGE ", " - "framerate = " GST_VIDEO_FPS_RANGE ", " + "video/x-raw-yuv, " + "width = " GST_VIDEO_SIZE_RANGE ", " + "height = " GST_VIDEO_SIZE_RANGE ", " + "framerate = " GST_VIDEO_FPS_RANGE ", " #endif - GST_CAPS_INTERLACED_MODES; + GST_CAPS_INTERLACED_MODES; +/* *INDENT-ON* */ +/* *INDENT-OFF* */ static const char gst_vaapipostproc_src_caps_str[] = - GST_VAAPIPOSTPROC_SURFACE_CAPS ", " - GST_CAPS_INTERLACED_FALSE "; " + GST_VAAPIPOSTPROC_SURFACE_CAPS ", " + GST_CAPS_INTERLACED_FALSE "; " #if GST_CHECK_VERSION(1,1,0) - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA") ", " - GST_CAPS_INTERLACED_FALSE "; " + GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA") ", " + GST_CAPS_INTERLACED_FALSE "; " #endif #if GST_CHECK_VERSION(1,0,0) - GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) ", " + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " #else - "video/x-raw-yuv, " - "width = " GST_VIDEO_SIZE_RANGE ", " - "height = " GST_VIDEO_SIZE_RANGE ", " - "framerate = " GST_VIDEO_FPS_RANGE ", " + "video/x-raw-yuv, " + "width = " GST_VIDEO_SIZE_RANGE ", " + "height = " GST_VIDEO_SIZE_RANGE ", " + "framerate = " GST_VIDEO_FPS_RANGE ", " #endif - GST_CAPS_INTERLACED_FALSE; + GST_CAPS_INTERLACED_FALSE; +/* *INDENT-ON* */ +/* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapipostproc_sink_factory = - GST_STATIC_PAD_TEMPLATE( - "sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS(gst_vaapipostproc_sink_caps_str)); + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapipostproc_sink_caps_str)); +/* *INDENT-ON* */ +/* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapipostproc_src_factory = - GST_STATIC_PAD_TEMPLATE( - "src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS(gst_vaapipostproc_src_caps_str)); + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapipostproc_src_caps_str)); +/* *INDENT-ON* */ -G_DEFINE_TYPE_WITH_CODE( - GstVaapiPostproc, - gst_vaapipostproc, - GST_TYPE_BASE_TRANSFORM, - GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) +G_DEFINE_TYPE_WITH_CODE (GstVaapiPostproc, gst_vaapipostproc, + GST_TYPE_BASE_TRANSFORM, GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES); -enum { - PROP_0, +enum +{ + PROP_0, - PROP_FORMAT, - PROP_WIDTH, - PROP_HEIGHT, - PROP_FORCE_ASPECT_RATIO, - PROP_DEINTERLACE_MODE, - PROP_DEINTERLACE_METHOD, - PROP_DENOISE, - PROP_SHARPEN, - PROP_HUE, - PROP_SATURATION, - PROP_BRIGHTNESS, - PROP_CONTRAST, - PROP_SCALE_METHOD, + PROP_FORMAT, + PROP_WIDTH, + PROP_HEIGHT, + PROP_FORCE_ASPECT_RATIO, + PROP_DEINTERLACE_MODE, + PROP_DEINTERLACE_METHOD, + PROP_DENOISE, + PROP_SHARPEN, + PROP_HUE, + PROP_SATURATION, + PROP_BRIGHTNESS, + PROP_CONTRAST, + PROP_SCALE_METHOD, }; #define DEFAULT_FORMAT GST_VIDEO_FORMAT_ENCODED @@ -133,1102 +137,1090 @@ enum { gst_vaapi_deinterlace_mode_get_type() static GType -gst_vaapi_deinterlace_mode_get_type(void) +gst_vaapi_deinterlace_mode_get_type (void) { - static GType deinterlace_mode_type = 0; + static GType deinterlace_mode_type = 0; - static const GEnumValue mode_types[] = { - { GST_VAAPI_DEINTERLACE_MODE_AUTO, - "Auto detection", "auto" }, - { GST_VAAPI_DEINTERLACE_MODE_INTERLACED, - "Force deinterlacing", "interlaced" }, - { GST_VAAPI_DEINTERLACE_MODE_DISABLED, - "Never deinterlace", "disabled" }, - { 0, NULL, NULL }, - }; + static const GEnumValue mode_types[] = { + {GST_VAAPI_DEINTERLACE_MODE_AUTO, + "Auto detection", "auto"}, + {GST_VAAPI_DEINTERLACE_MODE_INTERLACED, + "Force deinterlacing", "interlaced"}, + {GST_VAAPI_DEINTERLACE_MODE_DISABLED, + "Never deinterlace", "disabled"}, + {0, NULL, NULL}, + }; - if (!deinterlace_mode_type) { - deinterlace_mode_type = - g_enum_register_static("GstVaapiDeinterlaceMode", mode_types); - } - return deinterlace_mode_type; + if (!deinterlace_mode_type) { + deinterlace_mode_type = + g_enum_register_static ("GstVaapiDeinterlaceMode", mode_types); + } + return deinterlace_mode_type; } static void -ds_reset(GstVaapiDeinterlaceState *ds) +ds_reset (GstVaapiDeinterlaceState * ds) { - guint i; + guint i; - for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) - gst_buffer_replace(&ds->buffers[i], NULL); - ds->buffers_index = 0; - ds->num_surfaces = 0; - ds->deint = FALSE; - ds->tff = FALSE; + for (i = 0; i < G_N_ELEMENTS (ds->buffers); i++) + gst_buffer_replace (&ds->buffers[i], NULL); + ds->buffers_index = 0; + ds->num_surfaces = 0; + ds->deint = FALSE; + ds->tff = FALSE; } static void -ds_add_buffer(GstVaapiDeinterlaceState *ds, GstBuffer *buf) +ds_add_buffer (GstVaapiDeinterlaceState * ds, GstBuffer * buf) { - gst_buffer_replace(&ds->buffers[ds->buffers_index], buf); - ds->buffers_index = (ds->buffers_index + 1) % G_N_ELEMENTS(ds->buffers); + gst_buffer_replace (&ds->buffers[ds->buffers_index], buf); + ds->buffers_index = (ds->buffers_index + 1) % G_N_ELEMENTS (ds->buffers); } static inline GstBuffer * -ds_get_buffer(GstVaapiDeinterlaceState *ds, guint index) +ds_get_buffer (GstVaapiDeinterlaceState * ds, guint index) { - /* Note: the index increases towards older buffers. - i.e. buffer at index 0 means the immediately preceding buffer - in the history, buffer at index 1 means the one preceding the - surface at index 0, etc. */ - const guint n = ds->buffers_index + G_N_ELEMENTS(ds->buffers) - index - 1; - return ds->buffers[n % G_N_ELEMENTS(ds->buffers)]; + /* Note: the index increases towards older buffers. + i.e. buffer at index 0 means the immediately preceding buffer + in the history, buffer at index 1 means the one preceding the + surface at index 0, etc. */ + const guint n = ds->buffers_index + G_N_ELEMENTS (ds->buffers) - index - 1; + return ds->buffers[n % G_N_ELEMENTS (ds->buffers)]; } static void -ds_set_surfaces(GstVaapiDeinterlaceState *ds) +ds_set_surfaces (GstVaapiDeinterlaceState * ds) { - GstVaapiVideoMeta *meta; - guint i; + GstVaapiVideoMeta *meta; + guint i; - ds->num_surfaces = 0; - for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) { - GstBuffer * const buf = ds_get_buffer(ds, i); - if (!buf) - break; + ds->num_surfaces = 0; + for (i = 0; i < G_N_ELEMENTS (ds->buffers); i++) { + GstBuffer *const buf = ds_get_buffer (ds, i); + if (!buf) + break; - meta = gst_buffer_get_vaapi_video_meta(buf); - ds->surfaces[ds->num_surfaces++] = - gst_vaapi_video_meta_get_surface(meta); - } + meta = gst_buffer_get_vaapi_video_meta (buf); + ds->surfaces[ds->num_surfaces++] = gst_vaapi_video_meta_get_surface (meta); + } } static GstVaapiFilterOpInfo * -find_filter_op(GPtrArray *filter_ops, GstVaapiFilterOp op) +find_filter_op (GPtrArray * filter_ops, GstVaapiFilterOp op) { - guint i; + guint i; - if (filter_ops) { - for (i = 0; i < filter_ops->len; i++) { - GstVaapiFilterOpInfo * const filter_op = - g_ptr_array_index(filter_ops, i); - if (filter_op->op == op) - return filter_op; - } + if (filter_ops) { + for (i = 0; i < filter_ops->len; i++) { + GstVaapiFilterOpInfo *const filter_op = g_ptr_array_index (filter_ops, i); + if (filter_op->op == op) + return filter_op; } - return NULL; + } + return NULL; } static inline gboolean -gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc) +gst_vaapipostproc_ensure_display (GstVaapiPostproc * postproc) { - return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(postproc)); + return + gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (postproc)); } static gboolean -gst_vaapipostproc_ensure_uploader(GstVaapiPostproc *postproc) +gst_vaapipostproc_ensure_uploader (GstVaapiPostproc * postproc) { - if (!gst_vaapipostproc_ensure_display(postproc)) - return FALSE; - if (!gst_vaapi_plugin_base_ensure_uploader(GST_VAAPI_PLUGIN_BASE(postproc))) - return FALSE; - return TRUE; + if (!gst_vaapipostproc_ensure_display (postproc)) + return FALSE; + if (!gst_vaapi_plugin_base_ensure_uploader (GST_VAAPI_PLUGIN_BASE (postproc))) + return FALSE; + return TRUE; } static gboolean -gst_vaapipostproc_ensure_filter(GstVaapiPostproc *postproc) +gst_vaapipostproc_ensure_filter (GstVaapiPostproc * postproc) { - if (postproc->filter) - return TRUE; - - if (!gst_vaapipostproc_ensure_display(postproc)) - return FALSE; - - postproc->filter = gst_vaapi_filter_new( - GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); - if (!postproc->filter) - return FALSE; + if (postproc->filter) return TRUE; + + if (!gst_vaapipostproc_ensure_display (postproc)) + return FALSE; + + postproc->filter = + gst_vaapi_filter_new (GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc)); + if (!postproc->filter) + return FALSE; + return TRUE; } static gboolean -gst_vaapipostproc_ensure_filter_caps(GstVaapiPostproc *postproc) +gst_vaapipostproc_ensure_filter_caps (GstVaapiPostproc * postproc) { - if (!gst_vaapipostproc_ensure_filter(postproc)) - return FALSE; + if (!gst_vaapipostproc_ensure_filter (postproc)) + return FALSE; - postproc->filter_ops = gst_vaapi_filter_get_operations(postproc->filter); - if (!postproc->filter_ops) - return FALSE; + postproc->filter_ops = gst_vaapi_filter_get_operations (postproc->filter); + if (!postproc->filter_ops) + return FALSE; - postproc->filter_formats = gst_vaapi_filter_get_formats(postproc->filter); - if (!postproc->filter_formats) - return FALSE; - return TRUE; + postproc->filter_formats = gst_vaapi_filter_get_formats (postproc->filter); + if (!postproc->filter_formats) + return FALSE; + return TRUE; } static gboolean -gst_vaapipostproc_create(GstVaapiPostproc *postproc) +gst_vaapipostproc_create (GstVaapiPostproc * postproc) { - if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(postproc))) - return FALSE; - if (!gst_vaapipostproc_ensure_display(postproc)) - return FALSE; - if (!gst_vaapipostproc_ensure_uploader(postproc)) - return FALSE; + if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (postproc))) + return FALSE; + if (!gst_vaapipostproc_ensure_display (postproc)) + return FALSE; + if (!gst_vaapipostproc_ensure_uploader (postproc)) + return FALSE; - postproc->use_vpp = FALSE; - postproc->has_vpp = gst_vaapipostproc_ensure_filter(postproc); - return TRUE; + postproc->use_vpp = FALSE; + postproc->has_vpp = gst_vaapipostproc_ensure_filter (postproc); + return TRUE; } static void -gst_vaapipostproc_destroy_filter(GstVaapiPostproc *postproc) +gst_vaapipostproc_destroy_filter (GstVaapiPostproc * postproc) { - if (postproc->filter_formats) { - g_array_unref(postproc->filter_formats); - postproc->filter_formats = NULL; - } + if (postproc->filter_formats) { + g_array_unref (postproc->filter_formats); + postproc->filter_formats = NULL; + } - if (postproc->filter_ops) { - g_ptr_array_unref(postproc->filter_ops); - postproc->filter_ops = NULL; - } - gst_vaapi_filter_replace(&postproc->filter, NULL); - gst_vaapi_video_pool_replace(&postproc->filter_pool, NULL); - postproc->filter_pool_active = FALSE; + if (postproc->filter_ops) { + g_ptr_array_unref (postproc->filter_ops); + postproc->filter_ops = NULL; + } + gst_vaapi_filter_replace (&postproc->filter, NULL); + gst_vaapi_video_pool_replace (&postproc->filter_pool, NULL); + postproc->filter_pool_active = FALSE; } static void -gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) +gst_vaapipostproc_destroy (GstVaapiPostproc * postproc) { - ds_reset(&postproc->deinterlace_state); - gst_vaapipostproc_destroy_filter(postproc); + ds_reset (&postproc->deinterlace_state); + gst_vaapipostproc_destroy_filter (postproc); - gst_caps_replace(&postproc->allowed_sinkpad_caps, NULL); - gst_caps_replace(&postproc->allowed_srcpad_caps, NULL); - gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(postproc)); + gst_caps_replace (&postproc->allowed_sinkpad_caps, NULL); + gst_caps_replace (&postproc->allowed_srcpad_caps, NULL); + gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (postproc)); } static gboolean -gst_vaapipostproc_start(GstBaseTransform *trans) +gst_vaapipostproc_start (GstBaseTransform * trans) { - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - ds_reset(&postproc->deinterlace_state); - if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(postproc))) - return FALSE; - if (!gst_vaapipostproc_ensure_display(postproc)) - return FALSE; + ds_reset (&postproc->deinterlace_state); + if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (postproc))) + return FALSE; + if (!gst_vaapipostproc_ensure_display (postproc)) + return FALSE; + return TRUE; +} + +static gboolean +gst_vaapipostproc_stop (GstBaseTransform * trans) +{ + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + + ds_reset (&postproc->deinterlace_state); + gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (postproc)); + postproc->filter_pool_active = FALSE; + return TRUE; +} + +static gboolean +should_deinterlace_buffer (GstVaapiPostproc * postproc, GstBuffer * buf) +{ + if (!(postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) || + postproc->deinterlace_mode == GST_VAAPI_DEINTERLACE_MODE_DISABLED) + return FALSE; + + if (postproc->deinterlace_mode == GST_VAAPI_DEINTERLACE_MODE_INTERLACED) return TRUE; -} -static gboolean -gst_vaapipostproc_stop(GstBaseTransform *trans) -{ - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + g_assert (postproc->deinterlace_mode == GST_VAAPI_DEINTERLACE_MODE_AUTO); - ds_reset(&postproc->deinterlace_state); - gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(postproc)); - postproc->filter_pool_active = FALSE; - return TRUE; -} - -static gboolean -should_deinterlace_buffer(GstVaapiPostproc *postproc, GstBuffer *buf) -{ - if (!(postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) || - postproc->deinterlace_mode == GST_VAAPI_DEINTERLACE_MODE_DISABLED) - return FALSE; - - if (postproc->deinterlace_mode == GST_VAAPI_DEINTERLACE_MODE_INTERLACED) - return TRUE; - - g_assert(postproc->deinterlace_mode == GST_VAAPI_DEINTERLACE_MODE_AUTO); - - switch (GST_VIDEO_INFO_INTERLACE_MODE(&postproc->sinkpad_info)) { + switch (GST_VIDEO_INFO_INTERLACE_MODE (&postproc->sinkpad_info)) { case GST_VIDEO_INTERLACE_MODE_INTERLEAVED: - return TRUE; + return TRUE; case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE: - return FALSE; + return FALSE; case GST_VIDEO_INTERLACE_MODE_MIXED: #if GST_CHECK_VERSION(1,0,0) - if (GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_FLAG_INTERLACED)) - return TRUE; + if (GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_FLAG_INTERLACED)) + return TRUE; #else - if (!GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_PROGRESSIVE)) - return TRUE; + if (!GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_PROGRESSIVE)) + return TRUE; #endif - break; + break; default: - GST_ERROR("unhandled \"interlace-mode\", disabling deinterlacing" ); - break; - } - return FALSE; + GST_ERROR ("unhandled \"interlace-mode\", disabling deinterlacing"); + break; + } + return FALSE; } static GstBuffer * -create_output_buffer(GstVaapiPostproc *postproc) +create_output_buffer (GstVaapiPostproc * postproc) { - GstBuffer *outbuf; + GstBuffer *outbuf; #if GST_CHECK_VERSION(1,0,0) - GstBufferPool * const pool = - GST_VAAPI_PLUGIN_BASE(postproc)->srcpad_buffer_pool; - GstFlowReturn ret; + GstBufferPool *const pool = + GST_VAAPI_PLUGIN_BASE (postproc)->srcpad_buffer_pool; + GstFlowReturn ret; - g_return_val_if_fail(pool != NULL, NULL); + g_return_val_if_fail (pool != NULL, NULL); - if (!postproc->filter_pool_active) { - if (!gst_buffer_pool_set_active(pool, TRUE)) - goto error_activate_pool; - postproc->filter_pool_active = TRUE; - } + if (!postproc->filter_pool_active) { + if (!gst_buffer_pool_set_active (pool, TRUE)) + goto error_activate_pool; + postproc->filter_pool_active = TRUE; + } - outbuf = NULL; - ret = gst_buffer_pool_acquire_buffer(pool, &outbuf, NULL); - if (ret != GST_FLOW_OK || !outbuf) - goto error_create_buffer; + outbuf = NULL; + ret = gst_buffer_pool_acquire_buffer (pool, &outbuf, NULL); + if (ret != GST_FLOW_OK || !outbuf) + goto error_create_buffer; #else - /* Create a raw VA video buffer without GstVaapiVideoMeta attached - to it yet, as this will be done next in the transform() hook */ - outbuf = gst_vaapi_video_buffer_new_empty(); - if (!outbuf) - goto error_create_buffer; + /* Create a raw VA video buffer without GstVaapiVideoMeta attached + to it yet, as this will be done next in the transform() hook */ + outbuf = gst_vaapi_video_buffer_new_empty (); + if (!outbuf) + goto error_create_buffer; - gst_buffer_set_caps(outbuf, GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS(postproc)); + gst_buffer_set_caps (outbuf, GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS (postproc)); #endif - return outbuf; + return outbuf; - /* ERRORS */ + /* ERRORS */ #if GST_CHECK_VERSION(1,0,0) error_activate_pool: - { - GST_ERROR("failed to activate output video buffer pool"); - return NULL; - } + { + GST_ERROR ("failed to activate output video buffer pool"); + return NULL; + } #endif error_create_buffer: - { - GST_ERROR("failed to create output video buffer"); - return NULL; - } + { + GST_ERROR ("failed to create output video buffer"); + return NULL; + } } static gboolean -append_output_buffer_metadata(GstVaapiPostproc *postproc, GstBuffer *outbuf, - GstBuffer *inbuf, guint flags) +append_output_buffer_metadata (GstVaapiPostproc * postproc, GstBuffer * outbuf, + GstBuffer * inbuf, guint flags) { - GstVaapiVideoMeta *inbuf_meta, *outbuf_meta; - GstVaapiSurfaceProxy *proxy; + GstVaapiVideoMeta *inbuf_meta, *outbuf_meta; + GstVaapiSurfaceProxy *proxy; - gst_buffer_copy_into(outbuf, inbuf, flags | GST_BUFFER_COPY_FLAGS, 0, -1); + gst_buffer_copy_into (outbuf, inbuf, flags | GST_BUFFER_COPY_FLAGS, 0, -1); - /* GstVideoCropMeta */ + /* GstVideoCropMeta */ #if GST_CHECK_VERSION(1,0,0) - if (!postproc->use_vpp) { - GstVideoCropMeta * const crop_meta = - gst_buffer_get_video_crop_meta(inbuf); - if (crop_meta) { - GstVideoCropMeta * const out_crop_meta = - gst_buffer_add_video_crop_meta(outbuf); - if (out_crop_meta) - *out_crop_meta = *crop_meta; - } + if (!postproc->use_vpp) { + GstVideoCropMeta *const crop_meta = gst_buffer_get_video_crop_meta (inbuf); + if (crop_meta) { + GstVideoCropMeta *const out_crop_meta = + gst_buffer_add_video_crop_meta (outbuf); + if (out_crop_meta) + *out_crop_meta = *crop_meta; } + } #endif - /* GstVaapiVideoMeta */ - inbuf_meta = gst_buffer_get_vaapi_video_meta(inbuf); - g_return_val_if_fail(inbuf_meta != NULL, FALSE); - proxy = gst_vaapi_video_meta_get_surface_proxy(inbuf_meta); + /* GstVaapiVideoMeta */ + inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); + g_return_val_if_fail (inbuf_meta != NULL, FALSE); + proxy = gst_vaapi_video_meta_get_surface_proxy (inbuf_meta); - outbuf_meta = gst_buffer_get_vaapi_video_meta(outbuf); - g_return_val_if_fail(outbuf_meta != NULL, FALSE); - proxy = gst_vaapi_surface_proxy_copy(proxy); - if (!proxy) - return FALSE; + outbuf_meta = gst_buffer_get_vaapi_video_meta (outbuf); + g_return_val_if_fail (outbuf_meta != NULL, FALSE); + proxy = gst_vaapi_surface_proxy_copy (proxy); + if (!proxy) + return FALSE; - gst_vaapi_video_meta_set_surface_proxy(outbuf_meta, proxy); - gst_vaapi_surface_proxy_unref(proxy); - return TRUE; + gst_vaapi_video_meta_set_surface_proxy (outbuf_meta, proxy); + gst_vaapi_surface_proxy_unref (proxy); + return TRUE; } static gboolean -deint_method_is_advanced(GstVaapiDeinterlaceMethod deint_method) +deint_method_is_advanced (GstVaapiDeinterlaceMethod deint_method) { - gboolean is_advanced; + gboolean is_advanced; - switch (deint_method) { + switch (deint_method) { case GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE: case GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED: - is_advanced = TRUE; - break; + is_advanced = TRUE; + break; default: - is_advanced = FALSE; - break; - } - return is_advanced; + is_advanced = FALSE; + break; + } + return is_advanced; } static GstVaapiDeinterlaceMethod -get_next_deint_method(GstVaapiDeinterlaceMethod deint_method) +get_next_deint_method (GstVaapiDeinterlaceMethod deint_method) { - switch (deint_method) { + switch (deint_method) { case GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED: - deint_method = GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE; - break; + deint_method = GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE; + break; default: - /* Default to basic "bob" for all others */ - deint_method = GST_VAAPI_DEINTERLACE_METHOD_BOB; - break; - } - return deint_method; + /* Default to basic "bob" for all others */ + deint_method = GST_VAAPI_DEINTERLACE_METHOD_BOB; + break; + } + return deint_method; } static gboolean -set_best_deint_method(GstVaapiPostproc *postproc, guint flags, - GstVaapiDeinterlaceMethod *deint_method_ptr) +set_best_deint_method (GstVaapiPostproc * postproc, guint flags, + GstVaapiDeinterlaceMethod * deint_method_ptr) { - GstVaapiDeinterlaceMethod deint_method = postproc->deinterlace_method; - gboolean success; + GstVaapiDeinterlaceMethod deint_method = postproc->deinterlace_method; + gboolean success; - for (;;) { - success = gst_vaapi_filter_set_deinterlacing(postproc->filter, - deint_method, flags); - if (success || deint_method == GST_VAAPI_DEINTERLACE_METHOD_BOB) - break; - deint_method = get_next_deint_method(deint_method); - } - *deint_method_ptr = deint_method; - return success; + for (;;) { + success = gst_vaapi_filter_set_deinterlacing (postproc->filter, + deint_method, flags); + if (success || deint_method == GST_VAAPI_DEINTERLACE_METHOD_BOB) + break; + deint_method = get_next_deint_method (deint_method); + } + *deint_method_ptr = deint_method; + return success; } static GstFlowReturn -gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf, - GstBuffer *outbuf) +gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, + GstBuffer * outbuf) { - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); - GstVaapiDeinterlaceState * const ds = &postproc->deinterlace_state; - GstVaapiVideoMeta *inbuf_meta, *outbuf_meta; - GstVaapiSurface *inbuf_surface, *outbuf_surface; - GstVaapiSurfaceProxy *proxy; - GstVaapiFilterStatus status; - GstClockTime timestamp; - GstFlowReturn ret; - GstBuffer *fieldbuf; - GstVaapiDeinterlaceMethod deint_method; - guint flags, deint_flags; - gboolean tff, deint, deint_refs, deint_changed; - GstVaapiRectangle *crop_rect = NULL; + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + GstVaapiDeinterlaceState *const ds = &postproc->deinterlace_state; + GstVaapiVideoMeta *inbuf_meta, *outbuf_meta; + GstVaapiSurface *inbuf_surface, *outbuf_surface; + GstVaapiSurfaceProxy *proxy; + GstVaapiFilterStatus status; + GstClockTime timestamp; + GstFlowReturn ret; + GstBuffer *fieldbuf; + GstVaapiDeinterlaceMethod deint_method; + guint flags, deint_flags; + gboolean tff, deint, deint_refs, deint_changed; + GstVaapiRectangle *crop_rect = NULL; #if GST_CHECK_VERSION(1,0,0) - GstVaapiRectangle tmp_rect; + GstVaapiRectangle tmp_rect; #endif - /* Validate filters */ - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) && - !gst_vaapi_filter_set_format(postproc->filter, postproc->format)) - return GST_FLOW_NOT_SUPPORTED; + /* Validate filters */ + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) && + !gst_vaapi_filter_set_format (postproc->filter, postproc->format)) + return GST_FLOW_NOT_SUPPORTED; - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_DENOISE) && - !gst_vaapi_filter_set_denoising_level(postproc->filter, - postproc->denoise_level)) - return GST_FLOW_NOT_SUPPORTED; + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_DENOISE) && + !gst_vaapi_filter_set_denoising_level (postproc->filter, + postproc->denoise_level)) + return GST_FLOW_NOT_SUPPORTED; - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SHARPEN) && - !gst_vaapi_filter_set_sharpening_level(postproc->filter, - postproc->sharpen_level)) - return GST_FLOW_NOT_SUPPORTED; + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SHARPEN) && + !gst_vaapi_filter_set_sharpening_level (postproc->filter, + postproc->sharpen_level)) + return GST_FLOW_NOT_SUPPORTED; - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_HUE) && - !gst_vaapi_filter_set_hue(postproc->filter, - postproc->hue)) - return GST_FLOW_NOT_SUPPORTED; + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_HUE) && + !gst_vaapi_filter_set_hue (postproc->filter, postproc->hue)) + return GST_FLOW_NOT_SUPPORTED; - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SATURATION) && - !gst_vaapi_filter_set_saturation(postproc->filter, - postproc->saturation)) - return GST_FLOW_NOT_SUPPORTED; + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SATURATION) && + !gst_vaapi_filter_set_saturation (postproc->filter, postproc->saturation)) + return GST_FLOW_NOT_SUPPORTED; - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS) && - !gst_vaapi_filter_set_brightness(postproc->filter, - postproc->brightness)) - return GST_FLOW_NOT_SUPPORTED; + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS) && + !gst_vaapi_filter_set_brightness (postproc->filter, postproc->brightness)) + return GST_FLOW_NOT_SUPPORTED; - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_CONTRAST) && - !gst_vaapi_filter_set_contrast(postproc->filter, - postproc->contrast)) - return GST_FLOW_NOT_SUPPORTED; + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_CONTRAST) && + !gst_vaapi_filter_set_contrast (postproc->filter, postproc->contrast)) + return GST_FLOW_NOT_SUPPORTED; - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SCALE) && - !gst_vaapi_filter_set_scaling(postproc->filter, - postproc->scale_method)) - return GST_FLOW_NOT_SUPPORTED; + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SCALE) && + !gst_vaapi_filter_set_scaling (postproc->filter, postproc->scale_method)) + return GST_FLOW_NOT_SUPPORTED; - inbuf_meta = gst_buffer_get_vaapi_video_meta(inbuf); - if (!inbuf_meta) - goto error_invalid_buffer; - inbuf_surface = gst_vaapi_video_meta_get_surface(inbuf_meta); + inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); + if (!inbuf_meta) + goto error_invalid_buffer; + inbuf_surface = gst_vaapi_video_meta_get_surface (inbuf_meta); #if GST_CHECK_VERSION(1,0,0) - GstVideoCropMeta * const crop_meta = - gst_buffer_get_video_crop_meta(inbuf); - if (crop_meta) { - crop_rect = &tmp_rect; - crop_rect->x = crop_meta->x; - crop_rect->y = crop_meta->y; - crop_rect->width = crop_meta->width; - crop_rect->height = crop_meta->height; - } + GstVideoCropMeta *const crop_meta = gst_buffer_get_video_crop_meta (inbuf); + if (crop_meta) { + crop_rect = &tmp_rect; + crop_rect->x = crop_meta->x; + crop_rect->y = crop_meta->y; + crop_rect->width = crop_meta->width; + crop_rect->height = crop_meta->height; + } #endif - if (!crop_rect) - crop_rect = (GstVaapiRectangle *) - gst_vaapi_video_meta_get_render_rect(inbuf_meta); + if (!crop_rect) + crop_rect = (GstVaapiRectangle *) + gst_vaapi_video_meta_get_render_rect (inbuf_meta); - timestamp = GST_BUFFER_TIMESTAMP(inbuf); - tff = GST_BUFFER_FLAG_IS_SET(inbuf, GST_VIDEO_BUFFER_FLAG_TFF); - deint = should_deinterlace_buffer(postproc, inbuf); + timestamp = GST_BUFFER_TIMESTAMP (inbuf); + tff = GST_BUFFER_FLAG_IS_SET (inbuf, GST_VIDEO_BUFFER_FLAG_TFF); + deint = should_deinterlace_buffer (postproc, inbuf); - /* Drop references if deinterlacing conditions changed */ - deint_changed = deint != ds->deint; - if (deint_changed || (ds->num_surfaces > 0 && tff != ds->tff)) - ds_reset(ds); + /* Drop references if deinterlacing conditions changed */ + deint_changed = deint != ds->deint; + if (deint_changed || (ds->num_surfaces > 0 && tff != ds->tff)) + ds_reset (ds); - deint_method = postproc->deinterlace_method; - deint_refs = deint_method_is_advanced(deint_method); - if (deint_refs && 0) { - GstBuffer * const prev_buf = ds_get_buffer(ds, 0); - GstClockTime prev_pts, pts = GST_BUFFER_TIMESTAMP(inbuf); - /* Reset deinterlacing state when there is a discontinuity */ - if (prev_buf && (prev_pts = GST_BUFFER_TIMESTAMP(prev_buf)) != pts) { - const GstClockTimeDiff pts_diff = GST_CLOCK_DIFF(prev_pts, pts); - if (pts_diff < 0 || (postproc->field_duration > 0 && - pts_diff >= postproc->field_duration * 3 - 1)) - ds_reset(ds); - } + deint_method = postproc->deinterlace_method; + deint_refs = deint_method_is_advanced (deint_method); + if (deint_refs && 0) { + GstBuffer *const prev_buf = ds_get_buffer (ds, 0); + GstClockTime prev_pts, pts = GST_BUFFER_TIMESTAMP (inbuf); + /* Reset deinterlacing state when there is a discontinuity */ + if (prev_buf && (prev_pts = GST_BUFFER_TIMESTAMP (prev_buf)) != pts) { + const GstClockTimeDiff pts_diff = GST_CLOCK_DIFF (prev_pts, pts); + if (pts_diff < 0 || (postproc->field_duration > 0 && + pts_diff >= postproc->field_duration * 3 - 1)) + ds_reset (ds); } + } - ds->deint = deint; - ds->tff = tff; + ds->deint = deint; + ds->tff = tff; - flags = gst_vaapi_video_meta_get_render_flags(inbuf_meta) & - ~GST_VAAPI_PICTURE_STRUCTURE_MASK; + flags = gst_vaapi_video_meta_get_render_flags (inbuf_meta) & + ~GST_VAAPI_PICTURE_STRUCTURE_MASK; - /* First field */ - if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) { - fieldbuf = create_output_buffer(postproc); - if (!fieldbuf) - goto error_create_buffer; + /* First field */ + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) { + fieldbuf = create_output_buffer (postproc); + if (!fieldbuf) + goto error_create_buffer; - outbuf_meta = gst_buffer_get_vaapi_video_meta(fieldbuf); - if (!outbuf_meta) - goto error_create_meta; - - proxy = gst_vaapi_surface_proxy_new_from_pool( - GST_VAAPI_SURFACE_POOL(postproc->filter_pool)); - if (!proxy) - goto error_create_proxy; - gst_vaapi_video_meta_set_surface_proxy(outbuf_meta, proxy); - gst_vaapi_surface_proxy_unref(proxy); - - if (deint) { - deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD : 0); - if (tff) - deint_flags |= GST_VAAPI_DEINTERLACE_FLAG_TFF; - if (!set_best_deint_method(postproc, deint_flags, &deint_method)) - goto error_op_deinterlace; - - if (deint_method != postproc->deinterlace_method) { - GST_DEBUG("unsupported deinterlace-method %u. Using %u instead", - postproc->deinterlace_method, deint_method); - postproc->deinterlace_method = deint_method; - deint_refs = deint_method_is_advanced(deint_method); - } - - if (deint_refs) { - ds_set_surfaces(ds); - if (!gst_vaapi_filter_set_deinterlacing_references( - postproc->filter, ds->surfaces, ds->num_surfaces, - NULL, 0)) - goto error_op_deinterlace; - } - } - else if (deint_changed) { - // Reset internal filter to non-deinterlacing mode - deint_method = GST_VAAPI_DEINTERLACE_METHOD_NONE; - if (!gst_vaapi_filter_set_deinterlacing(postproc->filter, - deint_method, 0)) - goto error_op_deinterlace; - } - - outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); - gst_vaapi_filter_set_cropping_rectangle(postproc->filter, crop_rect); - status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, - outbuf_surface, flags); - if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) - goto error_process_vpp; - - GST_BUFFER_TIMESTAMP(fieldbuf) = timestamp; - GST_BUFFER_DURATION(fieldbuf) = postproc->field_duration; - ret = gst_pad_push(trans->srcpad, fieldbuf); - if (ret != GST_FLOW_OK) - goto error_push_buffer; - } - fieldbuf = NULL; - - /* Second field */ - outbuf_meta = gst_buffer_get_vaapi_video_meta(outbuf); + outbuf_meta = gst_buffer_get_vaapi_video_meta (fieldbuf); if (!outbuf_meta) - goto error_create_meta; + goto error_create_meta; - proxy = gst_vaapi_surface_proxy_new_from_pool( - GST_VAAPI_SURFACE_POOL(postproc->filter_pool)); + proxy = + gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL + (postproc->filter_pool)); if (!proxy) - goto error_create_proxy; - gst_vaapi_video_meta_set_surface_proxy(outbuf_meta, proxy); - gst_vaapi_surface_proxy_unref(proxy); + goto error_create_proxy; + gst_vaapi_video_meta_set_surface_proxy (outbuf_meta, proxy); + gst_vaapi_surface_proxy_unref (proxy); if (deint) { - deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD); - if (tff) - deint_flags |= GST_VAAPI_DEINTERLACE_FLAG_TFF; - if (!gst_vaapi_filter_set_deinterlacing(postproc->filter, - deint_method, deint_flags)) - goto error_op_deinterlace; - - if (deint_refs && !gst_vaapi_filter_set_deinterlacing_references( - postproc->filter, ds->surfaces, ds->num_surfaces, NULL, 0)) - goto error_op_deinterlace; - } - else if (deint_changed && !gst_vaapi_filter_set_deinterlacing( - postproc->filter, deint_method, 0)) + deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD : 0); + if (tff) + deint_flags |= GST_VAAPI_DEINTERLACE_FLAG_TFF; + if (!set_best_deint_method (postproc, deint_flags, &deint_method)) goto error_op_deinterlace; - outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta); - gst_vaapi_filter_set_cropping_rectangle(postproc->filter, crop_rect); - status = gst_vaapi_filter_process(postproc->filter, inbuf_surface, + if (deint_method != postproc->deinterlace_method) { + GST_DEBUG ("unsupported deinterlace-method %u. Using %u instead", + postproc->deinterlace_method, deint_method); + postproc->deinterlace_method = deint_method; + deint_refs = deint_method_is_advanced (deint_method); + } + + if (deint_refs) { + ds_set_surfaces (ds); + if (!gst_vaapi_filter_set_deinterlacing_references (postproc->filter, + ds->surfaces, ds->num_surfaces, NULL, 0)) + goto error_op_deinterlace; + } + } else if (deint_changed) { + // Reset internal filter to non-deinterlacing mode + deint_method = GST_VAAPI_DEINTERLACE_METHOD_NONE; + if (!gst_vaapi_filter_set_deinterlacing (postproc->filter, + deint_method, 0)) + goto error_op_deinterlace; + } + + outbuf_surface = gst_vaapi_video_meta_get_surface (outbuf_meta); + gst_vaapi_filter_set_cropping_rectangle (postproc->filter, crop_rect); + status = gst_vaapi_filter_process (postproc->filter, inbuf_surface, outbuf_surface, flags); if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) - goto error_process_vpp; + goto error_process_vpp; - if (!(postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE)) - gst_buffer_copy_into(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); - else { - GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration; - GST_BUFFER_DURATION(outbuf) = postproc->field_duration; - } - - if (deint && deint_refs) - ds_add_buffer(ds, inbuf); - postproc->use_vpp = TRUE; - return GST_FLOW_OK; - - /* ERRORS */ -error_invalid_buffer: - { - GST_ERROR("failed to validate source buffer"); - return GST_FLOW_ERROR; - } -error_create_buffer: - { - GST_ERROR("failed to create output buffer"); - return GST_FLOW_ERROR; - } -error_create_meta: - { - GST_ERROR("failed to create new output buffer meta"); - gst_buffer_replace(&fieldbuf, NULL); - return GST_FLOW_ERROR; - } -error_create_proxy: - { - GST_ERROR("failed to create surface proxy from pool"); - gst_buffer_replace(&fieldbuf, NULL); - return GST_FLOW_ERROR; - } -error_op_deinterlace: - { - GST_ERROR("failed to apply deinterlacing filter"); - gst_buffer_replace(&fieldbuf, NULL); - return GST_FLOW_NOT_SUPPORTED; - } -error_process_vpp: - { - GST_ERROR("failed to apply VPP filters (error %d)", status); - gst_buffer_replace(&fieldbuf, NULL); - return GST_FLOW_ERROR; - } -error_push_buffer: - { - if (ret != GST_FLOW_FLUSHING) - GST_ERROR("failed to push output buffer to video sink"); - return GST_FLOW_ERROR; - } -} - -static GstFlowReturn -gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf, - GstBuffer *outbuf) -{ - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); - GstVaapiVideoMeta *meta; - GstClockTime timestamp; - GstFlowReturn ret; - GstBuffer *fieldbuf; - guint fieldbuf_flags, outbuf_flags, flags; - gboolean tff, deint; - - meta = gst_buffer_get_vaapi_video_meta(inbuf); - if (!meta) - goto error_invalid_buffer; - - timestamp = GST_BUFFER_TIMESTAMP(inbuf); - tff = GST_BUFFER_FLAG_IS_SET(inbuf, GST_VIDEO_BUFFER_FLAG_TFF); - deint = should_deinterlace_buffer(postproc, inbuf); - - flags = gst_vaapi_video_meta_get_render_flags(meta) & - ~GST_VAAPI_PICTURE_STRUCTURE_MASK; - - /* First field */ - fieldbuf = create_output_buffer(postproc); - if (!fieldbuf) - goto error_create_buffer; - append_output_buffer_metadata(postproc, fieldbuf, inbuf, 0); - - meta = gst_buffer_get_vaapi_video_meta(fieldbuf); - fieldbuf_flags = flags; - fieldbuf_flags |= deint ? ( - tff ? - GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) : - GST_VAAPI_PICTURE_STRUCTURE_FRAME; - gst_vaapi_video_meta_set_render_flags(meta, fieldbuf_flags); - - GST_BUFFER_TIMESTAMP(fieldbuf) = timestamp; - GST_BUFFER_DURATION(fieldbuf) = postproc->field_duration; - ret = gst_pad_push(trans->srcpad, fieldbuf); + GST_BUFFER_TIMESTAMP (fieldbuf) = timestamp; + GST_BUFFER_DURATION (fieldbuf) = postproc->field_duration; + ret = gst_pad_push (trans->srcpad, fieldbuf); if (ret != GST_FLOW_OK) - goto error_push_buffer; + goto error_push_buffer; + } + fieldbuf = NULL; - /* Second field */ - append_output_buffer_metadata(postproc, outbuf, inbuf, 0); + /* Second field */ + outbuf_meta = gst_buffer_get_vaapi_video_meta (outbuf); + if (!outbuf_meta) + goto error_create_meta; - meta = gst_buffer_get_vaapi_video_meta(outbuf); - outbuf_flags = flags; - outbuf_flags |= deint ? ( - tff ? - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD : - GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) : - GST_VAAPI_PICTURE_STRUCTURE_FRAME; - gst_vaapi_video_meta_set_render_flags(meta, outbuf_flags); + proxy = + gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL + (postproc->filter_pool)); + if (!proxy) + goto error_create_proxy; + gst_vaapi_video_meta_set_surface_proxy (outbuf_meta, proxy); + gst_vaapi_surface_proxy_unref (proxy); - GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration; - GST_BUFFER_DURATION(outbuf) = postproc->field_duration; - return GST_FLOW_OK; + if (deint) { + deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD); + if (tff) + deint_flags |= GST_VAAPI_DEINTERLACE_FLAG_TFF; + if (!gst_vaapi_filter_set_deinterlacing (postproc->filter, + deint_method, deint_flags)) + goto error_op_deinterlace; - /* ERRORS */ + if (deint_refs + && !gst_vaapi_filter_set_deinterlacing_references (postproc->filter, + ds->surfaces, ds->num_surfaces, NULL, 0)) + goto error_op_deinterlace; + } else if (deint_changed + && !gst_vaapi_filter_set_deinterlacing (postproc->filter, deint_method, + 0)) + goto error_op_deinterlace; + + outbuf_surface = gst_vaapi_video_meta_get_surface (outbuf_meta); + gst_vaapi_filter_set_cropping_rectangle (postproc->filter, crop_rect); + status = gst_vaapi_filter_process (postproc->filter, inbuf_surface, + outbuf_surface, flags); + if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) + goto error_process_vpp; + + if (!(postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE)) + gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); + else { + GST_BUFFER_TIMESTAMP (outbuf) = timestamp + postproc->field_duration; + GST_BUFFER_DURATION (outbuf) = postproc->field_duration; + } + + if (deint && deint_refs) + ds_add_buffer (ds, inbuf); + postproc->use_vpp = TRUE; + return GST_FLOW_OK; + + /* ERRORS */ error_invalid_buffer: - { - GST_ERROR("failed to validate source buffer"); - return GST_FLOW_ERROR; - } + { + GST_ERROR ("failed to validate source buffer"); + return GST_FLOW_ERROR; + } error_create_buffer: - { - GST_ERROR("failed to create output buffer"); - return GST_FLOW_EOS; - } + { + GST_ERROR ("failed to create output buffer"); + return GST_FLOW_ERROR; + } +error_create_meta: + { + GST_ERROR ("failed to create new output buffer meta"); + gst_buffer_replace (&fieldbuf, NULL); + return GST_FLOW_ERROR; + } +error_create_proxy: + { + GST_ERROR ("failed to create surface proxy from pool"); + gst_buffer_replace (&fieldbuf, NULL); + return GST_FLOW_ERROR; + } +error_op_deinterlace: + { + GST_ERROR ("failed to apply deinterlacing filter"); + gst_buffer_replace (&fieldbuf, NULL); + return GST_FLOW_NOT_SUPPORTED; + } +error_process_vpp: + { + GST_ERROR ("failed to apply VPP filters (error %d)", status); + gst_buffer_replace (&fieldbuf, NULL); + return GST_FLOW_ERROR; + } error_push_buffer: - { - if (ret != GST_FLOW_FLUSHING) - GST_ERROR("failed to push output buffer to video sink"); - return GST_FLOW_EOS; - } + { + if (ret != GST_FLOW_FLUSHING) + GST_ERROR ("failed to push output buffer to video sink"); + return GST_FLOW_ERROR; + } } static GstFlowReturn -gst_vaapipostproc_passthrough(GstBaseTransform *trans, GstBuffer *inbuf, - GstBuffer *outbuf) +gst_vaapipostproc_process (GstBaseTransform * trans, GstBuffer * inbuf, + GstBuffer * outbuf) { - GstVaapiVideoMeta *meta; + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + GstVaapiVideoMeta *meta; + GstClockTime timestamp; + GstFlowReturn ret; + GstBuffer *fieldbuf; + guint fieldbuf_flags, outbuf_flags, flags; + gboolean tff, deint; - /* No video processing needed, simply copy buffer metadata */ - meta = gst_buffer_get_vaapi_video_meta(inbuf); - if (!meta) - goto error_invalid_buffer; + meta = gst_buffer_get_vaapi_video_meta (inbuf); + if (!meta) + goto error_invalid_buffer; - append_output_buffer_metadata(GST_VAAPIPOSTPROC(trans), outbuf, inbuf, - GST_BUFFER_COPY_TIMESTAMPS); - return GST_FLOW_OK; + timestamp = GST_BUFFER_TIMESTAMP (inbuf); + tff = GST_BUFFER_FLAG_IS_SET (inbuf, GST_VIDEO_BUFFER_FLAG_TFF); + deint = should_deinterlace_buffer (postproc, inbuf); - /* ERRORS */ + flags = gst_vaapi_video_meta_get_render_flags (meta) & + ~GST_VAAPI_PICTURE_STRUCTURE_MASK; + + /* First field */ + fieldbuf = create_output_buffer (postproc); + if (!fieldbuf) + goto error_create_buffer; + append_output_buffer_metadata (postproc, fieldbuf, inbuf, 0); + + meta = gst_buffer_get_vaapi_video_meta (fieldbuf); + fieldbuf_flags = flags; + fieldbuf_flags |= deint ? (tff ? + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) : + GST_VAAPI_PICTURE_STRUCTURE_FRAME; + gst_vaapi_video_meta_set_render_flags (meta, fieldbuf_flags); + + GST_BUFFER_TIMESTAMP (fieldbuf) = timestamp; + GST_BUFFER_DURATION (fieldbuf) = postproc->field_duration; + ret = gst_pad_push (trans->srcpad, fieldbuf); + if (ret != GST_FLOW_OK) + goto error_push_buffer; + + /* Second field */ + append_output_buffer_metadata (postproc, outbuf, inbuf, 0); + + meta = gst_buffer_get_vaapi_video_meta (outbuf); + outbuf_flags = flags; + outbuf_flags |= deint ? (tff ? + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD : + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) : + GST_VAAPI_PICTURE_STRUCTURE_FRAME; + gst_vaapi_video_meta_set_render_flags (meta, outbuf_flags); + + GST_BUFFER_TIMESTAMP (outbuf) = timestamp + postproc->field_duration; + GST_BUFFER_DURATION (outbuf) = postproc->field_duration; + return GST_FLOW_OK; + + /* ERRORS */ error_invalid_buffer: - { - GST_ERROR("failed to validate source buffer"); - return GST_FLOW_ERROR; - } + { + GST_ERROR ("failed to validate source buffer"); + return GST_FLOW_ERROR; + } +error_create_buffer: + { + GST_ERROR ("failed to create output buffer"); + return GST_FLOW_EOS; + } +error_push_buffer: + { + if (ret != GST_FLOW_FLUSHING) + GST_ERROR ("failed to push output buffer to video sink"); + return GST_FLOW_EOS; + } +} + +static GstFlowReturn +gst_vaapipostproc_passthrough (GstBaseTransform * trans, GstBuffer * inbuf, + GstBuffer * outbuf) +{ + GstVaapiVideoMeta *meta; + + /* No video processing needed, simply copy buffer metadata */ + meta = gst_buffer_get_vaapi_video_meta (inbuf); + if (!meta) + goto error_invalid_buffer; + + append_output_buffer_metadata (GST_VAAPIPOSTPROC (trans), outbuf, inbuf, + GST_BUFFER_COPY_TIMESTAMPS); + return GST_FLOW_OK; + + /* ERRORS */ +error_invalid_buffer: + { + GST_ERROR ("failed to validate source buffer"); + return GST_FLOW_ERROR; + } } static gboolean -is_deinterlace_enabled(GstVaapiPostproc *postproc, GstVideoInfo *vip) +is_deinterlace_enabled (GstVaapiPostproc * postproc, GstVideoInfo * vip) { - gboolean deinterlace; + gboolean deinterlace; - switch (postproc->deinterlace_mode) { + switch (postproc->deinterlace_mode) { case GST_VAAPI_DEINTERLACE_MODE_AUTO: - deinterlace = GST_VIDEO_INFO_IS_INTERLACED(vip); - break; + deinterlace = GST_VIDEO_INFO_IS_INTERLACED (vip); + break; case GST_VAAPI_DEINTERLACE_MODE_INTERLACED: - deinterlace = TRUE; - break; + deinterlace = TRUE; + break; default: - deinterlace = FALSE; - break; - } - return deinterlace; + deinterlace = FALSE; + break; + } + return deinterlace; } static gboolean -video_info_changed(GstVideoInfo *old_vip, GstVideoInfo *new_vip) +video_info_changed (GstVideoInfo * old_vip, GstVideoInfo * new_vip) { - if (GST_VIDEO_INFO_FORMAT(old_vip) != GST_VIDEO_INFO_FORMAT(new_vip)) - return TRUE; - if (GST_VIDEO_INFO_INTERLACE_MODE(old_vip) != - GST_VIDEO_INFO_INTERLACE_MODE(new_vip)) - return TRUE; - if (GST_VIDEO_INFO_WIDTH(old_vip) != GST_VIDEO_INFO_WIDTH(new_vip)) - return TRUE; - if (GST_VIDEO_INFO_HEIGHT(old_vip) != GST_VIDEO_INFO_HEIGHT(new_vip)) - return TRUE; + if (GST_VIDEO_INFO_FORMAT (old_vip) != GST_VIDEO_INFO_FORMAT (new_vip)) + return TRUE; + if (GST_VIDEO_INFO_INTERLACE_MODE (old_vip) != + GST_VIDEO_INFO_INTERLACE_MODE (new_vip)) + return TRUE; + if (GST_VIDEO_INFO_WIDTH (old_vip) != GST_VIDEO_INFO_WIDTH (new_vip)) + return TRUE; + if (GST_VIDEO_INFO_HEIGHT (old_vip) != GST_VIDEO_INFO_HEIGHT (new_vip)) + return TRUE; + return FALSE; +} + +static gboolean +gst_vaapipostproc_update_sink_caps (GstVaapiPostproc * postproc, GstCaps * caps, + gboolean * caps_changed_ptr) +{ + GstVideoInfo vi; + gboolean deinterlace; + + if (!gst_video_info_from_caps (&vi, caps)) return FALSE; + + if (video_info_changed (&vi, &postproc->sinkpad_info)) + postproc->sinkpad_info = vi, *caps_changed_ptr = TRUE; + + deinterlace = is_deinterlace_enabled (postproc, &vi); + if (deinterlace) + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_DEINTERLACE; + postproc->field_duration = GST_VIDEO_INFO_FPS_N (&vi) > 0 ? + gst_util_uint64_scale (GST_SECOND, GST_VIDEO_INFO_FPS_D (&vi), + (1 + deinterlace) * GST_VIDEO_INFO_FPS_N (&vi)) : 0; + + postproc->get_va_surfaces = gst_caps_has_vaapi_surface (caps); + return TRUE; } static gboolean -gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps, - gboolean *caps_changed_ptr) +gst_vaapipostproc_update_src_caps (GstVaapiPostproc * postproc, GstCaps * caps, + gboolean * caps_changed_ptr) { - GstVideoInfo vi; - gboolean deinterlace; + GstVideoInfo vi; - if (!gst_video_info_from_caps(&vi, caps)) - return FALSE; + if (!gst_video_info_from_caps (&vi, caps)) + return FALSE; - if (video_info_changed(&vi, &postproc->sinkpad_info)) - postproc->sinkpad_info = vi, *caps_changed_ptr = TRUE; + if (video_info_changed (&vi, &postproc->srcpad_info)) + postproc->srcpad_info = vi, *caps_changed_ptr = TRUE; - deinterlace = is_deinterlace_enabled(postproc, &vi); - if (deinterlace) - postproc->flags |= GST_VAAPI_POSTPROC_FLAG_DEINTERLACE; - postproc->field_duration = GST_VIDEO_INFO_FPS_N(&vi) > 0 ? - gst_util_uint64_scale(GST_SECOND, GST_VIDEO_INFO_FPS_D(&vi), - (1 + deinterlace) * GST_VIDEO_INFO_FPS_N(&vi)) : 0; + if (postproc->format != GST_VIDEO_INFO_FORMAT (&postproc->sinkpad_info) && + postproc->format != DEFAULT_FORMAT) + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_FORMAT; - postproc->get_va_surfaces = gst_caps_has_vaapi_surface(caps); - return TRUE; + if ((postproc->width || postproc->height) && + postproc->width != GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info) && + postproc->height != GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info)) + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SIZE; + return TRUE; } static gboolean -gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps, - gboolean *caps_changed_ptr) +ensure_allowed_sinkpad_caps (GstVaapiPostproc * postproc) { - GstVideoInfo vi; + GstCaps *out_caps, *raw_caps; - if (!gst_video_info_from_caps(&vi, caps)) - return FALSE; - - if (video_info_changed(&vi, &postproc->srcpad_info)) - postproc->srcpad_info = vi, *caps_changed_ptr = TRUE; - - if (postproc->format != GST_VIDEO_INFO_FORMAT(&postproc->sinkpad_info) && - postproc->format != DEFAULT_FORMAT) - postproc->flags |= GST_VAAPI_POSTPROC_FLAG_FORMAT; - - if ((postproc->width || postproc->height) && - postproc->width != GST_VIDEO_INFO_WIDTH(&postproc->sinkpad_info) && - postproc->height != GST_VIDEO_INFO_HEIGHT(&postproc->sinkpad_info)) - postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SIZE; + if (postproc->allowed_sinkpad_caps) return TRUE; -} -static gboolean -ensure_allowed_sinkpad_caps(GstVaapiPostproc *postproc) -{ - GstCaps *out_caps, *raw_caps; + /* Create VA caps */ + out_caps = gst_caps_from_string (GST_VAAPIPOSTPROC_SURFACE_CAPS ", " + GST_CAPS_INTERLACED_MODES); + if (!out_caps) { + GST_ERROR ("failed to create VA sink caps"); + return FALSE; + } - if (postproc->allowed_sinkpad_caps) - return TRUE; + /* Append raw video caps */ + if (gst_vaapipostproc_ensure_uploader (postproc)) { + raw_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS (postproc); + if (raw_caps) { + out_caps = gst_caps_make_writable (out_caps); + gst_caps_append (out_caps, gst_caps_copy (raw_caps)); + } else + GST_WARNING ("failed to create YUV sink caps"); + } + postproc->allowed_sinkpad_caps = out_caps; - /* Create VA caps */ - out_caps = gst_caps_from_string(GST_VAAPIPOSTPROC_SURFACE_CAPS ", " - GST_CAPS_INTERLACED_MODES); - if (!out_caps) { - GST_ERROR("failed to create VA sink caps"); - return FALSE; - } - - /* Append raw video caps */ - if (gst_vaapipostproc_ensure_uploader(postproc)) { - raw_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(postproc); - if (raw_caps) { - out_caps = gst_caps_make_writable(out_caps); - gst_caps_append(out_caps, gst_caps_copy(raw_caps)); - } - else - GST_WARNING("failed to create YUV sink caps"); - } - postproc->allowed_sinkpad_caps = out_caps; - - /* XXX: append VA/VPP filters */ - return TRUE; + /* XXX: append VA/VPP filters */ + return TRUE; } /* Fixup output caps so that to reflect the supported set of pixel formats */ static GstCaps * -expand_allowed_srcpad_caps(GstVaapiPostproc *postproc, GstCaps *caps) +expand_allowed_srcpad_caps (GstVaapiPostproc * postproc, GstCaps * caps) { - GValue value = G_VALUE_INIT, v_format = G_VALUE_INIT; - guint i, num_structures; - gboolean had_filter; + GValue value = G_VALUE_INIT, v_format = G_VALUE_INIT; + guint i, num_structures; + gboolean had_filter; - had_filter = postproc->filter != NULL; - if (!had_filter && !gst_vaapipostproc_ensure_filter(postproc)) - goto cleanup; - if (!gst_vaapipostproc_ensure_filter_caps(postproc)) - goto cleanup; + had_filter = postproc->filter != NULL; + if (!had_filter && !gst_vaapipostproc_ensure_filter (postproc)) + goto cleanup; + if (!gst_vaapipostproc_ensure_filter_caps (postproc)) + goto cleanup; - /* Reset "format" field for each structure */ - if (!gst_vaapi_value_set_format_list(&value, postproc->filter_formats)) - goto cleanup; - if (gst_vaapi_value_set_format(&v_format, GST_VIDEO_FORMAT_ENCODED)) { - gst_value_list_prepend_value(&value, &v_format); - g_value_unset(&v_format); - } + /* Reset "format" field for each structure */ + if (!gst_vaapi_value_set_format_list (&value, postproc->filter_formats)) + goto cleanup; + if (gst_vaapi_value_set_format (&v_format, GST_VIDEO_FORMAT_ENCODED)) { + gst_value_list_prepend_value (&value, &v_format); + g_value_unset (&v_format); + } - num_structures = gst_caps_get_size(caps); - for (i = 0; i < num_structures; i++) { + num_structures = gst_caps_get_size (caps); + for (i = 0; i < num_structures; i++) { #if GST_CHECK_VERSION(1,1,0) - GstCapsFeatures * const features = gst_caps_get_features (caps, i); - if (gst_caps_features_contains(features, - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META)) - continue; + GstCapsFeatures *const features = gst_caps_get_features (caps, i); + if (gst_caps_features_contains (features, + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META)) + continue; #endif - GstStructure * const structure = gst_caps_get_structure(caps, i); - if (!structure) - continue; - gst_structure_set_value(structure, "format", &value); - } - g_value_unset(&value); + GstStructure *const structure = gst_caps_get_structure (caps, i); + if (!structure) + continue; + gst_structure_set_value (structure, "format", &value); + } + g_value_unset (&value); cleanup: - if (!had_filter) - gst_vaapipostproc_destroy_filter(postproc); - return caps; + if (!had_filter) + gst_vaapipostproc_destroy_filter (postproc); + return caps; } static gboolean -ensure_allowed_srcpad_caps(GstVaapiPostproc *postproc) +ensure_allowed_srcpad_caps (GstVaapiPostproc * postproc) { - GstCaps *out_caps; + GstCaps *out_caps; - if (postproc->allowed_srcpad_caps) - return TRUE; + if (postproc->allowed_srcpad_caps) + return TRUE; - /* Create initial caps from pad template */ - out_caps = gst_caps_from_string(gst_vaapipostproc_src_caps_str); - if (!out_caps) { - GST_ERROR("failed to create VA src caps"); - return FALSE; - } + /* Create initial caps from pad template */ + out_caps = gst_caps_from_string (gst_vaapipostproc_src_caps_str); + if (!out_caps) { + GST_ERROR ("failed to create VA src caps"); + return FALSE; + } - postproc->allowed_srcpad_caps = - expand_allowed_srcpad_caps(postproc, out_caps); - return postproc->allowed_srcpad_caps != NULL; + postproc->allowed_srcpad_caps = + expand_allowed_srcpad_caps (postproc, out_caps); + return postproc->allowed_srcpad_caps != NULL; } static void -find_best_size(GstVaapiPostproc *postproc, GstVideoInfo *vip, - guint *width_ptr, guint *height_ptr) +find_best_size (GstVaapiPostproc * postproc, GstVideoInfo * vip, + guint * width_ptr, guint * height_ptr) { - guint width, height; + guint width, height; - width = GST_VIDEO_INFO_WIDTH(vip); - height = GST_VIDEO_INFO_HEIGHT(vip); - if (postproc->width && postproc->height) { - width = postproc->width; - height = postproc->height; + width = GST_VIDEO_INFO_WIDTH (vip); + height = GST_VIDEO_INFO_HEIGHT (vip); + if (postproc->width && postproc->height) { + width = postproc->width; + height = postproc->height; + } else if (postproc->keep_aspect) { + const gdouble ratio = (gdouble) width / height; + if (postproc->width) { + width = postproc->width; + height = postproc->width / ratio; + } else if (postproc->height) { + height = postproc->height; + width = postproc->height * ratio; } - else if (postproc->keep_aspect) { - const gdouble ratio = (gdouble)width / height; - if (postproc->width) { - width = postproc->width; - height = postproc->width / ratio; - } - else if (postproc->height) { - height = postproc->height; - width = postproc->height * ratio; - } - } - else if (postproc->width) - width = postproc->width; - else if (postproc->height) - height = postproc->height; + } else if (postproc->width) + width = postproc->width; + else if (postproc->height) + height = postproc->height; - *width_ptr = width; - *height_ptr = height; + *width_ptr = width; + *height_ptr = height; } static GstCaps * -gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, - GstPadDirection direction, GstCaps *caps) +gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps) { - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); - GstVideoInfo vi; - GstVideoFormat format, out_format; - GstCaps *out_caps; + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + GstVideoInfo vi; + GstVideoFormat format, out_format; + GstCaps *out_caps; #if GST_CHECK_VERSION(1,1,0) - GstVaapiCapsFeature feature; - const gchar *feature_str; + GstVaapiCapsFeature feature; + const gchar *feature_str; #endif - guint width, height; + guint width, height; - /* Generate the sink pad caps, that could be fixated afterwards */ - if (direction == GST_PAD_SRC) { - if (!ensure_allowed_sinkpad_caps(postproc)) - return NULL; - return gst_caps_ref(postproc->allowed_sinkpad_caps); - } + /* Generate the sink pad caps, that could be fixated afterwards */ + if (direction == GST_PAD_SRC) { + if (!ensure_allowed_sinkpad_caps (postproc)) + return NULL; + return gst_caps_ref (postproc->allowed_sinkpad_caps); + } - /* Generate complete set of src pad caps if non-fixated sink pad - caps are provided */ - if (!gst_caps_is_fixed(caps)) { - if (!ensure_allowed_srcpad_caps(postproc)) - return NULL; - return gst_caps_ref(postproc->allowed_srcpad_caps); - } + /* Generate complete set of src pad caps if non-fixated sink pad + caps are provided */ + if (!gst_caps_is_fixed (caps)) { + if (!ensure_allowed_srcpad_caps (postproc)) + return NULL; + return gst_caps_ref (postproc->allowed_srcpad_caps); + } - /* Generate the expected src pad caps, from the current fixated - sink pad caps */ - if (!gst_video_info_from_caps(&vi, caps)) - return NULL; + /* Generate the expected src pad caps, from the current fixated + sink pad caps */ + if (!gst_video_info_from_caps (&vi, caps)) + return NULL; - // Set double framerate in interlaced mode - if (is_deinterlace_enabled(postproc, &vi)) { - gint fps_n = GST_VIDEO_INFO_FPS_N(&vi); - gint fps_d = GST_VIDEO_INFO_FPS_D(&vi); - if (!gst_util_fraction_multiply(fps_n, fps_d, 2, 1, &fps_n, &fps_d)) - return NULL; - GST_VIDEO_INFO_FPS_N(&vi) = fps_n; - GST_VIDEO_INFO_FPS_D(&vi) = fps_d; - } + // Set double framerate in interlaced mode + if (is_deinterlace_enabled (postproc, &vi)) { + gint fps_n = GST_VIDEO_INFO_FPS_N (&vi); + gint fps_d = GST_VIDEO_INFO_FPS_D (&vi); + if (!gst_util_fraction_multiply (fps_n, fps_d, 2, 1, &fps_n, &fps_d)) + return NULL; + GST_VIDEO_INFO_FPS_N (&vi) = fps_n; + GST_VIDEO_INFO_FPS_D (&vi) = fps_d; + } - // Signal the other pad that we only generate progressive frames - GST_VIDEO_INFO_INTERLACE_MODE(&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; + // Signal the other pad that we only generate progressive frames + GST_VIDEO_INFO_INTERLACE_MODE (&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; - // Update size from user-specified parameters - format = GST_VIDEO_INFO_FORMAT(&vi); + // Update size from user-specified parameters + format = GST_VIDEO_INFO_FORMAT (&vi); #if GST_CHECK_VERSION(1,1,0) - /* XXX: this is a workaround until auto-plugging is fixed when - * format=ENCODED + memory:VASurface caps feature are provided. - * use the downstream negotiated video format as the output format - * if the user didn't explicitly ask for colorspace conversion. - * Use a filter caps which contain all raw video formats, (excluding - * GST_VIDEO_FORMAT_ENCODED) */ - if (postproc->format != DEFAULT_FORMAT) - out_format = postproc->format; - else { - GstCaps *peer_caps, *filter_caps; - GstVideoInfo peer_vi; - filter_caps = gst_caps_from_string (GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL)); - peer_caps = gst_pad_peer_query_caps( - GST_BASE_TRANSFORM_SRC_PAD(trans), filter_caps); - if (!gst_caps_is_fixed(peer_caps)) - peer_caps = gst_caps_fixate (peer_caps); - gst_video_info_from_caps(&peer_vi, peer_caps); - out_format = GST_VIDEO_INFO_FORMAT (&peer_vi); - gst_caps_unref (filter_caps); - if (peer_caps) - gst_caps_unref (peer_caps); - } + /* XXX: this is a workaround until auto-plugging is fixed when + * format=ENCODED + memory:VASurface caps feature are provided. + * use the downstream negotiated video format as the output format + * if the user didn't explicitly ask for colorspace conversion. + * Use a filter caps which contain all raw video formats, (excluding + * GST_VIDEO_FORMAT_ENCODED) */ + if (postproc->format != DEFAULT_FORMAT) + out_format = postproc->format; + else { + GstCaps *peer_caps, *filter_caps; + GstVideoInfo peer_vi; + filter_caps = + gst_caps_from_string (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL)); + peer_caps = + gst_pad_peer_query_caps (GST_BASE_TRANSFORM_SRC_PAD (trans), + filter_caps); + if (!gst_caps_is_fixed (peer_caps)) + peer_caps = gst_caps_fixate (peer_caps); + gst_video_info_from_caps (&peer_vi, peer_caps); + out_format = GST_VIDEO_INFO_FORMAT (&peer_vi); + gst_caps_unref (filter_caps); + if (peer_caps) + gst_caps_unref (peer_caps); + } #else - out_format = GST_VIDEO_FORMAT_ENCODED; + out_format = GST_VIDEO_FORMAT_ENCODED; #endif - find_best_size(postproc, &vi, &width, &height); - gst_video_info_change_format(&vi, out_format, width, height); + find_best_size (postproc, &vi, &width, &height); + gst_video_info_change_format (&vi, out_format, width, height); #if GST_CHECK_VERSION(1,1,0) - out_caps = gst_video_info_to_caps(&vi); - if (!out_caps) - return NULL; + out_caps = gst_video_info_to_caps (&vi); + if (!out_caps) + return NULL; - feature = gst_vaapi_find_preferred_caps_feature( - GST_BASE_TRANSFORM_SRC_PAD(trans), out_format); - if (feature) { - feature_str = gst_vaapi_caps_feature_to_string(feature); + feature = + gst_vaapi_find_preferred_caps_feature (GST_BASE_TRANSFORM_SRC_PAD (trans), + out_format); + if (feature) { + feature_str = gst_vaapi_caps_feature_to_string (feature); + if (feature_str) + gst_caps_set_features (out_caps, 0, + gst_caps_features_new (feature_str, NULL)); + + if (out_format == GST_VIDEO_FORMAT_ENCODED && + feature != GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) { + GstCaps *sink_caps, *peer_caps = + gst_pad_peer_query_caps (GST_BASE_TRANSFORM_SRC_PAD (trans), + postproc->allowed_srcpad_caps); + + if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) + format = GST_VIDEO_FORMAT_RGBA; + + gst_video_info_change_format (&vi, format, width, height); + sink_caps = gst_video_info_to_caps (&vi); + if (sink_caps) { if (feature_str) - gst_caps_set_features(out_caps, 0, - gst_caps_features_new(feature_str, NULL)); - - if (out_format == GST_VIDEO_FORMAT_ENCODED && - feature != GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) { - GstCaps *sink_caps, *peer_caps = - gst_pad_peer_query_caps(GST_BASE_TRANSFORM_SRC_PAD(trans), - postproc->allowed_srcpad_caps); - - if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) - format = GST_VIDEO_FORMAT_RGBA; - - gst_video_info_change_format(&vi, format, width, height); - sink_caps = gst_video_info_to_caps(&vi); - if (sink_caps) { - if (feature_str) - gst_caps_set_features(sink_caps, 0, - gst_caps_features_new(feature_str, NULL)); - if (gst_caps_can_intersect(peer_caps, sink_caps)) - gst_caps_set_simple(out_caps, "format", G_TYPE_STRING, - gst_video_format_to_string(format), NULL); - gst_caps_unref(sink_caps); - } - gst_caps_unref(peer_caps); - } + gst_caps_set_features (sink_caps, 0, + gst_caps_features_new (feature_str, NULL)); + if (gst_caps_can_intersect (peer_caps, sink_caps)) + gst_caps_set_simple (out_caps, "format", G_TYPE_STRING, + gst_video_format_to_string (format), NULL); + gst_caps_unref (sink_caps); + } + gst_caps_unref (peer_caps); } + } #else - /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not - reconstruct suitable caps for "encoded" video formats */ - out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); - if (!out_caps) - return NULL; + /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not + reconstruct suitable caps for "encoded" video formats */ + out_caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS_NAME); + if (!out_caps) + return NULL; - gst_caps_set_simple(out_caps, - "type", G_TYPE_STRING, "vaapi", - "opengl", G_TYPE_BOOLEAN, USE_GLX, - "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH(&vi), - "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT(&vi), - "framerate", GST_TYPE_FRACTION, GST_VIDEO_INFO_FPS_N(&vi), - GST_VIDEO_INFO_FPS_D(&vi), - "pixel-aspect-ratio", GST_TYPE_FRACTION, GST_VIDEO_INFO_PAR_N(&vi), - GST_VIDEO_INFO_PAR_D(&vi), - NULL); + gst_caps_set_simple (out_caps, + "type", G_TYPE_STRING, "vaapi", + "opengl", G_TYPE_BOOLEAN, USE_GLX, + "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH (&vi), + "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT (&vi), + "framerate", GST_TYPE_FRACTION, GST_VIDEO_INFO_FPS_N (&vi), + GST_VIDEO_INFO_FPS_D (&vi), + "pixel-aspect-ratio", GST_TYPE_FRACTION, GST_VIDEO_INFO_PAR_N (&vi), + GST_VIDEO_INFO_PAR_D (&vi), NULL); - gst_caps_set_interlaced(out_caps, &vi); + gst_caps_set_interlaced (out_caps, &vi); #endif - return out_caps; + return out_caps; } #if GST_CHECK_VERSION(1,0,0) static GstCaps * -gst_vaapipostproc_transform_caps(GstBaseTransform *trans, - GstPadDirection direction, GstCaps *caps, GstCaps *filter) +gst_vaapipostproc_transform_caps (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps, GstCaps * filter) { - GstCaps *out_caps; + GstCaps *out_caps; - caps = gst_vaapipostproc_transform_caps_impl(trans, direction, caps); - if (caps && filter) { - out_caps = gst_caps_intersect_full(caps, filter, - GST_CAPS_INTERSECT_FIRST); - gst_caps_unref(caps); - return out_caps; - } - return caps; + caps = gst_vaapipostproc_transform_caps_impl (trans, direction, caps); + if (caps && filter) { + out_caps = gst_caps_intersect_full (caps, filter, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (caps); + return out_caps; + } + return caps; } #else #define gst_vaapipostproc_transform_caps \ @@ -1242,531 +1234,521 @@ typedef guint GstBaseTransformSizeType; #endif static gboolean -gst_vaapipostproc_transform_size(GstBaseTransform *trans, - GstPadDirection direction, GstCaps *caps, GstBaseTransformSizeType size, - GstCaps *othercaps, GstBaseTransformSizeType *othersize) +gst_vaapipostproc_transform_size (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps, GstBaseTransformSizeType size, + GstCaps * othercaps, GstBaseTransformSizeType * othersize) { - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - if (direction == GST_PAD_SINK || postproc->get_va_surfaces) - *othersize = 0; - else - *othersize = size; - return TRUE; + if (direction == GST_PAD_SINK || postproc->get_va_surfaces) + *othersize = 0; + else + *othersize = size; + return TRUE; } static GstFlowReturn -gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf, - GstBuffer *outbuf) +gst_vaapipostproc_transform (GstBaseTransform * trans, GstBuffer * inbuf, + GstBuffer * outbuf) { - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); - GstBuffer *buf; - GstFlowReturn ret; + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + GstBuffer *buf; + GstFlowReturn ret; - ret = gst_vaapi_plugin_base_get_input_buffer( - GST_VAAPI_PLUGIN_BASE(postproc), inbuf, &buf); - if (ret != GST_FLOW_OK) - return GST_FLOW_ERROR; + ret = + gst_vaapi_plugin_base_get_input_buffer (GST_VAAPI_PLUGIN_BASE (postproc), + inbuf, &buf); + if (ret != GST_FLOW_OK) + return GST_FLOW_ERROR; - ret = GST_FLOW_NOT_SUPPORTED; - if (postproc->flags) { - /* Use VA/VPP extensions to process this frame */ - if (postproc->has_vpp && - (postproc->flags != GST_VAAPI_POSTPROC_FLAG_DEINTERLACE || - deint_method_is_advanced(postproc->deinterlace_method))) { - ret = gst_vaapipostproc_process_vpp(trans, buf, outbuf); - if (ret != GST_FLOW_NOT_SUPPORTED) - goto done; - GST_WARNING("unsupported VPP filters. Disabling"); - } - - /* Only append picture structure meta data (top/bottom field) */ - if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) { - ret = gst_vaapipostproc_process(trans, buf, outbuf); - if (ret != GST_FLOW_NOT_SUPPORTED) - goto done; - } + ret = GST_FLOW_NOT_SUPPORTED; + if (postproc->flags) { + /* Use VA/VPP extensions to process this frame */ + if (postproc->has_vpp && + (postproc->flags != GST_VAAPI_POSTPROC_FLAG_DEINTERLACE || + deint_method_is_advanced (postproc->deinterlace_method))) { + ret = gst_vaapipostproc_process_vpp (trans, buf, outbuf); + if (ret != GST_FLOW_NOT_SUPPORTED) + goto done; + GST_WARNING ("unsupported VPP filters. Disabling"); } - /* Fallback: passthrough to the downstream element as is */ - ret = gst_vaapipostproc_passthrough(trans, buf, outbuf); + /* Only append picture structure meta data (top/bottom field) */ + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) { + ret = gst_vaapipostproc_process (trans, buf, outbuf); + if (ret != GST_FLOW_NOT_SUPPORTED) + goto done; + } + } + + /* Fallback: passthrough to the downstream element as is */ + ret = gst_vaapipostproc_passthrough (trans, buf, outbuf); done: - gst_buffer_unref(buf); - return ret; + gst_buffer_unref (buf); + return ret; } static GstFlowReturn -gst_vaapipostproc_prepare_output_buffer(GstBaseTransform *trans, - GstBuffer *inbuf, +gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, + GstBuffer * inbuf, #if !GST_CHECK_VERSION(1,0,0) - gint size, GstCaps *caps, + gint size, GstCaps * caps, #endif - GstBuffer **outbuf_ptr) + GstBuffer ** outbuf_ptr) { - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - *outbuf_ptr = create_output_buffer(postproc); - return *outbuf_ptr ? GST_FLOW_OK : GST_FLOW_ERROR; + *outbuf_ptr = create_output_buffer (postproc); + return *outbuf_ptr ? GST_FLOW_OK : GST_FLOW_ERROR; } static gboolean -ensure_srcpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps) +ensure_srcpad_buffer_pool (GstVaapiPostproc * postproc, GstCaps * caps) { - GstVideoInfo vi; - GstVaapiVideoPool *pool; + GstVideoInfo vi; + GstVaapiVideoPool *pool; - gst_video_info_init(&vi); - gst_video_info_from_caps(&vi, caps); - gst_video_info_change_format(&vi, postproc->format, - GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); + gst_video_info_init (&vi); + gst_video_info_from_caps (&vi, caps); + gst_video_info_change_format (&vi, postproc->format, + GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); - if (postproc->filter_pool && !video_info_changed(&vi, &postproc->filter_pool_info)) - return TRUE; - postproc->filter_pool_info = vi; - - pool = gst_vaapi_surface_pool_new(GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc), - &postproc->filter_pool_info); - if (!pool) - return FALSE; - - gst_vaapi_video_pool_replace(&postproc->filter_pool, pool); - gst_vaapi_video_pool_unref(pool); + if (postproc->filter_pool + && !video_info_changed (&vi, &postproc->filter_pool_info)) return TRUE; + postproc->filter_pool_info = vi; + + pool = gst_vaapi_surface_pool_new (GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc), + &postproc->filter_pool_info); + if (!pool) + return FALSE; + + gst_vaapi_video_pool_replace (&postproc->filter_pool, pool); + gst_vaapi_video_pool_unref (pool); + return TRUE; } static gboolean -gst_vaapipostproc_set_caps(GstBaseTransform *trans, GstCaps *caps, - GstCaps *out_caps) +gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, + GstCaps * out_caps) { - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); - gboolean caps_changed = FALSE; + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + gboolean caps_changed = FALSE; - if (!gst_vaapipostproc_update_sink_caps(postproc, caps, &caps_changed)) - return FALSE; - if (!gst_vaapipostproc_update_src_caps(postproc, out_caps, &caps_changed)) - return FALSE; + if (!gst_vaapipostproc_update_sink_caps (postproc, caps, &caps_changed)) + return FALSE; + if (!gst_vaapipostproc_update_src_caps (postproc, out_caps, &caps_changed)) + return FALSE; - if (caps_changed) { - gst_vaapipostproc_destroy(postproc); - if (!gst_vaapipostproc_create(postproc)) - return FALSE; - if (!gst_vaapi_plugin_base_set_caps(GST_VAAPI_PLUGIN_BASE(trans), - caps, out_caps)) - return FALSE; - } + if (caps_changed) { + gst_vaapipostproc_destroy (postproc); + if (!gst_vaapipostproc_create (postproc)) + return FALSE; + if (!gst_vaapi_plugin_base_set_caps (GST_VAAPI_PLUGIN_BASE (trans), + caps, out_caps)) + return FALSE; + } - if (!ensure_srcpad_buffer_pool(postproc, out_caps)) - return FALSE; + if (!ensure_srcpad_buffer_pool (postproc, out_caps)) + return FALSE; + return TRUE; +} + +static gboolean +gst_vaapipostproc_query (GstBaseTransform * trans, GstPadDirection direction, + GstQuery * query) +{ + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + + GST_INFO_OBJECT (trans, "query type `%s'", GST_QUERY_TYPE_NAME (query)); + + if (gst_vaapi_reply_to_query (query, + GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc))) { + GST_DEBUG ("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc)); return TRUE; -} + } -static gboolean -gst_vaapipostproc_query(GstBaseTransform *trans, GstPadDirection direction, - GstQuery *query) -{ - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); - - GST_INFO_OBJECT(trans, "query type `%s'", GST_QUERY_TYPE_NAME(query)); - - if (gst_vaapi_reply_to_query(query, GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc))) { - GST_DEBUG("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); - return TRUE; - } - - return GST_BASE_TRANSFORM_CLASS(gst_vaapipostproc_parent_class)->query( - trans, direction, query); + return + GST_BASE_TRANSFORM_CLASS (gst_vaapipostproc_parent_class)->query (trans, + direction, query); } #if GST_CHECK_VERSION(1,0,0) static gboolean -gst_vaapipostproc_propose_allocation(GstBaseTransform *trans, - GstQuery *decide_query, GstQuery *query) +gst_vaapipostproc_propose_allocation (GstBaseTransform * trans, + GstQuery * decide_query, GstQuery * query) { - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(trans); + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (trans); - /* Let vaapidecode allocate the video buffers */ - if (postproc->get_va_surfaces) - return FALSE; - if (!gst_vaapi_plugin_base_propose_allocation(plugin, query)) - return FALSE; - return TRUE; + /* Let vaapidecode allocate the video buffers */ + if (postproc->get_va_surfaces) + return FALSE; + if (!gst_vaapi_plugin_base_propose_allocation (plugin, query)) + return FALSE; + return TRUE; } static gboolean -gst_vaapipostproc_decide_allocation(GstBaseTransform *trans, GstQuery *query) +gst_vaapipostproc_decide_allocation (GstBaseTransform * trans, GstQuery * query) { - return gst_vaapi_plugin_base_decide_allocation(GST_VAAPI_PLUGIN_BASE(trans), - query, 0); + return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (trans), + query, 0); } #endif static void -gst_vaapipostproc_finalize(GObject *object) +gst_vaapipostproc_finalize (GObject * object) { - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(object); + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (object); - gst_vaapipostproc_destroy(postproc); + gst_vaapipostproc_destroy (postproc); - gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(postproc)); - G_OBJECT_CLASS(gst_vaapipostproc_parent_class)->finalize(object); + gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (postproc)); + G_OBJECT_CLASS (gst_vaapipostproc_parent_class)->finalize (object); } static void -gst_vaapipostproc_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) +gst_vaapipostproc_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(object); + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (object); - switch (prop_id) { + switch (prop_id) { case PROP_FORMAT: - postproc->format = g_value_get_enum(value); - break; + postproc->format = g_value_get_enum (value); + break; case PROP_WIDTH: - postproc->width = g_value_get_uint(value); - break; + postproc->width = g_value_get_uint (value); + break; case PROP_HEIGHT: - postproc->height = g_value_get_uint(value); - break; + postproc->height = g_value_get_uint (value); + break; case PROP_FORCE_ASPECT_RATIO: - postproc->keep_aspect = g_value_get_boolean(value); - break; + postproc->keep_aspect = g_value_get_boolean (value); + break; case PROP_DEINTERLACE_MODE: - postproc->deinterlace_mode = g_value_get_enum(value); - break; + postproc->deinterlace_mode = g_value_get_enum (value); + break; case PROP_DEINTERLACE_METHOD: - postproc->deinterlace_method = g_value_get_enum(value); - break; - case PROP_DENOISE: - postproc->denoise_level = g_value_get_float(value); - postproc->flags |= GST_VAAPI_POSTPROC_FLAG_DENOISE; - break; - case PROP_SHARPEN: - postproc->sharpen_level = g_value_get_float(value); - postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SHARPEN; - break; - case PROP_HUE: - postproc->hue = g_value_get_float(value); - postproc->flags |= GST_VAAPI_POSTPROC_FLAG_HUE; - break; - case PROP_SATURATION: - postproc->saturation = g_value_get_float(value); - postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SATURATION; - break; - case PROP_BRIGHTNESS: - postproc->brightness = g_value_get_float(value); - postproc->flags |= GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS; - break; - case PROP_CONTRAST: - postproc->contrast = g_value_get_float(value); - postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CONTRAST; - break; - case PROP_SCALE_METHOD: - postproc->scale_method = g_value_get_enum(value); - postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SCALE; - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapipostproc_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(object); - - switch (prop_id) { - case PROP_FORMAT: - g_value_set_enum(value, postproc->format); - break; - case PROP_WIDTH: - g_value_set_uint(value, postproc->width); - break; - case PROP_HEIGHT: - g_value_set_uint(value, postproc->height); - break; - case PROP_FORCE_ASPECT_RATIO: - g_value_set_boolean(value, postproc->keep_aspect); - break; - case PROP_DEINTERLACE_MODE: - g_value_set_enum(value, postproc->deinterlace_mode); - break; - case PROP_DEINTERLACE_METHOD: - g_value_set_enum(value, postproc->deinterlace_method); - break; + postproc->deinterlace_method = g_value_get_enum (value); + break; case PROP_DENOISE: - g_value_set_float(value, postproc->denoise_level); - break; + postproc->denoise_level = g_value_get_float (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_DENOISE; + break; case PROP_SHARPEN: - g_value_set_float(value, postproc->sharpen_level); - break; + postproc->sharpen_level = g_value_get_float (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SHARPEN; + break; case PROP_HUE: - g_value_set_float(value, postproc->hue); - break; + postproc->hue = g_value_get_float (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_HUE; + break; case PROP_SATURATION: - g_value_set_float(value, postproc->saturation); - break; + postproc->saturation = g_value_get_float (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SATURATION; + break; case PROP_BRIGHTNESS: - g_value_set_float(value, postproc->brightness); - break; + postproc->brightness = g_value_get_float (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS; + break; case PROP_CONTRAST: - g_value_set_float(value, postproc->contrast); - break; + postproc->contrast = g_value_get_float (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CONTRAST; + break; case PROP_SCALE_METHOD: - g_value_set_enum(value, postproc->scale_method); - break; + postproc->scale_method = g_value_get_enum (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SCALE; + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) +gst_vaapipostproc_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); - GstPadTemplate *pad_template; - GPtrArray *filter_ops; - GstVaapiFilterOpInfo *filter_op; + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (object); - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapipostproc, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + switch (prop_id) { + case PROP_FORMAT: + g_value_set_enum (value, postproc->format); + break; + case PROP_WIDTH: + g_value_set_uint (value, postproc->width); + break; + case PROP_HEIGHT: + g_value_set_uint (value, postproc->height); + break; + case PROP_FORCE_ASPECT_RATIO: + g_value_set_boolean (value, postproc->keep_aspect); + break; + case PROP_DEINTERLACE_MODE: + g_value_set_enum (value, postproc->deinterlace_mode); + break; + case PROP_DEINTERLACE_METHOD: + g_value_set_enum (value, postproc->deinterlace_method); + break; + case PROP_DENOISE: + g_value_set_float (value, postproc->denoise_level); + break; + case PROP_SHARPEN: + g_value_set_float (value, postproc->sharpen_level); + break; + case PROP_HUE: + g_value_set_float (value, postproc->hue); + break; + case PROP_SATURATION: + g_value_set_float (value, postproc->saturation); + break; + case PROP_BRIGHTNESS: + g_value_set_float (value, postproc->brightness); + break; + case PROP_CONTRAST: + g_value_set_float (value, postproc->contrast); + break; + case PROP_SCALE_METHOD: + g_value_set_enum (value, postproc->scale_method); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} - gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass)); +static void +gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstBaseTransformClass *const trans_class = GST_BASE_TRANSFORM_CLASS (klass); + GstPadTemplate *pad_template; + GPtrArray *filter_ops; + GstVaapiFilterOpInfo *filter_op; - object_class->finalize = gst_vaapipostproc_finalize; - object_class->set_property = gst_vaapipostproc_set_property; - object_class->get_property = gst_vaapipostproc_get_property; - trans_class->start = gst_vaapipostproc_start; - trans_class->stop = gst_vaapipostproc_stop; - trans_class->transform_caps = gst_vaapipostproc_transform_caps; - trans_class->transform_size = gst_vaapipostproc_transform_size; - trans_class->transform = gst_vaapipostproc_transform; - trans_class->set_caps = gst_vaapipostproc_set_caps; - trans_class->query = gst_vaapipostproc_query; + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapipostproc, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + gst_vaapi_plugin_base_class_init (GST_VAAPI_PLUGIN_BASE_CLASS (klass)); + + object_class->finalize = gst_vaapipostproc_finalize; + object_class->set_property = gst_vaapipostproc_set_property; + object_class->get_property = gst_vaapipostproc_get_property; + trans_class->start = gst_vaapipostproc_start; + trans_class->stop = gst_vaapipostproc_stop; + trans_class->transform_caps = gst_vaapipostproc_transform_caps; + trans_class->transform_size = gst_vaapipostproc_transform_size; + trans_class->transform = gst_vaapipostproc_transform; + trans_class->set_caps = gst_vaapipostproc_set_caps; + trans_class->query = gst_vaapipostproc_query; #if GST_CHECK_VERSION(1,0,0) - trans_class->propose_allocation = gst_vaapipostproc_propose_allocation; - trans_class->decide_allocation = gst_vaapipostproc_decide_allocation; + trans_class->propose_allocation = gst_vaapipostproc_propose_allocation; + trans_class->decide_allocation = gst_vaapipostproc_decide_allocation; #endif - trans_class->prepare_output_buffer = - gst_vaapipostproc_prepare_output_buffer; + trans_class->prepare_output_buffer = gst_vaapipostproc_prepare_output_buffer; - gst_element_class_set_static_metadata(element_class, - "VA-API video postprocessing", - "Filter/Converter/Video;Filter/Converter/Video/Scaler;" - "Filter/Effect/Video;Filter/Effect/Video/Deinterlace", - GST_PLUGIN_DESC, - "Gwenole Beauchesne "); + gst_element_class_set_static_metadata (element_class, + "VA-API video postprocessing", + "Filter/Converter/Video;Filter/Converter/Video/Scaler;" + "Filter/Effect/Video;Filter/Effect/Video/Deinterlace", + GST_PLUGIN_DESC, "Gwenole Beauchesne "); - /* sink pad */ - pad_template = gst_static_pad_template_get(&gst_vaapipostproc_sink_factory); - gst_element_class_add_pad_template(element_class, pad_template); + /* sink pad */ + pad_template = gst_static_pad_template_get (&gst_vaapipostproc_sink_factory); + gst_element_class_add_pad_template (element_class, pad_template); - /* src pad */ - pad_template = gst_static_pad_template_get(&gst_vaapipostproc_src_factory); - gst_element_class_add_pad_template(element_class, pad_template); + /* src pad */ + pad_template = gst_static_pad_template_get (&gst_vaapipostproc_src_factory); + gst_element_class_add_pad_template (element_class, pad_template); - /** - * GstVaapiPostproc:deinterlace-mode: - * - * This selects whether the deinterlacing should always be applied or if - * they should only be applied on content that has the "interlaced" flag - * on the caps. - */ - g_object_class_install_property - (object_class, - PROP_DEINTERLACE_MODE, - g_param_spec_enum("deinterlace-mode", - "Deinterlace mode", - "Deinterlace mode to use", - GST_VAAPI_TYPE_DEINTERLACE_MODE, - DEFAULT_DEINTERLACE_MODE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiPostproc:deinterlace-mode: + * + * This selects whether the deinterlacing should always be applied + * or if they should only be applied on content that has the + * "interlaced" flag on the caps. + */ + g_object_class_install_property + (object_class, + PROP_DEINTERLACE_MODE, + g_param_spec_enum ("deinterlace-mode", + "Deinterlace mode", + "Deinterlace mode to use", + GST_VAAPI_TYPE_DEINTERLACE_MODE, + DEFAULT_DEINTERLACE_MODE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiPostproc:deinterlace-method: - * - * This selects the deinterlacing method to apply. - */ - g_object_class_install_property - (object_class, - PROP_DEINTERLACE_METHOD, - g_param_spec_enum("deinterlace-method", - "Deinterlace method", - "Deinterlace method to use", - GST_VAAPI_TYPE_DEINTERLACE_METHOD, - DEFAULT_DEINTERLACE_METHOD, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiPostproc:deinterlace-method: + * + * This selects the deinterlacing method to apply. + */ + g_object_class_install_property + (object_class, + PROP_DEINTERLACE_METHOD, + g_param_spec_enum ("deinterlace-method", + "Deinterlace method", + "Deinterlace method to use", + GST_VAAPI_TYPE_DEINTERLACE_METHOD, + DEFAULT_DEINTERLACE_METHOD, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - filter_ops = gst_vaapi_filter_get_operations(NULL); - if (!filter_ops) - return; + filter_ops = gst_vaapi_filter_get_operations (NULL); + if (!filter_ops) + return; - /** - * GstVaapiPostproc:format: - * - * The forced output pixel format, expressed as a #GstVideoFormat. - */ - filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_FORMAT); - if (filter_op) - g_object_class_install_property(object_class, - PROP_FORMAT, filter_op->pspec); + /** + * GstVaapiPostproc:format: + * + * The forced output pixel format, expressed as a #GstVideoFormat. + */ + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_FORMAT); + if (filter_op) + g_object_class_install_property (object_class, + PROP_FORMAT, filter_op->pspec); - /** - * GstVaapiPostproc:width: - * - * The forced output width in pixels. If set to zero, the width is - * calculated from the height if aspect ration is preserved, or - * inherited from the sink caps width - */ - g_object_class_install_property - (object_class, - PROP_WIDTH, - g_param_spec_uint("width", - "Width", - "Forced output width", - 0, G_MAXINT, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiPostproc:width: + * + * The forced output width in pixels. If set to zero, the width is + * calculated from the height if aspect ration is preserved, or + * inherited from the sink caps width + */ + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_uint ("width", + "Width", + "Forced output width", + 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiPostproc:height: - * - * The forced output height in pixels. If set to zero, the height - * is calculated from the width if aspect ration is preserved, or - * inherited from the sink caps height - */ - g_object_class_install_property - (object_class, - PROP_HEIGHT, - g_param_spec_uint("height", - "Height", - "Forced output height", - 0, G_MAXINT, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiPostproc:height: + * + * The forced output height in pixels. If set to zero, the height is + * calculated from the width if aspect ration is preserved, or + * inherited from the sink caps height + */ + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_uint ("height", + "Height", + "Forced output height", + 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiPostproc:force-aspect-ratio: - * - * When enabled, scaling respects video aspect ratio; when - * disabled, the video is distorted to fit the width and height - * properties. - */ - g_object_class_install_property - (object_class, - PROP_FORCE_ASPECT_RATIO, - g_param_spec_boolean("force-aspect-ratio", - "Force aspect ratio", - "When enabled, scaling will respect original aspect ratio", - TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiPostproc:force-aspect-ratio: + * + * When enabled, scaling respects video aspect ratio; when disabled, + * the video is distorted to fit the width and height properties. + */ + g_object_class_install_property + (object_class, + PROP_FORCE_ASPECT_RATIO, + g_param_spec_boolean ("force-aspect-ratio", + "Force aspect ratio", + "When enabled, scaling will respect original aspect ratio", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiPostproc:denoise: - * - * The level of noise reduction to apply. - */ - filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_DENOISE); - if (filter_op) - g_object_class_install_property(object_class, - PROP_DENOISE, filter_op->pspec); + /** + * GstVaapiPostproc:denoise: + * + * The level of noise reduction to apply. + */ + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_DENOISE); + if (filter_op) + g_object_class_install_property (object_class, + PROP_DENOISE, filter_op->pspec); - /** - * GstVaapiPostproc:sharpen: - * - * The level of sharpening to apply for positive values, or the - * level of blurring for negative values. - */ - filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_SHARPEN); - if (filter_op) - g_object_class_install_property(object_class, - PROP_SHARPEN, filter_op->pspec); + /** + * GstVaapiPostproc:sharpen: + * + * The level of sharpening to apply for positive values, or the + * level of blurring for negative values. + */ + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_SHARPEN); + if (filter_op) + g_object_class_install_property (object_class, + PROP_SHARPEN, filter_op->pspec); - /** - * GstVaapiPostproc:hue: - * - * The color hue, expressed as a float value. Range is -180.0 to - * 180.0. Default value is 0.0 and represents no modification. - */ - filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_HUE); - if (filter_op) - g_object_class_install_property(object_class, - PROP_HUE, filter_op->pspec); + /** + * GstVaapiPostproc:hue: + * + * The color hue, expressed as a float value. Range is -180.0 to + * 180.0. Default value is 0.0 and represents no modification. + */ + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_HUE); + if (filter_op) + g_object_class_install_property (object_class, PROP_HUE, filter_op->pspec); - /** - * GstVaapiPostproc:saturation: - * - * The color saturation, expressed as a float value. Range is 0.0 - * to 2.0. Default value is 1.0 and represents no modification. - */ - filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_SATURATION); - if (filter_op) - g_object_class_install_property(object_class, - PROP_SATURATION, filter_op->pspec); + /** + * GstVaapiPostproc:saturation: + * + * The color saturation, expressed as a float value. Range is 0.0 to + * 2.0. Default value is 1.0 and represents no modification. + */ + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_SATURATION); + if (filter_op) + g_object_class_install_property (object_class, + PROP_SATURATION, filter_op->pspec); - /** - * GstVaapiPostproc:brightness: - * - * The color brightness, expressed as a float value. Range is -1.0 - * to 1.0. Default value is 0.0 and represents no modification. - */ - filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_BRIGHTNESS); - if (filter_op) - g_object_class_install_property(object_class, - PROP_BRIGHTNESS, filter_op->pspec); + /** + * GstVaapiPostproc:brightness: + * + * The color brightness, expressed as a float value. Range is -1.0 + * to 1.0. Default value is 0.0 and represents no modification. + */ + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_BRIGHTNESS); + if (filter_op) + g_object_class_install_property (object_class, + PROP_BRIGHTNESS, filter_op->pspec); - /** - * GstVaapiPostproc:contrast: - * - * The color contrast, expressed as a float value. Range is 0.0 to - * 2.0. Default value is 1.0 and represents no modification. - */ - filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_CONTRAST); - if (filter_op) - g_object_class_install_property(object_class, - PROP_CONTRAST, filter_op->pspec); + /** + * GstVaapiPostproc:contrast: + * + * The color contrast, expressed as a float value. Range is 0.0 to + * 2.0. Default value is 1.0 and represents no modification. + */ + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_CONTRAST); + if (filter_op) + g_object_class_install_property (object_class, + PROP_CONTRAST, filter_op->pspec); - /** - * GstVaapiPostproc:scale-method: - * - * The scaling method to use, expressed as an enum value. See - * #GstVaapiScaleMethod. - */ - filter_op = find_filter_op(filter_ops, GST_VAAPI_FILTER_OP_SCALING); - if (filter_op) - g_object_class_install_property(object_class, - PROP_SCALE_METHOD, filter_op->pspec); + /** + * GstVaapiPostproc:scale-method: + * + * The scaling method to use, expressed as an enum value. See + * #GstVaapiScaleMethod. + */ + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_SCALING); + if (filter_op) + g_object_class_install_property (object_class, + PROP_SCALE_METHOD, filter_op->pspec); - g_ptr_array_unref(filter_ops); + g_ptr_array_unref (filter_ops); } static void -gst_vaapipostproc_init(GstVaapiPostproc *postproc) +gst_vaapipostproc_init (GstVaapiPostproc * postproc) { - gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(postproc), GST_CAT_DEFAULT); + gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (postproc), + GST_CAT_DEFAULT); - postproc->format = DEFAULT_FORMAT; - postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE; - postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; - postproc->field_duration = GST_CLOCK_TIME_NONE; - postproc->keep_aspect = TRUE; - postproc->get_va_surfaces = TRUE; + postproc->format = DEFAULT_FORMAT; + postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE; + postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; + postproc->field_duration = GST_CLOCK_TIME_NONE; + postproc->keep_aspect = TRUE; + postproc->get_va_surfaces = TRUE; - gst_video_info_init(&postproc->sinkpad_info); - gst_video_info_init(&postproc->srcpad_info); - gst_video_info_init(&postproc->filter_pool_info); + gst_video_info_init (&postproc->sinkpad_info); + gst_video_info_init (&postproc->srcpad_info); + gst_video_info_init (&postproc->filter_pool_info); } diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index af6fdf9dc1..aaa621019a 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -31,32 +31,23 @@ G_BEGIN_DECLS #define GST_TYPE_VAAPIPOSTPROC \ - (gst_vaapipostproc_get_type()) - -#define GST_VAAPIPOSTPROC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_TYPE_VAAPIPOSTPROC, \ - GstVaapiPostproc)) - -#define GST_VAAPIPOSTPROC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_TYPE_VAAPIPOSTPROC, \ - GstVaapiPostprocClass)) - + (gst_vaapipostproc_get_type ()) +#define GST_VAAPIPOSTPROC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPIPOSTPROC, GstVaapiPostproc)) +#define GST_VAAPIPOSTPROC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPIPOSTPROC, \ + GstVaapiPostprocClass)) #define GST_IS_VAAPIPOSTPROC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPIPOSTPROC)) - + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPIPOSTPROC)) #define GST_IS_VAAPIPOSTPROC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPIPOSTPROC)) + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPIPOSTPROC)) +#define GST_VAAPIPOSTPROC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_VAAPIPOSTPROC, \ + GstVaapiPostprocClass)) -#define GST_VAAPIPOSTPROC_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_TYPE_VAAPIPOSTPROC, \ - GstVaapiPostprocClass)) - -typedef struct _GstVaapiPostproc GstVaapiPostproc; -typedef struct _GstVaapiPostprocClass GstVaapiPostprocClass; -typedef struct _GstVaapiDeinterlaceState GstVaapiDeinterlaceState; +typedef struct _GstVaapiPostproc GstVaapiPostproc; +typedef struct _GstVaapiPostprocClass GstVaapiPostprocClass; +typedef struct _GstVaapiDeinterlaceState GstVaapiDeinterlaceState; /** * GstVaapiDeinterlaceMode: @@ -64,10 +55,11 @@ typedef struct _GstVaapiDeinterlaceState GstVaapiDeinterlaceState; * @GST_VAAPI_DEINTERLACE_MODE_INTERLACED: Force deinterlacing. * @GST_VAAPI_DEINTERLACE_MODE_DISABLED: Never perform deinterlacing. */ -typedef enum { - GST_VAAPI_DEINTERLACE_MODE_AUTO = 0, - GST_VAAPI_DEINTERLACE_MODE_INTERLACED, - GST_VAAPI_DEINTERLACE_MODE_DISABLED, +typedef enum +{ + GST_VAAPI_DEINTERLACE_MODE_AUTO = 0, + GST_VAAPI_DEINTERLACE_MODE_INTERLACED, + GST_VAAPI_DEINTERLACE_MODE_DISABLED, } GstVaapiDeinterlaceMode; /* @@ -97,20 +89,21 @@ typedef enum { * * The set of operations that are to be performed for each frame. */ -typedef enum { - GST_VAAPI_POSTPROC_FLAG_FORMAT = 1 << GST_VAAPI_FILTER_OP_FORMAT, - GST_VAAPI_POSTPROC_FLAG_DENOISE = 1 << GST_VAAPI_FILTER_OP_DENOISE, - GST_VAAPI_POSTPROC_FLAG_SHARPEN = 1 << GST_VAAPI_FILTER_OP_SHARPEN, - GST_VAAPI_POSTPROC_FLAG_HUE = 1 << GST_VAAPI_FILTER_OP_HUE, - GST_VAAPI_POSTPROC_FLAG_SATURATION = 1 << GST_VAAPI_FILTER_OP_SATURATION, - GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS = 1 << GST_VAAPI_FILTER_OP_BRIGHTNESS, - GST_VAAPI_POSTPROC_FLAG_CONTRAST = 1 << GST_VAAPI_FILTER_OP_CONTRAST, - GST_VAAPI_POSTPROC_FLAG_DEINTERLACE = 1 << GST_VAAPI_FILTER_OP_DEINTERLACING, - GST_VAAPI_POSTPROC_FLAG_SCALE = 1 << GST_VAAPI_FILTER_OP_SCALING, +typedef enum +{ + GST_VAAPI_POSTPROC_FLAG_FORMAT = 1 << GST_VAAPI_FILTER_OP_FORMAT, + GST_VAAPI_POSTPROC_FLAG_DENOISE = 1 << GST_VAAPI_FILTER_OP_DENOISE, + GST_VAAPI_POSTPROC_FLAG_SHARPEN = 1 << GST_VAAPI_FILTER_OP_SHARPEN, + GST_VAAPI_POSTPROC_FLAG_HUE = 1 << GST_VAAPI_FILTER_OP_HUE, + GST_VAAPI_POSTPROC_FLAG_SATURATION = 1 << GST_VAAPI_FILTER_OP_SATURATION, + GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS = 1 << GST_VAAPI_FILTER_OP_BRIGHTNESS, + GST_VAAPI_POSTPROC_FLAG_CONTRAST = 1 << GST_VAAPI_FILTER_OP_CONTRAST, + GST_VAAPI_POSTPROC_FLAG_DEINTERLACE = 1 << GST_VAAPI_FILTER_OP_DEINTERLACING, + GST_VAAPI_POSTPROC_FLAG_SCALE = 1 << GST_VAAPI_FILTER_OP_SCALING, - /* Additional custom flags */ - GST_VAAPI_POSTPROC_FLAG_CUSTOM = 1 << 20, - GST_VAAPI_POSTPROC_FLAG_SIZE = GST_VAAPI_POSTPROC_FLAG_CUSTOM, + /* Additional custom flags */ + GST_VAAPI_POSTPROC_FLAG_CUSTOM = 1 << 20, + GST_VAAPI_POSTPROC_FLAG_SIZE = GST_VAAPI_POSTPROC_FLAG_CUSTOM, } GstVaapiPostprocFlags; /* @@ -124,65 +117,68 @@ typedef enum { * * Context used to maintain deinterlacing state. */ -struct _GstVaapiDeinterlaceState { - GstBuffer *buffers[GST_VAAPI_DEINTERLACE_MAX_REFERENCES]; - guint buffers_index; - GstVaapiSurface *surfaces[GST_VAAPI_DEINTERLACE_MAX_REFERENCES]; - guint num_surfaces; - guint deint : 1; - guint tff : 1; +struct _GstVaapiDeinterlaceState +{ + GstBuffer *buffers[GST_VAAPI_DEINTERLACE_MAX_REFERENCES]; + guint buffers_index; + GstVaapiSurface *surfaces[GST_VAAPI_DEINTERLACE_MAX_REFERENCES]; + guint num_surfaces; + guint deint:1; + guint tff:1; }; -struct _GstVaapiPostproc { - /*< private >*/ - GstVaapiPluginBase parent_instance; +struct _GstVaapiPostproc +{ + /*< private >*/ + GstVaapiPluginBase parent_instance; - GstVaapiFilter *filter; - GPtrArray *filter_ops; - GstVaapiVideoPool *filter_pool; - GstVideoInfo filter_pool_info; - gboolean filter_pool_active; - GArray *filter_formats; - GstVideoFormat format; /* output video format (encoded) */ - guint width; - guint height; - guint flags; + GstVaapiFilter *filter; + GPtrArray *filter_ops; + GstVaapiVideoPool *filter_pool; + GstVideoInfo filter_pool_info; + gboolean filter_pool_active; + GArray *filter_formats; + GstVideoFormat format; /* output video format (encoded) */ + guint width; + guint height; + guint flags; - GstCaps *allowed_sinkpad_caps; - GstVideoInfo sinkpad_info; - GstCaps *allowed_srcpad_caps; - GstVideoInfo srcpad_info; + GstCaps *allowed_sinkpad_caps; + GstVideoInfo sinkpad_info; + GstCaps *allowed_srcpad_caps; + GstVideoInfo srcpad_info; - /* Deinterlacing */ - GstVaapiDeinterlaceMode deinterlace_mode; - GstVaapiDeinterlaceMethod deinterlace_method; - GstVaapiDeinterlaceState deinterlace_state; - GstClockTime field_duration; + /* Deinterlacing */ + GstVaapiDeinterlaceMode deinterlace_mode; + GstVaapiDeinterlaceMethod deinterlace_method; + GstVaapiDeinterlaceState deinterlace_state; + GstClockTime field_duration; - /* Basic filter values */ - gfloat denoise_level; - gfloat sharpen_level; + /* Basic filter values */ + gfloat denoise_level; + gfloat sharpen_level; - /* Color balance filter values */ - GstVaapiScaleMethod scale_method; - gfloat hue; - gfloat saturation; - gfloat brightness; - gfloat contrast; + /* Color balance filter values */ + GstVaapiScaleMethod scale_method; + gfloat hue; + gfloat saturation; + gfloat brightness; + gfloat contrast; - guint get_va_surfaces : 1; - guint has_vpp : 1; - guint use_vpp : 1; - guint keep_aspect : 1; + guint get_va_surfaces:1; + guint has_vpp:1; + guint use_vpp:1; + guint keep_aspect:1; }; -struct _GstVaapiPostprocClass { - /*< private >*/ - GstVaapiPluginBaseClass parent_class; +struct _GstVaapiPostprocClass +{ + /*< private >*/ + GstVaapiPluginBaseClass parent_class; }; GType -gst_vaapipostproc_get_type(void) G_GNUC_CONST; +gst_vaapipostproc_get_type (void) G_GNUC_CONST; G_END_DECLS diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 6d99c855fd..6c702b929c 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -36,475 +36,464 @@ #define GST_HELPER_NAME "vaapiupload" #define GST_HELPER_DESC "VA-API video uploader" -GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapi_uploader); +GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapi_uploader); #define GST_CAT_DEFAULT gst_debug_vaapi_uploader -G_DEFINE_TYPE(GstVaapiUploader, gst_vaapi_uploader, G_TYPE_OBJECT) +G_DEFINE_TYPE (GstVaapiUploader, gst_vaapi_uploader, G_TYPE_OBJECT); #define GST_VAAPI_UPLOADER_CAST(obj) \ - ((GstVaapiUploader *)(obj)) + ((GstVaapiUploader *)(obj)) +#define GST_VAAPI_UPLOADER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_VAAPI_TYPE_UPLOADER, \ + GstVaapiUploaderPrivate)) -#define GST_VAAPI_UPLOADER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_UPLOADER, \ - GstVaapiUploaderPrivate)) - -struct _GstVaapiUploaderPrivate { - GstVaapiDisplay *display; - GstCaps *allowed_caps; - GstVaapiVideoPool *images; - GstVideoInfo image_info; - GstVaapiVideoPool *surfaces; - GstVideoInfo surface_info; - guint direct_rendering; +struct _GstVaapiUploaderPrivate +{ + GstVaapiDisplay *display; + GstCaps *allowed_caps; + GstVaapiVideoPool *images; + GstVideoInfo image_info; + GstVaapiVideoPool *surfaces; + GstVideoInfo surface_info; + guint direct_rendering; }; -enum { - PROP_0, +enum +{ + PROP_0, - PROP_DISPLAY, + PROP_DISPLAY, }; static void -gst_vaapi_uploader_destroy(GstVaapiUploader *uploader) +gst_vaapi_uploader_destroy (GstVaapiUploader * uploader) { - GstVaapiUploaderPrivate * const priv = uploader->priv; + GstVaapiUploaderPrivate *const priv = uploader->priv; - gst_caps_replace(&priv->allowed_caps, NULL); - gst_vaapi_video_pool_replace(&priv->images, NULL); - gst_vaapi_video_pool_replace(&priv->surfaces, NULL); - gst_vaapi_display_replace(&priv->display, NULL); + gst_caps_replace (&priv->allowed_caps, NULL); + gst_vaapi_video_pool_replace (&priv->images, NULL); + gst_vaapi_video_pool_replace (&priv->surfaces, NULL); + gst_vaapi_display_replace (&priv->display, NULL); } static gboolean -ensure_display(GstVaapiUploader *uploader, GstVaapiDisplay *display) +ensure_display (GstVaapiUploader * uploader, GstVaapiDisplay * display) { - GstVaapiUploaderPrivate * const priv = uploader->priv; + GstVaapiUploaderPrivate *const priv = uploader->priv; - gst_vaapi_display_replace(&priv->display, display); + gst_vaapi_display_replace (&priv->display, display); + return TRUE; +} + +static gboolean +ensure_image (GstVaapiImage * image) +{ + guint i, num_planes, width, height; + + /* Make the image fully dirty */ + if (!gst_vaapi_image_map (image)) + return FALSE; + + gst_vaapi_image_get_size (image, &width, &height); + + num_planes = gst_vaapi_image_get_plane_count (image); + for (i = 0; i < num_planes; i++) { + guchar *const plane = gst_vaapi_image_get_plane (image, i); + if (plane) + memset (plane, 0, gst_vaapi_image_get_pitch (image, i)); + } + + if (!gst_vaapi_image_unmap (image)) + gst_vaapi_image_unmap (image); + return TRUE; +} + +static gboolean +ensure_allowed_caps (GstVaapiUploader * uploader) +{ + GstVaapiUploaderPrivate *const priv = uploader->priv; + GstVaapiSurface *surface = NULL; + GArray *formats = NULL, *out_formats = NULL; + GstCaps *out_caps; + guint i; + gboolean success = FALSE; + + enum + { WIDTH = 64, HEIGHT = 64 }; + + if (priv->allowed_caps) return TRUE; -} -static gboolean -ensure_image(GstVaapiImage *image) -{ - guint i, num_planes, width, height; + formats = gst_vaapi_display_get_image_formats (priv->display); + if (!formats) + goto cleanup; - /* Make the image fully dirty */ - if (!gst_vaapi_image_map(image)) - return FALSE; + out_formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), + formats->len); + if (!out_formats) + goto cleanup; - gst_vaapi_image_get_size(image, &width, &height); + surface = gst_vaapi_surface_new (priv->display, + GST_VAAPI_CHROMA_TYPE_YUV420, WIDTH, HEIGHT); + if (!surface) + goto cleanup; - num_planes = gst_vaapi_image_get_plane_count(image); - for (i = 0; i < num_planes; i++) { - guchar * const plane = gst_vaapi_image_get_plane(image, i); - if (plane) - memset(plane, 0, gst_vaapi_image_get_pitch(image, i)); - } + for (i = 0; i < formats->len; i++) { + const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); + GstVaapiImage *image; - if (!gst_vaapi_image_unmap(image)) - gst_vaapi_image_unmap(image); - return TRUE; -} + if (format == GST_VIDEO_FORMAT_UNKNOWN) + continue; + image = gst_vaapi_image_new (priv->display, format, WIDTH, HEIGHT); + if (!image) + continue; + if (ensure_image (image) && gst_vaapi_surface_put_image (surface, image)) + g_array_append_val (out_formats, format); + gst_vaapi_object_unref (image); + } -static gboolean -ensure_allowed_caps(GstVaapiUploader *uploader) -{ - GstVaapiUploaderPrivate * const priv = uploader->priv; - GstVaapiSurface *surface = NULL; - GArray *formats = NULL, *out_formats = NULL; - GstCaps *out_caps; - guint i; - gboolean success = FALSE; + out_caps = gst_vaapi_video_format_new_template_caps_from_list (out_formats); + if (!out_caps) + goto cleanup; - enum { WIDTH = 64, HEIGHT = 64 }; - - if (priv->allowed_caps) - return TRUE; - - formats = gst_vaapi_display_get_image_formats(priv->display); - if (!formats) - goto cleanup; - - out_formats = g_array_sized_new(FALSE, FALSE, sizeof(GstVideoFormat), - formats->len); - if (!out_formats) - goto cleanup; - - surface = gst_vaapi_surface_new(priv->display, - GST_VAAPI_CHROMA_TYPE_YUV420, WIDTH, HEIGHT); - if (!surface) - goto cleanup; - - for (i = 0; i < formats->len; i++) { - const GstVideoFormat format = - g_array_index(formats, GstVideoFormat, i); - GstVaapiImage *image; - - if (format == GST_VIDEO_FORMAT_UNKNOWN) - continue; - image = gst_vaapi_image_new(priv->display, format, WIDTH, HEIGHT); - if (!image) - continue; - if (ensure_image(image) && gst_vaapi_surface_put_image(surface, image)) - g_array_append_val(out_formats, format); - gst_vaapi_object_unref(image); - } - - out_caps = gst_vaapi_video_format_new_template_caps_from_list(out_formats); - if (!out_caps) - goto cleanup; - - gst_caps_replace(&priv->allowed_caps, out_caps); - gst_caps_unref(out_caps); - success = TRUE; + gst_caps_replace (&priv->allowed_caps, out_caps); + gst_caps_unref (out_caps); + success = TRUE; cleanup: - if (out_formats) - g_array_unref(out_formats); - if (formats) - g_array_unref(formats); - if (surface) - gst_vaapi_object_unref(surface); - return success; + if (out_formats) + g_array_unref (out_formats); + if (formats) + g_array_unref (formats); + if (surface) + gst_vaapi_object_unref (surface); + return success; } static gboolean -ensure_image_pool(GstVaapiUploader *uploader, GstCaps *caps, - gboolean *caps_changed_ptr) +ensure_image_pool (GstVaapiUploader * uploader, GstCaps * caps, + gboolean * caps_changed_ptr) { - GstVaapiUploaderPrivate * const priv = uploader->priv; - GstVaapiVideoPool *pool; - GstVideoInfo vi; - GstVideoFormat format; - guint width, height; + GstVaapiUploaderPrivate *const priv = uploader->priv; + GstVaapiVideoPool *pool; + GstVideoInfo vi; + GstVideoFormat format; + guint width, height; - if (!gst_video_info_from_caps(&vi, caps)) - return FALSE; + if (!gst_video_info_from_caps (&vi, caps)) + return FALSE; - format = GST_VIDEO_INFO_FORMAT(&vi); - width = GST_VIDEO_INFO_WIDTH(&vi); - height = GST_VIDEO_INFO_HEIGHT(&vi); + format = GST_VIDEO_INFO_FORMAT (&vi); + width = GST_VIDEO_INFO_WIDTH (&vi); + height = GST_VIDEO_INFO_HEIGHT (&vi); - *caps_changed_ptr = - format != GST_VIDEO_INFO_FORMAT(&priv->image_info) || - width != GST_VIDEO_INFO_WIDTH(&priv->image_info) || - height != GST_VIDEO_INFO_HEIGHT(&priv->image_info); - if (!*caps_changed_ptr) - return TRUE; - - pool = gst_vaapi_image_pool_new(priv->display, &vi); - if (!pool) - return FALSE; - - gst_video_info_set_format(&priv->image_info, format, width, height); - gst_vaapi_video_pool_replace(&priv->images, pool); - gst_vaapi_video_pool_unref(pool); + *caps_changed_ptr = + format != GST_VIDEO_INFO_FORMAT (&priv->image_info) || + width != GST_VIDEO_INFO_WIDTH (&priv->image_info) || + height != GST_VIDEO_INFO_HEIGHT (&priv->image_info); + if (!*caps_changed_ptr) return TRUE; + + pool = gst_vaapi_image_pool_new (priv->display, &vi); + if (!pool) + return FALSE; + + gst_video_info_set_format (&priv->image_info, format, width, height); + gst_vaapi_video_pool_replace (&priv->images, pool); + gst_vaapi_video_pool_unref (pool); + return TRUE; } static gboolean -ensure_surface_pool(GstVaapiUploader *uploader, GstCaps *caps, - gboolean *caps_changed_ptr) +ensure_surface_pool (GstVaapiUploader * uploader, GstCaps * caps, + gboolean * caps_changed_ptr) { - GstVaapiUploaderPrivate * const priv = uploader->priv; - GstVaapiVideoPool *pool; - GstVideoInfo vi; - GstVideoFormat format; - guint width, height; + GstVaapiUploaderPrivate *const priv = uploader->priv; + GstVaapiVideoPool *pool; + GstVideoInfo vi; + GstVideoFormat format; + guint width, height; - if (!gst_video_info_from_caps(&vi, caps)) - return FALSE; + if (!gst_video_info_from_caps (&vi, caps)) + return FALSE; - format = GST_VIDEO_INFO_FORMAT(&vi); - width = GST_VIDEO_INFO_WIDTH(&vi); - height = GST_VIDEO_INFO_HEIGHT(&vi); + format = GST_VIDEO_INFO_FORMAT (&vi); + width = GST_VIDEO_INFO_WIDTH (&vi); + height = GST_VIDEO_INFO_HEIGHT (&vi); - *caps_changed_ptr = - format != GST_VIDEO_INFO_FORMAT(&priv->surface_info) || - width != GST_VIDEO_INFO_WIDTH(&priv->surface_info) || - height != GST_VIDEO_INFO_HEIGHT(&priv->surface_info); - if (!*caps_changed_ptr) - return TRUE; - - /* Always try to downsample source buffers to YUV 4:2:0 format as - this saves memory bandwidth for further rendering */ - /* XXX: this also means that visual quality is not preserved */ - if (format != GST_VIDEO_FORMAT_ENCODED) { - const GstVaapiChromaType chroma_type = - gst_vaapi_video_format_get_chroma_type(format); - if (chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) { - const GstVideoFormat image_format = - GST_VIDEO_INFO_FORMAT(&priv->image_info); - GST_INFO("use implicit conversion of %s buffers to NV12 surfaces", - gst_video_format_to_string(image_format)); - gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12, width, height); - } - } - - pool = gst_vaapi_surface_pool_new(priv->display, &vi); - if (!pool) - return FALSE; - - gst_video_info_set_format(&priv->surface_info, format, width, height); - gst_vaapi_video_pool_replace(&priv->surfaces, pool); - gst_vaapi_video_pool_unref(pool); + *caps_changed_ptr = + format != GST_VIDEO_INFO_FORMAT (&priv->surface_info) || + width != GST_VIDEO_INFO_WIDTH (&priv->surface_info) || + height != GST_VIDEO_INFO_HEIGHT (&priv->surface_info); + if (!*caps_changed_ptr) return TRUE; -} -static void -gst_vaapi_uploader_finalize(GObject *object) -{ - gst_vaapi_uploader_destroy(GST_VAAPI_UPLOADER_CAST(object)); - - G_OBJECT_CLASS(gst_vaapi_uploader_parent_class)->finalize(object); -} - -static void -gst_vaapi_uploader_set_property(GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - GstVaapiUploader * const uploader = GST_VAAPI_UPLOADER_CAST(object); - - switch (prop_id) { - case PROP_DISPLAY: - ensure_display(uploader, g_value_get_pointer(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; + /* Always try to downsample source buffers to YUV 4:2:0 format as + this saves memory bandwidth for further rendering */ + /* XXX: this also means that visual quality is not preserved */ + if (format != GST_VIDEO_FORMAT_ENCODED) { + const GstVaapiChromaType chroma_type = + gst_vaapi_video_format_get_chroma_type (format); + if (chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) { + const GstVideoFormat image_format = + GST_VIDEO_INFO_FORMAT (&priv->image_info); + GST_INFO ("use implicit conversion of %s buffers to NV12 surfaces", + gst_video_format_to_string (image_format)); + gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, width, height); } + } + + pool = gst_vaapi_surface_pool_new (priv->display, &vi); + if (!pool) + return FALSE; + + gst_video_info_set_format (&priv->surface_info, format, width, height); + gst_vaapi_video_pool_replace (&priv->surfaces, pool); + gst_vaapi_video_pool_unref (pool); + return TRUE; } static void -gst_vaapi_uploader_get_property(GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +gst_vaapi_uploader_finalize (GObject * object) { - GstVaapiUploader * const uploader = GST_VAAPI_UPLOADER_CAST(object); + gst_vaapi_uploader_destroy (GST_VAAPI_UPLOADER_CAST (object)); - switch (prop_id) { + G_OBJECT_CLASS (gst_vaapi_uploader_parent_class)->finalize (object); +} + +static void +gst_vaapi_uploader_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiUploader *const uploader = GST_VAAPI_UPLOADER_CAST (object); + + switch (prop_id) { case PROP_DISPLAY: - g_value_set_pointer(value, uploader->priv->display); - break; + ensure_display (uploader, g_value_get_pointer (value)); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -gst_vaapi_uploader_class_init(GstVaapiUploaderClass *klass) +gst_vaapi_uploader_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiUploader *const uploader = GST_VAAPI_UPLOADER_CAST (object); - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapi_uploader, - GST_HELPER_NAME, 0, GST_HELPER_DESC); - - g_type_class_add_private(klass, sizeof(GstVaapiUploaderPrivate)); - - object_class->finalize = gst_vaapi_uploader_finalize; - object_class->set_property = gst_vaapi_uploader_set_property; - object_class->get_property = gst_vaapi_uploader_get_property; - - g_object_class_install_property( - object_class, - PROP_DISPLAY, - g_param_spec_pointer( - "display", - "Display", - "The GstVaapiDisplay this object is bound to", - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_pointer (value, uploader->priv->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -gst_vaapi_uploader_init(GstVaapiUploader *uploader) +gst_vaapi_uploader_class_init (GstVaapiUploaderClass * klass) { - GstVaapiUploaderPrivate *priv; + GObjectClass *const object_class = G_OBJECT_CLASS (klass); - priv = GST_VAAPI_UPLOADER_GET_PRIVATE(uploader); - uploader->priv = priv; + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_uploader, + GST_HELPER_NAME, 0, GST_HELPER_DESC); - gst_video_info_init(&priv->image_info); - gst_video_info_init(&priv->surface_info); + g_type_class_add_private (klass, sizeof (GstVaapiUploaderPrivate)); + + object_class->finalize = gst_vaapi_uploader_finalize; + object_class->set_property = gst_vaapi_uploader_set_property; + object_class->get_property = gst_vaapi_uploader_get_property; + + g_object_class_install_property (object_class, + PROP_DISPLAY, + g_param_spec_pointer ("display", + "Display", + "The GstVaapiDisplay this object is bound to", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static void +gst_vaapi_uploader_init (GstVaapiUploader * uploader) +{ + GstVaapiUploaderPrivate *priv; + + priv = GST_VAAPI_UPLOADER_GET_PRIVATE (uploader); + uploader->priv = priv; + + gst_video_info_init (&priv->image_info); + gst_video_info_init (&priv->surface_info); } GstVaapiUploader * -gst_vaapi_uploader_new(GstVaapiDisplay *display) +gst_vaapi_uploader_new (GstVaapiDisplay * display) { - return g_object_new(GST_VAAPI_TYPE_UPLOADER, "display", display, NULL); + return g_object_new (GST_VAAPI_TYPE_UPLOADER, "display", display, NULL); } gboolean -gst_vaapi_uploader_ensure_display( - GstVaapiUploader *uploader, - GstVaapiDisplay *display -) +gst_vaapi_uploader_ensure_display (GstVaapiUploader * uploader, + GstVaapiDisplay * display) { - g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); - g_return_val_if_fail(display != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), FALSE); + g_return_val_if_fail (display != NULL, FALSE); - return ensure_display(uploader,display); + return ensure_display (uploader, display); } gboolean -gst_vaapi_uploader_ensure_caps( - GstVaapiUploader *uploader, - GstCaps *src_caps, - GstCaps *out_caps -) +gst_vaapi_uploader_ensure_caps (GstVaapiUploader * uploader, + GstCaps * src_caps, GstCaps * out_caps) { - GstVaapiUploaderPrivate *priv; - GstVaapiImage *image; - gboolean image_caps_changed, surface_caps_changed; + GstVaapiUploaderPrivate *priv; + GstVaapiImage *image; + gboolean image_caps_changed, surface_caps_changed; - g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); - g_return_val_if_fail(src_caps != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), FALSE); + g_return_val_if_fail (src_caps != NULL, FALSE); - if (!out_caps) - out_caps = src_caps; + if (!out_caps) + out_caps = src_caps; - if (!ensure_image_pool(uploader, src_caps, &image_caps_changed)) - return FALSE; - if (!ensure_surface_pool(uploader, out_caps, &surface_caps_changed)) - return FALSE; - if (!image_caps_changed && !surface_caps_changed) - return TRUE; - - priv = uploader->priv; - priv->direct_rendering = 0; - - /* Check if we can alias source and output buffers (same data_size) */ - image = gst_vaapi_video_pool_get_object(priv->images); - if (image) { - if ((gst_vaapi_image_get_format(image) == - GST_VIDEO_INFO_FORMAT(&priv->image_info)) && - gst_vaapi_image_is_linear(image) && - (gst_vaapi_image_get_data_size(image) == - GST_VIDEO_INFO_SIZE(&priv->image_info))) - priv->direct_rendering = 1; - gst_vaapi_video_pool_put_object(priv->images, image); - } - - GST_INFO("direct-rendering: level %u", priv->direct_rendering); + if (!ensure_image_pool (uploader, src_caps, &image_caps_changed)) + return FALSE; + if (!ensure_surface_pool (uploader, out_caps, &surface_caps_changed)) + return FALSE; + if (!image_caps_changed && !surface_caps_changed) return TRUE; + + priv = uploader->priv; + priv->direct_rendering = 0; + + /* Check if we can alias source and output buffers (same data_size) */ + image = gst_vaapi_video_pool_get_object (priv->images); + if (image) { + if ((gst_vaapi_image_get_format (image) == + GST_VIDEO_INFO_FORMAT (&priv->image_info)) && + gst_vaapi_image_is_linear (image) && + (gst_vaapi_image_get_data_size (image) == + GST_VIDEO_INFO_SIZE (&priv->image_info))) + priv->direct_rendering = 1; + gst_vaapi_video_pool_put_object (priv->images, image); + } + + GST_INFO ("direct-rendering: level %u", priv->direct_rendering); + return TRUE; } gboolean -gst_vaapi_uploader_process( - GstVaapiUploader *uploader, - GstBuffer *src_buffer, - GstBuffer *out_buffer -) +gst_vaapi_uploader_process (GstVaapiUploader * uploader, + GstBuffer * src_buffer, GstBuffer * out_buffer) { - GstVaapiVideoMeta *src_meta, *out_meta; - GstVaapiSurface *surface; - GstVaapiImage *image; + GstVaapiVideoMeta *src_meta, *out_meta; + GstVaapiSurface *surface; + GstVaapiImage *image; - g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); + g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), FALSE); - out_meta = gst_buffer_get_vaapi_video_meta(out_buffer); - if (!out_meta) { - GST_WARNING("expected an output video buffer"); + out_meta = gst_buffer_get_vaapi_video_meta (out_buffer); + if (!out_meta) { + GST_WARNING ("expected an output video buffer"); + return FALSE; + } + + surface = gst_vaapi_video_meta_get_surface (out_meta); + g_return_val_if_fail (surface != NULL, FALSE); + + src_meta = gst_buffer_get_vaapi_video_meta (src_buffer); + if (src_meta) { + /* GstVaapiVideoBuffer with mapped VA image */ + image = gst_vaapi_video_meta_get_image (src_meta); + if (!image || !gst_vaapi_image_unmap (image)) + return FALSE; + } else { + /* Regular GstBuffer that needs to be uploaded to a VA image */ + image = gst_vaapi_video_meta_get_image (out_meta); + if (!image) { + image = gst_vaapi_video_pool_get_object (uploader->priv->images); + if (!image) return FALSE; + gst_vaapi_video_meta_set_image (out_meta, image); } + if (!gst_vaapi_image_update_from_buffer (image, src_buffer, NULL)) + return FALSE; + } + g_return_val_if_fail (image != NULL, FALSE); - surface = gst_vaapi_video_meta_get_surface(out_meta); - g_return_val_if_fail(surface != NULL, FALSE); + if (!gst_vaapi_surface_put_image (surface, image)) { + GST_WARNING ("failed to upload YUV buffer to VA surface"); + return FALSE; + } - src_meta = gst_buffer_get_vaapi_video_meta(src_buffer); - if (src_meta) { - /* GstVaapiVideoBuffer with mapped VA image */ - image = gst_vaapi_video_meta_get_image(src_meta); - if (!image || !gst_vaapi_image_unmap(image)) - return FALSE; - } - else { - /* Regular GstBuffer that needs to be uploaded to a VA image */ - image = gst_vaapi_video_meta_get_image(out_meta); - if (!image) { - image = gst_vaapi_video_pool_get_object(uploader->priv->images); - if (!image) - return FALSE; - gst_vaapi_video_meta_set_image(out_meta, image); - } - if (!gst_vaapi_image_update_from_buffer(image, src_buffer, NULL)) - return FALSE; - } - g_return_val_if_fail(image != NULL, FALSE); - - if (!gst_vaapi_surface_put_image(surface, image)) { - GST_WARNING("failed to upload YUV buffer to VA surface"); - return FALSE; - } - - /* Map again for next uploads */ - if (!gst_vaapi_image_map(image)) - return FALSE; - return TRUE; + /* Map again for next uploads */ + if (!gst_vaapi_image_map (image)) + return FALSE; + return TRUE; } GstCaps * -gst_vaapi_uploader_get_caps(GstVaapiUploader *uploader) +gst_vaapi_uploader_get_caps (GstVaapiUploader * uploader) { - g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), NULL); + g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), NULL); - if (!ensure_allowed_caps(uploader)) - return NULL; - return uploader->priv->allowed_caps; + if (!ensure_allowed_caps (uploader)) + return NULL; + return uploader->priv->allowed_caps; } GstBuffer * -gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader) +gst_vaapi_uploader_get_buffer (GstVaapiUploader * uploader) { - GstVaapiUploaderPrivate *priv; - GstVaapiImage *image; - GstVaapiVideoMeta *meta; - GstVaapiSurfaceProxy *proxy; - GstBuffer *buffer; + GstVaapiUploaderPrivate *priv; + GstVaapiImage *image; + GstVaapiVideoMeta *meta; + GstVaapiSurfaceProxy *proxy; + GstBuffer *buffer; - g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), NULL); + g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), NULL); - priv = uploader->priv; + priv = uploader->priv; - buffer = gst_vaapi_video_buffer_new_from_pool(priv->images); - if (!buffer) { - GST_WARNING("failed to allocate video buffer"); - goto error; - } + buffer = gst_vaapi_video_buffer_new_from_pool (priv->images); + if (!buffer) { + GST_WARNING ("failed to allocate video buffer"); + goto error; + } - proxy = gst_vaapi_surface_proxy_new_from_pool( - GST_VAAPI_SURFACE_POOL(priv->surfaces)); - if (!proxy) { - GST_WARNING("failed to allocate VA surface"); - goto error; - } + proxy = + gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL + (priv->surfaces)); + if (!proxy) { + GST_WARNING ("failed to allocate VA surface"); + goto error; + } - meta = gst_buffer_get_vaapi_video_meta(buffer); - gst_vaapi_video_meta_set_surface_proxy(meta, proxy); - gst_vaapi_surface_proxy_unref(proxy); - - image = gst_vaapi_video_meta_get_image(meta); - if (!gst_vaapi_image_map(image)) { - GST_WARNING("failed to map VA image"); - goto error; - } + meta = gst_buffer_get_vaapi_video_meta (buffer); + gst_vaapi_video_meta_set_surface_proxy (meta, proxy); + gst_vaapi_surface_proxy_unref (proxy); + image = gst_vaapi_video_meta_get_image (meta); + if (!gst_vaapi_image_map (image)) { + GST_WARNING ("failed to map VA image"); + goto error; + } #if !GST_CHECK_VERSION(1,0,0) - GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0); - GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image); + GST_BUFFER_DATA (buffer) = gst_vaapi_image_get_plane (image, 0); + GST_BUFFER_SIZE (buffer) = gst_vaapi_image_get_data_size (image); #endif - return buffer; + return buffer; error: - gst_buffer_unref(buffer); - return buffer; + gst_buffer_unref (buffer); + return buffer; } gboolean -gst_vaapi_uploader_has_direct_rendering(GstVaapiUploader *uploader) +gst_vaapi_uploader_has_direct_rendering (GstVaapiUploader * uploader) { - g_return_val_if_fail(GST_VAAPI_IS_UPLOADER(uploader), FALSE); + g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), FALSE); - return uploader->priv->direct_rendering; + return uploader->priv->direct_rendering; } diff --git a/gst/vaapi/gstvaapiuploader.h b/gst/vaapi/gstvaapiuploader.h index c52af73a79..1d9f94b0ea 100644 --- a/gst/vaapi/gstvaapiuploader.h +++ b/gst/vaapi/gstvaapiuploader.h @@ -30,87 +30,73 @@ G_BEGIN_DECLS #define GST_VAAPI_TYPE_UPLOADER \ - (gst_vaapi_uploader_get_type()) - -#define GST_VAAPI_UPLOADER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_UPLOADER, \ - GstVaapiUploader)) - -#define GST_VAAPI_UPLOADER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_UPLOADER, \ - GstVaapiUploaderClass)) - + (gst_vaapi_uploader_get_type ()) +#define GST_VAAPI_UPLOADER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_UPLOADER, \ + GstVaapiUploader)) +#define GST_VAAPI_UPLOADER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_UPLOADER, \ + GstVaapiUploaderClass)) #define GST_VAAPI_IS_UPLOADER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_UPLOADER)) - + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_UPLOADER)) #define GST_VAAPI_IS_UPLOADER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_UPLOADER)) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_UPLOADER)) +#define GST_VAAPI_UPLOADER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_UPLOADER, \ + GstVaapiUploaderClass)) -#define GST_VAAPI_UPLOADER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_UPLOADER, \ - GstVaapiUploaderClass)) +typedef struct _GstVaapiUploader GstVaapiUploader; +typedef struct _GstVaapiUploaderPrivate GstVaapiUploaderPrivate; +typedef struct _GstVaapiUploaderClass GstVaapiUploaderClass; -typedef struct _GstVaapiUploader GstVaapiUploader; -typedef struct _GstVaapiUploaderPrivate GstVaapiUploaderPrivate; -typedef struct _GstVaapiUploaderClass GstVaapiUploaderClass; +struct _GstVaapiUploader +{ + /*< private >*/ + GObject parent_instance; -struct _GstVaapiUploader { - /*< private >*/ - GObject parent_instance; - - GstVaapiUploaderPrivate *priv; + GstVaapiUploaderPrivate *priv; }; -struct _GstVaapiUploaderClass { - /*< private >*/ - GObjectClass parent_class; +struct _GstVaapiUploaderClass +{ + /*< private >*/ + GObjectClass parent_class; }; G_GNUC_INTERNAL GType -gst_vaapi_uploader_get_type(void) G_GNUC_CONST; +gst_vaapi_uploader_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstVaapiUploader * -gst_vaapi_uploader_new(GstVaapiDisplay *display); +gst_vaapi_uploader_new (GstVaapiDisplay * display); G_GNUC_INTERNAL gboolean -gst_vaapi_uploader_ensure_display( - GstVaapiUploader *uploader, - GstVaapiDisplay *display -); +gst_vaapi_uploader_ensure_display (GstVaapiUploader * uploader, + GstVaapiDisplay * display); G_GNUC_INTERNAL gboolean -gst_vaapi_uploader_ensure_caps( - GstVaapiUploader *uploader, - GstCaps *src_caps, - GstCaps *out_caps -); +gst_vaapi_uploader_ensure_caps (GstVaapiUploader * uploader, + GstCaps * src_caps, GstCaps * out_caps); G_GNUC_INTERNAL gboolean -gst_vaapi_uploader_process( - GstVaapiUploader *uploader, - GstBuffer *src_buffer, - GstBuffer *out_buffer -); +gst_vaapi_uploader_process (GstVaapiUploader * uploader, + GstBuffer * src_buffer, GstBuffer * out_buffer); G_GNUC_INTERNAL GstCaps * -gst_vaapi_uploader_get_caps(GstVaapiUploader *uploader); +gst_vaapi_uploader_get_caps (GstVaapiUploader * uploader); G_GNUC_INTERNAL GstBuffer * -gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader); +gst_vaapi_uploader_get_buffer (GstVaapiUploader * uploader); G_GNUC_INTERNAL gboolean -gst_vaapi_uploader_has_direct_rendering(GstVaapiUploader *uploader); +gst_vaapi_uploader_has_direct_rendering (GstVaapiUploader * uploader); G_END_DECLS From 0525f56ac538593171872510bdad32a30eed1e1f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 24 Nov 2014 14:25:33 +0100 Subject: [PATCH 1806/3781] vaapipostproc: fix check for compatible src pad capsfilters. When an explicit output video format is selected, from an src pad capsfilter, make sure that the downstream element actually supports that format. In particular, fix crash with the following pipelines: ... ! vaapipostproc ! video/x-raw,format=XXX ! xvimagesink ; where XXX is a format not supported by xvimagesink. While doing so, also reduce the set of src pad filter caps to the actual set of allowed src pad caps. --- gst/vaapi/gstvaapipostproc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index fb014d16f5..8633b33ed0 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1127,18 +1127,17 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, if (postproc->format != DEFAULT_FORMAT) out_format = postproc->format; else { - GstCaps *peer_caps, *filter_caps; + GstCaps *peer_caps; GstVideoInfo peer_vi; - filter_caps = - gst_caps_from_string (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL)); peer_caps = gst_pad_peer_query_caps (GST_BASE_TRANSFORM_SRC_PAD (trans), - filter_caps); + postproc->allowed_srcpad_caps); + if (gst_caps_is_empty (peer_caps)) + return peer_caps; if (!gst_caps_is_fixed (peer_caps)) peer_caps = gst_caps_fixate (peer_caps); gst_video_info_from_caps (&peer_vi, peer_caps); out_format = GST_VIDEO_INFO_FORMAT (&peer_vi); - gst_caps_unref (filter_caps); if (peer_caps) gst_caps_unref (peer_caps); } From 4be370f9ed13b5a00eb764dc62dc9125d416fa9d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 24 Nov 2014 15:14:37 +0100 Subject: [PATCH 1807/3781] vaapipostproc: fix out caps for GLMemory. If the best downstream capsfeature turns out to be GLMemory, then make sure to propagate RGBA video format in caps to that element. This fixes the following pipeline: ... ! vaapipostproc ! glimagesink. --- gst/vaapi/gstvaapipostproc.c | 44 ++++++++++++------------------------ 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 8633b33ed0..2d051c8a25 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1074,7 +1074,7 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); GstVideoInfo vi; - GstVideoFormat format, out_format; + GstVideoFormat out_format; GstCaps *out_caps; #if GST_CHECK_VERSION(1,1,0) GstVaapiCapsFeature feature; @@ -1116,7 +1116,9 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, GST_VIDEO_INFO_INTERLACE_MODE (&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; // Update size from user-specified parameters - format = GST_VIDEO_INFO_FORMAT (&vi); + find_best_size (postproc, &vi, &width, &height); + + // Update format from user-specified parameters #if GST_CHECK_VERSION(1,1,0) /* XXX: this is a workaround until auto-plugging is fixed when * format=ENCODED + memory:VASurface caps feature are provided. @@ -1141,10 +1143,20 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, if (peer_caps) gst_caps_unref (peer_caps); } + + feature = + gst_vaapi_find_preferred_caps_feature (GST_BASE_TRANSFORM_SRC_PAD (trans), + out_format); + switch (feature) { + case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: + out_format = GST_VIDEO_FORMAT_RGBA; + break; + default: + break; + } #else out_format = GST_VIDEO_FORMAT_ENCODED; #endif - find_best_size (postproc, &vi, &width, &height); gst_video_info_change_format (&vi, out_format, width, height); #if GST_CHECK_VERSION(1,1,0) @@ -1152,37 +1164,11 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, if (!out_caps) return NULL; - feature = - gst_vaapi_find_preferred_caps_feature (GST_BASE_TRANSFORM_SRC_PAD (trans), - out_format); if (feature) { feature_str = gst_vaapi_caps_feature_to_string (feature); if (feature_str) gst_caps_set_features (out_caps, 0, gst_caps_features_new (feature_str, NULL)); - - if (out_format == GST_VIDEO_FORMAT_ENCODED && - feature != GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) { - GstCaps *sink_caps, *peer_caps = - gst_pad_peer_query_caps (GST_BASE_TRANSFORM_SRC_PAD (trans), - postproc->allowed_srcpad_caps); - - if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) - format = GST_VIDEO_FORMAT_RGBA; - - gst_video_info_change_format (&vi, format, width, height); - sink_caps = gst_video_info_to_caps (&vi); - if (sink_caps) { - if (feature_str) - gst_caps_set_features (sink_caps, 0, - gst_caps_features_new (feature_str, NULL)); - if (gst_caps_can_intersect (peer_caps, sink_caps)) - gst_caps_set_simple (out_caps, "format", G_TYPE_STRING, - gst_video_format_to_string (format), NULL); - gst_caps_unref (sink_caps); - } - gst_caps_unref (peer_caps); - } } #else /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not From 669e33418e96d652cba96ff784f00f1171d67577 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 25 Nov 2014 11:41:49 +0100 Subject: [PATCH 1808/3781] encoder: h264: fix profile limits. Fix ensure_profile_limits() to lower profile to the desired limits, only if the latter are actually known and the profile needed to be changed to fit. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 3277f00017..ee740207f9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1005,6 +1005,8 @@ ensure_profile_limits (GstVaapiEncoderH264 * encoder) GST_WARNING ("lowering coding tools to meet target decoder constraints"); + profile = GST_VAAPI_PROFILE_UNKNOWN; + /* Try Main profile coding tools */ if (encoder->max_profile_idc < 100) { encoder->use_dct8x8 = FALSE; @@ -1018,8 +1020,10 @@ ensure_profile_limits (GstVaapiEncoderH264 * encoder) profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; } - encoder->profile = profile; - encoder->profile_idc = encoder->max_profile_idc; + if (profile) { + encoder->profile = profile; + encoder->profile_idc = encoder->max_profile_idc; + } return TRUE; } From 0508e13ddfd03e5f7a8e06273bba70925a523c1d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 25 Nov 2014 11:46:12 +0100 Subject: [PATCH 1809/3781] decoder: mpeg4: fix uninitialized variables. Fix gst_vaapi_decoder_mpeg4_parse() to initialize the packet type to GST_MPEG4_USER_DATA so that a parse error would result in skipping that packet. Also fix gst_vaapi_decoder_mpeg4_decode_codec_data() to initialize status to GST_VAAPI_DECODER_STATUS_SUCCESS. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 4f80f7f9b6..2f2620bec6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -957,7 +957,7 @@ gst_vaapi_decoder_mpeg4_decode_codec_data(GstVaapiDecoder *base_decoder, { GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); - GstVaapiDecoderStatus status; + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; guchar *buf; guint pos, buf_size; @@ -1033,6 +1033,7 @@ gst_vaapi_decoder_mpeg4_parse(GstVaapiDecoder *base_decoder, if (!buf) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + packet.type = GST_MPEG4_USER_DATA; if (priv->is_svh) result = gst_h263_parse(&packet, buf, 0, size); else From 88b481e5306177f4cde2d9787beda89735c06a20 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 27 Nov 2014 11:13:20 +0200 Subject: [PATCH 1810/3781] encoder: h264: fix pixel-aspect-ratio in encoded stream. Really report sample aspect ratio (SAR) as present, and make it match what we have obtained from the user as pixel-aspect-ratio (PAR). i.e. really make sure VUI parameter aspect_ratio_info_present_flag is set to TRUE and that the indication from aspect_ratio_idc is Extended_SAR. This is a leftover from git commit a12662f. https://bugzilla.gnome.org/show_bug.cgi?id=740360 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index ee740207f9..d2afd5f434 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1701,9 +1701,10 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) /* VUI parameters are always set, at least for timing_info (framerate) */ seq_param->vui_parameters_present_flag = TRUE; if (seq_param->vui_parameters_present_flag) { - seq_param->vui_fields.bits.aspect_ratio_info_present_flag = FALSE; + seq_param->vui_fields.bits.aspect_ratio_info_present_flag = TRUE; if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); + seq_param->aspect_ratio_idc = 0xff; seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip); seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip); } From 267465d7d0824753c5e54a4802d8c51546b546f3 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 27 Nov 2014 11:14:50 +0200 Subject: [PATCH 1811/3781] vaapisink: Protect the X11 API invokations with proper locking https://bugzilla.gnome.org/show_bug.cgi?id=739808 --- gst/vaapi/gstvaapisink.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index a1e1616397..dbd8388d1f 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -456,9 +456,11 @@ gst_vaapisink_x11_pre_start_event_thread (GstVaapiSink * sink) ExposureMask | StructureNotifyMask); if (sink->window) { + gst_vaapi_display_lock (GST_VAAPI_DISPLAY (display)); XSelectInput (gst_vaapi_display_x11_get_display (display), gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (sink->window)), x11_event_mask); + gst_vaapi_display_unlock (GST_VAAPI_DISPLAY (display)); } return TRUE; } @@ -470,8 +472,10 @@ gst_vaapisink_x11_pre_stop_event_thread (GstVaapiSink * sink) GST_VAAPI_DISPLAY_X11 (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); if (sink->window) { + gst_vaapi_display_lock (GST_VAAPI_DISPLAY (display)); XSelectInput (gst_vaapi_display_x11_get_display (display), gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (sink->window)), 0); + gst_vaapi_display_unlock (GST_VAAPI_DISPLAY (display)); } return TRUE; } From 7e4e6fc019c9d6b8528093f19cba3c8c027bfc77 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 27 Nov 2014 11:21:03 +0200 Subject: [PATCH 1812/3781] encoder: h264: Provide intra_idr_period value for VAEncSequenceParameterBufferH264 https://bugzilla.gnome.org/show_bug.cgi?id=734993 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index d2afd5f434..1997c45ac8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1637,6 +1637,7 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) seq_param->seq_parameter_set_id = encoder->view_idx; seq_param->level_idc = encoder->level_idc; seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); + seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq_param->ip_period = 1 + encoder->num_bframes; seq_param->bits_per_second = encoder->bitrate_bits; From 8bf8f1104d5725536243f44c0330144c3ba1a428 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 27 Nov 2014 12:11:03 +0200 Subject: [PATCH 1813/3781] encoder: h264: Fix the period between I/P frames If the key-frame period is set as one, then ip_period shuld be zero https://bugzilla.gnome.org/show_bug.cgi?id=734992 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 1997c45ac8..203177e9af 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1639,6 +1639,8 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq_param->ip_period = 1 + encoder->num_bframes; + seq_param->ip_period = seq_param->intra_period > 1 ? + (1 + encoder->num_bframes) : 0; seq_param->bits_per_second = encoder->bitrate_bits; seq_param->max_num_ref_frames = ref_pool->max_ref_frames; From 6e395c60acd604055f37af2b4cba82c03e1acb10 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 15 Jan 2015 00:00:16 +0200 Subject: [PATCH 1814/3781] codecparsers: update to gst-vaapi-branch commit 191cb2f 347605a: h264parse: expose compatible profiles to downstream d1ea97e: h264parse: Fix periodic SPS/PPS sending work after a seek 24a3126: Revert "h264parse: expose compatible profiles to downstream" 8661740: h264parse: expose compatible profiles to downstream 8b7ef3f: codecparsers: fix some compiler warnings --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 3d05d9f272..191cb2f08d 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 3d05d9f272c4a851d199732b8d47afbf3e6e83ea +Subproject commit 191cb2f08d4cd1a243c272f74ee7faeb634c5eef From 09dcb1e0f755683cfac69a296f8e459d32a23009 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 15 Jan 2015 16:14:13 +0100 Subject: [PATCH 1815/3781] vaapivideomemory: don't crash when trying to allocate 0x0 images. In some occasions, a buffer pool is created for pre-initialization purposes regardless of whether a valid image size is available or not. However, during actual decode stage, the vaapidecode element is expected to update the srcpad caps with the new dimensions, thus also triggering a reset of the underlying bufferpool. --- gst/vaapi/gstvaapivideomemory.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 454851a359..184d78d27f 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -60,6 +60,8 @@ get_image_data (GstVaapiImage * image) static GstVaapiImage * new_image (GstVaapiDisplay * display, const GstVideoInfo * vip) { + if (!GST_VIDEO_INFO_WIDTH (vip) || !GST_VIDEO_INFO_HEIGHT (vip)) + return NULL; return gst_vaapi_image_new (display, GST_VIDEO_INFO_FORMAT (vip), GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); } From 0777f357aa43365c73399d121bc27bdb971d0e61 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 15 Jan 2015 16:19:59 +0100 Subject: [PATCH 1816/3781] vaapidecode: always reset decoder on ::set_format(). Split GstVideoDecoder::set_format() handler to first update the sink pad caps and reset the active VA decoder instance based on those, and then update the src pad caps whenever possible, e.g. when the caps specify a valid video resolution. --- gst/vaapi/gstvaapidecode.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index db67323844..d39e84ea6e 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -151,7 +151,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, state = gst_video_decoder_set_output_state(vdec, format, ref_state->info.width, ref_state->info.height, (GstVideoCodecState *)ref_state); - if (!state) + if (!state || state->info.width == 0 || state->info.height == 0) return FALSE; vi = &state->info; @@ -735,15 +735,17 @@ gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) if (!gst_vaapidecode_update_sink_caps(decode, state->caps)) return FALSE; - if (!gst_vaapidecode_update_src_caps(decode, state)) - return FALSE; - if (!gst_video_decoder_negotiate(vdec)) - return FALSE; - if (!gst_vaapi_plugin_base_set_caps(plugin, decode->sinkpad_caps, - decode->srcpad_caps)) + if (!gst_vaapi_plugin_base_set_caps(plugin, decode->sinkpad_caps, NULL)) return FALSE; if (!gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, FALSE)) return FALSE; + + if (gst_vaapidecode_update_src_caps(decode, state)) { + if (!gst_video_decoder_negotiate(vdec)) + return FALSE; + if (!gst_vaapi_plugin_base_set_caps(plugin, NULL, decode->srcpad_caps)) + return FALSE; + } return TRUE; } From b8744f5b9acff3b57e0fa6d8654fb15a1bd7c441 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 15 Jan 2015 16:23:24 +0100 Subject: [PATCH 1817/3781] vaapidecode: commit updated srcpad caps to base plugin. Make sure that the GstVaapiPluginBase instance receives the new src pad caps whenever they get updated from within the GstVaapiDecoder decode routines. This also ensures that downstream elements receive correctly sized SW decoded buffers if needed. https://bugs.tizen.org/jira/browse/TC-114 --- gst/vaapi/gstvaapidecode.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d39e84ea6e..970c35ea40 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -115,11 +115,16 @@ gst_vaapi_decoder_state_changed(GstVaapiDecoder *decoder, { GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data); GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec); g_assert(decode->decoder == decoder); - gst_vaapidecode_update_src_caps(decode, codec_state); - gst_video_decoder_negotiate(vdec); + if (gst_vaapidecode_update_src_caps(decode, codec_state)) { + if (!gst_video_decoder_negotiate(vdec)) + return; + if (!gst_vaapi_plugin_base_set_caps(plugin, NULL, decode->srcpad_caps)) + return; + } } static inline gboolean From 09bb0d4b5d5fa7b6c8821c7bcac96b5a068158ee Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 19 Jan 2015 11:30:12 +0200 Subject: [PATCH 1818/3781] Fix compilation error if there is no GL/gl.h header file installed --- gst/vaapi/gstvaapivideometa_texture.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index de36bb864c..5a1a824ffc 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -26,10 +26,12 @@ #include "gst/vaapi/sysdeps.h" #include "gstvaapivideometa.h" -#include "gstvaapivideometa_texture.h" #include "gstvaapipluginutil.h" #if GST_CHECK_VERSION(1,1,0) && USE_GLX + +#include "gstvaapivideometa_texture.h" + struct _GstVaapiVideoMetaTexture { GstVaapiTexture *texture; From d5f9414975ba02aa1a175769a8841975ca49650b Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 21 Jan 2015 18:26:12 +0200 Subject: [PATCH 1819/3781] codecparsers: update to gst-vaapi-branch commit d3b5c1b 8194cac: h264parse: parse SPS subset 64b7f52: h264parse: expose stereo-high profile 774360a: h264parse: add initial support for MVC NAL units 258478f: h264parser: fix stack smashing --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 191cb2f08d..d3b5c1bf5d 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 191cb2f08d4cd1a243c272f74ee7faeb634c5eef +Subproject commit d3b5c1bf5dde36ab27110edbc5ced84b9bb07a63 From ad2941c44b2a938a31ece1a41474dab687b2cd8f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 21 Jan 2015 18:31:22 +0200 Subject: [PATCH 1820/3781] h264parse: drop patches merged upstream. 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch --- ...dd-initial-support-for-MVC-NAL-units.patch | 95 ------------------- patches/videoparsers/series.frag | 1 - 2 files changed, 96 deletions(-) delete mode 100644 patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch diff --git a/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch b/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch deleted file mode 100644 index e66d947bb4..0000000000 --- a/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch +++ /dev/null @@ -1,95 +0,0 @@ -From b1974b68fac0dad1c76ab74f0b6b3d9ff99b6f27 Mon Sep 17 00:00:00 2001 -From: Sreerenj Balachandran -Date: Tue, 19 Mar 2013 14:23:00 +0200 -Subject: [PATCH 8/8] h264parse: add initial support for MVC NAL units. - -Initial support for MVC NAL units. It is only needed to propagate the -complete set of NAL units downstream at this time. - -https://bugzilla.gnome.org/show_bug.cgi?id=696135 - -Signed-off-by: Sreerenj Balachandran -Signed-off-by: Gwenole Beauchesne ---- - gst/vaapi/gsth264parse.c | 20 +++++++++++++++----- - 1 file changed, 15 insertions(+), 5 deletions(-) - -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 413a227..b4f20f7 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -433,7 +433,7 @@ gst_h264_parser_store_nal (GstH264Parse * h264parse, guint id, - GstBuffer *buf, **store; - guint size = nalu->size, store_size; - -- if (naltype == GST_H264_NAL_SPS) { -+ if (naltype == GST_H264_NAL_SPS || naltype == GST_H264_NAL_SUBSET_SPS) { - store_size = GST_H264_MAX_SPS_COUNT; - store = h264parse->sps_nals; - GST_DEBUG_OBJECT (h264parse, "storing sps %u", id); -@@ -551,10 +551,16 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - nal_type, _nal_name (nal_type), nalu->size); - - switch (nal_type) { -+ case GST_H264_NAL_SUBSET_SPS: -+ if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS)) -+ return FALSE; -+ goto process_sps; -+ - case GST_H264_NAL_SPS: - /* reset state, everything else is obsolete */ - h264parse->state = 0; - -+ process_sps: - pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps, TRUE); - /* arranged for a fallback sps.id, so use that one and only warn */ - if (pres != GST_H264_PARSER_OK) { -@@ -631,6 +637,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - case GST_H264_NAL_SLICE_DPB: - case GST_H264_NAL_SLICE_DPC: - case GST_H264_NAL_SLICE_IDR: -+ case GST_H264_NAL_SLICE_EXT: - /* expected state: got-sps|got-pps (valid picture headers) */ - h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; - if (!GST_H264_PARSE_STATE_VALID (h264parse, -@@ -638,13 +645,15 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) - return FALSE; - - /* don't need to parse the whole slice (header) here */ -- if (*(nalu->data + nalu->offset + 1) & 0x80) { -+ if (*(nalu->data + nalu->offset + nalu->header_bytes) & 0x80) { - /* means first_mb_in_slice == 0 */ - /* real frame data */ - GST_DEBUG_OBJECT (h264parse, "first_mb_in_slice = 0"); - h264parse->frame_start = TRUE; - } - GST_DEBUG_OBJECT (h264parse, "frame start: %i", h264parse->frame_start); -+ if (nal_type == GST_H264_NAL_SLICE_EXT && !GST_H264_IS_MVC_NALU (nalu)) -+ break; - { - GstH264SliceHdr slice; - -@@ -741,8 +750,9 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data, - * and also works with broken frame_num in NAL - * (where spec-wise would fail) */ - nal_type = nnalu.type; -- complete = h264parse->picture_start && (nal_type >= GST_H264_NAL_SEI && -- nal_type <= GST_H264_NAL_AU_DELIMITER); -+ complete = h264parse->picture_start && ((nal_type >= GST_H264_NAL_SEI && -+ nal_type <= GST_H264_NAL_AU_DELIMITER) || -+ (nal_type >= 14 && nal_type <= 18)); - - GST_LOG_OBJECT (h264parse, "next nal type: %d %s", nal_type, - _nal_name (nal_type)); -@@ -750,7 +760,7 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data, - || nal_type == GST_H264_NAL_SLICE_DPA - || nal_type == GST_H264_NAL_SLICE_IDR) && - /* first_mb_in_slice == 0 considered start of frame */ -- (nnalu.data[nnalu.offset + 1] & 0x80); -+ (nnalu.data[nnalu.offset + nnalu.header_bytes] & 0x80); - - GST_LOG_OBJECT (h264parse, "au complete: %d", complete); - --- -1.7.9.5 - diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index f9aac326de..32fc5380c4 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -4,5 +4,4 @@ videoparsers_patches_base = \ 0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch \ 0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch \ 0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ - 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch \ $(NULL) From cffe87df89870ce7a68dc5bc39826bb66f817a57 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 27 Jan 2015 12:38:45 +0200 Subject: [PATCH 1821/3781] gstvaapiencoder: Fix the negotiation issue with _ENCODED format handling Don't error out for the video format GST_VIDEO_FORMAT_ENCODED with in gstvaapiencoder, since the vaaapi context creation (gstvaapicontext.c) can still use the default chroma type which is YUV420. https://bugzilla.gnome.org/show_bug.cgi?id=743567 https://bugzilla.gnome.org/show_bug.cgi?id=743035 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 520bea4e36..430da1e50e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -559,7 +559,7 @@ set_context_info (GstVaapiEncoder * encoder) cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); cip->ref_frames = encoder->num_ref_frames; - if (!cip->chroma_type) + if (!cip->chroma_type && (format != GST_VIDEO_FORMAT_ENCODED)) goto error_unsupported_format; memset (config, 0, sizeof (*config)); From b7d7a0197d6d92a557a9914af2a644c16235584c Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Tue, 27 Jan 2015 14:50:12 +0200 Subject: [PATCH 1822/3781] vaapidecode: don't print an error message for GST_FLOW_FLUSHING --- gst/vaapi/gstvaapidecode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 970c35ea40..a9c2462080 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -261,7 +261,8 @@ gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) /* ERRORS */ error_decode_loop: { - GST_ERROR("decode loop error %d", decode->decoder_loop_status); + if (decode->decoder_loop_status != GST_FLOW_FLUSHING) + GST_ERROR("decode loop error %d", decode->decoder_loop_status); gst_video_decoder_drop_frame(vdec, frame); return decode->decoder_loop_status; } From 22d1acb6d2f754fb851bd0f2fc535adf81b37d0b Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Tue, 27 Jan 2015 16:06:02 +0200 Subject: [PATCH 1823/3781] vaapipostproc: clear state on stop Otherwise restarting may fail because the state of vaapipluginbase and vaapipostproc don't match. e.g. gst_vaapipostproc_set_caps() will skip initailization and not call gst_vaapi_plugin_base_set_caps() --- gst/vaapi/gstvaapipostproc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 2d051c8a25..756491b3c6 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -334,6 +334,12 @@ gst_vaapipostproc_stop (GstBaseTransform * trans) ds_reset (&postproc->deinterlace_state); gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (postproc)); postproc->filter_pool_active = FALSE; + + postproc->field_duration = GST_CLOCK_TIME_NONE; + gst_video_info_init(&postproc->sinkpad_info); + gst_video_info_init(&postproc->srcpad_info); + gst_video_info_init(&postproc->filter_pool_info); + return TRUE; } From bee7460f3541f5eb3f6511ca8d74c3ce6533bf62 Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Tue, 27 Jan 2015 16:25:21 +0200 Subject: [PATCH 1824/3781] pluginutil: Fix clearing of subtitle overlay dvbsuboverlay signals no subtitles present by not setting GstVideoOverlayCompositionMeta on a buffer. Detect this, and remove subtitles whenever we have no overlay composition to hand. Signed-off-by: Simon Farnsworth --- gst/vaapi/gstvaapipluginutil.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 7b0ced4c8b..21f7e03dd7 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -347,17 +347,14 @@ gst_vaapi_apply_composition (GstVaapiSurface * surface, GstBuffer * buffer) #if GST_CHECK_VERSION(1,0,0) GstVideoOverlayCompositionMeta *const cmeta = gst_buffer_get_video_overlay_composition_meta (buffer); - GstVideoOverlayComposition *composition; + GstVideoOverlayComposition *composition = NULL; - if (!cmeta) - return TRUE; - composition = cmeta->overlay; + if (cmeta) + composition = cmeta->overlay; #else GstVideoOverlayComposition *const composition = gst_video_buffer_get_overlay_composition (buffer); #endif - if (!composition) - return TRUE; return gst_vaapi_surface_set_subpictures_from_composition (surface, composition, TRUE); } From c2afdb4650185b0cb337b354ce133cea1fd73309 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 2 Dec 2014 14:15:49 +0100 Subject: [PATCH 1825/3781] libs: re-indent all GstVaapiObject related source code. Re-indent and provide additional minor cosmetical changes to the GstVaapiMiniObject and GstVaapiObject source files. --- gst-libs/gst/vaapi/gstvaapiminiobject.c | 114 +++++++++++----------- gst-libs/gst/vaapi/gstvaapiminiobject.h | 60 +++++++----- gst-libs/gst/vaapi/gstvaapiobject.c | 94 +++++++++--------- gst-libs/gst/vaapi/gstvaapiobject.h | 22 ++--- gst-libs/gst/vaapi/gstvaapiobject_priv.h | 118 +++++++++++------------ 5 files changed, 210 insertions(+), 198 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.c b/gst-libs/gst/vaapi/gstvaapiminiobject.c index f38bdf7298..11fb769758 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.c @@ -1,7 +1,7 @@ /* * gstvaapiminiobject.c - A lightweight reference counted object * - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or @@ -24,17 +24,17 @@ #include "gstvaapiminiobject.h" static void -gst_vaapi_mini_object_free(GstVaapiMiniObject *object) +gst_vaapi_mini_object_free (GstVaapiMiniObject * object) { - const GstVaapiMiniObjectClass * const klass = object->object_class; + const GstVaapiMiniObjectClass *const klass = object->object_class; - g_atomic_int_inc(&object->ref_count); + g_atomic_int_inc (&object->ref_count); - if (klass->finalize) - klass->finalize(object); + if (klass->finalize) + klass->finalize (object); - if (G_LIKELY(g_atomic_int_dec_and_test(&object->ref_count))) - g_slice_free1(klass->size, object); + if (G_LIKELY (g_atomic_int_dec_and_test (&object->ref_count))) + g_slice_free1 (klass->size, object); } /** @@ -52,27 +52,27 @@ gst_vaapi_mini_object_free(GstVaapiMiniObject *object) * Returns: The newly allocated #GstVaapiMiniObject */ GstVaapiMiniObject * -gst_vaapi_mini_object_new(const GstVaapiMiniObjectClass *object_class) +gst_vaapi_mini_object_new (const GstVaapiMiniObjectClass * object_class) { - GstVaapiMiniObject *object; + GstVaapiMiniObject *object; - static const GstVaapiMiniObjectClass default_object_class = { - .size = sizeof(GstVaapiMiniObject), - }; + static const GstVaapiMiniObjectClass default_object_class = { + .size = sizeof (GstVaapiMiniObject), + }; - if (G_UNLIKELY(!object_class)) - object_class = &default_object_class; + if (G_UNLIKELY (!object_class)) + object_class = &default_object_class; - g_return_val_if_fail(object_class->size >= sizeof(*object), NULL); + g_return_val_if_fail (object_class->size >= sizeof (*object), NULL); - object = g_slice_alloc(object_class->size); - if (!object) - return NULL; + object = g_slice_alloc (object_class->size); + if (!object) + return NULL; - object->object_class = object_class; - object->ref_count = 1; - object->flags = 0; - return object; + object->object_class = object_class; + object->ref_count = 1; + object->flags = 0; + return object; } /** @@ -86,21 +86,21 @@ gst_vaapi_mini_object_new(const GstVaapiMiniObjectClass *object_class) * Returns: The newly allocated #GstVaapiMiniObject */ GstVaapiMiniObject * -gst_vaapi_mini_object_new0(const GstVaapiMiniObjectClass *object_class) +gst_vaapi_mini_object_new0 (const GstVaapiMiniObjectClass * object_class) { - GstVaapiMiniObject *object; - guint sub_size; + GstVaapiMiniObject *object; + guint sub_size; - object = gst_vaapi_mini_object_new(object_class); - if (!object) - return NULL; + object = gst_vaapi_mini_object_new (object_class); + if (!object) + return NULL; - object_class = object->object_class; + object_class = object->object_class; - sub_size = object_class->size - sizeof(*object); - if (sub_size > 0) - memset(((guchar *)object) + sizeof(*object), 0, sub_size); - return object; + sub_size = object_class->size - sizeof (*object); + if (sub_size > 0) + memset (((guchar *) object) + sizeof (*object), 0, sub_size); + return object; } /** @@ -112,12 +112,12 @@ gst_vaapi_mini_object_new0(const GstVaapiMiniObjectClass *object_class) * Returns: The same @object argument */ GstVaapiMiniObject * -gst_vaapi_mini_object_ref(GstVaapiMiniObject *object) +gst_vaapi_mini_object_ref (GstVaapiMiniObject * object) { - g_return_val_if_fail(object != NULL, NULL); + g_return_val_if_fail (object != NULL, NULL); - g_atomic_int_inc(&object->ref_count); - return object; + g_atomic_int_inc (&object->ref_count); + return object; } /** @@ -128,13 +128,13 @@ gst_vaapi_mini_object_ref(GstVaapiMiniObject *object) * the reference count reaches zero, the object will be free'd. */ void -gst_vaapi_mini_object_unref(GstVaapiMiniObject *object) +gst_vaapi_mini_object_unref (GstVaapiMiniObject * object) { - g_return_if_fail(object != NULL); - g_return_if_fail(object->ref_count > 0); + g_return_if_fail (object != NULL); + g_return_if_fail (object->ref_count > 0); - if (g_atomic_int_dec_and_test(&object->ref_count)) - gst_vaapi_mini_object_free(object); + if (g_atomic_int_dec_and_test (&object->ref_count)) + gst_vaapi_mini_object_free (object); } /** @@ -147,25 +147,25 @@ gst_vaapi_mini_object_unref(GstVaapiMiniObject *object) * valid object. However, @new_object can be NULL. */ void -gst_vaapi_mini_object_replace(GstVaapiMiniObject **old_object_ptr, - GstVaapiMiniObject *new_object) +gst_vaapi_mini_object_replace (GstVaapiMiniObject ** old_object_ptr, + GstVaapiMiniObject * new_object) { - GstVaapiMiniObject *old_object; + GstVaapiMiniObject *old_object; - g_return_if_fail(old_object_ptr != NULL); + g_return_if_fail (old_object_ptr != NULL); - old_object = g_atomic_pointer_get((gpointer *)old_object_ptr); + old_object = g_atomic_pointer_get ((gpointer *) old_object_ptr); - if (old_object == new_object) - return; + if (old_object == new_object) + return; - if (new_object) - gst_vaapi_mini_object_ref(new_object); + if (new_object) + gst_vaapi_mini_object_ref (new_object); - while (!g_atomic_pointer_compare_and_exchange((gpointer *)old_object_ptr, - old_object, new_object)) - old_object = g_atomic_pointer_get((gpointer *)old_object_ptr); + while (!g_atomic_pointer_compare_and_exchange ((gpointer *) old_object_ptr, + old_object, new_object)) + old_object = g_atomic_pointer_get ((gpointer *) old_object_ptr); - if (old_object) - gst_vaapi_mini_object_unref(old_object); + if (old_object) + gst_vaapi_mini_object_unref (old_object); } diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.h b/gst-libs/gst/vaapi/gstvaapiminiobject.h index 058378d470..7131a9d6c6 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.h @@ -1,7 +1,7 @@ /* * gstvaapiminiobject.h - A lightweight reference counted object * - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * Author: Gwenole Beauchesne * * This library is free software; you can redistribute it and/or @@ -28,8 +28,8 @@ G_BEGIN_DECLS -typedef struct _GstVaapiMiniObject GstVaapiMiniObject; -typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; +typedef struct _GstVaapiMiniObject GstVaapiMiniObject; +typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; /** * GST_VAAPI_MINI_OBJECT: @@ -38,7 +38,16 @@ typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; * Casts the @object to a #GstVaapiMiniObject */ #define GST_VAAPI_MINI_OBJECT(object) \ - ((GstVaapiMiniObject *)(object)) + ((GstVaapiMiniObject *) (object)) + +/** + * GST_VAAPI_MINI_OBJECT_PTR: + * @object_ptr: a pointer #GstVaapiMiniObject + * + * Casts the @object_ptr to a pointer to #GstVaapiMiniObject + */ +#define GST_VAAPI_MINI_OBJECT_PTR(object_ptr) \ + ((GstVaapiMiniObject **) (object_ptr)) /** * GST_VAAPI_MINI_OBJECT_CLASS: @@ -47,7 +56,7 @@ typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; * Casts the @klass to a #GstVaapiMiniObjectClass */ #define GST_VAAPI_MINI_OBJECT_CLASS(klass) \ - ((GstVaapiMiniObjectClass *)(klass)) + ((GstVaapiMiniObjectClass *) (klass)) /** * GST_VAAPI_MINI_OBJECT_GET_CLASS: @@ -56,7 +65,7 @@ typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; * Retrieves the #GstVaapiMiniObjectClass associated with the @object */ #define GST_VAAPI_MINI_OBJECT_GET_CLASS(object) \ - (GST_VAAPI_MINI_OBJECT(object)->object_class) + (GST_VAAPI_MINI_OBJECT (object)->object_class) /** * GST_VAAPI_MINI_OBJECT_FLAGS: @@ -65,7 +74,7 @@ typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; * The entire set of flags for the @object */ #define GST_VAAPI_MINI_OBJECT_FLAGS(object) \ - (GST_VAAPI_MINI_OBJECT(object)->flags) + (GST_VAAPI_MINI_OBJECT (object)->flags) /** * GST_VAAPI_MINI_OBJECT_FLAG_IS_SET: @@ -75,7 +84,7 @@ typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; * Checks whether the given @flag is set */ #define GST_VAAPI_MINI_OBJECT_FLAG_IS_SET(object, flag) \ - ((GST_VAAPI_MINI_OBJECT_FLAGS(object) & (flag)) != 0) + ((GST_VAAPI_MINI_OBJECT_FLAGS (object) & (flag)) != 0) /** * GST_VAAPI_MINI_OBJECT_FLAG_SET: @@ -85,7 +94,7 @@ typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; * This macro sets the given bits */ #define GST_VAAPI_MINI_OBJECT_FLAG_SET(object, flags) \ - (GST_VAAPI_MINI_OBJECT_FLAGS(object) |= (flags)) + (GST_VAAPI_MINI_OBJECT_FLAGS (object) |= (flags)) /** * GST_VAAPI_MINI_OBJECT_FLAG_UNSET: @@ -95,7 +104,7 @@ typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; * This macro unsets the given bits. */ #define GST_VAAPI_MINI_OBJECT_FLAG_UNSET(object, flags) \ - (GST_VAAPI_MINI_OBJECT_FLAGS(object) &= ~(flags)) + (GST_VAAPI_MINI_OBJECT_FLAGS (object) &= ~(flags)) /** * GstVaapiMiniObject: @@ -108,11 +117,12 @@ typedef struct _GstVaapiMiniObjectClass GstVaapiMiniObjectClass; * A #GstVaapiMiniObject represents a minimal reference counted data * structure that can hold a set of flags and user-provided data. */ -struct _GstVaapiMiniObject { - /*< private >*/ - gconstpointer object_class; - volatile gint ref_count; - guint flags; +struct _GstVaapiMiniObject +{ + /*< private >*/ + gconstpointer object_class; + volatile gint ref_count; + guint flags; }; /** @@ -125,31 +135,33 @@ struct _GstVaapiMiniObject { * defines the size of the #GstVaapiMiniObject and utility function to * dispose child objects */ -struct _GstVaapiMiniObjectClass { - guint size; - GDestroyNotify finalize; +struct _GstVaapiMiniObjectClass +{ + /*< protected >*/ + guint size; + GDestroyNotify finalize; }; G_GNUC_INTERNAL GstVaapiMiniObject * -gst_vaapi_mini_object_new(const GstVaapiMiniObjectClass *object_class); +gst_vaapi_mini_object_new (const GstVaapiMiniObjectClass * object_class); G_GNUC_INTERNAL GstVaapiMiniObject * -gst_vaapi_mini_object_new0(const GstVaapiMiniObjectClass *object_class); +gst_vaapi_mini_object_new0 (const GstVaapiMiniObjectClass * object_class); G_GNUC_INTERNAL GstVaapiMiniObject * -gst_vaapi_mini_object_ref(GstVaapiMiniObject *object); +gst_vaapi_mini_object_ref (GstVaapiMiniObject * object); G_GNUC_INTERNAL void -gst_vaapi_mini_object_unref(GstVaapiMiniObject *object); +gst_vaapi_mini_object_unref (GstVaapiMiniObject * object); G_GNUC_INTERNAL void -gst_vaapi_mini_object_replace(GstVaapiMiniObject **old_object_ptr, - GstVaapiMiniObject *new_object); +gst_vaapi_mini_object_replace (GstVaapiMiniObject ** old_object_ptr, + GstVaapiMiniObject * new_object); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 0d8856aa4c..15af267953 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -42,24 +42,23 @@ #undef gst_vaapi_object_replace static void -gst_vaapi_object_finalize(GstVaapiObject *object) +gst_vaapi_object_finalize (GstVaapiObject * object) { - const GstVaapiObjectClass * const klass = - GST_VAAPI_OBJECT_GET_CLASS(object); + const GstVaapiObjectClass *const klass = GST_VAAPI_OBJECT_GET_CLASS (object); - if (klass->finalize) - klass->finalize(object); - gst_vaapi_display_replace(&object->display, NULL); + if (klass->finalize) + klass->finalize (object); + gst_vaapi_display_replace (&object->display, NULL); } void -gst_vaapi_object_class_init(GstVaapiObjectClass *klass, guint size) +gst_vaapi_object_class_init (GstVaapiObjectClass * klass, guint size) { - GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); - object_class->size = size; - object_class->finalize = (GDestroyNotify)gst_vaapi_object_finalize; + object_class->size = size; + object_class->finalize = (GDestroyNotify) gst_vaapi_object_finalize; } /** @@ -77,30 +76,31 @@ gst_vaapi_object_class_init(GstVaapiObjectClass *klass, guint size) * Returns: The newly allocated #GstVaapiObject */ gpointer -gst_vaapi_object_new(const GstVaapiObjectClass *klass, GstVaapiDisplay *display) +gst_vaapi_object_new (const GstVaapiObjectClass * klass, + GstVaapiDisplay * display) { - const GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); - GstVaapiObject *object; - guint sub_size; + const GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiObject *object; + guint sub_size; - g_return_val_if_fail(klass != NULL, NULL); - g_return_val_if_fail(display != NULL, NULL); + g_return_val_if_fail (klass != NULL, NULL); + g_return_val_if_fail (display != NULL, NULL); - object = (GstVaapiObject *)gst_vaapi_mini_object_new(object_class); - if (!object) - return NULL; + object = (GstVaapiObject *) gst_vaapi_mini_object_new (object_class); + if (!object) + return NULL; - object->display = gst_vaapi_display_ref(display); - object->object_id = VA_INVALID_ID; + object->display = gst_vaapi_display_ref (display); + object->object_id = VA_INVALID_ID; - sub_size = object_class->size - sizeof(*object); - if (sub_size > 0) - memset(((guchar *)object) + sizeof(*object), 0, sub_size); + sub_size = object_class->size - sizeof (*object); + if (sub_size > 0) + memset (((guchar *) object) + sizeof (*object), 0, sub_size); - if (klass && klass->init) - klass->init (object); - return object; + if (klass && klass->init) + klass->init (object); + return object; } /** @@ -112,9 +112,9 @@ gst_vaapi_object_new(const GstVaapiObjectClass *klass, GstVaapiDisplay *display) * Returns: The same @object argument */ gpointer -gst_vaapi_object_ref(gpointer object) +gst_vaapi_object_ref (gpointer object) { - return gst_vaapi_object_ref_internal(object); + return gst_vaapi_object_ref_internal (object); } /** @@ -125,9 +125,9 @@ gst_vaapi_object_ref(gpointer object) * the reference count reaches zero, the object will be free'd. */ void -gst_vaapi_object_unref(gpointer object) +gst_vaapi_object_unref (gpointer object) { - gst_vaapi_object_unref_internal(object); + gst_vaapi_object_unref_internal (object); } /** @@ -140,9 +140,9 @@ gst_vaapi_object_unref(gpointer object) * valid object. However, @new_object can be NULL. */ void -gst_vaapi_object_replace(gpointer old_object_ptr, gpointer new_object) +gst_vaapi_object_replace (gpointer old_object_ptr, gpointer new_object) { - gst_vaapi_object_replace_internal(old_object_ptr, new_object); + gst_vaapi_object_replace_internal (old_object_ptr, new_object); } /** @@ -154,11 +154,11 @@ gst_vaapi_object_replace(gpointer old_object_ptr, gpointer new_object) * Return value: the parent #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_object_get_display(GstVaapiObject *object) +gst_vaapi_object_get_display (GstVaapiObject * object) { - g_return_val_if_fail(object != NULL, NULL); + g_return_val_if_fail (object != NULL, NULL); - return GST_VAAPI_OBJECT_DISPLAY(object); + return GST_VAAPI_OBJECT_DISPLAY (object); } /** @@ -170,11 +170,11 @@ gst_vaapi_object_get_display(GstVaapiObject *object) * unlocked by the other thread. */ void -gst_vaapi_object_lock_display(GstVaapiObject *object) +gst_vaapi_object_lock_display (GstVaapiObject * object) { - g_return_if_fail(object != NULL); + g_return_if_fail (object != NULL); - GST_VAAPI_OBJECT_LOCK_DISPLAY(object); + GST_VAAPI_OBJECT_LOCK_DISPLAY (object); } /** @@ -186,11 +186,11 @@ gst_vaapi_object_lock_display(GstVaapiObject *object) * display itself. */ void -gst_vaapi_object_unlock_display(GstVaapiObject *object) +gst_vaapi_object_unlock_display (GstVaapiObject * object) { - g_return_if_fail(object != NULL); + g_return_if_fail (object != NULL); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(object); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (object); } /** @@ -202,9 +202,9 @@ gst_vaapi_object_unlock_display(GstVaapiObject *object) * Return value: the #GstVaapiID of the @object */ GstVaapiID -gst_vaapi_object_get_id(GstVaapiObject *object) +gst_vaapi_object_get_id (GstVaapiObject * object) { - g_return_val_if_fail(object != NULL, 0); + g_return_val_if_fail (object != NULL, 0); - return GST_VAAPI_OBJECT_ID(object); + return GST_VAAPI_OBJECT_ID (object); } diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index ed76af1b8c..a9a977d1f1 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -31,9 +31,9 @@ G_BEGIN_DECLS #define GST_VAAPI_OBJECT(obj) \ - ((GstVaapiObject *)(obj)) + ((GstVaapiObject *) (obj)) -typedef struct _GstVaapiObject GstVaapiObject; +typedef struct _GstVaapiObject GstVaapiObject; /** * GST_VAAPI_OBJECT_DISPLAY: @@ -42,7 +42,7 @@ typedef struct _GstVaapiObject GstVaapiObject; * Macro that evaluates to the #GstVaapiDisplay the @object is bound to. */ #define GST_VAAPI_OBJECT_DISPLAY(object) \ - gst_vaapi_object_get_display(GST_VAAPI_OBJECT(object)) + gst_vaapi_object_get_display (GST_VAAPI_OBJECT (object)) /** * GST_VAAPI_OBJECT_ID: @@ -51,28 +51,28 @@ typedef struct _GstVaapiObject GstVaapiObject; * Macro that evaluates to the #GstVaapiID contained in @object. */ #define GST_VAAPI_OBJECT_ID(object) \ - gst_vaapi_object_get_id(GST_VAAPI_OBJECT(object)) + gst_vaapi_object_get_id (GST_VAAPI_OBJECT (object)) gpointer -gst_vaapi_object_ref(gpointer object); +gst_vaapi_object_ref (gpointer object); void -gst_vaapi_object_unref(gpointer object); +gst_vaapi_object_unref (gpointer object); void -gst_vaapi_object_replace(gpointer old_object_ptr, gpointer new_object); +gst_vaapi_object_replace (gpointer old_object_ptr, gpointer new_object); GstVaapiDisplay * -gst_vaapi_object_get_display(GstVaapiObject *object); +gst_vaapi_object_get_display (GstVaapiObject * object); void -gst_vaapi_object_lock_display(GstVaapiObject *object); +gst_vaapi_object_lock_display (GstVaapiObject * object); void -gst_vaapi_object_unlock_display(GstVaapiObject *object); +gst_vaapi_object_unlock_display (GstVaapiObject * object); GstVaapiID -gst_vaapi_object_get_id(GstVaapiObject *object); +gst_vaapi_object_get_id (GstVaapiObject * object); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index f6f3a5860c..9fedaacb04 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -32,50 +32,37 @@ G_BEGIN_DECLS #define GST_VAAPI_OBJECT_CLASS(klass) \ - ((GstVaapiObjectClass *)(klass)) - + ((GstVaapiObjectClass *) (klass)) #define GST_VAAPI_IS_OBJECT_CLASS(klass) \ - ((klass) != NULL) - + ((klass) != NULL) #define GST_VAAPI_OBJECT_GET_CLASS(object) \ - GST_VAAPI_OBJECT_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(object)) + GST_VAAPI_OBJECT_CLASS (GST_VAAPI_MINI_OBJECT_GET_CLASS (object)) -typedef struct _GstVaapiObjectClass GstVaapiObjectClass; -typedef void (*GstVaapiObjectInitFunc) (GstVaapiObject *object); -typedef void (*GstVaapiObjectFinalizeFunc) (GstVaapiObject *object); +typedef struct _GstVaapiObjectClass GstVaapiObjectClass; +typedef void (*GstVaapiObjectInitFunc) (GstVaapiObject * object); +typedef void (*GstVaapiObjectFinalizeFunc) (GstVaapiObject * object); #define GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE(TN, t_n, code) \ static inline const GstVaapiObjectClass * \ -G_PASTE(t_n,_class)(void) \ +G_PASTE(t_n,_class) (void) \ { \ static G_PASTE(TN,Class) g_class; \ static gsize g_class_init = FALSE; \ \ - if (g_once_init_enter(&g_class_init)) { \ + if (g_once_init_enter (&g_class_init)) { \ GstVaapiObjectClass * const klass = \ - GST_VAAPI_OBJECT_CLASS(&g_class); \ - gst_vaapi_object_class_init(klass, sizeof(TN)); \ + GST_VAAPI_OBJECT_CLASS (&g_class); \ + gst_vaapi_object_class_init (klass, sizeof(TN)); \ code; \ klass->finalize = (GstVaapiObjectFinalizeFunc) \ G_PASTE(t_n,_finalize); \ - g_once_init_leave(&g_class_init, TRUE); \ + g_once_init_leave (&g_class_init, TRUE); \ } \ - return GST_VAAPI_OBJECT_CLASS(&g_class); \ + return GST_VAAPI_OBJECT_CLASS (&g_class); \ } #define GST_VAAPI_OBJECT_DEFINE_CLASS(TN, t_n) \ - GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE(TN, t_n, /**/) - -/** - * GST_VAAPI_OBJECT_DISPLAY: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the #GstVaapiDisplay the @object is bound to. - * This is an internal macro that does not do any run-time type check. - */ -#undef GST_VAAPI_OBJECT_DISPLAY -#define GST_VAAPI_OBJECT_DISPLAY(object) \ - GST_VAAPI_OBJECT(object)->display + GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (TN, t_n, /**/) /** * GST_VAAPI_OBJECT_ID: @@ -86,7 +73,18 @@ G_PASTE(t_n,_class)(void) \ */ #undef GST_VAAPI_OBJECT_ID #define GST_VAAPI_OBJECT_ID(object) \ - GST_VAAPI_OBJECT(object)->object_id + (GST_VAAPI_OBJECT (object)->object_id) + +/** + * GST_VAAPI_OBJECT_DISPLAY: + * @object: a #GstVaapiObject + * + * Macro that evaluates to the #GstVaapiDisplay the @object is bound to. + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_OBJECT_DISPLAY +#define GST_VAAPI_OBJECT_DISPLAY(object) \ + (GST_VAAPI_OBJECT (object)->display) /** * GST_VAAPI_OBJECT_DISPLAY_X11: @@ -97,7 +95,7 @@ G_PASTE(t_n,_class)(void) \ * and requires #include "gstvaapidisplay_x11_priv.h" */ #define GST_VAAPI_OBJECT_DISPLAY_X11(object) \ - GST_VAAPI_DISPLAY_X11_CAST(GST_VAAPI_OBJECT_DISPLAY(object)) + GST_VAAPI_DISPLAY_X11_CAST (GST_VAAPI_OBJECT_DISPLAY (object)) /** * GST_VAAPI_OBJECT_DISPLAY_GLX: @@ -108,7 +106,7 @@ G_PASTE(t_n,_class)(void) \ * and requires #include "gstvaapidisplay_glx_priv.h". */ #define GST_VAAPI_OBJECT_DISPLAY_GLX(object) \ - GST_VAAPI_DISPLAY_GLX_CAST(GST_VAAPI_OBJECT_DISPLAY(object)) + GST_VAAPI_DISPLAY_GLX_CAST (GST_VAAPI_OBJECT_DISPLAY (object)) /** * GST_VAAPI_OBJECT_DISPLAY_WAYLAND: @@ -119,7 +117,7 @@ G_PASTE(t_n,_class)(void) \ * type check and requires #include "gstvaapidisplay_wayland_priv.h" */ #define GST_VAAPI_OBJECT_DISPLAY_WAYLAND(object) \ - GST_VAAPI_DISPLAY_WAYLAND_CAST(GST_VAAPI_OBJECT_DISPLAY(object)) + GST_VAAPI_DISPLAY_WAYLAND_CAST (GST_VAAPI_OBJECT_DISPLAY (object)) /** * GST_VAAPI_OBJECT_VADISPLAY: @@ -130,7 +128,7 @@ G_PASTE(t_n,_class)(void) \ * and requires #include "gstvaapidisplay_priv.h". */ #define GST_VAAPI_OBJECT_VADISPLAY(object) \ - GST_VAAPI_DISPLAY_VADISPLAY(GST_VAAPI_OBJECT_DISPLAY(object)) + GST_VAAPI_DISPLAY_VADISPLAY (GST_VAAPI_OBJECT_DISPLAY (object)) /** * GST_VAAPI_OBJECT_XDISPLAY: @@ -141,7 +139,7 @@ G_PASTE(t_n,_class)(void) \ * and requires #include "gstvaapidisplay_x11_priv.h". */ #define GST_VAAPI_OBJECT_XDISPLAY(object) \ - GST_VAAPI_DISPLAY_XDISPLAY(GST_VAAPI_OBJECT_DISPLAY(object)) + GST_VAAPI_DISPLAY_XDISPLAY (GST_VAAPI_OBJECT_DISPLAY (object)) /** * GST_VAAPI_OBJECT_XSCREEN: @@ -152,7 +150,7 @@ G_PASTE(t_n,_class)(void) \ * and requires #include "gstvaapidisplay_x11_priv.h". */ #define GST_VAAPI_OBJECT_XSCREEN(object) \ - GST_VAAPI_DISPLAY_XSCREEN(GST_VAAPI_OBJECT_DISPLAY(object)) + GST_VAAPI_DISPLAY_XSCREEN (GST_VAAPI_OBJECT_DISPLAY (object)) /** * GST_VAAPI_OBJECT_WL_DISPLAY: @@ -163,7 +161,7 @@ G_PASTE(t_n,_class)(void) \ * and requires #include "gstvaapidisplay_wayland_priv.h". */ #define GST_VAAPI_OBJECT_WL_DISPLAY(object) \ - GST_VAAPI_DISPLAY_WL_DISPLAY(GST_VAAPI_OBJECT_DISPLAY(object)) + GST_VAAPI_DISPLAY_WL_DISPLAY (GST_VAAPI_OBJECT_DISPLAY (object)) /** * GST_VAAPI_OBJECT_LOCK_DISPLAY: @@ -173,7 +171,7 @@ G_PASTE(t_n,_class)(void) \ * This is an internal macro that does not do any run-time type check. */ #define GST_VAAPI_OBJECT_LOCK_DISPLAY(object) \ - GST_VAAPI_DISPLAY_LOCK(GST_VAAPI_OBJECT_DISPLAY(object)) + GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_OBJECT_DISPLAY (object)) /** * GST_VAAPI_OBJECT_UNLOCK_DISPLAY: @@ -183,19 +181,20 @@ G_PASTE(t_n,_class)(void) \ * This is an internal macro that does not do any run-time type check. */ #define GST_VAAPI_OBJECT_UNLOCK_DISPLAY(object) \ - GST_VAAPI_DISPLAY_UNLOCK(GST_VAAPI_OBJECT_DISPLAY(object)) + GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_OBJECT_DISPLAY (object)) /** * GstVaapiObject: * * VA object base. */ -struct _GstVaapiObject { - /*< private >*/ - GstVaapiMiniObject parent_instance; +struct _GstVaapiObject +{ + /*< private >*/ + GstVaapiMiniObject parent_instance; - GstVaapiDisplay *display; - GstVaapiID object_id; + GstVaapiDisplay *display; + GstVaapiID object_id; }; /** @@ -203,53 +202,54 @@ struct _GstVaapiObject { * * VA object base class. */ -struct _GstVaapiObjectClass { - /*< private >*/ - GstVaapiMiniObjectClass parent_class; +struct _GstVaapiObjectClass +{ + /*< private >*/ + GstVaapiMiniObjectClass parent_class; - GstVaapiObjectInitFunc init; - GstVaapiObjectFinalizeFunc finalize; + GstVaapiObjectInitFunc init; + GstVaapiObjectFinalizeFunc finalize; }; void -gst_vaapi_object_class_init(GstVaapiObjectClass *klass, guint size); +gst_vaapi_object_class_init (GstVaapiObjectClass * klass, guint size); gpointer -gst_vaapi_object_new(const GstVaapiObjectClass *klass, - GstVaapiDisplay *display); +gst_vaapi_object_new (const GstVaapiObjectClass * klass, + GstVaapiDisplay * display); /* Inline reference counting for core libgstvaapi library */ #ifdef IN_LIBGSTVAAPI_CORE static inline gpointer -gst_vaapi_object_ref_internal(gpointer object) +gst_vaapi_object_ref_internal (gpointer object) { - return gst_vaapi_mini_object_ref(object); + return gst_vaapi_mini_object_ref (object); } static inline void -gst_vaapi_object_unref_internal(gpointer object) +gst_vaapi_object_unref_internal (gpointer object) { - gst_vaapi_mini_object_unref(object); + gst_vaapi_mini_object_unref (object); } static inline void -gst_vaapi_object_replace_internal(gpointer old_object_ptr, gpointer new_object) +gst_vaapi_object_replace_internal (gpointer old_object_ptr, gpointer new_object) { - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)old_object_ptr, - new_object); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_object_ptr, + new_object); } #undef gst_vaapi_object_ref #define gst_vaapi_object_ref(object) \ - gst_vaapi_object_ref_internal((object)) + gst_vaapi_object_ref_internal ((object)) #undef gst_vaapi_object_unref #define gst_vaapi_object_unref(object) \ - gst_vaapi_object_unref_internal((object)) + gst_vaapi_object_unref_internal ((object)) #undef gst_vaapi_object_replace #define gst_vaapi_object_replace(old_object_ptr, new_object) \ - gst_vaapi_object_replace_internal((old_object_ptr), (new_object)) + gst_vaapi_object_replace_internal ((old_object_ptr), (new_object)) #endif G_END_DECLS From fd775b440098c3e741eece08265baecd1edde098 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 2 Dec 2014 16:51:20 +0100 Subject: [PATCH 1826/3781] libs: expose GstVaapiMiniObject APIs to all backends. Make it possible to have all libgstvaapi backends (libs) access to a common GstVaapiMiniObject API and implementation. This is a minor step towards full exposure when needed, but restrict it to libgstvaapi at this time. --- gst-libs/gst/vaapi/gstvaapiminiobject.c | 17 +++++---- gst-libs/gst/vaapi/gstvaapiminiobject.h | 51 ++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.c b/gst-libs/gst/vaapi/gstvaapiminiobject.c index 11fb769758..f146d0faf3 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.c @@ -23,7 +23,12 @@ #include #include "gstvaapiminiobject.h" -static void +/* Ensure those symbols are actually defined in the resulting libraries */ +#undef gst_vaapi_mini_object_ref +#undef gst_vaapi_mini_object_unref +#undef gst_vaapi_mini_object_replace + +void gst_vaapi_mini_object_free (GstVaapiMiniObject * object) { const GstVaapiMiniObjectClass *const klass = object->object_class; @@ -116,8 +121,7 @@ gst_vaapi_mini_object_ref (GstVaapiMiniObject * object) { g_return_val_if_fail (object != NULL, NULL); - g_atomic_int_inc (&object->ref_count); - return object; + return gst_vaapi_mini_object_ref_internal (object); } /** @@ -133,8 +137,7 @@ gst_vaapi_mini_object_unref (GstVaapiMiniObject * object) g_return_if_fail (object != NULL); g_return_if_fail (object->ref_count > 0); - if (g_atomic_int_dec_and_test (&object->ref_count)) - gst_vaapi_mini_object_free (object); + gst_vaapi_mini_object_unref_internal (object); } /** @@ -160,12 +163,12 @@ gst_vaapi_mini_object_replace (GstVaapiMiniObject ** old_object_ptr, return; if (new_object) - gst_vaapi_mini_object_ref (new_object); + gst_vaapi_mini_object_ref_internal (new_object); while (!g_atomic_pointer_compare_and_exchange ((gpointer *) old_object_ptr, old_object, new_object)) old_object = g_atomic_pointer_get ((gpointer *) old_object_ptr); if (old_object) - gst_vaapi_mini_object_unref (old_object); + gst_vaapi_mini_object_unref_internal (old_object); } diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.h b/gst-libs/gst/vaapi/gstvaapiminiobject.h index 7131a9d6c6..562c5fc472 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.h @@ -142,27 +142,68 @@ struct _GstVaapiMiniObjectClass GDestroyNotify finalize; }; -G_GNUC_INTERNAL GstVaapiMiniObject * gst_vaapi_mini_object_new (const GstVaapiMiniObjectClass * object_class); -G_GNUC_INTERNAL GstVaapiMiniObject * gst_vaapi_mini_object_new0 (const GstVaapiMiniObjectClass * object_class); -G_GNUC_INTERNAL GstVaapiMiniObject * gst_vaapi_mini_object_ref (GstVaapiMiniObject * object); -G_GNUC_INTERNAL void gst_vaapi_mini_object_unref (GstVaapiMiniObject * object); -G_GNUC_INTERNAL void gst_vaapi_mini_object_replace (GstVaapiMiniObject ** old_object_ptr, GstVaapiMiniObject * new_object); +#ifdef IN_LIBGSTVAAPI_CORE +#undef gst_vaapi_mini_object_ref +#define gst_vaapi_mini_object_ref(object) \ + gst_vaapi_mini_object_ref_internal (object) + +#undef gst_vaapi_mini_object_unref +#define gst_vaapi_mini_object_unref(object) \ + gst_vaapi_mini_object_unref_internal (object) + +G_GNUC_INTERNAL +void +gst_vaapi_mini_object_free (GstVaapiMiniObject * object); + +/** + * gst_vaapi_mini_object_ref_internal: + * @object: a #GstVaapiMiniObject + * + * Atomically increases the reference count of the given @object by one. + * This is an internal function that does not do any run-time type check. + * + * Returns: The same @object argument + */ +static inline GstVaapiMiniObject * +gst_vaapi_mini_object_ref_internal (GstVaapiMiniObject * object) +{ + g_atomic_int_inc (&object->ref_count); + return object; +} + +/** + * gst_vaapi_mini_object_unref_internal: + * @object: a #GstVaapiMiniObject + * + * Atomically decreases the reference count of the @object by one. If + * the reference count reaches zero, the object will be free'd. + * + * This is an internal function that does not do any run-time type check. + */ +static inline void +gst_vaapi_mini_object_unref_internal (GstVaapiMiniObject * object) +{ + if (g_atomic_int_dec_and_test (&object->ref_count)) + gst_vaapi_mini_object_free (object); +} +#endif + G_END_DECLS #endif /* GST_VAAPI_MINI_OBJECT_H */ From f270838515e8a82772454fcf2ac755399532b7c6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 4 Dec 2014 14:36:35 +0100 Subject: [PATCH 1827/3781] libs: re-introduce a GST_VAAPI_ID_INVALID value. Re-introduce a GST_VAAPI_ID_INVALID value that represents a non-zero and invalid id. This is useful to have a value that is still invalid for cases where zero could actually be a valid value. --- gst-libs/gst/vaapi/gstvaapitypes.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index ccdddbfa06..9cc646f57e 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -37,6 +37,21 @@ G_BEGIN_DECLS */ typedef gsize GstVaapiID; +/** + * GST_VAAPI_ID: + * @id: an arbitrary integer value + * + * Macro that creates a #GstVaapiID from @id. + */ +#define GST_VAAPI_ID(id) ((GstVaapiID)(id)) + +/** + * GST_VAAPI_ID_INVALID: + * + * Macro that evaluates to an invalid #GstVaapiID value. + */ +#define GST_VAAPI_ID_INVALID GST_VAAPI_ID((gssize)(gint32)-1) + /** * GST_VAAPI_ID_FORMAT: * From 74a080a8da1dd30aa48f97146d3fb64a7e44f1ab Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 27 Jan 2015 18:02:56 +0100 Subject: [PATCH 1828/3781] libs: bump library major version. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 6d6fdca181..1b0a620323 100644 --- a/configure.ac +++ b/configure.ac @@ -10,12 +10,12 @@ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) ]) # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [5]) +m4_define([gst_vaapi_lt_current], [6]) m4_define([gst0_vaapi_lt_current_bias], [0]) m4_define([gst1_vaapi_lt_current_bias], [2]) m4_define([gst2_vaapi_lt_current_bias], [4]) m4_define([gst4_vaapi_lt_current_bias], [5]) -m4_define([gst6_vaapi_lt_current_bias], [5]) +m4_define([gst6_vaapi_lt_current_bias], [6]) m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [0]) From 1810a41c6831e69bc636709ce7d524a32f860c2b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 23 Jan 2015 16:37:06 +0100 Subject: [PATCH 1829/3781] surfaceproxy: re-indent all GstVaapiSurfaceProxy related source code. --- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 215 +++++++++--------- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 57 ++--- .../gst/vaapi/gstvaapisurfaceproxy_priv.h | 43 ++-- 3 files changed, 158 insertions(+), 157 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 1b817553c0..56e1ea69fa 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -36,30 +36,30 @@ #include "gstvaapidebug.h" static void -gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy) +gst_vaapi_surface_proxy_finalize (GstVaapiSurfaceProxy * proxy) { - if (proxy->surface) { - if (proxy->pool && !proxy->parent) - gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface); - gst_vaapi_object_unref(proxy->surface); - proxy->surface = NULL; - } - gst_vaapi_video_pool_replace(&proxy->pool, NULL); - gst_vaapi_surface_proxy_replace(&proxy->parent, NULL); + if (proxy->surface) { + if (proxy->pool && !proxy->parent) + gst_vaapi_video_pool_put_object (proxy->pool, proxy->surface); + gst_vaapi_object_unref (proxy->surface); + proxy->surface = NULL; + } + gst_vaapi_video_pool_replace (&proxy->pool, NULL); + gst_vaapi_surface_proxy_replace (&proxy->parent, NULL); - /* Notify the user function that the object is now destroyed */ - if (proxy->destroy_func) - proxy->destroy_func(proxy->destroy_data); + /* 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_surface_proxy_class(void) +gst_vaapi_surface_proxy_class (void) { - static const GstVaapiMiniObjectClass GstVaapiSurfaceProxyClass = { - sizeof(GstVaapiSurfaceProxy), - (GDestroyNotify)gst_vaapi_surface_proxy_finalize - }; - return &GstVaapiSurfaceProxyClass; + static const GstVaapiMiniObjectClass GstVaapiSurfaceProxyClass = { + sizeof (GstVaapiSurfaceProxy), + (GDestroyNotify) gst_vaapi_surface_proxy_finalize + }; + return &GstVaapiSurfaceProxyClass; } /** @@ -74,36 +74,35 @@ gst_vaapi_surface_proxy_class(void) * Returns: The same newly allocated @proxy object, or %NULL on error */ GstVaapiSurfaceProxy * -gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool) +gst_vaapi_surface_proxy_new_from_pool (GstVaapiSurfacePool * pool) { - GstVaapiSurfaceProxy *proxy; + GstVaapiSurfaceProxy *proxy; - g_return_val_if_fail(pool != NULL, NULL); + g_return_val_if_fail (pool != NULL, NULL); - proxy = (GstVaapiSurfaceProxy *) - gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class()); - if (!proxy) - return NULL; + proxy = (GstVaapiSurfaceProxy *) + gst_vaapi_mini_object_new (gst_vaapi_surface_proxy_class ()); + if (!proxy) + return NULL; - proxy->parent = NULL; - proxy->destroy_func = NULL; - proxy->pool = gst_vaapi_video_pool_ref(pool); - proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool); - if (!proxy->surface) - goto error; - proxy->view_id = 0; - proxy->timestamp = GST_CLOCK_TIME_NONE; - proxy->duration = GST_CLOCK_TIME_NONE; - proxy->has_crop_rect = FALSE; - gst_vaapi_object_ref(proxy->surface); - return proxy; + proxy->parent = NULL; + proxy->destroy_func = NULL; + proxy->pool = gst_vaapi_video_pool_ref (pool); + proxy->surface = gst_vaapi_video_pool_get_object (proxy->pool); + if (!proxy->surface) + goto error; + proxy->view_id = 0; + proxy->timestamp = GST_CLOCK_TIME_NONE; + proxy->duration = GST_CLOCK_TIME_NONE; + proxy->has_crop_rect = FALSE; + gst_vaapi_object_ref (proxy->surface); + return proxy; error: - gst_vaapi_surface_proxy_unref(proxy); - return NULL; + gst_vaapi_surface_proxy_unref (proxy); + return NULL; } - /** * gst_vaapi_surface_proxy_copy: * @proxy: the parent #GstVaapiSurfaceProxy @@ -118,32 +117,31 @@ error: * Returns: The same newly allocated @proxy object, or %NULL on error */ GstVaapiSurfaceProxy * -gst_vaapi_surface_proxy_copy(GstVaapiSurfaceProxy *proxy) +gst_vaapi_surface_proxy_copy (GstVaapiSurfaceProxy * proxy) { - GstVaapiSurfaceProxy *copy; + GstVaapiSurfaceProxy *copy; - g_return_val_if_fail(proxy != NULL, NULL); + g_return_val_if_fail (proxy != NULL, NULL); - copy = (GstVaapiSurfaceProxy *) - gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class()); - if (!copy) - return NULL; + copy = (GstVaapiSurfaceProxy *) + gst_vaapi_mini_object_new (gst_vaapi_surface_proxy_class ()); + if (!copy) + return NULL; - GST_VAAPI_SURFACE_PROXY_FLAGS(copy) = - GST_VAAPI_SURFACE_PROXY_FLAGS(proxy); + GST_VAAPI_SURFACE_PROXY_FLAGS (copy) = GST_VAAPI_SURFACE_PROXY_FLAGS (proxy); - copy->parent = gst_vaapi_surface_proxy_ref(proxy->parent ? - proxy->parent : proxy); - copy->pool = gst_vaapi_video_pool_ref(proxy->pool); - copy->surface = gst_vaapi_object_ref(proxy->surface); - copy->view_id = proxy->view_id; - copy->timestamp = proxy->timestamp; - copy->duration = proxy->duration; - copy->destroy_func = NULL; - copy->has_crop_rect = proxy->has_crop_rect; - if (copy->has_crop_rect) - copy->crop_rect = proxy->crop_rect; - return copy; + copy->parent = gst_vaapi_surface_proxy_ref (proxy->parent ? + proxy->parent : proxy); + copy->pool = gst_vaapi_video_pool_ref (proxy->pool); + copy->surface = gst_vaapi_object_ref (proxy->surface); + copy->view_id = proxy->view_id; + copy->timestamp = proxy->timestamp; + copy->duration = proxy->duration; + copy->destroy_func = NULL; + copy->has_crop_rect = proxy->has_crop_rect; + if (copy->has_crop_rect) + copy->crop_rect = proxy->crop_rect; + return copy; } /** @@ -155,12 +153,13 @@ gst_vaapi_surface_proxy_copy(GstVaapiSurfaceProxy *proxy) * Returns: The same @proxy argument */ GstVaapiSurfaceProxy * -gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy) +gst_vaapi_surface_proxy_ref (GstVaapiSurfaceProxy * proxy) { - g_return_val_if_fail(proxy != NULL, NULL); + g_return_val_if_fail (proxy != NULL, NULL); - return GST_VAAPI_SURFACE_PROXY(gst_vaapi_mini_object_ref( - GST_VAAPI_MINI_OBJECT(proxy))); + return + GST_VAAPI_SURFACE_PROXY (gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT + (proxy))); } /** @@ -171,11 +170,11 @@ gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy) * the reference count reaches zero, the object will be free'd. */ void -gst_vaapi_surface_proxy_unref(GstVaapiSurfaceProxy *proxy) +gst_vaapi_surface_proxy_unref (GstVaapiSurfaceProxy * proxy) { - g_return_if_fail(proxy != NULL); + g_return_if_fail (proxy != NULL); - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(proxy)); + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (proxy)); } /** @@ -188,13 +187,13 @@ gst_vaapi_surface_proxy_unref(GstVaapiSurfaceProxy *proxy) * object. However, @new_proxy can be NULL. */ void -gst_vaapi_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr, - GstVaapiSurfaceProxy *new_proxy) +gst_vaapi_surface_proxy_replace (GstVaapiSurfaceProxy ** old_proxy_ptr, + GstVaapiSurfaceProxy * new_proxy) { - g_return_if_fail(old_proxy_ptr != NULL); + 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_mini_object_replace ((GstVaapiMiniObject **) old_proxy_ptr, + GST_VAAPI_MINI_OBJECT (new_proxy)); } /** @@ -206,11 +205,11 @@ gst_vaapi_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr, * Return value: the #GstVaapiSurface */ GstVaapiSurface * -gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy) +gst_vaapi_surface_proxy_get_surface (GstVaapiSurfaceProxy * proxy) { - g_return_val_if_fail(proxy != NULL, NULL); + g_return_val_if_fail (proxy != NULL, NULL); - return GST_VAAPI_SURFACE_PROXY_SURFACE(proxy); + return GST_VAAPI_SURFACE_PROXY_SURFACE (proxy); } /** @@ -223,11 +222,11 @@ gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy) * Return value: the set of #GstVaapiSurfaceProxyFlags */ guint -gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy) +gst_vaapi_surface_proxy_get_flags (GstVaapiSurfaceProxy * proxy) { - g_return_val_if_fail(proxy != NULL, 0); - - return GST_VAAPI_SURFACE_PROXY_FLAGS(proxy); + g_return_val_if_fail (proxy != NULL, 0); + + return GST_VAAPI_SURFACE_PROXY_FLAGS (proxy); } /** @@ -239,12 +238,12 @@ gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy) * Return value: the #GstVaapiID */ GstVaapiID -gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) +gst_vaapi_surface_proxy_get_surface_id (GstVaapiSurfaceProxy * proxy) { - g_return_val_if_fail(proxy != NULL, VA_INVALID_ID); - g_return_val_if_fail(proxy->surface != NULL, VA_INVALID_ID); + g_return_val_if_fail (proxy != NULL, VA_INVALID_ID); + g_return_val_if_fail (proxy->surface != NULL, VA_INVALID_ID); - return GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy); + return GST_VAAPI_SURFACE_PROXY_SURFACE_ID (proxy); } /** @@ -256,11 +255,11 @@ gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy) * Return value: the #GstVaapiID */ guintptr -gst_vaapi_surface_proxy_get_view_id(GstVaapiSurfaceProxy *proxy) +gst_vaapi_surface_proxy_get_view_id (GstVaapiSurfaceProxy * proxy) { - g_return_val_if_fail(proxy != NULL, 0); + g_return_val_if_fail (proxy != NULL, 0); - return GST_VAAPI_SURFACE_PROXY_VIEW_ID(proxy); + return GST_VAAPI_SURFACE_PROXY_VIEW_ID (proxy); } /** @@ -272,11 +271,11 @@ gst_vaapi_surface_proxy_get_view_id(GstVaapiSurfaceProxy *proxy) * Return value: the presentation timestamp */ GstClockTime -gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy) +gst_vaapi_surface_proxy_get_timestamp (GstVaapiSurfaceProxy * proxy) { - g_return_val_if_fail(proxy != NULL, 0); - - return GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy); + g_return_val_if_fail (proxy != NULL, 0); + + return GST_VAAPI_SURFACE_PROXY_TIMESTAMP (proxy); } /** @@ -288,11 +287,11 @@ gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy) * Return value: the presentation duration */ GstClockTime -gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy) +gst_vaapi_surface_proxy_get_duration (GstVaapiSurfaceProxy * proxy) { - g_return_val_if_fail(proxy != NULL, 0); - - return GST_VAAPI_SURFACE_PROXY_DURATION(proxy); + g_return_val_if_fail (proxy != NULL, 0); + + return GST_VAAPI_SURFACE_PROXY_DURATION (proxy); } /** @@ -307,13 +306,13 @@ gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy) * the callback function shall not expect anything from that. */ void -gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy, +gst_vaapi_surface_proxy_set_destroy_notify (GstVaapiSurfaceProxy * proxy, GDestroyNotify destroy_func, gpointer user_data) { - g_return_if_fail(proxy != NULL); + g_return_if_fail (proxy != NULL); - proxy->destroy_func = destroy_func; - proxy->destroy_data = user_data; + proxy->destroy_func = destroy_func; + proxy->destroy_data = user_data; } /** @@ -331,11 +330,11 @@ gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy, * associated with the surface proxy */ const GstVaapiRectangle * -gst_vaapi_surface_proxy_get_crop_rect(GstVaapiSurfaceProxy *proxy) +gst_vaapi_surface_proxy_get_crop_rect (GstVaapiSurfaceProxy * proxy) { - g_return_val_if_fail(proxy != NULL, NULL); + g_return_val_if_fail (proxy != NULL, NULL); - return GST_VAAPI_SURFACE_PROXY_CROP_RECT(proxy); + return GST_VAAPI_SURFACE_PROXY_CROP_RECT (proxy); } /** @@ -346,12 +345,12 @@ gst_vaapi_surface_proxy_get_crop_rect(GstVaapiSurfaceProxy *proxy) * Associates the @crop_rect with the @proxy */ void -gst_vaapi_surface_proxy_set_crop_rect(GstVaapiSurfaceProxy *proxy, - const GstVaapiRectangle *crop_rect) +gst_vaapi_surface_proxy_set_crop_rect (GstVaapiSurfaceProxy * proxy, + const GstVaapiRectangle * crop_rect) { - g_return_if_fail(proxy != NULL); + g_return_if_fail (proxy != NULL); - proxy->has_crop_rect = crop_rect != NULL; - if (proxy->has_crop_rect) - proxy->crop_rect = *crop_rect; + proxy->has_crop_rect = crop_rect != NULL; + if (proxy->has_crop_rect) + proxy->crop_rect = *crop_rect; } diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index e0e358f64a..5129dc3f32 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -42,13 +42,14 @@ G_BEGIN_DECLS * * Flags for #GstVaapiDecoderFrame. */ -typedef enum { - GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED = (1 << 0), - GST_VAAPI_SURFACE_PROXY_FLAG_TFF = (1 << 1), - GST_VAAPI_SURFACE_PROXY_FLAG_RFF = (1 << 2), - GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD = (1 << 3), - GST_VAAPI_SURFACE_PROXY_FLAG_FFB = (1 << 4), - GST_VAAPI_SURFACE_PROXY_FLAG_LAST = (1 << 8) +typedef enum +{ + GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED = (1 << 0), + GST_VAAPI_SURFACE_PROXY_FLAG_TFF = (1 << 1), + GST_VAAPI_SURFACE_PROXY_FLAG_RFF = (1 << 2), + GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD = (1 << 3), + GST_VAAPI_SURFACE_PROXY_FLAG_FFB = (1 << 4), + GST_VAAPI_SURFACE_PROXY_FLAG_LAST = (1 << 8) } GstVaapiSurfaceProxyFlags; /** @@ -58,7 +59,7 @@ typedef enum { * Macro that evaluates to the #GstVaapiSurface of @proxy. */ #define GST_VAAPI_SURFACE_PROXY_SURFACE(proxy) \ - gst_vaapi_surface_proxy_get_surface(proxy) + gst_vaapi_surface_proxy_get_surface (proxy) /** * GST_VAAPI_SURFACE_PROXY_SURFACE_ID: @@ -68,7 +69,7 @@ typedef enum { * surface. */ #define GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) \ - gst_vaapi_surface_proxy_get_surface_id(proxy) + gst_vaapi_surface_proxy_get_surface_id (proxy) /** * GST_VAAPI_SURFACE_PROXY_VIEW_ID: @@ -78,7 +79,7 @@ typedef enum { * surface. */ #define GST_VAAPI_SURFACE_PROXY_VIEW_ID(proxy) \ - gst_vaapi_surface_proxy_get_view_id(proxy) + gst_vaapi_surface_proxy_get_view_id (proxy) /** * GST_VAAPI_SURFACE_PROXY_TIMESTAMP: @@ -88,7 +89,7 @@ typedef enum { * underlying @proxy surface. */ #define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy) \ - gst_vaapi_surface_proxy_get_timestamp(proxy) + gst_vaapi_surface_proxy_get_timestamp (proxy) /** * GST_VAAPI_SURFACE_PROXY_DURATION: @@ -98,52 +99,52 @@ typedef enum { * underlying @proxy surface. */ #define GST_VAAPI_SURFACE_PROXY_DURATION(proxy) \ - gst_vaapi_surface_proxy_get_duration(proxy) + gst_vaapi_surface_proxy_get_duration (proxy) GstVaapiSurfaceProxy * -gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool); +gst_vaapi_surface_proxy_new_from_pool (GstVaapiSurfacePool * pool); GstVaapiSurfaceProxy * -gst_vaapi_surface_proxy_copy(GstVaapiSurfaceProxy *proxy); +gst_vaapi_surface_proxy_copy (GstVaapiSurfaceProxy * proxy); GstVaapiSurfaceProxy * -gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy); +gst_vaapi_surface_proxy_ref (GstVaapiSurfaceProxy * proxy); void -gst_vaapi_surface_proxy_unref(GstVaapiSurfaceProxy *proxy); +gst_vaapi_surface_proxy_unref (GstVaapiSurfaceProxy * proxy); void -gst_vaapi_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr, - GstVaapiSurfaceProxy *new_proxy); +gst_vaapi_surface_proxy_replace (GstVaapiSurfaceProxy ** old_proxy_ptr, + GstVaapiSurfaceProxy * new_proxy); guint -gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy); +gst_vaapi_surface_proxy_get_flags (GstVaapiSurfaceProxy * proxy); GstVaapiSurface * -gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy); +gst_vaapi_surface_proxy_get_surface (GstVaapiSurfaceProxy * proxy); GstVaapiID -gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy); +gst_vaapi_surface_proxy_get_surface_id (GstVaapiSurfaceProxy * proxy); guintptr -gst_vaapi_surface_proxy_get_view_id(GstVaapiSurfaceProxy *proxy); +gst_vaapi_surface_proxy_get_view_id (GstVaapiSurfaceProxy * proxy); GstClockTime -gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy); +gst_vaapi_surface_proxy_get_timestamp (GstVaapiSurfaceProxy * proxy); GstClockTime -gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy); +gst_vaapi_surface_proxy_get_duration (GstVaapiSurfaceProxy * proxy); void -gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy, +gst_vaapi_surface_proxy_set_destroy_notify (GstVaapiSurfaceProxy * proxy, GDestroyNotify destroy_func, gpointer user_data); const GstVaapiRectangle * -gst_vaapi_surface_proxy_get_crop_rect(GstVaapiSurfaceProxy *proxy); +gst_vaapi_surface_proxy_get_crop_rect (GstVaapiSurfaceProxy * proxy); void -gst_vaapi_surface_proxy_set_crop_rect(GstVaapiSurfaceProxy *proxy, - const GstVaapiRectangle *crop_rect); +gst_vaapi_surface_proxy_set_crop_rect (GstVaapiSurfaceProxy * proxy, + const GstVaapiRectangle * crop_rect); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index 24043994dc..d3bc7abc02 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -31,22 +31,23 @@ #include "gstvaapisurface_priv.h" #define GST_VAAPI_SURFACE_PROXY(obj) \ - ((GstVaapiSurfaceProxy *)(obj)) + ((GstVaapiSurfaceProxy *) (obj)) -struct _GstVaapiSurfaceProxy { - /*< private >*/ - GstVaapiMiniObject parent_instance; - GstVaapiSurfaceProxy *parent; +struct _GstVaapiSurfaceProxy +{ + /*< private >*/ + GstVaapiMiniObject parent_instance; + GstVaapiSurfaceProxy *parent; - GstVaapiVideoPool *pool; - GstVaapiSurface *surface; - guintptr view_id; - GstClockTime timestamp; - GstClockTime duration; - GDestroyNotify destroy_func; - gpointer destroy_data; - GstVaapiRectangle crop_rect; - guint has_crop_rect : 1; + GstVaapiVideoPool *pool; + GstVaapiSurface *surface; + guintptr view_id; + GstClockTime timestamp; + GstClockTime duration; + GDestroyNotify destroy_func; + gpointer destroy_data; + GstVaapiRectangle crop_rect; + guint has_crop_rect:1; }; #define GST_VAAPI_SURFACE_PROXY_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS @@ -63,7 +64,7 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_SURFACE #define GST_VAAPI_SURFACE_PROXY_SURFACE(proxy) \ - GST_VAAPI_SURFACE_PROXY(proxy)->surface + (GST_VAAPI_SURFACE_PROXY (proxy)->surface) /** * GST_VAAPI_SURFACE_PROXY_SURFACE_ID: @@ -76,7 +77,7 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_SURFACE_ID #define GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) \ - GST_VAAPI_OBJECT_ID(GST_VAAPI_SURFACE_PROXY(proxy)->surface) + (GST_VAAPI_OBJECT_ID (GST_VAAPI_SURFACE_PROXY (proxy)->surface)) /** * GST_VAAPI_SURFACE_PROXY_VIEW_ID: @@ -89,7 +90,7 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_VIEW_ID #define GST_VAAPI_SURFACE_PROXY_VIEW_ID(proxy) \ - GST_VAAPI_SURFACE_PROXY(proxy)->view_id + (GST_VAAPI_SURFACE_PROXY (proxy)->view_id) /** * GST_VAAPI_SURFACE_PROXY_TIMESTAMP: @@ -102,7 +103,7 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_TIMESTAMP #define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy) \ - GST_VAAPI_SURFACE_PROXY(proxy)->timestamp + (GST_VAAPI_SURFACE_PROXY (proxy)->timestamp) /** * GST_VAAPI_SURFACE_PROXY_DURATION: @@ -115,7 +116,7 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_DURATION #define GST_VAAPI_SURFACE_PROXY_DURATION(proxy) \ - GST_VAAPI_SURFACE_PROXY(proxy)->duration + (GST_VAAPI_SURFACE_PROXY (proxy)->duration) /** * GST_VAAPI_SURFACE_PROXY_CROP_RECT: @@ -127,7 +128,7 @@ struct _GstVaapiSurfaceProxy { */ #undef GST_VAAPI_SURFACE_PROXY_CROP_RECT #define GST_VAAPI_SURFACE_PROXY_CROP_RECT(proxy) \ - (GST_VAAPI_SURFACE_PROXY(proxy)->has_crop_rect ? \ - &GST_VAAPI_SURFACE_PROXY(proxy)->crop_rect : NULL) + (GST_VAAPI_SURFACE_PROXY (proxy)->has_crop_rect ? \ + &GST_VAAPI_SURFACE_PROXY (proxy)->crop_rect : NULL) #endif /* GST_VAAPI_SURFACE_PROXY_PRIV_H */ From 568a62ae1e589c04239ab123177eae6d500dcaa5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 23 Jan 2015 16:44:34 +0100 Subject: [PATCH 1830/3781] surfaceproxy: add helper to create a wrapped surface object. Add new gst_vaapi_surface_proxy_new() helper to wrap a surface into a proxy. The main use case for that is to convey additional information at the proxy level that would not be suitable to the plain surface. --- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 52 ++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 3 ++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 56e1ea69fa..96865c7dfa 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -62,6 +62,51 @@ gst_vaapi_surface_proxy_class (void) return &GstVaapiSurfaceProxyClass; } +static void +gst_vaapi_surface_proxy_init_properties (GstVaapiSurfaceProxy * proxy) +{ + proxy->view_id = 0; + proxy->timestamp = GST_CLOCK_TIME_NONE; + proxy->duration = GST_CLOCK_TIME_NONE; + proxy->has_crop_rect = FALSE; +} + +/** + * gst_vaapi_surface_proxy_new: + * @surface: a #GstVaapiSurface + * + * Creates a new #GstVaapiSurfaceProxy with the specified + * surface. This allows for transporting additional information that + * are not to be attached to the @surface directly. + * + * Return value: the newly allocated #GstVaapiSurfaceProxy object + */ +GstVaapiSurfaceProxy * +gst_vaapi_surface_proxy_new (GstVaapiSurface * surface) +{ + GstVaapiSurfaceProxy *proxy; + + g_return_val_if_fail (surface != NULL, NULL); + + proxy = (GstVaapiSurfaceProxy *) + gst_vaapi_mini_object_new (gst_vaapi_surface_proxy_class ()); + if (!proxy) + return NULL; + + proxy->parent = NULL; + proxy->destroy_func = NULL; + proxy->pool = NULL; + proxy->surface = gst_vaapi_object_ref (surface); + if (!proxy->surface) + goto error; + gst_vaapi_surface_proxy_init_properties (proxy); + return proxy; + +error: + gst_vaapi_surface_proxy_unref (proxy); + return NULL; +} + /** * gst_vaapi_surface_proxy_new_from_pool: * @pool: a #GstVaapiSurfacePool @@ -91,11 +136,8 @@ gst_vaapi_surface_proxy_new_from_pool (GstVaapiSurfacePool * pool) proxy->surface = gst_vaapi_video_pool_get_object (proxy->pool); if (!proxy->surface) goto error; - proxy->view_id = 0; - proxy->timestamp = GST_CLOCK_TIME_NONE; - proxy->duration = GST_CLOCK_TIME_NONE; - proxy->has_crop_rect = FALSE; gst_vaapi_object_ref (proxy->surface); + gst_vaapi_surface_proxy_init_properties (proxy); return proxy; error: @@ -132,7 +174,7 @@ gst_vaapi_surface_proxy_copy (GstVaapiSurfaceProxy * proxy) copy->parent = gst_vaapi_surface_proxy_ref (proxy->parent ? proxy->parent : proxy); - copy->pool = gst_vaapi_video_pool_ref (proxy->pool); + copy->pool = proxy->pool ? gst_vaapi_video_pool_ref (proxy->pool) : NULL; copy->surface = gst_vaapi_object_ref (proxy->surface); copy->view_id = proxy->view_id; copy->timestamp = proxy->timestamp; diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 5129dc3f32..47d3021352 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -101,6 +101,9 @@ typedef enum #define GST_VAAPI_SURFACE_PROXY_DURATION(proxy) \ gst_vaapi_surface_proxy_get_duration (proxy) +GstVaapiSurfaceProxy * +gst_vaapi_surface_proxy_new (GstVaapiSurface * surface); + GstVaapiSurfaceProxy * gst_vaapi_surface_proxy_new_from_pool (GstVaapiSurfacePool * pool); From 334dd704b668a59be93892fcc0733a9f588a388c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Sep 2014 14:57:57 +0200 Subject: [PATCH 1831/3781] surface: re-indent all GstVaapiSurface related source code. --- gst-libs/gst/vaapi/gstvaapisurface.c | 866 ++++++++++------------ gst-libs/gst/vaapi/gstvaapisurface.h | 128 ++-- gst-libs/gst/vaapi/gstvaapisurface_priv.h | 46 +- 3 files changed, 479 insertions(+), 561 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index ba848cb774..ce211fe9f0 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -41,162 +41,148 @@ #include "gstvaapidebug.h" static gboolean -_gst_vaapi_surface_associate_subpicture( - GstVaapiSurface *surface, - GstVaapiSubpicture *subpicture, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect -); +_gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface, + GstVaapiSubpicture * subpicture, const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect); static gboolean -_gst_vaapi_surface_deassociate_subpicture( - GstVaapiSurface *surface, - GstVaapiSubpicture *subpicture -); +_gst_vaapi_surface_deassociate_subpicture (GstVaapiSurface * surface, + GstVaapiSubpicture * subpicture); static void -destroy_subpicture_cb(gpointer subpicture, gpointer surface) +destroy_subpicture_cb (gpointer subpicture, gpointer surface) { - _gst_vaapi_surface_deassociate_subpicture(surface, subpicture); - gst_vaapi_object_unref(subpicture); + _gst_vaapi_surface_deassociate_subpicture (surface, subpicture); + gst_vaapi_object_unref (subpicture); } static void -gst_vaapi_surface_destroy_subpictures(GstVaapiSurface *surface) +gst_vaapi_surface_destroy_subpictures (GstVaapiSurface * surface) { - if (surface->subpictures) { - g_ptr_array_foreach(surface->subpictures, destroy_subpicture_cb, - surface); - g_ptr_array_free(surface->subpictures, TRUE); - surface->subpictures = NULL; - } + if (surface->subpictures) { + g_ptr_array_foreach (surface->subpictures, destroy_subpicture_cb, surface); + g_ptr_array_free (surface->subpictures, TRUE); + surface->subpictures = NULL; + } } static void -gst_vaapi_surface_destroy(GstVaapiSurface *surface) +gst_vaapi_surface_destroy (GstVaapiSurface * surface) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface); - VASurfaceID surface_id; - VAStatus status; + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); + VASurfaceID surface_id; + VAStatus status; - surface_id = GST_VAAPI_OBJECT_ID(surface); - GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); + surface_id = GST_VAAPI_OBJECT_ID (surface); + GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); - gst_vaapi_surface_destroy_subpictures(surface); - gst_vaapi_surface_set_parent_context(surface, NULL); - - if (surface_id != VA_INVALID_SURFACE) { - GST_VAAPI_DISPLAY_LOCK(display); - status = vaDestroySurfaces( - GST_VAAPI_DISPLAY_VADISPLAY(display), - &surface_id, 1 - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaDestroySurfaces()")) - g_warning("failed to destroy surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(surface_id)); - GST_VAAPI_OBJECT_ID(surface) = VA_INVALID_SURFACE; - } + gst_vaapi_surface_destroy_subpictures (surface); + gst_vaapi_surface_set_parent_context (surface, NULL); + + if (surface_id != VA_INVALID_SURFACE) { + GST_VAAPI_DISPLAY_LOCK (display); + status = vaDestroySurfaces (GST_VAAPI_DISPLAY_VADISPLAY (display), + &surface_id, 1); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaDestroySurfaces()")) + g_warning ("failed to destroy surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (surface_id)); + GST_VAAPI_OBJECT_ID (surface) = VA_INVALID_SURFACE; + } } static gboolean -gst_vaapi_surface_create(GstVaapiSurface *surface, +gst_vaapi_surface_create (GstVaapiSurface * surface, GstVaapiChromaType chroma_type, guint width, guint height) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface); - VASurfaceID surface_id; - VAStatus status; - guint va_chroma_format; + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); + VASurfaceID surface_id; + VAStatus status; + guint va_chroma_format; - va_chroma_format = from_GstVaapiChromaType(chroma_type); - if (!va_chroma_format) - goto error_unsupported_chroma_type; + va_chroma_format = from_GstVaapiChromaType (chroma_type); + if (!va_chroma_format) + goto error_unsupported_chroma_type; - GST_VAAPI_DISPLAY_LOCK(display); - status = vaCreateSurfaces( - GST_VAAPI_DISPLAY_VADISPLAY(display), - width, height, va_chroma_format, - 1, &surface_id - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaCreateSurfaces()")) - return FALSE; - - surface->format = GST_VIDEO_FORMAT_UNKNOWN; - surface->chroma_type = chroma_type; - surface->width = width; - surface->height = height; - - GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); - GST_VAAPI_OBJECT_ID(surface) = surface_id; - return TRUE; - - /* ERRORS */ -error_unsupported_chroma_type: - GST_ERROR("unsupported chroma-type %u", chroma_type); + GST_VAAPI_DISPLAY_LOCK (display); + status = vaCreateSurfaces (GST_VAAPI_DISPLAY_VADISPLAY (display), + width, height, va_chroma_format, 1, &surface_id); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaCreateSurfaces()")) return FALSE; + + surface->format = GST_VIDEO_FORMAT_UNKNOWN; + surface->chroma_type = chroma_type; + surface->width = width; + surface->height = height; + + GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); + GST_VAAPI_OBJECT_ID (surface) = surface_id; + return TRUE; + + /* ERRORS */ +error_unsupported_chroma_type: + GST_ERROR ("unsupported chroma-type %u", chroma_type); + return FALSE; } static gboolean -gst_vaapi_surface_create_with_format(GstVaapiSurface *surface, +gst_vaapi_surface_create_with_format (GstVaapiSurface * surface, GstVideoFormat format, guint width, guint height) { #if VA_CHECK_VERSION(0,34,0) - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface); - VASurfaceID surface_id; - VAStatus status; - guint chroma_type, va_chroma_format; - const VAImageFormat *va_format; - VASurfaceAttrib attrib; + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); + VASurfaceID surface_id; + VAStatus status; + guint chroma_type, va_chroma_format; + const VAImageFormat *va_format; + VASurfaceAttrib attrib; - va_format = gst_vaapi_video_format_to_va_format(format); - if (!va_format) - goto error_unsupported_format; + va_format = gst_vaapi_video_format_to_va_format (format); + if (!va_format) + goto error_unsupported_format; - chroma_type = gst_vaapi_video_format_get_chroma_type(format); - if (!chroma_type) - goto error_unsupported_format; + chroma_type = gst_vaapi_video_format_get_chroma_type (format); + if (!chroma_type) + goto error_unsupported_format; - va_chroma_format = from_GstVaapiChromaType(chroma_type); - if (!va_chroma_format) - goto error_unsupported_format; + va_chroma_format = from_GstVaapiChromaType (chroma_type); + if (!va_chroma_format) + goto error_unsupported_format; - attrib.flags = VA_SURFACE_ATTRIB_SETTABLE; - attrib.type = VASurfaceAttribPixelFormat; - attrib.value.type = VAGenericValueTypeInteger; - attrib.value.value.i = va_format->fourcc; + attrib.flags = VA_SURFACE_ATTRIB_SETTABLE; + attrib.type = VASurfaceAttribPixelFormat; + attrib.value.type = VAGenericValueTypeInteger; + attrib.value.value.i = va_format->fourcc; - GST_VAAPI_DISPLAY_LOCK(display); - status = vaCreateSurfaces( - GST_VAAPI_DISPLAY_VADISPLAY(display), - va_chroma_format, width, height, - &surface_id, 1, - &attrib, 1 - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaCreateSurfaces()")) - return FALSE; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaCreateSurfaces (GST_VAAPI_DISPLAY_VADISPLAY (display), + va_chroma_format, width, height, &surface_id, 1, &attrib, 1); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaCreateSurfaces()")) + return FALSE; - surface->format = format; - surface->chroma_type = chroma_type; - surface->width = width; - surface->height = height; + surface->format = format; + surface->chroma_type = chroma_type; + surface->width = width; + surface->height = height; - GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); - GST_VAAPI_OBJECT_ID(surface) = surface_id; - return TRUE; + GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); + GST_VAAPI_OBJECT_ID (surface) = surface_id; + return TRUE; - /* ERRORS */ + /* ERRORS */ error_unsupported_format: - GST_ERROR("unsupported format %s", gst_vaapi_video_format_to_string(format)); - return FALSE; + GST_ERROR ("unsupported format %s", + gst_vaapi_video_format_to_string (format)); + return FALSE; #else - return FALSE; + return FALSE; #endif } #define gst_vaapi_surface_finalize gst_vaapi_surface_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiSurface, gst_vaapi_surface) +GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSurface, gst_vaapi_surface); /** * gst_vaapi_surface_new: @@ -211,28 +197,24 @@ GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiSurface, gst_vaapi_surface) * Return value: the newly allocated #GstVaapiSurface object */ GstVaapiSurface * -gst_vaapi_surface_new( - GstVaapiDisplay *display, - GstVaapiChromaType chroma_type, - guint width, - guint height -) +gst_vaapi_surface_new (GstVaapiDisplay * display, + GstVaapiChromaType chroma_type, guint width, guint height) { - GstVaapiSurface *surface; + GstVaapiSurface *surface; - GST_DEBUG("size %ux%u, chroma type 0x%x", width, height, chroma_type); + GST_DEBUG ("size %ux%u, chroma type 0x%x", width, height, chroma_type); - surface = gst_vaapi_object_new(gst_vaapi_surface_class(), display); - if (!surface) - return NULL; + surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); + if (!surface) + return NULL; - if (!gst_vaapi_surface_create(surface, chroma_type, width, height)) - goto error; - return surface; + if (!gst_vaapi_surface_create (surface, chroma_type, width, height)) + goto error; + return surface; error: - gst_vaapi_object_unref(surface); - return NULL; + gst_vaapi_object_unref (surface); + return NULL; } /** @@ -250,29 +232,25 @@ error: * supported or failed. */ GstVaapiSurface * -gst_vaapi_surface_new_with_format( - GstVaapiDisplay *display, - GstVideoFormat format, - guint width, - guint height -) +gst_vaapi_surface_new_with_format (GstVaapiDisplay * display, + GstVideoFormat format, guint width, guint height) { - GstVaapiSurface *surface; + GstVaapiSurface *surface; - GST_DEBUG("size %ux%u, format %s", width, height, - gst_vaapi_video_format_to_string(format)); + GST_DEBUG ("size %ux%u, format %s", width, height, + gst_vaapi_video_format_to_string (format)); - surface = gst_vaapi_object_new(gst_vaapi_surface_class(), display); - if (!surface) - return NULL; + surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); + if (!surface) + return NULL; - if (!gst_vaapi_surface_create_with_format(surface, format, width, height)) - goto error; - return surface; + if (!gst_vaapi_surface_create_with_format (surface, format, width, height)) + goto error; + return surface; error: - gst_vaapi_object_unref(surface); - return NULL; + gst_vaapi_object_unref (surface); + return NULL; } /** @@ -284,11 +262,11 @@ error: * Return value: the underlying VA surface id */ GstVaapiID -gst_vaapi_surface_get_id(GstVaapiSurface *surface) +gst_vaapi_surface_get_id (GstVaapiSurface * surface) { - g_return_val_if_fail(surface != NULL, VA_INVALID_SURFACE); + g_return_val_if_fail (surface != NULL, VA_INVALID_SURFACE); - return GST_VAAPI_OBJECT_ID(surface); + return GST_VAAPI_OBJECT_ID (surface); } /** @@ -300,11 +278,11 @@ gst_vaapi_surface_get_id(GstVaapiSurface *surface) * Return value: the #GstVaapiChromaType */ GstVaapiChromaType -gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface) +gst_vaapi_surface_get_chroma_type (GstVaapiSurface * surface) { - g_return_val_if_fail(surface != NULL, 0); + g_return_val_if_fail (surface != NULL, 0); - return GST_VAAPI_SURFACE_CHROMA_TYPE(surface); + return GST_VAAPI_SURFACE_CHROMA_TYPE (surface); } /** @@ -318,21 +296,21 @@ gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface) * the underlying video format could not be determined */ GstVideoFormat -gst_vaapi_surface_get_format(GstVaapiSurface *surface) +gst_vaapi_surface_get_format (GstVaapiSurface * surface) { - g_return_val_if_fail(surface != NULL, 0); + g_return_val_if_fail (surface != NULL, 0); - /* Try to determine the underlying VA surface format */ - if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) { - GstVaapiImage * const image = gst_vaapi_surface_derive_image(surface); - if (image) { - surface->format = GST_VAAPI_IMAGE_FORMAT(image); - gst_vaapi_object_unref(image); - } - if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) - surface->format = GST_VIDEO_FORMAT_ENCODED; + /* Try to determine the underlying VA surface format */ + if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) { + GstVaapiImage *const image = gst_vaapi_surface_derive_image (surface); + if (image) { + surface->format = GST_VAAPI_IMAGE_FORMAT (image); + gst_vaapi_object_unref (image); } - return GST_VAAPI_SURFACE_FORMAT(surface); + if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) + surface->format = GST_VIDEO_FORMAT_ENCODED; + } + return GST_VAAPI_SURFACE_FORMAT (surface); } /** @@ -344,11 +322,11 @@ gst_vaapi_surface_get_format(GstVaapiSurface *surface) * Return value: the surface width, in pixels */ guint -gst_vaapi_surface_get_width(GstVaapiSurface *surface) +gst_vaapi_surface_get_width (GstVaapiSurface * surface) { - g_return_val_if_fail(surface != NULL, 0); + g_return_val_if_fail (surface != NULL, 0); - return GST_VAAPI_SURFACE_WIDTH(surface); + return GST_VAAPI_SURFACE_WIDTH (surface); } /** @@ -360,35 +338,32 @@ gst_vaapi_surface_get_width(GstVaapiSurface *surface) * Return value: the surface height, in pixels. */ guint -gst_vaapi_surface_get_height(GstVaapiSurface *surface) +gst_vaapi_surface_get_height (GstVaapiSurface * surface) { - g_return_val_if_fail(surface != NULL, 0); + g_return_val_if_fail (surface != NULL, 0); - return GST_VAAPI_SURFACE_HEIGHT(surface); + return GST_VAAPI_SURFACE_HEIGHT (surface); } /** * gst_vaapi_surface_get_size: * @surface: a #GstVaapiSurface - * @pwidth: return location for the width, or %NULL - * @pheight: return location for the height, or %NULL + * @width_ptr: return location for the width, or %NULL + * @height_ptr: return location for the height, or %NULL * * Retrieves the dimensions of a #GstVaapiSurface. */ void -gst_vaapi_surface_get_size( - GstVaapiSurface *surface, - guint *pwidth, - guint *pheight -) +gst_vaapi_surface_get_size (GstVaapiSurface * surface, + guint * width_ptr, guint * height_ptr) { - g_return_if_fail(surface != NULL); + g_return_if_fail (surface != NULL); - if (pwidth) - *pwidth = GST_VAAPI_SURFACE_WIDTH(surface); + if (width_ptr) + *width_ptr = GST_VAAPI_SURFACE_WIDTH (surface); - if (pheight) - *pheight = GST_VAAPI_SURFACE_HEIGHT(surface); + if (height_ptr) + *height_ptr = GST_VAAPI_SURFACE_HEIGHT (surface); } /** @@ -401,14 +376,12 @@ gst_vaapi_surface_get_size( * which will be released when the surface is destroyed. */ void -gst_vaapi_surface_set_parent_context( - GstVaapiSurface *surface, - GstVaapiContext *context -) +gst_vaapi_surface_set_parent_context (GstVaapiSurface * surface, + GstVaapiContext * context) { - g_return_if_fail(surface != NULL); + g_return_if_fail (surface != NULL); - surface->parent_context = NULL; + surface->parent_context = NULL; } /** @@ -422,11 +395,11 @@ gst_vaapi_surface_set_parent_context( * Return value: the parent context, if any. */ GstVaapiContext * -gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface) +gst_vaapi_surface_get_parent_context (GstVaapiSurface * surface) { - g_return_val_if_fail(surface != NULL, NULL); + g_return_val_if_fail (surface != NULL, NULL); - return surface->parent_context; + return surface->parent_context; } /** @@ -454,31 +427,28 @@ gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface) * on failure */ GstVaapiImage * -gst_vaapi_surface_derive_image(GstVaapiSurface *surface) +gst_vaapi_surface_derive_image (GstVaapiSurface * surface) { - GstVaapiDisplay *display; - VAImage va_image; - VAStatus status; + GstVaapiDisplay *display; + VAImage va_image; + VAStatus status; - g_return_val_if_fail(surface != NULL, NULL); + g_return_val_if_fail (surface != NULL, NULL); - display = GST_VAAPI_OBJECT_DISPLAY(surface); - va_image.image_id = VA_INVALID_ID; - va_image.buf = VA_INVALID_ID; + display = GST_VAAPI_OBJECT_DISPLAY (surface); + va_image.image_id = VA_INVALID_ID; + va_image.buf = VA_INVALID_ID; - GST_VAAPI_DISPLAY_LOCK(display); - status = vaDeriveImage( - GST_VAAPI_DISPLAY_VADISPLAY(display), - GST_VAAPI_OBJECT_ID(surface), - &va_image - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaDeriveImage()")) - return NULL; - if (va_image.image_id == VA_INVALID_ID || va_image.buf == VA_INVALID_ID) - return NULL; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaDeriveImage (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_OBJECT_ID (surface), &va_image); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaDeriveImage()")) + return NULL; + if (va_image.image_id == VA_INVALID_ID || va_image.buf == VA_INVALID_ID) + return NULL; - return gst_vaapi_image_new_with_image(display, &va_image); + return gst_vaapi_image_new_with_image (display, &va_image); } /** @@ -492,41 +462,37 @@ gst_vaapi_surface_derive_image(GstVaapiSurface *surface) * Return value: %TRUE on success */ gboolean -gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) +gst_vaapi_surface_get_image (GstVaapiSurface * surface, GstVaapiImage * image) { - GstVaapiDisplay *display; - VAImageID image_id; - VAStatus status; - guint width, height; + GstVaapiDisplay *display; + VAImageID image_id; + VAStatus status; + guint width, height; - g_return_val_if_fail(surface != NULL, FALSE); - g_return_val_if_fail(image != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); + g_return_val_if_fail (image != NULL, FALSE); - display = GST_VAAPI_OBJECT_DISPLAY(surface); - if (!display) - return FALSE; + display = GST_VAAPI_OBJECT_DISPLAY (surface); + if (!display) + return FALSE; - width = GST_VAAPI_IMAGE_WIDTH(image); - height = GST_VAAPI_IMAGE_HEIGHT(image); - if (width != surface->width || height != surface->height) - return FALSE; + width = GST_VAAPI_IMAGE_WIDTH (image); + height = GST_VAAPI_IMAGE_HEIGHT (image); + if (width != surface->width || height != surface->height) + return FALSE; - image_id = GST_VAAPI_OBJECT_ID(image); - if (image_id == VA_INVALID_ID) - return FALSE; + image_id = GST_VAAPI_OBJECT_ID (image); + if (image_id == VA_INVALID_ID) + return FALSE; - GST_VAAPI_DISPLAY_LOCK(display); - status = vaGetImage( - GST_VAAPI_DISPLAY_VADISPLAY(display), - GST_VAAPI_OBJECT_ID(surface), - 0, 0, width, height, - image_id - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaGetImage()")) - return FALSE; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaGetImage (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_OBJECT_ID (surface), 0, 0, width, height, image_id); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaGetImage()")) + return FALSE; - return TRUE; + return TRUE; } /** @@ -540,42 +506,38 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image) * Return value: %TRUE on success */ gboolean -gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) +gst_vaapi_surface_put_image (GstVaapiSurface * surface, GstVaapiImage * image) { - GstVaapiDisplay *display; - VAImageID image_id; - VAStatus status; - guint width, height; + GstVaapiDisplay *display; + VAImageID image_id; + VAStatus status; + guint width, height; - g_return_val_if_fail(surface != NULL, FALSE); - g_return_val_if_fail(image != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); + g_return_val_if_fail (image != NULL, FALSE); - display = GST_VAAPI_OBJECT_DISPLAY(surface); - if (!display) - return FALSE; + display = GST_VAAPI_OBJECT_DISPLAY (surface); + if (!display) + return FALSE; - width = GST_VAAPI_IMAGE_WIDTH(image); - height = GST_VAAPI_IMAGE_HEIGHT(image); - if (width != surface->width || height != surface->height) - return FALSE; + width = GST_VAAPI_IMAGE_WIDTH (image); + height = GST_VAAPI_IMAGE_HEIGHT (image); + if (width != surface->width || height != surface->height) + return FALSE; - image_id = GST_VAAPI_OBJECT_ID(image); - if (image_id == VA_INVALID_ID) - return FALSE; + image_id = GST_VAAPI_OBJECT_ID (image); + if (image_id == VA_INVALID_ID) + return FALSE; - GST_VAAPI_DISPLAY_LOCK(display); - status = vaPutImage( - GST_VAAPI_DISPLAY_VADISPLAY(display), - GST_VAAPI_OBJECT_ID(surface), - image_id, - 0, 0, width, height, - 0, 0, width, height - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaPutImage()")) - return FALSE; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaPutImage (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_OBJECT_ID (surface), image_id, 0, 0, width, height, + 0, 0, width, height); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaPutImage()")) + return FALSE; - return TRUE; + return TRUE; } /** @@ -597,100 +559,87 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image) * Return value: %TRUE on success */ gboolean -gst_vaapi_surface_associate_subpicture( - GstVaapiSurface *surface, - GstVaapiSubpicture *subpicture, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect -) +gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface, + GstVaapiSubpicture * subpicture, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) { - gboolean success; + gboolean success; - g_return_val_if_fail(surface != NULL, FALSE); - g_return_val_if_fail(subpicture != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); + g_return_val_if_fail (subpicture != NULL, FALSE); - if (!surface->subpictures) { - surface->subpictures = g_ptr_array_new(); - if (!surface->subpictures) - return FALSE; - } + if (!surface->subpictures) { + surface->subpictures = g_ptr_array_new (); + if (!surface->subpictures) + return FALSE; + } - if (g_ptr_array_remove_fast(surface->subpictures, subpicture)) { - success = _gst_vaapi_surface_deassociate_subpicture(surface, - subpicture); - gst_vaapi_object_unref(subpicture); - if (!success) - return FALSE; - } - - success = _gst_vaapi_surface_associate_subpicture( - surface, - subpicture, - src_rect, - dst_rect - ); + if (g_ptr_array_remove_fast (surface->subpictures, subpicture)) { + success = _gst_vaapi_surface_deassociate_subpicture (surface, subpicture); + gst_vaapi_object_unref (subpicture); if (!success) - return FALSE; + return FALSE; + } - g_ptr_array_add(surface->subpictures, gst_vaapi_object_ref(subpicture)); - return TRUE; + success = _gst_vaapi_surface_associate_subpicture (surface, + subpicture, src_rect, dst_rect); + if (!success) + return FALSE; + + g_ptr_array_add (surface->subpictures, gst_vaapi_object_ref (subpicture)); + return TRUE; } gboolean -_gst_vaapi_surface_associate_subpicture( - GstVaapiSurface *surface, - GstVaapiSubpicture *subpicture, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect -) +_gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface, + GstVaapiSubpicture * subpicture, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) { - GstVaapiDisplay *display; - GstVaapiRectangle src_rect_default, dst_rect_default; - GstVaapiImage *image; - VASurfaceID surface_id; - VAStatus status; + GstVaapiDisplay *display; + GstVaapiRectangle src_rect_default, dst_rect_default; + GstVaapiImage *image; + VASurfaceID surface_id; + VAStatus status; - display = GST_VAAPI_OBJECT_DISPLAY(surface); - if (!display) - return FALSE; + display = GST_VAAPI_OBJECT_DISPLAY (surface); + if (!display) + return FALSE; - surface_id = GST_VAAPI_OBJECT_ID(surface); - if (surface_id == VA_INVALID_SURFACE) - return FALSE; + surface_id = GST_VAAPI_OBJECT_ID (surface); + if (surface_id == VA_INVALID_SURFACE) + return FALSE; - if (!src_rect) { - image = gst_vaapi_subpicture_get_image(subpicture); - if (!image) - return FALSE; - src_rect = &src_rect_default; - src_rect_default.x = 0; - src_rect_default.y = 0; - src_rect_default.width = GST_VAAPI_IMAGE_WIDTH(image); - src_rect_default.height = GST_VAAPI_IMAGE_HEIGHT(image); - } + if (!src_rect) { + image = gst_vaapi_subpicture_get_image (subpicture); + if (!image) + return FALSE; + src_rect = &src_rect_default; + src_rect_default.x = 0; + src_rect_default.y = 0; + src_rect_default.width = GST_VAAPI_IMAGE_WIDTH (image); + src_rect_default.height = GST_VAAPI_IMAGE_HEIGHT (image); + } - if (!dst_rect) { - dst_rect = &dst_rect_default; - dst_rect_default.x = 0; - dst_rect_default.y = 0; - dst_rect_default.width = surface->width; - dst_rect_default.height = surface->height; - } + if (!dst_rect) { + dst_rect = &dst_rect_default; + dst_rect_default.x = 0; + dst_rect_default.y = 0; + dst_rect_default.width = surface->width; + dst_rect_default.height = surface->height; + } - GST_VAAPI_DISPLAY_LOCK(display); - status = vaAssociateSubpicture( - GST_VAAPI_DISPLAY_VADISPLAY(display), - GST_VAAPI_OBJECT_ID(subpicture), - &surface_id, 1, - src_rect->x, src_rect->y, src_rect->width, src_rect->height, - dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height, - from_GstVaapiSubpictureFlags(gst_vaapi_subpicture_get_flags(subpicture)) - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaAssociateSubpicture()")) - return FALSE; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaAssociateSubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_OBJECT_ID (subpicture), &surface_id, 1, + src_rect->x, src_rect->y, src_rect->width, src_rect->height, + dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height, + from_GstVaapiSubpictureFlags (gst_vaapi_subpicture_get_flags + (subpicture))); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaAssociateSubpicture()")) + return FALSE; - return TRUE; + return TRUE; } /** @@ -703,62 +652,55 @@ _gst_vaapi_surface_associate_subpicture( * Return value: %TRUE on success */ gboolean -gst_vaapi_surface_deassociate_subpicture( - GstVaapiSurface *surface, - GstVaapiSubpicture *subpicture -) +gst_vaapi_surface_deassociate_subpicture (GstVaapiSurface * surface, + GstVaapiSubpicture * subpicture) { - gboolean success; + gboolean success; - g_return_val_if_fail(surface != NULL, FALSE); - g_return_val_if_fail(subpicture != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); + g_return_val_if_fail (subpicture != NULL, FALSE); - if (!surface->subpictures) - return TRUE; + if (!surface->subpictures) + return TRUE; - /* First, check subpicture was really associated with this surface */ - if (!g_ptr_array_remove_fast(surface->subpictures, subpicture)) { - GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT " was not bound to " - "surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(subpicture)), - GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface))); - return TRUE; - } + /* First, check subpicture was really associated with this surface */ + if (!g_ptr_array_remove_fast (surface->subpictures, subpicture)) { + GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT " was not bound to " + "surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (subpicture)), + GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (surface))); + return TRUE; + } - success = _gst_vaapi_surface_deassociate_subpicture(surface, subpicture); - gst_vaapi_object_unref(subpicture); - return success; + success = _gst_vaapi_surface_deassociate_subpicture (surface, subpicture); + gst_vaapi_object_unref (subpicture); + return success; } gboolean -_gst_vaapi_surface_deassociate_subpicture( - GstVaapiSurface *surface, - GstVaapiSubpicture *subpicture -) +_gst_vaapi_surface_deassociate_subpicture (GstVaapiSurface * surface, + GstVaapiSubpicture * subpicture) { - GstVaapiDisplay *display; - VASurfaceID surface_id; - VAStatus status; + GstVaapiDisplay *display; + VASurfaceID surface_id; + VAStatus status; - display = GST_VAAPI_OBJECT_DISPLAY(surface); - if (!display) - return FALSE; + display = GST_VAAPI_OBJECT_DISPLAY (surface); + if (!display) + return FALSE; - surface_id = GST_VAAPI_OBJECT_ID(surface); - if (surface_id == VA_INVALID_SURFACE) - return FALSE; + surface_id = GST_VAAPI_OBJECT_ID (surface); + if (surface_id == VA_INVALID_SURFACE) + return FALSE; - GST_VAAPI_DISPLAY_LOCK(display); - status = vaDeassociateSubpicture( - GST_VAAPI_DISPLAY_VADISPLAY(display), - GST_VAAPI_OBJECT_ID(subpicture), - &surface_id, 1 - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaDeassociateSubpicture()")) - return FALSE; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaDeassociateSubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_OBJECT_ID (subpicture), &surface_id, 1); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaDeassociateSubpicture()")) + return FALSE; - return TRUE; + return TRUE; } /** @@ -771,27 +713,25 @@ _gst_vaapi_surface_deassociate_subpicture( * Return value: %TRUE on success */ gboolean -gst_vaapi_surface_sync(GstVaapiSurface *surface) +gst_vaapi_surface_sync (GstVaapiSurface * surface) { - GstVaapiDisplay *display; - VAStatus status; + GstVaapiDisplay *display; + VAStatus status; - g_return_val_if_fail(surface != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); - display = GST_VAAPI_OBJECT_DISPLAY(surface); - if (!display) - return FALSE; + display = GST_VAAPI_OBJECT_DISPLAY (surface); + if (!display) + return FALSE; - GST_VAAPI_DISPLAY_LOCK(display); - status = vaSyncSurface( - GST_VAAPI_DISPLAY_VADISPLAY(display), - GST_VAAPI_OBJECT_ID(surface) - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaSyncSurface()")) - return FALSE; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaSyncSurface (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_OBJECT_ID (surface)); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaSyncSurface()")) + return FALSE; - return TRUE; + return TRUE; } /** @@ -805,29 +745,24 @@ gst_vaapi_surface_sync(GstVaapiSurface *surface) * Return value: %TRUE on success */ gboolean -gst_vaapi_surface_query_status( - GstVaapiSurface *surface, - GstVaapiSurfaceStatus *pstatus -) +gst_vaapi_surface_query_status (GstVaapiSurface * surface, + GstVaapiSurfaceStatus * pstatus) { - VASurfaceStatus surface_status; - VAStatus status; + VASurfaceStatus surface_status; + VAStatus status; - g_return_val_if_fail(surface != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); - GST_VAAPI_OBJECT_LOCK_DISPLAY(surface); - status = vaQuerySurfaceStatus( - GST_VAAPI_OBJECT_VADISPLAY(surface), - GST_VAAPI_OBJECT_ID(surface), - &surface_status - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(surface); - if (!vaapi_check_status(status, "vaQuerySurfaceStatus()")) - return FALSE; + GST_VAAPI_OBJECT_LOCK_DISPLAY (surface); + status = vaQuerySurfaceStatus (GST_VAAPI_OBJECT_VADISPLAY (surface), + GST_VAAPI_OBJECT_ID (surface), &surface_status); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (surface); + if (!vaapi_check_status (status, "vaQuerySurfaceStatus()")) + return FALSE; - if (pstatus) - *pstatus = to_GstVaapiSurfaceStatus(surface_status); - return TRUE; + if (pstatus) + *pstatus = to_GstVaapiSurfaceStatus (surface_status); + return TRUE; } /** @@ -844,54 +779,51 @@ gst_vaapi_surface_query_status( * Return value: %TRUE on success */ gboolean -gst_vaapi_surface_set_subpictures_from_composition( - GstVaapiSurface *surface, - GstVideoOverlayComposition *composition, - gboolean propagate_context -) +gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface, + GstVideoOverlayComposition * composition, gboolean propagate_context) { - GstVaapiDisplay *display; - guint n, nb_rectangles; + GstVaapiDisplay *display; + guint n, nb_rectangles; - g_return_val_if_fail(surface != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); - if (propagate_context && surface->parent_context) - return gst_vaapi_context_apply_composition(surface->parent_context, - composition); + if (propagate_context && surface->parent_context) + return gst_vaapi_context_apply_composition (surface->parent_context, + composition); - display = GST_VAAPI_OBJECT_DISPLAY(surface); - if (!display) - return FALSE; + display = GST_VAAPI_OBJECT_DISPLAY (surface); + if (!display) + return FALSE; - /* Clear current subpictures */ - gst_vaapi_surface_destroy_subpictures(surface); + /* Clear current subpictures */ + gst_vaapi_surface_destroy_subpictures (surface); - if (!composition) - return TRUE; - - nb_rectangles = gst_video_overlay_composition_n_rectangles (composition); - - /* Overlay all the rectangles cantained in the overlay composition */ - for (n = 0; n < nb_rectangles; ++n) { - GstVideoOverlayRectangle *rect; - GstVaapiRectangle sub_rect; - GstVaapiSubpicture *subpicture; - - rect = gst_video_overlay_composition_get_rectangle (composition, n); - subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle (display, - rect); - - gst_video_overlay_rectangle_get_render_rectangle (rect, - (gint *)&sub_rect.x, (gint *)&sub_rect.y, - &sub_rect.width, &sub_rect.height); - - if (!gst_vaapi_surface_associate_subpicture (surface, subpicture, - NULL, &sub_rect)) { - GST_WARNING ("could not render overlay rectangle %p", rect); - gst_vaapi_object_unref (subpicture); - return FALSE; - } - gst_vaapi_object_unref (subpicture); - } + if (!composition) return TRUE; + + nb_rectangles = gst_video_overlay_composition_n_rectangles (composition); + + /* Overlay all the rectangles cantained in the overlay composition */ + for (n = 0; n < nb_rectangles; ++n) { + GstVideoOverlayRectangle *rect; + GstVaapiRectangle sub_rect; + GstVaapiSubpicture *subpicture; + + rect = gst_video_overlay_composition_get_rectangle (composition, n); + subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle (display, + rect); + + gst_video_overlay_rectangle_get_render_rectangle (rect, + (gint *) & sub_rect.x, (gint *) & sub_rect.y, + &sub_rect.width, &sub_rect.height); + + if (!gst_vaapi_surface_associate_subpicture (surface, subpicture, + NULL, &sub_rect)) { + GST_WARNING ("could not render overlay rectangle %p", rect); + gst_vaapi_object_unref (subpicture); + return FALSE; + } + gst_vaapi_object_unref (subpicture); + } + return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 48f86622e3..e14861aac1 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -67,15 +67,16 @@ G_BEGIN_DECLS * * The set of all chroma types for #GstVaapiSurface. */ -typedef enum { - GST_VAAPI_CHROMA_TYPE_YUV420 = 1, - GST_VAAPI_CHROMA_TYPE_YUV422, - GST_VAAPI_CHROMA_TYPE_YUV444, - GST_VAAPI_CHROMA_TYPE_YUV411, - GST_VAAPI_CHROMA_TYPE_YUV410, - GST_VAAPI_CHROMA_TYPE_YUV400, - GST_VAAPI_CHROMA_TYPE_RGB32, - GST_VAAPI_CHROMA_TYPE_RGB16 +typedef enum +{ + GST_VAAPI_CHROMA_TYPE_YUV420 = 1, + GST_VAAPI_CHROMA_TYPE_YUV422, + GST_VAAPI_CHROMA_TYPE_YUV444, + GST_VAAPI_CHROMA_TYPE_YUV411, + GST_VAAPI_CHROMA_TYPE_YUV410, + GST_VAAPI_CHROMA_TYPE_YUV400, + GST_VAAPI_CHROMA_TYPE_RGB32, + GST_VAAPI_CHROMA_TYPE_RGB16 } GstVaapiChromaType; /** @@ -91,11 +92,12 @@ typedef enum { * * The set of all surface status for #GstVaapiSurface. */ -typedef enum { - GST_VAAPI_SURFACE_STATUS_IDLE = 1 << 0, - GST_VAAPI_SURFACE_STATUS_RENDERING = 1 << 1, - GST_VAAPI_SURFACE_STATUS_DISPLAYING = 1 << 2, - GST_VAAPI_SURFACE_STATUS_SKIPPED = 1 << 3 +typedef enum +{ + GST_VAAPI_SURFACE_STATUS_IDLE = 1 << 0, + GST_VAAPI_SURFACE_STATUS_RENDERING = 1 << 1, + GST_VAAPI_SURFACE_STATUS_DISPLAYING = 1 << 2, + GST_VAAPI_SURFACE_STATUS_SKIPPED = 1 << 3 } GstVaapiSurfaceStatus; /** @@ -121,21 +123,22 @@ typedef enum { * * The set of all render flags for gst_vaapi_window_put_surface(). */ -typedef enum { - /* Picture structure */ - GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD = 0x01 << 0, - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD = 0x02 << 0, - GST_VAAPI_PICTURE_STRUCTURE_FRAME = 0x03 << 0, - GST_VAAPI_PICTURE_STRUCTURE_MASK = 0x00000003, /* 2 bits */ +typedef enum +{ + /* Picture structure */ + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD = 0x01 << 0, + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD = 0x02 << 0, + GST_VAAPI_PICTURE_STRUCTURE_FRAME = 0x03 << 0, + GST_VAAPI_PICTURE_STRUCTURE_MASK = 0x00000003, /* 2 bits */ - /* Color standard */ - GST_VAAPI_COLOR_STANDARD_ITUR_BT_601 = 0x01 << 2, - GST_VAAPI_COLOR_STANDARD_ITUR_BT_709 = 0x02 << 2, - GST_VAAPI_COLOR_STANDARD_ITUR_BT_470M = 0x03 << 2, - GST_VAAPI_COLOR_STANDARD_ITUR_BT_470BG = 0x04 << 2, - GST_VAAPI_COLOR_STANDARD_SMPTE_170M = 0x05 << 2, - GST_VAAPI_COLOR_STANDARD_SMPTE_240M = 0x06 << 2, - GST_VAAPI_COLOR_STANDARD_MASK = 0x0000003c, /* 4 bits */ + /* Color standard */ + GST_VAAPI_COLOR_STANDARD_ITUR_BT_601 = 0x01 << 2, + GST_VAAPI_COLOR_STANDARD_ITUR_BT_709 = 0x02 << 2, + GST_VAAPI_COLOR_STANDARD_ITUR_BT_470M = 0x03 << 2, + GST_VAAPI_COLOR_STANDARD_ITUR_BT_470BG = 0x04 << 2, + GST_VAAPI_COLOR_STANDARD_SMPTE_170M = 0x05 << 2, + GST_VAAPI_COLOR_STANDARD_SMPTE_240M = 0x06 << 2, + GST_VAAPI_COLOR_STANDARD_MASK = 0x0000003c, /* 4 bits */ } GstVaapiSurfaceRenderFlags; #define GST_VAAPI_SURFACE(obj) \ @@ -145,81 +148,60 @@ typedef struct _GstVaapiSurface GstVaapiSurface; typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; GstVaapiSurface * -gst_vaapi_surface_new( - GstVaapiDisplay *display, - GstVaapiChromaType chroma_type, - guint width, - guint height -); +gst_vaapi_surface_new (GstVaapiDisplay * display, + GstVaapiChromaType chroma_type, guint width, guint height); GstVaapiSurface * -gst_vaapi_surface_new_with_format( - GstVaapiDisplay *display, - GstVideoFormat format, - guint width, - guint height -); +gst_vaapi_surface_new_with_format (GstVaapiDisplay * display, + GstVideoFormat format, guint width, guint height); GstVaapiID -gst_vaapi_surface_get_id(GstVaapiSurface *surface); +gst_vaapi_surface_get_id (GstVaapiSurface * surface); GstVaapiChromaType -gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface); +gst_vaapi_surface_get_chroma_type (GstVaapiSurface * surface); GstVideoFormat -gst_vaapi_surface_get_format(GstVaapiSurface *surface); +gst_vaapi_surface_get_format (GstVaapiSurface * surface); guint -gst_vaapi_surface_get_width(GstVaapiSurface *surface); +gst_vaapi_surface_get_width (GstVaapiSurface * surface); guint -gst_vaapi_surface_get_height(GstVaapiSurface *surface); +gst_vaapi_surface_get_height (GstVaapiSurface * surface); void -gst_vaapi_surface_get_size( - GstVaapiSurface *surface, - guint *pwidth, - guint *pheight -); +gst_vaapi_surface_get_size (GstVaapiSurface * surface, guint * width_ptr, + guint * height_ptr); GstVaapiImage * -gst_vaapi_surface_derive_image(GstVaapiSurface *surface); +gst_vaapi_surface_derive_image (GstVaapiSurface * surface); gboolean -gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image); +gst_vaapi_surface_get_image (GstVaapiSurface * surface, GstVaapiImage * image); gboolean -gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image); +gst_vaapi_surface_put_image (GstVaapiSurface * surface, GstVaapiImage * image); gboolean -gst_vaapi_surface_associate_subpicture( - GstVaapiSurface *surface, - GstVaapiSubpicture *subpicture, - const GstVaapiRectangle *src_rect, - const GstVaapiRectangle *dst_rect -); +gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface, + GstVaapiSubpicture * subpicture, const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect); gboolean -gst_vaapi_surface_deassociate_subpicture( - GstVaapiSurface *surface, - GstVaapiSubpicture *subpicture -); +gst_vaapi_surface_deassociate_subpicture (GstVaapiSurface * surface, + GstVaapiSubpicture * subpicture); gboolean -gst_vaapi_surface_sync(GstVaapiSurface *surface); +gst_vaapi_surface_sync (GstVaapiSurface * surface); gboolean -gst_vaapi_surface_query_status( - GstVaapiSurface *surface, - GstVaapiSurfaceStatus *pstatus -); +gst_vaapi_surface_query_status (GstVaapiSurface * surface, + GstVaapiSurfaceStatus * pstatus); gboolean -gst_vaapi_surface_set_subpictures_from_composition( - GstVaapiSurface *surface, - GstVideoOverlayComposition *composition, - gboolean propagate_context -); +gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface, + GstVideoOverlayComposition * composition, gboolean propagate_context); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index 468226d981..dc5663cce8 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -27,6 +27,8 @@ #include #include "gstvaapiobject_priv.h" +G_BEGIN_DECLS + typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; /** @@ -34,16 +36,17 @@ typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; * * A VA surface wrapper. */ -struct _GstVaapiSurface { - /*< private >*/ - GstVaapiObject parent_instance; +struct _GstVaapiSurface +{ + /*< private >*/ + GstVaapiObject parent_instance; - GstVideoFormat format; - guint width; - guint height; - GstVaapiChromaType chroma_type; - GPtrArray *subpictures; - GstVaapiContext *parent_context; + GstVideoFormat format; + guint width; + guint height; + GstVaapiChromaType chroma_type; + GPtrArray *subpictures; + GstVaapiContext *parent_context; }; /** @@ -51,9 +54,10 @@ struct _GstVaapiSurface { * * A VA surface wrapper class. */ -struct _GstVaapiSurfaceClass { - /*< private >*/ - GstVaapiObjectClass parent_class; +struct _GstVaapiSurfaceClass +{ + /*< private >*/ + GstVaapiObjectClass parent_class; }; /** @@ -66,7 +70,7 @@ struct _GstVaapiSurfaceClass { */ #undef GST_VAAPI_SURFACE_CHROMA_TYPE #define GST_VAAPI_SURFACE_CHROMA_TYPE(surface) \ - GST_VAAPI_SURFACE(surface)->chroma_type + (GST_VAAPI_SURFACE (surface)->chroma_type) /** * GST_VAAPI_SURFACE_SURFACE_FORMAT: @@ -78,7 +82,7 @@ struct _GstVaapiSurfaceClass { */ #undef GST_VAAPI_SURFACE_FORMAT #define GST_VAAPI_SURFACE_FORMAT(surface) \ - GST_VAAPI_SURFACE(surface)->format + (GST_VAAPI_SURFACE (surface)->format) /** * GST_VAAPI_SURFACE_SURFACE_WIDTH: @@ -90,7 +94,7 @@ struct _GstVaapiSurfaceClass { */ #undef GST_VAAPI_SURFACE_WIDTH #define GST_VAAPI_SURFACE_WIDTH(surface) \ - GST_VAAPI_SURFACE(surface)->width + (GST_VAAPI_SURFACE (surface)->width) /** * GST_VAAPI_SURFACE_SURFACE_HEIGHT: @@ -102,17 +106,17 @@ struct _GstVaapiSurfaceClass { */ #undef GST_VAAPI_SURFACE_HEIGHT #define GST_VAAPI_SURFACE_HEIGHT(surface) \ - GST_VAAPI_SURFACE(surface)->height + (GST_VAAPI_SURFACE (surface)->height) G_GNUC_INTERNAL void -gst_vaapi_surface_set_parent_context( - GstVaapiSurface *surface, - GstVaapiContext *context -); +gst_vaapi_surface_set_parent_context (GstVaapiSurface * surface, + GstVaapiContext * context); G_GNUC_INTERNAL GstVaapiContext * -gst_vaapi_surface_get_parent_context(GstVaapiSurface *surface); +gst_vaapi_surface_get_parent_context (GstVaapiSurface * surface); + +G_END_DECLS #endif /* GST_VAAPI_SURFACE_PRIV_H */ From 4ebfba0d49642087ea595e135ffeebacaf992e10 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 27 Jan 2015 11:16:34 +0100 Subject: [PATCH 1832/3781] surface: add more fine-grained allocation helper. Add new gst_vaapi_surface_new_full() helper function that allocates VA surface from a GstVideoInfo template in argument. Additional flags may include ways to - allocate linear storage (GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE) ; - allocate with fixed strides (GST_VAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) ; - allocate with fixed offsets (GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS). --- gst-libs/gst/vaapi/gstvaapisurface.c | 114 +++++++++++++++++++++------ gst-libs/gst/vaapi/gstvaapisurface.h | 23 ++++++ 2 files changed, 111 insertions(+), 26 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index ce211fe9f0..d3496d462b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -127,16 +127,19 @@ error_unsupported_chroma_type: } static gboolean -gst_vaapi_surface_create_with_format (GstVaapiSurface * surface, - GstVideoFormat format, guint width, guint height) +gst_vaapi_surface_create_full (GstVaapiSurface * surface, + const GstVideoInfo * vip, guint flags) { #if VA_CHECK_VERSION(0,34,0) GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); + const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (vip); VASurfaceID surface_id; VAStatus status; - guint chroma_type, va_chroma_format; + guint chroma_type, va_chroma_format, i; const VAImageFormat *va_format; - VASurfaceAttrib attrib; + VASurfaceAttrib attribs[3], *attrib; + VASurfaceAttribExternalBuffers extbuf; + gboolean extbuf_needed = FALSE; va_format = gst_vaapi_video_format_to_va_format (format); if (!va_format) @@ -150,22 +153,57 @@ gst_vaapi_surface_create_with_format (GstVaapiSurface * surface, if (!va_chroma_format) goto error_unsupported_format; - attrib.flags = VA_SURFACE_ATTRIB_SETTABLE; - attrib.type = VASurfaceAttribPixelFormat; - attrib.value.type = VAGenericValueTypeInteger; - attrib.value.value.i = va_format->fourcc; + memset (&extbuf, 0, sizeof (extbuf)); + extbuf.pixel_format = va_format->fourcc; + extbuf.width = GST_VIDEO_INFO_WIDTH (vip); + extbuf.height = GST_VIDEO_INFO_HEIGHT (vip); + extbuf_needed = !!(flags & GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); + + extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vip); + if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) { + for (i = 0; i < extbuf.num_planes; i++) + extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vip, i); + extbuf_needed = TRUE; + } + if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS) { + for (i = 0; i < extbuf.num_planes; i++) + extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vip, i); + extbuf_needed = TRUE; + } + + attrib = attribs; + attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; + attrib->type = VASurfaceAttribPixelFormat; + attrib->value.type = VAGenericValueTypeInteger; + attrib->value.value.i = va_format->fourcc; + attrib++; + + if (extbuf_needed) { + attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; + attrib->type = VASurfaceAttribMemoryType; + attrib->value.type = VAGenericValueTypeInteger; + attrib->value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA; + attrib++; + + attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; + attrib->type = VASurfaceAttribExternalBufferDescriptor; + attrib->value.type = VAGenericValueTypePointer; + attrib->value.value.p = &extbuf; + attrib++; + } GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateSurfaces (GST_VAAPI_DISPLAY_VADISPLAY (display), - va_chroma_format, width, height, &surface_id, 1, &attrib, 1); + va_chroma_format, extbuf.width, extbuf.height, &surface_id, 1, + attribs, attrib - attribs); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateSurfaces()")) return FALSE; surface->format = format; surface->chroma_type = chroma_type; - surface->width = width; - surface->height = height; + surface->width = extbuf.width; + surface->height = extbuf.height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); GST_VAAPI_OBJECT_ID (surface) = surface_id; @@ -217,6 +255,42 @@ error: return NULL; } +/** + * gst_vaapi_surface_new_full: + * @display: a #GstVaapiDisplay + * @vip: the pointer to a #GstVideoInfo + * @flags: (optional) allocation flags + * + * Creates a new #GstVaapiSurface with the specified video information + * and optional #GstVaapiSurfaceAllocFlags + * + * Return value: the newly allocated #GstVaapiSurface object, or %NULL + * if creation of VA surface with explicit pixel format is not + * supported or failed. + */ +GstVaapiSurface * +gst_vaapi_surface_new_full (GstVaapiDisplay * display, + const GstVideoInfo * vip, guint flags) +{ + GstVaapiSurface *surface; + + GST_DEBUG ("size %ux%u, format %s, flags 0x%08x", GST_VIDEO_INFO_WIDTH (vip), + GST_VIDEO_INFO_HEIGHT (vip), + gst_vaapi_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)), flags); + + surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); + if (!surface) + return NULL; + + if (!gst_vaapi_surface_create_full (surface, vip, flags)) + goto error; + return surface; + +error: + gst_vaapi_object_unref (surface); + return NULL; +} + /** * gst_vaapi_surface_new_with_format: * @display: a #GstVaapiDisplay @@ -235,22 +309,10 @@ GstVaapiSurface * gst_vaapi_surface_new_with_format (GstVaapiDisplay * display, GstVideoFormat format, guint width, guint height) { - GstVaapiSurface *surface; + GstVideoInfo vi; - GST_DEBUG ("size %ux%u, format %s", width, height, - gst_vaapi_video_format_to_string (format)); - - surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); - if (!surface) - return NULL; - - if (!gst_vaapi_surface_create_with_format (surface, format, width, height)) - goto error; - return surface; - -error: - gst_vaapi_object_unref (surface); - return NULL; + gst_video_info_set_format (&vi, format, width, height); + return gst_vaapi_surface_new_full (display, &vi, 0); } /** diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index e14861aac1..6317720ca5 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -141,6 +141,25 @@ typedef enum GST_VAAPI_COLOR_STANDARD_MASK = 0x0000003c, /* 4 bits */ } GstVaapiSurfaceRenderFlags; +/** + * GstVaapiSurfaceAllocFlags: + * @GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE: forces allocation + * with linear storage. Default behaviour matches native + * requirements, and thus could be tiled. + * @GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES: force allocation with + * the supplied strides information from #GstVideoInfo + * @GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS: force allocation with + * the supplied offsets information from #GstVideoInfo + * + * The set of optional allocation flags for gst_vaapi_surface_new_full(). + */ +typedef enum +{ + GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE = 1 << 0, + GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES = 1 << 1, + GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS = 1 << 2, +} GstVaapiSurfaceAllocFlags; + #define GST_VAAPI_SURFACE(obj) \ ((GstVaapiSurface *)(obj)) @@ -151,6 +170,10 @@ GstVaapiSurface * gst_vaapi_surface_new (GstVaapiDisplay * display, GstVaapiChromaType chroma_type, guint width, guint height); +GstVaapiSurface * +gst_vaapi_surface_new_full (GstVaapiDisplay * display, + const GstVideoInfo * vip, guint flags); + GstVaapiSurface * gst_vaapi_surface_new_with_format (GstVaapiDisplay * display, GstVideoFormat format, guint width, guint height); From 48fabae3eca192337aeaf396b7d7cbc61bd79548 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Oct 2014 11:22:10 +0200 Subject: [PATCH 1833/3781] texture: re-indent all GstVaapiTexture related source code. --- gst-libs/gst/vaapi/gstvaapitexture.c | 560 +++++++++++++-------------- gst-libs/gst/vaapi/gstvaapitexture.h | 51 +-- 2 files changed, 280 insertions(+), 331 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 0e4a76614c..68747528bd 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -40,26 +40,27 @@ #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiTextureClass GstVaapiTextureClass; +typedef struct _GstVaapiTextureClass GstVaapiTextureClass; /** * GstVaapiTexture: * * Base object for system-dependent textures. */ -struct _GstVaapiTexture { - /*< private >*/ - GstVaapiObject parent_instance; +struct _GstVaapiTexture +{ + /*< private >*/ + GstVaapiObject parent_instance; - GLenum target; - GLenum format; - guint width; - guint height; - GLContextState *gl_context; - void *gl_surface; - GLPixmapObject *pixo; - GLFramebufferObject *fbo; - guint foreign_texture : 1; + GLenum target; + GLenum format; + guint width; + guint height; + GLContextState *gl_context; + void *gl_surface; + GLPixmapObject *pixo; + GLFramebufferObject *fbo; + guint foreign_texture:1; }; /** @@ -67,156 +68,137 @@ struct _GstVaapiTexture { * * Base class for system-dependent textures. */ -struct _GstVaapiTextureClass { - GstVaapiObjectClass parent_class; +struct _GstVaapiTextureClass +{ + GstVaapiObjectClass parent_class; }; static void -_gst_vaapi_texture_destroy_objects(GstVaapiTexture *texture) +_gst_vaapi_texture_destroy_objects (GstVaapiTexture * texture) { #if USE_VAAPI_GLX - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - if (texture->gl_surface) { - vaDestroySurfaceGLX( - GST_VAAPI_OBJECT_VADISPLAY(texture), - texture->gl_surface - ); - texture->gl_surface = NULL; - } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + if (texture->gl_surface) { + vaDestroySurfaceGLX (GST_VAAPI_OBJECT_VADISPLAY (texture), + texture->gl_surface); + texture->gl_surface = NULL; + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); #else - GLContextState old_cs; + GLContextState old_cs; - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - if (texture->gl_context) - gl_set_current_context(texture->gl_context, &old_cs); + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + if (texture->gl_context) + gl_set_current_context (texture->gl_context, &old_cs); - if (texture->fbo) { - gl_destroy_framebuffer_object(texture->fbo); - texture->fbo = NULL; - } + if (texture->fbo) { + gl_destroy_framebuffer_object (texture->fbo); + texture->fbo = NULL; + } - if (texture->pixo) { - gl_destroy_pixmap_object(texture->pixo); - texture->pixo = NULL; - } + if (texture->pixo) { + gl_destroy_pixmap_object (texture->pixo); + texture->pixo = NULL; + } - if (texture->gl_context) { - gl_set_current_context(&old_cs, NULL); - gl_destroy_context(texture->gl_context); - texture->gl_context = NULL; - } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (texture->gl_context) { + gl_set_current_context (&old_cs, NULL); + gl_destroy_context (texture->gl_context); + texture->gl_context = NULL; + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); #endif } static void -gst_vaapi_texture_destroy(GstVaapiTexture *texture) +gst_vaapi_texture_destroy (GstVaapiTexture * texture) { - const GLuint texture_id = GST_VAAPI_OBJECT_ID(texture); + const GLuint texture_id = GST_VAAPI_OBJECT_ID (texture); - _gst_vaapi_texture_destroy_objects(texture); + _gst_vaapi_texture_destroy_objects (texture); - if (texture_id) { - if (!texture->foreign_texture) - glDeleteTextures(1, &texture_id); - GST_VAAPI_OBJECT_ID(texture) = 0; - } + if (texture_id) { + if (!texture->foreign_texture) + glDeleteTextures (1, &texture_id); + GST_VAAPI_OBJECT_ID (texture) = 0; + } } static gboolean -_gst_vaapi_texture_create_objects(GstVaapiTexture *texture, GLuint texture_id) +_gst_vaapi_texture_create_objects (GstVaapiTexture * texture, GLuint texture_id) { - gboolean success = FALSE; + gboolean success = FALSE; #if USE_VAAPI_GLX - VAStatus status; + VAStatus status; - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - status = vaCreateSurfaceGLX( - GST_VAAPI_OBJECT_VADISPLAY(texture), - texture->target, - texture_id, - &texture->gl_surface - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - success = vaapi_check_status(status, "vaCreateSurfaceGLX()"); + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + status = vaCreateSurfaceGLX (GST_VAAPI_OBJECT_VADISPLAY (texture), + texture->target, texture_id, &texture->gl_surface); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + success = vaapi_check_status (status, "vaCreateSurfaceGLX()"); #else - GLContextState old_cs; + GLContextState old_cs; - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - gl_get_current_context(&old_cs); - texture->gl_context = gl_create_context( - GST_VAAPI_OBJECT_XDISPLAY(texture), - GST_VAAPI_OBJECT_XSCREEN(texture), - &old_cs - ); - if (!texture->gl_context || - !gl_set_current_context(texture->gl_context, NULL)) - goto end; + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + gl_get_current_context (&old_cs); + texture->gl_context = gl_create_context (GST_VAAPI_OBJECT_XDISPLAY (texture), + GST_VAAPI_OBJECT_XSCREEN (texture), &old_cs); + if (!texture->gl_context || + !gl_set_current_context (texture->gl_context, NULL)) + goto end; - texture->pixo = gl_create_pixmap_object( - GST_VAAPI_OBJECT_XDISPLAY(texture), - texture->width, - texture->height - ); - if (!texture->pixo) - goto end; + texture->pixo = gl_create_pixmap_object (GST_VAAPI_OBJECT_XDISPLAY (texture), + texture->width, texture->height); + if (!texture->pixo) + goto end; - texture->fbo = gl_create_framebuffer_object( - texture->target, - texture_id, - texture->width, - texture->height - ); - if (texture->fbo) - success = TRUE; + texture->fbo = gl_create_framebuffer_object (texture->target, + texture_id, texture->width, texture->height); + if (texture->fbo) + success = TRUE; end: - gl_set_current_context(&old_cs, NULL); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + gl_set_current_context (&old_cs, NULL); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); #endif - return success; + return success; } static gboolean -gst_vaapi_texture_create(GstVaapiTexture *texture) +gst_vaapi_texture_create (GstVaapiTexture * texture) { - GLuint texture_id; + GLuint texture_id; - if (texture->foreign_texture) - texture_id = GST_VAAPI_OBJECT_ID(texture); - else { - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - texture_id = gl_create_texture( - texture->target, - texture->format, - texture->width, - texture->height - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - if (!texture_id) - return FALSE; - GST_VAAPI_OBJECT_ID(texture) = texture_id; - } + if (texture->foreign_texture) + texture_id = GST_VAAPI_OBJECT_ID (texture); + else { + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + texture_id = gl_create_texture (texture->target, + texture->format, texture->width, texture->height); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + if (!texture_id) + return FALSE; + GST_VAAPI_OBJECT_ID (texture) = texture_id; + } - return _gst_vaapi_texture_create_objects(texture, texture_id); + return _gst_vaapi_texture_create_objects (texture, texture_id); } static void -gst_vaapi_texture_init(GstVaapiTexture *texture, GLuint texture_id, +gst_vaapi_texture_init (GstVaapiTexture * texture, GLuint texture_id, GLenum target, GLenum format, guint width, guint height) { - GST_VAAPI_OBJECT_ID(texture) = texture_id; - texture->foreign_texture = texture_id != GL_NONE; + GST_VAAPI_OBJECT_ID (texture) = texture_id; + texture->foreign_texture = texture_id != GL_NONE; - texture->target = target; - texture->format = format; - texture->width = width; - texture->height = height; + texture->target = target; + texture->format = format; + texture->width = width; + texture->height = height; } #define gst_vaapi_texture_finalize gst_vaapi_texture_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiTexture, gst_vaapi_texture) +GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiTexture, gst_vaapi_texture); /** * gst_vaapi_texture_new: @@ -238,34 +220,29 @@ GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiTexture, gst_vaapi_texture) * Return value: the newly created #GstVaapiTexture object */ GstVaapiTexture * -gst_vaapi_texture_new( - GstVaapiDisplay *display, - GLenum target, - GLenum format, - guint width, - guint height -) +gst_vaapi_texture_new (GstVaapiDisplay * display, GLenum target, GLenum format, + guint width, guint height) { - GstVaapiTexture *texture; + GstVaapiTexture *texture; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); - g_return_val_if_fail(target != GL_NONE, NULL); - g_return_val_if_fail(format != GL_NONE, NULL); - g_return_val_if_fail(width > 0, NULL); - g_return_val_if_fail(height > 0, NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); + g_return_val_if_fail (target != GL_NONE, NULL); + g_return_val_if_fail (format != GL_NONE, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); - texture = gst_vaapi_object_new(gst_vaapi_texture_class(), display); - if (!texture) - return NULL; + texture = gst_vaapi_object_new (gst_vaapi_texture_class (), display); + if (!texture) + return NULL; - gst_vaapi_texture_init(texture, GL_NONE, target, format, width, height); - if (!gst_vaapi_texture_create(texture)) - goto error; - return texture; + gst_vaapi_texture_init (texture, GL_NONE, target, format, width, height); + if (!gst_vaapi_texture_create (texture)) + goto error; + return texture; error: - gst_vaapi_object_unref(texture); - return NULL; + gst_vaapi_object_unref (texture); + return NULL; } /** @@ -288,53 +265,49 @@ error: * Return value: the newly created #GstVaapiTexture object */ GstVaapiTexture * -gst_vaapi_texture_new_with_texture( - GstVaapiDisplay *display, - GLuint texture_id, - GLenum target, - GLenum format -) +gst_vaapi_texture_new_with_texture (GstVaapiDisplay * display, + GLuint texture_id, GLenum target, GLenum format) { - GstVaapiTexture *texture; - guint width, height, border_width; - GLTextureState ts; - gboolean success; + GstVaapiTexture *texture; + guint width, height, border_width; + GLTextureState ts; + gboolean success; - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_GLX(display), NULL); - g_return_val_if_fail(target != GL_NONE, NULL); - g_return_val_if_fail(format != GL_NONE, NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); + g_return_val_if_fail (target != GL_NONE, NULL); + g_return_val_if_fail (format != GL_NONE, NULL); - /* Check texture dimensions */ - GST_VAAPI_DISPLAY_LOCK(display); - success = gl_bind_texture(&ts, target, texture_id); - if (success) { - if (!gl_get_texture_param(target, GL_TEXTURE_WIDTH, &width) || - !gl_get_texture_param(target, GL_TEXTURE_HEIGHT, &height) || - !gl_get_texture_param(target, GL_TEXTURE_BORDER, &border_width)) - success = FALSE; - gl_unbind_texture(&ts); - } - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!success) - return NULL; + /* Check texture dimensions */ + GST_VAAPI_DISPLAY_LOCK (display); + success = gl_bind_texture (&ts, target, texture_id); + if (success) { + if (!gl_get_texture_param (target, GL_TEXTURE_WIDTH, &width) || + !gl_get_texture_param (target, GL_TEXTURE_HEIGHT, &height) || + !gl_get_texture_param (target, GL_TEXTURE_BORDER, &border_width)) + success = FALSE; + gl_unbind_texture (&ts); + } + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!success) + return NULL; - width -= 2 * border_width; - height -= 2 * border_width; - g_return_val_if_fail(width > 0, NULL); - g_return_val_if_fail(height > 0, NULL); + width -= 2 * border_width; + height -= 2 * border_width; + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); - texture = gst_vaapi_object_new(gst_vaapi_texture_class(), display); - if (!texture) - return NULL; + texture = gst_vaapi_object_new (gst_vaapi_texture_class (), display); + if (!texture) + return NULL; - gst_vaapi_texture_init(texture, texture_id, target, format, width, height); - if (!gst_vaapi_texture_create(texture)) - goto error; - return texture; + gst_vaapi_texture_init (texture, texture_id, target, format, width, height); + if (!gst_vaapi_texture_create (texture)) + goto error; + return texture; error: - gst_vaapi_object_unref(texture); - return NULL; + gst_vaapi_object_unref (texture); + return NULL; } /** @@ -346,9 +319,9 @@ error: * Returns: The same @texture argument */ GstVaapiTexture * -gst_vaapi_texture_ref(GstVaapiTexture *texture) +gst_vaapi_texture_ref (GstVaapiTexture * texture) { - return gst_vaapi_object_ref(texture); + return gst_vaapi_object_ref (texture); } /** @@ -359,9 +332,9 @@ gst_vaapi_texture_ref(GstVaapiTexture *texture) * the reference count reaches zero, the texture will be free'd. */ void -gst_vaapi_texture_unref(GstVaapiTexture *texture) +gst_vaapi_texture_unref (GstVaapiTexture * texture) { - gst_vaapi_object_unref(texture); + gst_vaapi_object_unref (texture); } /** @@ -374,10 +347,10 @@ gst_vaapi_texture_unref(GstVaapiTexture *texture) * a valid texture. However, @new_texture can be NULL. */ void -gst_vaapi_texture_replace(GstVaapiTexture **old_texture_ptr, - GstVaapiTexture *new_texture) +gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr, + GstVaapiTexture * new_texture) { - gst_vaapi_object_replace(old_texture_ptr, new_texture); + gst_vaapi_object_replace (old_texture_ptr, new_texture); } /** @@ -389,11 +362,11 @@ gst_vaapi_texture_replace(GstVaapiTexture **old_texture_ptr, * Return value: the underlying texture id of the @texture */ GLuint -gst_vaapi_texture_get_id(GstVaapiTexture *texture) +gst_vaapi_texture_get_id (GstVaapiTexture * texture) { - g_return_val_if_fail(texture != NULL, 0); + g_return_val_if_fail (texture != NULL, 0); - return GST_VAAPI_OBJECT_ID(texture); + return GST_VAAPI_OBJECT_ID (texture); } /** @@ -405,11 +378,11 @@ gst_vaapi_texture_get_id(GstVaapiTexture *texture) * Return value: the texture target */ GLenum -gst_vaapi_texture_get_target(GstVaapiTexture *texture) +gst_vaapi_texture_get_target (GstVaapiTexture * texture) { - g_return_val_if_fail(texture != NULL, GL_NONE); + g_return_val_if_fail (texture != NULL, GL_NONE); - return texture->target; + return texture->target; } /** @@ -421,11 +394,11 @@ gst_vaapi_texture_get_target(GstVaapiTexture *texture) * Return value: the texture format */ GLenum -gst_vaapi_texture_get_format(GstVaapiTexture *texture) +gst_vaapi_texture_get_format (GstVaapiTexture * texture) { - g_return_val_if_fail(texture != NULL, GL_NONE); + g_return_val_if_fail (texture != NULL, GL_NONE); - return texture->format; + return texture->format; } /** @@ -437,11 +410,11 @@ gst_vaapi_texture_get_format(GstVaapiTexture *texture) * Return value: the texture width, in pixels */ guint -gst_vaapi_texture_get_width(GstVaapiTexture *texture) +gst_vaapi_texture_get_width (GstVaapiTexture * texture) { - g_return_val_if_fail(texture != NULL, 0); + g_return_val_if_fail (texture != NULL, 0); - return texture->width; + return texture->width; } /** @@ -453,35 +426,32 @@ gst_vaapi_texture_get_width(GstVaapiTexture *texture) * Return value: the texture height, in pixels. */ guint -gst_vaapi_texture_get_height(GstVaapiTexture *texture) +gst_vaapi_texture_get_height (GstVaapiTexture * texture) { - g_return_val_if_fail(texture != NULL, 0); + g_return_val_if_fail (texture != NULL, 0); - return texture->height; + return texture->height; } /** * gst_vaapi_texture_get_size: * @texture: a #GstVaapiTexture - * @pwidth: return location for the width, or %NULL - * @pheight: return location for the height, or %NULL + * @width_ptr: return location for the width, or %NULL + * @height_ptr: return location for the height, or %NULL * * Retrieves the dimensions of a #GstVaapiTexture. */ void -gst_vaapi_texture_get_size( - GstVaapiTexture *texture, - guint *pwidth, - guint *pheight -) +gst_vaapi_texture_get_size (GstVaapiTexture * texture, + guint * width_ptr, guint * height_ptr) { - g_return_if_fail(texture != NULL); + g_return_if_fail (texture != NULL); - if (pwidth) - *pwidth = texture->width; + if (width_ptr) + *width_ptr = texture->width; - if (pheight) - *pheight = texture->height; + if (height_ptr) + *height_ptr = texture->height; } /** @@ -497,111 +467,105 @@ gst_vaapi_texture_get_size( * Return value: %TRUE on success */ static gboolean -_gst_vaapi_texture_put_surface( - GstVaapiTexture *texture, - GstVaapiSurface *surface, - guint flags -) +_gst_vaapi_texture_put_surface (GstVaapiTexture * texture, + GstVaapiSurface * surface, guint flags) { - VAStatus status; + VAStatus status; #if USE_VAAPI_GLX - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - status = vaCopySurfaceGLX( - GST_VAAPI_OBJECT_VADISPLAY(texture), - texture->gl_surface, - GST_VAAPI_OBJECT_ID(surface), - from_GstVaapiSurfaceRenderFlags(flags) - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - if (!vaapi_check_status(status, "vaCopySurfaceGLX()")) - return FALSE; + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + status = vaCopySurfaceGLX (GST_VAAPI_OBJECT_VADISPLAY (texture), + texture->gl_surface, + GST_VAAPI_OBJECT_ID (surface), from_GstVaapiSurfaceRenderFlags (flags) + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + if (!vaapi_check_status (status, "vaCopySurfaceGLX()")) + return FALSE; #else - guint surface_width, surface_height; - GLContextState old_cs; - gboolean success = FALSE; + guint surface_width, surface_height; + GLContextState old_cs; + gboolean success = FALSE; - gst_vaapi_surface_get_size(surface, &surface_width, &surface_height); + gst_vaapi_surface_get_size (surface, &surface_width, &surface_height); - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - status = vaPutSurface( - GST_VAAPI_OBJECT_VADISPLAY(texture), - GST_VAAPI_OBJECT_ID(surface), - texture->pixo->pixmap, - 0, 0, surface_width, surface_height, - 0, 0, texture->width, texture->height, - NULL, 0, - from_GstVaapiSurfaceRenderFlags(flags) - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - if (!vaapi_check_status(status, "vaPutSurface() [TFP]")) - return FALSE; + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture), + GST_VAAPI_OBJECT_ID (surface), + texture->pixo->pixmap, + 0, 0, surface_width, surface_height, + 0, 0, texture->width, texture->height, + NULL, 0, from_GstVaapiSurfaceRenderFlags (flags) + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + if (!vaapi_check_status (status, "vaPutSurface() [TFP]")) + return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - if (texture->gl_context) { - success = gl_set_current_context(texture->gl_context, &old_cs); - if (!success) - goto end; - } + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + if (texture->gl_context) { + success = gl_set_current_context (texture->gl_context, &old_cs); + if (!success) + goto end; + } - success = gl_bind_framebuffer_object(texture->fbo); - if (!success) { - GST_DEBUG("could not bind FBO"); - goto out_reset_context; - } + success = gl_bind_framebuffer_object (texture->fbo); + if (!success) { + GST_DEBUG ("could not bind FBO"); + goto out_reset_context; + } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - success = gst_vaapi_surface_sync(surface); - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - if (!success) { - GST_DEBUG("could not render surface to pixmap"); - goto out_unbind_fbo; - } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + success = gst_vaapi_surface_sync (surface); + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + if (!success) { + GST_DEBUG ("could not render surface to pixmap"); + goto out_unbind_fbo; + } - success = gl_bind_pixmap_object(texture->pixo); - if (!success) { - GST_DEBUG("could not bind GLX pixmap"); - goto out_unbind_fbo; - } + success = gl_bind_pixmap_object (texture->pixo); + if (!success) { + GST_DEBUG ("could not bind GLX pixmap"); + goto out_unbind_fbo; + } - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glBegin(GL_QUADS); - { - glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0 ); - glTexCoord2f(0.0f, 1.0f); glVertex2i(0, texture->height); - glTexCoord2f(1.0f, 1.0f); glVertex2i(texture->width, texture->height); - glTexCoord2f(1.0f, 0.0f); glVertex2i(texture->width, 0 ); - } - glEnd(); + glColor4f (1.0f, 1.0f, 1.0f, 1.0f); + glBegin (GL_QUADS); + { + glTexCoord2f (0.0f, 0.0f); + glVertex2i (0, 0); + glTexCoord2f (0.0f, 1.0f); + glVertex2i (0, texture->height); + glTexCoord2f (1.0f, 1.0f); + glVertex2i (texture->width, texture->height); + glTexCoord2f (1.0f, 0.0f); + glVertex2i (texture->width, 0); + } + glEnd (); - success = gl_unbind_pixmap_object(texture->pixo); - if (!success) { - GST_DEBUG("could not release GLX pixmap"); - goto out_unbind_fbo; - } + success = gl_unbind_pixmap_object (texture->pixo); + if (!success) { + GST_DEBUG ("could not release GLX pixmap"); + goto out_unbind_fbo; + } out_unbind_fbo: - if (!gl_unbind_framebuffer_object(texture->fbo)) - success = FALSE; + if (!gl_unbind_framebuffer_object (texture->fbo)) + success = FALSE; out_reset_context: - if (texture->gl_context && !gl_set_current_context(&old_cs, NULL)) - success = FALSE; + if (texture->gl_context && !gl_set_current_context (&old_cs, NULL)) + success = FALSE; end: - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - return success; + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + return success; #endif - return TRUE; + return TRUE; } gboolean -gst_vaapi_texture_put_surface( - GstVaapiTexture *texture, - GstVaapiSurface *surface, - guint flags -) +gst_vaapi_texture_put_surface (GstVaapiTexture * texture, + GstVaapiSurface * surface, guint flags) { - g_return_val_if_fail(texture != NULL, FALSE); - g_return_val_if_fail(surface != NULL, FALSE); + g_return_val_if_fail (texture != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); - return _gst_vaapi_texture_put_surface(texture, surface, flags); + return _gst_vaapi_texture_put_surface (texture, surface, flags); } diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 325957433f..2c6a8f0b7f 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -33,63 +33,48 @@ G_BEGIN_DECLS -typedef struct _GstVaapiTexture GstVaapiTexture; +typedef struct _GstVaapiTexture GstVaapiTexture; GstVaapiTexture * -gst_vaapi_texture_new( - GstVaapiDisplay *display, - GLenum target, - GLenum format, - guint width, - guint height -); +gst_vaapi_texture_new (GstVaapiDisplay * display, GLenum target, GLenum format, + guint width, guint height); GstVaapiTexture * -gst_vaapi_texture_new_with_texture( - GstVaapiDisplay *display, - GLuint texture_id, - GLenum target, - GLenum format -); +gst_vaapi_texture_new_with_texture (GstVaapiDisplay * display, GLuint texture_id, + GLenum target, GLenum format); GstVaapiTexture * -gst_vaapi_texture_ref(GstVaapiTexture *texture); +gst_vaapi_texture_ref (GstVaapiTexture * texture); void -gst_vaapi_texture_unref(GstVaapiTexture *texture); +gst_vaapi_texture_unref (GstVaapiTexture * texture); void -gst_vaapi_texture_replace(GstVaapiTexture **old_texture_ptr, - GstVaapiTexture *new_texture); +gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr, + GstVaapiTexture * new_texture); GLuint -gst_vaapi_texture_get_id(GstVaapiTexture *texture); +gst_vaapi_texture_get_id (GstVaapiTexture * texture); GLenum -gst_vaapi_texture_get_target(GstVaapiTexture *texture); +gst_vaapi_texture_get_target (GstVaapiTexture * texture); GLenum -gst_vaapi_texture_get_format(GstVaapiTexture *texture); +gst_vaapi_texture_get_format (GstVaapiTexture * texture); guint -gst_vaapi_texture_get_width(GstVaapiTexture *texture); +gst_vaapi_texture_get_width (GstVaapiTexture * texture); guint -gst_vaapi_texture_get_height(GstVaapiTexture *texture); +gst_vaapi_texture_get_height (GstVaapiTexture * texture); void -gst_vaapi_texture_get_size( - GstVaapiTexture *texture, - guint *pwidth, - guint *pheight -); +gst_vaapi_texture_get_size (GstVaapiTexture * texture, guint * width_ptr, + guint * height_ptr); gboolean -gst_vaapi_texture_put_surface( - GstVaapiTexture *texture, - GstVaapiSurface *surface, - guint flags -); +gst_vaapi_texture_put_surface (GstVaapiTexture * texture, + GstVaapiSurface * surface, guint flags); G_END_DECLS From 0a108653f2f78d7c25e3d20226cad0990d211f7e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Oct 2014 11:56:31 +0200 Subject: [PATCH 1834/3781] texture: add support for cropping rectangle during transfer. The gst_vaapi_texture_put_surface() function is missing a crop_rect argument that would be used during transfer for cropping the source surface to the desired dimensions. Note: from a user point-of-view, he should create the GstVaapiTexture object with the cropped size. That's the default behaviour in software decoding pipelines that we need to cope with. This is an API/ABI change, and SONAME version needs to be bumped. https://bugzilla.gnome.org/show_bug.cgi?id=736712 --- gst-libs/gst/vaapi/gstvaapitexture.c | 17 +++++++++++------ gst-libs/gst/vaapi/gstvaapitexture.h | 3 ++- gst/vaapi/gstvaapivideoconverter_glx.c | 5 ++++- gst/vaapi/gstvaapivideometa_texture.c | 5 ++++- tests/test-textures.c | 4 ++-- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 68747528bd..0ccc0579bb 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -468,7 +468,7 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture, */ static gboolean _gst_vaapi_texture_put_surface (GstVaapiTexture * texture, - GstVaapiSurface * surface, guint flags) + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) { VAStatus status; @@ -482,17 +482,22 @@ _gst_vaapi_texture_put_surface (GstVaapiTexture * texture, if (!vaapi_check_status (status, "vaCopySurfaceGLX()")) return FALSE; #else - guint surface_width, surface_height; + GstVaapiRectangle rect; GLContextState old_cs; gboolean success = FALSE; - gst_vaapi_surface_get_size (surface, &surface_width, &surface_height); + if (!crop_rect) { + rect.x = 0; + rect.y = 0; + gst_vaapi_surface_get_size (surface, &rect.width, &rect.height); + crop_rect = ▭ + } GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture), GST_VAAPI_OBJECT_ID (surface), texture->pixo->pixmap, - 0, 0, surface_width, surface_height, + crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height, 0, 0, texture->width, texture->height, NULL, 0, from_GstVaapiSurfaceRenderFlags (flags) ); @@ -562,10 +567,10 @@ end: gboolean gst_vaapi_texture_put_surface (GstVaapiTexture * texture, - GstVaapiSurface * surface, guint flags) + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) { g_return_val_if_fail (texture != NULL, FALSE); g_return_val_if_fail (surface != NULL, FALSE); - return _gst_vaapi_texture_put_surface (texture, surface, flags); + return _gst_vaapi_texture_put_surface (texture, surface, crop_rect, flags); } diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 2c6a8f0b7f..5ae71c201a 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -74,7 +74,8 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture, guint * width_ptr, gboolean gst_vaapi_texture_put_surface (GstVaapiTexture * texture, - GstVaapiSurface * surface, guint flags); + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, + guint flags); G_END_DECLS diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index 162bf6fcf5..06ca7c5f64 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -137,7 +137,9 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self, GstVaapiVideoConverterGLXPrivate *const priv = GST_VAAPI_VIDEO_CONVERTER_GLX (self)->priv; GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); - GstVaapiSurface *const surface = gst_vaapi_video_meta_get_surface (meta); + GstVaapiSurfaceProxy *const proxy = + gst_vaapi_video_meta_get_surface_proxy (meta); + GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); GstVaapiDisplay *new_dpy, *old_dpy; new_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); @@ -155,5 +157,6 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self, GST_WARNING ("could not update subtitles"); return gst_vaapi_texture_put_surface (priv->texture, surface, + gst_vaapi_surface_proxy_get_crop_rect (proxy), gst_vaapi_video_meta_get_render_flags (meta)); } diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 5a1a824ffc..429a8b3303 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -80,7 +80,9 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, GstVaapiVideoMeta *const vmeta = gst_buffer_get_vaapi_video_meta (meta->buffer); GstVaapiVideoMetaTexture *const meta_texture = meta->user_data; - GstVaapiSurface *const surface = gst_vaapi_video_meta_get_surface (vmeta); + GstVaapiSurfaceProxy *const proxy = + gst_vaapi_video_meta_get_surface_proxy (vmeta); + GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface); if (gst_vaapi_display_get_display_type (dpy) != GST_VAAPI_DISPLAY_TYPE_GLX) @@ -101,6 +103,7 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, gst_vaapi_texture_unref (texture); } return gst_vaapi_texture_put_surface (meta_texture->texture, surface, + gst_vaapi_surface_proxy_get_crop_rect (proxy), gst_vaapi_video_meta_get_render_flags (vmeta)); } diff --git a/tests/test-textures.c b/tests/test-textures.c index 9e608601a5..c4673adedd 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -105,7 +105,7 @@ main(int argc, char *argv[]) textures[0] = texture; texture_id = gst_vaapi_texture_get_id(texture); - if (!gst_vaapi_texture_put_surface(texture, surface, flags)) + if (!gst_vaapi_texture_put_surface(texture, surface, NULL, flags)) g_error("could not transfer VA surface to texture"); if (!gst_vaapi_window_glx_put_texture(glx_window, texture, NULL, NULL)) @@ -156,7 +156,7 @@ main(int argc, char *argv[]) textures[1] = texture; - if (!gst_vaapi_texture_put_surface(texture, surface, flags)) + if (!gst_vaapi_texture_put_surface(texture, surface, NULL, flags)) g_error("could not transfer VA surface to texture"); if (gl_get_current_texture_2d() != texture_id) From 1799b362a3a824bda373f8b6e5f95de2d0a383bd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Oct 2014 13:11:54 +0200 Subject: [PATCH 1835/3781] texture: drop support for VA/GLX interfaces. The VA/GLX interfaces are obsolete. They used to exist for XvBA, and ease of use, but they had other caveats to deal with. It's now better to move on to legacy mode, whereby VA/GLX interop is two be provided through (i) X11 Pixmap, and (ii) other modern means of buffer sharing. https://bugzilla.gnome.org/show_bug.cgi?id=736711 --- configure.ac | 18 ------------- gst-libs/gst/vaapi/Makefile.am | 4 +-- gst-libs/gst/vaapi/gstvaapicompat.h | 12 --------- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 5 ++-- gst-libs/gst/vaapi/gstvaapitexture.c | 34 ------------------------ 5 files changed, 4 insertions(+), 69 deletions(-) diff --git a/configure.ac b/configure.ac index 1b0a620323..cbe9962f1b 100644 --- a/configure.ac +++ b/configure.ac @@ -48,14 +48,12 @@ m4_define([va_api_version], [0.30.4]) m4_define([va_api_enc_version], [0.34.0]) m4_define([va_api_drm_version], [0.33.0]) m4_define([va_api_x11_version], [0.31.0]) -m4_define([va_api_glx_version], [0.32.0]) m4_define([va_api_wld_version], [0.33.0]) # libva package version number m4_define([libva_enc_package_version], [1.2.0]) m4_define([libva_drm_package_version], [1.1.0]) m4_define([libva_x11_package_version], [1.0.3]) -m4_define([libva_glx_package_version], [1.0.9]) m4_define([libva_wld_package_version], [1.1.0]) # gtk-doc version number @@ -693,22 +691,6 @@ if test $USE_X11 -eq 1; then fi AC_SUBST(LIBVA_X11_PKGNAME) -dnl VA/GLX API -HAVE_VA_GLX=0 -LIBVA_GLX_PKGNAME="libva-glx" -if test $USE_GLX -eq 1; then - PKG_CHECK_MODULES(LIBVA_GLX, [$LIBVA_GLX_PKGNAME >= va_api_glx_version], - [HAVE_VA_GLX=1], [LIBVA_GLX_PKGNAME="$LIBVA_X11_PKGNAME"]) - - if test $HAVE_VA_GLX -eq 1; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$LIBVA_GLX_CFLAGS" - AC_CHECK_HEADERS([va/va_glx.h], [:], [HAVE_VA_GLX=0]) - CPPFLAGS="$saved_CPPFLAGS" - fi -fi -AC_SUBST(LIBVA_GLX_PKGNAME) - dnl Check for va_dec_jpeg.h header saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 9d90f71ed0..9c5cf88d9b 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -389,7 +389,7 @@ libgstvaapi_glx_@GST_API_VERSION@_la_CFLAGS = \ $(GST_BASE_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ $(GL_CFLAGS) \ - $(LIBVA_GLX_CFLAGS) \ + $(LIBVA_X11_CFLAGS) \ $(NULL) libgstvaapi_glx_@GST_API_VERSION@_la_LIBADD = \ @@ -399,7 +399,7 @@ libgstvaapi_glx_@GST_API_VERSION@_la_LIBADD = \ $(GST_VIDEO_LIBS) \ $(X11_LIBS) \ $(GL_LIBS) \ - $(LIBVA_GLX_LIBS) \ + $(LIBVA_X11_LIBS) \ libgstvaapi-x11-$(GST_API_VERSION).la \ libgstvaapi-$(GST_API_VERSION).la \ $(DLOPEN_LIBS) \ diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index f2d5b92776..7f106eb782 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -27,18 +27,6 @@ #include -#ifdef HAVE_VA_VA_GLX_H -# define USE_VAAPI_GLX 1 -#else -# define USE_VAAPI_GLX 0 -#endif - -#if USE_VAAPI_GLX -# include -#else -# define vaGetDisplayGLX(dpy) vaGetDisplay(dpy) -#endif - /* Compatibility glue with VA-API < 0.31 */ #if !VA_CHECK_VERSION(0,31,0) #undef vaSyncSurface diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index e80d7c2f24..b1bdef966c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -48,11 +48,10 @@ gst_vaapi_display_glx_get_display_info (GstVaapiDisplay * display, const GstVaapiDisplayGLXClass *const klass = GST_VAAPI_DISPLAY_GLX_GET_CLASS (display); - info->va_display = vaGetDisplayGLX (GST_VAAPI_DISPLAY_XDISPLAY (display)); - if (!info->va_display) + if (!klass->parent_get_display (display, info)) return FALSE; info->display_type = GST_VAAPI_DISPLAY_TYPE_GLX; - return klass->parent_get_display (display, info); + return TRUE; } static void diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 0ccc0579bb..77ef95fb9b 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -76,15 +76,6 @@ struct _GstVaapiTextureClass static void _gst_vaapi_texture_destroy_objects (GstVaapiTexture * texture) { -#if USE_VAAPI_GLX - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - if (texture->gl_surface) { - vaDestroySurfaceGLX (GST_VAAPI_OBJECT_VADISPLAY (texture), - texture->gl_surface); - texture->gl_surface = NULL; - } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); -#else GLContextState old_cs; GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); @@ -107,7 +98,6 @@ _gst_vaapi_texture_destroy_objects (GstVaapiTexture * texture) texture->gl_context = NULL; } GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); -#endif } static void @@ -128,16 +118,6 @@ static gboolean _gst_vaapi_texture_create_objects (GstVaapiTexture * texture, GLuint texture_id) { gboolean success = FALSE; - -#if USE_VAAPI_GLX - VAStatus status; - - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - status = vaCreateSurfaceGLX (GST_VAAPI_OBJECT_VADISPLAY (texture), - texture->target, texture_id, &texture->gl_surface); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); - success = vaapi_check_status (status, "vaCreateSurfaceGLX()"); -#else GLContextState old_cs; GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); @@ -160,7 +140,6 @@ _gst_vaapi_texture_create_objects (GstVaapiTexture * texture, GLuint texture_id) end: gl_set_current_context (&old_cs, NULL); GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); -#endif return success; } @@ -471,17 +450,6 @@ _gst_vaapi_texture_put_surface (GstVaapiTexture * texture, GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) { VAStatus status; - -#if USE_VAAPI_GLX - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - status = vaCopySurfaceGLX (GST_VAAPI_OBJECT_VADISPLAY (texture), - texture->gl_surface, - GST_VAAPI_OBJECT_ID (surface), from_GstVaapiSurfaceRenderFlags (flags) - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); - if (!vaapi_check_status (status, "vaCopySurfaceGLX()")) - return FALSE; -#else GstVaapiRectangle rect; GLContextState old_cs; gboolean success = FALSE; @@ -561,8 +529,6 @@ out_reset_context: end: GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); return success; -#endif - return TRUE; } gboolean From 2101685b7d5f02d05665e85c0ed6d0788a3d25f5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 23 Oct 2014 17:44:23 +0200 Subject: [PATCH 1836/3781] texture: move to core libgstvaapi base library. GstVaapiTexture is a generic abstraction that could be moved to the core libgstvaapi library. While doing this, no extra dependency needs to be added. This means that a GstVaapitextureClass is now available for any specific code that needs to be added, e.g. creation of the underlying GL texture objects, or backend dependent ways to upload a surface to the texture object. Generic OpenGL data types (GLuint, GLenum) are also replaced with a plain guint. https://bugzilla.gnome.org/show_bug.cgi?id=736715 --- gst-libs/gst/vaapi/Makefile.am | 5 +- gst-libs/gst/vaapi/gstvaapitexture.c | 373 +++------------------ gst-libs/gst/vaapi/gstvaapitexture.h | 65 +++- gst-libs/gst/vaapi/gstvaapitexture_glx.c | 383 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapitexture_glx.h | 42 +++ gst-libs/gst/vaapi/gstvaapitexture_priv.h | 160 +++++++++ gst/vaapi/gstvaapivideoconverter_glx.c | 6 +- gst/vaapi/gstvaapivideometa_texture.c | 7 +- tests/test-textures.c | 12 +- 9 files changed, 702 insertions(+), 351 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapitexture_glx.c create mode 100644 gst-libs/gst/vaapi/gstvaapitexture_glx.h create mode 100644 gst-libs/gst/vaapi/gstvaapitexture_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 9c5cf88d9b..e0b9fd48b2 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -70,6 +70,7 @@ libgstvaapi_source_c = \ gstvaapisurface.c \ gstvaapisurfacepool.c \ gstvaapisurfaceproxy.c \ + gstvaapitexture.c \ gstvaapiutils.c \ gstvaapiutils_core.c \ gstvaapiutils_h264.c \ @@ -97,6 +98,7 @@ libgstvaapi_source_h = \ gstvaapisurface.h \ gstvaapisurfacepool.h \ gstvaapisurfaceproxy.h \ + gstvaapitexture.h \ gstvaapitypes.h \ gstvaapiutils_h264.h \ gstvaapiutils_mpeg2.h \ @@ -127,6 +129,7 @@ libgstvaapi_source_priv_h = \ gstvaapipixmap_priv.h \ gstvaapisurface_priv.h \ gstvaapisurfaceproxy_priv.h \ + gstvaapitexture_priv.h \ gstvaapiutils.h \ gstvaapiutils_core.h \ gstvaapiutils_h264_priv.h \ @@ -227,7 +230,7 @@ libgstvaapi_x11_source_priv_h = \ libgstvaapi_glx_source_c = \ gstvaapidisplay_glx.c \ - gstvaapitexture.c \ + gstvaapitexture_glx.c \ gstvaapiutils.c \ gstvaapiutils_glx.c \ gstvaapiutils_x11.c \ diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 77ef95fb9b..4d0df1c72f 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -29,258 +29,52 @@ #include "sysdeps.h" #include "gstvaapitexture.h" -#include "gstvaapicompat.h" -#include "gstvaapiutils.h" -#include "gstvaapiutils_glx.h" -#include "gstvaapidisplay_glx.h" -#include "gstvaapidisplay_x11_priv.h" -#include "gstvaapidisplay_glx_priv.h" -#include "gstvaapiobject_priv.h" +#include "gstvaapitexture_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiTextureClass GstVaapiTextureClass; - -/** - * GstVaapiTexture: - * - * Base object for system-dependent textures. - */ -struct _GstVaapiTexture -{ - /*< private >*/ - GstVaapiObject parent_instance; - - GLenum target; - GLenum format; - guint width; - guint height; - GLContextState *gl_context; - void *gl_surface; - GLPixmapObject *pixo; - GLFramebufferObject *fbo; - guint foreign_texture:1; -}; - -/** - * GstVaapiTextureClass: - * - * Base class for system-dependent textures. - */ -struct _GstVaapiTextureClass -{ - GstVaapiObjectClass parent_class; -}; +/* Ensure those symbols are actually defined in the resulting libraries */ +#undef gst_vaapi_texture_ref +#undef gst_vaapi_texture_unref +#undef gst_vaapi_texture_replace static void -_gst_vaapi_texture_destroy_objects (GstVaapiTexture * texture) -{ - GLContextState old_cs; - - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - if (texture->gl_context) - gl_set_current_context (texture->gl_context, &old_cs); - - if (texture->fbo) { - gl_destroy_framebuffer_object (texture->fbo); - texture->fbo = NULL; - } - - if (texture->pixo) { - gl_destroy_pixmap_object (texture->pixo); - texture->pixo = NULL; - } - - if (texture->gl_context) { - gl_set_current_context (&old_cs, NULL); - gl_destroy_context (texture->gl_context); - texture->gl_context = NULL; - } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); -} - -static void -gst_vaapi_texture_destroy (GstVaapiTexture * texture) -{ - const GLuint texture_id = GST_VAAPI_OBJECT_ID (texture); - - _gst_vaapi_texture_destroy_objects (texture); - - if (texture_id) { - if (!texture->foreign_texture) - glDeleteTextures (1, &texture_id); - GST_VAAPI_OBJECT_ID (texture) = 0; - } -} - -static gboolean -_gst_vaapi_texture_create_objects (GstVaapiTexture * texture, GLuint texture_id) -{ - gboolean success = FALSE; - GLContextState old_cs; - - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - gl_get_current_context (&old_cs); - texture->gl_context = gl_create_context (GST_VAAPI_OBJECT_XDISPLAY (texture), - GST_VAAPI_OBJECT_XSCREEN (texture), &old_cs); - if (!texture->gl_context || - !gl_set_current_context (texture->gl_context, NULL)) - goto end; - - texture->pixo = gl_create_pixmap_object (GST_VAAPI_OBJECT_XDISPLAY (texture), - texture->width, texture->height); - if (!texture->pixo) - goto end; - - texture->fbo = gl_create_framebuffer_object (texture->target, - texture_id, texture->width, texture->height); - if (texture->fbo) - success = TRUE; -end: - gl_set_current_context (&old_cs, NULL); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); - return success; -} - -static gboolean -gst_vaapi_texture_create (GstVaapiTexture * texture) -{ - GLuint texture_id; - - if (texture->foreign_texture) - texture_id = GST_VAAPI_OBJECT_ID (texture); - else { - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - texture_id = gl_create_texture (texture->target, - texture->format, texture->width, texture->height); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); - if (!texture_id) - return FALSE; - GST_VAAPI_OBJECT_ID (texture) = texture_id; - } - - return _gst_vaapi_texture_create_objects (texture, texture_id); -} - -static void -gst_vaapi_texture_init (GstVaapiTexture * texture, GLuint texture_id, - GLenum target, GLenum format, guint width, guint height) +gst_vaapi_texture_init (GstVaapiTexture * texture, guint texture_id, + guint target, guint format, guint width, guint height) { GST_VAAPI_OBJECT_ID (texture) = texture_id; - texture->foreign_texture = texture_id != GL_NONE; - - texture->target = target; - texture->format = format; + texture->is_wrapped = texture_id != 0; + texture->gl_target = target; + texture->gl_format = format; texture->width = width; texture->height = height; } -#define gst_vaapi_texture_finalize gst_vaapi_texture_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiTexture, gst_vaapi_texture); +static inline gboolean +gst_vaapi_texture_allocate (GstVaapiTexture * texture) +{ + return GST_VAAPI_TEXTURE_GET_CLASS (texture)->allocate (texture); +} -/** - * gst_vaapi_texture_new: - * @display: a #GstVaapiDisplay - * @target: the target to which the texture is bound - * @format: the format of the pixel data - * @width: the requested width, in pixels - * @height: the requested height, in pixels - * - * Creates a texture with the specified dimensions, @target and - * @format. Note that only GL_TEXTURE_2D @target and GL_RGBA or - * GL_BGRA formats are supported at this time. - * - * The application shall maintain the live GL context itself. That is, - * gst_vaapi_window_glx_make_current() must be called beforehand, or - * any other function like glXMakeCurrent() if the context is managed - * outside of this library. - * - * Return value: the newly created #GstVaapiTexture object - */ GstVaapiTexture * -gst_vaapi_texture_new (GstVaapiDisplay * display, GLenum target, GLenum format, +gst_vaapi_texture_new (const GstVaapiTextureClass * klass, + GstVaapiDisplay * display, guint texture_id, guint target, guint format, guint width, guint height) { GstVaapiTexture *texture; - g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); - g_return_val_if_fail (target != GL_NONE, NULL); - g_return_val_if_fail (format != GL_NONE, NULL); + g_return_val_if_fail (target != 0, NULL); + g_return_val_if_fail (format != 0, NULL); g_return_val_if_fail (width > 0, NULL); g_return_val_if_fail (height > 0, NULL); - texture = gst_vaapi_object_new (gst_vaapi_texture_class (), display); - if (!texture) - return NULL; - - gst_vaapi_texture_init (texture, GL_NONE, target, format, width, height); - if (!gst_vaapi_texture_create (texture)) - goto error; - return texture; - -error: - gst_vaapi_object_unref (texture); - return NULL; -} - -/** - * gst_vaapi_texture_new_with_texture: - * @display: a #GstVaapiDisplay - * @texture_id: the foreign GL texture name to use - * @target: the target to which the texture is bound - * @format: the format of the pixel data - * - * Creates a texture from an existing GL texture, with the specified - * @target and @format. Note that only GL_TEXTURE_2D @target and - * GL_RGBA or GL_BGRA formats are supported at this time. The - * dimensions will be retrieved from the @texture_id. - * - * The application shall maintain the live GL context itself. That is, - * gst_vaapi_window_glx_make_current() must be called beforehand, or - * any other function like glXMakeCurrent() if the context is managed - * outside of this library. - * - * Return value: the newly created #GstVaapiTexture object - */ -GstVaapiTexture * -gst_vaapi_texture_new_with_texture (GstVaapiDisplay * display, - GLuint texture_id, GLenum target, GLenum format) -{ - GstVaapiTexture *texture; - guint width, height, border_width; - GLTextureState ts; - gboolean success; - - g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); - g_return_val_if_fail (target != GL_NONE, NULL); - g_return_val_if_fail (format != GL_NONE, NULL); - - /* Check texture dimensions */ - GST_VAAPI_DISPLAY_LOCK (display); - success = gl_bind_texture (&ts, target, texture_id); - if (success) { - if (!gl_get_texture_param (target, GL_TEXTURE_WIDTH, &width) || - !gl_get_texture_param (target, GL_TEXTURE_HEIGHT, &height) || - !gl_get_texture_param (target, GL_TEXTURE_BORDER, &border_width)) - success = FALSE; - gl_unbind_texture (&ts); - } - GST_VAAPI_DISPLAY_UNLOCK (display); - if (!success) - return NULL; - - width -= 2 * border_width; - height -= 2 * border_width; - g_return_val_if_fail (width > 0, NULL); - g_return_val_if_fail (height > 0, NULL); - - texture = gst_vaapi_object_new (gst_vaapi_texture_class (), display); + texture = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (klass), display); if (!texture) return NULL; gst_vaapi_texture_init (texture, texture_id, target, format, width, height); - if (!gst_vaapi_texture_create (texture)) + if (!gst_vaapi_texture_allocate (texture)) goto error; return texture; @@ -300,7 +94,7 @@ error: GstVaapiTexture * gst_vaapi_texture_ref (GstVaapiTexture * texture) { - return gst_vaapi_object_ref (texture); + return gst_vaapi_texture_ref_internal (texture); } /** @@ -313,7 +107,7 @@ gst_vaapi_texture_ref (GstVaapiTexture * texture) void gst_vaapi_texture_unref (GstVaapiTexture * texture) { - gst_vaapi_object_unref (texture); + gst_vaapi_texture_unref_internal (texture); } /** @@ -329,7 +123,7 @@ void gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr, GstVaapiTexture * new_texture) { - gst_vaapi_object_replace (old_texture_ptr, new_texture); + gst_vaapi_texture_replace_internal (old_texture_ptr, new_texture); } /** @@ -340,12 +134,12 @@ gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr, * * Return value: the underlying texture id of the @texture */ -GLuint +guint gst_vaapi_texture_get_id (GstVaapiTexture * texture) { g_return_val_if_fail (texture != NULL, 0); - return GST_VAAPI_OBJECT_ID (texture); + return GST_VAAPI_TEXTURE_ID (texture); } /** @@ -356,12 +150,12 @@ gst_vaapi_texture_get_id (GstVaapiTexture * texture) * * Return value: the texture target */ -GLenum +guint gst_vaapi_texture_get_target (GstVaapiTexture * texture) { - g_return_val_if_fail (texture != NULL, GL_NONE); + g_return_val_if_fail (texture != NULL, 0); - return texture->target; + return GST_VAAPI_TEXTURE_TARGET (texture); } /** @@ -372,12 +166,12 @@ gst_vaapi_texture_get_target (GstVaapiTexture * texture) * * Return value: the texture format */ -GLenum +guint gst_vaapi_texture_get_format (GstVaapiTexture * texture) { - g_return_val_if_fail (texture != NULL, GL_NONE); + g_return_val_if_fail (texture != NULL, 0); - return texture->format; + return GST_VAAPI_TEXTURE_FORMAT (texture); } /** @@ -393,7 +187,7 @@ gst_vaapi_texture_get_width (GstVaapiTexture * texture) { g_return_val_if_fail (texture != NULL, 0); - return texture->width; + return GST_VAAPI_TEXTURE_WIDTH (texture); } /** @@ -409,7 +203,7 @@ gst_vaapi_texture_get_height (GstVaapiTexture * texture) { g_return_val_if_fail (texture != NULL, 0); - return texture->height; + return GST_VAAPI_TEXTURE_HEIGHT (texture); } /** @@ -427,10 +221,10 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture, g_return_if_fail (texture != NULL); if (width_ptr) - *width_ptr = texture->width; + *width_ptr = GST_VAAPI_TEXTURE_WIDTH (texture); if (height_ptr) - *height_ptr = texture->height; + *height_ptr = GST_VAAPI_TEXTURE_HEIGHT (texture); } /** @@ -445,14 +239,19 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture, * * Return value: %TRUE on success */ -static gboolean -_gst_vaapi_texture_put_surface (GstVaapiTexture * texture, +gboolean +gst_vaapi_texture_put_surface (GstVaapiTexture * texture, GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) { - VAStatus status; + const GstVaapiTextureClass *klass; GstVaapiRectangle rect; - GLContextState old_cs; - gboolean success = FALSE; + + g_return_val_if_fail (texture != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); + + klass = GST_VAAPI_TEXTURE_GET_CLASS (texture); + if (!klass) + return FALSE; if (!crop_rect) { rect.x = 0; @@ -460,83 +259,5 @@ _gst_vaapi_texture_put_surface (GstVaapiTexture * texture, gst_vaapi_surface_get_size (surface, &rect.width, &rect.height); crop_rect = ▭ } - - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture), - GST_VAAPI_OBJECT_ID (surface), - texture->pixo->pixmap, - crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height, - 0, 0, texture->width, texture->height, - NULL, 0, from_GstVaapiSurfaceRenderFlags (flags) - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); - if (!vaapi_check_status (status, "vaPutSurface() [TFP]")) - return FALSE; - - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - if (texture->gl_context) { - success = gl_set_current_context (texture->gl_context, &old_cs); - if (!success) - goto end; - } - - success = gl_bind_framebuffer_object (texture->fbo); - if (!success) { - GST_DEBUG ("could not bind FBO"); - goto out_reset_context; - } - - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); - success = gst_vaapi_surface_sync (surface); - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - if (!success) { - GST_DEBUG ("could not render surface to pixmap"); - goto out_unbind_fbo; - } - - success = gl_bind_pixmap_object (texture->pixo); - if (!success) { - GST_DEBUG ("could not bind GLX pixmap"); - goto out_unbind_fbo; - } - - glColor4f (1.0f, 1.0f, 1.0f, 1.0f); - glBegin (GL_QUADS); - { - glTexCoord2f (0.0f, 0.0f); - glVertex2i (0, 0); - glTexCoord2f (0.0f, 1.0f); - glVertex2i (0, texture->height); - glTexCoord2f (1.0f, 1.0f); - glVertex2i (texture->width, texture->height); - glTexCoord2f (1.0f, 0.0f); - glVertex2i (texture->width, 0); - } - glEnd (); - - success = gl_unbind_pixmap_object (texture->pixo); - if (!success) { - GST_DEBUG ("could not release GLX pixmap"); - goto out_unbind_fbo; - } - -out_unbind_fbo: - if (!gl_unbind_framebuffer_object (texture->fbo)) - success = FALSE; -out_reset_context: - if (texture->gl_context && !gl_set_current_context (&old_cs, NULL)) - success = FALSE; -end: - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); - return success; -} - -gboolean -gst_vaapi_texture_put_surface (GstVaapiTexture * texture, - GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) -{ - g_return_val_if_fail (texture != NULL, FALSE); - g_return_val_if_fail (surface != NULL, FALSE); - - return _gst_vaapi_texture_put_surface (texture, surface, crop_rect, flags); + return klass->put_surface (texture, surface, crop_rect, flags); } diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 5ae71c201a..3856df8714 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -25,24 +25,61 @@ #ifndef GST_VAAPI_TEXTURE_H #define GST_VAAPI_TEXTURE_H -#include #include -#include -#include #include G_BEGIN_DECLS +#define GST_VAAPI_TEXTURE(obj) \ + ((GstVaapiTexture *)(obj)) + +/** + * GST_VAAPI_TEXTURE_ID: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the GL texture id associated with the @texture + */ +#define GST_VAAPI_TEXTURE_ID(texture) \ + gst_vaapi_texture_get_id (GST_VAAPI_TEXTURE (texture)) + +/** + * GST_VAAPI_TEXTURE_TARGET: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the GL texture target associated with the @texture + */ +#define GST_VAAPI_TEXTURE_TARGET(texture) \ + gst_vaapi_texture_get_target (GST_VAAPI_TEXTURE (texture)) + +/** + * GST_VAAPI_TEXTURE_FORMAT: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the GL texture format associated with the @texture + */ +#define GST_VAAPI_TEXTURE_FORMAT(texture) \ + gst_vaapi_texture_get_format (GST_VAAPI_TEXTURE (texture)) + +/** + * GST_VAAPI_TEXTURE_WIDTH: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the GL texture width associated with the @texture + */ +#define GST_VAAPI_TEXTURE_WIDTH(texture) \ + gst_vaapi_texture_get_width (GST_VAAPI_TEXTURE (texture)) + +/** + * GST_VAAPI_TEXTURE_HEIGHT: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the GL texture height associated with the @texture + */ +#define GST_VAAPI_TEXTURE_HEIGHT(texture) \ + gst_vaapi_texture_get_height (GST_VAAPI_TEXTURE (texture)) + typedef struct _GstVaapiTexture GstVaapiTexture; -GstVaapiTexture * -gst_vaapi_texture_new (GstVaapiDisplay * display, GLenum target, GLenum format, - guint width, guint height); - -GstVaapiTexture * -gst_vaapi_texture_new_with_texture (GstVaapiDisplay * display, GLuint texture_id, - GLenum target, GLenum format); - GstVaapiTexture * gst_vaapi_texture_ref (GstVaapiTexture * texture); @@ -53,13 +90,13 @@ void gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr, GstVaapiTexture * new_texture); -GLuint +guint gst_vaapi_texture_get_id (GstVaapiTexture * texture); -GLenum +guint gst_vaapi_texture_get_target (GstVaapiTexture * texture); -GLenum +guint gst_vaapi_texture_get_format (GstVaapiTexture * texture); guint diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.c b/gst-libs/gst/vaapi/gstvaapitexture_glx.c new file mode 100644 index 0000000000..acaa4f05d0 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.c @@ -0,0 +1,383 @@ +/* + * gstvaapitexture_glx.c - VA/GLX texture abstraction + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne + * Copyright (C) 2012-2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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:gstvaapitexture_glx + * @short_description: VA/GLX texture abstraction + */ + +#include "sysdeps.h" +#include "gstvaapitexture.h" +#include "gstvaapitexture_glx.h" +#include "gstvaapitexture_priv.h" +#include "gstvaapicompat.h" +#include "gstvaapiutils.h" +#include "gstvaapiutils_glx.h" +#include "gstvaapidisplay_glx.h" +#include "gstvaapidisplay_x11_priv.h" +#include "gstvaapidisplay_glx_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +#define GST_VAAPI_TEXTURE_GLX(texture) \ + ((GstVaapiTextureGLX *)(texture)) + +typedef struct _GstVaapiTextureGLX GstVaapiTextureGLX; +typedef struct _GstVaapiTextureGLXClass GstVaapiTextureGLXClass; + +/** + * GstVaapiTextureGLX: + * + * Base object for GLX texture wrapper. + */ +struct _GstVaapiTextureGLX +{ + /*< private >*/ + GstVaapiTexture parent_instance; + + GLContextState *gl_context; + GLPixmapObject *pixo; + GLFramebufferObject *fbo; +}; + +/** + * GstVaapiTextureGLXClass: + * + * Base class for GLX texture wrapper. + */ +struct _GstVaapiTextureGLXClass +{ + /*< private >*/ + GstVaapiTextureClass parent_class; +}; + +static gboolean +gst_vaapi_texture_glx_put_surface (GstVaapiTexture * texture, + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, + guint flags); + +static void +destroy_objects (GstVaapiTextureGLX * texture) +{ + GLContextState old_cs; + + if (texture->gl_context) + gl_set_current_context (texture->gl_context, &old_cs); + + if (texture->fbo) { + gl_destroy_framebuffer_object (texture->fbo); + texture->fbo = NULL; + } + + if (texture->pixo) { + gl_destroy_pixmap_object (texture->pixo); + texture->pixo = NULL; + } + + if (texture->gl_context) { + gl_set_current_context (&old_cs, NULL); + gl_destroy_context (texture->gl_context); + texture->gl_context = NULL; + } +} + +static void +destroy_texture_unlocked (GstVaapiTexture * texture) +{ + const guint texture_id = GST_VAAPI_TEXTURE_ID (texture); + + destroy_objects (GST_VAAPI_TEXTURE_GLX (texture)); + + if (texture_id) { + if (!texture->is_wrapped) + glDeleteTextures (1, &texture_id); + GST_VAAPI_TEXTURE_ID (texture) = 0; + } +} + +static void +gst_vaapi_texture_glx_destroy (GstVaapiTexture * texture) +{ + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + destroy_texture_unlocked (texture); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); +} + +static gboolean +create_objects (GstVaapiTextureGLX * texture, guint texture_id) +{ + GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture); + GLContextState old_cs; + gboolean success = FALSE; + + gl_get_current_context (&old_cs); + + texture->gl_context = gl_create_context (GST_VAAPI_OBJECT_XDISPLAY (texture), + GST_VAAPI_OBJECT_XSCREEN (texture), &old_cs); + if (!texture->gl_context || + !gl_set_current_context (texture->gl_context, NULL)) + return FALSE; + + texture->pixo = gl_create_pixmap_object (GST_VAAPI_OBJECT_XDISPLAY (texture), + base_texture->width, base_texture->height); + if (!texture->pixo) { + GST_ERROR ("failed to create GLX pixmap"); + goto out_reset_context; + } + + texture->fbo = gl_create_framebuffer_object (base_texture->gl_target, + texture_id, base_texture->width, base_texture->height); + if (!texture->fbo) { + GST_ERROR ("failed to create FBO"); + goto out_reset_context; + } + success = TRUE; + +out_reset_context: + gl_set_current_context (&old_cs, NULL); + return success; +} + +static gboolean +create_texture_unlocked (GstVaapiTexture * texture) +{ + guint texture_id; + + if (texture->is_wrapped) + texture_id = GST_VAAPI_TEXTURE_ID (texture); + else { + texture_id = gl_create_texture (texture->gl_target, texture->gl_format, + texture->width, texture->height); + if (!texture_id) + return FALSE; + GST_VAAPI_TEXTURE_ID (texture) = texture_id; + } + return create_objects (GST_VAAPI_TEXTURE_GLX (texture), texture_id); +} + +static gboolean +gst_vaapi_texture_glx_create (GstVaapiTexture * texture) +{ + gboolean success; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + success = create_texture_unlocked (texture); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + return success; +} + +static void +gst_vaapi_texture_glx_class_init (GstVaapiTextureGLXClass * klass) +{ + GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); + GstVaapiTextureClass *const texture_class = GST_VAAPI_TEXTURE_CLASS (klass); + + object_class->finalize = (GstVaapiObjectFinalizeFunc) + gst_vaapi_texture_glx_destroy; + + texture_class->allocate = gst_vaapi_texture_glx_create; + texture_class->put_surface = gst_vaapi_texture_glx_put_surface; +} + +#define gst_vaapi_texture_glx_finalize gst_vaapi_texture_glx_destroy +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiTextureGLX, + gst_vaapi_texture_glx, gst_vaapi_texture_glx_class_init (&g_class)); + +/** + * gst_vaapi_texture_glx_new: + * @display: a #GstVaapiDisplay + * @target: the target to which the texture is bound + * @format: the format of the pixel data + * @width: the requested width, in pixels + * @height: the requested height, in pixels + * + * Creates a texture with the specified dimensions, @target and + * @format. Note that only GL_TEXTURE_2D @target and GL_RGBA or + * GL_BGRA formats are supported at this time. + * + * The application shall maintain the live GL context itself. That is, + * gst_vaapi_window_glx_make_current() must be called beforehand, or + * any other function like glXMakeCurrent() if the context is managed + * outside of this library. + * + * Return value: the newly created #GstVaapiTexture object + */ +GstVaapiTexture * +gst_vaapi_texture_glx_new (GstVaapiDisplay * display, guint target, + guint format, guint width, guint height) +{ + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); + + return + gst_vaapi_texture_new (GST_VAAPI_TEXTURE_CLASS + (gst_vaapi_texture_glx_class ()), display, GL_NONE, target, format, width, + height); +} + +/** + * gst_vaapi_texture_glx_new_wrapped: + * @display: a #GstVaapiDisplay + * @texture_id: the foreign GL texture name to use + * @target: the target to which the texture is bound + * @format: the format of the pixel data + * + * Creates a texture from an existing GL texture, with the specified + * @target and @format. Note that only GL_TEXTURE_2D @target and + * GL_RGBA or GL_BGRA formats are supported at this time. The + * dimensions will be retrieved from the @texture_id. + * + * The application shall maintain the live GL context itself. That is, + * gst_vaapi_window_glx_make_current() must be called beforehand, or + * any other function like glXMakeCurrent() if the context is managed + * outside of this library. + * + * Return value: the newly created #GstVaapiTexture object + */ +GstVaapiTexture * +gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display, + guint texture_id, guint target, guint format) +{ + guint width, height, border_width; + GLTextureState ts; + gboolean success; + + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); + g_return_val_if_fail (target != GL_NONE, NULL); + g_return_val_if_fail (format != GL_NONE, NULL); + + /* Check texture dimensions */ + GST_VAAPI_DISPLAY_LOCK (display); + success = gl_bind_texture (&ts, target, texture_id); + if (success) { + if (!gl_get_texture_param (target, GL_TEXTURE_WIDTH, &width) || + !gl_get_texture_param (target, GL_TEXTURE_HEIGHT, &height) || + !gl_get_texture_param (target, GL_TEXTURE_BORDER, &border_width)) + success = FALSE; + gl_unbind_texture (&ts); + } + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!success) + return NULL; + + width -= 2 * border_width; + height -= 2 * border_width; + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + + return + gst_vaapi_texture_new (GST_VAAPI_TEXTURE_CLASS + (gst_vaapi_texture_glx_class ()), display, texture_id, target, format, + width, height); +} + +/** + * gst_vaapi_texture_put_surface: + * @texture: a #GstVaapiTexture + * @surface: a #GstVaapiSurface + * @flags: postprocessing flags. See #GstVaapiTextureRenderFlags + * + * Renders the @surface into the àtexture. The @flags specify how + * de-interlacing (if needed), color space conversion, scaling and + * other postprocessing transformations are performed. + * + * Return value: %TRUE on success + */ +static gboolean +gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture, + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) +{ + GstVaapiTextureGLX *const texture = GST_VAAPI_TEXTURE_GLX (base_texture); + VAStatus status; + GLContextState old_cs; + gboolean success = FALSE; + + status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture), + GST_VAAPI_OBJECT_ID (surface), texture->pixo->pixmap, + crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height, + 0, 0, base_texture->width, base_texture->height, + NULL, 0, from_GstVaapiSurfaceRenderFlags (flags)); + if (!vaapi_check_status (status, "vaPutSurface() [TFP]")) + return FALSE; + + if (texture->gl_context && + !gl_set_current_context (texture->gl_context, &old_cs)) + return FALSE; + + if (!gl_bind_framebuffer_object (texture->fbo)) { + GST_ERROR ("failed to bind FBO"); + goto out_reset_context; + } + + if (!gst_vaapi_surface_sync (surface)) { + GST_ERROR ("failed to render surface to pixmap"); + goto out_unbind_fbo; + } + + if (!gl_bind_pixmap_object (texture->pixo)) { + GST_ERROR ("could not bind GLX pixmap"); + goto out_unbind_fbo; + } + + glColor4f (1.0f, 1.0f, 1.0f, 1.0f); + glBegin (GL_QUADS); + { + glTexCoord2f (0.0f, 0.0f); + glVertex2i (0, 0); + glTexCoord2f (0.0f, 1.0f); + glVertex2i (0, base_texture->height); + glTexCoord2f (1.0f, 1.0f); + glVertex2i (base_texture->width, base_texture->height); + glTexCoord2f (1.0f, 0.0f); + glVertex2i (base_texture->width, 0); + } + glEnd (); + + if (!gl_unbind_pixmap_object (texture->pixo)) { + GST_ERROR ("failed to release GLX pixmap"); + goto out_unbind_fbo; + } + success = TRUE; + +out_unbind_fbo: + if (!gl_unbind_framebuffer_object (texture->fbo)) + success = FALSE; +out_reset_context: + if (texture->gl_context && !gl_set_current_context (&old_cs, NULL)) + success = FALSE; + return success; +} + +static gboolean +gst_vaapi_texture_glx_put_surface (GstVaapiTexture * texture, + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) +{ + gboolean success; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + success = gst_vaapi_texture_glx_put_surface_unlocked (texture, surface, + crop_rect, flags); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + return success; +} diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.h b/gst-libs/gst/vaapi/gstvaapitexture_glx.h new file mode 100644 index 0000000000..db8ddbb49c --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.h @@ -0,0 +1,42 @@ +/* + * gstvaapitexture_glx.h - VA/GLX texture abstraction + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne + * Copyright (C) 2012-2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_TEXTURE_GLX_H +#define GST_VAAPI_TEXTURE_GLX_H + +#include + +G_BEGIN_DECLS + +GstVaapiTexture * +gst_vaapi_texture_glx_new (GstVaapiDisplay * display, guint target, + guint format, guint width, guint height); + +GstVaapiTexture * +gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display, guint id, + guint target, guint format); + +G_END_DECLS + +#endif /* GST_VAAPI_TEXTURE_GLX_H */ diff --git a/gst-libs/gst/vaapi/gstvaapitexture_priv.h b/gst-libs/gst/vaapi/gstvaapitexture_priv.h new file mode 100644 index 0000000000..8cf57e6031 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapitexture_priv.h @@ -0,0 +1,160 @@ +/* + * gstvaapitexture_priv.h - VA texture abstraction (private definitions) + * + * Copyright (C) 2010-2011 Splitted-Desktop Systems + * Author: Gwenole Beauchesne + * Copyright (C) 2012-2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_TEXTURE_PRIV_H +#define GST_VAAPI_TEXTURE_PRIV_H + +#include "gstvaapiobject_priv.h" + +G_BEGIN_DECLS + +#define GST_VAAPI_TEXTURE_CLASS(klass) \ + ((GstVaapiTextureClass *)(klass)) + +#define GST_VAAPI_TEXTURE_GET_CLASS(obj) \ + GST_VAAPI_TEXTURE_CLASS (GST_VAAPI_OBJECT_GET_CLASS (obj)) + +/** + * GST_VAAPI_TEXTURE_ID: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the GL texture id associated with the @texture + */ +#undef GST_VAAPI_TEXTURE_ID +#define GST_VAAPI_TEXTURE_ID(texture) \ + (GST_VAAPI_OBJECT_ID (texture)) + +/** + * GST_VAAPI_TEXTURE_TARGET: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the GL texture target associated with the @texture + */ +#undef GST_VAAPI_TEXTURE_TARGET +#define GST_VAAPI_TEXTURE_TARGET(texture) \ + (GST_VAAPI_TEXTURE (texture)->gl_target) + +/** + * GST_VAAPI_TEXTURE_FORMAT: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the GL texture format associated with the @texture + */ +#undef GST_VAAPI_TEXTURE_FORMAT +#define GST_VAAPI_TEXTURE_FORMAT(texture) \ + (GST_VAAPI_TEXTURE (texture)->gl_format) + +/** + * GST_VAAPI_TEXTURE_WIDTH: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the GL texture width associated with the @texture + */ +#undef GST_VAAPI_TEXTURE_WIDTH +#define GST_VAAPI_TEXTURE_WIDTH(texture) \ + (GST_VAAPI_TEXTURE (texture)->width) + +/** + * GST_VAAPI_TEXTURE_HEIGHT: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the GL texture height associated with the @texture + */ +#undef GST_VAAPI_TEXTURE_HEIGHT +#define GST_VAAPI_TEXTURE_HEIGHT(texture) \ + (GST_VAAPI_TEXTURE (texture)->height) + +/* GstVaapiTextureClass hooks */ +typedef gboolean (*GstVaapiTextureAllocateFunc) (GstVaapiTexture * texture); +typedef gboolean (*GstVaapiTexturePutSurfaceFunc) (GstVaapiTexture * texture, + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, + guint flags); + +typedef struct _GstVaapiTextureClass GstVaapiTextureClass; + +/** + * GstVaapiTexture: + * + * Base class for API-dependent textures. + */ +struct _GstVaapiTexture { + /*< private >*/ + GstVaapiObject parent_instance; + + /*< protected >*/ + guint gl_target; + guint gl_format; + guint width; + guint height; + guint is_wrapped:1; +}; + +/** + * GstVaapiTextureClass: + * @put_surface: virtual function to render a #GstVaapiSurface into a texture + * + * Base class for API-dependent textures. + */ +struct _GstVaapiTextureClass { + /*< private >*/ + GstVaapiObjectClass parent_class; + + /*< protected >*/ + GstVaapiTextureAllocateFunc allocate; + GstVaapiTexturePutSurfaceFunc put_surface; +}; + +GstVaapiTexture * +gst_vaapi_texture_new (const GstVaapiTextureClass * klass, + GstVaapiDisplay * display, guint texture_id, guint target, guint format, + guint width, guint height); + +/* Inline reference counting for core libgstvaapi library */ +#ifdef IN_LIBGSTVAAPI_CORE +#define gst_vaapi_texture_ref_internal(texture) \ + ((gpointer)gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (texture))) + +#define gst_vaapi_texture_unref_internal(texture) \ + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (texture)) + +#define gst_vaapi_texture_replace_internal(old_texture_ptr, new_texture) \ + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **)(old_texture_ptr), \ + GST_VAAPI_MINI_OBJECT (new_texture)) + +#undef gst_vaapi_texture_ref +#define gst_vaapi_texture_ref(texture) \ + gst_vaapi_texture_ref_internal ((texture)) + +#undef gst_vaapi_texture_unref +#define gst_vaapi_texture_unref(texture) \ + gst_vaapi_texture_unref_internal ((texture)) + +#undef gst_vaapi_texture_replace +#define gst_vaapi_texture_replace(old_texture_ptr, new_texture) \ + gst_vaapi_texture_replace_internal ((old_texture_ptr), (new_texture)) +#endif + +G_END_DECLS + +#endif /* GST_VAAPI_TEXTURE_PRIV_H */ diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index 06ca7c5f64..4512d17234 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -23,7 +23,7 @@ */ #include "gst/vaapi/sysdeps.h" -#include +#include #include "gstvaapivideoconverter_glx.h" #include "gstvaapivideoconverter_x11.h" #include "gstvaapipluginutil.h" @@ -120,7 +120,7 @@ gst_vaapi_video_converter_glx_new (GstBuffer * buffer, const gchar * type, /* FIXME Should we assume target and format ? */ texture = - gst_vaapi_texture_new_with_texture (gst_vaapi_video_meta_get_display + gst_vaapi_texture_glx_new_wrapped (gst_vaapi_video_meta_get_display (meta), g_value_get_uint (dest), GL_TEXTURE_2D, GL_BGRA); if (!texture) return NULL; @@ -149,7 +149,7 @@ gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self, const guint texture = gst_vaapi_texture_get_id (priv->texture); gst_vaapi_texture_replace (&priv->texture, NULL); - priv->texture = gst_vaapi_texture_new_with_texture (new_dpy, + priv->texture = gst_vaapi_texture_glx_new_wrapped (new_dpy, texture, GL_TEXTURE_2D, GL_BGRA); } diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 429a8b3303..6b08f94ebf 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -25,9 +25,14 @@ */ #include "gst/vaapi/sysdeps.h" +#include #include "gstvaapivideometa.h" #include "gstvaapipluginutil.h" +#if USE_GLX +#include +#endif + #if GST_CHECK_VERSION(1,1,0) && USE_GLX #include "gstvaapivideometa_texture.h" @@ -95,7 +100,7 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, gst_vaapi_texture_get_id (meta_texture->texture) != texture_id[0]) { /* FIXME: should we assume target? */ GstVaapiTexture *const texture = - gst_vaapi_texture_new_with_texture (dpy, texture_id[0], + gst_vaapi_texture_glx_new_wrapped (dpy, texture_id[0], GL_TEXTURE_2D, GL_RGBA); gst_vaapi_texture_replace (&meta_texture->texture, texture); if (!texture) diff --git a/tests/test-textures.c b/tests/test-textures.c index c4673adedd..63b4c784ae 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -23,9 +23,9 @@ #include "gst/vaapi/sysdeps.h" #include #include +#include #include #include -#include #include "image.h" static inline void pause(void) @@ -89,10 +89,10 @@ main(int argc, char *argv[]) g_error("coult not bind GL context"); g_print("#\n"); - g_print("# Create texture with gst_vaapi_texture_new()\n"); + g_print("# Create texture with gst_vaapi_texture_glx_new()\n"); g_print("#\n"); { - texture = gst_vaapi_texture_new( + texture = gst_vaapi_texture_glx_new( display, GL_TEXTURE_2D, GL_RGBA, @@ -113,7 +113,7 @@ main(int argc, char *argv[]) } g_print("#\n"); - g_print("# Create texture with gst_vaapi_texture_new_with_texture()\n"); + g_print("# Create texture with gst_vaapi_texture_glx_new_wrapped()\n"); g_print("#\n"); { const GLenum target = GL_TEXTURE_2D; @@ -139,7 +139,7 @@ main(int argc, char *argv[]) ); glDisable(target); - texture = gst_vaapi_texture_new_with_texture( + texture = gst_vaapi_texture_glx_new_wrapped( display, texture_id, target, @@ -152,7 +152,7 @@ main(int argc, char *argv[]) g_error("invalid texture id"); if (gl_get_current_texture_2d() != texture_id) - g_error("gst_vaapi_texture_new_with_texture() altered texture bindings"); + g_error("gst_vaapi_texture_glx_new_wrapped() altered texture bindings"); textures[1] = texture; From 93418ed5ee1fef86ae5dc78322f8c12c936db85d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 4 Dec 2014 14:36:35 +0100 Subject: [PATCH 1837/3781] texture: add generic helper to create textures. Add new generic helper functions gst_vaapi_texture_new_wrapped() and gst_vaapi_texture_new() to create a texture without having the caller to uselessly check for the display type himself. i.e. internally, there is now a GstVaapiDisplayClass hook to create textures, and the actual backend implementation fills it in. This is a simplification in view to supporting EGL. --- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 11 ++++ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 7 ++ gst-libs/gst/vaapi/gstvaapitexture.c | 80 +++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapitexture.h | 8 +++ gst-libs/gst/vaapi/gstvaapitexture_glx.c | 11 ++-- gst-libs/gst/vaapi/gstvaapitexture_priv.h | 4 +- 6 files changed, 107 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index b1bdef966c..5342a6ed43 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -35,6 +35,7 @@ #include "gstvaapidisplay_x11_priv.h" #include "gstvaapidisplay_glx.h" #include "gstvaapidisplay_glx_priv.h" +#include "gstvaapitexture_glx.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -54,6 +55,15 @@ gst_vaapi_display_glx_get_display_info (GstVaapiDisplay * display, return TRUE; } +static GstVaapiTexture * +gst_vaapi_display_glx_create_texture (GstVaapiDisplay * display, GstVaapiID id, + guint target, guint format, guint width, guint height) +{ + return id != GST_VAAPI_ID_INVALID ? + gst_vaapi_texture_glx_new_wrapped (display, id, target, format) : + gst_vaapi_texture_glx_new (display, target, format, width, height); +} + static void gst_vaapi_display_glx_class_init (GstVaapiDisplayGLXClass * klass) { @@ -67,6 +77,7 @@ gst_vaapi_display_glx_class_init (GstVaapiDisplayGLXClass * klass) klass->parent_get_display = dpy_class->get_display; dpy_class->display_types = g_display_types; dpy_class->get_display = gst_vaapi_display_glx_get_display_info; + dpy_class->create_texture = gst_vaapi_display_glx_create_texture; } static inline const GstVaapiDisplayClass * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index b1e116051c..d1bc700a28 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -27,6 +27,7 @@ #include #include +#include #include "gstvaapiminiobject.h" G_BEGIN_DECLS @@ -66,6 +67,9 @@ typedef void (*GstVaapiDisplayGetSizeFunc) (GstVaapiDisplay * display, guint * pwidth, guint * pheight); typedef void (*GstVaapiDisplayGetSizeMFunc) (GstVaapiDisplay * display, guint * pwidth, guint * pheight); +typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) ( + GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, + guint width, guint height); /** * GST_VAAPI_DISPLAY_VADISPLAY: @@ -187,6 +191,7 @@ struct _GstVaapiDisplay * @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 + * @create_texture: (optional) virtual function to create a texture * * Base class for VA displays. */ @@ -210,6 +215,8 @@ struct _GstVaapiDisplayClass GstVaapiDisplayGetInfoFunc get_display; GstVaapiDisplayGetSizeFunc get_size; GstVaapiDisplayGetSizeMFunc get_size_mm; + + GstVaapiDisplayCreateTextureFunc create_texture; }; /* Initialization types */ diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 4d0df1c72f..33b3e3163e 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -40,11 +40,11 @@ #undef gst_vaapi_texture_replace static void -gst_vaapi_texture_init (GstVaapiTexture * texture, guint texture_id, +gst_vaapi_texture_init (GstVaapiTexture * texture, GstVaapiID id, guint target, guint format, guint width, guint height) { - GST_VAAPI_OBJECT_ID (texture) = texture_id; - texture->is_wrapped = texture_id != 0; + texture->is_wrapped = id != GST_VAAPI_ID_INVALID; + GST_VAAPI_OBJECT_ID (texture) = texture->is_wrapped ? id : 0; texture->gl_target = target; texture->gl_format = format; texture->width = width; @@ -58,8 +58,8 @@ gst_vaapi_texture_allocate (GstVaapiTexture * texture) } GstVaapiTexture * -gst_vaapi_texture_new (const GstVaapiTextureClass * klass, - GstVaapiDisplay * display, guint texture_id, guint target, guint format, +gst_vaapi_texture_new_internal (const GstVaapiTextureClass * klass, + GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height) { GstVaapiTexture *texture; @@ -73,7 +73,7 @@ gst_vaapi_texture_new (const GstVaapiTextureClass * klass, if (!texture) return NULL; - gst_vaapi_texture_init (texture, texture_id, target, format, width, height); + gst_vaapi_texture_init (texture, id, target, format, width, height); if (!gst_vaapi_texture_allocate (texture)) goto error; return texture; @@ -83,6 +83,74 @@ error: return NULL; } +/** + * gst_vaapi_texture_new: + * @display: a #GstVaapiDisplay + * @target: the target to which the texture is bound + * @format: the format of the pixel data + * @width: the requested width, in pixels + * @height: the requested height, in pixels + * + * Creates a texture with the specified dimensions, @target and + * @format. Note that only GL_TEXTURE_2D @target and GL_RGBA or + * GL_BGRA formats are supported at this time. + * + * The application shall maintain the live GL context itself. + * + * Return value: the newly created #GstVaapiTexture object + */ +GstVaapiTexture * +gst_vaapi_texture_new (GstVaapiDisplay * display, guint target, guint format, + guint width, guint height) +{ + GstVaapiDisplayClass *dpy_class; + + g_return_val_if_fail (display != NULL, NULL); + + dpy_class = GST_VAAPI_DISPLAY_GET_CLASS (display); + if (G_UNLIKELY (!dpy_class->create_texture)) + return NULL; + return dpy_class->create_texture (display, GST_VAAPI_ID_INVALID, target, + format, width, height); +} + +/** + * gst_vaapi_texture_new_wrapped: + * @display: a #GstVaapiDisplay + * @texture_id: the foreign GL texture name to use + * @target: the target to which the texture is bound + * @format: the format of the pixel data + * @width: the suggested width, in pixels + * @height: the suggested height, in pixels + * + * Creates a texture with the specified dimensions, @target and + * @format. Note that only GL_TEXTURE_2D @target and GL_RGBA or + * GL_BGRA formats are supported at this time. + * + * The size arguments @width and @height are only a suggestion. Should + * this be 0x0, then the actual size of the allocated texture storage + * would be either inherited from the original texture storage, if any + * and/or if possible, or derived from the VA surface in subsequent + * gst_vaapi_texture_put_surface() calls. + * + * The application shall maintain the live GL context itself. + * + * Return value: the newly created #GstVaapiTexture object + */ +GstVaapiTexture * +gst_vaapi_texture_new_wrapped (GstVaapiDisplay * display, guint id, + guint target, guint format, guint width, guint height) +{ + GstVaapiDisplayClass *dpy_class; + + g_return_val_if_fail (display != NULL, NULL); + + dpy_class = GST_VAAPI_DISPLAY_GET_CLASS (display); + if (G_UNLIKELY (!dpy_class->create_texture)) + return NULL; + return dpy_class->create_texture (display, id, target, format, width, height); +} + /** * gst_vaapi_texture_ref: * @texture: a #GstVaapiTexture diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 3856df8714..316d52d0b3 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -80,6 +80,14 @@ G_BEGIN_DECLS typedef struct _GstVaapiTexture GstVaapiTexture; +GstVaapiTexture * +gst_vaapi_texture_new (GstVaapiDisplay * display, guint target, guint format, + guint width, guint height); + +GstVaapiTexture * +gst_vaapi_texture_new_wrapped (GstVaapiDisplay * display, guint id, + guint target, guint format, guint width, guint height); + GstVaapiTexture * gst_vaapi_texture_ref (GstVaapiTexture * texture); diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.c b/gst-libs/gst/vaapi/gstvaapitexture_glx.c index acaa4f05d0..ade7bb308c 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_glx.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.c @@ -230,10 +230,9 @@ gst_vaapi_texture_glx_new (GstVaapiDisplay * display, guint target, { g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); - return - gst_vaapi_texture_new (GST_VAAPI_TEXTURE_CLASS - (gst_vaapi_texture_glx_class ()), display, GL_NONE, target, format, width, - height); + return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS + (gst_vaapi_texture_glx_class ()), display, GST_VAAPI_ID_INVALID, target, + format, width, height); } /** @@ -264,6 +263,7 @@ gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display, gboolean success; g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); + g_return_val_if_fail (texture_id != GL_NONE, NULL); g_return_val_if_fail (target != GL_NONE, NULL); g_return_val_if_fail (format != GL_NONE, NULL); @@ -286,8 +286,7 @@ gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display, g_return_val_if_fail (width > 0, NULL); g_return_val_if_fail (height > 0, NULL); - return - gst_vaapi_texture_new (GST_VAAPI_TEXTURE_CLASS + return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS (gst_vaapi_texture_glx_class ()), display, texture_id, target, format, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapitexture_priv.h b/gst-libs/gst/vaapi/gstvaapitexture_priv.h index 8cf57e6031..1f69d2207e 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_priv.h +++ b/gst-libs/gst/vaapi/gstvaapitexture_priv.h @@ -126,8 +126,8 @@ struct _GstVaapiTextureClass { }; GstVaapiTexture * -gst_vaapi_texture_new (const GstVaapiTextureClass * klass, - GstVaapiDisplay * display, guint texture_id, guint target, guint format, +gst_vaapi_texture_new_internal (const GstVaapiTextureClass * klass, + GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height); /* Inline reference counting for core libgstvaapi library */ From 2fb20e990695537d67d6f3bbc3f13e2eed50f10f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 1 Dec 2014 16:54:32 +0100 Subject: [PATCH 1838/3781] display: use a recursive mutex for the display cache. Use a recursive mutex for the display cache so that a 3rdparty display object could be initialized during the initialization of the parent display. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 11 ++--- gst-libs/gst/vaapi/gstvaapidisplaycache.c | 55 +++++++++++++++++++---- gst-libs/gst/vaapi/gstvaapidisplaycache.h | 8 ++++ 3 files changed, 60 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index a3b8a8ddd2..3f34a3ee88 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -862,10 +862,11 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) gst_vaapi_display_replace_internal (&priv->parent, NULL); - g_mutex_lock (&g_display_cache_lock); - if (priv->cache) + if (priv->cache) { + gst_vaapi_display_cache_lock (priv->cache); gst_vaapi_display_cache_remove (priv->cache, display); - g_mutex_unlock (&g_display_cache_lock); + gst_vaapi_display_cache_unlock (priv->cache); + } gst_vaapi_display_cache_replace (&priv->cache, NULL); free_display_cache (); } @@ -953,9 +954,9 @@ gst_vaapi_display_create (GstVaapiDisplay * display, gst_vaapi_display_cache_replace (&priv->cache, cache); gst_vaapi_display_cache_unref (cache); - g_mutex_lock (&g_display_cache_lock); + gst_vaapi_display_cache_lock (cache); success = gst_vaapi_display_create_unlocked (display, init_type, init_value); - g_mutex_unlock (&g_display_cache_lock); + gst_vaapi_display_cache_unlock (cache); return success; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index e8c08ac4e9..f5c6069a77 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -37,6 +37,7 @@ struct _CacheEntry struct _GstVaapiDisplayCache { GstVaapiMiniObject parent_instance; + GRecMutex mutex; GList *list; }; @@ -164,13 +165,13 @@ gst_vaapi_display_cache_finalize (GstVaapiDisplayCache * cache) { GList *l; - if (!cache->list) - return; - - for (l = cache->list; l != NULL; l = l->next) - cache_entry_free (l->data); - g_list_free (cache->list); - cache->list = NULL; + if (cache->list) { + for (l = cache->list; l != NULL; l = l->next) + cache_entry_free (l->data); + g_list_free (cache->list); + cache->list = NULL; + } + g_rec_mutex_clear (&cache->mutex); } static const GstVaapiMiniObjectClass * @@ -193,8 +194,44 @@ gst_vaapi_display_cache_class (void) GstVaapiDisplayCache * gst_vaapi_display_cache_new (void) { - return (GstVaapiDisplayCache *) - gst_vaapi_mini_object_new0 (gst_vaapi_display_cache_class ()); + GstVaapiDisplayCache *cache; + + cache = (GstVaapiDisplayCache *) + gst_vaapi_mini_object_new (gst_vaapi_display_cache_class ()); + if (!cache) + return NULL; + + g_rec_mutex_init (&cache->mutex); + cache->list = NULL; + return cache; +} + +/** + * gst_vaapi_display_cache_lock: + * @cache: the #GstVaapiDisplayCache + * + * Locks the display cache @cache. + */ +void +gst_vaapi_display_cache_lock (GstVaapiDisplayCache * cache) +{ + g_return_if_fail (cache != NULL); + + g_rec_mutex_lock (&cache->mutex); +} + +/** + * gst_vaapi_display_cache_unlock: + * @cache: the #GstVaapiDisplayCache + * + * Unlocks the display cache @cache. + */ +void +gst_vaapi_display_cache_unlock (GstVaapiDisplayCache * cache) +{ + g_return_if_fail (cache != NULL); + + g_rec_mutex_unlock (&cache->mutex); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h index f7274327f1..9d0abb7762 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.h +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.h @@ -42,6 +42,14 @@ gst_vaapi_display_cache_new (void); gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_cache_ptr), \ GST_VAAPI_MINI_OBJECT (new_cache)) +G_GNUC_INTERNAL +void +gst_vaapi_display_cache_lock (GstVaapiDisplayCache * cache); + +G_GNUC_INTERNAL +void +gst_vaapi_display_cache_unlock (GstVaapiDisplayCache * cache); + G_GNUC_INTERNAL gboolean gst_vaapi_display_cache_is_empty (GstVaapiDisplayCache * cache); From 1843774c0b6664152d6b6b168511bf1f28360c30 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 1 Dec 2014 17:08:29 +0100 Subject: [PATCH 1839/3781] display: record native display object. Record the underlying native display instance into the toplevel GstVaapiDisplay object. This is useful for fast lookups to the underlying native display, e.g. for creating an EGL display. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 12 ++++++++ gst-libs/gst/vaapi/gstvaapiobject_priv.h | 33 ++++----------------- gst-libs/gst/vaapi/gstvaapipixmap_x11.c | 11 ++++--- gst-libs/gst/vaapi/gstvaapitexture_glx.c | 6 ++-- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 16 ++++------ gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 6 ++-- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 22 +++++++------- 8 files changed, 47 insertions(+), 60 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 3f34a3ee88..232a34c836 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -906,6 +906,7 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, return FALSE; priv->display = info.va_display; priv->display_type = info.display_type; + priv->native_display = info.native_display; if (klass->get_size) klass->get_size (display, &priv->width, &priv->height); if (klass->get_size_mm) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index d1bc700a28..c4967b12dd 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -71,6 +71,17 @@ typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) ( GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height); +/** + * 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 @@ -150,6 +161,7 @@ struct _GstVaapiDisplayPrivate GstVaapiDisplayType display_type; gchar *display_name; VADisplay display; + gpointer native_display; guint width; guint height; guint width_mm; diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 9fedaacb04..7a18f3bd13 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -131,37 +131,14 @@ G_PASTE(t_n,_class) (void) \ GST_VAAPI_DISPLAY_VADISPLAY (GST_VAAPI_OBJECT_DISPLAY (object)) /** - * GST_VAAPI_OBJECT_XDISPLAY: + * GST_VAAPI_OBJECT_NATIVE_DISPLAY: * @object: a #GstVaapiObject * - * Macro that evaluates to the underlying X11 #Display of @display. - * This is an internal macro that does not do any run-time type check - * and requires #include "gstvaapidisplay_x11_priv.h". + * Macro that evaluates to the underlying native @display object. + * This is an internal macro that does not do any run-time type check. */ -#define GST_VAAPI_OBJECT_XDISPLAY(object) \ - GST_VAAPI_DISPLAY_XDISPLAY (GST_VAAPI_OBJECT_DISPLAY (object)) - -/** - * GST_VAAPI_OBJECT_XSCREEN: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the underlying X11 screen of @display. - * This is an internal macro that does not do any run-time type check - * and requires #include "gstvaapidisplay_x11_priv.h". - */ -#define GST_VAAPI_OBJECT_XSCREEN(object) \ - GST_VAAPI_DISPLAY_XSCREEN (GST_VAAPI_OBJECT_DISPLAY (object)) - -/** - * GST_VAAPI_OBJECT_WL_DISPLAY: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the underlying #wl_display of @display. - * This is an internal macro that does not do any run-time type check - * and requires #include "gstvaapidisplay_wayland_priv.h". - */ -#define GST_VAAPI_OBJECT_WL_DISPLAY(object) \ - GST_VAAPI_DISPLAY_WL_DISPLAY (GST_VAAPI_OBJECT_DISPLAY (object)) +#define GST_VAAPI_OBJECT_NATIVE_DISPLAY(object) \ + GST_VAAPI_DISPLAY_NATIVE (GST_VAAPI_OBJECT_DISPLAY (object)) /** * GST_VAAPI_OBJECT_LOCK_DISPLAY: diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c index 044feaa346..4a14f80c41 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c +++ b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c @@ -58,14 +58,14 @@ gst_vaapi_pixmap_x11_create_from_xid(GstVaapiPixmap *pixmap, Pixmap xid) return FALSE; GST_VAAPI_OBJECT_LOCK_DISPLAY(pixmap); - success = x11_get_geometry(GST_VAAPI_OBJECT_XDISPLAY(pixmap), xid, + success = x11_get_geometry(GST_VAAPI_OBJECT_NATIVE_DISPLAY(pixmap), xid, NULL, NULL, &pixmap->width, &pixmap->height, &depth); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(pixmap); if (!success) return FALSE; pixmap->format = gst_vaapi_display_x11_get_pixmap_format( - GST_VAAPI_DISPLAY_X11(GST_VAAPI_OBJECT_DISPLAY(pixmap)), depth); + GST_VAAPI_OBJECT_DISPLAY_X11(pixmap), depth); if (pixmap->format == GST_VIDEO_FORMAT_UNKNOWN) return FALSE; return TRUE; @@ -76,7 +76,7 @@ gst_vaapi_pixmap_x11_create(GstVaapiPixmap *pixmap) { GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(GST_VAAPI_OBJECT_DISPLAY(pixmap)); - Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(display); + Display * const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY(display); Window rootwin; Pixmap xid; guint depth; @@ -90,7 +90,7 @@ gst_vaapi_pixmap_x11_create(GstVaapiPixmap *pixmap) return FALSE; GST_VAAPI_OBJECT_LOCK_DISPLAY(pixmap); - rootwin = RootWindow(dpy, GST_VAAPI_DISPLAY_XSCREEN(display)); + rootwin = RootWindow(dpy, DefaultScreen(dpy)); xid = XCreatePixmap(dpy, rootwin, pixmap->width, pixmap->height, depth); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(pixmap); @@ -102,13 +102,12 @@ gst_vaapi_pixmap_x11_create(GstVaapiPixmap *pixmap) static void gst_vaapi_pixmap_x11_destroy(GstVaapiPixmap *pixmap) { - Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(pixmap); const Pixmap xid = GST_VAAPI_OBJECT_ID(pixmap); if (xid) { if (!pixmap->use_foreign_pixmap) { GST_VAAPI_OBJECT_LOCK_DISPLAY(pixmap); - XFreePixmap(dpy, xid); + XFreePixmap(GST_VAAPI_OBJECT_NATIVE_DISPLAY(pixmap), xid); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(pixmap); } GST_VAAPI_OBJECT_ID(pixmap) = None; diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.c b/gst-libs/gst/vaapi/gstvaapitexture_glx.c index ade7bb308c..6dbe52a403 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_glx.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.c @@ -129,18 +129,18 @@ static gboolean create_objects (GstVaapiTextureGLX * texture, guint texture_id) { GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (texture); GLContextState old_cs; gboolean success = FALSE; gl_get_current_context (&old_cs); - texture->gl_context = gl_create_context (GST_VAAPI_OBJECT_XDISPLAY (texture), - GST_VAAPI_OBJECT_XSCREEN (texture), &old_cs); + texture->gl_context = gl_create_context (dpy, DefaultScreen (dpy), &old_cs); if (!texture->gl_context || !gl_set_current_context (texture->gl_context, NULL)) return FALSE; - texture->pixo = gl_create_pixmap_object (GST_VAAPI_OBJECT_XDISPLAY (texture), + texture->pixo = gl_create_pixmap_object (dpy, base_texture->width, base_texture->height); if (!texture->pixo) { GST_ERROR ("failed to create GLX pixmap"); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 1107902437..8830801dc3 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -128,7 +128,7 @@ _gst_vaapi_window_glx_create_context (GstVaapiWindow * window, { GstVaapiWindowGLXPrivate *const priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); GLContextState parent_cs; parent_cs.display = dpy; @@ -136,8 +136,7 @@ _gst_vaapi_window_glx_create_context (GstVaapiWindow * window, parent_cs.context = foreign_context; GST_VAAPI_OBJECT_LOCK_DISPLAY (window); - priv->gl_context = gl_create_context (dpy, - GST_VAAPI_OBJECT_XSCREEN (window), &parent_cs); + priv->gl_context = gl_create_context (dpy, DefaultScreen (dpy), &parent_cs); if (!priv->gl_context) { GST_DEBUG ("could not create GLX context"); goto end; @@ -223,7 +222,7 @@ gst_vaapi_window_glx_destroy_colormap (GstVaapiWindow * window) { GstVaapiWindowGLXPrivate *const priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); if (priv->cmap) { if (!window->use_foreign_window) { @@ -240,8 +239,7 @@ gst_vaapi_window_glx_create_colormap (GstVaapiWindow * window) { GstVaapiWindowGLXPrivate *const priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); - int screen; + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); XWindowAttributes wattr; gboolean success = FALSE; @@ -252,9 +250,7 @@ gst_vaapi_window_glx_create_colormap (GstVaapiWindow * window) GST_VAAPI_OBJECT_LOCK_DISPLAY (window); x11_trap_errors (); /* XXX: add a GstVaapiDisplayX11:x11-screen property? */ - screen = GST_VAAPI_OBJECT_XSCREEN (window); - priv->cmap = XCreateColormap (dpy, - RootWindow (dpy, screen), + priv->cmap = XCreateColormap (dpy, RootWindow (dpy, DefaultScreen (dpy)), priv->gl_context->visual->visual, AllocNone); success = x11_untrap_errors () == 0; GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); @@ -285,7 +281,7 @@ gst_vaapi_window_glx_resize (GstVaapiWindow * window, guint width, guint height) GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); const GstVaapiWindowGLXClass *const klass = GST_VAAPI_WINDOW_GLX_GET_CLASS (window); - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); GLContextState old_cs; if (!klass->parent_resize (window, width, height)) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index e5c91392fe..28f7cce741 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -163,7 +163,8 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); if (priv->frame) { - struct wl_display *const wl_display = GST_VAAPI_OBJECT_WL_DISPLAY (window); + struct wl_display *const wl_display = + GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); do { if (wl_display_dispatch_queue (wl_display, priv->event_queue) < 0) @@ -409,7 +410,8 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); - struct wl_display *const wl_display = GST_VAAPI_OBJECT_WL_DISPLAY (window); + struct wl_display *const wl_display = + GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); struct wl_buffer *buffer; FrameState *frame; guint width, height, va_flags; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 776c7d8784..77ec6d5d63 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -52,7 +52,7 @@ send_wmspec_change_state (GstVaapiWindow * window, Atom state, gboolean add) { GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); XClientMessageEvent xclient; memset (&xclient, 0, sizeof (xclient)); @@ -77,7 +77,7 @@ send_wmspec_change_state (GstVaapiWindow * window, Atom state, gboolean add) static void wait_event (GstVaapiWindow * window, int type) { - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); const Window xid = GST_VAAPI_OBJECT_ID (window); XEvent e; Bool got_event; @@ -96,7 +96,7 @@ static gboolean timed_wait_event (GstVaapiWindow * window, int type, guint64 end_time, XEvent * e) { - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); const Window xid = GST_VAAPI_OBJECT_ID (window); XEvent tmp_event; GTimeVal now; @@ -130,7 +130,7 @@ gst_vaapi_window_x11_show (GstVaapiWindow * window) { GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); const Window xid = GST_VAAPI_OBJECT_ID (window); XWindowAttributes wattr; gboolean has_errors; @@ -172,7 +172,7 @@ gst_vaapi_window_x11_hide (GstVaapiWindow * window) { GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); const Window xid = GST_VAAPI_OBJECT_ID (window); XWindowAttributes wattr; gboolean has_errors; @@ -212,7 +212,7 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, { GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Window xid = GST_VAAPI_OBJECT_ID (window); Visual *vis = NULL; Colormap cmap = None; @@ -265,7 +265,7 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, static void gst_vaapi_window_x11_destroy (GstVaapiWindow * window) { - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); const Window xid = GST_VAAPI_OBJECT_ID (window); #ifdef HAVE_XRENDER @@ -293,7 +293,7 @@ static gboolean gst_vaapi_window_x11_get_geometry (GstVaapiWindow * window, gint * px, gint * py, guint * pwidth, guint * pheight) { - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); const Window xid = GST_VAAPI_OBJECT_ID (window); gboolean success; @@ -309,7 +309,7 @@ gst_vaapi_window_x11_set_fullscreen (GstVaapiWindow * window, { GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); const Window xid = GST_VAAPI_OBJECT_ID (window); XEvent e; guint width, height; @@ -379,7 +379,7 @@ gst_vaapi_window_x11_resize (GstVaapiWindow * window, guint width, guint height) GST_VAAPI_OBJECT_LOCK_DISPLAY (window); x11_trap_errors (); - XResizeWindow (GST_VAAPI_OBJECT_XDISPLAY (window), + XResizeWindow (GST_VAAPI_OBJECT_NATIVE_DISPLAY (window), GST_VAAPI_OBJECT_ID (window), width, height); has_errors = x11_untrap_errors () != 0; GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); @@ -427,7 +427,7 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window, #ifdef HAVE_XRENDER GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_XDISPLAY (window); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); const Window win = GST_VAAPI_OBJECT_ID (window); const Pixmap pix = GST_VAAPI_OBJECT_ID (pixmap); Picture picture; From 17f21ac4dbbb258fadee36ecadbeb08df74a025a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 2 Dec 2014 11:23:29 +0100 Subject: [PATCH 1840/3781] display: cosmetics (helper macros, new internal API names). Add more helper macros to the top-level GstVaapiDisplay interfaces. Rename a few others used internally for improved consistency. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.h | 36 +++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 4 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 56 +++++++------------- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 4 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 4 +- 6 files changed, 63 insertions(+), 43 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 232a34c836..5fa5ffd33f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1281,7 +1281,7 @@ gst_vaapi_display_flush (GstVaapiDisplay * display) } /** - * gst_vaapi_display_get_display: + * gst_vaapi_display_get_display_type: * @display: a #GstVaapiDisplay * * Returns the #GstVaapiDisplayType bound to @display. diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index e7e1935be5..288b516f5c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -36,6 +36,42 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY(obj) \ ((GstVaapiDisplay *)(obj)) +/** + * GST_VAAPI_DISPLAY_TYPE: + * @display: a #GstVaapiDisplay + * + * Returns the @display type + */ +#define GST_VAAPI_DISPLAY_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; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index be748b9f0d..b42fe402ce 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -240,7 +240,7 @@ gst_vaapi_display_drm_open_display (GstVaapiDisplay * display, { GstVaapiDisplayDRMPrivate *const priv = GST_VAAPI_DISPLAY_DRM_PRIVATE (display); - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); const GstVaapiDisplayInfo *info; if (!set_device_path (display, name)) @@ -289,7 +289,7 @@ gst_vaapi_display_drm_get_display_info (GstVaapiDisplay * display, { GstVaapiDisplayDRMPrivate *const priv = GST_VAAPI_DISPLAY_DRM_PRIVATE (display); - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); const GstVaapiDisplayInfo *cached_info; /* Return any cached info even if child has its own VA display */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index c4967b12dd..895f6dacf7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -33,19 +33,19 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_CAST(display) \ - ((GstVaapiDisplay *)(display)) + ((GstVaapiDisplay *) (display)) #define GST_VAAPI_DISPLAY_GET_PRIVATE(display) \ - (&GST_VAAPI_DISPLAY_CAST(display)->priv) + (&GST_VAAPI_DISPLAY_CAST (display)->priv) #define GST_VAAPI_DISPLAY_CLASS(klass) \ - ((GstVaapiDisplayClass *)(klass)) + ((GstVaapiDisplayClass *) (klass)) #define GST_VAAPI_IS_DISPLAY_CLASS(klass) \ - ((klass) != NULL) + ((klass) != NULL) #define GST_VAAPI_DISPLAY_GET_CLASS(obj) \ - GST_VAAPI_DISPLAY_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + GST_VAAPI_DISPLAY_CLASS (GST_VAAPI_MINI_OBJECT_GET_CLASS (obj)) typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; @@ -73,85 +73,69 @@ typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) ( /** * GST_VAAPI_DISPLAY_NATIVE: - * @display_: a #GstVaapiDisplay + * @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) +#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. + * 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_LOCK: - * @display: a #GstVaapiDisplay - * - * Locks @display - */ -#undef GST_VAAPI_DISPLAY_LOCK -#define GST_VAAPI_DISPLAY_LOCK(display) \ - gst_vaapi_display_lock(GST_VAAPI_DISPLAY_CAST(display)) - -/** - * GST_VAAPI_DISPLAY_UNLOCK: - * @display: a #GstVaapiDisplay - * - * Unlocks @display - */ -#undef GST_VAAPI_DISPLAY_UNLOCK -#define GST_VAAPI_DISPLAY_UNLOCK(display) \ - gst_vaapi_display_unlock(GST_VAAPI_DISPLAY_CAST(display)) + (GST_VAAPI_DISPLAY_GET_PRIVATE (display_)->display) /** * GST_VAAPI_DISPLAY_TYPE: * @display: a #GstVaapiDisplay * * Returns the @display type + * This is an internal macro that does not do any run-time type check. */ #undef GST_VAAPI_DISPLAY_TYPE #define GST_VAAPI_DISPLAY_TYPE(display) \ - GST_VAAPI_DISPLAY_GET_PRIVATE(display)->display_type + (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display_type) /** * GST_VAAPI_DISPLAY_TYPES: * @display: a #GstVaapiDisplay * * Returns compatible @display types as a set of flags + * This is an internal macro that does not do any run-time type check. */ #undef GST_VAAPI_DISPLAY_TYPES #define GST_VAAPI_DISPLAY_TYPES(display) \ - gst_vaapi_display_get_display_types(GST_VAAPI_DISPLAY_CAST(display)) + gst_vaapi_display_get_display_types (GST_VAAPI_DISPLAY_CAST (display)) /** * 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)) + gst_vaapi_display_has_video_processing (GST_VAAPI_DISPLAY_CAST (display)) /** * GST_VAAPI_DISPLAY_CACHE: * @display: a @GstVaapiDisplay * * Returns the #GstVaapiDisplayCache attached to the supplied @display object. + * This is an internal macro that does not do any run-time type check. */ -#undef GST_VAAPI_DISPLAY_GET_CACHE -#define GST_VAAPI_DISPLAY_GET_CACHE(display) \ - (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->cache) +#undef GST_VAAPI_DISPLAY_CACHE +#define GST_VAAPI_DISPLAY_CACHE(display) \ + (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->cache) struct _GstVaapiDisplayPrivate { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index d7c5c1ffb3..d859840a4a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -204,7 +204,7 @@ gst_vaapi_display_wayland_open_display (GstVaapiDisplay * display, { GstVaapiDisplayWaylandPrivate *const priv = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); const GstVaapiDisplayInfo *info; if (!set_display_name (display, name)) @@ -263,7 +263,7 @@ gst_vaapi_display_wayland_get_display_info (GstVaapiDisplay * display, { GstVaapiDisplayWaylandPrivate *const priv = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); const GstVaapiDisplayInfo *cached_info; /* Return any cached info even if child has its own VA display */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 9d4dfd0553..e9d193a76f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -197,7 +197,7 @@ gst_vaapi_display_x11_open_display (GstVaapiDisplay * base_display, { GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11_CAST (base_display); GstVaapiDisplayX11Private *const priv = &display->priv; - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); const GstVaapiDisplayInfo *info; if (!set_display_name (display, name)) @@ -275,7 +275,7 @@ gst_vaapi_display_x11_get_display_info (GstVaapiDisplay * display, { GstVaapiDisplayX11Private *const priv = GST_VAAPI_DISPLAY_X11_PRIVATE (display); - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display); + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); const GstVaapiDisplayInfo *cached_info; /* Return any cached info even if child has its own VA display */ From 7d5d3e8640efec613b7717600fe6cb2e4f82a615 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Dec 2014 18:02:55 +0100 Subject: [PATCH 1841/3781] display: refine the meaning of display type. Make gst_vaapi_display_get_display_type() return the actual VA display type. Conversely, add a gst_vaapi_display_get_class_type() function to return the type of the GstVaapiDisplay instance. The former is used to identify the display server onto which the application is running, and the latter to identify the original object class. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 23 ++++++++++- gst-libs/gst/vaapi/gstvaapidisplay.h | 18 ++++++-- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 6 +-- gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 17 +------- gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 6 +-- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 41 ++++++++----------- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 6 +-- .../gst/vaapi/gstvaapidisplay_wayland_priv.h | 4 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 9 ++-- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 7 ++-- gst/vaapi/gstvaapipluginutil.c | 3 -- gst/vaapi/gstvaapivideobuffer.c | 2 +- gst/vaapi/gstvaapivideometa_texture.c | 2 +- 14 files changed, 73 insertions(+), 73 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 5fa5ffd33f..aab09369c2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1280,11 +1280,30 @@ gst_vaapi_display_flush (GstVaapiDisplay * display) klass->flush (display); } +/** + * gst_vaapi_display_get_class_type: + * @display: a #GstVaapiDisplay + * + * Returns the #GstVaapiDisplayType of @display. This is the type of + * the object, thus the associated class, not the type of the VA + * display. + * + * Return value: the #GstVaapiDisplayType + */ +GstVaapiDisplayType +gst_vaapi_display_get_class_type (GstVaapiDisplay * display) +{ + g_return_val_if_fail (display != NULL, GST_VAAPI_DISPLAY_TYPE_ANY); + + return GST_VAAPI_DISPLAY_GET_CLASS_TYPE (display); +} + /** * gst_vaapi_display_get_display_type: * @display: a #GstVaapiDisplay * - * Returns the #GstVaapiDisplayType bound to @display. + * Returns the #GstVaapiDisplayType of the VA display bound to + * @display. This is not the type of the @display object. * * Return value: the #GstVaapiDisplayType */ @@ -1293,7 +1312,7 @@ gst_vaapi_display_get_display_type (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, GST_VAAPI_DISPLAY_TYPE_ANY); - return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display_type; + return GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 288b516f5c..a3d43969c9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -37,12 +37,21 @@ G_BEGIN_DECLS ((GstVaapiDisplay *)(obj)) /** - * GST_VAAPI_DISPLAY_TYPE: + * GST_VAAPI_DISPLAY_GET_CLASS_TYPE: * @display: a #GstVaapiDisplay * - * Returns the @display type + * Returns the #display class type */ -#define GST_VAAPI_DISPLAY_TYPE(display) \ +#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)) /** @@ -157,6 +166,9 @@ 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); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index b42fe402ce..d24bd67808 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -247,7 +247,7 @@ gst_vaapi_display_drm_open_display (GstVaapiDisplay * display, return FALSE; info = gst_vaapi_display_cache_lookup_by_name (cache, priv->device_path, - GST_VAAPI_DISPLAY_TYPES (display)); + g_display_types); if (info) { priv->drm_device = GPOINTER_TO_INT (info->native_display); priv->use_foreign_display = TRUE; @@ -294,7 +294,7 @@ gst_vaapi_display_drm_get_display_info (GstVaapiDisplay * display, /* Return any cached info even if child has its own VA display */ cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache, - GINT_TO_POINTER (priv->drm_device), GST_VAAPI_DISPLAY_TYPES (display)); + GINT_TO_POINTER (priv->drm_device), g_display_types); if (cached_info) { *info = *cached_info; return TRUE; @@ -331,7 +331,7 @@ gst_vaapi_display_drm_class_init (GstVaapiDisplayDRMClass * klass) gst_vaapi_display_class_init (&klass->parent_class); object_class->size = sizeof (GstVaapiDisplayDRM); - dpy_class->display_types = g_display_types; + dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_DRM; dpy_class->init = gst_vaapi_display_drm_init; dpy_class->bind_display = gst_vaapi_display_drm_bind_display; dpy_class->open_display = gst_vaapi_display_drm_open_display; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h index 1e65fbbaaf..0fa295a683 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h @@ -30,7 +30,7 @@ G_BEGIN_DECLS #define GST_VAAPI_IS_DISPLAY_DRM(display) \ ((display) != NULL && \ - GST_VAAPI_DISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_DRM) + GST_VAAPI_DISPLAY_VADISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_DRM) #define GST_VAAPI_DISPLAY_DRM_CAST(display) \ ((GstVaapiDisplayDRM *)(display)) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 5342a6ed43..9a3ab3eeed 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -42,19 +42,6 @@ static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_GLX; -static gboolean -gst_vaapi_display_glx_get_display_info (GstVaapiDisplay * display, - GstVaapiDisplayInfo * info) -{ - const GstVaapiDisplayGLXClass *const klass = - GST_VAAPI_DISPLAY_GLX_GET_CLASS (display); - - if (!klass->parent_get_display (display, info)) - return FALSE; - info->display_type = GST_VAAPI_DISPLAY_TYPE_GLX; - return TRUE; -} - static GstVaapiTexture * gst_vaapi_display_glx_create_texture (GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height) @@ -74,9 +61,7 @@ gst_vaapi_display_glx_class_init (GstVaapiDisplayGLXClass * klass) gst_vaapi_display_x11_class_init (&klass->parent_class); object_class->size = sizeof (GstVaapiDisplayGLX); - klass->parent_get_display = dpy_class->get_display; - dpy_class->display_types = g_display_types; - dpy_class->get_display = gst_vaapi_display_glx_get_display_info; + dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_GLX; dpy_class->create_texture = gst_vaapi_display_glx_create_texture; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index 12ee2f24e5..63f7175ce7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -30,8 +30,8 @@ G_BEGIN_DECLS #define GST_VAAPI_IS_DISPLAY_GLX(display) \ - ((display) != NULL && \ - GST_VAAPI_DISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_GLX) + ((display) != NULL && \ + GST_VAAPI_DISPLAY_GET_CLASS_TYPE (display) == GST_VAAPI_DISPLAY_TYPE_GLX) #define GST_VAAPI_DISPLAY_GLX_CAST(display) \ ((GstVaapiDisplayGLX *)(display)) @@ -64,8 +64,6 @@ struct _GstVaapiDisplayGLXClass { /*< private >*/ GstVaapiDisplayX11Class parent_class; - - GstVaapiDisplayGetInfoFunc parent_get_display; }; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 895f6dacf7..a19b7d197b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -71,6 +71,17 @@ typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) ( GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height); +/** + * 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 @@ -94,27 +105,16 @@ typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) ( (GST_VAAPI_DISPLAY_GET_PRIVATE (display_)->display) /** - * GST_VAAPI_DISPLAY_TYPE: + * GST_VAAPI_DISPLAY_VADISPLAY_TYPE: * @display: a #GstVaapiDisplay * - * Returns the @display type + * Returns the underlying VADisplay @display type * This is an internal macro that does not do any run-time type check. */ -#undef GST_VAAPI_DISPLAY_TYPE -#define GST_VAAPI_DISPLAY_TYPE(display) \ +#undef GST_VAAPI_DISPLAY_VADISPLAY_TYPE +#define GST_VAAPI_DISPLAY_VADISPLAY_TYPE(display) \ (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display_type) -/** - * GST_VAAPI_DISPLAY_TYPES: - * @display: a #GstVaapiDisplay - * - * Returns compatible @display types as a set of flags - * This is an internal macro that does not do any run-time type check. - */ -#undef GST_VAAPI_DISPLAY_TYPES -#define GST_VAAPI_DISPLAY_TYPES(display) \ - gst_vaapi_display_get_display_types (GST_VAAPI_DISPLAY_CAST (display)) - /** * GST_VAAPI_DISPLAY_HAS_VPP: * @display: a @GstVaapiDisplay @@ -197,7 +197,7 @@ struct _GstVaapiDisplayClass GstVaapiMiniObjectClass parent_class; /*< protected >*/ - guint display_types; + guint display_type; /*< public >*/ GstVaapiDisplayInitFunc init; @@ -230,15 +230,6 @@ GstVaapiDisplay * gst_vaapi_display_new (const GstVaapiDisplayClass * klass, GstVaapiDisplayInitType init_type, gpointer init_value); -static inline guint -gst_vaapi_display_get_display_types (GstVaapiDisplay * display) -{ - const GstVaapiDisplayClass *const dpy_class = - GST_VAAPI_DISPLAY_GET_CLASS (display); - - return dpy_class->display_types; -} - /* Inline reference counting for core libgstvaapi library */ #ifdef IN_LIBGSTVAAPI_CORE #define gst_vaapi_display_ref_internal(display) \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index d859840a4a..b0458a99bf 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -211,7 +211,7 @@ gst_vaapi_display_wayland_open_display (GstVaapiDisplay * display, return FALSE; info = gst_vaapi_display_cache_lookup_custom (cache, compare_display_name, - priv->display_name, GST_VAAPI_DISPLAY_TYPES (display)); + priv->display_name, g_display_types); if (info) { priv->wl_display = info->native_display; priv->use_foreign_display = TRUE; @@ -268,7 +268,7 @@ gst_vaapi_display_wayland_get_display_info (GstVaapiDisplay * display, /* Return any cached info even if child has its own VA display */ cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache, - priv->wl_display, GST_VAAPI_DISPLAY_TYPES (display)); + priv->wl_display, g_display_types); if (cached_info) { *info = *cached_info; return TRUE; @@ -339,7 +339,7 @@ gst_vaapi_display_wayland_class_init (GstVaapiDisplayWaylandClass * klass) gst_vaapi_display_class_init (&klass->parent_class); object_class->size = sizeof (GstVaapiDisplayWayland); - dpy_class->display_types = g_display_types; + dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; dpy_class->init = gst_vaapi_display_wayland_init; dpy_class->bind_display = gst_vaapi_display_wayland_bind_display; dpy_class->open_display = gst_vaapi_display_wayland_open_display; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index 0a98ec7452..0232d2477a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -30,8 +30,8 @@ G_BEGIN_DECLS #define GST_VAAPI_IS_DISPLAY_WAYLAND(display) \ - ((display) != NULL && \ - GST_VAAPI_DISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_WAYLAND) + ((display) != NULL && \ + GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display) == GST_VAAPI_DISPLAY_TYPE_WAYLAND) #define GST_VAAPI_DISPLAY_WAYLAND_CAST(display) \ ((GstVaapiDisplayWayland *)(display)) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index e9d193a76f..d17535f0ab 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -45,8 +45,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -static const guint g_display_types = - (1U << GST_VAAPI_DISPLAY_TYPE_X11) | (1U << GST_VAAPI_DISPLAY_TYPE_GLX); +static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_X11; static gboolean parse_display_name (const gchar * name, guint * len_ptr, guint * id_ptr, @@ -204,7 +203,7 @@ gst_vaapi_display_x11_open_display (GstVaapiDisplay * base_display, return FALSE; info = gst_vaapi_display_cache_lookup_custom (cache, compare_display_name, - priv->display_name, GST_VAAPI_DISPLAY_TYPES (display)); + priv->display_name, g_display_types); if (info) { priv->x11_display = info->native_display; priv->use_foreign_display = TRUE; @@ -280,7 +279,7 @@ gst_vaapi_display_x11_get_display_info (GstVaapiDisplay * display, /* Return any cached info even if child has its own VA display */ cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache, - priv->x11_display, GST_VAAPI_DISPLAY_TYPES (display)); + priv->x11_display, g_display_types); if (cached_info) { *info = *cached_info; return TRUE; @@ -379,7 +378,7 @@ gst_vaapi_display_x11_class_init (GstVaapiDisplayX11Class * klass) gst_vaapi_display_class_init (&klass->parent_class); object_class->size = sizeof (GstVaapiDisplayX11); - dpy_class->display_types = g_display_types; + 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; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index ca333df754..3225328d3b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -31,10 +31,9 @@ G_BEGIN_DECLS -#define GST_VAAPI_IS_DISPLAY_X11(display) \ - ((display) != NULL && \ - (GST_VAAPI_DISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_X11 || \ - GST_VAAPI_DISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_GLX)) +#define GST_VAAPI_IS_DISPLAY_X11(display) \ + ((display) != NULL && \ + GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display) == GST_VAAPI_DISPLAY_TYPE_X11) #define GST_VAAPI_DISPLAY_X11_CAST(display) \ ((GstVaapiDisplayX11 *)(display)) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 21f7e03dd7..d3b2058570 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -274,9 +274,6 @@ gst_vaapi_reply_to_query (GstQuery * query, GstVaapiDisplay * display) } #endif #if USE_X11 -#if USE_GLX - case GST_VAAPI_DISPLAY_TYPE_GLX: -#endif case GST_VAAPI_DISPLAY_TYPE_X11:{ GstVaapiDisplayX11 *const xvadpy = GST_VAAPI_DISPLAY_X11 (display); Display *const x11dpy = gst_vaapi_display_x11_get_display (xvadpy); diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index a36846db93..1a5bff5fb7 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -267,7 +267,7 @@ get_surface_converter (GstVaapiDisplay * display) { GFunc func; - switch (gst_vaapi_display_get_display_type (display)) { + switch (gst_vaapi_display_get_class_type (display)) { #if USE_X11 && !GST_CHECK_VERSION(1,1,0) case GST_VAAPI_DISPLAY_TYPE_X11: func = (GFunc) gst_vaapi_video_converter_x11_new; diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 6b08f94ebf..2e3a84942e 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -90,7 +90,7 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface); - if (gst_vaapi_display_get_display_type (dpy) != GST_VAAPI_DISPLAY_TYPE_GLX) + if (gst_vaapi_display_get_class_type (dpy) != GST_VAAPI_DISPLAY_TYPE_GLX) return FALSE; if (!meta_texture->texture || From 807c4e8248025535188898d702e9da45eb8afea7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 3 Dec 2014 11:39:24 +0100 Subject: [PATCH 1842/3781] display: add utility function to check for OpenGL rendering. Add gst_vaapi_display_has_opengl() helper function to help determining whether the display can support OpenGL context to be bound to it, i.e. if the class is of type GST_VAAPI_DISPLAY_TYPE_GLX. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 23 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 3 +++ gst-libs/gst/vaapi/gstvaapitexture.c | 2 ++ gst/vaapi/gstvaapivideometa_texture.c | 2 +- 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index aab09369c2..c89a679a7e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -2115,3 +2115,26 @@ gst_vaapi_display_get_vendor_string (GstVaapiDisplay * display) return NULL; return display->priv.vendor_string; } + +/** + * gst_vaapi_display_has_opengl: + * @display: a #GstVaapiDisplay + * + * Returns wether the @display that was created does support OpenGL + * context to be attached. + * + * This function is thread safe. + * + * Return value: %TRUE if the @display supports OpenGL context, %FALSE + * otherwise + */ +gboolean +gst_vaapi_display_has_opengl (GstVaapiDisplay * display) +{ + GstVaapiDisplayClass *klass; + + g_return_val_if_fail (display != NULL, NULL); + + klass = GST_VAAPI_DISPLAY_GET_CLASS (display); + return (klass->display_type == GST_VAAPI_DISPLAY_TYPE_GLX); +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index a3d43969c9..998e96ef43 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -252,6 +252,9 @@ gst_vaapi_display_set_rotation (GstVaapiDisplay * display, const gchar * gst_vaapi_display_get_vendor_string (GstVaapiDisplay * display); +gboolean +gst_vaapi_display_has_opengl (GstVaapiDisplay * display); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 33b3e3163e..380c45ef20 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -106,6 +106,7 @@ gst_vaapi_texture_new (GstVaapiDisplay * display, guint target, guint format, GstVaapiDisplayClass *dpy_class; g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (gst_vaapi_display_has_opengl (display), NULL); dpy_class = GST_VAAPI_DISPLAY_GET_CLASS (display); if (G_UNLIKELY (!dpy_class->create_texture)) @@ -144,6 +145,7 @@ gst_vaapi_texture_new_wrapped (GstVaapiDisplay * display, guint id, GstVaapiDisplayClass *dpy_class; g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (gst_vaapi_display_has_opengl (display), NULL); dpy_class = GST_VAAPI_DISPLAY_GET_CLASS (display); if (G_UNLIKELY (!dpy_class->create_texture)) diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 2e3a84942e..1f605378fb 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -90,7 +90,7 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface); - if (gst_vaapi_display_get_class_type (dpy) != GST_VAAPI_DISPLAY_TYPE_GLX) + if (!gst_vaapi_display_has_opengl (dpy)) return FALSE; if (!meta_texture->texture || From ff0a237458cb92a4ace65ba4662a994ba0902fc1 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Dec 2014 18:12:24 +0100 Subject: [PATCH 1843/3781] window: add generic helper to create windows. Add a new generic helper function gst_vaapi_window_new() to create a window without having the caller to check for the display type himself. i.e. internally, there is now a GstVaapiDisplayClass hook to create windows, and the actual backend implementation fills it in. Add new generic helper functions gst_vaapi_texture_new_wrapped() This is a simplification in view to supporting EGL. --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 10 ++++ gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 11 +++++ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 5 ++ gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 11 +++++ gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 11 +++++ gst-libs/gst/vaapi/gstvaapiwindow.c | 52 ++++++++++++-------- gst-libs/gst/vaapi/gstvaapiwindow.h | 3 ++ gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 5 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 9 ++-- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 8 +-- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 6 +-- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 10 ++-- 12 files changed, 100 insertions(+), 41 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index d24bd67808..43516e40f7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -36,6 +36,7 @@ #include "gstvaapidisplay_priv.h" #include "gstvaapidisplay_drm.h" #include "gstvaapidisplay_drm_priv.h" +#include "gstvaapiwindow_drm.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -312,6 +313,14 @@ gst_vaapi_display_drm_get_display_info (GstVaapiDisplay * display, 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 (GstVaapiDisplay * display) { @@ -337,6 +346,7 @@ gst_vaapi_display_drm_class_init (GstVaapiDisplayDRMClass * klass) 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; } static inline const GstVaapiDisplayClass * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 9a3ab3eeed..2738454b07 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -35,6 +35,7 @@ #include "gstvaapidisplay_x11_priv.h" #include "gstvaapidisplay_glx.h" #include "gstvaapidisplay_glx_priv.h" +#include "gstvaapiwindow_glx.h" #include "gstvaapitexture_glx.h" #define DEBUG 1 @@ -42,6 +43,15 @@ static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_GLX; +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 GstVaapiTexture * gst_vaapi_display_glx_create_texture (GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height) @@ -62,6 +72,7 @@ gst_vaapi_display_glx_class_init (GstVaapiDisplayGLXClass * klass) object_class->size = sizeof (GstVaapiDisplayGLX); 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; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index a19b7d197b..c9b0e00449 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -27,6 +27,7 @@ #include #include +#include #include #include "gstvaapiminiobject.h" @@ -67,6 +68,8 @@ typedef void (*GstVaapiDisplayGetSizeFunc) (GstVaapiDisplay * display, guint * pwidth, guint * pheight); typedef void (*GstVaapiDisplayGetSizeMFunc) (GstVaapiDisplay * display, guint * pwidth, guint * pheight); +typedef GstVaapiWindow *(*GstVaapiDisplayCreateWindowFunc) ( + GstVaapiDisplay * display, GstVaapiID id, guint width, guint height); typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) ( GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height); @@ -187,6 +190,7 @@ struct _GstVaapiDisplay * @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 + * @create_window: (optional) virtual function to create a window * @create_texture: (optional) virtual function to create a texture * * Base class for VA displays. @@ -212,6 +216,7 @@ struct _GstVaapiDisplayClass GstVaapiDisplayGetSizeFunc get_size; GstVaapiDisplayGetSizeMFunc get_size_mm; + GstVaapiDisplayCreateWindowFunc create_window; GstVaapiDisplayCreateTextureFunc create_texture; }; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index b0458a99bf..090965eae2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -31,6 +31,7 @@ #include "gstvaapidisplay_priv.h" #include "gstvaapidisplay_wayland.h" #include "gstvaapidisplay_wayland_priv.h" +#include "gstvaapiwindow_wayland.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -320,6 +321,15 @@ gst_vaapi_display_wayland_get_size_mm (GstVaapiDisplay * display, *pheight = priv->phys_height; } +static GstVaapiWindow * +gst_vaapi_display_wayland_create_window (GstVaapiDisplay * display, + GstVaapiID id, guint width, guint height) +{ + return id != GST_VAAPI_ID_INVALID ? + NULL : + gst_vaapi_window_wayland_new (display, width, height); +} + static void gst_vaapi_display_wayland_init (GstVaapiDisplay * display) { @@ -347,6 +357,7 @@ gst_vaapi_display_wayland_class_init (GstVaapiDisplayWaylandClass * klass) 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; } static inline const GstVaapiDisplayClass * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index d17535f0ab..658b597577 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -33,6 +33,7 @@ #include "gstvaapidisplay_priv.h" #include "gstvaapidisplay_x11.h" #include "gstvaapidisplay_x11_priv.h" +#include "gstvaapiwindow_x11.h" #ifdef HAVE_XRANDR # include @@ -368,6 +369,15 @@ gst_vaapi_display_x11_get_size_mm (GstVaapiDisplay * display, *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) { @@ -387,6 +397,7 @@ gst_vaapi_display_x11_class_init (GstVaapiDisplayX11Class * klass) 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 inline const GstVaapiDisplayClass * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 7ebbdac9fe..c8956826a5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -30,6 +30,7 @@ #include "sysdeps.h" #include "gstvaapiwindow.h" #include "gstvaapiwindow_priv.h" +#include "gstvaapidisplay_priv.h" #include "gstvaapisurface_priv.h" #define DEBUG 1 @@ -74,20 +75,26 @@ gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height) } GstVaapiWindow * -gst_vaapi_window_new (const GstVaapiWindowClass * window_class, - GstVaapiDisplay * display, guint width, guint height) +gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, + GstVaapiDisplay * display, GstVaapiID id, guint width, guint height) { GstVaapiWindow *window; - g_return_val_if_fail (width > 0, NULL); - g_return_val_if_fail (height > 0, NULL); + if (id != GST_VAAPI_ID_INVALID) { + g_return_val_if_fail (width == 0, NULL); + g_return_val_if_fail (height == 0, NULL); + } else { + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + } window = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (window_class), display); if (!window) return NULL; - GST_VAAPI_OBJECT_ID (window) = 0; + window->use_foreign_window = id != GST_VAAPI_ID_INVALID; + GST_VAAPI_OBJECT_ID (window) = window->use_foreign_window ? id : 0; if (!gst_vaapi_window_create (window, width, height)) goto error; return window; @@ -97,26 +104,29 @@ error: return NULL; } +/** + * gst_vaapi_window_new: + * @display: a #GstVaapiDisplay + * @width: the requested window width, in pixels + * @height: the requested windo height, in pixels + * + * Creates a window with the specified @width and @height. The window + * will be attached to the @display and remains invisible to the user + * until gst_vaapi_window_show() is called. + * + * Return value: the newly allocated #GstVaapiWindow object + */ GstVaapiWindow * -gst_vaapi_window_new_from_native (const GstVaapiWindowClass * window_class, - GstVaapiDisplay * display, gpointer native_window) +gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height) { - GstVaapiWindow *window; + GstVaapiDisplayClass *dpy_class; - window = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (window_class), - display); - if (!window) + g_return_val_if_fail (display != NULL, NULL); + + dpy_class = GST_VAAPI_DISPLAY_GET_CLASS (display); + if (G_UNLIKELY (!dpy_class->create_window)) return NULL; - - GST_VAAPI_OBJECT_ID (window) = GPOINTER_TO_SIZE (native_window); - window->use_foreign_window = TRUE; - if (!gst_vaapi_window_create (window, 0, 0)) - goto error; - return window; - -error: - gst_vaapi_window_unref_internal (window); - return NULL; + return dpy_class->create_window (display, GST_VAAPI_ID_INVALID, width, height); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 84a6ef8db2..64ee3e50e4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -40,6 +40,9 @@ G_BEGIN_DECLS typedef struct _GstVaapiWindow GstVaapiWindow; typedef struct _GstVaapiWindowClass GstVaapiWindowClass; +GstVaapiWindow * +gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height); + GstVaapiWindow * gst_vaapi_window_ref (GstVaapiWindow * window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c index 510ae3b605..ae49a07cb0 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -137,6 +137,7 @@ gst_vaapi_window_drm_new (GstVaapiDisplay * display, guint width, guint height) g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_DRM (display), NULL); return - gst_vaapi_window_new (GST_VAAPI_WINDOW_CLASS (gst_vaapi_window_drm_class - ()), display, width, height); + gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS + (gst_vaapi_window_drm_class ()), display, GST_VAAPI_ID_INVALID, width, + height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 8830801dc3..722d522853 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -347,8 +347,9 @@ gst_vaapi_window_glx_new (GstVaapiDisplay * display, guint width, guint height) g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); window = - gst_vaapi_window_new (GST_VAAPI_WINDOW_CLASS (gst_vaapi_window_glx_class - ()), display, width, height); + gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS + (gst_vaapi_window_glx_class ()), display, GST_VAAPI_ID_INVALID, width, + height); if (!window) return NULL; @@ -384,8 +385,8 @@ gst_vaapi_window_glx_new_with_xid (GstVaapiDisplay * display, Window xid) g_return_val_if_fail (xid != None, NULL); window = - gst_vaapi_window_new_from_native (GST_VAAPI_WINDOW_CLASS - (gst_vaapi_window_glx_class ()), display, GINT_TO_POINTER (xid)); + gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS + (gst_vaapi_window_glx_class ()), display, xid, 0, 0); if (!window) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index fdc0937003..aac0361db5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -102,12 +102,8 @@ struct _GstVaapiWindowClass }; GstVaapiWindow * -gst_vaapi_window_new (const GstVaapiWindowClass * window_class, - GstVaapiDisplay * display, guint width, guint height); - -GstVaapiWindow * -gst_vaapi_window_new_from_native (const GstVaapiWindowClass * - window_class, GstVaapiDisplay * display, gpointer native_window); +gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, + GstVaapiDisplay * display, guintptr handle, guint width, guint height); /* Inline reference counting for core libgstvaapi library */ #ifdef IN_LIBGSTVAAPI_CORE diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 28f7cce741..2c40e48895 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -545,7 +545,7 @@ gst_vaapi_window_wayland_new (GstVaapiDisplay * display, g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_WAYLAND (display), NULL); - return - gst_vaapi_window_new (GST_VAAPI_WINDOW_CLASS - (gst_vaapi_window_wayland_class ()), display, width, height); + return gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS + (gst_vaapi_window_wayland_class ()), display, GST_VAAPI_ID_INVALID, width, + height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 77ec6d5d63..18b361eff7 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -565,8 +565,9 @@ gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height) g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); return - gst_vaapi_window_new (GST_VAAPI_WINDOW_CLASS (gst_vaapi_window_x11_class - ()), display, width, height); + gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS + (gst_vaapi_window_x11_class ()), display, GST_VAAPI_ID_INVALID, width, + height); } /** @@ -589,9 +590,8 @@ gst_vaapi_window_x11_new_with_xid (GstVaapiDisplay * display, Window xid) g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); g_return_val_if_fail (xid != None, NULL); - return - gst_vaapi_window_new_from_native (GST_VAAPI_WINDOW_CLASS - (gst_vaapi_window_x11_class ()), display, GINT_TO_POINTER (xid)); + return gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS + (gst_vaapi_window_x11_class ()), display, xid, 0, 0); } /** From e9f437167fafeae176f64afd67415da538553c55 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Dec 2014 19:36:12 +0100 Subject: [PATCH 1844/3781] window: add toplevel API to determine a visual id. Add GstVaapiWindowClass::get_visual_id() function hook to help find the best suitable visual id for the supplied window. While doing so, also simplify the process by which an X11 window is created with a desired Visual, i.e. now use a visual id instead of a Visual object. --- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 43 +++++++++++++++----- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 3 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 10 ++--- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 4 ++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 13 ++++-- gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 3 -- 6 files changed, 51 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 0b22aaef43..1f9fd0ba73 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -68,18 +68,18 @@ static const int x11_event_mask = * @dpy: an X11 #Display * @w: the requested width, in pixels * @h: the requested height, in pixels - * @vis: the request visual - * @cmap: the request colormap + * @vid: the requested visual id + * @cmap: the requested colormap * - * Creates a border-less window with the specified dimensions. If @vis - * is %NULL, the default visual for @display will be used. If @cmap is + * Creates a border-less window with the specified dimensions. If @vid + * is zero, the default visual for @display will be used. If @cmap is * %None, no specific colormap will be bound to the window. Also note * the default background color is black. * * Return value: the newly created X #Window. */ Window -x11_create_window (Display * dpy, guint w, guint h, Visual * vis, Colormap cmap) +x11_create_window (Display * dpy, guint w, guint h, guint vid, Colormap cmap) { Window rootwin, win; int screen, depth; @@ -87,14 +87,13 @@ x11_create_window (Display * dpy, guint w, guint h, Visual * vis, Colormap cmap) unsigned long xswa_mask; XWindowAttributes wattr; unsigned long black_pixel; + XVisualInfo visualInfo, *vi; + int num_visuals; screen = DefaultScreen (dpy); rootwin = RootWindow (dpy, screen); black_pixel = BlackPixel (dpy, screen); - if (!vis) - vis = DefaultVisual (dpy, screen); - XGetWindowAttributes (dpy, rootwin, &wattr); depth = wattr.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) @@ -109,13 +108,35 @@ x11_create_window (Display * dpy, guint w, guint h, Visual * vis, Colormap cmap) xswa.colormap = cmap; } - win = XCreateWindow (dpy, rootwin, 0, 0, w, h, 0, depth, InputOutput, vis, - xswa_mask, &xswa); + if (vid) { + visualInfo.visualid = vid; + vi = XGetVisualInfo (dpy, VisualIDMask, &visualInfo, &num_visuals); + if (!vi || num_visuals < 1) + goto error_create_visual; + } else { + vi = &visualInfo; + XMatchVisualInfo (dpy, screen, depth, TrueColor, vi); + } + + win = XCreateWindow (dpy, rootwin, 0, 0, w, h, 0, depth, InputOutput, + vi->visual, xswa_mask, &xswa); + if (vi != &visualInfo) + XFree (vi); if (!win) - return None; + goto error_create_window; XSelectInput (dpy, win, x11_event_mask); return win; + + /* ERRORS */ +error_create_visual: + GST_ERROR ("failed to create X visual (id:%zu)", (gsize) visualInfo.visualid); + if (vi) + XFree (vi); + return None; +error_create_window: + GST_ERROR ("failed to create X window of size %ux%u", w, h); + return None; } gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index ebc7380370..500a47fc39 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -40,8 +40,7 @@ x11_untrap_errors (void); G_GNUC_INTERNAL Window -x11_create_window (Display * dpy, guint w, guint h, Visual * vis, - Colormap cmap); +x11_create_window (Display * dpy, guint w, guint h, guint vid, Colormap cmap); G_GNUC_INTERNAL gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 722d522853..4005484bdc 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -206,15 +206,15 @@ gst_vaapi_window_glx_ensure_context (GstVaapiWindow * window, return TRUE; } -static Visual * -gst_vaapi_window_glx_get_visual (GstVaapiWindow * window) +static guintptr +gst_vaapi_window_glx_get_visual_id (GstVaapiWindow * window) { GstVaapiWindowGLXPrivate *const priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); if (!_gst_vaapi_window_glx_ensure_context (window, NULL)) - return NULL; - return priv->gl_context->visual->visual; + return 0; + return priv->gl_context->visual->visualid; } static void @@ -320,7 +320,7 @@ gst_vaapi_window_glx_class_init (GstVaapiWindowGLXClass * klass) klass->parent_resize = window_class->resize; klass->parent_finalize = GST_VAAPI_OBJECT_CLASS (klass)->finalize; window_class->resize = gst_vaapi_window_glx_resize; - xwindow_class->get_visual = gst_vaapi_window_glx_get_visual; + window_class->get_visual_id = gst_vaapi_window_glx_get_visual_id; xwindow_class->get_colormap = gst_vaapi_window_glx_get_colormap; } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index aac0361db5..36291c44d0 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -52,6 +52,7 @@ typedef gboolean (*GstVaapiWindowRenderFunc) (GstVaapiWindow * window, typedef gboolean (*GstVaapiWindowRenderPixmapFunc) (GstVaapiWindow * window, GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect); +typedef guintptr (*GstVaapiWindowGetVisualIdFunc) (GstVaapiWindow * window); /** * GstVaapiWindow: @@ -82,6 +83,8 @@ struct _GstVaapiWindow * @set_fullscreen: virtual function to change window fullscreen state * @resize: virtual function to resize a window * @render: virtual function to render a #GstVaapiSurface into a window + * @get_visual_id: virtual function to get the desired visual id used to + * create the window * * Base class for system-dependent windows. */ @@ -99,6 +102,7 @@ struct _GstVaapiWindowClass GstVaapiWindowResizeFunc resize; GstVaapiWindowRenderFunc render; GstVaapiWindowRenderPixmapFunc render_pixmap; + GstVaapiWindowGetVisualIdFunc get_visual_id; }; GstVaapiWindow * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 18b361eff7..49fc97ad88 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -214,8 +214,9 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Window xid = GST_VAAPI_OBJECT_ID (window); - Visual *vis = NULL; + guint vid = 0; Colormap cmap = None; + const GstVaapiWindowClass *window_class; const GstVaapiWindowX11Class *klass; XWindowAttributes wattr; Atom atoms[2]; @@ -238,10 +239,14 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, return ok; } + window_class = GST_VAAPI_WINDOW_GET_CLASS (window); + if (window_class) { + if (window_class->get_visual_id) + vid = window_class->get_visual_id (window); + } + klass = GST_VAAPI_WINDOW_X11_GET_CLASS (window); if (klass) { - if (klass->get_visual) - vis = klass->get_visual (window); if (klass->get_colormap) cmap = klass->get_colormap (window); } @@ -252,7 +257,7 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, priv->atom_NET_WM_STATE = atoms[0]; priv->atom_NET_WM_STATE_FULLSCREEN = atoms[1]; - xid = x11_create_window (dpy, *width, *height, vis, cmap); + xid = x11_create_window (dpy, *width, *height, vid, cmap); if (xid) XRaiseWindow (dpy, xid); GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index c14191f99a..c9d61cbf37 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -72,8 +72,6 @@ struct _GstVaapiWindowX11 /** * GstVaapiWindowX11Class: - * @get_visual: virtual function to get the desired visual used to - * create the window * @get_colormap: virtual function to get the desired colormap used to * create the window * @@ -84,7 +82,6 @@ struct _GstVaapiWindowX11Class /*< private >*/ GstVaapiWindowClass parent_class; - Visual *(*get_visual) (GstVaapiWindow * window); Colormap (*get_colormap) (GstVaapiWindow * window); }; From babae324322226cceb99a4fe38caf4233f17eb6e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Dec 2014 19:58:10 +0100 Subject: [PATCH 1845/3781] window: add toplevel API to determine the colormap. Add GstVaapiWindowClass::get_colormap() hook to help determine the currently active colormap bound to the supplied window, or actually create it if it does not already exist yet. --- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 6 +++--- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 4 ++++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 9 ++------- gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 4 ---- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 4005484bdc..13eac3f450 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -268,10 +268,10 @@ gst_vaapi_window_glx_create_colormap (GstVaapiWindow * window) return priv->cmap; } -static Colormap +static guintptr gst_vaapi_window_glx_get_colormap (GstVaapiWindow * window) { - return gst_vaapi_window_glx_create_colormap (window); + return GPOINTER_TO_SIZE (gst_vaapi_window_glx_create_colormap (window)); } static gboolean @@ -321,7 +321,7 @@ gst_vaapi_window_glx_class_init (GstVaapiWindowGLXClass * klass) klass->parent_finalize = GST_VAAPI_OBJECT_CLASS (klass)->finalize; window_class->resize = gst_vaapi_window_glx_resize; window_class->get_visual_id = gst_vaapi_window_glx_get_visual_id; - xwindow_class->get_colormap = gst_vaapi_window_glx_get_colormap; + window_class->get_colormap = gst_vaapi_window_glx_get_colormap; } GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowGLX, diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index 36291c44d0..af1581be83 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -53,6 +53,7 @@ typedef gboolean (*GstVaapiWindowRenderPixmapFunc) (GstVaapiWindow * window, GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect); typedef guintptr (*GstVaapiWindowGetVisualIdFunc) (GstVaapiWindow * window); +typedef guintptr (*GstVaapiWindowGetColormapFunc) (GstVaapiWindow * window); /** * GstVaapiWindow: @@ -85,6 +86,8 @@ struct _GstVaapiWindow * @render: virtual function to render a #GstVaapiSurface into a window * @get_visual_id: virtual function to get the desired visual id used to * create the window + * @get_colormap: virtual function to get the desired colormap used to + * create the window, or the currently allocated one * * Base class for system-dependent windows. */ @@ -103,6 +106,7 @@ struct _GstVaapiWindowClass GstVaapiWindowRenderFunc render; GstVaapiWindowRenderPixmapFunc render_pixmap; GstVaapiWindowGetVisualIdFunc get_visual_id; + GstVaapiWindowGetColormapFunc get_colormap; }; GstVaapiWindow * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 49fc97ad88..67b358006a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -217,7 +217,6 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, guint vid = 0; Colormap cmap = None; const GstVaapiWindowClass *window_class; - const GstVaapiWindowX11Class *klass; XWindowAttributes wattr; Atom atoms[2]; gboolean ok; @@ -243,12 +242,8 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, if (window_class) { if (window_class->get_visual_id) vid = window_class->get_visual_id (window); - } - - klass = GST_VAAPI_WINDOW_X11_GET_CLASS (window); - if (klass) { - if (klass->get_colormap) - cmap = klass->get_colormap (window); + if (window_class->get_colormap) + cmap = window_class->get_colormap (window); } GST_VAAPI_OBJECT_LOCK_DISPLAY (window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index c9d61cbf37..f57916c996 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -72,8 +72,6 @@ struct _GstVaapiWindowX11 /** * GstVaapiWindowX11Class: - * @get_colormap: virtual function to get the desired colormap used to - * create the window * * An X11 #Window wrapper class. */ @@ -81,8 +79,6 @@ struct _GstVaapiWindowX11Class { /*< private >*/ GstVaapiWindowClass parent_class; - - Colormap (*get_colormap) (GstVaapiWindow * window); }; void From f5af9d150e62a15cd40c86f7a16d5aeb059f3617 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Dec 2014 20:13:21 +0100 Subject: [PATCH 1846/3781] window: add toplevel display indirection for visualid and colormap. Add GstVaapiDisplay::get_{visual_id,colormap}() helpers to help determine the best suitable window visual id and colormap. This is an indirection in view to supporting EGL and custom/generic replacements. --- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 10 +++++++++- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index c9b0e00449..fd50fe79e2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -74,6 +74,11 @@ typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) ( GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height); +typedef guintptr (*GstVaapiDisplayGetVisualIdFunc) (GstVaapiDisplay * display, + GstVaapiWindow * window); +typedef guintptr (*GstVaapiDisplayGetColormapFunc) (GstVaapiDisplay * display, + GstVaapiWindow * window); + /** * GST_VAAPI_DISPLAY_GET_CLASS_TYPE: * @display: a #GstVaapiDisplay @@ -190,6 +195,8 @@ struct _GstVaapiDisplay * @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 * @@ -215,7 +222,8 @@ struct _GstVaapiDisplayClass GstVaapiDisplayGetInfoFunc get_display; GstVaapiDisplayGetSizeFunc get_size; GstVaapiDisplayGetSizeMFunc get_size_mm; - + GstVaapiDisplayGetVisualIdFunc get_visual_id; + GstVaapiDisplayGetColormapFunc get_colormap; GstVaapiDisplayCreateWindowFunc create_window; GstVaapiDisplayCreateTextureFunc create_texture; }; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 67b358006a..10ff1d42fa 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -212,10 +212,12 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, { GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Window xid = GST_VAAPI_OBJECT_ID (window); guint vid = 0; Colormap cmap = None; + const GstVaapiDisplayClass *display_class; const GstVaapiWindowClass *window_class; XWindowAttributes wattr; Atom atoms[2]; @@ -238,11 +240,19 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, return ok; } + display_class = GST_VAAPI_DISPLAY_GET_CLASS (display); + if (display_class) { + if (display_class->get_visual_id) + vid = display_class->get_visual_id (display, window); + if (display_class->get_colormap) + cmap = display_class->get_colormap (display, window); + } + window_class = GST_VAAPI_WINDOW_GET_CLASS (window); if (window_class) { - if (window_class->get_visual_id) + if (window_class->get_visual_id && !vid) vid = window_class->get_visual_id (window); - if (window_class->get_colormap) + if (window_class->get_colormap && !cmap) cmap = window_class->get_colormap (window); } From e4e43cd842868c7acbcab80a73c319d9cea7dffa Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 26 Jan 2015 23:21:56 +0100 Subject: [PATCH 1847/3781] videopool: re-indent all GstVaapiVideoPool related source code. --- gst-libs/gst/vaapi/gstvaapiimagepool.c | 78 +++--- gst-libs/gst/vaapi/gstvaapiimagepool.h | 6 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 111 ++++---- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 7 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 270 ++++++++++---------- gst-libs/gst/vaapi/gstvaapivideopool.h | 42 +-- gst-libs/gst/vaapi/gstvaapivideopool_priv.h | 59 ++--- 7 files changed, 289 insertions(+), 284 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 40971c1e12..377f050c4d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -39,45 +39,45 @@ * * A pool of lazily allocated #GstVaapiImage objects. */ -struct _GstVaapiImagePool { - /*< private >*/ - GstVaapiVideoPool parent_instance; +struct _GstVaapiImagePool +{ + /*< private >*/ + GstVaapiVideoPool parent_instance; - GstVideoFormat format; - guint width; - guint height; + GstVideoFormat format; + guint width; + guint height; }; static gboolean -image_pool_init(GstVaapiVideoPool *base_pool, const GstVideoInfo *vip) +image_pool_init (GstVaapiVideoPool * base_pool, const GstVideoInfo * vip) { - GstVaapiImagePool * const pool = GST_VAAPI_IMAGE_POOL(base_pool); + GstVaapiImagePool *const pool = GST_VAAPI_IMAGE_POOL (base_pool); - pool->format = GST_VIDEO_INFO_FORMAT(vip); - pool->width = GST_VIDEO_INFO_WIDTH(vip); - pool->height = GST_VIDEO_INFO_HEIGHT(vip); - return gst_vaapi_display_has_image_format(base_pool->display, pool->format); + pool->format = GST_VIDEO_INFO_FORMAT (vip); + pool->width = GST_VIDEO_INFO_WIDTH (vip); + pool->height = GST_VIDEO_INFO_HEIGHT (vip); + return gst_vaapi_display_has_image_format (base_pool->display, pool->format); } static gpointer -gst_vaapi_image_pool_alloc_object(GstVaapiVideoPool *base_pool) +gst_vaapi_image_pool_alloc_object (GstVaapiVideoPool * base_pool) { - GstVaapiImagePool * const pool = GST_VAAPI_IMAGE_POOL(base_pool); + GstVaapiImagePool *const pool = GST_VAAPI_IMAGE_POOL (base_pool); - return gst_vaapi_image_new(base_pool->display, pool->format, - pool->width, pool->height); + return gst_vaapi_image_new (base_pool->display, pool->format, + pool->width, pool->height); } static inline const GstVaapiMiniObjectClass * -gst_vaapi_image_pool_class(void) +gst_vaapi_image_pool_class (void) { - static const GstVaapiVideoPoolClass GstVaapiImagePoolClass = { - { sizeof(GstVaapiImagePool), - (GDestroyNotify)gst_vaapi_video_pool_finalize }, - - .alloc_object = gst_vaapi_image_pool_alloc_object - }; - return GST_VAAPI_MINI_OBJECT_CLASS(&GstVaapiImagePoolClass); + static const GstVaapiVideoPoolClass GstVaapiImagePoolClass = { + {sizeof (GstVaapiImagePool), + (GDestroyNotify) gst_vaapi_video_pool_finalize}, + .alloc_object = gst_vaapi_image_pool_alloc_object + }; + return GST_VAAPI_MINI_OBJECT_CLASS (&GstVaapiImagePoolClass); } /** @@ -91,26 +91,26 @@ gst_vaapi_image_pool_class(void) * Return value: the newly allocated #GstVaapiVideoPool */ GstVaapiVideoPool * -gst_vaapi_image_pool_new(GstVaapiDisplay *display, const GstVideoInfo *vip) +gst_vaapi_image_pool_new (GstVaapiDisplay * display, const GstVideoInfo * vip) { - GstVaapiVideoPool *pool; + GstVaapiVideoPool *pool; - g_return_val_if_fail(display != NULL, NULL); - g_return_val_if_fail(vip != NULL, NULL); + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (vip != NULL, NULL); - pool = (GstVaapiVideoPool *) - gst_vaapi_mini_object_new(gst_vaapi_image_pool_class()); - if (!pool) - return NULL; + pool = (GstVaapiVideoPool *) + gst_vaapi_mini_object_new (gst_vaapi_image_pool_class ()); + if (!pool) + return NULL; - gst_vaapi_video_pool_init(pool, display, - GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE); + gst_vaapi_video_pool_init (pool, display, + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE); - if (!image_pool_init(pool, vip)) - goto error; - return pool; + if (!image_pool_init (pool, vip)) + goto error; + return pool; error: - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pool)); - return NULL; + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pool)); + return NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h index 7bdadf3d44..7222bd99ae 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.h +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -32,12 +32,12 @@ G_BEGIN_DECLS #define GST_VAAPI_IMAGE_POOL(obj) \ - ((GstVaapiImagePool *)(obj)) + ((GstVaapiImagePool *)(obj)) -typedef struct _GstVaapiImagePool GstVaapiImagePool; +typedef struct _GstVaapiImagePool GstVaapiImagePool; GstVaapiVideoPool * -gst_vaapi_image_pool_new(GstVaapiDisplay *display, const GstVideoInfo *vip); +gst_vaapi_image_pool_new (GstVaapiDisplay * display, const GstVideoInfo * vip); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index eb8aecb7a9..8af8eac9a9 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -39,63 +39,64 @@ * * A pool of lazily allocated #GstVaapiSurface objects. */ -struct _GstVaapiSurfacePool { - /*< private >*/ - GstVaapiVideoPool parent_instance; +struct _GstVaapiSurfacePool +{ + /*< private >*/ + GstVaapiVideoPool parent_instance; - GstVaapiChromaType chroma_type; - GstVideoFormat format; - guint width; - guint height; + GstVaapiChromaType chroma_type; + GstVideoFormat format; + guint width; + guint height; }; static gboolean -surface_pool_init(GstVaapiSurfacePool *pool, const GstVideoInfo *vip) +surface_pool_init (GstVaapiSurfacePool * pool, const GstVideoInfo * vip) { - pool->format = GST_VIDEO_INFO_FORMAT(vip); - pool->width = GST_VIDEO_INFO_WIDTH(vip); - pool->height = GST_VIDEO_INFO_HEIGHT(vip); + pool->format = GST_VIDEO_INFO_FORMAT (vip); + pool->width = GST_VIDEO_INFO_WIDTH (vip); + pool->height = GST_VIDEO_INFO_HEIGHT (vip); - if (pool->format == GST_VIDEO_FORMAT_UNKNOWN) - return FALSE; + if (pool->format == GST_VIDEO_FORMAT_UNKNOWN) + return FALSE; - if (pool->format == GST_VIDEO_FORMAT_ENCODED) - pool->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - else - pool->chroma_type = gst_vaapi_video_format_get_chroma_type(pool->format); - if (!pool->chroma_type) - return FALSE; - return TRUE; + if (pool->format == GST_VIDEO_FORMAT_ENCODED) + pool->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + else + pool->chroma_type = gst_vaapi_video_format_get_chroma_type (pool->format); + if (!pool->chroma_type) + return FALSE; + return TRUE; } static gpointer -gst_vaapi_surface_pool_alloc_object(GstVaapiVideoPool *base_pool) +gst_vaapi_surface_pool_alloc_object (GstVaapiVideoPool * base_pool) { - GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(base_pool); + GstVaapiSurfacePool *const pool = GST_VAAPI_SURFACE_POOL (base_pool); - /* Try to allocate a surface with an explicit pixel format first */ - if (pool->format != GST_VIDEO_FORMAT_ENCODED) { - GstVaapiSurface * const surface = gst_vaapi_surface_new_with_format( - base_pool->display, pool->format, pool->width, pool->height); - if (surface) - return surface; - } + /* Try to allocate a surface with an explicit pixel format first */ + if (pool->format != GST_VIDEO_FORMAT_ENCODED) { + GstVaapiSurface *const surface = + gst_vaapi_surface_new_with_format (base_pool->display, pool->format, + pool->width, pool->height); + if (surface) + return surface; + } - /* Otherwise, fallback to the original interface, based on chroma format */ - return gst_vaapi_surface_new(base_pool->display, - pool->chroma_type, pool->width, pool->height); + /* Otherwise, fallback to the original interface, based on chroma format */ + return gst_vaapi_surface_new (base_pool->display, + pool->chroma_type, pool->width, pool->height); } static inline const GstVaapiMiniObjectClass * -gst_vaapi_surface_pool_class(void) +gst_vaapi_surface_pool_class (void) { - static const GstVaapiVideoPoolClass GstVaapiSurfacePoolClass = { - { sizeof(GstVaapiSurfacePool), - (GDestroyNotify)gst_vaapi_video_pool_finalize }, - - .alloc_object = gst_vaapi_surface_pool_alloc_object - }; - return GST_VAAPI_MINI_OBJECT_CLASS(&GstVaapiSurfacePoolClass); + static const GstVaapiVideoPoolClass GstVaapiSurfacePoolClass = { + {sizeof (GstVaapiSurfacePool), + (GDestroyNotify) gst_vaapi_video_pool_finalize}, + .alloc_object = gst_vaapi_surface_pool_alloc_object + }; + return GST_VAAPI_MINI_OBJECT_CLASS (&GstVaapiSurfacePoolClass); } /** @@ -109,25 +110,25 @@ gst_vaapi_surface_pool_class(void) * Return value: the newly allocated #GstVaapiVideoPool */ GstVaapiVideoPool * -gst_vaapi_surface_pool_new(GstVaapiDisplay *display, const GstVideoInfo *vip) +gst_vaapi_surface_pool_new (GstVaapiDisplay * display, const GstVideoInfo * vip) { - GstVaapiVideoPool *pool; + GstVaapiVideoPool *pool; - g_return_val_if_fail(display != NULL, NULL); - g_return_val_if_fail(vip != NULL, NULL); + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (vip != NULL, NULL); - pool = (GstVaapiVideoPool *) - gst_vaapi_mini_object_new(gst_vaapi_surface_pool_class()); - if (!pool) - return NULL; + pool = (GstVaapiVideoPool *) + gst_vaapi_mini_object_new (gst_vaapi_surface_pool_class ()); + if (!pool) + return NULL; - gst_vaapi_video_pool_init(pool, display, - GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE); - if (!surface_pool_init(GST_VAAPI_SURFACE_POOL(pool), vip)) - goto error; - return pool; + gst_vaapi_video_pool_init (pool, display, + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE); + if (!surface_pool_init (GST_VAAPI_SURFACE_POOL (pool), vip)) + goto error; + return pool; error: - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pool)); - return NULL; + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pool)); + return NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index bc7a3ed878..82d623b11f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -32,12 +32,13 @@ G_BEGIN_DECLS #define GST_VAAPI_SURFACE_POOL(obj) \ - ((GstVaapiSurfacePool *)(obj)) + ((GstVaapiSurfacePool *)(obj)) -typedef struct _GstVaapiSurfacePool GstVaapiSurfacePool; +typedef struct _GstVaapiSurfacePool GstVaapiSurfacePool; GstVaapiVideoPool * -gst_vaapi_surface_pool_new(GstVaapiDisplay *display, const GstVideoInfo *vip); +gst_vaapi_surface_pool_new (GstVaapiDisplay * display, + const GstVideoInfo * vip); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index f10a28ccf6..0b1adf0844 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -41,42 +41,42 @@ #undef gst_vaapi_video_pool_replace #define GST_VAAPI_VIDEO_POOL_GET_CLASS(obj) \ - gst_vaapi_video_pool_get_class(GST_VAAPI_VIDEO_POOL(obj)) + gst_vaapi_video_pool_get_class (GST_VAAPI_VIDEO_POOL (obj)) static inline const GstVaapiVideoPoolClass * -gst_vaapi_video_pool_get_class(GstVaapiVideoPool *pool) +gst_vaapi_video_pool_get_class (GstVaapiVideoPool * pool) { - return GST_VAAPI_VIDEO_POOL_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(pool)); + return GST_VAAPI_VIDEO_POOL_CLASS (GST_VAAPI_MINI_OBJECT_GET_CLASS (pool)); } static inline gpointer -gst_vaapi_video_pool_alloc_object(GstVaapiVideoPool *pool) +gst_vaapi_video_pool_alloc_object (GstVaapiVideoPool * pool) { - return GST_VAAPI_VIDEO_POOL_GET_CLASS(pool)->alloc_object(pool); + return GST_VAAPI_VIDEO_POOL_GET_CLASS (pool)->alloc_object (pool); } void -gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display, +gst_vaapi_video_pool_init (GstVaapiVideoPool * pool, GstVaapiDisplay * display, GstVaapiVideoPoolObjectType object_type) { - pool->object_type = object_type; - pool->display = gst_vaapi_display_ref(display); - pool->used_objects = NULL; - pool->used_count = 0; - pool->capacity = 0; + pool->object_type = object_type; + pool->display = gst_vaapi_display_ref (display); + pool->used_objects = NULL; + pool->used_count = 0; + pool->capacity = 0; - g_queue_init(&pool->free_objects); - g_mutex_init(&pool->mutex); + g_queue_init (&pool->free_objects); + g_mutex_init (&pool->mutex); } void -gst_vaapi_video_pool_finalize(GstVaapiVideoPool *pool) +gst_vaapi_video_pool_finalize (GstVaapiVideoPool * pool) { - g_list_free_full(pool->used_objects, gst_vaapi_object_unref); - g_queue_foreach(&pool->free_objects, (GFunc)gst_vaapi_object_unref, NULL); - g_queue_clear(&pool->free_objects); - gst_vaapi_display_replace(&pool->display, NULL); - g_mutex_clear(&pool->mutex); + g_list_free_full (pool->used_objects, gst_vaapi_object_unref); + g_queue_foreach (&pool->free_objects, (GFunc) gst_vaapi_object_unref, NULL); + g_queue_clear (&pool->free_objects); + gst_vaapi_display_replace (&pool->display, NULL); + g_mutex_clear (&pool->mutex); } /** @@ -88,9 +88,9 @@ gst_vaapi_video_pool_finalize(GstVaapiVideoPool *pool) * Returns: The same @pool argument */ GstVaapiVideoPool * -gst_vaapi_video_pool_ref(GstVaapiVideoPool *pool) +gst_vaapi_video_pool_ref (GstVaapiVideoPool * pool) { - return gst_vaapi_video_pool_ref_internal(pool); + return gst_vaapi_video_pool_ref_internal (pool); } /** @@ -101,9 +101,9 @@ gst_vaapi_video_pool_ref(GstVaapiVideoPool *pool) * the reference count reaches zero, the pool will be free'd. */ void -gst_vaapi_video_pool_unref(GstVaapiVideoPool *pool) +gst_vaapi_video_pool_unref (GstVaapiVideoPool * pool) { - gst_vaapi_video_pool_unref_internal(pool); + gst_vaapi_video_pool_unref_internal (pool); } /** @@ -116,10 +116,10 @@ gst_vaapi_video_pool_unref(GstVaapiVideoPool *pool) * pool. However, @new_pool can be NULL. */ void -gst_vaapi_video_pool_replace(GstVaapiVideoPool **old_pool_ptr, - GstVaapiVideoPool *new_pool) +gst_vaapi_video_pool_replace (GstVaapiVideoPool ** old_pool_ptr, + GstVaapiVideoPool * new_pool) { - gst_vaapi_video_pool_replace_internal(old_pool_ptr, new_pool); + gst_vaapi_video_pool_replace_internal (old_pool_ptr, new_pool); } /** @@ -132,11 +132,11 @@ gst_vaapi_video_pool_replace(GstVaapiVideoPool **old_pool_ptr, * Return value: the #GstVaapiDisplay the @pool is bound to */ GstVaapiDisplay * -gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool) +gst_vaapi_video_pool_get_display (GstVaapiVideoPool * pool) { - g_return_val_if_fail(pool != NULL, NULL); + g_return_val_if_fail (pool != NULL, NULL); - return pool->display; + return pool->display; } /** @@ -149,11 +149,11 @@ gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool) * objects */ GstVaapiVideoPoolObjectType -gst_vaapi_video_pool_get_object_type(GstVaapiVideoPool *pool) +gst_vaapi_video_pool_get_object_type (GstVaapiVideoPool * pool) { - g_return_val_if_fail(pool != NULL, (GstVaapiVideoPoolObjectType)0); + g_return_val_if_fail (pool != NULL, (GstVaapiVideoPoolObjectType) 0); - return pool->object_type; + return pool->object_type; } /** @@ -168,36 +168,36 @@ gst_vaapi_video_pool_get_object_type(GstVaapiVideoPool *pool) * Return value: a possibly newly allocated object, or %NULL on error */ static gpointer -gst_vaapi_video_pool_get_object_unlocked(GstVaapiVideoPool *pool) +gst_vaapi_video_pool_get_object_unlocked (GstVaapiVideoPool * pool) { - gpointer object; + gpointer object; - if (pool->capacity && pool->used_count >= pool->capacity) - return NULL; + if (pool->capacity && pool->used_count >= pool->capacity) + return NULL; - object = g_queue_pop_head(&pool->free_objects); - if (!object) { - object = gst_vaapi_video_pool_alloc_object(pool); - if (!object) - return NULL; - } + object = g_queue_pop_head (&pool->free_objects); + if (!object) { + object = gst_vaapi_video_pool_alloc_object (pool); + if (!object) + return NULL; + } - ++pool->used_count; - pool->used_objects = g_list_prepend(pool->used_objects, object); - return gst_vaapi_object_ref(object); + ++pool->used_count; + pool->used_objects = g_list_prepend (pool->used_objects, object); + return gst_vaapi_object_ref (object); } gpointer -gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) +gst_vaapi_video_pool_get_object (GstVaapiVideoPool * pool) { - gpointer object; + gpointer object; - g_return_val_if_fail(pool != NULL, NULL); + g_return_val_if_fail (pool != NULL, NULL); - g_mutex_lock(&pool->mutex); - object = gst_vaapi_video_pool_get_object_unlocked(pool); - g_mutex_unlock(&pool->mutex); - return object; + g_mutex_lock (&pool->mutex); + object = gst_vaapi_video_pool_get_object_unlocked (pool); + g_mutex_unlock (&pool->mutex); + return object; } /** @@ -211,30 +211,30 @@ gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool) * behaviour. */ static void -gst_vaapi_video_pool_put_object_unlocked(GstVaapiVideoPool *pool, +gst_vaapi_video_pool_put_object_unlocked (GstVaapiVideoPool * pool, gpointer object) { - GList *elem; + GList *elem; - elem = g_list_find(pool->used_objects, object); - if (!elem) - return; + elem = g_list_find (pool->used_objects, object); + if (!elem) + return; - gst_vaapi_object_unref(object); - --pool->used_count; - pool->used_objects = g_list_delete_link(pool->used_objects, elem); - g_queue_push_tail(&pool->free_objects, object); + gst_vaapi_object_unref (object); + --pool->used_count; + pool->used_objects = g_list_delete_link (pool->used_objects, elem); + g_queue_push_tail (&pool->free_objects, object); } void -gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) +gst_vaapi_video_pool_put_object (GstVaapiVideoPool * pool, gpointer object) { - g_return_if_fail(pool != NULL); - g_return_if_fail(object != NULL); + g_return_if_fail (pool != NULL); + g_return_if_fail (object != NULL); - g_mutex_lock(&pool->mutex); - gst_vaapi_video_pool_put_object_unlocked(pool, object); - g_mutex_unlock(&pool->mutex); + g_mutex_lock (&pool->mutex); + gst_vaapi_video_pool_put_object_unlocked (pool, object); + g_mutex_unlock (&pool->mutex); } /** @@ -249,25 +249,25 @@ gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object) * Return value: %TRUE on success. */ static inline gboolean -gst_vaapi_video_pool_add_object_unlocked(GstVaapiVideoPool *pool, +gst_vaapi_video_pool_add_object_unlocked (GstVaapiVideoPool * pool, gpointer object) { - g_queue_push_tail(&pool->free_objects, gst_vaapi_object_ref(object)); - return TRUE; + g_queue_push_tail (&pool->free_objects, gst_vaapi_object_ref (object)); + return TRUE; } gboolean -gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object) +gst_vaapi_video_pool_add_object (GstVaapiVideoPool * pool, gpointer object) { - gboolean success; + gboolean success; - g_return_val_if_fail(pool != NULL, FALSE); - g_return_val_if_fail(object != NULL, FALSE); + g_return_val_if_fail (pool != NULL, FALSE); + g_return_val_if_fail (object != NULL, FALSE); - g_mutex_lock(&pool->mutex); - success = gst_vaapi_video_pool_add_object_unlocked(pool, object); - g_mutex_unlock(&pool->mutex); - return success; + g_mutex_lock (&pool->mutex); + success = gst_vaapi_video_pool_add_object_unlocked (pool, object); + g_mutex_unlock (&pool->mutex); + return success; } /** @@ -282,30 +282,30 @@ gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object) * Return value: %TRUE on success. */ static gboolean -gst_vaapi_video_pool_add_objects_unlocked(GstVaapiVideoPool *pool, - GPtrArray *objects) +gst_vaapi_video_pool_add_objects_unlocked (GstVaapiVideoPool * pool, + GPtrArray * objects) { - guint i; + guint i; - for (i = 0; i < objects->len; i++) { - gpointer const object = g_ptr_array_index(objects, i); - if (!gst_vaapi_video_pool_add_object_unlocked(pool, object)) - return FALSE; - } - return TRUE; + for (i = 0; i < objects->len; i++) { + gpointer const object = g_ptr_array_index (objects, i); + if (!gst_vaapi_video_pool_add_object_unlocked (pool, object)) + return FALSE; + } + return TRUE; } gboolean -gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects) +gst_vaapi_video_pool_add_objects (GstVaapiVideoPool * pool, GPtrArray * objects) { - gboolean success; + gboolean success; - g_return_val_if_fail(pool != NULL, FALSE); + g_return_val_if_fail (pool != NULL, FALSE); - g_mutex_lock(&pool->mutex); - success = gst_vaapi_video_pool_add_objects_unlocked(pool, objects); - g_mutex_unlock(&pool->mutex); - return success; + g_mutex_lock (&pool->mutex); + success = gst_vaapi_video_pool_add_objects_unlocked (pool, objects); + g_mutex_unlock (&pool->mutex); + return success; } /** @@ -317,16 +317,16 @@ gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects) * Return value: number of free objects in the pool */ guint -gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool) +gst_vaapi_video_pool_get_size (GstVaapiVideoPool * pool) { - guint size; + guint size; - g_return_val_if_fail(pool != NULL, 0); + g_return_val_if_fail (pool != NULL, 0); - g_mutex_lock(&pool->mutex); - size = g_queue_get_length(&pool->free_objects); - g_mutex_unlock(&pool->mutex); - return size; + g_mutex_lock (&pool->mutex); + size = g_queue_get_length (&pool->free_objects); + g_mutex_unlock (&pool->mutex); + return size; } /** @@ -342,37 +342,37 @@ gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool) * Return value: %TRUE on success */ static gboolean -gst_vaapi_video_pool_reserve_unlocked(GstVaapiVideoPool *pool, guint n) +gst_vaapi_video_pool_reserve_unlocked (GstVaapiVideoPool * pool, guint n) { - guint i, num_allocated; + guint i, num_allocated; - num_allocated = gst_vaapi_video_pool_get_size(pool) + pool->used_count; - if (n < num_allocated) - return TRUE; - - if ((n -= num_allocated) > pool->capacity) - n = pool->capacity; - - for (i = num_allocated; i < n; i++) { - gpointer const object = gst_vaapi_video_pool_alloc_object(pool); - if (!object) - return FALSE; - g_queue_push_tail(&pool->free_objects, object); - } + num_allocated = gst_vaapi_video_pool_get_size (pool) + pool->used_count; + if (n < num_allocated) return TRUE; + + if ((n -= num_allocated) > pool->capacity) + n = pool->capacity; + + for (i = num_allocated; i < n; i++) { + gpointer const object = gst_vaapi_video_pool_alloc_object (pool); + if (!object) + return FALSE; + g_queue_push_tail (&pool->free_objects, object); + } + return TRUE; } gboolean -gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n) +gst_vaapi_video_pool_reserve (GstVaapiVideoPool * pool, guint n) { - gboolean success; + gboolean success; - g_return_val_if_fail(pool != NULL, 0); + g_return_val_if_fail (pool != NULL, 0); - g_mutex_lock(&pool->mutex); - success = gst_vaapi_video_pool_reserve_unlocked(pool, n); - g_mutex_unlock(&pool->mutex); - return success; + g_mutex_lock (&pool->mutex); + success = gst_vaapi_video_pool_reserve_unlocked (pool, n); + g_mutex_unlock (&pool->mutex); + return success; } /** @@ -385,17 +385,17 @@ gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n) * Return value: the capacity of the pool */ guint -gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool) +gst_vaapi_video_pool_get_capacity (GstVaapiVideoPool * pool) { - guint capacity; + guint capacity; - g_return_val_if_fail(pool != NULL, 0); + g_return_val_if_fail (pool != NULL, 0); - g_mutex_lock(&pool->mutex); - capacity = pool->capacity; - g_mutex_unlock(&pool->mutex); + g_mutex_lock (&pool->mutex); + capacity = pool->capacity; + g_mutex_unlock (&pool->mutex); - return capacity; + return capacity; } /** @@ -406,11 +406,11 @@ gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool) * Sets the maximum number of objects that can be allocated in the pool. */ void -gst_vaapi_video_pool_set_capacity(GstVaapiVideoPool *pool, guint capacity) +gst_vaapi_video_pool_set_capacity (GstVaapiVideoPool * pool, guint capacity) { - g_return_if_fail(pool != NULL); + g_return_if_fail (pool != NULL); - g_mutex_lock(&pool->mutex); - pool->capacity = capacity; - g_mutex_unlock(&pool->mutex); + g_mutex_lock (&pool->mutex); + pool->capacity = capacity; + g_mutex_unlock (&pool->mutex); } diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h index 84210edd5b..393de7b893 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -31,9 +31,9 @@ G_BEGIN_DECLS #define GST_VAAPI_VIDEO_POOL(obj) \ - ((GstVaapiVideoPool *)(obj)) + ((GstVaapiVideoPool *)(obj)) -typedef struct _GstVaapiVideoPool GstVaapiVideoPool; +typedef struct _GstVaapiVideoPool GstVaapiVideoPool; /** * GstVaapiVideoPoolObjectType: @@ -43,51 +43,53 @@ typedef struct _GstVaapiVideoPool GstVaapiVideoPool; * * The set of all supported #GstVaapiVideoPool object types. */ -typedef enum { - GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE = 1, - GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE, - GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER +typedef enum +{ + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE = 1, + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE, + GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER } GstVaapiVideoPoolObjectType; GstVaapiVideoPool * -gst_vaapi_video_pool_ref(GstVaapiVideoPool *pool); +gst_vaapi_video_pool_ref (GstVaapiVideoPool * pool); void -gst_vaapi_video_pool_unref(GstVaapiVideoPool *pool); +gst_vaapi_video_pool_unref (GstVaapiVideoPool * pool); void -gst_vaapi_video_pool_replace(GstVaapiVideoPool **old_pool_ptr, - GstVaapiVideoPool *new_pool); +gst_vaapi_video_pool_replace (GstVaapiVideoPool ** old_pool_ptr, + GstVaapiVideoPool * new_pool); GstVaapiDisplay * -gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool); +gst_vaapi_video_pool_get_display (GstVaapiVideoPool * pool); GstVaapiVideoPoolObjectType -gst_vaapi_video_pool_get_object_type(GstVaapiVideoPool *pool); +gst_vaapi_video_pool_get_object_type (GstVaapiVideoPool * pool); gpointer -gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool); +gst_vaapi_video_pool_get_object (GstVaapiVideoPool * pool); void -gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object); +gst_vaapi_video_pool_put_object (GstVaapiVideoPool * pool, gpointer object); gboolean -gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object); +gst_vaapi_video_pool_add_object (GstVaapiVideoPool * pool, gpointer object); gboolean -gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects); +gst_vaapi_video_pool_add_objects (GstVaapiVideoPool * pool, + GPtrArray * objects); guint -gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool); +gst_vaapi_video_pool_get_size (GstVaapiVideoPool * pool); gboolean -gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n); +gst_vaapi_video_pool_reserve (GstVaapiVideoPool * pool, guint n); guint -gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool); +gst_vaapi_video_pool_get_capacity (GstVaapiVideoPool * pool); void -gst_vaapi_video_pool_set_capacity(GstVaapiVideoPool *pool, guint capacity); +gst_vaapi_video_pool_set_capacity (GstVaapiVideoPool * pool, guint capacity); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h index 1411952a60..6e5fa3a950 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h @@ -30,29 +30,29 @@ G_BEGIN_DECLS #define GST_VAAPI_VIDEO_POOL_CLASS(klass) \ - ((GstVaapiVideoPoolClass *)(klass)) + ((GstVaapiVideoPoolClass *)(klass)) +#define GST_VAAPI_IS_VIDEO_POOL_CLASS(klass) \ + ((klass) != NULL) -#define GST_VAAPI_IS_VIDEO_POOL_CLASS(klass) \ - ((klass) != NULL) - -typedef struct _GstVaapiVideoPoolClass GstVaapiVideoPoolClass; +typedef struct _GstVaapiVideoPoolClass GstVaapiVideoPoolClass; /** * GstVaapiVideoPool: * * A pool of lazily allocated video objects. e.g. surfaces, images. */ -struct _GstVaapiVideoPool { - /*< private >*/ - GstVaapiMiniObject parent_instance; +struct _GstVaapiVideoPool +{ + /*< private >*/ + GstVaapiMiniObject parent_instance; - guint object_type; - GstVaapiDisplay *display; - GQueue free_objects; - GList *used_objects; - guint used_count; - guint capacity; - GMutex mutex; + guint object_type; + GstVaapiDisplay *display; + GQueue free_objects; + GList *used_objects; + guint used_count; + guint capacity; + GMutex mutex; }; /** @@ -61,46 +61,47 @@ struct _GstVaapiVideoPool { * * A pool base class used to hold video objects. e.g. surfaces, images. */ -struct _GstVaapiVideoPoolClass { - /*< private >*/ - GstVaapiMiniObjectClass parent_class; +struct _GstVaapiVideoPoolClass +{ + /*< private >*/ + GstVaapiMiniObjectClass parent_class; - /*< public >*/ - gpointer (*alloc_object)(GstVaapiVideoPool *pool); + /*< public >*/ + gpointer (*alloc_object) (GstVaapiVideoPool * pool); }; G_GNUC_INTERNAL void -gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display, +gst_vaapi_video_pool_init (GstVaapiVideoPool * pool, GstVaapiDisplay * display, GstVaapiVideoPoolObjectType object_type); G_GNUC_INTERNAL void -gst_vaapi_video_pool_finalize(GstVaapiVideoPool *pool); +gst_vaapi_video_pool_finalize (GstVaapiVideoPool * pool); /* Internal aliases */ #define gst_vaapi_video_pool_ref_internal(pool) \ - ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pool))) + ((gpointer)gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (pool))) #define gst_vaapi_video_pool_unref_internal(pool) \ - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pool)) + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pool)) #define gst_vaapi_video_pool_replace_internal(old_pool_ptr, new_pool) \ - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pool_ptr), \ - GST_VAAPI_MINI_OBJECT(new_pool)) + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **)(old_pool_ptr), \ + GST_VAAPI_MINI_OBJECT (new_pool)) #undef gst_vaapi_video_pool_ref #define gst_vaapi_video_pool_ref(pool) \ - gst_vaapi_video_pool_ref_internal((pool)) + gst_vaapi_video_pool_ref_internal ((pool)) #undef gst_vaapi_video_pool_unref #define gst_vaapi_video_pool_unref(pool) \ - gst_vaapi_video_pool_unref_internal((pool)) + gst_vaapi_video_pool_unref_internal ((pool)) #undef gst_vaapi_video_pool_replace #define gst_vaapi_video_pool_replace(old_pool_ptr, new_pool) \ - gst_vaapi_video_pool_replace_internal((old_pool_ptr), (new_pool)) + gst_vaapi_video_pool_replace_internal ((old_pool_ptr), (new_pool)) G_END_DECLS From 96ce1bc761b35d1dd49f99adc33c8c6ec451f37f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 27 Jan 2015 11:44:12 +0100 Subject: [PATCH 1848/3781] videopool: add optional flags for surface pool allocation. Reword surface pool allocation helpers so that to allow for a simple form, e.g. gst_vaapi_surface_pool_new(format, width, height); and a somewhat more elaborated/flexible form with optional allocation flags and precise GstVideoInfo specification. This is an API/ABI change, and SONAME version needs to be bumped. --- gst-libs/gst/vaapi/gstvaapicontext.c | 6 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 64 +++++++++++++++------ gst-libs/gst/vaapi/gstvaapisurfacepool.h | 8 ++- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 6 +- gst/vaapi/gstvaapipostproc.c | 5 +- gst/vaapi/gstvaapiuploader.c | 2 +- gst/vaapi/gstvaapivideobufferpool.c | 2 +- gst/vaapi/gstvaapivideomemory.c | 6 +- gst/vaapi/gstvaapivideomemory.h | 2 +- tests/test-surfaces.c | 6 +- 10 files changed, 69 insertions(+), 38 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 185ed7fdb8..a2c68a328a 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -134,7 +134,6 @@ static gboolean context_create_surfaces (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; - GstVideoInfo vi; guint num_surfaces; if (!gst_vaapi_context_overlay_reset (context)) @@ -149,10 +148,9 @@ context_create_surfaces (GstVaapiContext * context) } if (!context->surfaces_pool) { - gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_ENCODED, - cip->width, cip->height); context->surfaces_pool = - gst_vaapi_surface_pool_new (GST_VAAPI_OBJECT_DISPLAY (context), &vi); + gst_vaapi_surface_pool_new (GST_VAAPI_OBJECT_DISPLAY (context), + GST_VIDEO_FORMAT_ENCODED, cip->width, cip->height); if (!context->surfaces_pool) return FALSE; } diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 8af8eac9a9..02c0606041 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -45,25 +45,26 @@ struct _GstVaapiSurfacePool GstVaapiVideoPool parent_instance; GstVaapiChromaType chroma_type; - GstVideoFormat format; - guint width; - guint height; + GstVideoInfo video_info; + guint alloc_flags; }; static gboolean -surface_pool_init (GstVaapiSurfacePool * pool, const GstVideoInfo * vip) +surface_pool_init (GstVaapiSurfacePool * pool, const GstVideoInfo * vip, + guint flags) { - pool->format = GST_VIDEO_INFO_FORMAT (vip); - pool->width = GST_VIDEO_INFO_WIDTH (vip); - pool->height = GST_VIDEO_INFO_HEIGHT (vip); + const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (vip); - if (pool->format == GST_VIDEO_FORMAT_UNKNOWN) + pool->video_info = *vip; + pool->alloc_flags = flags; + + if (format == GST_VIDEO_FORMAT_UNKNOWN) return FALSE; - if (pool->format == GST_VIDEO_FORMAT_ENCODED) + if (format == GST_VIDEO_FORMAT_ENCODED) pool->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; else - pool->chroma_type = gst_vaapi_video_format_get_chroma_type (pool->format); + pool->chroma_type = gst_vaapi_video_format_get_chroma_type (format); if (!pool->chroma_type) return FALSE; return TRUE; @@ -75,17 +76,18 @@ gst_vaapi_surface_pool_alloc_object (GstVaapiVideoPool * base_pool) GstVaapiSurfacePool *const pool = GST_VAAPI_SURFACE_POOL (base_pool); /* Try to allocate a surface with an explicit pixel format first */ - if (pool->format != GST_VIDEO_FORMAT_ENCODED) { + if (GST_VIDEO_INFO_FORMAT (&pool->video_info) != GST_VIDEO_FORMAT_ENCODED) { GstVaapiSurface *const surface = - gst_vaapi_surface_new_with_format (base_pool->display, pool->format, - pool->width, pool->height); + gst_vaapi_surface_new_full (base_pool->display, &pool->video_info, + pool->alloc_flags); if (surface) return surface; } /* Otherwise, fallback to the original interface, based on chroma format */ return gst_vaapi_surface_new (base_pool->display, - pool->chroma_type, pool->width, pool->height); + pool->chroma_type, GST_VIDEO_INFO_WIDTH (&pool->video_info), + GST_VIDEO_INFO_HEIGHT (&pool->video_info)); } static inline const GstVaapiMiniObjectClass * @@ -102,7 +104,36 @@ gst_vaapi_surface_pool_class (void) /** * gst_vaapi_surface_pool_new: * @display: a #GstVaapiDisplay + * @format: a #GstVideoFormat + * @width: the desired width, in pixels + * @height: the desired height, in pixels + * + * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the specified + * format and dimensions. If @format is GST_VIDEO_FORMAT_ENCODED, then + * surfaces with best "native" format would be created. Typically, this is + * NV12 format, but this is implementation (driver) defined. + * + * Return value: the newly allocated #GstVaapiVideoPool + */ +GstVaapiVideoPool * +gst_vaapi_surface_pool_new (GstVaapiDisplay * display, GstVideoFormat format, + guint width, guint height) +{ + GstVideoInfo vi; + + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + + gst_video_info_set_format (&vi, format, width, height); + return gst_vaapi_surface_pool_new_full (display, &vi, 0); +} + +/** + * gst_vaapi_surface_pool_new_full: + * @display: a #GstVaapiDisplay * @vip: a #GstVideoInfo + * @flags: (optional) allocation flags * * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the * specified format and dimensions in @vip. @@ -110,7 +141,8 @@ gst_vaapi_surface_pool_class (void) * Return value: the newly allocated #GstVaapiVideoPool */ GstVaapiVideoPool * -gst_vaapi_surface_pool_new (GstVaapiDisplay * display, const GstVideoInfo * vip) +gst_vaapi_surface_pool_new_full (GstVaapiDisplay * display, + const GstVideoInfo * vip, guint flags) { GstVaapiVideoPool *pool; @@ -124,7 +156,7 @@ gst_vaapi_surface_pool_new (GstVaapiDisplay * display, const GstVideoInfo * vip) gst_vaapi_video_pool_init (pool, display, GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE); - if (!surface_pool_init (GST_VAAPI_SURFACE_POOL (pool), vip)) + if (!surface_pool_init (GST_VAAPI_SURFACE_POOL (pool), vip, flags)) goto error; return pool; diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 82d623b11f..e0529a22f4 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -37,8 +37,12 @@ G_BEGIN_DECLS typedef struct _GstVaapiSurfacePool GstVaapiSurfacePool; GstVaapiVideoPool * -gst_vaapi_surface_pool_new (GstVaapiDisplay * display, - const GstVideoInfo * vip); +gst_vaapi_surface_pool_new (GstVaapiDisplay * display, GstVideoFormat format, + guint width, guint height); + +GstVaapiVideoPool * +gst_vaapi_surface_pool_new_full (GstVaapiDisplay * display, + const GstVideoInfo * vip, guint flags); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 2c40e48895..9846063d9d 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -348,14 +348,12 @@ vpp_convert (GstVaapiWindow * window, GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); GstVaapiSurface *vpp_surface = NULL; GstVaapiFilterStatus status; - GstVideoInfo vi; /* Ensure VA surface pool is created */ /* XXX: optimize the surface format to use. e.g. YUY2 */ if (!priv->surface_pool) { - gst_video_info_set_format (&vi, priv->surface_format, - window->width, window->height); - priv->surface_pool = gst_vaapi_surface_pool_new (display, &vi); + priv->surface_pool = gst_vaapi_surface_pool_new (display, + priv->surface_format, window->width, window->height); if (!priv->surface_pool) return NULL; gst_vaapi_filter_replace (&priv->filter, NULL); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 756491b3c6..e701b8cdff 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1310,8 +1310,9 @@ ensure_srcpad_buffer_pool (GstVaapiPostproc * postproc, GstCaps * caps) return TRUE; postproc->filter_pool_info = vi; - pool = gst_vaapi_surface_pool_new (GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc), - &postproc->filter_pool_info); + pool = + gst_vaapi_surface_pool_new_full (GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc), + &postproc->filter_pool_info, 0); if (!pool) return FALSE; diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 6c702b929c..c4e5d14943 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -243,7 +243,7 @@ ensure_surface_pool (GstVaapiUploader * uploader, GstCaps * caps, } } - pool = gst_vaapi_surface_pool_new (priv->display, &vi); + pool = gst_vaapi_surface_pool_new_full (priv->display, &vi, 0); if (!pool) return FALSE; diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 4c642e7d50..84be8e3058 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -153,7 +153,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, GST_VIDEO_INFO_HEIGHT (cur_vip) != GST_VIDEO_INFO_HEIGHT (new_vip); if (changed_caps) { - allocator = gst_vaapi_video_allocator_new (priv->display, new_vip); + allocator = gst_vaapi_video_allocator_new (priv->display, new_vip, 0); if (!allocator) goto error_create_allocator; gst_object_replace ((GstObject **) & priv->allocator, diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 184d78d27f..33674f5e8a 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -650,7 +650,7 @@ gst_video_info_update_from_image (GstVideoInfo * vip, GstVaapiImage * image) GstAllocator * gst_vaapi_video_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * vip) + const GstVideoInfo * vip, guint flags) { GstVaapiVideoAllocator *allocator; GstVaapiSurface *surface; @@ -695,8 +695,8 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display, gst_vaapi_object_unref (image); } - allocator->surface_pool = gst_vaapi_surface_pool_new (display, - &allocator->surface_info); + allocator->surface_pool = gst_vaapi_surface_pool_new_full (display, + &allocator->surface_info, flags); if (!allocator->surface_pool) goto error_create_surface_pool; diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 5681a1c065..ba29564a25 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -187,7 +187,7 @@ gst_vaapi_video_allocator_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstAllocator * gst_vaapi_video_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * vip); + const GstVideoInfo * vip, guint flags); G_END_DECLS diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index c958e0754e..734774f567 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -36,7 +36,6 @@ main(int argc, char *argv[]) GstVaapiID surface_id; GstVaapiSurface *surfaces[MAX_SURFACES]; GstVaapiVideoPool *pool; - GstVideoInfo vi; gint i; static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; @@ -60,9 +59,8 @@ main(int argc, char *argv[]) gst_vaapi_object_unref(surface); - gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_ENCODED, width, height); - - pool = gst_vaapi_surface_pool_new(display, &vi); + pool = gst_vaapi_surface_pool_new(display, GST_VIDEO_FORMAT_ENCODED, + width, height); if (!pool) g_error("could not create Gst/VA surface pool"); From 7651c5132440149607e73d84bf7f42558c89e6c3 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 28 Jan 2015 18:25:09 +0200 Subject: [PATCH 1849/3781] Add missing header file to Makefile Add gstvaapitexture_glx.h to Makefile.am --- gst-libs/gst/vaapi/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index e0b9fd48b2..7f148bec87 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -240,6 +240,7 @@ libgstvaapi_glx_source_c = \ libgstvaapi_glx_source_h = \ gstvaapidisplay_glx.h \ gstvaapitexture.h \ + gstvaapitexture_glx.h \ gstvaapiwindow_glx.h \ $(NULL) From 250260cc36189911c5ebf62eade4c1a1647c85d8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Sep 2014 10:58:51 +0200 Subject: [PATCH 1850/3781] Add abstraction for exported VA buffers. The VA buffer export APIs work for a particular lifetime starting from vaAcquireBufferHandle() and ending with vaReleaseBufferHandle(). As such, it could be much more convenient to support implicit releases by simply having a refcount reaching zero. https://bugzilla.gnome.org/show_bug.cgi?id=736721 --- gst-libs/gst/vaapi/Makefile.am | 3 + gst-libs/gst/vaapi/gstvaapibufferproxy.c | 294 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapibufferproxy.h | 85 +++++ gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h | 114 +++++++ 4 files changed, 496 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapibufferproxy.c create mode 100644 gst-libs/gst/vaapi/gstvaapibufferproxy.h create mode 100644 gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 7f148bec87..0ecb66465d 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -45,6 +45,7 @@ libgstvaapi_libs = \ $(top_builddir)/gst-libs/gst/codecparsers/libgstvaapi-codecparsers.la libgstvaapi_source_c = \ + gstvaapibufferproxy.c \ gstvaapicodec_objects.c \ gstvaapicontext.c \ gstvaapicontext_overlay.c \ @@ -82,6 +83,7 @@ libgstvaapi_source_c = \ $(NULL) libgstvaapi_source_h = \ + gstvaapibufferproxy.h \ gstvaapidecoder.h \ gstvaapidecoder_h264.h \ gstvaapidecoder_mpeg2.h \ @@ -111,6 +113,7 @@ libgstvaapi_source_h = \ libgstvaapi_source_priv_h = \ glibcompat.h \ gstcompat.h \ + gstvaapibufferproxy_priv.h \ gstvaapicodec_objects.h \ gstvaapicompat.h \ gstvaapicontext.h \ diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c new file mode 100644 index 0000000000..26addfaa18 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -0,0 +1,294 @@ +/* + * gstvaapibufferproxy.c - Buffer proxy abstraction + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 "gstvaapibufferproxy.h" +#include "gstvaapibufferproxy_priv.h" +#include "gstvaapiutils.h" +#include "gstvaapiobject_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +/* Ensure those symbols are actually defined in the resulting libraries */ +#undef gst_vaapi_buffer_proxy_ref +#undef gst_vaapi_buffer_proxy_unref +#undef gst_vaapi_buffer_proxy_replace + +guint +from_GstVaapiBufferMemoryType (guint type) +{ + guint va_type; + + switch (type) { + default: + va_type = 0; + break; + } + return va_type; +} + +guint +to_GstVaapiBufferMemoryType (guint va_type) +{ + guint type; + + switch (va_type) { + default: + type = 0; + break; + } + return type; +} + +static gboolean +gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) +{ + const guint mem_type = proxy->va_info.mem_type; + VAStatus va_status; + + if (proxy->va_info.handle) + return TRUE; + + if (!proxy->parent || proxy->va_buf == VA_INVALID_ID) + return FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (proxy->parent); + va_status = vaAcquireBufferHandle (GST_VAAPI_OBJECT_VADISPLAY (proxy->parent), + proxy->va_buf, &proxy->va_info); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (proxy->parent); + 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) +{ + VAStatus va_status; + + if (!proxy->va_info.handle) + return TRUE; + + if (!proxy->parent || proxy->va_buf == VA_INVALID_ID) + return FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (proxy->parent); + va_status = vaReleaseBufferHandle (GST_VAAPI_OBJECT_VADISPLAY (proxy->parent), + proxy->va_buf); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (proxy->parent); + 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); + + gst_vaapi_object_replace (&proxy->parent, 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->parent = 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_internal (proxy); + return NULL; +} + +GstVaapiBufferProxy * +gst_vaapi_buffer_proxy_new_from_object (GstVaapiObject * object, + VABufferID buf_id, guint type, GDestroyNotify destroy_func, gpointer data) +{ + GstVaapiBufferProxy *proxy; + + g_return_val_if_fail (object != NULL, NULL); + + proxy = (GstVaapiBufferProxy *) + gst_vaapi_mini_object_new (gst_vaapi_buffer_proxy_class ()); + if (!proxy) + return NULL; + + proxy->parent = gst_vaapi_object_ref (object); + 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_internal (proxy); + return NULL; +error_acquire_handle: + GST_ERROR ("failed to acquire the underlying VA buffer handle"); + gst_vaapi_buffer_proxy_unref_internal (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 gst_vaapi_buffer_proxy_ref_internal (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_buffer_proxy_unref_internal (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_buffer_proxy_replace_internal (old_proxy_ptr, 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, NULL); + + 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); +} diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.h b/gst-libs/gst/vaapi/gstvaapibufferproxy.h new file mode 100644 index 0000000000..147157ddf5 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.h @@ -0,0 +1,85 @@ +/* + * gstvaapibufferproxy.h - Buffer proxy abstraction + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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; + +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); + +G_END_DECLS + +#endif /* GST_VAAPI_BUFFER_PROXY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h new file mode 100644 index 0000000000..f12daef9a2 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h @@ -0,0 +1,114 @@ +/* + * gstvaapibufferproxy_priv.h - Buffer proxy abstraction (private definitions) + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 "gstvaapiobject.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; + GstVaapiObject *parent; + + GDestroyNotify destroy_func; + gpointer destroy_data; + guint type; + VABufferID va_buf; + VABufferInfo va_info; +}; + +G_GNUC_INTERNAL +GstVaapiBufferProxy * +gst_vaapi_buffer_proxy_new_from_object (GstVaapiObject * object, + 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); + +/* Inline reference counting for core libgstvaapi library */ +#ifdef IN_LIBGSTVAAPI_CORE +#define gst_vaapi_buffer_proxy_ref_internal(proxy) \ + ((gpointer) gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (proxy))) + +#define gst_vaapi_buffer_proxy_unref_internal(proxy) \ + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (proxy)) + +#define gst_vaapi_buffer_proxy_replace_internal(old_proxy_ptr, new_proxy) \ + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **)(old_proxy_ptr), \ + GST_VAAPI_MINI_OBJECT (new_proxy)) + +#undef gst_vaapi_buffer_proxy_ref +#define gst_vaapi_buffer_proxy_ref(proxy) \ + gst_vaapi_buffer_proxy_ref_internal ((proxy)) + +#undef gst_vaapi_buffer_proxy_unref +#define gst_vaapi_buffer_proxy_unref(proxy) \ + gst_vaapi_buffer_proxy_unref_internal ((proxy)) + +#undef gst_vaapi_buffer_proxy_replace +#define gst_vaapi_buffer_proxy_replace(old_proxy_ptr, new_proxy) \ + gst_vaapi_buffer_proxy_replace_internal ((old_proxy_ptr), (new_proxy)) +#endif + +G_END_DECLS + +#endif /* GST_VAAPI_BUFFER_PROXY_PRIV_H */ From 073d6d59e1a95dedb8c97f66b55f641034e39a0c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Sep 2014 11:48:05 +0200 Subject: [PATCH 1851/3781] surface: add support for dma_buf exports. Use the new VA buffer export APIs to allow for a VA surface to be exposed as a plain PRIME fd. This is in view to simplifying interop with EGL or OpenCL for instance. https://bugzilla.gnome.org/show_bug.cgi?id=735364 --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapibufferproxy.c | 8 +++ gst-libs/gst/vaapi/gstvaapibufferproxy.h | 10 +++ gst-libs/gst/vaapi/gstvaapisurface_drm.c | 77 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface_drm.h | 36 +++++++++++ 5 files changed, 133 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapisurface_drm.c create mode 100644 gst-libs/gst/vaapi/gstvaapisurface_drm.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 0ecb66465d..63c1e2b687 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -69,6 +69,7 @@ libgstvaapi_source_c = \ gstvaapiprofile.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ + gstvaapisurface_drm.c \ gstvaapisurfacepool.c \ gstvaapisurfaceproxy.c \ gstvaapitexture.c \ @@ -98,6 +99,7 @@ libgstvaapi_source_h = \ gstvaapiprofile.h \ gstvaapisubpicture.h \ gstvaapisurface.h \ + gstvaapisurface_drm.h \ gstvaapisurfacepool.h \ gstvaapisurfaceproxy.h \ gstvaapitexture.h \ diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index 26addfaa18..485d555f74 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -21,6 +21,8 @@ */ #include "sysdeps.h" +#include +#include "gstvaapicompat.h" #include "gstvaapibufferproxy.h" #include "gstvaapibufferproxy_priv.h" #include "gstvaapiutils.h" @@ -40,6 +42,9 @@ from_GstVaapiBufferMemoryType (guint type) guint va_type; switch (type) { + case GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF: + va_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; + break; default: va_type = 0; break; @@ -53,6 +58,9 @@ to_GstVaapiBufferMemoryType (guint va_type) guint type; switch (va_type) { + case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: + type = GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF; + break; default: type = 0; break; diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.h b/gst-libs/gst/vaapi/gstvaapibufferproxy.h index 147157ddf5..3a92a2c800 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.h @@ -57,6 +57,16 @@ G_BEGIN_DECLS typedef struct _GstVaapiBufferProxy GstVaapiBufferProxy; +/** + * GstVaapiBufferMemoryType: + * @GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF: DRM PRIME buffer memory type. + * + * Set of underlying VA buffer memory types. + */ +typedef enum { + GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF = 1, +} GstVaapiBufferMemoryType; + GstVaapiBufferProxy * gst_vaapi_buffer_proxy_new (guintptr handle, guint type, gsize size, GDestroyNotify destroy_func, gpointer user_data); diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c new file mode 100644 index 0000000000..117ad390d0 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -0,0 +1,77 @@ +/* + * gstvaapisurface_drm.c - VA surface abstraction (DRM interop) + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 "gstvaapisurface_drm.h" +#include "gstvaapisurface_priv.h" +#include "gstvaapiimage_priv.h" +#include "gstvaapibufferproxy_priv.h" + +static GstVaapiBufferProxy * +gst_vaapi_surface_get_drm_buf_handle (GstVaapiSurface * surface, guint type) +{ + GstVaapiBufferProxy *proxy; + GstVaapiImage *image; + + image = gst_vaapi_surface_derive_image (surface); + if (!image) + goto error_derive_image; + + proxy = + gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), + image->internal_image.buf, type, gst_vaapi_object_unref, image); + if (!proxy) + goto error_alloc_export_buffer; + return proxy; + + /* ERRORS */ +error_derive_image: + GST_ERROR ("failed to extract image handle from surface"); + return NULL; +error_alloc_export_buffer: + GST_ERROR ("failed to allocate export buffer proxy"); + gst_vaapi_object_unref (image); + return NULL; +} + +/** + * gst_vaapi_surface_get_dma_buf_handle: + * @surface: a #GstVaapiSurface + * + * If the underlying VA driver implementation supports it, this + * function allows for returning a suitable dma_buf (DRM) buffer + * handle as a #GstVaapiBufferProxy instance. The resulting buffer + * handle is live until the last reference to the proxy gets + * released. Besides, any further change to the parent VA @surface may + * fail. + * + * Return value: the underlying buffer as a #GstVaapiBufferProxy + * instance. + */ +GstVaapiBufferProxy * +gst_vaapi_surface_get_dma_buf_handle (GstVaapiSurface * surface) +{ + g_return_val_if_fail (surface != NULL, NULL); + + return gst_vaapi_surface_get_drm_buf_handle (surface, + GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF); +} diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.h b/gst-libs/gst/vaapi/gstvaapisurface_drm.h new file mode 100644 index 0000000000..90a5ebb5c2 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.h @@ -0,0 +1,36 @@ +/* + * gstvaapisurface_drm.h - VA surface abstraction (DRM interop) + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_SURFACE_DRM_H +#define GST_VAAPI_SURFACE_DRM_H + +#include +#include + +G_BEGIN_DECLS + +GstVaapiBufferProxy * +gst_vaapi_surface_get_dma_buf_handle (GstVaapiSurface * surface); + +G_END_DECLS + +#endif /* GST_VAAPI_SURFACE_DRM_H */ From f3c58d4ef4c2edb776bdd554502ecec8eed21044 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Sep 2014 13:47:53 +0200 Subject: [PATCH 1852/3781] surface: add support for GEM buffer exports. Add support for GEM buffer exports. This will only work with VA drivers based off libdrm, e.g. the Intel HD Graphics VA driver. This is needed to support interop with EGL and the "Desktop" GL specification. Indeed, the EXT_image_dma_buf_import extension is not going to be supported in Desktop GL, due to the lack of support for GL_TEXTURE_EXTERNAL_OES targets there. This is useful for implementing VA/EGL interop with legacy Mesa stacks, in Desktop OpenGL context. https://bugzilla.gnome.org/show_bug.cgi?id=736717 --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 6 ++++++ gst-libs/gst/vaapi/gstvaapibufferproxy.h | 2 ++ gst-libs/gst/vaapi/gstvaapisurface_drm.c | 22 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface_drm.h | 3 +++ 4 files changed, 33 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index 485d555f74..22e17f2a96 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -45,6 +45,9 @@ from_GstVaapiBufferMemoryType (guint type) case GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF: va_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; break; + case GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF: + va_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; + break; default: va_type = 0; break; @@ -61,6 +64,9 @@ to_GstVaapiBufferMemoryType (guint va_type) case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: type = GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF; break; + case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: + type = GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF; + break; default: type = 0; break; diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.h b/gst-libs/gst/vaapi/gstvaapibufferproxy.h index 3a92a2c800..a70d33f419 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.h @@ -60,11 +60,13 @@ typedef struct _GstVaapiBufferProxy GstVaapiBufferProxy; /** * GstVaapiBufferMemoryType: * @GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF: DRM PRIME buffer memory type. + * @GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF: Kernel DRM buffer memory type. * * Set of underlying VA buffer memory types. */ typedef enum { GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF = 1, + GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF, } GstVaapiBufferMemoryType; GstVaapiBufferProxy * diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index 117ad390d0..bebbea1eaf 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -75,3 +75,25 @@ gst_vaapi_surface_get_dma_buf_handle (GstVaapiSurface * surface) return gst_vaapi_surface_get_drm_buf_handle (surface, GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF); } + +/** + * gst_vaapi_surface_get_gem_buf_handle: + * @surface: a #GstVaapiSurface + * + * If the underlying VA driver implementation supports it, this + * function allows for returning a suitable GEM buffer handle as a + * #GstVaapiBufferProxy instance. The resulting buffer handle is live + * until the last reference to the proxy gets released. Besides, any + * further change to the parent VA @surface may fail. + * + * Return value: the underlying buffer as a #GstVaapiBufferProxy + * instance. + */ +GstVaapiBufferProxy * +gst_vaapi_surface_get_gem_buf_handle (GstVaapiSurface * surface) +{ + g_return_val_if_fail (surface != NULL, NULL); + + return gst_vaapi_surface_get_drm_buf_handle (surface, + GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF); +} diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.h b/gst-libs/gst/vaapi/gstvaapisurface_drm.h index 90a5ebb5c2..cfbccbe11c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.h @@ -31,6 +31,9 @@ G_BEGIN_DECLS GstVaapiBufferProxy * gst_vaapi_surface_get_dma_buf_handle (GstVaapiSurface * surface); +GstVaapiBufferProxy * +gst_vaapi_surface_get_gem_buf_handle (GstVaapiSurface * surface); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_DRM_H */ From dd37fc4999bea6afd8b85846491d7f35ec2befda Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 27 Jan 2015 11:19:58 +0100 Subject: [PATCH 1853/3781] surface: add initial support for foreign buffer imports. Add gst_vaapi_surface_new_from_buffer_proxy() helper function to create a VA surface from an external buffer provided throug the new GstVaapiBufferProxy object. --- gst-libs/gst/vaapi/gstvaapisurface.c | 130 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 5 + gst-libs/gst/vaapi/gstvaapisurface_priv.h | 1 + 3 files changed, 136 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index d3496d462b..27438cc870 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -36,6 +36,7 @@ #include "gstvaapiimage.h" #include "gstvaapiimage_priv.h" #include "gstvaapicontext_overlay.h" +#include "gstvaapibufferproxy_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -89,6 +90,7 @@ gst_vaapi_surface_destroy (GstVaapiSurface * surface) GST_VAAPI_ID_ARGS (surface_id)); GST_VAAPI_OBJECT_ID (surface) = VA_INVALID_SURFACE; } + gst_vaapi_buffer_proxy_replace (&surface->extbuf_proxy, NULL); } static gboolean @@ -219,6 +221,95 @@ error_unsupported_format: #endif } +static gboolean +gst_vaapi_surface_create_from_buffer_proxy (GstVaapiSurface * surface, + GstVaapiBufferProxy * proxy, const GstVideoInfo * vip) +{ +#if VA_CHECK_VERSION (0,34,0) + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); + GstVideoFormat format; + VASurfaceID surface_id; + VAStatus status; + guint chroma_type, va_chroma_format; + const VAImageFormat *va_format; + VASurfaceAttrib attribs[2], *attrib; + VASurfaceAttribExternalBuffers extbuf; + unsigned long extbuf_handle; + guint i, width, height; + + format = GST_VIDEO_INFO_FORMAT (vip); + width = GST_VIDEO_INFO_WIDTH (vip); + height = GST_VIDEO_INFO_HEIGHT (vip); + + gst_vaapi_buffer_proxy_replace (&surface->extbuf_proxy, proxy); + + va_format = gst_vaapi_video_format_to_va_format (format); + if (!va_format) + goto error_unsupported_format; + + chroma_type = gst_vaapi_video_format_get_chroma_type (format); + if (!chroma_type) + goto error_unsupported_format; + + va_chroma_format = from_GstVaapiChromaType (chroma_type); + if (!va_chroma_format) + goto error_unsupported_format; + + extbuf_handle = GST_VAAPI_BUFFER_PROXY_HANDLE (proxy); + extbuf.pixel_format = va_format->fourcc; + extbuf.width = width; + extbuf.height = height; + extbuf.data_size = GST_VAAPI_BUFFER_PROXY_SIZE (proxy); + extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vip); + for (i = 0; i < extbuf.num_planes; i++) { + extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vip, i); + extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vip, i); + } + extbuf.buffers = &extbuf_handle; + extbuf.num_buffers = 1; + extbuf.flags = 0; + extbuf.private_data = NULL; + + attrib = attribs; + attrib->type = VASurfaceAttribExternalBufferDescriptor; + attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; + attrib->value.type = VAGenericValueTypePointer; + attrib->value.value.p = &extbuf; + attrib++; + attrib->type = VASurfaceAttribMemoryType; + attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; + attrib->value.type = VAGenericValueTypeInteger; + attrib->value.value.i = + from_GstVaapiBufferMemoryType (GST_VAAPI_BUFFER_PROXY_TYPE (proxy)); + attrib++; + + GST_VAAPI_DISPLAY_LOCK (display); + status = vaCreateSurfaces (GST_VAAPI_DISPLAY_VADISPLAY (display), + va_chroma_format, width, height, &surface_id, 1, attribs, + attrib - attribs); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaCreateSurfaces()")) + return FALSE; + + surface->format = format; + surface->chroma_type = chroma_type; + surface->width = width; + surface->height = height; + + GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); + GST_VAAPI_OBJECT_ID (surface) = surface_id; + return TRUE; + + /* ERRORS */ +error_unsupported_format: + GST_ERROR ("unsupported format %s", + gst_vaapi_video_format_to_string (format)); + return FALSE; +#else + return FALSE; +#endif +} + #define gst_vaapi_surface_finalize gst_vaapi_surface_destroy GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSurface, gst_vaapi_surface); @@ -315,6 +406,45 @@ gst_vaapi_surface_new_with_format (GstVaapiDisplay * display, return gst_vaapi_surface_new_full (display, &vi, 0); } +/** + * gst_vaapi_surface_new_from_buffer_proxy: + * @display: a #GstVaapiDisplay + * @proxy: a #GstVaapiBufferProxy + * @info: the #GstVideoInfo structure defining the layout of the buffer + * + * Creates a new #GstVaapiSurface with the supplied VA buffer proxy + * abstraction. The underlying VA buffer memory type could be anything + * that is supported by the VA driver. + * + * The resulting #GstVaapiSurface object owns an extra reference to + * the buffer @proxy, so the caller can safely release that handle as + * early as on return of this call. + * + * Return value: the newly allocated #GstVaapiSurface object, or %NULL + * if creation of VA surface failed or is not supported + */ +GstVaapiSurface * +gst_vaapi_surface_new_from_buffer_proxy (GstVaapiDisplay * display, + GstVaapiBufferProxy * proxy, const GstVideoInfo * info) +{ + GstVaapiSurface *surface; + + g_return_val_if_fail (proxy != NULL, NULL); + g_return_val_if_fail (info != NULL, NULL); + + surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); + if (!surface) + return NULL; + + if (!gst_vaapi_surface_create_from_buffer_proxy (surface, proxy, info)) + goto error; + return surface; + +error: + gst_vaapi_object_unref (surface); + return NULL; +} + /** * gst_vaapi_surface_get_id: * @surface: a #GstVaapiSurface diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 6317720ca5..50e6d04347 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -178,6 +179,10 @@ GstVaapiSurface * gst_vaapi_surface_new_with_format (GstVaapiDisplay * display, GstVideoFormat format, guint width, guint height); +GstVaapiSurface * +gst_vaapi_surface_new_from_buffer_proxy (GstVaapiDisplay * display, + GstVaapiBufferProxy * proxy, const GstVideoInfo * vip); + GstVaapiID gst_vaapi_surface_get_id (GstVaapiSurface * surface); diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index dc5663cce8..4ac1e0c1c5 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -41,6 +41,7 @@ struct _GstVaapiSurface /*< private >*/ GstVaapiObject parent_instance; + GstVaapiBufferProxy *extbuf_proxy; GstVideoFormat format; guint width; guint height; From 011f9bd6cbdacc8b4cc8546aa24f505d3fa17a08 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Sep 2014 15:25:09 +0200 Subject: [PATCH 1854/3781] surface: add support for dma_buf imports. Add new gst_vaapi_surface_new_with_dma_buf_handle() helper function to allow for creating VA surfaces from a foreign DRM PRIME fd. The resulting VA surface owns the supplied buffer handle. https://bugzilla.gnome.org/show_bug.cgi?id=735362 --- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 53 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface_drm.h | 5 +++ 2 files changed, 58 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index bebbea1eaf..d0898a521c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -97,3 +97,56 @@ gst_vaapi_surface_get_gem_buf_handle (GstVaapiSurface * surface) return gst_vaapi_surface_get_drm_buf_handle (surface, GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF); } + +static void +fill_video_info (GstVideoInfo * vip, GstVideoFormat format, guint width, + guint height, gsize offset[GST_VIDEO_MAX_PLANES], + gint stride[GST_VIDEO_MAX_PLANES]) +{ + guint i; + + gst_video_info_init (vip); + gst_video_info_set_format (vip, format, width, height); + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (vip); i++) { + GST_VIDEO_INFO_PLANE_OFFSET (vip, i) = offset[i]; + GST_VIDEO_INFO_PLANE_STRIDE (vip, i) = stride[i]; + } +} + +/** + * gst_vaapi_surface_new_with_dma_buf_handle: + * @display: a #GstVaapiDisplay + * @fd: the DRM PRIME file descriptor + * @size: the underlying DRM buffer size + * @format: the desired surface format + * @width: the desired surface width in pixels + * @height: the desired surface height in pixels + * @offset: the offsets to each plane + * @stride: the pitches for each plane + * + * Creates a new #GstVaapiSurface with an external DRM PRIME file + * descriptor. The newly created VA surfaces owns the supplied buffer + * handle. + * + * Return value: the newly allocated #GstVaapiSurface object, or %NULL + * if creation from DRM PRIME fd failed, or is not supported + */ +GstVaapiSurface * +gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, + gint fd, guint size, GstVideoFormat format, guint width, guint height, + gsize offset[GST_VIDEO_MAX_PLANES], gint stride[GST_VIDEO_MAX_PLANES]) +{ + GstVaapiBufferProxy *proxy; + GstVaapiSurface *surface; + GstVideoInfo vi; + + proxy = gst_vaapi_buffer_proxy_new ((gintptr) fd, + GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF, size, NULL, NULL); + if (!proxy) + return NULL; + + fill_video_info (&vi, format, width, height, offset, stride); + surface = gst_vaapi_surface_new_from_buffer_proxy (display, proxy, &vi); + gst_vaapi_buffer_proxy_unref (proxy); + return surface; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.h b/gst-libs/gst/vaapi/gstvaapisurface_drm.h index cfbccbe11c..eee010c520 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.h @@ -34,6 +34,11 @@ gst_vaapi_surface_get_dma_buf_handle (GstVaapiSurface * surface); GstVaapiBufferProxy * gst_vaapi_surface_get_gem_buf_handle (GstVaapiSurface * surface); +GstVaapiSurface * +gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, + gint fd, guint size, GstVideoFormat format, guint width, guint height, + gsize offset[GST_VIDEO_MAX_PLANES], gint stride[GST_VIDEO_MAX_PLANES]); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_DRM_H */ From 797632139ff73bdd6676f94cba043de7a41dd1be Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 15 Sep 2014 15:27:50 +0200 Subject: [PATCH 1855/3781] surface: add support for GEM buffer imports. Add support for GEM buffer imports. This is useful for VA/EGL interop with legacy Mesa implementations, or when it is desired or required to support outbound textures for instance. https://bugzilla.gnome.org/show_bug.cgi?id=736718 --- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 38 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface_drm.h | 5 ++++ 2 files changed, 43 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index d0898a521c..1a2ba20d28 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -150,3 +150,41 @@ gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, gst_vaapi_buffer_proxy_unref (proxy); return surface; } + +/** + * gst_vaapi_surface_new_with_dma_buf_handle: + * @display: a #GstVaapiDisplay + * @name: the DRM GEM buffer name + * @size: the underlying DRM buffer size + * @format: the desired surface format + * @width: the desired surface width in pixels + * @height: the desired surface height in pixels + * @offset: the offsets to each plane + * @stride: the pitches for each plane + * + * Creates a new #GstVaapiSurface with an external DRM GEM buffer + * name. The newly created VA surfaces owns the supplied buffer + * handle. + * + * Return value: the newly allocated #GstVaapiSurface object, or %NULL + * if creation from DRM PRIME fd failed, or is not supported + */ +GstVaapiSurface * +gst_vaapi_surface_new_with_gem_buf_handle (GstVaapiDisplay * display, + guint32 name, guint size, GstVideoFormat format, guint width, guint height, + gsize offset[GST_VIDEO_MAX_PLANES], gint stride[GST_VIDEO_MAX_PLANES]) +{ + GstVaapiBufferProxy *proxy; + GstVaapiSurface *surface; + GstVideoInfo vi; + + proxy = gst_vaapi_buffer_proxy_new ((guintptr) name, + GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF, size, NULL, NULL); + if (!proxy) + return NULL; + + fill_video_info (&vi, format, width, height, offset, stride); + surface = gst_vaapi_surface_new_from_buffer_proxy (display, proxy, &vi); + gst_vaapi_buffer_proxy_unref (proxy); + return surface; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.h b/gst-libs/gst/vaapi/gstvaapisurface_drm.h index eee010c520..5073f55641 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.h @@ -39,6 +39,11 @@ gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, gint fd, guint size, GstVideoFormat format, guint width, guint height, gsize offset[GST_VIDEO_MAX_PLANES], gint stride[GST_VIDEO_MAX_PLANES]); +GstVaapiSurface * +gst_vaapi_surface_new_with_gem_buf_handle (GstVaapiDisplay * display, + guint32 name, guint size, GstVideoFormat format, guint width, guint height, + gsize offset[GST_VIDEO_MAX_PLANES], gint stride[GST_VIDEO_MAX_PLANES]); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_DRM_H */ From 667749c67e86413ebbe5e51647df6603a3f2dc26 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Thu, 23 Jan 2014 05:00:09 -0500 Subject: [PATCH 1856/3781] plugins: add support for dma_buf imports. Allow imports of v4l2 buffers into VA surfaces for further operation with vaapi plugins, e.g. vaapipostproc or vaapiencode_* elements. https://bugzilla.gnome.org/show_bug.cgi?id=735362 [fixed memory leaks, ported to new dma_buf infrastructure, cleanups] Signed-off-by: Gwenole Beauchesne --- configure.ac | 4 ++ gst/vaapi/Makefile.am | 4 +- gst/vaapi/gstvaapipluginbase.c | 111 +++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index cbe9962f1b..92e25a6d05 100644 --- a/configure.ac +++ b/configure.ac @@ -305,6 +305,10 @@ PKG_CHECK_MODULES([GST_INTERFACES], [gstreamer-interfaces-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) fi +dnl ... gst_dmabuf_memory_get_fd (gstreamer-allocators) +PKG_CHECK_MODULES([GST_ALLOCATORS], + [gstreamer-allocators-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], [gstreamer-video-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 58800db59c..ffaa26bac4 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -150,7 +150,8 @@ libgstvaapi_la_CFLAGS = \ $(GST_VIDEO_CFLAGS) \ $(GST_INTERFACES_CFLAGS) \ $(GST_BASEVIDEO_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) + $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_ALLOCATORS_CFLAGS) libgstvaapi_la_LIBADD = \ $(libgstvaapi_LIBS) \ @@ -160,6 +161,7 @@ libgstvaapi_la_LIBADD = \ $(GST_INTERFACES_LIBS) \ $(GST_BASEVIDEO_LIBS) \ $(GST_PLUGINS_BASE_LIBS) \ + $(GST_ALLOCATORS_LIBS) \ $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 922260fa61..1a254060a1 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -23,6 +23,7 @@ */ #include "gst/vaapi/sysdeps.h" +#include #include "gstvaapipluginbase.h" #include "gstvaapipluginutil.h" #include "gstvaapivideocontext.h" @@ -30,6 +31,9 @@ #if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" #endif +#if GST_CHECK_VERSION(1,1,0) +#include +#endif /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) @@ -127,6 +131,98 @@ default_display_changed (GstVaapiPluginBase * plugin) { } +static gboolean +plugin_update_sinkpad_info_from_buffer (GstVaapiPluginBase * plugin, + GstBuffer * buf) +{ + GstVideoInfo *const vip = &plugin->sinkpad_info; + GstVideoMeta *vmeta; + guint i; + + vmeta = gst_buffer_get_video_meta (buf); + if (!vmeta) + return TRUE; + + if (GST_VIDEO_INFO_FORMAT (vip) != vmeta->format || + GST_VIDEO_INFO_WIDTH (vip) != vmeta->width || + GST_VIDEO_INFO_HEIGHT (vip) != vmeta->height || + GST_VIDEO_INFO_N_PLANES (vip) != vmeta->n_planes) + return FALSE; + + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (vip); ++i) { + GST_VIDEO_INFO_PLANE_OFFSET (vip, i) = vmeta->offset[i]; + GST_VIDEO_INFO_PLANE_STRIDE (vip, i) = vmeta->stride[i]; + } + GST_VIDEO_INFO_SIZE (vip) = gst_buffer_get_size (buf); + return TRUE; +} + +#if GST_CHECK_VERSION(1,1,0) +static gboolean +is_dma_buffer (GstBuffer * buf) +{ + GstMemory *mem; + + if (gst_buffer_n_memory (buf) < 1) + return FALSE; + + mem = gst_buffer_peek_memory (buf, 0); + if (!mem || !gst_is_dmabuf_memory (mem)) + return FALSE; + return TRUE; +} + +static gboolean +plugin_bind_dma_to_vaapi_buffer (GstVaapiPluginBase * plugin, + GstBuffer * inbuf, GstBuffer * outbuf) +{ + GstVideoInfo *const vip = &plugin->sinkpad_info; + GstVaapiVideoMeta *meta; + GstVaapiSurface *surface; + GstVaapiSurfaceProxy *proxy; + gint fd; + + fd = gst_dmabuf_memory_get_fd (gst_buffer_peek_memory (inbuf, 0)); + if (fd < 0) + return FALSE; + + if (!plugin_update_sinkpad_info_from_buffer (plugin, inbuf)) + goto error_update_sinkpad_info; + + meta = gst_buffer_get_vaapi_video_meta (outbuf); + g_return_val_if_fail (meta != NULL, FALSE); + + surface = gst_vaapi_surface_new_with_dma_buf_handle (plugin->display, fd, + GST_VIDEO_INFO_SIZE (vip), GST_VIDEO_INFO_FORMAT (vip), + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip), + vip->offset, vip->stride); + if (!surface) + goto error_create_surface; + + proxy = gst_vaapi_surface_proxy_new (surface); + gst_vaapi_object_unref (surface); + if (!proxy) + goto error_create_proxy; + + gst_vaapi_surface_proxy_set_destroy_notify (proxy, + (GDestroyNotify) gst_buffer_unref, (gpointer) gst_buffer_ref (inbuf)); + gst_vaapi_video_meta_set_surface_proxy (meta, proxy); + gst_vaapi_surface_proxy_unref (proxy); + return TRUE; + + /* ERRORS */ +error_update_sinkpad_info: + GST_ERROR ("failed to update sink pad video info from video meta"); + return FALSE; +error_create_surface: + GST_ERROR ("failed to create VA surface from dma_buf handle"); + return FALSE; +error_create_proxy: + GST_ERROR ("failed to create VA surface proxy from wrapped VA surface"); + return FALSE; +} +#endif + void gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) { @@ -686,6 +782,14 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, &outbuf, NULL) != GST_FLOW_OK) goto error_create_buffer; +#if GST_CHECK_VERSION(1,1,0) + if (is_dma_buffer (inbuf)) { + if (!plugin_bind_dma_to_vaapi_buffer (plugin, inbuf, outbuf)) + goto error_bind_dma_buffer; + goto done; + } +#endif + if (!gst_video_frame_map (&src_frame, &plugin->sinkpad_info, inbuf, GST_MAP_READ)) goto error_map_src_buffer; @@ -700,6 +804,7 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, if (!success) goto error_copy_buffer; +done: gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1); *outbuf_ptr = outbuf; @@ -758,6 +863,12 @@ error_create_buffer: GST_ERROR ("failed to create buffer"); return GST_FLOW_ERROR; } +error_bind_dma_buffer: + { + GST_ERROR ("failed to bind dma_buf to VA surface buffer"); + gst_buffer_unref (outbuf); + return GST_FLOW_ERROR; + } error_copy_buffer: { GST_WARNING ("failed to upload buffer to VA surface"); From 82fc406dfda4d477396c1396d0cf2d03b4417d6a Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 26 Jan 2015 18:30:47 +0100 Subject: [PATCH 1857/3781] plugins: add support for dma_buf exports (v4l2src). Allow v4l2src element to connected to vaapipostproc or vaapisink when "io-mode" is set to "dmabuf-import". In practice, this is a more likely operational mode with uvcvideo. Supporting v4lsrc with "io-mode" set to "dmabuf" could work, but with more demanding driver or kernel reqs. Note: with GStreamer 1.4, v4l2src (gst-plugins-good) needs to be built with --without-libv4l2. https://bugzilla.gnome.org/show_bug.cgi?id=743635 --- gst/vaapi/gstvaapipluginbase.c | 52 ++++++ gst/vaapi/gstvaapivideobufferpool.c | 56 ++++-- gst/vaapi/gstvaapivideobufferpool.h | 11 ++ gst/vaapi/gstvaapivideomemory.c | 263 ++++++++++++++++++++++++++++ gst/vaapi/gstvaapivideomemory.h | 33 ++++ 5 files changed, 405 insertions(+), 10 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 1a254060a1..ca681aa3f9 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -24,6 +24,7 @@ #include "gst/vaapi/sysdeps.h" #include +#include #include "gstvaapipluginbase.h" #include "gstvaapipluginutil.h" #include "gstvaapivideocontext.h" @@ -392,6 +393,42 @@ gst_vaapi_plugin_base_ensure_uploader (GstVaapiPluginBase * plugin) return TRUE; } +/* Checks whether the supplied pad peer element supports DMABUF sharing */ +/* XXX: this is a workaround to the absence of any proposer way to + specify DMABUF memory capsfeatures or bufferpool option to downstream */ +static gboolean +has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad) +{ + GstPad *other_pad = NULL; + GstElement *element = NULL; + gchar *element_name = NULL; + gboolean is_dmabuf_capable = FALSE; + gint v; + + do { + other_pad = gst_pad_get_peer (pad); + if (!other_pad) + break; + + element = gst_pad_get_parent_element (other_pad); + if (!element || !GST_IS_PUSH_SRC (element)) + break; + + element_name = gst_element_get_name (element); + if (!element_name || sscanf (element_name, "v4l2src%d", &v) != 1) + break; + + v = 0; + g_object_get (element, "io-mode", &v, NULL); + is_dmabuf_capable = v == 5; /* "dmabuf-import" enum value */ + } while (0); + + g_free (element_name); + g_clear_object (&element); + g_clear_object (&other_pad); + return is_dmabuf_capable; +} + /** * ensure_sinkpad_buffer_pool: * @plugin: a #GstVaapiPluginBase @@ -536,6 +573,16 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, return FALSE; gst_query_add_allocation_pool (query, plugin->sinkpad_buffer_pool, plugin->sinkpad_buffer_size, 0, 0); + + if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) { + GstStructure *const config = + gst_buffer_pool_get_config (plugin->sinkpad_buffer_pool); + + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_DMABUF_MEMORY); + if (!gst_buffer_pool_set_config (plugin->sinkpad_buffer_pool, config)) + goto error_pool_config; + } } gst_query_add_allocation_meta (query, GST_VAAPI_VIDEO_META_API_TYPE, NULL); @@ -548,6 +595,11 @@ error_no_caps: GST_ERROR ("no caps specified"); return FALSE; } +error_pool_config: + { + GST_ERROR ("failed to reset buffer pool config"); + return FALSE; + } } #endif diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 84be8e3058..56295ba3b7 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -46,10 +46,12 @@ struct _GstVaapiVideoBufferPoolPrivate GstVideoInfo video_info[2]; guint video_info_index; GstAllocator *allocator; + GstVideoInfo alloc_info; GstVaapiDisplay *display; guint has_video_meta:1; guint has_video_alignment:1; guint has_texture_upload_meta:1; + guint use_dmabuf_memory:1; }; #define GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(obj) \ @@ -105,8 +107,7 @@ gst_vaapi_video_buffer_pool_get_property (GObject * object, guint prop_id, static void fill_video_alignment (GstVaapiVideoBufferPool * pool, GstVideoAlignment * align) { - GstVideoInfo *const vip = - &GST_VAAPI_VIDEO_ALLOCATOR_CAST (pool->priv->allocator)->image_info; + GstVideoInfo *const vip = &pool->priv->alloc_info; guint i; gst_video_alignment_reset (align); @@ -140,26 +141,48 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, GstVideoInfo *const new_vip = &priv->video_info[!priv->video_info_index]; GstVideoAlignment align; GstAllocator *allocator; - gboolean changed_caps; + gboolean changed_caps, use_dmabuf_memory; if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) goto error_invalid_config; if (!caps || !gst_video_info_from_caps (new_vip, caps)) goto error_no_caps; + use_dmabuf_memory = gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_DMABUF_MEMORY); + if (priv->use_dmabuf_memory != use_dmabuf_memory) { + priv->use_dmabuf_memory = use_dmabuf_memory; + g_clear_object (&priv->allocator); + } + changed_caps = !priv->allocator || GST_VIDEO_INFO_FORMAT (cur_vip) != GST_VIDEO_INFO_FORMAT (new_vip) || GST_VIDEO_INFO_WIDTH (cur_vip) != GST_VIDEO_INFO_WIDTH (new_vip) || GST_VIDEO_INFO_HEIGHT (cur_vip) != GST_VIDEO_INFO_HEIGHT (new_vip); if (changed_caps) { - allocator = gst_vaapi_video_allocator_new (priv->display, new_vip, 0); + const GstVideoInfo *alloc_vip; + guint flags = 0; + + if (use_dmabuf_memory) { + /* XXX: also needs fixed strides/offsets */ + flags |= GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE; + allocator = + gst_vaapi_dmabuf_allocator_new (priv->display, new_vip, flags); + } else { + allocator = gst_vaapi_video_allocator_new (priv->display, new_vip, 0); + } if (!allocator) goto error_create_allocator; gst_object_replace ((GstObject **) & priv->allocator, GST_OBJECT_CAST (allocator)); gst_object_unref (allocator); priv->video_info_index ^= 1; + + alloc_vip = gst_allocator_get_vaapi_video_info (allocator, NULL); + if (!alloc_vip) + goto error_create_allocator_info; + priv->alloc_info = *alloc_vip; } if (!gst_buffer_pool_config_has_option (config, @@ -199,6 +222,11 @@ error_create_allocator: GST_ERROR ("failed to create GstVaapiVideoAllocator object"); return FALSE; } +error_create_allocator_info: + { + GST_ERROR ("failed to create GstVaapiVideoAllocator `video-info'"); + return FALSE; + } error_no_vaapi_video_meta_option: { GST_ERROR ("no GstVaapiVideoMeta option"); @@ -235,15 +263,17 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, if (!buffer) goto error_create_buffer; - mem = gst_vaapi_video_memory_new (priv->allocator, meta); + if (priv->use_dmabuf_memory) + mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta); + else + mem = gst_vaapi_video_memory_new (priv->allocator, meta); if (!mem) goto error_create_memory; gst_vaapi_video_meta_replace (&meta, NULL); gst_buffer_append_memory (buffer, mem); if (priv->has_video_meta) { - GstVideoInfo *const vip = - &GST_VAAPI_VIDEO_ALLOCATOR_CAST (priv->allocator)->image_info; + GstVideoInfo *const vip = &priv->alloc_info; GstVideoMeta *vmeta; vmeta = gst_buffer_add_video_meta_full (buffer, 0, @@ -251,9 +281,13 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, GST_VIDEO_INFO_HEIGHT (vip), GST_VIDEO_INFO_N_PLANES (vip), &GST_VIDEO_INFO_PLANE_OFFSET (vip, 0), &GST_VIDEO_INFO_PLANE_STRIDE (vip, 0)); - vmeta->map = gst_video_meta_map_vaapi_memory; - vmeta->unmap = gst_video_meta_unmap_vaapi_memory; + + if (GST_VAAPI_IS_VIDEO_MEMORY (mem)) { + vmeta->map = gst_video_meta_map_vaapi_memory; + vmeta->unmap = gst_video_meta_unmap_vaapi_memory; + } } + #if GST_CHECK_VERSION(1,1,0) && USE_GLX if (priv->has_texture_upload_meta) gst_buffer_add_texture_upload_meta (buffer); @@ -295,7 +329,8 @@ gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool, GstMemory *const mem = gst_buffer_peek_memory (buffer, 0); /* Release the underlying surface proxy */ - gst_vaapi_video_memory_reset_surface (GST_VAAPI_VIDEO_MEMORY_CAST (mem)); + if (GST_VAAPI_IS_VIDEO_MEMORY (mem)) + gst_vaapi_video_memory_reset_surface (GST_VAAPI_VIDEO_MEMORY_CAST (mem)); GST_BUFFER_POOL_CLASS (gst_vaapi_video_buffer_pool_parent_class)->reset_buffer (pool, buffer); @@ -344,6 +379,7 @@ gst_vaapi_video_buffer_pool_init (GstVaapiVideoBufferPool * pool) gst_video_info_init (&priv->video_info[0]); gst_video_info_init (&priv->video_info[1]); + gst_video_info_init (&priv->alloc_info); } GstBufferPool * diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index 7ced82bade..1ff3f57b7a 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -69,6 +69,17 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; "GstBufferPoolOptionVideoGLTextureUploadMeta" #endif +/** + * GST_BUFFER_POOL_OPTION_DMABUF_MEMORY: + * + * An option that can be activated on bufferpool to request dmabuf + * handles on buffers from the pool. + */ +#ifndef GST_BUFFER_POOL_OPTION_DMABUF_MEMORY +#define GST_BUFFER_POOL_OPTION_DMABUF_MEMORY \ + "GstBufferPoolOptionDMABUFMemory" +#endif + /** * GstVaapiVideoBufferPoolAcquireFlags: * @GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC: option to diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 33674f5e8a..04b49f247e 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -21,6 +21,7 @@ */ #include "gst/vaapi/sysdeps.h" +#include #include #include #include "gstvaapivideomemory.h" @@ -298,6 +299,8 @@ gst_vaapi_video_memory_new (GstAllocator * base_allocator, const GstVideoInfo *vip; GstVaapiVideoMemory *mem; + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (allocator), NULL); + mem = g_slice_new (GstVaapiVideoMemory); if (!mem) return NULL; @@ -725,6 +728,9 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display, &allocator->image_info); if (!allocator->image_pool) goto error_create_image_pool; + + gst_allocator_set_vaapi_video_info (GST_ALLOCATOR_CAST (allocator), + &allocator->image_info, 0); return GST_ALLOCATOR_CAST (allocator); /* ERRORS */ @@ -741,3 +747,260 @@ error_create_image_pool: return NULL; } } + +/* ------------------------------------------------------------------------ */ +/* --- GstVaapiDmaBufMemory --- */ +/* ------------------------------------------------------------------------ */ + +#define GST_VAAPI_BUFFER_PROXY_QUARK gst_vaapi_buffer_proxy_quark_get () +static GQuark +gst_vaapi_buffer_proxy_quark_get (void) +{ + static gsize g_quark; + + if (g_once_init_enter (&g_quark)) { + gsize quark = (gsize) g_quark_from_static_string ("GstVaapiBufferProxy"); + g_once_init_leave (&g_quark, quark); + } + return g_quark; +} + +GstMemory * +gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta) +{ + GstMemory *mem; + GstVaapiDisplay *display; + GstVaapiSurface *surface; + GstVaapiSurfaceProxy *proxy; + GstVaapiBufferProxy *dmabuf_proxy; + const GstVideoInfo *vip; + guint flags; + + g_return_val_if_fail (allocator != NULL, NULL); + g_return_val_if_fail (meta != NULL, NULL); + + vip = gst_allocator_get_vaapi_video_info (allocator, &flags); + if (!vip) + return NULL; + + display = gst_vaapi_video_meta_get_display (meta); + if (!meta) + return NULL; + + surface = gst_vaapi_surface_new_full (display, vip, flags); + if (!surface) + goto error_create_surface; + + proxy = gst_vaapi_surface_proxy_new (surface); + if (!proxy) + goto error_create_surface_proxy; + + dmabuf_proxy = gst_vaapi_surface_get_dma_buf_handle (surface); + gst_vaapi_object_unref (surface); + if (!dmabuf_proxy) + goto error_create_dmabuf_proxy; + + gst_vaapi_video_meta_set_surface_proxy (meta, proxy); + gst_vaapi_surface_proxy_unref (proxy); + + mem = gst_dmabuf_allocator_alloc (allocator, + gst_vaapi_buffer_proxy_get_handle (dmabuf_proxy), + gst_vaapi_buffer_proxy_get_size (dmabuf_proxy)); + if (!mem) + goto error_create_dmabuf_memory; + + gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem), + GST_VAAPI_BUFFER_PROXY_QUARK, dmabuf_proxy, + (GDestroyNotify) gst_vaapi_buffer_proxy_unref); + return mem; + + /* ERRORS */ +error_create_surface: + { + GST_ERROR ("failed to create VA surface (format:%s size:%ux%u)", + gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)), + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); + return NULL; + } +error_create_surface_proxy: + { + GST_ERROR ("failed to create VA surface proxy"); + gst_vaapi_object_unref (surface); + return NULL; + } +error_create_dmabuf_proxy: + { + GST_ERROR ("failed to export VA surface to DMABUF"); + gst_vaapi_surface_proxy_unref (proxy); + return NULL; + } +error_create_dmabuf_memory: + { + GST_ERROR ("failed to create DMABUF memory"); + gst_vaapi_buffer_proxy_unref (dmabuf_proxy); + return NULL; + } +} + +/* ------------------------------------------------------------------------ */ +/* --- GstVaapiDmaBufAllocator --- */ +/* ------------------------------------------------------------------------ */ + +GstAllocator * +gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, + const GstVideoInfo * vip, guint flags) +{ + GstAllocator *allocator = NULL; + GstVaapiSurface *surface = NULL; + GstVaapiImage *image = NULL; + GstVideoInfo alloc_info; + + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (vip != NULL, NULL); + + do { + surface = gst_vaapi_surface_new_full (display, vip, flags); + if (!surface) + break; + + image = gst_vaapi_surface_derive_image (surface); + if (!image || !gst_vaapi_image_map (image)) + break; + + gst_video_info_set_format (&alloc_info, GST_VIDEO_INFO_FORMAT (vip), + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); + gst_video_info_update_from_image (&alloc_info, image); + gst_vaapi_image_unmap (image); + + allocator = gst_dmabuf_allocator_new (); + if (!allocator) + break; + gst_allocator_set_vaapi_video_info (allocator, &alloc_info, flags); + } while (0); + + gst_vaapi_object_replace (&image, NULL); + gst_vaapi_object_replace (&surface, NULL); + return allocator; +} + +/* ------------------------------------------------------------------------ */ +/* --- GstVaapiVideoInfo = { GstVideoInfo, flags } --- */ +/* ------------------------------------------------------------------------ */ + +static GstVideoInfo * +gst_vaapi_video_info_copy (const GstVideoInfo * vip) +{ + GstVideoInfo *out_vip; + + out_vip = g_slice_new (GstVideoInfo); + if (!out_vip) + return NULL; + + gst_video_info_init (out_vip); + *out_vip = *vip; + return out_vip; +} + +static void +gst_vaapi_video_info_free (GstVideoInfo * vip) +{ + g_slice_free (GstVideoInfo, vip); +} + +#define GST_VAAPI_TYPE_VIDEO_INFO gst_vaapi_video_info_get_type () +static GType +gst_vaapi_video_info_get_type (void) +{ + static gsize g_type; + + if (g_once_init_enter (&g_type)) { + GType type; + type = g_boxed_type_register_static ("GstVaapiVideoInfo", + (GBoxedCopyFunc) gst_vaapi_video_info_copy, + (GBoxedFreeFunc) gst_vaapi_video_info_free); + g_once_init_leave (&g_type, type); + } + return (GType) g_type; +} + +#define GST_VAAPI_VIDEO_INFO_QUARK gst_vaapi_video_info_quark_get () +static GQuark +gst_vaapi_video_info_quark_get (void) +{ + static gsize g_quark; + + if (g_once_init_enter (&g_quark)) { + gsize quark = (gsize) g_quark_from_static_string ("GstVaapiVideoInfo"); + g_once_init_leave (&g_quark, quark); + } + return g_quark; +} + +#define INFO_QUARK info_quark_get () +static GQuark +info_quark_get (void) +{ + static gsize g_quark; + + if (g_once_init_enter (&g_quark)) { + gsize quark = (gsize) g_quark_from_static_string ("info"); + g_once_init_leave (&g_quark, quark); + } + return g_quark; +} + +#define FLAGS_QUARK flags_quark_get () +static GQuark +flags_quark_get (void) +{ + static gsize g_quark; + + if (g_once_init_enter (&g_quark)) { + gsize quark = (gsize) g_quark_from_static_string ("flags"); + g_once_init_leave (&g_quark, quark); + } + return g_quark; +} + +const GstVideoInfo * +gst_allocator_get_vaapi_video_info (GstAllocator * allocator, + guint * out_flags_ptr) +{ + const GstStructure *structure; + const GValue *value; + + g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), NULL); + + structure = + g_object_get_qdata (G_OBJECT (allocator), GST_VAAPI_VIDEO_INFO_QUARK); + if (!structure) + return NULL; + + if (out_flags_ptr) { + value = gst_structure_id_get_value (structure, FLAGS_QUARK); + if (!value) + return NULL; + *out_flags_ptr = g_value_get_uint (value); + } + + value = gst_structure_id_get_value (structure, INFO_QUARK); + if (!value) + return NULL; + return g_value_get_boxed (value); +} + +gboolean +gst_allocator_set_vaapi_video_info (GstAllocator * allocator, + const GstVideoInfo * vip, guint flags) +{ + g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), FALSE); + g_return_val_if_fail (vip != NULL, FALSE); + + g_object_set_qdata_full (G_OBJECT (allocator), GST_VAAPI_VIDEO_INFO_QUARK, + gst_structure_new_id (GST_VAAPI_VIDEO_INFO_QUARK, + INFO_QUARK, GST_VAAPI_TYPE_VIDEO_INFO, vip, + FLAGS_QUARK, G_TYPE_UINT, flags, NULL), + (GDestroyNotify) gst_structure_free); + + return TRUE; +} diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index ba29564a25..d3c6151a55 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -28,6 +28,9 @@ #include #include #include "gstvaapivideometa.h" +#if GST_CHECK_VERSION(1,1,0) +#include +#endif G_BEGIN_DECLS @@ -113,6 +116,10 @@ struct _GstVaapiVideoMemory gboolean use_direct_rendering; }; +G_GNUC_INTERNAL +GQuark +gst_vaapi_video_memory_quark_get (void); + G_GNUC_INTERNAL GstMemory * gst_vaapi_video_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta); @@ -189,6 +196,32 @@ GstAllocator * gst_vaapi_video_allocator_new (GstVaapiDisplay * display, const GstVideoInfo * vip, guint flags); +/* ------------------------------------------------------------------------ */ +/* --- GstVaapiDmaBufMemory --- */ +/* ------------------------------------------------------------------------ */ + +G_GNUC_INTERNAL +GstMemory * +gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, + GstVaapiVideoMeta * meta); + +/* ------------------------------------------------------------------------ */ +/* --- GstVaapiDmaBufAllocator --- */ +/* ------------------------------------------------------------------------ */ + +G_GNUC_INTERNAL +GstAllocator * +gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, + const GstVideoInfo * vip, guint flags); + +const GstVideoInfo * +gst_allocator_get_vaapi_video_info (GstAllocator * allocator, + guint * out_flags_ptr); + +gboolean +gst_allocator_set_vaapi_video_info (GstAllocator * allocator, + const GstVideoInfo * vip, guint flags); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_MEMORY_H */ From da6b88692f117537e61e607a831505aa4ef3d770 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 28 Jan 2015 18:09:40 +0100 Subject: [PATCH 1858/3781] plugins: drop leftover declaration. GstVaapiVideoMemory quark is not needed any more, and the actual implementation was already removed bfore the merge. i.e. this is an oversight for a hunk that was not meant to be pushed. --- gst/vaapi/gstvaapivideomemory.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index d3c6151a55..c38189fef2 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -116,10 +116,6 @@ struct _GstVaapiVideoMemory gboolean use_direct_rendering; }; -G_GNUC_INTERNAL -GQuark -gst_vaapi_video_memory_quark_get (void); - G_GNUC_INTERNAL GstMemory * gst_vaapi_video_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta); From b328e880fe6079f02932205a5b70e0d6f6a3f489 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 2 Feb 2015 11:43:58 +0200 Subject: [PATCH 1859/3781] Fix compilation error if there is no GL/gl.h header file installed --- gst/vaapi/gstvaapivideometa_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 1f605378fb..7a4efdfd5f 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -25,11 +25,11 @@ */ #include "gst/vaapi/sysdeps.h" -#include #include "gstvaapivideometa.h" #include "gstvaapipluginutil.h" #if USE_GLX +#include #include #endif From a49187ab397ca62b48c27d078de2138d0e9cd854 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 3 Feb 2015 10:00:23 +0200 Subject: [PATCH 1860/3781] NEWS: Updates --- NEWS | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index e412563cc4..339c668626 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,34 @@ -gst-vaapi NEWS -- summary of changes. 2014-07-29 +gst-vaapi NEWS -- summary of changes. 2015-02-03 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora +Version 0.5.10 - 3.Feb.2015 +* Add support for DRM Render-Nodes for headless operation +* Add support for VA surface buffer sharing with DMABUF and GEM handles +* Add support for v4l2src with io-mode={dmabuf,dmabuf-import} +* Drop support for VA/GLX specific APIs in libgstvaapi and vaapisink [#736711] +* Improvements to H.264 codecs + + Fix profile limits for encoding + + Fix pixel-aspect-ratio in the encoded stream + + Add decoding support for interlaced streams with repeat-first-field (RFF) + + Fix decoding of interlaced streams in top-field-first order (TFF) [#739291] + + Fix decoding of UK DVB-T2 streams [#739291] +* Improvements to plugin elements + + Add support for dma_buf imports (Wind Yuan) [#735362] + + Allow for SW decoding fallbacks with unsupported profiles [#730997] + + Make vaapipostproc work with SW elements (+Victor Jaquez) [#720174, #704078] + + Allow vaapipostproc to integrate with GL downstream elements [#735231] + + Add support for high-quality scaling to vaapipostproc ("scale-method=hq") + + Fix advanced deinterlacing when it is the unique filter applied + + Add GstColorBalance interface to vaapisink (Changzhi Wei) [#722390] + + Implement the GstNavigation interface into vaapisink [#711479] + + Allow rescaling of X11 window for vaapisink (Holger Kaelberer) [#711478] + + Optimizations to vaapidecode thread handling (Sebastian Dröge) [#734616] + + Fix deinterlacing from non VA memory buffers (Simon Farnsworth) [#726270] + + Fix clearing of subtitle overlay (Simon Farnsworth) + + Fix clearing of vaapipostproc state during restart (Michael Olbrich) + Version 0.5.9 - 29.Jul.2014 * Add VP8 decoder (+Halley Zhao) * Add H.264 MVC decoder and encoder (+Sreerenj Balachandran, Xiaowei Li) From a14ed0a78eba92ecf55789e631964f1663300d60 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 3 Feb 2015 10:00:42 +0200 Subject: [PATCH 1861/3781] 0.5.10 --- configure.ac | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 92e25a6d05..468a4c2939 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) m4_define([gst_vaapi_micro_version], [10]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ @@ -187,7 +187,7 @@ if test "$GST_API_VERSION" = "autodetect"; then else AS_VERSION_COMPARE([$GST_API_VERSION], [1.0], [gst_pkg_versions="0.10"], [gst_pkg_versions="1.0"], - dnl GStreamer 1.2.x APIs don't have their own namespace + dnl GStreamer 1.2.x and 1.4.x APIs don't have their own namespace [gst_pkg_versions="1.0"]) fi for gst_pkg_version in ${gst_pkg_versions}; do @@ -222,12 +222,12 @@ case $GST_API_VERSION in GST_PLUGINS_BASE_VERSION_REQUIRED=gst12_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst12_plugins_bad_version ;; -1.[[3-4]]) +1.4) GST_VERSION_REQUIRED=gst14_version GST_PLUGINS_BASE_VERSION_REQUIRED=gst14_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst14_plugins_bad_version ;; -1.5) +1.[[5-6]]) GST_VERSION_REQUIRED=gst16_version GST_PLUGINS_BASE_VERSION_REQUIRED=gst16_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst16_plugins_bad_version @@ -244,19 +244,23 @@ AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED) USE_GST_API_0_10="no" USE_GST_API_1_0p="no" USE_GST_API_1_2p="no" +USE_GST_API_1_4p="no" AS_VERSION_COMPARE([$GST_API_VERSION], [0.10], [], [USE_GST_API_0_10="yes"], []) AS_VERSION_COMPARE([$GST_API_VERSION], [1.0], [], [USE_GST_API_1_0p="yes"], [USE_GST_API_1_0p="yes"]) AS_VERSION_COMPARE([$GST_API_VERSION], [1.2], [], [USE_GST_API_1_2p="yes"], [USE_GST_API_1_2p="yes"]) +AS_VERSION_COMPARE([$GST_API_VERSION], [1.4], + [], [USE_GST_API_1_4p="yes"], [USE_GST_API_1_4p="yes"]) AM_CONDITIONAL([USE_GST_API_0_10], [test "$USE_GST_API_0_10" = "yes"]) AM_CONDITIONAL([USE_GST_API_1_0p], [test "$USE_GST_API_1_0p" = "yes"]) AM_CONDITIONAL([USE_GST_API_1_2p], [test "$USE_GST_API_1_2p" = "yes"]) +AM_CONDITIONAL([USE_GST_API_1_4p], [test "$USE_GST_API_1_4p" = "yes"]) -dnl GStreamer 1.2.x APIs don't have their own namespace +dnl GStreamer 1.2.x and 1.4.x APIs don't have their own namespace GST_PKG_VERSION="$GST_API_VERSION" -if test "$USE_GST_API_1_2p" = "yes"; then +if test "$USE_GST_API_1_2p" = "yes" || test "$USE_GST_API_1_4p" = "yes" ; then GST_PKG_VERSION="1.0" fi AC_SUBST([GST_PKG_VERSION]) @@ -268,8 +272,8 @@ if test "$USE_GST_API_0_10" = "yes"; then AC_MSG_WARN([disabled built-in videoparsers (unsupported)]) enable_builtin_videoparsers="no" fi -elif test "$USE_GST_API_1_2p" != "yes"; then - AC_MSG_WARN([support for GStreamer < 1.2 is deprecated, please upgrade]) +elif test "$GST_API_VERSION" = "1.0"; then + AC_MSG_WARN([support for GStreamer 1.0 is obsolete, and will be removed]) fi dnl GStreamer Core @@ -363,7 +367,7 @@ if test "$ac_cv_have_gst_video_overlay_hwcaps" = "yes"; then fi dnl GStreamer -bad plugins (deprecated in GStreamer v1.2) -if test "$USE_GST_API_1_2p" != "yes"; then +if test "$USE_GST_API_1_2p" != "yes" && test "$USE_GST_API_1_4p" != "yes"; then PKG_CHECK_MODULES([GST_BASEVIDEO], [gstreamer-basevideo-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) fi @@ -484,8 +488,8 @@ case $GST_API_VERSION in 0.10) lt_bias=gst0_vaapi_lt_current_bias;; 1.0) lt_bias=gst1_vaapi_lt_current_bias;; 1.2) lt_bias=gst2_vaapi_lt_current_bias;; -1.[[3-4]]) lt_bias=gst4_vaapi_lt_current_bias;; -1.5) lt_bias=gst6_vaapi_lt_current_bias;; +1.4) lt_bias=gst4_vaapi_lt_current_bias;; +1.[[5-6]]) lt_bias=gst6_vaapi_lt_current_bias;; esac GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - "$lt_bias"` AC_SUBST(GST_VAAPI_MAJOR_VERSION) From b6dece082c2b537e4be5f9e2b1ed7449a387e8e1 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 3 Feb 2015 13:08:01 +0200 Subject: [PATCH 1862/3781] Bump version for development. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 468a4c2939..555cfeae73 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [10]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [11]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From bb1b147180a07647f355e1e43453920a6c1db9db Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 3 Feb 2015 13:08:53 +0200 Subject: [PATCH 1863/3781] AUTHORS: Updates --- AUTHORS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 6eda1a05f1..d640d50c0e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,6 +1,7 @@ Maintainers: Gwenole Beauchesne - Lead developer +Sreerenj Balachandran - Lead developer Halley Zhao - MPEG-4:2 decoder This project is maintained by Intel Corporation. @@ -8,6 +9,7 @@ This project is maintained by Intel Corporation. Contributors (sorted by first name): Cong Zhong +Changzhi Wei Emilio Lopez Fabrice Bellet Feng Yuan @@ -21,12 +23,12 @@ Kristian Hogsberg Lionel Landwerlin Matthew Waters Matthieu Bouron +Michael Olbrich Nicolas Dufresne Philip Lorenz Robert Bradford Ross Burton Simon Farnsworth -Sreerenj Balachandran Thibault Saunier Victor Manuel Jaquez Leal Xiaowei Li From 4197c8de172b8237690c8723c7fe77a2058c091c Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 4 Feb 2015 11:14:15 +0200 Subject: [PATCH 1864/3781] configure: Add Check for JPEG encoding API --- configure.ac | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/configure.ac b/configure.ac index 555cfeae73..fc05f574b9 100644 --- a/configure.ac +++ b/configure.ac @@ -793,6 +793,7 @@ AC_CACHE_CHECK([for video post-postprocessing API], dnl Check for encoding support USE_ENCODERS=0 +USE_JPEG_ENCODER=0 if test "$enable_encoders" = "yes"; then PKG_CHECK_MODULES([LIBVA], [libva >= va_api_enc_version], [HAVE_VA_ENC=1], [HAVE_VA_ENC=0]) @@ -804,6 +805,34 @@ if test "$enable_encoders" = "yes"; then [USE_ENCODERS=1], [HAVE_VA_ENC=0 USE_ENCODERS=0], [#include ]) + + dnl Check for JPEG Encoding API (0.37.0+) + AC_CHECK_HEADERS([va/va_enc_jpeg.h], + [USE_JPEG_ENCODER=1], [], + [#include + ]) + AC_CACHE_CHECK([for JPEG encoding API], + ac_cv_have_jpeg_encoding_api, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #ifdef HAVE_VA_VA_ENC_JPEG_H + #include + #endif + ]], + [[VAEncPictureParameterBufferJPEG pic_param; + VAEncSliceParameterBufferJPEG slice_param; + VAQMatrixBufferJPEG q_matrix;]])], + [ac_cv_have_jpeg_encoding_api="yes" USE_JPEG_ENCODER=1], + [ac_cv_have_jpeg_encoding_api="no"] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" + ]) CPPFLAGS="$saved_CPPFLAGS" fi fi @@ -830,6 +859,10 @@ AC_DEFINE_UNQUOTED([USE_ENCODERS], $USE_ENCODERS, [Defined to 1 if video encoders are used]) AM_CONDITIONAL([USE_ENCODERS], [test $USE_ENCODERS -eq 1]) +AC_DEFINE_UNQUOTED(USE_JPEG_ENCODER, $USE_JPEG_ENCODER, + [Defined to 1 if JPEG encoder is used]) +AM_CONDITIONAL(USE_JPEG_ENCODER, test $USE_JPEG_ENCODER -eq 1) + AC_DEFINE_UNQUOTED(USE_VA_VPP, $USE_VA_VPP, [Defined to 1 if video post-processing is used]) AM_CONDITIONAL(USE_VA_VPP, test $USE_VA_VPP -eq 1) From d48ab9a3d6a6bbfddd4bf6522d51ad75466c38bf Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 4 Feb 2015 11:15:00 +0200 Subject: [PATCH 1865/3781] Encode: Add support for Picture level Entrypoint This is useful for JPEG encoding which is utilizing picture level entrypoint instead of slice level entrypoint like h264,mpeg2 etc. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + gst-libs/gst/vaapi/gstvaapiencoder.c | 18 ++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiprofile.c | 9 +++++---- gst-libs/gst/vaapi/gstvaapiprofile.h | 4 +++- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index c89a679a7e..0115c74648 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -557,6 +557,7 @@ ensure_profiles (GstVaapiDisplay * display) g_array_append_val (priv->decoders, config); break; case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: + case GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE: g_array_append_val (priv->encoders, config); break; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 430da1e50e..7bcdc41f91 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -512,14 +512,22 @@ get_config_attribute (GstVaapiEncoder * encoder, VAConfigAttribType type, { GstVaapiProfile profile; VAProfile va_profile; + VAEntrypoint va_entrypoint; + const GstVaapiEncoderClassData *const cdata = + GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; profile = get_profile (encoder); if (!profile) return FALSE; - va_profile = gst_vaapi_profile_get_va_profile (profile); + + if (cdata->codec != GST_VAAPI_CODEC_JPEG) + va_entrypoint = VAEntrypointEncSlice; + else + va_entrypoint = VAEntrypointEncPicture; + return gst_vaapi_get_config_attribute (encoder->display, va_profile, - VAEntrypointEncSlice, type, out_value_ptr); + va_entrypoint, type, out_value_ptr); } /* Determines the set of supported packed headers */ @@ -550,10 +558,16 @@ set_context_info (GstVaapiEncoder * encoder) GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); + const GstVaapiEncoderClassData *const cdata = + GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; cip->profile = encoder->profile; cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + if (cdata->codec != GST_VAAPI_CODEC_JPEG) + cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + else + cip->entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; cip->chroma_type = gst_vaapi_video_format_get_chroma_type (format); cip->width = GST_VAAPI_ENCODER_WIDTH (encoder); cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 6337fe99e2..1c831cdb77 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -144,11 +144,12 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { /* Entry-points */ static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = { - { GST_VAAPI_ENTRYPOINT_VLD, VAEntrypointVLD }, - { GST_VAAPI_ENTRYPOINT_IDCT, VAEntrypointIDCT }, - { GST_VAAPI_ENTRYPOINT_MOCO, VAEntrypointMoComp }, + { GST_VAAPI_ENTRYPOINT_VLD, VAEntrypointVLD }, + { GST_VAAPI_ENTRYPOINT_IDCT, VAEntrypointIDCT }, + { GST_VAAPI_ENTRYPOINT_MOCO, VAEntrypointMoComp }, #if VA_CHECK_VERSION(0,30,0) - { GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, VAEntrypointEncSlice }, + { GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, VAEntrypointEncSlice }, + { GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, VAEntrypointEncPicture }, #endif { 0, } }; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 24dde8988a..5a0e7679a2 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -161,6 +161,7 @@ typedef enum { * @GST_VAAPI_ENTRYPOINT_IDCT: Inverse Decrete Cosine Transform * @GST_VAAPI_ENTRYPOINT_MOCO: Motion Compensation * @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: Encode Slice + * @GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE: Encode Picture * * The set of all entrypoints for #GstVaapiEntrypoint */ @@ -168,7 +169,8 @@ typedef enum { GST_VAAPI_ENTRYPOINT_VLD = 1, GST_VAAPI_ENTRYPOINT_IDCT, GST_VAAPI_ENTRYPOINT_MOCO, - GST_VAAPI_ENTRYPOINT_SLICE_ENCODE + GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, + GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE } GstVaapiEntrypoint; const gchar * From f8020bb03e49ffd66fee72eeb0d6814666d5f3d2 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 4 Feb 2015 11:15:38 +0200 Subject: [PATCH 1866/3781] encoder_objects: Add QuantizationMatrix and JPEGHuffmanTable --- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 92 ++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 68 +++++++++++++++ 2 files changed, 160 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index f022264b92..d9a9e8460f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -249,6 +249,80 @@ gst_vaapi_enc_misc_param_new (GstVaapiEncoder * encoder, 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 --- */ +/* ------------------------------------------------------------------------- */ + +#if USE_JPEG_ENCODER +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); +} +#endif + /* ------------------------------------------------------------------------- */ /* --- Encoder Picture --- */ /* ------------------------------------------------------------------------- */ @@ -270,6 +344,10 @@ gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture) 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); @@ -422,6 +500,8 @@ gboolean gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture) { GstVaapiEncSequence *sequence; + GstVaapiEncQMatrix *q_matrix; + GstVaapiEncHuffmanTable *huf_table; VADisplay va_display; VAContextID va_context; VAStatus status; @@ -445,6 +525,18 @@ gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture) &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 = diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index aa1ccbf258..5f7e78bfe2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -33,6 +33,8 @@ 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 _GstVaapiCodedBuffer GstVaapiCodedBuffer; typedef struct _GstVaapiEncPackedHeader GstVaapiEncPackedHeader; @@ -155,6 +157,60 @@ 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 --- */ /* ------------------------------------------------------------------------- */ @@ -201,6 +257,8 @@ struct _GstVaapiEncPicture VASurfaceID surface_id; gpointer param; GPtrArray *slices; + GstVaapiEncQMatrix *q_matrix; + GstVaapiEncHuffmanTable *huf_table; GstClockTime pts; guint frame_num; guint poc; @@ -272,6 +330,16 @@ gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture); 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 */ From 0609fad69cb2e9ad0fd101ca2ec4d6a7fe0fc875 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 4 Feb 2015 11:16:05 +0200 Subject: [PATCH 1867/3781] encoder: Add JPEG Encoder --- gst-libs/gst/vaapi/Makefile.am | 9 + gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 807 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h | 52 ++ 3 files changed, 868 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 63c1e2b687..6668ffb60f 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -194,6 +194,13 @@ libgstvaapi_source_h += $(libgstvaapi_enc_source_h) libgstvaapi_source_priv_h += $(libgstvaapi_enc_source_priv_h) endif +libgstvaapi_jpegenc_source_c = gstvaapiencoder_jpeg.c +libgstvaapi_jpegenc_source_h = gstvaapiencoder_jpeg.h +if USE_JPEG_ENCODER +libgstvaapi_source_c += $(libgstvaapi_jpegenc_source_c) +libgstvaapi_source_h += $(libgstvaapi_jpegenc_source_h) +endif + libgstvaapi_drm_source_c = \ gstvaapidisplay_drm.c \ gstvaapiwindow_drm.c \ @@ -495,6 +502,8 @@ EXTRA_DIST += \ $(libgstvaapi_jpegdec_source_h) \ $(libgstvaapi_vp8dec_source_c) \ $(libgstvaapi_vp8dec_source_h) \ + $(libgstvaapi_jpegenc_source_c) \ + $(libgstvaapi_jpegenc_source_h) \ $(NULL) CLEANFILES = \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c new file mode 100644 index 0000000000..6b97f36500 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -0,0 +1,807 @@ +/* + * gstvaapiencoder_jpeg.c - JPEG encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 +#include +#include +#include +#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 --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENCODER_JPEG_CAST(encoder) \ + ((GstVaapiEncoderJpeg *)(encoder)) + +struct _GstVaapiEncoderJpeg +{ + GstVaapiEncoder parent_instance; + GstVaapiProfile profile; + guint quality; + GstJpegQuantTables 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); + + encoder->n_components = GST_VIDEO_INFO_N_COMPONENTS (vinfo); + if (GST_VIDEO_INFO_IS_GRAY (vinfo)) + encoder->n_components = 1; + + 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) { + GST_DEBUG ("%d %d", encoder->h_samp[i], encoder->h_max_samp); + encoder->h_samp[i] = encoder->h_max_samp / encoder->h_samp[i]; + encoder->v_samp[i] = encoder->v_max_samp / encoder->v_samp[i]; + } +} + +/* Derives the profile that suits best to the configuration */ +static GstVaapiEncoderStatus +ensure_profile (GstVaapiEncoderJpeg * encoder) +{ + GstVaapiProfile profile; + + /* 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 (0x%08x)", encoder->profile); + return FALSE; + } +} + +static GstVaapiEncoderStatus +set_context_info (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderJpeg *encoder = GST_VAAPI_ENCODER_JPEG_CAST (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; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static gboolean +fill_picture (GstVaapiEncoderJpeg * encoder, + GstVaapiEncPicture * picture, + GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + VAEncPictureParameterBufferJPEG *const pic_param = picture->param; + GstVideoInfo *vinfo = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); + + 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_OBJECT_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 = GST_VIDEO_INFO_N_COMPONENTS (vinfo); + pic_param->quality = encoder->quality; + 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; +} + +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) { + gst_jpeg_get_default_quantization_tables (&encoder->quant_tables); + encoder->has_quant_tables = TRUE; + } + 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; + + 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 = i + 1; + frame_hdr->components[i].horizontal_factor = encoder->h_samp[i]; + frame_hdr->components[i].vertical_factor = encoder->v_samp[i]; + if (i == 0) + frame_hdr->components[i].quant_table_selector = 0; + else + frame_hdr->components[i].quant_table_selector = 1; + } +} + +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) { + gst_jpeg_get_default_quantization_tables (&encoder->quant_tables); + 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->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->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; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Jpeg raw data header"); + return FALSE; + } +} + +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 (&bs, 128 * 8); + 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_clear (&bs, TRUE); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Packed Raw Data header"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +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; + +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_CAST (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; +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_CAST (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_CAST (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); + +error: + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; +} + +static gboolean +gst_vaapi_encoder_jpeg_init (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderJpeg *const encoder = + GST_VAAPI_ENCODER_JPEG_CAST (base_encoder); + + encoder->has_quant_tables = FALSE; + memset (&encoder->quant_tables, 0, sizeof (encoder->quant_tables)); + encoder->has_huff_tables = FALSE; + memset (&encoder->huff_tables, 0, sizeof (encoder->huff_tables)); + + return TRUE; +} + +static void +gst_vaapi_encoder_jpeg_finalize (GstVaapiEncoder * base_encoder) +{ +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_jpeg_set_property (GstVaapiEncoder * base_encoder, + gint prop_id, const GValue * value) +{ + GstVaapiEncoderJpeg *const encoder = + GST_VAAPI_ENCODER_JPEG_CAST (base_encoder); + + switch (prop_id) { + case GST_VAAPI_ENCODER_JPEG_PROP_QUALITY: + encoder->quality = g_value_get_uint (value); + break; + default: + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (JPEG); + +static inline const GstVaapiEncoderClass * +gst_vaapi_encoder_jpeg_class (void) +{ + static const GstVaapiEncoderClass GstVaapiEncoderJpegClass = { + GST_VAAPI_ENCODER_CLASS_INIT (Jpeg, jpeg), + .set_property = gst_vaapi_encoder_jpeg_set_property, + }; + return &GstVaapiEncoderJpegClass; +} + +/** + * 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 gst_vaapi_encoder_new (gst_vaapi_encoder_jpeg_class (), display); +} + +/** + * gst_vaapi_encoder_jpeg_get_default_properties: + * + * Determines the set of common and jpeg specific encoder properties. + * The caller owns an extra reference to the resulting array of + * #GstVaapiEncoderPropInfo elements, so it shall be released with + * g_ptr_array_unref() after usage. + * + * Return value: the set of encoder properties for #GstVaapiEncoderJpeg, + * or %NULL if an error occurred. + */ +GPtrArray * +gst_vaapi_encoder_jpeg_get_default_properties (void) +{ + const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_jpeg_class (); + GPtrArray *props; + + props = gst_vaapi_encoder_properties_get_default (klass); + if (!props) + return NULL; + + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_JPEG_PROP_QUALITY, + g_param_spec_uint ("quality", + "Quality factor", + "Quality factor", + 0, 100, 50, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h new file mode 100644 index 0000000000..a18c7e2796 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h @@ -0,0 +1,52 @@ +/* + * gstvaapiencoder_jpeg.h JPEGG encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_ENCODER_JPEG(encoder) \ + ((GstVaapiEncoderJpeg *) (encoder)) + +typedef struct _GstVaapiEncoderJpeg GstVaapiEncoderJpeg; + +/** + * GstVaapiEncoderJpegProp: + * @GST_VAAPI_ENCODER_JPEG_PROP_QUALITY: Quality Factor value (uint). + * + * The set of JPEG encoder specific configurable properties. + */ +typedef enum { + GST_VAAPI_ENCODER_JPEG_PROP_QUALITY = -1 +} GstVaapiEncoderJpegProp; + +GstVaapiEncoder * +gst_vaapi_encoder_jpeg_new (GstVaapiDisplay * display); + +GPtrArray * +gst_vaapi_encoder_jpeg_get_default_properties (void); + +G_END_DECLS +#endif /*GST_VAAPI_ENCODER_JPEG_H */ From 3332c25ef69900800bbfa8a754dc3ee65ee27a4f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 4 Feb 2015 11:16:37 +0200 Subject: [PATCH 1868/3781] gstvaapiencoder: Fix crash when handling rate control mask Having a ratecontrol_mask equal to zero is not a bug, but the driver might not be supporting any kind of rate control mechanisms. Eg: JPEG Encoding --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 7bcdc41f91..80ea2590b4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -854,7 +854,7 @@ gst_vaapi_encoder_set_rate_control (GstVaapiEncoder * encoder, goto error_operation_failed; rate_control_mask = get_rate_control_mask (encoder); - if (!(rate_control_mask & (1U << rate_control))) + if (rate_control_mask && !(rate_control_mask & (1U << rate_control))) goto error_unsupported_rate_control; encoder->rate_control = rate_control; From beefadc7b731848b9d146022b3434421e13752a1 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 4 Feb 2015 11:17:06 +0200 Subject: [PATCH 1869/3781] gstvaapiencoder: Use hardcoded packed_raw_data flag for JPEG Encoding --- gst-libs/gst/vaapi/gstvaapiencoder.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 80ea2590b4..d08f677b44 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -547,6 +547,15 @@ get_packed_headers (GstVaapiEncoder * encoder) encoder->got_packed_headers = TRUE; encoder->packed_headers = cdata->packed_headers & value; + + if (cdata->codec == GST_VAAPI_CODEC_JPEG) { +#if !VA_CHECK_VERSION(0,37,1) + encoder->packed_headers = VA_ENC_PACKED_HEADER_RAW_DATA; + GST_DEBUG ("Hard coding the packed header flag value to VA_ENC_PACKED_HEADER_RAW_DATA," + "This is a work around for the driver bug"); +#endif + } + return encoder->packed_headers; } From 7a84b06097743b57f32d37e00db2b8969325d17f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 4 Feb 2015 11:17:27 +0200 Subject: [PATCH 1870/3781] gstvaapicontext: Don't use the unsupported Ratecontrol attributes for vaCreateConfig Don't add the VAConfigAttribRateControl to the attribute list using for the vaCreateConfig if it is not supported by the driver. --- gst-libs/gst/vaapi/gstvaapicontext.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index a2c68a328a..87ea48efb5 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -218,19 +218,20 @@ context_create (GstVaapiContext * context) guint va_rate_control; /* Rate control */ - attrib->type = VAConfigAttribRateControl; - if (!context_get_attribute (context, attrib->type, &value)) - goto cleanup; - va_rate_control = from_GstVaapiRateControl (config->rc_mode); - 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++; + 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++; + } /* Packed headers */ if (config->packed_headers) { attrib->type = VAConfigAttribEncPackedHeaders; From 4c7c858374f65a97d4c535a0deb4b39baa550e25 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 4 Feb 2015 11:17:58 +0200 Subject: [PATCH 1871/3781] gstvaapicontext: Add VAConfigAttribValEncJPEG to the attribute list using for VAConfig creation. --- gst-libs/gst/vaapi/gstvaapicontext.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 87ea48efb5..ffa74580b8 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -246,6 +246,23 @@ context_create (GstVaapiContext * context) attrib->value = config->packed_headers; attrib++; } +#if VA_CHECK_VERSION(0,37,0) + if (cip->profile == GST_VAAPI_PROFILE_JPEG_BASELINE) { + VAConfigAttribValEncJPEG jpeg_attrib_val; + /* JPEG Encoding Attribute */ + attrib->type = VAConfigAttribEncJPEG; + if (!context_get_attribute (context, attrib->type, &value)) + goto cleanup; + jpeg_attrib_val.value = attrib->value; + /* Set JPEG profile attribs */ + jpeg_attrib_val.bits.arithmatic_coding_mode = 0; + jpeg_attrib_val.bits.progressive_dct_mode = 0; + jpeg_attrib_val.bits.non_interleaved_mode = 1; + jpeg_attrib_val.bits.differential_mode = 0; + attrib->value = jpeg_attrib_val.value; + attrib++; + } +#endif break; } #endif From d2e2784a78d1ed445a0f60fc2c4e7c3a18f38498 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 4 Feb 2015 11:18:29 +0200 Subject: [PATCH 1872/3781] plugins: Add JPEG encoder element --- gst/vaapi/Makefile.am | 37 ++++--- gst/vaapi/gstvaapi.c | 9 ++ gst/vaapi/gstvaapiencode_jpeg.c | 172 ++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode_jpeg.h | 69 +++++++++++++ 4 files changed, 273 insertions(+), 14 deletions(-) create mode 100644 gst/vaapi/gstvaapiencode_jpeg.c create mode 100644 gst/vaapi/gstvaapiencode_jpeg.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index ffaa26bac4..82a25f3fcc 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -77,6 +77,13 @@ libgstvaapi_source_c += $(libgstvaapi_enc_source_c) libgstvaapi_source_h += $(libgstvaapi_enc_source_h) endif +libgstvaapi_jpegenc_source_c = gstvaapiencode_jpeg.c +libgstvaapi_jpegenc_source_h = gstvaapiencode_jpeg.h +if USE_JPEG_ENCODER +libgstvaapi_source_c += $(libgstvaapi_jpegenc_source_c) +libgstvaapi_source_h += $(libgstvaapi_jpegenc_source_h) +endif + libgstvaapi_x11_source_c = gstvaapivideoconverter_x11.c libgstvaapi_x11_source_h = gstvaapivideoconverter_x11.h @@ -235,20 +242,22 @@ CLEANFILES = \ $(libgstvaapi_parse_gen_sources) EXTRA_DIST = \ - $(libgstvaapi_enc_source_c) \ - $(libgstvaapi_enc_source_h) \ - $(libgstvaapi_x11_source_c) \ - $(libgstvaapi_x11_source_h) \ - $(libgstvaapi_glx_source_c) \ - $(libgstvaapi_glx_source_h) \ - $(libgstvaapi_1_2p_source_c) \ - $(libgstvaapi_1_2p_source_h) \ - $(libgstvaapi_1_0p_source_c) \ - $(libgstvaapi_1_0p_source_h) \ - $(libgstvaapi_0_10_source_c) \ - $(libgstvaapi_0_10_source_h) \ - $(libgstvaapi_parse_source_c) \ - $(libgstvaapi_parse_source_h) \ + $(libgstvaapi_enc_source_c) \ + $(libgstvaapi_enc_source_h) \ + $(libgstvaapi_jpeg_enc_source_c) \ + $(libgstvaapi_jpeg_enc_source_h) \ + $(libgstvaapi_x11_source_c) \ + $(libgstvaapi_x11_source_h) \ + $(libgstvaapi_glx_source_c) \ + $(libgstvaapi_glx_source_h) \ + $(libgstvaapi_1_2p_source_c) \ + $(libgstvaapi_1_2p_source_h) \ + $(libgstvaapi_1_0p_source_c) \ + $(libgstvaapi_1_0p_source_h) \ + $(libgstvaapi_0_10_source_c) \ + $(libgstvaapi_0_10_source_h) \ + $(libgstvaapi_parse_source_c) \ + $(libgstvaapi_parse_source_h) \ $(NULL) # Extra clean files so that maintainer-clean removes *everything* diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index abe9da4d0a..8abd23b637 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -35,6 +35,10 @@ #include "gstvaapiencode_mpeg2.h" #endif +#if USE_JPEG_ENCODER +#include "gstvaapiencode_jpeg.h" +#endif + #define PLUGIN_NAME "vaapi" #define PLUGIN_DESC "VA-API based elements" #define PLUGIN_LICENSE "LGPL" @@ -67,6 +71,11 @@ plugin_init (GstPlugin *plugin) GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_MPEG2); #endif +#if USE_JPEG_ENCODER + gst_element_register(plugin, "vaapiencode_jpeg", + GST_RANK_PRIMARY, + GST_TYPE_VAAPIENCODE_JPEG); +#endif return TRUE; } diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c new file mode 100644 index 0000000000..826b06cdc4 --- /dev/null +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -0,0 +1,172 @@ +/* + * gstvaapiencode_jpeg.c - VA-API JPEG encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 "gst/vaapi/sysdeps.h" +#include +#include +#include "gstvaapiencode_jpeg.h" +#include "gstvaapipluginutil.h" +#if GST_CHECK_VERSION(1,0,0) +#include "gstvaapivideomemory.h" +#endif + +#define GST_PLUGIN_NAME "vaapiencode_jpeg" +#define GST_PLUGIN_DESC "A VA-API based JPEG video encoder" + +GST_DEBUG_CATEGORY_STATIC (gst_vaapi_jpeg_encode_debug); +#define GST_CAT_DEFAULT gst_vaapi_jpeg_encode_debug + +#define GST_CODEC_CAPS \ + "image/jpeg" + +/* *INDENT-OFF* */ +static const char gst_vaapiencode_jpeg_sink_caps_str[] = +#if GST_CHECK_VERSION(1,1,0) + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, + "{ ENCODED, NV12, I420, YV12 }") ", " +#else + GST_VAAPI_SURFACE_CAPS ", " +#endif + GST_CAPS_INTERLACED_FALSE "; " +#if GST_CHECK_VERSION(1,0,0) + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " +#endif + GST_CAPS_INTERLACED_FALSE; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static const char gst_vaapiencode_jpeg_src_caps_str[] = + GST_CODEC_CAPS; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapiencode_jpeg_sink_factory = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_jpeg_sink_caps_str)); +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapiencode_jpeg_src_factory = + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_jpeg_src_caps_str)); +/* *INDENT-ON* */ + +/* jpeg encode */ +G_DEFINE_TYPE (GstVaapiEncodeJpeg, gst_vaapiencode_jpeg, + GST_TYPE_VAAPIENCODE); + +static void +gst_vaapiencode_jpeg_init (GstVaapiEncodeJpeg * encode) +{ + gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); +} + +static void +gst_vaapiencode_jpeg_finalize (GObject * object) +{ + G_OBJECT_CLASS (gst_vaapiencode_jpeg_parent_class)->finalize (object); +} + +static void +gst_vaapiencode_jpeg_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + default: + if (!encode_class->set_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapiencode_jpeg_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + default: + if (!encode_class->get_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstCaps * +gst_vaapiencode_jpeg_get_caps (GstVaapiEncode * base_encode) +{ + GstCaps *caps; + + caps = gst_caps_from_string (GST_CODEC_CAPS); + + return caps; +} + +static GstVaapiEncoder * +gst_vaapiencode_jpeg_alloc_encoder (GstVaapiEncode * base, + GstVaapiDisplay * display) +{ + return gst_vaapi_encoder_jpeg_new (display); +} + +static void +gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_vaapi_jpeg_encode_debug, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + object_class->finalize = gst_vaapiencode_jpeg_finalize; + object_class->set_property = gst_vaapiencode_jpeg_set_property; + object_class->get_property = gst_vaapiencode_jpeg_get_property; + + encode_class->get_properties = gst_vaapi_encoder_jpeg_get_default_properties; + encode_class->get_caps = gst_vaapiencode_jpeg_get_caps; + encode_class->alloc_encoder = gst_vaapiencode_jpeg_alloc_encoder; + + gst_element_class_set_static_metadata (element_class, + "VA-API JPEG encoder", + "Codec/Encoder/Image", + GST_PLUGIN_DESC, "Sreerenj Balachandran "); + + /* sink pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_jpeg_sink_factory)); + + /* src pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_jpeg_src_factory)); + + gst_vaapiencode_class_init_properties (encode_class); +} diff --git a/gst/vaapi/gstvaapiencode_jpeg.h b/gst/vaapi/gstvaapiencode_jpeg.h new file mode 100644 index 0000000000..ea5a187332 --- /dev/null +++ b/gst/vaapi/gstvaapiencode_jpeg.h @@ -0,0 +1,69 @@ +/* + * gstvaapiencode_jpeg.h - VA-API JPEG encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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_VAAPIENCODE_JPEG_H +#define GST_VAAPIENCODE_JPEG_H + +#include +#include "gstvaapiencode.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIENCODE_JPEG \ + (gst_vaapiencode_jpeg_get_type ()) +#define GST_VAAPIENCODE_JPEG_CAST(obj) \ + ((GstVaapiEncodeJpeg *)(obj)) +#define GST_VAAPIENCODE_JPEG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPIENCODE_JPEG, \ + GstVaapiEncodeJpeg)) +#define GST_VAAPIENCODE_JPEG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPIENCODE_JPEG, \ + GstVaapiEncodeJpegClass)) +#define GST_VAAPIENCODE_JPEG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPIENCODE_JPEG, \ + GstVaapiEncodeJpegClass)) +#define GST_IS_VAAPIENCODE_JPEG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_JPEG)) +#define GST_IS_VAAPIENCODE_JPEG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_JPEG)) + +typedef struct _GstVaapiEncodeJpeg GstVaapiEncodeJpeg; +typedef struct _GstVaapiEncodeJpegClass GstVaapiEncodeJpegClass; + +struct _GstVaapiEncodeJpeg +{ + /*< private >*/ + GstVaapiEncode parent_instance; +}; + +struct _GstVaapiEncodeJpegClass +{ + /*< private >*/ + GstVaapiEncodeClass parent_class; +}; + +GType +gst_vaapiencode_jpeg_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GST_VAAPIENCODE_JPEG_H */ From fc7e6b19fd8f8b2bf4be2a69099482e051c14f2b Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Wed, 4 Feb 2015 18:34:59 +0200 Subject: [PATCH 1873/3781] vaapidecode: Check the condition after taking the lock Otherwise the condition could become true before the lock is taken and the g_cond_signal() could be called before the g_cond_wait(), so the g_cond_wait() is never awoken. https://bugzilla.gnome.org/show_bug.cgi?id=740645 --- gst-libs/gst/vaapi/gstvaapidecoder.h | 3 +++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 4 ---- gst/vaapi/gstvaapidecode.c | 5 ++++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index f98b345e83..77587d471d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -129,6 +129,9 @@ gst_vaapi_decoder_decode (GstVaapiDecoder * decoder, GstVaapiDecoderStatus gst_vaapi_decoder_flush (GstVaapiDecoder * decoder); +GstVaapiDecoderStatus +gst_vaapi_decoder_check_status (GstVaapiDecoder * decoder); + G_END_DECLS #endif /* GST_VAAPI_DECODER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 5a5cde4dc5..2ac56e8b05 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -273,10 +273,6 @@ void gst_vaapi_decoder_push_frame (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame); -G_GNUC_INTERNAL -GstVaapiDecoderStatus -gst_vaapi_decoder_check_status (GstVaapiDecoder * decoder); - G_GNUC_INTERNAL GstVaapiDecoderStatus gst_vaapi_decoder_decode_codec_data (GstVaapiDecoder * decoder); diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a9c2462080..f0e25cce7f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -235,13 +235,16 @@ gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) GstVaapiDecoderStatus status; GstFlowReturn ret; + /* Decode current frame */ for (;;) { status = gst_vaapi_decoder_decode(decode->decoder, frame); if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); g_mutex_lock(&decode->decoder_mutex); - g_cond_wait(&decode->decoder_ready, &decode->decoder_mutex); + if (gst_vaapi_decoder_check_status (decode->decoder) == + GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) + g_cond_wait(&decode->decoder_ready, &decode->decoder_mutex); g_mutex_unlock(&decode->decoder_mutex); GST_VIDEO_DECODER_STREAM_LOCK(vdec); if (decode->decoder_loop_status < 0) From 0f40843bb3dda1df820b18df899b17ffdee43f4e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 5 Feb 2015 12:13:38 +0200 Subject: [PATCH 1874/3781] encoder: Only support YUV420 native format as input for now Practically we should be able to support more formats, for eg: JPEG Encoder can support YUV422, RGBA and all. But this is causing more issues which need proper fix here and there. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index d08f677b44..51be5d9b70 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -585,6 +585,13 @@ set_context_info (GstVaapiEncoder * encoder) if (!cip->chroma_type && (format != GST_VIDEO_FORMAT_ENCODED)) goto error_unsupported_format; + if (cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420 && + format != GST_VIDEO_FORMAT_ENCODED) { + GST_ERROR ("We are only supporting YUV:4:2:0 for encoding," + "please try to use vaapipostproc to convert the input format!"); + goto error_unsupported_format; + } + memset (config, 0, sizeof (*config)); config->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); config->packed_headers = get_packed_headers (encoder); From 6b73746ab6453253ea4bb82170914e0a1892e135 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 5 Feb 2015 13:08:53 +0200 Subject: [PATCH 1875/3781] encoder: jpeg: Fix the sampling factor calculation for ENCODED format. If the incoming raw video format is GST_VIDEO_FORMAT_ENCODED, use native YUV420 format (which is i420) as default. --- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 6b97f36500..785b3bb45f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -88,9 +88,21 @@ generate_sampling_factors (GstVaapiEncoderJpeg * encoder) 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); - if (GST_VIDEO_INFO_IS_GRAY (vinfo)) - encoder->n_components = 1; encoder->h_max_samp = 0; encoder->v_max_samp = 0; @@ -111,9 +123,10 @@ generate_sampling_factors (GstVaapiEncoderJpeg * encoder) /* now invert */ /* maximum is invariant, as one of the components should have samp 1 */ for (i = 0; i < encoder->n_components; ++i) { - GST_DEBUG ("%d %d", encoder->h_samp[i], encoder->h_max_samp); 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]); } } @@ -216,7 +229,7 @@ fill_picture (GstVaapiEncoderJpeg * encoder, 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 = GST_VIDEO_INFO_N_COMPONENTS (vinfo); + pic_param->num_components = encoder->n_components; pic_param->quality = encoder->quality; return TRUE; } From 004968f5065b30dda29a86888941a32723265c0e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 6 Feb 2015 12:10:51 +0200 Subject: [PATCH 1876/3781] build: fix make dist when certain conditionals not met. Fix typo which was preventing the inclusion of jpeg encoder source files from make dist (when there is no jpeg encoder API support in libva). --- gst/vaapi/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 82a25f3fcc..097ca6a1a5 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -244,8 +244,8 @@ CLEANFILES = \ EXTRA_DIST = \ $(libgstvaapi_enc_source_c) \ $(libgstvaapi_enc_source_h) \ - $(libgstvaapi_jpeg_enc_source_c) \ - $(libgstvaapi_jpeg_enc_source_h) \ + $(libgstvaapi_jpegenc_source_c) \ + $(libgstvaapi_jpegenc_source_h) \ $(libgstvaapi_x11_source_c) \ $(libgstvaapi_x11_source_h) \ $(libgstvaapi_glx_source_c) \ From 6edb173486aa17226ad0e0ee5775ab57ea2daae4 Mon Sep 17 00:00:00 2001 From: Lim Siew Hoon Date: Tue, 10 Feb 2015 11:40:16 +0200 Subject: [PATCH 1877/3781] decoder: vc1: Rounding control handling for VC1 simple and Main profile Added rounding control handling for VC1 simple and Main profile based on VC1 standard spec: section 8.3.7 https://bugzilla.gnome.org/show_bug.cgi?id=743958 Signed-off-by: Lim Siew Hoon Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 780e15d600..372c58214f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -63,6 +63,7 @@ struct _GstVaapiDecoderVC1Private { GstVaapiDpb *dpb; gint32 next_poc; guint8 *rbdu_buffer; + guint8 rndctrl; guint rbdu_buffer_size; guint is_opened : 1; guint is_first_field : 1; @@ -173,6 +174,7 @@ gst_vaapi_decoder_vc1_create(GstVaapiDecoder *base_decoder) GstVaapiDecoderVC1Private * const priv = &decoder->priv; priv->profile = (GstVaapiProfile)0; + priv->rndctrl = 0; return TRUE; } @@ -668,7 +670,6 @@ fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) pic_param->cbp_table = pic->cbptab; pic_param->mb_mode_table = 0; /* XXX: interlaced frame */ pic_param->range_reduction_frame = pic->rangeredfrm; - pic_param->rounding_control = 0; /* advanced profile only */ pic_param->post_processing = 0; /* advanced profile only */ pic_param->picture_resolution_index = pic->respic; pic_param->luma_scale = pic->lumscale; @@ -686,6 +687,16 @@ fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf; pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm; pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2; + + /* Refer to 8.3.7 Rounding control for Simple and Main Profile */ + if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I || + frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) + priv->rndctrl = 1; + else if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P) + priv->rndctrl ^= 1; + + pic_param->rounding_control = priv->rndctrl; + return TRUE; } From 8145fbf70088c63a0f88872c34bddecbe3dacbf1 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 13 Feb 2015 13:40:19 +0200 Subject: [PATCH 1878/3781] configure: Add Check for VP8 Encoding API --- configure.ac | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/configure.ac b/configure.ac index fc05f574b9..f4efae0adf 100644 --- a/configure.ac +++ b/configure.ac @@ -794,6 +794,7 @@ AC_CACHE_CHECK([for video post-postprocessing API], dnl Check for encoding support USE_ENCODERS=0 USE_JPEG_ENCODER=0 +USE_VP8_ENCODER=0 if test "$enable_encoders" = "yes"; then PKG_CHECK_MODULES([LIBVA], [libva >= va_api_enc_version], [HAVE_VA_ENC=1], [HAVE_VA_ENC=0]) @@ -833,6 +834,34 @@ if test "$enable_encoders" = "yes"; then CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) + + dnl Check for VP8 Encoding API + AC_CHECK_HEADERS([va/va_enc_vp8.h], + [USE_VP8_ENCODER=1], [], + [#include + ]) + AC_CACHE_CHECK([for VP8 encoding API], + ac_cv_have_vp8_encoding_api, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #ifdef HAVE_VA_VA_ENC_VP8_H + #include + #endif + ]], + [[VAEncSequenceParameterBufferVP8 seq_param; + VAEncPictureParameterBufferVP8 pic_param; + VAQMatrixBufferVP8 q_matrix;]])], + [ac_cv_have_vp8_encoding_api="yes" USE_VP8_ENCODER=1], + [ac_cv_have_vp8_encoding_api="no" USE_VP8_ENCODER=0] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" + ]) CPPFLAGS="$saved_CPPFLAGS" fi fi @@ -863,6 +892,10 @@ AC_DEFINE_UNQUOTED(USE_JPEG_ENCODER, $USE_JPEG_ENCODER, [Defined to 1 if JPEG encoder is used]) AM_CONDITIONAL(USE_JPEG_ENCODER, test $USE_JPEG_ENCODER -eq 1) +AC_DEFINE_UNQUOTED(USE_VP8_ENCODER, $USE_VP8_ENCODER, + [Defined to 1 if VP8 encoder is used]) +AM_CONDITIONAL(USE_VP8_ENCODER, test $USE_VP8_ENCODER -eq 1) + AC_DEFINE_UNQUOTED(USE_VA_VPP, $USE_VA_VPP, [Defined to 1 if video post-processing is used]) AM_CONDITIONAL(USE_VA_VPP, test $USE_VA_VPP -eq 1) From eeefdb49582fabff4b34788d98dd4f5b9a523569 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 13 Feb 2015 13:42:04 +0200 Subject: [PATCH 1879/3781] Add VP8 Encoder to core libgstvaapi. --- gst-libs/gst/vaapi/Makefile.am | 11 +- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 568 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_vp8.h | 56 +++ 3 files changed, 634 insertions(+), 1 deletion(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_vp8.c create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_vp8.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 6668ffb60f..8332af4de3 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -201,6 +201,13 @@ libgstvaapi_source_c += $(libgstvaapi_jpegenc_source_c) libgstvaapi_source_h += $(libgstvaapi_jpegenc_source_h) endif +libgstvaapi_vp8enc_source_c = gstvaapiencoder_vp8.c +libgstvaapi_vp8enc_source_h = gstvaapiencoder_vp8.h +if USE_VP8_ENCODER +libgstvaapi_source_c += $(libgstvaapi_vp8enc_source_c) +libgstvaapi_source_h += $(libgstvaapi_vp8enc_source_h) +endif + libgstvaapi_drm_source_c = \ gstvaapidisplay_drm.c \ gstvaapiwindow_drm.c \ @@ -502,8 +509,10 @@ EXTRA_DIST += \ $(libgstvaapi_jpegdec_source_h) \ $(libgstvaapi_vp8dec_source_c) \ $(libgstvaapi_vp8dec_source_h) \ - $(libgstvaapi_jpegenc_source_c) \ $(libgstvaapi_jpegenc_source_h) \ + $(libgstvaapi_jpegenc_source_c) \ + $(libgstvaapi_vp8enc_source_h) \ + $(libgstvaapi_vp8enc_source_c) \ $(NULL) CLEANFILES = \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c new file mode 100644 index 0000000000..a9afc1134c --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -0,0 +1,568 @@ +/* + * gstvaapiencoder_vp8.c - VP8 encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 +#include +#include +#include +#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)) + +/* 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 --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENCODER_VP8_CAST(encoder) \ + ((GstVaapiEncoderVP8 *)(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) +{ + GstVaapiProfile profile; + + /* 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 (0x%08x)", 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: + if (!base_encoder->bitrate) { + base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * + GST_VAAPI_ENCODER_HEIGHT (encoder) * + GST_VAAPI_ENCODER_FPS_N (encoder) / + GST_VAAPI_ENCODER_FPS_D (encoder) / 4 * 1000; + } + default: + base_encoder->bitrate = 0; + break; + } + + return TRUE; +} + +static GstVaapiEncoderStatus +set_context_info (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderVP8 *encoder = GST_VAAPI_ENCODER_VP8_CAST (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. + Take an approximation of 4 times compress ratio */ + base_encoder->codedbuf_size = GST_ROUND_UP_16 (vip->width) * + GST_ROUND_UP_16 (vip->height) * 3 / 2 / 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; + + 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) + seq_param->bits_per_second = base_encoder->bitrate; + + 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; + +error: + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; +} + +static gboolean +fill_picture (GstVaapiEncoderVP8 * encoder, + GstVaapiEncPicture * picture, + GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + 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_OBJECT_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; + + 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_CAST (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_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; +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) +{ + 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_CAST (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_CAST (base_encoder); + GstVaapiEncoderStatus status; + + status = ensure_profile (encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + + if (!ensure_bitrate (encoder)) + goto error; + + return set_context_info (base_encoder); + +error: + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; +} + +static gboolean +gst_vaapi_encoder_vp8_init (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8_CAST (base_encoder); + + encoder->frame_num = 0; + encoder->last_ref = NULL; + encoder->golden_ref = NULL; + encoder->alt_ref = NULL; + + return TRUE; +} + +static void +gst_vaapi_encoder_vp8_finalize (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8_CAST (base_encoder); + clear_references (encoder); +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_vp8_set_property (GstVaapiEncoder * base_encoder, + gint prop_id, const GValue * value) +{ + GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8_CAST (base_encoder); + + switch (prop_id) { + case GST_VAAPI_ENCODER_VP8_PROP_LOOP_FILTER_LEVEL: + encoder->loop_filter_level = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_VP8_PROP_SHARPNESS_LEVEL: + encoder->sharpness_level = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_VP8_PROP_YAC_Q_INDEX: + encoder->yac_qi = g_value_get_uint (value); + break; + default: + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (VP8); + +static inline const GstVaapiEncoderClass * +gst_vaapi_encoder_vp8_class (void) +{ + static const GstVaapiEncoderClass GstVaapiEncoderVP8Class = { + GST_VAAPI_ENCODER_CLASS_INIT (VP8, vp8), + .set_property = gst_vaapi_encoder_vp8_set_property, + }; + return &GstVaapiEncoderVP8Class; +} + +/** + * 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 gst_vaapi_encoder_new (gst_vaapi_encoder_vp8_class (), display); +} + +/** + * gst_vaapi_encoder_vp8_get_default_properties: + * + * Determines the set of common and vp8 specific encoder properties. + * The caller owns an extra reference to the resulting array of + * #GstVaapiEncoderPropInfo elements, so it shall be released with + * g_ptr_array_unref() after usage. + * + * Return value: the set of encoder properties for #GstVaapiEncoderVP8, + * or %NULL if an error occurred. + */ +GPtrArray * +gst_vaapi_encoder_vp8_get_default_properties (void) +{ + const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_vp8_class (); + GPtrArray *props; + + props = gst_vaapi_encoder_properties_get_default (klass); + if (!props) + return NULL; + + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_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)); + + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_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)); + + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_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)); + + return props; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h new file mode 100644 index 0000000000..a48bf460c4 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h @@ -0,0 +1,56 @@ +/* + * gstvaapiencoder_vp8.h VP8G encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_ENCODER_VP8(encoder) \ + ((GstVaapiEncoderVP8 *) (encoder)) + +typedef struct _GstVaapiEncoderVP8 GstVaapiEncoderVP8; + +/** + * GstVaapiEncoderVP8Prop: + * @GST_VAAPI_ENCODER_VP8_PROP_LOOP_FILTER_LEVEL: Loop Filter Level(uint). + * @GST_VAAPI_ENCODER_VP8_PROP_LOOP_SHARPNESS_LEVEL: Sharpness Level(uint). + * @GST_VAAPI_ENCODER_VP8_PROP_YAC_Q_INDEX: Quantization table index for luma AC(uint). + * + * The set of VP8 encoder specific configurable properties. + */ +typedef enum { + GST_VAAPI_ENCODER_VP8_PROP_LOOP_FILTER_LEVEL = -1, + GST_VAAPI_ENCODER_VP8_PROP_SHARPNESS_LEVEL = -2, + GST_VAAPI_ENCODER_VP8_PROP_YAC_Q_INDEX = -3 +} GstVaapiEncoderVP8Prop; + +GstVaapiEncoder * +gst_vaapi_encoder_vp8_new (GstVaapiDisplay * display); + +GPtrArray * +gst_vaapi_encoder_vp8_get_default_properties (void); + +G_END_DECLS +#endif /*GST_VAAPI_ENCODER_VP8_H */ From a664a479a854be26b78f2d475845695fbf56dd70 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 13 Feb 2015 13:45:32 +0200 Subject: [PATCH 1880/3781] plugins: Add VP8 Encoder --- gst/vaapi/Makefile.am | 9 ++ gst/vaapi/gstvaapi.c | 9 ++ gst/vaapi/gstvaapiencode_vp8.c | 172 +++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode_vp8.h | 69 +++++++++++++ 4 files changed, 259 insertions(+) create mode 100644 gst/vaapi/gstvaapiencode_vp8.c create mode 100644 gst/vaapi/gstvaapiencode_vp8.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 097ca6a1a5..6a49fdf0f8 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -84,6 +84,13 @@ libgstvaapi_source_c += $(libgstvaapi_jpegenc_source_c) libgstvaapi_source_h += $(libgstvaapi_jpegenc_source_h) endif +libgstvaapi_vp8enc_source_c = gstvaapiencode_vp8.c +libgstvaapi_vp8enc_source_h = gstvaapiencode_vp8.h +if USE_VP8_ENCODER +libgstvaapi_source_c += $(libgstvaapi_vp8enc_source_c) +libgstvaapi_source_h += $(libgstvaapi_vp8enc_source_h) +endif + libgstvaapi_x11_source_c = gstvaapivideoconverter_x11.c libgstvaapi_x11_source_h = gstvaapivideoconverter_x11.h @@ -246,6 +253,8 @@ EXTRA_DIST = \ $(libgstvaapi_enc_source_h) \ $(libgstvaapi_jpegenc_source_c) \ $(libgstvaapi_jpegenc_source_h) \ + $(libgstvaapi_vp8enc_source_c) \ + $(libgstvaapi_vp8enc_source_h) \ $(libgstvaapi_x11_source_c) \ $(libgstvaapi_x11_source_h) \ $(libgstvaapi_glx_source_c) \ diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 8abd23b637..f15731b66f 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -39,6 +39,10 @@ #include "gstvaapiencode_jpeg.h" #endif +#if USE_VP8_ENCODER +#include "gstvaapiencode_vp8.h" +#endif + #define PLUGIN_NAME "vaapi" #define PLUGIN_DESC "VA-API based elements" #define PLUGIN_LICENSE "LGPL" @@ -76,6 +80,11 @@ plugin_init (GstPlugin *plugin) GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_JPEG); #endif +#if USE_VP8_ENCODER + gst_element_register(plugin, "vaapiencode_vp8", + GST_RANK_PRIMARY, + GST_TYPE_VAAPIENCODE_VP8); +#endif return TRUE; } diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c new file mode 100644 index 0000000000..e236206cb4 --- /dev/null +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -0,0 +1,172 @@ +/* + * gstvaapiencode_vp8.c - VA-API VP8 encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 "gst/vaapi/sysdeps.h" +#include +#include +#include "gstvaapiencode_vp8.h" +#include "gstvaapipluginutil.h" +#if GST_CHECK_VERSION(1,0,0) +#include "gstvaapivideomemory.h" +#endif + +#define GST_PLUGIN_NAME "vaapiencode_vp8" +#define GST_PLUGIN_DESC "A VA-API based VP8 video encoder" + +GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp8_encode_debug); +#define GST_CAT_DEFAULT gst_vaapi_vp8_encode_debug + +#define GST_CODEC_CAPS \ + "video/x-vp8" + +/* *INDENT-OFF* */ +static const char gst_vaapiencode_vp8_sink_caps_str[] = +#if GST_CHECK_VERSION(1,1,0) + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, + "{ ENCODED, NV12, I420, YV12 }") ", " +#else + GST_VAAPI_SURFACE_CAPS ", " +#endif + GST_CAPS_INTERLACED_FALSE "; " +#if GST_CHECK_VERSION(1,0,0) + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " +#endif + GST_CAPS_INTERLACED_FALSE; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static const char gst_vaapiencode_vp8_src_caps_str[] = + GST_CODEC_CAPS; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapiencode_vp8_sink_factory = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_vp8_sink_caps_str)); +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapiencode_vp8_src_factory = + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_vp8_src_caps_str)); +/* *INDENT-ON* */ + +/* vp8 encode */ +G_DEFINE_TYPE (GstVaapiEncodeVP8, gst_vaapiencode_vp8, GST_TYPE_VAAPIENCODE); + +static void +gst_vaapiencode_vp8_init (GstVaapiEncodeVP8 * encode) +{ + gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); +} + +static void +gst_vaapiencode_vp8_finalize (GObject * object) +{ + G_OBJECT_CLASS (gst_vaapiencode_vp8_parent_class)->finalize (object); +} + +static void +gst_vaapiencode_vp8_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + default: + if (!encode_class->set_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapiencode_vp8_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + default: + if (!encode_class->get_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstCaps * +gst_vaapiencode_vp8_get_caps (GstVaapiEncode * base_encode) +{ + GstCaps *caps; + + caps = gst_caps_from_string (GST_CODEC_CAPS); + + return caps; +} + +static GstVaapiEncoder * +gst_vaapiencode_vp8_alloc_encoder (GstVaapiEncode * base, + GstVaapiDisplay * display) +{ + return gst_vaapi_encoder_vp8_new (display); +} + +static void +gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_vaapi_vp8_encode_debug, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + object_class->finalize = gst_vaapiencode_vp8_finalize; + object_class->set_property = gst_vaapiencode_vp8_set_property; + object_class->get_property = gst_vaapiencode_vp8_get_property; + + encode_class->get_properties = gst_vaapi_encoder_vp8_get_default_properties; + encode_class->get_caps = gst_vaapiencode_vp8_get_caps; + encode_class->alloc_encoder = gst_vaapiencode_vp8_alloc_encoder; + + gst_element_class_set_static_metadata (element_class, + "VA-API VP8 encoder", + "Codec/Encoder/Video", + GST_PLUGIN_DESC, + "Sreerenj Balachandran "); + + /* sink pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_vp8_sink_factory)); + + /* src pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_vp8_src_factory)); + + gst_vaapiencode_class_init_properties (encode_class); +} diff --git a/gst/vaapi/gstvaapiencode_vp8.h b/gst/vaapi/gstvaapiencode_vp8.h new file mode 100644 index 0000000000..e71c25505e --- /dev/null +++ b/gst/vaapi/gstvaapiencode_vp8.h @@ -0,0 +1,69 @@ +/* + * gstvaapiencode_vp8.h - VA-API VP8 encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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_VAAPIENCODE_VP8_H +#define GST_VAAPIENCODE_VP8_H + +#include +#include "gstvaapiencode.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIENCODE_VP8 \ + (gst_vaapiencode_vp8_get_type ()) +#define GST_VAAPIENCODE_VP8_CAST(obj) \ + ((GstVaapiEncodeVP8 *)(obj)) +#define GST_VAAPIENCODE_VP8(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPIENCODE_VP8, \ + GstVaapiEncodeVP8)) +#define GST_VAAPIENCODE_VP8_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPIENCODE_VP8, \ + GstVaapiEncodeVP8Class)) +#define GST_VAAPIENCODE_VP8_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPIENCODE_VP8, \ + GstVaapiEncodeVP8Class)) +#define GST_IS_VAAPIENCODE_VP8(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_VP8)) +#define GST_IS_VAAPIENCODE_VP8_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_VP8)) + +typedef struct _GstVaapiEncodeVP8 GstVaapiEncodeVP8; +typedef struct _GstVaapiEncodeVP8Class GstVaapiEncodeVP8Class; + +struct _GstVaapiEncodeVP8 +{ + /*< private >*/ + GstVaapiEncode parent_instance; +}; + +struct _GstVaapiEncodeVP8Class +{ + /*< private >*/ + GstVaapiEncodeClass parent_class; +}; + +GType +gst_vaapiencode_vp8_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GST_VAAPIENCODE_VP8_H */ From aaf4165819ab3fee975e00dcfe754d665b3da3af Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Wed, 18 Feb 2015 11:19:26 +0200 Subject: [PATCH 1881/3781] vaapidecode: Emit error GstMessage when returning a GST_FLOW_ERROR This is required in GStreamer, elements should never return GST_FLOW_ERROR without posting an ERROR message on the bus. https://bugzilla.gnome.org/show_bug.cgi?id=744620 --- gst/vaapi/gstvaapidecode.c | 14 +++++++++++--- gst/vaapi/gstvaapipluginbase.c | 18 +++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f0e25cce7f..014e1eafef 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -279,6 +279,8 @@ error_decode: ret = GST_FLOW_NOT_SUPPORTED; break; default: + GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding error"), + ("Decode error %d", status)); ret = GST_FLOW_ERROR; break; } @@ -365,9 +367,11 @@ error_create_buffer: const GstVaapiID surface_id = gst_vaapi_surface_get_id(GST_VAAPI_SURFACE_PROXY_SURFACE(proxy)); - GST_ERROR("video sink failed to create video buffer for proxy'ed " + GST_ELEMENT_ERROR(vdec, STREAM, FAILED, + ("Failed to create sink buffer"), + ("video sink failed to create video buffer for proxy'ed " "surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(surface_id)); + GST_VAAPI_ID_ARGS(surface_id))); gst_video_decoder_drop_frame(vdec, out_frame); gst_video_codec_frame_unref(out_frame); return GST_FLOW_ERROR; @@ -375,7 +379,9 @@ error_create_buffer: #if GST_CHECK_VERSION(1,0,0) error_get_meta: { - GST_ERROR("failed to get vaapi video meta attached to video buffer"); + GST_ELEMENT_ERROR(vdec, STREAM, FAILED, + ("Failed to get vaapi video meta attached to video buffer"), + ("Failed to get vaapi video meta attached to video buffer")); gst_video_decoder_drop_frame(vdec, out_frame); gst_video_codec_frame_unref(out_frame); return GST_FLOW_ERROR; @@ -423,6 +429,8 @@ gst_vaapidecode_decode_loop(GstVaapiDecode *decode) ret = GST_VIDEO_DECODER_FLOW_NEED_DATA; break; default: + GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding failed"), + ("Unknown decoding error")); ret = GST_FLOW_ERROR; break; } diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index ca681aa3f9..691d02786b 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -865,12 +865,16 @@ done: /* ERRORS */ error_no_pool: { - GST_ERROR ("no buffer pool was negotiated"); + GST_ELEMENT_ERROR (plugin, STREAM, FAILED, + ("no buffer pool was negotiated"), + ("no buffer pool was negotiated")); return GST_FLOW_ERROR; } error_active_pool: { - GST_ERROR ("failed to activate buffer pool"); + GST_ELEMENT_ERROR (plugin, STREAM, FAILED, + ("failed to activate buffer pool"), + ("failed to activate buffer pool")); return GST_FLOW_ERROR; } error_map_dst_buffer: @@ -907,17 +911,21 @@ error_map_src_buffer: /* ERRORS */ error_invalid_buffer: { - GST_ERROR ("failed to validate source buffer"); + GST_ELEMENT_ERROR (plugin, STREAM, FAILED, + ("failed to validate source buffer"), + ("failed to validate source buffer")); return GST_FLOW_ERROR; } error_create_buffer: { - GST_ERROR ("failed to create buffer"); + GST_ELEMENT_ERROR (plugin, STREAM, FAILED, ("Allocation failed"), + ("failed to create buffer")); return GST_FLOW_ERROR; } error_bind_dma_buffer: { - GST_ERROR ("failed to bind dma_buf to VA surface buffer"); + GST_ELEMENT_ERROR (plugin, STREAM, FAILED, ("Allocation failed"), + ("failed to bind dma_buf to VA surface buffer")); gst_buffer_unref (outbuf); return GST_FLOW_ERROR; } From 481d6b1f250e8471b60eeb2a219867c7a3a978fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 18 Feb 2015 11:20:42 +0200 Subject: [PATCH 1882/3781] VC1: decoder: Ignore VC1 user BDU's Don't return error if the processed BDU is a user one, just ignore them. https://bugzilla.gnome.org/show_bug.cgi?id=741237 Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 372c58214f..d37ae9bb12 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1071,6 +1071,13 @@ decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu) case GST_VC1_END_OF_SEQ: status = decode_sequence_end(decoder); break; + case GST_VC1_FIELD_USER: + case GST_VC1_FRAME_USER: + case GST_VC1_ENTRY_POINT_USER: + case GST_VC1_SEQUENCE_USER: + /* Let's just ignore them */ + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; default: GST_WARNING("unsupported BDU type %d", ebdu->type); status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; From ee0855dc65251e07de89dc4368ba90aa1c01881a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 18 Feb 2015 11:21:35 +0200 Subject: [PATCH 1883/3781] vaapidecode: log flow error name https://bugzilla.gnome.org/show_bug.cgi?id=744387 --- gst/vaapi/gstvaapidecode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 014e1eafef..38afb31981 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -390,7 +390,8 @@ error_get_meta: error_commit_buffer: { if (ret != GST_FLOW_FLUSHING) - GST_ERROR("video sink rejected the video buffer (error %d)", ret); + GST_ERROR("video sink rejected the video buffer (error: %s [%d])", + gst_flow_get_name (ret), ret); gst_video_codec_frame_unref(out_frame); return ret; } From ce4d3355e151ddfd055450000ea293b7a089ed33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 18 Feb 2015 11:22:21 +0200 Subject: [PATCH 1884/3781] vaapidecode: Use GST_DEBUG_FUNCPTR for gst_vaapidecode_query() Hence the function name is shown in the gst-inspect-1.0 information rather than the memory address. https://bugzilla.gnome.org/show_bug.cgi?id=744330 --- gst/vaapi/gstvaapidecode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 38afb31981..1513e33483 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1032,12 +1032,12 @@ gst_vaapidecode_init(GstVaapiDecode *decode) /* Pad through which data comes in to the element */ pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD(decode); - gst_pad_set_query_function(pad, gst_vaapidecode_query); + gst_pad_set_query_function(pad, GST_DEBUG_FUNCPTR(gst_vaapidecode_query)); #if !GST_CHECK_VERSION(1,0,0) gst_pad_set_getcaps_function(pad, gst_vaapidecode_get_caps); #endif /* Pad through which data goes out of the element */ pad = GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode); - gst_pad_set_query_function(pad, gst_vaapidecode_query); + gst_pad_set_query_function(pad, GST_DEBUG_FUNCPTR(gst_vaapidecode_query)); } From 671b1ea305843eb747b0edcb62e0fca0e1471019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 18 Feb 2015 11:46:11 +0200 Subject: [PATCH 1885/3781] Fix compiler warnings This patch fixes some warnings that gcc 4.9 reports. https://bugzilla.gnome.org/show_bug.cgi?id=744411 --- gst-libs/gst/vaapi/Makefile.am | 2 +- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 3 ++- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 3 +-- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 22 ---------------------- gst/vaapi/gstvaapivideomemory.c | 2 +- 7 files changed, 7 insertions(+), 29 deletions(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 8332af4de3..57b831350e 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -454,7 +454,6 @@ libgstvaapi_wayland_@GST_API_VERSION@_la_CFLAGS = \ $(GST_VIDEO_CFLAGS) \ $(WAYLAND_CFLAGS) \ $(LIBVA_WAYLAND_CFLAGS) \ - $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la \ $(NULL) libgstvaapi_wayland_@GST_API_VERSION@_la_LIBADD = \ @@ -464,6 +463,7 @@ libgstvaapi_wayland_@GST_API_VERSION@_la_LIBADD = \ $(WAYLAND_LIBS) \ $(LIBVA_WAYLAND_LIBS) \ libgstvaapi-$(GST_API_VERSION).la \ + $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la \ $(NULL) libgstvaapi_wayland_@GST_API_VERSION@_la_LDFLAGS = \ diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index 22e17f2a96..c8904a720c 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -286,7 +286,7 @@ gst_vaapi_buffer_proxy_get_type (GstVaapiBufferProxy * proxy) guintptr gst_vaapi_buffer_proxy_get_handle (GstVaapiBufferProxy * proxy) { - g_return_val_if_fail (proxy != NULL, NULL); + g_return_val_if_fail (proxy != NULL, 0); return GST_VAAPI_BUFFER_PROXY_HANDLE (proxy); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index fde845086b..3ef4cbab8b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -908,8 +908,9 @@ gst_interlace_mode_to_string (GstVideoInterlaceMode mode) return "interleaved"; case GST_VIDEO_INTERLACE_MODE_MIXED: return "mixed"; + default: + return ""; } - return ""; } void diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 9730e124ab..ffc06d5723 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2561,7 +2561,7 @@ exec_picture_refs_modification_1( GstH264RefPicListModification *ref_pic_list_modification; guint num_ref_pic_list_modifications; GstVaapiPictureH264 **ref_list; - guint *ref_list_count_ptr, ref_list_count, ref_list_idx = 0; + guint *ref_list_count_ptr, ref_list_idx = 0; const guint16 *view_ids = NULL; guint i, j, n, num_refs, num_view_ids = 0; gint found_ref_idx; @@ -2611,7 +2611,6 @@ exec_picture_refs_modification_1( } } } - ref_list_count = *ref_list_count_ptr; if (!GST_VAAPI_PICTURE_IS_FRAME(picture)) { MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 0115c74648..fc37102998 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -2134,7 +2134,7 @@ gst_vaapi_display_has_opengl (GstVaapiDisplay * display) { GstVaapiDisplayClass *klass; - g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (display != NULL, FALSE); klass = GST_VAAPI_DISPLAY_GET_CLASS (display); return (klass->display_type == GST_VAAPI_DISPLAY_TYPE_GLX); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 785b3bb45f..f959b268c4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -134,8 +134,6 @@ generate_sampling_factors (GstVaapiEncoderJpeg * encoder) static GstVaapiEncoderStatus ensure_profile (GstVaapiEncoderJpeg * encoder) { - GstVaapiProfile profile; - /* Always start from "simple" profile for maximum compatibility */ encoder->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; @@ -210,9 +208,7 @@ fill_picture (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) { - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); VAEncPictureParameterBufferJPEG *const pic_param = picture->param; - GstVideoInfo *vinfo = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); memset (pic_param, 0, sizeof (VAEncPictureParameterBufferJPEG)); @@ -572,13 +568,6 @@ bs_write_jpeg_header (GstBitWriter * bs, GstVaapiEncoderJpeg * encoder, gst_bit_writer_put_bits_uint8 (bs, 0, 4); //0 for Baseline return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write Jpeg raw data header"); - return FALSE; - } } static gboolean @@ -611,14 +600,6 @@ add_packed_header (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture) gst_bit_writer_clear (&bs, TRUE); return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write Packed Raw Data header"); - gst_bit_writer_clear (&bs, TRUE); - return FALSE; - } } static gboolean @@ -722,9 +703,6 @@ gst_vaapi_encoder_jpeg_reconfigure (GstVaapiEncoder * base_encoder) generate_sampling_factors (encoder); return set_context_info (base_encoder); - -error: - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } static gboolean diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 04b49f247e..96a4b1e04c 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -370,7 +370,7 @@ gst_vaapi_video_memory_reset_surface (GstVaapiVideoMemory * mem) gboolean gst_vaapi_video_memory_sync (GstVaapiVideoMemory * mem) { - g_return_val_if_fail (mem, NULL); + g_return_val_if_fail (mem, FALSE); return ensure_surface_is_current (mem); } From 7ca05917591b3477a7d68a1e5adc308737b9e3e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 18 Feb 2015 13:36:16 +0200 Subject: [PATCH 1886/3781] vaapidecode: intersect filter from query caps According to documentation[1] when receiving a GST_QUERY_CAPS the return value should be all formats that this elements supports, taking into account limitations of peer elements further downstream or upstream, sorted by order of preference, highest preference first. This patch add those limitations intersecting with the received filter in the query. Also takes into account the already negotiated caps. Also adds the processing of the query on the SRC pad. 1. http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-nego-getcaps.html https://bugzilla.gnome.org/show_bug.cgi?id=744406 --- gst/vaapi/gstvaapidecode.c | 56 +++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1513e33483..e48fdba86e 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -990,7 +990,24 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) switch (GST_QUERY_TYPE(query)) { #if GST_CHECK_VERSION(1,0,0) case GST_QUERY_CAPS: { - GstCaps * const caps = gst_vaapidecode_get_caps(pad); + GstCaps *filter, *caps = NULL; + + gst_query_parse_caps(query, &filter); + if (!decode->sinkpad_caps) + caps = gst_vaapidecode_get_caps(pad); + else + caps = gst_caps_ref(decode->sinkpad_caps); + + if (filter) { + GstCaps *tmp = caps; + caps = gst_caps_intersect_full(filter, tmp, + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref(tmp); + } + + GST_DEBUG_OBJECT(decode, "Returning sink caps %" GST_PTR_FORMAT, + caps); + gst_query_set_caps_result(query, caps); gst_caps_unref(caps); res = TRUE; @@ -1003,9 +1020,40 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) break; } } - else - res = GST_PAD_QUERY_FUNCTION_CALL(plugin->srcpad_query, pad, - parent, query); + else { + switch (GST_QUERY_TYPE(query)) { +#if GST_CHECK_VERSION(1,0,0) + case GST_QUERY_CAPS: { + GstCaps *filter, *caps = NULL; + + gst_query_parse_caps(query, &filter); + if (!decode->srcpad_caps) + caps = gst_pad_get_pad_template_caps(pad); + else + caps = gst_caps_ref(decode->srcpad_caps); + + if (filter) { + GstCaps *tmp = caps; + caps = gst_caps_intersect_full(filter, tmp, + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref(tmp); + } + + GST_DEBUG_OBJECT(decode, "Returning src caps %" GST_PTR_FORMAT, + caps); + + gst_query_set_caps_result(query, caps); + gst_caps_unref(caps); + res = TRUE; + break; + } +#endif + default: + res = GST_PAD_QUERY_FUNCTION_CALL(plugin->srcpad_query, pad, + parent, query); + break; + } + } gst_object_unref(decode); return res; From 82e12a933e5a10443e30ee044b28f439480065bc Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 19 Feb 2015 13:37:09 +0200 Subject: [PATCH 1887/3781] vaapidecode: Caps query should return the list of all supported caps. Query caps filtering should be always done on top of allowed caps instead of existing fixed caps on a particular pad. This fixes the mvc stream decoding when there is a base view(high profile) and non-base view(stereo-high profile). --- gst/vaapi/gstvaapidecode.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index e48fdba86e..02745030c5 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -993,10 +993,7 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) GstCaps *filter, *caps = NULL; gst_query_parse_caps(query, &filter); - if (!decode->sinkpad_caps) - caps = gst_vaapidecode_get_caps(pad); - else - caps = gst_caps_ref(decode->sinkpad_caps); + caps = gst_vaapidecode_get_caps(pad); if (filter) { GstCaps *tmp = caps; @@ -1027,10 +1024,7 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) GstCaps *filter, *caps = NULL; gst_query_parse_caps(query, &filter); - if (!decode->srcpad_caps) - caps = gst_pad_get_pad_template_caps(pad); - else - caps = gst_caps_ref(decode->srcpad_caps); + caps = gst_pad_get_pad_template_caps(pad); if (filter) { GstCaps *tmp = caps; From 9b9878c96d1a43e53bb5e00d4f589595494e0d05 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 22 Jan 2015 22:45:24 +0100 Subject: [PATCH 1888/3781] vaapidecode: partially revert 0777f35. Reset the VA decoder after updating the base plugin caps, and most importantly, after GstVideoDecoder negotiation. The reason behind this is that the negotiation could trigger a last decide_allocation() where we could actually derive a new GstVaapiDisplay to use from the downstream element. e.g. GLX backend. --- gst/vaapi/gstvaapidecode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 02745030c5..3841ae166c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -755,8 +755,6 @@ gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) return FALSE; if (!gst_vaapi_plugin_base_set_caps(plugin, decode->sinkpad_caps, NULL)) return FALSE; - if (!gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, FALSE)) - return FALSE; if (gst_vaapidecode_update_src_caps(decode, state)) { if (!gst_video_decoder_negotiate(vdec)) @@ -764,6 +762,9 @@ gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) if (!gst_vaapi_plugin_base_set_caps(plugin, NULL, decode->srcpad_caps)) return FALSE; } + + if (!gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, FALSE)) + return FALSE; return TRUE; } From 11b02b05e542ff22591cf00e3c9852cf6991318b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 30 Jan 2015 21:35:10 +0100 Subject: [PATCH 1889/3781] libs: re-indent all GValue related source code. --- gst-libs/gst/vaapi/gstvaapivalue.c | 221 +++++++++++++++-------------- 1 file changed, 111 insertions(+), 110 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index fa825fd60d..b014af1814 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -32,172 +32,173 @@ #include "gstvaapivalue.h" static gpointer -default_copy_func(gpointer data) +default_copy_func (gpointer data) { - return data; + return data; } static void -default_free_func(gpointer data) +default_free_func (gpointer data) { } /* --- GstVaapiPoint --- */ GType -gst_vaapi_point_get_type(void) +gst_vaapi_point_get_type (void) { - static volatile gsize g_type = 0; + static volatile gsize g_type = 0; - if (g_once_init_enter(&g_type)) { - GType type = g_boxed_type_register_static( - g_intern_static_string("GstVaapiPoint"), - default_copy_func, default_free_func); - g_once_init_leave(&g_type, type); - } - return g_type; + if (g_once_init_enter (&g_type)) { + GType type = + g_boxed_type_register_static (g_intern_static_string ("GstVaapiPoint"), + default_copy_func, default_free_func); + g_once_init_leave (&g_type, type); + } + return g_type; } /* --- GstVaapiRectangle --- */ GType -gst_vaapi_rectangle_get_type(void) +gst_vaapi_rectangle_get_type (void) { - static volatile gsize g_type = 0; + static volatile gsize g_type = 0; - if (g_once_init_enter(&g_type)) { - GType type = g_boxed_type_register_static( - g_intern_static_string("GstVaapiRectangle"), - default_copy_func, default_free_func); - g_once_init_leave(&g_type, type); - } - return g_type; + if (g_once_init_enter (&g_type)) { + GType type = + g_boxed_type_register_static (g_intern_static_string + ("GstVaapiRectangle"), + default_copy_func, default_free_func); + g_once_init_leave (&g_type, type); + } + return g_type; } /* --- GstVaapiRenderMode --- */ GType -gst_vaapi_render_mode_get_type(void) +gst_vaapi_render_mode_get_type (void) { - static GType render_mode_type = 0; + static GType render_mode_type = 0; - static const GEnumValue render_modes[] = { - { GST_VAAPI_RENDER_MODE_OVERLAY, - "Overlay render mode", "overlay" }, - { GST_VAAPI_RENDER_MODE_TEXTURE, - "Textured-blit render mode", "texture" }, - { 0, NULL, NULL } - }; + static const GEnumValue render_modes[] = { + {GST_VAAPI_RENDER_MODE_OVERLAY, + "Overlay render mode", "overlay"}, + {GST_VAAPI_RENDER_MODE_TEXTURE, + "Textured-blit render mode", "texture"}, + {0, NULL, NULL} + }; - if (!render_mode_type) { - render_mode_type = - g_enum_register_static("GstVaapiRenderMode", render_modes); - } - return render_mode_type; + if (!render_mode_type) { + render_mode_type = + g_enum_register_static ("GstVaapiRenderMode", render_modes); + } + return render_mode_type; } /* --- GstVaapiRotation --- */ GType -gst_vaapi_rotation_get_type(void) +gst_vaapi_rotation_get_type (void) { - static GType g_type = 0; + static GType g_type = 0; - static const GEnumValue rotation_values[] = { - { GST_VAAPI_ROTATION_0, - "Unrotated mode", "0" }, - { GST_VAAPI_ROTATION_90, - "Rotated by 90°, clockwise", "90" }, - { GST_VAAPI_ROTATION_180, - "Rotated by 180°, clockwise", "180" }, - { GST_VAAPI_ROTATION_270, - "Rotated by 270°, clockwise", "270" }, - { 0, NULL, NULL }, - }; + static const GEnumValue rotation_values[] = { + {GST_VAAPI_ROTATION_0, + "Unrotated mode", "0"}, + {GST_VAAPI_ROTATION_90, + "Rotated by 90°, clockwise", "90"}, + {GST_VAAPI_ROTATION_180, + "Rotated by 180°, clockwise", "180"}, + {GST_VAAPI_ROTATION_270, + "Rotated by 270°, clockwise", "270"}, + {0, NULL, NULL}, + }; - if (!g_type) - g_type = g_enum_register_static("GstVaapiRotation", rotation_values); - return g_type; + if (!g_type) + g_type = g_enum_register_static ("GstVaapiRotation", rotation_values); + return g_type; } /* --- GstVaapiRateControl --- */ GType -gst_vaapi_rate_control_get_type(void) +gst_vaapi_rate_control_get_type (void) { - static volatile gsize g_type = 0; + static volatile gsize g_type = 0; - static const GEnumValue rate_control_values[] = { - { GST_VAAPI_RATECONTROL_NONE, - "None", "none" }, - { GST_VAAPI_RATECONTROL_CQP, - "Constant QP", "cqp" }, - { GST_VAAPI_RATECONTROL_CBR, - "Constant bitrate", "cbr" }, - { GST_VAAPI_RATECONTROL_VCM, - "Video conference", "vcm" }, - { GST_VAAPI_RATECONTROL_VBR, - "Variable bitrate", "vbr" }, - { GST_VAAPI_RATECONTROL_VBR_CONSTRAINED, - "Variable bitrate - Constrained", "vbr_constrained" }, - { 0, NULL, NULL }, - }; + static const GEnumValue rate_control_values[] = { + {GST_VAAPI_RATECONTROL_NONE, + "None", "none"}, + {GST_VAAPI_RATECONTROL_CQP, + "Constant QP", "cqp"}, + {GST_VAAPI_RATECONTROL_CBR, + "Constant bitrate", "cbr"}, + {GST_VAAPI_RATECONTROL_VCM, + "Video conference", "vcm"}, + {GST_VAAPI_RATECONTROL_VBR, + "Variable bitrate", "vbr"}, + {GST_VAAPI_RATECONTROL_VBR_CONSTRAINED, + "Variable bitrate - Constrained", "vbr_constrained"}, + {0, NULL, NULL}, + }; - if (g_once_init_enter(&g_type)) { - GType type = g_enum_register_static("GstVaapiRateControl", - rate_control_values); - g_once_init_leave(&g_type, type); - } - return g_type; + if (g_once_init_enter (&g_type)) { + GType type = g_enum_register_static ("GstVaapiRateControl", + rate_control_values); + g_once_init_leave (&g_type, type); + } + return g_type; } static gboolean -build_enum_subset_values_from_mask (GstVaapiEnumSubset *subset, guint32 mask) +build_enum_subset_values_from_mask (GstVaapiEnumSubset * subset, guint32 mask) { - GEnumClass *enum_class; - const GEnumValue *value; - guint i, n; + GEnumClass *enum_class; + const GEnumValue *value; + guint i, n; - enum_class = g_type_class_ref(subset->parent_type); - if (!enum_class) - return FALSE; + enum_class = g_type_class_ref (subset->parent_type); + if (!enum_class) + return FALSE; - for (i = 0, n = 0; i < 32 && n < subset->num_values; i++) { - if (!(mask & (1U << i))) - continue; - value = g_enum_get_value(enum_class, i); - if (!value) - continue; - subset->values[n++] = *value; - } - g_type_class_unref(enum_class); - if (n != subset->num_values - 1) - goto error_invalid_num_values; - return TRUE; + for (i = 0, n = 0; i < 32 && n < subset->num_values; i++) { + if (!(mask & (1U << i))) + continue; + value = g_enum_get_value (enum_class, i); + if (!value) + continue; + subset->values[n++] = *value; + } + g_type_class_unref (enum_class); + if (n != subset->num_values - 1) + goto error_invalid_num_values; + return TRUE; - /* ERRORS */ + /* ERRORS */ error_invalid_num_values: - { - g_error("invalid number of static values for `%s'", subset->type_name); - return FALSE; - } + { + g_error ("invalid number of static values for `%s'", subset->type_name); + return FALSE; + } } GType -gst_vaapi_type_define_enum_subset_from_mask(GstVaapiEnumSubset *subset, +gst_vaapi_type_define_enum_subset_from_mask (GstVaapiEnumSubset * subset, guint32 mask) { - if (g_once_init_enter(&subset->type)) { - GType type; + if (g_once_init_enter (&subset->type)) { + GType type; - build_enum_subset_values_from_mask(subset, mask); - memset(&subset->type_info, 0, sizeof(subset->type_info)); - g_enum_complete_type_info(subset->parent_type, &subset->type_info, - subset->values); + build_enum_subset_values_from_mask (subset, mask); + memset (&subset->type_info, 0, sizeof (subset->type_info)); + g_enum_complete_type_info (subset->parent_type, &subset->type_info, + subset->values); - type = g_type_register_static (G_TYPE_ENUM, subset->type_name, - &subset->type_info, 0); - g_once_init_leave(&subset->type, type); - } - return subset->type; + type = g_type_register_static (G_TYPE_ENUM, subset->type_name, + &subset->type_info, 0); + g_once_init_leave (&subset->type, type); + } + return subset->type; } From 91c5d948be120c256245724fbd7e54fd38e2e49e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 30 Jan 2015 21:38:07 +0100 Subject: [PATCH 1890/3781] libs: initialize GValues in a thread-safe manner. --- gst-libs/gst/vaapi/gstvaapivalue.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index b014af1814..e6bacfbed0 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -80,7 +80,7 @@ gst_vaapi_rectangle_get_type (void) GType gst_vaapi_render_mode_get_type (void) { - static GType render_mode_type = 0; + static volatile gsize g_type = 0; static const GEnumValue render_modes[] = { {GST_VAAPI_RENDER_MODE_OVERLAY, @@ -90,11 +90,11 @@ gst_vaapi_render_mode_get_type (void) {0, NULL, NULL} }; - if (!render_mode_type) { - render_mode_type = - g_enum_register_static ("GstVaapiRenderMode", render_modes); + if (g_once_init_enter (&g_type)) { + GType type = g_enum_register_static ("GstVaapiRenderMode", render_modes); + g_once_init_leave (&g_type, type); } - return render_mode_type; + return g_type; } /* --- GstVaapiRotation --- */ @@ -102,7 +102,7 @@ gst_vaapi_render_mode_get_type (void) GType gst_vaapi_rotation_get_type (void) { - static GType g_type = 0; + static volatile gsize g_type = 0; static const GEnumValue rotation_values[] = { {GST_VAAPI_ROTATION_0, @@ -116,8 +116,10 @@ gst_vaapi_rotation_get_type (void) {0, NULL, NULL}, }; - if (!g_type) - g_type = g_enum_register_static ("GstVaapiRotation", rotation_values); + if (g_once_init_enter (&g_type)) { + GType type = g_enum_register_static ("GstVaapiRotation", rotation_values); + g_once_init_leave (&g_type, type); + } return g_type; } From 1e7c4db5a740df7b68547c091148dc27f80388d7 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Feb 2015 15:27:53 +0100 Subject: [PATCH 1891/3781] Add initial support for EGL. Add initial support for EGL to libgstvaapi core library. The target display server and the desired OpenGL API can be programmatically selected at run-time. A comprehensive set of EGL utilities are provided to support those dynamic selection needs, but also most importantly to ensure that the GL command stream is executed from within a single thread. https://bugzilla.gnome.org/show_bug.cgi?id=743846 --- configure.ac | 94 ++ gst-libs/gst/vaapi/Makefile.am | 61 + gst-libs/gst/vaapi/egl_compat.h | 39 + gst-libs/gst/vaapi/egl_vtable.h | 785 ++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.c | 7 +- gst-libs/gst/vaapi/gstvaapidisplay.h | 2 + gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 582 +++++++ gst-libs/gst/vaapi/gstvaapidisplay_egl.h | 55 + gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h | 101 ++ gst-libs/gst/vaapi/gstvaapiutils_egl.c | 1342 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_egl.h | 238 +++ gst-libs/gst/vaapi/ogl_compat.h | 104 ++ 12 files changed, 3409 insertions(+), 1 deletion(-) create mode 100644 gst-libs/gst/vaapi/egl_compat.h create mode 100644 gst-libs/gst/vaapi/egl_vtable.h create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_egl.c create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_egl.h create mode 100644 gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_egl.c create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_egl.h create mode 100644 gst-libs/gst/vaapi/ogl_compat.h diff --git a/configure.ac b/configure.ac index f4efae0adf..e728459583 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,9 @@ m4_if(gst_vaapi_pre_version, [0], [], [ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) ]) +# Configure defaults +m4_define([default_glapi], [any]) + # gstreamer-vaapi library (libtool) version number m4_define([gst_vaapi_lt_current], [6]) m4_define([gst0_vaapi_lt_current_bias], [0]) @@ -147,6 +150,16 @@ AC_ARG_ENABLE(wayland, [enable Wayland output @<:@default=yes@:>@]), [], [enable_wayland="yes"]) +AC_ARG_ENABLE([egl], + AS_HELP_STRING([--enable-egl], + [enable EGL output @<:@default=yes@:>@]), + [], [enable_egl="yes"]) + +AC_ARG_WITH([glapi], + AS_HELP_STRING([--with-glapi=APIs], + [build with the specified OpenGL APIs @<:@default=default_glapi@:>@]), + [GLAPI="$with_glapi"], [GLAPI=default_glapi]) + AC_ARG_WITH([gstreamer-api], AC_HELP_STRING([--with-gstreamer-api=VERSION], [build against the specified GStreamer API version @@ -205,6 +218,9 @@ if test -z "$GST_PKG_VERSION"; then fi AC_MSG_RESULT([$GST_API_VERSION]) +AC_DEFINE_UNQUOTED([GST_API_VERSION_S], ["$GST_API_VERSION"], + [Defined to the string representation of GStreamer version]) + dnl Versions for GStreamer and plugins-base case $GST_API_VERSION in 0.10) @@ -265,6 +281,9 @@ if test "$USE_GST_API_1_2p" = "yes" || test "$USE_GST_API_1_4p" = "yes" ; then fi AC_SUBST([GST_PKG_VERSION]) +AC_DEFINE_UNQUOTED([GST_PKG_VERSION_S], ["$GST_PKG_VERSION"], + [Defined to the string representation of GStreamer API version]) + dnl Validate certain features if test "$USE_GST_API_0_10" = "yes"; then AC_MSG_WARN([support for GStreamer 0.10 is obsolete, and will be removed]) @@ -494,6 +513,9 @@ esac GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - "$lt_bias"` AC_SUBST(GST_VAAPI_MAJOR_VERSION) +AC_DEFINE_UNQUOTED([GST_VAAPI_MAJOR_VERSION_S], ["$GST_VAAPI_MAJOR_VERSION"], + [Defined to the string representation of gstreamer-vaapi major version]) + dnl GST_VAAPI_LT_LDFLAGS: GST_VAAPI_LT_CURRENT="$GST_VAAPI_MAJOR_VERSION" GST_VAAPI_LT_REV=gst_vaapi_lt_revision @@ -614,9 +636,15 @@ enable_opengl="no" if test "$enable_glx" = "yes"; then enable_opengl="yes" fi +if test "$enable_egl" = "yes"; then + enable_opengl="yes" +fi +GLES_VERSION_MASK=0 HAVE_GL=0 if test "$enable_opengl" = "yes"; then +case ",$GLAPI," in +(*,any,*|*,gl,*) HAVE_GL=1 PKG_CHECK_MODULES([GL], [gl], [:], [HAVE_GL=0]) saved_CPPFLAGS="$CPPFLAGS" @@ -627,7 +655,52 @@ if test "$enable_opengl" = "yes"; then #endif ]) CPPFLAGS="$saved_CPPFLAGS" + ;; +esac fi +GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GL "*" 1` + +dnl OpenGL|ESv2 +HAVE_GLESv2=0 +if test "$enable_opengl" = "yes"; then +case ",$GLAPI," in +(*,any,*|*,gles2,*) + HAVE_GLESv2=1 + PKG_CHECK_MODULES([GLES2], [glesv2], [:], [HAVE_GLESv2=0]) + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GLES2_CFLAGS" + AC_CHECK_HEADERS([GLES2/gl2.h GLES2/gl2ext.h], [:], + [HAVE_GLESv2=0], [ +#ifdef HAVE_GLES2_GL2_H +# include +#endif + ]) + CPPFLAGS="$saved_CPPFLAGS" + ;; +esac +fi +GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GLESv2 "*" 4` + +dnl OpenGL|ESv3 +HAVE_GLESv3=0 +if test "$enable_opengl" = "yes"; then +case ",$GLAPI," in +(*,any,*|*,gles3,*) + HAVE_GLESv3=1 + PKG_CHECK_MODULES([GLES3], [glesv2], [:], [HAVE_GLESv3=0]) + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GLES3_CFLAGS" + AC_CHECK_HEADERS([GLES3/gl3.h GLES3/gl3ext.h GLES2/gl2ext.h], [:], + [HAVE_GLESv3=0], [ +#ifdef HAVE_GLES3_GL3_H +# include +#endif + ]) + CPPFLAGS="$saved_CPPFLAGS" + ;; +esac +fi +GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GLESv3 "*" 8` dnl ... GLX USE_GLX=0 @@ -647,6 +720,19 @@ if test "$enable_glx" = "yes" -a $HAVE_GL -eq 1 -a $USE_X11 -eq 1; then LIBS="$saved_LIBS" fi +dnl ... EGL +USE_EGL=0 +if test "$enable_egl" = "yes" -a $GLES_VERSION_MASK -ne 0; then + USE_EGL=1 + PKG_CHECK_MODULES([EGL], [egl], [:], [USE_EGL=0]) + saved_CPPFLAGS="$CPPFLAGS" + saved_LIBS="$LIBS" + AC_CHECK_HEADERS([EGL/egl.h], [:], [USE_EGL=0]) + AC_CHECK_LIB([EGL], [eglGetDisplay], [:], [USE_EGL=0]) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +fi + dnl Check for Wayland USE_WAYLAND=0 if test "$enable_wayland" = "yes"; then @@ -920,6 +1006,13 @@ AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) +AC_DEFINE_UNQUOTED([USE_EGL], [$USE_EGL], + [Defined to 1 if EGL is enabled]) +AM_CONDITIONAL([USE_EGL], [test $USE_EGL -eq 1]) + +AC_DEFINE_UNQUOTED([USE_GLES_VERSION_MASK], [$GLES_VERSION_MASK], + [Defined to the set of enabled OpenGL ES APIs]) + AC_DEFINE_UNQUOTED(USE_WAYLAND, $USE_WAYLAND, [Defined to 1 if WAYLAND is enabled]) AM_CONDITIONAL(USE_WAYLAND, test $USE_WAYLAND -eq 1) @@ -990,6 +1083,7 @@ VIDEO_OUTPUTS="" AS_IF([test $USE_DRM -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS drm"]) AS_IF([test $USE_X11 -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS x11"]) AS_IF([test $USE_GLX -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS glx"]) +AS_IF([test $USE_EGL -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS egl"]) AS_IF([test $USE_WAYLAND -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS wayland"]) echo diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 57b831350e..a329e8fe7d 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -12,6 +12,10 @@ if USE_GLX lib_LTLIBRARIES += libgstvaapi-glx-@GST_API_VERSION@.la endif +if USE_EGL +lib_LTLIBRARIES += libgstvaapi-egl-@GST_API_VERSION@.la +endif + if USE_WAYLAND lib_LTLIBRARIES += libgstvaapi-wayland-@GST_API_VERSION@.la endif @@ -271,6 +275,23 @@ libgstvaapi_glx_source_priv_h = \ gstvaapiutils_x11.h \ $(NULL) +libgstvaapi_egl_source_c = \ + gstvaapidisplay_egl.c \ + gstvaapiutils_egl.c \ + $(NULL) + +libgstvaapi_egl_source_h = \ + gstvaapidisplay_egl.h \ + $(NULL) + +libgstvaapi_egl_source_priv_h = \ + egl_compat.h \ + egl_vtable.h \ + gstvaapidisplay_egl_priv.h \ + gstvaapiutils_egl.h \ + ogl_compat.h \ + $(NULL) + libgstvaapi_wayland_source_c = \ gstvaapidisplay_wayland.c \ gstvaapiutils.c \ @@ -433,6 +454,43 @@ libgstvaapi_glx_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) +libgstvaapi_egl_@GST_API_VERSION@_la_SOURCES = \ + $(libgstvaapi_egl_source_c) \ + $(libgstvaapi_egl_source_priv_h) \ + $(NULL) + +libgstvaapi_egl_@GST_API_VERSION@include_HEADERS = \ + $(libgstvaapi_egl_source_h) \ + $(NULL) + +libgstvaapi_egl_@GST_API_VERSION@includedir = \ + $(libgstvaapi_includedir) + +libgstvaapi_egl_@GST_API_VERSION@_la_CFLAGS = \ + -DIN_LIBGSTVAAPI \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + $(GLIB_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ + $(EGL_CFLAGS) \ + $(NULL) + +libgstvaapi_egl_@GST_API_VERSION@_la_LIBADD = \ + $(GLIB_LIBS) \ + $(GST_LIBS) \ + $(GST_BASE_LIBS) \ + $(GST_VIDEO_LIBS) \ + libgstvaapi-$(GST_API_VERSION).la \ + $(EGL_LIBS) \ + $(DLOPEN_LIBS) \ + $(NULL) + +libgstvaapi_egl_@GST_API_VERSION@_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(GST_VAAPI_LT_LDFLAGS) \ + $(NULL) + libgstvaapi_wayland_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_wayland_source_c) \ $(libgstvaapi_wayland_source_priv_h) \ @@ -513,6 +571,9 @@ EXTRA_DIST += \ $(libgstvaapi_jpegenc_source_c) \ $(libgstvaapi_vp8enc_source_h) \ $(libgstvaapi_vp8enc_source_c) \ + $(libgstvaapi_egl_source_c) \ + $(libgstvaapi_egl_source_h) \ + $(libgstvaapi_egl_source_priv_h) \ $(NULL) CLEANFILES = \ diff --git a/gst-libs/gst/vaapi/egl_compat.h b/gst-libs/gst/vaapi/egl_compat.h new file mode 100644 index 0000000000..c417211678 --- /dev/null +++ b/gst-libs/gst/vaapi/egl_compat.h @@ -0,0 +1,39 @@ +/* + * egl_compat.h - EGL compatiliby layer + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 +#include +#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 */ diff --git a/gst-libs/gst/vaapi/egl_vtable.h b/gst-libs/gst/vaapi/egl_vtable.h new file mode 100644 index 0000000000..89c5d029a0 --- /dev/null +++ b/gst-libs/gst/vaapi/egl_vtable.h @@ -0,0 +1,785 @@ +/* + * egl_vtable.h - EGL function definitions + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_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) + +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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index fc37102998..3fe523bb84 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -163,6 +163,10 @@ gst_vaapi_display_type_get_type (void) {GST_VAAPI_DISPLAY_TYPE_GLX, "VA/GLX display", "glx"}, #endif +#if USE_EGL + {GST_VAAPI_DISPLAY_TYPE_EGL, + "VA/EGL display", "egl"}, +#endif #if USE_WAYLAND {GST_VAAPI_DISPLAY_TYPE_WAYLAND, "VA/Wayland display", "wayland"}, @@ -2137,5 +2141,6 @@ gst_vaapi_display_has_opengl (GstVaapiDisplay * display) g_return_val_if_fail (display != NULL, FALSE); klass = GST_VAAPI_DISPLAY_GET_CLASS (display); - return (klass->display_type == GST_VAAPI_DISPLAY_TYPE_GLX); + return (klass->display_type == GST_VAAPI_DISPLAY_TYPE_GLX || + klass->display_type == GST_VAAPI_DISPLAY_TYPE_EGL); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 998e96ef43..f4cc8653d9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -91,6 +91,7 @@ typedef struct _GstVaapiDisplay GstVaapiDisplay; * @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 { @@ -99,6 +100,7 @@ typedef enum 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 \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c new file mode 100644 index 0000000000..b02f25380f --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -0,0 +1,582 @@ +/* + * gstvaapidisplay_egl.c - VA/EGL display abstraction + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 +#include "gstvaapidisplay_egl.h" +#include "gstvaapidisplay_egl_priv.h" +#include "gstvaapiwindow.h" + +GST_DEBUG_CATEGORY (gst_debug_vaapidisplay_egl); + +/* ------------------------------------------------------------------------- */ +/* --- Display backend loader --- */ +/* ------------------------------------------------------------------------- */ + +typedef struct _GstVaapiDisplayLoader GstVaapiDisplayLoader; +typedef struct _GstVaapiDisplayLoaderInfo GstVaapiDisplayLoaderInfo; + +typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFunc) (const gchar * name); +typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFromNativeFunc) (gpointer dpy); + +struct _GstVaapiDisplayLoader +{ + GstVaapiMiniObject parent_instance; + + GModule *module; + GPtrArray *module_names; + GstVaapiDisplayCreateFunc create_display; + GstVaapiDisplayCreateFromNativeFunc create_display_from_native; +}; + +struct _GstVaapiDisplayLoaderInfo +{ + const gchar *name; + GstVaapiDisplayType type; + const gchar *create_display; + const gchar *create_display_from_native; +}; + +static GMutex g_loader_lock; +static GstVaapiDisplayLoader *g_loader; + +/* *INDENT-OFF* */ +static const GstVaapiDisplayLoaderInfo g_loader_info[] = { +#if USE_WAYLAND + { "wayland", + GST_VAAPI_DISPLAY_TYPE_WAYLAND, + "gst_vaapi_display_wayland_new", + "gst_vaapi_display_wayland_new_with_display", + }, +#endif +#if USE_X11 + { "x11", + GST_VAAPI_DISPLAY_TYPE_X11, + "gst_vaapi_display_x11_new", + "gst_vaapi_display_x11_new_with_display", + }, +#endif + {NULL,} +}; +/* *INDENT-ON* */ + +static void +gst_vaapi_display_loader_finalize (GstVaapiDisplayLoader * loader) +{ + if (!loader) + return; + + if (loader->module) { + g_module_close (loader->module); + loader->module = NULL; + } + + if (loader->module_names) { + g_ptr_array_unref (loader->module_names); + loader->module_names = NULL; + } +} + +static inline const GstVaapiMiniObjectClass * +gst_vaapi_display_loader_class (void) +{ + static const GstVaapiMiniObjectClass g_class = { + .size = sizeof (GstVaapiDisplayLoader), + .finalize = (GDestroyNotify) gst_vaapi_display_loader_finalize, + }; + return &g_class; +} + +static inline GstVaapiDisplayLoader * +gst_vaapi_display_loader_new (void) +{ + return (GstVaapiDisplayLoader *) + gst_vaapi_mini_object_new0 (gst_vaapi_display_loader_class ()); +} + +static gboolean +gst_vaapi_display_loader_reset_module_names (GstVaapiDisplayLoader * loader, + const GstVaapiDisplayLoaderInfo * loader_info) +{ + gchar *module_name; + + if (loader->module_names) + g_ptr_array_unref (loader->module_names); + loader->module_names = g_ptr_array_new_full (3, (GDestroyNotify) g_free); + if (!loader->module_names) + return FALSE; + + module_name = + g_strdup_printf ("libgstvaapi-%s-%s.la", loader_info->name, + GST_API_VERSION_S); + if (module_name) + g_ptr_array_add (loader->module_names, module_name); + + module_name = + g_strdup_printf ("libgstvaapi-%s-%s.so", loader_info->name, + GST_API_VERSION_S); + if (module_name) + g_ptr_array_add (loader->module_names, module_name); + + module_name = + g_strdup_printf ("libgstvaapi-%s-%s.so.%s", loader_info->name, + GST_API_VERSION_S, GST_VAAPI_MAJOR_VERSION_S); + if (module_name) + g_ptr_array_add (loader->module_names, module_name); + + return loader->module_names->len > 0; +} + +static gboolean +gst_vaapi_display_loader_try_load_module (GstVaapiDisplayLoader * loader, + const GstVaapiDisplayLoaderInfo * loader_info) +{ + guint i; + + if (!gst_vaapi_display_loader_reset_module_names (loader, loader_info)) + return FALSE; + + if (loader->module) { + g_module_close (loader->module); + loader->module = NULL; + } + + for (i = 0; i < loader->module_names->len; i++) { + const gchar *const module_name = + g_ptr_array_index (loader->module_names, i); + + loader->module = g_module_open (module_name, + G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + if (loader->module) + return TRUE; + } + return FALSE; +} + +static gboolean +gst_vaapi_display_loader_try_load (GstVaapiDisplayLoader * loader, + const GstVaapiDisplayLoaderInfo * loader_info) +{ + guint has_errors = 0; + + if (!gst_vaapi_display_loader_try_load_module (loader, loader_info)) + return FALSE; + GST_DEBUG ("loaded backend: %s", g_module_name (loader->module)); + + has_errors |= !g_module_symbol (loader->module, + loader_info->create_display, (gpointer *) & loader->create_display); + has_errors |= !g_module_symbol (loader->module, + loader_info->create_display_from_native, + (gpointer *) & loader->create_display_from_native); + + return has_errors == 0; +} + +static GstVaapiDisplay * +gst_vaapi_display_loader_try_load_any (GstVaapiDisplayLoader * loader) +{ + GstVaapiDisplay *display; + const GstVaapiDisplayLoaderInfo *loader_info; + + for (loader_info = g_loader_info; loader_info->name != NULL; loader_info++) { + if (!gst_vaapi_display_loader_try_load (loader, loader_info)) + continue; + + display = loader->create_display (NULL); + if (display) { + GST_INFO ("selected backend: %s", loader_info->name); + return display; + } + } + return NULL; +} + +#define gst_vaapi_display_loader_ref(loader) \ + ((GstVaapiDisplayLoader *) gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (loader))) +#define gst_vaapi_display_loader_unref(loader) \ + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (loader)) +#define gst_vaapi_display_loader_replace(old_loader_ptr, new_loader) \ + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **)(old_loader_ptr), \ + GST_VAAPI_MINI_OBJECT (new_loader)) + +static GstVaapiDisplayLoader * +gst_vaapi_display_loader_acquire_global (void) +{ + GstVaapiDisplayLoader *loader; + + g_mutex_lock (&g_loader_lock); + loader = g_loader ? gst_vaapi_display_loader_ref (g_loader) : + gst_vaapi_display_loader_new (); + g_loader = loader; + g_mutex_unlock (&g_loader_lock); + return loader; +} + +static void +gst_vaapi_display_loader_release_global (void) +{ + g_mutex_lock (&g_loader_lock); + gst_vaapi_display_loader_replace (&g_loader, NULL); + g_mutex_unlock (&g_loader_lock); +} + +static const GstVaapiDisplayLoaderInfo * +gst_vaapi_display_loader_map_lookup_type (GstVaapiDisplayType type) +{ + const GstVaapiDisplayLoaderInfo *loader_info; + + for (loader_info = g_loader_info; loader_info->name != NULL; loader_info++) { + if (loader_info->type == type) + return loader_info; + } + return NULL; +} + +/* ------------------------------------------------------------------------- */ +/* --- EGL backend implementation --- */ +/* ------------------------------------------------------------------------- */ + +static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_EGL; + +typedef struct +{ + gpointer display; + guint display_type; + guint gles_version; +} 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 (GstVaapiDisplayEGL * display, + const InitParams * params) +{ + GstVaapiDisplay *native_display; + GstVaapiDisplayLoader *loader; + const GstVaapiDisplayLoaderInfo *loader_info; + EglDisplay *egl_display; + + loader = gst_vaapi_display_loader_acquire_global (); + if (params->display) { + loader_info = + gst_vaapi_display_loader_map_lookup_type (params->display_type); + if (!loader_info) + goto error_unsupported_display_type; + + loader = gst_vaapi_display_loader_new (); + if (!loader || !gst_vaapi_display_loader_try_load (loader, loader_info)) + goto error_init_loader; + + native_display = loader->create_display_from_native (params->display); + } else { + gst_vaapi_display_loader_ref (loader); + native_display = gst_vaapi_display_loader_try_load_any (loader); + } + gst_vaapi_display_loader_replace (&display->loader, loader); + gst_vaapi_display_loader_unref (loader); + if (!native_display) + return FALSE; + + gst_vaapi_display_replace (&display->display, native_display); + gst_vaapi_display_unref (native_display); + + egl_display = egl_display_new (GST_VAAPI_DISPLAY_NATIVE (display->display)); + 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; + + /* ERRORS */ +error_unsupported_display_type: + GST_ERROR ("unsupported display type (%d)", params->display_type); + return FALSE; +error_init_loader: + GST_ERROR ("failed to initialize display backend loader"); + gst_vaapi_display_loader_replace (&loader, NULL); + return FALSE; +} + +static void +gst_vaapi_display_egl_close_display (GstVaapiDisplayEGL * display) +{ + gst_vaapi_display_replace (&display->display, NULL); + gst_vaapi_display_loader_replace (&display->loader, NULL); + gst_vaapi_display_loader_release_global (); +} + +static void +gst_vaapi_display_egl_lock (GstVaapiDisplayEGL * 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 (GstVaapiDisplayEGL * 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 (GstVaapiDisplayEGL * 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 (GstVaapiDisplayEGL * 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 (GstVaapiDisplayEGL * display, + GstVaapiDisplayInfo * info) +{ + GstVaapiDisplayClass *const klass = + GST_VAAPI_DISPLAY_GET_CLASS (display->display); + + if (klass->get_display && !klass->get_display (display->display, info)) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_display_egl_get_size (GstVaapiDisplayEGL * display, + guint * width_ptr, guint * height_ptr) +{ + 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 (GstVaapiDisplayEGL * display, + guint * width_ptr, guint * height_ptr) +{ + 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 void +gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass) +{ + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapidisplay_egl, "vaapidisplay_egl", 0, + "VA/EGL backend"); + + gst_vaapi_display_class_init (dpy_class); + + object_class->size = sizeof (GstVaapiDisplayEGL); + dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_EGL; + dpy_class->bind_display = (GstVaapiDisplayBindFunc) + gst_vaapi_display_egl_bind_display; + dpy_class->close_display = (GstVaapiDisplayCloseFunc) + gst_vaapi_display_egl_close_display; + dpy_class->lock = (GstVaapiDisplayLockFunc) + gst_vaapi_display_egl_lock; + dpy_class->unlock = (GstVaapiDisplayUnlockFunc) + gst_vaapi_display_egl_unlock; + dpy_class->sync = (GstVaapiDisplaySyncFunc) + gst_vaapi_display_egl_sync; + dpy_class->flush = (GstVaapiDisplayFlushFunc) + gst_vaapi_display_egl_flush; + dpy_class->get_display = (GstVaapiDisplayGetInfoFunc) + gst_vaapi_display_egl_get_display_info; + dpy_class->get_size = (GstVaapiDisplayGetSizeFunc) + gst_vaapi_display_egl_get_size; + dpy_class->get_size_mm = (GstVaapiDisplayGetSizeMFunc) + gst_vaapi_display_egl_get_size_mm; +} + +static inline const GstVaapiDisplayClass * +gst_vaapi_display_egl_class (void) +{ + static GstVaapiDisplayEGLClass g_class; + static gsize g_class_init = FALSE; + + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_display_egl_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS (&g_class); +} + +/** + * 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) +{ + InitParams params; + + if (display) { + params.display = GST_VAAPI_DISPLAY_NATIVE (display); + params.display_type = GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display); + } else { + params.display = NULL; + params.display_type = GST_VAAPI_DISPLAY_TYPE_ANY; + } + params.gles_version = gles_version; + return gst_vaapi_display_new (gst_vaapi_display_egl_class (), + 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) +{ + InitParams params; + + g_return_val_if_fail (native_display != NULL, NULL); + + params.display = native_display; + params.display_type = display_type; + params.gles_version = gles_version; + return gst_vaapi_display_new (gst_vaapi_display_egl_class (), + 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); +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.h b/gst-libs/gst/vaapi/gstvaapidisplay_egl.h new file mode 100644 index 0000000000..2f79e88fdf --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.h @@ -0,0 +1,55 @@ +/* + * gstvaapidisplay_egl.h - VA/EGL display abstraction + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 +#include + +G_BEGIN_DECLS + +typedef struct _GstVaapiDisplayEGL GstVaapiDisplayEGL; + +#define GST_VAAPI_DISPLAY_EGL(obj) \ + ((GstVaapiDisplayEGL *)(obj)) + +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); + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_EGL_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h new file mode 100644 index 0000000000..3db5ad8980 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h @@ -0,0 +1,101 @@ +/* + * gstvaapidisplay_egl_priv.h - Internal VA/EGL interface + * + * Copyright (C) 2014 Splitted-Desktop Systems + * Author: Gwenole Beauchesne + * + * 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 +#include "gstvaapidisplay_egl.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapiutils_egl.h" + +G_BEGIN_DECLS + +#define GST_VAAPI_IS_DISPLAY_EGL(display) \ + ((display) != NULL && \ + GST_VAAPI_DISPLAY_GET_CLASS_TYPE (display) == GST_VAAPI_DISPLAY_TYPE_EGL) + +#define GST_VAAPI_DISPLAY_EGL_CLASS(klass) \ + ((GstVaapiDisplayEGLClass *)(klass)) + +#define GST_VAAPI_DISPLAY_EGL_GET_CLASS(obj) \ + GST_VAAPI_DISPLAY_EGL_CLASS (GST_VAAPI_DISPLAY_GET_CLASS (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 (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; +}; + +/** + * 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c new file mode 100644 index 0000000000..6217625139 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -0,0 +1,1342 @@ +/* + * gstvaapiutils_egl.c - EGL utilities + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 + */ + +#include "sysdeps.h" +#include "gstvaapiutils_egl.h" + +typedef struct egl_message_s EglMessage; +struct egl_message_s +{ + EglObject base; + EglContextRunFunc func; + gpointer args; +}; + +static void +egl_message_finalize (EglMessage * msg) +{ +} + +/* ------------------------------------------------------------------------- */ +// Utility functions + +typedef struct gl_version_info_s GlVersionInfo; +struct gl_version_info_s +{ + guint gles_version; + guint gl_api_bit; + guint gl_api; + const gchar *gl_api_name; +}; + +static const GlVersionInfo gl_version_info[] = { + {0, EGL_OPENGL_BIT, EGL_OPENGL_API, "OpenGL"}, + {1, EGL_OPENGL_ES_BIT, EGL_OPENGL_ES_API, "OpenGL_ES"}, + {2, EGL_OPENGL_ES2_BIT, EGL_OPENGL_ES_API, "OpenGL_ES2"}, + {3, EGL_OPENGL_ES3_BIT_KHR, EGL_OPENGL_ES_API, "OpenGL_ES3"}, + {0,} +}; + +static const GlVersionInfo * +gl_version_info_lookup (guint gles_version) +{ + const GlVersionInfo *vinfo; + + for (vinfo = gl_version_info; vinfo->gl_api_bit != 0; vinfo++) { + if (vinfo->gles_version == gles_version) + return vinfo; + } + return NULL; +} + +static const GlVersionInfo * +gl_version_info_lookup_by_api (guint api) +{ + const GlVersionInfo *vinfo; + + for (vinfo = gl_version_info; vinfo->gl_api_bit != 0; vinfo++) { + if (api & vinfo->gl_api_bit) + return vinfo; + } + return NULL; +} + +static const GlVersionInfo * +gl_version_info_lookup_by_api_name (const gchar * name) +{ + const GlVersionInfo *vinfo; + + for (vinfo = gl_version_info; vinfo->gl_api_bit != 0; vinfo++) { + if (g_strcmp0 (vinfo->gl_api_name, name) == 0) + return vinfo; + } + return NULL; +} + +static gboolean +g_strv_match_string (gchar ** extensions_list, const gchar * name) +{ + if (extensions_list) { + for (; *extensions_list != NULL; extensions_list++) { + if (g_strcmp0 (*extensions_list, name) == 0) + return TRUE; + } + } + return FALSE; +} + +static gboolean +egl_find_attrib_value (const EGLint * attribs, EGLint type, EGLint * value_ptr) +{ + while (attribs[0] != EGL_NONE) { + if (attribs[0] == type) { + if (value_ptr) + *value_ptr = attribs[1]; + return TRUE; + } + attribs += 2; + } + return FALSE; +} + +/* ------------------------------------------------------------------------- */ +// Basic objects + +#define EGL_OBJECT(object) ((EglObject *)(object)) +#define EGL_OBJECT_CLASS(klass) ((EglObjectClass *)(klass)) + +#define EGL_OBJECT_DEFINE_CLASS_WITH_CODE(TN, t_n, code) \ +static void \ +G_PASTE(t_n,_finalize) (TN * object); \ + \ +static inline const EglObjectClass * \ +G_PASTE(t_n,_class) (void) \ +{ \ + static G_PASTE(TN,Class) g_class; \ + static gsize g_class_init = FALSE; \ + \ + if (g_once_init_enter (&g_class_init)) { \ + GstVaapiMiniObjectClass *const object_class = \ + GST_VAAPI_MINI_OBJECT_CLASS (&g_class); \ + code; \ + object_class->size = sizeof (TN); \ + object_class->finalize = (GDestroyNotify) \ + G_PASTE(t_n,_finalize); \ + g_once_init_leave (&g_class_init, TRUE); \ + } \ + return EGL_OBJECT_CLASS (&g_class); \ +} + +#define EGL_OBJECT_DEFINE_CLASS(TN, t_n) \ + EGL_OBJECT_DEFINE_CLASS_WITH_CODE (TN, t_n, /**/) + +static inline gpointer +egl_object_new (const EglObjectClass * klass) +{ + return gst_vaapi_mini_object_new (GST_VAAPI_MINI_OBJECT_CLASS (klass)); +} + +static inline gpointer +egl_object_new0 (const EglObjectClass * klass) +{ + return gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS (klass)); +} + +typedef struct egl_object_class_s EglMessageClass; +typedef struct egl_object_class_s EglVTableClass; +typedef struct egl_object_class_s EglDisplayClass; +typedef struct egl_object_class_s EglConfigClass; +typedef struct egl_object_class_s EglContextClass; +typedef struct egl_object_class_s EglSurfaceClass; +typedef struct egl_object_class_s EglProgramClass; + +EGL_OBJECT_DEFINE_CLASS (EglMessage, egl_message); +EGL_OBJECT_DEFINE_CLASS (EglVTable, egl_vtable); +EGL_OBJECT_DEFINE_CLASS (EglDisplay, egl_display); +EGL_OBJECT_DEFINE_CLASS (EglConfig, egl_config); +EGL_OBJECT_DEFINE_CLASS (EglContext, egl_context); +EGL_OBJECT_DEFINE_CLASS (EglSurface, egl_surface); +EGL_OBJECT_DEFINE_CLASS (EglProgram, egl_program); + +/* ------------------------------------------------------------------------- */ +// Desktop OpenGL and OpenGL|ES dispatcher (vtable) + +static GMutex gl_vtables_lock; +static EglVTable *gl_vtables[4]; + +#if (USE_GLES_VERSION_MASK & (1U << 0)) +static const gchar *gl_library_names[] = { + "libGL.la", + "libGL.so.1", + NULL +}; +#endif + +#if (USE_GLES_VERSION_MASK & (1U << 1)) +static const gchar *gles1_library_names[] = { + "libGLESv1_CM.la", + "libGLESv1_CM.so.1", + NULL +}; +#endif + +#if (USE_GLES_VERSION_MASK & (1U << 2)) +static const gchar *gles2_library_names[] = { + "libGLESv2.la", + "libGLESv2.so.2", + NULL +}; +#endif + +static const gchar **gl_library_names_group[] = { +#if (USE_GLES_VERSION_MASK & (1U << 0)) + gl_library_names, +#endif + NULL +}; + +static const gchar **gles1_library_names_group[] = { +#if (USE_GLES_VERSION_MASK & (1U << 1)) + gles1_library_names, +#endif + NULL +}; + +static const gchar **gles2_library_names_group[] = { +#if (USE_GLES_VERSION_MASK & (1U << 2)) + gles2_library_names, +#endif + NULL +}; + +static const gchar **gles3_library_names_group[] = { +#if (USE_GLES_VERSION_MASK & (1U << 3)) + gles2_library_names, +#endif + NULL +}; + +static const gchar *** +egl_vtable_get_library_names_group (guint gles_version) +{ + const gchar ***library_names_group; + + switch (gles_version) { + case 0: + library_names_group = gl_library_names_group; + break; + case 1: + library_names_group = gles1_library_names_group; + break; + case 2: + library_names_group = gles2_library_names_group; + break; + case 3: + library_names_group = gles3_library_names_group; + break; + default: + library_names_group = NULL; + break; + } + return library_names_group; +} + +static gboolean +egl_vtable_check_extension (EglVTable * vtable, EGLDisplay display, + gboolean is_egl, const gchar * group_name, guint * group_ptr) +{ + gchar ***extensions_list; + const gchar *extensions; + + g_return_val_if_fail (group_name != NULL, FALSE); + g_return_val_if_fail (group_ptr != NULL, FALSE); + + if (*group_ptr > 0) + return TRUE; + + GST_DEBUG ("check for %s extension %s", is_egl ? "EGL" : "GL", group_name); + + if (is_egl) { + if (!vtable->egl_extensions) { + extensions = eglQueryString (display, EGL_EXTENSIONS); + if (!extensions) + return FALSE; + GST_DEBUG ("EGL extensions: %s", extensions); + vtable->egl_extensions = g_strsplit (extensions, " ", 0); + } + extensions_list = &vtable->egl_extensions; + } else { + if (!vtable->gl_extensions) { + extensions = (const gchar *) vtable->glGetString (GL_EXTENSIONS); + if (!extensions) + return FALSE; + GST_DEBUG ("GL extensions: %s", extensions); + vtable->gl_extensions = g_strsplit (extensions, " ", 0); + } + extensions_list = &vtable->gl_extensions; + } + if (!g_strv_match_string (*extensions_list, group_name)) + return FALSE; + + GST_LOG (" found %s extension %s", is_egl ? "EGL" : "GL", group_name); + (*group_ptr)++; + return TRUE; +} + +static gboolean +egl_vtable_load_symbol (EglVTable * vtable, EGLDisplay display, gboolean is_egl, + const gchar * symbol_name, gpointer * symbol_ptr, + const gchar * group_name, guint * group_ptr) +{ + void (*symbol) (void); + + if (group_ptr && !*group_ptr) { + if (!egl_vtable_check_extension (vtable, display, is_egl, group_name, + group_ptr)) + return FALSE; + } + + if (is_egl) { + symbol = eglGetProcAddress (symbol_name); + } else { + if (!g_module_symbol (vtable->base.handle.p, symbol_name, + (gpointer *) & symbol)) + return FALSE; + } + if (!symbol) + return FALSE; + + GST_LOG (" found symbol %s", symbol_name); + if (symbol_ptr) + *symbol_ptr = symbol; + if (group_ptr) + (*group_ptr)++; + return TRUE; +} + +static gboolean +egl_vtable_load_egl_symbols (EglVTable * vtable, EGLDisplay display) +{ + guint n = 0; + +#define EGL_DEFINE_EXTENSION(NAME) do { \ + egl_vtable_check_extension (vtable, display, TRUE, \ + "EGL_" G_STRINGIFY (NAME), \ + &vtable->GL_PROTO_GEN_CONCAT(has_EGL_,NAME)); \ + } while (0); + +#define EGL_PROTO_BEGIN(NAME, TYPE, EXTENSION) do { \ + n += egl_vtable_load_symbol (vtable, display, TRUE, \ + G_STRINGIFY(GL_PROTO_GEN_CONCAT(egl,NAME)), \ + (gpointer *) &vtable->GL_PROTO_GEN_CONCAT(egl,NAME), \ + "EGL_" G_STRINGIFY(EXTENSION), \ + &vtable->GL_PROTO_GEN_CONCAT(has_EGL_,EXTENSION)); \ + } while (0); + +#include "egl_vtable.h" + + vtable->num_egl_symbols = n; + return TRUE; +} + +static gboolean +egl_vtable_load_gl_symbols (EglVTable * vtable, EGLDisplay display) +{ + guint n = 0; + + vtable->has_GL_CORE_1_0 = 1; + vtable->has_GL_CORE_1_1 = 1; + vtable->has_GL_CORE_1_3 = 1; + vtable->has_GL_CORE_2_0 = 1; + +#define GL_DEFINE_EXTENSION(NAME) do { \ + egl_vtable_check_extension (vtable, display, FALSE, \ + "GL_" G_STRINGIFY (NAME), \ + &vtable->GL_PROTO_GEN_CONCAT(has_GL_,NAME)); \ + } while (0); + +#define GL_PROTO_BEGIN(NAME, TYPE, EXTENSION) do { \ + n += egl_vtable_load_symbol (vtable, display, FALSE, \ + G_STRINGIFY(GL_PROTO_GEN_CONCAT(gl,NAME)), \ + (gpointer *) &vtable->GL_PROTO_GEN_CONCAT(gl,NAME), \ + "GL_" G_STRINGIFY(EXTENSION), \ + &vtable->GL_PROTO_GEN_CONCAT(has_GL_,EXTENSION)); \ + } while (0); + +#include "egl_vtable.h" + + --vtable->has_GL_CORE_1_0; + --vtable->has_GL_CORE_1_1; + --vtable->has_GL_CORE_1_3; + --vtable->has_GL_CORE_2_0; + + vtable->num_gl_symbols = n; + return TRUE; +} + +static gboolean +egl_vtable_try_load_library (EglVTable * vtable, const gchar * name) +{ + if (vtable->base.handle.p) + g_module_close (vtable->base.handle.p); + vtable->base.handle.p = g_module_open (name, + G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + if (!vtable->base.handle.p) + return FALSE; + + GST_DEBUG ("loaded backend: %s", g_module_name (vtable->base.handle.p)); + return TRUE; +} + +static gboolean +egl_vtable_find_library (EglVTable * vtable) +{ + const gchar ***library_names_ptr = + egl_vtable_get_library_names_group (vtable->gles_version); + + if (!library_names_ptr) + return FALSE; + + for (; *library_names_ptr != NULL; library_names_ptr++) { + const gchar **library_name_ptr = *library_names_ptr; + for (; *library_name_ptr != NULL; library_name_ptr++) { + if (egl_vtable_try_load_library (vtable, *library_name_ptr)) + return TRUE; + } + } + return FALSE; +} + +static gboolean +egl_vtable_init (EglVTable * vtable, EGLDisplay display, guint gles_version) +{ + GST_DEBUG ("initialize for OpenGL|ES API version %d", gles_version); + + vtable->gles_version = gles_version; + if (!egl_vtable_find_library (vtable)) + return FALSE; + if (!egl_vtable_load_egl_symbols (vtable, display)) + return FALSE; + return TRUE; +} + +static void +egl_vtable_finalize (EglVTable * vtable) +{ + g_strfreev (vtable->egl_extensions); + g_strfreev (vtable->gl_extensions); + if (vtable->base.handle.p) + g_module_close (vtable->base.handle.p); + + if (vtable->base.is_wrapped) { + g_mutex_lock (&gl_vtables_lock); + gl_vtables[vtable->gles_version] = NULL; + g_mutex_unlock (&gl_vtables_lock); + } +} + +static EglVTable * +egl_vtable_new (EglDisplay * display, guint gles_version) +{ + EglVTable *vtable; + + g_return_val_if_fail (display != NULL, NULL); + + vtable = egl_object_new0 (egl_vtable_class ()); + if (!vtable + || !egl_vtable_init (vtable, display->base.handle.p, gles_version)) + goto error; + return vtable; + +error: + egl_object_replace (&vtable, NULL); + return NULL; +} + +static EglVTable * +egl_vtable_new_cached (EglDisplay * display, guint gles_version) +{ + EglVTable *vtable, **vtable_ptr; + + g_return_val_if_fail (gles_version < G_N_ELEMENTS (gl_vtables), NULL); + + vtable_ptr = &gl_vtables[gles_version]; + + g_mutex_lock (&gl_vtables_lock); + vtable = *vtable_ptr; + if (vtable) + egl_object_ref (vtable); + else { + vtable = egl_vtable_new (display, gles_version); + if (vtable) { + vtable->base.is_wrapped = TRUE; + *vtable_ptr = vtable; + } + } + g_mutex_unlock (&gl_vtables_lock); + return vtable; +} + +/* ------------------------------------------------------------------------- */ +// EGL Display + +static gboolean +egl_display_run (EglDisplay * display, EglContextRunFunc func, gpointer args) +{ + EglMessage *msg; + + if (display->gl_thread == g_thread_self ()) { + func (args); + return TRUE; + } + + msg = egl_object_new0 (egl_message_class ()); + if (!msg) + return FALSE; + + msg->base.is_valid = TRUE; + msg->func = func; + msg->args = args; + g_async_queue_push (display->gl_queue, egl_object_ref (msg)); + + g_mutex_lock (&display->mutex); + while (msg->base.is_valid) + g_cond_wait (&display->gl_thread_ready, &display->mutex); + g_mutex_unlock (&display->mutex); + egl_object_unref (msg); + return TRUE; +} + +static gpointer +egl_display_thread (gpointer data) +{ + EglDisplay *const display = data; + EGLDisplay gl_display = display->base.handle.p; + EGLint major_version, minor_version; + gchar **gl_apis, **gl_api; + + if (!display->base.is_wrapped) { + gl_display = display->base.handle.p = eglGetDisplay (gl_display); + if (!gl_display) + goto error; + if (!eglInitialize (gl_display, &major_version, &minor_version)) + goto error; + } + + display->gl_vendor_string = + g_strdup (eglQueryString (gl_display, EGL_VENDOR)); + display->gl_version_string = + g_strdup (eglQueryString (gl_display, EGL_VERSION)); + display->gl_apis_string = + g_strdup (eglQueryString (gl_display, EGL_CLIENT_APIS)); + + GST_INFO ("EGL vendor: %s", display->gl_vendor_string); + GST_INFO ("EGL version: %s", display->gl_version_string); + GST_INFO ("EGL client APIs: %s", display->gl_apis_string); + + gl_apis = g_strsplit (display->gl_apis_string, " ", 0); + if (!gl_apis) + goto error; + for (gl_api = gl_apis; *gl_api != NULL; gl_api++) { + const GlVersionInfo *const vinfo = + gl_version_info_lookup_by_api_name (*gl_api); + + if (vinfo) + display->gl_apis |= vinfo->gl_api_bit; + } + g_strfreev (gl_apis); + if (!display->gl_apis) + goto error; + + display->base.is_valid = TRUE; + g_cond_broadcast (&display->gl_thread_ready); + + while (!display->gl_thread_cancel) { + EglMessage *const msg = + g_async_queue_timeout_pop (display->gl_queue, 100000); + + if (msg) { + if (msg->base.is_valid) { + msg->func (msg->args); + msg->base.is_valid = FALSE; + g_cond_broadcast (&display->gl_thread_ready); + } + egl_object_unref (msg); + } + } + +done: + if (gl_display != EGL_NO_DISPLAY && !display->base.is_wrapped) + eglTerminate (gl_display); + display->base.handle.p = NULL; + g_cond_broadcast (&display->gl_thread_ready); + return NULL; + +error: + display->base.is_valid = FALSE; + goto done; +} + +static gboolean +egl_display_init (EglDisplay * display) +{ + display->gl_queue = + g_async_queue_new_full ((GDestroyNotify) gst_vaapi_mini_object_unref); + if (!display->gl_queue) + return FALSE; + + g_mutex_init (&display->mutex); + g_cond_init (&display->gl_thread_ready); + display->gl_thread = g_thread_try_new ("OpenGL Thread", egl_display_thread, + display, NULL); + if (!display->gl_thread) + return FALSE; + + g_mutex_lock (&display->mutex); + g_cond_wait (&display->gl_thread_ready, &display->mutex); + g_mutex_unlock (&display->mutex); + return display->base.is_valid; +} + +static void +egl_display_finalize (EglDisplay * display) +{ + display->gl_thread_cancel = TRUE; + g_thread_join (display->gl_thread); + g_cond_clear (&display->gl_thread_ready); + g_mutex_clear (&display->mutex); + g_async_queue_unref (display->gl_queue); + + g_free (display->gl_vendor_string); + g_free (display->gl_version_string); + g_free (display->gl_apis_string); +} + +static EglDisplay * +egl_display_new_full (gpointer handle, gboolean is_wrapped) +{ + EglDisplay *display; + + display = egl_object_new0 (egl_display_class ()); + if (!display) + return NULL; + + display->base.handle.p = handle; + display->base.is_wrapped = is_wrapped; + if (!egl_display_init (display)) + goto error; + return display; + +error: + egl_object_unref (display); + return NULL; +} + +EglDisplay * +egl_display_new (gpointer native_display) +{ + g_return_val_if_fail (native_display != NULL, NULL); + + return egl_display_new_full (native_display, FALSE); +} + +EglDisplay * +egl_display_new_wrapped (EGLDisplay gl_display) +{ + g_return_val_if_fail (gl_display != EGL_NO_DISPLAY, NULL); + + return egl_display_new_full (gl_display, TRUE); +} + +/* ------------------------------------------------------------------------- */ +// EGL Config + +static gboolean +egl_config_init (EglConfig * config, EglDisplay * display, + const EGLint * attribs) +{ + EGLDisplay const gl_display = display->base.handle.p; + const GlVersionInfo *vinfo; + EGLConfig gl_config; + EGLint v, gl_apis, num_configs; + + egl_object_replace (&config->display, display); + + if (!eglChooseConfig (gl_display, attribs, &gl_config, 1, &num_configs)) + return FALSE; + if (num_configs != 1) + return FALSE; + config->base.handle.p = gl_config; + + if (!eglGetConfigAttrib (gl_display, gl_config, EGL_CONFIG_ID, &v)) + return FALSE; + config->config_id = v; + + if (!eglGetConfigAttrib (gl_display, gl_config, EGL_NATIVE_VISUAL_ID, &v)) + return FALSE; + config->visual_id = v; + + if (!eglGetConfigAttrib (gl_display, gl_config, EGL_RENDERABLE_TYPE, &v)) + return FALSE; + if (!egl_find_attrib_value (attribs, EGL_RENDERABLE_TYPE, &gl_apis)) + return FALSE; + vinfo = gl_version_info_lookup_by_api (v & gl_apis); + if (!vinfo) + return FALSE; + config->gles_version = vinfo->gles_version; + config->gl_api = vinfo->gles_version > 0 ? EGL_OPENGL_ES_API : EGL_OPENGL_API; + return TRUE; +} + +static void +egl_config_finalize (EglConfig * config) +{ + egl_object_replace (&config->display, NULL); +} + +EglConfig * +egl_config_new (EglDisplay * display, guint gles_version, GstVideoFormat format) +{ + EGLint attribs[2 * 6 + 1], *attrib = attribs; + const GstVideoFormatInfo *finfo; + const GlVersionInfo *vinfo; + + g_return_val_if_fail (display != NULL, NULL); + + finfo = gst_video_format_get_info (format); + if (!finfo || !GST_VIDEO_FORMAT_INFO_IS_RGB (finfo)) + return NULL; + + vinfo = gl_version_info_lookup (gles_version); + if (!vinfo) + return NULL; + + *attrib++ = EGL_COLOR_BUFFER_TYPE; + *attrib++ = EGL_RGB_BUFFER; + *attrib++ = EGL_RED_SIZE; + *attrib++ = GST_VIDEO_FORMAT_INFO_DEPTH (finfo, GST_VIDEO_COMP_R); + *attrib++ = EGL_GREEN_SIZE; + *attrib++ = GST_VIDEO_FORMAT_INFO_DEPTH (finfo, GST_VIDEO_COMP_G); + *attrib++ = EGL_BLUE_SIZE; + *attrib++ = GST_VIDEO_FORMAT_INFO_DEPTH (finfo, GST_VIDEO_COMP_B); + *attrib++ = EGL_ALPHA_SIZE; + *attrib++ = GST_VIDEO_FORMAT_INFO_DEPTH (finfo, GST_VIDEO_COMP_A); + *attrib++ = EGL_RENDERABLE_TYPE; + *attrib++ = vinfo->gl_api_bit; + *attrib++ = EGL_NONE; + g_assert (attrib - attribs <= G_N_ELEMENTS (attribs)); + + return egl_config_new_with_attribs (display, attribs); +} + +EglConfig * +egl_config_new_with_attribs (EglDisplay * display, const EGLint * attribs) +{ + EglConfig *config; + + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (attribs != NULL, NULL); + + config = egl_object_new0 (egl_config_class ()); + if (!config || !egl_config_init (config, display, attribs)) + goto error; + return config; + +error: + egl_object_replace (&config, NULL); + return NULL; +} + +static EglConfig * +egl_config_new_from_gl_context (EglDisplay * display, EGLContext gl_context) +{ + EGLDisplay const gl_display = display->base.handle.p; + EGLint attribs[3 * 2 + 1], *attrib = attribs; + EGLint config_id, api, v; + guint gles_version; + const GlVersionInfo *vinfo; + + if (!eglQueryContext (gl_display, gl_context, EGL_CONFIG_ID, &config_id)) + return NULL; + if (!eglQueryContext (gl_display, gl_context, EGL_CONTEXT_CLIENT_TYPE, &api)) + return NULL; + if (!eglQueryContext (gl_display, gl_context, EGL_CONTEXT_CLIENT_VERSION, &v)) + return NULL; + + if (api == EGL_OPENGL_API) + gles_version = 0; + else if (api == EGL_OPENGL_ES_API) + gles_version = v; + else { + GST_ERROR ("unsupported EGL client API (%d)", api); + return NULL; + } + + vinfo = gl_version_info_lookup (gles_version); + if (!vinfo) + return NULL; + + *attrib++ = EGL_COLOR_BUFFER_TYPE; + *attrib++ = EGL_RGB_BUFFER; + *attrib++ = EGL_CONFIG_ID; + *attrib++ = config_id; + *attrib++ = EGL_RENDERABLE_TYPE; + *attrib++ = vinfo->gl_api_bit; + *attrib++ = EGL_NONE; + g_assert (attrib - attribs <= G_N_ELEMENTS (attribs)); + + return egl_config_new_with_attribs (display, attribs); +} + +/* ------------------------------------------------------------------------- */ +// EGL Surface + +static void +egl_surface_finalize (EglSurface * surface) +{ + if (surface->base.handle.p != EGL_NO_SURFACE && !surface->base.is_wrapped) + eglDestroySurface (surface->display->base.handle.p, surface->base.handle.p); + egl_object_replace (&surface->display, NULL); +} + +EglSurface * +egl_surface_new_wrapped (EglDisplay * display, EGLSurface gl_surface) +{ + EglSurface *surface; + + g_return_val_if_fail (display != NULL, NULL); + + surface = egl_object_new (egl_surface_class ()); + if (!surface) + return NULL; + + surface->base.is_wrapped = TRUE; + surface->base.handle.p = gl_surface; + surface->display = egl_object_ref (display); + return surface; +} + +/* ------------------------------------------------------------------------- */ +// EGL Context + +static void +egl_context_state_get_current (EglContextState * cs); + +static gboolean +egl_context_state_set_current (EglContextState * new_cs, + EglContextState * old_cs); + +static gboolean +ensure_vtable (EglContext * ctx) +{ + if (!ctx->vtable) { + ctx->vtable = egl_vtable_new_cached (ctx->display, + ctx->config ? ctx->config->gles_version : 0); + if (!ctx->vtable) + return FALSE; + } + return TRUE; +} + +static gboolean +ensure_context (EglContext * ctx, EGLContext gl_parent_context) +{ + EGLDisplay *const gl_display = ctx->display->base.handle.p; + EGLContext gl_context = ctx->base.handle.p; + EGLint gles_attribs[3], *attribs = NULL; + + if (!gl_context) { + if (ctx->config->gles_version >= 2) { + attribs = gles_attribs; + attribs[0] = EGL_CONTEXT_CLIENT_VERSION; + attribs[1] = ctx->config->gles_version; + attribs[2] = EGL_NONE; + } + + gl_context = eglCreateContext (gl_display, ctx->config->base.handle.p, + gl_parent_context, attribs); + if (!gl_context) + goto error_create_context; + ctx->base.handle.p = gl_context; + } + return TRUE; + + /* ERRORS */ +error_create_context: + GST_ERROR ("failed to create EGL context"); + return FALSE; +} + +static inline gboolean +ensure_gl_is_surfaceless (EglContext * ctx) +{ + return ctx->vtable->has_EGL_KHR_surfaceless_context || + (ctx->read_surface && ctx->draw_surface); +} + +static gboolean +ensure_gl_scene (EglContext * ctx) +{ + EglVTable *vtable; + + if (!ensure_gl_is_surfaceless (ctx)) + return FALSE; + + if (ctx->base.is_valid) + return TRUE; + + vtable = egl_context_get_vtable (ctx, TRUE); + if (!vtable) + return FALSE; + + vtable->glClearColor (0.0, 0.0, 0.0, 1.0); + if (ctx->config && ctx->config->gles_version == 0) + vtable->glEnable (GL_TEXTURE_2D); + vtable->glDisable (GL_BLEND); + vtable->glDisable (GL_DEPTH_TEST); + + ctx->base.is_valid = TRUE; + return TRUE; +} + +/** + * egl_context_state_get_current: + * @cs: return location to the current #EglContextState + * + * Retrieves the current EGL context, display and surface to pack into + * the #EglContextState struct. + */ +static void +egl_context_state_get_current (EglContextState * cs) +{ + cs->display = eglGetCurrentDisplay (); + cs->context = eglGetCurrentContext (); + if (cs->context) { + cs->read_surface = eglGetCurrentSurface (EGL_READ); + cs->draw_surface = eglGetCurrentSurface (EGL_DRAW); + } else { + cs->read_surface = EGL_NO_SURFACE; + cs->draw_surface = EGL_NO_SURFACE; + } +} + +/** + * egl_context_state_set_current: + * @new_cs: the requested new #EglContextState + * @old_cs: return location to the context that was previously current + * + * Makes the @new_cs EGL context the current EGL rendering context of + * the calling thread, replacing the previously current context if + * there was one. + * + * If @old_cs is non %NULL, the previously current EGL context and + * surface are recorded. + * + * Return value: %TRUE on success + */ +static gboolean +egl_context_state_set_current (EglContextState * new_cs, + EglContextState * old_cs) +{ + /* If display is NULL, this could be that new_cs was retrieved from + egl_context_state_get_current() with none set previously. If that case, + the other fields are also NULL and we don't return an error */ + if (!new_cs->display) + return !new_cs->context && !new_cs->read_surface && !new_cs->draw_surface; + + if (old_cs) { + if (old_cs == new_cs) + return TRUE; + egl_context_state_get_current (old_cs); + if (old_cs->display == new_cs->display && + old_cs->context == new_cs->context && + old_cs->read_surface == new_cs->read_surface && + old_cs->draw_surface == new_cs->draw_surface) + return TRUE; + } + return eglMakeCurrent (new_cs->display, new_cs->draw_surface, + new_cs->read_surface, new_cs->context); +} + +static gboolean +egl_context_init (EglContext * ctx, EglDisplay * display, EglConfig * config, + EGLContext gl_parent_context) +{ + egl_object_replace (&ctx->display, display); + egl_object_replace (&ctx->config, config); + + if (config) + eglBindAPI (config->gl_api); + + if (!ensure_vtable (ctx)) + return FALSE; + if (!ensure_context (ctx, gl_parent_context)) + return FALSE; + return TRUE; +} + +static void +egl_context_finalize (EglContext * ctx) +{ + if (ctx->base.handle.p && !ctx->base.is_wrapped) + eglDestroyContext (ctx->display->base.handle.p, ctx->base.handle.p); + egl_object_replace (&ctx->read_surface, NULL); + egl_object_replace (&ctx->draw_surface, NULL); + egl_object_replace (&ctx->config, NULL); + egl_object_replace (&ctx->display, NULL); + egl_object_replace (&ctx->vtable, NULL); +} + +typedef struct +{ + EglDisplay *display; + EglConfig *config; + EGLContext gl_parent_context; + EglContext *context; /* result */ +} CreateContextArgs; + +static void +do_egl_context_new (CreateContextArgs * args) +{ + EglContext *ctx; + + ctx = egl_object_new0 (egl_context_class ()); + if (!ctx || !egl_context_init (ctx, args->display, args->config, + args->gl_parent_context)) + goto error; + args->context = ctx; + return; + +error: + egl_object_replace (&ctx, NULL); + args->context = NULL; +} + +EglContext * +egl_context_new (EglDisplay * display, EglConfig * config, EglContext * parent) +{ + CreateContextArgs args; + + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (config != NULL, NULL); + + args.display = display; + args.config = config; + args.gl_parent_context = parent ? parent->base.handle.p : EGL_NO_CONTEXT; + if (!egl_display_run (display, (EglContextRunFunc) do_egl_context_new, &args)) + return NULL; + return args.context; +} + +EglContext * +egl_context_new_wrapped (EglDisplay * display, EGLContext gl_context) +{ + CreateContextArgs args; + EglConfig *config; + gboolean success; + + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (gl_context != EGL_NO_CONTEXT, NULL); + + config = egl_config_new_from_gl_context (display, gl_context); + if (!config) + return NULL; + + args.display = display; + args.config = config; + args.gl_parent_context = gl_context; + success = egl_display_run (display, (EglContextRunFunc) do_egl_context_new, + &args); + egl_object_unref (config); + if (!success) + return NULL; + return args.context; +} + +EglVTable * +egl_context_get_vtable (EglContext * ctx, gboolean need_gl_symbols) +{ + g_return_val_if_fail (ctx != NULL, NULL); + g_return_val_if_fail (ctx->display->gl_thread == g_thread_self (), NULL); + + if (!ensure_vtable (ctx)) + return NULL; + + if (need_gl_symbols && !(ctx->vtable->num_gl_symbols > 0 || + egl_vtable_load_gl_symbols (ctx->vtable, + ctx->display->base.handle.p))) + return NULL; + return ctx->vtable; +} + +void +egl_context_set_surface (EglContext * ctx, EglSurface * surface) +{ + g_return_if_fail (ctx != NULL); + g_return_if_fail (surface != NULL); + + egl_object_replace (&ctx->read_surface, surface); + egl_object_replace (&ctx->draw_surface, surface); +} + +gboolean +egl_context_set_current (EglContext * ctx, gboolean activate, + EglContextState * old_cs) +{ + EglContextState cs, *new_cs; + + g_return_val_if_fail (ctx != NULL, FALSE); + g_return_val_if_fail (ctx->display->gl_thread == g_thread_self (), FALSE); + + if (activate) { + new_cs = &cs; + new_cs->display = ctx->display->base.handle.p; + new_cs->context = ctx->base.handle.p; + new_cs->draw_surface = ctx->draw_surface ? + ctx->draw_surface->base.handle.p : EGL_NO_SURFACE; + new_cs->read_surface = ctx->read_surface ? + ctx->read_surface->base.handle.p : EGL_NO_SURFACE; + } else if (old_cs) { + new_cs = old_cs; + old_cs = NULL; + } else { + new_cs = &cs; + new_cs->display = ctx->display->base.handle.p; + new_cs->context = EGL_NO_CONTEXT; + new_cs->draw_surface = EGL_NO_SURFACE; + new_cs->read_surface = EGL_NO_SURFACE; + old_cs = NULL; + } + + if (!egl_context_state_set_current (new_cs, old_cs)) + return FALSE; + if (activate && !ensure_gl_scene (ctx)) + return FALSE; + return TRUE; +} + +gboolean +egl_context_run (EglContext * ctx, EglContextRunFunc func, gpointer args) +{ + g_return_val_if_fail (ctx != NULL, FALSE); + g_return_val_if_fail (func != NULL, FALSE); + + return egl_display_run (ctx->display, func, args); +} + +/* ------------------------------------------------------------------------- */ +// EGL Program + +static GLuint +egl_compile_shader (EglContext * ctx, GLenum type, const char *source) +{ + EglVTable *const vtable = egl_context_get_vtable (ctx, TRUE); + GLuint shader; + GLint status; + char log[BUFSIZ]; + GLsizei log_length; + + shader = vtable->glCreateShader (type); + vtable->glShaderSource (shader, 1, &source, NULL); + vtable->glCompileShader (shader); + vtable->glGetShaderiv (shader, GL_COMPILE_STATUS, &status); + if (!status) { + GST_ERROR ("failed to compile %s shader", + type == GL_FRAGMENT_SHADER ? "fragment" : + type == GL_VERTEX_SHADER ? "vertex" : ""); + + vtable->glGetShaderInfoLog (shader, sizeof (log), &log_length, log); + GST_ERROR ("info log: %s", log); + return 0; + } + return shader; +} + +static void +egl_program_finalize (EglProgram * program) +{ + EglVTable *const vtable = program->vtable; + + if (program->base.handle.u) + vtable->glDeleteProgram (program->base.handle.u); + if (program->frag_shader) + vtable->glDeleteShader (program->frag_shader); + if (program->vert_shader) + vtable->glDeleteShader (program->vert_shader); + egl_object_replace (&program->vtable, NULL); +} + +static gboolean +egl_program_init (EglProgram * program, EglContext * ctx, + const gchar * frag_shader_text, const gchar * vert_shader_text) +{ + EglVTable *const vtable = egl_context_get_vtable (ctx, TRUE); + GLuint prog_id; + char msg[BUFSIZ]; + GLsizei msglen; + GLint status; + + if (ctx->config->gles_version == 1) + goto error_unsupported_gles_version; + + program->vtable = egl_object_ref (vtable); + + program->frag_shader = + egl_compile_shader (ctx, GL_FRAGMENT_SHADER, frag_shader_text); + if (!program->frag_shader) + return FALSE; + + program->vert_shader = + egl_compile_shader (ctx, GL_VERTEX_SHADER, vert_shader_text); + if (!program->vert_shader) + return FALSE; + + prog_id = vtable->glCreateProgram (); + if (!prog_id) + return FALSE; + program->base.handle.u = prog_id; + + vtable->glAttachShader (prog_id, program->frag_shader); + vtable->glAttachShader (prog_id, program->vert_shader); + vtable->glBindAttribLocation (prog_id, 0, "position"); + vtable->glBindAttribLocation (prog_id, 1, "texcoord"); + vtable->glLinkProgram (prog_id); + + vtable->glGetProgramiv (prog_id, GL_LINK_STATUS, &status); + if (!status) + goto error_link_program; + return TRUE; + + /* ERRORS */ +error_unsupported_gles_version: + GST_ERROR ("unsupported shader with OpenGL|ES version 1"); + return FALSE; +error_link_program: + vtable->glGetProgramInfoLog (prog_id, sizeof (msg), &msglen, msg); + GST_ERROR ("failed to link program: %s", msg); + return FALSE; +} + +EglProgram * +egl_program_new (EglContext * ctx, const gchar * frag_shader_text, + const gchar * vert_shader_text) +{ + EglProgram *program; + + g_return_val_if_fail (ctx != NULL, NULL); + g_return_val_if_fail (frag_shader_text != NULL, NULL); + g_return_val_if_fail (vert_shader_text != NULL, NULL); + + program = egl_object_new0 (egl_program_class ()); + if (!program + || !egl_program_init (program, ctx, frag_shader_text, vert_shader_text)) + goto error; + return program; + +error: + egl_object_replace (&program, NULL); + return NULL; +} + +/* ------------------------------------------------------------------------- */ +// Misc utility functions + +void +egl_matrix_set_identity (gfloat m[16]) +{ +#define MAT(m,r,c) (m)[(c) * 4 + (r)] + MAT(m,0,0) = 1.0; MAT(m,0,1) = 0.0; MAT(m,0,2) = 0.0; MAT(m,0,3) = 0.0; + MAT(m,1,0) = 0.0; MAT(m,1,1) = 1.0; MAT(m,1,2) = 0.0; MAT(m,1,3) = 0.0; + MAT(m,2,0) = 0.0; MAT(m,2,1) = 0.0; MAT(m,2,2) = 1.0; MAT(m,2,3) = 0.0; + MAT(m,3,0) = 0.0; MAT(m,3,1) = 0.0; MAT(m,3,2) = 0.0; MAT(m,3,3) = 1.0; +#undef MAT +} + +/** + * egl_create_texture: + * @ctx: the parent #EglContext object + * @target: the target to which the texture is bound + * @format: the format of the pixel data + * @width: the requested width, in pixels + * @height: the requested height, in pixels + * + * Creates a texture with the specified dimensions and @format. The + * internal format will be automatically derived from @format. + * + * Return value: the newly created texture name + */ +guint +egl_create_texture (EglContext * ctx, guint target, guint format, + guint width, guint height) +{ + EglVTable *const vtable = egl_context_get_vtable (ctx, TRUE); + guint internal_format, texture, bytes_per_component; + + internal_format = format; + switch (format) { + case GL_LUMINANCE: + bytes_per_component = 1; + break; + case GL_LUMINANCE_ALPHA: + bytes_per_component = 2; + break; + case GL_RGBA: + case GL_BGRA_EXT: + internal_format = GL_RGBA; + bytes_per_component = 4; + break; + default: + bytes_per_component = 0; + break; + } + g_assert (bytes_per_component > 0); + + vtable->glGenTextures (1, &texture); + vtable->glBindTexture (target, texture); + + if (width > 0 && height > 0) + vtable->glTexImage2D (target, 0, internal_format, width, height, 0, + format, GL_UNSIGNED_BYTE, NULL); + + vtable->glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + vtable->glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + vtable->glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + vtable->glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + vtable->glPixelStorei (GL_UNPACK_ALIGNMENT, bytes_per_component); + + return texture; +} + +/** + * egl_destroy_texture: + * @ctx: the parent #EglContext object + * @texture: the texture name to delete + * + * Destroys the supplied @texture name. + */ +void +egl_destroy_texture (EglContext * ctx, guint texture) +{ + EglVTable *const vtable = egl_context_get_vtable (ctx, TRUE); + + vtable->glDeleteTextures (1, &texture); +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.h b/gst-libs/gst/vaapi/gstvaapiutils_egl.h new file mode 100644 index 0000000000..d1fd28ded7 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.h @@ -0,0 +1,238 @@ +/* + * gstvaapiutils_egl.h - EGL utilities + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 GST_VAAPI_UTILS_EGL_H +#define GST_VAAPI_UTILS_EGL_H + +#include +#include +#include +#include "egl_compat.h" +#include "gstvaapiminiobject.h" + +GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapidisplay_egl); +#define GST_CAT_DEFAULT gst_debug_vaapidisplay_egl + +typedef union egl_handle_s EglHandle; +typedef struct egl_object_s EglObject; +typedef struct egl_object_class_s EglObjectClass; +typedef struct egl_vtable_s EglVTable; +typedef struct egl_display_s EglDisplay; +typedef struct egl_config_s EglConfig; +typedef struct egl_context_state_s EglContextState; +typedef struct egl_context_s EglContext; +typedef struct egl_surface_s EglSurface; +typedef struct egl_program_s EglProgram; + +#define EGL_PROTO_BEGIN(NAME, TYPE, EXTENSION) \ + typedef TYPE (*GL_PROTO_GEN_CONCAT3(Egl,NAME,Proc)) +#define EGL_PROTO_END() ; +#define GL_PROTO_BEGIN(NAME, TYPE, EXTENSION) \ + typedef TYPE (*GL_PROTO_GEN_CONCAT3(Gl,NAME,Proc)) +#define GL_PROTO_ARG_LIST(...) (__VA_ARGS__) +#define GL_PROTO_ARG(NAME, TYPE) TYPE NAME +#define GL_PROTO_END() ; +#include "egl_vtable.h" + +union egl_handle_s +{ + gpointer p; + guintptr u; + gintptr i; +}; + +struct egl_object_s +{ + /*< private >*/ + GstVaapiMiniObject parent_instance; + + EglHandle handle; + guint is_wrapped:1; + guint is_valid:1; +}; + +struct egl_object_class_s +{ + /*< private >*/ + GstVaapiMiniObjectClass parent_class; +}; + +struct egl_vtable_s +{ + EglObject base; + + gchar **egl_extensions; + guint num_egl_symbols; + gchar **gl_extensions; + guint num_gl_symbols; + guint gles_version; + +#define EGL_PROTO_BEGIN(NAME, TYPE, EXTENSION) \ + GL_PROTO_BEGIN_I(NAME, TYPE, EXTENSION, Egl, egl) +#define GL_PROTO_BEGIN(NAME, TYPE, EXTENSION) \ + GL_PROTO_BEGIN_I(NAME, TYPE, EXTENSION, Gl, gl) +#define GL_PROTO_BEGIN_I(NAME, TYPE, EXTENSION, Prefix, prefix) \ + GL_PROTO_GEN_CONCAT3(Prefix,NAME,Proc) GL_PROTO_GEN_CONCAT(prefix,NAME); +#include "egl_vtable.h" + +#define EGL_DEFINE_EXTENSION(EXTENSION) \ + GL_DEFINE_EXTENSION_I(EXTENSION, EGL) +#define GL_DEFINE_EXTENSION(EXTENSION) \ + GL_DEFINE_EXTENSION_I(EXTENSION, GL) +#define GL_DEFINE_EXTENSION_I(EXTENSION, PREFIX) \ + guint GL_PROTO_GEN_CONCAT4(has_,PREFIX,_,EXTENSION); +#include "egl_vtable.h" +}; + +struct egl_display_s +{ + EglObject base; + + gchar *gl_vendor_string; + gchar *gl_version_string; + gchar *gl_apis_string; + guint gl_apis; /* EGL_*_BIT mask */ + + GMutex mutex; + GThread *gl_thread; + GCond gl_thread_ready; + volatile gboolean gl_thread_cancel; + GAsyncQueue *gl_queue; +}; + +struct egl_config_s +{ + EglObject base; + + EglDisplay *display; + guint gl_api; /* EGL_*_API value */ + guint gles_version; + gint config_id; + gint visual_id; +}; + +typedef void (*EglContextRunFunc) (gpointer args); + +struct egl_context_state_s +{ + EGLDisplay display; + EGLContext context; + EGLSurface read_surface; + EGLSurface draw_surface; +}; + +struct egl_context_s +{ + EglObject base; + + EglVTable *vtable; + EglDisplay *display; + EglConfig *config; + EglSurface *read_surface; + EglSurface *draw_surface; +}; + +struct egl_surface_s +{ + EglObject base; + + EglDisplay *display; +}; + +/* Defined to the maximum number of uniforms for a shader program */ +#define EGL_MAX_UNIFORMS 16 + +struct egl_program_s +{ + EglObject base; + + EglVTable *vtable; + guint frag_shader; + guint vert_shader; + gint uniforms[EGL_MAX_UNIFORMS]; +}; + +#define egl_object_ref(obj) \ + ((gpointer)gst_vaapi_mini_object_ref ((GstVaapiMiniObject *)(obj))) +#define egl_object_unref(obj) \ + gst_vaapi_mini_object_unref ((GstVaapiMiniObject *)(obj)) +#define egl_object_replace(old_obj_ptr, new_obj) \ + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **)(old_obj_ptr), \ + (GstVaapiMiniObject *)(new_obj)) + +G_GNUC_INTERNAL +EglDisplay * +egl_display_new (gpointer native_display); + +G_GNUC_INTERNAL +EglDisplay * +egl_display_new_wrapped (EGLDisplay gl_display); + +G_GNUC_INTERNAL +EglConfig * +egl_config_new (EglDisplay * display, guint gles_version, + GstVideoFormat format); + +G_GNUC_INTERNAL +EglConfig * +egl_config_new_with_attribs (EglDisplay * display, const EGLint * attribs); + +G_GNUC_INTERNAL +EglContext * +egl_context_new (EglDisplay * display, EglConfig * config, EglContext * parent); + +G_GNUC_INTERNAL +EglContext * +egl_context_new_wrapped (EglDisplay * display, EGLContext gl_context); + +G_GNUC_INTERNAL +EglVTable * +egl_context_get_vtable (EglContext * ctx, gboolean need_gl_symbols); + +G_GNUC_INTERNAL +gboolean +egl_context_set_current (EglContext * ctx, gboolean activate, + EglContextState * old_cs); + +G_GNUC_INTERNAL +gboolean +egl_context_run (EglContext * ctx, EglContextRunFunc func, gpointer args); + +G_GNUC_INTERNAL +EglProgram * +egl_program_new (EglContext * ctx, const gchar * frag_shader_text, + const gchar * vert_shader_text); + +G_GNUC_INTERNAL +guint +egl_create_texture (EglContext * ctx, guint target, guint format, + guint width, guint height); + +G_GNUC_INTERNAL +void +egl_destroy_texture (EglContext * ctx, guint texture); + +G_GNUC_INTERNAL +void +egl_matrix_set_identity (gfloat m[16]); + +#endif /* GST_VAAPI_UTILS_EGL_H */ diff --git a/gst-libs/gst/vaapi/ogl_compat.h b/gst-libs/gst/vaapi/ogl_compat.h new file mode 100644 index 0000000000..2fa40e743c --- /dev/null +++ b/gst-libs/gst/vaapi/ogl_compat.h @@ -0,0 +1,104 @@ +/* + * ogl_compat.h - OpenGL compatiliby layer + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 OGL_COMPAT_H +#define OGL_COMPAT_H + +typedef void GLvoid; +typedef char GLchar; +typedef unsigned char GLubyte; +typedef unsigned char GLboolean; +typedef int GLint; +typedef unsigned int GLuint; +typedef int GLsizei; +typedef float GLfloat; +typedef double GLdouble; +typedef GLuint GLenum; +typedef GLuint GLbitfield; +typedef GLfloat GLclampf; + +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 + +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_NONE 0 + +#define GL_BLEND 0x0BE2 +#define GL_DEPTH_TEST 0x0B71 + +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 + +#define GL_UNPACK_ALIGNMENT 0x0cf5 + +#define GL_TRIANGLE_FAN 0x0006 + +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 + +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F + +#define GL_VERTEX_ARRAY 0x8074 +#define GL_TEXTURE_COORD_ARRAY 0x8078 + +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_INFO_LOG_LENGTH 0x8B84 + +#define GL_BGRA_EXT 0x80e1 +#ifndef GL_R8 +#define GL_R8 GL_R8_EXT +#endif +#ifndef GL_RG8 +#define GL_RG8 GL_RG8_EXT +#endif + +#endif /* OGL_COMPAT_H */ From a9fe79610a6b3529f60ba0392c31fefacb6d5f45 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Dec 2014 18:14:56 +0100 Subject: [PATCH 1892/3781] egl: allow for EGLImage imports into VA Surfaces. Add helpers to import EGLImage objects into VA surfaces. There are two operational modes: (i) gst_vaapi_surface_new_from_egl_image(), which allows for implicit conversion from EGLImage to a VA surface in native video format, and (ii) gst_vaapi_surface_new_with_egl_image(), which exactly wraps the source EGLImage, typically in RGBA format with linear storage. Note: in case of (i), the EGLImage can be disposed right after the VA surface creation call, unlike in (ii) where the user shall ensure that the EGLImage is live until the associated VA surface is no longer needed. https://bugzilla.gnome.org/show_bug.cgi?id=743847 --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapisurface_egl.c | 255 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface_egl.h | 43 ++++ 3 files changed, 300 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapisurface_egl.c create mode 100644 gst-libs/gst/vaapi/gstvaapisurface_egl.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index a329e8fe7d..bcd5fb91de 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -277,11 +277,13 @@ libgstvaapi_glx_source_priv_h = \ libgstvaapi_egl_source_c = \ gstvaapidisplay_egl.c \ + gstvaapisurface_egl.c \ gstvaapiutils_egl.c \ $(NULL) libgstvaapi_egl_source_h = \ gstvaapidisplay_egl.h \ + gstvaapisurface_egl.h \ $(NULL) libgstvaapi_egl_source_priv_h = \ diff --git a/gst-libs/gst/vaapi/gstvaapisurface_egl.c b/gst-libs/gst/vaapi/gstvaapisurface_egl.c new file mode 100644 index 0000000000..8c13851655 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurface_egl.c @@ -0,0 +1,255 @@ +/* + * gstvaapisurface_egl.c - VA surface abstraction (EGL interop) + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 "gstvaapisurface_egl.h" +#include "gstvaapisurface_drm.h" +#include "gstvaapisurface_priv.h" +#include "gstvaapiimage_priv.h" +#include "gstvaapibufferproxy_priv.h" +#include "gstvaapidisplay_egl_priv.h" +#include "gstvaapifilter.h" + +typedef struct +{ + GstVaapiDisplayEGL *display; + EGLImageKHR image; + GstVideoFormat format; + guint width; + guint height; + GstVaapiSurface *surface; /* result */ +} CreateSurfaceWithEGLImageArgs; + +static GstVaapiSurface * +do_create_surface_with_egl_image_unlocked (GstVaapiDisplayEGL * display, + EGLImageKHR image, GstVideoFormat format, guint width, guint height) +{ + GstVaapiDisplay *const base_display = GST_VAAPI_DISPLAY_CAST (display); + EglContext *const ctx = GST_VAAPI_DISPLAY_EGL_CONTEXT (display); + EglVTable *vtable; + gsize size, offset[GST_VIDEO_MAX_PLANES]; + gint name, stride[GST_VIDEO_MAX_PLANES]; + + if (!ctx || !(vtable = egl_context_get_vtable (ctx, FALSE))) + return NULL; + + memset (offset, 0, sizeof (offset)); + memset (stride, 0, sizeof (stride)); + + if (vtable->has_EGL_MESA_drm_image) { + /* EGL_MESA_drm_image extension */ + if (!vtable->eglExportDRMImageMESA (ctx->display->base.handle.p, image, + &name, NULL, &stride[0])) + goto error_export_image_gem_buf; + + size = height * stride[0]; + return gst_vaapi_surface_new_with_gem_buf_handle (base_display, name, size, + format, width, height, offset, stride); + } + return NULL; + + /* ERRORS */ +error_export_image_gem_buf: + GST_ERROR ("failed to export EGL image to GEM buffer"); + return NULL; +} + +static void +do_create_surface_with_egl_image (CreateSurfaceWithEGLImageArgs * args) +{ + GST_VAAPI_DISPLAY_LOCK (args->display); + args->surface = do_create_surface_with_egl_image_unlocked (args->display, + args->image, args->format, args->width, args->height); + GST_VAAPI_DISPLAY_UNLOCK (args->display); +} + +// Creates VA surface with EGLImage buffer as backing storage (internal) +static inline GstVaapiSurface * +create_surface_with_egl_image (GstVaapiDisplayEGL * display, EGLImageKHR image, + GstVideoFormat format, guint width, guint height) +{ + CreateSurfaceWithEGLImageArgs args = + { display, image, format, width, height }; + + if (!egl_context_run (GST_VAAPI_DISPLAY_EGL_CONTEXT (display), + (EglContextRunFunc) do_create_surface_with_egl_image, &args)) + return NULL; + return args.surface; +} + +// Creates VA surface from an EGLImage buffer copy (internal) +static GstVaapiSurface * +create_surface_from_egl_image (GstVaapiDisplayEGL * display, + const GstVideoInfo * vip, EGLImageKHR image, GstVideoFormat format, + guint width, guint height, guint flags) +{ + GstVaapiDisplay *const base_display = GST_VAAPI_DISPLAY_CAST (display); + GstVaapiSurface *img_surface = NULL, *out_surface = NULL; + gboolean use_native_format = TRUE; + GstVaapiFilter *filter = NULL; + GstVaapiFilterStatus filter_status; + + img_surface = create_surface_with_egl_image (display, image, format, + width, height); + if (!img_surface) + return NULL; + + if (vip) { + use_native_format = + GST_VIDEO_INFO_FORMAT (vip) == GST_VIDEO_FORMAT_ENCODED || + GST_VIDEO_INFO_FORMAT (vip) == GST_VIDEO_FORMAT_UNKNOWN; + + if (GST_VIDEO_INFO_WIDTH (vip) && GST_VIDEO_INFO_HEIGHT (vip)) { + width = GST_VIDEO_INFO_WIDTH (vip); + height = GST_VIDEO_INFO_HEIGHT (vip); + } + } + + if (use_native_format) { + out_surface = gst_vaapi_surface_new (base_display, + GST_VAAPI_CHROMA_TYPE_YUV420, width, height); + } else { + out_surface = gst_vaapi_surface_new_with_format (base_display, + GST_VIDEO_INFO_FORMAT (vip), width, height); + } + if (!out_surface) + goto error_create_surface; + + filter = gst_vaapi_filter_new (base_display); + if (!filter) + goto error_create_filter; + + filter_status = gst_vaapi_filter_process (filter, + img_surface, out_surface, flags); + if (filter_status != GST_VAAPI_FILTER_STATUS_SUCCESS) + goto error_convert_surface; + + gst_vaapi_object_unref (img_surface); + gst_vaapi_filter_unref (filter); + return out_surface; + + /* ERRORS */ +error_create_surface: + GST_ERROR ("failed to create output surface format:%s size:%dx%d", + gst_vaapi_video_format_to_string (vip ? GST_VIDEO_INFO_FORMAT (vip) : + GST_VIDEO_FORMAT_ENCODED), width, height); + goto error_cleanup; +error_convert_surface: + GST_ERROR ("failed to transfer EGL image to VA surface (status = %d)", + filter_status); + goto error_cleanup; +error_create_filter: + GST_ERROR ("failed to create video processing filter"); + // fall-through +error_cleanup: + gst_vaapi_object_replace (&img_surface, NULL); + gst_vaapi_object_replace (&out_surface, NULL); + gst_vaapi_filter_replace (&filter, NULL); + return NULL; +} + +/** + * gst_vaapi_surface_new_from_egl_image: + * @display: a #GstVaapiDisplay + * @vip: the desired (optional) #GstVideoInfo constraints + * @image: the EGL image to import + * @format: the EGL @image format + * @width: the EGL @image width in pixels + * @height: the EGL @image height in pixels + * @flags: postprocessing flags. See #GstVaapiSurfaceRenderFlags + * + * Creates a new #GstVaapiSurface with a copy of the EGL image + * contents. i.e. the input EGL @image can be disposed and the + * resulting VA surface would still be valid with the contents at the + * time this function was called. + * + * If @vip is %NULL, then the resulting VA surface will be created + * with the same video format and size as the original @image. If @vip + * is non-%NULL and the desired format is GST_VIDEO_FORMAT_ENCODED, + * then the resulting VA surface will have the best "native" HW + * format, usually NV12. + * + * Return value: the newly allocated #GstVaapiSurface object, or %NULL + * if creation from EGL image failed, or is not supported + */ +GstVaapiSurface * +gst_vaapi_surface_new_from_egl_image (GstVaapiDisplay * base_display, + const GstVideoInfo * vip, EGLImageKHR image, GstVideoFormat format, + guint width, guint height, guint flags) +{ + GstVaapiDisplayEGL *display; + + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (base_display), NULL); + g_return_val_if_fail (image != EGL_NO_IMAGE_KHR, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + + display = GST_VAAPI_DISPLAY_EGL (base_display); + if (!display || !GST_VAAPI_IS_DISPLAY_EGL (display)) + goto error_invalid_display; + return create_surface_from_egl_image (display, vip, image, format, + width, height, flags); + + /* ERRORS */ +error_invalid_display: + GST_ERROR ("invalid display (NULL or not of EGL class"); + return NULL; +} + +/** + * gst_vaapi_surface_new_with_egl_image: + * @display: a #GstVaapiDisplay + * @image: the EGL image to import + * @format: the EGL @image format + * @width: the EGL @image width in pixels + * @height: the EGL @image height in pixels + * + * Creates a new #GstVaapiSurface bound to an external EGL image. + * + * The caller maintains the lifetime of the EGL image object. In + * particular, the EGL image shall not be destroyed before the last + * reference to the resulting VA surface is released. + * + * Return value: the newly allocated #GstVaapiSurface object, or %NULL + * if creation from EGL image failed, or is not supported + */ +GstVaapiSurface * +gst_vaapi_surface_new_with_egl_image (GstVaapiDisplay * base_display, + EGLImageKHR image, GstVideoFormat format, guint width, guint height) +{ + GstVaapiDisplayEGL *display; + + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (base_display), NULL); + g_return_val_if_fail (image != EGL_NO_IMAGE_KHR, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + + display = GST_VAAPI_DISPLAY_EGL (base_display); + if (!display || !GST_VAAPI_IS_DISPLAY_EGL (display)) + goto error_invalid_display; + return create_surface_with_egl_image (display, image, format, width, height); + + /* ERRORS */ +error_invalid_display: + GST_ERROR ("invalid display (NULL or not of EGL class"); + return NULL; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurface_egl.h b/gst-libs/gst/vaapi/gstvaapisurface_egl.h new file mode 100644 index 0000000000..70c8df8b77 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapisurface_egl.h @@ -0,0 +1,43 @@ +/* + * gstvaapisurface_egl.h - VA surface abstraction (EGL interop) + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_SURFACE_EGL_H +#define GST_VAAPI_SURFACE_EGL_H + +#include +#include +#include + +G_BEGIN_DECLS + +GstVaapiSurface * +gst_vaapi_surface_new_from_egl_image (GstVaapiDisplay * display, + const GstVideoInfo * vip, EGLImageKHR image, GstVideoFormat format, + guint width, guint height, guint flags); + +GstVaapiSurface * +gst_vaapi_surface_new_with_egl_image (GstVaapiDisplay * display, + EGLImageKHR image, GstVideoFormat format, guint width, guint height); + +G_END_DECLS + +#endif /* GST_VAAPI_SURFACE_EGL_H */ From 23c489d8eebbcfe544a224d57ff3dcf505bf4d85 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 24 Jan 2015 08:29:57 +0100 Subject: [PATCH 1893/3781] egl: add texture abstraction. Add GstVaapiTextureEGL abstraction that can create its own GL texture, or import a foreign allocated one, while still allowing updates from a VA surface. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 13 + gst-libs/gst/vaapi/gstvaapitexture_egl.c | 349 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapitexture_egl.h | 40 +++ 4 files changed, 404 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapitexture_egl.c create mode 100644 gst-libs/gst/vaapi/gstvaapitexture_egl.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index bcd5fb91de..8073582812 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -278,12 +278,14 @@ libgstvaapi_glx_source_priv_h = \ libgstvaapi_egl_source_c = \ gstvaapidisplay_egl.c \ gstvaapisurface_egl.c \ + gstvaapitexture_egl.c \ gstvaapiutils_egl.c \ $(NULL) libgstvaapi_egl_source_h = \ gstvaapidisplay_egl.h \ gstvaapisurface_egl.h \ + gstvaapitexture_egl.h \ $(NULL) libgstvaapi_egl_source_priv_h = \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index b02f25380f..4de23456dd 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -25,6 +25,7 @@ #include "gstvaapidisplay_egl.h" #include "gstvaapidisplay_egl_priv.h" #include "gstvaapiwindow.h" +#include "gstvaapitexture_egl.h" GST_DEBUG_CATEGORY (gst_debug_vaapidisplay_egl); @@ -441,6 +442,16 @@ gst_vaapi_display_egl_get_size_mm (GstVaapiDisplayEGL * display, klass->get_size_mm (display->display, width_ptr, height_ptr); } +static GstVaapiTexture * +gst_vaapi_display_egl_create_texture (GstVaapiDisplay * display, GstVaapiID id, + guint target, guint format, guint width, guint height) +{ + return id != GST_VAAPI_ID_INVALID ? + gst_vaapi_texture_egl_new_wrapped (display, id, target, format, + width, height) : + gst_vaapi_texture_egl_new (display, target, format, width, height); +} + static void gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass) { @@ -473,6 +484,8 @@ gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass) gst_vaapi_display_egl_get_size; dpy_class->get_size_mm = (GstVaapiDisplayGetSizeMFunc) gst_vaapi_display_egl_get_size_mm; + dpy_class->create_texture = (GstVaapiDisplayCreateTextureFunc) + gst_vaapi_display_egl_create_texture; } static inline const GstVaapiDisplayClass * diff --git a/gst-libs/gst/vaapi/gstvaapitexture_egl.c b/gst-libs/gst/vaapi/gstvaapitexture_egl.c new file mode 100644 index 0000000000..b350b22fff --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapitexture_egl.c @@ -0,0 +1,349 @@ +/* + * gstvaapitexture_egl.c - VA/EGL texture abstraction + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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:gstvaapitexture_egl + * @short_description: VA/EGL texture abstraction + */ + +#include "sysdeps.h" +#include "gstvaapitexture.h" +#include "gstvaapitexture_egl.h" +#include "gstvaapitexture_priv.h" +#include "gstvaapicompat.h" +#include "gstvaapiutils.h" +#include "gstvaapiutils_egl.h" +#include "gstvaapidisplay_egl.h" +#include "gstvaapidisplay_egl_priv.h" +#include "gstvaapisurface_egl.h" +#include "gstvaapifilter.h" + +#define GST_VAAPI_TEXTURE_EGL(texture) \ + ((GstVaapiTextureEGL *) (texture)) + +typedef struct _GstVaapiTextureEGL GstVaapiTextureEGL; +typedef struct _GstVaapiTextureEGLClass GstVaapiTextureEGLClass; + +/** + * GstVaapiTextureEGL: + * + * Base object for EGL texture wrapper. + */ +struct _GstVaapiTextureEGL +{ + /*< private >*/ + GstVaapiTexture parent_instance; + + EglContext *egl_context; + EGLImageKHR egl_image; + GstVaapiSurface *surface; + GstVaapiFilter *filter; +}; + +/** + * GstVaapiTextureEGLClass: + * + * Base class for EGL texture wrapper. + */ +struct _GstVaapiTextureEGLClass +{ + /*< private >*/ + GstVaapiTextureClass parent_class; +}; + +typedef struct +{ + GstVaapiTextureEGL *texture; + gboolean success; /* result */ +} CreateTextureArgs; + +typedef struct +{ + GstVaapiTextureEGL *texture; + GstVaapiSurface *surface; + const GstVaapiRectangle *crop_rect; + guint flags; + gboolean success; /* result */ +} UploadSurfaceArgs; + +static gboolean +create_objects (GstVaapiTextureEGL * texture, GLuint texture_id) +{ + GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture); + EglContext *const ctx = texture->egl_context; + EglVTable *const vtable = egl_context_get_vtable (ctx, FALSE); + GLint attribs[3], *attrib; + + attrib = attribs; + *attrib++ = EGL_IMAGE_PRESERVED_KHR; + *attrib++ = EGL_TRUE; + *attrib++ = EGL_NONE; + texture->egl_image = vtable->eglCreateImageKHR (ctx->display->base.handle.p, + ctx->base.handle.p, EGL_GL_TEXTURE_2D_KHR, + (EGLClientBuffer) GSIZE_TO_POINTER (texture_id), attribs); + if (!texture->egl_image) + goto error_create_image; + + texture->surface = + gst_vaapi_surface_new_with_egl_image (GST_VAAPI_OBJECT_DISPLAY (texture), + texture->egl_image, GST_VIDEO_FORMAT_RGBA, base_texture->width, + base_texture->height); + if (!texture->surface) + goto error_create_surface; + + texture->filter = gst_vaapi_filter_new (GST_VAAPI_OBJECT_DISPLAY (texture)); + if (!texture->filter) + goto error_create_filter; + return TRUE; + + /* ERRORS */ +error_create_image: + GST_ERROR ("failed to create EGL image from 2D texture %u", texture_id); + return FALSE; +error_create_surface: + GST_ERROR ("failed to create VA surface from 2D texture %u", texture_id); + return FALSE; +error_create_filter: + GST_ERROR ("failed to create VPP filter for color conversion"); + return FALSE; +} + +static gboolean +do_create_texture_unlocked (GstVaapiTextureEGL * texture) +{ + GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture); + GLuint texture_id; + + if (base_texture->is_wrapped) + texture_id = GST_VAAPI_TEXTURE_ID (texture); + else { + texture_id = egl_create_texture (texture->egl_context, + base_texture->gl_target, base_texture->gl_format, + base_texture->width, base_texture->height); + if (!texture_id) + return FALSE; + GST_VAAPI_TEXTURE_ID (texture) = texture_id; + } + return create_objects (texture, texture_id); +} + +static void +do_create_texture (CreateTextureArgs * args) +{ + GstVaapiTextureEGL *const texture = args->texture; + EglContextState old_cs; + + args->success = FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) { + args->success = do_create_texture_unlocked (texture); + egl_context_set_current (texture->egl_context, FALSE, &old_cs); + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); +} + +static void +destroy_objects (GstVaapiTextureEGL * texture) +{ + EglContext *const ctx = texture->egl_context; + EglVTable *const vtable = egl_context_get_vtable (ctx, FALSE); + + if (texture->egl_image != EGL_NO_IMAGE_KHR) { + vtable->eglDestroyImageKHR (ctx->display->base.handle.p, + texture->egl_image); + texture->egl_image = EGL_NO_IMAGE_KHR; + } + gst_vaapi_object_replace (&texture->surface, NULL); + gst_vaapi_filter_replace (&texture->filter, NULL); +} + +static void +do_destroy_texture_unlocked (GstVaapiTextureEGL * texture) +{ + GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture); + const GLuint texture_id = GST_VAAPI_TEXTURE_ID (texture); + + destroy_objects (texture); + + if (texture_id) { + if (!base_texture->is_wrapped) + egl_destroy_texture (texture->egl_context, texture_id); + GST_VAAPI_TEXTURE_ID (texture) = 0; + } +} + +static void +do_destroy_texture (GstVaapiTextureEGL * texture) +{ + EglContextState old_cs; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) { + do_destroy_texture_unlocked (texture); + egl_context_set_current (texture->egl_context, FALSE, &old_cs); + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + egl_object_replace (&texture->egl_context, NULL); +} + +static gboolean +do_upload_surface_unlocked (GstVaapiTextureEGL * texture, + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) +{ + GstVaapiFilterStatus status; + + if (!gst_vaapi_filter_set_cropping_rectangle (texture->filter, crop_rect)) + return FALSE; + + status = gst_vaapi_filter_process (texture->filter, surface, texture->surface, + flags); + if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) + return FALSE; + return TRUE; +} + +static void +do_upload_surface (UploadSurfaceArgs * args) +{ + GstVaapiTextureEGL *const texture = args->texture; + EglContextState old_cs; + + args->success = FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) { + args->success = do_upload_surface_unlocked (texture, args->surface, + args->crop_rect, args->flags); + egl_context_set_current (texture->egl_context, FALSE, &old_cs); + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); +} + +static gboolean +gst_vaapi_texture_egl_create (GstVaapiTextureEGL * texture) +{ + CreateTextureArgs args = { texture }; + + egl_object_replace (&texture->egl_context, + GST_VAAPI_DISPLAY_EGL_CONTEXT (GST_VAAPI_OBJECT_DISPLAY (texture))); + + return egl_context_run (texture->egl_context, + (EglContextRunFunc) do_create_texture, &args) && args.success; +} + +static void +gst_vaapi_texture_egl_destroy (GstVaapiTextureEGL * texture) +{ + egl_context_run (texture->egl_context, + (EglContextRunFunc) do_destroy_texture, texture); +} + +static gboolean +gst_vaapi_texture_egl_put_surface (GstVaapiTextureEGL * texture, + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) +{ + UploadSurfaceArgs args = { texture, surface, crop_rect, flags }; + + return egl_context_run (texture->egl_context, + (EglContextRunFunc) do_upload_surface, &args) && args.success; +} + +static void +gst_vaapi_texture_egl_class_init (GstVaapiTextureEGLClass * klass) +{ + GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); + GstVaapiTextureClass *const texture_class = GST_VAAPI_TEXTURE_CLASS (klass); + + object_class->finalize = (GstVaapiObjectFinalizeFunc) + gst_vaapi_texture_egl_destroy; + texture_class->allocate = (GstVaapiTextureAllocateFunc) + gst_vaapi_texture_egl_create; + texture_class->put_surface = (GstVaapiTexturePutSurfaceFunc) + gst_vaapi_texture_egl_put_surface; +} + +#define gst_vaapi_texture_egl_finalize gst_vaapi_texture_egl_destroy +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiTextureEGL, + gst_vaapi_texture_egl, gst_vaapi_texture_egl_class_init (&g_class)); + +/** + * gst_vaapi_texture_egl_new: + * @display: a #GstVaapiDisplay + * @target: the target to which the texture is bound + * @format: the format of the pixel data + * @width: the requested width, in pixels + * @height: the requested height, in pixels + * + * Creates a texture with the specified dimensions, @target and + * @format. Note that only GL_TEXTURE_2D @target and GL_RGBA or + * GL_BGRA formats are supported at this time. + * + * The application shall maintain the live EGL context itself. That + * is, gst_vaapi_window_egl_make_current() must be called beforehand, + * or any other function like eglMakeCurrent() if the context is + * managed outside of this library. + * + * Return value: the newly created #GstVaapiTexture object + */ +GstVaapiTexture * +gst_vaapi_texture_egl_new (GstVaapiDisplay * display, guint target, + guint format, guint width, guint height) +{ + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL); + + return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS + (gst_vaapi_texture_egl_class ()), display, GST_VAAPI_ID_INVALID, target, + format, width, height); +} + +/** + * gst_vaapi_texture_egl_new_wrapped: + * @display: a #GstVaapiDisplay + * @texture_id: the foreign GL texture name to use + * @target: the target to which the texture is bound + * @format: the format of the pixel data + * @width: the texture width, in pixels + * @height: the texture height, in pixels + * + * Creates a texture from an existing GL texture, with the specified + * @target and @format. Note that only GL_TEXTURE_2D @target and + * GL_RGBA or GL_BGRA formats are supported at this time. + * + * The application shall maintain the live EGL context itself. That + * is, gst_vaapi_window_egl_make_current() must be called beforehand, + * or any other function like eglMakeCurrent() if the context is + * managed outside of this library. + * + * Return value: the newly created #GstVaapiTexture object + */ +GstVaapiTexture * +gst_vaapi_texture_egl_new_wrapped (GstVaapiDisplay * display, + guint texture_id, guint target, GLenum format, guint width, guint height) +{ + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL); + g_return_val_if_fail (texture_id != GL_NONE, NULL); + + return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS + (gst_vaapi_texture_egl_class ()), display, texture_id, target, format, + width, height); +} diff --git a/gst-libs/gst/vaapi/gstvaapitexture_egl.h b/gst-libs/gst/vaapi/gstvaapitexture_egl.h new file mode 100644 index 0000000000..848c15d6e7 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapitexture_egl.h @@ -0,0 +1,40 @@ +/* + * gstvaapitexture_egl.h - VA/EGL texture abstraction + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_TEXTURE_EGL_H +#define GST_VAAPI_TEXTURE_EGL_H + +#include + +G_BEGIN_DECLS + +GstVaapiTexture * +gst_vaapi_texture_egl_new (GstVaapiDisplay * display, guint target, + guint format, guint width, guint height); + +GstVaapiTexture * +gst_vaapi_texture_egl_new_wrapped (GstVaapiDisplay * display, guint id, + guint target, guint format, guint width, guint height); + +G_END_DECLS + +#endif /* GST_VAAPI_TEXTURE_EGL_H */ From aabb8c99c23199ee17c4a91b64573c2cc5fe619c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 27 Jan 2015 16:21:04 +0100 Subject: [PATCH 1894/3781] egl: add windowing support. This provides for some basic EGL window abstraction. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 24 + gst-libs/gst/vaapi/gstvaapiutils_egl.c | 69 ++- gst-libs/gst/vaapi/gstvaapiutils_egl.h | 13 + gst-libs/gst/vaapi/gstvaapiwindow_egl.c | 565 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow_egl.h | 39 ++ 6 files changed, 710 insertions(+), 2 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_egl.c create mode 100644 gst-libs/gst/vaapi/gstvaapiwindow_egl.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 8073582812..9e5fe88d85 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -280,12 +280,14 @@ libgstvaapi_egl_source_c = \ gstvaapisurface_egl.c \ gstvaapitexture_egl.c \ gstvaapiutils_egl.c \ + gstvaapiwindow_egl.c \ $(NULL) libgstvaapi_egl_source_h = \ gstvaapidisplay_egl.h \ gstvaapisurface_egl.h \ gstvaapitexture_egl.h \ + gstvaapiwindow_egl.h \ $(NULL) libgstvaapi_egl_source_priv_h = \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index 4de23456dd..30385d2b04 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -25,6 +25,8 @@ #include "gstvaapidisplay_egl.h" #include "gstvaapidisplay_egl_priv.h" #include "gstvaapiwindow.h" +#include "gstvaapiwindow_egl.h" +#include "gstvaapiwindow_priv.h" #include "gstvaapitexture_egl.h" GST_DEBUG_CATEGORY (gst_debug_vaapidisplay_egl); @@ -442,6 +444,24 @@ gst_vaapi_display_egl_get_size_mm (GstVaapiDisplayEGL * display, klass->get_size_mm (display->display, width_ptr, height_ptr); } +static guintptr +gst_vaapi_display_egl_get_visual_id (GstVaapiDisplayEGL * display, + GstVaapiWindow * window) +{ + 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 GstVaapiTexture * gst_vaapi_display_egl_create_texture (GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height) @@ -484,6 +504,10 @@ gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass) gst_vaapi_display_egl_get_size; dpy_class->get_size_mm = (GstVaapiDisplayGetSizeMFunc) gst_vaapi_display_egl_get_size_mm; + dpy_class->get_visual_id = (GstVaapiDisplayGetVisualIdFunc) + gst_vaapi_display_egl_get_visual_id; + dpy_class->create_window = (GstVaapiDisplayCreateWindowFunc) + gst_vaapi_display_egl_create_window; dpy_class->create_texture = (GstVaapiDisplayCreateTextureFunc) gst_vaapi_display_egl_create_texture; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c index 6217625139..12cbd826f2 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -168,6 +168,7 @@ typedef struct egl_object_class_s EglConfigClass; typedef struct egl_object_class_s EglContextClass; typedef struct egl_object_class_s EglSurfaceClass; typedef struct egl_object_class_s EglProgramClass; +typedef struct egl_object_class_s EglWindowClass; EGL_OBJECT_DEFINE_CLASS (EglMessage, egl_message); EGL_OBJECT_DEFINE_CLASS (EglVTable, egl_vtable); @@ -176,6 +177,7 @@ EGL_OBJECT_DEFINE_CLASS (EglConfig, egl_config); EGL_OBJECT_DEFINE_CLASS (EglContext, egl_context); EGL_OBJECT_DEFINE_CLASS (EglSurface, egl_surface); EGL_OBJECT_DEFINE_CLASS (EglProgram, egl_program); +EGL_OBJECT_DEFINE_CLASS (EglWindow, egl_window); /* ------------------------------------------------------------------------- */ // Desktop OpenGL and OpenGL|ES dispatcher (vtable) @@ -818,7 +820,7 @@ egl_surface_finalize (EglSurface * surface) egl_object_replace (&surface->display, NULL); } -EglSurface * +static EglSurface * egl_surface_new_wrapped (EglDisplay * display, EGLSurface gl_surface) { EglSurface *surface; @@ -1088,7 +1090,7 @@ egl_context_get_vtable (EglContext * ctx, gboolean need_gl_symbols) return ctx->vtable; } -void +static void egl_context_set_surface (EglContext * ctx, EglSurface * surface) { g_return_if_fail (ctx != NULL); @@ -1257,6 +1259,69 @@ error: return NULL; } +/* ------------------------------------------------------------------------- */ +// EGL Window + +static gboolean +egl_window_init (EglWindow * window, EglContext * ctx, gpointer native_window) +{ + EGLSurface gl_surface; + + window->context = egl_context_new (ctx->display, ctx->config, ctx); + if (!window->context) + return FALSE; + ctx = window->context; + + gl_surface = eglCreateWindowSurface (ctx->display->base.handle.p, + ctx->config->base.handle.p, (EGLNativeWindowType) native_window, NULL); + if (!gl_surface) + return FALSE; + + window->surface = egl_surface_new_wrapped (ctx->display, gl_surface); + if (!window->surface) + goto error_create_surface; + window->base.handle.p = gl_surface; + window->base.is_wrapped = FALSE; + + egl_context_set_surface (ctx, window->surface); + return TRUE; + + /* ERRORS */ +error_create_surface: + GST_ERROR ("failed to create EGL wrapper surface"); + eglDestroySurface (ctx->display->base.handle.p, gl_surface); + return FALSE; +} + +static void +egl_window_finalize (EglWindow * window) +{ + if (window->context && window->base.handle.p) + eglDestroySurface (window->context->display->base.handle.p, + window->base.handle.p); + + egl_object_replace (&window->surface, NULL); + egl_object_replace (&window->context, NULL); +} + +EglWindow * +egl_window_new (EglContext * ctx, gpointer native_window) +{ + EglWindow *window; + + g_return_val_if_fail (ctx != NULL, NULL); + g_return_val_if_fail (native_window != NULL, NULL); + + window = egl_object_new0 (egl_window_class ()); + if (!window || !egl_window_init (window, ctx, native_window)) + goto error; + return window; + +error: + egl_object_replace (&window, NULL); + return NULL; +} + /* ------------------------------------------------------------------------- */ // Misc utility functions diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.h b/gst-libs/gst/vaapi/gstvaapiutils_egl.h index d1fd28ded7..1c5cdc3083 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.h @@ -42,6 +42,7 @@ typedef struct egl_context_state_s EglContextState; typedef struct egl_context_s EglContext; typedef struct egl_surface_s EglSurface; typedef struct egl_program_s EglProgram; +typedef struct egl_window_s EglWindow; #define EGL_PROTO_BEGIN(NAME, TYPE, EXTENSION) \ typedef TYPE (*GL_PROTO_GEN_CONCAT3(Egl,NAME,Proc)) @@ -171,6 +172,14 @@ struct egl_program_s gint uniforms[EGL_MAX_UNIFORMS]; }; +struct egl_window_s +{ + EglObject base; + + EglContext *context; + EglSurface *surface; +}; + #define egl_object_ref(obj) \ ((gpointer)gst_vaapi_mini_object_ref ((GstVaapiMiniObject *)(obj))) #define egl_object_unref(obj) \ @@ -222,6 +231,10 @@ EglProgram * egl_program_new (EglContext * ctx, const gchar * frag_shader_text, const gchar * vert_shader_text); +G_GNUC_INTERNAL +EglWindow * +egl_window_new (EglContext * ctx, gpointer native_window); + G_GNUC_INTERNAL guint egl_create_texture (EglContext * ctx, guint target, guint format, diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c new file mode 100644 index 0000000000..006ca2eb57 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c @@ -0,0 +1,565 @@ +/* + * gstvaapiwindow_egl.c - VA/EGL window abstraction + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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:gstvaapiwindow_egl + * @short_description: VA/EGL window abstraction + */ + +#include "sysdeps.h" +#include "gstvaapiwindow_egl.h" +#include "gstvaapiwindow_priv.h" +#include "gstvaapitexture_egl.h" +#include "gstvaapitexture_priv.h" +#include "gstvaapidisplay_egl_priv.h" + +#define GST_VAAPI_WINDOW_EGL(obj) \ + ((GstVaapiWindowEGL *)(obj)) + +#define GST_VAAPI_WINDOW_EGL_CLASS(klass) \ + ((GstVaapiWindowEGLClass *)(klass)) + +#define GST_VAAPI_WINDOW_EGL_GET_CLASS(obj) \ + GST_VAAPI_WINDOW_EGL_CLASS (GST_VAAPI_WINDOW_GET_CLASS (obj)) + +typedef struct _GstVaapiWindowEGL GstVaapiWindowEGL; +typedef struct _GstVaapiWindowEGLClass GstVaapiWindowEGLClass; + +enum +{ + RENDER_PROGRAM_VAR_PROJ = 0, + RENDER_PROGRAM_VAR_TEX0, + RENDER_PROGRAM_VAR_TEX1, + RENDER_PROGRAM_VAR_TEX2, +}; + +struct _GstVaapiWindowEGL +{ + GstVaapiWindow parent_instance; + + GstVaapiWindow *window; + GstVaapiTexture *texture; + EglWindow *egl_window; + EglVTable *egl_vtable; + EglProgram *render_program; + gfloat render_projection[16]; +}; + +struct _GstVaapiWindowEGLClass +{ + GstVaapiWindowClass parent_class; +}; + +typedef struct +{ + GstVaapiWindowEGL *window; + guint width; + guint height; + EglContext *egl_context; + gboolean success; /* result */ +} CreateObjectsArgs; + +typedef struct +{ + GstVaapiWindowEGL *window; + guint width; + guint height; + gboolean success; /* result */ +} ResizeWindowArgs; + +typedef struct +{ + GstVaapiWindowEGL *window; + GstVaapiSurface *surface; + const GstVaapiRectangle *src_rect; + const GstVaapiRectangle *dst_rect; + guint flags; + gboolean success; /* result */ +} UploadSurfaceArgs; + +static const gchar *vert_shader_text = + "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "\n" + "uniform mat4 proj;\n" + "\n" + "attribute vec2 position;\n" + "attribute vec2 texcoord;\n" + "varying vec2 v_texcoord;\n" + "\n" + "void main () {\n" + " gl_Position = proj * vec4 (position, 0.0, 1.0);\n" + " v_texcoord = texcoord;\n" + "}\n"; + +static const gchar *frag_shader_text_rgba = + "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "\n" + "uniform sampler2D tex0;\n" + "\n" + "varying vec2 v_texcoord;\n" + "\n" + "void main () {\n" + " gl_FragColor = texture2D (tex0, v_texcoord);\n" + "}\n"; + +static gboolean +ensure_texture (GstVaapiWindowEGL * window, guint width, guint height) +{ + GstVaapiTexture *texture; + + if (window->texture && + GST_VAAPI_TEXTURE_WIDTH (window->texture) == width && + GST_VAAPI_TEXTURE_HEIGHT (window->texture) == height) + return TRUE; + + texture = gst_vaapi_texture_egl_new (GST_VAAPI_OBJECT_DISPLAY (window), + GL_TEXTURE_2D, GL_RGBA, width, height); + gst_vaapi_texture_replace (&window->texture, texture); + gst_vaapi_texture_replace (&texture, NULL); + return window->texture != NULL; +} + +static gboolean +ensure_shaders (GstVaapiWindowEGL * window) +{ + EglVTable *const vtable = window->egl_vtable; + EglProgram *program; + GLuint prog_id; + + g_return_val_if_fail (window->texture != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_TEXTURE_FORMAT (window->texture) == GL_RGBA, + FALSE); + + if (window->render_program) + return TRUE; + + program = egl_program_new (window->egl_window->context, + frag_shader_text_rgba, vert_shader_text); + if (!program) + return FALSE; + + prog_id = program->base.handle.u; + + vtable->glUseProgram (prog_id); + program->uniforms[RENDER_PROGRAM_VAR_PROJ] = + vtable->glGetUniformLocation (prog_id, "proj"); + program->uniforms[RENDER_PROGRAM_VAR_TEX0] = + vtable->glGetUniformLocation (prog_id, "tex0"); + program->uniforms[RENDER_PROGRAM_VAR_TEX1] = + vtable->glGetUniformLocation (prog_id, "tex1"); + program->uniforms[RENDER_PROGRAM_VAR_TEX2] = + vtable->glGetUniformLocation (prog_id, "tex2"); + vtable->glUseProgram (0); + + egl_matrix_set_identity (window->render_projection); + + egl_object_replace (&window->render_program, program); + egl_object_replace (&program, NULL); + return TRUE; +} + +static gboolean +do_create_objects_unlocked (GstVaapiWindowEGL * window, guint width, + guint height, EglContext * egl_context) +{ + EglWindow *egl_window; + EglVTable *egl_vtable; + + egl_window = egl_window_new (egl_context, + GSIZE_TO_POINTER (GST_VAAPI_OBJECT_ID (window->window))); + if (!egl_window) + return FALSE; + window->egl_window = egl_window; + + egl_vtable = egl_context_get_vtable (egl_window->context, TRUE); + if (!egl_vtable) + return FALSE; + window->egl_vtable = egl_object_ref (egl_vtable); + return TRUE; +} + +static void +do_create_objects (CreateObjectsArgs * args) +{ + GstVaapiWindowEGL *const window = args->window; + EglContextState old_cs; + + args->success = FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + if (egl_context_set_current (args->egl_context, TRUE, &old_cs)) { + args->success = do_create_objects_unlocked (window, args->width, + args->height, args->egl_context); + egl_context_set_current (args->egl_context, FALSE, &old_cs); + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); +} + +static gboolean +gst_vaapi_window_egl_create (GstVaapiWindowEGL * window, + guint * width, guint * height) +{ + GstVaapiDisplayEGL *const display = + GST_VAAPI_DISPLAY_EGL (GST_VAAPI_OBJECT_DISPLAY (window)); + const GstVaapiDisplayClass *const native_dpy_class = + GST_VAAPI_DISPLAY_GET_CLASS (display->display); + CreateObjectsArgs args; + + g_return_val_if_fail (native_dpy_class != NULL, FALSE); + + window->window = native_dpy_class->create_window (GST_VAAPI_DISPLAY (display), + GST_VAAPI_ID_INVALID, *width, *height); + if (!window->window) + return FALSE; + + gst_vaapi_window_get_size (window->window, width, height); + + args.window = window; + args.width = *width; + args.height = *height; + args.egl_context = GST_VAAPI_DISPLAY_EGL_CONTEXT (display); + return egl_context_run (args.egl_context, + (EglContextRunFunc) do_create_objects, &args) && args.success; +} + +static void +do_destroy_objects_unlocked (GstVaapiWindowEGL * window) +{ + egl_object_replace (&window->render_program, NULL); + egl_object_replace (&window->egl_vtable, NULL); + egl_object_replace (&window->egl_window, NULL); +} + +static void +do_destroy_objects (GstVaapiWindowEGL * window) +{ + EglContext *const egl_context = + GST_VAAPI_DISPLAY_EGL_CONTEXT (GST_VAAPI_OBJECT_DISPLAY (window)); + EglContextState old_cs; + + if (!window->egl_window) + return; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + if (egl_context_set_current (egl_context, TRUE, &old_cs)) { + do_destroy_objects_unlocked (window); + egl_context_set_current (egl_context, FALSE, &old_cs); + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); +} + +static void +gst_vaapi_window_egl_destroy (GstVaapiWindowEGL * window) +{ + egl_context_run (window->egl_window->context, + (EglContextRunFunc) do_destroy_objects, window); + gst_vaapi_window_replace (&window->window, NULL); + gst_vaapi_texture_replace (&window->texture, NULL); +} + +static gboolean +gst_vaapi_window_egl_show (GstVaapiWindowEGL * window) +{ + const GstVaapiWindowClass *const klass = + GST_VAAPI_WINDOW_GET_CLASS (window->window); + + g_return_val_if_fail (klass->show, FALSE); + + return klass->show (window->window); +} + +static gboolean +gst_vaapi_window_egl_hide (GstVaapiWindowEGL * window) +{ + const GstVaapiWindowClass *const klass = + GST_VAAPI_WINDOW_GET_CLASS (window->window); + + g_return_val_if_fail (klass->hide, FALSE); + + return klass->hide (window->window); +} + +static gboolean +gst_vaapi_window_egl_get_geometry (GstVaapiWindowEGL * window, + gint * x_ptr, gint * y_ptr, guint * width_ptr, guint * height_ptr) +{ + const GstVaapiWindowClass *const klass = + GST_VAAPI_WINDOW_GET_CLASS (window->window); + + return klass->get_geometry ? klass->get_geometry (window->window, + x_ptr, y_ptr, width_ptr, height_ptr) : FALSE; +} + +static gboolean +gst_vaapi_window_egl_set_fullscreen (GstVaapiWindowEGL * window, + gboolean fullscreen) +{ + const GstVaapiWindowClass *const klass = + GST_VAAPI_WINDOW_GET_CLASS (window->window); + + return klass->set_fullscreen ? klass->set_fullscreen (window->window, + fullscreen) : FALSE; +} + +static gboolean +do_resize_window_unlocked (GstVaapiWindowEGL * window, guint width, + guint height) +{ + EglVTable *const vtable = window->egl_vtable; + + vtable->glViewport (0, 0, width, height); + vtable->glClearColor (0.0f, 0.0f, 0.0f, 1.0f); + vtable->glClear (GL_COLOR_BUFFER_BIT); + return TRUE; +} + +static void +do_resize_window (ResizeWindowArgs * args) +{ + GstVaapiWindowEGL *const window = args->window; + EglContextState old_cs; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + if (egl_context_set_current (window->egl_window->context, TRUE, &old_cs)) { + args->success = do_resize_window_unlocked (window, args->width, + args->height); + egl_context_set_current (window->egl_window->context, FALSE, &old_cs); + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); +} + +static gboolean +gst_vaapi_window_egl_resize (GstVaapiWindowEGL * window, guint width, + guint height) +{ + const GstVaapiWindowClass *const klass = + GST_VAAPI_WINDOW_GET_CLASS (window->window); + ResizeWindowArgs args = { window, width, height }; + + g_return_val_if_fail (klass->resize, FALSE); + + if (!klass->resize (window->window, width, height)) + return FALSE; + + return egl_context_run (window->egl_window->context, + (EglContextRunFunc) do_resize_window, &args) && args.success; +} + +static gboolean +do_render_texture (GstVaapiWindowEGL * window, const GstVaapiRectangle * rect) +{ + const GLuint tex_id = GST_VAAPI_OBJECT_ID (window->texture); + EglVTable *const vtable = window->egl_vtable; + GLfloat x0, y0, x1, y1; + GLfloat texcoords[4][2]; + GLfloat positions[4][2]; + guint tex_width, tex_height; + + if (!ensure_shaders (window)) + return FALSE; + + tex_width = GST_VAAPI_TEXTURE_WIDTH (window->texture); + tex_height = GST_VAAPI_TEXTURE_HEIGHT (window->texture); + + // Source coords in VA surface + x0 = 0.0f; + y0 = 0.0f; + x1 = 1.0f; + y1 = 1.0f; + texcoords[0][0] = x0; + texcoords[0][1] = y1; + texcoords[1][0] = x1; + texcoords[1][1] = y1; + texcoords[2][0] = x1; + texcoords[2][1] = y0; + texcoords[3][0] = x0; + texcoords[3][1] = y0; + + // Target coords in EGL surface + x0 = 2.0f * ((GLfloat) rect->x / tex_width) - 1.0f; + y1 = -2.0f * ((GLfloat) rect->y / tex_height) + 1.0f; + x1 = 2.0f * ((GLfloat) (rect->x + rect->width) / tex_width) - 1.0f; + y0 = -2.0f * ((GLfloat) (rect->y + rect->height) / tex_height) + 1.0f; + positions[0][0] = x0; + positions[0][1] = y0; + positions[1][0] = x1; + positions[1][1] = y0; + positions[2][0] = x1; + positions[2][1] = y1; + positions[3][0] = x0; + positions[3][1] = y1; + + vtable->glClear (GL_COLOR_BUFFER_BIT); + + if (G_UNLIKELY (window->egl_window->context->config->gles_version == 1)) { + vtable->glBindTexture (GST_VAAPI_TEXTURE_TARGET (window->texture), tex_id); + vtable->glEnableClientState (GL_VERTEX_ARRAY); + vtable->glVertexPointer (2, GL_FLOAT, 0, positions); + vtable->glEnableClientState (GL_TEXTURE_COORD_ARRAY); + vtable->glTexCoordPointer (2, GL_FLOAT, 0, texcoords); + + vtable->glDrawArrays (GL_TRIANGLE_FAN, 0, 4); + + vtable->glDisableClientState (GL_VERTEX_ARRAY); + vtable->glDisableClientState (GL_TEXTURE_COORD_ARRAY); + } else { + EglProgram *const program = window->render_program; + + vtable->glUseProgram (program->base.handle.u); + vtable->glUniformMatrix4fv (program->uniforms[RENDER_PROGRAM_VAR_PROJ], + 1, GL_FALSE, window->render_projection); + vtable->glEnableVertexAttribArray (0); + vtable->glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 0, positions); + vtable->glEnableVertexAttribArray (1); + vtable->glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, texcoords); + + vtable->glBindTexture (GST_VAAPI_TEXTURE_TARGET (window->texture), tex_id); + vtable->glUniform1i (program->uniforms[RENDER_PROGRAM_VAR_TEX0], 0); + vtable->glDrawArrays (GL_TRIANGLE_FAN, 0, 4); + + vtable->glDisableVertexAttribArray (1); + vtable->glDisableVertexAttribArray (0); + vtable->glUseProgram (0); + } + + eglSwapBuffers (window->egl_window->context->display->base.handle.p, + window->egl_window->base.handle.p); + return TRUE; +} + +static gboolean +do_upload_surface_unlocked (GstVaapiWindowEGL * window, + GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags) +{ + if (!ensure_texture (window, dst_rect->width, dst_rect->height)) + return FALSE; + if (!gst_vaapi_texture_put_surface (window->texture, surface, src_rect, + flags)) + return FALSE; + if (!do_render_texture (window, dst_rect)) + return FALSE; + return TRUE; +} + +static void +do_upload_surface (UploadSurfaceArgs * args) +{ + GstVaapiWindowEGL *const window = args->window; + EglContextState old_cs; + + args->success = FALSE; + + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + if (egl_context_set_current (window->egl_window->context, TRUE, &old_cs)) { + args->success = do_upload_surface_unlocked (window, args->surface, + args->src_rect, args->dst_rect, args->flags); + egl_context_set_current (window->egl_window->context, FALSE, &old_cs); + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); +} + +static gboolean +gst_vaapi_window_egl_render (GstVaapiWindowEGL * window, + GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags) +{ + UploadSurfaceArgs args = { window, surface, src_rect, dst_rect, flags }; + + return egl_context_run (window->egl_window->context, + (EglContextRunFunc) do_upload_surface, &args) && args.success; +} + +static gboolean +gst_vaapi_window_egl_render_pixmap (GstVaapiWindowEGL * window, + GstVaapiPixmap * pixmap, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) +{ + const GstVaapiWindowClass *const klass = + GST_VAAPI_WINDOW_GET_CLASS (window->window); + + if (!klass->render_pixmap) + return FALSE; + return klass->render_pixmap (window->window, pixmap, src_rect, dst_rect); +} + +void +gst_vaapi_window_egl_class_init (GstVaapiWindowEGLClass * klass) +{ + GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); + GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); + + object_class->finalize = (GstVaapiObjectFinalizeFunc) + gst_vaapi_window_egl_destroy; + + window_class->create = (GstVaapiWindowCreateFunc) + gst_vaapi_window_egl_create; + window_class->show = (GstVaapiWindowShowFunc) + gst_vaapi_window_egl_show; + window_class->hide = (GstVaapiWindowHideFunc) + gst_vaapi_window_egl_hide; + window_class->get_geometry = (GstVaapiWindowGetGeometryFunc) + gst_vaapi_window_egl_get_geometry; + window_class->set_fullscreen = (GstVaapiWindowSetFullscreenFunc) + gst_vaapi_window_egl_set_fullscreen; + window_class->resize = (GstVaapiWindowResizeFunc) + gst_vaapi_window_egl_resize; + window_class->render = (GstVaapiWindowRenderFunc) + gst_vaapi_window_egl_render; + window_class->render_pixmap = (GstVaapiWindowRenderPixmapFunc) + gst_vaapi_window_egl_render_pixmap; +} + +#define gst_vaapi_window_egl_finalize \ + gst_vaapi_window_egl_destroy + +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowEGL, + gst_vaapi_window_egl, gst_vaapi_window_egl_class_init (&g_class)); + +/** + * gst_vaapi_window_egl_new: + * @display: a #GstVaapiDisplay + * @width: the requested window width, in pixels + * @height: the requested windo height, in pixels + * + * Creates a window with the specified @width and @height. The window + * will be attached to the @display and remains invisible to the user + * until gst_vaapi_window_show() is called. + * + * Return value: the newly allocated #GstVaapiWindow object + */ +GstVaapiWindow * +gst_vaapi_window_egl_new (GstVaapiDisplay * display, guint width, guint height) +{ + GST_DEBUG ("new window, size %ux%u", width, height); + + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL); + + return + gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS + (gst_vaapi_window_egl_class ()), display, GST_VAAPI_ID_INVALID, width, + height); +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_egl.h b/gst-libs/gst/vaapi/gstvaapiwindow_egl.h new file mode 100644 index 0000000000..b2ffa2de1b --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_egl.h @@ -0,0 +1,39 @@ +/* + * gstvaapiwindow_egl.h - VA/EGL window abstraction + * + * Copyright (C) 2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_WINDOW_EGL_H +#define GST_VAAPI_WINDOW_EGL_H + +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_WINDOW_EGL(obj) \ + ((GstVaapiWindowEGL *)(obj)) + +GstVaapiWindow * +gst_vaapi_window_egl_new (GstVaapiDisplay * display, guint width, guint height); + +G_END_DECLS + +#endif /* GST_VAAPI_WINDOW_EGL_H */ From 8d4498f9fdd7d901f0292546e638384286ee02cd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 1 Dec 2014 14:52:39 +0100 Subject: [PATCH 1895/3781] egl: update tests. Add initial support for EGL to tests. The new EGL backend can be selected through the --egl command line option. The OpenGL|ES version can further be selected with the --gles-version command line option, where the default of 0 means "desktop" OpenGL. --- tests/Makefile.am | 8 ++++++++ tests/output.c | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index ec6863a6f0..80826d1a90 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -52,6 +52,14 @@ TEST_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la endif +if USE_EGL +TEST_CFLAGS += $(EGL_CFLAGS) +TEST_LIBS += \ + $(LIBVA_EGL_LIBS) \ + $(EGL_LIBS) \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl-$(GST_API_VERSION).la +endif + if USE_WAYLAND TEST_CFLAGS += $(WAYLAND_CFLAGS) TEST_LIBS += \ diff --git a/tests/output.c b/tests/output.c index d5396a7d34..579e885068 100644 --- a/tests/output.c +++ b/tests/output.c @@ -36,6 +36,10 @@ # include # include #endif +#if USE_EGL +# include +# include +#endif #if USE_WAYLAND # include # include @@ -78,6 +82,9 @@ static gchar *g_output_name; static gboolean g_list_outputs = FALSE; static gboolean g_fullscreen = FALSE; +static gboolean g_egl_mode = FALSE; +static guint g_gles_version; + static GOptionEntry g_options[] = { { "list-outputs", 0, 0, @@ -91,6 +98,14 @@ static GOptionEntry g_options[] = { 0, G_OPTION_ARG_NONE, &g_fullscreen, "fullscreen mode", NULL }, + { "egl", 0, + 0, + G_OPTION_ARG_NONE, &g_egl_mode, + "enable EGL rendering", NULL }, + { "gles-version", 0, + 0, + G_OPTION_ARG_INT, &g_gles_version, + "OpenGL|ES version (in --egl mode)", NULL }, { NULL, } }; @@ -160,7 +175,7 @@ GstVaapiDisplay * video_output_create_display(const gchar *display_name) { const VideoOutputInfo *o = g_video_output; - GstVaapiDisplay *display = NULL; + GstVaapiDisplay *egl_display, *display = NULL; if (!o) { if (g_output_name) @@ -184,6 +199,19 @@ video_output_create_display(const gchar *display_name) if (!display) display = o->create_display(display_name); + + if (g_egl_mode) { +#if USE_EGL + egl_display = gst_vaapi_display_egl_new (display, g_gles_version); +#else + egl_display = NULL; + g_print("error: unsupported EGL renderering mode\n"); +#endif + gst_vaapi_display_unref (display); + if (!egl_display) + return NULL; + display = egl_display; + } return display; } @@ -195,7 +223,12 @@ video_output_create_window(GstVaapiDisplay *display, guint width, guint height) if (!g_video_output) return NULL; - window = g_video_output->create_window(display, width, height); +#if USE_EGL + if (g_egl_mode) + window = gst_vaapi_window_egl_new(display, width, height); + else +#endif + window = g_video_output->create_window(display, width, height); if (!window) return NULL; From d9c082168b64ea7175dd2b469e1955d2d79e39e3 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 3 Dec 2014 14:14:30 +0100 Subject: [PATCH 1896/3781] plugins: record downstream GstGLContext. Record GL context supplied by downstream elements. This can be useful, and further needed, to enforce run-time check that the GL context is compatible for use by libgstvaapi. e.g. check that we don't create a VA/GLX display for EGL/X11 contexts. https://bugzilla.gnome.org/show_bug.cgi?id=725643 Original-path-by: Matthew Waters --- configure.ac | 32 +++++++++++++++++++++++++ gst/vaapi/Makefile.am | 5 ++++ gst/vaapi/gstvaapipluginbase.c | 43 +++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapipluginbase.h | 11 +++++++++ 4 files changed, 90 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index e728459583..0f32826ff9 100644 --- a/configure.ac +++ b/configure.ac @@ -503,6 +503,38 @@ dnl ... video parsers AM_CONDITIONAL([USE_LOCAL_VIDEO_PARSERS], [test "$enable_builtin_videoparsers" = "yes"]) +dnl ... opengl helper libraries +HAVE_GSTGL=0 +if test "$enable_glx" = "yes" -o "$enable_egl" = "yes"; then + PKG_CHECK_MODULES([GST_GL], + [gstreamer-gl-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED], + [HAVE_GSTGL=1], [HAVE_GSTGL=0]) +fi + +if test $HAVE_GSTGL -eq 1; then + AC_CACHE_CHECK([for GStreamer OpenGL helper libraries], + [ac_cv_have_gst_gl_helpers], [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_GL_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$saved_LIBS" + AC_CHECK_HEADERS([gst/gl/gl.h], [:], [HAVE_GSTGL=0]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[GstGLContext gl_context;]])], + [ac_cv_have_gst_gl_helpers="yes"], + [ac_cv_have_gst_gl_helpers="no" HAVE_GSTGL=0] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" + ]) +fi +AM_CONDITIONAL([USE_GST_GL_HELPERS], [test $HAVE_GSTGL -eq 1]) + +AC_DEFINE_UNQUOTED([USE_GST_GL_HELPERS], [$HAVE_GSTGL], + [Defined to 1 if GStreamer OpenGL helper libraries are available]) + case $GST_API_VERSION in 0.10) lt_bias=gst0_vaapi_lt_current_bias;; 1.0) lt_bias=gst1_vaapi_lt_current_bias;; diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 6a49fdf0f8..8d4b2f1b8e 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -35,6 +35,11 @@ libgstvaapi_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-$(GST_API_VERSION).la endif +if USE_GST_GL_HELPERS +libgstvaapi_CFLAGS += $(GST_GL_CFLAGS) +libgstvaapi_LIBS += $(GST_GL_LIBS) +endif + libgstvaapi_source_c = \ gstvaapi.c \ gstvaapidecode.c \ diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 691d02786b..22300e6550 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -295,6 +295,7 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) { g_clear_object (&plugin->uploader); gst_vaapi_display_replace (&plugin->display, NULL); + gst_object_replace (&plugin->gl_context, NULL); gst_caps_replace (&plugin->sinkpad_caps, NULL); plugin->sinkpad_caps_changed = FALSE; @@ -629,12 +630,17 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gboolean has_video_alignment = FALSE; #if GST_CHECK_VERSION(1,1,0) && USE_GLX gboolean has_texture_upload_meta = FALSE; + guint idx; #endif g_return_val_if_fail (plugin->display != NULL, FALSE); gst_query_parse_allocation (query, &caps, &need_pool); + /* We don't need any GL context beyond this point if not requested + so explicitly through GstVideoGLTextureUploadMeta */ + gst_object_replace (&plugin->gl_context, NULL); + if (!caps) goto error_no_caps; @@ -648,7 +654,23 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, #if GST_CHECK_VERSION(1,1,0) && USE_GLX has_texture_upload_meta = gst_query_find_allocation_meta (query, - GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx); + +#if USE_GST_GL_HELPERS + if (has_texture_upload_meta) { + const GstStructure *params; + GstObject *gl_context; + + gst_query_parse_nth_allocation_meta (query, idx, ¶ms); + if (params) { + if (gst_structure_get (params, "gst.gl.GstGLContext", GST_GL_TYPE_CONTEXT, + &gl_context, NULL) && gl_context) { + gst_vaapi_plugin_base_set_gl_context (plugin, gl_context); + gst_object_unref (gl_context); + } + } + } +#endif #endif gst_video_info_init (&vi); @@ -936,3 +958,22 @@ error_copy_buffer: return GST_FLOW_NOT_SUPPORTED; } } + +/** + * gst_vaapi_plugin_base_set_gl_context: + * @plugin: a #GstVaapiPluginBase + * @object: the new GL context from downstream + * + * Registers the new GL context. The change is effective at the next + * call to gst_vaapi_plugin_base_ensure_display(), where the + * underlying display object could be re-allocated to fit the GL + * context needs + */ +void +gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, + GstObject * object) +{ +#if USE_GST_GL_HELPERS + gst_object_replace (&plugin->gl_context, object); +#endif +} diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index e7426cba20..717716a19b 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -32,6 +32,10 @@ #include #include "gstvaapiuploader.h" +#ifdef HAVE_GST_GL_GL_H +# include +#endif + G_BEGIN_DECLS typedef struct _GstVaapiPluginBase GstVaapiPluginBase; @@ -145,6 +149,8 @@ struct _GstVaapiPluginBase GstVaapiDisplayType display_type_req; gchar *display_name; + GstObject *gl_context; + GstVaapiUploader *uploader; gboolean uploader_used; }; @@ -233,6 +239,11 @@ GstFlowReturn gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, GstBuffer * inbuf, GstBuffer ** outbuf_ptr); +G_GNUC_INTERNAL +void +gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, + GstObject * object); + G_END_DECLS #endif /* GST_VAAPI_PLUGIN_BASE_H */ From 9aa5eac5e3e2636f08a85a7d4f850f5b9dff8c7b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 3 Dec 2014 15:45:52 +0100 Subject: [PATCH 1897/3781] plugins: ensure VA display matches GL context expectations. If a GstGLContext is supplied by the downstream element, then make sure that the VA plugin element gets a compatible display to what is requested by the GL context. e.g. re-allocate a VA/GLX display when a GLX context is provided by the downstream element. --- gst/vaapi/gstvaapipluginbase.c | 60 ++++++++++++++++++++++++++++++++-- gst/vaapi/gstvaapipluginbase.h | 5 +++ gst/vaapi/gstvaapipluginutil.c | 3 +- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 22300e6550..c4adb8bb36 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -313,6 +313,35 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) gst_video_info_init (&plugin->srcpad_info); } +/** + * gst_vaapi_plugin_base_has_display_type: + * @plugin: a #GstVaapiPluginBase + * @display_type_req: the desired #GstVaapiDisplayType + * + * Checks whether the @plugin elements already has a #GstVaapiDisplay + * instance compatible with type @display_type_req. + * + * Return value: %TRUE if @plugin has a compatible display, %FALSE otherwise + */ +gboolean +gst_vaapi_plugin_base_has_display_type (GstVaapiPluginBase * plugin, + GstVaapiDisplayType display_type_req) +{ + GstVaapiDisplayType display_type; + + if (!plugin->display) + return FALSE; + + display_type = plugin->display_type; + if (gst_vaapi_display_type_is_compatible (display_type, display_type_req)) + return TRUE; + + display_type = gst_vaapi_display_get_class_type (plugin->display); + if (gst_vaapi_display_type_is_compatible (display_type, display_type_req)) + return TRUE; + return FALSE; +} + /** * gst_vaapi_plugin_base_set_display_type: * @plugin: a #GstVaapiPluginBase @@ -357,9 +386,7 @@ gst_vaapi_plugin_base_set_display_name (GstVaapiPluginBase * plugin, gboolean gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) { - if (plugin->display - && gst_vaapi_display_type_is_compatible (plugin->display_type, - plugin->display_type_req)) + if (gst_vaapi_plugin_base_has_display_type (plugin, plugin->display_type_req)) return TRUE; gst_vaapi_display_replace (&plugin->display, NULL); @@ -673,6 +700,12 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, #endif #endif + /* Make sure the display we pass down to the buffer pool is actually + the expected one, especially when the downstream element requires + a GLX or EGL display */ + if (!gst_vaapi_plugin_base_ensure_display (plugin)) + goto error_ensure_display; + gst_video_info_init (&vi); gst_video_info_from_caps (&vi, caps); if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) @@ -757,6 +790,12 @@ error_no_caps: GST_ERROR_OBJECT (plugin, "no caps specified"); return FALSE; } +error_ensure_display: + { + GST_ERROR_OBJECT (plugin, "failed to ensure display of type %d", + plugin->display_type_req); + return FALSE; + } error_create_pool: { GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); @@ -974,6 +1013,21 @@ gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, GstObject * object) { #if USE_GST_GL_HELPERS + GstGLContext *const gl_context = GST_GL_CONTEXT (object); + GstVaapiDisplayType display_type; + gst_object_replace (&plugin->gl_context, object); + + switch (gst_gl_context_get_gl_platform (gl_context)) { +#if USE_GLX + case GST_GL_PLATFORM_GLX: + display_type = GST_VAAPI_DISPLAY_TYPE_GLX; + break; +#endif + default: + display_type = plugin->display_type; + break; + } + gst_vaapi_plugin_base_set_display_type (plugin, display_type); #endif } diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 717716a19b..d444c6a745 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -196,6 +196,11 @@ G_GNUC_INTERNAL void gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_has_display_type (GstVaapiPluginBase * plugin, + GstVaapiDisplayType display_type_req); + G_GNUC_INTERNAL void gst_vaapi_plugin_base_set_display_type (GstVaapiPluginBase * plugin, diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index d3b2058570..72f2382977 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -122,8 +122,7 @@ gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type) gst_vaapi_video_context_prepare (context, display_types); /* Neighbour found and it updated the display */ - if (plugin->display - && gst_vaapi_display_type_is_compatible (plugin->display_type, type)) + if (gst_vaapi_plugin_base_has_display_type (plugin, type)) return TRUE; /* If no neighboor, or application not interested, use system default */ From 44013fdaf013b56dc2de076190ddbf9ade969fa5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 9 Dec 2014 11:46:58 +0100 Subject: [PATCH 1898/3781] plugins: track video texture size changes. Sync video texture sizes to GstVideoGLTextureUploadMeta private date, i.e. GstVaapiVideoMetaTexture, on a regular basis. In particular, we now update the texture size from the GstVideoMeta, if any, or reset to some defaults otherwise. --- gst/vaapi/gstvaapivideometa_texture.c | 64 ++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 7a4efdfd5f..190685e50f 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -33,6 +33,8 @@ #include #endif +#define DEFAULT_FORMAT GST_VIDEO_FORMAT_RGBA + #if GST_CHECK_VERSION(1,1,0) && USE_GLX #include "gstvaapivideometa_texture.h" @@ -40,8 +42,48 @@ struct _GstVaapiVideoMetaTexture { GstVaapiTexture *texture; + GstVideoGLTextureType texture_type; + guint gl_format; + guint width; + guint height; }; +static gboolean +meta_texture_ensure_format (GstVaapiVideoMetaTexture * meta, + GstVideoFormat format) +{ + switch (format) { + case GST_VIDEO_FORMAT_RGBA: + meta->gl_format = GL_RGBA; + meta->texture_type = GST_VIDEO_GL_TEXTURE_TYPE_RGBA; + break; + default: + goto error_unsupported_format; + } + return TRUE; + + /* ERRORS */ +error_unsupported_format: + GST_ERROR ("unsupported texture format %s", + gst_video_format_to_string (format)); + return FALSE; +} + +static void +meta_texture_ensure_size_from_buffer (GstVaapiVideoMetaTexture * meta, + GstBuffer * buffer) +{ + GstVideoMeta *vmeta; + + if (!buffer || !(vmeta = gst_buffer_get_video_meta (buffer))) { + meta->width = 0; + meta->height = 0; + } else { + meta->width = vmeta->width; + meta->height = vmeta->height; + } +} + static void meta_texture_free (GstVaapiVideoMetaTexture * meta) { @@ -62,6 +104,8 @@ meta_texture_new (void) return NULL; meta->texture = NULL; + meta_texture_ensure_format (meta, DEFAULT_FORMAT); + meta_texture_ensure_size_from_buffer (meta, NULL); return meta; } @@ -74,6 +118,10 @@ meta_texture_copy (GstVaapiVideoMetaTexture * meta) if (!copy) return NULL; + copy->texture_type = meta->texture_type; + copy->gl_format = meta->gl_format; + copy->width = meta->width; + copy->height = meta->height; gst_vaapi_texture_replace (©->texture, meta->texture); return copy; } @@ -101,7 +149,7 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, /* FIXME: should we assume target? */ GstVaapiTexture *const texture = gst_vaapi_texture_glx_new_wrapped (dpy, texture_id[0], - GL_TEXTURE_2D, GL_RGBA); + GL_TEXTURE_2D, meta_texture->gl_format); gst_vaapi_texture_replace (&meta_texture->texture, texture); if (!texture) return FALSE; @@ -116,7 +164,6 @@ gboolean gst_buffer_add_texture_upload_meta (GstBuffer * buffer) { GstVideoGLTextureUploadMeta *meta = NULL; - GstVideoGLTextureType tex_type[] = { GST_VIDEO_GL_TEXTURE_TYPE_RGBA }; GstVaapiVideoMetaTexture *meta_texture; if (!buffer) @@ -126,9 +173,10 @@ gst_buffer_add_texture_upload_meta (GstBuffer * buffer) if (!meta_texture) return FALSE; + meta_texture_ensure_size_from_buffer (meta_texture, buffer); meta = gst_buffer_add_video_gl_texture_upload_meta (buffer, GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, - 1, tex_type, gst_vaapi_texture_upload, + 1, &meta_texture->texture_type, gst_vaapi_texture_upload, meta_texture, (GBoxedCopyFunc) meta_texture_copy, (GBoxedFreeFunc) meta_texture_free); if (!meta) @@ -143,7 +191,13 @@ error: gboolean gst_buffer_ensure_texture_upload_meta (GstBuffer * buffer) { - return gst_buffer_get_video_gl_texture_upload_meta (buffer) || - gst_buffer_add_texture_upload_meta (buffer); + GstVideoGLTextureUploadMeta *const meta = + gst_buffer_get_video_gl_texture_upload_meta (buffer); + + if (meta) { + meta_texture_ensure_size_from_buffer (meta->user_data, buffer); + return TRUE; + } + return gst_buffer_add_texture_upload_meta (buffer); } #endif From 60e96e80cc0b10ad0b70e25ffae9b75eb9be2390 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Feb 2015 15:29:17 +0100 Subject: [PATCH 1899/3781] plugins: add initial support for EGL. Add initial support for EGL through GstVideoGLTextureUploadMeta. Fix gst_vaapi_ensure_display() to allocate a GstVaapiDisplay off the downstream supplied GstGLContext configuration, i.e. use its native display handle to create a GstVaapiDisplay of type X11 or Wayland ; and use the desired OpenGL API to allocate the GstVaapiDisplayEGL wrapper. https://bugzilla.gnome.org/show_bug.cgi?id=741079 --- configure.ac | 5 + gst/vaapi/Makefile.am | 17 +++- gst/vaapi/gstvaapidecode.c | 6 +- gst/vaapi/gstvaapipluginbase.c | 13 ++- gst/vaapi/gstvaapipluginutil.c | 130 ++++++++++++++++++++++++-- gst/vaapi/gstvaapivideobufferpool.c | 4 +- gst/vaapi/gstvaapivideometa_texture.c | 13 ++- 7 files changed, 161 insertions(+), 27 deletions(-) diff --git a/configure.ac b/configure.ac index 0f32826ff9..529d0f8764 100644 --- a/configure.ac +++ b/configure.ac @@ -535,6 +535,11 @@ AM_CONDITIONAL([USE_GST_GL_HELPERS], [test $HAVE_GSTGL -eq 1]) AC_DEFINE_UNQUOTED([USE_GST_GL_HELPERS], [$HAVE_GSTGL], [Defined to 1 if GStreamer OpenGL helper libraries are available]) +if test "$enable_egl" = "yes" -a $HAVE_GSTGL -ne 1; then + AC_MSG_WARN([GStreamer/GL helper libraries not found, disabling EGL support]) + enable_egl="no" +fi + case $GST_API_VERSION in 0.10) lt_bias=gst0_vaapi_lt_current_bias;; 1.0) lt_bias=gst1_vaapi_lt_current_bias;; diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 8d4b2f1b8e..d2ff9455b3 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -26,6 +26,11 @@ libgstvaapi_LIBS += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la endif +if USE_EGL +libgstvaapi_LIBS += \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl-$(GST_API_VERSION).la +endif + if USE_WAYLAND libgstvaapi_CFLAGS += \ $(WAYLAND_CFLAGS) \ @@ -116,6 +121,14 @@ libgstvaapi_source_h += $(libgstvaapi_glx_source_h) endif endif +libgstvaapi_egl_source_c = +libgstvaapi_egl_source_h = + +if USE_EGL +libgstvaapi_source_c += $(libgstvaapi_egl_source_c) +libgstvaapi_source_h += $(libgstvaapi_egl_source_h) +endif + libgstvaapi_1_2p_source_c = \ gstvaapivideometa_texture.c \ $(NULL) @@ -256,7 +269,7 @@ CLEANFILES = \ EXTRA_DIST = \ $(libgstvaapi_enc_source_c) \ $(libgstvaapi_enc_source_h) \ - $(libgstvaapi_jpegenc_source_c) \ + $(libgstvaapi_jpegenc_source_c) \ $(libgstvaapi_jpegenc_source_h) \ $(libgstvaapi_vp8enc_source_c) \ $(libgstvaapi_vp8enc_source_h) \ @@ -264,6 +277,8 @@ EXTRA_DIST = \ $(libgstvaapi_x11_source_h) \ $(libgstvaapi_glx_source_c) \ $(libgstvaapi_glx_source_h) \ + $(libgstvaapi_egl_source_c) \ + $(libgstvaapi_egl_source_h) \ $(libgstvaapi_1_2p_source_c) \ $(libgstvaapi_1_2p_source_h) \ $(libgstvaapi_1_0p_source_c) \ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3841ae166c..f42e6f8367 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -36,7 +36,7 @@ #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" #include "gstvaapivideobuffer.h" -#if GST_CHECK_VERSION(1,1,0) && USE_GLX +#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) #include "gstvaapivideometa_texture.h" #endif #if GST_CHECK_VERSION(1,0,0) @@ -342,7 +342,7 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec, } } -#if GST_CHECK_VERSION(1,1,0) && USE_GLX +#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) if (decode->has_texture_upload_meta) gst_buffer_ensure_texture_upload_meta(out_frame->output_buffer); #endif @@ -528,7 +528,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gst_query_parse_allocation(query, &caps, &need_pool); decode->has_texture_upload_meta = FALSE; -#if GST_CHECK_VERSION(1,1,0) && USE_GLX +#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) decode->has_texture_upload_meta = gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec), GST_VIDEO_FORMAT_ENCODED) == diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index c4adb8bb36..130ed50941 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -655,7 +655,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gboolean need_pool, update_pool; gboolean has_video_meta = FALSE; gboolean has_video_alignment = FALSE; -#if GST_CHECK_VERSION(1,1,0) && USE_GLX +#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) gboolean has_texture_upload_meta = FALSE; guint idx; #endif @@ -679,7 +679,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, has_video_meta = gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); -#if GST_CHECK_VERSION(1,1,0) && USE_GLX +#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) has_texture_upload_meta = gst_query_find_allocation_meta (query, GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx); @@ -751,7 +751,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); -#if GST_CHECK_VERSION(1,1,0) && USE_GLX +#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) if (has_texture_upload_meta) gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); @@ -765,7 +765,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, } /* GstVideoGLTextureUploadMeta (OpenGL) */ -#if GST_CHECK_VERSION(1,1,0) && USE_GLX +#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META && !has_texture_upload_meta) { config = gst_buffer_pool_get_config (pool); @@ -1023,6 +1023,11 @@ gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, case GST_GL_PLATFORM_GLX: display_type = GST_VAAPI_DISPLAY_TYPE_GLX; break; +#endif +#if USE_EGL + case GST_GL_PLATFORM_EGL: + display_type = GST_VAAPI_DISPLAY_TYPE_EGL; + break; #endif default: display_type = plugin->display_type; diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 72f2382977..c2a3daebfa 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -33,6 +33,9 @@ #if USE_GLX # include #endif +#if USE_EGL +# include +#endif #if USE_WAYLAND # include #endif @@ -58,36 +61,48 @@ static const char *display_types[] = { NULL }; +typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFunc) (const gchar *); +typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFromHandleFunc) (gpointer); + typedef struct { const gchar *type_str; GstVaapiDisplayType type; - GstVaapiDisplay *(*create_display) (const gchar *); + GstVaapiDisplayCreateFunc create_display; + GstVaapiDisplayCreateFromHandleFunc create_display_from_handle; } DisplayMap; +/* *INDENT-OFF* */ static const DisplayMap g_display_map[] = { #if USE_WAYLAND {"wayland", - GST_VAAPI_DISPLAY_TYPE_WAYLAND, - gst_vaapi_display_wayland_new}, + GST_VAAPI_DISPLAY_TYPE_WAYLAND, + gst_vaapi_display_wayland_new, + (GstVaapiDisplayCreateFromHandleFunc) + gst_vaapi_display_wayland_new_with_display}, #endif #if USE_GLX {"glx", - GST_VAAPI_DISPLAY_TYPE_GLX, - gst_vaapi_display_glx_new}, + GST_VAAPI_DISPLAY_TYPE_GLX, + gst_vaapi_display_glx_new, + (GstVaapiDisplayCreateFromHandleFunc) + gst_vaapi_display_glx_new_with_display}, #endif #if USE_X11 {"x11", - GST_VAAPI_DISPLAY_TYPE_X11, - gst_vaapi_display_x11_new}, + GST_VAAPI_DISPLAY_TYPE_X11, + gst_vaapi_display_x11_new, + (GstVaapiDisplayCreateFromHandleFunc) + gst_vaapi_display_x11_new_with_display}, #endif #if USE_DRM {"drm", - GST_VAAPI_DISPLAY_TYPE_DRM, - gst_vaapi_display_drm_new}, + GST_VAAPI_DISPLAY_TYPE_DRM, + gst_vaapi_display_drm_new}, #endif {NULL,} }; +/* *INDENT-ON* */ static GstVaapiDisplay * gst_vaapi_create_display (GstVaapiDisplayType display_type, @@ -107,6 +122,98 @@ gst_vaapi_create_display (GstVaapiDisplayType display_type, return display; } +static GstVaapiDisplay * +gst_vaapi_create_display_from_handle (GstVaapiDisplayType display_type, + gpointer handle) +{ + GstVaapiDisplay *display; + const DisplayMap *m; + + if (display_type == GST_VAAPI_DISPLAY_TYPE_ANY) + return NULL; + + for (m = g_display_map; m->type_str != NULL; m++) { + if (m->type == display_type) { + display = m->create_display_from_handle ? + m->create_display_from_handle (handle) : NULL; + return display; + } + } + return NULL; +} + +static GstVaapiDisplay * +gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) +{ +#if USE_GST_GL_HELPERS + GstGLContext *const gl_context = GST_GL_CONTEXT (gl_context_object); + GstGLDisplay *const gl_display = gst_gl_context_get_display (gl_context); + GstVaapiDisplay *display, *out_display; + GstVaapiDisplayType display_type; + + switch (gst_gl_display_get_handle_type (gl_display)) { +#if USE_X11 + case GST_GL_DISPLAY_TYPE_X11: + display_type = GST_VAAPI_DISPLAY_TYPE_X11; + break; +#endif +#if USE_WAYLAND + case GST_GL_DISPLAY_TYPE_WAYLAND: + display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; + break; +#endif + default: + display_type = GST_VAAPI_DISPLAY_TYPE_ANY; + break; + } + if (!display_type) + return NULL; + + display = gst_vaapi_create_display_from_handle (display_type, + GSIZE_TO_POINTER (gst_gl_display_get_handle (gl_display))); + if (!display) + return NULL; + + switch (gst_gl_context_get_gl_platform (gl_context)) { +#if USE_EGL + case GST_GL_PLATFORM_EGL:{ + guint gles_version; + + switch (gst_gl_context_get_gl_api (gl_context)) { + case GST_GL_API_GLES1: + gles_version = 1; + goto create_egl_display; + case GST_GL_API_GLES2: + gles_version = 2; + goto create_egl_display; + case GST_GL_API_OPENGL: + case GST_GL_API_OPENGL3: + gles_version = 0; + create_egl_display: + out_display = gst_vaapi_display_egl_new (display, gles_version); + break; + default: + out_display = NULL; + break; + } + if (!out_display) + return NULL; + gst_vaapi_display_egl_set_gl_context (GST_VAAPI_DISPLAY_EGL (out_display), + GSIZE_TO_POINTER (gst_gl_context_get_gl_context (gl_context))); + break; + } +#endif + default: + out_display = gst_vaapi_display_ref (display); + break; + } + gst_vaapi_display_unref (display); + return out_display; +#endif + GST_ERROR ("unsupported GStreamer version %s", GST_API_VERSION_S); + return NULL; +} + gboolean gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type) { @@ -126,7 +233,10 @@ gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type) return TRUE; /* If no neighboor, or application not interested, use system default */ - display = gst_vaapi_create_display (type, plugin->display_name); + if (plugin->gl_context) + display = gst_vaapi_create_display_from_gl_context (plugin->gl_context); + else + display = gst_vaapi_create_display (type, plugin->display_name); if (!display) return FALSE; diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 56295ba3b7..5aaf7eb830 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -24,7 +24,7 @@ #include "gstvaapivideobufferpool.h" #include "gstvaapivideobuffer.h" #include "gstvaapivideomemory.h" -#if GST_CHECK_VERSION(1,1,0) && USE_GLX +#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) #include "gstvaapivideometa_texture.h" #endif @@ -288,7 +288,7 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, } } -#if GST_CHECK_VERSION(1,1,0) && USE_GLX +#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) if (priv->has_texture_upload_meta) gst_buffer_add_texture_upload_meta (buffer); #endif diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 190685e50f..da5119e61d 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -25,20 +25,18 @@ */ #include "gst/vaapi/sysdeps.h" +#include "gst/vaapi/ogl_compat.h" #include "gstvaapivideometa.h" +#include "gstvaapivideometa_texture.h" #include "gstvaapipluginutil.h" #if USE_GLX -#include #include #endif #define DEFAULT_FORMAT GST_VIDEO_FORMAT_RGBA -#if GST_CHECK_VERSION(1,1,0) && USE_GLX - -#include "gstvaapivideometa_texture.h" - +#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) struct _GstVaapiVideoMetaTexture { GstVaapiTexture *texture; @@ -148,8 +146,9 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, gst_vaapi_texture_get_id (meta_texture->texture) != texture_id[0]) { /* FIXME: should we assume target? */ GstVaapiTexture *const texture = - gst_vaapi_texture_glx_new_wrapped (dpy, texture_id[0], - GL_TEXTURE_2D, meta_texture->gl_format); + gst_vaapi_texture_new_wrapped (dpy, texture_id[0], + GL_TEXTURE_2D, meta_texture->gl_format, meta_texture->width, + meta_texture->height); gst_vaapi_texture_replace (&meta_texture->texture, texture); if (!texture) return FALSE; From 7343ce41cd385483b9f6b849a6cdc598eea777f5 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 23 Jan 2015 09:31:57 +0100 Subject: [PATCH 1900/3781] plugins: fix support for Wayland/EGL running alongside X11. When multiple display servers are available, the glimagesink element (from GStreamer 1.4) may not be able to derive a global display in Wayland. Rather, a "window"-specific display is created. In this case, the GstGLDisplay handle available through GstGLContext is invalid. So, try to improve heuristics for display server characterisation in those particular situations. --- gst/vaapi/gstvaapipluginutil.c | 36 ++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index c2a3daebfa..b6abb590fa 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -148,6 +148,8 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) #if USE_GST_GL_HELPERS GstGLContext *const gl_context = GST_GL_CONTEXT (gl_context_object); GstGLDisplay *const gl_display = gst_gl_context_get_display (gl_context); + gpointer native_display = + GSIZE_TO_POINTER (gst_gl_display_get_handle (gl_display)); GstVaapiDisplay *display, *out_display; GstVaapiDisplayType display_type; @@ -162,6 +164,37 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; break; #endif + case GST_GL_DISPLAY_TYPE_ANY:{ + /* Derive from the active window */ + GstGLWindow *const gl_window = gst_gl_context_get_window (gl_context); + const gchar *const gl_window_type = g_getenv ("GST_GL_WINDOW"); + + display_type = GST_VAAPI_DISPLAY_TYPE_ANY; + if (!gl_window) + break; + native_display = GSIZE_TO_POINTER (gst_gl_window_get_display (gl_window)); + + if (gl_window_type) { +#if USE_X11 + if (!display_type && g_strcmp0 (gl_window_type, "x11") == 0) + display_type = GST_VAAPI_DISPLAY_TYPE_X11; +#endif +#if USE_WAYLAND + if (!display_type && g_strcmp0 (gl_window_type, "wayland") == 0) + display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; +#endif + } else { +#if USE_X11 + if (!display_type && GST_GL_HAVE_WINDOW_X11) + display_type = GST_VAAPI_DISPLAY_TYPE_X11; +#endif +#if USE_WAYLAND + if (!display_type && GST_GL_HAVE_WINDOW_WAYLAND) + display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; +#endif + } + break; + } default: display_type = GST_VAAPI_DISPLAY_TYPE_ANY; break; @@ -169,8 +202,7 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) if (!display_type) return NULL; - display = gst_vaapi_create_display_from_handle (display_type, - GSIZE_TO_POINTER (gst_gl_display_get_handle (gl_display))); + display = gst_vaapi_create_display_from_handle (display_type, native_display); if (!display) return NULL; From 8c93c842ef8a19e2b3c296d9e33c31c07afd6ab0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 9 Feb 2015 21:09:07 +0100 Subject: [PATCH 1901/3781] plugins: add support for BGRA textures. Some frameworks (EFL) expect BGRA textures for storage. However, adding support for that broadly into GStreamer framework implies two kinds of hacks: (i) libgstgl helpers currently do not support BGRA textures correctly, (ii) we need to better parse downstream suggested caps and intersect them with what the VA plugin elements can offer to them for GL texturing. --- gst/vaapi/gstvaapidecode.c | 15 ++++--- gst/vaapi/gstvaapipluginbase.c | 2 +- gst/vaapi/gstvaapipluginutil.c | 57 ++++++++++++++++++++++----- gst/vaapi/gstvaapipluginutil.h | 3 +- gst/vaapi/gstvaapipostproc.c | 11 +----- gst/vaapi/gstvaapivideometa_texture.c | 36 ++++++++++++----- 6 files changed, 85 insertions(+), 39 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f42e6f8367..d2213c1663 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -79,7 +79,7 @@ static const char gst_vaapidecode_src_caps_str[] = GST_VIDEO_CAPS_MAKE_WITH_FEATURES( GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") ";" GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA") ";" + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") ";" GST_VIDEO_CAPS_MAKE("{ I420, YV12, NV12 }"); #else GST_VAAPI_SURFACE_CAPS; @@ -148,7 +148,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, feature = gst_vaapi_find_preferred_caps_feature( GST_VIDEO_DECODER_SRC_PAD(vdec), - GST_VIDEO_INFO_FORMAT(&ref_state->info)); + GST_VIDEO_INFO_FORMAT(&ref_state->info), &out_format); #endif format = GST_VIDEO_INFO_FORMAT(&ref_state->info); @@ -160,9 +160,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, return FALSE; vi = &state->info; - out_format = format; - if (format == GST_VIDEO_FORMAT_ENCODED) { - out_format = GST_VIDEO_FORMAT_I420; + if (format != out_format) { gst_video_info_init(&vis); gst_video_info_set_format(&vis, out_format, GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); @@ -174,7 +172,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, vis = *vi; switch (feature) { case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: - gst_video_info_change_format(&vis, GST_VIDEO_FORMAT_RGBA, + gst_video_info_change_format(&vis, out_format, GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); features = gst_caps_features_new( GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); @@ -524,6 +522,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gboolean need_pool; GstVideoCodecState *state; GstVaapiCapsFeature feature; + GstVideoFormat out_format; gst_query_parse_allocation(query, &caps, &need_pool); @@ -531,7 +530,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) #if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) decode->has_texture_upload_meta = gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec), - GST_VIDEO_FORMAT_ENCODED) == + GST_VIDEO_FORMAT_ENCODED, &out_format) == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META; #endif @@ -543,7 +542,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) state = gst_video_decoder_get_output_state(vdec); if (!gst_caps_is_always_compatible(caps, state->caps)) { if (decode->has_texture_upload_meta) - gst_video_info_change_format(&state->info, GST_VIDEO_FORMAT_RGBA, + gst_video_info_change_format(&state->info, out_format, GST_VIDEO_INFO_WIDTH(&state->info), GST_VIDEO_INFO_HEIGHT(&state->info)); gst_vaapidecode_update_src_caps(decode, state); diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 130ed50941..718e5f3ae6 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -674,7 +674,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!feature) feature = gst_vaapi_find_preferred_caps_feature (plugin->srcpad, - GST_VIDEO_FORMAT_ENCODED); + GST_VIDEO_FORMAT_ENCODED, NULL); has_video_meta = gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index b6abb590fa..1bb7c97eb7 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -634,8 +634,20 @@ gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, return caps; } +static GstCaps * +new_gl_texture_upload_meta_caps (void) +{ +#if GST_CHECK_VERSION(1,1,0) + return gst_caps_from_string (GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }")); +#else + return gst_caps_new_empty (); +#endif +} + GstVaapiCapsFeature -gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format) +gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, + GstVideoFormat * out_format_ptr) { GstVaapiCapsFeature feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; #if GST_CHECK_VERSION(1,1,0) @@ -645,29 +657,27 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format) GstCaps *sysmem_caps = NULL; GstCaps *vaapi_caps = NULL; GstCaps *out_caps; + GstVideoFormat out_format; out_caps = gst_pad_peer_query_caps (pad, NULL); if (!out_caps) goto cleanup; - gl_texture_upload_caps = - gst_vaapi_video_format_new_template_caps_with_features - (GST_VIDEO_FORMAT_RGBA, - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META); + out_format = format == GST_VIDEO_FORMAT_ENCODED ? + GST_VIDEO_FORMAT_I420 : format; + + gl_texture_upload_caps = new_gl_texture_upload_meta_caps (); if (!gl_texture_upload_caps) goto cleanup; - if (format == GST_VIDEO_FORMAT_ENCODED) - format = GST_VIDEO_FORMAT_I420; - vaapi_caps = - gst_vaapi_video_format_new_template_caps_with_features (format, + gst_vaapi_video_format_new_template_caps_with_features (out_format, GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE); if (!vaapi_caps) goto cleanup; sysmem_caps = - gst_vaapi_video_format_new_template_caps_with_features (format, + gst_vaapi_video_format_new_template_caps_with_features (out_format, GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY); if (!sysmem_caps) goto cleanup; @@ -707,6 +717,33 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format) #endif } + if (out_format_ptr) { +#if GST_CHECK_VERSION(1,1,0) + if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) { + GstStructure *structure; + gchar *format_str; + out_format = GST_VIDEO_FORMAT_UNKNOWN; + do { + caps = gst_caps_intersect_full (out_caps, gl_texture_upload_caps, + GST_CAPS_INTERSECT_FIRST); + if (!caps) + break; + structure = gst_caps_get_structure (caps, 0); + if (!structure) + break; + if (!gst_structure_get (structure, "format", G_TYPE_STRING, + &format_str, NULL)) + break; + out_format = gst_video_format_from_string (format_str); + g_free (format_str); + } while (0); + if (!out_format) + goto cleanup; +#endif + } + *out_format_ptr = out_format; + } + cleanup: gst_caps_replace (&gl_texture_upload_caps, NULL); gst_caps_replace (&sysmem_caps, NULL); diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 0f6490ef2f..b72b01cad1 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -90,7 +90,8 @@ gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, G_GNUC_INTERNAL GstVaapiCapsFeature -gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format); +gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, + GstVideoFormat * out_format_ptr); G_GNUC_INTERNAL const gchar * diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index e701b8cdff..e5d563084a 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -77,7 +77,7 @@ static const char gst_vaapipostproc_src_caps_str[] = GST_CAPS_INTERLACED_FALSE "; " #if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA") ", " + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") ", " GST_CAPS_INTERLACED_FALSE "; " #endif #if GST_CHECK_VERSION(1,0,0) @@ -1152,14 +1152,7 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, feature = gst_vaapi_find_preferred_caps_feature (GST_BASE_TRANSFORM_SRC_PAD (trans), - out_format); - switch (feature) { - case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: - out_format = GST_VIDEO_FORMAT_RGBA; - break; - default: - break; - } + out_format, &out_format); #else out_format = GST_VIDEO_FORMAT_ENCODED; #endif diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index da5119e61d..5052145fe9 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -55,6 +55,11 @@ meta_texture_ensure_format (GstVaapiVideoMetaTexture * meta, meta->gl_format = GL_RGBA; meta->texture_type = GST_VIDEO_GL_TEXTURE_TYPE_RGBA; break; + case GST_VIDEO_FORMAT_BGRA: + meta->gl_format = GL_BGRA_EXT; + /* FIXME: add GST_VIDEO_GL_TEXTURE_TYPE_BGRA extension */ + meta->texture_type = GST_VIDEO_GL_TEXTURE_TYPE_RGBA; + break; default: goto error_unsupported_format; } @@ -67,19 +72,26 @@ error_unsupported_format: return FALSE; } -static void -meta_texture_ensure_size_from_buffer (GstVaapiVideoMetaTexture * meta, +static gboolean +meta_texture_ensure_info_from_buffer (GstVaapiVideoMetaTexture * meta, GstBuffer * buffer) { GstVideoMeta *vmeta; + GstVideoFormat format; if (!buffer || !(vmeta = gst_buffer_get_video_meta (buffer))) { + format = DEFAULT_FORMAT; meta->width = 0; meta->height = 0; } else { + const GstVideoFormatInfo *const fmt_info = + gst_video_format_get_info (vmeta->format); + format = (fmt_info && GST_VIDEO_FORMAT_INFO_IS_RGB (fmt_info)) ? + vmeta->format : DEFAULT_FORMAT; meta->width = vmeta->width; meta->height = vmeta->height; } + return meta_texture_ensure_format (meta, format); } static void @@ -102,9 +114,13 @@ meta_texture_new (void) return NULL; meta->texture = NULL; - meta_texture_ensure_format (meta, DEFAULT_FORMAT); - meta_texture_ensure_size_from_buffer (meta, NULL); + if (!meta_texture_ensure_info_from_buffer (meta, NULL)) + goto error; return meta; + +error: + meta_texture_free (meta); + return NULL; } static GstVaapiVideoMetaTexture * @@ -172,7 +188,9 @@ gst_buffer_add_texture_upload_meta (GstBuffer * buffer) if (!meta_texture) return FALSE; - meta_texture_ensure_size_from_buffer (meta_texture, buffer); + if (!meta_texture_ensure_info_from_buffer (meta_texture, buffer)) + goto error; + meta = gst_buffer_add_video_gl_texture_upload_meta (buffer, GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, 1, &meta_texture->texture_type, gst_vaapi_texture_upload, @@ -193,10 +211,8 @@ gst_buffer_ensure_texture_upload_meta (GstBuffer * buffer) GstVideoGLTextureUploadMeta *const meta = gst_buffer_get_video_gl_texture_upload_meta (buffer); - if (meta) { - meta_texture_ensure_size_from_buffer (meta->user_data, buffer); - return TRUE; - } - return gst_buffer_add_texture_upload_meta (buffer); + return meta ? + meta_texture_ensure_info_from_buffer (meta->user_data, buffer) : + gst_buffer_add_texture_upload_meta (buffer); } #endif From 6a465ae79365d4db1c2ab428b8faca601f6676a8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Feb 2015 15:13:03 +0100 Subject: [PATCH 1902/3781] plugins: add support for GstVideoGLTextureOrientation. Add support for GstVideoGLTextureOrientation modes. In particular, add orientation flags to the GstVaapiTexture wrapper and the GLX implementations. Default mode is that texture memory is laid out with top lines first, left row first. Flags indicate whether the X or Y axis need to be inverted. --- gst-libs/gst/vaapi/gstvaapitexture.c | 41 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapitexture.h | 25 ++++++++++++++ gst-libs/gst/vaapi/gstvaapitexture_glx.c | 18 +++++++--- gst-libs/gst/vaapi/gstvaapitexture_priv.h | 5 +++ gst/vaapi/gstvaapivideometa_texture.c | 27 +++++++++++++++ 5 files changed, 112 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 380c45ef20..0ff118c884 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -39,6 +39,10 @@ #undef gst_vaapi_texture_unref #undef gst_vaapi_texture_replace +#define GST_VAAPI_TEXTURE_ORIENTATION_FLAGS \ + (GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED | \ + GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED) + static void gst_vaapi_texture_init (GstVaapiTexture * texture, GstVaapiID id, guint target, guint format, guint width, guint height) @@ -297,6 +301,43 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture, *height_ptr = GST_VAAPI_TEXTURE_HEIGHT (texture); } +/** + * gst_vaapi_texture_get_orientation_flags: + * @texture: a #GstVaapiTexture + * + * Retrieves the texture memory layout flags, i.e. orientation. + * + * Return value: the #GstVaapiTextureOrientationFlags. + */ +guint +gst_vaapi_texture_get_orientation_flags (GstVaapiTexture * texture) +{ + g_return_val_if_fail (texture != NULL, 0); + + return GST_VAAPI_TEXTURE_FLAGS (texture) & + GST_VAAPI_TEXTURE_ORIENTATION_FLAGS; +} + +/** + * gst_vaapi_texture_set_orientation_flags: + * @texture: a #GstVaapiTexture + * @flags: a bitmask of #GstVaapiTextureOrientationFlags + * + * Reset the texture orientation flags to the supplied set of + * @flags. This completely replaces the previously installed + * flags. So, should they still be needed, then they shall be + * retrieved first with gst_vaapi_texture_get_orientation_flags(). + */ +void +gst_vaapi_texture_set_orientation_flags (GstVaapiTexture * texture, guint flags) +{ + g_return_if_fail (texture != NULL); + g_return_if_fail ((flags & ~GST_VAAPI_TEXTURE_ORIENTATION_FLAGS) == 0); + + GST_VAAPI_TEXTURE_FLAG_UNSET (texture, GST_VAAPI_TEXTURE_ORIENTATION_FLAGS); + GST_VAAPI_TEXTURE_FLAG_SET (texture, flags); +} + /** * gst_vaapi_texture_put_surface: * @texture: a #GstVaapiTexture diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 316d52d0b3..529ae2727e 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -80,6 +80,24 @@ G_BEGIN_DECLS typedef struct _GstVaapiTexture GstVaapiTexture; +/** + * GstVaapiTextureOrientationFlags: + * @GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED: indicates whether + * the right row comes first in memory. + * @GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED: indicates whether + * the bottom line comes first in memory. + * + * Additional flags to indicate whether the texture data is organized + * in memory with the X or Y, or both, axis inverted. e.g. if only + * @GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED is set, this means + * that the bottom line comes first in memory, with pixels laid out + * from the left to the right. + */ +typedef enum { + GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED = 1 << 31, + GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED = 1 << 30, +} GstVaapiTextureOrientationFlags; + GstVaapiTexture * gst_vaapi_texture_new (GstVaapiDisplay * display, guint target, guint format, guint width, guint height); @@ -117,6 +135,13 @@ void gst_vaapi_texture_get_size (GstVaapiTexture * texture, guint * width_ptr, guint * height_ptr); +guint +gst_vaapi_texture_get_orientation_flags (GstVaapiTexture * texture); + +void +gst_vaapi_texture_set_orientation_flags (GstVaapiTexture * texture, + guint flags); + gboolean gst_vaapi_texture_put_surface (GstVaapiTexture * texture, GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.c b/gst-libs/gst/vaapi/gstvaapitexture_glx.c index 6dbe52a403..abaac944ba 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_glx.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.c @@ -312,6 +312,12 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture, GLContextState old_cs; gboolean success = FALSE; + const GLfloat *txc, *tyc; + static const GLfloat g_texcoords[2][2] = { + {0.0f, 1.0f}, + {1.0f, 0.0f}, + }; + status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture), GST_VAAPI_OBJECT_ID (surface), texture->pixo->pixmap, crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height, @@ -339,16 +345,20 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture, goto out_unbind_fbo; } + flags = GST_VAAPI_TEXTURE_FLAGS (texture); + txc = g_texcoords[! !(flags & GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED)]; + tyc = g_texcoords[! !(flags & GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED)]; + glColor4f (1.0f, 1.0f, 1.0f, 1.0f); glBegin (GL_QUADS); { - glTexCoord2f (0.0f, 0.0f); + glTexCoord2f (txc[0], tyc[0]); glVertex2i (0, 0); - glTexCoord2f (0.0f, 1.0f); + glTexCoord2f (txc[0], tyc[1]); glVertex2i (0, base_texture->height); - glTexCoord2f (1.0f, 1.0f); + glTexCoord2f (txc[1], tyc[1]); glVertex2i (base_texture->width, base_texture->height); - glTexCoord2f (1.0f, 0.0f); + glTexCoord2f (txc[1], tyc[0]); glVertex2i (base_texture->width, 0); } glEnd (); diff --git a/gst-libs/gst/vaapi/gstvaapitexture_priv.h b/gst-libs/gst/vaapi/gstvaapitexture_priv.h index 1f69d2207e..782ae78309 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_priv.h +++ b/gst-libs/gst/vaapi/gstvaapitexture_priv.h @@ -85,6 +85,11 @@ G_BEGIN_DECLS #define GST_VAAPI_TEXTURE_HEIGHT(texture) \ (GST_VAAPI_TEXTURE (texture)->height) +#define GST_VAAPI_TEXTURE_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS +#define GST_VAAPI_TEXTURE_FLAG_IS_SET GST_VAAPI_MINI_OBJECT_FLAG_IS_SET +#define GST_VAAPI_TEXTURE_FLAG_SET GST_VAAPI_MINI_OBJECT_FLAG_SET +#define GST_VAAPI_TEXTURE_FLAG_UNSET GST_VAAPI_MINI_OBJECT_FLAG_UNSET + /* GstVaapiTextureClass hooks */ typedef gboolean (*GstVaapiTextureAllocateFunc) (GstVaapiTexture * texture); typedef gboolean (*GstVaapiTexturePutSurfaceFunc) (GstVaapiTexture * texture, diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 5052145fe9..64efdcdc62 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -46,6 +46,29 @@ struct _GstVaapiVideoMetaTexture guint height; }; +static guint +get_texture_orientation_flags (GstVideoGLTextureOrientation orientation) +{ + guint flags; + + switch (orientation) { + case GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_FLIP: + flags = GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED; + break; + case GST_VIDEO_GL_TEXTURE_ORIENTATION_X_FLIP_Y_NORMAL: + flags = GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED; + break; + case GST_VIDEO_GL_TEXTURE_ORIENTATION_X_FLIP_Y_FLIP: + flags = GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED | + GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED; + break; + default: + flags = 0; + break; + } + return flags; +} + static gboolean meta_texture_ensure_format (GstVaapiVideoMetaTexture * meta, GstVideoFormat format) @@ -170,6 +193,10 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, return FALSE; gst_vaapi_texture_unref (texture); } + + gst_vaapi_texture_set_orientation_flags (meta_texture->texture, + get_texture_orientation_flags (meta->texture_orientation)); + return gst_vaapi_texture_put_surface (meta_texture->texture, surface, gst_vaapi_surface_proxy_get_crop_rect (proxy), gst_vaapi_video_meta_get_render_flags (vmeta)); From 71d3ce4de2f32b7d454345b6ec3741dce6c33fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 23 Feb 2015 16:55:36 +0100 Subject: [PATCH 1903/3781] plugins: upload meta only if feature and allocation Working on bug #743687, I realized that vaapidecode always adds to its buffer pool the config option GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META if the decide_allocation()'s query has GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE. Nevertheless, there are occasions where the query has the API type, but the last negotiated caps don't have the feature meta:GstVideoGLTextureUploadMeta. Under this contradiction, vaapidecode adds the GLTextureUploadMeta API to its buffer pool configuration, and adds its buffer's meta to each output buffer, even if the negotiated caps feature is memory:SystemMemory with I420 color format. This kind of output buffers chokes ClutterAutoVideosSink, since it uses a map that relates caps <-> GL upload method. If it receives a buffer with color format I420, it assumes that it doesn't have a texture upload meta, because only those with RGB color format has it. Our buffers, with I420 format, say that they have the upload meta too. In that case the mapped method is a dummy one which does nothing. I reported this issue in bug #744039 (the patch, obviously, was rejected). This patch workarounds the problem: the buffer pool's configuration option GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META is set if and only if the query has the GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE *and* the negotiated caps feature is meta:GstVideoGLTextureUploadMeta. I have tested these patches with gst-master (1.5), gst-1.4 and gst-1.2 and in all they seem to work correctly. https://bugzilla.gnome.org/show_bug.cgi?id=744618 [adapted to fit current EGL changes] Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapipluginbase.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 718e5f3ae6..29fa096ec3 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -681,7 +681,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, #if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) has_texture_upload_meta = gst_query_find_allocation_meta (query, - GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx); + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx) && + (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); #if USE_GST_GL_HELPERS if (has_texture_upload_meta) { @@ -751,11 +752,6 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); -#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) - if (has_texture_upload_meta) - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); -#endif gst_buffer_pool_set_config (pool, config); } else if (has_video_alignment) { config = gst_buffer_pool_get_config (pool); @@ -766,8 +762,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, /* GstVideoGLTextureUploadMeta (OpenGL) */ #if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) - if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META - && !has_texture_upload_meta) { + if (has_texture_upload_meta) { config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); From 3f28da7f5a224178d104992fe902212015dfb2e4 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 24 Feb 2015 17:14:33 +0200 Subject: [PATCH 1904/3781] encoder: h264: add support for more than 2 views Add support for H.264 MVC Multiview High profile encoding with more than 2 views. All views within the same accesss unit are provided in increasing order of view order index (VOIdx). Upto 10 view are supported for now. A new property "view-ids" has been provided for the plugins to set the view ids (which is an array of guint values) to be used for mvc encoding. https://bugzilla.gnome.org/show_bug.cgi?id=732453 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 61 +++++++++++++++++++---- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 + 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 203177e9af..2a5a3c757d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -21,6 +21,11 @@ * Boston, MA 02110-1301 USA */ +/* GValueArray has deprecated without providing an alternative in glib >= 2.32 + * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 + */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include "sysdeps.h" #include #include @@ -37,8 +42,12 @@ #define DEBUG 1 #include "gstvaapidebug.h" + /* Define the maximum number of views supported */ -#define MAX_NUM_VIEWS 2 +#define MAX_NUM_VIEWS 10 + +/* Define the maximum value for view-id */ +#define MAX_VIEW_ID 1023 /* Define the maximum IDR period */ #define MAX_IDR_PERIOD 512 @@ -549,7 +558,7 @@ bs_write_sps (GstBitWriter * bs, static gboolean bs_write_subset_sps (GstBitWriter * bs, const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, - guint num_views, const VAEncMiscParameterHRD * hrd_params) + guint num_views, guint16 *view_ids, const VAEncMiscParameterHRD * hrd_params) { guint32 i, j, k; @@ -569,7 +578,7 @@ bs_write_subset_sps (GstBitWriter * bs, WRITE_UE (bs, num_views_minus1); for (i = 0; i <= num_views_minus1; i++) - WRITE_UE (bs, i); + WRITE_UE (bs, view_ids[i]); for (i = 1; i <= num_views_minus1; i++) { guint32 num_anchor_refs_l0 = 0; @@ -759,8 +768,9 @@ struct _GstVaapiEncoderH264 /* MVC */ gboolean is_mvc; - guint32 view_idx; + guint32 view_idx; /* View Order Index (VOIdx) */ guint32 num_views; + guint16 view_ids[MAX_NUM_VIEWS]; GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS]; GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS]; }; @@ -1311,7 +1321,7 @@ add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder, WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS); - bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views, + bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views, encoder->view_ids, &hrd_params); g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); @@ -1491,7 +1501,7 @@ add_packed_slice_header (GstVaapiEncoderH264 * encoder, /* pack nal_unit_header_mvc_extension() for the non base view */ if (encoder->is_mvc && encoder->view_idx) { bs_write_nal_header (&bs, nal_ref_idc, GST_H264_NAL_SLICE_EXT); - bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_idx); + bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_ids[encoder->view_idx]); } else bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); @@ -1760,7 +1770,7 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); pic_param->pic_parameter_set_id = encoder->view_idx; - pic_param->seq_parameter_set_id = encoder->view_idx; + pic_param->seq_parameter_set_id = encoder->view_idx ? 1 : 0; pic_param->last_picture = 0; /* means last encoding picture */ pic_param->frame_num = picture->frame_num; pic_param->pic_init_qp = encoder->init_qp; @@ -2404,9 +2414,9 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, /* encoding views alternatively for MVC */ if (encoder->is_mvc) { if (frame) - encoder->view_idx = frame->system_frame_number % MAX_NUM_VIEWS; + encoder->view_idx = frame->system_frame_number % encoder->num_views; else - encoder->view_idx = (encoder->view_idx + 1) % MAX_NUM_VIEWS; + encoder->view_idx = (encoder->view_idx + 1) % encoder->num_views; } reorder_pool = &encoder->reorder_pools[encoder->view_idx]; @@ -2584,6 +2594,7 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder) encoder->is_mvc = FALSE; encoder->num_views = 1; encoder->view_idx = 0; + memset (encoder->view_ids, 0, sizeof (encoder->view_ids)); /* re-ordering list initialize */ for (i = 0; i < MAX_NUM_VIEWS; i++) { @@ -2677,6 +2688,25 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: encoder->num_views = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS: + { + guint i; + GValueArray *view_ids = g_value_get_boxed (value); + + if (view_ids == NULL) { + for (i = 0; i < encoder->num_views; i++) + encoder->view_ids[i] = i; + } + else { + g_assert (view_ids->n_values <= encoder->num_views); + + for (i = 0; i < encoder->num_views; i++) { + GValue *val = g_value_array_get_nth (view_ids, i); + encoder->view_ids[i] = g_value_get_uint (val); + } + } + break; + } default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -2828,6 +2858,19 @@ gst_vaapi_encoder_h264_get_default_properties (void) "Number of Views", "Number of Views for MVC encoding", 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:view-ids: + * + * The view ids for MVC encoding . + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS, + g_param_spec_value_array ("view-ids", + "View IDs", "Set of View Ids used for MVC encoding", + g_param_spec_uint ("view-id-value", "View id value", + "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 77d7f0a42b..4e64d3bc64 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -47,6 +47,7 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * @GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH: Length of the CPB buffer * in milliseconds (uint). * @GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: Number of views per frame. + * @GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS: View IDs * * The set of H.264 encoder specific configurable properties. */ @@ -59,6 +60,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_DCT8X8 = -6, GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH = -7, GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS = -8, + GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS = -9 } GstVaapiEncoderH264Prop; GstVaapiEncoder * From 9799875df41c263a2614cae37cb7405a032928db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Feb 2015 12:24:55 +0200 Subject: [PATCH 1905/3781] vaapidecode: delayed src caps negotiation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the src caps are set immediately after the sink caps are set, but in that moment the pipeline might not fully constructed and the video sink has not negotiated its supported caps and features. As a consequence, in many cases of playback, the least optimized caps feature is forced. This is partially the responsible of bug #744039. Also, vaapidecode doesn't attend the reconfigure events from downstream, which is a problem too, since the video sink can be changed with different caps features. This patch delays the src caps, setting them until the first frame arrives to the decoder, assuming until that very moment the whole pipeline is already negotiated. Particularly, it checks if the src pad needs to be reconfigured, as a consequence of a reconfiguration event from downstream. A key part of this patch is the new GstVaapiCapsFeature GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED, which is returned when the src pad doesn't have a peer yet. Also, for a better report of the caps allowed through the src pad and its peer, this patch uses gst_pad_get_allowed_caps() instead of gst_pad_peer_query_caps() when looking for the preferred feature. v3: move the input_state unref to close(), since videodecoder resets at some events such as navigation. v4: a) the state_changed() callback replaces the input_state if the media changed, so this case is also handled. b) since the parameter ref_state in gst_vaapidecode_update_src_caps() is always the input_state, the parameter were removed. c) there were a lot of repeated code handling the input_state, so I refactored it with the function gst_vaapi_decode_input_state_replace(). https://bugzilla.gnome.org/show_bug.cgi?id=744618 Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapidecode.c | 103 ++++++++++++++++++++++++++------- gst/vaapi/gstvaapidecode.h | 3 + gst/vaapi/gstvaapipluginutil.c | 6 +- gst/vaapi/gstvaapipluginutil.h | 3 +- 4 files changed, 92 insertions(+), 23 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d2213c1663..8054a1b78b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -106,8 +106,11 @@ G_DEFINE_TYPE_WITH_CODE( GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) static gboolean -gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, - const GstVideoCodecState *ref_state); +gst_vaapidecode_update_src_caps(GstVaapiDecode *decode); + +static gboolean +gst_vaapi_decode_input_state_replace(GstVaapiDecode *decode, + const GstVideoCodecState *new_state); static void gst_vaapi_decoder_state_changed(GstVaapiDecoder *decoder, @@ -119,12 +122,36 @@ gst_vaapi_decoder_state_changed(GstVaapiDecoder *decoder, g_assert(decode->decoder == decoder); - if (gst_vaapidecode_update_src_caps(decode, codec_state)) { - if (!gst_video_decoder_negotiate(vdec)) - return; - if (!gst_vaapi_plugin_base_set_caps(plugin, NULL, decode->srcpad_caps)) - return; - } + if (!gst_vaapi_decode_input_state_replace(decode, codec_state)) + return; + if (!gst_vaapidecode_update_src_caps(decode)) + return; + if (!gst_video_decoder_negotiate(vdec)) + return; + if (!gst_vaapi_plugin_base_set_caps(plugin, NULL, decode->srcpad_caps)) + return; +} + +static gboolean +gst_vaapi_decode_input_state_replace(GstVaapiDecode *decode, + const GstVideoCodecState *new_state) +{ + if (decode->input_state) { + if (new_state) { + const GstCaps *curcaps = decode->input_state->caps; + if (gst_caps_is_always_compatible(curcaps, new_state->caps)) + return FALSE; + } + gst_video_codec_state_unref(decode->input_state); + } + + if (new_state) + decode->input_state = gst_video_codec_state_ref + ((GstVideoCodecState*) new_state); + else + decode->input_state = NULL; + + return TRUE; } static inline gboolean @@ -135,13 +162,18 @@ gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps) } static gboolean -gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, - const GstVideoCodecState *ref_state) +gst_vaapidecode_update_src_caps(GstVaapiDecode *decode) { GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); - GstVideoCodecState *state; + GstVideoCodecState *state, *ref_state; GstVideoInfo *vi, vis; GstVideoFormat format, out_format; + + if (!decode->input_state) + return FALSE; + + ref_state = decode->input_state; + #if GST_CHECK_VERSION(1,1,0) GstCapsFeatures *features = NULL; GstVaapiCapsFeature feature; @@ -149,6 +181,9 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, feature = gst_vaapi_find_preferred_caps_feature( GST_VIDEO_DECODER_SRC_PAD(vdec), GST_VIDEO_INFO_FORMAT(&ref_state->info), &out_format); + + if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) + return FALSE; #endif format = GST_VIDEO_INFO_FORMAT(&ref_state->info); @@ -398,14 +433,43 @@ error_commit_buffer: static GstFlowReturn gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) { + GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstFlowReturn ret; + if (!decode->input_state) + goto not_negotiated; + + if (G_UNLIKELY(!decode->active) || + gst_pad_needs_reconfigure(GST_VIDEO_DECODER_SRC_PAD(vdec))) { + GST_DEBUG_OBJECT(decode, "activating the decoder"); + if (!gst_vaapidecode_update_src_caps(decode)) + goto not_negotiated; + + if (!gst_video_decoder_negotiate(vdec)) + goto not_negotiated; + + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec); + if (!gst_vaapi_plugin_base_set_caps(plugin, NULL, decode->srcpad_caps)) + goto not_negotiated; + + decode->active = TRUE; + } + /* Make sure to release the base class stream lock so that decode loop can call gst_video_decoder_finish_frame() without blocking */ GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); ret = gst_vaapidecode_decode_frame(vdec, frame); GST_VIDEO_DECODER_STREAM_LOCK(vdec); return ret; + + /* ERRORS */ +not_negotiated: + { + GST_ERROR_OBJECT (decode, "not negotiated"); + ret = GST_FLOW_NOT_NEGOTIATED; + gst_video_decoder_drop_frame (vdec, frame); + return ret; + } } static void @@ -545,7 +609,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) gst_video_info_change_format(&state->info, out_format, GST_VIDEO_INFO_WIDTH(&state->info), GST_VIDEO_INFO_HEIGHT(&state->info)); - gst_vaapidecode_update_src_caps(decode, state); + gst_vaapidecode_update_src_caps(decode); } gst_video_codec_state_unref(state); @@ -639,6 +703,9 @@ gst_vaapidecode_destroy(GstVaapiDecode *decode) gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); gst_vaapi_decoder_replace(&decode->decoder, NULL); gst_caps_replace(&decode->decoder_caps, NULL); + + decode->active = FALSE; + gst_vaapidecode_release(decode); } @@ -728,6 +795,7 @@ gst_vaapidecode_close(GstVideoDecoder *vdec) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + gst_vaapi_decode_input_state_replace(decode, NULL); gst_vaapidecode_destroy(decode); gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(decode)); return TRUE; @@ -750,20 +818,15 @@ gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec); GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + if (!gst_vaapi_decode_input_state_replace(decode, state)) + return TRUE; if (!gst_vaapidecode_update_sink_caps(decode, state->caps)) return FALSE; if (!gst_vaapi_plugin_base_set_caps(plugin, decode->sinkpad_caps, NULL)) return FALSE; - - if (gst_vaapidecode_update_src_caps(decode, state)) { - if (!gst_video_decoder_negotiate(vdec)) - return FALSE; - if (!gst_vaapi_plugin_base_set_caps(plugin, NULL, decode->srcpad_caps)) - return FALSE; - } - if (!gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, FALSE)) return FALSE; + return TRUE; } diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 7128709deb..02f192e2ce 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -73,6 +73,9 @@ struct _GstVaapiDecode { GstCaps *allowed_caps; guint current_frame_size; guint has_texture_upload_meta : 1; + + GstVideoCodecState *input_state; + volatile gboolean active; }; struct _GstVaapiDecodeClass { diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 1bb7c97eb7..e075f836c4 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -659,9 +659,11 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, GstCaps *out_caps; GstVideoFormat out_format; - out_caps = gst_pad_peer_query_caps (pad, NULL); - if (!out_caps) + out_caps= gst_pad_get_allowed_caps (pad); + if (!out_caps) { + feature = GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED; goto cleanup; + } out_format = format == GST_VIDEO_FORMAT_ENCODED ? GST_VIDEO_FORMAT_I420 : format; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index b72b01cad1..7520cddbfd 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -70,7 +70,8 @@ gst_vaapi_value_set_format_list (GValue * value, GArray * formats); /* Helpers to build video caps */ typedef enum { - GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY = 1, + GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED, + GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY, GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META, GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE, } GstVaapiCapsFeature; From e4f8d14979c4cdf18e5af5594ee02d59f3b3250b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Feb 2015 12:26:54 +0200 Subject: [PATCH 1906/3781] vaapidecode: upload meta only if feature and allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When vaapidecode finishes the decoding of a frame and pushes it, if, in the decide_allocation() method, it is determined if the next element supports the GL texture upload meta feature, the decoder adds the buffer's meta. Nonetheless, in the same spirit of the commit 71d3ce4d, the determination if the next element supports the GL texture upload meta needs to check both the preferred caps feature *and* if the allocation query request the API type. This patch, first removes the unused variable need_pool, and determines the attribute has_texture_upload_meta using the preferred caps feature *and* the allocation query. Also, the feature passed to GstVaapPluginBase is not longer determined by has_texture_upload_meta, but by the computed preferred one. https://bugzilla.gnome.org/show_bug.cgi?id=744618 Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapidecode.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 8054a1b78b..741ff1830f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -583,25 +583,23 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstCaps *caps = NULL; - gboolean need_pool; GstVideoCodecState *state; GstVaapiCapsFeature feature; GstVideoFormat out_format; - gst_query_parse_allocation(query, &caps, &need_pool); + gst_query_parse_allocation(query, &caps, NULL); + feature = + gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec), + GST_VIDEO_FORMAT_ENCODED, &out_format); decode->has_texture_upload_meta = FALSE; #if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) decode->has_texture_upload_meta = - gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec), - GST_VIDEO_FORMAT_ENCODED, &out_format) == - GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META; + (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) && + gst_query_find_allocation_meta (query, + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); #endif - feature = decode->has_texture_upload_meta ? - GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META : - GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE; - /* Update src caps if feature is not handled downstream */ state = gst_video_decoder_get_output_state(vdec); if (!gst_caps_is_always_compatible(caps, state->caps)) { From 3d8e5e59a72aafc5d06917a3b22006278697a7d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Feb 2015 12:28:02 +0200 Subject: [PATCH 1907/3781] vaapidecode: keep src caps and output state in sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vaapidecode keeps an output state that use the format GST_VIDEO_FORMAT_ENCODED, while it crafts a different src caps for a correct negotiation. I don't see the rational behind this decoupling, it looks like unnecessary complexity. This patch simplify this logic keeping in sync the output state and the src caps. This patch improves the readability of the function gst_vaapidecode_update_src_caps() and simplify its logic. Also, the patch validates if the buffer pool has the configuration for the GL texture upload meta, in order to set the caps feature meta:GLTextureUpload. Otherwise, the I420 format is set back. https://bugzilla.gnome.org/show_bug.cgi?id=744618 Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapidecode.c | 69 ++++++++++++++------------------------ 1 file changed, 26 insertions(+), 43 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 741ff1830f..efdffffe35 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -166,8 +166,8 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode) { GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); GstVideoCodecState *state, *ref_state; - GstVideoInfo *vi, vis; - GstVideoFormat format, out_format; + GstVideoInfo *vi; + GstVideoFormat format = GST_VIDEO_FORMAT_I420; if (!decode->input_state) return FALSE; @@ -180,13 +180,31 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode) feature = gst_vaapi_find_preferred_caps_feature( GST_VIDEO_DECODER_SRC_PAD(vdec), - GST_VIDEO_INFO_FORMAT(&ref_state->info), &out_format); + GST_VIDEO_INFO_FORMAT(&ref_state->info), &format); if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) return FALSE; -#endif - format = GST_VIDEO_INFO_FORMAT(&ref_state->info); + switch (feature) { +#if (USE_GLX || USE_EGL) + case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: + if (decode->has_texture_upload_meta) + features = gst_caps_features_new( + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); + else + format = GST_VIDEO_FORMAT_I420; + break; +#endif +#if GST_CHECK_VERSION(1,5,0) + case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE: + features = gst_caps_features_new( + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL); + break; +#endif + default: + break; + } +#endif state = gst_video_decoder_set_output_state(vdec, format, ref_state->info.width, ref_state->info.height, @@ -195,40 +213,9 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode) return FALSE; vi = &state->info; - if (format != out_format) { - gst_video_info_init(&vis); - gst_video_info_set_format(&vis, out_format, - GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); - vi->size = vis.size; - } - gst_video_codec_state_unref(state); #if GST_CHECK_VERSION(1,1,0) - vis = *vi; - switch (feature) { - case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: - gst_video_info_change_format(&vis, out_format, - GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); - features = gst_caps_features_new( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); - break; - default: - if (format == GST_VIDEO_FORMAT_ENCODED) { - /* XXX: this is a workaround until auto-plugging is fixed when - format=ENCODED + memory:VASurface caps feature are provided. - Meanwhile, providing a random format here works but this is - a terribly wrong thing per se. */ - gst_video_info_change_format(&vis, out_format, - GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); -#if GST_CHECK_VERSION(1,5,0) - if (feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) - features = gst_caps_features_new( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL); -#endif - } - break; - } - state->caps = gst_video_info_to_caps(&vis); + state->caps = gst_video_info_to_caps(vi); if (features) gst_caps_set_features(state->caps, 0, features); #else @@ -250,6 +237,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode) gst_caps_set_interlaced(state->caps, vi); #endif gst_caps_replace(&decode->srcpad_caps, state->caps); + gst_video_codec_state_unref(state); return TRUE; } @@ -602,13 +590,8 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) /* Update src caps if feature is not handled downstream */ state = gst_video_decoder_get_output_state(vdec); - if (!gst_caps_is_always_compatible(caps, state->caps)) { - if (decode->has_texture_upload_meta) - gst_video_info_change_format(&state->info, out_format, - GST_VIDEO_INFO_WIDTH(&state->info), - GST_VIDEO_INFO_HEIGHT(&state->info)); + if (!gst_caps_is_always_compatible(caps, state->caps)) gst_vaapidecode_update_src_caps(decode); - } gst_video_codec_state_unref(state); return gst_vaapi_plugin_base_decide_allocation(GST_VAAPI_PLUGIN_BASE(vdec), From 8b91ddac0b888b532101b644abb88421e7834120 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Mar 2015 11:12:53 +0100 Subject: [PATCH 1908/3781] plugins: fix allocation of DMABUF memory. The dmabuf allocator would close the DMABUF handle passed in the init function gst_dmabuf_allocator_alloc(). So, we need to dup() it so that to avoid a double close, ultimately in the underlying driver that owns the DMABUF handle. --- gst/vaapi/gstvaapivideomemory.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 96a4b1e04c..3583530696 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -21,6 +21,7 @@ */ #include "gst/vaapi/sysdeps.h" +#include #include #include #include @@ -773,6 +774,7 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta) GstVaapiSurface *surface; GstVaapiSurfaceProxy *proxy; GstVaapiBufferProxy *dmabuf_proxy; + gint dmabuf_fd; const GstVideoInfo *vip; guint flags; @@ -803,8 +805,11 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta) gst_vaapi_video_meta_set_surface_proxy (meta, proxy); gst_vaapi_surface_proxy_unref (proxy); - mem = gst_dmabuf_allocator_alloc (allocator, - gst_vaapi_buffer_proxy_get_handle (dmabuf_proxy), + dmabuf_fd = gst_vaapi_buffer_proxy_get_handle (dmabuf_proxy); + if (dmabuf_fd < 0 || (dmabuf_fd = dup (dmabuf_fd)) < 0) + goto error_create_dmabuf_handle; + + mem = gst_dmabuf_allocator_alloc (allocator, dmabuf_fd, gst_vaapi_buffer_proxy_get_size (dmabuf_proxy)); if (!mem) goto error_create_dmabuf_memory; @@ -834,6 +839,12 @@ error_create_dmabuf_proxy: gst_vaapi_surface_proxy_unref (proxy); return NULL; } +error_create_dmabuf_handle: + { + GST_ERROR ("failed to duplicate DMABUF handle"); + gst_vaapi_buffer_proxy_unref (dmabuf_proxy); + return NULL; + } error_create_dmabuf_memory: { GST_ERROR ("failed to create DMABUF memory"); From 336eddffa5aa494d2307f2d57bf1d2bfc0e8d5de Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Mar 2015 13:28:41 +0100 Subject: [PATCH 1909/3781] plugins: fix detection of upstream v4l2src element. Improve check for upstream element that requires DMABUF buffer pool, e.g. v4l2src element. In particular, make sure to traverse through any additional capsfilter for instance. Note: the traversal to the top-most upstream element could be made more generic, but we are insofar only interested in supporting pipes similar to v4l2src or v4l2src ! capsfilter, e.g. with an explicit specification for a desired video camera format, or resolution. --- gst/vaapi/gstvaapipluginbase.c | 37 +++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 29fa096ec3..a5f1ad0c32 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -433,27 +433,46 @@ has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad) gboolean is_dmabuf_capable = FALSE; gint v; - do { + gst_object_ref (pad); + + for (;;) { other_pad = gst_pad_get_peer (pad); + gst_object_unref (pad); if (!other_pad) break; element = gst_pad_get_parent_element (other_pad); - if (!element || !GST_IS_PUSH_SRC (element)) + gst_object_unref (other_pad); + if (!element) break; - element_name = gst_element_get_name (element); - if (!element_name || sscanf (element_name, "v4l2src%d", &v) != 1) + if (GST_IS_PUSH_SRC (element)) { + element_name = gst_element_get_name (element); + if (!element_name || sscanf (element_name, "v4l2src%d", &v) != 1) + break; + + v = 0; + g_object_get (element, "io-mode", &v, NULL); + is_dmabuf_capable = v == 5; /* "dmabuf-import" enum value */ + break; + } else if (GST_IS_BASE_TRANSFORM (element)) { + element_name = gst_element_get_name (element); + if (!element_name || sscanf (element_name, "capsfilter%d", &v) != 1) + break; + + pad = gst_element_get_static_pad (element, "sink"); + if (!pad) + break; + } else break; - v = 0; - g_object_get (element, "io-mode", &v, NULL); - is_dmabuf_capable = v == 5; /* "dmabuf-import" enum value */ - } while (0); + g_free (element_name); + element_name = NULL; + g_clear_object (&element); + } g_free (element_name); g_clear_object (&element); - g_clear_object (&other_pad); return is_dmabuf_capable; } From aafa59f01ed5b15bc3628772d1658c63ac87a199 Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Mon, 2 Mar 2015 14:46:38 +0200 Subject: [PATCH 1910/3781] vaapidecode: Switch back to Single thread implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because the decoder uses the thread from handle_frame() to decode a frame, the src pad task creates an unsolveable AB-BA deadlock between handle_frame() waiting for a free surface and decode_loop() pushing decoded frames out. Instead, have handle_frame() take responsibility for pushing surfaces, and remove the deadlock completely. If you need a separate thread downstream, you can insert a queue between vaapidecode and its downstream to get one. Another justification for the single thread implementation is, there are two many point of locking in gstreamer-vaapi's current implementation which can lead to deadlocks. https://bugzilla.gnome.org/show_bug.cgi?id=742605 Signed-off-by: Simon Farnsworth Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapidecode.c | 275 +++++++++++++------------------------ gst/vaapi/gstvaapidecode.h | 7 +- 2 files changed, 100 insertions(+), 182 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index efdffffe35..0ba5ee7fcf 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -244,70 +244,9 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode) static void gst_vaapidecode_release(GstVaapiDecode *decode) { - g_mutex_lock(&decode->decoder_mutex); - g_cond_signal(&decode->decoder_ready); - g_mutex_unlock(&decode->decoder_mutex); -} - -static GstFlowReturn -gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) -{ - GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - GstVaapiDecoderStatus status; - GstFlowReturn ret; - - - /* Decode current frame */ - for (;;) { - status = gst_vaapi_decoder_decode(decode->decoder, frame); - if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { - GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); - g_mutex_lock(&decode->decoder_mutex); - if (gst_vaapi_decoder_check_status (decode->decoder) == - GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) - g_cond_wait(&decode->decoder_ready, &decode->decoder_mutex); - g_mutex_unlock(&decode->decoder_mutex); - GST_VIDEO_DECODER_STREAM_LOCK(vdec); - if (decode->decoder_loop_status < 0) - goto error_decode_loop; - continue; - } - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - goto error_decode; - break; - } - - /* Try to report back early any error that occured in the decode task */ - GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); - GST_VIDEO_DECODER_STREAM_LOCK(vdec); - return decode->decoder_loop_status; - - /* ERRORS */ -error_decode_loop: - { - if (decode->decoder_loop_status != GST_FLOW_FLUSHING) - GST_ERROR("decode loop error %d", decode->decoder_loop_status); - gst_video_decoder_drop_frame(vdec, frame); - return decode->decoder_loop_status; - } -error_decode: - { - GST_ERROR("decode error %d", status); - switch (status) { - case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: - case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: - case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: - ret = GST_FLOW_NOT_SUPPORTED; - break; - default: - GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding error"), - ("Decode error %d", status)); - ret = GST_FLOW_ERROR; - break; - } - gst_video_decoder_drop_frame(vdec, frame); - return ret; - } + g_mutex_lock(&decode->surface_ready_mutex); + g_cond_signal(&decode->surface_ready); + g_mutex_unlock(&decode->surface_ready_mutex); } static GstFlowReturn @@ -418,10 +357,39 @@ error_commit_buffer: } } +static GstFlowReturn +gst_vaapidecode_push_all_decoded_frames(GstVaapiDecode *decode) +{ + GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); + GstVaapiDecoderStatus status; + GstVideoCodecFrame *out_frame; + GstFlowReturn ret; + + for (;;) { + status = gst_vaapi_decoder_get_frame(decode->decoder, &out_frame); + + switch (status) { + case GST_VAAPI_DECODER_STATUS_SUCCESS: + ret = gst_vaapidecode_push_decoded_frame(vdec, out_frame); + if (ret != GST_FLOW_OK) + return ret; + break; + case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: + return GST_FLOW_OK; + default: + GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding failed"), + ("Unknown decoding error")); + return GST_FLOW_ERROR; + } + } + g_assert_not_reached(); +} + static GstFlowReturn gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + GstVaapiDecoderStatus status; GstFlowReturn ret; if (!decode->input_state) @@ -443,67 +411,67 @@ gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) decode->active = TRUE; } - /* Make sure to release the base class stream lock so that decode - loop can call gst_video_decoder_finish_frame() without blocking */ - GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); - ret = gst_vaapidecode_decode_frame(vdec, frame); - GST_VIDEO_DECODER_STREAM_LOCK(vdec); + /* Decode current frame */ + for (;;) { + status = gst_vaapi_decoder_decode(decode->decoder, frame); + if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { + /* Make sure that there are no decoded frames waiting in the + output queue. */ + ret = gst_vaapidecode_push_all_decoded_frames(decode); + if (ret != GST_FLOW_OK) + goto error_push_all_decoded_frames; + + g_mutex_lock(&decode->surface_ready_mutex); + if (gst_vaapi_decoder_check_status (decode->decoder) == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) + g_cond_wait(&decode->surface_ready, &decode->surface_ready_mutex); + g_mutex_unlock(&decode->surface_ready_mutex); + continue; + } + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto error_decode; + break; + } + + /* Note that gst_vaapi_decoder_decode cannot return success without + completing the decode and pushing all decoded frames into the output + queue */ + ret = gst_vaapidecode_push_all_decoded_frames(decode); + if (ret != GST_FLOW_OK && ret != GST_FLOW_FLUSHING) + GST_ERROR("push loop error after decoding %d", ret); return ret; /* ERRORS */ +error_push_all_decoded_frames: + { + GST_ERROR("push loop error while decoding %d", ret); + gst_video_decoder_drop_frame(vdec, frame); + return ret; + } +error_decode: + { + GST_ERROR("decode error %d", status); + switch (status) { + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: + ret = GST_FLOW_NOT_SUPPORTED; + break; + default: + GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding error"), + ("Decode error %d", status)); + ret = GST_FLOW_ERROR; + break; + } + gst_video_decoder_drop_frame(vdec, frame); + return ret; + } not_negotiated: - { - GST_ERROR_OBJECT (decode, "not negotiated"); - ret = GST_FLOW_NOT_NEGOTIATED; - gst_video_decoder_drop_frame (vdec, frame); - return ret; - } -} - -static void -gst_vaapidecode_decode_loop(GstVaapiDecode *decode) -{ - GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); - GstVaapiDecoderStatus status; - GstVideoCodecFrame *out_frame; - GstFlowReturn ret; - - status = gst_vaapi_decoder_get_frame_with_timeout(decode->decoder, - &out_frame, 100000); - - GST_VIDEO_DECODER_STREAM_LOCK(vdec); - switch (status) { - case GST_VAAPI_DECODER_STATUS_SUCCESS: - ret = gst_vaapidecode_push_decoded_frame(vdec, out_frame); - break; - case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: - ret = GST_VIDEO_DECODER_FLOW_NEED_DATA; - break; - default: - GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding failed"), - ("Unknown decoding error")); - ret = GST_FLOW_ERROR; - break; + { + GST_ERROR_OBJECT (decode, "not negotiated"); + ret = GST_FLOW_NOT_NEGOTIATED; + gst_video_decoder_drop_frame (vdec, frame); + return ret; } - decode->decoder_loop_status = ret; - GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); - - /* If invoked from gst_vaapidecode_finish(), then return right - away no matter the errors, or the GstVaapiDecoder needs further - data to complete decoding (there no more data to feed in) */ - if (decode->decoder_finish) { - g_mutex_lock(&decode->decoder_mutex); - g_cond_signal(&decode->decoder_finish_done); - g_mutex_unlock(&decode->decoder_mutex); - return; - } - - if (ret == GST_FLOW_OK) - return; - - /* Suspend the task if an error occurred */ - if (ret != GST_VIDEO_DECODER_FLOW_NEED_DATA) - gst_pad_pause_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); } static gboolean @@ -544,25 +512,12 @@ gst_vaapidecode_finish(GstVideoDecoder *vdec) if (!decode->decoder) return GST_FLOW_OK; - if (!gst_vaapidecode_flush(vdec)) - ret = GST_FLOW_OK; - - /* Make sure the decode loop function has a chance to return, thus - possibly unlocking gst_video_decoder_finish_frame() */ - if (decode->decoder_loop_status == GST_FLOW_OK) { - decode->decoder_finish = TRUE; - GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); - g_mutex_lock(&decode->decoder_mutex); - while (decode->decoder_loop_status == GST_FLOW_OK) - g_cond_wait(&decode->decoder_finish_done, &decode->decoder_mutex); - g_mutex_unlock(&decode->decoder_mutex); - gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); - GST_VIDEO_DECODER_STREAM_LOCK(vdec); - decode->decoder_finish = FALSE; - gst_pad_start_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode), - (GstTaskFunction)gst_vaapidecode_decode_loop, decode, NULL); + if (!gst_vaapidecode_flush(vdec)) { + gst_vaapidecode_push_all_decoded_frames(decode); + return GST_FLOW_ERROR; } - return ret; + + return gst_vaapidecode_push_all_decoded_frames(decode); } #if GST_CHECK_VERSION(1,0,0) @@ -674,14 +629,12 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) gst_vaapi_decoder_state_changed, decode); decode->decoder_caps = gst_caps_ref(caps); - return gst_pad_start_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode), - (GstTaskFunction)gst_vaapidecode_decode_loop, decode, NULL); + return TRUE; } static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { - gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); gst_vaapi_decoder_replace(&decode->decoder, NULL); gst_caps_replace(&decode->decoder_caps, NULL); @@ -706,10 +659,6 @@ gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) GstVideoCodecFrame *out_frame = NULL; gst_vaapi_decoder_flush(decode->decoder); - GST_VIDEO_DECODER_STREAM_UNLOCK(vdec); - gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); - GST_VIDEO_DECODER_STREAM_LOCK(vdec); - decode->decoder_loop_status = GST_FLOW_OK; /* Purge all decoded frames as we don't need them (e.g. seek) */ while (gst_vaapi_decoder_get_frame_with_timeout(decode->decoder, @@ -741,9 +690,8 @@ gst_vaapidecode_finalize(GObject *object) gst_caps_replace(&decode->srcpad_caps, NULL); gst_caps_replace(&decode->allowed_caps, NULL); - g_cond_clear(&decode->decoder_finish_done); - g_cond_clear(&decode->decoder_ready); - g_mutex_clear(&decode->decoder_mutex); + g_cond_clear(&decode->surface_ready); + g_mutex_clear(&decode->surface_ready_mutex); gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object)); G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object); @@ -868,28 +816,6 @@ gst_vaapidecode_parse(GstVideoDecoder *vdec, return ret; } -static GstStateChangeReturn -gst_vaapidecode_change_state (GstElement * element, GstStateChange transition) -{ - GstVaapiDecode * const decode = GST_VAAPIDECODE(element); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - g_mutex_lock(&decode->decoder_mutex); - decode->decoder_finish = TRUE; - g_cond_signal(&decode->decoder_finish_done); - g_cond_signal(&decode->decoder_ready); - g_mutex_unlock(&decode->decoder_mutex); - gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode)); - decode->decoder_finish = FALSE; - break; - default: - break; - } - return GST_ELEMENT_CLASS(gst_vaapidecode_parent_class)->change_state( - element, transition); -} - static void gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) { @@ -905,9 +831,6 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) object_class->finalize = gst_vaapidecode_finalize; - element_class->change_state = - GST_DEBUG_FUNCPTR(gst_vaapidecode_change_state); - vdec_class->open = GST_DEBUG_FUNCPTR(gst_vaapidecode_open); vdec_class->close = GST_DEBUG_FUNCPTR(gst_vaapidecode_close); vdec_class->set_format = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_format); @@ -1108,11 +1031,9 @@ gst_vaapidecode_init(GstVaapiDecode *decode) decode->decoder = NULL; decode->decoder_caps = NULL; decode->allowed_caps = NULL; - decode->decoder_loop_status = GST_FLOW_OK; - g_mutex_init(&decode->decoder_mutex); - g_cond_init(&decode->decoder_ready); - g_cond_init(&decode->decoder_finish_done); + g_mutex_init(&decode->surface_ready_mutex); + g_cond_init(&decode->surface_ready); gst_video_decoder_set_packetized(vdec, FALSE); diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 02f192e2ce..48807ddaa5 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -64,11 +64,8 @@ struct _GstVaapiDecode { GstCaps *sinkpad_caps; GstCaps *srcpad_caps; GstVaapiDecoder *decoder; - GMutex decoder_mutex; - GCond decoder_ready; - GstFlowReturn decoder_loop_status; - volatile gboolean decoder_finish; - GCond decoder_finish_done; + GMutex surface_ready_mutex; + GCond surface_ready; GstCaps *decoder_caps; GstCaps *allowed_caps; guint current_frame_size; From 5425a05bd4638ed068d4f6e1a6f5e1d162a01288 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 2 Mar 2015 14:59:16 +0200 Subject: [PATCH 1911/3781] vaapidecode: re-indent (gst-indent) gstvaapidecode.c --- gst/vaapi/gstvaapidecode.c | 1345 ++++++++++++++++++------------------ 1 file changed, 671 insertions(+), 674 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 0ba5ee7fcf..9ae72a7c83 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -56,12 +56,13 @@ #define GST_VAAPI_DECODE_FLOW_PARSE_DATA GST_FLOW_CUSTOM_SUCCESS_2 -GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapidecode); +GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapidecode); #define GST_CAT_DEFAULT gst_debug_vaapidecode /* Default templates */ #define GST_CAPS_CODEC(CODEC) CODEC "; " +/* *INDENT-OFF* */ static const char gst_vaapidecode_sink_caps_str[] = GST_CAPS_CODEC("video/mpeg, mpegversion=2, systemstream=(boolean)false") GST_CAPS_CODEC("video/mpeg, mpegversion=4") @@ -104,947 +105,943 @@ G_DEFINE_TYPE_WITH_CODE( gst_vaapidecode, GST_TYPE_VIDEO_DECODER, GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) +/* *INDENT-ON* */ + +static gboolean gst_vaapidecode_update_src_caps (GstVaapiDecode * decode); static gboolean -gst_vaapidecode_update_src_caps(GstVaapiDecode *decode); - -static gboolean -gst_vaapi_decode_input_state_replace(GstVaapiDecode *decode, - const GstVideoCodecState *new_state); +gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, + const GstVideoCodecState * new_state); static void -gst_vaapi_decoder_state_changed(GstVaapiDecoder *decoder, - const GstVideoCodecState *codec_state, gpointer user_data) +gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, + const GstVideoCodecState * codec_state, gpointer user_data) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data); - GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec); + GstVaapiDecode *const decode = GST_VAAPIDECODE (user_data); + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); - g_assert(decode->decoder == decoder); + g_assert (decode->decoder == decoder); - if (!gst_vaapi_decode_input_state_replace(decode, codec_state)) - return; - if (!gst_vaapidecode_update_src_caps(decode)) - return; - if (!gst_video_decoder_negotiate(vdec)) - return; - if (!gst_vaapi_plugin_base_set_caps(plugin, NULL, decode->srcpad_caps)) - return; + if (!gst_vaapi_decode_input_state_replace (decode, codec_state)) + return; + if (!gst_vaapidecode_update_src_caps (decode)) + return; + if (!gst_video_decoder_negotiate (vdec)) + return; + if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) + return; } static gboolean -gst_vaapi_decode_input_state_replace(GstVaapiDecode *decode, - const GstVideoCodecState *new_state) +gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, + const GstVideoCodecState * new_state) { - if (decode->input_state) { - if (new_state) { - const GstCaps *curcaps = decode->input_state->caps; - if (gst_caps_is_always_compatible(curcaps, new_state->caps)) - return FALSE; - } - gst_video_codec_state_unref(decode->input_state); + if (decode->input_state) { + if (new_state) { + const GstCaps *curcaps = decode->input_state->caps; + if (gst_caps_is_always_compatible (curcaps, new_state->caps)) + return FALSE; } + gst_video_codec_state_unref (decode->input_state); + } - if (new_state) - decode->input_state = gst_video_codec_state_ref - ((GstVideoCodecState*) new_state); - else - decode->input_state = NULL; + if (new_state) + decode->input_state = gst_video_codec_state_ref + ((GstVideoCodecState *) new_state); + else + decode->input_state = NULL; - return TRUE; + return TRUE; } static inline gboolean -gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps) +gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps) { - gst_caps_replace(&decode->sinkpad_caps, caps); - return TRUE; + gst_caps_replace (&decode->sinkpad_caps, caps); + return TRUE; } static gboolean -gst_vaapidecode_update_src_caps(GstVaapiDecode *decode) +gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) { - GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); - GstVideoCodecState *state, *ref_state; - GstVideoInfo *vi; - GstVideoFormat format = GST_VIDEO_FORMAT_I420; + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); + GstVideoCodecState *state, *ref_state; + GstVideoInfo *vi; + GstVideoFormat format = GST_VIDEO_FORMAT_I420; - if (!decode->input_state) - return FALSE; + if (!decode->input_state) + return FALSE; - ref_state = decode->input_state; + ref_state = decode->input_state; #if GST_CHECK_VERSION(1,1,0) - GstCapsFeatures *features = NULL; - GstVaapiCapsFeature feature; + GstCapsFeatures *features = NULL; + GstVaapiCapsFeature feature; - feature = gst_vaapi_find_preferred_caps_feature( - GST_VIDEO_DECODER_SRC_PAD(vdec), - GST_VIDEO_INFO_FORMAT(&ref_state->info), &format); + feature = + gst_vaapi_find_preferred_caps_feature (GST_VIDEO_DECODER_SRC_PAD (vdec), + GST_VIDEO_INFO_FORMAT (&ref_state->info), &format); - if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) - return FALSE; + if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) + return FALSE; - switch (feature) { + switch (feature) { #if (USE_GLX || USE_EGL) case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: - if (decode->has_texture_upload_meta) - features = gst_caps_features_new( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); - else - format = GST_VIDEO_FORMAT_I420; - break; + if (decode->has_texture_upload_meta) + features = + gst_caps_features_new + (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); + else + format = GST_VIDEO_FORMAT_I420; + break; #endif #if GST_CHECK_VERSION(1,5,0) case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE: - features = gst_caps_features_new( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL); - break; + features = + gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL); + break; #endif default: - break; - } + break; + } #endif - state = gst_video_decoder_set_output_state(vdec, format, - ref_state->info.width, ref_state->info.height, - (GstVideoCodecState *)ref_state); - if (!state || state->info.width == 0 || state->info.height == 0) - return FALSE; + state = gst_video_decoder_set_output_state (vdec, format, + ref_state->info.width, ref_state->info.height, + (GstVideoCodecState *) ref_state); + if (!state || state->info.width == 0 || state->info.height == 0) + return FALSE; - vi = &state->info; + vi = &state->info; #if GST_CHECK_VERSION(1,1,0) - state->caps = gst_video_info_to_caps(vi); - if (features) - gst_caps_set_features(state->caps, 0, features); + state->caps = gst_video_info_to_caps (vi); + if (features) + gst_caps_set_features (state->caps, 0, features); #else - /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not - reconstruct suitable caps for "encoded" video formats */ - state->caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME); - if (!state->caps) - return FALSE; + /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not + reconstruct suitable caps for "encoded" video formats */ + state->caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS_NAME); + if (!state->caps) + return FALSE; - gst_caps_set_simple(state->caps, - "type", G_TYPE_STRING, "vaapi", - "opengl", G_TYPE_BOOLEAN, USE_GLX, - "width", G_TYPE_INT, vi->width, - "height", G_TYPE_INT, vi->height, - "framerate", GST_TYPE_FRACTION, vi->fps_n, vi->fps_d, - "pixel-aspect-ratio", GST_TYPE_FRACTION, vi->par_n, vi->par_d, - NULL); + gst_caps_set_simple (state->caps, + "type", G_TYPE_STRING, "vaapi", + "opengl", G_TYPE_BOOLEAN, USE_GLX, + "width", G_TYPE_INT, vi->width, + "height", G_TYPE_INT, vi->height, + "framerate", GST_TYPE_FRACTION, vi->fps_n, vi->fps_d, + "pixel-aspect-ratio", GST_TYPE_FRACTION, vi->par_n, vi->par_d, NULL); - gst_caps_set_interlaced(state->caps, vi); + gst_caps_set_interlaced (state->caps, vi); #endif - gst_caps_replace(&decode->srcpad_caps, state->caps); - gst_video_codec_state_unref(state); - return TRUE; + gst_caps_replace (&decode->srcpad_caps, state->caps); + gst_video_codec_state_unref (state); + return TRUE; } static void -gst_vaapidecode_release(GstVaapiDecode *decode) +gst_vaapidecode_release (GstVaapiDecode * decode) { - g_mutex_lock(&decode->surface_ready_mutex); - g_cond_signal(&decode->surface_ready); - g_mutex_unlock(&decode->surface_ready_mutex); + g_mutex_lock (&decode->surface_ready_mutex); + g_cond_signal (&decode->surface_ready); + g_mutex_unlock (&decode->surface_ready_mutex); } static GstFlowReturn -gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec, - GstVideoCodecFrame *out_frame) +gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, + GstVideoCodecFrame * out_frame) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - GstVaapiSurfaceProxy *proxy; - GstFlowReturn ret; + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstVaapiSurfaceProxy *proxy; + GstFlowReturn ret; #if GST_CHECK_VERSION(1,0,0) - const GstVaapiRectangle *crop_rect; - GstVaapiVideoMeta *meta; - guint flags; + const GstVaapiRectangle *crop_rect; + GstVaapiVideoMeta *meta; + guint flags; #endif - if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(out_frame)) { - proxy = gst_video_codec_frame_get_user_data(out_frame); + if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) { + proxy = gst_video_codec_frame_get_user_data (out_frame); - gst_vaapi_surface_proxy_set_destroy_notify(proxy, - (GDestroyNotify)gst_vaapidecode_release, decode); + gst_vaapi_surface_proxy_set_destroy_notify (proxy, + (GDestroyNotify) gst_vaapidecode_release, decode); #if GST_CHECK_VERSION(1,0,0) - ret = gst_video_decoder_allocate_output_frame(vdec, out_frame); - if (ret != GST_FLOW_OK) - goto error_create_buffer; + ret = gst_video_decoder_allocate_output_frame (vdec, out_frame); + if (ret != GST_FLOW_OK) + goto error_create_buffer; - meta = gst_buffer_get_vaapi_video_meta(out_frame->output_buffer); - if (!meta) - goto error_get_meta; - gst_vaapi_video_meta_set_surface_proxy(meta, proxy); + meta = gst_buffer_get_vaapi_video_meta (out_frame->output_buffer); + if (!meta) + goto error_get_meta; + gst_vaapi_video_meta_set_surface_proxy (meta, proxy); - flags = gst_vaapi_surface_proxy_get_flags(proxy); - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED) { - guint out_flags = GST_VIDEO_BUFFER_FLAG_INTERLACED; - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF) - out_flags |= GST_VIDEO_BUFFER_FLAG_TFF; - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF) - out_flags |= GST_VIDEO_BUFFER_FLAG_RFF; - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) - out_flags |= GST_VIDEO_BUFFER_FLAG_ONEFIELD; - GST_BUFFER_FLAG_SET(out_frame->output_buffer, out_flags); - } - - crop_rect = gst_vaapi_surface_proxy_get_crop_rect(proxy); - if (crop_rect) { - GstVideoCropMeta * const crop_meta = - gst_buffer_add_video_crop_meta(out_frame->output_buffer); - if (crop_meta) { - crop_meta->x = crop_rect->x; - crop_meta->y = crop_rect->y; - crop_meta->width = crop_rect->width; - crop_meta->height = crop_rect->height; - } - } + flags = gst_vaapi_surface_proxy_get_flags (proxy); + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED) { + guint out_flags = GST_VIDEO_BUFFER_FLAG_INTERLACED; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF) + out_flags |= GST_VIDEO_BUFFER_FLAG_TFF; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF) + out_flags |= GST_VIDEO_BUFFER_FLAG_RFF; + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) + out_flags |= GST_VIDEO_BUFFER_FLAG_ONEFIELD; + GST_BUFFER_FLAG_SET (out_frame->output_buffer, out_flags); + } + crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy); + if (crop_rect) { + GstVideoCropMeta *const crop_meta = + gst_buffer_add_video_crop_meta (out_frame->output_buffer); + if (crop_meta) { + crop_meta->x = crop_rect->x; + crop_meta->y = crop_rect->y; + crop_meta->width = crop_rect->width; + crop_meta->height = crop_rect->height; + } + } #if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) - if (decode->has_texture_upload_meta) - gst_buffer_ensure_texture_upload_meta(out_frame->output_buffer); + if (decode->has_texture_upload_meta) + gst_buffer_ensure_texture_upload_meta (out_frame->output_buffer); #endif #else - out_frame->output_buffer = - gst_vaapi_video_buffer_new_with_surface_proxy(proxy); - if (!out_frame->output_buffer) - goto error_create_buffer; + out_frame->output_buffer = + gst_vaapi_video_buffer_new_with_surface_proxy (proxy); + if (!out_frame->output_buffer) + goto error_create_buffer; #endif - } + } - ret = gst_video_decoder_finish_frame(vdec, out_frame); - if (ret != GST_FLOW_OK) - goto error_commit_buffer; + ret = gst_video_decoder_finish_frame (vdec, out_frame); + if (ret != GST_FLOW_OK) + goto error_commit_buffer; - gst_video_codec_frame_unref(out_frame); - return GST_FLOW_OK; + gst_video_codec_frame_unref (out_frame); + return GST_FLOW_OK; - /* ERRORS */ + /* ERRORS */ error_create_buffer: - { - const GstVaapiID surface_id = - gst_vaapi_surface_get_id(GST_VAAPI_SURFACE_PROXY_SURFACE(proxy)); + { + const GstVaapiID surface_id = + gst_vaapi_surface_get_id (GST_VAAPI_SURFACE_PROXY_SURFACE (proxy)); - GST_ELEMENT_ERROR(vdec, STREAM, FAILED, - ("Failed to create sink buffer"), - ("video sink failed to create video buffer for proxy'ed " - "surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(surface_id))); - gst_video_decoder_drop_frame(vdec, out_frame); - gst_video_codec_frame_unref(out_frame); - return GST_FLOW_ERROR; - } + GST_ELEMENT_ERROR (vdec, STREAM, FAILED, + ("Failed to create sink buffer"), + ("video sink failed to create video buffer for proxy'ed " + "surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id))); + gst_video_decoder_drop_frame (vdec, out_frame); + gst_video_codec_frame_unref (out_frame); + return GST_FLOW_ERROR; + } #if GST_CHECK_VERSION(1,0,0) error_get_meta: - { - GST_ELEMENT_ERROR(vdec, STREAM, FAILED, - ("Failed to get vaapi video meta attached to video buffer"), - ("Failed to get vaapi video meta attached to video buffer")); - gst_video_decoder_drop_frame(vdec, out_frame); - gst_video_codec_frame_unref(out_frame); - return GST_FLOW_ERROR; - } + { + GST_ELEMENT_ERROR (vdec, STREAM, FAILED, + ("Failed to get vaapi video meta attached to video buffer"), + ("Failed to get vaapi video meta attached to video buffer")); + gst_video_decoder_drop_frame (vdec, out_frame); + gst_video_codec_frame_unref (out_frame); + return GST_FLOW_ERROR; + } #endif error_commit_buffer: - { - if (ret != GST_FLOW_FLUSHING) - GST_ERROR("video sink rejected the video buffer (error: %s [%d])", - gst_flow_get_name (ret), ret); - gst_video_codec_frame_unref(out_frame); - return ret; - } + { + if (ret != GST_FLOW_FLUSHING) + GST_ERROR ("video sink rejected the video buffer (error: %s [%d])", + gst_flow_get_name (ret), ret); + gst_video_codec_frame_unref (out_frame); + return ret; + } } static GstFlowReturn -gst_vaapidecode_push_all_decoded_frames(GstVaapiDecode *decode) +gst_vaapidecode_push_all_decoded_frames (GstVaapiDecode * decode) { - GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); - GstVaapiDecoderStatus status; - GstVideoCodecFrame *out_frame; - GstFlowReturn ret; + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); + GstVaapiDecoderStatus status; + GstVideoCodecFrame *out_frame; + GstFlowReturn ret; - for (;;) { - status = gst_vaapi_decoder_get_frame(decode->decoder, &out_frame); + for (;;) { + status = gst_vaapi_decoder_get_frame (decode->decoder, &out_frame); - switch (status) { - case GST_VAAPI_DECODER_STATUS_SUCCESS: - ret = gst_vaapidecode_push_decoded_frame(vdec, out_frame); - if (ret != GST_FLOW_OK) - return ret; - break; - case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: - return GST_FLOW_OK; - default: - GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding failed"), - ("Unknown decoding error")); - return GST_FLOW_ERROR; - } + switch (status) { + case GST_VAAPI_DECODER_STATUS_SUCCESS: + ret = gst_vaapidecode_push_decoded_frame (vdec, out_frame); + if (ret != GST_FLOW_OK) + return ret; + break; + case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: + return GST_FLOW_OK; + default: + GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding failed"), + ("Unknown decoding error")); + return GST_FLOW_ERROR; } - g_assert_not_reached(); + } + g_assert_not_reached (); } static GstFlowReturn -gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame) +gst_vaapidecode_handle_frame (GstVideoDecoder * vdec, + GstVideoCodecFrame * frame) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - GstVaapiDecoderStatus status; - GstFlowReturn ret; + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstVaapiDecoderStatus status; + GstFlowReturn ret; - if (!decode->input_state) - goto not_negotiated; + if (!decode->input_state) + goto not_negotiated; - if (G_UNLIKELY(!decode->active) || - gst_pad_needs_reconfigure(GST_VIDEO_DECODER_SRC_PAD(vdec))) { - GST_DEBUG_OBJECT(decode, "activating the decoder"); - if (!gst_vaapidecode_update_src_caps(decode)) - goto not_negotiated; + if (G_UNLIKELY (!decode->active) || + gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec))) { + GST_DEBUG_OBJECT (decode, "activating the decoder"); + if (!gst_vaapidecode_update_src_caps (decode)) + goto not_negotiated; - if (!gst_video_decoder_negotiate(vdec)) - goto not_negotiated; + if (!gst_video_decoder_negotiate (vdec)) + goto not_negotiated; - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec); - if (!gst_vaapi_plugin_base_set_caps(plugin, NULL, decode->srcpad_caps)) - goto not_negotiated; + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); + if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) + goto not_negotiated; - decode->active = TRUE; + decode->active = TRUE; + } + + /* Decode current frame */ + for (;;) { + status = gst_vaapi_decoder_decode (decode->decoder, frame); + if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { + /* Make sure that there are no decoded frames waiting in the + output queue. */ + ret = gst_vaapidecode_push_all_decoded_frames (decode); + if (ret != GST_FLOW_OK) + goto error_push_all_decoded_frames; + + g_mutex_lock (&decode->surface_ready_mutex); + if (gst_vaapi_decoder_check_status (decode->decoder) == + GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) + g_cond_wait (&decode->surface_ready, &decode->surface_ready_mutex); + g_mutex_unlock (&decode->surface_ready_mutex); + continue; } + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto error_decode; + break; + } - /* Decode current frame */ - for (;;) { - status = gst_vaapi_decoder_decode(decode->decoder, frame); - if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { - /* Make sure that there are no decoded frames waiting in the - output queue. */ - ret = gst_vaapidecode_push_all_decoded_frames(decode); - if (ret != GST_FLOW_OK) - goto error_push_all_decoded_frames; + /* Note that gst_vaapi_decoder_decode cannot return success without + completing the decode and pushing all decoded frames into the output + queue */ + ret = gst_vaapidecode_push_all_decoded_frames (decode); + if (ret != GST_FLOW_OK && ret != GST_FLOW_FLUSHING) + GST_ERROR ("push loop error after decoding %d", ret); + return ret; - g_mutex_lock(&decode->surface_ready_mutex); - if (gst_vaapi_decoder_check_status (decode->decoder) == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) - g_cond_wait(&decode->surface_ready, &decode->surface_ready_mutex); - g_mutex_unlock(&decode->surface_ready_mutex); - continue; - } - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - goto error_decode; + /* ERRORS */ +error_push_all_decoded_frames: + { + GST_ERROR ("push loop error while decoding %d", ret); + gst_video_decoder_drop_frame (vdec, frame); + return ret; + } +error_decode: + { + GST_ERROR ("decode error %d", status); + switch (status) { + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: + case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: + ret = GST_FLOW_NOT_SUPPORTED; + break; + default: + GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding error"), + ("Decode error %d", status)); + ret = GST_FLOW_ERROR; break; } - - /* Note that gst_vaapi_decoder_decode cannot return success without - completing the decode and pushing all decoded frames into the output - queue */ - ret = gst_vaapidecode_push_all_decoded_frames(decode); - if (ret != GST_FLOW_OK && ret != GST_FLOW_FLUSHING) - GST_ERROR("push loop error after decoding %d", ret); + gst_video_decoder_drop_frame (vdec, frame); return ret; - - /* ERRORS */ -error_push_all_decoded_frames: - { - GST_ERROR("push loop error while decoding %d", ret); - gst_video_decoder_drop_frame(vdec, frame); - return ret; - } -error_decode: - { - GST_ERROR("decode error %d", status); - switch (status) { - case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: - case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: - case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: - ret = GST_FLOW_NOT_SUPPORTED; - break; - default: - GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding error"), - ("Decode error %d", status)); - ret = GST_FLOW_ERROR; - break; - } - gst_video_decoder_drop_frame(vdec, frame); - return ret; - } + } not_negotiated: - { - GST_ERROR_OBJECT (decode, "not negotiated"); - ret = GST_FLOW_NOT_NEGOTIATED; - gst_video_decoder_drop_frame (vdec, frame); - return ret; - } + { + GST_ERROR_OBJECT (decode, "not negotiated"); + ret = GST_FLOW_NOT_NEGOTIATED; + gst_video_decoder_drop_frame (vdec, frame); + return ret; + } } static gboolean -gst_vaapidecode_flush(GstVideoDecoder *vdec) +gst_vaapidecode_flush (GstVideoDecoder * vdec) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - GstVaapiDecoderStatus status; + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstVaapiDecoderStatus status; - if (!decode->decoder) - return TRUE; - - /* If there is something in GstVideoDecoder's output adapter, then - submit the frame for decoding */ - if (decode->current_frame_size) { - gst_video_decoder_have_frame(vdec); - decode->current_frame_size = 0; - } - - status = gst_vaapi_decoder_flush(decode->decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - goto error_flush; + if (!decode->decoder) return TRUE; - /* ERRORS */ + /* If there is something in GstVideoDecoder's output adapter, then + submit the frame for decoding */ + if (decode->current_frame_size) { + gst_video_decoder_have_frame (vdec); + decode->current_frame_size = 0; + } + + status = gst_vaapi_decoder_flush (decode->decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto error_flush; + return TRUE; + + /* ERRORS */ error_flush: - { - GST_ERROR("failed to flush decoder (status %d)", status); - return FALSE; - } + { + GST_ERROR ("failed to flush decoder (status %d)", status); + return FALSE; + } } static GstFlowReturn -gst_vaapidecode_finish(GstVideoDecoder *vdec) +gst_vaapidecode_finish (GstVideoDecoder * vdec) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - GstFlowReturn ret = GST_FLOW_OK; + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstFlowReturn ret = GST_FLOW_OK; - if (!decode->decoder) - return GST_FLOW_OK; + if (!decode->decoder) + return GST_FLOW_OK; - if (!gst_vaapidecode_flush(vdec)) { - gst_vaapidecode_push_all_decoded_frames(decode); - return GST_FLOW_ERROR; - } + if (!gst_vaapidecode_flush (vdec)) { + gst_vaapidecode_push_all_decoded_frames (decode); + return GST_FLOW_ERROR; + } - return gst_vaapidecode_push_all_decoded_frames(decode); + return gst_vaapidecode_push_all_decoded_frames (decode); } #if GST_CHECK_VERSION(1,0,0) static gboolean -gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) +gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - GstCaps *caps = NULL; - GstVideoCodecState *state; - GstVaapiCapsFeature feature; - GstVideoFormat out_format; + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstCaps *caps = NULL; + GstVideoCodecState *state; + GstVaapiCapsFeature feature; + GstVideoFormat out_format; - gst_query_parse_allocation(query, &caps, NULL); + gst_query_parse_allocation (query, &caps, NULL); - feature = - gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec), - GST_VIDEO_FORMAT_ENCODED, &out_format); - decode->has_texture_upload_meta = FALSE; + feature = + gst_vaapi_find_preferred_caps_feature (GST_VIDEO_DECODER_SRC_PAD (vdec), + GST_VIDEO_FORMAT_ENCODED, &out_format); + decode->has_texture_upload_meta = FALSE; #if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) - decode->has_texture_upload_meta = - (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) && - gst_query_find_allocation_meta (query, - GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); + decode->has_texture_upload_meta = + (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) && + gst_query_find_allocation_meta (query, + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); #endif - /* Update src caps if feature is not handled downstream */ - state = gst_video_decoder_get_output_state(vdec); - if (!gst_caps_is_always_compatible(caps, state->caps)) - gst_vaapidecode_update_src_caps(decode); - gst_video_codec_state_unref(state); + /* Update src caps if feature is not handled downstream */ + state = gst_video_decoder_get_output_state (vdec); + if (!gst_caps_is_always_compatible (caps, state->caps)) + gst_vaapidecode_update_src_caps (decode); + gst_video_codec_state_unref (state); - return gst_vaapi_plugin_base_decide_allocation(GST_VAAPI_PLUGIN_BASE(vdec), - query, feature); + return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), + query, feature); } #endif static inline gboolean -gst_vaapidecode_ensure_display(GstVaapiDecode *decode) +gst_vaapidecode_ensure_display (GstVaapiDecode * decode) { - return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(decode)); + return gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (decode)); } static inline guint -gst_vaapi_codec_from_caps(GstCaps *caps) +gst_vaapi_codec_from_caps (GstCaps * caps) { - return gst_vaapi_profile_get_codec(gst_vaapi_profile_from_caps(caps)); + return gst_vaapi_profile_get_codec (gst_vaapi_profile_from_caps (caps)); } static gboolean -gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps) +gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) { - GstVaapiDisplay *dpy; + GstVaapiDisplay *dpy; - if (!gst_vaapidecode_ensure_display(decode)) - return FALSE; - dpy = GST_VAAPI_PLUGIN_BASE_DISPLAY(decode); + if (!gst_vaapidecode_ensure_display (decode)) + return FALSE; + dpy = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode); - switch (gst_vaapi_codec_from_caps(caps)) { + switch (gst_vaapi_codec_from_caps (caps)) { case GST_VAAPI_CODEC_MPEG2: - decode->decoder = gst_vaapi_decoder_mpeg2_new(dpy, caps); - break; + decode->decoder = gst_vaapi_decoder_mpeg2_new (dpy, caps); + break; case GST_VAAPI_CODEC_MPEG4: case GST_VAAPI_CODEC_H263: - decode->decoder = gst_vaapi_decoder_mpeg4_new(dpy, caps); - break; + decode->decoder = gst_vaapi_decoder_mpeg4_new (dpy, caps); + break; case GST_VAAPI_CODEC_H264: - decode->decoder = gst_vaapi_decoder_h264_new(dpy, caps); + decode->decoder = gst_vaapi_decoder_h264_new (dpy, caps); - /* Set the stream buffer alignment for better optimizations */ - if (decode->decoder && caps) { - GstStructure * const structure = gst_caps_get_structure(caps, 0); - const gchar *str = NULL; + /* Set the stream buffer alignment for better optimizations */ + if (decode->decoder && caps) { + GstStructure *const structure = gst_caps_get_structure (caps, 0); + const gchar *str = NULL; - if ((str = gst_structure_get_string(structure, "alignment"))) { - GstVaapiStreamAlignH264 alignment; - if (g_strcmp0(str, "au") == 0) - alignment = GST_VAAPI_STREAM_ALIGN_H264_AU; - else if (g_strcmp0(str, "nal") == 0) - alignment = GST_VAAPI_STREAM_ALIGN_H264_NALU; - else - alignment = GST_VAAPI_STREAM_ALIGN_H264_NONE; - gst_vaapi_decoder_h264_set_alignment( - GST_VAAPI_DECODER_H264(decode->decoder), alignment); - } + if ((str = gst_structure_get_string (structure, "alignment"))) { + GstVaapiStreamAlignH264 alignment; + if (g_strcmp0 (str, "au") == 0) + alignment = GST_VAAPI_STREAM_ALIGN_H264_AU; + else if (g_strcmp0 (str, "nal") == 0) + alignment = GST_VAAPI_STREAM_ALIGN_H264_NALU; + else + alignment = GST_VAAPI_STREAM_ALIGN_H264_NONE; + gst_vaapi_decoder_h264_set_alignment (GST_VAAPI_DECODER_H264 (decode-> + decoder), alignment); } - break; + } + break; case GST_VAAPI_CODEC_WMV3: case GST_VAAPI_CODEC_VC1: - decode->decoder = gst_vaapi_decoder_vc1_new(dpy, caps); - break; + decode->decoder = gst_vaapi_decoder_vc1_new (dpy, caps); + break; #if USE_JPEG_DECODER case GST_VAAPI_CODEC_JPEG: - decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps); - break; + decode->decoder = gst_vaapi_decoder_jpeg_new (dpy, caps); + break; #endif #if USE_VP8_DECODER case GST_VAAPI_CODEC_VP8: - decode->decoder = gst_vaapi_decoder_vp8_new(dpy, caps); - break; + decode->decoder = gst_vaapi_decoder_vp8_new (dpy, caps); + break; #endif default: - decode->decoder = NULL; - break; - } - if (!decode->decoder) - return FALSE; + decode->decoder = NULL; + break; + } + if (!decode->decoder) + return FALSE; - gst_vaapi_decoder_set_codec_state_changed_func(decode->decoder, - gst_vaapi_decoder_state_changed, decode); + gst_vaapi_decoder_set_codec_state_changed_func (decode->decoder, + gst_vaapi_decoder_state_changed, decode); - decode->decoder_caps = gst_caps_ref(caps); - return TRUE; + decode->decoder_caps = gst_caps_ref (caps); + return TRUE; } static void -gst_vaapidecode_destroy(GstVaapiDecode *decode) +gst_vaapidecode_destroy (GstVaapiDecode * decode) { - gst_vaapi_decoder_replace(&decode->decoder, NULL); - gst_caps_replace(&decode->decoder_caps, NULL); + gst_vaapi_decoder_replace (&decode->decoder, NULL); + gst_caps_replace (&decode->decoder_caps, NULL); - decode->active = FALSE; + decode->active = FALSE; - gst_vaapidecode_release(decode); + gst_vaapidecode_release (decode); } static gboolean -gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard) +gst_vaapidecode_reset_full (GstVaapiDecode * decode, GstCaps * caps, + gboolean hard) { - GstVaapiCodec codec; + GstVaapiCodec codec; - decode->has_texture_upload_meta = FALSE; + decode->has_texture_upload_meta = FALSE; - /* Reset tracked frame size */ - decode->current_frame_size = 0; + /* Reset tracked frame size */ + decode->current_frame_size = 0; - /* Reset timers if hard reset was requested (e.g. seek) */ - if (hard) { - GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); - GstVideoCodecFrame *out_frame = NULL; + /* Reset timers if hard reset was requested (e.g. seek) */ + if (hard) { + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); + GstVideoCodecFrame *out_frame = NULL; - gst_vaapi_decoder_flush(decode->decoder); + gst_vaapi_decoder_flush (decode->decoder); - /* Purge all decoded frames as we don't need them (e.g. seek) */ - while (gst_vaapi_decoder_get_frame_with_timeout(decode->decoder, - &out_frame, 0) == GST_VAAPI_DECODER_STATUS_SUCCESS) { - gst_video_codec_frame_unref(out_frame); - out_frame = NULL; - } + /* Purge all decoded frames as we don't need them (e.g. seek) */ + while (gst_vaapi_decoder_get_frame_with_timeout (decode->decoder, + &out_frame, 0) == GST_VAAPI_DECODER_STATUS_SUCCESS) { + gst_video_codec_frame_unref (out_frame); + out_frame = NULL; } + } - /* Only reset decoder if codec type changed */ - else if (decode->decoder && decode->decoder_caps) { - if (gst_caps_is_always_compatible(caps, decode->decoder_caps)) - return TRUE; - codec = gst_vaapi_codec_from_caps(caps); - if (codec == gst_vaapi_decoder_get_codec(decode->decoder)) - return TRUE; - } + /* Only reset decoder if codec type changed */ + else if (decode->decoder && decode->decoder_caps) { + if (gst_caps_is_always_compatible (caps, decode->decoder_caps)) + return TRUE; + codec = gst_vaapi_codec_from_caps (caps); + if (codec == gst_vaapi_decoder_get_codec (decode->decoder)) + return TRUE; + } - gst_vaapidecode_destroy(decode); - return gst_vaapidecode_create(decode, caps); + gst_vaapidecode_destroy (decode); + return gst_vaapidecode_create (decode, caps); } static void -gst_vaapidecode_finalize(GObject *object) +gst_vaapidecode_finalize (GObject * object) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(object); + GstVaapiDecode *const decode = GST_VAAPIDECODE (object); - gst_caps_replace(&decode->sinkpad_caps, NULL); - gst_caps_replace(&decode->srcpad_caps, NULL); - gst_caps_replace(&decode->allowed_caps, NULL); + gst_caps_replace (&decode->sinkpad_caps, NULL); + gst_caps_replace (&decode->srcpad_caps, NULL); + gst_caps_replace (&decode->allowed_caps, NULL); - g_cond_clear(&decode->surface_ready); - g_mutex_clear(&decode->surface_ready_mutex); + g_cond_clear (&decode->surface_ready); + g_mutex_clear (&decode->surface_ready_mutex); - gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object)); - G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object); + gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (object)); + G_OBJECT_CLASS (gst_vaapidecode_parent_class)->finalize (object); } static gboolean -gst_vaapidecode_open(GstVideoDecoder *vdec) +gst_vaapidecode_open (GstVideoDecoder * vdec) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - GstVaapiDisplay * const old_display = GST_VAAPI_PLUGIN_BASE_DISPLAY(decode); - gboolean success; + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstVaapiDisplay *const old_display = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode); + gboolean success; - if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(decode))) - return FALSE; + if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (decode))) + return FALSE; - /* Let GstVideoContext ask for a proper display to its neighbours */ - /* Note: steal old display that may be allocated from get_caps() - so that to retain a reference to it, thus avoiding extra - initialization steps if we turn out to simply re-use the - existing (cached) VA display */ - GST_VAAPI_PLUGIN_BASE_DISPLAY(decode) = NULL; - success = gst_vaapidecode_ensure_display(decode); - if (old_display) - gst_vaapi_display_unref(old_display); - return success; + /* Let GstVideoContext ask for a proper display to its neighbours */ + /* Note: steal old display that may be allocated from get_caps() + so that to retain a reference to it, thus avoiding extra + initialization steps if we turn out to simply re-use the + existing (cached) VA display */ + GST_VAAPI_PLUGIN_BASE_DISPLAY (decode) = NULL; + success = gst_vaapidecode_ensure_display (decode); + if (old_display) + gst_vaapi_display_unref (old_display); + return success; } static gboolean -gst_vaapidecode_close(GstVideoDecoder *vdec) +gst_vaapidecode_close (GstVideoDecoder * vdec) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - gst_vaapi_decode_input_state_replace(decode, NULL); - gst_vaapidecode_destroy(decode); - gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(decode)); + gst_vaapi_decode_input_state_replace (decode, NULL); + gst_vaapidecode_destroy (decode); + gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (decode)); + return TRUE; +} + +static gboolean +gst_vaapidecode_reset (GstVideoDecoder * vdec, gboolean hard) +{ + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + + /* In GStreamer 1.0 context, this means a flush */ + if (decode->decoder && !hard && !gst_vaapidecode_flush (vdec)) + return FALSE; + return gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, hard); +} + +static gboolean +gst_vaapidecode_set_format (GstVideoDecoder * vdec, GstVideoCodecState * state) +{ + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + + if (!gst_vaapi_decode_input_state_replace (decode, state)) return TRUE; -} + if (!gst_vaapidecode_update_sink_caps (decode, state->caps)) + return FALSE; + if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) + return FALSE; + if (!gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, FALSE)) + return FALSE; -static gboolean -gst_vaapidecode_reset(GstVideoDecoder *vdec, gboolean hard) -{ - GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - - /* In GStreamer 1.0 context, this means a flush */ - if (decode->decoder && !hard && !gst_vaapidecode_flush(vdec)) - return FALSE; - return gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, hard); -} - -static gboolean -gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state) -{ - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec); - GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - - if (!gst_vaapi_decode_input_state_replace(decode, state)) - return TRUE; - if (!gst_vaapidecode_update_sink_caps(decode, state->caps)) - return FALSE; - if (!gst_vaapi_plugin_base_set_caps(plugin, decode->sinkpad_caps, NULL)) - return FALSE; - if (!gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, FALSE)) - return FALSE; - - return TRUE; + return TRUE; } static GstFlowReturn -gst_vaapidecode_parse_frame(GstVideoDecoder *vdec, - GstVideoCodecFrame *frame, GstAdapter *adapter, gboolean at_eos) +gst_vaapidecode_parse_frame (GstVideoDecoder * vdec, + GstVideoCodecFrame * frame, GstAdapter * adapter, gboolean at_eos) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); - GstVaapiDecoderStatus status; - GstFlowReturn ret; - guint got_unit_size; - gboolean got_frame; + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstVaapiDecoderStatus status; + GstFlowReturn ret; + guint got_unit_size; + gboolean got_frame; - status = gst_vaapi_decoder_parse(decode->decoder, frame, - adapter, at_eos, &got_unit_size, &got_frame); + status = gst_vaapi_decoder_parse (decode->decoder, frame, + adapter, at_eos, &got_unit_size, &got_frame); - switch (status) { + switch (status) { case GST_VAAPI_DECODER_STATUS_SUCCESS: - if (got_unit_size > 0) { - gst_video_decoder_add_to_frame(vdec, got_unit_size); - decode->current_frame_size += got_unit_size; - } - if (got_frame) { - ret = gst_video_decoder_have_frame(vdec); - decode->current_frame_size = 0; - } - else - ret = GST_VAAPI_DECODE_FLOW_PARSE_DATA; - break; + if (got_unit_size > 0) { + gst_video_decoder_add_to_frame (vdec, got_unit_size); + decode->current_frame_size += got_unit_size; + } + if (got_frame) { + ret = gst_video_decoder_have_frame (vdec); + decode->current_frame_size = 0; + } else + ret = GST_VAAPI_DECODE_FLOW_PARSE_DATA; + break; case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: - ret = GST_VIDEO_DECODER_FLOW_NEED_DATA; - break; + ret = GST_VIDEO_DECODER_FLOW_NEED_DATA; + break; case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: - GST_WARNING("parse error %d", status); - ret = GST_FLOW_NOT_SUPPORTED; - decode->current_frame_size = 0; - break; + GST_WARNING ("parse error %d", status); + ret = GST_FLOW_NOT_SUPPORTED; + decode->current_frame_size = 0; + break; default: - GST_ERROR("parse error %d", status); - ret = GST_FLOW_EOS; - decode->current_frame_size = 0; - break; - } - return ret; + GST_ERROR ("parse error %d", status); + ret = GST_FLOW_EOS; + decode->current_frame_size = 0; + break; + } + return ret; } static GstFlowReturn -gst_vaapidecode_parse(GstVideoDecoder *vdec, - GstVideoCodecFrame *frame, GstAdapter *adapter, gboolean at_eos) +gst_vaapidecode_parse (GstVideoDecoder * vdec, + GstVideoCodecFrame * frame, GstAdapter * adapter, gboolean at_eos) { - GstFlowReturn ret; + GstFlowReturn ret; - do { - ret = gst_vaapidecode_parse_frame(vdec, frame, adapter, at_eos); - } while (ret == GST_VAAPI_DECODE_FLOW_PARSE_DATA); - return ret; + do { + ret = gst_vaapidecode_parse_frame (vdec, frame, adapter, at_eos); + } while (ret == GST_VAAPI_DECODE_FLOW_PARSE_DATA); + return ret; } static void -gst_vaapidecode_class_init(GstVaapiDecodeClass *klass) +gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - GstVideoDecoderClass * const vdec_class = GST_VIDEO_DECODER_CLASS(klass); - GstPadTemplate *pad_template; + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstVideoDecoderClass *const vdec_class = GST_VIDEO_DECODER_CLASS (klass); + GstPadTemplate *pad_template; - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapidecode, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass)); + gst_vaapi_plugin_base_class_init (GST_VAAPI_PLUGIN_BASE_CLASS (klass)); - object_class->finalize = gst_vaapidecode_finalize; + object_class->finalize = gst_vaapidecode_finalize; - vdec_class->open = GST_DEBUG_FUNCPTR(gst_vaapidecode_open); - vdec_class->close = GST_DEBUG_FUNCPTR(gst_vaapidecode_close); - vdec_class->set_format = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_format); - vdec_class->reset = GST_DEBUG_FUNCPTR(gst_vaapidecode_reset); - vdec_class->parse = GST_DEBUG_FUNCPTR(gst_vaapidecode_parse); - vdec_class->handle_frame = GST_DEBUG_FUNCPTR(gst_vaapidecode_handle_frame); - vdec_class->finish = GST_DEBUG_FUNCPTR(gst_vaapidecode_finish); + vdec_class->open = GST_DEBUG_FUNCPTR (gst_vaapidecode_open); + vdec_class->close = GST_DEBUG_FUNCPTR (gst_vaapidecode_close); + vdec_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapidecode_set_format); + vdec_class->reset = GST_DEBUG_FUNCPTR (gst_vaapidecode_reset); + vdec_class->parse = GST_DEBUG_FUNCPTR (gst_vaapidecode_parse); + vdec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapidecode_handle_frame); + vdec_class->finish = GST_DEBUG_FUNCPTR (gst_vaapidecode_finish); #if GST_CHECK_VERSION(1,0,0) - vdec_class->decide_allocation = - GST_DEBUG_FUNCPTR(gst_vaapidecode_decide_allocation); + vdec_class->decide_allocation = + GST_DEBUG_FUNCPTR (gst_vaapidecode_decide_allocation); #endif - gst_element_class_set_static_metadata(element_class, - "VA-API decoder", - "Codec/Decoder/Video", - GST_PLUGIN_DESC, - "Gwenole Beauchesne "); + gst_element_class_set_static_metadata (element_class, + "VA-API decoder", + "Codec/Decoder/Video", + GST_PLUGIN_DESC, "Gwenole Beauchesne "); - /* sink pad */ - pad_template = gst_static_pad_template_get(&gst_vaapidecode_sink_factory); - gst_element_class_add_pad_template(element_class, pad_template); + /* sink pad */ + pad_template = gst_static_pad_template_get (&gst_vaapidecode_sink_factory); + gst_element_class_add_pad_template (element_class, pad_template); - /* src pad */ - pad_template = gst_static_pad_template_get(&gst_vaapidecode_src_factory); - gst_element_class_add_pad_template(element_class, pad_template); + /* src pad */ + pad_template = gst_static_pad_template_get (&gst_vaapidecode_src_factory); + gst_element_class_add_pad_template (element_class, pad_template); } static gboolean -gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode) +gst_vaapidecode_ensure_allowed_caps (GstVaapiDecode * decode) { - GstCaps *caps, *allowed_caps; - GArray *profiles; - guint i; + GstCaps *caps, *allowed_caps; + GArray *profiles; + guint i; - if (decode->allowed_caps) - return TRUE; - - if (!gst_vaapidecode_ensure_display(decode)) - goto error_no_display; - - profiles = gst_vaapi_display_get_decode_profiles( - GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); - if (!profiles) - goto error_no_profiles; - - allowed_caps = gst_caps_new_empty(); - if (!allowed_caps) - goto error_no_memory; - - for (i = 0; i < profiles->len; i++) { - const GstVaapiProfile profile = - g_array_index(profiles, GstVaapiProfile, i); - const gchar *media_type_name; - const gchar *profile_name; - GstStructure *structure; - - media_type_name = gst_vaapi_profile_get_media_type_name(profile); - if (!media_type_name) - continue; - - caps = gst_caps_from_string(media_type_name); - if (!caps) - continue; - structure = gst_caps_get_structure (caps, 0); - - profile_name = gst_vaapi_profile_get_name(profile); - if (profile_name) - gst_structure_set(structure, "profile", G_TYPE_STRING, - profile_name, NULL); - - allowed_caps = gst_caps_merge(allowed_caps, caps); - } - decode->allowed_caps = gst_caps_simplify (allowed_caps); - - g_array_unref(profiles); + if (decode->allowed_caps) return TRUE; - /* ERRORS */ + if (!gst_vaapidecode_ensure_display (decode)) + goto error_no_display; + + profiles = + gst_vaapi_display_get_decode_profiles (GST_VAAPI_PLUGIN_BASE_DISPLAY + (decode)); + if (!profiles) + goto error_no_profiles; + + allowed_caps = gst_caps_new_empty (); + if (!allowed_caps) + goto error_no_memory; + + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index (profiles, GstVaapiProfile, i); + const gchar *media_type_name; + const gchar *profile_name; + GstStructure *structure; + + media_type_name = gst_vaapi_profile_get_media_type_name (profile); + if (!media_type_name) + continue; + + caps = gst_caps_from_string (media_type_name); + if (!caps) + continue; + structure = gst_caps_get_structure (caps, 0); + + profile_name = gst_vaapi_profile_get_name (profile); + if (profile_name) + gst_structure_set (structure, "profile", G_TYPE_STRING, + profile_name, NULL); + + allowed_caps = gst_caps_merge (allowed_caps, caps); + } + decode->allowed_caps = gst_caps_simplify (allowed_caps); + + g_array_unref (profiles); + return TRUE; + + /* ERRORS */ error_no_display: - { - GST_ERROR("failed to retrieve VA display"); - return FALSE; - } + { + GST_ERROR ("failed to retrieve VA display"); + return FALSE; + } error_no_profiles: - { - GST_ERROR("failed to retrieve VA decode profiles"); - return FALSE; - } + { + GST_ERROR ("failed to retrieve VA decode profiles"); + return FALSE; + } error_no_memory: - { - GST_ERROR("failed to allocate allowed-caps set"); - g_array_unref(profiles); - return FALSE; - } + { + GST_ERROR ("failed to allocate allowed-caps set"); + g_array_unref (profiles); + return FALSE; + } } static GstCaps * -gst_vaapidecode_get_caps(GstPad *pad) +gst_vaapidecode_get_caps (GstPad * pad) { - GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); + GstVaapiDecode *const decode = GST_VAAPIDECODE (GST_OBJECT_PARENT (pad)); - if (!gst_vaapidecode_ensure_allowed_caps(decode)) - return gst_caps_new_empty(); + if (!gst_vaapidecode_ensure_allowed_caps (decode)) + return gst_caps_new_empty (); - return gst_caps_ref(decode->allowed_caps); + return gst_caps_ref (decode->allowed_caps); } static gboolean -gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS) +gst_vaapidecode_query (GST_PAD_QUERY_FUNCTION_ARGS) { - GstVaapiDecode * const decode = - GST_VAAPIDECODE(gst_pad_get_parent_element(pad)); - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(decode); - gboolean res; + GstVaapiDecode *const decode = + GST_VAAPIDECODE (gst_pad_get_parent_element (pad)); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (decode); + gboolean res; - GST_INFO_OBJECT(decode, "query type %s", GST_QUERY_TYPE_NAME(query)); + GST_INFO_OBJECT (decode, "query type %s", GST_QUERY_TYPE_NAME (query)); - if (gst_vaapi_reply_to_query(query, plugin->display)) { - GST_DEBUG("sharing display %p", plugin->display); + if (gst_vaapi_reply_to_query (query, plugin->display)) { + GST_DEBUG ("sharing display %p", plugin->display); + res = TRUE; + } else if (GST_PAD_IS_SINK (pad)) { + switch (GST_QUERY_TYPE (query)) { +#if GST_CHECK_VERSION(1,0,0) + case GST_QUERY_CAPS:{ + GstCaps *filter, *caps = NULL; + + gst_query_parse_caps (query, &filter); + caps = gst_vaapidecode_get_caps (pad); + + if (filter) { + GstCaps *tmp = caps; + caps = gst_caps_intersect_full (filter, tmp, + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (tmp); + } + + GST_DEBUG_OBJECT (decode, "Returning sink caps %" GST_PTR_FORMAT, caps); + + gst_query_set_caps_result (query, caps); + gst_caps_unref (caps); res = TRUE; - } - else if (GST_PAD_IS_SINK(pad)) { - switch (GST_QUERY_TYPE(query)) { -#if GST_CHECK_VERSION(1,0,0) - case GST_QUERY_CAPS: { - GstCaps *filter, *caps = NULL; - - gst_query_parse_caps(query, &filter); - caps = gst_vaapidecode_get_caps(pad); - - if (filter) { - GstCaps *tmp = caps; - caps = gst_caps_intersect_full(filter, tmp, - GST_CAPS_INTERSECT_FIRST); - gst_caps_unref(tmp); - } - - GST_DEBUG_OBJECT(decode, "Returning sink caps %" GST_PTR_FORMAT, - caps); - - gst_query_set_caps_result(query, caps); - gst_caps_unref(caps); - res = TRUE; - break; - } + break; + } #endif - default: - res = GST_PAD_QUERY_FUNCTION_CALL(plugin->sinkpad_query, pad, - parent, query); - break; - } + default: + res = GST_PAD_QUERY_FUNCTION_CALL (plugin->sinkpad_query, pad, + parent, query); + break; } - else { - switch (GST_QUERY_TYPE(query)) { + } else { + switch (GST_QUERY_TYPE (query)) { #if GST_CHECK_VERSION(1,0,0) - case GST_QUERY_CAPS: { - GstCaps *filter, *caps = NULL; + case GST_QUERY_CAPS:{ + GstCaps *filter, *caps = NULL; - gst_query_parse_caps(query, &filter); - caps = gst_pad_get_pad_template_caps(pad); + gst_query_parse_caps (query, &filter); + caps = gst_pad_get_pad_template_caps (pad); - if (filter) { - GstCaps *tmp = caps; - caps = gst_caps_intersect_full(filter, tmp, - GST_CAPS_INTERSECT_FIRST); - gst_caps_unref(tmp); - } - - GST_DEBUG_OBJECT(decode, "Returning src caps %" GST_PTR_FORMAT, - caps); - - gst_query_set_caps_result(query, caps); - gst_caps_unref(caps); - res = TRUE; - break; + if (filter) { + GstCaps *tmp = caps; + caps = gst_caps_intersect_full (filter, tmp, + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (tmp); } + + GST_DEBUG_OBJECT (decode, "Returning src caps %" GST_PTR_FORMAT, caps); + + gst_query_set_caps_result (query, caps); + gst_caps_unref (caps); + res = TRUE; + break; + } #endif - default: - res = GST_PAD_QUERY_FUNCTION_CALL(plugin->srcpad_query, pad, - parent, query); - break; - } + default: + res = GST_PAD_QUERY_FUNCTION_CALL (plugin->srcpad_query, pad, + parent, query); + break; } + } - gst_object_unref(decode); - return res; + gst_object_unref (decode); + return res; } static void -gst_vaapidecode_init(GstVaapiDecode *decode) +gst_vaapidecode_init (GstVaapiDecode * decode) { - GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode); - GstPad *pad; + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); + GstPad *pad; - gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(decode), GST_CAT_DEFAULT); + gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (decode), GST_CAT_DEFAULT); - decode->decoder = NULL; - decode->decoder_caps = NULL; - decode->allowed_caps = NULL; + decode->decoder = NULL; + decode->decoder_caps = NULL; + decode->allowed_caps = NULL; - g_mutex_init(&decode->surface_ready_mutex); - g_cond_init(&decode->surface_ready); + g_mutex_init (&decode->surface_ready_mutex); + g_cond_init (&decode->surface_ready); - gst_video_decoder_set_packetized(vdec, FALSE); + gst_video_decoder_set_packetized (vdec, FALSE); - /* Pad through which data comes in to the element */ - pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD(decode); - gst_pad_set_query_function(pad, GST_DEBUG_FUNCPTR(gst_vaapidecode_query)); + /* Pad through which data comes in to the element */ + pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD (decode); + gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_vaapidecode_query)); #if !GST_CHECK_VERSION(1,0,0) - gst_pad_set_getcaps_function(pad, gst_vaapidecode_get_caps); + gst_pad_set_getcaps_function (pad, gst_vaapidecode_get_caps); #endif - /* Pad through which data goes out of the element */ - pad = GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode); - gst_pad_set_query_function(pad, GST_DEBUG_FUNCPTR(gst_vaapidecode_query)); + /* Pad through which data goes out of the element */ + pad = GST_VAAPI_PLUGIN_BASE_SRC_PAD (decode); + gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_vaapidecode_query)); } From 8eabe9f3774eedf14a029da3385b744f38af4b19 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 2 Mar 2015 15:19:40 +0200 Subject: [PATCH 1912/3781] plugins: Add a vaapidecodebin element Add a "vaapidecodebin" element to vaapi plugins. Child Elements: "vaapidecode ! queue ! vaapipostproc" The Reasons for implementing a new bin element: -- Help to Autoplug Hardware Accelerated Video Postprocessing element in playbin with out any dependency to upstream gstreamer. This is to overcome the *unacceptable* delay in upstream gstreamer to get new features in. Eg: https://bugzilla.gnome.org/show_bug.cgi?id=687182. Also customers using older gstreamer versions (1.2 and 1.4) will get the benefit of autoplugging, hardware accelerated deinterlacing support etc. -- Help to maintain a single thread implementation in vaapidecode. This will result a dead-lock free vaapidecode in most of the cases. More details here: https://bugzilla.gnome.org/show_bug.cgi?id=742605 https://bugzilla.gnome.org/show_bug.cgi?id=745216 --- gst/vaapi/Makefile.am | 4 +- gst/vaapi/gstvaapi.c | 4 + gst/vaapi/gstvaapidecodebin.c | 284 ++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapidecodebin.h | 64 ++++++++ 4 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 gst/vaapi/gstvaapidecodebin.c create mode 100644 gst/vaapi/gstvaapidecodebin.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index d2ff9455b3..69fb6bf5a6 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -56,6 +56,7 @@ libgstvaapi_source_c = \ gstvaapivideobuffer.c \ gstvaapivideocontext.c \ gstvaapivideometa.c \ + gstvaapidecodebin.c \ $(NULL) libgstvaapi_source_h = \ @@ -68,6 +69,7 @@ libgstvaapi_source_h = \ gstvaapivideobuffer.h \ gstvaapivideocontext.h \ gstvaapivideometa.h \ + gstvaapidecodebin.h \ $(NULL) libgstvaapi_enc_source_c = \ @@ -189,7 +191,7 @@ libgstvaapi_la_LIBADD = \ $(libgstvaapi_LIBS) \ $(GST_LIBS) \ $(GST_BASE_LIBS) \ - $(GST_VIDEO_LIBS) \ + $(GST_VIDEO_LIBS) -lgstpbutils-$(GST_PKG_VERSION) \ $(GST_INTERFACES_LIBS) \ $(GST_BASEVIDEO_LIBS) \ $(GST_PLUGINS_BASE_LIBS) \ diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index f15731b66f..44bbc84bff 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -29,6 +29,7 @@ #include "gstvaapidecode.h" #include "gstvaapipostproc.h" #include "gstvaapisink.h" +#include "gstvaapidecodebin.h" #if USE_ENCODERS #include "gstvaapiencode_h264.h" @@ -86,6 +87,9 @@ plugin_init (GstPlugin *plugin) GST_TYPE_VAAPIENCODE_VP8); #endif + gst_element_register(plugin, "vaapidecodebin", + GST_RANK_PRIMARY + 2, + GST_TYPE_VAAPI_DECODE_BIN); return TRUE; } diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c new file mode 100644 index 0000000000..388ff02463 --- /dev/null +++ b/gst/vaapi/gstvaapidecodebin.c @@ -0,0 +1,284 @@ +/* + * gstvaapidecodebin.c + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 "gst/vaapi/sysdeps.h" +#include +#include +#include +#include +#include "gstvaapipluginutil.h" +#include "gstvaapidecodebin.h" + +#define GST_PLUGIN_NAME "vaapidecodebin" +#define GST_PLUGIN_DESC "A Bin of VA-API elements: vaapidecode ! queue ! vaapipostproc" + +GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapi_decode_bin); +#define GST_CAT_DEFAULT gst_debug_vaapi_decode_bin + +#define DEFAULT_QUEUE_MAX_SIZE_BUFFERS 0 +#define DEFAULT_QUEUE_MAX_SIZE_BYTES 0 +#define DEFAULT_QUEUE_MAX_SIZE_TIME 0 + +enum +{ + PROP_0, + PROP_MAX_SIZE_BUFFERS, + PROP_MAX_SIZE_BYTES, + PROP_MAX_SIZE_TIME +}; + +#if GST_CHECK_VERSION(1,1,0) +#define GST_VAAPI_DECODE_BIN_SURFACE_CAPS \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") +#else +#define GST_VAAPI_DECODE_BIN_SURFACE_CAPS \ + GST_VAAPI_SURFACE_CAPS +#endif + +/* Default templates */ +#define GST_CAPS_CODEC(CODEC) CODEC "; " +/* *INDENT-OFF* */ +static const char gst_vaapi_decode_bin_sink_caps_str[] = + GST_CAPS_CODEC("video/mpeg, mpegversion=2, systemstream=(boolean)false") + GST_CAPS_CODEC("video/mpeg, mpegversion=4") + GST_CAPS_CODEC("video/x-divx") + GST_CAPS_CODEC("video/x-xvid") + GST_CAPS_CODEC("video/x-h263") + GST_CAPS_CODEC("video/x-h264") + GST_CAPS_CODEC("video/x-wmv") + GST_CAPS_CODEC("video/x-vp8") + GST_CAPS_CODEC("image/jpeg") + ; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static const char gst_vaapi_decode_bin_src_caps_str[] = + GST_VAAPI_DECODE_BIN_SURFACE_CAPS ", " + GST_CAPS_INTERLACED_FALSE "; " +#if GST_CHECK_VERSION(1,1,0) + GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") ", " + GST_CAPS_INTERLACED_FALSE "; " +#endif +#if GST_CHECK_VERSION(1,0,0) + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " +#endif + GST_CAPS_INTERLACED_FALSE; +/* *INDENT-ON* */ + +static GstStaticPadTemplate gst_vaapi_decode_bin_sink_factory = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapi_decode_bin_sink_caps_str)); + +static GstStaticPadTemplate gst_vaapi_decode_bin_src_factory = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapi_decode_bin_src_caps_str)); + +G_DEFINE_TYPE (GstVaapiDecodeBin, gst_vaapi_decode_bin, GST_TYPE_BIN); + +static void +gst_vaapi_decode_bin_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstVaapiDecodeBin *vaapidecbin = GST_VAAPI_DECODE_BIN (object); + + switch (prop_id) { + case PROP_MAX_SIZE_BYTES: + vaapidecbin->max_size_bytes = g_value_get_uint (value); + g_object_set (G_OBJECT (vaapidecbin->queue), "max-size-bytes", + vaapidecbin->max_size_bytes, NULL); + break; + case PROP_MAX_SIZE_BUFFERS: + vaapidecbin->max_size_buffers = g_value_get_uint (value); + g_object_set (G_OBJECT (vaapidecbin->queue), "max-size-buffers", + vaapidecbin->max_size_buffers, NULL); + break; + case PROP_MAX_SIZE_TIME: + vaapidecbin->max_size_time = g_value_get_uint64 (value); + g_object_set (G_OBJECT (vaapidecbin->queue), "max-size-time", + vaapidecbin->max_size_time, NULL); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_decode_bin_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstVaapiDecodeBin *vaapidecbin = GST_VAAPI_DECODE_BIN (object); + + switch (prop_id) { + case PROP_MAX_SIZE_BYTES: + g_value_set_uint (value, vaapidecbin->max_size_bytes); + break; + case PROP_MAX_SIZE_BUFFERS: + g_value_set_uint (value, vaapidecbin->max_size_buffers); + break; + case PROP_MAX_SIZE_TIME: + g_value_set_uint64 (value, vaapidecbin->max_size_time); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *element_class; + + gobject_class = G_OBJECT_CLASS (klass); + element_class = GST_ELEMENT_CLASS (klass); + + gobject_class->set_property = gst_vaapi_decode_bin_set_property; + gobject_class->get_property = gst_vaapi_decode_bin_get_property; + + gst_element_class_set_static_metadata (element_class, + "VA-API Decode Bin", + "Codec/Decoder/Video", + GST_PLUGIN_DESC, + "Sreerenj Balachandran "); + + g_object_class_install_property (gobject_class, PROP_MAX_SIZE_BYTES, + g_param_spec_uint ("max-size-bytes", "Max. size (kB)", + "Max. amount of data in the queue (bytes, 0=disable)", + 0, G_MAXUINT, DEFAULT_QUEUE_MAX_SIZE_BYTES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MAX_SIZE_BUFFERS, + g_param_spec_uint ("max-size-buffers", "Max. size (buffers)", + "Max. number of buffers in the queue (0=disable)", 0, G_MAXUINT, + DEFAULT_QUEUE_MAX_SIZE_BUFFERS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MAX_SIZE_TIME, + g_param_spec_uint64 ("max-size-time", "Max. size (ns)", + "Max. amount of data in the queue (in ns, 0=disable)", 0, G_MAXUINT64, + DEFAULT_QUEUE_MAX_SIZE_TIME, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapi_decode_bin_sink_factory)); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapi_decode_bin_src_factory)); + + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_decode_bin, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); +} + +static gboolean +gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) +{ + gchar *missing_factory = NULL; + + /* create the decoder */ + vaapidecbin->decoder = + gst_element_factory_make ("vaapidecode", "vaapidecode"); + if (!vaapidecbin->decoder) { + missing_factory = "vaapidecode"; + goto error_element_missing; + } + /* create the queue */ + vaapidecbin->queue = gst_element_factory_make ("queue", "queue"); + if (!vaapidecbin->queue) { + missing_factory = "queue"; + goto error_element_missing; + } + /* create the postproc */ + vaapidecbin->postproc = + gst_element_factory_make ("vaapipostproc", "vaapipostproc"); + if (!vaapidecbin->postproc) { + missing_factory = "vaapipostproc"; + goto error_element_missing; + } + + g_object_set (G_OBJECT (vaapidecbin->queue), + "max-size-bytes", vaapidecbin->max_size_bytes, + "max-size-buffers", vaapidecbin->max_size_buffers, + "max-size-time", vaapidecbin->max_size_time, NULL); + + gst_bin_add_many (GST_BIN (vaapidecbin), + vaapidecbin->decoder, vaapidecbin->queue, vaapidecbin->postproc, NULL); + + if (!gst_element_link_pads_full (vaapidecbin->decoder, "src", + vaapidecbin->queue, "sink", GST_PAD_LINK_CHECK_NOTHING)) + goto error_link_pad; + + if (!gst_element_link_pads_full (vaapidecbin->queue, "src", + vaapidecbin->postproc, "sink", GST_PAD_LINK_CHECK_NOTHING)) + goto error_link_pad; + + return TRUE; + +error_element_missing: + { + GstMessage *msg; + GST_ERROR_OBJECT (vaapidecbin, "Failed to create %s element", + missing_factory); + msg = + gst_missing_element_message_new (GST_ELEMENT_CAST (vaapidecbin), + missing_factory); + gst_element_post_message (GST_ELEMENT_CAST (vaapidecbin), msg); + return FALSE; + } +error_link_pad: + { + GST_ERROR_OBJECT (vaapidecbin, "Failed to link the child elements"); + return FALSE; + } +} + +static void +gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) +{ + GstPad *element_pad, *ghost_pad; + + if (!gst_vaapi_decode_bin_configure (vaapidecbin)) + return; + + /* create ghost pad sink */ + element_pad = + gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->decoder), "sink"); + ghost_pad = + gst_ghost_pad_new_from_template ("sink", element_pad, + GST_PAD_PAD_TEMPLATE (element_pad)); + gst_object_unref (element_pad); + gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghost_pad); + + /* create ghost pad src */ + element_pad = + gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->postproc), "src"); + ghost_pad = + gst_ghost_pad_new_from_template ("src", element_pad, + GST_PAD_PAD_TEMPLATE (element_pad)); + gst_object_unref (element_pad); + gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghost_pad); +} diff --git a/gst/vaapi/gstvaapidecodebin.h b/gst/vaapi/gstvaapidecodebin.h new file mode 100644 index 0000000000..24776358f8 --- /dev/null +++ b/gst/vaapi/gstvaapidecodebin.h @@ -0,0 +1,64 @@ +/* + * gstvaapidecodebin.h + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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_DECODE_BIN_H__ +#define __GST_VAAPI_DECODE_BIN_H__ + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPI_DECODE_BIN (gst_vaapi_decode_bin_get_type ()) +#define GST_VAAPI_DECODE_BIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DECODE_BIN, GstVaapiDecodeBin)) +#define GST_VAAPI_DECODE_BIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_DECODE_BIN, GstVaapiDecodeBinClass)) +#define GST_IS_AUTO_DETECT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_DECODE_BIN)) +#define GST_IS_AUTO_DETECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_DECODE_BIN)) +#define GST_VAAPI_DECODE_BIN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_DECODE_BIN, GstVaapiDecodeBinClass)) + +typedef struct _GstVaapiDecodeBin { + /* < private > */ + GstBin parent; + + GstElement *decoder; + GstElement *queue; + GstElement *postproc; + + /* properties */ + guint max_size_buffers; + guint max_size_bytes; + guint64 max_size_time; + +} GstVaapiDecodeBin; + +typedef struct _GstVaapiDecodeBinClass { + GstBinClass parent_class; + +} GstVaapiDecodeBinClass; + +GType gst_vaapi_decode_bin_get_type (void); + +G_END_DECLS + +#endif /* __GST_VAAPI_DECODE_BIN_H__ */ From 29853f2aae1fab659ab24af3d9bab2adebe3777f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 3 Mar 2015 12:31:11 +0200 Subject: [PATCH 1913/3781] plugins: Disable vaapidecodebin for GStreamer < 1.4 There are autoplugging issues in GStreamer-1.2. Lets disable vaapidecodebin untill we get some workarounds for this. --- gst/vaapi/gstvaapi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 44bbc84bff..4926d012b3 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -87,9 +87,11 @@ plugin_init (GstPlugin *plugin) GST_TYPE_VAAPIENCODE_VP8); #endif +#if GST_CHECK_VERSION(1,4,0) gst_element_register(plugin, "vaapidecodebin", GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); +#endif return TRUE; } From 73b726418b8233c5f8edbed89496cf95d79cf27c Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 3 Mar 2015 12:37:41 +0200 Subject: [PATCH 1914/3781] vaapidecodebin: Avoid usage of "__" prefix in macro names Avoiding "__" prefix usage in Header File Guards as per C standard recommendation. --- gst/vaapi/gstvaapidecodebin.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.h b/gst/vaapi/gstvaapidecodebin.h index 24776358f8..4d3acfdbd5 100644 --- a/gst/vaapi/gstvaapidecodebin.h +++ b/gst/vaapi/gstvaapidecodebin.h @@ -20,8 +20,8 @@ * Boston, MA 02110-1301 USA */ -#ifndef __GST_VAAPI_DECODE_BIN_H__ -#define __GST_VAAPI_DECODE_BIN_H__ +#ifndef GST_VAAPI_DECODE_BIN_H +#define GST_VAAPI_DECODE_BIN_H G_BEGIN_DECLS @@ -61,4 +61,4 @@ GType gst_vaapi_decode_bin_get_type (void); G_END_DECLS -#endif /* __GST_VAAPI_DECODE_BIN_H__ */ +#endif /* GST_VAAPI_DECODE_BIN_H */ From 7524b5eea620f97bbd2ff02507fa0433c602d7da Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 2 Mar 2015 17:04:20 +0100 Subject: [PATCH 1915/3781] vaapisink: fix minor memory leak in debug mode. The gst_video_colorimetry_to_string() function returns a newly created string that represents the GstVideoColorimetry value. So, that needs to be released after usage, in e.g. GST_DEBUG(). --- gst/vaapi/gstvaapisink.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index dbd8388d1f..7572c8e12b 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1282,7 +1282,13 @@ update_colorimetry (GstVaapiSink * sink, GstVideoColorimetry * cinfo) else sink->color_standard = 0; - GST_DEBUG ("colorimetry %s", gst_video_colorimetry_to_string (cinfo)); +#ifndef GST_DISABLE_GST_DEBUG + { + gchar *const colorimetry_string = gst_video_colorimetry_to_string (cinfo); + GST_DEBUG ("colorimetry %s", colorimetry_string); + g_free (colorimetry_string); + } +#endif #endif } From 98655a195fcacd649d51f1fd45c7ef9cc2d26fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 6 Mar 2015 12:16:17 +0200 Subject: [PATCH 1916/3781] vaapipostproc: always activate buffer pool The vaapipostproc has a proxy flag to know if the the buffer pool is already active. But this fails in some situations where it is needed to renegotiate the buffer pool. This patch removes that flag so the renegotiation is done whenever is required. https://bugzilla.gnome.org/show_bug.cgi?id=745535 --- gst/vaapi/gstvaapipostproc.c | 9 ++------- gst/vaapi/gstvaapipostproc.h | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index e5d563084a..75bc9fbde1 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -299,7 +299,6 @@ gst_vaapipostproc_destroy_filter (GstVaapiPostproc * postproc) } gst_vaapi_filter_replace (&postproc->filter, NULL); gst_vaapi_video_pool_replace (&postproc->filter_pool, NULL); - postproc->filter_pool_active = FALSE; } static void @@ -333,7 +332,6 @@ gst_vaapipostproc_stop (GstBaseTransform * trans) ds_reset (&postproc->deinterlace_state); gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (postproc)); - postproc->filter_pool_active = FALSE; postproc->field_duration = GST_CLOCK_TIME_NONE; gst_video_info_init(&postproc->sinkpad_info); @@ -388,11 +386,8 @@ create_output_buffer (GstVaapiPostproc * postproc) g_return_val_if_fail (pool != NULL, NULL); - if (!postproc->filter_pool_active) { - if (!gst_buffer_pool_set_active (pool, TRUE)) - goto error_activate_pool; - postproc->filter_pool_active = TRUE; - } + if (!gst_buffer_pool_set_active (pool, TRUE)) + goto error_activate_pool; outbuf = NULL; ret = gst_buffer_pool_acquire_buffer (pool, &outbuf, NULL); diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index aaa621019a..a74043d419 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -136,7 +136,6 @@ struct _GstVaapiPostproc GPtrArray *filter_ops; GstVaapiVideoPool *filter_pool; GstVideoInfo filter_pool_info; - gboolean filter_pool_active; GArray *filter_formats; GstVideoFormat format; /* output video format (encoded) */ guint width; From 2f8c1159e34ee3e3215b932a87a8fc8047bbe79e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 6 Mar 2015 14:09:22 +0200 Subject: [PATCH 1917/3781] vaapidecode: use the query virtual methods in 1.4 GstVideoDecoder, the base class of vaapidecode, added support for pad queries as virtual methods. This patch enables the use of that support, while keeping support for lower versions of gstreamer. This patch is important because GstVideoDecoder takes care of other queries that might be important in the pipeline managing. v2: 1) rebase to current master 2) fix indentation with gst-indent 3) simplify the patch layout 4) fix the context query 5) initialise the filter to NULL 6) improve the query log message for gst-1.2 https://bugzilla.gnome.org/show_bug.cgi?id=744406 --- gst/vaapi/gstvaapidecode.c | 175 ++++++++++++++++++++++++------------- 1 file changed, 116 insertions(+), 59 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9ae72a7c83..a8267c4dec 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -113,6 +113,11 @@ static gboolean gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, const GstVideoCodecState * new_state); +static gboolean +gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query); +static gboolean +gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query); + static void gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, const GstVideoCodecState * codec_state, gpointer user_data) @@ -844,6 +849,10 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->decide_allocation = GST_DEBUG_FUNCPTR (gst_vaapidecode_decide_allocation); #endif +#if GST_CHECK_VERSION(1,4,0) + vdec_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_src_query); + vdec_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_query); +#endif gst_element_class_set_static_metadata (element_class, "VA-API decoder", @@ -940,88 +949,134 @@ gst_vaapidecode_get_caps (GstPad * pad) return gst_caps_ref (decode->allowed_caps); } +#if !GST_CHECK_VERSION(1,4,0) static gboolean gst_vaapidecode_query (GST_PAD_QUERY_FUNCTION_ARGS) { GstVaapiDecode *const decode = GST_VAAPIDECODE (gst_pad_get_parent_element (pad)); - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (decode); + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); gboolean res; - GST_INFO_OBJECT (decode, "query type %s", GST_QUERY_TYPE_NAME (query)); + GST_INFO_OBJECT (decode, "query type %s on %s pad", + GST_QUERY_TYPE_NAME (query), GST_PAD_IS_SINK (pad) ? "sink" : "src"); + + if (GST_PAD_IS_SINK (pad)) + res = gst_vaapidecode_sink_query (vdec, query); + else + res = gst_vaapidecode_src_query (vdec, query); + + gst_object_unref (vdec); + return res; +} +#endif + +static gboolean +gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query) +{ + gboolean ret = TRUE; + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (decode); if (gst_vaapi_reply_to_query (query, plugin->display)) { - GST_DEBUG ("sharing display %p", plugin->display); - res = TRUE; - } else if (GST_PAD_IS_SINK (pad)) { - switch (GST_QUERY_TYPE (query)) { + GST_DEBUG_OBJECT (decode, "sharing display %p", plugin->display); + return TRUE; + } + + switch (GST_QUERY_TYPE (query)) { #if GST_CHECK_VERSION(1,0,0) - case GST_QUERY_CAPS:{ - GstCaps *filter, *caps = NULL; + case GST_QUERY_CAPS:{ + GstCaps *caps, *filter = NULL; + GstPad *pad = GST_VIDEO_DECODER_SINK_PAD (vdec); - gst_query_parse_caps (query, &filter); - caps = gst_vaapidecode_get_caps (pad); + gst_query_parse_caps (query, &filter); + caps = gst_vaapidecode_get_caps (pad); - if (filter) { - GstCaps *tmp = caps; - caps = gst_caps_intersect_full (filter, tmp, - GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (tmp); - } - - GST_DEBUG_OBJECT (decode, "Returning sink caps %" GST_PTR_FORMAT, caps); - - gst_query_set_caps_result (query, caps); - gst_caps_unref (caps); - res = TRUE; - break; + if (filter) { + GstCaps *tmp = caps; + caps = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (tmp); } -#endif - default: - res = GST_PAD_QUERY_FUNCTION_CALL (plugin->sinkpad_query, pad, - parent, query); - break; + + gst_query_set_caps_result (query, caps); + gst_caps_unref (caps); + break; } - } else { - switch (GST_QUERY_TYPE (query)) { -#if GST_CHECK_VERSION(1,0,0) - case GST_QUERY_CAPS:{ - GstCaps *filter, *caps = NULL; - - gst_query_parse_caps (query, &filter); - caps = gst_pad_get_pad_template_caps (pad); - - if (filter) { - GstCaps *tmp = caps; - caps = gst_caps_intersect_full (filter, tmp, - GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (tmp); - } - - GST_DEBUG_OBJECT (decode, "Returning src caps %" GST_PTR_FORMAT, caps); - - gst_query_set_caps_result (query, caps); - gst_caps_unref (caps); - res = TRUE; - break; - } #endif - default: - res = GST_PAD_QUERY_FUNCTION_CALL (plugin->srcpad_query, pad, - parent, query); - break; + default:{ +#if GST_CHECK_VERSION(1,4,0) + ret = GST_VIDEO_DECODER_CLASS (gst_vaapidecode_parent_class)->sink_query + (vdec, query); +#else + GstPad *pad = GST_VIDEO_DECODER_SINK_PAD (vdec); + GstObject *parent = gst_pad_get_parent (pad); + ret = GST_PAD_QUERY_FUNCTION_CALL (plugin->sinkpad_query, pad, parent, + query); + if (parent) + gst_object_unref (parent); +#endif + break; } } - gst_object_unref (decode); - return res; + return ret; +} + +static gboolean +gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) +{ + gboolean ret = TRUE; + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (decode); + + if (gst_vaapi_reply_to_query (query, plugin->display)) { + GST_DEBUG_OBJECT (decode, "sharing display %p", plugin->display); + return TRUE; + } + + switch (GST_QUERY_TYPE (query)) { +#if GST_CHECK_VERSION(1,0,0) + case GST_QUERY_CAPS:{ + GstCaps *caps, *filter = NULL; + GstPad *pad = GST_VIDEO_DECODER_SRC_PAD (vdec); + + gst_query_parse_caps (query, &filter); + caps = gst_pad_get_pad_template_caps (pad); + + if (filter) { + GstCaps *tmp = caps; + caps = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (tmp); + } + + gst_query_set_caps_result (query, caps); + gst_caps_unref (caps); + break; + } +#endif + default:{ +#if GST_CHECK_VERSION(1,4,0) + ret = GST_VIDEO_DECODER_CLASS (gst_vaapidecode_parent_class)->src_query + (vdec, query); +#else + GstPad *pad = GST_VIDEO_DECODER_SRC_PAD (vdec); + GstObject *parent = gst_pad_get_parent (pad); + ret = GST_PAD_QUERY_FUNCTION_CALL (plugin->sinkpad_query, pad, parent, + query); + if (parent) + gst_object_unref (parent); +#endif + break; + } + } + + return ret; } static void gst_vaapidecode_init (GstVaapiDecode * decode) { GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); - GstPad *pad; gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (decode), GST_CAT_DEFAULT); @@ -1034,8 +1089,9 @@ gst_vaapidecode_init (GstVaapiDecode * decode) gst_video_decoder_set_packetized (vdec, FALSE); +#if !GST_CHECK_VERSION(1,4,0) /* Pad through which data comes in to the element */ - pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD (decode); + GstPad *pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD (decode); gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_vaapidecode_query)); #if !GST_CHECK_VERSION(1,0,0) gst_pad_set_getcaps_function (pad, gst_vaapidecode_get_caps); @@ -1044,4 +1100,5 @@ gst_vaapidecode_init (GstVaapiDecode * decode) /* Pad through which data goes out of the element */ pad = GST_VAAPI_PLUGIN_BASE_SRC_PAD (decode); gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_vaapidecode_query)); +#endif } From 7e19e6a00a144a930a89cf738b92c52a81e4b4d0 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 6 Mar 2015 14:31:21 +0200 Subject: [PATCH 1918/3781] vaapidecode: clean-ups (indentation, drop unused variables) --- gst/vaapi/gstvaapidecode.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a8267c4dec..441607733a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -513,7 +513,6 @@ static GstFlowReturn gst_vaapidecode_finish (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - GstFlowReturn ret = GST_FLOW_OK; if (!decode->decoder) return GST_FLOW_OK; @@ -605,8 +604,8 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) alignment = GST_VAAPI_STREAM_ALIGN_H264_NALU; else alignment = GST_VAAPI_STREAM_ALIGN_H264_NONE; - gst_vaapi_decoder_h264_set_alignment (GST_VAAPI_DECODER_H264 (decode-> - decoder), alignment); + gst_vaapi_decoder_h264_set_alignment (GST_VAAPI_DECODER_H264 + (decode->decoder), alignment); } } break; @@ -662,7 +661,6 @@ gst_vaapidecode_reset_full (GstVaapiDecode * decode, GstCaps * caps, /* Reset timers if hard reset was requested (e.g. seek) */ if (hard) { - GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); GstVideoCodecFrame *out_frame = NULL; gst_vaapi_decoder_flush (decode->decoder); From 8f56b758b6a3d6e742a97e8551c16605eb57e5aa Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Fri, 6 Mar 2015 15:20:01 +0200 Subject: [PATCH 1919/3781] vaapidecode: Don't crash if a buffer outlives the decoder Sometimes, for example, when switching video streams but keeping the same sink, the surface will be released after the decoder is stopped and replaced. This caused a crash because the release callback was called on an invalid pointer. The patch adding an additional reference to the decoder object in the buffer. https://bugzilla.gnome.org/show_bug.cgi?id=745189 Signed-off-by: Olivier Crete Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapidecode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 441607733a..a773428d6c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -253,6 +253,7 @@ gst_vaapidecode_release (GstVaapiDecode * decode) g_mutex_lock (&decode->surface_ready_mutex); g_cond_signal (&decode->surface_ready); g_mutex_unlock (&decode->surface_ready_mutex); + gst_object_unref (decode); } static GstFlowReturn @@ -272,7 +273,7 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, proxy = gst_video_codec_frame_get_user_data (out_frame); gst_vaapi_surface_proxy_set_destroy_notify (proxy, - (GDestroyNotify) gst_vaapidecode_release, decode); + (GDestroyNotify) gst_vaapidecode_release, gst_object_ref (decode)); #if GST_CHECK_VERSION(1,0,0) ret = gst_video_decoder_allocate_output_frame (vdec, out_frame); @@ -645,7 +646,7 @@ gst_vaapidecode_destroy (GstVaapiDecode * decode) decode->active = FALSE; - gst_vaapidecode_release (decode); + gst_vaapidecode_release (gst_object_ref (decode)); } static gboolean From 200b1baabc066f8a4102f82f539655d588200ec9 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Sat, 14 Mar 2015 22:12:19 +0200 Subject: [PATCH 1920/3781] vaapidisplay: mark X11 display as compatible with EGL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GST_GL_WINDOW=x11 GST_GL_API=gles2 GST_GL_PLATFORM=egl gst-launch-1.0 ... ! vaapidecode ! glimagesink https://bugzilla.gnome.org/show_bug.cgi?id=745902 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapidisplay.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 3fe523bb84..44b6f00a1f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -205,6 +205,10 @@ gst_vaapi_display_type_is_compatible (GstVaapiDisplayType type1, if (type2 == GST_VAAPI_DISPLAY_TYPE_X11) return TRUE; break; + case GST_VAAPI_DISPLAY_TYPE_X11: + if (type2 == GST_VAAPI_DISPLAY_TYPE_EGL) + return TRUE; + break; default: break; } From ccccbf4b09c952306a154d343bf3b00722d43da7 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Sun, 15 Mar 2015 00:36:45 +0200 Subject: [PATCH 1921/3781] gitmodules: Use https:// url instead of git:// for submodules. Gitorious is failing to clone repositories over git:// url. --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index b4b4ef78dd..ac8df86ae7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ [submodule "ext/codecparsers"] path = ext/codecparsers - url = git://gitorious.org/vaapi/gstreamer-codecparsers.git + url = https://gitorious.org/vaapi/gstreamer-codecparsers.git [submodule "ext/videoutils"] path = ext/videoutils - url = git://gitorious.org/vaapi/gstreamer-videoutils.git + url = https://gitorious.org/vaapi/gstreamer-videoutils.git [submodule "ext/libvpx/upstream"] path = ext/libvpx/upstream url = https://chromium.googlesource.com/webm/libvpx From d8d2f00bd031ccce1eae80e0c38918eb25b768e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 16 Mar 2015 23:10:53 +0200 Subject: [PATCH 1922/3781] vaapidecode: call the correct query function In commit 2f8c115 (vaapidecode: use the query virtual methods in 1.4) a bug was introduced: when calling the parent's query function of the src pad, the one of the sink pad is called instead. This patch fixes this issue. https://bugzilla.gnome.org/show_bug.cgi?id=746248 --- gst/vaapi/gstvaapidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a773428d6c..164aae3399 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1060,7 +1060,7 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) #else GstPad *pad = GST_VIDEO_DECODER_SRC_PAD (vdec); GstObject *parent = gst_pad_get_parent (pad); - ret = GST_PAD_QUERY_FUNCTION_CALL (plugin->sinkpad_query, pad, parent, + ret = GST_PAD_QUERY_FUNCTION_CALL (plugin->srcpad_query, pad, parent, query); if (parent) gst_object_unref (parent); From 1bd810fe99a29c869230e69ff31730e92bec9f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 16 Mar 2015 23:36:33 +0200 Subject: [PATCH 1923/3781] vaapidecode: handle flush() vmethod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since GStreamer 1.2 the vmethod reset() in GstVideoDecoderClass was deprecated and flush() was added. This patch set the vmethod flush() if the installed GStreamer version is 1.2 or superior. Otherwise, reset() is set. v2: 1) In order to avoid symbol collision, the old method gst_vaapidecode_flush() was renamed to gst_vaapidecode_internal_flush(). 2) The new vmethod flush() always do a hard full reset. v3: 1) Call gst_vaapidecode_internal_flush() first in flush() vmethod, in order to gather all collected data with gst_video_decoder_have_frame() https://bugzilla.gnome.org/show_bug.cgi?id=742922 Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapidecode.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 164aae3399..e1c9126fce 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -482,7 +482,7 @@ not_negotiated: } static gboolean -gst_vaapidecode_flush (GstVideoDecoder * vdec) +gst_vaapidecode_internal_flush (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstVaapiDecoderStatus status; @@ -518,7 +518,7 @@ gst_vaapidecode_finish (GstVideoDecoder * vdec) if (!decode->decoder) return GST_FLOW_OK; - if (!gst_vaapidecode_flush (vdec)) { + if (!gst_vaapidecode_internal_flush (vdec)) { gst_vaapidecode_push_all_decoded_frames (decode); return GST_FLOW_ERROR; } @@ -736,16 +736,31 @@ gst_vaapidecode_close (GstVideoDecoder * vdec) return TRUE; } +#if GST_CHECK_VERSION(1,2,0) +static gboolean +gst_vaapidecode_flush (GstVideoDecoder * vdec) +{ + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + + if (decode->decoder && !gst_vaapidecode_internal_flush (vdec)) + return FALSE; + + /* There could be issues if we avoid the reset_full() while doing + * seeking: we have to reset the internal state */ + return gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, TRUE); +} +#else static gboolean gst_vaapidecode_reset (GstVideoDecoder * vdec, gboolean hard) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); /* In GStreamer 1.0 context, this means a flush */ - if (decode->decoder && !hard && !gst_vaapidecode_flush (vdec)) + if (decode->decoder && !hard && !gst_vaapidecode_internal_flush (vdec)) return FALSE; return gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, hard); } +#endif static gboolean gst_vaapidecode_set_format (GstVideoDecoder * vdec, GstVideoCodecState * state) @@ -839,7 +854,11 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->open = GST_DEBUG_FUNCPTR (gst_vaapidecode_open); vdec_class->close = GST_DEBUG_FUNCPTR (gst_vaapidecode_close); vdec_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapidecode_set_format); +#if GST_CHECK_VERSION(1,2,0) + vdec_class->flush = GST_DEBUG_FUNCPTR (gst_vaapidecode_flush); +#else vdec_class->reset = GST_DEBUG_FUNCPTR (gst_vaapidecode_reset); +#endif vdec_class->parse = GST_DEBUG_FUNCPTR (gst_vaapidecode_parse); vdec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapidecode_handle_frame); vdec_class->finish = GST_DEBUG_FUNCPTR (gst_vaapidecode_finish); From 49606b8d2547e7ea1d7e805f9b55b30e821f7af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 16 Mar 2015 23:37:29 +0200 Subject: [PATCH 1924/3781] vaapidecode: remove vmethod reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since in bug #745728 the support for GStreamer 1.0 is going to be dropped, this patch removes the method reset() which was deprecated in GStreamer 1.2. https://bugzilla.gnome.org/show_bug.cgi?id=742922 Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapidecode.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index e1c9126fce..95319bbcc4 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -736,7 +736,6 @@ gst_vaapidecode_close (GstVideoDecoder * vdec) return TRUE; } -#if GST_CHECK_VERSION(1,2,0) static gboolean gst_vaapidecode_flush (GstVideoDecoder * vdec) { @@ -749,18 +748,6 @@ gst_vaapidecode_flush (GstVideoDecoder * vdec) * seeking: we have to reset the internal state */ return gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, TRUE); } -#else -static gboolean -gst_vaapidecode_reset (GstVideoDecoder * vdec, gboolean hard) -{ - GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - - /* In GStreamer 1.0 context, this means a flush */ - if (decode->decoder && !hard && !gst_vaapidecode_internal_flush (vdec)) - return FALSE; - return gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, hard); -} -#endif static gboolean gst_vaapidecode_set_format (GstVideoDecoder * vdec, GstVideoCodecState * state) @@ -854,11 +841,7 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->open = GST_DEBUG_FUNCPTR (gst_vaapidecode_open); vdec_class->close = GST_DEBUG_FUNCPTR (gst_vaapidecode_close); vdec_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapidecode_set_format); -#if GST_CHECK_VERSION(1,2,0) vdec_class->flush = GST_DEBUG_FUNCPTR (gst_vaapidecode_flush); -#else - vdec_class->reset = GST_DEBUG_FUNCPTR (gst_vaapidecode_reset); -#endif vdec_class->parse = GST_DEBUG_FUNCPTR (gst_vaapidecode_parse); vdec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapidecode_handle_frame); vdec_class->finish = GST_DEBUG_FUNCPTR (gst_vaapidecode_finish); From 71d91c77163036ee30d5aac68b7c3797bba943a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 16 Mar 2015 23:38:18 +0200 Subject: [PATCH 1925/3781] vaapidecode: add drain() vmethod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In GStremer v1.6 a new vmethod drain() was added in GstVideoDecoder class. This patch implements this new method. https://bugzilla.gnome.org/show_bug.cgi?id=742922 Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapidecode.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 95319bbcc4..04851f43b2 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -481,6 +481,19 @@ not_negotiated: } } +#if GST_CHECK_VERSION(1,5,0) +static GstFlowReturn +gst_vaapidecode_drain (GstVideoDecoder * vdec) +{ + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + + if (!decode->decoder) + return GST_FLOW_NOT_NEGOTIATED; + + return gst_vaapidecode_push_all_decoded_frames (decode); +} +#endif + static gboolean gst_vaapidecode_internal_flush (GstVideoDecoder * vdec) { @@ -845,6 +858,9 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->parse = GST_DEBUG_FUNCPTR (gst_vaapidecode_parse); vdec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapidecode_handle_frame); vdec_class->finish = GST_DEBUG_FUNCPTR (gst_vaapidecode_finish); +#if GST_CHECK_VERSION(1,5,0) + vdec_class->drain = GST_DEBUG_FUNCPTR (gst_vaapidecode_drain); +#endif #if GST_CHECK_VERSION(1,0,0) vdec_class->decide_allocation = From 0311c7c8af6bcab9f5ea38c39d80556ef9e34803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 16:54:54 +0300 Subject: [PATCH 1926/3781] autotools: remove gstreamer-0.10 support This patch only removes the support of gstreamer-0.10 in the autotools scripts. No other files are touched. The configuration parameter --gstreamer-api was deleted since now it is always auto-detected. The verification of vmethod query in GstBaseSinkClass was removed since it was added in gstreamer 0.10.35. The same case for GstVideoOverlayComposition and its format flags. The precious variable GST_PLUGIN_PATH was removed, while GST_PLUGIN_PATH_1_0 remained. The automake files were changed accordingly. Removed, in debian/control, the vaapiupload and vaapidownload descriptions. https://bugzilla.gnome.org/show_bug.cgi?id=732666 https://bugzilla.gnome.org/show_bug.cgi?id=745728 Signed-off-by: Gwenole Beauchesne --- configure.ac | 138 +++------------------------------ debian.upstream/control.in | 2 - gst-libs/gst/video/Makefile.am | 5 -- gst/vaapi/Makefile.am | 17 ---- 4 files changed, 12 insertions(+), 150 deletions(-) diff --git a/configure.ac b/configure.ac index 529d0f8764..92e8bdb18e 100644 --- a/configure.ac +++ b/configure.ac @@ -27,9 +27,6 @@ m4_define([glib_version], [2.28]) # gstreamer version number m4_define([gst_api_version], [autodetect]) -m4_define([gst0_version], [0.10.36]) -m4_define([gst0_plugins_base_version], [0.10.31]) -m4_define([gst0_plugins_bad_version], [0.10.22]) m4_define([gst1_version], [1.0.0]) m4_define([gst1_plugins_base_version], [1.0.0]) m4_define([gst1_plugins_bad_version], [1.0.0]) @@ -160,12 +157,6 @@ AC_ARG_WITH([glapi], [build with the specified OpenGL APIs @<:@default=default_glapi@:>@]), [GLAPI="$with_glapi"], [GLAPI=default_glapi]) -AC_ARG_WITH([gstreamer-api], - AC_HELP_STRING([--with-gstreamer-api=VERSION], - [build against the specified GStreamer API version - @<:@default=gst_api_version@:>@]), - [GST_API_VERSION="$with_gstreamer_api"], [GST_API_VERSION=gst_api_version]) - dnl Check for basic libraries AC_CHECK_LIB(m, tan) @@ -191,30 +182,16 @@ AC_SUBST([DLOPEN_LIBS]) dnl --------------------------------------------------------------------------- dnl -- GStreamer -- dnl --------------------------------------------------------------------------- - -dnl If GStreamer API version is to be autodetected, then always try -dnl with the latest version first AC_MSG_CHECKING([for GStreamer API version]) -if test "$GST_API_VERSION" = "autodetect"; then - gst_pkg_versions="1.0 0.10" -else - AS_VERSION_COMPARE([$GST_API_VERSION], [1.0], - [gst_pkg_versions="0.10"], [gst_pkg_versions="1.0"], - dnl GStreamer 1.2.x and 1.4.x APIs don't have their own namespace - [gst_pkg_versions="1.0"]) +if $PKG_CONFIG --exists "gstreamer-1.0"; then + gst_version=`$PKG_CONFIG --modversion "gstreamer-1.0"` + gst_major_version=`echo "$gst_version" | cut -d'.' -f1` + gst_minor_version=`echo "$gst_version" | cut -d'.' -f2` + GST_API_VERSION="${gst_major_version}.${gst_minor_version}" + GST_PKG_VERSION="1.0" fi -for gst_pkg_version in ${gst_pkg_versions}; do - if $PKG_CONFIG --exists "gstreamer-$gst_pkg_version"; then - gst_version=`$PKG_CONFIG --modversion "gstreamer-$gst_pkg_version"` - gst_major_version=`echo "$gst_version" | cut -d'.' -f1` - gst_minor_version=`echo "$gst_version" | cut -d'.' -f2` - GST_API_VERSION="${gst_major_version}.${gst_minor_version}" - GST_PKG_VERSION="$gst_pkg_version" - break - fi -done if test -z "$GST_PKG_VERSION"; then - AC_MSG_ERROR([version $GST_API_VERSION not found]) + AC_MSG_ERROR([gstreamer-$GST_PKG_VERSION was not found]) fi AC_MSG_RESULT([$GST_API_VERSION]) @@ -223,11 +200,6 @@ AC_DEFINE_UNQUOTED([GST_API_VERSION_S], ["$GST_API_VERSION"], dnl Versions for GStreamer and plugins-base case $GST_API_VERSION in -0.10) - GST_VERSION_REQUIRED=gst0_version - GST_PLUGINS_BASE_VERSION_REQUIRED=gst0_plugins_base_version - GST_PLUGINS_BAD_VERSION_REQUIRED=gst0_plugins_bad_version - ;; 1.0) GST_VERSION_REQUIRED=gst1_version GST_PLUGINS_BASE_VERSION_REQUIRED=gst1_plugins_base_version @@ -257,41 +229,26 @@ AC_SUBST(GST_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED) -USE_GST_API_0_10="no" USE_GST_API_1_0p="no" USE_GST_API_1_2p="no" USE_GST_API_1_4p="no" -AS_VERSION_COMPARE([$GST_API_VERSION], [0.10], - [], [USE_GST_API_0_10="yes"], []) AS_VERSION_COMPARE([$GST_API_VERSION], [1.0], [], [USE_GST_API_1_0p="yes"], [USE_GST_API_1_0p="yes"]) AS_VERSION_COMPARE([$GST_API_VERSION], [1.2], [], [USE_GST_API_1_2p="yes"], [USE_GST_API_1_2p="yes"]) AS_VERSION_COMPARE([$GST_API_VERSION], [1.4], [], [USE_GST_API_1_4p="yes"], [USE_GST_API_1_4p="yes"]) -AM_CONDITIONAL([USE_GST_API_0_10], [test "$USE_GST_API_0_10" = "yes"]) AM_CONDITIONAL([USE_GST_API_1_0p], [test "$USE_GST_API_1_0p" = "yes"]) AM_CONDITIONAL([USE_GST_API_1_2p], [test "$USE_GST_API_1_2p" = "yes"]) AM_CONDITIONAL([USE_GST_API_1_4p], [test "$USE_GST_API_1_4p" = "yes"]) -dnl GStreamer 1.2.x and 1.4.x APIs don't have their own namespace -GST_PKG_VERSION="$GST_API_VERSION" -if test "$USE_GST_API_1_2p" = "yes" || test "$USE_GST_API_1_4p" = "yes" ; then - GST_PKG_VERSION="1.0" -fi AC_SUBST([GST_PKG_VERSION]) AC_DEFINE_UNQUOTED([GST_PKG_VERSION_S], ["$GST_PKG_VERSION"], [Defined to the string representation of GStreamer API version]) dnl Validate certain features -if test "$USE_GST_API_0_10" = "yes"; then - AC_MSG_WARN([support for GStreamer 0.10 is obsolete, and will be removed]) - if test "$enable_builtin_videoparsers" = "yes"; then - AC_MSG_WARN([disabled built-in videoparsers (unsupported)]) - enable_builtin_videoparsers="no" - fi -elif test "$GST_API_VERSION" = "1.0"; then +if test "$GST_API_VERSION" = "1.0"; then AC_MSG_WARN([support for GStreamer 1.0 is obsolete, and will be removed]) fi @@ -301,25 +258,6 @@ PKG_CHECK_MODULES([GST], PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) -AC_CACHE_CHECK([for GstBaseSink::query hook], ac_cv_have_gst_base_sink_query, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_BASE_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $GST_BASE_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[GstBaseSinkClass klass; klass.query = NULL;]])], - [ac_cv_have_gst_base_sink_query="yes"], - [ac_cv_have_gst_base_sink_query="no"] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" -]) -if test "$ac_cv_have_gst_base_sink_query" != "yes"; then - AC_MSG_ERROR([GstBaseSink does not contain the 'query' vfunc]) -fi - dnl GStreamer -base plugins PKG_CHECK_MODULES([GST_PLUGINS_BASE], [gstreamer-plugins-base-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) @@ -336,54 +274,8 @@ dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], [gstreamer-video-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) -AC_CACHE_CHECK([for GstVideoOverlayComposition], - ac_cv_have_gst_video_overlay_composition, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_VIDEO_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $GST_LIBS $GST_VIDEO_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[GstVideoOverlayComposition *c; - c = gst_video_overlay_composition_new(0);]])], - [ac_cv_have_gst_video_overlay_composition="yes"], - [ac_cv_have_gst_video_overlay_composition="no"] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" -]) -if test "$ac_cv_have_gst_video_overlay_composition" != "yes"; then - AC_MSG_ERROR([GstVideoOverlayComposition is not available]) -fi - -AC_CACHE_CHECK([... with advanced format flags], - ac_cv_have_gst_video_overlay_hwcaps, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_VIDEO_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $GST_LIBS $GST_VIDEO_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[GstVideoOverlayRectangle *rect; - const guint w = 64, h = 64; - guint flags = ( - GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA| - GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA); - rect = gst_video_overlay_rectangle_new_argb(NULL, w, h, w * 4, - 0, 0, w, h, flags); - gst_video_overlay_rectangle_set_global_alpha(rect, 0.5f);]])], - [ac_cv_have_gst_video_overlay_hwcaps="yes"], - [ac_cv_have_gst_video_overlay_hwcaps="no"] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" -]) -if test "$ac_cv_have_gst_video_overlay_hwcaps" = "yes"; then - AC_DEFINE_UNQUOTED([HAVE_GST_VIDEO_OVERLAY_HWCAPS], 1, - [Defined to 1 if GstVideoOverlayComposition API supports HW hints.]) -fi +AC_DEFINE_UNQUOTED([HAVE_GST_VIDEO_OVERLAY_HWCAPS], 1, + [Defined to 1 if GstVideoOverlayComposition API supports HW hints.]) dnl GStreamer -bad plugins (deprecated in GStreamer v1.2) if test "$USE_GST_API_1_2p" != "yes" && test "$USE_GST_API_1_4p" != "yes"; then @@ -541,7 +433,6 @@ if test "$enable_egl" = "yes" -a $HAVE_GSTGL -ne 1; then fi case $GST_API_VERSION in -0.10) lt_bias=gst0_vaapi_lt_current_bias;; 1.0) lt_bias=gst1_vaapi_lt_current_bias;; 1.2) lt_bias=gst2_vaapi_lt_current_bias;; 1.4) lt_bias=gst4_vaapi_lt_current_bias;; @@ -575,15 +466,10 @@ GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^([_]*gst_plug AC_SUBST(GST_PLUGIN_LDFLAGS) dnl Check for the GStreamer plugins directory -AC_ARG_VAR([GST_PLUGIN_PATH], [installation path for gstreamer-vaapi plugin elements for GStreamer 0.10]) AC_ARG_VAR([GST_PLUGIN_PATH_1_0], [installation path for gstreamer-vaapi plugin elements for GStreamer 1.0]) AC_MSG_CHECKING([for GStreamer plugins directory]) -case $GST_PKG_VERSION in -0.10) _gst_plugin_path="$GST_PLUGIN_PATH";; -1.0) _gst_plugin_path="$GST_PLUGIN_PATH_1_0";; -esac -if test -d "$_gst_plugin_path"; then - GST_PLUGINS_DIR="$_gst_plugin_path" +if test -d "$GST_PLUGIN_PATH_1_0"; then + GST_PLUGINS_DIR="$GST_PLUGIN_PATH_1_0" else GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_PKG_VERSION --variable pluginsdir` if test -z "$GST_PLUGINS_DIR"; then diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 0c1fadcdf4..932dc6867b 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -26,8 +26,6 @@ Description: VA-API plugins for GStreamer - `vaapidecode': decode bitstreams using VA-API @USE_ENCODERS_TRUE@ - `vaapiencode_mpeg2': encode bitstreams using VA-API (MPEG-2 codec) @USE_ENCODERS_TRUE@ - `vaapiencode_h264': encode bitstreams using VA-API (H.264 codec) -@USE_GST_API_0_10_TRUE@ - `vaapiupload': convert from YUV pixels to VA surfaces -@USE_GST_API_0_10_TRUE@ - `vaapidownload': convert from VA surfaces to YUV pixels - `vaapipostproc': postprocess VA surfaces, e.g. for deinterlacing - `vaapisink': a VA-API based video sink diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index d890cae07e..33fea30730 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -21,11 +21,6 @@ libgstvaapi_videoutils_libs = \ gen_source_c = gen_source_h = -if USE_GST_API_0_10 -gen_source_c += gstvideodecoder.c gstvideoencoder.c gstvideoutils.c video.c -gen_source_h += gstvideodecoder.h gstvideoencoder.h gstvideoutils.h video.h -endif - GENFILES = \ $(gen_source_c) \ $(gen_source_h) \ diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 69fb6bf5a6..30d61558ef 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -159,21 +159,6 @@ libgstvaapi_source_c += $(libgstvaapi_1_0p_source_c) libgstvaapi_source_h += $(libgstvaapi_1_0p_source_h) endif -libgstvaapi_0_10_source_c = \ - gstvaapidownload.c \ - gstvaapiupload.c \ - $(NULL) - -libgstvaapi_0_10_source_h = \ - gstvaapidownload.h \ - gstvaapiupload.h \ - $(NULL) - -if USE_GST_API_0_10 -libgstvaapi_source_c += $(libgstvaapi_0_10_source_c) -libgstvaapi_source_h += $(libgstvaapi_0_10_source_h) -endif - libgstvaapi_la_SOURCES = $(libgstvaapi_source_c) noinst_HEADERS = $(libgstvaapi_source_h) @@ -285,8 +270,6 @@ EXTRA_DIST = \ $(libgstvaapi_1_2p_source_h) \ $(libgstvaapi_1_0p_source_c) \ $(libgstvaapi_1_0p_source_h) \ - $(libgstvaapi_0_10_source_c) \ - $(libgstvaapi_0_10_source_h) \ $(libgstvaapi_parse_source_c) \ $(libgstvaapi_parse_source_h) \ $(NULL) From d256f1d283066a87f2930a40770d3dca8336a8d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 16:55:27 +0300 Subject: [PATCH 1927/3781] Removal of gstreamer-0.10 support This patch removes all the pre-processor conditional code compilation guarded for gstreamer-0.10. https://bugzilla.gnome.org/show_bug.cgi?id=745728 https://bugzilla.gnome.org/show_bug.cgi?id=732666 Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstcompat.h | 280 --------- gst-libs/gst/vaapi/gstvaapicontext_overlay.c | 5 - gst-libs/gst/vaapi/gstvaapidecoder.c | 15 - gst-libs/gst/vaapi/gstvaapiimage.c | 47 -- gst-libs/gst/vaapi/gstvaapisubpicture.c | 14 +- gst-libs/gst/vaapi/video-format.c | 49 -- gst-libs/gst/vaapi/video-format.h | 3 - gst/vaapi/gstvaapi.c | 18 - gst/vaapi/gstvaapidecode.c | 25 - gst/vaapi/gstvaapidecodebin.c | 2 - gst/vaapi/gstvaapidownload.c | 585 ------------------- gst/vaapi/gstvaapidownload.h | 67 --- gst/vaapi/gstvaapiencode.c | 29 - gst/vaapi/gstvaapiencode_h264.c | 8 - gst/vaapi/gstvaapiencode_jpeg.c | 4 - gst/vaapi/gstvaapiencode_mpeg2.c | 8 - gst/vaapi/gstvaapiencode_vp8.c | 4 - gst/vaapi/gstvaapiparse.c | 8 - gst/vaapi/gstvaapipluginbase.c | 57 -- gst/vaapi/gstvaapipluginbase.h | 4 - gst/vaapi/gstvaapipluginutil.c | 43 -- gst/vaapi/gstvaapipluginutil.h | 9 - gst/vaapi/gstvaapipostproc.c | 62 +- gst/vaapi/gstvaapisink.c | 54 -- gst/vaapi/gstvaapiupload.c | 445 -------------- gst/vaapi/gstvaapiupload.h | 77 --- gst/vaapi/gstvaapiuploader.c | 4 - gst/vaapi/gstvaapivideobuffer.c | 88 +-- gst/vaapi/gstvaapivideoconverter_glx.c | 5 - gst/vaapi/gstvaapivideoconverter_x11.c | 7 - gst/vaapi/gstvaapivideometa.c | 88 +-- gst/vaapi/gstvaapivideometa.h | 2 - tests/test-filter.c | 2 +- tests/test-subpicture.c | 6 - 34 files changed, 6 insertions(+), 2118 deletions(-) delete mode 100644 gst/vaapi/gstvaapidownload.c delete mode 100644 gst/vaapi/gstvaapidownload.h delete mode 100644 gst/vaapi/gstvaapiupload.c delete mode 100644 gst/vaapi/gstvaapiupload.h diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h index 9abc2fd37f..ad5a1724a4 100644 --- a/gst-libs/gst/vaapi/gstcompat.h +++ b/gst-libs/gst/vaapi/gstcompat.h @@ -25,11 +25,6 @@ #include -/* ------------------------------------------------------------------------ */ -/* --- GStreamer >= 1.0 --- */ -/* ------------------------------------------------------------------------ */ - -#if GST_CHECK_VERSION(1,0,0) #include /* GstStructure */ @@ -73,279 +68,4 @@ typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, GstCaps *); #define GST_MAKE_FORMAT_STRING(FORMAT) \ "format=(string)" G_STRINGIFY(FORMAT) -/* ------------------------------------------------------------------------ */ -/* --- GStreamer = 0.10 --- */ -/* ------------------------------------------------------------------------ */ - -#else - -/* GstMemory */ -typedef enum { - GST_MEMORY_FLAG_READONLY = GST_MINI_OBJECT_FLAG_READONLY -} GstMemoryFlags; - -typedef enum { - GST_BUFFER_COPY_META = GST_BUFFER_COPY_QDATA, - GST_BUFFER_COPY_MEMORY = 0, -} GstBufferCopyFlags1_0; - -typedef enum { - GST_MAP_READ = 1 << 0, - GST_MAP_WRITE = 1 << 1 -} GstMapFlags; - -typedef struct { - GstMapFlags flags; - guint8 *data; - gsize size; -} GstMapInfo; - -/* GstBuffer */ -#undef gst_buffer_new_wrapped -#define gst_buffer_new_wrapped(data, size) \ - gst_compat_buffer_new_wrapped_full(0, data, size, 0, size, data, g_free) -#undef gst_buffer_new_wrapped_full -#define gst_buffer_new_wrapped_full(flags, data, maxsize, ofs, size, ud, udd) \ - gst_compat_buffer_new_wrapped_full(flags, data, maxsize, ofs, size, ud, udd) -#undef gst_buffer_new_allocate -#define gst_buffer_new_allocate(allocator, size, params) \ - gst_compat_buffer_new_allocate((allocator), (size), (params)) -#undef gst_buffer_get_size -#define gst_buffer_get_size(buffer) gst_compat_buffer_get_size(buffer) -#undef gst_buffer_map -#define gst_buffer_map(buffer, mip, f) gst_compat_buffer_map(buffer, mip, f) -#undef gst_buffer_unmap -#define gst_buffer_unmap(buffer, mip) gst_compat_buffer_unmap(buffer, mip) -#undef gst_buffer_extract -#define gst_buffer_extract(buffer, offset, dest, size) \ - gst_compat_buffer_extract(buffer, offset, dest, size) -#undef gst_buffer_fill -#define gst_buffer_fill(buffer, offset, src, size) \ - gst_compat_buffer_fill((buffer), (offset), (src), (size)) -#undef gst_buffer_copy_into -#define gst_buffer_copy_into(dest, src, flags, offset, size) \ - gst_compat_buffer_copy_into(dest, src, flags, offset, size) - -static inline GstBuffer * -gst_compat_buffer_new_wrapped_full(GstMemoryFlags flags, gpointer data, - gsize maxsize, gsize offset, gsize size, gpointer user_data, - GDestroyNotify notify) -{ - GstBuffer *buffer; - - /* XXX: unsupported */ - g_return_val_if_fail(maxsize >= size, NULL); - - buffer = gst_buffer_new(); - if (!buffer) - return NULL; - - GST_BUFFER_DATA(buffer) = data + offset; - GST_BUFFER_SIZE(buffer) = size; - - if (notify) - gst_mini_object_weak_ref(GST_MINI_OBJECT_CAST(buffer), - (GstMiniObjectWeakNotify)notify, user_data); - return buffer; -} - -static inline GstBuffer * -gst_compat_buffer_new_allocate(gpointer allocator, gsize size, gpointer params) -{ - /* XXX: unsupported */ - g_return_val_if_fail(allocator == NULL, NULL); - g_return_val_if_fail(params == NULL, NULL); - - return gst_buffer_new_and_alloc(size); -} - -static inline gsize -gst_compat_buffer_get_size(GstBuffer *buffer) -{ - return GST_BUFFER_SIZE(buffer); -} - -static inline gboolean -gst_compat_buffer_map(GstBuffer *buffer, GstMapInfo *mip, GstMapFlags flags) -{ - mip->flags = flags; - mip->data = GST_BUFFER_DATA(buffer); - mip->size = GST_BUFFER_SIZE(buffer); - return TRUE; -} - -static inline void -gst_compat_buffer_unmap(GstBuffer *buffer, GstMapInfo *mip) -{ -} - -static inline gsize -gst_compat_buffer_extract(GstBuffer *buffer, gsize offset, gpointer dest, - gsize size) -{ - gsize esize; - - if (!buffer || !dest || offset >= GST_BUFFER_SIZE(buffer)) - return 0; - - esize = MIN(size, GST_BUFFER_SIZE(buffer) - offset); - memcpy(dest, GST_BUFFER_DATA(buffer) + offset, esize); - return esize; -} - -static inline gsize -gst_compat_buffer_fill(GstBuffer *buffer, gsize offset, gconstpointer src, - gsize size) -{ - gsize fsize; - - if (!buffer || !src || offset >= GST_BUFFER_SIZE(buffer)) - return 0; - - fsize = MIN(size, GST_BUFFER_SIZE(buffer) - offset); - memcpy(GST_BUFFER_DATA(buffer) + offset, src, fsize); - return fsize; -} - -static inline void -gst_compat_buffer_copy_into(GstBuffer *dest, GstBuffer *src, - GstBufferCopyFlags flags, gsize offset, gsize size) -{ - g_return_if_fail(offset == 0); - g_return_if_fail(size == (gsize)-1); - - gst_buffer_copy_metadata(dest, src, flags); -} - -/* GstAdapter */ -#include - -#undef gst_adapter_map -#define gst_adapter_map(adapter, size) gst_compat_adapter_map(adapter, size) -#undef gst_adapter_unmap -#define gst_adapter_unmap(adapter) gst_compat_adapter_unmap(adapter) - -static inline gconstpointer -gst_compat_adapter_map(GstAdapter *adapter, gsize size) -{ - return gst_adapter_peek(adapter, size); -} - -static inline void -gst_compat_adapter_unmap(GstAdapter *adapter) -{ -} - -/* GstCaps */ -#undef gst_caps_merge -#define gst_caps_merge(caps1, caps2) gst_compat_caps_merge(caps1, caps2) -#undef gst_caps_merge_structure -#define gst_caps_merge_structure(caps, structure) \ - gst_compat_caps_merge_structure(caps, structure) - -static inline GstCaps * -gst_compat_caps_merge(GstCaps *caps1, GstCaps *caps2) -{ - (gst_caps_merge)(caps1, caps2); - return caps1; -} - -static inline GstCaps * -gst_compat_caps_merge_structure(GstCaps *caps, GstStructure *structure) -{ - (gst_caps_merge_structure)(caps, structure); - return caps; -} - -/* GstVideoOverlayComposition */ -#include - -#undef gst_video_overlay_rectangle_get_pixels_unscaled_raw -#define gst_video_overlay_rectangle_get_pixels_unscaled_raw(rect, flags) \ - gst_compat_video_overlay_rectangle_get_pixels_unscaled_raw(rect, flags) - -#ifndef HAVE_GST_VIDEO_OVERLAY_HWCAPS -#define gst_video_overlay_rectangle_get_flags(rect) (0) -#define gst_video_overlay_rectangle_get_global_alpha(rect) (1.0f) -#endif - -static inline GstBuffer * -gst_compat_video_overlay_rectangle_get_pixels_unscaled_raw( - GstVideoOverlayRectangle *rect, GstVideoOverlayFormatFlags flags) -{ - guint width, height, stride; - - /* Try to retrieve the original buffer that was passed to - gst_video_overlay_rectangle_new_argb(). This will only work if - there was no previous user that required pixels with non native - alpha type */ - return gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect, - &width, &height, &stride, flags); -} - -typedef enum { - GST_VIDEO_BUFFER_FLAG_TFF = GST_VIDEO_BUFFER_TFF, - GST_VIDEO_BUFFER_FLAG_RFF = GST_VIDEO_BUFFER_RFF, - GST_VIDEO_BUFFER_FLAG_ONEFIELD = GST_VIDEO_BUFFER_ONEFIELD -} GstVideoBufferFlags; - -/* GstPad */ -#undef GST_FLOW_EOS -#define GST_FLOW_EOS GST_FLOW_UNEXPECTED -#undef GST_FLOW_FLUSHING -#define GST_FLOW_FLUSHING GST_FLOW_WRONG_STATE - -#define GST_PAD_CHAIN_FUNCTION_ARGS \ - GstPad *pad, GstBuffer *buffer -#define GST_PAD_EVENT_FUNCTION_ARGS \ - GstPad *pad, GstEvent *event - -static inline gboolean -gst_compat_pad_start_task(GstPad *pad, GstTaskFunction func, gpointer user_data, - GDestroyNotify notify) -{ - g_return_val_if_fail(notify == NULL, FALSE); - - return gst_pad_start_task(pad, func, user_data); -} - -#undef gst_pad_start_task -#define gst_pad_start_task(pad, func, user_data, notify) \ - gst_compat_pad_start_task(pad, func, user_data, notify) - -/* GstElement */ -#undef GST_ELEMENT_FLAG_SINK -#define GST_ELEMENT_FLAG_SINK GST_ELEMENT_IS_SINK -#undef gst_element_class_set_static_metadata -#define gst_element_class_set_static_metadata(klass, name, path, desc, author) \ - gst_compat_element_class_set_static_metadata(klass, name, path, desc, author) - -static inline void -gst_compat_element_class_set_static_metadata(GstElementClass *klass, - const gchar *name, const char *path, const gchar *desc, const gchar *author) -{ - gst_element_class_set_details_simple(klass, name, path, desc, author); -} - -/* GstTypeFind */ -#undef GstTypeFindPeekFunction -#define GstTypeFindPeekFunction GstCompatTypeFindPeekFunction -#undef GstTypeFindSuggestFunction -#define GstTypeFindSuggestFunction GstCompatTypeFindSuggestFunction - -typedef guint8 *(*GstCompatTypeFindPeekFunction)(gpointer, gint64, guint); -typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, const GstCaps *); - -/* GstQuery */ -#define GST_PAD_QUERY_FUNCTION_ARGS \ - GstPad *pad, GstQuery *query -#define GST_PAD_QUERY_FUNCTION_CALL(func, pad, parent, query) \ - (func)(pad, query) - -/* Misc helpers */ -#define GST_MAKE_FORMAT_STRING(FORMAT) \ - "format=(fourcc)" G_STRINGIFY(FORMAT) - -#endif - #endif /* GST_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapicontext_overlay.c b/gst-libs/gst/vaapi/gstvaapicontext_overlay.c index b38e62e795..117f0d8a75 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext_overlay.c +++ b/gst-libs/gst/vaapi/gstvaapicontext_overlay.c @@ -198,7 +198,6 @@ overlay_rectangle_changed_pixels (GstVaapiOverlayRectangle * overlay, buffer = gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags); if (!buffer) return FALSE; -#if GST_CHECK_VERSION(1,0,0) { const guint n_blocks = gst_buffer_n_memory (buffer); gsize ofs; @@ -217,10 +216,6 @@ overlay_rectangle_changed_pixels (GstVaapiOverlayRectangle * overlay, return FALSE; } } -#else - if (GST_BUFFER_DATA (overlay->rect_buffer) != GST_BUFFER_DATA (buffer)) - return FALSE; -#endif return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 3ef4cbab8b..87801f186a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -816,21 +816,6 @@ gst_vaapi_decoder_get_frame_with_timeout (GstVaapiDecoder * decoder, if (!out_frame) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; -#if !GST_CHECK_VERSION(1,0,0) - if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) { - const guint flags = GST_VAAPI_SURFACE_PROXY_FLAGS (out_frame->user_data); - guint out_flags = 0; - - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF) - out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_TFF; - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF) - out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_RFF; - if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) - out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_ONEFIELD; - GST_VIDEO_CODEC_FRAME_FLAG_SET (out_frame, out_flags); - } -#endif - *out_frame_ptr = out_frame; return GST_VAAPI_DECODER_STATUS_SUCCESS; } diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 41d4a1c2fa..8a295a5f8e 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -698,7 +698,6 @@ gst_vaapi_image_get_data_size(GstVaapiImage *image) return image->image.data_size; } -#if GST_CHECK_VERSION(1,0,0) #include static gboolean @@ -715,52 +714,6 @@ init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) return vmeta ? init_image_from_video_meta(raw_image, vmeta) : FALSE; } -#else -static gboolean -init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) -{ - GstCaps *caps; - guchar *data; - guint32 data_size; - GstVideoInfo vi; - guint i, frame_size; - - data = GST_BUFFER_DATA(buffer); - data_size = GST_BUFFER_SIZE(buffer); - caps = GST_BUFFER_CAPS(buffer); - - if (!caps) - return FALSE; - - if (!gst_video_info_from_caps(&vi, caps)) - goto error_unsupported_caps; - - /* Check for compatible data size */ - frame_size = GST_VIDEO_INFO_SIZE(&vi); - if (frame_size != data_size) - goto error_incompatible_size; - - raw_image->format = GST_VIDEO_INFO_FORMAT(&vi); - raw_image->width = GST_VIDEO_INFO_WIDTH(&vi); - raw_image->height = GST_VIDEO_INFO_HEIGHT(&vi); - - raw_image->num_planes = GST_VIDEO_INFO_N_PLANES(&vi); - for (i = 0; i < raw_image->num_planes; i++) { - raw_image->pixels[i] = data + GST_VIDEO_INFO_PLANE_OFFSET(&vi, i); - raw_image->stride[i] = GST_VIDEO_INFO_PLANE_STRIDE(&vi, i); - } - return TRUE; - - /* ERRORS */ -error_unsupported_caps: - GST_ERROR("unsupported caps %" GST_PTR_FORMAT, caps); - return FALSE; -error_incompatible_size: - GST_ERROR("incompatible frame size (%u) with buffer size (%u)", - frame_size, data_size); - return FALSE; -} -#endif /* Copy N lines of an image */ static inline void diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index e8d28a470b..370ff8716f 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -191,10 +191,8 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( gfloat global_alpha; guint width, height, stride; guint hw_flags, flags; -#if GST_CHECK_VERSION(1,0,0) GstVideoMeta *vmeta; GstMapInfo map_info; -#endif g_return_val_if_fail(GST_IS_VIDEO_OVERLAY_RECTANGLE(rect), NULL); @@ -206,11 +204,10 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( #endif if (!gst_vaapi_display_has_subpicture_format(display, format, &hw_flags)) return NULL; - + flags = hw_flags & from_GstVideoOverlayFormatFlags( gst_video_overlay_rectangle_get_flags(rect)); -#if GST_CHECK_VERSION(1,0,0) buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect, to_GstVideoOverlayFormatFlags(flags)); if (!buffer) @@ -225,13 +222,6 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( if (!gst_video_meta_map(vmeta, 0, &map_info, (gpointer *)&data, (gint *)&stride, GST_MAP_READ)) return NULL; -#else - buffer = (gst_video_overlay_rectangle_get_pixels_unscaled_argb)(rect, - &width, &height, &stride, to_GstVideoOverlayFormatFlags(flags)); - if (!buffer) - return NULL; - data = GST_BUFFER_DATA(buffer); -#endif image = gst_vaapi_image_new(display, format, width, height); if (!image) @@ -251,9 +241,7 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( subpicture = gst_vaapi_subpicture_new(image, flags); gst_vaapi_object_unref(image); -#if GST_CHECK_VERSION(1,0,0) gst_video_meta_unmap(vmeta, 0, &map_info); -#endif if (!subpicture) return NULL; diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 88778790bf..34c70aac8d 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -125,55 +125,6 @@ get_map (GstVideoFormat format) return NULL; } -/** - * gst_vaapi_video_format_from_string: - * @str: a string representation of #GstVideoFormat - * - * Returns the #GstVideoFormat represented as the string @str. - * - * Return value: #GstVideoFormat for the string representation of - * video format in @str. - */ -GstVideoFormat -gst_vaapi_video_format_from_string (const gchar * str) -{ -#if GST_CHECK_VERSION(1,0,0) - return gst_video_format_from_string (str); -#else - GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; - - do { - /* Validate input string */ - if (!str) - break; - - /* Fast path: assume this represents a common fourcc value */ - const guint32 fourcc = GST_MAKE_FOURCC (str[0], str[1], str[2], str[3]); - format = gst_video_format_from_fourcc (fourcc); - if (format != GST_VIDEO_FORMAT_UNKNOWN) - break; - - /* Slow path: check through all registered enum values */ - GEnumClass *const enum_class = g_type_class_ref (GST_TYPE_VIDEO_FORMAT); - if (!enum_class) - break; - - gchar *const video_format_str = - g_strdup_printf ("GST_VIDEO_FORMAT_%s", str); - if (video_format_str) { - const GEnumValue *const enum_value = - g_enum_get_value_by_name (enum_class, video_format_str); - - if (enum_value) - format = enum_value->value; - g_free (video_format_str); - } - g_type_class_unref (enum_class); - } while (0); - return format; -#endif -} - /** * gst_vaapi_video_format_to_string: * @format: a #GstVideoFormat diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index acc333da43..4830522fe2 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -29,9 +29,6 @@ G_BEGIN_DECLS -GstVideoFormat -gst_vaapi_video_format_from_string (const gchar * str); - const gchar * gst_vaapi_video_format_to_string (GstVideoFormat format); diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 4926d012b3..bf39038e2d 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -24,8 +24,6 @@ #include "gst/vaapi/sysdeps.h" #include -#include "gstvaapidownload.h" -#include "gstvaapiupload.h" #include "gstvaapidecode.h" #include "gstvaapipostproc.h" #include "gstvaapisink.h" @@ -51,14 +49,6 @@ static gboolean plugin_init (GstPlugin *plugin) { -#if !GST_CHECK_VERSION(1,0,0) - gst_element_register(plugin, "vaapidownload", - GST_RANK_SECONDARY, - GST_TYPE_VAAPIDOWNLOAD); - gst_element_register(plugin, "vaapiupload", - GST_RANK_PRIMARY, - GST_TYPE_VAAPIUPLOAD); -#endif gst_element_register(plugin, "vaapidecode", GST_RANK_PRIMARY + 1, GST_TYPE_VAAPIDECODE); @@ -95,14 +85,6 @@ plugin_init (GstPlugin *plugin) return TRUE; } -#if GST_CHECK_VERSION(1,0,0) -/* XXX: use PLUGIN_NAME when GST_PLUGIN_DEFINE is fixed to use - G_STRINGIFY() for name argument, instead of plain #name */ GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, vaapi, PLUGIN_DESC, plugin_init, PACKAGE_VERSION, PLUGIN_LICENSE, PACKAGE, PACKAGE_BUGREPORT) -#else -GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, - PLUGIN_NAME, PLUGIN_DESC, plugin_init, - PACKAGE_VERSION, PLUGIN_LICENSE, PACKAGE, PACKAGE_BUGREPORT) -#endif diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 04851f43b2..7ada2b541e 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -39,10 +39,8 @@ #if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) #include "gstvaapivideometa_texture.h" #endif -#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" #include "gstvaapivideomemory.h" -#endif #include #include @@ -263,11 +261,9 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstVaapiSurfaceProxy *proxy; GstFlowReturn ret; -#if GST_CHECK_VERSION(1,0,0) const GstVaapiRectangle *crop_rect; GstVaapiVideoMeta *meta; guint flags; -#endif if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) { proxy = gst_video_codec_frame_get_user_data (out_frame); @@ -275,7 +271,6 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, gst_vaapi_surface_proxy_set_destroy_notify (proxy, (GDestroyNotify) gst_vaapidecode_release, gst_object_ref (decode)); -#if GST_CHECK_VERSION(1,0,0) ret = gst_video_decoder_allocate_output_frame (vdec, out_frame); if (ret != GST_FLOW_OK) goto error_create_buffer; @@ -311,12 +306,6 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, #if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) if (decode->has_texture_upload_meta) gst_buffer_ensure_texture_upload_meta (out_frame->output_buffer); -#endif -#else - out_frame->output_buffer = - gst_vaapi_video_buffer_new_with_surface_proxy (proxy); - if (!out_frame->output_buffer) - goto error_create_buffer; #endif } @@ -341,7 +330,6 @@ error_create_buffer: gst_video_codec_frame_unref (out_frame); return GST_FLOW_ERROR; } -#if GST_CHECK_VERSION(1,0,0) error_get_meta: { GST_ELEMENT_ERROR (vdec, STREAM, FAILED, @@ -351,7 +339,6 @@ error_get_meta: gst_video_codec_frame_unref (out_frame); return GST_FLOW_ERROR; } -#endif error_commit_buffer: { if (ret != GST_FLOW_FLUSHING) @@ -539,7 +526,6 @@ gst_vaapidecode_finish (GstVideoDecoder * vdec) return gst_vaapidecode_push_all_decoded_frames (decode); } -#if GST_CHECK_VERSION(1,0,0) static gboolean gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) { @@ -571,7 +557,6 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), query, feature); } -#endif static inline gboolean gst_vaapidecode_ensure_display (GstVaapiDecode * decode) @@ -861,11 +846,8 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) #if GST_CHECK_VERSION(1,5,0) vdec_class->drain = GST_DEBUG_FUNCPTR (gst_vaapidecode_drain); #endif - -#if GST_CHECK_VERSION(1,0,0) vdec_class->decide_allocation = GST_DEBUG_FUNCPTR (gst_vaapidecode_decide_allocation); -#endif #if GST_CHECK_VERSION(1,4,0) vdec_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_src_query); vdec_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_query); @@ -1001,7 +983,6 @@ gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query) } switch (GST_QUERY_TYPE (query)) { -#if GST_CHECK_VERSION(1,0,0) case GST_QUERY_CAPS:{ GstCaps *caps, *filter = NULL; GstPad *pad = GST_VIDEO_DECODER_SINK_PAD (vdec); @@ -1019,7 +1000,6 @@ gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query) gst_caps_unref (caps); break; } -#endif default:{ #if GST_CHECK_VERSION(1,4,0) ret = GST_VIDEO_DECODER_CLASS (gst_vaapidecode_parent_class)->sink_query @@ -1052,7 +1032,6 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) } switch (GST_QUERY_TYPE (query)) { -#if GST_CHECK_VERSION(1,0,0) case GST_QUERY_CAPS:{ GstCaps *caps, *filter = NULL; GstPad *pad = GST_VIDEO_DECODER_SRC_PAD (vdec); @@ -1070,7 +1049,6 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) gst_caps_unref (caps); break; } -#endif default:{ #if GST_CHECK_VERSION(1,4,0) ret = GST_VIDEO_DECODER_CLASS (gst_vaapidecode_parent_class)->src_query @@ -1110,9 +1088,6 @@ gst_vaapidecode_init (GstVaapiDecode * decode) /* Pad through which data comes in to the element */ GstPad *pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD (decode); gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_vaapidecode_query)); -#if !GST_CHECK_VERSION(1,0,0) - gst_pad_set_getcaps_function (pad, gst_vaapidecode_get_caps); -#endif /* Pad through which data goes out of the element */ pad = GST_VAAPI_PLUGIN_BASE_SRC_PAD (decode); diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 388ff02463..6454cb9e59 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -80,9 +80,7 @@ static const char gst_vaapi_decode_bin_src_caps_str[] = GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") ", " GST_CAPS_INTERLACED_FALSE "; " #endif -#if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " -#endif GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c deleted file mode 100644 index 045a6de343..0000000000 --- a/gst/vaapi/gstvaapidownload.c +++ /dev/null @@ -1,585 +0,0 @@ -/* - * gstvaapidownload.c - VA-API video downloader - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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:gstvaapidownload - * @short_description: A VA to video flow filter - * - * vaapidownload converts from VA surfaces to raw YUV pixels. - */ - -#include "gst/vaapi/sysdeps.h" -#include -#include - -#include "gstvaapidownload.h" -#include "gstvaapipluginutil.h" -#include "gstvaapivideobuffer.h" - -#define GST_PLUGIN_NAME "vaapidownload" -#define GST_PLUGIN_DESC "A VA to video flow filter" - -GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapidownload); -#define GST_CAT_DEFAULT gst_debug_vaapidownload - -/* Default templates */ -static const char gst_vaapidownload_yuv_caps_str[] = - "video/x-raw-yuv, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; "; - -static const char gst_vaapidownload_vaapi_caps_str[] = - GST_VAAPI_SURFACE_CAPS; - -static GstStaticPadTemplate gst_vaapidownload_sink_factory = - GST_STATIC_PAD_TEMPLATE( - "sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS(gst_vaapidownload_vaapi_caps_str)); - -static GstStaticPadTemplate gst_vaapidownload_src_factory = - GST_STATIC_PAD_TEMPLATE( - "src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS(gst_vaapidownload_yuv_caps_str)); - -typedef struct _TransformSizeCache TransformSizeCache; -struct _TransformSizeCache { - GstCaps *caps; - guint size; -}; - -struct _GstVaapiDownload { - /*< private >*/ - GstVaapiPluginBase parent_instance; - - GstCaps *allowed_caps; - TransformSizeCache transform_size_cache[2]; - GstVaapiVideoPool *images; - GstVideoFormat image_format; - guint image_width; - guint image_height; - unsigned int images_reset : 1; -}; - -struct _GstVaapiDownloadClass { - /*< private >*/ - GstVaapiPluginBaseClass parent_class; -}; - -G_DEFINE_TYPE_WITH_CODE( - GstVaapiDownload, - gst_vaapidownload, - GST_TYPE_BASE_TRANSFORM, - GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) - -static gboolean -gst_vaapidownload_start(GstBaseTransform *trans); - -static gboolean -gst_vaapidownload_stop(GstBaseTransform *trans); - -static void -gst_vaapidownload_before_transform(GstBaseTransform *trans, GstBuffer *buffer); - -static GstFlowReturn -gst_vaapidownload_transform( - GstBaseTransform *trans, - GstBuffer *inbuf, - GstBuffer *outbuf -); - -static GstCaps * -gst_vaapidownload_transform_caps( - GstBaseTransform *trans, - GstPadDirection direction, - GstCaps *caps -); - -static gboolean -gst_vaapidownload_transform_size( - GstBaseTransform *trans, - GstPadDirection direction, - GstCaps *caps, - guint size, - GstCaps *othercaps, - guint *othersize -); - -static gboolean -gst_vaapidownload_set_caps( - GstBaseTransform *trans, - GstCaps *incaps, - GstCaps *outcaps -); - -static gboolean -gst_vaapidownload_query( - GstPad *pad, - GstQuery *query -); - -static void -gst_vaapidownload_destroy(GstVaapiDownload *download) -{ - guint i; - - for (i = 0; i < G_N_ELEMENTS(download->transform_size_cache); i++) { - TransformSizeCache * const tsc = &download->transform_size_cache[i]; - if (tsc->caps) { - gst_caps_unref(tsc->caps); - tsc->caps = NULL; - tsc->size = 0; - } - } - - if (download->allowed_caps) { - gst_caps_unref(download->allowed_caps); - download->allowed_caps = NULL; - } - - gst_vaapi_video_pool_replace(&download->images, NULL); - GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(download, NULL); -} - -static void -gst_vaapidownload_finalize(GObject *object) -{ - gst_vaapidownload_destroy(GST_VAAPIDOWNLOAD(object)); - - gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object)); - G_OBJECT_CLASS(gst_vaapidownload_parent_class)->finalize(object); -} - -static void -gst_vaapidownload_class_init(GstVaapiDownloadClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - GstPadTemplate *pad_template; - - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidownload, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - - gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass)); - - object_class->finalize = gst_vaapidownload_finalize; - trans_class->start = gst_vaapidownload_start; - trans_class->stop = gst_vaapidownload_stop; - trans_class->before_transform = gst_vaapidownload_before_transform; - trans_class->transform = gst_vaapidownload_transform; - trans_class->transform_caps = gst_vaapidownload_transform_caps; - trans_class->transform_size = gst_vaapidownload_transform_size; - trans_class->set_caps = gst_vaapidownload_set_caps; - - gst_element_class_set_static_metadata(element_class, - "VA-API colorspace converter", - "Filter/Converter/Video", - GST_PLUGIN_DESC, - "Gwenole Beauchesne "); - - /* sink pad */ - pad_template = gst_static_pad_template_get(&gst_vaapidownload_sink_factory); - gst_element_class_add_pad_template(element_class, pad_template); - - /* src pad */ - pad_template = gst_static_pad_template_get(&gst_vaapidownload_src_factory); - gst_element_class_add_pad_template(element_class, pad_template); -} - -static void -gst_vaapidownload_init(GstVaapiDownload *download) -{ - GstPad *sinkpad, *srcpad; - - gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(download), GST_CAT_DEFAULT); - - download->allowed_caps = NULL; - download->images = NULL; - download->images_reset = FALSE; - download->image_format = GST_VIDEO_FORMAT_UNKNOWN; - download->image_width = 0; - download->image_height = 0; - - /* Override buffer allocator on sink pad */ - sinkpad = gst_element_get_static_pad(GST_ELEMENT(download), "sink"); - gst_pad_set_query_function(sinkpad, gst_vaapidownload_query); - gst_object_unref(sinkpad); - - /* Override query on src pad */ - srcpad = gst_element_get_static_pad(GST_ELEMENT(download), "src"); - gst_pad_set_query_function(srcpad, gst_vaapidownload_query); - gst_object_unref(srcpad); -} - -static inline gboolean -gst_vaapidownload_ensure_display(GstVaapiDownload *download) -{ - return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(download)); -} - -static gboolean -gst_vaapidownload_start(GstBaseTransform *trans) -{ - GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - - if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(trans))) - return FALSE; - if (!gst_vaapidownload_ensure_display(download)) - return FALSE; - return TRUE; -} - -static gboolean -gst_vaapidownload_stop(GstBaseTransform *trans) -{ - gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(trans)); - return TRUE; -} - -static GstVideoFormat -get_surface_format(GstVaapiSurface *surface) -{ - GstVaapiImage *image; - GstVideoFormat format = GST_VIDEO_FORMAT_NV12; - - /* XXX: NV12 is assumed by default */ - image = gst_vaapi_surface_derive_image(surface); - if (image) { - format = gst_vaapi_image_get_format(image); - gst_vaapi_object_unref(image); - } - return format; -} - -static gboolean -gst_vaapidownload_update_src_caps(GstVaapiDownload *download, GstBuffer *buffer) -{ - GstVaapiVideoMeta *meta; - GstVaapiSurface *surface; - GstVideoFormat format; - GstVideoInfo vi; - GstPad *srcpad; - GstCaps *in_caps, *out_caps; - - meta = gst_buffer_get_vaapi_video_meta(buffer); - surface = gst_vaapi_video_meta_get_surface(meta); - if (!surface) { - GST_WARNING("failed to retrieve VA surface from buffer"); - return FALSE; - } - - format = get_surface_format(surface); - if (format == download->image_format) - return TRUE; - - in_caps = GST_BUFFER_CAPS(buffer); - if (!in_caps || !gst_caps_is_fixed(in_caps)) { - GST_WARNING("failed to retrieve caps from buffer"); - return FALSE; - } - - if (!gst_video_info_from_caps(&vi, in_caps)) { - GST_WARNING("failed to parse caps %" GST_PTR_FORMAT, in_caps); - return FALSE; - } - - gst_video_info_set_format(&vi, download->image_format, - GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); - out_caps = gst_video_info_to_caps(&vi); - if (!out_caps) { - GST_WARNING("failed to create caps from format %s", - gst_video_format_to_string(download->image_format)); - return FALSE; - } - - /* Try to renegotiate downstream caps */ - srcpad = gst_element_get_static_pad(GST_ELEMENT(download), "src"); - gst_pad_set_caps(srcpad, out_caps); - gst_object_unref(srcpad); - - gst_vaapidownload_set_caps(GST_BASE_TRANSFORM(download), in_caps, out_caps); - gst_caps_replace(&download->allowed_caps, out_caps); - gst_caps_unref(out_caps); - return TRUE; -} - -static void -gst_vaapidownload_before_transform(GstBaseTransform *trans, GstBuffer *buffer) -{ - GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - - gst_vaapidownload_update_src_caps(download, buffer); -} - -static GstFlowReturn -gst_vaapidownload_transform( - GstBaseTransform *trans, - GstBuffer *inbuf, - GstBuffer *outbuf -) -{ - GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - GstVaapiVideoMeta *meta; - GstVaapiSurface *surface; - GstVaapiImage *image = NULL; - gboolean success; - - meta = gst_buffer_get_vaapi_video_meta(inbuf); - surface = gst_vaapi_video_meta_get_surface(meta); - if (!surface) - return GST_FLOW_UNEXPECTED; - - image = gst_vaapi_video_pool_get_object(download->images); - if (!image) - return GST_FLOW_UNEXPECTED; - if (!gst_vaapi_surface_get_image(surface, image)) - goto error_get_image; - - success = gst_vaapi_image_get_buffer(image, outbuf, NULL); - gst_vaapi_video_pool_put_object(download->images, image); - if (!success) - goto error_get_buffer; - return GST_FLOW_OK; - -error_get_image: - { - const GstVideoFormat format = gst_vaapi_image_get_format(image); - GST_WARNING("failed to download %s image from surface 0x%08x", - gst_video_format_to_string(format), - gst_vaapi_surface_get_id(surface)); - gst_vaapi_video_pool_put_object(download->images, image); - return GST_FLOW_UNEXPECTED; - } - -error_get_buffer: - { - GST_WARNING("failed to transfer image to output video buffer"); - return GST_FLOW_UNEXPECTED; - } -} - -static GstCaps * -gst_vaapidownload_transform_caps( - GstBaseTransform *trans, - GstPadDirection direction, - GstCaps *caps -) -{ - GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - GstPad *srcpad; - GstCaps *allowed_caps, *tmp_caps, *out_caps = NULL; - GstStructure *structure; - GArray *formats; - - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); - - structure = gst_caps_get_structure(caps, 0); - - if (direction == GST_PAD_SINK) { - if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) - return NULL; - if (!gst_vaapidownload_ensure_display(download)) - return NULL; - out_caps = gst_caps_from_string(gst_vaapidownload_yuv_caps_str); - - /* Build up allowed caps */ - /* XXX: we don't know the decoded surface format yet so we - expose whatever VA images we support */ - if (download->allowed_caps) - allowed_caps = gst_caps_ref(download->allowed_caps); - else { - formats = gst_vaapi_display_get_image_formats( - GST_VAAPI_PLUGIN_BASE_DISPLAY(download)); - if (G_UNLIKELY(!formats)) - allowed_caps = gst_caps_new_empty(); - else { - allowed_caps = - gst_vaapi_video_format_new_template_caps_from_list(formats); - g_array_unref(formats); - } - if (!allowed_caps) - return NULL; - } - tmp_caps = gst_caps_intersect(out_caps, allowed_caps); - gst_caps_unref(allowed_caps); - gst_caps_unref(out_caps); - out_caps = tmp_caps; - - /* Intersect with allowed caps from the peer, if any */ - srcpad = gst_element_get_static_pad(GST_ELEMENT(download), "src"); - allowed_caps = gst_pad_peer_get_caps(srcpad); - if (allowed_caps) { - tmp_caps = gst_caps_intersect(out_caps, allowed_caps); - gst_caps_unref(allowed_caps); - gst_caps_unref(out_caps); - out_caps = tmp_caps; - } - } - else { - if (!gst_structure_has_name(structure, "video/x-raw-yuv")) - return NULL; - out_caps = gst_caps_from_string(gst_vaapidownload_vaapi_caps_str); - - structure = gst_caps_get_structure(out_caps, 0); - gst_structure_set( - structure, - "type", G_TYPE_STRING, "vaapi", - "opengl", G_TYPE_BOOLEAN, USE_GLX, - NULL - ); - } - - if (!gst_vaapi_append_surface_caps(out_caps, caps)) { - gst_caps_unref(out_caps); - return NULL; - } - return out_caps; -} - -static gboolean -gst_vaapidownload_ensure_image_pool(GstVaapiDownload *download, GstCaps *caps) -{ - GstVideoInfo vi; - GstVideoFormat format; - guint width, height; - - if (!gst_video_info_from_caps(&vi, caps)) - return FALSE; - - format = GST_VIDEO_INFO_FORMAT(&vi); - width = GST_VIDEO_INFO_WIDTH(&vi); - height = GST_VIDEO_INFO_HEIGHT(&vi); - - if (format != download->image_format || - width != download->image_width || - height != download->image_height) { - download->image_format = format; - download->image_width = width; - download->image_height = height; - gst_vaapi_video_pool_replace(&download->images, NULL); - download->images = gst_vaapi_image_pool_new( - GST_VAAPI_PLUGIN_BASE_DISPLAY(download), &vi); - if (!download->images) - return FALSE; - download->images_reset = TRUE; - } - return TRUE; -} - -static inline gboolean -gst_vaapidownload_negotiate_buffers( - GstVaapiDownload *download, - GstCaps *incaps, - GstCaps *outcaps -) -{ - if (!gst_vaapidownload_ensure_image_pool(download, outcaps)) - return FALSE; - return TRUE; -} - -static gboolean -gst_vaapidownload_set_caps( - GstBaseTransform *trans, - GstCaps *incaps, - GstCaps *outcaps -) -{ - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(trans); - GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - - if (!gst_vaapi_plugin_base_set_caps(plugin, incaps, outcaps)) - return FALSE; - if (!gst_vaapidownload_negotiate_buffers(download, incaps, outcaps)) - return FALSE; - return TRUE; -} - -static gboolean -gst_vaapidownload_transform_size( - GstBaseTransform *trans, - GstPadDirection direction, - GstCaps *caps, - guint size, - GstCaps *othercaps, - guint *othersize -) -{ - GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans); - GstStructure * const structure = gst_caps_get_structure(othercaps, 0); - GstVideoFormat format; - gint width, height; - guint i; - - /* Lookup in cache */ - for (i = 0; i < G_N_ELEMENTS(download->transform_size_cache); i++) { - TransformSizeCache * const tsc = &download->transform_size_cache[i]; - if (tsc->caps && tsc->caps == othercaps) { - *othersize = tsc->size; - return TRUE; - } - } - - /* Compute requested buffer size */ - if (gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) - *othersize = 0; - else { - if (!gst_video_format_parse_caps(othercaps, &format, &width, &height)) - return FALSE; - *othersize = gst_video_format_get_size(format, width, height); - } - - /* Update cache */ - for (i = 0; i < G_N_ELEMENTS(download->transform_size_cache); i++) { - TransformSizeCache * const tsc = &download->transform_size_cache[i]; - if (!tsc->caps) { - gst_caps_replace(&tsc->caps, othercaps); - tsc->size = *othersize; - } - } - return TRUE; -} - -static gboolean -gst_vaapidownload_query(GstPad *pad, GstQuery *query) -{ - GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(gst_pad_get_parent_element(pad)); - GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(download); - gboolean res; - - GST_DEBUG("sharing display %p", display); - - if (gst_vaapi_reply_to_query(query, display)) - res = TRUE; - else - res = gst_pad_query_default(pad, query); - - gst_object_unref(download); - return res; - -} diff --git a/gst/vaapi/gstvaapidownload.h b/gst/vaapi/gstvaapidownload.h deleted file mode 100644 index bb29fca547..0000000000 --- a/gst/vaapi/gstvaapidownload.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * gstvaapidownload.h - VA-API video downloader - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * This program 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free - * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA -*/ - -#ifndef GST_VAAPIDOWNLOAD_H -#define GST_VAAPIDOWNLOAD_H - -#include "gstvaapipluginbase.h" -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_VAAPIDOWNLOAD \ - (gst_vaapidownload_get_type()) - -#define GST_VAAPIDOWNLOAD(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_TYPE_VAAPIDOWNLOAD, \ - GstVaapiDownload)) - -#define GST_VAAPIDOWNLOAD_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_TYPE_VAAPIDOWNLOAD, \ - GstVaapiDownloadClass)) - -#define GST_IS_VAAPIDOWNLOAD(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPIDOWNLOAD)) - -#define GST_IS_VAAPIDOWNLOAD_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPIDOWNLOAD)) - -#define GST_VAAPIDOWNLOAD_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_TYPE_VAAPIDOWNLOAD, \ - GstVaapiDownloadClass)) - -typedef struct _GstVaapiDownload GstVaapiDownload; -typedef struct _GstVaapiDownloadClass GstVaapiDownloadClass; - -GType -gst_vaapidownload_get_type(void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* GST_VAAPIDOWNLOAD_H */ diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 6209f369e5..1167490296 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -27,10 +27,8 @@ #include "gstvaapiencode.h" #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" -#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideomemory.h" #include "gstvaapivideobufferpool.h" -#endif #define GST_PLUGIN_NAME "vaapiencode" #define GST_PLUGIN_DESC "A VA-API based video encoder" @@ -187,13 +185,9 @@ gst_vaapiencode_default_alloc_buffer (GstVaapiEncode * encode, if (buf_size <= 0) goto error_invalid_buffer; -#if GST_CHECK_VERSION(1,0,0) buf = gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER_CAST (encode), buf_size); -#else - buf = gst_buffer_new_and_alloc (buf_size); -#endif if (!buf) goto error_create_buffer; if (!gst_vaapi_coded_buffer_copy_into (buf, coded_buf)) @@ -248,10 +242,8 @@ ensure_output_state (GstVaapiEncode * encode) return FALSE; } -#if GST_CHECK_VERSION(1,0,0) if (!gst_video_encoder_negotiate (venc)) return FALSE; -#endif encode->input_state_changed = FALSE; return TRUE; @@ -350,24 +342,11 @@ gst_vaapiencode_get_caps_impl (GstVideoEncoder * venc) if (plugin->sinkpad_caps) caps = gst_caps_ref (plugin->sinkpad_caps); else { -#if GST_CHECK_VERSION(1,0,0) caps = gst_pad_get_pad_template_caps (plugin->sinkpad); -#else - caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS); - - if (caps && ensure_uploader (GST_VAAPIENCODE_CAST (plugin))) { - GstCaps *const yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS (plugin); - if (yuv_caps) { - caps = gst_caps_make_writable (caps); - gst_caps_append (caps, gst_caps_copy (yuv_caps)); - } - } -#endif } return caps; } -#if GST_CHECK_VERSION(1,0,0) static GstCaps * gst_vaapiencode_get_caps (GstVideoEncoder * venc, GstCaps * filter) { @@ -381,9 +360,6 @@ gst_vaapiencode_get_caps (GstVideoEncoder * venc, GstCaps * filter) } return out_caps; } -#else -#define gst_vaapiencode_get_caps gst_vaapiencode_get_caps_impl -#endif static gboolean gst_vaapiencode_destroy (GstVaapiEncode * encode) @@ -615,7 +591,6 @@ gst_vaapiencode_change_state (GstElement * element, GstStateChange transition) change_state (element, transition); } -#if GST_CHECK_VERSION(1,0,0) static gboolean gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query) { @@ -625,7 +600,6 @@ gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query) return FALSE; return TRUE; } -#endif static void gst_vaapiencode_finalize (GObject * object) @@ -678,11 +652,8 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) venc_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapiencode_handle_frame); venc_class->finish = GST_DEBUG_FUNCPTR (gst_vaapiencode_finish); venc_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapiencode_get_caps); - -#if GST_CHECK_VERSION(1,0,0) venc_class->propose_allocation = GST_DEBUG_FUNCPTR (gst_vaapiencode_propose_allocation); -#endif klass->get_property = gst_vaapiencode_default_get_property; klass->set_property = gst_vaapiencode_default_set_property; diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 93d6288c19..3c16c91cee 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -27,9 +27,7 @@ #include #include "gstvaapiencode_h264.h" #include "gstvaapipluginutil.h" -#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideomemory.h" -#endif #define GST_PLUGIN_NAME "vaapiencode_h264" #define GST_PLUGIN_DESC "A VA-API based H.264 video encoder" @@ -51,13 +49,7 @@ static const char gst_vaapiencode_h264_sink_caps_str[] = GST_VAAPI_SURFACE_CAPS ", " #endif GST_CAPS_INTERLACED_FALSE "; " -#if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " -#else - "video/x-raw-yuv, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ], " -#endif GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 826b06cdc4..07ce6eae13 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -25,9 +25,7 @@ #include #include "gstvaapiencode_jpeg.h" #include "gstvaapipluginutil.h" -#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideomemory.h" -#endif #define GST_PLUGIN_NAME "vaapiencode_jpeg" #define GST_PLUGIN_DESC "A VA-API based JPEG video encoder" @@ -47,9 +45,7 @@ static const char gst_vaapiencode_jpeg_sink_caps_str[] = GST_VAAPI_SURFACE_CAPS ", " #endif GST_CAPS_INTERLACED_FALSE "; " -#if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " -#endif GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 95c0edc145..0d6fb74c3d 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -26,9 +26,7 @@ #include #include "gstvaapiencode_mpeg2.h" #include "gstvaapipluginutil.h" -#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideomemory.h" -#endif #define GST_PLUGIN_NAME "vaapiencode_mpeg2" #define GST_PLUGIN_DESC "A VA-API based MPEG-2 video encoder" @@ -49,13 +47,7 @@ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = GST_VAAPI_SURFACE_CAPS ", " #endif GST_CAPS_INTERLACED_FALSE "; " -#if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " -#else - "video/x-raw-yuv, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ], " -#endif GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index e236206cb4..0cba42b759 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -25,9 +25,7 @@ #include #include "gstvaapiencode_vp8.h" #include "gstvaapipluginutil.h" -#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideomemory.h" -#endif #define GST_PLUGIN_NAME "vaapiencode_vp8" #define GST_PLUGIN_DESC "A VA-API based VP8 video encoder" @@ -47,9 +45,7 @@ static const char gst_vaapiencode_vp8_sink_caps_str[] = GST_VAAPI_SURFACE_CAPS ", " #endif GST_CAPS_INTERLACED_FALSE "; " -#if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " -#endif GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiparse.c b/gst/vaapi/gstvaapiparse.c index 3b1e9fcd7f..81724be99d 100644 --- a/gst/vaapi/gstvaapiparse.c +++ b/gst/vaapi/gstvaapiparse.c @@ -40,14 +40,6 @@ plugin_init (GstPlugin * plugin) return !failure; } -#if GST_CHECK_VERSION(1,0,0) -/* XXX: use PLUGIN_NAME when GST_PLUGIN_DEFINE is fixed to use - G_STRINGIFY() for name argument, instead of plain #name */ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, vaapiparse, PLUGIN_DESC, plugin_init, PACKAGE_VERSION, PLUGIN_LICENSE, PACKAGE, PACKAGE_BUGREPORT) -#else -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, - PLUGIN_NAME, PLUGIN_DESC, plugin_init, - PACKAGE_VERSION, PLUGIN_LICENSE, PACKAGE, PACKAGE_BUGREPORT) -#endif diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index a5f1ad0c32..7a9a3fa7f3 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -29,9 +29,7 @@ #include "gstvaapipluginutil.h" #include "gstvaapivideocontext.h" #include "gstvaapivideometa.h" -#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" -#endif #if GST_CHECK_VERSION(1,1,0) #include #endif @@ -39,25 +37,6 @@ /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) -/* GstImplementsInterface interface */ -#if !GST_CHECK_VERSION(1,0,0) -static gboolean -implements_interface_supported (GstImplementsInterface * iface, GType type) -{ - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (iface); - - if (type == GST_TYPE_VIDEO_CONTEXT) - return TRUE; - return GST_VAAPI_PLUGIN_BASE_GET_CLASS (plugin)->has_interface (plugin, type); -} - -static void -implements_interface_init (GstImplementsInterfaceClass * iface) -{ - iface->supported = implements_interface_supported; -} -#endif - /* GstVideoContext interface */ static void plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) @@ -112,10 +91,6 @@ video_context_interface_init (GstVideoContextInterface * iface) void gst_vaapi_plugin_base_init_interfaces (GType g_define_type_id) { -#if !GST_CHECK_VERSION(1,0,0) - G_IMPLEMENT_INTERFACE (GST_TYPE_IMPLEMENTS_INTERFACE, - implements_interface_init); -#endif #if !GST_CHECK_VERSION(1,1,0) G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_CONTEXT, video_context_interface_init); #endif @@ -300,13 +275,11 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) gst_caps_replace (&plugin->sinkpad_caps, NULL); plugin->sinkpad_caps_changed = FALSE; gst_video_info_init (&plugin->sinkpad_info); -#if GST_CHECK_VERSION(1,0,0) if (plugin->sinkpad_buffer_pool) { gst_object_unref (plugin->sinkpad_buffer_pool); plugin->sinkpad_buffer_pool = NULL; } g_clear_object (&plugin->srcpad_buffer_pool); -#endif gst_caps_replace (&plugin->srcpad_caps, NULL); plugin->srcpad_caps_changed = FALSE; @@ -489,7 +462,6 @@ has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad) static gboolean ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) { -#if GST_CHECK_VERSION(1,0,0) GstBufferPool *pool; GstCaps *pool_caps; GstStructure *config; @@ -546,9 +518,6 @@ error_pool_config: gst_object_unref (pool); return FALSE; } -#else - return TRUE; -#endif } /** @@ -603,7 +572,6 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, * * Returns: %TRUE if successful, %FALSE otherwise. */ -#if GST_CHECK_VERSION(1,0,0) gboolean gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, GstQuery * query) @@ -648,7 +616,6 @@ error_pool_config: return FALSE; } } -#endif /** * gst_vaapi_plugin_base_decide_allocation: @@ -661,7 +628,6 @@ error_pool_config: * * Returns: %TRUE if successful, %FALSE otherwise. */ -#if GST_CHECK_VERSION(1,0,0) gboolean gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GstQuery * query, guint feature) @@ -816,7 +782,6 @@ error_create_pool: return FALSE; } } -#endif /** * gst_vaapi_plugin_base_allocate_input_buffer: @@ -880,16 +845,13 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, { GstVaapiVideoMeta *meta; GstBuffer *outbuf; -#if GST_CHECK_VERSION(1,0,0) GstVideoFrame src_frame, out_frame; gboolean success; -#endif g_return_val_if_fail (inbuf != NULL, GST_FLOW_ERROR); g_return_val_if_fail (outbuf_ptr != NULL, GST_FLOW_ERROR); meta = gst_buffer_get_vaapi_video_meta (inbuf); -#if GST_CHECK_VERSION(1,0,0) if (meta) { *outbuf_ptr = gst_buffer_ref (inbuf); return GST_FLOW_OK; @@ -963,25 +925,6 @@ error_map_src_buffer: gst_buffer_unref (outbuf); return GST_FLOW_NOT_SUPPORTED; } -#else - if (meta) - outbuf = gst_buffer_ref (inbuf); - else if (plugin->sinkpad_caps_is_raw) { - outbuf = gst_vaapi_uploader_get_buffer (plugin->uploader); - if (!outbuf) - goto error_create_buffer; - gst_buffer_copy_metadata (outbuf, inbuf, - GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); - } else - goto error_invalid_buffer; - - if (plugin->sinkpad_caps_is_raw && - !gst_vaapi_uploader_process (plugin->uploader, inbuf, outbuf)) - goto error_copy_buffer; - - *outbuf_ptr = outbuf; - return GST_FLOW_OK; -#endif /* ERRORS */ error_invalid_buffer: diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index d444c6a745..e64e9a89a2 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -130,19 +130,15 @@ struct _GstVaapiPluginBase gboolean sinkpad_caps_is_raw; GstVideoInfo sinkpad_info; GstPadQueryFunction sinkpad_query; -#if GST_CHECK_VERSION(1,0,0) GstBufferPool *sinkpad_buffer_pool; guint sinkpad_buffer_size; -#endif GstPad *srcpad; GstCaps *srcpad_caps; gboolean srcpad_caps_changed; GstVideoInfo srcpad_info; GstPadQueryFunction srcpad_query; -#if GST_CHECK_VERSION(1,0,0) GstBufferPool *srcpad_buffer_pool; -#endif GstVaapiDisplay *display; GstVaapiDisplayType display_type; diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index e075f836c4..d9dfd5ed2a 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -482,17 +482,12 @@ gst_vaapi_append_surface_caps (GstCaps * out_caps, GstCaps * in_caps) gboolean gst_vaapi_apply_composition (GstVaapiSurface * surface, GstBuffer * buffer) { -#if GST_CHECK_VERSION(1,0,0) GstVideoOverlayCompositionMeta *const cmeta = gst_buffer_get_video_overlay_composition_meta (buffer); GstVideoOverlayComposition *composition = NULL; if (cmeta) composition = cmeta->overlay; -#else - GstVideoOverlayComposition *const composition = - gst_video_buffer_get_overlay_composition (buffer); -#endif return gst_vaapi_surface_set_subpictures_from_composition (surface, composition, TRUE); } @@ -500,7 +495,6 @@ gst_vaapi_apply_composition (GstVaapiSurface * surface, GstBuffer * buffer) gboolean gst_vaapi_value_set_format (GValue * value, GstVideoFormat format) { -#if GST_CHECK_VERSION(1,0,0) const gchar *str; str = gst_video_format_to_string (format); @@ -509,16 +503,6 @@ gst_vaapi_value_set_format (GValue * value, GstVideoFormat format) g_value_init (value, G_TYPE_STRING); g_value_set_string (value, str); -#else - guint32 fourcc; - - fourcc = gst_video_format_to_fourcc (format); - if (!fourcc) - return FALSE; - - g_value_init (value, GST_TYPE_FOURCC); - gst_value_set_fourcc (value, fourcc); -#endif return TRUE; } @@ -555,7 +539,6 @@ set_video_template_caps (GstCaps * caps) GstCaps * gst_vaapi_video_format_new_template_caps (GstVideoFormat format) { -#if GST_CHECK_VERSION(1,0,0) GstCaps *caps; g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL); @@ -568,15 +551,11 @@ gst_vaapi_video_format_new_template_caps (GstVideoFormat format) "format", G_TYPE_STRING, gst_video_format_to_string (format), NULL); set_video_template_caps (caps); return caps; -#else - return gst_video_format_new_template_caps (format); -#endif } GstCaps * gst_vaapi_video_format_new_template_caps_from_list (GArray * formats) { -#if GST_CHECK_VERSION(1,0,0) GValue v_formats = G_VALUE_INIT; GstCaps *caps; @@ -592,23 +571,6 @@ gst_vaapi_video_format_new_template_caps_from_list (GArray * formats) gst_caps_set_value (caps, "format", &v_formats); set_video_template_caps (caps); g_value_unset (&v_formats); -#else - GstCaps *caps, *tmp_caps; - guint i; - - g_return_val_if_fail (formats != NULL, NULL); - - caps = gst_caps_new_empty (); - if (!caps) - return NULL; - - for (i = 0; i < formats->len; i++) { - const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); - tmp_caps = gst_vaapi_video_format_new_template_caps (format); - if (tmp_caps) - gst_caps_append (caps, tmp_caps); - } -#endif return caps; } @@ -783,7 +745,6 @@ gst_vaapi_caps_feature_to_string (GstVaapiCapsFeature feature) gboolean gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip) { -#if GST_CHECK_VERSION(1,0,0) GstVideoInterlaceMode mode; const gchar *mode_str; @@ -805,10 +766,6 @@ gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip) } gst_caps_set_simple (caps, "interlace-mode", G_TYPE_STRING, mode_str, NULL); -#else - gst_caps_set_simple (caps, "interlaced", G_TYPE_BOOLEAN, - vip ? GST_VIDEO_INFO_IS_INTERLACED (vip) : FALSE, NULL); -#endif return TRUE; } diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 7520cddbfd..9d07a49d6f 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -27,9 +27,7 @@ #include #include -#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideomemory.h" -#endif G_GNUC_INTERNAL gboolean @@ -99,17 +97,10 @@ const gchar * gst_vaapi_caps_feature_to_string (GstVaapiCapsFeature feature); /* Helpers to handle interlaced contents */ -#if GST_CHECK_VERSION(1,0,0) # define GST_CAPS_INTERLACED_MODES \ "interlace-mode = (string){ progressive, interleaved, mixed }" # define GST_CAPS_INTERLACED_FALSE \ "interlace-mode = (string)progressive" -#else -# define GST_CAPS_INTERLACED_MODES \ - "interlaced = (boolean){ true, false }" -# define GST_CAPS_INTERLACED_FALSE \ - "interlaced = (boolean)false" -#endif G_GNUC_INTERNAL gboolean diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 75bc9fbde1..f47a419f40 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -35,10 +35,8 @@ #include "gstvaapipostproc.h" #include "gstvaapipluginutil.h" #include "gstvaapivideobuffer.h" -#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" #include "gstvaapivideomemory.h" -#endif #define GST_PLUGIN_NAME "vaapipostproc" #define GST_PLUGIN_DESC "A video postprocessing filter" @@ -60,14 +58,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapipostproc); static const char gst_vaapipostproc_sink_caps_str[] = GST_VAAPIPOSTPROC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES "; " -#if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " -#else - "video/x-raw-yuv, " - "width = " GST_VIDEO_SIZE_RANGE ", " - "height = " GST_VIDEO_SIZE_RANGE ", " - "framerate = " GST_VIDEO_FPS_RANGE ", " -#endif GST_CAPS_INTERLACED_MODES; /* *INDENT-ON* */ @@ -80,14 +71,7 @@ static const char gst_vaapipostproc_src_caps_str[] = GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") ", " GST_CAPS_INTERLACED_FALSE "; " #endif -#if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " -#else - "video/x-raw-yuv, " - "width = " GST_VIDEO_SIZE_RANGE ", " - "height = " GST_VIDEO_SIZE_RANGE ", " - "framerate = " GST_VIDEO_FPS_RANGE ", " -#endif GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ @@ -359,13 +343,8 @@ should_deinterlace_buffer (GstVaapiPostproc * postproc, GstBuffer * buf) case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE: return FALSE; case GST_VIDEO_INTERLACE_MODE_MIXED: -#if GST_CHECK_VERSION(1,0,0) if (GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_FLAG_INTERLACED)) return TRUE; -#else - if (!GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_PROGRESSIVE)) - return TRUE; -#endif break; default: GST_ERROR ("unhandled \"interlace-mode\", disabling deinterlacing"); @@ -379,7 +358,6 @@ create_output_buffer (GstVaapiPostproc * postproc) { GstBuffer *outbuf; -#if GST_CHECK_VERSION(1,0,0) GstBufferPool *const pool = GST_VAAPI_PLUGIN_BASE (postproc)->srcpad_buffer_pool; GstFlowReturn ret; @@ -393,25 +371,14 @@ create_output_buffer (GstVaapiPostproc * postproc) ret = gst_buffer_pool_acquire_buffer (pool, &outbuf, NULL); if (ret != GST_FLOW_OK || !outbuf) goto error_create_buffer; -#else - /* Create a raw VA video buffer without GstVaapiVideoMeta attached - to it yet, as this will be done next in the transform() hook */ - outbuf = gst_vaapi_video_buffer_new_empty (); - if (!outbuf) - goto error_create_buffer; - - gst_buffer_set_caps (outbuf, GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS (postproc)); -#endif return outbuf; /* ERRORS */ -#if GST_CHECK_VERSION(1,0,0) error_activate_pool: { GST_ERROR ("failed to activate output video buffer pool"); return NULL; } -#endif error_create_buffer: { GST_ERROR ("failed to create output video buffer"); @@ -429,7 +396,6 @@ append_output_buffer_metadata (GstVaapiPostproc * postproc, GstBuffer * outbuf, gst_buffer_copy_into (outbuf, inbuf, flags | GST_BUFFER_COPY_FLAGS, 0, -1); /* GstVideoCropMeta */ -#if GST_CHECK_VERSION(1,0,0) if (!postproc->use_vpp) { GstVideoCropMeta *const crop_meta = gst_buffer_get_video_crop_meta (inbuf); if (crop_meta) { @@ -439,7 +405,6 @@ append_output_buffer_metadata (GstVaapiPostproc * postproc, GstBuffer * outbuf, *out_crop_meta = *crop_meta; } } -#endif /* GstVaapiVideoMeta */ inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); @@ -524,9 +489,7 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, guint flags, deint_flags; gboolean tff, deint, deint_refs, deint_changed; GstVaapiRectangle *crop_rect = NULL; -#if GST_CHECK_VERSION(1,0,0) GstVaapiRectangle tmp_rect; -#endif /* Validate filters */ if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) && @@ -568,7 +531,6 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, goto error_invalid_buffer; inbuf_surface = gst_vaapi_video_meta_get_surface (inbuf_meta); -#if GST_CHECK_VERSION(1,0,0) GstVideoCropMeta *const crop_meta = gst_buffer_get_video_crop_meta (inbuf); if (crop_meta) { crop_rect = &tmp_rect; @@ -577,7 +539,6 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, crop_rect->width = crop_meta->width; crop_rect->height = crop_meta->height; } -#endif if (!crop_rect) crop_rect = (GstVaapiRectangle *) gst_vaapi_video_meta_get_render_rect (inbuf_meta); @@ -1186,7 +1147,6 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, return out_caps; } -#if GST_CHECK_VERSION(1,0,0) static GstCaps * gst_vaapipostproc_transform_caps (GstBaseTransform * trans, GstPadDirection direction, GstCaps * caps, GstCaps * filter) @@ -1201,21 +1161,11 @@ gst_vaapipostproc_transform_caps (GstBaseTransform * trans, } return caps; } -#else -#define gst_vaapipostproc_transform_caps \ - gst_vaapipostproc_transform_caps_impl -#endif - -#if GST_CHECK_VERSION(1,0,0) -typedef gsize GstBaseTransformSizeType; -#else -typedef guint GstBaseTransformSizeType; -#endif static gboolean gst_vaapipostproc_transform_size (GstBaseTransform * trans, - GstPadDirection direction, GstCaps * caps, GstBaseTransformSizeType size, - GstCaps * othercaps, GstBaseTransformSizeType * othersize) + GstPadDirection direction, GstCaps * caps, gsize size, + GstCaps * othercaps, gsize * othersize) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); @@ -1271,9 +1221,6 @@ done: static GstFlowReturn gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, GstBuffer * inbuf, -#if !GST_CHECK_VERSION(1,0,0) - gint size, GstCaps * caps, -#endif GstBuffer ** outbuf_ptr) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); @@ -1354,7 +1301,6 @@ gst_vaapipostproc_query (GstBaseTransform * trans, GstPadDirection direction, direction, query); } -#if GST_CHECK_VERSION(1,0,0) static gboolean gst_vaapipostproc_propose_allocation (GstBaseTransform * trans, GstQuery * decide_query, GstQuery * query) @@ -1376,7 +1322,6 @@ gst_vaapipostproc_decide_allocation (GstBaseTransform * trans, GstQuery * query) return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (trans), query, 0); } -#endif static void gst_vaapipostproc_finalize (GObject * object) @@ -1525,11 +1470,8 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) trans_class->transform = gst_vaapipostproc_transform; trans_class->set_caps = gst_vaapipostproc_set_caps; trans_class->query = gst_vaapipostproc_query; - -#if GST_CHECK_VERSION(1,0,0) trans_class->propose_allocation = gst_vaapipostproc_propose_allocation; trans_class->decide_allocation = gst_vaapipostproc_decide_allocation; -#endif trans_class->prepare_output_buffer = gst_vaapipostproc_prepare_output_buffer; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 7572c8e12b..192cfa2c67 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -38,34 +38,15 @@ #include /* Supported interfaces */ -#if GST_CHECK_VERSION(1,0,0) # include # include # include -#else -# include -# include - -# define GST_TYPE_VIDEO_OVERLAY GST_TYPE_X_OVERLAY -# define GST_VIDEO_OVERLAY GST_X_OVERLAY -# define GstVideoOverlay GstXOverlay -# define GstVideoOverlayInterface GstXOverlayClass - -# define gst_video_overlay_prepare_window_handle(sink) \ - gst_x_overlay_prepare_xwindow_id(sink) -# define gst_video_overlay_got_window_handle(sink, window_handle) \ - gst_x_overlay_got_window_handle(sink, window_handle) - -# define GstColorBalanceInterface GstColorBalanceClass -#endif #include "gstvaapisink.h" #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" -#if GST_CHECK_VERSION(1,0,0) #include "gstvaapivideobufferpool.h" #include "gstvaapivideomemory.h" -#endif #define GST_PLUGIN_NAME "vaapisink" #define GST_PLUGIN_DESC "A VA-API based videosink" @@ -81,13 +62,7 @@ static const char gst_vaapisink_sink_caps_str[] = "{ ENCODED, NV12, I420, YV12 }") ";" GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL); #else -#if GST_CHECK_VERSION(1,0,0) GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) "; " -#else - "video/x-raw-yuv, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; " -#endif GST_VAAPI_SURFACE_CAPS; #endif /* *INDENT-ON* */ @@ -831,11 +806,7 @@ gst_vaapisink_color_balance_iface_init (GstColorBalanceInterface * iface) iface->list_channels = gst_vaapisink_color_balance_list_channels; iface->set_value = gst_vaapisink_color_balance_set_value; iface->get_value = gst_vaapisink_color_balance_get_value; -#if GST_CHECK_VERSION(1,0,0) iface->get_balance_type = gst_vaapisink_color_balance_get_type; -#else - iface->balance_type = gst_vaapisink_color_balance_get_type (NULL); -#endif } /* ------------------------------------------------------------------------ */ @@ -1250,7 +1221,6 @@ gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) return out_caps; } -#if GST_CHECK_VERSION(1,0,0) static inline GstCaps * gst_vaapisink_get_caps (GstBaseSink * base_sink, GstCaps * filter) { @@ -1264,14 +1234,10 @@ gst_vaapisink_get_caps (GstBaseSink * base_sink, GstCaps * filter) out_caps = caps; return out_caps; } -#else -#define gst_vaapisink_get_caps gst_vaapisink_get_caps_impl -#endif static void update_colorimetry (GstVaapiSink * sink, GstVideoColorimetry * cinfo) { -#if GST_CHECK_VERSION(1,0,0) if (gst_video_colorimetry_matches (cinfo, GST_VIDEO_COLORIMETRY_BT601)) sink->color_standard = GST_VAAPI_COLOR_STANDARD_ITUR_BT_601; else if (gst_video_colorimetry_matches (cinfo, GST_VIDEO_COLORIMETRY_BT709)) @@ -1289,7 +1255,6 @@ update_colorimetry (GstVaapiSink * sink, GstVideoColorimetry * cinfo) g_free (colorimetry_string); } #endif -#endif } static gboolean @@ -1357,13 +1322,10 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) GstBuffer *buffer; guint flags; GstVaapiRectangle *surface_rect = NULL; -#if GST_CHECK_VERSION(1,0,0) GstVaapiRectangle tmp_rect; -#endif GstFlowReturn ret; gint32 view_id; -#if GST_CHECK_VERSION(1,0,0) GstVideoCropMeta *const crop_meta = gst_buffer_get_video_crop_meta (src_buffer); if (crop_meta) { @@ -1373,7 +1335,6 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) surface_rect->width = crop_meta->width; surface_rect->height = crop_meta->height; } -#endif ret = gst_vaapi_plugin_base_get_input_buffer (GST_VAAPI_PLUGIN_BASE (sink), src_buffer, &buffer); @@ -1454,7 +1415,6 @@ gst_vaapisink_show_frame (GstBaseSink * base_sink, GstBuffer * src_buffer) return ret; } -#if GST_CHECK_VERSION(1,0,0) static gboolean gst_vaapisink_propose_allocation (GstBaseSink * base_sink, GstQuery * query) { @@ -1468,16 +1428,6 @@ gst_vaapisink_propose_allocation (GstBaseSink * base_sink, GstQuery * query) GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL); return TRUE; } -#else -static GstFlowReturn -gst_vaapisink_buffer_alloc (GstBaseSink * base_sink, guint64 offset, guint size, - GstCaps * caps, GstBuffer ** outbuf_ptr) -{ - return - gst_vaapi_plugin_base_allocate_input_buffer (GST_VAAPI_PLUGIN_BASE - (base_sink), caps, outbuf_ptr); -} -#endif static gboolean gst_vaapisink_query (GstBaseSink * base_sink, GstQuery * query) @@ -1631,11 +1581,7 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) basesink_class->preroll = gst_vaapisink_show_frame; basesink_class->render = gst_vaapisink_show_frame; basesink_class->query = gst_vaapisink_query; -#if GST_CHECK_VERSION(1,0,0) basesink_class->propose_allocation = gst_vaapisink_propose_allocation; -#else - basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc; -#endif element_class->set_bus = gst_vaapisink_set_bus; gst_element_class_set_static_metadata (element_class, diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c deleted file mode 100644 index e90ef3034d..0000000000 --- a/gst/vaapi/gstvaapiupload.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * gstvaapiupload.c - VA-API video upload element - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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:gstvaapiupload - * @short_description: A video to VA flow filter - * - * vaapiupload converts from raw YUV pixels to VA surfaces suitable - * for the vaapisink element, for example. - */ - -#include "gst/vaapi/sysdeps.h" -#include -#include - -#include "gstvaapiupload.h" -#include "gstvaapipluginutil.h" -#include "gstvaapivideobuffer.h" - -#define GST_PLUGIN_NAME "vaapiupload" -#define GST_PLUGIN_DESC "A video to VA flow filter" - -GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapiupload); -#define GST_CAT_DEFAULT gst_debug_vaapiupload - -/* Default templates */ -static const char gst_vaapiupload_yuv_caps_str[] = - "video/x-raw-yuv, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; "; - -static const char gst_vaapiupload_vaapi_caps_str[] = - GST_VAAPI_SURFACE_CAPS; - -static GstStaticPadTemplate gst_vaapiupload_sink_factory = - GST_STATIC_PAD_TEMPLATE( - "sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS(gst_vaapiupload_yuv_caps_str)); - -static GstStaticPadTemplate gst_vaapiupload_src_factory = - GST_STATIC_PAD_TEMPLATE( - "src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS(gst_vaapiupload_vaapi_caps_str)); - -G_DEFINE_TYPE_WITH_CODE( - GstVaapiUpload, - gst_vaapiupload, - GST_TYPE_BASE_TRANSFORM, - GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) - -static gboolean -gst_vaapiupload_start(GstBaseTransform *trans); - -static gboolean -gst_vaapiupload_stop(GstBaseTransform *trans); - -static GstFlowReturn -gst_vaapiupload_transform( - GstBaseTransform *trans, - GstBuffer *inbuf, - GstBuffer *outbuf -); - -static GstCaps * -gst_vaapiupload_transform_caps( - GstBaseTransform *trans, - GstPadDirection direction, - GstCaps *caps -); - -static gboolean -gst_vaapiupload_set_caps( - GstBaseTransform *trans, - GstCaps *incaps, - GstCaps *outcaps -); - -static gboolean -gst_vaapiupload_get_unit_size( - GstBaseTransform *trans, - GstCaps *caps, - guint *size -); - -static GstFlowReturn -gst_vaapiupload_sinkpad_buffer_alloc( - GstPad *pad, - guint64 offset, - guint size, - GstCaps *caps, - GstBuffer **pbuf -); - -static GstFlowReturn -gst_vaapiupload_prepare_output_buffer( - GstBaseTransform *trans, - GstBuffer *inbuf, - gint size, - GstCaps *caps, - GstBuffer **poutbuf -); - -static gboolean -gst_vaapiupload_query( - GstPad *pad, - GstQuery *query -); - -static void -gst_vaapiupload_destroy(GstVaapiUpload *upload) -{ - g_clear_object(&upload->uploader); -} - -static void -gst_vaapiupload_finalize(GObject *object) -{ - gst_vaapiupload_destroy(GST_VAAPIUPLOAD(object)); - - gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object)); - G_OBJECT_CLASS(gst_vaapiupload_parent_class)->finalize(object); -} - -static void -gst_vaapiupload_class_init(GstVaapiUploadClass *klass) -{ - GObjectClass * const object_class = G_OBJECT_CLASS(klass); - GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass); - GstPadTemplate *pad_template; - - GST_DEBUG_CATEGORY_INIT(gst_debug_vaapiupload, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - - gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass)); - - object_class->finalize = gst_vaapiupload_finalize; - - trans_class->start = gst_vaapiupload_start; - trans_class->stop = gst_vaapiupload_stop; - trans_class->transform = gst_vaapiupload_transform; - trans_class->transform_caps = gst_vaapiupload_transform_caps; - trans_class->set_caps = gst_vaapiupload_set_caps; - trans_class->get_unit_size = gst_vaapiupload_get_unit_size; - trans_class->prepare_output_buffer = gst_vaapiupload_prepare_output_buffer; - - gst_element_class_set_static_metadata(element_class, - "VA-API colorspace converter", - "Filter/Converter/Video", - GST_PLUGIN_DESC, - "Gwenole Beauchesne "); - - /* sink pad */ - pad_template = gst_static_pad_template_get(&gst_vaapiupload_sink_factory); - gst_element_class_add_pad_template(element_class, pad_template); - - /* src pad */ - pad_template = gst_static_pad_template_get(&gst_vaapiupload_src_factory); - gst_element_class_add_pad_template(element_class, pad_template); -} - -static void -gst_vaapiupload_init(GstVaapiUpload *upload) -{ - GstPad *sinkpad, *srcpad; - - gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(upload), GST_CAT_DEFAULT); - - /* Override buffer allocator on sink pad */ - sinkpad = gst_element_get_static_pad(GST_ELEMENT(upload), "sink"); - gst_pad_set_bufferalloc_function( - sinkpad, - gst_vaapiupload_sinkpad_buffer_alloc - ); - gst_pad_set_query_function(sinkpad, gst_vaapiupload_query); - gst_object_unref(sinkpad); - - /* Override query on src pad */ - srcpad = gst_element_get_static_pad(GST_ELEMENT(upload), "src"); - gst_pad_set_query_function(srcpad, gst_vaapiupload_query); - gst_object_unref(srcpad); -} - -static inline gboolean -gst_vaapiupload_ensure_display(GstVaapiUpload *upload) -{ - return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(upload)); -} - -static gboolean -gst_vaapiupload_ensure_uploader(GstVaapiUpload *upload) -{ - if (!gst_vaapiupload_ensure_display(upload)) - return FALSE; - - if (!upload->uploader) { - upload->uploader = gst_vaapi_uploader_new( - GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)); - if (!upload->uploader) - return FALSE; - } - if (!gst_vaapi_uploader_ensure_display(upload->uploader, - GST_VAAPI_PLUGIN_BASE_DISPLAY(upload))) - return FALSE; - return TRUE; -} - -static gboolean -gst_vaapiupload_start(GstBaseTransform *trans) -{ - GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - - if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(trans))) - return FALSE; - if (!gst_vaapiupload_ensure_uploader(upload)) - return FALSE; - return TRUE; -} - -static gboolean -gst_vaapiupload_stop(GstBaseTransform *trans) -{ - gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(trans)); - return TRUE; -} - -static GstFlowReturn -gst_vaapiupload_transform( - GstBaseTransform *trans, - GstBuffer *inbuf, - GstBuffer *outbuf -) -{ - GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - - if (!gst_vaapi_uploader_process(upload->uploader, inbuf, outbuf)) - return GST_FLOW_UNEXPECTED; - return GST_FLOW_OK; -} - -static GstCaps * -gst_vaapiupload_transform_caps( - GstBaseTransform *trans, - GstPadDirection direction, - GstCaps *caps -) -{ - GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - GstCaps *out_caps = NULL; - GstStructure *structure; - - g_return_val_if_fail(GST_IS_CAPS(caps), NULL); - - structure = gst_caps_get_structure(caps, 0); - - if (direction == GST_PAD_SINK) { - if (!gst_structure_has_name(structure, "video/x-raw-yuv")) - return NULL; - out_caps = gst_caps_from_string(gst_vaapiupload_vaapi_caps_str); - - structure = gst_caps_get_structure(out_caps, 0); - gst_structure_set( - structure, - "type", G_TYPE_STRING, "vaapi", - "opengl", G_TYPE_BOOLEAN, USE_GLX, - NULL - ); - } - else { - if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) - return NULL; - out_caps = gst_caps_from_string(gst_vaapiupload_yuv_caps_str); - if (gst_vaapiupload_ensure_uploader(upload)) { - GstCaps *allowed_caps, *inter_caps; - allowed_caps = gst_vaapi_uploader_get_caps(upload->uploader); - if (!allowed_caps) - return NULL; - inter_caps = gst_caps_intersect(out_caps, allowed_caps); - gst_caps_unref(out_caps); - out_caps = inter_caps; - } - } - - if (!gst_vaapi_append_surface_caps(out_caps, caps)) { - gst_caps_unref(out_caps); - return NULL; - } - return out_caps; -} - -static gboolean -gst_vaapiupload_set_caps( - GstBaseTransform *trans, - GstCaps *incaps, - GstCaps *outcaps -) -{ - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(trans); - GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - - if (!gst_vaapi_plugin_base_set_caps(plugin, incaps, outcaps)) - return FALSE; - if (!gst_vaapi_uploader_ensure_caps(upload->uploader, incaps, outcaps)) - return FALSE; - return TRUE; -} - -static gboolean -gst_vaapiupload_get_unit_size( - GstBaseTransform *trans, - GstCaps *caps, - guint *size -) -{ - GstStructure * const structure = gst_caps_get_structure(caps, 0); - GstVideoFormat format; - gint width, height; - - if (gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) - *size = 0; - else { - if (!gst_video_format_parse_caps(caps, &format, &width, &height)) - return FALSE; - *size = gst_video_format_get_size(format, width, height); - } - return TRUE; -} - -static GstFlowReturn -gst_vaapiupload_buffer_alloc( - GstBaseTransform *trans, - guint size, - GstCaps *caps, - GstBuffer **pbuf -) -{ - GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - - *pbuf = NULL; - - if (!gst_vaapi_uploader_ensure_display(upload->uploader, - GST_VAAPI_PLUGIN_BASE_DISPLAY(upload))) - return GST_FLOW_NOT_SUPPORTED; - if (!gst_vaapi_uploader_ensure_caps(upload->uploader, caps, NULL)) - return GST_FLOW_NOT_SUPPORTED; - - /* Allocate a regular GstBuffer if direct rendering is not supported */ - if (!gst_vaapi_uploader_has_direct_rendering(upload->uploader)) - return GST_FLOW_OK; - - *pbuf = gst_vaapi_uploader_get_buffer(upload->uploader); - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_vaapiupload_sinkpad_buffer_alloc( - GstPad *pad, - guint64 offset, - guint size, - GstCaps *caps, - GstBuffer **pbuf -) -{ - GstBaseTransform *trans; - GstFlowReturn ret; - - trans = GST_BASE_TRANSFORM(gst_pad_get_parent_element(pad)); - if (!trans) - return GST_FLOW_UNEXPECTED; - - ret = gst_vaapiupload_buffer_alloc(trans, size, caps, pbuf); - gst_object_unref(trans); - return ret; -} - -static GstFlowReturn -gst_vaapiupload_prepare_output_buffer( - GstBaseTransform *trans, - GstBuffer *inbuf, - gint size, - GstCaps *caps, - GstBuffer **poutbuf -) -{ - GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans); - GstBuffer *buffer; - - *poutbuf = NULL; - - if (!gst_vaapi_uploader_has_direct_rendering(upload->uploader)) - buffer = gst_vaapi_uploader_get_buffer(upload->uploader); - else - buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf); - if (!buffer) - return GST_FLOW_UNEXPECTED; - - gst_buffer_set_caps(buffer, caps); - GST_BUFFER_DATA(buffer) = NULL; - GST_BUFFER_SIZE(buffer) = 0; - - *poutbuf = buffer; - return GST_FLOW_OK; -} - -static gboolean -gst_vaapiupload_query(GstPad *pad, GstQuery *query) -{ - GstVaapiUpload *upload = GST_VAAPIUPLOAD (gst_pad_get_parent_element (pad)); - gboolean res; - - GST_DEBUG ("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)); - - if (gst_vaapi_reply_to_query (query, GST_VAAPI_PLUGIN_BASE_DISPLAY(upload))) - res = TRUE; - else - res = gst_pad_query_default (pad, query); - - gst_object_unref (upload); - return res; -} diff --git a/gst/vaapi/gstvaapiupload.h b/gst/vaapi/gstvaapiupload.h deleted file mode 100644 index 6a2c0776c6..0000000000 --- a/gst/vaapi/gstvaapiupload.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * gstvaapiupload.h - VA-API video upload element - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation - * Author: Gwenole Beauchesne - * - * This program 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free - * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA -*/ - -#ifndef GST_VAAPIUPLOAD_H -#define GST_VAAPIUPLOAD_H - -#include "gstvaapipluginbase.h" -#include "gstvaapiuploader.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VAAPIUPLOAD \ - (gst_vaapiupload_get_type()) - -#define GST_VAAPIUPLOAD(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_TYPE_VAAPIUPLOAD, \ - GstVaapiUpload)) - -#define GST_VAAPIUPLOAD_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_TYPE_VAAPIUPLOAD, \ - GstVaapiUploadClass)) - -#define GST_IS_VAAPIUPLOAD(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPIUPLOAD)) - -#define GST_IS_VAAPIUPLOAD_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPIUPLOAD)) - -#define GST_VAAPIUPLOAD_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_TYPE_VAAPIUPLOAD, \ - GstVaapiUploadClass)) - -typedef struct _GstVaapiUpload GstVaapiUpload; -typedef struct _GstVaapiUploadClass GstVaapiUploadClass; - -struct _GstVaapiUpload { - /*< private >*/ - GstVaapiPluginBase parent_instance; - - GstVaapiUploader *uploader; -}; - -struct _GstVaapiUploadClass { - /*< private >*/ - GstVaapiPluginBaseClass parent_class; -}; - -GType -gst_vaapiupload_get_type(void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* GST_VAAPIUPLOAD_H */ diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index c4e5d14943..7d696e4384 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -479,10 +479,6 @@ gst_vaapi_uploader_get_buffer (GstVaapiUploader * uploader) GST_WARNING ("failed to map VA image"); goto error; } -#if !GST_CHECK_VERSION(1,0,0) - GST_BUFFER_DATA (buffer) = gst_vaapi_image_get_plane (image, 0); - GST_BUFFER_SIZE (buffer) = gst_vaapi_image_get_data_size (image); -#endif return buffer; error: diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 1a5bff5fb7..17641eaad5 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -42,7 +42,7 @@ gst_surface_buffer_new (void) { return gst_buffer_new (); } -#elif GST_CHECK_VERSION(1,0,0) +#else #include #define GST_VAAPI_SURFACE_META_CAST(obj) \ @@ -173,93 +173,7 @@ gst_surface_buffer_new (void) gst_buffer_add_meta (buffer, GST_VAAPI_SURFACE_META_INFO, NULL); return buffer; } -#else -#include -#define GST_VAAPI_TYPE_VIDEO_BUFFER \ - (gst_vaapi_video_buffer_get_type ()) -#define GST_VAAPI_VIDEO_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER, \ - GstVaapiVideoBuffer)) -#define GST_VAAPI_VIDEO_BUFFER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_BUFFER, \ - GstVaapiVideoBufferClass)) -#define GST_VAAPI_IS_VIDEO_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER)) -#define GST_VAAPI_IS_VIDEO_BUFFER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_BUFFER)) -#define GST_VAAPI_VIDEO_BUFFER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER, \ - GstVaapiVideoBufferClass)) - -typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass; - -/** - * GstVaapiVideoBuffer: - * - * A #GstBuffer holding video objects (#GstVaapiSurface and #GstVaapiImage). - */ -struct _GstVaapiVideoBuffer -{ - /*< private >*/ - GstSurfaceBuffer parent_instance; -}; - -/** - * GstVaapiVideoBufferClass: - * - * A #GstBuffer holding video objects - */ -struct _GstVaapiVideoBufferClass -{ - /*< private >*/ - GstSurfaceBufferClass parent_class; -}; - -GType -gst_vaapi_video_buffer_get_type (void) G_GNUC_CONST; - -G_DEFINE_TYPE (GstVaapiVideoBuffer, - gst_vaapi_video_buffer, GST_TYPE_SURFACE_BUFFER); - -typedef GstSurfaceConverter * -(*GstSurfaceConverterCreateFunc) (GstSurfaceBuffer * surface, - const gchar * type, GValue * dest); - -static GstSurfaceConverter * -gst_vaapi_video_buffer_create_converter (GstSurfaceBuffer * surface, - const gchar * type, GValue * dest) -{ - GstVaapiVideoMeta *const meta = - gst_buffer_get_vaapi_video_meta (GST_BUFFER (surface)); - GstSurfaceConverterCreateFunc func; - - g_return_val_if_fail (meta != NULL, NULL); - - func = (GstSurfaceConverterCreateFunc) - gst_vaapi_video_meta_get_surface_converter (meta); - - return func ? func (surface, type, dest) : NULL; -} - -static void -gst_vaapi_video_buffer_class_init (GstVaapiVideoBufferClass * klass) -{ - GstSurfaceBufferClass *const surface_class = GST_SURFACE_BUFFER_CLASS (klass); - - surface_class->create_converter = gst_vaapi_video_buffer_create_converter; -} - -static void -gst_vaapi_video_buffer_init (GstVaapiVideoBuffer * buffer) -{ -} - -static inline GstBuffer * -gst_surface_buffer_new (void) -{ - return GST_BUFFER_CAST (gst_mini_object_new (GST_VAAPI_TYPE_VIDEO_BUFFER)); -} #endif static GFunc diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index 4512d17234..60c1678033 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -29,13 +29,8 @@ #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" -#if GST_CHECK_VERSION(1,0,0) typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *, GstBuffer *); -#else -typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *, - GstSurfaceBuffer *); -#endif static void gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface * iface); diff --git a/gst/vaapi/gstvaapivideoconverter_x11.c b/gst/vaapi/gstvaapivideoconverter_x11.c index 0855562605..22ddd1366b 100644 --- a/gst/vaapi/gstvaapivideoconverter_x11.c +++ b/gst/vaapi/gstvaapivideoconverter_x11.c @@ -26,13 +26,8 @@ #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" -#if GST_CHECK_VERSION(1,0,0) -typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *, - GstBuffer *); -#else typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *, GstSurfaceBuffer *); -#endif static void gst_vaapi_video_converter_x11_iface_init (GstSurfaceConverterInterface * iface); @@ -175,7 +170,6 @@ gst_vaapi_video_converter_x11_upload (GstSurfaceConverter * self, if (!gst_vaapi_apply_composition (surface, buffer)) GST_WARNING ("could not update subtitles"); -#if GST_CHECK_VERSION(1,0,0) GstVideoCropMeta *const crop_meta = gst_buffer_get_video_crop_meta (buffer); if (crop_meta) { GstVaapiRectangle crop_rect_tmp; @@ -185,7 +179,6 @@ gst_vaapi_video_converter_x11_upload (GstSurfaceConverter * self, crop_rect_tmp.width = crop_meta->width; crop_rect_tmp.height = crop_meta->height; } -#endif if (!crop_rect) crop_rect = gst_vaapi_video_meta_get_render_rect (meta); diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index ab97be5f65..ceff5d1588 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -31,10 +31,7 @@ #include #include #include "gstvaapivideometa.h" - -#if GST_CHECK_VERSION(1,0,0) -# include "gstvaapivideomemory.h" -#endif +#include "gstvaapivideomemory.h" #define GST_VAAPI_VIDEO_META(obj) \ ((GstVaapiVideoMeta *) (obj)) @@ -61,14 +58,12 @@ ensure_surface_proxy (GstVaapiVideoMeta * meta) if (!meta->proxy) return FALSE; -#if GST_CHECK_VERSION(1,0,0) if (meta->buffer) { GstMemory *const mem = gst_buffer_peek_memory (meta->buffer, 0); if (GST_VAAPI_IS_VIDEO_MEMORY (mem)) return gst_vaapi_video_memory_sync (GST_VAAPI_VIDEO_MEMORY_CAST (mem)); } -#endif return TRUE; } @@ -146,24 +141,6 @@ gst_vaapi_video_meta_destroy_proxy (GstVaapiVideoMeta * meta) gst_vaapi_surface_proxy_replace (&meta->proxy, NULL); } -#if !GST_CHECK_VERSION(1,0,0) -#define GST_VAAPI_TYPE_VIDEO_META gst_vaapi_video_meta_get_type () -static GType -gst_vaapi_video_meta_get_type (void) -{ - static gsize g_type; - - if (g_once_init_enter (&g_type)) { - GType type; - type = g_boxed_type_register_static ("GstVaapiVideoMeta", - (GBoxedCopyFunc) gst_vaapi_video_meta_ref, - (GBoxedFreeFunc) gst_vaapi_video_meta_unref); - g_once_init_leave (&g_type, type); - } - return (GType) g_type; -} -#endif - static void gst_vaapi_video_meta_finalize (GstVaapiVideoMeta * meta) { @@ -707,8 +684,6 @@ gst_vaapi_video_meta_set_render_rect (GstVaapiVideoMeta * meta, meta->render_rect = *rect; } -#if GST_CHECK_VERSION(1,0,0) - #define GST_VAAPI_VIDEO_META_HOLDER(meta) \ ((GstVaapiVideoMetaHolder *) (meta)) @@ -812,64 +787,3 @@ gst_buffer_set_vaapi_video_meta (GstBuffer * buffer, GstVaapiVideoMeta * meta) if (m) GST_VAAPI_VIDEO_META_HOLDER (m)->meta = gst_vaapi_video_meta_ref (meta); } -#else - -#define GST_VAAPI_VIDEO_META_QUARK gst_vaapi_video_meta_quark_get () -static GQuark -gst_vaapi_video_meta_quark_get (void) -{ - static gsize g_quark; - - if (g_once_init_enter (&g_quark)) { - gsize quark = (gsize) g_quark_from_static_string ("GstVaapiVideoMeta"); - g_once_init_leave (&g_quark, quark); - } - return g_quark; -} - -#define META_QUARK meta_quark_get () -static GQuark -meta_quark_get (void) -{ - static gsize g_quark; - - if (g_once_init_enter (&g_quark)) { - gsize quark = (gsize) g_quark_from_static_string ("meta"); - g_once_init_leave (&g_quark, quark); - } - return g_quark; -} - -GstVaapiVideoMeta * -gst_buffer_get_vaapi_video_meta (GstBuffer * buffer) -{ - GstVaapiVideoMeta *meta; - const GstStructure *structure; - const GValue *value; - - g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); - - structure = gst_buffer_get_qdata (buffer, GST_VAAPI_VIDEO_META_QUARK); - if (!structure) - return NULL; - - value = gst_structure_id_get_value (structure, META_QUARK); - if (!value) - return NULL; - - meta = GST_VAAPI_VIDEO_META (g_value_get_boxed (value)); - meta->buffer = buffer; - return meta; -} - -void -gst_buffer_set_vaapi_video_meta (GstBuffer * buffer, GstVaapiVideoMeta * meta) -{ - g_return_if_fail (GST_IS_BUFFER (buffer)); - g_return_if_fail (GST_VAAPI_IS_VIDEO_META (meta)); - - gst_buffer_set_qdata (buffer, GST_VAAPI_VIDEO_META_QUARK, - gst_structure_id_new (GST_VAAPI_VIDEO_META_QUARK, - META_QUARK, GST_VAAPI_TYPE_VIDEO_META, meta, NULL)); -} -#endif diff --git a/gst/vaapi/gstvaapivideometa.h b/gst/vaapi/gstvaapivideometa.h index 21fd35a4c6..62f4322ebd 100644 --- a/gst/vaapi/gstvaapivideometa.h +++ b/gst/vaapi/gstvaapivideometa.h @@ -35,14 +35,12 @@ G_BEGIN_DECLS typedef struct _GstVaapiVideoMeta GstVaapiVideoMeta; -#if GST_CHECK_VERSION(1,0,0) #define GST_VAAPI_VIDEO_META_API_TYPE \ gst_vaapi_video_meta_api_get_type () G_GNUC_INTERNAL GType gst_vaapi_video_meta_api_get_type (void) G_GNUC_CONST; -#endif G_GNUC_INTERNAL GstVaapiVideoMeta * diff --git a/tests/test-filter.c b/tests/test-filter.c index 8e19fab778..05dfee9d11 100644 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -100,7 +100,7 @@ create_test_surface(GstVaapiDisplay *display, guint width, guint height, GError *error = NULL; if (g_src_format_str) { - format = gst_vaapi_video_format_from_string(g_src_format_str); + format = gst_video_format_from_string(g_src_format_str); if (format == GST_VIDEO_FORMAT_UNKNOWN) goto error_invalid_format; } diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 87cbace6cb..782be089b1 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -130,7 +130,6 @@ main(int argc, char *argv[]) subrect.height = subinfo.height; subrect.width = subinfo.width; -#if GST_CHECK_VERSION(1,0,0) { GstVideoMeta * const vmeta = gst_buffer_add_video_meta(buffer, GST_VIDEO_FRAME_FLAG_NONE, @@ -142,11 +141,6 @@ main(int argc, char *argv[]) overlay = gst_video_overlay_rectangle_new_raw(buffer, subrect.x, subrect.y, subrect.width, subrect.height, flags); } -#else - overlay = gst_video_overlay_rectangle_new_argb(buffer, - subinfo.width, subinfo.height, subinfo.width * 4, - subrect.x, subrect.y, subrect.width, subrect.height, flags); -#endif if (!overlay) g_error("could not create video overlay"); gst_buffer_unref(buffer); From 43d8366ec6d9679d9fb66ecf803f6117f4411c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 16:55:43 +0300 Subject: [PATCH 1928/3781] Remove HAVE_GST_VIDEO_OVERLAY_HWCAPS macro This macro guarded the use of HAVE_GST_VIDEO_OVERLAY_HWCAPS, which was not defined before gstreamer 0.10.35. Since the support of gstreamer-0.10 is deprecated these guards are not required. https://bugzilla.gnome.org/show_bug.cgi?id=745728 https://bugzilla.gnome.org/show_bug.cgi?id=732666 Signed-off-by: Gwenole Beauchesne --- configure.ac | 3 --- gst-libs/gst/vaapi/gstvaapicontext_overlay.c | 2 -- gst-libs/gst/vaapi/gstvaapiutils.c | 4 ---- tests/test-subpicture.c | 6 ------ 4 files changed, 15 deletions(-) diff --git a/configure.ac b/configure.ac index 92e8bdb18e..1a19c5bdc3 100644 --- a/configure.ac +++ b/configure.ac @@ -274,9 +274,6 @@ dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], [gstreamer-video-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) -AC_DEFINE_UNQUOTED([HAVE_GST_VIDEO_OVERLAY_HWCAPS], 1, - [Defined to 1 if GstVideoOverlayComposition API supports HW hints.]) - dnl GStreamer -bad plugins (deprecated in GStreamer v1.2) if test "$USE_GST_API_1_2p" != "yes" && test "$USE_GST_API_1_4p" != "yes"; then PKG_CHECK_MODULES([GST_BASEVIDEO], diff --git a/gst-libs/gst/vaapi/gstvaapicontext_overlay.c b/gst-libs/gst/vaapi/gstvaapicontext_overlay.c index 117f0d8a75..0d670b03db 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext_overlay.c +++ b/gst-libs/gst/vaapi/gstvaapicontext_overlay.c @@ -246,11 +246,9 @@ static inline gboolean overlay_rectangle_update_global_alpha (GstVaapiOverlayRectangle * overlay, GstVideoOverlayRectangle * rect) { -#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS const guint flags = gst_video_overlay_rectangle_get_flags (rect); if (!(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)) return TRUE; -#endif return gst_vaapi_subpicture_set_global_alpha (overlay->subpicture, gst_video_overlay_rectangle_get_global_alpha (rect)); } diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 6c6a5fb46d..117fd4eedf 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -364,12 +364,10 @@ from_GstVideoOverlayFormatFlags (guint ovl_flags) { guint flags = 0; -#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA) flags |= GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA; if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA) flags |= GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA; -#endif return flags; } @@ -386,12 +384,10 @@ to_GstVideoOverlayFormatFlags (guint flags) { guint ovl_flags = 0; -#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS if (flags & GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA) ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA; if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA; -#endif return ovl_flags; } diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 782be089b1..97ca232992 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -41,12 +41,10 @@ static GOptionEntry g_options[] = { 0, G_OPTION_ARG_STRING, &g_codec_str, "codec to test", NULL }, -#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS { "global-alpha", 'g', 0, G_OPTION_ARG_DOUBLE, &g_global_alpha, "global-alpha value", NULL }, -#endif { NULL, } }; @@ -92,10 +90,8 @@ main(int argc, char *argv[]) if (!video_output_init(&argc, argv, g_options)) g_error("failed to initialize video output subsystem"); -#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS if (g_global_alpha != 1.0) flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA; -#endif g_print("Test subpicture\n"); @@ -145,10 +141,8 @@ main(int argc, char *argv[]) g_error("could not create video overlay"); gst_buffer_unref(buffer); -#ifdef HAVE_GST_VIDEO_OVERLAY_HWCAPS if (flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA) gst_video_overlay_rectangle_set_global_alpha(overlay, g_global_alpha); -#endif compo = gst_video_overlay_composition_new(overlay); if (!compo) From f5d3c2d85dfd857e2692c1aaa4c24e0588880000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 17:01:45 +0300 Subject: [PATCH 1929/3781] Remove libgstvaapi-videoutils.so This library was intended to add the base classes for video decoders which where not included in gstreamer-0.10. Since the support of gstreamer-0.10 is deprecated those classes are not required, thus the whole library is removed. https://bugzilla.gnome.org/show_bug.cgi?id=745728 https://bugzilla.gnome.org/show_bug.cgi?id=732666 Signed-off-by: Gwenole Beauchesne --- configure.ac | 1 - gst-libs/gst/Makefile.am | 4 +-- gst-libs/gst/vaapi/Makefile.am | 2 -- gst-libs/gst/video/Makefile.am | 60 ---------------------------------- gst/vaapi/Makefile.am | 3 +- tests/Makefile.am | 9 ++--- 6 files changed, 6 insertions(+), 73 deletions(-) delete mode 100644 gst-libs/gst/video/Makefile.am diff --git a/configure.ac b/configure.ac index 1a19c5bdc3..1f81958b36 100644 --- a/configure.ac +++ b/configure.ac @@ -974,7 +974,6 @@ debian.upstream/libgstvaapi-x11.install.in gst-libs/gst/base/Makefile gst-libs/gst/codecparsers/Makefile gst-libs/gst/vaapi/Makefile - gst-libs/gst/video/Makefile gst/Makefile gst/vaapi/Makefile patches/Makefile diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 823fca438f..8acd19b055 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = base codecparsers video vaapi +SUBDIRS = base codecparsers vaapi # Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in $(gen_headers) +MAINTAINERCLEANFILES = Makefile.in diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 9e5fe88d85..d457b3cc75 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -45,7 +45,6 @@ libgstvaapi_libs = \ $(GST_CODEC_PARSERS_LIBS) \ $(LIBVA_LIBS) \ $(top_builddir)/gst-libs/gst/base/libgstvaapi-baseutils.la \ - $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la \ $(top_builddir)/gst-libs/gst/codecparsers/libgstvaapi-codecparsers.la libgstvaapi_source_c = \ @@ -527,7 +526,6 @@ libgstvaapi_wayland_@GST_API_VERSION@_la_LIBADD = \ $(WAYLAND_LIBS) \ $(LIBVA_WAYLAND_LIBS) \ libgstvaapi-$(GST_API_VERSION).la \ - $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la \ $(NULL) libgstvaapi_wayland_@GST_API_VERSION@_la_LDFLAGS = \ diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am deleted file mode 100644 index 33fea30730..0000000000 --- a/gst-libs/gst/video/Makefile.am +++ /dev/null @@ -1,60 +0,0 @@ -noinst_LTLIBRARIES = \ - libgstvaapi-videoutils.la \ - $(NULL) - -local_videoutils_srcdir = \ - $(top_srcdir)/ext/videoutils/gst-libs/gst/video - -libgstvaapi_videoutils_cflags = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - -I$(top_builddir)/gst-libs \ - $(GST_BASE_CFLAGS) \ - $(GST_CFLAGS) \ - $(NULL) - -libgstvaapi_videoutils_libs = \ - $(GST_BASE_LIBS) \ - $(GST_LIBS) \ - $(NULL) - -gen_source_c = -gen_source_h = - -GENFILES = \ - $(gen_source_c) \ - $(gen_source_h) \ - $(NULL) - -nodist_EXTRA_libgstvaapi_videoutils_la_SOURCES = dummy.c - -nodist_libgstvaapi_videoutils_la_SOURCES = \ - $(gen_source_c) \ - $(NULL) - -libgstvaapi_videoutils_la_CFLAGS = \ - $(libgstvaapi_videoutils_cflags) \ - $(NULL) - -libgstvaapi_videoutils_la_LIBADD = \ - $(libgstvaapi_videoutils_libs) \ - $(NULL) - -libgstvaapi_videoutils_la_LDFLAGS = \ - $(GST_ALL_LDFLAGS) \ - $(NULL) - -all-local: .timestamp.symlinks - -.timestamp.symlinks: $(GENFILES) - touch $@ - -$(gen_source_c): %.c: $(local_videoutils_srcdir)/%.c $(gen_source_h) - $(LN_S) -f $< $@ -$(gen_source_h): %.h: $(local_videoutils_srcdir)/%.h - $(LN_S) -f $< $@ - -DISTCLEANFILES = $(GENFILES) .timestamp.symlinks - -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 30d61558ef..8db30be270 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -180,8 +180,7 @@ libgstvaapi_la_LIBADD = \ $(GST_INTERFACES_LIBS) \ $(GST_BASEVIDEO_LIBS) \ $(GST_PLUGINS_BASE_LIBS) \ - $(GST_ALLOCATORS_LIBS) \ - $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la + $(GST_ALLOCATORS_LIBS) libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvaapi_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/tests/Makefile.am b/tests/Makefile.am index 80826d1a90..9b0168139b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -97,13 +97,11 @@ test_display_LDADD = libutils.la $(TEST_LIBS) test_filter_SOURCES = test-filter.c test_filter_CFLAGS = $(TEST_CFLAGS) -test_filter_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) \ - $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la +test_filter_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) test_surfaces_SOURCES = test-surfaces.c test_surfaces_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) -test_surfaces_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) \ - $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la +test_surfaces_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) test_subpicture_SOURCES = test-subpicture.c test-subpicture-data.c test_subpicture_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) @@ -122,8 +120,7 @@ simple_decoder_source_c = simple-decoder.c simple_decoder_source_h = simple_decoder_SOURCES = $(simple_decoder_source_c) simple_decoder_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) -simple_decoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) \ - $(top_builddir)/gst-libs/gst/video/libgstvaapi-videoutils.la +simple_decoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) EXTRA_DIST = \ test-subpicture-data.h \ From 5deae3bcfbc0d4fd4f1c451b1ac7db277b674cf2 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 3 Apr 2015 17:03:38 +0300 Subject: [PATCH 1930/3781] Remove the gstreamer-videoutils submodule --- .gitmodules | 3 --- ext/Makefile.am | 21 --------------------- ext/videoutils | 1 - 3 files changed, 25 deletions(-) delete mode 160000 ext/videoutils diff --git a/.gitmodules b/.gitmodules index ac8df86ae7..bd53240d8a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "ext/codecparsers"] path = ext/codecparsers url = https://gitorious.org/vaapi/gstreamer-codecparsers.git -[submodule "ext/videoutils"] - path = ext/videoutils - url = https://gitorious.org/vaapi/gstreamer-videoutils.git [submodule "ext/libvpx/upstream"] path = ext/libvpx/upstream url = https://chromium.googlesource.com/webm/libvpx diff --git a/ext/Makefile.am b/ext/Makefile.am index 9915e4a6e7..1444152870 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -52,26 +52,5 @@ videoparsers_source_h = \ EXTRA_DIST += $(videoparsers_source_h:%.h=$(videoparsers_srcdir)/%.h) -videoutils_srcdir = \ - $(top_srcdir)/ext/videoutils/gst-libs/gst/video - -videoutils_source_c = \ - gstvideodecoder.c \ - gstvideoencoder.c \ - gstvideoutils.c \ - video.c \ - $(NULL) - -EXTRA_DIST += $(videoutils_source_c:%.c=$(videoutils_srcdir)/%.c) - -videoutils_source_h = \ - gstvideodecoder.h \ - gstvideoencoder.h \ - gstvideoutils.h \ - video.h \ - $(NULL) - -EXTRA_DIST += $(videoutils_source_h:%.h=$(videoutils_srcdir)/%.h) - # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in diff --git a/ext/videoutils b/ext/videoutils deleted file mode 160000 index f56f0ca70e..0000000000 --- a/ext/videoutils +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f56f0ca70eaa39dc8f66f61e991094b385ed71ff From 1256ce613ae3082285757fb9763e970b703229ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 17:05:45 +0300 Subject: [PATCH 1931/3781] autotools: remove gstreamer-1.0 support This patch only removes the support of gstreamer-1.0 in the autotools scripts. No other files are touched. In the automake file all the converters were deprecated. https://bugzilla.gnome.org/show_bug.cgi?id=745728 Signed-off-by: Gwenole Beauchesne Signed-off-by: Sreerenj Balachandran --- configure.ac | 17 ---------------- gst/vaapi/Makefile.am | 45 ++++--------------------------------------- 2 files changed, 4 insertions(+), 58 deletions(-) diff --git a/configure.ac b/configure.ac index 1f81958b36..91e3419fad 100644 --- a/configure.ac +++ b/configure.ac @@ -27,9 +27,6 @@ m4_define([glib_version], [2.28]) # gstreamer version number m4_define([gst_api_version], [autodetect]) -m4_define([gst1_version], [1.0.0]) -m4_define([gst1_plugins_base_version], [1.0.0]) -m4_define([gst1_plugins_bad_version], [1.0.0]) m4_define([gst12_version], [1.1.90]) m4_define([gst12_plugins_base_version], [1.1.0]) m4_define([gst12_plugins_bad_version], [1.1.0]) @@ -200,11 +197,6 @@ AC_DEFINE_UNQUOTED([GST_API_VERSION_S], ["$GST_API_VERSION"], dnl Versions for GStreamer and plugins-base case $GST_API_VERSION in -1.0) - GST_VERSION_REQUIRED=gst1_version - GST_PLUGINS_BASE_VERSION_REQUIRED=gst1_plugins_base_version - GST_PLUGINS_BAD_VERSION_REQUIRED=gst1_plugins_bad_version - ;; 1.2) GST_VERSION_REQUIRED=gst12_version GST_PLUGINS_BASE_VERSION_REQUIRED=gst12_plugins_base_version @@ -229,16 +221,12 @@ AC_SUBST(GST_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED) -USE_GST_API_1_0p="no" USE_GST_API_1_2p="no" USE_GST_API_1_4p="no" -AS_VERSION_COMPARE([$GST_API_VERSION], [1.0], - [], [USE_GST_API_1_0p="yes"], [USE_GST_API_1_0p="yes"]) AS_VERSION_COMPARE([$GST_API_VERSION], [1.2], [], [USE_GST_API_1_2p="yes"], [USE_GST_API_1_2p="yes"]) AS_VERSION_COMPARE([$GST_API_VERSION], [1.4], [], [USE_GST_API_1_4p="yes"], [USE_GST_API_1_4p="yes"]) -AM_CONDITIONAL([USE_GST_API_1_0p], [test "$USE_GST_API_1_0p" = "yes"]) AM_CONDITIONAL([USE_GST_API_1_2p], [test "$USE_GST_API_1_2p" = "yes"]) AM_CONDITIONAL([USE_GST_API_1_4p], [test "$USE_GST_API_1_4p" = "yes"]) @@ -247,11 +235,6 @@ AC_SUBST([GST_PKG_VERSION]) AC_DEFINE_UNQUOTED([GST_PKG_VERSION_S], ["$GST_PKG_VERSION"], [Defined to the string representation of GStreamer API version]) -dnl Validate certain features -if test "$GST_API_VERSION" = "1.0"; then - AC_MSG_WARN([support for GStreamer 1.0 is obsolete, and will be removed]) -fi - dnl GStreamer Core PKG_CHECK_MODULES([GST], [gstreamer-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 8db30be270..37ecc37251 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -57,6 +57,8 @@ libgstvaapi_source_c = \ gstvaapivideocontext.c \ gstvaapivideometa.c \ gstvaapidecodebin.c \ + gstvaapivideobufferpool.c \ + gstvaapivideomemory.c \ $(NULL) libgstvaapi_source_h = \ @@ -70,6 +72,8 @@ libgstvaapi_source_h = \ gstvaapivideocontext.h \ gstvaapivideometa.h \ gstvaapidecodebin.h \ + gstvaapivideobufferpool.h \ + gstvaapivideomemory.h \ $(NULL) libgstvaapi_enc_source_c = \ @@ -103,26 +107,6 @@ libgstvaapi_source_c += $(libgstvaapi_vp8enc_source_c) libgstvaapi_source_h += $(libgstvaapi_vp8enc_source_h) endif -libgstvaapi_x11_source_c = gstvaapivideoconverter_x11.c -libgstvaapi_x11_source_h = gstvaapivideoconverter_x11.h - -if USE_X11 -if !USE_GST_API_1_2p -libgstvaapi_source_c += $(libgstvaapi_x11_source_c) -libgstvaapi_source_h += $(libgstvaapi_x11_source_h) -endif -endif - -libgstvaapi_glx_source_c = gstvaapivideoconverter_glx.c -libgstvaapi_glx_source_h = gstvaapivideoconverter_glx.h - -if USE_GLX -if !USE_GST_API_1_2p -libgstvaapi_source_c += $(libgstvaapi_glx_source_c) -libgstvaapi_source_h += $(libgstvaapi_glx_source_h) -endif -endif - libgstvaapi_egl_source_c = libgstvaapi_egl_source_h = @@ -144,21 +128,6 @@ libgstvaapi_source_c += $(libgstvaapi_1_2p_source_c) libgstvaapi_source_h += $(libgstvaapi_1_2p_source_h) endif -libgstvaapi_1_0p_source_c = \ - gstvaapivideobufferpool.c \ - gstvaapivideomemory.c \ - $(NULL) - -libgstvaapi_1_0p_source_h = \ - gstvaapivideobufferpool.h \ - gstvaapivideomemory.h \ - $(NULL) - -if USE_GST_API_1_0p -libgstvaapi_source_c += $(libgstvaapi_1_0p_source_c) -libgstvaapi_source_h += $(libgstvaapi_1_0p_source_h) -endif - libgstvaapi_la_SOURCES = $(libgstvaapi_source_c) noinst_HEADERS = $(libgstvaapi_source_h) @@ -259,16 +228,10 @@ EXTRA_DIST = \ $(libgstvaapi_jpegenc_source_h) \ $(libgstvaapi_vp8enc_source_c) \ $(libgstvaapi_vp8enc_source_h) \ - $(libgstvaapi_x11_source_c) \ - $(libgstvaapi_x11_source_h) \ - $(libgstvaapi_glx_source_c) \ - $(libgstvaapi_glx_source_h) \ $(libgstvaapi_egl_source_c) \ $(libgstvaapi_egl_source_h) \ $(libgstvaapi_1_2p_source_c) \ $(libgstvaapi_1_2p_source_h) \ - $(libgstvaapi_1_0p_source_c) \ - $(libgstvaapi_1_0p_source_h) \ $(libgstvaapi_parse_source_c) \ $(libgstvaapi_parse_source_h) \ $(NULL) From c561b8da8aa266963cbe8fc6e1d43984e2a44aed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 17:08:30 +0300 Subject: [PATCH 1932/3781] update and move gstcompat.h The purpose of gstcompat.h is to couple the API differences among gstreamer-1.0 and gstreamer-0.10. Since gstreamer-0.10 is obsolete, the code in this compatibility layer shall be removed. Nevertheless, the gstcompat.h header should be kept, if new incompatibilites appear in the future, but it shall live in gst/vaapi, not in gst-libs. This patch removes the crumbs defined gstcompat.h and moves it to gst/vaapi. In order to avoid layer violations, gstcompat.h includes sysdeps.h and all the includes in gst/vaapi of sysdeps.h are replaced with gstcompat.h https://bugzilla.gnome.org/show_bug.cgi?id=745728 Signed-off-by: Gwenole Beauchesne Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstcompat.h | 71 ------------------------ gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 6 +- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- gst-libs/gst/vaapi/sysdeps.h | 3 +- gst/vaapi/gstcompat.h | 28 ++++++++++ gst/vaapi/gstvaapi.c | 2 +- gst/vaapi/gstvaapidecode.c | 10 ++-- gst/vaapi/gstvaapidecodebin.c | 2 +- gst/vaapi/gstvaapiencode.c | 10 ++-- gst/vaapi/gstvaapiencode_h264.c | 2 +- gst/vaapi/gstvaapiencode_jpeg.c | 2 +- gst/vaapi/gstvaapiencode_mpeg2.c | 2 +- gst/vaapi/gstvaapiencode_vp8.c | 2 +- gst/vaapi/gstvaapiparse.c | 2 +- gst/vaapi/gstvaapipluginbase.c | 2 +- gst/vaapi/gstvaapipluginutil.c | 2 +- gst/vaapi/gstvaapipostproc.c | 2 +- gst/vaapi/gstvaapisink.c | 2 +- gst/vaapi/gstvaapiuploader.c | 2 +- gst/vaapi/gstvaapivideobuffer.c | 2 +- gst/vaapi/gstvaapivideobufferpool.c | 2 +- gst/vaapi/gstvaapivideocontext.c | 2 +- gst/vaapi/gstvaapivideoconverter_glx.c | 2 +- gst/vaapi/gstvaapivideoconverter_x11.c | 2 +- gst/vaapi/gstvaapivideomemory.c | 2 +- gst/vaapi/gstvaapivideometa.c | 2 +- gst/vaapi/gstvaapivideometa_texture.c | 2 +- tests/codec.c | 6 +- 28 files changed, 67 insertions(+), 109 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstcompat.h create mode 100644 gst/vaapi/gstcompat.h diff --git a/gst-libs/gst/vaapi/gstcompat.h b/gst-libs/gst/vaapi/gstcompat.h deleted file mode 100644 index ad5a1724a4..0000000000 --- a/gst-libs/gst/vaapi/gstcompat.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * gstcompat.h - Compatibility glue for GStreamer - * - * Copyright (C) 2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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_COMPAT_H -#define GST_COMPAT_H - -#include - -#include - -/* GstStructure */ -#undef gst_structure_get_fourcc -#define gst_structure_get_fourcc(structure, fieldname, value) \ - gst_compat_structure_get_fourcc(structure, fieldname, value) - -static inline gboolean -gst_compat_structure_get_fourcc(const GstStructure *structure, - const gchar *fieldname, guint32 *value) -{ - const gchar *s = gst_structure_get_string(structure, fieldname); - - if (!s || strlen(s) != 4) - return FALSE; - - *value = GST_MAKE_FOURCC(s[0], s[1], s[2], s[3]); - return TRUE; -} - -/* GstTypeFind */ -#undef GstTypeFindPeekFunction -#define GstTypeFindPeekFunction GstCompatTypeFindPeekFunction -#undef GstTypeFindSuggestFunction -#define GstTypeFindSuggestFunction GstCompatTypeFindSuggestFunction - -typedef const guint8 *(*GstCompatTypeFindPeekFunction)(gpointer, gint64, guint); -typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, GstCaps *); - -/* GstPad */ -#define GST_PAD_CHAIN_FUNCTION_ARGS \ - GstPad *pad, GstObject *parent, GstBuffer *buffer -#define GST_PAD_EVENT_FUNCTION_ARGS \ - GstPad *pad, GstObject *parent, GstEvent *event -#define GST_PAD_QUERY_FUNCTION_ARGS \ - GstPad *pad, GstObject *parent, GstQuery *query -#define GST_PAD_QUERY_FUNCTION_CALL(func, pad, parent, query) \ - (func)(pad, parent, query) - -/* Misc helpers */ -#define GST_MAKE_FORMAT_STRING(FORMAT) \ - "format=(string)" G_STRINGIFY(FORMAT) - -#endif /* GST_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index d37ae9bb12..1aabe13d15 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1124,6 +1124,7 @@ gst_vaapi_decoder_vc1_decode_codec_data(GstVaapiDecoder *base_decoder, gint width, height; guint32 format; gint version; + const gchar *s; priv->has_codec_data = TRUE; @@ -1136,7 +1137,10 @@ gst_vaapi_decoder_vc1_decode_codec_data(GstVaapiDecoder *base_decoder, caps = GST_VAAPI_DECODER_CODEC_STATE(decoder)->caps; structure = gst_caps_get_structure(caps, 0); - if (!gst_structure_get_fourcc(structure, "format", &format)) { + s = gst_structure_get_string(structure, "format"); + if (s && strlen(s) == 4) { + format = GST_MAKE_FOURCC(s[0], s[1], s[2], s[3]); + } else { /* Try to determine format from "wmvversion" property */ if (gst_structure_get_int(structure, "wmvversion", &version)) format = (version >= 1 && version <= 3) ? diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 1c831cdb77..51e273621b 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -127,7 +127,7 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-wmv, wmvversion=3", "main" }, { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, - "video/x-wmv, wmvversion=3, " GST_MAKE_FORMAT_STRING(WVC1), "advanced" + "video/x-wmv, wmvversion=3, format=(string)WVC1", "advanced" }, #if VA_CHECK_VERSION(0,32,0) { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline, diff --git a/gst-libs/gst/vaapi/sysdeps.h b/gst-libs/gst/vaapi/sysdeps.h index e17081f38f..f298f56bcc 100644 --- a/gst-libs/gst/vaapi/sysdeps.h +++ b/gst-libs/gst/vaapi/sysdeps.h @@ -32,6 +32,7 @@ #include #include "glibcompat.h" -#include "gstcompat.h" + +#include #endif /* SYSDEPS_H */ diff --git a/gst/vaapi/gstcompat.h b/gst/vaapi/gstcompat.h new file mode 100644 index 0000000000..c953783fd1 --- /dev/null +++ b/gst/vaapi/gstcompat.h @@ -0,0 +1,28 @@ +/* + * gstcompat.h - Compatibility glue for GStreamer + * + * Copyright (C) 2013 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_COMPAT_H +#define GST_COMPAT_H + +#include "gst/vaapi/sysdeps.h" + +#endif /* GST_COMPAT_H */ diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index bf39038e2d..64ee44c477 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -22,7 +22,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include "gstvaapidecode.h" #include "gstvaapipostproc.h" diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 7ada2b541e..1d2bd7bd2d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -30,7 +30,7 @@ * the vaapisink element. */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include "gstvaapidecode.h" @@ -950,7 +950,7 @@ gst_vaapidecode_get_caps (GstPad * pad) #if !GST_CHECK_VERSION(1,4,0) static gboolean -gst_vaapidecode_query (GST_PAD_QUERY_FUNCTION_ARGS) +gst_vaapidecode_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstVaapiDecode *const decode = GST_VAAPIDECODE (gst_pad_get_parent_element (pad)); @@ -1007,8 +1007,7 @@ gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query) #else GstPad *pad = GST_VIDEO_DECODER_SINK_PAD (vdec); GstObject *parent = gst_pad_get_parent (pad); - ret = GST_PAD_QUERY_FUNCTION_CALL (plugin->sinkpad_query, pad, parent, - query); + ret = plugin->sinkpad_query (pad, parent, query); if (parent) gst_object_unref (parent); #endif @@ -1056,8 +1055,7 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) #else GstPad *pad = GST_VIDEO_DECODER_SRC_PAD (vdec); GstObject *parent = gst_pad_get_parent (pad); - ret = GST_PAD_QUERY_FUNCTION_CALL (plugin->srcpad_query, pad, parent, - query); + ret = plugin->srcpad_query (pad, parent, query); if (parent) gst_object_unref (parent); #endif diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 6454cb9e59..c95e50f168 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include #include diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 1167490296..8e06433456 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -21,7 +21,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include #include "gstvaapiencode.h" @@ -68,7 +68,7 @@ ensure_uploader (GstVaapiEncode * encode) } static gboolean -gst_vaapiencode_query (GST_PAD_QUERY_FUNCTION_ARGS) +gst_vaapiencode_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (gst_pad_get_parent_element (pad)); @@ -79,11 +79,9 @@ gst_vaapiencode_query (GST_PAD_QUERY_FUNCTION_ARGS) if (gst_vaapi_reply_to_query (query, plugin->display)) success = TRUE; else if (GST_PAD_IS_SINK (pad)) - success = GST_PAD_QUERY_FUNCTION_CALL (plugin->sinkpad_query, - plugin->sinkpad, parent, query); + success = plugin->sinkpad_query (plugin->sinkpad, parent, query); else - success = GST_PAD_QUERY_FUNCTION_CALL (plugin->srcpad_query, - plugin->srcpad, parent, query); + success = plugin->srcpad_query (plugin->srcpad, parent, query); gst_object_unref (plugin); return success; diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 3c16c91cee..0f2bb64bc3 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -21,7 +21,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include #include diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 07ce6eae13..009287a25c 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include #include "gstvaapiencode_jpeg.h" diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 0d6fb74c3d..9bbaa0020d 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -21,7 +21,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include #include "gstvaapiencode_mpeg2.h" diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 0cba42b759..7e7099af7f 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include #include "gstvaapiencode_vp8.h" diff --git a/gst/vaapi/gstvaapiparse.c b/gst/vaapi/gstvaapiparse.c index 81724be99d..f29e503dd9 100644 --- a/gst/vaapi/gstvaapiparse.c +++ b/gst/vaapi/gstvaapiparse.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include "gstvaapiparse.h" #include "gsth264parse.h" diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 7a9a3fa7f3..d2639a5c7e 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -22,7 +22,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include #include "gstvaapipluginbase.h" diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index d9dfd5ed2a..d388eb3a60 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -22,7 +22,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include "gstvaapivideocontext.h" #if USE_DRM # include diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index f47a419f40..dc72948b34 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -29,7 +29,7 @@ * implemented. */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include "gstvaapipostproc.h" diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 192cfa2c67..1b30fa5afd 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -31,7 +31,7 @@ * create its own internal window and render into it. */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c index 7d696e4384..70e654fc1c 100644 --- a/gst/vaapi/gstvaapiuploader.c +++ b/gst/vaapi/gstvaapiuploader.c @@ -22,7 +22,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include #include diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 17641eaad5..6e27e029eb 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -27,7 +27,7 @@ * @short_description: VA video buffer for GStreamer */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include "gstvaapivideobuffer.h" #if USE_X11 && !GST_CHECK_VERSION(1,1,0) # include "gstvaapivideoconverter_x11.h" diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 5aaf7eb830..74a18aaf41 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include "gstvaapivideobufferpool.h" #include "gstvaapivideobuffer.h" #include "gstvaapivideomemory.h" diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 54645c325f..6c3ee0916f 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -23,7 +23,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include "gstvaapivideocontext.h" #if GST_CHECK_VERSION(1,1,0) diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c index 60c1678033..4cf1c822fc 100644 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ b/gst/vaapi/gstvaapivideoconverter_glx.c @@ -22,7 +22,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include "gstvaapivideoconverter_glx.h" #include "gstvaapivideoconverter_x11.h" diff --git a/gst/vaapi/gstvaapivideoconverter_x11.c b/gst/vaapi/gstvaapivideoconverter_x11.c index 22ddd1366b..6fda71c76a 100644 --- a/gst/vaapi/gstvaapivideoconverter_x11.c +++ b/gst/vaapi/gstvaapivideoconverter_x11.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include "gstvaapivideoconverter_x11.h" #include "gstvaapipluginutil.h" diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 3583530696..409cdd48c7 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -20,7 +20,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include #include diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index ceff5d1588..aef333e440 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -27,7 +27,7 @@ * @short_description: VA video meta for GStreamer */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include #include #include "gstvaapivideometa.h" diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 64efdcdc62..e1b4331d8d 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -24,7 +24,7 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include "gstcompat.h" #include "gst/vaapi/ogl_compat.h" #include "gstvaapivideometa.h" #include "gstvaapivideometa_texture.h" diff --git a/tests/codec.c b/tests/codec.c index 0269ae6c25..b30c0af4b5 100644 --- a/tests/codec.c +++ b/tests/codec.c @@ -42,7 +42,7 @@ static const CodecMap g_codec_map[] = { { "wmv3", GST_VAAPI_CODEC_VC1, "video/x-wmv, wmvversion=3" }, { "vc1", GST_VAAPI_CODEC_VC1, - "video/x-wmv, wmvversion=3, " GST_MAKE_FORMAT_STRING(WVC1) }, + "video/x-wmv, wmvversion=3, format=(string)WVC1" }, { NULL, } }; @@ -156,8 +156,8 @@ codec_identifier_new(const gchar *filename) goto error; tfp = &cip->type_find; - tfp->peek = (GstTypeFindPeekFunction)codec_identifier_peek; - tfp->suggest = (GstTypeFindSuggestFunction)codec_identifier_suggest; + tfp->peek = codec_identifier_peek; + tfp->suggest = codec_identifier_suggest; tfp->data = cip; return cip; From 8b36e25f477b165a4c1b3c08961d9bf1b51b1e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 17:09:08 +0300 Subject: [PATCH 1933/3781] Removal of gstreamer-1.0 support The support for GStreamer 1.0 has been obsoleted in 0.5.10 release. GStreamer 1.2 is the a minimal requirement for building the gstreamer-vaapi. This patch removes all the pre-processor conditional code compilation guarded for gstreamer-1.0. Thus, all the video converters were removed too. https://bugzilla.gnome.org/show_bug.cgi?id=745728 Signed-off-by: Gwenole Beauchesne Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapidecode.c | 30 +---- gst/vaapi/gstvaapidecodebin.c | 7 - gst/vaapi/gstvaapiencode_h264.c | 4 - gst/vaapi/gstvaapiencode_jpeg.c | 4 - gst/vaapi/gstvaapiencode_mpeg2.c | 4 - gst/vaapi/gstvaapiencode_vp8.c | 4 - gst/vaapi/gstvaapipluginbase.c | 38 +----- gst/vaapi/gstvaapipluginutil.c | 176 ------------------------- gst/vaapi/gstvaapipluginutil.h | 5 - gst/vaapi/gstvaapipostproc.c | 35 ----- gst/vaapi/gstvaapisink.c | 9 -- gst/vaapi/gstvaapivideobuffer.c | 150 --------------------- gst/vaapi/gstvaapivideobufferpool.c | 4 +- gst/vaapi/gstvaapivideocontext.c | 4 - gst/vaapi/gstvaapivideocontext.h | 20 --- gst/vaapi/gstvaapivideoconverter_glx.h | 89 ------------- gst/vaapi/gstvaapivideoconverter_x11.h | 87 ------------ gst/vaapi/gstvaapivideomemory.h | 4 - gst/vaapi/gstvaapivideometa_texture.c | 2 +- 19 files changed, 9 insertions(+), 667 deletions(-) delete mode 100644 gst/vaapi/gstvaapivideoconverter_glx.h delete mode 100644 gst/vaapi/gstvaapivideoconverter_x11.h diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1d2bd7bd2d..05c9d0c33c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -36,7 +36,7 @@ #include "gstvaapidecode.h" #include "gstvaapipluginutil.h" #include "gstvaapivideobuffer.h" -#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) +#if (USE_GLX || USE_EGL) #include "gstvaapivideometa_texture.h" #endif #include "gstvaapivideobufferpool.h" @@ -74,15 +74,11 @@ static const char gst_vaapidecode_sink_caps_str[] = ; static const char gst_vaapidecode_src_caps_str[] = -#if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES( GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") ";" GST_VIDEO_CAPS_MAKE_WITH_FEATURES( GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") ";" GST_VIDEO_CAPS_MAKE("{ I420, YV12, NV12 }"); -#else - GST_VAAPI_SURFACE_CAPS; -#endif static GstStaticPadTemplate gst_vaapidecode_sink_factory = GST_STATIC_PAD_TEMPLATE( @@ -178,7 +174,6 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) ref_state = decode->input_state; -#if GST_CHECK_VERSION(1,1,0) GstCapsFeatures *features = NULL; GstVaapiCapsFeature feature; @@ -209,7 +204,6 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) default: break; } -#endif state = gst_video_decoder_set_output_state (vdec, format, ref_state->info.width, ref_state->info.height, @@ -219,27 +213,9 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) vi = &state->info; -#if GST_CHECK_VERSION(1,1,0) state->caps = gst_video_info_to_caps (vi); if (features) gst_caps_set_features (state->caps, 0, features); -#else - /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not - reconstruct suitable caps for "encoded" video formats */ - state->caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS_NAME); - if (!state->caps) - return FALSE; - - gst_caps_set_simple (state->caps, - "type", G_TYPE_STRING, "vaapi", - "opengl", G_TYPE_BOOLEAN, USE_GLX, - "width", G_TYPE_INT, vi->width, - "height", G_TYPE_INT, vi->height, - "framerate", GST_TYPE_FRACTION, vi->fps_n, vi->fps_d, - "pixel-aspect-ratio", GST_TYPE_FRACTION, vi->par_n, vi->par_d, NULL); - - gst_caps_set_interlaced (state->caps, vi); -#endif gst_caps_replace (&decode->srcpad_caps, state->caps); gst_video_codec_state_unref (state); return TRUE; @@ -303,7 +279,7 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, crop_meta->height = crop_rect->height; } } -#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) +#if (USE_GLX || USE_EGL) if (decode->has_texture_upload_meta) gst_buffer_ensure_texture_upload_meta (out_frame->output_buffer); #endif @@ -541,7 +517,7 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) gst_vaapi_find_preferred_caps_feature (GST_VIDEO_DECODER_SRC_PAD (vdec), GST_VIDEO_FORMAT_ENCODED, &out_format); decode->has_texture_upload_meta = FALSE; -#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) +#if (USE_GLX || USE_EGL) decode->has_texture_upload_meta = (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) && gst_query_find_allocation_meta (query, diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index c95e50f168..cfeae5e023 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -46,14 +46,9 @@ enum PROP_MAX_SIZE_TIME }; -#if GST_CHECK_VERSION(1,1,0) #define GST_VAAPI_DECODE_BIN_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") -#else -#define GST_VAAPI_DECODE_BIN_SURFACE_CAPS \ - GST_VAAPI_SURFACE_CAPS -#endif /* Default templates */ #define GST_CAPS_CODEC(CODEC) CODEC "; " @@ -75,11 +70,9 @@ static const char gst_vaapi_decode_bin_sink_caps_str[] = static const char gst_vaapi_decode_bin_src_caps_str[] = GST_VAAPI_DECODE_BIN_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " -#if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") ", " GST_CAPS_INTERLACED_FALSE "; " -#endif GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 0f2bb64bc3..2a95d65001 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -42,12 +42,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_h264_sink_caps_str[] = -#if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ", " -#else - GST_VAAPI_SURFACE_CAPS ", " -#endif GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 009287a25c..78304f90e6 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -38,12 +38,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_jpeg_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_jpeg_sink_caps_str[] = -#if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ", " -#else - GST_VAAPI_SURFACE_CAPS ", " -#endif GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 9bbaa0020d..d48252632c 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -40,12 +40,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = -#if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ", " -#else - GST_VAAPI_SURFACE_CAPS ", " -#endif GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 7e7099af7f..eb4bb1dfb1 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -38,12 +38,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp8_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_vp8_sink_caps_str[] = -#if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ", " -#else - GST_VAAPI_SURFACE_CAPS ", " -#endif GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index d2639a5c7e..37aa39089b 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -30,9 +30,7 @@ #include "gstvaapivideocontext.h" #include "gstvaapivideometa.h" #include "gstvaapivideobufferpool.h" -#if GST_CHECK_VERSION(1,1,0) #include -#endif /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) @@ -57,7 +55,6 @@ plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) gst_vaapi_display_unref (display); } -#if GST_CHECK_VERSION(1,1,0) static void plugin_set_context (GstElement * element, GstContext * context) { @@ -67,33 +64,10 @@ plugin_set_context (GstElement * element, GstContext * context) if (gst_vaapi_video_context_get_display (context, &display)) plugin_set_display (plugin, display); } -#else -static void -plugin_set_context (GstVideoContext * context, const gchar * type, - const GValue * value) -{ - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (context); - GstVaapiDisplay *display = NULL; - - gst_vaapi_set_display (type, value, &display); - plugin_set_display (plugin, display); -} - -static void -video_context_interface_init (GstVideoContextInterface * iface) -{ - iface->set_context = plugin_set_context; -} - -#define GstVideoContextClass GstVideoContextInterface -#endif void gst_vaapi_plugin_base_init_interfaces (GType g_define_type_id) { -#if !GST_CHECK_VERSION(1,1,0) - G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_CONTEXT, video_context_interface_init); -#endif } static gboolean @@ -133,7 +107,6 @@ plugin_update_sinkpad_info_from_buffer (GstVaapiPluginBase * plugin, return TRUE; } -#if GST_CHECK_VERSION(1,1,0) static gboolean is_dma_buffer (GstBuffer * buf) { @@ -197,7 +170,6 @@ error_create_proxy: GST_ERROR ("failed to create VA surface proxy from wrapped VA surface"); return FALSE; } -#endif void gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) @@ -205,10 +177,8 @@ gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) klass->has_interface = default_has_interface; klass->display_changed = default_display_changed; -#if GST_CHECK_VERSION(1,1,0) GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); element_class->set_context = GST_DEBUG_FUNCPTR (plugin_set_context); -#endif } void @@ -640,7 +610,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gboolean need_pool, update_pool; gboolean has_video_meta = FALSE; gboolean has_video_alignment = FALSE; -#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) +#if (USE_GLX || USE_EGL) gboolean has_texture_upload_meta = FALSE; guint idx; #endif @@ -664,7 +634,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, has_video_meta = gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); -#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) +#if (USE_GLX || USE_EGL) has_texture_upload_meta = gst_query_find_allocation_meta (query, GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx) && (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); @@ -746,7 +716,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, } /* GstVideoGLTextureUploadMeta (OpenGL) */ -#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) +#if (USE_GLX || USE_EGL) if (has_texture_upload_meta) { config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_add_option (config, @@ -871,13 +841,11 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, &outbuf, NULL) != GST_FLOW_OK) goto error_create_buffer; -#if GST_CHECK_VERSION(1,1,0) if (is_dma_buffer (inbuf)) { if (!plugin_bind_dma_to_vaapi_buffer (plugin, inbuf, outbuf)) goto error_bind_dma_buffer; goto done; } -#endif if (!gst_video_frame_map (&src_frame, &plugin->sinkpad_info, inbuf, GST_MAP_READ)) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index d388eb3a60..cb490601b9 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -278,75 +278,9 @@ gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type) return TRUE; } -void -gst_vaapi_set_display (const gchar * type, - const GValue * value, GstVaapiDisplay ** display_ptr) -{ - GstVaapiDisplay *display = NULL; - - if (!strcmp (type, "vaapi-display")) { - g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); - display = gst_vaapi_display_new_with_display (g_value_get_pointer (value)); - } else if (!strcmp (type, "gst-vaapi-display")) { - g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); - display = gst_vaapi_display_ref (g_value_get_pointer (value)); - } -#if USE_DRM - else if (!strcmp (type, "drm-device")) { - gint device; - g_return_if_fail (G_VALUE_HOLDS_INT (value)); - device = g_value_get_int (value); - display = gst_vaapi_display_drm_new_with_device (device); - } else if (!strcmp (type, "drm-device-path")) { - const gchar *device_path; - g_return_if_fail (G_VALUE_HOLDS_STRING (value)); - device_path = g_value_get_string (value); - display = gst_vaapi_display_drm_new (device_path); - } -#endif -#if USE_X11 - else if (!strcmp (type, "x11-display-name")) { - g_return_if_fail (G_VALUE_HOLDS_STRING (value)); -#if USE_GLX - display = gst_vaapi_display_glx_new (g_value_get_string (value)); -#endif - if (!display) - display = gst_vaapi_display_x11_new (g_value_get_string (value)); - } else if (!strcmp (type, "x11-display")) { - g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); -#if USE_GLX - display = - gst_vaapi_display_glx_new_with_display (g_value_get_pointer (value)); -#endif - if (!display) - display = - gst_vaapi_display_x11_new_with_display (g_value_get_pointer (value)); - } -#endif -#if USE_WAYLAND - else if (!strcmp (type, "wl-display")) { - struct wl_display *wl_display; - g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); - wl_display = g_value_get_pointer (value); - display = gst_vaapi_display_wayland_new_with_display (wl_display); - } else if (!strcmp (type, "wl-display-name")) { - const gchar *display_name; - g_return_if_fail (G_VALUE_HOLDS_STRING (value)); - display_name = g_value_get_string (value); - display = gst_vaapi_display_wayland_new (display_name); - } -#endif - - if (display) { - gst_vaapi_display_replace (display_ptr, display); - gst_vaapi_display_unref (display); - } -} - gboolean gst_vaapi_reply_to_query (GstQuery * query, GstVaapiDisplay * display) { -#if GST_CHECK_VERSION(1,1,0) const gchar *type = NULL; GstContext *context; @@ -367,88 +301,6 @@ gst_vaapi_reply_to_query (GstQuery * query, GstVaapiDisplay * display) gst_context_unref (context); return TRUE; -#else - GstVaapiDisplayType display_type; - const gchar **types; - const gchar *type; - gint i; - gboolean res = FALSE; - - if (GST_QUERY_TYPE (query) != GST_QUERY_CUSTOM) - return FALSE; - - if (!display) - return FALSE; - - types = gst_video_context_query_get_supported_types (query); - - if (!types) - return FALSE; - - display_type = gst_vaapi_display_get_display_type (display); - for (i = 0; types[i] && !res; i++) { - type = types[i]; - - res = TRUE; - if (!strcmp (type, "gst-vaapi-display")) { - gst_video_context_query_set_pointer (query, type, display); - } else if (!strcmp (type, "vaapi-display")) { - VADisplay vadpy = gst_vaapi_display_get_display (display); - gst_video_context_query_set_pointer (query, type, vadpy); - } else { - switch (display_type) { -#if USE_DRM - case GST_VAAPI_DISPLAY_TYPE_DRM:{ - GstVaapiDisplayDRM *const drm_dpy = GST_VAAPI_DISPLAY_DRM (display); - if (!strcmp (type, "drm-device-path")) - gst_video_context_query_set_string (query, type, - gst_vaapi_display_drm_get_device_path (drm_dpy)); -#if 0 - /* XXX: gst_video_context_query_set_int() does not exist yet */ - else if (!strcmp (type, "drm-device")) - gst_video_context_query_set_int (query, type, - gst_vaapi_display_drm_get_device (drm_dpy)); -#endif - else - res = FALSE; - break; - } -#endif -#if USE_X11 - case GST_VAAPI_DISPLAY_TYPE_X11:{ - GstVaapiDisplayX11 *const xvadpy = GST_VAAPI_DISPLAY_X11 (display); - Display *const x11dpy = gst_vaapi_display_x11_get_display (xvadpy); - if (!strcmp (type, "x11-display")) - gst_video_context_query_set_pointer (query, type, x11dpy); - else if (!strcmp (type, "x11-display-name")) - gst_video_context_query_set_string (query, type, - DisplayString (x11dpy)); - else - res = FALSE; - break; - } -#endif -#if USE_WAYLAND - case GST_VAAPI_DISPLAY_TYPE_WAYLAND:{ - GstVaapiDisplayWayland *const wlvadpy = - GST_VAAPI_DISPLAY_WAYLAND (display); - struct wl_display *const wldpy = - gst_vaapi_display_wayland_get_display (wlvadpy); - if (!strcmp (type, "wl-display")) - gst_video_context_query_set_pointer (query, type, wldpy); - else - res = FALSE; - break; - } -#endif - default: - res = FALSE; - break; - } - } - } - return res; -#endif /* !GST_CHECK_VERSION(1,1,0) */ } gboolean @@ -584,7 +436,6 @@ gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, if (!caps) return NULL; -#if GST_CHECK_VERSION(1,1,0) GstCapsFeatures *const features = gst_caps_features_new (features_string, NULL); if (!features) { @@ -592,19 +443,14 @@ gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, return NULL; } gst_caps_set_features (caps, 0, features); -#endif return caps; } static GstCaps * new_gl_texture_upload_meta_caps (void) { -#if GST_CHECK_VERSION(1,1,0) return gst_caps_from_string (GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }")); -#else - return gst_caps_new_empty (); -#endif } GstVaapiCapsFeature @@ -612,7 +458,6 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, GstVideoFormat * out_format_ptr) { GstVaapiCapsFeature feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; -#if GST_CHECK_VERSION(1,1,0) guint i, num_structures; GstCaps *caps = NULL; GstCaps *gl_texture_upload_caps = NULL; @@ -682,7 +527,6 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, } if (out_format_ptr) { -#if GST_CHECK_VERSION(1,1,0) if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) { GstStructure *structure; gchar *format_str; @@ -703,7 +547,6 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, } while (0); if (!out_format) goto cleanup; -#endif } *out_format_ptr = out_format; } @@ -714,7 +557,6 @@ cleanup: gst_caps_replace (&vaapi_caps, NULL); gst_caps_replace (&caps, NULL); gst_caps_replace (&out_caps, NULL); -#endif return feature; } @@ -724,7 +566,6 @@ gst_vaapi_caps_feature_to_string (GstVaapiCapsFeature feature) const gchar *str; switch (feature) { -#if GST_CHECK_VERSION(1,1,0) case GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY: str = GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY; break; @@ -734,7 +575,6 @@ gst_vaapi_caps_feature_to_string (GstVaapiCapsFeature feature) case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE: str = GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE; break; -#endif default: str = NULL; break; @@ -782,7 +622,6 @@ gst_caps_has_vaapi_surface (GstCaps * caps) if (num_structures < 1) return FALSE; -#if GST_CHECK_VERSION(1,1,0) for (i = 0; i < num_structures && !found_caps; i++) { GstCapsFeatures *const features = gst_caps_get_features (caps, i); @@ -795,21 +634,6 @@ gst_caps_has_vaapi_surface (GstCaps * caps) found_caps = gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE); } -#else - for (i = 0; i < num_structures && !found_caps; i++) { - GstStructure *const structure = gst_caps_get_structure (caps, i); - GstCaps *test_caps; - GstVideoInfo vi; - - test_caps = gst_caps_new_full (gst_structure_copy (structure), NULL); - if (!test_caps) - continue; - - found_caps = gst_video_info_from_caps (&vi, test_caps) && - GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED; - gst_caps_unref (test_caps); - } -#endif return found_caps; } diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 9d07a49d6f..0209d08d91 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -33,11 +33,6 @@ G_GNUC_INTERNAL gboolean gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type); -G_GNUC_INTERNAL -void -gst_vaapi_set_display (const gchar * type, - const GValue * value, GstVaapiDisplay ** display_ptr); - G_GNUC_INTERNAL gboolean gst_vaapi_reply_to_query (GstQuery * query, GstVaapiDisplay * display); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index dc72948b34..e1ea5ac7ce 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -44,14 +44,9 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapipostproc); #define GST_CAT_DEFAULT gst_debug_vaapipostproc -#if GST_CHECK_VERSION(1,1,0) # define GST_VAAPIPOSTPROC_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") -#else -# define GST_VAAPIPOSTPROC_SURFACE_CAPS \ - GST_VAAPI_SURFACE_CAPS -#endif /* Default templates */ /* *INDENT-OFF* */ @@ -66,11 +61,9 @@ static const char gst_vaapipostproc_sink_caps_str[] = static const char gst_vaapipostproc_src_caps_str[] = GST_VAAPIPOSTPROC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " -#if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") ", " GST_CAPS_INTERLACED_FALSE "; " -#endif GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ @@ -961,12 +954,10 @@ expand_allowed_srcpad_caps (GstVaapiPostproc * postproc, GstCaps * caps) num_structures = gst_caps_get_size (caps); for (i = 0; i < num_structures; i++) { -#if GST_CHECK_VERSION(1,1,0) GstCapsFeatures *const features = gst_caps_get_features (caps, i); if (gst_caps_features_contains (features, GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META)) continue; -#endif GstStructure *const structure = gst_caps_get_structure (caps, i); if (!structure) @@ -1038,10 +1029,8 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, GstVideoInfo vi; GstVideoFormat out_format; GstCaps *out_caps; -#if GST_CHECK_VERSION(1,1,0) GstVaapiCapsFeature feature; const gchar *feature_str; -#endif guint width, height; /* Generate the sink pad caps, that could be fixated afterwards */ @@ -1081,7 +1070,6 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, find_best_size (postproc, &vi, &width, &height); // Update format from user-specified parameters -#if GST_CHECK_VERSION(1,1,0) /* XXX: this is a workaround until auto-plugging is fixed when * format=ENCODED + memory:VASurface caps feature are provided. * use the downstream negotiated video format as the output format @@ -1109,12 +1097,8 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, feature = gst_vaapi_find_preferred_caps_feature (GST_BASE_TRANSFORM_SRC_PAD (trans), out_format, &out_format); -#else - out_format = GST_VIDEO_FORMAT_ENCODED; -#endif gst_video_info_change_format (&vi, out_format, width, height); -#if GST_CHECK_VERSION(1,1,0) out_caps = gst_video_info_to_caps (&vi); if (!out_caps) return NULL; @@ -1125,25 +1109,6 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, gst_caps_set_features (out_caps, 0, gst_caps_features_new (feature_str, NULL)); } -#else - /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not - reconstruct suitable caps for "encoded" video formats */ - out_caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS_NAME); - if (!out_caps) - return NULL; - - gst_caps_set_simple (out_caps, - "type", G_TYPE_STRING, "vaapi", - "opengl", G_TYPE_BOOLEAN, USE_GLX, - "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH (&vi), - "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT (&vi), - "framerate", GST_TYPE_FRACTION, GST_VIDEO_INFO_FPS_N (&vi), - GST_VIDEO_INFO_FPS_D (&vi), - "pixel-aspect-ratio", GST_TYPE_FRACTION, GST_VIDEO_INFO_PAR_N (&vi), - GST_VIDEO_INFO_PAR_D (&vi), NULL); - - gst_caps_set_interlaced (out_caps, &vi); -#endif return out_caps; } diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 1b30fa5afd..75310c487f 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -57,14 +57,9 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapisink); /* Default template */ /* *INDENT-OFF* */ static const char gst_vaapisink_sink_caps_str[] = -#if GST_CHECK_VERSION(1,1,0) GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ";" GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL); -#else - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) "; " - GST_VAAPI_SURFACE_CAPS; -#endif /* *INDENT-ON* */ static GstStaticPadTemplate gst_vaapisink_sink_factory = @@ -1203,11 +1198,7 @@ gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); GstCaps *out_caps, *yuv_caps; -#if GST_CHECK_VERSION(1,1,0) out_caps = gst_static_pad_template_get_caps (&gst_vaapisink_sink_factory); -#else - out_caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS); -#endif if (!out_caps) return NULL; diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 6e27e029eb..68dbff3d15 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -29,152 +29,12 @@ #include "gstcompat.h" #include "gstvaapivideobuffer.h" -#if USE_X11 && !GST_CHECK_VERSION(1,1,0) -# include "gstvaapivideoconverter_x11.h" -#endif -#if USE_GLX && !GST_CHECK_VERSION(1,1,0) -# include "gstvaapivideoconverter_glx.h" -#endif -#if GST_CHECK_VERSION(1,1,0) static inline GstBuffer * gst_surface_buffer_new (void) { return gst_buffer_new (); } -#else -#include - -#define GST_VAAPI_SURFACE_META_CAST(obj) \ - ((GstVaapiSurfaceMeta *) (obj)) - -typedef struct _GstVaapiSurfaceMeta GstVaapiSurfaceMeta; -struct _GstVaapiSurfaceMeta -{ - GstSurfaceMeta base; - GstBuffer *buffer; -}; - -#define GST_VAAPI_SURFACE_META_INFO \ - gst_vaapi_surface_meta_get_info () - -static const GstMetaInfo * -gst_vaapi_surface_meta_get_info (void); - -typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc) (GstSurfaceMeta * - meta, const gchar * type, GValue * dest); - -#if USE_X11 -static GstSurfaceConverter * -gst_vaapi_surface_create_converter_x11 (GstSurfaceMeta * base_meta, - const gchar * type, GValue * dest) -{ - GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta); - - return gst_vaapi_video_converter_x11_new (meta->buffer, type, dest); -} - -#undef gst_vaapi_video_converter_x11_new -#define gst_vaapi_video_converter_x11_new \ - gst_vaapi_surface_create_converter_x11 -#endif - -#if USE_GLX -static GstSurfaceConverter * -gst_vaapi_surface_create_converter_glx (GstSurfaceMeta * base_meta, - const gchar * type, GValue * dest) -{ - GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta); - - return gst_vaapi_video_converter_glx_new (meta->buffer, type, dest); -} - -#undef gst_vaapi_video_converter_glx_new -#define gst_vaapi_video_converter_glx_new \ - gst_vaapi_surface_create_converter_glx -#endif - -static GstSurfaceConverter * -gst_vaapi_surface_create_converter (GstSurfaceMeta * base_meta, - const gchar * type, GValue * dest) -{ - GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta); - GstVaapiVideoMeta *const vmeta = - gst_buffer_get_vaapi_video_meta (meta->buffer); - GstSurfaceConverterCreateFunc func; - - if (G_UNLIKELY (!vmeta)) - return NULL; - - func = (GstSurfaceConverterCreateFunc) - gst_vaapi_video_meta_get_surface_converter (vmeta); - - return func ? func (base_meta, type, dest) : NULL; -} - -static gboolean -gst_vaapi_surface_meta_init (GstVaapiSurfaceMeta * meta, gpointer params, - GstBuffer * buffer) -{ - meta->base.create_converter = gst_vaapi_surface_create_converter; - meta->buffer = buffer; - return TRUE; -} - -static void -gst_vaapi_surface_meta_free (GstVaapiSurfaceMeta * meta, GstBuffer * buffer) -{ -} - -static gboolean -gst_vaapi_surface_meta_transform (GstBuffer * dst_buffer, GstMeta * meta, - GstBuffer * src_buffer, GQuark type, gpointer data) -{ - GstVaapiVideoMeta *const src_vmeta = - gst_buffer_get_vaapi_video_meta (src_buffer); - - if (GST_META_TRANSFORM_IS_COPY (type)) { - GstVaapiSurfaceMeta *const dst_smeta = - GST_VAAPI_SURFACE_META_CAST (gst_buffer_add_meta (dst_buffer, - GST_VAAPI_SURFACE_META_INFO, NULL)); - - /* Note: avoid meta lookups in gst_vaapi_surface_create_converter() - by directly calling the GstVaapiVideoMeta::surface_converter hook */ - dst_smeta->base.create_converter = (GstSurfaceConverterCreateFunc) - gst_vaapi_video_meta_get_surface_converter (src_vmeta); - return TRUE; - } - return FALSE; -} - -const GstMetaInfo * -gst_vaapi_surface_meta_get_info (void) -{ - static gsize g_meta_info; - - if (g_once_init_enter (&g_meta_info)) { - gsize meta_info = - GPOINTER_TO_SIZE (gst_meta_register (GST_SURFACE_META_API_TYPE, - "GstVaapiSurfaceMeta", sizeof (GstVaapiSurfaceMeta), - (GstMetaInitFunction) gst_vaapi_surface_meta_init, - (GstMetaFreeFunction) gst_vaapi_surface_meta_free, - (GstMetaTransformFunction) gst_vaapi_surface_meta_transform)); - g_once_init_leave (&g_meta_info, meta_info); - } - return GSIZE_TO_POINTER (g_meta_info); -} - -static GstBuffer * -gst_surface_buffer_new (void) -{ - GstBuffer *const buffer = gst_buffer_new (); - - if (buffer) - gst_buffer_add_meta (buffer, GST_VAAPI_SURFACE_META_INFO, NULL); - return buffer; -} - -#endif static GFunc get_surface_converter (GstVaapiDisplay * display) @@ -182,16 +42,6 @@ get_surface_converter (GstVaapiDisplay * display) GFunc func; switch (gst_vaapi_display_get_class_type (display)) { -#if USE_X11 && !GST_CHECK_VERSION(1,1,0) - case GST_VAAPI_DISPLAY_TYPE_X11: - func = (GFunc) gst_vaapi_video_converter_x11_new; - break; -#endif -#if USE_GLX && !GST_CHECK_VERSION(1,1,0) - case GST_VAAPI_DISPLAY_TYPE_GLX: - func = (GFunc) gst_vaapi_video_converter_glx_new; - break; -#endif default: func = NULL; break; diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 74a18aaf41..0b15901041 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -24,7 +24,7 @@ #include "gstvaapivideobufferpool.h" #include "gstvaapivideobuffer.h" #include "gstvaapivideomemory.h" -#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) +#if (USE_GLX || USE_EGL) #include "gstvaapivideometa_texture.h" #endif @@ -288,7 +288,7 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, } } -#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) +#if (USE_GLX || USE_EGL) if (priv->has_texture_upload_meta) gst_buffer_add_texture_upload_meta (buffer); #endif diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 6c3ee0916f..fa482421ae 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -26,8 +26,6 @@ #include "gstcompat.h" #include "gstvaapivideocontext.h" -#if GST_CHECK_VERSION(1,1,0) - GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); #define GST_VAAPI_TYPE_DISPLAY \ @@ -177,5 +175,3 @@ gst_vaapi_video_context_propagate (GstElement * element, msg = gst_message_new_have_context (GST_OBJECT_CAST (element), context); gst_element_post_message (GST_ELEMENT_CAST (element), msg); } - -#endif diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index 47de0e0f23..0c8797edb7 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -29,8 +29,6 @@ #include -#if GST_CHECK_VERSION(1,1,0) - #define GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME "gst.vaapi.Display" /* Fake GstVideoContext symbols */ @@ -58,22 +56,4 @@ void gst_vaapi_video_context_propagate (GstElement * element, GstVaapiDisplay * display); -#else -#include - -static inline void -gst_vaapi_video_context_prepare (GstVideoContext * context, - const gchar ** types) -{ - gst_video_context_prepare (context, types); -} - -static inline void -gst_vaapi_video_context_propagate (GstVideoContext * context, - GstVaapiDisplay * display) -{ -} - -#endif - #endif /* GST_VAAPI_VIDEO_CONTEXT_H */ diff --git a/gst/vaapi/gstvaapivideoconverter_glx.h b/gst/vaapi/gstvaapivideoconverter_glx.h deleted file mode 100644 index 35ed4df0ae..0000000000 --- a/gst/vaapi/gstvaapivideoconverter_glx.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * gstvaapivideoconverter_glx.h - Gstreamer/VA video converter - * - * Copyright (C) 2011-2013 Intel Corporation - * Author: Gwenole Beauchesne - * Copyright (C) 2011 Collabora Ltd. - * Author: Nicolas Dufresne - * - * 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_VIDEO_CONVERTER_GLX_H -#define GST_VAAPI_VIDEO_CONVERTER_GLX_H - -#include -#include "gstvaapivideobuffer.h" - -G_BEGIN_DECLS - -#define GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX \ - (gst_vaapi_video_converter_glx_get_type ()) -#define GST_VAAPI_VIDEO_CONVERTER_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ - GstVaapiVideoConverterGLX)) -#define GST_VAAPI_VIDEO_CONVERTER_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ - GstVaapiVideoConverterGLXClass)) -#define GST_VAAPI_IS_VIDEO_CONVERTER_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX)) -#define GST_VAAPI_IS_VIDEO_CONVERTER_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX)) -#define GST_VAAPI_VIDEO_CONVERTER_GLX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ - GstVaapiVideoConverterGLXClass)) - -typedef struct _GstVaapiVideoConverterGLX GstVaapiVideoConverterGLX; -typedef struct _GstVaapiVideoConverterGLXPrivate - GstVaapiVideoConverterGLXPrivate; -typedef struct _GstVaapiVideoConverterGLXClass GstVaapiVideoConverterGLXClass; - -/** - * GstVaapiVideoConverterGLX: - * - * Converter to transform VA buffers into GL textures. - */ -struct _GstVaapiVideoConverterGLX -{ - /*< private >*/ - GObject parent_instance; - - GstVaapiVideoConverterGLXPrivate *priv; -}; - -/** - * GstVaapiVideoConverterGLXClass: - * - * Converter class to transform VA buffers into GL textures. - */ -struct _GstVaapiVideoConverterGLXClass -{ - /*< private >*/ - GObjectClass parent_class; -}; - -G_GNUC_INTERNAL -GType -gst_vaapi_video_converter_glx_get_type (void) G_GNUC_CONST; - -G_GNUC_INTERNAL -GstSurfaceConverter * -gst_vaapi_video_converter_glx_new (GstBuffer * buffer, const gchar * type, - GValue * dest); - -G_END_DECLS - -#endif /* GST_VAAPI_VIDEO_CONVERTER_GLX_H */ diff --git a/gst/vaapi/gstvaapivideoconverter_x11.h b/gst/vaapi/gstvaapivideoconverter_x11.h deleted file mode 100644 index abf9211ac1..0000000000 --- a/gst/vaapi/gstvaapivideoconverter_x11.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * gstvaapivideoconverter_x11.h - VA video converter to X11 pixmap - * - * Copyright (C) 2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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_VIDEO_CONVERTER_X11_H -#define GST_VAAPI_VIDEO_CONVERTER_X11_H - -#include -#include "gstvaapivideobuffer.h" - -G_BEGIN_DECLS - -#define GST_VAAPI_TYPE_VIDEO_CONVERTER_X11 \ - (gst_vaapi_video_converter_x11_get_type ()) -#define GST_VAAPI_VIDEO_CONVERTER_X11(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ - GstVaapiVideoConverterX11)) -#define GST_VAAPI_VIDEO_CONVERTER_X11_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ - GstVaapiVideoConverterX11Class)) -#define GST_VAAPI_IS_VIDEO_CONVERTER_X11(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11)) -#define GST_VAAPI_IS_VIDEO_CONVERTER_X11_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11)) -#define GST_VAAPI_VIDEO_CONVERTER_X11_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ - GstVaapiVideoConverterX11Class)) - -typedef struct _GstVaapiVideoConverterX11 GstVaapiVideoConverterX11; -typedef struct _GstVaapiVideoConverterX11Private - GstVaapiVideoConverterX11Private; -typedef struct _GstVaapiVideoConverterX11Class GstVaapiVideoConverterX11Class; - -/** - * GstVaapiVideoConverterX11: - * - * Converter to transform VA buffers into GL textures. - */ -struct _GstVaapiVideoConverterX11 -{ - /*< private >*/ - GObject parent_instance; - - GstVaapiVideoConverterX11Private *priv; -}; - -/** - * GstVaapiVideoConverterX11Class: - * - * Converter class to transform VA buffers into GL textures. - */ -struct _GstVaapiVideoConverterX11Class -{ - /*< private >*/ - GObjectClass parent_class; -}; - -G_GNUC_INTERNAL -GType -gst_vaapi_video_converter_x11_get_type (void) G_GNUC_CONST; - -G_GNUC_INTERNAL -GstSurfaceConverter * -gst_vaapi_video_converter_x11_new (GstBuffer * buffer, const gchar * type, - GValue * dest); - -G_END_DECLS - -#endif /* GST_VAAPI_VIDEO_CONVERTER_X11_H */ diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index c38189fef2..43994c7a50 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -28,9 +28,7 @@ #include #include #include "gstvaapivideometa.h" -#if GST_CHECK_VERSION(1,1,0) #include -#endif G_BEGIN_DECLS @@ -50,9 +48,7 @@ typedef struct _GstVaapiVideoAllocatorClass GstVaapiVideoAllocatorClass; #define GST_VAAPI_VIDEO_MEMORY_NAME "GstVaapiVideoMemory" -#if GST_CHECK_VERSION(1,1,0) #define GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "memory:VASurface" -#endif #define GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET(mem, flag) \ GST_MEMORY_FLAG_IS_SET (mem, flag) diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index e1b4331d8d..9608d6578e 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -36,7 +36,7 @@ #define DEFAULT_FORMAT GST_VIDEO_FORMAT_RGBA -#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL) +#if (USE_GLX || USE_EGL) struct _GstVaapiVideoMetaTexture { GstVaapiTexture *texture; From 316abf6520900cb252838cfe2888bf905ae507e0 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 3 Apr 2015 17:45:08 +0300 Subject: [PATCH 1934/3781] Remove the gstvaapivideoconverter_*.c source files missed in commit 51b1e4a --- gst/vaapi/gstvaapivideoconverter_glx.c | 157 --------------------- gst/vaapi/gstvaapivideoconverter_x11.c | 187 ------------------------- 2 files changed, 344 deletions(-) delete mode 100644 gst/vaapi/gstvaapivideoconverter_glx.c delete mode 100644 gst/vaapi/gstvaapivideoconverter_x11.c diff --git a/gst/vaapi/gstvaapivideoconverter_glx.c b/gst/vaapi/gstvaapivideoconverter_glx.c deleted file mode 100644 index 4cf1c822fc..0000000000 --- a/gst/vaapi/gstvaapivideoconverter_glx.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * gstvaapivideoconverter_glx.c - Gst VA video converter - * - * Copyright (C) 2011-2013 Intel Corporation - * Author: Gwenole Beauchesne - * Copyright (C) 2011 Collabora Ltd. - * Author: Nicolas Dufresne - * - * 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 "gstcompat.h" -#include -#include "gstvaapivideoconverter_glx.h" -#include "gstvaapivideoconverter_x11.h" -#include "gstvaapipluginutil.h" -#include "gstvaapivideometa.h" - -typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *, - GstBuffer *); - -static void -gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface * iface); - -G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoConverterGLX, - gst_vaapi_video_converter_glx, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (GST_TYPE_SURFACE_CONVERTER, - gst_vaapi_video_converter_glx_iface_init)); - -#define GST_VAAPI_VIDEO_CONVERTER_GLX_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \ - GstVaapiVideoConverterGLXPrivate)) - -struct _GstVaapiVideoConverterGLXPrivate -{ - GstVaapiTexture *texture; -}; - -static gboolean -gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self, - GstBuffer * buffer); - -static void -gst_vaapi_video_converter_glx_dispose (GObject * object) -{ - GstVaapiVideoConverterGLXPrivate *const priv = - GST_VAAPI_VIDEO_CONVERTER_GLX (object)->priv; - - gst_vaapi_texture_replace (&priv->texture, NULL); - - G_OBJECT_CLASS (gst_vaapi_video_converter_glx_parent_class)->dispose (object); -} - -static void -gst_vaapi_video_converter_glx_class_init (GstVaapiVideoConverterGLXClass * - klass) -{ - GObjectClass *const object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (GstVaapiVideoConverterGLXPrivate)); - - object_class->dispose = gst_vaapi_video_converter_glx_dispose; -} - -static void -gst_vaapi_video_converter_glx_init (GstVaapiVideoConverterGLX * buffer) -{ - buffer->priv = GST_VAAPI_VIDEO_CONVERTER_GLX_GET_PRIVATE (buffer); -} - -static void -gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface * iface) -{ - iface->upload = (GstSurfaceUploadFunction) - gst_vaapi_video_converter_glx_upload; -} - -/** - * gst_vaapi_video_converter_glx_new: - * @surface: the #GstSurfaceBuffer - * @type: type of the target buffer (must be "opengl") - * @dest: target of the conversion (must be GL texture id) - * - * Creates an empty #GstBuffer. The caller is responsible for - * completing the initialization of the buffer with the - * gst_vaapi_video_converter_glx_set_*() functions. - * - * Return value: the newly allocated #GstBuffer, or %NULL on error - */ -GstSurfaceConverter * -gst_vaapi_video_converter_glx_new (GstBuffer * buffer, const gchar * type, - GValue * dest) -{ - GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); - GstVaapiTexture *texture; - GstVaapiVideoConverterGLX *converter; - - /* Check for "opengl" request, or chain up to X11 converter */ - if (strcmp (type, "opengl") != 0 || !G_VALUE_HOLDS_UINT (dest)) - return gst_vaapi_video_converter_x11_new (buffer, type, dest); - - /* FIXME Should we assume target and format ? */ - texture = - gst_vaapi_texture_glx_new_wrapped (gst_vaapi_video_meta_get_display - (meta), g_value_get_uint (dest), GL_TEXTURE_2D, GL_BGRA); - if (!texture) - return NULL; - - converter = g_object_new (GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, NULL); - converter->priv->texture = texture; - return GST_SURFACE_CONVERTER (converter); -} - -gboolean -gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self, - GstBuffer * buffer) -{ - GstVaapiVideoConverterGLXPrivate *const priv = - GST_VAAPI_VIDEO_CONVERTER_GLX (self)->priv; - GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); - GstVaapiSurfaceProxy *const proxy = - gst_vaapi_video_meta_get_surface_proxy (meta); - GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); - GstVaapiDisplay *new_dpy, *old_dpy; - - new_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); - old_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (priv->texture)); - - if (old_dpy != new_dpy) { - const guint texture = gst_vaapi_texture_get_id (priv->texture); - - gst_vaapi_texture_replace (&priv->texture, NULL); - priv->texture = gst_vaapi_texture_glx_new_wrapped (new_dpy, - texture, GL_TEXTURE_2D, GL_BGRA); - } - - if (!gst_vaapi_apply_composition (surface, buffer)) - GST_WARNING ("could not update subtitles"); - - return gst_vaapi_texture_put_surface (priv->texture, surface, - gst_vaapi_surface_proxy_get_crop_rect (proxy), - gst_vaapi_video_meta_get_render_flags (meta)); -} diff --git a/gst/vaapi/gstvaapivideoconverter_x11.c b/gst/vaapi/gstvaapivideoconverter_x11.c deleted file mode 100644 index 6fda71c76a..0000000000 --- a/gst/vaapi/gstvaapivideoconverter_x11.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * gstvaapivideoconverter_x11.h - VA video converter to X11 pixmap - * - * Copyright (C) 2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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 "gstcompat.h" -#include -#include "gstvaapivideoconverter_x11.h" -#include "gstvaapipluginutil.h" -#include "gstvaapivideometa.h" - -typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *, - GstSurfaceBuffer *); - -static void -gst_vaapi_video_converter_x11_iface_init (GstSurfaceConverterInterface * iface); - -G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoConverterX11, - gst_vaapi_video_converter_x11, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (GST_TYPE_SURFACE_CONVERTER, - gst_vaapi_video_converter_x11_iface_init)); - -#define GST_VAAPI_VIDEO_CONVERTER_X11_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, \ - GstVaapiVideoConverterX11Private)) - -struct _GstVaapiVideoConverterX11Private -{ - GstVaapiPixmap *pixmap; - XID pixmap_id; -}; - -static gboolean -gst_vaapi_video_converter_x11_upload (GstSurfaceConverter * self, - GstBuffer * buffer); - -static void -gst_vaapi_video_converter_x11_dispose (GObject * object) -{ - GstVaapiVideoConverterX11Private *const priv = - GST_VAAPI_VIDEO_CONVERTER_X11 (object)->priv; - - gst_vaapi_pixmap_replace (&priv->pixmap, NULL); - - G_OBJECT_CLASS (gst_vaapi_video_converter_x11_parent_class)->dispose (object); -} - -static void -gst_vaapi_video_converter_x11_class_init (GstVaapiVideoConverterX11Class * - klass) -{ - GObjectClass *const object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (GstVaapiVideoConverterX11Private)); - - object_class->dispose = gst_vaapi_video_converter_x11_dispose; -} - -static void -gst_vaapi_video_converter_x11_init (GstVaapiVideoConverterX11 * buffer) -{ - buffer->priv = GST_VAAPI_VIDEO_CONVERTER_X11_GET_PRIVATE (buffer); -} - -static void -gst_vaapi_video_converter_x11_iface_init (GstSurfaceConverterInterface * iface) -{ - iface->upload = (GstSurfaceUploadFunction) - gst_vaapi_video_converter_x11_upload; -} - -static gboolean -set_pixmap (GstVaapiVideoConverterX11 * converter, GstVaapiDisplay * display, - XID pixmap_id) -{ - GstVaapiVideoConverterX11Private *const priv = converter->priv; - GstVaapiPixmap *pixmap; - - pixmap = gst_vaapi_pixmap_x11_new_with_xid (display, pixmap_id); - if (!pixmap) - return FALSE; - - gst_vaapi_pixmap_replace (&priv->pixmap, pixmap); - gst_vaapi_pixmap_unref (pixmap); - priv->pixmap_id = pixmap_id; - return TRUE; -} - -/** - * gst_vaapi_video_converter_x11_new: - * @surface: the #GstSurfaceBuffer - * @type: type of the target buffer (must be "x11-pixmap") - * @dest: target of the conversion (must be an X11 pixmap id) - * - * Creates an empty #GstBuffer. The caller is responsible for - * completing the initialization of the buffer with the - * gst_vaapi_video_converter_x11_set_*() functions. - * - * Return value: the newly allocated #GstBuffer, or %NULL on error - */ -GstSurfaceConverter * -gst_vaapi_video_converter_x11_new (GstBuffer * buffer, const gchar * type, - GValue * dest) -{ - GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); - GstVaapiVideoConverterX11 *converter; - - /* We only support X11 pixmap conversion */ - if (strcmp (type, "x11-pixmap") != 0 || !G_VALUE_HOLDS_UINT (dest)) - return NULL; - - converter = g_object_new (GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, NULL); - if (!converter) - return NULL; - - if (!set_pixmap (converter, gst_vaapi_video_meta_get_display (meta), - g_value_get_uint (dest))) - goto error; - return GST_SURFACE_CONVERTER (converter); - -error: - g_object_unref (converter); - return NULL; -} - -gboolean -gst_vaapi_video_converter_x11_upload (GstSurfaceConverter * self, - GstBuffer * buffer) -{ - GstVaapiVideoConverterX11 *const converter = - GST_VAAPI_VIDEO_CONVERTER_X11 (self); - GstVaapiVideoConverterX11Private *const priv = converter->priv; - GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer); - const GstVaapiRectangle *crop_rect = NULL; - GstVaapiSurface *surface; - GstVaapiDisplay *old_display, *new_display; - - g_return_val_if_fail (meta != NULL, FALSE); - - surface = gst_vaapi_video_meta_get_surface (meta); - if (!surface) - return FALSE; - - old_display = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (priv->pixmap)); - new_display = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); - - if (old_display != new_display) { - if (!set_pixmap (converter, new_display, priv->pixmap_id)) - return FALSE; - } - - if (!gst_vaapi_apply_composition (surface, buffer)) - GST_WARNING ("could not update subtitles"); - - GstVideoCropMeta *const crop_meta = gst_buffer_get_video_crop_meta (buffer); - if (crop_meta) { - GstVaapiRectangle crop_rect_tmp; - crop_rect = &crop_rect_tmp; - crop_rect_tmp.x = crop_meta->x; - crop_rect_tmp.y = crop_meta->y; - crop_rect_tmp.width = crop_meta->width; - crop_rect_tmp.height = crop_meta->height; - } - if (!crop_rect) - crop_rect = gst_vaapi_video_meta_get_render_rect (meta); - - return gst_vaapi_pixmap_put_surface (priv->pixmap, surface, crop_rect, - gst_vaapi_video_meta_get_render_flags (meta)); -} From f304d4168b3d5d878a43bca595adf37ef446b420 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 3 Apr 2015 23:30:24 +0300 Subject: [PATCH 1935/3781] codecparsers: update to gst-vaapi-branch commit 1f792e4 87f4a7e: bytereader: add gst_byte_reader_peek_sub_reader() and _get_sub_reader() 7d8ba7a: bytereader: use unchecked inline variant for get_remaining in more places 2528ea6: bytereader: add gst_byte_reader_masked_scan_uint32_peek 2b92a67: h264parse: reset the parser information when caps changes 05eee86: codecparsers: Indent file e27a38b: codecparsers: Add READ_UE_MAX macro 2036471: Constify some static arrays everywhere --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index d3b5c1bf5d..8cb5608877 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit d3b5c1bf5dde36ab27110edbc5ced84b9bb07a63 +Subproject commit 8cb56088773832e63cce284bef00749601f792e4 From 0c2fc4a381d30c4f18843fe9f610ccfde82b3524 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Sat, 4 Apr 2015 00:06:56 +0300 Subject: [PATCH 1936/3781] Changing source code download links from https://gitorious to https://github -- gitmodules: Change gstreamer-codecparsers submodule source download link -- README: Change the gstreamer-vaapi webpage link --- .gitmodules | 2 +- README | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index bd53240d8a..bb34d0d12d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "ext/codecparsers"] path = ext/codecparsers - url = https://gitorious.org/vaapi/gstreamer-codecparsers.git + url = https://github.com/01org/gstreamer-codecparsers.git [submodule "ext/libvpx/upstream"] path = ext/libvpx/upstream url = https://chromium.googlesource.com/webm/libvpx diff --git a/README b/README index beb9a7e6dd..fcbca3bc0b 100644 --- a/README +++ b/README @@ -133,7 +133,7 @@ Sources Git repository for work-in-progress changes is available at: - + Reporting Bugs From d1cb1959b2d4190c48409e8be645deee537d4210 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Sat, 4 Apr 2015 00:40:29 +0300 Subject: [PATCH 1937/3781] Update README --- README | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/README b/README index fcbca3bc0b..05fa94ac21 100644 --- a/README +++ b/README @@ -26,9 +26,10 @@ GStreamer and helper libraries. implicitly download the decoded surface to raw YUV buffers. * `vaapiencode_' is used to encode into MPEG-2, H.264 AVC, - H.264 MVC videos, depending on the actual value of (mpeg2, - h264, etc.). By default, raw format bitstreams are generated, so - the result may be piped to a muxer. e.g. qtmux for MP4 containers. + H.264 MVC, JPEG, VP8 videos, depending on the actual value of + (mpeg2, h264, etc.). 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 @@ -43,9 +44,9 @@ GStreamer and helper libraries. Features -------- - * VA-API support from 0.29 to 0.35 + * VA-API support from 0.29 to 0.37 * JPEG, MPEG-2, MPEG-4, H.264 AVC, H.264 MVC, VP8 and VC-1 ad-hoc decoders - * MPEG-2, H.264 AVC and H.264 MVC ad-hoc encoders + * MPEG-2, H.264 AVC,H.264 MVC, JPEG and VP8 ad-hoc encoders * OpenGL rendering through VA/GLX or GLX texture-from-pixmap + FBO * Support for the Wayland display server * Support for headless decode pipelines with VA/DRM @@ -62,22 +63,11 @@ Requirements Software requirements - * GStreamer 0.10.x [DEPRECATED]: + * GStreamer 1.2.x (up to including GStreamer 1.6): libglib2.0-dev (>= 2.28) - libgstreamer0.10-dev (>= 0.10.36) - or with GstBaseSink::query() - libgstreamer-plugins-base0.10-dev (>= 0.10.36) - libgstreamer-plugins-bad0.10-dev (>= 0.10.22.1) - or with GstVideoContext, GstSurfaceBuffer, codecparsers - - Note: support for GStreamer 0.10 APIs is deprecated and will be - removed in a future release. - - * GStreamer 1.0.x (up to including GStreamer 1.4): - libglib2.0-dev (>= 2.28) - libgstreamer1.0-dev (>= 1.0.0) - libgstreamer-plugins-base1.0-dev (>= 1.0.0) - libgstreamer-plugins-bad1.0-dev (>= 1.0.0) + libgstreamer1.0-dev (>= 1.2.0) + libgstreamer-plugins-base1.0-dev (>= 1.2.0) + libgstreamer-plugins-bad1.0-dev (>= 1.2.0) * Renderers: DRM: libva-dev (>= 1.1.0), libdrm-dev, libudev-dev @@ -89,7 +79,8 @@ Hardware requirements * AMD platforms with UVD2 (XvBA supported) * Intel Eaglelake (G45) - * Intel Ironlake, Sandybridge, Ivybridge and Haswell (HD Graphics) + * Intel Ironlake, Sandybridge, Ivybridge, Haswell and Broadwell (HD Graphics) + * Intel BayTrail * Intel Poulsbo (US15W) * Intel Medfield or Cedar Trail * NVIDIA platforms with PureVideo (VDPAU supported) @@ -99,7 +90,7 @@ Usage ----- VA elements are automatically plugged into GStreamer pipelines. So, - using playbin (or playbin2 with GStreamer 0.10) should work as is. + using playbin should work as is. However, here are a few alternate pipelines that could be manually constructed. From c9f0807752f6ae09ee85478c8d16d53d222f6435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 20:02:29 +0200 Subject: [PATCH 1938/3781] decoder: cast GST_VAAPI_DECODER_STATUS_DROP_FRAME Since GST_VAAPI_DECODER_STATUS_DROP_FRAME is not part of the enum GstVaapiDecoderStatus, we need to cast it to avoid compiler complains. https://bugzilla.gnome.org/show_bug.cgi?id=747312 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 6 +----- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 2 +- 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 87801f186a..d1bf5a19e0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -241,7 +241,7 @@ do_decode_1 (GstVaapiDecoder * decoder, GstVaapiParserFrame * frame) /* Drop frame if there is no slice data unit in there */ if (G_UNLIKELY (frame->units->len == 0)) - return GST_VAAPI_DECODER_STATUS_DROP_FRAME; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; return GST_VAAPI_DECODER_STATUS_SUCCESS; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index ffc06d5723..207d99a6c7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1515,7 +1515,7 @@ error: drop_frame: priv->decoder_state = 0; priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME; - return GST_VAAPI_DECODER_STATUS_DROP_FRAME; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; } static GstVaapiDecoderStatus @@ -3522,10 +3522,6 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) switch (sps->profile_idc) { case GST_H264_PROFILE_MULTIVIEW_HIGH: case GST_H264_PROFILE_STEREO_HIGH: - if (0) { - GST_DEBUG("drop picture from substream"); - return GST_VAAPI_DECODER_STATUS_DROP_FRAME; - } break; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index a45ab8f792..bfa1d2c69b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -241,7 +241,7 @@ error: drop_frame: priv->decoder_state = 0; - return GST_VAAPI_DECODER_STATUS_DROP_FRAME; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index c3ab7a68a3..1bb2a2279e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -550,7 +550,7 @@ error: drop_frame: priv->state &= GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS; - return GST_VAAPI_DECODER_STATUS_DROP_FRAME; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; } static GstVaapiDecoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 2f2620bec6..68cb80c76c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -518,7 +518,7 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) parser_result = gst_mpeg4_parse_video_object_plane(vop_hdr, sprite_trajectory, vol_hdr, buf, buf_size); /* Need to skip this frame if VOP was not coded */ if (GST_MPEG4_PARSER_OK == parser_result && !vop_hdr->coded) - return GST_VAAPI_DECODER_STATUS_DROP_FRAME; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; } if (parser_result != GST_MPEG4_PARSER_OK) { From d363000eaaa239c43cf1400199aa72b845aa73e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 20:27:24 +0200 Subject: [PATCH 1939/3781] encoder: mpeg2: use fabsf() instead of abs() The member value in frame_rate_tab is float, the result of the abs() function should be float too. But abs() only manages integers. This patch replaces abs() with fabsf() to handle correctly the possible floats values. https://bugzilla.gnome.org/show_bug.cgi?id=747312 --- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 453636538a..9747ae1cd4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -22,6 +22,7 @@ */ #include "sysdeps.h" +#include #include #include #include @@ -887,9 +888,9 @@ find_frame_rate_code (const VAEncSequenceParameterBufferMPEG2 * seq_param) for (i = 0; i < sizeof (frame_rate_tab) / sizeof (frame_rate_tab[0]); i++) { - if (abs (1000 * frame_rate_tab[i].value - 1000 * frame_rate_value) < delta) { + if (fabsf (1000 * frame_rate_tab[i].value - 1000 * frame_rate_value) < delta) { code = frame_rate_tab[i].code; - delta = abs (1000 * frame_rate_tab[i].value - 1000 * frame_rate_value); + delta = fabsf (1000 * frame_rate_tab[i].value - 1000 * frame_rate_value); } } return code; From c82e51738fcae3c5952e551eebc0842b49c58ad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 20:28:22 +0200 Subject: [PATCH 1940/3781] libs: remove unused variables clang reports these unused variables. Let's get rid of them. https://bugzilla.gnome.org/show_bug.cgi?id=747312 --- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 2 -- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 3 --- 2 files changed, 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index 30385d2b04..4d995eb391 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -258,8 +258,6 @@ gst_vaapi_display_loader_map_lookup_type (GstVaapiDisplayType type) /* --- EGL backend implementation --- */ /* ------------------------------------------------------------------------- */ -static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_EGL; - typedef struct { gpointer display; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index a9afc1134c..dadccfd8c5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -78,8 +78,6 @@ struct _GstVaapiEncoderVP8 static GstVaapiEncoderStatus ensure_profile (GstVaapiEncoderVP8 * encoder) { - GstVaapiProfile profile; - /* Always start from "simple" profile for maximum compatibility */ encoder->profile = GST_VAAPI_PROFILE_VP8; @@ -258,7 +256,6 @@ fill_picture (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) { - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); VAEncPictureParameterBufferVP8 *const pic_param = picture->param; int i; From b1bbc087c1d00a30910673a61b2872cd629c9663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 20:31:47 +0200 Subject: [PATCH 1941/3781] encoder: avoid GstVaapiCodedBuffer redefinition The symbol GstVaapiCodedBuffer is already defined in gst-libs/gst/vaapi/gstvaapicodedbuffer.h which is loaded, at the end, by gstvaapiencoder_objects.h. Clang complains about the symbol re-definition. This patch removes that redefinition. https://bugzilla.gnome.org/show_bug.cgi?id=747312 --- gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index 5f7e78bfe2..6e8945cd9f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -35,7 +35,6 @@ typedef struct _GstVaapiEncMiscParam GstVaapiEncMiscParam; typedef struct _GstVaapiEncSlice GstVaapiEncSlice; typedef struct _GstVaapiEncQMatrix GstVaapiEncQMatrix; typedef struct _GstVaapiEncHuffmanTable GstVaapiEncHuffmanTable; -typedef struct _GstVaapiCodedBuffer GstVaapiCodedBuffer; typedef struct _GstVaapiEncPackedHeader GstVaapiEncPackedHeader; /* ------------------------------------------------------------------------- */ From 7c71f057b406d0922e92cb3a59e91747aee7bcb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 20:33:44 +0200 Subject: [PATCH 1942/3781] encoder: h264: casts slice_param->slice_type slice_type in slice_param is defined as (char *), but it is compared against a signed integer. clang complains about this comparison. This patch casts the variable. https://bugzilla.gnome.org/show_bug.cgi?id=747312 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 2a5a3c757d..1287e81369 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1838,7 +1838,7 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, slice_param->num_macroblocks = cur_slice_mbs; slice_param->macroblock_info = VA_INVALID_ID; slice_param->slice_type = h264_get_slice_type (picture->type); - g_assert (slice_param->slice_type != -1); + g_assert ((gint8) slice_param->slice_type != -1); slice_param->pic_parameter_set_id = encoder->view_idx; slice_param->idr_pic_id = encoder->idr_num; slice_param->pic_order_cnt_lsb = picture->poc; From a6518f68880df0c5b4dcd5f15908efbd02b02eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Apr 2015 20:38:07 +0200 Subject: [PATCH 1943/3781] decoder: mpeg4: remove an spurious comparison The member size in GstMpeg4Packet is gsize which is unsigned, which cannot be less than zero. Hence this pre-condition test is a no-op. This patch removes that code. https://bugzilla.gnome.org/show_bug.cgi?id=747312 --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 68cb80c76c..a4e2825746 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -818,9 +818,6 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) GstMpeg4Packet *tos = &packet; GstVaapiDecoderStatus status; - if (tos->size < 0) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - // packet.size is the size from current marker to the next. if (tos->type == GST_MPEG4_VISUAL_OBJ_SEQ_START) { status = decode_sequence(decoder, packet.data + packet.offset, packet.size); From 93d0141cc296e9ff8a0fc2994940380a95f56eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 8 Apr 2015 18:20:34 +0200 Subject: [PATCH 1944/3781] libs: remove unused variables clang reports these unused variables. Let's get rid of them. This patch is a missing part of commit c82e5173 https://bugzilla.gnome.org/show_bug.cgi?id=747312 --- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 2738454b07..32aa714113 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -41,8 +41,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_GLX; - static GstVaapiWindow * gst_vaapi_display_glx_create_window (GstVaapiDisplay * display, GstVaapiID id, guint width, guint height) From a314b682b2520415a62c474611ea514308336fa5 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Thu, 11 Dec 2014 12:02:38 +0100 Subject: [PATCH 1945/3781] vaapidecode: unref video codec frame twice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We get one reference when the frame is passed to decode_handle_frame() and create another one in gst_vaapi_decoder_push_frame(). Usually the frame is handled in gst_vaapidecode_push_decoded_frame(). Here the frame is always released twice: gst_video_decoder_finish_frame() + gst_video_codec_frame_unref() or gst_video_decoder_drop_frame() + gst_video_codec_frame_unref(). In gst_vaapidecode_reset_full() both references to the frame must be released as well. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=743226 --- gst/vaapi/gstvaapidecode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 05c9d0c33c..707efabcff 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -636,6 +636,7 @@ gst_vaapidecode_reset_full (GstVaapiDecode * decode, GstCaps * caps, /* Reset timers if hard reset was requested (e.g. seek) */ if (hard) { + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); GstVideoCodecFrame *out_frame = NULL; gst_vaapi_decoder_flush (decode->decoder); @@ -643,6 +644,7 @@ gst_vaapidecode_reset_full (GstVaapiDecode * decode, GstCaps * caps, /* Purge all decoded frames as we don't need them (e.g. seek) */ while (gst_vaapi_decoder_get_frame_with_timeout (decode->decoder, &out_frame, 0) == GST_VAAPI_DECODER_STATUS_SUCCESS) { + gst_video_decoder_drop_frame (vdec, out_frame); gst_video_codec_frame_unref (out_frame); out_frame = NULL; } From c750fa937d99b79f5afd5dd8d79df84acd133dd3 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 13 Apr 2015 11:29:35 +0300 Subject: [PATCH 1946/3781] codecparsers: Update to gst-vaapi-branch commit 9bc72b0 767bf22: codecparsers: h265: add helpers to convert quantization matrices 71c8e93: codecparser: h265: skip byte alignment bits while parsing slice header 3bf0355: codecparsre: h265: Fix the NumDeltaPocs calculation 10e2087: codecparser: h265: Fix the NumPocTotalCurr calculatio 2d753b8: codecparser: h265: Fix nal size calculation for EOS and EOB --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 8cb5608877..b09990aec6 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 8cb56088773832e63cce284bef00749601f792e4 +Subproject commit b09990aec609acd1b8d3071f0e48835709bc72b0 From 38f8fea4bb0deb81916b615160fcf8dc75ccb058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 8 Apr 2015 18:05:20 +0200 Subject: [PATCH 1947/3781] guard buffer export API if not available The support for buffer exports in VA-API was added in version 0.36. These interfaces are for interop with EGL, OpenCL, etc. GStreamer-VAAPI uses it for a dmabuf memory allocator. Though, gstreamer-vaapi has to support VA-API versions ranging from 0.30.4, which doesn't support it. This patch guards all the buffer exports handling (and dmabuf allocator) if the detected VA-API version is below 0.36. https://bugzilla.gnome.org/show_bug.cgi?id=746405 --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 24 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h | 2 ++ gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index c8904a720c..92655668ec 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -77,6 +77,7 @@ to_GstVaapiBufferMemoryType (guint va_type) static gboolean gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) { +#if VA_CHECK_VERSION (0,36,0) const guint mem_type = proxy->va_info.mem_type; VAStatus va_status; @@ -95,11 +96,15 @@ gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) if (proxy->va_info.mem_type != mem_type) return FALSE; return TRUE; +#else + return FALSE; +#endif } static gboolean gst_vaapi_buffer_proxy_release_handle (GstVaapiBufferProxy * proxy) { +#if VA_CHECK_VERSION (0,36,0) VAStatus va_status; if (!proxy->va_info.handle) @@ -115,6 +120,9 @@ gst_vaapi_buffer_proxy_release_handle (GstVaapiBufferProxy * proxy) if (!vaapi_check_status (va_status, "vaReleaseBufferHandle()")) return FALSE; return TRUE; +#else + return FALSE; +#endif } static void @@ -143,6 +151,7 @@ GstVaapiBufferProxy * gst_vaapi_buffer_proxy_new (guintptr handle, guint type, gsize size, GDestroyNotify destroy_func, gpointer user_data) { +#if VA_CHECK_VERSION (0,36,0) GstVaapiBufferProxy *proxy; g_return_val_if_fail (handle != 0, NULL); @@ -171,12 +180,16 @@ error_unsupported_mem_type: GST_ERROR ("unsupported buffer type (%d)", proxy->type); gst_vaapi_buffer_proxy_unref_internal (proxy); return NULL; +#else + return NULL; +#endif } GstVaapiBufferProxy * gst_vaapi_buffer_proxy_new_from_object (GstVaapiObject * object, VABufferID buf_id, guint type, GDestroyNotify destroy_func, gpointer data) { +#if VA_CHECK_VERSION (0,36,0) GstVaapiBufferProxy *proxy; g_return_val_if_fail (object != NULL, NULL); @@ -208,6 +221,9 @@ error_acquire_handle: GST_ERROR ("failed to acquire the underlying VA buffer handle"); gst_vaapi_buffer_proxy_unref_internal (proxy); return NULL; +#else + return NULL; +#endif } /** @@ -288,7 +304,11 @@ gst_vaapi_buffer_proxy_get_handle (GstVaapiBufferProxy * proxy) { g_return_val_if_fail (proxy != NULL, 0); +#if VA_CHECK_VERSION (0,36,0) return GST_VAAPI_BUFFER_PROXY_HANDLE (proxy); +#else + return 0; +#endif } /** @@ -304,5 +324,9 @@ gst_vaapi_buffer_proxy_get_size (GstVaapiBufferProxy * proxy) { g_return_val_if_fail (proxy != NULL, 0); +#if VA_CHECK_VERSION (0,36,0) return GST_VAAPI_BUFFER_PROXY_SIZE (proxy); +#else + return 0; +#endif } diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h index f12daef9a2..833e22ce22 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h @@ -68,7 +68,9 @@ struct _GstVaapiBufferProxy { gpointer destroy_data; guint type; VABufferID va_buf; +#if VA_CHECK_VERSION (0,36,0) VABufferInfo va_info; +#endif }; G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 27438cc870..9d425ef62b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -225,7 +225,7 @@ static gboolean gst_vaapi_surface_create_from_buffer_proxy (GstVaapiSurface * surface, GstVaapiBufferProxy * proxy, const GstVideoInfo * vip) { -#if VA_CHECK_VERSION (0,34,0) +#if VA_CHECK_VERSION (0,36,0) GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); GstVideoFormat format; VASurfaceID surface_id; From 33023d4d4d4fe2ce304adce8ebe0695d586a4d0c Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 13 Apr 2015 14:51:51 +0300 Subject: [PATCH 1948/3781] HEVC: Allow to build h265 codecparser internally Signed-off-by: Sreerenj Balachandran --- configure.ac | 26 ++++++++++++++++++++++++++ ext/Makefile.am | 2 ++ gst-libs/gst/codecparsers/Makefile.am | 5 +++++ 3 files changed, 33 insertions(+) diff --git a/configure.ac b/configure.ac index 91e3419fad..72dbabc3ea 100644 --- a/configure.ac +++ b/configure.ac @@ -269,6 +269,7 @@ if test "$enable_builtin_codecparsers" = "yes"; then ac_cv_have_gst_h264_parser="no" ac_cv_have_gst_jpeg_parser="no" ac_cv_have_gst_vp8_parser="no" + ac_cv_have_gst_h265_parser="no" else PKG_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) @@ -371,6 +372,31 @@ AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_VP8], [test "$ac_cv_have_gst_vp8_parser" != "yes"]) AM_CONDITIONAL([USE_BUILTIN_LIBVPX], [test "$enable_builtin_libvpx" = "yes"]) +dnl ... H.265 parser, with the required extensions +AC_CACHE_CHECK([for H.265 parser], + ac_cv_have_gst_h265_parser, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[GstH265SliceHdr slice_hdr; + GstH265VUIParams vui_params; + GstH265Profile profile = GST_H265_PROFILE_MAIN_STILL_PICTURE; + slice_hdr.n_emulation_prevention_bytes = 0; + vui_params.par_n = 0; + vui_params.par_d = 0;]])], + [ac_cv_have_gst_h265_parser="yes"], + [ac_cv_have_gst_h265_parser="no"] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +]) +AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_H265], + [test "$ac_cv_have_gst_h265_parser" != "yes"]) + dnl ... video parsers AM_CONDITIONAL([USE_LOCAL_VIDEO_PARSERS], [test "$enable_builtin_videoparsers" = "yes"]) diff --git a/ext/Makefile.am b/ext/Makefile.am index 1444152870..8450b85d50 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -17,6 +17,7 @@ codecparsers_source_c = \ nalutils.c \ parserutils.c \ vp8utils.c \ + gsth265parser.c \ $(NULL) EXTRA_DIST += $(codecparsers_source_c:%.c=$(codecparsers_srcdir)/%.c) @@ -33,6 +34,7 @@ codecparsers_source_h = \ nalutils.h \ parserutils.h \ vp8utils.h \ + gsth265parser.h \ $(NULL) EXTRA_DIST += $(codecparsers_source_h:%.h=$(codecparsers_srcdir)/%.h) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 56102ed697..a160450cde 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -62,6 +62,11 @@ gen_source_h += dboolhuff.h endif endif +if USE_LOCAL_CODEC_PARSERS_H265 +gen_source_c += gsth265parser.c +gen_source_h += gsth265parser.h +endif + GENFILES = \ $(gen_source_c) \ $(gen_source_h) \ From c253c2227631a3769cd556886698f9ff8640f9ee Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 13 Apr 2015 14:52:14 +0300 Subject: [PATCH 1949/3781] HEVC: build: Check availability of h265 decoder APIs Signed-off-by: Sreerenj Balachandran --- configure.ac | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/configure.ac b/configure.ac index 72dbabc3ea..72afb8aaee 100644 --- a/configure.ac +++ b/configure.ac @@ -780,6 +780,38 @@ AC_CACHE_CHECK([for VP8 decoding API], LIBS="$saved_LIBS" ]) +dnl Check for va_dec_hevc.h header +saved_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" +AC_CHECK_HEADERS([va/va_dec_hevc.h], [], [], [#include ]) +CPPFLAGS="$saved_CPPFLAGS" + +dnl Check for HEVC decoding API (0.38+) +USE_HEVC_DECODER=0 +AC_CACHE_CHECK([for HEVC decoding API], + ac_cv_have_hevc_decoding_api, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #ifdef HAVE_VA_VA_DEC_HEVC_H + #include + #endif + ]], + [[VAPictureParameterBufferHEVC pic_param; + VASliceParameterBufferHEVC slice_param; + VAIQMatrixBufferHEVC iq_matrix; + slice_param.slice_data_offset = 0; + slice_param.slice_data_flag = 0;]])], + [ac_cv_have_hevc_decoding_api="yes" USE_HEVC_DECODER=1], + [ac_cv_have_hevc_decoding_api="no"] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +]) dnl Check for vpp (video post-processing) support USE_VA_VPP=0 From 23bf2ff9e5130484e81e7dff8f6994ae59e82801 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 13 Apr 2015 14:52:53 +0300 Subject: [PATCH 1950/3781] HEVC: gstvaapiprofile: Add profile definitions Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapiprofile.c | 35 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiprofile.h | 12 ++++++++++ 2 files changed, 47 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 51e273621b..a6f9e98a59 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -66,6 +66,7 @@ static const GstVaapiCodecMap gst_vaapi_codecs[] = { { GST_VAAPI_CODEC_VC1, "vc1" }, { GST_VAAPI_CODEC_JPEG, "jpeg" }, { GST_VAAPI_CODEC_VP8, "vp8" }, + { GST_VAAPI_CODEC_H265, "h265" }, { 0, } }; @@ -138,6 +139,14 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_VP8, VAProfileVP8Version0_3, "video/x-vp8", NULL }, +#endif +#if VA_CHECK_VERSION(0,37,0) + { GST_VAAPI_PROFILE_H265_MAIN, VAProfileHEVCMain, + "video/x-h265", "main" + }, + { GST_VAAPI_PROFILE_H265_MAIN10, VAProfileHEVCMain10, + "video/x-h265", "main10" + }, #endif { 0, } }; @@ -292,6 +301,29 @@ gst_vaapi_profile_from_codec_data_h264(GstBuffer *buffer) return 0; } +static GstVaapiProfile +gst_vaapi_profile_from_codec_data_h265(GstBuffer *buffer) +{ + /* ISO/IEC 14496-15: HEVC file format */ + guchar buf[3]; + + if (gst_buffer_extract(buffer, 0, buf, sizeof(buf)) != sizeof(buf)) + return 0; + + if (buf[0] != 1) /* configurationVersion = 1 */ + return 0; + + if (buf[1] & 0xc0) /* general_profile_space = 0 */ + return 0; + + switch (buf[1] & 0x1f) { /* HEVCProfileIndication */ + case 1: return GST_VAAPI_PROFILE_H265_MAIN; + case 2: return GST_VAAPI_PROFILE_H265_MAIN10; + case 3: return GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; + } + return 0; +} + static GstVaapiProfile gst_vaapi_profile_from_codec_data(GstVaapiCodec codec, GstBuffer *buffer) { @@ -304,6 +336,9 @@ gst_vaapi_profile_from_codec_data(GstVaapiCodec codec, GstBuffer *buffer) case GST_VAAPI_CODEC_H264: profile = gst_vaapi_profile_from_codec_data_h264(buffer); break; + case GST_VAAPI_CODEC_H265: + profile = gst_vaapi_profile_from_codec_data_h265(buffer); + break; default: profile = 0; break; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 5a0e7679a2..00e07691fa 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -39,6 +39,7 @@ G_BEGIN_DECLS * @GST_VAAPI_CODEC_WMV3: Windows Media Video 9. VC-1 Simple or Main profile (SMPTE 421M) * @GST_VAAPI_CODEC_VC1: VC-1 Advanced profile (SMPTE 421M) * @GST_VAAPI_CODEC_JPEG: JPEG (ITU-T 81) + * @GST_VAAPI_CODEC_H265: H.265 aka MPEG-H Part 2 (ITU-T H.265) * * The set of all codecs for #GstVaapiCodec. */ @@ -52,6 +53,7 @@ typedef enum { GST_VAAPI_CODEC_VC1 = GST_MAKE_FOURCC('V','C','1',0), GST_VAAPI_CODEC_JPEG = GST_MAKE_FOURCC('J','P','G',0), GST_VAAPI_CODEC_VP8 = GST_MAKE_FOURCC('V','P','8',0), + GST_VAAPI_CODEC_H265 = GST_MAKE_FOURCC('2','6','5',0), } GstVaapiCodec; /** @@ -121,6 +123,12 @@ typedef enum { * VC-1 advanced profile * @GST_VAAPI_PROFILE_JPEG_BASELINE: * JPEG baseline profile + * @GST_VAAPI_PROFILE_H265_MAIN: + * H.265 main profile [A.3.2] + * @GST_VAAPI_PROFILE_H265_MAIN10: + * H.265 main 10 profile [A.3.3] + * @GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE: + * H.265 main still picture profile [A.3.4] * * The set of all profiles for #GstVaapiProfile. */ @@ -153,6 +161,10 @@ typedef enum { GST_VAAPI_PROFILE_VC1_ADVANCED = GST_VAAPI_MAKE_PROFILE(VC1,3), GST_VAAPI_PROFILE_JPEG_BASELINE = GST_VAAPI_MAKE_PROFILE(JPEG,1), GST_VAAPI_PROFILE_VP8 = GST_VAAPI_MAKE_PROFILE(VP8,1), + GST_VAAPI_PROFILE_H265_MAIN = GST_VAAPI_MAKE_PROFILE(H265,1), + GST_VAAPI_PROFILE_H265_MAIN10 = GST_VAAPI_MAKE_PROFILE(H265,2), + GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE = + GST_VAAPI_MAKE_PROFILE(H265,3), } GstVaapiProfile; /** From 8c5f1b1c4b8bb89db207b2a57cebea45bf43d599 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 13 Apr 2015 14:53:46 +0300 Subject: [PATCH 1951/3781] HEVC: Add codec utility methods to core libgstvaapi Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/Makefile.am | 3 + gst-libs/gst/vaapi/gstvaapiutils_h265.c | 325 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_h265.h | 88 +++++ gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h | 105 ++++++ 4 files changed, 521 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_h265.c create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_h265.h create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index d457b3cc75..782f1ccb3b 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -80,6 +80,7 @@ libgstvaapi_source_c = \ gstvaapiutils_core.c \ gstvaapiutils_h264.c \ gstvaapiutils_mpeg2.c \ + gstvaapiutils_h265.c \ gstvaapivalue.c \ gstvaapivideopool.c \ gstvaapiwindow.c \ @@ -109,6 +110,7 @@ libgstvaapi_source_h = \ gstvaapitypes.h \ gstvaapiutils_h264.h \ gstvaapiutils_mpeg2.h \ + gstvaapiutils_h265.h \ gstvaapivalue.h \ gstvaapivideopool.h \ gstvaapiwindow.h \ @@ -142,6 +144,7 @@ libgstvaapi_source_priv_h = \ gstvaapiutils_core.h \ gstvaapiutils_h264_priv.h \ gstvaapiutils_mpeg2_priv.h \ + gstvaapiutils_h265_priv.h \ gstvaapiversion.h \ gstvaapivideopool_priv.h \ gstvaapiwindow_priv.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c new file mode 100644 index 0000000000..279400e0ca --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -0,0 +1,325 @@ +/* + * gstvaapiutils_h265.c - H.265 related utilities + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 +#include "gstvaapiutils_h265_priv.h" + +struct map +{ + guint value; + const gchar *name; +}; + +/* Profile string map */ +static const struct map gst_vaapi_h265_profile_map[] = { +/* *INDENT-OFF* */ + { GST_VAAPI_PROFILE_H265_MAIN, "main" }, + { GST_VAAPI_PROFILE_H265_MAIN10, "main-10" }, + { GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE, "main-still-picture" }, + { 0, NULL } +/* *INDENT-ON* */ +}; + +/* Level string map */ +static const struct map gst_vaapi_h265_level_map[] = { +/* *INDENT-OFF* */ + { GST_VAAPI_LEVEL_H265_L1, "1" }, + { GST_VAAPI_LEVEL_H265_L2, "2" }, + { GST_VAAPI_LEVEL_H265_L2_1, "2.1" }, + { GST_VAAPI_LEVEL_H265_L3, "3" }, + { GST_VAAPI_LEVEL_H265_L3_1, "3.1" }, + { GST_VAAPI_LEVEL_H265_L4, "4" }, + { GST_VAAPI_LEVEL_H265_L4_1, "4.1" }, + { GST_VAAPI_LEVEL_H265_L5, "5" }, + { GST_VAAPI_LEVEL_H265_L5_1, "5.1" }, + { GST_VAAPI_LEVEL_H265_L5_2, "5.2" }, + { GST_VAAPI_LEVEL_H265_L6, "6" }, + { GST_VAAPI_LEVEL_H265_L6_1, "6.1" }, + { GST_VAAPI_LEVEL_H265_L6_2, "6.2" }, + { 0, NULL } +/* *INDENT-ON* */ +}; + +/* Table A-1 - Level limits */ +/* *INDENT-OFF* */ +static const GstVaapiH265LevelLimits gst_vaapi_h265_level_limits[] = { + /* level idc MaxLumaPs MCPBMt MCPBHt MSlSeg MTR MTC MaxLumaSr MBRMt MBRHt MinCr*/ + { GST_VAAPI_LEVEL_H265_L1, 30, 36864, 350, 0, 16, 1, 1, 552960, 128, 0, 2}, + { GST_VAAPI_LEVEL_H265_L2, 60, 122880, 1500, 0, 16, 1, 1, 3686400, 1500, 0, 2}, + { GST_VAAPI_LEVEL_H265_L2_1, 63, 245760, 3000, 0, 20, 1, 1, 7372800, 3000, 0, 2}, + { GST_VAAPI_LEVEL_H265_L3, 90, 552960, 6000, 0, 30, 2, 2, 16588800, 6000, 0, 2}, + { GST_VAAPI_LEVEL_H265_L3_1, 93, 983040, 10000, 0, 40, 3, 3, 33177600, 10000, 0, 2}, + { GST_VAAPI_LEVEL_H265_L4, 120, 2228224, 12000, 30000, 75, 5, 5, 66846720, 12000, 30000, 4}, + { GST_VAAPI_LEVEL_H265_L4_1, 123, 2228224, 20000, 50000, 75, 5, 5, 133693440, 20000, 50000, 4}, + { GST_VAAPI_LEVEL_H265_L5, 150, 8912896, 25000, 100000, 200, 11, 10, 267386880, 25000, 100000, 6}, + { GST_VAAPI_LEVEL_H265_L5_1, 153, 8912896, 40000, 160000, 200, 11, 10, 534773760, 40000, 160000, 8}, + { GST_VAAPI_LEVEL_H265_L5_2, 156, 8912896, 60000, 240000, 200, 11, 10, 1069547520, 60000, 240000, 8}, + { GST_VAAPI_LEVEL_H265_L6, 180, 35651584, 60000, 240000, 600, 22, 20, 1069547520, 60000, 240000, 8}, + { GST_VAAPI_LEVEL_H265_L6_1, 183, 35651584, 120000, 480000, 600, 22, 20, 2139095040, 120000, 480000, 8}, + { GST_VAAPI_LEVEL_H265_L6_2, 186, 35651584, 240000, 800000, 600, 22, 20, 4278190080, 240000, 800000, 6}, + { 0, } +}; +/* *INDENT-ON* */ + +/* Lookup value in map */ +static const struct map * +map_lookup_value (const struct map *m, guint value) +{ + g_return_val_if_fail (m != NULL, NULL); + + for (; m->name != NULL; m++) { + if (m->value == value) + return m; + } + return NULL; +} + +/* Lookup name in map */ +static const struct map * +map_lookup_name (const struct map *m, const gchar * name) +{ + g_return_val_if_fail (m != NULL, NULL); + + if (!name) + return NULL; + + for (; m->name != NULL; m++) { + if (strcmp (m->name, name) == 0) + return m; + } + return NULL; +} + +/** Returns a relative score for the supplied GstVaapiProfile */ +guint +gst_vaapi_utils_h265_get_profile_score (GstVaapiProfile profile) +{ + const struct map *const m = + map_lookup_value (gst_vaapi_h265_profile_map, profile); + + return m ? 1 + (m - gst_vaapi_h265_profile_map) : 0; +} + +/** Returns GstVaapiProfile from H.265 profile_idc value */ +GstVaapiProfile +gst_vaapi_utils_h265_get_profile (guint8 profile_idc) +{ + GstVaapiProfile profile; + + switch (profile_idc) { + case GST_H265_PROFILE_MAIN: + profile = GST_VAAPI_PROFILE_H265_MAIN; + break; + case GST_H265_PROFILE_MAIN_10: + profile = GST_VAAPI_PROFILE_H265_MAIN10; + break; + case GST_H265_PROFILE_MAIN_STILL_PICTURE: + profile = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; + break; + default: + g_debug ("unsupported profile_idc value"); + profile = GST_VAAPI_PROFILE_UNKNOWN; + break; + } + return profile; +} + +/** Returns H.265 profile_idc value from GstVaapiProfile */ +guint8 +gst_vaapi_utils_h265_get_profile_idc (GstVaapiProfile profile) +{ + guint8 profile_idc; + + switch (profile) { + case GST_VAAPI_PROFILE_H265_MAIN: + profile_idc = GST_H265_PROFILE_MAIN; + break; + case GST_VAAPI_PROFILE_H265_MAIN10: + profile_idc = GST_H265_PROFILE_MAIN_10; + break; + case GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE: + profile_idc = GST_H265_PROFILE_MAIN_STILL_PICTURE; + break; + default: + g_debug ("unsupported GstVaapiProfile value"); + profile_idc = 0; + break; + } + return profile_idc; +} + +/** Returns GstVaapiProfile from a string representation */ +GstVaapiProfile +gst_vaapi_utils_h265_get_profile_from_string (const gchar * str) +{ + const struct map *const m = map_lookup_name (gst_vaapi_h265_profile_map, str); + + return m ? (GstVaapiProfile) m->value : GST_VAAPI_PROFILE_UNKNOWN; +} + +/** Returns a string representation for the supplied H.265 profile */ +const gchar * +gst_vaapi_utils_h265_get_profile_string (GstVaapiProfile profile) +{ + const struct map *const m = + map_lookup_value (gst_vaapi_h265_profile_map, profile); + + return m ? m->name : NULL; +} + +/** Returns GstVaapiLevelH265 from H.265 level_idc value */ +GstVaapiLevelH265 +gst_vaapi_utils_h265_get_level (guint8 level_idc) +{ + const GstVaapiH265LevelLimits *llp; + + for (llp = gst_vaapi_h265_level_limits; llp->level != 0; llp++) { + if (llp->level_idc == level_idc) + return llp->level; + } + g_debug ("unsupported level_idc value"); + return (GstVaapiLevelH265) 0; +} + +/** Returns H.265 level_idc value from GstVaapiLevelH265 */ +guint8 +gst_vaapi_utils_h265_get_level_idc (GstVaapiLevelH265 level) +{ + const GstVaapiH265LevelLimits *const llp = + gst_vaapi_utils_h265_get_level_limits (level); + + return llp ? llp->level_idc : 0; +} + +/** Returns GstVaapiLevelH265 from a string representation */ +GstVaapiLevelH265 +gst_vaapi_utils_h265_get_level_from_string (const gchar * str) +{ + gint v, level_idc = 0; + + if (!str || !str[0]) + goto not_found; + + v = g_ascii_digit_value (str[0]); + if (v < 0) + goto not_found; + level_idc = v * 30; + + switch (str[1]) { + case '\0': + break; + case '.': + v = g_ascii_digit_value (str[2]); + if (v < 0 || str[3] != '\0') + goto not_found; + level_idc += v; + break; + default: + goto not_found; + } + return gst_vaapi_utils_h265_get_level (level_idc); + +not_found: + return (GstVaapiLevelH265) 0; +} + +/** Returns a string representation for the supplied H.265 level */ +const gchar * +gst_vaapi_utils_h265_get_level_string (GstVaapiLevelH265 level) +{ + if (level < GST_VAAPI_LEVEL_H265_L1 || level > GST_VAAPI_LEVEL_H265_L6_2) + return NULL; + return gst_vaapi_h265_level_map[level - GST_VAAPI_LEVEL_H265_L1].name; +} + +/** Returns level limits as specified in Table A-1 of the H.265 standard */ +const GstVaapiH265LevelLimits * +gst_vaapi_utils_h265_get_level_limits (GstVaapiLevelH265 level) +{ + if (level < GST_VAAPI_LEVEL_H265_L1 || level > GST_VAAPI_LEVEL_H265_L6_2) + return NULL; + return &gst_vaapi_h265_level_limits[level - GST_VAAPI_LEVEL_H265_L1]; +} + +/** Returns the Table A-1 & A-2 specification */ +const GstVaapiH265LevelLimits * +gst_vaapi_utils_h265_get_level_limits_table (guint * out_length_ptr) +{ + if (out_length_ptr) + *out_length_ptr = G_N_ELEMENTS (gst_vaapi_h265_level_limits) - 1; + return gst_vaapi_h265_level_limits; +} + +/** Returns GstVaapiChromaType from H.265 chroma_format_idc value */ +GstVaapiChromaType +gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc) +{ + GstVaapiChromaType chroma_type; + + switch (chroma_format_idc) { + case 0: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400; + break; + case 1: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + break; + case 2: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; + break; + case 3: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; + break; + default: + g_debug ("unsupported chroma_format_idc value"); + chroma_type = (GstVaapiChromaType) 0; + break; + } + return chroma_type; +} + +/** Returns H.265 chroma_format_idc value from GstVaapiChromaType */ +guint +gst_vaapi_utils_h265_get_chroma_format_idc (GstVaapiChromaType chroma_type) +{ + guint chroma_format_idc; + + switch (chroma_type) { + case GST_VAAPI_CHROMA_TYPE_YUV400: + chroma_format_idc = 0; + break; + case GST_VAAPI_CHROMA_TYPE_YUV420: + chroma_format_idc = 1; + break; + case GST_VAAPI_CHROMA_TYPE_YUV422: + chroma_format_idc = 2; + break; + case GST_VAAPI_CHROMA_TYPE_YUV444: + chroma_format_idc = 3; + break; + default: + g_debug ("unsupported GstVaapiChromaType value"); + chroma_format_idc = 1; + break; + } + return chroma_format_idc; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.h b/gst-libs/gst/vaapi/gstvaapiutils_h265.h new file mode 100644 index 0000000000..fff6e6416b --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.h @@ -0,0 +1,88 @@ +/* + * gstvaapiutils_h265.h - H.265 related utilities + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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_UTILS_H265_H +#define GST_VAAPI_UTILS_H265_H + +#include +#include +#include + +G_BEGIN_DECLS + +/** + * GstVaapiLevelH265: + * @GST_VAAPI_LEVEL_H265_L1: H.265 level 1. + * @GST_VAAPI_LEVEL_H265_L2: H.265 level 2. + * @GST_VAAPI_LEVEL_H265_L2_1: H.265 level 2.1. + * @GST_VAAPI_LEVEL_H265_L3: H.265 level 3. + * @GST_VAAPI_LEVEL_H265_L3_1: H.265 level 3.1. + * @GST_VAAPI_LEVEL_H265_L4: H.265 level 4. + * @GST_VAAPI_LEVEL_H265_L4_1: H.265 level 4.1. + * @GST_VAAPI_LEVEL_H265_L5: H.265 level 5. + * @GST_VAAPI_LEVEL_H265_L5_1: H.265 level 5.1. + * @GST_VAAPI_LEVEL_H265_L5_2: H.265 level 5.2. + * @GST_VAAPI_LEVEL_H265_L6: H.265 level 6. + * @GST_VAAPI_LEVEL_H265_L6_1: H.265 level 6.1. + * @GST_VAAPI_LEVEL_H265_L6_2: H.265 level 6.2. + * + * The set of all levels for #GstVaapiLevelH265. + */ +typedef enum { + GST_VAAPI_LEVEL_H265_L1 = 1, + GST_VAAPI_LEVEL_H265_L2, + GST_VAAPI_LEVEL_H265_L2_1, + GST_VAAPI_LEVEL_H265_L3, + GST_VAAPI_LEVEL_H265_L3_1, + GST_VAAPI_LEVEL_H265_L4, + GST_VAAPI_LEVEL_H265_L4_1, + GST_VAAPI_LEVEL_H265_L5, + GST_VAAPI_LEVEL_H265_L5_1, + GST_VAAPI_LEVEL_H265_L5_2, + GST_VAAPI_LEVEL_H265_L6, + GST_VAAPI_LEVEL_H265_L6_1, + GST_VAAPI_LEVEL_H265_L6_2, +} GstVaapiLevelH265; + +/* Returns a relative score for the supplied GstVaapiProfile */ +guint +gst_vaapi_utils_h265_get_profile_score (GstVaapiProfile profile); + +/* Returns GstVaapiProfile from a string representation */ +GstVaapiProfile +gst_vaapi_utils_h265_get_profile_from_string (const gchar * str); + +/* Returns a string representation for the supplied H.265 profile */ +const gchar * +gst_vaapi_utils_h265_get_profile_string (GstVaapiProfile profile); + +/* Returns GstVaapiLevelH265 from a string representation */ +GstVaapiLevelH265 +gst_vaapi_utils_h265_get_level_from_string (const gchar * str); + +/* Returns a string representation for the supplied H.265 level */ +const gchar * +gst_vaapi_utils_h265_get_level_string (GstVaapiLevelH265 level); + +G_END_DECLS + +#endif /* GST_VAAPI_UTILS_H265_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h new file mode 100644 index 0000000000..3991ee96a4 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h @@ -0,0 +1,105 @@ +/* + * gstvaapiutils_h265_priv.h - H.265 related utilities + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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_UTILS_H265_PRIV_H +#define GST_VAAPI_UTILS_H265_PRIV_H + +#include "gstvaapiutils_h265.h" +#include "libgstvaapi_priv_check.h" + +G_BEGIN_DECLS + +/** + * GstVaapiH265LevelLimits: + * @level: the #GstVaapiLevelH265 + * @level_idc: the H.265 level_idc value + * @MaxLumaPs: the maximum luma picture size + * @MaxCPBTierMain: the maximum CPB size for Main tier(kbits) + * @MaxCPBTierHigh: the maximum CPB size for High tier(kbits) + * @MaxSliceSegPic: the maximum slice segments per picture + * @MaxTileRows: the maximum number of Tile Rows + * @MaxTileColumns: the maximum number of Tile Columns + * @MaxLumaSr: the maximum luma sample rate (samples/sec) + * @MaxBRTierMain: the maximum video bit rate for Main Tier(kbps) + * @MaxBRTierHigh: the maximum video bit rate for High Tier(kbps) + * @MinCr: the mimimum compression ratio + * + * The data structure that describes the limits of an H.265 level. + */ +typedef struct { + GstVaapiLevelH265 level; + guint8 level_idc; + guint32 MaxLumaPs; + guint32 MaxCPBTierMain; + guint32 MaxCPBTierHigh; + guint32 MaxSliceSegPic; + guint32 MaxTileRows; + guint32 MaxTileColumns; + guint32 MaxLumaSr; + guint32 MaxBRTierMain; + guint32 MaxBRTierHigh; + guint32 MinCr; +} GstVaapiH265LevelLimits; + +/* Returns GstVaapiProfile from H.265 profile_idc value */ +G_GNUC_INTERNAL +GstVaapiProfile +gst_vaapi_utils_h265_get_profile (guint8 profile_idc); + +/* Returns H.265 profile_idc value from GstVaapiProfile */ +G_GNUC_INTERNAL +guint8 +gst_vaapi_utils_h265_get_profile_idc (GstVaapiProfile profile); + +/* Returns GstVaapiLevelH265 from H.265 level_idc value */ +G_GNUC_INTERNAL +GstVaapiLevelH265 +gst_vaapi_utils_h265_get_level (guint8 level_idc); + +/* Returns H.265 level_idc value from GstVaapiLevelH265 */ +G_GNUC_INTERNAL +guint8 +gst_vaapi_utils_h265_get_level_idc (GstVaapiLevelH265 level); + +/* Returns level limits as specified in Table A-1 of the H.265 standard */ +G_GNUC_INTERNAL +const GstVaapiH265LevelLimits * +gst_vaapi_utils_h265_get_level_limits (GstVaapiLevelH265 level); + +/* Returns the Table A-1 specification */ +G_GNUC_INTERNAL +const GstVaapiH265LevelLimits * +gst_vaapi_utils_h265_get_level_limits_table (guint * out_length_ptr); + +/* Returns GstVaapiChromaType from H.265 chroma_format_idc value */ +G_GNUC_INTERNAL +GstVaapiChromaType +gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc); + +/* Returns H.265 chroma_format_idc value from GstVaapiChromaType */ +G_GNUC_INTERNAL +guint +gst_vaapi_utils_h265_get_chroma_format_idc (GstVaapiChromaType chroma_type); + +G_END_DECLS + +#endif /* GST_VAAPI_UTILS_H265_PRIV_H */ From 430174f5a70792b954bf93481aff49db2ed8bbaa Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 13 Apr 2015 15:41:45 +0300 Subject: [PATCH 1952/3781] HEVC: Add HEVC(h265) decoder to core libgstvaapi Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 2942 +++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_h265.h | 61 + 3 files changed, 3005 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_h265.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_h265.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 782f1ccb3b..4c6a254db7 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -55,6 +55,7 @@ libgstvaapi_source_c = \ gstvaapidecoder.c \ gstvaapidecoder_dpb.c \ gstvaapidecoder_h264.c \ + gstvaapidecoder_h265.c \ gstvaapidecoder_mpeg2.c \ gstvaapidecoder_mpeg4.c \ gstvaapidecoder_objects.c \ @@ -91,6 +92,7 @@ libgstvaapi_source_h = \ gstvaapibufferproxy.h \ gstvaapidecoder.h \ gstvaapidecoder_h264.h \ + gstvaapidecoder_h265.h \ gstvaapidecoder_mpeg2.h \ gstvaapidecoder_mpeg4.h \ gstvaapidecoder_vc1.h \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c new file mode 100644 index 0000000000..be0f9cc066 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -0,0 +1,2942 @@ +/* + * gstvaapidecoder_h265.c - H.265 decoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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_h265 + * @short_description: H.265 decoder + */ + +#include "sysdeps.h" +#include +#include +#include +#include "gstvaapidecoder_h265.h" +#include "gstvaapidecoder_objects.h" +#include "gstvaapidecoder_priv.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapiobject_priv.h" +#include "gstvaapiutils_h265_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +/* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */ +#define USE_STRICT_DPB_ORDERING 0 + +typedef struct _GstVaapiDecoderH265Private GstVaapiDecoderH265Private; +typedef struct _GstVaapiDecoderH265Class GstVaapiDecoderH265Class; +typedef struct _GstVaapiFrameStore GstVaapiFrameStore; +typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; +typedef struct _GstVaapiParserInfoH265 GstVaapiParserInfoH265; +typedef struct _GstVaapiPictureH265 GstVaapiPictureH265; + +static gboolean nal_is_slice (guint8 nal_type); + +/* ------------------------------------------------------------------------- */ +/* --- H.265 Parser Info --- */ +/* ------------------------------------------------------------------------- */ + +/* + * Extended decoder unit flags: + * + * @GST_VAAPI_DECODER_UNIT_AU_START: marks the start of an access unit. + * @GST_VAAPI_DECODER_UNIT_AU_END: marks the end of an access unit. + */ +enum +{ + GST_VAAPI_DECODER_UNIT_FLAG_AU_START = + (GST_VAAPI_DECODER_UNIT_FLAG_LAST << 0), + GST_VAAPI_DECODER_UNIT_FLAG_AU_END = (GST_VAAPI_DECODER_UNIT_FLAG_LAST << 1), + + GST_VAAPI_DECODER_UNIT_FLAGS_AU = (GST_VAAPI_DECODER_UNIT_FLAG_AU_START | + GST_VAAPI_DECODER_UNIT_FLAG_AU_END), +}; + +#define GST_VAAPI_PARSER_INFO_H265(obj) \ + ((GstVaapiParserInfoH265 *)(obj)) + +struct _GstVaapiParserInfoH265 +{ + GstVaapiMiniObject parent_instance; + GstH265NalUnit nalu; + union + { + GstH265VPS vps; + GstH265SPS sps; + GstH265PPS pps; + /* Fix SEI parsing in codecparser, have to use GArry like h264parser */ + GstH265SEIMessage sei; + GstH265SliceHdr slice_hdr; + } data; + guint state; + guint flags; // Same as decoder unit flags (persistent) +}; + +static void +gst_vaapi_parser_info_h265_finalize (GstVaapiParserInfoH265 * pi) +{ + if (nal_is_slice (pi->nalu.type)) + gst_h265_slice_hdr_free (&pi->data.slice_hdr); + else { + switch (pi->nalu.type) { + case GST_H265_NAL_VPS: + case GST_H265_NAL_SPS: + case GST_H265_NAL_PPS: + break; + case GST_H265_NAL_PREFIX_SEI: + case GST_H265_NAL_SUFFIX_SEI: + gst_h265_sei_free (&pi->data.sei); + break; + } + } +} + +static inline const GstVaapiMiniObjectClass * +gst_vaapi_parser_info_h265_class (void) +{ + static const GstVaapiMiniObjectClass GstVaapiParserInfoH265Class = { + .size = sizeof (GstVaapiParserInfoH265), + .finalize = (GDestroyNotify) gst_vaapi_parser_info_h265_finalize + }; + return &GstVaapiParserInfoH265Class; +} + +static inline GstVaapiParserInfoH265 * +gst_vaapi_parser_info_h265_new (void) +{ + return (GstVaapiParserInfoH265 *) + gst_vaapi_mini_object_new (gst_vaapi_parser_info_h265_class ()); +} + +#define gst_vaapi_parser_info_h265_ref(pi) \ + gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pi)) + +#define gst_vaapi_parser_info_h265_unref(pi) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pi)) + +#define gst_vaapi_parser_info_h265_replace(old_pi_ptr, new_pi) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pi_ptr), \ + (GstVaapiMiniObject *)(new_pi)) + +/* ------------------------------------------------------------------------- */ +/* --- H.265 Pictures --- */ +/* ------------------------------------------------------------------------- */ + +/* + * Extended picture flags: + * + * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture + * @GST_VAAPI_PICTURE_FLAG_AU_START: flag that marks the start of an + * access unit (AU) + * @GST_VAAPI_PICTURE_FLAG_AU_END: flag that marks the end of an + * access unit (AU) + * @GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE: flag indicate the inclusion + * of picture in RefPicSetStCurrBefore reference list + * @GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER: flag indicate the inclusion + * of picture in RefPictSetStCurrAfter reference list + * @GST_VAAPI_PICTURE_FLAG_RPS_ST_FOLL: flag indicate the inclusion + * of picture in RefPicSetStFoll reference list + * @GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR: flag indicate the inclusion + * of picture in RefPicSetLtCurr reference list + * @GST_VAAPI_PICTURE_FLAG_RPS_LT_FOLL: flag indicate the inclusion + * of picture in RefPicSetLtFoll reference list + * @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies + * "used for short-term reference" + * @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies + * "used for long-term reference" + * @GST_VAAPI_PICTURE_FLAGS_REFERENCE: mask covering any kind of + * reference picture (short-term reference or long-term reference) + */ +enum +{ + GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0), + GST_VAAPI_PICTURE_FLAG_REFERENCE2 = (GST_VAAPI_PICTURE_FLAG_LAST << 1), + GST_VAAPI_PICTURE_FLAG_AU_START = (GST_VAAPI_PICTURE_FLAG_LAST << 4), + GST_VAAPI_PICTURE_FLAG_AU_END = (GST_VAAPI_PICTURE_FLAG_LAST << 5), + GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE = + (GST_VAAPI_PICTURE_FLAG_LAST << 6), + GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER = (GST_VAAPI_PICTURE_FLAG_LAST << 7), + GST_VAAPI_PICTURE_FLAG_RPS_ST_FOLL = (GST_VAAPI_PICTURE_FLAG_LAST << 8), + GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR = (GST_VAAPI_PICTURE_FLAG_LAST << 9), + GST_VAAPI_PICTURE_FLAG_RPS_LT_FOLL = (GST_VAAPI_PICTURE_FLAG_LAST << 10), + + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = + (GST_VAAPI_PICTURE_FLAG_REFERENCE), + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = + (GST_VAAPI_PICTURE_FLAG_REFERENCE | GST_VAAPI_PICTURE_FLAG_REFERENCE2), + GST_VAAPI_PICTURE_FLAGS_REFERENCE = + (GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE | + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE), + + GST_VAAPI_PICTURE_FLAGS_RPS_ST = + (GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE | + GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER | + GST_VAAPI_PICTURE_FLAG_RPS_ST_FOLL), + GST_VAAPI_PICTURE_FLAGS_RPS_LT = + (GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR | GST_VAAPI_PICTURE_FLAG_RPS_LT_FOLL), +}; + +#define GST_VAAPI_PICTURE_IS_IDR(picture) \ + (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR)) + +#define GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture) \ + ((GST_VAAPI_PICTURE_FLAGS(picture) & \ + GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \ + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE) + +#define GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture) \ + ((GST_VAAPI_PICTURE_FLAGS(picture) & \ + GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \ + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE) + +#define GST_VAAPI_PICTURE_H265(picture) \ + ((GstVaapiPictureH265 *)(picture)) + +struct _GstVaapiPictureH265 +{ + GstVaapiPicture base; + GstH265SliceHdr *last_slice_hdr; + guint structure; + gint32 poc; // PicOrderCntVal (8.3.1) + gint32 poc_lsb; // slice_pic_order_cnt_lsb + guint32 pic_latency_cnt; // PicLatencyCount + guint output_flag:1; + guint output_needed:1; + guint NoRaslOutputFlag:1; + guint NoOutputOfPriorPicsFlag:1; + guint RapPicFlag:1; // nalu type between 16 and 21 + guint IntraPicFlag:1; // Intra pic (only Intra slices) +}; + +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiPictureH265, gst_vaapi_picture_h265); + +void +gst_vaapi_picture_h265_destroy (GstVaapiPictureH265 * picture) +{ + gst_vaapi_picture_destroy (GST_VAAPI_PICTURE (picture)); +} + +gboolean +gst_vaapi_picture_h265_create (GstVaapiPictureH265 * picture, + const GstVaapiCodecObjectConstructorArgs * args) +{ + if (!gst_vaapi_picture_create (GST_VAAPI_PICTURE (picture), args)) + return FALSE; + + picture->poc = G_MAXINT32; + picture->output_needed = FALSE; + return TRUE; +} + +static inline GstVaapiPictureH265 * +gst_vaapi_picture_h265_new (GstVaapiDecoderH265 * decoder) +{ + return (GstVaapiPictureH265 *) + gst_vaapi_codec_object_new (&GstVaapiPictureH265Class, + GST_VAAPI_CODEC_BASE (decoder), NULL, + sizeof (VAPictureParameterBufferHEVC), NULL, 0, 0); +} + +static inline void +gst_vaapi_picture_h265_set_reference (GstVaapiPictureH265 * picture, + guint reference_flags) +{ + if (!picture) + return; + GST_VAAPI_PICTURE_FLAG_UNSET (picture, + GST_VAAPI_PICTURE_FLAGS_RPS_ST | GST_VAAPI_PICTURE_FLAGS_RPS_LT); + GST_VAAPI_PICTURE_FLAG_UNSET (picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); + GST_VAAPI_PICTURE_FLAG_SET (picture, reference_flags); +} + +/* ------------------------------------------------------------------------- */ +/* --- Frame Buffers (DPB) --- */ +/* ------------------------------------------------------------------------- */ + +struct _GstVaapiFrameStore +{ + /*< private > */ + GstVaapiMiniObject parent_instance; + + GstVaapiPictureH265 *buffer; +}; + +static void +gst_vaapi_frame_store_finalize (gpointer object) +{ + GstVaapiFrameStore *const fs = object; + + gst_vaapi_picture_replace (&fs->buffer, NULL); +} + +static GstVaapiFrameStore * +gst_vaapi_frame_store_new (GstVaapiPictureH265 * picture) +{ + GstVaapiFrameStore *fs; + + static const GstVaapiMiniObjectClass GstVaapiFrameStoreClass = { + sizeof (GstVaapiFrameStore), + gst_vaapi_frame_store_finalize + }; + + fs = (GstVaapiFrameStore *) + gst_vaapi_mini_object_new (&GstVaapiFrameStoreClass); + if (!fs) + return NULL; + + fs->buffer = gst_vaapi_picture_ref (picture); + + return fs; +} + +static inline gboolean +gst_vaapi_frame_store_has_reference (GstVaapiFrameStore * fs) +{ + if (GST_VAAPI_PICTURE_IS_REFERENCE (fs->buffer)) + return TRUE; + return FALSE; +} + +#define gst_vaapi_frame_store_ref(fs) \ + gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(fs)) + +#define gst_vaapi_frame_store_unref(fs) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(fs)) + +#define gst_vaapi_frame_store_replace(old_fs_p, new_fs) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_fs_p), \ + (GstVaapiMiniObject *)(new_fs)) + +/* ------------------------------------------------------------------------- */ +/* --- H.265 Decoder --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_DECODER_H265_CAST(decoder) \ + ((GstVaapiDecoderH265 *)(decoder)) + +typedef enum +{ + GST_H265_VIDEO_STATE_GOT_VPS = 1 << 0, + GST_H265_VIDEO_STATE_GOT_SPS = 1 << 1, + GST_H265_VIDEO_STATE_GOT_PPS = 1 << 2, + GST_H265_VIDEO_STATE_GOT_SLICE = 1 << 3, + + GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS = + (GST_H265_VIDEO_STATE_GOT_SPS | GST_H265_VIDEO_STATE_GOT_PPS), + GST_H265_VIDEO_STATE_VALID_PICTURE = + (GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS | + GST_H265_VIDEO_STATE_GOT_SLICE) +} GstH265VideoState; + +struct _GstVaapiDecoderH265Private +{ + GstH265Parser *parser; + guint parser_state; + guint decoder_state; + GstVaapiStreamAlignH265 stream_alignment; + GstVaapiPictureH265 *current_picture; + GstVaapiParserInfoH265 *vps[GST_H265_MAX_VPS_COUNT]; + GstVaapiParserInfoH265 *active_vps; + GstVaapiParserInfoH265 *sps[GST_H265_MAX_SPS_COUNT]; + GstVaapiParserInfoH265 *active_sps; + GstVaapiParserInfoH265 *pps[GST_H265_MAX_PPS_COUNT]; + GstVaapiParserInfoH265 *active_pps; + GstVaapiParserInfoH265 *prev_pi; + GstVaapiParserInfoH265 *prev_slice_pi; + GstVaapiParserInfoH265 *prev_independent_slice_pi; + GstVaapiFrameStore **dpb; + guint dpb_count; + guint dpb_size; + guint dpb_size_max; + GstVaapiProfile profile; + GstVaapiEntrypoint entrypoint; + GstVaapiChromaType chroma_type; + + GstVaapiPictureH265 *RefPicSetStCurrBefore[16]; + GstVaapiPictureH265 *RefPicSetStCurrAfter[16]; + GstVaapiPictureH265 *RefPicSetStFoll[16]; + GstVaapiPictureH265 *RefPicSetLtCurr[16]; + GstVaapiPictureH265 *RefPicSetLtFoll[16]; + + GstVaapiPictureH265 *RefPicList0[16]; + guint RefPicList0_count; + GstVaapiPictureH265 *RefPicList1[16]; + guint RefPicList1_count; + + guint32 SpsMaxLatencyPictures; + + guint nal_length_size; + + guint pic_width_in_luma_samples; //sps->pic_width_in_luma_samples + guint pic_height_in_luma_samples; //sps->pic_height_in_luma_samples + guint pic_structure; // pic_struct (from SEI pic_timing() or inferred) + gint32 poc; // PicOrderCntVal + gint32 poc_msb; // PicOrderCntMsb + gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header()) + gint32 prev_poc_msb; // prevPicOrderCntMsb + gint32 prev_poc_lsb; // prevPicOrderCntLsb + gint32 prev_tid0pic_poc_lsb; + gint32 prev_tid0pic_poc_msb; + gint32 PocStCurrBefore[16]; + gint32 PocStCurrAfter[16]; + gint32 PocStFoll[16]; + gint32 PocLtCurr[16]; + gint32 PocLtFoll[16]; + guint NumPocStCurrBefore; + guint NumPocStCurrAfter; + guint NumPocStFoll; + guint NumPocLtCurr; + guint NumPocLtFoll; + guint NumPocTotalCurr; + guint is_opened:1; + guint is_hvcC:1; + guint has_context:1; + guint progressive_sequence:1; +}; + +/** + * GstVaapiDecoderH265: + * + * A decoder based on H265. + */ +struct _GstVaapiDecoderH265 +{ + /*< private > */ + GstVaapiDecoder parent_instance; + GstVaapiDecoderH265Private priv; +}; + +/** + * GstVaapiDecoderH265Class: + * + * A decoder class based on H265. + */ +struct _GstVaapiDecoderH265Class +{ + /*< private > */ + GstVaapiDecoderClass parent_class; +}; + +#define RSV_VCL_N10 10 +#define RSV_VCL_N12 12 +#define RSV_VCL_N14 14 + +static gboolean +nal_is_idr (guint8 nal_type) +{ + if ((nal_type == GST_H265_NAL_SLICE_IDR_W_RADL) || + (nal_type == GST_H265_NAL_SLICE_IDR_N_LP)) + return TRUE; + return FALSE; +} + +static gboolean +nal_is_irap (guint8 nal_type) +{ + if ((nal_type >= GST_H265_NAL_SLICE_BLA_W_LP) && + (nal_type <= RESERVED_IRAP_NAL_TYPE_MAX)) + return TRUE; + return FALSE; +} + +static gboolean +nal_is_bla (guint8 nal_type) +{ + if ((nal_type >= GST_H265_NAL_SLICE_BLA_W_LP) && + (nal_type <= GST_H265_NAL_SLICE_BLA_N_LP)) + return TRUE; + return FALSE; +} + +static gboolean +nal_is_radl (guint8 nal_type) +{ + if ((nal_type >= GST_H265_NAL_SLICE_RADL_N) && + (nal_type <= GST_H265_NAL_SLICE_RADL_R)) + return TRUE; + return FALSE; +} + +static gboolean +nal_is_rasl (guint8 nal_type) +{ + if ((nal_type >= GST_H265_NAL_SLICE_RASL_N) && + (nal_type <= GST_H265_NAL_SLICE_RASL_R)) + return TRUE; + return FALSE; +} + +static gboolean +nal_is_slice (guint8 nal_type) +{ + if ((nal_type >= GST_H265_NAL_SLICE_TRAIL_N) && + (nal_type <= GST_H265_NAL_SLICE_CRA_NUT)) + return TRUE; + return FALSE; +} + +static gboolean +nal_is_ref (guint8 nal_type) +{ + gboolean ret = FALSE; + switch (nal_type) { + case GST_H265_NAL_SLICE_TRAIL_N: + case GST_H265_NAL_SLICE_TSA_N: + case GST_H265_NAL_SLICE_STSA_N: + case GST_H265_NAL_SLICE_RADL_N: + case GST_H265_NAL_SLICE_RASL_N: + case RSV_VCL_N10: + case RSV_VCL_N12: + case RSV_VCL_N14: + ret = FALSE; + break; + default: + ret = TRUE; + break; + } + return ret; +} + +/* Activates the supplied PPS */ +static GstH265PPS * +ensure_pps (GstVaapiDecoderH265 * decoder, GstH265PPS * pps) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = priv->pps[pps->id]; + gst_vaapi_parser_info_h265_replace (&priv->active_pps, pi); + return pi ? &pi->data.pps : NULL; +} + +/* Returns the active PPS */ +static inline GstH265PPS * +get_pps (GstVaapiDecoderH265 * decoder) +{ + GstVaapiParserInfoH265 *const pi = decoder->priv.active_pps; + return pi ? &pi->data.pps : NULL; +} + +/* Activate the supplied SPS */ +static GstH265SPS * +ensure_sps (GstVaapiDecoderH265 * decoder, GstH265SPS * sps) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = priv->sps[sps->id]; + gst_vaapi_parser_info_h265_replace (&priv->active_sps, pi); + return pi ? &pi->data.sps : NULL; +} + +/* Returns the active SPS */ +static inline GstH265SPS * +get_sps (GstVaapiDecoderH265 * decoder) +{ + GstVaapiParserInfoH265 *const pi = decoder->priv.active_sps; + return pi ? &pi->data.sps : NULL; +} + +/* Activate the supplied VPS */ +static GstH265VPS * +ensure_vps (GstVaapiDecoderH265 * decoder, GstH265VPS * vps) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = priv->vps[vps->id]; + gst_vaapi_parser_info_h265_replace (&priv->active_vps, pi); + return pi ? &pi->data.vps : NULL; +} + +/* Returns the active VPS */ +static inline GstH265VPS * +get_vps (GstVaapiDecoderH265 * decoder) +{ + GstVaapiParserInfoH265 *const pi = decoder->priv.active_vps; + return pi ? &pi->data.vps : NULL; +} + +/* Get number of reference frames to use */ +static guint +get_max_dec_frame_buffering (GstH265SPS * sps) +{ + guint max_dec_frame_buffering; + GstVaapiLevelH265 level; + const GstVaapiH265LevelLimits *level_limits; + level = gst_vaapi_utils_h265_get_level (sps->profile_tier_level.level_idc); + level_limits = gst_vaapi_utils_h265_get_level_limits (level); + if (G_UNLIKELY (!level_limits)) { + GST_FIXME ("unsupported level_idc value (%d)", + sps->profile_tier_level.level_idc); + max_dec_frame_buffering = 16; + } + /* Fixme: Add limit check based on Annex A */ + return MAX (1, (sps->max_dec_pic_buffering_minus1[0] + 1)); +} + +static void +dpb_remove_index (GstVaapiDecoderH265 * decoder, gint index) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + guint i, num_frames = --priv->dpb_count; + if (USE_STRICT_DPB_ORDERING) { + for (i = index; i < num_frames; i++) + gst_vaapi_frame_store_replace (&priv->dpb[i], priv->dpb[i + 1]); + } else if (index != num_frames) + gst_vaapi_frame_store_replace (&priv->dpb[index], priv->dpb[num_frames]); + gst_vaapi_frame_store_replace (&priv->dpb[num_frames], NULL); +} + +static gboolean +dpb_output (GstVaapiDecoderH265 * decoder, GstVaapiFrameStore * fs) +{ + GstVaapiPictureH265 *picture; + g_return_val_if_fail (fs != NULL, FALSE); + + picture = fs->buffer; + g_return_val_if_fail (picture != NULL, FALSE); + + picture->output_needed = FALSE; + return gst_vaapi_picture_output (GST_VAAPI_PICTURE_CAST (picture)); +} + +/* Get the dpb picture having the specifed poc or poc_lsb */ +static GstVaapiPictureH265 * +dpb_get_picture (GstVaapiDecoderH265 * decoder, gint poc, gboolean match_lsb) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiPictureH265 *picture = NULL; + gint i; + + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + picture = fs->buffer; + + if (picture && GST_VAAPI_PICTURE_FLAG_IS_SET (picture, + GST_VAAPI_PICTURE_FLAGS_REFERENCE)) { + if (match_lsb) { + if (picture->poc_lsb == poc) + return picture; + } else { + if (picture->poc == poc) + return picture; + } + } + } + return NULL; +} + +/* Get the dpb picture having the specifed poc and shor/long ref flags */ +static GstVaapiPictureH265 * +dpb_get_ref_picture (GstVaapiDecoderH265 * decoder, gint poc, gboolean is_short) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiPictureH265 *picture = NULL; + gint i; + + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + picture = fs->buffer; + + if (picture && picture->poc == poc) { + if (is_short && GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE (picture)) + return picture; + + else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (picture)) + return picture; + } + } + + return NULL; +} + +/* Finds the picture with the lowest POC that needs to be output */ +static gint +dpb_find_lowest_poc (GstVaapiDecoderH265 * decoder, + GstVaapiPictureH265 ** found_picture_ptr) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiPictureH265 *found_picture = NULL; + GstVaapiPictureH265 *tmp_picture = NULL; + guint i, found_index; + + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + tmp_picture = fs->buffer; + if (tmp_picture && !tmp_picture->output_needed) + continue; + if (!found_picture) { + found_picture = tmp_picture; + found_index = i; + } + if (found_picture->poc > tmp_picture->poc) { + found_picture = tmp_picture; + found_index = i; + } + } + + if (found_picture_ptr) + *found_picture_ptr = found_picture; + return found_picture ? found_index : -1; +} + +static gboolean +dpb_bump (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiPictureH265 *found_picture; + gint found_index; + gboolean success; + + found_index = dpb_find_lowest_poc (decoder, &found_picture); + if (found_index < 0) + return FALSE; + + success = dpb_output (decoder, priv->dpb[found_index]); + + if (!gst_vaapi_frame_store_has_reference (priv->dpb[found_index])) + dpb_remove_index (decoder, found_index); + + return success; +} + +static void +dpb_clear (GstVaapiDecoderH265 * decoder, gboolean hard_flush) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiPictureH265 *pic; + guint i; + + if (hard_flush) { + for (i = 0; i < priv->dpb_count; i++) + dpb_remove_index (decoder, i); + priv->dpb_count = 0; + } else { + /* Remove unused pictures from DPB */ + i = 0; + while (i < priv->dpb_count) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + pic = fs->buffer; + if (!pic->output_needed && !gst_vaapi_frame_store_has_reference (fs)) + dpb_remove_index (decoder, i); + else + i++; + } + } +} + +static void +dpb_flush (GstVaapiDecoderH265 * decoder) +{ + /* Output any frame remaining in DPB */ + while (dpb_bump (decoder, NULL)); + dpb_clear (decoder, TRUE); +} + +static gint +dpb_get_num_need_output (GstVaapiDecoderH265 * decoder) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + guint i = 0, n_output_needed = 0; + + while (i < priv->dpb_count) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + if (fs->buffer->output_needed) + n_output_needed++; + i++; + } + + return n_output_needed; +} + +static gboolean +check_latency_cnt (GstVaapiDecoderH265 * decoder) +{ + GstVaapiPictureH265 *tmp_pic; + guint i = 0; + GstVaapiDecoderH265Private *const priv = &decoder->priv; + + while (i < priv->dpb_count) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + tmp_pic = fs->buffer; + if (tmp_pic->output_needed) { + if (tmp_pic->pic_latency_cnt >= priv->SpsMaxLatencyPictures) + return TRUE; + } + i++; + } + + return FALSE; +} + +static gboolean +dpb_add (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) +{ + GstVaapiFrameStore *fs; + GstVaapiPictureH265 *tmp_pic; + guint i = 0; + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstH265SPS *const sps = get_sps (decoder); + + /* C.5.2.3 */ + while (i < priv->dpb_count) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + tmp_pic = fs->buffer; + if (tmp_pic->output_needed) + tmp_pic->pic_latency_cnt += 1; + i++; + } + + if (picture->output_flag) { + picture->output_needed = 1; + picture->pic_latency_cnt = 0; + } else + picture->output_needed = 0; + + /* set pic as short_term_ref */ + gst_vaapi_picture_h265_set_reference (picture, + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE); + + /* C.5.2.4 "Bumping" process */ + while ((dpb_get_num_need_output (decoder) > + sps->max_num_reorder_pics[sps->max_sub_layers_minus1]) + || (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1] + && check_latency_cnt (decoder))) + dpb_bump (decoder, picture); + + /* Create new frame store */ + fs = gst_vaapi_frame_store_new (picture); + if (!fs) + return FALSE; + gst_vaapi_frame_store_replace (&priv->dpb[priv->dpb_count++], fs); + gst_vaapi_frame_store_unref (fs); + + return TRUE; +} + + +static gboolean +dpb_init (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture, + GstVaapiParserInfoH265 * pi) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstH265SPS *const sps = get_sps (decoder); + + /* Fixme: Not required?? */ + if (nal_is_idr (pi->nalu.type)) + while (dpb_bump (decoder, picture)); + + /* C.5.2.2 */ + if (picture->IntraPicFlag && + picture->NoRaslOutputFlag /*&& Fixme: Not picture0 */ ) { + if (picture->NoOutputOfPriorPicsFlag) + dpb_clear (decoder, TRUE); + else + dpb_clear (decoder, FALSE); + } else { + dpb_clear (decoder, FALSE); + while ((dpb_get_num_need_output (decoder) > + sps->max_num_reorder_pics[sps->max_sub_layers_minus1]) + || (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1] + && check_latency_cnt (decoder)) + || (priv->dpb_count >= + (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] + + 1))) { + dpb_bump (decoder, picture); + } + } + + return TRUE; +} + +static gboolean +dpb_reset (GstVaapiDecoderH265 * decoder, guint dpb_size) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + if (dpb_size > priv->dpb_size_max) { + priv->dpb = g_try_realloc_n (priv->dpb, dpb_size, sizeof (*priv->dpb)); + if (!priv->dpb) + return FALSE; + memset (&priv->dpb[priv->dpb_size_max], 0, + (dpb_size - priv->dpb_size_max) * sizeof (*priv->dpb)); + priv->dpb_size_max = dpb_size; + } + priv->dpb_size = dpb_size; + GST_DEBUG ("DPB size %u", priv->dpb_size); + return TRUE; +} + +static GstVaapiDecoderStatus +get_status (GstH265ParserResult result) +{ + GstVaapiDecoderStatus status; + switch (result) { + case GST_H265_PARSER_OK: + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + case GST_H265_PARSER_NO_NAL_END: + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + break; + case GST_H265_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_h265_close (GstVaapiDecoderH265 * decoder) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + gst_vaapi_picture_replace (&priv->current_picture, NULL); + gst_vaapi_parser_info_h265_replace (&priv->prev_slice_pi, NULL); + gst_vaapi_parser_info_h265_replace (&priv->prev_independent_slice_pi, NULL); + gst_vaapi_parser_info_h265_replace (&priv->prev_pi, NULL); + + dpb_clear (decoder, TRUE); + + if (priv->parser) { + gst_h265_parser_free (priv->parser); + priv->parser = NULL; + } +} + +static gboolean +gst_vaapi_decoder_h265_open (GstVaapiDecoderH265 * decoder) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + gst_vaapi_decoder_h265_close (decoder); + priv->parser = gst_h265_parser_new (); + if (!priv->parser) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_decoder_h265_destroy (GstVaapiDecoder * base_decoder) +{ + GstVaapiDecoderH265 *const decoder = + GST_VAAPI_DECODER_H265_CAST (base_decoder); + GstVaapiDecoderH265Private *const priv = &decoder->priv; + guint i; + gst_vaapi_decoder_h265_close (decoder); + g_free (priv->dpb); + priv->dpb = NULL; + priv->dpb_size = 0; + for (i = 0; i < G_N_ELEMENTS (priv->pps); i++) + gst_vaapi_parser_info_h265_replace (&priv->pps[i], NULL); + gst_vaapi_parser_info_h265_replace (&priv->active_pps, NULL); + for (i = 0; i < G_N_ELEMENTS (priv->sps); i++) + gst_vaapi_parser_info_h265_replace (&priv->sps[i], NULL); + gst_vaapi_parser_info_h265_replace (&priv->active_sps, NULL); + for (i = 0; i < G_N_ELEMENTS (priv->vps); i++) + gst_vaapi_parser_info_h265_replace (&priv->vps[i], NULL); + gst_vaapi_parser_info_h265_replace (&priv->active_vps, NULL); +} + +static gboolean +gst_vaapi_decoder_h265_create (GstVaapiDecoder * base_decoder) +{ + GstVaapiDecoderH265 *const decoder = + GST_VAAPI_DECODER_H265_CAST (base_decoder); + GstVaapiDecoderH265Private *const priv = &decoder->priv; + priv->profile = GST_VAAPI_PROFILE_UNKNOWN; + priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD; + priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + priv->progressive_sequence = TRUE; + return TRUE; +} + + +static void +fill_profiles (GstVaapiProfile profiles[16], guint * n_profiles_ptr, + GstVaapiProfile profile) +{ + guint n_profiles = *n_profiles_ptr; + profiles[n_profiles++] = profile; + switch (profile) { + case GST_VAAPI_PROFILE_H265_MAIN: + profiles[n_profiles++] = GST_VAAPI_PROFILE_H265_MAIN10; + break; + case GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE: + profiles[n_profiles++] = GST_VAAPI_PROFILE_H265_MAIN; + profiles[n_profiles++] = GST_VAAPI_PROFILE_H265_MAIN10; + break; + default: + break; + } + *n_profiles_ptr = n_profiles; +} + +static GstVaapiProfile +get_profile (GstVaapiDecoderH265 * decoder, GstH265SPS * sps, guint dpb_size) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiDisplay *const display = GST_VAAPI_DECODER_DISPLAY (decoder); + GstVaapiProfile profile, profiles[3]; + guint i, n_profiles = 0; + profile = + gst_vaapi_utils_h265_get_profile (sps->profile_tier_level.profile_idc); + if (!profile) + return GST_VAAPI_PROFILE_UNKNOWN; + fill_profiles (profiles, &n_profiles, profile); + switch (profile) { + case GST_VAAPI_PROFILE_H265_MAIN10: + if (sps->profile_tier_level.profile_compatibility_flag[1]) { // A.2.3.2 (main profile) + fill_profiles (profiles, &n_profiles, GST_VAAPI_PROFILE_H265_MAIN); + } + break; + default: + break; + } + + /* If the preferred profile (profiles[0]) matches one that we already + found, then just return it now instead of searching for it again */ + if (profiles[0] == priv->profile) + return priv->profile; + for (i = 0; i < n_profiles; i++) { + if (gst_vaapi_display_has_decoder (display, profiles[i], priv->entrypoint)) + return profiles[i]; + } + return GST_VAAPI_PROFILE_UNKNOWN; +} + +static GstVaapiDecoderStatus +ensure_context (GstVaapiDecoderH265 * decoder, GstH265SPS * sps) +{ + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER_CAST (decoder); + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiContextInfo info; + GstVaapiProfile profile; + GstVaapiChromaType chroma_type; + gboolean reset_context = FALSE; + guint dpb_size; + + dpb_size = get_max_dec_frame_buffering (sps); + if (priv->dpb_size < dpb_size) { + GST_DEBUG ("DPB size increased"); + reset_context = TRUE; + } + + profile = get_profile (decoder, sps, dpb_size); + if (!profile) { + GST_ERROR ("unsupported profile_idc %u", + sps->profile_tier_level.profile_idc); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + + if (!priv->profile || (priv->profile != profile)) { + GST_DEBUG ("profile changed"); + reset_context = TRUE; + priv->profile = profile; + } + + chroma_type = gst_vaapi_utils_h265_get_chroma_type (sps->chroma_format_idc); + if (!chroma_type) { + GST_ERROR ("unsupported chroma_format_idc %u", sps->chroma_format_idc); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; + } + + if (priv->chroma_type != chroma_type) { + GST_DEBUG ("chroma format changed"); + reset_context = TRUE; + priv->chroma_type = chroma_type; + } + + if (priv->pic_width_in_luma_samples != sps->pic_width_in_luma_samples || + priv->pic_height_in_luma_samples != sps->pic_height_in_luma_samples) { + GST_DEBUG ("size changed"); + reset_context = TRUE; + priv->pic_width_in_luma_samples = sps->pic_width_in_luma_samples; + priv->pic_height_in_luma_samples = sps->pic_height_in_luma_samples; + } + + priv->progressive_sequence = 1; /*Fixme */ + gst_vaapi_decoder_set_interlaced (base_decoder, !priv->progressive_sequence); + gst_vaapi_decoder_set_pixel_aspect_ratio (base_decoder, + sps->vui_params.par_n, sps->vui_params.par_d); + if (!reset_context && priv->has_context) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + /* XXX: fix surface size when cropping is implemented */ + info.profile = priv->profile; + info.entrypoint = priv->entrypoint; + info.chroma_type = priv->chroma_type; + info.width = sps->width; + info.height = sps->height; + info.ref_frames = dpb_size; + + if (!gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + priv->has_context = TRUE; + + /* Reset DPB */ + if (!dpb_reset (decoder, dpb_size)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static void +fill_iq_matrix_4x4 (VAIQMatrixBufferHEVC * iq_matrix, + GstH265ScalingList * scaling_list) +{ + guint i; + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4) == 6); + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4[0]) == 16); + for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList4x4); i++) { + gst_h265_quant_matrix_4x4_get_raster_from_zigzag (iq_matrix->ScalingList4x4 + [i], scaling_list->scaling_lists_4x4[i]); + } +} + +static void +fill_iq_matrix_8x8 (VAIQMatrixBufferHEVC * iq_matrix, + GstH265ScalingList * scaling_list) +{ + guint i; + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8) == 6); + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8[0]) == 64); + for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList8x8); i++) { + gst_h265_quant_matrix_8x8_get_raster_from_zigzag (iq_matrix->ScalingList8x8 + [i], scaling_list->scaling_lists_8x8[i]); + } +} + +static void +fill_iq_matrix_16x16 (VAIQMatrixBufferHEVC * iq_matrix, + GstH265ScalingList * scaling_list) +{ + guint i; + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList16x16) == 6); + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList16x16[0]) == 64); + for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList16x16); i++) { + gst_h265_quant_matrix_16x16_get_raster_from_zigzag + (iq_matrix->ScalingList16x16[i], scaling_list->scaling_lists_16x16[i]); + } +} + +static void +fill_iq_matrix_32x32 (VAIQMatrixBufferHEVC * iq_matrix, + GstH265ScalingList * scaling_list) +{ + guint i; + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList32x32) == 2); + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList32x32[0]) == 64); + for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList32x32); i++) { + gst_h265_quant_matrix_32x32_get_raster_from_zigzag + (iq_matrix->ScalingList32x32[i], scaling_list->scaling_lists_32x32[i]); + } +} + +static void +fill_iq_matrix_dc_16x16 (VAIQMatrixBufferHEVC * iq_matrix, + GstH265ScalingList * scaling_list) +{ + guint i; + for (i = 0; i < 6; i++) + iq_matrix->ScalingListDC16x16[i] = + scaling_list->scaling_list_dc_coef_minus8_16x16[i] + 8; +} + +static void +fill_iq_matrix_dc_32x32 (VAIQMatrixBufferHEVC * iq_matrix, + GstH265ScalingList * scaling_list) +{ + guint i; + for (i = 0; i < 2; i++) + iq_matrix->ScalingListDC32x32[i] = + scaling_list->scaling_list_dc_coef_minus8_32x32[i] + 8; +} + +static GstVaapiDecoderStatus +ensure_quant_matrix (GstVaapiDecoderH265 * decoder, + GstVaapiPictureH265 * picture) +{ + GstVaapiPicture *const base_picture = &picture->base; + GstH265PPS *const pps = get_pps (decoder); + GstH265SPS *const sps = get_sps (decoder); + GstH265ScalingList *scaling_list = NULL; + VAIQMatrixBufferHEVC *iq_matrix; + + if (pps && + (pps->scaling_list_data_present_flag || + (sps->scaling_list_enabled_flag + && !sps->scaling_list_data_present_flag))) + scaling_list = &pps->scaling_list; + else if (sps && sps->scaling_list_enabled_flag + && sps->scaling_list_data_present_flag) + scaling_list = &sps->scaling_list; + else + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW (HEVC, decoder); + if (!base_picture->iq_matrix) { + GST_ERROR ("failed to allocate IQ matrix"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + iq_matrix = base_picture->iq_matrix->param; + + /* Only supporting 4:2:0 */ + if (sps->chroma_format_idc != 1) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; + + fill_iq_matrix_4x4 (iq_matrix, scaling_list); + fill_iq_matrix_8x8 (iq_matrix, scaling_list); + fill_iq_matrix_16x16 (iq_matrix, scaling_list); + fill_iq_matrix_32x32 (iq_matrix, scaling_list); + fill_iq_matrix_dc_16x16 (iq_matrix, scaling_list); + fill_iq_matrix_dc_32x32 (iq_matrix, scaling_list); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static inline gboolean +is_valid_state (guint state, guint ref_state) +{ + return (state & ref_state) == ref_state; +} + +static GstVaapiDecoderStatus +decode_current_picture (GstVaapiDecoderH265 * decoder) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiPictureH265 *const picture = priv->current_picture; + + if (!is_valid_state (priv->decoder_state, GST_H265_VIDEO_STATE_VALID_PICTURE)) { + goto drop_frame; + } + + priv->decoder_state = 0; + /*Fixme: Use SEI header values */ + priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + + if (!picture) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (!gst_vaapi_picture_decode (GST_VAAPI_PICTURE_CAST (picture))) + goto error; + + if (!dpb_add (decoder, picture)) + goto error; + + gst_vaapi_picture_replace (&priv->current_picture, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; + +error: + gst_vaapi_picture_replace (&priv->current_picture, NULL); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; +drop_frame: + priv->decoder_state = 0; + priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + return GST_VAAPI_DECODER_STATUS_DROP_FRAME; +} + +static GstVaapiDecoderStatus +parse_vps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = unit->parsed_info; + GstH265VPS *const vps = &pi->data.vps; + GstH265ParserResult result; + + GST_DEBUG ("parse VPS"); + priv->parser_state = 0; + + memset (vps, 0, sizeof (GstH265VPS)); + + result = gst_h265_parser_parse_vps (priv->parser, &pi->nalu, vps); + if (result != GST_H265_PARSER_OK) + return get_status (result); + + priv->parser_state |= GST_H265_VIDEO_STATE_GOT_VPS; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +parse_sps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = unit->parsed_info; + GstH265SPS *const sps = &pi->data.sps; + GstH265ParserResult result; + + GST_DEBUG ("parse SPS"); + priv->parser_state = 0; + + memset (sps, 0, sizeof (GstH265SPS)); + + result = gst_h265_parser_parse_sps (priv->parser, &pi->nalu, sps, TRUE); + if (result != GST_H265_PARSER_OK) + return get_status (result); + + priv->parser_state |= GST_H265_VIDEO_STATE_GOT_SPS; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + + +static GstVaapiDecoderStatus +parse_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = unit->parsed_info; + GstH265PPS *const pps = &pi->data.pps; + GstH265ParserResult result; + + GST_DEBUG ("parse PPS"); + priv->parser_state &= GST_H265_VIDEO_STATE_GOT_SPS; + + memset (pps, 0, sizeof (GstH265PPS)); + + result = gst_h265_parser_parse_pps (priv->parser, &pi->nalu, pps); + if (result != GST_H265_PARSER_OK) + return get_status (result); + + priv->parser_state |= GST_H265_VIDEO_STATE_GOT_PPS; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +parse_sei (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GST_FIXME ("Parse SEI, Not implemented !"); +#if 0 + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = unit->parsed_info; + GstH265SEIMessage *sei = &pi->data.sei; + GstH265ParserResult result; + GST_DEBUG ("parse SEI"); + result = gst_h265_parser_parse_sei (priv->parser, &pi->nalu, sei); + if (result != GST_H265_PARSER_OK) { + GST_WARNING ("failed to parse SEI messages"); + return get_status (result); + } +#endif + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +parse_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = unit->parsed_info; + GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; + GstH265ParserResult result; + + GST_DEBUG ("parse slice"); + priv->parser_state &= (GST_H265_VIDEO_STATE_GOT_SPS | + GST_H265_VIDEO_STATE_GOT_PPS); + + slice_hdr->short_term_ref_pic_set_idx = 0; + + memset (slice_hdr, 0, sizeof (GstH265SliceHdr)); + + result = gst_h265_parser_parse_slice_hdr (priv->parser, &pi->nalu, slice_hdr); + if (result != GST_H265_PARSER_OK) + return get_status (result); + + priv->parser_state |= GST_H265_VIDEO_STATE_GOT_SLICE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_vps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = unit->parsed_info; + GstH265VPS *const vps = &pi->data.vps; + + GST_DEBUG ("decode VPS"); + + gst_vaapi_parser_info_h265_replace (&priv->vps[vps->id], pi); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = unit->parsed_info; + GstH265SPS *const sps = &pi->data.sps; + + GST_DEBUG ("decode SPS"); + + if (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1]) + priv->SpsMaxLatencyPictures = + sps->max_num_reorder_pics[sps->max_sub_layers_minus1] + + sps->max_latency_increase_plus1[sps->max_sub_layers_minus1] - 1; + + gst_vaapi_parser_info_h265_replace (&priv->sps[sps->id], pi); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = unit->parsed_info; + GstH265PPS *const pps = &pi->data.pps; + + GST_DEBUG ("decode PPS"); + + gst_vaapi_parser_info_h265_replace (&priv->pps[pps->id], pi); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sei (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GST_FIXME ("Decode SEI, Not implemented!"); +#if 0 + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = unit->parsed_info; + GstH265SEIMessage *sei = &pi->data.sei; + guint i; + GST_DEBUG ("decode SEI messages"); + switch (sei->payloadType) { + case GST_H265_SEI_PIC_TIMING:{ + GstH265PicTiming *pic_timing = &sei->payload.pic_timing; + /* Fix: only if vps->frame_field_info_present_flag */ + priv->pic_structure = pic_timing->pic_struct; + break; + } + default: + break; + } +#endif + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence_end (GstVaapiDecoderH265 * decoder) +{ + GstVaapiDecoderStatus status; + GST_DEBUG ("decode sequence-end"); + status = decode_current_picture (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + dpb_flush (decoder); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +/* 8.3.1 - Decoding process for picture order count */ +static void +init_picture_poc (GstVaapiDecoderH265 * decoder, + GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; + GstH265SPS *const sps = get_sps (decoder); + const gint32 MaxPicOrderCntLsb = + 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); + guint8 nal_type = pi->nalu.type; + guint8 temporal_id = pi->nalu.temporal_id_plus1 - 1; + + GST_DEBUG ("decode PicOrderCntVal"); + + priv->prev_poc_lsb = priv->poc_lsb; + priv->prev_poc_msb = priv->poc_msb; + + if (!nal_is_irap (nal_type) && picture->NoRaslOutputFlag) { + priv->prev_poc_lsb = priv->prev_tid0pic_poc_lsb; + priv->prev_poc_msb = priv->prev_tid0pic_poc_msb; + } + + /* Finding PicOrderCntMsb */ + if (nal_is_irap (nal_type) && picture->NoRaslOutputFlag) + priv->poc_msb = 0; + else { + /* (8-1) */ + if ((slice_hdr->pic_order_cnt_lsb < priv->prev_poc_lsb) && + ((priv->prev_poc_lsb - slice_hdr->pic_order_cnt_lsb) >= + (MaxPicOrderCntLsb / 2))) + priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb; + + else if ((slice_hdr->pic_order_cnt_lsb > priv->prev_poc_lsb) && + ((slice_hdr->pic_order_cnt_lsb - priv->prev_poc_lsb) > + (MaxPicOrderCntLsb / 2))) + priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb; + + else + priv->poc_msb = priv->prev_poc_msb; + } + + /* (8-2) */ + priv->poc = picture->poc = priv->poc_msb + slice_hdr->pic_order_cnt_lsb; + priv->poc_lsb = picture->poc_lsb = slice_hdr->pic_order_cnt_lsb; + + if (nal_is_idr (nal_type)) { + picture->poc = 0; + picture->poc_lsb = 0; + priv->poc_lsb = 0; + priv->poc_msb = 0; + priv->prev_poc_lsb = 0; + priv->prev_poc_msb = 0; + priv->prev_tid0pic_poc_lsb = 0; + priv->prev_tid0pic_poc_msb = 0; + } + +done: + picture->base.poc = picture->poc; + GST_DEBUG ("PicOrderCntVal %d", picture->base.poc); + + if (!temporal_id && !nal_is_rasl (nal_type) && + !nal_is_radl (nal_type) && nal_is_ref (nal_type)) { + priv->prev_tid0pic_poc_lsb = slice_hdr->pic_order_cnt_lsb; + priv->prev_tid0pic_poc_msb = priv->poc_msb; + } +} + +static void +init_picture_refs (GstVaapiDecoderH265 * decoder, + GstVaapiPictureH265 * picture, GstH265SliceHdr * slice_hdr) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + guint32 NumRpsCurrTempList0 = 0, NumRpsCurrTempList1 = 0; + GstVaapiPictureH265 *RefPicListTemp0[16] = { NULL, }, *RefPicListTemp1[16] = { + NULL,}; + guint i, rIdx = 0; + guint num_ref_idx_l0_active_minus1 = 0; + guint num_ref_idx_l1_active_minus1 = 0; + GstH265RefPicListModification *ref_pic_list_modification; + guint type; + + memset (priv->RefPicList0, 0, sizeof (GstVaapiPictureH265 *) * 16); + memset (priv->RefPicList1, 0, sizeof (GstVaapiPictureH265 *) * 16); + priv->RefPicList0_count = priv->RefPicList1_count = 0; + + if ((slice_hdr->type != GST_H265_B_SLICE) && + (slice_hdr->type != GST_H265_P_SLICE)) + return; + + if (slice_hdr->dependent_slice_segment_flag) { + GstH265SliceHdr *tmp = &priv->prev_independent_slice_pi->data.slice_hdr; + num_ref_idx_l0_active_minus1 = tmp->num_ref_idx_l0_active_minus1; + num_ref_idx_l1_active_minus1 = tmp->num_ref_idx_l1_active_minus1; + ref_pic_list_modification = &tmp->ref_pic_list_modification; + type = tmp->type; + } else { + num_ref_idx_l0_active_minus1 = slice_hdr->num_ref_idx_l0_active_minus1; + num_ref_idx_l1_active_minus1 = slice_hdr->num_ref_idx_l1_active_minus1; + ref_pic_list_modification = &slice_hdr->ref_pic_list_modification; + type = slice_hdr->type; + } + + NumRpsCurrTempList0 = + MAX ((num_ref_idx_l0_active_minus1 + 1), priv->NumPocTotalCurr); + NumRpsCurrTempList1 = + MAX ((num_ref_idx_l1_active_minus1 + 1), priv->NumPocTotalCurr); + + /* (8-8) */ + while (rIdx < NumRpsCurrTempList0) { + for (i = 0; i < priv->NumPocStCurrBefore && rIdx < NumRpsCurrTempList0; + rIdx++, i++) + RefPicListTemp0[rIdx] = priv->RefPicSetStCurrBefore[i]; + for (i = 0; i < priv->NumPocStCurrAfter && rIdx < NumRpsCurrTempList0; + rIdx++, i++) + RefPicListTemp0[rIdx] = priv->RefPicSetStCurrAfter[i]; + for (i = 0; i < priv->NumPocLtCurr && rIdx < NumRpsCurrTempList0; + rIdx++, i++) + RefPicListTemp0[rIdx] = priv->RefPicSetLtCurr[i]; + } + + /* construct RefPicList0 (8-9) */ + for (rIdx = 0; rIdx <= num_ref_idx_l0_active_minus1; rIdx++) + priv->RefPicList0[rIdx] = + ref_pic_list_modification->ref_pic_list_modification_flag_l0 ? + RefPicListTemp0[ref_pic_list_modification->list_entry_l0[rIdx]] : + RefPicListTemp0[rIdx]; + priv->RefPicList0_count = rIdx; + + if (type == GST_H265_B_SLICE) { + rIdx = 0; + + /* (8-10) */ + while (rIdx < NumRpsCurrTempList1) { + for (i = 0; i < priv->NumPocStCurrAfter && rIdx < NumRpsCurrTempList1; + rIdx++, i++) + RefPicListTemp1[rIdx] = priv->RefPicSetStCurrAfter[i]; + for (i = 0; i < priv->NumPocStCurrBefore && rIdx < NumRpsCurrTempList1; + rIdx++, i++) + RefPicListTemp1[rIdx] = priv->RefPicSetStCurrBefore[i]; + for (i = 0; i < priv->NumPocLtCurr && rIdx < NumRpsCurrTempList1; + rIdx++, i++) + RefPicListTemp1[rIdx] = priv->RefPicSetLtCurr[i]; + } + + /* construct RefPicList1 (8-10) */ + for (rIdx = 0; rIdx <= num_ref_idx_l1_active_minus1; rIdx++) + priv->RefPicList1[rIdx] = + ref_pic_list_modification->ref_pic_list_modification_flag_l1 ? + RefPicListTemp1[ref_pic_list_modification->list_entry_l1 + [rIdx]] : RefPicListTemp1[rIdx]; + priv->RefPicList1_count = rIdx; + } +} + +static gboolean +init_picture (GstVaapiDecoderH265 * decoder, + GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi) +{ + GstVaapiPicture *const base_picture = &picture->base; + GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; + + base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts; + base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE; + + if (nal_is_idr (pi->nalu.type)) { + GST_DEBUG (""); + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_IDR); + } + + if (nal_is_irap (pi->nalu.type)) + picture->IntraPicFlag = TRUE; + + if (pi->nalu.type >= GST_H265_NAL_SLICE_BLA_W_LP && + pi->nalu.type <= GST_H265_NAL_SLICE_CRA_NUT) + picture->RapPicFlag = TRUE; + + /*Fixme: Use SEI header values */ + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + picture->structure = base_picture->structure; + + /*NoRaslOutputFlag ==1 if the current picture is + 1) an IDR picture + 2) a BLA picture + 3) a CRA picture that is the first access unit in the bitstream (Fixme: Not yet added) + 4) first picture that follows an end of sequence NAL unit in decoding order (Fixme: Not yet added) + 5) has HandleCraAsBlaFlag == 1 (Fixme: Not yet added) + */ + if (nal_is_idr (pi->nalu.type) || nal_is_bla (pi->nalu.type) || + pi->nalu.type == GST_H265_NAL_SLICE_CRA_NUT) { + picture->NoRaslOutputFlag = 1; + } + + if (nal_is_rasl (pi-> + nalu.type) /* Fixme: || NoRaslOutPutFlag of asso irap=1 */ ) + picture->output_flag = FALSE; + else + picture->output_flag = slice_hdr->pic_output_flag; + + init_picture_poc (decoder, picture, pi); + + /* C.3.2 */ + if (nal_is_irap (pi->nalu.type) + && picture->NoRaslOutputFlag && picture->poc /*&& Fixme: Not picture0 */ ) { + + if (pi->nalu.type == GST_H265_NAL_SLICE_CRA_NUT) + picture->NoOutputOfPriorPicsFlag = 1; + else + picture->NoOutputOfPriorPicsFlag = + slice_hdr->no_output_of_prior_pics_flag; + } + + return TRUE; +} + +static void +vaapi_init_picture (VAPictureHEVC * pic) +{ + pic->picture_id = VA_INVALID_SURFACE; + pic->pic_order_cnt = 0; + pic->flags = VA_PICTURE_HEVC_INVALID; +} + +static void +vaapi_fill_picture (VAPictureHEVC * pic, GstVaapiPictureH265 * picture, + guint picture_structure) +{ + + if (!picture_structure) + picture_structure = picture->structure; + + pic->picture_id = picture->base.surface_id; + pic->pic_order_cnt = picture->poc; + pic->flags = 0; + + /* Set the VAPictureHEVC flags */ + if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (picture)) + pic->flags |= VA_PICTURE_HEVC_LONG_TERM_REFERENCE; + + if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture, + GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE)) + pic->flags |= VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE; + + else if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture, + GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER)) + pic->flags |= VA_PICTURE_HEVC_RPS_ST_CURR_AFTER; + + else if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture, + GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR)) + pic->flags |= VA_PICTURE_HEVC_RPS_LT_CURR; + + switch (picture_structure) { + case GST_VAAPI_PICTURE_STRUCTURE_FRAME: + break; + case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: + pic->flags |= VA_PICTURE_HEVC_FIELD_PIC; + break; + case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: + pic->flags |= VA_PICTURE_HEVC_FIELD_PIC; + pic->flags |= VA_PICTURE_HEVC_BOTTOM_FIELD; + break; + default: + break; + } +} + +static guint +get_index_for_RefPicListX (VAPictureHEVC * ReferenceFrames, + GstVaapiPictureH265 * pic) +{ + gint i; + + for (i = 0; i < 15; i++) { + if ((ReferenceFrames[i].picture_id != VA_INVALID_ID) && pic) { + if ((ReferenceFrames[i].pic_order_cnt == pic->poc) && + (ReferenceFrames[i].picture_id == pic->base.surface_id)) { + return i; + } + } + } + return 0xff; +} + +static gboolean +fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiPicture *const base_picture = &picture->base; + GstH265PPS *const pps = get_pps (decoder); + GstH265SPS *const sps = get_sps (decoder); + VAPictureParameterBufferHEVC *const pic_param = base_picture->param; + guint i, n; + + pic_param->pic_fields.value = 0; + pic_param->slice_parsing_fields.value = 0; + + /* Fill in VAPictureHEVC */ + vaapi_fill_picture (&pic_param->CurrPic, picture, 0); + /* Fill in ReferenceFrames */ + for (i = 0, n = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + if ((gst_vaapi_frame_store_has_reference (fs))) + vaapi_fill_picture (&pic_param->ReferenceFrames[n++], fs->buffer, + fs->buffer->structure); + if (n >= G_N_ELEMENTS (pic_param->ReferenceFrames)) + break; + } + for (; n < G_N_ELEMENTS (pic_param->ReferenceFrames); n++) + vaapi_init_picture (&pic_param->ReferenceFrames[n]); + + +#define COPY_FIELD(s, f) \ + pic_param->f = (s)->f +#define COPY_BFM(a, s, f) \ + pic_param->a.bits.f = (s)->f + + COPY_FIELD (sps, pic_width_in_luma_samples); + COPY_FIELD (sps, pic_height_in_luma_samples); + COPY_BFM (pic_fields, sps, chroma_format_idc); + COPY_BFM (pic_fields, sps, separate_colour_plane_flag); + COPY_BFM (pic_fields, sps, pcm_enabled_flag); + COPY_BFM (pic_fields, sps, scaling_list_enabled_flag); + COPY_BFM (pic_fields, pps, transform_skip_enabled_flag); + COPY_BFM (pic_fields, sps, amp_enabled_flag); + COPY_BFM (pic_fields, sps, strong_intra_smoothing_enabled_flag); + COPY_BFM (pic_fields, pps, sign_data_hiding_enabled_flag); + COPY_BFM (pic_fields, pps, constrained_intra_pred_flag); + COPY_BFM (pic_fields, pps, cu_qp_delta_enabled_flag); + COPY_BFM (pic_fields, pps, weighted_pred_flag); + COPY_BFM (pic_fields, pps, weighted_bipred_flag); + COPY_BFM (pic_fields, pps, transquant_bypass_enabled_flag); + COPY_BFM (pic_fields, pps, tiles_enabled_flag); + COPY_BFM (pic_fields, pps, entropy_coding_sync_enabled_flag); + pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag = + pps->loop_filter_across_slices_enabled_flag; + COPY_BFM (pic_fields, pps, loop_filter_across_tiles_enabled_flag); + COPY_BFM (pic_fields, sps, pcm_loop_filter_disabled_flag); + /* Fix: Assign value based on sps_max_num_reorder_pics */ + pic_param->pic_fields.bits.NoPicReorderingFlag = 0; + /* Fix: Enable if picture has no B slices */ + pic_param->pic_fields.bits.NoBiPredFlag = 0; + + pic_param->sps_max_dec_pic_buffering_minus1 = + sps->max_dec_pic_buffering_minus1[0]; + COPY_FIELD (sps, bit_depth_luma_minus8); + COPY_FIELD (sps, bit_depth_chroma_minus8); + COPY_FIELD (sps, pcm_sample_bit_depth_luma_minus1); + COPY_FIELD (sps, pcm_sample_bit_depth_chroma_minus1); + COPY_FIELD (sps, log2_min_luma_coding_block_size_minus3); + COPY_FIELD (sps, log2_diff_max_min_luma_coding_block_size); + COPY_FIELD (sps, log2_min_transform_block_size_minus2); + COPY_FIELD (sps, log2_diff_max_min_transform_block_size); + COPY_FIELD (sps, log2_min_pcm_luma_coding_block_size_minus3); + COPY_FIELD (sps, log2_diff_max_min_pcm_luma_coding_block_size); + COPY_FIELD (sps, max_transform_hierarchy_depth_intra); + COPY_FIELD (sps, max_transform_hierarchy_depth_inter); + COPY_FIELD (pps, init_qp_minus26); + COPY_FIELD (pps, diff_cu_qp_delta_depth); + pic_param->pps_cb_qp_offset = pps->cb_qp_offset; + pic_param->pps_cr_qp_offset = pps->cr_qp_offset; + COPY_FIELD (pps, log2_parallel_merge_level_minus2); + COPY_FIELD (pps, num_tile_columns_minus1); + COPY_FIELD (pps, num_tile_rows_minus1); + for (i = 0; i < 19; i++) + pic_param->column_width_minus1[i] = pps->column_width_minus1[i]; + for (i = 0; i < 21; i++) + pic_param->row_height_minus1[i] = pps->row_height_minus1[i]; + + COPY_BFM (slice_parsing_fields, pps, lists_modification_present_flag); + COPY_BFM (slice_parsing_fields, sps, long_term_ref_pics_present_flag); + pic_param->slice_parsing_fields.bits.sps_temporal_mvp_enabled_flag = + sps->temporal_mvp_enabled_flag; + COPY_BFM (slice_parsing_fields, pps, cabac_init_present_flag); + COPY_BFM (slice_parsing_fields, pps, output_flag_present_flag); + COPY_BFM (slice_parsing_fields, pps, dependent_slice_segments_enabled_flag); + pic_param->slice_parsing_fields. + bits.pps_slice_chroma_qp_offsets_present_flag = + pps->slice_chroma_qp_offsets_present_flag; + COPY_BFM (slice_parsing_fields, sps, sample_adaptive_offset_enabled_flag); + COPY_BFM (slice_parsing_fields, pps, deblocking_filter_override_enabled_flag); + pic_param->slice_parsing_fields.bits.pps_disable_deblocking_filter_flag = + pps->deblocking_filter_disabled_flag; + COPY_BFM (slice_parsing_fields, pps, + slice_segment_header_extension_present_flag); + pic_param->slice_parsing_fields.bits.RapPicFlag = picture->RapPicFlag; + pic_param->slice_parsing_fields.bits.IdrPicFlag = + GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_IDR); + pic_param->slice_parsing_fields.bits.IntraPicFlag = picture->IntraPicFlag; + + COPY_FIELD (sps, log2_max_pic_order_cnt_lsb_minus4); + COPY_FIELD (sps, num_short_term_ref_pic_sets); + pic_param->num_long_term_ref_pic_sps = sps->num_long_term_ref_pics_sps; + COPY_FIELD (pps, num_ref_idx_l0_default_active_minus1); + COPY_FIELD (pps, num_ref_idx_l1_default_active_minus1); + pic_param->pps_beta_offset_div2 = pps->beta_offset_div2; + pic_param->pps_tc_offset_div2 = pps->tc_offset_div2; + COPY_FIELD (pps, num_extra_slice_header_bits); + + /*Fixme: Set correct value as mentioned in va_dec_hevc.h */ + pic_param->st_rps_bits = 0; + return TRUE; +} + +/* Detection of the first VCL NAL unit of a coded picture (7.4.2.4.5 ) */ +static gboolean +is_new_picture (GstVaapiParserInfoH265 * pi, GstVaapiParserInfoH265 * prev_pi) +{ + GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; + + if (!prev_pi) + return TRUE; + + if (slice_hdr->first_slice_segment_in_pic_flag) + return TRUE; + + return FALSE; +} + +/* Detection of a new access unit, assuming we are already in presence + of a new picture */ +static inline gboolean +is_new_access_unit (GstVaapiParserInfoH265 * pi, + GstVaapiParserInfoH265 * prev_pi) +{ + if (!prev_pi) + return TRUE; +} + +static gboolean +has_entry_in_rps (GstVaapiPictureH265 * dpb_pic, + GstVaapiPictureH265 ** rps_list, guint rps_list_length) +{ + guint i; + + if (!dpb_pic || !rps_list || !rps_list_length) + return FALSE; + + for (i = 0; i < rps_list_length; i++) { + if (rps_list[i]->poc == dpb_pic->poc) + return TRUE; + } + return FALSE; +} + +/* the derivation process for the RPS and the picture marking */ +static void +derive_and_mark_rps (GstVaapiDecoderH265 * decoder, + GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi, + gint32 * CurrDeltaPocMsbPresentFlag, gint32 * FollDeltaPocMsbPresentFlag) +{ + guint i; + GstVaapiPictureH265 *dpb_pic = NULL; + GstVaapiDecoderH265Private *const priv = &decoder->priv; + + memset (priv->RefPicSetLtCurr, 0, sizeof (GstVaapiPictureH265 *) * 16); + memset (priv->RefPicSetLtFoll, 0, sizeof (GstVaapiPictureH265 *) * 16); + memset (priv->RefPicSetStCurrBefore, 0, sizeof (GstVaapiPictureH265 *) * 16); + memset (priv->RefPicSetStCurrAfter, 0, sizeof (GstVaapiPictureH265 *) * 16); + memset (priv->RefPicSetStFoll, 0, sizeof (GstVaapiPictureH265 *) * 16); + + /* (8-6) */ + for (i = 0; i < priv->NumPocLtCurr; i++) { + if (!CurrDeltaPocMsbPresentFlag[i]) { + dpb_pic = dpb_get_picture (decoder, priv->PocLtCurr[i], TRUE); + if (dpb_pic) + priv->RefPicSetLtCurr[i] = dpb_pic; + else + priv->RefPicSetLtCurr[i] = NULL; + } else { + dpb_pic = dpb_get_picture (decoder, priv->PocLtCurr[i], FALSE); + if (dpb_pic) + priv->RefPicSetLtCurr[i] = dpb_pic; + else + priv->RefPicSetLtCurr[i] = NULL; + } + } + for (; i < 16; i++) + priv->RefPicSetLtCurr[i] = NULL; + + for (i = 0; i < priv->NumPocLtFoll; i++) { + if (!FollDeltaPocMsbPresentFlag[i]) { + dpb_pic = dpb_get_picture (decoder, priv->PocLtFoll[i], TRUE); + if (dpb_pic) + priv->RefPicSetLtFoll[i] = dpb_pic; + else + priv->RefPicSetLtFoll[i] = NULL; + } else { + dpb_pic = dpb_get_picture (decoder, priv->PocLtFoll[i], FALSE); + if (dpb_pic) + priv->RefPicSetLtFoll[i] = dpb_pic; + else + priv->RefPicSetLtFoll[i] = NULL; + } + } + for (; i < 16; i++) + priv->RefPicSetLtFoll[i] = NULL; + + /* Mark all ref pics in RefPicSetLtCurr and RefPicSetLtFol as long_term_refs */ + for (i = 0; i < priv->NumPocLtCurr; i++) { + if (priv->RefPicSetLtCurr[i]) + gst_vaapi_picture_h265_set_reference (priv->RefPicSetLtCurr[i], + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE | + GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR); + } + for (i = 0; i < priv->NumPocLtFoll; i++) { + if (priv->RefPicSetLtFoll[i]) + gst_vaapi_picture_h265_set_reference (priv->RefPicSetLtFoll[i], + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE | + GST_VAAPI_PICTURE_FLAG_RPS_LT_FOLL); + } + + /* (8-7) */ + for (i = 0; i < priv->NumPocStCurrBefore; i++) { + dpb_pic = dpb_get_ref_picture (decoder, priv->PocStCurrBefore[i], TRUE); + if (dpb_pic) { + gst_vaapi_picture_h265_set_reference (dpb_pic, + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE | + GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE); + priv->RefPicSetStCurrBefore[i] = dpb_pic; + } else + priv->RefPicSetStCurrBefore[i] = NULL; + } + for (; i < 16; i++) + priv->RefPicSetStCurrBefore[i] = NULL; + + for (i = 0; i < priv->NumPocStCurrAfter; i++) { + dpb_pic = dpb_get_ref_picture (decoder, priv->PocStCurrAfter[i], TRUE); + if (dpb_pic) { + gst_vaapi_picture_h265_set_reference (dpb_pic, + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE | + GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER); + priv->RefPicSetStCurrAfter[i] = dpb_pic; + } else + priv->RefPicSetStCurrAfter[i] = NULL; + } + for (; i < 16; i++) + priv->RefPicSetStCurrAfter[i] = NULL; + + for (i = 0; i < priv->NumPocStFoll; i++) { + dpb_pic = dpb_get_ref_picture (decoder, priv->PocStFoll[i], TRUE); + if (dpb_pic) { + gst_vaapi_picture_h265_set_reference (dpb_pic, + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE | + GST_VAAPI_PICTURE_FLAG_RPS_ST_FOLL); + priv->RefPicSetStFoll[i] = dpb_pic; + } else + priv->RefPicSetStFoll[i] = NULL; + } + for (; i < 16; i++) + priv->RefPicSetStFoll[i] = NULL; + + /* Mark all dpb pics not beloging to RefPicSet*[] as unused for ref */ + for (i = 0; i < priv->dpb_count; i++) { + dpb_pic = priv->dpb[i]->buffer; + if (dpb_pic && + !has_entry_in_rps (dpb_pic, priv->RefPicSetLtCurr, priv->NumPocLtCurr) + && !has_entry_in_rps (dpb_pic, priv->RefPicSetLtFoll, + priv->NumPocLtFoll) + && !has_entry_in_rps (dpb_pic, priv->RefPicSetStCurrAfter, + priv->NumPocStCurrAfter) + && !has_entry_in_rps (dpb_pic, priv->RefPicSetStCurrBefore, + priv->NumPocStCurrBefore) + && !has_entry_in_rps (dpb_pic, priv->RefPicSetStFoll, + priv->NumPocStFoll)) + gst_vaapi_picture_h265_set_reference (dpb_pic, 0); + } +} + +/* Decoding process for reference picture set (8.3.2) */ +static gboolean +decode_ref_pic_set (GstVaapiDecoderH265 * decoder, + GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi) +{ + guint i, j, k; + gint32 CurrDeltaPocMsbPresentFlag[16] = { 0, }; + gint32 FollDeltaPocMsbPresentFlag[16] = { 0, }; + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; + GstH265SPS *const sps = get_sps (decoder); + const gint32 MaxPicOrderCntLsb = + 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); + + /* if it is an irap pic, set all ref pics in dpb as unused for ref */ + if (nal_is_irap (pi->nalu.type) && picture->NoRaslOutputFlag) { + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + gst_vaapi_picture_h265_set_reference (fs->buffer, 0); + } + } + + /* Reset everything for IDR */ + if (nal_is_idr (pi->nalu.type)) { + memset (priv->PocStCurrBefore, 0, sizeof (guint) * 16); + memset (priv->PocStCurrAfter, 0, sizeof (guint) * 16); + memset (priv->PocStFoll, 0, sizeof (guint) * 16); + memset (priv->PocLtCurr, 0, sizeof (guint) * 16); + memset (priv->PocLtFoll, 0, sizeof (guint) * 16); + priv->NumPocStCurrBefore = priv->NumPocStCurrAfter = priv->NumPocStFoll = 0; + priv->NumPocLtCurr = priv->NumPocLtFoll = 0; + } else { + GstH265ShortTermRefPicSet *stRefPic; + gint32 num_lt_pics, pocLt, PocLsbLt[16] = { 0, } + , UsedByCurrPicLt[16] = { + 0,}; + gint32 DeltaPocMsbCycleLt[16] = { 0, }; + gint numtotalcurr = 0; + + /* this is based on CurrRpsIdx described in spec */ + if (!slice_hdr->short_term_ref_pic_set_sps_flag) + stRefPic = &slice_hdr->short_term_ref_pic_sets; + else if (sps->num_short_term_ref_pic_sets) + stRefPic = + &sps->short_term_ref_pic_set[slice_hdr->short_term_ref_pic_set_idx]; + + + for (i = 0, j = 0, k = 0; i < stRefPic->NumNegativePics; i++) { + if (stRefPic->UsedByCurrPicS0[i]) { + priv->PocStCurrBefore[j++] = picture->poc + stRefPic->DeltaPocS0[i]; + numtotalcurr++; + } else + priv->PocStFoll[k++] = picture->poc + stRefPic->DeltaPocS0[i]; + } + priv->NumPocStCurrBefore = j; + for (i = 0, j = 0; i < stRefPic->NumPositivePics; i++) { + if (stRefPic->UsedByCurrPicS1[i]) { + priv->PocStCurrAfter[j++] = picture->poc + stRefPic->DeltaPocS1[i]; + numtotalcurr++; + } else + priv->PocStFoll[k++] = picture->poc + stRefPic->DeltaPocS1[i]; + } + priv->NumPocStCurrAfter = j; + priv->NumPocStFoll = k; + num_lt_pics = slice_hdr->num_long_term_sps + slice_hdr->num_long_term_pics; + /* The variables PocLsbLt[i] and UsedByCurrPicLt[i] are derived as follows: */ + for (i = 0; i < num_lt_pics; i++) { + if (i < slice_hdr->num_long_term_sps) { + PocLsbLt[i] = sps->lt_ref_pic_poc_lsb_sps[slice_hdr->lt_idx_sps[i]]; + UsedByCurrPicLt[i] = + sps->used_by_curr_pic_lt_sps_flag[slice_hdr->lt_idx_sps[i]]; + } else { + PocLsbLt[i] = slice_hdr->poc_lsb_lt[i]; + UsedByCurrPicLt[i] = slice_hdr->used_by_curr_pic_lt_flag[i]; + } + if (UsedByCurrPicLt[i]) + numtotalcurr++; + } + + priv->NumPocTotalCurr = numtotalcurr; + + /* The variable DeltaPocMsbCycleLt[i] is derived as follows: (7-38) */ + for (i = 0; i < num_lt_pics; i++) { + if (i == 0 || i == slice_hdr->num_long_term_sps) + DeltaPocMsbCycleLt[i] = slice_hdr->delta_poc_msb_cycle_lt[i]; + else + DeltaPocMsbCycleLt[i] = + slice_hdr->delta_poc_msb_cycle_lt[i] + DeltaPocMsbCycleLt[i - 1]; + } + + /* (8-5) */ + for (i = 0, j = 0, k = 0; i < num_lt_pics; i++) { + pocLt = PocLsbLt[i]; + if (slice_hdr->delta_poc_msb_present_flag[i]) + pocLt += + picture->poc - DeltaPocMsbCycleLt[i] * MaxPicOrderCntLsb - + slice_hdr->pic_order_cnt_lsb; + if (UsedByCurrPicLt[i]) { + priv->PocLtCurr[j] = pocLt; + CurrDeltaPocMsbPresentFlag[j++] = + slice_hdr->delta_poc_msb_present_flag[i]; + } else { + priv->PocLtFoll[k] = pocLt; + FollDeltaPocMsbPresentFlag[k++] = + slice_hdr->delta_poc_msb_present_flag[i]; + } + } + priv->NumPocLtCurr = j; + priv->NumPocLtFoll = k; + + } + + /* the derivation process for the RPS and the picture marking */ + derive_and_mark_rps (decoder, picture, pi, CurrDeltaPocMsbPresentFlag, + FollDeltaPocMsbPresentFlag); + + return TRUE; +} + +static GstVaapiDecoderStatus +decode_picture (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *pi = unit->parsed_info; + GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; + GstH265PPS *const pps = ensure_pps (decoder, slice_hdr->pps); + GstH265SPS *const sps = ensure_sps (decoder, slice_hdr->pps->sps); + GstVaapiPictureH265 *picture; + GstVaapiDecoderStatus status; + + g_return_val_if_fail (pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); + g_return_val_if_fail (sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); + + status = ensure_context (decoder, sps); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + priv->decoder_state = 0; + + /* Create new picture */ + picture = gst_vaapi_picture_h265_new (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); + + /* Update cropping rectangle */ + /* Fixme: Add cropping rectangle, fix needed in codecparser */ + + status = ensure_quant_matrix (decoder, picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_ERROR ("failed to reset quantizer matrix"); + return status; + } + + if (!init_picture (decoder, picture, pi)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + if (!decode_ref_pic_set (decoder, picture, pi)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + /* Fixme: if pic is BLA or CRA,and have NoRaslOutputFlag == 1, + invoke 8.3.3 as described in specification for generating + unavailable reference pictures */ + + if (!dpb_init (decoder, picture, pi)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + if (!fill_picture (decoder, picture)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + priv->decoder_state = pi->state; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static inline guint +get_slice_data_byte_offset (GstH265SliceHdr * slice_hdr, guint nal_header_bytes) +{ + guint epb_count; + epb_count = slice_hdr->n_emulation_prevention_bytes; + return nal_header_bytes + (slice_hdr->header_size + 7) / 8 - epb_count; +} + +static gint +clip3 (gint x, gint y, gint z) +{ + if (z < x) + return x; + if (z > y) + return y; + return z; +} + +static gboolean +fill_pred_weight_table (GstVaapiDecoderH265 * decoder, + GstVaapiSlice * slice, GstH265SliceHdr * slice_hdr) +{ + VASliceParameterBufferHEVC *const slice_param = slice->param; + GstH265PPS *const pps = get_pps (decoder); + GstH265SPS *const sps = get_sps (decoder); + GstH265PredWeightTable *const w = &slice_hdr->pred_weight_table; + gint chroma_weight, chroma_log2_weight_denom; + gint i, j; + + slice_param->luma_log2_weight_denom = 0; + slice_param->delta_chroma_log2_weight_denom = 0; + + if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice_hdr)) || + (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice_hdr))) { + + slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom; + if (!sps->chroma_format_idc) + slice_param->delta_chroma_log2_weight_denom = + w->delta_chroma_log2_weight_denom; + + chroma_log2_weight_denom = + slice_param->luma_log2_weight_denom + + slice_param->delta_chroma_log2_weight_denom; + + for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { + if (slice_hdr->pred_weight_table.luma_weight_l0_flag[i]) { + slice_param->delta_luma_weight_l0[i] = w->delta_luma_weight_l0[i]; + slice_param->luma_offset_l0[i] = w->luma_offset_l0[i]; + } + if (slice_hdr->pred_weight_table.chroma_weight_l0_flag[i]) { + for (j = 0; j < 2; j++) { + slice_param->delta_chroma_weight_l0[i][j] = + w->delta_chroma_weight_l0[i][j]; + /* Find ChromaWeightL0 */ + chroma_weight = + (1 << chroma_log2_weight_denom) + w->delta_chroma_weight_l0[i][j]; + /* 7-44 */ + slice_param->ChromaOffsetL0[i][j] = clip3 (-128, 127, + (w->delta_chroma_offset_l0[i][j] - + ((128 * chroma_weight) >> chroma_log2_weight_denom))); + } + } + } + + if (GST_H265_IS_B_SLICE (slice_hdr)) { + for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { + if (slice_hdr->pred_weight_table.luma_weight_l1_flag[i]) { + slice_param->delta_luma_weight_l1[i] = w->delta_luma_weight_l1[i]; + slice_param->luma_offset_l1[i] = w->luma_offset_l1[i]; + } + if (slice_hdr->pred_weight_table.chroma_weight_l1_flag[i]) { + for (j = 0; j < 2; j++) { + slice_param->delta_chroma_weight_l1[i][j] = + w->delta_chroma_weight_l1[i][j]; + /* Find ChromaWeightL1 */ + chroma_weight = + (1 << chroma_log2_weight_denom) + + w->delta_chroma_weight_l1[i][j]; + slice_param->ChromaOffsetL1[i][j] = + clip3 (-128, 127, + (w->delta_chroma_offset_l1[i][j] - + ((128 * chroma_weight) >> chroma_log2_weight_denom))); + } + } + } + } + } + /* Fixme: Optimize */ + else { + for (i = 0; i < 15; i++) { + slice_param->delta_luma_weight_l0[i] = 0; + slice_param->luma_offset_l0[i] = 0; + slice_param->delta_luma_weight_l1[i] = 0; + slice_param->luma_offset_l1[i] = 0; + } + for (i = 0; i < 15; i++) { + for (j = 0; j < 2; j++) { + slice_param->delta_chroma_weight_l0[i][j] = 0; + slice_param->ChromaOffsetL0[i][j] = 0; + slice_param->delta_chroma_weight_l1[i][j] = 0; + slice_param->ChromaOffsetL1[i][j] = 0; + } + } + } + return TRUE; +} + +static gboolean +fill_RefPicList (GstVaapiDecoderH265 * decoder, + GstVaapiPictureH265 * picture, GstVaapiSlice * slice, + GstH265SliceHdr * slice_hdr) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + VASliceParameterBufferHEVC *const slice_param = slice->param; + GstVaapiPicture *const base_picture = &picture->base; + VAPictureParameterBufferHEVC *const pic_param = base_picture->param; + guint i, num_ref_lists = 0, j; + + slice_param->num_ref_idx_l0_active_minus1 = 0; + slice_param->num_ref_idx_l1_active_minus1 = 0; + for (j = 0; j < 2; j++) + for (i = 0; i < 15; i++) + slice_param->RefPicList[j][i] = 0xFF; + + if (GST_H265_IS_B_SLICE (slice_hdr)) + num_ref_lists = 2; + else if (GST_H265_IS_I_SLICE (slice_hdr)) + num_ref_lists = 0; + else + num_ref_lists = 1; + + if (num_ref_lists < 1) + return TRUE; + + slice_param->num_ref_idx_l0_active_minus1 = + slice_hdr->num_ref_idx_l0_active_minus1; + slice_param->num_ref_idx_l1_active_minus1 = + slice_hdr->num_ref_idx_l1_active_minus1; + + for (i = 0; i < priv->RefPicList0_count; i++) + slice_param->RefPicList[0][i] = + get_index_for_RefPicListX (pic_param->ReferenceFrames, + priv->RefPicList0[i]); + for (; i < 15; i++) + slice_param->RefPicList[0][i] = 0xFF; + + if (num_ref_lists < 2) + return TRUE; + + for (i = 0; i < priv->RefPicList1_count; i++) + slice_param->RefPicList[1][i] = + get_index_for_RefPicListX (pic_param->ReferenceFrames, + priv->RefPicList1[i]); + for (; i < 15; i++) + slice_param->RefPicList[1][i] = 0xFF; + + return TRUE; +} + +static gboolean +fill_slice (GstVaapiDecoderH265 * decoder, + GstVaapiPictureH265 * picture, GstVaapiSlice * slice, + GstVaapiParserInfoH265 * pi, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + VASliceParameterBufferHEVC *const slice_param = slice->param; + GstH265SliceHdr *slice_hdr = &pi->data.slice_hdr; + + /* Fill in VASliceParameterBufferH265 */ + slice_param->LongSliceFlags.value = 0; + slice_param->slice_data_byte_offset = + get_slice_data_byte_offset (slice_hdr, pi->nalu.header_bytes); + + slice_param->slice_segment_address = slice_hdr->segment_address; + +#define COPY_LFF(f) \ + slice_param->LongSliceFlags.fields.f = (slice_hdr)->f + + if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_END)) + slice_param->LongSliceFlags.fields.LastSliceOfPic = 1; + else + slice_param->LongSliceFlags.fields.LastSliceOfPic = 0; + + COPY_LFF (dependent_slice_segment_flag); + + /* use most recent independent slice segment header syntax elements + * for filling the missing fields in dependent slice segment header */ + if (slice_hdr->dependent_slice_segment_flag) + slice_hdr = &priv->prev_independent_slice_pi->data.slice_hdr; + + COPY_LFF (mvd_l1_zero_flag); + COPY_LFF (cabac_init_flag); + COPY_LFF (collocated_from_l0_flag); + slice_param->LongSliceFlags.fields.color_plane_id = + slice_hdr->colour_plane_id; + slice_param->LongSliceFlags.fields.slice_type = slice_hdr->type; + slice_param->LongSliceFlags.fields.slice_sao_luma_flag = + slice_hdr->sao_luma_flag; + slice_param->LongSliceFlags.fields.slice_sao_chroma_flag = + slice_hdr->sao_chroma_flag; + slice_param->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag = + slice_hdr->temporal_mvp_enabled_flag; + slice_param->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag = + slice_hdr->deblocking_filter_disabled_flag; + slice_param->LongSliceFlags. + fields.slice_loop_filter_across_slices_enabled_flag = + slice_hdr->loop_filter_across_slices_enabled_flag; + + if (!slice_hdr->temporal_mvp_enabled_flag) + slice_param->collocated_ref_idx = 0xFF; + else + slice_param->collocated_ref_idx = slice_hdr->collocated_ref_idx; + + slice_param->num_ref_idx_l0_active_minus1 = + slice_hdr->num_ref_idx_l0_active_minus1; + slice_param->num_ref_idx_l1_active_minus1 = + slice_hdr->num_ref_idx_l1_active_minus1; + slice_param->slice_qp_delta = slice_hdr->qp_delta; + slice_param->slice_cb_qp_offset = slice_hdr->cb_qp_offset; + slice_param->slice_cr_qp_offset = slice_hdr->cr_qp_offset; + slice_param->slice_beta_offset_div2 = slice_hdr->beta_offset_div2; + slice_param->slice_tc_offset_div2 = slice_hdr->tc_offset_div2; + slice_param->five_minus_max_num_merge_cand = + slice_hdr->five_minus_max_num_merge_cand; + + if (!fill_RefPicList (decoder, picture, slice, slice_hdr)) + return FALSE; + + if (!fill_pred_weight_table (decoder, slice, slice_hdr)) + return FALSE; + + return TRUE; +} + +static GstVaapiDecoderStatus +decode_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = unit->parsed_info; + GstVaapiPictureH265 *const picture = priv->current_picture; + GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; + GstVaapiSlice *slice; + GstBuffer *const buffer = + GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer; + GstMapInfo map_info; + + GST_DEBUG ("slice (%u bytes)", pi->nalu.size); + if (!is_valid_state (pi->state, GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS)) { + GST_WARNING ("failed to receive enough headers to decode slice"); + return GST_VAAPI_DECODER_STATUS_SUCCESS; + } + + if (!ensure_pps (decoder, slice_hdr->pps)) { + GST_ERROR ("failed to activate PPS"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!ensure_sps (decoder, slice_hdr->pps->sps)) { + GST_ERROR ("failed to activate SPS"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) { + GST_ERROR ("failed to map buffer"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + /* Check wether this is the first/last slice in the current access unit */ + if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_START) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_START); + + if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_END); + + slice = GST_VAAPI_SLICE_NEW (HEVC, decoder, + (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size); + + gst_buffer_unmap (buffer, &map_info); + if (!slice) { + GST_ERROR ("failed to allocate slice"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + init_picture_refs (decoder, picture, slice_hdr); + + if (!fill_slice (decoder, picture, slice, pi, unit)) { + 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); + picture->last_slice_hdr = slice_hdr; + priv->decoder_state |= GST_H265_VIDEO_STATE_GOT_SLICE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static inline gint +scan_for_start_code (GstAdapter * adapter, guint ofs, guint size, guint32 * scp) +{ + return (gint) gst_adapter_masked_scan_uint32_peek (adapter, + 0xffffff00, 0x00000100, ofs, size, scp); +} + +static GstVaapiDecoderStatus +decode_unit (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const pi = unit->parsed_info; + GstVaapiDecoderStatus status; + priv->decoder_state |= pi->state; + switch (pi->nalu.type) { + case GST_H265_NAL_VPS: + status = decode_vps (decoder, unit); + break; + case GST_H265_NAL_SPS: + status = decode_sps (decoder, unit); + break; + case GST_H265_NAL_PPS: + status = decode_pps (decoder, unit); + break; + case GST_H265_NAL_SLICE_TRAIL_N: + case GST_H265_NAL_SLICE_TRAIL_R: + case GST_H265_NAL_SLICE_TSA_N: + case GST_H265_NAL_SLICE_TSA_R: + case GST_H265_NAL_SLICE_STSA_N: + case GST_H265_NAL_SLICE_STSA_R: + case GST_H265_NAL_SLICE_RADL_N: + case GST_H265_NAL_SLICE_RADL_R: + case GST_H265_NAL_SLICE_RASL_N: + case GST_H265_NAL_SLICE_RASL_R: + case GST_H265_NAL_SLICE_BLA_W_LP: + case GST_H265_NAL_SLICE_BLA_W_RADL: + case GST_H265_NAL_SLICE_BLA_N_LP: + case GST_H265_NAL_SLICE_IDR_W_RADL: + case GST_H265_NAL_SLICE_IDR_N_LP: + case GST_H265_NAL_SLICE_CRA_NUT: + status = decode_slice (decoder, unit); + break; + case GST_H265_NAL_EOS: + case GST_H265_NAL_EOB: + status = decode_sequence_end (decoder); + break; + case GST_H265_NAL_SUFFIX_SEI: + case GST_H265_NAL_PREFIX_SEI: + status = decode_sei (decoder, unit); + break; + default: + GST_WARNING ("unsupported NAL unit type %d", pi->nalu.type); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + return status; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_h265_decode_codec_data (GstVaapiDecoder * + base_decoder, const guchar * buf, guint buf_size) +{ + GstVaapiDecoderH265 *const decoder = + GST_VAAPI_DECODER_H265_CAST (base_decoder); + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; + GstVaapiDecoderUnit unit; + GstVaapiParserInfoH265 *pi = NULL; + GstH265ParserResult result; + guint num_nal_arrays, num_nals; + guint i, j, ofs; + unit.parsed_info = NULL; + if (buf_size < 23) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + if (buf[0] != 1) { + GST_ERROR ("failed to decode codec-data, not in hvcC format"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + priv->nal_length_size = (buf[21] & 0x03) + 1; + GST_DEBUG ("nal length size %u", priv->nal_length_size); + num_nal_arrays = buf[22]; + ofs = 23; + for (i = 0; i < num_nal_arrays; i++) { + num_nals = GST_READ_UINT16_BE (buf + ofs + 1); + for (j = 0; j < num_nals; j++) { + pi = gst_vaapi_parser_info_h265_new (); + if (!pi) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + unit.parsed_info = pi; + result = gst_h265_parser_identify_nalu_hevc (priv->parser, + buf, ofs + 3, buf_size, 2, &pi->nalu); + if (result != GST_H265_PARSER_OK) { + status = get_status (result); + goto cleanup; + } + + switch (pi->nalu.type) { + case GST_H265_NAL_VPS: + status = parse_vps (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + status = decode_vps (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + break; + case GST_H265_NAL_SPS: + status = parse_sps (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + status = decode_sps (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + break; + case GST_H265_NAL_PPS: + status = parse_pps (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + status = decode_pps (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + break; + } + gst_vaapi_parser_info_h265_replace (&pi, NULL); + } + } + + priv->is_hvcC = TRUE; + status = GST_VAAPI_DECODER_STATUS_SUCCESS; +cleanup: + gst_vaapi_parser_info_h265_replace (&pi, NULL); + return status; +} + +static GstVaapiDecoderStatus +ensure_decoder (GstVaapiDecoderH265 * decoder) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; + if (!priv->is_opened) { + priv->is_opened = gst_vaapi_decoder_h265_open (decoder); + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + status = + gst_vaapi_decoder_decode_codec_data (GST_VAAPI_DECODER_CAST (decoder)); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder, + GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265 *const decoder = + GST_VAAPI_DECODER_H265_CAST (base_decoder); + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserState *const ps = GST_VAAPI_PARSER_STATE (base_decoder); + GstVaapiParserInfoH265 *pi; + GstVaapiDecoderStatus status; + GstH265ParserResult result; + guchar *buf; + guint i, size, buf_size, nalu_size, flags; + guint32 start_code; + gint ofs, ofs2; + gboolean at_au_end = FALSE; + status = ensure_decoder (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + switch (priv->stream_alignment) { + case GST_VAAPI_STREAM_ALIGN_H265_NALU: + case GST_VAAPI_STREAM_ALIGN_H265_AU: + size = gst_adapter_available_fast (adapter); + break; + default: + size = gst_adapter_available (adapter); + break; + } + + if (priv->is_hvcC) { + if (size < priv->nal_length_size) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + buf = (guchar *) & start_code; + g_assert (priv->nal_length_size <= sizeof (start_code)); + gst_adapter_copy (adapter, buf, 0, priv->nal_length_size); + nalu_size = 0; + for (i = 0; i < priv->nal_length_size; i++) + nalu_size = (nalu_size << 8) | buf[i]; + buf_size = priv->nal_length_size + nalu_size; + if (size < buf_size) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + else if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H265_AU) + at_au_end = (buf_size == size); + } else { + if (size < 4) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H265_NALU) + buf_size = size; + else { + ofs = scan_for_start_code (adapter, 0, size, NULL); + if (ofs < 0) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + if (ofs > 0) { + gst_adapter_flush (adapter, ofs); + size -= ofs; + } + + ofs2 = ps->input_offset2 - ofs - 4; + if (ofs2 < 4) + ofs2 = 4; + ofs = G_UNLIKELY (size < ofs2 + 4) ? -1 : + scan_for_start_code (adapter, ofs2, size - ofs2, NULL); + if (ofs < 0) { + // Assume the whole NAL unit is present if end-of-stream + // or stream buffers aligned on access unit boundaries + if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H265_AU) + at_au_end = TRUE; + else if (!at_eos) { + ps->input_offset2 = size; + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } + ofs = size; + } + buf_size = ofs; + } + } + ps->input_offset2 = 0; + buf = (guchar *) gst_adapter_map (adapter, buf_size); + if (!buf) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + unit->size = buf_size; + pi = gst_vaapi_parser_info_h265_new (); + if (!pi) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + gst_vaapi_decoder_unit_set_parsed_info (unit, + pi, (GDestroyNotify) gst_vaapi_mini_object_unref); + if (priv->is_hvcC) + result = gst_h265_parser_identify_nalu_hevc (priv->parser, + buf, 0, buf_size, priv->nal_length_size, &pi->nalu); + else + result = gst_h265_parser_identify_nalu_unchecked (priv->parser, + buf, 0, buf_size, &pi->nalu); + status = get_status (result); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + switch (pi->nalu.type) { + case GST_H265_NAL_VPS: + status = parse_vps (decoder, unit); + break; + case GST_H265_NAL_SPS: + status = parse_sps (decoder, unit); + break; + case GST_H265_NAL_PPS: + status = parse_pps (decoder, unit); + break; + case GST_H265_NAL_PREFIX_SEI: + case GST_H265_NAL_SUFFIX_SEI: + status = parse_sei (decoder, unit); + break; + case GST_H265_NAL_SLICE_TRAIL_N: + case GST_H265_NAL_SLICE_TRAIL_R: + case GST_H265_NAL_SLICE_TSA_N: + case GST_H265_NAL_SLICE_TSA_R: + case GST_H265_NAL_SLICE_STSA_N: + case GST_H265_NAL_SLICE_STSA_R: + case GST_H265_NAL_SLICE_RADL_N: + case GST_H265_NAL_SLICE_RADL_R: + case GST_H265_NAL_SLICE_RASL_N: + case GST_H265_NAL_SLICE_RASL_R: + case GST_H265_NAL_SLICE_BLA_W_LP: + case GST_H265_NAL_SLICE_BLA_W_RADL: + case GST_H265_NAL_SLICE_BLA_N_LP: + case GST_H265_NAL_SLICE_IDR_W_RADL: + case GST_H265_NAL_SLICE_IDR_N_LP: + case GST_H265_NAL_SLICE_CRA_NUT: + status = parse_slice (decoder, unit); + break; + default: + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + flags = 0; + if (at_au_end) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END | + GST_VAAPI_DECODER_UNIT_FLAG_AU_END; + } + switch (pi->nalu.type) { + case GST_H265_NAL_AUD: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + /* fall-through */ + case GST_H265_NAL_FD: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + break; + case GST_H265_NAL_EOB: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; + /* fall-through */ + case GST_H265_NAL_SUFFIX_SEI: + case GST_H265_NAL_EOS: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END; + break; + case GST_H265_NAL_VPS: + case GST_H265_NAL_SPS: + case GST_H265_NAL_PPS: + case GST_H265_NAL_PREFIX_SEI: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; + case GST_H265_NAL_SLICE_TRAIL_N: + case GST_H265_NAL_SLICE_TRAIL_R: + case GST_H265_NAL_SLICE_TSA_N: + case GST_H265_NAL_SLICE_TSA_R: + case GST_H265_NAL_SLICE_STSA_N: + case GST_H265_NAL_SLICE_STSA_R: + case GST_H265_NAL_SLICE_RADL_N: + case GST_H265_NAL_SLICE_RADL_R: + case GST_H265_NAL_SLICE_RASL_N: + case GST_H265_NAL_SLICE_RASL_R: + case GST_H265_NAL_SLICE_BLA_W_LP: + case GST_H265_NAL_SLICE_BLA_W_RADL: + case GST_H265_NAL_SLICE_BLA_N_LP: + case GST_H265_NAL_SLICE_IDR_W_RADL: + case GST_H265_NAL_SLICE_IDR_N_LP: + case GST_H265_NAL_SLICE_CRA_NUT: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + if (priv->prev_pi && + (priv->prev_pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END)) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START | + GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + } else if (is_new_picture (pi, priv->prev_slice_pi)) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + if (is_new_access_unit (pi, priv->prev_slice_pi)) + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; + } + gst_vaapi_parser_info_h265_replace (&priv->prev_slice_pi, pi); + if (!pi->data.slice_hdr.dependent_slice_segment_flag) + gst_vaapi_parser_info_h265_replace (&priv->prev_independent_slice_pi, + pi); + break; + default: + /* Fix */ + break; + } + if ((flags & GST_VAAPI_DECODER_UNIT_FLAGS_AU) && priv->prev_slice_pi) + priv->prev_slice_pi->flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END; + GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags); + pi->nalu.data = NULL; + pi->state = priv->parser_state; + pi->flags = flags; + gst_vaapi_parser_info_h265_replace (&priv->prev_pi, pi); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_h265_decode (GstVaapiDecoder * base_decoder, + GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265 *const decoder = + GST_VAAPI_DECODER_H265_CAST (base_decoder); + GstVaapiDecoderStatus status; + status = ensure_decoder (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + return decode_unit (decoder, unit); +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_h265_start_frame (GstVaapiDecoder * base_decoder, + GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH265 *const decoder = + GST_VAAPI_DECODER_H265_CAST (base_decoder); + return decode_picture (decoder, unit); +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_h265_end_frame (GstVaapiDecoder * base_decoder) +{ + GstVaapiDecoderH265 *const decoder = + GST_VAAPI_DECODER_H265_CAST (base_decoder); + + return decode_current_picture (decoder); +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_h265_flush (GstVaapiDecoder * base_decoder) +{ + GstVaapiDecoderH265 *const decoder = + GST_VAAPI_DECODER_H265_CAST (base_decoder); + dpb_flush (decoder); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static void +gst_vaapi_decoder_h265_class_init (GstVaapiDecoderH265Class * klass) +{ + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); + object_class->size = sizeof (GstVaapiDecoderH265); + object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; + decoder_class->create = gst_vaapi_decoder_h265_create; + decoder_class->destroy = gst_vaapi_decoder_h265_destroy; + decoder_class->parse = gst_vaapi_decoder_h265_parse; + decoder_class->decode = gst_vaapi_decoder_h265_decode; + decoder_class->start_frame = gst_vaapi_decoder_h265_start_frame; + decoder_class->end_frame = gst_vaapi_decoder_h265_end_frame; + decoder_class->flush = gst_vaapi_decoder_h265_flush; + decoder_class->decode_codec_data = gst_vaapi_decoder_h265_decode_codec_data; +} + +static inline const GstVaapiDecoderClass * +gst_vaapi_decoder_h265_class (void) +{ + static GstVaapiDecoderH265Class g_class; + static gsize g_class_init = FALSE; + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_decoder_h265_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS (&g_class); +} + +/** + * gst_vaapi_decoder_h265_set_alignment: + * @decoder: a #GstVaapiDecoderH265 + * @alignment: the #GstVaapiStreamAlignH265 + * + * Specifies how stream buffers are aligned / fed, i.e. the boundaries + * of each buffer that is supplied to the decoder. This could be no + * specific alignment, NAL unit boundaries, or access unit boundaries. + */ +void +gst_vaapi_decoder_h265_set_alignment (GstVaapiDecoderH265 * decoder, + GstVaapiStreamAlignH265 alignment) +{ + g_return_if_fail (decoder != NULL); + decoder->priv.stream_alignment = alignment; +} + +/** + * gst_vaapi_decoder_h265_new: + * @display: a #GstVaapiDisplay + * @caps: a #GstCaps holding codec information + * + * Creates a new #GstVaapiDecoder for MPEG-2 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_h265_new (GstVaapiDisplay * display, GstCaps * caps) +{ + return gst_vaapi_decoder_new (gst_vaapi_decoder_h265_class (), display, caps); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.h b/gst-libs/gst/vaapi/gstvaapidecoder_h265.h new file mode 100644 index 0000000000..89f0f931bf --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.h @@ -0,0 +1,61 @@ +/* + * gstvaapidecoder_h265.h - H.265 decoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * Author: Gwenole Beauchesne + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_DECODER_H265(decoder) \ + ((GstVaapiDecoderH265 *)(decoder)) + +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; + +GstVaapiDecoder * +gst_vaapi_decoder_h265_new(GstVaapiDisplay *display, GstCaps *caps); + +void +gst_vaapi_decoder_h265_set_alignment(GstVaapiDecoderH265 *decoder, + GstVaapiStreamAlignH265 alignment); + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_H265_H */ From a9b85e451da10719440ce3afc06a7cdafd7d2fa2 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 13 Apr 2015 15:43:30 +0300 Subject: [PATCH 1953/3781] plugins: Add HEVC decoder Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapidecode.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 707efabcff..afeaf2cb12 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -48,6 +48,7 @@ #include #include #include +#include #define GST_PLUGIN_NAME "vaapidecode" #define GST_PLUGIN_DESC "A VA-API based video decoder" @@ -68,6 +69,7 @@ static const char gst_vaapidecode_sink_caps_str[] = GST_CAPS_CODEC("video/x-xvid") GST_CAPS_CODEC("video/x-h263") GST_CAPS_CODEC("video/x-h264") + GST_CAPS_CODEC("video/x-h265") GST_CAPS_CODEC("video/x-wmv") GST_CAPS_CODEC("video/x-vp8") GST_CAPS_CODEC("image/jpeg") @@ -584,6 +586,27 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) } } break; + case GST_VAAPI_CODEC_H265: + decode->decoder = gst_vaapi_decoder_h265_new (dpy, caps); + + /* Set the stream buffer alignment for better optimizations */ + if (decode->decoder && caps) { + GstStructure *const structure = gst_caps_get_structure (caps, 0); + const gchar *str = NULL; + + if ((str = gst_structure_get_string (structure, "alignment"))) { + GstVaapiStreamAlignH265 alignment; + if (g_strcmp0 (str, "au") == 0) + alignment = GST_VAAPI_STREAM_ALIGN_H265_AU; + else if (g_strcmp0 (str, "nal") == 0) + alignment = GST_VAAPI_STREAM_ALIGN_H265_NALU; + else + alignment = GST_VAAPI_STREAM_ALIGN_H265_NONE; + gst_vaapi_decoder_h265_set_alignment (GST_VAAPI_DECODER_H265 + (decode->decoder), alignment); + } + } + break; case GST_VAAPI_CODEC_WMV3: case GST_VAAPI_CODEC_VC1: decode->decoder = gst_vaapi_decoder_vc1_new (dpy, caps); From 25382f3d91c96d79e72b83e788cffcb8252455ea Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 13 Apr 2015 16:04:59 +0300 Subject: [PATCH 1954/3781] vaapidecode: Update Author name in plugin metadata --- gst/vaapi/gstvaapidecode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index afeaf2cb12..82b7b02925 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -857,7 +857,11 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) gst_element_class_set_static_metadata (element_class, "VA-API decoder", "Codec/Decoder/Video", - GST_PLUGIN_DESC, "Gwenole Beauchesne "); + GST_PLUGIN_DESC, + "Gwenole Beauchesne , " + "Halley Zhao , " + "Sreerenj Balachandran , " + "Wind Yuan "); /* sink pad */ pad_template = gst_static_pad_template_get (&gst_vaapidecode_sink_factory); From 3eb7986409b900abf1261b8e94ad08afba69d1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 14 Apr 2015 10:08:47 +0200 Subject: [PATCH 1955/3781] build: don't compile HEVC if not supported HEVC decoding was added recently libva-1.5. This patch avoids HEVC decoding support in libgstvaapi if it is not available in the installed libva. https://bugzilla.gnome.org/show_bug.cgi?id=747831 --- configure.ac | 4 ++++ gst-libs/gst/vaapi/Makefile.am | 18 ++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 72afb8aaee..d86545f71d 100644 --- a/configure.ac +++ b/configure.ac @@ -955,6 +955,10 @@ AC_DEFINE_UNQUOTED(USE_VP8_DECODER, $USE_VP8_DECODER, [Defined to 1 if VP8 decoder is used]) AM_CONDITIONAL(USE_VP8_DECODER, test $USE_VP8_DECODER -eq 1) +AC_DEFINE_UNQUOTED(USE_HEVC_DECODER, $USE_HEVC_DECODER, + [Defined to 1 if HEVC decoder is used]) +AM_CONDITIONAL(USE_HEVC_DECODER, test $USE_HEVC_DECODER -eq 1) + AC_DEFINE_UNQUOTED(USE_DRM, $USE_DRM, [Defined to 1 if DRM is enabled]) AM_CONDITIONAL(USE_DRM, test $USE_DRM -eq 1) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 4c6a254db7..4c3551e666 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -55,7 +55,6 @@ libgstvaapi_source_c = \ gstvaapidecoder.c \ gstvaapidecoder_dpb.c \ gstvaapidecoder_h264.c \ - gstvaapidecoder_h265.c \ gstvaapidecoder_mpeg2.c \ gstvaapidecoder_mpeg4.c \ gstvaapidecoder_objects.c \ @@ -81,7 +80,6 @@ libgstvaapi_source_c = \ gstvaapiutils_core.c \ gstvaapiutils_h264.c \ gstvaapiutils_mpeg2.c \ - gstvaapiutils_h265.c \ gstvaapivalue.c \ gstvaapivideopool.c \ gstvaapiwindow.c \ @@ -112,7 +110,6 @@ libgstvaapi_source_h = \ gstvaapitypes.h \ gstvaapiutils_h264.h \ gstvaapiutils_mpeg2.h \ - gstvaapiutils_h265.h \ gstvaapivalue.h \ gstvaapivideopool.h \ gstvaapiwindow.h \ @@ -146,7 +143,6 @@ libgstvaapi_source_priv_h = \ gstvaapiutils_core.h \ gstvaapiutils_h264_priv.h \ gstvaapiutils_mpeg2_priv.h \ - gstvaapiutils_h265_priv.h \ gstvaapiversion.h \ gstvaapivideopool_priv.h \ gstvaapiwindow_priv.h \ @@ -169,6 +165,17 @@ libgstvaapi_source_c += $(libgstvaapi_vp8dec_source_c) libgstvaapi_source_h += $(libgstvaapi_vp8dec_source_h) endif +libgstvaapi_hevcdec_source_c = \ + gstvaapidecoder_h265.c \ + gstvaapiutils_h265.c +libgstvaapi_hevcdec_source_h = gstvaapiutils_h265.h +libgstvaapi_hevcdec_source_priv_h = gstvaapiutils_h265_priv.h +if USE_HEVC_DECODER +libgstvaapi_source_c += $(libgstvaapi_hevcdec_source_c) +libgstvaapi_source_h += $(libgstvaapi_hevcdec_source_h) +libgstvaapi_source_priv_h += $(libgstvaapi_hevcdec_source_priv_h) +endif + libgstvaapi_enc_source_c = \ gstvaapicodedbuffer.c \ gstvaapicodedbufferpool.c \ @@ -576,6 +583,9 @@ EXTRA_DIST += \ $(libgstvaapi_jpegdec_source_h) \ $(libgstvaapi_vp8dec_source_c) \ $(libgstvaapi_vp8dec_source_h) \ + $(libgstvaapi_hevcdec_source_c) \ + $(libgstvaapi_hevcdec_source_h) \ + $(libgstvaapi_hevcdec_source_priv_h) \ $(libgstvaapi_jpegenc_source_h) \ $(libgstvaapi_jpegenc_source_c) \ $(libgstvaapi_vp8enc_source_h) \ From b8f8d50f414ac5757215ca8bd26bafc667f86d00 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Mon, 2 Feb 2015 16:42:43 +0100 Subject: [PATCH 1956/3781] wayland: destroy vpp buffer pool on resize Otherwise the old buffers with the old size are used. https://bugzilla.gnome.org/show_bug.cgi?id=747491 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 9846063d9d..e28d06e0fe 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -311,6 +311,7 @@ gst_vaapi_window_wayland_resize (GstVaapiWindow * window, GST_DEBUG ("resize window, new size %ux%u", width, height); + gst_vaapi_video_pool_replace (&priv->surface_pool, NULL); if (priv->opaque_region) wl_region_destroy (priv->opaque_region); GST_VAAPI_OBJECT_LOCK_DISPLAY (window); From 8bef2cbd49ae44fa965366f9eabd8325112195d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 14 Apr 2015 10:17:16 +0200 Subject: [PATCH 1957/3781] HEVC: silence the compiler Fixed a couple of clang complains. --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index be0f9cc066..72a1bff490 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1246,7 +1246,7 @@ error: drop_frame: priv->decoder_state = 0; priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - return GST_VAAPI_DECODER_STATUS_DROP_FRAME; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; } static GstVaapiDecoderStatus @@ -1496,7 +1496,6 @@ init_picture_poc (GstVaapiDecoderH265 * decoder, priv->prev_tid0pic_poc_msb = 0; } -done: picture->base.poc = picture->poc; GST_DEBUG ("PicOrderCntVal %d", picture->base.poc); @@ -1865,6 +1864,8 @@ is_new_access_unit (GstVaapiParserInfoH265 * pi, { if (!prev_pi) return TRUE; + + return FALSE; } static gboolean @@ -2039,7 +2040,7 @@ decode_ref_pic_set (GstVaapiDecoderH265 * decoder, priv->NumPocStCurrBefore = priv->NumPocStCurrAfter = priv->NumPocStFoll = 0; priv->NumPocLtCurr = priv->NumPocLtFoll = 0; } else { - GstH265ShortTermRefPicSet *stRefPic; + GstH265ShortTermRefPicSet *stRefPic = NULL; gint32 num_lt_pics, pocLt, PocLsbLt[16] = { 0, } , UsedByCurrPicLt[16] = { 0,}; @@ -2053,6 +2054,7 @@ decode_ref_pic_set (GstVaapiDecoderH265 * decoder, stRefPic = &sps->short_term_ref_pic_set[slice_hdr->short_term_ref_pic_set_idx]; + g_assert (stRefPic != NULL); for (i = 0, j = 0, k = 0; i < stRefPic->NumNegativePics; i++) { if (stRefPic->UsedByCurrPicS0[i]) { From 562bd629a68cee3f0dd4fa4372b6784e04e31958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 15 Apr 2015 18:16:47 +0200 Subject: [PATCH 1958/3781] vaapisink: add 'handoff' signal This patch adds the signal ::handoff and the property signal-handoffs. If the property is set TRUE, the signal ::handoff is emitted just after the buffer is rendered. Based on Zhao Halley https://bugzilla.gnome.org/show_bug.cgi?id=747905 --- gst/vaapi/gstvaapisink.c | 44 ++++++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapisink.h | 1 + 2 files changed, 45 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 75310c487f..026a92e50c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -94,6 +94,14 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiSink, G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION, gst_vaapisink_navigation_iface_init)); +enum +{ + HANDOFF_SIGNAL, + LAST_SIGNAL +}; + +static guint gst_vaapisink_signals[LAST_SIGNAL] = { 0 }; + enum { PROP_0, @@ -108,12 +116,14 @@ enum PROP_SATURATION, PROP_BRIGHTNESS, PROP_CONTRAST, + PROP_SIGNAL_HANDOFFS, N_PROPERTIES }; #define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 +#define DEFAULT_SIGNAL_HANDOFFS FALSE static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; @@ -1381,9 +1391,13 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) if (!sink->backend->render_surface (sink, surface, surface_rect, flags)) goto error; + if (sink->signal_handoffs) + g_signal_emit (sink, gst_vaapisink_signals[HANDOFF_SIGNAL], 0, buffer); + /* Retain VA surface until the next one is displayed */ gst_buffer_replace (&sink->video_buffer, buffer); gst_buffer_unref (buffer); + return GST_FLOW_OK; error: @@ -1403,6 +1417,7 @@ gst_vaapisink_show_frame (GstBaseSink * base_sink, GstBuffer * src_buffer) gst_vaapi_display_lock (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); ret = gst_vaapisink_show_frame_unlocked (sink, src_buffer); gst_vaapi_display_unlock (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); + return ret; } @@ -1481,6 +1496,9 @@ gst_vaapisink_set_property (GObject * object, case PROP_FORCE_ASPECT_RATIO: sink->keep_aspect = g_value_get_boolean (value); break; + case PROP_SIGNAL_HANDOFFS: + sink->signal_handoffs = g_value_get_boolean (value); + break; case PROP_HUE: case PROP_SATURATION: case PROP_BRIGHTNESS: @@ -1518,6 +1536,9 @@ gst_vaapisink_get_property (GObject * object, case PROP_FORCE_ASPECT_RATIO: g_value_set_boolean (value, sink->keep_aspect); break; + case PROP_SIGNAL_HANDOFFS: + g_value_set_boolean (value, sink->signal_handoffs); + break; case PROP_HUE: case PROP_SATURATION: case PROP_BRIGHTNESS: @@ -1639,6 +1660,16 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) "When enabled, scaling will respect original aspect ratio", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiSink:signal-handoffs: + * + * Send a signal after rendering the buffer. + */ + g_properties[PROP_SIGNAL_HANDOFFS] = + g_param_spec_boolean ("signal-handoffs", "Signal handoffs", + "Send a signal after rendering the buffer", DEFAULT_SIGNAL_HANDOFFS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** * GstVaapiSink:view-id: * @@ -1701,6 +1732,18 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT); g_object_class_install_properties (object_class, N_PROPERTIES, g_properties); + + /** + * GstVaapiSink::handoff: + * @object: the #GstVaapiSink instance + * @buffer: the buffer that was rendered + * + * This signal gets emitted after rendering the frame. + */ + gst_vaapisink_signals[HANDOFF_SIGNAL] = + g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, + G_TYPE_NONE, 1, GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE); } static void @@ -1719,6 +1762,7 @@ gst_vaapisink_init (GstVaapiSink * sink) sink->rotation = DEFAULT_ROTATION; sink->rotation_req = DEFAULT_ROTATION; sink->keep_aspect = TRUE; + sink->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS; gst_video_info_init (&sink->video_info); for (i = 0; i < G_N_ELEMENTS (sink->cb_values); i++) diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 958d6cc17a..3ba3dfcdc7 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -110,6 +110,7 @@ struct _GstVaapiSink guint use_overlay : 1; guint use_rotation : 1; guint keep_aspect : 1; + guint signal_handoffs : 1; }; struct _GstVaapiSinkClass From 504fdedf84cc356d002539abac0b263363c9d4a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 15 Apr 2015 17:26:43 +0200 Subject: [PATCH 1959/3781] vaapisink: use GstVideoSink vmethod show_frame() vaapisink inherits from GstVideoSink, in order to use its functionality (such as ::show-preroll-frame property), we should use its vmethod show_frame(), rather than call ourselves render() and preroll(). --- gst/vaapi/gstvaapisink.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 026a92e50c..9392da55f3 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -137,7 +137,7 @@ static void gst_vaapisink_set_event_handling (GstVaapiSink * sink, gboolean handle_events); static GstFlowReturn -gst_vaapisink_show_frame (GstBaseSink * base_sink, GstBuffer * buffer); +gst_vaapisink_show_frame (GstVideoSink * video_sink, GstBuffer * buffer); static gboolean gst_vaapisink_ensure_render_rect (GstVaapiSink * sink, guint width, @@ -563,7 +563,7 @@ gst_vaapisink_video_overlay_expose (GstVideoOverlay * overlay) if (sink->video_buffer) { gst_vaapisink_reconfigure_window (sink); - gst_vaapisink_show_frame (GST_BASE_SINK_CAST (sink), sink->video_buffer); + gst_vaapisink_show_frame (GST_VIDEO_SINK_CAST (sink), sink->video_buffer); } } @@ -1406,9 +1406,9 @@ error: } static GstFlowReturn -gst_vaapisink_show_frame (GstBaseSink * base_sink, GstBuffer * src_buffer) +gst_vaapisink_show_frame (GstVideoSink * video_sink, GstBuffer * src_buffer) { - GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); + GstVaapiSink *const sink = GST_VAAPISINK_CAST (video_sink); GstFlowReturn ret; /* We need at least to protect the gst_vaapi_aplpy_composition() @@ -1571,6 +1571,7 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstBaseSinkClass *const basesink_class = GST_BASE_SINK_CLASS (klass); + GstVideoSinkClass *const videosink_class = GST_VIDEO_SINK_CLASS (klass); GstVaapiPluginBaseClass *const base_plugin_class = GST_VAAPI_PLUGIN_BASE_CLASS (klass); GstPadTemplate *pad_template; @@ -1590,11 +1591,11 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) basesink_class->stop = gst_vaapisink_stop; basesink_class->get_caps = gst_vaapisink_get_caps; basesink_class->set_caps = gst_vaapisink_set_caps; - basesink_class->preroll = gst_vaapisink_show_frame; - basesink_class->render = gst_vaapisink_show_frame; - basesink_class->query = gst_vaapisink_query; + basesink_class->query = GST_DEBUG_FUNCPTR (gst_vaapisink_query); basesink_class->propose_allocation = gst_vaapisink_propose_allocation; + videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_vaapisink_show_frame); + element_class->set_bus = gst_vaapisink_set_bus; gst_element_class_set_static_metadata (element_class, "VA-API sink", "Sink/Video", GST_PLUGIN_DESC, From 0adb36b6587b099724453bc4ef0aafb1b65a392f Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Wed, 15 Apr 2015 15:20:17 -0400 Subject: [PATCH 1960/3781] videopool: Release lock while allocating new object The video pool can be accessed with the display lock held, for example, when releasing a buffer from inside vaapisink_render, but allocating a new object can may also take the display lock. Which means a possible deadlock. https://bugzilla.gnome.org/show_bug.cgi?id=747944 --- gst-libs/gst/vaapi/gstvaapivideopool.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 0b1adf0844..4ec1736ddf 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -177,7 +177,9 @@ gst_vaapi_video_pool_get_object_unlocked (GstVaapiVideoPool * pool) object = g_queue_pop_head (&pool->free_objects); if (!object) { + g_mutex_unlock (&pool->mutex); object = gst_vaapi_video_pool_alloc_object (pool); + g_mutex_lock (&pool->mutex); if (!object) return NULL; } @@ -354,7 +356,11 @@ gst_vaapi_video_pool_reserve_unlocked (GstVaapiVideoPool * pool, guint n) n = pool->capacity; for (i = num_allocated; i < n; i++) { - gpointer const object = gst_vaapi_video_pool_alloc_object (pool); + gpointer object; + + g_mutex_unlock (&pool->mutex); + object = gst_vaapi_video_pool_alloc_object (pool); + g_mutex_lock (&pool->mutex); if (!object) return FALSE; g_queue_push_tail (&pool->free_objects, object); From 6f298f6182614cfaf9f3d043207ebe8a6141ffaf Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Wed, 15 Apr 2015 15:26:12 -0400 Subject: [PATCH 1961/3781] vaapipostproc: Don't create filter on caps query The problem with this is that creating the filter causes the display to be selected, and the caps query happens while linking the element. So, if the downstream or upstream element is using a specific display object, it won't be propagated correctly to the postproc as it already has a display at this point. https://bugzilla.gnome.org/show_bug.cgi?id=747945 --- gst/vaapi/gstvaapipostproc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index e1ea5ac7ce..236633882a 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -224,6 +224,9 @@ gst_vaapipostproc_ensure_filter (GstVaapiPostproc * postproc) if (!gst_vaapipostproc_ensure_display (postproc)) return FALSE; + gst_caps_replace (&postproc->allowed_srcpad_caps, NULL); + gst_caps_replace (&postproc->allowed_sinkpad_caps, NULL); + postproc->filter = gst_vaapi_filter_new (GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc)); if (!postproc->filter) @@ -297,7 +300,7 @@ gst_vaapipostproc_start (GstBaseTransform * trans) ds_reset (&postproc->deinterlace_state); if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (postproc))) return FALSE; - if (!gst_vaapipostproc_ensure_display (postproc)) + if (!gst_vaapipostproc_ensure_filter (postproc)) return FALSE; return TRUE; } @@ -936,10 +939,8 @@ expand_allowed_srcpad_caps (GstVaapiPostproc * postproc, GstCaps * caps) { GValue value = G_VALUE_INIT, v_format = G_VALUE_INIT; guint i, num_structures; - gboolean had_filter; - had_filter = postproc->filter != NULL; - if (!had_filter && !gst_vaapipostproc_ensure_filter (postproc)) + if (postproc->filter == NULL) goto cleanup; if (!gst_vaapipostproc_ensure_filter_caps (postproc)) goto cleanup; @@ -967,8 +968,6 @@ expand_allowed_srcpad_caps (GstVaapiPostproc * postproc, GstCaps * caps) g_value_unset (&value); cleanup: - if (!had_filter) - gst_vaapipostproc_destroy_filter (postproc); return caps; } From b5425da1de221b678c8819df543f2775f1cf1ad7 Mon Sep 17 00:00:00 2001 From: Martin Sherburn Date: Tue, 14 Apr 2015 10:54:54 +0100 Subject: [PATCH 1962/3781] display: drm: fix race condition setting device type There is a race condition where g_drm_device_type can be left set to DRM_DEVICE_RENDERNODES when it shouldn't. If thread 1 comes in and falls into the last else statement setting up both RENDERNODES and LEGACY types. And begins to process the first type (RENDERNODES), it sets g_drm_device_type = RENDERNODES. Now when thread 2 comes in and sees g_drm_device_type is RENDERNODES, it queues up that type to be tried but then encounters the lock and has to wait until the first thread finishes. Once the lock is acquired it will then proceed to ONLY try RENDERNODES and fail it. But it doesn't try LEGACY. And from then on, all future attempts will only try RENDERNODES. So to avoid this situation I have simply moved the acquisition of the lock higher up in the attached patch. https://bugzilla.gnome.org/show_bug.cgi?id=747914 --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 43516e40f7..56da23507d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -382,6 +382,7 @@ gst_vaapi_display_drm_new (const gchar * device_path) GstVaapiDisplay *display; guint types[2], i, num_types = 0; + g_mutex_lock (&g_drm_device_type_lock); if (device_path) types[num_types++] = 0; else if (g_drm_device_type) @@ -391,7 +392,6 @@ gst_vaapi_display_drm_new (const gchar * device_path) types[num_types++] = DRM_DEVICE_LEGACY; } - g_mutex_lock (&g_drm_device_type_lock); for (i = 0; i < num_types; i++) { g_drm_device_type = types[i]; display = gst_vaapi_display_new (gst_vaapi_display_drm_class (), From 2ddfcd8bc373e093d446c0f74ab52902932534cf Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 16 Apr 2015 14:13:21 +0300 Subject: [PATCH 1963/3781] decoder: hevc: Fix decoding when there are RASL pictures present. -- Set NoRaslOutputFlag based on EOS and EOB Nal units -- Fix PicOutputFlag setting for RASL picture -- Fix prev_poc_lsb/prev_poc_msb calculation -- Drop the RASL frames if NoRaslOutputFlag is TRUE for the associated IRAP picture -- Fixed couple of crashes and added cosmetics --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 96 +++++++++++++++-------- 1 file changed, 62 insertions(+), 34 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 72a1bff490..764fbd82e7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -411,6 +411,9 @@ struct _GstVaapiDecoderH265Private guint is_hvcC:1; guint has_context:1; guint progressive_sequence:1; + guint new_bitstream:1; + guint prev_nal_is_eos:1; /*previous nal type is EOS */ + guint associated_irap_NoRaslOutputFlag:1; }; /** @@ -467,6 +470,14 @@ nal_is_bla (guint8 nal_type) return FALSE; } +static gboolean +nal_is_cra (guint8 nal_type) +{ + if (nal_type == GST_H265_NAL_SLICE_CRA_NUT) + return TRUE; + return FALSE; +} + static gboolean nal_is_radl (guint8 nal_type) { @@ -829,24 +840,30 @@ dpb_add (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) } +/* C.5.2.2 */ static gboolean dpb_init (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi) { GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; GstH265SPS *const sps = get_sps (decoder); - /* Fixme: Not required?? */ - if (nal_is_idr (pi->nalu.type)) - while (dpb_bump (decoder, picture)); + if (nal_is_irap (pi->nalu.type) + && picture->NoRaslOutputFlag && !priv->new_bitstream) { + + if (pi->nalu.type == GST_H265_NAL_SLICE_CRA_NUT) + picture->NoOutputOfPriorPicsFlag = 1; + else + picture->NoOutputOfPriorPicsFlag = + slice_hdr->no_output_of_prior_pics_flag; - /* C.5.2.2 */ - if (picture->IntraPicFlag && - picture->NoRaslOutputFlag /*&& Fixme: Not picture0 */ ) { if (picture->NoOutputOfPriorPicsFlag) dpb_clear (decoder, TRUE); - else + else { dpb_clear (decoder, FALSE); + while (dpb_bump (decoder, NULL)); + } } else { dpb_clear (decoder, FALSE); while ((dpb_get_num_need_output (decoder) > @@ -961,6 +978,8 @@ gst_vaapi_decoder_h265_create (GstVaapiDecoder * base_decoder) priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD; priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; priv->progressive_sequence = TRUE; + priv->new_bitstream = TRUE; + priv->prev_nal_is_eos = FALSE; return TRUE; } @@ -1457,7 +1476,7 @@ init_picture_poc (GstVaapiDecoderH265 * decoder, priv->prev_poc_lsb = priv->poc_lsb; priv->prev_poc_msb = priv->poc_msb; - if (!nal_is_irap (nal_type) && picture->NoRaslOutputFlag) { + if (!(nal_is_irap (nal_type) && picture->NoRaslOutputFlag)) { priv->prev_poc_lsb = priv->prev_tid0pic_poc_lsb; priv->prev_poc_msb = priv->prev_tid0pic_poc_msb; } @@ -1597,6 +1616,7 @@ static gboolean init_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi) { + GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiPicture *const base_picture = &picture->base; GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; @@ -1608,9 +1628,6 @@ init_picture (GstVaapiDecoderH265 * decoder, GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_IDR); } - if (nal_is_irap (pi->nalu.type)) - picture->IntraPicFlag = TRUE; - if (pi->nalu.type >= GST_H265_NAL_SLICE_BLA_W_LP && pi->nalu.type <= GST_H265_NAL_SLICE_CRA_NUT) picture->RapPicFlag = TRUE; @@ -1622,34 +1639,28 @@ init_picture (GstVaapiDecoderH265 * decoder, /*NoRaslOutputFlag ==1 if the current picture is 1) an IDR picture 2) a BLA picture - 3) a CRA picture that is the first access unit in the bitstream (Fixme: Not yet added) - 4) first picture that follows an end of sequence NAL unit in decoding order (Fixme: Not yet added) - 5) has HandleCraAsBlaFlag == 1 (Fixme: Not yet added) + 3) a CRA picture that is the first access unit in the bitstream + 4) first picture that follows an end of sequence NAL unit in decoding order + 5) has HandleCraAsBlaFlag == 1 (set by external means, so not considering ) */ if (nal_is_idr (pi->nalu.type) || nal_is_bla (pi->nalu.type) || - pi->nalu.type == GST_H265_NAL_SLICE_CRA_NUT) { + (nal_is_cra (pi->nalu.type) && priv->new_bitstream) + || priv->prev_nal_is_eos) { picture->NoRaslOutputFlag = 1; } - if (nal_is_rasl (pi-> - nalu.type) /* Fixme: || NoRaslOutPutFlag of asso irap=1 */ ) + if (nal_is_irap (pi->nalu.type)) { + picture->IntraPicFlag = TRUE; + priv->associated_irap_NoRaslOutputFlag = picture->NoRaslOutputFlag; + } + + if (nal_is_rasl (pi->nalu.type) && priv->associated_irap_NoRaslOutputFlag) picture->output_flag = FALSE; else picture->output_flag = slice_hdr->pic_output_flag; init_picture_poc (decoder, picture, pi); - /* C.3.2 */ - if (nal_is_irap (pi->nalu.type) - && picture->NoRaslOutputFlag && picture->poc /*&& Fixme: Not picture0 */ ) { - - if (pi->nalu.type == GST_H265_NAL_SLICE_CRA_NUT) - picture->NoOutputOfPriorPicsFlag = 1; - else - picture->NoOutputOfPriorPicsFlag = - slice_hdr->no_output_of_prior_pics_flag; - } - return TRUE; } @@ -1878,7 +1889,7 @@ has_entry_in_rps (GstVaapiPictureH265 * dpb_pic, return FALSE; for (i = 0; i < rps_list_length; i++) { - if (rps_list[i]->poc == dpb_pic->poc) + if (rps_list[i] && rps_list[i]->poc == dpb_pic->poc) return TRUE; } return FALSE; @@ -2006,6 +2017,7 @@ derive_and_mark_rps (GstVaapiDecoderH265 * decoder, priv->NumPocStFoll)) gst_vaapi_picture_h265_set_reference (dpb_pic, 0); } + } /* Decoding process for reference picture set (8.3.2) */ @@ -2170,13 +2182,16 @@ decode_picture (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) if (!init_picture (decoder, picture, pi)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + /* Drop all RASL pictures having NoRaslOutputFlag is TRUE for the + * associated IRAP picture */ + if (nal_is_rasl (pi->nalu.type) && priv->associated_irap_NoRaslOutputFlag) { + gst_vaapi_picture_replace (&priv->current_picture, NULL); + return (GstVaapiDecoderStatus)GST_VAAPI_DECODER_STATUS_DROP_FRAME; + } + if (!decode_ref_pic_set (decoder, picture, pi)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - /* Fixme: if pic is BLA or CRA,and have NoRaslOutputFlag == 1, - invoke 8.3.3 as described in specification for generating - unavailable reference pictures */ - if (!dpb_init (decoder, picture, pi)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; @@ -2523,10 +2538,22 @@ decode_unit (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) case GST_H265_NAL_SLICE_IDR_W_RADL: case GST_H265_NAL_SLICE_IDR_N_LP: case GST_H265_NAL_SLICE_CRA_NUT: + /* slice decoding will get started only after completing all the + initialization routines for each picture which is hanlding in + start_frame() call back, so the new_bitstream and prev_nal_is_eos + flags will have effects starting from the next frame onwards */ + priv->new_bitstream = FALSE; + priv->prev_nal_is_eos = FALSE; status = decode_slice (decoder, unit); break; - case GST_H265_NAL_EOS: case GST_H265_NAL_EOB: + priv->new_bitstream = TRUE; + GST_DEBUG + ("Next AU(if there is any) will be the begining of new bitstream"); + status = decode_sequence_end (decoder); + break; + case GST_H265_NAL_EOS: + priv->prev_nal_is_eos = TRUE; status = decode_sequence_end (decoder); break; case GST_H265_NAL_SUFFIX_SEI: @@ -2772,6 +2799,7 @@ gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder, flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END | GST_VAAPI_DECODER_UNIT_FLAG_AU_END; } + switch (pi->nalu.type) { case GST_H265_NAL_AUD: flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; From baec8e35f494be8e1832e4a6bf9d83593407c8f1 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 16 Apr 2015 14:13:59 +0300 Subject: [PATCH 1964/3781] decoder: hevc: Add Support for tiled video decoding Based up on the value of uniform_spacing_flag in Picture Parameter Set, the tile column width and tile row height should be calculated. Equations: 6-1, 6-2 Tiled video Descriptions: 7.3.2.3, 7.4.3.3 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 72 ++++++++++++++++++++++- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 764fbd82e7..0fc845237e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -27,6 +27,7 @@ #include "sysdeps.h" #include +#include #include #include #include "gstvaapidecoder_h265.h" @@ -1310,6 +1311,23 @@ parse_sps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static void +get_pic_width_height_in_ctbs (GstH265PPS * pps, + guint * PicWidthInCtbsY, guint * PicHeightInCtbsY) +{ + gint MinCbLog2SizeY, CtbLog2SizeY, MinCbSizeY, CtbSizeY; + GstH265SPS *sps = pps->sps; + + MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3; + CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size; + MinCbSizeY = 1 << MinCbLog2SizeY; + CtbSizeY = 1 << CtbLog2SizeY; + + *PicWidthInCtbsY = + ceil ((double) sps->pic_width_in_luma_samples / (double) CtbSizeY); + *PicHeightInCtbsY = + ceil ((double) sps->pic_height_in_luma_samples / (double) CtbSizeY); +} static GstVaapiDecoderStatus parse_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) @@ -1318,16 +1336,60 @@ parse_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) GstVaapiParserInfoH265 *const pi = unit->parsed_info; GstH265PPS *const pps = &pi->data.pps; GstH265ParserResult result; - + guint col_width[19], row_height[21]; GST_DEBUG ("parse PPS"); priv->parser_state &= GST_H265_VIDEO_STATE_GOT_SPS; + memset (col_width, 0, sizeof (col_width)); + memset (row_height, 0, sizeof (row_height)); + memset (pps, 0, sizeof (GstH265PPS)); result = gst_h265_parser_parse_pps (priv->parser, &pi->nalu, pps); if (result != GST_H265_PARSER_OK) return get_status (result); + if (pps->tiles_enabled_flag) { + guint i; + guint PicWidthInCtbsY, PicHeightInCtbsY; + + get_pic_width_height_in_ctbs (pps, &PicWidthInCtbsY, &PicHeightInCtbsY); + GST_DEBUG ("PicWidthInCtbsY %d PicHeightInCtbsY %d", PicWidthInCtbsY, + PicHeightInCtbsY); + + /* Tile Scanning Conversion 6-3 and 6-4 */ + if (pps->uniform_spacing_flag) { + + for (i = 0; i <= pps->num_tile_columns_minus1; i++) + col_width[i] = + ((i + 1) * PicWidthInCtbsY) / (pps->num_tile_columns_minus1 + 1) - + (i * PicWidthInCtbsY) / (pps->num_tile_columns_minus1 + 1); + + for (i = 0; i <= pps->num_tile_rows_minus1; i++) + row_height[i] = + ((i + 1) * PicHeightInCtbsY) / (pps->num_tile_rows_minus1 + 1) - + (i * PicHeightInCtbsY) / (pps->num_tile_rows_minus1 + 1); + + } else { + + col_width[pps->num_tile_columns_minus1] = PicWidthInCtbsY; + for (i = 0; i < pps->num_tile_columns_minus1; i++) { + col_width[i] = pps->column_width_minus1[i] + 1; + col_width[pps->num_tile_columns_minus1] -= col_width[i]; + } + + row_height[pps->num_tile_rows_minus1] = PicHeightInCtbsY; + for (i = 0; i < pps->num_tile_rows_minus1; i++) { + row_height[i] = pps->row_height_minus1[i] + 1; + row_height[pps->num_tile_rows_minus1] -= row_height[i]; + } + } + for (i = 0; i <= pps->num_tile_columns_minus1; i++) + pps->column_width_minus1[i] = col_width[i] - 1; + for (i = 0; i <= pps->num_tile_rows_minus1; i++) + pps->row_height_minus1[i] = row_height[i] - 1; + } + priv->parser_state |= GST_H265_VIDEO_STATE_GOT_PPS; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1812,10 +1874,14 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) COPY_FIELD (pps, log2_parallel_merge_level_minus2); COPY_FIELD (pps, num_tile_columns_minus1); COPY_FIELD (pps, num_tile_rows_minus1); - for (i = 0; i < 19; i++) + for (i = 0; i <= pps->num_tile_columns_minus1; i++) pic_param->column_width_minus1[i] = pps->column_width_minus1[i]; - for (i = 0; i < 21; i++) + for (; i < 19; i++) + pic_param->column_width_minus1[i] = 0; + for (i = 0; i <= pps->num_tile_rows_minus1; i++) pic_param->row_height_minus1[i] = pps->row_height_minus1[i]; + for (; i < 21; i++) + pic_param->row_height_minus1[i] = 0; COPY_BFM (slice_parsing_fields, pps, lists_modification_present_flag); COPY_BFM (slice_parsing_fields, sps, long_term_ref_pics_present_flag); From b3eccdb72be42469ad0d4fc45ffb6a8f7b3ebf25 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 17 Apr 2015 10:36:25 +0200 Subject: [PATCH 1965/3781] decoder: hevc: cosmetics. Mostly coding style updates. Avoid integer signess inconsistencies. Optimize dpb_find_lowest_poc() to align with original h264's decoder. --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 88 ++++++++++++++--------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 0fc845237e..98eb93ee92 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -50,7 +50,8 @@ typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; typedef struct _GstVaapiParserInfoH265 GstVaapiParserInfoH265; typedef struct _GstVaapiPictureH265 GstVaapiPictureH265; -static gboolean nal_is_slice (guint8 nal_type); +static gboolean +nal_is_slice (guint8 nal_type); /* ------------------------------------------------------------------------- */ /* --- H.265 Parser Info --- */ @@ -84,7 +85,7 @@ struct _GstVaapiParserInfoH265 GstH265VPS vps; GstH265SPS sps; GstH265PPS pps; - /* Fix SEI parsing in codecparser, have to use GArry like h264parser */ + /* Fix SEI parsing in codecparser, have to use GArray like h264parser */ GstH265SEIMessage sei; GstH265SliceHdr slice_hdr; } data; @@ -275,7 +276,7 @@ gst_vaapi_picture_h265_set_reference (GstVaapiPictureH265 * picture, struct _GstVaapiFrameStore { - /*< private > */ + /*< private >*/ GstVaapiMiniObject parent_instance; GstVaapiPictureH265 *buffer; @@ -424,7 +425,7 @@ struct _GstVaapiDecoderH265Private */ struct _GstVaapiDecoderH265 { - /*< private > */ + /*< private >*/ GstVaapiDecoder parent_instance; GstVaapiDecoderH265Private priv; }; @@ -436,7 +437,7 @@ struct _GstVaapiDecoderH265 */ struct _GstVaapiDecoderH265Class { - /*< private > */ + /*< private >*/ GstVaapiDecoderClass parent_class; }; @@ -534,6 +535,7 @@ ensure_pps (GstVaapiDecoderH265 * decoder, GstH265PPS * pps) { GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiParserInfoH265 *const pi = priv->pps[pps->id]; + gst_vaapi_parser_info_h265_replace (&priv->active_pps, pi); return pi ? &pi->data.pps : NULL; } @@ -543,6 +545,7 @@ static inline GstH265PPS * get_pps (GstVaapiDecoderH265 * decoder) { GstVaapiParserInfoH265 *const pi = decoder->priv.active_pps; + return pi ? &pi->data.pps : NULL; } @@ -552,6 +555,7 @@ ensure_sps (GstVaapiDecoderH265 * decoder, GstH265SPS * sps) { GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiParserInfoH265 *const pi = priv->sps[sps->id]; + gst_vaapi_parser_info_h265_replace (&priv->active_sps, pi); return pi ? &pi->data.sps : NULL; } @@ -561,6 +565,7 @@ static inline GstH265SPS * get_sps (GstVaapiDecoderH265 * decoder) { GstVaapiParserInfoH265 *const pi = decoder->priv.active_sps; + return pi ? &pi->data.sps : NULL; } @@ -570,6 +575,7 @@ ensure_vps (GstVaapiDecoderH265 * decoder, GstH265VPS * vps) { GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiParserInfoH265 *const pi = priv->vps[vps->id]; + gst_vaapi_parser_info_h265_replace (&priv->active_vps, pi); return pi ? &pi->data.vps : NULL; } @@ -589,6 +595,7 @@ get_max_dec_frame_buffering (GstH265SPS * sps) guint max_dec_frame_buffering; GstVaapiLevelH265 level; const GstVaapiH265LevelLimits *level_limits; + level = gst_vaapi_utils_h265_get_level (sps->profile_tier_level.level_idc); level_limits = gst_vaapi_utils_h265_get_level_limits (level); if (G_UNLIKELY (!level_limits)) { @@ -605,6 +612,7 @@ dpb_remove_index (GstVaapiDecoderH265 * decoder, gint index) { GstVaapiDecoderH265Private *const priv = &decoder->priv; guint i, num_frames = --priv->dpb_count; + if (USE_STRICT_DPB_ORDERING) { for (i = index; i < num_frames; i++) gst_vaapi_frame_store_replace (&priv->dpb[i], priv->dpb[i + 1]); @@ -617,6 +625,7 @@ static gboolean dpb_output (GstVaapiDecoderH265 * decoder, GstVaapiFrameStore * fs) { GstVaapiPictureH265 *picture; + g_return_val_if_fail (fs != NULL, FALSE); picture = fs->buffer; @@ -631,12 +640,10 @@ static GstVaapiPictureH265 * dpb_get_picture (GstVaapiDecoderH265 * decoder, gint poc, gboolean match_lsb) { GstVaapiDecoderH265Private *const priv = &decoder->priv; - GstVaapiPictureH265 *picture = NULL; - gint i; + guint i; for (i = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore *const fs = priv->dpb[i]; - picture = fs->buffer; + GstVaapiPictureH265 *const picture = priv->dpb[i]->buffer; if (picture && GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE)) { @@ -657,17 +664,14 @@ static GstVaapiPictureH265 * dpb_get_ref_picture (GstVaapiDecoderH265 * decoder, gint poc, gboolean is_short) { GstVaapiDecoderH265Private *const priv = &decoder->priv; - GstVaapiPictureH265 *picture = NULL; - gint i; + guint i; for (i = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore *const fs = priv->dpb[i]; - picture = fs->buffer; + GstVaapiPictureH265 *const picture = priv->dpb[i]->buffer; if (picture && picture->poc == poc) { if (is_short && GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE (picture)) return picture; - else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (picture)) return picture; } @@ -683,22 +687,14 @@ dpb_find_lowest_poc (GstVaapiDecoderH265 * decoder, { GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiPictureH265 *found_picture = NULL; - GstVaapiPictureH265 *tmp_picture = NULL; guint i, found_index; for (i = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore *const fs = priv->dpb[i]; - tmp_picture = fs->buffer; - if (tmp_picture && !tmp_picture->output_needed) + GstVaapiPictureH265 *const picture = priv->dpb[i]->buffer; + if (picture && !picture->output_needed) continue; - if (!found_picture) { - found_picture = tmp_picture; - found_index = i; - } - if (found_picture->poc > tmp_picture->poc) { - found_picture = tmp_picture; - found_index = i; - } + if (!found_picture || found_picture->poc > picture->poc) + found_picture = picture, found_index = i; } if (found_picture_ptr) @@ -778,9 +774,9 @@ dpb_get_num_need_output (GstVaapiDecoderH265 * decoder) static gboolean check_latency_cnt (GstVaapiDecoderH265 * decoder) { + GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiPictureH265 *tmp_pic; guint i = 0; - GstVaapiDecoderH265Private *const priv = &decoder->priv; while (i < priv->dpb_count) { GstVaapiFrameStore *const fs = priv->dpb[i]; @@ -798,11 +794,11 @@ check_latency_cnt (GstVaapiDecoderH265 * decoder) static gboolean dpb_add (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) { + GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstH265SPS *const sps = get_sps (decoder); GstVaapiFrameStore *fs; GstVaapiPictureH265 *tmp_pic; guint i = 0; - GstVaapiDecoderH265Private *const priv = &decoder->priv; - GstH265SPS *const sps = get_sps (decoder); /* C.5.2.3 */ while (i < priv->dpb_count) { @@ -885,6 +881,7 @@ static gboolean dpb_reset (GstVaapiDecoderH265 * decoder, guint dpb_size) { GstVaapiDecoderH265Private *const priv = &decoder->priv; + if (dpb_size > priv->dpb_size_max) { priv->dpb = g_try_realloc_n (priv->dpb, dpb_size, sizeof (*priv->dpb)); if (!priv->dpb) @@ -902,6 +899,7 @@ static GstVaapiDecoderStatus get_status (GstH265ParserResult result) { GstVaapiDecoderStatus status; + switch (result) { case GST_H265_PARSER_OK: status = GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -923,6 +921,7 @@ static void gst_vaapi_decoder_h265_close (GstVaapiDecoderH265 * decoder) { GstVaapiDecoderH265Private *const priv = &decoder->priv; + gst_vaapi_picture_replace (&priv->current_picture, NULL); gst_vaapi_parser_info_h265_replace (&priv->prev_slice_pi, NULL); gst_vaapi_parser_info_h265_replace (&priv->prev_independent_slice_pi, NULL); @@ -940,6 +939,7 @@ static gboolean gst_vaapi_decoder_h265_open (GstVaapiDecoderH265 * decoder) { GstVaapiDecoderH265Private *const priv = &decoder->priv; + gst_vaapi_decoder_h265_close (decoder); priv->parser = gst_h265_parser_new (); if (!priv->parser) @@ -954,6 +954,7 @@ gst_vaapi_decoder_h265_destroy (GstVaapiDecoder * base_decoder) GST_VAAPI_DECODER_H265_CAST (base_decoder); GstVaapiDecoderH265Private *const priv = &decoder->priv; guint i; + gst_vaapi_decoder_h265_close (decoder); g_free (priv->dpb); priv->dpb = NULL; @@ -975,6 +976,7 @@ gst_vaapi_decoder_h265_create (GstVaapiDecoder * base_decoder) GstVaapiDecoderH265 *const decoder = GST_VAAPI_DECODER_H265_CAST (base_decoder); GstVaapiDecoderH265Private *const priv = &decoder->priv; + priv->profile = GST_VAAPI_PROFILE_UNKNOWN; priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD; priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; @@ -990,6 +992,7 @@ fill_profiles (GstVaapiProfile profiles[16], guint * n_profiles_ptr, GstVaapiProfile profile) { guint n_profiles = *n_profiles_ptr; + profiles[n_profiles++] = profile; switch (profile) { case GST_VAAPI_PROFILE_H265_MAIN: @@ -1012,6 +1015,7 @@ get_profile (GstVaapiDecoderH265 * decoder, GstH265SPS * sps, guint dpb_size) GstVaapiDisplay *const display = GST_VAAPI_DECODER_DISPLAY (decoder); GstVaapiProfile profile, profiles[3]; guint i, n_profiles = 0; + profile = gst_vaapi_utils_h265_get_profile (sps->profile_tier_level.profile_idc); if (!profile) @@ -1119,6 +1123,7 @@ fill_iq_matrix_4x4 (VAIQMatrixBufferHEVC * iq_matrix, GstH265ScalingList * scaling_list) { guint i; + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4) == 6); g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4[0]) == 16); for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList4x4); i++) { @@ -1132,6 +1137,7 @@ fill_iq_matrix_8x8 (VAIQMatrixBufferHEVC * iq_matrix, GstH265ScalingList * scaling_list) { guint i; + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8) == 6); g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8[0]) == 64); for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList8x8); i++) { @@ -1145,6 +1151,7 @@ fill_iq_matrix_16x16 (VAIQMatrixBufferHEVC * iq_matrix, GstH265ScalingList * scaling_list) { guint i; + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList16x16) == 6); g_assert (G_N_ELEMENTS (iq_matrix->ScalingList16x16[0]) == 64); for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList16x16); i++) { @@ -1158,6 +1165,7 @@ fill_iq_matrix_32x32 (VAIQMatrixBufferHEVC * iq_matrix, GstH265ScalingList * scaling_list) { guint i; + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList32x32) == 2); g_assert (G_N_ELEMENTS (iq_matrix->ScalingList32x32[0]) == 64); for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList32x32); i++) { @@ -1171,6 +1179,7 @@ fill_iq_matrix_dc_16x16 (VAIQMatrixBufferHEVC * iq_matrix, GstH265ScalingList * scaling_list) { guint i; + for (i = 0; i < 6; i++) iq_matrix->ScalingListDC16x16[i] = scaling_list->scaling_list_dc_coef_minus8_16x16[i] + 8; @@ -1181,6 +1190,7 @@ fill_iq_matrix_dc_32x32 (VAIQMatrixBufferHEVC * iq_matrix, GstH265ScalingList * scaling_list) { guint i; + for (i = 0; i < 2; i++) iq_matrix->ScalingListDC32x32[i] = scaling_list->scaling_list_dc_coef_minus8_32x32[i] + 8; @@ -1337,6 +1347,7 @@ parse_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) GstH265PPS *const pps = &pi->data.pps; GstH265ParserResult result; guint col_width[19], row_height[21]; + GST_DEBUG ("parse PPS"); priv->parser_state &= GST_H265_VIDEO_STATE_GOT_SPS; @@ -1512,10 +1523,13 @@ static GstVaapiDecoderStatus decode_sequence_end (GstVaapiDecoderH265 * decoder) { GstVaapiDecoderStatus status; + GST_DEBUG ("decode sequence-end"); + status = decode_current_picture (decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; + dpb_flush (decoder); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1967,9 +1981,9 @@ derive_and_mark_rps (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi, gint32 * CurrDeltaPocMsbPresentFlag, gint32 * FollDeltaPocMsbPresentFlag) { - guint i; - GstVaapiPictureH265 *dpb_pic = NULL; GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiPictureH265 *dpb_pic = NULL; + guint i; memset (priv->RefPicSetLtCurr, 0, sizeof (GstVaapiPictureH265 *) * 16); memset (priv->RefPicSetLtFoll, 0, sizeof (GstVaapiPictureH265 *) * 16); @@ -2252,7 +2266,7 @@ decode_picture (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) * associated IRAP picture */ if (nal_is_rasl (pi->nalu.type) && priv->associated_irap_NoRaslOutputFlag) { gst_vaapi_picture_replace (&priv->current_picture, NULL); - return (GstVaapiDecoderStatus)GST_VAAPI_DECODER_STATUS_DROP_FRAME; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; } if (!decode_ref_pic_set (decoder, picture, pi)) @@ -2272,6 +2286,7 @@ static inline guint get_slice_data_byte_offset (GstH265SliceHdr * slice_hdr, guint nal_header_bytes) { guint epb_count; + epb_count = slice_hdr->n_emulation_prevention_bytes; return nal_header_bytes + (slice_hdr->header_size + 7) / 8 - epb_count; } @@ -2647,6 +2662,7 @@ gst_vaapi_decoder_h265_decode_codec_data (GstVaapiDecoder * GstH265ParserResult result; guint num_nal_arrays, num_nals; guint i, j, ofs; + unit.parsed_info = NULL; if (buf_size < 23) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; @@ -2715,6 +2731,7 @@ ensure_decoder (GstVaapiDecoderH265 * decoder) { GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiDecoderStatus status; + if (!priv->is_opened) { priv->is_opened = gst_vaapi_decoder_h265_open (decoder); if (!priv->is_opened) @@ -2743,9 +2760,11 @@ gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder, guint32 start_code; gint ofs, ofs2; gboolean at_au_end = FALSE; + status = ensure_decoder (decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; + switch (priv->stream_alignment) { case GST_VAAPI_STREAM_ALIGN_H265_NALU: case GST_VAAPI_STREAM_ALIGN_H265_AU: @@ -2941,6 +2960,7 @@ gst_vaapi_decoder_h265_decode (GstVaapiDecoder * base_decoder, GstVaapiDecoderH265 *const decoder = GST_VAAPI_DECODER_H265_CAST (base_decoder); GstVaapiDecoderStatus status; + status = ensure_decoder (decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; @@ -2953,6 +2973,7 @@ gst_vaapi_decoder_h265_start_frame (GstVaapiDecoder * base_decoder, { GstVaapiDecoderH265 *const decoder = GST_VAAPI_DECODER_H265_CAST (base_decoder); + return decode_picture (decoder, unit); } @@ -2970,6 +2991,7 @@ gst_vaapi_decoder_h265_flush (GstVaapiDecoder * base_decoder) { GstVaapiDecoderH265 *const decoder = GST_VAAPI_DECODER_H265_CAST (base_decoder); + dpb_flush (decoder); return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -2980,6 +3002,7 @@ gst_vaapi_decoder_h265_class_init (GstVaapiDecoderH265Class * klass) GstVaapiMiniObjectClass *const object_class = GST_VAAPI_MINI_OBJECT_CLASS (klass); GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); + object_class->size = sizeof (GstVaapiDecoderH265); object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; decoder_class->create = gst_vaapi_decoder_h265_create; @@ -2997,6 +3020,7 @@ gst_vaapi_decoder_h265_class (void) { static GstVaapiDecoderH265Class g_class; static gsize g_class_init = FALSE; + if (g_once_init_enter (&g_class_init)) { gst_vaapi_decoder_h265_class_init (&g_class); g_once_init_leave (&g_class_init, TRUE); From 78aa9c4433548645bb16377a2fbf25c4492062cd Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 17 Apr 2015 10:10:10 +0200 Subject: [PATCH 1966/3781] autogen: drop videoutils submodule. --- autogen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index d7213afcac..b36c8dc801 100755 --- a/autogen.sh +++ b/autogen.sh @@ -21,7 +21,7 @@ if test -z "$GIT"; then exit 1 else submodule_init="no" - for ext_module in codecparsers videoutils; do + for ext_module in codecparsers; do if test ! -f ext/${ext_module}/autogen.sh; then submodule_init="yes" fi From c7f41b770b1076634f475e923c509116010ac369 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 17 Apr 2015 15:44:04 +0300 Subject: [PATCH 1967/3781] codecparsers: Update to gst-vaapi-branch commit 43a0368 45f1c28: codecparser: h265: Fix nal unit size checking f25987b: codecparser: h265: Calculate crop rectangle dimensions 639573a: codecparser: h265: Fix parsing multiple SEI messages in a single SEI Nal 4c8ec41: Add h265 videoparser plugin source files --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index b09990aec6..eca844dc66 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit b09990aec609acd1b8d3071f0e48835709bc72b0 +Subproject commit eca844dc660181d47ebcf77b6ffbbcc5e43a0368 From 8c7bc7dff8ccb482f86a3d34b7f5e5a31af61037 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 17 Apr 2015 16:45:22 +0300 Subject: [PATCH 1968/3781] plugins: Add h265 videoparser element "vaapiparse_h265" This is a mirror of h265parse element in upstream gst-plugins-bad. There could be additional patches but all should go to upstream. This is for making development faster. Note: vaapiparse_h265 will get build only for GStreamer version >= 1.4 --- ext/Makefile.am | 2 ++ gst/vaapi/Makefile.am | 18 ++++++++++ gst/vaapi/gstvaapiparse.c | 9 +++++ gst/vaapi/gstvaapiparse.h | 11 +++++++ ...01-h265parse-include-gstvaapiparse.h.patch | 33 +++++++++++++++++++ patches/videoparsers/series.frag | 1 + 6 files changed, 74 insertions(+) create mode 100644 patches/videoparsers/0001-h265parse-include-gstvaapiparse.h.patch diff --git a/ext/Makefile.am b/ext/Makefile.am index 8450b85d50..d6085815e6 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -44,12 +44,14 @@ videoparsers_srcdir = \ videoparsers_source_c = \ gsth264parse.c \ + gsth265parse.c \ $(NULL) EXTRA_DIST += $(videoparsers_source_c:%.c=$(videoparsers_srcdir)/%.c) videoparsers_source_h = \ gsth264parse.h \ + gsth265parse.h \ $(NULL) EXTRA_DIST += $(videoparsers_source_h:%.h=$(videoparsers_srcdir)/%.h) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 37ecc37251..d63f1684a4 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -167,14 +167,30 @@ libgstvaapi_parse_gen_source_h = \ gsth264parse.h \ $(NULL) +libgstvaapi_1_4p_parse_gen_source_c = \ + gsth265parse.c \ + $(NULL) + +libgstvaapi_1_4p_parse_gen_source_h = \ + gsth265parse.h \ + $(NULL) + libgstvaapi_parse_gen_sources = \ $(libgstvaapi_parse_gen_source_c) \ $(libgstvaapi_parse_gen_source_h) \ $(NUL) +libgstvaapi_parse_gen_sources += $(libgstvaapi_1_4p_parse_gen_source_c) +libgstvaapi_parse_gen_sources += $(libgstvaapi_1_4p_parse_gen_source_h) + libgstvaapi_parse_source_c = gstvaapiparse.c $(libgstvaapi_parse_gen_source_c) libgstvaapi_parse_source_h = gstvaapiparse.h $(libgstvaapi_parse_gen_source_h) +if USE_GST_API_1_4p +libgstvaapi_parse_source_c += $(libgstvaapi_1_4p_parse_gen_source_c) +libgstvaapi_parse_source_h += $(libgstvaapi_1_4p_parse_gen_source_h) +endif + libgstvaapi_parse_la_SOURCES = $(libgstvaapi_parse_source_c) noinst_HEADERS += $(libgstvaapi_parse_source_h) @@ -234,6 +250,8 @@ EXTRA_DIST = \ $(libgstvaapi_1_2p_source_h) \ $(libgstvaapi_parse_source_c) \ $(libgstvaapi_parse_source_h) \ + $(libgstvaapi_1_4p_parse_gen_source_c) \ + $(libgstvaapi_1_4p_parse_gen_source_h) \ $(NULL) # Extra clean files so that maintainer-clean removes *everything* diff --git a/gst/vaapi/gstvaapiparse.c b/gst/vaapi/gstvaapiparse.c index f29e503dd9..06ac69c4bc 100644 --- a/gst/vaapi/gstvaapiparse.c +++ b/gst/vaapi/gstvaapiparse.c @@ -25,6 +25,10 @@ #include "gstvaapiparse.h" #include "gsth264parse.h" +#if GST_CHECK_VERSION(1,4,0) +#include "gsth265parse.h" +#endif + #define PLUGIN_NAME "vaapiparse" #define PLUGIN_DESC "VA-API based elements" #define PLUGIN_LICENSE "LGPL" @@ -37,6 +41,11 @@ plugin_init (GstPlugin * plugin) failure |= !gst_element_register (plugin, "vaapiparse_h264", GST_RANK_PRIMARY + 2, GST_TYPE_H264_PARSE); +#if GST_CHECK_VERSION(1,4,0) + failure |= !gst_element_register (plugin, "vaapiparse_h265", + GST_RANK_PRIMARY + 2, GST_TYPE_H265_PARSE); +#endif + return !failure; } diff --git a/gst/vaapi/gstvaapiparse.h b/gst/vaapi/gstvaapiparse.h index 03e74d9656..8983c866fd 100644 --- a/gst/vaapi/gstvaapiparse.h +++ b/gst/vaapi/gstvaapiparse.h @@ -33,4 +33,15 @@ #define gst_h264_parse_parent_class gst_vaapi_h264_parse_parent_class #define gst_h264_parse_get_type gst_vaapi_h264_parse_get_type +/* vaapiparse_h265 */ +#define _GstH265Parse _GstVaapiH265Parse +#define GstH265Parse GstVaapiH265Parse +#define _GstH265ParseClass _GstVaapiH265ParseClass +#define GstH265ParseClass GstVaapiH265ParseClass +#define gst_h265_parse gst_vaapi_h265_parse +#define gst_h265_parse_init gst_vaapi_h265_parse_init +#define gst_h265_parse_class_init gst_vaapi_h265_parse_class_init +#define gst_h265_parse_parent_class gst_vaapi_h265_parse_parent_class +#define gst_h265_parse_get_type gst_vaapi_h265_parse_get_type + #endif /* GST_VAAPI_PARSE_H */ diff --git a/patches/videoparsers/0001-h265parse-include-gstvaapiparse.h.patch b/patches/videoparsers/0001-h265parse-include-gstvaapiparse.h.patch new file mode 100644 index 0000000000..613b875c9b --- /dev/null +++ b/patches/videoparsers/0001-h265parse-include-gstvaapiparse.h.patch @@ -0,0 +1,33 @@ +From a205193cffee9405bc9013416b15d8d1499be6bb Mon Sep 17 00:00:00 2001 +From: Sreerenj Balachandran +Date: Thu, 16 Apr 2015 18:04:53 +0300 +Subject: [PATCH] h265parse: include gstvaapiparse.h + +--- + gst/vaapi/gsth265parse.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/gst/vaapi/gsth265parse.c b/gst/vaapi/gsth265parse.c +index 2d7b997..5942d41 100644 +--- a/gst/vaapi/gsth265parse.c ++++ b/gst/vaapi/gsth265parse.c +@@ -22,6 +22,7 @@ + # include "config.h" + #endif + ++#include "gstvaapiparse.h" + #include + #include + #include +@@ -101,7 +102,7 @@ gst_h265_parse_class_init (GstH265ParseClass * klass) + GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); + +- GST_DEBUG_CATEGORY_INIT (h265_parse_debug, "h265parse", 0, "h265 parser"); ++ GST_DEBUG_CATEGORY_INIT (h265_parse_debug, "vaapiparse_h265", 0, "h265 parser"); + + gobject_class->finalize = gst_h265_parse_finalize; + gobject_class->set_property = gst_h265_parse_set_property; +-- +1.9.1 + diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index 32fc5380c4..040b2bd0fa 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -4,4 +4,5 @@ videoparsers_patches_base = \ 0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch \ 0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch \ 0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ + 0001-h265parse-include-gstvaapiparse.h.patch \ $(NULL) From bd86647970b17995f1d73c05e048f86fdd31eed5 Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Fri, 17 Apr 2015 19:10:35 +0000 Subject: [PATCH 1969/3781] vaapipluginbase: The allocation query can return without a pool It is possible to return the min/max/size without actually providing a pool. This way the source knows how many buffers downstream needs. https://bugzilla.gnome.org/show_bug.cgi?id=748076 --- gst/vaapi/gstvaapipluginbase.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 37aa39089b..e8079d089b 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -670,13 +670,15 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); - size = MAX (size, vi.size); - update_pool = TRUE; + if (pool) { + size = MAX (size, vi.size); + update_pool = TRUE; - /* Check whether downstream element proposed a bufferpool but did - not provide a correct propose_allocation() implementation */ - has_video_alignment = gst_buffer_pool_has_option (pool, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + /* Check whether downstream element proposed a bufferpool but did + not provide a correct propose_allocation() implementation */ + has_video_alignment = gst_buffer_pool_has_option (pool, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + } } else { pool = NULL; size = vi.size; From 7e08786e1d38bf98c3aba2ad6d3498f0dfca07d3 Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Thu, 16 Apr 2015 20:18:13 -0400 Subject: [PATCH 1970/3781] vaapidecode: Use the GstVideoDecoder error reporting function This way, the decoder won't stop on the first decoding error, in most cases it can recover after some glitchiness. https://bugzilla.gnome.org/show_bug.cgi?id=744620 --- gst/vaapi/gstvaapidecode.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 82b7b02925..685da6bbb0 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -347,9 +347,9 @@ gst_vaapidecode_push_all_decoded_frames (GstVaapiDecode * decode) case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: return GST_FLOW_OK; default: - GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding failed"), - ("Unknown decoding error")); - return GST_FLOW_ERROR; + GST_VIDEO_DECODER_ERROR (vdec, 1, STREAM, DECODE, ("Decoding failed"), + ("Unknown decoding error"), ret); + return ret; } } g_assert_not_reached (); @@ -429,9 +429,8 @@ error_decode: ret = GST_FLOW_NOT_SUPPORTED; break; default: - GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding error"), - ("Decode error %d", status)); - ret = GST_FLOW_ERROR; + GST_VIDEO_DECODER_ERROR (vdec, 1, STREAM, DECODE, ("Decoding error"), + ("Decode error %d", status), ret); break; } gst_video_decoder_drop_frame (vdec, frame); From dedbbdd41b9d510f8c1a667182b796d5cbcbbf65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 19 Apr 2015 11:19:03 +0200 Subject: [PATCH 1971/3781] vaapidecode: reduce logging noise When a frame is rejected by downstream, the message is logged twice. This patch removes one of those logging messages. Also, the reject of a frame doesn't mean an alarming error. This patch demotes the log message from error to info. --- gst/vaapi/gstvaapidecode.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 685da6bbb0..276a050297 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -319,9 +319,8 @@ error_get_meta: } error_commit_buffer: { - if (ret != GST_FLOW_FLUSHING) - GST_ERROR ("video sink rejected the video buffer (error: %s [%d])", - gst_flow_get_name (ret), ret); + GST_INFO_OBJECT (decode, "downstream element rejected the frame (%s [%d])", + gst_flow_get_name (ret), ret); gst_video_codec_frame_unref (out_frame); return ret; } @@ -407,10 +406,7 @@ gst_vaapidecode_handle_frame (GstVideoDecoder * vdec, /* Note that gst_vaapi_decoder_decode cannot return success without completing the decode and pushing all decoded frames into the output queue */ - ret = gst_vaapidecode_push_all_decoded_frames (decode); - if (ret != GST_FLOW_OK && ret != GST_FLOW_FLUSHING) - GST_ERROR ("push loop error after decoding %d", ret); - return ret; + return gst_vaapidecode_push_all_decoded_frames (decode); /* ERRORS */ error_push_all_decoded_frames: From 11c963a3c1e3d0b21e0867a83faadcc6076fca2d Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Thu, 16 Apr 2015 12:53:18 -0400 Subject: [PATCH 1972/3781] vaapidecode: Tell the base class about released frames on close The base class needs to be informed about frames that were still queued in the decoder on release, otherwise they are leaked. https://bugzilla.gnome.org/show_bug.cgi?id=747999 --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 3 +- gst/vaapi/gstvaapidecode.c | 32 ++++++++++------------ 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 1bb2a2279e..c1866416f2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -774,7 +774,8 @@ decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) { GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - gst_vaapi_dpb_flush(priv->dpb); + if (priv->dpb) + gst_vaapi_dpb_flush(priv->dpb); return GST_VAAPI_DECODER_STATUS_SUCCESS; } diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 276a050297..27593ae30f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -633,6 +633,19 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) static void gst_vaapidecode_destroy (GstVaapiDecode * decode) { + GstVideoCodecFrame *out_frame = NULL; + + if (decode->decoder) { + gst_vaapi_decoder_flush (decode->decoder); + + /* Purge all decoded frames as we don't need them (e.g. seek) */ + while (gst_vaapi_decoder_get_frame_with_timeout (decode->decoder, + &out_frame, 0) == GST_VAAPI_DECODER_STATUS_SUCCESS) { + gst_video_decoder_release_frame (GST_VIDEO_DECODER (decode), out_frame); + gst_video_codec_frame_unref (out_frame); + out_frame = NULL; + } + } gst_vaapi_decoder_replace (&decode->decoder, NULL); gst_caps_replace (&decode->decoder_caps, NULL); @@ -652,24 +665,7 @@ gst_vaapidecode_reset_full (GstVaapiDecode * decode, GstCaps * caps, /* Reset tracked frame size */ decode->current_frame_size = 0; - /* Reset timers if hard reset was requested (e.g. seek) */ - if (hard) { - GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); - GstVideoCodecFrame *out_frame = NULL; - - gst_vaapi_decoder_flush (decode->decoder); - - /* Purge all decoded frames as we don't need them (e.g. seek) */ - while (gst_vaapi_decoder_get_frame_with_timeout (decode->decoder, - &out_frame, 0) == GST_VAAPI_DECODER_STATUS_SUCCESS) { - gst_video_decoder_drop_frame (vdec, out_frame); - gst_video_codec_frame_unref (out_frame); - out_frame = NULL; - } - } - - /* Only reset decoder if codec type changed */ - else if (decode->decoder && decode->decoder_caps) { + if (!hard && decode->decoder && decode->decoder_caps) { if (gst_caps_is_always_compatible (caps, decode->decoder_caps)) return TRUE; codec = gst_vaapi_codec_from_caps (caps); From dbc8f3f25f7893cc943dd2efcf39141b75fdd989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 20 Apr 2015 13:27:27 +0200 Subject: [PATCH 1973/3781] vaapidecode: refactor gst_vaapidecode_destroy() Add the method gst_vaapidecode_purge(). This method releases the flushed frames from the decoder. This new method add more readablity to gst_vaapidecode_destroy() --- gst/vaapi/gstvaapidecode.c | 40 ++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 27593ae30f..002e0ad7ce 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -630,22 +630,38 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) return TRUE; } +static void +gst_vaapidecode_purge (GstVaapiDecode * decode) +{ + GstVaapiDecoderStatus status; + + if (!decode->decoder) + return; + + status = gst_vaapi_decoder_flush (decode->decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + GST_INFO_OBJECT (decode, "decoder flush failed"); + + /* Purge all decoded frames as we don't need them (e.g. flush and close) + * Releasing the frames is important, otherwise the frames are not + * freed. */ + do { + GstVideoCodecFrame *frame = NULL; + + status = + gst_vaapi_decoder_get_frame_with_timeout (decode->decoder, &frame, 0); + if (frame) { + gst_video_decoder_release_frame (GST_VIDEO_DECODER (decode), frame); + gst_video_codec_frame_unref (frame); + } + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); +} + static void gst_vaapidecode_destroy (GstVaapiDecode * decode) { - GstVideoCodecFrame *out_frame = NULL; + gst_vaapidecode_purge (decode); - if (decode->decoder) { - gst_vaapi_decoder_flush (decode->decoder); - - /* Purge all decoded frames as we don't need them (e.g. seek) */ - while (gst_vaapi_decoder_get_frame_with_timeout (decode->decoder, - &out_frame, 0) == GST_VAAPI_DECODER_STATUS_SUCCESS) { - gst_video_decoder_release_frame (GST_VIDEO_DECODER (decode), out_frame); - gst_video_codec_frame_unref (out_frame); - out_frame = NULL; - } - } gst_vaapi_decoder_replace (&decode->decoder, NULL); gst_caps_replace (&decode->decoder_caps, NULL); From 99f95690b5facbe9c823df1e20438be3936813c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 21 Apr 2015 10:00:36 +0200 Subject: [PATCH 1974/3781] vaapidecode: refactor gst_vaapidecode_internal_flush() This a cosmetic refactor: gst_vaapidecode_internal_flush() removes its only label; gst_vaapidecode_finish() is more readable and gst_vaapidecode_purge() shares the same error message of gst_vaapidecode_internal_flush() when flush fails. --- gst/vaapi/gstvaapidecode.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 002e0ad7ce..4a9653420e 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -471,32 +471,29 @@ gst_vaapidecode_internal_flush (GstVideoDecoder * vdec) } status = gst_vaapi_decoder_flush (decode->decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - goto error_flush; - return TRUE; - - /* ERRORS */ -error_flush: - { - GST_ERROR ("failed to flush decoder (status %d)", status); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_WARNING_OBJECT (decode, "failed to flush decoder (status %d)", status); return FALSE; } + + return TRUE; } static GstFlowReturn gst_vaapidecode_finish (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + gboolean flushed; + GstFlowReturn ret; if (!decode->decoder) return GST_FLOW_OK; - if (!gst_vaapidecode_internal_flush (vdec)) { - gst_vaapidecode_push_all_decoded_frames (decode); + flushed = gst_vaapidecode_internal_flush (vdec); + ret = gst_vaapidecode_push_all_decoded_frames (decode); + if (!flushed) return GST_FLOW_ERROR; - } - - return gst_vaapidecode_push_all_decoded_frames (decode); + return ret; } static gboolean @@ -640,7 +637,7 @@ gst_vaapidecode_purge (GstVaapiDecode * decode) status = gst_vaapi_decoder_flush (decode->decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - GST_INFO_OBJECT (decode, "decoder flush failed"); + GST_INFO_OBJECT (decode, "failed to flush decoder (status %d)", status); /* Purge all decoded frames as we don't need them (e.g. flush and close) * Releasing the frames is important, otherwise the frames are not From 7548c72a7d7db3e1d1d2bb2965a08d028907565a Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Tue, 3 Feb 2015 16:52:06 +0100 Subject: [PATCH 1975/3781] wayland: free frame in buffer release callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Wayland compositor may still use the buffer when the frame done callback is called. This patch destroys the frame (which contains the buffer) until the release callback is called. The draw termination callback only controls the display queue dispatching. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=747492 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 22 +++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index e28d06e0fe..41943170ca 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -114,6 +114,7 @@ struct _GstVaapiWindowWaylandPrivate guint is_shown:1; guint fullscreen_on_show:1; guint use_vpp:1; + guint frame_pending:1; }; /** @@ -162,14 +163,14 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); - if (priv->frame) { + if (priv->frame_pending) { struct wl_display *const wl_display = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); do { if (wl_display_dispatch_queue (wl_display, priv->event_queue) < 0) return FALSE; - } while (priv->frame); + } while (priv->frame_pending); } return TRUE; } @@ -329,15 +330,24 @@ frame_redraw_callback (void *data, struct wl_callback *callback, uint32_t time) GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); - frame_state_free (frame); if (priv->frame == frame) - priv->frame = NULL; + priv->frame_pending = FALSE; } static const struct wl_callback_listener frame_callback_listener = { frame_redraw_callback }; +static void +frame_release_callback (void *data, struct wl_buffer *wl_buffer) +{ + frame_state_free (data); +} + +static const struct wl_buffer_listener frame_buffer_listener = { + frame_release_callback +}; + static GstVaapiSurface * vpp_convert (GstVaapiWindow * window, GstVaapiSurface * surface, @@ -474,6 +484,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, if (!frame) return FALSE; priv->frame = frame; + priv->frame_pending = TRUE; if (need_vpp && priv->use_vpp) { frame->surface = surface; @@ -492,6 +503,9 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, } frame->buffer = buffer; + wl_proxy_set_queue ((struct wl_proxy *) buffer, priv->event_queue); + wl_buffer_add_listener (buffer, &frame_buffer_listener, frame); + frame->callback = wl_surface_frame (priv->surface); wl_callback_add_listener (frame->callback, &frame_callback_listener, frame); From af8ea3701e9b747460a60743a36b17cdf6b908d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 21 Apr 2015 17:17:06 +0200 Subject: [PATCH 1976/3781] wayland: refactor _sync() method and rename callback This patch only intends to improve readability: in the method gst_vaapi_window_wayland_sync() the if/do instructions are squashed into a single while loop. Also renames the frame_redraw_callback() callback into frame_done_callback(), which is a bit more aligned to Wayland API. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 41943170ca..dbbaa2fcb9 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -163,14 +163,12 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); - if (priv->frame_pending) { + while (priv->frame_pending) { struct wl_display *const wl_display = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - do { - if (wl_display_dispatch_queue (wl_display, priv->event_queue) < 0) - return FALSE; - } while (priv->frame_pending); + if (wl_display_dispatch_queue (wl_display, priv->event_queue) < 0) + return FALSE; } return TRUE; } @@ -324,7 +322,7 @@ gst_vaapi_window_wayland_resize (GstVaapiWindow * window, } static void -frame_redraw_callback (void *data, struct wl_callback *callback, uint32_t time) +frame_done_callback (void *data, struct wl_callback *callback, uint32_t time) { FrameState *const frame = data; GstVaapiWindowWaylandPrivate *const priv = @@ -335,7 +333,7 @@ frame_redraw_callback (void *data, struct wl_callback *callback, uint32_t time) } static const struct wl_callback_listener frame_callback_listener = { - frame_redraw_callback + frame_done_callback }; static void From 4091e86ab6ec25deb8bfa38ddb716731e59131db Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Mon, 27 Apr 2015 20:31:50 -0400 Subject: [PATCH 1977/3781] wayland: don't leak the registry proxy Release the registry proxy when closing the display. https://bugzilla.gnome.org/show_bug.cgi?id=748564 --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 090965eae2..71c4909c13 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -246,6 +246,11 @@ gst_vaapi_display_wayland_close_display (GstVaapiDisplay * display) priv->compositor = NULL; } + if (priv->registry) { + wl_registry_destroy (priv->registry); + priv->registry = NULL; + } + if (priv->wl_display) { if (!priv->use_foreign_display) wl_display_disconnect (priv->wl_display); From be37f459986ca7144643d4570482773909d067cf Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Mon, 27 Apr 2015 20:50:19 -0400 Subject: [PATCH 1978/3781] videopool: Free members before chaining up finalize The finalize function in GObject frees the object memory, so everything else needs to have been freed before. https://bugzilla.gnome.org/show_bug.cgi?id=748563 --- gst/vaapi/gstvaapivideobufferpool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 0b15901041..e79158f555 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -64,10 +64,10 @@ gst_vaapi_video_buffer_pool_finalize (GObject * object) GstVaapiVideoBufferPoolPrivate *const priv = GST_VAAPI_VIDEO_BUFFER_POOL (object)->priv; - G_OBJECT_CLASS (gst_vaapi_video_buffer_pool_parent_class)->finalize (object); - gst_vaapi_display_replace (&priv->display, NULL); g_clear_object (&priv->allocator); + + G_OBJECT_CLASS (gst_vaapi_video_buffer_pool_parent_class)->finalize (object); } static void From d70a2e8d130f4bff935d674ce0f8ee8bede6867e Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Mon, 27 Apr 2015 19:21:12 -0400 Subject: [PATCH 1979/3781] vaapipluginbase: Update the pool if there was no pool in the downstream reply MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix regression introduced by bd866479, the query after decide_allocation() always needs a pool in the first slot. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=748559 --- gst/vaapi/gstvaapipluginbase.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e8079d089b..23c14a6d6c 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -607,7 +607,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GstStructure *config; GstVideoInfo vi; guint size, min, max; - gboolean need_pool, update_pool; + gboolean need_pool, update_pool = FALSE; gboolean has_video_meta = FALSE; gboolean has_video_alignment = FALSE; #if (USE_GLX || USE_EGL) @@ -670,9 +670,9 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); + update_pool = (pool != NULL); if (pool) { size = MAX (size, vi.size); - update_pool = TRUE; /* Check whether downstream element proposed a bufferpool but did not provide a correct propose_allocation() implementation */ @@ -683,7 +683,6 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, pool = NULL; size = vi.size; min = max = 0; - update_pool = FALSE; } /* GstVaapiVideoMeta is mandatory, and this implies VA surface memory */ From b8268b1f3efa5dfede539b5b410d631e7bf5c9dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Apr 2015 12:22:29 +0200 Subject: [PATCH 1980/3781] plugins: delete unused variable need_pool is a boolean variable extracted from the allocation query, but it is not used afterwards. --- gst/vaapi/gstvaapipluginbase.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 23c14a6d6c..f5edd26fd8 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -607,7 +607,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GstStructure *config; GstVideoInfo vi; guint size, min, max; - gboolean need_pool, update_pool = FALSE; + gboolean update_pool = FALSE; gboolean has_video_meta = FALSE; gboolean has_video_alignment = FALSE; #if (USE_GLX || USE_EGL) @@ -617,7 +617,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, g_return_val_if_fail (plugin->display != NULL, FALSE); - gst_query_parse_allocation (query, &caps, &need_pool); + gst_query_parse_allocation (query, &caps, NULL); /* We don't need any GL context beyond this point if not requested so explicitly through GstVideoGLTextureUploadMeta */ From 100d5971b59b2a0b93510625b6addd98b0ab44bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Apr 2015 12:24:52 +0200 Subject: [PATCH 1981/3781] plugins: more specific log message Be more specific in the log message about the reason of creating a new pool. --- gst/vaapi/gstvaapipluginbase.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index f5edd26fd8..a5f3d29d16 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -688,8 +688,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, /* GstVaapiVideoMeta is mandatory, and this implies VA surface memory */ if (!pool || !gst_buffer_pool_has_option (pool, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) { - GST_INFO_OBJECT (plugin, "no pool or doesn't support GstVaapiVideoMeta, " - "making new pool"); + GST_INFO_OBJECT (plugin, "%s. Making a new pool", pool == NULL ? "No pool" : + "Pool hasn't GstVaapiVideoMeta"); if (pool) gst_object_unref (pool); pool = gst_vaapi_video_buffer_pool_new (plugin->display); From 97b768675a72042607588921f429652af9249eec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Apr 2015 12:27:43 +0200 Subject: [PATCH 1982/3781] plugins: check gst_buffer_pool_set_config() Check the return value of gst_buffer_pool_set_config(). If it fails an error message is posted in the bus. --- gst/vaapi/gstvaapipluginbase.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index a5f3d29d16..206848d541 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -700,7 +700,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gst_buffer_pool_config_set_params (config, caps, size, min, max); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - gst_buffer_pool_set_config (pool, config); + if (!gst_buffer_pool_set_config (pool, config)) + goto config_failed; } /* Check whether GstVideoMeta, or GstVideoAlignment, is needed (raw video) */ @@ -708,12 +709,14 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); - gst_buffer_pool_set_config (pool, config); + if (!gst_buffer_pool_set_config (pool, config)) + goto config_failed; } else if (has_video_alignment) { config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); - gst_buffer_pool_set_config (pool, config); + if (!gst_buffer_pool_set_config (pool, config)) + goto config_failed; } /* GstVideoGLTextureUploadMeta (OpenGL) */ @@ -722,7 +725,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); - gst_buffer_pool_set_config (pool, config); + if (!gst_buffer_pool_set_config (pool, config)) + goto config_failed; } #endif @@ -752,6 +756,15 @@ error_create_pool: GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); return FALSE; } +config_failed: + { + if (pool) + gst_object_unref (pool); + GST_ELEMENT_ERROR (plugin, RESOURCE, SETTINGS, + ("Failed to configure the buffer pool"), + ("Configuration is most likely invalid, please report this issue.")); + return FALSE; + } } /** From 28b4fc4dd90737587d2f5384b1101722d4ac37f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Apr 2015 12:39:50 +0200 Subject: [PATCH 1983/3781] vaapipostproc: tune up a couple of log messages In order to reduce the noise, the query type log was downgrade from INFO to DEBUG, and the shared display address log message is assigned to the object. --- gst/vaapi/gstvaapipostproc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 236633882a..1b8acb9c62 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1252,11 +1252,12 @@ gst_vaapipostproc_query (GstBaseTransform * trans, GstPadDirection direction, { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - GST_INFO_OBJECT (trans, "query type `%s'", GST_QUERY_TYPE_NAME (query)); + GST_DEBUG_OBJECT (trans, "query type `%s'", GST_QUERY_TYPE_NAME (query)); if (gst_vaapi_reply_to_query (query, GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc))) { - GST_DEBUG ("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc)); + GST_DEBUG_OBJECT (postproc, "sharing display %p", + GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc)); return TRUE; } From 188d8fe44261555c77b92169710d6400ca118be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 30 Apr 2015 13:21:08 +0200 Subject: [PATCH 1984/3781] plugins: check if the pool config is already set In commit 97b768, a regression for GStreamer 1.2 was introduced: GStreamer 1.2 doesn't check, in gst_buffer_pool_set_config() if the config option is already set. This patch adds an inline function to first verify if the option is not in the pool config berfore add it. --- gst/vaapi/gstvaapipluginbase.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 206848d541..d29e817c69 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -587,6 +587,22 @@ error_pool_config: } } +/* XXXX: GStreamer 1.2 doesn't check, in gst_buffer_pool_set_config() + if the config option is already set */ +static inline gboolean +gst_vaapi_plugin_base_set_pool_config (GstBufferPool * pool, + const gchar * option) +{ + GstStructure *config; + + config = gst_buffer_pool_get_config (pool); + if (!gst_buffer_pool_config_has_option (config, option)) { + gst_buffer_pool_config_add_option (config, option); + return gst_buffer_pool_set_config (pool, config); + } + return TRUE; +} + /** * gst_vaapi_plugin_base_decide_allocation: * @plugin: a #GstVaapiPluginBase @@ -706,26 +722,20 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, /* Check whether GstVideoMeta, or GstVideoAlignment, is needed (raw video) */ if (has_video_meta) { - config = gst_buffer_pool_get_config (pool); - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_META); - if (!gst_buffer_pool_set_config (pool, config)) + if (!gst_vaapi_plugin_base_set_pool_config (pool, + GST_BUFFER_POOL_OPTION_VIDEO_META)) goto config_failed; } else if (has_video_alignment) { - config = gst_buffer_pool_get_config (pool); - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); - if (!gst_buffer_pool_set_config (pool, config)) + if (!gst_vaapi_plugin_base_set_pool_config (pool, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) goto config_failed; } /* GstVideoGLTextureUploadMeta (OpenGL) */ #if (USE_GLX || USE_EGL) if (has_texture_upload_meta) { - config = gst_buffer_pool_get_config (pool); - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); - if (!gst_buffer_pool_set_config (pool, config)) + if (!gst_vaapi_plugin_base_set_pool_config (pool, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META)) goto config_failed; } #endif From 81d6b42420a001a68089d7fed42edd4013ddba3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 30 Apr 2015 13:29:48 +0200 Subject: [PATCH 1985/3781] build: upgrade glib dependency to 2.32 Since bug #745728 was fixed the oldest supported version of GStreamer is 1.2. That GStreamer release requires glib 2.32, so we can upgrade our requirement too. This patch changes the required version of glib in configure.ac and removes the hacks in glibcompat.h https://bugzilla.gnome.org/show_bug.cgi?id=748698 --- configure.ac | 2 +- gst-libs/gst/vaapi/glibcompat.h | 126 -------------------------------- 2 files changed, 1 insertion(+), 127 deletions(-) diff --git a/configure.ac b/configure.ac index d86545f71d..22ff810725 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [0]) # glib version number -m4_define([glib_version], [2.28]) +m4_define([glib_version], [2.32]) # gstreamer version number m4_define([gst_api_version], [autodetect]) diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h index 734d6e4824..b02fbade68 100644 --- a/gst-libs/gst/vaapi/glibcompat.h +++ b/gst-libs/gst/vaapi/glibcompat.h @@ -33,132 +33,6 @@ new_api new_args \ old_api old_args; \ } -#if !GLIB_CHECK_VERSION(2,27,2) -static inline void -g_list_free_full(GList *list, GDestroyNotify free_func) -{ - g_list_foreach(list, (GFunc)free_func, NULL); - g_list_free(list); -} -#endif - -#if !GLIB_CHECK_VERSION(2,28,0) -static inline void -g_clear_object_inline(volatile GObject **object_ptr) -{ - gpointer * const ptr = (gpointer)object_ptr; - gpointer old; - - do { - old = g_atomic_pointer_get(ptr); - } while G_UNLIKELY(!g_atomic_pointer_compare_and_exchange(ptr, old, NULL)); - - if (old) - g_object_unref(old); -} -#undef g_clear_object -#define g_clear_object(obj) g_clear_object_inline((volatile GObject **)(obj)) -#endif - -#if !GLIB_CHECK_VERSION(2,31,2) -typedef GStaticMutex GCompatMutex; -G_COMPAT_DEFINE(g_compat_mutex_init, (GCompatMutex *mutex), - g_static_mutex_init, (mutex)) -G_COMPAT_DEFINE(g_compat_mutex_clear, (GCompatMutex *mutex), - g_static_mutex_free, (mutex)) -G_COMPAT_DEFINE(g_compat_mutex_lock, (GCompatMutex *mutex), - g_static_mutex_lock, (mutex)) -G_COMPAT_DEFINE(g_compat_mutex_unlock, (GCompatMutex *mutex), - g_static_mutex_unlock, (mutex)) - -typedef GStaticRecMutex GCompatRecMutex; -G_COMPAT_DEFINE(g_compat_rec_mutex_init, (GCompatRecMutex *mutex), - g_static_rec_mutex_init, (mutex)) -G_COMPAT_DEFINE(g_compat_rec_mutex_clear, (GCompatRecMutex *mutex), - g_static_rec_mutex_free, (mutex)) -G_COMPAT_DEFINE(g_compat_rec_mutex_lock, (GCompatRecMutex *mutex), - g_static_rec_mutex_lock, (mutex)) -G_COMPAT_DEFINE(g_compat_rec_mutex_unlock, (GCompatRecMutex *mutex), - g_static_rec_mutex_unlock, (mutex)) - -typedef GCond *GCompatCond; -G_COMPAT_DEFINE(g_compat_cond_init, (GCompatCond *cond), - *cond = g_cond_new, ()) -G_COMPAT_DEFINE(g_compat_cond_clear, (GCompatCond *cond), - if (*cond) g_cond_free, (*cond)) -G_COMPAT_DEFINE(g_compat_cond_signal, (GCompatCond *cond), - g_cond_signal, (*cond)) -G_COMPAT_DEFINE(g_compat_cond_broadcast, (GCompatCond *cond), - g_cond_broadcast, (*cond)) -G_COMPAT_DEFINE(g_compat_cond_wait, (GCompatCond *cond, GCompatMutex *mutex), - g_cond_wait, (*cond, g_static_mutex_get_mutex(mutex))) - -static inline gboolean -g_cond_wait_until(GCompatCond *cond, GStaticMutex *mutex, gint64 end_time) -{ - gint64 diff_time; - GTimeVal timeout; - - diff_time = end_time - g_get_monotonic_time(); - g_get_current_time(&timeout); - g_time_val_add(&timeout, diff_time > 0 ? diff_time : 0); - return g_cond_timed_wait(*cond, g_static_mutex_get_mutex(mutex), &timeout); -} - -#define GMutex GCompatMutex -#undef g_mutex_init -#define g_mutex_init(mutex) g_compat_mutex_init(mutex) -#undef g_mutex_clear -#define g_mutex_clear(mutex) g_compat_mutex_clear(mutex) -#undef g_mutex_lock -#define g_mutex_lock(mutex) g_compat_mutex_lock(mutex) -#undef g_mutex_unlock -#define g_mutex_unlock(mutex) g_compat_mutex_unlock(mutex) - -#define GRecMutex GCompatRecMutex -#undef g_rec_mutex_init -#define g_rec_mutex_init(mutex) g_compat_rec_mutex_init(mutex) -#undef g_rec_mutex_clear -#define g_rec_mutex_clear(mutex) g_compat_rec_mutex_clear(mutex) -#undef g_rec_mutex_lock -#define g_rec_mutex_lock(mutex) g_compat_rec_mutex_lock(mutex) -#undef g_rec_mutex_unlock -#define g_rec_mutex_unlock(mutex) g_compat_rec_mutex_unlock(mutex) - -#define GCond GCompatCond -#undef g_cond_init -#define g_cond_init(cond) g_compat_cond_init(cond) -#undef g_cond_clear -#define g_cond_clear(cond) g_compat_cond_clear(cond) -#undef g_cond_signal -#define g_cond_signal(cond) g_compat_cond_signal(cond) -#undef g_cond_wait -#define g_cond_wait(cond, mutex) g_compat_cond_wait(cond, mutex) - -#undef g_thread_try_new -#define g_thread_try_new(name, func, data, error) \ - g_compat_thread_try_new(name, func, data, error) - -static inline GThread * -g_compat_thread_try_new(const gchar *name, GThreadFunc func, gpointer data, - GError **error) -{ - return g_thread_create(func, data, TRUE, error); -} -#endif - -#if !GLIB_CHECK_VERSION(2,31,18) -static inline gpointer -g_async_queue_timeout_pop(GAsyncQueue *queue, guint64 timeout) -{ - GTimeVal end_time; - - g_get_current_time(&end_time); - g_time_val_add(&end_time, timeout); - return g_async_queue_timed_pop(queue, &end_time); -} -#endif - #undef G_COMPAT_DEFINE #endif /* GLIB_COMPAT_H */ From 5993b0d60fcd162a33283f20b4c54b4185c25f64 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 4 May 2015 14:24:43 +0200 Subject: [PATCH 1986/3781] vaapidecode: add guards for disabled codecs. Fix link when building plugin elements without HEVC support. e.g. don't try to call into gst_vaapi_decoder_h265_set_alignment() if there is no support HEVC enabled in libgstvaapi. Also, drop disabled codecs from static template caps. Add the missing HEVC static template caps into vaapidecodebin too. --- gst/vaapi/gstvaapidecode.c | 8 ++++++++ gst/vaapi/gstvaapidecodebin.c | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4a9653420e..4a7916ac65 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -69,10 +69,16 @@ static const char gst_vaapidecode_sink_caps_str[] = GST_CAPS_CODEC("video/x-xvid") GST_CAPS_CODEC("video/x-h263") GST_CAPS_CODEC("video/x-h264") +#if USE_HEVC_DECODER GST_CAPS_CODEC("video/x-h265") +#endif GST_CAPS_CODEC("video/x-wmv") +#if USE_VP8_DECODER GST_CAPS_CODEC("video/x-vp8") +#endif +#if USE_JPEG_DECODER GST_CAPS_CODEC("image/jpeg") +#endif ; static const char gst_vaapidecode_src_caps_str[] = @@ -578,6 +584,7 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) } } break; +#if USE_HEVC_DECODER case GST_VAAPI_CODEC_H265: decode->decoder = gst_vaapi_decoder_h265_new (dpy, caps); @@ -599,6 +606,7 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) } } break; +#endif case GST_VAAPI_CODEC_WMV3: case GST_VAAPI_CODEC_VC1: decode->decoder = gst_vaapi_decoder_vc1_new (dpy, caps); diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index cfeae5e023..27d0f4adf6 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -60,9 +60,16 @@ static const char gst_vaapi_decode_bin_sink_caps_str[] = GST_CAPS_CODEC("video/x-xvid") GST_CAPS_CODEC("video/x-h263") GST_CAPS_CODEC("video/x-h264") +#if USE_HEVC_DECODER + GST_CAPS_CODEC("video/x-h265") +#endif GST_CAPS_CODEC("video/x-wmv") +#if USE_VP8_DECODER GST_CAPS_CODEC("video/x-vp8") +#endif +#if USE_JPEG_DECODER GST_CAPS_CODEC("image/jpeg") +#endif ; /* *INDENT-ON* */ From e60df073a0db436fb61ee24d3095bc56a27b55b3 Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Sun, 15 Feb 2015 15:01:03 +0000 Subject: [PATCH 1987/3781] window: Correct prototype to match implementation On s390x, guintptr and GstVaapiID are not compatible types. The implementation of gst_vaapi_window_new_internal() and all its callers seem to assume that its third argument is a GstVaapiID, while the header gives it guintptr type. https://bugzilla.gnome.org/show_bug.cgi?id=744559 --- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index af1581be83..08cd90c3c5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -111,7 +111,7 @@ struct _GstVaapiWindowClass GstVaapiWindow * gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, - GstVaapiDisplay * display, guintptr handle, guint width, guint height); + GstVaapiDisplay * display, GstVaapiID handle, guint width, guint height); /* Inline reference counting for core libgstvaapi library */ #ifdef IN_LIBGSTVAAPI_CORE From 069edff757d92e37cce0ec1411a9821cc9df2ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 5 May 2015 13:02:19 +0200 Subject: [PATCH 1988/3781] libs: trivial documentation fix GST_VAAPI_ENCODER_STATUS_NO_SURFACE and GST_VAAPI_ENCODER_STATUS_NO_BUFFER are not errors, so they do not have the ERROR namespace. This patch fixes this typo in documentation. --- gst-libs/gst/vaapi/gstvaapiencoder.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 0ae80b69fb..a90e26dc67 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -37,9 +37,9 @@ typedef struct _GstVaapiEncoder GstVaapiEncoder; /** * GstVaapiEncoderStatus: * @GST_VAAPI_ENCODER_STATUS_SUCCESS: Success. - * @GST_VAAPI_ENCODER_STATUS_ERROR_NO_SURFACE: No surface left to encode. - * @GST_VAAPI_ENCODER_STATUS_ERROR_NO_BUFFER: No coded buffer left to - * hold the encoded picture. + * @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 From be40a1d479794539bc335ecba45b3a012489eecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 5 May 2015 13:08:25 +0200 Subject: [PATCH 1989/3781] tests: add simple-encoder program MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a simple-encoder test program that uses libgstvaapi for video encoding to elementary (raw) streams. Input stream is raw YUV in the Y4M format. That can be from a regular file or standard input when the input filename is "-". Usage: simple-encoder [options]* Options: --output|-o output file name --codec|-c codec to use for video encoding --bitrate|-b desired bitrate (kbps) By default, and as an initial patch, the encoded stream shall conform to the minimally supported profile. That is "Constrained Baseline Profile" for H.264 and "Simple Profile" for MPEG-2. Though, those are the defaults to be generated by libgstvaapi. You can find Y4M sample files here http://samples.mplayerhq.hu/yuv4mpeg2/ Original-patch-by: Changzhi Wei * general code clean-up * removed the yuv reader thread * re-wrote the y4m file parser * updated used API fixed some wrong usage * fixed a lot of memory leaks * added the bitrate setting * keep fps' numerator and denominator * simplified the thread control * removed custom logging and use glib Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=719528 --- tests/Makefile.am | 7 + tests/simple-encoder.c | 514 +++++++++++++++++++++++++++++++++++++++++ tests/y4mreader.c | 261 +++++++++++++++++++++ tests/y4mreader.h | 40 ++++ 4 files changed, 822 insertions(+) create mode 100644 tests/simple-encoder.c create mode 100644 tests/y4mreader.c create mode 100644 tests/y4mreader.h diff --git a/tests/Makefile.am b/tests/Makefile.am index 9b0168139b..fa1ee3a42d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,6 +6,7 @@ noinst_PROGRAMS = \ test-surfaces \ test-windows \ test-subpicture \ + simple-encoder \ $(NULL) if USE_GLX @@ -122,6 +123,12 @@ simple_decoder_SOURCES = $(simple_decoder_source_c) simple_decoder_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) simple_decoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) +simple_encoder_source_c = simple-encoder.c y4mreader.c +simple_encoder_source_h = y4mreader.h +simple_encoder_SOURCES = $(simple_encoder_source_c) +simple_encoder_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) +simple_encoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) + EXTRA_DIST = \ test-subpicture-data.h \ $(simple_decoder_source_h) \ diff --git a/tests/simple-encoder.c b/tests/simple-encoder.c new file mode 100644 index 0000000000..1a6f32c576 --- /dev/null +++ b/tests/simple-encoder.c @@ -0,0 +1,514 @@ +/* + * simple-encoder.c - Test GstVaapiencoder + * + * Copyright (C) 2015 Intel Corporation + * + * 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 "gst/vaapi/sysdeps.h" +#include +#include +#include +#include + +#include "output.h" +#include "y4mreader.h" + +static guint g_bitrate = 0; +static gchar *g_codec_str; +static gchar *g_output_file_name; +static char **g_input_files = NULL; + +#define SURFACE_NUM 16 + +static GOptionEntry g_options[] = { + {"codec", 'c', 0, G_OPTION_ARG_STRING, &g_codec_str, + "codec to use for video encoding (h264/mpeg2)", NULL}, + {"bitrate", 'b', 0, G_OPTION_ARG_INT, &g_bitrate, + "desired bitrate expressed in kbps", NULL}, + {"output", 'o', 0, G_OPTION_ARG_FILENAME, &g_output_file_name, + "output file name", NULL}, + {G_OPTION_REMAINING, ' ', 0, G_OPTION_ARG_FILENAME_ARRAY, &g_input_files, + "input file name", NULL}, + {NULL} +}; + +typedef struct +{ + GstVaapiDisplay *display; + GstVaapiEncoder *encoder; + guint read_frames; + guint encoded_frames; + guint saved_frames; + Y4MReader *parser; + FILE *output_file; + guint input_stopped:1; + guint encode_failed:1; +} App; + +static inline gchar * +generate_output_filename (const gchar * ext) +{ + gchar *fn; + int i = 0; + + while (1) { + fn = g_strdup_printf ("temp%02d.%s", i, ext); + if (g_file_test (fn, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { + i++; + g_free (fn); + } else { + break; + } + } + + return fn; +} + +static gboolean +parse_options (int *argc, char *argv[]) +{ + GOptionContext *ctx; + gboolean success; + GError *error = NULL; + + ctx = g_option_context_new (" - encoder test options"); + if (!ctx) + return FALSE; + + g_option_context_add_group (ctx, gst_init_get_option_group ()); + g_option_context_add_main_entries (ctx, g_options, NULL); + g_option_context_set_help_enabled (ctx, TRUE); + success = g_option_context_parse (ctx, argc, &argv, &error); + if (!success) { + g_printerr ("Option parsing failed: %s\n", error->message); + g_error_free (error); + goto bail; + } + + if (!g_codec_str) + g_codec_str = g_strdup ("h264"); + if (!g_output_file_name) + g_output_file_name = generate_output_filename (g_codec_str); + +bail: + g_option_context_free (ctx); + return success; +} + +static void +print_yuv_info (App * app) +{ + g_print ("\n"); + g_print ("Encode : %s\n", g_codec_str); + g_print ("Resolution : %dx%d\n", app->parser->width, app->parser->height); + g_print ("Source YUV : %s\n", g_input_files ? g_input_files[0] : "stdin"); + g_print ("Frame Rate : %0.1f fps\n", + 1.0 * app->parser->fps_n / app->parser->fps_d); + g_print ("Coded file : %s\n", g_output_file_name); + g_print ("\n"); +} + +static void +print_num_frame (App * app) +{ + g_print ("\n"); + g_print ("read frames : %d\n", app->read_frames); + g_print ("encoded frames : %d\n", app->encoded_frames); + g_print ("saved frames : %d\n", app->saved_frames); + g_print ("\n"); +} + +static GstVaapiEncoder * +encoder_new (GstVaapiDisplay * display) +{ + GstVaapiEncoder *encoder = NULL; + + if (!g_strcmp0 (g_codec_str, "mpeg2")) + encoder = gst_vaapi_encoder_mpeg2_new (display); + else if (!g_strcmp0 (g_codec_str, "h264")) + encoder = gst_vaapi_encoder_h264_new (display); + else + return NULL; + + gst_vaapi_encoder_set_bitrate (encoder, g_bitrate); + + return encoder; +} + +static GstVideoCodecState * +new_codec_state (gint width, gint height, gint fps_n, gint fps_d) +{ + GstVideoCodecState *state; + + state = g_slice_new0 (GstVideoCodecState); + state->ref_count = 1; + gst_video_info_init (&state->info); + gst_video_info_set_format (&state->info, GST_VIDEO_FORMAT_ENCODED, width, + height); + + state->info.fps_n = fps_n; + state->info.fps_d = fps_d; + + return state; +} + +static gboolean +set_format (GstVaapiEncoder * encoder, gint width, gint height, gint fps_n, + gint fps_d) +{ + GstVideoCodecState *in_state; + GstVaapiEncoderStatus status; + GstCaps *caps; + + if (!g_strcmp0 (g_codec_str, "mpeg2")) { + caps = gst_caps_from_string ("video/mpeg"); + gst_caps_set_simple (caps, + "mpegversion", G_TYPE_INT, 2, + "systemstream", G_TYPE_BOOLEAN, FALSE, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); + } else if (!g_strcmp0 (g_codec_str, "h264")) { + caps = gst_caps_new_empty_simple ("video/x-h264"); + gst_caps_set_simple (caps, "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); + } else { + return FALSE; + } + + in_state = new_codec_state (width, height, fps_n, fps_d); + status = gst_vaapi_encoder_set_codec_state (encoder, in_state); + gst_caps_unref (caps); + g_slice_free (GstVideoCodecState, in_state); + + return (status == GST_VAAPI_ENCODER_STATUS_SUCCESS); +} + +static GstBuffer * +allocate_buffer (GstVaapiCodedBuffer * vbuf) +{ + GstBuffer *buf; + gssize size; + + size = gst_vaapi_coded_buffer_get_size (vbuf); + if (size <= 0) { + g_warning ("Invalid VAAPI buffer size (%d)", size); + return NULL; + } + + buf = gst_buffer_new_and_alloc (size); + if (!buf) { + g_warning ("Failed to create output buffer of size %d", size); + return NULL; + } + + if (!gst_vaapi_coded_buffer_copy_into (buf, vbuf)) { + g_warning ("Failed to copy VAAPI buffer data"); + gst_buffer_unref (buf); + return NULL; + } + + return buf; +} + +static GstVaapiEncoderStatus +get_encoder_buffer (GstVaapiEncoder * encoder, GstBuffer ** buffer) +{ + GstVaapiCodedBufferProxy *proxy = NULL; + GstVaapiEncoderStatus status; + + status = gst_vaapi_encoder_get_buffer_with_timeout (encoder, &proxy, 50000); + if (status < GST_VAAPI_ENCODER_STATUS_SUCCESS) { + g_warning ("Failed to get a buffer from encoder: %d", status); + return status; + } else if (status > GST_VAAPI_ENCODER_STATUS_SUCCESS) { + return status; + } + + *buffer = allocate_buffer (GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (proxy)); + gst_vaapi_coded_buffer_proxy_unref (proxy); + + return status; +} + +static gboolean +outputs_to_file (GstBuffer * buffer, FILE * file) +{ + GstMapInfo info; + size_t written; + gboolean ret = FALSE; + + gst_buffer_map (buffer, &info, GST_MAP_READ); + + if (info.size <= 0 || !info.data) + return FALSE; + + written = fwrite (info.data, 1, info.size, file); + if (written < info.size) { + g_warning ("write file error."); + goto bail; + } + + ret = TRUE; + +bail: + gst_buffer_unmap (buffer, &info); + return ret; +} + +static gpointer +get_buffer_thread (gpointer data) +{ + App *app = data; + + GstVaapiEncoderStatus ret; + GstBuffer *obuf; + + while (1) { + obuf = NULL; + ret = get_encoder_buffer (app->encoder, &obuf); + if (app->input_stopped && ret > GST_VAAPI_ENCODER_STATUS_SUCCESS) { + break; /* finished */ + } else if (ret > GST_VAAPI_ENCODER_STATUS_SUCCESS) { /* another chance */ + continue; + } + if (ret < GST_VAAPI_ENCODER_STATUS_SUCCESS) { /* fatal error */ + app->encode_failed = TRUE; + break; + } + + app->encoded_frames++; + g_debug ("encoded frame %d, buffer = %p", app->encoded_frames, obuf); + + if (app->output_file && outputs_to_file (obuf, app->output_file)) + app->saved_frames++; + + gst_buffer_unref (obuf); + } + + if (obuf) + gst_buffer_replace (&obuf, NULL); + + return NULL; +} + +static void +app_free (App * app) +{ + g_return_if_fail (app); + + if (app->parser) + y4m_reader_close (app->parser); + + if (app->encoder) { + gst_vaapi_encoder_flush (app->encoder); + gst_vaapi_encoder_unref (app->encoder); + } + + if (app->display) + gst_vaapi_display_unref (app->display); + + if (app->output_file) + fclose (app->output_file); + + g_slice_free (App, app); +} + +static App * +app_new (const gchar * input_fn, const gchar * output_fn) +{ + App *app = g_slice_new0 (App); + if (!app) + return NULL; + + app->parser = y4m_reader_open (input_fn); + if (!app->parser) { + g_warning ("Could not parse input stream."); + goto error; + } + + app->output_file = fopen (output_fn, "w"); + if (app->output_file == NULL) { + g_warning ("Could not open file \"%s\" for writing: %s.", output_fn, + g_strerror (errno)); + goto error; + } + + app->display = video_output_create_display (NULL); + if (!app->display) { + g_warning ("Could not create VA display."); + goto error; + } + + app->encoder = encoder_new (app->display); + if (!app->encoder) { + g_warning ("Could not create encoder."); + goto error; + } + + if (!set_format (app->encoder, app->parser->width, app->parser->height, + app->parser->fps_n, app->parser->fps_d)) { + g_warning ("Could not set format."); + goto error; + } + + return app; + +error: + app_free (app); + return NULL; +} + +static gboolean +upload_frame (GstVaapiEncoder * encoder, GstVaapiSurfaceProxy * proxy) +{ + GstVideoCodecFrame *frame; + GstVaapiEncoderStatus ret; + + frame = g_slice_new0 (GstVideoCodecFrame); + gst_video_codec_frame_set_user_data (frame, + gst_vaapi_surface_proxy_ref (proxy), + (GDestroyNotify) gst_vaapi_surface_proxy_unref); + + ret = gst_vaapi_encoder_put_frame (encoder, frame); + return (ret == GST_VAAPI_ENCODER_STATUS_SUCCESS); +} + +static gboolean +load_frame (App * app, GstVaapiImage * image) +{ + gboolean ret = FALSE; + + if (!gst_vaapi_image_map (image)) + return FALSE; + + ret = y4m_reader_load_image (app->parser, image); + + if (!gst_vaapi_image_unmap (image)) + return FALSE; + + return ret; +} + +static int +app_run (App * app) +{ + GstVaapiImage *image; + GstVaapiVideoPool *pool; + GThread *buffer_thread; + gsize id; + int ret = EXIT_FAILURE; + + image = gst_vaapi_image_new (app->display, GST_VIDEO_FORMAT_I420, + app->parser->width, app->parser->height); + + { + GstVideoInfo vi; + gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_ENCODED, + app->parser->width, app->parser->height); + pool = gst_vaapi_surface_pool_new_full (app->display, &vi, 0); + } + + buffer_thread = g_thread_new ("get buffer thread", get_buffer_thread, app); + + while (1) { + if (!load_frame (app, image)) + break; + + if (!gst_vaapi_image_unmap (image)) + break; + + GstVaapiSurfaceProxy *proxy = + gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL (pool)); + if (!proxy) { + g_warning ("Could not get surface proxy from pool."); + break; + } + GstVaapiSurface *surface = gst_vaapi_surface_proxy_get_surface (proxy); + if (!surface) { + g_warning ("Could not get surface from proxy."); + break; + } + + if (!gst_vaapi_surface_put_image (surface, image)) { + g_warning ("Could not update surface"); + break; + } + + if (!upload_frame (app->encoder, proxy)) { + g_warning ("put frame failed"); + break; + } + + app->read_frames++; + id = gst_vaapi_surface_get_id (surface); + g_debug ("input frame %d, surface id = %lu", app->read_frames, id); + + gst_vaapi_surface_proxy_unref (proxy); + } + + app->input_stopped = TRUE; + + g_thread_join (buffer_thread); + + if (!app->encode_failed && feof (app->parser->fp)) + ret = EXIT_SUCCESS; + + gst_vaapi_video_pool_replace (&pool, NULL); + gst_vaapi_object_unref (image); + return ret; +} + +int +main (int argc, char *argv[]) +{ + App *app; + int ret = EXIT_FAILURE; + gchar *input_fn; + + if (!parse_options (&argc, argv)) + return EXIT_FAILURE; + + /* @TODO: iterate all the input files */ + input_fn = g_input_files ? g_input_files[0] : NULL; + if (input_fn && !g_file_test (input_fn, + G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { + g_warning ("input file \"%s\" doesn't exist", input_fn); + goto bail; + } + + app = app_new (input_fn, g_output_file_name); + if (!app) + goto bail; + + print_yuv_info (app); + ret = app_run (app); + print_num_frame (app); + + app_free (app); + +bail: + g_free (g_codec_str); + g_free (g_output_file_name); + g_strfreev (g_input_files); + + gst_deinit (); + + return ret; +} diff --git a/tests/y4mreader.c b/tests/y4mreader.c new file mode 100644 index 0000000000..aeb1d80834 --- /dev/null +++ b/tests/y4mreader.c @@ -0,0 +1,261 @@ +/* + * y4mreader.c - Y4M parser + * + * Copyright (C) 2015 Intel Corporation + * + * 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 "y4mreader.h" + +#include + +/* format documentation: + * http://wiki.multimedia.cx/index.php?title=YUV4MPEG2 */ + +static inline gboolean +parse_int (const gchar * str, glong * out_value_ptr) +{ + gint saved_errno; + glong value; + gboolean ret; + + if (!str) + return FALSE; + str += 1; + if (!str) + return FALSE; + + saved_errno = errno; + errno = 0; + value = strtol (str, NULL, 0); + ret = (errno == 0); + errno = saved_errno; + *out_value_ptr = value; + + return ret; +} + +static gboolean +parse_header (Y4MReader * file) +{ + gint i, j; + guint8 header[BUFSIZ]; + gint8 b; + size_t s; + gchar *str; + + memset (header, 0, BUFSIZ); + s = fread (header, 1, 9, file->fp); + if (s < 9) + return FALSE; + + if (memcmp (header, "YUV4MPEG2", 9) != 0) + return FALSE; + + for (i = 9; i < BUFSIZ - 1; i++) { + b = fgetc (file->fp); + if (b == EOF) + return FALSE; + if (b == 0xa) + break; + header[i] = b; + } + + if (i == BUFSIZ - 1) + return FALSE; + + j = 9; + while (j < i) { + if ((header[j] != 0x20) && (header[j - 1] == 0x20)) { + switch (header[j]) { + case 'W': + if (!parse_int ((gchar *) & header[j], (glong *) & file->width)) + return FALSE; + break; + case 'H': + if (!parse_int ((gchar *) & header[j], (glong *) & file->height)) + return FALSE; + break; + case 'C': + str = (char *) &header[j + 1]; + if (strncmp (str, "420", 3) != 0) { + g_warning ("Unsupported chroma subsampling."); + return FALSE; /* unsupported chroma subsampling */ + } + break; + case 'I': + str = (char *) &header[j + 1]; + if (*str != 'p' && *str != '?') { + g_warning ("Interlaced content are not supported."); + return FALSE; /* interlaced is unsupported */ + } + break; + case 'F': /* frame rate ratio */ + { + guint num, den; + + if (!parse_int ((gchar *) & header[j], (glong *) & num)) + return FALSE; + while ((header[j] != ':') && (j < i)) + j++; + if (!parse_int ((gchar *) & header[j], (glong *) & den)) + return FALSE; + + if (num <= 0 || den <= 0) { + file->fps_n = 30; /* default to 30 fps */ + file->fps_d = 1; + } else { + file->fps_n = num; + file->fps_d = den; + } + break; + } + case 'A': /* sample aspect ration */ + break; + case 'X': /* metadata */ + break; + default: + break; + } + } + j++; + } + + return TRUE; +} + +Y4MReader * +y4m_reader_open (const gchar * filename) +{ + Y4MReader *imagefile; + + imagefile = g_slice_new0 (Y4MReader); + + if (filename) { + imagefile->fp = fopen (filename, "r"); + if (!imagefile->fp) { + g_warning ("open file %s error", filename); + goto bail; + } + } else { + imagefile->fp = stdin; + } + + if (!parse_header (imagefile)) + goto bail; + + return imagefile; + +bail: + if (imagefile->fp && imagefile->fp != stdin) + fclose (imagefile->fp); + + g_slice_free (Y4MReader, imagefile); + return NULL; +} + +void +y4m_reader_close (Y4MReader * file) +{ + g_return_if_fail (file); + + if (file->fp && file->fp != stdin) + fclose (file->fp); + + g_slice_free (Y4MReader, file); +} + +static gboolean +skip_frame_header (Y4MReader * file) +{ + gint i; + guint8 header[BUFSIZ]; + gint8 b; + size_t s; + + memset (header, 0, BUFSIZ); + s = fread (header, 1, 5, file->fp); + if (s < 5) + return FALSE; + + if (memcmp (header, "FRAME", 5) != 0) + return FALSE; + + for (i = 5; i < BUFSIZ - 1; i++) { + b = fgetc (file->fp); + if (b == EOF) + return FALSE; + if (b == 0xa) + break; + header[i] = b; + } + + return (i < BUFSIZ - 1); +} + +gboolean +y4m_reader_load_image (Y4MReader * file, GstVaapiImage * image) +{ + guint8 *plane; + size_t s; + guint frame_size, stride, i; + + g_return_val_if_fail (gst_vaapi_image_is_mapped (image), FALSE); + g_return_val_if_fail (file && file->fp, FALSE); + + /* only valid for I420 */ + frame_size = file->height * file->width * 3 / 2; + if (gst_vaapi_image_get_data_size (image) < frame_size) + return FALSE; + if (gst_vaapi_image_get_plane_count (image) != 3) + return FALSE; + + if (!skip_frame_header (file)) + return FALSE; + + /* Y plane */ + plane = gst_vaapi_image_get_plane (image, 0); + stride = gst_vaapi_image_get_pitch (image, 0); + for (i = 0; i < file->height; i++) { + s = fread (plane, 1, file->width, file->fp); + if (s != file->width) + return FALSE; + plane += stride; + } + + /* U plane */ + plane = gst_vaapi_image_get_plane (image, 1); + stride = gst_vaapi_image_get_pitch (image, 1); + for (i = 0; i < file->height / 2; i++) { + s = fread (plane, 1, file->width / 2, file->fp); + if (s != file->width / 2) + return FALSE; + plane += stride; + } + + /* V plane */ + plane = gst_vaapi_image_get_plane (image, 2); + stride = gst_vaapi_image_get_pitch (image, 2); + for (i = 0; i < file->height / 2; i++) { + s = fread (plane, 1, file->width / 2, file->fp); + if (s != file->width / 2) + return FALSE; + plane += stride; + } + + return TRUE; +} diff --git a/tests/y4mreader.h b/tests/y4mreader.h new file mode 100644 index 0000000000..30d754bc4a --- /dev/null +++ b/tests/y4mreader.h @@ -0,0 +1,40 @@ +/* + * y4mreader.h - Y4M parser + * + * Copyright (C) 2015 Intel Corporation + * + * 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 "gst/vaapi/sysdeps.h" +#include + +typedef struct _Y4MReader Y4MReader; + +struct _Y4MReader +{ + FILE *fp; + guint width; + guint height; + gint fps_n; + gint fps_d; +}; + +Y4MReader *y4m_reader_open (const gchar * filename); + +void y4m_reader_close (Y4MReader * file); + +gboolean y4m_reader_load_image (Y4MReader * file, GstVaapiImage * image); From 3024640d4f7b0dd5450e99e8c0ec3dcda9c48a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 8 May 2015 15:54:09 +0200 Subject: [PATCH 1990/3781] plugins: remove gstreamer-0.10 crumbs GstVideoContext was used in gstreamer-0.10, which is not supported anymore. Still, its definition was still in the code. This patch removes it. https://bugzilla.gnome.org/show_bug.cgi?id=749113 --- gst/vaapi/gstvaapipluginbase.c | 3 ++- gst/vaapi/gstvaapipluginutil.c | 12 ++++-------- gst/vaapi/gstvaapipluginutil.h | 2 +- gst/vaapi/gstvaapivideocontext.h | 6 ------ 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index d29e817c69..e4f1c586ad 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -333,7 +333,8 @@ gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) return TRUE; gst_vaapi_display_replace (&plugin->display, NULL); - if (!gst_vaapi_ensure_display (plugin, plugin->display_type_req)) + if (!gst_vaapi_ensure_display (GST_ELEMENT (plugin), + plugin->display_type_req)) return FALSE; plugin->display_type = gst_vaapi_display_get_display_type (plugin->display); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index cb490601b9..64bc3ba2fb 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -247,18 +247,14 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) } gboolean -gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type) +gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type) { GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); GstVaapiDisplay *display; - GstVideoContext *context; - g_return_val_if_fail (GST_IS_VIDEO_CONTEXT (element), FALSE); + g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); - context = GST_VIDEO_CONTEXT (element); - g_return_val_if_fail (context != NULL, FALSE); - - gst_vaapi_video_context_prepare (context, display_types); + gst_vaapi_video_context_prepare (element, display_types); /* Neighbour found and it updated the display */ if (gst_vaapi_plugin_base_has_display_type (plugin, type)) @@ -272,7 +268,7 @@ gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type) if (!display) return FALSE; - gst_vaapi_video_context_propagate (context, display); + gst_vaapi_video_context_propagate (element, display); GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE (plugin, display); gst_vaapi_display_unref (display); return TRUE; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 0209d08d91..5b437c7678 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -31,7 +31,7 @@ G_GNUC_INTERNAL gboolean -gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type); +gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type); G_GNUC_INTERNAL gboolean diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index 0c8797edb7..1f052be8bc 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -31,12 +31,6 @@ #define GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME "gst.vaapi.Display" -/* Fake GstVideoContext symbols */ -#define GST_VIDEO_CONTEXT(obj) (GST_ELEMENT (obj)) -#define GST_IS_VIDEO_CONTEXT(obj) (GST_IS_ELEMENT (obj)) -#define GstVideoContext GstElement -#define gst_video_context_prepare gst_vaapi_video_context_prepare - G_GNUC_INTERNAL GstContext * gst_vaapi_video_context_new_with_display (GstVaapiDisplay * display, From c5756a91575fa4d93aa8c6c58be97ca732ce530b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 12 May 2015 16:04:33 +0200 Subject: [PATCH 1991/3781] tests: simple-encoder: fix build warnings on 64-bit platforms. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a cosmetic change to replace VAAPI buffer with VA buffer and most importantly fix warnings spitted out during build on 64-bit platforms. ../../tests/simple-encoder.c:211:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘gssize’ [-Wformat=] g_warning ("Invalid VAAPI buffer size (%d)", size); ^ ../../tests/simple-encoder.c:217:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘gssize’ [-Wformat=] g_warning ("Failed to create output buffer of size %d", size); ^ --- tests/simple-encoder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/simple-encoder.c b/tests/simple-encoder.c index 1a6f32c576..ff9ddcbe72 100644 --- a/tests/simple-encoder.c +++ b/tests/simple-encoder.c @@ -208,18 +208,18 @@ allocate_buffer (GstVaapiCodedBuffer * vbuf) size = gst_vaapi_coded_buffer_get_size (vbuf); if (size <= 0) { - g_warning ("Invalid VAAPI buffer size (%d)", size); + g_warning ("Invalid VA buffer size (%zd)", size); return NULL; } buf = gst_buffer_new_and_alloc (size); if (!buf) { - g_warning ("Failed to create output buffer of size %d", size); + g_warning ("Failed to create output buffer of size %zd", size); return NULL; } if (!gst_vaapi_coded_buffer_copy_into (buf, vbuf)) { - g_warning ("Failed to copy VAAPI buffer data"); + g_warning ("Failed to copy VA buffer data"); gst_buffer_unref (buf); return NULL; } From ae95a72dd1d4ecb17c5ccf91b5bda7217d370b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 13 May 2015 13:28:17 +0200 Subject: [PATCH 1992/3781] h264parse: update patches with upstream These patches didn't applied cleanly, breaking the `make distcleancheck` target. Re-sync'ed the patches against the current git's submodule. --- ...the-built-in-video-parsers-as-vaapip.patch | 19 ++++++++----------- ...uild-with-older-GStreamer-1.x-stacks.patch | 14 +++++++------- ...t-to-byte-stream-nalu-format-Annex-B.patch | 14 +++++++------- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch b/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch index 978cf3130d..c82d465268 100644 --- a/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch +++ b/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch @@ -1,4 +1,4 @@ -From c78b4c043dc41f071bdf170ecb001dc1aef8f5f6 Mon Sep 17 00:00:00 2001 +From c2531548cad46c80b665e7d78b2a0a0d63a083a9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Apr 2014 17:44:03 +0200 Subject: [PATCH 1/3] plugins: compile the built-in video parsers as @@ -8,17 +8,11 @@ The built-in video parsers elements are built into a single DSO named libgstvaapi_parse.so. The various video parsers could be accessed as vaapiparse_CODEC. --- - configure.ac | 9 ++++++++ - gst/vaapi/Makefile.am | 35 ++++++++++++++++++++++++++++++ - gst/vaapi/gsth264parse.c | 4 +++- - gst/vaapi/gstvaapiparse.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ - gst/vaapi/gstvaapiparse.h | 36 ++++++++++++++++++++++++++++++ - 5 files changed, 136 insertions(+), 1 deletion(-) - create mode 100644 gst/vaapi/gstvaapiparse.c - create mode 100644 gst/vaapi/gstvaapiparse.h + gst/vaapi/gsth264parse.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 9105d7f..4246b6e 100644 +index 3473ca8..078ca83 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c @@ -26,6 +26,7 @@ @@ -29,7 +23,7 @@ index 9105d7f..4246b6e 100644 #include #include #include -@@ -105,7 +106,8 @@ gst_h264_parse_class_init (GstH264ParseClass * klass) +@@ -121,7 +122,8 @@ gst_h264_parse_class_init (GstH264ParseClass * klass) GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass); GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); @@ -39,3 +33,6 @@ index 9105d7f..4246b6e 100644 gobject_class->finalize = gst_h264_parse_finalize; gobject_class->set_property = gst_h264_parse_set_property; +-- +2.1.4 + diff --git a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch index 02f17bf1e3..1635475ce5 100644 --- a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch +++ b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch @@ -1,15 +1,15 @@ -From 92908c46e7dd90063a613742f285e9c494c90d6f Mon Sep 17 00:00:00 2001 +From df5b8e09df21d96aaace4376318d5790d7c51cdc Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Apr 2014 17:17:04 +0200 Subject: [PATCH 2/3] h264parse: fix build with older GStreamer 1.x stacks. --- - gst/vaapi/gsth264parse.c | 4 +++- - gst/vaapi/gsth264parse.h | 1 + + gst/vaapi/gsth264parse.c | 4 +++- + gst/vaapi/gsth264parse.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 678c7f7..37ce228 100644 +index 078ca83..fceec68 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c @@ -27,7 +27,7 @@ @@ -21,7 +21,7 @@ index 678c7f7..37ce228 100644 #include #include #include "gsth264parse.h" -@@ -148,7 +148,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) +@@ -164,7 +164,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) { h264parse->frame_out = gst_adapter_new (); gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h264parse), FALSE); @@ -32,7 +32,7 @@ index 678c7f7..37ce228 100644 diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h -index 4c3fdd4..3db8f21 100644 +index e056ca2..56d2612 100644 --- a/gst/vaapi/gsth264parse.h +++ b/gst/vaapi/gsth264parse.h @@ -27,6 +27,7 @@ @@ -44,5 +44,5 @@ index 4c3fdd4..3db8f21 100644 G_BEGIN_DECLS -- -1.7.9.5 +2.1.4 diff --git a/patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch b/patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch index c86b3c9c0b..a1d2360955 100644 --- a/patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch +++ b/patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch @@ -1,7 +1,7 @@ -From 3885faab12f7bbcc862a3da191161bf91b0b8bd9 Mon Sep 17 00:00:00 2001 +From 134793f35f1a219c79b32b2d23df73ceff0b5e32 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 24 Jun 2014 17:27:12 +0200 -Subject: [PATCH 4/8] h264parse: default to byte-stream/nalu format (Annex B). +Subject: [PATCH 3/3] h264parse: default to byte-stream/nalu format (Annex B). Always default to stream-format=byte-stream,alignment=nalu if avcC format was not detected. This is the natural stream format specified @@ -12,14 +12,14 @@ https://bugzilla.gnome.org/show_bug.cgi?id=732167 Signed-off-by: Gwenole Beauchesne --- - gst/vaapi/gsth264parse.c | 5 +++-- + gst/vaapi/gsth264parse.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 7a88a07..4800c2b 100644 +index fceec68..f15b1b0 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c -@@ -367,7 +367,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, +@@ -393,7 +393,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, if (!format) format = GST_H264_PARSE_FORMAT_BYTE; if (!align) @@ -29,7 +29,7 @@ index 7a88a07..4800c2b 100644 GST_DEBUG_OBJECT (h264parse, "selected format %s, alignment %s", gst_h264_parse_get_string (h264parse, TRUE, format), -@@ -1893,7 +1894,7 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) +@@ -2204,7 +2205,7 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) if (format == GST_H264_PARSE_FORMAT_NONE) { format = GST_H264_PARSE_FORMAT_BYTE; @@ -39,5 +39,5 @@ index 7a88a07..4800c2b 100644 } -- -1.7.9.5 +2.1.4 From ef7dc4eaf6067f5086f43e1000f200d67004803c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 13 May 2015 11:54:01 +0200 Subject: [PATCH 1993/3781] build: fix make distcheck This patch fixes several issues found when running the `make distcheck` target: - In commit c561b8da, the update of gstcompat.h in Makefile.am was forgotten. - In commit c5756a91 add the simple_encoder_source_h in EXTRA_DIST was forgotten. - vpx.build.stamp is not generated at all, only vpx.configure.stamp. - The make target distcleancheck failed because some autogenerated files were not handled with the DISTCLEANFILES variable. Note: `make distcheck -jXX` is not currently supported. --- debian.upstream/Makefile.am | 1 + ext/libvpx/Makefile.am | 14 ++++++++++++-- gst-libs/gst/vaapi/Makefile.am | 2 +- gst/vaapi/Makefile.am | 1 + tests/Makefile.am | 1 + 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index 455ed08217..e05a66d04d 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -37,6 +37,7 @@ DEBIANGENFILES = \ EXTRA_DIST = $(DEBIANFILES) dist_noinst_DATA = $(DEBIANGENFILES) +DISTCLEANFILES = $(DEBIANGENFILES) # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = Makefile.in $(DEBIANGENFILES) diff --git a/ext/libvpx/Makefile.am b/ext/libvpx/Makefile.am index f945dce608..793026ec3d 100644 --- a/ext/libvpx/Makefile.am +++ b/ext/libvpx/Makefile.am @@ -69,11 +69,21 @@ vpx.build: vpx.configure.stamp vpx.clean: @[ -d $(vpx_builddir) ] && \ $(MAKE) -C $(vpx_builddir) clean || : - rm -f vpx.build.stamp vpx.configure.stamp + rm -f vpx.configure.stamp vpx.maintainer.clean: vpx.clean rm -rf $(vpx_builddir) +DISTCLEANFILES = \ + $(vpx_builddir)/config.mk \ + $(vpx_builddir)/config.log \ + $(vpx_builddir)/libs-x86_64-linux-gcc.mk \ + $(vpx_builddir)/Makefile \ + $(vpx_builddir)/vpx_config.c \ + $(vpx_builddir)/vpx_config.h \ + $(vpx_builddir)/vpx_config.asm \ + $(NULL) + vpx.configure.stamp: @[ -d $(vpx_builddir) ] || mkdir $(vpx_builddir); \ cd $(vpx_builddir) ; \ @@ -97,7 +107,7 @@ vpx.configure.stamp: $(gst_vpx_source_c): vpx.build -CLEANFILES = vpx.build.stamp +CLEANFILES = vpx.configure.stamp # Files for packaging include $(srcdir)/sources.frag diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 4c3551e666..bb0123b670 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -118,7 +118,6 @@ libgstvaapi_source_h = \ libgstvaapi_source_priv_h = \ glibcompat.h \ - gstcompat.h \ gstvaapibufferproxy_priv.h \ gstvaapicodec_objects.h \ gstvaapicompat.h \ @@ -574,6 +573,7 @@ $(PKG_VERSION_FILE): $(NEW_VERSION_FILE) BUILT_SOURCES = gstvaapiversion.h EXTRA_DIST = gstvaapiversion.h.in $(PKG_VERSION_FILE) +DISTCLEANFILES = $(BUILT_SOURCES) EXTRA_DIST += \ $(libgstvaapi_enc_source_c) \ diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index d63f1684a4..0dd3c990f6 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -62,6 +62,7 @@ libgstvaapi_source_c = \ $(NULL) libgstvaapi_source_h = \ + gstcompat.h \ gstvaapidecode.h \ gstvaapipluginbase.h \ gstvaapipluginutil.h \ diff --git a/tests/Makefile.am b/tests/Makefile.am index fa1ee3a42d..a852f4091b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -132,6 +132,7 @@ simple_encoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) EXTRA_DIST = \ test-subpicture-data.h \ $(simple_decoder_source_h) \ + $(simple_encoder_source_h) \ $(test_utils_dec_source_h) \ $(test_utils_source_h) \ $(NULL) From 77ab913ee6cddf250fea072baf059a8ccc26a367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 14 May 2015 16:22:36 +0200 Subject: [PATCH 1994/3781] vaapisink: fix indentation --- gst/vaapi/gstvaapisink.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 9392da55f3..a6a3ab5e15 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -127,11 +127,9 @@ enum static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; -static void -gst_vaapisink_video_overlay_expose (GstVideoOverlay * overlay); +static void gst_vaapisink_video_overlay_expose (GstVideoOverlay * overlay); -static gboolean -gst_vaapisink_reconfigure_window (GstVaapiSink * sink); +static gboolean gst_vaapisink_reconfigure_window (GstVaapiSink * sink); static void gst_vaapisink_set_event_handling (GstVaapiSink * sink, gboolean handle_events); @@ -1742,9 +1740,9 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) * This signal gets emitted after rendering the frame. */ gst_vaapisink_signals[HANDOFF_SIGNAL] = - g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, - G_TYPE_NONE, 1, GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, + G_TYPE_NONE, 1, GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE); } static void From 62c3888b76afc69f714a020957e8c5dd9d98f561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 7 May 2015 10:36:17 +0200 Subject: [PATCH 1995/3781] wayland: decouple wl_buffer from frame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch takes out the wayland's buffer from the the frame structure. The buffer is queued to wayland and destroyed in the "release" callback. The frame is freed in the surface's "done" callback. In this way a buffer may be leaked but not the whole frame structure. - surface 'done' callback is used to throttle the rendering operation and to unallocate the frame, but not the buffer. - buffer 'release' callback is used to destroy wl_buffer. Original-patch-by: Zhao Halley * code rebase * kept the the event_queue for buffer's proxy Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=749078 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 25 +++++++++------------ 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index dbbaa2fcb9..0d691ad4b2 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -55,7 +55,6 @@ struct _FrameState GstVaapiWindow *window; GstVaapiSurface *surface; GstVaapiVideoPool *surface_pool; - struct wl_buffer *buffer; struct wl_callback *callback; }; @@ -71,7 +70,6 @@ frame_state_new (GstVaapiWindow * window) frame->window = window; frame->surface = NULL; frame->surface_pool = NULL; - frame->buffer = NULL; frame->callback = NULL; return frame; } @@ -89,11 +87,6 @@ frame_state_free (FrameState * frame) } gst_vaapi_video_pool_replace (&frame->surface_pool, NULL); - if (frame->buffer) { - wl_buffer_destroy (frame->buffer); - frame->buffer = NULL; - } - if (frame->callback) { wl_callback_destroy (frame->callback); frame->callback = NULL; @@ -162,11 +155,10 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + struct wl_display *const wl_display = + GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); while (priv->frame_pending) { - struct wl_display *const wl_display = - GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - if (wl_display_dispatch_queue (wl_display, priv->event_queue) < 0) return FALSE; } @@ -328,8 +320,11 @@ frame_done_callback (void *data, struct wl_callback *callback, uint32_t time) GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); - if (priv->frame == frame) + if (priv->frame == frame) { priv->frame_pending = FALSE; + frame_state_free (frame); + priv->frame = NULL; + } } static const struct wl_callback_listener frame_callback_listener = { @@ -339,7 +334,7 @@ static const struct wl_callback_listener frame_callback_listener = { static void frame_release_callback (void *data, struct wl_buffer *wl_buffer) { - frame_state_free (data); + wl_buffer_destroy (wl_buffer); } static const struct wl_buffer_listener frame_buffer_listener = { @@ -500,9 +495,11 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, priv->opaque_region = NULL; } - frame->buffer = buffer; + /* @TODO: It is not OK to use internal event_queue here, since there + * may still be a WL_BUFFER_RELEASE event when we destroy the + * event_queue in gst_vaapi_window_wayland_destroy (). */ wl_proxy_set_queue ((struct wl_proxy *) buffer, priv->event_queue); - wl_buffer_add_listener (buffer, &frame_buffer_listener, frame); + wl_buffer_add_listener (buffer, &frame_buffer_listener, NULL); frame->callback = wl_surface_frame (priv->surface); wl_callback_add_listener (frame->callback, &frame_callback_listener, frame); From c80951ada12758d00e6a2305aebe2792f52c45cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 7 May 2015 11:18:12 +0200 Subject: [PATCH 1996/3781] wayland: use a counter as sync flag Wayland window has a pointer to the last pushed frame and use it to set the flag for stopping the queue dispatch loop. This may lead to memory leaks, since we are not keeping track of all the queued frames structures. This patch removes the last pushed frame pointer and change the binary flag for an atomic counter, keeping track of number of queued frames and use it for the queue dispatch loop. https://bugzilla.gnome.org/show_bug.cgi?id=749078 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 0d691ad4b2..8ee907c44d 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -107,7 +107,7 @@ struct _GstVaapiWindowWaylandPrivate guint is_shown:1; guint fullscreen_on_show:1; guint use_vpp:1; - guint frame_pending:1; + volatile guint num_frames_pending; }; /** @@ -158,7 +158,7 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) struct wl_display *const wl_display = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - while (priv->frame_pending) { + while (g_atomic_int_get (&priv->num_frames_pending) > 0) { if (wl_display_dispatch_queue (wl_display, priv->event_queue) < 0) return FALSE; } @@ -321,10 +321,10 @@ frame_done_callback (void *data, struct wl_callback *callback, uint32_t time) GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); if (priv->frame == frame) { - priv->frame_pending = FALSE; - frame_state_free (frame); priv->frame = NULL; } + frame_state_free (frame); + g_atomic_int_dec_and_test (&priv->num_frames_pending); } static const struct wl_callback_listener frame_callback_listener = { @@ -477,7 +477,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, if (!frame) return FALSE; priv->frame = frame; - priv->frame_pending = TRUE; + g_atomic_int_inc (&priv->num_frames_pending); if (need_vpp && priv->use_vpp) { frame->surface = surface; From 882387de30c20a64d0318ced01b023e9b831e40b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 7 May 2015 18:30:33 +0200 Subject: [PATCH 1997/3781] wayland: rename frame for last_frame Since frame in the private data means the last frame sent, it would semantically better use last_frame. Also, this patch makes use of g_atomic_pointer_{compare_and_exchange, set}() functions. https://bugzilla.gnome.org/show_bug.cgi?id=749078 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 8ee907c44d..9015c39bbf 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -100,7 +100,7 @@ struct _GstVaapiWindowWaylandPrivate struct wl_surface *surface; struct wl_region *opaque_region; struct wl_event_queue *event_queue; - FrameState *frame; + FrameState *last_frame; GstVideoFormat surface_format; GstVaapiVideoPool *surface_pool; GstVaapiFilter *filter; @@ -267,9 +267,9 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); - if (priv->frame) { - frame_state_free (priv->frame); - priv->frame = NULL; + if (priv->last_frame) { + frame_state_free (priv->last_frame); + priv->last_frame = NULL; } if (priv->shell_surface) { @@ -320,9 +320,7 @@ frame_done_callback (void *data, struct wl_callback *callback, uint32_t time) GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); - if (priv->frame == frame) { - priv->frame = NULL; - } + g_atomic_pointer_compare_and_exchange (&priv->last_frame, frame, NULL); frame_state_free (frame); g_atomic_int_dec_and_test (&priv->num_frames_pending); } @@ -476,7 +474,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, frame = frame_state_new (window); if (!frame) return FALSE; - priv->frame = frame; + g_atomic_pointer_set (&priv->last_frame, frame); g_atomic_int_inc (&priv->num_frames_pending); if (need_vpp && priv->use_vpp) { From 522ec79d2e5c641ca2861689e9a63a6782739d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 7 May 2015 12:33:34 +0200 Subject: [PATCH 1998/3781] wayland: wl_display_dispatch_queue() can block forever. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit wl_display_dispatch_queue() might prevent the pipeline from shutting down. This can happen e.g. if the wayland compositor exits while the pipeline is running. This patch replaces it with these steps: - With wl_display_prepare_read() all threads announce their intention to read. - wl_display_read_events() is thread save. On threads reads, the other wait for it to finish. - With wl_display_dispatch_queue_pending() each thread dispatches its own events. wl_display_dispatch_queue_pending() was defined since wayland 1.0.2 Original-patch-by: Michael Olbrich * stripped out the unlock() unlock_stop() logic * stripped out the poll handling Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=749078 https://bugzilla.gnome.org/show_bug.cgi?id=747492 --- configure.ac | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 22ff810725..34fe92b3da 100644 --- a/configure.ac +++ b/configure.ac @@ -38,7 +38,7 @@ m4_define([gst16_plugins_base_version], [1.5.0]) m4_define([gst16_plugins_bad_version], [1.5.0]) # Wayland minimum version number -m4_define([wayland_api_version], [1.0.0]) +m4_define([wayland_api_version], [1.0.2]) # VA-API minimum version number m4_define([va_api_version], [0.30.4]) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 9015c39bbf..efb455ca3c 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -159,10 +159,23 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); while (g_atomic_int_get (&priv->num_frames_pending) > 0) { - if (wl_display_dispatch_queue (wl_display, priv->event_queue) < 0) - return FALSE; + while (wl_display_prepare_read_queue (wl_display, priv->event_queue) < 0) { + if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) + goto error; + } + + if (wl_display_flush (wl_display) < 0) + goto error; + if (wl_display_read_events (wl_display) < 0) + goto error; + if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) + goto error; } return TRUE; + +error: + GST_ERROR ("Error on dispatching events: %s", g_strerror (errno)); + return FALSE; } static void From 11b9260b6c40d9a87b4e30aed78d2583f306f0ff Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Thu, 7 May 2015 15:55:40 +0200 Subject: [PATCH 1999/3781] vaapisink: implement unlock/unlock_stop for wayland MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise wl_display_dispatch_queue() might prevent the pipeline from shutting down. This can happen e.g. if the wayland compositor exits while the pipeline is running. Changes: * renamed unlock()/unlock_stop() to unblock()/unblock_cancel() in gstvaapiwindow * splitted the patch removing wl_display_dispatch_queue() Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=747492 https://bugzilla.gnome.org/show_bug.cgi?id=749078 --- gst-libs/gst/vaapi/gstvaapiwindow.c | 42 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow.h | 6 +++ gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 7 +++ gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 50 +++++++++++++++++++++ gst/vaapi/gstvaapisink.c | 24 ++++++++++ 5 files changed, 129 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index c8956826a5..2480ee63bf 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -509,3 +509,45 @@ gst_vaapi_window_reconfigure (GstVaapiWindow * window) window->check_geometry = TRUE; gst_vaapi_window_ensure_size (window); } + +/** + * gst_vaapi_window_unblock: + * @window: a #GstVaapiWindow + * + * Unblocks a rendering surface operation. + */ +gboolean +gst_vaapi_window_unblock (GstVaapiWindow * window) +{ + const GstVaapiWindowClass *klass; + + g_return_val_if_fail (window != NULL, FALSE); + + klass = GST_VAAPI_WINDOW_GET_CLASS (window); + + if (klass->unblock) + return klass->unblock (window); + + return TRUE; +} + +/** + * gst_vaapi_window_unblock_cancel: + * @window: a #GstVaapiWindow + * + * Cancels the previous unblock request. + */ +gboolean +gst_vaapi_window_unblock_cancel (GstVaapiWindow * window) +{ + const GstVaapiWindowClass *klass; + + g_return_val_if_fail (window != NULL, FALSE); + + klass = GST_VAAPI_WINDOW_GET_CLASS (window); + + if (klass->unblock_cancel) + return klass->unblock_cancel (window); + + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 64ee3e50e4..c2d895441f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -99,6 +99,12 @@ gst_vaapi_window_put_pixmap (GstVaapiWindow * window, GstVaapiPixmap * pixmap, void gst_vaapi_window_reconfigure (GstVaapiWindow * window); +gboolean +gst_vaapi_window_unblock (GstVaapiWindow * window); + +gboolean +gst_vaapi_window_unblock_cancel (GstVaapiWindow * window); + G_END_DECLS #endif /* GST_VAAPI_WINDOW_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index 08cd90c3c5..3d0a59639e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -54,6 +54,8 @@ typedef gboolean (*GstVaapiWindowRenderPixmapFunc) (GstVaapiWindow * window, const GstVaapiRectangle * dst_rect); typedef guintptr (*GstVaapiWindowGetVisualIdFunc) (GstVaapiWindow * window); typedef guintptr (*GstVaapiWindowGetColormapFunc) (GstVaapiWindow * window); +typedef gboolean (*GstVaapiWindowSetUnblockFunc) (GstVaapiWindow * window); +typedef gboolean (*GstVaapiWindowSetUnblockCancelFunc) (GstVaapiWindow * window); /** * GstVaapiWindow: @@ -88,6 +90,9 @@ struct _GstVaapiWindow * create the window * @get_colormap: virtual function to get the desired colormap used to * create the window, or the currently allocated one + * @unblock: virtual function to unblock a rendering surface operation + * @unblock_cancel: virtual function to cancel the previous unblock + * request. * * Base class for system-dependent windows. */ @@ -107,6 +112,8 @@ struct _GstVaapiWindowClass GstVaapiWindowRenderPixmapFunc render_pixmap; GstVaapiWindowGetVisualIdFunc get_visual_id; GstVaapiWindowGetColormapFunc get_colormap; + GstVaapiWindowSetUnblockFunc unblock; + GstVaapiWindowSetUnblockCancelFunc unblock_cancel; }; GstVaapiWindow * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index efb455ca3c..00b5ef115a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -104,6 +104,8 @@ struct _GstVaapiWindowWaylandPrivate GstVideoFormat surface_format; GstVaapiVideoPool *surface_pool; GstVaapiFilter *filter; + GstPoll *poll; + GstPollFD pollfd; guint is_shown:1; guint fullscreen_on_show:1; guint use_vpp:1; @@ -158,6 +160,12 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) struct wl_display *const wl_display = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); + if (priv->pollfd.fd < 0) { + priv->pollfd.fd = wl_display_get_fd (wl_display); + gst_poll_add_fd (priv->poll, &priv->pollfd); + gst_poll_fd_ctl_read (priv->poll, &priv->pollfd, TRUE); + } + while (g_atomic_int_get (&priv->num_frames_pending) > 0) { while (wl_display_prepare_read_queue (wl_display, priv->event_queue) < 0) { if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) @@ -166,6 +174,19 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) if (wl_display_flush (wl_display) < 0) goto error; + + again: + if (gst_poll_wait (priv->poll, GST_CLOCK_TIME_NONE) < 0) { + int saved_errno = errno; + if (saved_errno == EAGAIN || saved_errno == EINTR) + goto again; + if (saved_errno == EBUSY) { /* closing */ + wl_display_cancel_read (wl_display); + break; + } + goto error; + } + if (wl_display_read_events (wl_display) < 0) goto error; if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) @@ -264,6 +285,9 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window, &shell_surface_listener, priv); wl_shell_surface_set_toplevel (priv->shell_surface); + priv->poll = gst_poll_new (TRUE); + gst_poll_fd_init (&priv->pollfd); + if (priv->fullscreen_on_show) gst_vaapi_window_wayland_set_fullscreen (window, TRUE); @@ -302,6 +326,8 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) gst_vaapi_filter_replace (&priv->filter, NULL); gst_vaapi_video_pool_replace (&priv->surface_pool, NULL); + + gst_poll_free (priv->poll); } static gboolean @@ -521,6 +547,28 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, return TRUE; } +static gboolean +gst_vaapi_window_wayland_unblock (GstVaapiWindow * window) +{ + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + + gst_poll_set_flushing (priv->poll, TRUE); + + return TRUE; +} + +static gboolean +gst_vaapi_window_wayland_unblock_cancel (GstVaapiWindow * window) +{ + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + + gst_poll_set_flushing (priv->poll, FALSE); + + return TRUE; +} + static void gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass) { @@ -536,6 +584,8 @@ gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass) window_class->render = gst_vaapi_window_wayland_render; window_class->resize = gst_vaapi_window_wayland_resize; window_class->set_fullscreen = gst_vaapi_window_wayland_set_fullscreen; + window_class->unblock = gst_vaapi_window_wayland_unblock; + window_class->unblock_cancel = gst_vaapi_window_wayland_unblock_cancel; } #define gst_vaapi_window_wayland_finalize \ diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index a6a3ab5e15..bc89cff7c5 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1550,6 +1550,28 @@ gst_vaapisink_get_property (GObject * object, } } +static gboolean +gst_vaapisink_unlock (GstBaseSink * base_sink) +{ + GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); + + if (sink->window) + return gst_vaapi_window_unblock (sink->window); + + return TRUE; +} + +static gboolean +gst_vaapisink_unlock_stop (GstBaseSink * base_sink) +{ + GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); + + if (sink->window) + return gst_vaapi_window_unblock_cancel (sink->window); + + return TRUE; +} + static void gst_vaapisink_set_bus (GstElement * element, GstBus * bus) { @@ -1591,6 +1613,8 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) basesink_class->set_caps = gst_vaapisink_set_caps; basesink_class->query = GST_DEBUG_FUNCPTR (gst_vaapisink_query); basesink_class->propose_allocation = gst_vaapisink_propose_allocation; + basesink_class->unlock = gst_vaapisink_unlock; + basesink_class->unlock_stop = gst_vaapisink_unlock_stop; videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_vaapisink_show_frame); From 70eff01d36a2870cbf06ffb91c2a941e8cb6b804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 7 May 2015 11:28:15 +0200 Subject: [PATCH 2000/3781] wayland: sync() when destroy() Before pushing a the new frame, the render() method calls sync() to flush the pending frames. Nonetheless, the last pushed frame never gets rendered, leading to a memory leak too. This patch calls sync() in the destroy() to flush the pending frames before destroying the window. Also a is_cancelled flag is added. This flag tells to not flush the event queue again since the method failed previously or were cancelled by the user. https://bugzilla.gnome.org/show_bug.cgi?id=749078 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 00b5ef115a..95e34e6b94 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -109,6 +109,7 @@ struct _GstVaapiWindowWaylandPrivate guint is_shown:1; guint fullscreen_on_show:1; guint use_vpp:1; + guint is_cancelled:1; volatile guint num_frames_pending; }; @@ -160,6 +161,9 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) struct wl_display *const wl_display = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); + if (priv->is_cancelled) + return FALSE; + if (priv->pollfd.fd < 0) { priv->pollfd.fd = wl_display_get_fd (wl_display); gst_poll_add_fd (priv->poll, &priv->pollfd); @@ -182,6 +186,7 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) goto again; if (saved_errno == EBUSY) { /* closing */ wl_display_cancel_read (wl_display); + priv->is_cancelled = TRUE; break; } goto error; @@ -195,6 +200,7 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) return TRUE; error: + priv->is_cancelled = TRUE; GST_ERROR ("Error on dispatching events: %s", g_strerror (errno)); return FALSE; } @@ -304,6 +310,9 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + /* Wait for the last frame to complete redraw */ + gst_vaapi_window_wayland_sync (window); + if (priv->last_frame) { frame_state_free (priv->last_frame); priv->last_frame = NULL; @@ -507,8 +516,15 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, } /* Wait for the previous frame to complete redraw */ - if (!gst_vaapi_window_wayland_sync (window)) + if (!gst_vaapi_window_wayland_sync (window)) { + wl_buffer_destroy (buffer); return FALSE; + } + + if (priv->is_cancelled) { + wl_buffer_destroy (buffer); + return TRUE; + } frame = frame_state_new (window); if (!frame) From 89e41fc8e35209b37665a8c45721285d0fd45751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 13 May 2015 10:38:24 +0200 Subject: [PATCH 2001/3781] build: use git.mk This patch handles dinamically the gitignore files with git.mk[1]. Removed the automake variable MAINTAINERCLANFILES in most of the Makefile.am files since now it is handled by the top one. 1. https://github.com/behdad/git.mk/blob/master/git.mk https://bugzilla.gnome.org/show_bug.cgi?id=749321 --- .gitignore | 73 ------ Makefile.am | 10 +- debian.upstream/Makefile.am | 3 +- docs/Makefile.am | 3 +- docs/reference/Makefile.am | 3 +- docs/reference/libs/Makefile.am | 3 +- docs/reference/plugins/Makefile.am | 3 +- ext/Makefile.am | 3 +- ext/libvpx/Makefile.am | 3 +- git.mk | 333 ++++++++++++++++++++++++++ gst-libs/Makefile.am | 3 +- gst-libs/gst/Makefile.am | 3 +- gst-libs/gst/base/Makefile.am | 3 +- gst-libs/gst/codecparsers/Makefile.am | 3 +- gst-libs/gst/vaapi/Makefile.am | 3 +- gst/Makefile.am | 3 +- gst/vaapi/Makefile.am | 3 +- patches/Makefile.am | 3 +- patches/videoparsers/Makefile.am | 3 +- pkgconfig/Makefile.am | 3 +- tests/Makefile.am | 3 +- 21 files changed, 358 insertions(+), 112 deletions(-) delete mode 100644 .gitignore create mode 100644 git.mk diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0ff526c3f9..0000000000 --- a/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -ABOUT-NLS -_stdint.h -aclocal.m4 -autom4te.cache -autoregen.sh -compile -config.guess -config.h* -config.log -config.rpath -config.status -config.sub -configure -depcomp -gst-element-check-*.m4 -gstreamer-vaapi-*.tar.gz -install-sh -libtool -ltmain.sh -missing -mkinstalldirs -stamp-h -stamp-h.in -stamp-h1 - -/m4 - -.deps -.libs -*.lo -*.la -*.o -Makefile.in -Makefile -*~ -*.swp - -debian.build/ -debian.upstream/changelog -debian.upstream/control -debian.upstream/gstreamer0.10-vaapi-doc.install -debian.upstream/gstreamer0.10-vaapi.install -debian.upstream/libgstvaapi-dev.install -debian.upstream/libgstvaapi-drm-0.install -debian.upstream/libgstvaapi-glx-0.install -debian.upstream/libgstvaapi-wayland-0.install -debian.upstream/libgstvaapi-x11-0.install -debian.upstream/libgstvaapi0.install -docs/reference/libs/*.stamp -docs/reference/libs/html* -docs/reference/libs/libs-docs.xml -docs/reference/libs/tmpl* -docs/reference/libs/xml* -docs/reference/plugins/*.stamp -docs/reference/plugins/html* -docs/reference/plugins/plugins-docs.xml -docs/reference/plugins/tmpl* -docs/reference/plugins/xml* -gst-libs/gst/codecparsers/*.[ch] -gst-libs/gst/codecparsers/.timestamp.* -gst-libs/gst/gstutils_version.h -gtk-doc.make -pkgconfig/gstreamer-vaapi-0.10.pc -pkgconfig/gstreamer-vaapi-drm-0.10.pc -pkgconfig/gstreamer-vaapi-glx-0.10.pc -pkgconfig/gstreamer-vaapi-wayland-0.10.pc -pkgconfig/gstreamer-vaapi-x11-0.10.pc -tests/test-decode -tests/test-display -tests/test-subpicture -tests/test-surfaces -tests/test-textures -tests/test-windows diff --git a/Makefile.am b/Makefile.am index b3332012b6..9331c49ca1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,9 +6,11 @@ SUBDIRS = debian.upstream ext gst-libs gst pkgconfig tests docs patches # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ - aclocal.m4 compile config.guess config.sub \ - configure depcomp install-sh ltmain.sh \ - Makefile.in missing config.h.in gtk-doc.make + $(GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL) \ + $(GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN) \ + $(GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL) \ + $(srcdir)/gtk-doc.make $(srcdir)/m4/gtk-doc.m4 \ + $(NULL) DEB_BUILDDIR = debian.build @@ -23,3 +25,5 @@ deb.upstream: dist-bzip2 cd $(PACKAGE)-$(VERSION) && \ $(LN_S) debian.upstream debian && \ $(MAKE) deb -f Makefile.am + +-include $(top_srcdir)/git.mk diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index e05a66d04d..fd5dad5bbb 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -39,5 +39,4 @@ EXTRA_DIST = $(DEBIANFILES) dist_noinst_DATA = $(DEBIANGENFILES) DISTCLEANFILES = $(DEBIANGENFILES) -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in $(DEBIANGENFILES) +-include $(top_srcdir)/git.mk diff --git a/docs/Makefile.am b/docs/Makefile.am index 58bb28723e..1feb33d768 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -6,5 +6,4 @@ endif DIST_SUBDIRS = reference -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am index 3eef00ec9e..28657ac1f7 100644 --- a/docs/reference/Makefile.am +++ b/docs/reference/Makefile.am @@ -1,4 +1,3 @@ SUBDIRS = libs plugins -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index bda6fe62dd..036bd7dcc0 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -123,5 +123,4 @@ EXTRA_DIST += \ libs-docs.xml.in \ $(NULL) -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in lib-docs.xml +-include $(top_srcdir)/git.mk diff --git a/docs/reference/plugins/Makefile.am b/docs/reference/plugins/Makefile.am index 6b89cade56..d3e204048f 100644 --- a/docs/reference/plugins/Makefile.am +++ b/docs/reference/plugins/Makefile.am @@ -104,5 +104,4 @@ EXTRA_DIST += \ $(DOC_MODULE)-docs.xml.in \ $(NULL) -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in $(DOC_MODULE)-docs.xml +-include $(top_srcdir)/git.mk diff --git a/ext/Makefile.am b/ext/Makefile.am index d6085815e6..537e18f52f 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -56,5 +56,4 @@ videoparsers_source_h = \ EXTRA_DIST += $(videoparsers_source_h:%.h=$(videoparsers_srcdir)/%.h) -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/ext/libvpx/Makefile.am b/ext/libvpx/Makefile.am index 793026ec3d..d54c298e2f 100644 --- a/ext/libvpx/Makefile.am +++ b/ext/libvpx/Makefile.am @@ -148,5 +148,4 @@ dist-hook: cp -fpR $(vpx_srcdir)/$$f $(distdir)/$(vpx_upstream)/$$f; \ done -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in vpx.configure.stamp +-include $(top_srcdir)/git.mk diff --git a/git.mk b/git.mk new file mode 100644 index 0000000000..9d4bf2511e --- /dev/null +++ b/git.mk @@ -0,0 +1,333 @@ +# git.mk, a small Makefile to autogenerate .gitignore files +# for autotools-based projects. +# +# Copyright 2009, Red Hat, Inc. +# Copyright 2010,2011,2012,2013 Behdad Esfahbod +# Written by Behdad Esfahbod +# +# Copying and distribution of this file, with or without modification, +# is permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +# +# The latest version of this file can be downloaded from: +GIT_MK_URL = https://raw.githubusercontent.com/behdad/git.mk/master/git.mk +# +# Bugs, etc, should be reported upstream at: +# https://github.com/behdad/git.mk +# +# To use in your project, import this file in your git repo's toplevel, +# then do "make -f git.mk". This modifies all Makefile.am files in +# your project to -include git.mk. Remember to add that line to new +# Makefile.am files you create in your project, or just rerun the +# "make -f git.mk". +# +# This enables automatic .gitignore generation. If you need to ignore +# more files, add them to the GITIGNOREFILES variable in your Makefile.am. +# But think twice before doing that. If a file has to be in .gitignore, +# chances are very high that it's a generated file and should be in one +# of MOSTLYCLEANFILES, CLEANFILES, DISTCLEANFILES, or MAINTAINERCLEANFILES. +# +# The only case that you need to manually add a file to GITIGNOREFILES is +# when remove files in one of mostlyclean-local, clean-local, distclean-local, +# or maintainer-clean-local make targets. +# +# Note that for files like editor backup, etc, there are better places to +# ignore them. See "man gitignore". +# +# If "make maintainer-clean" removes the files but they are not recognized +# by this script (that is, if "git status" shows untracked files still), send +# me the output of "git status" as well as your Makefile.am and Makefile for +# the directories involved and I'll diagnose. +# +# For a list of toplevel files that should be in MAINTAINERCLEANFILES, see +# Makefile.am.sample in the git.mk git repo. +# +# Don't EXTRA_DIST this file. It is supposed to only live in git clones, +# not tarballs. It serves no useful purpose in tarballs and clutters the +# build dir. +# +# This file knows how to handle autoconf, automake, libtool, gtk-doc, +# gnome-doc-utils, yelp.m4, mallard, intltool, gsettings, dejagnu, appdata, +# appstream. +# +# This makefile provides the following targets: +# +# - all: "make all" will build all gitignore files. +# - gitignore: makes all gitignore files in the current dir and subdirs. +# - .gitignore: make gitignore file for the current dir. +# - gitignore-recurse: makes all gitignore files in the subdirs. +# +# KNOWN ISSUES: +# +# - Recursive configure doesn't work as $(top_srcdir)/git.mk inside the +# submodule doesn't find us. If you have configure.{in,ac} files in +# subdirs, add a proxy git.mk file in those dirs that simply does: +# "include $(top_srcdir)/../git.mk". Add more ..'s to your taste. +# And add those files to git. See vte/gnome-pty-helper/git.mk for +# example. +# + + + +############################################################################### +# Variables user modules may want to add to toplevel MAINTAINERCLEANFILES: +############################################################################### + +# +# Most autotools-using modules should be fine including this variable in their +# toplevel MAINTAINERCLEANFILES: +GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL = \ + $(srcdir)/aclocal.m4 \ + $(srcdir)/autoscan.log \ + $(srcdir)/configure.scan \ + `AUX_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_AUX_DIR:$$1' ./configure.ac); \ + test "x$$AUX_DIR" = "x$(srcdir)/" && AUX_DIR=$(srcdir); \ + for x in \ + ar-lib \ + compile \ + config.guess \ + config.sub \ + depcomp \ + install-sh \ + ltmain.sh \ + missing \ + mkinstalldirs \ + test-driver \ + ylwrap \ + ; do echo "$$AUX_DIR/$$x"; done` \ + `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_HEADERS:$$1' ./configure.ac | \ + head -n 1 | while read f; do echo "$(srcdir)/$$f.in"; done` +# +# All modules should also be fine including the following variable, which +# removes automake-generated Makefile.in files: +GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN = \ + `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_FILES:$$1' ./configure.ac | \ + while read f; do \ + case $$f in Makefile|*/Makefile) \ + test -f "$(srcdir)/$$f.am" && echo "$(srcdir)/$$f.in";; esac; \ + done` +# +# Modules that use libtool and use AC_CONFIG_MACRO_DIR() may also include this, +# though it's harmless to include regardless. +GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL = \ + `MACRO_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_MACRO_DIR:$$1' ./configure.ac); \ + if test "x$$MACRO_DIR" != "x$(srcdir)/"; then \ + for x in \ + libtool.m4 \ + ltoptions.m4 \ + ltsugar.m4 \ + ltversion.m4 \ + lt~obsolete.m4 \ + ; do echo "$$MACRO_DIR/$$x"; done; \ + fi` + + + +############################################################################### +# Default rule is to install ourselves in all Makefile.am files: +############################################################################### + +git-all: git-mk-install + +git-mk-install: + @echo "Installing git makefile" + @any_failed=; \ + find "`test -z "$(top_srcdir)" && echo . || echo "$(top_srcdir)"`" -name Makefile.am | while read x; do \ + if grep 'include .*/git.mk' $$x >/dev/null; then \ + echo "$$x already includes git.mk"; \ + else \ + failed=; \ + echo "Updating $$x"; \ + { cat $$x; \ + echo ''; \ + echo '-include $$(top_srcdir)/git.mk'; \ + } > $$x.tmp || failed=1; \ + if test x$$failed = x; then \ + mv $$x.tmp $$x || failed=1; \ + fi; \ + if test x$$failed = x; then : else \ + echo "Failed updating $$x"; >&2 \ + any_failed=1; \ + fi; \ + fi; done; test -z "$$any_failed" + +git-mk-update: + wget $(GIT_MK_URL) -O $(top_srcdir)/git.mk + +.PHONY: git-all git-mk-install git-mk-update + + + +############################################################################### +# Actual .gitignore generation: +############################################################################### + +$(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk + @echo "git.mk: Generating $@" + @{ \ + if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \ + for x in \ + $(DOC_MODULE)-decl-list.txt \ + $(DOC_MODULE)-decl.txt \ + tmpl/$(DOC_MODULE)-unused.sgml \ + "tmpl/*.bak" \ + xml html \ + ; do echo "/$$x"; done; \ + FLAVOR=$$(cd $(top_srcdir); $(AUTOCONF) --trace 'GTK_DOC_CHECK:$$2' ./configure.ac); \ + case $$FLAVOR in *no-tmpl*) echo /tmpl;; esac; \ + fi; \ + if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \ + for lc in $(DOC_LINGUAS); do \ + for x in \ + $(if $(DOC_MODULE),$(DOC_MODULE).xml) \ + $(DOC_PAGES) \ + $(DOC_INCLUDES) \ + ; do echo "/$$lc/$$x"; done; \ + done; \ + for x in \ + $(_DOC_OMF_ALL) \ + $(_DOC_DSK_ALL) \ + $(_DOC_HTML_ALL) \ + $(_DOC_MOFILES) \ + $(DOC_H_FILE) \ + "*/.xml2po.mo" \ + "*/*.omf.out" \ + ; do echo /$$x; done; \ + fi; \ + if test "x$(HELP_ID)" = x -o "x$(HELP_LINGUAS)" = x; then :; else \ + for lc in $(HELP_LINGUAS); do \ + for x in \ + $(HELP_FILES) \ + "$$lc.stamp" \ + "$$lc.mo" \ + ; do echo "/$$lc/$$x"; done; \ + done; \ + fi; \ + if test "x$(gsettings_SCHEMAS)" = x; then :; else \ + for x in \ + $(gsettings_SCHEMAS:.xml=.valid) \ + $(gsettings__enum_file) \ + ; do echo "/$$x"; done; \ + fi; \ + if test "x$(appdata_XML)" = x; then :; else \ + for x in \ + $(appdata_XML:.xml=.valid) \ + ; do echo "/$$x"; done; \ + fi; \ + if test "x$(appstream_XML)" = x; then :; else \ + for x in \ + $(appstream_XML:.xml=.valid) \ + ; do echo "/$$x"; done; \ + fi; \ + if test -f $(srcdir)/po/Makefile.in.in; then \ + for x in \ + po/Makefile.in.in \ + po/Makefile.in.in~ \ + po/Makefile.in \ + po/Makefile \ + po/Makevars.template \ + po/POTFILES \ + po/Rules-quot \ + po/stamp-it \ + po/.intltool-merge-cache \ + "po/*.gmo" \ + "po/*.header" \ + "po/*.mo" \ + "po/*.sed" \ + "po/*.sin" \ + po/$(GETTEXT_PACKAGE).pot \ + intltool-extract.in \ + intltool-merge.in \ + intltool-update.in \ + ; do echo "/$$x"; done; \ + fi; \ + if test -f $(srcdir)/configure; then \ + for x in \ + autom4te.cache \ + configure \ + config.h \ + stamp-h1 \ + libtool \ + config.lt \ + ; do echo "/$$x"; done; \ + fi; \ + if test "x$(DEJATOOL)" = x; then :; else \ + for x in \ + $(DEJATOOL) \ + ; do echo "/$$x.sum"; echo "/$$x.log"; done; \ + echo /site.exp; \ + fi; \ + if test "x$(am__dirstamp)" = x; then :; else \ + echo "$(am__dirstamp)"; \ + fi; \ + if test "x$(LTCOMPILE)" = x -a "x$(LTCXXCOMPILE)" = x -a "x$(GTKDOC_RUN)" = x; then :; else \ + for x in \ + "*.lo" \ + ".libs" "_libs" \ + ; do echo "$$x"; done; \ + fi; \ + for x in \ + .gitignore \ + $(GITIGNOREFILES) \ + $(CLEANFILES) \ + $(PROGRAMS) $(check_PROGRAMS) $(EXTRA_PROGRAMS) \ + $(LIBRARIES) $(check_LIBRARIES) $(EXTRA_LIBRARIES) \ + $(LTLIBRARIES) $(check_LTLIBRARIES) $(EXTRA_LTLIBRARIES) \ + so_locations \ + $(MOSTLYCLEANFILES) \ + $(TEST_LOGS) \ + $(TEST_LOGS:.log=.trs) \ + $(TEST_SUITE_LOG) \ + $(TESTS:=.test) \ + "*.gcda" \ + "*.gcno" \ + $(DISTCLEANFILES) \ + $(am__CONFIG_DISTCLEAN_FILES) \ + $(CONFIG_CLEAN_FILES) \ + TAGS ID GTAGS GRTAGS GSYMS GPATH tags \ + "*.tab.c" \ + $(MAINTAINERCLEANFILES) \ + $(BUILT_SOURCES) \ + $(patsubst %.vala,%.c,$(filter %.vala,$(SOURCES))) \ + $(filter %_vala.stamp,$(DIST_COMMON)) \ + $(filter %.vapi,$(DIST_COMMON)) \ + $(filter $(addprefix %,$(notdir $(patsubst %.vapi,%.h,$(filter %.vapi,$(DIST_COMMON))))),$(DIST_COMMON)) \ + Makefile \ + Makefile.in \ + "*.orig" \ + "*.rej" \ + "*.bak" \ + "*~" \ + ".*.sw[nop]" \ + ".dirstamp" \ + ; do echo "/$$x"; done; \ + for x in \ + "*.$(OBJEXT)" \ + $(DEPDIR) \ + ; do echo "$$x"; done; \ + } | \ + sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \ + sed 's@/[.]/@/@g' | \ + LC_ALL=C sort | uniq > $@.tmp && \ + mv $@.tmp $@; + +all: $(srcdir)/.gitignore gitignore-recurse-maybe +gitignore: $(srcdir)/.gitignore gitignore-recurse + +gitignore-recurse-maybe: + @for subdir in $(DIST_SUBDIRS); do \ + case " $(SUBDIRS) " in \ + *" $$subdir "*) :;; \ + *) test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir");; \ + esac; \ + done +gitignore-recurse: + @for subdir in $(DIST_SUBDIRS); do \ + test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir"); \ + done + +maintainer-clean: gitignore-clean +gitignore-clean: + -rm -f $(srcdir)/.gitignore + +.PHONY: gitignore-clean gitignore gitignore-recurse gitignore-recurse-maybe diff --git a/gst-libs/Makefile.am b/gst-libs/Makefile.am index d5356a6f97..85cb878323 100644 --- a/gst-libs/Makefile.am +++ b/gst-libs/Makefile.am @@ -1,4 +1,3 @@ SUBDIRS = gst -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 8acd19b055..77be8ee030 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -1,4 +1,3 @@ SUBDIRS = base codecparsers vaapi -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/base/Makefile.am b/gst-libs/gst/base/Makefile.am index b3c1dada20..87358734d8 100644 --- a/gst-libs/gst/base/Makefile.am +++ b/gst-libs/gst/base/Makefile.am @@ -44,5 +44,4 @@ EXTRA_DIST = \ $(source_h) \ $(NULL) -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index a160450cde..d164df63aa 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -107,5 +107,4 @@ EXTRA_DIST = gstvaapilibvpx.c DISTCLEANFILES = $(GENFILES) .timestamp.symlinks -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index bb0123b670..348e0c1860 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -601,5 +601,4 @@ CLEANFILES = \ $(PKG_VERSION_FILE) \ $(NULL) -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/gst/Makefile.am b/gst/Makefile.am index 37d365da29..80a5198af9 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -1,4 +1,3 @@ SUBDIRS = vaapi -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 0dd3c990f6..a66db37cce 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -255,5 +255,4 @@ EXTRA_DIST = \ $(libgstvaapi_1_4p_parse_gen_source_h) \ $(NULL) -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/patches/Makefile.am b/patches/Makefile.am index 0512fcaeb2..7591cb368a 100644 --- a/patches/Makefile.am +++ b/patches/Makefile.am @@ -1,4 +1,3 @@ SUBDIRS = videoparsers -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/patches/videoparsers/Makefile.am b/patches/videoparsers/Makefile.am index ec3b761285..401b2ad75e 100644 --- a/patches/videoparsers/Makefile.am +++ b/patches/videoparsers/Makefile.am @@ -2,5 +2,4 @@ include series.frag EXTRA_DIST = series.frag $(videoparsers_patches_base) -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index 25c3cb227f..2acc572a59 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -29,5 +29,4 @@ EXTRA_DIST = $(all_pcfiles_in) DISTCLEANFILES = $(all_pcfiles) -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk diff --git a/tests/Makefile.am b/tests/Makefile.am index a852f4091b..8fb3f95d55 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -137,5 +137,4 @@ EXTRA_DIST = \ $(test_utils_source_h) \ $(NULL) -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = Makefile.in +-include $(top_srcdir)/git.mk From e9866d065655821892c5686952a705584a0daa96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 6 May 2015 16:19:23 +0200 Subject: [PATCH 2002/3781] doc: update sections and symbols https://bugzilla.gnome.org/show_bug.cgi?id=749018 --- docs/reference/libs/libs-docs.xml.in | 14 ++ docs/reference/libs/libs-sections.txt | 197 ++++++++++++++++++++++++-- 2 files changed, 200 insertions(+), 11 deletions(-) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 45e05eab13..720e79f586 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -13,9 +13,15 @@ + + + + + + @@ -23,6 +29,8 @@ + + @@ -33,8 +41,14 @@ + + + + + + diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt index aa7b472ef1..4cdc2f8d4c 100644 --- a/docs/reference/libs/libs-sections.txt +++ b/docs/reference/libs/libs-sections.txt @@ -2,14 +2,12 @@ videoformat GstVideoFormat gst_vaapi_video_format_to_string -gst_vaapi_video_format_from_caps -gst_vaapi_video_format_from_structure +gst_vaapi_video_format_from_va_fourcc gst_vaapi_video_format_from_va_format gst_vaapi_video_format_get_chroma_type gst_vaapi_video_format_get_score gst_vaapi_video_format_is_rgb gst_vaapi_video_format_is_yuv -gst_vaapi_video_format_to_caps gst_vaapi_video_format_to_va_format @@ -52,6 +50,36 @@ gst_vaapi_display_x11_get_screen GST_VAAPI_DISPLAY_X11 +
+gstvaapidisplay_drm +GstVaapiDisplayDRM +gst_vaapi_display_drm_new +gst_vaapi_display_drm_new_with_device +gst_vaapi_display_drm_get_device +gst_vaapi_display_drm_get_device_path +
+ +
+gstvaapidisplay_wayland +GstVaapiDisplayWayland +gst_vaapi_display_wayland_new +gst_vaapi_display_wayland_new_with_display +gst_vaapi_display_wayland_get_display +
+ +
+gstvaapidisplay_egl +GstVaapiDisplayEGL +GstVaapiDisplayEGL +gst_vaapi_display_egl_new +gst_vaapi_display_egl_new_with_native_display +gst_vaapi_display_egl_get_gl_display +gst_vaapi_display_egl_set_gl_context +gst_vaapi_display_egl_get_gl_context + +GST_VAAPI_DISPLAY_EGL +
+
gstvaapiwindow_x11 GstVaapiWindowX11 @@ -65,6 +93,36 @@ gst_vaapi_window_x11_is_foreign_xid GST_VAAPI_WINDOW_X11
+
+gstvaapiwindow_wayland +GstVaapiWindowWayland +gst_vaapi_window_wayland_new +
+ +
+gstvaapiwindow_drm +GstVaapiWindowDRM +gst_vaapi_window_drm_new +
+ +
+gstvaapiwindow_glx +GstVaapiWindowGLX +gst_vaapi_window_glx_new +gst_vaapi_window_glx_new_with_xid +gst_vaapi_window_glx_get_context +gst_vaapi_window_glx_set_context +gst_vaapi_window_glx_make_current +gst_vaapi_window_glx_swap_buffers +gst_vaapi_window_glx_put_texture +
+ +
+gstvaapiwindow_egl +GstVaapiWindowEGL +gst_vaapi_window_egl_new +
+
gstvaapipixmap_x11 GstVaapiPixmapX11 @@ -106,32 +164,56 @@ GST_VAAPI_WINDOW_GLX
gstvaapidisplay GstVaapiDisplay +GstVaapiDisplayType GstVaapiDisplay +GstVaapiDisplayInfo gst_vaapi_display_new_with_display +gst_vaapi_display_ref +gst_vaapi_display_unref +gst_vaapi_display_replace gst_vaapi_display_lock gst_vaapi_display_unlock gst_vaapi_display_sync gst_vaapi_display_flush +gst_vaapi_display_get_class_type +gst_vaapi_display_get_display_type +gst_vaapi_display_get_display_name gst_vaapi_display_get_display gst_vaapi_display_get_width gst_vaapi_display_get_height gst_vaapi_display_get_size gst_vaapi_display_get_pixel_aspect_ratio -gst_vaapi_display_get_decode_caps +gst_vaapi_display_has_video_processing +gst_vaapi_display_get_decode_profiles gst_vaapi_display_has_decoder -gst_vaapi_display_get_encode_caps +gst_vaapi_display_get_encode_profiles gst_vaapi_display_has_encoder -gst_vaapi_display_get_image_caps +gst_vaapi_display_get_image_formats gst_vaapi_display_has_image_format -gst_vaapi_display_get_subpicture_caps +gst_vaapi_display_get_subpicture_formats gst_vaapi_display_has_subpicture_format gst_vaapi_display_has_property -gst_vaapi_display_get_rotation -gst_vaapi_display_set_rotation +gst_vaapi_display_get_property +gst_vaapi_display_set_property gst_vaapi_display_get_render_mode gst_vaapi_display_set_render_mode +gst_vaapi_display_get_rotation +gst_vaapi_display_set_rotation +gst_vaapi_display_get_vendor_string +gst_vaapi_display_has_opengl GST_VAAPI_DISPLAY +GST_VAAPI_DISPLAY_GET_CLASS_TYPE +GST_VAAPI_DISPLAY_VADISPLAY_TYPE +GST_VAAPI_DISPLAY_VADISPLAY +GST_VAAPI_DISPLAY_LOCK +GST_VAAPI_DISPLAY_UNLOCK +GST_VAAPI_DISPLAY_PROP_RENDER_MODE +GST_VAAPI_DISPLAY_PROP_ROTATION +GST_VAAPI_DISPLAY_PROP_HUE +GST_VAAPI_DISPLAY_PROP_SATURATION +GST_VAAPI_DISPLAY_PROP_BRIGHTNESS +GST_VAAPI_DISPLAY_PROP_CONTRAST
@@ -294,16 +376,35 @@ gst_vaapi_entrypoint_get_va_entrypoint GstVaapiTexture GstVaapiTexture gst_vaapi_texture_new -gst_vaapi_texture_new_with_texture +gst_vaapi_texture_new_wrapped +gst_vaapi_texture_ref +gst_vaapi_texture_unref +gst_vaapi_texture_replace gst_vaapi_texture_get_id gst_vaapi_texture_get_target gst_vaapi_texture_get_format gst_vaapi_texture_get_width gst_vaapi_texture_get_height gst_vaapi_texture_get_size +gst_vaapi_texture_get_orientation_flags +gst_vaapi_texture_set_orientation_flags gst_vaapi_texture_put_surface
+
+gstvaapitexture_egl +GstVaapiTextureEGL +gst_vaapi_texture_egl_new +gst_vaapi_texture_egl_new_wrapped +
+ +
+gstvaapitexture_glx +GstVaapiTextureGLX +gst_vaapi_texture_glx_new +gst_vaapi_texture_glx_new_wrapped +
+
gstvaapidecoder GstVaapiDecoderStatus @@ -357,6 +458,22 @@ GstVaapiDecoderVC1 gst_vaapi_decoder_vc1_new
+
+gstvaapidecoder_vp8 +GstVaapiDecoderVp8 +GstVaapiDecoderVp8 +gst_vaapi_decoder_vp8_new +
+ +
+gstvaapidecoder_h265 +GstVaapiDecoderH265 +GstVaapiDecoderH265 +GstVaapiStreamAlignH265 +gst_vaapi_decoder_h265_new +gst_vaapi_decoder_h265_set_alignment +
+
gstvaapisurfaceproxy GstVaapiSurfaceProxy @@ -379,6 +496,7 @@ GST_VAAPI_SURFACE_PROXY_SURFACE gstvaapifilter GstVaapiFilter GstVaapiFilter +GstVaapiFilterOp gst_vaapi_filter_new gst_vaapi_filter_ref gst_vaapi_filter_unref @@ -394,7 +512,6 @@ gst_vaapi_filter_set_target_rectangle gst_vaapi_filter_set_denoising_level gst_vaapi_filter_set_sharpening_level gst_vaapi_filter_set_hue -gst_vaapi_filter_set_saturation gst_vaapi_filter_set_brightness gst_vaapi_filter_set_saturation gst_vaapi_filter_set_deinterlacing @@ -402,3 +519,61 @@ gst_vaapi_filter_set_deinterlacing_references GST_VAAPI_FILTER
+ +
+gstvaapiparser_frame +GstVaapiParserFrame +gst_vaapi_parser_frame_new +gst_vaapi_parser_frame_free +gst_vaapi_parser_frame_append_unit +gst_vaapi_parser_frame_ref +gst_vaapi_parser_frame_unref +gst_vaapi_parser_frame_replace +
+ +
+gstvaapicontext +GstVaapiContext +GstVaapiConfigInfoEncoder +GstVaapiContextInfo +GstVaapiContext +GstVaapiContextUsage +gst_vaapi_context_new +gst_vaapi_context_reset +gst_vaapi_context_get_id +gst_vaapi_context_get_surface_proxy +gst_vaapi_context_get_surface_count +
+ +
+gstvaapidecoder_unit +GstVaapiDecoderUnit +GstVaapiDecoderUnitFlags +GstVaapiDecoderUnit +gst_vaapi_decoder_unit_init +gst_vaapi_decoder_unit_clear +gst_vaapi_decoder_unit_new +gst_vaapi_decoder_unit_set_parsed_info + +GST_VAAPI_DECODER_UNIT_FLAGS +GST_VAAPI_DECODER_UNIT_FLAG_IS_SET +GST_VAAPI_DECODER_UNIT_FLAG_SET +GST_VAAPI_DECODER_UNIT_FLAG_UNSET +GST_VAAPI_DECODER_UNIT_IS_FRAME_START +GST_VAAPI_DECODER_UNIT_IS_FRAME_END +GST_VAAPI_DECODER_UNIT_IS_STREAM_END +GST_VAAPI_DECODER_UNIT_IS_SLICE +GST_VAAPI_DECODER_UNIT_IS_SKIPPED +
+ +
+gstvaapivalue +GstVaapiValue +GstVaapiEnumSubset +GST_VAAPI_TYPE_POINT +GST_VAAPI_TYPE_RECTANGLE +GST_VAAPI_TYPE_RENDER_MODE +GST_VAAPI_TYPE_ROTATION +GST_VAAPI_TYPE_RATE_CONTROL +GST_VAAPI_POPCOUNT32 +
From f895c07174f9baabfcf03b8581cacfac6616ee0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 May 2015 10:37:13 +0200 Subject: [PATCH 2003/3781] doc: fix scanner compilation warning https://bugzilla.gnome.org/show_bug.cgi?id=749018 --- docs/reference/plugins/plugins.types | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/reference/plugins/plugins.types b/docs/reference/plugins/plugins.types index 183cdd3ea3..375d7c6b94 100644 --- a/docs/reference/plugins/plugins.types +++ b/docs/reference/plugins/plugins.types @@ -1,3 +1,9 @@ +#include + +#include +#include +#include + gst_vaapidecode_get_type gst_vaapipostproc_get_type gst_vaapisink_get_type From 40e836e5eb925cd757cb97de6d8f20b7abc8b56b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 May 2015 10:57:42 +0200 Subject: [PATCH 2004/3781] doc: conditional linking for scanner Add x11 library only if it is enabled. https://bugzilla.gnome.org/show_bug.cgi?id=749018 --- docs/reference/plugins/Makefile.am | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/reference/plugins/Makefile.am b/docs/reference/plugins/Makefile.am index d3e204048f..d933508438 100644 --- a/docs/reference/plugins/Makefile.am +++ b/docs/reference/plugins/Makefile.am @@ -87,9 +87,18 @@ INCLUDES = \ $(GST_CFLAGS) \ $(NULL) -GTKDOC_LIBS = \ +gtkdoc_vaapi_libs = \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_API_VERSION).la \ + $(NULL) + +if USE_X11 +gtkdoc_vaapi_libs += \ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la \ + $(NULL) +endif + +GTKDOC_LIBS = \ + $(gtkdoc_vaapi_libs) \ $(top_builddir)/gst/vaapi/libgstvaapi.la \ $(GLIB_LIBS) \ $(GST_LIBS) \ From e069ddf2b135c4c422a959a6c59e78d15a5e091a Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 25 May 2015 10:58:52 +0300 Subject: [PATCH 2005/3781] gstvaapiutils_h265: Add H265 Tier specific utility functions -- New API: gst_vaapi_utils_h265_get_tier_from_string() -- New API: gst_vaapi_utils_h265_get_tier_string() https://bugzilla.gnome.org/show_bug.cgi?id=748874 Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 28 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_h265.h | 22 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 279400e0ca..0a80d3db7d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -40,6 +40,15 @@ static const struct map gst_vaapi_h265_profile_map[] = { /* *INDENT-ON* */ }; +/* Tier string map */ +static const struct map gst_vaapi_h265_tier_map[] = { +/* *INDENT-OFF* */ + { GST_VAAPI_TIER_H265_MAIN, "main" }, + { GST_VAAPI_TIER_H265_HIGH, "high"}, + { GST_VAAPI_TIER_H265_UNKNOWN, "unknown"} +/* *INDENT-ON* */ +}; + /* Level string map */ static const struct map gst_vaapi_h265_level_map[] = { /* *INDENT-OFF* */ @@ -323,3 +332,22 @@ gst_vaapi_utils_h265_get_chroma_format_idc (GstVaapiChromaType chroma_type) } return chroma_format_idc; } + +/** Returns GstVaapiTierH265 from a string representation */ +GstVaapiTierH265 +gst_vaapi_utils_h265_get_tier_from_string (const gchar * str) +{ + const struct map *const m = map_lookup_name (gst_vaapi_h265_tier_map, str); + + return m ? (GstVaapiTierH265) m->value : GST_VAAPI_TIER_H265_UNKNOWN; +} + +/** Returns a string representation for the supplied H.265 tier */ +const gchar * +gst_vaapi_utils_h265_get_tier_string (GstVaapiTierH265 tier) +{ + const struct map *const m = + map_lookup_value (gst_vaapi_h265_tier_map, tier); + + return m ? m->name : NULL; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.h b/gst-libs/gst/vaapi/gstvaapiutils_h265.h index fff6e6416b..71011b99cd 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.h @@ -63,6 +63,20 @@ typedef enum { GST_VAAPI_LEVEL_H265_L6_2, } GstVaapiLevelH265; +/** + * GstVaapiTierH265: + * GST_VAAPI_TIER_H265_MAIN: H265 Tier 0 + * GST_VAAPI_TIER_H265_HIGH: H265 Tier 1 + * GST_VAAPI_TIER_H265_UNKNOWN: Unknown Tier + * + * The set of all Tier for #GstVaapiTierH265. + */ +typedef enum { + GST_VAAPI_TIER_H265_MAIN, + GST_VAAPI_TIER_H265_HIGH, + GST_VAAPI_TIER_H265_UNKNOWN = -1 +} GstVaapiTierH265; + /* Returns a relative score for the supplied GstVaapiProfile */ guint gst_vaapi_utils_h265_get_profile_score (GstVaapiProfile profile); @@ -83,6 +97,14 @@ gst_vaapi_utils_h265_get_level_from_string (const gchar * str); const gchar * gst_vaapi_utils_h265_get_level_string (GstVaapiLevelH265 level); +/* Returns GstVaapiTierH265 from a string representation */ +GstVaapiTierH265 +gst_vaapi_utils_h265_get_tier_from_string (const gchar * str); + +/* Returns a string representation for the supplied H.265 Tier */ +const gchar * +gst_vaapi_utils_h265_get_tier_string (GstVaapiTierH265 tier); + G_END_DECLS #endif /* GST_VAAPI_UTILS_H265_H */ From e6f03391789011689ffb437a33da3110e8a8f427 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 25 May 2015 11:26:14 +0300 Subject: [PATCH 2006/3781] HEVC_Encode: build: Check availability of VA APIs for H265 encoding. Signed-off-by: Sreerenj Balachandran https://bugzilla.gnome.org/show_bug.cgi?id=748874 --- configure.ac | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/configure.ac b/configure.ac index 34fe92b3da..a7859564a7 100644 --- a/configure.ac +++ b/configure.ac @@ -842,6 +842,7 @@ dnl Check for encoding support USE_ENCODERS=0 USE_JPEG_ENCODER=0 USE_VP8_ENCODER=0 +USE_H265_ENCODER=0 if test "$enable_encoders" = "yes"; then PKG_CHECK_MODULES([LIBVA], [libva >= va_api_enc_version], [HAVE_VA_ENC=1], [HAVE_VA_ENC=0]) @@ -910,6 +911,36 @@ if test "$enable_encoders" = "yes"; then LIBS="$saved_LIBS" ]) CPPFLAGS="$saved_CPPFLAGS" + + dnl Check for H265/HEVC Encoding API + AC_CHECK_HEADERS([va/va_enc_hevc.h], + [USE_H265_ENCODER=1], [], + [#include + ]) + AC_CACHE_CHECK([for HEVC encoding API], + ac_cv_have_hevc_encoding_api, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #ifdef HAVE_VA_VA_ENC_HEVC_H + #include + #endif + ]], + [[VAEncSequenceParameterBufferHEVC seq_param; + VAEncPictureParameterBufferHEVC pic_param; + VAEncSliceParameterBufferHEVC; + VAQMatrixBufferHEVC q_matrix;]])], + [ac_cv_have_hevc_encoding_api="yes" USE_H265_ENCODER=1], + [ac_cv_have_hevc_encoding_api="no" USE_H265_ENCODER=0] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" + ]) + CPPFLAGS="$saved_CPPFLAGS" fi fi @@ -943,6 +974,10 @@ AC_DEFINE_UNQUOTED(USE_VP8_ENCODER, $USE_VP8_ENCODER, [Defined to 1 if VP8 encoder is used]) AM_CONDITIONAL(USE_VP8_ENCODER, test $USE_VP8_ENCODER -eq 1) +AC_DEFINE_UNQUOTED(USE_H265_ENCODER, $USE_H265_ENCODER, + [Defined to 1 if H265 encoder is used]) +AM_CONDITIONAL(USE_H265_ENCODER, test $USE_H265_ENCODER -eq 1) + AC_DEFINE_UNQUOTED(USE_VA_VPP, $USE_VA_VPP, [Defined to 1 if video post-processing is used]) AM_CONDITIONAL(USE_VA_VPP, test $USE_VA_VPP -eq 1) From e623651d696ffc358243c1c997ec6c67642aa94b Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 25 May 2015 11:38:34 +0300 Subject: [PATCH 2007/3781] HEVC_Encode: Add HEVC(h265) encoder to core libgstvaapi https://bugzilla.gnome.org/show_bug.cgi?id=748874 Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/Makefile.am | 9 + gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 2562 +++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 72 + 3 files changed, 2643 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_h265.c create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_h265.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 348e0c1860..1c65a7b13d 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -222,6 +222,13 @@ libgstvaapi_source_c += $(libgstvaapi_vp8enc_source_c) libgstvaapi_source_h += $(libgstvaapi_vp8enc_source_h) endif +libgstvaapi_h265enc_source_c = gstvaapiencoder_h265.c +libgstvaapi_h265enc_source_h = gstvaapiencoder_h265.h +if USE_H265_ENCODER +libgstvaapi_source_c += $(libgstvaapi_h265enc_source_c) +libgstvaapi_source_h += $(libgstvaapi_h265enc_source_h) +endif + libgstvaapi_drm_source_c = \ gstvaapidisplay_drm.c \ gstvaapiwindow_drm.c \ @@ -590,6 +597,8 @@ EXTRA_DIST += \ $(libgstvaapi_jpegenc_source_c) \ $(libgstvaapi_vp8enc_source_h) \ $(libgstvaapi_vp8enc_source_c) \ + $(libgstvaapi_h265enc_source_h) \ + $(libgstvaapi_h265enc_source_c) \ $(libgstvaapi_egl_source_c) \ $(libgstvaapi_egl_source_h) \ $(libgstvaapi_egl_source_priv_h) \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c new file mode 100644 index 0000000000..0be492b8eb --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -0,0 +1,2562 @@ +/* + * gstvaapiencoder_h265.c - H.265 encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 + */ + +/* GValueArray has deprecated without providing an alternative in glib >= 2.32 + * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 + */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#include "sysdeps.h" +#include +#include +#include +#include +#include +#include "gstvaapicompat.h" +#include "gstvaapiencoder_priv.h" +#include "gstvaapiencoder_h265.h" +#include "gstvaapiutils_h265.h" +#include "gstvaapiutils_h265_priv.h" +#include "gstvaapicodedbufferproxy_priv.h" +#include "gstvaapisurface.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +/* Define the maximum IDR period */ +#define MAX_IDR_PERIOD 512 + +/* 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)) + +/* 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_SEQUENCE | \ + VA_ENC_PACKED_HEADER_PICTURE | \ + VA_ENC_PACKED_HEADER_SLICE) + +typedef struct +{ + GstVaapiSurfaceProxy *pic; + guint poc; +} GstVaapiEncoderH265Ref; + +typedef enum +{ + GST_VAAPI_ENC_H265_REORD_NONE = 0, + GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES = 1, + GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES = 2 +} GstVaapiEncH265ReorderState; + +typedef struct _GstVaapiH265RefPool +{ + GQueue ref_list; + guint max_ref_frames; + guint max_reflist0_count; + guint max_reflist1_count; +} GstVaapiH265RefPool; + +typedef struct _GstVaapiH265ReorderPool +{ + GQueue reorder_frame_list; + guint reorder_state; + guint frame_index; + guint cur_present_index; +} GstVaapiH265ReorderPool; + +/* ------------------------------------------------------------------------- */ +/* --- H.265 Encoder --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENCODER_H265_CAST(encoder) \ + ((GstVaapiEncoderH265 *)(encoder)) + +struct _GstVaapiEncoderH265 +{ + GstVaapiEncoder parent_instance; + + GstVaapiProfile profile; + GstVaapiTierH265 tier; + GstVaapiLevelH265 level; + guint8 profile_idc; + guint8 max_profile_idc; + guint8 hw_max_profile_idc; + guint8 level_idc; + guint32 idr_period; + guint32 init_qp; + guint32 min_qp; + guint32 num_slices; + guint32 num_bframes; + guint32 ctu_width; /* CTU == Coding Tree Unit */ + guint32 ctu_height; + guint32 luma_width; + guint32 luma_height; + GstClockTime cts_offset; + gboolean config_changed; + + /* maximum required size of the decoded picture buffer */ + guint32 max_dec_pic_buffering; + /* maximum allowed number of pictures that can precede any picture in + * the CVS in decoding order and follow that picture in output order */ + guint32 max_num_reorder_pics; + + /* frame, poc */ + guint32 max_pic_order_cnt; + guint32 log2_max_pic_order_cnt; + guint32 idr_num; + + GstBuffer *vps_data; + GstBuffer *sps_data; + GstBuffer *pps_data; + + guint bitrate_bits; // bitrate (bits) + + /* Crop rectangle */ + guint conformance_window_flag:1; + guint32 conf_win_left_offset; + guint32 conf_win_right_offset; + guint32 conf_win_top_offset; + guint32 conf_win_bottom_offset; + + GstVaapiH265RefPool ref_pool; + GstVaapiH265ReorderPool reorder_pool; + guint first_slice_segment_in_pic_flag:1; + guint sps_temporal_mvp_enabled_flag:1; + guint sample_adaptive_offset_enabled_flag:1; +}; + +static inline gboolean +_poc_greater_than (guint poc1, guint poc2, guint max_poc) +{ + return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2); +} + +/* Get slice_type value for H.265 specification */ +static guint8 +h265_get_slice_type (GstVaapiPictureType type) +{ + switch (type) { + case GST_VAAPI_PICTURE_TYPE_I: + return GST_H265_I_SLICE; + case GST_VAAPI_PICTURE_TYPE_P: + return GST_H265_P_SLICE; + case GST_VAAPI_PICTURE_TYPE_B: + return GST_H265_B_SLICE; + default: + break; + } + return -1; +} + +/* Get log2_max_pic_order_cnt value for H.265 specification */ +static guint +h265_get_log2_max_pic_order_cnt (guint num) +{ + guint ret = 0; + + while (num) { + ++ret; + num >>= 1; + } + if (ret <= 4) + ret = 4; + else if (ret > 10) + ret = 10; + /* must be greater than 4 */ + return ret; +} + +/* ------------------------------------------------------------------------- */ +/* --- H.265 Bitstream Writer --- */ +/* ------------------------------------------------------------------------- */ + +#define WRITE_UINT32(bs, val, nbits) do { \ + if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \ + GST_WARNING ("failed to write uint32, nbits: %d", nbits); \ + goto bs_error; \ + } \ + } while (0) + +#define WRITE_UE(bs, val) do { \ + if (!bs_write_ue (bs, val)) { \ + GST_WARNING ("failed to write ue(v)"); \ + goto bs_error; \ + } \ + } while (0) + +#define WRITE_SE(bs, val) do { \ + if (!bs_write_se (bs, val)) { \ + GST_WARNING ("failed to write se(v)"); \ + goto bs_error; \ + } \ + } while (0) + +/* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */ +static gboolean +bs_write_ue (GstBitWriter * bs, guint32 value) +{ + guint32 size_in_bits = 0; + guint32 tmp_value = ++value; + + while (tmp_value) { + ++size_in_bits; + tmp_value >>= 1; + } + if (size_in_bits > 1 + && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1)) + return FALSE; + if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits)) + return FALSE; + return TRUE; +} + +/* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */ +static gboolean +bs_write_se (GstBitWriter * bs, gint32 value) +{ + guint32 new_val; + + if (value <= 0) + new_val = -(value << 1); + else + new_val = (value << 1) - 1; + + if (!bs_write_ue (bs, new_val)) + return FALSE; + return TRUE; +} + +/* Write the NAL unit header */ +static gboolean +bs_write_nal_header (GstBitWriter * bs, guint32 nal_unit_type) +{ + guint8 nuh_layer_id = 0; + guint8 nuh_temporal_id_plus1 = 1; + + WRITE_UINT32 (bs, 0, 1); + WRITE_UINT32 (bs, nal_unit_type, 6); + WRITE_UINT32 (bs, nuh_layer_id, 6); + WRITE_UINT32 (bs, nuh_temporal_id_plus1, 3); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write NAL unit header"); + return FALSE; + } +} + +/* Write the NAL unit trailing bits */ +static gboolean +bs_write_trailing_bits (GstBitWriter * bs) +{ + if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1)) + goto bs_error; + gst_bit_writer_align_bytes_unchecked (bs, 0); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write NAL unit trailing bits"); + return FALSE; + } +} + +/* Write profile_tier_level() */ +static gboolean +bs_write_profile_tier_level (GstBitWriter * bs, + const VAEncSequenceParameterBufferHEVC * seq_param) +{ + guint i; + /* general_profile_space */ + WRITE_UINT32 (bs, 0, 2); + /* general_tier_flag */ + WRITE_UINT32 (bs, seq_param->general_tier_flag, 1); + /* general_profile_idc */ + WRITE_UINT32 (bs, seq_param->general_profile_idc, 5); + /* general_profile_compatibility_flag[32] */ + for (i = 0; i < 32; i++) { + if (i == 1 || i == 2) + WRITE_UINT32 (bs, 1, 1); + else + WRITE_UINT32 (bs, 0, 1); + } + /* general_progressive_source_flag */ + WRITE_UINT32 (bs, 1, 1); + /* general_interlaced_source_flag */ + WRITE_UINT32 (bs, 0, 1); + /* general_non_packed_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* general_frame_only_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* general_reserved_zero_44bits */ + for (i = 0; i < 44; i++) + WRITE_UINT32 (bs, 0, 1); + /* general_level_idc */ + WRITE_UINT32 (bs, seq_param->general_level_idc, 8); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Profile Tier Level"); + return FALSE; + } +} + +/* Write an VPS NAL unit */ +static gboolean +bs_write_vps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, + const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile) +{ + guint32 video_parameter_set_id = 0; + guint32 vps_max_layers_minus1 = 0; + guint32 vps_max_sub_layers_minus1 = 0; + guint32 vps_temporal_id_nesting_flag = 1; + guint32 vps_sub_layer_ordering_info_present_flag = 0; + guint32 vps_max_latency_increase_plus1 = 0; + guint32 vps_max_layer_id = 0; + guint32 vps_num_layer_sets_minus1 = 0; + guint32 vps_timing_info_present_flag = 0; + guint32 vps_extension_flag = 0; + + /* video_parameter_set_id */ + WRITE_UINT32 (bs, video_parameter_set_id, 4); + /* vps_reserved_three_2bits */ + WRITE_UINT32 (bs, 3, 2); + /* vps_max_layers_minus1 */ + WRITE_UINT32 (bs, vps_max_layers_minus1, 6); + /* vps_max_sub_layers_minus1 */ + WRITE_UINT32 (bs, vps_max_sub_layers_minus1, 3); + /* vps_temporal_id_nesting_flag */ + WRITE_UINT32 (bs, vps_temporal_id_nesting_flag, 1); + /* vps_reserved_0xffff_16bits */ + WRITE_UINT32 (bs, 0xffff, 16); + + /* profile_tier_level */ + bs_write_profile_tier_level (bs, seq_param); + + /* vps_sub_layer_ordering_info_present_flag */ + WRITE_UINT32 (bs, vps_sub_layer_ordering_info_present_flag, 1); + /* vps_max_dec_pic_buffering_minus1 */ + WRITE_UE (bs, encoder->max_dec_pic_buffering - 1); + /* vps_max_num_reorder_pics */ + WRITE_UE (bs, encoder->max_num_reorder_pics); + /* vps_max_latency_increase_plus1 */ + WRITE_UE (bs, vps_max_latency_increase_plus1); + /* vps_max_layer_id */ + WRITE_UINT32 (bs, vps_max_layer_id, 6); + /* vps_num_layer_sets_minus1 */ + WRITE_UE (bs, vps_num_layer_sets_minus1); + /* vps_timing_info_present_flag */ + WRITE_UINT32 (bs, vps_timing_info_present_flag, 1); + /* vps_extension_flag */ + WRITE_UINT32 (bs, vps_extension_flag, 1); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write VPS NAL unit"); + return FALSE; + } +} + +static gboolean +bs_write_vps (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, + const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile) +{ + if (!bs_write_vps_data (bs, encoder, picture, seq_param, profile)) + return FALSE; + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + + return FALSE; +} + +/* Write an SPS NAL unit */ +static gboolean +bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, + const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile) +{ + guint32 video_parameter_set_id = 0; + guint32 max_sub_layers_minus1 = 0; + guint32 temporal_id_nesting_flag = 1; + guint32 seq_parameter_set_id = 0; + guint32 sps_sub_layer_ordering_info_present_flag = 0; + guint32 sps_max_latency_increase_plus1 = 0; + guint32 num_short_term_ref_pic_sets = 0; + guint32 long_term_ref_pics_present_flag = 0; + guint32 sps_extension_flag = 0; + + /* video_parameter_set_id */ + WRITE_UINT32 (bs, video_parameter_set_id, 4); + /* max_sub_layers_minus1 */ + WRITE_UINT32 (bs, max_sub_layers_minus1, 3); + /* temporal_id_nesting_flag */ + WRITE_UINT32 (bs, temporal_id_nesting_flag, 1); + + /* profile_tier_level */ + bs_write_profile_tier_level (bs, seq_param); + + /* seq_parameter_set_id */ + WRITE_UE (bs, seq_parameter_set_id); + /* chroma_format_idc = 1, 4:2:0 */ + WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc); + /* pic_width_in_luma_samples */ + WRITE_UE (bs, seq_param->pic_width_in_luma_samples); + /* pic_height_in_luma_samples */ + WRITE_UE (bs, seq_param->pic_height_in_luma_samples); + + /* conformance_window_flag */ + WRITE_UINT32 (bs, encoder->conformance_window_flag, 1); + if (encoder->conformance_window_flag) { + WRITE_UE (bs, encoder->conf_win_left_offset); + WRITE_UE (bs, encoder->conf_win_right_offset); + WRITE_UE (bs, encoder->conf_win_top_offset); + WRITE_UE (bs, encoder->conf_win_bottom_offset); + } + + /* bit_depth_luma_minus8 */ + WRITE_UE (bs, seq_param->seq_fields.bits.bit_depth_luma_minus8); + /* bit_depth_chroma_minus8 */ + WRITE_UE (bs, seq_param->seq_fields.bits.bit_depth_chroma_minus8); + /* log2_max_pic_order_cnt_lsb_minus4 */ + WRITE_UE (bs, encoder->log2_max_pic_order_cnt - 4); + + /* sps_sub_layer_ordering_info_present_flag */ + WRITE_UINT32 (bs, sps_sub_layer_ordering_info_present_flag, 1); + /* sps_max_dec_pic_buffering_minus1 */ + WRITE_UE (bs, encoder->max_dec_pic_buffering - 1); + /* sps_max_num_reorder_pics */ + WRITE_UE (bs, encoder->max_num_reorder_pics); + /* sps_max_latency_increase_plus1 */ + WRITE_UE (bs, sps_max_latency_increase_plus1); + + /* log2_min_luma_coding_block_size_minus3 */ + WRITE_UE (bs, seq_param->log2_min_luma_coding_block_size_minus3); + /* log2_diff_max_min_luma_coding_block_size */ + WRITE_UE (bs, seq_param->log2_diff_max_min_luma_coding_block_size); + /* log2_min_transform_block_size_minus2 */ + WRITE_UE (bs, seq_param->log2_min_transform_block_size_minus2); + /* log2_diff_max_min_transform_block_size */ + WRITE_UE (bs, seq_param->log2_diff_max_min_transform_block_size); + /* max_transform_hierarchy_depth_inter */ + WRITE_UE (bs, seq_param->max_transform_hierarchy_depth_inter); + /*max_transform_hierarchy_depth_intra */ + WRITE_UE (bs, seq_param->max_transform_hierarchy_depth_intra); + + /* scaling_list_enabled_flag */ + WRITE_UINT32 (bs, seq_param->seq_fields.bits.scaling_list_enabled_flag, 1); + /* amp_enabled_flag */ + WRITE_UINT32 (bs, seq_param->seq_fields.bits.amp_enabled_flag, 1); + /* sample_adaptive_offset_enabled_flag */ + WRITE_UINT32 (bs, + seq_param->seq_fields.bits.sample_adaptive_offset_enabled_flag, 1); + /* pcm_enabled_flag */ + WRITE_UINT32 (bs, seq_param->seq_fields.bits.pcm_enabled_flag, 1); + + /* num_short_term_ref_pic_sets */ + WRITE_UE (bs, num_short_term_ref_pic_sets); + + /* long_term_ref_pics_present_flag */ + WRITE_UINT32 (bs, long_term_ref_pics_present_flag, 1); + + /* sps_temporal_mvp_enabled_flag */ + WRITE_UINT32 (bs, seq_param->seq_fields.bits.sps_temporal_mvp_enabled_flag, + 1); + /* strong_intra_smoothing_enabled_flag */ + WRITE_UINT32 (bs, + seq_param->seq_fields.bits.strong_intra_smoothing_enabled_flag, 1); + + /* vui_parameters_present_flag */ + WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1); + + /*--------------- Write VUI Parameters--------------- */ + if (seq_param->vui_parameters_present_flag) { + gboolean vui_hrd_parameters_present_flag; + /* aspect_ratio_info_present_flag */ + WRITE_UINT32 (bs, + seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1); + if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { + WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8); + if (seq_param->aspect_ratio_idc == 0xFF) { + WRITE_UINT32 (bs, seq_param->sar_width, 16); + WRITE_UINT32 (bs, seq_param->sar_height, 16); + } + } + /* overscan_info_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* video_signal_type_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* chroma_loc_info_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* neutral_chroma_indication_flag */ + WRITE_UINT32 (bs, seq_param->vui_fields.bits.neutral_chroma_indication_flag, + 1); + /* field_seq_flag */ + WRITE_UINT32 (bs, seq_param->vui_fields.bits.field_seq_flag, 1); + /* frame_field_info_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* default_display_window_flag */ + WRITE_UINT32 (bs, 0, 1); + + /* timing_info_present_flag */ + WRITE_UINT32 (bs, seq_param->vui_fields.bits.vui_timing_info_present_flag, + 1); + if (seq_param->vui_fields.bits.vui_timing_info_present_flag) { + /* vui_num_units_in_tick */ + WRITE_UINT32 (bs, seq_param->vui_num_units_in_tick, 32); + /* vui_time_scale */ + WRITE_UINT32 (bs, seq_param->vui_time_scale, 32); + /* vui_poc_proportional_to_timing_flag */ + WRITE_UINT32 (bs, 0, 1); + + /* vui_hrd_parameters_present_flag */ + vui_hrd_parameters_present_flag = seq_param->bits_per_second > 0; + vui_hrd_parameters_present_flag = FALSE; /* XXX: disabled for now */ + WRITE_UINT32 (bs, vui_hrd_parameters_present_flag, 1); + } + /* bitstream_restriction_flag */ + WRITE_UINT32 (bs, seq_param->vui_fields.bits.bitstream_restriction_flag, 1); + } + /* sps_extension_flag */ + WRITE_UINT32 (bs, sps_extension_flag, 1); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SPS NAL unit"); + return FALSE; + } +} + +static gboolean +bs_write_sps (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, + const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile) +{ + if (!bs_write_sps_data (bs, encoder, picture, seq_param, profile)) + return FALSE; + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + + return FALSE; +} + +/* Write a PPS NAL unit */ +static gboolean +bs_write_pps (GstBitWriter * bs, + const VAEncPictureParameterBufferHEVC * pic_param) +{ + guint32 pic_parameter_set_id = 0; + guint32 seq_parameter_set_id = 0; + guint32 output_flag_present_flag = 0; + guint32 num_extra_slice_header_bits = 0; + guint32 cabac_init_present_flag = 0; + guint32 pps_slice_chroma_qp_offsets_present_flag = 0; + guint32 deblocking_filter_control_present_flag = 0; + guint32 lists_modification_present_flag = 0; + guint32 slice_segment_header_extension_present_flag = 0; + guint32 pps_extension_flag = 0; + + /* pic_parameter_set_id */ + WRITE_UE (bs, pic_parameter_set_id); + /* seq_parameter_set_id */ + WRITE_UE (bs, seq_parameter_set_id); + /* dependent_slice_segments_enabled_flag */ + WRITE_UINT32 (bs, + pic_param->pic_fields.bits.dependent_slice_segments_enabled_flag, 1); + /* output_flag_present_flag */ + WRITE_UINT32 (bs, output_flag_present_flag, 1); + /* num_extra_slice_header_bits */ + WRITE_UINT32 (bs, num_extra_slice_header_bits, 3); + /* sign_data_hiding_enabled_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.sign_data_hiding_enabled_flag, + 1); + /* cabac_init_present_flag */ + WRITE_UINT32 (bs, cabac_init_present_flag, 1); + /* num_ref_idx_l0_default_active_minus1 */ + WRITE_UE (bs, pic_param->num_ref_idx_l0_default_active_minus1); + /* num_ref_idx_l1_default_active_minus1 */ + WRITE_UE (bs, pic_param->num_ref_idx_l1_default_active_minus1); + /* pic_init_qp_minus26 */ + WRITE_SE (bs, pic_param->pic_init_qp - 26); + /* constrained_intra_pred_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1); + /* transform_skip_enabled_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_skip_enabled_flag, 1); + /* cu_qp_delta_enabled_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.cu_qp_delta_enabled_flag, 1); + /* diff_cu_qp_delta_depth */ + if (pic_param->pic_fields.bits.cu_qp_delta_enabled_flag) + WRITE_UE (bs, pic_param->diff_cu_qp_delta_depth); + + /* pps_cb_qp_offset */ + WRITE_SE (bs, pic_param->pps_cb_qp_offset); + /* pps_cr_qp_offset */ + WRITE_SE (bs, pic_param->pps_cr_qp_offset); + /* pps_slice_chroma_qp_offsets_present_flag */ + WRITE_UINT32 (bs, pps_slice_chroma_qp_offsets_present_flag, 1); + /* weighted_pred_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1); + /* weighted_bipred_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_flag, 1); + /* transquant_bypass_enabled_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.transquant_bypass_enabled_flag, + 1); + /* tiles_enabled_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.tiles_enabled_flag, 1); + /* entropy_coding_sync_enabled_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_sync_enabled_flag, + 1); + /* pps_loop_filter_across_slices_enabled_flag */ + WRITE_UINT32 (bs, + pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag, 1); + /* deblocking_filter_control_present_flag */ + WRITE_UINT32 (bs, deblocking_filter_control_present_flag, 1); + /* pps_scaling_list_data_present_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.scaling_list_data_present_flag, + 1); + /* lists_modification_present_flag */ + WRITE_UINT32 (bs, lists_modification_present_flag, 1); + /* log2_parallel_merge_level_minus2 */ + WRITE_UE (bs, pic_param->log2_parallel_merge_level_minus2); + /* slice_segment_header_extension_present_flag */ + WRITE_UINT32 (bs, slice_segment_header_extension_present_flag, 1); + /* pps_extension_flag */ + WRITE_UINT32 (bs, pps_extension_flag, 1); + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write PPS NAL unit"); + return FALSE; + } +} + +/* Write a Slice NAL unit */ +static gboolean +bs_write_slice (GstBitWriter * bs, + const VAEncSliceParameterBufferHEVC * slice_param, + GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, + guint8 nal_unit_type) +{ + const VAEncPictureParameterBufferHEVC *const pic_param = picture->param; + + guint8 no_output_of_prior_pics_flag = 0; + guint8 dependent_slice_segment_flag = 0; + guint8 short_term_ref_pic_set_sps_flag = 0; + guint8 num_ref_idx_active_override_flag = 0; + guint8 slice_deblocking_filter_disabled_flag = 0; + + /* first_slice_segment_in_pic_flag */ + WRITE_UINT32 (bs, encoder->first_slice_segment_in_pic_flag, 1); + + /* Fixme: For all IRAP pics */ + /* no_output_of_prior_pics_flag */ + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1); + + /* slice_pic_parameter_set_id */ + WRITE_UE (bs, slice_param->slice_pic_parameter_set_id); + + /* slice_segment_address , bits_size = Ceil(Log2(PicSizeInCtbsY)) */ + if (!encoder->first_slice_segment_in_pic_flag) { + guint pic_size_ctb = encoder->ctu_width * encoder->ctu_height; + guint bits_size = (guint) ceil ((log2 (pic_size_ctb))); + WRITE_UINT32 (bs, slice_param->slice_segment_address, bits_size); + } + + if (!dependent_slice_segment_flag) { + /* slice_type */ + WRITE_UE (bs, slice_param->slice_type); + + if (!pic_param->pic_fields.bits.idr_pic_flag) { + /* slice_pic_order_cnt_lsb */ + WRITE_UINT32 (bs, picture->poc, encoder->log2_max_pic_order_cnt); + /* short_term_ref_pic_set_sps_flag */ + WRITE_UINT32 (bs, short_term_ref_pic_set_sps_flag, 1); + + /*---------- Write short_term_ref_pic_set(0) ----------- */ + { + guint num_positive_pics = 0, num_negative_pics = 0; + guint delta_poc_s0_minus1 = 0, delta_poc_s1_minus1 = 0; + guint used_by_curr_pic_s0_flag = 0, used_by_curr_pic_s1_flag = 0; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_P) { + num_negative_pics = 1; + num_positive_pics = 0; + delta_poc_s0_minus1 = + picture->poc - slice_param->ref_pic_list0[0].pic_order_cnt - 1; + used_by_curr_pic_s0_flag = 1; + delta_poc_s1_minus1 = 0; + used_by_curr_pic_s1_flag = 0; + } + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + num_negative_pics = 1; + num_positive_pics = 1; + delta_poc_s0_minus1 = + picture->poc - slice_param->ref_pic_list0[0].pic_order_cnt - 1; + used_by_curr_pic_s0_flag = 1; + delta_poc_s1_minus1 = + slice_param->ref_pic_list1[0].pic_order_cnt - picture->poc - 1; + used_by_curr_pic_s1_flag = 1; + } + + /* num_negative_pics */ + WRITE_UE (bs, num_negative_pics); + /* num_positive_pics */ + WRITE_UE (bs, num_positive_pics); + if (num_negative_pics) { + /* delta_poc_s0_minus1 */ + WRITE_UE (bs, delta_poc_s0_minus1); + /* used_by_curr_pic_s0_flag */ + WRITE_UINT32 (bs, used_by_curr_pic_s0_flag, 1); + } + if (num_positive_pics) { + /* delta_poc_s1_minus1 */ + WRITE_UE (bs, delta_poc_s1_minus1); + /* used_by_curr_pic_s1_flag */ + WRITE_UINT32 (bs, used_by_curr_pic_s1_flag, 1); + } + } + + /* slice_temporal_mvp_enabled_flag */ + if (encoder->sps_temporal_mvp_enabled_flag) + WRITE_UINT32 (bs, + slice_param->slice_fields.bits.slice_temporal_mvp_enabled_flag, 1); + } + + if (encoder->sample_adaptive_offset_enabled_flag) { + WRITE_UINT32 (bs, slice_param->slice_fields.bits.slice_sao_luma_flag, 1); + WRITE_UINT32 (bs, slice_param->slice_fields.bits.slice_sao_chroma_flag, + 1); + } + + if (slice_param->slice_type == GST_H265_P_SLICE || + slice_param->slice_type == GST_H265_B_SLICE) { + /* num_ref_idx_active_override_flag */ + WRITE_UINT32 (bs, num_ref_idx_active_override_flag, 1); + /* mvd_l1_zero_flag */ + if (slice_param->slice_type == GST_H265_B_SLICE) + WRITE_UINT32 (bs, slice_param->slice_fields.bits.mvd_l1_zero_flag, 1); + + /* cabac_init_present_flag == FALSE */ + /* cabac_init_flag = FALSE */ + + /* collocated_from_l0_flag */ + if (slice_param->slice_fields.bits.slice_temporal_mvp_enabled_flag) { + if (slice_param->slice_type == GST_H265_B_SLICE) + WRITE_UINT32 (bs, + slice_param->slice_fields.bits.collocated_from_l0_flag, 1); + } + /* five_minus_max_num_merge_cand */ + WRITE_UE (bs, 5 - slice_param->max_num_merge_cand); + } + + /* slice_qp_delta */ + WRITE_SE (bs, slice_param->slice_qp_delta); + if (pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag && + (slice_param->slice_fields.bits.slice_sao_luma_flag + || slice_param->slice_fields.bits.slice_sao_chroma_flag + || !slice_deblocking_filter_disabled_flag)) + WRITE_UINT32 (bs, + slice_param->slice_fields. + bits.slice_loop_filter_across_slices_enabled_flag, 1); + + } + + /* byte_alignment() */ + { + /* alignment_bit_equal_to_one */ + WRITE_UINT32 (bs, 1, 1); + while (GST_BIT_WRITER_BIT_SIZE (bs) % 8 != 0) { + /* alignment_bit_equal_to_zero */ + WRITE_UINT32 (bs, 0, 1); + } + } + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Slice NAL unit"); + return FALSE; + } +} + +static inline void +_check_vps_sps_pps_status (GstVaapiEncoderH265 * encoder, + const guint8 * nal, guint32 size) +{ + guint8 nal_type; + gsize ret; + g_assert (size); + + if (encoder->vps_data && encoder->sps_data && encoder->pps_data) + return; + + nal_type = (nal[0] & 0x7E) >> 1; + switch (nal_type) { + case GST_H265_NAL_VPS: + encoder->vps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (encoder->vps_data, 0, nal, size); + g_assert (ret == size); + break; + case GST_H265_NAL_SPS: + encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (encoder->sps_data, 0, nal, size); + g_assert (ret == size); + break; + case GST_H265_NAL_PPS: + encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (encoder->pps_data, 0, nal, size); + g_assert (ret == size); + break; + default: + break; + } +} + +/* Determines the largest supported profile by the underlying hardware */ +static gboolean +ensure_hw_profile_limits (GstVaapiEncoderH265 * encoder) +{ + GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); + GArray *profiles; + guint i, profile_idc, max_profile_idc; + + if (encoder->hw_max_profile_idc) + return TRUE; + + profiles = gst_vaapi_display_get_encode_profiles (display); + if (!profiles) + return FALSE; + + max_profile_idc = 0; + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index (profiles, GstVaapiProfile, i); + profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile); + if (!profile_idc) + continue; + if (max_profile_idc < profile_idc) + max_profile_idc = profile_idc; + } + g_array_unref (profiles); + + encoder->hw_max_profile_idc = max_profile_idc; + return TRUE; +} + +/* Derives the profile supported by the underlying hardware */ +static gboolean +ensure_hw_profile (GstVaapiEncoderH265 * encoder) +{ + GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); + GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + GstVaapiProfile profile, profiles[4]; + guint i, num_profiles = 0; + + profiles[num_profiles++] = encoder->profile; + switch (encoder->profile) { + case GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE: + profiles[num_profiles++] = GST_VAAPI_PROFILE_H265_MAIN; + // fall-through + case GST_VAAPI_PROFILE_H265_MAIN: + profiles[num_profiles++] = GST_VAAPI_PROFILE_H265_MAIN10; + break; + default: + break; + } + + 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 (0x%08x)", encoder->profile); + return FALSE; + } +} + +/* Check target decoder constraints */ +static gboolean +ensure_profile_limits (GstVaapiEncoderH265 * encoder) +{ + + if (!encoder->max_profile_idc + || encoder->profile_idc <= encoder->max_profile_idc) + return TRUE; + + GST_WARNING + ("Needs to lower coding tools to meet target decoder constraints"); + GST_WARNING ("Only supporting Main profile, reset profile to Main"); + + encoder->profile = GST_VAAPI_PROFILE_H265_MAIN;; + encoder->profile_idc = + gst_vaapi_utils_h265_get_profile_idc (encoder->profile); + + return TRUE; +} + +/* Derives the minimum profile from the active coding tools */ +static gboolean +ensure_profile (GstVaapiEncoderH265 * encoder) +{ + GstVaapiProfile profile; + + /* Always start from "Main" profile for maximum + compatibility */ + profile = GST_VAAPI_PROFILE_H265_MAIN; + + encoder->profile = profile; + encoder->profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile); + return TRUE; +} + +/* Derives the minimum tier from the active coding tools */ +static gboolean +ensure_tier (GstVaapiEncoderH265 * encoder) +{ + + encoder->tier = GST_VAAPI_TIER_H265_MAIN; + /*Fixme: Derive proper tier based on upstream caps or limits, coding tools etc */ + + return TRUE; +} + +/* Derives the level from the currently set limits */ +static gboolean +ensure_level (GstVaapiEncoderH265 * encoder) +{ + const GstVaapiH265LevelLimits *limits_table; + guint i, num_limits, PicSizeInSamplesY; + + PicSizeInSamplesY = encoder->luma_width * encoder->luma_height; + + limits_table = gst_vaapi_utils_h265_get_level_limits_table (&num_limits); + for (i = 0; i < num_limits; i++) { + const GstVaapiH265LevelLimits *const limits = &limits_table[i]; + if (PicSizeInSamplesY <= limits->MaxLumaPs) + break; + /* Fixme: Add more constraint checking:tier (extracted from caps), cpb size, + * bitrate, num_tile_columns and num_tile_rows */ + } + if (i == num_limits) + goto error_unsupported_level; + + encoder->level = limits_table[i].level; + encoder->level_idc = limits_table[i].level_idc; + return TRUE; + + /* ERRORS */ +error_unsupported_level: + { + GST_ERROR ("failed to find a suitable level matching codec config"); + return FALSE; + } +} + +/* Enable "high-compression" tuning options */ +static gboolean +ensure_tuning_high_compression (GstVaapiEncoderH265 * encoder) +{ + guint8 profile_idc; + + if (!ensure_hw_profile_limits (encoder)) + return FALSE; + + profile_idc = encoder->hw_max_profile_idc; + if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc) + profile_idc = encoder->max_profile_idc; + + /* Tuning options */ + if (!encoder->num_bframes) + encoder->num_bframes = 3; + + return TRUE; +} + +/* Ensure tuning options */ +static gboolean +ensure_tuning (GstVaapiEncoderH265 * encoder) +{ + gboolean success; + + switch (GST_VAAPI_ENCODER_TUNE (encoder)) { + case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: + success = ensure_tuning_high_compression (encoder); + break; + default: + success = TRUE; + break; + } + return success; +} + +/* Handle new GOP starts */ +static void +reset_gop_start (GstVaapiEncoderH265 * encoder) +{ + GstVaapiH265ReorderPool *const reorder_pool = &encoder->reorder_pool; + + reorder_pool->frame_index = 1; + reorder_pool->cur_present_index = 0; + ++encoder->idr_num; +} + +/* Marks the supplied picture as a B-frame */ +static void +set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder) +{ + g_assert (pic && encoder); + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_B; +} + +/* Marks the supplied picture as a P-frame */ +static void +set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder) +{ + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_P; +} + +/* Marks the supplied picture as an I-frame */ +static void +set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder) +{ + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_I; + + g_assert (pic->frame); + GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); +} + +/* Marks the supplied picture as an IDR frame */ +static void +set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder) +{ + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_I; + pic->poc = 0; + GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR); + + g_assert (pic->frame); + GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); +} + +/* Marks the supplied picture a a key-frame */ +static void +set_key_frame (GstVaapiEncPicture * picture, + GstVaapiEncoderH265 * encoder, gboolean is_idr) +{ + if (is_idr) { + reset_gop_start (encoder); + set_idr_frame (picture, encoder); + } else + set_i_frame (picture, encoder); +} + +/* Adds the supplied video parameter set header (VPS) to the list of packed + headers to pass down as-is to the encoder */ +static gboolean +add_packed_vps_header (GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) +{ + GstVaapiEncPackedHeader *packed_vps; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_vps_param = { 0 }; + const VAEncSequenceParameterBufferHEVC *const seq_param = sequence->param; + GstVaapiProfile profile = encoder->profile; + + guint32 data_bit_size; + guint8 *data; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H265_NAL_VPS); + + bs_write_vps (&bs, encoder, picture, seq_param, profile); + + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_vps_param.type = VAEncPackedHeaderSequence; + packed_vps_param.bit_length = data_bit_size; + packed_vps_param.has_emulation_bytes = 0; + + packed_vps = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_vps_param, sizeof (packed_vps_param), + data, (data_bit_size + 7) / 8); + g_assert (packed_vps); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_vps); + gst_vaapi_codec_object_replace (&packed_vps, NULL); + + /* store vps data */ + _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write VPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +/* Adds the supplied sequence header (SPS) to the list of packed + headers to pass down as-is to the encoder */ +static gboolean +add_packed_sequence_header (GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) +{ + GstVaapiEncPackedHeader *packed_seq; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 }; + const VAEncSequenceParameterBufferHEVC *const seq_param = sequence->param; + GstVaapiProfile profile = encoder->profile; + + guint32 data_bit_size; + guint8 *data; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H265_NAL_SPS); + + bs_write_sps (&bs, encoder, picture, seq_param, profile); + + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_seq_param.type = VAEncPackedHeaderSequence; + packed_seq_param.bit_length = data_bit_size; + packed_seq_param.has_emulation_bytes = 0; + + packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_seq_param, sizeof (packed_seq_param), + data, (data_bit_size + 7) / 8); + g_assert (packed_seq); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); + gst_vaapi_codec_object_replace (&packed_seq, NULL); + + /* store sps data */ + _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +/* Adds the supplied picture header (PPS) to the list of packed + headers to pass down as-is to the encoder */ +static gboolean +add_packed_picture_header (GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncPackedHeader *packed_pic; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 }; + const VAEncPictureParameterBufferHEVC *const pic_param = picture->param; + guint32 data_bit_size; + guint8 *data; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H265_NAL_PPS); + bs_write_pps (&bs, pic_param); + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_pic_param.type = VAEncPackedHeaderPicture; + packed_pic_param.bit_length = data_bit_size; + packed_pic_param.has_emulation_bytes = 0; + + packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_pic_param, sizeof (packed_pic_param), + data, (data_bit_size + 7) / 8); + g_assert (packed_pic); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_pic); + gst_vaapi_codec_object_replace (&packed_pic, NULL); + + /* store pps data */ + _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write PPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +static gboolean +get_nal_unit_type (GstVaapiEncPicture * picture, guint8 * nal_unit_type) +{ + switch (picture->type) { + case GST_VAAPI_PICTURE_TYPE_I: + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + *nal_unit_type = GST_H265_NAL_SLICE_IDR_W_RADL; + else + *nal_unit_type = GST_H265_NAL_SLICE_TRAIL_R; + break; + case GST_VAAPI_PICTURE_TYPE_P: + *nal_unit_type = GST_H265_NAL_SLICE_TRAIL_R; + break; + case GST_VAAPI_PICTURE_TYPE_B: + *nal_unit_type = GST_H265_NAL_SLICE_TRAIL_N; + break; + default: + return FALSE; + } + return TRUE; +} + +/* Adds the supplied slice header to the list of packed + headers to pass down as-is to the encoder */ +static gboolean +add_packed_slice_header (GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, GstVaapiEncSlice * slice) +{ + GstVaapiEncPackedHeader *packed_slice; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 }; + const VAEncSliceParameterBufferHEVC *const slice_param = slice->param; + guint32 data_bit_size; + guint8 *data; + guint8 nal_unit_type; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + + if (!get_nal_unit_type (picture, &nal_unit_type)) + goto bs_error; + bs_write_nal_header (&bs, nal_unit_type); + + bs_write_slice (&bs, slice_param, encoder, picture, nal_unit_type); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_slice_param.type = VAEncPackedHeaderSlice; + packed_slice_param.bit_length = data_bit_size; + packed_slice_param.has_emulation_bytes = 0; + + packed_slice = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_slice_param, sizeof (packed_slice_param), + data, (data_bit_size + 7) / 8); + g_assert (packed_slice); + + gst_vaapi_enc_slice_add_packed_header (slice, packed_slice); + gst_vaapi_codec_object_replace (&packed_slice, NULL); + + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Slice NAL unit header"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +/* Reference picture management */ +static void +reference_pic_free (GstVaapiEncoderH265 * encoder, GstVaapiEncoderH265Ref * ref) +{ + if (!ref) + return; + if (ref->pic) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic); + g_slice_free (GstVaapiEncoderH265Ref, ref); +} + +static inline GstVaapiEncoderH265Ref * +reference_pic_create (GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) +{ + GstVaapiEncoderH265Ref *const ref = g_slice_new0 (GstVaapiEncoderH265Ref); + + ref->pic = surface; + ref->poc = picture->poc; + return ref; +} + +static gboolean +reference_list_update (GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) +{ + GstVaapiEncoderH265Ref *ref; + GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool; + + if (GST_VAAPI_PICTURE_TYPE_B == picture->type) { + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface); + return TRUE; + } + + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { + while (!g_queue_is_empty (&ref_pool->ref_list)) + reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list)); + } else if (g_queue_get_length (&ref_pool->ref_list) >= + ref_pool->max_ref_frames) { + reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list)); + } + ref = reference_pic_create (encoder, picture, surface); + g_queue_push_tail (&ref_pool->ref_list, ref); + g_assert (g_queue_get_length (&ref_pool->ref_list) <= + ref_pool->max_ref_frames); + return TRUE; +} + +static gboolean +reference_list_init (GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, + GstVaapiEncoderH265Ref ** reflist_0, + guint * reflist_0_count, + GstVaapiEncoderH265Ref ** reflist_1, guint * reflist_1_count) +{ + GstVaapiEncoderH265Ref *tmp; + GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool; + GList *iter, *list_0_start = NULL, *list_1_start = NULL; + guint count; + + *reflist_0_count = 0; + *reflist_1_count = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_I) + return TRUE; + + iter = g_queue_peek_tail_link (&ref_pool->ref_list); + for (; iter; iter = g_list_previous (iter)) { + tmp = (GstVaapiEncoderH265Ref *) iter->data; + g_assert (tmp && tmp->poc != picture->poc); + if (_poc_greater_than (picture->poc, tmp->poc, encoder->max_pic_order_cnt)) { + list_0_start = iter; + list_1_start = g_list_next (iter); + break; + } + } + + /* order reflist_0 */ + g_assert (list_0_start); + iter = list_0_start; + count = 0; + for (; iter; iter = g_list_previous (iter)) { + reflist_0[count] = (GstVaapiEncoderH265Ref *) iter->data; + ++count; + } + *reflist_0_count = count; + + if (picture->type != GST_VAAPI_PICTURE_TYPE_B) + return TRUE; + + /* order reflist_1 */ + count = 0; + iter = list_1_start; + for (; iter; iter = g_list_next (iter)) { + reflist_1[count] = (GstVaapiEncoderH265Ref *) iter->data; + ++count; + } + *reflist_1_count = count; + return TRUE; +} + +/* Fills in VA sequence parameter buffer */ +static gboolean +fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) +{ + VAEncSequenceParameterBufferHEVC *const seq_param = sequence->param; + + memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferHEVC)); + + seq_param->general_profile_idc = encoder->profile_idc; + seq_param->general_level_idc = encoder->level_idc; + seq_param->general_tier_flag = 0; /* Fixme: use the tier flag extracted from upstream caps or calcuted one */ + + seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); + seq_param->intra_idr_period = encoder->idr_period; + seq_param->ip_period = 1 + encoder->num_bframes; + seq_param->ip_period = seq_param->intra_period > 1 ? + (1 + encoder->num_bframes) : 0; + seq_param->bits_per_second = encoder->bitrate_bits; + + seq_param->pic_width_in_luma_samples = encoder->luma_width; + seq_param->pic_height_in_luma_samples = encoder->luma_height; + + /*sequence field values */ + seq_param->seq_fields.value = 0; + seq_param->seq_fields.bits.chroma_format_idc = 1; + seq_param->seq_fields.bits.separate_colour_plane_flag = 0; + seq_param->seq_fields.bits.bit_depth_luma_minus8 = 0; + seq_param->seq_fields.bits.bit_depth_chroma_minus8 = 0; + seq_param->seq_fields.bits.scaling_list_enabled_flag = FALSE; + seq_param->seq_fields.bits.strong_intra_smoothing_enabled_flag = TRUE; + seq_param->seq_fields.bits.amp_enabled_flag = TRUE; + seq_param->seq_fields.bits.sample_adaptive_offset_enabled_flag = + encoder->sample_adaptive_offset_enabled_flag = FALSE; + seq_param->seq_fields.bits.pcm_enabled_flag = FALSE; + seq_param->seq_fields.bits.pcm_loop_filter_disabled_flag = FALSE; + seq_param->seq_fields.bits.sps_temporal_mvp_enabled_flag = + encoder->sps_temporal_mvp_enabled_flag = TRUE; + + /* Based on 32x32 CTU */ + seq_param->log2_min_luma_coding_block_size_minus3 = 0; + seq_param->log2_diff_max_min_luma_coding_block_size = 2; + seq_param->log2_min_transform_block_size_minus2 = 0; + seq_param->log2_diff_max_min_transform_block_size = 3; + seq_param->max_transform_hierarchy_depth_inter = 3; + seq_param->max_transform_hierarchy_depth_intra = 3; + + seq_param->pcm_sample_bit_depth_luma_minus1 = 0; + seq_param->pcm_sample_bit_depth_chroma_minus1 = 0; + seq_param->log2_min_pcm_luma_coding_block_size_minus3 = 0; + seq_param->log2_max_pcm_luma_coding_block_size_minus3 = 0; + + /* VUI parameters are always set, at least for timing_info (framerate) */ + seq_param->vui_parameters_present_flag = TRUE; + if (seq_param->vui_parameters_present_flag) { + seq_param->vui_fields.bits.aspect_ratio_info_present_flag = TRUE; + if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { + const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); + seq_param->aspect_ratio_idc = 0xff; + seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip); + seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip); + } + seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE; + seq_param->vui_fields.bits.vui_timing_info_present_flag = TRUE; + if (seq_param->vui_fields.bits.vui_timing_info_present_flag) { + seq_param->vui_num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder); + seq_param->vui_time_scale = GST_VAAPI_ENCODER_FPS_N (encoder); + } + } + return TRUE; +} + +/* Fills in VA picture parameter buffer */ +static gboolean +fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, + GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) +{ + VAEncPictureParameterBufferHEVC *const pic_param = picture->param; + GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool; + GstVaapiEncoderH265Ref *ref_pic; + GList *reflist; + guint i; + guint8 nal_unit_type, no_output_of_prior_pics_flag = 0; + + memset (pic_param, 0, sizeof (VAEncPictureParameterBufferHEVC)); + + pic_param->decoded_curr_pic.picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); + pic_param->decoded_curr_pic.pic_order_cnt = picture->poc; + pic_param->decoded_curr_pic.flags = 0; + + i = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (reflist = g_queue_peek_head_link (&ref_pool->ref_list); + reflist; reflist = g_list_next (reflist)) { + ref_pic = reflist->data; + g_assert (ref_pic && ref_pic->pic && + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID); + + pic_param->reference_frames[i].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); + ++i; + } + g_assert (i <= 15 && i <= ref_pool->max_ref_frames); + } + for (; i < 15; ++i) { + pic_param->reference_frames[i].picture_id = VA_INVALID_SURFACE; + pic_param->reference_frames[i].flags = 0; + } + pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + + /* slice_temporal_mvp_enable_flag == FALSE */ + pic_param->collocated_ref_pic_index = 0xFF; + + pic_param->last_picture = 0; + pic_param->pic_init_qp = encoder->init_qp; + pic_param->num_ref_idx_l0_default_active_minus1 = + (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0); + pic_param->num_ref_idx_l1_default_active_minus1 = + (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0); + + get_nal_unit_type (picture, &nal_unit_type); + pic_param->nal_unit_type = nal_unit_type; + + /* set picture fields */ + pic_param->pic_fields.value = 0; + pic_param->pic_fields.bits.idr_pic_flag = + GST_VAAPI_ENC_PICTURE_IS_IDR (picture); + pic_param->pic_fields.bits.coding_type = picture->type; + if (picture->type != GST_VAAPI_PICTURE_TYPE_B) + pic_param->pic_fields.bits.reference_pic_flag = TRUE; + pic_param->pic_fields.bits.sign_data_hiding_enabled_flag = FALSE; + pic_param->pic_fields.bits.transform_skip_enabled_flag = TRUE; + pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag = TRUE; + + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + no_output_of_prior_pics_flag = 1; + pic_param->pic_fields.bits.no_output_of_prior_pics_flag = + no_output_of_prior_pics_flag; + + return TRUE; +} + +/* Adds slice headers to picture */ +static gboolean +add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, + GstVaapiEncoderH265Ref ** reflist_0, guint reflist_0_count, + GstVaapiEncoderH265Ref ** reflist_1, guint reflist_1_count) +{ + VAEncSliceParameterBufferHEVC *slice_param; + GstVaapiEncSlice *slice; + guint slice_of_ctus, slice_mod_ctus, cur_slice_ctus; + guint ctu_size; + guint last_ctu_index; + guint i_slice, i_ref; + + g_assert (picture); + + ctu_size = encoder->ctu_width * encoder->ctu_height; + + g_assert (encoder->num_slices && encoder->num_slices < ctu_size); + slice_of_ctus = ctu_size / encoder->num_slices; + slice_mod_ctus = ctu_size % encoder->num_slices; + last_ctu_index = 0; + for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) { + cur_slice_ctus = slice_of_ctus; + if (slice_mod_ctus) { + ++cur_slice_ctus; + --slice_mod_ctus; + } + slice = GST_VAAPI_ENC_SLICE_NEW (HEVC, encoder); + g_assert (slice && slice->param_id != VA_INVALID_ID); + slice_param = slice->param; + + memset (slice_param, 0, sizeof (VAEncSliceParameterBufferHEVC)); + if (i_slice == 0) { + encoder->first_slice_segment_in_pic_flag = TRUE; + slice_param->slice_segment_address = 0; + } else { + encoder->first_slice_segment_in_pic_flag = FALSE; + slice_param->slice_segment_address = last_ctu_index; + } + slice_param->num_ctu_in_slice = cur_slice_ctus; + slice_param->slice_type = h265_get_slice_type (picture->type); + slice_param->slice_pic_parameter_set_id = 0; + + if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) + slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; + else + slice_param->num_ref_idx_l0_active_minus1 = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0) + slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; + else + slice_param->num_ref_idx_l1_active_minus1 = 0; + g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0); + g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0); + + i_ref = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (; i_ref < reflist_0_count; ++i_ref) { + slice_param->ref_pic_list0[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); + slice_param->ref_pic_list0[i_ref].pic_order_cnt = reflist_0[i_ref]->poc; + } + g_assert (i_ref == 1); + } + for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i_ref) { + slice_param->ref_pic_list0[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->ref_pic_list0[i_ref].flags = 0; + } + + i_ref = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + for (; i_ref < reflist_1_count; ++i_ref) { + slice_param->ref_pic_list1[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); + slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_1[i_ref]->poc; + } + g_assert (i_ref == 1); + } + for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i_ref) { + slice_param->ref_pic_list1[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->ref_pic_list1[i_ref].flags = 0; + } + + slice_param->max_num_merge_cand = 5; /* MaxNumMergeCand */ + slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp; + + slice_param->slice_fields.value = 0; + if (i_slice == encoder->num_slices - 1) + slice_param->slice_fields.bits.last_slice_of_pic_flag = 1; + + slice_param->slice_fields. + bits.slice_loop_filter_across_slices_enabled_flag = TRUE; + /* set calculation for next slice */ + last_ctu_index += cur_slice_ctus; + + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VAEncPackedHeaderHEVC_Slice) + && !add_packed_slice_header (encoder, picture, slice)) + goto error_create_packed_slice_hdr; + + gst_vaapi_enc_picture_add_slice (picture, slice); + gst_vaapi_codec_object_replace (&slice, NULL); + } + g_assert (last_ctu_index == ctu_size); + return TRUE; + +error_create_packed_slice_hdr: + { + GST_ERROR ("failed to create packed slice header buffer"); + gst_vaapi_codec_object_replace (&slice, NULL); + return FALSE; + } +} + +/* Generates and submits SPS header accordingly into the bitstream */ +static gboolean +ensure_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncSequence *sequence = NULL; + + /* submit an SPS header before every new I-frame, if codec config changed */ + if (!encoder->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I) + return TRUE; + + sequence = GST_VAAPI_ENC_SEQUENCE_NEW (HEVC, encoder); + if (!sequence || !fill_sequence (encoder, sequence)) + goto error_create_seq_param; + + /* add packed vps and sps headers */ + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderHEVC_SPS) + && !(add_packed_vps_header (encoder, picture, sequence) + && add_packed_sequence_header (encoder, picture, sequence))) { + goto error_create_packed_seq_hdr; + } + + if (sequence) { + gst_vaapi_enc_picture_set_sequence (picture, sequence); + gst_vaapi_codec_object_replace (&sequence, NULL); + } + + encoder->config_changed = FALSE; + return TRUE; + + /* ERRORS */ +error_create_seq_param: + { + GST_ERROR ("failed to create sequence parameter buffer (SPS)"); + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; + } +error_create_packed_seq_hdr: + { + GST_ERROR ("failed to create packed sequence header buffer"); + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; + } +} + +/* Generates and submits PPS header accordingly into the bitstream */ +static gboolean +ensure_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, + GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) +{ + GstVaapiCodedBuffer *const codedbuf = + GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); + gboolean res = FALSE; + + res = fill_picture (encoder, picture, codedbuf, surface); + + if (!res) + return FALSE; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_I && + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderHEVC_PPS) + && !add_packed_picture_header (encoder, picture)) { + GST_ERROR ("set picture packed header failed"); + return FALSE; + } + return TRUE; +} + +/* Generates slice headers */ +static gboolean +ensure_slices (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncoderH265Ref *reflist_0[15]; + GstVaapiEncoderH265Ref *reflist_1[15]; + GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool; + guint reflist_0_count = 0, reflist_1_count = 0; + + g_assert (picture); + + if (picture->type != GST_VAAPI_PICTURE_TYPE_I && + !reference_list_init (encoder, picture, + reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) { + GST_ERROR ("reference list reorder failed"); + return FALSE; + } + + g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames); + if (reflist_0_count > ref_pool->max_reflist0_count) + reflist_0_count = ref_pool->max_reflist0_count; + if (reflist_1_count > ref_pool->max_reflist1_count) + reflist_1_count = ref_pool->max_reflist1_count; + + if (!add_slice_headers (encoder, picture, + reflist_0, reflist_0_count, reflist_1, reflist_1_count)) + return FALSE; + + return TRUE; +} + +/* Estimates a good enough bitrate if none was supplied */ +static void +ensure_bitrate (GstVaapiEncoderH265 * encoder) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + + switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { + case GST_VAAPI_RATECONTROL_CBR: + case GST_VAAPI_RATECONTROL_VBR: + case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: + if (!base_encoder->bitrate) { + /* Fixme: Provide better estimation */ + /* Using a 1/6 compression ratio */ + /* 12 bits per pixel fro yuv420 */ + base_encoder->bitrate = + (encoder->luma_width * encoder->luma_height * 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); + } + break; + default: + base_encoder->bitrate = 0; + break; + } +} + +/* Constructs profile, tier and level information based on user-defined limits */ +static GstVaapiEncoderStatus +ensure_profile_tier_level (GstVaapiEncoderH265 * encoder) +{ + const GstVaapiProfile profile = encoder->profile; + const GstVaapiTierH265 tier = encoder->tier; + const GstVaapiLevelH265 level = encoder->level; + + ensure_tuning (encoder); + + if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + /* Check HW constraints */ + if (!ensure_hw_profile_limits (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + if (encoder->profile_idc > encoder->hw_max_profile_idc) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + /* ensure tier */ + if (!ensure_tier (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + + if (!ensure_level (encoder)) + /* Ensure bitrate if not set already and derive the right level to use */ + ensure_bitrate (encoder); + if (!ensure_level (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + + if (encoder->profile != profile || encoder->level != level + || encoder->tier != tier) { + GST_DEBUG ("selected %s profile at tier %s and level %s", + gst_vaapi_utils_h265_get_profile_string (encoder->profile), + gst_vaapi_utils_h265_get_tier_string (encoder->tier), + gst_vaapi_utils_h265_get_level_string (encoder->level)); + encoder->config_changed = TRUE; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static void +reset_properties (GstVaapiEncoderH265 * encoder) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + GstVaapiH265ReorderPool *reorder_pool; + GstVaapiH265RefPool *ref_pool; + guint ctu_size; + + if (encoder->idr_period < base_encoder->keyframe_period) + encoder->idr_period = base_encoder->keyframe_period; + if (encoder->idr_period > MAX_IDR_PERIOD) + encoder->idr_period = MAX_IDR_PERIOD; + + /*Fixme: provide user control for idr_period ?? */ + encoder->idr_period = base_encoder->keyframe_period * 2; + + if (encoder->min_qp > encoder->init_qp || + (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP && + encoder->min_qp < encoder->init_qp)) + encoder->min_qp = encoder->init_qp; + + ctu_size = encoder->ctu_width * encoder->ctu_height; + if (encoder->num_slices > (ctu_size + 1) / 2) + encoder->num_slices = (ctu_size + 1) / 2; + g_assert (encoder->num_slices); + + if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) + encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; + + if (encoder->num_bframes) + encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) / + GST_VAAPI_ENCODER_FPS_N (encoder); + else + encoder->cts_offset = 0; + + /* init max_poc */ + encoder->log2_max_pic_order_cnt = + h265_get_log2_max_pic_order_cnt (encoder->idr_period); + g_assert (encoder->log2_max_pic_order_cnt >= 4); + encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); + encoder->idr_num = 0; + + /* Only Supporting a maximum of two reference frames */ + if (encoder->num_bframes) { + encoder->max_dec_pic_buffering = 3; + encoder->max_num_reorder_pics = 1; + } else { + encoder->max_dec_pic_buffering = + (GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder) == 1) ? 1 : 2; + encoder->max_num_reorder_pics = 0; + } + + ref_pool = &encoder->ref_pool; + ref_pool->max_reflist0_count = 1; + ref_pool->max_reflist1_count = encoder->num_bframes > 0; + ref_pool->max_ref_frames = ref_pool->max_reflist0_count + + ref_pool->max_reflist1_count; + + reorder_pool = &encoder->reorder_pool; + reorder_pool->frame_index = 0; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h265_encode (GstVaapiEncoder * base_encoder, + GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) +{ + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265_CAST (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_picture (encoder, picture, codedbuf, reconstruct)) + goto error; + if (!ensure_slices (encoder, picture)) + goto error; + if (!gst_vaapi_enc_picture_encode (picture)) + goto error; + + if (!reference_list_update (encoder, picture, reconstruct)) + goto error; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +error: + if (reconstruct) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); + return ret; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h265_flush (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiH265ReorderPool *reorder_pool; + GstVaapiEncPicture *pic; + + reorder_pool = &encoder->reorder_pool; + reorder_pool->frame_index = 0; + reorder_pool->cur_present_index = 0; + + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&reorder_pool->reorder_frame_list); + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +/* Generate "codec-data" buffer */ +static GstVaapiEncoderStatus +gst_vaapi_encoder_h265_get_codec_data (GstVaapiEncoder * base_encoder, + GstBuffer ** out_buffer_ptr) +{ + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265_CAST (base_encoder); + const guint32 configuration_version = 0x01; + const guint32 nal_length_size = 4; + GstMapInfo vps_info, sps_info, pps_info; + GstBitWriter bs; + GstBuffer *buffer; + guint min_spatial_segmentation_idc = 0; + guint num_arrays = 3; + + if (!encoder->vps_data || !encoder->sps_data || !encoder->pps_data) + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER; + if (gst_buffer_get_size (encoder->sps_data) < 4) + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER; + + if (!gst_buffer_map (encoder->vps_data, &vps_info, GST_MAP_READ)) + goto error_map_vps_buffer; + + if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ)) + goto error_map_sps_buffer; + + if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ)) + goto error_map_pps_buffer; + + /* Header */ + gst_bit_writer_init (&bs, + (vps_info.size + sps_info.size + pps_info.size + 64) * 8); + WRITE_UINT32 (&bs, configuration_version, 8); + WRITE_UINT32 (&bs, sps_info.data[4], 8); /* profile_space | tier_flag | profile_idc */ + WRITE_UINT32 (&bs, sps_info.data[5], 32); /* profile_compatibility_flag [0-31] */ + /* progressive_source_flag | interlaced_source_flag | non_packed_constraint_flag | + * frame_only_constraint_flag | reserved_zero_bits[0-27] */ + WRITE_UINT32 (&bs, sps_info.data[9], 32); + WRITE_UINT32 (&bs, sps_info.data[13], 16); /* reserved_zero_bits [28-43] */ + WRITE_UINT32 (&bs, sps_info.data[15], 8); /* level_idc */ + WRITE_UINT32 (&bs, 0x0f, 4); /* 1111 */ + WRITE_UINT32 (&bs, min_spatial_segmentation_idc, 12); /* min_spatial_segmentation_idc */ + WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */ + WRITE_UINT32 (&bs, 0x00, 2); /* parallelismType */ + WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */ + WRITE_UINT32 (&bs, 0x01, 2); /* chroma_format_idc */ + WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */ + WRITE_UINT32 (&bs, 0x01, 3); /* bit_depth_luma_minus8 */ + WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */ + WRITE_UINT32 (&bs, 0x01, 3); /* bit_depth_chroma_minus8 */ + WRITE_UINT32 (&bs, 0x00, 16); /* avgFramerate */ + WRITE_UINT32 (&bs, 0x00, 2); /* constatnFramerate */ + WRITE_UINT32 (&bs, 0x00, 3); /* numTemporalLayers */ + WRITE_UINT32 (&bs, 0x00, 1); /* temporalIdNested */ + WRITE_UINT32 (&bs, nal_length_size - 1, 2); /* lengthSizeMinusOne */ + WRITE_UINT32 (&bs, 0x00, 8); /* numOfArrays */ + + WRITE_UINT32 (&bs, num_arrays, 8); /* numOfArrays */ + + /* Write VPS */ + WRITE_UINT32 (&bs, 0x00, 1); /* array_completeness */ + WRITE_UINT32 (&bs, 0x00, 1); /* reserved zero */ + WRITE_UINT32 (&bs, GST_H265_NAL_VPS, 6); /* Nal_unit_type */ + WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, VPS count = 1 */ + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + WRITE_UINT32 (&bs, vps_info.size, 16); /* VPS nalUnitLength */ + gst_bit_writer_put_bytes (&bs, vps_info.data, vps_info.size); + + /* Write SPS */ + WRITE_UINT32 (&bs, 0x00, 1); /* array_completeness */ + WRITE_UINT32 (&bs, 0x00, 1); /* reserved zero */ + WRITE_UINT32 (&bs, GST_H265_NAL_SPS, 6); /* Nal_unit_type */ + WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, SPS count = 1 */ + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + WRITE_UINT32 (&bs, sps_info.size, 16); /* SPS nalUnitLength */ + gst_bit_writer_put_bytes (&bs, sps_info.data, sps_info.size); + + /* Write PPS */ + WRITE_UINT32 (&bs, 0x00, 1); /* array_completeness */ + WRITE_UINT32 (&bs, 0x00, 1); /* reserved zero */ + WRITE_UINT32 (&bs, GST_H265_NAL_PPS, 6); /* Nal_unit_type */ + WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, PPS count = 1 */ + WRITE_UINT32 (&bs, pps_info.size, 16); /* PPS nalUnitLength */ + gst_bit_writer_put_bytes (&bs, pps_info.data, pps_info.size); + + gst_buffer_unmap (encoder->pps_data, &pps_info); + gst_buffer_unmap (encoder->sps_data, &sps_info); + gst_buffer_unmap (encoder->vps_data, &vps_info); + + buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&bs), + GST_BIT_WRITER_BIT_SIZE (&bs) / 8); + if (!buffer) + goto error_alloc_buffer; + *out_buffer_ptr = buffer; + + gst_bit_writer_clear (&bs, FALSE); + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +bs_error: + { + GST_ERROR ("failed to write codec-data"); + gst_buffer_unmap (encoder->vps_data, &vps_info); + gst_buffer_unmap (encoder->sps_data, &sps_info); + gst_buffer_unmap (encoder->pps_data, &pps_info); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +error_map_vps_buffer: + { + GST_ERROR ("failed to map VPS packed header"); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_map_sps_buffer: + { + GST_ERROR ("failed to map SPS packed header"); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_map_pps_buffer: + { + GST_ERROR ("failed to map PPS packed header"); + gst_buffer_unmap (encoder->sps_data, &sps_info); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_alloc_buffer: + { + GST_ERROR ("failed to allocate codec-data buffer"); + gst_bit_writer_clear (&bs, TRUE); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +} + +/* TODO */ +/* The re-ordering algorithm is similar to what we implemented for + * h264 encoder. But We could have a better algorithm for hevc encoder + * by having B-frames as reference pictures */ +static GstVaapiEncoderStatus +gst_vaapi_encoder_h265_reordering (GstVaapiEncoder * base_encoder, + GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) +{ + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiH265ReorderPool *reorder_pool = NULL; + GstVaapiEncPicture *picture; + gboolean is_idr = FALSE; + + *output = NULL; + + reorder_pool = &encoder->reorder_pool; + + if (!frame) { + if (reorder_pool->reorder_state != GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES) + return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; + + /* reorder_state = GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES + dump B frames from queue, sometime, there may also have P frame or I frame */ + g_assert (encoder->num_bframes > 0); + g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list), + GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN); + picture = g_queue_pop_head (&reorder_pool->reorder_frame_list); + g_assert (picture); + if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES; + } + goto end; + } + + /* new frame coming */ + picture = GST_VAAPI_ENC_PICTURE_NEW (HEVC, encoder, frame); + if (!picture) { + GST_WARNING ("create H265 picture failed, frame timestamp:%" + GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } + ++reorder_pool->cur_present_index; + picture->poc = ((reorder_pool->cur_present_index * 1) % + encoder->max_pic_order_cnt); + + is_idr = (reorder_pool->frame_index == 0 || + reorder_pool->frame_index >= encoder->idr_period); + + /* check key frames */ + if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) || + (reorder_pool->frame_index % + GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == 0) { + ++reorder_pool->frame_index; + + /* b frame enabled, check queue of reorder_frame_list */ + if (encoder->num_bframes + && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + GstVaapiEncPicture *p_pic; + + p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list); + set_p_frame (p_pic, encoder); + g_queue_foreach (&reorder_pool->reorder_frame_list, + (GFunc) set_b_frame, encoder); + set_key_frame (picture, encoder, is_idr); + g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); + picture = p_pic; + reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES; + } else { /* no b frames in queue */ + set_key_frame (picture, encoder, is_idr); + g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list)); + if (encoder->num_bframes) + reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES; + } + goto end; + } + + /* new p/b frames coming */ + ++reorder_pool->frame_index; + if (reorder_pool->reorder_state == GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES && + g_queue_get_length (&reorder_pool->reorder_frame_list) < + encoder->num_bframes) { + g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); + return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; + } + + set_p_frame (picture, encoder); + + if (reorder_pool->reorder_state == GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES) { + g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame, + encoder); + reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES; + g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list)); + } + +end: + g_assert (picture); + frame = picture->frame; + if (GST_CLOCK_TIME_IS_VALID (frame->pts)) + frame->pts += encoder->cts_offset; + *output = picture; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static GstVaapiEncoderStatus +set_context_info (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); + const guint DEFAULT_SURFACES_COUNT = 3; + + /* Fixme: Using only a rough approximation for bitstream headers.. + * Fixme: Not taken into account: ScalingList, RefPicListModification, PredWeightTable */ + /* Maximum sizes for common headers (in bits) */ + enum + { + MAX_PROFILE_TIER_LEVEL_SIZE = 684, + MAX_VPS_HDR_SIZE = 13781, + MAX_SPS_HDR_SIZE = 615, + MAX_SHORT_TERM_REFPICSET_SIZE = 55, + MAX_VUI_PARAMS_SIZE = 267, + MAX_HRD_PARAMS_SIZE = 8196, + MAX_PPS_HDR_SIZE = 274, + MAX_SLICE_HDR_SIZE = 33660 + }; + + /* Account for VPS header */ + base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_VPS_HDR_SIZE + + MAX_PROFILE_TIER_LEVEL_SIZE + MAX_HRD_PARAMS_SIZE) / 8; + + /* Account for SPS header */ + base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE + + MAX_PROFILE_TIER_LEVEL_SIZE + 64 * MAX_SHORT_TERM_REFPICSET_SIZE + + MAX_VUI_PARAMS_SIZE + MAX_HRD_PARAMS_SIZE) / 8; + + /* Account for PPS header */ + base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8; + + /* Account for slice header */ + base_encoder->codedbuf_size += encoder->num_slices * (4 + + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE + MAX_SHORT_TERM_REFPICSET_SIZE) / 8); + + if (!ensure_hw_profile (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + base_encoder->num_ref_frames = + ((encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT); + + /* Take an approximation of 6 times compression ratio */ + base_encoder->codedbuf_size = ((GST_ROUND_UP_32 (vip->width) * + GST_ROUND_UP_32 (vip->height) * 12 / 6)) / 8; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiEncoderStatus status; + guint luma_width, luma_height; + + luma_width = GST_VAAPI_ENCODER_WIDTH (encoder); + luma_height = GST_VAAPI_ENCODER_HEIGHT (encoder); + + if (luma_width != encoder->luma_width || luma_height != encoder->luma_height) { + GST_DEBUG ("resolution: %d %d", GST_VAAPI_ENCODER_WIDTH (encoder), + GST_VAAPI_ENCODER_HEIGHT (encoder)); + encoder->luma_width = GST_ROUND_UP_32 (luma_width); + encoder->luma_height = GST_ROUND_UP_32 (luma_height); + encoder->ctu_width = (encoder->luma_width + 31) / 32; + encoder->ctu_height = (encoder->luma_height + 31) / 32; + encoder->config_changed = TRUE; + + /* Frame Cropping */ + if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 31) || + (GST_VAAPI_ENCODER_HEIGHT (encoder) & 31)) { + static const guint SubWidthC[] = { 1, 2, 2, 1 }; + static const guint SubHeightC[] = { 1, 2, 1, 1 }; + encoder->conformance_window_flag = 1; + encoder->conf_win_left_offset = 0; + encoder->conf_win_right_offset = + (encoder->luma_width - + GST_VAAPI_ENCODER_WIDTH (encoder)) / SubWidthC[1]; + encoder->conf_win_top_offset = 0; + encoder->conf_win_bottom_offset = + (encoder->luma_height - + GST_VAAPI_ENCODER_HEIGHT (encoder)) / SubHeightC[1]; + } + } + + status = ensure_profile_tier_level (encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + + reset_properties (encoder); + return set_context_info (base_encoder); +} + +static gboolean +gst_vaapi_encoder_h265_init (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiH265ReorderPool *reorder_pool; + GstVaapiH265RefPool *ref_pool; + + encoder->conformance_window_flag = 0; + encoder->num_slices = 1; + + /* re-ordering list initialize */ + reorder_pool = &encoder->reorder_pool; + g_queue_init (&reorder_pool->reorder_frame_list); + reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_NONE; + reorder_pool->frame_index = 0; + reorder_pool->cur_present_index = 0; + + /* reference list info initialize */ + ref_pool = &encoder->ref_pool; + g_queue_init (&ref_pool->ref_list); + ref_pool->max_ref_frames = 0; + ref_pool->max_reflist0_count = 1; + ref_pool->max_reflist1_count = 1; + + return TRUE; +} + +static void +gst_vaapi_encoder_h265_finalize (GstVaapiEncoder * base_encoder) +{ + /*free private buffers */ + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiEncPicture *pic; + GstVaapiEncoderH265Ref *ref; + GstVaapiH265RefPool *ref_pool; + GstVaapiH265ReorderPool *reorder_pool; + + gst_buffer_replace (&encoder->vps_data, NULL); + gst_buffer_replace (&encoder->sps_data, NULL); + gst_buffer_replace (&encoder->pps_data, NULL); + + /* reference list info de-init */ + ref_pool = &encoder->ref_pool; + while (!g_queue_is_empty (&ref_pool->ref_list)) { + ref = (GstVaapiEncoderH265Ref *) g_queue_pop_head (&ref_pool->ref_list); + reference_pic_free (encoder, ref); + } + g_queue_clear (&ref_pool->ref_list); + + /* re-ordering list initialize */ + reorder_pool = &encoder->reorder_pool; + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&reorder_pool->reorder_frame_list); +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, + gint prop_id, const GValue * value) +{ + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265_CAST (base_encoder); + + switch (prop_id) { + case GST_VAAPI_ENCODER_H265_PROP_MAX_BFRAMES: + encoder->num_bframes = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H265_PROP_INIT_QP: + encoder->init_qp = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H265_PROP_MIN_QP: + encoder->min_qp = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES: + encoder->num_slices = g_value_get_uint (value); + if (encoder->num_slices > 1) + GST_ERROR ("Mulit-slice encoding is not yet functional!"); + break; + default: + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H265); + +static inline const GstVaapiEncoderClass * +gst_vaapi_encoder_h265_class (void) +{ + static const GstVaapiEncoderClass GstVaapiEncoderH265Class = { + GST_VAAPI_ENCODER_CLASS_INIT (H265, h265), + .set_property = gst_vaapi_encoder_h265_set_property, + .get_codec_data = gst_vaapi_encoder_h265_get_codec_data + }; + return &GstVaapiEncoderH265Class; +} + +/** + * gst_vaapi_encoder_h265_new: + * @display: a #GstVaapiDisplay + * + * Creates a new #GstVaapiEncoder for H.265 encoding. Note that the + * only supported output stream format is "byte-stream" format. + * + * Return value: the newly allocated #GstVaapiEncoder object + */ +GstVaapiEncoder * +gst_vaapi_encoder_h265_new (GstVaapiDisplay * display) +{ + return gst_vaapi_encoder_new (gst_vaapi_encoder_h265_class (), display); +} + +/** + * gst_vaapi_encoder_h265_get_default_properties: + * + * Determines the set of common and H.265 specific encoder properties. + * The caller owns an extra reference to the resulting array of + * #GstVaapiEncoderPropInfo elements, so it shall be released with + * g_ptr_array_unref() after usage. + * + * Return value: the set of encoder properties for #GstVaapiEncoderH265, + * or %NULL if an error occurred. + */ +GPtrArray * +gst_vaapi_encoder_h265_get_default_properties (void) +{ + const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h265_class (); + GPtrArray *props; + + props = gst_vaapi_encoder_properties_get_default (klass); + if (!props) + return NULL; + + /** + * GstVaapiEncoderH265:max-bframes: + * + * The number of B-frames between I and P. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H265_PROP_MAX_BFRAMES, + g_param_spec_uint ("max-bframes", + "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH265:init-qp: + * + * The initial quantizer value. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H265_PROP_INIT_QP, + g_param_spec_uint ("init-qp", + "Initial QP", "Initial quantizer value", 1, 51, 26, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH265:min-qp: + * + * The minimum quantizer value. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H265_PROP_MIN_QP, + g_param_spec_uint ("min-qp", + "Minimum QP", "Minimum quantizer value", 1, 51, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /* Fixme: there seems to be issues with multi-slice encoding */ + /** + * GstVaapiEncoderH265:num-slices: + * + * The number of slices per frame. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES, + g_param_spec_uint ("num-slices", + "Number of Slices", + "Number of slices per frame", + 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; +} + +/** + * gst_vaapi_encoder_h265_set_max_profile: + * @encoder: a #GstVaapiEncoderH265 + * @profile: an H.265 #GstVaapiProfile + * + * Notifies the @encoder to use coding tools from the supplied + * @profile at most. + * + * This means that if the minimal profile derived to + * support the specified coding tools is greater than this @profile, + * then an error is returned when the @encoder is configured. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_encoder_h265_set_max_profile (GstVaapiEncoderH265 * encoder, + GstVaapiProfile profile) +{ + guint8 profile_idc; + + g_return_val_if_fail (encoder != NULL, FALSE); + g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE); + + if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H265) + return FALSE; + + profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile); + if (!profile_idc) + return FALSE; + + encoder->max_profile_idc = profile_idc; + return TRUE; +} + +/** + * gst_vaapi_encoder_h265_get_profile_tier_level: + * @encoder: a #GstVaapiEncoderH265 + * @out_profile_ptr: return location for the #GstVaapiProfile + * @out_level_ptr: return location for the #GstVaapiLevelH265 + * @out_tier_ptr: return location for the #GstVaapiTierH265 + * + * Queries the H.265 @encoder for the active profile and level. That + * information is only constructed and valid after the encoder is + * configured, i.e. after the gst_vaapi_encoder_set_codec_state() + * function is called. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_encoder_h265_get_profile_tier_level (GstVaapiEncoderH265 * encoder, + GstVaapiProfile * out_profile_ptr, GstVaapiTierH265 * out_tier_ptr, + GstVaapiLevelH265 * out_level_ptr) +{ + g_return_val_if_fail (encoder != NULL, FALSE); + + if (!encoder->profile || !encoder->tier || !encoder->level) + return FALSE; + + if (out_profile_ptr) + *out_profile_ptr = encoder->profile; + if (out_level_ptr) + *out_level_ptr = encoder->level; + if (out_tier_ptr) + *out_tier_ptr = encoder->tier; + + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h new file mode 100644 index 0000000000..ec8483e5b7 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -0,0 +1,72 @@ +/* + * gstvaapiencoder_h265.h - H.265 encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_ENCODER_H265(encoder) \ + ((GstVaapiEncoderH265 *) (encoder)) + +typedef struct _GstVaapiEncoderH265 GstVaapiEncoderH265; + +/** + * GstVaapiEncoderH265Prop: + * @GST_VAAPI_ENCODER_H265_PROP_MAX_BFRAMES: Number of B-frames between I + * and P (uint). + * @GST_VAAPI_ENCODER_H265_PROP_INIT_QP: Initial quantizer value (uint). + * @GST_VAAPI_ENCODER_H265_PROP_MIN_QP: Minimal quantizer value (uint). + * @GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES: Number of slices per frame (uint). + * @GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH: Length of the CPB buffer + * in milliseconds (uint). + * + * The set of H.265 encoder specific configurable properties. + */ +typedef enum { + GST_VAAPI_ENCODER_H265_PROP_MAX_BFRAMES = -1, + GST_VAAPI_ENCODER_H265_PROP_INIT_QP = -2, + GST_VAAPI_ENCODER_H265_PROP_MIN_QP = -3, + GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES = -4, + GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH = -7 +} GstVaapiEncoderH265Prop; + +GstVaapiEncoder * +gst_vaapi_encoder_h265_new (GstVaapiDisplay * display); + +GPtrArray * +gst_vaapi_encoder_h265_get_default_properties (void); + +gboolean +gst_vaapi_encoder_h265_set_max_profile (GstVaapiEncoderH265 * encoder, + GstVaapiProfile profile); + +gboolean +gst_vaapi_encoder_h265_get_profile_tier_level (GstVaapiEncoderH265 * encoder, + GstVaapiProfile * out_profile_ptr, GstVaapiTierH265 *out_tier_ptr, GstVaapiLevelH265 * out_level_ptr); + +G_END_DECLS + +#endif /*GST_VAAPI_ENCODER_H265_H */ From eaf57cc90b991a59aed548f4a4ad022500c5aa5f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 25 May 2015 11:58:20 +0300 Subject: [PATCH 2008/3781] HEVC_Encode: Add HEVC(h265) Encoder plugin https://bugzilla.gnome.org/show_bug.cgi?id=748874 Signed-off-by: Sreerenj Balachandran --- gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapi.c | 10 + gst/vaapi/gstvaapiencode_h265.c | 403 ++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode_h265.h | 71 ++++++ 4 files changed, 486 insertions(+) create mode 100644 gst/vaapi/gstvaapiencode_h265.c create mode 100644 gst/vaapi/gstvaapiencode_h265.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index a66db37cce..75cf214c4b 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -81,12 +81,14 @@ libgstvaapi_enc_source_c = \ gstvaapiencode.c \ gstvaapiencode_h264.c \ gstvaapiencode_mpeg2.c \ + gstvaapiencode_h265.c \ $(NULL) libgstvaapi_enc_source_h = \ gstvaapiencode.h \ gstvaapiencode_h264.h \ gstvaapiencode_mpeg2.h \ + gstvaapiencode_h265.h \ $(NULL) if USE_ENCODERS diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 64ee44c477..e5bf227257 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -42,6 +42,10 @@ #include "gstvaapiencode_vp8.h" #endif +#if USE_H265_ENCODER +#include "gstvaapiencode_h265.h" +#endif + #define PLUGIN_NAME "vaapi" #define PLUGIN_DESC "VA-API based elements" #define PLUGIN_LICENSE "LGPL" @@ -77,6 +81,12 @@ plugin_init (GstPlugin *plugin) GST_TYPE_VAAPIENCODE_VP8); #endif +#if USE_H265_ENCODER + gst_element_register(plugin, "vaapiencode_h265", + GST_RANK_PRIMARY, + GST_TYPE_VAAPIENCODE_H265); +#endif + #if GST_CHECK_VERSION(1,4,0) gst_element_register(plugin, "vaapidecodebin", GST_RANK_PRIMARY + 2, diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c new file mode 100644 index 0000000000..9bd38b6eb3 --- /dev/null +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -0,0 +1,403 @@ +/* + * gstvaapiencode_h265.c - VA-API H.265 encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 "gstcompat.h" +#include +#include +#include +#include "gstvaapiencode_h265.h" +#include "gstvaapipluginutil.h" +#include "gstvaapivideomemory.h" + +#define GST_PLUGIN_NAME "vaapiencode_h265" +#define GST_PLUGIN_DESC "A VA-API based H.265 video encoder" + +GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h265_encode_debug); +#define GST_CAT_DEFAULT gst_vaapi_h265_encode_debug + +#define GST_CODEC_CAPS \ + "video/x-h265, " \ + "stream-format = (string) { hvc1, byte-stream }, " \ + "alignment = (string) au" + +/* *INDENT-OFF* */ +static const char gst_vaapiencode_h265_sink_caps_str[] = + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, + "{ ENCODED, NV12, I420, YV12 }") ", " + GST_CAPS_INTERLACED_FALSE "; " + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static const char gst_vaapiencode_h265_src_caps_str[] = + GST_CODEC_CAPS ", " + "profile = (string) { main }"; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapiencode_h265_sink_factory = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_h265_sink_caps_str)); +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapiencode_h265_src_factory = + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_h265_src_caps_str)); +/* *INDENT-ON* */ + +/* h265 encode */ +G_DEFINE_TYPE (GstVaapiEncodeH265, gst_vaapiencode_h265, GST_TYPE_VAAPIENCODE); + +static void +gst_vaapiencode_h265_init (GstVaapiEncodeH265 * encode) +{ + gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); +} + +static void +gst_vaapiencode_h265_finalize (GObject * object) +{ + G_OBJECT_CLASS (gst_vaapiencode_h265_parent_class)->finalize (object); +} + +static void +gst_vaapiencode_h265_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + default: + if (!encode_class->set_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapiencode_h265_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + default: + if (!encode_class->get_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +typedef struct +{ + GstVaapiProfile best_profile; + guint best_score; +} FindBestProfileData; + +static void +find_best_profile_value (FindBestProfileData * data, const GValue * value) +{ + const gchar *str; + GstVaapiProfile profile; + guint score; + + if (!value || !G_VALUE_HOLDS_STRING (value)) + return; + + str = g_value_get_string (value); + if (!str) + return; + profile = gst_vaapi_utils_h265_get_profile_from_string (str); + if (!profile) + return; + score = gst_vaapi_utils_h265_get_profile_score (profile); + if (score < data->best_score) + return; + data->best_profile = profile; + data->best_score = score; +} + +static GstVaapiProfile +find_best_profile (GstCaps * caps) +{ + FindBestProfileData data; + guint i, j, num_structures, num_values; + + data.best_profile = GST_VAAPI_PROFILE_UNKNOWN; + data.best_score = 0; + + num_structures = gst_caps_get_size (caps); + for (i = 0; i < num_structures; i++) { + GstStructure *const structure = gst_caps_get_structure (caps, i); + const GValue *const value = gst_structure_get_value (structure, "profile"); + + if (!value) + continue; + if (G_VALUE_HOLDS_STRING (value)) + find_best_profile_value (&data, value); + else if (GST_VALUE_HOLDS_LIST (value)) { + num_values = gst_value_list_get_size (value); + for (j = 0; j < num_values; j++) + find_best_profile_value (&data, gst_value_list_get_value (value, j)); + } + } + return data.best_profile; +} + +static gboolean +gst_vaapiencode_h265_set_config (GstVaapiEncode * base_encode) +{ + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265 (base_encode->encoder); + GstCaps *allowed_caps; + GstVaapiProfile profile; + + /* Check for the largest profile that is supported */ + allowed_caps = + gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (base_encode)); + if (!allowed_caps) + return TRUE; + + profile = find_best_profile (allowed_caps); + gst_caps_unref (allowed_caps); + if (profile) { + GST_INFO ("using %s profile as target decoder constraints", + gst_vaapi_utils_h265_get_profile_string (profile)); + if (!gst_vaapi_encoder_h265_set_max_profile (encoder, profile)) + return FALSE; + } + return TRUE; +} + +static GstCaps * +gst_vaapiencode_h265_get_caps (GstVaapiEncode * base_encode) +{ + GstVaapiEncodeH265 *const encode = GST_VAAPIENCODE_H265_CAST (base_encode); + GstCaps *caps, *allowed_caps; + + caps = gst_caps_from_string (GST_CODEC_CAPS); + + /* Check whether "stream-format" is hvcC mode */ + allowed_caps = + gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); + if (allowed_caps) { + const char *stream_format = NULL; + GstStructure *structure; + guint i, num_structures; + + num_structures = gst_caps_get_size (allowed_caps); + for (i = 0; !stream_format && i < num_structures; i++) { + structure = gst_caps_get_structure (allowed_caps, i); + if (!gst_structure_has_field_typed (structure, "stream-format", + G_TYPE_STRING)) + continue; + stream_format = gst_structure_get_string (structure, "stream-format"); + } + encode->is_hvc = stream_format && strcmp (stream_format, "hvc1") == 0; + gst_caps_unref (allowed_caps); + } + gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, + encode->is_hvc ? "hvc1" : "byte-stream", NULL); + + base_encode->need_codec_data = encode->is_hvc; + + /* XXX: update profile and level information */ + return caps; +} + +static GstVaapiEncoder * +gst_vaapiencode_h265_alloc_encoder (GstVaapiEncode * base, + GstVaapiDisplay * display) +{ + return gst_vaapi_encoder_h265_new (display); +} + +/* h265 NAL byte stream operations */ +static guint8 * +_h265_byte_stream_next_nal (guint8 * buffer, guint32 len, guint32 * nal_size) +{ + const guint8 *cur = buffer; + const guint8 *const end = buffer + len; + guint8 *nal_start = NULL; + guint32 flag = 0xFFFFFFFF; + guint32 nal_start_len = 0; + + g_assert (len >= 0 && buffer && nal_size); + if (len < 3) { + *nal_size = len; + nal_start = (len ? buffer : NULL); + return nal_start; + } + + /*locate head postion */ + if (!buffer[0] && !buffer[1]) { + if (buffer[2] == 1) { /* 0x000001 */ + nal_start_len = 3; + } else if (!buffer[2] && len >= 4 && buffer[3] == 1) { /* 0x00000001 */ + nal_start_len = 4; + } + } + nal_start = buffer + nal_start_len; + cur = nal_start; + + /*find next nal start position */ + while (cur < end) { + flag = ((flag << 8) | ((*cur++) & 0xFF)); + if ((flag & 0x00FFFFFF) == 0x00000001) { + if (flag == 0x00000001) + *nal_size = cur - 4 - nal_start; + else + *nal_size = cur - 3 - nal_start; + break; + } + } + if (cur >= end) { + *nal_size = end - nal_start; + if (nal_start >= end) { + nal_start = NULL; + } + } + return nal_start; +} + +static inline void +_start_code_to_size (guint8 nal_start_code[4], guint32 nal_size) +{ + nal_start_code[0] = ((nal_size >> 24) & 0xFF); + nal_start_code[1] = ((nal_size >> 16) & 0xFF); + nal_start_code[2] = ((nal_size >> 8) & 0xFF); + nal_start_code[3] = (nal_size & 0xFF); +} + +static gboolean +_h265_convert_byte_stream_to_hvc (GstBuffer * buf) +{ + GstMapInfo info; + guint32 nal_size; + guint8 *nal_start_code, *nal_body; + guint8 *frame_end; + + g_assert (buf); + + if (!gst_buffer_map (buf, &info, GST_MAP_READ | GST_MAP_WRITE)) + return FALSE; + + nal_start_code = info.data; + frame_end = info.data + info.size; + nal_size = 0; + + while ((frame_end > nal_start_code) && + (nal_body = _h265_byte_stream_next_nal (nal_start_code, + frame_end - nal_start_code, &nal_size)) != NULL) { + if (!nal_size) + goto error; + + g_assert (nal_body - nal_start_code == 4); + _start_code_to_size (nal_start_code, nal_size); + nal_start_code = nal_body + nal_size; + } + gst_buffer_unmap (buf, &info); + return TRUE; + +error: + gst_buffer_unmap (buf, &info); + return FALSE; +} + +static GstFlowReturn +gst_vaapiencode_h265_alloc_buffer (GstVaapiEncode * base_encode, + GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buffer_ptr) +{ + GstVaapiEncodeH265 *const encode = GST_VAAPIENCODE_H265_CAST (base_encode); + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265 (base_encode->encoder); + GstFlowReturn ret; + + g_return_val_if_fail (encoder != NULL, GST_FLOW_ERROR); + + ret = + GST_VAAPIENCODE_CLASS (gst_vaapiencode_h265_parent_class)->alloc_buffer + (base_encode, coded_buf, out_buffer_ptr); + if (ret != GST_FLOW_OK) + return ret; + + if (!encode->is_hvc) + return GST_FLOW_OK; + + /* Convert to hvcC format */ + if (!_h265_convert_byte_stream_to_hvc (*out_buffer_ptr)) + goto error_convert_buffer; + return GST_FLOW_OK; + + /* ERRORS */ +error_convert_buffer: + { + GST_ERROR ("failed to convert from bytestream format to hvcC format"); + gst_buffer_replace (out_buffer_ptr, NULL); + return GST_FLOW_ERROR; + } +} + +static void +gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_vaapi_h265_encode_debug, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + object_class->finalize = gst_vaapiencode_h265_finalize; + object_class->set_property = gst_vaapiencode_h265_set_property; + object_class->get_property = gst_vaapiencode_h265_get_property; + + encode_class->get_properties = gst_vaapi_encoder_h265_get_default_properties; + encode_class->set_config = gst_vaapiencode_h265_set_config; + encode_class->get_caps = gst_vaapiencode_h265_get_caps; + encode_class->alloc_encoder = gst_vaapiencode_h265_alloc_encoder; + encode_class->alloc_buffer = gst_vaapiencode_h265_alloc_buffer; + + gst_element_class_set_static_metadata (element_class, + "VA-API H.265 encoder", + "Codec/Encoder/Video", + GST_PLUGIN_DESC, + "Sreerenj Balachandran "); + + /* sink pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_h265_sink_factory)); + + /* src pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_h265_src_factory)); + + gst_vaapiencode_class_init_properties (encode_class); +} diff --git a/gst/vaapi/gstvaapiencode_h265.h b/gst/vaapi/gstvaapiencode_h265.h new file mode 100644 index 0000000000..db567b3946 --- /dev/null +++ b/gst/vaapi/gstvaapiencode_h265.h @@ -0,0 +1,71 @@ +/* + * gstvaapiencode_h265.h - VA-API H.265 encoder + * + * Copyright (C) 2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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_VAAPIENCODE_H265_H +#define GST_VAAPIENCODE_H265_H + +#include +#include "gstvaapiencode.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIENCODE_H265 \ + (gst_vaapiencode_h265_get_type ()) +#define GST_VAAPIENCODE_H265_CAST(obj) \ + ((GstVaapiEncodeH265 *)(obj)) +#define GST_VAAPIENCODE_H265(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPIENCODE_H265, \ + GstVaapiEncodeH265)) +#define GST_VAAPIENCODE_H265_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPIENCODE_H265, \ + GstVaapiEncodeH265Class)) +#define GST_VAAPIENCODE_H265_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPIENCODE_H265, \ + GstVaapiEncodeH265Class)) +#define GST_IS_VAAPIENCODE_H265(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_H265)) +#define GST_IS_VAAPIENCODE_H265_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_H265)) + +typedef struct _GstVaapiEncodeH265 GstVaapiEncodeH265; +typedef struct _GstVaapiEncodeH265Class GstVaapiEncodeH265Class; + +struct _GstVaapiEncodeH265 +{ + /*< private >*/ + GstVaapiEncode parent_instance; + + guint is_hvc:1; /* [FALSE]=byte-stream (default); [TRUE]=hvcC */ +}; + +struct _GstVaapiEncodeH265Class +{ + /*< private >*/ + GstVaapiEncodeClass parent_class; +}; + +GType +gst_vaapiencode_h265_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GST_VAAPIENCODE_H265_H */ From 8762b04a192a6ab6dcccad96770fc0025de8bcbc Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 26 May 2015 05:33:33 +0300 Subject: [PATCH 2009/3781] HEVC: decode: Update Cropping Rectangle Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 98eb93ee92..0630617f6a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -50,8 +50,7 @@ typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; typedef struct _GstVaapiParserInfoH265 GstVaapiParserInfoH265; typedef struct _GstVaapiPictureH265 GstVaapiPictureH265; -static gboolean -nal_is_slice (guint8 nal_type); +static gboolean nal_is_slice (guint8 nal_type); /* ------------------------------------------------------------------------- */ /* --- H.265 Parser Info --- */ @@ -276,7 +275,7 @@ gst_vaapi_picture_h265_set_reference (GstVaapiPictureH265 * picture, struct _GstVaapiFrameStore { - /*< private >*/ + /*< private > */ GstVaapiMiniObject parent_instance; GstVaapiPictureH265 *buffer; @@ -425,7 +424,7 @@ struct _GstVaapiDecoderH265Private */ struct _GstVaapiDecoderH265 { - /*< private >*/ + /*< private > */ GstVaapiDecoder parent_instance; GstVaapiDecoderH265Private priv; }; @@ -437,7 +436,7 @@ struct _GstVaapiDecoderH265 */ struct _GstVaapiDecoderH265Class { - /*< private >*/ + /*< private > */ GstVaapiDecoderClass parent_class; }; @@ -2251,7 +2250,14 @@ decode_picture (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) gst_vaapi_picture_unref (picture); /* Update cropping rectangle */ - /* Fixme: Add cropping rectangle, fix needed in codecparser */ + if (sps->conformance_window_flag) { + GstVaapiRectangle crop_rect; + crop_rect.x = sps->crop_rect_x; + crop_rect.y = sps->crop_rect_y; + crop_rect.width = sps->crop_rect_width; + crop_rect.height = sps->crop_rect_height; + gst_vaapi_picture_set_crop_rect (&picture->base, &crop_rect); + } status = ensure_quant_matrix (decoder, picture); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { From 78fb4bcf8d4ed1e48002b72bcd3a59c6af78d5f9 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 26 May 2015 06:01:10 +0300 Subject: [PATCH 2010/3781] HEVC: decode: Replace clip3 implementation with glib CLAMP macro Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 0630617f6a..a5bf999731 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2297,16 +2297,6 @@ get_slice_data_byte_offset (GstH265SliceHdr * slice_hdr, guint nal_header_bytes) return nal_header_bytes + (slice_hdr->header_size + 7) / 8 - epb_count; } -static gint -clip3 (gint x, gint y, gint z) -{ - if (z < x) - return x; - if (z > y) - return y; - return z; -} - static gboolean fill_pred_weight_table (GstVaapiDecoderH265 * decoder, GstVaapiSlice * slice, GstH265SliceHdr * slice_hdr) @@ -2346,9 +2336,10 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, chroma_weight = (1 << chroma_log2_weight_denom) + w->delta_chroma_weight_l0[i][j]; /* 7-44 */ - slice_param->ChromaOffsetL0[i][j] = clip3 (-128, 127, + slice_param->ChromaOffsetL0[i][j] = CLAMP ( (w->delta_chroma_offset_l0[i][j] - - ((128 * chroma_weight) >> chroma_log2_weight_denom))); + ((128 * chroma_weight) >> chroma_log2_weight_denom)), -128, + 127); } } } @@ -2368,9 +2359,9 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, (1 << chroma_log2_weight_denom) + w->delta_chroma_weight_l1[i][j]; slice_param->ChromaOffsetL1[i][j] = - clip3 (-128, 127, - (w->delta_chroma_offset_l1[i][j] - - ((128 * chroma_weight) >> chroma_log2_weight_denom))); + CLAMP ((w->delta_chroma_offset_l1[i][j] - + ((128 * chroma_weight) >> chroma_log2_weight_denom)), -128, + 127); } } } From 943b96603ad3a1b3976dfa8d972d52b855a68a38 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 26 May 2015 10:03:20 +0300 Subject: [PATCH 2011/3781] codecparsers: Update to gst-vaapi-branch commit 20ee952 b7dded3: h264parse: don't consider unknown stream-format as avc 5110ad9: h264parse: fix up handling of input caps corner cases e51db3e: h264parse: Remove dead code 3d739d0: codecparser: h265: Fix the number of tile rows/columns parsing 8482957: h265parse: Fix profile, tier and level setting in caps 4649acb: h265parse: Fix the memory freeing of stored VPS nals f2beeb7: h265parse: Fix source caps to report cropped dimensions 6886a31: h264parse: Fix profile and level setting in caps 5286c1a: h264parse: Consider SEI NALU as "HEADER" packets eb97854: videoparsers: h264: bit-exact sync with upstream, minor changes here and there 53074fc: build: Upgrade GStreamer dependency to 1.0 Signed-off-by: Sreerenj Balachandran --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index eca844dc66..31231759f3 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit eca844dc660181d47ebcf77b6ffbbcc5e43a0368 +Subproject commit 31231759f3d6a2d83214abdc5cfec5e3820ee952 From c393b7e2ab23c96f9a67ed2966083cda5034328a Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 26 May 2015 10:21:59 +0300 Subject: [PATCH 2012/3781] patches/videoparsers: Rebase the patch on top of gst-vaapi-branch commit 20ee952 Signed-off-by: Sreerenj Balachandran --- ...-to-byte-stream-nalu-format-Annex-B.patch} | 27 ++++++++++--------- patches/videoparsers/series.frag | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) rename patches/videoparsers/{0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch => 0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch} (60%) diff --git a/patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch b/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch similarity index 60% rename from patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch rename to patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch index a1d2360955..4bd43eeac2 100644 --- a/patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch +++ b/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch @@ -1,6 +1,6 @@ -From 134793f35f1a219c79b32b2d23df73ceff0b5e32 Mon Sep 17 00:00:00 2001 +From 7650c8681ecf1304a59e7cc4c0bc9eba4f753ffa Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne -Date: Tue, 24 Jun 2014 17:27:12 +0200 +Date: Tue, 26 May 2015 09:33:57 +0300 Subject: [PATCH 3/3] h264parse: default to byte-stream/nalu format (Annex B). Always default to stream-format=byte-stream,alignment=nalu if avcC @@ -11,15 +11,16 @@ usual start code. https://bugzilla.gnome.org/show_bug.cgi?id=732167 Signed-off-by: Gwenole Beauchesne +Signed-off-by: Sreerenj Balachandran --- - gst/vaapi/gsth264parse.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) + gst/vaapi/gsth264parse.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index fceec68..f15b1b0 100644 +index 76f7686..b28d449 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c -@@ -393,7 +393,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, +@@ -388,7 +388,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, if (!format) format = GST_H264_PARSE_FORMAT_BYTE; if (!align) @@ -29,15 +30,15 @@ index fceec68..f15b1b0 100644 GST_DEBUG_OBJECT (h264parse, "selected format %s, alignment %s", gst_h264_parse_get_string (h264parse, TRUE, format), -@@ -2204,7 +2205,7 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) +@@ -2260,6 +2261,8 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) - if (format == GST_H264_PARSE_FORMAT_NONE) { - format = GST_H264_PARSE_FORMAT_BYTE; -- align = GST_H264_PARSE_ALIGN_AU; + /* bytestream caps sanity checks */ + if (format == GST_H264_PARSE_FORMAT_BYTE) { ++ if (align == GST_H264_PARSE_ALIGN_NONE) + align = GST_H264_PARSE_ALIGN_NAL; - } - } - + /* should have SPS/PSS in-band (and/or oob in streamheader field) */ + if (codec_data_value != NULL) + goto bytestream_caps_with_codec_data; -- 2.1.4 diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index 040b2bd0fa..227df479a5 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -3,6 +3,6 @@ videoparsers_patches_base = \ 0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch \ 0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch \ - 0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ + 0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ 0001-h265parse-include-gstvaapiparse.h.patch \ $(NULL) From f1a60ec6a2d9523c10713a43871df22ddc68d720 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Wed, 17 Dec 2014 00:41:10 +1100 Subject: [PATCH 2013/3781] mpeg2: Avoid crashes and warnings on re-opened decoder after a seek Reset state and add some checks for safe state to avoid a crash and a warning after the decoder is destroyed/recreated during a seek. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index c1866416f2..ad5d8cbf60 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -308,6 +308,8 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, NULL); gst_vaapi_parser_info_mpeg2_replace(&priv->slice_hdr, NULL); + priv->state = 0; + gst_vaapi_dpb_replace(&priv->dpb, NULL); } @@ -1104,6 +1106,9 @@ parse_slice(GstVaapiDecoderMpeg2 *decoder, GST_MPEG_VIDEO_STATE_GOT_PIC_HDR| GST_MPEG_VIDEO_STATE_GOT_PIC_EXT); + if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->slice_hdr)) { GST_ERROR("failed to allocate parser info for slice header"); return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; @@ -1538,7 +1543,8 @@ gst_vaapi_decoder_mpeg2_flush(GstVaapiDecoder *base_decoder) GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - gst_vaapi_dpb_flush(priv->dpb); + if (priv->dpb) + gst_vaapi_dpb_flush(priv->dpb); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From d6255be9398f5d6803c0997446a4b89c10beab26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 May 2015 10:49:56 +0200 Subject: [PATCH 2014/3781] mpeg2: avoid crash when seeking with debug logs Move down the debug message when the state of the decoder is verified so the slice header is not NULL. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index ad5d8cbf60..db11b96fd7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -1141,8 +1141,6 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; GstMapInfo map_info; - GST_DEBUG("slice %d (%u bytes)", slice_hdr->mb_row, unit->size); - if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -1151,6 +1149,8 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } + GST_DEBUG("slice %d (%u bytes)", slice_hdr->mb_row, unit->size); + slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, (map_info.data + unit->offset), unit->size); gst_buffer_unmap(buffer, &map_info); From efc07f6bb1873704458d3a5f6432dfc1871ec661 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 May 2015 13:28:32 +0200 Subject: [PATCH 2015/3781] mpeg2: fix PTS cache for GOP start. If the GOP temporal sequence number (TSN) is interpolated from a valid PTS, then we need to compensate that PTS corresponding to the start of GOP with the next picture to be decoded, which shall be an I-frame, based on its sequence number. https://bugzilla.gnome.org/show_bug.cgi?id=748676 --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index db11b96fd7..6dc9f0cf92 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -128,11 +128,16 @@ pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn) GstClockTime pts; if (!GST_CLOCK_TIME_IS_VALID(tsg->gop_pts)) - tsg->gop_pts = 0; + tsg->gop_pts = pts_get_duration(tsg, pic_tsn); pts = pic_pts; if (!GST_CLOCK_TIME_IS_VALID (pts)) pts = tsg->gop_pts + pts_get_duration(tsg, tsg->ovl_tsn * 1024 + pic_tsn); + else if (pts == tsg->gop_pts) { + /* The picture following the GOP header shall be an I-frame. + So we can compensate for the GOP start time from here */ + tsg->gop_pts -= pts_get_duration(tsg, pic_tsn); + } if (!GST_CLOCK_TIME_IS_VALID(tsg->max_pts) || tsg->max_pts < pts) tsg->max_pts = pts; From 3857d5fce1e38671cd1ff797deb250d95096793c Mon Sep 17 00:00:00 2001 From: Alban Browaeys Date: Wed, 27 May 2015 23:43:16 +0300 Subject: [PATCH 2016/3781] HEVC: decode: add missing va_dec_hevc header Signed-off-by: Alban Browaeys Signed-off-by: Sreerenj Balachandran https://bugzilla.gnome.org/show_bug.cgi?id=749953 --- gst-libs/gst/vaapi/gstvaapicompat.h | 4 ++++ gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 1 + 2 files changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 7f106eb782..0e4b24a646 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -42,4 +42,8 @@ # include #endif +#ifdef HAVE_VA_VA_DEC_HEVC_H +# include +#endif + #endif /* GST_VAAPI_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index a5bf999731..11dca0047c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -30,6 +30,7 @@ #include #include #include +#include "gstvaapicompat.h" #include "gstvaapidecoder_h265.h" #include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" From 22f4d8b768e8506034ea9b3dac9d2ec2e7f15905 Mon Sep 17 00:00:00 2001 From: Alban Browaeys Date: Wed, 27 May 2015 23:49:18 +0300 Subject: [PATCH 2017/3781] build: don't compile HEVC encoder if not supported Fix: (gst-plugin-scanner:16681): GStreamer-WARNING **: Failed to load plugin '/usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstvaapi.so': /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstvaapi.so: undefined symbol: gst_vaapi_encoder_h265_get_default_properties https://bugzilla.gnome.org/show_bug.cgi?id=749954 Signed-off-by: Alban Browaeys Signed-off-by: Sreerenj Balachandran --- gst/vaapi/Makefile.am | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 75cf214c4b..1f7135b7f6 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -81,14 +81,12 @@ libgstvaapi_enc_source_c = \ gstvaapiencode.c \ gstvaapiencode_h264.c \ gstvaapiencode_mpeg2.c \ - gstvaapiencode_h265.c \ $(NULL) libgstvaapi_enc_source_h = \ gstvaapiencode.h \ gstvaapiencode_h264.h \ gstvaapiencode_mpeg2.h \ - gstvaapiencode_h265.h \ $(NULL) if USE_ENCODERS @@ -110,6 +108,16 @@ libgstvaapi_source_c += $(libgstvaapi_vp8enc_source_c) libgstvaapi_source_h += $(libgstvaapi_vp8enc_source_h) endif + +libgstvaapi_h265enc_source_c = gstvaapiencode_h265.c +libgstvaapi_h265enc_source_h = gstvaapiencode_h265.h +if USE_H265_ENCODER +libgstvaapi_source_c += $(libgstvaapi_h265enc_source_c) +libgstvaapi_source_h += $(libgstvaapi_h265enc_source_h) +endif + + + libgstvaapi_egl_source_c = libgstvaapi_egl_source_h = @@ -247,6 +255,8 @@ EXTRA_DIST = \ $(libgstvaapi_jpegenc_source_h) \ $(libgstvaapi_vp8enc_source_c) \ $(libgstvaapi_vp8enc_source_h) \ + $(libgstvaapi_h265enc_source_c) \ + $(libgstvaapi_h265enc_source_h) \ $(libgstvaapi_egl_source_c) \ $(libgstvaapi_egl_source_h) \ $(libgstvaapi_1_2p_source_c) \ From a89a8cf1e3a0307c481510b4a43cb8f6ec96b740 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Thu, 28 Feb 2013 15:26:36 +0800 Subject: [PATCH 2018/3781] decoder: add utility function to clone picture objects. https://bugzilla.gnome.org/show_bug.cgi?id=703921 Signed-off-by: Wind Yuan [added cosmetic changes, fixed propagation of "one-field" flag to children, fixed per-codec clone modes (h264)] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 16 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 4 ++++ 4 files changed, 22 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 207d99a6c7..6391c9da97 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -238,6 +238,7 @@ gst_vaapi_picture_h264_create( if (!gst_vaapi_picture_create(GST_VAAPI_PICTURE(picture), args)) return FALSE; + picture->structure = picture->base.structure; picture->field_poc[0] = G_MAXINT32; picture->field_poc[1] = G_MAXINT32; picture->output_needed = FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 11dca0047c..25d0ebe310 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -244,6 +244,7 @@ gst_vaapi_picture_h265_create (GstVaapiPictureH265 * picture, if (!gst_vaapi_picture_create (GST_VAAPI_PICTURE (picture), args)) return FALSE; + picture->structure = picture->base.structure; picture->poc = G_MAXINT32; picture->output_needed = FALSE; return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index c8cbfbe31a..eb773b039a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -114,6 +114,7 @@ gst_vaapi_picture_create (GstVaapiPicture * picture, 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)); picture->structure = parent_picture->structure; @@ -196,6 +197,21 @@ gst_vaapi_picture_new_field (GstVaapiPicture * picture) 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) { diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 9edb449634..c9b0dfd48c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -178,6 +178,10 @@ 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); From 6229ad4f7fa143e89e94e45d38e16b2577ba4af6 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 12 May 2015 15:36:10 +0200 Subject: [PATCH 2019/3781] decoder: h264: fix processing of EOSEQ NAL. Fix decoding of end_of_seq() NAL unit so that to not submit the current picture for decoding again. This is pretty vintage code that dates back before the existing of the whole decoder units machinery. One issue that could be arising if that code was kept is that we could have submitted a picture, and subsequently a GstVideoCodec frame, twice. Once without the decode_only flag set, and once with that flag set. The end result is that the GstVideoDecoder would release the codec frame twice, thus releasing stale data. In short, the piece of code that is removed by this patch is for once completely obsolete for a while, and secondly error-prone in corner cases. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 6391c9da97..8021553b89 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1743,14 +1743,9 @@ static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiDecoderStatus status; GST_DEBUG("decode sequence-end"); - status = decode_current_picture(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - dpb_flush(decoder, NULL); /* Reset defaults, should there be a new sequence available next */ From b4e920843bd9cd6f07eb6ace3017d72eb98e09a0 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 5 May 2015 11:56:11 +0200 Subject: [PATCH 2020/3781] decoder: h264: skip all pictures prior the first I-frame. Don't try to decode pictures until the first I-frame is received within the currently active sequence. There is no point is decoding and then displaying frames with artifacts. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 29 +++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 8021553b89..24bae5fb3b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -450,6 +450,8 @@ typedef enum { GST_H264_VIDEO_STATE_GOT_SPS = 1 << 0, GST_H264_VIDEO_STATE_GOT_PPS = 1 << 1, GST_H264_VIDEO_STATE_GOT_SLICE = 1 << 2, + GST_H264_VIDEO_STATE_GOT_I_FRAME = 1 << 3, // persistent across SPS + GST_H264_VIDEO_STATE_GOT_P_SLICE = 1 << 4, // predictive (all non-intra) GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS = ( GST_H264_VIDEO_STATE_GOT_SPS | @@ -1208,6 +1210,12 @@ ensure_sps(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiParserInfoH264 * const pi = priv->sps[sps->id]; + /* Propagate "got I-frame" state to the next SPS unit if the + current sequence was not ended */ + if (pi && priv->active_sps) + pi->state |= (priv->active_sps->state & + GST_H264_VIDEO_STATE_GOT_I_FRAME); + gst_vaapi_parser_info_h264_replace(&priv->active_sps, pi); return pi ? &pi->data.sps : NULL; } @@ -1489,10 +1497,20 @@ static GstVaapiDecoderStatus decode_current_picture(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiParserInfoH264 * const sps_pi = decoder->priv.active_sps; GstVaapiPictureH264 * const picture = priv->current_picture; - if (!is_valid_state(priv->decoder_state, GST_H264_VIDEO_STATE_VALID_PICTURE)) + if (!is_valid_state(priv->decoder_state, + GST_H264_VIDEO_STATE_VALID_PICTURE)) goto drop_frame; + + priv->decoder_state |= sps_pi->state; + if (!(priv->decoder_state & GST_H264_VIDEO_STATE_GOT_I_FRAME)) { + if (priv->decoder_state & GST_H264_VIDEO_STATE_GOT_P_SLICE) + goto drop_frame; + sps_pi->state |= GST_H264_VIDEO_STATE_GOT_I_FRAME; + } + priv->decoder_state = 0; priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME; @@ -1669,6 +1687,8 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) pi->voc = get_view_order_index(sps, pi->view_id); priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SLICE; + if (!GST_H264_IS_I_SLICE(slice_hdr)) + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_P_SLICE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1743,9 +1763,15 @@ static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderH264 *decoder) { GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiParserInfoH264 * const sps_pi = decoder->priv.active_sps; GST_DEBUG("decode sequence-end"); + /* Sequence ended, don't try to propagate "got I-frame" state + beyond this point */ + if (sps_pi) + sps_pi->state &= ~GST_H264_VIDEO_STATE_GOT_I_FRAME; + dpb_flush(decoder, NULL); /* Reset defaults, should there be a new sequence available next */ @@ -3782,7 +3808,6 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) gst_vaapi_picture_add_slice(GST_VAAPI_PICTURE_CAST(picture), slice); picture->last_slice_hdr = slice_hdr; - priv->decoder_state |= GST_H264_VIDEO_STATE_GOT_SLICE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 4776138d4aa082baa58ff6c46c6c7456c856df60 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 May 2015 17:06:11 +0200 Subject: [PATCH 2021/3781] decoder: h264: improve tracking of "top-field-first" flag. Try to maintain a "top-field-first" (TFF) flag, even if the H.264 standard does not mandate it. This will be useful for tracking missing fields, and also for more correct _split_fields() implementation for frames in the DPB. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 27 +++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 24bae5fb3b..b056339475 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -363,14 +363,14 @@ gst_vaapi_frame_store_add(GstVaapiFrameStore *fs, GstVaapiPictureH264 *picture) } static gboolean -gst_vaapi_frame_store_split_fields(GstVaapiFrameStore *fs) +gst_vaapi_frame_store_split_fields(GstVaapiFrameStore *fs, gboolean tff) { GstVaapiPictureH264 * const first_field = fs->buffers[0]; GstVaapiPictureH264 *second_field; g_return_val_if_fail(fs->num_buffers == 1, FALSE); - first_field->base.structure = GST_VAAPI_PICTURE_IS_TFF(first_field) ? + first_field->base.structure = tff ? GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; GST_VAAPI_PICTURE_FLAG_SET(first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED); @@ -510,6 +510,7 @@ struct _GstVaapiDecoderH264Private { guint is_avcC : 1; guint has_context : 1; guint progressive_sequence : 1; + guint top_field_first : 1; }; /** @@ -989,7 +990,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) gst_vaapi_frame_store_unref(fs); if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) { - if (!gst_vaapi_frame_store_split_fields(fs)) + if (!gst_vaapi_frame_store_split_fields(fs, priv->top_field_first)) return FALSE; } @@ -1180,6 +1181,7 @@ gst_vaapi_decoder_h264_create(GstVaapiDecoder *base_decoder) priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; priv->progressive_sequence = TRUE; + priv->top_field_first = FALSE; return TRUE; } @@ -1392,8 +1394,13 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) priv->mb_height = mb_height; } - priv->progressive_sequence = sps->frame_mbs_only_flag; - gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence); + if (priv->progressive_sequence != sps->frame_mbs_only_flag) { + GST_DEBUG("interlacing-mode changed"); + priv->progressive_sequence = sps->frame_mbs_only_flag; + gst_vaapi_decoder_set_interlaced(base_decoder, + !priv->progressive_sequence); + priv->top_field_first = FALSE; + } gst_vaapi_decoder_set_pixel_aspect_ratio( base_decoder, @@ -2947,7 +2954,7 @@ init_picture( case GST_H264_SEI_PIC_STRUCT_TOP_FIELD: base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; if (GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture)) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF); + priv->top_field_first = TRUE; break; case GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD: base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; @@ -2957,13 +2964,19 @@ init_picture( // fall-through case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM: if (GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture)) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF); + priv->top_field_first = TRUE; break; case GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_RFF); break; + case GST_H264_SEI_PIC_STRUCT_FRAME: + if (!priv->progressive_sequence && priv->dpb_count == 0) + priv->top_field_first = TRUE; + break; } picture->structure = base_picture->structure; + if (priv->top_field_first) + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF); /* Initialize reference flags */ if (pi->nalu.ref_idc) { From efaadfc7c086e97442df28383430957c7f01c337 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 7 May 2015 14:00:58 +0200 Subject: [PATCH 2022/3781] decoder: h264: add support for missing second field. Interlaced H.264 video frames always have two fields to decode and display. However, in some cases, e.g. packet loss, one of the field can be missing. This perturbs the reference picture marking process, whereby the number of references available in DPB no longer matches the expected value. This patch adds initial support for missing field within a decoded frame. The current strategy taken is to find out the nearest field, by POC value, and with the same parity. https://bugzilla.gnome.org/show_bug.cgi?id=745048 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 169 +++++++++++++++++++--- 1 file changed, 151 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index b056339475..a7afd37764 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -160,6 +160,9 @@ gst_vaapi_parser_info_h264_new(void) * access unit (AU) * @GST_VAAPI_PICTURE_FLAG_AU_END: flag that marks the end of an * access unit (AU) + * @GST_VAAPI_PICTURE_FLAG_GHOST: flag that specifies a "non-existing" + * picture, without any viable GstVideoCodecFrame associated to it. + * i.e. a dummy picture with some valid contents * @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies * "used for short-term reference" * @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies @@ -174,6 +177,7 @@ enum { GST_VAAPI_PICTURE_FLAG_ANCHOR = (GST_VAAPI_PICTURE_FLAG_LAST << 3), GST_VAAPI_PICTURE_FLAG_AU_START = (GST_VAAPI_PICTURE_FLAG_LAST << 4), GST_VAAPI_PICTURE_FLAG_AU_END = (GST_VAAPI_PICTURE_FLAG_LAST << 5), + GST_VAAPI_PICTURE_FLAG_GHOST = (GST_VAAPI_PICTURE_FLAG_LAST << 6), GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = ( GST_VAAPI_PICTURE_FLAG_REFERENCE), @@ -705,24 +709,25 @@ dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index) static gboolean dpb_output(GstVaapiDecoderH264 *decoder, GstVaapiFrameStore *fs) { - GstVaapiPictureH264 *picture; + GstVaapiPictureH264 *picture = NULL; + guint i; g_return_val_if_fail(fs != NULL, FALSE); if (!gst_vaapi_frame_store_is_complete(fs)) return TRUE; - picture = fs->buffers[0]; - g_return_val_if_fail(picture != NULL, FALSE); - picture->output_needed = FALSE; - - if (fs->num_buffers > 1) { - picture = fs->buffers[1]; - g_return_val_if_fail(picture != NULL, FALSE); - picture->output_needed = FALSE; + for (i = 0; i < fs->num_buffers; i++) { + GstVaapiPictureH264 * const pic = fs->buffers[i]; + g_return_val_if_fail(pic != NULL, FALSE); + pic->output_needed = FALSE; + if (!GST_VAAPI_PICTURE_FLAG_IS_SET(pic, GST_VAAPI_PICTURE_FLAG_GHOST)) + picture = pic; } fs->output_needed = 0; + if (!picture) + return TRUE; return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture)); } @@ -753,6 +758,41 @@ dpb_find_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return -1; } +/* Finds the picture with the nearest previous POC and same structure */ +static gint +dpb_find_nearest_prev_poc(GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *picture, guint picture_structure, + GstVaapiPictureH264 **found_picture_ptr) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiPictureH264 *found_picture = NULL; + guint i, j, found_index; + + g_return_val_if_fail(picture != NULL, -1); + + if (!picture_structure) + picture_structure = picture->base.structure; + + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + if (picture->base.view_id != fs->view_id) + continue; + for (j = 0; j < fs->num_buffers; j++) { + GstVaapiPictureH264 * const pic = fs->buffers[j]; + if (pic->base.structure != picture_structure) + continue; + if (pic->base.poc >= picture->base.poc) + continue; + if (!found_picture || found_picture->base.poc < pic->base.poc) + found_picture = pic, found_index = i; + } + } + + if (found_picture_ptr) + *found_picture_ptr = found_picture; + return found_picture ? found_index : -1; +} + /* Finds the picture with the lowest POC that needs to be output */ static gint dpb_find_lowest_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, @@ -2899,6 +2939,63 @@ init_picture_refs( } } +static GstVaapiPictureH264 * +fill_picture_other_field_gap(GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *f0) +{ + GstVaapiPictureH264 *prev_picture, *f1; + gint prev_picture_index; + guint picture_structure; + + picture_structure = f0->base.structure; + 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; + default: + g_assert(0 && "unexpected picture structure"); + return NULL; + } + GST_VAAPI_PICTURE_FLAG_SET(f0, GST_VAAPI_PICTURE_FLAG_ONEFIELD); + + prev_picture_index = dpb_find_nearest_prev_poc(decoder, f0, + picture_structure, &prev_picture); + if (prev_picture_index < 0) + return NULL; + + f1 = gst_vaapi_picture_h264_new_field(f0); + if (!f1) + goto error_allocate_field; + + gst_vaapi_surface_proxy_replace(&f1->base.proxy, prev_picture->base.proxy); + f1->base.surface = GST_VAAPI_SURFACE_PROXY_SURFACE(f1->base.proxy); + f1->base.surface_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID(f1->base.proxy); + f1->base.poc++; + f1->structure = f1->base.structure; + + /* XXX: clone other H.264 picture specific flags */ + GST_VAAPI_PICTURE_FLAG_SET(f1, + (GST_VAAPI_PICTURE_FLAG_SKIPPED | + GST_VAAPI_PICTURE_FLAG_GHOST)); + + if (!dpb_add(decoder, f1)) + goto error_append_field; + gst_vaapi_picture_unref(f1); + return f1; + + /* ERRORS */ +error_allocate_field: + GST_ERROR("failed to allocate missing field for previous frame store"); + return NULL; +error_append_field: + GST_ERROR("failed to add missing field into previous frame store"); + gst_vaapi_picture_unref(f1); + return NULL; +} + static gboolean init_picture( GstVaapiDecoderH264 *decoder, @@ -3519,24 +3616,60 @@ is_new_access_unit(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) return pi->voc < prev_pi->voc; } +/* Determines whether the supplied picture has the same field parity + than a picture specified through the other slice header */ +static inline gboolean +same_field_parity(GstVaapiPictureH264 *field, GstH264SliceHdr *slice_hdr) +{ + g_return_val_if_fail(GST_VAAPI_PICTURE_IS_INTERLACED(field), FALSE); + + return ((field->base.structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) ^ + slice_hdr->bottom_field_flag) == 0; +} + /* Finds the first field picture corresponding to the supplied picture */ static GstVaapiPictureH264 * -find_first_field(GstVaapiDecoderH264 *decoder, GstVaapiParserInfoH264 *pi) +find_first_field(GstVaapiDecoderH264 *decoder, GstVaapiParserInfoH264 *pi, + gboolean fill_gaps) { GstVaapiDecoderH264Private * const priv = &decoder->priv; GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; GstVaapiFrameStore *fs; - - if (!slice_hdr->field_pic_flag) - return NULL; + GstVaapiPictureH264 *f0, *f1; fs = priv->prev_frames[pi->voc]; - if (!fs || gst_vaapi_frame_store_has_frame(fs)) + if (!fs) return NULL; - if (fs->buffers[0]->frame_num == slice_hdr->frame_num) - return fs->buffers[0]; - return NULL; + f0 = fs->buffers[0]; + if (!slice_hdr->field_pic_flag) { + if (fill_gaps && !gst_vaapi_frame_store_has_frame(fs)) + fill_picture_other_field_gap(decoder, f0); + return NULL; + } + + /* At this point, the current frame is known to be interlaced */ + if (gst_vaapi_frame_store_has_frame(fs)) { + f1 = NULL; + return f1; + } + + /* At this point, the previous frame is interlaced and contains a + single field */ + if (f0->frame_num == slice_hdr->frame_num) { + f1 = f0; + if (fill_gaps && same_field_parity(f0, slice_hdr)) { + fill_picture_other_field_gap(decoder, f0); + f1 = NULL; + } + return f1; + } + + f1 = NULL; + if (fill_gaps) { + fill_picture_other_field_gap(decoder, f0); + } + return f1; } static GstVaapiDecoderStatus @@ -3566,7 +3699,7 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) priv->decoder_state = 0; - first_field = find_first_field(decoder, pi); + first_field = find_first_field(decoder, pi, TRUE); if (first_field) { /* Re-use current picture where the first field was decoded */ picture = gst_vaapi_picture_h264_new_field(first_field); From 8dd93e9c8ab301d17c84fb9a92e30990aff853ad Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 May 2015 11:42:52 +0200 Subject: [PATCH 2023/3781] decoder: h264: add support for missing first field. Try to identify missing first fields too, thus disregarding any intermediate gaps in frames. We also assume that we keep the same field sequence, i.e. if previous frames were in top-field-first (TFF) order, then so are subsequent frames. Note that insertion of dummy first fields need to operate in two steps: (i) create the original first field that the current field will inherit from, and (ii) submit that field into the DPB prior to initializing the current (other) field POC values but after any reference flag was set. i.e. copy reference flags from the child (other field) to the parent (first field). https://bugzilla.gnome.org/show_bug.cgi?id=745048 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 93 +++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index a7afd37764..a8dae645fc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -286,6 +286,14 @@ gst_vaapi_picture_h264_new_field(GstVaapiPictureH264 *picture) return (GstVaapiPictureH264 *)gst_vaapi_picture_new_field(&picture->base); } +static inline GstVaapiPictureH264 * +gst_vaapi_picture_h264_new_clone(GstVaapiPictureH264 *picture) +{ + g_return_val_if_fail(picture, NULL); + + return (GstVaapiPictureH264 *)gst_vaapi_picture_new_clone(&picture->base); +} + /* ------------------------------------------------------------------------- */ /* --- Frame Buffers (DPB) --- */ /* ------------------------------------------------------------------------- */ @@ -471,6 +479,7 @@ struct _GstVaapiDecoderH264Private { guint decoder_state; GstVaapiStreamAlignH264 stream_alignment; GstVaapiPictureH264 *current_picture; + GstVaapiPictureH264 *missing_picture; GstVaapiParserInfoH264 *sps[GST_H264_MAX_SPS_COUNT]; GstVaapiParserInfoH264 *active_sps; GstVaapiParserInfoH264 *pps[GST_H264_MAX_PPS_COUNT]; @@ -541,6 +550,9 @@ struct _GstVaapiDecoderH264Class { static gboolean exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture); +static gboolean +exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder); + static gboolean is_inter_view_reference_for_next_pictures(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture); @@ -1153,6 +1165,7 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) GstVaapiDecoderH264Private * const priv = &decoder->priv; gst_vaapi_picture_replace(&priv->current_picture, NULL); + gst_vaapi_picture_replace(&priv->missing_picture, NULL); gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL); gst_vaapi_parser_info_h264_replace(&priv->prev_pi, NULL); @@ -2939,6 +2952,80 @@ init_picture_refs( } } +static GstVaapiPictureH264 * +fill_picture_first_field_gap(GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *f0) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiPictureH264 *f1; + + f1 = gst_vaapi_picture_h264_new_clone(f0); + if (!f1) + goto error_allocate_field; + + gst_vaapi_picture_replace(&priv->missing_picture, f1); + gst_vaapi_picture_unref(f1); + + GST_VAAPI_PICTURE_FLAG_SET(f1, + (GST_VAAPI_PICTURE_FLAG_ONEFIELD | + GST_VAAPI_PICTURE_FLAG_SKIPPED | + GST_VAAPI_PICTURE_FLAG_GHOST)); + + gst_vaapi_picture_h264_set_reference(f1, 0, FALSE); + return f1; + + /* ERRORS */ +error_allocate_field: + GST_ERROR("failed to allocate missing field for current frame store"); + return NULL; +} + +static gboolean +fill_picture_first_field_gap_done(GstVaapiDecoderH264 *decoder, + GstH264SliceHdr *slice_hdr) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiPictureH264 * const lost_field = priv->missing_picture; + GstH264SliceHdr lost_slice_hdr; + gboolean success = FALSE; + + g_return_val_if_fail(priv->current_picture != NULL, FALSE); + + if (!lost_field) + return TRUE; + + lost_field->frame_num = slice_hdr->frame_num; + lost_field->frame_num_wrap = slice_hdr->frame_num; + + gst_vaapi_picture_h264_set_reference(lost_field, + (GST_VAAPI_PICTURE_FLAGS(priv->current_picture) & + GST_VAAPI_PICTURE_FLAGS_REFERENCE), FALSE); + + lost_slice_hdr = *slice_hdr; + lost_slice_hdr.bottom_field_flag = !lost_slice_hdr.bottom_field_flag; + + init_picture_poc(decoder, lost_field, &lost_slice_hdr); + init_picture_ref_lists(decoder, lost_field); + init_picture_refs_pic_num(decoder, lost_field, &lost_slice_hdr); + if (!exec_ref_pic_marking_sliding_window(decoder)) + goto error_exec_ref_pic_marking; + if (!dpb_add(decoder, lost_field)) + goto error_dpb_add; + success = TRUE; + +cleanup: + gst_vaapi_picture_replace(&priv->missing_picture, NULL); + return success; + + /* ERRORS */ +error_exec_ref_pic_marking: + GST_ERROR("failed to execute reference picture marking process"); + goto cleanup; +error_dpb_add: + GST_ERROR("failed to store lost picture into the DPB"); + goto cleanup; +} + static GstVaapiPictureH264 * fill_picture_other_field_gap(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *f0) @@ -3089,6 +3176,7 @@ init_picture( GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE); } + fill_picture_first_field_gap_done(decoder, slice_hdr); init_picture_poc(decoder, picture, slice_hdr); return TRUE; } @@ -3651,6 +3739,8 @@ find_first_field(GstVaapiDecoderH264 *decoder, GstVaapiParserInfoH264 *pi, /* At this point, the current frame is known to be interlaced */ if (gst_vaapi_frame_store_has_frame(fs)) { f1 = NULL; + if (fill_gaps && !same_field_parity(f0, slice_hdr)) + f1 = fill_picture_first_field_gap(decoder, f0); return f1; } @@ -3668,6 +3758,8 @@ find_first_field(GstVaapiDecoderH264 *decoder, GstVaapiParserInfoH264 *pi, f1 = NULL; if (fill_gaps) { fill_picture_other_field_gap(decoder, f0); + if (!same_field_parity(f0, slice_hdr)) + f1 = fill_picture_first_field_gap(decoder, f0); } return f1; } @@ -3698,6 +3790,7 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) return status; priv->decoder_state = 0; + gst_vaapi_picture_replace(&priv->missing_picture, NULL); first_field = find_first_field(decoder, pi, TRUE); if (first_field) { From 5abd2b90b6b67403cd12e88496abf28e6fb39dc9 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 12 Mar 2015 22:57:22 +0100 Subject: [PATCH 2024/3781] decoder: h264: add initial support for loss of pictures. Implement decoding process for gaps in frame_num (8.5.2). This also somewhat supports unintentional loss of pictures. https://bugzilla.gnome.org/show_bug.cgi?id=745048 https://bugzilla.gnome.org/show_bug.cgi?id=703921 Original-patch-by: Wind Yuan [fixed derivation of POC, ensured clone is valid for reference, actually fixed detection of gaps in FrameNum by PrevRefFrameNum] Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 140 +++++++++++++++++++++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index a8dae645fc..20d96ceec0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -517,7 +517,9 @@ struct _GstVaapiDecoderH264Private { gint32 frame_num_offset; // FrameNumOffset gint32 frame_num; // frame_num (from slice_header()) gint32 prev_frame_num; // prevFrameNum + gint32 prev_ref_frame_num; // prevRefFrameNum gboolean prev_pic_has_mmco5; // prevMmco5Pic + gboolean prev_pic_reference; // previous picture is a reference guint prev_pic_structure; // previous picture structure guint is_opened : 1; guint is_avcC : 1; @@ -805,6 +807,29 @@ dpb_find_nearest_prev_poc(GstVaapiDecoderH264 *decoder, return found_picture ? found_index : -1; } +/* Finds the picture with the associated FrameNum */ +static gint +dpb_find_frame_num(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, + gint frame_num, GstVaapiPictureH264 **found_picture_ptr) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + guint i, j; + + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore * const fs = priv->dpb[i]; + if (picture && picture->base.view_id != fs->view_id) + continue; + for (j = 0; j < fs->num_buffers; j++) { + if (fs->buffers[j]->frame_num != frame_num) + continue; + if (found_picture_ptr) + *found_picture_ptr = fs->buffers[j]; + return i; + } + } + return -1; +} + /* Finds the picture with the lowest POC that needs to be output */ static gint dpb_find_lowest_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, @@ -3083,6 +3108,114 @@ error_append_field: return NULL; } +static gboolean +fill_picture_gaps(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, + GstH264SliceHdr *slice_hdr) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstH264SPS * const sps = get_sps(decoder); + const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); + GstVaapiPicture *base_picture; + GstVaapiPictureH264 *lost_picture, *prev_picture; + GstH264SliceHdr lost_slice_hdr; + gboolean success = FALSE; + + if (priv->prev_ref_frame_num == priv->frame_num) + return TRUE; + if ((priv->prev_ref_frame_num + 1) % MaxFrameNum == priv->frame_num) + return TRUE; + if (priv->dpb_count == 0) + return TRUE; + + prev_picture = NULL; + dpb_find_frame_num(decoder, picture, priv->prev_ref_frame_num, + &prev_picture); + if (prev_picture) + gst_vaapi_picture_ref(prev_picture); + gst_vaapi_picture_ref(picture); + + lost_slice_hdr = *slice_hdr; + lost_slice_hdr.field_pic_flag = 0; + if (sps->pic_order_cnt_type == 1) { + lost_slice_hdr.delta_pic_order_cnt[0] = 0; + lost_slice_hdr.delta_pic_order_cnt[1] = 0; + } + lost_slice_hdr.dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag = 0; + + /* XXX: this process is incorrect for MVC */ + /* XXX: optimize to reduce the number of dummy pictures created */ + priv->frame_num = priv->prev_ref_frame_num; + for (;;) { + priv->prev_ref_frame_num = priv->frame_num; + priv->frame_num = (priv->prev_ref_frame_num + 1) % MaxFrameNum; + if (priv->frame_num == slice_hdr->frame_num) + break; + + /* Create new picture */ + if (prev_picture) + lost_picture = gst_vaapi_picture_h264_new_clone(prev_picture); + else + lost_picture = gst_vaapi_picture_h264_new(decoder); + if (!lost_picture) + goto error_allocate_picture; + + base_picture = &lost_picture->base; + base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE; + base_picture->pts = GST_CLOCK_TIME_NONE; + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + lost_picture->frame_num = priv->frame_num; + lost_picture->frame_num_wrap = priv->frame_num; + lost_picture->structure = base_picture->structure; + + GST_VAAPI_PICTURE_FLAG_SET(lost_picture, + (GST_VAAPI_PICTURE_FLAG_SKIPPED | + GST_VAAPI_PICTURE_FLAG_GHOST | + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE)); + + if (sps->pic_order_cnt_type != 0) + init_picture_poc(decoder, lost_picture, &lost_slice_hdr); + else { + base_picture->poc = prev_picture->base.poc + 2; + if (prev_picture->field_poc[0] != G_MAXINT32) + lost_picture->field_poc[0] = prev_picture->field_poc[0] + 2; + if (prev_picture->field_poc[1] != G_MAXINT32) + lost_picture->field_poc[1] = prev_picture->field_poc[1] + 2; + } + + gst_vaapi_picture_replace(&prev_picture, lost_picture); + gst_vaapi_picture_replace(&priv->current_picture, lost_picture); + gst_vaapi_picture_unref(lost_picture); + + init_picture_ref_lists(decoder, lost_picture); + init_picture_refs_pic_num(decoder, lost_picture, &lost_slice_hdr); + if (!exec_ref_pic_marking_sliding_window(decoder)) + goto error_exec_ref_pic_marking; + if (!dpb_add(decoder, lost_picture)) + goto error_dpb_add; + gst_vaapi_picture_replace(&priv->current_picture, NULL); + } + success = TRUE; + +cleanup: + priv->frame_num = slice_hdr->frame_num; + priv->prev_ref_frame_num = (priv->frame_num + MaxFrameNum - 1) % MaxFrameNum; + gst_vaapi_picture_replace(&prev_picture, NULL); + gst_vaapi_picture_replace(&priv->current_picture, picture); + gst_vaapi_picture_unref(picture); + return success; + + /* ERRORS */ +error_allocate_picture: + GST_ERROR("failed to allocate lost picture"); + goto cleanup; +error_exec_ref_pic_marking: + GST_ERROR("failed to execute reference picture marking process"); + goto cleanup; +error_dpb_add: + GST_ERROR("failed to store lost picture into the DPB"); + goto cleanup; +} + static gboolean init_picture( GstVaapiDecoderH264 *decoder, @@ -3092,6 +3225,8 @@ init_picture( GstVaapiPicture * const base_picture = &picture->base; GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; + if (priv->prev_pic_reference) + priv->prev_ref_frame_num = priv->frame_num; priv->prev_frame_num = priv->frame_num; priv->frame_num = slice_hdr->frame_num; picture->frame_num = priv->frame_num; @@ -3124,6 +3259,8 @@ init_picture( GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR); dpb_flush(decoder, picture); } + else if (!fill_picture_gaps(decoder, picture, slice_hdr)) + return FALSE; /* Initialize picture structure */ if (slice_hdr->field_pic_flag) { @@ -3457,13 +3594,14 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) { GstVaapiDecoderH264Private * const priv = &decoder->priv; + priv->prev_pic_reference = GST_VAAPI_PICTURE_IS_REFERENCE(picture); priv->prev_pic_has_mmco5 = FALSE; priv->prev_pic_structure = picture->structure; if (GST_VAAPI_PICTURE_IS_INTER_VIEW(picture)) g_ptr_array_add(priv->inter_views, gst_vaapi_picture_ref(picture)); - if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) + if (!priv->prev_pic_reference) return TRUE; if (!GST_VAAPI_PICTURE_IS_IDR(picture)) { From 55775c6203a7dc4c1ed9065176ebb83b7eeab783 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 28 May 2015 05:43:49 +0300 Subject: [PATCH 2025/3781] encoder: hevc: fix bug in multi slice encoding. This is a work-around for satisfying the VA-Intel driver. The driver only support slices begin from CTU row start address. Multi-Slice encoding also requires a fix in va-intel-driver: http://lists.freedesktop.org/archives/libva/2015-May/003351.html https://bugzilla.gnome.org/show_bug.cgi?id=749854 Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 27 ++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 0be492b8eb..7ba45a020c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1588,6 +1588,7 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, GstVaapiEncSlice *slice; guint slice_of_ctus, slice_mod_ctus, cur_slice_ctus; guint ctu_size; + guint ctu_width_round_factor; guint last_ctu_index; guint i_slice, i_ref; @@ -1599,12 +1600,23 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, slice_of_ctus = ctu_size / encoder->num_slices; slice_mod_ctus = ctu_size % encoder->num_slices; last_ctu_index = 0; - for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) { + + for (i_slice = 0; + i_slice < encoder->num_slices && (last_ctu_index < ctu_size); ++i_slice) { cur_slice_ctus = slice_of_ctus; if (slice_mod_ctus) { ++cur_slice_ctus; --slice_mod_ctus; } + + /* Work-around for satisfying the VA-Intel driver. + * The driver only support multi slice begin from row start address */ + ctu_width_round_factor = + encoder->ctu_width - (cur_slice_ctus % encoder->ctu_width); + cur_slice_ctus += ctu_width_round_factor; + if ((last_ctu_index + cur_slice_ctus) > ctu_size) + cur_slice_ctus = ctu_size - last_ctu_index; + slice = GST_VAAPI_ENC_SLICE_NEW (HEVC, encoder); g_assert (slice && slice->param_id != VA_INVALID_ID); slice_param = slice->param; @@ -1664,14 +1676,16 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp; slice_param->slice_fields.value = 0; - if (i_slice == encoder->num_slices - 1) - slice_param->slice_fields.bits.last_slice_of_pic_flag = 1; slice_param->slice_fields. bits.slice_loop_filter_across_slices_enabled_flag = TRUE; + /* set calculation for next slice */ last_ctu_index += cur_slice_ctus; + if ((i_slice == encoder->num_slices - 1) || (last_ctu_index == ctu_size)) + slice_param->slice_fields.bits.last_slice_of_pic_flag = 1; + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderHEVC_Slice) && !add_packed_slice_header (encoder, picture, slice)) @@ -1680,7 +1694,12 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, gst_vaapi_enc_picture_add_slice (picture, slice); gst_vaapi_codec_object_replace (&slice, NULL); } + if (i_slice < encoder->num_slices) + GST_WARNING + ("Using less number of slices than requested, Number of slices per pictures is %d", + i_slice); g_assert (last_ctu_index == ctu_size); + return TRUE; error_create_packed_slice_hdr: @@ -2387,8 +2406,6 @@ gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, break; case GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES: encoder->num_slices = g_value_get_uint (value); - if (encoder->num_slices > 1) - GST_ERROR ("Mulit-slice encoding is not yet functional!"); break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; From 4d8eaf1918934db66c43259447146c1ba21e89c6 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 28 May 2015 10:43:20 +0300 Subject: [PATCH 2026/3781] encoder: vp8: Fix the size over-flow for encoded buffer. The approximation of 4 times compression ratio will not work in all cases. Especially when enabling I frames. Provide large enough size for coded-buffer creation. --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index dadccfd8c5..65b449ed84 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -161,10 +161,9 @@ set_context_info (GstVaapiEncoder * base_encoder) base_encoder->num_ref_frames = 3; - /* Only YUV 4:2:0 formats are supported for now. - Take an approximation of 4 times compress ratio */ + /* 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 / 4; + GST_ROUND_UP_16 (vip->height) * 3 / 2; base_encoder->codedbuf_size += MAX_FRAME_TAG_SIZE + MAX_UPDATE_SEGMENTATION_SIZE + From 619058b5b705d927a36061aa5b952d7ab856d7e6 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 28 May 2015 10:52:48 +0300 Subject: [PATCH 2027/3781] encoder: hevc: Fix the size over-flow for encoded buffer. The approximation of 6 times compression ratio migh not work in all cases. Especially when enabling I frames. Provide large enough size for coded-buffer creation. --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 7ba45a020c..a9c09a7604 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2274,9 +2274,9 @@ set_context_info (GstVaapiEncoder * base_encoder) base_encoder->num_ref_frames = ((encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT); - /* Take an approximation of 6 times compression ratio */ - base_encoder->codedbuf_size = ((GST_ROUND_UP_32 (vip->width) * - GST_ROUND_UP_32 (vip->height) * 12 / 6)) / 8; + /* Only YUV 4:2:0 formats are supported for now. */ + base_encoder->codedbuf_size += GST_ROUND_UP_32 (vip->width) * + GST_ROUND_UP_32 (vip->height) * 3 / 2; return GST_VAAPI_ENCODER_STATUS_SUCCESS; } From dff6b7cb31071aeef913b2ff2739d53f0161e968 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 21 May 2015 23:16:14 +1000 Subject: [PATCH 2028/3781] configure: Compiling against libgstgl requires libgstvideo Fix detection of the GstGL helper headers in uninstalled builds. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a7859564a7..0e094918fc 100644 --- a/configure.ac +++ b/configure.ac @@ -413,7 +413,7 @@ if test $HAVE_GSTGL -eq 1; then AC_CACHE_CHECK([for GStreamer OpenGL helper libraries], [ac_cv_have_gst_gl_helpers], [ saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_GL_CFLAGS" + CPPFLAGS="$CPPFLAGS $GST_GL_CFLAGS $GST_VIDEO_CFLAGS" saved_LIBS="$LIBS" LIBS="$saved_LIBS" AC_CHECK_HEADERS([gst/gl/gl.h], [:], [HAVE_GSTGL=0]) From 26cedfa9fa6726a327d770d13ef711fea8fec38a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 21 May 2015 19:38:33 +0200 Subject: [PATCH 2029/3781] vaapidecode: calculate decoding latency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a naïve approach to the calculation of the VA-API decoding latency. It takes into consideration when the frame-rate has some insane value. https://bugzilla.gnome.org/show_bug.cgi?id=740419 --- gst/vaapi/gstvaapidecode.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4a7916ac65..ac4208e14a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -226,6 +226,22 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) gst_caps_set_features (state->caps, 0, features); gst_caps_replace (&decode->srcpad_caps, state->caps); gst_video_codec_state_unref (state); + + gint fps_n = GST_VIDEO_INFO_FPS_N (vi); + gint fps_d = GST_VIDEO_INFO_FPS_D (vi); + if (fps_n <= 0 || fps_d <= 0) { + GST_DEBUG_OBJECT (decode, "forcing 25/1 framerate for latency calculation"); + fps_n = 1; + fps_d = 25; + } + + /* For parsing/preparation purposes we'd need at least 1 frame + * latency in general, with perfectly known unit boundaries (NALU, + * AU), and up to 2 frames when we need to wait for the second frame + * start to determine the first frame is complete */ + GstClockTime latency = gst_util_uint64_scale (2 * GST_SECOND, fps_d, fps_n); + gst_video_decoder_set_latency (vdec, latency, latency); + return TRUE; } From 2492afa86c0795b1902ab5ead375064bcec32c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 1 Jun 2015 18:39:18 +0200 Subject: [PATCH 2030/3781] vaapidecode: remove unneeded casting And a code-style fix --- gst/vaapi/gstvaapidecode.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ac4208e14a..2087a2fa23 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -214,8 +214,7 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) } state = gst_video_decoder_set_output_state (vdec, format, - ref_state->info.width, ref_state->info.height, - (GstVideoCodecState *) ref_state); + ref_state->info.width, ref_state->info.height, ref_state); if (!state || state->info.width == 0 || state->info.height == 0) return FALSE; @@ -670,7 +669,7 @@ gst_vaapidecode_purge (GstVaapiDecode * decode) GstVideoCodecFrame *frame = NULL; status = - gst_vaapi_decoder_get_frame_with_timeout (decode->decoder, &frame, 0); + gst_vaapi_decoder_get_frame_with_timeout (decode->decoder, &frame, 0); if (frame) { gst_video_decoder_release_frame (GST_VIDEO_DECODER (decode), frame); gst_video_codec_frame_unref (frame); From d2791a7844b83bb0bad40784541aa57403214f6e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 2 Jun 2015 11:46:00 +0200 Subject: [PATCH 2031/3781] decoder: h264: fix uninitialized variables in avcC mode. Fix uninitialized variables when decoding SPS and PPS NAL units from "codec-data" buffers. This is particularly important when seeking ops are involved, and the new persistent states are used more often. https://bugzilla.gnome.org/show_bug.cgi?id=750094 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 20d96ceec0..677e73b7ac 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4285,6 +4285,9 @@ gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder, goto cleanup; ofs = pi->nalu.offset + pi->nalu.size; + pi->state = priv->parser_state; + pi->flags = 0; + status = decode_sps(decoder, &unit); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto cleanup; @@ -4315,6 +4318,9 @@ gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder, goto cleanup; ofs = pi->nalu.offset + pi->nalu.size; + pi->state = priv->parser_state; + pi->flags = 0; + status = decode_pps(decoder, &unit); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto cleanup; From 2a2ecbe8652555ecd2c888be025a9720ddf36214 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 2 Jun 2015 08:52:53 +0300 Subject: [PATCH 2032/3781] encoder: jpeg: Fix the packed header generation This is a work-around to satisfy the va-intel-driver. Normalize the quality factor and scale QM values (only for packed header generation) 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. https://bugzilla.gnome.org/show_bug.cgi?id=748335 Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 40 +++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index f959b268c4..c2b0181f8c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -67,6 +67,7 @@ struct _GstVaapiEncoderJpeg GstVaapiProfile profile; guint quality; GstJpegQuantTables quant_tables; + GstJpegQuantTables scaled_quant_tables; gboolean has_quant_tables; GstJpegHuffmanTables huff_tables; gboolean has_huff_tables; @@ -243,6 +244,34 @@ ensure_picture (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture, 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 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) / 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) / 100; + scaled_quant_tables->quant_tables[1].quant_table[i] = + CLAMP (qt_val, 1, 255); + } +} + static gboolean fill_quantization_table (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture) @@ -262,6 +291,8 @@ fill_quantization_table (GstVaapiEncoderJpeg * encoder, if (!encoder->has_quant_tables) { 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); } q_matrix->load_lum_quantiser_matrix = 1; for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) { @@ -472,8 +503,11 @@ bs_write_jpeg_header (GstBitWriter * bs, GstVaapiEncoderJpeg * encoder, /* Add quantization table */ if (!encoder->has_quant_tables) { gst_jpeg_get_default_quantization_tables (&encoder->quant_tables); + generate_scaled_qm (&encoder->quant_tables, &encoder->scaled_quant_tables, + encoder->quality); 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 @@ -481,7 +515,7 @@ bs_write_jpeg_header (GstBitWriter * bs, GstVaapiEncoderJpeg * encoder, 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->quant_tables.quant_tables[0].quant_table[i], 8); + 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); @@ -490,7 +524,7 @@ bs_write_jpeg_header (GstBitWriter * bs, GstVaapiEncoderJpeg * encoder, 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->quant_tables.quant_tables[1].quant_table[i], 8); + encoder->scaled_quant_tables.quant_tables[1].quant_table[i], 8); } /*Add frame header */ @@ -713,6 +747,8 @@ gst_vaapi_encoder_jpeg_init (GstVaapiEncoder * base_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)); From d0a1636fa8b9828913c45199a6d437a5fd8bc334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 4 Jun 2015 18:29:15 +0200 Subject: [PATCH 2033/3781] build: don't build in parallel libvpx This fixes the distcheck -j XX target. --- ext/libvpx/Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/libvpx/Makefile.am b/ext/libvpx/Makefile.am index d54c298e2f..42db5493dd 100644 --- a/ext/libvpx/Makefile.am +++ b/ext/libvpx/Makefile.am @@ -149,3 +149,7 @@ dist-hook: done -include $(top_srcdir)/git.mk + +# Tell version 3.79 and up of GNU make to not build goals in this +# directory in parallel. +.NOTPARALLEL: From d8764aa11b826eb11cdb75b7ba8fa1346644911d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 4 Jun 2015 19:03:44 +0200 Subject: [PATCH 2034/3781] patches/videoparsers: rebase all the h264parse patches In order to avoid the creation of .orig files and break the distcheck target --- ...ins-compile-the-built-in-video-parsers-as-vaapip.patch | 6 +++--- ...4parse-fix-build-with-older-GStreamer-1.x-stacks.patch | 6 +++--- ...parse-default-to-byte-stream-nalu-format-Annex-B.patch | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch b/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch index c82d465268..c08a6eedd4 100644 --- a/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch +++ b/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch @@ -1,4 +1,4 @@ -From c2531548cad46c80b665e7d78b2a0a0d63a083a9 Mon Sep 17 00:00:00 2001 +From a0cdb5443b5ae3176b217a08fb5107e77eea4113 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Apr 2014 17:44:03 +0200 Subject: [PATCH 1/3] plugins: compile the built-in video parsers as @@ -12,7 +12,7 @@ vaapiparse_CODEC. 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 3473ca8..078ca83 100644 +index 76f7686..9d588e2 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c @@ -26,6 +26,7 @@ @@ -23,7 +23,7 @@ index 3473ca8..078ca83 100644 #include #include #include -@@ -121,7 +122,8 @@ gst_h264_parse_class_init (GstH264ParseClass * klass) +@@ -120,7 +121,8 @@ gst_h264_parse_class_init (GstH264ParseClass * klass) GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass); GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); diff --git a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch index 1635475ce5..d58bcc850a 100644 --- a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch +++ b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch @@ -1,4 +1,4 @@ -From df5b8e09df21d96aaace4376318d5790d7c51cdc Mon Sep 17 00:00:00 2001 +From cfc25cf07e6547c9b9b6bd0ee7e337df0ba842d2 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Apr 2014 17:17:04 +0200 Subject: [PATCH 2/3] h264parse: fix build with older GStreamer 1.x stacks. @@ -9,7 +9,7 @@ Subject: [PATCH 2/3] h264parse: fix build with older GStreamer 1.x stacks. 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 078ca83..fceec68 100644 +index 9d588e2..4060145 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c @@ -27,7 +27,7 @@ @@ -21,7 +21,7 @@ index 078ca83..fceec68 100644 #include #include #include "gsth264parse.h" -@@ -164,7 +164,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) +@@ -163,7 +163,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) { h264parse->frame_out = gst_adapter_new (); gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h264parse), FALSE); diff --git a/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch b/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch index 4bd43eeac2..da8a1ae40e 100644 --- a/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch +++ b/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch @@ -1,4 +1,4 @@ -From 7650c8681ecf1304a59e7cc4c0bc9eba4f753ffa Mon Sep 17 00:00:00 2001 +From 652357e0da6528b0ff8a8e01782c84c032c9f342 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 May 2015 09:33:57 +0300 Subject: [PATCH 3/3] h264parse: default to byte-stream/nalu format (Annex B). @@ -17,10 +17,10 @@ Signed-off-by: Sreerenj Balachandran 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 76f7686..b28d449 100644 +index 4060145..b5d2955 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c -@@ -388,7 +388,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, +@@ -392,7 +392,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, if (!format) format = GST_H264_PARSE_FORMAT_BYTE; if (!align) @@ -30,7 +30,7 @@ index 76f7686..b28d449 100644 GST_DEBUG_OBJECT (h264parse, "selected format %s, alignment %s", gst_h264_parse_get_string (h264parse, TRUE, format), -@@ -2260,6 +2261,8 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) +@@ -2264,6 +2265,8 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) /* bytestream caps sanity checks */ if (format == GST_H264_PARSE_FORMAT_BYTE) { From b524990e075b910ad1976ee20263201420c20cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 20 May 2015 18:02:37 +0200 Subject: [PATCH 2035/3781] doc: add VA-API reference in freedesktop --- docs/reference/libs/libs-docs.xml.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in index 720e79f586..84228ff935 100644 --- a/docs/reference/libs/libs-docs.xml.in +++ b/docs/reference/libs/libs-docs.xml.in @@ -6,6 +6,11 @@ GStreamer VA-API Plugins @GST_API_VERSION@ Library Reference Manual + + To ease the creation of plugins, a Gstreamer-oriented library was created, + which wraps VA-API. + + gst-plugins-vaapi Library From 1ef8c10aa88350a5a7f636d56ef584a982741d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 May 2015 18:13:25 +0200 Subject: [PATCH 2036/3781] vaapipostproc: add skin tone enhancement Added the 'skin-tone-enhancement' property to vaapostproc. https://bugzilla.gnome.org/show_bug.cgi?id=744088 --- gst-libs/gst/vaapi/gstvaapifilter.c | 84 +++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 6 +++ gst/vaapi/gstvaapipostproc.c | 23 ++++++++ gst/vaapi/gstvaapipostproc.h | 4 ++ 4 files changed, 117 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 67cd539418..3ca4b4b094 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -278,6 +278,7 @@ enum PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST, PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING, PROP_SCALING = GST_VAAPI_FILTER_OP_SCALING, + PROP_SKINTONE = GST_VAAPI_FILTER_OP_SKINTONE, N_PROPERTIES }; @@ -399,6 +400,16 @@ init_properties (void) "Scaling method to use", GST_VAAPI_TYPE_SCALE_METHOD, DEFAULT_SCALING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFilter:skin-tone-enhancement: + * + * Apply the skin tone enhancement algorithm. + */ + g_properties[PROP_SKINTONE] = g_param_spec_boolean ("skin-tone-enhancement", + "Skin tone enhancement", + "Apply the skin tone enhancement algorithm", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); } static void @@ -447,6 +458,10 @@ op_data_new (GstVaapiFilterOp op, GParamSpec * pspec) op_data->va_cap_size = sizeof (VAProcFilterCap); op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer); break; + case GST_VAAPI_FILTER_OP_SKINTONE: + op_data->va_type = VAProcFilterSkinToneEnhancement; + op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer); + break; case GST_VAAPI_FILTER_OP_HUE: op_data->va_subtype = VAProcColorBalanceHue; goto op_colorbalance; @@ -628,6 +643,11 @@ get_operations_ordered (GstVaapiFilter * filter, GPtrArray * default_ops) if (op_data->va_type != va_type) continue; + if (op_data->va_cap_size == 0) { /* no caps, like skintone */ + g_ptr_array_add (ops, op_data_ref (op_data)); + continue; + } + if (!filter_caps) { filter_caps = vpp_get_filter_caps (filter, va_type, op_data->va_cap_size, &num_filter_caps); @@ -878,6 +898,46 @@ op_set_deinterlace (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, return success; } +/* Update skin tone enhancement */ +#if USE_VA_VPP +gboolean +op_set_skintone_unlocked (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data, gboolean value) +{ + VAProcFilterParameterBuffer *buf; + + if (!op_data || !op_ensure_buffer (filter, op_data)) + return FALSE; + + op_data->is_enabled = value; + if (!op_data->is_enabled) + return TRUE; + + buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer); + if (!buf) + return FALSE; + buf->type = op_data->va_type; + buf->value = 0; + vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL); + return TRUE; +} +#endif + +static inline gboolean +op_set_skintone (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, + gboolean enhance) +{ + gboolean success = FALSE; + +#if USE_VA_VPP + GST_VAAPI_DISPLAY_LOCK (filter->display); + success = op_set_skintone_unlocked (filter, op_data, enhance); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); +#endif + return success; +} + + static gboolean deint_refs_set (GArray * refs, GstVaapiSurface ** surfaces, guint num_surfaces) { @@ -1300,6 +1360,10 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, case GST_VAAPI_FILTER_OP_SCALING: return gst_vaapi_filter_set_scaling (filter, value ? g_value_get_enum (value) : DEFAULT_SCALING); + case GST_VAAPI_FILTER_OP_SKINTONE: + return op_set_skintone (filter, op_data, + (value ? g_value_get_boolean (value) : + G_PARAM_SPEC_BOOLEAN (op_data->pspec)->default_value)); default: break; } @@ -1789,3 +1853,23 @@ gst_vaapi_filter_set_scaling (GstVaapiFilter * filter, filter->scale_method = method; return TRUE; } + +/** + * gst_vaapi_filter_set_skintone: + * @filter: a #GstVaapiFilter + * @enhance: %TRUE if enable the skin tone enhancement algorithm + * + * Applies the skin tone enhancement algorithm. + * + * Return value: %TRUE if the operation is supported, %FALSE + * otherwise. + **/ +gboolean +gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, + gboolean enhance) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return op_set_skintone (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE), enhance); +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 0f25a86b0c..6364803c06 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -41,6 +41,7 @@ typedef struct _GstVaapiFilterOpInfo GstVaapiFilterOpInfo; * @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_SKINTONE: Skin tone enhancement (bool). * * The set of operations that could be applied to the filter. */ @@ -55,6 +56,7 @@ typedef enum { GST_VAAPI_FILTER_OP_CONTRAST, GST_VAAPI_FILTER_OP_DEINTERLACING, GST_VAAPI_FILTER_OP_SCALING, + GST_VAAPI_FILTER_OP_SKINTONE, } GstVaapiFilterOp; /** @@ -240,4 +242,8 @@ gboolean gst_vaapi_filter_set_scaling (GstVaapiFilter * filter, GstVaapiScaleMethod method); +gboolean +gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, + gboolean enhance); + #endif /* GST_VAAPI_FILTER_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 1b8acb9c62..baa5a73e98 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -104,6 +104,7 @@ enum PROP_BRIGHTNESS, PROP_CONTRAST, PROP_SCALE_METHOD, + PROP_SKIN_TONE_ENHANCEMENT, }; #define DEFAULT_FORMAT GST_VIDEO_FORMAT_ENCODED @@ -522,6 +523,11 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, !gst_vaapi_filter_set_scaling (postproc->filter, postproc->scale_method)) return GST_FLOW_NOT_SUPPORTED; + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SKINTONE) && + !gst_vaapi_filter_set_skintone (postproc->filter, + postproc->skintone_enhance)) + return GST_FLOW_NOT_SUPPORTED; + inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); if (!inbuf_meta) goto error_invalid_buffer; @@ -1352,6 +1358,10 @@ gst_vaapipostproc_set_property (GObject * object, postproc->scale_method = g_value_get_enum (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SCALE; break; + case PROP_SKIN_TONE_ENHANCEMENT: + postproc->skintone_enhance = g_value_get_boolean (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SKINTONE; + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1404,6 +1414,9 @@ gst_vaapipostproc_get_property (GObject * object, case PROP_SCALE_METHOD: g_value_set_enum (value, postproc->scale_method); break; + case PROP_SKIN_TONE_ENHANCEMENT: + g_value_set_boolean (value, postproc->skintone_enhance); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1619,6 +1632,16 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) g_object_class_install_property (object_class, PROP_SCALE_METHOD, filter_op->pspec); + /** + * GstVaapiPostproc:skin-tone-enhancement: + * + * Apply the skin tone enhancement algorithm. + */ + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_SKINTONE); + if (filter_op) + g_object_class_install_property (object_class, + PROP_SKIN_TONE_ENHANCEMENT, filter_op->pspec); + g_ptr_array_unref (filter_ops); } diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index a74043d419..dc50fb3d28 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -86,6 +86,7 @@ typedef enum * @GST_VAAPI_POSTPROC_FLAG_DEINTERLACE: Deinterlacing. * @GST_VAAPI_POSTPROC_FLAG_SIZE: Video scaling. * @GST_VAAPI_POSTPROC_FLAG_SCALE: Video scaling mode. + * @GST_VAAPI_POSTPROC_FLAG_SKINTONE: Skin tone enhancement. * * The set of operations that are to be performed for each frame. */ @@ -100,6 +101,7 @@ typedef enum GST_VAAPI_POSTPROC_FLAG_CONTRAST = 1 << GST_VAAPI_FILTER_OP_CONTRAST, GST_VAAPI_POSTPROC_FLAG_DEINTERLACE = 1 << GST_VAAPI_FILTER_OP_DEINTERLACING, GST_VAAPI_POSTPROC_FLAG_SCALE = 1 << GST_VAAPI_FILTER_OP_SCALING, + GST_VAAPI_POSTPROC_FLAG_SKINTONE = 1 << GST_VAAPI_FILTER_OP_SKINTONE, /* Additional custom flags */ GST_VAAPI_POSTPROC_FLAG_CUSTOM = 1 << 20, @@ -164,6 +166,8 @@ struct _GstVaapiPostproc gfloat brightness; gfloat contrast; + gboolean skintone_enhance; + guint get_va_surfaces:1; guint has_vpp:1; guint use_vpp:1; From cbc2d15becc33718085c6663f300e5a4cd2b1b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 9 Jun 2015 15:15:31 +0200 Subject: [PATCH 2037/3781] vaapipostproc: add color balance interface https://bugzilla.gnome.org/show_bug.cgi?id=720376 --- gst/vaapi/gstvaapipostproc.c | 197 ++++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapipostproc.h | 3 + 2 files changed, 199 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index baa5a73e98..2a5f43302a 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -84,8 +84,12 @@ static GstStaticPadTemplate gst_vaapipostproc_src_factory = GST_STATIC_CAPS (gst_vaapipostproc_src_caps_str)); /* *INDENT-ON* */ +static void gst_vaapipostproc_colorbalance_init (gpointer iface, gpointer data); + G_DEFINE_TYPE_WITH_CODE (GstVaapiPostproc, gst_vaapipostproc, - GST_TYPE_BASE_TRANSFORM, GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES); + GST_TYPE_BASE_TRANSFORM, GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES + G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE, + gst_vaapipostproc_colorbalance_init)); enum { @@ -278,6 +282,10 @@ gst_vaapipostproc_destroy_filter (GstVaapiPostproc * postproc) g_ptr_array_unref (postproc->filter_ops); postproc->filter_ops = NULL; } + if (postproc->cb_channels) { + g_list_free_full (postproc->cb_channels, g_object_unref); + postproc->cb_channels = NULL; + } gst_vaapi_filter_replace (&postproc->filter, NULL); gst_vaapi_video_pool_replace (&postproc->filter_pool, NULL); } @@ -1645,9 +1653,47 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) g_ptr_array_unref (filter_ops); } +static float * +find_value_ptr (GstVaapiPostproc * postproc, GstVaapiFilterOp op) +{ + switch (op) { + case GST_VAAPI_FILTER_OP_HUE: + return &postproc->hue; + case GST_VAAPI_FILTER_OP_SATURATION: + return &postproc->saturation; + case GST_VAAPI_FILTER_OP_BRIGHTNESS: + return &postproc->brightness; + case GST_VAAPI_FILTER_OP_CONTRAST: + return &postproc->contrast; + default: + return NULL; + } +} + +static void +cb_set_default_value (GstVaapiPostproc * postproc, GPtrArray * filter_ops, + GstVaapiFilterOp op) +{ + GstVaapiFilterOpInfo *filter_op; + GParamSpecFloat *pspec; + float *var; + + filter_op = find_filter_op (filter_ops, op); + if (!filter_op) + return; + var = find_value_ptr (postproc, op); + if (!var) + return; + pspec = G_PARAM_SPEC_FLOAT (filter_op->pspec); + *var = pspec->default_value; +} + static void gst_vaapipostproc_init (GstVaapiPostproc * postproc) { + GPtrArray *filter_ops; + guint i; + gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (postproc), GST_CAT_DEFAULT); @@ -1658,7 +1704,156 @@ gst_vaapipostproc_init (GstVaapiPostproc * postproc) postproc->keep_aspect = TRUE; postproc->get_va_surfaces = TRUE; + filter_ops = gst_vaapi_filter_get_operations (NULL); + if (filter_ops) { + for (i = GST_VAAPI_FILTER_OP_HUE; i <= GST_VAAPI_FILTER_OP_CONTRAST; i++) + cb_set_default_value (postproc, filter_ops, i); + g_ptr_array_unref (filter_ops); + } + gst_video_info_init (&postproc->sinkpad_info); gst_video_info_init (&postproc->srcpad_info); gst_video_info_init (&postproc->filter_pool_info); } + +/* ------------------------------------------------------------------------ */ +/* --- GstColorBalance interface --- */ +/* ------------------------------------------------------------------------ */ + +#define CB_CHANNEL_FACTOR 1000.0 + +typedef struct +{ + GstVaapiFilterOp op; + const gchar *name; +} ColorBalanceChannel; + +ColorBalanceChannel cb_channels[] = { + {GST_VAAPI_FILTER_OP_HUE, "VA_FILTER_HUE"}, + {GST_VAAPI_FILTER_OP_SATURATION, "VA_FILTER_SATURATION"}, + {GST_VAAPI_FILTER_OP_BRIGHTNESS, "VA_FILTER_BRIGHTNESS"}, + {GST_VAAPI_FILTER_OP_CONTRAST, "VA_FILTER_CONTRAST"}, +}; + +static void +cb_channels_init (GstVaapiPostproc * postproc) +{ + GPtrArray *filter_ops; + GstVaapiFilterOpInfo *filter_op; + GParamSpecFloat *pspec; + GstColorBalanceChannel *channel; + guint i; + + if (postproc->cb_channels) + return; + + if (!gst_vaapipostproc_ensure_filter (postproc)) + return; + + filter_ops = postproc->filter_ops ? g_ptr_array_ref (postproc->filter_ops) + : gst_vaapi_filter_get_operations (postproc->filter); + if (!filter_ops) + return; + + for (i = 0; i < G_N_ELEMENTS (cb_channels); i++) { + filter_op = find_filter_op (filter_ops, cb_channels[i].op); + if (!filter_op) + continue; + + pspec = G_PARAM_SPEC_FLOAT (filter_op->pspec); + channel = g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL, NULL); + channel->label = g_strdup (cb_channels[i].name); + channel->min_value = pspec->minimum * CB_CHANNEL_FACTOR; + channel->max_value = pspec->maximum * CB_CHANNEL_FACTOR; + + postproc->cb_channels = g_list_prepend (postproc->cb_channels, channel); + } + + g_ptr_array_unref (filter_ops); +} + +static const GList * +gst_vaapipostproc_colorbalance_list_channels (GstColorBalance * balance) +{ + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (balance); + + cb_channels_init (postproc); + return postproc->cb_channels; +} + +static gfloat * +cb_get_value_ptr (GstVaapiPostproc * postproc, GstColorBalanceChannel * channel, + GstVaapiPostprocFlags * flags) +{ + guint i; + gfloat *ret = NULL; + + for (i = 0; i < G_N_ELEMENTS (cb_channels); i++) { + if (g_ascii_strcasecmp (cb_channels[i].name, channel->label) == 0) + break; + } + if (i >= G_N_ELEMENTS (cb_channels)) + return NULL; + + ret = find_value_ptr (postproc, cb_channels[i].op); + if (flags) + *flags = 1 << cb_channels[i].op; + return ret; +} + +static void +gst_vaapipostproc_colorbalance_set_value (GstColorBalance * balance, + GstColorBalanceChannel * channel, gint value) +{ + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (balance); + GstVaapiPostprocFlags flags; + gfloat new_val, *var; + + value = CLAMP (value, channel->min_value, channel->max_value); + new_val = (gfloat) value / CB_CHANNEL_FACTOR; + + var = cb_get_value_ptr (postproc, channel, &flags); + if (var) { + *var = new_val; + postproc->flags |= flags; + gst_color_balance_value_changed (balance, channel, value); + return; + } + + GST_WARNING_OBJECT (postproc, "unknown channel %s", channel->label); +} + +static gint +gst_vaapipostproc_colorbalance_get_value (GstColorBalance * balance, + GstColorBalanceChannel * channel) +{ + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (balance); + gfloat *var; + gint new_val; + + var = cb_get_value_ptr (postproc, channel, NULL); + if (var) { + new_val = (gint) ((*var) * CB_CHANNEL_FACTOR); + new_val = CLAMP (new_val, channel->min_value, channel->max_value); + return new_val; + } + + GST_WARNING_OBJECT (postproc, "unknown channel %s", channel->label); + return G_MININT; +} + +static GstColorBalanceType +gst_vaapipostproc_colorbalance_get_balance_type (GstColorBalance * balance) +{ + return GST_COLOR_BALANCE_HARDWARE; +} + +static void +gst_vaapipostproc_colorbalance_init (gpointer iface, gpointer data) +{ + GstColorBalanceInterface *cbface = iface; + cbface->list_channels = gst_vaapipostproc_colorbalance_list_channels; + cbface->set_value = gst_vaapipostproc_colorbalance_set_value; + cbface->get_value = gst_vaapipostproc_colorbalance_get_value; + cbface->get_balance_type = gst_vaapipostproc_colorbalance_get_balance_type; +} diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index dc50fb3d28..a42997560a 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -172,6 +172,9 @@ struct _GstVaapiPostproc guint has_vpp:1; guint use_vpp:1; guint keep_aspect:1; + + /* color balance's channel list */ + GList *cb_channels; }; struct _GstVaapiPostprocClass From 3241296f67be75a100a7926eee5a7918dd66dc08 Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Wed, 17 Jun 2015 09:53:29 +0300 Subject: [PATCH 2038/3781] vaapipluginbase: Override downstream allocation reply if no pool If the downstream replied without a pool, then override it. https://bugzilla.gnome.org/show_bug.cgi?id=748559 --- gst/vaapi/gstvaapipluginbase.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e4f1c586ad..6624316bb0 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -687,10 +687,9 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); - update_pool = (pool != NULL); + update_pool = TRUE; + size = MAX (size, vi.size); if (pool) { - size = MAX (size, vi.size); - /* Check whether downstream element proposed a bufferpool but did not provide a correct propose_allocation() implementation */ has_video_alignment = gst_buffer_pool_has_option (pool, From 64acc74d1795c3f5cadddc550e5d4c77257a878d Mon Sep 17 00:00:00 2001 From: Adrian Cox Date: Wed, 17 Jun 2015 12:41:28 +0300 Subject: [PATCH 2039/3781] vaapisink: Expose the overlay capability for compatibility with dvbsuboverlay. https://bugzilla.gnome.org/show_bug.cgi?id=750095 Signed-off-by: Sreerenj Balachandran Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index bc89cff7c5..26ea5bf4c1 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -57,9 +57,19 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapisink); /* Default template */ /* *INDENT-OFF* */ static const char gst_vaapisink_sink_caps_str[] = - GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, - "{ ENCODED, NV12, I420, YV12 }") ";" - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL); + GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE +#if GST_CHECK_VERSION(1,3,1) + "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION +#endif + ,"{ ENCODED, NV12, I420, YV12 }") ";" +#if GST_CHECK_VERSION(1,3,1) + GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + GST_VIDEO_FORMATS_ALL); +#else + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL); +#endif /* *INDENT-ON* */ static GstStaticPadTemplate gst_vaapisink_sink_factory = From 28e50ad40788735bcfaa0d5f33abcd942d678b09 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 17 Jun 2015 14:20:37 +0300 Subject: [PATCH 2040/3781] vaapisink: Fix the capsfeature advertisement in padtemplate This fixes the regression introduced in 64acc74. If a pad supports multiple set of capsfeatures, it needs to add multiple equal structures with different feature sets to the caps. Because caps structures with the same name but with a non-equal set of caps features are not compatible. Without this patch, playbin will autoplug xvimagesink instead of vaapisink. https://bugzilla.gnome.org/show_bug.cgi?id=750095 --- gst/vaapi/gstvaapisink.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 26ea5bf4c1..5c78a0b26c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -58,17 +58,19 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapisink); /* *INDENT-OFF* */ static const char gst_vaapisink_sink_caps_str[] = GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, + "{ ENCODED, NV12, I420, YV12 }") ";" #if GST_CHECK_VERSION(1,3,1) - "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION + GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "," + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + "{ ENCODED, NV12, I420, YV12 }") ";" #endif - ,"{ ENCODED, NV12, I420, YV12 }") ";" + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ";" #if GST_CHECK_VERSION(1,3,1) GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, GST_VIDEO_FORMATS_ALL); -#else - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL); #endif /* *INDENT-ON* */ From cf9a0225c8c1999d4214b4b814ee2a629c6cde0b Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 18 Jun 2015 12:20:37 +0300 Subject: [PATCH 2041/3781] Fix build error for older VA-API versions Provide guards for VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM and VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME which are only availble from VA >= 0.36. --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 5 ++++- gst-libs/gst/vaapi/gstvaapicompat.h | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index 92655668ec..aba9d301f5 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -21,7 +21,6 @@ */ #include "sysdeps.h" -#include #include "gstvaapicompat.h" #include "gstvaapibufferproxy.h" #include "gstvaapibufferproxy_priv.h" @@ -42,12 +41,14 @@ from_GstVaapiBufferMemoryType (guint type) guint va_type; switch (type) { +#if VA_CHECK_VERSION(0,36,0) case GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF: va_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; break; case GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF: va_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; break; +#endif default: va_type = 0; break; @@ -61,12 +62,14 @@ to_GstVaapiBufferMemoryType (guint va_type) guint type; switch (va_type) { +#if VA_CHECK_VERSION(0,36,0) case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: type = GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF; break; case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: type = GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF; break; +#endif default: type = 0; break; diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 0e4b24a646..781e30d610 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -42,6 +42,10 @@ # include #endif +#if VA_CHECK_VERSION(0,36,0) +#include +#endif + #ifdef HAVE_VA_VA_DEC_HEVC_H # include #endif From 2d64321313e66ac5d78e870ffec83c9658e29107 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 18 Jun 2015 13:19:26 +0300 Subject: [PATCH 2042/3781] build: Don't build simple-encoder test program if there is no VA Encoding support This will fix the build error against older VA-APIs <= 0.32 --- tests/Makefile.am | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Makefile.am b/tests/Makefile.am index 8fb3f95d55..3637d92297 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,8 +6,13 @@ noinst_PROGRAMS = \ test-surfaces \ test-windows \ test-subpicture \ + $(NULL) + +if USE_ENCODERS +noinst_PROGRAMS += \ simple-encoder \ $(NULL) +endif if USE_GLX noinst_PROGRAMS += \ From 34a4748d3d65fd4df5b2c9b09e066af752f9aeea Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 18 Jun 2015 14:55:12 +0300 Subject: [PATCH 2043/3781] vaapisink: Fix the conditional pad template creation. --- gst/vaapi/gstvaapisink.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 5c78a0b26c..8f4eb02046 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -65,13 +65,11 @@ static const char gst_vaapisink_sink_caps_str[] = GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, "{ ENCODED, NV12, I420, YV12 }") ";" -#endif - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ";" -#if GST_CHECK_VERSION(1,3,1) GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_VIDEO_FORMATS_ALL); + GST_VIDEO_FORMATS_ALL) ";" #endif + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL); /* *INDENT-ON* */ static GstStaticPadTemplate gst_vaapisink_sink_factory = From 0df96e1c3be63770672b097e43fac119a8434316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 7 May 2015 15:57:26 +0200 Subject: [PATCH 2044/3781] vaapisink: error handling if rendering fails This patch enhance the code path when an error is found when rendering a buffer. If the video meta doesn't contain a surface proxy or a surface, a warning message is printed. If the rendering backend fails, a error message is posted in the bus. https://bugzilla.gnome.org/show_bug.cgi?id=749382 --- gst/vaapi/gstvaapisink.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 8f4eb02046..82769684e6 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1356,19 +1356,19 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) proxy = gst_vaapi_video_meta_get_surface_proxy (meta); if (!proxy) - goto error; + goto no_surface; surface = gst_vaapi_video_meta_get_surface (meta); if (!surface) - goto error; + goto no_surface; /* Validate view component to display */ view_id = GST_VAAPI_SURFACE_PROXY_VIEW_ID (proxy); if (G_UNLIKELY (sink->view_id == -1)) sink->view_id = view_id; else if (sink->view_id != view_id) { - gst_buffer_unref (buffer); - return GST_FLOW_OK; + ret = GST_FLOW_OK; + goto done; } gst_vaapisink_ensure_colorbalance (sink); @@ -1404,13 +1404,24 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) /* Retain VA surface until the next one is displayed */ gst_buffer_replace (&sink->video_buffer, buffer); - gst_buffer_unref (buffer); - return GST_FLOW_OK; + ret = GST_FLOW_OK; + +done: + gst_buffer_unref (buffer); + return ret; error: - gst_buffer_unref (buffer); - return GST_FLOW_EOS; + GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, + ("Internal error: could not render surface"), (NULL)); + ret = GST_FLOW_ERROR; + goto done; + +no_surface: + /* No surface or surface proxy. That's very bad! */ + GST_WARNING_OBJECT (sink, "could not get surface"); + ret = GST_FLOW_ERROR; + goto done; } static GstFlowReturn From e2d60c83a6b5f7300f1c605d293787aa2474b1e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 12 Feb 2015 12:31:57 +0100 Subject: [PATCH 2045/3781] vaapidecode: log negotiated src/sink caps --- gst/vaapi/gstvaapidecode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 2087a2fa23..b40dd97804 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -165,6 +165,7 @@ gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, static inline gboolean gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps) { + GST_INFO_OBJECT (decode, "new sink caps = %" GST_PTR_FORMAT, caps); gst_caps_replace (&decode->sinkpad_caps, caps); return TRUE; } @@ -223,6 +224,7 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) state->caps = gst_video_info_to_caps (vi); if (features) gst_caps_set_features (state->caps, 0, features); + GST_INFO_OBJECT (decode, "new src caps = %" GST_PTR_FORMAT, state->caps); gst_caps_replace (&decode->srcpad_caps, state->caps); gst_video_codec_state_unref (state); From 700f01076654c526a0b8e835ab10aba82c55f7ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 18 May 2015 14:30:22 +0200 Subject: [PATCH 2046/3781] vaapipostproc: remove useless debug message --- gst/vaapi/gstvaapipostproc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 2a5f43302a..16e0a26048 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1266,8 +1266,6 @@ gst_vaapipostproc_query (GstBaseTransform * trans, GstPadDirection direction, { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - GST_DEBUG_OBJECT (trans, "query type `%s'", GST_QUERY_TYPE_NAME (query)); - if (gst_vaapi_reply_to_query (query, GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc))) { GST_DEBUG_OBJECT (postproc, "sharing display %p", From eb510e23cecd02ffc9c3906807487fa1d156e627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 May 2015 11:24:10 +0200 Subject: [PATCH 2047/3781] vaapipostproc: log negotiated caps --- gst/vaapi/gstvaapipostproc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 16e0a26048..40d9466d29 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -876,6 +876,8 @@ gst_vaapipostproc_update_sink_caps (GstVaapiPostproc * postproc, GstCaps * caps, GstVideoInfo vi; gboolean deinterlace; + GST_INFO_OBJECT (postproc, "new sink caps = %" GST_PTR_FORMAT, caps); + if (!gst_video_info_from_caps (&vi, caps)) return FALSE; @@ -899,6 +901,8 @@ gst_vaapipostproc_update_src_caps (GstVaapiPostproc * postproc, GstCaps * caps, { GstVideoInfo vi; + GST_INFO_OBJECT (postproc, "new src caps = %" GST_PTR_FORMAT, caps); + if (!gst_video_info_from_caps (&vi, caps)) return FALSE; From 76060c9542847a93edc6912dc21a4ef8f162dd75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Aragunde=20P=C3=A9rez?= Date: Wed, 29 Apr 2015 16:34:07 +0200 Subject: [PATCH 2048/3781] vaapidecodebin: expose deinterlace-method property from inner vaapipostproc https://bugzilla.gnome.org/show_bug.cgi?id=745901 --- gst/vaapi/gstvaapidecodebin.c | 20 +++++++++++++++++++- gst/vaapi/gstvaapidecodebin.h | 3 +++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 27d0f4adf6..840548f397 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -37,13 +37,15 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapi_decode_bin); #define DEFAULT_QUEUE_MAX_SIZE_BUFFERS 0 #define DEFAULT_QUEUE_MAX_SIZE_BYTES 0 #define DEFAULT_QUEUE_MAX_SIZE_TIME 0 +#define DEFAULT_DEINTERLACE_METHOD GST_VAAPI_DEINTERLACE_METHOD_BOB enum { PROP_0, PROP_MAX_SIZE_BUFFERS, PROP_MAX_SIZE_BYTES, - PROP_MAX_SIZE_TIME + PROP_MAX_SIZE_TIME, + PROP_DEINTERLACE_METHOD }; #define GST_VAAPI_DECODE_BIN_SURFACE_CAPS \ @@ -120,6 +122,11 @@ gst_vaapi_decode_bin_set_property (GObject * object, g_object_set (G_OBJECT (vaapidecbin->queue), "max-size-time", vaapidecbin->max_size_time, NULL); break; + case PROP_DEINTERLACE_METHOD: + vaapidecbin->deinterlace_method = g_value_get_enum (value); + g_object_set (G_OBJECT (vaapidecbin->postproc), "deinterlace-method", + vaapidecbin->deinterlace_method, NULL); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -142,6 +149,9 @@ gst_vaapi_decode_bin_get_property (GObject * object, case PROP_MAX_SIZE_TIME: g_value_set_uint64 (value, vaapidecbin->max_size_time); break; + case PROP_DEINTERLACE_METHOD: + g_value_set_enum (value, vaapidecbin->deinterlace_method); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -181,6 +191,11 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) "Max. amount of data in the queue (in ns, 0=disable)", 0, G_MAXUINT64, DEFAULT_QUEUE_MAX_SIZE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_DEINTERLACE_METHOD, + g_param_spec_enum ("deinterlace-method", "Deinterlace method", + "Deinterlace method to use", GST_VAAPI_TYPE_DEINTERLACE_METHOD, + DEFAULT_DEINTERLACE_METHOD, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_vaapi_decode_bin_sink_factory)); @@ -223,6 +238,9 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) "max-size-buffers", vaapidecbin->max_size_buffers, "max-size-time", vaapidecbin->max_size_time, NULL); + g_object_set (G_OBJECT (vaapidecbin->postproc), + "deinterlace-method", vaapidecbin->deinterlace_method, NULL); + gst_bin_add_many (GST_BIN (vaapidecbin), vaapidecbin->decoder, vaapidecbin->queue, vaapidecbin->postproc, NULL); diff --git a/gst/vaapi/gstvaapidecodebin.h b/gst/vaapi/gstvaapidecodebin.h index 4d3acfdbd5..928683fc87 100644 --- a/gst/vaapi/gstvaapidecodebin.h +++ b/gst/vaapi/gstvaapidecodebin.h @@ -23,6 +23,8 @@ #ifndef GST_VAAPI_DECODE_BIN_H #define GST_VAAPI_DECODE_BIN_H +#include + G_BEGIN_DECLS #define GST_TYPE_VAAPI_DECODE_BIN (gst_vaapi_decode_bin_get_type ()) @@ -49,6 +51,7 @@ typedef struct _GstVaapiDecodeBin { guint max_size_buffers; guint max_size_bytes; guint64 max_size_time; + GstVaapiDeinterlaceMethod deinterlace_method; } GstVaapiDecodeBin; From d946e7972e0d361f2060349440f0b879c458f59b Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Mon, 29 Jun 2015 13:06:30 +0300 Subject: [PATCH 2049/3781] Work around ABBA deadlock between vaapisink and vaapipostproc vaapisink takes the display lock, then does a gst_buffer_replace which can take the lock on the gst_vaapi_video_pool. vaapipostproc asks the gst_vaapi_video_pool for a new surface. This takes the lock on the gst_vaapi_video_pool; if you're unlucky, there are no free surfaces, which means that gst_vaapi_surface_create is called. gst_vaapi_surface_create takes the display lock. If vaapisink and vaapipostproc are in different threads, and this happens, you get a deadlock. vaapisink holds the display lock, and wants the gst_vaapi_video_pool lock. vaapipostproc holds the gst_vaapi_video_pool lock and wants the display lock. Work around this by releasing the display lock in vaapisink around the gst_buffer_replace. https://bugzilla.gnome.org/show_bug.cgi?id=738249 Signed-off-by: Simon Farnsworth Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapisink.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 82769684e6..2fa36668b0 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1403,7 +1403,10 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) g_signal_emit (sink, gst_vaapisink_signals[HANDOFF_SIGNAL], 0, buffer); /* Retain VA surface until the next one is displayed */ + /* Need to release the lock for the duration, otherwise a deadlock is possible */ + gst_vaapi_display_unlock (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); gst_buffer_replace (&sink->video_buffer, buffer); + gst_vaapi_display_lock (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); ret = GST_FLOW_OK; From a1eef1c35505ae5df9d96ed98eab5c928da77e06 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 29 Jun 2015 13:20:28 +0300 Subject: [PATCH 2050/3781] vaapipostproc: prevent advanced-deinterlacing of non-native video formats. This is a workaround to deal with the va-intel-driver for non-native formats while doing advanced deinterlacing. The format of reference surfaces must be same as the format used by the driver internally for motion adaptive deinterlacing and motion compensated deinterlacing. A permanent solution could be to do the color space conversion internally for reference surfaces. https://bugzilla.gnome.org/show_bug.cgi?id=730925 Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapipostproc.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 40d9466d29..124ccded24 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -91,6 +91,9 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiPostproc, gst_vaapipostproc, G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE, gst_vaapipostproc_colorbalance_init)); +static GstVideoFormat native_formats[] = + { GST_VIDEO_FORMAT_NV12, GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_I420 }; + enum { PROP_0, @@ -1238,15 +1241,37 @@ ensure_srcpad_buffer_pool (GstVaapiPostproc * postproc, GstCaps * caps) return TRUE; } +static gboolean +is_native_video_format (GstVideoFormat format) +{ + guint i = 0; + for (i = 0; i < G_N_ELEMENTS (native_formats); i++) + if (native_formats[i] == format) + return TRUE; + return FALSE; +} + static gboolean gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, GstCaps * out_caps) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); gboolean caps_changed = FALSE; + GstVideoInfo vinfo; if (!gst_vaapipostproc_update_sink_caps (postproc, caps, &caps_changed)) return FALSE; + /* HACK: This is a workaround to deal with the va-intel-driver for non-native + * formats while doing advanced deinterlacing. The format of reference surfaces must + * be same as the format used by the driver internally for motion adaptive + * deinterlacing and motion compensated deinterlacing */ + gst_video_info_from_caps (&vinfo, caps); + if (deint_method_is_advanced (postproc->deinterlace_method) + && !is_native_video_format (GST_VIDEO_INFO_FORMAT (&vinfo))) { + GST_WARNING_OBJECT (postproc, + "Advanced deinterlacing requires the native video formats used by the driver internally"); + return FALSE; + } if (!gst_vaapipostproc_update_src_caps (postproc, out_caps, &caps_changed)) return FALSE; From d14a201699356d1a0fcb140d0700e15df52cc52e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 29 Jun 2015 13:35:59 +0300 Subject: [PATCH 2051/3781] vaapipostproc: Fix wrong selection of passthrough mode. The Current code path is falling back to passthorugh mode if there is no vpp property set by the user explictily. But we should not use the passthrough mode if the negotiated src pad caps have a differnt color space format than sink pad caps (Even though the user didn't set the format property explicitly). https://bugzilla.gnome.org/show_bug.cgi?id=748184 Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapipostproc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 124ccded24..74743c128d 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1110,6 +1110,7 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, peer_caps = gst_caps_fixate (peer_caps); gst_video_info_from_caps (&peer_vi, peer_caps); out_format = GST_VIDEO_INFO_FORMAT (&peer_vi); + postproc->format = out_format; if (peer_caps) gst_caps_unref (peer_caps); } From f1bc4f8461cd6e5be9a22092f8c9c5ea042223e5 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 30 Jun 2015 09:35:37 +0300 Subject: [PATCH 2052/3781] vaapidecodebin: Add property to disable VPP Adding a new propery "disable-vpp", enabling it will prevent the insertion of vaapipostproc child element. This is helpful in debugging, specifically to narrow-down the vaapidecodebin/vaapipostproc related negotiation issues. No support for run-time disabling for now. https://bugzilla.gnome.org/show_bug.cgi?id=745901 --- gst/vaapi/gstvaapidecodebin.c | 88 +++++++++++++++++++++++++++-------- gst/vaapi/gstvaapidecodebin.h | 3 ++ 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 840548f397..6ed8f910d8 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -45,7 +45,8 @@ enum PROP_MAX_SIZE_BUFFERS, PROP_MAX_SIZE_BYTES, PROP_MAX_SIZE_TIME, - PROP_DEINTERLACE_METHOD + PROP_DEINTERLACE_METHOD, + PROP_DISABLE_VPP }; #define GST_VAAPI_DECODE_BIN_SURFACE_CAPS \ @@ -100,6 +101,33 @@ GST_STATIC_PAD_TEMPLATE ("src", G_DEFINE_TYPE (GstVaapiDecodeBin, gst_vaapi_decode_bin, GST_TYPE_BIN); +/* Remove the vaapipostproc if already added and reset the ghost pad target */ +static void +disable_vpp (GstVaapiDecodeBin *vaapidecbin) +{ + GstPad *pad; + GstStateChangeReturn ret; + GstState state; + + /*Fixme: Add run-time disabling support */ + ret = gst_element_get_state (GST_ELEMENT (vaapidecbin), &state, NULL, GST_CLOCK_TIME_NONE); + if (ret != GST_STATE_CHANGE_SUCCESS || state > GST_STATE_NULL) { + GST_WARNING_OBJECT (vaapidecbin, "Failed to set disable-vpp property!,," + "No support for run-time disabling, Ignoring the user request to disable VPP."); + return; + } + + gst_element_set_state (vaapidecbin->postproc, GST_STATE_NULL); + gst_bin_remove (GST_BIN (vaapidecbin), vaapidecbin->postproc); + + pad = + gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->queue), + "src"); + gst_ghost_pad_set_target ((GstGhostPad *) vaapidecbin->ghost_pad_src, + pad); + gst_object_unref (pad); +} + static void gst_vaapi_decode_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -127,6 +155,12 @@ gst_vaapi_decode_bin_set_property (GObject * object, g_object_set (G_OBJECT (vaapidecbin->postproc), "deinterlace-method", vaapidecbin->deinterlace_method, NULL); break; + case PROP_DISABLE_VPP: + vaapidecbin->disable_vpp = g_value_get_boolean (value); + /* Remove the vaapipostpro */ + if (vaapidecbin->disable_vpp && vaapidecbin->postproc) + disable_vpp (vaapidecbin); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -152,6 +186,9 @@ gst_vaapi_decode_bin_get_property (GObject * object, case PROP_DEINTERLACE_METHOD: g_value_set_enum (value, vaapidecbin->deinterlace_method); break; + case PROP_DISABLE_VPP: + g_value_set_boolean (value, vaapidecbin->disable_vpp); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -196,6 +233,11 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) "Deinterlace method to use", GST_VAAPI_TYPE_DEINTERLACE_METHOD, DEFAULT_DEINTERLACE_METHOD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_DISABLE_VPP, + g_param_spec_boolean ("disable-vpp", + "Disable VPP", + "Disable Video Post Processing(No support for run time disabling)", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_vaapi_decode_bin_sink_factory)); @@ -225,32 +267,36 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) missing_factory = "queue"; goto error_element_missing; } - /* create the postproc */ - vaapidecbin->postproc = - gst_element_factory_make ("vaapipostproc", "vaapipostproc"); - if (!vaapidecbin->postproc) { - missing_factory = "vaapipostproc"; - goto error_element_missing; - } g_object_set (G_OBJECT (vaapidecbin->queue), "max-size-bytes", vaapidecbin->max_size_bytes, "max-size-buffers", vaapidecbin->max_size_buffers, "max-size-time", vaapidecbin->max_size_time, NULL); - g_object_set (G_OBJECT (vaapidecbin->postproc), - "deinterlace-method", vaapidecbin->deinterlace_method, NULL); - gst_bin_add_many (GST_BIN (vaapidecbin), - vaapidecbin->decoder, vaapidecbin->queue, vaapidecbin->postproc, NULL); + vaapidecbin->decoder, vaapidecbin->queue, NULL); if (!gst_element_link_pads_full (vaapidecbin->decoder, "src", vaapidecbin->queue, "sink", GST_PAD_LINK_CHECK_NOTHING)) goto error_link_pad; - if (!gst_element_link_pads_full (vaapidecbin->queue, "src", - vaapidecbin->postproc, "sink", GST_PAD_LINK_CHECK_NOTHING)) - goto error_link_pad; + if (!vaapidecbin->disable_vpp) { + /* create the postproc */ + vaapidecbin->postproc = + gst_element_factory_make ("vaapipostproc", "vaapipostproc"); + if (!vaapidecbin->postproc) { + missing_factory = "vaapipostproc"; + goto error_element_missing; + } + + g_object_set (G_OBJECT (vaapidecbin->postproc), + "deinterlace-method", vaapidecbin->deinterlace_method, NULL); + + gst_bin_add (GST_BIN (vaapidecbin), vaapidecbin->postproc); + if (!gst_element_link_pads_full (vaapidecbin->queue, "src", + vaapidecbin->postproc, "sink", GST_PAD_LINK_CHECK_NOTHING)) + goto error_link_pad; + } return TRUE; @@ -276,6 +322,7 @@ static void gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) { GstPad *element_pad, *ghost_pad; + GstElement *src_element; if (!gst_vaapi_decode_bin_configure (vaapidecbin)) return; @@ -290,11 +337,12 @@ gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghost_pad); /* create ghost pad src */ - element_pad = - gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->postproc), "src"); - ghost_pad = - gst_ghost_pad_new_from_template ("src", element_pad, - GST_PAD_PAD_TEMPLATE (element_pad)); + src_element = + vaapidecbin->disable_vpp ? vaapidecbin->queue : vaapidecbin->postproc; + element_pad = gst_element_get_static_pad (GST_ELEMENT (src_element), "src"); + + ghost_pad = gst_ghost_pad_new ("src", element_pad); + vaapidecbin->ghost_pad_src = ghost_pad; gst_object_unref (element_pad); gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghost_pad); } diff --git a/gst/vaapi/gstvaapidecodebin.h b/gst/vaapi/gstvaapidecodebin.h index 928683fc87..a5c8b876a9 100644 --- a/gst/vaapi/gstvaapidecodebin.h +++ b/gst/vaapi/gstvaapidecodebin.h @@ -47,11 +47,14 @@ typedef struct _GstVaapiDecodeBin { GstElement *queue; GstElement *postproc; + GstPad *ghost_pad_src; + /* properties */ guint max_size_buffers; guint max_size_bytes; guint64 max_size_time; GstVaapiDeinterlaceMethod deinterlace_method; + gboolean disable_vpp; } GstVaapiDecodeBin; From b4154ac85cbd9440ef71822e28dfa5385396d3f9 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 30 Jun 2015 09:44:18 +0300 Subject: [PATCH 2053/3781] gst/vaapi: Switch to upstreram like indentation. gst-indent for all gst/vaapi/*.c source files --- gst/vaapi/gstvaapi.c | 55 ++++++++++++----------------- gst/vaapi/gstvaapidecodebin.c | 15 ++++---- gst/vaapi/gstvaapiencode.c | 5 +-- gst/vaapi/gstvaapiencode_jpeg.c | 6 ++-- gst/vaapi/gstvaapipluginbase.c | 8 ++--- gst/vaapi/gstvaapipluginutil.c | 10 +++--- gst/vaapi/gstvaapipostproc.c | 12 +++---- gst/vaapi/gstvaapivideobufferpool.c | 1 - gst/vaapi/gstvaapivideocontext.c | 8 ++--- gst/vaapi/gstvaapivideomemory.c | 3 +- gst/vaapi/gstvaapivideometa.c | 4 +-- 11 files changed, 57 insertions(+), 70 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index e5bf227257..3ad0ec0f05 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -51,50 +51,41 @@ #define PLUGIN_LICENSE "LGPL" static gboolean -plugin_init (GstPlugin *plugin) +plugin_init (GstPlugin * plugin) { - gst_element_register(plugin, "vaapidecode", - GST_RANK_PRIMARY + 1, - GST_TYPE_VAAPIDECODE); - gst_element_register(plugin, "vaapipostproc", - GST_RANK_PRIMARY, - GST_TYPE_VAAPIPOSTPROC); - gst_element_register(plugin, "vaapisink", - GST_RANK_PRIMARY, - GST_TYPE_VAAPISINK); + gst_element_register (plugin, "vaapidecode", + GST_RANK_PRIMARY + 1, GST_TYPE_VAAPIDECODE); + gst_element_register (plugin, "vaapipostproc", + GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); + gst_element_register (plugin, "vaapisink", + GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); #if USE_ENCODERS - gst_element_register(plugin, "vaapiencode_h264", - GST_RANK_PRIMARY, - GST_TYPE_VAAPIENCODE_H264); - gst_element_register(plugin, "vaapiencode_mpeg2", - GST_RANK_PRIMARY, - GST_TYPE_VAAPIENCODE_MPEG2); + gst_element_register (plugin, "vaapiencode_h264", + GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_H264); + gst_element_register (plugin, "vaapiencode_mpeg2", + GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_MPEG2); #endif #if USE_JPEG_ENCODER - gst_element_register(plugin, "vaapiencode_jpeg", - GST_RANK_PRIMARY, - GST_TYPE_VAAPIENCODE_JPEG); + gst_element_register (plugin, "vaapiencode_jpeg", + GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_JPEG); #endif #if USE_VP8_ENCODER - gst_element_register(plugin, "vaapiencode_vp8", - GST_RANK_PRIMARY, - GST_TYPE_VAAPIENCODE_VP8); + gst_element_register (plugin, "vaapiencode_vp8", + GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_VP8); #endif #if USE_H265_ENCODER - gst_element_register(plugin, "vaapiencode_h265", - GST_RANK_PRIMARY, - GST_TYPE_VAAPIENCODE_H265); + gst_element_register (plugin, "vaapiencode_h265", + GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_H265); #endif #if GST_CHECK_VERSION(1,4,0) - gst_element_register(plugin, "vaapidecodebin", - GST_RANK_PRIMARY + 2, - GST_TYPE_VAAPI_DECODE_BIN); + gst_element_register (plugin, "vaapidecodebin", + GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); #endif - return TRUE; + return TRUE; } -GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, - vaapi, PLUGIN_DESC, plugin_init, - PACKAGE_VERSION, PLUGIN_LICENSE, PACKAGE, PACKAGE_BUGREPORT) +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, + vaapi, PLUGIN_DESC, plugin_init, + PACKAGE_VERSION, PLUGIN_LICENSE, PACKAGE, PACKAGE_BUGREPORT) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 6ed8f910d8..ad814e77ea 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -103,14 +103,16 @@ G_DEFINE_TYPE (GstVaapiDecodeBin, gst_vaapi_decode_bin, GST_TYPE_BIN); /* Remove the vaapipostproc if already added and reset the ghost pad target */ static void -disable_vpp (GstVaapiDecodeBin *vaapidecbin) +disable_vpp (GstVaapiDecodeBin * vaapidecbin) { GstPad *pad; GstStateChangeReturn ret; GstState state; /*Fixme: Add run-time disabling support */ - ret = gst_element_get_state (GST_ELEMENT (vaapidecbin), &state, NULL, GST_CLOCK_TIME_NONE); + ret = + gst_element_get_state (GST_ELEMENT (vaapidecbin), &state, NULL, + GST_CLOCK_TIME_NONE); if (ret != GST_STATE_CHANGE_SUCCESS || state > GST_STATE_NULL) { GST_WARNING_OBJECT (vaapidecbin, "Failed to set disable-vpp property!,," "No support for run-time disabling, Ignoring the user request to disable VPP."); @@ -120,14 +122,11 @@ disable_vpp (GstVaapiDecodeBin *vaapidecbin) gst_element_set_state (vaapidecbin->postproc, GST_STATE_NULL); gst_bin_remove (GST_BIN (vaapidecbin), vaapidecbin->postproc); - pad = - gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->queue), - "src"); - gst_ghost_pad_set_target ((GstGhostPad *) vaapidecbin->ghost_pad_src, - pad); + pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->queue), "src"); + gst_ghost_pad_set_target ((GstGhostPad *) vaapidecbin->ghost_pad_src, pad); gst_object_unref (pad); } - + static void gst_vaapi_decode_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 8e06433456..7306b758ba 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -585,8 +585,9 @@ gst_vaapiencode_change_state (GstElement * element, GstStateChange transition) default: break; } - return GST_ELEMENT_CLASS (gst_vaapiencode_parent_class)-> - change_state (element, transition); + return + GST_ELEMENT_CLASS (gst_vaapiencode_parent_class)->change_state (element, + transition); } static gboolean diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 78304f90e6..a5a93621b9 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -67,8 +67,7 @@ static GstStaticPadTemplate gst_vaapiencode_jpeg_src_factory = /* *INDENT-ON* */ /* jpeg encode */ -G_DEFINE_TYPE (GstVaapiEncodeJpeg, gst_vaapiencode_jpeg, - GST_TYPE_VAAPIENCODE); +G_DEFINE_TYPE (GstVaapiEncodeJpeg, gst_vaapiencode_jpeg, GST_TYPE_VAAPIENCODE); static void gst_vaapiencode_jpeg_init (GstVaapiEncodeJpeg * encode) @@ -150,7 +149,8 @@ gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass) gst_element_class_set_static_metadata (element_class, "VA-API JPEG encoder", "Codec/Encoder/Image", - GST_PLUGIN_DESC, "Sreerenj Balachandran "); + GST_PLUGIN_DESC, + "Sreerenj Balachandran "); /* sink pad */ gst_element_class_add_pad_template (element_class, diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 6624316bb0..5e922b3056 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -397,7 +397,7 @@ has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad) v = 0; g_object_get (element, "io-mode", &v, NULL); - is_dmabuf_capable = v == 5; /* "dmabuf-import" enum value */ + is_dmabuf_capable = v == 5; /* "dmabuf-import" enum value */ break; } else if (GST_IS_BASE_TRANSFORM (element)) { element_name = gst_element_get_name (element); @@ -895,15 +895,13 @@ done: error_no_pool: { GST_ELEMENT_ERROR (plugin, STREAM, FAILED, - ("no buffer pool was negotiated"), - ("no buffer pool was negotiated")); + ("no buffer pool was negotiated"), ("no buffer pool was negotiated")); return GST_FLOW_ERROR; } error_active_pool: { GST_ELEMENT_ERROR (plugin, STREAM, FAILED, - ("failed to activate buffer pool"), - ("failed to activate buffer pool")); + ("failed to activate buffer pool"), ("failed to activate buffer pool")); return GST_FLOW_ERROR; } error_map_dst_buffer: diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 64bc3ba2fb..ce9cbb0a99 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -445,8 +445,10 @@ gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, static GstCaps * new_gl_texture_upload_meta_caps (void) { - return gst_caps_from_string (GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }")); + return + gst_caps_from_string (GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, + "{ RGBA, BGRA }")); } GstVaapiCapsFeature @@ -462,14 +464,14 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, GstCaps *out_caps; GstVideoFormat out_format; - out_caps= gst_pad_get_allowed_caps (pad); + out_caps = gst_pad_get_allowed_caps (pad); if (!out_caps) { feature = GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED; goto cleanup; } out_format = format == GST_VIDEO_FORMAT_ENCODED ? - GST_VIDEO_FORMAT_I420 : format; + GST_VIDEO_FORMAT_I420 : format; gl_texture_upload_caps = new_gl_texture_upload_meta_caps (); if (!gl_texture_upload_caps) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 74743c128d..427d8ad772 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -326,9 +326,9 @@ gst_vaapipostproc_stop (GstBaseTransform * trans) gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (postproc)); postproc->field_duration = GST_CLOCK_TIME_NONE; - gst_video_info_init(&postproc->sinkpad_info); - gst_video_info_init(&postproc->srcpad_info); - gst_video_info_init(&postproc->filter_pool_info); + gst_video_info_init (&postproc->sinkpad_info); + gst_video_info_init (&postproc->srcpad_info); + gst_video_info_init (&postproc->filter_pool_info); return TRUE; } @@ -536,7 +536,7 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SKINTONE) && !gst_vaapi_filter_set_skintone (postproc->filter, - postproc->skintone_enhance)) + postproc->skintone_enhance)) return GST_FLOW_NOT_SUPPORTED; inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); @@ -1082,7 +1082,6 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, GST_VIDEO_INFO_FPS_N (&vi) = fps_n; GST_VIDEO_INFO_FPS_D (&vi) = fps_d; } - // Signal the other pad that we only generate progressive frames GST_VIDEO_INFO_INTERLACE_MODE (&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; @@ -1206,8 +1205,7 @@ done: static GstFlowReturn gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, - GstBuffer * inbuf, - GstBuffer ** outbuf_ptr) + GstBuffer * inbuf, GstBuffer ** outbuf_ptr) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index e79158f555..8e45bbc4c0 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -287,7 +287,6 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, vmeta->unmap = gst_video_meta_unmap_vaapi_memory; } } - #if (USE_GLX || USE_EGL) if (priv->has_texture_upload_meta) gst_buffer_add_texture_upload_meta (buffer); diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index fa482421ae..1d3dcbaa53 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -32,15 +32,15 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); gst_vaapi_display_get_type () GType -gst_vaapi_display_get_type (void) G_GNUC_CONST; +gst_vaapi_display_get_type (void) + G_GNUC_CONST; G_DEFINE_BOXED_TYPE (GstVaapiDisplay, gst_vaapi_display, (GBoxedCopyFunc) gst_vaapi_display_ref, (GBoxedFreeFunc) gst_vaapi_display_unref); -GstContext * -gst_vaapi_video_context_new_with_display (GstVaapiDisplay * display, - gboolean persistent) + GstContext *gst_vaapi_video_context_new_with_display (GstVaapiDisplay * + display, gboolean persistent) { GstContext *context; GstStructure *structure; diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 409cdd48c7..fcd225fb8b 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -42,8 +42,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapivideomemory); /* --- GstVaapiVideoMemory --- */ /* ------------------------------------------------------------------------ */ -static void -gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem); +static void gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem); static guchar * get_image_data (GstVaapiImage * image) diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index aef333e440..caafcbeae0 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -531,8 +531,8 @@ gst_vaapi_video_meta_get_surface (GstVaapiVideoMeta * meta) { g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); - return ensure_surface_proxy (meta) ? GST_VAAPI_SURFACE_PROXY_SURFACE (meta-> - proxy) : NULL; + return ensure_surface_proxy (meta) ? + GST_VAAPI_SURFACE_PROXY_SURFACE (meta->proxy) : NULL; } /** From cd662096760ba36312afcb0e95864aa0ca6eb41d Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 2 Jul 2015 10:25:25 +0300 Subject: [PATCH 2054/3781] libs: Bump library major version --- configure.ac | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 0e094918fc..47a360ff84 100644 --- a/configure.ac +++ b/configure.ac @@ -13,9 +13,7 @@ m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) m4_define([default_glapi], [any]) # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [6]) -m4_define([gst0_vaapi_lt_current_bias], [0]) -m4_define([gst1_vaapi_lt_current_bias], [2]) +m4_define([gst_vaapi_lt_current], [7]) m4_define([gst2_vaapi_lt_current_bias], [4]) m4_define([gst4_vaapi_lt_current_bias], [5]) m4_define([gst6_vaapi_lt_current_bias], [6]) @@ -439,9 +437,8 @@ if test "$enable_egl" = "yes" -a $HAVE_GSTGL -ne 1; then fi case $GST_API_VERSION in -1.0) lt_bias=gst1_vaapi_lt_current_bias;; 1.2) lt_bias=gst2_vaapi_lt_current_bias;; -1.4) lt_bias=gst4_vaapi_lt_current_bias;; +1.4) lt_bias=gst4_vaapi_lt_current_bias;; 1.[[5-6]]) lt_bias=gst6_vaapi_lt_current_bias;; esac GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - "$lt_bias"` From f728b9d67ce1a6864ccf10b65bb4f703d9bbfc7c Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 2 Jul 2015 10:45:50 +0300 Subject: [PATCH 2055/3781] configure: fix the build while enabling egl as the only renderer --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 47a360ff84..1f59a17422 100644 --- a/configure.ac +++ b/configure.ac @@ -951,7 +951,7 @@ dnl --------------------------------------------------------------------------- dnl -- Generate files and summary -- dnl --------------------------------------------------------------------------- -case ":$USE_X11:$USE_GLX:$USE_WAYLAND:$USE_DRM:" in +case ":$USE_X11:$USE_GLX:$USE_EGL:$USE_WAYLAND:$USE_DRM:" in *:1:*) ;; *) From 157ce777277e053a4beaca09d2e0ddc7a46801a2 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 2 Jul 2015 12:29:32 +0300 Subject: [PATCH 2056/3781] tests: Fix compilation while enabling egl as the only renderer in build Include missing header files gstvaapidisplay_egl.h and gstvaapiwindow_egl.h. --- tests/test-display.c | 3 +++ tests/test-windows.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/tests/test-display.c b/tests/test-display.c index 22f5859a47..2ab97dc961 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -42,6 +42,9 @@ #if USE_WAYLAND # include #endif +#if USE_EGL +# include +#endif #ifdef HAVE_VA_VA_GLX_H # include diff --git a/tests/test-windows.c b/tests/test-windows.c index c050cd2421..e90f4c0e72 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -37,6 +37,10 @@ # include # include #endif +#if USE_EGL +# include +# include +#endif #include "image.h" static inline void From 5c799b35f71ce70aa7e493c1471920355a30deef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 1 Jul 2015 14:17:17 +0200 Subject: [PATCH 2057/3781] vaapidecodebin: enable vpp if it is available Instead of creating and adding VPP into the bin at setup, we wait until we are sure the VA driver supports it. We know that when the VA video context is received by the bin. Afterwards, it is decided to instanciate and link the VPP or not. This is more efficient and safer than waiting the VPP to fail and then disable it. https://bugzilla.gnome.org/show_bug.cgi?id=749554 --- gst/vaapi/gstvaapidecodebin.c | 180 +++++++++++++++++++++++----------- gst/vaapi/gstvaapidecodebin.h | 1 + 2 files changed, 123 insertions(+), 58 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index ad814e77ea..f147f1c5a5 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -27,6 +27,7 @@ #include #include "gstvaapipluginutil.h" #include "gstvaapidecodebin.h" +#include "gstvaapivideocontext.h" #define GST_PLUGIN_NAME "vaapidecodebin" #define GST_PLUGIN_DESC "A Bin of VA-API elements: vaapidecode ! queue ! vaapipostproc" @@ -101,30 +102,73 @@ GST_STATIC_PAD_TEMPLATE ("src", G_DEFINE_TYPE (GstVaapiDecodeBin, gst_vaapi_decode_bin, GST_TYPE_BIN); -/* Remove the vaapipostproc if already added and reset the ghost pad target */ static void -disable_vpp (GstVaapiDecodeBin * vaapidecbin) +post_missing_element_message (GstVaapiDecodeBin * vaapidecbin, + const gchar * missing_factory) { - GstPad *pad; - GstStateChangeReturn ret; - GstState state; + GstMessage *msg; - /*Fixme: Add run-time disabling support */ - ret = - gst_element_get_state (GST_ELEMENT (vaapidecbin), &state, NULL, - GST_CLOCK_TIME_NONE); - if (ret != GST_STATE_CHANGE_SUCCESS || state > GST_STATE_NULL) { - GST_WARNING_OBJECT (vaapidecbin, "Failed to set disable-vpp property!,," - "No support for run-time disabling, Ignoring the user request to disable VPP."); - return; + GST_ERROR_OBJECT (vaapidecbin, "Failed to create %s element", + missing_factory); + msg = + gst_missing_element_message_new (GST_ELEMENT_CAST (vaapidecbin), + missing_factory); + gst_element_post_message (GST_ELEMENT_CAST (vaapidecbin), msg); +} + +static gboolean +activate_vpp (GstVaapiDecodeBin * vaapidecbin) +{ + GstElement *src; + + if (vaapidecbin->ghost_pad_src || vaapidecbin->postproc) + return TRUE; + + if (!vaapidecbin->has_vpp || vaapidecbin->disable_vpp) { + src = vaapidecbin->queue; + goto connect_src_ghost_pad; } - gst_element_set_state (vaapidecbin->postproc, GST_STATE_NULL); - gst_bin_remove (GST_BIN (vaapidecbin), vaapidecbin->postproc); + /* create the postproc */ + vaapidecbin->postproc = + gst_element_factory_make ("vaapipostproc", "vaapipostproc"); + if (!vaapidecbin->postproc) + goto error_element_missing; - pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->queue), "src"); - gst_ghost_pad_set_target ((GstGhostPad *) vaapidecbin->ghost_pad_src, pad); - gst_object_unref (pad); + g_object_set (G_OBJECT (vaapidecbin->postproc), "deinterlace-method", + vaapidecbin->deinterlace_method, NULL); + + gst_bin_add (GST_BIN (vaapidecbin), vaapidecbin->postproc); + if (!gst_element_link_pads_full (vaapidecbin->queue, "src", + vaapidecbin->postproc, "sink", GST_PAD_LINK_CHECK_NOTHING)) + goto error_link_pad; + + GST_DEBUG_OBJECT (vaapidecbin, "Enabling VPP"); + src = vaapidecbin->postproc; + + goto connect_src_ghost_pad; + +error_element_missing: + { + post_missing_element_message (vaapidecbin, "vaapipostproc"); + return FALSE; + } +error_link_pad: + { + GST_ERROR_OBJECT (vaapidecbin, "Failed to link the child elements"); + return FALSE; + } +connect_src_ghost_pad: + { + GstPad *srcpad, *ghostpad; + + srcpad = gst_element_get_static_pad (src, "src"); + ghostpad = gst_ghost_pad_new ("src", srcpad); + vaapidecbin->ghost_pad_src = ghostpad; + gst_object_unref (srcpad); + gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad); + return TRUE; + } } static void @@ -155,11 +199,19 @@ gst_vaapi_decode_bin_set_property (GObject * object, vaapidecbin->deinterlace_method, NULL); break; case PROP_DISABLE_VPP: - vaapidecbin->disable_vpp = g_value_get_boolean (value); - /* Remove the vaapipostpro */ - if (vaapidecbin->disable_vpp && vaapidecbin->postproc) - disable_vpp (vaapidecbin); + { + gboolean disable_vpp; + + disable_vpp = g_value_get_boolean (value); + if (!disable_vpp && !vaapidecbin->has_vpp) + GST_WARNING_OBJECT (vaapidecbin, + "Cannot enable VPP since the VA driver does not support it"); + else + vaapidecbin->disable_vpp = disable_vpp; + + /* @TODO: Add run-time disabling support */ break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -194,18 +246,62 @@ gst_vaapi_decode_bin_get_property (GObject * object, } } +static void +gst_vaapi_decode_bin_handle_message (GstBin * bin, GstMessage * message) +{ + GstVaapiDecodeBin *vaapidecbin = GST_VAAPI_DECODE_BIN (bin); + GstMessageType type; + GstContext *context = NULL; + const gchar *context_type; + GstVaapiDisplay *display = NULL; + + type = GST_MESSAGE_TYPE (message); + if (type != GST_MESSAGE_HAVE_CONTEXT) + goto bail; + gst_message_parse_have_context (message, &context); + if (!context) + goto bail; + context_type = gst_context_get_context_type (context); + if (g_strcmp0 (context_type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) != 0) + goto bail; + if (!gst_vaapi_video_context_get_display (context, &display)) + goto bail; + + vaapidecbin->has_vpp = gst_vaapi_display_has_video_processing (display); + + /* the underlying VA driver implementation doesn't support video + * post-processing, hence we have to disable it */ + if (!vaapidecbin->has_vpp) { + GST_WARNING_OBJECT (vaapidecbin, "VA driver doesn't support VPP"); + if (!vaapidecbin->disable_vpp) { + vaapidecbin->disable_vpp = TRUE; + } + } + + activate_vpp (vaapidecbin); + +bail: + GST_BIN_CLASS (gst_vaapi_decode_bin_parent_class)->handle_message (bin, + message); +} + static void gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) { GObjectClass *gobject_class; GstElementClass *element_class; + GstBinClass *bin_class; gobject_class = G_OBJECT_CLASS (klass); element_class = GST_ELEMENT_CLASS (klass); + bin_class = GST_BIN_CLASS (klass); gobject_class->set_property = gst_vaapi_decode_bin_set_property; gobject_class->get_property = gst_vaapi_decode_bin_get_property; + bin_class->handle_message = + GST_DEBUG_FUNCPTR (gst_vaapi_decode_bin_handle_message); + gst_element_class_set_static_metadata (element_class, "VA-API Decode Bin", "Codec/Decoder/Video", @@ -279,35 +375,11 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) vaapidecbin->queue, "sink", GST_PAD_LINK_CHECK_NOTHING)) goto error_link_pad; - if (!vaapidecbin->disable_vpp) { - /* create the postproc */ - vaapidecbin->postproc = - gst_element_factory_make ("vaapipostproc", "vaapipostproc"); - if (!vaapidecbin->postproc) { - missing_factory = "vaapipostproc"; - goto error_element_missing; - } - - g_object_set (G_OBJECT (vaapidecbin->postproc), - "deinterlace-method", vaapidecbin->deinterlace_method, NULL); - - gst_bin_add (GST_BIN (vaapidecbin), vaapidecbin->postproc); - if (!gst_element_link_pads_full (vaapidecbin->queue, "src", - vaapidecbin->postproc, "sink", GST_PAD_LINK_CHECK_NOTHING)) - goto error_link_pad; - } - return TRUE; error_element_missing: { - GstMessage *msg; - GST_ERROR_OBJECT (vaapidecbin, "Failed to create %s element", - missing_factory); - msg = - gst_missing_element_message_new (GST_ELEMENT_CAST (vaapidecbin), - missing_factory); - gst_element_post_message (GST_ELEMENT_CAST (vaapidecbin), msg); + post_missing_element_message (vaapidecbin, missing_factory); return FALSE; } error_link_pad: @@ -321,7 +393,9 @@ static void gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) { GstPad *element_pad, *ghost_pad; - GstElement *src_element; + + /* let's assume we have VPP until we prove the opposite */ + vaapidecbin->has_vpp = TRUE; if (!gst_vaapi_decode_bin_configure (vaapidecbin)) return; @@ -334,14 +408,4 @@ gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) GST_PAD_PAD_TEMPLATE (element_pad)); gst_object_unref (element_pad); gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghost_pad); - - /* create ghost pad src */ - src_element = - vaapidecbin->disable_vpp ? vaapidecbin->queue : vaapidecbin->postproc; - element_pad = gst_element_get_static_pad (GST_ELEMENT (src_element), "src"); - - ghost_pad = gst_ghost_pad_new ("src", element_pad); - vaapidecbin->ghost_pad_src = ghost_pad; - gst_object_unref (element_pad); - gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghost_pad); } diff --git a/gst/vaapi/gstvaapidecodebin.h b/gst/vaapi/gstvaapidecodebin.h index a5c8b876a9..0f3fb6cdcb 100644 --- a/gst/vaapi/gstvaapidecodebin.h +++ b/gst/vaapi/gstvaapidecodebin.h @@ -55,6 +55,7 @@ typedef struct _GstVaapiDecodeBin { guint64 max_size_time; GstVaapiDeinterlaceMethod deinterlace_method; gboolean disable_vpp; + gboolean has_vpp; } GstVaapiDecodeBin; From b4d9c0a79a16f7e772b3faca5bc4bec9b0e947a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 1 Jul 2015 14:16:50 +0200 Subject: [PATCH 2058/3781] vaapidecodebin: notify if vpp is disabled When the system is aware that VPP is not available by the VA driver, it would be useful to notify to the user that the disable-vpp property has changed. https://bugzilla.gnome.org/show_bug.cgi?id=749554 --- gst/vaapi/gstvaapidecodebin.c | 54 ++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index f147f1c5a5..cbedbb227f 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -47,9 +47,12 @@ enum PROP_MAX_SIZE_BYTES, PROP_MAX_SIZE_TIME, PROP_DEINTERLACE_METHOD, - PROP_DISABLE_VPP + PROP_DISABLE_VPP, + PROP_LAST }; +static GParamSpec *properties[PROP_LAST]; + #define GST_VAAPI_DECODE_BIN_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") @@ -275,6 +278,8 @@ gst_vaapi_decode_bin_handle_message (GstBin * bin, GstMessage * message) GST_WARNING_OBJECT (vaapidecbin, "VA driver doesn't support VPP"); if (!vaapidecbin->disable_vpp) { vaapidecbin->disable_vpp = TRUE; + g_object_notify_by_pspec (G_OBJECT (vaapidecbin), + properties[PROP_DISABLE_VPP]); } } @@ -308,31 +313,28 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) GST_PLUGIN_DESC, "Sreerenj Balachandran "); - g_object_class_install_property (gobject_class, PROP_MAX_SIZE_BYTES, - g_param_spec_uint ("max-size-bytes", "Max. size (kB)", - "Max. amount of data in the queue (bytes, 0=disable)", - 0, G_MAXUINT, DEFAULT_QUEUE_MAX_SIZE_BYTES, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_MAX_SIZE_BUFFERS, - g_param_spec_uint ("max-size-buffers", "Max. size (buffers)", - "Max. number of buffers in the queue (0=disable)", 0, G_MAXUINT, - DEFAULT_QUEUE_MAX_SIZE_BUFFERS, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_MAX_SIZE_TIME, - g_param_spec_uint64 ("max-size-time", "Max. size (ns)", - "Max. amount of data in the queue (in ns, 0=disable)", 0, G_MAXUINT64, - DEFAULT_QUEUE_MAX_SIZE_TIME, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_DEINTERLACE_METHOD, - g_param_spec_enum ("deinterlace-method", "Deinterlace method", - "Deinterlace method to use", GST_VAAPI_TYPE_DEINTERLACE_METHOD, - DEFAULT_DEINTERLACE_METHOD, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_DISABLE_VPP, - g_param_spec_boolean ("disable-vpp", - "Disable VPP", - "Disable Video Post Processing(No support for run time disabling)", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + properties[PROP_MAX_SIZE_BYTES] = g_param_spec_uint ("max-size-bytes", + "Max. size (kB)", "Max. amount of data in the queue (bytes, 0=disable)", + 0, G_MAXUINT, DEFAULT_QUEUE_MAX_SIZE_BYTES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + properties[PROP_MAX_SIZE_BUFFERS] = g_param_spec_uint ("max-size-buffers", + "Max. size (buffers)", "Max. number of buffers in the queue (0=disable)", + 0, G_MAXUINT, DEFAULT_QUEUE_MAX_SIZE_BUFFERS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + properties[PROP_MAX_SIZE_TIME] = g_param_spec_uint64 ("max-size-time", + "Max. size (ns)", "Max. amount of data in the queue (in ns, 0=disable)", + 0, G_MAXUINT64, DEFAULT_QUEUE_MAX_SIZE_TIME, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + properties[PROP_DEINTERLACE_METHOD] = g_param_spec_enum ("deinterlace-method", + "Deinterlace method", "Deinterlace method to use", + GST_VAAPI_TYPE_DEINTERLACE_METHOD, DEFAULT_DEINTERLACE_METHOD, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + properties[PROP_DISABLE_VPP] = g_param_spec_boolean ("disable-vpp", + "Disable VPP", + "Disable Video Post Processing (No support for run time disabling)", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, PROP_LAST, properties); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_vaapi_decode_bin_sink_factory)); From a2604261946e0716dd2708686454d3ad6262f938 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 2 Jul 2015 21:00:14 +0300 Subject: [PATCH 2059/3781] encoder: h264: submit SEI buffering_period() and picture_timing() messages for CBR mode One buffering_period() SEI message shall be present in every IDR access unit when NalHrdBpPresentFlag is inferred to be equal to 1. This is the case when we use a non-CQP mode, e.g. CBR. In other words, when nal_hrd_parameters_present_flag is set to 1. One picture_timing() SEI messages shall be present in every access unit if CpbDpbDelaysPresentFlag is equal to 1 or pic_struct_present_flag is equal to 1 https://bugzilla.gnome.org/show_bug.cgi?id=722734 https://bugzilla.gnome.org/show_bug.cgi?id=751831 Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 223 +++++++++++++++++++++- 1 file changed, 220 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 1287e81369..14ab73764b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -81,13 +81,22 @@ (VA_ENC_PACKED_HEADER_SEQUENCE | \ VA_ENC_PACKED_HEADER_PICTURE | \ VA_ENC_PACKED_HEADER_SLICE | \ - VA_ENC_PACKED_HEADER_RAW_DATA) + VA_ENC_PACKED_HEADER_RAW_DATA | \ + VA_ENC_PACKED_HEADER_MISC) #define GST_H264_NAL_REF_IDC_NONE 0 #define GST_H264_NAL_REF_IDC_LOW 1 #define GST_H264_NAL_REF_IDC_MEDIUM 2 #define GST_H264_NAL_REF_IDC_HIGH 3 +/* only for internal usage, values won't be equal to actual payload type */ +typedef enum +{ + GST_VAAPI_H264_SEI_UNKNOWN = 0, + GST_VAAPI_H264_SEI_BUF_PERIOD = (1 << 0), + GST_VAAPI_H264_SEI_PIC_TIMING = (1 << 1) +} GstVaapiH264SeiPayloadType; + typedef struct { GstVaapiSurfaceProxy *pic; @@ -115,6 +124,7 @@ typedef struct _GstVaapiH264ViewReorderPool GQueue reorder_frame_list; guint reorder_state; guint frame_index; + guint frame_count; /* monotonically increasing with in every idr period */ guint cur_frame_num; guint cur_present_index; } GstVaapiH264ViewReorderPool; @@ -491,7 +501,6 @@ bs_write_sps_data (GstBitWriter * bs, /* nal_hrd_parameters_present_flag */ nal_hrd_parameters_present_flag = seq_param->bits_per_second > 0; - nal_hrd_parameters_present_flag = FALSE; /* XXX: disabled for now */ WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1); if (nal_hrd_parameters_present_flag) { /* hrd_parameters */ @@ -527,7 +536,7 @@ bs_write_sps_data (GstBitWriter * bs, WRITE_UINT32 (bs, 0, 1); } /* pic_struct_present_flag */ - WRITE_UINT32 (bs, 0, 1); + WRITE_UINT32 (bs, 1, 1); /* bs_restriction_flag */ WRITE_UINT32 (bs, 0, 1); } @@ -775,6 +784,95 @@ struct _GstVaapiEncoderH264 GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS]; }; +/* Write a SEI buffering period payload */ +static gboolean +bs_write_sei_buf_period (GstBitWriter * bs, + GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) +{ + guint initial_cpb_removal_delay = 0; + guint initial_cpb_removal_delay_offset = 0; + guint8 initial_cpb_removal_delay_length = 24; + + /* sequence_parameter_set_id */ + WRITE_UE (bs, encoder->view_idx); + /* NalHrdBpPresentFlag == TRUE */ + /* cpb_cnt_minus1 == 0 */ + + /* decoding should start when the CPB fullness reaches half of cpb size + * initial_cpb_remvoal_delay = (((cpb_length / 2) * 90000) / 1000) */ + initial_cpb_removal_delay = encoder->cpb_length * 45; + + /* initial_cpb_remvoal_dealy */ + WRITE_UINT32 (bs, initial_cpb_removal_delay, initial_cpb_removal_delay_length); + + /* initial_cpb_removal_delay_offset */ + WRITE_UINT32 (bs, initial_cpb_removal_delay_offset, + initial_cpb_removal_delay_length); + + /* VclHrdBpPresentFlag == FALSE */ + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Buffering Period SEI message"); + return FALSE; + } +} + +/* Write a SEI picture timing payload */ +static gboolean +bs_write_sei_pic_timing (GstBitWriter * bs, + GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiH264ViewReorderPool *reorder_pool = NULL; + guint cpb_removal_delay; + guint dpb_output_delay; + guint8 cpb_removal_delay_length = 24; + guint8 dpb_output_delay_length = 24; + guint pic_struct = 0; + guint clock_timestamp_flag = 0; + + reorder_pool = &encoder->reorder_pools[encoder->view_idx]; + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + reorder_pool->frame_count = 0; + else + reorder_pool->frame_count++; + + /* clock-tick = no_units_in_tick/time_scale (C-1) + * time_scale = FPS_N * 2 (E.2.1) + * num_units_in_tick = FPS_D (E.2.1) + * frame_duration = clock-tick * 2 + * so removal time for one frame is 2 clock-ticks. + * but adding a tolerance of one frame duration, + * which is 2 more clock-ticks */ + cpb_removal_delay = (reorder_pool->frame_count * 2 + 2); + + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) + dpb_output_delay = 0; + else + dpb_output_delay = picture->poc - reorder_pool->frame_count * 2; + + /* CpbDpbDelaysPresentFlag == 1 */ + WRITE_UINT32 (bs, cpb_removal_delay, cpb_removal_delay_length); + WRITE_UINT32 (bs, dpb_output_delay, dpb_output_delay_length); + + /* pic_struct_present_flag == 1 */ + /* pic_struct */ + WRITE_UINT32 (bs, pic_struct, 4); + /* clock_timestamp_flag */ + WRITE_UINT32 (bs, clock_timestamp_flag, 1); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Picture Timing SEI message"); + return FALSE; + } +} + /* Write a Slice NAL unit */ static gboolean bs_write_slice (GstBitWriter * bs, @@ -1401,6 +1499,102 @@ bs_error: } } +static gboolean +add_packed_sei_header (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, + GstVaapiH264SeiPayloadType payloadtype) +{ + GstVaapiEncPackedHeader *packed_sei; + GstBitWriter bs, bs_buf_period, bs_pic_timing; + VAEncPackedHeaderParameterBuffer packed_sei_param = { 0 }; + guint32 data_bit_size; + guint8 buf_period_payload_size = 0, pic_timing_payload_size = 0; + guint8 *data, *buf_period_payload, *pic_timing_payload; + gboolean need_buf_period, need_pic_timing; + + gst_bit_writer_init (&bs_buf_period, 128 * 8); + gst_bit_writer_init (&bs_pic_timing, 128 * 8); + gst_bit_writer_init (&bs, 128 * 8); + + need_buf_period = GST_VAAPI_H264_SEI_BUF_PERIOD & payloadtype; + need_pic_timing = GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype; + + if (need_buf_period) { + /* Write a Buffering Period SEI message */ + bs_write_sei_buf_period (&bs_buf_period, encoder, picture); + /* Write byte alignment bits */ + if (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period) % 8 != 0) + bs_write_trailing_bits(&bs_buf_period); + buf_period_payload_size = + (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period)) / 8; + buf_period_payload = GST_BIT_WRITER_DATA (&bs_buf_period); + } + + if (need_pic_timing) { + /* Write a Picture Timing SEI message */ + if (GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype) + bs_write_sei_pic_timing (&bs_pic_timing, encoder, picture); + /* Write byte alignment bits */ + if (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing) % 8 != 0) + bs_write_trailing_bits(&bs_pic_timing); + pic_timing_payload_size = + (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing)) / 8; + pic_timing_payload = GST_BIT_WRITER_DATA (&bs_pic_timing); + } + + /* Write the SEI message */ + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_NONE, GST_H264_NAL_SEI); + + if (need_buf_period) { + WRITE_UINT32 (&bs, GST_H264_SEI_BUF_PERIOD, 8); + WRITE_UINT32 (&bs, buf_period_payload_size, 8); + /* Add buffering period sei message */ + gst_bit_writer_put_bytes (&bs, buf_period_payload, buf_period_payload_size); + } + + if (need_pic_timing) { + WRITE_UINT32 (&bs, GST_H264_SEI_PIC_TIMING, 8); + WRITE_UINT32 (&bs, pic_timing_payload_size, 8); + /* Add picture timing sei message */ + gst_bit_writer_put_bytes (&bs, pic_timing_payload, pic_timing_payload_size); + } + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (&bs); + + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_sei_param.type = VAEncPackedHeaderH264_SEI; + packed_sei_param.bit_length = data_bit_size; + packed_sei_param.has_emulation_bytes = 0; + + packed_sei = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_sei_param, sizeof (packed_sei_param), + data, (data_bit_size + 7) / 8); + g_assert (packed_sei); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_sei); + gst_vaapi_codec_object_replace (&packed_sei, NULL); + + gst_bit_writer_clear (&bs_buf_period, TRUE); + gst_bit_writer_clear (&bs_pic_timing, TRUE); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SEI NAL unit"); + gst_bit_writer_clear (&bs_buf_period, TRUE); + gst_bit_writer_clear (&bs_pic_timing, TRUE); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + static gboolean get_nal_hdr_attributes (GstVaapiEncPicture * picture, guint8 * nal_ref_idc, guint8 * nal_unit_type) @@ -2035,8 +2229,31 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) rate_control->basic_unit_size = 0; gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); + + if (!encoder->view_idx) { + if ((GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) && + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_MISC) && + !add_packed_sei_header (encoder, picture, + GST_VAAPI_H264_SEI_BUF_PERIOD | GST_VAAPI_H264_SEI_PIC_TIMING)) + goto error_create_packed_sei_hdr; + + else if (!GST_VAAPI_ENC_PICTURE_IS_IDR (picture) && + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_MISC) && + !add_packed_sei_header (encoder, picture, + GST_VAAPI_H264_SEI_PIC_TIMING)) + goto error_create_packed_sei_hdr; + } + } return TRUE; + +error_create_packed_sei_hdr: + { + GST_ERROR ("failed to create packed SEI header"); + return FALSE; + } } /* Generates and submits PPS header accordingly into the bitstream */ From 02d8092da9f3f0bdccfd77f4776862798ba04315 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 2 Jul 2015 21:37:56 +0300 Subject: [PATCH 2060/3781] encoder:h264: Fix the check for packed-header support Use VA_ENC_PACKED_HEADER_* definition for checking. Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 14ab73764b..36edd9dd30 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2163,11 +2163,11 @@ ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) /* add subset sps for non-base view and sps for base view */ if (encoder->is_mvc && encoder->view_idx) { - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS) + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_SEQUENCE) && !add_packed_sequence_header_mvc (encoder, picture, sequence)) goto error_create_packed_seq_hdr; } else { - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS) + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_SEQUENCE) && !add_packed_sequence_header (encoder, picture, sequence)) goto error_create_packed_seq_hdr; } @@ -2271,7 +2271,7 @@ ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, return FALSE; if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_PPS) + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_PICTURE) && !add_packed_picture_header (encoder, picture)) { GST_ERROR ("set picture packed header failed"); return FALSE; From 6b8877762789af1dedfe7bd22e1fc80f7501df73 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 2 Jul 2015 21:57:38 +0300 Subject: [PATCH 2061/3781] encoder:h265: Fix the check for packed-header support Use VA_ENC_PACKED_HEADER_* definition for checking. Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index a9c09a7604..6d10bf67fb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1687,7 +1687,7 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, slice_param->slice_fields.bits.last_slice_of_pic_flag = 1; if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & - VAEncPackedHeaderHEVC_Slice) + VA_ENC_PACKED_HEADER_SLICE) && !add_packed_slice_header (encoder, picture, slice)) goto error_create_packed_slice_hdr; @@ -1725,7 +1725,7 @@ ensure_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) goto error_create_seq_param; /* add packed vps and sps headers */ - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderHEVC_SPS) + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_SEQUENCE) && !(add_packed_vps_header (encoder, picture, sequence) && add_packed_sequence_header (encoder, picture, sequence))) { goto error_create_packed_seq_hdr; @@ -1769,7 +1769,7 @@ ensure_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, return FALSE; if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderHEVC_PPS) + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_PICTURE) && !add_packed_picture_header (encoder, picture)) { GST_ERROR ("set picture packed header failed"); return FALSE; From eb465fb392434d839d9bdfaac810aa8fa7a561bf Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 3 Jul 2015 12:42:09 +0300 Subject: [PATCH 2062/3781] gstvaapifilter: Add guard for VAProcFilterSkinToneEnhancement VAProcFilterSkinToneEnhancement is avaialbe from VA >= 0.36. Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapifilter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 3ca4b4b094..636e6717fd 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -458,10 +458,12 @@ op_data_new (GstVaapiFilterOp op, GParamSpec * pspec) op_data->va_cap_size = sizeof (VAProcFilterCap); op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer); break; +#if VA_CHECK_VERSION(0,36,0) case GST_VAAPI_FILTER_OP_SKINTONE: op_data->va_type = VAProcFilterSkinToneEnhancement; op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer); break; +#endif case GST_VAAPI_FILTER_OP_HUE: op_data->va_subtype = VAProcColorBalanceHue; goto op_colorbalance; From 9984678398de39f73dba3d866f49c2611190a5de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 2 Jul 2015 17:49:25 +0200 Subject: [PATCH 2063/3781] vaapipostproc: no format convert on GL tex upload meta When GL texture upload meta is negotiated, vaapipostproc shall not modify the color format of the buffer. https://bugzilla.gnome.org/show_bug.cgi?id=748184 --- gst/vaapi/gstvaapipostproc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 427d8ad772..d80d091291 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1109,7 +1109,6 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, peer_caps = gst_caps_fixate (peer_caps); gst_video_info_from_caps (&peer_vi, peer_caps); out_format = GST_VIDEO_INFO_FORMAT (&peer_vi); - postproc->format = out_format; if (peer_caps) gst_caps_unref (peer_caps); } @@ -1129,6 +1128,13 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, gst_caps_set_features (out_caps, 0, gst_caps_features_new (feature_str, NULL)); } + + /* we don't need to do format conversion if GL_TEXTURE_UPLOAD_META + * is negotiated */ + if (feature != GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META && + postproc->format != out_format) { + postproc->format = out_format; + } return out_caps; } From 9f0e054d9d3e1e7380a9c09c978bc325b0ddd86c Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 3 Jul 2015 15:07:02 +0300 Subject: [PATCH 2064/3781] gstvaapifilter: Only register STE property if it supported by corresponding VA library Fix the regression introduced in commit eb465fb. VAProcFilterSkinToneEnhancement is avaialbe from VA >= 0.36. Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapifilter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 636e6717fd..343e2c7ef3 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -401,6 +401,7 @@ init_properties (void) GST_VAAPI_TYPE_SCALE_METHOD, DEFAULT_SCALING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); +#if VA_CHECK_VERSION(0,36,0) /** * GstVaapiFilter:skin-tone-enhancement: * @@ -410,6 +411,7 @@ init_properties (void) "Skin tone enhancement", "Apply the skin tone enhancement algorithm", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); +#endif } static void From 86c4cdc8b60aaf7be465d3d5c02c9379eea413b2 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 7 Jul 2015 13:32:18 +0300 Subject: [PATCH 2065/3781] build: Add missing CFLAGS to Makefile.am --- gst-libs/gst/vaapi/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 1c65a7b13d..c6f845c2fe 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -496,6 +496,7 @@ libgstvaapi_egl_@GST_API_VERSION@_la_CFLAGS = \ $(GLIB_CFLAGS) \ $(GST_BASE_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ + $(LIBVA_CFLAGS) \ $(EGL_CFLAGS) \ $(NULL) From 3ccb198b513dc6ad287fe44117d03bec4d6a966a Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 7 Jul 2015 20:57:20 +0300 Subject: [PATCH 2066/3781] Marking rank of vaapidecodebin as GST_RANK_MARGINAL for now. Unfortunately vaapidecodebin element is not seems to be stable enough for autoplugging ahead of vaapidecode. Lowering the rank for now (cosidering the immediate 0.6 release). See this: https://bugzilla.gnome.org/show_bug.cgi?id=749554 Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 3ad0ec0f05..ee44859c16 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -81,7 +81,7 @@ plugin_init (GstPlugin * plugin) #if GST_CHECK_VERSION(1,4,0) gst_element_register (plugin, "vaapidecodebin", - GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); + GST_RANK_MARGINAL, GST_TYPE_VAAPI_DECODE_BIN); #endif return TRUE; } From 1b76561d958461d5daba9fed712f06660c45d645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 14 Jul 2015 19:39:20 +0200 Subject: [PATCH 2067/3781] vaapidecoder: no wmv profiles gstreamer 1.4/1.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fix the auto-plugging problem in gstreamer 1.2 and gstreamer 1.4 Right now there is not a primary ranked parser for vc1 and the demuxers delivers caps without specifying the profile. This situation is not an issue for avdec_vc1 but for vaapidecode it is, which refuses to negotiate without a explicit profile defined in the negotiated caps. Nonetheless, in gstreamer 1.5 it seems not to be a problem since the negotiation admits caps subsets try outs. This patch solves the issue ignoring the profile negotiation in the caps. For gstreamer < 1.5 the profile string is not handled, so the auto-plugging get done without the vc1 parser, such as happens in gstreamer 1.5. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiprofile.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index a6f9e98a59..731bee3674 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -121,6 +121,7 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h264", "stereo-high" }, #endif +#if GST_CHECK_VERSION(1,5,0) { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, "video/x-wmv, wmvversion=3", "simple" }, @@ -130,6 +131,17 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, "video/x-wmv, wmvversion=3, format=(string)WVC1", "advanced" }, +#else + { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, + "video/x-wmv, wmvversion=3", NULL + }, + { GST_VAAPI_PROFILE_VC1_MAIN, VAProfileVC1Main, + "video/x-wmv, wmvversion=3", NULL + }, + { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, + "video/x-wmv, wmvversion=3, format=(string)WVC1", NULL + }, +#endif #if VA_CHECK_VERSION(0,32,0) { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline, "image/jpeg", NULL From 0b66e7b22ce4d86c0cfff2f5b17a1f9e2782e886 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 15 Jul 2015 15:49:19 +0300 Subject: [PATCH 2068/3781] NEWS: updates --- NEWS | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 339c668626..928487663e 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,51 @@ -gst-vaapi NEWS -- summary of changes. 2015-02-03 +gst-vaapi NEWS -- summary of changes. 2015-07-15 Copyright (C) 2010-2011 Splitted-Desktop Systems Copyright (C) 2011-2013 Intel Corporation Copyright (C) 2011 Collabora +Version 0.6 - 15.Jul.2015 +* Add HEVC(H265) Decoder +* Add HEVC(H265) Encoder +* Add VP8 Encoder +* Add JPEG Encoder +* Add support for EGL [#743846, #743847, #741079] +* Add a vaapidecodebin(vaapidecode->queue->vaapipostproc) element [#745216] +* Add skin-tone-enhancement feature in vaapipostproc [#744088] +* Add support for H.264 MVC Multiview High profile encoding with more than 2 views [#732453] +* Add support for GstVideoGLTextureOrientation in plugins +* Add support for BGRA textures in plugins +* Removed all GStreamer 0.10 and 1.0 specific code sections [#745728,#732666] +* Add support for loss of picturers in h264 decoder [#745048,#703921] +* Add a simple-encoder test program that uses libgstvaapi for video encoding [#719528] +* Add finer wayland frame control and many other optimizations [#719528, #749078, #747492#] +* Add scaling of quality factor and Qantization tables for JPEG encoder [#748335] +* Add GstColorBalance interface in vaapipostproc [#720376] +* Add a handoff signal to vaapisink [#747905] +* Add rounding control handling for VC1 simple and Main profile [#743958] +* Record glconext supplied by downstream to enable run-time compatibility check [#725643] +* Switch back to single thread implementation in vaapidecode [#742605] +* Set decoding latency in vaapidecode by assuming realtime performance fo the HW decoding [#740419] +* Allow vaapidecode to connect with glimagesink, mark x11 display as compatible with EGL [#745902] +* Allow decoding of VC1 streams which contain user BDUs [#741237] +* Use git.mk, a small Makefile to autogenerate .gitignore files +* Expose the overlay capability in vaapisink for compatibility with dvbsuboverlay [#750095] +* Enable VPP element in vaapidecodebin only if there is HW support [#749554] +* Fix autoplugging of vaapidecode in playbin for wmv/asf streams +* Fix multi-slice hevc encoding [#749854] +* Fix ABBA deadlock between vaapisink and vaapipostproc if running in different threds [#738249] +* Fix Seeking failure while using navseek in pipeline [#738677] +* Fix PTS cache for MPEG2 GOP start [#748676] +* Fix the wrong selection of passthrough mode in vaapipostproc [#748184] +* Fix GstVaapiVideoPool related dead-lock [#747944] +* Fix the race condition while setting drm device type [#747914] +* Fix crash in vaapidecode if buffer outlives the decoder [#745189] +* Fix memory leak in vaapidecode [#743226] +* Fix multiple caps negotiation issues with vaapi elements [#744618] +* Improve check for upstream element that requires DMABUF buffer pool +* Fix vaapisink memory leak in debug mode +* Fix crash when seeking mpeg2 strems +* Fix support for Wayland/EGL running alongside X11 + Version 0.5.10 - 3.Feb.2015 * Add support for DRM Render-Nodes for headless operation * Add support for VA surface buffer sharing with DMABUF and GEM handles From daf5ea0be124febd808a7c5b51a74a873aaacf72 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 15 Jul 2015 15:49:38 +0300 Subject: [PATCH 2069/3781] 0.6.0 --- configure.ac | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 1f59a17422..24014d4233 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) -m4_define([gst_vaapi_minor_version], [5]) -m4_define([gst_vaapi_micro_version], [11]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_minor_version], [6]) +m4_define([gst_vaapi_micro_version], [0]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ @@ -57,7 +57,7 @@ m4_define([gtkdoc_version], [1.9]) AC_PREREQ([2.66]) AC_INIT([gst_vaapi], [gst_vaapi_version], - [gwenole.beauchesne@intel.com], + [gwenole.beauchesne@intel.com, sreerenj.balachandran@intel.com], [gstreamer-vaapi]) AC_CONFIG_HEADERS([config.h]) @@ -233,6 +233,10 @@ AC_SUBST([GST_PKG_VERSION]) AC_DEFINE_UNQUOTED([GST_PKG_VERSION_S], ["$GST_PKG_VERSION"], [Defined to the string representation of GStreamer API version]) +if test "$GST_API_VERSION" = "1.2"; then + AC_MSG_WARN([support for GStreamer 1.2 is deprecated, please upgrade]) +fi + dnl GStreamer Core PKG_CHECK_MODULES([GST], [gstreamer-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) From ab312dc1929129c15800eeefd4690e84a7498a95 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 15 Jul 2015 18:18:49 +0300 Subject: [PATCH 2070/3781] Bump version for development --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 24014d4233..f918dda98b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [6]) -m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 939bdb08a5f23e46e4507774931874fcc721946b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Jun 2015 13:48:46 +0200 Subject: [PATCH 2071/3781] decoder: add initial infrastructure for marking corrupted output. Add initial infrastructure in core codec library and vaapidecode to mark corrupted frames as such. A corrupted frame is such a frame that was reconstructed from invalid references for instance. https://bugzilla.gnome.org/show_bug.cgi?id=751434 Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 9 +++++++++ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 8 +++++++- gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 3 +++ gst/vaapi/gstvaapidecode.c | 8 +++++--- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index eb773b039a..092befddc7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -117,6 +117,12 @@ gst_vaapi_picture_create (GstVaapiPicture * picture, 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)) { @@ -348,6 +354,9 @@ do_output (GstVaapiPicture * 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; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index c9b0dfd48c..c4c4f8586f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -68,6 +68,8 @@ typedef enum * @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. @@ -83,7 +85,8 @@ typedef enum 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_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 9), + 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 @@ -126,6 +129,9 @@ typedef enum #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: * diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 47d3021352..1dc218c45d 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -38,6 +38,8 @@ G_BEGIN_DECLS * @GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD: only one field is available * @GST_VAAPI_SURFACE_PROXY_FLAG_FFB: first frame in bundle, e.g. the first * view component of a MultiView Coded (MVC) frame + * @GST_VAAPI_SURFACE_PROXY_FLAG_CORRUPTED: the underlying surface is + * corrupted somehow, e.g. reconstructed from invalid references * @GST_VAAPI_SURFACE_PROXY_FLAG_LAST: first flag that can be used by subclasses * * Flags for #GstVaapiDecoderFrame. @@ -49,6 +51,7 @@ typedef enum GST_VAAPI_SURFACE_PROXY_FLAG_RFF = (1 << 2), GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD = (1 << 3), GST_VAAPI_SURFACE_PROXY_FLAG_FFB = (1 << 4), + GST_VAAPI_SURFACE_PROXY_FLAG_CORRUPTED = (1 << 5), GST_VAAPI_SURFACE_PROXY_FLAG_LAST = (1 << 8) } GstVaapiSurfaceProxyFlags; diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b40dd97804..93d3a5a61c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -264,7 +264,7 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, GstFlowReturn ret; const GstVaapiRectangle *crop_rect; GstVaapiVideoMeta *meta; - guint flags; + guint flags, out_flags = 0; if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) { proxy = gst_video_codec_frame_get_user_data (out_frame); @@ -282,16 +282,18 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, gst_vaapi_video_meta_set_surface_proxy (meta, proxy); flags = gst_vaapi_surface_proxy_get_flags (proxy); + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_CORRUPTED) + out_flags |= GST_BUFFER_FLAG_CORRUPTED; if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED) { - guint out_flags = GST_VIDEO_BUFFER_FLAG_INTERLACED; + out_flags |= GST_VIDEO_BUFFER_FLAG_INTERLACED; if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF) out_flags |= GST_VIDEO_BUFFER_FLAG_TFF; if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF) out_flags |= GST_VIDEO_BUFFER_FLAG_RFF; if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) out_flags |= GST_VIDEO_BUFFER_FLAG_ONEFIELD; - GST_BUFFER_FLAG_SET (out_frame->output_buffer, out_flags); } + GST_BUFFER_FLAG_SET (out_frame->output_buffer, out_flags); crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy); if (crop_rect) { From 80a7ab09591474d20e158f774d50ce1e5c32d35e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 24 Jun 2015 13:58:17 +0200 Subject: [PATCH 2072/3781] decoder: h264: track corrupted frames. Mark the picture as "corrupted" if it is reconstructed from corrupted references or if those references are fake, e.g. resulting from lost frames. This is useful for notifying the upper layer, or downstream elements, that the decoded frame may contain artefacts. https://bugzilla.gnome.org/show_bug.cgi?id=703921 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 677e73b7ac..45a5e5aac8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2875,6 +2875,37 @@ exec_picture_refs_modification( exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1); } +static gboolean +check_picture_ref_corruption(GstVaapiDecoderH264 *decoder, + GstVaapiPictureH264 *RefPicList[32], guint RefPicList_count) +{ + const guint corrupted_flags = + GST_VAAPI_PICTURE_FLAG_CORRUPTED | GST_VAAPI_PICTURE_FLAG_GHOST; + guint i; + + for (i = 0; i < RefPicList_count; i++) { + GstVaapiPictureH264 * const picture = RefPicList[i]; + if (picture && (GST_VAAPI_PICTURE_FLAGS(picture) & corrupted_flags)) + return TRUE; + } + return FALSE; +} + +static void +mark_picture_refs(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +{ + GstVaapiDecoderH264Private * const priv = &decoder->priv; + + if (GST_VAAPI_PICTURE_IS_CORRUPTED(picture)) + return; + + if (check_picture_ref_corruption(decoder, + priv->RefPicList0, priv->RefPicList0_count) || + check_picture_ref_corruption(decoder, + priv->RefPicList1, priv->RefPicList1_count)) + GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_CORRUPTED); +} + static void init_picture_ref_lists(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) @@ -2975,6 +3006,8 @@ init_picture_refs( default: break; } + + mark_picture_refs(decoder, picture); } static GstVaapiPictureH264 * From d4ccae8398c4971c9400473b1a8a1308f7ea1ea8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 6 Jul 2015 14:38:26 +0200 Subject: [PATCH 2073/3781] decoder: h264: fix closure of "other-field" gap. When a dummy "other-field" is inserted, it is assumed to inherit the reference flags from the first field, and the sliding window decoded reference picture marking process is also executed so that corrupted frames are moved out as early as possible. While doing so, we also try to output frames that now contain a single valid field picture, prior to inserting any other picture into the DPB. Note: this may be superfluous currently based on the fact that dpb_add() combines the two most recent pairable fields, but this process would be further simplified later on. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 35 +++++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 45a5e5aac8..ab86ba1a15 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -307,6 +307,7 @@ struct _GstVaapiFrameStore { GstVaapiPictureH264 *buffers[2]; guint num_buffers; guint output_needed; + guint output_called; }; static void @@ -340,6 +341,7 @@ gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture) fs->buffers[1] = NULL; fs->num_buffers = 1; fs->output_needed = 0; + fs->output_called = 0; if (picture->output_flag) { picture->output_needed = TRUE; @@ -728,6 +730,7 @@ dpb_output(GstVaapiDecoderH264 *decoder, GstVaapiFrameStore *fs) g_return_val_if_fail(fs != NULL, FALSE); + fs->output_called++; if (!gst_vaapi_frame_store_is_complete(fs)) return TRUE; @@ -740,6 +743,7 @@ dpb_output(GstVaapiDecoderH264 *decoder, GstVaapiFrameStore *fs) } fs->output_needed = 0; + fs->output_called = 0; if (!picture) return TRUE; return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture)); @@ -1059,6 +1063,12 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) } } + // Try to output the previous frame again if it was not submitted yet + // e.g. delayed while waiting for the next field, or a field gap was closed + fs = priv->prev_frames[picture->base.voc]; + if (fs && fs->output_called) + dpb_output(decoder, fs); + // Create new frame store, and split fields if necessary fs = gst_vaapi_frame_store_new(picture); if (!fs) @@ -3088,8 +3098,9 @@ static GstVaapiPictureH264 * fill_picture_other_field_gap(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *f0) { + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiPictureH264 *prev_picture, *f1; - gint prev_picture_index; + gint prev_frame_index; guint picture_structure; picture_structure = f0->base.structure; @@ -3106,10 +3117,10 @@ fill_picture_other_field_gap(GstVaapiDecoderH264 *decoder, } GST_VAAPI_PICTURE_FLAG_SET(f0, GST_VAAPI_PICTURE_FLAG_ONEFIELD); - prev_picture_index = dpb_find_nearest_prev_poc(decoder, f0, + prev_frame_index = dpb_find_nearest_prev_poc(decoder, f0, picture_structure, &prev_picture); - if (prev_picture_index < 0) - return NULL; + if (prev_frame_index < 0) + goto error_find_field; f1 = gst_vaapi_picture_h264_new_field(f0); if (!f1) @@ -3126,18 +3137,30 @@ fill_picture_other_field_gap(GstVaapiDecoderH264 *decoder, (GST_VAAPI_PICTURE_FLAG_SKIPPED | GST_VAAPI_PICTURE_FLAG_GHOST)); + gst_vaapi_picture_h264_set_reference(f1, 0, FALSE); + gst_vaapi_picture_replace(&priv->current_picture, f1); + gst_vaapi_picture_unref(f1); + + init_picture_ref_lists(decoder, f1); + init_picture_refs_pic_num(decoder, f1, NULL); + if (!exec_ref_pic_marking_sliding_window(decoder)) + goto error_exec_ref_pic_marking; if (!dpb_add(decoder, f1)) goto error_append_field; - gst_vaapi_picture_unref(f1); return f1; /* ERRORS */ +error_find_field: + GST_ERROR("failed to find field with POC nearest to %d", f0->base.poc); + return NULL; error_allocate_field: GST_ERROR("failed to allocate missing field for previous frame store"); return NULL; +error_exec_ref_pic_marking: + GST_ERROR("failed to execute reference picture marking process"); + return NULL; error_append_field: GST_ERROR("failed to add missing field into previous frame store"); - gst_vaapi_picture_unref(f1); return NULL; } From 06147100f263c35f418e971361672d4a73c00ebf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 29 Jun 2015 13:16:09 +0200 Subject: [PATCH 2074/3781] decoder: h264: fix integration of second field into the DPB. If the new picture to be added to the DPB is not a first field, then it shall be the second field of the previous picture that was added before. This removes the need for dpb_find_picture() now that we track the immediately preceding decoded picture, in decode order. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 34 +++++------------------ 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index ab86ba1a15..fa945eb5dc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -759,23 +759,6 @@ dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i) dpb_remove_index(decoder, i); } -/* Finds the frame store holding the supplied picture */ -static gint -dpb_find_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) -{ - GstVaapiDecoderH264Private * const priv = &decoder->priv; - gint i, j; - - for (i = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - for (j = 0; j < fs->num_buffers; j++) { - if (fs->buffers[j] == picture) - return i; - } - } - return -1; -} - /* Finds the picture with the nearest previous POC and same structure */ static gint dpb_find_nearest_prev_poc(GstVaapiDecoderH264 *decoder, @@ -1049,18 +1032,15 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) // Check if picture is the second field and the first field is still in DPB if (GST_VAAPI_PICTURE_IS_INTERLACED(picture) && !GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture)) { - const gint found_index = dpb_find_picture(decoder, - GST_VAAPI_PICTURE_H264(picture->base.parent_picture)); - if (found_index >= 0) - return gst_vaapi_frame_store_add(priv->dpb[found_index], picture); - - // ... also check the previous picture that was immediately output fs = priv->prev_frames[picture->base.voc]; - if (fs && &fs->buffers[0]->base == picture->base.parent_picture) { - if (!gst_vaapi_frame_store_add(fs, picture)) - return FALSE; + if (!fs || &fs->buffers[0]->base != picture->base.parent_picture) + return FALSE; + if (!gst_vaapi_frame_store_add(fs, picture)) + return FALSE; + + if (fs->output_called) return dpb_output(decoder, fs); - } + return TRUE; } // Try to output the previous frame again if it was not submitted yet From 52adebe779240d1b1fe942176b1b6d81b1ea7154 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 29 Jun 2015 14:27:56 +0200 Subject: [PATCH 2075/3781] decoder: h264: track previous reference frames. Improve closure of gaps in frame_num by strictly following and trying to fill them with previous reference frames. So, they are now tracked thus avoiding insertion of dummy ("greenish") frames. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 75 +++++++++++++---------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index fa945eb5dc..7a90f4b291 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -488,6 +488,7 @@ struct _GstVaapiDecoderH264Private { GstVaapiParserInfoH264 *active_pps; GstVaapiParserInfoH264 *prev_pi; GstVaapiParserInfoH264 *prev_slice_pi; + GstVaapiFrameStore **prev_ref_frames; GstVaapiFrameStore **prev_frames; guint prev_frames_alloc; GstVaapiFrameStore **dpb; @@ -794,29 +795,6 @@ dpb_find_nearest_prev_poc(GstVaapiDecoderH264 *decoder, return found_picture ? found_index : -1; } -/* Finds the picture with the associated FrameNum */ -static gint -dpb_find_frame_num(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, - gint frame_num, GstVaapiPictureH264 **found_picture_ptr) -{ - GstVaapiDecoderH264Private * const priv = &decoder->priv; - guint i, j; - - for (i = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - if (picture && picture->base.view_id != fs->view_id) - continue; - for (j = 0; j < fs->num_buffers; j++) { - if (fs->buffers[j]->frame_num != frame_num) - continue; - if (found_picture_ptr) - *found_picture_ptr = fs->buffers[j]; - return i; - } - } - return -1; -} - /* Finds the picture with the lowest POC that needs to be output */ static gint dpb_find_lowest_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, @@ -960,6 +938,15 @@ dpb_clear(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) for (i = 0; i < priv->max_views; i++) gst_vaapi_frame_store_replace(&priv->prev_frames[i], NULL); } + + /* Clear previous reference frame buffers only if this is a "flush-all" + operation, or if the picture is part of an IDR NAL */ + if (priv->prev_ref_frames && (!picture || + GST_VAAPI_PICTURE_FLAG_IS_SET(picture, + GST_VAAPI_PICTURE_FLAG_IDR))) { + for (i = 0; i < priv->max_views; i++) + gst_vaapi_frame_store_replace(&priv->prev_ref_frames[i], NULL); + } } static void @@ -1067,6 +1054,8 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) if (!dpb_bump(decoder, picture)) return FALSE; } + gst_vaapi_frame_store_replace(&priv->prev_ref_frames[picture->base.voc], + fs); } // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB @@ -1137,19 +1126,36 @@ mvc_reset(GstVaapiDecoderH264 *decoder) } // Resize array of previous frame buffers - for (i = priv->max_views; i < priv->prev_frames_alloc; i++) + for (i = priv->max_views; i < priv->prev_frames_alloc; i++) { + gst_vaapi_frame_store_replace(&priv->prev_ref_frames[i], NULL); gst_vaapi_frame_store_replace(&priv->prev_frames[i], NULL); + } + + priv->prev_ref_frames = g_try_realloc_n(priv->prev_ref_frames, + priv->max_views, sizeof(*priv->prev_ref_frames)); + if (!priv->prev_ref_frames) + goto error_allocate; priv->prev_frames = g_try_realloc_n(priv->prev_frames, priv->max_views, sizeof(*priv->prev_frames)); - if (!priv->prev_frames) { - priv->prev_frames_alloc = 0; - return FALSE; - } - for (i = priv->prev_frames_alloc; i < priv->max_views; i++) + if (!priv->prev_frames) + goto error_allocate; + + for (i = priv->prev_frames_alloc; i < priv->max_views; i++) { + priv->prev_ref_frames[i] = NULL; priv->prev_frames[i] = NULL; + } priv->prev_frames_alloc = priv->max_views; return TRUE; + + /* ERRORS */ +error_allocate: + g_free(priv->prev_ref_frames); + priv->prev_ref_frames = NULL; + g_free(priv->prev_frames); + priv->prev_frames = NULL; + priv->prev_frames_alloc = 0; + return FALSE; } static GstVaapiDecoderStatus @@ -1224,6 +1230,8 @@ gst_vaapi_decoder_h264_destroy(GstVaapiDecoder *base_decoder) priv->dpb = NULL; priv->dpb_size = 0; + g_free(priv->prev_ref_frames); + priv->prev_ref_frames = NULL; g_free(priv->prev_frames); priv->prev_frames = NULL; priv->prev_frames_alloc = 0; @@ -3151,6 +3159,7 @@ fill_picture_gaps(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, GstVaapiDecoderH264Private * const priv = &decoder->priv; GstH264SPS * const sps = get_sps(decoder); const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); + GstVaapiFrameStore *prev_frame; GstVaapiPicture *base_picture; GstVaapiPictureH264 *lost_picture, *prev_picture; GstH264SliceHdr lost_slice_hdr; @@ -3163,11 +3172,9 @@ fill_picture_gaps(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, if (priv->dpb_count == 0) return TRUE; - prev_picture = NULL; - dpb_find_frame_num(decoder, picture, priv->prev_ref_frame_num, - &prev_picture); - if (prev_picture) - gst_vaapi_picture_ref(prev_picture); + prev_frame = priv->prev_ref_frames[picture->base.voc]; + g_assert(prev_frame != NULL); + prev_picture = gst_vaapi_picture_ref(prev_frame->buffers[0]); gst_vaapi_picture_ref(picture); lost_slice_hdr = *slice_hdr; From b6ed40cfea4e6622668aa36d020c5b472a890844 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 22 Jul 2015 09:31:02 +0300 Subject: [PATCH 2076/3781] codecparsers: Update to gst-vaapi-branch commit 800bdb2 ed13220: mpegvideometa: add meta transform function 18d5efd: codecparsers: jpeg: add some padding to ScanHdr struct 7a51722: codecparsers: jpeg: fix docs for table parsing functions 06b8ded: codecparsers: jpeg: fix validity checking of data parsed 387a39d: codecparsers: jpeg: fix up API db9d6a9: codecparsers: jpeg: tweak API a little bb6951e: codecparsers: jpeg: hide gst_jpeg_scan_for_marker_code() f33c30c: codecparsers: jpeg: fix and optimize scan for next marker code 4658c30: codecparsers: jpeg: fix calculation of segment size 759bcb9: codecparsers: jpeg: fix default Huffman tables generation b4811ee: codecparsers: jpeg: add JPEG bitstream parser 9422464: h264parse: fix typo in log message 9e793a0: h264parse: Move PAR calcs, and use them for stereoscopic half-aspect 77704ce: nalutils: trivial patch to check if 8bb9249: codecparsers: mpeg4: actually return full number of bits of resync marker 7862f95: Revert "codecparsers: remove ignored increment of return" 54017b1: h264parse: Add support for passing stereoscopic/multiview info 8667ee4: h264parse: Don't switch to passthrough on set_caps() Signed-off-by: Sreerenj Balachandran --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 31231759f3..0e9eec084a 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 31231759f3d6a2d83214abdc5cfec5e3820ee952 +Subproject commit 0e9eec084ad932c849308114c2230d779800bdb2 From 47b78b754798f89522fd69e292e7d0fd250a9284 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 22 Jul 2015 09:38:42 +0300 Subject: [PATCH 2077/3781] decoder: jpeg: Align with new API/ABI changes in codecparser Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 57 +++++++++++------------ 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index bfa1d2c69b..781a60d9ef 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -99,12 +99,12 @@ struct _GstVaapiDecoderJpegClass { }; static inline void -unit_set_marker_code(GstVaapiDecoderUnit *unit, GstJpegMarkerCode marker) +unit_set_marker_code(GstVaapiDecoderUnit *unit, GstJpegMarker marker) { unit->parsed_info = GSIZE_TO_POINTER(marker); } -static inline GstJpegMarkerCode +static inline GstJpegMarker unit_get_marker_code(GstVaapiDecoderUnit *unit) { return GPOINTER_TO_SIZE(unit->parsed_info); @@ -411,8 +411,7 @@ get_component(const GstJpegFrameHdr *frame_hdr, guint selector) } static GstVaapiDecoderStatus -decode_picture(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, - const guchar *buf) +decode_picture(GstVaapiDecoderJpeg *decoder, GstJpegSegment *seg) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstJpegFrameHdr * const frame_hdr = &priv->frame_hdr; @@ -430,7 +429,7 @@ decode_picture(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, } memset(frame_hdr, 0, sizeof(*frame_hdr)); - if (!gst_jpeg_parse_frame_hdr(frame_hdr, buf + seg->offset, seg->size, 0)) { + if (!gst_jpeg_segment_parse_frame_header(seg, frame_hdr)) { GST_ERROR("failed to parse image"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } @@ -444,8 +443,7 @@ decode_picture(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, static GstVaapiDecoderStatus decode_huffman_table( GstVaapiDecoderJpeg *decoder, - const guchar *buf, - guint buf_size + GstJpegSegment *seg ) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; @@ -453,7 +451,7 @@ decode_huffman_table( if (!VALID_STATE(decoder, GOT_SOI)) return GST_VAAPI_DECODER_STATUS_SUCCESS; - if (!gst_jpeg_parse_huffman_table(&priv->huf_tables, buf, buf_size, 0)) { + 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; } @@ -465,8 +463,7 @@ decode_huffman_table( static GstVaapiDecoderStatus decode_quant_table( GstVaapiDecoderJpeg *decoder, - const guchar *buf, - guint buf_size + GstJpegSegment *seg ) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; @@ -474,7 +471,7 @@ decode_quant_table( if (!VALID_STATE(decoder, GOT_SOI)) return GST_VAAPI_DECODER_STATUS_SUCCESS; - if (!gst_jpeg_parse_quant_table(&priv->quant_tables, buf, buf_size, 0)) { + 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; } @@ -486,8 +483,7 @@ decode_quant_table( static GstVaapiDecoderStatus decode_restart_interval( GstVaapiDecoderJpeg *decoder, - const guchar *buf, - guint buf_size + GstJpegSegment *seg ) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; @@ -495,7 +491,7 @@ decode_restart_interval( if (!VALID_STATE(decoder, GOT_SOI)) return GST_VAAPI_DECODER_STATUS_SUCCESS; - if (!gst_jpeg_parse_restart_interval(&priv->mcu_restart, buf, buf_size, 0)) { + 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; } @@ -503,8 +499,7 @@ decode_restart_interval( } static GstVaapiDecoderStatus -decode_scan(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, - const guchar *buf) +decode_scan(GstVaapiDecoderJpeg *decoder, GstJpegSegment *seg) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstVaapiPicture * const picture = priv->current_picture; @@ -517,17 +512,17 @@ decode_scan(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, if (!VALID_STATE(decoder, GOT_SOF)) return GST_VAAPI_DECODER_STATUS_SUCCESS; - scan_hdr_size = (buf[seg->offset] << 8) | buf[seg->offset + 1]; + 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_parse_scan_hdr(&scan_hdr, buf + seg->offset, seg->size, 0)) { + 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, - buf + seg->offset + scan_hdr_size, scan_data_size); + 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; @@ -588,8 +583,7 @@ decode_scan(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, } static GstVaapiDecoderStatus -decode_segment(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, - const guchar *buf) +decode_segment(GstVaapiDecoderJpeg *decoder, GstJpegSegment *seg) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstVaapiDecoderStatus status; @@ -609,22 +603,22 @@ decode_segment(GstVaapiDecoderJpeg *decoder, GstJpegMarkerSegment *seg, status = GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; break; case GST_JPEG_MARKER_DHT: - status = decode_huffman_table(decoder, buf + seg->offset, seg->size); + status = decode_huffman_table(decoder, seg); break; case GST_JPEG_MARKER_DQT: - status = decode_quant_table(decoder, buf + seg->offset, seg->size); + status = decode_quant_table(decoder, seg); break; case GST_JPEG_MARKER_DRI: - status = decode_restart_interval(decoder, buf + seg->offset, seg->size); + status = decode_restart_interval(decoder, seg); break; case GST_JPEG_MARKER_SOS: - status = decode_scan(decoder, seg, buf); + 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, buf); + status = decode_picture(decoder, seg); break; } return status; @@ -644,7 +638,7 @@ ensure_decoder(GstVaapiDecoderJpeg *decoder) } static gboolean -is_scan_complete(GstJpegMarkerCode marker) +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; @@ -659,8 +653,8 @@ gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder, GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); GstVaapiDecoderStatus status; - GstJpegMarkerCode marker; - GstJpegMarkerSegment seg; + GstJpegMarker marker; + GstJpegSegment seg; const guchar *buf; guint buf_size, flags; gint ofs1, ofs2; @@ -790,7 +784,7 @@ gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder, GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG_CAST(base_decoder); GstVaapiDecoderStatus status; - GstJpegMarkerSegment seg; + GstJpegSegment seg; GstBuffer * const buffer = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; GstMapInfo map_info; @@ -805,10 +799,11 @@ gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder, } 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, map_info.data); + status = decode_segment(decoder, &seg); gst_buffer_unmap(buffer, &map_info); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; From 6d7b63126ada17e45c736b3612ce033b634321f1 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 22 Jul 2015 09:41:34 +0300 Subject: [PATCH 2078/3781] patches/Videoparsers: update patch to fix build with older GStreamer 1.2 stacks --- ...uild-with-older-GStreamer-1.x-stacks.patch | 41 ++++++++----------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch index d58bcc850a..6688269c11 100644 --- a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch +++ b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch @@ -1,27 +1,18 @@ -From cfc25cf07e6547c9b9b6bd0ee7e337df0ba842d2 Mon Sep 17 00:00:00 2001 +From d8f4736b91c227b13abf35a1153d5ea669a15791 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne -Date: Mon, 28 Apr 2014 17:17:04 +0200 -Subject: [PATCH 2/3] h264parse: fix build with older GStreamer 1.x stacks. +Date: Tue, 21 Jul 2015 13:01:06 +0300 +Subject: [PATCH 2/2] h264parse: fix build with older GStreamer 1.x stacks --- - gst/vaapi/gsth264parse.c | 4 +++- - gst/vaapi/gsth264parse.h | 1 + - 2 files changed, 4 insertions(+), 1 deletion(-) + gst/videoparsers/gsth264parse.c | 2 ++ + gst/videoparsers/gsth264parse.h | 1 + + 2 files changed, 3 insertions(+) -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 9d588e2..4060145 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -27,7 +27,7 @@ - #endif - - #include "gstvaapiparse.h" --#include -+#include - #include - #include - #include "gsth264parse.h" -@@ -163,7 +163,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) +diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c +index 9e74f2d..b6fd35b 100644 +--- a/gst/videoparsers/gsth264parse.c ++++ b/gst/videoparsers/gsth264parse.c +@@ -165,7 +165,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) { h264parse->frame_out = gst_adapter_new (); gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h264parse), FALSE); @@ -31,18 +22,18 @@ index 9d588e2..4060145 100644 } -diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h -index e056ca2..56d2612 100644 ---- a/gst/vaapi/gsth264parse.h -+++ b/gst/vaapi/gsth264parse.h +diff --git a/gst/videoparsers/gsth264parse.h b/gst/videoparsers/gsth264parse.h +index 58d818c..617e616 100644 +--- a/gst/videoparsers/gsth264parse.h ++++ b/gst/videoparsers/gsth264parse.h @@ -27,6 +27,7 @@ #include #include +#include #include + #include - G_BEGIN_DECLS -- 2.1.4 From 33962322ae9962f43111ffbcd7c3d69c95277e76 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 22 Jul 2015 09:45:26 +0300 Subject: [PATCH 2079/3781] patches/videoparsers: h264parse: Disable 3D video support for GStremaer < 1.5 All API/ABI changes for S3D/MVC are added in 1.5, backporting them to older verison is not recommended. Signed-off-by: Sreerenj Balachandran --- ...e-3D-video-support-for-GStremaer-1.5.patch | 107 ++++++++++++++++++ patches/videoparsers/series.frag | 1 + 2 files changed, 108 insertions(+) create mode 100644 patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch diff --git a/patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch b/patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch new file mode 100644 index 0000000000..b61a8ca6fa --- /dev/null +++ b/patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch @@ -0,0 +1,107 @@ +From a711206aeb002e5e523ed6f4a045c2b2b7fb128e Mon Sep 17 00:00:00 2001 +From: Sreerenj Balachandran +Date: Tue, 21 Jul 2015 12:13:18 +0300 +Subject: [PATCH 4/4] h264parse: Disable 3D video support for GStremaer < 1.5 + +All API/ABI changes for S3D/MVC are added in 1.5, backporting +them to older verison is not recommended. + +Signed-off-by: Sreerenj Balachandran +--- + gst/vaapi/gsth264parse.c | 11 ++++++++++- + gst/vaapi/gsth264parse.h | 2 ++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index 98e9aa6..cd8cf2b 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -215,9 +215,11 @@ gst_h264_parse_reset_stream_info (GstH264Parse * h264parse) + h264parse->have_pps = FALSE; + h264parse->have_sps = FALSE; + ++#if GST_CHECK_VERSION(1,5,0) + h264parse->multiview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE; + h264parse->multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE; + h264parse->first_in_bundle = TRUE; ++#endif + + h264parse->align = GST_H264_PARSE_ALIGN_NONE; + h264parse->format = GST_H264_PARSE_FORMAT_NONE; +@@ -562,6 +564,7 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) + /* Additional messages that are not innerly useful to the + * element but for debugging purposes */ + case GST_H264_SEI_STEREO_VIDEO_INFO:{ ++#if GST_CHECK_VERSION(1,5,0) + GstVideoMultiviewMode mview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE; + GstVideoMultiviewFlags mview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE; + +@@ -593,9 +596,11 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) + /* output caps need to be changed */ + gst_h264_parse_update_src_caps (h264parse, NULL); + } ++#endif + break; + } + case GST_H264_SEI_FRAME_PACKING:{ ++#if GST_CHECK_VERSION(1,5,0) + GstVideoMultiviewMode mview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE; + GstVideoMultiviewFlags mview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE; + +@@ -684,6 +689,7 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) + /* output caps need to be changed */ + gst_h264_parse_update_src_caps (h264parse, NULL); + } ++#endif + break; + } + } +@@ -1746,9 +1752,11 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) + gint width, height; + GstClockTime latency; + ++#if GST_CHECK_VERSION(1,5,0) + const gchar *caps_mview_mode = NULL; + GstVideoMultiviewMode mview_mode = h264parse->multiview_mode; + GstVideoMultiviewFlags mview_flags = h264parse->multiview_flags; ++#endif + + fps_num = h264parse->fps_num; + fps_den = h264parse->fps_den; +@@ -1780,6 +1788,7 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) + } + } + ++#if GST_CHECK_VERSION(1,5,0) + /* Pass through or set output stereo/multiview config */ + if (s && gst_structure_has_field (s, "multiview-mode")) { + caps_mview_mode = gst_structure_get_string (s, "multiview-mode"); +@@ -1798,7 +1807,7 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) + GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, mview_flags, + GST_FLAG_SET_MASK_EXACT, NULL); + } +- ++#endif + gst_caps_set_simple (caps, "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, NULL); + +diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h +index 58d818c..de9be02 100644 +--- a/gst/vaapi/gsth264parse.h ++++ b/gst/vaapi/gsth264parse.h +@@ -123,10 +123,12 @@ struct _GstH264Parse + GstClockTime pending_key_unit_ts; + GstEvent *force_key_unit_event; + ++#if GST_CHECK_VERSION(1,5,0) + /* Stereo / multiview info */ + GstVideoMultiviewMode multiview_mode; + GstVideoMultiviewFlags multiview_flags; + gboolean first_in_bundle; ++#endif + }; + + struct _GstH264ParseClass +-- +2.1.4 + diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index 227df479a5..12469b6ce7 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -4,5 +4,6 @@ videoparsers_patches_base = \ 0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch \ 0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch \ 0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ + 0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch \ 0001-h265parse-include-gstvaapiparse.h.patch \ $(NULL) From 4b5fcaaf0478b8fa706a886e106dc881fed65b02 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 22 Jul 2015 12:40:19 +0300 Subject: [PATCH 2080/3781] README: updates --- README | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/README b/README index 05fa94ac21..4df26dc729 100644 --- a/README +++ b/README @@ -21,13 +21,13 @@ gstreamer-vaapi consists in a collection of VA-API based plugins for GStreamer and helper libraries. * `vaapidecode' is used to decode JPEG, MPEG-2, MPEG-4:2, H.264 AVC, - H.264 MVC, VP8, VC-1, WMV3 videos to VA surfaces, depending on the - underlying hardware capabilities. This plugin is also able to - implicitly download the decoded surface to raw YUV buffers. + H.264 MVC, VP8, VC-1, WMV3, HEVC videos to VA surfaces, depending + on the underlying hardware capabilities. This plugin is also able + to implicitly download the decoded surface to raw YUV buffers. * `vaapiencode_' is used to encode into MPEG-2, H.264 AVC, - H.264 MVC, JPEG, VP8 videos, depending on the actual value of - (mpeg2, h264, etc.). By default, raw format bitstreams + H.264 MVC, JPEG, VP8, HEVC videos, depending on the actual value + of (mpeg2, h264, etc.). By default, raw format bitstreams are generated, so the result may be piped to a muxer. e.g. qtmux for MP4 containers. @@ -44,17 +44,19 @@ GStreamer and helper libraries. Features -------- - * VA-API support from 0.29 to 0.37 - * JPEG, MPEG-2, MPEG-4, H.264 AVC, H.264 MVC, VP8 and VC-1 ad-hoc decoders - * MPEG-2, H.264 AVC,H.264 MVC, JPEG and VP8 ad-hoc encoders + * VA-API support from 0.29 to 0.38 + * JPEG, MPEG-2, MPEG-4, H.264 AVC, H.264 MVC, VP8, VC-1 and HEVC ad-hoc decoders + * MPEG-2, H.264 AVC,H.264 MVC, JPEG, VP8 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 Reduction + - Image enhancement filters: Sharpening, Noise Reductio, Color Balance, + Skin-Tone-Enhancement - Advanced deinterlacing: Motion-Adaptive, Motion-Compensated @@ -64,7 +66,7 @@ Requirements Software requirements * GStreamer 1.2.x (up to including GStreamer 1.6): - libglib2.0-dev (>= 2.28) + libglib2.0-dev (>= 2.32) libgstreamer1.0-dev (>= 1.2.0) libgstreamer-plugins-base1.0-dev (>= 1.2.0) libgstreamer-plugins-bad1.0-dev (>= 1.2.0) @@ -73,14 +75,14 @@ Software requirements DRM: libva-dev (>= 1.1.0), libdrm-dev, libudev-dev X11: libva-dev (>= 1.0.1) GLX: libva-dev (>= 1.0.3) - Wayland: libva-dev (>= 1.1.0), libwayland-dev (>= 0.95.0) + Wayland: libva-dev (>= 1.1.0), libwayland-dev (>= 1.0.2) Hardware requirements * AMD platforms with UVD2 (XvBA supported) * Intel Eaglelake (G45) * Intel Ironlake, Sandybridge, Ivybridge, Haswell and Broadwell (HD Graphics) - * Intel BayTrail + * Intel BayTrail, Braswell * Intel Poulsbo (US15W) * Intel Medfield or Cedar Trail * NVIDIA platforms with PureVideo (VDPAU supported) From c76fe74297bdc03a2143a5045321a046a64c061b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 21 Jul 2015 18:45:56 +0200 Subject: [PATCH 2081/3781] plugins: don't use gst_pad_get_allowed_caps() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gst_pad_get_allowed_caps() query the pad and the peer pad. In the case decoders, that is OK, but in the case of the postproc might lead loops, since the gst_base_transform_query_caps() forwards the query upstream and forth. Instead of gst_pad_get_allowed_caps() we only query the peer with gst_pad_peer_query_caps() using the pad's template as filter. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=752558 --- gst/vaapi/gstvaapipluginutil.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ce9cbb0a99..c80895eb5c 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -461,10 +461,12 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, GstCaps *gl_texture_upload_caps = NULL; GstCaps *sysmem_caps = NULL; GstCaps *vaapi_caps = NULL; - GstCaps *out_caps; + GstCaps *out_caps, *templ; GstVideoFormat out_format; - out_caps = gst_pad_get_allowed_caps (pad); + templ = gst_pad_get_pad_template_caps (pad); + out_caps = gst_pad_peer_query_caps (pad, templ); + gst_caps_unref (templ); if (!out_caps) { feature = GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED; goto cleanup; From b601bf0df672d7239ab12742199705770dfbfd6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 27 Jul 2015 18:49:13 +0200 Subject: [PATCH 2082/3781] vaapidecode: don't lost GLTextureUpload on seek MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When seeking, the decoder is reset, but the buffer pool is not re-negotiated, but in reset_full() the code forgets if the negotiated buffer pool has the GLTextureUpload meta. The decoder knows that GLTextureUpload meta was negotiated in decide_allocation(), but this method is not called when seeking. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=752929 --- gst/vaapi/gstvaapidecode.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 93d3a5a61c..58d5f38d10 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -700,8 +700,6 @@ gst_vaapidecode_reset_full (GstVaapiDecode * decode, GstCaps * caps, { GstVaapiCodec codec; - decode->has_texture_upload_meta = FALSE; - /* Reset tracked frame size */ decode->current_frame_size = 0; From 001a5c637de4423d397c9d64fe4a816dbd290d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 23 Jul 2015 13:11:40 +0200 Subject: [PATCH 2083/3781] remove gstvaapiuploader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Working on bug #744042 I realized that the gstvaapiuploader is practically not used. This patch removes the gstvaapiuploader and add the method gst_vaapi_plugin_base_get_allowed_raw_caps () that returns the raw caps that the system can handle, which is used by vaapisink and vaapipostproc. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=752777 --- gst/vaapi/Makefile.am | 2 - gst/vaapi/gstvaapiencode.c | 13 - gst/vaapi/gstvaapipluginbase.c | 155 ++++++----- gst/vaapi/gstvaapipluginbase.h | 24 +- gst/vaapi/gstvaapipostproc.c | 23 +- gst/vaapi/gstvaapisink.c | 24 +- gst/vaapi/gstvaapiuploader.c | 495 --------------------------------- gst/vaapi/gstvaapiuploader.h | 103 ------- 8 files changed, 97 insertions(+), 742 deletions(-) delete mode 100644 gst/vaapi/gstvaapiuploader.c delete mode 100644 gst/vaapi/gstvaapiuploader.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 1f7135b7f6..709caa7808 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -52,7 +52,6 @@ libgstvaapi_source_c = \ gstvaapipluginutil.c \ gstvaapipostproc.c \ gstvaapisink.c \ - gstvaapiuploader.c \ gstvaapivideobuffer.c \ gstvaapivideocontext.c \ gstvaapivideometa.c \ @@ -68,7 +67,6 @@ libgstvaapi_source_h = \ gstvaapipluginutil.h \ gstvaapipostproc.h \ gstvaapisink.h \ - gstvaapiuploader.h \ gstvaapivideobuffer.h \ gstvaapivideocontext.h \ gstvaapivideometa.h \ diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 7306b758ba..88c5549e20 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -57,16 +57,6 @@ ensure_display (GstVaapiEncode * encode) return gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (encode)); } -static gboolean -ensure_uploader (GstVaapiEncode * encode) -{ - if (!ensure_display (encode)) - return FALSE; - if (!gst_vaapi_plugin_base_ensure_uploader (GST_VAAPI_PLUGIN_BASE (encode))) - return FALSE; - return TRUE; -} - static gboolean gst_vaapiencode_query (GstPad * pad, GstObject * parent, GstQuery * query) { @@ -385,9 +375,6 @@ ensure_encoder (GstVaapiEncode * encode) g_return_val_if_fail (klass->alloc_encoder, FALSE); - if (!ensure_uploader (encode)) - return FALSE; - encode->encoder = klass->alloc_encoder (encode, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); if (!encode->encoder) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 5e922b3056..51a7a43b27 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -238,7 +238,6 @@ gst_vaapi_plugin_base_open (GstVaapiPluginBase * plugin) void gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) { - g_clear_object (&plugin->uploader); gst_vaapi_display_replace (&plugin->display, NULL); gst_object_replace (&plugin->gl_context, NULL); @@ -254,6 +253,7 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) gst_caps_replace (&plugin->srcpad_caps, NULL); plugin->srcpad_caps_changed = FALSE; gst_video_info_init (&plugin->srcpad_info); + gst_caps_replace (&plugin->allowed_raw_caps, NULL); } /** @@ -342,29 +342,6 @@ gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) return TRUE; } -/** - * gst_vaapi_plugin_base_ensure_uploader: - * @plugin: a #GstVaapiPluginBase - * - * Makes sure the built-in #GstVaapiUploader object is created, or - * that it was successfully notified of any VA display change. - * - * Returns: %TRUE if the uploader was successfully created, %FALSE otherwise. - */ -gboolean -gst_vaapi_plugin_base_ensure_uploader (GstVaapiPluginBase * plugin) -{ - if (plugin->uploader) { - if (!gst_vaapi_uploader_ensure_display (plugin->uploader, plugin->display)) - return FALSE; - } else { - plugin->uploader = gst_vaapi_uploader_new (plugin->display); - if (!plugin->uploader) - return FALSE; - } - return TRUE; -} - /* Checks whether the supplied pad peer element supports DMABUF sharing */ /* XXX: this is a workaround to the absence of any proposer way to specify DMABUF memory capsfeatures or bufferpool option to downstream */ @@ -521,14 +498,6 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, plugin->srcpad_caps_changed = TRUE; } - if (plugin->uploader && plugin->sinkpad_caps_is_raw) { - if (!gst_vaapi_uploader_ensure_display (plugin->uploader, plugin->display)) - return FALSE; - if (!gst_vaapi_uploader_ensure_caps (plugin->uploader, - plugin->sinkpad_caps, plugin->srcpad_caps)) - return FALSE; - } - if (!ensure_sinkpad_buffer_pool (plugin, plugin->sinkpad_caps)) return FALSE; return TRUE; @@ -777,49 +746,6 @@ config_failed: } } -/** - * gst_vaapi_plugin_base_allocate_input_buffer: - * @plugin: a #GstVaapiPluginBase - * @caps: the buffer caps constraints to honour - * @outbuf_ptr: the pointer location to the newly allocated buffer - * - * Creates a buffer that holds a VA surface memory for the sink pad to - * use it as the result for buffer_alloc() impementations. - * - * Return: #GST_FLOW_OK if the buffer could be created. - */ -GstFlowReturn -gst_vaapi_plugin_base_allocate_input_buffer (GstVaapiPluginBase * plugin, - GstCaps * caps, GstBuffer ** outbuf_ptr) -{ - GstBuffer *outbuf; - - *outbuf_ptr = NULL; - - if (!plugin->sinkpad_caps_changed) { - if (!gst_video_info_from_caps (&plugin->sinkpad_info, caps)) - return GST_FLOW_NOT_SUPPORTED; - plugin->sinkpad_caps_changed = TRUE; - } - - if (!plugin->sinkpad_caps_is_raw) - return GST_FLOW_OK; - - if (!gst_vaapi_uploader_ensure_display (plugin->uploader, plugin->display)) - return GST_FLOW_NOT_SUPPORTED; - if (!gst_vaapi_uploader_ensure_caps (plugin->uploader, caps, NULL)) - return GST_FLOW_NOT_SUPPORTED; - - outbuf = gst_vaapi_uploader_get_buffer (plugin->uploader); - if (!outbuf) { - GST_WARNING ("failed to allocate resources for raw YUV buffer"); - return GST_FLOW_NOT_SUPPORTED; - } - - *outbuf_ptr = outbuf; - return GST_FLOW_OK; -} - /** * gst_vaapi_plugin_base_get_input_buffer: * @plugin: a #GstVaapiPluginBase @@ -983,3 +909,82 @@ gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, gst_vaapi_plugin_base_set_display_type (plugin, display_type); #endif } + +static gboolean +ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) +{ + GArray *formats, *out_formats; + GstVaapiSurface *surface; + guint i; + GstCaps *out_caps; + gboolean ret = FALSE; + + if (plugin->allowed_raw_caps) + return TRUE; + + out_formats = formats = NULL; + surface = NULL; + + formats = gst_vaapi_display_get_image_formats (plugin->display); + if (!formats) + goto bail; + + out_formats = + g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), formats->len); + if (!out_formats) + goto bail; + + surface = + gst_vaapi_surface_new (plugin->display, GST_VAAPI_CHROMA_TYPE_YUV420, 64, + 64); + if (!surface) + goto bail; + + for (i = 0; i < formats->len; i++) { + const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); + GstVaapiImage *image; + + if (format == GST_VIDEO_FORMAT_UNKNOWN) + continue; + image = gst_vaapi_image_new (plugin->display, format, 64, 64); + if (!image) + continue; + if (gst_vaapi_surface_put_image (surface, image)) + g_array_append_val (out_formats, format); + gst_vaapi_object_unref (image); + } + + out_caps = gst_vaapi_video_format_new_template_caps_from_list (out_formats); + if (!out_caps) + goto bail; + + gst_caps_replace (&plugin->allowed_raw_caps, out_caps); + gst_caps_unref (out_caps); + ret = TRUE; + +bail: + if (formats) + g_array_unref (formats); + if (out_formats) + g_array_unref (out_formats); + if (surface) + gst_vaapi_object_unref (surface); + + return ret; +} + +/** + * gst_vaapi_plugin_base_get_allowed_raw_caps: + * @plugin: a #GstVaapiPluginBase + * + * Returns the raw #GstCaps allowed by the element. + * + * Returns: the allowed raw #GstCaps or %NULL + **/ +GstCaps * +gst_vaapi_plugin_base_get_allowed_raw_caps (GstVaapiPluginBase * plugin) +{ + if (!ensure_allowed_raw_caps (plugin)) + return NULL; + return plugin->allowed_raw_caps; +} diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index e64e9a89a2..0a1566f272 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -30,7 +30,6 @@ #include #include #include -#include "gstvaapiuploader.h" #ifdef HAVE_GST_GL_GL_H # include @@ -103,13 +102,6 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (gst_vaapi_display_replace(&GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin), \ (new_display))) -#define GST_VAAPI_PLUGIN_BASE_UPLOADER(plugin) \ - (GST_VAAPI_PLUGIN_BASE(plugin)->uploader) -#define GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(plugin) \ - (gst_vaapi_uploader_get_caps(GST_VAAPI_PLUGIN_BASE_UPLOADER(plugin))) -#define GST_VAAPI_PLUGIN_BASE_UPLOADER_USED(plugin) \ - (GST_VAAPI_PLUGIN_BASE(plugin)->uploader_used) - struct _GstVaapiPluginBase { /*< private >*/ @@ -147,8 +139,7 @@ struct _GstVaapiPluginBase GstObject *gl_context; - GstVaapiUploader *uploader; - gboolean uploader_used; + GstCaps *allowed_raw_caps; }; struct _GstVaapiPluginBaseClass @@ -211,10 +202,6 @@ G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin); -G_GNUC_INTERNAL -gboolean -gst_vaapi_plugin_base_ensure_uploader (GstVaapiPluginBase * plugin); - G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, @@ -230,11 +217,6 @@ gboolean gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GstQuery * query, guint feature); -G_GNUC_INTERNAL -GstFlowReturn -gst_vaapi_plugin_base_allocate_input_buffer (GstVaapiPluginBase * plugin, - GstCaps * caps, GstBuffer ** outbuf_ptr); - G_GNUC_INTERNAL GstFlowReturn gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, @@ -245,6 +227,10 @@ void gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, GstObject * object); +G_GNUC_INTERNAL +GstCaps * +gst_vaapi_plugin_base_get_allowed_raw_caps (GstVaapiPluginBase * plugin); + G_END_DECLS #endif /* GST_VAAPI_PLUGIN_BASE_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index d80d091291..cecde49efd 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -213,16 +213,6 @@ gst_vaapipostproc_ensure_display (GstVaapiPostproc * postproc) gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (postproc)); } -static gboolean -gst_vaapipostproc_ensure_uploader (GstVaapiPostproc * postproc) -{ - if (!gst_vaapipostproc_ensure_display (postproc)) - return FALSE; - if (!gst_vaapi_plugin_base_ensure_uploader (GST_VAAPI_PLUGIN_BASE (postproc))) - return FALSE; - return TRUE; -} - static gboolean gst_vaapipostproc_ensure_filter (GstVaapiPostproc * postproc) { @@ -265,8 +255,6 @@ gst_vaapipostproc_create (GstVaapiPostproc * postproc) return FALSE; if (!gst_vaapipostproc_ensure_display (postproc)) return FALSE; - if (!gst_vaapipostproc_ensure_uploader (postproc)) - return FALSE; postproc->use_vpp = FALSE; postproc->has_vpp = gst_vaapipostproc_ensure_filter (postproc); @@ -935,18 +923,19 @@ ensure_allowed_sinkpad_caps (GstVaapiPostproc * postproc) out_caps = gst_caps_from_string (GST_VAAPIPOSTPROC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES); if (!out_caps) { - GST_ERROR ("failed to create VA sink caps"); + GST_ERROR_OBJECT (postproc, "failed to create VA sink caps"); return FALSE; } /* Append raw video caps */ - if (gst_vaapipostproc_ensure_uploader (postproc)) { - raw_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS (postproc); + if (gst_vaapipostproc_ensure_display (postproc)) { + raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE (postproc)); if (raw_caps) { out_caps = gst_caps_make_writable (out_caps); gst_caps_append (out_caps, gst_caps_copy (raw_caps)); - } else - GST_WARNING ("failed to create YUV sink caps"); + } else { + GST_WARNING_OBJECT (postproc, "failed to create YUV sink caps"); + } } postproc->allowed_sinkpad_caps = out_caps; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 2fa36668b0..991e0fa8fa 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -979,16 +979,6 @@ gst_vaapisink_ensure_backend (GstVaapiSink * sink) } } -static gboolean -gst_vaapisink_ensure_uploader (GstVaapiSink * sink) -{ - if (!gst_vaapisink_ensure_display (sink)) - return FALSE; - if (!gst_vaapi_plugin_base_ensure_uploader (GST_VAAPI_PLUGIN_BASE (sink))) - return FALSE; - return TRUE; -} - static gboolean gst_vaapisink_ensure_render_rect (GstVaapiSink * sink, guint width, guint height) @@ -1193,9 +1183,7 @@ gst_vaapisink_start (GstBaseSink * base_sink) { GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); - if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (sink))) - return FALSE; - return gst_vaapisink_ensure_uploader (sink); + return gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (sink)); } static gboolean @@ -1214,17 +1202,17 @@ static GstCaps * gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) { GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); - GstCaps *out_caps, *yuv_caps; + GstCaps *out_caps, *raw_caps; out_caps = gst_static_pad_template_get_caps (&gst_vaapisink_sink_factory); if (!out_caps) return NULL; - if (gst_vaapisink_ensure_uploader (sink)) { - yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS (sink); - if (yuv_caps) { + if (gst_vaapisink_ensure_display (sink)) { + raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE (sink)); + if (raw_caps) { out_caps = gst_caps_make_writable (out_caps); - gst_caps_append (out_caps, gst_caps_copy (yuv_caps)); + gst_caps_append (out_caps, gst_caps_copy (raw_caps)); } } return out_caps; diff --git a/gst/vaapi/gstvaapiuploader.c b/gst/vaapi/gstvaapiuploader.c deleted file mode 100644 index 70e654fc1c..0000000000 --- a/gst/vaapi/gstvaapiuploader.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * gstvaapiuploader.c - VA-API video upload helper - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Author: Gwenole Beauchesne - * Copyright (C) 2011-2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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 "gstcompat.h" -#include -#include -#include -#include -#include - -#include "gstvaapiuploader.h" -#include "gstvaapipluginutil.h" -#include "gstvaapivideobuffer.h" - -#define GST_HELPER_NAME "vaapiupload" -#define GST_HELPER_DESC "VA-API video uploader" - -GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapi_uploader); -#define GST_CAT_DEFAULT gst_debug_vaapi_uploader - -G_DEFINE_TYPE (GstVaapiUploader, gst_vaapi_uploader, G_TYPE_OBJECT); - -#define GST_VAAPI_UPLOADER_CAST(obj) \ - ((GstVaapiUploader *)(obj)) -#define GST_VAAPI_UPLOADER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_VAAPI_TYPE_UPLOADER, \ - GstVaapiUploaderPrivate)) - -struct _GstVaapiUploaderPrivate -{ - GstVaapiDisplay *display; - GstCaps *allowed_caps; - GstVaapiVideoPool *images; - GstVideoInfo image_info; - GstVaapiVideoPool *surfaces; - GstVideoInfo surface_info; - guint direct_rendering; -}; - -enum -{ - PROP_0, - - PROP_DISPLAY, -}; - -static void -gst_vaapi_uploader_destroy (GstVaapiUploader * uploader) -{ - GstVaapiUploaderPrivate *const priv = uploader->priv; - - gst_caps_replace (&priv->allowed_caps, NULL); - gst_vaapi_video_pool_replace (&priv->images, NULL); - gst_vaapi_video_pool_replace (&priv->surfaces, NULL); - gst_vaapi_display_replace (&priv->display, NULL); -} - -static gboolean -ensure_display (GstVaapiUploader * uploader, GstVaapiDisplay * display) -{ - GstVaapiUploaderPrivate *const priv = uploader->priv; - - gst_vaapi_display_replace (&priv->display, display); - return TRUE; -} - -static gboolean -ensure_image (GstVaapiImage * image) -{ - guint i, num_planes, width, height; - - /* Make the image fully dirty */ - if (!gst_vaapi_image_map (image)) - return FALSE; - - gst_vaapi_image_get_size (image, &width, &height); - - num_planes = gst_vaapi_image_get_plane_count (image); - for (i = 0; i < num_planes; i++) { - guchar *const plane = gst_vaapi_image_get_plane (image, i); - if (plane) - memset (plane, 0, gst_vaapi_image_get_pitch (image, i)); - } - - if (!gst_vaapi_image_unmap (image)) - gst_vaapi_image_unmap (image); - return TRUE; -} - -static gboolean -ensure_allowed_caps (GstVaapiUploader * uploader) -{ - GstVaapiUploaderPrivate *const priv = uploader->priv; - GstVaapiSurface *surface = NULL; - GArray *formats = NULL, *out_formats = NULL; - GstCaps *out_caps; - guint i; - gboolean success = FALSE; - - enum - { WIDTH = 64, HEIGHT = 64 }; - - if (priv->allowed_caps) - return TRUE; - - formats = gst_vaapi_display_get_image_formats (priv->display); - if (!formats) - goto cleanup; - - out_formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), - formats->len); - if (!out_formats) - goto cleanup; - - surface = gst_vaapi_surface_new (priv->display, - GST_VAAPI_CHROMA_TYPE_YUV420, WIDTH, HEIGHT); - if (!surface) - goto cleanup; - - for (i = 0; i < formats->len; i++) { - const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); - GstVaapiImage *image; - - if (format == GST_VIDEO_FORMAT_UNKNOWN) - continue; - image = gst_vaapi_image_new (priv->display, format, WIDTH, HEIGHT); - if (!image) - continue; - if (ensure_image (image) && gst_vaapi_surface_put_image (surface, image)) - g_array_append_val (out_formats, format); - gst_vaapi_object_unref (image); - } - - out_caps = gst_vaapi_video_format_new_template_caps_from_list (out_formats); - if (!out_caps) - goto cleanup; - - gst_caps_replace (&priv->allowed_caps, out_caps); - gst_caps_unref (out_caps); - success = TRUE; - -cleanup: - if (out_formats) - g_array_unref (out_formats); - if (formats) - g_array_unref (formats); - if (surface) - gst_vaapi_object_unref (surface); - return success; -} - -static gboolean -ensure_image_pool (GstVaapiUploader * uploader, GstCaps * caps, - gboolean * caps_changed_ptr) -{ - GstVaapiUploaderPrivate *const priv = uploader->priv; - GstVaapiVideoPool *pool; - GstVideoInfo vi; - GstVideoFormat format; - guint width, height; - - if (!gst_video_info_from_caps (&vi, caps)) - return FALSE; - - format = GST_VIDEO_INFO_FORMAT (&vi); - width = GST_VIDEO_INFO_WIDTH (&vi); - height = GST_VIDEO_INFO_HEIGHT (&vi); - - *caps_changed_ptr = - format != GST_VIDEO_INFO_FORMAT (&priv->image_info) || - width != GST_VIDEO_INFO_WIDTH (&priv->image_info) || - height != GST_VIDEO_INFO_HEIGHT (&priv->image_info); - if (!*caps_changed_ptr) - return TRUE; - - pool = gst_vaapi_image_pool_new (priv->display, &vi); - if (!pool) - return FALSE; - - gst_video_info_set_format (&priv->image_info, format, width, height); - gst_vaapi_video_pool_replace (&priv->images, pool); - gst_vaapi_video_pool_unref (pool); - return TRUE; -} - -static gboolean -ensure_surface_pool (GstVaapiUploader * uploader, GstCaps * caps, - gboolean * caps_changed_ptr) -{ - GstVaapiUploaderPrivate *const priv = uploader->priv; - GstVaapiVideoPool *pool; - GstVideoInfo vi; - GstVideoFormat format; - guint width, height; - - if (!gst_video_info_from_caps (&vi, caps)) - return FALSE; - - format = GST_VIDEO_INFO_FORMAT (&vi); - width = GST_VIDEO_INFO_WIDTH (&vi); - height = GST_VIDEO_INFO_HEIGHT (&vi); - - *caps_changed_ptr = - format != GST_VIDEO_INFO_FORMAT (&priv->surface_info) || - width != GST_VIDEO_INFO_WIDTH (&priv->surface_info) || - height != GST_VIDEO_INFO_HEIGHT (&priv->surface_info); - if (!*caps_changed_ptr) - return TRUE; - - /* Always try to downsample source buffers to YUV 4:2:0 format as - this saves memory bandwidth for further rendering */ - /* XXX: this also means that visual quality is not preserved */ - if (format != GST_VIDEO_FORMAT_ENCODED) { - const GstVaapiChromaType chroma_type = - gst_vaapi_video_format_get_chroma_type (format); - if (chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) { - const GstVideoFormat image_format = - GST_VIDEO_INFO_FORMAT (&priv->image_info); - GST_INFO ("use implicit conversion of %s buffers to NV12 surfaces", - gst_video_format_to_string (image_format)); - gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, width, height); - } - } - - pool = gst_vaapi_surface_pool_new_full (priv->display, &vi, 0); - if (!pool) - return FALSE; - - gst_video_info_set_format (&priv->surface_info, format, width, height); - gst_vaapi_video_pool_replace (&priv->surfaces, pool); - gst_vaapi_video_pool_unref (pool); - return TRUE; -} - -static void -gst_vaapi_uploader_finalize (GObject * object) -{ - gst_vaapi_uploader_destroy (GST_VAAPI_UPLOADER_CAST (object)); - - G_OBJECT_CLASS (gst_vaapi_uploader_parent_class)->finalize (object); -} - -static void -gst_vaapi_uploader_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVaapiUploader *const uploader = GST_VAAPI_UPLOADER_CAST (object); - - switch (prop_id) { - case PROP_DISPLAY: - ensure_display (uploader, g_value_get_pointer (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_uploader_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVaapiUploader *const uploader = GST_VAAPI_UPLOADER_CAST (object); - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_pointer (value, uploader->priv->display); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_uploader_class_init (GstVaapiUploaderClass * klass) -{ - GObjectClass *const object_class = G_OBJECT_CLASS (klass); - - GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_uploader, - GST_HELPER_NAME, 0, GST_HELPER_DESC); - - g_type_class_add_private (klass, sizeof (GstVaapiUploaderPrivate)); - - object_class->finalize = gst_vaapi_uploader_finalize; - object_class->set_property = gst_vaapi_uploader_set_property; - object_class->get_property = gst_vaapi_uploader_get_property; - - g_object_class_install_property (object_class, - PROP_DISPLAY, - g_param_spec_pointer ("display", - "Display", - "The GstVaapiDisplay this object is bound to", - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); -} - -static void -gst_vaapi_uploader_init (GstVaapiUploader * uploader) -{ - GstVaapiUploaderPrivate *priv; - - priv = GST_VAAPI_UPLOADER_GET_PRIVATE (uploader); - uploader->priv = priv; - - gst_video_info_init (&priv->image_info); - gst_video_info_init (&priv->surface_info); -} - -GstVaapiUploader * -gst_vaapi_uploader_new (GstVaapiDisplay * display) -{ - return g_object_new (GST_VAAPI_TYPE_UPLOADER, "display", display, NULL); -} - -gboolean -gst_vaapi_uploader_ensure_display (GstVaapiUploader * uploader, - GstVaapiDisplay * display) -{ - g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), FALSE); - g_return_val_if_fail (display != NULL, FALSE); - - return ensure_display (uploader, display); -} - -gboolean -gst_vaapi_uploader_ensure_caps (GstVaapiUploader * uploader, - GstCaps * src_caps, GstCaps * out_caps) -{ - GstVaapiUploaderPrivate *priv; - GstVaapiImage *image; - gboolean image_caps_changed, surface_caps_changed; - - g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), FALSE); - g_return_val_if_fail (src_caps != NULL, FALSE); - - if (!out_caps) - out_caps = src_caps; - - if (!ensure_image_pool (uploader, src_caps, &image_caps_changed)) - return FALSE; - if (!ensure_surface_pool (uploader, out_caps, &surface_caps_changed)) - return FALSE; - if (!image_caps_changed && !surface_caps_changed) - return TRUE; - - priv = uploader->priv; - priv->direct_rendering = 0; - - /* Check if we can alias source and output buffers (same data_size) */ - image = gst_vaapi_video_pool_get_object (priv->images); - if (image) { - if ((gst_vaapi_image_get_format (image) == - GST_VIDEO_INFO_FORMAT (&priv->image_info)) && - gst_vaapi_image_is_linear (image) && - (gst_vaapi_image_get_data_size (image) == - GST_VIDEO_INFO_SIZE (&priv->image_info))) - priv->direct_rendering = 1; - gst_vaapi_video_pool_put_object (priv->images, image); - } - - GST_INFO ("direct-rendering: level %u", priv->direct_rendering); - return TRUE; -} - -gboolean -gst_vaapi_uploader_process (GstVaapiUploader * uploader, - GstBuffer * src_buffer, GstBuffer * out_buffer) -{ - GstVaapiVideoMeta *src_meta, *out_meta; - GstVaapiSurface *surface; - GstVaapiImage *image; - - g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), FALSE); - - out_meta = gst_buffer_get_vaapi_video_meta (out_buffer); - if (!out_meta) { - GST_WARNING ("expected an output video buffer"); - return FALSE; - } - - surface = gst_vaapi_video_meta_get_surface (out_meta); - g_return_val_if_fail (surface != NULL, FALSE); - - src_meta = gst_buffer_get_vaapi_video_meta (src_buffer); - if (src_meta) { - /* GstVaapiVideoBuffer with mapped VA image */ - image = gst_vaapi_video_meta_get_image (src_meta); - if (!image || !gst_vaapi_image_unmap (image)) - return FALSE; - } else { - /* Regular GstBuffer that needs to be uploaded to a VA image */ - image = gst_vaapi_video_meta_get_image (out_meta); - if (!image) { - image = gst_vaapi_video_pool_get_object (uploader->priv->images); - if (!image) - return FALSE; - gst_vaapi_video_meta_set_image (out_meta, image); - } - if (!gst_vaapi_image_update_from_buffer (image, src_buffer, NULL)) - return FALSE; - } - g_return_val_if_fail (image != NULL, FALSE); - - if (!gst_vaapi_surface_put_image (surface, image)) { - GST_WARNING ("failed to upload YUV buffer to VA surface"); - return FALSE; - } - - /* Map again for next uploads */ - if (!gst_vaapi_image_map (image)) - return FALSE; - return TRUE; -} - -GstCaps * -gst_vaapi_uploader_get_caps (GstVaapiUploader * uploader) -{ - g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), NULL); - - if (!ensure_allowed_caps (uploader)) - return NULL; - return uploader->priv->allowed_caps; -} - -GstBuffer * -gst_vaapi_uploader_get_buffer (GstVaapiUploader * uploader) -{ - GstVaapiUploaderPrivate *priv; - GstVaapiImage *image; - GstVaapiVideoMeta *meta; - GstVaapiSurfaceProxy *proxy; - GstBuffer *buffer; - - g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), NULL); - - priv = uploader->priv; - - buffer = gst_vaapi_video_buffer_new_from_pool (priv->images); - if (!buffer) { - GST_WARNING ("failed to allocate video buffer"); - goto error; - } - - proxy = - gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL - (priv->surfaces)); - if (!proxy) { - GST_WARNING ("failed to allocate VA surface"); - goto error; - } - - meta = gst_buffer_get_vaapi_video_meta (buffer); - gst_vaapi_video_meta_set_surface_proxy (meta, proxy); - gst_vaapi_surface_proxy_unref (proxy); - - image = gst_vaapi_video_meta_get_image (meta); - if (!gst_vaapi_image_map (image)) { - GST_WARNING ("failed to map VA image"); - goto error; - } - return buffer; - -error: - gst_buffer_unref (buffer); - return buffer; -} - -gboolean -gst_vaapi_uploader_has_direct_rendering (GstVaapiUploader * uploader) -{ - g_return_val_if_fail (GST_VAAPI_IS_UPLOADER (uploader), FALSE); - - return uploader->priv->direct_rendering; -} diff --git a/gst/vaapi/gstvaapiuploader.h b/gst/vaapi/gstvaapiuploader.h deleted file mode 100644 index 1d9f94b0ea..0000000000 --- a/gst/vaapi/gstvaapiuploader.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * gstvaapiuploader.h - VA-API video upload helper - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Author: Gwenole Beauchesne - * Copyright (C) 2011-2012 Intel Corporation - * Author: Gwenole Beauchesne - * - * This program 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free - * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA -*/ - -#ifndef GST_VAAPIUPLOADER_H -#define GST_VAAPIUPLOADER_H - -#include - -G_BEGIN_DECLS - -#define GST_VAAPI_TYPE_UPLOADER \ - (gst_vaapi_uploader_get_type ()) -#define GST_VAAPI_UPLOADER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_UPLOADER, \ - GstVaapiUploader)) -#define GST_VAAPI_UPLOADER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_UPLOADER, \ - GstVaapiUploaderClass)) -#define GST_VAAPI_IS_UPLOADER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_UPLOADER)) -#define GST_VAAPI_IS_UPLOADER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_UPLOADER)) -#define GST_VAAPI_UPLOADER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_UPLOADER, \ - GstVaapiUploaderClass)) - -typedef struct _GstVaapiUploader GstVaapiUploader; -typedef struct _GstVaapiUploaderPrivate GstVaapiUploaderPrivate; -typedef struct _GstVaapiUploaderClass GstVaapiUploaderClass; - -struct _GstVaapiUploader -{ - /*< private >*/ - GObject parent_instance; - - GstVaapiUploaderPrivate *priv; -}; - -struct _GstVaapiUploaderClass -{ - /*< private >*/ - GObjectClass parent_class; -}; - -G_GNUC_INTERNAL -GType -gst_vaapi_uploader_get_type (void) G_GNUC_CONST; - -G_GNUC_INTERNAL -GstVaapiUploader * -gst_vaapi_uploader_new (GstVaapiDisplay * display); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_uploader_ensure_display (GstVaapiUploader * uploader, - GstVaapiDisplay * display); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_uploader_ensure_caps (GstVaapiUploader * uploader, - GstCaps * src_caps, GstCaps * out_caps); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_uploader_process (GstVaapiUploader * uploader, - GstBuffer * src_buffer, GstBuffer * out_buffer); - -G_GNUC_INTERNAL -GstCaps * -gst_vaapi_uploader_get_caps (GstVaapiUploader * uploader); - -G_GNUC_INTERNAL -GstBuffer * -gst_vaapi_uploader_get_buffer (GstVaapiUploader * uploader); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_uploader_has_direct_rendering (GstVaapiUploader * uploader); - -G_END_DECLS - -#endif /* GST_VAAPI_UPLOADER_H */ From 954037cd2477c1ab8484389f89121a4f28da1e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Jul 2015 09:35:16 +0200 Subject: [PATCH 2084/3781] vaapipostroc: GLTextureUploadMeta in sink template Advertise GLTextureUploadMeta in sink caps template. https://bugzilla.gnome.org/show_bug.cgi?id=752130 --- gst/vaapi/gstvaapipostproc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index cecde49efd..6fc9917ba2 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -48,11 +48,16 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapipostproc); GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") +# define GST_VAAPIPOSTPROC_GLTEXUPLOAD_CAPS \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") + /* Default templates */ /* *INDENT-OFF* */ static const char gst_vaapipostproc_sink_caps_str[] = GST_VAAPIPOSTPROC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES "; " + GST_VAAPIPOSTPROC_GLTEXUPLOAD_CAPS "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_MODES; /* *INDENT-ON* */ @@ -61,9 +66,7 @@ static const char gst_vaapipostproc_sink_caps_str[] = static const char gst_vaapipostproc_src_caps_str[] = GST_VAAPIPOSTPROC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") ", " - GST_CAPS_INTERLACED_FALSE "; " + GST_VAAPIPOSTPROC_GLTEXUPLOAD_CAPS "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ From 351496a304d3cd9969b602707d25e0a95ec9fb45 Mon Sep 17 00:00:00 2001 From: Victor Jaquez Date: Thu, 18 Jun 2015 17:37:46 +0200 Subject: [PATCH 2085/3781] gstvaapiencoder: framerate 0/1 is valid too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Framerate 0/1 is valid, and it is particularly useful for picture encoding, such as jpeg. This patch makes the encoder to admit that framerate. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=744042 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 51be5d9b70..ab0d674884 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -452,7 +452,7 @@ check_video_info (GstVaapiEncoder * encoder, const GstVideoInfo * vip) { if (!vip->width || !vip->height) goto error_invalid_resolution; - if (!vip->fps_n || !vip->fps_d) + if (vip->fps_n < 0 || vip->fps_d <= 0) goto error_invalid_framerate; return GST_VAAPI_ENCODER_STATUS_SUCCESS; From 1e8610fc95a8a3d8b3d6a135eed6f74f2a5d8d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 23 Jun 2015 17:49:51 +0200 Subject: [PATCH 2086/3781] gstvaapicontext: fix the JPEG encoder attribs value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we query for the VAConfigAttribEncJPEG, we get a value which packs the VAConfigAttribValEncJPEG structure, but we did not assign it. This patch assigns the returned value to the attribute. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=744042 --- gst-libs/gst/vaapi/gstvaapicontext.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index ffa74580b8..113c960f9e 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -248,18 +248,10 @@ context_create (GstVaapiContext * context) } #if VA_CHECK_VERSION(0,37,0) if (cip->profile == GST_VAAPI_PROFILE_JPEG_BASELINE) { - VAConfigAttribValEncJPEG jpeg_attrib_val; - /* JPEG Encoding Attribute */ attrib->type = VAConfigAttribEncJPEG; if (!context_get_attribute (context, attrib->type, &value)) goto cleanup; - jpeg_attrib_val.value = attrib->value; - /* Set JPEG profile attribs */ - jpeg_attrib_val.bits.arithmatic_coding_mode = 0; - jpeg_attrib_val.bits.progressive_dct_mode = 0; - jpeg_attrib_val.bits.non_interleaved_mode = 1; - jpeg_attrib_val.bits.differential_mode = 0; - attrib->value = jpeg_attrib_val.value; + attrib->value = value; attrib++; } #endif From 9bdf43a84330f94e07f0911a9e0492497adc0032 Mon Sep 17 00:00:00 2001 From: Victor Jaquez Date: Mon, 22 Jun 2015 17:38:41 +0200 Subject: [PATCH 2087/3781] plugins: reduce the noise of warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Those messagse should be attached to the object, also the lack of caps is not an error, in particular in the case of JPEG encoding. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=744042 --- gst/vaapi/gstvaapipluginbase.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 51a7a43b27..05b816c62c 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -547,12 +547,12 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, /* ERRORS */ error_no_caps: { - GST_ERROR ("no caps specified"); + GST_INFO_OBJECT (plugin, "no caps specified"); return FALSE; } error_pool_config: { - GST_ERROR ("failed to reset buffer pool config"); + GST_ERROR_OBJECT (plugin, "failed to reset buffer pool config"); return FALSE; } } From cb8b2af5f0fb7c0d5579e2c3e39e33b79ce60431 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 5 Aug 2015 05:23:20 +0300 Subject: [PATCH 2088/3781] decoder: hevc: Fix the decoding of dependent slice segment Decoding process for reference picture list construction needs to be invoked only for P and B slice and the value for slice_type of dependent slice segment should be taken from the previous independent slice segment header of the same pic. https://bugzilla.gnome.org/show_bug.cgi?id=753226 Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 25d0ebe310..4767fbc076 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1620,10 +1620,6 @@ init_picture_refs (GstVaapiDecoderH265 * decoder, memset (priv->RefPicList1, 0, sizeof (GstVaapiPictureH265 *) * 16); priv->RefPicList0_count = priv->RefPicList1_count = 0; - if ((slice_hdr->type != GST_H265_B_SLICE) && - (slice_hdr->type != GST_H265_P_SLICE)) - return; - if (slice_hdr->dependent_slice_segment_flag) { GstH265SliceHdr *tmp = &priv->prev_independent_slice_pi->data.slice_hdr; num_ref_idx_l0_active_minus1 = tmp->num_ref_idx_l0_active_minus1; @@ -1637,6 +1633,11 @@ init_picture_refs (GstVaapiDecoderH265 * decoder, type = slice_hdr->type; } + /* decoding process for reference picture list construction needs to be + * invoked only for P and B slice */ + if (type == GST_H265_I_SLICE) + return; + NumRpsCurrTempList0 = MAX ((num_ref_idx_l0_active_minus1 + 1), priv->NumPocTotalCurr); NumRpsCurrTempList1 = From 343739e281f9362dc591171ac18ec147ceea5f6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 5 Aug 2015 14:15:07 +0200 Subject: [PATCH 2089/3781] gstvaapipostproc: fix code style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapipostproc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6fc9917ba2..c7fc155c95 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -932,7 +932,9 @@ ensure_allowed_sinkpad_caps (GstVaapiPostproc * postproc) /* Append raw video caps */ if (gst_vaapipostproc_ensure_display (postproc)) { - raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE (postproc)); + raw_caps = + gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE + (postproc)); if (raw_caps) { out_caps = gst_caps_make_writable (out_caps); gst_caps_append (out_caps, gst_caps_copy (raw_caps)); From 66f05af28830cd297387bda28f457fec8d2cd1f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 5 Aug 2015 14:11:12 +0200 Subject: [PATCH 2090/3781] refactor vaapi caps strings for pad templates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor the main vaapi caps strings into three macros: GST_VAAPI_MAKE_SURFACE_CAPS, GST_VAAPI_MAKE_ENC_SURFACE_CAPS and GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS. Those are in gstvaapipluginutil.h so all the elements could use them, instead of re-declaring them every time. No functional changes. Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapidecode.c | 6 ++---- gst/vaapi/gstvaapidecodebin.c | 9 ++------- gst/vaapi/gstvaapiencode_h264.c | 3 +-- gst/vaapi/gstvaapiencode_h265.c | 3 +-- gst/vaapi/gstvaapiencode_jpeg.c | 3 +-- gst/vaapi/gstvaapiencode_mpeg2.c | 3 +-- gst/vaapi/gstvaapiencode_vp8.c | 3 +-- gst/vaapi/gstvaapipluginutil.h | 12 ++++++++++++ gst/vaapi/gstvaapipostproc.c | 18 +++++------------- gst/vaapi/gstvaapisink.c | 4 +--- 10 files changed, 27 insertions(+), 37 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 58d5f38d10..cf4b67abc1 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -82,10 +82,8 @@ static const char gst_vaapidecode_sink_caps_str[] = ; static const char gst_vaapidecode_src_caps_str[] = - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") ";" - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") ";" + GST_VAAPI_MAKE_SURFACE_CAPS ";" + GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" GST_VIDEO_CAPS_MAKE("{ I420, YV12, NV12 }"); static GstStaticPadTemplate gst_vaapidecode_sink_factory = diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index cbedbb227f..03f34ac26d 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -53,10 +53,6 @@ enum static GParamSpec *properties[PROP_LAST]; -#define GST_VAAPI_DECODE_BIN_SURFACE_CAPS \ - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") - /* Default templates */ #define GST_CAPS_CODEC(CODEC) CODEC "; " /* *INDENT-OFF* */ @@ -82,10 +78,9 @@ static const char gst_vaapi_decode_bin_sink_caps_str[] = /* *INDENT-OFF* */ static const char gst_vaapi_decode_bin_src_caps_str[] = - GST_VAAPI_DECODE_BIN_SURFACE_CAPS ", " + GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") ", " + GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 2a95d65001..7800786150 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -42,8 +42,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_h264_sink_caps_str[] = - GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, - "{ ENCODED, NV12, I420, YV12 }") ", " + GST_VAAPI_MAKE_ENC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 9bd38b6eb3..964048a54b 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -41,8 +41,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h265_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_h265_sink_caps_str[] = - GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, - "{ ENCODED, NV12, I420, YV12 }") ", " + GST_VAAPI_MAKE_ENC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index a5a93621b9..d9dd34510a 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -38,8 +38,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_jpeg_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_jpeg_sink_caps_str[] = - GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, - "{ ENCODED, NV12, I420, YV12 }") ", " + GST_VAAPI_MAKE_ENC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index d48252632c..5584c60185 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -40,8 +40,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = - GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, - "{ ENCODED, NV12, I420, YV12 }") ", " + GST_VAAPI_MAKE_ENC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index eb4bb1dfb1..366cdfd894 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -38,8 +38,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp8_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_vp8_sink_caps_str[] = - GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, - "{ ENCODED, NV12, I420, YV12 }") ", " + GST_VAAPI_MAKE_ENC_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 5b437c7678..3decd05945 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -97,6 +97,18 @@ gst_vaapi_caps_feature_to_string (GstVaapiCapsFeature feature); # define GST_CAPS_INTERLACED_FALSE \ "interlace-mode = (string)progressive" +#define GST_VAAPI_MAKE_SURFACE_CAPS \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") + +#define GST_VAAPI_MAKE_ENC_SURFACE_CAPS \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") + +#define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") + G_GNUC_INTERNAL gboolean gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index c7fc155c95..fc8c7cb208 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -44,29 +44,21 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapipostproc); #define GST_CAT_DEFAULT gst_debug_vaapipostproc -# define GST_VAAPIPOSTPROC_SURFACE_CAPS \ - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") - -# define GST_VAAPIPOSTPROC_GLTEXUPLOAD_CAPS \ - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") - /* Default templates */ /* *INDENT-OFF* */ static const char gst_vaapipostproc_sink_caps_str[] = - GST_VAAPIPOSTPROC_SURFACE_CAPS ", " + GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES "; " - GST_VAAPIPOSTPROC_GLTEXUPLOAD_CAPS "; " + GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_MODES; /* *INDENT-ON* */ /* *INDENT-OFF* */ static const char gst_vaapipostproc_src_caps_str[] = - GST_VAAPIPOSTPROC_SURFACE_CAPS ", " + GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " - GST_VAAPIPOSTPROC_GLTEXUPLOAD_CAPS "; " + GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ @@ -923,7 +915,7 @@ ensure_allowed_sinkpad_caps (GstVaapiPostproc * postproc) return TRUE; /* Create VA caps */ - out_caps = gst_caps_from_string (GST_VAAPIPOSTPROC_SURFACE_CAPS ", " + out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES); if (!out_caps) { GST_ERROR_OBJECT (postproc, "failed to create VA sink caps"); diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 991e0fa8fa..b148cacc9e 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -57,9 +57,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapisink); /* Default template */ /* *INDENT-OFF* */ static const char gst_vaapisink_sink_caps_str[] = - GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, - "{ ENCODED, NV12, I420, YV12 }") ";" + GST_VAAPI_MAKE_ENC_SURFACE_CAPS ";" #if GST_CHECK_VERSION(1,3,1) GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "," From 696b446f097a3a00e19307a1106c950a170b80a1 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 6 Aug 2015 04:01:24 +0300 Subject: [PATCH 2091/3781] decoder: hevc: Fix decoding of stream when it has temporal sublayers We are calculating the dpb size based on max_dec_pic_buffering. But if there are more than one temporal sublayers, we are supposed to use the max_dec_pic_buffering[max_sub_layers_minus] for dpb size calculation (Assuming HighestTid as max_sub_layers_minus). Sample streams: TSCL_A_VIDYO_5.bin, TSCL_B_VIDYO_4.bin https://bugzilla.gnome.org/show_bug.cgi?id=753226 Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 4767fbc076..50a0125956 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -604,8 +604,11 @@ get_max_dec_frame_buffering (GstH265SPS * sps) sps->profile_tier_level.level_idc); max_dec_frame_buffering = 16; } + /* Fixme: Add limit check based on Annex A */ - return MAX (1, (sps->max_dec_pic_buffering_minus1[0] + 1)); + + /* Assuming HighestTid as sps_max_sub_layers_minus1 */ + return MAX (1, (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] + 1)); } static void From de1bc55cebb39c95af30425434c342b9ee79c8c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Aug 2015 13:07:53 +0200 Subject: [PATCH 2092/3781] gstvaapivideocontext: remove unused parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gst_vaapi_video_context_prepare() received an unused parameter. This patch removes it and the structure passed by the caller. This a left over of "Removal of gstreamer-1.0 support" (commit 8b36e25f). Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapipluginutil.c | 21 +-------------------- gst/vaapi/gstvaapivideocontext.c | 2 +- gst/vaapi/gstvaapivideocontext.h | 2 +- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index c80895eb5c..c23cd160b9 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -42,25 +42,6 @@ #include "gstvaapipluginutil.h" #include "gstvaapipluginbase.h" -/* Preferred first */ -static const char *display_types[] = { - "gst-vaapi-display", - "vaapi-display", -#if USE_WAYLAND - "wl-display", - "wl-display-name", -#endif -#if USE_X11 - "x11-display", - "x11-display-name", -#endif -#if USE_DRM - "drm-device", - "drm-device-path", -#endif - NULL -}; - typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFunc) (const gchar *); typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFromHandleFunc) (gpointer); @@ -254,7 +235,7 @@ gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type) g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); - gst_vaapi_video_context_prepare (element, display_types); + gst_vaapi_video_context_prepare (element); /* Neighbour found and it updated the display */ if (gst_vaapi_plugin_base_has_display_type (plugin, type)) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 1d3dcbaa53..e3e4afcff1 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -111,7 +111,7 @@ run_context_query (GstElement * element, GstQuery * query) } void -gst_vaapi_video_context_prepare (GstElement * element, const gchar ** types) +gst_vaapi_video_context_prepare (GstElement * element) { GstContext *context; GstQuery *query; diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index 1f052be8bc..b3d955bf7e 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -43,7 +43,7 @@ gst_vaapi_video_context_get_display (GstContext * context, G_GNUC_INTERNAL void -gst_vaapi_video_context_prepare (GstElement * element, const gchar ** types); +gst_vaapi_video_context_prepare (GstElement * element); G_GNUC_INTERNAL void From 682fbb414652a36f3aa53f6ac9d4ca6966228ce8 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 7 Aug 2015 08:34:55 +0300 Subject: [PATCH 2093/3781] codecparsers: Update to gst-vaapi-branch commit b8d8be4 ee7e81b: h264parse: Don't discard first AU delimiter 3690fb9: h264parse: Add more NAL types for debugging output 108d368: h265parse: Avoid checking for Non Mandatory VPS NAL ace61048: h265parse: expose compatible profiles to downstream Signed-off-by: Sreerenj Balachandran --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 0e9eec084a..b8d8be47c7 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 0e9eec084ad932c849308114c2230d779800bdb2 +Subproject commit b8d8be47c7f86c300ce43f15e25b595a9dd2b5c7 From 869facf3bc4f877380d33b18d1dd5cb478c804bc Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 7 Aug 2015 08:41:57 +0300 Subject: [PATCH 2094/3781] patches/videoparsers: Fix the wrong source file path This is something wrongly typed in commit 6d7b631 --- ...x-build-with-older-GStreamer-1.x-stacks.patch | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch index 6688269c11..d0446081db 100644 --- a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch +++ b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch @@ -4,14 +4,14 @@ Date: Tue, 21 Jul 2015 13:01:06 +0300 Subject: [PATCH 2/2] h264parse: fix build with older GStreamer 1.x stacks --- - gst/videoparsers/gsth264parse.c | 2 ++ - gst/videoparsers/gsth264parse.h | 1 + + gst/vaapi/gsth264parse.c | 2 ++ + gst/vaapi/gsth264parse.h | 1 + 2 files changed, 3 insertions(+) -diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c index 9e74f2d..b6fd35b 100644 ---- a/gst/videoparsers/gsth264parse.c -+++ b/gst/videoparsers/gsth264parse.c +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c @@ -165,7 +165,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) { h264parse->frame_out = gst_adapter_new (); @@ -22,10 +22,10 @@ index 9e74f2d..b6fd35b 100644 } -diff --git a/gst/videoparsers/gsth264parse.h b/gst/videoparsers/gsth264parse.h +diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h index 58d818c..617e616 100644 ---- a/gst/videoparsers/gsth264parse.h -+++ b/gst/videoparsers/gsth264parse.h +--- a/gst/vaapi/gsth264parse.h ++++ b/gst/vaapi/gsth264parse.h @@ -27,6 +27,7 @@ #include From 95b8ca0cda7e34b9e9c1f033f176ab24f4d5ba34 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 7 Aug 2015 08:43:44 +0300 Subject: [PATCH 2095/3781] decoder: hevc: Workaround to recognize wrongly encoded main profile streams HACK: This is a work-around to identify some main profile streams having wrong profile_idc. There are some wrongly encoded main profile streams(eg: ENTP_C_LG_3.bin) which doesn't have any of the profile_idc values mentioned in Annex-A, instead general_profile_idc has been set as zero and having general_profile_compatibility_flag[general_profile_idc] is TRUE. Assuming them as MAIN profile for now. https://bugzilla.gnome.org/show_bug.cgi?id=753226 Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 50a0125956..3ab7445ea2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -608,7 +608,8 @@ get_max_dec_frame_buffering (GstH265SPS * sps) /* Fixme: Add limit check based on Annex A */ /* Assuming HighestTid as sps_max_sub_layers_minus1 */ - return MAX (1, (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] + 1)); + return MAX (1, + (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] + 1)); } static void @@ -1022,8 +1023,21 @@ get_profile (GstVaapiDecoderH265 * decoder, GstH265SPS * sps, guint dpb_size) profile = gst_vaapi_utils_h265_get_profile (sps->profile_tier_level.profile_idc); - if (!profile) - return GST_VAAPI_PROFILE_UNKNOWN; + if (!profile) { + /* HACK: This is a work-around to identify some main profile streams having wrong profile_idc. + * There are some wrongly encoded main profile streams(eg: ENTP_C_LG_3.bin) which doesn't + * have any of the profile_idc values mentioned in Annex-A, instead general_profile_idc + * has been set as zero and having general_profile_compatibility_flag[general_profile_idc] + * is TRUE. Assuming them as MAIN profile for now */ + if (sps->profile_tier_level.profile_space == 0 && + sps->profile_tier_level.profile_idc == 0 && + sps->profile_tier_level.profile_compatibility_flag[0] == 1) { + GST_WARNING ("Wrong profile_idc, blindly setting it as main profile !!"); + profile = GST_VAAPI_PROFILE_H265_MAIN; + } else + return GST_VAAPI_PROFILE_UNKNOWN; + } + fill_profiles (profiles, &n_profiles, profile); switch (profile) { case GST_VAAPI_PROFILE_H265_MAIN10: From f7ce9a33d53d2c270d465c4389f0930e0654fbda Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 10 Aug 2015 05:50:50 +0300 Subject: [PATCH 2096/3781] decoder: hevc: Add SEI parsing Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 44 ++++++++++++----------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 3ab7445ea2..15ec78606c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -85,8 +85,7 @@ struct _GstVaapiParserInfoH265 GstH265VPS vps; GstH265SPS sps; GstH265PPS pps; - /* Fix SEI parsing in codecparser, have to use GArray like h264parser */ - GstH265SEIMessage sei; + GArray *sei; GstH265SliceHdr slice_hdr; } data; guint state; @@ -106,7 +105,10 @@ gst_vaapi_parser_info_h265_finalize (GstVaapiParserInfoH265 * pi) break; case GST_H265_NAL_PREFIX_SEI: case GST_H265_NAL_SUFFIX_SEI: - gst_h265_sei_free (&pi->data.sei); + if (pi->data.sei) { + g_array_unref (pi->data.sei); + pi->data.sei = NULL; + } break; } } @@ -1426,19 +1428,18 @@ parse_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) static GstVaapiDecoderStatus parse_sei (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) { - GST_FIXME ("Parse SEI, Not implemented !"); -#if 0 GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiParserInfoH265 *const pi = unit->parsed_info; - GstH265SEIMessage *sei = &pi->data.sei; + GArray **const sei_ptr = &pi->data.sei; GstH265ParserResult result; + GST_DEBUG ("parse SEI"); - result = gst_h265_parser_parse_sei (priv->parser, &pi->nalu, sei); + + result = gst_h265_parser_parse_sei (priv->parser, &pi->nalu, sei_ptr); if (result != GST_H265_PARSER_OK) { GST_WARNING ("failed to parse SEI messages"); return get_status (result); } -#endif return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1516,24 +1517,27 @@ decode_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) static GstVaapiDecoderStatus decode_sei (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) { - GST_FIXME ("Decode SEI, Not implemented!"); -#if 0 + GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiParserInfoH265 *const pi = unit->parsed_info; - GstH265SEIMessage *sei = &pi->data.sei; guint i; + GST_DEBUG ("decode SEI messages"); - switch (sei->payloadType) { - case GST_H265_SEI_PIC_TIMING:{ - GstH265PicTiming *pic_timing = &sei->payload.pic_timing; - /* Fix: only if vps->frame_field_info_present_flag */ - priv->pic_structure = pic_timing->pic_struct; - break; + + for (i = 0; i < pi->data.sei->len; i++) { + const GstH265SEIMessage *const sei = + &g_array_index (pi->data.sei, GstH265SEIMessage, i); + + switch (sei->payloadType) { + case GST_H265_SEI_PIC_TIMING:{ + const GstH265PicTiming *const pic_timing = &sei->payload.pic_timing; + priv->pic_structure = pic_timing->pic_struct; + break; + } + default: + break; } - default: - break; } -#endif return GST_VAAPI_DECODER_STATUS_SUCCESS; } From d357e3a15f2ca2570ca66bc1b4ef9e78e22fcddb Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 11 Aug 2015 08:09:10 +0300 Subject: [PATCH 2097/3781] codecparsers: Update to gst-vaapi-branch commit c18b8ad 8a03e67: videoparsers: h265: Avoid skipping of EOS and EOB nals a033083: videoparsers: h265: Fix the frame start detection code Signed-off-by: Sreerenj Balachandran --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index b8d8be47c7..c18b8ad0f0 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit b8d8be47c7f86c300ce43f15e25b595a9dd2b5c7 +Subproject commit c18b8ad0f03ea48932d15a3144bd34100f6b190b From a57f294ed3bb18ee8d8bf87ee4110fbff547a82e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 13 Aug 2015 03:06:32 +0300 Subject: [PATCH 2098/3781] codecparsers: Update to gst-vaapi-branch commit 1c70432 8e98b41: codecparsers: h265: Fix the range of delta_chroma_log2_weight_denom 839c5bc: codecparsers: h265: Fix the parsing of ref_pic_lists_modification Signed-off-by: Sreerenj Balachandran --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index c18b8ad0f0..1c7043290a 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit c18b8ad0f03ea48932d15a3144bd34100f6b190b +Subproject commit 1c7043290a9574e1579b18b47e81a0c8c4612759 From 8939674a367a22de94dcf92f2e0c7fe5f03d3005 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 13 Aug 2015 03:48:43 +0300 Subject: [PATCH 2099/3781] decoder: hevc: Fix the value assigning for delta_chroma_log2_weight_denom Assign only if ChromaArrayType != 0.. Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 15ec78606c..e401b81f95 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2339,7 +2339,7 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice_hdr))) { slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom; - if (!sps->chroma_format_idc) + if (sps->chroma_array_type != 0) slice_param->delta_chroma_log2_weight_denom = w->delta_chroma_log2_weight_denom; From 666900058064eec911103ca928416613e5b03874 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 13 Aug 2015 04:08:03 +0300 Subject: [PATCH 2100/3781] decoder: hevc: Fix default value assignment of pred_weight_table --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 35 ++++++++++++----------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index e401b81f95..4616fa7825 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2338,6 +2338,24 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice_hdr)) || (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice_hdr))) { + /* Fixme: This should be done in parser apis */ + memset (slice_param->delta_luma_weight_l0, 0, + sizeof (slice_param->delta_luma_weight_l0)); + memset (slice_param->luma_offset_l0, 0, + sizeof (slice_param->luma_offset_l0)); + memset (slice_param->delta_luma_weight_l1, 0, + sizeof (slice_param->delta_luma_weight_l1)); + memset (slice_param->luma_offset_l1, 0, + sizeof (slice_param->luma_offset_l1)); + memset (slice_param->delta_chroma_weight_l0, 0, + sizeof (slice_param->delta_chroma_weight_l0)); + memset (slice_param->ChromaOffsetL0, 0, + sizeof (slice_param->ChromaOffsetL0)); + memset (slice_param->delta_chroma_weight_l1, 0, + sizeof (slice_param->delta_chroma_weight_l1)); + memset (slice_param->ChromaOffsetL1, 0, + sizeof (slice_param->ChromaOffsetL1)); + slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom; if (sps->chroma_array_type != 0) slice_param->delta_chroma_log2_weight_denom = @@ -2391,23 +2409,6 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, } } } - /* Fixme: Optimize */ - else { - for (i = 0; i < 15; i++) { - slice_param->delta_luma_weight_l0[i] = 0; - slice_param->luma_offset_l0[i] = 0; - slice_param->delta_luma_weight_l1[i] = 0; - slice_param->luma_offset_l1[i] = 0; - } - for (i = 0; i < 15; i++) { - for (j = 0; j < 2; j++) { - slice_param->delta_chroma_weight_l0[i][j] = 0; - slice_param->ChromaOffsetL0[i][j] = 0; - slice_param->delta_chroma_weight_l1[i][j] = 0; - slice_param->ChromaOffsetL1[i][j] = 0; - } - } - } return TRUE; } From 1f287dc71c104b30050379a4558ba007d02446ed Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 13 Aug 2015 04:09:44 +0300 Subject: [PATCH 2101/3781] decoder: hevc: Fix ChromaOffsetL0/ChromaOffsetL1 calculation Based on ITU-T rec H265(4/2015): 7-56 This was a wrong equation in rec H265 (4/2013): 7-44... Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 4616fa7825..eec156c534 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2377,9 +2377,9 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, /* Find ChromaWeightL0 */ chroma_weight = (1 << chroma_log2_weight_denom) + w->delta_chroma_weight_l0[i][j]; - /* 7-44 */ + /* 7-56 */ slice_param->ChromaOffsetL0[i][j] = CLAMP ( - (w->delta_chroma_offset_l0[i][j] - + (127 + w->delta_chroma_offset_l0[i][j] - ((128 * chroma_weight) >> chroma_log2_weight_denom)), -128, 127); } @@ -2401,7 +2401,7 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, (1 << chroma_log2_weight_denom) + w->delta_chroma_weight_l1[i][j]; slice_param->ChromaOffsetL1[i][j] = - CLAMP ((w->delta_chroma_offset_l1[i][j] - + CLAMP ((127 + w->delta_chroma_offset_l1[i][j] - ((128 * chroma_weight) >> chroma_log2_weight_denom)), -128, 127); } From 53a0e78948bb43b2d7e21130de14744b0272b126 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 13 Aug 2015 05:07:52 +0300 Subject: [PATCH 2102/3781] decoder: hevc: Add calculation of WpOffsetHalfRangeC This is necessary for finding ChromaOffsetL0/ChromaOffsetL1 prediction weight table values with out using any hard coding. Fixme: We don't have parser API for sps_range_extension, so assumed zero value for high_precision_offsets_enabled_flag. Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 26 +++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index eec156c534..9b212ad174 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -388,6 +388,7 @@ struct _GstVaapiDecoderH265Private guint RefPicList1_count; guint32 SpsMaxLatencyPictures; + gint32 WpOffsetHalfRangeC; guint nal_length_size; @@ -1487,6 +1488,7 @@ decode_sps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiParserInfoH265 *const pi = unit->parsed_info; GstH265SPS *const sps = &pi->data.sps; + guint high_precision_offsets_enabled_flag = 0, bitdepthC = 0; GST_DEBUG ("decode SPS"); @@ -1495,6 +1497,13 @@ decode_sps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) sps->max_num_reorder_pics[sps->max_sub_layers_minus1] + sps->max_latency_increase_plus1[sps->max_sub_layers_minus1] - 1; + /* Calculate WpOffsetHalfRangeC: (7-34) + * Fixme: We don't have parser API for sps_range_extension, so assuming + * high_precision_offsets_enabled_flag as zero */ + bitdepthC = sps->bit_depth_chroma_minus8 + 8; + priv->WpOffsetHalfRangeC = + 1 << (high_precision_offsets_enabled_flag ? (bitdepthC - 1) : 7); + gst_vaapi_parser_info_h265_replace (&priv->sps[sps->id], pi); return GST_VAAPI_DECODER_STATUS_SUCCESS; @@ -2325,6 +2334,7 @@ static gboolean fill_pred_weight_table (GstVaapiDecoderH265 * decoder, GstVaapiSlice * slice, GstH265SliceHdr * slice_hdr) { + GstVaapiDecoderH265Private *const priv = &decoder->priv; VASliceParameterBufferHEVC *const slice_param = slice->param; GstH265PPS *const pps = get_pps (decoder); GstH265SPS *const sps = get_sps (decoder); @@ -2379,9 +2389,10 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, (1 << chroma_log2_weight_denom) + w->delta_chroma_weight_l0[i][j]; /* 7-56 */ slice_param->ChromaOffsetL0[i][j] = CLAMP ( - (127 + w->delta_chroma_offset_l0[i][j] - - ((128 * chroma_weight) >> chroma_log2_weight_denom)), -128, - 127); + (priv->WpOffsetHalfRangeC + w->delta_chroma_offset_l0[i][j] - + ((priv->WpOffsetHalfRangeC * + chroma_weight) >> chroma_log2_weight_denom)), + -priv->WpOffsetHalfRangeC, priv->WpOffsetHalfRangeC - 1); } } } @@ -2400,10 +2411,13 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, chroma_weight = (1 << chroma_log2_weight_denom) + w->delta_chroma_weight_l1[i][j]; + /* 7-56 */ slice_param->ChromaOffsetL1[i][j] = - CLAMP ((127 + w->delta_chroma_offset_l1[i][j] - - ((128 * chroma_weight) >> chroma_log2_weight_denom)), -128, - 127); + CLAMP ((priv->WpOffsetHalfRangeC + + w->delta_chroma_offset_l1[i][j] - + ((priv->WpOffsetHalfRangeC * + chroma_weight) >> chroma_log2_weight_denom)), + -priv->WpOffsetHalfRangeC, priv->WpOffsetHalfRangeC - 1); } } } From 002ac0ba9e1ba34fb0a2998754d66df2f4dafdfd Mon Sep 17 00:00:00 2001 From: Victor Jaquez Date: Fri, 19 Jun 2015 15:51:07 +0200 Subject: [PATCH 2103/3781] gstvaapiencoder: validate chroma according to the VA's RT format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before, only YUV420 color space where supported. With this patch, the encoder is queried to know the supported formats and admits YUV422 color space if its available. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=744042 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 40 ++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index ab0d674884..ebd5d3a21d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -559,6 +559,37 @@ get_packed_headers (GstVaapiEncoder * encoder) return encoder->packed_headers; } +static inline gboolean +is_chroma_type_supported (GstVaapiEncoder * encoder) +{ + GstVaapiContextInfo *const cip = &encoder->context_info; + const GstVideoFormat fmt = + GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); + guint format = 0; + + if (fmt == GST_VIDEO_FORMAT_ENCODED) + return TRUE; + + if (cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420 && + cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV422) + goto unsupported; + + if (!get_config_attribute (encoder, VAConfigAttribRTFormat, &format)) + return FALSE; + + if (!(format & from_GstVaapiChromaType (cip->chroma_type))) + goto unsupported; + + return TRUE; + +unsupported: + { + GST_ERROR ("We only support YUV 4:2:0 and YUV 4:2:2 for encoding. " + "Please try to use vaapipostproc to convert the input format."); + return FALSE; + } +} + /* Updates video context */ static gboolean set_context_info (GstVaapiEncoder * encoder) @@ -582,16 +613,9 @@ set_context_info (GstVaapiEncoder * encoder) cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); cip->ref_frames = encoder->num_ref_frames; - if (!cip->chroma_type && (format != GST_VIDEO_FORMAT_ENCODED)) + if (!is_chroma_type_supported (encoder)) goto error_unsupported_format; - if (cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420 && - format != GST_VIDEO_FORMAT_ENCODED) { - GST_ERROR ("We are only supporting YUV:4:2:0 for encoding," - "please try to use vaapipostproc to convert the input format!"); - goto error_unsupported_format; - } - memset (config, 0, sizeof (*config)); config->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); config->packed_headers = get_packed_headers (encoder); From 940dc1a18efe3ad62655da7218b5223e9929fed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 23 Jul 2015 16:03:43 +0200 Subject: [PATCH 2104/3781] gstvaapivideomemory: refactor gst_vaapi_video_allocator_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=744042 --- gst/vaapi/gstvaapivideomemory.c | 134 +++++++++++++++++++------------- 1 file changed, 81 insertions(+), 53 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index fcd225fb8b..49856726cf 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -651,13 +651,90 @@ gst_video_info_update_from_image (GstVideoInfo * vip, GstVaapiImage * image) return TRUE; } +static inline void +allocator_configure_surface_info (GstVaapiDisplay * display, + GstVaapiVideoAllocator * allocator) +{ + const GstVideoInfo *vinfo; + GstVaapiSurface *surface = NULL; + GstVaapiImage *image = NULL; + gboolean updated; + + vinfo = &allocator->video_info; + + gst_video_info_set_format (&allocator->surface_info, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); + + /* nothing to configure */ + if (GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) + return; + + surface = new_surface (display, vinfo); + if (!surface) + goto bail; + image = gst_vaapi_surface_derive_image (surface); + if (!image) + goto bail; + if (!gst_vaapi_image_map (image)) + goto bail; + + updated = gst_video_info_update_from_image (&allocator->surface_info, image); + + allocator->has_direct_rendering = !USE_NATIVE_FORMATS && updated && + (GST_VAAPI_IMAGE_FORMAT (image) == GST_VIDEO_INFO_FORMAT (vinfo)); + + GST_INFO ("has direct-rendering for %s surfaces: %s", + GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info), + allocator->has_direct_rendering ? "yes" : "no"); + + gst_vaapi_image_unmap (image); + +bail: + if (surface) + gst_vaapi_object_unref (surface); + if (image) + gst_vaapi_object_unref (image); +} + +static inline void +allocator_configure_image_info (GstVaapiDisplay * display, + GstVaapiVideoAllocator * allocator) +{ + GstVaapiImage *image = NULL; + const GstVideoInfo *vinfo; + + if (allocator->has_direct_rendering) { + allocator->image_info = allocator->surface_info; + return; + } + + vinfo = &allocator->video_info; + + if (GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) + gst_video_info_set_format (&allocator->image_info, GST_VIDEO_FORMAT_I420, + GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); + else + allocator->image_info = *vinfo; + + image = new_image (display, &allocator->image_info); + if (!image) + goto bail; + if (!gst_vaapi_image_map (image)) + goto bail; + + gst_video_info_update_from_image (&allocator->image_info, image); + gst_vaapi_image_unmap (image); + +bail: + if (image) + gst_vaapi_object_unref (image); +} + GstAllocator * gst_vaapi_video_allocator_new (GstVaapiDisplay * display, const GstVideoInfo * vip, guint flags) { GstVaapiVideoAllocator *allocator; - GstVaapiSurface *surface; - GstVaapiImage *image; g_return_val_if_fail (display != NULL, NULL); g_return_val_if_fail (vip != NULL, NULL); @@ -667,63 +744,14 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display, return NULL; allocator->video_info = *vip; - gst_video_info_set_format (&allocator->surface_info, GST_VIDEO_FORMAT_NV12, - GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); - - if (GST_VIDEO_INFO_FORMAT (vip) != GST_VIDEO_FORMAT_ENCODED) { - image = NULL; - do { - surface = new_surface (display, vip); - if (!surface) - break; - image = gst_vaapi_surface_derive_image (surface); - if (!image) - break; - if (!gst_vaapi_image_map (image)) - break; - allocator->has_direct_rendering = - gst_video_info_update_from_image (&allocator->surface_info, image); - if (GST_VAAPI_IMAGE_FORMAT (image) != GST_VIDEO_INFO_FORMAT (vip)) - allocator->has_direct_rendering = FALSE; - if (USE_NATIVE_FORMATS) - allocator->has_direct_rendering = FALSE; - gst_vaapi_image_unmap (image); - GST_INFO ("has direct-rendering for %s surfaces: %s", - GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info), - allocator->has_direct_rendering ? "yes" : "no"); - } while (0); - if (surface) - gst_vaapi_object_unref (surface); - if (image) - gst_vaapi_object_unref (image); - } + allocator_configure_surface_info (display, allocator); allocator->surface_pool = gst_vaapi_surface_pool_new_full (display, &allocator->surface_info, flags); if (!allocator->surface_pool) goto error_create_surface_pool; - allocator->image_info = *vip; - if (GST_VIDEO_INFO_FORMAT (vip) == GST_VIDEO_FORMAT_ENCODED) - gst_video_info_set_format (&allocator->image_info, GST_VIDEO_FORMAT_I420, - GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); - - if (allocator->has_direct_rendering) - allocator->image_info = allocator->surface_info; - else { - do { - image = new_image (display, &allocator->image_info); - if (!image) - break; - if (!gst_vaapi_image_map (image)) - break; - gst_video_info_update_from_image (&allocator->image_info, image); - gst_vaapi_image_unmap (image); - } while (0); - if (image) - gst_vaapi_object_unref (image); - } - + allocator_configure_image_info (display, allocator); allocator->image_pool = gst_vaapi_image_pool_new (display, &allocator->image_info); if (!allocator->image_pool) From ceb70c3ca6d3ce85526a50b524ba6a01831f33ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 23 Jul 2015 20:07:59 +0200 Subject: [PATCH 2105/3781] surface pool config based on video info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First added the function gst_vaapi_video_format_get_best_native(), which returns the best native format that matches a particular chroma type: YUV 4:2:0 -> NV12, YUV 4:2:2 -> YUY2, YUV 4:0:0 -> Y800 RGB32 chroma and encoded format map to NV12 too. That format is used to configure, initially, the surface's pool for the allocator. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=744042 --- gst-libs/gst/vaapi/video-format.c | 32 +++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/video-format.h | 3 +++ gst/vaapi/gstvaapivideomemory.c | 4 +++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 34c70aac8d..9a6edd47a1 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -270,3 +270,35 @@ gst_vaapi_video_format_get_score (GstVideoFormat format) return m ? (m - &gst_vaapi_video_formats[0]) : G_MAXUINT; } + +/** + * gst_vaapi_video_format_get_best_native: + * @format: a #GstVideoFormat + * + * Returns the best "native" pixel format that matches a particular + * color-space. + * + * Returns: the #GstVideoFormat with the corresponding best native + * format for #GstVaapiSurface + **/ +GstVideoFormat +gst_vaapi_video_format_get_best_native (GstVideoFormat format) +{ + GstVaapiChromaType chroma_type; + + if (format == GST_VIDEO_FORMAT_ENCODED) + return GST_VIDEO_FORMAT_NV12; + + chroma_type = gst_vaapi_video_format_get_chroma_type (format); + switch (chroma_type) { + case GST_VAAPI_CHROMA_TYPE_YUV422: + return GST_VIDEO_FORMAT_YUY2; + case GST_VAAPI_CHROMA_TYPE_YUV400: + return GST_VIDEO_FORMAT_GRAY8; + case GST_VAAPI_CHROMA_TYPE_YUV420: + case GST_VAAPI_CHROMA_TYPE_RGB32: /* GstVideoGLTextureUploadMeta */ + return GST_VIDEO_FORMAT_NV12; + default: + return GST_VIDEO_FORMAT_UNKNOWN; + }; +} diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index 4830522fe2..25e1161120 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -53,6 +53,9 @@ gst_vaapi_video_format_get_chroma_type (GstVideoFormat format); guint gst_vaapi_video_format_get_score (GstVideoFormat format); +GstVideoFormat +gst_vaapi_video_format_get_best_native (GstVideoFormat format); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_FORMAT_H */ diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 49856726cf..21c02998e4 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -659,10 +659,12 @@ allocator_configure_surface_info (GstVaapiDisplay * display, GstVaapiSurface *surface = NULL; GstVaapiImage *image = NULL; gboolean updated; + GstVideoFormat fmt; vinfo = &allocator->video_info; - gst_video_info_set_format (&allocator->surface_info, GST_VIDEO_FORMAT_NV12, + fmt = gst_vaapi_video_format_get_best_native (GST_VIDEO_INFO_FORMAT (vinfo)); + gst_video_info_set_format (&allocator->surface_info, fmt, GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); /* nothing to configure */ From f0d6b0ac3f88f5af8c5320f10507dea7213c28e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 3 Aug 2015 16:33:02 +0200 Subject: [PATCH 2106/3781] gstvaapivideomemory: native format with no derived image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If USE_NATIVE_FORMATS is defined we bail out before configuring the surface info based on the derived image configuration. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=744042 --- gst/vaapi/gstvaapivideomemory.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 21c02998e4..de4e092eb6 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -668,7 +668,8 @@ allocator_configure_surface_info (GstVaapiDisplay * display, GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); /* nothing to configure */ - if (GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) + if (USE_NATIVE_FORMATS || + GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) return; surface = new_surface (display, vinfo); From 00043017149264642b82559c28880543b1032731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Aug 2015 12:36:07 +0200 Subject: [PATCH 2107/3781] vaapidecodebin: has_vpp as a tri-state variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit has_vpp can be UNKNOWN while the context message hasn't being received. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=749554 --- gst/vaapi/gstvaapidecodebin.c | 17 ++++++++++++----- gst/vaapi/gstvaapidecodebin.h | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 03f34ac26d..85ab5ece69 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -51,6 +51,13 @@ enum PROP_LAST }; +enum +{ + HAS_VPP_UNKNOWN, + HAS_VPP_NO, + HAS_VPP_YES +}; + static GParamSpec *properties[PROP_LAST]; /* Default templates */ @@ -122,7 +129,7 @@ activate_vpp (GstVaapiDecodeBin * vaapidecbin) if (vaapidecbin->ghost_pad_src || vaapidecbin->postproc) return TRUE; - if (!vaapidecbin->has_vpp || vaapidecbin->disable_vpp) { + if (vaapidecbin->has_vpp != HAS_VPP_YES || vaapidecbin->disable_vpp) { src = vaapidecbin->queue; goto connect_src_ghost_pad; } @@ -265,11 +272,12 @@ gst_vaapi_decode_bin_handle_message (GstBin * bin, GstMessage * message) if (!gst_vaapi_video_context_get_display (context, &display)) goto bail; - vaapidecbin->has_vpp = gst_vaapi_display_has_video_processing (display); + vaapidecbin->has_vpp = gst_vaapi_display_has_video_processing (display) ? + HAS_VPP_YES : HAS_VPP_NO; /* the underlying VA driver implementation doesn't support video * post-processing, hence we have to disable it */ - if (!vaapidecbin->has_vpp) { + if (vaapidecbin->has_vpp != HAS_VPP_YES) { GST_WARNING_OBJECT (vaapidecbin, "VA driver doesn't support VPP"); if (!vaapidecbin->disable_vpp) { vaapidecbin->disable_vpp = TRUE; @@ -391,8 +399,7 @@ gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) { GstPad *element_pad, *ghost_pad; - /* let's assume we have VPP until we prove the opposite */ - vaapidecbin->has_vpp = TRUE; + vaapidecbin->has_vpp = HAS_VPP_UNKNOWN; if (!gst_vaapi_decode_bin_configure (vaapidecbin)) return; diff --git a/gst/vaapi/gstvaapidecodebin.h b/gst/vaapi/gstvaapidecodebin.h index 0f3fb6cdcb..18685fe7b4 100644 --- a/gst/vaapi/gstvaapidecodebin.h +++ b/gst/vaapi/gstvaapidecodebin.h @@ -55,7 +55,7 @@ typedef struct _GstVaapiDecodeBin { guint64 max_size_time; GstVaapiDeinterlaceMethod deinterlace_method; gboolean disable_vpp; - gboolean has_vpp; + guint has_vpp; } GstVaapiDecodeBin; From 1e061c54e196da7f66fc37fdee28bfba819f2def Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Aug 2015 12:39:52 +0200 Subject: [PATCH 2108/3781] vaapidecodebin: post an error message if fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the construction of the bin fails, post an error message in the bus. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=749554 --- gst/vaapi/gstvaapidecodebin.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 85ab5ece69..1e72278871 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -389,7 +389,8 @@ error_element_missing: } error_link_pad: { - GST_ERROR_OBJECT (vaapidecbin, "Failed to link the child elements"); + GST_ELEMENT_ERROR (vaapidecbin, CORE, PAD, + (NULL), ("Failed to configure the vaapidecodebin.")); return FALSE; } } From ee5d8ee2023df8b3983bde199f513d48c87f951b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Aug 2015 18:48:13 +0200 Subject: [PATCH 2109/3781] vaapidecodebin: ensure VPP before going to READY There are sometimes that the VA-API display context is not shared among the pipeline, but it is important to know it before going to READY state (when the pipeline is already linked). One instance of this case is this: gst-launch-1.0 filesrc location=media ! decodebin ! vaapipostproc ! vaapisink This patch adds a new function in gstvaapipluginutil called gst_vaapi_create_test_display(). Its purpose is to create a disposable VA-API display, which only will be used for verify if the VAEntrypointVideoProc is available by the hardware. Afterwards, it should be unrefed. If the vaapidecodebin is going to READY state, and the element still doesn't know if VPP is available, the last resort is to create a new instance of the VA-API display and test for it. https://bugzilla.gnome.org/show_bug.cgi?id=749554 --- gst/vaapi/gstvaapidecodebin.c | 56 ++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.c | 15 +++++++++ gst/vaapi/gstvaapipluginutil.h | 4 +++ 3 files changed, 75 insertions(+) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 1e72278871..121bda73a0 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -176,6 +176,30 @@ connect_src_ghost_pad: } } +static gboolean +ensure_vpp (GstVaapiDecodeBin * vaapidecbin) +{ + GstVaapiDisplay *display; + + if (vaapidecbin->has_vpp != HAS_VPP_UNKNOWN) + return TRUE; + + GST_DEBUG_OBJECT (vaapidecbin, "Creating a dummy display to test for vpp"); + display = gst_vaapi_create_test_display (); + if (!display) + return FALSE; + + vaapidecbin->has_vpp = gst_vaapi_display_has_video_processing (display) ? + HAS_VPP_YES : HAS_VPP_NO; + + gst_vaapi_display_unref (display); + + if (!activate_vpp (vaapidecbin)) + return FALSE; + + return TRUE; +} + static void gst_vaapi_decode_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -293,6 +317,35 @@ bail: message); } +static GstStateChangeReturn +gst_vaapi_decode_bin_change_state (GstElement * element, + GstStateChange transition) +{ + GstVaapiDecodeBin *vaapidecbin = GST_VAAPI_DECODE_BIN (element); + GstStateChangeReturn ret; + + switch (transition) { + default: + break; + } + + ret = GST_ELEMENT_CLASS (gst_vaapi_decode_bin_parent_class)->change_state + (element, transition); + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + if (!ensure_vpp (vaapidecbin)) + return GST_STATE_CHANGE_FAILURE; + break; + default: + break; + } + + return ret; +} + static void gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) { @@ -307,6 +360,9 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) gobject_class->set_property = gst_vaapi_decode_bin_set_property; gobject_class->get_property = gst_vaapi_decode_bin_get_property; + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_vaapi_decode_bin_change_state); + bin_class->handle_message = GST_DEBUG_FUNCPTR (gst_vaapi_decode_bin_handle_message); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index c23cd160b9..ef3c6cffd6 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -634,3 +634,18 @@ gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, vip->fps_n = vi.fps_n; vip->fps_d = vi.fps_d; } + +/** + * gst_vaapi_create_test_display: + * + * Creates a temporal #GstVaapiDisplay instance, just for testing the + * supported features. + * + * Returns: a new #GstVaapiDisplay instances. Free with + * gst_vaapi_display_unref () after use. + **/ +GstVaapiDisplay * +gst_vaapi_create_test_display () +{ + return gst_vaapi_create_display (GST_VAAPI_DISPLAY_TYPE_ANY, NULL); +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 3decd05945..94050fb04a 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -122,4 +122,8 @@ void gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, guint width, guint height); +G_GNUC_INTERNAL +GstVaapiDisplay * +gst_vaapi_create_test_display (void); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ From 7f34c6e17d98c6a24f4542e5ecaf8bf267cd622f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 6 Jul 2015 20:22:57 +0200 Subject: [PATCH 2110/3781] vaapidecodebin: check for postproc instance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the VPP's deinterlace-method is set, first we should check if the postproc is already instanced to set it. Otherwise we just store it until the VPP is added into the bin. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=749554 --- gst/vaapi/gstvaapidecodebin.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 121bda73a0..e602d62cf2 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -224,8 +224,9 @@ gst_vaapi_decode_bin_set_property (GObject * object, break; case PROP_DEINTERLACE_METHOD: vaapidecbin->deinterlace_method = g_value_get_enum (value); - g_object_set (G_OBJECT (vaapidecbin->postproc), "deinterlace-method", - vaapidecbin->deinterlace_method, NULL); + if (vaapidecbin->postproc) + g_object_set (G_OBJECT (vaapidecbin->postproc), "deinterlace-method", + vaapidecbin->deinterlace_method, NULL); break; case PROP_DISABLE_VPP: { @@ -457,6 +458,7 @@ gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) GstPad *element_pad, *ghost_pad; vaapidecbin->has_vpp = HAS_VPP_UNKNOWN; + vaapidecbin->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; if (!gst_vaapi_decode_bin_configure (vaapidecbin)) return; From 18a8b87975baf7ad1eb6c02a5dde6889269b33fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Aug 2015 12:28:51 +0200 Subject: [PATCH 2111/3781] Revert "Marking rank of vaapidecodebin as GST_RANK_MARGINAL for now." This reverts commit 3ccb198b513dc6ad287fe44117d03bec4d6a966a. --- gst/vaapi/gstvaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index ee44859c16..3ad0ec0f05 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -81,7 +81,7 @@ plugin_init (GstPlugin * plugin) #if GST_CHECK_VERSION(1,4,0) gst_element_register (plugin, "vaapidecodebin", - GST_RANK_MARGINAL, GST_TYPE_VAAPI_DECODE_BIN); + GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); #endif return TRUE; } From a83057cdb16ba28f01093d8de4aa14b13c62d1f1 Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Thu, 13 Aug 2015 15:12:44 -0400 Subject: [PATCH 2112/3781] wayland: Don't return GST_FLOW_ERROR on flushing Setting the sink to flushing causes gst_vaapi_window_wayland_sync() to return FALSE which makes gst_vaapi_window_wayland_render() return FALSE which ends up posting an ERROR message in gst_vaapisink_show_frame_unlocked(). Solution is to just return TRUE in the EBUSY case. https://bugzilla.gnome.org/show_bug.cgi?id=753598 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 95e34e6b94..96d1d74a31 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -186,8 +186,7 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) goto again; if (saved_errno == EBUSY) { /* closing */ wl_display_cancel_read (wl_display); - priv->is_cancelled = TRUE; - break; + return FALSE; } goto error; } @@ -518,12 +517,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, /* Wait for the previous frame to complete redraw */ if (!gst_vaapi_window_wayland_sync (window)) { wl_buffer_destroy (buffer); - return FALSE; - } - - if (priv->is_cancelled) { - wl_buffer_destroy (buffer); - return TRUE; + return !priv->is_cancelled; } frame = frame_state_new (window); From 5fd4c8dffeb446c756435d52ac3c1beea61253b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 24 Aug 2015 19:22:14 +0200 Subject: [PATCH 2113/3781] wayland: rename is_cancelled to sync_failed Since commit 065a18a3, the semantics of the variable is_cancelled did not make sense. This commit renames this variable to sync_failed. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 96d1d74a31..aeffc38b3c 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -109,7 +109,7 @@ struct _GstVaapiWindowWaylandPrivate guint is_shown:1; guint fullscreen_on_show:1; guint use_vpp:1; - guint is_cancelled:1; + guint sync_failed:1; volatile guint num_frames_pending; }; @@ -161,7 +161,7 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) struct wl_display *const wl_display = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - if (priv->is_cancelled) + if (priv->sync_failed) return FALSE; if (priv->pollfd.fd < 0) { @@ -199,7 +199,7 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) return TRUE; error: - priv->is_cancelled = TRUE; + priv->sync_failed = TRUE; GST_ERROR ("Error on dispatching events: %s", g_strerror (errno)); return FALSE; } @@ -517,7 +517,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, /* Wait for the previous frame to complete redraw */ if (!gst_vaapi_window_wayland_sync (window)) { wl_buffer_destroy (buffer); - return !priv->is_cancelled; + return !priv->sync_failed; } frame = frame_state_new (window); From 5dd1202fb06b13bd7d4d7b20e0478b29d735c746 Mon Sep 17 00:00:00 2001 From: Lim Siew Hoon Date: Fri, 14 Aug 2015 19:21:04 +0800 Subject: [PATCH 2114/3781] debian: remove --with-gstreamer-api option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is no longer valid in gstreamer-vaapi. Signed-off-by: Lim Siew Hoon [removed unused GST_API_VERSION variable] Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=753618 --- debian.upstream/rules | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/debian.upstream/rules b/debian.upstream/rules index 75787a9474..4a73db614a 100755 --- a/debian.upstream/rules +++ b/debian.upstream/rules @@ -5,9 +5,6 @@ include /usr/share/cdbs/1/class/autotools.mk include /usr/share/cdbs/1/rules/simple-patchsys.mk include /usr/share/cdbs/1/rules/utils.mk -GST_API_VERSION = $(shell echo "$(DEB_SOURCE_PACKAGE)" | \ - sed -n '/gstreamer\([0-9][0-9.]*\)-vaapi/s//\1/p') - # Allow SMP build ifeq ($(DEBIAN_BUILD_NCPUS),) DEBIAN_BUILD_NCPUS = $(shell /usr/bin/getconf _NPROCESSORS_ONLN) @@ -19,8 +16,7 @@ MAKE += $(EXTRA_MAKE_FLAGS) # Allow HTML documentation build indep_conf_flags = \ - --with-html-dir=\$${prefix}/share/doc/$(DEB_SOURCE_PACKAGE) \ - --with-gstreamer-api=$(GST_API_VERSION) + --with-html-dir=\$${prefix}/share/doc/$(DEB_SOURCE_PACKAGE) # only build the docs if gtk-doc-tools is installed, i.e. binary-indep is # called From 1cf9381b0867153fc1f6921eba11ed1452e063bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 25 Aug 2015 15:38:42 +0000 Subject: [PATCH 2115/3781] debian: add yasm as build dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the compilation of libvpx (for vp8 parser) is enabled by default, yasm is required by default too. Signed-off-by: Víctor Manuel Jáquez Leal --- debian.upstream/control.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian.upstream/control.in b/debian.upstream/control.in index 932dc6867b..ec60688f02 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -12,7 +12,8 @@ Build-Depends: debhelper (>= 5), @USE_X11_TRUE@ libx11-dev, libxrandr-dev, @USE_GLX_TRUE@ libgl-dev, @USE_WAYLAND_TRUE@ libwayland-dev (>= @WAYLAND_API_VERSION@), - libva-dev (>= @LIBVA_PACKAGE_VERSION@) + libva-dev (>= @LIBVA_PACKAGE_VERSION@), + yasm Build-Depends-Indep: gtk-doc-tools (>= @GTKDOC_VERSION@) Standards-Version: 3.7.2 From b00511355ca438430c9ff95dda3011dec18bafac Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 26 Aug 2015 06:57:36 +0300 Subject: [PATCH 2116/3781] codecparsers: Update to gst-vaapi-branch commit 69550f1 c207c6d: codecparsers: h265: Fix tile row and column parsing 47074c5: codecparsers: h265: Add APIs for up-right-diagonal/raster scan conversion cd28b18: codecparsers: h265: Fix the range of delta_chroma_log2_weight_denom 1746bbe: videoparsers: Use gst_base_parse_merge_tags() 2f0932b: h264parse: Clear SPS info after processing f57d6b0: videoparsers: enable accept-template flag --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 1c7043290a..69550f1b97 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 1c7043290a9574e1579b18b47e81a0c8c4612759 +Subproject commit 69550f1b97495f7095333d5c6f96bdf37db76ad5 From 3b7c0f8bb143542c92dff51661fe2da9d3b51c3b Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 26 Aug 2015 07:04:22 +0300 Subject: [PATCH 2117/3781] patches/Videoparsers: update patch to fix build with older GStreamer 1.2 stacks --- ...parse-fix-build-with-older-GStreamer-1.x-stacks.patch | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch index d0446081db..4ad3162539 100644 --- a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch +++ b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch @@ -1,6 +1,6 @@ -From d8f4736b91c227b13abf35a1153d5ea669a15791 Mon Sep 17 00:00:00 2001 +From cb4349b2f36194fbdd557eb11175d83fac144158 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne -Date: Tue, 21 Jul 2015 13:01:06 +0300 +Date: Wed, 26 Aug 2015 06:50:41 +0300 Subject: [PATCH 2/2] h264parse: fix build with older GStreamer 1.x stacks --- @@ -9,15 +9,16 @@ Subject: [PATCH 2/2] h264parse: fix build with older GStreamer 1.x stacks 2 files changed, 3 insertions(+) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 9e74f2d..b6fd35b 100644 +index 8f3b225..a3d2952 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c -@@ -165,7 +165,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) +@@ -165,8 +165,10 @@ gst_h264_parse_init (GstH264Parse * h264parse) { h264parse->frame_out = gst_adapter_new (); gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h264parse), FALSE); +#if GST_CHECK_VERSION(1,3,0) GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h264parse)); + GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (h264parse)); +#endif } From 279c49e8f2443376dc1312a1e26b21748c7d8fe6 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 26 Aug 2015 07:20:09 +0300 Subject: [PATCH 2118/3781] decoder: hevc: sync with the codecparser changes The Tile Scanning Conversion process (spec 6-3 and 6-4) is implemented in codecparsers now. Remove the duplication from gstvaapidecoder_h265 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 41 ----------------------- 1 file changed, 41 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 9b212ad174..a55f1efbe9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1381,47 +1381,6 @@ parse_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) if (result != GST_H265_PARSER_OK) return get_status (result); - if (pps->tiles_enabled_flag) { - guint i; - guint PicWidthInCtbsY, PicHeightInCtbsY; - - get_pic_width_height_in_ctbs (pps, &PicWidthInCtbsY, &PicHeightInCtbsY); - GST_DEBUG ("PicWidthInCtbsY %d PicHeightInCtbsY %d", PicWidthInCtbsY, - PicHeightInCtbsY); - - /* Tile Scanning Conversion 6-3 and 6-4 */ - if (pps->uniform_spacing_flag) { - - for (i = 0; i <= pps->num_tile_columns_minus1; i++) - col_width[i] = - ((i + 1) * PicWidthInCtbsY) / (pps->num_tile_columns_minus1 + 1) - - (i * PicWidthInCtbsY) / (pps->num_tile_columns_minus1 + 1); - - for (i = 0; i <= pps->num_tile_rows_minus1; i++) - row_height[i] = - ((i + 1) * PicHeightInCtbsY) / (pps->num_tile_rows_minus1 + 1) - - (i * PicHeightInCtbsY) / (pps->num_tile_rows_minus1 + 1); - - } else { - - col_width[pps->num_tile_columns_minus1] = PicWidthInCtbsY; - for (i = 0; i < pps->num_tile_columns_minus1; i++) { - col_width[i] = pps->column_width_minus1[i] + 1; - col_width[pps->num_tile_columns_minus1] -= col_width[i]; - } - - row_height[pps->num_tile_rows_minus1] = PicHeightInCtbsY; - for (i = 0; i < pps->num_tile_rows_minus1; i++) { - row_height[i] = pps->row_height_minus1[i] + 1; - row_height[pps->num_tile_rows_minus1] -= row_height[i]; - } - } - for (i = 0; i <= pps->num_tile_columns_minus1; i++) - pps->column_width_minus1[i] = col_width[i] - 1; - for (i = 0; i <= pps->num_tile_rows_minus1; i++) - pps->row_height_minus1[i] = row_height[i] - 1; - } - priv->parser_state |= GST_H265_VIDEO_STATE_GOT_PPS; return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 11716efdd3cf6a47e78a2f33245854a0ba6df995 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 26 Aug 2015 07:25:03 +0300 Subject: [PATCH 2119/3781] decoder: hevc: Fix the scaling list scan order The default scan order of scaling lists are up-right-diagonal as per hevc specification. Use the newly implemented uprightdiagonal_to_raster conversion codecparser APIs to get the the scaling_list values in raster order, which is what the VA intel driver requires. --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index a55f1efbe9..f8da6651db 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1148,7 +1148,7 @@ fill_iq_matrix_4x4 (VAIQMatrixBufferHEVC * iq_matrix, g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4) == 6); g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4[0]) == 16); for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList4x4); i++) { - gst_h265_quant_matrix_4x4_get_raster_from_zigzag (iq_matrix->ScalingList4x4 + gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (iq_matrix->ScalingList4x4 [i], scaling_list->scaling_lists_4x4[i]); } } @@ -1162,7 +1162,7 @@ fill_iq_matrix_8x8 (VAIQMatrixBufferHEVC * iq_matrix, g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8) == 6); g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8[0]) == 64); for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList8x8); i++) { - gst_h265_quant_matrix_8x8_get_raster_from_zigzag (iq_matrix->ScalingList8x8 + gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (iq_matrix->ScalingList8x8 [i], scaling_list->scaling_lists_8x8[i]); } } @@ -1176,7 +1176,7 @@ fill_iq_matrix_16x16 (VAIQMatrixBufferHEVC * iq_matrix, g_assert (G_N_ELEMENTS (iq_matrix->ScalingList16x16) == 6); g_assert (G_N_ELEMENTS (iq_matrix->ScalingList16x16[0]) == 64); for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList16x16); i++) { - gst_h265_quant_matrix_16x16_get_raster_from_zigzag + gst_h265_quant_matrix_16x16_get_raster_from_uprightdiagonal (iq_matrix->ScalingList16x16[i], scaling_list->scaling_lists_16x16[i]); } } @@ -1190,7 +1190,7 @@ fill_iq_matrix_32x32 (VAIQMatrixBufferHEVC * iq_matrix, g_assert (G_N_ELEMENTS (iq_matrix->ScalingList32x32) == 2); g_assert (G_N_ELEMENTS (iq_matrix->ScalingList32x32[0]) == 64); for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList32x32); i++) { - gst_h265_quant_matrix_32x32_get_raster_from_zigzag + gst_h265_quant_matrix_32x32_get_raster_from_uprightdiagonal (iq_matrix->ScalingList32x32[i], scaling_list->scaling_lists_32x32[i]); } } From ba8fcf54356d84ec5794a14892c263ae9a870ded Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 28 Aug 2015 23:43:47 +0300 Subject: [PATCH 2120/3781] vaapidecode: Always keep a copy of input codec state Currently we are sharing the input GstVideoCodecState with GstVaapiDecoder(gst-libs/gst/vaapi) by just doing ref and unref for each caps change. This is troublesome in many cases, for eg: if resoultion changes with in a singe stream. Because, when ever there is a resolution change, GstVideoDecoder will first change the Codec_state->caps fields with new resolution, but since we are using the same codecstate (ref) in gstvaapidecode.c, the caps check for input caps change will always fail. https://bugzilla.gnome.org/show_bug.cgi?id=753914 --- gst/vaapi/gstvaapidecode.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index cf4b67abc1..e40ee94b2e 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -138,6 +138,37 @@ gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, return; } +static GstVideoCodecState * +copy_video_codec_state (const GstVideoCodecState * in_state) +{ + GstVideoCodecState *state; + GstStructure *structure; + const GValue *codec_data; + + g_return_val_if_fail (in_state != NULL, NULL); + + state = g_slice_new0 (GstVideoCodecState); + state->ref_count = 1; + gst_video_info_init (&state->info); + if (G_UNLIKELY (!gst_video_info_from_caps (&state->info, in_state->caps))) + goto fail; + state->caps = gst_caps_copy (in_state->caps); + + structure = gst_caps_get_structure (state->caps, 0); + + codec_data = gst_structure_get_value (structure, "codec_data"); + if (codec_data && G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) + state->codec_data = GST_BUFFER (g_value_dup_boxed (codec_data)); + + return state; + +fail: + { + g_slice_free (GstVideoCodecState, state); + return NULL; + } +} + static gboolean gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, const GstVideoCodecState * new_state) @@ -152,8 +183,7 @@ gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, } if (new_state) - decode->input_state = gst_video_codec_state_ref - ((GstVideoCodecState *) new_state); + decode->input_state = copy_video_codec_state (new_state); else decode->input_state = NULL; From 6eba201f3252eba6a99ab7da7a4c662091a3e884 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Sat, 29 Aug 2015 00:18:57 +0300 Subject: [PATCH 2121/3781] vaapidecode: Rework the re-negotiation code to handle multi resoultion videos Delaying the pool re-negotiation untill we push all decoded (and queued) frames downstream. Otherwise for the multi-resolution videos, the GstVideoVideoMemory will be having wrong resolution and which leads to nasty behaviours, especially when using software renderers. sample media file: RAP_B_Bossen_1.bin case explained: The first SPS Nal will report resoultion of 448x256 and having crop rectangles to get the final resoultion 416x240. Starting from 25 th frame, the resolution will change to 416x240. But parser elements won't report this since the effective croped resolution is same in both cases. Here the core libgstvaapi will detect this through it's internal parsing and do all context/pool destory/reset stuffs. Also it will notify this change to plugins in advance. But if the plugin try to do re-negotiaion of pool immediately, this will not sync with the resolution of already decoded and queued frames and which will lead to failure in gst_video_frame_map() in downstream(if we use the software renderer). So we have to delay the pool renegotiation in vaapidecode, untill we push all decoded frames downstream. https://bugzilla.gnome.org/show_bug.cgi?id=753914 --- gst/vaapi/gstvaapidecode.c | 39 ++++++++++++++++++++++++++++++++------ gst/vaapi/gstvaapidecode.h | 1 + 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index e40ee94b2e..e0378b523a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -107,6 +107,8 @@ G_DEFINE_TYPE_WITH_CODE( GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) /* *INDENT-ON* */ +static gboolean +gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps); static gboolean gst_vaapidecode_update_src_caps (GstVaapiDecode * decode); static gboolean @@ -130,12 +132,10 @@ gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, if (!gst_vaapi_decode_input_state_replace (decode, codec_state)) return; - if (!gst_vaapidecode_update_src_caps (decode)) - return; - if (!gst_video_decoder_negotiate (vdec)) - return; - if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) - return; + if (!gst_vaapidecode_update_sink_caps (decode, decode->input_state->caps)) + return FALSE; + + decode->do_renego = TRUE; } static GstVideoCodecState * @@ -379,6 +379,31 @@ error_commit_buffer: } } +static gboolean +gst_vaapidecode_negotiate (GstVaapiDecode * decode) +{ + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); + + if (!decode->do_renego) + return TRUE; + + GST_DEBUG_OBJECT (decode, "Input codec state changed, doing renegotiation"); + + if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) + return FALSE; + if (!gst_vaapidecode_update_src_caps (decode)) + return FALSE; + if (!gst_video_decoder_negotiate (vdec)) + return FALSE; + if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) + return FALSE; + + decode->do_renego = FALSE; + + return TRUE; +} + static GstFlowReturn gst_vaapidecode_push_all_decoded_frames (GstVaapiDecode * decode) { @@ -397,6 +422,8 @@ gst_vaapidecode_push_all_decoded_frames (GstVaapiDecode * decode) return ret; break; case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: + if (!gst_vaapidecode_negotiate (decode)) + return GST_FLOW_ERROR; return GST_FLOW_OK; default: GST_VIDEO_DECODER_ERROR (vdec, 1, STREAM, DECODE, ("Decoding failed"), diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 48807ddaa5..13c57bc0fa 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -73,6 +73,7 @@ struct _GstVaapiDecode { GstVideoCodecState *input_state; volatile gboolean active; + volatile gboolean do_renego; }; struct _GstVaapiDecodeClass { From 32d1c5adff4c478a2b7aab0dc9a87de4839cd03b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 29 Aug 2015 00:27:05 +0300 Subject: [PATCH 2122/3781] vaapidecode: renegotiate if caps are not equal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The use of gst_caps_is_always_compatible() for this optimization may lead to false positives. It is better to stick to gst_caps_is_strictly_equal() to know if it is required a re-negotiation. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=750835 --- gst/vaapi/gstvaapidecode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index e0378b523a..07e8a8bd67 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -176,8 +176,13 @@ gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, if (decode->input_state) { if (new_state) { const GstCaps *curcaps = decode->input_state->caps; - if (gst_caps_is_always_compatible (curcaps, new_state->caps)) + /* If existing caps are equal of the new state, keep the + * existing state without renegotiating. */ + if (gst_caps_is_strictly_equal (curcaps, new_state->caps)) { + GST_DEBUG ("Ignoring new caps %" GST_PTR_FORMAT + " since are equal to current ones", new_state->caps); return FALSE; + } } gst_video_codec_state_unref (decode->input_state); } From b8068874d584828c98a4abdc620883d986ef0c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 28 Aug 2015 16:06:08 +0200 Subject: [PATCH 2123/3781] vaapidecode: compilation fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gst_vaapi_decoder_state_changed() returns void. This patch fixes the compilation where the toolchain uses restrictive flags as clang. Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 07e8a8bd67..acb8a440cf 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -133,7 +133,7 @@ gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, if (!gst_vaapi_decode_input_state_replace (decode, codec_state)) return; if (!gst_vaapidecode_update_sink_caps (decode, decode->input_state->caps)) - return FALSE; + return; decode->do_renego = TRUE; } From 9d8a0144239ab279156ae385d63bef6bfeabb80e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 28 Aug 2015 17:10:40 +0200 Subject: [PATCH 2124/3781] vaapidecode: remove unused variable Thus silence the compilation warnings. --- gst/vaapi/gstvaapidecode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index acb8a440cf..9590a35b92 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -126,7 +126,6 @@ gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, { GstVaapiDecode *const decode = GST_VAAPIDECODE (user_data); GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); g_assert (decode->decoder == decoder); From dbedad66df57babcdc6594e06f4897a57ef651f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 31 Aug 2015 13:11:54 +0200 Subject: [PATCH 2125/3781] vaapidecode: remove (another) unused variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapidecode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9590a35b92..43509d8f4a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -125,7 +125,6 @@ gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, const GstVideoCodecState * codec_state, gpointer user_data) { GstVaapiDecode *const decode = GST_VAAPIDECODE (user_data); - GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); g_assert (decode->decoder == decoder); From cc63452d723ab8631c39a2d61ad745eeb0d97d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 28 Aug 2015 17:12:12 +0200 Subject: [PATCH 2126/3781] decoder: hevc: remove unused functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=754250 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 25 +++++++---------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index f8da6651db..d3acdfb215 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -573,6 +573,12 @@ get_sps (GstVaapiDecoderH265 * decoder) return pi ? &pi->data.sps : NULL; } +/* VPS nal is not necessary to decode the base layers, so this is not + * needed at the moment. But in future we need this, especially when + * dealing with MVC and scalable layer decoding. + * See https://bugzilla.gnome.org/show_bug.cgi?id=754250 + */ +#if 0 /* Activate the supplied VPS */ static GstH265VPS * ensure_vps (GstVaapiDecoderH265 * decoder, GstH265VPS * vps) @@ -591,6 +597,7 @@ get_vps (GstVaapiDecoderH265 * decoder) GstVaapiParserInfoH265 *const pi = decoder->priv.active_vps; return pi ? &pi->data.vps : NULL; } +#endif /* Get number of reference frames to use */ static guint @@ -1342,24 +1349,6 @@ parse_sps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -static void -get_pic_width_height_in_ctbs (GstH265PPS * pps, - guint * PicWidthInCtbsY, guint * PicHeightInCtbsY) -{ - gint MinCbLog2SizeY, CtbLog2SizeY, MinCbSizeY, CtbSizeY; - GstH265SPS *sps = pps->sps; - - MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3; - CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size; - MinCbSizeY = 1 << MinCbLog2SizeY; - CtbSizeY = 1 << CtbLog2SizeY; - - *PicWidthInCtbsY = - ceil ((double) sps->pic_width_in_luma_samples / (double) CtbSizeY); - *PicHeightInCtbsY = - ceil ((double) sps->pic_height_in_luma_samples / (double) CtbSizeY); -} - static GstVaapiDecoderStatus parse_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) { From b0194a1dc58ab98023028b3622da4354346ff13d Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sat, 13 Jun 2015 01:39:31 +1000 Subject: [PATCH 2127/3781] multiview: initial attempt at stereo/multiview support Add support for marking caps and buffers for multiview or stereoscopic output. https://bugzilla.gnome.org/show_bug.cgi?id=750835 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 29 ++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 32 ++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 7 +++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 12 ++++++++- gst/vaapi/gstvaapidecode.c | 8 ++++++ gst/vaapi/gstvaapipluginutil.c | 7 +++++ 6 files changed, 93 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index d1bf5a19e0..72367d9f76 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -924,6 +924,35 @@ gst_vaapi_decoder_set_interlaced (GstVaapiDecoder * decoder, GST_VIDEO_INTERLACE_MODE_PROGRESSIVE)); } +#if GST_CHECK_VERSION(1,5,0) +void +gst_vaapi_decoder_set_multiview_mode (GstVaapiDecoder * decoder, + gint views, GstVideoMultiviewMode mv_mode, GstVideoMultiviewFlags mv_flags) +{ + GstVideoCodecState *const codec_state = decoder->codec_state; + GstVideoInfo *info = &codec_state->info; + + if (GST_VIDEO_INFO_VIEWS (info) != views || + GST_VIDEO_INFO_MULTIVIEW_MODE (info) != mv_mode || + GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) != mv_flags) { + const gchar *mv_mode_str = gst_video_multiview_mode_to_caps_string (mv_mode); + + GST_DEBUG ("Multiview mode changed to %s flags 0x%x views %d", + mv_mode_str, mv_flags, views); + GST_VIDEO_INFO_MULTIVIEW_MODE (info) = mv_mode; + GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) = mv_flags; + GST_VIDEO_INFO_VIEWS (info) = views; + + gst_caps_set_simple (codec_state->caps, "multiview-mode", + G_TYPE_STRING, mv_mode_str, + "multiview-flags", GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, mv_flags, + GST_FLAG_SET_MASK_EXACT, "views", G_TYPE_INT, views, NULL); + + notify_codec_state_changed (decoder); + } +} +#endif + gboolean gst_vaapi_decoder_ensure_context (GstVaapiDecoder * decoder, GstVaapiContextInfo * cip) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 7a90f4b291..3947a44504 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1443,11 +1443,41 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) } if (!priv->profile || (priv->profile != profile && priv->max_views == 1)) { - GST_DEBUG("profile changed"); + GST_DEBUG("profile changed to %x", profile); reset_context = TRUE; priv->profile = profile; } +#if GST_CHECK_VERSION(1,5,0) + /* Multiview flags only available in >= 1.5 */ + if (reset_context) { + switch (num_views) { + case 1: + /* Frame-packed mode details should be copied from the parser + * if we set NONE */ + gst_vaapi_decoder_set_multiview_mode (base_decoder, + num_views, GST_VIDEO_MULTIVIEW_MODE_NONE, + GST_VIDEO_MULTIVIEW_FLAGS_NONE); + break; + case 2: /* Assume stereo */ + if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { + GST_DEBUG ("Stereo profile - frame-by-frame output, %d views", num_views); + gst_vaapi_decoder_set_multiview_mode (base_decoder, + num_views, GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME, + GST_VIDEO_MULTIVIEW_FLAGS_NONE); + break; + } + /* non-stereo 2 views. Fall through */ + default: + GST_DEBUG ("Multiview profile - frame-by-frame output, %d views", num_views); + gst_vaapi_decoder_set_multiview_mode (base_decoder, + num_views, GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME, + GST_VIDEO_MULTIVIEW_FLAGS_NONE); + break; + } + } +#endif + chroma_type = gst_vaapi_utils_h264_get_chroma_type(sps->chroma_format_idc); if (!chroma_type) { GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 2ac56e8b05..3b7aa0e8ee 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -263,6 +263,13 @@ void gst_vaapi_decoder_set_interlaced (GstVaapiDecoder * decoder, gboolean interlaced); +#if GST_CHECK_VERSION(1,5,0) +G_GNUC_INTERNAL +void +gst_vaapi_decoder_set_multiview_mode (GstVaapiDecoder * decoder, + gint views, GstVideoMultiviewMode mv_mode, GstVideoMultiviewFlags mv_flags); +#endif + G_GNUC_INTERNAL gboolean gst_vaapi_decoder_ensure_context (GstVaapiDecoder * decoder, diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 36edd9dd30..c3a7c5fe98 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2450,7 +2450,6 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); encoder->idr_num = 0; - encoder->is_mvc = encoder->num_views > 1; for (i = 0; i < encoder->num_views; i++) { GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; ref_pool->max_reflist0_count = 1; @@ -2630,6 +2629,7 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, /* encoding views alternatively for MVC */ if (encoder->is_mvc) { + /* FIXME: Use first-in-bundle flag on buffers to reset view idx? */ if (frame) encoder->view_idx = frame->system_frame_number % encoder->num_views; else @@ -2779,6 +2779,7 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) { GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); GstVaapiEncoderStatus status; guint mb_width, mb_height; @@ -2792,6 +2793,15 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) encoder->config_changed = TRUE; } +#if GST_CHECK_VERSION(1,5,0) + /* Take number of MVC views from input caps if provided */ + if (GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME || + GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME) + encoder->num_views = GST_VIDEO_INFO_VIEWS (vip); +#endif + + encoder->is_mvc = encoder->num_views > 1; + status = ensure_profile_and_level (encoder); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 43509d8f4a..313e4049c6 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -326,6 +326,14 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, } GST_BUFFER_FLAG_SET (out_frame->output_buffer, out_flags); +#if GST_CHECK_VERSION(1,5,0) + /* First-in-bundle flag only appeared in 1.5 dev */ + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_FFB) { + GST_BUFFER_FLAG_SET (out_frame->output_buffer, + GST_VIDEO_BUFFER_FLAG_FIRST_IN_BUNDLE); + } +#endif + crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy); if (crop_rect) { GstVideoCropMeta *const crop_meta = diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ef3c6cffd6..997e8e0ca6 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -633,6 +633,13 @@ gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, vip->par_d = vi.par_d; vip->fps_n = vi.fps_n; vip->fps_d = vi.fps_d; + +#if GST_CHECK_VERSION(1,5,0) + GST_VIDEO_INFO_MULTIVIEW_MODE (vip) = + GST_VIDEO_INFO_MULTIVIEW_MODE (&vi); + GST_VIDEO_INFO_MULTIVIEW_FLAGS (vip) = + GST_VIDEO_INFO_MULTIVIEW_FLAGS (&vi); +#endif } /** From ac92e6d5bc997c2b0a43bf04adbc0395421c9588 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 4 Sep 2015 22:00:36 +0300 Subject: [PATCH 2128/3781] decoder: h265: Fix indentation --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index d3acdfb215..4bd947e0d1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1155,8 +1155,8 @@ fill_iq_matrix_4x4 (VAIQMatrixBufferHEVC * iq_matrix, g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4) == 6); g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4[0]) == 16); for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList4x4); i++) { - gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (iq_matrix->ScalingList4x4 - [i], scaling_list->scaling_lists_4x4[i]); + gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal + (iq_matrix->ScalingList4x4[i], scaling_list->scaling_lists_4x4[i]); } } @@ -1169,8 +1169,8 @@ fill_iq_matrix_8x8 (VAIQMatrixBufferHEVC * iq_matrix, g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8) == 6); g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8[0]) == 64); for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList8x8); i++) { - gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (iq_matrix->ScalingList8x8 - [i], scaling_list->scaling_lists_8x8[i]); + gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal + (iq_matrix->ScalingList8x8[i], scaling_list->scaling_lists_8x8[i]); } } From 8799a8044d0f0dae1c8f61310990b1222d1d5366 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 4 Sep 2015 22:02:55 +0300 Subject: [PATCH 2129/3781] decoder: hevc: Fix the picture addition in dpb() based on spec H265 v3 (04/2015) This fix is based on the V3 vesion of spec which was missing in older versions. When the current picture has PicOutputFlag equal to 1, for each picture in the DPB that is marked as "needed for output" and follows the current picture in output order, the associated variable PicLatencyCount is set equal to PicLatencyCount + 1 (C.5.2.3). https://bugzilla.gnome.org/show_bug.cgi?id=754010 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 4bd947e0d1..ba2ab395dd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -816,12 +816,14 @@ dpb_add (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) guint i = 0; /* C.5.2.3 */ - while (i < priv->dpb_count) { - GstVaapiFrameStore *const fs = priv->dpb[i]; - tmp_pic = fs->buffer; - if (tmp_pic->output_needed) - tmp_pic->pic_latency_cnt += 1; - i++; + if (picture->output_flag) { + while (i < priv->dpb_count) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + tmp_pic = fs->buffer; + if (tmp_pic->output_needed) + tmp_pic->pic_latency_cnt += 1; + i++; + } } if (picture->output_flag) { From e90ea99df1044c371060f18101f11e17fac3ec10 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 4 Sep 2015 22:11:10 +0300 Subject: [PATCH 2130/3781] decoder: hevc: Fix the dpb_add() based on C.5.2.3 Follow the spec as it is in C.5.2.3, add the decoded frame to dpb just after the PicLatencyCnt setting of existing dpb frames. https://bugzilla.gnome.org/show_bug.cgi?id=754010 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index ba2ab395dd..460c830138 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -826,6 +826,13 @@ dpb_add (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) } } + /* Create new frame store */ + fs = gst_vaapi_frame_store_new (picture); + if (!fs) + return FALSE; + gst_vaapi_frame_store_replace (&priv->dpb[priv->dpb_count++], fs); + gst_vaapi_frame_store_unref (fs); + if (picture->output_flag) { picture->output_needed = 1; picture->pic_latency_cnt = 0; @@ -843,13 +850,6 @@ dpb_add (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) && check_latency_cnt (decoder))) dpb_bump (decoder, picture); - /* Create new frame store */ - fs = gst_vaapi_frame_store_new (picture); - if (!fs) - return FALSE; - gst_vaapi_frame_store_replace (&priv->dpb[priv->dpb_count++], fs); - gst_vaapi_frame_store_unref (fs); - return TRUE; } From 3bd6185f9fb81ab258d5b85609dbf61c06005802 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 4 Sep 2015 22:19:55 +0300 Subject: [PATCH 2131/3781] decoder: hevc: Don't flush dpb for EOS/EOB nal Explicit flushing of dpb for EOS and EOB nal decoding is wrong, the dpb_add() itself will handle the flusing(if needed) of dpb for end of sequence and end of bitstream. https://bugzilla.gnome.org/show_bug.cgi?id=754010 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 460c830138..c308d27899 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1511,7 +1511,6 @@ decode_sequence_end (GstVaapiDecoderH265 * decoder) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; - dpb_flush (decoder); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From cf097e60c7eeb0b8edb581434819460d1c2fd9a3 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 11 Sep 2015 20:51:42 +0300 Subject: [PATCH 2132/3781] codecparsers: Update to gst-vaapi-branch commit f9e284b dae1a84: h264parse/h265parse: Fix negotiation crash 45a9f8a: codecparsers: h265 : Fix default scaling list values 28eaaf5: codecparsers: h265: Fix the selection of Active Ref Pic Set Signed-off-by: Sreerenj Balachandran --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 69550f1b97..f9e284b033 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 69550f1b97495f7095333d5c6f96bdf37db76ad5 +Subproject commit f9e284b0333ec1902e885884b0b213e83f38da14 From 6d0c2a8e23ee69292a9e107f0d60e378f6c623dd Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 15 Sep 2015 11:01:29 +0300 Subject: [PATCH 2133/3781] vaapidecode: proper numerator and denominator for forced latency framerate https://bugzilla.gnome.org/show_bug.cgi?id=755040 --- gst/vaapi/gstvaapidecode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 313e4049c6..6703672e1c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -263,8 +263,8 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) gint fps_d = GST_VIDEO_INFO_FPS_D (vi); if (fps_n <= 0 || fps_d <= 0) { GST_DEBUG_OBJECT (decode, "forcing 25/1 framerate for latency calculation"); - fps_n = 1; - fps_d = 25; + fps_n = 25; + fps_d = 1; } /* For parsing/preparation purposes we'd need at least 1 frame From f6ae00a6bb5d55b48fc2074b5abccad0bccee641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 11 Sep 2015 16:49:16 +0200 Subject: [PATCH 2134/3781] decoder: h264: initialize PPS's slice_group_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the GstVaapiParserInfoH264 is allocated, the memory is not initialized, so it contains random data. When gst_h264_parser_parse_pps() fails, the PPS structure keeps slice_group_id pointer uninitialized, leading to a segmentation fault when the memory is freed. This patch prevents this by initializing the slice_group_id before the PPS parsing. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=754845 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 3947a44504..55cb3962bc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1713,6 +1713,7 @@ parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) standard but that should get a default value anyway */ pps->slice_group_map_type = 0; pps->slice_group_change_rate_minus1 = 0; + pps->slice_group_id = NULL; result = gst_h264_parser_parse_pps(priv->parser, &pi->nalu, pps); if (result != GST_H264_PARSER_OK) From ccc9ce7101158d743fdbdcc387890036ecdf1933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 11 Sep 2015 16:35:30 +0200 Subject: [PATCH 2135/3781] build: verify for H264 MVC and H265 SPS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the H264 and H265 parsers look for MVC and SPS respectively, and the required symbols for those were added in GStreamer 1.5 If we try to compile in GStreamer < 1.4, without enabling the builtin codec parsers, the compilation fails, because the lack of those symbols. This patch verifies if the installed H264 and H265 parsers have those symbols. If they do not, the specific built in codec parsers are enabled and used. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=754845 --- configure.ac | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index f918dda98b..acf5600b76 100644 --- a/configure.ac +++ b/configure.ac @@ -320,7 +320,11 @@ AC_CACHE_CHECK([for H.264 parser], GstH264Profile profile = GST_H264_PROFILE_HIGH; slice_hdr.n_emulation_prevention_bytes = 0; vui_params.par_n = 0; - vui_params.par_d = 0;]])], + vui_params.par_d = 0; + GstH264SPS sps; + sps.extension.mvc.num_views_minus1 = 1; + GstH264NalUnit nalu; + nalu.extension_type = GST_H264_NAL_EXTENSION_MVC;]])], [ac_cv_have_gst_h264_parser="yes"], [ac_cv_have_gst_h264_parser="no"] ) @@ -389,7 +393,10 @@ AC_CACHE_CHECK([for H.265 parser], GstH265Profile profile = GST_H265_PROFILE_MAIN_STILL_PICTURE; slice_hdr.n_emulation_prevention_bytes = 0; vui_params.par_n = 0; - vui_params.par_d = 0;]])], + vui_params.par_d = 0; + GstH265SPS sps; + sps.crop_rect_x = 0; + sps.crop_rect_width = 0;]])], [ac_cv_have_gst_h265_parser="yes"], [ac_cv_have_gst_h265_parser="no"] ) From 2aaafe96b73ffc8a5c365cf418f248d01eb15570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 15 Sep 2015 16:53:31 +0200 Subject: [PATCH 2136/3781] build: link libgstvaapi_parse against codec parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GST_CODEC_PARSER_* variables are defined if builtin codec parsers are disabled when running configure. Right now, libgstcodecparsers links only to libgstvaapi, but libgstvaapi_parse need it if builtin codec parsers are disabled. This patch adds GST_CODEC_PARSER_* variables to libgstvaapi_parse compilation. If builtin codec parsers are enable, this variable is null, so it should work using libgstvaapi, as normal. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=754845 --- gst/vaapi/Makefile.am | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 709caa7808..95001bd377 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -210,14 +210,18 @@ libgstvaapi_parse_la_CFLAGS = \ $(GST_CFLAGS) \ $(GST_BASE_CFLAGS) \ $(GST_PLUGINS_BASE_CFLAGS) \ - $(GST_VIDEO_CFLAGS) + $(GST_VIDEO_CFLAGS) \ + $(GST_CODEC_PARSERS_CFLAGS) \ + $(NULL) libgstvaapi_parse_la_LIBADD = \ $(top_builddir)/gst-libs/gst/codecparsers/libgstvaapi-codecparsers.la \ $(GST_LIBS) \ $(GST_BASE_LIBS) \ $(GST_PLUGINS_BASE_LIBS) \ - $(GST_VIDEO_LIBS) -lgstpbutils-$(GST_PKG_VERSION) + $(GST_VIDEO_LIBS) -lgstpbutils-$(GST_PKG_VERSION) \ + $(GST_CODEC_PARSERS_LIBS) \ + $(NULL) libgstvaapi_parse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvaapi_parse_la_LIBTOOLFLAGS = --tag=disable-static From ac43e1c596933878711444e9eb1ea4719a799fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 14 Sep 2015 19:15:18 +0200 Subject: [PATCH 2137/3781] patches/videoparsers: h264parser: refresh patches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to avoid the creation of .orig files and break the distcheck target. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=754845 --- ...ompile-the-built-in-video-parsers-as-vaapip.patch | 10 +++++----- ...-default-to-byte-stream-nalu-format-Annex-B.patch | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch b/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch index c08a6eedd4..8e21c45d8f 100644 --- a/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch +++ b/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch @@ -1,7 +1,7 @@ -From a0cdb5443b5ae3176b217a08fb5107e77eea4113 Mon Sep 17 00:00:00 2001 +From e412ece68af9b1a4ce7309774b38ec548a2d709f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 28 Apr 2014 17:44:03 +0200 -Subject: [PATCH 1/3] plugins: compile the built-in video parsers as +Subject: [PATCH 1/6] plugins: compile the built-in video parsers as "vaapiparse" element. The built-in video parsers elements are built into a single DSO named @@ -12,7 +12,7 @@ vaapiparse_CODEC. 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 76f7686..9d588e2 100644 +index 915c2d7..96901e0 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c @@ -26,6 +26,7 @@ @@ -23,7 +23,7 @@ index 76f7686..9d588e2 100644 #include #include #include -@@ -120,7 +121,8 @@ gst_h264_parse_class_init (GstH264ParseClass * klass) +@@ -122,7 +123,8 @@ gst_h264_parse_class_init (GstH264ParseClass * klass) GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass); GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); @@ -34,5 +34,5 @@ index 76f7686..9d588e2 100644 gobject_class->finalize = gst_h264_parse_finalize; gobject_class->set_property = gst_h264_parse_set_property; -- -2.1.4 +2.5.1 diff --git a/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch b/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch index da8a1ae40e..486e98f82a 100644 --- a/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch +++ b/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch @@ -1,7 +1,7 @@ -From 652357e0da6528b0ff8a8e01782c84c032c9f342 Mon Sep 17 00:00:00 2001 +From 56df8be6dff017d32218bb3111e6ae6ff1316dec Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 26 May 2015 09:33:57 +0300 -Subject: [PATCH 3/3] h264parse: default to byte-stream/nalu format (Annex B). +Subject: [PATCH 3/6] h264parse: default to byte-stream/nalu format (Annex B). Always default to stream-format=byte-stream,alignment=nalu if avcC format was not detected. This is the natural stream format specified @@ -17,10 +17,10 @@ Signed-off-by: Sreerenj Balachandran 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 4060145..b5d2955 100644 +index f472a5e..f1ed269 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c -@@ -392,7 +392,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, +@@ -405,7 +405,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, if (!format) format = GST_H264_PARSE_FORMAT_BYTE; if (!align) @@ -30,7 +30,7 @@ index 4060145..b5d2955 100644 GST_DEBUG_OBJECT (h264parse, "selected format %s, alignment %s", gst_h264_parse_get_string (h264parse, TRUE, format), -@@ -2264,6 +2265,8 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) +@@ -2452,6 +2453,8 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) /* bytestream caps sanity checks */ if (format == GST_H264_PARSE_FORMAT_BYTE) { @@ -40,5 +40,5 @@ index 4060145..b5d2955 100644 if (codec_data_value != NULL) goto bytestream_caps_with_codec_data; -- -2.1.4 +2.5.1 From 0ec0dab21ca68c72d87cca73508bf9765a76e198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 14 Sep 2015 19:16:51 +0200 Subject: [PATCH 2138/3781] patches/videoparsers: h264parser: fix description and refresh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a typo in the patch description and refresh it in order to avoid the creation of .orig files and break the distcheck target. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=754845 --- ...-3D-video-support-for-GStreamer-1.5.patch} | 49 +++++++++---------- patches/videoparsers/series.frag | 2 +- 2 files changed, 25 insertions(+), 26 deletions(-) rename patches/videoparsers/{0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch => 0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch} (81%) diff --git a/patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch b/patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch similarity index 81% rename from patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch rename to patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch index b61a8ca6fa..c1335c664d 100644 --- a/patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch +++ b/patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch @@ -1,7 +1,7 @@ -From a711206aeb002e5e523ed6f4a045c2b2b7fb128e Mon Sep 17 00:00:00 2001 +From dbdc05803a63c4d530ea0c2932af2b35df5467b3 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 21 Jul 2015 12:13:18 +0300 -Subject: [PATCH 4/4] h264parse: Disable 3D video support for GStremaer < 1.5 +Subject: [PATCH 4/6] h264parse: Disable 3D video support for GStreamer < 1.5 All API/ABI changes for S3D/MVC are added in 1.5, backporting them to older verison is not recommended. @@ -13,30 +13,30 @@ Signed-off-by: Sreerenj Balachandran 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 98e9aa6..cd8cf2b 100644 +index f1ed269..7ed6db8 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c -@@ -215,9 +215,11 @@ gst_h264_parse_reset_stream_info (GstH264Parse * h264parse) +@@ -218,9 +218,11 @@ gst_h264_parse_reset_stream_info (GstH264Parse * h264parse) h264parse->have_pps = FALSE; h264parse->have_sps = FALSE; - + +#if GST_CHECK_VERSION(1,5,0) h264parse->multiview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE; h264parse->multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE; h264parse->first_in_bundle = TRUE; +#endif - + h264parse->align = GST_H264_PARSE_ALIGN_NONE; h264parse->format = GST_H264_PARSE_FORMAT_NONE; -@@ -562,6 +564,7 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) +@@ -571,6 +573,7 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) /* Additional messages that are not innerly useful to the * element but for debugging purposes */ case GST_H264_SEI_STEREO_VIDEO_INFO:{ +#if GST_CHECK_VERSION(1,5,0) GstVideoMultiviewMode mview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE; GstVideoMultiviewFlags mview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE; - -@@ -593,9 +596,11 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) + +@@ -602,9 +605,11 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) /* output caps need to be changed */ gst_h264_parse_update_src_caps (h264parse, NULL); } @@ -47,8 +47,8 @@ index 98e9aa6..cd8cf2b 100644 +#if GST_CHECK_VERSION(1,5,0) GstVideoMultiviewMode mview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE; GstVideoMultiviewFlags mview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE; - -@@ -684,6 +689,7 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) + +@@ -693,6 +698,7 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) /* output caps need to be changed */ gst_h264_parse_update_src_caps (h264parse, NULL); } @@ -56,27 +56,27 @@ index 98e9aa6..cd8cf2b 100644 break; } } -@@ -1746,9 +1752,11 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) +@@ -1762,9 +1768,11 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) gint width, height; GstClockTime latency; - + +#if GST_CHECK_VERSION(1,5,0) const gchar *caps_mview_mode = NULL; GstVideoMultiviewMode mview_mode = h264parse->multiview_mode; GstVideoMultiviewFlags mview_flags = h264parse->multiview_flags; +#endif - + fps_num = h264parse->fps_num; fps_den = h264parse->fps_den; -@@ -1780,6 +1788,7 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) +@@ -1796,6 +1804,7 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) } } - + +#if GST_CHECK_VERSION(1,5,0) /* Pass through or set output stereo/multiview config */ if (s && gst_structure_has_field (s, "multiview-mode")) { caps_mview_mode = gst_structure_get_string (s, "multiview-mode"); -@@ -1798,7 +1807,7 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) +@@ -1814,7 +1823,7 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, mview_flags, GST_FLAG_SET_MASK_EXACT, NULL); } @@ -84,15 +84,15 @@ index 98e9aa6..cd8cf2b 100644 +#endif gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL); - + diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h -index 58d818c..de9be02 100644 +index 617e616..1b89d31 100644 --- a/gst/vaapi/gsth264parse.h +++ b/gst/vaapi/gsth264parse.h -@@ -123,10 +123,12 @@ struct _GstH264Parse +@@ -124,10 +124,12 @@ struct _GstH264Parse GstClockTime pending_key_unit_ts; GstEvent *force_key_unit_event; - + +#if GST_CHECK_VERSION(1,5,0) /* Stereo / multiview info */ GstVideoMultiviewMode multiview_mode; @@ -100,8 +100,7 @@ index 58d818c..de9be02 100644 gboolean first_in_bundle; +#endif }; - - struct _GstH264ParseClass --- -2.1.4 + struct _GstH264ParseClass +-- +2.5.1 diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index 12469b6ce7..f2934372fa 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -4,6 +4,6 @@ videoparsers_patches_base = \ 0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch \ 0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch \ 0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ - 0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch \ + 0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch \ 0001-h265parse-include-gstvaapiparse.h.patch \ $(NULL) From ad463c8927de63c245dbda6cf1a5e599d87f093a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 14 Sep 2015 19:18:33 +0200 Subject: [PATCH 2139/3781] patches/videoparsers: h264parser: more API fences and refresh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add more API fences according with its version and refresh the patch. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=754845 --- ...uild-with-older-GStreamer-1.x-stacks.patch | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch index 4ad3162539..767a2545fd 100644 --- a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch +++ b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch @@ -1,40 +1,55 @@ -From cb4349b2f36194fbdd557eb11175d83fac144158 Mon Sep 17 00:00:00 2001 +From 48233a9eeb20d19fbc3f5550d8fecb4271be1822 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 26 Aug 2015 06:50:41 +0300 -Subject: [PATCH 2/2] h264parse: fix build with older GStreamer 1.x stacks +Subject: [PATCH 2/6] h264parse: fix build with older GStreamer 1.x stacks --- - gst/vaapi/gsth264parse.c | 2 ++ + gst/vaapi/gsth264parse.c | 9 +++++++++ gst/vaapi/gsth264parse.h | 1 + - 2 files changed, 3 insertions(+) + 2 files changed, 10 insertions(+) diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 8f3b225..a3d2952 100644 +index 96901e0..f472a5e 100644 --- a/gst/vaapi/gsth264parse.c +++ b/gst/vaapi/gsth264parse.c -@@ -165,8 +165,10 @@ gst_h264_parse_init (GstH264Parse * h264parse) +@@ -165,8 +165,12 @@ gst_h264_parse_init (GstH264Parse * h264parse) { h264parse->frame_out = gst_adapter_new (); gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h264parse), FALSE); +#if GST_CHECK_VERSION(1,3,0) GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h264parse)); ++#endif ++#if GST_CHECK_VERSION(1,5,0) GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (h264parse)); +#endif } - - + + +@@ -2216,8 +2220,13 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) + GST_TAG_VIDEO_CODEC, caps); + gst_caps_unref (caps); + ++#if GST_CHECK_VERSION(1,5,0) + gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE); + gst_tag_list_unref (taglist); ++#else ++ gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (h264parse), ++ gst_event_new_tag (taglist)); ++#endif + + /* also signals the end of first-frame processing */ + h264parse->sent_codec_tag = TRUE; diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h index 58d818c..617e616 100644 --- a/gst/vaapi/gsth264parse.h +++ b/gst/vaapi/gsth264parse.h @@ -27,6 +27,7 @@ - + #include #include +#include #include #include - --- -2.1.4 +-- +2.5.1 From 5524af5c0a2200d5322d0bd50adb37b70afad01b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 14 Sep 2015 19:19:56 +0200 Subject: [PATCH 2140/3781] patches/videoparsers: h265parser: rename patch keeping number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refresh the patch and rename it in order to keep the patch number. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=754845 --- ...h => 0005-h265parse-include-gstvaapiparse.h.patch} | 11 +++++------ patches/videoparsers/series.frag | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) rename patches/videoparsers/{0001-h265parse-include-gstvaapiparse.h.patch => 0005-h265parse-include-gstvaapiparse.h.patch} (80%) diff --git a/patches/videoparsers/0001-h265parse-include-gstvaapiparse.h.patch b/patches/videoparsers/0005-h265parse-include-gstvaapiparse.h.patch similarity index 80% rename from patches/videoparsers/0001-h265parse-include-gstvaapiparse.h.patch rename to patches/videoparsers/0005-h265parse-include-gstvaapiparse.h.patch index 613b875c9b..75bc8d5995 100644 --- a/patches/videoparsers/0001-h265parse-include-gstvaapiparse.h.patch +++ b/patches/videoparsers/0005-h265parse-include-gstvaapiparse.h.patch @@ -1,14 +1,14 @@ -From a205193cffee9405bc9013416b15d8d1499be6bb Mon Sep 17 00:00:00 2001 +From 06ab8f433c02590b63e8afdf394a2a1caf570fad Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 16 Apr 2015 18:04:53 +0300 -Subject: [PATCH] h265parse: include gstvaapiparse.h +Subject: [PATCH 5/6] h265parse: include gstvaapiparse.h --- gst/vaapi/gsth265parse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gsth265parse.c b/gst/vaapi/gsth265parse.c -index 2d7b997..5942d41 100644 +index d649681..5f65ab6 100644 --- a/gst/vaapi/gsth265parse.c +++ b/gst/vaapi/gsth265parse.c @@ -22,6 +22,7 @@ @@ -19,7 +19,7 @@ index 2d7b997..5942d41 100644 #include #include #include -@@ -101,7 +102,7 @@ gst_h265_parse_class_init (GstH265ParseClass * klass) +@@ -100,7 +101,7 @@ gst_h265_parse_class_init (GstH265ParseClass * klass) GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass); GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); @@ -29,5 +29,4 @@ index 2d7b997..5942d41 100644 gobject_class->finalize = gst_h265_parse_finalize; gobject_class->set_property = gst_h265_parse_set_property; -- -1.9.1 - +2.5.1 diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index f2934372fa..acc8a2fac9 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -5,5 +5,5 @@ videoparsers_patches_base = \ 0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch \ 0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ 0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch \ - 0001-h265parse-include-gstvaapiparse.h.patch \ + 0005-h265parse-include-gstvaapiparse.h.patch \ $(NULL) From d20ae2667305b603491f2eaa192797d811363d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 14 Sep 2015 19:21:08 +0200 Subject: [PATCH 2141/3781] patches/videoparsers: h265parser: more API fences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add more API fences according with its version and refresh the patch. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=754845 --- ...65parse-fix-build-with-GStreamer-1.5.patch | 48 +++++++++++++++++++ patches/videoparsers/series.frag | 1 + 2 files changed, 49 insertions(+) create mode 100644 patches/videoparsers/0006-h265parse-fix-build-with-GStreamer-1.5.patch diff --git a/patches/videoparsers/0006-h265parse-fix-build-with-GStreamer-1.5.patch b/patches/videoparsers/0006-h265parse-fix-build-with-GStreamer-1.5.patch new file mode 100644 index 0000000000..0bf8617246 --- /dev/null +++ b/patches/videoparsers/0006-h265parse-fix-build-with-GStreamer-1.5.patch @@ -0,0 +1,48 @@ +From aaf9569d096392d73f45bcf9973d58b90a7ecd27 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= + +Date: Mon, 14 Sep 2015 19:11:59 +0200 +Subject: [PATCH 6/6] h265parse: fix build with GStreamer < 1.5 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Víctor Manuel Jáquez Leal +--- + gst/vaapi/gsth265parse.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/gst/vaapi/gsth265parse.c b/gst/vaapi/gsth265parse.c +index 5f65ab6..35b0812 100644 +--- a/gst/vaapi/gsth265parse.c ++++ b/gst/vaapi/gsth265parse.c +@@ -141,8 +141,12 @@ gst_h265_parse_init (GstH265Parse * h265parse) + { + h265parse->frame_out = gst_adapter_new (); + gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h265parse), FALSE); ++#if GST_CHECK_VERSION(1,3,0) + GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h265parse)); ++#endif ++#if GST_CHECK_VERSION(1,5,0) + GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (h265parse)); ++#endif + } + + +@@ -1774,8 +1778,14 @@ gst_h265_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) + GST_TAG_VIDEO_CODEC, caps); + gst_caps_unref (caps); + ++#if GST_CHECK_VERSION(1,5,0) + gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE); + gst_tag_list_unref (taglist); ++#else ++ gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (h265parse), ++ gst_event_new_tag (taglist)); ++#endif ++ + + /* also signals the end of first-frame processing */ + h265parse->sent_codec_tag = TRUE; +-- +2.5.1 diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index acc8a2fac9..5d06453a84 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -6,4 +6,5 @@ videoparsers_patches_base = \ 0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ 0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch \ 0005-h265parse-include-gstvaapiparse.h.patch \ + 0006-h265parse-fix-build-with-GStreamer-1.5.patch \ $(NULL) From 5ab4c15754ab487fde03a7bc60ab311ba63e0d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 23 Sep 2015 12:13:41 +0200 Subject: [PATCH 2142/3781] vaapidecode: simplify copy of GstVideoCodecState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapidecode.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6703672e1c..438b954036 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -140,31 +140,16 @@ static GstVideoCodecState * copy_video_codec_state (const GstVideoCodecState * in_state) { GstVideoCodecState *state; - GstStructure *structure; - const GValue *codec_data; g_return_val_if_fail (in_state != NULL, NULL); state = g_slice_new0 (GstVideoCodecState); state->ref_count = 1; - gst_video_info_init (&state->info); - if (G_UNLIKELY (!gst_video_info_from_caps (&state->info, in_state->caps))) - goto fail; + state->info = in_state->info; state->caps = gst_caps_copy (in_state->caps); - - structure = gst_caps_get_structure (state->caps, 0); - - codec_data = gst_structure_get_value (structure, "codec_data"); - if (codec_data && G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) - state->codec_data = GST_BUFFER (g_value_dup_boxed (codec_data)); + state->codec_data = gst_buffer_copy_deep (in_state->codec_data); return state; - -fail: - { - g_slice_free (GstVideoCodecState, state); - return NULL; - } } static gboolean From 52b94556ed08b07354f15bd2906b59b197cbd225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 23 Sep 2015 16:02:46 +0200 Subject: [PATCH 2143/3781] gstcompat: add gst_buffer_copy_deep() if gst < 1.5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gst_buffer_copy_deep() was added in GStreamer 1.5. If want to use it we should add an implementation if gstreamer-vaapi is linked to previous versions. Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstcompat.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/gst/vaapi/gstcompat.h b/gst/vaapi/gstcompat.h index c953783fd1..17bd3e6e08 100644 --- a/gst/vaapi/gstcompat.h +++ b/gst/vaapi/gstcompat.h @@ -25,4 +25,27 @@ #include "gst/vaapi/sysdeps.h" +#if !GST_CHECK_VERSION (1,5,0) +static inline GstBuffer * +gst_buffer_copy_deep (const GstBuffer * buffer) +{ + GstBuffer *copy; + + g_return_val_if_fail (buffer != NULL, NULL); + + copy = gst_buffer_new (); + + if (!gst_buffer_copy_into (copy, (GstBuffer *) buffer, + GST_BUFFER_COPY_ALL | GST_BUFFER_COPY_DEEP, 0, -1)) + gst_buffer_replace (©, NULL); + +#if GST_CHECK_VERSION (1,4,0) + if (copy) + GST_BUFFER_FLAG_UNSET (copy, GST_BUFFER_FLAG_TAG_MEMORY); +#endif + + return copy; +} +#endif + #endif /* GST_COMPAT_H */ From 0681da967064e15fa5224c1e04a13ac3c5de23cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 28 Sep 2015 14:57:33 +0200 Subject: [PATCH 2144/3781] build: allow builds against GStreamer 1.7.x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/configure.ac b/configure.ac index acf5600b76..6c94f94967 100644 --- a/configure.ac +++ b/configure.ac @@ -17,6 +17,7 @@ m4_define([gst_vaapi_lt_current], [7]) m4_define([gst2_vaapi_lt_current_bias], [4]) m4_define([gst4_vaapi_lt_current_bias], [5]) m4_define([gst6_vaapi_lt_current_bias], [6]) +m4_define([gst8_vaapi_lt_current_bias], [7]) m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [0]) @@ -34,6 +35,9 @@ m4_define([gst14_plugins_bad_version], [1.3.0]) m4_define([gst16_version], [1.5.0]) m4_define([gst16_plugins_base_version], [1.5.0]) m4_define([gst16_plugins_bad_version], [1.5.0]) +m4_define([gst18_version], [1.7.0]) +m4_define([gst18_plugins_base_version], [1.7.0]) +m4_define([gst18_plugins_bad_version], [1.7.0]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) @@ -210,6 +214,11 @@ case $GST_API_VERSION in GST_PLUGINS_BASE_VERSION_REQUIRED=gst16_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst16_plugins_bad_version ;; +1.[[7-8]]) + GST_VERSION_REQUIRED=gst18_version + GST_PLUGINS_BASE_VERSION_REQUIRED=gst18_plugins_base_version + GST_PLUGINS_BAD_VERSION_REQUIRED=gst18_plugins_bad_version + ;; *) AC_MSG_ERROR([unsupported GStreamer API version $GST_API_VERSION]) ;; @@ -451,6 +460,7 @@ case $GST_API_VERSION in 1.2) lt_bias=gst2_vaapi_lt_current_bias;; 1.4) lt_bias=gst4_vaapi_lt_current_bias;; 1.[[5-6]]) lt_bias=gst6_vaapi_lt_current_bias;; +1.[[7-8]]) lt_bias=gst8_vaapi_lt_current_bias;; esac GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - "$lt_bias"` AC_SUBST(GST_VAAPI_MAJOR_VERSION) From 087e549c1e082545d0bc86fd202d200ab57e54fd Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 12 Oct 2015 14:13:03 +0300 Subject: [PATCH 2145/3781] vaapidecode: Fix buffer copy assertion Don't try to copy the NULL buffer-codec_data. --- gst/vaapi/gstvaapidecode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 438b954036..2dc7c6cac8 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -147,7 +147,8 @@ copy_video_codec_state (const GstVideoCodecState * in_state) state->ref_count = 1; state->info = in_state->info; state->caps = gst_caps_copy (in_state->caps); - state->codec_data = gst_buffer_copy_deep (in_state->codec_data); + if (in_state->codec_data) + state->codec_data = gst_buffer_copy_deep (in_state->codec_data); return state; } From e2c4b087419264bb86bb6967c28e1862523d306d Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 15 Oct 2015 10:59:08 +0300 Subject: [PATCH 2146/3781] configure: mark support for GStreamer 1.2 as obsolete. Support for GStreamer 1.2 is obsolete. i.e. it is no longer supported. Our goal is to support the last two stable versions of GStreamer which are 1.4 and 1.6 at the moment. We still keep the 1.2 specific codes until the next gstreamer-vaapi-0.7 release and will get rid of those in 0.8. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6c94f94967..2c567d59bd 100644 --- a/configure.ac +++ b/configure.ac @@ -243,7 +243,7 @@ AC_DEFINE_UNQUOTED([GST_PKG_VERSION_S], ["$GST_PKG_VERSION"], [Defined to the string representation of GStreamer API version]) if test "$GST_API_VERSION" = "1.2"; then - AC_MSG_WARN([support for GStreamer 1.2 is deprecated, please upgrade]) + AC_MSG_WARN([support for GStreamer 1.2 is obsolete, and will be removed]) fi dnl GStreamer Core From f06798aa8a5177875fc4eade8f4c35a8a5526a0e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 15 Oct 2015 19:00:26 +0300 Subject: [PATCH 2147/3781] libvpx: Update the submodule to libvpx-1.4.0 libvpx git commit: c74bf6d889992c3cabe017ec353ca85c323107cd --- ext/libvpx/upstream | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/libvpx/upstream b/ext/libvpx/upstream index 2e88f2f2ec..c74bf6d889 160000 --- a/ext/libvpx/upstream +++ b/ext/libvpx/upstream @@ -1 +1 @@ -Subproject commit 2e88f2f2ec777259bda1714e72f1ecd2519bceb5 +Subproject commit c74bf6d889992c3cabe017ec353ca85c323107cd From a8c973e9600d0b9bd805fc33cabc5cc50ae68197 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 15 Oct 2015 19:20:21 +0300 Subject: [PATCH 2148/3781] build: Remove disable-md5 option for libvpx build The configure option --disable-md5 was provided in libvpx-1.3.0 which has been removed in 1.4.0. --- ext/libvpx/Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/libvpx/Makefile.am b/ext/libvpx/Makefile.am index 42db5493dd..cdb5ffaa8a 100644 --- a/ext/libvpx/Makefile.am +++ b/ext/libvpx/Makefile.am @@ -98,7 +98,6 @@ vpx.configure.stamp: --$(VP9_DECODER)-vp9-decoder \ --$(VP9_ENCODER)-vp9-encoder \ --enable-runtime-cpu-detect \ - --disable-md5 \ --disable-examples \ --disable-docs \ --disable-unit-tests && \ From 3a2430c78902181325632919c3bc383d44c40048 Mon Sep 17 00:00:00 2001 From: Lim Siew Hoon Date: Fri, 16 Oct 2015 20:21:50 +0800 Subject: [PATCH 2149/3781] build: check for patch and fix yasm check Add configure checking for GNU patch tools and fixed configure checking YASM to correct sequence. Signed-off-by: Lim Siew Hoon https://bugzilla.gnome.org/show_bug.cgi?id=756690 --- configure.ac | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 2c567d59bd..1c538a3827 100644 --- a/configure.ac +++ b/configure.ac @@ -96,12 +96,6 @@ AC_ARG_VAR([GIT], [Path to git program, if any]) AC_PATH_PROG([GIT], [git]) AM_CONDITIONAL([HAVE_GIT], [test -n "$GIT"]) -AC_ARG_VAR([YASM], [Path to yasm program, if any]) -AC_PATH_PROG([YASM], [yasm]) -if test -z "$YASM" -a "$enable_builtin_libvpx" = "yes"; then - AC_MSG_ERROR([yasm is needed to build libvpx sources]) -fi - dnl Initialize libtool LT_PREREQ([2.2]) LT_INIT @@ -156,6 +150,22 @@ AC_ARG_WITH([glapi], [build with the specified OpenGL APIs @<:@default=default_glapi@:>@]), [GLAPI="$with_glapi"], [GLAPI=default_glapi]) + +dnl Check fr YASM +AC_ARG_VAR([YASM], [Path to yasm program, if any]) +AC_PATH_PROG([YASM], [yasm]) +if test -z "$YASM" -a "$enable_builtin_libvpx" = "yes"; then + AC_MSG_ERROR([yasm is needed to build libvpx sources]) +fi + +dnl Check for PATCH +AC_ARG_VAR([PATCH], [Path to patch program, if any]) +AC_PATH_PROG([PATCH], [patch]) +if test -z "$PATCH" -a "$enable_builtin_videoparsers" = "yes"; then + AC_MSG_ERROR([patch is needed to apply patches for built videoparsers +sources]) +fi + dnl Check for basic libraries AC_CHECK_LIB(m, tan) From 45487fe87cc4dcc0c319701af0516ef6973794ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 14 Oct 2015 20:22:43 +0200 Subject: [PATCH 2150/3781] vaapidecode: set format before decide allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a regression from commit 3d8e5e. It was expected the buffer pool allocation occur before the caps negotiation, but it is not. This patch fixes this regression: the caps negotiation is done regardless the allocation query from downstream. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=756686 --- gst/vaapi/gstvaapidecode.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 2dc7c6cac8..28302777b1 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -213,12 +213,9 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) switch (feature) { #if (USE_GLX || USE_EGL) case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: - if (decode->has_texture_upload_meta) features = gst_caps_features_new (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); - else - format = GST_VIDEO_FORMAT_I420; break; #endif #if GST_CHECK_VERSION(1,5,0) From 6d9f31e305d2c395bafd11c07d5a015f92bcd1b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 14 Oct 2015 20:30:30 +0200 Subject: [PATCH 2151/3781] vaapidecode: use caps to check the features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of calling gst_vaapi_find_preferred_caps_feature(), which is expensive, we check the caps from the allocation query, to check the negotiated feature. In order to do this verification a new utility function has been implemented: gst_vaapi_caps_feature_contains(). As this new function shared its logic with gst_caps_has_vaapi_surface(), both have been refactorized. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=756686 --- gst/vaapi/gstvaapidecode.c | 13 +++------ gst/vaapi/gstvaapipluginutil.c | 52 +++++++++++++++++++++------------- gst/vaapi/gstvaapipluginutil.h | 5 ++++ 3 files changed, 41 insertions(+), 29 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 28302777b1..9835fbeed3 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -576,20 +576,15 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstCaps *caps = NULL; GstVideoCodecState *state; - GstVaapiCapsFeature feature; - GstVideoFormat out_format; gst_query_parse_allocation (query, &caps, NULL); - - feature = - gst_vaapi_find_preferred_caps_feature (GST_VIDEO_DECODER_SRC_PAD (vdec), - GST_VIDEO_FORMAT_ENCODED, &out_format); decode->has_texture_upload_meta = FALSE; #if (USE_GLX || USE_EGL) decode->has_texture_upload_meta = - (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) && gst_query_find_allocation_meta (query, - GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL) && + gst_vaapi_caps_feature_contains (caps, + GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); #endif /* Update src caps if feature is not handled downstream */ @@ -599,7 +594,7 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) gst_video_codec_state_unref (state); return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), - query, feature); + query, 0); } static inline gboolean diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 997e8e0ca6..2071adc215 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -590,32 +590,44 @@ gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip) return TRUE; } +static gboolean +_gst_caps_has_feature (const GstCaps * caps, const gchar * feature) +{ + guint i; + + for (i = 0; i < gst_caps_get_size (caps); i++) { + GstCapsFeatures *const features = gst_caps_get_features (caps, i); + /* Skip ANY features, we need an exact match for correct evaluation */ + if (gst_caps_features_is_any (features)) + continue; + if (gst_caps_features_contains (features, feature)) + return TRUE; + } + + return FALSE; +} + +gboolean +gst_vaapi_caps_feature_contains (const GstCaps * caps, GstVaapiCapsFeature feature) +{ + const gchar *feature_str; + + g_return_val_if_fail (caps != NULL, FALSE); + + feature_str = gst_vaapi_caps_feature_to_string (feature); + if (!feature_str) + return FALSE; + + return _gst_caps_has_feature (caps, feature_str); +} + /* Checks whether the supplied caps contain VA surfaces */ gboolean gst_caps_has_vaapi_surface (GstCaps * caps) { - gboolean found_caps = FALSE; - guint i, num_structures; - g_return_val_if_fail (caps != NULL, FALSE); - num_structures = gst_caps_get_size (caps); - if (num_structures < 1) - return FALSE; - - for (i = 0; i < num_structures && !found_caps; i++) { - GstCapsFeatures *const features = gst_caps_get_features (caps, i); - -#if GST_CHECK_VERSION(1,3,0) - /* Skip ANY features, we need an exact match for correct evaluation */ - if (gst_caps_features_is_any (features)) - continue; -#endif - - found_caps = gst_caps_features_contains (features, - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE); - } - return found_caps; + return _gst_caps_has_feature (caps, GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE); } void diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 94050fb04a..4ca82253ea 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -91,6 +91,11 @@ G_GNUC_INTERNAL const gchar * gst_vaapi_caps_feature_to_string (GstVaapiCapsFeature feature); +G_GNUC_INTERNAL +gboolean +gst_vaapi_caps_feature_contains (const GstCaps * caps, + GstVaapiCapsFeature feature); + /* Helpers to handle interlaced contents */ # define GST_CAPS_INTERLACED_MODES \ "interlace-mode = (string){ progressive, interleaved, mixed }" From 361f55be31b1e5fdb01fd5eac9e3ccd584766f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 15 Oct 2015 18:18:36 +0200 Subject: [PATCH 2152/3781] vaapidecode: decide allocation doesn't update srccaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The received caps query will bring the already negotiated caps, so they are not expected to change. This patch removes this verification which is dead code path. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=756686 --- gst/vaapi/gstvaapidecode.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9835fbeed3..f142b0ab7b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -575,7 +575,6 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstCaps *caps = NULL; - GstVideoCodecState *state; gst_query_parse_allocation (query, &caps, NULL); decode->has_texture_upload_meta = FALSE; @@ -587,12 +586,6 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); #endif - /* Update src caps if feature is not handled downstream */ - state = gst_video_decoder_get_output_state (vdec); - if (!gst_caps_is_always_compatible (caps, state->caps)) - gst_vaapidecode_update_src_caps (decode); - gst_video_codec_state_unref (state); - return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), query, 0); } From b76f4825c5e57609b8179f886c371f33bdd6b138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 16 Oct 2015 15:55:40 +0200 Subject: [PATCH 2153/3781] vaapidecode: relax guards for memory:VASurface capsfeature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Though caps features are supported since GStreamer 1.2, there are some issues with the features caps negotiation in that version. Nonetheless, those issues are fixed in GStreamer 1.4. So, the memoy:VASurface caps feature negotiation is relaxed for GStreamer 1.4. The guard is the same as in vaapisink's caps template. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=756686 --- gst/vaapi/gstvaapidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f142b0ab7b..3c944de136 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -218,7 +218,7 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); break; #endif -#if GST_CHECK_VERSION(1,5,0) +#if GST_CHECK_VERSION(1,3,1) case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE: features = gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL); From 486ad0ba5c8ec68e3978d66aecb21d2efd764753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 4 Nov 2015 15:37:34 +0100 Subject: [PATCH 2154/3781] configure.ac: don't use an undefined variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the environment lacks of gstreamer development packages, this error will be reported to the user: "gstreamer- was not found" This is because we are using an undefined variable in the printed message. The fix simple changes the variable for the hard-coded string "1.0". Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757283 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 1c538a3827..f4f1ef0448 100644 --- a/configure.ac +++ b/configure.ac @@ -200,7 +200,7 @@ if $PKG_CONFIG --exists "gstreamer-1.0"; then GST_PKG_VERSION="1.0" fi if test -z "$GST_PKG_VERSION"; then - AC_MSG_ERROR([gstreamer-$GST_PKG_VERSION was not found]) + AC_MSG_ERROR([gstreamer-1.0 was not found]) fi AC_MSG_RESULT([$GST_API_VERSION]) From ba33154dc406c9284b81f7a0cf6a0a218b2c0b0a Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 6 Nov 2015 12:38:46 +0200 Subject: [PATCH 2155/3781] codecparsers: Update to gst-vaapi-branch commit ac5dc1a ac5dc1a: codecparsers: vp9: Add vp9 codec parser e7d9217: codecparser: h264: initialize parsing structures 403d400: codecparser: h265: initialize parsing structures --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index f9e284b033..ac5dc1ad65 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit f9e284b0333ec1902e885884b0b213e83f38da14 +Subproject commit ac5dc1ad659f0e3730215b063be6c3b906a00527 From 279f494bc0f9eec135f76d484891991d9cbec483 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 6 Nov 2015 14:24:08 +0200 Subject: [PATCH 2156/3781] VP9: Allow building vp9 codecparser internally --- configure.ac | 21 +++++++++++++++++++++ ext/Makefile.am | 4 ++++ gst-libs/gst/codecparsers/Makefile.am | 5 +++++ 3 files changed, 30 insertions(+) diff --git a/configure.ac b/configure.ac index f4f1ef0448..433d3bbc97 100644 --- a/configure.ac +++ b/configure.ac @@ -291,6 +291,7 @@ if test "$enable_builtin_codecparsers" = "yes"; then ac_cv_have_gst_jpeg_parser="no" ac_cv_have_gst_vp8_parser="no" ac_cv_have_gst_h265_parser="no" + ac_cv_have_gst_vp9_parser="no" else PKG_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) @@ -397,6 +398,26 @@ AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_VP8], [test "$ac_cv_have_gst_vp8_parser" != "yes"]) AM_CONDITIONAL([USE_BUILTIN_LIBVPX], [test "$enable_builtin_libvpx" = "yes"]) +dnl ... VP9 parser, with required extensions +AC_CACHE_CHECK([for VP9 parser], + ac_cv_have_gst_vp9_parser, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[GstVp9FrameHdr frame_hdr;]])], + [ac_cv_have_gst_vp9_parser="yes"], + [ac_cv_have_gst_vp9_parser="no"] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +]) +AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_VP9], + [test "$ac_cv_have_gst_vp9_parser" != "yes"]) + dnl ... H.265 parser, with the required extensions AC_CACHE_CHECK([for H.265 parser], ac_cv_have_gst_h265_parser, [ diff --git a/ext/Makefile.am b/ext/Makefile.am index 537e18f52f..7a9a147487 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -18,6 +18,8 @@ codecparsers_source_c = \ parserutils.c \ vp8utils.c \ gsth265parser.c \ + gstvp9parser.c \ + vp9utils.c \ $(NULL) EXTRA_DIST += $(codecparsers_source_c:%.c=$(codecparsers_srcdir)/%.c) @@ -35,6 +37,8 @@ codecparsers_source_h = \ parserutils.h \ vp8utils.h \ gsth265parser.h \ + gstvp9parser.h \ + vp9utils.h \ $(NULL) EXTRA_DIST += $(codecparsers_source_h:%.h=$(codecparsers_srcdir)/%.h) diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index d164df63aa..9f07940218 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -62,6 +62,11 @@ gen_source_h += dboolhuff.h endif endif +if USE_LOCAL_CODEC_PARSERS_VP9 +gen_source_c += gstvp9parser.c vp9utils.c +gen_source_h += gstvp9parser.h vp9utils.h +endif + if USE_LOCAL_CODEC_PARSERS_H265 gen_source_c += gsth265parser.c gen_source_h += gsth265parser.h From 608a045ba1fb46930e62b90063d7a4a57cc4c6c6 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 6 Nov 2015 14:39:22 +0200 Subject: [PATCH 2157/3781] VP9: build: Check availability of vp9 decoder APIs --- configure.ac | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/configure.ac b/configure.ac index 433d3bbc97..a8996dae93 100644 --- a/configure.ac +++ b/configure.ac @@ -829,6 +829,39 @@ AC_CACHE_CHECK([for VP8 decoding API], LIBS="$saved_LIBS" ]) +dnl Check for va_dec_vp9.h header +saved_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" +AC_CHECK_HEADERS([va/va_dec_vp9.h], [], [], [#include ]) +CPPFLAGS="$saved_CPPFLAGS" + +dnl Check for VP9 decoding API (0.37+) +USE_VP9_DECODER=0 +AC_CACHE_CHECK([for VP9 decoding API], + ac_cv_have_vp9_decoding_api, [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #ifdef HAVE_VA_VA_DEC_VP9_H + #include + #endif + ]], + [[VADecPictureParameterBufferVP9 pic_param; + VASliceParameterBufferVP9 slice_param; + VASegmentParameterVP9 seg_param; + slice_param.slice_data_offset = 0; + slice_param.slice_data_flag = 0;]])], + [ac_cv_have_vp9_decoding_api="yes" USE_VP9_DECODER=1], + [ac_cv_have_vp9_decoding_api="no"] + ) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" +]) + dnl Check for va_dec_hevc.h header saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" @@ -1039,6 +1072,10 @@ AC_DEFINE_UNQUOTED(USE_VP8_DECODER, $USE_VP8_DECODER, [Defined to 1 if VP8 decoder is used]) AM_CONDITIONAL(USE_VP8_DECODER, test $USE_VP8_DECODER -eq 1) +AC_DEFINE_UNQUOTED(USE_VP9_DECODER, $USE_VP9_DECODER, + [Defined to 1 if VP9 decoder is used]) +AM_CONDITIONAL(USE_VP9_DECODER, test $USE_VP9_DECODER -eq 1) + AC_DEFINE_UNQUOTED(USE_HEVC_DECODER, $USE_HEVC_DECODER, [Defined to 1 if HEVC decoder is used]) AM_CONDITIONAL(USE_HEVC_DECODER, test $USE_HEVC_DECODER -eq 1) From a3d63724dd4634c537e075475ff089457bc5669d Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 6 Nov 2015 14:57:00 +0200 Subject: [PATCH 2158/3781] VP9: gstvaapiprofile: Add profile definitions --- gst-libs/gst/vaapi/gstvaapiprofile.c | 6 ++++++ gst-libs/gst/vaapi/gstvaapiprofile.h | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 731bee3674..650bea5aaf 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -67,6 +67,7 @@ static const GstVaapiCodecMap gst_vaapi_codecs[] = { { GST_VAAPI_CODEC_JPEG, "jpeg" }, { GST_VAAPI_CODEC_VP8, "vp8" }, { GST_VAAPI_CODEC_H265, "h265" }, + { GST_VAAPI_CODEC_VP9, "vp9" }, { 0, } }; @@ -159,6 +160,11 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_H265_MAIN10, VAProfileHEVCMain10, "video/x-h265", "main10" }, +#endif +#if VA_CHECK_VERSION(0,38,0) + { GST_VAAPI_PROFILE_VP9, VAProfileVP9Profile0, + "video/x-vp9", NULL + }, #endif { 0, } }; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 00e07691fa..8bc340e2e0 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -40,6 +40,7 @@ G_BEGIN_DECLS * @GST_VAAPI_CODEC_VC1: VC-1 Advanced profile (SMPTE 421M) * @GST_VAAPI_CODEC_JPEG: JPEG (ITU-T 81) * @GST_VAAPI_CODEC_H265: H.265 aka MPEG-H Part 2 (ITU-T H.265) + * @GST_VAAPI_CODEC_VP9: VP9 (libvpx) * * The set of all codecs for #GstVaapiCodec. */ @@ -54,6 +55,7 @@ typedef enum { GST_VAAPI_CODEC_JPEG = GST_MAKE_FOURCC('J','P','G',0), GST_VAAPI_CODEC_VP8 = GST_MAKE_FOURCC('V','P','8',0), GST_VAAPI_CODEC_H265 = GST_MAKE_FOURCC('2','6','5',0), + GST_VAAPI_CODEC_VP9 = GST_MAKE_FOURCC('V','P','9',0), } GstVaapiCodec; /** @@ -129,6 +131,8 @@ typedef enum { * H.265 main 10 profile [A.3.3] * @GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE: * H.265 main still picture profile [A.3.4] + * @GST_VAAPI_PROFILE_VP9: + * VP9 prfile 0 * * The set of all profiles for #GstVaapiProfile. */ @@ -165,6 +169,7 @@ typedef enum { GST_VAAPI_PROFILE_H265_MAIN10 = GST_VAAPI_MAKE_PROFILE(H265,2), GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE = GST_VAAPI_MAKE_PROFILE(H265,3), + GST_VAAPI_PROFILE_VP9 = GST_VAAPI_MAKE_PROFILE(VP9,1), } GstVaapiProfile; /** From db877e015da92c137a0db3d022fe1226dab2c55f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 6 Nov 2015 15:12:51 +0200 Subject: [PATCH 2159/3781] VP9: libgstvaapi: Add VP9 decoder --- gst-libs/gst/vaapi/Makefile.am | 9 + gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 679 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_vp9.h | 37 ++ 3 files changed, 725 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_vp9.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_vp9.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index c6f845c2fe..107ef2a5ca 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -175,6 +175,13 @@ libgstvaapi_source_h += $(libgstvaapi_hevcdec_source_h) libgstvaapi_source_priv_h += $(libgstvaapi_hevcdec_source_priv_h) endif +libgstvaapi_vp9dec_source_c = gstvaapidecoder_vp9.c +libgstvaapi_vp9dec_source_h = gstvaapidecoder_vp9.h +if USE_VP9_DECODER +libgstvaapi_source_c += $(libgstvaapi_vp9dec_source_c) +libgstvaapi_source_h += $(libgstvaapi_vp9dec_source_h) +endif + libgstvaapi_enc_source_c = \ gstvaapicodedbuffer.c \ gstvaapicodedbufferpool.c \ @@ -594,6 +601,8 @@ EXTRA_DIST += \ $(libgstvaapi_hevcdec_source_c) \ $(libgstvaapi_hevcdec_source_h) \ $(libgstvaapi_hevcdec_source_priv_h) \ + $(libgstvaapi_vp9dec_source_c) \ + $(libgstvaapi_vp9dec_source_h) \ $(libgstvaapi_jpegenc_source_h) \ $(libgstvaapi_jpegenc_source_c) \ $(libgstvaapi_vp8enc_source_h) \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c new file mode 100644 index 0000000000..c3ec964114 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -0,0 +1,679 @@ +/* + * gstvaapidecoder_vp9.c - VP9 decoder + * + * Copyright (C) 2014-2015 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 +#include "gstvaapidecoder_vp9.h" +#include "gstvaapidecoder_objects.h" +#include "gstvaapidecoder_priv.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapiobject_priv.h" + +#include "gstvaapicompat.h" +#ifdef HAVE_VA_VA_DEC_VP9_H +#include +#endif + +#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; +}; + +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); + + if (priv->parser) + gst_vp9_parser_free (priv->parser); +} + +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 +ensure_context (GstVaapiDecoderVp9 * decoder) +{ + GstVaapiDecoderVp9Private *const priv = &decoder->priv; + const GstVaapiProfile profile = GST_VAAPI_PROFILE_VP9; + 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 = 8; + 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 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) { + for (i = 0; i < G_N_ELEMENTS (priv->ref_frames); i++) + pic_param->reference_frames[i] = picture->surface_id; + + } else { + 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]; + + if (frame_hdr->ref_frame_indices[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; + gint i; + + /* Fill in VAPictureParameterBufferVP9 */ + pic_param->frame_width = priv->width; + pic_param->frame_height = priv->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, frame_hdr, subsampling_x); + COPY_BFM (pic_fields, frame_hdr, 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, parser, 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); + + 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)); + memcpy (pic_param->segment_pred_probs, parser->segment_pred_probs, + sizeof (parser->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; + GstVp9FrameHdr *const frame_hdr = &priv->frame_hdr; + 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; + GstVaapiPicture *picture; + GstVaapiDecoderStatus status; + + status = ensure_context (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + /* Fixme: handle show_existing_frame */ + + /* 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); + + 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 (!gst_vaapi_picture_decode (picture)) + goto error; + + update_ref_frames (decoder); + + if (frame_hdr->show_frame) + if (!gst_vaapi_picture_output (picture)) + goto error; + + gst_vaapi_picture_replace (&priv->current_picture, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; + +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; + + result = gst_vp9_parser_parse_frame_header (priv->parser, frame_hdr, + buf, buf_size); + if (result != GST_VP9_PARSER_OK) + return get_status (result); + + if ((frame_hdr->frame_type == GST_VP9_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_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; + static guint cnt = 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; + +set_flags: + 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); +} + +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_class_init (GstVaapiDecoderVp9Class * klass) +{ + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); + + object_class->size = sizeof (GstVaapiDecoderVp9); + object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; + + decoder_class->create = gst_vaapi_decoder_vp9_create; + decoder_class->destroy = gst_vaapi_decoder_vp9_destroy; + 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 inline const GstVaapiDecoderClass * +gst_vaapi_decoder_vp9_class (void) +{ + static GstVaapiDecoderVp9Class g_class; + static gsize g_class_init = FALSE; + + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_decoder_vp9_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS (&g_class); +} + +/** + * 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 gst_vaapi_decoder_new (gst_vaapi_decoder_vp9_class (), display, caps); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.h b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.h new file mode 100644 index 0000000000..9d28c5e357 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.h @@ -0,0 +1,37 @@ +/* + * gstvaapidecoder_vp9.h - VP9 decoder + * + * Copyright (C) 2015-2016 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 + +G_BEGIN_DECLS + +typedef struct _GstVaapiDecoderVp9 GstVaapiDecoderVp9; + +GstVaapiDecoder * +gst_vaapi_decoder_vp9_new (GstVaapiDisplay * display, GstCaps * caps); + +G_END_DECLS + +#endif /* GST_VAAPI_DECODER_VP9_H */ From 6722c541a1743d65be2ad0dfcda6a5ee19075875 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 6 Nov 2015 15:19:38 +0200 Subject: [PATCH 2160/3781] VP9: plugins: Add VP9 decoder --- gst/vaapi/gstvaapidecode.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3c944de136..6be9eb1e50 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -49,6 +49,7 @@ #include #include #include +#include #define GST_PLUGIN_NAME "vaapidecode" #define GST_PLUGIN_DESC "A VA-API based video decoder" @@ -78,6 +79,9 @@ static const char gst_vaapidecode_sink_caps_str[] = #endif #if USE_JPEG_DECODER GST_CAPS_CODEC("image/jpeg") +#endif +#if USE_VP9_DECODER + GST_CAPS_CODEC("video/x-vp9") #endif ; @@ -676,6 +680,11 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) case GST_VAAPI_CODEC_VP8: decode->decoder = gst_vaapi_decoder_vp8_new (dpy, caps); break; +#endif +#if USE_VP9_DECODER + case GST_VAAPI_CODEC_VP9: + decode->decoder = gst_vaapi_decoder_vp9_new (dpy, caps); + break; #endif default: decode->decoder = NULL; From bf046cd0b6feda503e62b1341b78cbacf86aff4a Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 6 Nov 2015 19:18:54 +0200 Subject: [PATCH 2161/3781] codecparsers: Update to gst-vaapi-branch 0ea6792 0ea6792: codecparsers: vp9: Add header comments 347ffc7: codecparsers: vp9: Use g_slice_free() for releasing memory allocated from the slice allocator --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index ac5dc1ad65..0ea6792228 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit ac5dc1ad659f0e3730215b063be6c3b906a00527 +Subproject commit 0ea6792228885a33802ca03792a1b794420a5906 From f182fcfb379344690292c52542f92a9e7f0bf1a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 4 Nov 2015 16:50:44 +0100 Subject: [PATCH 2162/3781] libs: remove unneeded headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since gstvaapidisplay_glx.h do not expose gl.h/glx.h structures, it is not required to include them in the header. It is not also required to include them in gstvaapidisplay_glx.c, since gstvaapiutils_glx.h includes them and exposes their structures (e.g. GLXPixmap). Nonetheless, glext.h neither glxext.h are required to include, they are already included conditionally by gl.h and glx.h, respectively. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757577 --- gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 2 -- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index 8096cb2243..485c413cd0 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -25,8 +25,6 @@ #ifndef GST_VAAPI_DISPLAY_GLX_H #define GST_VAAPI_DISPLAY_GLX_H -#include -#include #include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index c89c85f409..d78b3ee74d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -28,9 +28,7 @@ #include "config.h" #include "libgstvaapi_priv_check.h" #include -#include #include -#include #include #if GLX_GLXEXT_VERSION < 18 From a2611b7f35ef34677eda6e7c149690e5a5a6bcc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 2 Nov 2015 19:05:07 +0100 Subject: [PATCH 2163/3781] vaapidecodebin: fix a leaked display instance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The display returned by gst_vaapi_video_context_get_display() increments the references. Thus, we have to unref the returned display. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757595 --- gst/vaapi/gstvaapidecodebin.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index e602d62cf2..4baec20b02 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -314,6 +314,12 @@ gst_vaapi_decode_bin_handle_message (GstBin * bin, GstMessage * message) activate_vpp (vaapidecbin); bail: + if (display) + gst_vaapi_display_unref (display); + + if (context) + gst_context_unref (context); + GST_BIN_CLASS (gst_vaapi_decode_bin_parent_class)->handle_message (bin, message); } From 4fc8769761843a9b98c97c2cbe3fb5487c1b68de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 6 Nov 2015 10:20:34 +0100 Subject: [PATCH 2164/3781] tests: simple-encoder: remove dead code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The caps creation for codec state configuration is not used. Let's remove it. Signed-off-by: Víctor Manuel Jáquez Leal --- tests/simple-encoder.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/tests/simple-encoder.c b/tests/simple-encoder.c index ff9ddcbe72..ae0c20de91 100644 --- a/tests/simple-encoder.c +++ b/tests/simple-encoder.c @@ -150,7 +150,7 @@ encoder_new (GstVaapiDisplay * display) return encoder; } -static GstVideoCodecState * +static inline GstVideoCodecState * new_codec_state (gint width, gint height, gint fps_n, gint fps_d) { GstVideoCodecState *state; @@ -173,28 +173,9 @@ set_format (GstVaapiEncoder * encoder, gint width, gint height, gint fps_n, { GstVideoCodecState *in_state; GstVaapiEncoderStatus status; - GstCaps *caps; - - if (!g_strcmp0 (g_codec_str, "mpeg2")) { - caps = gst_caps_from_string ("video/mpeg"); - gst_caps_set_simple (caps, - "mpegversion", G_TYPE_INT, 2, - "systemstream", G_TYPE_BOOLEAN, FALSE, - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); - } else if (!g_strcmp0 (g_codec_str, "h264")) { - caps = gst_caps_new_empty_simple ("video/x-h264"); - gst_caps_set_simple (caps, "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); - } else { - return FALSE; - } in_state = new_codec_state (width, height, fps_n, fps_d); status = gst_vaapi_encoder_set_codec_state (encoder, in_state); - gst_caps_unref (caps); g_slice_free (GstVideoCodecState, in_state); return (status == GST_VAAPI_ENCODER_STATUS_SUCCESS); From 1e96fae94c28866ed6f3ed63e79d83932bf79f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 2 Nov 2015 16:48:27 +0100 Subject: [PATCH 2165/3781] plugin: chain up set_context() vmethod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since Gstreamer 1.7, set_context() vmethod needs to be chained up with the parent class in order to broadcast all its contexts when the element is added into a bin: http://cgit.freedesktop.org/gstreamer/gstreamer/commit/?id=d5ded1588920c4471eefe055d09095d9e5e989b5 There is no need to guard the call, because before GStreamer 1.7, the set_context() vmethod was NULL in the element class, hence the conditional call make it safe. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapipluginbase.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 05b816c62c..5acc807467 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -35,6 +35,8 @@ /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) +static gpointer plugin_parent_class = NULL; + /* GstVideoContext interface */ static void plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) @@ -59,10 +61,14 @@ static void plugin_set_context (GstElement * element, GstContext * context) { GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); + GstElementClass *element_class = GST_ELEMENT_CLASS (plugin_parent_class); GstVaapiDisplay *display = NULL; if (gst_vaapi_video_context_get_display (context, &display)) plugin_set_display (plugin, display); + + if (element_class->set_context) + element_class->set_context (element, context); } void @@ -177,6 +183,8 @@ gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) klass->has_interface = default_has_interface; klass->display_changed = default_display_changed; + plugin_parent_class = g_type_class_peek_parent (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); element_class->set_context = GST_DEBUG_FUNCPTR (plugin_set_context); } From c20318d1982a3b071f633e2cb3473e0699851d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 23 Oct 2015 11:17:01 +0200 Subject: [PATCH 2166/3781] gstvaapivideocontext: fix indentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gst-indent does not handle correctly some expression like function declaration with attributes, breaking the following expressions. This patch makes gst-indent to ignore the attributed function declartion so the followed function definition is not mangled, such as happened in commit b4154a Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapivideocontext.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index e3e4afcff1..183e12a393 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -31,16 +31,17 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); #define GST_VAAPI_TYPE_DISPLAY \ gst_vaapi_display_get_type () -GType -gst_vaapi_display_get_type (void) - G_GNUC_CONST; +/* *INDENT-OFF* */ +static GType gst_vaapi_display_get_type (void) G_GNUC_CONST; +/* *INDENT-ON* */ G_DEFINE_BOXED_TYPE (GstVaapiDisplay, gst_vaapi_display, (GBoxedCopyFunc) gst_vaapi_display_ref, (GBoxedFreeFunc) gst_vaapi_display_unref); - GstContext *gst_vaapi_video_context_new_with_display (GstVaapiDisplay * - display, gboolean persistent) +GstContext * +gst_vaapi_video_context_new_with_display (GstVaapiDisplay * display, + gboolean persistent) { GstContext *context; GstStructure *structure; From 7e9ee7f66d490ab11e0c1ba64bca97b71554b80d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 30 Oct 2015 11:18:47 +0100 Subject: [PATCH 2167/3781] vaapivideocontext: refactor context category debug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor the extraction GST_CAT_CONTEXT logging using a only once initializator, so we could get the debug category from different code paths, safely. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapivideocontext.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 183e12a393..296fb1e587 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -39,6 +39,19 @@ G_DEFINE_BOXED_TYPE (GstVaapiDisplay, gst_vaapi_display, (GBoxedCopyFunc) gst_vaapi_display_ref, (GBoxedFreeFunc) gst_vaapi_display_unref); +static void +_init_context_debug (void) +{ +#ifndef GST_DISABLE_GST_DEBUG + static volatile gsize _init = 0; + + if (g_once_init_enter (&_init)) { + GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"); + g_once_init_leave (&_init, 1); + } +#endif +} + GstContext * gst_vaapi_video_context_new_with_display (GstVaapiDisplay * display, gboolean persistent) @@ -79,6 +92,7 @@ context_pad_query (const GValue * item, GValue * value, gpointer user_data) return FALSE; } + _init_context_debug (); GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, pad, "context pad peer query failed"); return TRUE; } @@ -118,8 +132,7 @@ gst_vaapi_video_context_prepare (GstElement * element) GstQuery *query; GstMessage *msg; - if (!GST_CAT_CONTEXT) - GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"); + _init_context_debug (); /* 1) Check if the element already has a context of the specific * type, i.e. it was previously set via @@ -170,6 +183,7 @@ gst_vaapi_video_context_propagate (GstElement * element, context = gst_vaapi_video_context_new_with_display (display, FALSE); + _init_context_debug (); GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "posting `have-context' (%p) message with display (%p)", context, display); From 5d0ab369248672d338e1ff5a50e91d9d704fd9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 4 Nov 2015 19:02:34 +0100 Subject: [PATCH 2168/3781] vaapivideocontext: refactor gst_vaapi_video_context_prepare() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First, refactorized run_context_query() into _gst_context_run_query(), adding a new parameter: the pad direction, in order to simplify the code. Second, added a new helper function: _gst_context_query(), which is a generic context query function. It isolates the operation of running the query and sets the context if found, also it enhances the logs. _gst_context_query() is similar to the one used in GstGL. Perhaps, in the future this helper function will be merged into the core libraries of GStreamer. Finally, gst_vaapi_video_context_prepare() was rewritten to use _gst_context_query(). Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapivideocontext.c | 105 +++++++++++++++++++------------ 1 file changed, 64 insertions(+), 41 deletions(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 296fb1e587..534477555f 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -98,7 +98,8 @@ context_pad_query (const GValue * item, GValue * value, gpointer user_data) } static gboolean -run_context_query (GstElement * element, GstQuery * query) +_gst_context_run_query (GstElement * element, GstQuery * query, + GstPadDirection direction) { GstIteratorFoldFunction const func = context_pad_query; GstIterator *it; @@ -107,17 +108,12 @@ run_context_query (GstElement * element, GstQuery * query) g_value_init (&res, G_TYPE_BOOLEAN); g_value_set_boolean (&res, FALSE); - /* Ask downstream neighbour */ - it = gst_element_iterate_src_pads (element); - while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC) - gst_iterator_resync (it); - gst_iterator_free (it); + /* Ask neighbour */ + if (direction == GST_PAD_SRC) + it = gst_element_iterate_src_pads (element); + else + it = gst_element_iterate_sink_pads (element); - if (g_value_get_boolean (&res)) - return TRUE; - - /* If none, ask upstream neighbour (auto-plugged case) */ - it = gst_element_iterate_sink_pads (element); while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC) gst_iterator_resync (it); gst_iterator_free (it); @@ -125,53 +121,80 @@ run_context_query (GstElement * element, GstQuery * query) return g_value_get_boolean (&res); } -void -gst_vaapi_video_context_prepare (GstElement * element) +static gboolean +_gst_context_get_from_query (GstElement * element, GstQuery * query, + GstPadDirection direction) +{ + GstContext *ctxt; + + if (!_gst_context_run_query (element, query, direction)) + return FALSE; + + gst_query_parse_context (query, &ctxt); + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, + "found context (%" GST_PTR_FORMAT ") in %s query", ctxt, + direction == GST_PAD_SRC ? "downstream" : "upstream"); + gst_element_set_context (element, ctxt); + return TRUE; +} + +static void +_gst_context_query (GstElement * element, const gchar * context_type) { - GstContext *context; GstQuery *query; GstMessage *msg; _init_context_debug (); - /* 1) Check if the element already has a context of the specific - * type, i.e. it was previously set via - * gst_element_set_context(). */ - /* This was already done by the caller of this function: - * gst_vaapi_ensure_display() */ - /* 2) Query downstream with GST_QUERY_CONTEXT for the context and check if downstream already has a context of the specific type */ /* 3) Query upstream with GST_QUERY_CONTEXT for the context and check if upstream already has a context of the specific type */ - context = NULL; - query = gst_query_new_context (GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); - if (run_context_query (element, query)) { - gst_query_parse_context (query, &context); - GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, - "found context (%p) in query", context); - gst_element_set_context (element, context); - } else { - /* 4) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with - the required context types and afterwards check if an - usable context was set now as in 1). The message could - be handled by the parent bins of the element and the - application. */ - GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, - "posting `need-context' message"); - msg = gst_message_new_need_context (GST_OBJECT_CAST (element), - GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); - gst_element_post_message (element, msg); + query = gst_query_new_context (context_type); + if (_gst_context_get_from_query (element, query, GST_PAD_SRC)) + goto found; + if (_gst_context_get_from_query (element, query, GST_PAD_SINK)) + goto found; - /* The check of an usable context is done by the caller: - gst_vaapi_ensure_display() */ - } + /* 4) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with + the required context types and afterwards check if an + usable context was set now as in 1). The message could + be handled by the parent bins of the element and the + application. */ + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, + "posting `need-context' message"); + msg = gst_message_new_need_context (GST_OBJECT_CAST (element), context_type); + gst_element_post_message (element, msg); + /* + * Whomever responds to the need-context message performs a + * GstElement::set_context() with the required context in which the + * element is required to update the display_ptr + */ + +found: gst_query_unref (query); } +void +gst_vaapi_video_context_prepare (GstElement * element) +{ + g_return_if_fail (element != NULL); + + /* 1) Check if the element already has a context of the specific + * type, i.e. it was previously set via + * gst_element_set_context(). */ + /* This was already done by the caller of this function: + * gst_vaapi_ensure_display() */ + + _gst_context_query (element, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); + + /* The check of an usable context is done by the caller: + gst_vaapi_ensure_display() */ +} + /* 5) Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT message on the bus. */ void From 959c13933d5e48fff3f3603b25ec94daecf25490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 2 Nov 2015 18:20:07 +0100 Subject: [PATCH 2169/3781] vaapivideocontext: rename context structure The context structure is named "display" which is too generic. The contrary happens, for example, with GstGL, what uses the same name as the context, and its logs make more sense. This patch renames the context structure with the same name as the context, thus GST_PTR_FORMAT can pretty print it. https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapivideocontext.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 534477555f..36737a0b2d 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -61,8 +61,8 @@ gst_vaapi_video_context_new_with_display (GstVaapiDisplay * display, context = gst_context_new (GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, persistent); structure = gst_context_writable_structure (context); - gst_structure_set (structure, "display", GST_VAAPI_TYPE_DISPLAY, - display, NULL); + gst_structure_set (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, + GST_VAAPI_TYPE_DISPLAY, display, NULL); return context; } @@ -77,8 +77,8 @@ gst_vaapi_video_context_get_display (GstContext * context, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) == 0, FALSE); structure = gst_context_get_structure (context); - return gst_structure_get (structure, "display", GST_VAAPI_TYPE_DISPLAY, - display_ptr, NULL); + return gst_structure_get (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, + GST_VAAPI_TYPE_DISPLAY, display_ptr, NULL); } static gboolean From b45089f0f72e5a5bd56beeeeeedc085e9b59e6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 30 Oct 2015 12:33:48 +0100 Subject: [PATCH 2170/3781] plugins: set display through context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of setting the display to the plugin directly after its creation, do it through the gstreamer's context mechanism, avoiding double assignations. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapipluginutil.c | 1 - gst/vaapi/gstvaapivideocontext.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 2071adc215..f5d3fe6da0 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -250,7 +250,6 @@ gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type) return FALSE; gst_vaapi_video_context_propagate (element, display); - GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE (plugin, display); gst_vaapi_display_unref (display); return TRUE; } diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 36737a0b2d..62bd9d43f2 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -205,6 +205,7 @@ gst_vaapi_video_context_propagate (GstElement * element, GstMessage *msg; context = gst_vaapi_video_context_new_with_display (display, FALSE); + gst_element_set_context (element, context); _init_context_debug (); GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, From ef3fb4afaf38fbfd52e5b8b7bc7008b3f0e1cdaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 30 Oct 2015 12:27:16 +0100 Subject: [PATCH 2171/3781] plugins: check if display is set in sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the context messages are sync'ed, the display assignation happens in the same thread, hence we can know if the display was found or not as soon we call for it. In order to take advantage of it, gst_vaapi_video_context_prepare() receives, as a new parameter, the address of the plugin's display, and reports back if the display was found and set. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapipluginutil.c | 10 +++++----- gst/vaapi/gstvaapivideocontext.c | 24 +++++++++++++++--------- gst/vaapi/gstvaapivideocontext.h | 5 +++-- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index f5d3fe6da0..135d109c59 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -235,11 +235,11 @@ gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type) g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); - gst_vaapi_video_context_prepare (element); - - /* Neighbour found and it updated the display */ - if (gst_vaapi_plugin_base_has_display_type (plugin, type)) - return TRUE; + if (gst_vaapi_video_context_prepare (element, &plugin->display)) { + /* Neighbour found and it updated the display */ + if (gst_vaapi_plugin_base_has_display_type (plugin, type)) + return TRUE; + } /* If no neighboor, or application not interested, use system default */ if (plugin->gl_context) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 62bd9d43f2..f049273efe 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -178,21 +178,27 @@ found: gst_query_unref (query); } -void -gst_vaapi_video_context_prepare (GstElement * element) +gboolean +gst_vaapi_video_context_prepare (GstElement * element, + GstVaapiDisplay ** display_ptr) { - g_return_if_fail (element != NULL); + g_return_val_if_fail (element != NULL, FALSE); + g_return_val_if_fail (display_ptr != NULL, FALSE); /* 1) Check if the element already has a context of the specific - * type, i.e. it was previously set via - * gst_element_set_context(). */ - /* This was already done by the caller of this function: - * gst_vaapi_ensure_display() */ + * type. + */ + if (*display_ptr) { + GST_LOG_OBJECT (element, "already have a display (%p)", *display_ptr); + return TRUE; + } _gst_context_query (element, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); - /* The check of an usable context is done by the caller: - gst_vaapi_ensure_display() */ + if (*display_ptr) + GST_LOG_OBJECT (element, "found a display (%p)", *display_ptr); + + return *display_ptr != NULL; } /* 5) Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT message diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index b3d955bf7e..95e134b627 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -42,8 +42,9 @@ gst_vaapi_video_context_get_display (GstContext * context, GstVaapiDisplay ** display_ptr); G_GNUC_INTERNAL -void -gst_vaapi_video_context_prepare (GstElement * element); +gboolean +gst_vaapi_video_context_prepare (GstElement * element, + GstVaapiDisplay ** display_ptr); G_GNUC_INTERNAL void From ed280f5b84cce8c46a529acff5c30692834d5bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 4 Nov 2015 20:29:03 +0100 Subject: [PATCH 2172/3781] vaapivideocontext: add gst_vaapi_video_context_set_display() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function set the display to an already created context. This function is going to be used later. Also, gst_vaapi_video_context_new_with_display() now uses this function. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapivideocontext.c | 18 ++++++++++++++---- gst/vaapi/gstvaapivideocontext.h | 5 +++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index f049273efe..c90ede7de1 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -52,17 +52,27 @@ _init_context_debug (void) #endif } +void +gst_vaapi_video_context_set_display (GstContext * context, + GstVaapiDisplay * display) +{ + GstStructure *structure; + + g_return_if_fail (context != NULL); + + structure = gst_context_writable_structure (context); + gst_structure_set (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, + GST_VAAPI_TYPE_DISPLAY, display, NULL); +} + GstContext * gst_vaapi_video_context_new_with_display (GstVaapiDisplay * display, gboolean persistent) { GstContext *context; - GstStructure *structure; context = gst_context_new (GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, persistent); - structure = gst_context_writable_structure (context); - gst_structure_set (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, - GST_VAAPI_TYPE_DISPLAY, display, NULL); + gst_vaapi_video_context_set_display (context, display); return context; } diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index 95e134b627..2d56183dfb 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -31,6 +31,11 @@ #define GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME "gst.vaapi.Display" +G_GNUC_INTERNAL +void +gst_vaapi_video_context_set_display (GstContext * context, + GstVaapiDisplay * display); + G_GNUC_INTERNAL GstContext * gst_vaapi_video_context_new_with_display (GstVaapiDisplay * display, From 28c366a003c6483a0602775b3dd18add75c12592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 4 Nov 2015 20:37:05 +0100 Subject: [PATCH 2173/3781] plugin: don't lose previous context at query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When processing the GST_CONTEXT_QUERY we should not lose the previous context in the query, we should only add our display structure. This patch copies the old context, if it is there, and stamp our display on it. Otherwise, a new context is created. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapipluginutil.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 135d109c59..00babbe1b2 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -258,7 +258,7 @@ gboolean gst_vaapi_reply_to_query (GstQuery * query, GstVaapiDisplay * display) { const gchar *type = NULL; - GstContext *context; + GstContext *context, *old_context; if (GST_QUERY_TYPE (query) != GST_QUERY_CONTEXT) return FALSE; @@ -272,7 +272,14 @@ gst_vaapi_reply_to_query (GstQuery * query, GstVaapiDisplay * display) if (g_strcmp0 (type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME)) return FALSE; - context = gst_vaapi_video_context_new_with_display (display, FALSE); + gst_query_parse_context (query, &old_context); + if (old_context) { + context = gst_context_copy (old_context); + gst_vaapi_video_context_set_display (context, display); + } else { + context = gst_vaapi_video_context_new_with_display (display, FALSE); + } + gst_query_set_context (query, context); gst_context_unref (context); From b2707c8eece0a57906b3225f3f8706d94d41831c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 4 Nov 2015 21:38:42 +0100 Subject: [PATCH 2174/3781] plugins: fix context query handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current context query handling design is flawed: the function gst_vaapi_reply_to_query() returns FALSE either if the query is not a GST_CONTEXT_QUERY of if the query could not be handled correctly. But the pad query function should handle differently each case. This patch changes the gst_vaapi_reply_to_query() for gst_vaapi_handle_context_query() and changes it usage in all the vaapi plugins to match the correct context query handling. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapidecode.c | 18 ++++++++---------- gst/vaapi/gstvaapiencode.c | 4 ++-- gst/vaapi/gstvaapipluginutil.c | 5 ++--- gst/vaapi/gstvaapipluginutil.h | 2 +- gst/vaapi/gstvaapipostproc.c | 12 +++++++----- gst/vaapi/gstvaapisink.c | 19 ++++++++++++------- 6 files changed, 32 insertions(+), 28 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6be9eb1e50..7bec7b8869 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1057,11 +1057,6 @@ gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query) GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (decode); - if (gst_vaapi_reply_to_query (query, plugin->display)) { - GST_DEBUG_OBJECT (decode, "sharing display %p", plugin->display); - return TRUE; - } - switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CAPS:{ GstCaps *caps, *filter = NULL; @@ -1080,6 +1075,10 @@ gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query) gst_caps_unref (caps); break; } + case GST_QUERY_CONTEXT:{ + ret = gst_vaapi_handle_context_query (query, plugin->display); + break; + } default:{ #if GST_CHECK_VERSION(1,4,0) ret = GST_VIDEO_DECODER_CLASS (gst_vaapidecode_parent_class)->sink_query @@ -1105,11 +1104,6 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (decode); - if (gst_vaapi_reply_to_query (query, plugin->display)) { - GST_DEBUG_OBJECT (decode, "sharing display %p", plugin->display); - return TRUE; - } - switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CAPS:{ GstCaps *caps, *filter = NULL; @@ -1128,6 +1122,10 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) gst_caps_unref (caps); break; } + case GST_QUERY_CONTEXT:{ + ret = gst_vaapi_handle_context_query (query, plugin->display); + break; + } default:{ #if GST_CHECK_VERSION(1,4,0) ret = GST_VIDEO_DECODER_CLASS (gst_vaapidecode_parent_class)->src_query diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 88c5549e20..141544184e 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -66,8 +66,8 @@ gst_vaapiencode_query (GstPad * pad, GstObject * parent, GstQuery * query) GST_INFO_OBJECT (plugin, "query type %s", GST_QUERY_TYPE_NAME (query)); - if (gst_vaapi_reply_to_query (query, plugin->display)) - success = TRUE; + if (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT) + success = gst_vaapi_handle_context_query (query, plugin->display); else if (GST_PAD_IS_SINK (pad)) success = plugin->sinkpad_query (plugin->sinkpad, parent, query); else diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 00babbe1b2..74f311b2ad 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -255,13 +255,12 @@ gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type) } gboolean -gst_vaapi_reply_to_query (GstQuery * query, GstVaapiDisplay * display) +gst_vaapi_handle_context_query (GstQuery * query, GstVaapiDisplay * display) { const gchar *type = NULL; GstContext *context, *old_context; - if (GST_QUERY_TYPE (query) != GST_QUERY_CONTEXT) - return FALSE; + g_return_val_if_fail (query != NULL, FALSE); if (!display) return FALSE; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 4ca82253ea..d46f2dbb7b 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -35,7 +35,7 @@ gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type); G_GNUC_INTERNAL gboolean -gst_vaapi_reply_to_query (GstQuery * query, GstVaapiDisplay * display); +gst_vaapi_handle_context_query (GstQuery * query, GstVaapiDisplay * display); G_GNUC_INTERNAL gboolean diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index fc8c7cb208..38fa9b5cc8 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1286,11 +1286,13 @@ gst_vaapipostproc_query (GstBaseTransform * trans, GstPadDirection direction, { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - if (gst_vaapi_reply_to_query (query, - GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc))) { - GST_DEBUG_OBJECT (postproc, "sharing display %p", - GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc)); - return TRUE; + if (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT) { + if (gst_vaapi_handle_context_query (query, + GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc))) { + GST_DEBUG_OBJECT (postproc, "sharing display %p", + GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc)); + return TRUE; + } } return diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index b148cacc9e..7ff8401241 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1447,15 +1447,20 @@ static gboolean gst_vaapisink_query (GstBaseSink * base_sink, GstQuery * query) { GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (sink); + gboolean ret = FALSE; - GST_INFO_OBJECT (sink, "query type %s", GST_QUERY_TYPE_NAME (query)); - - if (gst_vaapi_reply_to_query (query, GST_VAAPI_PLUGIN_BASE_DISPLAY (sink))) { - GST_DEBUG ("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); - return TRUE; + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CONTEXT: + ret = gst_vaapi_handle_context_query (query, plugin->display); + break; + default: + ret = GST_BASE_SINK_CLASS (gst_vaapisink_parent_class)->query (base_sink, + query); + break; } - return GST_BASE_SINK_CLASS (gst_vaapisink_parent_class)->query (base_sink, - query); + + return ret; } static void From d69f747d0949bc87816bb74ac33135b618296c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 28 Oct 2015 12:59:02 +0100 Subject: [PATCH 2175/3781] plugins: don't create display at caps query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caps query can happen before the element has a bus. The display creation should be should occur on the context negotiation, when the bus is already configured. Then at caps query no display should be created. Instead of force the display creation, we graciously fail the allowed_caps() creation. This change only applies for vaapidecode and vaapisink. The vaapipostroc, as a basetransform descendant, seems to be not affected by this, nor the encoders. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapidecode.c | 4 ++-- gst/vaapi/gstvaapisink.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 7bec7b8869..5fc2592b85 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -957,7 +957,7 @@ gst_vaapidecode_ensure_allowed_caps (GstVaapiDecode * decode) if (decode->allowed_caps) return TRUE; - if (!gst_vaapidecode_ensure_display (decode)) + if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)) goto error_no_display; profiles = @@ -1001,7 +1001,7 @@ gst_vaapidecode_ensure_allowed_caps (GstVaapiDecode * decode) /* ERRORS */ error_no_display: { - GST_ERROR ("failed to retrieve VA display"); + GST_INFO_OBJECT (decode, "no VA display shared yet"); return FALSE; } error_no_profiles: diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 7ff8401241..fd22524227 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1206,7 +1206,7 @@ gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) if (!out_caps) return NULL; - if (gst_vaapisink_ensure_display (sink)) { + if (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)) { raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE (sink)); if (raw_caps) { out_caps = gst_caps_make_writable (out_caps); From 75e7a0a36ce5288cb1d6c24f0c8a97aae33c546d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 28 Oct 2015 13:01:04 +0100 Subject: [PATCH 2176/3781] vaapidecode: return pad's template caps if no display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A caps query can occur before the element has a display. In that case, the element can return its pad's template. But when the element already has a display, and the caps probe fails, the element shall return an empty caps, so the auto-plug could try with another decoder. If the element has a display and the caps probe works, then the computed caps should be returned. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757598 --- gst/vaapi/gstvaapidecode.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 5fc2592b85..fdd1acc1ef 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -954,12 +954,6 @@ gst_vaapidecode_ensure_allowed_caps (GstVaapiDecode * decode) GArray *profiles; guint i; - if (decode->allowed_caps) - return TRUE; - - if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)) - goto error_no_display; - profiles = gst_vaapi_display_get_decode_profiles (GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)); @@ -999,11 +993,6 @@ gst_vaapidecode_ensure_allowed_caps (GstVaapiDecode * decode) return TRUE; /* ERRORS */ -error_no_display: - { - GST_INFO_OBJECT (decode, "no VA display shared yet"); - return FALSE; - } error_no_profiles: { GST_ERROR ("failed to retrieve VA decode profiles"); @@ -1022,9 +1011,19 @@ gst_vaapidecode_get_caps (GstPad * pad) { GstVaapiDecode *const decode = GST_VAAPIDECODE (GST_OBJECT_PARENT (pad)); + if (decode->allowed_caps) + goto bail; + + /* if we haven't a display yet, return our pad's template caps */ + if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)) + return gst_pad_get_pad_template_caps (pad); + + /* if the allowed caps calculation fails, return an empty caps, so + * the auto-plug can try other decoder */ if (!gst_vaapidecode_ensure_allowed_caps (decode)) return gst_caps_new_empty (); +bail: return gst_caps_ref (decode->allowed_caps); } From ea802072d1329cafdb2e4e1d6105afbbda8d4cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 5 Nov 2015 12:39:55 +0100 Subject: [PATCH 2177/3781] vaapiencode: use pad query vmethods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GstVideoEncoder, the base class of vaapiencode, added support for pad queries as virtual methods since gstreamer 1.4. This patch enables those vmethods, while keeps support for previous versions of gstreamer. This patch is relevant since GstVideoEncoder takes care of other queries that we are currently ignoring. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757629 --- gst/vaapi/gstvaapiencode.c | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 141544184e..a9b8b3d633 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -57,6 +57,45 @@ ensure_display (GstVaapiEncode * encode) return gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (encode)); } +#if GST_CHECK_VERSION(1,4,0) +static gboolean +gst_vaapiencode_sink_query (GstVideoEncoder * encoder, GstQuery * query) +{ + gboolean ret = TRUE; + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (encoder); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CONTEXT: + ret = gst_vaapi_handle_context_query (query, plugin->display); + break; + default: + ret = GST_VIDEO_ENCODER_CLASS (gst_vaapiencode_parent_class)->sink_query + (encoder, query); + break; + } + + return ret; +} + +static gboolean +gst_vaapiencode_src_query (GstVideoEncoder * encoder, GstQuery * query) +{ + gboolean ret = TRUE; + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (encoder); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CONTEXT: + ret = gst_vaapi_handle_context_query (query, plugin->display); + break; + default: + ret = GST_VIDEO_ENCODER_CLASS (gst_vaapiencode_parent_class)->src_query + (encoder, query); + break; + } + + return ret; +} +#else static gboolean gst_vaapiencode_query (GstPad * pad, GstObject * parent, GstQuery * query) { @@ -76,6 +115,7 @@ gst_vaapiencode_query (GstPad * pad, GstObject * parent, GstQuery * query) gst_object_unref (plugin); return success; } +#endif typedef struct { @@ -610,8 +650,10 @@ gst_vaapiencode_init (GstVaapiEncode * encode) gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (encode), GST_CAT_DEFAULT); +#if !GST_CHECK_VERSION(1,4,0) gst_pad_set_query_function (plugin->sinkpad, gst_vaapiencode_query); gst_pad_set_query_function (plugin->srcpad, gst_vaapiencode_query); +#endif gst_pad_use_fixed_caps (plugin->srcpad); } @@ -645,8 +687,13 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) klass->set_property = gst_vaapiencode_default_set_property; klass->alloc_buffer = gst_vaapiencode_default_alloc_buffer; +#if GST_CHECK_VERSION(1,4,0) + venc_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapiencode_src_query); + venc_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapiencode_sink_query); +#else /* Registering debug symbols for function pointers */ GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_query); +#endif } static inline GPtrArray * From 1efe569639712ec78099532e4e65d6d513590b7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 5 Nov 2015 12:58:52 +0100 Subject: [PATCH 2178/3781] plugin: guard pointers to pad query functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since gstreamer 1.4 is not required to have pad query functions if the query vmethods are used. This patch guards out the pad query functions for gstreamer < 1.4 Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757629 --- gst/vaapi/gstvaapipluginbase.c | 6 +++++- gst/vaapi/gstvaapipluginbase.h | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 5acc807467..41ffa77504 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -199,13 +199,17 @@ gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin, /* sink pad */ plugin->sinkpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "sink"); - plugin->sinkpad_query = GST_PAD_QUERYFUNC (plugin->sinkpad); gst_video_info_init (&plugin->sinkpad_info); +#if !GST_CHECK_VERSION(1,4,0) + plugin->sinkpad_query = GST_PAD_QUERYFUNC (plugin->sinkpad); +#endif /* src pad */ if (!(GST_OBJECT_FLAGS (plugin) & GST_ELEMENT_FLAG_SINK)) { plugin->srcpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "src"); +#if !GST_CHECK_VERSION(1,4,0) plugin->srcpad_query = GST_PAD_QUERYFUNC (plugin->srcpad); +#endif } gst_video_info_init (&plugin->srcpad_info); } diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 0a1566f272..40f2d123e9 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -121,7 +121,6 @@ struct _GstVaapiPluginBase gboolean sinkpad_caps_changed; gboolean sinkpad_caps_is_raw; GstVideoInfo sinkpad_info; - GstPadQueryFunction sinkpad_query; GstBufferPool *sinkpad_buffer_pool; guint sinkpad_buffer_size; @@ -129,9 +128,13 @@ struct _GstVaapiPluginBase GstCaps *srcpad_caps; gboolean srcpad_caps_changed; GstVideoInfo srcpad_info; - GstPadQueryFunction srcpad_query; GstBufferPool *srcpad_buffer_pool; +#if !GST_CHECK_VERSION(1,4,0) + GstPadQueryFunction srcpad_query; + GstPadQueryFunction sinkpad_query; +#endif + GstVaapiDisplay *display; GstVaapiDisplayType display_type; GstVaapiDisplayType display_type_req; From 3d9efa7572e33bb0aba035b6b5f14973f07471ec Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 10 Nov 2015 19:00:22 +0200 Subject: [PATCH 2179/3781] codecparsers: Update to gst-vaapi-branch da251bb da251bb: codecparsers: vp9: Optimize the memory allocation f5759f4: codecparsers: vp9: Fix the wrong memcpy of probability arrays --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index 0ea6792228..da251bbc9d 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit 0ea6792228885a33802ca03792a1b794420a5906 +Subproject commit da251bbc9d2927b04397bb9be27693c0745e034c From 57b69d36f2204364a832d10fbd94c0c8b52490e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 11 Nov 2015 19:16:16 +0100 Subject: [PATCH 2180/3781] libs: vp9: remove unused symbols MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clang complains about a couple variables and one label which were not used. This patch removes them. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757958 --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index c3ec964114..dacff29c61 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -252,7 +252,6 @@ fill_picture (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture) VADecPictureParameterBufferVP9 *pic_param = picture->param; GstVp9Parser *parser = priv->parser; GstVp9FrameHdr *frame_hdr = &priv->frame_hdr; - gint i; /* Fill in VAPictureParameterBufferVP9 */ pic_param->frame_width = priv->width; @@ -313,7 +312,6 @@ fill_slice (GstVaapiDecoderVp9 * decoder, GstVaapiSlice * slice) GstVaapiDecoderVp9Private *const priv = &decoder->priv; GstVp9Parser *parser = priv->parser; VASliceParameterBufferVP9 *const slice_param = slice->param; - GstVp9FrameHdr *const frame_hdr = &priv->frame_hdr; guint i; #define COPY_SEG_FIELD(s, f) \ @@ -529,7 +527,6 @@ gst_vaapi_decoder_vp9_parse (GstVaapiDecoder * base_decoder, GstVaapiDecoderVp9Private *const priv = &decoder->priv; guchar *buf; guint buf_size, flags = 0; - static guint cnt = 0; buf_size = gst_adapter_available (adapter); if (!buf_size) @@ -561,7 +558,6 @@ gst_vaapi_decoder_vp9_parse (GstVaapiDecoder * base_decoder, flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; -set_flags: GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags); return GST_VAAPI_DECODER_STATUS_SUCCESS; From 66bfe9bad7d166390838d527b59fdb9695f829ff Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 13 Nov 2015 18:40:52 +0200 Subject: [PATCH 2181/3781] codecparsers: Update to gst-vaapi-branch d9f25 d9f2527: codecparsers: vp9: Set lossless flag in frame header --- ext/codecparsers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/codecparsers b/ext/codecparsers index da251bbc9d..d9f25273df 160000 --- a/ext/codecparsers +++ b/ext/codecparsers @@ -1 +1 @@ -Subproject commit da251bbc9d2927b04397bb9be27693c0745e034c +Subproject commit d9f25273dfa3fe0f5f791c6e35b1243f6462d990 From 9b885c65ca9b646ed726837761ef94fd0736b698 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 13 Nov 2015 18:41:53 +0200 Subject: [PATCH 2182/3781] decoder: vp9: Set lossless flag from frame header --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index dacff29c61..6d5e71991f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -277,7 +277,7 @@ fill_picture (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture) 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, parser, lossless_flag); + COPY_BFM (pic_fields, frame_hdr, lossless_flag); pic_param->pic_fields.bits.segmentation_enabled = frame_hdr->segmentation.enabled; From b9feff206f2fcf03208a58f65bb2d31734d17470 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 13 Nov 2015 18:51:27 +0200 Subject: [PATCH 2183/3781] vaapidecode: Add comments for corner case fixes and fix couple of indentations. --- gst/vaapi/gstvaapidecode.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index fdd1acc1ef..60ce329716 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -217,9 +217,9 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) switch (feature) { #if (USE_GLX || USE_EGL) case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: - features = - gst_caps_features_new - (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); + features = + gst_caps_features_new + (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); break; #endif #if GST_CHECK_VERSION(1,3,1) @@ -420,6 +420,10 @@ gst_vaapidecode_push_all_decoded_frames (GstVaapiDecode * decode) return ret; break; case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: + /* Delayed the pool re-negotiation untill we push all decoded (and queued) + * frames downstream. Otherwise for the multi-resolution videos, the + * GstVideoVideoMemory will be having wrong resolution. + * commit 6eba201f3252eba6a99ab7da7a4c662091a3e884 */ if (!gst_vaapidecode_negotiate (decode)) return GST_FLOW_ERROR; return GST_FLOW_OK; @@ -585,9 +589,9 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) #if (USE_GLX || USE_EGL) decode->has_texture_upload_meta = gst_query_find_allocation_meta (query, - GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL) && + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL) && gst_vaapi_caps_feature_contains (caps, - GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); + GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); #endif return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), From 4aa523f8b426eadd16990978a75c73404b4ecce0 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 13 Nov 2015 18:58:33 +0200 Subject: [PATCH 2184/3781] decoder: vp9: Fill the VADecPictureParameterBufferVP9 width/height from frame header Always fill width/height of VADecPictureParameterBufferVP9 from frame header. Preliminary fix for supproting multi resolution video decode. --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 6d5e71991f..39834eca89 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -254,8 +254,8 @@ fill_picture (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture) GstVp9FrameHdr *frame_hdr = &priv->frame_hdr; /* Fill in VAPictureParameterBufferVP9 */ - pic_param->frame_width = priv->width; - pic_param->frame_height = priv->height; + 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); From a48eebefd63b37b842f45d2e8a040a0e2c57a36f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 13 Nov 2015 19:23:05 +0200 Subject: [PATCH 2185/3781] decoder: vp9: Fix the context and surface pool reset for multi resolution video Unlike other decoders, vp9 decoder doesn't need to reset the whole context and surfaces for each resolution change. Context reset only needed if resolution of any frame is greater than what actullay configured. 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. --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 39834eca89..508805e44a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -504,14 +504,28 @@ parse_frame_header (GstVaapiDecoderVp9 * decoder, const guchar * buf, { 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); - if ((frame_hdr->frame_type == GST_VP9_KEY_FRAME) && - (frame_hdr->width != priv->width || frame_hdr->height != priv->height)) { + /* Unlike other decoders, vp9 decoder doesn't need to reset the + * whole context and surfaces for each resolution change. context + * reset only needed if resolution of any frame is greater than + * what actullay configured. 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; From 8ee23ffd967b65f244ed5c72dadf8b3e1b374b6c Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 13 Nov 2015 19:39:56 +0200 Subject: [PATCH 2186/3781] decoder: vp9: Add crop rectangle support. Set crop rectange if: There is display_width and display_height which is different from actual width/height or The changed resolution is less than the actual configured dimension of surfaces --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 508805e44a..ea5673a03c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -395,8 +395,10 @@ 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; status = ensure_context (decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) @@ -413,6 +415,23 @@ decode_picture (GstVaapiDecoderVp9 * decoder, const guchar * buf, gst_vaapi_picture_replace (&priv->current_picture, picture); gst_vaapi_picture_unref (picture); + if (frame_hdr->display_size_enabled) { + crop_width = frame_hdr->display_width; + crop_height = frame_hdr->display_height; + } else 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; From ce3d1a6203330d6a2110797dc89709605c4c9282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 11 Nov 2015 16:33:24 +0100 Subject: [PATCH 2187/3781] vaapidecodebin: delay the bin configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delay the bin configuration until changing to READY state. This is because we should add the vaapipostproc element until the vaapidecode has emitted the HAVE_CONTEXT message, so de gst_bin_add() could set the context set to vaapipostproc. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757957 --- gst/vaapi/gstvaapidecodebin.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 4baec20b02..edde5c80fb 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -194,10 +194,16 @@ ensure_vpp (GstVaapiDecodeBin * vaapidecbin) gst_vaapi_display_unref (display); - if (!activate_vpp (vaapidecbin)) + return TRUE; +} + +static gboolean +gst_vaapi_decode_bin_reconfigure (GstVaapiDecodeBin* vaapidecbin) +{ + if (!ensure_vpp (vaapidecbin)) return FALSE; - return TRUE; + return activate_vpp (vaapidecbin); } static void @@ -311,8 +317,6 @@ gst_vaapi_decode_bin_handle_message (GstBin * bin, GstMessage * message) } } - activate_vpp (vaapidecbin); - bail: if (display) gst_vaapi_display_unref (display); @@ -343,7 +347,7 @@ gst_vaapi_decode_bin_change_state (GstElement * element, switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - if (!ensure_vpp (vaapidecbin)) + if (!gst_vaapi_decode_bin_reconfigure (vaapidecbin)) return GST_STATE_CHANGE_FAILURE; break; default: From bd4395ce9f2bf037a86cd9597b4b22b652e61e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 11 Nov 2015 19:04:25 +0100 Subject: [PATCH 2188/3781] vaapidecodebin: add postprocessor dynamically MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The former approach to left the bin unfinished has some problems: the context cannot be shared because the vaapidecode is unlinked in many cases, leading to creating a VADisplay twice. Initially the bin is fully functional, constructed as (-----------------------------------) | vaapidecodebin | | (-------------) (-------) | |<--| vaapidecode |--->| queue |--->| | (-------------) (-------) | (-----------------------------------) When the context is shared and the VADisplay has VPP capabilities, before changing to READY state, the bin is reconfigured dynamically, adding the vaapipostproc element afeter the queue: (--------------------------------------------------------) | vaapidecodebin | | (-------------) (-------) (---------------) | |<--| vaapidecode |--->| queue |--->| vaapipostproc |--->| | (-------------) (-------) (---------------) | (--------------------------------------------------------) Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757957 --- gst/vaapi/gstvaapidecodebin.c | 107 +++++++++++++++++++++------------- gst/vaapi/gstvaapidecodebin.h | 2 - 2 files changed, 66 insertions(+), 43 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index edde5c80fb..635cdf3bbb 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -124,15 +124,16 @@ post_missing_element_message (GstVaapiDecodeBin * vaapidecbin, static gboolean activate_vpp (GstVaapiDecodeBin * vaapidecbin) { - GstElement *src; + GstPad *queue_srcpad, *srcpad, *vpp_sinkpad, *vpp_srcpad; + gboolean res; - if (vaapidecbin->ghost_pad_src || vaapidecbin->postproc) + if (vaapidecbin->postproc) return TRUE; - if (vaapidecbin->has_vpp != HAS_VPP_YES || vaapidecbin->disable_vpp) { - src = vaapidecbin->queue; - goto connect_src_ghost_pad; - } + if (vaapidecbin->has_vpp != HAS_VPP_YES || vaapidecbin->disable_vpp) + return TRUE; + + GST_DEBUG_OBJECT (vaapidecbin, "Enabling VPP"); /* create the postproc */ vaapidecbin->postproc = @@ -144,35 +145,47 @@ activate_vpp (GstVaapiDecodeBin * vaapidecbin) vaapidecbin->deinterlace_method, NULL); gst_bin_add (GST_BIN (vaapidecbin), vaapidecbin->postproc); - if (!gst_element_link_pads_full (vaapidecbin->queue, "src", - vaapidecbin->postproc, "sink", GST_PAD_LINK_CHECK_NOTHING)) + + if (!gst_element_sync_state_with_parent (vaapidecbin->postproc)) + goto error_sync_state; + + srcpad = gst_element_get_static_pad (GST_ELEMENT_CAST (vaapidecbin), "src"); + if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (srcpad), NULL)) goto error_link_pad; - GST_DEBUG_OBJECT (vaapidecbin, "Enabling VPP"); - src = vaapidecbin->postproc; + queue_srcpad = gst_element_get_static_pad (vaapidecbin->queue, "src"); + vpp_sinkpad = gst_element_get_static_pad (vaapidecbin->postproc, "sink"); + res = (gst_pad_link (queue_srcpad, vpp_sinkpad) == GST_PAD_LINK_OK); + gst_object_unref (vpp_sinkpad); + gst_object_unref (queue_srcpad); + if (!res) + goto error_link_pad; - goto connect_src_ghost_pad; + vpp_srcpad = gst_element_get_static_pad (vaapidecbin->postproc, "src"); + res = gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (srcpad), vpp_srcpad); + gst_object_unref (vpp_srcpad); + if (!res) + goto error_link_pad; + + gst_object_unref (srcpad); + + return TRUE; error_element_missing: { post_missing_element_message (vaapidecbin, "vaapipostproc"); return FALSE; } -error_link_pad: +error_sync_state: { - GST_ERROR_OBJECT (vaapidecbin, "Failed to link the child elements"); + GST_ERROR_OBJECT (vaapidecbin, "Failed to sync VPP state"); return FALSE; } -connect_src_ghost_pad: +error_link_pad: { - GstPad *srcpad, *ghostpad; - - srcpad = gst_element_get_static_pad (src, "src"); - ghostpad = gst_ghost_pad_new ("src", srcpad); - vaapidecbin->ghost_pad_src = ghostpad; gst_object_unref (srcpad); - gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad); - return TRUE; + GST_ERROR_OBJECT (vaapidecbin, "Failed to link the child elements"); + return FALSE; } } @@ -184,7 +197,7 @@ ensure_vpp (GstVaapiDecodeBin * vaapidecbin) if (vaapidecbin->has_vpp != HAS_VPP_UNKNOWN) return TRUE; - GST_DEBUG_OBJECT (vaapidecbin, "Creating a dummy display to test for vpp"); + GST_INFO_OBJECT (vaapidecbin, "Creating a dummy display to test for vpp"); display = gst_vaapi_create_test_display (); if (!display) return FALSE; @@ -420,6 +433,8 @@ static gboolean gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) { gchar *missing_factory = NULL; + GstPad *pad, *ghostpad; + GstPadTemplate *tmpl; /* create the decoder */ vaapidecbin->decoder = @@ -440,13 +455,29 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) "max-size-buffers", vaapidecbin->max_size_buffers, "max-size-time", vaapidecbin->max_size_time, NULL); - gst_bin_add_many (GST_BIN (vaapidecbin), - vaapidecbin->decoder, vaapidecbin->queue, NULL); + gst_bin_add_many (GST_BIN (vaapidecbin), vaapidecbin->decoder, + vaapidecbin->queue, NULL); - if (!gst_element_link_pads_full (vaapidecbin->decoder, "src", - vaapidecbin->queue, "sink", GST_PAD_LINK_CHECK_NOTHING)) + if (!gst_element_link_many (vaapidecbin->decoder, vaapidecbin->queue, NULL)) goto error_link_pad; + /* create ghost pad sink */ + pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->decoder), "sink"); + ghostpad = gst_ghost_pad_new_from_template ("sink", pad, + GST_PAD_PAD_TEMPLATE (pad)); + gst_object_unref (pad); + if (!gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad)) + goto error_adding_pad; + + /* create ghost pad src */ + pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->queue), "src"); + tmpl = gst_static_pad_template_get (&gst_vaapi_decode_bin_src_factory); + ghostpad = gst_ghost_pad_new_from_template ("src", pad, tmpl); + gst_object_unref (pad); + gst_object_unref (tmpl); + if (!gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad)) + goto error_adding_pad; + return TRUE; error_element_missing: @@ -456,8 +487,14 @@ error_element_missing: } error_link_pad: { - GST_ELEMENT_ERROR (vaapidecbin, CORE, PAD, - (NULL), ("Failed to configure the vaapidecodebin.")); + GST_ELEMENT_ERROR (vaapidecbin, CORE, PAD, (NULL), + ("Failed to configure the vaapidecodebin.")); + return FALSE; + } +error_adding_pad: + { + GST_ELEMENT_ERROR (vaapidecbin, CORE, PAD, (NULL), + ("Failed to adding pads.")); return FALSE; } } @@ -465,20 +502,8 @@ error_link_pad: static void gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) { - GstPad *element_pad, *ghost_pad; - vaapidecbin->has_vpp = HAS_VPP_UNKNOWN; vaapidecbin->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; - if (!gst_vaapi_decode_bin_configure (vaapidecbin)) - return; - - /* create ghost pad sink */ - element_pad = - gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->decoder), "sink"); - ghost_pad = - gst_ghost_pad_new_from_template ("sink", element_pad, - GST_PAD_PAD_TEMPLATE (element_pad)); - gst_object_unref (element_pad); - gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghost_pad); + gst_vaapi_decode_bin_configure (vaapidecbin); } diff --git a/gst/vaapi/gstvaapidecodebin.h b/gst/vaapi/gstvaapidecodebin.h index 18685fe7b4..81804b99d5 100644 --- a/gst/vaapi/gstvaapidecodebin.h +++ b/gst/vaapi/gstvaapidecodebin.h @@ -47,8 +47,6 @@ typedef struct _GstVaapiDecodeBin { GstElement *queue; GstElement *postproc; - GstPad *ghost_pad_src; - /* properties */ guint max_size_buffers; guint max_size_bytes; From 7c71ffccc04094b134437daad3571950a503ad65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 12 Nov 2015 12:47:01 +0100 Subject: [PATCH 2189/3781] vaapidecodebin: try to get display from decoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than create a dummy display, if none has propagated as a context, we should try to get the one from vaapidecode. As the bin is already in READY state, the vaapidecode should be also in that state. That means that the contexts have been negotiated, and it should have already a display. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757957 --- gst/vaapi/gstvaapidecodebin.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 635cdf3bbb..e0858e3981 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -28,6 +28,7 @@ #include "gstvaapipluginutil.h" #include "gstvaapidecodebin.h" #include "gstvaapivideocontext.h" +#include "gstvaapipluginbase.h" #define GST_PLUGIN_NAME "vaapidecodebin" #define GST_PLUGIN_DESC "A Bin of VA-API elements: vaapidecode ! queue ! vaapipostproc" @@ -197,8 +198,14 @@ ensure_vpp (GstVaapiDecodeBin * vaapidecbin) if (vaapidecbin->has_vpp != HAS_VPP_UNKNOWN) return TRUE; - GST_INFO_OBJECT (vaapidecbin, "Creating a dummy display to test for vpp"); - display = gst_vaapi_create_test_display (); + display = GST_VAAPI_PLUGIN_BASE_DISPLAY (vaapidecbin->decoder); + if (display) { + GST_INFO_OBJECT (vaapidecbin, "Got display from vaapidecode"); + gst_vaapi_display_ref (display); + } else { + GST_INFO_OBJECT (vaapidecbin, "Creating a dummy display to test for vpp"); + display = gst_vaapi_create_test_display (); + } if (!display) return FALSE; From ac8d19dab48a397ac51985b8bdc589f62e6a15ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 12 Nov 2015 11:07:38 +0100 Subject: [PATCH 2190/3781] vaapidecodebin: add me as element co-author MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=757957 --- gst/vaapi/gstvaapidecodebin.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index e0858e3981..98aaed4b7c 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -3,6 +3,7 @@ * * Copyright (C) 2015 Intel Corporation * Author: Sreerenj Balachandran + * Author: Victor Jaquez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -401,7 +402,8 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) "VA-API Decode Bin", "Codec/Decoder/Video", GST_PLUGIN_DESC, - "Sreerenj Balachandran "); + "Sreerenj Balachandran , " + "Victor Jaquez "); properties[PROP_MAX_SIZE_BYTES] = g_param_spec_uint ("max-size-bytes", "Max. size (kB)", "Max. amount of data in the queue (bytes, 0=disable)", From 247896884b0d8dc4af4ab3290bac69b9a4e2784d Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 16 Nov 2015 18:21:56 +0200 Subject: [PATCH 2191/3781] decoder: vp9: Add repeat-frame display handling If vp9 frame header come up with show_existing_frame flag set, we should duplicate the existing decoded frame as current frame to be displayed. --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 38 +++++++++++++++++++----- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index ea5673a03c..5309c49048 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -399,27 +399,49 @@ decode_picture (GstVaapiDecoderVp9 * decoder, const guchar * buf, 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; - /* Fixme: handle show_existing_frame */ + /* 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]; - /* 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; + 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; + } 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 (frame_hdr->display_size_enabled) { crop_width = frame_hdr->display_width; crop_height = frame_hdr->display_height; - } else if (priv->width > frame_hdr->width - || priv->height > frame_hdr->height) { + } else if (priv->width > frame_hdr->width || priv->height > frame_hdr->height) { crop_width = frame_hdr->width; crop_height = frame_hdr->height; } From 26f895f4a833535f8dee16e2a556fb93cd504883 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 16 Nov 2015 18:22:14 +0200 Subject: [PATCH 2192/3781] decoder: vp9: Fix ref picture update while doing repeat frame Don't try to do frame decoding and reference picture update while receiving a vp9 frame having show_existing_frame flag set as TRUE. --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 5309c49048..b97487a57c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -422,8 +422,12 @@ decode_picture (GstVaapiDecoderVp9 * decoder, const guchar * buf, 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); } else { /* Create new picture */ picture = GST_VAAPI_PICTURE_NEW (VP9, decoder); @@ -472,16 +476,21 @@ decode_current_picture (GstVaapiDecoderVp9 * decoder) 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 (frame_hdr->show_frame) if (!gst_vaapi_picture_output (picture)) goto error; gst_vaapi_picture_replace (&priv->current_picture, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; error: From 9a314a2430048b4a48d471acc79c64c97d46cf6f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 16 Nov 2015 18:22:33 +0200 Subject: [PATCH 2193/3781] decoder: vp9: Avoid unnecessary show_frame flag checking while doing picture output We always set GST_VAAPI_PICTURE_FLAG_SKIPPED for DECODE_ONLY frames and the gstvaapidecoder base calss is reponsible for handling those frames later on. No need for explicit verification of frame header's show_frame in order to do picture outputing. --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index b97487a57c..b9e023d673 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -485,9 +485,8 @@ decode_current_picture (GstVaapiDecoderVp9 * decoder) update_ref_frames (decoder); ret: - if (frame_hdr->show_frame) - if (!gst_vaapi_picture_output (picture)) - goto error; + if (!gst_vaapi_picture_output (picture)) + goto error; gst_vaapi_picture_replace (&priv->current_picture, NULL); From 2855682bd37b72a22a4a7e5de3469c615fb15bbe Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 16 Nov 2015 18:22:55 +0200 Subject: [PATCH 2194/3781] decoder: vp9: Fix PTS calculation of cloned frames --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index b9e023d673..3dbc0fbe3d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -428,6 +428,9 @@ decode_picture (GstVaapiDecoderVp9 * decoder, const guchar * buf, * 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); From e267e167db3056f5c26facfaa3a8b6a310138623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 25 Aug 2015 16:01:51 +0000 Subject: [PATCH 2195/3781] debian: remove custom parallel compilation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to build a debian package with upstream source, the user should do ./autogen.sh cp -a debian.upstream debian debuild -eDEB_BUILD_OPTIONS="parallel=8" -us -uc -b The environment variable DEB_BUILD_OPTIONS="parallel=8" is the canonical way to make a parallel build (-j8 in this case). This commit removes the script in debian/rules that detects the number of cpus, requested by the environment variable DEBIAN_BUILD_NCPUS, which is not official in debian. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=754087 --- debian.upstream/rules | 9 --------- 1 file changed, 9 deletions(-) diff --git a/debian.upstream/rules b/debian.upstream/rules index 4a73db614a..fe7eae2c7c 100755 --- a/debian.upstream/rules +++ b/debian.upstream/rules @@ -5,15 +5,6 @@ include /usr/share/cdbs/1/class/autotools.mk include /usr/share/cdbs/1/rules/simple-patchsys.mk include /usr/share/cdbs/1/rules/utils.mk -# Allow SMP build -ifeq ($(DEBIAN_BUILD_NCPUS),) - DEBIAN_BUILD_NCPUS = $(shell /usr/bin/getconf _NPROCESSORS_ONLN) -endif -ifneq ($(DEBIAN_BUILD_NCPUS),) - EXTRA_MAKE_FLAGS += -j$(DEBIAN_BUILD_NCPUS) -endif -MAKE += $(EXTRA_MAKE_FLAGS) - # Allow HTML documentation build indep_conf_flags = \ --with-html-dir=\$${prefix}/share/doc/$(DEB_SOURCE_PACKAGE) From a24918037d3d3638ad785bde2a334e29d2a656a1 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 17 Nov 2015 19:37:07 +0200 Subject: [PATCH 2196/3781] decoder: vp9: Fix last/golden/altref frame index setting Always fill VADecPictureParameterBufferVP9 last/golden/altref indices based on what ever reference frame indices encoded in frame header. --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 3dbc0fbe3d..055ac09b7c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -226,17 +226,14 @@ vaapi_fill_ref_frames (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture, 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]; - - if (frame_hdr->ref_frame_indices[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]; - } + 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] = From fc8a0d121c157720ae25b684f28e909e79d56e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 24 Sep 2015 10:35:44 +0000 Subject: [PATCH 2197/3781] build: declare real built files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When runnig the `make dist` target from a clean tree, it fails because if could not find the copied files from codecparsers submodule. They weren't copied because they weren't declared as built sources. This patch removes the stamp mechanism and use the actual file list to copy as the built sources. Also it fixes the duplication of the parser files. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=755525 --- gst/vaapi/Makefile.am | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 95001bd377..7a5f31a0f6 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -185,13 +185,12 @@ libgstvaapi_1_4p_parse_gen_source_h = \ $(NULL) libgstvaapi_parse_gen_sources = \ - $(libgstvaapi_parse_gen_source_c) \ - $(libgstvaapi_parse_gen_source_h) \ + $(libgstvaapi_parse_gen_source_c) \ + $(libgstvaapi_parse_gen_source_h) \ + $(libgstvaapi_1_4p_parse_gen_source_c) \ + $(libgstvaapi_1_4p_parse_gen_source_h) \ $(NUL) -libgstvaapi_parse_gen_sources += $(libgstvaapi_1_4p_parse_gen_source_c) -libgstvaapi_parse_gen_sources += $(libgstvaapi_1_4p_parse_gen_source_h) - libgstvaapi_parse_source_c = gstvaapiparse.c $(libgstvaapi_parse_gen_source_c) libgstvaapi_parse_source_h = gstvaapiparse.h $(libgstvaapi_parse_gen_source_h) @@ -233,17 +232,21 @@ videoparsers_patches_dir = \ include $(videoparsers_patches_dir)/series.frag videoparsers_patches = \ $(videoparsers_patches_base:%=$(top_srcdir)/patches/videoparsers/%) +videoparsers_orig_sources = \ + $(libgstvaapi_parse_gen_sources:%=$(videoparsers_sources_dir)/%) -videoparsers.prepare.stamp: $(videoparsers_patches) - @for f in $(libgstvaapi_parse_gen_sources); do \ - cp -f $(videoparsers_sources_dir)/$$f $$f; \ - done - @for f in $(videoparsers_patches); do \ - patch -p3 < $$f; \ +$(libgstvaapi_parse_gen_sources): $(videoparsers_orig_sources) + cp -f $(videoparsers_sources_dir)/$@ $@ + +videoparsers.prepare.stamp: $(videoparsers_patches) $(libgstvaapi_parse_gen_sources) + @for f in $(videoparsers_patches); do \ + patch -p3 < $$f; \ done @touch $@ -BUILT_SOURCES += videoparsers.prepare.stamp +BUILT_SOURCES += \ + $(libgstvaapi_parse_gen_sources) \ + videoparsers.prepare.stamp endif CLEANFILES = \ From fc958520c328641b74ca04b6a416f0c77b8fddc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 12 Nov 2015 16:13:25 +0100 Subject: [PATCH 2198/3781] vaapipostproc: params video_info_changed() callers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The signature is video_info_changed(old_vip, new_vip). Nonetheless the callers swapped the the order. This didn't raise problems since the comparison of both structures were not affected by its semantics. But still it would be better to fix this to keep the coherence of the code. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=758007 --- gst/vaapi/gstvaapipostproc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 38fa9b5cc8..18f3474b51 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -867,7 +867,7 @@ gst_vaapipostproc_update_sink_caps (GstVaapiPostproc * postproc, GstCaps * caps, if (!gst_video_info_from_caps (&vi, caps)) return FALSE; - if (video_info_changed (&vi, &postproc->sinkpad_info)) + if (video_info_changed (&postproc->sinkpad_info, &vi)) postproc->sinkpad_info = vi, *caps_changed_ptr = TRUE; deinterlace = is_deinterlace_enabled (postproc, &vi); @@ -892,7 +892,7 @@ gst_vaapipostproc_update_src_caps (GstVaapiPostproc * postproc, GstCaps * caps, if (!gst_video_info_from_caps (&vi, caps)) return FALSE; - if (video_info_changed (&vi, &postproc->srcpad_info)) + if (video_info_changed (&postproc->srcpad_info, &vi)) postproc->srcpad_info = vi, *caps_changed_ptr = TRUE; if (postproc->format != GST_VIDEO_INFO_FORMAT (&postproc->sinkpad_info) && @@ -1217,7 +1217,7 @@ ensure_srcpad_buffer_pool (GstVaapiPostproc * postproc, GstCaps * caps) GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); if (postproc->filter_pool - && !video_info_changed (&vi, &postproc->filter_pool_info)) + && !video_info_changed (&postproc->filter_pool_info, &vi)) return TRUE; postproc->filter_pool_info = vi; From 757833230bc73b8e3b4e31649e4618ba802bea51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 16 Nov 2015 17:49:01 +0100 Subject: [PATCH 2199/3781] vaapipostproc: don't set caps change at first set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the source caps change, the filter is destroyed and recreated. Nonetheless, this happens every time the vaapipostproc starts, since the caps change detection algorithm does not take in consideration when the caps are set by first time. This patch intents to be an optimization, to avoid a useless filter destroy-creation cycle when the sources caps are set for first time. The new helper function video_info_update() is a refactorization to avoid duplicated code. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=758007 --- gst/vaapi/gstvaapipostproc.c | 39 +++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 18f3474b51..982b69e844 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -855,6 +855,32 @@ video_info_changed (GstVideoInfo * old_vip, GstVideoInfo * new_vip) return FALSE; } +static inline gboolean +video_info_is_filled (GstVideoInfo * info) +{ + return (GST_VIDEO_INFO_FORMAT (info) > GST_VIDEO_FORMAT_UNKNOWN + && GST_VIDEO_INFO_WIDTH (info) > 0 + && GST_VIDEO_INFO_HEIGHT (info) > 0); +} + +static gboolean +video_info_update (GstCaps * caps, GstVideoInfo * info, + gboolean * caps_changed_ptr) +{ + GstVideoInfo vi; + + if (!gst_video_info_from_caps (&vi, caps)) + return FALSE; + + *caps_changed_ptr = FALSE; + if (video_info_changed (info, &vi)) { + *caps_changed_ptr = video_info_is_filled (info); + *info = vi; + } + + return TRUE; +} + static gboolean gst_vaapipostproc_update_sink_caps (GstVaapiPostproc * postproc, GstCaps * caps, gboolean * caps_changed_ptr) @@ -864,12 +890,10 @@ gst_vaapipostproc_update_sink_caps (GstVaapiPostproc * postproc, GstCaps * caps, GST_INFO_OBJECT (postproc, "new sink caps = %" GST_PTR_FORMAT, caps); - if (!gst_video_info_from_caps (&vi, caps)) + if (!video_info_update (caps, &postproc->sinkpad_info, caps_changed_ptr)) return FALSE; - if (video_info_changed (&postproc->sinkpad_info, &vi)) - postproc->sinkpad_info = vi, *caps_changed_ptr = TRUE; - + vi = postproc->sinkpad_info; deinterlace = is_deinterlace_enabled (postproc, &vi); if (deinterlace) postproc->flags |= GST_VAAPI_POSTPROC_FLAG_DEINTERLACE; @@ -885,16 +909,11 @@ static gboolean gst_vaapipostproc_update_src_caps (GstVaapiPostproc * postproc, GstCaps * caps, gboolean * caps_changed_ptr) { - GstVideoInfo vi; - GST_INFO_OBJECT (postproc, "new src caps = %" GST_PTR_FORMAT, caps); - if (!gst_video_info_from_caps (&vi, caps)) + if (!video_info_update (caps, &postproc->srcpad_info, caps_changed_ptr)) return FALSE; - if (video_info_changed (&postproc->srcpad_info, &vi)) - postproc->srcpad_info = vi, *caps_changed_ptr = TRUE; - if (postproc->format != GST_VIDEO_INFO_FORMAT (&postproc->sinkpad_info) && postproc->format != DEFAULT_FORMAT) postproc->flags |= GST_VAAPI_POSTPROC_FLAG_FORMAT; From f355e62170d75ceb2c7eccb5cebdd583e2f27e46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 18 Nov 2015 20:48:30 +0100 Subject: [PATCH 2200/3781] build: libvpx: update the sources lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `make dist` broke since commit f06798 (libvpx: Update the submodule to libvpx-1.4.0) because the sources.frag does not contain all the module sources. This patch updates thoroughly the sources. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=755525 --- ext/libvpx/Makefile.am | 20 +- ext/libvpx/sources.frag | 537 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 504 insertions(+), 53 deletions(-) diff --git a/ext/libvpx/Makefile.am b/ext/libvpx/Makefile.am index cdb5ffaa8a..d8ff808ee8 100644 --- a/ext/libvpx/Makefile.am +++ b/ext/libvpx/Makefile.am @@ -116,18 +116,24 @@ vpx_sources = \ $(vpx_srcdir)/CHANGELOG \ $(vpx_srcdir)/LICENSE \ $(vpx_srcdir)/PATENTS \ - $(vpx_srcdir)/build/make/Makefile \ - $(vpx_srcdir)/build/make/ads2gas.pl \ + $(vpx_srcdir)/build/make/ads2armasm_ms.pl \ $(vpx_srcdir)/build/make/ads2gas_apple.pl \ + $(vpx_srcdir)/build/make/ads2gas.pl \ + $(vpx_srcdir)/build/make/Android.mk \ + $(vpx_srcdir)/build/make/armlink_adapter.sh \ $(vpx_srcdir)/build/make/configure.sh \ $(vpx_srcdir)/build/make/gen_asm_deps.sh \ - $(vpx_srcdir)/build/make/obj_int_extract.c \ - $(vpx_srcdir)/build/make/rtcd.sh \ + $(vpx_srcdir)/build/make/gen_msvs_def.sh \ + $(vpx_srcdir)/build/make/gen_msvs_proj.sh \ + $(vpx_srcdir)/build/make/gen_msvs_sln.sh \ + $(vpx_srcdir)/build/make/gen_msvs_vcxproj.sh \ + $(vpx_srcdir)/build/make/iosbuild.sh \ + $(vpx_srcdir)/build/make/Makefile \ + $(vpx_srcdir)/build/make/msvs_common.sh \ + $(vpx_srcdir)/build/make/rtcd.pl \ + $(vpx_srcdir)/build/make/thumb.pm \ $(vpx_srcdir)/build/make/version.sh \ $(vpx_srcdir)/configure \ - $(vpx_srcdir)/vp8/common/rtcd_defs.sh \ - $(vpx_srcdir)/vp9/common/vp9_rtcd_defs.sh \ - $(vpx_srcdir)/vpx_scale/vpx_scale_rtcd.sh \ $(vpx_source_mak:%.mk=$(vpx_srcdir)/%.mk) \ $(vpx_source_c:%.c=$(vpx_srcdir)/%.c) \ $(vpx_source_h:%.h=$(vpx_srcdir)/%.h) \ diff --git a/ext/libvpx/sources.frag b/ext/libvpx/sources.frag index 02eb45d381..2c5680538a 100644 --- a/ext/libvpx/sources.frag +++ b/ext/libvpx/sources.frag @@ -19,27 +19,79 @@ # Boston, MA 02110-1301, USA. vpx_source_mak = \ + build/make/Android.mk \ docs.mk \ examples.mk \ libs.mk \ solution.mk \ + test/android/Android.mk \ + test/test-data.mk \ test/test.mk \ + third_party/googletest/gtest.mk \ + third_party/libwebm/Android.mk \ vp8/vp8_common.mk \ - vp8/vp8cx.mk \ vp8/vp8cx_arm.mk \ + vp8/vp8cx.mk \ vp8/vp8dx.mk \ vp9/vp9_common.mk \ vp9/vp9cx.mk \ vp9/vp9dx.mk \ - vpx/vpx_codec.mk \ vpx_mem/vpx_mem.mk \ vpx_ports/vpx_ports.mk \ vpx_scale/vpx_scale.mk \ + vpx/vpx_codec.mk \ $(NULL) vpx_source_c = \ + args.c \ + examples/decode_to_md5.c \ + examples/decode_with_drops.c \ + examples/postproc.c \ + examples/resize_util.c \ + examples/set_maps.c \ + examples/simple_decoder.c \ + examples/simple_encoder.c \ + examples/twopass_encoder.c \ + examples/vp8cx_set_ref.c \ + examples/vp8_multi_resolution_encoder.c \ + examples/vp9_lossless_encoder.c \ + examples/vp9_spatial_svc_encoder.c \ + examples/vpx_temporal_svc_encoder.c \ + ivfdec.c \ + ivfenc.c \ + md5_utils.c \ + rate_hist.c \ + tools_common.c \ + video_reader.c \ + video_writer.c \ vp8/common/alloccommon.c \ + vp8/common/arm/armv6/idct_blk_v6.c \ + vp8/common/arm/bilinearfilter_arm.c \ + vp8/common/arm/dequantize_arm.c \ + vp8/common/arm/filter_arm.c \ + vp8/common/arm/loopfilter_arm.c \ + vp8/common/arm/neon/bilinearpredict_neon.c \ + vp8/common/arm/neon/copymem_neon.c \ + vp8/common/arm/neon/dc_only_idct_add_neon.c \ + vp8/common/arm/neon/dequant_idct_neon.c \ + vp8/common/arm/neon/dequantizeb_neon.c \ + vp8/common/arm/neon/idct_blk_neon.c \ + vp8/common/arm/neon/idct_dequant_0_2x_neon.c \ + vp8/common/arm/neon/idct_dequant_full_2x_neon.c \ + vp8/common/arm/neon/iwalsh_neon.c \ + vp8/common/arm/neon/loopfilter_neon.c \ + vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c \ + vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c \ + vp8/common/arm/neon/mbloopfilter_neon.c \ + vp8/common/arm/neon/reconintra_neon.c \ + vp8/common/arm/neon/sad_neon.c \ + vp8/common/arm/neon/shortidct4x4llm_neon.c \ + vp8/common/arm/neon/sixtappredict_neon.c \ + vp8/common/arm/neon/variance_neon.c \ + vp8/common/arm/neon/vp8_subpixelvariance_neon.c \ + vp8/common/arm/variance_arm.c \ vp8/common/blockd.c \ + vp8/common/context.c \ vp8/common/debugmodes.c \ vp8/common/dequantize.c \ vp8/common/entropy.c \ @@ -55,51 +107,145 @@ vpx_source_c = \ vp8/common/loopfilter_filters.c \ vp8/common/mbpitch.c \ vp8/common/mfqe.c \ + vp8/common/mips/dspr2/dequantize_dspr2.c \ + vp8/common/mips/dspr2/filter_dspr2.c \ + vp8/common/mips/dspr2/idct_blk_dspr2.c \ + vp8/common/mips/dspr2/idctllm_dspr2.c \ + vp8/common/mips/dspr2/loopfilter_filters_dspr2.c \ + vp8/common/mips/dspr2/reconinter_dspr2.c \ vp8/common/modecont.c \ vp8/common/postproc.c \ + vp8/common/ppc/loopfilter_altivec.c \ + vp8/common/ppc/systemdependent.c \ vp8/common/quant_common.c \ vp8/common/reconinter.c \ - vp8/common/reconintra.c \ vp8/common/reconintra4x4.c \ + vp8/common/reconintra.c \ vp8/common/rtcd.c \ vp8/common/sad_c.c \ vp8/common/setupintrarecon.c \ vp8/common/swapyv12buffer.c \ + vp8/common/textblit.c \ vp8/common/treecoder.c \ vp8/common/variance_c.c \ vp8/common/x86/filter_x86.c \ vp8/common/x86/idct_blk_mmx.c \ vp8/common/x86/idct_blk_sse2.c \ vp8/common/x86/loopfilter_x86.c \ - vp8/common/x86/postproc_x86.c \ vp8/common/x86/recon_wrapper_sse2.c \ vp8/common/x86/variance_mmx.c \ vp8/common/x86/variance_sse2.c \ vp8/common/x86/variance_ssse3.c \ vp8/common/x86/vp8_asm_stubs.c \ vp8/decoder/dboolhuff.c \ + vp8/decoder/decodeframe.c \ vp8/decoder/decodemv.c \ - vp8/decoder/decodframe.c \ vp8/decoder/detokenize.c \ + vp8/decoder/error_concealment.c \ vp8/decoder/onyxd_if.c \ vp8/decoder/threading.c \ + vp8/encoder/arm/dct_arm.c \ + vp8/encoder/arm/neon/denoising_neon.c \ + vp8/encoder/arm/neon/fastquantizeb_neon.c \ + vp8/encoder/arm/neon/shortfdct_neon.c \ + vp8/encoder/arm/neon/subtract_neon.c \ + vp8/encoder/arm/neon/vp8_mse16x16_neon.c \ + vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.c \ + vp8/encoder/bitstream.c \ + vp8/encoder/boolhuff.c \ + vp8/encoder/dct.c \ + vp8/encoder/denoising.c \ + vp8/encoder/encodeframe.c \ + vp8/encoder/encodeintra.c \ + vp8/encoder/encodemb.c \ + vp8/encoder/encodemv.c \ + vp8/encoder/ethreading.c \ + vp8/encoder/firstpass.c \ + vp8/encoder/lookahead.c \ + vp8/encoder/mcomp.c \ + vp8/encoder/modecosts.c \ + vp8/encoder/mr_dissim.c \ + vp8/encoder/onyx_if.c \ + vp8/encoder/pickinter.c \ + vp8/encoder/picklpf.c \ + vp8/encoder/ppc/csystemdependent.c \ + vp8/encoder/quantize.c \ + vp8/encoder/ratectrl.c \ + vp8/encoder/rdopt.c \ + vp8/encoder/segmentation.c \ + vp8/encoder/ssim.c \ + vp8/encoder/temporal_filter.c \ + vp8/encoder/tokenize.c \ + vp8/encoder/treewriter.c \ + vp8/encoder/x86/denoising_sse2.c \ + vp8/encoder/x86/quantize_sse2.c \ + vp8/encoder/x86/quantize_sse4.c \ + vp8/encoder/x86/quantize_ssse3.c \ + vp8/encoder/x86/vp8_enc_stubs_mmx.c \ + vp8/encoder/x86/vp8_enc_stubs_sse2.c \ + vp8/vp8_cx_iface.c \ vp8/vp8_dx_iface.c \ - vp9/common/generic/vp9_systemdependent.c \ + vp9/common/arm/neon/vp9_avg_neon.c \ + vp9/common/arm/neon/vp9_convolve8_avg_neon.c \ + vp9/common/arm/neon/vp9_convolve8_neon.c \ + vp9/common/arm/neon/vp9_convolve_neon.c \ + vp9/common/arm/neon/vp9_copy_neon.c \ + vp9/common/arm/neon/vp9_idct16x16_1_add_neon.c \ + vp9/common/arm/neon/vp9_idct16x16_add_neon.c \ + vp9/common/arm/neon/vp9_idct16x16_neon.c \ + vp9/common/arm/neon/vp9_idct32x32_1_add_neon.c \ + vp9/common/arm/neon/vp9_idct32x32_add_neon.c \ + vp9/common/arm/neon/vp9_idct4x4_1_add_neon.c \ + vp9/common/arm/neon/vp9_idct4x4_add_neon.c \ + vp9/common/arm/neon/vp9_idct8x8_1_add_neon.c \ + vp9/common/arm/neon/vp9_idct8x8_add_neon.c \ + vp9/common/arm/neon/vp9_iht4x4_add_neon.c \ + vp9/common/arm/neon/vp9_iht8x8_add_neon.c \ + vp9/common/arm/neon/vp9_loopfilter_16_neon.c \ + vp9/common/arm/neon/vp9_loopfilter_4_neon.c \ + vp9/common/arm/neon/vp9_loopfilter_8_neon.c \ + vp9/common/arm/neon/vp9_loopfilter_neon.c \ + vp9/common/arm/neon/vp9_reconintra_neon.c \ + vp9/common/mips/dspr2/vp9_convolve2_avg_dspr2.c \ + vp9/common/mips/dspr2/vp9_convolve2_avg_horiz_dspr2.c \ + vp9/common/mips/dspr2/vp9_convolve2_dspr2.c \ + vp9/common/mips/dspr2/vp9_convolve2_horiz_dspr2.c \ + vp9/common/mips/dspr2/vp9_convolve2_vert_dspr2.c \ + vp9/common/mips/dspr2/vp9_convolve8_avg_dspr2.c \ + vp9/common/mips/dspr2/vp9_convolve8_avg_horiz_dspr2.c \ + vp9/common/mips/dspr2/vp9_convolve8_dspr2.c \ + vp9/common/mips/dspr2/vp9_convolve8_horiz_dspr2.c \ + vp9/common/mips/dspr2/vp9_convolve8_vert_dspr2.c \ + vp9/common/mips/dspr2/vp9_intrapred16_dspr2.c \ + vp9/common/mips/dspr2/vp9_intrapred4_dspr2.c \ + vp9/common/mips/dspr2/vp9_intrapred8_dspr2.c \ + vp9/common/mips/dspr2/vp9_itrans16_dspr2.c \ + vp9/common/mips/dspr2/vp9_itrans32_cols_dspr2.c \ + vp9/common/mips/dspr2/vp9_itrans32_dspr2.c \ + vp9/common/mips/dspr2/vp9_itrans4_dspr2.c \ + vp9/common/mips/dspr2/vp9_itrans8_dspr2.c \ + vp9/common/mips/dspr2/vp9_loopfilter_filters_dspr2.c \ + vp9/common/mips/dspr2/vp9_mbloop_loopfilter_dspr2.c \ + vp9/common/mips/dspr2/vp9_mblpf_horiz_loopfilter_dspr2.c \ + vp9/common/mips/dspr2/vp9_mblpf_vert_loopfilter_dspr2.c \ vp9/common/vp9_alloccommon.c \ + vp9/common/vp9_blockd.c \ vp9/common/vp9_common_data.c \ vp9/common/vp9_convolve.c \ vp9/common/vp9_debugmodes.c \ vp9/common/vp9_entropy.c \ vp9/common/vp9_entropymode.c \ vp9/common/vp9_entropymv.c \ - vp9/common/vp9_extend.c \ vp9/common/vp9_filter.c \ - vp9/common/vp9_findnearmv.c \ + vp9/common/vp9_frame_buffers.c \ vp9/common/vp9_idct.c \ vp9/common/vp9_loopfilter.c \ vp9/common/vp9_loopfilter_filters.c \ + vp9/common/vp9_mfqe.c \ vp9/common/vp9_mvref_common.c \ + vp9/common/vp9_postproc.c \ vp9/common/vp9_pred_common.c \ + vp9/common/vp9_prob.c \ vp9/common/vp9_quant_common.c \ vp9/common/vp9_reconinter.c \ vp9/common/vp9_reconintra.c \ @@ -107,35 +253,170 @@ vpx_source_c = \ vp9/common/vp9_scale.c \ vp9/common/vp9_scan.c \ vp9/common/vp9_seg_common.c \ + vp9/common/vp9_textblit.c \ + vp9/common/vp9_thread.c \ + vp9/common/vp9_thread_common.c \ vp9/common/vp9_tile_common.c \ - vp9/common/vp9_treecoder.c \ vp9/common/x86/vp9_asm_stubs.c \ + vp9/common/x86/vp9_high_loopfilter_intrin_sse2.c \ vp9/common/x86/vp9_idct_intrin_sse2.c \ + vp9/common/x86/vp9_idct_intrin_ssse3.c \ + vp9/common/x86/vp9_loopfilter_intrin_avx2.c \ vp9/common/x86/vp9_loopfilter_intrin_sse2.c \ - vp9/decoder/vp9_dboolhuff.c \ + vp9/common/x86/vp9_subpixel_8t_intrin_avx2.c \ + vp9/common/x86/vp9_subpixel_8t_intrin_ssse3.c \ + vp9/decoder/vp9_decodeframe.c \ vp9/decoder/vp9_decodemv.c \ - vp9/decoder/vp9_decodframe.c \ + vp9/decoder/vp9_decoder.c \ vp9/decoder/vp9_detokenize.c \ vp9/decoder/vp9_dsubexp.c \ - vp9/decoder/vp9_onyxd_if.c \ - vp9/decoder/vp9_thread.c \ + vp9/decoder/vp9_dthread.c \ + vp9/decoder/vp9_read_bit_buffer.c \ + vp9/decoder/vp9_reader.c \ + vp9/encoder/arm/neon/vp9_avg_neon.c \ + vp9/encoder/arm/neon/vp9_dct_neon.c \ + vp9/encoder/arm/neon/vp9_quantize_neon.c \ + vp9/encoder/arm/neon/vp9_sad4d_neon.c \ + vp9/encoder/arm/neon/vp9_sad_neon.c \ + vp9/encoder/arm/neon/vp9_subtract_neon.c \ + vp9/encoder/arm/neon/vp9_variance_neon.c \ + vp9/encoder/vp9_aq_complexity.c \ + vp9/encoder/vp9_aq_cyclicrefresh.c \ + vp9/encoder/vp9_aq_variance.c \ + vp9/encoder/vp9_avg.c \ + vp9/encoder/vp9_bitstream.c \ + vp9/encoder/vp9_context_tree.c \ + vp9/encoder/vp9_cost.c \ + vp9/encoder/vp9_dct.c \ + vp9/encoder/vp9_denoiser.c \ + vp9/encoder/vp9_encodeframe.c \ + vp9/encoder/vp9_encodemb.c \ + vp9/encoder/vp9_encodemv.c \ + vp9/encoder/vp9_encoder.c \ + vp9/encoder/vp9_ethread.c \ + vp9/encoder/vp9_extend.c \ + vp9/encoder/vp9_firstpass.c \ + vp9/encoder/vp9_lookahead.c \ + vp9/encoder/vp9_mbgraph.c \ + vp9/encoder/vp9_mcomp.c \ + vp9/encoder/vp9_picklpf.c \ + vp9/encoder/vp9_pickmode.c \ + vp9/encoder/vp9_quantize.c \ + vp9/encoder/vp9_ratectrl.c \ + vp9/encoder/vp9_rd.c \ + vp9/encoder/vp9_rdopt.c \ + vp9/encoder/vp9_resize.c \ + vp9/encoder/vp9_sad.c \ + vp9/encoder/vp9_segmentation.c \ + vp9/encoder/vp9_skin_detection.c \ + vp9/encoder/vp9_speed_features.c \ + vp9/encoder/vp9_ssim.c \ + vp9/encoder/vp9_subexp.c \ + vp9/encoder/vp9_svc_layercontext.c \ + vp9/encoder/vp9_temporal_filter.c \ + vp9/encoder/vp9_tokenize.c \ + vp9/encoder/vp9_treewriter.c \ + vp9/encoder/vp9_variance.c \ + vp9/encoder/vp9_write_bit_buffer.c \ + vp9/encoder/vp9_writer.c \ + vp9/encoder/x86/vp9_avg_intrin_sse2.c \ + vp9/encoder/x86/vp9_dct32x32_avx2.c \ + vp9/encoder/x86/vp9_dct32x32_sse2.c \ + vp9/encoder/x86/vp9_dct_avx2.c \ + vp9/encoder/x86/vp9_dct_impl_sse2.c \ + vp9/encoder/x86/vp9_dct_sse2.c \ + vp9/encoder/x86/vp9_dct_ssse3.c \ + vp9/encoder/x86/vp9_denoiser_sse2.c \ + vp9/encoder/x86/vp9_error_intrin_avx2.c \ + vp9/encoder/x86/vp9_highbd_block_error_intrin_sse2.c \ + vp9/encoder/x86/vp9_highbd_quantize_intrin_sse2.c \ + vp9/encoder/x86/vp9_highbd_variance_sse2.c \ + vp9/encoder/x86/vp9_quantize_sse2.c \ + vp9/encoder/x86/vp9_sad4d_intrin_avx2.c \ + vp9/encoder/x86/vp9_sad_intrin_avx2.c \ + vp9/encoder/x86/vp9_subpel_variance_impl_intrin_avx2.c \ + vp9/encoder/x86/vp9_variance_avx2.c \ + vp9/encoder/x86/vp9_variance_impl_intrin_avx2.c \ + vp9/encoder/x86/vp9_variance_sse2.c \ + vp9/vp9_cx_iface.c \ vp9/vp9_dx_iface.c \ - vpx/src/vpx_codec.c \ - vpx/src/vpx_decoder.c \ - vpx/src/vpx_encoder.c \ - vpx/src/vpx_image.c \ + vpxdec.c \ + vpxenc.c \ + vpx_mem/memory_manager/hmm_alloc.c \ + vpx_mem/memory_manager/hmm_base.c \ + vpx_mem/memory_manager/hmm_dflt_abort.c \ + vpx_mem/memory_manager/hmm_grow.c \ + vpx_mem/memory_manager/hmm_largest.c \ + vpx_mem/memory_manager/hmm_resize.c \ + vpx_mem/memory_manager/hmm_shrink.c \ + vpx_mem/memory_manager/hmm_true.c \ vpx_mem/vpx_mem.c \ - vpx_ports/x86_cpuid.c \ + vpx_mem/vpx_mem_tracker.c \ + vpx_ports/arm_cpudetect.c \ vpx_scale/generic/gen_scalers.c \ vpx_scale/generic/vpx_scale.c \ vpx_scale/generic/yv12config.c \ vpx_scale/generic/yv12extend.c \ - vpx_scale/vpx_scale_asm_offsets.c \ + vpx_scale/mips/dspr2/yv12extend_dspr2.c \ vpx_scale/vpx_scale_rtcd.c \ + vpx_scale/win32/scaleopt.c \ + vpx/src/svc_encodeframe.c \ + vpx/src/vpx_codec.c \ + vpx/src/vpx_decoder.c \ + vpx/src/vpx_encoder.c \ + vpx/src/vpx_image.c \ + vpx/src/vpx_psnr.c \ + vpxstats.c \ + warnings.c \ + y4menc.c \ + y4minput.c \ $(NULL) vpx_source_h = \ + args.h \ + ivfdec.h \ + ivfenc.h \ + md5_utils.h \ + rate_hist.h \ + test/acm_random.h \ + test/clear_system_state.h \ + test/codec_factory.h \ + test/decode_test_driver.h \ + test/encode_test_driver.h \ + test/i420_video_source.h \ + test/ivf_video_source.h \ + test/md5_helper.h \ + test/register_state_check.h \ + test/test_vectors.h \ + test/util.h \ + test/video_source.h \ + test/webm_video_source.h \ + test/y4m_video_source.h \ + test/yuv_video_source.h \ + third_party/googletest/src/include/gtest/gtest.h \ + third_party/libyuv/include/libyuv/basic_types.h \ + third_party/libyuv/include/libyuv/compare.h \ + third_party/libyuv/include/libyuv/convert_argb.h \ + third_party/libyuv/include/libyuv/convert_from_argb.h \ + third_party/libyuv/include/libyuv/convert_from.h \ + third_party/libyuv/include/libyuv/convert.h \ + third_party/libyuv/include/libyuv/cpu_id.h \ + third_party/libyuv/include/libyuv/mjpeg_decoder.h \ + third_party/libyuv/include/libyuv/planar_functions.h \ + third_party/libyuv/include/libyuv/rotate_argb.h \ + third_party/libyuv/include/libyuv/rotate.h \ + third_party/libyuv/include/libyuv/row.h \ + third_party/libyuv/include/libyuv/scale_argb.h \ + third_party/libyuv/include/libyuv/scale.h \ + third_party/libyuv/include/libyuv/scale_row.h \ + third_party/libyuv/include/libyuv/version.h \ + third_party/libyuv/include/libyuv/video_common.h \ + tools_common.h \ + video_common.h \ + video_reader.h \ + video_writer.h \ vp8/common/alloccommon.h \ + vp8/common/arm/bilinearfilter_arm.h \ vp8/common/blockd.h \ vp8/common/coefupdateprobs.h \ vp8/common/common.h \ @@ -153,9 +434,9 @@ vpx_source_h = \ vp8/common/mv.h \ vp8/common/onyxc_int.h \ vp8/common/onyxd.h \ + vp8/common/onyx.h \ vp8/common/postproc.h \ vp8/common/ppflags.h \ - vp8/common/pragmas.h \ vp8/common/quant_common.h \ vp8/common/reconinter.h \ vp8/common/reconintra4x4.h \ @@ -171,28 +452,59 @@ vpx_source_h = \ vp8/decoder/decodemv.h \ vp8/decoder/decoderthreading.h \ vp8/decoder/detokenize.h \ + vp8/decoder/ec_types.h \ + vp8/decoder/error_concealment.h \ vp8/decoder/onyxd_int.h \ vp8/decoder/treereader.h \ + vp8/encoder/bitstream.h \ + vp8/encoder/block.h \ + vp8/encoder/boolhuff.h \ + vp8/encoder/dct_value_cost.h \ + vp8/encoder/dct_value_tokens.h \ + vp8/encoder/defaultcoefcounts.h \ + vp8/encoder/denoising.h \ + vp8/encoder/encodeframe.h \ + vp8/encoder/encodeintra.h \ + vp8/encoder/encodemb.h \ + vp8/encoder/encodemv.h \ + vp8/encoder/firstpass.h \ + vp8/encoder/lookahead.h \ + vp8/encoder/mcomp.h \ + vp8/encoder/modecosts.h \ + vp8/encoder/mr_dissim.h \ + vp8/encoder/onyx_int.h \ + vp8/encoder/pickinter.h \ + vp8/encoder/quantize.h \ + vp8/encoder/ratectrl.h \ + vp8/encoder/rdopt.h \ + vp8/encoder/segmentation.h \ + vp8/encoder/tokenize.h \ + vp8/encoder/treewriter.h \ + vp9/common/mips/dspr2/vp9_common_dspr2.h \ + vp9/common/mips/dspr2/vp9_loopfilter_filters_dspr2.h \ + vp9/common/mips/dspr2/vp9_loopfilter_macros_dspr2.h \ + vp9/common/mips/dspr2/vp9_loopfilter_masks_dspr2.h \ vp9/common/vp9_alloccommon.h \ vp9/common/vp9_blockd.h \ - vp9/common/vp9_common.h \ vp9/common/vp9_common_data.h \ + vp9/common/vp9_common.h \ vp9/common/vp9_convolve.h \ - vp9/common/vp9_default_coef_probs.h \ vp9/common/vp9_entropy.h \ vp9/common/vp9_entropymode.h \ vp9/common/vp9_entropymv.h \ vp9/common/vp9_enums.h \ - vp9/common/vp9_extend.h \ vp9/common/vp9_filter.h \ - vp9/common/vp9_findnearmv.h \ + vp9/common/vp9_frame_buffers.h \ vp9/common/vp9_idct.h \ vp9/common/vp9_loopfilter.h \ + vp9/common/vp9_mfqe.h \ vp9/common/vp9_mv.h \ vp9/common/vp9_mvref_common.h \ vp9/common/vp9_onyxc_int.h \ + vp9/common/vp9_postproc.h \ vp9/common/vp9_ppflags.h \ vp9/common/vp9_pred_common.h \ + vp9/common/vp9_prob.h \ vp9/common/vp9_quant_common.h \ vp9/common/vp9_reconinter.h \ vp9/common/vp9_reconintra.h \ @@ -200,48 +512,140 @@ vpx_source_h = \ vp9/common/vp9_scan.h \ vp9/common/vp9_seg_common.h \ vp9/common/vp9_systemdependent.h \ + vp9/common/vp9_textblit.h \ + vp9/common/vp9_thread_common.h \ + vp9/common/vp9_thread.h \ vp9/common/vp9_tile_common.h \ - vp9/common/vp9_treecoder.h \ - vp9/decoder/vp9_dboolhuff.h \ + vp9/common/x86/vp9_idct_intrin_sse2.h \ + vp9/decoder/vp9_decodeframe.h \ vp9/decoder/vp9_decodemv.h \ - vp9/decoder/vp9_decodframe.h \ + vp9/decoder/vp9_decoder.h \ vp9/decoder/vp9_detokenize.h \ vp9/decoder/vp9_dsubexp.h \ - vp9/decoder/vp9_onyxd.h \ - vp9/decoder/vp9_onyxd_int.h \ + vp9/decoder/vp9_dthread.h \ vp9/decoder/vp9_read_bit_buffer.h \ - vp9/decoder/vp9_thread.h \ - vp9/decoder/vp9_thread.h \ - vp9/decoder/vp9_treereader.h \ + vp9/decoder/vp9_reader.h \ + vp9/encoder/vp9_aq_complexity.h \ + vp9/encoder/vp9_aq_cyclicrefresh.h \ + vp9/encoder/vp9_aq_variance.h \ + vp9/encoder/vp9_bitstream.h \ + vp9/encoder/vp9_block.h \ + vp9/encoder/vp9_context_tree.h \ + vp9/encoder/vp9_cost.h \ + vp9/encoder/vp9_dct.h \ + vp9/encoder/vp9_denoiser.h \ + vp9/encoder/vp9_encodeframe.h \ + vp9/encoder/vp9_encodemb.h \ + vp9/encoder/vp9_encodemv.h \ + vp9/encoder/vp9_encoder.h \ + vp9/encoder/vp9_ethread.h \ + vp9/encoder/vp9_extend.h \ + vp9/encoder/vp9_firstpass.h \ + vp9/encoder/vp9_lookahead.h \ + vp9/encoder/vp9_mbgraph.h \ + vp9/encoder/vp9_mcomp.h \ + vp9/encoder/vp9_picklpf.h \ + vp9/encoder/vp9_pickmode.h \ + vp9/encoder/vp9_quantize.h \ + vp9/encoder/vp9_ratectrl.h \ + vp9/encoder/vp9_rd.h \ + vp9/encoder/vp9_rdopt.h \ + vp9/encoder/vp9_resize.h \ + vp9/encoder/vp9_segmentation.h \ + vp9/encoder/vp9_skin_detection.h \ + vp9/encoder/vp9_speed_features.h \ + vp9/encoder/vp9_ssim.h \ + vp9/encoder/vp9_subexp.h \ + vp9/encoder/vp9_svc_layercontext.h \ + vp9/encoder/vp9_temporal_filter.h \ + vp9/encoder/vp9_tokenize.h \ + vp9/encoder/vp9_treewriter.h \ + vp9/encoder/vp9_variance.h \ + vp9/encoder/vp9_write_bit_buffer.h \ + vp9/encoder/vp9_writer.h \ + vp9/encoder/x86/vp9_dct_sse2.h \ vp9/vp9_iface_common.h \ + vpxenc.h \ vpx/internal/vpx_codec_internal.h \ - vpx/vp8.h \ - vpx/vp8dx.h \ - vpx/vpx_codec.h \ - vpx/vpx_decoder.h \ - vpx/vpx_encoder.h \ - vpx/vpx_image.h \ - vpx/vpx_integer.h \ + vpx/internal/vpx_psnr.h \ vpx_mem/include/vpx_mem_intrnl.h \ + vpx_mem/include/vpx_mem_tracker.h \ + vpx_mem/memory_manager/include/cavl_if.h \ + vpx_mem/memory_manager/include/cavl_impl.h \ + vpx_mem/memory_manager/include/heapmm.h \ + vpx_mem/memory_manager/include/hmm_cnfg.h \ + vpx_mem/memory_manager/include/hmm_intrnl.h \ vpx_mem/vpx_mem.h \ - vpx_ports/asm_offsets.h \ + vpx_ports/arm.h \ + vpx_ports/config.h \ vpx_ports/emmintrin_compat.h \ vpx_ports/mem.h \ + vpx_ports/mem_ops_aligned.h \ + vpx_ports/mem_ops.h \ vpx_ports/vpx_once.h \ vpx_ports/vpx_timer.h \ vpx_ports/x86.h \ vpx_scale/vpx_scale.h \ vpx_scale/yv12config.h \ + vpxstats.h \ + vpx/svc_context.h \ + vpx/vp8cx.h \ + vpx/vp8dx.h \ + vpx/vp8.h \ + vpx/vpx_codec.h \ + vpx/vpx_decoder.h \ + vpx/vpx_encoder.h \ + vpx/vpx_frame_buffer.h \ + vpx/vpx_image.h \ + vpx/vpx_integer.h \ + vpx_scale_rtcd.h \ + warnings.h \ + webmdec.h \ + webmenc.h \ + y4menc.h \ + y4minput.h \ $(NULL) vpx_source_asm = \ + third_party/libyuv/source/row_x86.asm \ + third_party/libyuv/source/x86inc.asm \ third_party/x86inc/x86inc.asm \ + vp8/common/arm/armv6/bilinearfilter_v6.asm \ + vp8/common/arm/armv6/copymem16x16_v6.asm \ + vp8/common/arm/armv6/copymem8x4_v6.asm \ + vp8/common/arm/armv6/copymem8x8_v6.asm \ + vp8/common/arm/armv6/dc_only_idct_add_v6.asm \ + vp8/common/arm/armv6/dequant_idct_v6.asm \ + vp8/common/arm/armv6/dequantize_v6.asm \ + vp8/common/arm/armv6/filter_v6.asm \ + vp8/common/arm/armv6/idct_v6.asm \ + vp8/common/arm/armv6/intra4x4_predict_v6.asm \ + vp8/common/arm/armv6/iwalsh_v6.asm \ + vp8/common/arm/armv6/loopfilter_v6.asm \ + vp8/common/arm/armv6/simpleloopfilter_v6.asm \ + vp8/common/arm/armv6/sixtappredict8x4_v6.asm \ + vp8/common/arm/armv6/vp8_sad16x16_armv6.asm \ + vp8/common/arm/armv6/vp8_variance16x16_armv6.asm \ + vp8/common/arm/armv6/vp8_variance8x8_armv6.asm \ + vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_h_armv6.asm \ + vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_hv_armv6.asm \ + vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_v_armv6.asm \ + vp8/common/ppc/copy_altivec.asm \ + vp8/common/ppc/filter_altivec.asm \ + vp8/common/ppc/filter_bilinear_altivec.asm \ + vp8/common/ppc/idctllm_altivec.asm \ + vp8/common/ppc/loopfilter_filters_altivec.asm \ + vp8/common/ppc/platform_altivec.asm \ + vp8/common/ppc/recon_altivec.asm \ + vp8/common/ppc/sad_altivec.asm \ + vp8/common/ppc/variance_altivec.asm \ + vp8/common/ppc/variance_subpixel_altivec.asm \ vp8/common/x86/dequantize_mmx.asm \ vp8/common/x86/idctllm_mmx.asm \ vp8/common/x86/idctllm_sse2.asm \ vp8/common/x86/iwalsh_mmx.asm \ vp8/common/x86/iwalsh_sse2.asm \ - vp8/common/x86/loopfilter_block_sse2.asm \ + vp8/common/x86/loopfilter_block_sse2_x86_64.asm \ vp8/common/x86/loopfilter_mmx.asm \ vp8/common/x86/loopfilter_sse2.asm \ vp8/common/x86/mfqe_sse2.asm \ @@ -260,12 +664,53 @@ vpx_source_asm = \ vp8/common/x86/variance_impl_mmx.asm \ vp8/common/x86/variance_impl_sse2.asm \ vp8/common/x86/variance_impl_ssse3.asm \ + vp8/encoder/arm/armv6/vp8_mse16x16_armv6.asm \ + vp8/encoder/arm/armv6/vp8_short_fdct4x4_armv6.asm \ + vp8/encoder/arm/armv6/walsh_v6.asm \ + vp8/encoder/ppc/encodemb_altivec.asm \ + vp8/encoder/ppc/fdct_altivec.asm \ + vp8/encoder/ppc/rdopt_altivec.asm \ + vp8/encoder/x86/dct_mmx.asm \ + vp8/encoder/x86/dct_sse2.asm \ + vp8/encoder/x86/encodeopt.asm \ + vp8/encoder/x86/fwalsh_sse2.asm \ + vp8/encoder/x86/quantize_mmx.asm \ + vp8/encoder/x86/ssim_opt_x86_64.asm \ + vp8/encoder/x86/subtract_mmx.asm \ + vp8/encoder/x86/subtract_sse2.asm \ + vp8/encoder/x86/temporal_filter_apply_sse2.asm \ + vp9/common/arm/neon/vp9_avg_neon_asm.asm \ + vp9/common/arm/neon/vp9_convolve8_avg_neon_asm.asm \ + vp9/common/arm/neon/vp9_convolve8_neon_asm.asm \ + vp9/common/arm/neon/vp9_copy_neon_asm.asm \ + vp9/common/arm/neon/vp9_idct16x16_1_add_neon_asm.asm \ + vp9/common/arm/neon/vp9_idct16x16_add_neon_asm.asm \ + vp9/common/arm/neon/vp9_idct32x32_1_add_neon_asm.asm \ + vp9/common/arm/neon/vp9_idct32x32_add_neon_asm.asm \ + vp9/common/arm/neon/vp9_idct4x4_1_add_neon_asm.asm \ + vp9/common/arm/neon/vp9_idct4x4_add_neon_asm.asm \ + vp9/common/arm/neon/vp9_idct8x8_1_add_neon_asm.asm \ + vp9/common/arm/neon/vp9_idct8x8_add_neon_asm.asm \ + vp9/common/arm/neon/vp9_loopfilter_16_neon_asm.asm \ + vp9/common/arm/neon/vp9_loopfilter_4_neon_asm.asm \ + vp9/common/arm/neon/vp9_loopfilter_8_neon_asm.asm \ + vp9/common/arm/neon/vp9_mb_lpf_neon.asm \ + vp9/common/arm/neon/vp9_reconintra_neon_asm.asm \ + vp9/common/arm/neon/vp9_save_reg_neon.asm \ vp9/common/x86/vp9_copy_sse2.asm \ - vp9/common/x86/vp9_intrapred_sse2.asm \ - vp9/common/x86/vp9_intrapred_ssse3.asm \ - vp9/common/x86/vp9_loopfilter_mmx.asm \ - vp9/common/x86/vp9_subpixel_8t_sse2.asm \ - vp9/common/x86/vp9_subpixel_8t_ssse3.asm \ + vp9/common/x86/vp9_high_intrapred_sse2.asm \ + vp9/common/x86/vp9_high_subpixel_8t_sse2.asm \ + vp9/common/x86/vp9_high_subpixel_bilinear_sse2.asm \ + vp9/common/x86/vp9_idct_ssse3_x86_64.asm \ + vp9/encoder/x86/vp9_sad4d_sse2.asm \ + vp9/encoder/x86/vp9_sad_sse2.asm \ + vp9/encoder/x86/vp9_sad_sse3.asm \ + vp9/encoder/x86/vp9_sad_sse4.asm \ + vp9/encoder/x86/vp9_sad_ssse3.asm \ + vp9/encoder/x86/vp9_ssim_opt_x86_64.asm \ + vp9/encoder/x86/vp9_subpel_variance.asm \ + vp9/encoder/x86/vp9_subtract_sse2.asm \ + vp9/encoder/x86/vp9_temporal_filter_apply_sse2.asm \ vpx_ports/emms.asm \ vpx_ports/x86_abi_support.asm \ $(NULL) From 0f3e8139567ee8658aba68657a53f040cd94c29e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 23 Nov 2015 17:21:23 +0200 Subject: [PATCH 2201/3781] vaapipostproc: Correctly detect the caps change This is a quick fix for regression introuduced by the commit 757833230bc73b8e3b4e31649e4618ba802bea51 With out this, the gst_vaapipostproc_create() will never get invoked. https://bugzilla.gnome.org/show_bug.cgi?id=758543 --- gst/vaapi/gstvaapipostproc.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 982b69e844..7334fdf276 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -855,14 +855,6 @@ video_info_changed (GstVideoInfo * old_vip, GstVideoInfo * new_vip) return FALSE; } -static inline gboolean -video_info_is_filled (GstVideoInfo * info) -{ - return (GST_VIDEO_INFO_FORMAT (info) > GST_VIDEO_FORMAT_UNKNOWN - && GST_VIDEO_INFO_WIDTH (info) > 0 - && GST_VIDEO_INFO_HEIGHT (info) > 0); -} - static gboolean video_info_update (GstCaps * caps, GstVideoInfo * info, gboolean * caps_changed_ptr) @@ -874,7 +866,7 @@ video_info_update (GstCaps * caps, GstVideoInfo * info, *caps_changed_ptr = FALSE; if (video_info_changed (info, &vi)) { - *caps_changed_ptr = video_info_is_filled (info); + *caps_changed_ptr = TRUE; *info = vi; } From e111ad4574dbed99288ff4424f2b5411fe3f78a0 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 24 Nov 2015 17:14:20 +0200 Subject: [PATCH 2202/3781] build: libvpx: Add missing source file --- ext/libvpx/sources.frag | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/libvpx/sources.frag b/ext/libvpx/sources.frag index 2c5680538a..a6feecad35 100644 --- a/ext/libvpx/sources.frag +++ b/ext/libvpx/sources.frag @@ -378,6 +378,7 @@ vpx_source_h = \ ivfenc.h \ md5_utils.h \ rate_hist.h \ + vp8_rtcd.h \ test/acm_random.h \ test/clear_system_state.h \ test/codec_factory.h \ From d38d4c617c146148c69550885fc381c048f65157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 25 Nov 2015 15:11:28 +0200 Subject: [PATCH 2203/3781] build: declare correctly parse lib built files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a continuation of commit fc8a0d12 When declaring BUILT_SOURCES, those files should not be distributed. This patch avoids the distribution of the generated source code. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=755525 --- gst/vaapi/Makefile.am | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 7a5f31a0f6..1d5a250b50 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -187,20 +187,18 @@ libgstvaapi_1_4p_parse_gen_source_h = \ libgstvaapi_parse_gen_sources = \ $(libgstvaapi_parse_gen_source_c) \ $(libgstvaapi_parse_gen_source_h) \ - $(libgstvaapi_1_4p_parse_gen_source_c) \ - $(libgstvaapi_1_4p_parse_gen_source_h) \ - $(NUL) - -libgstvaapi_parse_source_c = gstvaapiparse.c $(libgstvaapi_parse_gen_source_c) -libgstvaapi_parse_source_h = gstvaapiparse.h $(libgstvaapi_parse_gen_source_h) + $(NULL) if USE_GST_API_1_4p -libgstvaapi_parse_source_c += $(libgstvaapi_1_4p_parse_gen_source_c) -libgstvaapi_parse_source_h += $(libgstvaapi_1_4p_parse_gen_source_h) +libgstvaapi_parse_gen_source_c += $(libgstvaapi_1_4p_parse_gen_source_c) +libgstvaapi_parse_gen_source_h += $(libgstvaapi_1_4p_parse_gen_source_h) endif -libgstvaapi_parse_la_SOURCES = $(libgstvaapi_parse_source_c) -noinst_HEADERS += $(libgstvaapi_parse_source_h) +libgstvaapi_parse_la_SOURCES = gstvaapiparse.c gstvaapiparse.h +nodist_libgstvaapi_parse_la_SOURCES = \ + $(libgstvaapi_parse_gen_source_c) \ + $(libgstvaapi_parse_gen_source_h) \ + $(NULL) libgstvaapi_parse_la_CFLAGS = \ -DGST_USE_UNSTABLE_API \ @@ -266,10 +264,6 @@ EXTRA_DIST = \ $(libgstvaapi_egl_source_h) \ $(libgstvaapi_1_2p_source_c) \ $(libgstvaapi_1_2p_source_h) \ - $(libgstvaapi_parse_source_c) \ - $(libgstvaapi_parse_source_h) \ - $(libgstvaapi_1_4p_parse_gen_source_c) \ - $(libgstvaapi_1_4p_parse_gen_source_h) \ $(NULL) -include $(top_srcdir)/git.mk From fd73557d2c65443e0578c533b7bdfacb608f207d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 25 Nov 2015 15:12:53 +0200 Subject: [PATCH 2204/3781] build: add gsth265parse patches conditionally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As gsth265parse was added in GStreamer 1.4, and gstreamer-vaapi still support GStreamer 1.2, the patching of gsth265parse must be conditional to the target GStreamer version. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=755525 --- gst/vaapi/Makefile.am | 4 ++++ patches/videoparsers/Makefile.am | 6 +++++- patches/videoparsers/series.frag | 7 +++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 1d5a250b50..e99493e0a9 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -230,6 +230,10 @@ videoparsers_patches_dir = \ include $(videoparsers_patches_dir)/series.frag videoparsers_patches = \ $(videoparsers_patches_base:%=$(top_srcdir)/patches/videoparsers/%) +if USE_GST_API_1_4p +videoparsers_patches += \ + $(videoparsers_patches_1_4p:%=$(top_srcdir)/patches/videoparsers/%) +endif videoparsers_orig_sources = \ $(libgstvaapi_parse_gen_sources:%=$(videoparsers_sources_dir)/%) diff --git a/patches/videoparsers/Makefile.am b/patches/videoparsers/Makefile.am index 401b2ad75e..cf1b2a87e8 100644 --- a/patches/videoparsers/Makefile.am +++ b/patches/videoparsers/Makefile.am @@ -1,5 +1,9 @@ include series.frag -EXTRA_DIST = series.frag $(videoparsers_patches_base) +EXTRA_DIST = \ + series.frag \ + $(videoparsers_patches_base) \ + $(videoparsers_patches_1_4p) \ + $(NULL) -include $(top_srcdir)/git.mk diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index 5d06453a84..d9f809ce09 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -5,6 +5,9 @@ videoparsers_patches_base = \ 0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch \ 0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ 0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch \ - 0005-h265parse-include-gstvaapiparse.h.patch \ - 0006-h265parse-fix-build-with-GStreamer-1.5.patch \ + $(NULL) + +videoparsers_patches_1_4p = \ + 0005-h265parse-include-gstvaapiparse.h.patch \ + 0006-h265parse-fix-build-with-GStreamer-1.5.patch \ $(NULL) From 52eaafcd6c8f27d50ffff0ca8d18310d9378654b Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 27 Nov 2015 14:24:55 +0200 Subject: [PATCH 2205/3781] patches/videoparsers: h264: Disable passthorugh mode enabling This is a quick fix for regression introduced by the upstream commit e8908f5aeef952566f6bccde743c7735d3f8c6ef in h264 videoparser. The patch is disabling the passthrough mode, otherwise it will break multi-layer mvc stream parsing. https://bugzilla.gnome.org/show_bug.cgi?id=758656 --- ...64-Disable-passthorugh-mode-enabling.patch | 43 +++++++++++++++++++ ...6-h265parse-include-gstvaapiparse.h.patch} | 0 ...5parse-fix-build-with-GStreamer-1.5.patch} | 0 patches/videoparsers/series.frag | 5 ++- 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 patches/videoparsers/0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch rename patches/videoparsers/{0005-h265parse-include-gstvaapiparse.h.patch => 0006-h265parse-include-gstvaapiparse.h.patch} (100%) rename patches/videoparsers/{0006-h265parse-fix-build-with-GStreamer-1.5.patch => 0007-h265parse-fix-build-with-GStreamer-1.5.patch} (100%) diff --git a/patches/videoparsers/0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch b/patches/videoparsers/0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch new file mode 100644 index 0000000000..4366e70897 --- /dev/null +++ b/patches/videoparsers/0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch @@ -0,0 +1,43 @@ +From 90251ef253564e7e53c754205cb506e863a93a6c Mon Sep 17 00:00:00 2001 +From: Sreerenj Balachandran +Date: Thu, 26 Nov 2015 19:13:43 +0200 +Subject: [PATCH] videoparsers: h264: Disable passthorugh mode enabling + +Enabling passthorugh mode for optimization is cauing multiple +issues while parsing MVC streams. Specifically if streams have +two separate layers (base-view and non-base-view). + +Proper fixes needed in many places: +(handle prefix nal unit, handle non-base-view slice nal extension, +fix the picture_start detection for multi-layer-mvc streams etc) + +https://bugzilla.gnome.org/show_bug.cgi?id=758656 +--- + gst/vaapi/gsth264parse.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index 915c2d7..445a791 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -2356,6 +2356,9 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) + } + } + ++ /* Fixme: setting passthrough mode for MVC streams causing multiple ++ * issues. Disabing passthourgh mode for now */ ++#if 0 + /* If SPS/PPS and a keyframe have been parsed, and we're not converting, + * we might switch to passthrough mode now on the basis that we've seen + * the SEI packets and know optional caps params (such as multiview). +@@ -2367,6 +2370,7 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) + gst_base_parse_set_passthrough (parse, TRUE); + } + } ++#endif + + gst_h264_parse_reset_frame (h264parse); + +-- +2.5.0 + diff --git a/patches/videoparsers/0005-h265parse-include-gstvaapiparse.h.patch b/patches/videoparsers/0006-h265parse-include-gstvaapiparse.h.patch similarity index 100% rename from patches/videoparsers/0005-h265parse-include-gstvaapiparse.h.patch rename to patches/videoparsers/0006-h265parse-include-gstvaapiparse.h.patch diff --git a/patches/videoparsers/0006-h265parse-fix-build-with-GStreamer-1.5.patch b/patches/videoparsers/0007-h265parse-fix-build-with-GStreamer-1.5.patch similarity index 100% rename from patches/videoparsers/0006-h265parse-fix-build-with-GStreamer-1.5.patch rename to patches/videoparsers/0007-h265parse-fix-build-with-GStreamer-1.5.patch diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index d9f809ce09..ae09dbcb26 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -5,9 +5,10 @@ videoparsers_patches_base = \ 0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch \ 0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ 0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch \ + 0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch \ $(NULL) videoparsers_patches_1_4p = \ - 0005-h265parse-include-gstvaapiparse.h.patch \ - 0006-h265parse-fix-build-with-GStreamer-1.5.patch \ + 0006-h265parse-include-gstvaapiparse.h.patch \ + 0007-h265parse-fix-build-with-GStreamer-1.5.patch \ $(NULL) From d7bd0a4c103db08a20368975eafd397b3fab6a9f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 27 Nov 2015 12:29:11 +0200 Subject: [PATCH 2206/3781] build: Add gmodule dependency for libgstvaapi_egl https://bugzilla.gnome.org/show_bug.cgi?id=756259 --- configure.ac | 8 ++++++++ gst-libs/gst/vaapi/Makefile.am | 2 ++ 2 files changed, 10 insertions(+) diff --git a/configure.ac b/configure.ac index a8996dae93..900fce8d61 100644 --- a/configure.ac +++ b/configure.ac @@ -24,6 +24,9 @@ m4_define([gst_vaapi_lt_age], [0]) # glib version number m4_define([glib_version], [2.32]) +# gmodule version number +m4_define([gmodule_version], [2.32]) + # gstreamer version number m4_define([gst_api_version], [autodetect]) m4_define([gst12_version], [1.1.90]) @@ -709,6 +712,11 @@ if test "$enable_egl" = "yes" -a $GLES_VERSION_MASK -ne 0; then AC_CHECK_LIB([EGL], [eglGetDisplay], [:], [USE_EGL=0]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" + + dnl Check for GMODULE + GMODULE_VERSION_REQUIRED=gmodule_version + PKG_CHECK_MODULES([GMODULE], [gmodule-2.0 >= $GMODULE_VERSION_REQUIRED]) + AC_SUBST(GMODULE_VERSION_REQUIRED) fi dnl Check for Wayland diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 107ef2a5ca..314fd2d226 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -501,6 +501,7 @@ libgstvaapi_egl_@GST_API_VERSION@_la_CFLAGS = \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ $(GST_BASE_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ $(LIBVA_CFLAGS) \ @@ -509,6 +510,7 @@ libgstvaapi_egl_@GST_API_VERSION@_la_CFLAGS = \ libgstvaapi_egl_@GST_API_VERSION@_la_LIBADD = \ $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ $(GST_LIBS) \ $(GST_BASE_LIBS) \ $(GST_VIDEO_LIBS) \ From 03fed576f0d9076d064cd2022099a6cb67df7c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Nov 2015 10:14:45 +0100 Subject: [PATCH 2207/3781] libs: add gl_get_current_api() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to know which OpenGL API use, we must detect the API type of current context. This patch adds the function gl_get_current_api() which returns the OpenGL API type. This function is an adaptation of gst_gl_context_get_current_gl_api() from GstGL. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=753099 --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 89 ++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_glx.h | 14 ++++ 2 files changed, 103 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index b21cb6c961..974d3a03b5 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -1087,3 +1087,92 @@ gl_unbind_framebuffer_object (GLFramebufferObject * fbo) fbo->is_bound = FALSE; return TRUE; } + +/** + * gl_get_current_api: + * @major: (out): (allow-none): the GL major version + * @minor: (out): (allow-none): the GL minor version + * + * If an error occurs, @major and @minor aren't modified and + * %GST_VAAPI_GL_API_NONE is returned. + * + * This is an adaptation of gst_gl_context_get_current_gl_api() from GstGL. + * + * Returns: The version supported by the OpenGL context current in the calling + * thread or %GST_VAAPI_GL_API_NONE + */ +GstVaapiGLApi +gl_get_current_api (guint * major, guint * minor) +{ + const gchar *version; + gint maj, min, n; + GstVaapiGLApi ret = (1 << 31); + + while (ret != GST_VAAPI_GL_API_NONE) { + version = (const gchar *) glGetString (GL_VERSION); + if (!version) + goto next; + + /* strlen (x.x) == 3 */ + n = strlen (version); + if (n < 3) + goto next; + + if (g_strstr_len (version, 9, "OpenGL ES")) { + /* strlen (OpenGL ES x.x) == 13 */ + if (n < 13) + goto next; + + sscanf (&version[10], "%d.%d", &maj, &min); + + if (maj <= 0 || min < 0) + goto next; + + if (maj == 1) { + ret = GST_VAAPI_GL_API_GLES1; + break; + } else if (maj == 2 || maj == 3) { + ret = GST_VAAPI_GL_API_GLES2; + break; + } + + goto next; + } else { + sscanf (version, "%d.%d", &maj, &min); + + if (maj <= 0 || min < 0) + goto next; + + if (maj > 3 || (maj == 3 && min > 1)) { + GLuint context_flags = 0; + + ret = GST_VAAPI_GL_API_NONE; + if (!gl_get_param (GL_CONTEXT_PROFILE_MASK, &context_flags)) + break; + + if (context_flags & GL_CONTEXT_CORE_PROFILE_BIT) + ret |= GST_VAAPI_GL_API_OPENGL3; + if (context_flags & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) + ret |= GST_VAAPI_GL_API_OPENGL; + break; + } + + ret = GST_VAAPI_GL_API_OPENGL; + break; + } + + next: + /* iterate through the apis */ + ret >>= 1; + } + + if (ret == GST_VAAPI_GL_API_NONE) + return GST_VAAPI_GL_API_NONE; + + if (major) + *major = maj; + if (minor) + *minor = min; + + return ret; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index d78b3ee74d..42e047f528 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -210,4 +210,18 @@ G_GNUC_INTERNAL gboolean gl_unbind_framebuffer_object (GLFramebufferObject * fbo); +typedef enum { + GST_VAAPI_GL_API_NONE = 0, + GST_VAAPI_GL_API_OPENGL = (1 << 0), + GST_VAAPI_GL_API_OPENGL3 = (1 << 1), + GST_VAAPI_GL_API_GLES1 = (1 << 15), + GST_VAAPI_GL_API_GLES2 = (1 << 16), + + GST_VAAPI_GL_API_ANY = G_MAXUINT32 +} GstVaapiGLApi; + +G_GNUC_INTERNAL +GstVaapiGLApi +gl_get_current_api (guint * major, guint * minor); + #endif /* GST_VAAPI_UTILS_GLX_H */ From da835c750838a50ed0708907aff84f0d0661943f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Nov 2015 10:26:10 +0100 Subject: [PATCH 2208/3781] libs: add gl3_bind_texture_2d() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since OpenGL3.1 removed the fixed pipelines[1] enabling 2D textures is not needed. In particular, the Intel's Mesa implementation complains if it is called. This patch add a new binding function for 2D textures, without enabling gl3_bind_texture_2d()[2]. 1. https://www.opengl.org/wiki/Fixed_Function_Pipeline 2. https://www.opengl.org/wiki/Common_Mistakes#OOP_and_hidden_binding Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=753099 --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 95 +++++++++++++++++++------- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 4 ++ 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 974d3a03b5..37e9375dde 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -465,6 +465,41 @@ gl_swap_buffers (GLContextState * cs) cs->swapped_buffers = TRUE; } +static inline gboolean +_init_texture_state (GLTextureState * ts, GLenum target, GLuint texture, + gboolean enabled) +{ + GLenum binding; + + ts->target = target; + + if (enabled) { + binding = gl_get_texture_binding (target); + if (!binding) + return FALSE; + if (!gl_get_param (binding, &ts->old_texture)) + return FALSE; + ts->was_enabled = TRUE; + ts->was_bound = texture == ts->old_texture; + } else { + ts->old_texture = 0; + ts->was_enabled = FALSE; + ts->was_bound = FALSE; + } + + return TRUE; +} + +static inline gboolean +_bind_enabled_texture (GLenum target, GLuint texture) +{ + gl_purge_errors (); + glBindTexture (target, texture); + if (gl_check_error ()) + return FALSE; + return TRUE; +} + /** * gl_bind_texture: * @ts: a #GLTextureState @@ -479,32 +514,44 @@ gl_swap_buffers (GLContextState * cs) gboolean gl_bind_texture (GLTextureState * ts, GLenum target, GLuint texture) { - GLenum binding; + gboolean enabled; - ts->target = target; - - if (glIsEnabled (target)) { - binding = gl_get_texture_binding (target); - if (!binding) - return FALSE; - if (!gl_get_param (binding, &ts->old_texture)) - return FALSE; - ts->was_enabled = TRUE; - ts->was_bound = texture == ts->old_texture; - if (ts->was_bound) - return TRUE; - } else { - glEnable (target); - ts->old_texture = 0; - ts->was_enabled = FALSE; - ts->was_bound = FALSE; - } - - gl_purge_errors (); - glBindTexture (target, texture); - if (gl_check_error ()) + enabled = (gboolean) glIsEnabled (target); + if (!_init_texture_state (ts, target, texture, enabled)) return FALSE; - return TRUE; + if (ts->was_bound) + return TRUE; + if (!enabled) + glEnable (target); + + return _bind_enabled_texture (target, texture); +} + +/** + * gl3_bind_texture_2d: + * @ts: a #GLTextureState + * @target: the target to which the texture is bound + * @texture: the name of a texture + * + * Binds @texture to the specified @target, while recording the + * previous state in @ts. + * + * This function is for OpenGL3 API and for targets type GL_TEXTURE_2D. + * + * Return value: %TRUE on success + */ +gboolean +gl3_bind_texture_2d (GLTextureState * ts, GLenum target, GLuint texture) +{ + if (target != GL_TEXTURE_2D) + return FALSE; + + if (!_init_texture_state (ts, target, texture, TRUE)) + return FALSE; + if (ts->was_bound) + return TRUE; + + return _bind_enabled_texture (target, texture); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 42e047f528..3fafe5ec99 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -120,6 +120,10 @@ G_GNUC_INTERNAL gboolean gl_bind_texture (GLTextureState * ts, GLenum target, GLuint texture); +G_GNUC_INTERNAL +gboolean +gl3_bind_texture_2d (GLTextureState * ts, GLenum target, GLuint texture); + G_GNUC_INTERNAL void gl_unbind_texture (GLTextureState * ts); From 1e39b59ce8c45669eb240c36e421771e8d5f7e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Nov 2015 10:19:32 +0100 Subject: [PATCH 2209/3781] texture: check for expected target and format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gst_vaapi_texture_glx_new_wrapped() only handles a GL_TEXTURE_2D target and formats GL_RGBA or GL_BGRA. This patch adds a debugging verification of those values. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=753099 --- gst-libs/gst/vaapi/gstvaapitexture_glx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.c b/gst-libs/gst/vaapi/gstvaapitexture_glx.c index abaac944ba..b9eb81faac 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_glx.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.c @@ -264,8 +264,8 @@ gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display, g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); g_return_val_if_fail (texture_id != GL_NONE, NULL); - g_return_val_if_fail (target != GL_NONE, NULL); - g_return_val_if_fail (format != GL_NONE, NULL); + g_return_val_if_fail (target == GL_TEXTURE_2D, NULL); + g_return_val_if_fail (format == GL_RGBA || format == GL_BGRA, NULL); /* Check texture dimensions */ GST_VAAPI_DISPLAY_LOCK (display); From 4897d96945dabf3fa9a222b2d6443904865e34ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Nov 2015 10:34:12 +0100 Subject: [PATCH 2210/3781] texture: detect GL version and use the proper API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When receiving the texture from the application or the video sink, we must know it size and border. To query the texture the API has changed according to the OpenGL version used in the GL context of the application/vsink. This patch checks the current context API type and queries the texture according to this detected API. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=753099 --- gst-libs/gst/vaapi/gstvaapitexture_glx.c | 35 ++++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.c b/gst-libs/gst/vaapi/gstvaapitexture_glx.c index b9eb81faac..dc931f740f 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_glx.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.c @@ -235,6 +235,21 @@ gst_vaapi_texture_glx_new (GstVaapiDisplay * display, guint target, format, width, height); } +/* Can we assume that the vsink/app context API won't change ever? */ +GstVaapiGLApi +gl_get_curent_api_once () +{ + static GstVaapiGLApi cur_api = GST_VAAPI_GL_API_NONE; + static volatile gsize _init = 0; + + if (g_once_init_enter (&_init)) { + cur_api = gl_get_current_api (NULL, NULL); + g_once_init_leave (&_init, 1); + } + + return cur_api; +} + /** * gst_vaapi_texture_glx_new_wrapped: * @display: a #GstVaapiDisplay @@ -258,23 +273,33 @@ GstVaapiTexture * gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display, guint texture_id, guint target, guint format) { - guint width, height, border_width; - GLTextureState ts; + guint width, height, border_width = 0; + GLTextureState ts = { 0, }; gboolean success; + GstVaapiGLApi gl_api; g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); g_return_val_if_fail (texture_id != GL_NONE, NULL); g_return_val_if_fail (target == GL_TEXTURE_2D, NULL); g_return_val_if_fail (format == GL_RGBA || format == GL_BGRA, NULL); + gl_api = gl_get_curent_api_once (); + if (gl_api != GST_VAAPI_GL_API_OPENGL && gl_api != GST_VAAPI_GL_API_OPENGL3) + return NULL; + /* Check texture dimensions */ GST_VAAPI_DISPLAY_LOCK (display); - success = gl_bind_texture (&ts, target, texture_id); + if (gl_api == GST_VAAPI_GL_API_OPENGL) + success = gl_bind_texture (&ts, target, texture_id); + else + success = gl3_bind_texture_2d (&ts, target, texture_id); + if (success) { if (!gl_get_texture_param (target, GL_TEXTURE_WIDTH, &width) || - !gl_get_texture_param (target, GL_TEXTURE_HEIGHT, &height) || - !gl_get_texture_param (target, GL_TEXTURE_BORDER, &border_width)) + !gl_get_texture_param (target, GL_TEXTURE_HEIGHT, &height)) success = FALSE; + if (success && gl_api == GST_VAAPI_GL_API_OPENGL) + success = gl_get_texture_param (target, GL_TEXTURE_BORDER, &border_width); gl_unbind_texture (&ts); } GST_VAAPI_DISPLAY_UNLOCK (display); From da6af8458dd0390f9b773348a2891a4e067aa111 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 7 Dec 2015 12:39:23 +0200 Subject: [PATCH 2211/3781] README: Update --- README | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README b/README index 4df26dc729..69c63ae015 100644 --- a/README +++ b/README @@ -45,7 +45,7 @@ Features -------- * VA-API support from 0.29 to 0.38 - * JPEG, MPEG-2, MPEG-4, H.264 AVC, H.264 MVC, VP8, VC-1 and HEVC ad-hoc decoders + * 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 and HEVC ad-hoc encoders * OpenGL rendering through VA/GLX or GLX texture-from-pixmap + FBO * Support for EGL backend @@ -65,11 +65,11 @@ Requirements Software requirements - * GStreamer 1.2.x (up to including GStreamer 1.6): + * GStreamer 1.4.x (up to including GStreamer 1.6): libglib2.0-dev (>= 2.32) - libgstreamer1.0-dev (>= 1.2.0) - libgstreamer-plugins-base1.0-dev (>= 1.2.0) - libgstreamer-plugins-bad1.0-dev (>= 1.2.0) + libgstreamer1.0-dev (>= 1.4.0) + libgstreamer-plugins-base1.0-dev (>= 1.4.0) + libgstreamer-plugins-bad1.0-dev (>= 1.4.0) * Renderers: DRM: libva-dev (>= 1.1.0), libdrm-dev, libudev-dev From 1ff4d325c5dba367892c16907e25a221a9a975ff Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 7 Dec 2015 12:47:04 +0200 Subject: [PATCH 2212/3781] AUTHORS: Update --- AUTHORS | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index d640d50c0e..cb1e39b845 100644 --- a/AUTHORS +++ b/AUTHORS @@ -8,28 +8,38 @@ This project is maintained by Intel Corporation. Contributors (sorted by first name): -Cong Zhong +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 From 960f50763d791da17283743d7ee8b7bd6417f222 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 7 Dec 2015 12:49:05 +0200 Subject: [PATCH 2213/3781] NEWS: Updates --- NEWS | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 928487663e..a17ea5fd62 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,47 @@ -gst-vaapi NEWS -- summary of changes. 2015-07-15 +gst-vaapi NEWS -- summary of changes. 2015-12-07 Copyright (C) 2010-2011 Splitted-Desktop Systems -Copyright (C) 2011-2013 Intel Corporation +Copyright (C) 2011-2015 Intel Corporation Copyright (C) 2011 Collabora +Version 0.7 - 07.Dec.2015 +* Add VP9 Decoder +* Improvements to HEVC(H265) decoder + + Fix the decoding of dependent slice segment + + Fix decoding of stream when it has temporal sublayers + + Added Workaround to recognize wrongly encoded main profile streams + + Add SEI Header parsing + + Fix the value assigning for delta_chroma_log2_weight_denom + + Fix default value assignment of pred_weight_table + + Fix ChromaOffsetL0/ChromaOffsetL1 calculation + + Add calculation of WpOffsetHalfRangeC + + Fix the scaling list scan order + + Fix the picture addition in dpb() based on spec H265 v3 (04/2015) + + Fix the dpb_add() based on C.5.2.3 + + Fix flushing of dpb for EOS/EOB nal +* Added infrastructure for handling corrupted pictures in h264 decoder [#703921, #751434] +* Add number of fixes and optimizations to GstContext sharing [#757598] +* Add API for dynamic detection of OpenGL API in use [#753099] +* Make vaapidecode + glimagesink combination work with opengl3 [#753099] +* Fix segfault in vaapipostproc [#752558] +* Fix seeking while using GLTextureUpload for rendering [#752929] +* Ported JPEG decoder to new API/ABI changes in codecparser +* Removed gstvaapiuploader [#752777] +* Fix 0/1 frame-rate handling in encoder [#744042] +* Validate chroma sampling according to the VA's RT format in Encoder [#744042] +* Number of improvements in vaapi video memory handling [#744042] +* Stabilization of vaapidecodebin [#749554, #757957] +* Wayland fixes: Don't return GST_FLOW_ERROR on flushing [#753598] +* Add yasm as build dependency +* Remvoved custom(non-official) debian parallel compilation option +* Fix multi-resolution video handling in vaapidecode [#753914] +* Adding stereoscopic/multiview upstream API support [#750835] +* Fixed fps calculation for for forced latency framerate [#755040] +* Fix build issues while disabling built-in codecparsers [#754845] +* Mark support for GStreamer 1.2 as obsolete +* Update libvpx submodule to 1.4.0 +* Fix caps negotiation for meta:GstVideoGLTextureUploadMeta [#756686] +* Fixed leaked display instance in vaapidecodebin [#757595] + Version 0.6 - 15.Jul.2015 * Add HEVC(H265) Decoder * Add HEVC(H265) Encoder From b5f10415d7ec4537bf702bc899be2715950747fd Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 7 Dec 2015 12:52:10 +0200 Subject: [PATCH 2214/3781] 0.7.0 --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 900fce8d61..87aef0e2d2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) -m4_define([gst_vaapi_minor_version], [6]) -m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_minor_version], [7]) +m4_define([gst_vaapi_micro_version], [0]) +m4_define([gst_vaapi_pre_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From 1544842fe3c8191168afa77cd9fe94fc8463eec1 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 7 Dec 2015 16:17:11 +0200 Subject: [PATCH 2215/3781] Bump version for development --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 87aef0e2d2..df0a948e27 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [7]) -m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_pre_version], [0]) +m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_pre_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_pre_version, [0], [], [ From a2171ea0eb84489b5ce522f31c617ee564847e8b Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 7 Dec 2015 17:26:24 +0200 Subject: [PATCH 2216/3781] gstvaapiporfile: Fix string representation of HEVCMain10 profile --- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 650bea5aaf..2377b86999 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -158,7 +158,7 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h265", "main" }, { GST_VAAPI_PROFILE_H265_MAIN10, VAProfileHEVCMain10, - "video/x-h265", "main10" + "video/x-h265", "main-10" }, #endif #if VA_CHECK_VERSION(0,38,0) From 009c2c72c9f14d77fbadbcf9999f7e6d3b4d91cf Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 7 Dec 2015 19:06:28 +0200 Subject: [PATCH 2217/3781] Add definitions for YUV420 with more than 8 bits per channel --- gst-libs/gst/vaapi/gstvaapisurface.h | 4 +++- gst-libs/gst/vaapi/gstvaapiutils.c | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 50e6d04347..b176a2cdfe 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -65,6 +65,7 @@ G_BEGIN_DECLS * @GST_VAAPI_CHROMA_TYPE_YUV400: YUV 4:0:0 chroma format (grayscale) * @GST_VAAPI_CHROMA_TYPE_RGB32: 32-bit RGB chroma format * @GST_VAAPI_CHROMA_TYPE_RGB16: 16-bit RGB chroma format + * @GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: YUV 4:2:0 chroma format, more than 8 bits per channel * * The set of all chroma types for #GstVaapiSurface. */ @@ -77,7 +78,8 @@ typedef enum GST_VAAPI_CHROMA_TYPE_YUV410, GST_VAAPI_CHROMA_TYPE_YUV400, GST_VAAPI_CHROMA_TYPE_RGB32, - GST_VAAPI_CHROMA_TYPE_RGB16 + GST_VAAPI_CHROMA_TYPE_RGB16, + GST_VAAPI_CHROMA_TYPE_YUV420_10BPP } GstVaapiChromaType; /** diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 117fd4eedf..c1cca4633c 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -231,6 +231,9 @@ string_of_va_chroma_format (guint chroma_format) MAP (RGB32); MAP (RGBP); #endif +#if VA_CHECK_VERSION(0,38,1) + MAP (YUV420_10BPP); +#endif #undef MAP default: break; @@ -299,6 +302,11 @@ from_GstVaapiChromaType (guint chroma_type) case GST_VAAPI_CHROMA_TYPE_RGB16: format = VA_RT_FORMAT_RGB16; break; +#endif +#if VA_CHECK_VERSION(0,38,1) + case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: + format = VA_RT_FORMAT_YUV420_10BPP; + break; #endif default: format = 0; From 9ccdbce4bdf9cbd25db202ca81a1e5d89c180aee Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 1 Jan 2001 04:59:28 +0200 Subject: [PATCH 2218/3781] gstvaapisurfacepool: Add new API to create surface pool based on chroma type This new API gst_vaapi_surface_pool_new_with_chroma_type() is for creating a new GstVaapiVideoPool of GstVaapiSurfaces with the specified chroam type and dimensions. The underlying format of the surfaces is implementation (driver) defined. --- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 36 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurfacepool.h | 4 +++ 2 files changed, 40 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 02c0606041..65bc65c677 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -164,3 +164,39 @@ error: gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pool)); return NULL; } + +/** + * gst_vaapi_surface_pool_new_with_chroma_type: + * @display: a #GstVaapiDisplay + * @chroma_type: a #GstVaapiChromatype + * @width: the desired width, in pixels + * @height: the desired height, in pixels + * + * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the specified + * chroam type and dimensions. The underlying format of the surfaces is + * implementation (driver) defined. + * + * Return value: the newly allocated #GstVaapiVideoPool + */ +GstVaapiVideoPool * +gst_vaapi_surface_pool_new_with_chroma_type (GstVaapiDisplay * display, + GstVaapiChromaType chroma_type, guint width, guint height) +{ + GstVaapiVideoPool *pool; + GstVideoInfo vi; + + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (chroma_type > 0, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + + gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_ENCODED, width, height); + + pool = gst_vaapi_surface_pool_new_full (display, &vi, 0); + if (!pool) + return NULL; + + GST_VAAPI_SURFACE_POOL (pool)->chroma_type = chroma_type; + + return pool; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index e0529a22f4..8c5a1efeae 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -44,6 +44,10 @@ GstVaapiVideoPool * gst_vaapi_surface_pool_new_full (GstVaapiDisplay * display, const GstVideoInfo * vip, guint flags); +GstVaapiVideoPool * +gst_vaapi_surface_pool_new_with_chroma_type (GstVaapiDisplay * display, + GstVaapiChromaType chroma_type, guint width, guint height); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_POOL_H */ From 61045041c4e9f8159e3262ae0df0949d889804ef Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 8 Dec 2015 16:14:11 +0200 Subject: [PATCH 2219/3781] Add 10 HEVC 10 bit decoding support Only supporting vaapidecode ! vaapisink combination for now. Missing dependencies: 1: No support for P010 video format in GStreamer 2: No support for P010 vaGetImage()/vaPutimage() in vaapi-intel-driver 3: As a result of 1&2 , we have no support for Vaapi Video memory mapping through GstVideoMeta. Right now we only set chroma format (YUV420 with more than 8 bits per channel) for surface pool and keeping GST_VIDEO_FORMAT as ENCODED. The underlying format of the surfaces is implementation (driver) defined, which is P010. --- gst-libs/gst/vaapi/gstvaapicontext.c | 5 +++-- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 10 +++++++--- gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h | 2 +- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 113c960f9e..36fc18af3a 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -149,8 +149,9 @@ context_create_surfaces (GstVaapiContext * context) if (!context->surfaces_pool) { context->surfaces_pool = - gst_vaapi_surface_pool_new (GST_VAAPI_OBJECT_DISPLAY (context), - GST_VIDEO_FORMAT_ENCODED, cip->width, cip->height); + gst_vaapi_surface_pool_new_with_chroma_type (GST_VAAPI_OBJECT_DISPLAY (context), + cip->chroma_type, cip->width, cip->height); + if (!context->surfaces_pool) return FALSE; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index c308d27899..26b8a4a625 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1102,7 +1102,7 @@ ensure_context (GstVaapiDecoderH265 * decoder, GstH265SPS * sps) priv->profile = profile; } - chroma_type = gst_vaapi_utils_h265_get_chroma_type (sps->chroma_format_idc); + chroma_type = gst_vaapi_utils_h265_get_chroma_type (sps->chroma_format_idc, sps->bit_depth_luma_minus8 + 8); if (!chroma_type) { GST_ERROR ("unsupported chroma_format_idc %u", sps->chroma_format_idc); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 0a80d3db7d..5eebf9b2c0 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -281,16 +281,19 @@ gst_vaapi_utils_h265_get_level_limits_table (guint * out_length_ptr) /** Returns GstVaapiChromaType from H.265 chroma_format_idc value */ GstVaapiChromaType -gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc) +gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, guint luma_bit_depth) { - GstVaapiChromaType chroma_type; + GstVaapiChromaType chroma_type = (GstVaapiChromaType) 0; switch (chroma_format_idc) { case 0: chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400; break; case 1: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + if (luma_bit_depth == 8) + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + else if (luma_bit_depth > 8) + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; break; case 2: chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; @@ -317,6 +320,7 @@ gst_vaapi_utils_h265_get_chroma_format_idc (GstVaapiChromaType chroma_type) chroma_format_idc = 0; break; case GST_VAAPI_CHROMA_TYPE_YUV420: + case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: chroma_format_idc = 1; break; case GST_VAAPI_CHROMA_TYPE_YUV422: diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h index 3991ee96a4..5e9f53211d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h @@ -93,7 +93,7 @@ gst_vaapi_utils_h265_get_level_limits_table (guint * out_length_ptr); /* Returns GstVaapiChromaType from H.265 chroma_format_idc value */ G_GNUC_INTERNAL GstVaapiChromaType -gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc); +gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, guint luma_bit_depth); /* Returns H.265 chroma_format_idc value from GstVaapiChromaType */ G_GNUC_INTERNAL From 1a84348e766220831aa26bfa50b8aeefec0ebdd4 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Wed, 9 Dec 2015 18:24:50 +0200 Subject: [PATCH 2220/3781] build: Don't ignore GST_PLUGIN_PATH_1_0 even if the directory doesn't exist yet https://bugzilla.gnome.org/show_bug.cgi?id=759184 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index df0a948e27..e29ada930a 100644 --- a/configure.ac +++ b/configure.ac @@ -526,7 +526,7 @@ AC_SUBST(GST_PLUGIN_LDFLAGS) dnl Check for the GStreamer plugins directory AC_ARG_VAR([GST_PLUGIN_PATH_1_0], [installation path for gstreamer-vaapi plugin elements for GStreamer 1.0]) AC_MSG_CHECKING([for GStreamer plugins directory]) -if test -d "$GST_PLUGIN_PATH_1_0"; then +if test -n "$GST_PLUGIN_PATH_1_0"; then GST_PLUGINS_DIR="$GST_PLUGIN_PATH_1_0" else GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_PKG_VERSION --variable pluginsdir` From 8f77d541039759a82ca65b1bcd65ff1406eca34a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 13 Jan 2016 19:17:02 +0100 Subject: [PATCH 2221/3781] vaapisink: ignore frame if its upload failed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When gst_vaapi_plugin_base_get_input_buffer() fail to copy the input buffer into a VAAPI buffer, the return value is GST_FLOW_NOT_SUPPORTED, and it was ignored by the vaapisink, leading to a segmentation fault. This patch ignores the frame that generated the GST_FLOW_NOT_SUPPORTED returned by gst_vaapi_plugin_base_get_input_buffer(), avoiding the segmentation fault, but doing and effort to continue rendering. This is the same behavior of ximagesink. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=759332 --- gst/vaapi/gstvaapisink.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index fd22524227..f52c4da8ed 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1333,7 +1333,9 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) ret = gst_vaapi_plugin_base_get_input_buffer (GST_VAAPI_PLUGIN_BASE (sink), src_buffer, &buffer); - if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_SUPPORTED) + if (ret == GST_FLOW_NOT_SUPPORTED) + return GST_FLOW_OK; /* let's ignore the frame if it couldn't be uploaded */ + if (ret != GST_FLOW_OK) return ret; meta = gst_buffer_get_vaapi_video_meta (buffer); From b8da44bdea43df3dba1eff292508416c2a4388a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 14 Jan 2016 17:36:24 +0100 Subject: [PATCH 2222/3781] vaapipostproc: check ANY caps at transform_caps() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When transforming downstream caps we should check for ANY caps from peer pad, otherwise we get a segmentation fault. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=759893 --- gst/vaapi/gstvaapipostproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 7334fdf276..ab5b78821d 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1100,7 +1100,7 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, peer_caps = gst_pad_peer_query_caps (GST_BASE_TRANSFORM_SRC_PAD (trans), postproc->allowed_srcpad_caps); - if (gst_caps_is_empty (peer_caps)) + if (gst_caps_is_any (peer_caps) || gst_caps_is_empty (peer_caps)) return peer_caps; if (!gst_caps_is_fixed (peer_caps)) peer_caps = gst_caps_fixate (peer_caps); From e4ed64b7313fb8f5199b312852ecef2b3f238c15 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Wed, 28 Oct 2015 09:56:46 +0100 Subject: [PATCH 2223/3781] wayland: free the frame in frame_release_callback() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This basically reverts 62c3888b76afc69f714a020957e8c5dd9d98f561 (wayland: decouple wl_buffer from frame). Otherwise the frame may be overwritten while it is still used by the compositer: The frame done callback (frame_done_callback()) is called, when the compositor is done processing the frame and hands it to the hardware. The buffer release callback (frame_release_callback()) is called when the buffer memory is no longer used. This can be quite some time later: E.g. if weston (with the DRM backend) puts the buffer on a hardware plane, then then buffer release callback is called when the kernel is done with the buffer. This is usually when the next frame is shown, so most likely after the frame done callback for the next frame! Since 70eff01d36a2870cbf06ffb91c2a941e8cb6b804 "wayland: sync() when destroy()" the mentioned possible leak should no longer be a problem, so reverting this change should cause no leaking buffers. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=758848 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index aeffc38b3c..aab48793f4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -368,7 +368,6 @@ frame_done_callback (void *data, struct wl_callback *callback, uint32_t time) GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); g_atomic_pointer_compare_and_exchange (&priv->last_frame, frame, NULL); - frame_state_free (frame); g_atomic_int_dec_and_test (&priv->num_frames_pending); } @@ -380,6 +379,7 @@ static void frame_release_callback (void *data, struct wl_buffer *wl_buffer) { wl_buffer_destroy (wl_buffer); + frame_state_free (data); } static const struct wl_buffer_listener frame_buffer_listener = { @@ -542,11 +542,8 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, priv->opaque_region = NULL; } - /* @TODO: It is not OK to use internal event_queue here, since there - * may still be a WL_BUFFER_RELEASE event when we destroy the - * event_queue in gst_vaapi_window_wayland_destroy (). */ wl_proxy_set_queue ((struct wl_proxy *) buffer, priv->event_queue); - wl_buffer_add_listener (buffer, &frame_buffer_listener, NULL); + wl_buffer_add_listener (buffer, &frame_buffer_listener, frame); frame->callback = wl_surface_frame (priv->surface); wl_callback_add_listener (frame->callback, &frame_callback_listener, frame); From 046c880d8aee6fc972ccc8374017bf8b3a2b8d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Dec 2015 14:12:22 +0100 Subject: [PATCH 2224/3781] build: fix check for GstJpegParser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Right now the local JPEG parser is always compiled because the check for the upstreamed version is broken: it looks for an non existent symbol: GstJpegImage. This patch changes that check for< GstJpegFrameHdr. Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index e29ada930a..861b5cfd21 100644 --- a/configure.ac +++ b/configure.ac @@ -367,7 +367,7 @@ AC_CACHE_CHECK([for JPEG parser], AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], - [[GstJpegImage jpeg_image;]])], + [[GstJpegFrameHdr frame_hdr;]])], [ac_cv_have_gst_jpeg_parser="yes"], [ac_cv_have_gst_jpeg_parser="no"] ) From 258214aa334a82d6ac976414a7d3b181ed071371 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 8 Dec 2015 00:36:36 +0200 Subject: [PATCH 2225/3781] Remove libvpx submodule We will be using upstream codecparsers always. No more internal libvpx ! --- .gitmodules | 3 - autogen.sh | 1 - configure.ac | 18 - debian.upstream/libgstvaapi.install.in | 1 - ext/Makefile.am | 2 - ext/libvpx/Makefile.am | 160 ----- ext/libvpx/gstlibvpx.c | 119 ---- ext/libvpx/gstlibvpx.h | 65 -- ext/libvpx/libgstcodecparsers_vpx.vers | 16 - ext/libvpx/sources.frag | 717 --------------------- ext/libvpx/upstream | 1 - gst-libs/gst/codecparsers/Makefile.am | 23 +- gst-libs/gst/codecparsers/gstvaapilibvpx.c | 104 --- 13 files changed, 2 insertions(+), 1228 deletions(-) delete mode 100644 ext/libvpx/Makefile.am delete mode 100644 ext/libvpx/gstlibvpx.c delete mode 100644 ext/libvpx/gstlibvpx.h delete mode 100644 ext/libvpx/libgstcodecparsers_vpx.vers delete mode 100644 ext/libvpx/sources.frag delete mode 160000 ext/libvpx/upstream delete mode 100644 gst-libs/gst/codecparsers/gstvaapilibvpx.c diff --git a/.gitmodules b/.gitmodules index bb34d0d12d..a72ea38931 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "ext/codecparsers"] path = ext/codecparsers url = https://github.com/01org/gstreamer-codecparsers.git -[submodule "ext/libvpx/upstream"] - path = ext/libvpx/upstream - url = https://chromium.googlesource.com/webm/libvpx diff --git a/autogen.sh b/autogen.sh index b36c8dc801..245970a49a 100755 --- a/autogen.sh +++ b/autogen.sh @@ -26,7 +26,6 @@ else submodule_init="yes" fi done - [ -f ext/libvpx/upstream/configure ] || submodule_init="yes" if test "$submodule_init" = "yes"; then $GIT submodule init fi diff --git a/configure.ac b/configure.ac index 861b5cfd21..734e1cfdc8 100644 --- a/configure.ac +++ b/configure.ac @@ -113,11 +113,6 @@ AC_ARG_ENABLE(builtin_codecparsers, [enable built-in codecparsers @<:@default=yes@:>@]), [], [enable_builtin_codecparsers="yes"]) -AC_ARG_ENABLE(builtin_libvpx, - AS_HELP_STRING([--enable-builtin-libvpx], - [enable built-in libvpx @<:@default=yes@:>@]), - [], [enable_builtin_libvpx="yes"]) - AC_ARG_ENABLE([encoders], AS_HELP_STRING([--enable-encoders], [enable video encoders @<:@default=yes@:>@]), @@ -153,14 +148,6 @@ AC_ARG_WITH([glapi], [build with the specified OpenGL APIs @<:@default=default_glapi@:>@]), [GLAPI="$with_glapi"], [GLAPI=default_glapi]) - -dnl Check fr YASM -AC_ARG_VAR([YASM], [Path to yasm program, if any]) -AC_PATH_PROG([YASM], [yasm]) -if test -z "$YASM" -a "$enable_builtin_libvpx" = "yes"; then - AC_MSG_ERROR([yasm is needed to build libvpx sources]) -fi - dnl Check for PATCH AC_ARG_VAR([PATCH], [Path to patch program, if any]) AC_PATH_PROG([PATCH], [patch]) @@ -378,9 +365,6 @@ AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_JPEG], [test "$ac_cv_have_gst_jpeg_parser" != "yes"]) dnl ... VP8 parser, not upstream yet -if test "$enable_builtin_libvpx" = "yes"; then - ac_cv_have_gst_vp8_parser="no" -fi AC_CACHE_CHECK([for VP8 parser], ac_cv_have_gst_vp8_parser, [ saved_CPPFLAGS="$CPPFLAGS" @@ -399,7 +383,6 @@ AC_CACHE_CHECK([for VP8 parser], ]) AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_VP8], [test "$ac_cv_have_gst_vp8_parser" != "yes"]) -AM_CONDITIONAL([USE_BUILTIN_LIBVPX], [test "$enable_builtin_libvpx" = "yes"]) dnl ... VP9 parser, with required extensions AC_CACHE_CHECK([for VP9 parser], @@ -1142,7 +1125,6 @@ debian.upstream/libgstvaapi-x11.install.in docs/reference/plugins/Makefile docs/reference/plugins/plugins-docs.xml ext/Makefile - ext/libvpx/Makefile gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/base/Makefile diff --git a/debian.upstream/libgstvaapi.install.in b/debian.upstream/libgstvaapi.install.in index afb5221421..f719a6f347 100644 --- a/debian.upstream/libgstvaapi.install.in +++ b/debian.upstream/libgstvaapi.install.in @@ -1,2 +1 @@ -debian/tmp/usr/lib/libgstcodecparsers_vpx.so.* debian/tmp/usr/lib/libgstvaapi-@GST_API_VERSION@.so.* diff --git a/ext/Makefile.am b/ext/Makefile.am index 7a9a147487..b639f03c82 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -1,5 +1,3 @@ -SUBDIRS = libvpx - EXTRA_DIST = codecparsers_srcdir = \ diff --git a/ext/libvpx/Makefile.am b/ext/libvpx/Makefile.am deleted file mode 100644 index d8ff808ee8..0000000000 --- a/ext/libvpx/Makefile.am +++ /dev/null @@ -1,160 +0,0 @@ -# Makefile.am - Rules for the built-in libvpx sources -# -# Copyright (C) 2014 Intel Corporation -# Author: Gwenole Beauchesne -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -# Boston, MA 02110-1301, USA. - -lib_LTLIBRARIES = -if USE_BUILTIN_LIBVPX -lib_LTLIBRARIES += libgstcodecparsers_vpx.la -endif - -gst_vpx_source_c = gstlibvpx.c -gst_vpx_source_h = gstlibvpx.h - -vpx_upstream = upstream -vpx_srcdir = $(srcdir)/$(vpx_upstream) -vpx_builddir = $(builddir)/$(vpx_upstream) -vpx_versions = libgstcodecparsers_vpx.vers - -vpx_cflags = \ - -I$(vpx_srcdir) \ - -I$(vpx_builddir) \ - $(NULL) - -vpx_libs = \ - -Wl,-Bsymbolic \ - -Wl,--whole-archive \ - -Wl,$(vpx_builddir)/libvpx.a \ - -Wl,--no-whole-archive \ - -Wl,--version-script,$(srcdir)/$(vpx_versions) \ - -Wl,-lpthread \ - -Wl,-lm \ - $(NULL) - -libgstcodecparsers_vpx_la_SOURCES = $(gst_vpx_source_c) -libgstcodecparsers_vpx_la_CFLAGS = $(vpx_cflags) -libgstcodecparsers_vpx_la_DEPENDENCIES = vpx.build -libgstcodecparsers_vpx_la_LINK = $(LINK) $(vpx_libs) -EXTRA_libgstcodecparsers_vpx_la_DEPENDENCIES = $(srcdir)/$(vpx_versions) - -VPX_DEBUG = yes - -# Codecs -VP8_DECODER = enable -VP8_ENCODER = disable -VP9_DECODER = disable -VP9_ENCODER = disable - -clean-local: vpx.clean -maintainer-clean-local: vpx.maintainer.clean - -vpx.build: vpx.configure.stamp - @$(MAKE) -C $(vpx_builddir) - -vpx.clean: - @[ -d $(vpx_builddir) ] && \ - $(MAKE) -C $(vpx_builddir) clean || : - rm -f vpx.configure.stamp - -vpx.maintainer.clean: vpx.clean - rm -rf $(vpx_builddir) - -DISTCLEANFILES = \ - $(vpx_builddir)/config.mk \ - $(vpx_builddir)/config.log \ - $(vpx_builddir)/libs-x86_64-linux-gcc.mk \ - $(vpx_builddir)/Makefile \ - $(vpx_builddir)/vpx_config.c \ - $(vpx_builddir)/vpx_config.h \ - $(vpx_builddir)/vpx_config.asm \ - $(NULL) - -vpx.configure.stamp: - @[ -d $(vpx_builddir) ] || mkdir $(vpx_builddir); \ - cd $(vpx_builddir) ; \ - test "$(VPX_DEBUG)" = "yes" && \ - CONFIGURE_FLAGS="$$CONFIGURE_FLAGS --enable-debug" ; \ - $(abs_srcdir)/$(vpx_upstream)/configure $$CONFIGURE_FLAGS \ - --enable-static \ - --enable-pic \ - --disable-shared \ - --$(VP8_DECODER)-vp8-decoder \ - --$(VP8_ENCODER)-vp8-encoder \ - --$(VP9_DECODER)-vp9-decoder \ - --$(VP9_ENCODER)-vp9-encoder \ - --enable-runtime-cpu-detect \ - --disable-examples \ - --disable-docs \ - --disable-unit-tests && \ - cd .. && \ - touch $@ - -$(gst_vpx_source_c): vpx.build - -CLEANFILES = vpx.configure.stamp - -# Files for packaging -include $(srcdir)/sources.frag - -vpx_sources = \ - $(vpx_srcdir)/AUTHORS \ - $(vpx_srcdir)/CHANGELOG \ - $(vpx_srcdir)/LICENSE \ - $(vpx_srcdir)/PATENTS \ - $(vpx_srcdir)/build/make/ads2armasm_ms.pl \ - $(vpx_srcdir)/build/make/ads2gas_apple.pl \ - $(vpx_srcdir)/build/make/ads2gas.pl \ - $(vpx_srcdir)/build/make/Android.mk \ - $(vpx_srcdir)/build/make/armlink_adapter.sh \ - $(vpx_srcdir)/build/make/configure.sh \ - $(vpx_srcdir)/build/make/gen_asm_deps.sh \ - $(vpx_srcdir)/build/make/gen_msvs_def.sh \ - $(vpx_srcdir)/build/make/gen_msvs_proj.sh \ - $(vpx_srcdir)/build/make/gen_msvs_sln.sh \ - $(vpx_srcdir)/build/make/gen_msvs_vcxproj.sh \ - $(vpx_srcdir)/build/make/iosbuild.sh \ - $(vpx_srcdir)/build/make/Makefile \ - $(vpx_srcdir)/build/make/msvs_common.sh \ - $(vpx_srcdir)/build/make/rtcd.pl \ - $(vpx_srcdir)/build/make/thumb.pm \ - $(vpx_srcdir)/build/make/version.sh \ - $(vpx_srcdir)/configure \ - $(vpx_source_mak:%.mk=$(vpx_srcdir)/%.mk) \ - $(vpx_source_c:%.c=$(vpx_srcdir)/%.c) \ - $(vpx_source_h:%.h=$(vpx_srcdir)/%.h) \ - $(NULL) - -EXTRA_DIST = \ - sources.frag \ - $(gst_vpx_source_h) \ - $(vpx_sources) \ - $(vpx_versions) \ - $(NULL) - -# Avoid implicit rule that tries to compile .asm.o to .asm -dist-hook: - for f in $(vpx_source_asm); do \ - mkdir -p $(distdir)/$(vpx_upstream)/$$(dirname $$f); \ - cp -fpR $(vpx_srcdir)/$$f $(distdir)/$(vpx_upstream)/$$f; \ - done - --include $(top_srcdir)/git.mk - -# Tell version 3.79 and up of GNU make to not build goals in this -# directory in parallel. -.NOTPARALLEL: diff --git a/ext/libvpx/gstlibvpx.c b/ext/libvpx/gstlibvpx.c deleted file mode 100644 index fc376e12ca..0000000000 --- a/ext/libvpx/gstlibvpx.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * gstlibvpx.c - GStreamer/libvpx glue - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include -#include "gstlibvpx.h" - -#define BOOL_DECODER_CAST(bd) \ - ((BOOL_DECODER *)(&(bd)->private[1])) - -bool -vp8_bool_decoder_init (vp8_bool_decoder * bd, const uint8_t * buf, - unsigned int buf_size) -{ - assert ((sizeof (*bd) - sizeof (bd->private[0])) >= sizeof (BOOL_DECODER)); - - bd->private[0] = (uintptr_t)buf; - return vp8dx_start_decode (BOOL_DECODER_CAST (bd), buf, buf_size, - NULL, NULL) == 0; -} - -int -vp8_bool_decoder_read (vp8_bool_decoder * bd, uint8_t prob) -{ - return vp8dx_decode_bool (BOOL_DECODER_CAST (bd), prob); -} - -int -vp8_bool_decoder_read_literal (vp8_bool_decoder * bd, int bits) -{ - return vp8_decode_value (BOOL_DECODER_CAST (bd), bits); -} - -unsigned int -vp8_bool_decoder_get_pos (vp8_bool_decoder * bd_) -{ - BOOL_DECODER *const bd = BOOL_DECODER_CAST (bd_); - - return ((uintptr_t)bd->user_buffer - bd_->private[0]) * 8 - (8 + bd->count); -} - -void -vp8_bool_decoder_get_state (vp8_bool_decoder * bd_, - vp8_bool_decoder_state * state) -{ - BOOL_DECODER *const bd = BOOL_DECODER_CAST (bd_); - - if (bd->count < 0) - vp8dx_bool_decoder_fill (bd); - - state->range = bd->range; - state->value = (uint8_t) ((bd->value) >> (VP8_BD_VALUE_SIZE - 8)); - state->count = (8 + bd->count) % 8; -} - -void -vp8_init_token_update_probs (uint8_t - probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]) -{ - memcpy (probs, vp8_coef_update_probs, sizeof (vp8_coef_update_probs)); -} - -void -vp8_init_default_token_probs (uint8_t - probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]) -{ - memcpy (probs, default_coef_probs, sizeof (default_coef_probs)); -} - -void -vp8_init_mv_update_probs (uint8_t probs[2][MVPcount]) -{ - memcpy (probs[0], vp8_mv_update_probs[0].prob, - sizeof (vp8_mv_update_probs[0].prob)); - memcpy (probs[1], vp8_mv_update_probs[1].prob, - sizeof (vp8_mv_update_probs[1].prob)); -} - -void -vp8_init_default_mv_probs (uint8_t probs[2][MVPcount]) -{ - memcpy (probs[0], vp8_default_mv_context[0].prob, - sizeof (vp8_default_mv_context[0].prob)); - memcpy (probs[1], vp8_default_mv_context[1].prob, - sizeof (vp8_default_mv_context[1].prob)); -} - -void -vp8_init_default_intra_mode_probs (uint8_t y_probs[VP8_YMODES-1], - uint8_t uv_probs[VP8_UV_MODES-1]) -{ - extern const uint8_t vp8_kf_ymode_prob[VP8_YMODES-1]; - extern const uint8_t vp8_kf_uv_mode_prob[VP8_UV_MODES-1]; - - memcpy (y_probs, vp8_kf_ymode_prob, sizeof (vp8_kf_ymode_prob)); - memcpy (uv_probs, vp8_kf_uv_mode_prob, sizeof (vp8_kf_uv_mode_prob)); -} - -void -vp8_init_default_inter_mode_probs (uint8_t y_probs[VP8_YMODES-1], - uint8_t uv_probs[VP8_UV_MODES-1]) -{ - extern const uint8_t vp8_ymode_prob[VP8_YMODES-1]; - extern const uint8_t vp8_uv_mode_prob[VP8_UV_MODES-1]; - - memcpy (y_probs, vp8_ymode_prob, sizeof (vp8_ymode_prob)); - memcpy (uv_probs, vp8_uv_mode_prob, sizeof (vp8_uv_mode_prob)); -} diff --git a/ext/libvpx/gstlibvpx.h b/ext/libvpx/gstlibvpx.h deleted file mode 100644 index d4bd7845aa..0000000000 --- a/ext/libvpx/gstlibvpx.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * gstlibvpx.h - GStreamer/libvpx glue - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef GST_LIBVPX_H -#define GST_LIBVPX_H - -#include -#include - -typedef struct _vp8_bool_decoder vp8_bool_decoder; -typedef struct _vp8_bool_decoder_state vp8_bool_decoder_state; - -struct _vp8_bool_decoder { - uintptr_t private[16]; -}; - -struct _vp8_bool_decoder_state { - uint8_t range; /* Current "range" value (<= 255) */ - uint8_t value; /* Current "value" value */ - uint8_t count; /* Number of bits shifted out of value (<= 7) */ -}; - -bool -vp8_bool_decoder_init (vp8_bool_decoder * bd, const uint8_t * buf, - unsigned int buf_size); - -int -vp8_bool_decoder_read (vp8_bool_decoder * bd, uint8_t prob); - -int -vp8_bool_decoder_read_literal (vp8_bool_decoder * bd, int bits); - -unsigned int -vp8_bool_decoder_get_pos (vp8_bool_decoder * bd); - -void -vp8_bool_decoder_get_state (vp8_bool_decoder * bd, - vp8_bool_decoder_state * state); - -void -vp8_init_token_update_probs (uint8_t probs[4][8][3][11]); - -void -vp8_init_default_token_probs (uint8_t probs[4][8][3][11]); - -void -vp8_init_mv_update_probs (uint8_t probs[2][19]); - -void -vp8_init_default_mv_probs (uint8_t probs[2][19]); - -void -vp8_init_default_intra_mode_probs (uint8_t y_probs[4], uint8_t uv_probs[3]); - -void -vp8_init_default_inter_mode_probs (uint8_t y_probs[4], uint8_t uv_probs[3]); - -#endif /* GST_LIBVPX_H */ diff --git a/ext/libvpx/libgstcodecparsers_vpx.vers b/ext/libvpx/libgstcodecparsers_vpx.vers deleted file mode 100644 index 6c178e72b9..0000000000 --- a/ext/libvpx/libgstcodecparsers_vpx.vers +++ /dev/null @@ -1,16 +0,0 @@ -GSTREAMER { -global: - vp8_bool_decoder_init; - vp8_bool_decoder_read; - vp8_bool_decoder_read_literal; - vp8_bool_decoder_get_pos; - vp8_bool_decoder_get_state; - vp8_init_token_update_probs; - vp8_init_default_token_probs; - vp8_init_mv_update_probs; - vp8_init_default_mv_probs; - vp8_init_default_intra_mode_probs; - vp8_init_default_inter_mode_probs; -local: - *; -}; diff --git a/ext/libvpx/sources.frag b/ext/libvpx/sources.frag deleted file mode 100644 index a6feecad35..0000000000 --- a/ext/libvpx/sources.frag +++ /dev/null @@ -1,717 +0,0 @@ -# sources.frag - Generated list of source files for libvpx (-*- makefile -*-) -# -# Copyright (C) 2014 Intel Corporation -# Author: Gwenole Beauchesne -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -# Boston, MA 02110-1301, USA. - -vpx_source_mak = \ - build/make/Android.mk \ - docs.mk \ - examples.mk \ - libs.mk \ - solution.mk \ - test/android/Android.mk \ - test/test-data.mk \ - test/test.mk \ - third_party/googletest/gtest.mk \ - third_party/libwebm/Android.mk \ - vp8/vp8_common.mk \ - vp8/vp8cx_arm.mk \ - vp8/vp8cx.mk \ - vp8/vp8dx.mk \ - vp9/vp9_common.mk \ - vp9/vp9cx.mk \ - vp9/vp9dx.mk \ - vpx_mem/vpx_mem.mk \ - vpx_ports/vpx_ports.mk \ - vpx_scale/vpx_scale.mk \ - vpx/vpx_codec.mk \ - $(NULL) - -vpx_source_c = \ - args.c \ - examples/decode_to_md5.c \ - examples/decode_with_drops.c \ - examples/postproc.c \ - examples/resize_util.c \ - examples/set_maps.c \ - examples/simple_decoder.c \ - examples/simple_encoder.c \ - examples/twopass_encoder.c \ - examples/vp8cx_set_ref.c \ - examples/vp8_multi_resolution_encoder.c \ - examples/vp9_lossless_encoder.c \ - examples/vp9_spatial_svc_encoder.c \ - examples/vpx_temporal_svc_encoder.c \ - ivfdec.c \ - ivfenc.c \ - md5_utils.c \ - rate_hist.c \ - tools_common.c \ - video_reader.c \ - video_writer.c \ - vp8/common/alloccommon.c \ - vp8/common/arm/armv6/idct_blk_v6.c \ - vp8/common/arm/bilinearfilter_arm.c \ - vp8/common/arm/dequantize_arm.c \ - vp8/common/arm/filter_arm.c \ - vp8/common/arm/loopfilter_arm.c \ - vp8/common/arm/neon/bilinearpredict_neon.c \ - vp8/common/arm/neon/copymem_neon.c \ - vp8/common/arm/neon/dc_only_idct_add_neon.c \ - vp8/common/arm/neon/dequant_idct_neon.c \ - vp8/common/arm/neon/dequantizeb_neon.c \ - vp8/common/arm/neon/idct_blk_neon.c \ - vp8/common/arm/neon/idct_dequant_0_2x_neon.c \ - vp8/common/arm/neon/idct_dequant_full_2x_neon.c \ - vp8/common/arm/neon/iwalsh_neon.c \ - vp8/common/arm/neon/loopfilter_neon.c \ - vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c \ - vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c \ - vp8/common/arm/neon/mbloopfilter_neon.c \ - vp8/common/arm/neon/reconintra_neon.c \ - vp8/common/arm/neon/sad_neon.c \ - vp8/common/arm/neon/shortidct4x4llm_neon.c \ - vp8/common/arm/neon/sixtappredict_neon.c \ - vp8/common/arm/neon/variance_neon.c \ - vp8/common/arm/neon/vp8_subpixelvariance_neon.c \ - vp8/common/arm/variance_arm.c \ - vp8/common/blockd.c \ - vp8/common/context.c \ - vp8/common/debugmodes.c \ - vp8/common/dequantize.c \ - vp8/common/entropy.c \ - vp8/common/entropymode.c \ - vp8/common/entropymv.c \ - vp8/common/extend.c \ - vp8/common/filter.c \ - vp8/common/findnearmv.c \ - vp8/common/generic/systemdependent.c \ - vp8/common/idct_blk.c \ - vp8/common/idctllm.c \ - vp8/common/loopfilter.c \ - vp8/common/loopfilter_filters.c \ - vp8/common/mbpitch.c \ - vp8/common/mfqe.c \ - vp8/common/mips/dspr2/dequantize_dspr2.c \ - vp8/common/mips/dspr2/filter_dspr2.c \ - vp8/common/mips/dspr2/idct_blk_dspr2.c \ - vp8/common/mips/dspr2/idctllm_dspr2.c \ - vp8/common/mips/dspr2/loopfilter_filters_dspr2.c \ - vp8/common/mips/dspr2/reconinter_dspr2.c \ - vp8/common/modecont.c \ - vp8/common/postproc.c \ - vp8/common/ppc/loopfilter_altivec.c \ - vp8/common/ppc/systemdependent.c \ - vp8/common/quant_common.c \ - vp8/common/reconinter.c \ - vp8/common/reconintra4x4.c \ - vp8/common/reconintra.c \ - vp8/common/rtcd.c \ - vp8/common/sad_c.c \ - vp8/common/setupintrarecon.c \ - vp8/common/swapyv12buffer.c \ - vp8/common/textblit.c \ - vp8/common/treecoder.c \ - vp8/common/variance_c.c \ - vp8/common/x86/filter_x86.c \ - vp8/common/x86/idct_blk_mmx.c \ - vp8/common/x86/idct_blk_sse2.c \ - vp8/common/x86/loopfilter_x86.c \ - vp8/common/x86/recon_wrapper_sse2.c \ - vp8/common/x86/variance_mmx.c \ - vp8/common/x86/variance_sse2.c \ - vp8/common/x86/variance_ssse3.c \ - vp8/common/x86/vp8_asm_stubs.c \ - vp8/decoder/dboolhuff.c \ - vp8/decoder/decodeframe.c \ - vp8/decoder/decodemv.c \ - vp8/decoder/detokenize.c \ - vp8/decoder/error_concealment.c \ - vp8/decoder/onyxd_if.c \ - vp8/decoder/threading.c \ - vp8/encoder/arm/dct_arm.c \ - vp8/encoder/arm/neon/denoising_neon.c \ - vp8/encoder/arm/neon/fastquantizeb_neon.c \ - vp8/encoder/arm/neon/shortfdct_neon.c \ - vp8/encoder/arm/neon/subtract_neon.c \ - vp8/encoder/arm/neon/vp8_mse16x16_neon.c \ - vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.c \ - vp8/encoder/bitstream.c \ - vp8/encoder/boolhuff.c \ - vp8/encoder/dct.c \ - vp8/encoder/denoising.c \ - vp8/encoder/encodeframe.c \ - vp8/encoder/encodeintra.c \ - vp8/encoder/encodemb.c \ - vp8/encoder/encodemv.c \ - vp8/encoder/ethreading.c \ - vp8/encoder/firstpass.c \ - vp8/encoder/lookahead.c \ - vp8/encoder/mcomp.c \ - vp8/encoder/modecosts.c \ - vp8/encoder/mr_dissim.c \ - vp8/encoder/onyx_if.c \ - vp8/encoder/pickinter.c \ - vp8/encoder/picklpf.c \ - vp8/encoder/ppc/csystemdependent.c \ - vp8/encoder/quantize.c \ - vp8/encoder/ratectrl.c \ - vp8/encoder/rdopt.c \ - vp8/encoder/segmentation.c \ - vp8/encoder/ssim.c \ - vp8/encoder/temporal_filter.c \ - vp8/encoder/tokenize.c \ - vp8/encoder/treewriter.c \ - vp8/encoder/x86/denoising_sse2.c \ - vp8/encoder/x86/quantize_sse2.c \ - vp8/encoder/x86/quantize_sse4.c \ - vp8/encoder/x86/quantize_ssse3.c \ - vp8/encoder/x86/vp8_enc_stubs_mmx.c \ - vp8/encoder/x86/vp8_enc_stubs_sse2.c \ - vp8/vp8_cx_iface.c \ - vp8/vp8_dx_iface.c \ - vp9/common/arm/neon/vp9_avg_neon.c \ - vp9/common/arm/neon/vp9_convolve8_avg_neon.c \ - vp9/common/arm/neon/vp9_convolve8_neon.c \ - vp9/common/arm/neon/vp9_convolve_neon.c \ - vp9/common/arm/neon/vp9_copy_neon.c \ - vp9/common/arm/neon/vp9_idct16x16_1_add_neon.c \ - vp9/common/arm/neon/vp9_idct16x16_add_neon.c \ - vp9/common/arm/neon/vp9_idct16x16_neon.c \ - vp9/common/arm/neon/vp9_idct32x32_1_add_neon.c \ - vp9/common/arm/neon/vp9_idct32x32_add_neon.c \ - vp9/common/arm/neon/vp9_idct4x4_1_add_neon.c \ - vp9/common/arm/neon/vp9_idct4x4_add_neon.c \ - vp9/common/arm/neon/vp9_idct8x8_1_add_neon.c \ - vp9/common/arm/neon/vp9_idct8x8_add_neon.c \ - vp9/common/arm/neon/vp9_iht4x4_add_neon.c \ - vp9/common/arm/neon/vp9_iht8x8_add_neon.c \ - vp9/common/arm/neon/vp9_loopfilter_16_neon.c \ - vp9/common/arm/neon/vp9_loopfilter_4_neon.c \ - vp9/common/arm/neon/vp9_loopfilter_8_neon.c \ - vp9/common/arm/neon/vp9_loopfilter_neon.c \ - vp9/common/arm/neon/vp9_reconintra_neon.c \ - vp9/common/mips/dspr2/vp9_convolve2_avg_dspr2.c \ - vp9/common/mips/dspr2/vp9_convolve2_avg_horiz_dspr2.c \ - vp9/common/mips/dspr2/vp9_convolve2_dspr2.c \ - vp9/common/mips/dspr2/vp9_convolve2_horiz_dspr2.c \ - vp9/common/mips/dspr2/vp9_convolve2_vert_dspr2.c \ - vp9/common/mips/dspr2/vp9_convolve8_avg_dspr2.c \ - vp9/common/mips/dspr2/vp9_convolve8_avg_horiz_dspr2.c \ - vp9/common/mips/dspr2/vp9_convolve8_dspr2.c \ - vp9/common/mips/dspr2/vp9_convolve8_horiz_dspr2.c \ - vp9/common/mips/dspr2/vp9_convolve8_vert_dspr2.c \ - vp9/common/mips/dspr2/vp9_intrapred16_dspr2.c \ - vp9/common/mips/dspr2/vp9_intrapred4_dspr2.c \ - vp9/common/mips/dspr2/vp9_intrapred8_dspr2.c \ - vp9/common/mips/dspr2/vp9_itrans16_dspr2.c \ - vp9/common/mips/dspr2/vp9_itrans32_cols_dspr2.c \ - vp9/common/mips/dspr2/vp9_itrans32_dspr2.c \ - vp9/common/mips/dspr2/vp9_itrans4_dspr2.c \ - vp9/common/mips/dspr2/vp9_itrans8_dspr2.c \ - vp9/common/mips/dspr2/vp9_loopfilter_filters_dspr2.c \ - vp9/common/mips/dspr2/vp9_mbloop_loopfilter_dspr2.c \ - vp9/common/mips/dspr2/vp9_mblpf_horiz_loopfilter_dspr2.c \ - vp9/common/mips/dspr2/vp9_mblpf_vert_loopfilter_dspr2.c \ - vp9/common/vp9_alloccommon.c \ - vp9/common/vp9_blockd.c \ - vp9/common/vp9_common_data.c \ - vp9/common/vp9_convolve.c \ - vp9/common/vp9_debugmodes.c \ - vp9/common/vp9_entropy.c \ - vp9/common/vp9_entropymode.c \ - vp9/common/vp9_entropymv.c \ - vp9/common/vp9_filter.c \ - vp9/common/vp9_frame_buffers.c \ - vp9/common/vp9_idct.c \ - vp9/common/vp9_loopfilter.c \ - vp9/common/vp9_loopfilter_filters.c \ - vp9/common/vp9_mfqe.c \ - vp9/common/vp9_mvref_common.c \ - vp9/common/vp9_postproc.c \ - vp9/common/vp9_pred_common.c \ - vp9/common/vp9_prob.c \ - vp9/common/vp9_quant_common.c \ - vp9/common/vp9_reconinter.c \ - vp9/common/vp9_reconintra.c \ - vp9/common/vp9_rtcd.c \ - vp9/common/vp9_scale.c \ - vp9/common/vp9_scan.c \ - vp9/common/vp9_seg_common.c \ - vp9/common/vp9_textblit.c \ - vp9/common/vp9_thread.c \ - vp9/common/vp9_thread_common.c \ - vp9/common/vp9_tile_common.c \ - vp9/common/x86/vp9_asm_stubs.c \ - vp9/common/x86/vp9_high_loopfilter_intrin_sse2.c \ - vp9/common/x86/vp9_idct_intrin_sse2.c \ - vp9/common/x86/vp9_idct_intrin_ssse3.c \ - vp9/common/x86/vp9_loopfilter_intrin_avx2.c \ - vp9/common/x86/vp9_loopfilter_intrin_sse2.c \ - vp9/common/x86/vp9_subpixel_8t_intrin_avx2.c \ - vp9/common/x86/vp9_subpixel_8t_intrin_ssse3.c \ - vp9/decoder/vp9_decodeframe.c \ - vp9/decoder/vp9_decodemv.c \ - vp9/decoder/vp9_decoder.c \ - vp9/decoder/vp9_detokenize.c \ - vp9/decoder/vp9_dsubexp.c \ - vp9/decoder/vp9_dthread.c \ - vp9/decoder/vp9_read_bit_buffer.c \ - vp9/decoder/vp9_reader.c \ - vp9/encoder/arm/neon/vp9_avg_neon.c \ - vp9/encoder/arm/neon/vp9_dct_neon.c \ - vp9/encoder/arm/neon/vp9_quantize_neon.c \ - vp9/encoder/arm/neon/vp9_sad4d_neon.c \ - vp9/encoder/arm/neon/vp9_sad_neon.c \ - vp9/encoder/arm/neon/vp9_subtract_neon.c \ - vp9/encoder/arm/neon/vp9_variance_neon.c \ - vp9/encoder/vp9_aq_complexity.c \ - vp9/encoder/vp9_aq_cyclicrefresh.c \ - vp9/encoder/vp9_aq_variance.c \ - vp9/encoder/vp9_avg.c \ - vp9/encoder/vp9_bitstream.c \ - vp9/encoder/vp9_context_tree.c \ - vp9/encoder/vp9_cost.c \ - vp9/encoder/vp9_dct.c \ - vp9/encoder/vp9_denoiser.c \ - vp9/encoder/vp9_encodeframe.c \ - vp9/encoder/vp9_encodemb.c \ - vp9/encoder/vp9_encodemv.c \ - vp9/encoder/vp9_encoder.c \ - vp9/encoder/vp9_ethread.c \ - vp9/encoder/vp9_extend.c \ - vp9/encoder/vp9_firstpass.c \ - vp9/encoder/vp9_lookahead.c \ - vp9/encoder/vp9_mbgraph.c \ - vp9/encoder/vp9_mcomp.c \ - vp9/encoder/vp9_picklpf.c \ - vp9/encoder/vp9_pickmode.c \ - vp9/encoder/vp9_quantize.c \ - vp9/encoder/vp9_ratectrl.c \ - vp9/encoder/vp9_rd.c \ - vp9/encoder/vp9_rdopt.c \ - vp9/encoder/vp9_resize.c \ - vp9/encoder/vp9_sad.c \ - vp9/encoder/vp9_segmentation.c \ - vp9/encoder/vp9_skin_detection.c \ - vp9/encoder/vp9_speed_features.c \ - vp9/encoder/vp9_ssim.c \ - vp9/encoder/vp9_subexp.c \ - vp9/encoder/vp9_svc_layercontext.c \ - vp9/encoder/vp9_temporal_filter.c \ - vp9/encoder/vp9_tokenize.c \ - vp9/encoder/vp9_treewriter.c \ - vp9/encoder/vp9_variance.c \ - vp9/encoder/vp9_write_bit_buffer.c \ - vp9/encoder/vp9_writer.c \ - vp9/encoder/x86/vp9_avg_intrin_sse2.c \ - vp9/encoder/x86/vp9_dct32x32_avx2.c \ - vp9/encoder/x86/vp9_dct32x32_sse2.c \ - vp9/encoder/x86/vp9_dct_avx2.c \ - vp9/encoder/x86/vp9_dct_impl_sse2.c \ - vp9/encoder/x86/vp9_dct_sse2.c \ - vp9/encoder/x86/vp9_dct_ssse3.c \ - vp9/encoder/x86/vp9_denoiser_sse2.c \ - vp9/encoder/x86/vp9_error_intrin_avx2.c \ - vp9/encoder/x86/vp9_highbd_block_error_intrin_sse2.c \ - vp9/encoder/x86/vp9_highbd_quantize_intrin_sse2.c \ - vp9/encoder/x86/vp9_highbd_variance_sse2.c \ - vp9/encoder/x86/vp9_quantize_sse2.c \ - vp9/encoder/x86/vp9_sad4d_intrin_avx2.c \ - vp9/encoder/x86/vp9_sad_intrin_avx2.c \ - vp9/encoder/x86/vp9_subpel_variance_impl_intrin_avx2.c \ - vp9/encoder/x86/vp9_variance_avx2.c \ - vp9/encoder/x86/vp9_variance_impl_intrin_avx2.c \ - vp9/encoder/x86/vp9_variance_sse2.c \ - vp9/vp9_cx_iface.c \ - vp9/vp9_dx_iface.c \ - vpxdec.c \ - vpxenc.c \ - vpx_mem/memory_manager/hmm_alloc.c \ - vpx_mem/memory_manager/hmm_base.c \ - vpx_mem/memory_manager/hmm_dflt_abort.c \ - vpx_mem/memory_manager/hmm_grow.c \ - vpx_mem/memory_manager/hmm_largest.c \ - vpx_mem/memory_manager/hmm_resize.c \ - vpx_mem/memory_manager/hmm_shrink.c \ - vpx_mem/memory_manager/hmm_true.c \ - vpx_mem/vpx_mem.c \ - vpx_mem/vpx_mem_tracker.c \ - vpx_ports/arm_cpudetect.c \ - vpx_scale/generic/gen_scalers.c \ - vpx_scale/generic/vpx_scale.c \ - vpx_scale/generic/yv12config.c \ - vpx_scale/generic/yv12extend.c \ - vpx_scale/mips/dspr2/yv12extend_dspr2.c \ - vpx_scale/vpx_scale_rtcd.c \ - vpx_scale/win32/scaleopt.c \ - vpx/src/svc_encodeframe.c \ - vpx/src/vpx_codec.c \ - vpx/src/vpx_decoder.c \ - vpx/src/vpx_encoder.c \ - vpx/src/vpx_image.c \ - vpx/src/vpx_psnr.c \ - vpxstats.c \ - warnings.c \ - y4menc.c \ - y4minput.c \ - $(NULL) - -vpx_source_h = \ - args.h \ - ivfdec.h \ - ivfenc.h \ - md5_utils.h \ - rate_hist.h \ - vp8_rtcd.h \ - test/acm_random.h \ - test/clear_system_state.h \ - test/codec_factory.h \ - test/decode_test_driver.h \ - test/encode_test_driver.h \ - test/i420_video_source.h \ - test/ivf_video_source.h \ - test/md5_helper.h \ - test/register_state_check.h \ - test/test_vectors.h \ - test/util.h \ - test/video_source.h \ - test/webm_video_source.h \ - test/y4m_video_source.h \ - test/yuv_video_source.h \ - third_party/googletest/src/include/gtest/gtest.h \ - third_party/libyuv/include/libyuv/basic_types.h \ - third_party/libyuv/include/libyuv/compare.h \ - third_party/libyuv/include/libyuv/convert_argb.h \ - third_party/libyuv/include/libyuv/convert_from_argb.h \ - third_party/libyuv/include/libyuv/convert_from.h \ - third_party/libyuv/include/libyuv/convert.h \ - third_party/libyuv/include/libyuv/cpu_id.h \ - third_party/libyuv/include/libyuv/mjpeg_decoder.h \ - third_party/libyuv/include/libyuv/planar_functions.h \ - third_party/libyuv/include/libyuv/rotate_argb.h \ - third_party/libyuv/include/libyuv/rotate.h \ - third_party/libyuv/include/libyuv/row.h \ - third_party/libyuv/include/libyuv/scale_argb.h \ - third_party/libyuv/include/libyuv/scale.h \ - third_party/libyuv/include/libyuv/scale_row.h \ - third_party/libyuv/include/libyuv/version.h \ - third_party/libyuv/include/libyuv/video_common.h \ - tools_common.h \ - video_common.h \ - video_reader.h \ - video_writer.h \ - vp8/common/alloccommon.h \ - vp8/common/arm/bilinearfilter_arm.h \ - vp8/common/blockd.h \ - vp8/common/coefupdateprobs.h \ - vp8/common/common.h \ - vp8/common/default_coef_probs.h \ - vp8/common/entropy.h \ - vp8/common/entropymode.h \ - vp8/common/entropymv.h \ - vp8/common/extend.h \ - vp8/common/filter.h \ - vp8/common/findnearmv.h \ - vp8/common/header.h \ - vp8/common/invtrans.h \ - vp8/common/loopfilter.h \ - vp8/common/modecont.h \ - vp8/common/mv.h \ - vp8/common/onyxc_int.h \ - vp8/common/onyxd.h \ - vp8/common/onyx.h \ - vp8/common/postproc.h \ - vp8/common/ppflags.h \ - vp8/common/quant_common.h \ - vp8/common/reconinter.h \ - vp8/common/reconintra4x4.h \ - vp8/common/setupintrarecon.h \ - vp8/common/swapyv12buffer.h \ - vp8/common/systemdependent.h \ - vp8/common/threading.h \ - vp8/common/treecoder.h \ - vp8/common/variance.h \ - vp8/common/vp8_entropymodedata.h \ - vp8/common/x86/filter_x86.h \ - vp8/decoder/dboolhuff.h \ - vp8/decoder/decodemv.h \ - vp8/decoder/decoderthreading.h \ - vp8/decoder/detokenize.h \ - vp8/decoder/ec_types.h \ - vp8/decoder/error_concealment.h \ - vp8/decoder/onyxd_int.h \ - vp8/decoder/treereader.h \ - vp8/encoder/bitstream.h \ - vp8/encoder/block.h \ - vp8/encoder/boolhuff.h \ - vp8/encoder/dct_value_cost.h \ - vp8/encoder/dct_value_tokens.h \ - vp8/encoder/defaultcoefcounts.h \ - vp8/encoder/denoising.h \ - vp8/encoder/encodeframe.h \ - vp8/encoder/encodeintra.h \ - vp8/encoder/encodemb.h \ - vp8/encoder/encodemv.h \ - vp8/encoder/firstpass.h \ - vp8/encoder/lookahead.h \ - vp8/encoder/mcomp.h \ - vp8/encoder/modecosts.h \ - vp8/encoder/mr_dissim.h \ - vp8/encoder/onyx_int.h \ - vp8/encoder/pickinter.h \ - vp8/encoder/quantize.h \ - vp8/encoder/ratectrl.h \ - vp8/encoder/rdopt.h \ - vp8/encoder/segmentation.h \ - vp8/encoder/tokenize.h \ - vp8/encoder/treewriter.h \ - vp9/common/mips/dspr2/vp9_common_dspr2.h \ - vp9/common/mips/dspr2/vp9_loopfilter_filters_dspr2.h \ - vp9/common/mips/dspr2/vp9_loopfilter_macros_dspr2.h \ - vp9/common/mips/dspr2/vp9_loopfilter_masks_dspr2.h \ - vp9/common/vp9_alloccommon.h \ - vp9/common/vp9_blockd.h \ - vp9/common/vp9_common_data.h \ - vp9/common/vp9_common.h \ - vp9/common/vp9_convolve.h \ - vp9/common/vp9_entropy.h \ - vp9/common/vp9_entropymode.h \ - vp9/common/vp9_entropymv.h \ - vp9/common/vp9_enums.h \ - vp9/common/vp9_filter.h \ - vp9/common/vp9_frame_buffers.h \ - vp9/common/vp9_idct.h \ - vp9/common/vp9_loopfilter.h \ - vp9/common/vp9_mfqe.h \ - vp9/common/vp9_mv.h \ - vp9/common/vp9_mvref_common.h \ - vp9/common/vp9_onyxc_int.h \ - vp9/common/vp9_postproc.h \ - vp9/common/vp9_ppflags.h \ - vp9/common/vp9_pred_common.h \ - vp9/common/vp9_prob.h \ - vp9/common/vp9_quant_common.h \ - vp9/common/vp9_reconinter.h \ - vp9/common/vp9_reconintra.h \ - vp9/common/vp9_scale.h \ - vp9/common/vp9_scan.h \ - vp9/common/vp9_seg_common.h \ - vp9/common/vp9_systemdependent.h \ - vp9/common/vp9_textblit.h \ - vp9/common/vp9_thread_common.h \ - vp9/common/vp9_thread.h \ - vp9/common/vp9_tile_common.h \ - vp9/common/x86/vp9_idct_intrin_sse2.h \ - vp9/decoder/vp9_decodeframe.h \ - vp9/decoder/vp9_decodemv.h \ - vp9/decoder/vp9_decoder.h \ - vp9/decoder/vp9_detokenize.h \ - vp9/decoder/vp9_dsubexp.h \ - vp9/decoder/vp9_dthread.h \ - vp9/decoder/vp9_read_bit_buffer.h \ - vp9/decoder/vp9_reader.h \ - vp9/encoder/vp9_aq_complexity.h \ - vp9/encoder/vp9_aq_cyclicrefresh.h \ - vp9/encoder/vp9_aq_variance.h \ - vp9/encoder/vp9_bitstream.h \ - vp9/encoder/vp9_block.h \ - vp9/encoder/vp9_context_tree.h \ - vp9/encoder/vp9_cost.h \ - vp9/encoder/vp9_dct.h \ - vp9/encoder/vp9_denoiser.h \ - vp9/encoder/vp9_encodeframe.h \ - vp9/encoder/vp9_encodemb.h \ - vp9/encoder/vp9_encodemv.h \ - vp9/encoder/vp9_encoder.h \ - vp9/encoder/vp9_ethread.h \ - vp9/encoder/vp9_extend.h \ - vp9/encoder/vp9_firstpass.h \ - vp9/encoder/vp9_lookahead.h \ - vp9/encoder/vp9_mbgraph.h \ - vp9/encoder/vp9_mcomp.h \ - vp9/encoder/vp9_picklpf.h \ - vp9/encoder/vp9_pickmode.h \ - vp9/encoder/vp9_quantize.h \ - vp9/encoder/vp9_ratectrl.h \ - vp9/encoder/vp9_rd.h \ - vp9/encoder/vp9_rdopt.h \ - vp9/encoder/vp9_resize.h \ - vp9/encoder/vp9_segmentation.h \ - vp9/encoder/vp9_skin_detection.h \ - vp9/encoder/vp9_speed_features.h \ - vp9/encoder/vp9_ssim.h \ - vp9/encoder/vp9_subexp.h \ - vp9/encoder/vp9_svc_layercontext.h \ - vp9/encoder/vp9_temporal_filter.h \ - vp9/encoder/vp9_tokenize.h \ - vp9/encoder/vp9_treewriter.h \ - vp9/encoder/vp9_variance.h \ - vp9/encoder/vp9_write_bit_buffer.h \ - vp9/encoder/vp9_writer.h \ - vp9/encoder/x86/vp9_dct_sse2.h \ - vp9/vp9_iface_common.h \ - vpxenc.h \ - vpx/internal/vpx_codec_internal.h \ - vpx/internal/vpx_psnr.h \ - vpx_mem/include/vpx_mem_intrnl.h \ - vpx_mem/include/vpx_mem_tracker.h \ - vpx_mem/memory_manager/include/cavl_if.h \ - vpx_mem/memory_manager/include/cavl_impl.h \ - vpx_mem/memory_manager/include/heapmm.h \ - vpx_mem/memory_manager/include/hmm_cnfg.h \ - vpx_mem/memory_manager/include/hmm_intrnl.h \ - vpx_mem/vpx_mem.h \ - vpx_ports/arm.h \ - vpx_ports/config.h \ - vpx_ports/emmintrin_compat.h \ - vpx_ports/mem.h \ - vpx_ports/mem_ops_aligned.h \ - vpx_ports/mem_ops.h \ - vpx_ports/vpx_once.h \ - vpx_ports/vpx_timer.h \ - vpx_ports/x86.h \ - vpx_scale/vpx_scale.h \ - vpx_scale/yv12config.h \ - vpxstats.h \ - vpx/svc_context.h \ - vpx/vp8cx.h \ - vpx/vp8dx.h \ - vpx/vp8.h \ - vpx/vpx_codec.h \ - vpx/vpx_decoder.h \ - vpx/vpx_encoder.h \ - vpx/vpx_frame_buffer.h \ - vpx/vpx_image.h \ - vpx/vpx_integer.h \ - vpx_scale_rtcd.h \ - warnings.h \ - webmdec.h \ - webmenc.h \ - y4menc.h \ - y4minput.h \ - $(NULL) - -vpx_source_asm = \ - third_party/libyuv/source/row_x86.asm \ - third_party/libyuv/source/x86inc.asm \ - third_party/x86inc/x86inc.asm \ - vp8/common/arm/armv6/bilinearfilter_v6.asm \ - vp8/common/arm/armv6/copymem16x16_v6.asm \ - vp8/common/arm/armv6/copymem8x4_v6.asm \ - vp8/common/arm/armv6/copymem8x8_v6.asm \ - vp8/common/arm/armv6/dc_only_idct_add_v6.asm \ - vp8/common/arm/armv6/dequant_idct_v6.asm \ - vp8/common/arm/armv6/dequantize_v6.asm \ - vp8/common/arm/armv6/filter_v6.asm \ - vp8/common/arm/armv6/idct_v6.asm \ - vp8/common/arm/armv6/intra4x4_predict_v6.asm \ - vp8/common/arm/armv6/iwalsh_v6.asm \ - vp8/common/arm/armv6/loopfilter_v6.asm \ - vp8/common/arm/armv6/simpleloopfilter_v6.asm \ - vp8/common/arm/armv6/sixtappredict8x4_v6.asm \ - vp8/common/arm/armv6/vp8_sad16x16_armv6.asm \ - vp8/common/arm/armv6/vp8_variance16x16_armv6.asm \ - vp8/common/arm/armv6/vp8_variance8x8_armv6.asm \ - vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_h_armv6.asm \ - vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_hv_armv6.asm \ - vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_v_armv6.asm \ - vp8/common/ppc/copy_altivec.asm \ - vp8/common/ppc/filter_altivec.asm \ - vp8/common/ppc/filter_bilinear_altivec.asm \ - vp8/common/ppc/idctllm_altivec.asm \ - vp8/common/ppc/loopfilter_filters_altivec.asm \ - vp8/common/ppc/platform_altivec.asm \ - vp8/common/ppc/recon_altivec.asm \ - vp8/common/ppc/sad_altivec.asm \ - vp8/common/ppc/variance_altivec.asm \ - vp8/common/ppc/variance_subpixel_altivec.asm \ - vp8/common/x86/dequantize_mmx.asm \ - vp8/common/x86/idctllm_mmx.asm \ - vp8/common/x86/idctllm_sse2.asm \ - vp8/common/x86/iwalsh_mmx.asm \ - vp8/common/x86/iwalsh_sse2.asm \ - vp8/common/x86/loopfilter_block_sse2_x86_64.asm \ - vp8/common/x86/loopfilter_mmx.asm \ - vp8/common/x86/loopfilter_sse2.asm \ - vp8/common/x86/mfqe_sse2.asm \ - vp8/common/x86/postproc_mmx.asm \ - vp8/common/x86/postproc_sse2.asm \ - vp8/common/x86/recon_mmx.asm \ - vp8/common/x86/recon_sse2.asm \ - vp8/common/x86/sad_mmx.asm \ - vp8/common/x86/sad_sse2.asm \ - vp8/common/x86/sad_sse3.asm \ - vp8/common/x86/sad_sse4.asm \ - vp8/common/x86/sad_ssse3.asm \ - vp8/common/x86/subpixel_mmx.asm \ - vp8/common/x86/subpixel_sse2.asm \ - vp8/common/x86/subpixel_ssse3.asm \ - vp8/common/x86/variance_impl_mmx.asm \ - vp8/common/x86/variance_impl_sse2.asm \ - vp8/common/x86/variance_impl_ssse3.asm \ - vp8/encoder/arm/armv6/vp8_mse16x16_armv6.asm \ - vp8/encoder/arm/armv6/vp8_short_fdct4x4_armv6.asm \ - vp8/encoder/arm/armv6/walsh_v6.asm \ - vp8/encoder/ppc/encodemb_altivec.asm \ - vp8/encoder/ppc/fdct_altivec.asm \ - vp8/encoder/ppc/rdopt_altivec.asm \ - vp8/encoder/x86/dct_mmx.asm \ - vp8/encoder/x86/dct_sse2.asm \ - vp8/encoder/x86/encodeopt.asm \ - vp8/encoder/x86/fwalsh_sse2.asm \ - vp8/encoder/x86/quantize_mmx.asm \ - vp8/encoder/x86/ssim_opt_x86_64.asm \ - vp8/encoder/x86/subtract_mmx.asm \ - vp8/encoder/x86/subtract_sse2.asm \ - vp8/encoder/x86/temporal_filter_apply_sse2.asm \ - vp9/common/arm/neon/vp9_avg_neon_asm.asm \ - vp9/common/arm/neon/vp9_convolve8_avg_neon_asm.asm \ - vp9/common/arm/neon/vp9_convolve8_neon_asm.asm \ - vp9/common/arm/neon/vp9_copy_neon_asm.asm \ - vp9/common/arm/neon/vp9_idct16x16_1_add_neon_asm.asm \ - vp9/common/arm/neon/vp9_idct16x16_add_neon_asm.asm \ - vp9/common/arm/neon/vp9_idct32x32_1_add_neon_asm.asm \ - vp9/common/arm/neon/vp9_idct32x32_add_neon_asm.asm \ - vp9/common/arm/neon/vp9_idct4x4_1_add_neon_asm.asm \ - vp9/common/arm/neon/vp9_idct4x4_add_neon_asm.asm \ - vp9/common/arm/neon/vp9_idct8x8_1_add_neon_asm.asm \ - vp9/common/arm/neon/vp9_idct8x8_add_neon_asm.asm \ - vp9/common/arm/neon/vp9_loopfilter_16_neon_asm.asm \ - vp9/common/arm/neon/vp9_loopfilter_4_neon_asm.asm \ - vp9/common/arm/neon/vp9_loopfilter_8_neon_asm.asm \ - vp9/common/arm/neon/vp9_mb_lpf_neon.asm \ - vp9/common/arm/neon/vp9_reconintra_neon_asm.asm \ - vp9/common/arm/neon/vp9_save_reg_neon.asm \ - vp9/common/x86/vp9_copy_sse2.asm \ - vp9/common/x86/vp9_high_intrapred_sse2.asm \ - vp9/common/x86/vp9_high_subpixel_8t_sse2.asm \ - vp9/common/x86/vp9_high_subpixel_bilinear_sse2.asm \ - vp9/common/x86/vp9_idct_ssse3_x86_64.asm \ - vp9/encoder/x86/vp9_sad4d_sse2.asm \ - vp9/encoder/x86/vp9_sad_sse2.asm \ - vp9/encoder/x86/vp9_sad_sse3.asm \ - vp9/encoder/x86/vp9_sad_sse4.asm \ - vp9/encoder/x86/vp9_sad_ssse3.asm \ - vp9/encoder/x86/vp9_ssim_opt_x86_64.asm \ - vp9/encoder/x86/vp9_subpel_variance.asm \ - vp9/encoder/x86/vp9_subtract_sse2.asm \ - vp9/encoder/x86/vp9_temporal_filter_apply_sse2.asm \ - vpx_ports/emms.asm \ - vpx_ports/x86_abi_support.asm \ - $(NULL) diff --git a/ext/libvpx/upstream b/ext/libvpx/upstream deleted file mode 160000 index c74bf6d889..0000000000 --- a/ext/libvpx/upstream +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c74bf6d889992c3cabe017ec353ca85c323107cd diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am index 9f07940218..ac1654dd8b 100644 --- a/gst-libs/gst/codecparsers/Makefile.am +++ b/gst-libs/gst/codecparsers/Makefile.am @@ -43,23 +43,8 @@ gen_source_h += gsth264parser.h endif if USE_LOCAL_CODEC_PARSERS_VP8 -gen_source_c += gstvp8parser.c -gen_source_h += gstvp8parser.h gstvp8rangedecoder.h vp8utils.h - -if USE_BUILTIN_LIBVPX -add_source_c += gstvaapilibvpx.c - -libgstvaapi_codecparsers_cflags += \ - -I$(top_srcdir)/ext/libvpx \ - -I$(top_srcdir)/ext/libvpx/upstream \ - -I$(top_builddir)/ext/libvpx/upstream - -libgstvaapi_codecparsers_libs += \ - $(top_builddir)/ext/libvpx/libgstcodecparsers_vpx.la -else -gen_source_c += dboolhuff.c gstvp8rangedecoder.c vp8utils.c -gen_source_h += dboolhuff.h -endif +gen_source_c += gstvp8parser.c dboolhuff.c gstvp8rangedecoder.c vp8utils.c +gen_source_h += gstvp8parser.h gstvp8rangedecoder.h vp8utils.h dboolhuff.h endif if USE_LOCAL_CODEC_PARSERS_VP9 @@ -105,10 +90,6 @@ $(gen_source_c): %.c: $(local_codecparsers_srcdir)/%.c $(gen_source_h) $(LN_S) -f $< $@ $(gen_source_h): %.h: $(local_codecparsers_srcdir)/%.h $(LN_S) -f $< $@ -$(top_builddir)/ext/libvpx/libgstcodecparsers_vpx.la: - $(MAKE) -C $(top_builddir)/ext/libvpx - -EXTRA_DIST = gstvaapilibvpx.c DISTCLEANFILES = $(GENFILES) .timestamp.symlinks diff --git a/gst-libs/gst/codecparsers/gstvaapilibvpx.c b/gst-libs/gst/codecparsers/gstvaapilibvpx.c deleted file mode 100644 index 81baeb048a..0000000000 --- a/gst-libs/gst/codecparsers/gstvaapilibvpx.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * gstvaapilibvpx.c - libvpx wrapper for gstreamer-vaapi - * - * Copyright (C) 2014 Intel Corporation - * Author: Gwenole Beauchesne - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "gstvp8rangedecoder.h" -#include "vp8utils.h" -#include "gstlibvpx.h" - -#define BOOL_DECODER_CAST(rd) \ - ((vp8_bool_decoder *)(&(rd)->_gst_reserved[0])) - -#define BOOL_DECODER_STATE_CAST(s) \ - ((vp8_bool_decoder_state *)(s)) - -gboolean -gst_vp8_range_decoder_init (GstVp8RangeDecoder * rd, const guchar * buf, - guint buf_size) -{ - vp8_bool_decoder *const bd = BOOL_DECODER_CAST (rd); - - g_return_val_if_fail (sizeof (rd->_gst_reserved) >= sizeof (*bd), FALSE); - - rd->buf = buf; - rd->buf_size = buf_size; - return vp8_bool_decoder_init (bd, buf, buf_size); -} - -gint -gst_vp8_range_decoder_read (GstVp8RangeDecoder * rd, guint8 prob) -{ - return vp8_bool_decoder_read (BOOL_DECODER_CAST (rd), prob); -} - -gint -gst_vp8_range_decoder_read_literal (GstVp8RangeDecoder * rd, gint bits) -{ - return vp8_bool_decoder_read_literal (BOOL_DECODER_CAST (rd), bits); -} - -guint -gst_vp8_range_decoder_get_pos (GstVp8RangeDecoder * rd) -{ - return vp8_bool_decoder_get_pos (BOOL_DECODER_CAST (rd)); -} - -void -gst_vp8_range_decoder_get_state (GstVp8RangeDecoder * rd, - GstVp8RangeDecoderState * state) -{ - vp8_bool_decoder_get_state (BOOL_DECODER_CAST (rd), - BOOL_DECODER_STATE_CAST (state)); -} - -void -gst_vp8_token_update_probs_init (GstVp8TokenProbs * probs) -{ - vp8_init_token_update_probs (probs->prob); -} - -void -gst_vp8_token_probs_init_defaults (GstVp8TokenProbs * probs) -{ - vp8_init_default_token_probs (probs->prob); -} - -void -gst_vp8_mv_update_probs_init (GstVp8MvProbs * probs) -{ - vp8_init_mv_update_probs (probs->prob); -} - -void -gst_vp8_mv_probs_init_defaults (GstVp8MvProbs * probs) -{ - vp8_init_default_mv_probs (probs->prob); -} - -void -gst_vp8_mode_probs_init_defaults (GstVp8ModeProbs * probs, gboolean key_frame) -{ - if (key_frame) { - vp8_init_default_intra_mode_probs (probs->y_prob, probs->uv_prob); - } else { - vp8_init_default_inter_mode_probs (probs->y_prob, probs->uv_prob); - } -} From 56fab31c00f491b5eed4a66baed7d13c090e50df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Dec 2015 13:24:30 +0100 Subject: [PATCH 2226/3781] Remove codecparsers submodule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- .gitmodules | 3 - Makefile.am | 2 +- configure.ac | 62 +++++------------ ext/Makefile.am | 61 ----------------- ext/codecparsers | 1 - gst-libs/gst/Makefile.am | 2 +- gst-libs/gst/codecparsers/Makefile.am | 96 --------------------------- gst-libs/gst/vaapi/Makefile.am | 2 +- gst/vaapi/Makefile.am | 92 ------------------------- 9 files changed, 21 insertions(+), 300 deletions(-) delete mode 100644 .gitmodules delete mode 100644 ext/Makefile.am delete mode 160000 ext/codecparsers delete mode 100644 gst-libs/gst/codecparsers/Makefile.am diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index a72ea38931..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "ext/codecparsers"] - path = ext/codecparsers - url = https://github.com/01org/gstreamer-codecparsers.git diff --git a/Makefile.am b/Makefile.am index 9331c49ca1..94182c68dd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} AUTOMAKE_OPTIONS = foreign -SUBDIRS = debian.upstream ext gst-libs gst pkgconfig tests docs patches +SUBDIRS = debian.upstream gst-libs gst pkgconfig tests docs patches # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ diff --git a/configure.ac b/configure.ac index 734e1cfdc8..c1f17c52cc 100644 --- a/configure.ac +++ b/configure.ac @@ -108,11 +108,6 @@ AC_ARG_ENABLE(builtin_videoparsers, [enable built-in videoparsers @<:@default=yes@:>@]), [], [enable_builtin_videoparsers="yes"]) -AC_ARG_ENABLE(builtin_codecparsers, - AS_HELP_STRING([--enable-builtin-codecparsers], - [enable built-in codecparsers @<:@default=yes@:>@]), - [], [enable_builtin_codecparsers="yes"]) - AC_ARG_ENABLE([encoders], AS_HELP_STRING([--enable-encoders], [enable video encoders @<:@default=yes@:>@]), @@ -275,19 +270,11 @@ PKG_CHECK_MODULES([GST_BASEVIDEO], fi dnl ... bitstream parsers -if test "$enable_builtin_codecparsers" = "yes"; then - ac_cv_have_gst_mpeg2_parser="no" - ac_cv_have_gst_h264_parser="no" - ac_cv_have_gst_jpeg_parser="no" - ac_cv_have_gst_vp8_parser="no" - ac_cv_have_gst_h265_parser="no" - ac_cv_have_gst_vp9_parser="no" -else PKG_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) -fi dnl ... MPEG-2 parser, with the required extensions +HAVE_GST_MPEG2_PARSER=0 AC_CACHE_CHECK([for MPEG-2 parser], ac_cv_have_gst_mpeg2_parser, [ saved_CPPFLAGS="$CPPFLAGS" @@ -306,16 +293,15 @@ AC_CACHE_CHECK([for MPEG-2 parser], &seq_hdr, NULL); gst_mpeg_video_finalise_mpeg2_sequence_header(&seq_hdr, &seq_ext, &seq_dpy);]])], - [ac_cv_have_gst_mpeg2_parser="yes"], + [ac_cv_have_gst_mpeg2_parser="yes" HAVE_GST_MPEG2_PARSER=1], [ac_cv_have_gst_mpeg2_parser="no"] ) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) -AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_MPEG2], - [test "$ac_cv_have_gst_mpeg2_parser" != "yes"]) dnl ... H.264 parser, with the required extensions +HAVE_GST_H264_PARSER=0 AC_CACHE_CHECK([for H.264 parser], ac_cv_have_gst_h264_parser, [ saved_CPPFLAGS="$CPPFLAGS" @@ -335,16 +321,15 @@ AC_CACHE_CHECK([for H.264 parser], sps.extension.mvc.num_views_minus1 = 1; GstH264NalUnit nalu; nalu.extension_type = GST_H264_NAL_EXTENSION_MVC;]])], - [ac_cv_have_gst_h264_parser="yes"], + [ac_cv_have_gst_h264_parser="yes" HAVE_GST_H264_PARSER=1], [ac_cv_have_gst_h264_parser="no"] ) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) -AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_H264], - [test "$ac_cv_have_gst_h264_parser" != "yes"]) -dnl ... JPEG parser, not upstream yet +dnl ... JPEG parser +HAVE_GST_JPEG_PARSER=0 AC_CACHE_CHECK([for JPEG parser], ac_cv_have_gst_jpeg_parser, [ saved_CPPFLAGS="$CPPFLAGS" @@ -355,16 +340,15 @@ AC_CACHE_CHECK([for JPEG parser], [AC_LANG_PROGRAM( [[#include ]], [[GstJpegFrameHdr frame_hdr;]])], - [ac_cv_have_gst_jpeg_parser="yes"], + [ac_cv_have_gst_jpeg_parser="yes" HAVE_GST_JPEG_PARSER=1], [ac_cv_have_gst_jpeg_parser="no"] ) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) -AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_JPEG], - [test "$ac_cv_have_gst_jpeg_parser" != "yes"]) -dnl ... VP8 parser, not upstream yet +dnl ... VP8 parser +HAVE_GST_VP8_PARSER=0 AC_CACHE_CHECK([for VP8 parser], ac_cv_have_gst_vp8_parser, [ saved_CPPFLAGS="$CPPFLAGS" @@ -375,16 +359,15 @@ AC_CACHE_CHECK([for VP8 parser], [AC_LANG_PROGRAM( [[#include ]], [[GstVp8FrameHdr frame_hdr;]])], - [ac_cv_have_gst_vp8_parser="yes"], + [ac_cv_have_gst_vp8_parser="yes" HAVE_GST_VP8_PARSER=1], [ac_cv_have_gst_vp8_parser="no"] ) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) -AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_VP8], - [test "$ac_cv_have_gst_vp8_parser" != "yes"]) dnl ... VP9 parser, with required extensions +HAVE_GST_VP9_PARSER=0 AC_CACHE_CHECK([for VP9 parser], ac_cv_have_gst_vp9_parser, [ saved_CPPFLAGS="$CPPFLAGS" @@ -395,16 +378,15 @@ AC_CACHE_CHECK([for VP9 parser], [AC_LANG_PROGRAM( [[#include ]], [[GstVp9FrameHdr frame_hdr;]])], - [ac_cv_have_gst_vp9_parser="yes"], + [ac_cv_have_gst_vp9_parser="yes" HAVE_GST_VP9_PARSER=1], [ac_cv_have_gst_vp9_parser="no"] ) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) -AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_VP9], - [test "$ac_cv_have_gst_vp9_parser" != "yes"]) dnl ... H.265 parser, with the required extensions +HAVE_GST_H265_PARSER=0 AC_CACHE_CHECK([for H.265 parser], ac_cv_have_gst_h265_parser, [ saved_CPPFLAGS="$CPPFLAGS" @@ -423,18 +405,12 @@ AC_CACHE_CHECK([for H.265 parser], GstH265SPS sps; sps.crop_rect_x = 0; sps.crop_rect_width = 0;]])], - [ac_cv_have_gst_h265_parser="yes"], + [ac_cv_have_gst_h265_parser="yes" HAVE_GST_H265_PARSER=1], [ac_cv_have_gst_h265_parser="no"] ) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) -AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_H265], - [test "$ac_cv_have_gst_h265_parser" != "yes"]) - -dnl ... video parsers -AM_CONDITIONAL([USE_LOCAL_VIDEO_PARSERS], - [test "$enable_builtin_videoparsers" = "yes"]) dnl ... opengl helper libraries HAVE_GSTGL=0 @@ -779,7 +755,7 @@ AC_CACHE_CHECK([for JPEG decoding API], VASliceParameterBufferJPEGBaseline slice_param; VAHuffmanTableBufferJPEGBaseline huffman_table; VAIQMatrixBufferJPEGBaseline iq_matrix;]])], - [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=1], + [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=$HAVE_GST_JPEG_PARSER], [ac_cv_have_jpeg_decoding_api="no"] ) CPPFLAGS="$saved_CPPFLAGS" @@ -813,7 +789,7 @@ AC_CACHE_CHECK([for VP8 decoding API], VAIQMatrixBufferVP8 iq_matrix; slice_param.slice_data_offset = 0; slice_param.slice_data_flag = 0;]])], - [ac_cv_have_vp8_decoding_api="yes" USE_VP8_DECODER=1], + [ac_cv_have_vp8_decoding_api="yes" USE_VP8_DECODER=$HAVE_GST_VP8_PARSER], [ac_cv_have_vp8_decoding_api="no"] ) CPPFLAGS="$saved_CPPFLAGS" @@ -846,7 +822,7 @@ AC_CACHE_CHECK([for VP9 decoding API], VASegmentParameterVP9 seg_param; slice_param.slice_data_offset = 0; slice_param.slice_data_flag = 0;]])], - [ac_cv_have_vp9_decoding_api="yes" USE_VP9_DECODER=1], + [ac_cv_have_vp9_decoding_api="yes" USE_VP9_DECODER=$HAVE_GST_VP9_PARSER], [ac_cv_have_vp9_decoding_api="no"] ) CPPFLAGS="$saved_CPPFLAGS" @@ -879,7 +855,7 @@ AC_CACHE_CHECK([for HEVC decoding API], VAIQMatrixBufferHEVC iq_matrix; slice_param.slice_data_offset = 0; slice_param.slice_data_flag = 0;]])], - [ac_cv_have_hevc_decoding_api="yes" USE_HEVC_DECODER=1], + [ac_cv_have_hevc_decoding_api="yes" USE_HEVC_DECODER=$HAVE_GST_H265_PARSER], [ac_cv_have_hevc_decoding_api="no"] ) CPPFLAGS="$saved_CPPFLAGS" @@ -1124,11 +1100,9 @@ debian.upstream/libgstvaapi-x11.install.in docs/reference/libs/libs-docs.xml docs/reference/plugins/Makefile docs/reference/plugins/plugins-docs.xml - ext/Makefile gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/base/Makefile - gst-libs/gst/codecparsers/Makefile gst-libs/gst/vaapi/Makefile gst/Makefile gst/vaapi/Makefile diff --git a/ext/Makefile.am b/ext/Makefile.am deleted file mode 100644 index b639f03c82..0000000000 --- a/ext/Makefile.am +++ /dev/null @@ -1,61 +0,0 @@ -EXTRA_DIST = - -codecparsers_srcdir = \ - $(top_srcdir)/ext/codecparsers/gst-libs/gst/codecparsers - -codecparsers_source_c = \ - dboolhuff.c \ - gsth264parser.c \ - gstjpegparser.c \ - gstmpeg4parser.c \ - gstmpegvideoparser.c \ - gstvc1parser.c \ - gstvp8parser.c \ - gstvp8rangedecoder.c \ - nalutils.c \ - parserutils.c \ - vp8utils.c \ - gsth265parser.c \ - gstvp9parser.c \ - vp9utils.c \ - $(NULL) - -EXTRA_DIST += $(codecparsers_source_c:%.c=$(codecparsers_srcdir)/%.c) - -codecparsers_source_h = \ - dboolhuff.h \ - gsth264parser.h \ - gstjpegparser.h \ - gstmpeg4parser.h \ - gstmpegvideoparser.h \ - gstvc1parser.h \ - gstvp8parser.h \ - gstvp8rangedecoder.h \ - nalutils.h \ - parserutils.h \ - vp8utils.h \ - gsth265parser.h \ - gstvp9parser.h \ - vp9utils.h \ - $(NULL) - -EXTRA_DIST += $(codecparsers_source_h:%.h=$(codecparsers_srcdir)/%.h) - -videoparsers_srcdir = \ - $(top_srcdir)/ext/codecparsers/gst/videoparsers - -videoparsers_source_c = \ - gsth264parse.c \ - gsth265parse.c \ - $(NULL) - -EXTRA_DIST += $(videoparsers_source_c:%.c=$(videoparsers_srcdir)/%.c) - -videoparsers_source_h = \ - gsth264parse.h \ - gsth265parse.h \ - $(NULL) - -EXTRA_DIST += $(videoparsers_source_h:%.h=$(videoparsers_srcdir)/%.h) - --include $(top_srcdir)/git.mk diff --git a/ext/codecparsers b/ext/codecparsers deleted file mode 160000 index d9f25273df..0000000000 --- a/ext/codecparsers +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d9f25273dfa3fe0f5f791c6e35b1243f6462d990 diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 77be8ee030..de02514679 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = base codecparsers vaapi +SUBDIRS = base vaapi -include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am deleted file mode 100644 index ac1654dd8b..0000000000 --- a/gst-libs/gst/codecparsers/Makefile.am +++ /dev/null @@ -1,96 +0,0 @@ -noinst_LTLIBRARIES = \ - libgstvaapi-codecparsers.la \ - $(NULL) - -local_codecparsers_srcdir = \ - $(top_srcdir)/ext/codecparsers/gst-libs/gst/codecparsers - -libgstvaapi_codecparsers_cflags = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - -I$(top_builddir)/gst-libs \ - $(GST_BASE_CFLAGS) \ - $(GST_CFLAGS) \ - $(NULL) - -libgstvaapi_codecparsers_libs = \ - $(GST_BASE_LIBS) \ - $(GST_LIBS) \ - $(NULL) - -add_source_c = -add_source_h = -gen_source_c = parserutils.c nalutils.c -gen_source_h = parserutils.h nalutils.h - -# Always build VC-1 and MPEG-4 parsers for now -gen_source_c += gstvc1parser.c gstmpeg4parser.c -gen_source_h += gstvc1parser.h gstmpeg4parser.h - -if USE_LOCAL_CODEC_PARSERS_JPEG -gen_source_c += gstjpegparser.c -gen_source_h += gstjpegparser.h -endif - -if USE_LOCAL_CODEC_PARSERS_MPEG2 -gen_source_c += gstmpegvideoparser.c -gen_source_h += gstmpegvideoparser.h -endif - -if USE_LOCAL_CODEC_PARSERS_H264 -gen_source_c += gsth264parser.c -gen_source_h += gsth264parser.h -endif - -if USE_LOCAL_CODEC_PARSERS_VP8 -gen_source_c += gstvp8parser.c dboolhuff.c gstvp8rangedecoder.c vp8utils.c -gen_source_h += gstvp8parser.h gstvp8rangedecoder.h vp8utils.h dboolhuff.h -endif - -if USE_LOCAL_CODEC_PARSERS_VP9 -gen_source_c += gstvp9parser.c vp9utils.c -gen_source_h += gstvp9parser.h vp9utils.h -endif - -if USE_LOCAL_CODEC_PARSERS_H265 -gen_source_c += gsth265parser.c -gen_source_h += gsth265parser.h -endif - -GENFILES = \ - $(gen_source_c) \ - $(gen_source_h) \ - $(NULL) - -nodist_EXTRA_libgstvaapi_codecparsers_la_SOURCES = dummy.c - -nodist_libgstvaapi_codecparsers_la_SOURCES = \ - $(gen_source_c) \ - $(add_source_c) \ - $(NULL) - -libgstvaapi_codecparsers_la_CFLAGS = \ - $(libgstvaapi_codecparsers_cflags) \ - $(NULL) - -libgstvaapi_codecparsers_la_LIBADD = \ - $(libgstvaapi_codecparsers_libs) \ - $(NULL) - -libgstvaapi_codecparsers_la_LDFLAGS = \ - $(GST_ALL_LDFLAGS) \ - $(NULL) - -all-local: .timestamp.symlinks - -.timestamp.symlinks: $(GENFILES) - touch $@ - -$(gen_source_c): %.c: $(local_codecparsers_srcdir)/%.c $(gen_source_h) - $(LN_S) -f $< $@ -$(gen_source_h): %.h: $(local_codecparsers_srcdir)/%.h - $(LN_S) -f $< $@ - -DISTCLEANFILES = $(GENFILES) .timestamp.symlinks - --include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 314fd2d226..1818f75c50 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -45,7 +45,7 @@ libgstvaapi_libs = \ $(GST_CODEC_PARSERS_LIBS) \ $(LIBVA_LIBS) \ $(top_builddir)/gst-libs/gst/base/libgstvaapi-baseutils.la \ - $(top_builddir)/gst-libs/gst/codecparsers/libgstvaapi-codecparsers.la + $(NULL) libgstvaapi_source_c = \ gstvaapibufferproxy.c \ diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index e99493e0a9..0fb9ad3cb2 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -163,98 +163,6 @@ libgstvaapi_la_LIBADD = \ libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvaapi_la_LIBTOOLFLAGS = --tag=disable-static -BUILT_SOURCES = - -if USE_LOCAL_VIDEO_PARSERS -plugin_LTLIBRARIES += libgstvaapi_parse.la - -libgstvaapi_parse_gen_source_c = \ - gsth264parse.c \ - $(NULL) - -libgstvaapi_parse_gen_source_h = \ - gsth264parse.h \ - $(NULL) - -libgstvaapi_1_4p_parse_gen_source_c = \ - gsth265parse.c \ - $(NULL) - -libgstvaapi_1_4p_parse_gen_source_h = \ - gsth265parse.h \ - $(NULL) - -libgstvaapi_parse_gen_sources = \ - $(libgstvaapi_parse_gen_source_c) \ - $(libgstvaapi_parse_gen_source_h) \ - $(NULL) - -if USE_GST_API_1_4p -libgstvaapi_parse_gen_source_c += $(libgstvaapi_1_4p_parse_gen_source_c) -libgstvaapi_parse_gen_source_h += $(libgstvaapi_1_4p_parse_gen_source_h) -endif - -libgstvaapi_parse_la_SOURCES = gstvaapiparse.c gstvaapiparse.h -nodist_libgstvaapi_parse_la_SOURCES = \ - $(libgstvaapi_parse_gen_source_c) \ - $(libgstvaapi_parse_gen_source_h) \ - $(NULL) - -libgstvaapi_parse_la_CFLAGS = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - -I$(top_builddir)/gst-libs \ - $(GST_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(GST_CODEC_PARSERS_CFLAGS) \ - $(NULL) - -libgstvaapi_parse_la_LIBADD = \ - $(top_builddir)/gst-libs/gst/codecparsers/libgstvaapi-codecparsers.la \ - $(GST_LIBS) \ - $(GST_BASE_LIBS) \ - $(GST_PLUGINS_BASE_LIBS) \ - $(GST_VIDEO_LIBS) -lgstpbutils-$(GST_PKG_VERSION) \ - $(GST_CODEC_PARSERS_LIBS) \ - $(NULL) - -libgstvaapi_parse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstvaapi_parse_la_LIBTOOLFLAGS = --tag=disable-static - -videoparsers_sources_dir = \ - $(top_srcdir)/ext/codecparsers/gst/videoparsers -videoparsers_patches_dir = \ - $(top_srcdir)/patches/videoparsers -include $(videoparsers_patches_dir)/series.frag -videoparsers_patches = \ - $(videoparsers_patches_base:%=$(top_srcdir)/patches/videoparsers/%) -if USE_GST_API_1_4p -videoparsers_patches += \ - $(videoparsers_patches_1_4p:%=$(top_srcdir)/patches/videoparsers/%) -endif -videoparsers_orig_sources = \ - $(libgstvaapi_parse_gen_sources:%=$(videoparsers_sources_dir)/%) - -$(libgstvaapi_parse_gen_sources): $(videoparsers_orig_sources) - cp -f $(videoparsers_sources_dir)/$@ $@ - -videoparsers.prepare.stamp: $(videoparsers_patches) $(libgstvaapi_parse_gen_sources) - @for f in $(videoparsers_patches); do \ - patch -p3 < $$f; \ - done - @touch $@ - -BUILT_SOURCES += \ - $(libgstvaapi_parse_gen_sources) \ - videoparsers.prepare.stamp -endif - -CLEANFILES = \ - videoparsers.prepare.stamp \ - $(libgstvaapi_parse_gen_sources) - EXTRA_DIST = \ $(libgstvaapi_enc_source_c) \ $(libgstvaapi_enc_source_h) \ From ef36e88f255f0f706bc9b791259848b40d2eafbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Dec 2015 15:18:11 +0100 Subject: [PATCH 2227/3781] Remove pkg-config files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- Makefile.am | 2 +- configure.ac | 11 -------- debian.upstream/libgstvaapi-dev.install.in | 1 - pkgconfig/Makefile.am | 32 ---------------------- pkgconfig/gstreamer-vaapi-drm.pc.in | 12 -------- pkgconfig/gstreamer-vaapi-glx.pc.in | 12 -------- pkgconfig/gstreamer-vaapi-wayland.pc.in | 12 -------- pkgconfig/gstreamer-vaapi-x11.pc.in | 12 -------- pkgconfig/gstreamer-vaapi.pc.in | 12 -------- 9 files changed, 1 insertion(+), 105 deletions(-) delete mode 100644 pkgconfig/Makefile.am delete mode 100644 pkgconfig/gstreamer-vaapi-drm.pc.in delete mode 100644 pkgconfig/gstreamer-vaapi-glx.pc.in delete mode 100644 pkgconfig/gstreamer-vaapi-wayland.pc.in delete mode 100644 pkgconfig/gstreamer-vaapi-x11.pc.in delete mode 100644 pkgconfig/gstreamer-vaapi.pc.in diff --git a/Makefile.am b/Makefile.am index 94182c68dd..20409e4e2f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} AUTOMAKE_OPTIONS = foreign -SUBDIRS = debian.upstream gst-libs gst pkgconfig tests docs patches +SUBDIRS = debian.upstream gst-libs gst tests docs patches # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ diff --git a/configure.ac b/configure.ac index c1f17c52cc..46299d67a2 100644 --- a/configure.ac +++ b/configure.ac @@ -1108,17 +1108,6 @@ debian.upstream/libgstvaapi-x11.install.in gst/vaapi/Makefile patches/Makefile patches/videoparsers/Makefile - pkgconfig/Makefile - pkgconfig/gstreamer-vaapi-$GST_PKG_VERSION.pc:\ -pkgconfig/gstreamer-vaapi.pc.in - pkgconfig/gstreamer-vaapi-drm-$GST_PKG_VERSION.pc:\ -pkgconfig/gstreamer-vaapi-drm.pc.in - pkgconfig/gstreamer-vaapi-glx-$GST_PKG_VERSION.pc:\ -pkgconfig/gstreamer-vaapi-glx.pc.in - pkgconfig/gstreamer-vaapi-wayland-$GST_PKG_VERSION.pc:\ -pkgconfig/gstreamer-vaapi-wayland.pc.in - pkgconfig/gstreamer-vaapi-x11-$GST_PKG_VERSION.pc:\ -pkgconfig/gstreamer-vaapi-x11.pc.in tests/Makefile ]) AC_OUTPUT diff --git a/debian.upstream/libgstvaapi-dev.install.in b/debian.upstream/libgstvaapi-dev.install.in index 33d178a05a..b6aa01de4d 100644 --- a/debian.upstream/libgstvaapi-dev.install.in +++ b/debian.upstream/libgstvaapi-dev.install.in @@ -1,3 +1,2 @@ debian/tmp/usr/lib/libgstvaapi*.so -debian/tmp/usr/lib/pkgconfig/gstreamer-vaapi*.pc debian/tmp/usr/include/gstreamer-@GST_PKG_VERSION@/gst/vaapi/*.h diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am deleted file mode 100644 index 2acc572a59..0000000000 --- a/pkgconfig/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -pcfiles_in = gstreamer-vaapi.pc.in -if USE_DRM -pcfiles_in += gstreamer-vaapi-drm.pc.in -endif -if USE_X11 -pcfiles_in += gstreamer-vaapi-x11.pc.in -endif -if USE_GLX -pcfiles_in += gstreamer-vaapi-glx.pc.in -endif -if USE_WAYLAND -pcfiles_in += gstreamer-vaapi-wayland.pc.in -endif - -pcfiles = $(pcfiles_in:%.pc.in=%-$(GST_PKG_VERSION).pc) - -all_pcfiles_in = gstreamer-vaapi.pc.in -all_pcfiles_in += gstreamer-vaapi-drm.pc.in -all_pcfiles_in += gstreamer-vaapi-x11.pc.in -all_pcfiles_in += gstreamer-vaapi-glx.pc.in -all_pcfiles_in += gstreamer-vaapi-wayland.pc.in - -all_pcfiles = $(all_pcfiles_in:%.pc.in=%-$(GST_PKG_VERSION).pc) - -pkgconfigdir = @pkgconfigdir@ -pkgconfig_DATA = $(pcfiles) - -EXTRA_DIST = $(all_pcfiles_in) - -DISTCLEANFILES = $(all_pcfiles) - --include $(top_srcdir)/git.mk diff --git a/pkgconfig/gstreamer-vaapi-drm.pc.in b/pkgconfig/gstreamer-vaapi-drm.pc.in deleted file mode 100644 index f5f44d3d75..0000000000 --- a/pkgconfig/gstreamer-vaapi-drm.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_PKG_VERSION@ -pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ - -Name: GStreamer VA-API (DRM) Plugins Libraries -Description: Streaming media framework, VA-API (DRM) plugins libraries -Requires: gstreamer-vaapi-@GST_PKG_VERSION@ libva-drm -Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-drm-@GST_API_VERSION@ -Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi-glx.pc.in b/pkgconfig/gstreamer-vaapi-glx.pc.in deleted file mode 100644 index 4ac3d11cf7..0000000000 --- a/pkgconfig/gstreamer-vaapi-glx.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_PKG_VERSION@ -pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ - -Name: GStreamer VA-API (GLX) Plugins Libraries -Description: Streaming media framework, VA-API (GLX) plugins libraries -Requires: gstreamer-vaapi-@GST_PKG_VERSION@ @LIBVA_GLX_PKGNAME@ -Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-glx-@GST_API_VERSION@ -Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi-wayland.pc.in b/pkgconfig/gstreamer-vaapi-wayland.pc.in deleted file mode 100644 index 2ec0a87ad5..0000000000 --- a/pkgconfig/gstreamer-vaapi-wayland.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_PKG_VERSION@ -pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ - -Name: GStreamer VA-API (Wayland) Plugins Libraries -Description: Streaming media framework, VA-API (Wayland) plugins libraries -Requires: gstreamer-vaapi-@GST_PKG_VERSION@ libva-wayland -Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-wayland-@GST_API_VERSION@ -Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi-x11.pc.in b/pkgconfig/gstreamer-vaapi-x11.pc.in deleted file mode 100644 index 7c0eb6db37..0000000000 --- a/pkgconfig/gstreamer-vaapi-x11.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_PKG_VERSION@ -pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ - -Name: GStreamer VA-API (X11) Plugins Libraries -Description: Streaming media framework, VA-API (X11) plugins libraries -Requires: gstreamer-vaapi-@GST_PKG_VERSION@ @LIBVA_X11_PKGNAME@ -Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-x11-@GST_API_VERSION@ -Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-vaapi.pc.in b/pkgconfig/gstreamer-vaapi.pc.in deleted file mode 100644 index 57c56095b3..0000000000 --- a/pkgconfig/gstreamer-vaapi.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@/gstreamer-@GST_PKG_VERSION@ -pluginsdir=@libdir@/gstreamer-@GST_PKG_VERSION@ - -Name: GStreamer VA-API Plugins Libraries -Description: Streaming media framework, VA-API plugins libraries -Requires: gstreamer-@GST_PKG_VERSION@ >= @GST_VERSION_REQUIRED@ gstreamer-base-@GST_PKG_VERSION@ >= @GST_PLUGINS_BASE_VERSION_REQUIRED@ @LIBVA_PKGNAME@ -Version: @VERSION@ -Libs: -L${libdir} -lgstvaapi-@GST_API_VERSION@ -Cflags: -I${includedir} From c2aff6e32cbcca7d007d3bc8984d3cad24030b5e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 19 Jan 2016 10:40:54 +0200 Subject: [PATCH 2228/3781] Remove videoparser patches --- Makefile.am | 2 +- configure.ac | 10 -- patches/Makefile.am | 3 - ...the-built-in-video-parsers-as-vaapip.patch | 38 ------- ...uild-with-older-GStreamer-1.x-stacks.patch | 55 --------- ...t-to-byte-stream-nalu-format-Annex-B.patch | 44 -------- ...e-3D-video-support-for-GStreamer-1.5.patch | 106 ------------------ ...64-Disable-passthorugh-mode-enabling.patch | 43 ------- ...06-h265parse-include-gstvaapiparse.h.patch | 32 ------ ...65parse-fix-build-with-GStreamer-1.5.patch | 48 -------- patches/videoparsers/Makefile.am | 9 -- patches/videoparsers/series.frag | 14 --- 12 files changed, 1 insertion(+), 403 deletions(-) delete mode 100644 patches/Makefile.am delete mode 100644 patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch delete mode 100644 patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch delete mode 100644 patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch delete mode 100644 patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch delete mode 100644 patches/videoparsers/0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch delete mode 100644 patches/videoparsers/0006-h265parse-include-gstvaapiparse.h.patch delete mode 100644 patches/videoparsers/0007-h265parse-fix-build-with-GStreamer-1.5.patch delete mode 100644 patches/videoparsers/Makefile.am delete mode 100644 patches/videoparsers/series.frag diff --git a/Makefile.am b/Makefile.am index 20409e4e2f..b10a0c7252 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} AUTOMAKE_OPTIONS = foreign -SUBDIRS = debian.upstream gst-libs gst tests docs patches +SUBDIRS = debian.upstream gst-libs gst tests docs # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ diff --git a/configure.ac b/configure.ac index 46299d67a2..0926c86ef6 100644 --- a/configure.ac +++ b/configure.ac @@ -143,14 +143,6 @@ AC_ARG_WITH([glapi], [build with the specified OpenGL APIs @<:@default=default_glapi@:>@]), [GLAPI="$with_glapi"], [GLAPI=default_glapi]) -dnl Check for PATCH -AC_ARG_VAR([PATCH], [Path to patch program, if any]) -AC_PATH_PROG([PATCH], [patch]) -if test -z "$PATCH" -a "$enable_builtin_videoparsers" = "yes"; then - AC_MSG_ERROR([patch is needed to apply patches for built videoparsers -sources]) -fi - dnl Check for basic libraries AC_CHECK_LIB(m, tan) @@ -1106,8 +1098,6 @@ debian.upstream/libgstvaapi-x11.install.in gst-libs/gst/vaapi/Makefile gst/Makefile gst/vaapi/Makefile - patches/Makefile - patches/videoparsers/Makefile tests/Makefile ]) AC_OUTPUT diff --git a/patches/Makefile.am b/patches/Makefile.am deleted file mode 100644 index 7591cb368a..0000000000 --- a/patches/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = videoparsers - --include $(top_srcdir)/git.mk diff --git a/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch b/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch deleted file mode 100644 index 8e21c45d8f..0000000000 --- a/patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch +++ /dev/null @@ -1,38 +0,0 @@ -From e412ece68af9b1a4ce7309774b38ec548a2d709f Mon Sep 17 00:00:00 2001 -From: Gwenole Beauchesne -Date: Mon, 28 Apr 2014 17:44:03 +0200 -Subject: [PATCH 1/6] plugins: compile the built-in video parsers as - "vaapiparse" element. - -The built-in video parsers elements are built into a single DSO named -libgstvaapi_parse.so. The various video parsers could be accessed as -vaapiparse_CODEC. ---- - gst/vaapi/gsth264parse.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 915c2d7..96901e0 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -26,6 +26,7 @@ - # include "config.h" - #endif - -+#include "gstvaapiparse.h" - #include - #include - #include -@@ -122,7 +123,8 @@ gst_h264_parse_class_init (GstH264ParseClass * klass) - GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass); - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - -- GST_DEBUG_CATEGORY_INIT (h264_parse_debug, "h264parse", 0, "h264 parser"); -+ GST_DEBUG_CATEGORY_INIT (h264_parse_debug, "vaapiparse_h264", 0, -+ "h264 parser"); - - gobject_class->finalize = gst_h264_parse_finalize; - gobject_class->set_property = gst_h264_parse_set_property; --- -2.5.1 - diff --git a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch b/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch deleted file mode 100644 index 767a2545fd..0000000000 --- a/patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 48233a9eeb20d19fbc3f5550d8fecb4271be1822 Mon Sep 17 00:00:00 2001 -From: Gwenole Beauchesne -Date: Wed, 26 Aug 2015 06:50:41 +0300 -Subject: [PATCH 2/6] h264parse: fix build with older GStreamer 1.x stacks - ---- - gst/vaapi/gsth264parse.c | 9 +++++++++ - gst/vaapi/gsth264parse.h | 1 + - 2 files changed, 10 insertions(+) - -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 96901e0..f472a5e 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -165,8 +165,12 @@ gst_h264_parse_init (GstH264Parse * h264parse) - { - h264parse->frame_out = gst_adapter_new (); - gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h264parse), FALSE); -+#if GST_CHECK_VERSION(1,3,0) - GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h264parse)); -+#endif -+#if GST_CHECK_VERSION(1,5,0) - GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (h264parse)); -+#endif - } - - -@@ -2216,8 +2220,13 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) - GST_TAG_VIDEO_CODEC, caps); - gst_caps_unref (caps); - -+#if GST_CHECK_VERSION(1,5,0) - gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE); - gst_tag_list_unref (taglist); -+#else -+ gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (h264parse), -+ gst_event_new_tag (taglist)); -+#endif - - /* also signals the end of first-frame processing */ - h264parse->sent_codec_tag = TRUE; -diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h -index 58d818c..617e616 100644 ---- a/gst/vaapi/gsth264parse.h -+++ b/gst/vaapi/gsth264parse.h -@@ -27,6 +27,7 @@ - - #include - #include -+#include - #include - #include - --- -2.5.1 diff --git a/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch b/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch deleted file mode 100644 index 486e98f82a..0000000000 --- a/patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 56df8be6dff017d32218bb3111e6ae6ff1316dec Mon Sep 17 00:00:00 2001 -From: Gwenole Beauchesne -Date: Tue, 26 May 2015 09:33:57 +0300 -Subject: [PATCH 3/6] h264parse: default to byte-stream/nalu format (Annex B). - -Always default to stream-format=byte-stream,alignment=nalu if avcC -format was not detected. This is the natural stream format specified -in the standard (Annex.B): a series of NAL units prefixed with the -usual start code. - -https://bugzilla.gnome.org/show_bug.cgi?id=732167 - -Signed-off-by: Gwenole Beauchesne -Signed-off-by: Sreerenj Balachandran ---- - gst/vaapi/gsth264parse.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index f472a5e..f1ed269 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -405,7 +405,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format, - if (!format) - format = GST_H264_PARSE_FORMAT_BYTE; - if (!align) -- align = GST_H264_PARSE_ALIGN_AU; -+ align = format == GST_H264_PARSE_FORMAT_BYTE ? GST_H264_PARSE_ALIGN_NAL : -+ GST_H264_PARSE_ALIGN_AU; - - GST_DEBUG_OBJECT (h264parse, "selected format %s, alignment %s", - gst_h264_parse_get_string (h264parse, TRUE, format), -@@ -2452,6 +2453,8 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) - - /* bytestream caps sanity checks */ - if (format == GST_H264_PARSE_FORMAT_BYTE) { -+ if (align == GST_H264_PARSE_ALIGN_NONE) -+ align = GST_H264_PARSE_ALIGN_NAL; - /* should have SPS/PSS in-band (and/or oob in streamheader field) */ - if (codec_data_value != NULL) - goto bytestream_caps_with_codec_data; --- -2.5.1 - diff --git a/patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch b/patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch deleted file mode 100644 index c1335c664d..0000000000 --- a/patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch +++ /dev/null @@ -1,106 +0,0 @@ -From dbdc05803a63c4d530ea0c2932af2b35df5467b3 Mon Sep 17 00:00:00 2001 -From: Sreerenj Balachandran -Date: Tue, 21 Jul 2015 12:13:18 +0300 -Subject: [PATCH 4/6] h264parse: Disable 3D video support for GStreamer < 1.5 - -All API/ABI changes for S3D/MVC are added in 1.5, backporting -them to older verison is not recommended. - -Signed-off-by: Sreerenj Balachandran ---- - gst/vaapi/gsth264parse.c | 11 ++++++++++- - gst/vaapi/gsth264parse.h | 2 ++ - 2 files changed, 12 insertions(+), 1 deletion(-) - -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index f1ed269..7ed6db8 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -218,9 +218,11 @@ gst_h264_parse_reset_stream_info (GstH264Parse * h264parse) - h264parse->have_pps = FALSE; - h264parse->have_sps = FALSE; - -+#if GST_CHECK_VERSION(1,5,0) - h264parse->multiview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE; - h264parse->multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE; - h264parse->first_in_bundle = TRUE; -+#endif - - h264parse->align = GST_H264_PARSE_ALIGN_NONE; - h264parse->format = GST_H264_PARSE_FORMAT_NONE; -@@ -571,6 +573,7 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) - /* Additional messages that are not innerly useful to the - * element but for debugging purposes */ - case GST_H264_SEI_STEREO_VIDEO_INFO:{ -+#if GST_CHECK_VERSION(1,5,0) - GstVideoMultiviewMode mview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE; - GstVideoMultiviewFlags mview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE; - -@@ -602,9 +605,11 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) - /* output caps need to be changed */ - gst_h264_parse_update_src_caps (h264parse, NULL); - } -+#endif - break; - } - case GST_H264_SEI_FRAME_PACKING:{ -+#if GST_CHECK_VERSION(1,5,0) - GstVideoMultiviewMode mview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE; - GstVideoMultiviewFlags mview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE; - -@@ -693,6 +698,7 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) - /* output caps need to be changed */ - gst_h264_parse_update_src_caps (h264parse, NULL); - } -+#endif - break; - } - } -@@ -1762,9 +1768,11 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) - gint width, height; - GstClockTime latency; - -+#if GST_CHECK_VERSION(1,5,0) - const gchar *caps_mview_mode = NULL; - GstVideoMultiviewMode mview_mode = h264parse->multiview_mode; - GstVideoMultiviewFlags mview_flags = h264parse->multiview_flags; -+#endif - - fps_num = h264parse->fps_num; - fps_den = h264parse->fps_den; -@@ -1796,6 +1804,7 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) - } - } - -+#if GST_CHECK_VERSION(1,5,0) - /* Pass through or set output stereo/multiview config */ - if (s && gst_structure_has_field (s, "multiview-mode")) { - caps_mview_mode = gst_structure_get_string (s, "multiview-mode"); -@@ -1814,7 +1823,7 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) - GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, mview_flags, - GST_FLAG_SET_MASK_EXACT, NULL); - } -- -+#endif - gst_caps_set_simple (caps, "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, NULL); - -diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h -index 617e616..1b89d31 100644 ---- a/gst/vaapi/gsth264parse.h -+++ b/gst/vaapi/gsth264parse.h -@@ -124,10 +124,12 @@ struct _GstH264Parse - GstClockTime pending_key_unit_ts; - GstEvent *force_key_unit_event; - -+#if GST_CHECK_VERSION(1,5,0) - /* Stereo / multiview info */ - GstVideoMultiviewMode multiview_mode; - GstVideoMultiviewFlags multiview_flags; - gboolean first_in_bundle; -+#endif - }; - - struct _GstH264ParseClass --- -2.5.1 diff --git a/patches/videoparsers/0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch b/patches/videoparsers/0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch deleted file mode 100644 index 4366e70897..0000000000 --- a/patches/videoparsers/0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 90251ef253564e7e53c754205cb506e863a93a6c Mon Sep 17 00:00:00 2001 -From: Sreerenj Balachandran -Date: Thu, 26 Nov 2015 19:13:43 +0200 -Subject: [PATCH] videoparsers: h264: Disable passthorugh mode enabling - -Enabling passthorugh mode for optimization is cauing multiple -issues while parsing MVC streams. Specifically if streams have -two separate layers (base-view and non-base-view). - -Proper fixes needed in many places: -(handle prefix nal unit, handle non-base-view slice nal extension, -fix the picture_start detection for multi-layer-mvc streams etc) - -https://bugzilla.gnome.org/show_bug.cgi?id=758656 ---- - gst/vaapi/gsth264parse.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c -index 915c2d7..445a791 100644 ---- a/gst/vaapi/gsth264parse.c -+++ b/gst/vaapi/gsth264parse.c -@@ -2356,6 +2356,9 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) - } - } - -+ /* Fixme: setting passthrough mode for MVC streams causing multiple -+ * issues. Disabing passthourgh mode for now */ -+#if 0 - /* If SPS/PPS and a keyframe have been parsed, and we're not converting, - * we might switch to passthrough mode now on the basis that we've seen - * the SEI packets and know optional caps params (such as multiview). -@@ -2367,6 +2370,7 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) - gst_base_parse_set_passthrough (parse, TRUE); - } - } -+#endif - - gst_h264_parse_reset_frame (h264parse); - --- -2.5.0 - diff --git a/patches/videoparsers/0006-h265parse-include-gstvaapiparse.h.patch b/patches/videoparsers/0006-h265parse-include-gstvaapiparse.h.patch deleted file mode 100644 index 75bc8d5995..0000000000 --- a/patches/videoparsers/0006-h265parse-include-gstvaapiparse.h.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 06ab8f433c02590b63e8afdf394a2a1caf570fad Mon Sep 17 00:00:00 2001 -From: Sreerenj Balachandran -Date: Thu, 16 Apr 2015 18:04:53 +0300 -Subject: [PATCH 5/6] h265parse: include gstvaapiparse.h - ---- - gst/vaapi/gsth265parse.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/gst/vaapi/gsth265parse.c b/gst/vaapi/gsth265parse.c -index d649681..5f65ab6 100644 ---- a/gst/vaapi/gsth265parse.c -+++ b/gst/vaapi/gsth265parse.c -@@ -22,6 +22,7 @@ - # include "config.h" - #endif - -+#include "gstvaapiparse.h" - #include - #include - #include -@@ -100,7 +101,7 @@ gst_h265_parse_class_init (GstH265ParseClass * klass) - GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass); - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - -- GST_DEBUG_CATEGORY_INIT (h265_parse_debug, "h265parse", 0, "h265 parser"); -+ GST_DEBUG_CATEGORY_INIT (h265_parse_debug, "vaapiparse_h265", 0, "h265 parser"); - - gobject_class->finalize = gst_h265_parse_finalize; - gobject_class->set_property = gst_h265_parse_set_property; --- -2.5.1 diff --git a/patches/videoparsers/0007-h265parse-fix-build-with-GStreamer-1.5.patch b/patches/videoparsers/0007-h265parse-fix-build-with-GStreamer-1.5.patch deleted file mode 100644 index 0bf8617246..0000000000 --- a/patches/videoparsers/0007-h265parse-fix-build-with-GStreamer-1.5.patch +++ /dev/null @@ -1,48 +0,0 @@ -From aaf9569d096392d73f45bcf9973d58b90a7ecd27 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= - -Date: Mon, 14 Sep 2015 19:11:59 +0200 -Subject: [PATCH 6/6] h265parse: fix build with GStreamer < 1.5 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Víctor Manuel Jáquez Leal ---- - gst/vaapi/gsth265parse.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/gst/vaapi/gsth265parse.c b/gst/vaapi/gsth265parse.c -index 5f65ab6..35b0812 100644 ---- a/gst/vaapi/gsth265parse.c -+++ b/gst/vaapi/gsth265parse.c -@@ -141,8 +141,12 @@ gst_h265_parse_init (GstH265Parse * h265parse) - { - h265parse->frame_out = gst_adapter_new (); - gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h265parse), FALSE); -+#if GST_CHECK_VERSION(1,3,0) - GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h265parse)); -+#endif -+#if GST_CHECK_VERSION(1,5,0) - GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (h265parse)); -+#endif - } - - -@@ -1774,8 +1778,14 @@ gst_h265_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) - GST_TAG_VIDEO_CODEC, caps); - gst_caps_unref (caps); - -+#if GST_CHECK_VERSION(1,5,0) - gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE); - gst_tag_list_unref (taglist); -+#else -+ gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (h265parse), -+ gst_event_new_tag (taglist)); -+#endif -+ - - /* also signals the end of first-frame processing */ - h265parse->sent_codec_tag = TRUE; --- -2.5.1 diff --git a/patches/videoparsers/Makefile.am b/patches/videoparsers/Makefile.am deleted file mode 100644 index cf1b2a87e8..0000000000 --- a/patches/videoparsers/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -include series.frag - -EXTRA_DIST = \ - series.frag \ - $(videoparsers_patches_base) \ - $(videoparsers_patches_1_4p) \ - $(NULL) - --include $(top_srcdir)/git.mk diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag deleted file mode 100644 index ae09dbcb26..0000000000 --- a/patches/videoparsers/series.frag +++ /dev/null @@ -1,14 +0,0 @@ -# sources.frag - Generated list of patches for videoparsers (-*- makefile -*-) - -videoparsers_patches_base = \ - 0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch \ - 0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch \ - 0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ - 0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch \ - 0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch \ - $(NULL) - -videoparsers_patches_1_4p = \ - 0006-h265parse-include-gstvaapiparse.h.patch \ - 0007-h265parse-fix-build-with-GStreamer-1.5.patch \ - $(NULL) From bc54fa27e6a0ef44f7ca0f47c5a5a9980b650359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Dec 2015 15:37:39 +0100 Subject: [PATCH 2229/3781] Do not install libgstvaapi headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- debian.upstream/libgstvaapi-dev.install.in | 1 - gst-libs/gst/vaapi/Makefile.am | 39 ---------------------- 2 files changed, 40 deletions(-) diff --git a/debian.upstream/libgstvaapi-dev.install.in b/debian.upstream/libgstvaapi-dev.install.in index b6aa01de4d..91ef83bd82 100644 --- a/debian.upstream/libgstvaapi-dev.install.in +++ b/debian.upstream/libgstvaapi-dev.install.in @@ -1,2 +1 @@ debian/tmp/usr/lib/libgstvaapi*.so -debian/tmp/usr/include/gstreamer-@GST_PKG_VERSION@/gst/vaapi/*.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 1818f75c50..ec007260f5 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -20,9 +20,6 @@ if USE_WAYLAND lib_LTLIBRARIES += libgstvaapi-wayland-@GST_API_VERSION@.la endif -libgstvaapi_includedir = \ - $(includedir)/gstreamer-$(GST_PKG_VERSION)/gst/vaapi - libgstvaapi_cflags = \ -DIN_LIBGSTVAAPI \ -DIN_LIBGSTVAAPI_CORE \ @@ -342,15 +339,9 @@ libgstvaapi_wayland_source_priv_h = \ libgstvaapi_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_source_c) \ $(libgstvaapi_source_priv_h) \ - $(NULL) - -libgstvaapi_@GST_API_VERSION@include_HEADERS = \ $(libgstvaapi_source_h) \ $(NULL) -libgstvaapi_@GST_API_VERSION@includedir = \ - $(libgstvaapi_includedir) - libgstvaapi_@GST_API_VERSION@_la_CFLAGS = \ $(libgstvaapi_cflags) \ $(NULL) @@ -368,15 +359,9 @@ libgstvaapi_@GST_API_VERSION@_la_LDFLAGS = \ libgstvaapi_drm_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_drm_source_c) \ $(libgstvaapi_drm_source_priv_h) \ - $(NULL) - -libgstvaapi_drm_@GST_API_VERSION@include_HEADERS = \ $(libgstvaapi_drm_source_h) \ $(NULL) -libgstvaapi_drm_@GST_API_VERSION@includedir = \ - $(libgstvaapi_includedir) - libgstvaapi_drm_@GST_API_VERSION@_la_CFLAGS = \ -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ @@ -406,15 +391,9 @@ libgstvaapi_drm_@GST_API_VERSION@_la_LDFLAGS = \ libgstvaapi_x11_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_x11_source_c) \ $(libgstvaapi_x11_source_priv_h) \ - $(NULL) - -libgstvaapi_x11_@GST_API_VERSION@include_HEADERS = \ $(libgstvaapi_x11_source_h) \ $(NULL) -libgstvaapi_x11_@GST_API_VERSION@includedir = \ - $(libgstvaapi_includedir) - libgstvaapi_x11_@GST_API_VERSION@_la_CFLAGS = \ -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ @@ -446,15 +425,9 @@ libgstvaapi_x11_@GST_API_VERSION@_la_LDFLAGS = \ libgstvaapi_glx_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_glx_source_c) \ $(libgstvaapi_glx_source_priv_h) \ - $(NULL) - -libgstvaapi_glx_@GST_API_VERSION@include_HEADERS = \ $(libgstvaapi_glx_source_h) \ $(NULL) -libgstvaapi_glx_@GST_API_VERSION@includedir = \ - $(libgstvaapi_includedir) - libgstvaapi_glx_@GST_API_VERSION@_la_CFLAGS = \ -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ @@ -487,15 +460,9 @@ libgstvaapi_glx_@GST_API_VERSION@_la_LDFLAGS = \ libgstvaapi_egl_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_egl_source_c) \ $(libgstvaapi_egl_source_priv_h) \ - $(NULL) - -libgstvaapi_egl_@GST_API_VERSION@include_HEADERS = \ $(libgstvaapi_egl_source_h) \ $(NULL) -libgstvaapi_egl_@GST_API_VERSION@includedir = \ - $(libgstvaapi_includedir) - libgstvaapi_egl_@GST_API_VERSION@_la_CFLAGS = \ -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ @@ -527,15 +494,9 @@ libgstvaapi_egl_@GST_API_VERSION@_la_LDFLAGS = \ libgstvaapi_wayland_@GST_API_VERSION@_la_SOURCES = \ $(libgstvaapi_wayland_source_c) \ $(libgstvaapi_wayland_source_priv_h) \ - $(NULL) - -libgstvaapi_wayland_@GST_API_VERSION@include_HEADERS = \ $(libgstvaapi_wayland_source_h) \ $(NULL) -libgstvaapi_wayland_@GST_API_VERSION@includedir = \ - $(libgstvaapi_includedir) - libgstvaapi_wayland_@GST_API_VERSION@_la_CFLAGS = \ -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ From f8bb6740288c6fb94bb79155a8b6e66fd0605706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Dec 2015 16:59:16 +0100 Subject: [PATCH 2230/3781] libs: make libraries no installables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 12 ---- debian.upstream/Makefile.am | 12 ---- debian.upstream/control.in | 60 ------------------- debian.upstream/libgstvaapi-dev.install.in | 1 - debian.upstream/libgstvaapi-drm.install.in | 1 - debian.upstream/libgstvaapi-glx.install.in | 1 - .../libgstvaapi-wayland.install.in | 1 - debian.upstream/libgstvaapi-x11.install.in | 1 - debian.upstream/libgstvaapi.install.in | 1 - gst-libs/gst/vaapi/Makefile.am | 34 ++--------- tests/Makefile.am | 32 +++++++--- 11 files changed, 30 insertions(+), 126 deletions(-) delete mode 100644 debian.upstream/libgstvaapi-dev.install.in delete mode 100644 debian.upstream/libgstvaapi-drm.install.in delete mode 100644 debian.upstream/libgstvaapi-glx.install.in delete mode 100644 debian.upstream/libgstvaapi-wayland.install.in delete mode 100644 debian.upstream/libgstvaapi-x11.install.in delete mode 100644 debian.upstream/libgstvaapi.install.in diff --git a/configure.ac b/configure.ac index 0926c86ef6..554ff34879 100644 --- a/configure.ac +++ b/configure.ac @@ -1074,18 +1074,6 @@ AC_CONFIG_FILES([ debian.upstream/gstreamer-vaapi-doc.install.in debian.upstream/gstreamer$GST_API_VERSION-vaapi.install:\ debian.upstream/gstreamer-vaapi.install.in - debian.upstream/libgstvaapi$GST_PKG_VERSION-dev.install:\ -debian.upstream/libgstvaapi-dev.install.in - debian.upstream/libgstvaapi$GST_VAAPI_MAJOR_VERSION.install:\ -debian.upstream/libgstvaapi.install.in - debian.upstream/libgstvaapi-drm-$GST_VAAPI_MAJOR_VERSION.install:\ -debian.upstream/libgstvaapi-drm.install.in - debian.upstream/libgstvaapi-glx-$GST_VAAPI_MAJOR_VERSION.install:\ -debian.upstream/libgstvaapi-glx.install.in - debian.upstream/libgstvaapi-wayland-$GST_VAAPI_MAJOR_VERSION.install:\ -debian.upstream/libgstvaapi-wayland.install.in - debian.upstream/libgstvaapi-x11-$GST_VAAPI_MAJOR_VERSION.install:\ -debian.upstream/libgstvaapi-x11.install.in docs/Makefile docs/reference/Makefile docs/reference/libs/Makefile diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am index fd5dad5bbb..ea97d15887 100644 --- a/debian.upstream/Makefile.am +++ b/debian.upstream/Makefile.am @@ -12,12 +12,6 @@ DEBIANFILES = \ copyright \ gstreamer-vaapi-doc.install.in \ gstreamer-vaapi.install.in \ - libgstvaapi-dev.install.in \ - libgstvaapi-drm.install.in \ - libgstvaapi-glx.install.in \ - libgstvaapi-wayland.install.in \ - libgstvaapi-x11.install.in \ - libgstvaapi.install.in \ rules \ $(NULL) @@ -26,12 +20,6 @@ DEBIANGENFILES = \ control \ gstreamer$(GST_API_VERSION)-vaapi-doc.install \ gstreamer$(GST_API_VERSION)-vaapi.install \ - libgstvaapi$(GST_PKG_VERSION)-dev.install \ - libgstvaapi$(GST_VAAPI_MAJOR_VERSION).install \ - libgstvaapi-drm-$(GST_VAAPI_MAJOR_VERSION).install \ - libgstvaapi-glx-$(GST_VAAPI_MAJOR_VERSION).install \ - libgstvaapi-wayland-$(GST_VAAPI_MAJOR_VERSION).install \ - libgstvaapi-x11-$(GST_VAAPI_MAJOR_VERSION).install \ $(NULL) EXTRA_DIST = $(DEBIANFILES) diff --git a/debian.upstream/control.in b/debian.upstream/control.in index ec60688f02..a66e6c8447 100644 --- a/debian.upstream/control.in +++ b/debian.upstream/control.in @@ -45,63 +45,3 @@ Description: VA-API plugins for GStreamer VA-API support plugins for GStreamer. . This package contains the debug files. - -Package: libgstvaapi@GST_VAAPI_MAJOR_VERSION@ -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: GStreamer libraries from the "vaapi" set - VA-API support libraries for GStreamer. - . - This package contains common libraries for the "vaapi" set. - -@USE_DRM_TRUE@Package: libgstvaapi-drm-@GST_VAAPI_MAJOR_VERSION@ -@USE_DRM_TRUE@Section: libs -@USE_DRM_TRUE@Architecture: any -@USE_DRM_TRUE@Depends: ${shlibs:Depends}, ${misc:Depends} -@USE_DRM_TRUE@Description: GStreamer libraries from the "vaapi" set -@USE_DRM_TRUE@ VA-API support libraries for GStreamer. -@USE_DRM_TRUE@ . -@USE_DRM_TRUE@ This package contains headless libraries for the "vaapi" set. - -@USE_X11_TRUE@Package: libgstvaapi-x11-@GST_VAAPI_MAJOR_VERSION@ -@USE_X11_TRUE@Section: libs -@USE_X11_TRUE@Architecture: any -@USE_X11_TRUE@Depends: ${shlibs:Depends}, ${misc:Depends} -@USE_X11_TRUE@Description: GStreamer libraries from the "vaapi" set -@USE_X11_TRUE@ VA-API support libraries for GStreamer. -@USE_X11_TRUE@ . -@USE_X11_TRUE@ This package contains x11 libraries for the "vaapi" set. - -@USE_GLX_TRUE@Package: libgstvaapi-glx-@GST_VAAPI_MAJOR_VERSION@ -@USE_GLX_TRUE@Section: libs -@USE_GLX_TRUE@Architecture: any -@USE_GLX_TRUE@Depends: ${shlibs:Depends}, ${misc:Depends} -@USE_GLX_TRUE@Description: GStreamer libraries from the "vaapi" set -@USE_GLX_TRUE@ VA-API support libraries for GStreamer. -@USE_GLX_TRUE@ . -@USE_GLX_TRUE@ This package contains glx libraries for the "vaapi" set. - -@USE_WAYLAND_TRUE@Package: libgstvaapi-wayland-@GST_VAAPI_MAJOR_VERSION@ -@USE_WAYLAND_TRUE@Section: libs -@USE_WAYLAND_TRUE@Architecture: any -@USE_WAYLAND_TRUE@Depends: ${shlibs:Depends}, ${misc:Depends} -@USE_WAYLAND_TRUE@Description: GStreamer libraries from the "vaapi" set -@USE_WAYLAND_TRUE@ VA-API support libraries for GStreamer. -@USE_WAYLAND_TRUE@ . -@USE_WAYLAND_TRUE@ This package contains Wayland libraries for the "vaapi" set. - -Package: libgstvaapi@GST_PKG_VERSION@-dev -Architecture: any -Section: libdevel -Depends: ${shlibs:Depends}, ${misc:Depends}, -@USE_DRM_TRUE@ libgstvaapi-drm-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), -@USE_X11_TRUE@ libgstvaapi-x11-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), -@USE_GLX_TRUE@ libgstvaapi-glx-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), -@USE_WAYLAND_TRUE@ libgstvaapi-wayland-@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}), - libgstvaapi@GST_VAAPI_MAJOR_VERSION@ (= ${Source-Version}) -Description: GStreamer development files for libraries from the "vaapi" set - GStreamer/VA-API development files. - . - This package contains development files for GStreamer libraries for - the "vaapi" set. diff --git a/debian.upstream/libgstvaapi-dev.install.in b/debian.upstream/libgstvaapi-dev.install.in deleted file mode 100644 index 91ef83bd82..0000000000 --- a/debian.upstream/libgstvaapi-dev.install.in +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libgstvaapi*.so diff --git a/debian.upstream/libgstvaapi-drm.install.in b/debian.upstream/libgstvaapi-drm.install.in deleted file mode 100644 index 3b18b62ef7..0000000000 --- a/debian.upstream/libgstvaapi-drm.install.in +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libgstvaapi-drm-@GST_API_VERSION@.so.* diff --git a/debian.upstream/libgstvaapi-glx.install.in b/debian.upstream/libgstvaapi-glx.install.in deleted file mode 100644 index c1001021ac..0000000000 --- a/debian.upstream/libgstvaapi-glx.install.in +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libgstvaapi-glx-@GST_API_VERSION@.so.* diff --git a/debian.upstream/libgstvaapi-wayland.install.in b/debian.upstream/libgstvaapi-wayland.install.in deleted file mode 100644 index ce4b3dd64e..0000000000 --- a/debian.upstream/libgstvaapi-wayland.install.in +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libgstvaapi-wayland-@GST_API_VERSION@.so.* diff --git a/debian.upstream/libgstvaapi-x11.install.in b/debian.upstream/libgstvaapi-x11.install.in deleted file mode 100644 index ff05932a2c..0000000000 --- a/debian.upstream/libgstvaapi-x11.install.in +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libgstvaapi-x11-@GST_API_VERSION@.so.* diff --git a/debian.upstream/libgstvaapi.install.in b/debian.upstream/libgstvaapi.install.in deleted file mode 100644 index f719a6f347..0000000000 --- a/debian.upstream/libgstvaapi.install.in +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libgstvaapi-@GST_API_VERSION@.so.* diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index ec007260f5..ee10733b26 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -1,23 +1,23 @@ -lib_LTLIBRARIES = libgstvaapi-@GST_API_VERSION@.la +noinst_LTLIBRARIES = libgstvaapi-@GST_API_VERSION@.la if USE_DRM -lib_LTLIBRARIES += libgstvaapi-drm-@GST_API_VERSION@.la +noinst_LTLIBRARIES += libgstvaapi-drm-@GST_API_VERSION@.la endif if USE_X11 -lib_LTLIBRARIES += libgstvaapi-x11-@GST_API_VERSION@.la +noinst_LTLIBRARIES += libgstvaapi-x11-@GST_API_VERSION@.la endif if USE_GLX -lib_LTLIBRARIES += libgstvaapi-glx-@GST_API_VERSION@.la +noinst_LTLIBRARIES += libgstvaapi-glx-@GST_API_VERSION@.la endif if USE_EGL -lib_LTLIBRARIES += libgstvaapi-egl-@GST_API_VERSION@.la +noinst_LTLIBRARIES += libgstvaapi-egl-@GST_API_VERSION@.la endif if USE_WAYLAND -lib_LTLIBRARIES += libgstvaapi-wayland-@GST_API_VERSION@.la +noinst_LTLIBRARIES += libgstvaapi-wayland-@GST_API_VERSION@.la endif libgstvaapi_cflags = \ @@ -236,7 +236,6 @@ endif libgstvaapi_drm_source_c = \ gstvaapidisplay_drm.c \ gstvaapiwindow_drm.c \ - gstvaapiutils.c \ $(NULL) libgstvaapi_drm_source_h = \ @@ -247,13 +246,11 @@ libgstvaapi_drm_source_h = \ libgstvaapi_drm_source_priv_h = \ gstvaapicompat.h \ gstvaapidisplay_drm_priv.h \ - gstvaapiutils.h \ $(NULL) libgstvaapi_x11_source_c = \ gstvaapidisplay_x11.c \ gstvaapipixmap_x11.c \ - gstvaapiutils.c \ gstvaapiutils_x11.c \ gstvaapiwindow_x11.c \ $(NULL) @@ -267,7 +264,6 @@ libgstvaapi_x11_source_h = \ libgstvaapi_x11_source_priv_h = \ gstvaapicompat.h \ gstvaapidisplay_x11_priv.h \ - gstvaapiutils.h \ gstvaapiutils_x11.h \ gstvaapiwindow_x11_priv.h \ $(NULL) @@ -275,9 +271,7 @@ libgstvaapi_x11_source_priv_h = \ libgstvaapi_glx_source_c = \ gstvaapidisplay_glx.c \ gstvaapitexture_glx.c \ - gstvaapiutils.c \ gstvaapiutils_glx.c \ - gstvaapiutils_x11.c \ gstvaapiwindow_glx.c \ $(NULL) @@ -293,7 +287,6 @@ libgstvaapi_glx_source_priv_h = \ gstvaapidisplay_glx_priv.h \ gstvaapiutils.h \ gstvaapiutils_glx.h \ - gstvaapiutils_x11.h \ $(NULL) libgstvaapi_egl_source_c = \ @@ -321,7 +314,6 @@ libgstvaapi_egl_source_priv_h = \ libgstvaapi_wayland_source_c = \ gstvaapidisplay_wayland.c \ - gstvaapiutils.c \ gstvaapiwindow_wayland.c \ $(NULL) @@ -333,7 +325,6 @@ libgstvaapi_wayland_source_h = \ libgstvaapi_wayland_source_priv_h = \ gstvaapicompat.h \ gstvaapidisplay_wayland_priv.h \ - gstvaapiutils.h \ $(NULL) libgstvaapi_@GST_API_VERSION@_la_SOURCES = \ @@ -352,8 +343,6 @@ libgstvaapi_@GST_API_VERSION@_la_LIBADD = \ libgstvaapi_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ - $(GST_VAAPI_LT_LDFLAGS) \ - -export-symbols-regex "^gst_.*vaapi.*" \ $(NULL) libgstvaapi_drm_@GST_API_VERSION@_la_SOURCES = \ @@ -380,12 +369,10 @@ libgstvaapi_drm_@GST_API_VERSION@_la_LIBADD = \ $(UDEV_LIBS) \ $(DRM_LIBS) \ $(LIBVA_DRM_LIBS) \ - libgstvaapi-$(GST_API_VERSION).la \ $(NULL) libgstvaapi_drm_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ - $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) libgstvaapi_x11_@GST_API_VERSION@_la_SOURCES = \ @@ -414,12 +401,10 @@ libgstvaapi_x11_@GST_API_VERSION@_la_LIBADD = \ $(XRANDR_LIBS) \ $(XRENDER_LIBS) \ $(LIBVA_X11_LIBS) \ - libgstvaapi-$(GST_API_VERSION).la \ $(NULL) libgstvaapi_x11_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ - $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) libgstvaapi_glx_@GST_API_VERSION@_la_SOURCES = \ @@ -447,14 +432,11 @@ libgstvaapi_glx_@GST_API_VERSION@_la_LIBADD = \ $(X11_LIBS) \ $(GL_LIBS) \ $(LIBVA_X11_LIBS) \ - libgstvaapi-x11-$(GST_API_VERSION).la \ - libgstvaapi-$(GST_API_VERSION).la \ $(DLOPEN_LIBS) \ $(NULL) libgstvaapi_glx_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ - $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) libgstvaapi_egl_@GST_API_VERSION@_la_SOURCES = \ @@ -481,14 +463,12 @@ libgstvaapi_egl_@GST_API_VERSION@_la_LIBADD = \ $(GST_LIBS) \ $(GST_BASE_LIBS) \ $(GST_VIDEO_LIBS) \ - libgstvaapi-$(GST_API_VERSION).la \ $(EGL_LIBS) \ $(DLOPEN_LIBS) \ $(NULL) libgstvaapi_egl_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ - $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) libgstvaapi_wayland_@GST_API_VERSION@_la_SOURCES = \ @@ -514,12 +494,10 @@ libgstvaapi_wayland_@GST_API_VERSION@_la_LIBADD = \ $(GST_VIDEO_LIBS) \ $(WAYLAND_LIBS) \ $(LIBVA_WAYLAND_LIBS) \ - libgstvaapi-$(GST_API_VERSION).la \ $(NULL) libgstvaapi_wayland_@GST_API_VERSION@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ - $(GST_VAAPI_LT_LDFLAGS) \ $(NULL) VERSION_FILE = .VERSION diff --git a/tests/Makefile.am b/tests/Makefile.am index 3637d92297..831a9d914e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -29,49 +29,53 @@ TEST_CFLAGS = \ $(GST_VIDEO_CFLAGS) \ $(NULL) +GST_VAAPI_LIBS = $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_API_VERSION).la TEST_LIBS = \ $(LIBVA_LIBS) \ $(GST_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_API_VERSION).la + $(NULL) if USE_DRM +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm-$(GST_API_VERSION).la TEST_CFLAGS += $(LIBVA_DRM_CFLAGS) -TEST_LIBS += \ - $(LIBVA_DRM_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm-$(GST_API_VERSION).la +TEST_LIBS += $(LIBVA_DRM_LIBS) endif if USE_X11 +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la TEST_CFLAGS += $(X11_CFLAGS) TEST_LIBS += \ $(LIBVA_X11_LIBS) \ $(X11_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la + $(NULL) endif if USE_GLX +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la TEST_CFLAGS += $(X11_CFLAGS) $(GL_CFLAGS) TEST_LIBS += \ $(LIBVA_GLX_LIBS) \ $(X11_LIBS) \ $(GL_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la + $(NULL) endif if USE_EGL +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl-$(GST_API_VERSION).la TEST_CFLAGS += $(EGL_CFLAGS) TEST_LIBS += \ $(LIBVA_EGL_LIBS) \ $(EGL_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl-$(GST_API_VERSION).la + $(NULL) endif if USE_WAYLAND +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-$(GST_API_VERSION).la TEST_CFLAGS += $(WAYLAND_CFLAGS) TEST_LIBS += \ $(LIBVA_WAYLAND_LIBS) \ $(WAYLAND_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-$(GST_API_VERSION).la + $(NULL) endif test_utils_dec_source_c = \ @@ -88,10 +92,14 @@ test_utils_source_c = codec.c image.c output.c test_utils_source_h = codec.h image.h output.h noinst_LTLIBRARIES = libutils.la libutils_dec.la + libutils_la_SOURCES = $(test_utils_source_c) libutils_la_CFLAGS = $(TEST_CFLAGS) +libutils_la_LDFLAGS = $(GST_VAAPI_LIBS) + libutils_dec_la_SOURCES = $(test_utils_dec_source_c) libutils_dec_la_CFLAGS = $(TEST_CFLAGS) +libutils_dec_la_LDFLAGS = $(GST_VAAPI_LIBS) test_decode_SOURCES = test-decode.c test_decode_CFLAGS = $(TEST_CFLAGS) @@ -99,39 +107,47 @@ test_decode_LDADD = libutils.la libutils_dec.la $(TEST_LIBS) test_display_SOURCES = test-display.c test_display_CFLAGS = $(TEST_CFLAGS) +test_display_LDFLAGS = $(GST_VAAPI_LIBS) test_display_LDADD = libutils.la $(TEST_LIBS) test_filter_SOURCES = test-filter.c test_filter_CFLAGS = $(TEST_CFLAGS) +test_filter_LDFLAGS = $(GST_VAAPI_LIBS) test_filter_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) test_surfaces_SOURCES = test-surfaces.c test_surfaces_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) +test_surfaces_LDFLAGS = $(GST_VAAPI_LIBS) test_surfaces_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) test_subpicture_SOURCES = test-subpicture.c test-subpicture-data.c test_subpicture_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) test_subpicture_LDADD = libutils.la libutils_dec.la $(TEST_LIBS) \ $(GST_VIDEO_LIBS) +test_subpicture_LDFLAGS = $(GST_VAAPI_LIBS) test_windows_SOURCES = test-windows.c test_windows_CFLAGS = $(TEST_CFLAGS) +test_windows_LDFLAGS = $(GST_VAAPI_LIBS) test_windows_LDADD = libutils.la $(TEST_LIBS) test_textures_SOURCES = test-textures.c test_textures_CFLAGS = $(TEST_CFLAGS) +test_textures_LDFLAGS = $(GST_VAAPI_LIBS) test_textures_LDADD = libutils.la $(TEST_LIBS) simple_decoder_source_c = simple-decoder.c simple_decoder_source_h = simple_decoder_SOURCES = $(simple_decoder_source_c) simple_decoder_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) +simple_decoder_LDFLAGS = $(GST_VAAPI_LIBS) simple_decoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) simple_encoder_source_c = simple-encoder.c y4mreader.c simple_encoder_source_h = y4mreader.h simple_encoder_SOURCES = $(simple_encoder_source_c) simple_encoder_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) +simple_encoder_LDFLAGS = $(GST_VAAPI_LIBS) simple_encoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) EXTRA_DIST = \ From fa6144545f2ba281b3492838f9525ce0fe157503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Dec 2015 19:52:33 +0100 Subject: [PATCH 2231/3781] libs: remove versioning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we don't install libraries anymore, it makes no sense to keep versioning them according to the gstreamer's version. Signed-off-by: Víctor Manuel Jáquez Leal --- docs/reference/libs/Makefile.am | 6 +-- docs/reference/plugins/Makefile.am | 4 +- gst-libs/gst/vaapi/Makefile.am | 60 +++++++++++++++--------------- gst/vaapi/Makefile.am | 17 +++------ tests/Makefile.am | 12 +++--- 5 files changed, 47 insertions(+), 52 deletions(-) diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am index 036bd7dcc0..6298a5c11c 100644 --- a/docs/reference/libs/Makefile.am +++ b/docs/reference/libs/Makefile.am @@ -104,14 +104,14 @@ INCLUDES = \ GTKDOC_LIBS = \ $(GLIB_LIBS) \ $(GST_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_API_VERSION).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la GTKDOC_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11.la if USE_GLX GTKDOC_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx.la endif # This includes the standard gtk-doc make rules, copied by gtkdocize. diff --git a/docs/reference/plugins/Makefile.am b/docs/reference/plugins/Makefile.am index d933508438..87addf9490 100644 --- a/docs/reference/plugins/Makefile.am +++ b/docs/reference/plugins/Makefile.am @@ -88,12 +88,12 @@ INCLUDES = \ $(NULL) gtkdoc_vaapi_libs = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_API_VERSION).la \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la \ $(NULL) if USE_X11 gtkdoc_vaapi_libs += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la \ + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11.la \ $(NULL) endif diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index ee10733b26..ab4e968f86 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -1,23 +1,23 @@ -noinst_LTLIBRARIES = libgstvaapi-@GST_API_VERSION@.la +noinst_LTLIBRARIES = libgstvaapi.la if USE_DRM -noinst_LTLIBRARIES += libgstvaapi-drm-@GST_API_VERSION@.la +noinst_LTLIBRARIES += libgstvaapi-drm.la endif if USE_X11 -noinst_LTLIBRARIES += libgstvaapi-x11-@GST_API_VERSION@.la +noinst_LTLIBRARIES += libgstvaapi-x11.la endif if USE_GLX -noinst_LTLIBRARIES += libgstvaapi-glx-@GST_API_VERSION@.la +noinst_LTLIBRARIES += libgstvaapi-glx.la endif if USE_EGL -noinst_LTLIBRARIES += libgstvaapi-egl-@GST_API_VERSION@.la +noinst_LTLIBRARIES += libgstvaapi-egl.la endif if USE_WAYLAND -noinst_LTLIBRARIES += libgstvaapi-wayland-@GST_API_VERSION@.la +noinst_LTLIBRARIES += libgstvaapi-wayland.la endif libgstvaapi_cflags = \ @@ -327,31 +327,31 @@ libgstvaapi_wayland_source_priv_h = \ gstvaapidisplay_wayland_priv.h \ $(NULL) -libgstvaapi_@GST_API_VERSION@_la_SOURCES = \ +libgstvaapi_la_SOURCES = \ $(libgstvaapi_source_c) \ $(libgstvaapi_source_priv_h) \ $(libgstvaapi_source_h) \ $(NULL) -libgstvaapi_@GST_API_VERSION@_la_CFLAGS = \ +libgstvaapi_la_CFLAGS = \ $(libgstvaapi_cflags) \ $(NULL) -libgstvaapi_@GST_API_VERSION@_la_LIBADD = \ +libgstvaapi_la_LIBADD = \ $(libgstvaapi_libs) \ $(NULL) -libgstvaapi_@GST_API_VERSION@_la_LDFLAGS = \ +libgstvaapi_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) -libgstvaapi_drm_@GST_API_VERSION@_la_SOURCES = \ +libgstvaapi_drm_la_SOURCES = \ $(libgstvaapi_drm_source_c) \ $(libgstvaapi_drm_source_priv_h) \ $(libgstvaapi_drm_source_h) \ $(NULL) -libgstvaapi_drm_@GST_API_VERSION@_la_CFLAGS = \ +libgstvaapi_drm_la_CFLAGS = \ -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ @@ -363,7 +363,7 @@ libgstvaapi_drm_@GST_API_VERSION@_la_CFLAGS = \ $(LIBVA_DRM_CFLAGS) \ $(NULL) -libgstvaapi_drm_@GST_API_VERSION@_la_LIBADD = \ +libgstvaapi_drm_la_LIBADD = \ $(GLIB_LIBS) \ $(GST_LIBS) \ $(UDEV_LIBS) \ @@ -371,17 +371,17 @@ libgstvaapi_drm_@GST_API_VERSION@_la_LIBADD = \ $(LIBVA_DRM_LIBS) \ $(NULL) -libgstvaapi_drm_@GST_API_VERSION@_la_LDFLAGS = \ +libgstvaapi_drm_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) -libgstvaapi_x11_@GST_API_VERSION@_la_SOURCES = \ +libgstvaapi_x11_la_SOURCES = \ $(libgstvaapi_x11_source_c) \ $(libgstvaapi_x11_source_priv_h) \ $(libgstvaapi_x11_source_h) \ $(NULL) -libgstvaapi_x11_@GST_API_VERSION@_la_CFLAGS = \ +libgstvaapi_x11_la_CFLAGS = \ -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ @@ -394,7 +394,7 @@ libgstvaapi_x11_@GST_API_VERSION@_la_CFLAGS = \ $(LIBVA_X11_CFLAGS) \ $(NULL) -libgstvaapi_x11_@GST_API_VERSION@_la_LIBADD = \ +libgstvaapi_x11_la_LIBADD = \ $(GLIB_LIBS) \ $(GST_LIBS) \ $(X11_LIBS) \ @@ -403,17 +403,17 @@ libgstvaapi_x11_@GST_API_VERSION@_la_LIBADD = \ $(LIBVA_X11_LIBS) \ $(NULL) -libgstvaapi_x11_@GST_API_VERSION@_la_LDFLAGS = \ +libgstvaapi_x11_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) -libgstvaapi_glx_@GST_API_VERSION@_la_SOURCES = \ +libgstvaapi_glx_la_SOURCES = \ $(libgstvaapi_glx_source_c) \ $(libgstvaapi_glx_source_priv_h) \ $(libgstvaapi_glx_source_h) \ $(NULL) -libgstvaapi_glx_@GST_API_VERSION@_la_CFLAGS = \ +libgstvaapi_glx_la_CFLAGS = \ -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ @@ -424,7 +424,7 @@ libgstvaapi_glx_@GST_API_VERSION@_la_CFLAGS = \ $(LIBVA_X11_CFLAGS) \ $(NULL) -libgstvaapi_glx_@GST_API_VERSION@_la_LIBADD = \ +libgstvaapi_glx_la_LIBADD = \ $(GLIB_LIBS) \ $(GST_LIBS) \ $(GST_BASE_LIBS) \ @@ -435,17 +435,17 @@ libgstvaapi_glx_@GST_API_VERSION@_la_LIBADD = \ $(DLOPEN_LIBS) \ $(NULL) -libgstvaapi_glx_@GST_API_VERSION@_la_LDFLAGS = \ +libgstvaapi_glx_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) -libgstvaapi_egl_@GST_API_VERSION@_la_SOURCES = \ +libgstvaapi_egl_la_SOURCES = \ $(libgstvaapi_egl_source_c) \ $(libgstvaapi_egl_source_priv_h) \ $(libgstvaapi_egl_source_h) \ $(NULL) -libgstvaapi_egl_@GST_API_VERSION@_la_CFLAGS = \ +libgstvaapi_egl_la_CFLAGS = \ -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ @@ -457,7 +457,7 @@ libgstvaapi_egl_@GST_API_VERSION@_la_CFLAGS = \ $(EGL_CFLAGS) \ $(NULL) -libgstvaapi_egl_@GST_API_VERSION@_la_LIBADD = \ +libgstvaapi_egl_la_LIBADD = \ $(GLIB_LIBS) \ $(GMODULE_LIBS) \ $(GST_LIBS) \ @@ -467,17 +467,17 @@ libgstvaapi_egl_@GST_API_VERSION@_la_LIBADD = \ $(DLOPEN_LIBS) \ $(NULL) -libgstvaapi_egl_@GST_API_VERSION@_la_LDFLAGS = \ +libgstvaapi_egl_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) -libgstvaapi_wayland_@GST_API_VERSION@_la_SOURCES = \ +libgstvaapi_wayland_la_SOURCES = \ $(libgstvaapi_wayland_source_c) \ $(libgstvaapi_wayland_source_priv_h) \ $(libgstvaapi_wayland_source_h) \ $(NULL) -libgstvaapi_wayland_@GST_API_VERSION@_la_CFLAGS = \ +libgstvaapi_wayland_la_CFLAGS = \ -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ @@ -488,7 +488,7 @@ libgstvaapi_wayland_@GST_API_VERSION@_la_CFLAGS = \ $(LIBVA_WAYLAND_CFLAGS) \ $(NULL) -libgstvaapi_wayland_@GST_API_VERSION@_la_LIBADD = \ +libgstvaapi_wayland_la_LIBADD = \ $(GLIB_LIBS) \ $(GST_LIBS) \ $(GST_VIDEO_LIBS) \ @@ -496,7 +496,7 @@ libgstvaapi_wayland_@GST_API_VERSION@_la_LIBADD = \ $(LIBVA_WAYLAND_LIBS) \ $(NULL) -libgstvaapi_wayland_@GST_API_VERSION@_la_LDFLAGS = \ +libgstvaapi_wayland_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 0fb9ad3cb2..b25d2dfde8 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -7,28 +7,24 @@ libgstvaapi_CFLAGS = \ -I$(top_builddir)/gst-libs \ $(NULL) -libgstvaapi_LIBS = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_API_VERSION).la +libgstvaapi_LIBS = $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la if USE_DRM -libgstvaapi_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm-$(GST_API_VERSION).la +libgstvaapi_LIBS +=$(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm.la endif if USE_X11 libgstvaapi_LIBS += \ $(X11_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la + $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11.la endif if USE_GLX -libgstvaapi_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la +libgstvaapi_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx.la endif if USE_EGL -libgstvaapi_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl-$(GST_API_VERSION).la +libgstvaapi_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl.la endif if USE_WAYLAND @@ -36,8 +32,7 @@ libgstvaapi_CFLAGS += \ $(WAYLAND_CFLAGS) \ $(NULL) -libgstvaapi_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-$(GST_API_VERSION).la +libgstvaapi_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland.la endif if USE_GST_GL_HELPERS diff --git a/tests/Makefile.am b/tests/Makefile.am index 831a9d914e..578b60538e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -29,20 +29,20 @@ TEST_CFLAGS = \ $(GST_VIDEO_CFLAGS) \ $(NULL) -GST_VAAPI_LIBS = $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-$(GST_API_VERSION).la +GST_VAAPI_LIBS = $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la TEST_LIBS = \ $(LIBVA_LIBS) \ $(GST_LIBS) \ $(NULL) if USE_DRM -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm-$(GST_API_VERSION).la +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm.la TEST_CFLAGS += $(LIBVA_DRM_CFLAGS) TEST_LIBS += $(LIBVA_DRM_LIBS) endif if USE_X11 -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_API_VERSION).la +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11.la TEST_CFLAGS += $(X11_CFLAGS) TEST_LIBS += \ $(LIBVA_X11_LIBS) \ @@ -51,7 +51,7 @@ TEST_LIBS += \ endif if USE_GLX -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx.la TEST_CFLAGS += $(X11_CFLAGS) $(GL_CFLAGS) TEST_LIBS += \ $(LIBVA_GLX_LIBS) \ @@ -61,7 +61,7 @@ TEST_LIBS += \ endif if USE_EGL -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl-$(GST_API_VERSION).la +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl.la TEST_CFLAGS += $(EGL_CFLAGS) TEST_LIBS += \ $(LIBVA_EGL_LIBS) \ @@ -70,7 +70,7 @@ TEST_LIBS += \ endif if USE_WAYLAND -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-$(GST_API_VERSION).la +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland.la TEST_CFLAGS += $(WAYLAND_CFLAGS) TEST_LIBS += \ $(LIBVA_WAYLAND_LIBS) \ From 28caa2016710baf803b16877f247b50cf2cbebee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 Jan 2016 19:23:43 +0100 Subject: [PATCH 2232/3781] Remove video parser crufts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We forgot to remove gstvaapiparse.c when we removed all the videoparser machinery. Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapiparse.c | 54 --------------------------------------- 1 file changed, 54 deletions(-) delete mode 100644 gst/vaapi/gstvaapiparse.c diff --git a/gst/vaapi/gstvaapiparse.c b/gst/vaapi/gstvaapiparse.c deleted file mode 100644 index 06ac69c4bc..0000000000 --- a/gst/vaapi/gstvaapiparse.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * gstvaapiparse.c - Recent enough GStreamer video parsers - * - * Copyright (C) 2011 Mark Nauwelaerts - * Copyright (C) 2009 Tim-Philipp Müller - * - * 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 "gstcompat.h" -#include -#include "gstvaapiparse.h" -#include "gsth264parse.h" - -#if GST_CHECK_VERSION(1,4,0) -#include "gsth265parse.h" -#endif - -#define PLUGIN_NAME "vaapiparse" -#define PLUGIN_DESC "VA-API based elements" -#define PLUGIN_LICENSE "LGPL" - -static gboolean -plugin_init (GstPlugin * plugin) -{ - gboolean failure = FALSE; - - failure |= !gst_element_register (plugin, "vaapiparse_h264", - GST_RANK_PRIMARY + 2, GST_TYPE_H264_PARSE); - -#if GST_CHECK_VERSION(1,4,0) - failure |= !gst_element_register (plugin, "vaapiparse_h265", - GST_RANK_PRIMARY + 2, GST_TYPE_H265_PARSE); -#endif - - return !failure; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, - vaapiparse, PLUGIN_DESC, plugin_init, - PACKAGE_VERSION, PLUGIN_LICENSE, PACKAGE, PACKAGE_BUGREPORT) From 1c722efe54b89a0c31840108ace71661aaca969f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 Jan 2016 19:27:13 +0100 Subject: [PATCH 2233/3781] Remove old gst version guards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As gstreamer-vaapi now only supports from GStreamer 1.6, this patch removes all the old GStreamer version guards. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 - gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 3 -- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 - gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 - gst-libs/gst/vaapi/gstvaapiprofile.c | 12 ----- gst/vaapi/gstcompat.h | 23 --------- gst/vaapi/gstvaapi.c | 2 - gst/vaapi/gstvaapidecode.c | 59 ----------------------- gst/vaapi/gstvaapiencode.c | 32 ------------ gst/vaapi/gstvaapipluginbase.c | 9 +--- gst/vaapi/gstvaapipluginbase.h | 5 -- gst/vaapi/gstvaapipluginutil.c | 6 --- gst/vaapi/gstvaapisink.c | 2 - 13 files changed, 1 insertion(+), 158 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 72367d9f76..2c9ccbeeb2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -924,7 +924,6 @@ gst_vaapi_decoder_set_interlaced (GstVaapiDecoder * decoder, GST_VIDEO_INTERLACE_MODE_PROGRESSIVE)); } -#if GST_CHECK_VERSION(1,5,0) void gst_vaapi_decoder_set_multiview_mode (GstVaapiDecoder * decoder, gint views, GstVideoMultiviewMode mv_mode, GstVideoMultiviewFlags mv_flags) @@ -951,7 +950,6 @@ gst_vaapi_decoder_set_multiview_mode (GstVaapiDecoder * decoder, notify_codec_state_changed (decoder); } } -#endif gboolean gst_vaapi_decoder_ensure_context (GstVaapiDecoder * decoder, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 55cb3962bc..bd8f32a107 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1448,8 +1448,6 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) priv->profile = profile; } -#if GST_CHECK_VERSION(1,5,0) - /* Multiview flags only available in >= 1.5 */ if (reset_context) { switch (num_views) { case 1: @@ -1476,7 +1474,6 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) break; } } -#endif chroma_type = gst_vaapi_utils_h264_get_chroma_type(sps->chroma_format_idc); if (!chroma_type) { diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 3b7aa0e8ee..3473315f56 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -263,12 +263,10 @@ void gst_vaapi_decoder_set_interlaced (GstVaapiDecoder * decoder, gboolean interlaced); -#if GST_CHECK_VERSION(1,5,0) G_GNUC_INTERNAL void gst_vaapi_decoder_set_multiview_mode (GstVaapiDecoder * decoder, gint views, GstVideoMultiviewMode mv_mode, GstVideoMultiviewFlags mv_flags); -#endif G_GNUC_INTERNAL gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index c3a7c5fe98..758af7f2fe 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2793,12 +2793,10 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) encoder->config_changed = TRUE; } -#if GST_CHECK_VERSION(1,5,0) /* Take number of MVC views from input caps if provided */ if (GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME || GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME) encoder->num_views = GST_VIDEO_INFO_VIEWS (vip); -#endif encoder->is_mvc = encoder->num_views > 1; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 2377b86999..5ebbb8a6ef 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -122,7 +122,6 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h264", "stereo-high" }, #endif -#if GST_CHECK_VERSION(1,5,0) { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, "video/x-wmv, wmvversion=3", "simple" }, @@ -132,17 +131,6 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, "video/x-wmv, wmvversion=3, format=(string)WVC1", "advanced" }, -#else - { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, - "video/x-wmv, wmvversion=3", NULL - }, - { GST_VAAPI_PROFILE_VC1_MAIN, VAProfileVC1Main, - "video/x-wmv, wmvversion=3", NULL - }, - { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, - "video/x-wmv, wmvversion=3, format=(string)WVC1", NULL - }, -#endif #if VA_CHECK_VERSION(0,32,0) { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline, "image/jpeg", NULL diff --git a/gst/vaapi/gstcompat.h b/gst/vaapi/gstcompat.h index 17bd3e6e08..c953783fd1 100644 --- a/gst/vaapi/gstcompat.h +++ b/gst/vaapi/gstcompat.h @@ -25,27 +25,4 @@ #include "gst/vaapi/sysdeps.h" -#if !GST_CHECK_VERSION (1,5,0) -static inline GstBuffer * -gst_buffer_copy_deep (const GstBuffer * buffer) -{ - GstBuffer *copy; - - g_return_val_if_fail (buffer != NULL, NULL); - - copy = gst_buffer_new (); - - if (!gst_buffer_copy_into (copy, (GstBuffer *) buffer, - GST_BUFFER_COPY_ALL | GST_BUFFER_COPY_DEEP, 0, -1)) - gst_buffer_replace (©, NULL); - -#if GST_CHECK_VERSION (1,4,0) - if (copy) - GST_BUFFER_FLAG_UNSET (copy, GST_BUFFER_FLAG_TAG_MEMORY); -#endif - - return copy; -} -#endif - #endif /* GST_COMPAT_H */ diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 3ad0ec0f05..a64cb64573 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -79,10 +79,8 @@ plugin_init (GstPlugin * plugin) GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_H265); #endif -#if GST_CHECK_VERSION(1,4,0) gst_element_register (plugin, "vaapidecodebin", GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); -#endif return TRUE; } diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 60ce329716..45003e8e42 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -222,12 +222,10 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); break; #endif -#if GST_CHECK_VERSION(1,3,1) case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE: features = gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL); break; -#endif default: break; } @@ -313,13 +311,10 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, } GST_BUFFER_FLAG_SET (out_frame->output_buffer, out_flags); -#if GST_CHECK_VERSION(1,5,0) - /* First-in-bundle flag only appeared in 1.5 dev */ if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_FFB) { GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_VIDEO_BUFFER_FLAG_FIRST_IN_BUNDLE); } -#endif crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy); if (crop_rect) { @@ -523,7 +518,6 @@ not_negotiated: } } -#if GST_CHECK_VERSION(1,5,0) static GstFlowReturn gst_vaapidecode_drain (GstVideoDecoder * vdec) { @@ -534,7 +528,6 @@ gst_vaapidecode_drain (GstVideoDecoder * vdec) return gst_vaapidecode_push_all_decoded_frames (decode); } -#endif static gboolean gst_vaapidecode_internal_flush (GstVideoDecoder * vdec) @@ -923,15 +916,11 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->parse = GST_DEBUG_FUNCPTR (gst_vaapidecode_parse); vdec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapidecode_handle_frame); vdec_class->finish = GST_DEBUG_FUNCPTR (gst_vaapidecode_finish); -#if GST_CHECK_VERSION(1,5,0) vdec_class->drain = GST_DEBUG_FUNCPTR (gst_vaapidecode_drain); -#endif vdec_class->decide_allocation = GST_DEBUG_FUNCPTR (gst_vaapidecode_decide_allocation); -#if GST_CHECK_VERSION(1,4,0) vdec_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_src_query); vdec_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_query); -#endif gst_element_class_set_static_metadata (element_class, "VA-API decoder", @@ -1031,28 +1020,6 @@ bail: return gst_caps_ref (decode->allowed_caps); } -#if !GST_CHECK_VERSION(1,4,0) -static gboolean -gst_vaapidecode_query (GstPad * pad, GstObject * parent, GstQuery * query) -{ - GstVaapiDecode *const decode = - GST_VAAPIDECODE (gst_pad_get_parent_element (pad)); - GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); - gboolean res; - - GST_INFO_OBJECT (decode, "query type %s on %s pad", - GST_QUERY_TYPE_NAME (query), GST_PAD_IS_SINK (pad) ? "sink" : "src"); - - if (GST_PAD_IS_SINK (pad)) - res = gst_vaapidecode_sink_query (vdec, query); - else - res = gst_vaapidecode_src_query (vdec, query); - - gst_object_unref (vdec); - return res; -} -#endif - static gboolean gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query) { @@ -1083,16 +1050,8 @@ gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query) break; } default:{ -#if GST_CHECK_VERSION(1,4,0) ret = GST_VIDEO_DECODER_CLASS (gst_vaapidecode_parent_class)->sink_query (vdec, query); -#else - GstPad *pad = GST_VIDEO_DECODER_SINK_PAD (vdec); - GstObject *parent = gst_pad_get_parent (pad); - ret = plugin->sinkpad_query (pad, parent, query); - if (parent) - gst_object_unref (parent); -#endif break; } } @@ -1130,16 +1089,8 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) break; } default:{ -#if GST_CHECK_VERSION(1,4,0) ret = GST_VIDEO_DECODER_CLASS (gst_vaapidecode_parent_class)->src_query (vdec, query); -#else - GstPad *pad = GST_VIDEO_DECODER_SRC_PAD (vdec); - GstObject *parent = gst_pad_get_parent (pad); - ret = plugin->srcpad_query (pad, parent, query); - if (parent) - gst_object_unref (parent); -#endif break; } } @@ -1162,14 +1113,4 @@ gst_vaapidecode_init (GstVaapiDecode * decode) g_cond_init (&decode->surface_ready); gst_video_decoder_set_packetized (vdec, FALSE); - -#if !GST_CHECK_VERSION(1,4,0) - /* Pad through which data comes in to the element */ - GstPad *pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD (decode); - gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_vaapidecode_query)); - - /* Pad through which data goes out of the element */ - pad = GST_VAAPI_PLUGIN_BASE_SRC_PAD (decode); - gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_vaapidecode_query)); -#endif } diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index a9b8b3d633..a9a477053f 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -57,7 +57,6 @@ ensure_display (GstVaapiEncode * encode) return gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (encode)); } -#if GST_CHECK_VERSION(1,4,0) static gboolean gst_vaapiencode_sink_query (GstVideoEncoder * encoder, GstQuery * query) { @@ -95,27 +94,6 @@ gst_vaapiencode_src_query (GstVideoEncoder * encoder, GstQuery * query) return ret; } -#else -static gboolean -gst_vaapiencode_query (GstPad * pad, GstObject * parent, GstQuery * query) -{ - GstVaapiPluginBase *const plugin = - GST_VAAPI_PLUGIN_BASE (gst_pad_get_parent_element (pad)); - gboolean success; - - GST_INFO_OBJECT (plugin, "query type %s", GST_QUERY_TYPE_NAME (query)); - - if (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT) - success = gst_vaapi_handle_context_query (query, plugin->display); - else if (GST_PAD_IS_SINK (pad)) - success = plugin->sinkpad_query (plugin->sinkpad, parent, query); - else - success = plugin->srcpad_query (plugin->srcpad, parent, query); - - gst_object_unref (plugin); - return success; -} -#endif typedef struct { @@ -649,11 +627,6 @@ gst_vaapiencode_init (GstVaapiEncode * encode) GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (encode); gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (encode), GST_CAT_DEFAULT); - -#if !GST_CHECK_VERSION(1,4,0) - gst_pad_set_query_function (plugin->sinkpad, gst_vaapiencode_query); - gst_pad_set_query_function (plugin->srcpad, gst_vaapiencode_query); -#endif gst_pad_use_fixed_caps (plugin->srcpad); } @@ -687,13 +660,8 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) klass->set_property = gst_vaapiencode_default_set_property; klass->alloc_buffer = gst_vaapiencode_default_alloc_buffer; -#if GST_CHECK_VERSION(1,4,0) venc_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapiencode_src_query); venc_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapiencode_sink_query); -#else - /* Registering debug symbols for function pointers */ - GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_query); -#endif } static inline GPtrArray * diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 41ffa77504..45c32b593e 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -200,17 +200,10 @@ gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin, /* sink pad */ plugin->sinkpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "sink"); gst_video_info_init (&plugin->sinkpad_info); -#if !GST_CHECK_VERSION(1,4,0) - plugin->sinkpad_query = GST_PAD_QUERYFUNC (plugin->sinkpad); -#endif /* src pad */ - if (!(GST_OBJECT_FLAGS (plugin) & GST_ELEMENT_FLAG_SINK)) { + if (!(GST_OBJECT_FLAGS (plugin) & GST_ELEMENT_FLAG_SINK)) plugin->srcpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "src"); -#if !GST_CHECK_VERSION(1,4,0) - plugin->srcpad_query = GST_PAD_QUERYFUNC (plugin->srcpad); -#endif - } gst_video_info_init (&plugin->srcpad_info); } diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 40f2d123e9..24252e1166 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -130,11 +130,6 @@ struct _GstVaapiPluginBase GstVideoInfo srcpad_info; GstBufferPool *srcpad_buffer_pool; -#if !GST_CHECK_VERSION(1,4,0) - GstPadQueryFunction srcpad_query; - GstPadQueryFunction sinkpad_query; -#endif - GstVaapiDisplay *display; GstVaapiDisplayType display_type; GstVaapiDisplayType display_type_req; diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 74f311b2ad..e07d2b61ca 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -482,11 +482,9 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, GstCapsFeatures *const features = gst_caps_get_features (out_caps, i); GstStructure *const structure = gst_caps_get_structure (out_caps, i); -#if GST_CHECK_VERSION(1,3,0) /* Skip ANY features, we need an exact match for correct evaluation */ if (gst_caps_features_is_any (features)) continue; -#endif caps = gst_caps_new_full (gst_structure_copy (structure), NULL); if (!caps) @@ -504,12 +502,10 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; gst_caps_replace (&caps, NULL); -#if GST_CHECK_VERSION(1,3,0) /* Stop at the first match, the caps should already be sorted out by preference order from downstream elements */ if (feature != GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) break; -#endif } if (out_format_ptr) { @@ -651,12 +647,10 @@ gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, vip->fps_n = vi.fps_n; vip->fps_d = vi.fps_d; -#if GST_CHECK_VERSION(1,5,0) GST_VIDEO_INFO_MULTIVIEW_MODE (vip) = GST_VIDEO_INFO_MULTIVIEW_MODE (&vi); GST_VIDEO_INFO_MULTIVIEW_FLAGS (vip) = GST_VIDEO_INFO_MULTIVIEW_FLAGS (&vi); -#endif } /** diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index f52c4da8ed..75c588bf4a 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -58,7 +58,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapisink); /* *INDENT-OFF* */ static const char gst_vaapisink_sink_caps_str[] = GST_VAAPI_MAKE_ENC_SURFACE_CAPS ";" -#if GST_CHECK_VERSION(1,3,1) GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, @@ -66,7 +65,6 @@ static const char gst_vaapisink_sink_caps_str[] = GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, GST_VIDEO_FORMATS_ALL) ";" -#endif GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL); /* *INDENT-ON* */ From 71f2f765f673cd5b791a9f30dd757fd32d6b0f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 25 Jan 2016 12:40:49 +0000 Subject: [PATCH 2234/3781] Remove debian.upstream packaging https://bugzilla.gnome.org/show_bug.cgi?id=759192 --- Makefile.am | 16 +------ configure.ac | 7 --- debian.upstream/Makefile.am | 30 ------------ debian.upstream/changelog.in | 5 -- debian.upstream/compat | 1 - debian.upstream/control.in | 47 ------------------- debian.upstream/copyright | 35 -------------- .../gstreamer-vaapi-doc.install.in | 1 - debian.upstream/gstreamer-vaapi.install.in | 1 - debian.upstream/rules | 18 ------- 10 files changed, 1 insertion(+), 160 deletions(-) delete mode 100644 debian.upstream/Makefile.am delete mode 100644 debian.upstream/changelog.in delete mode 100644 debian.upstream/compat delete mode 100644 debian.upstream/control.in delete mode 100644 debian.upstream/copyright delete mode 100644 debian.upstream/gstreamer-vaapi-doc.install.in delete mode 100644 debian.upstream/gstreamer-vaapi.install.in delete mode 100755 debian.upstream/rules diff --git a/Makefile.am b/Makefile.am index b10a0c7252..1f2bcdb440 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} AUTOMAKE_OPTIONS = foreign -SUBDIRS = debian.upstream gst-libs gst tests docs +SUBDIRS = gst-libs gst tests docs # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ @@ -12,18 +12,4 @@ MAINTAINERCLEANFILES = \ $(srcdir)/gtk-doc.make $(srcdir)/m4/gtk-doc.m4 \ $(NULL) -DEB_BUILDDIR = debian.build - -deb: - dpkg-buildpackage -rfakeroot -uc -us - -deb.upstream: dist-bzip2 - -mkdir -p $(DEB_BUILDDIR) - cd $(DEB_BUILDDIR) && \ - rm -rf $(PACKAGE)-$(VERSION) && \ - tar jxvf ../$(PACKAGE)-$(VERSION).tar.bz2 && \ - cd $(PACKAGE)-$(VERSION) && \ - $(LN_S) debian.upstream debian && \ - $(MAKE) deb -f Makefile.am - -include $(top_srcdir)/git.mk diff --git a/configure.ac b/configure.ac index 554ff34879..c16e534609 100644 --- a/configure.ac +++ b/configure.ac @@ -1067,13 +1067,6 @@ AC_SUBST(pkgconfigdir) AC_CONFIG_FILES([ Makefile - debian.upstream/Makefile - debian.upstream/changelog - debian.upstream/control - debian.upstream/gstreamer$GST_API_VERSION-vaapi-doc.install:\ -debian.upstream/gstreamer-vaapi-doc.install.in - debian.upstream/gstreamer$GST_API_VERSION-vaapi.install:\ -debian.upstream/gstreamer-vaapi.install.in docs/Makefile docs/reference/Makefile docs/reference/libs/Makefile diff --git a/debian.upstream/Makefile.am b/debian.upstream/Makefile.am deleted file mode 100644 index ea97d15887..0000000000 --- a/debian.upstream/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -DOCS = \ - AUTHORS \ - COPYING.LIB \ - NEWS \ - README \ - $(NULL) - -DEBIANFILES = \ - changelog.in \ - compat \ - control.in \ - copyright \ - gstreamer-vaapi-doc.install.in \ - gstreamer-vaapi.install.in \ - rules \ - $(NULL) - -DEBIANGENFILES = \ - changelog \ - control \ - gstreamer$(GST_API_VERSION)-vaapi-doc.install \ - gstreamer$(GST_API_VERSION)-vaapi.install \ - $(NULL) - -EXTRA_DIST = $(DEBIANFILES) - -dist_noinst_DATA = $(DEBIANGENFILES) -DISTCLEANFILES = $(DEBIANGENFILES) - --include $(top_srcdir)/git.mk diff --git a/debian.upstream/changelog.in b/debian.upstream/changelog.in deleted file mode 100644 index e84ef3e430..0000000000 --- a/debian.upstream/changelog.in +++ /dev/null @@ -1,5 +0,0 @@ -gstreamer@GST_API_VERSION@-vaapi (@PACKAGE_VERSION@-1) unstable; urgency=low - - * Autogenerated package, see NEWS file for ChangeLog. - - -- Gwenole Beauchesne @TODAY@ diff --git a/debian.upstream/compat b/debian.upstream/compat deleted file mode 100644 index 7ed6ff82de..0000000000 --- a/debian.upstream/compat +++ /dev/null @@ -1 +0,0 @@ -5 diff --git a/debian.upstream/control.in b/debian.upstream/control.in deleted file mode 100644 index a66e6c8447..0000000000 --- a/debian.upstream/control.in +++ /dev/null @@ -1,47 +0,0 @@ -Source: gstreamer@GST_API_VERSION@-vaapi -Section: libs -Priority: optional -Maintainer: Gwenole Beauchesne -Build-Depends: debhelper (>= 5), - cdbs, - libglib2.0-dev (>= @GLIB_VERSION_REQUIRED@), - libgstreamer@GST_PKG_VERSION@-dev (>= @GST_VERSION_REQUIRED@), - libgstreamer-plugins-base@GST_PKG_VERSION@-dev (>= @GST_PLUGINS_BASE_VERSION_REQUIRED@), - libgstreamer-plugins-bad@GST_PKG_VERSION@-dev (>= @GST_PLUGINS_BAD_VERSION_REQUIRED@), -@USE_DRM_TRUE@ libdrm-dev, libudev-dev, -@USE_X11_TRUE@ libx11-dev, libxrandr-dev, -@USE_GLX_TRUE@ libgl-dev, -@USE_WAYLAND_TRUE@ libwayland-dev (>= @WAYLAND_API_VERSION@), - libva-dev (>= @LIBVA_PACKAGE_VERSION@), - yasm -Build-Depends-Indep: gtk-doc-tools (>= @GTKDOC_VERSION@) -Standards-Version: 3.7.2 - -Package: gstreamer@GST_API_VERSION@-vaapi -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Suggests: gstreamer@GST_API_VERSION@-vaapi-doc -Description: VA-API plugins for GStreamer - This package contains GStreamer plugins for VA-API support: - - `vaapidecode': decode bitstreams using VA-API -@USE_ENCODERS_TRUE@ - `vaapiencode_mpeg2': encode bitstreams using VA-API (MPEG-2 codec) -@USE_ENCODERS_TRUE@ - `vaapiencode_h264': encode bitstreams using VA-API (H.264 codec) - - `vaapipostproc': postprocess VA surfaces, e.g. for deinterlacing - - `vaapisink': a VA-API based video sink - -Package: gstreamer@GST_API_VERSION@-vaapi-doc -Architecture: all -Section: doc -Recommends: libgstvaapi@GST_API_VERSION@-dev (= ${source:Version}) -Description: GStreamer VA-API documentation and manuals - This packages contains documentation for libraries and elements. - -Package: gstreamer@GST_API_VERSION@-vaapi-dbg -Section: libdevel -Architecture: any -Depends: gstreamer@GST_API_VERSION@-vaapi (= ${Source-Version}) -Description: VA-API plugins for GStreamer - VA-API support plugins for GStreamer. - . - This package contains the debug files. diff --git a/debian.upstream/copyright b/debian.upstream/copyright deleted file mode 100644 index 4ebb78e8cc..0000000000 --- a/debian.upstream/copyright +++ /dev/null @@ -1,35 +0,0 @@ -This package is maintained by: -Gwenole Beauchesne - -Copyright: - - gstreamer-vaapi helper libraries - and plugins elements: LGPL (v2.1 or later) - -License: - - Copyright (C) 2010-2011, Splitted-Desktop Systems. - Copyright (C) 2011-2014, Intel Corporation. - Copyright (C) 2011, Collabora Ltd. - - gstreamer-vaapi helper libraries and plugins elements are available under - the terms of the GNU Lesser General Public License v2.1+. - - 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 - -On Debian GNU/Linux systems, the complete text of the GNU Lesser General -Public License can be found in `/usr/share/common-licenses/LGPL-2.1'. - diff --git a/debian.upstream/gstreamer-vaapi-doc.install.in b/debian.upstream/gstreamer-vaapi-doc.install.in deleted file mode 100644 index ff90f75b40..0000000000 --- a/debian.upstream/gstreamer-vaapi-doc.install.in +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/share/doc/gstreamer@GST_API_VERSION@-vaapi diff --git a/debian.upstream/gstreamer-vaapi.install.in b/debian.upstream/gstreamer-vaapi.install.in deleted file mode 100644 index 2417257f05..0000000000 --- a/debian.upstream/gstreamer-vaapi.install.in +++ /dev/null @@ -1 +0,0 @@ -debian/tmp@plugindir@/libgstvaapi*.so diff --git a/debian.upstream/rules b/debian.upstream/rules deleted file mode 100755 index fe7eae2c7c..0000000000 --- a/debian.upstream/rules +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/make -f - -include /usr/share/cdbs/1/rules/debhelper.mk -include /usr/share/cdbs/1/class/autotools.mk -include /usr/share/cdbs/1/rules/simple-patchsys.mk -include /usr/share/cdbs/1/rules/utils.mk - -# Allow HTML documentation build -indep_conf_flags = \ - --with-html-dir=\$${prefix}/share/doc/$(DEB_SOURCE_PACKAGE) - -# only build the docs if gtk-doc-tools is installed, i.e. binary-indep is -# called -ifeq ($(shell test "`dpkg -l gtk-doc-tools | grep ^ii`" && echo binary-indep),binary-indep) -indep_conf_flags += --enable-gtk-doc -endif - -DEB_CONFIGURE_EXTRA_FLAGS += $(indep_conf_flags) From c8d6febfab1ccfc46ec6cf70b9cb62761c9cf075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 25 Jan 2016 12:43:15 +0000 Subject: [PATCH 2235/3781] docs: remove library documentation which is non-public now https://bugzilla.gnome.org/show_bug.cgi?id=759192 --- configure.ac | 2 - docs/reference/Makefile.am | 2 +- docs/reference/libs/Makefile.am | 126 ------ docs/reference/libs/libs-docs.xml.in | 70 --- docs/reference/libs/libs-overrides.txt | 0 docs/reference/libs/libs-sections.txt | 579 ------------------------- 6 files changed, 1 insertion(+), 778 deletions(-) delete mode 100644 docs/reference/libs/Makefile.am delete mode 100644 docs/reference/libs/libs-docs.xml.in delete mode 100644 docs/reference/libs/libs-overrides.txt delete mode 100644 docs/reference/libs/libs-sections.txt diff --git a/configure.ac b/configure.ac index c16e534609..a698884d43 100644 --- a/configure.ac +++ b/configure.ac @@ -1069,8 +1069,6 @@ AC_CONFIG_FILES([ Makefile docs/Makefile docs/reference/Makefile - docs/reference/libs/Makefile - docs/reference/libs/libs-docs.xml docs/reference/plugins/Makefile docs/reference/plugins/plugins-docs.xml gst-libs/Makefile diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am index 28657ac1f7..41143a195b 100644 --- a/docs/reference/Makefile.am +++ b/docs/reference/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = libs plugins +SUBDIRS = plugins -include $(top_srcdir)/git.mk diff --git a/docs/reference/libs/Makefile.am b/docs/reference/libs/Makefile.am deleted file mode 100644 index 6298a5c11c..0000000000 --- a/docs/reference/libs/Makefile.am +++ /dev/null @@ -1,126 +0,0 @@ -## Process this file with automake to produce Makefile.in - -# We require automake 1.6 at least. -AUTOMAKE_OPTIONS = 1.6 - -# This is a blank Makefile.am for using gtk-doc. -# Copy this to your project's API docs directory and modify the variables to -# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples -# of using the various options. - -# The name of the module, e.g. 'glib'. -DOC_MODULE = libs - -# The top-level SGML file. You can change this if you want to. -DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml - -# The directory containing the source code. Relative to $(srcdir). -# gtk-doc will search all .c & .h files beneath here for inline comments -# documenting the functions and macros. -# e.g. DOC_SOURCE_DIR=../../../gtk -DOC_SOURCE_DIR = $(top_srcdir)/gst-libs/gst/vaapi - -# Extra options to pass to gtkdoc-scangobj. Not normally needed. -SCANGOBJ_OPTIONS = --type-init-func="g_type_init()" - -# List files used by scanobj -SCANOBJ_TYPES = - -# Extra options to supply to gtkdoc-scan. -# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" -SCAN_OPTIONS = --deprecated-guards="GST_VAAPI_DISABLE_DEPRECATED" - -# Extra options to supply to gtkdoc-mkdb. -# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml -MKDB_OPTIONS = --sgml-mode --output-format=xml --name-space=$(DOC_MODULE) - -# Extra options to supply to gtkdoc-mktmpl -# e.g. MKTMPL_OPTIONS=--only-section-tmpl -MKTMPL_OPTIONS = - -# Extra options to supply to gtkdoc-fixref. Not normally needed. -# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html -FIXXREF_OPTIONS = \ - --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib \ - --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/gobject \ - --extra-dir=$(CAIRO_PREFIX)/share/gtk-doc/html/cairo \ - --extra-dir=$(PANGO_PREFIX)/share/gtk-doc/html/pango - -# Used for dependencies. The docs will be rebuilt if any of these change. -# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h -# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.h -CFILE_GLOB = $(top_srcdir)/gst-libs/gst/vaapi/*.c - -# Header files to ignore when scanning. -# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h -IGNORE_HFILES = \ - gstvaapi_priv.h \ - gstvaapicompat.h \ - gstvaapidebug.h \ - gstvaapidecoder_priv.h \ - gstvaapidisplay_priv.h \ - gstvaapidisplay_glx_priv.h \ - gstvaapidisplay_x11_priv.h \ - gstvaapiobject_priv.h \ - gstvaapiutils.h \ - gstvaapiutils_glx.h \ - gstvaapiutils_gst.h \ - gstvaapiutils_x11.h \ - $(NULL) - -EXTRA_HFILES = \ - $(NULL) - -# Images to copy into HTML directory. -# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png -HTML_IMAGES = \ - $(NULL) - -# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). -# e.g. content_files=running.sgml building.sgml changes-2.0.sgml -content_files = \ - $(NULL) - -# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded -# These files must be listed here *and* in content_files -# e.g. expand_content_files=running.sgml -expand_content_files = \ - $(NULL) - -# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. -# Only needed if you are using gtkdoc-scangobj to dynamically query widget -# signals and properties. -# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) -# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) - -INCLUDES = \ - $(GLIB_CFLAGS) \ - $(GST_CFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/gst-libs \ - -I$(top_srcdir)/gst-libs/gst/vaapi - -GTKDOC_LIBS = \ - $(GLIB_LIBS) \ - $(GST_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la - -GTKDOC_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11.la - -if USE_GLX -GTKDOC_LIBS += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx.la -endif - -# This includes the standard gtk-doc make rules, copied by gtkdocize. -include $(top_srcdir)/gtk-doc.make - -# Other files to distribute -# e.g. EXTRA_DIST += version.xml.in -EXTRA_DIST += \ - libs-docs.xml.in \ - $(NULL) - --include $(top_srcdir)/git.mk diff --git a/docs/reference/libs/libs-docs.xml.in b/docs/reference/libs/libs-docs.xml.in deleted file mode 100644 index 84228ff935..0000000000 --- a/docs/reference/libs/libs-docs.xml.in +++ /dev/null @@ -1,70 +0,0 @@ - - - - - GStreamer VA-API Plugins @GST_API_VERSION@ Library Reference Manual - - - - To ease the creation of plugins, a Gstreamer-oriented library was created, - which wraps VA-API. - - - - gst-plugins-vaapi Library - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Object Hierarchy - - - - - API Index - - - - - diff --git a/docs/reference/libs/libs-overrides.txt b/docs/reference/libs/libs-overrides.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt deleted file mode 100644 index 4cdc2f8d4c..0000000000 --- a/docs/reference/libs/libs-sections.txt +++ /dev/null @@ -1,579 +0,0 @@ -
-videoformat -GstVideoFormat -gst_vaapi_video_format_to_string -gst_vaapi_video_format_from_va_fourcc -gst_vaapi_video_format_from_va_format -gst_vaapi_video_format_get_chroma_type -gst_vaapi_video_format_get_score -gst_vaapi_video_format_is_rgb -gst_vaapi_video_format_is_yuv -gst_vaapi_video_format_to_va_format -
- -
-gstvaapisurfacepool -GstVaapiSurfacePool -GstVaapiSurfacePool -gst_vaapi_surface_pool_new - -GST_VAAPI_SURFACE_POOL -
- -
-gstvaapivideopool -GstVaapiVideoPool -GstVaapiVideoPool -gst_vaapi_video_pool_get_display -gst_vaapi_video_pool_get_object_type -gst_vaapi_video_pool_get_object -gst_vaapi_video_pool_put_object -gst_vaapi_video_pool_add_object -gst_vaapi_video_pool_add_objects -gst_vaapi_video_pool_get_capacity -gst_vaapi_video_pool_set_capacity -gst_vaapi_video_pool_get_size -gst_vaapi_video_pool_reserve - -GST_VAAPI_VIDEO_POOL -
- -
-gstvaapidisplay_x11 -GstVaapiDisplayX11 -GstVaapiDisplayX11 -gst_vaapi_display_x11_new -gst_vaapi_display_x11_new_with_display -gst_vaapi_display_x11_get_display -gst_vaapi_display_x11_get_screen - -GST_VAAPI_DISPLAY_X11 -
- -
-gstvaapidisplay_drm -GstVaapiDisplayDRM -gst_vaapi_display_drm_new -gst_vaapi_display_drm_new_with_device -gst_vaapi_display_drm_get_device -gst_vaapi_display_drm_get_device_path -
- -
-gstvaapidisplay_wayland -GstVaapiDisplayWayland -gst_vaapi_display_wayland_new -gst_vaapi_display_wayland_new_with_display -gst_vaapi_display_wayland_get_display -
- -
-gstvaapidisplay_egl -GstVaapiDisplayEGL -GstVaapiDisplayEGL -gst_vaapi_display_egl_new -gst_vaapi_display_egl_new_with_native_display -gst_vaapi_display_egl_get_gl_display -gst_vaapi_display_egl_set_gl_context -gst_vaapi_display_egl_get_gl_context - -GST_VAAPI_DISPLAY_EGL -
- -
-gstvaapiwindow_x11 -GstVaapiWindowX11 -GstVaapiWindowX11 -GST_VAAPI_WINDOW_XWINDOW -gst_vaapi_window_x11_new -gst_vaapi_window_x11_new_with_xid -gst_vaapi_window_x11_get_xid -gst_vaapi_window_x11_is_foreign_xid - -GST_VAAPI_WINDOW_X11 -
- -
-gstvaapiwindow_wayland -GstVaapiWindowWayland -gst_vaapi_window_wayland_new -
- -
-gstvaapiwindow_drm -GstVaapiWindowDRM -gst_vaapi_window_drm_new -
- -
-gstvaapiwindow_glx -GstVaapiWindowGLX -gst_vaapi_window_glx_new -gst_vaapi_window_glx_new_with_xid -gst_vaapi_window_glx_get_context -gst_vaapi_window_glx_set_context -gst_vaapi_window_glx_make_current -gst_vaapi_window_glx_swap_buffers -gst_vaapi_window_glx_put_texture -
- -
-gstvaapiwindow_egl -GstVaapiWindowEGL -gst_vaapi_window_egl_new -
- -
-gstvaapipixmap_x11 -GstVaapiPixmapX11 -GstVaapiPixmapX11 -GST_VAAPI_PIXMAP_XPIXMAP -gst_vaapi_pixmap_x11_new -gst_vaapi_pixmap_x11_new_with_xid -gst_vaapi_pixmap_x11_get_xid -gst_vaapi_pixmap_x11_is_foreign_xid - -GST_VAAPI_WINDOW_X11 -
- -
-gstvaapidisplay_glx -GstVaapiDisplayGLX -GstVaapiDisplayGLX -gst_vaapi_display_glx_new -gst_vaapi_display_glx_new_with_display - -GST_VAAPI_DISPLAY_GLX -
- -
-gstvaapiwindow_glx -GstVaapiWindowGLX -GstVaapiWindowGLX -gst_vaapi_window_glx_new -gst_vaapi_window_glx_new_with_xid -gst_vaapi_window_glx_get_context -gst_vaapi_window_glx_set_context -gst_vaapi_window_glx_make_current -gst_vaapi_window_glx_swap_buffers -gst_vaapi_window_glx_put_texture - -GST_VAAPI_WINDOW_GLX -
- -
-gstvaapidisplay -GstVaapiDisplay -GstVaapiDisplayType -GstVaapiDisplay -GstVaapiDisplayInfo -gst_vaapi_display_new_with_display -gst_vaapi_display_ref -gst_vaapi_display_unref -gst_vaapi_display_replace -gst_vaapi_display_lock -gst_vaapi_display_unlock -gst_vaapi_display_sync -gst_vaapi_display_flush -gst_vaapi_display_get_class_type -gst_vaapi_display_get_display_type -gst_vaapi_display_get_display_name -gst_vaapi_display_get_display -gst_vaapi_display_get_width -gst_vaapi_display_get_height -gst_vaapi_display_get_size -gst_vaapi_display_get_pixel_aspect_ratio -gst_vaapi_display_has_video_processing -gst_vaapi_display_get_decode_profiles -gst_vaapi_display_has_decoder -gst_vaapi_display_get_encode_profiles -gst_vaapi_display_has_encoder -gst_vaapi_display_get_image_formats -gst_vaapi_display_has_image_format -gst_vaapi_display_get_subpicture_formats -gst_vaapi_display_has_subpicture_format -gst_vaapi_display_has_property -gst_vaapi_display_get_property -gst_vaapi_display_set_property -gst_vaapi_display_get_render_mode -gst_vaapi_display_set_render_mode -gst_vaapi_display_get_rotation -gst_vaapi_display_set_rotation -gst_vaapi_display_get_vendor_string -gst_vaapi_display_has_opengl - -GST_VAAPI_DISPLAY -GST_VAAPI_DISPLAY_GET_CLASS_TYPE -GST_VAAPI_DISPLAY_VADISPLAY_TYPE -GST_VAAPI_DISPLAY_VADISPLAY -GST_VAAPI_DISPLAY_LOCK -GST_VAAPI_DISPLAY_UNLOCK -GST_VAAPI_DISPLAY_PROP_RENDER_MODE -GST_VAAPI_DISPLAY_PROP_ROTATION -GST_VAAPI_DISPLAY_PROP_HUE -GST_VAAPI_DISPLAY_PROP_SATURATION -GST_VAAPI_DISPLAY_PROP_BRIGHTNESS -GST_VAAPI_DISPLAY_PROP_CONTRAST -
- -
-gstvaapiimagepool -GstVaapiImagePool -GstVaapiImagePool -gst_vaapi_image_pool_new - -GST_VAAPI_IMAGE_POOL -
- -
-gstvaapitypes -Basic data structures -GstVaapiID -GST_VAAPI_ID_FORMAT -GST_VAAPI_ID_ARGS -GstVaapiPoint -GstVaapiRectangle -
- -
-gstvaapipixmap -GstVaapiPixmap -GstVaapiPixmap -gst_vaapi_pixmap_ref -gst_vaapi_pixmap_unref -gst_vaapi_pixmap_replace -gst_vaapi_pixmap_get_format -gst_vaapi_pixmap_get_width -gst_vaapi_pixmap_get_height -gst_vaapi_pixmap_get_size -gst_vaapi_pixmap_put_surface - -GST_VAAPI_PIXMAP -
- -
-gstvaapiwindow -GstVaapiWindow -GstVaapiWindow -gst_vaapi_window_get_display -gst_vaapi_window_show -gst_vaapi_window_hide -gst_vaapi_window_get_fullscreen -gst_vaapi_window_set_fullscreen -gst_vaapi_window_get_width -gst_vaapi_window_get_height -gst_vaapi_window_get_size -gst_vaapi_window_set_width -gst_vaapi_window_set_height -gst_vaapi_window_set_size -gst_vaapi_window_put_pixmap -gst_vaapi_window_put_surface - -GST_VAAPI_WINDOW -
- -
-gstvaapiobject -GstVaapiObject -GstVaapiObject -gst_vaapi_object_get_display -gst_vaapi_object_lock_display -gst_vaapi_object_unlock_display -gst_vaapi_object_get_id - -GST_VAAPI_OBJECT -
- -
-gstvaapiimage -GST_VAAPI_IMAGE_FORMAT -GST_VAAPI_IMAGE_WIDTH -GST_VAAPI_IMAGE_HEIGHT -GstVaapiImage -GstVaapiImage -gst_vaapi_image_new -gst_vaapi_image_new_with_image -gst_vaapi_image_get_id -gst_vaapi_image_get_image -gst_vaapi_image_get_format -gst_vaapi_image_get_width -gst_vaapi_image_get_height -gst_vaapi_image_get_size -gst_vaapi_image_is_linear -gst_vaapi_image_is_mapped -gst_vaapi_image_map -gst_vaapi_image_unmap -gst_vaapi_image_get_plane_count -gst_vaapi_image_get_plane -gst_vaapi_image_get_pitch -gst_vaapi_image_get_data_size -gst_vaapi_image_get_buffer -gst_vaapi_image_update_from_buffer -gst_vaapi_image_copy - -GST_VAAPI_IMAGE -
- -
-gstvaapisurface -GstVaapiChromaType -GstVaapiSurfaceStatus -GstVaapiSurfaceRenderFlags -GstVaapiSurface -GstVaapiSurface -gst_vaapi_surface_new -gst_vaapi_surface_new_with_format -gst_vaapi_surface_get_id -gst_vaapi_surface_get_chroma_type -gst_vaapi_surface_get_format -gst_vaapi_surface_get_width -gst_vaapi_surface_get_height -gst_vaapi_surface_get_size -gst_vaapi_surface_derive_image -gst_vaapi_surface_get_image -gst_vaapi_surface_put_image -gst_vaapi_surface_associate_subpicture -gst_vaapi_surface_deassociate_subpicture -gst_vaapi_surface_sync -gst_vaapi_surface_query_status - -GST_VAAPI_SURFACE -
- -
-gstvaapisubpicture -GstVaapiSubpicture -GstVaapiSubpicture -gst_vaapi_subpicture_new -gst_vaapi_subpicture_new_from_overlay_rectangle -gst_vaapi_subpicture_get_id -gst_vaapi_subpicture_get_flags -gst_vaapi_subpicture_get_global_alpha -gst_vaapi_subpicture_set_global_alpha -gst_vaapi_subpicture_get_image -gst_vaapi_subpicture_set_image - -GST_VAAPI_SUBPICTURE -
- -
-gstvaapiprofile -GstVaapiProfile -GstVaapiCodec -GstVaapiProfile -GstVaapiEntrypoint -gst_vaapi_profile -gst_vaapi_profile_from_caps -gst_vaapi_profile_get_va_profile -gst_vaapi_profile_get_caps -gst_vaapi_profile_get_codec -gst_vaapi_entrypoint -gst_vaapi_entrypoint_get_va_entrypoint -
- -
-gstvaapitexture -GstVaapiTexture -GstVaapiTexture -gst_vaapi_texture_new -gst_vaapi_texture_new_wrapped -gst_vaapi_texture_ref -gst_vaapi_texture_unref -gst_vaapi_texture_replace -gst_vaapi_texture_get_id -gst_vaapi_texture_get_target -gst_vaapi_texture_get_format -gst_vaapi_texture_get_width -gst_vaapi_texture_get_height -gst_vaapi_texture_get_size -gst_vaapi_texture_get_orientation_flags -gst_vaapi_texture_set_orientation_flags -gst_vaapi_texture_put_surface -
- -
-gstvaapitexture_egl -GstVaapiTextureEGL -gst_vaapi_texture_egl_new -gst_vaapi_texture_egl_new_wrapped -
- -
-gstvaapitexture_glx -GstVaapiTextureGLX -gst_vaapi_texture_glx_new -gst_vaapi_texture_glx_new_wrapped -
- -
-gstvaapidecoder -GstVaapiDecoderStatus -GstVaapiDecoder -GstVaapiDecoder -gst_vaapi_decoder_get_caps -gst_vaapi_decoder_get_codec -gst_vaapi_decoder_get_codec_state -gst_vaapi_decoder_put_buffer -gst_vaapi_decoder_get_surface -gst_vaapi_decoder_get_frame -gst_vaapi_decoder_get_frame_with_timeout -gst_vaapi_decoder_parse -gst_vaapi_decoder_decode - -GST_VAAPI_DECODER -
- -
-gstvaapidecoder_jpeg -GstVaapiDecoderJpeg -GstVaapiDecoderJpeg -gst_vaapi_decoder_jpeg_new -
- -
-gstvaapidecoder_mpeg2 -GstVaapiDecoderMpeg2 -GstVaapiDecoderMpeg2 -gst_vaapi_decoder_mpeg2_new -
- -
-gstvaapidecoder_mpeg4 -GstVaapiDecoderMpeg4 -GstVaapiDecoderMpeg4 -gst_vaapi_decoder_mpeg4_new -
- -
-gstvaapidecoder_h264 -GstVaapiDecoderH264 -GstVaapiDecoderH264 -gst_vaapi_decoder_h264_new -
- -
-gstvaapidecoder_vc1 -GstVaapiDecoderVC1 -GstVaapiDecoderVC1 -gst_vaapi_decoder_vc1_new -
- -
-gstvaapidecoder_vp8 -GstVaapiDecoderVp8 -GstVaapiDecoderVp8 -gst_vaapi_decoder_vp8_new -
- -
-gstvaapidecoder_h265 -GstVaapiDecoderH265 -GstVaapiDecoderH265 -GstVaapiStreamAlignH265 -gst_vaapi_decoder_h265_new -gst_vaapi_decoder_h265_set_alignment -
- -
-gstvaapisurfaceproxy -GstVaapiSurfaceProxy -gst_vaapi_surface_proxy_get_duration -gst_vaapi_surface_proxy_get_flags -gst_vaapi_surface_proxy_get_surface -gst_vaapi_surface_proxy_get_surface_id -gst_vaapi_surface_proxy_get_timestamp -gst_vaapi_surface_proxy_new_from_pool -gst_vaapi_surface_proxy_copy -gst_vaapi_surface_proxy_ref -gst_vaapi_surface_proxy_replace -gst_vaapi_surface_proxy_set_destroy_notify -gst_vaapi_surface_proxy_unref - -GST_VAAPI_SURFACE_PROXY_SURFACE -
- -
-gstvaapifilter -GstVaapiFilter -GstVaapiFilter -GstVaapiFilterOp -gst_vaapi_filter_new -gst_vaapi_filter_ref -gst_vaapi_filter_unref -gst_vaapi_filter_replace -gst_vaapi_filter_get_operations -gst_vaapi_filter_get_formats -gst_vaapi_filter_has_operation -gst_vaapi_filter_use_operation -gst_vaapi_filter_set_operation -gst_vaapi_filter_set_format -gst_vaapi_filter_set_cropping_rectangle -gst_vaapi_filter_set_target_rectangle -gst_vaapi_filter_set_denoising_level -gst_vaapi_filter_set_sharpening_level -gst_vaapi_filter_set_hue -gst_vaapi_filter_set_brightness -gst_vaapi_filter_set_saturation -gst_vaapi_filter_set_deinterlacing -gst_vaapi_filter_set_deinterlacing_references - -GST_VAAPI_FILTER -
- -
-gstvaapiparser_frame -GstVaapiParserFrame -gst_vaapi_parser_frame_new -gst_vaapi_parser_frame_free -gst_vaapi_parser_frame_append_unit -gst_vaapi_parser_frame_ref -gst_vaapi_parser_frame_unref -gst_vaapi_parser_frame_replace -
- -
-gstvaapicontext -GstVaapiContext -GstVaapiConfigInfoEncoder -GstVaapiContextInfo -GstVaapiContext -GstVaapiContextUsage -gst_vaapi_context_new -gst_vaapi_context_reset -gst_vaapi_context_get_id -gst_vaapi_context_get_surface_proxy -gst_vaapi_context_get_surface_count -
- -
-gstvaapidecoder_unit -GstVaapiDecoderUnit -GstVaapiDecoderUnitFlags -GstVaapiDecoderUnit -gst_vaapi_decoder_unit_init -gst_vaapi_decoder_unit_clear -gst_vaapi_decoder_unit_new -gst_vaapi_decoder_unit_set_parsed_info - -GST_VAAPI_DECODER_UNIT_FLAGS -GST_VAAPI_DECODER_UNIT_FLAG_IS_SET -GST_VAAPI_DECODER_UNIT_FLAG_SET -GST_VAAPI_DECODER_UNIT_FLAG_UNSET -GST_VAAPI_DECODER_UNIT_IS_FRAME_START -GST_VAAPI_DECODER_UNIT_IS_FRAME_END -GST_VAAPI_DECODER_UNIT_IS_STREAM_END -GST_VAAPI_DECODER_UNIT_IS_SLICE -GST_VAAPI_DECODER_UNIT_IS_SKIPPED -
- -
-gstvaapivalue -GstVaapiValue -GstVaapiEnumSubset -GST_VAAPI_TYPE_POINT -GST_VAAPI_TYPE_RECTANGLE -GST_VAAPI_TYPE_RENDER_MODE -GST_VAAPI_TYPE_ROTATION -GST_VAAPI_TYPE_RATE_CONTROL -GST_VAAPI_POPCOUNT32 -
From e387ad53881984920eebb677a8457ccf5d8ee37b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 26 Jan 2016 11:49:40 +0100 Subject: [PATCH 2236/3781] Remove more video parser crufts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This header is not used anymore since it declares parsers that are already in GStreamer 1.6 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapiparse.h | 47 --------------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 gst/vaapi/gstvaapiparse.h diff --git a/gst/vaapi/gstvaapiparse.h b/gst/vaapi/gstvaapiparse.h deleted file mode 100644 index 8983c866fd..0000000000 --- a/gst/vaapi/gstvaapiparse.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * gstvaapiparse.h - Recent enough GStreamer video parsers - * - * Copyright (C) 2014 Intel Corporation - * - * 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_PARSE_H -#define GST_VAAPI_PARSE_H - -/* vaapiparse_h264 */ -#define _GstH264Parse _GstVaapiH264Parse -#define GstH264Parse GstVaapiH264Parse -#define _GstH264ParseClass _GstVaapiH264ParseClass -#define GstH264ParseClass GstVaapiH264ParseClass -#define gst_h264_parse gst_vaapi_h264_parse -#define gst_h264_parse_init gst_vaapi_h264_parse_init -#define gst_h264_parse_class_init gst_vaapi_h264_parse_class_init -#define gst_h264_parse_parent_class gst_vaapi_h264_parse_parent_class -#define gst_h264_parse_get_type gst_vaapi_h264_parse_get_type - -/* vaapiparse_h265 */ -#define _GstH265Parse _GstVaapiH265Parse -#define GstH265Parse GstVaapiH265Parse -#define _GstH265ParseClass _GstVaapiH265ParseClass -#define GstH265ParseClass GstVaapiH265ParseClass -#define gst_h265_parse gst_vaapi_h265_parse -#define gst_h265_parse_init gst_vaapi_h265_parse_init -#define gst_h265_parse_class_init gst_vaapi_h265_parse_class_init -#define gst_h265_parse_parent_class gst_vaapi_h265_parse_parent_class -#define gst_h265_parse_get_type gst_vaapi_h265_parse_get_type - -#endif /* GST_VAAPI_PARSE_H */ From 14662eeec12fb3e65c3aa41ad82c7c5e554989b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Jan 2016 17:19:32 +0100 Subject: [PATCH 2237/3781] build: remove check for GStreamer 1.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we are working for current stable GStreamer 1.6 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/Makefile.am | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index b25d2dfde8..04568c95f5 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -53,6 +53,7 @@ libgstvaapi_source_c = \ gstvaapidecodebin.c \ gstvaapivideobufferpool.c \ gstvaapivideomemory.c \ + gstvaapivideometa_texture.c \ $(NULL) libgstvaapi_source_h = \ @@ -68,6 +69,7 @@ libgstvaapi_source_h = \ gstvaapidecodebin.h \ gstvaapivideobufferpool.h \ gstvaapivideomemory.h \ + gstvaapivideometa_texture.h \ $(NULL) libgstvaapi_enc_source_c = \ @@ -119,19 +121,6 @@ libgstvaapi_source_c += $(libgstvaapi_egl_source_c) libgstvaapi_source_h += $(libgstvaapi_egl_source_h) endif -libgstvaapi_1_2p_source_c = \ - gstvaapivideometa_texture.c \ - $(NULL) - -libgstvaapi_1_2p_source_h = \ - gstvaapivideometa_texture.h \ - $(NULL) - -if USE_GST_API_1_2p -libgstvaapi_source_c += $(libgstvaapi_1_2p_source_c) -libgstvaapi_source_h += $(libgstvaapi_1_2p_source_h) -endif - libgstvaapi_la_SOURCES = $(libgstvaapi_source_c) noinst_HEADERS = $(libgstvaapi_source_h) From ba91bf4c563b0c506e6e5859ac6b11d0d217047b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Jan 2016 17:20:31 +0100 Subject: [PATCH 2238/3781] build: remove unused EGL specific sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These Makefile variables are not used at all. Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/Makefile.am | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 04568c95f5..5732a2f1c5 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -111,16 +111,6 @@ libgstvaapi_source_c += $(libgstvaapi_h265enc_source_c) libgstvaapi_source_h += $(libgstvaapi_h265enc_source_h) endif - - -libgstvaapi_egl_source_c = -libgstvaapi_egl_source_h = - -if USE_EGL -libgstvaapi_source_c += $(libgstvaapi_egl_source_c) -libgstvaapi_source_h += $(libgstvaapi_egl_source_h) -endif - libgstvaapi_la_SOURCES = $(libgstvaapi_source_c) noinst_HEADERS = $(libgstvaapi_source_h) From 54011c22e254d9113f20053b905322c3fde7f2b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Jan 2016 17:47:32 +0100 Subject: [PATCH 2239/3781] build: fix when HEVC decoder is disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This a very pathological situation: when we have a HEVC encoder but not a HEVC decoder. The encoder needs functions that are only available when the decoder is enabled. This patch moves the utils functions into the generic sources, such as the rest of the utils. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/Makefile.am | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index ab4e968f86..eba5445bfa 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -76,6 +76,7 @@ libgstvaapi_source_c = \ gstvaapiutils.c \ gstvaapiutils_core.c \ gstvaapiutils_h264.c \ + gstvaapiutils_h265.c \ gstvaapiutils_mpeg2.c \ gstvaapivalue.c \ gstvaapivideopool.c \ @@ -106,6 +107,7 @@ libgstvaapi_source_h = \ gstvaapitexture.h \ gstvaapitypes.h \ gstvaapiutils_h264.h \ + gstvaapiutils_h265.h \ gstvaapiutils_mpeg2.h \ gstvaapivalue.h \ gstvaapivideopool.h \ @@ -138,6 +140,7 @@ libgstvaapi_source_priv_h = \ gstvaapiutils.h \ gstvaapiutils_core.h \ gstvaapiutils_h264_priv.h \ + gstvaapiutils_h265_priv.h \ gstvaapiutils_mpeg2_priv.h \ gstvaapiversion.h \ gstvaapivideopool_priv.h \ @@ -161,15 +164,11 @@ libgstvaapi_source_c += $(libgstvaapi_vp8dec_source_c) libgstvaapi_source_h += $(libgstvaapi_vp8dec_source_h) endif -libgstvaapi_hevcdec_source_c = \ - gstvaapidecoder_h265.c \ - gstvaapiutils_h265.c -libgstvaapi_hevcdec_source_h = gstvaapiutils_h265.h -libgstvaapi_hevcdec_source_priv_h = gstvaapiutils_h265_priv.h +libgstvaapi_hevcdec_source_c = gstvaapidecoder_h265.c +libgstvaapi_hevcdec_source_h = gstvaapidecoder_h265.h if USE_HEVC_DECODER libgstvaapi_source_c += $(libgstvaapi_hevcdec_source_c) libgstvaapi_source_h += $(libgstvaapi_hevcdec_source_h) -libgstvaapi_source_priv_h += $(libgstvaapi_hevcdec_source_priv_h) endif libgstvaapi_vp9dec_source_c = gstvaapidecoder_vp9.c From 1ca14030c45f475e0a637d3c39c5676834f2d506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Jan 2016 17:53:59 +0100 Subject: [PATCH 2240/3781] build: fix variable declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a698884d43..9dcc4d2afd 100644 --- a/configure.ac +++ b/configure.ac @@ -973,7 +973,7 @@ if test "$enable_encoders" = "yes"; then ]], [[VAEncSequenceParameterBufferHEVC seq_param; VAEncPictureParameterBufferHEVC pic_param; - VAEncSliceParameterBufferHEVC; + VAEncSliceParameterBufferHEVC buf_param; VAQMatrixBufferHEVC q_matrix;]])], [ac_cv_have_hevc_encoding_api="yes" USE_H265_ENCODER=1], [ac_cv_have_hevc_encoding_api="no" USE_H265_ENCODER=0] From 3c6eb032fa682aa7d4f2579e0765b9f196e64c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Jan 2016 12:11:17 +0100 Subject: [PATCH 2241/3781] build: add gstreamer-pbutils dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This dependency was added in gstvaapidecodebin with the call gst_missing_element_message_new(). Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 4 ++++ gst/vaapi/Makefile.am | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 9dcc4d2afd..8863d1af93 100644 --- a/configure.ac +++ b/configure.ac @@ -255,6 +255,10 @@ dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], [gstreamer-video-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) +dnl ... GStreamer base utils (gstreamer-pbutils) +PKG_CHECK_MODULES([GST_PBUTILS], + [gstreamer-pbutils-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + dnl GStreamer -bad plugins (deprecated in GStreamer v1.2) if test "$USE_GST_API_1_2p" != "yes" && test "$USE_GST_API_1_4p" != "yes"; then PKG_CHECK_MODULES([GST_BASEVIDEO], diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 5732a2f1c5..21eef47a1b 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -119,6 +119,7 @@ libgstvaapi_la_CFLAGS = \ $(GST_CFLAGS) \ $(GST_BASE_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ + $(GST_PBUTILS_CFLAGS) \ $(GST_INTERFACES_CFLAGS) \ $(GST_BASEVIDEO_CFLAGS) \ $(GST_PLUGINS_BASE_CFLAGS) \ @@ -128,7 +129,8 @@ libgstvaapi_la_LIBADD = \ $(libgstvaapi_LIBS) \ $(GST_LIBS) \ $(GST_BASE_LIBS) \ - $(GST_VIDEO_LIBS) -lgstpbutils-$(GST_PKG_VERSION) \ + $(GST_VIDEO_LIBS) \ + $(GST_PBUTILS_LIBS) \ $(GST_INTERFACES_LIBS) \ $(GST_BASEVIDEO_LIBS) \ $(GST_PLUGINS_BASE_LIBS) \ From 12e910faf8518b9b2d992d6ea95bc3e3982e0a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Jan 2016 17:55:02 +0100 Subject: [PATCH 2242/3781] build: remove GStreamer's parsers checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch removes almost all the parsers check since they are already in place, with the exception of the VP9 parser, since it was merged in Gstreamer 1.7. Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 131 ++------------------------------------------------- 1 file changed, 3 insertions(+), 128 deletions(-) diff --git a/configure.ac b/configure.ac index 8863d1af93..a250e716eb 100644 --- a/configure.ac +++ b/configure.ac @@ -103,11 +103,6 @@ dnl Initialize libtool LT_PREREQ([2.2]) LT_INIT -AC_ARG_ENABLE(builtin_videoparsers, - AS_HELP_STRING([--enable-builtin-videoparsers], - [enable built-in videoparsers @<:@default=yes@:>@]), - [], [enable_builtin_videoparsers="yes"]) - AC_ARG_ENABLE([encoders], AS_HELP_STRING([--enable-encoders], [enable video encoders @<:@default=yes@:>@]), @@ -269,99 +264,6 @@ dnl ... bitstream parsers PKG_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) -dnl ... MPEG-2 parser, with the required extensions -HAVE_GST_MPEG2_PARSER=0 -AC_CACHE_CHECK([for MPEG-2 parser], - ac_cv_have_gst_mpeg2_parser, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[GstMpegVideoSequenceHdr seq_hdr; - GstMpegVideoSequenceExt seq_ext; - GstMpegVideoSequenceDisplayExt seq_dpy; - GstMpegVideoSliceHdr slice_hdr; - GstMpegVideoPacket packet; - gst_mpeg_video_packet_parse_slice_header(&packet, &slice_hdr, - &seq_hdr, NULL); - gst_mpeg_video_finalise_mpeg2_sequence_header(&seq_hdr, - &seq_ext, &seq_dpy);]])], - [ac_cv_have_gst_mpeg2_parser="yes" HAVE_GST_MPEG2_PARSER=1], - [ac_cv_have_gst_mpeg2_parser="no"] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" -]) - -dnl ... H.264 parser, with the required extensions -HAVE_GST_H264_PARSER=0 -AC_CACHE_CHECK([for H.264 parser], - ac_cv_have_gst_h264_parser, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[GstH264SliceHdr slice_hdr; - GstH264VUIParams vui_params; - GstH264Profile profile = GST_H264_PROFILE_HIGH; - slice_hdr.n_emulation_prevention_bytes = 0; - vui_params.par_n = 0; - vui_params.par_d = 0; - GstH264SPS sps; - sps.extension.mvc.num_views_minus1 = 1; - GstH264NalUnit nalu; - nalu.extension_type = GST_H264_NAL_EXTENSION_MVC;]])], - [ac_cv_have_gst_h264_parser="yes" HAVE_GST_H264_PARSER=1], - [ac_cv_have_gst_h264_parser="no"] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" -]) - -dnl ... JPEG parser -HAVE_GST_JPEG_PARSER=0 -AC_CACHE_CHECK([for JPEG parser], - ac_cv_have_gst_jpeg_parser, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[GstJpegFrameHdr frame_hdr;]])], - [ac_cv_have_gst_jpeg_parser="yes" HAVE_GST_JPEG_PARSER=1], - [ac_cv_have_gst_jpeg_parser="no"] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" -]) - -dnl ... VP8 parser -HAVE_GST_VP8_PARSER=0 -AC_CACHE_CHECK([for VP8 parser], - ac_cv_have_gst_vp8_parser, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[GstVp8FrameHdr frame_hdr;]])], - [ac_cv_have_gst_vp8_parser="yes" HAVE_GST_VP8_PARSER=1], - [ac_cv_have_gst_vp8_parser="no"] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" -]) - dnl ... VP9 parser, with required extensions HAVE_GST_VP9_PARSER=0 AC_CACHE_CHECK([for VP9 parser], @@ -381,33 +283,6 @@ AC_CACHE_CHECK([for VP9 parser], LIBS="$saved_LIBS" ]) -dnl ... H.265 parser, with the required extensions -HAVE_GST_H265_PARSER=0 -AC_CACHE_CHECK([for H.265 parser], - ac_cv_have_gst_h265_parser, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[GstH265SliceHdr slice_hdr; - GstH265VUIParams vui_params; - GstH265Profile profile = GST_H265_PROFILE_MAIN_STILL_PICTURE; - slice_hdr.n_emulation_prevention_bytes = 0; - vui_params.par_n = 0; - vui_params.par_d = 0; - GstH265SPS sps; - sps.crop_rect_x = 0; - sps.crop_rect_width = 0;]])], - [ac_cv_have_gst_h265_parser="yes" HAVE_GST_H265_PARSER=1], - [ac_cv_have_gst_h265_parser="no"] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" -]) - dnl ... opengl helper libraries HAVE_GSTGL=0 if test "$enable_glx" = "yes" -o "$enable_egl" = "yes"; then @@ -751,7 +626,7 @@ AC_CACHE_CHECK([for JPEG decoding API], VASliceParameterBufferJPEGBaseline slice_param; VAHuffmanTableBufferJPEGBaseline huffman_table; VAIQMatrixBufferJPEGBaseline iq_matrix;]])], - [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=$HAVE_GST_JPEG_PARSER], + [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=1], [ac_cv_have_jpeg_decoding_api="no"] ) CPPFLAGS="$saved_CPPFLAGS" @@ -785,7 +660,7 @@ AC_CACHE_CHECK([for VP8 decoding API], VAIQMatrixBufferVP8 iq_matrix; slice_param.slice_data_offset = 0; slice_param.slice_data_flag = 0;]])], - [ac_cv_have_vp8_decoding_api="yes" USE_VP8_DECODER=$HAVE_GST_VP8_PARSER], + [ac_cv_have_vp8_decoding_api="yes" USE_VP8_DECODER=1], [ac_cv_have_vp8_decoding_api="no"] ) CPPFLAGS="$saved_CPPFLAGS" @@ -851,7 +726,7 @@ AC_CACHE_CHECK([for HEVC decoding API], VAIQMatrixBufferHEVC iq_matrix; slice_param.slice_data_offset = 0; slice_param.slice_data_flag = 0;]])], - [ac_cv_have_hevc_decoding_api="yes" USE_HEVC_DECODER=$HAVE_GST_H265_PARSER], + [ac_cv_have_hevc_decoding_api="yes" USE_HEVC_DECODER=1], [ac_cv_have_hevc_decoding_api="no"] ) CPPFLAGS="$saved_CPPFLAGS" From 27e18b6f366e9de963b7dc1c47fed9d657d23f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Jan 2016 19:00:51 +0100 Subject: [PATCH 2243/3781] build: remove check for old version of gstreamer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 115 ++++++++++----------------------------------------- 1 file changed, 22 insertions(+), 93 deletions(-) diff --git a/configure.ac b/configure.ac index a250e716eb..60917326b9 100644 --- a/configure.ac +++ b/configure.ac @@ -14,10 +14,7 @@ m4_define([default_glapi], [any]) # gstreamer-vaapi library (libtool) version number m4_define([gst_vaapi_lt_current], [7]) -m4_define([gst2_vaapi_lt_current_bias], [4]) -m4_define([gst4_vaapi_lt_current_bias], [5]) -m4_define([gst6_vaapi_lt_current_bias], [6]) -m4_define([gst8_vaapi_lt_current_bias], [7]) +m4_define([gst_vaapi_lt_current_bias], [7]) m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [0]) @@ -28,19 +25,9 @@ m4_define([glib_version], [2.32]) m4_define([gmodule_version], [2.32]) # gstreamer version number -m4_define([gst_api_version], [autodetect]) -m4_define([gst12_version], [1.1.90]) -m4_define([gst12_plugins_base_version], [1.1.0]) -m4_define([gst12_plugins_bad_version], [1.1.0]) -m4_define([gst14_version], [1.2.90]) -m4_define([gst14_plugins_base_version], [1.3.0]) -m4_define([gst14_plugins_bad_version], [1.3.0]) -m4_define([gst16_version], [1.5.0]) -m4_define([gst16_plugins_base_version], [1.5.0]) -m4_define([gst16_plugins_bad_version], [1.5.0]) -m4_define([gst18_version], [1.7.0]) -m4_define([gst18_plugins_base_version], [1.7.0]) -m4_define([gst18_plugins_bad_version], [1.7.0]) +m4_define([gst_version], [1.6.3]) +m4_define([gst_plugins_base_version], [1.6.3]) +m4_define([gst_plugins_bad_version], [1.6.3]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) @@ -163,84 +150,38 @@ AC_SUBST([DLOPEN_LIBS]) dnl --------------------------------------------------------------------------- dnl -- GStreamer -- dnl --------------------------------------------------------------------------- -AC_MSG_CHECKING([for GStreamer API version]) -if $PKG_CONFIG --exists "gstreamer-1.0"; then - gst_version=`$PKG_CONFIG --modversion "gstreamer-1.0"` - gst_major_version=`echo "$gst_version" | cut -d'.' -f1` - gst_minor_version=`echo "$gst_version" | cut -d'.' -f2` - GST_API_VERSION="${gst_major_version}.${gst_minor_version}" - GST_PKG_VERSION="1.0" -fi -if test -z "$GST_PKG_VERSION"; then - AC_MSG_ERROR([gstreamer-1.0 was not found]) -fi -AC_MSG_RESULT([$GST_API_VERSION]) - -AC_DEFINE_UNQUOTED([GST_API_VERSION_S], ["$GST_API_VERSION"], - [Defined to the string representation of GStreamer version]) +GST_PKG_VERSION="1.0" +AC_SUBST([GST_PKG_VERSION]) +AC_DEFINE_UNQUOTED([GST_PKG_VERSION_S], ["$GST_PKG_VERSION"], + [Defined to the string representation of GStreamer API version]) dnl Versions for GStreamer and plugins-base -case $GST_API_VERSION in -1.2) - GST_VERSION_REQUIRED=gst12_version - GST_PLUGINS_BASE_VERSION_REQUIRED=gst12_plugins_base_version - GST_PLUGINS_BAD_VERSION_REQUIRED=gst12_plugins_bad_version - ;; -1.4) - GST_VERSION_REQUIRED=gst14_version - GST_PLUGINS_BASE_VERSION_REQUIRED=gst14_plugins_base_version - GST_PLUGINS_BAD_VERSION_REQUIRED=gst14_plugins_bad_version - ;; -1.[[5-6]]) - GST_VERSION_REQUIRED=gst16_version - GST_PLUGINS_BASE_VERSION_REQUIRED=gst16_plugins_base_version - GST_PLUGINS_BAD_VERSION_REQUIRED=gst16_plugins_bad_version - ;; -1.[[7-8]]) - GST_VERSION_REQUIRED=gst18_version - GST_PLUGINS_BASE_VERSION_REQUIRED=gst18_plugins_base_version - GST_PLUGINS_BAD_VERSION_REQUIRED=gst18_plugins_bad_version - ;; -*) - AC_MSG_ERROR([unsupported GStreamer API version $GST_API_VERSION]) - ;; -esac -AC_SUBST(GST_API_VERSION) +GST_VERSION_REQUIRED=gst_version +GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version +GST_PLUGINS_BAD_VERSION_REQUIRED=gst_plugins_bad_version AC_SUBST(GST_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED) -USE_GST_API_1_2p="no" -USE_GST_API_1_4p="no" -AS_VERSION_COMPARE([$GST_API_VERSION], [1.2], - [], [USE_GST_API_1_2p="yes"], [USE_GST_API_1_2p="yes"]) -AS_VERSION_COMPARE([$GST_API_VERSION], [1.4], - [], [USE_GST_API_1_4p="yes"], [USE_GST_API_1_4p="yes"]) -AM_CONDITIONAL([USE_GST_API_1_2p], [test "$USE_GST_API_1_2p" = "yes"]) -AM_CONDITIONAL([USE_GST_API_1_4p], [test "$USE_GST_API_1_4p" = "yes"]) - -AC_SUBST([GST_PKG_VERSION]) - -AC_DEFINE_UNQUOTED([GST_PKG_VERSION_S], ["$GST_PKG_VERSION"], - [Defined to the string representation of GStreamer API version]) - -if test "$GST_API_VERSION" = "1.2"; then - AC_MSG_WARN([support for GStreamer 1.2 is obsolete, and will be removed]) -fi - dnl GStreamer Core PKG_CHECK_MODULES([GST], [gstreamer-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) + +AC_MSG_CHECKING([for GStreamer API version]) +gst_api_version=`$PKG_CONFIG --modversion "gstreamer-$GST_PKG_VERSION"` +gst_major_version=`echo "$gst_api_version" | cut -d'.' -f1` +gst_minor_version=`echo "$gst_api_version" | cut -d'.' -f2` +GST_API_VERSION="${gst_major_version}.${gst_minor_version}" +AC_MSG_RESULT([$GST_API_VERSION]) +AC_DEFINE_UNQUOTED([GST_API_VERSION_S], ["$GST_API_VERSION"], + [Defined to the string representation of GStreamer version]) + PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) dnl GStreamer -base plugins PKG_CHECK_MODULES([GST_PLUGINS_BASE], [gstreamer-plugins-base-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) -if test "$GST_API_VERSION" = "0.10"; then -PKG_CHECK_MODULES([GST_INTERFACES], - [gstreamer-interfaces-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) -fi dnl ... gst_dmabuf_memory_get_fd (gstreamer-allocators) PKG_CHECK_MODULES([GST_ALLOCATORS], @@ -254,12 +195,6 @@ dnl ... GStreamer base utils (gstreamer-pbutils) PKG_CHECK_MODULES([GST_PBUTILS], [gstreamer-pbutils-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) -dnl GStreamer -bad plugins (deprecated in GStreamer v1.2) -if test "$USE_GST_API_1_2p" != "yes" && test "$USE_GST_API_1_4p" != "yes"; then -PKG_CHECK_MODULES([GST_BASEVIDEO], - [gstreamer-basevideo-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) -fi - dnl ... bitstream parsers PKG_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) @@ -320,13 +255,7 @@ if test "$enable_egl" = "yes" -a $HAVE_GSTGL -ne 1; then enable_egl="no" fi -case $GST_API_VERSION in -1.2) lt_bias=gst2_vaapi_lt_current_bias;; -1.4) lt_bias=gst4_vaapi_lt_current_bias;; -1.[[5-6]]) lt_bias=gst6_vaapi_lt_current_bias;; -1.[[7-8]]) lt_bias=gst8_vaapi_lt_current_bias;; -esac -GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - "$lt_bias"` +GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - gst_vaapi_lt_current_bias` AC_SUBST(GST_VAAPI_MAJOR_VERSION) AC_DEFINE_UNQUOTED([GST_VAAPI_MAJOR_VERSION_S], ["$GST_VAAPI_MAJOR_VERSION"], From 1de5e4bcb01dacfdbb6b36b8839d4b636ba24976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Jan 2016 14:29:16 +0100 Subject: [PATCH 2244/3781] build: remove unused variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 53 ++++------------------------------------------------ 1 file changed, 4 insertions(+), 49 deletions(-) diff --git a/configure.ac b/configure.ac index 60917326b9..2078296978 100644 --- a/configure.ac +++ b/configure.ac @@ -39,12 +39,6 @@ m4_define([va_api_drm_version], [0.33.0]) m4_define([va_api_x11_version], [0.31.0]) m4_define([va_api_wld_version], [0.33.0]) -# libva package version number -m4_define([libva_enc_package_version], [1.2.0]) -m4_define([libva_drm_package_version], [1.1.0]) -m4_define([libva_x11_package_version], [1.0.3]) -m4_define([libva_wld_package_version], [1.1.0]) - # gtk-doc version number # XXX: introspection annotations require gtk-doc >= 1.12 m4_define([gtkdoc_version], [1.9]) @@ -63,15 +57,6 @@ AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([1.11 tar-ustar no-dist-gzip dist-bzip2]) -TODAY="`LC_ALL=C date +'%a, %d %b %Y %X %z'`" -AC_SUBST(TODAY) - -LIBVA_PACKAGE_VERSION=libva_x11_package_version -AC_SUBST(LIBVA_PACKAGE_VERSION) - -WAYLAND_API_VERSION=wayland_api_version -AC_SUBST(WAYLAND_API_VERSION) - dnl Use pretty build output with automake >= 1.11 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [ AM_DEFAULT_VERBOSITY=1 @@ -134,12 +119,10 @@ GTKDOC_VERSION=gtkdoc_version m4_ifdef([GTK_DOC_CHECK], [ GTK_DOC_CHECK([$GTKDOC_VERSION], [--flavour no-tmpl])], [ AM_CONDITIONAL([ENABLE_GTK_DOC], [false])]) -AC_SUBST(GTKDOC_VERSION) dnl Check for GLib GLIB_VERSION_REQUIRED=glib_version PKG_CHECK_MODULES([GLIB], [glib-2.0 >= $GLIB_VERSION_REQUIRED]) -AC_SUBST(GLIB_VERSION_REQUIRED) dnl Check to see if dlopen is in default libraries (like Solaris, which dnl has it in libc), or if libdl is needed to get it. @@ -159,9 +142,6 @@ dnl Versions for GStreamer and plugins-base GST_VERSION_REQUIRED=gst_version GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version GST_PLUGINS_BAD_VERSION_REQUIRED=gst_plugins_bad_version -AC_SUBST(GST_VERSION_REQUIRED) -AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED) -AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED) dnl GStreamer Core PKG_CHECK_MODULES([GST], @@ -256,20 +236,9 @@ if test "$enable_egl" = "yes" -a $HAVE_GSTGL -ne 1; then fi GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - gst_vaapi_lt_current_bias` -AC_SUBST(GST_VAAPI_MAJOR_VERSION) - AC_DEFINE_UNQUOTED([GST_VAAPI_MAJOR_VERSION_S], ["$GST_VAAPI_MAJOR_VERSION"], [Defined to the string representation of gstreamer-vaapi major version]) -dnl GST_VAAPI_LT_LDFLAGS: -GST_VAAPI_LT_CURRENT="$GST_VAAPI_MAJOR_VERSION" -GST_VAAPI_LT_REV=gst_vaapi_lt_revision -GST_VAAPI_LT_AGE=gst_vaapi_lt_age -GST_VAAPI_LT_VERSION="$GST_VAAPI_LT_CURRENT:$GST_VAAPI_LT_REV:$GST_VAAPI_LT_AGE" -GST_VAAPI_LT_LDFLAGS="-version-info $GST_VAAPI_LT_VERSION" -AC_SUBST(GST_VAAPI_LT_VERSION) -AC_SUBST(GST_VAAPI_LT_LDFLAGS) - dnl GST_ALL_LDFLAGS: dnl LDFLAGS really should only contain flags, not libs - they get added before dnl whatevertarget_LIBS and -L flags here affect the rest of the linking @@ -475,7 +444,6 @@ if test "$enable_egl" = "yes" -a $GLES_VERSION_MASK -ne 0; then dnl Check for GMODULE GMODULE_VERSION_REQUIRED=gmodule_version PKG_CHECK_MODULES([GMODULE], [gmodule-2.0 >= $GMODULE_VERSION_REQUIRED]) - AC_SUBST(GMODULE_VERSION_REQUIRED) fi dnl Check for Wayland @@ -497,15 +465,8 @@ dnl -- VA-API -- dnl --------------------------------------------------------------------------- dnl Core API -LIBVA_PKGNAME="libva" -PKG_CHECK_MODULES(LIBVA, [$LIBVA_PKGNAME >= va_api_version]) -AC_SUBST(LIBVA_PKGNAME) - -VA_VERSION=`$PKG_CONFIG --modversion libva` -VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1` -VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2` -VA_MICRO_VERSION=`echo "$VA_VERSION" | cut -d'.' -f3` -VA_VERSION_STR="$VA_VERSION" +PKG_CHECK_MODULES([LIBVA], [libva >= va_api_version]) +VA_VERSION_STR=`$PKG_CONFIG --modversion libva` dnl VA/DRM API HAVE_VA_DRM=0 @@ -522,13 +483,10 @@ if test $USE_DRM -eq 1; then fi dnl VA/X11 API -HAVE_VA_X11=0 -LIBVA_X11_PKGNAME="libva-x11" if test $USE_X11 -eq 1; then - PKG_CHECK_MODULES(LIBVA_X11, [$LIBVA_X11_PKGNAME >= va_api_x11_version], - [HAVE_VA_X11=1], [USE_X11=0]) + PKG_CHECK_MODULES(LIBVA_X11, [libva-x11 >= va_api_x11_version], + [], [USE_X11=0]) fi -AC_SUBST(LIBVA_X11_PKGNAME) dnl Check for va_dec_jpeg.h header saved_CPPFLAGS="$CPPFLAGS" @@ -870,9 +828,6 @@ AC_DEFINE_UNQUOTED(USE_WAYLAND, $USE_WAYLAND, [Defined to 1 if WAYLAND is enabled]) AM_CONDITIONAL(USE_WAYLAND, test $USE_WAYLAND -eq 1) -pkgconfigdir=${libdir}/pkgconfig -AC_SUBST(pkgconfigdir) - AC_CONFIG_FILES([ Makefile docs/Makefile From af87f9056eb00a9da5ead566dd0585578a87d041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Jan 2016 11:14:34 +0100 Subject: [PATCH 2245/3781] build: enhance string comparisons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a 'x' as a prefix in string comparisons to watch out for edge cases where the string is empty or undefined. Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index 2078296978..7d9de18f11 100644 --- a/configure.ac +++ b/configure.ac @@ -200,7 +200,7 @@ AC_CACHE_CHECK([for VP9 parser], dnl ... opengl helper libraries HAVE_GSTGL=0 -if test "$enable_glx" = "yes" -o "$enable_egl" = "yes"; then +if test "x$enable_glx" = "xyes" -o "x$enable_egl" = "xyes"; then PKG_CHECK_MODULES([GST_GL], [gstreamer-gl-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED], [HAVE_GSTGL=1], [HAVE_GSTGL=0]) @@ -230,7 +230,7 @@ AM_CONDITIONAL([USE_GST_GL_HELPERS], [test $HAVE_GSTGL -eq 1]) AC_DEFINE_UNQUOTED([USE_GST_GL_HELPERS], [$HAVE_GSTGL], [Defined to 1 if GStreamer OpenGL helper libraries are available]) -if test "$enable_egl" = "yes" -a $HAVE_GSTGL -ne 1; then +if test "x$enable_egl" = "xyes" -a $HAVE_GSTGL -ne 1; then AC_MSG_WARN([GStreamer/GL helper libraries not found, disabling EGL support]) enable_egl="no" fi @@ -272,7 +272,7 @@ dnl --------------------------------------------------------------------------- dnl Check for DRM/libudev USE_DRM=0 -if test "$enable_drm" = "yes"; then +if test "x$enable_drm" = "xyes"; then PKG_CHECK_MODULES(DRM, [libdrm], [USE_DRM=1], [USE_DRM=0]) PKG_CHECK_MODULES(UDEV, [libudev], [:], [USE_DRM=0]) @@ -286,7 +286,7 @@ fi dnl Check for X11 USE_X11=0 -if test "$enable_x11" = "yes"; then +if test "x$enable_x11" = "xyes"; then PKG_CHECK_MODULES(X11, [x11], [USE_X11=1], [USE_X11=0]) if test $USE_X11 -eq 1; then saved_CPPFLAGS="$CPPFLAGS" @@ -342,16 +342,16 @@ fi dnl OpenGL enable_opengl="no" -if test "$enable_glx" = "yes"; then +if test "x$enable_glx" = "xyes"; then enable_opengl="yes" fi -if test "$enable_egl" = "yes"; then +if test "x$enable_egl" = "xyes"; then enable_opengl="yes" fi GLES_VERSION_MASK=0 HAVE_GL=0 -if test "$enable_opengl" = "yes"; then +if test "x$enable_opengl" = "xyes"; then case ",$GLAPI," in (*,any,*|*,gl,*) HAVE_GL=1 @@ -371,7 +371,7 @@ GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GL "*" 1` dnl OpenGL|ESv2 HAVE_GLESv2=0 -if test "$enable_opengl" = "yes"; then +if test "x$enable_opengl" = "xyes"; then case ",$GLAPI," in (*,any,*|*,gles2,*) HAVE_GLESv2=1 @@ -392,7 +392,7 @@ GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GLESv2 "*" 4` dnl OpenGL|ESv3 HAVE_GLESv3=0 -if test "$enable_opengl" = "yes"; then +if test "x$enable_opengl" = "xyes"; then case ",$GLAPI," in (*,any,*|*,gles3,*) HAVE_GLESv3=1 @@ -413,7 +413,7 @@ GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GLESv3 "*" 8` dnl ... GLX USE_GLX=0 -if test "$enable_glx" = "yes" -a $HAVE_GL -eq 1 -a $USE_X11 -eq 1; then +if test "x$enable_glx" = "xyes" -a $HAVE_GL -eq 1 -a $USE_X11 -eq 1; then USE_GLX=1 saved_CPPFLAGS="$CPPFLAGS" saved_LIBS="$LIBS" @@ -431,7 +431,7 @@ fi dnl ... EGL USE_EGL=0 -if test "$enable_egl" = "yes" -a $GLES_VERSION_MASK -ne 0; then +if test "x$enable_egl" = "xyes" -a $GLES_VERSION_MASK -ne 0; then USE_EGL=1 PKG_CHECK_MODULES([EGL], [egl], [:], [USE_EGL=0]) saved_CPPFLAGS="$CPPFLAGS" @@ -448,7 +448,7 @@ fi dnl Check for Wayland USE_WAYLAND=0 -if test "$enable_wayland" = "yes"; then +if test "x$enable_wayland" = "xyes"; then PKG_CHECK_MODULES(WAYLAND, [wayland-client >= wayland_api_version], [USE_WAYLAND=1], [USE_WAYLAND=0]) @@ -650,7 +650,7 @@ USE_ENCODERS=0 USE_JPEG_ENCODER=0 USE_VP8_ENCODER=0 USE_H265_ENCODER=0 -if test "$enable_encoders" = "yes"; then +if test "x$enable_encoders" = "xyes"; then PKG_CHECK_MODULES([LIBVA], [libva >= va_api_enc_version], [HAVE_VA_ENC=1], [HAVE_VA_ENC=0]) @@ -752,7 +752,7 @@ if test "$enable_encoders" = "yes"; then fi dnl VA/Wayland API -if test "$enable_wayland" = "yes"; then +if test "x$enable_wayland" = "xyes"; then PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= va_api_wld_version], [:], [USE_WAYLAND=0]) fi From 2cc3f47f6a651f6283eeab5f6496942b291d4d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Jan 2016 16:50:39 +0100 Subject: [PATCH 2246/3781] build: upgrade autotools version dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 7d9de18f11..728d9acaf1 100644 --- a/configure.ac +++ b/configure.ac @@ -41,9 +41,9 @@ m4_define([va_api_wld_version], [0.33.0]) # gtk-doc version number # XXX: introspection annotations require gtk-doc >= 1.12 -m4_define([gtkdoc_version], [1.9]) +m4_define([gtkdoc_version], [1.12]) -AC_PREREQ([2.66]) +AC_PREREQ([2.69]) AC_INIT([gst_vaapi], [gst_vaapi_version], [gwenole.beauchesne@intel.com, sreerenj.balachandran@intel.com], [gstreamer-vaapi]) @@ -55,13 +55,10 @@ AC_CONFIG_AUX_DIR([build-aux]) AC_CANONICAL_TARGET -AM_INIT_AUTOMAKE([1.11 tar-ustar no-dist-gzip dist-bzip2]) +AM_INIT_AUTOMAKE([-Wno-portability 1.14 no-dist-gzip dist-xz tar-ustar subdir-objects]) -dnl Use pretty build output with automake >= 1.11 -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [ - AM_DEFAULT_VERBOSITY=1 - AC_SUBST(AM_DEFAULT_VERBOSITY) -]) +dnl Use pretty build output +AM_SILENT_RULES([yes]) dnl Check for tools AC_PROG_CC @@ -72,7 +69,7 @@ AC_PATH_PROG([GIT], [git]) AM_CONDITIONAL([HAVE_GIT], [test -n "$GIT"]) dnl Initialize libtool -LT_PREREQ([2.2]) +LT_PREREQ([2.2.6]) LT_INIT AC_ARG_ENABLE([encoders], From 19945763deb00d7cc23070bb3ad539055d39d9f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Jan 2016 16:55:44 +0100 Subject: [PATCH 2247/3781] build: indent and add square braces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 193 +++++++++++++++++++++++++-------------------------- 1 file changed, 95 insertions(+), 98 deletions(-) diff --git a/configure.ac b/configure.ac index 728d9acaf1..5e85ee4f12 100644 --- a/configure.ac +++ b/configure.ac @@ -44,9 +44,9 @@ m4_define([va_api_wld_version], [0.33.0]) m4_define([gtkdoc_version], [1.12]) AC_PREREQ([2.69]) -AC_INIT([gst_vaapi], [gst_vaapi_version], - [gwenole.beauchesne@intel.com, sreerenj.balachandran@intel.com], - [gstreamer-vaapi]) +AC_INIT([GStreamer VA-API Plug-ins], [gst_vaapi_version], + [http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer], + [gstreamer-vaapi]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([Makefile.am]) @@ -73,42 +73,42 @@ LT_PREREQ([2.2.6]) LT_INIT AC_ARG_ENABLE([encoders], - AS_HELP_STRING([--enable-encoders], - [enable video encoders @<:@default=yes@:>@]), - [], [enable_encoders="yes"]) + AS_HELP_STRING([--enable-encoders], + [enable video encoders @<:@default=yes@:>@]), + [], [enable_encoders="yes"]) -AC_ARG_ENABLE(drm, - AS_HELP_STRING([--enable-drm], - [enable DRM backend @<:@default=yes@:>@]), - [], [enable_drm="yes"]) +AC_ARG_ENABLE([drm], + AS_HELP_STRING([--enable-drm], + [enable DRM backend @<:@default=yes@:>@]), + [], [enable_drm="yes"]) -AC_ARG_ENABLE(x11, - AS_HELP_STRING([--enable-x11], - [enable X11 output @<:@default=yes@:>@]), - [], [enable_x11="yes"]) +AC_ARG_ENABLE([x11], + AS_HELP_STRING([--enable-x11], + [enable X11 output @<:@default=yes@:>@]), + [], [enable_x11="yes"]) -AC_ARG_ENABLE(glx, - AS_HELP_STRING([--enable-glx], - [enable OpenGL/X11 output @<:@default=yes@:>@]), - [], [enable_glx="yes"]) +AC_ARG_ENABLE([glx], + AS_HELP_STRING([--enable-glx], + [enable OpenGL/X11 output @<:@default=yes@:>@]), + [], [enable_glx="yes"]) -AC_ARG_ENABLE(wayland, - AC_HELP_STRING([--enable-wayland], - [enable Wayland output @<:@default=yes@:>@]), - [], [enable_wayland="yes"]) +AC_ARG_ENABLE([wayland], + AC_HELP_STRING([--enable-wayland], + [enable Wayland output @<:@default=yes@:>@]), + [], [enable_wayland="yes"]) AC_ARG_ENABLE([egl], - AS_HELP_STRING([--enable-egl], - [enable EGL output @<:@default=yes@:>@]), - [], [enable_egl="yes"]) + AS_HELP_STRING([--enable-egl], + [enable EGL output @<:@default=yes@:>@]), + [], [enable_egl="yes"]) AC_ARG_WITH([glapi], - AS_HELP_STRING([--with-glapi=APIs], - [build with the specified OpenGL APIs @<:@default=default_glapi@:>@]), - [GLAPI="$with_glapi"], [GLAPI=default_glapi]) + AS_HELP_STRING([--with-glapi=APIs], + [build with the specified OpenGL APIs @<:@default=default_glapi@:>@]), + [GLAPI="$with_glapi"], [GLAPI=default_glapi]) dnl Check for basic libraries -AC_CHECK_LIB(m, tan) +AC_CHECK_LIB([m], [tan]) dnl Check for Gtk doc GTKDOC_VERSION=gtkdoc_version @@ -124,7 +124,7 @@ PKG_CHECK_MODULES([GLIB], [glib-2.0 >= $GLIB_VERSION_REQUIRED]) dnl Check to see if dlopen is in default libraries (like Solaris, which dnl has it in libc), or if libdl is needed to get it. AC_CHECK_FUNC([dlopen], [], [ - AC_CHECK_LIB([dl], [dlopen], [DLOPEN_LIBS="-ldl"])]) + AC_CHECK_LIB([dl], [dlopen], [DLOPEN_LIBS="-ldl"])]) AC_SUBST([DLOPEN_LIBS]) dnl --------------------------------------------------------------------------- @@ -133,7 +133,7 @@ dnl --------------------------------------------------------------------------- GST_PKG_VERSION="1.0" AC_SUBST([GST_PKG_VERSION]) AC_DEFINE_UNQUOTED([GST_PKG_VERSION_S], ["$GST_PKG_VERSION"], - [Defined to the string representation of GStreamer API version]) + [Defined to the string representation of GStreamer API version]) dnl Versions for GStreamer and plugins-base GST_VERSION_REQUIRED=gst_version @@ -142,7 +142,7 @@ GST_PLUGINS_BAD_VERSION_REQUIRED=gst_plugins_bad_version dnl GStreamer Core PKG_CHECK_MODULES([GST], - [gstreamer-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) + [gstreamer-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) AC_MSG_CHECKING([for GStreamer API version]) gst_api_version=`$PKG_CONFIG --modversion "gstreamer-$GST_PKG_VERSION"` @@ -151,30 +151,30 @@ gst_minor_version=`echo "$gst_api_version" | cut -d'.' -f2` GST_API_VERSION="${gst_major_version}.${gst_minor_version}" AC_MSG_RESULT([$GST_API_VERSION]) AC_DEFINE_UNQUOTED([GST_API_VERSION_S], ["$GST_API_VERSION"], - [Defined to the string representation of GStreamer version]) + [Defined to the string representation of GStreamer version]) PKG_CHECK_MODULES([GST_BASE], - [gstreamer-base-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) + [gstreamer-base-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) dnl GStreamer -base plugins PKG_CHECK_MODULES([GST_PLUGINS_BASE], - [gstreamer-plugins-base-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + [gstreamer-plugins-base-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) dnl ... gst_dmabuf_memory_get_fd (gstreamer-allocators) PKG_CHECK_MODULES([GST_ALLOCATORS], - [gstreamer-allocators-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + [gstreamer-allocators-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], - [gstreamer-video-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + [gstreamer-video-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) dnl ... GStreamer base utils (gstreamer-pbutils) PKG_CHECK_MODULES([GST_PBUTILS], - [gstreamer-pbutils-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + [gstreamer-pbutils-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) dnl ... bitstream parsers PKG_CHECK_MODULES([GST_CODEC_PARSERS], - [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) + [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) dnl ... VP9 parser, with required extensions HAVE_GST_VP9_PARSER=0 @@ -223,33 +223,33 @@ if test $HAVE_GSTGL -eq 1; then ]) fi AM_CONDITIONAL([USE_GST_GL_HELPERS], [test $HAVE_GSTGL -eq 1]) - AC_DEFINE_UNQUOTED([USE_GST_GL_HELPERS], [$HAVE_GSTGL], - [Defined to 1 if GStreamer OpenGL helper libraries are available]) + [Defined to 1 if GStreamer OpenGL helper libraries are available]) if test "x$enable_egl" = "xyes" -a $HAVE_GSTGL -ne 1; then - AC_MSG_WARN([GStreamer/GL helper libraries not found, disabling EGL support]) - enable_egl="no" + AC_MSG_WARN([GStreamer/GL helper libraries not found, disabling EGL support]) + enable_egl="no" fi GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - gst_vaapi_lt_current_bias` AC_DEFINE_UNQUOTED([GST_VAAPI_MAJOR_VERSION_S], ["$GST_VAAPI_MAJOR_VERSION"], - [Defined to the string representation of gstreamer-vaapi major version]) + [Defined to the string representation of gstreamer-vaapi major version]) dnl GST_ALL_LDFLAGS: dnl LDFLAGS really should only contain flags, not libs - they get added before dnl whatevertarget_LIBS and -L flags here affect the rest of the linking GST_ALL_LDFLAGS="-no-undefined" -AC_SUBST(GST_ALL_LDFLAGS) +AC_SUBST([GST_ALL_LDFLAGS]) dnl GST_PLUGIN_LDFLAGS: dnl this really should only contain flags, not libs - they get added before dnl whatevertarget_LIBS and -L flags here affect the rest of the linking GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^([_]*gst_plugin_desc|gst_.*_get_type)\$\$' $GST_ALL_LDFLAGS" -AC_SUBST(GST_PLUGIN_LDFLAGS) +AC_SUBST([GST_PLUGIN_LDFLAGS]) dnl Check for the GStreamer plugins directory -AC_ARG_VAR([GST_PLUGIN_PATH_1_0], [installation path for gstreamer-vaapi plugin elements for GStreamer 1.0]) +AC_ARG_VAR([GST_PLUGIN_PATH_1_0], + [installation path for gstreamer-vaapi plugin elements for GStreamer 1.0]) AC_MSG_CHECKING([for GStreamer plugins directory]) if test -n "$GST_PLUGIN_PATH_1_0"; then GST_PLUGINS_DIR="$GST_PLUGIN_PATH_1_0" @@ -261,7 +261,7 @@ else fi AC_MSG_RESULT([$GST_PLUGINS_DIR]) plugindir="$GST_PLUGINS_DIR" -AC_SUBST(plugindir) +AC_SUBST([plugindir]) dnl --------------------------------------------------------------------------- dnl -- Renderers -- @@ -481,8 +481,8 @@ fi dnl VA/X11 API if test $USE_X11 -eq 1; then - PKG_CHECK_MODULES(LIBVA_X11, [libva-x11 >= va_api_x11_version], - [], [USE_X11=0]) + PKG_CHECK_MODULES(LIBVA_X11, [libva-x11 >= va_api_x11_version], + [], [USE_X11=0]) fi dnl Check for va_dec_jpeg.h header @@ -750,8 +750,8 @@ fi dnl VA/Wayland API if test "x$enable_wayland" = "xyes"; then - PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= va_api_wld_version], - [:], [USE_WAYLAND=0]) + PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= va_api_wld_version], + [], [USE_WAYLAND=0]) fi dnl --------------------------------------------------------------------------- @@ -759,71 +759,68 @@ dnl -- Generate files and summary -- dnl --------------------------------------------------------------------------- case ":$USE_X11:$USE_GLX:$USE_EGL:$USE_WAYLAND:$USE_DRM:" in -*:1:*) - ;; -*) - AC_MSG_ERROR([No renderer is enabled]) - ;; +*:1:*) ;; +*) AC_MSG_ERROR([No renderer is enabled]) ;; esac -AC_DEFINE_UNQUOTED([USE_ENCODERS], $USE_ENCODERS, - [Defined to 1 if video encoders are used]) +AC_DEFINE_UNQUOTED([USE_ENCODERS], [$USE_ENCODERS], + [Defined to 1 if video encoders are used]) AM_CONDITIONAL([USE_ENCODERS], [test $USE_ENCODERS -eq 1]) -AC_DEFINE_UNQUOTED(USE_JPEG_ENCODER, $USE_JPEG_ENCODER, - [Defined to 1 if JPEG encoder is used]) -AM_CONDITIONAL(USE_JPEG_ENCODER, test $USE_JPEG_ENCODER -eq 1) +AC_DEFINE_UNQUOTED([USE_JPEG_ENCODER], [$USE_JPEG_ENCODER], + [Defined to 1 if JPEG encoder is used]) +AM_CONDITIONAL([USE_JPEG_ENCODER], [test $USE_JPEG_ENCODER -eq 1]) -AC_DEFINE_UNQUOTED(USE_VP8_ENCODER, $USE_VP8_ENCODER, - [Defined to 1 if VP8 encoder is used]) -AM_CONDITIONAL(USE_VP8_ENCODER, test $USE_VP8_ENCODER -eq 1) +AC_DEFINE_UNQUOTED([USE_VP8_ENCODER], [$USE_VP8_ENCODER], + [Defined to 1 if VP8 encoder is used]) +AM_CONDITIONAL([USE_VP8_ENCODER], [test $USE_VP8_ENCODER -eq 1]) -AC_DEFINE_UNQUOTED(USE_H265_ENCODER, $USE_H265_ENCODER, - [Defined to 1 if H265 encoder is used]) -AM_CONDITIONAL(USE_H265_ENCODER, test $USE_H265_ENCODER -eq 1) +AC_DEFINE_UNQUOTED([USE_H265_ENCODER], [$USE_H265_ENCODER], + [Defined to 1 if H265 encoder is used]) +AM_CONDITIONAL([USE_H265_ENCODER], [test $USE_H265_ENCODER -eq 1]) -AC_DEFINE_UNQUOTED(USE_VA_VPP, $USE_VA_VPP, - [Defined to 1 if video post-processing is used]) -AM_CONDITIONAL(USE_VA_VPP, test $USE_VA_VPP -eq 1) +AC_DEFINE_UNQUOTED([USE_VA_VPP], [$USE_VA_VPP], + [Defined to 1 if video post-processing is used]) +AM_CONDITIONAL([USE_VA_VPP], [test $USE_VA_VPP -eq 1]) -AC_DEFINE_UNQUOTED(USE_JPEG_DECODER, $USE_JPEG_DECODER, - [Defined to 1 if JPEG decoder is used]) -AM_CONDITIONAL(USE_JPEG_DECODER, test $USE_JPEG_DECODER -eq 1) +AC_DEFINE_UNQUOTED([USE_JPEG_DECODER], [$USE_JPEG_DECODER], + [Defined to 1 if JPEG decoder is used]) +AM_CONDITIONAL([USE_JPEG_DECODER], [test $USE_JPEG_DECODER -eq 1]) -AC_DEFINE_UNQUOTED(USE_VP8_DECODER, $USE_VP8_DECODER, - [Defined to 1 if VP8 decoder is used]) -AM_CONDITIONAL(USE_VP8_DECODER, test $USE_VP8_DECODER -eq 1) +AC_DEFINE_UNQUOTED([USE_VP8_DECODER], [$USE_VP8_DECODER], + [Defined to 1 if VP8 decoder is used]) +AM_CONDITIONAL([USE_VP8_DECODER], [test $USE_VP8_DECODER -eq 1]) -AC_DEFINE_UNQUOTED(USE_VP9_DECODER, $USE_VP9_DECODER, - [Defined to 1 if VP9 decoder is used]) -AM_CONDITIONAL(USE_VP9_DECODER, test $USE_VP9_DECODER -eq 1) +AC_DEFINE_UNQUOTED([USE_VP9_DECODER], [$USE_VP9_DECODER], + [Defined to 1 if VP9 decoder is used]) +AM_CONDITIONAL([USE_VP9_DECODER], [test $USE_VP9_DECODER -eq 1]) -AC_DEFINE_UNQUOTED(USE_HEVC_DECODER, $USE_HEVC_DECODER, - [Defined to 1 if HEVC decoder is used]) -AM_CONDITIONAL(USE_HEVC_DECODER, test $USE_HEVC_DECODER -eq 1) +AC_DEFINE_UNQUOTED([USE_HEVC_DECODER], [$USE_HEVC_DECODER], + [Defined to 1 if HEVC decoder is used]) +AM_CONDITIONAL([USE_HEVC_DECODER], [test $USE_HEVC_DECODER -eq 1]) -AC_DEFINE_UNQUOTED(USE_DRM, $USE_DRM, - [Defined to 1 if DRM is enabled]) -AM_CONDITIONAL(USE_DRM, test $USE_DRM -eq 1) +AC_DEFINE_UNQUOTED([USE_DRM], [$USE_DRM], + [Defined to 1 if DRM is enabled]) +AM_CONDITIONAL([USE_DRM], [test $USE_DRM -eq 1]) -AC_DEFINE_UNQUOTED(USE_X11, $USE_X11, - [Defined to 1 if X11 is enabled]) -AM_CONDITIONAL(USE_X11, test $USE_X11 -eq 1) +AC_DEFINE_UNQUOTED([USE_X11], [$USE_X11], + [Defined to 1 if X11 is enabled]) +AM_CONDITIONAL([USE_X11], [test $USE_X11 -eq 1]) -AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, - [Defined to 1 if GLX is enabled]) -AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) +AC_DEFINE_UNQUOTED([USE_GLX], [$USE_GLX], + [Defined to 1 if GLX is enabled]) +AM_CONDITIONAL([USE_GLX], [test $USE_GLX -eq 1]) AC_DEFINE_UNQUOTED([USE_EGL], [$USE_EGL], - [Defined to 1 if EGL is enabled]) + [Defined to 1 if EGL is enabled]) AM_CONDITIONAL([USE_EGL], [test $USE_EGL -eq 1]) AC_DEFINE_UNQUOTED([USE_GLES_VERSION_MASK], [$GLES_VERSION_MASK], - [Defined to the set of enabled OpenGL ES APIs]) + [Defined to the set of enabled OpenGL ES APIs]) -AC_DEFINE_UNQUOTED(USE_WAYLAND, $USE_WAYLAND, - [Defined to 1 if WAYLAND is enabled]) -AM_CONDITIONAL(USE_WAYLAND, test $USE_WAYLAND -eq 1) +AC_DEFINE_UNQUOTED([USE_WAYLAND], [$USE_WAYLAND], + [Defined to 1 if WAYLAND is enabled]) +AM_CONDITIONAL([USE_WAYLAND], [test $USE_WAYLAND -eq 1]) AC_CONFIG_FILES([ Makefile @@ -843,7 +840,7 @@ AC_OUTPUT dnl Print summary yesno() { - test $1 -eq 1 && echo yes || echo no + test $1 -eq 1 && echo yes || echo no } VIDEO_OUTPUTS="" From e1a6f57468de7b51e5797c2a09a3468b68560044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Jan 2016 12:34:30 +0100 Subject: [PATCH 2248/3781] build: check for OpenGL either GLX or EGL are requested MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor some code in configure.ac to centralize $enable_opengl definition. Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 5e85ee4f12..ec5a89c7dd 100644 --- a/configure.ac +++ b/configure.ac @@ -195,9 +195,12 @@ AC_CACHE_CHECK([for VP9 parser], LIBS="$saved_LIBS" ]) +AS_IF([test "x$enable_glx" = "xyes" -o "x$enable_egl" = "xyes"], + [enable_opengl="yes"], [enable_opengl="no"]) + dnl ... opengl helper libraries HAVE_GSTGL=0 -if test "x$enable_glx" = "xyes" -o "x$enable_egl" = "xyes"; then +if test "x$enable_opengl" = "xyes"; then PKG_CHECK_MODULES([GST_GL], [gstreamer-gl-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED], [HAVE_GSTGL=1], [HAVE_GSTGL=0]) @@ -338,13 +341,6 @@ if test $HAVE_XRENDER -eq 1; then fi dnl OpenGL -enable_opengl="no" -if test "x$enable_glx" = "xyes"; then - enable_opengl="yes" -fi -if test "x$enable_egl" = "xyes"; then - enable_opengl="yes" -fi GLES_VERSION_MASK=0 HAVE_GL=0 From ad8d17d53ade5381376549cee148f4f732583cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Jan 2016 17:14:51 +0100 Subject: [PATCH 2249/3781] build: refactorization of dependency tracking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch tries to avoid branching in configure.ac using a more functional approach in macros usage. Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 755 ++++++++++++++++++++++++++++----------------------- 1 file changed, 409 insertions(+), 346 deletions(-) diff --git a/configure.ac b/configure.ac index ec5a89c7dd..6b13d299c7 100644 --- a/configure.ac +++ b/configure.ac @@ -179,21 +179,27 @@ PKG_CHECK_MODULES([GST_CODEC_PARSERS], dnl ... VP9 parser, with required extensions HAVE_GST_VP9_PARSER=0 AC_CACHE_CHECK([for VP9 parser], - ac_cv_have_gst_vp9_parser, [ + [ac_cv_have_gst_vp9_parser], + [ saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[GstVp9FrameHdr frame_hdr;]])], - [ac_cv_have_gst_vp9_parser="yes" HAVE_GST_VP9_PARSER=1], - [ac_cv_have_gst_vp9_parser="no"] - ) + [ + AC_LANG_PROGRAM( + [[ +#include + ]], + [[ +GstVp9FrameHdr frame_hdr; + ]]) + ], + [ac_cv_have_gst_vp9_parser="yes" HAVE_GST_VP9_PARSER=1], + [ac_cv_have_gst_vp9_parser="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" -]) + ]) AS_IF([test "x$enable_glx" = "xyes" -o "x$enable_egl" = "xyes"], [enable_opengl="yes"], [enable_opengl="no"]) @@ -201,29 +207,34 @@ AS_IF([test "x$enable_glx" = "xyes" -o "x$enable_egl" = "xyes"], dnl ... opengl helper libraries HAVE_GSTGL=0 if test "x$enable_opengl" = "xyes"; then - PKG_CHECK_MODULES([GST_GL], - [gstreamer-gl-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED], - [HAVE_GSTGL=1], [HAVE_GSTGL=0]) -fi - -if test $HAVE_GSTGL -eq 1; then - AC_CACHE_CHECK([for GStreamer OpenGL helper libraries], - [ac_cv_have_gst_gl_helpers], [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_GL_CFLAGS $GST_VIDEO_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$saved_LIBS" - AC_CHECK_HEADERS([gst/gl/gl.h], [:], [HAVE_GSTGL=0]) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[GstGLContext gl_context;]])], + PKG_CHECK_MODULES([GST_GL], + [gstreamer-gl-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED], + [ + HAVE_GSTGL=1 + AC_CACHE_CHECK([for GStreamer OpenGL helper libraries], + [ac_cv_have_gst_gl_helpers], + [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GST_GL_CFLAGS $GST_VIDEO_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$saved_LIBS" + AC_CHECK_HEADERS([gst/gl/gl.h], [], [HAVE_GSTGL=0]) + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ +#include + ]], + [[ +GstGLContext gl_context; + ]]) + ], [ac_cv_have_gst_gl_helpers="yes"], - [ac_cv_have_gst_gl_helpers="no" HAVE_GSTGL=0] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) + [ac_cv_have_gst_gl_helpers="no" HAVE_GSTGL=0]) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" + ]) + ], []) fi AM_CONDITIONAL([USE_GST_GL_HELPERS], [test $HAVE_GSTGL -eq 1]) AC_DEFINE_UNQUOTED([USE_GST_GL_HELPERS], [$HAVE_GSTGL], @@ -273,184 +284,186 @@ dnl --------------------------------------------------------------------------- dnl Check for DRM/libudev USE_DRM=0 if test "x$enable_drm" = "xyes"; then - PKG_CHECK_MODULES(DRM, [libdrm], [USE_DRM=1], [USE_DRM=0]) - PKG_CHECK_MODULES(UDEV, [libudev], [:], [USE_DRM=0]) - - if test $USE_DRM -eq 1; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $DRM_CFLAGS" - AC_CHECK_HEADERS([drm_fourcc.h], [:], [USE_DRM=0]) - CPPFLAGS="$saved_CPPFLAGS" - fi + PKG_CHECK_MODULES([DRM], [libdrm libudev], + [ + USE_DRM=1 + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $DRM_CFLAGS" + AC_CHECK_HEADERS([drm_fourcc.h], [], [USE_DRM=0]) + CPPFLAGS="$saved_CPPFLAGS" + ], []) fi dnl Check for X11 USE_X11=0 if test "x$enable_x11" = "xyes"; then - PKG_CHECK_MODULES(X11, [x11], [USE_X11=1], [USE_X11=0]) - if test $USE_X11 -eq 1; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $X11_CFLAGS" - AC_CHECK_HEADERS([X11/Xlib.h X11/Xutil.h X11/Xatom.h], [:], [USE_X11=0]) - CPPFLAGS="$saved_CPPFLAGS" - fi + PKG_CHECK_MODULES([X11], [x11], + [ + USE_X11=1 + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $X11_CFLAGS" + AC_CHECK_HEADERS([X11/Xlib.h X11/Xutil.h X11/Xatom.h], [], [USE_X11=0]) + CPPFLAGS="$saved_CPPFLAGS" + ], []) fi -dnl Check for XKB library HAVE_XKBLIB=0 -if test $USE_X11 -eq 1; then - AC_CHECK_HEADERS([X11/XKBlib.h], [HAVE_XKBLIB=1], [:]) -fi -if test $HAVE_XKBLIB -eq 1; then - AC_DEFINE_UNQUOTED([HAVE_XKBLIB], 1, - [Defined to 1 if the XKB extension exists.]) -fi - -dnl Check for XRandR HAVE_XRANDR=0 -if test $USE_X11 -eq 1; then - HAVE_XRANDR=1 - PKG_CHECK_MODULES([XRANDR], [xrandr], [:], [HAVE_XRANDR=0]) - if test $HAVE_XRANDR -eq 1; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $XRANDR_CFLAGS" - AC_CHECK_HEADERS([X11/extensions/Xrandr.h], [:], [HAVE_XRANDR=0]) - CPPFLAGS="$saved_CPPFLAGS" - fi -fi -if test $HAVE_XRANDR -eq 1; then - AC_DEFINE_UNQUOTED(HAVE_XRANDR, 1, - [Defined to 1 if the XRandR extension exists.]) -fi - -dnl Check for XRender HAVE_XRENDER=0 if test $USE_X11 -eq 1; then - HAVE_XRENDER=1 - PKG_CHECK_MODULES([XRENDER], [xrender], [:], [HAVE_XRENDER=0]) - if test $HAVE_XRENDER -eq 1; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $XRENDER_CFLAGS" - AC_CHECK_HEADERS([X11/extensions/Xrender.h], [:], [HAVE_XRENDER=0]) - CPPFLAGS="$saved_CPPFLAGS" - fi -fi -if test $HAVE_XRENDER -eq 1; then - AC_DEFINE_UNQUOTED([HAVE_XRENDER], [1], - [Defined to 1 if the XRender extension exists.]) + dnl Check for XKB library + HAVE_XKBLIB=1 + AC_CHECK_HEADERS([X11/XKBlib.h], [], [HAVE_XKBLIB=0]) + + dnl Check for XRandR + PKG_CHECK_MODULES([XRANDR], [xrandr], + [ + HAVE_XRANDR=1 + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $XRANDR_CFLAGS" + AC_CHECK_HEADERS([X11/extensions/Xrandr.h], [], [HAVE_XRANDR=0]) + CPPFLAGS="$saved_CPPFLAGS" + ], []) + + dnl Check for XRender + PKG_CHECK_MODULES([XRENDER], [xrender], + [ + HAVE_XRENDER=1 + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $XRENDER_CFLAGS" + AC_CHECK_HEADERS([X11/extensions/Xrender.h], [], [HAVE_XRENDER=0]) + CPPFLAGS="$saved_CPPFLAGS" + ], []) fi +AC_DEFINE_UNQUOTED([HAVE_XKBLIB], [$HAVE_XKBLIB], + [Defined to 1 if the XKB extension exists.]) +AC_DEFINE_UNQUOTED([HAVE_XRANDR], [$HAVE_XRANDR], + [Defined to 1 if the XRandR extension exists.]) +AC_DEFINE_UNQUOTED([HAVE_XRENDER], [$HAVE_XRENDER], + [Defined to 1 if the XRender extension exists.]) + dnl OpenGL GLES_VERSION_MASK=0 HAVE_GL=0 +HAVE_GLESv2=0 +HAVE_GLESv3=0 if test "x$enable_opengl" = "xyes"; then -case ",$GLAPI," in -(*,any,*|*,gl,*) - HAVE_GL=1 - PKG_CHECK_MODULES([GL], [gl], [:], [HAVE_GL=0]) - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GL_CFLAGS" - AC_CHECK_HEADERS([GL/gl.h GL/glext.h], [:], [HAVE_GL=0], [ + dnl OpenGL + case ",$GLAPI," in + (*,any,*|*,gl,*) + HAVE_GL=1 + PKG_CHECK_MODULES([GL], [gl], + [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GL_CFLAGS" + AC_CHECK_HEADERS([GL/gl.h GL/glext.h], [], [HAVE_GL=0], + [ #ifdef HAVE_GL_GL_H # include #endif - ]) - CPPFLAGS="$saved_CPPFLAGS" + ]) + CPPFLAGS="$saved_CPPFLAGS" + ], [HAVE_GL=0]) + GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GL "*" 1` ;; -esac -fi -GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GL "*" 1` + esac -dnl OpenGL|ESv2 -HAVE_GLESv2=0 -if test "x$enable_opengl" = "xyes"; then -case ",$GLAPI," in -(*,any,*|*,gles2,*) - HAVE_GLESv2=1 - PKG_CHECK_MODULES([GLES2], [glesv2], [:], [HAVE_GLESv2=0]) - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GLES2_CFLAGS" - AC_CHECK_HEADERS([GLES2/gl2.h GLES2/gl2ext.h], [:], - [HAVE_GLESv2=0], [ + dnl OpenGL|ESv2 + case ",$GLAPI," in + (*,any,*|*,gles2,*) + HAVE_GLESv2=1 + PKG_CHECK_MODULES([GLES2], [glesv2], + [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GLES2_CFLAGS" + AC_CHECK_HEADERS([GLES2/gl2.h GLES2/gl2ext.h], [], [HAVE_GLESv2=0], + [ #ifdef HAVE_GLES2_GL2_H # include #endif - ]) - CPPFLAGS="$saved_CPPFLAGS" + ]) + CPPFLAGS="$saved_CPPFLAGS" + ], [HAVE_GLESv2=0]) + GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GLESv2 "*" 4` ;; -esac -fi -GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GLESv2 "*" 4` + esac -dnl OpenGL|ESv3 -HAVE_GLESv3=0 -if test "x$enable_opengl" = "xyes"; then -case ",$GLAPI," in -(*,any,*|*,gles3,*) - HAVE_GLESv3=1 - PKG_CHECK_MODULES([GLES3], [glesv2], [:], [HAVE_GLESv3=0]) - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GLES3_CFLAGS" - AC_CHECK_HEADERS([GLES3/gl3.h GLES3/gl3ext.h GLES2/gl2ext.h], [:], - [HAVE_GLESv3=0], [ + dnl OpenGL|ESv3 + case ",$GLAPI," in + (*,any,*|*,gles3,*) + HAVE_GLESv3=1 + PKG_CHECK_MODULES([GLES3], [glesv2], + [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GLES3_CFLAGS" + AC_CHECK_HEADERS([GLES3/gl3.h GLES3/gl3ext.h GLES2/gl2ext.h], [], + [HAVE_GLESv3=0], + [ #ifdef HAVE_GLES3_GL3_H # include #endif - ]) - CPPFLAGS="$saved_CPPFLAGS" + ]) + CPPFLAGS="$saved_CPPFLAGS" + ], [HAVE_GLESv3=0]) + GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GLESv3 "*" 8` ;; -esac + esac fi -GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GLESv3 "*" 8` dnl ... GLX USE_GLX=0 if test "x$enable_glx" = "xyes" -a $HAVE_GL -eq 1 -a $USE_X11 -eq 1; then - USE_GLX=1 - saved_CPPFLAGS="$CPPFLAGS" - saved_LIBS="$LIBS" - CPPFLAGS="$CPPFLAGS $GL_CFLAGS" - LIBS="$LIBS $GL_LIBS" - AC_CHECK_HEADERS([GL/glx.h], [:], [USE_GLX=0], [ + USE_GLX=1 + + saved_CPPFLAGS="$CPPFLAGS" + saved_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $GL_CFLAGS" + LIBS="$LIBS $GL_LIBS" + AC_CHECK_HEADERS([GL/glx.h], [], [USE_GLX=0], + [ #ifdef HAVE_GL_GL_H # include #endif ]) - AC_CHECK_LIB([GL], [glXCreateContext], [:], [USE_GLX=0]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" + AC_CHECK_LIB([GL], [glXCreateContext], [], [USE_GLX=0]) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" fi dnl ... EGL USE_EGL=0 if test "x$enable_egl" = "xyes" -a $GLES_VERSION_MASK -ne 0; then - USE_EGL=1 - PKG_CHECK_MODULES([EGL], [egl], [:], [USE_EGL=0]) - saved_CPPFLAGS="$CPPFLAGS" - saved_LIBS="$LIBS" - AC_CHECK_HEADERS([EGL/egl.h], [:], [USE_EGL=0]) - AC_CHECK_LIB([EGL], [eglGetDisplay], [:], [USE_EGL=0]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" + PKG_CHECK_MODULES([EGL], [egl], + [ + USE_EGL=1 - dnl Check for GMODULE - GMODULE_VERSION_REQUIRED=gmodule_version - PKG_CHECK_MODULES([GMODULE], [gmodule-2.0 >= $GMODULE_VERSION_REQUIRED]) + saved_CPPFLAGS="$CPPFLAGS" + saved_LIBS="$LIBS" + AC_CHECK_HEADERS([EGL/egl.h], [], [USE_EGL=0]) + AC_CHECK_LIB([EGL], [eglGetDisplay], [], [USE_EGL=0]) + + dnl Check for GMODULE + GMODULE_VERSION_REQUIRED=gmodule_version + PKG_CHECK_MODULES([GMODULE], + [gmodule-2.0 >= $GMODULE_VERSION_REQUIRED]) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" + ], []) fi dnl Check for Wayland USE_WAYLAND=0 if test "x$enable_wayland" = "xyes"; then - PKG_CHECK_MODULES(WAYLAND, [wayland-client >= wayland_api_version], - [USE_WAYLAND=1], [USE_WAYLAND=0]) - - if test $USE_WAYLAND -eq 1; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $WAYLAND_CFLAGS" - AC_CHECK_HEADERS([wayland-client.h], [:], [USE_WAYLAND=0]) - CPPFLAGS="$saved_CPPFLAGS" - fi + PKG_CHECK_MODULES([WAYLAND], [wayland-client >= wayland_api_version], + [ + USE_WAYLAND=1 + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $WAYLAND_CFLAGS" + AC_CHECK_HEADERS([wayland-client.h], [], [USE_WAYLAND=0]) + CPPFLAGS="$saved_CPPFLAGS" + ], []) fi dnl --------------------------------------------------------------------------- @@ -462,17 +475,14 @@ PKG_CHECK_MODULES([LIBVA], [libva >= va_api_version]) VA_VERSION_STR=`$PKG_CONFIG --modversion libva` dnl VA/DRM API -HAVE_VA_DRM=0 if test $USE_DRM -eq 1; then - PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= va_api_drm_version], - [HAVE_VA_DRM=1], [USE_DRM=0]) - - if test $HAVE_VA_DRM -eq 1; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$LIBVA_DRM_CFLAGS" - AC_CHECK_HEADERS([va/va_drm.h], [:], [HAVE_VA_DRM=0 USE_DRM=0]) - CPPFLAGS="$saved_CPPFLAGS" - fi + PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= va_api_drm_version], + [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$LIBVA_DRM_CFLAGS" + AC_CHECK_HEADERS([va/va_drm.h], [], [USE_DRM=0]) + CPPFLAGS="$saved_CPPFLAGS" + ], [USE_DRM=0]) fi dnl VA/X11 API @@ -484,268 +494,321 @@ fi dnl Check for va_dec_jpeg.h header saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" -AC_CHECK_HEADERS([va/va_dec_jpeg.h], [], [], [#include ]) +AC_CHECK_HEADERS([va/va_dec_jpeg.h], [], [], + [ +#include + ]) CPPFLAGS="$saved_CPPFLAGS" dnl Check for JPEG decoding API (0.32.1+) USE_JPEG_DECODER=0 AC_CACHE_CHECK([for JPEG decoding API], - ac_cv_have_jpeg_decoding_api, [ + [ac_cv_have_jpeg_decoding_api], + [ saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $LIBVA_LIBS" AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #ifdef HAVE_VA_VA_DEC_JPEG_H - #include - #endif - ]], - [[VAPictureParameterBufferJPEGBaseline pic_param; - VASliceParameterBufferJPEGBaseline slice_param; - VAHuffmanTableBufferJPEGBaseline huffman_table; - VAIQMatrixBufferJPEGBaseline iq_matrix;]])], - [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=1], - [ac_cv_have_jpeg_decoding_api="no"] - ) + [ + AC_LANG_PROGRAM( + [[ +#include +#ifdef HAVE_VA_VA_DEC_JPEG_H +# include +#endif + ]], + [[ +VAPictureParameterBufferJPEGBaseline pic_param; +VASliceParameterBufferJPEGBaseline slice_param; +VAHuffmanTableBufferJPEGBaseline huffman_table; +VAIQMatrixBufferJPEGBaseline iq_matrix; + ]]) + ], + [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=1], + [ac_cv_have_jpeg_decoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" -]) + ]) dnl Check for va_dec_vp8.h header saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" -AC_CHECK_HEADERS([va/va_dec_vp8.h], [], [], [#include ]) +AC_CHECK_HEADERS([va/va_dec_vp8.h], [], [], + [ +#include + ]) CPPFLAGS="$saved_CPPFLAGS" dnl Check for VP8 decoding API (0.34+) USE_VP8_DECODER=0 AC_CACHE_CHECK([for VP8 decoding API], - ac_cv_have_vp8_decoding_api, [ + [ac_cv_have_vp8_decoding_api], + [ saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $LIBVA_LIBS" AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #ifdef HAVE_VA_VA_DEC_VP8_H - #include - #endif - ]], - [[VAPictureParameterBufferVP8 pic_param; - VASliceParameterBufferVP8 slice_param; - VAProbabilityDataBufferVP8 prob_data; - VAIQMatrixBufferVP8 iq_matrix; - slice_param.slice_data_offset = 0; - slice_param.slice_data_flag = 0;]])], - [ac_cv_have_vp8_decoding_api="yes" USE_VP8_DECODER=1], - [ac_cv_have_vp8_decoding_api="no"] - ) + [ + AC_LANG_PROGRAM( + [[ +#include +#ifdef HAVE_VA_VA_DEC_VP8_H +# include +#endif + ]], + [[ +VAPictureParameterBufferVP8 pic_param; +VASliceParameterBufferVP8 slice_param; +VAProbabilityDataBufferVP8 prob_data; +VAIQMatrixBufferVP8 iq_matrix; +slice_param.slice_data_offset = 0; +slice_param.slice_data_flag = 0; + ]]) + ], + [ac_cv_have_vp8_decoding_api="yes" USE_VP8_DECODER=1], + [ac_cv_have_vp8_decoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" -]) + ]) dnl Check for va_dec_vp9.h header saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" -AC_CHECK_HEADERS([va/va_dec_vp9.h], [], [], [#include ]) +AC_CHECK_HEADERS([va/va_dec_vp9.h], [], [], + [ +#include + ]) CPPFLAGS="$saved_CPPFLAGS" dnl Check for VP9 decoding API (0.37+) USE_VP9_DECODER=0 AC_CACHE_CHECK([for VP9 decoding API], - ac_cv_have_vp9_decoding_api, [ + [ac_cv_have_vp9_decoding_api], + [ saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $LIBVA_LIBS" AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #ifdef HAVE_VA_VA_DEC_VP9_H - #include - #endif - ]], - [[VADecPictureParameterBufferVP9 pic_param; - VASliceParameterBufferVP9 slice_param; - VASegmentParameterVP9 seg_param; - slice_param.slice_data_offset = 0; - slice_param.slice_data_flag = 0;]])], - [ac_cv_have_vp9_decoding_api="yes" USE_VP9_DECODER=$HAVE_GST_VP9_PARSER], - [ac_cv_have_vp9_decoding_api="no"] - ) + [ + AC_LANG_PROGRAM( + [[ +#include +#ifdef HAVE_VA_VA_DEC_VP9_H +# include +#endif + ]], + [[ +VADecPictureParameterBufferVP9 pic_param; +VASliceParameterBufferVP9 slice_param; +VASegmentParameterVP9 seg_param; +slice_param.slice_data_offset = 0; +slice_param.slice_data_flag = 0; + ]]) + ], + [ac_cv_have_vp9_decoding_api="yes" USE_VP9_DECODER=$HAVE_GST_VP9_PARSER], + [ac_cv_have_vp9_decoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" -]) + ]) dnl Check for va_dec_hevc.h header saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" -AC_CHECK_HEADERS([va/va_dec_hevc.h], [], [], [#include ]) +AC_CHECK_HEADERS([va/va_dec_hevc.h], [], [], + [ +#include + ]) CPPFLAGS="$saved_CPPFLAGS" dnl Check for HEVC decoding API (0.38+) USE_HEVC_DECODER=0 AC_CACHE_CHECK([for HEVC decoding API], - ac_cv_have_hevc_decoding_api, [ + [ac_cv_have_hevc_decoding_api], + [ saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $LIBVA_LIBS" AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #ifdef HAVE_VA_VA_DEC_HEVC_H - #include - #endif - ]], - [[VAPictureParameterBufferHEVC pic_param; - VASliceParameterBufferHEVC slice_param; - VAIQMatrixBufferHEVC iq_matrix; - slice_param.slice_data_offset = 0; - slice_param.slice_data_flag = 0;]])], - [ac_cv_have_hevc_decoding_api="yes" USE_HEVC_DECODER=1], - [ac_cv_have_hevc_decoding_api="no"] - ) + [ + AC_LANG_PROGRAM( + [[ +#include +#ifdef HAVE_VA_VA_DEC_HEVC_H +# include +#endif + ]], + [[ +VAPictureParameterBufferHEVC pic_param; +VASliceParameterBufferHEVC slice_param; +VAIQMatrixBufferHEVC iq_matrix; +slice_param.slice_data_offset = 0; +slice_param.slice_data_flag = 0; + ]]) + ], + [ac_cv_have_hevc_decoding_api="yes" USE_HEVC_DECODER=1], + [ac_cv_have_hevc_decoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" -]) + ]) dnl Check for vpp (video post-processing) support USE_VA_VPP=0 AC_CACHE_CHECK([for video post-postprocessing API], - ac_cv_have_va_vpp_api, [ + [ac_cv_have_va_vpp_api], + [ saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $LIBVA_LIBS" AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #include ]], - [[VADisplay va_dpy; - VAContextID vpp_ctx; - VAProcFilterType filters[VAProcFilterCount]; - unsigned int num_filters = VAProcFilterCount; - vaQueryVideoProcFilters(va_dpy, vpp_ctx, filters, &num_filters); - ]])], - [ac_cv_have_va_vpp_api="yes" USE_VA_VPP=1], - [ac_cv_have_va_vpp_api="no"] - ) + [ + AC_LANG_PROGRAM( + [[ +#include +#include + ]], + [[ +VADisplay va_dpy; +VAContextID vpp_ctx; +VAProcFilterType filters[VAProcFilterCount]; +unsigned int num_filters = VAProcFilterCount; +vaQueryVideoProcFilters(va_dpy, vpp_ctx, filters, &num_filters); + ]]) + ], + [ac_cv_have_va_vpp_api="yes" USE_VA_VPP=1], + [ac_cv_have_va_vpp_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" -]) + ]) dnl Check for encoding support USE_ENCODERS=0 +if test "x$enable_encoders" = "xyes"; then + PKG_CHECK_MODULES([LIBVA], [libva >= va_api_enc_version], + [ + USE_ENCODERS=1 + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$LIBVA_CFLAGS" + AC_CHECK_HEADERS([va/va_enc_mpeg2.h va/va_enc_h264.h], [], + [USE_ENCODERS=0], + [ +#include + ]) + CPPFLAGS="$saved_CPPFLAGS" + ], []) +fi + USE_JPEG_ENCODER=0 USE_VP8_ENCODER=0 USE_H265_ENCODER=0 -if test "x$enable_encoders" = "xyes"; then - PKG_CHECK_MODULES([LIBVA], [libva >= va_api_enc_version], - [HAVE_VA_ENC=1], [HAVE_VA_ENC=0]) +if test $USE_ENCODERS -eq 1; then + dnl Check for JPEG Encoding API (0.37.0+) + AC_CHECK_HEADERS([va/va_enc_jpeg.h], [], [], + [ +#include + ]) + AC_CACHE_CHECK([for JPEG encoding API], + [ac_cv_have_jpeg_encoding_api], + [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ +#include +#ifdef HAVE_VA_VA_ENC_JPEG_H +# include +#endif + ]], + [[ +VAEncPictureParameterBufferJPEG pic_param; +VAEncSliceParameterBufferJPEG slice_param; +VAQMatrixBufferJPEG q_matrix; + ]]) + ], + [ac_cv_have_jpeg_encoding_api="yes" USE_JPEG_ENCODER=1], + [ac_cv_have_jpeg_encoding_api="no"]) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" + ]) - if test $HAVE_VA_ENC -eq 1; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$LIBVA_CFLAGS" - AC_CHECK_HEADERS([va/va_enc_mpeg2.h va/va_enc_h264.h], - [USE_ENCODERS=1], [HAVE_VA_ENC=0 USE_ENCODERS=0], - [#include - ]) + dnl Check for VP8 Encoding API + AC_CHECK_HEADERS([va/va_enc_vp8.h], [], [], + [ +#include + ]) + AC_CACHE_CHECK([for VP8 encoding API], + [ac_cv_have_vp8_encoding_api], + [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ +#include +#ifdef HAVE_VA_VA_ENC_VP8_H +# include +#endif + ]], + [[ +VAEncSequenceParameterBufferVP8 seq_param; +VAEncPictureParameterBufferVP8 pic_param; +VAQMatrixBufferVP8 q_matrix; + ]]) + ], + [ac_cv_have_vp8_encoding_api="yes" USE_VP8_ENCODER=1], + [ac_cv_have_vp8_encoding_api="no"]) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" + ]) - dnl Check for JPEG Encoding API (0.37.0+) - AC_CHECK_HEADERS([va/va_enc_jpeg.h], - [USE_JPEG_ENCODER=1], [], - [#include - ]) - AC_CACHE_CHECK([for JPEG encoding API], - ac_cv_have_jpeg_encoding_api, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #ifdef HAVE_VA_VA_ENC_JPEG_H - #include - #endif - ]], - [[VAEncPictureParameterBufferJPEG pic_param; - VAEncSliceParameterBufferJPEG slice_param; - VAQMatrixBufferJPEG q_matrix;]])], - [ac_cv_have_jpeg_encoding_api="yes" USE_JPEG_ENCODER=1], - [ac_cv_have_jpeg_encoding_api="no"] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) - - dnl Check for VP8 Encoding API - AC_CHECK_HEADERS([va/va_enc_vp8.h], - [USE_VP8_ENCODER=1], [], - [#include - ]) - AC_CACHE_CHECK([for VP8 encoding API], - ac_cv_have_vp8_encoding_api, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #ifdef HAVE_VA_VA_ENC_VP8_H - #include - #endif - ]], - [[VAEncSequenceParameterBufferVP8 seq_param; - VAEncPictureParameterBufferVP8 pic_param; - VAQMatrixBufferVP8 q_matrix;]])], - [ac_cv_have_vp8_encoding_api="yes" USE_VP8_ENCODER=1], - [ac_cv_have_vp8_encoding_api="no" USE_VP8_ENCODER=0] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) - CPPFLAGS="$saved_CPPFLAGS" - - dnl Check for H265/HEVC Encoding API - AC_CHECK_HEADERS([va/va_enc_hevc.h], - [USE_H265_ENCODER=1], [], - [#include - ]) - AC_CACHE_CHECK([for HEVC encoding API], - ac_cv_have_hevc_encoding_api, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #ifdef HAVE_VA_VA_ENC_HEVC_H - #include - #endif - ]], - [[VAEncSequenceParameterBufferHEVC seq_param; - VAEncPictureParameterBufferHEVC pic_param; - VAEncSliceParameterBufferHEVC buf_param; - VAQMatrixBufferHEVC q_matrix;]])], - [ac_cv_have_hevc_encoding_api="yes" USE_H265_ENCODER=1], - [ac_cv_have_hevc_encoding_api="no" USE_H265_ENCODER=0] - ) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) - CPPFLAGS="$saved_CPPFLAGS" - fi + dnl Check for H265/HEVC Encoding API + AC_CHECK_HEADERS([va/va_enc_hevc.h], [], [], + [ +#include + ]) + AC_CACHE_CHECK([for HEVC encoding API], + [ac_cv_have_hevc_encoding_api], + [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ +#include +#ifdef HAVE_VA_VA_ENC_HEVC_H +# include +#endif + ]], + [[ +VAEncSequenceParameterBufferHEVC seq_param; +VAEncPictureParameterBufferHEVC pic_param; +VAEncSliceParameterBufferHEVC buf_param; +VAQMatrixBufferHEVC q_matrix; + ]]) + ], + [ac_cv_have_hevc_encoding_api="yes" USE_H265_ENCODER=1], + [ac_cv_have_hevc_encoding_api="no"]) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" + ]) fi dnl VA/Wayland API -if test "x$enable_wayland" = "xyes"; then +if test $USE_WAYLAND -eq 1; then PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= va_api_wld_version], [], [USE_WAYLAND=0]) fi From 616c426032dcb8be5880138471079d857498f82e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Jan 2016 19:01:43 +0100 Subject: [PATCH 2250/3781] build: hard-code an unneeded macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That macro is required for EGL's dynamic module loading, but since gstreamer-vaapi doesn't creates dynamic modules, it is not required anymore. That code in gst-libs/gst/vaapi/gstvaapidisplay_egl.c should be removed. Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 6b13d299c7..1706486977 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,6 @@ m4_define([default_glapi], [any]) # gstreamer-vaapi library (libtool) version number m4_define([gst_vaapi_lt_current], [7]) -m4_define([gst_vaapi_lt_current_bias], [7]) m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [0]) @@ -245,10 +244,6 @@ if test "x$enable_egl" = "xyes" -a $HAVE_GSTGL -ne 1; then enable_egl="no" fi -GST_VAAPI_MAJOR_VERSION=`expr gst_vaapi_lt_current - gst_vaapi_lt_current_bias` -AC_DEFINE_UNQUOTED([GST_VAAPI_MAJOR_VERSION_S], ["$GST_VAAPI_MAJOR_VERSION"], - [Defined to the string representation of gstreamer-vaapi major version]) - dnl GST_ALL_LDFLAGS: dnl LDFLAGS really should only contain flags, not libs - they get added before dnl whatevertarget_LIBS and -L flags here affect the rest of the linking @@ -881,6 +876,10 @@ AC_DEFINE_UNQUOTED([USE_WAYLAND], [$USE_WAYLAND], [Defined to 1 if WAYLAND is enabled]) AM_CONDITIONAL([USE_WAYLAND], [test $USE_WAYLAND -eq 1]) +dnl @TODO hack for egl's dynamic module loading. remove it! +AC_DEFINE_UNQUOTED([GST_VAAPI_MAJOR_VERSION_S], ["0"], + [Defined to the string representation of gstreamer-vaapi major version]) + AC_CONFIG_FILES([ Makefile docs/Makefile From f452769ddea7cda43ef0225d32dc80a9daee1242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Jan 2016 19:12:13 +0100 Subject: [PATCH 2251/3781] build: use common version variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 67 ++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/configure.ac b/configure.ac index 1706486977..5f46e65c34 100644 --- a/configure.ac +++ b/configure.ac @@ -20,9 +20,6 @@ m4_define([gst_vaapi_lt_age], [0]) # glib version number m4_define([glib_version], [2.32]) -# gmodule version number -m4_define([gmodule_version], [2.32]) - # gstreamer version number m4_define([gst_version], [1.6.3]) m4_define([gst_plugins_base_version], [1.6.3]) @@ -67,6 +64,21 @@ AC_ARG_VAR([GIT], [Path to git program, if any]) AC_PATH_PROG([GIT], [git]) AM_CONDITIONAL([HAVE_GIT], [test -n "$GIT"]) +dnl *** required versions of GStreamer stuff *** +GLIB_REQ=glib_version +GST_REQ=gst_version +GST_PBREQ=gst_plugins_base_version +GST_PBADREQ=gst_plugins_bad_version +WAYLAND_REQ=wayland_api_version +GTKDOC_REQ=gtkdoc_version + +dnl *** required versions of VA-API stuff *** +VAAPI_REQ=va_api_version +VAAPI_ENC_REQ=va_api_enc_version +VAAPI_DRM_REQ=va_api_drm_version +VAAPI_X11_REQ=va_api_x11_version +VAAPI_WLD_REQ=va_api_wld_version + dnl Initialize libtool LT_PREREQ([2.2.6]) LT_INIT @@ -110,15 +122,13 @@ dnl Check for basic libraries AC_CHECK_LIB([m], [tan]) dnl Check for Gtk doc -GTKDOC_VERSION=gtkdoc_version # gtkdocize greps for '^GTK_DOC_CHECK', so it needs to be on its own line m4_ifdef([GTK_DOC_CHECK], [ -GTK_DOC_CHECK([$GTKDOC_VERSION], [--flavour no-tmpl])], [ +GTK_DOC_CHECK([$GTKDOC_REQ], [--flavour no-tmpl])], [ AM_CONDITIONAL([ENABLE_GTK_DOC], [false])]) dnl Check for GLib -GLIB_VERSION_REQUIRED=glib_version -PKG_CHECK_MODULES([GLIB], [glib-2.0 >= $GLIB_VERSION_REQUIRED]) +PKG_CHECK_MODULES([GLIB], [glib-2.0 >= $GLIB_REQ]) dnl Check to see if dlopen is in default libraries (like Solaris, which dnl has it in libc), or if libdl is needed to get it. @@ -134,14 +144,8 @@ AC_SUBST([GST_PKG_VERSION]) AC_DEFINE_UNQUOTED([GST_PKG_VERSION_S], ["$GST_PKG_VERSION"], [Defined to the string representation of GStreamer API version]) -dnl Versions for GStreamer and plugins-base -GST_VERSION_REQUIRED=gst_version -GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version -GST_PLUGINS_BAD_VERSION_REQUIRED=gst_plugins_bad_version - dnl GStreamer Core -PKG_CHECK_MODULES([GST], - [gstreamer-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) +PKG_CHECK_MODULES([GST], [gstreamer-$GST_PKG_VERSION >= $GST_REQ]) AC_MSG_CHECKING([for GStreamer API version]) gst_api_version=`$PKG_CONFIG --modversion "gstreamer-$GST_PKG_VERSION"` @@ -152,28 +156,27 @@ AC_MSG_RESULT([$GST_API_VERSION]) AC_DEFINE_UNQUOTED([GST_API_VERSION_S], ["$GST_API_VERSION"], [Defined to the string representation of GStreamer version]) -PKG_CHECK_MODULES([GST_BASE], - [gstreamer-base-$GST_PKG_VERSION >= $GST_VERSION_REQUIRED]) +PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-$GST_PKG_VERSION >= $GST_REQ]) dnl GStreamer -base plugins PKG_CHECK_MODULES([GST_PLUGINS_BASE], - [gstreamer-plugins-base-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + [gstreamer-plugins-base-$GST_PKG_VERSION >= $GST_PBREQ]) dnl ... gst_dmabuf_memory_get_fd (gstreamer-allocators) PKG_CHECK_MODULES([GST_ALLOCATORS], - [gstreamer-allocators-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + [gstreamer-allocators-$GST_PKG_VERSION >= $GST_PBREQ]) dnl ... GstVideoOverlayComposition (gstreamer-video) PKG_CHECK_MODULES([GST_VIDEO], - [gstreamer-video-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + [gstreamer-video-$GST_PKG_VERSION >= $GST_PBREQ]) dnl ... GStreamer base utils (gstreamer-pbutils) PKG_CHECK_MODULES([GST_PBUTILS], - [gstreamer-pbutils-$GST_PKG_VERSION >= $GST_PLUGINS_BASE_VERSION_REQUIRED]) + [gstreamer-pbutils-$GST_PKG_VERSION >= $GST_PBREQ]) dnl ... bitstream parsers PKG_CHECK_MODULES([GST_CODEC_PARSERS], - [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED]) + [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PBADREQ]) dnl ... VP9 parser, with required extensions HAVE_GST_VP9_PARSER=0 @@ -207,7 +210,7 @@ dnl ... opengl helper libraries HAVE_GSTGL=0 if test "x$enable_opengl" = "xyes"; then PKG_CHECK_MODULES([GST_GL], - [gstreamer-gl-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED], + [gstreamer-gl-$GST_PKG_VERSION >= $GST_PBADREQ], [ HAVE_GSTGL=1 AC_CACHE_CHECK([for GStreamer OpenGL helper libraries], @@ -438,20 +441,18 @@ if test "x$enable_egl" = "xyes" -a $GLES_VERSION_MASK -ne 0; then saved_LIBS="$LIBS" AC_CHECK_HEADERS([EGL/egl.h], [], [USE_EGL=0]) AC_CHECK_LIB([EGL], [eglGetDisplay], [], [USE_EGL=0]) - - dnl Check for GMODULE - GMODULE_VERSION_REQUIRED=gmodule_version - PKG_CHECK_MODULES([GMODULE], - [gmodule-2.0 >= $GMODULE_VERSION_REQUIRED]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" + + dnl Check for GMODULE + PKG_CHECK_MODULES([GMODULE], [gmodule-2.0 >= $GLIB_REQ]) ], []) fi dnl Check for Wayland USE_WAYLAND=0 if test "x$enable_wayland" = "xyes"; then - PKG_CHECK_MODULES([WAYLAND], [wayland-client >= wayland_api_version], + PKG_CHECK_MODULES([WAYLAND], [wayland-client >= $WAYLAND_REQ], [ USE_WAYLAND=1 saved_CPPFLAGS="$CPPFLAGS" @@ -466,12 +467,12 @@ dnl -- VA-API -- dnl --------------------------------------------------------------------------- dnl Core API -PKG_CHECK_MODULES([LIBVA], [libva >= va_api_version]) +PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ]) VA_VERSION_STR=`$PKG_CONFIG --modversion libva` dnl VA/DRM API if test $USE_DRM -eq 1; then - PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= va_api_drm_version], + PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= $VAAPI_DRM_REQ], [ saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$LIBVA_DRM_CFLAGS" @@ -482,7 +483,7 @@ fi dnl VA/X11 API if test $USE_X11 -eq 1; then - PKG_CHECK_MODULES(LIBVA_X11, [libva-x11 >= va_api_x11_version], + PKG_CHECK_MODULES(LIBVA_X11, [libva-x11 >= $VAAPI_X11_REQ], [], [USE_X11=0]) fi @@ -683,7 +684,7 @@ vaQueryVideoProcFilters(va_dpy, vpp_ctx, filters, &num_filters); dnl Check for encoding support USE_ENCODERS=0 if test "x$enable_encoders" = "xyes"; then - PKG_CHECK_MODULES([LIBVA], [libva >= va_api_enc_version], + PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_ENC_REQ], [ USE_ENCODERS=1 saved_CPPFLAGS="$CPPFLAGS" @@ -804,7 +805,7 @@ fi dnl VA/Wayland API if test $USE_WAYLAND -eq 1; then - PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= va_api_wld_version], + PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= $VAAPI_WLD_REQ], [], [USE_WAYLAND=0]) fi From bef8caaaae0e0513d94cc5a23118d3176dafc3a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Jan 2016 13:13:56 +0100 Subject: [PATCH 2252/3781] build: honor configure's cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The user might enable --config-cache when calling configure script. If so, our configuration variables will not be correctly calculated. This patch extracts the value of our variables either from the cache or from the operation result. Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 5f46e65c34..8689f0a59f 100644 --- a/configure.ac +++ b/configure.ac @@ -197,11 +197,12 @@ AC_CACHE_CHECK([for VP9 parser], GstVp9FrameHdr frame_hdr; ]]) ], - [ac_cv_have_gst_vp9_parser="yes" HAVE_GST_VP9_PARSER=1], + [ac_cv_have_gst_vp9_parser="yes"], [ac_cv_have_gst_vp9_parser="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) +AS_IF([test "x$ac_cv_have_gst_vp9_parser" = "xyes"], [HAVE_GST_VP9_PARSER=1]) AS_IF([test "x$enable_glx" = "xyes" -o "x$enable_egl" = "xyes"], [enable_opengl="yes"], [enable_opengl="no"]) @@ -232,12 +233,13 @@ GstGLContext gl_context; ]]) ], [ac_cv_have_gst_gl_helpers="yes"], - [ac_cv_have_gst_gl_helpers="no" HAVE_GSTGL=0]) + [ac_cv_have_gst_gl_helpers="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) ], []) fi +AS_IF([test "x$ac_cv_have_gst_gl_helpers" = "xno"], [HAVE_GSTGL=0]) AM_CONDITIONAL([USE_GST_GL_HELPERS], [test $HAVE_GSTGL -eq 1]) AC_DEFINE_UNQUOTED([USE_GST_GL_HELPERS], [$HAVE_GSTGL], [Defined to 1 if GStreamer OpenGL helper libraries are available]) @@ -521,11 +523,12 @@ VAHuffmanTableBufferJPEGBaseline huffman_table; VAIQMatrixBufferJPEGBaseline iq_matrix; ]]) ], - [ac_cv_have_jpeg_decoding_api="yes" USE_JPEG_DECODER=1], + [ac_cv_have_jpeg_decoding_api="yes"], [ac_cv_have_jpeg_decoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) +AS_IF([test "x$ac_cv_have_jpeg_decoding_api" = "xyes"], [USE_JPEG_DECODER=1]) dnl Check for va_dec_vp8.h header saved_CPPFLAGS="$CPPFLAGS" @@ -563,11 +566,12 @@ slice_param.slice_data_offset = 0; slice_param.slice_data_flag = 0; ]]) ], - [ac_cv_have_vp8_decoding_api="yes" USE_VP8_DECODER=1], + [ac_cv_have_vp8_decoding_api="yes"], [ac_cv_have_vp8_decoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) +AS_IF([test "x$ac_cv_have_vp8_decoding_api" = "xyes"], [USE_VP8_DECODER=1]) dnl Check for va_dec_vp9.h header saved_CPPFLAGS="$CPPFLAGS" @@ -604,11 +608,13 @@ slice_param.slice_data_offset = 0; slice_param.slice_data_flag = 0; ]]) ], - [ac_cv_have_vp9_decoding_api="yes" USE_VP9_DECODER=$HAVE_GST_VP9_PARSER], + [ac_cv_have_vp9_decoding_api="yes"], [ac_cv_have_vp9_decoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) +AS_IF([test "x$ac_cv_have_vp9_decoding_api" = "xyes"], + [USE_VP9_DECODER=$HAVE_GST_VP9_PARSER]) dnl Check for va_dec_hevc.h header saved_CPPFLAGS="$CPPFLAGS" @@ -645,11 +651,12 @@ slice_param.slice_data_offset = 0; slice_param.slice_data_flag = 0; ]]) ], - [ac_cv_have_hevc_decoding_api="yes" USE_HEVC_DECODER=1], + [ac_cv_have_hevc_decoding_api="yes"], [ac_cv_have_hevc_decoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) +AS_IF([test "x$ac_cv_have_hevc_decoding_api" = "xyes"], [USE_HEVC_DECODER=1]) dnl Check for vpp (video post-processing) support USE_VA_VPP=0 @@ -675,11 +682,12 @@ unsigned int num_filters = VAProcFilterCount; vaQueryVideoProcFilters(va_dpy, vpp_ctx, filters, &num_filters); ]]) ], - [ac_cv_have_va_vpp_api="yes" USE_VA_VPP=1], + [ac_cv_have_va_vpp_api="yes"], [ac_cv_have_va_vpp_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) +AS_IF([test "x$ac_cv_have_va_vpp_api" = "xyes"], [USE_VA_VPP=1]) dnl Check for encoding support USE_ENCODERS=0 @@ -729,11 +737,12 @@ VAEncSliceParameterBufferJPEG slice_param; VAQMatrixBufferJPEG q_matrix; ]]) ], - [ac_cv_have_jpeg_encoding_api="yes" USE_JPEG_ENCODER=1], + [ac_cv_have_jpeg_encoding_api="yes"], [ac_cv_have_jpeg_encoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) + AS_IF([test "x$ac_cv_have_jpeg_encoding_api" = "xyes"], [USE_JPEG_ENCODER=1]) dnl Check for VP8 Encoding API AC_CHECK_HEADERS([va/va_enc_vp8.h], [], [], @@ -762,11 +771,12 @@ VAEncPictureParameterBufferVP8 pic_param; VAQMatrixBufferVP8 q_matrix; ]]) ], - [ac_cv_have_vp8_encoding_api="yes" USE_VP8_ENCODER=1], + [ac_cv_have_vp8_encoding_api="yes"], [ac_cv_have_vp8_encoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) + AS_IF([test "x$ac_cv_have_vp8_encoding_api" = "xyes"], [USE_VP8_ENCODER=1]) dnl Check for H265/HEVC Encoding API AC_CHECK_HEADERS([va/va_enc_hevc.h], [], [], @@ -796,11 +806,12 @@ VAEncSliceParameterBufferHEVC buf_param; VAQMatrixBufferHEVC q_matrix; ]]) ], - [ac_cv_have_hevc_encoding_api="yes" USE_H265_ENCODER=1], + [ac_cv_have_hevc_encoding_api="yes"], [ac_cv_have_hevc_encoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) + AS_IF([test "x$ac_cv_have_hevc_encoding_api" = "xyes"], [USE_H265_ENCODER=1]) fi dnl VA/Wayland API From 2a80f4b9090a0ecfff74dc341a09b9bbb5db644c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Jan 2016 18:06:29 +0100 Subject: [PATCH 2253/3781] decoder: update a deprecated function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Somehow this didn't show up earlier, but gst_adapter_prev_timestamp() got deprecated since GStreamer 1.0. This patch replace it with gst_adapter_prev_pts() Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapidecoder.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 2c9ccbeeb2..c4858ab526 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -332,8 +332,7 @@ decode_step (GstVaapiDecoder * decoder) input_size -= got_unit_size; if (gst_adapter_available (ps->output_adapter) == 0) { - ps->current_frame->pts = - gst_adapter_prev_timestamp (ps->input_adapter, NULL); + ps->current_frame->pts = gst_adapter_prev_pts (ps->input_adapter, NULL); } gst_adapter_push (ps->output_adapter, buffer); } From d83ffd123151d3a1f1858fcf0535f47c2b00b035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Jan 2016 15:51:49 +0100 Subject: [PATCH 2254/3781] plugins: use the same pre-processor macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In gstvaapipluginbase.c we are using the macro USE_GST_GL_HELPERS to guard the code related with GstGL. Nonetheless, in gstvaapipluginbase.h we are using HAVE_GST_GL_GL_H macro in order to include the GstGLContext's header. We should use only one to be homogeneous. This patch sets USE_GST_GL_HELPERS in the header file. Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapipluginbase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 24252e1166..27c7491cb4 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -31,7 +31,7 @@ #include #include -#ifdef HAVE_GST_GL_GL_H +#ifdef USE_GST_GL_HELPERS # include #endif From 0a9ce66ec75b3566bcec7892fb16cafac22442bc Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 27 Jan 2016 08:56:45 +0200 Subject: [PATCH 2255/3781] vaapidecode: Fix renegotiation for resolution change Always renegotiate the pool if the immediate frame which going to be pushed has a different un-cropped resolution than the already configured one. --- gst/vaapi/gstvaapidecode.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 45003e8e42..7b62ad0873 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -123,6 +123,8 @@ static gboolean gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query); static gboolean gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query); +static gboolean +gst_vaapidecode_negotiate (GstVaapiDecode * decode); static void gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, @@ -271,6 +273,27 @@ gst_vaapidecode_release (GstVaapiDecode * decode) gst_object_unref (decode); } +static gboolean +is_surface_resolution_changed (GstVideoDecoder *vdec, GstVaapiSurface *surface) +{ + guint surface_width, surface_height; + guint configured_width, configured_height; + GstVideoCodecState *state; + gboolean ret = FALSE; + + gst_vaapi_surface_get_size(surface, &surface_width, &surface_height); + + state = gst_video_decoder_get_output_state (vdec); + configured_width = GST_VIDEO_INFO_WIDTH (&state->info); + configured_height = GST_VIDEO_INFO_HEIGHT (&state->info); + gst_video_codec_state_unref (state); + + if (surface_width != configured_width || surface_height != configured_height) + ret = TRUE; + + return ret; +} + static GstFlowReturn gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, GstVideoCodecFrame * out_frame) @@ -285,6 +308,10 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) { proxy = gst_video_codec_frame_get_user_data (out_frame); + /* reconfigure if un-cropped surface resolution changed */ + if (is_surface_resolution_changed (vdec, GST_VAAPI_SURFACE_PROXY_SURFACE (proxy))) + gst_vaapidecode_negotiate (decode); + gst_vaapi_surface_proxy_set_destroy_notify (proxy, (GDestroyNotify) gst_vaapidecode_release, gst_object_ref (decode)); From eb2daed2a7495f9049126a198548d68938346096 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 28 Jan 2016 14:21:04 +0200 Subject: [PATCH 2256/3781] decoder: vp9: Fix crop rectangle setting Align with software vp9dec behaviour: Add crop rectangle only if display_width/display_height is less than the frame_hdr->width/frame_hdr->height --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 055ac09b7c..bb13e96196 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -442,13 +442,16 @@ decode_picture (GstVaapiDecoderVp9 * decoder, const guchar * buf, if (is_clone_pic) return GST_VAAPI_DECODER_STATUS_SUCCESS; - if (frame_hdr->display_size_enabled) { - crop_width = frame_hdr->display_width; - crop_height = frame_hdr->display_height; - } else if (priv->width > frame_hdr->width || priv->height > frame_hdr->height) { + if (priv->width > frame_hdr->width || priv->height > frame_hdr->height) { crop_width = frame_hdr->width; crop_height = frame_hdr->height; } + if (frame_hdr->display_size_enabled && + (frame_hdr->width > frame_hdr->display_width + || frame_hdr->height > frame_hdr->display_height)) { + crop_width = frame_hdr->display_width; + crop_height = frame_hdr->display_height; + } if (crop_width || crop_height) { GstVaapiRectangle crop_rect; crop_rect.x = 0; From 24168a2093b9a9380d6b47d1dc2600545489f6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 1 Feb 2016 13:02:13 +0000 Subject: [PATCH 2257/3781] vaapi: fix 'ISO C90 forbids mixed declarations and code' compiler warnings Declare variables at the beginning of a code block, which is how it's done in GStreamer. https://bugzilla.gnome.org/show_bug.cgi?id=759192 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 ++-- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 26 ++++++++++++++-------- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 11 +++++---- gst-libs/gst/vaapi/gstvaapifilter.c | 3 ++- gst/vaapi/gstvaapidecode.c | 16 +++++++------ gst/vaapi/gstvaapipluginbase.c | 3 ++- gst/vaapi/gstvaapipluginutil.c | 4 ++-- gst/vaapi/gstvaapipostproc.c | 7 ++++-- tests/simple-encoder.c | 7 ++++-- tests/test-filter.c | 5 +++-- 10 files changed, 54 insertions(+), 32 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index bd8f32a107..ffe9e5fbc5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -3626,8 +3626,6 @@ exec_ref_pic_marking_adaptive( { guint i; - GST_DEBUG("reference picture marking process (adaptive memory control)"); - typedef void (*exec_ref_pic_marking_adaptive_mmco_func)( GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, @@ -3644,6 +3642,8 @@ exec_ref_pic_marking_adaptive( exec_ref_pic_marking_adaptive_mmco_6, }; + GST_DEBUG("reference picture marking process (adaptive memory control)"); + for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) { GstH264RefPicMarking * const ref_pic_marking = &dec_ref_pic_marking->ref_pic_marking[i]; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index a4e2825746..3afb765eef 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -610,10 +610,12 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) if (priv->is_svh) { guint temp_ref = priv->svh_hdr.temporal_reference; + guint delta_ref; + if (temp_ref < priv->prev_t_ref) { temp_ref += 256; } - guint delta_ref = temp_ref - priv->prev_t_ref; + delta_ref = temp_ref - priv->prev_t_ref; pts = priv->sync_time; // see temporal_reference definition in spec, 30000/1001Hz @@ -707,6 +709,8 @@ fill_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) pic_param->num_macroblocks_in_gob = priv->svh_hdr.num_macroblocks_in_gob; } else { + int i; + // VOL parameters pic_param->vol_fields.bits.short_video_header = 0; pic_param->vol_fields.bits.chroma_format = priv->vol_hdr.chroma_format; @@ -720,7 +724,7 @@ fill_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) pic_param->vol_fields.bits.reversible_vlc = priv->vol_hdr.reversible_vlc; pic_param->vol_fields.bits.resync_marker_disable = priv->vol_hdr.resync_marker_disable; pic_param->no_of_sprite_warping_points = priv->vol_hdr.no_of_sprite_warping_points; - int i =0; + for (i=0; i<3 && ivol_hdr.no_of_sprite_warping_points ; i++) { pic_param->sprite_trajectory_du[i] = priv->sprite_trajectory.vop_ref_points[i]; pic_param->sprite_trajectory_dv[i] = priv->sprite_trajectory.sprite_ref_points[i]; @@ -839,6 +843,10 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) status = decode_gop(decoder, packet.data + packet.offset, packet.size); } else if (tos->type == GST_MPEG4_VIDEO_OBJ_PLANE) { + GstMpeg4Packet video_packet; + const guint8 *_data; + gint _data_size; + status = decode_picture(decoder, packet.data + packet.offset, packet.size); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; @@ -852,9 +860,8 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) * while MB doesn't start from byte boundary -- it is what 'macroblock_offset' * in slice refer to */ - const guint8 *_data = packet.data + packet.offset + priv->vop_hdr.size/8; - gint _data_size = packet.size - (priv->vop_hdr.size/8); - GstMpeg4Packet video_packet; + _data = packet.data + packet.offset + priv->vop_hdr.size/8; + _data_size = packet.size - (priv->vop_hdr.size/8); if (priv->vol_hdr.resync_marker_disable) { status = decode_slice(decoder, _data, _data_size, FALSE); @@ -862,11 +869,12 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) return status; } else { + GstMpeg4ParseResult ret = GST_MPEG4_PARSER_OK; + gboolean first_slice = TRUE; + // next start_code is required to determine the end of last slice _data_size += 4; - GstMpeg4ParseResult ret = GST_MPEG4_PARSER_OK; - gboolean first_slice = TRUE; while (_data_size > 0) { // we can skip user data here ret = gst_mpeg4_parse(&video_packet, TRUE, &priv->vop_hdr, _data, 0, _data_size); @@ -955,6 +963,8 @@ gst_vaapi_decoder_mpeg4_decode_codec_data(GstVaapiDecoder *base_decoder, GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; + GstMpeg4ParseResult result = GST_MPEG4_PARSER_OK; + GstMpeg4Packet packet; guchar *buf; guint pos, buf_size; @@ -968,8 +978,6 @@ gst_vaapi_decoder_mpeg4_decode_codec_data(GstVaapiDecoder *base_decoder, buf[buf_size-1] = 0xb2; pos = 0; - GstMpeg4Packet packet; - GstMpeg4ParseResult result = GST_MPEG4_PARSER_OK; while (result == GST_MPEG4_PARSER_OK && pos < buf_size) { result = gst_mpeg4_parse(&packet, FALSE, NULL, buf, pos, buf_size); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 758af7f2fe..3ad9378bd2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -591,11 +591,12 @@ bs_write_subset_sps (GstBitWriter * bs, for (i = 1; i <= num_views_minus1; i++) { guint32 num_anchor_refs_l0 = 0; + guint32 num_anchor_refs_l1 = 0; + WRITE_UE (bs, num_anchor_refs_l0); for (j = 0; j < num_anchor_refs_l0; j++) WRITE_UE (bs, 0); - guint32 num_anchor_refs_l1 = 0; WRITE_UE (bs, num_anchor_refs_l1); for (j = 0; j < num_anchor_refs_l1; j++) WRITE_UE (bs, 0); @@ -603,11 +604,12 @@ bs_write_subset_sps (GstBitWriter * bs, for (i = 1; i <= num_views_minus1; i++) { guint32 num_non_anchor_refs_l0 = 0; + guint32 num_non_anchor_refs_l1 = 0; + WRITE_UE (bs, num_non_anchor_refs_l0); for (j = 0; j < num_non_anchor_refs_l0; j++) WRITE_UE (bs, 0); - guint32 num_non_anchor_refs_l1 = 0; WRITE_UE (bs, num_non_anchor_refs_l1); for (j = 0; j < num_non_anchor_refs_l1; j++) WRITE_UE (bs, 0); @@ -2452,13 +2454,14 @@ reset_properties (GstVaapiEncoderH264 * encoder) for (i = 0; i < encoder->num_views; i++) { GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[i]; + ref_pool->max_reflist0_count = 1; ref_pool->max_reflist1_count = encoder->num_bframes > 0; ref_pool->max_ref_frames = ref_pool->max_reflist0_count + ref_pool->max_reflist1_count; - GstVaapiH264ViewReorderPool *const reorder_pool = - &encoder->reorder_pools[i]; reorder_pool->frame_index = 0; } } diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 343e2c7ef3..802e12ceec 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -596,11 +596,12 @@ get_operations_default (void) ensure_properties (); for (i = 0; i < N_PROPERTIES; i++) { + GstVaapiFilterOpData *op_data; GParamSpec *const pspec = g_properties[i]; if (!pspec) continue; - GstVaapiFilterOpData *const op_data = op_data_new (i, pspec); + op_data = op_data_new (i, pspec); if (!op_data) goto error; g_ptr_array_add (ops, op_data); diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 7b62ad0873..d7ed728a90 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -198,17 +198,18 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) { GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); GstVideoCodecState *state, *ref_state; + GstVaapiCapsFeature feature; + GstCapsFeatures *features = NULL; GstVideoInfo *vi; GstVideoFormat format = GST_VIDEO_FORMAT_I420; + GstClockTime latency; + gint fps_d, fps_n; if (!decode->input_state) return FALSE; ref_state = decode->input_state; - GstCapsFeatures *features = NULL; - GstVaapiCapsFeature feature; - feature = gst_vaapi_find_preferred_caps_feature (GST_VIDEO_DECODER_SRC_PAD (vdec), GST_VIDEO_INFO_FORMAT (&ref_state->info), &format); @@ -246,8 +247,8 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) gst_caps_replace (&decode->srcpad_caps, state->caps); gst_video_codec_state_unref (state); - gint fps_n = GST_VIDEO_INFO_FPS_N (vi); - gint fps_d = GST_VIDEO_INFO_FPS_D (vi); + fps_n = GST_VIDEO_INFO_FPS_N (vi); + fps_d = GST_VIDEO_INFO_FPS_D (vi); if (fps_n <= 0 || fps_d <= 0) { GST_DEBUG_OBJECT (decode, "forcing 25/1 framerate for latency calculation"); fps_n = 25; @@ -258,7 +259,7 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) * latency in general, with perfectly known unit boundaries (NALU, * AU), and up to 2 frames when we need to wait for the second frame * start to determine the first frame is complete */ - GstClockTime latency = gst_util_uint64_scale (2 * GST_SECOND, fps_d, fps_n); + latency = gst_util_uint64_scale (2 * GST_SECOND, fps_d, fps_n); gst_video_decoder_set_latency (vdec, latency, latency); return TRUE; @@ -464,6 +465,7 @@ gst_vaapidecode_handle_frame (GstVideoDecoder * vdec, { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstVaapiDecoderStatus status; + GstVaapiPluginBase *plugin; GstFlowReturn ret; if (!decode->input_state) @@ -478,7 +480,7 @@ gst_vaapidecode_handle_frame (GstVideoDecoder * vdec, if (!gst_video_decoder_negotiate (vdec)) goto not_negotiated; - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); + plugin = GST_VAAPI_PLUGIN_BASE (vdec); if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) goto not_negotiated; diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 45c32b593e..9e878cea24 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -180,12 +180,13 @@ error_create_proxy: void gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) { + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + klass->has_interface = default_has_interface; klass->display_changed = default_display_changed; plugin_parent_class = g_type_class_peek_parent (klass); - GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); element_class->set_context = GST_DEBUG_FUNCPTR (plugin_set_context); } diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index e07d2b61ca..7f628d8cd5 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -412,14 +412,14 @@ GstCaps * gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, const gchar * features_string) { + GstCapsFeatures *features; GstCaps *caps; caps = gst_vaapi_video_format_new_template_caps (format); if (!caps) return NULL; - GstCapsFeatures *const features = - gst_caps_features_new (features_string, NULL); + features = gst_caps_features_new (features_string, NULL); if (!features) { gst_caps_unref (caps); return NULL; diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index ab5b78821d..9583c27eae 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -479,6 +479,7 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, GstVaapiDeinterlaceMethod deint_method; guint flags, deint_flags; gboolean tff, deint, deint_refs, deint_changed; + const GstVideoCropMeta *crop_meta; GstVaapiRectangle *crop_rect = NULL; GstVaapiRectangle tmp_rect; @@ -527,7 +528,7 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, goto error_invalid_buffer; inbuf_surface = gst_vaapi_video_meta_get_surface (inbuf_meta); - GstVideoCropMeta *const crop_meta = gst_buffer_get_video_crop_meta (inbuf); + crop_meta = gst_buffer_get_video_crop_meta (inbuf); if (crop_meta) { crop_rect = &tmp_rect; crop_rect->x = crop_meta->x; @@ -974,11 +975,13 @@ expand_allowed_srcpad_caps (GstVaapiPostproc * postproc, GstCaps * caps) num_structures = gst_caps_get_size (caps); for (i = 0; i < num_structures; i++) { GstCapsFeatures *const features = gst_caps_get_features (caps, i); + GstStructure *structure; + if (gst_caps_features_contains (features, GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META)) continue; - GstStructure *const structure = gst_caps_get_structure (caps, i); + structure = gst_caps_get_structure (caps, i); if (!structure) continue; gst_structure_set_value (structure, "format", &value); diff --git a/tests/simple-encoder.c b/tests/simple-encoder.c index ae0c20de91..b424d69206 100644 --- a/tests/simple-encoder.c +++ b/tests/simple-encoder.c @@ -409,19 +409,22 @@ app_run (App * app) buffer_thread = g_thread_new ("get buffer thread", get_buffer_thread, app); while (1) { + GstVaapiSurfaceProxy *proxy; + GstVaapiSurface *surface; + if (!load_frame (app, image)) break; if (!gst_vaapi_image_unmap (image)) break; - GstVaapiSurfaceProxy *proxy = + proxy = gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL (pool)); if (!proxy) { g_warning ("Could not get surface proxy from pool."); break; } - GstVaapiSurface *surface = gst_vaapi_surface_proxy_get_surface (proxy); + surface = gst_vaapi_surface_proxy_get_surface (proxy); if (!surface) { g_warning ("Could not get surface from proxy."); break; diff --git a/tests/test-filter.c b/tests/test-filter.c index 05dfee9d11..0f681e8d6e 100644 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -246,12 +246,13 @@ parse_enum(const gchar *str, GType type, gint default_value, g_return_val_if_fail(out_value_ptr != NULL, FALSE); if (str) { + const GEnumValue *enum_value; GEnumClass * const enum_class = g_type_class_ref(type); + if (!enum_class) return FALSE; - const GEnumValue * const enum_value = - g_enum_get_value_by_nick(enum_class, str); + enum_value = g_enum_get_value_by_nick(enum_class, str); if (enum_value) out_value = enum_value->value; g_type_class_unref(enum_class); From ab28dea7c1e0ec284def41713c9e2c23169c607a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 1 Feb 2016 13:22:10 +0000 Subject: [PATCH 2258/3781] Fix some more compiler warning Two (false) compiler warnings about variables potentially being used uninitialized, and one about a variable being set but not used. https://bugzilla.gnome.org/show_bug.cgi?id=759192 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 26b8a4a625..4ac3cdc086 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -603,7 +603,7 @@ get_vps (GstVaapiDecoderH265 * decoder) static guint get_max_dec_frame_buffering (GstH265SPS * sps) { - guint max_dec_frame_buffering; + G_GNUC_UNUSED guint max_dec_frame_buffering; /* FIXME */ GstVaapiLevelH265 level; const GstVaapiH265LevelLimits *level_limits; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 3ad9378bd2..db65b2c0ee 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1511,7 +1511,7 @@ add_packed_sei_header (GstVaapiEncoderH264 * encoder, VAEncPackedHeaderParameterBuffer packed_sei_param = { 0 }; guint32 data_bit_size; guint8 buf_period_payload_size = 0, pic_timing_payload_size = 0; - guint8 *data, *buf_period_payload, *pic_timing_payload; + guint8 *data, *buf_period_payload = NULL, *pic_timing_payload = NULL; gboolean need_buf_period, need_pic_timing; gst_bit_writer_init (&bs_buf_period, 128 * 8); From bb2248ab663ea3e9a2bd124416a9d98548b09e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 3 Feb 2016 12:17:59 +0100 Subject: [PATCH 2259/3781] plugins: fix code style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minor code style changes by executing gst-indent in gst/vaapi directory. Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapidecode.c | 11 ++++++----- gst/vaapi/gstvaapidecodebin.c | 8 ++++---- gst/vaapi/gstvaapipluginutil.c | 9 ++++----- gst/vaapi/gstvaapisink.c | 6 ++++-- gst/vaapi/gstvaapivideomemory.c | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d7ed728a90..de61d14c4f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -123,8 +123,7 @@ static gboolean gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query); static gboolean gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query); -static gboolean -gst_vaapidecode_negotiate (GstVaapiDecode * decode); +static gboolean gst_vaapidecode_negotiate (GstVaapiDecode * decode); static void gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, @@ -275,14 +274,15 @@ gst_vaapidecode_release (GstVaapiDecode * decode) } static gboolean -is_surface_resolution_changed (GstVideoDecoder *vdec, GstVaapiSurface *surface) +is_surface_resolution_changed (GstVideoDecoder * vdec, + GstVaapiSurface * surface) { guint surface_width, surface_height; guint configured_width, configured_height; GstVideoCodecState *state; gboolean ret = FALSE; - gst_vaapi_surface_get_size(surface, &surface_width, &surface_height); + gst_vaapi_surface_get_size (surface, &surface_width, &surface_height); state = gst_video_decoder_get_output_state (vdec); configured_width = GST_VIDEO_INFO_WIDTH (&state->info); @@ -310,7 +310,8 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, proxy = gst_video_codec_frame_get_user_data (out_frame); /* reconfigure if un-cropped surface resolution changed */ - if (is_surface_resolution_changed (vdec, GST_VAAPI_SURFACE_PROXY_SURFACE (proxy))) + if (is_surface_resolution_changed (vdec, + GST_VAAPI_SURFACE_PROXY_SURFACE (proxy))) gst_vaapidecode_negotiate (decode); gst_vaapi_surface_proxy_set_destroy_notify (proxy, diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 98aaed4b7c..9ab354f93f 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -211,7 +211,7 @@ ensure_vpp (GstVaapiDecodeBin * vaapidecbin) return FALSE; vaapidecbin->has_vpp = gst_vaapi_display_has_video_processing (display) ? - HAS_VPP_YES : HAS_VPP_NO; + HAS_VPP_YES : HAS_VPP_NO; gst_vaapi_display_unref (display); @@ -219,7 +219,7 @@ ensure_vpp (GstVaapiDecodeBin * vaapidecbin) } static gboolean -gst_vaapi_decode_bin_reconfigure (GstVaapiDecodeBin* vaapidecbin) +gst_vaapi_decode_bin_reconfigure (GstVaapiDecodeBin * vaapidecbin) { if (!ensure_vpp (vaapidecbin)) return FALSE; @@ -325,7 +325,7 @@ gst_vaapi_decode_bin_handle_message (GstBin * bin, GstMessage * message) goto bail; vaapidecbin->has_vpp = gst_vaapi_display_has_video_processing (display) ? - HAS_VPP_YES : HAS_VPP_NO; + HAS_VPP_YES : HAS_VPP_NO; /* the underlying VA driver implementation doesn't support video * post-processing, hence we have to disable it */ @@ -362,7 +362,7 @@ gst_vaapi_decode_bin_change_state (GstElement * element, } ret = GST_ELEMENT_CLASS (gst_vaapi_decode_bin_parent_class)->change_state - (element, transition); + (element, transition); if (ret == GST_STATE_CHANGE_FAILURE) return ret; diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 7f628d8cd5..5293c8744b 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -609,7 +609,8 @@ _gst_caps_has_feature (const GstCaps * caps, const gchar * feature) } gboolean -gst_vaapi_caps_feature_contains (const GstCaps * caps, GstVaapiCapsFeature feature) +gst_vaapi_caps_feature_contains (const GstCaps * caps, + GstVaapiCapsFeature feature) { const gchar *feature_str; @@ -647,10 +648,8 @@ gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, vip->fps_n = vi.fps_n; vip->fps_d = vi.fps_d; - GST_VIDEO_INFO_MULTIVIEW_MODE (vip) = - GST_VIDEO_INFO_MULTIVIEW_MODE (&vi); - GST_VIDEO_INFO_MULTIVIEW_FLAGS (vip) = - GST_VIDEO_INFO_MULTIVIEW_FLAGS (&vi); + GST_VIDEO_INFO_MULTIVIEW_MODE (vip) = GST_VIDEO_INFO_MULTIVIEW_MODE (&vi); + GST_VIDEO_INFO_MULTIVIEW_FLAGS (vip) = GST_VIDEO_INFO_MULTIVIEW_FLAGS (&vi); } /** diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 75c588bf4a..f7fb5a2f6a 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1205,7 +1205,9 @@ gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) return NULL; if (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)) { - raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE (sink)); + raw_caps = + gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE + (sink)); if (raw_caps) { out_caps = gst_caps_make_writable (out_caps); gst_caps_append (out_caps, gst_caps_copy (raw_caps)); @@ -1332,7 +1334,7 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) ret = gst_vaapi_plugin_base_get_input_buffer (GST_VAAPI_PLUGIN_BASE (sink), src_buffer, &buffer); if (ret == GST_FLOW_NOT_SUPPORTED) - return GST_FLOW_OK; /* let's ignore the frame if it couldn't be uploaded */ + return GST_FLOW_OK; /* let's ignore the frame if it couldn't be uploaded */ if (ret != GST_FLOW_OK) return ret; diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index de4e092eb6..3cf4746b14 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -717,7 +717,7 @@ allocator_configure_image_info (GstVaapiDisplay * display, gst_video_info_set_format (&allocator->image_info, GST_VIDEO_FORMAT_I420, GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); else - allocator->image_info = *vinfo; + allocator->image_info = *vinfo; image = new_image (display, &allocator->image_info); if (!image) From a0b325c19afe0e67bb8093606425dda2723f0c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 2 Feb 2016 17:31:02 +0100 Subject: [PATCH 2260/3781] libs: avoid gst-indent mess up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guard pieces of code to avoid gst-ident to mess up the following code. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapicodedbuffer.c | 2 + gst-libs/gst/vaapi/gstvaapiwindow_egl.c | 48 ++++++++++++------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodedbuffer.c b/gst-libs/gst/vaapi/gstvaapicodedbuffer.c index acdc10632e..5ae15cf783 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbuffer.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbuffer.c @@ -93,8 +93,10 @@ coded_buffer_unmap (GstVaapiCodedBuffer * buf) GST_VAAPI_OBJECT_UNLOCK_DISPLAY (buf); } +/* *INDENT-OFF* */ #define gst_vaapi_coded_buffer_finalize coded_buffer_destroy GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiCodedBuffer, gst_vaapi_coded_buffer) +/* *INDENT-ON* */ /* * gst_vaapi_coded_buffer_new: diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c index 006ca2eb57..412e3a2d4c 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c @@ -96,34 +96,32 @@ typedef struct gboolean success; /* result */ } UploadSurfaceArgs; +/* *IDENT-OFF* */ static const gchar *vert_shader_text = - "#ifdef GL_ES\n" - "precision mediump float;\n" - "#endif\n" - "\n" - "uniform mat4 proj;\n" - "\n" - "attribute vec2 position;\n" - "attribute vec2 texcoord;\n" - "varying vec2 v_texcoord;\n" - "\n" - "void main () {\n" - " gl_Position = proj * vec4 (position, 0.0, 1.0);\n" - " v_texcoord = texcoord;\n" - "}\n"; + "#ifdef GL_ES \n" + "precision mediump float; \n" + "#endif \n" + "uniform mat4 proj; \n" + "attribute vec2 position; \n" + "attribute vec2 texcoord; \n" + "varying vec2 v_texcoord; \n" + "void main () \n" + "{ \n" + " gl_Position = proj * vec4 (position, 0.0, 1.0); \n" + " v_texcoord = texcoord; \n" + "} \n"; static const gchar *frag_shader_text_rgba = - "#ifdef GL_ES\n" - "precision mediump float;\n" - "#endif\n" - "\n" - "uniform sampler2D tex0;\n" - "\n" - "varying vec2 v_texcoord;\n" - "\n" - "void main () {\n" - " gl_FragColor = texture2D (tex0, v_texcoord);\n" - "}\n"; + "#ifdef GL_ES \n" + "precision mediump float; \n" + "#endif \n" + "uniform sampler2D tex0; \n" + "varying vec2 v_texcoord; \n" + "void main () \n" + "{ \n" + " gl_FragColor = texture2D (tex0, v_texcoord); \n" + "} \n"; +/* *IDENT-ON* */ static gboolean ensure_texture (GstVaapiWindowEGL * window, guint width, guint height) From 02c0e6c183531ebc4c05c782d95c7c2f5b629da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 2 Feb 2016 17:50:19 +0100 Subject: [PATCH 2261/3781] libs: trivial comment style fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapicodedbufferpool.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiimagepool.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 2 +- gst-libs/gst/vaapi/gstvaapitexture_egl.c | 4 ++-- gst-libs/gst/vaapi/gstvaapitexture_glx.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c index ef12849574..9b09ec6538 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c @@ -36,7 +36,7 @@ */ struct _GstVaapiCodedBufferPool { - /*< private >*/ + /*< private > */ GstVaapiVideoPool parent_instance; GstVaapiContext *context; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index 3e078b02f7..3641a61b0d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -69,7 +69,7 @@ struct _GstVaapiDecoderVp8Private */ struct _GstVaapiDecoderVp8 { - /*< private >*/ + /*< private > */ GstVaapiDecoder parent_instance; GstVaapiDecoderVp8Private priv; @@ -82,7 +82,7 @@ struct _GstVaapiDecoderVp8 */ struct _GstVaapiDecoderVp8Class { - /*< private >*/ + /*< private > */ GstVaapiDecoderClass parent_class; }; diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 377f050c4d..a6b0b58f23 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -41,7 +41,7 @@ */ struct _GstVaapiImagePool { - /*< private >*/ + /*< private > */ GstVaapiVideoPool parent_instance; GstVideoFormat format; diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 65bc65c677..c777194b63 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -41,7 +41,7 @@ */ struct _GstVaapiSurfacePool { - /*< private >*/ + /*< private > */ GstVaapiVideoPool parent_instance; GstVaapiChromaType chroma_type; diff --git a/gst-libs/gst/vaapi/gstvaapitexture_egl.c b/gst-libs/gst/vaapi/gstvaapitexture_egl.c index b350b22fff..1df21e3a3b 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_egl.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_egl.c @@ -50,7 +50,7 @@ typedef struct _GstVaapiTextureEGLClass GstVaapiTextureEGLClass; */ struct _GstVaapiTextureEGL { - /*< private >*/ + /*< private > */ GstVaapiTexture parent_instance; EglContext *egl_context; @@ -66,7 +66,7 @@ struct _GstVaapiTextureEGL */ struct _GstVaapiTextureEGLClass { - /*< private >*/ + /*< private > */ GstVaapiTextureClass parent_class; }; diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.c b/gst-libs/gst/vaapi/gstvaapitexture_glx.c index dc931f740f..b1e641bfbf 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_glx.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.c @@ -54,7 +54,7 @@ typedef struct _GstVaapiTextureGLXClass GstVaapiTextureGLXClass; */ struct _GstVaapiTextureGLX { - /*< private >*/ + /*< private > */ GstVaapiTexture parent_instance; GLContextState *gl_context; @@ -69,7 +69,7 @@ struct _GstVaapiTextureGLX */ struct _GstVaapiTextureGLXClass { - /*< private >*/ + /*< private > */ GstVaapiTextureClass parent_class; }; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c index ae49a07cb0..fdbdd2d8c8 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -42,7 +42,7 @@ typedef struct _GstVaapiWindowDRMClass GstVaapiWindowDRMClass; */ struct _GstVaapiWindowDRM { - /*< private >*/ + /*< private > */ GstVaapiWindow parent_instance; }; @@ -53,7 +53,7 @@ struct _GstVaapiWindowDRM */ struct _GstVaapiWindowDRMClass { - /*< private >*/ + /*< private > */ GstVaapiWindowClass parent_instance; }; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 13eac3f450..32d3b7a0be 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -64,7 +64,7 @@ struct _GstVaapiWindowGLXPrivate */ struct _GstVaapiWindowGLX { - /*< private >*/ + /*< private > */ GstVaapiWindowX11 parent_instance; GstVaapiWindowGLXPrivate priv; @@ -77,7 +77,7 @@ struct _GstVaapiWindowGLX */ struct _GstVaapiWindowGLXClass { - /*< private >*/ + /*< private > */ GstVaapiWindowX11Class parent_class; GstVaapiObjectFinalizeFunc parent_finalize; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index aab48793f4..0b4dd2fa39 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -120,7 +120,7 @@ struct _GstVaapiWindowWaylandPrivate */ struct _GstVaapiWindowWayland { - /*< private >*/ + /*< private > */ GstVaapiWindow parent_instance; GstVaapiWindowWaylandPrivate priv; @@ -133,7 +133,7 @@ struct _GstVaapiWindowWayland */ struct _GstVaapiWindowWaylandClass { - /*< private >*/ + /*< private > */ GstVaapiWindowClass parent_class; }; From 28d01c08576933f1ccc41456f80730a689de0508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 2 Feb 2016 17:59:57 +0100 Subject: [PATCH 2262/3781] libs: small code style fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This a set of small code style fixes detected as-is by gst-indent. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 3 +- gst-libs/gst/vaapi/gstvaapicodedbufferpool.c | 6 +- gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder.c | 6 +- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 12 +-- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 3 +- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 6 +- gst-libs/gst/vaapi/gstvaapiencoder.c | 9 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 83 ++++++++++--------- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 17 ++-- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 3 +- gst-libs/gst/vaapi/gstvaapifilter.c | 9 +- gst-libs/gst/vaapi/gstvaapiimagepool.c | 3 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 3 +- gst-libs/gst/vaapi/gstvaapiutils_egl.c | 23 +++-- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 6 +- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 6 +- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 12 +-- gst-libs/gst/vaapi/gstvaapiwindow.c | 3 +- gst-libs/gst/vaapi/gstvaapiwindow_egl.c | 4 +- 22 files changed, 118 insertions(+), 105 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index edf4b35e42..06c52e640a 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -76,8 +76,7 @@ gst_vaapi_codec_object_new (const GstVaapiCodecObjectClass * object_class, GstVaapiCodecObject *obj; GstVaapiCodecObjectConstructorArgs args; - obj = - (GstVaapiCodecObject *) + obj = (GstVaapiCodecObject *) gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS (object_class)); if (!obj) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c index 9b09ec6538..e2475536de 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c @@ -69,9 +69,9 @@ static inline const GstVaapiMiniObjectClass * gst_vaapi_coded_buffer_pool_class (void) { static const GstVaapiVideoPoolClass GstVaapiCodedBufferPoolClass = { - { sizeof (GstVaapiCodedBufferPool), - (GDestroyNotify)coded_buffer_pool_finalize }, - + {sizeof (GstVaapiCodedBufferPool), + (GDestroyNotify) coded_buffer_pool_finalize} + , .alloc_object = coded_buffer_pool_alloc_object }; return GST_VAAPI_MINI_OBJECT_CLASS (&GstVaapiCodedBufferPoolClass); diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c index bf173ab971..bcf471abf2 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c @@ -61,7 +61,7 @@ gst_vaapi_coded_buffer_proxy_class (void) { static const GstVaapiMiniObjectClass GstVaapiCodedBufferProxyClass = { sizeof (GstVaapiCodedBufferProxy), - (GDestroyNotify)coded_buffer_proxy_finalize + (GDestroyNotify) coded_buffer_proxy_finalize }; return &GstVaapiCodedBufferProxyClass; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index c4858ab526..7de5276c0f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -38,8 +38,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -static void -drop_frame (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame); +static void drop_frame (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame); static void parser_state_finalize (GstVaapiParserState * ps) @@ -933,7 +932,8 @@ gst_vaapi_decoder_set_multiview_mode (GstVaapiDecoder * decoder, if (GST_VIDEO_INFO_VIEWS (info) != views || GST_VIDEO_INFO_MULTIVIEW_MODE (info) != mv_mode || GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) != mv_flags) { - const gchar *mv_mode_str = gst_video_multiview_mode_to_caps_string (mv_mode); + const gchar *mv_mode_str = + gst_video_multiview_mode_to_caps_string (mv_mode); GST_DEBUG ("Multiview mode changed to %s flags 0x%x views %d", mv_mode_str, mv_flags, views); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 4ac3cdc086..6170b6a54c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1102,7 +1102,9 @@ ensure_context (GstVaapiDecoderH265 * decoder, GstH265SPS * sps) priv->profile = profile; } - chroma_type = gst_vaapi_utils_h265_get_chroma_type (sps->chroma_format_idc, sps->bit_depth_luma_minus8 + 8); + chroma_type = + gst_vaapi_utils_h265_get_chroma_type (sps->chroma_format_idc, + sps->bit_depth_luma_minus8 + 8); if (!chroma_type) { GST_ERROR ("unsupported chroma_format_idc %u", sps->chroma_format_idc); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; @@ -1885,8 +1887,8 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) COPY_BFM (slice_parsing_fields, pps, cabac_init_present_flag); COPY_BFM (slice_parsing_fields, pps, output_flag_present_flag); COPY_BFM (slice_parsing_fields, pps, dependent_slice_segments_enabled_flag); - pic_param->slice_parsing_fields. - bits.pps_slice_chroma_qp_offsets_present_flag = + pic_param->slice_parsing_fields.bits. + pps_slice_chroma_qp_offsets_present_flag = pps->slice_chroma_qp_offsets_present_flag; COPY_BFM (slice_parsing_fields, sps, sample_adaptive_offset_enabled_flag); COPY_BFM (slice_parsing_fields, pps, deblocking_filter_override_enabled_flag); @@ -2472,8 +2474,8 @@ fill_slice (GstVaapiDecoderH265 * decoder, slice_hdr->temporal_mvp_enabled_flag; slice_param->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag = slice_hdr->deblocking_filter_disabled_flag; - slice_param->LongSliceFlags. - fields.slice_loop_filter_across_slices_enabled_flag = + slice_param->LongSliceFlags.fields. + slice_loop_filter_across_slices_enabled_flag = slice_hdr->loop_filter_across_slices_enabled_flag; if (!slice_hdr->temporal_mvp_enabled_flag) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 092befddc7..20d4f55159 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -211,8 +211,7 @@ gst_vaapi_picture_new_clone (GstVaapiPicture * picture) 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); + picture->param_size, picture, 0, GST_VAAPI_CREATE_PICTURE_FLAG_CLONE); if (!object) return NULL; return GST_VAAPI_PICTURE_CAST (object); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index 3641a61b0d..0a50740625 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -262,7 +262,7 @@ init_picture (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture) 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; + 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); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 44b6f00a1f..9de677b185 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1627,8 +1627,8 @@ gst_vaapi_display_get_subpicture_formats (GstVaapiDisplay * display) if (!ensure_subpicture_formats (display)) return NULL; - return get_formats (GST_VAAPI_DISPLAY_GET_PRIVATE (display)-> - subpicture_formats); + return + get_formats (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->subpicture_formats); } /** @@ -2146,5 +2146,5 @@ gst_vaapi_display_has_opengl (GstVaapiDisplay * display) klass = GST_VAAPI_DISPLAY_GET_CLASS (display); return (klass->display_type == GST_VAAPI_DISPLAY_TYPE_GLX || - klass->display_type == GST_VAAPI_DISPLAY_TYPE_EGL); + klass->display_type == GST_VAAPI_DISPLAY_TYPE_EGL); } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index ebd5d3a21d..cf77864804 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -551,8 +551,9 @@ get_packed_headers (GstVaapiEncoder * encoder) if (cdata->codec == GST_VAAPI_CODEC_JPEG) { #if !VA_CHECK_VERSION(0,37,1) encoder->packed_headers = VA_ENC_PACKED_HEADER_RAW_DATA; - GST_DEBUG ("Hard coding the packed header flag value to VA_ENC_PACKED_HEADER_RAW_DATA," - "This is a work around for the driver bug"); + GST_DEBUG ("Hard coding the packed header flag value to " + "VA_ENC_PACKED_HEADER_RAW_DATA. This is a work around for the driver " + "bug"); #endif } @@ -564,7 +565,7 @@ is_chroma_type_supported (GstVaapiEncoder * encoder) { GstVaapiContextInfo *const cip = &encoder->context_info; const GstVideoFormat fmt = - GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); + GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); guint format = 0; if (fmt == GST_VIDEO_FORMAT_ENCODED) @@ -597,7 +598,7 @@ set_context_info (GstVaapiEncoder * encoder) GstVaapiContextInfo *const cip = &encoder->context_info; GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; const GstVideoFormat format = - GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); + GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); const GstVaapiEncoderClassData *const cdata = GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index db65b2c0ee..7ad5637986 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -124,7 +124,7 @@ typedef struct _GstVaapiH264ViewReorderPool GQueue reorder_frame_list; guint reorder_state; guint frame_index; - guint frame_count; /* monotonically increasing with in every idr period */ + guint frame_count; /* monotonically increasing with in every idr period */ guint cur_frame_num; guint cur_present_index; } GstVaapiH264ViewReorderPool; @@ -567,7 +567,8 @@ bs_write_sps (GstBitWriter * bs, static gboolean bs_write_subset_sps (GstBitWriter * bs, const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, - guint num_views, guint16 *view_ids, const VAEncMiscParameterHRD * hrd_params) + guint num_views, guint16 * view_ids, + const VAEncMiscParameterHRD * hrd_params) { guint32 i, j, k; @@ -779,7 +780,7 @@ struct _GstVaapiEncoderH264 /* MVC */ gboolean is_mvc; - guint32 view_idx; /* View Order Index (VOIdx) */ + guint32 view_idx; /* View Order Index (VOIdx) */ guint32 num_views; guint16 view_ids[MAX_NUM_VIEWS]; GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS]; @@ -805,11 +806,12 @@ bs_write_sei_buf_period (GstBitWriter * bs, initial_cpb_removal_delay = encoder->cpb_length * 45; /* initial_cpb_remvoal_dealy */ - WRITE_UINT32 (bs, initial_cpb_removal_delay, initial_cpb_removal_delay_length); + WRITE_UINT32 (bs, initial_cpb_removal_delay, + initial_cpb_removal_delay_length); /* initial_cpb_removal_delay_offset */ WRITE_UINT32 (bs, initial_cpb_removal_delay_offset, - initial_cpb_removal_delay_length); + initial_cpb_removal_delay_length); /* VclHrdBpPresentFlag == FALSE */ return TRUE; @@ -1421,8 +1423,8 @@ add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder, WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS); - bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views, encoder->view_ids, - &hrd_params); + bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views, + encoder->view_ids, &hrd_params); g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); @@ -1503,8 +1505,7 @@ bs_error: static gboolean add_packed_sei_header (GstVaapiEncoderH264 * encoder, - GstVaapiEncPicture * picture, - GstVaapiH264SeiPayloadType payloadtype) + GstVaapiEncPicture * picture, GstVaapiH264SeiPayloadType payloadtype) { GstVaapiEncPackedHeader *packed_sei; GstBitWriter bs, bs_buf_period, bs_pic_timing; @@ -1526,9 +1527,8 @@ add_packed_sei_header (GstVaapiEncoderH264 * encoder, bs_write_sei_buf_period (&bs_buf_period, encoder, picture); /* Write byte alignment bits */ if (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period) % 8 != 0) - bs_write_trailing_bits(&bs_buf_period); - buf_period_payload_size = - (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period)) / 8; + bs_write_trailing_bits (&bs_buf_period); + buf_period_payload_size = (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period)) / 8; buf_period_payload = GST_BIT_WRITER_DATA (&bs_buf_period); } @@ -1538,9 +1538,8 @@ add_packed_sei_header (GstVaapiEncoderH264 * encoder, bs_write_sei_pic_timing (&bs_pic_timing, encoder, picture); /* Write byte alignment bits */ if (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing) % 8 != 0) - bs_write_trailing_bits(&bs_pic_timing); - pic_timing_payload_size = - (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing)) / 8; + bs_write_trailing_bits (&bs_pic_timing); + pic_timing_payload_size = (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing)) / 8; pic_timing_payload = GST_BIT_WRITER_DATA (&bs_pic_timing); } @@ -1697,7 +1696,8 @@ add_packed_slice_header (GstVaapiEncoderH264 * encoder, /* pack nal_unit_header_mvc_extension() for the non base view */ if (encoder->is_mvc && encoder->view_idx) { bs_write_nal_header (&bs, nal_ref_idc, GST_H264_NAL_SLICE_EXT); - bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_ids[encoder->view_idx]); + bs_write_nal_header_mvc_extension (&bs, picture, + encoder->view_ids[encoder->view_idx]); } else bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); @@ -2165,11 +2165,13 @@ ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) /* add subset sps for non-base view and sps for base view */ if (encoder->is_mvc && encoder->view_idx) { - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_SEQUENCE) + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_SEQUENCE) && !add_packed_sequence_header_mvc (encoder, picture, sequence)) goto error_create_packed_seq_hdr; } else { - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_SEQUENCE) + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_SEQUENCE) && !add_packed_sequence_header (encoder, picture, sequence)) goto error_create_packed_seq_hdr; } @@ -2236,15 +2238,15 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) if ((GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) && (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_MISC) && - !add_packed_sei_header (encoder, picture, + !add_packed_sei_header (encoder, picture, GST_VAAPI_H264_SEI_BUF_PERIOD | GST_VAAPI_H264_SEI_PIC_TIMING)) goto error_create_packed_sei_hdr; else if (!GST_VAAPI_ENC_PICTURE_IS_IDR (picture) && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & - VA_ENC_PACKED_HEADER_MISC) && - !add_packed_sei_header (encoder, picture, - GST_VAAPI_H264_SEI_PIC_TIMING)) + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_MISC) && + !add_packed_sei_header (encoder, picture, + GST_VAAPI_H264_SEI_PIC_TIMING)) goto error_create_packed_sei_hdr; } @@ -2273,7 +2275,8 @@ ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, return FALSE; if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_PICTURE) + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_PICTURE) && !add_packed_picture_header (encoder, picture)) { GST_ERROR ("set picture packed header failed"); return FALSE; @@ -2797,8 +2800,10 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) } /* Take number of MVC views from input caps if provided */ - if (GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME || - GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME) + if (GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == + GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME + || GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == + GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME) encoder->num_views = GST_VIDEO_INFO_VIEWS (vip); encoder->is_mvc = encoder->num_views > 1; @@ -2916,23 +2921,21 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: encoder->num_views = g_value_get_uint (value); break; - case GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS: - { - guint i; - GValueArray *view_ids = g_value_get_boxed (value); + case GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS:{ + guint i; + GValueArray *view_ids = g_value_get_boxed (value); - if (view_ids == NULL) { - for (i = 0; i < encoder->num_views; i++) - encoder->view_ids[i] = i; - } - else { - g_assert (view_ids->n_values <= encoder->num_views); + if (view_ids == NULL) { + for (i = 0; i < encoder->num_views; i++) + encoder->view_ids[i] = i; + } else { + g_assert (view_ids->n_values <= encoder->num_views); - for (i = 0; i < encoder->num_views; i++) { - GValue *val = g_value_array_get_nth (view_ids, i); - encoder->view_ids[i] = g_value_get_uint (val); - } + for (i = 0; i < encoder->num_views; i++) { + GValue *val = g_value_array_get_nth (view_ids, i); + encoder->view_ids[i] = g_value_get_uint (val); } + } break; } default: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 6d10bf67fb..bae7577ccd 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -805,9 +805,8 @@ bs_write_slice (GstBitWriter * bs, (slice_param->slice_fields.bits.slice_sao_luma_flag || slice_param->slice_fields.bits.slice_sao_chroma_flag || !slice_deblocking_filter_disabled_flag)) - WRITE_UINT32 (bs, - slice_param->slice_fields. - bits.slice_loop_filter_across_slices_enabled_flag, 1); + WRITE_UINT32 (bs, slice_param->slice_fields.bits. + slice_loop_filter_across_slices_enabled_flag, 1); } @@ -1677,8 +1676,8 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, slice_param->slice_fields.value = 0; - slice_param->slice_fields. - bits.slice_loop_filter_across_slices_enabled_flag = TRUE; + slice_param->slice_fields.bits. + slice_loop_filter_across_slices_enabled_flag = TRUE; /* set calculation for next slice */ last_ctu_index += cur_slice_ctus; @@ -1725,7 +1724,8 @@ ensure_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) goto error_create_seq_param; /* add packed vps and sps headers */ - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_SEQUENCE) + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_SEQUENCE) && !(add_packed_vps_header (encoder, picture, sequence) && add_packed_sequence_header (encoder, picture, sequence))) { goto error_create_packed_seq_hdr; @@ -1769,7 +1769,8 @@ ensure_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, return FALSE; if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VA_ENC_PACKED_HEADER_PICTURE) + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_PICTURE) && !add_packed_picture_header (encoder, picture)) { GST_ERROR ("set picture packed header failed"); return FALSE; @@ -2276,7 +2277,7 @@ set_context_info (GstVaapiEncoder * base_encoder) /* Only YUV 4:2:0 formats are supported for now. */ base_encoder->codedbuf_size += GST_ROUND_UP_32 (vip->width) * - GST_ROUND_UP_32 (vip->height) * 3 / 2; + GST_ROUND_UP_32 (vip->height) * 3 / 2; return GST_VAAPI_ENCODER_STATUS_SUCCESS; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index d9a9e8460f..02149d239e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -290,7 +290,8 @@ gst_vaapi_enc_q_matrix_new (GstVaapiEncoder * encoder, /* ------------------------------------------------------------------------- */ #if USE_JPEG_ENCODER -GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncHuffmanTable, gst_vaapi_enc_huffman_table); +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncHuffmanTable, + gst_vaapi_enc_huffman_table); void gst_vaapi_enc_huffman_table_destroy (GstVaapiEncHuffmanTable * huf_table) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 802e12ceec..df9c801e0b 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -648,7 +648,7 @@ get_operations_ordered (GstVaapiFilter * filter, GPtrArray * default_ops) if (op_data->va_type != va_type) continue; - if (op_data->va_cap_size == 0) { /* no caps, like skintone */ + if (op_data->va_cap_size == 0) { /* no caps, like skintone */ g_ptr_array_add (ops, op_data_ref (op_data)); continue; } @@ -907,7 +907,7 @@ op_set_deinterlace (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, #if USE_VA_VPP gboolean op_set_skintone_unlocked (GstVaapiFilter * filter, - GstVaapiFilterOpData * op_data, gboolean value) + GstVaapiFilterOpData * op_data, gboolean value) { VAProcFilterParameterBuffer *buf; @@ -930,7 +930,7 @@ op_set_skintone_unlocked (GstVaapiFilter * filter, static inline gboolean op_set_skintone (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, - gboolean enhance) + gboolean enhance) { gboolean success = FALSE; @@ -1870,8 +1870,7 @@ gst_vaapi_filter_set_scaling (GstVaapiFilter * filter, * otherwise. **/ gboolean -gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, - gboolean enhance) +gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, gboolean enhance) { g_return_val_if_fail (filter != NULL, FALSE); diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index a6b0b58f23..3a8dc76a49 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -74,7 +74,8 @@ gst_vaapi_image_pool_class (void) { static const GstVaapiVideoPoolClass GstVaapiImagePoolClass = { {sizeof (GstVaapiImagePool), - (GDestroyNotify) gst_vaapi_video_pool_finalize}, + (GDestroyNotify) gst_vaapi_video_pool_finalize} + , .alloc_object = gst_vaapi_image_pool_alloc_object }; return GST_VAAPI_MINI_OBJECT_CLASS (&GstVaapiImagePoolClass); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 9d425ef62b..9900c78138 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -159,7 +159,7 @@ gst_vaapi_surface_create_full (GstVaapiSurface * surface, extbuf.pixel_format = va_format->fourcc; extbuf.width = GST_VIDEO_INFO_WIDTH (vip); extbuf.height = GST_VIDEO_INFO_HEIGHT (vip); - extbuf_needed = !!(flags & GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); + extbuf_needed = ! !(flags & GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vip); if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) { diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index c777194b63..cb1b2b7d05 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -95,7 +95,8 @@ gst_vaapi_surface_pool_class (void) { static const GstVaapiVideoPoolClass GstVaapiSurfacePoolClass = { {sizeof (GstVaapiSurfacePool), - (GDestroyNotify) gst_vaapi_video_pool_finalize}, + (GDestroyNotify) gst_vaapi_video_pool_finalize} + , .alloc_object = gst_vaapi_surface_pool_alloc_object }; return GST_VAAPI_MINI_OBJECT_CLASS (&GstVaapiSurfacePoolClass); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c index 12cbd826f2..dc5dfcb392 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -840,8 +840,7 @@ egl_surface_new_wrapped (EglDisplay * display, EGLSurface gl_surface) /* ------------------------------------------------------------------------- */ // EGL Context -static void -egl_context_state_get_current (EglContextState * cs); +static void egl_context_state_get_current (EglContextState * cs); static gboolean egl_context_state_set_current (EglContextState * new_cs, @@ -1329,10 +1328,22 @@ void egl_matrix_set_identity (gfloat m[16]) { #define MAT(m,r,c) (m)[(c) * 4 + (r)] - MAT(m,0,0) = 1.0; MAT(m,0,1) = 0.0; MAT(m,0,2) = 0.0; MAT(m,0,3) = 0.0; - MAT(m,1,0) = 0.0; MAT(m,1,1) = 1.0; MAT(m,1,2) = 0.0; MAT(m,1,3) = 0.0; - MAT(m,2,0) = 0.0; MAT(m,2,1) = 0.0; MAT(m,2,2) = 1.0; MAT(m,2,3) = 0.0; - MAT(m,3,0) = 0.0; MAT(m,3,1) = 0.0; MAT(m,3,2) = 0.0; MAT(m,3,3) = 1.0; + MAT (m, 0, 0) = 1.0; + MAT (m, 0, 1) = 0.0; + MAT (m, 0, 2) = 0.0; + MAT (m, 0, 3) = 0.0; + MAT (m, 1, 0) = 0.0; + MAT (m, 1, 1) = 1.0; + MAT (m, 1, 2) = 0.0; + MAT (m, 1, 3) = 0.0; + MAT (m, 2, 0) = 0.0; + MAT (m, 2, 1) = 0.0; + MAT (m, 2, 2) = 1.0; + MAT (m, 2, 3) = 0.0; + MAT (m, 3, 0) = 0.0; + MAT (m, 3, 1) = 0.0; + MAT (m, 3, 2) = 0.0; + MAT (m, 3, 3) = 1.0; #undef MAT } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 37e9375dde..39b3bf9af8 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -35,7 +35,7 @@ /** Lookup for substring NAME in string EXT using SEP as separators */ static gboolean -find_string (const gchar *name, const gchar *ext, const gchar *sep) +find_string (const gchar * name, const gchar * ext, const gchar * sep) { const gchar *end; int name_len, n; @@ -635,7 +635,7 @@ typedef void (*GLFuncPtr) (void); typedef GLFuncPtr (*GLXGetProcAddressProc) (const gchar *); static GLFuncPtr -get_proc_address_default (const gchar *name) +get_proc_address_default (const gchar * name) { return NULL; } @@ -658,7 +658,7 @@ get_proc_address_func (void) } static inline GLFuncPtr -get_proc_address (const gchar *name) +get_proc_address (const gchar * name) { static GLXGetProcAddressProc get_proc_func = NULL; if (!get_proc_func) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 5eebf9b2c0..aa1515ceee 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -281,7 +281,8 @@ gst_vaapi_utils_h265_get_level_limits_table (guint * out_length_ptr) /** Returns GstVaapiChromaType from H.265 chroma_format_idc value */ GstVaapiChromaType -gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, guint luma_bit_depth) +gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, + guint luma_bit_depth) { GstVaapiChromaType chroma_type = (GstVaapiChromaType) 0; @@ -350,8 +351,7 @@ gst_vaapi_utils_h265_get_tier_from_string (const gchar * str) const gchar * gst_vaapi_utils_h265_get_tier_string (GstVaapiTierH265 tier) { - const struct map *const m = - map_lookup_value (gst_vaapi_h265_tier_map, tier); + const struct map *const m = map_lookup_value (gst_vaapi_h265_tier_map, tier); return m ? m->name : NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 1f9fd0ba73..a4f943c9c9 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -53,15 +53,9 @@ x11_untrap_errors (void) } // X window management -static const int x11_event_mask = - (KeyPressMask | - KeyReleaseMask | - ButtonPressMask | - ButtonReleaseMask | - PointerMotionMask | - EnterWindowMask | - ExposureMask | - StructureNotifyMask); +static const int x11_event_mask = (KeyPressMask | KeyReleaseMask + | ButtonPressMask | ButtonReleaseMask | PointerMotionMask + | EnterWindowMask | ExposureMask | StructureNotifyMask); /** * x11_create_window: diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 2480ee63bf..715ef62721 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -126,7 +126,8 @@ gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height) dpy_class = GST_VAAPI_DISPLAY_GET_CLASS (display); if (G_UNLIKELY (!dpy_class->create_window)) return NULL; - return dpy_class->create_window (display, GST_VAAPI_ID_INVALID, width, height); + return dpy_class->create_window (display, GST_VAAPI_ID_INVALID, width, + height); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c index 412e3a2d4c..e511e5eba6 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c @@ -397,9 +397,9 @@ do_render_texture (GstVaapiWindowEGL * window, const GstVaapiRectangle * rect) texcoords[3][1] = y0; // Target coords in EGL surface - x0 = 2.0f * ((GLfloat) rect->x / tex_width) - 1.0f; + x0 = 2.0f * ((GLfloat) rect->x / tex_width) - 1.0f; y1 = -2.0f * ((GLfloat) rect->y / tex_height) + 1.0f; - x1 = 2.0f * ((GLfloat) (rect->x + rect->width) / tex_width) - 1.0f; + x1 = 2.0f * ((GLfloat) (rect->x + rect->width) / tex_width) - 1.0f; y0 = -2.0f * ((GLfloat) (rect->y + rect->height) / tex_height) + 1.0f; positions[0][0] = x0; positions[0][1] = y0; From 4b5be5973ed7784a5099463de976e1fd118d6f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 3 Feb 2016 11:04:15 +0100 Subject: [PATCH 2263/3781] libs: small refactors to enhance the code style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As gst-indent generated ugly code in these cases, this patch changes the used idiomatic into other one. No functional changes were introduced. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapicontext.c | 5 +++-- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 5 ++--- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 6 +++--- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 9 +++++---- gst/vaapi/gstvaapivideomemory.c | 14 ++++++++------ 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 36fc18af3a..000c713739 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -134,6 +134,7 @@ static gboolean context_create_surfaces (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); guint num_surfaces; if (!gst_vaapi_context_overlay_reset (context)) @@ -149,8 +150,8 @@ context_create_surfaces (GstVaapiContext * context) if (!context->surfaces_pool) { context->surfaces_pool = - gst_vaapi_surface_pool_new_with_chroma_type (GST_VAAPI_OBJECT_DISPLAY (context), - cip->chroma_type, cip->width, cip->height); + gst_vaapi_surface_pool_new_with_chroma_type (display, cip->chroma_type, + cip->width, cip->height); if (!context->surfaces_pool) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index bb13e96196..ecb449143e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -236,9 +236,8 @@ vaapi_fill_ref_frames (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture, 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; + pic_param->reference_frames[i] = priv->ref_frames[i] ? + priv->ref_frames[i]->surface_id : VA_INVALID_SURFACE; } } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index 4d995eb391..3d7ec20b16 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -464,10 +464,10 @@ static GstVaapiTexture * gst_vaapi_display_egl_create_texture (GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height) { - return id != GST_VAAPI_ID_INVALID ? - gst_vaapi_texture_egl_new_wrapped (display, id, target, format, - width, height) : - gst_vaapi_texture_egl_new (display, target, format, width, height); + if (id != GST_VAAPI_ID_INVALID) + return gst_vaapi_texture_egl_new_wrapped (display, id, target, format, + width, height); + return gst_vaapi_texture_egl_new (display, target, format, width, height); } static void diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 71c4909c13..8b8e8cb36e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -330,9 +330,9 @@ static GstVaapiWindow * gst_vaapi_display_wayland_create_window (GstVaapiDisplay * display, GstVaapiID id, guint width, guint height) { - return id != GST_VAAPI_ID_INVALID ? - NULL : - gst_vaapi_window_wayland_new (display, width, height); + if (id != GST_VAAPI_ID_INVALID) + return NULL; + return gst_vaapi_window_wayland_new (display, width, height); } static void diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 9747ae1cd4..0620d9f9be 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -880,17 +880,18 @@ static struct static int find_frame_rate_code (const VAEncSequenceParameterBufferMPEG2 * seq_param) { - unsigned int delta = -1; + unsigned int ndelta, delta = -1; int code = 1, i; float frame_rate_value = seq_param->frame_rate * (seq_param->sequence_extension.bits.frame_rate_extension_d + 1) / (seq_param->sequence_extension.bits.frame_rate_extension_n + 1); - for (i = 0; i < sizeof (frame_rate_tab) / sizeof (frame_rate_tab[0]); i++) { + for (i = 0; i < G_N_ELEMENTS (frame_rate_tab); i++) { - if (fabsf (1000 * frame_rate_tab[i].value - 1000 * frame_rate_value) < delta) { + ndelta = fabsf (1000 * frame_rate_tab[i].value - 1000 * frame_rate_value); + if (ndelta < delta) { code = frame_rate_tab[i].code; - delta = fabsf (1000 * frame_rate_tab[i].value - 1000 * frame_rate_value); + delta = ndelta; } } return code; diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 3cf4746b14..00f6a85d11 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -188,12 +188,13 @@ gboolean gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags) { + GstAllocator *allocator; GstVaapiVideoMemory *const mem = GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0)); - g_return_val_if_fail (mem, FALSE); - g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (mem->parent_instance. - allocator), FALSE); + + allocator = GST_MEMORY_CAST (mem)->allocator; + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (allocator), FALSE); g_return_val_if_fail (mem->meta, FALSE); if (mem->map_type && mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR) @@ -264,12 +265,13 @@ gboolean gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane, GstMapInfo * info) { + GstAllocator *allocator; GstVaapiVideoMemory *const mem = GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0)); - g_return_val_if_fail (mem, FALSE); - g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (mem->parent_instance. - allocator), FALSE); + + allocator = GST_MEMORY_CAST (mem)->allocator; + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (allocator), FALSE); g_return_val_if_fail (mem->meta, FALSE); g_return_val_if_fail (mem->surface, FALSE); g_return_val_if_fail (mem->image, FALSE); From ac730d0a62a39e4379d218c7ae13c65323bf49f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 3 Feb 2016 11:50:13 +0100 Subject: [PATCH 2264/3781] libs: humongous code style fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As part of the upstreaming process of gstreamer-vaapi into the GStreamer umbrella, we need to comply with the project's code style. This meant to change a lot of code. It was decided to use a single massive patch to update the code style. I would like to apologize with the original developers of this code because of the history breakage. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 476 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 6888 ++++++++++---------- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 1217 ++-- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 2284 +++---- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 1858 +++--- gst-libs/gst/vaapi/gstvaapidecoder_unit.c | 28 +- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 2178 +++---- gst-libs/gst/vaapi/gstvaapiimage.c | 1008 ++- gst-libs/gst/vaapi/gstvaapiparser_frame.c | 116 +- gst-libs/gst/vaapi/gstvaapipixmap.c | 151 +- gst-libs/gst/vaapi/gstvaapipixmap_x11.c | 212 +- gst-libs/gst/vaapi/gstvaapiprofile.c | 535 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 344 +- 13 files changed, 8565 insertions(+), 8730 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index d96186f753..b9531fa8e2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -37,14 +37,15 @@ * * A decoded picture buffer (DPB) object. */ -struct _GstVaapiDpb { - /*< private >*/ - GstVaapiMiniObject parent_instance; +struct _GstVaapiDpb +{ + /*< private > */ + GstVaapiMiniObject parent_instance; - /*< protected >*/ - GstVaapiPicture **pictures; - guint num_pictures; - guint max_pictures; + /*< protected > */ + GstVaapiPicture **pictures; + guint num_pictures; + guint max_pictures; }; /** @@ -52,124 +53,123 @@ struct _GstVaapiDpb { * * The #GstVaapiDpb base class. */ -struct _GstVaapiDpbClass { - /*< private >*/ - GstVaapiMiniObjectClass parent_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); + /*< 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_dpb_class (void); -static const GstVaapiMiniObjectClass * -gst_vaapi_dpb2_class(void); +static const GstVaapiMiniObjectClass *gst_vaapi_dpb2_class (void); /* ------------------------------------------------------------------------- */ /* --- Common utilities --- */ /* ------------------------------------------------------------------------- */ static inline GstVaapiDpb * -dpb_new(guint max_pictures) +dpb_new (guint max_pictures) { - GstVaapiDpb *dpb; + GstVaapiDpb *dpb; - g_return_val_if_fail(max_pictures > 0, NULL); + 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 = + (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->num_pictures = 0; + dpb->max_pictures = max_pictures; - dpb->pictures = g_new0(GstVaapiPicture *, max_pictures); - if (!dpb->pictures) - goto error; - return dpb; + dpb->pictures = g_new0 (GstVaapiPicture *, max_pictures); + if (!dpb->pictures) + goto error; + return dpb; error: - gst_vaapi_dpb_unref(dpb); - return NULL; + gst_vaapi_dpb_unref (dpb); + return NULL; } static gint -dpb_get_oldest(GstVaapiDpb *dpb, gboolean output) +dpb_get_oldest (GstVaapiDpb * dpb, gboolean output) { - gint i, lowest_pts_index; + 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; + 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; + 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) +dpb_remove_index (GstVaapiDpb * dpb, guint index) { - GstVaapiPicture ** const pictures = dpb->pictures; - guint num_pictures = --dpb->num_pictures; + 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); + 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) +dpb_output (GstVaapiDpb * dpb, GstVaapiPicture * picture) { - return gst_vaapi_picture_output(picture); + return gst_vaapi_picture_output (picture); } static gboolean -dpb_bump(GstVaapiDpb *dpb) +dpb_bump (GstVaapiDpb * dpb) { - gint index; - gboolean success; + gint index; + gboolean success; - index = dpb_get_oldest(dpb, FALSE); - if (index < 0) - return FALSE; + 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; + 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) +dpb_clear (GstVaapiDpb * dpb) { - guint i; + guint i; - for (i = 0; i < dpb->num_pictures; i++) - gst_vaapi_picture_replace(&dpb->pictures[i], NULL); - dpb->num_pictures = 0; + 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) +dpb_flush (GstVaapiDpb * dpb) { - while (dpb_bump(dpb)) - ; - dpb_clear(dpb); + while (dpb_bump (dpb)); + dpb_clear (dpb); } /* ------------------------------------------------------------------------- */ @@ -177,82 +177,80 @@ dpb_flush(GstVaapiDpb *dpb) /* ------------------------------------------------------------------------- */ static gboolean -dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) +dpb_add (GstVaapiDpb * dpb, GstVaapiPicture * picture) { - guint i; + 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++; - } + // 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 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; - } + } + // 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; + } + 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) +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; + 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; - } + /* 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); + 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; + if (prev_picture_ptr) + *prev_picture_ptr = prev_picture; + if (next_picture_ptr) + *next_picture_ptr = next_picture; } /* ------------------------------------------------------------------------- */ @@ -260,66 +258,66 @@ dpb_get_neighbours(GstVaapiDpb *dpb, GstVaapiPicture *picture, /* ------------------------------------------------------------------------- */ static gboolean -dpb2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) +dpb2_add (GstVaapiDpb * dpb, GstVaapiPicture * picture) { - GstVaapiPicture *ref_picture; - gint index = -1; + 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); + 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; - } + /* + * 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 (!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; + 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) +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; + 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)); + 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; - } + 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]; + if (prev_picture_ptr) + *prev_picture_ptr = ref_pictures[0]; + if (next_picture_ptr) + *next_picture_ptr = ref_pictures[1]; } /* ------------------------------------------------------------------------- */ @@ -327,92 +325,94 @@ dpb2_get_neighbours(GstVaapiDpb *dpb, GstVaapiPicture *picture, /* ------------------------------------------------------------------------- */ static void -gst_vaapi_dpb_finalize(GstVaapiDpb *dpb) +gst_vaapi_dpb_finalize (GstVaapiDpb * dpb) { - dpb_clear(dpb); - g_free(dpb->pictures); + dpb_clear (dpb); + g_free (dpb->pictures); } static const GstVaapiMiniObjectClass * -gst_vaapi_dpb_class(void) +gst_vaapi_dpb_class (void) { - static const GstVaapiDpbClass GstVaapiDpbClass = { - { sizeof(GstVaapiDpb), - (GDestroyNotify)gst_vaapi_dpb_finalize }, + static const GstVaapiDpbClass GstVaapiDpbClass = { + {sizeof (GstVaapiDpb), + (GDestroyNotify) gst_vaapi_dpb_finalize} + , - dpb_flush, - dpb_add, - dpb_get_neighbours - }; - return &GstVaapiDpbClass.parent_class; + dpb_flush, + dpb_add, + dpb_get_neighbours + }; + return &GstVaapiDpbClass.parent_class; } static const GstVaapiMiniObjectClass * -gst_vaapi_dpb2_class(void) +gst_vaapi_dpb2_class (void) { - static const GstVaapiDpbClass GstVaapiDpb2Class = { - { sizeof(GstVaapiDpb), - (GDestroyNotify)gst_vaapi_dpb_finalize }, + static const GstVaapiDpbClass GstVaapiDpb2Class = { + {sizeof (GstVaapiDpb), + (GDestroyNotify) gst_vaapi_dpb_finalize} + , - dpb_flush, - dpb2_add, - dpb2_get_neighbours - }; - return &GstVaapiDpb2Class.parent_class; + dpb_flush, + dpb2_add, + dpb2_get_neighbours + }; + return &GstVaapiDpb2Class.parent_class; } GstVaapiDpb * -gst_vaapi_dpb_new(guint max_pictures) +gst_vaapi_dpb_new (guint max_pictures) { - return dpb_new(max_pictures); + return dpb_new (max_pictures); } void -gst_vaapi_dpb_flush(GstVaapiDpb *dpb) +gst_vaapi_dpb_flush (GstVaapiDpb * dpb) { - const GstVaapiDpbClass *klass; + const GstVaapiDpbClass *klass; - g_return_if_fail(GST_VAAPI_IS_DPB(dpb)); + 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); + 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) +gst_vaapi_dpb_add (GstVaapiDpb * dpb, GstVaapiPicture * picture) { - const GstVaapiDpbClass *klass; + 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); + 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); + 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) +gst_vaapi_dpb_size (GstVaapiDpb * dpb) { - g_return_val_if_fail(GST_VAAPI_IS_DPB(dpb), 0); + g_return_val_if_fail (GST_VAAPI_IS_DPB (dpb), 0); - return dpb->num_pictures; + return dpb->num_pictures; } void -gst_vaapi_dpb_get_neighbours(GstVaapiDpb *dpb, GstVaapiPicture *picture, - GstVaapiPicture **prev_picture_ptr, GstVaapiPicture **next_picture_ptr) +gst_vaapi_dpb_get_neighbours (GstVaapiDpb * dpb, GstVaapiPicture * picture, + GstVaapiPicture ** prev_picture_ptr, GstVaapiPicture ** next_picture_ptr) { - const GstVaapiDpbClass *klass; + const GstVaapiDpbClass *klass; - g_return_if_fail(GST_VAAPI_IS_DPB(dpb)); - g_return_if_fail(GST_VAAPI_IS_PICTURE(picture)); + 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); + 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); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index ffe9e5fbc5..5f08e07f57 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -42,12 +42,12 @@ /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */ #define USE_STRICT_DPB_ORDERING 0 -typedef struct _GstVaapiDecoderH264Private GstVaapiDecoderH264Private; -typedef struct _GstVaapiDecoderH264Class GstVaapiDecoderH264Class; -typedef struct _GstVaapiFrameStore GstVaapiFrameStore; -typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; -typedef struct _GstVaapiParserInfoH264 GstVaapiParserInfoH264; -typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; +typedef struct _GstVaapiDecoderH264Private GstVaapiDecoderH264Private; +typedef struct _GstVaapiDecoderH264Class GstVaapiDecoderH264Class; +typedef struct _GstVaapiFrameStore GstVaapiFrameStore; +typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; +typedef struct _GstVaapiParserInfoH264 GstVaapiParserInfoH264; +typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; // Used for field_poc[] #define TOP_FIELD 0 @@ -63,74 +63,75 @@ typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; * @GST_VAAPI_DECODER_UNIT_AU_START: marks the start of an access unit. * @GST_VAAPI_DECODER_UNIT_AU_END: marks the end of an access unit. */ -enum { - /* This flag does not strictly follow the definitions (7.4.1.2.3) - for detecting the start of an access unit as we are only - interested in knowing if the current slice is the first one or - the last one in the current access unit */ - GST_VAAPI_DECODER_UNIT_FLAG_AU_START = ( - GST_VAAPI_DECODER_UNIT_FLAG_LAST << 0), - GST_VAAPI_DECODER_UNIT_FLAG_AU_END = ( - GST_VAAPI_DECODER_UNIT_FLAG_LAST << 1), +enum +{ + /* This flag does not strictly follow the definitions (7.4.1.2.3) + for detecting the start of an access unit as we are only + interested in knowing if the current slice is the first one or + the last one in the current access unit */ + GST_VAAPI_DECODER_UNIT_FLAG_AU_START = + (GST_VAAPI_DECODER_UNIT_FLAG_LAST << 0), + GST_VAAPI_DECODER_UNIT_FLAG_AU_END = (GST_VAAPI_DECODER_UNIT_FLAG_LAST << 1), - GST_VAAPI_DECODER_UNIT_FLAGS_AU = ( - GST_VAAPI_DECODER_UNIT_FLAG_AU_START | - GST_VAAPI_DECODER_UNIT_FLAG_AU_END), + GST_VAAPI_DECODER_UNIT_FLAGS_AU = (GST_VAAPI_DECODER_UNIT_FLAG_AU_START | + GST_VAAPI_DECODER_UNIT_FLAG_AU_END), }; #define GST_VAAPI_PARSER_INFO_H264(obj) \ ((GstVaapiParserInfoH264 *)(obj)) -struct _GstVaapiParserInfoH264 { - GstVaapiMiniObject parent_instance; - GstH264NalUnit nalu; - union { - GstH264SPS sps; - GstH264PPS pps; - GArray *sei; - GstH264SliceHdr slice_hdr; - } data; - guint state; - guint flags; // Same as decoder unit flags (persistent) - guint view_id; // View ID of slice - guint voc; // View order index (VOIdx) of slice +struct _GstVaapiParserInfoH264 +{ + GstVaapiMiniObject parent_instance; + GstH264NalUnit nalu; + union + { + GstH264SPS sps; + GstH264PPS pps; + GArray *sei; + GstH264SliceHdr slice_hdr; + } data; + guint state; + guint flags; // Same as decoder unit flags (persistent) + guint view_id; // View ID of slice + guint voc; // View order index (VOIdx) of slice }; static void -gst_vaapi_parser_info_h264_finalize(GstVaapiParserInfoH264 *pi) +gst_vaapi_parser_info_h264_finalize (GstVaapiParserInfoH264 * pi) { - switch (pi->nalu.type) { + switch (pi->nalu.type) { case GST_H264_NAL_SPS: case GST_H264_NAL_SUBSET_SPS: - gst_h264_sps_clear(&pi->data.sps); - break; + gst_h264_sps_clear (&pi->data.sps); + break; case GST_H264_NAL_PPS: - gst_h264_pps_clear(&pi->data.pps); - break; + gst_h264_pps_clear (&pi->data.pps); + break; case GST_H264_NAL_SEI: - if (pi->data.sei) { - g_array_unref(pi->data.sei); - pi->data.sei = NULL; - } - break; - } + if (pi->data.sei) { + g_array_unref (pi->data.sei); + pi->data.sei = NULL; + } + break; + } } static inline const GstVaapiMiniObjectClass * -gst_vaapi_parser_info_h264_class(void) +gst_vaapi_parser_info_h264_class (void) { - static const GstVaapiMiniObjectClass GstVaapiParserInfoH264Class = { - .size = sizeof(GstVaapiParserInfoH264), - .finalize = (GDestroyNotify)gst_vaapi_parser_info_h264_finalize - }; - return &GstVaapiParserInfoH264Class; + static const GstVaapiMiniObjectClass GstVaapiParserInfoH264Class = { + .size = sizeof (GstVaapiParserInfoH264), + .finalize = (GDestroyNotify) gst_vaapi_parser_info_h264_finalize + }; + return &GstVaapiParserInfoH264Class; } static inline GstVaapiParserInfoH264 * -gst_vaapi_parser_info_h264_new(void) +gst_vaapi_parser_info_h264_new (void) { - return (GstVaapiParserInfoH264 *) - gst_vaapi_mini_object_new(gst_vaapi_parser_info_h264_class()); + return (GstVaapiParserInfoH264 *) + gst_vaapi_mini_object_new (gst_vaapi_parser_info_h264_class ()); } #define gst_vaapi_parser_info_h264_ref(pi) \ @@ -170,22 +171,23 @@ gst_vaapi_parser_info_h264_new(void) * @GST_VAAPI_PICTURE_FLAGS_REFERENCE: mask covering any kind of * reference picture (short-term reference or long-term reference) */ -enum { - GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0), - GST_VAAPI_PICTURE_FLAG_REFERENCE2 = (GST_VAAPI_PICTURE_FLAG_LAST << 1), - GST_VAAPI_PICTURE_FLAG_INTER_VIEW = (GST_VAAPI_PICTURE_FLAG_LAST << 2), - GST_VAAPI_PICTURE_FLAG_ANCHOR = (GST_VAAPI_PICTURE_FLAG_LAST << 3), - GST_VAAPI_PICTURE_FLAG_AU_START = (GST_VAAPI_PICTURE_FLAG_LAST << 4), - GST_VAAPI_PICTURE_FLAG_AU_END = (GST_VAAPI_PICTURE_FLAG_LAST << 5), - GST_VAAPI_PICTURE_FLAG_GHOST = (GST_VAAPI_PICTURE_FLAG_LAST << 6), +enum +{ + GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0), + GST_VAAPI_PICTURE_FLAG_REFERENCE2 = (GST_VAAPI_PICTURE_FLAG_LAST << 1), + GST_VAAPI_PICTURE_FLAG_INTER_VIEW = (GST_VAAPI_PICTURE_FLAG_LAST << 2), + GST_VAAPI_PICTURE_FLAG_ANCHOR = (GST_VAAPI_PICTURE_FLAG_LAST << 3), + GST_VAAPI_PICTURE_FLAG_AU_START = (GST_VAAPI_PICTURE_FLAG_LAST << 4), + GST_VAAPI_PICTURE_FLAG_AU_END = (GST_VAAPI_PICTURE_FLAG_LAST << 5), + GST_VAAPI_PICTURE_FLAG_GHOST = (GST_VAAPI_PICTURE_FLAG_LAST << 6), - GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = ( - GST_VAAPI_PICTURE_FLAG_REFERENCE), - GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = ( - GST_VAAPI_PICTURE_FLAG_REFERENCE | GST_VAAPI_PICTURE_FLAG_REFERENCE2), - GST_VAAPI_PICTURE_FLAGS_REFERENCE = ( - GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE | - GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE), + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = + (GST_VAAPI_PICTURE_FLAG_REFERENCE), + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = + (GST_VAAPI_PICTURE_FLAG_REFERENCE | GST_VAAPI_PICTURE_FLAG_REFERENCE2), + GST_VAAPI_PICTURE_FLAGS_REFERENCE = + (GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE | + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE), }; #define GST_VAAPI_PICTURE_IS_IDR(picture) \ @@ -210,237 +212,233 @@ enum { #define GST_VAAPI_PICTURE_H264(picture) \ ((GstVaapiPictureH264 *)(picture)) -struct _GstVaapiPictureH264 { - GstVaapiPicture base; - GstH264SliceHdr *last_slice_hdr; - guint structure; - gint32 field_poc[2]; - gint32 frame_num; // Original frame_num from slice_header() - gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap - gint32 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx - gint32 pic_num; // Temporary for ref pic marking: PicNum - gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum - GstVaapiPictureH264 *other_field; // Temporary for ref pic marking: other field in the same frame store - guint output_flag : 1; - guint output_needed : 1; +struct _GstVaapiPictureH264 +{ + GstVaapiPicture base; + GstH264SliceHdr *last_slice_hdr; + guint structure; + gint32 field_poc[2]; + gint32 frame_num; // Original frame_num from slice_header() + gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap + gint32 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx + gint32 pic_num; // Temporary for ref pic marking: PicNum + gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum + GstVaapiPictureH264 *other_field; // Temporary for ref pic marking: other field in the same frame store + guint output_flag:1; + guint output_needed:1; }; -GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264, gst_vaapi_picture_h264); +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiPictureH264, gst_vaapi_picture_h264); void -gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *picture) +gst_vaapi_picture_h264_destroy (GstVaapiPictureH264 * picture) { - gst_vaapi_picture_destroy(GST_VAAPI_PICTURE(picture)); + gst_vaapi_picture_destroy (GST_VAAPI_PICTURE (picture)); } gboolean -gst_vaapi_picture_h264_create( - GstVaapiPictureH264 *picture, - const GstVaapiCodecObjectConstructorArgs *args -) +gst_vaapi_picture_h264_create (GstVaapiPictureH264 * picture, + const GstVaapiCodecObjectConstructorArgs * args) { - if (!gst_vaapi_picture_create(GST_VAAPI_PICTURE(picture), args)) - return FALSE; + if (!gst_vaapi_picture_create (GST_VAAPI_PICTURE (picture), args)) + return FALSE; - picture->structure = picture->base.structure; - picture->field_poc[0] = G_MAXINT32; - picture->field_poc[1] = G_MAXINT32; - picture->output_needed = FALSE; - return TRUE; + picture->structure = picture->base.structure; + picture->field_poc[0] = G_MAXINT32; + picture->field_poc[1] = G_MAXINT32; + picture->output_needed = FALSE; + return TRUE; } static inline GstVaapiPictureH264 * -gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder) +gst_vaapi_picture_h264_new (GstVaapiDecoderH264 * decoder) { - return (GstVaapiPictureH264 *)gst_vaapi_codec_object_new( - &GstVaapiPictureH264Class, - GST_VAAPI_CODEC_BASE(decoder), - NULL, sizeof(VAPictureParameterBufferH264), - NULL, 0, - 0); + return (GstVaapiPictureH264 *) + gst_vaapi_codec_object_new (&GstVaapiPictureH264Class, + GST_VAAPI_CODEC_BASE (decoder), NULL, + sizeof (VAPictureParameterBufferH264), NULL, 0, 0); } static inline void -gst_vaapi_picture_h264_set_reference( - GstVaapiPictureH264 *picture, - guint reference_flags, - gboolean other_field -) +gst_vaapi_picture_h264_set_reference (GstVaapiPictureH264 * picture, + guint reference_flags, gboolean other_field) { - if (!picture) - return; - GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); - GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags); + if (!picture) + return; + GST_VAAPI_PICTURE_FLAG_UNSET (picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); + GST_VAAPI_PICTURE_FLAG_SET (picture, reference_flags); - if (!other_field || !(picture = picture->other_field)) - return; - GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); - GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags); + if (!other_field || !(picture = picture->other_field)) + return; + GST_VAAPI_PICTURE_FLAG_UNSET (picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); + GST_VAAPI_PICTURE_FLAG_SET (picture, reference_flags); } static inline GstVaapiPictureH264 * -gst_vaapi_picture_h264_new_field(GstVaapiPictureH264 *picture) +gst_vaapi_picture_h264_new_field (GstVaapiPictureH264 * picture) { - g_return_val_if_fail(picture, NULL); + g_return_val_if_fail (picture, NULL); - return (GstVaapiPictureH264 *)gst_vaapi_picture_new_field(&picture->base); + return (GstVaapiPictureH264 *) gst_vaapi_picture_new_field (&picture->base); } static inline GstVaapiPictureH264 * -gst_vaapi_picture_h264_new_clone(GstVaapiPictureH264 *picture) +gst_vaapi_picture_h264_new_clone (GstVaapiPictureH264 * picture) { - g_return_val_if_fail(picture, NULL); + g_return_val_if_fail (picture, NULL); - return (GstVaapiPictureH264 *)gst_vaapi_picture_new_clone(&picture->base); + return (GstVaapiPictureH264 *) gst_vaapi_picture_new_clone (&picture->base); } /* ------------------------------------------------------------------------- */ /* --- Frame Buffers (DPB) --- */ /* ------------------------------------------------------------------------- */ -struct _GstVaapiFrameStore { - /*< private >*/ - GstVaapiMiniObject parent_instance; +struct _GstVaapiFrameStore +{ + /*< private > */ + GstVaapiMiniObject parent_instance; - guint view_id; - guint structure; - GstVaapiPictureH264 *buffers[2]; - guint num_buffers; - guint output_needed; - guint output_called; + guint view_id; + guint structure; + GstVaapiPictureH264 *buffers[2]; + guint num_buffers; + guint output_needed; + guint output_called; }; static void -gst_vaapi_frame_store_finalize(gpointer object) +gst_vaapi_frame_store_finalize (gpointer object) { - GstVaapiFrameStore * const fs = object; - guint i; + GstVaapiFrameStore *const fs = object; + guint i; - for (i = 0; i < fs->num_buffers; i++) - gst_vaapi_picture_replace(&fs->buffers[i], NULL); + for (i = 0; i < fs->num_buffers; i++) + gst_vaapi_picture_replace (&fs->buffers[i], NULL); } static GstVaapiFrameStore * -gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture) +gst_vaapi_frame_store_new (GstVaapiPictureH264 * picture) { - GstVaapiFrameStore *fs; + GstVaapiFrameStore *fs; - static const GstVaapiMiniObjectClass GstVaapiFrameStoreClass = { - sizeof(GstVaapiFrameStore), - gst_vaapi_frame_store_finalize - }; + static const GstVaapiMiniObjectClass GstVaapiFrameStoreClass = { + sizeof (GstVaapiFrameStore), + gst_vaapi_frame_store_finalize + }; - fs = (GstVaapiFrameStore *) - gst_vaapi_mini_object_new(&GstVaapiFrameStoreClass); - if (!fs) - return NULL; + fs = (GstVaapiFrameStore *) + gst_vaapi_mini_object_new (&GstVaapiFrameStoreClass); + if (!fs) + return NULL; - fs->view_id = picture->base.view_id; - fs->structure = picture->structure; - fs->buffers[0] = gst_vaapi_picture_ref(picture); - fs->buffers[1] = NULL; - fs->num_buffers = 1; - fs->output_needed = 0; - fs->output_called = 0; + fs->view_id = picture->base.view_id; + fs->structure = picture->structure; + fs->buffers[0] = gst_vaapi_picture_ref (picture); + fs->buffers[1] = NULL; + fs->num_buffers = 1; + fs->output_needed = 0; + fs->output_called = 0; - if (picture->output_flag) { - picture->output_needed = TRUE; - fs->output_needed++; - } - return fs; + if (picture->output_flag) { + picture->output_needed = TRUE; + fs->output_needed++; + } + return fs; } static gboolean -gst_vaapi_frame_store_add(GstVaapiFrameStore *fs, GstVaapiPictureH264 *picture) +gst_vaapi_frame_store_add (GstVaapiFrameStore * fs, + GstVaapiPictureH264 * picture) { - guint field; + guint field; - g_return_val_if_fail(fs->num_buffers == 1, FALSE); - g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FRAME(picture), FALSE); - g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture), FALSE); + g_return_val_if_fail (fs->num_buffers == 1, FALSE); + g_return_val_if_fail (!GST_VAAPI_PICTURE_IS_FRAME (picture), FALSE); + g_return_val_if_fail (!GST_VAAPI_PICTURE_IS_FIRST_FIELD (picture), FALSE); - gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], picture); - if (picture->output_flag) { - picture->output_needed = TRUE; - fs->output_needed++; - } + gst_vaapi_picture_replace (&fs->buffers[fs->num_buffers++], picture); + if (picture->output_flag) { + picture->output_needed = TRUE; + fs->output_needed++; + } - fs->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + fs->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - field = picture->structure == GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD ? - TOP_FIELD : BOTTOM_FIELD; - g_return_val_if_fail(fs->buffers[0]->field_poc[field] == G_MAXINT32, FALSE); - fs->buffers[0]->field_poc[field] = picture->field_poc[field]; - g_return_val_if_fail(picture->field_poc[!field] == G_MAXINT32, FALSE); - picture->field_poc[!field] = fs->buffers[0]->field_poc[!field]; - return TRUE; + field = picture->structure == GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD ? + TOP_FIELD : BOTTOM_FIELD; + g_return_val_if_fail (fs->buffers[0]->field_poc[field] == G_MAXINT32, FALSE); + fs->buffers[0]->field_poc[field] = picture->field_poc[field]; + g_return_val_if_fail (picture->field_poc[!field] == G_MAXINT32, FALSE); + picture->field_poc[!field] = fs->buffers[0]->field_poc[!field]; + return TRUE; } static gboolean -gst_vaapi_frame_store_split_fields(GstVaapiFrameStore *fs, gboolean tff) +gst_vaapi_frame_store_split_fields (GstVaapiFrameStore * fs, gboolean tff) { - GstVaapiPictureH264 * const first_field = fs->buffers[0]; - GstVaapiPictureH264 *second_field; + GstVaapiPictureH264 *const first_field = fs->buffers[0]; + GstVaapiPictureH264 *second_field; - g_return_val_if_fail(fs->num_buffers == 1, FALSE); + g_return_val_if_fail (fs->num_buffers == 1, FALSE); - first_field->base.structure = tff ? - GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; - GST_VAAPI_PICTURE_FLAG_SET(first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED); + first_field->base.structure = tff ? + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD : + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + GST_VAAPI_PICTURE_FLAG_SET (first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED); - second_field = gst_vaapi_picture_h264_new_field(first_field); - if (!second_field) - return FALSE; - gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], second_field); - gst_vaapi_picture_unref(second_field); - - second_field->frame_num = first_field->frame_num; - second_field->field_poc[0] = first_field->field_poc[0]; - second_field->field_poc[1] = first_field->field_poc[1]; - second_field->output_flag = first_field->output_flag; - if (second_field->output_flag) { - second_field->output_needed = TRUE; - fs->output_needed++; - } - return TRUE; -} - -static inline gboolean -gst_vaapi_frame_store_has_frame(GstVaapiFrameStore *fs) -{ - return fs->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME; -} - -static inline gboolean -gst_vaapi_frame_store_is_complete(GstVaapiFrameStore *fs) -{ - return gst_vaapi_frame_store_has_frame(fs) || - GST_VAAPI_PICTURE_IS_ONEFIELD(fs->buffers[0]); -} - -static inline gboolean -gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs) -{ - guint i; - - for (i = 0; i < fs->num_buffers; i++) { - if (GST_VAAPI_PICTURE_IS_REFERENCE(fs->buffers[i])) - return TRUE; - } + second_field = gst_vaapi_picture_h264_new_field (first_field); + if (!second_field) return FALSE; + gst_vaapi_picture_replace (&fs->buffers[fs->num_buffers++], second_field); + gst_vaapi_picture_unref (second_field); + + second_field->frame_num = first_field->frame_num; + second_field->field_poc[0] = first_field->field_poc[0]; + second_field->field_poc[1] = first_field->field_poc[1]; + second_field->output_flag = first_field->output_flag; + if (second_field->output_flag) { + second_field->output_needed = TRUE; + fs->output_needed++; + } + return TRUE; +} + +static inline gboolean +gst_vaapi_frame_store_has_frame (GstVaapiFrameStore * fs) +{ + return fs->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME; +} + +static inline gboolean +gst_vaapi_frame_store_is_complete (GstVaapiFrameStore * fs) +{ + return gst_vaapi_frame_store_has_frame (fs) || + GST_VAAPI_PICTURE_IS_ONEFIELD (fs->buffers[0]); +} + +static inline gboolean +gst_vaapi_frame_store_has_reference (GstVaapiFrameStore * fs) +{ + guint i; + + for (i = 0; i < fs->num_buffers; i++) { + if (GST_VAAPI_PICTURE_IS_REFERENCE (fs->buffers[i])) + return TRUE; + } + return FALSE; } static gboolean -gst_vaapi_frame_store_has_inter_view(GstVaapiFrameStore *fs) +gst_vaapi_frame_store_has_inter_view (GstVaapiFrameStore * fs) { - guint i; + guint i; - for (i = 0; i < fs->num_buffers; i++) { - if (GST_VAAPI_PICTURE_IS_INTER_VIEW(fs->buffers[i])) - return TRUE; - } - return FALSE; + for (i = 0; i < fs->num_buffers; i++) { + if (GST_VAAPI_PICTURE_IS_INTER_VIEW (fs->buffers[i])) + return TRUE; + } + return FALSE; } #define gst_vaapi_frame_store_ref(fs) \ @@ -460,75 +458,76 @@ gst_vaapi_frame_store_has_inter_view(GstVaapiFrameStore *fs) #define GST_VAAPI_DECODER_H264_CAST(decoder) \ ((GstVaapiDecoderH264 *)(decoder)) -typedef enum { - GST_H264_VIDEO_STATE_GOT_SPS = 1 << 0, - GST_H264_VIDEO_STATE_GOT_PPS = 1 << 1, - GST_H264_VIDEO_STATE_GOT_SLICE = 1 << 2, - GST_H264_VIDEO_STATE_GOT_I_FRAME = 1 << 3, // persistent across SPS - GST_H264_VIDEO_STATE_GOT_P_SLICE = 1 << 4, // predictive (all non-intra) +typedef enum +{ + GST_H264_VIDEO_STATE_GOT_SPS = 1 << 0, + GST_H264_VIDEO_STATE_GOT_PPS = 1 << 1, + GST_H264_VIDEO_STATE_GOT_SLICE = 1 << 2, + GST_H264_VIDEO_STATE_GOT_I_FRAME = 1 << 3, // persistent across SPS + GST_H264_VIDEO_STATE_GOT_P_SLICE = 1 << 4, // predictive (all non-intra) - GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS = ( - GST_H264_VIDEO_STATE_GOT_SPS | - GST_H264_VIDEO_STATE_GOT_PPS), - GST_H264_VIDEO_STATE_VALID_PICTURE = ( - GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS | - GST_H264_VIDEO_STATE_GOT_SLICE) + GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS = (GST_H264_VIDEO_STATE_GOT_SPS | + GST_H264_VIDEO_STATE_GOT_PPS), + GST_H264_VIDEO_STATE_VALID_PICTURE = + (GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS | + GST_H264_VIDEO_STATE_GOT_SLICE) } GstH264VideoState; -struct _GstVaapiDecoderH264Private { - GstH264NalParser *parser; - guint parser_state; - guint decoder_state; - GstVaapiStreamAlignH264 stream_alignment; - GstVaapiPictureH264 *current_picture; - GstVaapiPictureH264 *missing_picture; - GstVaapiParserInfoH264 *sps[GST_H264_MAX_SPS_COUNT]; - GstVaapiParserInfoH264 *active_sps; - GstVaapiParserInfoH264 *pps[GST_H264_MAX_PPS_COUNT]; - GstVaapiParserInfoH264 *active_pps; - GstVaapiParserInfoH264 *prev_pi; - GstVaapiParserInfoH264 *prev_slice_pi; - GstVaapiFrameStore **prev_ref_frames; - GstVaapiFrameStore **prev_frames; - guint prev_frames_alloc; - GstVaapiFrameStore **dpb; - guint dpb_count; - guint dpb_size; - guint dpb_size_max; - guint max_views; - GstVaapiProfile profile; - GstVaapiEntrypoint entrypoint; - GstVaapiChromaType chroma_type; - GPtrArray *inter_views; - GstVaapiPictureH264 *short_ref[32]; - guint short_ref_count; - GstVaapiPictureH264 *long_ref[32]; - guint long_ref_count; - GstVaapiPictureH264 *RefPicList0[32]; - guint RefPicList0_count; - GstVaapiPictureH264 *RefPicList1[32]; - guint RefPicList1_count; - guint nal_length_size; - guint mb_width; - guint mb_height; - guint pic_structure; // pic_struct (from SEI pic_timing() or inferred) - gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt - gint32 poc_msb; // PicOrderCntMsb - gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header()) - gint32 prev_poc_msb; // prevPicOrderCntMsb - gint32 prev_poc_lsb; // prevPicOrderCntLsb - gint32 frame_num_offset; // FrameNumOffset - gint32 frame_num; // frame_num (from slice_header()) - gint32 prev_frame_num; // prevFrameNum - gint32 prev_ref_frame_num; // prevRefFrameNum - gboolean prev_pic_has_mmco5; // prevMmco5Pic - gboolean prev_pic_reference; // previous picture is a reference - guint prev_pic_structure; // previous picture structure - guint is_opened : 1; - guint is_avcC : 1; - guint has_context : 1; - guint progressive_sequence : 1; - guint top_field_first : 1; +struct _GstVaapiDecoderH264Private +{ + GstH264NalParser *parser; + guint parser_state; + guint decoder_state; + GstVaapiStreamAlignH264 stream_alignment; + GstVaapiPictureH264 *current_picture; + GstVaapiPictureH264 *missing_picture; + GstVaapiParserInfoH264 *sps[GST_H264_MAX_SPS_COUNT]; + GstVaapiParserInfoH264 *active_sps; + GstVaapiParserInfoH264 *pps[GST_H264_MAX_PPS_COUNT]; + GstVaapiParserInfoH264 *active_pps; + GstVaapiParserInfoH264 *prev_pi; + GstVaapiParserInfoH264 *prev_slice_pi; + GstVaapiFrameStore **prev_ref_frames; + GstVaapiFrameStore **prev_frames; + guint prev_frames_alloc; + GstVaapiFrameStore **dpb; + guint dpb_count; + guint dpb_size; + guint dpb_size_max; + guint max_views; + GstVaapiProfile profile; + GstVaapiEntrypoint entrypoint; + GstVaapiChromaType chroma_type; + GPtrArray *inter_views; + GstVaapiPictureH264 *short_ref[32]; + guint short_ref_count; + GstVaapiPictureH264 *long_ref[32]; + guint long_ref_count; + GstVaapiPictureH264 *RefPicList0[32]; + guint RefPicList0_count; + GstVaapiPictureH264 *RefPicList1[32]; + guint RefPicList1_count; + guint nal_length_size; + guint mb_width; + guint mb_height; + guint pic_structure; // pic_struct (from SEI pic_timing() or inferred) + gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt + gint32 poc_msb; // PicOrderCntMsb + gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header()) + gint32 prev_poc_msb; // prevPicOrderCntMsb + gint32 prev_poc_lsb; // prevPicOrderCntLsb + gint32 frame_num_offset; // FrameNumOffset + gint32 frame_num; // frame_num (from slice_header()) + gint32 prev_frame_num; // prevFrameNum + gint32 prev_ref_frame_num; // prevRefFrameNum + gboolean prev_pic_has_mmco5; // prevMmco5Pic + gboolean prev_pic_reference; // previous picture is a reference + guint prev_pic_structure; // previous picture structure + guint is_opened:1; + guint is_avcC:1; + guint has_context:1; + guint progressive_sequence:1; + guint top_field_first:1; }; /** @@ -536,10 +535,11 @@ struct _GstVaapiDecoderH264Private { * * A decoder based on H264. */ -struct _GstVaapiDecoderH264 { - /*< private >*/ - GstVaapiDecoder parent_instance; - GstVaapiDecoderH264Private priv; +struct _GstVaapiDecoderH264 +{ + /*< private > */ + GstVaapiDecoder parent_instance; + GstVaapiDecoderH264Private priv; }; /** @@ -547,161 +547,162 @@ struct _GstVaapiDecoderH264 { * * A decoder class based on H264. */ -struct _GstVaapiDecoderH264Class { - /*< private >*/ - GstVaapiDecoderClass parent_class; +struct _GstVaapiDecoderH264Class +{ + /*< private > */ + GstVaapiDecoderClass parent_class; }; static gboolean -exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture); +exec_ref_pic_marking (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture); static gboolean -exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder); +exec_ref_pic_marking_sliding_window (GstVaapiDecoderH264 * decoder); static gboolean -is_inter_view_reference_for_next_pictures(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture); +is_inter_view_reference_for_next_pictures (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture); static inline gboolean -is_inter_view_reference_for_next_frames(GstVaapiDecoderH264 *decoder, - GstVaapiFrameStore *fs) +is_inter_view_reference_for_next_frames (GstVaapiDecoderH264 * decoder, + GstVaapiFrameStore * fs) { - return is_inter_view_reference_for_next_pictures(decoder, fs->buffers[0]); + return is_inter_view_reference_for_next_pictures (decoder, fs->buffers[0]); } /* Determines if the supplied profile is one of the MVC set */ static gboolean -is_mvc_profile(GstH264Profile profile) +is_mvc_profile (GstH264Profile profile) { - return profile == GST_H264_PROFILE_MULTIVIEW_HIGH || - profile == GST_H264_PROFILE_STEREO_HIGH; + return profile == GST_H264_PROFILE_MULTIVIEW_HIGH || + profile == GST_H264_PROFILE_STEREO_HIGH; } /* Determines the view_id from the supplied NAL unit */ static inline guint -get_view_id(GstH264NalUnit *nalu) +get_view_id (GstH264NalUnit * nalu) { - return GST_H264_IS_MVC_NALU(nalu) ? nalu->extension.mvc.view_id : 0; + return GST_H264_IS_MVC_NALU (nalu) ? nalu->extension.mvc.view_id : 0; } /* Determines the view order index (VOIdx) from the supplied view_id */ static gint -get_view_order_index(GstH264SPS *sps, guint16 view_id) +get_view_order_index (GstH264SPS * sps, guint16 view_id) { - GstH264SPSExtMVC *mvc; - gint i; + GstH264SPSExtMVC *mvc; + gint i; - if (!sps || sps->extension_type != GST_H264_NAL_EXTENSION_MVC) - return 0; + if (!sps || sps->extension_type != GST_H264_NAL_EXTENSION_MVC) + return 0; - mvc = &sps->extension.mvc; - for (i = 0; i <= mvc->num_views_minus1; i++) { - if (mvc->view[i].view_id == view_id) - return i; - } - GST_ERROR("failed to find VOIdx from view_id (%d)", view_id); - return -1; + mvc = &sps->extension.mvc; + for (i = 0; i <= mvc->num_views_minus1; i++) { + if (mvc->view[i].view_id == view_id) + return i; + } + GST_ERROR ("failed to find VOIdx from view_id (%d)", view_id); + return -1; } /* Determines NumViews */ static guint -get_num_views(GstH264SPS *sps) +get_num_views (GstH264SPS * sps) { - return 1 + (sps->extension_type == GST_H264_NAL_EXTENSION_MVC ? - sps->extension.mvc.num_views_minus1 : 0); + return 1 + (sps->extension_type == GST_H264_NAL_EXTENSION_MVC ? + sps->extension.mvc.num_views_minus1 : 0); } /* Get number of reference frames to use */ static guint -get_max_dec_frame_buffering(GstH264SPS *sps) +get_max_dec_frame_buffering (GstH264SPS * sps) { - guint num_views, max_dpb_frames; - guint max_dec_frame_buffering, PicSizeMbs; - GstVaapiLevelH264 level; - const GstVaapiH264LevelLimits *level_limits; + guint num_views, max_dpb_frames; + guint max_dec_frame_buffering, PicSizeMbs; + GstVaapiLevelH264 level; + const GstVaapiH264LevelLimits *level_limits; - /* Table A-1 - Level limits */ - if (G_UNLIKELY(sps->level_idc == 11 && sps->constraint_set3_flag)) - level = GST_VAAPI_LEVEL_H264_L1b; - else - level = gst_vaapi_utils_h264_get_level(sps->level_idc); - level_limits = gst_vaapi_utils_h264_get_level_limits(level); - if (G_UNLIKELY(!level_limits)) { - GST_FIXME("unsupported level_idc value (%d)", sps->level_idc); - max_dec_frame_buffering = 16; - } + /* Table A-1 - Level limits */ + if (G_UNLIKELY (sps->level_idc == 11 && sps->constraint_set3_flag)) + level = GST_VAAPI_LEVEL_H264_L1b; + else + level = gst_vaapi_utils_h264_get_level (sps->level_idc); + level_limits = gst_vaapi_utils_h264_get_level_limits (level); + if (G_UNLIKELY (!level_limits)) { + GST_FIXME ("unsupported level_idc value (%d)", sps->level_idc); + max_dec_frame_buffering = 16; + } else { + PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) * + (sps->pic_height_in_map_units_minus1 + 1) * + (sps->frame_mbs_only_flag ? 1 : 2)); + max_dec_frame_buffering = level_limits->MaxDpbMbs / PicSizeMbs; + } + if (is_mvc_profile (sps->profile_idc)) + max_dec_frame_buffering <<= 1; + + /* VUI parameters */ + if (sps->vui_parameters_present_flag) { + GstH264VUIParams *const vui_params = &sps->vui_parameters; + if (vui_params->bitstream_restriction_flag) + max_dec_frame_buffering = vui_params->max_dec_frame_buffering; else { - PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) * - (sps->pic_height_in_map_units_minus1 + 1) * - (sps->frame_mbs_only_flag ? 1 : 2)); - max_dec_frame_buffering = level_limits->MaxDpbMbs / PicSizeMbs; + switch (sps->profile_idc) { + case 44: // CAVLC 4:4:4 Intra profile + case GST_H264_PROFILE_SCALABLE_HIGH: + case GST_H264_PROFILE_HIGH: + case GST_H264_PROFILE_HIGH10: + case GST_H264_PROFILE_HIGH_422: + case GST_H264_PROFILE_HIGH_444: + if (sps->constraint_set3_flag) + max_dec_frame_buffering = 0; + break; + } } - if (is_mvc_profile(sps->profile_idc)) - max_dec_frame_buffering <<= 1; + } - /* VUI parameters */ - if (sps->vui_parameters_present_flag) { - GstH264VUIParams * const vui_params = &sps->vui_parameters; - if (vui_params->bitstream_restriction_flag) - max_dec_frame_buffering = vui_params->max_dec_frame_buffering; - else { - switch (sps->profile_idc) { - case 44: // CAVLC 4:4:4 Intra profile - case GST_H264_PROFILE_SCALABLE_HIGH: - case GST_H264_PROFILE_HIGH: - case GST_H264_PROFILE_HIGH10: - case GST_H264_PROFILE_HIGH_422: - case GST_H264_PROFILE_HIGH_444: - if (sps->constraint_set3_flag) - max_dec_frame_buffering = 0; - break; - } - } - } - - num_views = get_num_views(sps); - max_dpb_frames = 16 * (num_views > 1 ? g_bit_storage(num_views - 1) : 1); - if (max_dec_frame_buffering > max_dpb_frames) - max_dec_frame_buffering = max_dpb_frames; - else if (max_dec_frame_buffering < sps->num_ref_frames) - max_dec_frame_buffering = sps->num_ref_frames; - return MAX(1, max_dec_frame_buffering); + num_views = get_num_views (sps); + max_dpb_frames = 16 * (num_views > 1 ? g_bit_storage (num_views - 1) : 1); + if (max_dec_frame_buffering > max_dpb_frames) + max_dec_frame_buffering = max_dpb_frames; + else if (max_dec_frame_buffering < sps->num_ref_frames) + max_dec_frame_buffering = sps->num_ref_frames; + return MAX (1, max_dec_frame_buffering); } static void -array_remove_index_fast(void *array, guint *array_length_ptr, guint index) +array_remove_index_fast (void *array, guint * array_length_ptr, guint index) { - gpointer * const entries = array; - guint num_entries = *array_length_ptr; + gpointer *const entries = array; + guint num_entries = *array_length_ptr; - g_return_if_fail(index < num_entries); + g_return_if_fail (index < num_entries); - if (index != --num_entries) - entries[index] = entries[num_entries]; - entries[num_entries] = NULL; - *array_length_ptr = num_entries; + if (index != --num_entries) + entries[index] = entries[num_entries]; + entries[num_entries] = NULL; + *array_length_ptr = num_entries; } #if 1 static inline void -array_remove_index(void *array, guint *array_length_ptr, guint index) +array_remove_index (void *array, guint * array_length_ptr, guint index) { - array_remove_index_fast(array, array_length_ptr, index); + array_remove_index_fast (array, array_length_ptr, index); } #else static void -array_remove_index(void *array, guint *array_length_ptr, guint index) +array_remove_index (void *array, guint * array_length_ptr, guint index) { - gpointer * const entries = array; - const guint num_entries = *array_length_ptr - 1; - guint i; + gpointer *const entries = array; + const guint num_entries = *array_length_ptr - 1; + guint i; - g_return_if_fail(index <= num_entries); + g_return_if_fail (index <= num_entries); - for (i = index; i < num_entries; i++) - entries[i] = entries[i + 1]; - entries[num_entries] = NULL; - *array_length_ptr = num_entries; + for (i = index; i < num_entries; i++) + entries[i] = entries[i + 1]; + entries[num_entries] = NULL; + *array_length_ptr = num_entries; } #endif @@ -709,1690 +710,1654 @@ array_remove_index(void *array, guint *array_length_ptr, guint index) array_remove_index(array, &array##_count, index) static void -dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index) +dpb_remove_index (GstVaapiDecoderH264 * decoder, guint index) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - guint i, num_frames = --priv->dpb_count; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + guint i, num_frames = --priv->dpb_count; - if (USE_STRICT_DPB_ORDERING) { - for (i = index; i < num_frames; i++) - gst_vaapi_frame_store_replace(&priv->dpb[i], priv->dpb[i + 1]); - } - else if (index != num_frames) - gst_vaapi_frame_store_replace(&priv->dpb[index], priv->dpb[num_frames]); - gst_vaapi_frame_store_replace(&priv->dpb[num_frames], NULL); + if (USE_STRICT_DPB_ORDERING) { + for (i = index; i < num_frames; i++) + gst_vaapi_frame_store_replace (&priv->dpb[i], priv->dpb[i + 1]); + } else if (index != num_frames) + gst_vaapi_frame_store_replace (&priv->dpb[index], priv->dpb[num_frames]); + gst_vaapi_frame_store_replace (&priv->dpb[num_frames], NULL); } static gboolean -dpb_output(GstVaapiDecoderH264 *decoder, GstVaapiFrameStore *fs) +dpb_output (GstVaapiDecoderH264 * decoder, GstVaapiFrameStore * fs) { - GstVaapiPictureH264 *picture = NULL; - guint i; + GstVaapiPictureH264 *picture = NULL; + guint i; - g_return_val_if_fail(fs != NULL, FALSE); + g_return_val_if_fail (fs != NULL, FALSE); - fs->output_called++; - if (!gst_vaapi_frame_store_is_complete(fs)) - return TRUE; + fs->output_called++; + if (!gst_vaapi_frame_store_is_complete (fs)) + return TRUE; - for (i = 0; i < fs->num_buffers; i++) { - GstVaapiPictureH264 * const pic = fs->buffers[i]; - g_return_val_if_fail(pic != NULL, FALSE); - pic->output_needed = FALSE; - if (!GST_VAAPI_PICTURE_FLAG_IS_SET(pic, GST_VAAPI_PICTURE_FLAG_GHOST)) - picture = pic; - } + for (i = 0; i < fs->num_buffers; i++) { + GstVaapiPictureH264 *const pic = fs->buffers[i]; + g_return_val_if_fail (pic != NULL, FALSE); + pic->output_needed = FALSE; + if (!GST_VAAPI_PICTURE_FLAG_IS_SET (pic, GST_VAAPI_PICTURE_FLAG_GHOST)) + picture = pic; + } - fs->output_needed = 0; - fs->output_called = 0; - if (!picture) - return TRUE; - return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture)); + fs->output_needed = 0; + fs->output_called = 0; + if (!picture) + return TRUE; + return gst_vaapi_picture_output (GST_VAAPI_PICTURE_CAST (picture)); } static inline void -dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i) +dpb_evict (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, + guint i) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiFrameStore * const fs = priv->dpb[i]; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiFrameStore *const fs = priv->dpb[i]; - if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs)) - dpb_remove_index(decoder, i); + if (!fs->output_needed && !gst_vaapi_frame_store_has_reference (fs)) + dpb_remove_index (decoder, i); } /* Finds the picture with the nearest previous POC and same structure */ static gint -dpb_find_nearest_prev_poc(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, guint picture_structure, - GstVaapiPictureH264 **found_picture_ptr) +dpb_find_nearest_prev_poc (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, guint picture_structure, + GstVaapiPictureH264 ** found_picture_ptr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 *found_picture = NULL; - guint i, j, found_index; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 *found_picture = NULL; + guint i, j, found_index; - g_return_val_if_fail(picture != NULL, -1); + g_return_val_if_fail (picture != NULL, -1); - if (!picture_structure) - picture_structure = picture->base.structure; + if (!picture_structure) + picture_structure = picture->base.structure; - for (i = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - if (picture->base.view_id != fs->view_id) - continue; - for (j = 0; j < fs->num_buffers; j++) { - GstVaapiPictureH264 * const pic = fs->buffers[j]; - if (pic->base.structure != picture_structure) - continue; - if (pic->base.poc >= picture->base.poc) - continue; - if (!found_picture || found_picture->base.poc < pic->base.poc) - found_picture = pic, found_index = i; - } + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + if (picture->base.view_id != fs->view_id) + continue; + for (j = 0; j < fs->num_buffers; j++) { + GstVaapiPictureH264 *const pic = fs->buffers[j]; + if (pic->base.structure != picture_structure) + continue; + if (pic->base.poc >= picture->base.poc) + continue; + if (!found_picture || found_picture->base.poc < pic->base.poc) + found_picture = pic, found_index = i; } + } - if (found_picture_ptr) - *found_picture_ptr = found_picture; - return found_picture ? found_index : -1; + if (found_picture_ptr) + *found_picture_ptr = found_picture; + return found_picture ? found_index : -1; } /* Finds the picture with the lowest POC that needs to be output */ static gint -dpb_find_lowest_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, - GstVaapiPictureH264 **found_picture_ptr) +dpb_find_lowest_poc (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstVaapiPictureH264 ** found_picture_ptr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 *found_picture = NULL; - guint i, j, found_index; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 *found_picture = NULL; + guint i, j, found_index; - for (i = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - if (!fs->output_needed) - continue; - if (picture && picture->base.view_id != fs->view_id) - continue; - for (j = 0; j < fs->num_buffers; j++) { - GstVaapiPictureH264 * const pic = fs->buffers[j]; - if (!pic->output_needed) - continue; - if (!found_picture || found_picture->base.poc > pic->base.poc || - (found_picture->base.poc == pic->base.poc && - found_picture->base.voc > pic->base.voc)) - found_picture = pic, found_index = i; - } + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + if (!fs->output_needed) + continue; + if (picture && picture->base.view_id != fs->view_id) + continue; + for (j = 0; j < fs->num_buffers; j++) { + GstVaapiPictureH264 *const pic = fs->buffers[j]; + if (!pic->output_needed) + continue; + if (!found_picture || found_picture->base.poc > pic->base.poc || + (found_picture->base.poc == pic->base.poc && + found_picture->base.voc > pic->base.voc)) + found_picture = pic, found_index = i; } + } - if (found_picture_ptr) - *found_picture_ptr = found_picture; - return found_picture ? found_index : -1; + if (found_picture_ptr) + *found_picture_ptr = found_picture; + return found_picture ? found_index : -1; } /* Finds the picture with the lowest VOC that needs to be output */ static gint -dpb_find_lowest_voc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, - GstVaapiPictureH264 **found_picture_ptr) +dpb_find_lowest_voc (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstVaapiPictureH264 ** found_picture_ptr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 *found_picture = NULL; - guint i, j, found_index; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 *found_picture = NULL; + guint i, j, found_index; - for (i = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - if (!fs->output_needed || fs->view_id == picture->base.view_id) - continue; - for (j = 0; j < fs->num_buffers; j++) { - GstVaapiPictureH264 * const pic = fs->buffers[j]; - if (!pic->output_needed || pic->base.poc != picture->base.poc) - continue; - if (!found_picture || found_picture->base.voc > pic->base.voc) - found_picture = pic, found_index = i; - } + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + if (!fs->output_needed || fs->view_id == picture->base.view_id) + continue; + for (j = 0; j < fs->num_buffers; j++) { + GstVaapiPictureH264 *const pic = fs->buffers[j]; + if (!pic->output_needed || pic->base.poc != picture->base.poc) + continue; + if (!found_picture || found_picture->base.voc > pic->base.voc) + found_picture = pic, found_index = i; } + } - if (found_picture_ptr) - *found_picture_ptr = found_picture; - return found_picture ? found_index : -1; + if (found_picture_ptr) + *found_picture_ptr = found_picture; + return found_picture ? found_index : -1; } static gboolean -dpb_output_other_views(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, guint voc) +dpb_output_other_views (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, guint voc) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 *found_picture; - gint found_index; - gboolean success; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 *found_picture; + gint found_index; + gboolean success; - if (priv->max_views == 1) - return TRUE; - - /* Emit all other view components that were in the same access - unit than the picture we have just found */ - found_picture = picture; - for (;;) { - found_index = dpb_find_lowest_voc(decoder, found_picture, - &found_picture); - if (found_index < 0 || found_picture->base.voc >= voc) - break; - success = dpb_output(decoder, priv->dpb[found_index]); - dpb_evict(decoder, found_picture, found_index); - if (!success) - return FALSE; - } + if (priv->max_views == 1) return TRUE; + + /* Emit all other view components that were in the same access + unit than the picture we have just found */ + found_picture = picture; + for (;;) { + found_index = dpb_find_lowest_voc (decoder, found_picture, &found_picture); + if (found_index < 0 || found_picture->base.voc >= voc) + break; + success = dpb_output (decoder, priv->dpb[found_index]); + dpb_evict (decoder, found_picture, found_index); + if (!success) + return FALSE; + } + return TRUE; } static gboolean -dpb_bump(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +dpb_bump (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 *found_picture; - gint found_index; - gboolean success; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 *found_picture; + gint found_index; + gboolean success; - found_index = dpb_find_lowest_poc(decoder, picture, &found_picture); - if (found_index < 0) - return FALSE; + found_index = dpb_find_lowest_poc (decoder, picture, &found_picture); + if (found_index < 0) + return FALSE; - if (picture && picture->base.poc != found_picture->base.poc) - dpb_output_other_views(decoder, found_picture, found_picture->base.voc); + if (picture && picture->base.poc != found_picture->base.poc) + dpb_output_other_views (decoder, found_picture, found_picture->base.voc); - success = dpb_output(decoder, priv->dpb[found_index]); - dpb_evict(decoder, found_picture, found_index); - if (priv->max_views == 1) - return success; - - if (picture && picture->base.poc != found_picture->base.poc) - dpb_output_other_views(decoder, found_picture, G_MAXUINT32); + success = dpb_output (decoder, priv->dpb[found_index]); + dpb_evict (decoder, found_picture, found_index); + if (priv->max_views == 1) return success; + + if (picture && picture->base.poc != found_picture->base.poc) + dpb_output_other_views (decoder, found_picture, G_MAXUINT32); + return success; } static void -dpb_clear(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +dpb_clear (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - guint i, n; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + guint i, n; - for (i = 0; i < priv->dpb_count; i++) { - if (picture && picture->base.view_id != priv->dpb[i]->view_id) - continue; - gst_vaapi_frame_store_replace(&priv->dpb[i], NULL); - } + for (i = 0; i < priv->dpb_count; i++) { + if (picture && picture->base.view_id != priv->dpb[i]->view_id) + continue; + gst_vaapi_frame_store_replace (&priv->dpb[i], NULL); + } - /* Compact the resulting DPB, i.e. remove holes */ - for (i = 0, n = 0; i < priv->dpb_count; i++) { - if (priv->dpb[i]) { - if (i != n) { - priv->dpb[n] = priv->dpb[i]; - priv->dpb[i] = NULL; - } - n++; - } + /* Compact the resulting DPB, i.e. remove holes */ + for (i = 0, n = 0; i < priv->dpb_count; i++) { + if (priv->dpb[i]) { + if (i != n) { + priv->dpb[n] = priv->dpb[i]; + priv->dpb[i] = NULL; + } + n++; } - priv->dpb_count = n; + } + priv->dpb_count = n; - /* Clear previous frame buffers only if this is a "flush-all" operation, - or if the picture is the first one in the access unit */ - if (priv->prev_frames && (!picture || - GST_VAAPI_PICTURE_FLAG_IS_SET(picture, - GST_VAAPI_PICTURE_FLAG_AU_START))) { - for (i = 0; i < priv->max_views; i++) - gst_vaapi_frame_store_replace(&priv->prev_frames[i], NULL); - } + /* Clear previous frame buffers only if this is a "flush-all" operation, + or if the picture is the first one in the access unit */ + if (priv->prev_frames && (!picture || + GST_VAAPI_PICTURE_FLAG_IS_SET (picture, + GST_VAAPI_PICTURE_FLAG_AU_START))) { + for (i = 0; i < priv->max_views; i++) + gst_vaapi_frame_store_replace (&priv->prev_frames[i], NULL); + } - /* Clear previous reference frame buffers only if this is a "flush-all" - operation, or if the picture is part of an IDR NAL */ - if (priv->prev_ref_frames && (!picture || - GST_VAAPI_PICTURE_FLAG_IS_SET(picture, - GST_VAAPI_PICTURE_FLAG_IDR))) { - for (i = 0; i < priv->max_views; i++) - gst_vaapi_frame_store_replace(&priv->prev_ref_frames[i], NULL); - } + /* Clear previous reference frame buffers only if this is a "flush-all" + operation, or if the picture is part of an IDR NAL */ + if (priv->prev_ref_frames && (!picture || + GST_VAAPI_PICTURE_FLAG_IS_SET (picture, + GST_VAAPI_PICTURE_FLAG_IDR))) { + for (i = 0; i < priv->max_views; i++) + gst_vaapi_frame_store_replace (&priv->prev_ref_frames[i], NULL); + } } static void -dpb_flush(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +dpb_flush (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - guint i; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + guint i; - /* Detect broken frames and mark them as having a single field if - needed */ - for (i = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - if (!fs->output_needed || gst_vaapi_frame_store_is_complete(fs)) - continue; - GST_VAAPI_PICTURE_FLAG_SET(fs->buffers[0], - GST_VAAPI_PICTURE_FLAG_ONEFIELD); - } + /* Detect broken frames and mark them as having a single field if + needed */ + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + if (!fs->output_needed || gst_vaapi_frame_store_is_complete (fs)) + continue; + GST_VAAPI_PICTURE_FLAG_SET (fs->buffers[0], + GST_VAAPI_PICTURE_FLAG_ONEFIELD); + } - /* Output any frame remaining in DPB */ - while (dpb_bump(decoder, picture)) - ; - dpb_clear(decoder, picture); + /* Output any frame remaining in DPB */ + while (dpb_bump (decoder, picture)); + dpb_clear (decoder, picture); } static void -dpb_prune_mvc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +dpb_prune_mvc (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - const gboolean is_last_picture = /* in the access unit */ - GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_AU_END); - guint i; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + const gboolean is_last_picture = /* in the access unit */ + GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_END); + guint i; - // Remove all unused inter-view only reference components of the current AU + // Remove all unused inter-view only reference components of the current AU + i = 0; + while (i < priv->dpb_count) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + if (fs->view_id != picture->base.view_id && + !fs->output_needed && !gst_vaapi_frame_store_has_reference (fs) && + (is_last_picture || + !is_inter_view_reference_for_next_frames (decoder, fs))) + dpb_remove_index (decoder, i); + else + i++; + } +} + +static gboolean +dpb_add (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) +{ + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiFrameStore *fs; + guint i; + + if (priv->max_views > 1) + dpb_prune_mvc (decoder, picture); + + // Remove all unused pictures + if (!GST_VAAPI_PICTURE_IS_IDR (picture)) { i = 0; while (i < priv->dpb_count) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - if (fs->view_id != picture->base.view_id && - !fs->output_needed && !gst_vaapi_frame_store_has_reference(fs) && - (is_last_picture || - !is_inter_view_reference_for_next_frames(decoder, fs))) - dpb_remove_index(decoder, i); - else - i++; + GstVaapiFrameStore *const fs = priv->dpb[i]; + if (fs->view_id == picture->base.view_id && + !fs->output_needed && !gst_vaapi_frame_store_has_reference (fs)) + dpb_remove_index (decoder, i); + else + i++; } -} - -static gboolean -dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) -{ - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiFrameStore *fs; - guint i; - - if (priv->max_views > 1) - dpb_prune_mvc(decoder, picture); - - // Remove all unused pictures - if (!GST_VAAPI_PICTURE_IS_IDR(picture)) { - i = 0; - while (i < priv->dpb_count) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - if (fs->view_id == picture->base.view_id && - !fs->output_needed && !gst_vaapi_frame_store_has_reference(fs)) - dpb_remove_index(decoder, i); - else - i++; - } - } - - // Check if picture is the second field and the first field is still in DPB - if (GST_VAAPI_PICTURE_IS_INTERLACED(picture) && - !GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture)) { - fs = priv->prev_frames[picture->base.voc]; - if (!fs || &fs->buffers[0]->base != picture->base.parent_picture) - return FALSE; - if (!gst_vaapi_frame_store_add(fs, picture)) - return FALSE; - - if (fs->output_called) - return dpb_output(decoder, fs); - return TRUE; - } - - // Try to output the previous frame again if it was not submitted yet - // e.g. delayed while waiting for the next field, or a field gap was closed + } + // Check if picture is the second field and the first field is still in DPB + if (GST_VAAPI_PICTURE_IS_INTERLACED (picture) && + !GST_VAAPI_PICTURE_IS_FIRST_FIELD (picture)) { fs = priv->prev_frames[picture->base.voc]; - if (fs && fs->output_called) - dpb_output(decoder, fs); + if (!fs || &fs->buffers[0]->base != picture->base.parent_picture) + return FALSE; + if (!gst_vaapi_frame_store_add (fs, picture)) + return FALSE; - // Create new frame store, and split fields if necessary - fs = gst_vaapi_frame_store_new(picture); - if (!fs) - return FALSE; - gst_vaapi_frame_store_replace(&priv->prev_frames[picture->base.voc], fs); - gst_vaapi_frame_store_unref(fs); - - if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) { - if (!gst_vaapi_frame_store_split_fields(fs, priv->top_field_first)) - return FALSE; - } - - // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB - if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { - while (priv->dpb_count == priv->dpb_size) { - if (!dpb_bump(decoder, picture)) - return FALSE; - } - gst_vaapi_frame_store_replace(&priv->prev_ref_frames[picture->base.voc], - fs); - } - - // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB - else { - const gboolean StoreInterViewOnlyRefFlag = - !GST_VAAPI_PICTURE_FLAG_IS_SET(picture, - GST_VAAPI_PICTURE_FLAG_AU_END) && - GST_VAAPI_PICTURE_FLAG_IS_SET(picture, - GST_VAAPI_PICTURE_FLAG_INTER_VIEW); - if (!picture->output_flag && !StoreInterViewOnlyRefFlag) - return TRUE; - while (priv->dpb_count == priv->dpb_size) { - GstVaapiPictureH264 *found_picture; - if (!StoreInterViewOnlyRefFlag) { - if (dpb_find_lowest_poc(decoder, picture, &found_picture) < 0 || - found_picture->base.poc > picture->base.poc) - return dpb_output(decoder, fs); - } - if (!dpb_bump(decoder, picture)) - return FALSE; - } - } - gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs); + if (fs->output_called) + return dpb_output (decoder, fs); return TRUE; + } + // Try to output the previous frame again if it was not submitted yet + // e.g. delayed while waiting for the next field, or a field gap was closed + fs = priv->prev_frames[picture->base.voc]; + if (fs && fs->output_called) + dpb_output (decoder, fs); + + // Create new frame store, and split fields if necessary + fs = gst_vaapi_frame_store_new (picture); + if (!fs) + return FALSE; + gst_vaapi_frame_store_replace (&priv->prev_frames[picture->base.voc], fs); + gst_vaapi_frame_store_unref (fs); + + if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame (fs)) { + if (!gst_vaapi_frame_store_split_fields (fs, priv->top_field_first)) + return FALSE; + } + // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB + if (GST_VAAPI_PICTURE_IS_REFERENCE (picture)) { + while (priv->dpb_count == priv->dpb_size) { + if (!dpb_bump (decoder, picture)) + return FALSE; + } + gst_vaapi_frame_store_replace (&priv->prev_ref_frames[picture->base.voc], + fs); + } + // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB + else { + const gboolean StoreInterViewOnlyRefFlag = + !GST_VAAPI_PICTURE_FLAG_IS_SET (picture, + GST_VAAPI_PICTURE_FLAG_AU_END) && + GST_VAAPI_PICTURE_FLAG_IS_SET (picture, + GST_VAAPI_PICTURE_FLAG_INTER_VIEW); + if (!picture->output_flag && !StoreInterViewOnlyRefFlag) + return TRUE; + while (priv->dpb_count == priv->dpb_size) { + GstVaapiPictureH264 *found_picture; + if (!StoreInterViewOnlyRefFlag) { + if (dpb_find_lowest_poc (decoder, picture, &found_picture) < 0 || + found_picture->base.poc > picture->base.poc) + return dpb_output (decoder, fs); + } + if (!dpb_bump (decoder, picture)) + return FALSE; + } + } + gst_vaapi_frame_store_replace (&priv->dpb[priv->dpb_count++], fs); + return TRUE; } static gboolean -dpb_reset(GstVaapiDecoderH264 *decoder, guint dpb_size) +dpb_reset (GstVaapiDecoderH264 * decoder, guint dpb_size) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiDecoderH264Private *const priv = &decoder->priv; - if (dpb_size > priv->dpb_size_max) { - priv->dpb = g_try_realloc_n(priv->dpb, dpb_size, sizeof(*priv->dpb)); - if (!priv->dpb) - return FALSE; - memset(&priv->dpb[priv->dpb_size_max], 0, - (dpb_size - priv->dpb_size_max) * sizeof(*priv->dpb)); - priv->dpb_size_max = dpb_size; - } - priv->dpb_size = dpb_size; + if (dpb_size > priv->dpb_size_max) { + priv->dpb = g_try_realloc_n (priv->dpb, dpb_size, sizeof (*priv->dpb)); + if (!priv->dpb) + return FALSE; + memset (&priv->dpb[priv->dpb_size_max], 0, + (dpb_size - priv->dpb_size_max) * sizeof (*priv->dpb)); + priv->dpb_size_max = dpb_size; + } + priv->dpb_size = dpb_size; - GST_DEBUG("DPB size %u", priv->dpb_size); - return TRUE; + GST_DEBUG ("DPB size %u", priv->dpb_size); + return TRUE; } static void -unref_inter_view(GstVaapiPictureH264 *picture) +unref_inter_view (GstVaapiPictureH264 * picture) { - if (!picture) - return; - GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAG_INTER_VIEW); - gst_vaapi_picture_unref(picture); + if (!picture) + return; + GST_VAAPI_PICTURE_FLAG_UNSET (picture, GST_VAAPI_PICTURE_FLAG_INTER_VIEW); + gst_vaapi_picture_unref (picture); } /* Resets MVC resources */ static gboolean -mvc_reset(GstVaapiDecoderH264 *decoder) +mvc_reset (GstVaapiDecoderH264 * decoder) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - guint i; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + guint i; - // Resize array of inter-view references - if (!priv->inter_views) { - priv->inter_views = g_ptr_array_new_full(priv->max_views, - (GDestroyNotify)unref_inter_view); - if (!priv->inter_views) - return FALSE; - } + // Resize array of inter-view references + if (!priv->inter_views) { + priv->inter_views = g_ptr_array_new_full (priv->max_views, + (GDestroyNotify) unref_inter_view); + if (!priv->inter_views) + return FALSE; + } + // Resize array of previous frame buffers + for (i = priv->max_views; i < priv->prev_frames_alloc; i++) { + gst_vaapi_frame_store_replace (&priv->prev_ref_frames[i], NULL); + gst_vaapi_frame_store_replace (&priv->prev_frames[i], NULL); + } - // Resize array of previous frame buffers - for (i = priv->max_views; i < priv->prev_frames_alloc; i++) { - gst_vaapi_frame_store_replace(&priv->prev_ref_frames[i], NULL); - gst_vaapi_frame_store_replace(&priv->prev_frames[i], NULL); - } + priv->prev_ref_frames = g_try_realloc_n (priv->prev_ref_frames, + priv->max_views, sizeof (*priv->prev_ref_frames)); + if (!priv->prev_ref_frames) + goto error_allocate; - priv->prev_ref_frames = g_try_realloc_n(priv->prev_ref_frames, - priv->max_views, sizeof(*priv->prev_ref_frames)); - if (!priv->prev_ref_frames) - goto error_allocate; + priv->prev_frames = g_try_realloc_n (priv->prev_frames, priv->max_views, + sizeof (*priv->prev_frames)); + if (!priv->prev_frames) + goto error_allocate; - priv->prev_frames = g_try_realloc_n(priv->prev_frames, priv->max_views, - sizeof(*priv->prev_frames)); - if (!priv->prev_frames) - goto error_allocate; + for (i = priv->prev_frames_alloc; i < priv->max_views; i++) { + priv->prev_ref_frames[i] = NULL; + priv->prev_frames[i] = NULL; + } + priv->prev_frames_alloc = priv->max_views; + return TRUE; - for (i = priv->prev_frames_alloc; i < priv->max_views; i++) { - priv->prev_ref_frames[i] = NULL; - priv->prev_frames[i] = NULL; - } - priv->prev_frames_alloc = priv->max_views; - return TRUE; - - /* ERRORS */ + /* ERRORS */ error_allocate: - g_free(priv->prev_ref_frames); - priv->prev_ref_frames = NULL; - g_free(priv->prev_frames); - priv->prev_frames = NULL; - priv->prev_frames_alloc = 0; - return FALSE; + g_free (priv->prev_ref_frames); + priv->prev_ref_frames = NULL; + g_free (priv->prev_frames); + priv->prev_frames = NULL; + priv->prev_frames_alloc = 0; + return FALSE; } static GstVaapiDecoderStatus -get_status(GstH264ParserResult result) +get_status (GstH264ParserResult result) { - GstVaapiDecoderStatus status; + GstVaapiDecoderStatus status; - switch (result) { + switch (result) { case GST_H264_PARSER_OK: - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; case GST_H264_PARSER_NO_NAL_END: - status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - break; + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + break; case GST_H264_PARSER_ERROR: - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - break; + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; default: - status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - break; - } - return status; + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + break; + } + return status; } static void -gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder) +gst_vaapi_decoder_h264_close (GstVaapiDecoderH264 * decoder) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiDecoderH264Private *const priv = &decoder->priv; - gst_vaapi_picture_replace(&priv->current_picture, NULL); - gst_vaapi_picture_replace(&priv->missing_picture, NULL); - gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL); - gst_vaapi_parser_info_h264_replace(&priv->prev_pi, NULL); + gst_vaapi_picture_replace (&priv->current_picture, NULL); + gst_vaapi_picture_replace (&priv->missing_picture, NULL); + gst_vaapi_parser_info_h264_replace (&priv->prev_slice_pi, NULL); + gst_vaapi_parser_info_h264_replace (&priv->prev_pi, NULL); - dpb_clear(decoder, NULL); + dpb_clear (decoder, NULL); - if (priv->inter_views) { - g_ptr_array_unref(priv->inter_views); - priv->inter_views = NULL; - } + if (priv->inter_views) { + g_ptr_array_unref (priv->inter_views); + priv->inter_views = NULL; + } - if (priv->parser) { - gst_h264_nal_parser_free(priv->parser); - priv->parser = NULL; - } + if (priv->parser) { + gst_h264_nal_parser_free (priv->parser); + priv->parser = NULL; + } } static gboolean -gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder) +gst_vaapi_decoder_h264_open (GstVaapiDecoderH264 * decoder) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiDecoderH264Private *const priv = &decoder->priv; - gst_vaapi_decoder_h264_close(decoder); + gst_vaapi_decoder_h264_close (decoder); - priv->parser = gst_h264_nal_parser_new(); - if (!priv->parser) - return FALSE; - return TRUE; + priv->parser = gst_h264_nal_parser_new (); + if (!priv->parser) + return FALSE; + return TRUE; } static void -gst_vaapi_decoder_h264_destroy(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_h264_destroy (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderH264 * const decoder = - GST_VAAPI_DECODER_H264_CAST(base_decoder); - GstVaapiDecoderH264Private * const priv = &decoder->priv; - guint i; + GstVaapiDecoderH264 *const decoder = + GST_VAAPI_DECODER_H264_CAST (base_decoder); + GstVaapiDecoderH264Private *const priv = &decoder->priv; + guint i; - gst_vaapi_decoder_h264_close(decoder); + gst_vaapi_decoder_h264_close (decoder); - g_free(priv->dpb); - priv->dpb = NULL; - priv->dpb_size = 0; + g_free (priv->dpb); + priv->dpb = NULL; + priv->dpb_size = 0; - g_free(priv->prev_ref_frames); - priv->prev_ref_frames = NULL; - g_free(priv->prev_frames); - priv->prev_frames = NULL; - priv->prev_frames_alloc = 0; + g_free (priv->prev_ref_frames); + priv->prev_ref_frames = NULL; + g_free (priv->prev_frames); + priv->prev_frames = NULL; + priv->prev_frames_alloc = 0; - for (i = 0; i < G_N_ELEMENTS(priv->pps); i++) - gst_vaapi_parser_info_h264_replace(&priv->pps[i], NULL); - gst_vaapi_parser_info_h264_replace(&priv->active_pps, NULL); + for (i = 0; i < G_N_ELEMENTS (priv->pps); i++) + gst_vaapi_parser_info_h264_replace (&priv->pps[i], NULL); + gst_vaapi_parser_info_h264_replace (&priv->active_pps, NULL); - for (i = 0; i < G_N_ELEMENTS(priv->sps); i++) - gst_vaapi_parser_info_h264_replace(&priv->sps[i], NULL); - gst_vaapi_parser_info_h264_replace(&priv->active_sps, NULL); + for (i = 0; i < G_N_ELEMENTS (priv->sps); i++) + gst_vaapi_parser_info_h264_replace (&priv->sps[i], NULL); + gst_vaapi_parser_info_h264_replace (&priv->active_sps, NULL); } static gboolean -gst_vaapi_decoder_h264_create(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_h264_create (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderH264 * const decoder = - GST_VAAPI_DECODER_H264_CAST(base_decoder); - GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiDecoderH264 *const decoder = + GST_VAAPI_DECODER_H264_CAST (base_decoder); + GstVaapiDecoderH264Private *const priv = &decoder->priv; - priv->profile = GST_VAAPI_PROFILE_UNKNOWN; - priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD; - priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - priv->progressive_sequence = TRUE; - priv->top_field_first = FALSE; - return TRUE; + priv->profile = GST_VAAPI_PROFILE_UNKNOWN; + priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD; + priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + priv->progressive_sequence = TRUE; + priv->top_field_first = FALSE; + return TRUE; } /* Activates the supplied PPS */ static GstH264PPS * -ensure_pps(GstVaapiDecoderH264 *decoder, GstH264PPS *pps) +ensure_pps (GstVaapiDecoderH264 * decoder, GstH264PPS * pps) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = priv->pps[pps->id]; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = priv->pps[pps->id]; - gst_vaapi_parser_info_h264_replace(&priv->active_pps, pi); - return pi ? &pi->data.pps : NULL; + gst_vaapi_parser_info_h264_replace (&priv->active_pps, pi); + return pi ? &pi->data.pps : NULL; } /* Returns the active PPS */ static inline GstH264PPS * -get_pps(GstVaapiDecoderH264 *decoder) +get_pps (GstVaapiDecoderH264 * decoder) { - GstVaapiParserInfoH264 * const pi = decoder->priv.active_pps; + GstVaapiParserInfoH264 *const pi = decoder->priv.active_pps; - return pi ? &pi->data.pps : NULL; + return pi ? &pi->data.pps : NULL; } /* Activate the supplied SPS */ static GstH264SPS * -ensure_sps(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) +ensure_sps (GstVaapiDecoderH264 * decoder, GstH264SPS * sps) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = priv->sps[sps->id]; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = priv->sps[sps->id]; - /* Propagate "got I-frame" state to the next SPS unit if the - current sequence was not ended */ - if (pi && priv->active_sps) - pi->state |= (priv->active_sps->state & - GST_H264_VIDEO_STATE_GOT_I_FRAME); + /* Propagate "got I-frame" state to the next SPS unit if the + current sequence was not ended */ + if (pi && priv->active_sps) + pi->state |= (priv->active_sps->state & GST_H264_VIDEO_STATE_GOT_I_FRAME); - gst_vaapi_parser_info_h264_replace(&priv->active_sps, pi); - return pi ? &pi->data.sps : NULL; + gst_vaapi_parser_info_h264_replace (&priv->active_sps, pi); + return pi ? &pi->data.sps : NULL; } /* Returns the active SPS */ static inline GstH264SPS * -get_sps(GstVaapiDecoderH264 *decoder) +get_sps (GstVaapiDecoderH264 * decoder) { - GstVaapiParserInfoH264 * const pi = decoder->priv.active_sps; + GstVaapiParserInfoH264 *const pi = decoder->priv.active_sps; - return pi ? &pi->data.sps : NULL; + return pi ? &pi->data.sps : NULL; } static void -fill_profiles(GstVaapiProfile profiles[16], guint *n_profiles_ptr, +fill_profiles (GstVaapiProfile profiles[16], guint * n_profiles_ptr, GstVaapiProfile profile) { - guint n_profiles = *n_profiles_ptr; + guint n_profiles = *n_profiles_ptr; - profiles[n_profiles++] = profile; - switch (profile) { + profiles[n_profiles++] = profile; + switch (profile) { case GST_VAAPI_PROFILE_H264_MAIN: - profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; - break; + profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; + break; default: - break; - } - *n_profiles_ptr = n_profiles; + break; + } + *n_profiles_ptr = n_profiles; } /* Fills in compatible profiles for MVC decoding */ static void -fill_profiles_mvc(GstVaapiDecoderH264 *decoder, GstVaapiProfile profiles[16], - guint *n_profiles_ptr, guint dpb_size) +fill_profiles_mvc (GstVaapiDecoderH264 * decoder, GstVaapiProfile profiles[16], + guint * n_profiles_ptr, guint dpb_size) { - const gchar * const vendor_string = - gst_vaapi_display_get_vendor_string(GST_VAAPI_DECODER_DISPLAY(decoder)); + const gchar *const vendor_string = + gst_vaapi_display_get_vendor_string (GST_VAAPI_DECODER_DISPLAY (decoder)); - gboolean add_high_profile = FALSE; - struct map { - const gchar *str; - guint str_len; + gboolean add_high_profile = FALSE; + struct map + { + const gchar *str; + guint str_len; + }; + const struct map *m; + + // Drivers that support slice level decoding + if (vendor_string && dpb_size <= 16) { + static const struct map drv_names[] = { + {"Intel i965 driver", 17}, + {NULL, 0} }; - const struct map *m; - - // Drivers that support slice level decoding - if (vendor_string && dpb_size <= 16) { - static const struct map drv_names[] = { - { "Intel i965 driver", 17 }, - { NULL, 0 } - }; - for (m = drv_names; m->str != NULL && !add_high_profile; m++) { - if (g_ascii_strncasecmp(vendor_string, m->str, m->str_len) == 0) - add_high_profile = TRUE; - } + for (m = drv_names; m->str != NULL && !add_high_profile; m++) { + if (g_ascii_strncasecmp (vendor_string, m->str, m->str_len) == 0) + add_high_profile = TRUE; } + } - if (add_high_profile) - fill_profiles(profiles, n_profiles_ptr, GST_VAAPI_PROFILE_H264_HIGH); + if (add_high_profile) + fill_profiles (profiles, n_profiles_ptr, GST_VAAPI_PROFILE_H264_HIGH); } static GstVaapiProfile -get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps, guint dpb_size) +get_profile (GstVaapiDecoderH264 * decoder, GstH264SPS * sps, guint dpb_size) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder); - GstVaapiProfile profile, profiles[4]; - guint i, n_profiles = 0; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiDisplay *const display = GST_VAAPI_DECODER_DISPLAY (decoder); + GstVaapiProfile profile, profiles[4]; + guint i, n_profiles = 0; - profile = gst_vaapi_utils_h264_get_profile(sps->profile_idc); - if (!profile) - return GST_VAAPI_PROFILE_UNKNOWN; - - fill_profiles(profiles, &n_profiles, profile); - switch (profile) { - case GST_VAAPI_PROFILE_H264_BASELINE: - if (sps->constraint_set1_flag) { // A.2.2 (main profile) - fill_profiles(profiles, &n_profiles, - GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE); - fill_profiles(profiles, &n_profiles, - GST_VAAPI_PROFILE_H264_MAIN); - } - break; - case GST_VAAPI_PROFILE_H264_EXTENDED: - if (sps->constraint_set1_flag) { // A.2.2 (main profile) - fill_profiles(profiles, &n_profiles, - GST_VAAPI_PROFILE_H264_MAIN); - } - break; - case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH: - if (priv->max_views == 2) { - fill_profiles(profiles, &n_profiles, - GST_VAAPI_PROFILE_H264_STEREO_HIGH); - } - fill_profiles_mvc(decoder, profiles, &n_profiles, dpb_size); - break; - case GST_VAAPI_PROFILE_H264_STEREO_HIGH: - if (sps->frame_mbs_only_flag) { - fill_profiles(profiles, &n_profiles, - GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH); - } - fill_profiles_mvc(decoder, profiles, &n_profiles, dpb_size); - break; - default: - break; - } - - /* If the preferred profile (profiles[0]) matches one that we already - found, then just return it now instead of searching for it again */ - if (profiles[0] == priv->profile) - return priv->profile; - - for (i = 0; i < n_profiles; i++) { - if (gst_vaapi_display_has_decoder(display, profiles[i], priv->entrypoint)) - return profiles[i]; - } + profile = gst_vaapi_utils_h264_get_profile (sps->profile_idc); + if (!profile) return GST_VAAPI_PROFILE_UNKNOWN; + + fill_profiles (profiles, &n_profiles, profile); + switch (profile) { + case GST_VAAPI_PROFILE_H264_BASELINE: + if (sps->constraint_set1_flag) { // A.2.2 (main profile) + fill_profiles (profiles, &n_profiles, + GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE); + fill_profiles (profiles, &n_profiles, GST_VAAPI_PROFILE_H264_MAIN); + } + break; + case GST_VAAPI_PROFILE_H264_EXTENDED: + if (sps->constraint_set1_flag) { // A.2.2 (main profile) + fill_profiles (profiles, &n_profiles, GST_VAAPI_PROFILE_H264_MAIN); + } + break; + case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH: + if (priv->max_views == 2) { + fill_profiles (profiles, &n_profiles, + GST_VAAPI_PROFILE_H264_STEREO_HIGH); + } + fill_profiles_mvc (decoder, profiles, &n_profiles, dpb_size); + break; + case GST_VAAPI_PROFILE_H264_STEREO_HIGH: + if (sps->frame_mbs_only_flag) { + fill_profiles (profiles, &n_profiles, + GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH); + } + fill_profiles_mvc (decoder, profiles, &n_profiles, dpb_size); + break; + default: + break; + } + + /* If the preferred profile (profiles[0]) matches one that we already + found, then just return it now instead of searching for it again */ + if (profiles[0] == priv->profile) + return priv->profile; + + for (i = 0; i < n_profiles; i++) { + if (gst_vaapi_display_has_decoder (display, profiles[i], priv->entrypoint)) + return profiles[i]; + } + return GST_VAAPI_PROFILE_UNKNOWN; } static GstVaapiDecoderStatus -ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) +ensure_context (GstVaapiDecoderH264 * decoder, GstH264SPS * sps) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiContextInfo info; - GstVaapiProfile profile; - GstVaapiChromaType chroma_type; - gboolean reset_context = FALSE; - guint mb_width, mb_height, dpb_size, num_views; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER_CAST (decoder); + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiContextInfo info; + GstVaapiProfile profile; + GstVaapiChromaType chroma_type; + gboolean reset_context = FALSE; + guint mb_width, mb_height, dpb_size, num_views; - num_views = get_num_views(sps); - if (priv->max_views < num_views) { - priv->max_views = num_views; - GST_DEBUG("maximum number of views changed to %u", num_views); - } + num_views = get_num_views (sps); + if (priv->max_views < num_views) { + priv->max_views = num_views; + GST_DEBUG ("maximum number of views changed to %u", num_views); + } - dpb_size = get_max_dec_frame_buffering(sps); - if (priv->dpb_size < dpb_size) { - GST_DEBUG("DPB size increased"); - reset_context = TRUE; - } + dpb_size = get_max_dec_frame_buffering (sps); + if (priv->dpb_size < dpb_size) { + GST_DEBUG ("DPB size increased"); + reset_context = TRUE; + } - profile = get_profile(decoder, sps, dpb_size); - if (!profile) { - GST_ERROR("unsupported profile_idc %u", sps->profile_idc); - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - } + profile = get_profile (decoder, sps, dpb_size); + if (!profile) { + GST_ERROR ("unsupported profile_idc %u", sps->profile_idc); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } - if (!priv->profile || (priv->profile != profile && priv->max_views == 1)) { - GST_DEBUG("profile changed to %x", profile); - reset_context = TRUE; - priv->profile = profile; - } + if (!priv->profile || (priv->profile != profile && priv->max_views == 1)) { + GST_DEBUG ("profile changed to %x", profile); + reset_context = TRUE; + priv->profile = profile; + } - if (reset_context) { - switch (num_views) { - case 1: - /* Frame-packed mode details should be copied from the parser - * if we set NONE */ - gst_vaapi_decoder_set_multiview_mode (base_decoder, - num_views, GST_VIDEO_MULTIVIEW_MODE_NONE, - GST_VIDEO_MULTIVIEW_FLAGS_NONE); - break; - case 2: /* Assume stereo */ - if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { - GST_DEBUG ("Stereo profile - frame-by-frame output, %d views", num_views); - gst_vaapi_decoder_set_multiview_mode (base_decoder, - num_views, GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME, - GST_VIDEO_MULTIVIEW_FLAGS_NONE); - break; - } - /* non-stereo 2 views. Fall through */ - default: - GST_DEBUG ("Multiview profile - frame-by-frame output, %d views", num_views); - gst_vaapi_decoder_set_multiview_mode (base_decoder, - num_views, GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME, - GST_VIDEO_MULTIVIEW_FLAGS_NONE); - break; + if (reset_context) { + switch (num_views) { + case 1: + /* Frame-packed mode details should be copied from the parser + * if we set NONE */ + gst_vaapi_decoder_set_multiview_mode (base_decoder, + num_views, GST_VIDEO_MULTIVIEW_MODE_NONE, + GST_VIDEO_MULTIVIEW_FLAGS_NONE); + break; + case 2: /* Assume stereo */ + if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { + GST_DEBUG ("Stereo profile - frame-by-frame output, %d views", + num_views); + gst_vaapi_decoder_set_multiview_mode (base_decoder, num_views, + GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME, + GST_VIDEO_MULTIVIEW_FLAGS_NONE); + break; } + /* non-stereo 2 views. Fall through */ + default: + GST_DEBUG ("Multiview profile - frame-by-frame output, %d views", + num_views); + gst_vaapi_decoder_set_multiview_mode (base_decoder, num_views, + GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME, + GST_VIDEO_MULTIVIEW_FLAGS_NONE); + break; } + } - chroma_type = gst_vaapi_utils_h264_get_chroma_type(sps->chroma_format_idc); - if (!chroma_type) { - GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc); - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; - } + chroma_type = gst_vaapi_utils_h264_get_chroma_type (sps->chroma_format_idc); + if (!chroma_type) { + GST_ERROR ("unsupported chroma_format_idc %u", sps->chroma_format_idc); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; + } - if (priv->chroma_type != chroma_type) { - GST_DEBUG("chroma format changed"); - reset_context = TRUE; - priv->chroma_type = chroma_type; - } + if (priv->chroma_type != chroma_type) { + GST_DEBUG ("chroma format changed"); + reset_context = TRUE; + priv->chroma_type = chroma_type; + } - mb_width = sps->pic_width_in_mbs_minus1 + 1; - mb_height = (sps->pic_height_in_map_units_minus1 + 1) << - !sps->frame_mbs_only_flag; - if (priv->mb_width != mb_width || priv->mb_height != mb_height) { - GST_DEBUG("size changed"); - reset_context = TRUE; - priv->mb_width = mb_width; - priv->mb_height = mb_height; - } + mb_width = sps->pic_width_in_mbs_minus1 + 1; + mb_height = (sps->pic_height_in_map_units_minus1 + 1) << + !sps->frame_mbs_only_flag; + if (priv->mb_width != mb_width || priv->mb_height != mb_height) { + GST_DEBUG ("size changed"); + reset_context = TRUE; + priv->mb_width = mb_width; + priv->mb_height = mb_height; + } - if (priv->progressive_sequence != sps->frame_mbs_only_flag) { - GST_DEBUG("interlacing-mode changed"); - priv->progressive_sequence = sps->frame_mbs_only_flag; - gst_vaapi_decoder_set_interlaced(base_decoder, - !priv->progressive_sequence); - priv->top_field_first = FALSE; - } + if (priv->progressive_sequence != sps->frame_mbs_only_flag) { + GST_DEBUG ("interlacing-mode changed"); + priv->progressive_sequence = sps->frame_mbs_only_flag; + gst_vaapi_decoder_set_interlaced (base_decoder, + !priv->progressive_sequence); + priv->top_field_first = FALSE; + } - gst_vaapi_decoder_set_pixel_aspect_ratio( - base_decoder, - sps->vui_parameters.par_n, - sps->vui_parameters.par_d - ); + gst_vaapi_decoder_set_pixel_aspect_ratio (base_decoder, + sps->vui_parameters.par_n, sps->vui_parameters.par_d); - if (!reset_context && priv->has_context) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - /* XXX: fix surface size when cropping is implemented */ - info.profile = priv->profile; - info.entrypoint = priv->entrypoint; - info.chroma_type = priv->chroma_type; - info.width = sps->width; - info.height = sps->height; - info.ref_frames = dpb_size; - - if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - priv->has_context = TRUE; - - /* Reset DPB */ - if (!dpb_reset(decoder, dpb_size)) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - - /* Reset MVC data */ - if (!mvc_reset(decoder)) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + if (!reset_context && priv->has_context) return GST_VAAPI_DECODER_STATUS_SUCCESS; + + /* XXX: fix surface size when cropping is implemented */ + info.profile = priv->profile; + info.entrypoint = priv->entrypoint; + info.chroma_type = priv->chroma_type; + info.width = sps->width; + info.height = sps->height; + info.ref_frames = dpb_size; + + if (!gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + priv->has_context = TRUE; + + /* Reset DPB */ + if (!dpb_reset (decoder, dpb_size)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + /* Reset MVC data */ + if (!mvc_reset (decoder)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static void -fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps, - const GstH264SPS *sps) +fill_iq_matrix_4x4 (VAIQMatrixBufferH264 * iq_matrix, const GstH264PPS * pps, + const GstH264SPS * sps) { - guint i; + guint i; - /* There are always 6 4x4 scaling lists */ - g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4) == 6); - g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16); + /* There are always 6 4x4 scaling lists */ + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4) == 6); + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4[0]) == 16); - for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) - gst_h264_quant_matrix_4x4_get_raster_from_zigzag( - iq_matrix->ScalingList4x4[i], pps->scaling_lists_4x4[i]); + for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList4x4); i++) + gst_h264_quant_matrix_4x4_get_raster_from_zigzag (iq_matrix->ScalingList4x4 + [i], pps->scaling_lists_4x4[i]); } static void -fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps, - const GstH264SPS *sps) +fill_iq_matrix_8x8 (VAIQMatrixBufferH264 * iq_matrix, const GstH264PPS * pps, + const GstH264SPS * sps) { - guint i, n; + guint i, n; - /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */ - if (!pps->transform_8x8_mode_flag) - return; + /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */ + if (!pps->transform_8x8_mode_flag) + return; - g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8) >= 2); - g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64); + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8) >= 2); + g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8[0]) == 64); - n = (sps->chroma_format_idc != 3) ? 2 : 6; - for (i = 0; i < n; i++) { - gst_h264_quant_matrix_8x8_get_raster_from_zigzag( - iq_matrix->ScalingList8x8[i], pps->scaling_lists_8x8[i]); - } + n = (sps->chroma_format_idc != 3) ? 2 : 6; + for (i = 0; i < n; i++) { + gst_h264_quant_matrix_8x8_get_raster_from_zigzag (iq_matrix->ScalingList8x8 + [i], pps->scaling_lists_8x8[i]); + } } static GstVaapiDecoderStatus -ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +ensure_quant_matrix (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture) { - GstVaapiPicture * const base_picture = &picture->base; - GstH264PPS * const pps = get_pps(decoder); - GstH264SPS * const sps = get_sps(decoder); - VAIQMatrixBufferH264 *iq_matrix; + GstVaapiPicture *const base_picture = &picture->base; + GstH264PPS *const pps = get_pps (decoder); + GstH264SPS *const sps = get_sps (decoder); + VAIQMatrixBufferH264 *iq_matrix; - base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder); - if (!base_picture->iq_matrix) { - GST_ERROR("failed to allocate IQ matrix"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - iq_matrix = base_picture->iq_matrix->param; + base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW (H264, decoder); + if (!base_picture->iq_matrix) { + GST_ERROR ("failed to allocate IQ matrix"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + iq_matrix = base_picture->iq_matrix->param; - /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[] - is not large enough to hold lists for 4:4:4 */ - if (sps->chroma_format_idc == 3) - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; + /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[] + is not large enough to hold lists for 4:4:4 */ + if (sps->chroma_format_idc == 3) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; - fill_iq_matrix_4x4(iq_matrix, pps, sps); - fill_iq_matrix_8x8(iq_matrix, pps, sps); + fill_iq_matrix_4x4 (iq_matrix, pps, sps); + fill_iq_matrix_8x8 (iq_matrix, pps, sps); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static inline gboolean -is_valid_state(guint state, guint ref_state) +is_valid_state (guint state, guint ref_state) { - return (state & ref_state) == ref_state; + return (state & ref_state) == ref_state; } static GstVaapiDecoderStatus -decode_current_picture(GstVaapiDecoderH264 *decoder) +decode_current_picture (GstVaapiDecoderH264 * decoder) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const sps_pi = decoder->priv.active_sps; - GstVaapiPictureH264 * const picture = priv->current_picture; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const sps_pi = decoder->priv.active_sps; + GstVaapiPictureH264 *const picture = priv->current_picture; - if (!is_valid_state(priv->decoder_state, - GST_H264_VIDEO_STATE_VALID_PICTURE)) - goto drop_frame; + if (!is_valid_state (priv->decoder_state, GST_H264_VIDEO_STATE_VALID_PICTURE)) + goto drop_frame; - priv->decoder_state |= sps_pi->state; - if (!(priv->decoder_state & GST_H264_VIDEO_STATE_GOT_I_FRAME)) { - if (priv->decoder_state & GST_H264_VIDEO_STATE_GOT_P_SLICE) - goto drop_frame; - sps_pi->state |= GST_H264_VIDEO_STATE_GOT_I_FRAME; - } + priv->decoder_state |= sps_pi->state; + if (!(priv->decoder_state & GST_H264_VIDEO_STATE_GOT_I_FRAME)) { + if (priv->decoder_state & GST_H264_VIDEO_STATE_GOT_P_SLICE) + goto drop_frame; + sps_pi->state |= GST_H264_VIDEO_STATE_GOT_I_FRAME; + } - priv->decoder_state = 0; - priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME; + priv->decoder_state = 0; + priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME; - if (!picture) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture))) - goto error; - if (!exec_ref_pic_marking(decoder, picture)) - goto error; - if (!dpb_add(decoder, picture)) - goto error; - gst_vaapi_picture_replace(&priv->current_picture, NULL); + if (!picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_vaapi_picture_decode (GST_VAAPI_PICTURE_CAST (picture))) + goto error; + if (!exec_ref_pic_marking (decoder, picture)) + goto error; + if (!dpb_add (decoder, picture)) + goto error; + gst_vaapi_picture_replace (&priv->current_picture, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; + 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; + /* 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; drop_frame: - priv->decoder_state = 0; - priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME; - return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; + priv->decoder_state = 0; + priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; } static GstVaapiDecoderStatus -parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +parse_sps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GstH264SPS * const sps = &pi->data.sps; - GstH264ParserResult result; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + GstH264SPS *const sps = &pi->data.sps; + GstH264ParserResult result; - GST_DEBUG("parse SPS"); + GST_DEBUG ("parse SPS"); - priv->parser_state = 0; + priv->parser_state = 0; - /* Variables that don't have inferred values per the H.264 - standard but that should get a default value anyway */ - sps->log2_max_pic_order_cnt_lsb_minus4 = 0; + /* Variables that don't have inferred values per the H.264 + standard but that should get a default value anyway */ + sps->log2_max_pic_order_cnt_lsb_minus4 = 0; - result = gst_h264_parser_parse_sps(priv->parser, &pi->nalu, sps, TRUE); - if (result != GST_H264_PARSER_OK) - return get_status(result); + result = gst_h264_parser_parse_sps (priv->parser, &pi->nalu, sps, TRUE); + if (result != GST_H264_PARSER_OK) + return get_status (result); - priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_subset_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +parse_subset_sps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GstH264SPS * const sps = &pi->data.sps; - GstH264ParserResult result; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + GstH264SPS *const sps = &pi->data.sps; + GstH264ParserResult result; - GST_DEBUG("parse subset SPS"); + GST_DEBUG ("parse subset SPS"); - /* Variables that don't have inferred values per the H.264 - standard but that should get a default value anyway */ - sps->log2_max_pic_order_cnt_lsb_minus4 = 0; + /* Variables that don't have inferred values per the H.264 + standard but that should get a default value anyway */ + sps->log2_max_pic_order_cnt_lsb_minus4 = 0; - result = gst_h264_parser_parse_subset_sps(priv->parser, &pi->nalu, sps, - TRUE); - if (result != GST_H264_PARSER_OK) - return get_status(result); + result = gst_h264_parser_parse_subset_sps (priv->parser, &pi->nalu, sps, + TRUE); + if (result != GST_H264_PARSER_OK) + return get_status (result); - priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +parse_pps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GstH264PPS * const pps = &pi->data.pps; - GstH264ParserResult result; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + GstH264PPS *const pps = &pi->data.pps; + GstH264ParserResult result; - GST_DEBUG("parse PPS"); + GST_DEBUG ("parse PPS"); - priv->parser_state &= GST_H264_VIDEO_STATE_GOT_SPS; + priv->parser_state &= GST_H264_VIDEO_STATE_GOT_SPS; - /* Variables that don't have inferred values per the H.264 - standard but that should get a default value anyway */ - pps->slice_group_map_type = 0; - pps->slice_group_change_rate_minus1 = 0; - pps->slice_group_id = NULL; + /* Variables that don't have inferred values per the H.264 + standard but that should get a default value anyway */ + pps->slice_group_map_type = 0; + pps->slice_group_change_rate_minus1 = 0; + pps->slice_group_id = NULL; - result = gst_h264_parser_parse_pps(priv->parser, &pi->nalu, pps); - if (result != GST_H264_PARSER_OK) - return get_status(result); + result = gst_h264_parser_parse_pps (priv->parser, &pi->nalu, pps); + if (result != GST_H264_PARSER_OK) + return get_status (result); - priv->parser_state |= GST_H264_VIDEO_STATE_GOT_PPS; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_PPS; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +parse_sei (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GArray ** const sei_ptr = &pi->data.sei; - GstH264ParserResult result; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + GArray **const sei_ptr = &pi->data.sei; + GstH264ParserResult result; - GST_DEBUG("parse SEI"); + GST_DEBUG ("parse SEI"); - result = gst_h264_parser_parse_sei(priv->parser, &pi->nalu, sei_ptr); - if (result != GST_H264_PARSER_OK) { - GST_WARNING("failed to parse SEI messages"); - return get_status(result); - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; + result = gst_h264_parser_parse_sei (priv->parser, &pi->nalu, sei_ptr); + if (result != GST_H264_PARSER_OK) { + GST_WARNING ("failed to parse SEI messages"); + return get_status (result); + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +parse_slice (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; - GstH264NalUnit * const nalu = &pi->nalu; - GstH264SPS *sps; - GstH264ParserResult result; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + GstH264SliceHdr *const slice_hdr = &pi->data.slice_hdr; + GstH264NalUnit *const nalu = &pi->nalu; + GstH264SPS *sps; + GstH264ParserResult result; - GST_DEBUG("parse slice"); + GST_DEBUG ("parse slice"); - priv->parser_state &= (GST_H264_VIDEO_STATE_GOT_SPS| - GST_H264_VIDEO_STATE_GOT_PPS); + priv->parser_state &= (GST_H264_VIDEO_STATE_GOT_SPS | + GST_H264_VIDEO_STATE_GOT_PPS); - /* Propagate Prefix NAL unit info, if necessary */ - switch (nalu->type) { + /* Propagate Prefix NAL unit info, if necessary */ + switch (nalu->type) { case GST_H264_NAL_SLICE: - case GST_H264_NAL_SLICE_IDR: { - GstVaapiParserInfoH264 * const prev_pi = priv->prev_pi; - if (prev_pi && prev_pi->nalu.type == GST_H264_NAL_PREFIX_UNIT) { - /* MVC sequences shall have a Prefix NAL unit immediately - preceding this NAL unit */ - pi->nalu.extension_type = prev_pi->nalu.extension_type; - pi->nalu.extension = prev_pi->nalu.extension; - } - else { - /* In the very unlikely case there is no Prefix NAL unit - immediately preceding this NAL unit, try to infer some - defaults (H.7.4.1.1) */ - GstH264NalUnitExtensionMVC * const mvc = &pi->nalu.extension.mvc; - mvc->non_idr_flag = !(nalu->type == GST_H264_NAL_SLICE_IDR); - nalu->idr_pic_flag = !mvc->non_idr_flag; - mvc->priority_id = 0; - mvc->view_id = 0; - mvc->temporal_id = 0; - mvc->anchor_pic_flag = 0; - mvc->inter_view_flag = 1; - } + case GST_H264_NAL_SLICE_IDR:{ + GstVaapiParserInfoH264 *const prev_pi = priv->prev_pi; + if (prev_pi && prev_pi->nalu.type == GST_H264_NAL_PREFIX_UNIT) { + /* MVC sequences shall have a Prefix NAL unit immediately + preceding this NAL unit */ + pi->nalu.extension_type = prev_pi->nalu.extension_type; + pi->nalu.extension = prev_pi->nalu.extension; + } else { + /* In the very unlikely case there is no Prefix NAL unit + immediately preceding this NAL unit, try to infer some + defaults (H.7.4.1.1) */ + GstH264NalUnitExtensionMVC *const mvc = &pi->nalu.extension.mvc; + mvc->non_idr_flag = !(nalu->type == GST_H264_NAL_SLICE_IDR); + nalu->idr_pic_flag = !mvc->non_idr_flag; + mvc->priority_id = 0; + mvc->view_id = 0; + mvc->temporal_id = 0; + mvc->anchor_pic_flag = 0; + mvc->inter_view_flag = 1; + } + break; + } + } + + /* Variables that don't have inferred values per the H.264 + standard but that should get a default value anyway */ + slice_hdr->cabac_init_idc = 0; + slice_hdr->direct_spatial_mv_pred_flag = 0; + + result = gst_h264_parser_parse_slice_hdr (priv->parser, &pi->nalu, + slice_hdr, TRUE, TRUE); + if (result != GST_H264_PARSER_OK) + return get_status (result); + + sps = slice_hdr->pps->sequence; + + /* Update MVC data */ + pi->view_id = get_view_id (&pi->nalu); + pi->voc = get_view_order_index (sps, pi->view_id); + + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SLICE; + if (!GST_H264_IS_I_SLICE (slice_hdr)) + priv->parser_state |= GST_H264_VIDEO_STATE_GOT_P_SLICE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + GstH264SPS *const sps = &pi->data.sps; + + GST_DEBUG ("decode SPS"); + + gst_vaapi_parser_info_h264_replace (&priv->sps[sps->id], pi); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_subset_sps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + GstH264SPS *const sps = &pi->data.sps; + + GST_DEBUG ("decode subset SPS"); + + gst_vaapi_parser_info_h264_replace (&priv->sps[sps->id], pi); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_pps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + GstH264PPS *const pps = &pi->data.pps; + + GST_DEBUG ("decode PPS"); + + gst_vaapi_parser_info_h264_replace (&priv->pps[pps->id], pi); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sei (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + guint i; + + GST_DEBUG ("decode SEI messages"); + + for (i = 0; i < pi->data.sei->len; i++) { + const GstH264SEIMessage *const sei = + &g_array_index (pi->data.sei, GstH264SEIMessage, i); + + switch (sei->payloadType) { + case GST_H264_SEI_PIC_TIMING:{ + const GstH264PicTiming *const pic_timing = &sei->payload.pic_timing; + if (pic_timing->pic_struct_present_flag) + priv->pic_structure = pic_timing->pic_struct; + break; + } + default: break; } - } - - /* Variables that don't have inferred values per the H.264 - standard but that should get a default value anyway */ - slice_hdr->cabac_init_idc = 0; - slice_hdr->direct_spatial_mv_pred_flag = 0; - - result = gst_h264_parser_parse_slice_hdr(priv->parser, &pi->nalu, - slice_hdr, TRUE, TRUE); - if (result != GST_H264_PARSER_OK) - return get_status(result); - - sps = slice_hdr->pps->sequence; - - /* Update MVC data */ - pi->view_id = get_view_id(&pi->nalu); - pi->voc = get_view_order_index(sps, pi->view_id); - - priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SLICE; - if (!GST_H264_IS_I_SLICE(slice_hdr)) - priv->parser_state |= GST_H264_VIDEO_STATE_GOT_P_SLICE; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +decode_sequence_end (GstVaapiDecoderH264 * decoder) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GstH264SPS * const sps = &pi->data.sps; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const sps_pi = decoder->priv.active_sps; - GST_DEBUG("decode SPS"); + GST_DEBUG ("decode sequence-end"); - gst_vaapi_parser_info_h264_replace(&priv->sps[sps->id], pi); - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} + /* Sequence ended, don't try to propagate "got I-frame" state + beyond this point */ + if (sps_pi) + sps_pi->state &= ~GST_H264_VIDEO_STATE_GOT_I_FRAME; -static GstVaapiDecoderStatus -decode_subset_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) -{ - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GstH264SPS * const sps = &pi->data.sps; + dpb_flush (decoder, NULL); - GST_DEBUG("decode subset SPS"); - - gst_vaapi_parser_info_h264_replace(&priv->sps[sps->id], pi); - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -decode_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) -{ - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GstH264PPS * const pps = &pi->data.pps; - - GST_DEBUG("decode PPS"); - - gst_vaapi_parser_info_h264_replace(&priv->pps[pps->id], pi); - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -decode_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) -{ - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - guint i; - - GST_DEBUG("decode SEI messages"); - - for (i = 0; i < pi->data.sei->len; i++) { - const GstH264SEIMessage * const sei = - &g_array_index(pi->data.sei, GstH264SEIMessage, i); - - switch (sei->payloadType) { - case GST_H264_SEI_PIC_TIMING: { - const GstH264PicTiming * const pic_timing = - &sei->payload.pic_timing; - if (pic_timing->pic_struct_present_flag) - priv->pic_structure = pic_timing->pic_struct; - break; - } - default: - break; - } - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -decode_sequence_end(GstVaapiDecoderH264 *decoder) -{ - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const sps_pi = decoder->priv.active_sps; - - GST_DEBUG("decode sequence-end"); - - /* Sequence ended, don't try to propagate "got I-frame" state - beyond this point */ - if (sps_pi) - sps_pi->state &= ~GST_H264_VIDEO_STATE_GOT_I_FRAME; - - dpb_flush(decoder, NULL); - - /* Reset defaults, should there be a new sequence available next */ - priv->max_views = 1; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + /* Reset defaults, should there be a new sequence available next */ + priv->max_views = 1; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } /* 8.2.1.1 - Decoding process for picture order count type 0 */ static void -init_picture_poc_0( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr -) +init_picture_poc_0 (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264SPS * const sps = get_sps(decoder); - const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); - gint32 temp_poc; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstH264SPS *const sps = get_sps (decoder); + const gint32 MaxPicOrderCntLsb = + 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); + gint32 temp_poc; - GST_DEBUG("decode picture order count type 0"); + GST_DEBUG ("decode picture order count type 0"); - if (GST_VAAPI_PICTURE_IS_IDR(picture)) { - priv->prev_poc_msb = 0; - priv->prev_poc_lsb = 0; - } - else if (priv->prev_pic_has_mmco5) { - priv->prev_poc_msb = 0; - priv->prev_poc_lsb = - (priv->prev_pic_structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD ? - 0 : priv->field_poc[TOP_FIELD]); - } - else { - priv->prev_poc_msb = priv->poc_msb; - priv->prev_poc_lsb = priv->poc_lsb; - } + if (GST_VAAPI_PICTURE_IS_IDR (picture)) { + priv->prev_poc_msb = 0; + priv->prev_poc_lsb = 0; + } else if (priv->prev_pic_has_mmco5) { + priv->prev_poc_msb = 0; + priv->prev_poc_lsb = + (priv->prev_pic_structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD ? + 0 : priv->field_poc[TOP_FIELD]); + } else { + priv->prev_poc_msb = priv->poc_msb; + priv->prev_poc_lsb = priv->poc_lsb; + } - // (8-3) - priv->poc_lsb = slice_hdr->pic_order_cnt_lsb; - if (priv->poc_lsb < priv->prev_poc_lsb && - (priv->prev_poc_lsb - priv->poc_lsb) >= (MaxPicOrderCntLsb / 2)) - priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb; - else if (priv->poc_lsb > priv->prev_poc_lsb && - (priv->poc_lsb - priv->prev_poc_lsb) > (MaxPicOrderCntLsb / 2)) - priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb; - else - priv->poc_msb = priv->prev_poc_msb; + // (8-3) + priv->poc_lsb = slice_hdr->pic_order_cnt_lsb; + if (priv->poc_lsb < priv->prev_poc_lsb && + (priv->prev_poc_lsb - priv->poc_lsb) >= (MaxPicOrderCntLsb / 2)) + priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb; + else if (priv->poc_lsb > priv->prev_poc_lsb && + (priv->poc_lsb - priv->prev_poc_lsb) > (MaxPicOrderCntLsb / 2)) + priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb; + else + priv->poc_msb = priv->prev_poc_msb; - temp_poc = priv->poc_msb + priv->poc_lsb; - switch (picture->structure) { + temp_poc = priv->poc_msb + priv->poc_lsb; + switch (picture->structure) { case GST_VAAPI_PICTURE_STRUCTURE_FRAME: - // (8-4, 8-5) - priv->field_poc[TOP_FIELD] = temp_poc; - priv->field_poc[BOTTOM_FIELD] = temp_poc + - slice_hdr->delta_pic_order_cnt_bottom; - break; + // (8-4, 8-5) + priv->field_poc[TOP_FIELD] = temp_poc; + priv->field_poc[BOTTOM_FIELD] = temp_poc + + slice_hdr->delta_pic_order_cnt_bottom; + break; case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: - // (8-4) - priv->field_poc[TOP_FIELD] = temp_poc; - break; + // (8-4) + priv->field_poc[TOP_FIELD] = temp_poc; + break; case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: - // (8-5) - priv->field_poc[BOTTOM_FIELD] = temp_poc; - break; - } + // (8-5) + priv->field_poc[BOTTOM_FIELD] = temp_poc; + break; + } } /* 8.2.1.2 - Decoding process for picture order count type 1 */ static void -init_picture_poc_1( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr -) +init_picture_poc_1 (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264SPS * const sps = get_sps(decoder); - const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); - gint32 prev_frame_num_offset, abs_frame_num, expected_poc; - guint i; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstH264SPS *const sps = get_sps (decoder); + const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); + gint32 prev_frame_num_offset, abs_frame_num, expected_poc; + guint i; - GST_DEBUG("decode picture order count type 1"); + GST_DEBUG ("decode picture order count type 1"); - if (priv->prev_pic_has_mmco5) - prev_frame_num_offset = 0; - else - prev_frame_num_offset = priv->frame_num_offset; + if (priv->prev_pic_has_mmco5) + prev_frame_num_offset = 0; + else + prev_frame_num_offset = priv->frame_num_offset; - // (8-6) - if (GST_VAAPI_PICTURE_IS_IDR(picture)) - priv->frame_num_offset = 0; - else if (priv->prev_frame_num > priv->frame_num) - priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum; - else - priv->frame_num_offset = prev_frame_num_offset; + // (8-6) + if (GST_VAAPI_PICTURE_IS_IDR (picture)) + priv->frame_num_offset = 0; + else if (priv->prev_frame_num > priv->frame_num) + priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum; + else + priv->frame_num_offset = prev_frame_num_offset; - // (8-7) - if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0) - abs_frame_num = priv->frame_num_offset + priv->frame_num; - else - abs_frame_num = 0; - if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture) && abs_frame_num > 0) - abs_frame_num = abs_frame_num - 1; + // (8-7) + if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0) + abs_frame_num = priv->frame_num_offset + priv->frame_num; + else + abs_frame_num = 0; + if (!GST_VAAPI_PICTURE_IS_REFERENCE (picture) && abs_frame_num > 0) + abs_frame_num = abs_frame_num - 1; - if (abs_frame_num > 0) { - gint32 expected_delta_per_poc_cycle; - gint32 poc_cycle_cnt, frame_num_in_poc_cycle; + if (abs_frame_num > 0) { + gint32 expected_delta_per_poc_cycle; + gint32 poc_cycle_cnt, frame_num_in_poc_cycle; - expected_delta_per_poc_cycle = 0; - for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++) - expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i]; + expected_delta_per_poc_cycle = 0; + for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++) + expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i]; - // (8-8) - poc_cycle_cnt = (abs_frame_num - 1) / - sps->num_ref_frames_in_pic_order_cnt_cycle; - frame_num_in_poc_cycle = (abs_frame_num - 1) % - sps->num_ref_frames_in_pic_order_cnt_cycle; + // (8-8) + poc_cycle_cnt = (abs_frame_num - 1) / + sps->num_ref_frames_in_pic_order_cnt_cycle; + frame_num_in_poc_cycle = (abs_frame_num - 1) % + sps->num_ref_frames_in_pic_order_cnt_cycle; - // (8-9) - expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle; - for (i = 0; i <= frame_num_in_poc_cycle; i++) - expected_poc += sps->offset_for_ref_frame[i]; - } - else - expected_poc = 0; - if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) - expected_poc += sps->offset_for_non_ref_pic; + // (8-9) + expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle; + for (i = 0; i <= frame_num_in_poc_cycle; i++) + expected_poc += sps->offset_for_ref_frame[i]; + } else + expected_poc = 0; + if (!GST_VAAPI_PICTURE_IS_REFERENCE (picture)) + expected_poc += sps->offset_for_non_ref_pic; - // (8-10) - switch (picture->structure) { + // (8-10) + switch (picture->structure) { case GST_VAAPI_PICTURE_STRUCTURE_FRAME: - priv->field_poc[TOP_FIELD] = expected_poc + - slice_hdr->delta_pic_order_cnt[0]; - priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] + - sps->offset_for_top_to_bottom_field + - slice_hdr->delta_pic_order_cnt[1]; - break; + priv->field_poc[TOP_FIELD] = expected_poc + + slice_hdr->delta_pic_order_cnt[0]; + priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] + + sps->offset_for_top_to_bottom_field + + slice_hdr->delta_pic_order_cnt[1]; + break; case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: - priv->field_poc[TOP_FIELD] = expected_poc + - slice_hdr->delta_pic_order_cnt[0]; - break; + priv->field_poc[TOP_FIELD] = expected_poc + + slice_hdr->delta_pic_order_cnt[0]; + break; case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: - priv->field_poc[BOTTOM_FIELD] = expected_poc + - sps->offset_for_top_to_bottom_field + - slice_hdr->delta_pic_order_cnt[0]; - break; - } + priv->field_poc[BOTTOM_FIELD] = expected_poc + + sps->offset_for_top_to_bottom_field + + slice_hdr->delta_pic_order_cnt[0]; + break; + } } /* 8.2.1.3 - Decoding process for picture order count type 2 */ static void -init_picture_poc_2( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr -) +init_picture_poc_2 (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264SPS * const sps = get_sps(decoder); - const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); - gint32 prev_frame_num_offset, temp_poc; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstH264SPS *const sps = get_sps (decoder); + const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); + gint32 prev_frame_num_offset, temp_poc; - GST_DEBUG("decode picture order count type 2"); + GST_DEBUG ("decode picture order count type 2"); - if (priv->prev_pic_has_mmco5) - prev_frame_num_offset = 0; - else - prev_frame_num_offset = priv->frame_num_offset; + if (priv->prev_pic_has_mmco5) + prev_frame_num_offset = 0; + else + prev_frame_num_offset = priv->frame_num_offset; - // (8-11) - if (GST_VAAPI_PICTURE_IS_IDR(picture)) - priv->frame_num_offset = 0; - else if (priv->prev_frame_num > priv->frame_num) - priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum; - else - priv->frame_num_offset = prev_frame_num_offset; + // (8-11) + if (GST_VAAPI_PICTURE_IS_IDR (picture)) + priv->frame_num_offset = 0; + else if (priv->prev_frame_num > priv->frame_num) + priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum; + else + priv->frame_num_offset = prev_frame_num_offset; - // (8-12) - if (GST_VAAPI_PICTURE_IS_IDR(picture)) - temp_poc = 0; - else if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) - temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1; - else - temp_poc = 2 * (priv->frame_num_offset + priv->frame_num); + // (8-12) + if (GST_VAAPI_PICTURE_IS_IDR (picture)) + temp_poc = 0; + else if (!GST_VAAPI_PICTURE_IS_REFERENCE (picture)) + temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1; + else + temp_poc = 2 * (priv->frame_num_offset + priv->frame_num); - // (8-13) - if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) - priv->field_poc[TOP_FIELD] = temp_poc; - if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) - priv->field_poc[BOTTOM_FIELD] = temp_poc; + // (8-13) + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) + priv->field_poc[TOP_FIELD] = temp_poc; + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) + priv->field_poc[BOTTOM_FIELD] = temp_poc; } /* 8.2.1 - Decoding process for picture order count */ static void -init_picture_poc( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr -) +init_picture_poc (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264SPS * const sps = get_sps(decoder); + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstH264SPS *const sps = get_sps (decoder); - switch (sps->pic_order_cnt_type) { + switch (sps->pic_order_cnt_type) { case 0: - init_picture_poc_0(decoder, picture, slice_hdr); - break; + init_picture_poc_0 (decoder, picture, slice_hdr); + break; case 1: - init_picture_poc_1(decoder, picture, slice_hdr); - break; + init_picture_poc_1 (decoder, picture, slice_hdr); + break; case 2: - init_picture_poc_2(decoder, picture, slice_hdr); - break; - } + init_picture_poc_2 (decoder, picture, slice_hdr); + break; + } - if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) - picture->field_poc[TOP_FIELD] = priv->field_poc[TOP_FIELD]; - if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) - picture->field_poc[BOTTOM_FIELD] = priv->field_poc[BOTTOM_FIELD]; - picture->base.poc = MIN(picture->field_poc[0], picture->field_poc[1]); + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) + picture->field_poc[TOP_FIELD] = priv->field_poc[TOP_FIELD]; + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) + picture->field_poc[BOTTOM_FIELD] = priv->field_poc[BOTTOM_FIELD]; + picture->base.poc = MIN (picture->field_poc[0], picture->field_poc[1]); } static int -compare_picture_pic_num_dec(const void *a, const void *b) +compare_picture_pic_num_dec (const void *a, const void *b) { - const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; - const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + const GstVaapiPictureH264 *const picA = *(GstVaapiPictureH264 **) a; + const GstVaapiPictureH264 *const picB = *(GstVaapiPictureH264 **) b; - return picB->pic_num - picA->pic_num; + return picB->pic_num - picA->pic_num; } static int -compare_picture_long_term_pic_num_inc(const void *a, const void *b) +compare_picture_long_term_pic_num_inc (const void *a, const void *b) { - const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; - const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + const GstVaapiPictureH264 *const picA = *(GstVaapiPictureH264 **) a; + const GstVaapiPictureH264 *const picB = *(GstVaapiPictureH264 **) b; - return picA->long_term_pic_num - picB->long_term_pic_num; + return picA->long_term_pic_num - picB->long_term_pic_num; } static int -compare_picture_poc_dec(const void *a, const void *b) +compare_picture_poc_dec (const void *a, const void *b) { - const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; - const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + const GstVaapiPictureH264 *const picA = *(GstVaapiPictureH264 **) a; + const GstVaapiPictureH264 *const picB = *(GstVaapiPictureH264 **) b; - return picB->base.poc - picA->base.poc; + return picB->base.poc - picA->base.poc; } static int -compare_picture_poc_inc(const void *a, const void *b) +compare_picture_poc_inc (const void *a, const void *b) { - const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; - const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + const GstVaapiPictureH264 *const picA = *(GstVaapiPictureH264 **) a; + const GstVaapiPictureH264 *const picB = *(GstVaapiPictureH264 **) b; - return picA->base.poc - picB->base.poc; + return picA->base.poc - picB->base.poc; } static int -compare_picture_frame_num_wrap_dec(const void *a, const void *b) +compare_picture_frame_num_wrap_dec (const void *a, const void *b) { - const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; - const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + const GstVaapiPictureH264 *const picA = *(GstVaapiPictureH264 **) a; + const GstVaapiPictureH264 *const picB = *(GstVaapiPictureH264 **) b; - return picB->frame_num_wrap - picA->frame_num_wrap; + return picB->frame_num_wrap - picA->frame_num_wrap; } static int -compare_picture_long_term_frame_idx_inc(const void *a, const void *b) +compare_picture_long_term_frame_idx_inc (const void *a, const void *b) { - const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a; - const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b; + const GstVaapiPictureH264 *const picA = *(GstVaapiPictureH264 **) a; + const GstVaapiPictureH264 *const picB = *(GstVaapiPictureH264 **) b; - return picA->long_term_frame_idx - picB->long_term_frame_idx; + return picA->long_term_frame_idx - picB->long_term_frame_idx; } /* 8.2.4.1 - Decoding process for picture numbers */ static void -init_picture_refs_pic_num( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr -) +init_picture_refs_pic_num (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264SPS * const sps = get_sps(decoder); - const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); - guint i; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstH264SPS *const sps = get_sps (decoder); + const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); + guint i; - GST_DEBUG("decode picture numbers"); + GST_DEBUG ("decode picture numbers"); - for (i = 0; i < priv->short_ref_count; i++) { - GstVaapiPictureH264 * const pic = priv->short_ref[i]; + for (i = 0; i < priv->short_ref_count; i++) { + GstVaapiPictureH264 *const pic = priv->short_ref[i]; - // (H.8.2) - if (pic->base.view_id != picture->base.view_id) - continue; + // (H.8.2) + if (pic->base.view_id != picture->base.view_id) + continue; - // (8-27) - if (pic->frame_num > priv->frame_num) - pic->frame_num_wrap = pic->frame_num - MaxFrameNum; - else - pic->frame_num_wrap = pic->frame_num; + // (8-27) + if (pic->frame_num > priv->frame_num) + pic->frame_num_wrap = pic->frame_num - MaxFrameNum; + else + pic->frame_num_wrap = pic->frame_num; - // (8-28, 8-30, 8-31) - if (GST_VAAPI_PICTURE_IS_FRAME(picture)) - pic->pic_num = pic->frame_num_wrap; - else { - if (pic->structure == picture->structure) - pic->pic_num = 2 * pic->frame_num_wrap + 1; - else - pic->pic_num = 2 * pic->frame_num_wrap; - } + // (8-28, 8-30, 8-31) + if (GST_VAAPI_PICTURE_IS_FRAME (picture)) + pic->pic_num = pic->frame_num_wrap; + else { + if (pic->structure == picture->structure) + pic->pic_num = 2 * pic->frame_num_wrap + 1; + else + pic->pic_num = 2 * pic->frame_num_wrap; } + } - for (i = 0; i < priv->long_ref_count; i++) { - GstVaapiPictureH264 * const pic = priv->long_ref[i]; + for (i = 0; i < priv->long_ref_count; i++) { + GstVaapiPictureH264 *const pic = priv->long_ref[i]; - // (H.8.2) - if (pic->base.view_id != picture->base.view_id) - continue; + // (H.8.2) + if (pic->base.view_id != picture->base.view_id) + continue; - // (8-29, 8-32, 8-33) - if (GST_VAAPI_PICTURE_IS_FRAME(picture)) - pic->long_term_pic_num = pic->long_term_frame_idx; - else { - if (pic->structure == picture->structure) - pic->long_term_pic_num = 2 * pic->long_term_frame_idx + 1; - else - pic->long_term_pic_num = 2 * pic->long_term_frame_idx; - } + // (8-29, 8-32, 8-33) + if (GST_VAAPI_PICTURE_IS_FRAME (picture)) + pic->long_term_pic_num = pic->long_term_frame_idx; + else { + if (pic->structure == picture->structure) + pic->long_term_pic_num = 2 * pic->long_term_frame_idx + 1; + else + pic->long_term_pic_num = 2 * pic->long_term_frame_idx; } + } } #define SORT_REF_LIST(list, n, compare_func) \ qsort(list, n, sizeof(*(list)), compare_picture_##compare_func) static void -init_picture_refs_fields_1( - guint picture_structure, - GstVaapiPictureH264 *RefPicList[32], - guint *RefPicList_count, - GstVaapiPictureH264 *ref_list[32], - guint ref_list_count -) +init_picture_refs_fields_1 (guint picture_structure, + GstVaapiPictureH264 * RefPicList[32], + guint * RefPicList_count, + GstVaapiPictureH264 * ref_list[32], guint ref_list_count) { - guint i, j, n; + guint i, j, n; - i = 0; - j = 0; - n = *RefPicList_count; - do { - g_assert(n < 32); - for (; i < ref_list_count; i++) { - if (ref_list[i]->structure == picture_structure) { - RefPicList[n++] = ref_list[i++]; - break; - } - } - for (; j < ref_list_count; j++) { - if (ref_list[j]->structure != picture_structure) { - RefPicList[n++] = ref_list[j++]; - break; - } - } - } while (i < ref_list_count || j < ref_list_count); - *RefPicList_count = n; + i = 0; + j = 0; + n = *RefPicList_count; + do { + g_assert (n < 32); + for (; i < ref_list_count; i++) { + if (ref_list[i]->structure == picture_structure) { + RefPicList[n++] = ref_list[i++]; + break; + } + } + for (; j < ref_list_count; j++) { + if (ref_list[j]->structure != picture_structure) { + RefPicList[n++] = ref_list[j++]; + break; + } + } + } while (i < ref_list_count || j < ref_list_count); + *RefPicList_count = n; } static inline void -init_picture_refs_fields( - GstVaapiPictureH264 *picture, - GstVaapiPictureH264 *RefPicList[32], - guint *RefPicList_count, - GstVaapiPictureH264 *short_ref[32], - guint short_ref_count, - GstVaapiPictureH264 *long_ref[32], - guint long_ref_count -) +init_picture_refs_fields (GstVaapiPictureH264 * picture, + GstVaapiPictureH264 * RefPicList[32], + guint * RefPicList_count, + GstVaapiPictureH264 * short_ref[32], + guint short_ref_count, + GstVaapiPictureH264 * long_ref[32], guint long_ref_count) { - guint n = 0; + guint n = 0; - /* 8.2.4.2.5 - reference picture lists in fields */ - init_picture_refs_fields_1(picture->structure, RefPicList, &n, - short_ref, short_ref_count); - init_picture_refs_fields_1(picture->structure, RefPicList, &n, - long_ref, long_ref_count); - *RefPicList_count = n; + /* 8.2.4.2.5 - reference picture lists in fields */ + init_picture_refs_fields_1 (picture->structure, RefPicList, &n, + short_ref, short_ref_count); + init_picture_refs_fields_1 (picture->structure, RefPicList, &n, + long_ref, long_ref_count); + *RefPicList_count = n; } /* Finds the inter-view reference picture with the supplied view id */ static GstVaapiPictureH264 * -find_inter_view_reference(GstVaapiDecoderH264 *decoder, guint16 view_id) +find_inter_view_reference (GstVaapiDecoderH264 * decoder, guint16 view_id) { - GPtrArray * const inter_views = decoder->priv.inter_views; - guint i; + GPtrArray *const inter_views = decoder->priv.inter_views; + guint i; - for (i = 0; i < inter_views->len; i++) { - GstVaapiPictureH264 * const picture = g_ptr_array_index(inter_views, i); - if (picture->base.view_id == view_id) - return picture; - } + for (i = 0; i < inter_views->len; i++) { + GstVaapiPictureH264 *const picture = g_ptr_array_index (inter_views, i); + if (picture->base.view_id == view_id) + return picture; + } - GST_WARNING("failed to find inter-view reference picture for view_id: %d", - view_id); - return NULL; + GST_WARNING ("failed to find inter-view reference picture for view_id: %d", + view_id); + return NULL; } /* Checks whether the view id exists in the supplied list of view ids */ static gboolean -find_view_id(guint16 view_id, const guint16 *view_ids, guint num_view_ids) +find_view_id (guint16 view_id, const guint16 * view_ids, guint num_view_ids) { - guint i; + guint i; - for (i = 0; i < num_view_ids; i++) { - if (view_ids[i] == view_id) - return TRUE; - } - return FALSE; + for (i = 0; i < num_view_ids; i++) { + if (view_ids[i] == view_id) + return TRUE; + } + return FALSE; } static gboolean -find_view_id_in_view(guint16 view_id, const GstH264SPSExtMVCView *view, +find_view_id_in_view (guint16 view_id, const GstH264SPSExtMVCView * view, gboolean is_anchor) { - if (is_anchor) - return (find_view_id(view_id, view->anchor_ref_l0, - view->num_anchor_refs_l0) || - find_view_id(view_id, view->anchor_ref_l1, - view->num_anchor_refs_l1)); + if (is_anchor) + return (find_view_id (view_id, view->anchor_ref_l0, + view->num_anchor_refs_l0) || + find_view_id (view_id, view->anchor_ref_l1, view->num_anchor_refs_l1)); - return (find_view_id(view_id, view->non_anchor_ref_l0, - view->num_non_anchor_refs_l0) || - find_view_id(view_id, view->non_anchor_ref_l1, - view->num_non_anchor_refs_l1)); + return (find_view_id (view_id, view->non_anchor_ref_l0, + view->num_non_anchor_refs_l0) || + find_view_id (view_id, view->non_anchor_ref_l1, + view->num_non_anchor_refs_l1)); } /* Checks whether the inter-view reference picture with the supplied view id is used for decoding the current view component picture */ static gboolean -is_inter_view_reference_for_picture(GstVaapiDecoderH264 *decoder, - guint16 view_id, GstVaapiPictureH264 *picture) +is_inter_view_reference_for_picture (GstVaapiDecoderH264 * decoder, + guint16 view_id, GstVaapiPictureH264 * picture) { - const GstH264SPS * const sps = get_sps(decoder); - gboolean is_anchor; + const GstH264SPS *const sps = get_sps (decoder); + gboolean is_anchor; - if (!GST_VAAPI_PICTURE_IS_MVC(picture) || - sps->extension_type != GST_H264_NAL_EXTENSION_MVC) - return FALSE; + if (!GST_VAAPI_PICTURE_IS_MVC (picture) || + sps->extension_type != GST_H264_NAL_EXTENSION_MVC) + return FALSE; - is_anchor = GST_VAAPI_PICTURE_IS_ANCHOR(picture); - return find_view_id_in_view(view_id, - &sps->extension.mvc.view[picture->base.voc], is_anchor); + is_anchor = GST_VAAPI_PICTURE_IS_ANCHOR (picture); + return find_view_id_in_view (view_id, + &sps->extension.mvc.view[picture->base.voc], is_anchor); } /* Checks whether the supplied inter-view reference picture is used for decoding the next view component pictures */ static gboolean -is_inter_view_reference_for_next_pictures(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture) +is_inter_view_reference_for_next_pictures (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture) { - const GstH264SPS * const sps = get_sps(decoder); - gboolean is_anchor; - guint i, num_views; + const GstH264SPS *const sps = get_sps (decoder); + gboolean is_anchor; + guint i, num_views; - if (!GST_VAAPI_PICTURE_IS_MVC(picture) || - sps->extension_type != GST_H264_NAL_EXTENSION_MVC) - return FALSE; - - is_anchor = GST_VAAPI_PICTURE_IS_ANCHOR(picture); - num_views = sps->extension.mvc.num_views_minus1 + 1; - for (i = picture->base.voc + 1; i < num_views; i++) { - const GstH264SPSExtMVCView * const view = &sps->extension.mvc.view[i]; - if (find_view_id_in_view(picture->base.view_id, view, is_anchor)) - return TRUE; - } + if (!GST_VAAPI_PICTURE_IS_MVC (picture) || + sps->extension_type != GST_H264_NAL_EXTENSION_MVC) return FALSE; + + is_anchor = GST_VAAPI_PICTURE_IS_ANCHOR (picture); + num_views = sps->extension.mvc.num_views_minus1 + 1; + for (i = picture->base.voc + 1; i < num_views; i++) { + const GstH264SPSExtMVCView *const view = &sps->extension.mvc.view[i]; + if (find_view_id_in_view (picture->base.view_id, view, is_anchor)) + return TRUE; + } + return FALSE; } /* H.8.2.1 - Initialization process for inter-view prediction references */ static void -init_picture_refs_mvc_1(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 **ref_list, guint *ref_list_count_ptr, guint num_refs, - const guint16 *view_ids, guint num_view_ids) +init_picture_refs_mvc_1 (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 ** ref_list, guint * ref_list_count_ptr, guint num_refs, + const guint16 * view_ids, guint num_view_ids) { - guint j, n; + guint j, n; - n = *ref_list_count_ptr; - for (j = 0; j < num_view_ids && n < num_refs; j++) { - GstVaapiPictureH264 * const pic = - find_inter_view_reference(decoder, view_ids[j]); - if (pic) - ref_list[n++] = pic; - } - *ref_list_count_ptr = n; + n = *ref_list_count_ptr; + for (j = 0; j < num_view_ids && n < num_refs; j++) { + GstVaapiPictureH264 *const pic = + find_inter_view_reference (decoder, view_ids[j]); + if (pic) + ref_list[n++] = pic; + } + *ref_list_count_ptr = n; } static inline void -init_picture_refs_mvc(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, GstH264SliceHdr *slice_hdr, guint list) +init_picture_refs_mvc (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr, guint list) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - const GstH264SPS * const sps = get_sps(decoder); - const GstH264SPSExtMVCView *view; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + const GstH264SPS *const sps = get_sps (decoder); + const GstH264SPSExtMVCView *view; - GST_DEBUG("initialize reference picture list for inter-view prediction"); + GST_DEBUG ("initialize reference picture list for inter-view prediction"); - if (sps->extension_type != GST_H264_NAL_EXTENSION_MVC) - return; - view = &sps->extension.mvc.view[picture->base.voc]; + if (sps->extension_type != GST_H264_NAL_EXTENSION_MVC) + return; + view = &sps->extension.mvc.view[picture->base.voc]; #define INVOKE_INIT_PICTURE_REFS_MVC(ref_list, view_list) do { \ init_picture_refs_mvc_1(decoder, \ @@ -2403,1384 +2368,1327 @@ init_picture_refs_mvc(GstVaapiDecoderH264 *decoder, view->num_##view_list##s_l##ref_list); \ } while (0) - if (list == 0) { - if (GST_VAAPI_PICTURE_IS_ANCHOR(picture)) - INVOKE_INIT_PICTURE_REFS_MVC(0, anchor_ref); - else - INVOKE_INIT_PICTURE_REFS_MVC(0, non_anchor_ref); - } - else { - if (GST_VAAPI_PICTURE_IS_ANCHOR(picture)) - INVOKE_INIT_PICTURE_REFS_MVC(1, anchor_ref); - else - INVOKE_INIT_PICTURE_REFS_MVC(1, non_anchor_ref); - } + if (list == 0) { + if (GST_VAAPI_PICTURE_IS_ANCHOR (picture)) + INVOKE_INIT_PICTURE_REFS_MVC (0, anchor_ref); + else + INVOKE_INIT_PICTURE_REFS_MVC (0, non_anchor_ref); + } else { + if (GST_VAAPI_PICTURE_IS_ANCHOR (picture)) + INVOKE_INIT_PICTURE_REFS_MVC (1, anchor_ref); + else + INVOKE_INIT_PICTURE_REFS_MVC (1, non_anchor_ref); + } #undef INVOKE_INIT_PICTURE_REFS_MVC } static void -init_picture_refs_p_slice( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr -) +init_picture_refs_p_slice (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 **ref_list; - guint i; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 **ref_list; + guint i; - GST_DEBUG("decode reference picture list for P and SP slices"); + GST_DEBUG ("decode reference picture list for P and SP slices"); - if (GST_VAAPI_PICTURE_IS_FRAME(picture)) { - /* 8.2.4.2.1 - P and SP slices in frames */ - if (priv->short_ref_count > 0) { - ref_list = priv->RefPicList0; - for (i = 0; i < priv->short_ref_count; i++) - ref_list[i] = priv->short_ref[i]; - SORT_REF_LIST(ref_list, i, pic_num_dec); - priv->RefPicList0_count += i; - } - - if (priv->long_ref_count > 0) { - ref_list = &priv->RefPicList0[priv->RefPicList0_count]; - for (i = 0; i < priv->long_ref_count; i++) - ref_list[i] = priv->long_ref[i]; - SORT_REF_LIST(ref_list, i, long_term_pic_num_inc); - priv->RefPicList0_count += i; - } - } - else { - /* 8.2.4.2.2 - P and SP slices in fields */ - GstVaapiPictureH264 *short_ref[32]; - guint short_ref_count = 0; - GstVaapiPictureH264 *long_ref[32]; - guint long_ref_count = 0; - - if (priv->short_ref_count > 0) { - for (i = 0; i < priv->short_ref_count; i++) - short_ref[i] = priv->short_ref[i]; - SORT_REF_LIST(short_ref, i, frame_num_wrap_dec); - short_ref_count = i; - } - - if (priv->long_ref_count > 0) { - for (i = 0; i < priv->long_ref_count; i++) - long_ref[i] = priv->long_ref[i]; - SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc); - long_ref_count = i; - } - - init_picture_refs_fields( - picture, - priv->RefPicList0, &priv->RefPicList0_count, - short_ref, short_ref_count, - long_ref, long_ref_count - ); + if (GST_VAAPI_PICTURE_IS_FRAME (picture)) { + /* 8.2.4.2.1 - P and SP slices in frames */ + if (priv->short_ref_count > 0) { + ref_list = priv->RefPicList0; + for (i = 0; i < priv->short_ref_count; i++) + ref_list[i] = priv->short_ref[i]; + SORT_REF_LIST (ref_list, i, pic_num_dec); + priv->RefPicList0_count += i; } - if (GST_VAAPI_PICTURE_IS_MVC(picture)) { - /* RefPicList0 */ - init_picture_refs_mvc(decoder, picture, slice_hdr, 0); + if (priv->long_ref_count > 0) { + ref_list = &priv->RefPicList0[priv->RefPicList0_count]; + for (i = 0; i < priv->long_ref_count; i++) + ref_list[i] = priv->long_ref[i]; + SORT_REF_LIST (ref_list, i, long_term_pic_num_inc); + priv->RefPicList0_count += i; } + } else { + /* 8.2.4.2.2 - P and SP slices in fields */ + GstVaapiPictureH264 *short_ref[32]; + guint short_ref_count = 0; + GstVaapiPictureH264 *long_ref[32]; + guint long_ref_count = 0; + + if (priv->short_ref_count > 0) { + for (i = 0; i < priv->short_ref_count; i++) + short_ref[i] = priv->short_ref[i]; + SORT_REF_LIST (short_ref, i, frame_num_wrap_dec); + short_ref_count = i; + } + + if (priv->long_ref_count > 0) { + for (i = 0; i < priv->long_ref_count; i++) + long_ref[i] = priv->long_ref[i]; + SORT_REF_LIST (long_ref, i, long_term_frame_idx_inc); + long_ref_count = i; + } + + init_picture_refs_fields (picture, + priv->RefPicList0, &priv->RefPicList0_count, + short_ref, short_ref_count, long_ref, long_ref_count); + } + + if (GST_VAAPI_PICTURE_IS_MVC (picture)) { + /* RefPicList0 */ + init_picture_refs_mvc (decoder, picture, slice_hdr, 0); + } } static void -init_picture_refs_b_slice( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr -) +init_picture_refs_b_slice (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 **ref_list; - guint i, n; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 **ref_list; + guint i, n; - GST_DEBUG("decode reference picture list for B slices"); + GST_DEBUG ("decode reference picture list for B slices"); - if (GST_VAAPI_PICTURE_IS_FRAME(picture)) { - /* 8.2.4.2.3 - B slices in frames */ + if (GST_VAAPI_PICTURE_IS_FRAME (picture)) { + /* 8.2.4.2.3 - B slices in frames */ - /* RefPicList0 */ - if (priv->short_ref_count > 0) { - // 1. Short-term references - ref_list = priv->RefPicList0; - for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->base.poc < picture->base.poc) - ref_list[n++] = priv->short_ref[i]; - } - SORT_REF_LIST(ref_list, n, poc_dec); - priv->RefPicList0_count += n; + /* RefPicList0 */ + if (priv->short_ref_count > 0) { + // 1. Short-term references + ref_list = priv->RefPicList0; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->base.poc < picture->base.poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST (ref_list, n, poc_dec); + priv->RefPicList0_count += n; - ref_list = &priv->RefPicList0[priv->RefPicList0_count]; - for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->base.poc >= picture->base.poc) - ref_list[n++] = priv->short_ref[i]; - } - SORT_REF_LIST(ref_list, n, poc_inc); - priv->RefPicList0_count += n; - } - - if (priv->long_ref_count > 0) { - // 2. Long-term references - ref_list = &priv->RefPicList0[priv->RefPicList0_count]; - for (n = 0, i = 0; i < priv->long_ref_count; i++) - ref_list[n++] = priv->long_ref[i]; - SORT_REF_LIST(ref_list, n, long_term_pic_num_inc); - priv->RefPicList0_count += n; - } - - /* RefPicList1 */ - if (priv->short_ref_count > 0) { - // 1. Short-term references - ref_list = priv->RefPicList1; - for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->base.poc > picture->base.poc) - ref_list[n++] = priv->short_ref[i]; - } - SORT_REF_LIST(ref_list, n, poc_inc); - priv->RefPicList1_count += n; - - ref_list = &priv->RefPicList1[priv->RefPicList1_count]; - for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->base.poc <= picture->base.poc) - ref_list[n++] = priv->short_ref[i]; - } - SORT_REF_LIST(ref_list, n, poc_dec); - priv->RefPicList1_count += n; - } - - if (priv->long_ref_count > 0) { - // 2. Long-term references - ref_list = &priv->RefPicList1[priv->RefPicList1_count]; - for (n = 0, i = 0; i < priv->long_ref_count; i++) - ref_list[n++] = priv->long_ref[i]; - SORT_REF_LIST(ref_list, n, long_term_pic_num_inc); - priv->RefPicList1_count += n; - } - } - else { - /* 8.2.4.2.4 - B slices in fields */ - GstVaapiPictureH264 *short_ref0[32]; - guint short_ref0_count = 0; - GstVaapiPictureH264 *short_ref1[32]; - guint short_ref1_count = 0; - GstVaapiPictureH264 *long_ref[32]; - guint long_ref_count = 0; - - /* refFrameList0ShortTerm */ - if (priv->short_ref_count > 0) { - ref_list = short_ref0; - for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->base.poc <= picture->base.poc) - ref_list[n++] = priv->short_ref[i]; - } - SORT_REF_LIST(ref_list, n, poc_dec); - short_ref0_count += n; - - ref_list = &short_ref0[short_ref0_count]; - for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->base.poc > picture->base.poc) - ref_list[n++] = priv->short_ref[i]; - } - SORT_REF_LIST(ref_list, n, poc_inc); - short_ref0_count += n; - } - - /* refFrameList1ShortTerm */ - if (priv->short_ref_count > 0) { - ref_list = short_ref1; - for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->base.poc > picture->base.poc) - ref_list[n++] = priv->short_ref[i]; - } - SORT_REF_LIST(ref_list, n, poc_inc); - short_ref1_count += n; - - ref_list = &short_ref1[short_ref1_count]; - for (n = 0, i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->base.poc <= picture->base.poc) - ref_list[n++] = priv->short_ref[i]; - } - SORT_REF_LIST(ref_list, n, poc_dec); - short_ref1_count += n; - } - - /* refFrameListLongTerm */ - if (priv->long_ref_count > 0) { - for (i = 0; i < priv->long_ref_count; i++) - long_ref[i] = priv->long_ref[i]; - SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc); - long_ref_count = i; - } - - init_picture_refs_fields( - picture, - priv->RefPicList0, &priv->RefPicList0_count, - short_ref0, short_ref0_count, - long_ref, long_ref_count - ); - - init_picture_refs_fields( - picture, - priv->RefPicList1, &priv->RefPicList1_count, - short_ref1, short_ref1_count, - long_ref, long_ref_count - ); - } - - /* Check whether RefPicList1 is identical to RefPicList0, then - swap if necessary */ - if (priv->RefPicList1_count > 1 && - priv->RefPicList1_count == priv->RefPicList0_count && - memcmp(priv->RefPicList0, priv->RefPicList1, - priv->RefPicList0_count * sizeof(priv->RefPicList0[0])) == 0) { - GstVaapiPictureH264 * const tmp = priv->RefPicList1[0]; - priv->RefPicList1[0] = priv->RefPicList1[1]; - priv->RefPicList1[1] = tmp; + ref_list = &priv->RefPicList0[priv->RefPicList0_count]; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->base.poc >= picture->base.poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST (ref_list, n, poc_inc); + priv->RefPicList0_count += n; } - if (GST_VAAPI_PICTURE_IS_MVC(picture)) { - /* RefPicList0 */ - init_picture_refs_mvc(decoder, picture, slice_hdr, 0); - - /* RefPicList1 */ - init_picture_refs_mvc(decoder, picture, slice_hdr, 1); + if (priv->long_ref_count > 0) { + // 2. Long-term references + ref_list = &priv->RefPicList0[priv->RefPicList0_count]; + for (n = 0, i = 0; i < priv->long_ref_count; i++) + ref_list[n++] = priv->long_ref[i]; + SORT_REF_LIST (ref_list, n, long_term_pic_num_inc); + priv->RefPicList0_count += n; } + + /* RefPicList1 */ + if (priv->short_ref_count > 0) { + // 1. Short-term references + ref_list = priv->RefPicList1; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->base.poc > picture->base.poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST (ref_list, n, poc_inc); + priv->RefPicList1_count += n; + + ref_list = &priv->RefPicList1[priv->RefPicList1_count]; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->base.poc <= picture->base.poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST (ref_list, n, poc_dec); + priv->RefPicList1_count += n; + } + + if (priv->long_ref_count > 0) { + // 2. Long-term references + ref_list = &priv->RefPicList1[priv->RefPicList1_count]; + for (n = 0, i = 0; i < priv->long_ref_count; i++) + ref_list[n++] = priv->long_ref[i]; + SORT_REF_LIST (ref_list, n, long_term_pic_num_inc); + priv->RefPicList1_count += n; + } + } else { + /* 8.2.4.2.4 - B slices in fields */ + GstVaapiPictureH264 *short_ref0[32]; + guint short_ref0_count = 0; + GstVaapiPictureH264 *short_ref1[32]; + guint short_ref1_count = 0; + GstVaapiPictureH264 *long_ref[32]; + guint long_ref_count = 0; + + /* refFrameList0ShortTerm */ + if (priv->short_ref_count > 0) { + ref_list = short_ref0; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->base.poc <= picture->base.poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST (ref_list, n, poc_dec); + short_ref0_count += n; + + ref_list = &short_ref0[short_ref0_count]; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->base.poc > picture->base.poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST (ref_list, n, poc_inc); + short_ref0_count += n; + } + + /* refFrameList1ShortTerm */ + if (priv->short_ref_count > 0) { + ref_list = short_ref1; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->base.poc > picture->base.poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST (ref_list, n, poc_inc); + short_ref1_count += n; + + ref_list = &short_ref1[short_ref1_count]; + for (n = 0, i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->base.poc <= picture->base.poc) + ref_list[n++] = priv->short_ref[i]; + } + SORT_REF_LIST (ref_list, n, poc_dec); + short_ref1_count += n; + } + + /* refFrameListLongTerm */ + if (priv->long_ref_count > 0) { + for (i = 0; i < priv->long_ref_count; i++) + long_ref[i] = priv->long_ref[i]; + SORT_REF_LIST (long_ref, i, long_term_frame_idx_inc); + long_ref_count = i; + } + + init_picture_refs_fields (picture, + priv->RefPicList0, &priv->RefPicList0_count, + short_ref0, short_ref0_count, long_ref, long_ref_count); + + init_picture_refs_fields (picture, + priv->RefPicList1, &priv->RefPicList1_count, + short_ref1, short_ref1_count, long_ref, long_ref_count); + } + + /* Check whether RefPicList1 is identical to RefPicList0, then + swap if necessary */ + if (priv->RefPicList1_count > 1 && + priv->RefPicList1_count == priv->RefPicList0_count && + memcmp (priv->RefPicList0, priv->RefPicList1, + priv->RefPicList0_count * sizeof (priv->RefPicList0[0])) == 0) { + GstVaapiPictureH264 *const tmp = priv->RefPicList1[0]; + priv->RefPicList1[0] = priv->RefPicList1[1]; + priv->RefPicList1[1] = tmp; + } + + if (GST_VAAPI_PICTURE_IS_MVC (picture)) { + /* RefPicList0 */ + init_picture_refs_mvc (decoder, picture, slice_hdr, 0); + + /* RefPicList1 */ + init_picture_refs_mvc (decoder, picture, slice_hdr, 1); + } } #undef SORT_REF_LIST static gint -find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num) +find_short_term_reference (GstVaapiDecoderH264 * decoder, gint32 pic_num) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - guint i; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + guint i; - for (i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i]->pic_num == pic_num) - return i; - } - GST_ERROR("found no short-term reference picture with PicNum = %d", - pic_num); - return -1; + for (i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i]->pic_num == pic_num) + return i; + } + GST_ERROR ("found no short-term reference picture with PicNum = %d", pic_num); + return -1; } static gint -find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num) +find_long_term_reference (GstVaapiDecoderH264 * decoder, + gint32 long_term_pic_num) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - guint i; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + guint i; - for (i = 0; i < priv->long_ref_count; i++) { - if (priv->long_ref[i]->long_term_pic_num == long_term_pic_num) - return i; - } - GST_ERROR("found no long-term reference picture with LongTermPicNum = %d", - long_term_pic_num); - return -1; + for (i = 0; i < priv->long_ref_count; i++) { + if (priv->long_ref[i]->long_term_pic_num == long_term_pic_num) + return i; + } + GST_ERROR ("found no long-term reference picture with LongTermPicNum = %d", + long_term_pic_num); + return -1; } static void -exec_picture_refs_modification_1( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr, - guint list -) +exec_picture_refs_modification_1 (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr, guint list) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264SPS * const sps = get_sps(decoder); - GstH264RefPicListModification *ref_pic_list_modification; - guint num_ref_pic_list_modifications; - GstVaapiPictureH264 **ref_list; - guint *ref_list_count_ptr, ref_list_idx = 0; - const guint16 *view_ids = NULL; - guint i, j, n, num_refs, num_view_ids = 0; - gint found_ref_idx; - gint32 MaxPicNum, CurrPicNum, picNumPred, picViewIdxPred; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstH264SPS *const sps = get_sps (decoder); + GstH264RefPicListModification *ref_pic_list_modification; + guint num_ref_pic_list_modifications; + GstVaapiPictureH264 **ref_list; + guint *ref_list_count_ptr, ref_list_idx = 0; + const guint16 *view_ids = NULL; + guint i, j, n, num_refs, num_view_ids = 0; + gint found_ref_idx; + gint32 MaxPicNum, CurrPicNum, picNumPred, picViewIdxPred; - GST_DEBUG("modification process of reference picture list %u", list); + GST_DEBUG ("modification process of reference picture list %u", list); - if (list == 0) { - ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l0; - num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0; - ref_list = priv->RefPicList0; - ref_list_count_ptr = &priv->RefPicList0_count; - num_refs = slice_hdr->num_ref_idx_l0_active_minus1 + 1; + if (list == 0) { + ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l0; + num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0; + ref_list = priv->RefPicList0; + ref_list_count_ptr = &priv->RefPicList0_count; + num_refs = slice_hdr->num_ref_idx_l0_active_minus1 + 1; - if (GST_VAAPI_PICTURE_IS_MVC(picture) && - sps->extension_type == GST_H264_NAL_EXTENSION_MVC) { - const GstH264SPSExtMVCView * const view = - &sps->extension.mvc.view[picture->base.voc]; - if (GST_VAAPI_PICTURE_IS_ANCHOR(picture)) { - view_ids = view->anchor_ref_l0; - num_view_ids = view->num_anchor_refs_l0; - } - else { - view_ids = view->non_anchor_ref_l0; - num_view_ids = view->num_non_anchor_refs_l0; - } - } + if (GST_VAAPI_PICTURE_IS_MVC (picture) && + sps->extension_type == GST_H264_NAL_EXTENSION_MVC) { + const GstH264SPSExtMVCView *const view = + &sps->extension.mvc.view[picture->base.voc]; + if (GST_VAAPI_PICTURE_IS_ANCHOR (picture)) { + view_ids = view->anchor_ref_l0; + num_view_ids = view->num_anchor_refs_l0; + } else { + view_ids = view->non_anchor_ref_l0; + num_view_ids = view->num_non_anchor_refs_l0; + } } - else { - ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l1; - num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1; - ref_list = priv->RefPicList1; - ref_list_count_ptr = &priv->RefPicList1_count; - num_refs = slice_hdr->num_ref_idx_l1_active_minus1 + 1; + } else { + ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l1; + num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1; + ref_list = priv->RefPicList1; + ref_list_count_ptr = &priv->RefPicList1_count; + num_refs = slice_hdr->num_ref_idx_l1_active_minus1 + 1; - if (GST_VAAPI_PICTURE_IS_MVC(picture) && - sps->extension_type == GST_H264_NAL_EXTENSION_MVC) { - const GstH264SPSExtMVCView * const view = - &sps->extension.mvc.view[picture->base.voc]; - if (GST_VAAPI_PICTURE_IS_ANCHOR(picture)) { - view_ids = view->anchor_ref_l1; - num_view_ids = view->num_anchor_refs_l1; - } - else { - view_ids = view->non_anchor_ref_l1; - num_view_ids = view->num_non_anchor_refs_l1; - } - } + if (GST_VAAPI_PICTURE_IS_MVC (picture) && + sps->extension_type == GST_H264_NAL_EXTENSION_MVC) { + const GstH264SPSExtMVCView *const view = + &sps->extension.mvc.view[picture->base.voc]; + if (GST_VAAPI_PICTURE_IS_ANCHOR (picture)) { + view_ids = view->anchor_ref_l1; + num_view_ids = view->num_anchor_refs_l1; + } else { + view_ids = view->non_anchor_ref_l1; + num_view_ids = view->num_non_anchor_refs_l1; + } + } + } + + if (!GST_VAAPI_PICTURE_IS_FRAME (picture)) { + MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum + CurrPicNum = 2 * slice_hdr->frame_num + 1; // 2 * frame_num + 1 + } else { + MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 4); // MaxFrameNum + CurrPicNum = slice_hdr->frame_num; // frame_num + } + + picNumPred = CurrPicNum; + picViewIdxPred = -1; + + for (i = 0; i < num_ref_pic_list_modifications; i++) { + GstH264RefPicListModification *const l = &ref_pic_list_modification[i]; + if (l->modification_of_pic_nums_idc == 3) + break; + + /* 8.2.4.3.1 - Short-term reference pictures */ + if (l->modification_of_pic_nums_idc == 0 + || l->modification_of_pic_nums_idc == 1) { + gint32 abs_diff_pic_num = l->value.abs_diff_pic_num_minus1 + 1; + gint32 picNum, picNumNoWrap; + + // (8-34) + if (l->modification_of_pic_nums_idc == 0) { + picNumNoWrap = picNumPred - abs_diff_pic_num; + if (picNumNoWrap < 0) + picNumNoWrap += MaxPicNum; + } + // (8-35) + else { + picNumNoWrap = picNumPred + abs_diff_pic_num; + if (picNumNoWrap >= MaxPicNum) + picNumNoWrap -= MaxPicNum; + } + picNumPred = picNumNoWrap; + + // (8-36) + picNum = picNumNoWrap; + if (picNum > CurrPicNum) + picNum -= MaxPicNum; + + // (8-37) + for (j = num_refs; j > ref_list_idx; j--) + ref_list[j] = ref_list[j - 1]; + found_ref_idx = find_short_term_reference (decoder, picNum); + ref_list[ref_list_idx++] = + found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL; + n = ref_list_idx; + for (j = ref_list_idx; j <= num_refs; j++) { + gint32 PicNumF; + if (!ref_list[j]) + continue; + PicNumF = + GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE (ref_list[j]) ? + ref_list[j]->pic_num : MaxPicNum; + if (PicNumF != picNum || + ref_list[j]->base.view_id != picture->base.view_id) + ref_list[n++] = ref_list[j]; + } } - if (!GST_VAAPI_PICTURE_IS_FRAME(picture)) { - MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum - CurrPicNum = 2 * slice_hdr->frame_num + 1; // 2 * frame_num + 1 - } - else { - MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 4); // MaxFrameNum - CurrPicNum = slice_hdr->frame_num; // frame_num + /* 8.2.4.3.2 - Long-term reference pictures */ + else if (l->modification_of_pic_nums_idc == 2) { + + for (j = num_refs; j > ref_list_idx; j--) + ref_list[j] = ref_list[j - 1]; + found_ref_idx = + find_long_term_reference (decoder, l->value.long_term_pic_num); + ref_list[ref_list_idx++] = + found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL; + n = ref_list_idx; + for (j = ref_list_idx; j <= num_refs; j++) { + gint32 LongTermPicNumF; + if (!ref_list[j]) + continue; + LongTermPicNumF = + GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (ref_list[j]) ? + ref_list[j]->long_term_pic_num : INT_MAX; + if (LongTermPicNumF != l->value.long_term_pic_num || + ref_list[j]->base.view_id != picture->base.view_id) + ref_list[n++] = ref_list[j]; + } } - picNumPred = CurrPicNum; - picViewIdxPred = -1; + /* H.8.2.2.3 - Inter-view prediction reference pictures */ + else if ((GST_VAAPI_PICTURE_IS_MVC (picture) && + sps->extension_type == GST_H264_NAL_EXTENSION_MVC) && + (l->modification_of_pic_nums_idc == 4 || + l->modification_of_pic_nums_idc == 5)) { + gint32 abs_diff_view_idx = l->value.abs_diff_view_idx_minus1 + 1; + gint32 picViewIdx, targetViewId; - for (i = 0; i < num_ref_pic_list_modifications; i++) { - GstH264RefPicListModification * const l = &ref_pic_list_modification[i]; - if (l->modification_of_pic_nums_idc == 3) - break; + // (H-6) + if (l->modification_of_pic_nums_idc == 4) { + picViewIdx = picViewIdxPred - abs_diff_view_idx; + if (picViewIdx < 0) + picViewIdx += num_view_ids; + } + // (H-7) + else { + picViewIdx = picViewIdxPred + abs_diff_view_idx; + if (picViewIdx >= num_view_ids) + picViewIdx -= num_view_ids; + } + picViewIdxPred = picViewIdx; - /* 8.2.4.3.1 - Short-term reference pictures */ - if (l->modification_of_pic_nums_idc == 0 || l->modification_of_pic_nums_idc == 1) { - gint32 abs_diff_pic_num = l->value.abs_diff_pic_num_minus1 + 1; - gint32 picNum, picNumNoWrap; + // (H-8, H-9) + targetViewId = view_ids[picViewIdx]; - // (8-34) - if (l->modification_of_pic_nums_idc == 0) { - picNumNoWrap = picNumPred - abs_diff_pic_num; - if (picNumNoWrap < 0) - picNumNoWrap += MaxPicNum; - } - - // (8-35) - else { - picNumNoWrap = picNumPred + abs_diff_pic_num; - if (picNumNoWrap >= MaxPicNum) - picNumNoWrap -= MaxPicNum; - } - picNumPred = picNumNoWrap; - - // (8-36) - picNum = picNumNoWrap; - if (picNum > CurrPicNum) - picNum -= MaxPicNum; - - // (8-37) - for (j = num_refs; j > ref_list_idx; j--) - ref_list[j] = ref_list[j - 1]; - found_ref_idx = find_short_term_reference(decoder, picNum); - ref_list[ref_list_idx++] = - found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL; - n = ref_list_idx; - for (j = ref_list_idx; j <= num_refs; j++) { - gint32 PicNumF; - if (!ref_list[j]) - continue; - PicNumF = - GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(ref_list[j]) ? - ref_list[j]->pic_num : MaxPicNum; - if (PicNumF != picNum || - ref_list[j]->base.view_id != picture->base.view_id) - ref_list[n++] = ref_list[j]; - } - } - - /* 8.2.4.3.2 - Long-term reference pictures */ - else if (l->modification_of_pic_nums_idc == 2) { - - for (j = num_refs; j > ref_list_idx; j--) - ref_list[j] = ref_list[j - 1]; - found_ref_idx = - find_long_term_reference(decoder, l->value.long_term_pic_num); - ref_list[ref_list_idx++] = - found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL; - n = ref_list_idx; - for (j = ref_list_idx; j <= num_refs; j++) { - gint32 LongTermPicNumF; - if (!ref_list[j]) - continue; - LongTermPicNumF = - GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(ref_list[j]) ? - ref_list[j]->long_term_pic_num : INT_MAX; - if (LongTermPicNumF != l->value.long_term_pic_num || - ref_list[j]->base.view_id != picture->base.view_id) - ref_list[n++] = ref_list[j]; - } - } - - /* H.8.2.2.3 - Inter-view prediction reference pictures */ - else if ((GST_VAAPI_PICTURE_IS_MVC(picture) && - sps->extension_type == GST_H264_NAL_EXTENSION_MVC) && - (l->modification_of_pic_nums_idc == 4 || - l->modification_of_pic_nums_idc == 5)) { - gint32 abs_diff_view_idx = l->value.abs_diff_view_idx_minus1 + 1; - gint32 picViewIdx, targetViewId; - - // (H-6) - if (l->modification_of_pic_nums_idc == 4) { - picViewIdx = picViewIdxPred - abs_diff_view_idx; - if (picViewIdx < 0) - picViewIdx += num_view_ids; - } - - // (H-7) - else { - picViewIdx = picViewIdxPred + abs_diff_view_idx; - if (picViewIdx >= num_view_ids) - picViewIdx -= num_view_ids; - } - picViewIdxPred = picViewIdx; - - // (H-8, H-9) - targetViewId = view_ids[picViewIdx]; - - // (H-10) - for (j = num_refs; j > ref_list_idx; j--) - ref_list[j] = ref_list[j - 1]; - ref_list[ref_list_idx++] = - find_inter_view_reference(decoder, targetViewId); - n = ref_list_idx; - for (j = ref_list_idx; j <= num_refs; j++) { - if (!ref_list[j]) - continue; - if (ref_list[j]->base.view_id != targetViewId || - ref_list[j]->base.poc != picture->base.poc) - ref_list[n++] = ref_list[j]; - } - } + // (H-10) + for (j = num_refs; j > ref_list_idx; j--) + ref_list[j] = ref_list[j - 1]; + ref_list[ref_list_idx++] = + find_inter_view_reference (decoder, targetViewId); + n = ref_list_idx; + for (j = ref_list_idx; j <= num_refs; j++) { + if (!ref_list[j]) + continue; + if (ref_list[j]->base.view_id != targetViewId || + ref_list[j]->base.poc != picture->base.poc) + ref_list[n++] = ref_list[j]; + } } + } #if DEBUG - for (i = 0; i < num_refs; i++) - if (!ref_list[i]) - GST_ERROR("list %u entry %u is empty", list, i); + for (i = 0; i < num_refs; i++) + if (!ref_list[i]) + GST_ERROR ("list %u entry %u is empty", list, i); #endif - *ref_list_count_ptr = num_refs; + *ref_list_count_ptr = num_refs; } /* 8.2.4.3 - Modification process for reference picture lists */ static void -exec_picture_refs_modification( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr -) +exec_picture_refs_modification (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { - GST_DEBUG("execute ref_pic_list_modification()"); + GST_DEBUG ("execute ref_pic_list_modification()"); - /* RefPicList0 */ - if (!GST_H264_IS_I_SLICE(slice_hdr) && !GST_H264_IS_SI_SLICE(slice_hdr) && - slice_hdr->ref_pic_list_modification_flag_l0) - exec_picture_refs_modification_1(decoder, picture, slice_hdr, 0); + /* RefPicList0 */ + if (!GST_H264_IS_I_SLICE (slice_hdr) && !GST_H264_IS_SI_SLICE (slice_hdr) && + slice_hdr->ref_pic_list_modification_flag_l0) + exec_picture_refs_modification_1 (decoder, picture, slice_hdr, 0); - /* RefPicList1 */ - if (GST_H264_IS_B_SLICE(slice_hdr) && - slice_hdr->ref_pic_list_modification_flag_l1) - exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1); + /* RefPicList1 */ + if (GST_H264_IS_B_SLICE (slice_hdr) && + slice_hdr->ref_pic_list_modification_flag_l1) + exec_picture_refs_modification_1 (decoder, picture, slice_hdr, 1); } static gboolean -check_picture_ref_corruption(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *RefPicList[32], guint RefPicList_count) +check_picture_ref_corruption (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * RefPicList[32], guint RefPicList_count) { - const guint corrupted_flags = - GST_VAAPI_PICTURE_FLAG_CORRUPTED | GST_VAAPI_PICTURE_FLAG_GHOST; - guint i; + const guint corrupted_flags = + GST_VAAPI_PICTURE_FLAG_CORRUPTED | GST_VAAPI_PICTURE_FLAG_GHOST; + guint i; - for (i = 0; i < RefPicList_count; i++) { - GstVaapiPictureH264 * const picture = RefPicList[i]; - if (picture && (GST_VAAPI_PICTURE_FLAGS(picture) & corrupted_flags)) - return TRUE; - } - return FALSE; + for (i = 0; i < RefPicList_count; i++) { + GstVaapiPictureH264 *const picture = RefPicList[i]; + if (picture && (GST_VAAPI_PICTURE_FLAGS (picture) & corrupted_flags)) + return TRUE; + } + return FALSE; } static void -mark_picture_refs(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +mark_picture_refs (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiDecoderH264Private *const priv = &decoder->priv; - if (GST_VAAPI_PICTURE_IS_CORRUPTED(picture)) - return; + if (GST_VAAPI_PICTURE_IS_CORRUPTED (picture)) + return; - if (check_picture_ref_corruption(decoder, - priv->RefPicList0, priv->RefPicList0_count) || - check_picture_ref_corruption(decoder, - priv->RefPicList1, priv->RefPicList1_count)) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_CORRUPTED); + if (check_picture_ref_corruption (decoder, + priv->RefPicList0, priv->RefPicList0_count) || + check_picture_ref_corruption (decoder, + priv->RefPicList1, priv->RefPicList1_count)) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_CORRUPTED); } static void -init_picture_ref_lists(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture) +init_picture_ref_lists (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - guint i, j, short_ref_count, long_ref_count; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + guint i, j, short_ref_count, long_ref_count; - short_ref_count = 0; - long_ref_count = 0; - if (GST_VAAPI_PICTURE_IS_FRAME(picture)) { - for (i = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - GstVaapiPictureH264 *pic; - if (!gst_vaapi_frame_store_has_frame(fs)) - continue; - pic = fs->buffers[0]; - if (pic->base.view_id != picture->base.view_id) - continue; - if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(pic)) - priv->short_ref[short_ref_count++] = pic; - else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(pic)) - priv->long_ref[long_ref_count++] = pic; - pic->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - pic->other_field = fs->buffers[1]; - } + short_ref_count = 0; + long_ref_count = 0; + if (GST_VAAPI_PICTURE_IS_FRAME (picture)) { + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + GstVaapiPictureH264 *pic; + if (!gst_vaapi_frame_store_has_frame (fs)) + continue; + pic = fs->buffers[0]; + if (pic->base.view_id != picture->base.view_id) + continue; + if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE (pic)) + priv->short_ref[short_ref_count++] = pic; + else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (pic)) + priv->long_ref[long_ref_count++] = pic; + pic->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + pic->other_field = fs->buffers[1]; } - else { - for (i = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - for (j = 0; j < fs->num_buffers; j++) { - GstVaapiPictureH264 * const pic = fs->buffers[j]; - if (pic->base.view_id != picture->base.view_id) - continue; - if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(pic)) - priv->short_ref[short_ref_count++] = pic; - else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(pic)) - priv->long_ref[long_ref_count++] = pic; - pic->structure = pic->base.structure; - pic->other_field = fs->buffers[j ^ 1]; - } - } + } else { + for (i = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + for (j = 0; j < fs->num_buffers; j++) { + GstVaapiPictureH264 *const pic = fs->buffers[j]; + if (pic->base.view_id != picture->base.view_id) + continue; + if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE (pic)) + priv->short_ref[short_ref_count++] = pic; + else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (pic)) + priv->long_ref[long_ref_count++] = pic; + pic->structure = pic->base.structure; + pic->other_field = fs->buffers[j ^ 1]; + } } + } - for (i = short_ref_count; i < priv->short_ref_count; i++) - priv->short_ref[i] = NULL; - priv->short_ref_count = short_ref_count; + for (i = short_ref_count; i < priv->short_ref_count; i++) + priv->short_ref[i] = NULL; + priv->short_ref_count = short_ref_count; - for (i = long_ref_count; i < priv->long_ref_count; i++) - priv->long_ref[i] = NULL; - priv->long_ref_count = long_ref_count; + for (i = long_ref_count; i < priv->long_ref_count; i++) + priv->long_ref[i] = NULL; + priv->long_ref_count = long_ref_count; } static void -init_picture_refs( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr -) +init_picture_refs (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - guint i, num_refs; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + guint i, num_refs; - init_picture_ref_lists(decoder, picture); - init_picture_refs_pic_num(decoder, picture, slice_hdr); + init_picture_ref_lists (decoder, picture); + init_picture_refs_pic_num (decoder, picture, slice_hdr); - priv->RefPicList0_count = 0; - priv->RefPicList1_count = 0; + priv->RefPicList0_count = 0; + priv->RefPicList1_count = 0; - switch (slice_hdr->type % 5) { + switch (slice_hdr->type % 5) { case GST_H264_P_SLICE: case GST_H264_SP_SLICE: - init_picture_refs_p_slice(decoder, picture, slice_hdr); - break; + init_picture_refs_p_slice (decoder, picture, slice_hdr); + break; case GST_H264_B_SLICE: - init_picture_refs_b_slice(decoder, picture, slice_hdr); - break; + init_picture_refs_b_slice (decoder, picture, slice_hdr); + break; default: - break; - } + break; + } - exec_picture_refs_modification(decoder, picture, slice_hdr); + exec_picture_refs_modification (decoder, picture, slice_hdr); - switch (slice_hdr->type % 5) { + switch (slice_hdr->type % 5) { case GST_H264_B_SLICE: - num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1; - for (i = priv->RefPicList1_count; i < num_refs; i++) - priv->RefPicList1[i] = NULL; - priv->RefPicList1_count = num_refs; + num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1; + for (i = priv->RefPicList1_count; i < num_refs; i++) + priv->RefPicList1[i] = NULL; + priv->RefPicList1_count = num_refs; - // fall-through + // fall-through case GST_H264_P_SLICE: case GST_H264_SP_SLICE: - num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1; - for (i = priv->RefPicList0_count; i < num_refs; i++) - priv->RefPicList0[i] = NULL; - priv->RefPicList0_count = num_refs; - break; + num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1; + for (i = priv->RefPicList0_count; i < num_refs; i++) + priv->RefPicList0[i] = NULL; + priv->RefPicList0_count = num_refs; + break; default: - break; - } + break; + } - mark_picture_refs(decoder, picture); + mark_picture_refs (decoder, picture); } static GstVaapiPictureH264 * -fill_picture_first_field_gap(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *f0) +fill_picture_first_field_gap (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * f0) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 *f1; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 *f1; - f1 = gst_vaapi_picture_h264_new_clone(f0); - if (!f1) - goto error_allocate_field; + f1 = gst_vaapi_picture_h264_new_clone (f0); + if (!f1) + goto error_allocate_field; - gst_vaapi_picture_replace(&priv->missing_picture, f1); - gst_vaapi_picture_unref(f1); + gst_vaapi_picture_replace (&priv->missing_picture, f1); + gst_vaapi_picture_unref (f1); - GST_VAAPI_PICTURE_FLAG_SET(f1, - (GST_VAAPI_PICTURE_FLAG_ONEFIELD | - GST_VAAPI_PICTURE_FLAG_SKIPPED | - GST_VAAPI_PICTURE_FLAG_GHOST)); + GST_VAAPI_PICTURE_FLAG_SET (f1, + (GST_VAAPI_PICTURE_FLAG_ONEFIELD | + GST_VAAPI_PICTURE_FLAG_SKIPPED | GST_VAAPI_PICTURE_FLAG_GHOST)); - gst_vaapi_picture_h264_set_reference(f1, 0, FALSE); - return f1; + gst_vaapi_picture_h264_set_reference (f1, 0, FALSE); + return f1; - /* ERRORS */ + /* ERRORS */ error_allocate_field: - GST_ERROR("failed to allocate missing field for current frame store"); - return NULL; + GST_ERROR ("failed to allocate missing field for current frame store"); + return NULL; } static gboolean -fill_picture_first_field_gap_done(GstVaapiDecoderH264 *decoder, - GstH264SliceHdr *slice_hdr) +fill_picture_first_field_gap_done (GstVaapiDecoderH264 * decoder, + GstH264SliceHdr * slice_hdr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 * const lost_field = priv->missing_picture; - GstH264SliceHdr lost_slice_hdr; - gboolean success = FALSE; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 *const lost_field = priv->missing_picture; + GstH264SliceHdr lost_slice_hdr; + gboolean success = FALSE; - g_return_val_if_fail(priv->current_picture != NULL, FALSE); + g_return_val_if_fail (priv->current_picture != NULL, FALSE); - if (!lost_field) - return TRUE; - - lost_field->frame_num = slice_hdr->frame_num; - lost_field->frame_num_wrap = slice_hdr->frame_num; - - gst_vaapi_picture_h264_set_reference(lost_field, - (GST_VAAPI_PICTURE_FLAGS(priv->current_picture) & - GST_VAAPI_PICTURE_FLAGS_REFERENCE), FALSE); - - lost_slice_hdr = *slice_hdr; - lost_slice_hdr.bottom_field_flag = !lost_slice_hdr.bottom_field_flag; - - init_picture_poc(decoder, lost_field, &lost_slice_hdr); - init_picture_ref_lists(decoder, lost_field); - init_picture_refs_pic_num(decoder, lost_field, &lost_slice_hdr); - if (!exec_ref_pic_marking_sliding_window(decoder)) - goto error_exec_ref_pic_marking; - if (!dpb_add(decoder, lost_field)) - goto error_dpb_add; - success = TRUE; - -cleanup: - gst_vaapi_picture_replace(&priv->missing_picture, NULL); - return success; - - /* ERRORS */ -error_exec_ref_pic_marking: - GST_ERROR("failed to execute reference picture marking process"); - goto cleanup; -error_dpb_add: - GST_ERROR("failed to store lost picture into the DPB"); - goto cleanup; -} - -static GstVaapiPictureH264 * -fill_picture_other_field_gap(GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *f0) -{ - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 *prev_picture, *f1; - gint prev_frame_index; - guint picture_structure; - - picture_structure = f0->base.structure; - 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; - default: - g_assert(0 && "unexpected picture structure"); - return NULL; - } - GST_VAAPI_PICTURE_FLAG_SET(f0, GST_VAAPI_PICTURE_FLAG_ONEFIELD); - - prev_frame_index = dpb_find_nearest_prev_poc(decoder, f0, - picture_structure, &prev_picture); - if (prev_frame_index < 0) - goto error_find_field; - - f1 = gst_vaapi_picture_h264_new_field(f0); - if (!f1) - goto error_allocate_field; - - gst_vaapi_surface_proxy_replace(&f1->base.proxy, prev_picture->base.proxy); - f1->base.surface = GST_VAAPI_SURFACE_PROXY_SURFACE(f1->base.proxy); - f1->base.surface_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID(f1->base.proxy); - f1->base.poc++; - f1->structure = f1->base.structure; - - /* XXX: clone other H.264 picture specific flags */ - GST_VAAPI_PICTURE_FLAG_SET(f1, - (GST_VAAPI_PICTURE_FLAG_SKIPPED | - GST_VAAPI_PICTURE_FLAG_GHOST)); - - gst_vaapi_picture_h264_set_reference(f1, 0, FALSE); - gst_vaapi_picture_replace(&priv->current_picture, f1); - gst_vaapi_picture_unref(f1); - - init_picture_ref_lists(decoder, f1); - init_picture_refs_pic_num(decoder, f1, NULL); - if (!exec_ref_pic_marking_sliding_window(decoder)) - goto error_exec_ref_pic_marking; - if (!dpb_add(decoder, f1)) - goto error_append_field; - return f1; - - /* ERRORS */ -error_find_field: - GST_ERROR("failed to find field with POC nearest to %d", f0->base.poc); - return NULL; -error_allocate_field: - GST_ERROR("failed to allocate missing field for previous frame store"); - return NULL; -error_exec_ref_pic_marking: - GST_ERROR("failed to execute reference picture marking process"); - return NULL; -error_append_field: - GST_ERROR("failed to add missing field into previous frame store"); - return NULL; -} - -static gboolean -fill_picture_gaps(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, - GstH264SliceHdr *slice_hdr) -{ - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264SPS * const sps = get_sps(decoder); - const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); - GstVaapiFrameStore *prev_frame; - GstVaapiPicture *base_picture; - GstVaapiPictureH264 *lost_picture, *prev_picture; - GstH264SliceHdr lost_slice_hdr; - gboolean success = FALSE; - - if (priv->prev_ref_frame_num == priv->frame_num) - return TRUE; - if ((priv->prev_ref_frame_num + 1) % MaxFrameNum == priv->frame_num) - return TRUE; - if (priv->dpb_count == 0) - return TRUE; - - prev_frame = priv->prev_ref_frames[picture->base.voc]; - g_assert(prev_frame != NULL); - prev_picture = gst_vaapi_picture_ref(prev_frame->buffers[0]); - gst_vaapi_picture_ref(picture); - - lost_slice_hdr = *slice_hdr; - lost_slice_hdr.field_pic_flag = 0; - if (sps->pic_order_cnt_type == 1) { - lost_slice_hdr.delta_pic_order_cnt[0] = 0; - lost_slice_hdr.delta_pic_order_cnt[1] = 0; - } - lost_slice_hdr.dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag = 0; - - /* XXX: this process is incorrect for MVC */ - /* XXX: optimize to reduce the number of dummy pictures created */ - priv->frame_num = priv->prev_ref_frame_num; - for (;;) { - priv->prev_ref_frame_num = priv->frame_num; - priv->frame_num = (priv->prev_ref_frame_num + 1) % MaxFrameNum; - if (priv->frame_num == slice_hdr->frame_num) - break; - - /* Create new picture */ - if (prev_picture) - lost_picture = gst_vaapi_picture_h264_new_clone(prev_picture); - else - lost_picture = gst_vaapi_picture_h264_new(decoder); - if (!lost_picture) - goto error_allocate_picture; - - base_picture = &lost_picture->base; - base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE; - base_picture->pts = GST_CLOCK_TIME_NONE; - base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - lost_picture->frame_num = priv->frame_num; - lost_picture->frame_num_wrap = priv->frame_num; - lost_picture->structure = base_picture->structure; - - GST_VAAPI_PICTURE_FLAG_SET(lost_picture, - (GST_VAAPI_PICTURE_FLAG_SKIPPED | - GST_VAAPI_PICTURE_FLAG_GHOST | - GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE)); - - if (sps->pic_order_cnt_type != 0) - init_picture_poc(decoder, lost_picture, &lost_slice_hdr); - else { - base_picture->poc = prev_picture->base.poc + 2; - if (prev_picture->field_poc[0] != G_MAXINT32) - lost_picture->field_poc[0] = prev_picture->field_poc[0] + 2; - if (prev_picture->field_poc[1] != G_MAXINT32) - lost_picture->field_poc[1] = prev_picture->field_poc[1] + 2; - } - - gst_vaapi_picture_replace(&prev_picture, lost_picture); - gst_vaapi_picture_replace(&priv->current_picture, lost_picture); - gst_vaapi_picture_unref(lost_picture); - - init_picture_ref_lists(decoder, lost_picture); - init_picture_refs_pic_num(decoder, lost_picture, &lost_slice_hdr); - if (!exec_ref_pic_marking_sliding_window(decoder)) - goto error_exec_ref_pic_marking; - if (!dpb_add(decoder, lost_picture)) - goto error_dpb_add; - gst_vaapi_picture_replace(&priv->current_picture, NULL); - } - success = TRUE; - -cleanup: - priv->frame_num = slice_hdr->frame_num; - priv->prev_ref_frame_num = (priv->frame_num + MaxFrameNum - 1) % MaxFrameNum; - gst_vaapi_picture_replace(&prev_picture, NULL); - gst_vaapi_picture_replace(&priv->current_picture, picture); - gst_vaapi_picture_unref(picture); - return success; - - /* ERRORS */ -error_allocate_picture: - GST_ERROR("failed to allocate lost picture"); - goto cleanup; -error_exec_ref_pic_marking: - GST_ERROR("failed to execute reference picture marking process"); - goto cleanup; -error_dpb_add: - GST_ERROR("failed to store lost picture into the DPB"); - goto cleanup; -} - -static gboolean -init_picture( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi) -{ - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPicture * const base_picture = &picture->base; - GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; - - if (priv->prev_pic_reference) - priv->prev_ref_frame_num = priv->frame_num; - priv->prev_frame_num = priv->frame_num; - priv->frame_num = slice_hdr->frame_num; - picture->frame_num = priv->frame_num; - picture->frame_num_wrap = priv->frame_num; - picture->output_flag = TRUE; /* XXX: conformant to Annex A only */ - base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; - base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE; - base_picture->view_id = pi->view_id; - base_picture->voc = pi->voc; - - /* Initialize extensions */ - switch (pi->nalu.extension_type) { - case GST_H264_NAL_EXTENSION_MVC: { - GstH264NalUnitExtensionMVC * const mvc = &pi->nalu.extension.mvc; - - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_MVC); - if (mvc->inter_view_flag) - GST_VAAPI_PICTURE_FLAG_SET(picture, - GST_VAAPI_PICTURE_FLAG_INTER_VIEW); - if (mvc->anchor_pic_flag) - GST_VAAPI_PICTURE_FLAG_SET(picture, - GST_VAAPI_PICTURE_FLAG_ANCHOR); - break; - } - } - - /* Reset decoder state for IDR pictures */ - if (pi->nalu.idr_pic_flag) { - GST_DEBUG(""); - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR); - dpb_flush(decoder, picture); - } - else if (!fill_picture_gaps(decoder, picture, slice_hdr)) - return FALSE; - - /* Initialize picture structure */ - if (slice_hdr->field_pic_flag) { - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED); - priv->pic_structure = slice_hdr->bottom_field_flag ? - GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD : - GST_H264_SEI_PIC_STRUCT_TOP_FIELD; - } - - base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - switch (priv->pic_structure) { - case GST_H264_SEI_PIC_STRUCT_TOP_FIELD: - base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; - if (GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture)) - priv->top_field_first = TRUE; - break; - case GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD: - base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; - break; - case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP: - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_RFF); - // fall-through - case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM: - if (GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture)) - priv->top_field_first = TRUE; - break; - case GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_RFF); - break; - case GST_H264_SEI_PIC_STRUCT_FRAME: - if (!priv->progressive_sequence && priv->dpb_count == 0) - priv->top_field_first = TRUE; - break; - } - picture->structure = base_picture->structure; - if (priv->top_field_first) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF); - - /* Initialize reference flags */ - if (pi->nalu.ref_idc) { - GstH264DecRefPicMarking * const dec_ref_pic_marking = - &slice_hdr->dec_ref_pic_marking; - - if (GST_VAAPI_PICTURE_IS_IDR(picture) && - dec_ref_pic_marking->long_term_reference_flag) - GST_VAAPI_PICTURE_FLAG_SET(picture, - GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); - else - GST_VAAPI_PICTURE_FLAG_SET(picture, - GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE); - } - - fill_picture_first_field_gap_done(decoder, slice_hdr); - init_picture_poc(decoder, picture, slice_hdr); + if (!lost_field) return TRUE; + + lost_field->frame_num = slice_hdr->frame_num; + lost_field->frame_num_wrap = slice_hdr->frame_num; + + gst_vaapi_picture_h264_set_reference (lost_field, + (GST_VAAPI_PICTURE_FLAGS (priv->current_picture) & + GST_VAAPI_PICTURE_FLAGS_REFERENCE), FALSE); + + lost_slice_hdr = *slice_hdr; + lost_slice_hdr.bottom_field_flag = !lost_slice_hdr.bottom_field_flag; + + init_picture_poc (decoder, lost_field, &lost_slice_hdr); + init_picture_ref_lists (decoder, lost_field); + init_picture_refs_pic_num (decoder, lost_field, &lost_slice_hdr); + if (!exec_ref_pic_marking_sliding_window (decoder)) + goto error_exec_ref_pic_marking; + if (!dpb_add (decoder, lost_field)) + goto error_dpb_add; + success = TRUE; + +cleanup: + gst_vaapi_picture_replace (&priv->missing_picture, NULL); + return success; + + /* ERRORS */ +error_exec_ref_pic_marking: + GST_ERROR ("failed to execute reference picture marking process"); + goto cleanup; +error_dpb_add: + GST_ERROR ("failed to store lost picture into the DPB"); + goto cleanup; +} + +static GstVaapiPictureH264 * +fill_picture_other_field_gap (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * f0) +{ + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 *prev_picture, *f1; + gint prev_frame_index; + guint picture_structure; + + picture_structure = f0->base.structure; + 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; + default: + g_assert (0 && "unexpected picture structure"); + return NULL; + } + GST_VAAPI_PICTURE_FLAG_SET (f0, GST_VAAPI_PICTURE_FLAG_ONEFIELD); + + prev_frame_index = dpb_find_nearest_prev_poc (decoder, f0, + picture_structure, &prev_picture); + if (prev_frame_index < 0) + goto error_find_field; + + f1 = gst_vaapi_picture_h264_new_field (f0); + if (!f1) + goto error_allocate_field; + + gst_vaapi_surface_proxy_replace (&f1->base.proxy, prev_picture->base.proxy); + f1->base.surface = GST_VAAPI_SURFACE_PROXY_SURFACE (f1->base.proxy); + f1->base.surface_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (f1->base.proxy); + f1->base.poc++; + f1->structure = f1->base.structure; + + /* XXX: clone other H.264 picture specific flags */ + GST_VAAPI_PICTURE_FLAG_SET (f1, + (GST_VAAPI_PICTURE_FLAG_SKIPPED | GST_VAAPI_PICTURE_FLAG_GHOST)); + + gst_vaapi_picture_h264_set_reference (f1, 0, FALSE); + gst_vaapi_picture_replace (&priv->current_picture, f1); + gst_vaapi_picture_unref (f1); + + init_picture_ref_lists (decoder, f1); + init_picture_refs_pic_num (decoder, f1, NULL); + if (!exec_ref_pic_marking_sliding_window (decoder)) + goto error_exec_ref_pic_marking; + if (!dpb_add (decoder, f1)) + goto error_append_field; + return f1; + + /* ERRORS */ +error_find_field: + GST_ERROR ("failed to find field with POC nearest to %d", f0->base.poc); + return NULL; +error_allocate_field: + GST_ERROR ("failed to allocate missing field for previous frame store"); + return NULL; +error_exec_ref_pic_marking: + GST_ERROR ("failed to execute reference picture marking process"); + return NULL; +error_append_field: + GST_ERROR ("failed to add missing field into previous frame store"); + return NULL; +} + +static gboolean +fill_picture_gaps (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, + GstH264SliceHdr * slice_hdr) +{ + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstH264SPS *const sps = get_sps (decoder); + const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); + GstVaapiFrameStore *prev_frame; + GstVaapiPicture *base_picture; + GstVaapiPictureH264 *lost_picture, *prev_picture; + GstH264SliceHdr lost_slice_hdr; + gboolean success = FALSE; + + if (priv->prev_ref_frame_num == priv->frame_num) + return TRUE; + if ((priv->prev_ref_frame_num + 1) % MaxFrameNum == priv->frame_num) + return TRUE; + if (priv->dpb_count == 0) + return TRUE; + + prev_frame = priv->prev_ref_frames[picture->base.voc]; + g_assert (prev_frame != NULL); + prev_picture = gst_vaapi_picture_ref (prev_frame->buffers[0]); + gst_vaapi_picture_ref (picture); + + lost_slice_hdr = *slice_hdr; + lost_slice_hdr.field_pic_flag = 0; + if (sps->pic_order_cnt_type == 1) { + lost_slice_hdr.delta_pic_order_cnt[0] = 0; + lost_slice_hdr.delta_pic_order_cnt[1] = 0; + } + lost_slice_hdr.dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag = 0; + + /* XXX: this process is incorrect for MVC */ + /* XXX: optimize to reduce the number of dummy pictures created */ + priv->frame_num = priv->prev_ref_frame_num; + for (;;) { + priv->prev_ref_frame_num = priv->frame_num; + priv->frame_num = (priv->prev_ref_frame_num + 1) % MaxFrameNum; + if (priv->frame_num == slice_hdr->frame_num) + break; + + /* Create new picture */ + if (prev_picture) + lost_picture = gst_vaapi_picture_h264_new_clone (prev_picture); + else + lost_picture = gst_vaapi_picture_h264_new (decoder); + if (!lost_picture) + goto error_allocate_picture; + + base_picture = &lost_picture->base; + base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE; + base_picture->pts = GST_CLOCK_TIME_NONE; + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + lost_picture->frame_num = priv->frame_num; + lost_picture->frame_num_wrap = priv->frame_num; + lost_picture->structure = base_picture->structure; + + GST_VAAPI_PICTURE_FLAG_SET (lost_picture, + (GST_VAAPI_PICTURE_FLAG_SKIPPED | + GST_VAAPI_PICTURE_FLAG_GHOST | + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE)); + + if (sps->pic_order_cnt_type != 0) + init_picture_poc (decoder, lost_picture, &lost_slice_hdr); + else { + base_picture->poc = prev_picture->base.poc + 2; + if (prev_picture->field_poc[0] != G_MAXINT32) + lost_picture->field_poc[0] = prev_picture->field_poc[0] + 2; + if (prev_picture->field_poc[1] != G_MAXINT32) + lost_picture->field_poc[1] = prev_picture->field_poc[1] + 2; + } + + gst_vaapi_picture_replace (&prev_picture, lost_picture); + gst_vaapi_picture_replace (&priv->current_picture, lost_picture); + gst_vaapi_picture_unref (lost_picture); + + init_picture_ref_lists (decoder, lost_picture); + init_picture_refs_pic_num (decoder, lost_picture, &lost_slice_hdr); + if (!exec_ref_pic_marking_sliding_window (decoder)) + goto error_exec_ref_pic_marking; + if (!dpb_add (decoder, lost_picture)) + goto error_dpb_add; + gst_vaapi_picture_replace (&priv->current_picture, NULL); + } + success = TRUE; + +cleanup: + priv->frame_num = slice_hdr->frame_num; + priv->prev_ref_frame_num = (priv->frame_num + MaxFrameNum - 1) % MaxFrameNum; + gst_vaapi_picture_replace (&prev_picture, NULL); + gst_vaapi_picture_replace (&priv->current_picture, picture); + gst_vaapi_picture_unref (picture); + return success; + + /* ERRORS */ +error_allocate_picture: + GST_ERROR ("failed to allocate lost picture"); + goto cleanup; +error_exec_ref_pic_marking: + GST_ERROR ("failed to execute reference picture marking process"); + goto cleanup; +error_dpb_add: + GST_ERROR ("failed to store lost picture into the DPB"); + goto cleanup; +} + +static gboolean +init_picture (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstVaapiParserInfoH264 * pi) +{ + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPicture *const base_picture = &picture->base; + GstH264SliceHdr *const slice_hdr = &pi->data.slice_hdr; + + if (priv->prev_pic_reference) + priv->prev_ref_frame_num = priv->frame_num; + priv->prev_frame_num = priv->frame_num; + priv->frame_num = slice_hdr->frame_num; + picture->frame_num = priv->frame_num; + picture->frame_num_wrap = priv->frame_num; + picture->output_flag = TRUE; /* XXX: conformant to Annex A only */ + base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts; + base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE; + base_picture->view_id = pi->view_id; + base_picture->voc = pi->voc; + + /* Initialize extensions */ + switch (pi->nalu.extension_type) { + case GST_H264_NAL_EXTENSION_MVC:{ + GstH264NalUnitExtensionMVC *const mvc = &pi->nalu.extension.mvc; + + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_MVC); + if (mvc->inter_view_flag) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_INTER_VIEW); + if (mvc->anchor_pic_flag) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_ANCHOR); + break; + } + } + + /* Reset decoder state for IDR pictures */ + if (pi->nalu.idr_pic_flag) { + GST_DEBUG (""); + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_IDR); + dpb_flush (decoder, picture); + } else if (!fill_picture_gaps (decoder, picture, slice_hdr)) + return FALSE; + + /* Initialize picture structure */ + if (slice_hdr->field_pic_flag) { + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_INTERLACED); + priv->pic_structure = slice_hdr->bottom_field_flag ? + GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD : + GST_H264_SEI_PIC_STRUCT_TOP_FIELD; + } + + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + switch (priv->pic_structure) { + case GST_H264_SEI_PIC_STRUCT_TOP_FIELD: + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + if (GST_VAAPI_PICTURE_IS_FIRST_FIELD (picture)) + priv->top_field_first = TRUE; + break; + case GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD: + base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + break; + case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP: + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_RFF); + // fall-through + case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM: + if (GST_VAAPI_PICTURE_IS_FIRST_FIELD (picture)) + priv->top_field_first = TRUE; + break; + case GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_RFF); + break; + case GST_H264_SEI_PIC_STRUCT_FRAME: + if (!priv->progressive_sequence && priv->dpb_count == 0) + priv->top_field_first = TRUE; + break; + } + picture->structure = base_picture->structure; + if (priv->top_field_first) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_TFF); + + /* Initialize reference flags */ + if (pi->nalu.ref_idc) { + GstH264DecRefPicMarking *const dec_ref_pic_marking = + &slice_hdr->dec_ref_pic_marking; + + if (GST_VAAPI_PICTURE_IS_IDR (picture) && + dec_ref_pic_marking->long_term_reference_flag) + GST_VAAPI_PICTURE_FLAG_SET (picture, + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); + else + GST_VAAPI_PICTURE_FLAG_SET (picture, + GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE); + } + + fill_picture_first_field_gap_done (decoder, slice_hdr); + init_picture_poc (decoder, picture, slice_hdr); + return TRUE; } /* 8.2.5.3 - Sliding window decoded reference picture marking process */ static gboolean -exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) +exec_ref_pic_marking_sliding_window (GstVaapiDecoderH264 * decoder) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264SPS * const sps = get_sps(decoder); - GstVaapiPictureH264 *ref_picture; - guint i, m, max_num_ref_frames; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstH264SPS *const sps = get_sps (decoder); + GstVaapiPictureH264 *ref_picture; + guint i, m, max_num_ref_frames; - GST_DEBUG("reference picture marking process (sliding window)"); + GST_DEBUG ("reference picture marking process (sliding window)"); - if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD(priv->current_picture)) - return TRUE; - - max_num_ref_frames = sps->num_ref_frames; - if (max_num_ref_frames == 0) - max_num_ref_frames = 1; - if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) - max_num_ref_frames <<= 1; - - if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames) - return TRUE; - if (priv->short_ref_count < 1) - return FALSE; - - for (m = 0, i = 1; i < priv->short_ref_count; i++) { - GstVaapiPictureH264 * const picture = priv->short_ref[i]; - if (picture->frame_num_wrap < priv->short_ref[m]->frame_num_wrap) - m = i; - } - - ref_picture = priv->short_ref[m]; - gst_vaapi_picture_h264_set_reference(ref_picture, 0, TRUE); - ARRAY_REMOVE_INDEX(priv->short_ref, m); - - /* Both fields need to be marked as "unused for reference", so - remove the other field from the short_ref[] list as well */ - if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture) && ref_picture->other_field) { - for (i = 0; i < priv->short_ref_count; i++) { - if (priv->short_ref[i] == ref_picture->other_field) { - ARRAY_REMOVE_INDEX(priv->short_ref, i); - break; - } - } - } + if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD (priv->current_picture)) return TRUE; + + max_num_ref_frames = sps->num_ref_frames; + if (max_num_ref_frames == 0) + max_num_ref_frames = 1; + if (!GST_VAAPI_PICTURE_IS_FRAME (priv->current_picture)) + max_num_ref_frames <<= 1; + + if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames) + return TRUE; + if (priv->short_ref_count < 1) + return FALSE; + + for (m = 0, i = 1; i < priv->short_ref_count; i++) { + GstVaapiPictureH264 *const picture = priv->short_ref[i]; + if (picture->frame_num_wrap < priv->short_ref[m]->frame_num_wrap) + m = i; + } + + ref_picture = priv->short_ref[m]; + gst_vaapi_picture_h264_set_reference (ref_picture, 0, TRUE); + ARRAY_REMOVE_INDEX (priv->short_ref, m); + + /* Both fields need to be marked as "unused for reference", so + remove the other field from the short_ref[] list as well */ + if (!GST_VAAPI_PICTURE_IS_FRAME (priv->current_picture) + && ref_picture->other_field) { + for (i = 0; i < priv->short_ref_count; i++) { + if (priv->short_ref[i] == ref_picture->other_field) { + ARRAY_REMOVE_INDEX (priv->short_ref, i); + break; + } + } + } + return TRUE; } static inline gint32 -get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking) +get_picNumX (GstVaapiPictureH264 * picture, + GstH264RefPicMarking * ref_pic_marking) { - gint32 pic_num; + gint32 pic_num; - if (GST_VAAPI_PICTURE_IS_FRAME(picture)) - pic_num = picture->frame_num_wrap; - else - pic_num = 2 * picture->frame_num_wrap + 1; - pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1; - return pic_num; + if (GST_VAAPI_PICTURE_IS_FRAME (picture)) + pic_num = picture->frame_num_wrap; + else + pic_num = 2 * picture->frame_num_wrap + 1; + pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1; + return pic_num; } /* 8.2.5.4.1. Mark short-term reference picture as "unused for reference" */ static void -exec_ref_pic_marking_adaptive_mmco_1( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264RefPicMarking *ref_pic_marking -) +exec_ref_pic_marking_adaptive_mmco_1 (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264RefPicMarking * ref_pic_marking) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - gint32 i, picNumX; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + gint32 i, picNumX; - picNumX = get_picNumX(picture, ref_pic_marking); - i = find_short_term_reference(decoder, picNumX); - if (i < 0) - return; + picNumX = get_picNumX (picture, ref_pic_marking); + i = find_short_term_reference (decoder, picNumX); + if (i < 0) + return; - gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0, - GST_VAAPI_PICTURE_IS_FRAME(picture)); - ARRAY_REMOVE_INDEX(priv->short_ref, i); + gst_vaapi_picture_h264_set_reference (priv->short_ref[i], 0, + GST_VAAPI_PICTURE_IS_FRAME (picture)); + ARRAY_REMOVE_INDEX (priv->short_ref, i); } /* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */ static void -exec_ref_pic_marking_adaptive_mmco_2( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264RefPicMarking *ref_pic_marking -) +exec_ref_pic_marking_adaptive_mmco_2 (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264RefPicMarking * ref_pic_marking) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - gint32 i; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + gint32 i; - i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num); - if (i < 0) - return; + i = find_long_term_reference (decoder, ref_pic_marking->long_term_pic_num); + if (i < 0) + return; - gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, - GST_VAAPI_PICTURE_IS_FRAME(picture)); - ARRAY_REMOVE_INDEX(priv->long_ref, i); + gst_vaapi_picture_h264_set_reference (priv->long_ref[i], 0, + GST_VAAPI_PICTURE_IS_FRAME (picture)); + ARRAY_REMOVE_INDEX (priv->long_ref, i); } /* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */ static void -exec_ref_pic_marking_adaptive_mmco_3( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264RefPicMarking *ref_pic_marking -) +exec_ref_pic_marking_adaptive_mmco_3 (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264RefPicMarking * ref_pic_marking) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 *ref_picture, *other_field; - gint32 i, picNumX; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 *ref_picture, *other_field; + gint32 i, picNumX; - for (i = 0; i < priv->long_ref_count; i++) { - if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx) - break; - } - if (i != priv->long_ref_count) { - gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE); - ARRAY_REMOVE_INDEX(priv->long_ref, i); - } + for (i = 0; i < priv->long_ref_count; i++) { + if (priv->long_ref[i]->long_term_frame_idx == + ref_pic_marking->long_term_frame_idx) + break; + } + if (i != priv->long_ref_count) { + gst_vaapi_picture_h264_set_reference (priv->long_ref[i], 0, TRUE); + ARRAY_REMOVE_INDEX (priv->long_ref, i); + } - picNumX = get_picNumX(picture, ref_pic_marking); - i = find_short_term_reference(decoder, picNumX); - if (i < 0) - return; + picNumX = get_picNumX (picture, ref_pic_marking); + i = find_short_term_reference (decoder, picNumX); + if (i < 0) + return; - ref_picture = priv->short_ref[i]; - ARRAY_REMOVE_INDEX(priv->short_ref, i); - priv->long_ref[priv->long_ref_count++] = ref_picture; + ref_picture = priv->short_ref[i]; + ARRAY_REMOVE_INDEX (priv->short_ref, i); + priv->long_ref[priv->long_ref_count++] = ref_picture; - ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; - gst_vaapi_picture_h264_set_reference(ref_picture, - GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, - GST_VAAPI_PICTURE_IS_COMPLETE(picture)); + ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; + gst_vaapi_picture_h264_set_reference (ref_picture, + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, + GST_VAAPI_PICTURE_IS_COMPLETE (picture)); - /* Assign LongTermFrameIdx to the other field if it was also - marked as "used for long-term reference */ - other_field = ref_picture->other_field; - if (other_field && GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(other_field)) - other_field->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; + /* Assign LongTermFrameIdx to the other field if it was also + marked as "used for long-term reference */ + other_field = ref_picture->other_field; + if (other_field && GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (other_field)) + other_field->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; } /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx * as "unused for reference" */ static void -exec_ref_pic_marking_adaptive_mmco_4( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264RefPicMarking *ref_pic_marking -) +exec_ref_pic_marking_adaptive_mmco_4 (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264RefPicMarking * ref_pic_marking) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - gint32 i, long_term_frame_idx; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + gint32 i, long_term_frame_idx; - long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1; + long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1; - for (i = 0; i < priv->long_ref_count; i++) { - if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx) - continue; - gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, FALSE); - ARRAY_REMOVE_INDEX(priv->long_ref, i); - i--; - } + for (i = 0; i < priv->long_ref_count; i++) { + if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx) + continue; + gst_vaapi_picture_h264_set_reference (priv->long_ref[i], 0, FALSE); + ARRAY_REMOVE_INDEX (priv->long_ref, i); + i--; + } } /* 8.2.5.4.5. Mark all reference pictures as "unused for reference" */ static void -exec_ref_pic_marking_adaptive_mmco_5( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264RefPicMarking *ref_pic_marking -) +exec_ref_pic_marking_adaptive_mmco_5 (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264RefPicMarking * ref_pic_marking) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiDecoderH264Private *const priv = &decoder->priv; - dpb_flush(decoder, picture); + dpb_flush (decoder, picture); - priv->prev_pic_has_mmco5 = TRUE; + priv->prev_pic_has_mmco5 = TRUE; - /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */ - priv->frame_num = 0; - priv->frame_num_offset = 0; - picture->frame_num = 0; + /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */ + priv->frame_num = 0; + priv->frame_num_offset = 0; + picture->frame_num = 0; - /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */ - if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) - picture->field_poc[TOP_FIELD] -= picture->base.poc; - if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) - picture->field_poc[BOTTOM_FIELD] -= picture->base.poc; - picture->base.poc = 0; + /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */ + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) + picture->field_poc[TOP_FIELD] -= picture->base.poc; + if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) + picture->field_poc[BOTTOM_FIELD] -= picture->base.poc; + picture->base.poc = 0; } /* 8.2.5.4.6. Assign a long-term frame index to the current picture */ static void -exec_ref_pic_marking_adaptive_mmco_6( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264RefPicMarking *ref_pic_marking -) +exec_ref_pic_marking_adaptive_mmco_6 (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstH264RefPicMarking * ref_pic_marking) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPictureH264 *other_field; - guint i; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPictureH264 *other_field; + guint i; - for (i = 0; i < priv->long_ref_count; i++) { - if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx) - break; - } - if (i != priv->long_ref_count) { - gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE); - ARRAY_REMOVE_INDEX(priv->long_ref, i); - } + for (i = 0; i < priv->long_ref_count; i++) { + if (priv->long_ref[i]->long_term_frame_idx == + ref_pic_marking->long_term_frame_idx) + break; + } + if (i != priv->long_ref_count) { + gst_vaapi_picture_h264_set_reference (priv->long_ref[i], 0, TRUE); + ARRAY_REMOVE_INDEX (priv->long_ref, i); + } - picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; - gst_vaapi_picture_h264_set_reference(picture, - GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, - GST_VAAPI_PICTURE_IS_COMPLETE(picture)); + picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; + gst_vaapi_picture_h264_set_reference (picture, + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, + GST_VAAPI_PICTURE_IS_COMPLETE (picture)); - /* Assign LongTermFrameIdx to the other field if it was also - marked as "used for long-term reference */ - other_field = GST_VAAPI_PICTURE_H264(picture->base.parent_picture); - if (other_field && GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(other_field)) - other_field->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; + /* Assign LongTermFrameIdx to the other field if it was also + marked as "used for long-term reference */ + other_field = GST_VAAPI_PICTURE_H264 (picture->base.parent_picture); + if (other_field && GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (other_field)) + other_field->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; } /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */ static gboolean -exec_ref_pic_marking_adaptive( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264DecRefPicMarking *dec_ref_pic_marking -) +exec_ref_pic_marking_adaptive (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, + GstH264DecRefPicMarking * dec_ref_pic_marking) { - guint i; + guint i; - typedef void (*exec_ref_pic_marking_adaptive_mmco_func)( - GstVaapiDecoderH264 *decoder, - GstVaapiPictureH264 *picture, - GstH264RefPicMarking *ref_pic_marking - ); + typedef void (*exec_ref_pic_marking_adaptive_mmco_func) (GstVaapiDecoderH264 * + decoder, GstVaapiPictureH264 * picture, + GstH264RefPicMarking * ref_pic_marking); - static const exec_ref_pic_marking_adaptive_mmco_func mmco_funcs[] = { - NULL, - exec_ref_pic_marking_adaptive_mmco_1, - exec_ref_pic_marking_adaptive_mmco_2, - exec_ref_pic_marking_adaptive_mmco_3, - exec_ref_pic_marking_adaptive_mmco_4, - exec_ref_pic_marking_adaptive_mmco_5, - exec_ref_pic_marking_adaptive_mmco_6, - }; + static const exec_ref_pic_marking_adaptive_mmco_func mmco_funcs[] = { + NULL, + exec_ref_pic_marking_adaptive_mmco_1, + exec_ref_pic_marking_adaptive_mmco_2, + exec_ref_pic_marking_adaptive_mmco_3, + exec_ref_pic_marking_adaptive_mmco_4, + exec_ref_pic_marking_adaptive_mmco_5, + exec_ref_pic_marking_adaptive_mmco_6, + }; - GST_DEBUG("reference picture marking process (adaptive memory control)"); + GST_DEBUG ("reference picture marking process (adaptive memory control)"); - for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) { - GstH264RefPicMarking * const ref_pic_marking = - &dec_ref_pic_marking->ref_pic_marking[i]; + for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) { + GstH264RefPicMarking *const ref_pic_marking = + &dec_ref_pic_marking->ref_pic_marking[i]; - const guint mmco = ref_pic_marking->memory_management_control_operation; - if (mmco < G_N_ELEMENTS(mmco_funcs) && mmco_funcs[mmco]) - mmco_funcs[mmco](decoder, picture, ref_pic_marking); - else { - GST_ERROR("unhandled MMCO %u", mmco); - return FALSE; - } + const guint mmco = ref_pic_marking->memory_management_control_operation; + if (mmco < G_N_ELEMENTS (mmco_funcs) && mmco_funcs[mmco]) + mmco_funcs[mmco] (decoder, picture, ref_pic_marking); + else { + GST_ERROR ("unhandled MMCO %u", mmco); + return FALSE; } - return TRUE; + } + return TRUE; } /* 8.2.5 - Execute reference picture marking process */ static gboolean -exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +exec_ref_pic_marking (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; + GstVaapiDecoderH264Private *const priv = &decoder->priv; - priv->prev_pic_reference = GST_VAAPI_PICTURE_IS_REFERENCE(picture); - priv->prev_pic_has_mmco5 = FALSE; - priv->prev_pic_structure = picture->structure; + priv->prev_pic_reference = GST_VAAPI_PICTURE_IS_REFERENCE (picture); + priv->prev_pic_has_mmco5 = FALSE; + priv->prev_pic_structure = picture->structure; - if (GST_VAAPI_PICTURE_IS_INTER_VIEW(picture)) - g_ptr_array_add(priv->inter_views, gst_vaapi_picture_ref(picture)); + if (GST_VAAPI_PICTURE_IS_INTER_VIEW (picture)) + g_ptr_array_add (priv->inter_views, gst_vaapi_picture_ref (picture)); - if (!priv->prev_pic_reference) - return TRUE; - - if (!GST_VAAPI_PICTURE_IS_IDR(picture)) { - GstH264DecRefPicMarking * const dec_ref_pic_marking = - &picture->last_slice_hdr->dec_ref_pic_marking; - if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) { - if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking)) - return FALSE; - } - else { - if (!exec_ref_pic_marking_sliding_window(decoder)) - return FALSE; - } - } + if (!priv->prev_pic_reference) return TRUE; + + if (!GST_VAAPI_PICTURE_IS_IDR (picture)) { + GstH264DecRefPicMarking *const dec_ref_pic_marking = + &picture->last_slice_hdr->dec_ref_pic_marking; + if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) { + if (!exec_ref_pic_marking_adaptive (decoder, picture, + dec_ref_pic_marking)) + return FALSE; + } else { + if (!exec_ref_pic_marking_sliding_window (decoder)) + return FALSE; + } + } + return TRUE; } static void -vaapi_init_picture(VAPictureH264 *pic) +vaapi_init_picture (VAPictureH264 * pic) { - pic->picture_id = VA_INVALID_ID; - pic->frame_idx = 0; - pic->flags = VA_PICTURE_H264_INVALID; - pic->TopFieldOrderCnt = 0; - pic->BottomFieldOrderCnt = 0; + pic->picture_id = VA_INVALID_ID; + pic->frame_idx = 0; + pic->flags = VA_PICTURE_H264_INVALID; + pic->TopFieldOrderCnt = 0; + pic->BottomFieldOrderCnt = 0; } static void -vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture, +vaapi_fill_picture (VAPictureH264 * pic, GstVaapiPictureH264 * picture, guint picture_structure) { - if (!picture_structure) - picture_structure = picture->structure; + if (!picture_structure) + picture_structure = picture->structure; - pic->picture_id = picture->base.surface_id; - pic->flags = 0; + pic->picture_id = picture->base.surface_id; + pic->flags = 0; - if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) { - pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE; - pic->frame_idx = picture->long_term_frame_idx; - } - else { - if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) - pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE; - pic->frame_idx = picture->frame_num; - } + if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (picture)) { + pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE; + pic->frame_idx = picture->long_term_frame_idx; + } else { + if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE (picture)) + pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE; + pic->frame_idx = picture->frame_num; + } - switch (picture_structure) { + switch (picture_structure) { case GST_VAAPI_PICTURE_STRUCTURE_FRAME: - pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD]; - pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD]; - break; + pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD]; + pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD]; + break; case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: - pic->flags |= VA_PICTURE_H264_TOP_FIELD; - pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD]; - pic->BottomFieldOrderCnt = 0; - break; + pic->flags |= VA_PICTURE_H264_TOP_FIELD; + pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD]; + pic->BottomFieldOrderCnt = 0; + break; case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: - pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD; - pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD]; - pic->TopFieldOrderCnt = 0; - break; - } + pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD; + pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD]; + pic->TopFieldOrderCnt = 0; + break; + } } static void -vaapi_fill_picture_for_RefPicListX(VAPictureH264 *pic, - GstVaapiPictureH264 *picture) +vaapi_fill_picture_for_RefPicListX (VAPictureH264 * pic, + GstVaapiPictureH264 * picture) { - vaapi_fill_picture(pic, picture, 0); + vaapi_fill_picture (pic, picture, 0); - /* H.8.4 - MVC inter prediction and inter-view prediction process */ - if (GST_VAAPI_PICTURE_IS_INTER_VIEW(picture)) { - /* The inter-view reference components and inter-view only - reference components that are included in the reference - picture lists are considered as not being marked as "used for - short-term reference" or "used for long-term reference" */ - pic->flags &= ~(VA_PICTURE_H264_SHORT_TERM_REFERENCE| - VA_PICTURE_H264_LONG_TERM_REFERENCE); - } + /* H.8.4 - MVC inter prediction and inter-view prediction process */ + if (GST_VAAPI_PICTURE_IS_INTER_VIEW (picture)) { + /* The inter-view reference components and inter-view only + reference components that are included in the reference + picture lists are considered as not being marked as "used for + short-term reference" or "used for long-term reference" */ + pic->flags &= ~(VA_PICTURE_H264_SHORT_TERM_REFERENCE | + VA_PICTURE_H264_LONG_TERM_REFERENCE); + } } static gboolean -fill_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) +fill_picture (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiPicture * const base_picture = &picture->base; - GstH264PPS * const pps = get_pps(decoder); - GstH264SPS * const sps = get_sps(decoder); - VAPictureParameterBufferH264 * const pic_param = base_picture->param; - guint i, n; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiPicture *const base_picture = &picture->base; + GstH264PPS *const pps = get_pps (decoder); + GstH264SPS *const sps = get_sps (decoder); + VAPictureParameterBufferH264 *const pic_param = base_picture->param; + guint i, n; - /* Fill in VAPictureParameterBufferH264 */ - vaapi_fill_picture(&pic_param->CurrPic, picture, 0); + /* Fill in VAPictureParameterBufferH264 */ + vaapi_fill_picture (&pic_param->CurrPic, picture, 0); - for (i = 0, n = 0; i < priv->dpb_count; i++) { - GstVaapiFrameStore * const fs = priv->dpb[i]; - if ((gst_vaapi_frame_store_has_reference(fs) && - fs->view_id == picture->base.view_id) || - (gst_vaapi_frame_store_has_inter_view(fs) && - is_inter_view_reference_for_picture(decoder, fs->view_id, picture))) - vaapi_fill_picture(&pic_param->ReferenceFrames[n++], - fs->buffers[0], fs->structure); - if (n >= G_N_ELEMENTS(pic_param->ReferenceFrames)) - break; - } - for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++) - vaapi_init_picture(&pic_param->ReferenceFrames[n]); + for (i = 0, n = 0; i < priv->dpb_count; i++) { + GstVaapiFrameStore *const fs = priv->dpb[i]; + if ((gst_vaapi_frame_store_has_reference (fs) && + fs->view_id == picture->base.view_id) || + (gst_vaapi_frame_store_has_inter_view (fs) && + is_inter_view_reference_for_picture (decoder, fs->view_id, + picture))) + vaapi_fill_picture (&pic_param->ReferenceFrames[n++], fs->buffers[0], + fs->structure); + if (n >= G_N_ELEMENTS (pic_param->ReferenceFrames)) + break; + } + for (; n < G_N_ELEMENTS (pic_param->ReferenceFrames); n++) + vaapi_init_picture (&pic_param->ReferenceFrames[n]); #define COPY_FIELD(s, f) \ pic_param->f = (s)->f @@ -3788,62 +3696,65 @@ fill_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) #define COPY_BFM(a, s, f) \ pic_param->a.bits.f = (s)->f - pic_param->picture_width_in_mbs_minus1 = priv->mb_width - 1; - pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1; - pic_param->frame_num = priv->frame_num; + pic_param->picture_width_in_mbs_minus1 = priv->mb_width - 1; + pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1; + pic_param->frame_num = priv->frame_num; - COPY_FIELD(sps, bit_depth_luma_minus8); - COPY_FIELD(sps, bit_depth_chroma_minus8); - COPY_FIELD(sps, num_ref_frames); - COPY_FIELD(pps, num_slice_groups_minus1); - COPY_FIELD(pps, slice_group_map_type); - COPY_FIELD(pps, slice_group_change_rate_minus1); - COPY_FIELD(pps, pic_init_qp_minus26); - COPY_FIELD(pps, pic_init_qs_minus26); - COPY_FIELD(pps, chroma_qp_index_offset); - COPY_FIELD(pps, second_chroma_qp_index_offset); + COPY_FIELD (sps, bit_depth_luma_minus8); + COPY_FIELD (sps, bit_depth_chroma_minus8); + COPY_FIELD (sps, num_ref_frames); + COPY_FIELD (pps, num_slice_groups_minus1); + COPY_FIELD (pps, slice_group_map_type); + COPY_FIELD (pps, slice_group_change_rate_minus1); + COPY_FIELD (pps, pic_init_qp_minus26); + COPY_FIELD (pps, pic_init_qs_minus26); + COPY_FIELD (pps, chroma_qp_index_offset); + COPY_FIELD (pps, second_chroma_qp_index_offset); - pic_param->seq_fields.value = 0; /* reset all bits */ - pic_param->seq_fields.bits.residual_colour_transform_flag = sps->separate_colour_plane_flag; - pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */ + pic_param->seq_fields.value = 0; /* reset all bits */ + pic_param->seq_fields.bits.residual_colour_transform_flag = + sps->separate_colour_plane_flag; + pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */ - COPY_BFM(seq_fields, sps, chroma_format_idc); - COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag); - COPY_BFM(seq_fields, sps, frame_mbs_only_flag); - COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag); - COPY_BFM(seq_fields, sps, direct_8x8_inference_flag); - COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4); - COPY_BFM(seq_fields, sps, pic_order_cnt_type); - COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4); - COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag); + COPY_BFM (seq_fields, sps, chroma_format_idc); + COPY_BFM (seq_fields, sps, gaps_in_frame_num_value_allowed_flag); + COPY_BFM (seq_fields, sps, frame_mbs_only_flag); + COPY_BFM (seq_fields, sps, mb_adaptive_frame_field_flag); + COPY_BFM (seq_fields, sps, direct_8x8_inference_flag); + COPY_BFM (seq_fields, sps, log2_max_frame_num_minus4); + COPY_BFM (seq_fields, sps, pic_order_cnt_type); + COPY_BFM (seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4); + COPY_BFM (seq_fields, sps, delta_pic_order_always_zero_flag); - pic_param->pic_fields.value = 0; /* reset all bits */ - pic_param->pic_fields.bits.field_pic_flag = GST_VAAPI_PICTURE_IS_INTERLACED(picture); - pic_param->pic_fields.bits.reference_pic_flag = GST_VAAPI_PICTURE_IS_REFERENCE(picture); + pic_param->pic_fields.value = 0; /* reset all bits */ + pic_param->pic_fields.bits.field_pic_flag = + GST_VAAPI_PICTURE_IS_INTERLACED (picture); + pic_param->pic_fields.bits.reference_pic_flag = + GST_VAAPI_PICTURE_IS_REFERENCE (picture); - COPY_BFM(pic_fields, pps, entropy_coding_mode_flag); - COPY_BFM(pic_fields, pps, weighted_pred_flag); - COPY_BFM(pic_fields, pps, weighted_bipred_idc); - COPY_BFM(pic_fields, pps, transform_8x8_mode_flag); - COPY_BFM(pic_fields, pps, constrained_intra_pred_flag); - COPY_BFM(pic_fields, pps, pic_order_present_flag); - COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag); - COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag); - return TRUE; + COPY_BFM (pic_fields, pps, entropy_coding_mode_flag); + COPY_BFM (pic_fields, pps, weighted_pred_flag); + COPY_BFM (pic_fields, pps, weighted_bipred_idc); + COPY_BFM (pic_fields, pps, transform_8x8_mode_flag); + COPY_BFM (pic_fields, pps, constrained_intra_pred_flag); + COPY_BFM (pic_fields, pps, pic_order_present_flag); + COPY_BFM (pic_fields, pps, deblocking_filter_control_present_flag); + COPY_BFM (pic_fields, pps, redundant_pic_cnt_present_flag); + return TRUE; } /* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */ static gboolean -is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) +is_new_picture (GstVaapiParserInfoH264 * pi, GstVaapiParserInfoH264 * prev_pi) { - GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; - GstH264PPS * const pps = slice_hdr->pps; - GstH264SPS * const sps = pps->sequence; - GstH264SliceHdr *prev_slice_hdr; + GstH264SliceHdr *const slice_hdr = &pi->data.slice_hdr; + GstH264PPS *const pps = slice_hdr->pps; + GstH264SPS *const sps = pps->sequence; + GstH264SliceHdr *prev_slice_hdr; - if (!prev_pi) - return TRUE; - prev_slice_hdr = &prev_pi->data.slice_hdr; + if (!prev_pi) + return TRUE; + prev_slice_hdr = &prev_pi->data.slice_hdr; #define CHECK_EXPR(expr, field_name) do { \ if (!(expr)) { \ @@ -3855,868 +3766,859 @@ is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) #define CHECK_VALUE(new_slice_hdr, old_slice_hdr, field) \ CHECK_EXPR(((new_slice_hdr)->field == (old_slice_hdr)->field), #field) - /* view_id differs in value and VOIdx of current slice_hdr is less - than the VOIdx of the prev_slice_hdr */ - CHECK_VALUE(pi, prev_pi, view_id); + /* view_id differs in value and VOIdx of current slice_hdr is less + than the VOIdx of the prev_slice_hdr */ + CHECK_VALUE (pi, prev_pi, view_id); - /* frame_num differs in value, regardless of inferred values to 0 */ - CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num); + /* frame_num differs in value, regardless of inferred values to 0 */ + CHECK_VALUE (slice_hdr, prev_slice_hdr, frame_num); - /* pic_parameter_set_id differs in value */ - CHECK_VALUE(slice_hdr, prev_slice_hdr, pps); + /* pic_parameter_set_id differs in value */ + CHECK_VALUE (slice_hdr, prev_slice_hdr, pps); - /* field_pic_flag differs in value */ - CHECK_VALUE(slice_hdr, prev_slice_hdr, field_pic_flag); + /* field_pic_flag differs in value */ + CHECK_VALUE (slice_hdr, prev_slice_hdr, field_pic_flag); - /* bottom_field_flag is present in both and differs in value */ - if (slice_hdr->field_pic_flag && prev_slice_hdr->field_pic_flag) - CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag); + /* bottom_field_flag is present in both and differs in value */ + if (slice_hdr->field_pic_flag && prev_slice_hdr->field_pic_flag) + CHECK_VALUE (slice_hdr, prev_slice_hdr, bottom_field_flag); - /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */ - CHECK_EXPR((pi->nalu.ref_idc != 0) == - (prev_pi->nalu.ref_idc != 0), "nal_ref_idc"); + /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */ + CHECK_EXPR ((pi->nalu.ref_idc != 0) == + (prev_pi->nalu.ref_idc != 0), "nal_ref_idc"); - /* POC type is 0 for both and either pic_order_cnt_lsb differs in - value or delta_pic_order_cnt_bottom differs in value */ - if (sps->pic_order_cnt_type == 0) { - CHECK_VALUE(slice_hdr, prev_slice_hdr, pic_order_cnt_lsb); - if (pps->pic_order_present_flag && !slice_hdr->field_pic_flag) - CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt_bottom); - } + /* POC type is 0 for both and either pic_order_cnt_lsb differs in + value or delta_pic_order_cnt_bottom differs in value */ + if (sps->pic_order_cnt_type == 0) { + CHECK_VALUE (slice_hdr, prev_slice_hdr, pic_order_cnt_lsb); + if (pps->pic_order_present_flag && !slice_hdr->field_pic_flag) + CHECK_VALUE (slice_hdr, prev_slice_hdr, delta_pic_order_cnt_bottom); + } - /* POC type is 1 for both and either delta_pic_order_cnt[0] - differs in value or delta_pic_order_cnt[1] differs in value */ - else if (sps->pic_order_cnt_type == 1) { - CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[0]); - CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[1]); - } + /* POC type is 1 for both and either delta_pic_order_cnt[0] + differs in value or delta_pic_order_cnt[1] differs in value */ + else if (sps->pic_order_cnt_type == 1) { + CHECK_VALUE (slice_hdr, prev_slice_hdr, delta_pic_order_cnt[0]); + CHECK_VALUE (slice_hdr, prev_slice_hdr, delta_pic_order_cnt[1]); + } - /* IdrPicFlag differs in value */ - CHECK_VALUE(&pi->nalu, &prev_pi->nalu, idr_pic_flag); + /* IdrPicFlag differs in value */ + CHECK_VALUE (&pi->nalu, &prev_pi->nalu, idr_pic_flag); - /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */ - if (pi->nalu.idr_pic_flag) - CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id); + /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */ + if (pi->nalu.idr_pic_flag) + CHECK_VALUE (slice_hdr, prev_slice_hdr, idr_pic_id); #undef CHECK_EXPR #undef CHECK_VALUE - return FALSE; + return FALSE; } /* Detection of a new access unit, assuming we are already in presence of a new picture */ static inline gboolean -is_new_access_unit(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi) +is_new_access_unit (GstVaapiParserInfoH264 * pi, + GstVaapiParserInfoH264 * prev_pi) { - if (!prev_pi || prev_pi->view_id == pi->view_id) - return TRUE; - return pi->voc < prev_pi->voc; + if (!prev_pi || prev_pi->view_id == pi->view_id) + return TRUE; + return pi->voc < prev_pi->voc; } /* Determines whether the supplied picture has the same field parity than a picture specified through the other slice header */ static inline gboolean -same_field_parity(GstVaapiPictureH264 *field, GstH264SliceHdr *slice_hdr) +same_field_parity (GstVaapiPictureH264 * field, GstH264SliceHdr * slice_hdr) { - g_return_val_if_fail(GST_VAAPI_PICTURE_IS_INTERLACED(field), FALSE); + g_return_val_if_fail (GST_VAAPI_PICTURE_IS_INTERLACED (field), FALSE); - return ((field->base.structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) ^ - slice_hdr->bottom_field_flag) == 0; + return ((field->base.structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) ^ + slice_hdr->bottom_field_flag) == 0; } /* Finds the first field picture corresponding to the supplied picture */ static GstVaapiPictureH264 * -find_first_field(GstVaapiDecoderH264 *decoder, GstVaapiParserInfoH264 *pi, +find_first_field (GstVaapiDecoderH264 * decoder, GstVaapiParserInfoH264 * pi, gboolean fill_gaps) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; - GstVaapiFrameStore *fs; - GstVaapiPictureH264 *f0, *f1; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstH264SliceHdr *const slice_hdr = &pi->data.slice_hdr; + GstVaapiFrameStore *fs; + GstVaapiPictureH264 *f0, *f1; - fs = priv->prev_frames[pi->voc]; - if (!fs) - return NULL; + fs = priv->prev_frames[pi->voc]; + if (!fs) + return NULL; - f0 = fs->buffers[0]; - if (!slice_hdr->field_pic_flag) { - if (fill_gaps && !gst_vaapi_frame_store_has_frame(fs)) - fill_picture_other_field_gap(decoder, f0); - return NULL; - } - - /* At this point, the current frame is known to be interlaced */ - if (gst_vaapi_frame_store_has_frame(fs)) { - f1 = NULL; - if (fill_gaps && !same_field_parity(f0, slice_hdr)) - f1 = fill_picture_first_field_gap(decoder, f0); - return f1; - } - - /* At this point, the previous frame is interlaced and contains a - single field */ - if (f0->frame_num == slice_hdr->frame_num) { - f1 = f0; - if (fill_gaps && same_field_parity(f0, slice_hdr)) { - fill_picture_other_field_gap(decoder, f0); - f1 = NULL; - } - return f1; - } + f0 = fs->buffers[0]; + if (!slice_hdr->field_pic_flag) { + if (fill_gaps && !gst_vaapi_frame_store_has_frame (fs)) + fill_picture_other_field_gap (decoder, f0); + return NULL; + } + /* At this point, the current frame is known to be interlaced */ + if (gst_vaapi_frame_store_has_frame (fs)) { f1 = NULL; - if (fill_gaps) { - fill_picture_other_field_gap(decoder, f0); - if (!same_field_parity(f0, slice_hdr)) - f1 = fill_picture_first_field_gap(decoder, f0); + if (fill_gaps && !same_field_parity (f0, slice_hdr)) + f1 = fill_picture_first_field_gap (decoder, f0); + return f1; + } + + /* At this point, the previous frame is interlaced and contains a + single field */ + if (f0->frame_num == slice_hdr->frame_num) { + f1 = f0; + if (fill_gaps && same_field_parity (f0, slice_hdr)) { + fill_picture_other_field_gap (decoder, f0); + f1 = NULL; } return f1; + } + + f1 = NULL; + if (fill_gaps) { + fill_picture_other_field_gap (decoder, f0); + if (!same_field_parity (f0, slice_hdr)) + f1 = fill_picture_first_field_gap (decoder, f0); + } + return f1; } static GstVaapiDecoderStatus -decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +decode_picture (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; - GstH264PPS * const pps = ensure_pps(decoder, slice_hdr->pps); - GstH264SPS * const sps = ensure_sps(decoder, slice_hdr->pps->sequence); - GstVaapiPictureH264 *picture, *first_field; - GstVaapiDecoderStatus status; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + GstH264SliceHdr *const slice_hdr = &pi->data.slice_hdr; + GstH264PPS *const pps = ensure_pps (decoder, slice_hdr->pps); + GstH264SPS *const sps = ensure_sps (decoder, slice_hdr->pps->sequence); + GstVaapiPictureH264 *picture, *first_field; + GstVaapiDecoderStatus status; - g_return_val_if_fail(pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); - g_return_val_if_fail(sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); + g_return_val_if_fail (pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); + g_return_val_if_fail (sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); - /* Only decode base stream for MVC */ - switch (sps->profile_idc) { + /* Only decode base stream for MVC */ + switch (sps->profile_idc) { case GST_H264_PROFILE_MULTIVIEW_HIGH: case GST_H264_PROFILE_STEREO_HIGH: - break; + break; + } + + status = ensure_context (decoder, sps); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + priv->decoder_state = 0; + gst_vaapi_picture_replace (&priv->missing_picture, NULL); + + first_field = find_first_field (decoder, pi, TRUE); + if (first_field) { + /* Re-use current picture where the first field was decoded */ + picture = gst_vaapi_picture_h264_new_field (first_field); + if (!picture) { + GST_ERROR ("failed to allocate field picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } - - status = ensure_context(decoder, sps); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - - priv->decoder_state = 0; - gst_vaapi_picture_replace(&priv->missing_picture, NULL); - - first_field = find_first_field(decoder, pi, TRUE); - if (first_field) { - /* Re-use current picture where the first field was decoded */ - picture = gst_vaapi_picture_h264_new_field(first_field); - if (!picture) { - GST_ERROR("failed to allocate field picture"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } + } else { + /* Create new picture */ + picture = gst_vaapi_picture_h264_new (decoder); + if (!picture) { + GST_ERROR ("failed to allocate picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } - else { - /* Create new picture */ - picture = gst_vaapi_picture_h264_new(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); + } + gst_vaapi_picture_replace (&priv->current_picture, picture); + gst_vaapi_picture_unref (picture); - /* Clear inter-view references list if this is the primary coded - picture of the current access unit */ - if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_START) - g_ptr_array_set_size(priv->inter_views, 0); + /* Clear inter-view references list if this is the primary coded + picture of the current access unit */ + if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_START) + g_ptr_array_set_size (priv->inter_views, 0); - /* Update cropping rectangle */ - if (sps->frame_cropping_flag) { - GstVaapiRectangle crop_rect; - crop_rect.x = sps->crop_rect_x; - crop_rect.y = sps->crop_rect_y; - crop_rect.width = sps->crop_rect_width; - crop_rect.height = sps->crop_rect_height; - gst_vaapi_picture_set_crop_rect(&picture->base, &crop_rect); - } + /* Update cropping rectangle */ + if (sps->frame_cropping_flag) { + GstVaapiRectangle crop_rect; + crop_rect.x = sps->crop_rect_x; + crop_rect.y = sps->crop_rect_y; + crop_rect.width = sps->crop_rect_width; + crop_rect.height = sps->crop_rect_height; + gst_vaapi_picture_set_crop_rect (&picture->base, &crop_rect); + } - status = ensure_quant_matrix(decoder, picture); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_ERROR("failed to reset quantizer matrix"); - return status; - } + status = ensure_quant_matrix (decoder, picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_ERROR ("failed to reset quantizer matrix"); + return status; + } - if (!init_picture(decoder, picture, pi)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - if (!fill_picture(decoder, picture)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + if (!init_picture (decoder, picture, pi)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + if (!fill_picture (decoder, picture)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - priv->decoder_state = pi->state; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + priv->decoder_state = pi->state; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static inline guint -get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, guint nal_header_bytes) +get_slice_data_bit_offset (GstH264SliceHdr * slice_hdr, guint nal_header_bytes) { - guint epb_count; + guint epb_count; - epb_count = slice_hdr->n_emulation_prevention_bytes; - return 8 * nal_header_bytes + slice_hdr->header_size - epb_count * 8; + epb_count = slice_hdr->n_emulation_prevention_bytes; + return 8 * nal_header_bytes + slice_hdr->header_size - epb_count * 8; } static gboolean -fill_pred_weight_table(GstVaapiDecoderH264 *decoder, - GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr) +fill_pred_weight_table (GstVaapiDecoderH264 * decoder, + GstVaapiSlice * slice, GstH264SliceHdr * slice_hdr) { - VASliceParameterBufferH264 * const slice_param = slice->param; - GstH264PPS * const pps = get_pps(decoder); - GstH264SPS * const sps = get_sps(decoder); - GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table; - guint num_weight_tables = 0; - gint i, j; + VASliceParameterBufferH264 *const slice_param = slice->param; + GstH264PPS *const pps = get_pps (decoder); + GstH264SPS *const sps = get_sps (decoder); + GstH264PredWeightTable *const w = &slice_hdr->pred_weight_table; + guint num_weight_tables = 0; + gint i, j; - if (pps->weighted_pred_flag && - (GST_H264_IS_P_SLICE(slice_hdr) || GST_H264_IS_SP_SLICE(slice_hdr))) - num_weight_tables = 1; - else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE(slice_hdr)) - num_weight_tables = 2; - else - num_weight_tables = 0; + if (pps->weighted_pred_flag && + (GST_H264_IS_P_SLICE (slice_hdr) || GST_H264_IS_SP_SLICE (slice_hdr))) + num_weight_tables = 1; + else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE (slice_hdr)) + num_weight_tables = 2; + else + num_weight_tables = 0; - slice_param->luma_log2_weight_denom = 0; - slice_param->chroma_log2_weight_denom = 0; - slice_param->luma_weight_l0_flag = 0; - slice_param->chroma_weight_l0_flag = 0; - slice_param->luma_weight_l1_flag = 0; - slice_param->chroma_weight_l1_flag = 0; + slice_param->luma_log2_weight_denom = 0; + slice_param->chroma_log2_weight_denom = 0; + slice_param->luma_weight_l0_flag = 0; + slice_param->chroma_weight_l0_flag = 0; + slice_param->luma_weight_l1_flag = 0; + slice_param->chroma_weight_l1_flag = 0; - if (num_weight_tables < 1) - return TRUE; + if (num_weight_tables < 1) + return TRUE; - slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom; - slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom; + slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom; + slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom; - slice_param->luma_weight_l0_flag = 1; + slice_param->luma_weight_l0_flag = 1; + for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { + slice_param->luma_weight_l0[i] = w->luma_weight_l0[i]; + slice_param->luma_offset_l0[i] = w->luma_offset_l0[i]; + } + + slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0; + if (slice_param->chroma_weight_l0_flag) { for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { - slice_param->luma_weight_l0[i] = w->luma_weight_l0[i]; - slice_param->luma_offset_l0[i] = w->luma_offset_l0[i]; + for (j = 0; j < 2; j++) { + slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j]; + slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j]; + } } + } - slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0; - if (slice_param->chroma_weight_l0_flag) { - for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { - for (j = 0; j < 2; j++) { - slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j]; - slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j]; - } - } - } + if (num_weight_tables < 2) + return TRUE; - if (num_weight_tables < 2) - return TRUE; + slice_param->luma_weight_l1_flag = 1; + for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { + slice_param->luma_weight_l1[i] = w->luma_weight_l1[i]; + slice_param->luma_offset_l1[i] = w->luma_offset_l1[i]; + } - slice_param->luma_weight_l1_flag = 1; + slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0; + if (slice_param->chroma_weight_l1_flag) { for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { - slice_param->luma_weight_l1[i] = w->luma_weight_l1[i]; - slice_param->luma_offset_l1[i] = w->luma_offset_l1[i]; + for (j = 0; j < 2; j++) { + slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j]; + slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j]; + } } - - slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0; - if (slice_param->chroma_weight_l1_flag) { - for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { - for (j = 0; j < 2; j++) { - slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j]; - slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j]; - } - } - } - return TRUE; + } + return TRUE; } static gboolean -fill_RefPicList(GstVaapiDecoderH264 *decoder, - GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr) +fill_RefPicList (GstVaapiDecoderH264 * decoder, + GstVaapiSlice * slice, GstH264SliceHdr * slice_hdr) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - VASliceParameterBufferH264 * const slice_param = slice->param; - guint i, num_ref_lists = 0; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + VASliceParameterBufferH264 *const slice_param = slice->param; + guint i, num_ref_lists = 0; - slice_param->num_ref_idx_l0_active_minus1 = 0; - slice_param->num_ref_idx_l1_active_minus1 = 0; + slice_param->num_ref_idx_l0_active_minus1 = 0; + slice_param->num_ref_idx_l1_active_minus1 = 0; - if (GST_H264_IS_B_SLICE(slice_hdr)) - num_ref_lists = 2; - else if (GST_H264_IS_I_SLICE(slice_hdr)) - num_ref_lists = 0; - else - num_ref_lists = 1; + if (GST_H264_IS_B_SLICE (slice_hdr)) + num_ref_lists = 2; + else if (GST_H264_IS_I_SLICE (slice_hdr)) + num_ref_lists = 0; + else + num_ref_lists = 1; - if (num_ref_lists < 1) - return TRUE; - - slice_param->num_ref_idx_l0_active_minus1 = - slice_hdr->num_ref_idx_l0_active_minus1; - - for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++) - vaapi_fill_picture_for_RefPicListX(&slice_param->RefPicList0[i], - priv->RefPicList0[i]); - for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++) - vaapi_init_picture(&slice_param->RefPicList0[i]); - - if (num_ref_lists < 2) - return TRUE; - - slice_param->num_ref_idx_l1_active_minus1 = - slice_hdr->num_ref_idx_l1_active_minus1; - - for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++) - vaapi_fill_picture_for_RefPicListX(&slice_param->RefPicList1[i], - priv->RefPicList1[i]); - for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++) - vaapi_init_picture(&slice_param->RefPicList1[i]); + if (num_ref_lists < 1) return TRUE; + + slice_param->num_ref_idx_l0_active_minus1 = + slice_hdr->num_ref_idx_l0_active_minus1; + + for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++) + vaapi_fill_picture_for_RefPicListX (&slice_param->RefPicList0[i], + priv->RefPicList0[i]); + for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++) + vaapi_init_picture (&slice_param->RefPicList0[i]); + + if (num_ref_lists < 2) + return TRUE; + + slice_param->num_ref_idx_l1_active_minus1 = + slice_hdr->num_ref_idx_l1_active_minus1; + + for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++) + vaapi_fill_picture_for_RefPicListX (&slice_param->RefPicList1[i], + priv->RefPicList1[i]); + for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++) + vaapi_init_picture (&slice_param->RefPicList1[i]); + return TRUE; } static gboolean -fill_slice(GstVaapiDecoderH264 *decoder, - GstVaapiSlice *slice, GstVaapiParserInfoH264 *pi) +fill_slice (GstVaapiDecoderH264 * decoder, + GstVaapiSlice * slice, GstVaapiParserInfoH264 * pi) { - VASliceParameterBufferH264 * const slice_param = slice->param; - GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; + VASliceParameterBufferH264 *const slice_param = slice->param; + GstH264SliceHdr *const slice_hdr = &pi->data.slice_hdr; - /* Fill in VASliceParameterBufferH264 */ - slice_param->slice_data_bit_offset = - get_slice_data_bit_offset(slice_hdr, pi->nalu.header_bytes); - slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice; - slice_param->slice_type = slice_hdr->type % 5; - slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag; - slice_param->cabac_init_idc = slice_hdr->cabac_init_idc; - slice_param->slice_qp_delta = slice_hdr->slice_qp_delta; - slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc; - slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2; - slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2; + /* Fill in VASliceParameterBufferH264 */ + slice_param->slice_data_bit_offset = + get_slice_data_bit_offset (slice_hdr, pi->nalu.header_bytes); + slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice; + slice_param->slice_type = slice_hdr->type % 5; + slice_param->direct_spatial_mv_pred_flag = + slice_hdr->direct_spatial_mv_pred_flag; + slice_param->cabac_init_idc = slice_hdr->cabac_init_idc; + slice_param->slice_qp_delta = slice_hdr->slice_qp_delta; + slice_param->disable_deblocking_filter_idc = + slice_hdr->disable_deblocking_filter_idc; + slice_param->slice_alpha_c0_offset_div2 = + slice_hdr->slice_alpha_c0_offset_div2; + slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2; - if (!fill_RefPicList(decoder, slice, slice_hdr)) - return FALSE; - if (!fill_pred_weight_table(decoder, slice, slice_hdr)) - return FALSE; - return TRUE; + if (!fill_RefPicList (decoder, slice, slice_hdr)) + return FALSE; + if (!fill_pred_weight_table (decoder, slice, slice_hdr)) + return FALSE; + return TRUE; } static GstVaapiDecoderStatus -decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +decode_slice (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GstVaapiPictureH264 * const picture = priv->current_picture; - GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr; - GstVaapiSlice *slice; - GstBuffer * const buffer = - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; - GstMapInfo map_info; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + GstVaapiPictureH264 *const picture = priv->current_picture; + GstH264SliceHdr *const slice_hdr = &pi->data.slice_hdr; + GstVaapiSlice *slice; + GstBuffer *const buffer = + GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer; + GstMapInfo map_info; - GST_DEBUG("slice (%u bytes)", pi->nalu.size); + GST_DEBUG ("slice (%u bytes)", pi->nalu.size); - if (!is_valid_state(pi->state, - GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS)) { - GST_WARNING("failed to receive enough headers to decode slice"); - return GST_VAAPI_DECODER_STATUS_SUCCESS; - } - - if (!ensure_pps(decoder, slice_hdr->pps)) { - GST_ERROR("failed to activate PPS"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - - if (!ensure_sps(decoder, slice_hdr->pps->sequence)) { - GST_ERROR("failed to activate SPS"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - - if (!gst_buffer_map(buffer, &map_info, GST_MAP_READ)) { - GST_ERROR("failed to map buffer"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - - /* Check wether this is the first/last slice in the current access unit */ - if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_START) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_AU_START); - if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_AU_END); - - slice = GST_VAAPI_SLICE_NEW(H264, decoder, - (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size); - gst_buffer_unmap(buffer, &map_info); - if (!slice) { - GST_ERROR("failed to allocate slice"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - - init_picture_refs(decoder, picture, slice_hdr); - if (!fill_slice(decoder, slice, pi)) { - 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); - picture->last_slice_hdr = slice_hdr; + if (!is_valid_state (pi->state, GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS)) { + GST_WARNING ("failed to receive enough headers to decode slice"); return GST_VAAPI_DECODER_STATUS_SUCCESS; + } + + if (!ensure_pps (decoder, slice_hdr->pps)) { + GST_ERROR ("failed to activate PPS"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!ensure_sps (decoder, slice_hdr->pps->sequence)) { + GST_ERROR ("failed to activate SPS"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) { + GST_ERROR ("failed to map buffer"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + /* Check wether this is the first/last slice in the current access unit */ + if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_START) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_START); + if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_END); + + slice = GST_VAAPI_SLICE_NEW (H264, decoder, + (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size); + gst_buffer_unmap (buffer, &map_info); + if (!slice) { + GST_ERROR ("failed to allocate slice"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + init_picture_refs (decoder, picture, slice_hdr); + if (!fill_slice (decoder, slice, pi)) { + 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); + picture->last_slice_hdr = slice_hdr; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static inline gint -scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) +scan_for_start_code (GstAdapter * adapter, guint ofs, guint size, guint32 * scp) { - return (gint)gst_adapter_masked_scan_uint32_peek(adapter, - 0xffffff00, 0x00000100, - ofs, size, - scp); + return (gint) gst_adapter_masked_scan_uint32_peek (adapter, + 0xffffff00, 0x00000100, ofs, size, scp); } static GstVaapiDecoderStatus -decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) +decode_unit (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserInfoH264 * const pi = unit->parsed_info; - GstVaapiDecoderStatus status; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserInfoH264 *const pi = unit->parsed_info; + GstVaapiDecoderStatus status; - priv->decoder_state |= pi->state; - switch (pi->nalu.type) { + priv->decoder_state |= pi->state; + switch (pi->nalu.type) { case GST_H264_NAL_SPS: - status = decode_sps(decoder, unit); - break; + status = decode_sps (decoder, unit); + break; case GST_H264_NAL_SUBSET_SPS: - status = decode_subset_sps(decoder, unit); - break; + status = decode_subset_sps (decoder, unit); + break; case GST_H264_NAL_PPS: - status = decode_pps(decoder, unit); - break; + status = decode_pps (decoder, unit); + break; case GST_H264_NAL_SLICE_EXT: case GST_H264_NAL_SLICE_IDR: - /* fall-through. IDR specifics are handled in init_picture() */ + /* fall-through. IDR specifics are handled in init_picture() */ case GST_H264_NAL_SLICE: - status = decode_slice(decoder, unit); - break; + status = decode_slice (decoder, unit); + break; case GST_H264_NAL_SEQ_END: case GST_H264_NAL_STREAM_END: - status = decode_sequence_end(decoder); - break; + status = decode_sequence_end (decoder); + break; case GST_H264_NAL_SEI: - status = decode_sei(decoder, unit); - break; + status = decode_sei (decoder, unit); + break; default: - GST_WARNING("unsupported NAL unit type %d", pi->nalu.type); - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - break; - } - return status; + GST_WARNING ("unsupported NAL unit type %d", pi->nalu.type); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + return status; } static GstVaapiDecoderStatus -gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder, - const guchar *buf, guint buf_size) +gst_vaapi_decoder_h264_decode_codec_data (GstVaapiDecoder * base_decoder, + const guchar * buf, guint buf_size) { - GstVaapiDecoderH264 * const decoder = - GST_VAAPI_DECODER_H264_CAST(base_decoder); - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiDecoderStatus status; - GstVaapiDecoderUnit unit; - GstVaapiParserInfoH264 *pi = NULL; - GstH264ParserResult result; - guint i, ofs, num_sps, num_pps; + GstVaapiDecoderH264 *const decoder = + GST_VAAPI_DECODER_H264_CAST (base_decoder); + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; + GstVaapiDecoderUnit unit; + GstVaapiParserInfoH264 *pi = NULL; + GstH264ParserResult result; + guint i, ofs, num_sps, num_pps; - unit.parsed_info = NULL; + unit.parsed_info = NULL; - if (buf_size < 8) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + if (buf_size < 8) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - if (buf[0] != 1) { - GST_ERROR("failed to decode codec-data, not in avcC format"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + if (buf[0] != 1) { + GST_ERROR ("failed to decode codec-data, not in avcC format"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + priv->nal_length_size = (buf[4] & 0x03) + 1; + + num_sps = buf[5] & 0x1f; + ofs = 6; + + for (i = 0; i < num_sps; i++) { + pi = gst_vaapi_parser_info_h264_new (); + if (!pi) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + unit.parsed_info = pi; + + result = gst_h264_parser_identify_nalu_avc (priv->parser, + buf, ofs, buf_size, 2, &pi->nalu); + if (result != GST_H264_PARSER_OK) { + status = get_status (result); + goto cleanup; } - priv->nal_length_size = (buf[4] & 0x03) + 1; + status = parse_sps (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + ofs = pi->nalu.offset + pi->nalu.size; - num_sps = buf[5] & 0x1f; - ofs = 6; + pi->state = priv->parser_state; + pi->flags = 0; - for (i = 0; i < num_sps; i++) { - pi = gst_vaapi_parser_info_h264_new(); - if (!pi) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - unit.parsed_info = pi; + status = decode_sps (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + gst_vaapi_parser_info_h264_replace (&pi, NULL); + } - result = gst_h264_parser_identify_nalu_avc( - priv->parser, - buf, ofs, buf_size, 2, - &pi->nalu - ); - if (result != GST_H264_PARSER_OK) { - status = get_status(result); - goto cleanup; - } + num_pps = buf[ofs]; + ofs++; - status = parse_sps(decoder, &unit); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - goto cleanup; - ofs = pi->nalu.offset + pi->nalu.size; + for (i = 0; i < num_pps; i++) { + pi = gst_vaapi_parser_info_h264_new (); + if (!pi) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + unit.parsed_info = pi; - pi->state = priv->parser_state; - pi->flags = 0; - - status = decode_sps(decoder, &unit); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - goto cleanup; - gst_vaapi_parser_info_h264_replace(&pi, NULL); + result = gst_h264_parser_identify_nalu_avc (priv->parser, + buf, ofs, buf_size, 2, &pi->nalu); + if (result != GST_H264_PARSER_OK) { + status = get_status (result); + goto cleanup; } - num_pps = buf[ofs]; - ofs++; + status = parse_pps (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + ofs = pi->nalu.offset + pi->nalu.size; - for (i = 0; i < num_pps; i++) { - pi = gst_vaapi_parser_info_h264_new(); - if (!pi) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - unit.parsed_info = pi; + pi->state = priv->parser_state; + pi->flags = 0; - result = gst_h264_parser_identify_nalu_avc( - priv->parser, - buf, ofs, buf_size, 2, - &pi->nalu - ); - if (result != GST_H264_PARSER_OK) { - status = get_status(result); - goto cleanup; - } + status = decode_pps (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + gst_vaapi_parser_info_h264_replace (&pi, NULL); + } - status = parse_pps(decoder, &unit); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - goto cleanup; - ofs = pi->nalu.offset + pi->nalu.size; - - pi->state = priv->parser_state; - pi->flags = 0; - - status = decode_pps(decoder, &unit); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - goto cleanup; - gst_vaapi_parser_info_h264_replace(&pi, NULL); - } - - priv->is_avcC = TRUE; - status = GST_VAAPI_DECODER_STATUS_SUCCESS; + priv->is_avcC = TRUE; + status = GST_VAAPI_DECODER_STATUS_SUCCESS; cleanup: - gst_vaapi_parser_info_h264_replace(&pi, NULL); - return status; + gst_vaapi_parser_info_h264_replace (&pi, NULL); + return status; } static GstVaapiDecoderStatus -ensure_decoder(GstVaapiDecoderH264 *decoder) +ensure_decoder (GstVaapiDecoderH264 * decoder) { - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiDecoderStatus status; + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; - if (!priv->is_opened) { - priv->is_opened = gst_vaapi_decoder_h264_open(decoder); - if (!priv->is_opened) - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + if (!priv->is_opened) { + priv->is_opened = gst_vaapi_decoder_h264_open (decoder); + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; - status = gst_vaapi_decoder_decode_codec_data( - GST_VAAPI_DECODER_CAST(decoder)); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder, - GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) -{ - GstVaapiDecoderH264 * const decoder = - GST_VAAPI_DECODER_H264_CAST(base_decoder); - GstVaapiDecoderH264Private * const priv = &decoder->priv; - GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); - GstVaapiParserInfoH264 *pi; - GstVaapiDecoderStatus status; - GstH264ParserResult result; - guchar *buf; - guint i, size, buf_size, nalu_size, flags; - guint32 start_code; - gint ofs, ofs2; - gboolean at_au_end = FALSE; - - status = ensure_decoder(decoder); + status = + gst_vaapi_decoder_decode_codec_data (GST_VAAPI_DECODER_CAST (decoder)); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; + return status; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} - switch (priv->stream_alignment) { +static GstVaapiDecoderStatus +gst_vaapi_decoder_h264_parse (GstVaapiDecoder * base_decoder, + GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderH264 *const decoder = + GST_VAAPI_DECODER_H264_CAST (base_decoder); + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVaapiParserState *const ps = GST_VAAPI_PARSER_STATE (base_decoder); + GstVaapiParserInfoH264 *pi; + GstVaapiDecoderStatus status; + GstH264ParserResult result; + guchar *buf; + guint i, size, buf_size, nalu_size, flags; + guint32 start_code; + gint ofs, ofs2; + gboolean at_au_end = FALSE; + + status = ensure_decoder (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + switch (priv->stream_alignment) { case GST_VAAPI_STREAM_ALIGN_H264_NALU: case GST_VAAPI_STREAM_ALIGN_H264_AU: - size = gst_adapter_available_fast(adapter); - break; + size = gst_adapter_available_fast (adapter); + break; default: - size = gst_adapter_available(adapter); - break; - } + size = gst_adapter_available (adapter); + break; + } - if (priv->is_avcC) { - if (size < priv->nal_length_size) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + if (priv->is_avcC) { + if (size < priv->nal_length_size) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - buf = (guchar *)&start_code; - g_assert(priv->nal_length_size <= sizeof(start_code)); - gst_adapter_copy(adapter, buf, 0, priv->nal_length_size); + buf = (guchar *) & start_code; + g_assert (priv->nal_length_size <= sizeof (start_code)); + gst_adapter_copy (adapter, buf, 0, priv->nal_length_size); - nalu_size = 0; - for (i = 0; i < priv->nal_length_size; i++) - nalu_size = (nalu_size << 8) | buf[i]; + nalu_size = 0; + for (i = 0; i < priv->nal_length_size; i++) + nalu_size = (nalu_size << 8) | buf[i]; - buf_size = priv->nal_length_size + nalu_size; - if (size < buf_size) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - else if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_AU) - at_au_end = (buf_size == size); - } + buf_size = priv->nal_length_size + nalu_size; + if (size < buf_size) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + else if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_AU) + at_au_end = (buf_size == size); + } else { + if (size < 4) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_NALU) + buf_size = size; else { - if (size < 4) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - - if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_NALU) - buf_size = size; - else { - ofs = scan_for_start_code(adapter, 0, size, NULL); - if (ofs < 0) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - - if (ofs > 0) { - gst_adapter_flush(adapter, ofs); - size -= ofs; - } - - ofs2 = ps->input_offset2 - ofs - 4; - if (ofs2 < 4) - ofs2 = 4; - - ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 : - scan_for_start_code(adapter, ofs2, size - ofs2, NULL); - if (ofs < 0) { - // Assume the whole NAL unit is present if end-of-stream - // or stream buffers aligned on access unit boundaries - if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_AU) - at_au_end = TRUE; - else if (!at_eos) { - ps->input_offset2 = size; - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - } - ofs = size; - } - buf_size = ofs; - } - } - ps->input_offset2 = 0; - - buf = (guchar *)gst_adapter_map(adapter, buf_size); - if (!buf) + ofs = scan_for_start_code (adapter, 0, size, NULL); + if (ofs < 0) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - unit->size = buf_size; + if (ofs > 0) { + gst_adapter_flush (adapter, ofs); + size -= ofs; + } - pi = gst_vaapi_parser_info_h264_new(); - if (!pi) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + ofs2 = ps->input_offset2 - ofs - 4; + if (ofs2 < 4) + ofs2 = 4; - gst_vaapi_decoder_unit_set_parsed_info(unit, - pi, (GDestroyNotify)gst_vaapi_mini_object_unref); - - if (priv->is_avcC) - result = gst_h264_parser_identify_nalu_avc(priv->parser, - buf, 0, buf_size, priv->nal_length_size, &pi->nalu); - else - result = gst_h264_parser_identify_nalu_unchecked(priv->parser, - buf, 0, buf_size, &pi->nalu); - status = get_status(result); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - - switch (pi->nalu.type) { - case GST_H264_NAL_SPS: - status = parse_sps(decoder, unit); - break; - case GST_H264_NAL_SUBSET_SPS: - status = parse_subset_sps(decoder, unit); - break; - case GST_H264_NAL_PPS: - status = parse_pps(decoder, unit); - break; - case GST_H264_NAL_SEI: - status = parse_sei(decoder, unit); - break; - case GST_H264_NAL_SLICE_EXT: - if (!GST_H264_IS_MVC_NALU(&pi->nalu)) { - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; + ofs = G_UNLIKELY (size < ofs2 + 4) ? -1 : + scan_for_start_code (adapter, ofs2, size - ofs2, NULL); + if (ofs < 0) { + // Assume the whole NAL unit is present if end-of-stream + // or stream buffers aligned on access unit boundaries + if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_AU) + at_au_end = TRUE; + else if (!at_eos) { + ps->input_offset2 = size; + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; } - /* fall-through */ - case GST_H264_NAL_SLICE_IDR: - case GST_H264_NAL_SLICE: - status = parse_slice(decoder, unit); - break; - default: + ofs = size; + } + buf_size = ofs; + } + } + ps->input_offset2 = 0; + + buf = (guchar *) gst_adapter_map (adapter, buf_size); + if (!buf) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + unit->size = buf_size; + + pi = gst_vaapi_parser_info_h264_new (); + if (!pi) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + + gst_vaapi_decoder_unit_set_parsed_info (unit, + pi, (GDestroyNotify) gst_vaapi_mini_object_unref); + + if (priv->is_avcC) + result = gst_h264_parser_identify_nalu_avc (priv->parser, + buf, 0, buf_size, priv->nal_length_size, &pi->nalu); + else + result = gst_h264_parser_identify_nalu_unchecked (priv->parser, + buf, 0, buf_size, &pi->nalu); + status = get_status (result); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + switch (pi->nalu.type) { + case GST_H264_NAL_SPS: + status = parse_sps (decoder, unit); + break; + case GST_H264_NAL_SUBSET_SPS: + status = parse_subset_sps (decoder, unit); + break; + case GST_H264_NAL_PPS: + status = parse_pps (decoder, unit); + break; + case GST_H264_NAL_SEI: + status = parse_sei (decoder, unit); + break; + case GST_H264_NAL_SLICE_EXT: + if (!GST_H264_IS_MVC_NALU (&pi->nalu)) { status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; - } - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; + } + /* fall-through */ + case GST_H264_NAL_SLICE_IDR: + case GST_H264_NAL_SLICE: + status = parse_slice (decoder, unit); + break; + default: + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; - flags = 0; - if (at_au_end) { - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END | - GST_VAAPI_DECODER_UNIT_FLAG_AU_END; - } - switch (pi->nalu.type) { + flags = 0; + if (at_au_end) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END | + GST_VAAPI_DECODER_UNIT_FLAG_AU_END; + } + switch (pi->nalu.type) { case GST_H264_NAL_AU_DELIMITER: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - /* fall-through */ + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + /* fall-through */ case GST_H264_NAL_FILLER_DATA: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; - break; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + break; case GST_H264_NAL_STREAM_END: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; - /* fall-through */ + flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; + /* fall-through */ case GST_H264_NAL_SEQ_END: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; - flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END; - break; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END; + break; case GST_H264_NAL_SPS: case GST_H264_NAL_SUBSET_SPS: case GST_H264_NAL_PPS: case GST_H264_NAL_SEI: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - break; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; case GST_H264_NAL_SLICE_EXT: - if (!GST_H264_IS_MVC_NALU(&pi->nalu)) { - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; - break; - } - /* fall-through */ - case GST_H264_NAL_SLICE_IDR: - case GST_H264_NAL_SLICE: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; - if (priv->prev_pi && - (priv->prev_pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END)) { - flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START | - GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - } - else if (is_new_picture(pi, priv->prev_slice_pi)) { - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - if (is_new_access_unit(pi, priv->prev_slice_pi)) - flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; - } - gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, pi); - break; - case GST_H264_NAL_SPS_EXT: - case GST_H264_NAL_SLICE_AUX: - /* skip SPS extension and auxiliary slice for now */ + if (!GST_H264_IS_MVC_NALU (&pi->nalu)) { flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; break; - case GST_H264_NAL_PREFIX_UNIT: - /* skip Prefix NAL units for now */ - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP | - GST_VAAPI_DECODER_UNIT_FLAG_AU_START | + } + /* fall-through */ + case GST_H264_NAL_SLICE_IDR: + case GST_H264_NAL_SLICE: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + if (priv->prev_pi && + (priv->prev_pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END)) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START | GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - break; + } else if (is_new_picture (pi, priv->prev_slice_pi)) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + if (is_new_access_unit (pi, priv->prev_slice_pi)) + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; + } + gst_vaapi_parser_info_h264_replace (&priv->prev_slice_pi, pi); + break; + case GST_H264_NAL_SPS_EXT: + case GST_H264_NAL_SLICE_AUX: + /* skip SPS extension and auxiliary slice for now */ + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + break; + case GST_H264_NAL_PREFIX_UNIT: + /* skip Prefix NAL units for now */ + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP | + GST_VAAPI_DECODER_UNIT_FLAG_AU_START | + GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; default: - if (pi->nalu.type >= 14 && pi->nalu.type <= 18) - flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START | - GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - break; - } - if ((flags & GST_VAAPI_DECODER_UNIT_FLAGS_AU) && priv->prev_slice_pi) - priv->prev_slice_pi->flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END; - GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); + if (pi->nalu.type >= 14 && pi->nalu.type <= 18) + flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START | + GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; + } + if ((flags & GST_VAAPI_DECODER_UNIT_FLAGS_AU) && priv->prev_slice_pi) + priv->prev_slice_pi->flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END; + GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags); - pi->nalu.data = NULL; - pi->state = priv->parser_state; - pi->flags = flags; - gst_vaapi_parser_info_h264_replace(&priv->prev_pi, pi); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + pi->nalu.data = NULL; + pi->state = priv->parser_state; + pi->flags = flags; + gst_vaapi_parser_info_h264_replace (&priv->prev_pi, pi); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base_decoder, - GstVaapiDecoderUnit *unit) +gst_vaapi_decoder_h264_decode (GstVaapiDecoder * base_decoder, + GstVaapiDecoderUnit * unit) { - GstVaapiDecoderH264 * const decoder = - GST_VAAPI_DECODER_H264_CAST(base_decoder); - GstVaapiDecoderStatus status; + GstVaapiDecoderH264 *const decoder = + GST_VAAPI_DECODER_H264_CAST (base_decoder); + GstVaapiDecoderStatus status; - status = ensure_decoder(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - return decode_unit(decoder, unit); + status = ensure_decoder (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + return decode_unit (decoder, unit); } static GstVaapiDecoderStatus -gst_vaapi_decoder_h264_start_frame(GstVaapiDecoder *base_decoder, - GstVaapiDecoderUnit *unit) +gst_vaapi_decoder_h264_start_frame (GstVaapiDecoder * base_decoder, + GstVaapiDecoderUnit * unit) { - GstVaapiDecoderH264 * const decoder = - GST_VAAPI_DECODER_H264_CAST(base_decoder); + GstVaapiDecoderH264 *const decoder = + GST_VAAPI_DECODER_H264_CAST (base_decoder); - return decode_picture(decoder, unit); + return decode_picture (decoder, unit); } static GstVaapiDecoderStatus -gst_vaapi_decoder_h264_end_frame(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_h264_end_frame (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderH264 * const decoder = - GST_VAAPI_DECODER_H264_CAST(base_decoder); + GstVaapiDecoderH264 *const decoder = + GST_VAAPI_DECODER_H264_CAST (base_decoder); - return decode_current_picture(decoder); + return decode_current_picture (decoder); } static GstVaapiDecoderStatus -gst_vaapi_decoder_h264_flush(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_h264_flush (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderH264 * const decoder = - GST_VAAPI_DECODER_H264_CAST(base_decoder); + GstVaapiDecoderH264 *const decoder = + GST_VAAPI_DECODER_H264_CAST (base_decoder); - dpb_flush(decoder, NULL); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + dpb_flush (decoder, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static void -gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass) +gst_vaapi_decoder_h264_class_init (GstVaapiDecoderH264Class * klass) { - GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); - GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof(GstVaapiDecoderH264); - object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize; + object_class->size = sizeof (GstVaapiDecoderH264); + object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; - decoder_class->create = gst_vaapi_decoder_h264_create; - decoder_class->destroy = gst_vaapi_decoder_h264_destroy; - decoder_class->parse = gst_vaapi_decoder_h264_parse; - decoder_class->decode = gst_vaapi_decoder_h264_decode; - decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame; - decoder_class->end_frame = gst_vaapi_decoder_h264_end_frame; - decoder_class->flush = gst_vaapi_decoder_h264_flush; + decoder_class->create = gst_vaapi_decoder_h264_create; + decoder_class->destroy = gst_vaapi_decoder_h264_destroy; + decoder_class->parse = gst_vaapi_decoder_h264_parse; + decoder_class->decode = gst_vaapi_decoder_h264_decode; + decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame; + decoder_class->end_frame = gst_vaapi_decoder_h264_end_frame; + decoder_class->flush = gst_vaapi_decoder_h264_flush; - decoder_class->decode_codec_data = - gst_vaapi_decoder_h264_decode_codec_data; + decoder_class->decode_codec_data = gst_vaapi_decoder_h264_decode_codec_data; } static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_h264_class(void) +gst_vaapi_decoder_h264_class (void) { - static GstVaapiDecoderH264Class g_class; - static gsize g_class_init = FALSE; + static GstVaapiDecoderH264Class g_class; + static gsize g_class_init = FALSE; - if (g_once_init_enter(&g_class_init)) { - gst_vaapi_decoder_h264_class_init(&g_class); - g_once_init_leave(&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS(&g_class); + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_decoder_h264_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS (&g_class); } /** @@ -4729,12 +4631,12 @@ gst_vaapi_decoder_h264_class(void) * specific alignment, NAL unit boundaries, or access unit boundaries. */ void -gst_vaapi_decoder_h264_set_alignment(GstVaapiDecoderH264 *decoder, +gst_vaapi_decoder_h264_set_alignment (GstVaapiDecoderH264 * decoder, GstVaapiStreamAlignH264 alignment) { - g_return_if_fail(decoder != NULL); + g_return_if_fail (decoder != NULL); - decoder->priv.stream_alignment = alignment; + decoder->priv.stream_alignment = alignment; } /** @@ -4748,7 +4650,7 @@ gst_vaapi_decoder_h264_set_alignment(GstVaapiDecoderH264 *decoder, * Return value: the newly allocated #GstVaapiDecoder object */ GstVaapiDecoder * -gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps) +gst_vaapi_decoder_h264_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new(gst_vaapi_decoder_h264_class(), display, caps); + return gst_vaapi_decoder_new (gst_vaapi_decoder_h264_class (), display, caps); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 781a60d9ef..d199bb2f9e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -46,35 +46,35 @@ #define GST_VAAPI_DECODER_JPEG_CAST(decoder) \ ((GstVaapiDecoderJpeg *)(decoder)) -typedef struct _GstVaapiDecoderJpegPrivate GstVaapiDecoderJpegPrivate; -typedef struct _GstVaapiDecoderJpegClass GstVaapiDecoderJpegClass; +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, +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), + 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; +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; }; /** @@ -82,10 +82,11 @@ struct _GstVaapiDecoderJpegPrivate { * * A decoder based on Jpeg. */ -struct _GstVaapiDecoderJpeg { - /*< private >*/ - GstVaapiDecoder parent_instance; - GstVaapiDecoderJpegPrivate priv; +struct _GstVaapiDecoderJpeg +{ + /*< private > */ + GstVaapiDecoder parent_instance; + GstVaapiDecoderJpegPrivate priv; }; /** @@ -93,122 +94,121 @@ struct _GstVaapiDecoderJpeg { * * A decoder class based on Jpeg. */ -struct _GstVaapiDecoderJpegClass { - /*< private >*/ - GstVaapiDecoderClass parent_class; +struct _GstVaapiDecoderJpegClass +{ + /*< private > */ + GstVaapiDecoderClass parent_class; }; static inline void -unit_set_marker_code(GstVaapiDecoderUnit *unit, GstJpegMarker marker) +unit_set_marker_code (GstVaapiDecoderUnit * unit, GstJpegMarker marker) { - unit->parsed_info = GSIZE_TO_POINTER(marker); + unit->parsed_info = GSIZE_TO_POINTER (marker); } static inline GstJpegMarker -unit_get_marker_code(GstVaapiDecoderUnit *unit) +unit_get_marker_code (GstVaapiDecoderUnit * unit) { - return GPOINTER_TO_SIZE(unit->parsed_info); + return GPOINTER_TO_SIZE (unit->parsed_info); } static void -gst_vaapi_decoder_jpeg_close(GstVaapiDecoderJpeg *decoder) +gst_vaapi_decoder_jpeg_close (GstVaapiDecoderJpeg * decoder) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; + GstVaapiDecoderJpegPrivate *const priv = &decoder->priv; - gst_vaapi_picture_replace(&priv->current_picture, NULL); + 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; + /* Reset all */ + priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; + priv->width = 0; + priv->height = 0; + priv->is_opened = FALSE; + priv->profile_changed = TRUE; } static gboolean -gst_vaapi_decoder_jpeg_open(GstVaapiDecoderJpeg *decoder) +gst_vaapi_decoder_jpeg_open (GstVaapiDecoderJpeg * decoder) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; + GstVaapiDecoderJpegPrivate *const priv = &decoder->priv; - gst_vaapi_decoder_jpeg_close(decoder); + gst_vaapi_decoder_jpeg_close (decoder); - priv->parser_state = 0; - priv->decoder_state = 0; - return TRUE; + priv->parser_state = 0; + priv->decoder_state = 0; + return TRUE; } static void -gst_vaapi_decoder_jpeg_destroy(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_jpeg_destroy (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderJpeg * const decoder = - GST_VAAPI_DECODER_JPEG_CAST(base_decoder); + GstVaapiDecoderJpeg *const decoder = + GST_VAAPI_DECODER_JPEG_CAST (base_decoder); - gst_vaapi_decoder_jpeg_close(decoder); + gst_vaapi_decoder_jpeg_close (decoder); } static gboolean -gst_vaapi_decoder_jpeg_create(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_jpeg_create (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderJpeg * const decoder = - GST_VAAPI_DECODER_JPEG_CAST(base_decoder); - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; + 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; - return TRUE; + priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; + priv->profile_changed = TRUE; + return TRUE; } static GstVaapiDecoderStatus -ensure_context(GstVaapiDecoderJpeg *decoder) +ensure_context (GstVaapiDecoderJpeg * decoder) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; - GstVaapiProfile profiles[2]; - GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; - guint i, n_profiles = 0; - gboolean reset_context = FALSE; + GstVaapiDecoderJpegPrivate *const priv = &decoder->priv; + 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; + 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; + 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]; + 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 (reset_context) { - GstVaapiContextInfo info; + 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 = 2; - 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; + 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 = 2; + 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) +is_valid_state (guint state, guint ref_state) { - return (state & ref_state) == ref_state; + return (state & ref_state) == ref_state; } #define VALID_STATE(TYPE, STATE) \ @@ -216,677 +216,662 @@ is_valid_state(guint state, guint ref_state) G_PASTE(GST_JPEG_VIDEO_STATE_,STATE)) static GstVaapiDecoderStatus -decode_current_picture(GstVaapiDecoderJpeg *decoder) +decode_current_picture (GstVaapiDecoderJpeg * decoder) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; - GstVaapiPicture * const picture = priv->current_picture; + 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 (!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); + 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; + error: - gst_vaapi_picture_replace(&priv->current_picture, NULL); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + 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; + priv->decoder_state = 0; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; } static gboolean -fill_picture( - GstVaapiDecoderJpeg *decoder, - GstVaapiPicture *picture, - GstJpegFrameHdr *frame_hdr -) +fill_picture (GstVaapiDecoderJpeg * decoder, + GstVaapiPicture * picture, GstJpegFrameHdr * frame_hdr) { - VAPictureParameterBufferJPEGBaseline * const pic_param = picture->param; - guint i; + 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; + 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; + 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) +fill_quantization_table (GstVaapiDecoderJpeg * decoder, + GstVaapiPicture * picture) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; - VAIQMatrixBufferJPEGBaseline *iq_matrix; - guint i, j, num_tables; + 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; + 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; } - 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; + 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) +huffman_tables_updated (const GstJpegHuffmanTables * huf_tables) { - guint i; + 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; + 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) +huffman_tables_reset (GstJpegHuffmanTables * huf_tables) { - guint i; + 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; + 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) +fill_huffman_table (GstVaapiHuffmanTable * huf_table, + const GstJpegHuffmanTables * huf_tables) { - VAHuffmanTableBufferJPEGBaseline * const huffman_table = huf_table->param; - guint i, num_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); + 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; + 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)); - } + 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) +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; + 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; - } + 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; + 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) +get_component (const GstJpegFrameHdr * frame_hdr, guint selector) { - guint i; + 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; + 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) +decode_picture (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; - GstJpegFrameHdr * const frame_hdr = &priv->frame_hdr; + GstVaapiDecoderJpegPrivate *const priv = &decoder->priv; + GstJpegFrameHdr *const frame_hdr = &priv->frame_hdr; - if (!VALID_STATE(decoder, GOT_SOI)) - return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!VALID_STATE (decoder, GOT_SOI)) + return GST_VAAPI_DECODER_STATUS_SUCCESS; - switch (seg->marker) { + switch (seg->marker) { case GST_JPEG_MARKER_SOF_MIN: - priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; - break; + priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; + break; default: - GST_ERROR("unsupported profile %d", seg->marker); - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - } + 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; - } - priv->height = frame_hdr->height; - priv->width = frame_hdr->width; + 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; + } + 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; + priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_SOF; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_huffman_table( - GstVaapiDecoderJpeg *decoder, - GstJpegSegment *seg -) +decode_huffman_table (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; + 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; + 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 -) +decode_quant_table (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; + 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; + 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 -) +decode_restart_interval (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; + 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; - } + 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) +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; + 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; + 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) +decode_segment (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; - GstVaapiDecoderStatus status; + GstVaapiDecoderJpegPrivate *const priv = &decoder->priv; + GstVaapiDecoderStatus status; - // Decode segment - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - switch (seg->marker) { + // 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; + priv->mcu_restart = 0; + priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_SOI; + break; case GST_JPEG_MARKER_EOI: - priv->decoder_state = 0; - break; + 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; + 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; + status = decode_huffman_table (decoder, seg); + break; case GST_JPEG_MARKER_DQT: - status = decode_quant_table(decoder, seg); - break; + status = decode_quant_table (decoder, seg); + break; case GST_JPEG_MARKER_DRI: - status = decode_restart_interval(decoder, seg); - break; + status = decode_restart_interval (decoder, seg); + break; case GST_JPEG_MARKER_SOS: - status = decode_scan(decoder, seg); - break; + 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; + // 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) +ensure_decoder (GstVaapiDecoderJpeg * decoder) { - GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; + 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; + 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) +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; + // 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) +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; + 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; + 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; + /* 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; + 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; + 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; + 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; } - gst_adapter_unmap(adapter); + ofs1 = seg.offset; - unit->size = ofs2 - ofs1; - unit_set_marker_code(unit, marker); - gst_adapter_flush(adapter, ofs1); - ps->input_offset1 = 2; - ps->input_offset2 = 2; + 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; - flags = 0; - switch (marker) { + // 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; + 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; + 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; + 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: + if (priv->parser_state & GST_JPEG_VIDEO_STATE_GOT_SOF) flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; - break; + 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; + 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; + /* 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; + /* 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; + /* 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) +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; + 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; + 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; - } + 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; + 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; + 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) +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; + 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; + 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) +gst_vaapi_decoder_jpeg_end_frame (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderJpeg * const decoder = - GST_VAAPI_DECODER_JPEG_CAST(base_decoder); + GstVaapiDecoderJpeg *const decoder = + GST_VAAPI_DECODER_JPEG_CAST (base_decoder); - return decode_current_picture(decoder); + return decode_current_picture (decoder); } static void -gst_vaapi_decoder_jpeg_class_init(GstVaapiDecoderJpegClass *klass) +gst_vaapi_decoder_jpeg_class_init (GstVaapiDecoderJpegClass * klass) { - GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); - GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof(GstVaapiDecoderJpeg); - object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize; + object_class->size = sizeof (GstVaapiDecoderJpeg); + object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; - decoder_class->create = gst_vaapi_decoder_jpeg_create; - decoder_class->destroy = gst_vaapi_decoder_jpeg_destroy; - 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; + decoder_class->create = gst_vaapi_decoder_jpeg_create; + decoder_class->destroy = gst_vaapi_decoder_jpeg_destroy; + 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 inline const GstVaapiDecoderClass * -gst_vaapi_decoder_jpeg_class(void) +gst_vaapi_decoder_jpeg_class (void) { - static GstVaapiDecoderJpegClass g_class; - static gsize g_class_init = FALSE; + static GstVaapiDecoderJpegClass g_class; + static gsize g_class_init = FALSE; - if (g_once_init_enter(&g_class_init)) { - gst_vaapi_decoder_jpeg_class_init(&g_class); - g_once_init_leave(&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS(&g_class); + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_decoder_jpeg_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS (&g_class); } /** @@ -900,7 +885,7 @@ gst_vaapi_decoder_jpeg_class(void) * Return value: the newly allocated #GstVaapiDecoder object */ GstVaapiDecoder * -gst_vaapi_decoder_jpeg_new(GstVaapiDisplay *display, GstCaps *caps) +gst_vaapi_decoder_jpeg_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new(gst_vaapi_decoder_jpeg_class(), display, caps); + return gst_vaapi_decoder_new (gst_vaapi_decoder_jpeg_class (), display, caps); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 6dc9f0cf92..b828a9fe4a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -44,113 +44,112 @@ /* ------------------------------------------------------------------------- */ typedef struct _PTSGenerator PTSGenerator; -struct _PTSGenerator { - GstClockTime gop_pts; // Current GOP PTS - GstClockTime max_pts; // Max picture PTS - guint gop_tsn; // Absolute GOP TSN - guint max_tsn; // Max picture TSN, relative to last GOP TSN - guint ovl_tsn; // How many times TSN overflowed since GOP - guint lst_tsn; // Last picture TSN - guint fps_n; - guint fps_d; +struct _PTSGenerator +{ + GstClockTime gop_pts; // Current GOP PTS + GstClockTime max_pts; // Max picture PTS + guint gop_tsn; // Absolute GOP TSN + guint max_tsn; // Max picture TSN, relative to last GOP TSN + guint ovl_tsn; // How many times TSN overflowed since GOP + guint lst_tsn; // Last picture TSN + guint fps_n; + guint fps_d; }; static void -pts_init(PTSGenerator *tsg) +pts_init (PTSGenerator * tsg) { - tsg->gop_pts = GST_CLOCK_TIME_NONE; - tsg->max_pts = GST_CLOCK_TIME_NONE; - tsg->gop_tsn = 0; - tsg->max_tsn = 0; - tsg->ovl_tsn = 0; - tsg->lst_tsn = 0; - tsg->fps_n = 0; - tsg->fps_d = 0; + tsg->gop_pts = GST_CLOCK_TIME_NONE; + tsg->max_pts = GST_CLOCK_TIME_NONE; + tsg->gop_tsn = 0; + tsg->max_tsn = 0; + tsg->ovl_tsn = 0; + tsg->lst_tsn = 0; + tsg->fps_n = 0; + tsg->fps_d = 0; } static inline GstClockTime -pts_get_duration(PTSGenerator *tsg, guint num_frames) +pts_get_duration (PTSGenerator * tsg, guint num_frames) { - return gst_util_uint64_scale(num_frames, - GST_SECOND * tsg->fps_d, tsg->fps_n); + return gst_util_uint64_scale (num_frames, + GST_SECOND * tsg->fps_d, tsg->fps_n); } static inline guint -pts_get_poc(PTSGenerator *tsg) +pts_get_poc (PTSGenerator * tsg) { - return tsg->gop_tsn + tsg->ovl_tsn * 1024 + tsg->lst_tsn; + return tsg->gop_tsn + tsg->ovl_tsn * 1024 + tsg->lst_tsn; } static void -pts_set_framerate(PTSGenerator *tsg, guint fps_n, guint fps_d) +pts_set_framerate (PTSGenerator * tsg, guint fps_n, guint fps_d) { - tsg->fps_n = fps_n; - tsg->fps_d = fps_d; + tsg->fps_n = fps_n; + tsg->fps_d = fps_d; } static void -pts_sync(PTSGenerator *tsg, GstClockTime gop_pts) +pts_sync (PTSGenerator * tsg, GstClockTime gop_pts) { - guint gop_tsn; + guint gop_tsn; - if (!GST_CLOCK_TIME_IS_VALID(gop_pts) || - (GST_CLOCK_TIME_IS_VALID(tsg->max_pts) && tsg->max_pts >= gop_pts)) { - /* Invalid GOP PTS, interpolate from the last known picture PTS */ - if (GST_CLOCK_TIME_IS_VALID(tsg->max_pts)) { - gop_pts = tsg->max_pts + pts_get_duration(tsg, 1); - gop_tsn = tsg->gop_tsn + tsg->ovl_tsn * 1024 + tsg->max_tsn + 1; - } - else { - gop_pts = 0; - gop_tsn = 0; - } - } - else { - /* Interpolate GOP TSN from this valid PTS */ - if (GST_CLOCK_TIME_IS_VALID(tsg->gop_pts)) - gop_tsn = tsg->gop_tsn + gst_util_uint64_scale( - gop_pts - tsg->gop_pts + pts_get_duration(tsg, 1) - 1, - tsg->fps_n, GST_SECOND * tsg->fps_d); - else - gop_tsn = 0; + if (!GST_CLOCK_TIME_IS_VALID (gop_pts) || + (GST_CLOCK_TIME_IS_VALID (tsg->max_pts) && tsg->max_pts >= gop_pts)) { + /* Invalid GOP PTS, interpolate from the last known picture PTS */ + if (GST_CLOCK_TIME_IS_VALID (tsg->max_pts)) { + gop_pts = tsg->max_pts + pts_get_duration (tsg, 1); + gop_tsn = tsg->gop_tsn + tsg->ovl_tsn * 1024 + tsg->max_tsn + 1; + } else { + gop_pts = 0; + gop_tsn = 0; } + } else { + /* Interpolate GOP TSN from this valid PTS */ + if (GST_CLOCK_TIME_IS_VALID (tsg->gop_pts)) + gop_tsn = + tsg->gop_tsn + gst_util_uint64_scale (gop_pts - tsg->gop_pts + + pts_get_duration (tsg, 1) - 1, tsg->fps_n, GST_SECOND * tsg->fps_d); + else + gop_tsn = 0; + } - tsg->gop_pts = gop_pts; - tsg->gop_tsn = gop_tsn; - tsg->max_tsn = 0; - tsg->ovl_tsn = 0; - tsg->lst_tsn = 0; + tsg->gop_pts = gop_pts; + tsg->gop_tsn = gop_tsn; + tsg->max_tsn = 0; + tsg->ovl_tsn = 0; + tsg->lst_tsn = 0; } static GstClockTime -pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn) +pts_eval (PTSGenerator * tsg, GstClockTime pic_pts, guint pic_tsn) { - GstClockTime pts; + GstClockTime pts; - if (!GST_CLOCK_TIME_IS_VALID(tsg->gop_pts)) - tsg->gop_pts = pts_get_duration(tsg, pic_tsn); + if (!GST_CLOCK_TIME_IS_VALID (tsg->gop_pts)) + tsg->gop_pts = pts_get_duration (tsg, pic_tsn); - pts = pic_pts; - if (!GST_CLOCK_TIME_IS_VALID (pts)) - pts = tsg->gop_pts + pts_get_duration(tsg, tsg->ovl_tsn * 1024 + pic_tsn); - else if (pts == tsg->gop_pts) { - /* The picture following the GOP header shall be an I-frame. - So we can compensate for the GOP start time from here */ - tsg->gop_pts -= pts_get_duration(tsg, pic_tsn); - } + pts = pic_pts; + if (!GST_CLOCK_TIME_IS_VALID (pts)) + pts = tsg->gop_pts + pts_get_duration (tsg, tsg->ovl_tsn * 1024 + pic_tsn); + else if (pts == tsg->gop_pts) { + /* The picture following the GOP header shall be an I-frame. + So we can compensate for the GOP start time from here */ + tsg->gop_pts -= pts_get_duration (tsg, pic_tsn); + } - if (!GST_CLOCK_TIME_IS_VALID(tsg->max_pts) || tsg->max_pts < pts) - tsg->max_pts = pts; + if (!GST_CLOCK_TIME_IS_VALID (tsg->max_pts) || tsg->max_pts < pts) + tsg->max_pts = pts; - if (tsg->max_tsn < pic_tsn) - tsg->max_tsn = pic_tsn; - else if (tsg->max_tsn == 1023 && pic_tsn < tsg->lst_tsn) { /* TSN wrapped */ - tsg->max_tsn = pic_tsn; - tsg->ovl_tsn++; - } - tsg->lst_tsn = pic_tsn; + if (tsg->max_tsn < pic_tsn) + tsg->max_tsn = pic_tsn; + else if (tsg->max_tsn == 1023 && pic_tsn < tsg->lst_tsn) { /* TSN wrapped */ + tsg->max_tsn = pic_tsn; + tsg->ovl_tsn++; + } + tsg->lst_tsn = pic_tsn; - return pts; + return pts; } /* ------------------------------------------------------------------------- */ @@ -158,50 +157,52 @@ pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn) /* ------------------------------------------------------------------------- */ typedef struct _GstVaapiParserInfoMpeg2 GstVaapiParserInfoMpeg2; -struct _GstVaapiParserInfoMpeg2 { - GstVaapiMiniObject parent_instance; - GstMpegVideoPacket packet; - guint8 extension_type; /* for Extension packets */ - union { - GstMpegVideoSequenceHdr seq_hdr; - GstMpegVideoSequenceExt seq_ext; - GstMpegVideoSequenceDisplayExt seq_display_ext; - GstMpegVideoSequenceScalableExt seq_scalable_ext; - GstMpegVideoGop gop; - GstMpegVideoQuantMatrixExt quant_matrix; - GstMpegVideoPictureHdr pic_hdr; - GstMpegVideoPictureExt pic_ext; - GstMpegVideoSliceHdr slice_hdr; - } data; +struct _GstVaapiParserInfoMpeg2 +{ + GstVaapiMiniObject parent_instance; + GstMpegVideoPacket packet; + guint8 extension_type; /* for Extension packets */ + union + { + GstMpegVideoSequenceHdr seq_hdr; + GstMpegVideoSequenceExt seq_ext; + GstMpegVideoSequenceDisplayExt seq_display_ext; + GstMpegVideoSequenceScalableExt seq_scalable_ext; + GstMpegVideoGop gop; + GstMpegVideoQuantMatrixExt quant_matrix; + GstMpegVideoPictureHdr pic_hdr; + GstMpegVideoPictureExt pic_ext; + GstMpegVideoSliceHdr slice_hdr; + } data; }; static inline const GstVaapiMiniObjectClass * -gst_vaapi_parser_info_mpeg2_class(void) +gst_vaapi_parser_info_mpeg2_class (void) { - static const GstVaapiMiniObjectClass GstVaapiParserInfoMpeg2Class = { - sizeof(GstVaapiParserInfoMpeg2), - NULL - }; - return &GstVaapiParserInfoMpeg2Class; + static const GstVaapiMiniObjectClass GstVaapiParserInfoMpeg2Class = { + sizeof (GstVaapiParserInfoMpeg2), + NULL + }; + return &GstVaapiParserInfoMpeg2Class; } static inline GstVaapiParserInfoMpeg2 * -gst_vaapi_parser_info_mpeg2_new(void) +gst_vaapi_parser_info_mpeg2_new (void) { - return (GstVaapiParserInfoMpeg2 *) - gst_vaapi_mini_object_new(gst_vaapi_parser_info_mpeg2_class()); + return (GstVaapiParserInfoMpeg2 *) + gst_vaapi_mini_object_new (gst_vaapi_parser_info_mpeg2_class ()); } static inline GstVaapiParserInfoMpeg2 * -gst_vaapi_parser_info_mpeg2_ensure(GstVaapiParserInfoMpeg2 **pi_ptr) +gst_vaapi_parser_info_mpeg2_ensure (GstVaapiParserInfoMpeg2 ** pi_ptr) { - GstVaapiParserInfoMpeg2 *pi = *pi_ptr; + GstVaapiParserInfoMpeg2 *pi = *pi_ptr; - if (G_LIKELY(pi != NULL)) - return pi; - - *pi_ptr = pi = gst_vaapi_parser_info_mpeg2_new(); + if (G_LIKELY (pi != NULL)) return pi; + + *pi_ptr = pi = gst_vaapi_parser_info_mpeg2_new (); + return pi; } #define gst_vaapi_parser_info_mpeg2_ref(pi) \ @@ -221,57 +222,55 @@ gst_vaapi_parser_info_mpeg2_ensure(GstVaapiParserInfoMpeg2 **pi_ptr) #define GST_VAAPI_DECODER_MPEG2_CAST(decoder) \ ((GstVaapiDecoderMpeg2 *)(decoder)) -typedef struct _GstVaapiDecoderMpeg2Private GstVaapiDecoderMpeg2Private; -typedef struct _GstVaapiDecoderMpeg2Class GstVaapiDecoderMpeg2Class; +typedef struct _GstVaapiDecoderMpeg2Private GstVaapiDecoderMpeg2Private; +typedef struct _GstVaapiDecoderMpeg2Class GstVaapiDecoderMpeg2Class; -typedef enum { - GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR = 1 << 0, - GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT = 1 << 1, - GST_MPEG_VIDEO_STATE_GOT_PIC_HDR = 1 << 2, - GST_MPEG_VIDEO_STATE_GOT_PIC_EXT = 1 << 3, - GST_MPEG_VIDEO_STATE_GOT_SLICE = 1 << 4, +typedef enum +{ + GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR = 1 << 0, + GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT = 1 << 1, + GST_MPEG_VIDEO_STATE_GOT_PIC_HDR = 1 << 2, + GST_MPEG_VIDEO_STATE_GOT_PIC_EXT = 1 << 3, + GST_MPEG_VIDEO_STATE_GOT_SLICE = 1 << 4, - GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS = ( - GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| - GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT), - GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS = ( - GST_MPEG_VIDEO_STATE_GOT_PIC_HDR| - GST_MPEG_VIDEO_STATE_GOT_PIC_EXT), - GST_MPEG_VIDEO_STATE_VALID_PICTURE = ( - GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS| - GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS| - GST_MPEG_VIDEO_STATE_GOT_SLICE) + GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS = (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR | + GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT), + GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS = (GST_MPEG_VIDEO_STATE_GOT_PIC_HDR | + GST_MPEG_VIDEO_STATE_GOT_PIC_EXT), + GST_MPEG_VIDEO_STATE_VALID_PICTURE = (GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS | + GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS | GST_MPEG_VIDEO_STATE_GOT_SLICE) } GstMpegVideoState; -struct _GstVaapiDecoderMpeg2Private { - GstVaapiProfile profile; - GstVaapiProfile hw_profile; - guint width; - guint height; - guint fps_n; - guint fps_d; - guint state; - GstVaapiRectangle crop_rect; - GstVaapiParserInfoMpeg2 *seq_hdr; - GstVaapiParserInfoMpeg2 *seq_ext; - GstVaapiParserInfoMpeg2 *seq_display_ext; - GstVaapiParserInfoMpeg2 *seq_scalable_ext; - GstVaapiParserInfoMpeg2 *gop; - GstVaapiParserInfoMpeg2 *pic_hdr; - GstVaapiParserInfoMpeg2 *pic_ext; - GstVaapiParserInfoMpeg2 *pic_display_ext; - GstVaapiParserInfoMpeg2 *quant_matrix; - GstVaapiParserInfoMpeg2 *slice_hdr; - GstVaapiPicture *current_picture; - GstVaapiDpb *dpb; - PTSGenerator tsg; - guint is_opened : 1; - guint size_changed : 1; - guint profile_changed : 1; - guint quant_matrix_changed : 1; - guint progressive_sequence : 1; - guint closed_gop : 1; - guint broken_link : 1; +struct _GstVaapiDecoderMpeg2Private +{ + GstVaapiProfile profile; + GstVaapiProfile hw_profile; + guint width; + guint height; + guint fps_n; + guint fps_d; + guint state; + GstVaapiRectangle crop_rect; + GstVaapiParserInfoMpeg2 *seq_hdr; + GstVaapiParserInfoMpeg2 *seq_ext; + GstVaapiParserInfoMpeg2 *seq_display_ext; + GstVaapiParserInfoMpeg2 *seq_scalable_ext; + GstVaapiParserInfoMpeg2 *gop; + GstVaapiParserInfoMpeg2 *pic_hdr; + GstVaapiParserInfoMpeg2 *pic_ext; + GstVaapiParserInfoMpeg2 *pic_display_ext; + GstVaapiParserInfoMpeg2 *quant_matrix; + GstVaapiParserInfoMpeg2 *slice_hdr; + GstVaapiPicture *current_picture; + GstVaapiDpb *dpb; + PTSGenerator tsg; + guint is_opened:1; + guint size_changed:1; + guint profile_changed:1; + guint quant_matrix_changed:1; + guint progressive_sequence:1; + guint closed_gop:1; + guint broken_link:1; }; /** @@ -279,10 +278,11 @@ struct _GstVaapiDecoderMpeg2Private { * * A decoder based on Mpeg2. */ -struct _GstVaapiDecoderMpeg2 { - /*< private >*/ - GstVaapiDecoder parent_instance; - GstVaapiDecoderMpeg2Private priv; +struct _GstVaapiDecoderMpeg2 +{ + /*< private > */ + GstVaapiDecoder parent_instance; + GstVaapiDecoderMpeg2Private priv; }; /** @@ -290,1299 +290,1303 @@ struct _GstVaapiDecoderMpeg2 { * * A decoder class based on Mpeg2. */ -struct _GstVaapiDecoderMpeg2Class { - /*< private >*/ - GstVaapiDecoderClass parent_class; +struct _GstVaapiDecoderMpeg2Class +{ + /*< private > */ + GstVaapiDecoderClass parent_class; }; static void -gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder) +gst_vaapi_decoder_mpeg2_close (GstVaapiDecoderMpeg2 * decoder) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; - gst_vaapi_picture_replace(&priv->current_picture, NULL); + gst_vaapi_picture_replace (&priv->current_picture, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->seq_hdr, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->seq_scalable_ext, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->gop, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->pic_hdr, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->pic_display_ext, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->slice_hdr, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->seq_hdr, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->seq_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->seq_display_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->seq_scalable_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->gop, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->pic_hdr, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->pic_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->pic_display_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->quant_matrix, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->slice_hdr, NULL); - priv->state = 0; + priv->state = 0; - gst_vaapi_dpb_replace(&priv->dpb, NULL); + gst_vaapi_dpb_replace (&priv->dpb, NULL); } static gboolean -gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder) +gst_vaapi_decoder_mpeg2_open (GstVaapiDecoderMpeg2 * decoder) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; - gst_vaapi_decoder_mpeg2_close(decoder); + gst_vaapi_decoder_mpeg2_close (decoder); - priv->dpb = gst_vaapi_dpb_new(2); - if (!priv->dpb) - return FALSE; + priv->dpb = gst_vaapi_dpb_new (2); + if (!priv->dpb) + return FALSE; - pts_init(&priv->tsg); - return TRUE; + pts_init (&priv->tsg); + return TRUE; } static void -gst_vaapi_decoder_mpeg2_destroy(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_mpeg2_destroy (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderMpeg2 * const decoder = - GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); + GstVaapiDecoderMpeg2 *const decoder = + GST_VAAPI_DECODER_MPEG2_CAST (base_decoder); - gst_vaapi_decoder_mpeg2_close(decoder); + gst_vaapi_decoder_mpeg2_close (decoder); } static gboolean -gst_vaapi_decoder_mpeg2_create(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_mpeg2_create (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderMpeg2 * const decoder = - GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; + GstVaapiDecoderMpeg2 *const decoder = + GST_VAAPI_DECODER_MPEG2_CAST (base_decoder); + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; - priv->hw_profile = GST_VAAPI_PROFILE_UNKNOWN; - priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; - priv->profile_changed = TRUE; /* Allow fallbacks to work */ - return TRUE; + priv->hw_profile = GST_VAAPI_PROFILE_UNKNOWN; + priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; + priv->profile_changed = TRUE; /* Allow fallbacks to work */ + return TRUE; } static inline void -copy_quant_matrix(guint8 dst[64], const guint8 src[64]) +copy_quant_matrix (guint8 dst[64], const guint8 src[64]) { - memcpy(dst, src, 64); + memcpy (dst, src, 64); } static const char * -get_profile_str(GstVaapiProfile profile) +get_profile_str (GstVaapiProfile profile) { - char *str; + char *str; - switch (profile) { - case GST_VAAPI_PROFILE_MPEG2_SIMPLE: str = "simple"; break; - case GST_VAAPI_PROFILE_MPEG2_MAIN: str = "main"; break; - case GST_VAAPI_PROFILE_MPEG2_HIGH: str = "high"; break; - default: str = ""; break; - } - return str; + switch (profile) { + case GST_VAAPI_PROFILE_MPEG2_SIMPLE: + str = "simple"; + break; + case GST_VAAPI_PROFILE_MPEG2_MAIN: + str = "main"; + break; + case GST_VAAPI_PROFILE_MPEG2_HIGH: + str = "high"; + break; + default: + str = ""; + break; + } + return str; } static GstVaapiProfile -get_profile(GstVaapiDecoderMpeg2 *decoder, GstVaapiEntrypoint entrypoint) +get_profile (GstVaapiDecoderMpeg2 * decoder, GstVaapiEntrypoint entrypoint) { - GstVaapiDisplay * const va_display = GST_VAAPI_DECODER_DISPLAY(decoder); - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstVaapiProfile profile = priv->profile; + GstVaapiDisplay *const va_display = GST_VAAPI_DECODER_DISPLAY (decoder); + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstVaapiProfile profile = priv->profile; - do { - /* Return immediately if the exact same profile was found */ - if (gst_vaapi_display_has_decoder(va_display, profile, entrypoint)) - break; + do { + /* Return immediately if the exact same profile was found */ + if (gst_vaapi_display_has_decoder (va_display, profile, entrypoint)) + break; - /* Otherwise, try to map to a higher profile */ - switch (profile) { - case GST_VAAPI_PROFILE_MPEG2_SIMPLE: - profile = GST_VAAPI_PROFILE_MPEG2_MAIN; - break; - case GST_VAAPI_PROFILE_MPEG2_MAIN: - profile = GST_VAAPI_PROFILE_MPEG2_HIGH; - break; - case GST_VAAPI_PROFILE_MPEG2_HIGH: - // Try to map to main profile if no high profile specific bits used - if (priv->profile == profile && - !priv->seq_scalable_ext && - (priv->seq_ext && - priv->seq_ext->data.seq_ext.chroma_format == 1)) { - profile = GST_VAAPI_PROFILE_MPEG2_MAIN; - break; - } - // fall-through - default: - profile = GST_VAAPI_PROFILE_UNKNOWN; - break; + /* Otherwise, try to map to a higher profile */ + switch (profile) { + case GST_VAAPI_PROFILE_MPEG2_SIMPLE: + profile = GST_VAAPI_PROFILE_MPEG2_MAIN; + break; + case GST_VAAPI_PROFILE_MPEG2_MAIN: + profile = GST_VAAPI_PROFILE_MPEG2_HIGH; + break; + case GST_VAAPI_PROFILE_MPEG2_HIGH: + // Try to map to main profile if no high profile specific bits used + if (priv->profile == profile && + !priv->seq_scalable_ext && + (priv->seq_ext && priv->seq_ext->data.seq_ext.chroma_format == 1)) { + profile = GST_VAAPI_PROFILE_MPEG2_MAIN; + break; } - } while (profile != GST_VAAPI_PROFILE_UNKNOWN); + // fall-through + default: + profile = GST_VAAPI_PROFILE_UNKNOWN; + break; + } + } while (profile != GST_VAAPI_PROFILE_UNKNOWN); - if (profile != priv->profile) - GST_INFO("forced %s profile to %s profile", - get_profile_str(priv->profile), get_profile_str(profile)); - return profile; + if (profile != priv->profile) + GST_INFO ("forced %s profile to %s profile", + get_profile_str (priv->profile), get_profile_str (profile)); + return profile; } static GstVaapiDecoderStatus -ensure_context(GstVaapiDecoderMpeg2 *decoder) +ensure_context (GstVaapiDecoderMpeg2 * decoder) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; - gboolean reset_context = FALSE; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; + gboolean reset_context = FALSE; - if (priv->profile_changed) { - GST_DEBUG("profile changed"); - priv->profile_changed = FALSE; - reset_context = TRUE; + if (priv->profile_changed) { + GST_DEBUG ("profile changed"); + priv->profile_changed = FALSE; + reset_context = TRUE; - priv->hw_profile = get_profile(decoder, entrypoint); - if (priv->hw_profile == GST_VAAPI_PROFILE_UNKNOWN) - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - } + priv->hw_profile = get_profile (decoder, entrypoint); + if (priv->hw_profile == GST_VAAPI_PROFILE_UNKNOWN) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } - if (priv->size_changed) { - GST_DEBUG("size changed"); - priv->size_changed = FALSE; - reset_context = TRUE; - } + if (priv->size_changed) { + GST_DEBUG ("size changed"); + priv->size_changed = FALSE; + reset_context = TRUE; + } - if (reset_context) { - GstVaapiContextInfo info; + if (reset_context) { + GstVaapiContextInfo info; - info.profile = priv->hw_profile; - info.entrypoint = entrypoint; - info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - info.width = priv->width; - info.height = priv->height; - info.ref_frames = 2; - reset_context = gst_vaapi_decoder_ensure_context( - GST_VAAPI_DECODER_CAST(decoder), - &info - ); - if (!reset_context) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; + info.profile = priv->hw_profile; + info.entrypoint = entrypoint; + info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + info.width = priv->width; + info.height = priv->height; + info.ref_frames = 2; + reset_context = + gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER_CAST (decoder), + &info); + if (!reset_context) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) +ensure_quant_matrix (GstVaapiDecoderMpeg2 * decoder, GstVaapiPicture * picture) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr->data.seq_hdr; - VAIQMatrixBufferMPEG2 *iq_matrix; - guint8 *intra_quant_matrix = NULL; - guint8 *non_intra_quant_matrix = NULL; - guint8 *chroma_intra_quant_matrix = NULL; - guint8 *chroma_non_intra_quant_matrix = NULL; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoSequenceHdr *const seq_hdr = &priv->seq_hdr->data.seq_hdr; + VAIQMatrixBufferMPEG2 *iq_matrix; + guint8 *intra_quant_matrix = NULL; + guint8 *non_intra_quant_matrix = NULL; + guint8 *chroma_intra_quant_matrix = NULL; + guint8 *chroma_non_intra_quant_matrix = NULL; - if (!priv->quant_matrix_changed) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - priv->quant_matrix_changed = FALSE; - - picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(MPEG2, 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; - - intra_quant_matrix = seq_hdr->intra_quantizer_matrix; - non_intra_quant_matrix = seq_hdr->non_intra_quantizer_matrix; - - if (priv->quant_matrix) { - GstMpegVideoQuantMatrixExt * const quant_matrix = - &priv->quant_matrix->data.quant_matrix; - if (quant_matrix->load_intra_quantiser_matrix) - intra_quant_matrix = quant_matrix->intra_quantiser_matrix; - if (quant_matrix->load_non_intra_quantiser_matrix) - non_intra_quant_matrix = quant_matrix->non_intra_quantiser_matrix; - if (quant_matrix->load_chroma_intra_quantiser_matrix) - chroma_intra_quant_matrix = quant_matrix->chroma_intra_quantiser_matrix; - if (quant_matrix->load_chroma_non_intra_quantiser_matrix) - chroma_non_intra_quant_matrix = quant_matrix->chroma_non_intra_quantiser_matrix; - } - - iq_matrix->load_intra_quantiser_matrix = intra_quant_matrix != NULL; - if (intra_quant_matrix) - copy_quant_matrix(iq_matrix->intra_quantiser_matrix, - intra_quant_matrix); - - iq_matrix->load_non_intra_quantiser_matrix = non_intra_quant_matrix != NULL; - if (non_intra_quant_matrix) - copy_quant_matrix(iq_matrix->non_intra_quantiser_matrix, - non_intra_quant_matrix); - - iq_matrix->load_chroma_intra_quantiser_matrix = chroma_intra_quant_matrix != NULL; - if (chroma_intra_quant_matrix) - copy_quant_matrix(iq_matrix->chroma_intra_quantiser_matrix, - chroma_intra_quant_matrix); - - iq_matrix->load_chroma_non_intra_quantiser_matrix = chroma_non_intra_quant_matrix != NULL; - if (chroma_non_intra_quant_matrix) - copy_quant_matrix(iq_matrix->chroma_non_intra_quantiser_matrix, - chroma_non_intra_quant_matrix); + if (!priv->quant_matrix_changed) return GST_VAAPI_DECODER_STATUS_SUCCESS; + + priv->quant_matrix_changed = FALSE; + + picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW (MPEG2, 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; + + intra_quant_matrix = seq_hdr->intra_quantizer_matrix; + non_intra_quant_matrix = seq_hdr->non_intra_quantizer_matrix; + + if (priv->quant_matrix) { + GstMpegVideoQuantMatrixExt *const quant_matrix = + &priv->quant_matrix->data.quant_matrix; + if (quant_matrix->load_intra_quantiser_matrix) + intra_quant_matrix = quant_matrix->intra_quantiser_matrix; + if (quant_matrix->load_non_intra_quantiser_matrix) + non_intra_quant_matrix = quant_matrix->non_intra_quantiser_matrix; + if (quant_matrix->load_chroma_intra_quantiser_matrix) + chroma_intra_quant_matrix = quant_matrix->chroma_intra_quantiser_matrix; + if (quant_matrix->load_chroma_non_intra_quantiser_matrix) + chroma_non_intra_quant_matrix = + quant_matrix->chroma_non_intra_quantiser_matrix; + } + + iq_matrix->load_intra_quantiser_matrix = intra_quant_matrix != NULL; + if (intra_quant_matrix) + copy_quant_matrix (iq_matrix->intra_quantiser_matrix, intra_quant_matrix); + + iq_matrix->load_non_intra_quantiser_matrix = non_intra_quant_matrix != NULL; + if (non_intra_quant_matrix) + copy_quant_matrix (iq_matrix->non_intra_quantiser_matrix, + non_intra_quant_matrix); + + iq_matrix->load_chroma_intra_quantiser_matrix = + chroma_intra_quant_matrix != NULL; + if (chroma_intra_quant_matrix) + copy_quant_matrix (iq_matrix->chroma_intra_quantiser_matrix, + chroma_intra_quant_matrix); + + iq_matrix->load_chroma_non_intra_quantiser_matrix = + chroma_non_intra_quant_matrix != NULL; + if (chroma_non_intra_quant_matrix) + copy_quant_matrix (iq_matrix->chroma_non_intra_quantiser_matrix, + chroma_non_intra_quant_matrix); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static inline gboolean -is_valid_state(GstVaapiDecoderMpeg2 *decoder, guint state) +is_valid_state (GstVaapiDecoderMpeg2 * decoder, guint state) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; - return (priv->state & state) == state; + return (priv->state & state) == state; } static GstVaapiDecoderStatus -decode_current_picture(GstVaapiDecoderMpeg2 *decoder) +decode_current_picture (GstVaapiDecoderMpeg2 * decoder) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstVaapiPicture * const picture = priv->current_picture; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstVaapiPicture *const picture = priv->current_picture; - if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PICTURE)) - goto drop_frame; - priv->state &= GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS; + if (!is_valid_state (decoder, GST_MPEG_VIDEO_STATE_VALID_PICTURE)) + goto drop_frame; + priv->state &= GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS; - if (!picture) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - if (!gst_vaapi_picture_decode(picture)) - goto error; - if (GST_VAAPI_PICTURE_IS_COMPLETE(picture)) { - if (!gst_vaapi_dpb_add(priv->dpb, picture)) - goto error; - gst_vaapi_picture_replace(&priv->current_picture, NULL); - } + if (!picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_vaapi_picture_decode (picture)) + goto error; + if (GST_VAAPI_PICTURE_IS_COMPLETE (picture)) { + if (!gst_vaapi_dpb_add (priv->dpb, picture)) + goto error; + gst_vaapi_picture_replace (&priv->current_picture, NULL); + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; + 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; + /* 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; drop_frame: - priv->state &= GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS; - return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; + priv->state &= GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; } static GstVaapiDecoderStatus -parse_sequence(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) +parse_sequence (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit, const GstMpegVideoPacket * packet) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoSequenceHdr *seq_hdr; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoSequenceHdr *seq_hdr; - priv->state = 0; + priv->state = 0; - if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_hdr)) { - GST_ERROR("failed to allocate parser info for sequence header"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } + if (!gst_vaapi_parser_info_mpeg2_ensure (&priv->seq_hdr)) { + GST_ERROR ("failed to allocate parser info for sequence header"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } - seq_hdr = &priv->seq_hdr->data.seq_hdr; + seq_hdr = &priv->seq_hdr->data.seq_hdr; - if (!gst_mpeg_video_packet_parse_sequence_header(packet, seq_hdr)) { - GST_ERROR("failed to parse sequence header"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + if (!gst_mpeg_video_packet_parse_sequence_header (packet, seq_hdr)) { + GST_ERROR ("failed to parse sequence header"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } - gst_vaapi_decoder_unit_set_parsed_info(unit, seq_hdr, NULL); + gst_vaapi_decoder_unit_set_parsed_info (unit, seq_hdr, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence (GstVaapiDecoderMpeg2 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER_CAST (decoder); + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoSequenceHdr *const seq_hdr = unit->parsed_info; + + gst_vaapi_parser_info_mpeg2_replace (&priv->seq_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->seq_display_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->seq_scalable_ext, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->quant_matrix, NULL); + gst_vaapi_parser_info_mpeg2_replace (&priv->pic_display_ext, NULL); + + priv->fps_n = seq_hdr->fps_n; + priv->fps_d = seq_hdr->fps_d; + pts_set_framerate (&priv->tsg, priv->fps_n, priv->fps_d); + gst_vaapi_decoder_set_framerate (base_decoder, priv->fps_n, priv->fps_d); + + priv->width = seq_hdr->width; + priv->height = seq_hdr->height; + priv->size_changed = TRUE; + priv->quant_matrix_changed = TRUE; + priv->progressive_sequence = TRUE; + + priv->state |= GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR; + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +parse_sequence_ext (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit, const GstMpegVideoPacket * packet) +{ + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoSequenceExt *seq_ext; + + priv->state &= GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR; + + if (!gst_vaapi_parser_info_mpeg2_ensure (&priv->seq_ext)) { + GST_ERROR ("failed to allocate parser info for sequence extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + seq_ext = &priv->seq_ext->data.seq_ext; + + if (!gst_mpeg_video_packet_parse_sequence_extension (packet, seq_ext)) { + GST_ERROR ("failed to parse sequence-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + gst_vaapi_decoder_unit_set_parsed_info (unit, seq_ext, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +decode_sequence_ext (GstVaapiDecoderMpeg2 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER_CAST (decoder); + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoSequenceExt *const seq_ext = unit->parsed_info; + GstVaapiProfile profile; + guint width, height; + + if (!is_valid_state (decoder, GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR)) return GST_VAAPI_DECODER_STATUS_SUCCESS; -} -static GstVaapiDecoderStatus -decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) -{ - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoSequenceHdr * const seq_hdr = unit->parsed_info; + priv->progressive_sequence = seq_ext->progressive; + gst_vaapi_decoder_set_interlaced (base_decoder, !priv->progressive_sequence); - gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->seq_scalable_ext, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, NULL); - gst_vaapi_parser_info_mpeg2_replace(&priv->pic_display_ext, NULL); + width = (priv->width & 0x0fff) | ((guint32) seq_ext->horiz_size_ext << 12); + height = (priv->height & 0x0fff) | ((guint32) seq_ext->vert_size_ext << 12); + GST_DEBUG ("video resolution %ux%u", width, height); - priv->fps_n = seq_hdr->fps_n; - priv->fps_d = seq_hdr->fps_d; - pts_set_framerate(&priv->tsg, priv->fps_n, priv->fps_d); - gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); + if (seq_ext->fps_n_ext && seq_ext->fps_d_ext) { + priv->fps_n *= seq_ext->fps_n_ext + 1; + priv->fps_d *= seq_ext->fps_d_ext + 1; + pts_set_framerate (&priv->tsg, priv->fps_n, priv->fps_d); + gst_vaapi_decoder_set_framerate (base_decoder, priv->fps_n, priv->fps_d); + } - priv->width = seq_hdr->width; - priv->height = seq_hdr->height; - priv->size_changed = TRUE; - priv->quant_matrix_changed = TRUE; - priv->progressive_sequence = TRUE; + if (priv->width != width) { + priv->width = width; + priv->size_changed = TRUE; + } - priv->state |= GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR; - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} + if (priv->height != height) { + priv->height = height; + priv->size_changed = TRUE; + } -static GstVaapiDecoderStatus -parse_sequence_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) -{ - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoSequenceExt *seq_ext; - - priv->state &= GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR; - - if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_ext)) { - GST_ERROR("failed to allocate parser info for sequence extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - - seq_ext = &priv->seq_ext->data.seq_ext; - - if (!gst_mpeg_video_packet_parse_sequence_extension(packet, seq_ext)) { - GST_ERROR("failed to parse sequence-extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } - - gst_vaapi_decoder_unit_set_parsed_info(unit, seq_ext, NULL); - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) -{ - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder); - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoSequenceExt * const seq_ext = unit->parsed_info; - GstVaapiProfile profile; - guint width, height; - - if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR)) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - priv->progressive_sequence = seq_ext->progressive; - gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence); - - width = (priv->width & 0x0fff) | ((guint32)seq_ext->horiz_size_ext << 12); - height = (priv->height & 0x0fff) | ((guint32)seq_ext->vert_size_ext << 12); - GST_DEBUG("video resolution %ux%u", width, height); - - if (seq_ext->fps_n_ext && seq_ext->fps_d_ext) { - priv->fps_n *= seq_ext->fps_n_ext + 1; - priv->fps_d *= seq_ext->fps_d_ext + 1; - pts_set_framerate(&priv->tsg, priv->fps_n, priv->fps_d); - gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); - } - - if (priv->width != width) { - priv->width = width; - priv->size_changed = TRUE; - } - - if (priv->height != height) { - priv->height = height; - priv->size_changed = TRUE; - } - - switch (seq_ext->profile) { + switch (seq_ext->profile) { case GST_MPEG_VIDEO_PROFILE_SIMPLE: - profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; - break; + profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; + break; case GST_MPEG_VIDEO_PROFILE_MAIN: - profile = GST_VAAPI_PROFILE_MPEG2_MAIN; - break; + profile = GST_VAAPI_PROFILE_MPEG2_MAIN; + break; case GST_MPEG_VIDEO_PROFILE_HIGH: - profile = GST_VAAPI_PROFILE_MPEG2_HIGH; - break; + profile = GST_VAAPI_PROFILE_MPEG2_HIGH; + break; default: - GST_ERROR("unsupported profile %d", seq_ext->profile); - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - } - if (priv->profile != profile) { - priv->profile = profile; - priv->profile_changed = TRUE; - } + GST_ERROR ("unsupported profile %d", seq_ext->profile); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + if (priv->profile != profile) { + priv->profile = profile; + priv->profile_changed = TRUE; + } - priv->state |= GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + priv->state |= GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) +parse_sequence_display_ext (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit, const GstMpegVideoPacket * packet) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoSequenceDisplayExt *seq_display_ext; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoSequenceDisplayExt *seq_display_ext; - if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_display_ext)) { - GST_ERROR("failed to allocate parser info for sequence display extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } + if (!gst_vaapi_parser_info_mpeg2_ensure (&priv->seq_display_ext)) { + GST_ERROR ("failed to allocate parser info for sequence display extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } - seq_display_ext = &priv->seq_display_ext->data.seq_display_ext; + seq_display_ext = &priv->seq_display_ext->data.seq_display_ext; - if (!gst_mpeg_video_packet_parse_sequence_display_extension(packet, - seq_display_ext)) { - GST_ERROR("failed to parse sequence-display-extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + if (!gst_mpeg_video_packet_parse_sequence_display_extension (packet, + seq_display_ext)) { + GST_ERROR ("failed to parse sequence-display-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } - gst_vaapi_decoder_unit_set_parsed_info(unit, seq_display_ext, NULL); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_vaapi_decoder_unit_set_parsed_info (unit, seq_display_ext, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit) +decode_sequence_display_ext (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoSequenceDisplayExt *seq_display_ext; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoSequenceDisplayExt *seq_display_ext; - seq_display_ext = priv->seq_display_ext ? - &priv->seq_display_ext->data.seq_display_ext : NULL; + seq_display_ext = priv->seq_display_ext ? + &priv->seq_display_ext->data.seq_display_ext : NULL; - /* Update cropping rectangle */ - if (seq_display_ext) { - GstVaapiRectangle * const crop_rect = &priv->crop_rect; - crop_rect->x = 0; - crop_rect->y = 0; - crop_rect->width = seq_display_ext->display_horizontal_size; - crop_rect->height = seq_display_ext->display_vertical_size; - } + /* Update cropping rectangle */ + if (seq_display_ext) { + GstVaapiRectangle *const crop_rect = &priv->crop_rect; + crop_rect->x = 0; + crop_rect->y = 0; + crop_rect->width = seq_display_ext->display_horizontal_size; + crop_rect->height = seq_display_ext->display_vertical_size; + } - /* XXX: handle color primaries */ - return GST_VAAPI_DECODER_STATUS_SUCCESS; + /* XXX: handle color primaries */ + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_sequence_scalable_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) +parse_sequence_scalable_ext (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit, const GstMpegVideoPacket * packet) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoSequenceScalableExt *seq_scalable_ext; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoSequenceScalableExt *seq_scalable_ext; - if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_scalable_ext)) { - GST_ERROR("failed to allocate parser info for sequence scalable extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } + if (!gst_vaapi_parser_info_mpeg2_ensure (&priv->seq_scalable_ext)) { + GST_ERROR + ("failed to allocate parser info for sequence scalable extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } - seq_scalable_ext = &priv->seq_scalable_ext->data.seq_scalable_ext; + seq_scalable_ext = &priv->seq_scalable_ext->data.seq_scalable_ext; - if (!gst_mpeg_video_packet_parse_sequence_scalable_extension(packet, - seq_scalable_ext)) { - GST_ERROR("failed to parse sequence-scalable-extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + if (!gst_mpeg_video_packet_parse_sequence_scalable_extension (packet, + seq_scalable_ext)) { + GST_ERROR ("failed to parse sequence-scalable-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } - gst_vaapi_decoder_unit_set_parsed_info(unit, seq_scalable_ext, NULL); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_vaapi_decoder_unit_set_parsed_info (unit, seq_scalable_ext, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_sequence_scalable_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit) +decode_sequence_scalable_ext (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit) { - /* XXX: unsupported header -- ignore */ - return GST_VAAPI_DECODER_STATUS_SUCCESS; + /* XXX: unsupported header -- ignore */ + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_sequence_end(GstVaapiDecoderMpeg2 *decoder) +decode_sequence_end (GstVaapiDecoderMpeg2 * decoder) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; - if (priv->dpb) - gst_vaapi_dpb_flush(priv->dpb); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (priv->dpb) + gst_vaapi_dpb_flush (priv->dpb); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) +parse_quant_matrix_ext (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit, const GstMpegVideoPacket * packet) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoQuantMatrixExt *quant_matrix; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoQuantMatrixExt *quant_matrix; - if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->quant_matrix)) { - GST_ERROR("failed to allocate parser info for quantization matrix"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } + if (!gst_vaapi_parser_info_mpeg2_ensure (&priv->quant_matrix)) { + GST_ERROR ("failed to allocate parser info for quantization matrix"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } - quant_matrix = &priv->quant_matrix->data.quant_matrix; + quant_matrix = &priv->quant_matrix->data.quant_matrix; - if (!gst_mpeg_video_packet_parse_quant_matrix_extension(packet, - quant_matrix)) { - GST_ERROR("failed to parse quant-matrix-extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + if (!gst_mpeg_video_packet_parse_quant_matrix_extension (packet, + quant_matrix)) { + GST_ERROR ("failed to parse quant-matrix-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } - gst_vaapi_decoder_unit_set_parsed_info(unit, quant_matrix, NULL); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_vaapi_decoder_unit_set_parsed_info (unit, quant_matrix, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit) +decode_quant_matrix_ext (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; - priv->quant_matrix_changed = TRUE; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + priv->quant_matrix_changed = TRUE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_gop(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) +parse_gop (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit, const GstMpegVideoPacket * packet) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoGop *gop; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoGop *gop; - if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->gop)) { - GST_ERROR("failed to allocate parser info for GOP"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } + if (!gst_vaapi_parser_info_mpeg2_ensure (&priv->gop)) { + GST_ERROR ("failed to allocate parser info for GOP"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } - gop = &priv->gop->data.gop; + gop = &priv->gop->data.gop; - if (!gst_mpeg_video_packet_parse_gop(packet, gop)) { - GST_ERROR("failed to parse GOP"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + if (!gst_mpeg_video_packet_parse_gop (packet, gop)) { + GST_ERROR ("failed to parse GOP"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } - gst_vaapi_decoder_unit_set_parsed_info(unit, gop, NULL); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_vaapi_decoder_unit_set_parsed_info (unit, gop, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) +decode_gop (GstVaapiDecoderMpeg2 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoGop * const gop = unit->parsed_info; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoGop *const gop = unit->parsed_info; - priv->closed_gop = gop->closed_gop; - priv->broken_link = gop->broken_link; + priv->closed_gop = gop->closed_gop; + priv->broken_link = gop->broken_link; - GST_DEBUG("GOP %02u:%02u:%02u:%02u (closed_gop %d, broken_link %d)", - gop->hour, gop->minute, gop->second, gop->frame, - priv->closed_gop, priv->broken_link); + GST_DEBUG ("GOP %02u:%02u:%02u:%02u (closed_gop %d, broken_link %d)", + gop->hour, gop->minute, gop->second, gop->frame, + priv->closed_gop, priv->broken_link); - pts_sync(&priv->tsg, GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + pts_sync (&priv->tsg, GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_picture(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) +parse_picture (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit, const GstMpegVideoPacket * packet) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoPictureHdr *pic_hdr; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoPictureHdr *pic_hdr; - priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| - GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT); + priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR | + GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT); - if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->pic_hdr)) { - GST_ERROR("failed to allocate parser info for picture header"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } + if (!gst_vaapi_parser_info_mpeg2_ensure (&priv->pic_hdr)) { + GST_ERROR ("failed to allocate parser info for picture header"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } - pic_hdr = &priv->pic_hdr->data.pic_hdr; + pic_hdr = &priv->pic_hdr->data.pic_hdr; - if (!gst_mpeg_video_packet_parse_picture_header(packet, pic_hdr)) { - GST_ERROR("failed to parse picture header"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + if (!gst_mpeg_video_packet_parse_picture_header (packet, pic_hdr)) { + GST_ERROR ("failed to parse picture header"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } - gst_vaapi_decoder_unit_set_parsed_info(unit, pic_hdr, NULL); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_vaapi_decoder_unit_set_parsed_info (unit, pic_hdr, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) +decode_picture (GstVaapiDecoderMpeg2 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; - if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS)) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, NULL); - - priv->state |= GST_MPEG_VIDEO_STATE_GOT_PIC_HDR; + if (!is_valid_state (decoder, GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS)) return GST_VAAPI_DECODER_STATUS_SUCCESS; + + gst_vaapi_parser_info_mpeg2_replace (&priv->pic_ext, NULL); + + priv->state |= GST_MPEG_VIDEO_STATE_GOT_PIC_HDR; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -parse_picture_ext(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) +parse_picture_ext (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit, const GstMpegVideoPacket * packet) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoPictureExt *pic_ext; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoPictureExt *pic_ext; - priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| - GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT| - GST_MPEG_VIDEO_STATE_GOT_PIC_HDR); + priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR | + GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT | GST_MPEG_VIDEO_STATE_GOT_PIC_HDR); - if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->pic_ext)) { - GST_ERROR("failed to allocate parser info for picture extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } + if (!gst_vaapi_parser_info_mpeg2_ensure (&priv->pic_ext)) { + GST_ERROR ("failed to allocate parser info for picture extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } - pic_ext = &priv->pic_ext->data.pic_ext; + pic_ext = &priv->pic_ext->data.pic_ext; - if (!gst_mpeg_video_packet_parse_picture_extension(packet, pic_ext)) { - GST_ERROR("failed to parse picture-extension"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + if (!gst_mpeg_video_packet_parse_picture_extension (packet, pic_ext)) { + GST_ERROR ("failed to parse picture-extension"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } - gst_vaapi_decoder_unit_set_parsed_info(unit, pic_ext, NULL); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_vaapi_decoder_unit_set_parsed_info (unit, pic_ext, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) +decode_picture_ext (GstVaapiDecoderMpeg2 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoPictureExt * const pic_ext = unit->parsed_info; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoPictureExt *const pic_ext = unit->parsed_info; - if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_GOT_PIC_HDR)) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - if (priv->progressive_sequence && !pic_ext->progressive_frame) { - GST_WARNING("invalid interlaced frame in progressive sequence, fixing"); - pic_ext->progressive_frame = 1; - } - - if (pic_ext->picture_structure == 0 || - (pic_ext->progressive_frame && - pic_ext->picture_structure != GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME)) { - GST_WARNING("invalid picture_structure %d, replacing with \"frame\"", - pic_ext->picture_structure); - pic_ext->picture_structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME; - } - - priv->state |= GST_MPEG_VIDEO_STATE_GOT_PIC_EXT; + if (!is_valid_state (decoder, GST_MPEG_VIDEO_STATE_GOT_PIC_HDR)) return GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (priv->progressive_sequence && !pic_ext->progressive_frame) { + GST_WARNING ("invalid interlaced frame in progressive sequence, fixing"); + pic_ext->progressive_frame = 1; + } + + if (pic_ext->picture_structure == 0 || + (pic_ext->progressive_frame && + pic_ext->picture_structure != + GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME)) { + GST_WARNING ("invalid picture_structure %d, replacing with \"frame\"", + pic_ext->picture_structure); + pic_ext->picture_structure = GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME; + } + + priv->state |= GST_MPEG_VIDEO_STATE_GOT_PIC_EXT; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static inline guint32 -pack_f_code(guint8 f_code[2][2]) +pack_f_code (guint8 f_code[2][2]) { - return (((guint32)f_code[0][0] << 12) | - ((guint32)f_code[0][1] << 8) | - ((guint32)f_code[1][0] << 4) | - ( f_code[1][1] )); + return (((guint32) f_code[0][0] << 12) | + ((guint32) f_code[0][1] << 8) | + ((guint32) f_code[1][0] << 4) | (f_code[1][1])); } static GstVaapiDecoderStatus -init_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) +init_picture (GstVaapiDecoderMpeg2 * decoder, GstVaapiPicture * picture) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr->data.pic_hdr; - GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext->data.pic_ext; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoPictureHdr *const pic_hdr = &priv->pic_hdr->data.pic_hdr; + GstMpegVideoPictureExt *const pic_ext = &priv->pic_ext->data.pic_ext; - switch (pic_hdr->pic_type) { + switch (pic_hdr->pic_type) { case GST_MPEG_VIDEO_PICTURE_TYPE_I: - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - picture->type = GST_VAAPI_PICTURE_TYPE_I; - break; + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + picture->type = GST_VAAPI_PICTURE_TYPE_I; + break; case GST_MPEG_VIDEO_PICTURE_TYPE_P: - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - picture->type = GST_VAAPI_PICTURE_TYPE_P; - break; + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + picture->type = GST_VAAPI_PICTURE_TYPE_P; + break; case GST_MPEG_VIDEO_PICTURE_TYPE_B: - picture->type = GST_VAAPI_PICTURE_TYPE_B; - break; + picture->type = GST_VAAPI_PICTURE_TYPE_B; + break; default: - GST_ERROR("unsupported picture type %d", pic_hdr->pic_type); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } + GST_ERROR ("unsupported picture type %d", pic_hdr->pic_type); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } - if (!priv->progressive_sequence && !pic_ext->progressive_frame) { - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED); - if (pic_ext->top_field_first) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF); - } + if (!priv->progressive_sequence && !pic_ext->progressive_frame) { + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_INTERLACED); + if (pic_ext->top_field_first) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_TFF); + } - switch (pic_ext->picture_structure) { + switch (pic_ext->picture_structure) { case GST_MPEG_VIDEO_PICTURE_STRUCTURE_TOP_FIELD: - picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; - break; + picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + break; case GST_MPEG_VIDEO_PICTURE_STRUCTURE_BOTTOM_FIELD: - picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; - break; + picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + break; case GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME: - picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - break; + picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + break; + } + + /* Allocate dummy picture for first field based I-frame */ + if (picture->type == GST_VAAPI_PICTURE_TYPE_I && + !GST_VAAPI_PICTURE_IS_FRAME (picture) && + gst_vaapi_dpb_size (priv->dpb) == 0) { + GstVaapiPicture *dummy_picture; + gboolean success; + + dummy_picture = GST_VAAPI_PICTURE_NEW (MPEG2, decoder); + if (!dummy_picture) { + GST_ERROR ("failed to allocate dummy picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } - /* Allocate dummy picture for first field based I-frame */ - if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - !GST_VAAPI_PICTURE_IS_FRAME(picture) && - gst_vaapi_dpb_size(priv->dpb) == 0) { - GstVaapiPicture *dummy_picture; - gboolean success; + dummy_picture->type = GST_VAAPI_PICTURE_TYPE_I; + dummy_picture->pts = GST_CLOCK_TIME_NONE; + dummy_picture->poc = -1; + dummy_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - dummy_picture = GST_VAAPI_PICTURE_NEW(MPEG2, decoder); - if (!dummy_picture) { - GST_ERROR("failed to allocate dummy picture"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - - dummy_picture->type = GST_VAAPI_PICTURE_TYPE_I; - dummy_picture->pts = GST_CLOCK_TIME_NONE; - dummy_picture->poc = -1; - dummy_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - - GST_VAAPI_PICTURE_FLAG_SET( - dummy_picture, - (GST_VAAPI_PICTURE_FLAG_SKIPPED | - GST_VAAPI_PICTURE_FLAG_OUTPUT | - GST_VAAPI_PICTURE_FLAG_REFERENCE) + GST_VAAPI_PICTURE_FLAG_SET (dummy_picture, + (GST_VAAPI_PICTURE_FLAG_SKIPPED | + GST_VAAPI_PICTURE_FLAG_OUTPUT | GST_VAAPI_PICTURE_FLAG_REFERENCE) ); - success = gst_vaapi_dpb_add(priv->dpb, dummy_picture); - gst_vaapi_picture_unref(dummy_picture); - if (!success) { - GST_ERROR("failed to add dummy picture into DPB"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - GST_INFO("allocated dummy picture for first field based I-frame"); + success = gst_vaapi_dpb_add (priv->dpb, dummy_picture); + gst_vaapi_picture_unref (dummy_picture); + if (!success) { + GST_ERROR ("failed to add dummy picture into DPB"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } + GST_INFO ("allocated dummy picture for first field based I-frame"); + } - /* Update presentation time */ - picture->pts = pts_eval(&priv->tsg, - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts, pic_hdr->tsn); - picture->poc = pts_get_poc(&priv->tsg); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + /* Update presentation time */ + picture->pts = pts_eval (&priv->tsg, + GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts, pic_hdr->tsn); + picture->poc = pts_get_poc (&priv->tsg); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static void -fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture) +fill_picture (GstVaapiDecoderMpeg2 * decoder, GstVaapiPicture * picture) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - VAPictureParameterBufferMPEG2 * const pic_param = picture->param; - GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr->data.pic_hdr; - GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext->data.pic_ext; - GstVaapiPicture *prev_picture, *next_picture; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + VAPictureParameterBufferMPEG2 *const pic_param = picture->param; + GstMpegVideoPictureHdr *const pic_hdr = &priv->pic_hdr->data.pic_hdr; + GstMpegVideoPictureExt *const pic_ext = &priv->pic_ext->data.pic_ext; + GstVaapiPicture *prev_picture, *next_picture; - /* Fill in VAPictureParameterBufferMPEG2 */ - pic_param->horizontal_size = priv->width; - pic_param->vertical_size = priv->height; - pic_param->forward_reference_picture = VA_INVALID_ID; - pic_param->backward_reference_picture = VA_INVALID_ID; - pic_param->picture_coding_type = pic_hdr->pic_type; - pic_param->f_code = pack_f_code(pic_ext->f_code); + /* Fill in VAPictureParameterBufferMPEG2 */ + pic_param->horizontal_size = priv->width; + pic_param->vertical_size = priv->height; + pic_param->forward_reference_picture = VA_INVALID_ID; + pic_param->backward_reference_picture = VA_INVALID_ID; + pic_param->picture_coding_type = pic_hdr->pic_type; + pic_param->f_code = pack_f_code (pic_ext->f_code); #define COPY_FIELD(a, b, f) \ pic_param->a.b.f = pic_ext->f - pic_param->picture_coding_extension.value = 0; - pic_param->picture_coding_extension.bits.is_first_field = - GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture); - COPY_FIELD(picture_coding_extension, bits, intra_dc_precision); - COPY_FIELD(picture_coding_extension, bits, picture_structure); - COPY_FIELD(picture_coding_extension, bits, top_field_first); - COPY_FIELD(picture_coding_extension, bits, frame_pred_frame_dct); - COPY_FIELD(picture_coding_extension, bits, concealment_motion_vectors); - COPY_FIELD(picture_coding_extension, bits, q_scale_type); - COPY_FIELD(picture_coding_extension, bits, intra_vlc_format); - COPY_FIELD(picture_coding_extension, bits, alternate_scan); - COPY_FIELD(picture_coding_extension, bits, repeat_first_field); - COPY_FIELD(picture_coding_extension, bits, progressive_frame); + pic_param->picture_coding_extension.value = 0; + pic_param->picture_coding_extension.bits.is_first_field = + GST_VAAPI_PICTURE_IS_FIRST_FIELD (picture); + COPY_FIELD (picture_coding_extension, bits, intra_dc_precision); + COPY_FIELD (picture_coding_extension, bits, picture_structure); + COPY_FIELD (picture_coding_extension, bits, top_field_first); + COPY_FIELD (picture_coding_extension, bits, frame_pred_frame_dct); + COPY_FIELD (picture_coding_extension, bits, concealment_motion_vectors); + COPY_FIELD (picture_coding_extension, bits, q_scale_type); + COPY_FIELD (picture_coding_extension, bits, intra_vlc_format); + COPY_FIELD (picture_coding_extension, bits, alternate_scan); + COPY_FIELD (picture_coding_extension, bits, repeat_first_field); + COPY_FIELD (picture_coding_extension, bits, progressive_frame); - gst_vaapi_dpb_get_neighbours(priv->dpb, picture, - &prev_picture, &next_picture); + gst_vaapi_dpb_get_neighbours (priv->dpb, picture, + &prev_picture, &next_picture); - switch (pic_hdr->pic_type) { + switch (pic_hdr->pic_type) { case GST_MPEG_VIDEO_PICTURE_TYPE_B: - if (next_picture) - pic_param->backward_reference_picture = next_picture->surface_id; - if (prev_picture) - pic_param->forward_reference_picture = prev_picture->surface_id; - else if (!priv->closed_gop) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_SKIPPED); - break; + if (next_picture) + pic_param->backward_reference_picture = next_picture->surface_id; + if (prev_picture) + pic_param->forward_reference_picture = prev_picture->surface_id; + else if (!priv->closed_gop) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_SKIPPED); + break; case GST_MPEG_VIDEO_PICTURE_TYPE_P: - if (prev_picture) - pic_param->forward_reference_picture = prev_picture->surface_id; - break; - } + if (prev_picture) + pic_param->forward_reference_picture = prev_picture->surface_id; + break; + } } static GstVaapiDecoderStatus -parse_slice(GstVaapiDecoderMpeg2 *decoder, - GstVaapiDecoderUnit *unit, const GstMpegVideoPacket *packet) +parse_slice (GstVaapiDecoderMpeg2 * decoder, + GstVaapiDecoderUnit * unit, const GstMpegVideoPacket * packet) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoSliceHdr *slice_hdr; - GstMpegVideoSequenceHdr *seq_hdr; - GstMpegVideoSequenceScalableExt *seq_scalable_ext; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoSliceHdr *slice_hdr; + GstMpegVideoSequenceHdr *seq_hdr; + GstMpegVideoSequenceScalableExt *seq_scalable_ext; - priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR| - GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT| - GST_MPEG_VIDEO_STATE_GOT_PIC_HDR| - GST_MPEG_VIDEO_STATE_GOT_PIC_EXT); + priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR | + GST_MPEG_VIDEO_STATE_GOT_SEQ_EXT | + GST_MPEG_VIDEO_STATE_GOT_PIC_HDR | GST_MPEG_VIDEO_STATE_GOT_PIC_EXT); - if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->slice_hdr)) { - GST_ERROR("failed to allocate parser info for slice header"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - - slice_hdr = &priv->slice_hdr->data.slice_hdr; - seq_hdr = &priv->seq_hdr->data.seq_hdr; - seq_scalable_ext = priv->seq_scalable_ext ? - &priv->seq_scalable_ext->data.seq_scalable_ext : NULL; - - if (!gst_mpeg_video_packet_parse_slice_header(packet, slice_hdr, - seq_hdr, seq_scalable_ext)) { - GST_ERROR("failed to parse slice header"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } - - gst_vaapi_decoder_unit_set_parsed_info(unit, slice_hdr, NULL); + if (!is_valid_state (decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) return GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (!gst_vaapi_parser_info_mpeg2_ensure (&priv->slice_hdr)) { + GST_ERROR ("failed to allocate parser info for slice header"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + slice_hdr = &priv->slice_hdr->data.slice_hdr; + seq_hdr = &priv->seq_hdr->data.seq_hdr; + seq_scalable_ext = priv->seq_scalable_ext ? + &priv->seq_scalable_ext->data.seq_scalable_ext : NULL; + + if (!gst_mpeg_video_packet_parse_slice_header (packet, slice_hdr, + seq_hdr, seq_scalable_ext)) { + GST_ERROR ("failed to parse slice header"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + gst_vaapi_decoder_unit_set_parsed_info (unit, slice_hdr, NULL); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit) +decode_slice (GstVaapiDecoderMpeg2 * decoder, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstVaapiPicture * const picture = priv->current_picture; - GstVaapiSlice *slice; - VASliceParameterBufferMPEG2 *slice_param; - GstMpegVideoSliceHdr * const slice_hdr = unit->parsed_info; - GstBuffer * const buffer = - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; - GstMapInfo map_info; + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstVaapiPicture *const picture = priv->current_picture; + GstVaapiSlice *slice; + VASliceParameterBufferMPEG2 *slice_param; + GstMpegVideoSliceHdr *const slice_hdr = unit->parsed_info; + GstBuffer *const buffer = + GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer; + GstMapInfo map_info; - if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - if (!gst_buffer_map(buffer, &map_info, GST_MAP_READ)) { - GST_ERROR("failed to map buffer"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - - GST_DEBUG("slice %d (%u bytes)", slice_hdr->mb_row, unit->size); - - slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, - (map_info.data + unit->offset), unit->size); - gst_buffer_unmap(buffer, &map_info); - if (!slice) { - GST_ERROR("failed to allocate slice"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - gst_vaapi_picture_add_slice(picture, slice); - - /* Fill in VASliceParameterBufferMPEG2 */ - slice_param = slice->param; - slice_param->macroblock_offset = slice_hdr->header_size + 32; - slice_param->slice_horizontal_position = slice_hdr->mb_column; - slice_param->slice_vertical_position = slice_hdr->mb_row; - slice_param->quantiser_scale_code = slice_hdr->quantiser_scale_code; - slice_param->intra_slice_flag = slice_hdr->intra_slice; - - priv->state |= GST_MPEG_VIDEO_STATE_GOT_SLICE; + if (!is_valid_state (decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) return GST_VAAPI_DECODER_STATUS_SUCCESS; + + if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) { + GST_ERROR ("failed to map buffer"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + GST_DEBUG ("slice %d (%u bytes)", slice_hdr->mb_row, unit->size); + + slice = GST_VAAPI_SLICE_NEW (MPEG2, decoder, + (map_info.data + unit->offset), unit->size); + gst_buffer_unmap (buffer, &map_info); + if (!slice) { + GST_ERROR ("failed to allocate slice"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + gst_vaapi_picture_add_slice (picture, slice); + + /* Fill in VASliceParameterBufferMPEG2 */ + slice_param = slice->param; + slice_param->macroblock_offset = slice_hdr->header_size + 32; + slice_param->slice_horizontal_position = slice_hdr->mb_column; + slice_param->slice_vertical_position = slice_hdr->mb_row; + slice_param->quantiser_scale_code = slice_hdr->quantiser_scale_code; + slice_param->intra_slice_flag = slice_hdr->intra_slice; + + priv->state |= GST_MPEG_VIDEO_STATE_GOT_SLICE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static inline gint -scan_for_start_code(const guchar *buf, guint buf_size, - GstMpegVideoPacketTypeCode *type_ptr) +scan_for_start_code (const guchar * buf, guint buf_size, + GstMpegVideoPacketTypeCode * type_ptr) { - guint i = 0; + guint i = 0; - while (i <= (buf_size - 4)) { - if (buf[i + 2] > 1) - i += 3; - else if (buf[i + 1]) - i += 2; - else if (buf[i] || buf[i + 2] != 1) - i++; - else - break; - } + while (i <= (buf_size - 4)) { + if (buf[i + 2] > 1) + i += 3; + else if (buf[i + 1]) + i += 2; + else if (buf[i] || buf[i + 2] != 1) + i++; + else + break; + } - if (i <= (buf_size - 4)) { - if (type_ptr) - *type_ptr = buf[i + 3]; - return i; - } - return -1; + if (i <= (buf_size - 4)) { + if (type_ptr) + *type_ptr = buf[i + 3]; + return i; + } + return -1; } static GstVaapiDecoderStatus -parse_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, - GstMpegVideoPacket *packet) +parse_unit (GstVaapiDecoderMpeg2 * decoder, GstVaapiDecoderUnit * unit, + GstMpegVideoPacket * packet) { - GstMpegVideoPacketTypeCode type; - GstMpegVideoPacketExtensionCode ext_type; - GstVaapiDecoderStatus status; + GstMpegVideoPacketTypeCode type; + GstMpegVideoPacketExtensionCode ext_type; + GstVaapiDecoderStatus status; - type = packet->type; - switch (type) { + type = packet->type; + switch (type) { case GST_MPEG_VIDEO_PACKET_PICTURE: - status = parse_picture(decoder, unit, packet); - break; + status = parse_picture (decoder, unit, packet); + break; case GST_MPEG_VIDEO_PACKET_SEQUENCE: - status = parse_sequence(decoder, unit, packet); - break; + status = parse_sequence (decoder, unit, packet); + break; case GST_MPEG_VIDEO_PACKET_EXTENSION: - ext_type = packet->data[4] >> 4; - switch (ext_type) { + ext_type = packet->data[4] >> 4; + switch (ext_type) { case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: - status = parse_sequence_ext(decoder, unit, packet); - break; + status = parse_sequence_ext (decoder, unit, packet); + break; case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY: - status = parse_sequence_display_ext(decoder, unit, packet); - break; + status = parse_sequence_display_ext (decoder, unit, packet); + break; case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_SCALABLE: - status = parse_sequence_scalable_ext(decoder, unit, packet); - break; + status = parse_sequence_scalable_ext (decoder, unit, packet); + break; case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: - status = parse_quant_matrix_ext(decoder, unit, packet); - break; + status = parse_quant_matrix_ext (decoder, unit, packet); + break; case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: - status = parse_picture_ext(decoder, unit, packet); - break; + status = parse_picture_ext (decoder, unit, packet); + break; default: - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } - break; + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + break; case GST_MPEG_VIDEO_PACKET_GOP: - status = parse_gop(decoder, unit, packet); - break; + status = parse_gop (decoder, unit, packet); + break; default: - if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && - type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { - status = parse_slice(decoder, unit, packet); - break; - } - status = GST_VAAPI_DECODER_STATUS_SUCCESS; + if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { + status = parse_slice (decoder, unit, packet); break; - } - return status; + } + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + return status; } static GstVaapiDecoderStatus -decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit, - GstMpegVideoPacket *packet) +decode_unit (GstVaapiDecoderMpeg2 * decoder, GstVaapiDecoderUnit * unit, + GstMpegVideoPacket * packet) { - GstMpegVideoPacketTypeCode type; - GstMpegVideoPacketExtensionCode ext_type; - GstVaapiDecoderStatus status; + GstMpegVideoPacketTypeCode type; + GstMpegVideoPacketExtensionCode ext_type; + GstVaapiDecoderStatus status; - type = packet->type; - switch (type) { + type = packet->type; + switch (type) { case GST_MPEG_VIDEO_PACKET_PICTURE: - status = decode_picture(decoder, unit); - break; + status = decode_picture (decoder, unit); + break; case GST_MPEG_VIDEO_PACKET_SEQUENCE: - status = decode_sequence(decoder, unit); - break; + status = decode_sequence (decoder, unit); + break; case GST_MPEG_VIDEO_PACKET_EXTENSION: - ext_type = packet->data[4] >> 4; - switch (ext_type) { + ext_type = packet->data[4] >> 4; + switch (ext_type) { case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: - status = decode_sequence_ext(decoder, unit); - break; + status = decode_sequence_ext (decoder, unit); + break; case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY: - status = decode_sequence_display_ext(decoder, unit); - break; + status = decode_sequence_display_ext (decoder, unit); + break; case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_SCALABLE: - status = decode_sequence_scalable_ext(decoder, unit); - break; + status = decode_sequence_scalable_ext (decoder, unit); + break; case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: - status = decode_quant_matrix_ext(decoder, unit); - break; + status = decode_quant_matrix_ext (decoder, unit); + break; case GST_MPEG_VIDEO_PACKET_EXT_PICTURE: - status = decode_picture_ext(decoder, unit); - break; + status = decode_picture_ext (decoder, unit); + break; default: - // Ignore unknown start-code extensions - GST_WARNING("unsupported packet extension type 0x%02x", ext_type); - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; - } - break; + // Ignore unknown start-code extensions + GST_WARNING ("unsupported packet extension type 0x%02x", ext_type); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + } + break; case GST_MPEG_VIDEO_PACKET_SEQUENCE_END: - status = decode_sequence_end(decoder); - break; + status = decode_sequence_end (decoder); + break; case GST_MPEG_VIDEO_PACKET_GOP: - status = decode_gop(decoder, unit); - break; + status = decode_gop (decoder, unit); + break; default: - if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && - type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { - status = decode_slice(decoder, unit); - break; - } - GST_WARNING("unsupported packet type 0x%02x", type); - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { + status = decode_slice (decoder, unit); break; - } + } + GST_WARNING ("unsupported packet type 0x%02x", type); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + return status; +} + +static GstVaapiDecoderStatus +ensure_decoder (GstVaapiDecoderMpeg2 * decoder) +{ + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + + if (!priv->is_opened) { + priv->is_opened = gst_vaapi_decoder_mpeg2_open (decoder); + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg2_parse (GstVaapiDecoder * base_decoder, + GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderMpeg2 *const decoder = + GST_VAAPI_DECODER_MPEG2_CAST (base_decoder); + GstVaapiParserState *const ps = GST_VAAPI_PARSER_STATE (base_decoder); + GstVaapiDecoderStatus status; + GstMpegVideoPacketTypeCode type, type2 = GST_MPEG_VIDEO_PACKET_NONE; + const guchar *buf; + guint buf_size, flags; + gint ofs, ofs1, ofs2; + + status = ensure_decoder (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; -} -static GstVaapiDecoderStatus -ensure_decoder(GstVaapiDecoderMpeg2 *decoder) -{ - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; + buf_size = gst_adapter_available (adapter); + if (buf_size < 4) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - if (!priv->is_opened) { - priv->is_opened = gst_vaapi_decoder_mpeg2_open(decoder); - if (!priv->is_opened) - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + buf = gst_adapter_map (adapter, buf_size); + if (!buf) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + ofs = scan_for_start_code (buf, buf_size, &type); + if (ofs < 0) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + ofs1 = ofs; + + ofs2 = ps->input_offset2 - 4; + if (ofs2 < ofs1 + 4) + ofs2 = ofs1 + 4; + + ofs = G_UNLIKELY (buf_size < ofs2 + 4) ? -1 : + scan_for_start_code (&buf[ofs2], buf_size - ofs2, &type2); + if (ofs < 0) { + // Assume the whole packet is present if end-of-stream + if (!at_eos) { + ps->input_offset2 = buf_size; + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; } - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} + ofs = buf_size - ofs2; + } + ofs2 += ofs; -static GstVaapiDecoderStatus -gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder, - GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) -{ - GstVaapiDecoderMpeg2 * const decoder = - GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); - GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder); - GstVaapiDecoderStatus status; - GstMpegVideoPacketTypeCode type, type2 = GST_MPEG_VIDEO_PACKET_NONE; - const guchar *buf; - guint buf_size, flags; - gint ofs, ofs1, ofs2; + unit->size = ofs2 - ofs1; + gst_adapter_flush (adapter, ofs1); + ps->input_offset2 = 4; - status = ensure_decoder(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - - buf_size = gst_adapter_available(adapter); - if (buf_size < 4) - 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; - - ofs = scan_for_start_code(buf, buf_size, &type); - if (ofs < 0) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - ofs1 = ofs; - - ofs2 = ps->input_offset2 - 4; - if (ofs2 < ofs1 + 4) - ofs2 = ofs1 + 4; - - ofs = G_UNLIKELY(buf_size < ofs2 + 4) ? -1 : - scan_for_start_code(&buf[ofs2], buf_size - ofs2, &type2); - if (ofs < 0) { - // Assume the whole packet is present if end-of-stream - if (!at_eos) { - ps->input_offset2 = buf_size; - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - } - ofs = buf_size - ofs2; - } - ofs2 += ofs; - - unit->size = ofs2 - ofs1; - gst_adapter_flush(adapter, ofs1); - ps->input_offset2 = 4; - - /* Check for start of new picture */ - flags = 0; - switch (type) { + /* Check for start of new picture */ + flags = 0; + switch (type) { case GST_MPEG_VIDEO_PACKET_SEQUENCE_END: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; - flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; - break; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; + break; case GST_MPEG_VIDEO_PACKET_USER_DATA: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; - /* fall-through */ + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + /* fall-through */ case GST_MPEG_VIDEO_PACKET_SEQUENCE: case GST_MPEG_VIDEO_PACKET_GOP: case GST_MPEG_VIDEO_PACKET_PICTURE: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - break; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; case GST_MPEG_VIDEO_PACKET_EXTENSION: - if (G_UNLIKELY(unit->size < 5)) - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - break; + if (G_UNLIKELY (unit->size < 5)) + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; default: - if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && - type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; - switch (type2) { - case GST_MPEG_VIDEO_PACKET_USER_DATA: - case GST_MPEG_VIDEO_PACKET_SEQUENCE: - case GST_MPEG_VIDEO_PACKET_GOP: - case GST_MPEG_VIDEO_PACKET_PICTURE: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; - break; - default: - break; - } + if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && + type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + switch (type2) { + case GST_MPEG_VIDEO_PACKET_USER_DATA: + case GST_MPEG_VIDEO_PACKET_SEQUENCE: + case GST_MPEG_VIDEO_PACKET_GOP: + case GST_MPEG_VIDEO_PACKET_PICTURE: + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + break; + default: + break; } + } + // Ignore system start codes (PES headers) + else if (type >= 0xb9 && type <= 0xff) + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + break; + } + GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} - // Ignore system start codes (PES headers) - else if (type >= 0xb9 && type <= 0xff) - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; - break; - } - GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg2_decode (GstVaapiDecoder * base_decoder, + GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderMpeg2 *const decoder = + GST_VAAPI_DECODER_MPEG2_CAST (base_decoder); + GstVaapiDecoderStatus status; + GstMpegVideoPacket packet; + 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; + } + + packet.data = map_info.data + unit->offset; + packet.size = unit->size; + packet.type = packet.data[3]; + packet.offset = 4; + + status = parse_unit (decoder, unit, &packet); + gst_buffer_unmap (buffer, &map_info); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + return decode_unit (decoder, unit, &packet); +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg2_start_frame (GstVaapiDecoder * base_decoder, + GstVaapiDecoderUnit * base_unit) +{ + GstVaapiDecoderMpeg2 *const decoder = + GST_VAAPI_DECODER_MPEG2_CAST (base_decoder); + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; + GstMpegVideoSequenceHdr *seq_hdr; + GstMpegVideoSequenceExt *seq_ext; + GstMpegVideoSequenceDisplayExt *seq_display_ext; + GstVaapiPicture *picture; + GstVaapiDecoderStatus status; + + if (!is_valid_state (decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) return GST_VAAPI_DECODER_STATUS_SUCCESS; + priv->state &= ~GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS; + + seq_hdr = &priv->seq_hdr->data.seq_hdr; + seq_ext = priv->seq_ext ? &priv->seq_ext->data.seq_ext : NULL; + seq_display_ext = priv->seq_display_ext ? + &priv->seq_display_ext->data.seq_display_ext : NULL; + if (gst_mpeg_video_finalise_mpeg2_sequence_header (seq_hdr, seq_ext, + seq_display_ext)) + gst_vaapi_decoder_set_pixel_aspect_ratio (base_decoder, + seq_hdr->par_w, seq_hdr->par_h); + + status = ensure_context (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_ERROR ("failed to reset context"); + return status; + } + + if (priv->current_picture) { + /* Re-use current picture where the first field was decoded */ + picture = gst_vaapi_picture_new_field (priv->current_picture); + if (!picture) { + GST_ERROR ("failed to allocate field picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + } else { + /* Create new picture */ + picture = GST_VAAPI_PICTURE_NEW (MPEG2, 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); + + /* Update cropping rectangle */ + /* XXX: handle picture_display_extension() */ + if (seq_display_ext && priv->pic_display_ext) { + GstVaapiRectangle *const crop_rect = &priv->crop_rect; + if (crop_rect->x + crop_rect->width <= priv->width && + crop_rect->y + crop_rect->height <= priv->height) + gst_vaapi_picture_set_crop_rect (picture, crop_rect); + } + + status = ensure_quant_matrix (decoder, picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_ERROR ("failed to reset quantizer matrix"); + return status; + } + + status = init_picture (decoder, picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + fill_picture (decoder, picture); + + priv->state |= GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -gst_vaapi_decoder_mpeg2_decode(GstVaapiDecoder *base_decoder, - GstVaapiDecoderUnit *unit) +gst_vaapi_decoder_mpeg2_end_frame (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderMpeg2 * const decoder = - GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); - GstVaapiDecoderStatus status; - GstMpegVideoPacket packet; - GstBuffer * const buffer = - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; - GstMapInfo map_info; + GstVaapiDecoderMpeg2 *const decoder = + GST_VAAPI_DECODER_MPEG2_CAST (base_decoder); - 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; - } - - packet.data = map_info.data + unit->offset; - packet.size = unit->size; - packet.type = packet.data[3]; - packet.offset = 4; - - status = parse_unit(decoder, unit, &packet); - gst_buffer_unmap(buffer, &map_info); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - return decode_unit(decoder, unit, &packet); + return decode_current_picture (decoder); } static GstVaapiDecoderStatus -gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder, - GstVaapiDecoderUnit *base_unit) +gst_vaapi_decoder_mpeg2_flush (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderMpeg2 * const decoder = - GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - GstMpegVideoSequenceHdr *seq_hdr; - GstMpegVideoSequenceExt *seq_ext; - GstMpegVideoSequenceDisplayExt *seq_display_ext; - GstVaapiPicture *picture; - GstVaapiDecoderStatus status; + GstVaapiDecoderMpeg2 *const decoder = + GST_VAAPI_DECODER_MPEG2_CAST (base_decoder); + GstVaapiDecoderMpeg2Private *const priv = &decoder->priv; - if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS)) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - priv->state &= ~GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS; - - seq_hdr = &priv->seq_hdr->data.seq_hdr; - seq_ext = priv->seq_ext ? &priv->seq_ext->data.seq_ext : NULL; - seq_display_ext = priv->seq_display_ext ? - &priv->seq_display_ext->data.seq_display_ext : NULL; - if (gst_mpeg_video_finalise_mpeg2_sequence_header(seq_hdr, seq_ext, - seq_display_ext)) - gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, - seq_hdr->par_w, seq_hdr->par_h); - - status = ensure_context(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_ERROR("failed to reset context"); - return status; - } - - if (priv->current_picture) { - /* Re-use current picture where the first field was decoded */ - picture = gst_vaapi_picture_new_field(priv->current_picture); - if (!picture) { - GST_ERROR("failed to allocate field picture"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - } - else { - /* Create new picture */ - picture = GST_VAAPI_PICTURE_NEW(MPEG2, 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); - - /* Update cropping rectangle */ - /* XXX: handle picture_display_extension() */ - if (seq_display_ext && priv->pic_display_ext) { - GstVaapiRectangle * const crop_rect = &priv->crop_rect; - if (crop_rect->x + crop_rect->width <= priv->width && - crop_rect->y + crop_rect->height <= priv->height) - gst_vaapi_picture_set_crop_rect(picture, crop_rect); - } - - status = ensure_quant_matrix(decoder, picture); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_ERROR("failed to reset quantizer matrix"); - return status; - } - - status = init_picture(decoder, picture); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - - fill_picture(decoder, picture); - - priv->state |= GST_MPEG_VIDEO_STATE_VALID_PIC_HEADERS; - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -gst_vaapi_decoder_mpeg2_end_frame(GstVaapiDecoder *base_decoder) -{ - GstVaapiDecoderMpeg2 * const decoder = - GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); - - return decode_current_picture(decoder); -} - -static GstVaapiDecoderStatus -gst_vaapi_decoder_mpeg2_flush(GstVaapiDecoder *base_decoder) -{ - GstVaapiDecoderMpeg2 * const decoder = - GST_VAAPI_DECODER_MPEG2_CAST(base_decoder); - GstVaapiDecoderMpeg2Private * const priv = &decoder->priv; - - if (priv->dpb) - gst_vaapi_dpb_flush(priv->dpb); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (priv->dpb) + gst_vaapi_dpb_flush (priv->dpb); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static void -gst_vaapi_decoder_mpeg2_class_init(GstVaapiDecoderMpeg2Class *klass) +gst_vaapi_decoder_mpeg2_class_init (GstVaapiDecoderMpeg2Class * klass) { - GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); - GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof(GstVaapiDecoderMpeg2); - object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize; + object_class->size = sizeof (GstVaapiDecoderMpeg2); + object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; - decoder_class->create = gst_vaapi_decoder_mpeg2_create; - decoder_class->destroy = gst_vaapi_decoder_mpeg2_destroy; - decoder_class->parse = gst_vaapi_decoder_mpeg2_parse; - decoder_class->decode = gst_vaapi_decoder_mpeg2_decode; - decoder_class->start_frame = gst_vaapi_decoder_mpeg2_start_frame; - decoder_class->end_frame = gst_vaapi_decoder_mpeg2_end_frame; - decoder_class->flush = gst_vaapi_decoder_mpeg2_flush; + decoder_class->create = gst_vaapi_decoder_mpeg2_create; + decoder_class->destroy = gst_vaapi_decoder_mpeg2_destroy; + decoder_class->parse = gst_vaapi_decoder_mpeg2_parse; + decoder_class->decode = gst_vaapi_decoder_mpeg2_decode; + decoder_class->start_frame = gst_vaapi_decoder_mpeg2_start_frame; + decoder_class->end_frame = gst_vaapi_decoder_mpeg2_end_frame; + decoder_class->flush = gst_vaapi_decoder_mpeg2_flush; } static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_mpeg2_class(void) +gst_vaapi_decoder_mpeg2_class (void) { - static GstVaapiDecoderMpeg2Class g_class; - static gsize g_class_init = FALSE; + static GstVaapiDecoderMpeg2Class g_class; + static gsize g_class_init = FALSE; - if (g_once_init_enter(&g_class_init)) { - gst_vaapi_decoder_mpeg2_class_init(&g_class); - g_once_init_leave(&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS(&g_class); + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_decoder_mpeg2_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS (&g_class); } /** @@ -1596,8 +1600,8 @@ gst_vaapi_decoder_mpeg2_class(void) * Return value: the newly allocated #GstVaapiDecoder object */ GstVaapiDecoder * -gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps) +gst_vaapi_decoder_mpeg2_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new(gst_vaapi_decoder_mpeg2_class(), - display, caps); + return gst_vaapi_decoder_new (gst_vaapi_decoder_mpeg2_class (), + display, caps); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 3afb765eef..9ab340debc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -41,58 +41,59 @@ #define GST_VAAPI_DECODER_MPEG4_CAST(decoder) \ ((GstVaapiDecoderMpeg4 *)(decoder)) -typedef struct _GstVaapiDecoderMpeg4Private GstVaapiDecoderMpeg4Private; -typedef struct _GstVaapiDecoderMpeg4Class GstVaapiDecoderMpeg4Class; +typedef struct _GstVaapiDecoderMpeg4Private GstVaapiDecoderMpeg4Private; +typedef struct _GstVaapiDecoderMpeg4Class GstVaapiDecoderMpeg4Class; -struct _GstVaapiDecoderMpeg4Private { - GstVaapiProfile profile; - guint level; - guint width; - guint height; - guint fps_n; - guint fps_d; - guint coding_type; - GstMpeg4VisualObjectSequence vos_hdr; - GstMpeg4VisualObject vo_hdr; - GstMpeg4VideoSignalType signal_type; - GstMpeg4VideoObjectLayer vol_hdr; - GstMpeg4VideoObjectPlane vop_hdr; - GstMpeg4VideoPlaneShortHdr svh_hdr; - GstMpeg4VideoPacketHdr packet_hdr; - GstMpeg4SpriteTrajectory sprite_trajectory; - VAIQMatrixBufferMPEG4 iq_matrix; - GstVaapiPicture *curr_picture; - // forward reference pic - GstVaapiPicture *next_picture; - // backward reference pic - GstVaapiPicture *prev_picture; - GstClockTime seq_pts; - GstClockTime gop_pts; - GstClockTime pts_diff; - GstClockTime max_pts; - // anchor sync time base for any picture type, - // it is time base of backward reference frame - GstClockTime last_sync_time; - // time base for recent I/P/S frame, - // it is time base of forward reference frame for B frame - GstClockTime sync_time; +struct _GstVaapiDecoderMpeg4Private +{ + GstVaapiProfile profile; + guint level; + guint width; + guint height; + guint fps_n; + guint fps_d; + guint coding_type; + GstMpeg4VisualObjectSequence vos_hdr; + GstMpeg4VisualObject vo_hdr; + GstMpeg4VideoSignalType signal_type; + GstMpeg4VideoObjectLayer vol_hdr; + GstMpeg4VideoObjectPlane vop_hdr; + GstMpeg4VideoPlaneShortHdr svh_hdr; + GstMpeg4VideoPacketHdr packet_hdr; + GstMpeg4SpriteTrajectory sprite_trajectory; + VAIQMatrixBufferMPEG4 iq_matrix; + GstVaapiPicture *curr_picture; + // forward reference pic + GstVaapiPicture *next_picture; + // backward reference pic + GstVaapiPicture *prev_picture; + GstClockTime seq_pts; + GstClockTime gop_pts; + GstClockTime pts_diff; + GstClockTime max_pts; + // anchor sync time base for any picture type, + // it is time base of backward reference frame + GstClockTime last_sync_time; + // time base for recent I/P/S frame, + // it is time base of forward reference frame for B frame + GstClockTime sync_time; - /* last non-b-frame time by resolution */ - GstClockTime last_non_b_scale_time; - GstClockTime non_b_scale_time; - GstClockTime trb; - GstClockTime trd; - // temporal_reference of previous frame of svh - guint8 prev_t_ref; - guint is_opened : 1; - guint is_first_field : 1; - guint size_changed : 1; - guint profile_changed : 1; - guint progressive_sequence : 1; - guint closed_gop : 1; - guint broken_link : 1; - guint calculate_pts_diff : 1; - guint is_svh : 1; + /* last non-b-frame time by resolution */ + GstClockTime last_non_b_scale_time; + GstClockTime non_b_scale_time; + GstClockTime trb; + GstClockTime trd; + // temporal_reference of previous frame of svh + guint8 prev_t_ref; + guint is_opened:1; + guint is_first_field:1; + guint size_changed:1; + guint profile_changed:1; + guint progressive_sequence:1; + guint closed_gop:1; + guint broken_link:1; + guint calculate_pts_diff:1; + guint is_svh:1; }; /** @@ -100,10 +101,11 @@ struct _GstVaapiDecoderMpeg4Private { * * A decoder based on Mpeg4. */ -struct _GstVaapiDecoderMpeg4 { - /*< private >*/ - GstVaapiDecoder parent_instance; - GstVaapiDecoderMpeg4Private priv; +struct _GstVaapiDecoderMpeg4 +{ + /*< private > */ + GstVaapiDecoder parent_instance; + GstVaapiDecoderMpeg4Private priv; }; /** @@ -111,951 +113,966 @@ struct _GstVaapiDecoderMpeg4 { * * A decoder class based on Mpeg4. */ -struct _GstVaapiDecoderMpeg4Class { - /*< private >*/ - GstVaapiDecoderClass parent_class; +struct _GstVaapiDecoderMpeg4Class +{ + /*< private > */ + GstVaapiDecoderClass parent_class; }; static void -gst_vaapi_decoder_mpeg4_close(GstVaapiDecoderMpeg4 *decoder) +gst_vaapi_decoder_mpeg4_close (GstVaapiDecoderMpeg4 * decoder) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; - gst_vaapi_picture_replace(&priv->curr_picture, NULL); - gst_vaapi_picture_replace(&priv->next_picture, NULL); - gst_vaapi_picture_replace(&priv->prev_picture, NULL); + gst_vaapi_picture_replace (&priv->curr_picture, NULL); + gst_vaapi_picture_replace (&priv->next_picture, NULL); + gst_vaapi_picture_replace (&priv->prev_picture, NULL); } static gboolean -gst_vaapi_decoder_mpeg4_open(GstVaapiDecoderMpeg4 *decoder) +gst_vaapi_decoder_mpeg4_open (GstVaapiDecoderMpeg4 * decoder) { - GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER(decoder); - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstCaps *caps = NULL; - GstStructure *structure = NULL; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstCaps *caps = NULL; + GstStructure *structure = NULL; - gst_vaapi_decoder_mpeg4_close(decoder); + gst_vaapi_decoder_mpeg4_close (decoder); - priv->is_svh = 0; - caps = gst_vaapi_decoder_get_caps(base_decoder); - if (caps) { - structure = gst_caps_get_structure(caps, 0); - if (structure) { - if (gst_structure_has_name(structure, "video/x-h263")) { - priv->is_svh = 1; - priv->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; - priv->prev_t_ref = -1; - } - } + priv->is_svh = 0; + caps = gst_vaapi_decoder_get_caps (base_decoder); + if (caps) { + structure = gst_caps_get_structure (caps, 0); + if (structure) { + if (gst_structure_has_name (structure, "video/x-h263")) { + priv->is_svh = 1; + priv->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; + priv->prev_t_ref = -1; + } } - return TRUE; + } + return TRUE; } static void -gst_vaapi_decoder_mpeg4_destroy(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_mpeg4_destroy (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderMpeg4 * const decoder = - GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); + GstVaapiDecoderMpeg4 *const decoder = + GST_VAAPI_DECODER_MPEG4_CAST (base_decoder); - gst_vaapi_decoder_mpeg4_close(decoder); + gst_vaapi_decoder_mpeg4_close (decoder); } static gboolean -gst_vaapi_decoder_mpeg4_create(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_mpeg4_create (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderMpeg4 * const decoder = - GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; + GstVaapiDecoderMpeg4 *const decoder = + GST_VAAPI_DECODER_MPEG4_CAST (base_decoder); + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; - priv->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; - priv->seq_pts = GST_CLOCK_TIME_NONE; - priv->gop_pts = GST_CLOCK_TIME_NONE; - priv->max_pts = GST_CLOCK_TIME_NONE; - priv->calculate_pts_diff = TRUE; - priv->size_changed = TRUE; - priv->profile_changed = TRUE; - return TRUE; + priv->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; + priv->seq_pts = GST_CLOCK_TIME_NONE; + priv->gop_pts = GST_CLOCK_TIME_NONE; + priv->max_pts = GST_CLOCK_TIME_NONE; + priv->calculate_pts_diff = TRUE; + priv->size_changed = TRUE; + priv->profile_changed = TRUE; + return TRUE; } static inline void -copy_quant_matrix(guint8 dst[64], const guint8 src[64]) +copy_quant_matrix (guint8 dst[64], const guint8 src[64]) { - memcpy(dst, src, 64); + memcpy (dst, src, 64); } static GstVaapiDecoderStatus -ensure_context(GstVaapiDecoderMpeg4 *decoder) +ensure_context (GstVaapiDecoderMpeg4 * decoder) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstVaapiProfile profiles[2]; - GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; - guint i, n_profiles = 0; - gboolean reset_context = FALSE; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + 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; + 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_MPEG4_SIMPLE) - profiles[n_profiles++] = GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE; + profiles[n_profiles++] = priv->profile; + if (priv->profile == GST_VAAPI_PROFILE_MPEG4_SIMPLE) + profiles[n_profiles++] = GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE; - 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]; + 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 (priv->size_changed) { + GST_DEBUG ("size changed"); + priv->size_changed = FALSE; + reset_context = TRUE; + } - if (reset_context) { - GstVaapiContextInfo info; + 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 = 2; - 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; + 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 = 2; + 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(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) +ensure_quant_matrix (GstVaapiDecoderMpeg4 * decoder, GstVaapiPicture * picture) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - VAIQMatrixBufferMPEG4 *iq_matrix; - - if (!priv->vol_hdr.load_intra_quant_mat && !priv->vol_hdr.load_non_intra_quant_mat) { - return GST_VAAPI_DECODER_STATUS_SUCCESS; - } - - picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(MPEG4, decoder); - if (!picture->iq_matrix) { - GST_DEBUG("failed to allocate IQ matrix"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - iq_matrix = picture->iq_matrix->param; - - if (priv->vol_hdr.load_intra_quant_mat) { - iq_matrix->load_intra_quant_mat = 1; - copy_quant_matrix(iq_matrix->intra_quant_mat, - priv->vol_hdr.intra_quant_mat); - } - else - iq_matrix->load_intra_quant_mat = 0; - - if (priv->vol_hdr.load_non_intra_quant_mat) { - iq_matrix->load_non_intra_quant_mat = 1; - copy_quant_matrix(iq_matrix->non_intra_quant_mat, - priv->vol_hdr.non_intra_quant_mat); - } - else - iq_matrix->load_non_intra_quant_mat = 0; - + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + VAIQMatrixBufferMPEG4 *iq_matrix; + if (!priv->vol_hdr.load_intra_quant_mat + && !priv->vol_hdr.load_non_intra_quant_mat) { return GST_VAAPI_DECODER_STATUS_SUCCESS; + } + + picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW (MPEG4, decoder); + if (!picture->iq_matrix) { + GST_DEBUG ("failed to allocate IQ matrix"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + iq_matrix = picture->iq_matrix->param; + + if (priv->vol_hdr.load_intra_quant_mat) { + iq_matrix->load_intra_quant_mat = 1; + copy_quant_matrix (iq_matrix->intra_quant_mat, + priv->vol_hdr.intra_quant_mat); + } else + iq_matrix->load_intra_quant_mat = 0; + + if (priv->vol_hdr.load_non_intra_quant_mat) { + iq_matrix->load_non_intra_quant_mat = 1; + copy_quant_matrix (iq_matrix->non_intra_quant_mat, + priv->vol_hdr.non_intra_quant_mat); + } else + iq_matrix->load_non_intra_quant_mat = 0; + + + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static inline GstVaapiDecoderStatus -render_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) +render_picture (GstVaapiDecoderMpeg4 * decoder, GstVaapiPicture * picture) { - if (!gst_vaapi_picture_output(picture)) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_vaapi_picture_output (picture)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } /* decode_picture() start to decode a frame/picture - * decode_current_picture() finishe decoding a frame/picture + * decode_current_picture() finishe decoding a frame/picture * (commit buffer to driver for decoding) */ static GstVaapiDecoderStatus -decode_current_picture(GstVaapiDecoderMpeg4 *decoder) +decode_current_picture (GstVaapiDecoderMpeg4 * decoder) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstVaapiPicture * const picture = priv->curr_picture; - GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstVaapiPicture *const picture = priv->curr_picture; + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; - if (picture) { - if (!gst_vaapi_picture_decode(picture)) - status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { - if ((priv->prev_picture && priv->next_picture) || - (priv->closed_gop && priv->next_picture)) - status = render_picture(decoder, picture); - } - gst_vaapi_picture_replace(&priv->curr_picture, NULL); + if (picture) { + if (!gst_vaapi_picture_decode (picture)) + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + if (!GST_VAAPI_PICTURE_IS_REFERENCE (picture)) { + if ((priv->prev_picture && priv->next_picture) || + (priv->closed_gop && priv->next_picture)) + status = render_picture (decoder, picture); } - return status; + gst_vaapi_picture_replace (&priv->curr_picture, NULL); + } + return status; } static GstVaapiDecoderStatus -decode_sequence(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) +decode_sequence (GstVaapiDecoderMpeg4 * decoder, const guint8 * buf, + guint buf_size) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstMpeg4VisualObjectSequence * const vos_hdr = &priv->vos_hdr; - GstVaapiProfile profile; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstMpeg4VisualObjectSequence *const vos_hdr = &priv->vos_hdr; + GstVaapiProfile profile; - if (gst_mpeg4_parse_visual_object_sequence(vos_hdr, buf, buf_size) != GST_MPEG4_PARSER_OK) { - GST_DEBUG("failed to parse sequence header"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + if (gst_mpeg4_parse_visual_object_sequence (vos_hdr, buf, + buf_size) != GST_MPEG4_PARSER_OK) { + GST_DEBUG ("failed to parse sequence header"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } - priv->level = vos_hdr->level; - switch (vos_hdr->profile) { + priv->level = vos_hdr->level; + switch (vos_hdr->profile) { case GST_MPEG4_PROFILE_SIMPLE: - profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; - break; + profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; + break; case GST_MPEG4_PROFILE_ADVANCED_SIMPLE: - case GST_MPEG4_PROFILE_SIMPLE_SCALABLE: /* shared profile with ADVANCED_SIMPLE */ - profile = GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE; - break; + case GST_MPEG4_PROFILE_SIMPLE_SCALABLE: /* shared profile with ADVANCED_SIMPLE */ + profile = GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE; + break; default: - GST_DEBUG("unsupported profile %d", vos_hdr->profile); - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - } - if (priv->profile != profile) { - priv->profile = profile; - priv->profile_changed = TRUE; - } - priv->seq_pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; - priv->size_changed = TRUE; + GST_DEBUG ("unsupported profile %d", vos_hdr->profile); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + if (priv->profile != profile) { + priv->profile = profile; + priv->profile_changed = TRUE; + } + priv->seq_pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts; + priv->size_changed = TRUE; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_sequence_end(GstVaapiDecoderMpeg4 *decoder) +decode_sequence_end (GstVaapiDecoderMpeg4 * decoder) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstVaapiDecoderStatus status; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; - if (priv->curr_picture) { - status = decode_current_picture(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - status = render_picture(decoder, priv->curr_picture); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } + if (priv->curr_picture) { + status = decode_current_picture (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + status = render_picture (decoder, priv->curr_picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } - if (priv->next_picture) { - status = render_picture(decoder, priv->next_picture); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; + if (priv->next_picture) { + status = render_picture (decoder, priv->next_picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + return GST_VAAPI_DECODER_STATUS_END_OF_STREAM; } static GstVaapiDecoderStatus -decode_visual_object(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) +decode_visual_object (GstVaapiDecoderMpeg4 * decoder, const guint8 * buf, + guint buf_size) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstMpeg4VisualObject * vo_hdr = &priv->vo_hdr; - GstMpeg4VideoSignalType * signal_type = &priv->signal_type; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstMpeg4VisualObject *vo_hdr = &priv->vo_hdr; + GstMpeg4VideoSignalType *signal_type = &priv->signal_type; - if (gst_mpeg4_parse_visual_object (vo_hdr, signal_type, buf, buf_size) != GST_MPEG4_PARSER_OK) { - GST_DEBUG("failed to parse visual object"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + if (gst_mpeg4_parse_visual_object (vo_hdr, signal_type, buf, + buf_size) != GST_MPEG4_PARSER_OK) { + GST_DEBUG ("failed to parse visual object"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } - /* XXX: video_signal_type isn't used for decoding */ - return GST_VAAPI_DECODER_STATUS_SUCCESS; + /* XXX: video_signal_type isn't used for decoding */ + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_video_object_layer(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) +decode_video_object_layer (GstVaapiDecoderMpeg4 * decoder, const guint8 * buf, + guint buf_size) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstMpeg4VisualObject * vo_hdr = &priv->vo_hdr; - GstMpeg4VideoObjectLayer * vol_hdr = &priv->vol_hdr; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstMpeg4VisualObject *vo_hdr = &priv->vo_hdr; + GstMpeg4VideoObjectLayer *vol_hdr = &priv->vol_hdr; - if (gst_mpeg4_parse_video_object_layer (vol_hdr, vo_hdr, buf, buf_size) != GST_MPEG4_PARSER_OK) { - GST_DEBUG("failed to parse video object layer"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + if (gst_mpeg4_parse_video_object_layer (vol_hdr, vo_hdr, buf, + buf_size) != GST_MPEG4_PARSER_OK) { + GST_DEBUG ("failed to parse video object layer"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } - priv->width = vol_hdr->width; - priv->height = vol_hdr->height; + priv->width = vol_hdr->width; + priv->height = vol_hdr->height; - priv->progressive_sequence = !vol_hdr->interlaced; + priv->progressive_sequence = !vol_hdr->interlaced; - if (vol_hdr->fixed_vop_rate) { - priv->fps_n = vol_hdr->vop_time_increment_resolution; - priv->fps_d = vol_hdr->fixed_vop_time_increment; - gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); - } + if (vol_hdr->fixed_vop_rate) { + priv->fps_n = vol_hdr->vop_time_increment_resolution; + priv->fps_d = vol_hdr->fixed_vop_time_increment; + gst_vaapi_decoder_set_framerate (base_decoder, priv->fps_n, priv->fps_d); + } - gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, priv->vol_hdr.par_width, priv->vol_hdr.par_height); - gst_vaapi_decoder_set_picture_size(base_decoder, priv->width, priv->height); + gst_vaapi_decoder_set_pixel_aspect_ratio (base_decoder, + priv->vol_hdr.par_width, priv->vol_hdr.par_height); + gst_vaapi_decoder_set_picture_size (base_decoder, priv->width, priv->height); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_gop(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) +decode_gop (GstVaapiDecoderMpeg4 * decoder, const guint8 * buf, guint buf_size) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstMpeg4GroupOfVOP gop; - GstClockTime gop_time; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstMpeg4GroupOfVOP gop; + GstClockTime gop_time; - if (buf_size >4) { - if (gst_mpeg4_parse_group_of_vop(&gop, buf, buf_size) != GST_MPEG4_PARSER_OK) { - GST_DEBUG("failed to parse GOP"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } - } - else { - gop.closed = 1; - gop.broken_link = 0; - gop.hours = 0; - gop.minutes = 0; - gop.seconds = 0; + if (buf_size > 4) { + if (gst_mpeg4_parse_group_of_vop (&gop, buf, + buf_size) != GST_MPEG4_PARSER_OK) { + GST_DEBUG ("failed to parse GOP"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } + } else { + gop.closed = 1; + gop.broken_link = 0; + gop.hours = 0; + gop.minutes = 0; + gop.seconds = 0; + } - priv->closed_gop = gop.closed; - priv->broken_link = gop.broken_link; + priv->closed_gop = gop.closed; + priv->broken_link = gop.broken_link; - GST_DEBUG("GOP %02u:%02u:%02u (closed_gop %d, broken_link %d)", - gop.hours, gop.minutes, gop.seconds, - priv->closed_gop, priv->broken_link); + GST_DEBUG ("GOP %02u:%02u:%02u (closed_gop %d, broken_link %d)", + gop.hours, gop.minutes, gop.seconds, priv->closed_gop, priv->broken_link); - gop_time = gop.hours * 3600 + gop.minutes * 60 + gop.seconds; - priv->last_sync_time = gop_time; - priv->sync_time = gop_time; - - if (priv->gop_pts != GST_CLOCK_TIME_NONE) - priv->pts_diff += gop_time * GST_SECOND - priv->gop_pts; - priv->gop_pts = gop_time * GST_SECOND; - priv->calculate_pts_diff = TRUE; - priv->is_first_field = TRUE; + gop_time = gop.hours * 3600 + gop.minutes * 60 + gop.seconds; + priv->last_sync_time = gop_time; + priv->sync_time = gop_time; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (priv->gop_pts != GST_CLOCK_TIME_NONE) + priv->pts_diff += gop_time * GST_SECOND - priv->gop_pts; + priv->gop_pts = gop_time * GST_SECOND; + priv->calculate_pts_diff = TRUE; + priv->is_first_field = TRUE; + + return GST_VAAPI_DECODER_STATUS_SUCCESS; } void -calculate_pts_diff(GstVaapiDecoderMpeg4 *decoder, - GstMpeg4VideoObjectLayer *vol_hdr, - GstMpeg4VideoObjectPlane *vop_hdr) +calculate_pts_diff (GstVaapiDecoderMpeg4 * decoder, + GstMpeg4VideoObjectLayer * vol_hdr, GstMpeg4VideoObjectPlane * vop_hdr) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstClockTime frame_timestamp; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstClockTime frame_timestamp; - frame_timestamp = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; - if (frame_timestamp && frame_timestamp != GST_CLOCK_TIME_NONE) { - /* Buffer with timestamp */ - if (priv->max_pts != GST_CLOCK_TIME_NONE && - frame_timestamp < priv->max_pts) { - frame_timestamp = priv->max_pts + - gst_util_uint64_scale((vol_hdr->fixed_vop_rate ? - vol_hdr->fixed_vop_time_increment : 1), - GST_SECOND, - vol_hdr->vop_time_increment_resolution); - } - } else { - /* Buffer without timestamp set */ - if (priv->max_pts == GST_CLOCK_TIME_NONE) /* first buffer */ - frame_timestamp = 0; - else { - GstClockTime tmp_pts; - tmp_pts = priv->pts_diff + priv->gop_pts + - vop_hdr->modulo_time_base * GST_SECOND + - gst_util_uint64_scale(vop_hdr->time_increment, - GST_SECOND, - vol_hdr->vop_time_increment_resolution); - if (tmp_pts > priv->max_pts) - frame_timestamp = tmp_pts; - else - frame_timestamp = priv->max_pts + - gst_util_uint64_scale((vol_hdr->fixed_vop_rate ? - vol_hdr->fixed_vop_time_increment : 1), - GST_SECOND, - vol_hdr->vop_time_increment_resolution); - } + frame_timestamp = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts; + if (frame_timestamp && frame_timestamp != GST_CLOCK_TIME_NONE) { + /* Buffer with timestamp */ + if (priv->max_pts != GST_CLOCK_TIME_NONE && frame_timestamp < priv->max_pts) { + frame_timestamp = priv->max_pts + + gst_util_uint64_scale ((vol_hdr->fixed_vop_rate ? + vol_hdr->fixed_vop_time_increment : 1), + GST_SECOND, vol_hdr->vop_time_increment_resolution); } + } else { + /* Buffer without timestamp set */ + if (priv->max_pts == GST_CLOCK_TIME_NONE) /* first buffer */ + frame_timestamp = 0; + else { + GstClockTime tmp_pts; + tmp_pts = priv->pts_diff + priv->gop_pts + + vop_hdr->modulo_time_base * GST_SECOND + + gst_util_uint64_scale (vop_hdr->time_increment, + GST_SECOND, vol_hdr->vop_time_increment_resolution); + if (tmp_pts > priv->max_pts) + frame_timestamp = tmp_pts; + else + frame_timestamp = priv->max_pts + + gst_util_uint64_scale ((vol_hdr->fixed_vop_rate ? + vol_hdr->fixed_vop_time_increment : 1), + GST_SECOND, vol_hdr->vop_time_increment_resolution); + } + } - priv->pts_diff = frame_timestamp - - (priv->gop_pts + vop_hdr->modulo_time_base * GST_SECOND + - gst_util_uint64_scale(vop_hdr->time_increment, GST_SECOND, - vol_hdr->vop_time_increment_resolution)); + priv->pts_diff = frame_timestamp - + (priv->gop_pts + vop_hdr->modulo_time_base * GST_SECOND + + gst_util_uint64_scale (vop_hdr->time_increment, GST_SECOND, + vol_hdr->vop_time_increment_resolution)); } - + static GstVaapiDecoderStatus -decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size) +decode_picture (GstVaapiDecoderMpeg4 * decoder, const guint8 * buf, + guint buf_size) { - GstMpeg4ParseResult parser_result = GST_MPEG4_PARSER_OK; - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr; - GstMpeg4VideoObjectLayer * const vol_hdr = &priv->vol_hdr; - GstMpeg4SpriteTrajectory * const sprite_trajectory = &priv->sprite_trajectory; - GstVaapiPicture *picture; - GstVaapiDecoderStatus status; - GstClockTime pts; + GstMpeg4ParseResult parser_result = GST_MPEG4_PARSER_OK; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstMpeg4VideoObjectPlane *const vop_hdr = &priv->vop_hdr; + GstMpeg4VideoObjectLayer *const vol_hdr = &priv->vol_hdr; + GstMpeg4SpriteTrajectory *const sprite_trajectory = &priv->sprite_trajectory; + GstVaapiPicture *picture; + GstVaapiDecoderStatus status; + GstClockTime pts; - // context depends on priv->width and priv->height, so we move parse_vop a little earlier - if (priv->is_svh) { - parser_result = gst_mpeg4_parse_video_plane_short_header(&priv->svh_hdr, buf, buf_size); + // context depends on priv->width and priv->height, so we move parse_vop a little earlier + if (priv->is_svh) { + parser_result = + gst_mpeg4_parse_video_plane_short_header (&priv->svh_hdr, buf, + buf_size); - } - else { - parser_result = gst_mpeg4_parse_video_object_plane(vop_hdr, sprite_trajectory, vol_hdr, buf, buf_size); - /* Need to skip this frame if VOP was not coded */ - if (GST_MPEG4_PARSER_OK == parser_result && !vop_hdr->coded) - return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; - } + } else { + parser_result = + gst_mpeg4_parse_video_object_plane (vop_hdr, sprite_trajectory, vol_hdr, + buf, buf_size); + /* Need to skip this frame if VOP was not coded */ + if (GST_MPEG4_PARSER_OK == parser_result && !vop_hdr->coded) + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; + } - if (parser_result != GST_MPEG4_PARSER_OK) { - GST_DEBUG("failed to parse picture header"); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } + if (parser_result != GST_MPEG4_PARSER_OK) { + GST_DEBUG ("failed to parse picture header"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } - if (priv->is_svh) { - priv->width = priv->svh_hdr.vop_width; - priv->height = priv->svh_hdr.vop_height; - } - else { - if (!vop_hdr->width && !vop_hdr->height) { - vop_hdr->width = vol_hdr->width; - vop_hdr->height = vol_hdr->height; - } - priv->width = vop_hdr->width; - priv->height = vop_hdr->height; + if (priv->is_svh) { + priv->width = priv->svh_hdr.vop_width; + priv->height = priv->svh_hdr.vop_height; + } else { + if (!vop_hdr->width && !vop_hdr->height) { + vop_hdr->width = vol_hdr->width; + vop_hdr->height = vol_hdr->height; } + priv->width = vop_hdr->width; + priv->height = vop_hdr->height; + } - status = ensure_context(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_DEBUG("failed to reset context"); - return status; - } - - if (priv->curr_picture) { - status = decode_current_picture(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - - priv->curr_picture = GST_VAAPI_PICTURE_NEW(MPEG4, decoder); - if (!priv->curr_picture) { - GST_DEBUG("failed to allocate picture"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - picture = priv->curr_picture; - - status = ensure_quant_matrix(decoder, picture); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_DEBUG("failed to reset quantizer matrix"); - return status; - } - - /* 7.6.7 Temporal prediction structure - * forward reference frame B B B B B B backward reference frame - * | | - * nearest I/P/S in the past with vop_coded ==1 | - * nearest I/P/S in the future with any vop_coded - * fixme, it said that B frame shouldn't use backward reference frame - * when backward reference frame coded is 0 - */ - if (priv->is_svh) { - priv->coding_type = priv->svh_hdr.picture_coding_type; - } - else { - priv->coding_type = priv->vop_hdr.coding_type; - } - switch (priv->coding_type) { - case GST_MPEG4_I_VOP: - picture->type = GST_VAAPI_PICTURE_TYPE_I; - if (priv->is_svh || vop_hdr->coded) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - break; - case GST_MPEG4_P_VOP: - picture->type = GST_VAAPI_PICTURE_TYPE_P; - if (priv->is_svh || vop_hdr->coded) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - break; - case GST_MPEG4_B_VOP: - picture->type = GST_VAAPI_PICTURE_TYPE_B; - break; - case GST_MPEG4_S_VOP: - picture->type = GST_VAAPI_PICTURE_TYPE_S; - // see 3.175 reference VOP - if (vop_hdr->coded) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - break; - default: - GST_DEBUG("unsupported picture type %d", priv->coding_type); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - - if (!priv->is_svh && !vop_hdr->coded) { - status = render_picture(decoder, priv->prev_picture); - return status; - } - - if (priv->is_svh) { - guint temp_ref = priv->svh_hdr.temporal_reference; - guint delta_ref; - - if (temp_ref < priv->prev_t_ref) { - temp_ref += 256; - } - delta_ref = temp_ref - priv->prev_t_ref; - - pts = priv->sync_time; - // see temporal_reference definition in spec, 30000/1001Hz - pts += gst_util_uint64_scale(delta_ref, GST_SECOND*1001, 30000); - priv->sync_time = pts; - priv->prev_t_ref = priv->svh_hdr.temporal_reference; - } - else { - /* Update priv->pts_diff */ - if (priv->calculate_pts_diff) { - calculate_pts_diff(decoder, vol_hdr, vop_hdr); - priv->calculate_pts_diff = FALSE; - } - - /* Update presentation time, 6.3.5 */ - if(vop_hdr->coding_type != GST_MPEG4_B_VOP) { - // increment basing on decoding order - priv->last_sync_time = priv->sync_time; - priv->sync_time = priv->last_sync_time + vop_hdr->modulo_time_base; - pts = priv->sync_time * GST_SECOND; - pts += gst_util_uint64_scale(vop_hdr->time_increment, GST_SECOND, vol_hdr->vop_time_increment_resolution); - priv->last_non_b_scale_time = priv->non_b_scale_time; - priv->non_b_scale_time = priv->sync_time * vol_hdr->vop_time_increment_resolution + vop_hdr->time_increment; - priv->trd = priv->non_b_scale_time - priv->last_non_b_scale_time; - } - else { - // increment basing on display oder - pts = (priv->last_sync_time + vop_hdr->modulo_time_base) * GST_SECOND; - pts += gst_util_uint64_scale(vop_hdr->time_increment, GST_SECOND, vol_hdr->vop_time_increment_resolution); - priv->trb = (priv->last_sync_time + vop_hdr->modulo_time_base) * vol_hdr->vop_time_increment_resolution + - vop_hdr->time_increment - priv->last_non_b_scale_time; - } - } - picture->pts = pts + priv->pts_diff; - if (priv->max_pts == GST_CLOCK_TIME_NONE || priv->max_pts < picture->pts) - priv->max_pts = picture->pts; - - /* Update reference pictures */ - /* XXX: consider priv->vol_hdr.low_delay, consider packed video frames for DivX/XviD */ - if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { - if (priv->next_picture) - status = render_picture(decoder, priv->next_picture); - gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture); - gst_vaapi_picture_replace(&priv->next_picture, picture); - } + status = ensure_context (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_DEBUG ("failed to reset context"); return status; + } + + if (priv->curr_picture) { + status = decode_current_picture (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + + priv->curr_picture = GST_VAAPI_PICTURE_NEW (MPEG4, decoder); + if (!priv->curr_picture) { + GST_DEBUG ("failed to allocate picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + picture = priv->curr_picture; + + status = ensure_quant_matrix (decoder, picture); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_DEBUG ("failed to reset quantizer matrix"); + return status; + } + + /* 7.6.7 Temporal prediction structure + * forward reference frame B B B B B B backward reference frame + * | | + * nearest I/P/S in the past with vop_coded ==1 | + * nearest I/P/S in the future with any vop_coded + * fixme, it said that B frame shouldn't use backward reference frame + * when backward reference frame coded is 0 + */ + if (priv->is_svh) { + priv->coding_type = priv->svh_hdr.picture_coding_type; + } else { + priv->coding_type = priv->vop_hdr.coding_type; + } + switch (priv->coding_type) { + case GST_MPEG4_I_VOP: + picture->type = GST_VAAPI_PICTURE_TYPE_I; + if (priv->is_svh || vop_hdr->coded) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + break; + case GST_MPEG4_P_VOP: + picture->type = GST_VAAPI_PICTURE_TYPE_P; + if (priv->is_svh || vop_hdr->coded) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + break; + case GST_MPEG4_B_VOP: + picture->type = GST_VAAPI_PICTURE_TYPE_B; + break; + case GST_MPEG4_S_VOP: + picture->type = GST_VAAPI_PICTURE_TYPE_S; + // see 3.175 reference VOP + if (vop_hdr->coded) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + break; + default: + GST_DEBUG ("unsupported picture type %d", priv->coding_type); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!priv->is_svh && !vop_hdr->coded) { + status = render_picture (decoder, priv->prev_picture); + return status; + } + + if (priv->is_svh) { + guint temp_ref = priv->svh_hdr.temporal_reference; + guint delta_ref; + + if (temp_ref < priv->prev_t_ref) { + temp_ref += 256; + } + delta_ref = temp_ref - priv->prev_t_ref; + + pts = priv->sync_time; + // see temporal_reference definition in spec, 30000/1001Hz + pts += gst_util_uint64_scale (delta_ref, GST_SECOND * 1001, 30000); + priv->sync_time = pts; + priv->prev_t_ref = priv->svh_hdr.temporal_reference; + } else { + /* Update priv->pts_diff */ + if (priv->calculate_pts_diff) { + calculate_pts_diff (decoder, vol_hdr, vop_hdr); + priv->calculate_pts_diff = FALSE; + } + + /* Update presentation time, 6.3.5 */ + if (vop_hdr->coding_type != GST_MPEG4_B_VOP) { + // increment basing on decoding order + priv->last_sync_time = priv->sync_time; + priv->sync_time = priv->last_sync_time + vop_hdr->modulo_time_base; + pts = priv->sync_time * GST_SECOND; + pts += + gst_util_uint64_scale (vop_hdr->time_increment, GST_SECOND, + vol_hdr->vop_time_increment_resolution); + priv->last_non_b_scale_time = priv->non_b_scale_time; + priv->non_b_scale_time = + priv->sync_time * vol_hdr->vop_time_increment_resolution + + vop_hdr->time_increment; + priv->trd = priv->non_b_scale_time - priv->last_non_b_scale_time; + } else { + // increment basing on display oder + pts = (priv->last_sync_time + vop_hdr->modulo_time_base) * GST_SECOND; + pts += + gst_util_uint64_scale (vop_hdr->time_increment, GST_SECOND, + vol_hdr->vop_time_increment_resolution); + priv->trb = + (priv->last_sync_time + + vop_hdr->modulo_time_base) * vol_hdr->vop_time_increment_resolution + + vop_hdr->time_increment - priv->last_non_b_scale_time; + } + } + picture->pts = pts + priv->pts_diff; + if (priv->max_pts == GST_CLOCK_TIME_NONE || priv->max_pts < picture->pts) + priv->max_pts = picture->pts; + + /* Update reference pictures */ + /* XXX: consider priv->vol_hdr.low_delay, consider packed video frames for DivX/XviD */ + if (GST_VAAPI_PICTURE_IS_REFERENCE (picture)) { + if (priv->next_picture) + status = render_picture (decoder, priv->next_picture); + gst_vaapi_picture_replace (&priv->prev_picture, priv->next_picture); + gst_vaapi_picture_replace (&priv->next_picture, picture); + } + return status; } static inline guint -get_vop_coding_type(GstVaapiPicture *picture) +get_vop_coding_type (GstVaapiPicture * picture) { - return picture->type - GST_VAAPI_PICTURE_TYPE_I; + return picture->type - GST_VAAPI_PICTURE_TYPE_I; } static gboolean -fill_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture) +fill_picture (GstVaapiDecoderMpeg4 * decoder, GstVaapiPicture * picture) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - VAPictureParameterBufferMPEG4 * const pic_param = picture->param; - GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + VAPictureParameterBufferMPEG4 *const pic_param = picture->param; + GstMpeg4VideoObjectPlane *const vop_hdr = &priv->vop_hdr; - /* Fill in VAPictureParameterBufferMPEG4 */ - pic_param->forward_reference_picture = VA_INVALID_ID; - pic_param->backward_reference_picture = VA_INVALID_ID; + /* Fill in VAPictureParameterBufferMPEG4 */ + pic_param->forward_reference_picture = VA_INVALID_ID; + pic_param->backward_reference_picture = VA_INVALID_ID; - pic_param->vol_fields.value = 0; - pic_param->vop_fields.value = 0; - if(priv->is_svh) { - // vol_hdr Parameters - pic_param->vol_fields.bits.short_video_header = 1; - // does the following vol_hdr parameters matter for short video header? - pic_param->vol_fields.bits.chroma_format = 1; // I420, see table 6-15. - pic_param->vol_fields.bits.interlaced = 0; - pic_param->vol_fields.bits.obmc_disable = 1; - pic_param->vol_fields.bits.sprite_enable = 0; - pic_param->vol_fields.bits.sprite_warping_accuracy = 0; - pic_param->vol_fields.bits.quant_type = 0; //method 1; $7.4.4 - pic_param->vol_fields.bits.quarter_sample = 0; - pic_param->vol_fields.bits.data_partitioned = 0; - pic_param->vol_fields.bits.reversible_vlc = 0; - pic_param->vol_fields.bits.resync_marker_disable = 1; - pic_param->no_of_sprite_warping_points = 0; - pic_param->quant_precision = 5; - // VOP parameters - pic_param->vop_width = priv->svh_hdr.vop_width; - pic_param->vop_height = priv->svh_hdr.vop_height; - pic_param->vop_fields.bits.vop_coding_type = priv->svh_hdr.picture_coding_type; - pic_param->vop_time_increment_resolution = priv->vol_hdr.vop_time_increment_resolution; - - pic_param->num_gobs_in_vop = priv->svh_hdr.num_gobs_in_vop; - pic_param->num_macroblocks_in_gob = priv->svh_hdr.num_macroblocks_in_gob; + pic_param->vol_fields.value = 0; + pic_param->vop_fields.value = 0; + if (priv->is_svh) { + // vol_hdr Parameters + pic_param->vol_fields.bits.short_video_header = 1; + // does the following vol_hdr parameters matter for short video header? + pic_param->vol_fields.bits.chroma_format = 1; // I420, see table 6-15. + pic_param->vol_fields.bits.interlaced = 0; + pic_param->vol_fields.bits.obmc_disable = 1; + pic_param->vol_fields.bits.sprite_enable = 0; + pic_param->vol_fields.bits.sprite_warping_accuracy = 0; + pic_param->vol_fields.bits.quant_type = 0; //method 1; $7.4.4 + pic_param->vol_fields.bits.quarter_sample = 0; + pic_param->vol_fields.bits.data_partitioned = 0; + pic_param->vol_fields.bits.reversible_vlc = 0; + pic_param->vol_fields.bits.resync_marker_disable = 1; + pic_param->no_of_sprite_warping_points = 0; + pic_param->quant_precision = 5; + // VOP parameters + pic_param->vop_width = priv->svh_hdr.vop_width; + pic_param->vop_height = priv->svh_hdr.vop_height; + pic_param->vop_fields.bits.vop_coding_type = + priv->svh_hdr.picture_coding_type; + pic_param->vop_time_increment_resolution = + priv->vol_hdr.vop_time_increment_resolution; + + pic_param->num_gobs_in_vop = priv->svh_hdr.num_gobs_in_vop; + pic_param->num_macroblocks_in_gob = priv->svh_hdr.num_macroblocks_in_gob; + } else { + int i; + + // VOL parameters + pic_param->vol_fields.bits.short_video_header = 0; + pic_param->vol_fields.bits.chroma_format = priv->vol_hdr.chroma_format; + pic_param->vol_fields.bits.interlaced = priv->vol_hdr.interlaced; + pic_param->vol_fields.bits.obmc_disable = priv->vol_hdr.obmc_disable; + pic_param->vol_fields.bits.sprite_enable = priv->vol_hdr.sprite_enable; + pic_param->vol_fields.bits.sprite_warping_accuracy = + priv->vol_hdr.sprite_warping_accuracy; + pic_param->vol_fields.bits.quant_type = priv->vol_hdr.quant_type; + pic_param->vol_fields.bits.quarter_sample = priv->vol_hdr.quarter_sample; + pic_param->vol_fields.bits.data_partitioned = + priv->vol_hdr.data_partitioned; + pic_param->vol_fields.bits.reversible_vlc = priv->vol_hdr.reversible_vlc; + pic_param->vol_fields.bits.resync_marker_disable = + priv->vol_hdr.resync_marker_disable; + pic_param->no_of_sprite_warping_points = + priv->vol_hdr.no_of_sprite_warping_points; + + for (i = 0; i < 3 && i < priv->vol_hdr.no_of_sprite_warping_points; i++) { + pic_param->sprite_trajectory_du[i] = + priv->sprite_trajectory.vop_ref_points[i]; + pic_param->sprite_trajectory_dv[i] = + priv->sprite_trajectory.sprite_ref_points[i]; } - else { - int i; + pic_param->quant_precision = priv->vol_hdr.quant_precision; - // VOL parameters - pic_param->vol_fields.bits.short_video_header = 0; - pic_param->vol_fields.bits.chroma_format = priv->vol_hdr.chroma_format; - pic_param->vol_fields.bits.interlaced = priv->vol_hdr.interlaced; - pic_param->vol_fields.bits.obmc_disable = priv->vol_hdr.obmc_disable; - pic_param->vol_fields.bits.sprite_enable = priv->vol_hdr.sprite_enable; - pic_param->vol_fields.bits.sprite_warping_accuracy = priv->vol_hdr.sprite_warping_accuracy; - pic_param->vol_fields.bits.quant_type = priv->vol_hdr.quant_type; - pic_param->vol_fields.bits.quarter_sample = priv->vol_hdr.quarter_sample; - pic_param->vol_fields.bits.data_partitioned = priv->vol_hdr.data_partitioned; - pic_param->vol_fields.bits.reversible_vlc = priv->vol_hdr.reversible_vlc; - pic_param->vol_fields.bits.resync_marker_disable = priv->vol_hdr.resync_marker_disable; - pic_param->no_of_sprite_warping_points = priv->vol_hdr.no_of_sprite_warping_points; + // VOP parameters + pic_param->vop_width = vop_hdr->width; + pic_param->vop_height = vop_hdr->height; + pic_param->vop_fields.bits.vop_coding_type = vop_hdr->coding_type; + pic_param->vop_fields.bits.vop_rounding_type = vop_hdr->rounding_type; + pic_param->vop_fields.bits.intra_dc_vlc_thr = vop_hdr->intra_dc_vlc_thr; + pic_param->vop_fields.bits.top_field_first = vop_hdr->top_field_first; + pic_param->vop_fields.bits.alternate_vertical_scan_flag = + vop_hdr->alternate_vertical_scan_flag; - for (i=0; i<3 && ivol_hdr.no_of_sprite_warping_points ; i++) { - pic_param->sprite_trajectory_du[i] = priv->sprite_trajectory.vop_ref_points[i]; - pic_param->sprite_trajectory_dv[i] = priv->sprite_trajectory.sprite_ref_points[i]; - } - pic_param->quant_precision = priv->vol_hdr.quant_precision; - - // VOP parameters - pic_param->vop_width = vop_hdr->width; - pic_param->vop_height = vop_hdr->height; - pic_param->vop_fields.bits.vop_coding_type = vop_hdr->coding_type; - pic_param->vop_fields.bits.vop_rounding_type = vop_hdr->rounding_type; - pic_param->vop_fields.bits.intra_dc_vlc_thr = vop_hdr->intra_dc_vlc_thr; - pic_param->vop_fields.bits.top_field_first = vop_hdr->top_field_first; - pic_param->vop_fields.bits.alternate_vertical_scan_flag = vop_hdr->alternate_vertical_scan_flag; + pic_param->vop_fcode_forward = vop_hdr->fcode_forward; + pic_param->vop_fcode_backward = vop_hdr->fcode_backward; + pic_param->vop_time_increment_resolution = + priv->vol_hdr.vop_time_increment_resolution; + } - pic_param->vop_fcode_forward = vop_hdr->fcode_forward; - pic_param->vop_fcode_backward = vop_hdr->fcode_backward; - pic_param->vop_time_increment_resolution = priv->vol_hdr.vop_time_increment_resolution; - } - - pic_param->TRB = 0; - pic_param->TRD = 0; - switch (priv->coding_type) { + pic_param->TRB = 0; + pic_param->TRD = 0; + switch (priv->coding_type) { case GST_MPEG4_B_VOP: - pic_param->TRB = priv->trb; - pic_param->backward_reference_picture = priv->next_picture->surface_id; - pic_param->vop_fields.bits.backward_reference_vop_coding_type = get_vop_coding_type(priv->next_picture); - // fall-through + pic_param->TRB = priv->trb; + pic_param->backward_reference_picture = priv->next_picture->surface_id; + pic_param->vop_fields.bits.backward_reference_vop_coding_type = + get_vop_coding_type (priv->next_picture); + // fall-through case GST_MPEG4_P_VOP: - pic_param->TRD = priv->trd; - if (priv->prev_picture) - pic_param->forward_reference_picture = priv->prev_picture->surface_id; - break; - } + pic_param->TRD = priv->trd; + if (priv->prev_picture) + pic_param->forward_reference_picture = priv->prev_picture->surface_id; + break; + } - if (priv->vol_hdr.interlaced) { - priv->is_first_field ^= 1; - } - return TRUE; + if (priv->vol_hdr.interlaced) { + priv->is_first_field ^= 1; + } + return TRUE; } static GstVaapiDecoderStatus -decode_slice( - GstVaapiDecoderMpeg4 *decoder, - const guint8 *buf, - guint buf_size, - gboolean has_packet_header -) +decode_slice (GstVaapiDecoderMpeg4 * decoder, + const guint8 * buf, guint buf_size, gboolean has_packet_header) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstVaapiPicture * const picture = priv->curr_picture; - GstVaapiSlice *slice; - VASliceParameterBufferMPEG4 *slice_param; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstVaapiPicture *const picture = priv->curr_picture; + GstVaapiSlice *slice; + VASliceParameterBufferMPEG4 *slice_param; - GST_DEBUG("decoder silce: %p, %u bytes)", buf, buf_size); + GST_DEBUG ("decoder silce: %p, %u bytes)", buf, buf_size); - // has_packet_header is ture for the 2+ slice - if (!has_packet_header && !fill_picture(decoder, picture)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + // has_packet_header is ture for the 2+ slice + if (!has_packet_header && !fill_picture (decoder, picture)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - slice = GST_VAAPI_SLICE_NEW(MPEG4, decoder, buf, buf_size); - if (!slice) { - GST_DEBUG("failed to allocate slice"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + slice = GST_VAAPI_SLICE_NEW (MPEG4, decoder, buf, buf_size); + if (!slice) { + GST_DEBUG ("failed to allocate slice"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + gst_vaapi_picture_add_slice (picture, slice); + + /* Fill in VASliceParameterBufferMPEG4 */ + slice_param = slice->param; + if (priv->is_svh) { + slice_param->macroblock_offset = (priv->svh_hdr.size) % 8; + slice_param->macroblock_number = 0; + // the header of first gob_layer is empty (gob_header_empty=1), use vop_quant + slice_param->quant_scale = priv->svh_hdr.vop_quant; + } else { + if (has_packet_header) { + slice_param->macroblock_offset = priv->packet_hdr.size % 8; + slice_param->macroblock_number = priv->packet_hdr.macroblock_number; + slice_param->quant_scale = priv->packet_hdr.quant_scale; + } else { + slice_param->macroblock_offset = priv->vop_hdr.size % 8; + slice_param->macroblock_number = 0; + slice_param->quant_scale = priv->vop_hdr.quant; } - gst_vaapi_picture_add_slice(picture, slice); - - /* Fill in VASliceParameterBufferMPEG4 */ - slice_param = slice->param; - if (priv->is_svh) { - slice_param->macroblock_offset = (priv->svh_hdr.size)%8; - slice_param->macroblock_number = 0; - // the header of first gob_layer is empty (gob_header_empty=1), use vop_quant - slice_param->quant_scale = priv->svh_hdr.vop_quant; - } - else { - if (has_packet_header) { - slice_param->macroblock_offset = priv->packet_hdr.size % 8; - slice_param->macroblock_number = priv->packet_hdr.macroblock_number; - slice_param->quant_scale = priv->packet_hdr.quant_scale; - } - else { - slice_param->macroblock_offset = priv->vop_hdr.size % 8; - slice_param->macroblock_number = 0; - slice_param->quant_scale = priv->vop_hdr.quant; - } - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet) +decode_packet (GstVaapiDecoderMpeg4 * decoder, GstMpeg4Packet packet) { - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstMpeg4Packet *tos = &packet; - GstVaapiDecoderStatus status; + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstMpeg4Packet *tos = &packet; + GstVaapiDecoderStatus status; - // packet.size is the size from current marker to the next. - if (tos->type == GST_MPEG4_VISUAL_OBJ_SEQ_START) { - status = decode_sequence(decoder, packet.data + packet.offset, packet.size); - } - else if (tos->type == GST_MPEG4_VISUAL_OBJ_SEQ_END) { - status = decode_sequence_end(decoder); - } - else if (tos->type == GST_MPEG4_VISUAL_OBJ) { - status = decode_visual_object(decoder, packet.data + packet.offset, packet.size); - } - else if (tos->type >= GST_MPEG4_VIDEO_OBJ_FIRST && tos->type <= GST_MPEG4_VIDEO_OBJ_LAST) { - GST_WARNING("unexpected marker: (GST_MPEG4_VIDEO_OBJ_FIRST, GST_MPEG4_VIDEO_OBJ_LAST)"); - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - } - else if (tos->type >= GST_MPEG4_VIDEO_LAYER_FIRST && tos->type <= GST_MPEG4_VIDEO_LAYER_LAST) { - status = decode_video_object_layer(decoder, packet.data + packet.offset, packet.size); - } - else if (tos->type == GST_MPEG4_GROUP_OF_VOP) { - status = decode_gop(decoder, packet.data + packet.offset, packet.size); - } - else if (tos->type == GST_MPEG4_VIDEO_OBJ_PLANE) { - GstMpeg4Packet video_packet; - const guint8 *_data; - gint _data_size; + // packet.size is the size from current marker to the next. + if (tos->type == GST_MPEG4_VISUAL_OBJ_SEQ_START) { + status = + decode_sequence (decoder, packet.data + packet.offset, packet.size); + } else if (tos->type == GST_MPEG4_VISUAL_OBJ_SEQ_END) { + status = decode_sequence_end (decoder); + } else if (tos->type == GST_MPEG4_VISUAL_OBJ) { + status = + decode_visual_object (decoder, packet.data + packet.offset, + packet.size); + } else if (tos->type >= GST_MPEG4_VIDEO_OBJ_FIRST + && tos->type <= GST_MPEG4_VIDEO_OBJ_LAST) { + GST_WARNING + ("unexpected marker: (GST_MPEG4_VIDEO_OBJ_FIRST, GST_MPEG4_VIDEO_OBJ_LAST)"); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + } else if (tos->type >= GST_MPEG4_VIDEO_LAYER_FIRST + && tos->type <= GST_MPEG4_VIDEO_LAYER_LAST) { + status = + decode_video_object_layer (decoder, packet.data + packet.offset, + packet.size); + } else if (tos->type == GST_MPEG4_GROUP_OF_VOP) { + status = decode_gop (decoder, packet.data + packet.offset, packet.size); + } else if (tos->type == GST_MPEG4_VIDEO_OBJ_PLANE) { + GstMpeg4Packet video_packet; + const guint8 *_data; + gint _data_size; - status = decode_picture(decoder, packet.data + packet.offset, packet.size); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - - /* decode slice - * A resync marker shall only be located immediately before a macroblock - * (or video packet header if exists) and aligned with a byte - * either start_code or resync_marker are scaned/measured by byte, - * while the header itself are parsed/measured in bit - * it means: resync_marker(video_packet_header) start from byte boundary, - * while MB doesn't start from byte boundary -- it is what 'macroblock_offset' - * in slice refer to - */ - _data = packet.data + packet.offset + priv->vop_hdr.size/8; - _data_size = packet.size - (priv->vop_hdr.size/8); - - if (priv->vol_hdr.resync_marker_disable) { - status = decode_slice(decoder, _data, _data_size, FALSE); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - else { - GstMpeg4ParseResult ret = GST_MPEG4_PARSER_OK; - gboolean first_slice = TRUE; - - // next start_code is required to determine the end of last slice - _data_size += 4; - - while (_data_size > 0) { - // we can skip user data here - ret = gst_mpeg4_parse(&video_packet, TRUE, &priv->vop_hdr, _data, 0, _data_size); - if(ret != GST_MPEG4_PARSER_OK) { - break; - } - - if (first_slice) { - status = decode_slice(decoder, _data, video_packet.size, FALSE); - first_slice = FALSE; - } - else { - _data += video_packet.offset; - _data_size -= video_packet.offset; - - ret = gst_mpeg4_parse_video_packet_header (&priv->packet_hdr, &priv->vol_hdr, &priv->vop_hdr, &priv->sprite_trajectory, _data, _data_size); - status = decode_slice(decoder,_data + priv->packet_hdr.size/8, video_packet.size - priv->packet_hdr.size/8, TRUE); - } - - _data += video_packet.size; - _data_size -= video_packet.size; - } - } - status = decode_current_picture(decoder); - } - else if (tos->type == GST_MPEG4_USER_DATA - || tos->type == GST_MPEG4_VIDEO_SESSION_ERR - || tos->type == GST_MPEG4_FBA - || tos->type == GST_MPEG4_FBA_PLAN - || tos->type == GST_MPEG4_MESH - || tos->type == GST_MPEG4_MESH_PLAN - || tos->type == GST_MPEG4_STILL_TEXTURE_OBJ - || tos->type == GST_MPEG4_TEXTURE_SPATIAL - || tos->type == GST_MPEG4_TEXTURE_SNR_LAYER - || tos->type == GST_MPEG4_TEXTURE_TILE - || tos->type == GST_MPEG4_SHAPE_LAYER - || tos->type == GST_MPEG4_STUFFING - || tos->type == GST_MPEG4_SYSTEM_FIRST - || tos->type == GST_MPEG4_SYSTEM_LAST) { - GST_WARNING("Ignore marker: %x\n", tos->type); - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - } - else { - GST_ERROR("unsupported start code %x\n", tos->type); - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - } - - return status; -} - -static GstVaapiDecoderStatus -decode_buffer(GstVaapiDecoderMpeg4 *decoder, const guchar *buf, guint buf_size) -{ - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstVaapiDecoderStatus status; - GstMpeg4Packet packet; - guint ofs; - - if (priv->is_svh) { - status = decode_picture(decoder, buf, buf_size); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - - ofs = priv->svh_hdr.size / 8; - status = decode_slice(decoder, buf + ofs, buf_size - ofs, FALSE); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - else { - packet.data = buf; - packet.offset = 0; - packet.size = buf_size; - packet.type = (GstMpeg4StartCode)packet.data[0]; - - status = decode_packet(decoder, packet); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -gst_vaapi_decoder_mpeg4_decode_codec_data(GstVaapiDecoder *base_decoder, - const guchar *_buf, guint _buf_size) -{ - GstVaapiDecoderMpeg4 * const decoder = - GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); - GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; - GstMpeg4ParseResult result = GST_MPEG4_PARSER_OK; - GstMpeg4Packet packet; - guchar *buf; - guint pos, buf_size; - - // add additional 0x000001b2 to enclose the last header - buf_size = _buf_size + 4; - buf = malloc(buf_size); - memcpy(buf, _buf, buf_size); - buf[buf_size-4] = 0; - buf[buf_size-3] = 0; - buf[buf_size-2] = 1; - buf[buf_size-1] = 0xb2; - - pos = 0; - - while (result == GST_MPEG4_PARSER_OK && pos < buf_size) { - result = gst_mpeg4_parse(&packet, FALSE, NULL, buf, pos, buf_size); - if (result != GST_MPEG4_PARSER_OK) { - break; - } - status = decode_packet(decoder, packet); - if (GST_VAAPI_DECODER_STATUS_SUCCESS == status) { - pos = packet.offset + packet.size; - } - else { - GST_WARNING("decode mp4 packet failed when decoding codec data\n"); - break; - } - } - free(buf); - return status; -} - -static GstVaapiDecoderStatus -ensure_decoder(GstVaapiDecoderMpeg4 *decoder) -{ - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstVaapiDecoderStatus status; - - if (!priv->is_opened) { - priv->is_opened = gst_vaapi_decoder_mpeg4_open(decoder); - if (!priv->is_opened) - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; - - status = gst_vaapi_decoder_decode_codec_data( - GST_VAAPI_DECODER_CAST(decoder)); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - -static GstVaapiDecoderStatus -gst_vaapi_decoder_mpeg4_parse(GstVaapiDecoder *base_decoder, - GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) -{ - GstVaapiDecoderMpeg4 * const decoder = - GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); - GstVaapiDecoderMpeg4Private * const priv = &decoder->priv; - GstVaapiDecoderStatus status; - GstMpeg4Packet packet; - GstMpeg4ParseResult result; - const guchar *buf; - guint size, buf_size, flags = 0; - - status = ensure_decoder(decoder); + status = decode_picture (decoder, packet.data + packet.offset, packet.size); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + /* decode slice + * A resync marker shall only be located immediately before a macroblock + * (or video packet header if exists) and aligned with a byte + * either start_code or resync_marker are scaned/measured by byte, + * while the header itself are parsed/measured in bit + * it means: resync_marker(video_packet_header) start from byte boundary, + * while MB doesn't start from byte boundary -- it is what 'macroblock_offset' + * in slice refer to + */ + _data = packet.data + packet.offset + priv->vop_hdr.size / 8; + _data_size = packet.size - (priv->vop_hdr.size / 8); + + if (priv->vol_hdr.resync_marker_disable) { + status = decode_slice (decoder, _data, _data_size, FALSE); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; + } else { + GstMpeg4ParseResult ret = GST_MPEG4_PARSER_OK; + gboolean first_slice = TRUE; - size = gst_adapter_available(adapter); - buf = gst_adapter_map(adapter, size); - if (!buf) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + // next start_code is required to determine the end of last slice + _data_size += 4; - packet.type = GST_MPEG4_USER_DATA; - if (priv->is_svh) - result = gst_h263_parse(&packet, buf, 0, size); - else - result = gst_mpeg4_parse(&packet, FALSE, NULL, buf, 0, size); - if (result == GST_MPEG4_PARSER_NO_PACKET_END && at_eos) - packet.size = size - packet.offset; - else if (result == GST_MPEG4_PARSER_ERROR) - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - else if (result != GST_MPEG4_PARSER_OK) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + while (_data_size > 0) { + // we can skip user data here + ret = + gst_mpeg4_parse (&video_packet, TRUE, &priv->vop_hdr, _data, 0, + _data_size); + if (ret != GST_MPEG4_PARSER_OK) { + break; + } - buf_size = packet.size; - gst_adapter_flush(adapter, packet.offset); - unit->size = buf_size; + if (first_slice) { + status = decode_slice (decoder, _data, video_packet.size, FALSE); + first_slice = FALSE; + } else { + _data += video_packet.offset; + _data_size -= video_packet.offset; - /* Check for start of new picture */ - switch (packet.type) { + ret = + gst_mpeg4_parse_video_packet_header (&priv->packet_hdr, + &priv->vol_hdr, &priv->vop_hdr, &priv->sprite_trajectory, _data, + _data_size); + status = + decode_slice (decoder, _data + priv->packet_hdr.size / 8, + video_packet.size - priv->packet_hdr.size / 8, TRUE); + } + + _data += video_packet.size; + _data_size -= video_packet.size; + } + } + status = decode_current_picture (decoder); + } else if (tos->type == GST_MPEG4_USER_DATA + || tos->type == GST_MPEG4_VIDEO_SESSION_ERR + || tos->type == GST_MPEG4_FBA + || tos->type == GST_MPEG4_FBA_PLAN + || tos->type == GST_MPEG4_MESH + || tos->type == GST_MPEG4_MESH_PLAN + || tos->type == GST_MPEG4_STILL_TEXTURE_OBJ + || tos->type == GST_MPEG4_TEXTURE_SPATIAL + || tos->type == GST_MPEG4_TEXTURE_SNR_LAYER + || tos->type == GST_MPEG4_TEXTURE_TILE + || tos->type == GST_MPEG4_SHAPE_LAYER + || tos->type == GST_MPEG4_STUFFING + || tos->type == GST_MPEG4_SYSTEM_FIRST + || tos->type == GST_MPEG4_SYSTEM_LAST) { + GST_WARNING ("Ignore marker: %x\n", tos->type); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + } else { + GST_ERROR ("unsupported start code %x\n", tos->type); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + } + + return status; +} + +static GstVaapiDecoderStatus +decode_buffer (GstVaapiDecoderMpeg4 * decoder, const guchar * buf, + guint buf_size) +{ + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; + GstMpeg4Packet packet; + guint ofs; + + if (priv->is_svh) { + status = decode_picture (decoder, buf, buf_size); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + ofs = priv->svh_hdr.size / 8; + status = decode_slice (decoder, buf + ofs, buf_size - ofs, FALSE); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } else { + packet.data = buf; + packet.offset = 0; + packet.size = buf_size; + packet.type = (GstMpeg4StartCode) packet.data[0]; + + status = decode_packet (decoder, packet); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg4_decode_codec_data (GstVaapiDecoder * base_decoder, + const guchar * _buf, guint _buf_size) +{ + GstVaapiDecoderMpeg4 *const decoder = + GST_VAAPI_DECODER_MPEG4_CAST (base_decoder); + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; + GstMpeg4ParseResult result = GST_MPEG4_PARSER_OK; + GstMpeg4Packet packet; + guchar *buf; + guint pos, buf_size; + + // add additional 0x000001b2 to enclose the last header + buf_size = _buf_size + 4; + buf = malloc (buf_size); + memcpy (buf, _buf, buf_size); + buf[buf_size - 4] = 0; + buf[buf_size - 3] = 0; + buf[buf_size - 2] = 1; + buf[buf_size - 1] = 0xb2; + + pos = 0; + + while (result == GST_MPEG4_PARSER_OK && pos < buf_size) { + result = gst_mpeg4_parse (&packet, FALSE, NULL, buf, pos, buf_size); + if (result != GST_MPEG4_PARSER_OK) { + break; + } + status = decode_packet (decoder, packet); + if (GST_VAAPI_DECODER_STATUS_SUCCESS == status) { + pos = packet.offset + packet.size; + } else { + GST_WARNING ("decode mp4 packet failed when decoding codec data\n"); + break; + } + } + free (buf); + return status; +} + +static GstVaapiDecoderStatus +ensure_decoder (GstVaapiDecoderMpeg4 * decoder) +{ + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; + + if (!priv->is_opened) { + priv->is_opened = gst_vaapi_decoder_mpeg4_open (decoder); + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + + status = + gst_vaapi_decoder_decode_codec_data (GST_VAAPI_DECODER_CAST (decoder)); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg4_parse (GstVaapiDecoder * base_decoder, + GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderMpeg4 *const decoder = + GST_VAAPI_DECODER_MPEG4_CAST (base_decoder); + GstVaapiDecoderMpeg4Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; + GstMpeg4Packet packet; + GstMpeg4ParseResult result; + const guchar *buf; + guint size, buf_size, flags = 0; + + status = ensure_decoder (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + + size = gst_adapter_available (adapter); + buf = gst_adapter_map (adapter, size); + if (!buf) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + packet.type = GST_MPEG4_USER_DATA; + if (priv->is_svh) + result = gst_h263_parse (&packet, buf, 0, size); + else + result = gst_mpeg4_parse (&packet, FALSE, NULL, buf, 0, size); + if (result == GST_MPEG4_PARSER_NO_PACKET_END && at_eos) + packet.size = size - packet.offset; + else if (result == GST_MPEG4_PARSER_ERROR) + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + else if (result != GST_MPEG4_PARSER_OK) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + buf_size = packet.size; + gst_adapter_flush (adapter, packet.offset); + unit->size = buf_size; + + /* Check for start of new picture */ + switch (packet.type) { case GST_MPEG4_VIDEO_SESSION_ERR: case GST_MPEG4_FBA: case GST_MPEG4_FBA_PLAN: @@ -1067,103 +1084,102 @@ gst_vaapi_decoder_mpeg4_parse(GstVaapiDecoder *base_decoder, case GST_MPEG4_TEXTURE_TILE: case GST_MPEG4_SHAPE_LAYER: case GST_MPEG4_STUFFING: - gst_adapter_flush(adapter, packet.size); - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + gst_adapter_flush (adapter, packet.size); + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; case GST_MPEG4_USER_DATA: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; - break; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + break; case GST_MPEG4_VISUAL_OBJ_SEQ_END: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; - flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; - break; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; + break; case GST_MPEG4_VIDEO_OBJ_PLANE: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; - /* fall-through */ + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + /* fall-through */ case GST_MPEG4_VISUAL_OBJ_SEQ_START: case GST_MPEG4_VISUAL_OBJ: case GST_MPEG4_GROUP_OF_VOP: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - break; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; default: - if (packet.type >= GST_MPEG4_VIDEO_OBJ_FIRST && - packet.type <= GST_MPEG4_VIDEO_OBJ_LAST) { - gst_adapter_flush(adapter, packet.size); - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - } - if (packet.type >= GST_MPEG4_VIDEO_LAYER_FIRST && - packet.type <= GST_MPEG4_VIDEO_LAYER_LAST) { - break; - } - if (packet.type >= GST_MPEG4_SYSTEM_FIRST && - packet.type <= GST_MPEG4_SYSTEM_LAST) { - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; - break; - } - GST_WARNING("unsupported start code (0x%02x)", packet.type); - return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - } - GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (packet.type >= GST_MPEG4_VIDEO_OBJ_FIRST && + packet.type <= GST_MPEG4_VIDEO_OBJ_LAST) { + gst_adapter_flush (adapter, packet.size); + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } + if (packet.type >= GST_MPEG4_VIDEO_LAYER_FIRST && + packet.type <= GST_MPEG4_VIDEO_LAYER_LAST) { + break; + } + if (packet.type >= GST_MPEG4_SYSTEM_FIRST && + packet.type <= GST_MPEG4_SYSTEM_LAST) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + break; + } + GST_WARNING ("unsupported start code (0x%02x)", packet.type); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base_decoder, - GstVaapiDecoderUnit *unit) +gst_vaapi_decoder_mpeg4_decode (GstVaapiDecoder * base_decoder, + GstVaapiDecoderUnit * unit) { - GstVaapiDecoderMpeg4 * const decoder = - GST_VAAPI_DECODER_MPEG4_CAST(base_decoder); - GstVaapiDecoderStatus status; - GstBuffer * const buffer = - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; - GstMapInfo map_info; + GstVaapiDecoderMpeg4 *const decoder = + GST_VAAPI_DECODER_MPEG4_CAST (base_decoder); + GstVaapiDecoderStatus status; + 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; + 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; - } + 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; + 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 void -gst_vaapi_decoder_mpeg4_class_init(GstVaapiDecoderMpeg4Class *klass) +gst_vaapi_decoder_mpeg4_class_init (GstVaapiDecoderMpeg4Class * klass) { - GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); - GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof(GstVaapiDecoderMpeg4); - object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize; + object_class->size = sizeof (GstVaapiDecoderMpeg4); + object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; - decoder_class->create = gst_vaapi_decoder_mpeg4_create; - decoder_class->destroy = gst_vaapi_decoder_mpeg4_destroy; - decoder_class->parse = gst_vaapi_decoder_mpeg4_parse; - decoder_class->decode = gst_vaapi_decoder_mpeg4_decode; + decoder_class->create = gst_vaapi_decoder_mpeg4_create; + decoder_class->destroy = gst_vaapi_decoder_mpeg4_destroy; + decoder_class->parse = gst_vaapi_decoder_mpeg4_parse; + decoder_class->decode = gst_vaapi_decoder_mpeg4_decode; - decoder_class->decode_codec_data = - gst_vaapi_decoder_mpeg4_decode_codec_data; + decoder_class->decode_codec_data = gst_vaapi_decoder_mpeg4_decode_codec_data; } static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_mpeg4_class(void) +gst_vaapi_decoder_mpeg4_class (void) { - static GstVaapiDecoderMpeg4Class g_class; - static gsize g_class_init = FALSE; + static GstVaapiDecoderMpeg4Class g_class; + static gsize g_class_init = FALSE; - if (g_once_init_enter(&g_class_init)) { - gst_vaapi_decoder_mpeg4_class_init(&g_class); - g_once_init_leave(&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS(&g_class); + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_decoder_mpeg4_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS (&g_class); } /** @@ -1177,8 +1193,8 @@ gst_vaapi_decoder_mpeg4_class(void) * Return value: the newly allocated #GstVaapiDecoder object */ GstVaapiDecoder * -gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps) +gst_vaapi_decoder_mpeg4_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new(gst_vaapi_decoder_mpeg4_class(), - display, caps); + return gst_vaapi_decoder_new (gst_vaapi_decoder_mpeg4_class (), + display, caps); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c index 8ffbf076ff..fd08a83e31 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.c @@ -38,14 +38,14 @@ * sub-classes. */ void -gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit) +gst_vaapi_decoder_unit_init (GstVaapiDecoderUnit * unit) { - unit->flags = 0; - unit->size = 0; - unit->offset = 0; + unit->flags = 0; + unit->size = 0; + unit->offset = 0; - unit->parsed_info = NULL; - unit->parsed_info_destroy_notify = NULL; + unit->parsed_info = NULL; + unit->parsed_info_destroy_notify = NULL; } /** @@ -59,9 +59,9 @@ gst_vaapi_decoder_unit_init(GstVaapiDecoderUnit *unit) * sub-classes. */ void -gst_vaapi_decoder_unit_clear(GstVaapiDecoderUnit *unit) +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, NULL, NULL); } /** @@ -77,13 +77,13 @@ gst_vaapi_decoder_unit_clear(GstVaapiDecoderUnit *unit) * function will be called before the @parsed_info is replaced. */ void -gst_vaapi_decoder_unit_set_parsed_info(GstVaapiDecoderUnit *unit, +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)); + 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; + 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; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 1aabe13d15..9289eac917 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -42,37 +42,38 @@ #define GST_VAAPI_DECODER_VC1_CAST(decoder) \ ((GstVaapiDecoderVC1 *)(decoder)) -typedef struct _GstVaapiDecoderVC1Private GstVaapiDecoderVC1Private; -typedef struct _GstVaapiDecoderVC1Class GstVaapiDecoderVC1Class; +typedef struct _GstVaapiDecoderVC1Private GstVaapiDecoderVC1Private; +typedef struct _GstVaapiDecoderVC1Class GstVaapiDecoderVC1Class; /** * GstVaapiDecoderVC1: * * A decoder based on VC1. */ -struct _GstVaapiDecoderVC1Private { - GstVaapiProfile profile; - guint width; - guint height; - GstVC1SeqHdr seq_hdr; - GstVC1EntryPointHdr entrypoint_hdr; - GstVC1FrameHdr frame_hdr; - GstVC1BitPlanes *bitplanes; - GstVaapiPicture *current_picture; - GstVaapiPicture *last_non_b_picture; - GstVaapiDpb *dpb; - gint32 next_poc; - guint8 *rbdu_buffer; - guint8 rndctrl; - guint rbdu_buffer_size; - guint is_opened : 1; - guint is_first_field : 1; - guint has_codec_data : 1; - guint has_entrypoint : 1; - guint size_changed : 1; - guint profile_changed : 1; - guint closed_entry : 1; - guint broken_link : 1; +struct _GstVaapiDecoderVC1Private +{ + GstVaapiProfile profile; + guint width; + guint height; + GstVC1SeqHdr seq_hdr; + GstVC1EntryPointHdr entrypoint_hdr; + GstVC1FrameHdr frame_hdr; + GstVC1BitPlanes *bitplanes; + GstVaapiPicture *current_picture; + GstVaapiPicture *last_non_b_picture; + GstVaapiDpb *dpb; + gint32 next_poc; + guint8 *rbdu_buffer; + guint8 rndctrl; + guint rbdu_buffer_size; + guint is_opened:1; + guint is_first_field:1; + guint has_codec_data:1; + guint has_entrypoint:1; + guint size_changed:1; + guint profile_changed:1; + guint closed_entry:1; + guint broken_link:1; }; /** @@ -80,10 +81,11 @@ struct _GstVaapiDecoderVC1Private { * * A decoder based on VC1. */ -struct _GstVaapiDecoderVC1 { - /*< private >*/ - GstVaapiDecoder parent_instance; - GstVaapiDecoderVC1Private priv; +struct _GstVaapiDecoderVC1 +{ + /*< private > */ + GstVaapiDecoder parent_instance; + GstVaapiDecoderVC1Private priv; }; /** @@ -91,1339 +93,1339 @@ struct _GstVaapiDecoderVC1 { * * A decoder class based on VC1. */ -struct _GstVaapiDecoderVC1Class { - /*< private >*/ - GstVaapiDecoderClass parent_class; +struct _GstVaapiDecoderVC1Class +{ + /*< private > */ + GstVaapiDecoderClass parent_class; }; static GstVaapiDecoderStatus -get_status(GstVC1ParserResult result) +get_status (GstVC1ParserResult result) { - GstVaapiDecoderStatus status; + GstVaapiDecoderStatus status; - switch (result) { + switch (result) { case GST_VC1_PARSER_OK: - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; case GST_VC1_PARSER_NO_BDU_END: - status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - break; + status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + break; case GST_VC1_PARSER_ERROR: - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; - break; + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; default: - status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + break; + } + return status; +} + +static void +gst_vaapi_decoder_vc1_close (GstVaapiDecoderVC1 * decoder) +{ + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + + gst_vaapi_picture_replace (&priv->last_non_b_picture, NULL); + gst_vaapi_picture_replace (&priv->current_picture, NULL); + gst_vaapi_dpb_replace (&priv->dpb, NULL); + + if (priv->bitplanes) { + gst_vc1_bitplanes_free (priv->bitplanes); + priv->bitplanes = NULL; + } +} + +static gboolean +gst_vaapi_decoder_vc1_open (GstVaapiDecoderVC1 * decoder) +{ + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + + gst_vaapi_decoder_vc1_close (decoder); + + priv->dpb = gst_vaapi_dpb_new (2); + if (!priv->dpb) + return FALSE; + + priv->bitplanes = gst_vc1_bitplanes_new (); + if (!priv->bitplanes) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_decoder_vc1_destroy (GstVaapiDecoder * base_decoder) +{ + GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder); + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + + gst_vaapi_decoder_vc1_close (decoder); + + if (priv->rbdu_buffer) { + g_free (priv->rbdu_buffer); + priv->rbdu_buffer = NULL; + priv->rbdu_buffer_size = 0; + } +} + +static gboolean +gst_vaapi_decoder_vc1_create (GstVaapiDecoder * base_decoder) +{ + GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder); + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + + priv->profile = (GstVaapiProfile) 0; + priv->rndctrl = 0; + return TRUE; +} + +static GstVaapiDecoderStatus +ensure_context (GstVaapiDecoderVC1 * decoder) +{ + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + 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_VC1_SIMPLE) + profiles[n_profiles++] = GST_VAAPI_PROFILE_VC1_MAIN; + + for (i = 0; i < n_profiles; i++) { + if (gst_vaapi_display_has_decoder (GST_VAAPI_DECODER_DISPLAY (decoder), + profiles[i], entrypoint)) break; } - return status; -} + if (i == n_profiles) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + priv->profile = profiles[i]; + } -static void -gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder) -{ - GstVaapiDecoderVC1Private * const priv = &decoder->priv; + if (priv->size_changed) { + GST_DEBUG ("size changed"); + priv->size_changed = FALSE; + reset_context = TRUE; + } - gst_vaapi_picture_replace(&priv->last_non_b_picture, NULL); - gst_vaapi_picture_replace(&priv->current_picture, NULL); - gst_vaapi_dpb_replace(&priv->dpb, NULL); + if (reset_context) { + GstVaapiContextInfo info; - if (priv->bitplanes) { - gst_vc1_bitplanes_free(priv->bitplanes); - priv->bitplanes = NULL; - } -} - -static gboolean -gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder) -{ - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - - gst_vaapi_decoder_vc1_close(decoder); - - priv->dpb = gst_vaapi_dpb_new(2); - if (!priv->dpb) - return FALSE; - - priv->bitplanes = gst_vc1_bitplanes_new(); - if (!priv->bitplanes) - return FALSE; - return TRUE; -} - -static void -gst_vaapi_decoder_vc1_destroy(GstVaapiDecoder *base_decoder) -{ - GstVaapiDecoderVC1 * const decoder = - GST_VAAPI_DECODER_VC1_CAST(base_decoder); - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - - gst_vaapi_decoder_vc1_close(decoder); - - if (priv->rbdu_buffer) { - g_free(priv->rbdu_buffer); - priv->rbdu_buffer = NULL; - priv->rbdu_buffer_size = 0; - } -} - -static gboolean -gst_vaapi_decoder_vc1_create(GstVaapiDecoder *base_decoder) -{ - GstVaapiDecoderVC1 * const decoder = - GST_VAAPI_DECODER_VC1_CAST(base_decoder); - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - - priv->profile = (GstVaapiProfile)0; - priv->rndctrl = 0; - return TRUE; + 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 = 2; + 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_context(GstVaapiDecoderVC1 *decoder) +decode_current_picture (GstVaapiDecoderVC1 * decoder) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVaapiProfile profiles[2]; - GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; - guint i, n_profiles = 0; - gboolean reset_context = FALSE; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVaapiPicture *const picture = priv->current_picture; - 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_VC1_SIMPLE) - profiles[n_profiles++] = GST_VAAPI_PROFILE_VC1_MAIN; - - 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.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - info.width = priv->width; - info.height = priv->height; - info.ref_frames = 2; - reset_context = gst_vaapi_decoder_ensure_context( - GST_VAAPI_DECODER(decoder), - &info - ); - if (!reset_context) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } + if (!picture) return GST_VAAPI_DECODER_STATUS_SUCCESS; -} -static GstVaapiDecoderStatus -decode_current_picture(GstVaapiDecoderVC1 *decoder) -{ - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVaapiPicture * const picture = priv->current_picture; - - if (!picture) - return GST_VAAPI_DECODER_STATUS_SUCCESS; - - if (!gst_vaapi_picture_decode(picture)) - goto error; - if (GST_VAAPI_PICTURE_IS_COMPLETE(picture)) { - if (!gst_vaapi_dpb_add(priv->dpb, picture)) - goto error; - gst_vaapi_picture_replace(&priv->current_picture, NULL); - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_vaapi_picture_decode (picture)) + goto error; + if (GST_VAAPI_PICTURE_IS_COMPLETE (picture)) { + if (!gst_vaapi_dpb_add (priv->dpb, picture)) + goto error; + gst_vaapi_picture_replace (&priv->current_picture, NULL); + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; 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; + /* 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 -decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) +decode_sequence (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, + GstVC1BDU * ebdu) { - GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; - GstVC1AdvancedSeqHdr * const adv_hdr = &seq_hdr->advanced; - GstVC1SeqStructC * const structc = &seq_hdr->struct_c; - GstVC1ParserResult result; - GstVaapiProfile profile; - guint width, height, fps_n, fps_d, par_n, par_d; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr; + GstVC1AdvancedSeqHdr *const adv_hdr = &seq_hdr->advanced; + GstVC1SeqStructC *const structc = &seq_hdr->struct_c; + GstVC1ParserResult result; + GstVaapiProfile profile; + guint width, height, fps_n, fps_d, par_n, par_d; - result = gst_vc1_parse_sequence_header( - rbdu->data + rbdu->offset, - rbdu->size, - seq_hdr - ); - if (result != GST_VC1_PARSER_OK) { - GST_ERROR("failed to parse sequence layer"); - return get_status(result); - } + result = gst_vc1_parse_sequence_header (rbdu->data + rbdu->offset, + rbdu->size, seq_hdr); + if (result != GST_VC1_PARSER_OK) { + GST_ERROR ("failed to parse sequence layer"); + return get_status (result); + } - priv->has_entrypoint = FALSE; + priv->has_entrypoint = FALSE; - /* Reset POC */ - if (priv->last_non_b_picture) { - if (priv->last_non_b_picture->poc == priv->next_poc) - priv->next_poc++; - gst_vaapi_picture_replace(&priv->last_non_b_picture, NULL); - } + /* Reset POC */ + if (priv->last_non_b_picture) { + if (priv->last_non_b_picture->poc == priv->next_poc) + priv->next_poc++; + gst_vaapi_picture_replace (&priv->last_non_b_picture, NULL); + } - /* Validate profile */ - switch (seq_hdr->profile) { + /* Validate profile */ + switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: case GST_VC1_PROFILE_MAIN: case GST_VC1_PROFILE_ADVANCED: - break; + break; default: - GST_ERROR("unsupported profile %d", seq_hdr->profile); - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - } + GST_ERROR ("unsupported profile %d", seq_hdr->profile); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } - fps_n = 0; - fps_d = 0; - par_n = 0; - par_d = 0; - switch (seq_hdr->profile) { + fps_n = 0; + fps_d = 0; + par_n = 0; + par_d = 0; + switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: case GST_VC1_PROFILE_MAIN: - if (structc->wmvp) { - fps_n = structc->framerate; - fps_d = 1; - } - break; + if (structc->wmvp) { + fps_n = structc->framerate; + fps_d = 1; + } + break; case GST_VC1_PROFILE_ADVANCED: - fps_n = adv_hdr->fps_n; - fps_d = adv_hdr->fps_d; - par_n = adv_hdr->par_n; - par_d = adv_hdr->par_d; - break; + fps_n = adv_hdr->fps_n; + fps_d = adv_hdr->fps_d; + par_n = adv_hdr->par_n; + par_d = adv_hdr->par_d; + break; default: - g_assert(0 && "XXX: we already validated the profile above"); - break; - } + g_assert (0 && "XXX: we already validated the profile above"); + break; + } - if (fps_n && fps_d) - gst_vaapi_decoder_set_framerate(base_decoder, fps_n, fps_d); + if (fps_n && fps_d) + gst_vaapi_decoder_set_framerate (base_decoder, fps_n, fps_d); - if (par_n > 0 && par_d > 0) - gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, par_n, par_d); + if (par_n > 0 && par_d > 0) + gst_vaapi_decoder_set_pixel_aspect_ratio (base_decoder, par_n, par_d); - switch (seq_hdr->profile) { + switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: case GST_VC1_PROFILE_MAIN: - width = seq_hdr->struct_c.coded_width; - height = seq_hdr->struct_c.coded_height; - break; + width = seq_hdr->struct_c.coded_width; + height = seq_hdr->struct_c.coded_height; + break; case GST_VC1_PROFILE_ADVANCED: - width = seq_hdr->advanced.max_coded_width; - height = seq_hdr->advanced.max_coded_height; - break; + width = seq_hdr->advanced.max_coded_width; + height = seq_hdr->advanced.max_coded_height; + break; default: - g_assert(0 && "XXX: we already validated the profile above"); - break; - } + g_assert (0 && "XXX: we already validated the profile above"); + break; + } - if (priv->width != width) { - priv->width = width; - priv->size_changed = TRUE; - } + if (priv->width != width) { + priv->width = width; + priv->size_changed = TRUE; + } - if (priv->height != height) { - priv->height = height; - priv->size_changed = TRUE; - } + if (priv->height != height) { + priv->height = height; + priv->size_changed = TRUE; + } - switch (seq_hdr->profile) { + switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: - profile = GST_VAAPI_PROFILE_VC1_SIMPLE; - break; + profile = GST_VAAPI_PROFILE_VC1_SIMPLE; + break; case GST_VC1_PROFILE_MAIN: - profile = GST_VAAPI_PROFILE_VC1_MAIN; - break; + profile = GST_VAAPI_PROFILE_VC1_MAIN; + break; case GST_VC1_PROFILE_ADVANCED: - profile = GST_VAAPI_PROFILE_VC1_ADVANCED; - break; + profile = GST_VAAPI_PROFILE_VC1_ADVANCED; + break; default: - g_assert(0 && "XXX: we already validated the profile above"); - break; - } - if (priv->profile != profile) { - priv->profile = profile; - priv->profile_changed = TRUE; - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; + g_assert (0 && "XXX: we already validated the profile above"); + break; + } + if (priv->profile != profile) { + priv->profile = profile; + priv->profile_changed = TRUE; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_sequence_end(GstVaapiDecoderVC1 *decoder) +decode_sequence_end (GstVaapiDecoderVC1 * decoder) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVaapiDecoderStatus status; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; - status = decode_current_picture(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; + status = decode_current_picture (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; - gst_vaapi_dpb_flush(priv->dpb); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_vaapi_dpb_flush (priv->dpb); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_entry_point(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) +decode_entry_point (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, + GstVC1BDU * ebdu) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; - GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr; - GstVC1ParserResult result; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr; + GstVC1EntryPointHdr *const entrypoint_hdr = &priv->entrypoint_hdr; + GstVC1ParserResult result; - result = gst_vc1_parse_entry_point_header( - rbdu->data + rbdu->offset, - rbdu->size, - entrypoint_hdr, - seq_hdr - ); - if (result != GST_VC1_PARSER_OK) { - GST_ERROR("failed to parse entrypoint layer"); - return get_status(result); - } + result = gst_vc1_parse_entry_point_header (rbdu->data + rbdu->offset, + rbdu->size, entrypoint_hdr, seq_hdr); + if (result != GST_VC1_PARSER_OK) { + GST_ERROR ("failed to parse entrypoint layer"); + return get_status (result); + } - if (entrypoint_hdr->coded_size_flag) { - priv->width = entrypoint_hdr->coded_width; - priv->height = entrypoint_hdr->coded_height; - priv->size_changed = TRUE; - } + if (entrypoint_hdr->coded_size_flag) { + priv->width = entrypoint_hdr->coded_width; + priv->height = entrypoint_hdr->coded_height; + priv->size_changed = TRUE; + } - priv->has_entrypoint = TRUE; - priv->closed_entry = entrypoint_hdr->closed_entry; - priv->broken_link = entrypoint_hdr->broken_link; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + priv->has_entrypoint = TRUE; + priv->closed_entry = entrypoint_hdr->closed_entry; + priv->broken_link = entrypoint_hdr->broken_link; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } /* Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */ static guint -get_PTYPE(guint ptype) +get_PTYPE (guint ptype) { - switch (ptype) { - case GST_VC1_PICTURE_TYPE_I: return 0; - case GST_VC1_PICTURE_TYPE_P: return 1; - case GST_VC1_PICTURE_TYPE_B: return 2; - case GST_VC1_PICTURE_TYPE_BI: return 3; - } - return 4; /* skipped P-frame */ + switch (ptype) { + case GST_VC1_PICTURE_TYPE_I: + return 0; + case GST_VC1_PICTURE_TYPE_P: + return 1; + case GST_VC1_PICTURE_TYPE_B: + return 2; + case GST_VC1_PICTURE_TYPE_BI: + return 3; + } + return 4; /* skipped P-frame */ } /* Reconstruct bitstream BFRACTION (7.1.1.14, index into Table-40) */ static guint -get_BFRACTION(guint bfraction) +get_BFRACTION (guint bfraction) { - guint i; + guint i; - static const struct { - guint16 index; - guint16 value; - } - bfraction_map[] = { - { 0, GST_VC1_BFRACTION_BASIS / 2 }, - { 1, GST_VC1_BFRACTION_BASIS / 3 }, - { 2, (GST_VC1_BFRACTION_BASIS * 2) / 3 }, - { 3, GST_VC1_BFRACTION_BASIS / 4 }, - { 4, (GST_VC1_BFRACTION_BASIS * 3) / 4 }, - { 5, GST_VC1_BFRACTION_BASIS / 5 }, - { 6, (GST_VC1_BFRACTION_BASIS * 2) / 5 }, - { 7, (GST_VC1_BFRACTION_BASIS * 3) / 5 }, - { 8, (GST_VC1_BFRACTION_BASIS * 4) / 5 }, - { 9, GST_VC1_BFRACTION_BASIS / 6 }, - { 10, (GST_VC1_BFRACTION_BASIS * 5) / 6 }, - { 11, GST_VC1_BFRACTION_BASIS / 7 }, - { 12, (GST_VC1_BFRACTION_BASIS * 2) / 7 }, - { 13, (GST_VC1_BFRACTION_BASIS * 3) / 7 }, - { 14, (GST_VC1_BFRACTION_BASIS * 4) / 7 }, - { 15, (GST_VC1_BFRACTION_BASIS * 5) / 7 }, - { 16, (GST_VC1_BFRACTION_BASIS * 6) / 7 }, - { 17, GST_VC1_BFRACTION_BASIS / 8 }, - { 18, (GST_VC1_BFRACTION_BASIS * 3) / 8 }, - { 19, (GST_VC1_BFRACTION_BASIS * 5) / 8 }, - { 20, (GST_VC1_BFRACTION_BASIS * 7) / 8 }, - { 21, GST_VC1_BFRACTION_RESERVED }, - { 22, GST_VC1_BFRACTION_PTYPE_BI } - }; + static const struct + { + guint16 index; + guint16 value; + } + bfraction_map[] = { + { + 0, GST_VC1_BFRACTION_BASIS / 2}, { + 1, GST_VC1_BFRACTION_BASIS / 3}, { + 2, (GST_VC1_BFRACTION_BASIS * 2) / 3}, { + 3, GST_VC1_BFRACTION_BASIS / 4}, { + 4, (GST_VC1_BFRACTION_BASIS * 3) / 4}, { + 5, GST_VC1_BFRACTION_BASIS / 5}, { + 6, (GST_VC1_BFRACTION_BASIS * 2) / 5}, { + 7, (GST_VC1_BFRACTION_BASIS * 3) / 5}, { + 8, (GST_VC1_BFRACTION_BASIS * 4) / 5}, { + 9, GST_VC1_BFRACTION_BASIS / 6}, { + 10, (GST_VC1_BFRACTION_BASIS * 5) / 6}, { + 11, GST_VC1_BFRACTION_BASIS / 7}, { + 12, (GST_VC1_BFRACTION_BASIS * 2) / 7}, { + 13, (GST_VC1_BFRACTION_BASIS * 3) / 7}, { + 14, (GST_VC1_BFRACTION_BASIS * 4) / 7}, { + 15, (GST_VC1_BFRACTION_BASIS * 5) / 7}, { + 16, (GST_VC1_BFRACTION_BASIS * 6) / 7}, { + 17, GST_VC1_BFRACTION_BASIS / 8}, { + 18, (GST_VC1_BFRACTION_BASIS * 3) / 8}, { + 19, (GST_VC1_BFRACTION_BASIS * 5) / 8}, { + 20, (GST_VC1_BFRACTION_BASIS * 7) / 8}, { + 21, GST_VC1_BFRACTION_RESERVED}, { + 22, GST_VC1_BFRACTION_PTYPE_BI} + }; - if (!bfraction) - return 0; + if (!bfraction) + return 0; - for (i = 0; i < G_N_ELEMENTS(bfraction_map); i++) { - if (bfraction_map[i].value == bfraction) - return bfraction_map[i].index; - } - return 21; /* RESERVED */ + for (i = 0; i < G_N_ELEMENTS (bfraction_map); i++) { + if (bfraction_map[i].value == bfraction) + return bfraction_map[i].index; + } + return 21; /* RESERVED */ } /* Translate GStreamer MV modes to VA-API */ static guint -get_VAMvModeVC1(guint mvmode) +get_VAMvModeVC1 (guint mvmode) { - switch (mvmode) { - case GST_VC1_MVMODE_1MV_HPEL_BILINEAR: return VAMvMode1MvHalfPelBilinear; - case GST_VC1_MVMODE_1MV: return VAMvMode1Mv; - case GST_VC1_MVMODE_1MV_HPEL: return VAMvMode1MvHalfPel; - case GST_VC1_MVMODE_MIXED_MV: return VAMvModeMixedMv; - case GST_VC1_MVMODE_INTENSITY_COMP: return VAMvModeIntensityCompensation; - } - return 0; + switch (mvmode) { + case GST_VC1_MVMODE_1MV_HPEL_BILINEAR: + return VAMvMode1MvHalfPelBilinear; + case GST_VC1_MVMODE_1MV: + return VAMvMode1Mv; + case GST_VC1_MVMODE_1MV_HPEL: + return VAMvMode1MvHalfPel; + case GST_VC1_MVMODE_MIXED_MV: + return VAMvModeMixedMv; + case GST_VC1_MVMODE_INTENSITY_COMP: + return VAMvModeIntensityCompensation; + } + return 0; } /* Reconstruct bitstream MVMODE (7.1.1.32) */ static guint -get_MVMODE(GstVC1FrameHdr *frame_hdr) +get_MVMODE (GstVC1FrameHdr * frame_hdr) { - guint mvmode; + guint mvmode; - if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) - mvmode = frame_hdr->pic.advanced.mvmode; - else - mvmode = frame_hdr->pic.simple.mvmode; + if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) + mvmode = frame_hdr->pic.advanced.mvmode; + else + mvmode = frame_hdr->pic.simple.mvmode; - if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P || - frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B) - return get_VAMvModeVC1(mvmode); - return 0; + if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P || + frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B) + return get_VAMvModeVC1 (mvmode); + return 0; } /* Reconstruct bitstream MVMODE2 (7.1.1.33) */ static guint -get_MVMODE2(GstVC1FrameHdr *frame_hdr) +get_MVMODE2 (GstVC1FrameHdr * frame_hdr) { - guint mvmode, mvmode2; + guint mvmode, mvmode2; - if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) { - mvmode = frame_hdr->pic.advanced.mvmode; - mvmode2 = frame_hdr->pic.advanced.mvmode2; - } - else { - mvmode = frame_hdr->pic.simple.mvmode; - mvmode2 = frame_hdr->pic.simple.mvmode2; - } + if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) { + mvmode = frame_hdr->pic.advanced.mvmode; + mvmode2 = frame_hdr->pic.advanced.mvmode2; + } else { + mvmode = frame_hdr->pic.simple.mvmode; + mvmode2 = frame_hdr->pic.simple.mvmode2; + } - if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P && - mvmode == GST_VC1_MVMODE_INTENSITY_COMP) - return get_VAMvModeVC1(mvmode2); - return 0; + if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P && + mvmode == GST_VC1_MVMODE_INTENSITY_COMP) + return get_VAMvModeVC1 (mvmode2); + return 0; } static inline int -has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder) +has_MVTYPEMB_bitplane (GstVaapiDecoderVC1 * decoder) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; - GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; - guint mvmode, mvmode2; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr; + GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr; + guint mvmode, mvmode2; - if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { - GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; - if (pic->mvtypemb) - return 0; - mvmode = pic->mvmode; - mvmode2 = pic->mvmode2; - } - else { - GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple; - if (pic->mvtypemb) - return 0; - mvmode = pic->mvmode; - mvmode2 = pic->mvmode2; - } - return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P && - (mvmode == GST_VC1_MVMODE_MIXED_MV || - (mvmode == GST_VC1_MVMODE_INTENSITY_COMP && + if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { + GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced; + if (pic->mvtypemb) + return 0; + mvmode = pic->mvmode; + mvmode2 = pic->mvmode2; + } else { + GstVC1PicSimpleMain *const pic = &frame_hdr->pic.simple; + if (pic->mvtypemb) + return 0; + mvmode = pic->mvmode; + mvmode2 = pic->mvmode2; + } + return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P && + (mvmode == GST_VC1_MVMODE_MIXED_MV || + (mvmode == GST_VC1_MVMODE_INTENSITY_COMP && mvmode2 == GST_VC1_MVMODE_MIXED_MV))); } static inline int -has_SKIPMB_bitplane(GstVaapiDecoderVC1 *decoder) +has_SKIPMB_bitplane (GstVaapiDecoderVC1 * decoder) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; - GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr; + GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr; - if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { - GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; - if (pic->skipmb) - return 0; - } - else { - GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple; - if (pic->skipmb) - return 0; - } - return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P || - frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B); + if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { + GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced; + if (pic->skipmb) + return 0; + } else { + GstVC1PicSimpleMain *const pic = &frame_hdr->pic.simple; + if (pic->skipmb) + return 0; + } + return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P || + frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B); } static inline int -has_DIRECTMB_bitplane(GstVaapiDecoderVC1 *decoder) +has_DIRECTMB_bitplane (GstVaapiDecoderVC1 * decoder) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; - GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr; + GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr; - if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { - GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; - if (pic->directmb) - return 0; - } - else { - GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple; - if (pic->directmb) - return 0; - } - return frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B; + if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { + GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced; + if (pic->directmb) + return 0; + } else { + GstVC1PicSimpleMain *const pic = &frame_hdr->pic.simple; + if (pic->directmb) + return 0; + } + return frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B; } static inline int -has_ACPRED_bitplane(GstVaapiDecoderVC1 *decoder) +has_ACPRED_bitplane (GstVaapiDecoderVC1 * decoder) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; - GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; - GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr; + GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr; + GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced; - if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED) - return 0; - if (pic->acpred) - return 0; - return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I || - frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI); + if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED) + return 0; + if (pic->acpred) + return 0; + return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I || + frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI); } static inline int -has_OVERFLAGS_bitplane(GstVaapiDecoderVC1 *decoder) +has_OVERFLAGS_bitplane (GstVaapiDecoderVC1 * decoder) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; - GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr; - GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; - GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr; + GstVC1EntryPointHdr *const entrypoint_hdr = &priv->entrypoint_hdr; + GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr; + GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced; - if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED) - return 0; - if (pic->overflags) - return 0; - return ((frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I || - frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) && - (entrypoint_hdr->overlap && frame_hdr->pquant <= 8) && - pic->condover == GST_VC1_CONDOVER_SELECT); + if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED) + return 0; + if (pic->overflags) + return 0; + return ((frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I || + frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) && + (entrypoint_hdr->overlap && frame_hdr->pquant <= 8) && + pic->condover == GST_VC1_CONDOVER_SELECT); } static inline void -pack_bitplanes(GstVaapiBitPlane *bitplane, guint n, const guint8 *bitplanes[3], guint x, guint y, guint stride) +pack_bitplanes (GstVaapiBitPlane * bitplane, guint n, + const guint8 * bitplanes[3], guint x, guint y, guint stride) { - const guint dst_index = n / 2; - const guint src_index = y * stride + x; - guint8 v = 0; + const guint dst_index = n / 2; + const guint src_index = y * stride + x; + guint8 v = 0; - if (bitplanes[0]) - v |= bitplanes[0][src_index]; - if (bitplanes[1]) - v |= bitplanes[1][src_index] << 1; - if (bitplanes[2]) - v |= bitplanes[2][src_index] << 2; - bitplane->data[dst_index] = (bitplane->data[dst_index] << 4) | v; + if (bitplanes[0]) + v |= bitplanes[0][src_index]; + if (bitplanes[1]) + v |= bitplanes[1][src_index] << 1; + if (bitplanes[2]) + v |= bitplanes[2][src_index] << 2; + bitplane->data[dst_index] = (bitplane->data[dst_index] << 4) | v; } static gboolean -fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) +fill_picture_structc (GstVaapiDecoderVC1 * decoder, GstVaapiPicture * picture) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - VAPictureParameterBufferVC1 * const pic_param = picture->param; - GstVC1SeqStructC * const structc = &priv->seq_hdr.struct_c; - GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; - GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + VAPictureParameterBufferVC1 *const pic_param = picture->param; + GstVC1SeqStructC *const structc = &priv->seq_hdr.struct_c; + GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr; + GstVC1PicSimpleMain *const pic = &frame_hdr->pic.simple; - /* Fill in VAPictureParameterBufferVC1 (simple/main profile bits) */ - pic_param->sequence_fields.bits.finterpflag = structc->finterpflag; - pic_param->sequence_fields.bits.multires = structc->multires; - pic_param->sequence_fields.bits.overlap = structc->overlap; - pic_param->sequence_fields.bits.syncmarker = structc->syncmarker; - pic_param->sequence_fields.bits.rangered = structc->rangered; - pic_param->sequence_fields.bits.max_b_frames = structc->maxbframes; - pic_param->conditional_overlap_flag = 0; /* advanced profile only */ - pic_param->fast_uvmc_flag = structc->fastuvmc; - pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction); - pic_param->cbp_table = pic->cbptab; - pic_param->mb_mode_table = 0; /* XXX: interlaced frame */ - pic_param->range_reduction_frame = pic->rangeredfrm; - pic_param->post_processing = 0; /* advanced profile only */ - pic_param->picture_resolution_index = pic->respic; - pic_param->luma_scale = pic->lumscale; - pic_param->luma_shift = pic->lumshift; - pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb; - pic_param->raw_coding.flags.direct_mb = pic->directmb; - pic_param->raw_coding.flags.skip_mb = pic->skipmb; - pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder); - pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder); - pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder); - pic_param->mv_fields.bits.mv_table = pic->mvtab; - pic_param->mv_fields.bits.extended_mv_flag = structc->extended_mv; - pic_param->mv_fields.bits.extended_mv_range = pic->mvrange; - pic_param->transform_fields.bits.variable_sized_transform_flag = structc->vstransform; - pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf; - pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm; - pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2; + /* Fill in VAPictureParameterBufferVC1 (simple/main profile bits) */ + pic_param->sequence_fields.bits.finterpflag = structc->finterpflag; + pic_param->sequence_fields.bits.multires = structc->multires; + pic_param->sequence_fields.bits.overlap = structc->overlap; + pic_param->sequence_fields.bits.syncmarker = structc->syncmarker; + pic_param->sequence_fields.bits.rangered = structc->rangered; + pic_param->sequence_fields.bits.max_b_frames = structc->maxbframes; + pic_param->conditional_overlap_flag = 0; /* advanced profile only */ + pic_param->fast_uvmc_flag = structc->fastuvmc; + pic_param->b_picture_fraction = get_BFRACTION (pic->bfraction); + pic_param->cbp_table = pic->cbptab; + pic_param->mb_mode_table = 0; /* XXX: interlaced frame */ + pic_param->range_reduction_frame = pic->rangeredfrm; + pic_param->post_processing = 0; /* advanced profile only */ + pic_param->picture_resolution_index = pic->respic; + pic_param->luma_scale = pic->lumscale; + pic_param->luma_shift = pic->lumshift; + pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb; + pic_param->raw_coding.flags.direct_mb = pic->directmb; + pic_param->raw_coding.flags.skip_mb = pic->skipmb; + pic_param->bitplane_present.flags.bp_mv_type_mb = + has_MVTYPEMB_bitplane (decoder); + pic_param->bitplane_present.flags.bp_direct_mb = + has_DIRECTMB_bitplane (decoder); + pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane (decoder); + pic_param->mv_fields.bits.mv_table = pic->mvtab; + pic_param->mv_fields.bits.extended_mv_flag = structc->extended_mv; + pic_param->mv_fields.bits.extended_mv_range = pic->mvrange; + pic_param->transform_fields.bits.variable_sized_transform_flag = + structc->vstransform; + pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf; + pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm; + pic_param->transform_fields.bits.transform_ac_codingset_idx2 = + pic->transacfrm2; - /* Refer to 8.3.7 Rounding control for Simple and Main Profile */ - if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I || - frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) - priv->rndctrl = 1; - else if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P) - priv->rndctrl ^= 1; + /* Refer to 8.3.7 Rounding control for Simple and Main Profile */ + if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I || + frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) + priv->rndctrl = 1; + else if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P) + priv->rndctrl ^= 1; - pic_param->rounding_control = priv->rndctrl; + pic_param->rounding_control = priv->rndctrl; - return TRUE; + return TRUE; } static gboolean -fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) +fill_picture_advanced (GstVaapiDecoderVC1 * decoder, GstVaapiPicture * picture) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - VAPictureParameterBufferVC1 * const pic_param = picture->param; - GstVC1AdvancedSeqHdr * const adv_hdr = &priv->seq_hdr.advanced; - GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr; - GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; - GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + VAPictureParameterBufferVC1 *const pic_param = picture->param; + GstVC1AdvancedSeqHdr *const adv_hdr = &priv->seq_hdr.advanced; + GstVC1EntryPointHdr *const entrypoint_hdr = &priv->entrypoint_hdr; + GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr; + GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced; - if (!priv->has_entrypoint) - return FALSE; + if (!priv->has_entrypoint) + return FALSE; - /* Fill in VAPictureParameterBufferVC1 (advanced profile bits) */ - pic_param->sequence_fields.bits.pulldown = adv_hdr->pulldown; - pic_param->sequence_fields.bits.interlace = adv_hdr->interlace; - pic_param->sequence_fields.bits.tfcntrflag = adv_hdr->tfcntrflag; - pic_param->sequence_fields.bits.finterpflag = adv_hdr->finterpflag; - pic_param->sequence_fields.bits.psf = adv_hdr->psf; - pic_param->sequence_fields.bits.overlap = entrypoint_hdr->overlap; - pic_param->entrypoint_fields.bits.broken_link = entrypoint_hdr->broken_link; - pic_param->entrypoint_fields.bits.closed_entry = entrypoint_hdr->closed_entry; - pic_param->entrypoint_fields.bits.panscan_flag = entrypoint_hdr->panscan_flag; - pic_param->entrypoint_fields.bits.loopfilter = entrypoint_hdr->loopfilter; - pic_param->conditional_overlap_flag = pic->condover; - pic_param->fast_uvmc_flag = entrypoint_hdr->fastuvmc; - pic_param->range_mapping_fields.bits.luma_flag = entrypoint_hdr->range_mapy_flag; - pic_param->range_mapping_fields.bits.luma = entrypoint_hdr->range_mapy; - pic_param->range_mapping_fields.bits.chroma_flag = entrypoint_hdr->range_mapuv_flag; - pic_param->range_mapping_fields.bits.chroma = entrypoint_hdr->range_mapuv; - pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction); - pic_param->cbp_table = pic->cbptab; - pic_param->mb_mode_table = 0; /* XXX: interlaced frame */ - pic_param->range_reduction_frame = 0; /* simple/main profile only */ - pic_param->rounding_control = pic->rndctrl; - pic_param->post_processing = pic->postproc; - pic_param->picture_resolution_index = 0; /* simple/main profile only */ - pic_param->luma_scale = pic->lumscale; - pic_param->luma_shift = pic->lumshift; - pic_param->picture_fields.bits.frame_coding_mode = pic->fcm; - pic_param->picture_fields.bits.top_field_first = pic->tff; - pic_param->picture_fields.bits.is_first_field = pic->fcm == 0; /* XXX: interlaced frame */ - pic_param->picture_fields.bits.intensity_compensation = pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP; - pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb; - pic_param->raw_coding.flags.direct_mb = pic->directmb; - pic_param->raw_coding.flags.skip_mb = pic->skipmb; - pic_param->raw_coding.flags.ac_pred = pic->acpred; - pic_param->raw_coding.flags.overflags = pic->overflags; - pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder); - pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder); - pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder); - pic_param->bitplane_present.flags.bp_ac_pred = has_ACPRED_bitplane(decoder); - pic_param->bitplane_present.flags.bp_overflags = has_OVERFLAGS_bitplane(decoder); - pic_param->reference_fields.bits.reference_distance_flag = entrypoint_hdr->refdist_flag; - pic_param->mv_fields.bits.mv_table = pic->mvtab; - pic_param->mv_fields.bits.extended_mv_flag = entrypoint_hdr->extended_mv; - pic_param->mv_fields.bits.extended_mv_range = pic->mvrange; - pic_param->mv_fields.bits.extended_dmv_flag = entrypoint_hdr->extended_dmv; - pic_param->pic_quantizer_fields.bits.dquant = entrypoint_hdr->dquant; - pic_param->pic_quantizer_fields.bits.quantizer = entrypoint_hdr->quantizer; - pic_param->transform_fields.bits.variable_sized_transform_flag = entrypoint_hdr->vstransform; - pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf; - pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm; - pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2; - return TRUE; + /* Fill in VAPictureParameterBufferVC1 (advanced profile bits) */ + pic_param->sequence_fields.bits.pulldown = adv_hdr->pulldown; + pic_param->sequence_fields.bits.interlace = adv_hdr->interlace; + pic_param->sequence_fields.bits.tfcntrflag = adv_hdr->tfcntrflag; + pic_param->sequence_fields.bits.finterpflag = adv_hdr->finterpflag; + pic_param->sequence_fields.bits.psf = adv_hdr->psf; + pic_param->sequence_fields.bits.overlap = entrypoint_hdr->overlap; + pic_param->entrypoint_fields.bits.broken_link = entrypoint_hdr->broken_link; + pic_param->entrypoint_fields.bits.closed_entry = entrypoint_hdr->closed_entry; + pic_param->entrypoint_fields.bits.panscan_flag = entrypoint_hdr->panscan_flag; + pic_param->entrypoint_fields.bits.loopfilter = entrypoint_hdr->loopfilter; + pic_param->conditional_overlap_flag = pic->condover; + pic_param->fast_uvmc_flag = entrypoint_hdr->fastuvmc; + pic_param->range_mapping_fields.bits.luma_flag = + entrypoint_hdr->range_mapy_flag; + pic_param->range_mapping_fields.bits.luma = entrypoint_hdr->range_mapy; + pic_param->range_mapping_fields.bits.chroma_flag = + entrypoint_hdr->range_mapuv_flag; + pic_param->range_mapping_fields.bits.chroma = entrypoint_hdr->range_mapuv; + pic_param->b_picture_fraction = get_BFRACTION (pic->bfraction); + pic_param->cbp_table = pic->cbptab; + pic_param->mb_mode_table = 0; /* XXX: interlaced frame */ + pic_param->range_reduction_frame = 0; /* simple/main profile only */ + pic_param->rounding_control = pic->rndctrl; + pic_param->post_processing = pic->postproc; + pic_param->picture_resolution_index = 0; /* simple/main profile only */ + pic_param->luma_scale = pic->lumscale; + pic_param->luma_shift = pic->lumshift; + pic_param->picture_fields.bits.frame_coding_mode = pic->fcm; + pic_param->picture_fields.bits.top_field_first = pic->tff; + pic_param->picture_fields.bits.is_first_field = pic->fcm == 0; /* XXX: interlaced frame */ + pic_param->picture_fields.bits.intensity_compensation = + pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP; + pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb; + pic_param->raw_coding.flags.direct_mb = pic->directmb; + pic_param->raw_coding.flags.skip_mb = pic->skipmb; + pic_param->raw_coding.flags.ac_pred = pic->acpred; + pic_param->raw_coding.flags.overflags = pic->overflags; + pic_param->bitplane_present.flags.bp_mv_type_mb = + has_MVTYPEMB_bitplane (decoder); + pic_param->bitplane_present.flags.bp_direct_mb = + has_DIRECTMB_bitplane (decoder); + pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane (decoder); + pic_param->bitplane_present.flags.bp_ac_pred = has_ACPRED_bitplane (decoder); + pic_param->bitplane_present.flags.bp_overflags = + has_OVERFLAGS_bitplane (decoder); + pic_param->reference_fields.bits.reference_distance_flag = + entrypoint_hdr->refdist_flag; + pic_param->mv_fields.bits.mv_table = pic->mvtab; + pic_param->mv_fields.bits.extended_mv_flag = entrypoint_hdr->extended_mv; + pic_param->mv_fields.bits.extended_mv_range = pic->mvrange; + pic_param->mv_fields.bits.extended_dmv_flag = entrypoint_hdr->extended_dmv; + pic_param->pic_quantizer_fields.bits.dquant = entrypoint_hdr->dquant; + pic_param->pic_quantizer_fields.bits.quantizer = entrypoint_hdr->quantizer; + pic_param->transform_fields.bits.variable_sized_transform_flag = + entrypoint_hdr->vstransform; + pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf; + pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm; + pic_param->transform_fields.bits.transform_ac_codingset_idx2 = + pic->transacfrm2; + return TRUE; } static gboolean -fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture) +fill_picture (GstVaapiDecoderVC1 * decoder, GstVaapiPicture * picture) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - VAPictureParameterBufferVC1 * const pic_param = picture->param; - GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; - GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; - GstVC1VopDquant * const vopdquant = &frame_hdr->vopdquant; - GstVaapiPicture *prev_picture, *next_picture; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + VAPictureParameterBufferVC1 *const pic_param = picture->param; + GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr; + GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr; + GstVC1VopDquant *const vopdquant = &frame_hdr->vopdquant; + GstVaapiPicture *prev_picture, *next_picture; - /* Fill in VAPictureParameterBufferVC1 (common fields) */ - pic_param->forward_reference_picture = VA_INVALID_ID; - pic_param->backward_reference_picture = VA_INVALID_ID; - pic_param->inloop_decoded_picture = VA_INVALID_ID; - pic_param->sequence_fields.value = 0; + /* Fill in VAPictureParameterBufferVC1 (common fields) */ + pic_param->forward_reference_picture = VA_INVALID_ID; + pic_param->backward_reference_picture = VA_INVALID_ID; + pic_param->inloop_decoded_picture = VA_INVALID_ID; + pic_param->sequence_fields.value = 0; #if VA_CHECK_VERSION(0,32,0) - pic_param->sequence_fields.bits.profile = seq_hdr->profile; + pic_param->sequence_fields.bits.profile = seq_hdr->profile; #endif - pic_param->coded_width = priv->width; - pic_param->coded_height = priv->height; - pic_param->entrypoint_fields.value = 0; - pic_param->range_mapping_fields.value = 0; - pic_param->picture_fields.value = 0; - pic_param->picture_fields.bits.picture_type = get_PTYPE(frame_hdr->ptype); - pic_param->raw_coding.value = 0; - pic_param->bitplane_present.value = 0; - pic_param->reference_fields.value = 0; - pic_param->mv_fields.value = 0; - pic_param->mv_fields.bits.mv_mode = get_MVMODE(frame_hdr); - pic_param->mv_fields.bits.mv_mode2 = get_MVMODE2(frame_hdr); - pic_param->pic_quantizer_fields.value = 0; - pic_param->pic_quantizer_fields.bits.half_qp = frame_hdr->halfqp; - pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = frame_hdr->pquant; - pic_param->pic_quantizer_fields.bits.pic_quantizer_type = frame_hdr->pquantizer; - pic_param->pic_quantizer_fields.bits.dq_frame = vopdquant->dquantfrm; - pic_param->pic_quantizer_fields.bits.dq_profile = vopdquant->dqprofile; - pic_param->pic_quantizer_fields.bits.dq_sb_edge = vopdquant->dqprofile == GST_VC1_DQPROFILE_SINGLE_EDGE ? vopdquant->dqbedge : 0; - pic_param->pic_quantizer_fields.bits.dq_db_edge = vopdquant->dqprofile == GST_VC1_DQPROFILE_DOUBLE_EDGES ? vopdquant->dqbedge : 0; - pic_param->pic_quantizer_fields.bits.dq_binary_level = vopdquant->dqbilevel; - pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = vopdquant->altpquant; - pic_param->transform_fields.value = 0; - pic_param->transform_fields.bits.transform_ac_codingset_idx1 = frame_hdr->transacfrm; - pic_param->transform_fields.bits.intra_transform_dc_table = frame_hdr->transdctab; + pic_param->coded_width = priv->width; + pic_param->coded_height = priv->height; + pic_param->entrypoint_fields.value = 0; + pic_param->range_mapping_fields.value = 0; + pic_param->picture_fields.value = 0; + pic_param->picture_fields.bits.picture_type = get_PTYPE (frame_hdr->ptype); + pic_param->raw_coding.value = 0; + pic_param->bitplane_present.value = 0; + pic_param->reference_fields.value = 0; + pic_param->mv_fields.value = 0; + pic_param->mv_fields.bits.mv_mode = get_MVMODE (frame_hdr); + pic_param->mv_fields.bits.mv_mode2 = get_MVMODE2 (frame_hdr); + pic_param->pic_quantizer_fields.value = 0; + pic_param->pic_quantizer_fields.bits.half_qp = frame_hdr->halfqp; + pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = frame_hdr->pquant; + pic_param->pic_quantizer_fields.bits.pic_quantizer_type = + frame_hdr->pquantizer; + pic_param->pic_quantizer_fields.bits.dq_frame = vopdquant->dquantfrm; + pic_param->pic_quantizer_fields.bits.dq_profile = vopdquant->dqprofile; + pic_param->pic_quantizer_fields.bits.dq_sb_edge = + vopdquant->dqprofile == + GST_VC1_DQPROFILE_SINGLE_EDGE ? vopdquant->dqbedge : 0; + pic_param->pic_quantizer_fields.bits.dq_db_edge = + vopdquant->dqprofile == + GST_VC1_DQPROFILE_DOUBLE_EDGES ? vopdquant->dqbedge : 0; + pic_param->pic_quantizer_fields.bits.dq_binary_level = vopdquant->dqbilevel; + pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = vopdquant->altpquant; + pic_param->transform_fields.value = 0; + pic_param->transform_fields.bits.transform_ac_codingset_idx1 = + frame_hdr->transacfrm; + pic_param->transform_fields.bits.intra_transform_dc_table = + frame_hdr->transdctab; - if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { - if (!fill_picture_advanced(decoder, picture)) - return FALSE; - } - else { - if (!fill_picture_structc(decoder, picture)) - return FALSE; - } + if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) { + if (!fill_picture_advanced (decoder, picture)) + return FALSE; + } else { + if (!fill_picture_structc (decoder, picture)) + return FALSE; + } - gst_vaapi_dpb_get_neighbours(priv->dpb, picture, - &prev_picture, &next_picture); + gst_vaapi_dpb_get_neighbours (priv->dpb, picture, + &prev_picture, &next_picture); + + switch (picture->type) { + case GST_VAAPI_PICTURE_TYPE_B: + if (next_picture) + pic_param->backward_reference_picture = next_picture->surface_id; + if (prev_picture) + pic_param->forward_reference_picture = prev_picture->surface_id; + else if (!priv->closed_entry) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_SKIPPED); + break; + case GST_VAAPI_PICTURE_TYPE_P: + if (prev_picture) + pic_param->forward_reference_picture = prev_picture->surface_id; + break; + default: + break; + } + + if (pic_param->bitplane_present.value) { + const guint8 *bitplanes[3]; + guint x, y, n; switch (picture->type) { - case GST_VAAPI_PICTURE_TYPE_B: - if (next_picture) - pic_param->backward_reference_picture = next_picture->surface_id; - if (prev_picture) - pic_param->forward_reference_picture = prev_picture->surface_id; - else if (!priv->closed_entry) - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_SKIPPED); + case GST_VAAPI_PICTURE_TYPE_P: + bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? + priv->bitplanes->directmb : NULL; + bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? + priv->bitplanes->skipmb : NULL; + bitplanes[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ? + priv->bitplanes->mvtypemb : NULL; break; - case GST_VAAPI_PICTURE_TYPE_P: - if (prev_picture) - pic_param->forward_reference_picture = prev_picture->surface_id; + case GST_VAAPI_PICTURE_TYPE_B: + bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? + priv->bitplanes->directmb : NULL; + bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? + priv->bitplanes->skipmb : NULL; + bitplanes[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */ break; - default: + case GST_VAAPI_PICTURE_TYPE_BI: + case GST_VAAPI_PICTURE_TYPE_I: + bitplanes[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */ + bitplanes[1] = pic_param->bitplane_present.flags.bp_ac_pred ? + priv->bitplanes->acpred : NULL; + bitplanes[2] = pic_param->bitplane_present.flags.bp_overflags ? + priv->bitplanes->overflags : NULL; + break; + default: + bitplanes[0] = NULL; + bitplanes[1] = NULL; + bitplanes[2] = NULL; break; } - if (pic_param->bitplane_present.value) { - const guint8 *bitplanes[3]; - guint x, y, n; + picture->bitplane = GST_VAAPI_BITPLANE_NEW (decoder, + (seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2); + if (!picture->bitplane) + return FALSE; - switch (picture->type) { - case GST_VAAPI_PICTURE_TYPE_P: - bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL; - bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL; - bitplanes[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ? priv->bitplanes->mvtypemb : NULL; - break; - case GST_VAAPI_PICTURE_TYPE_B: - bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL; - bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL; - bitplanes[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */ - break; - case GST_VAAPI_PICTURE_TYPE_BI: - case GST_VAAPI_PICTURE_TYPE_I: - bitplanes[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */ - bitplanes[1] = pic_param->bitplane_present.flags.bp_ac_pred ? priv->bitplanes->acpred : NULL; - bitplanes[2] = pic_param->bitplane_present.flags.bp_overflags ? priv->bitplanes->overflags : NULL; - break; - default: - bitplanes[0] = NULL; - bitplanes[1] = NULL; - bitplanes[2] = NULL; - break; - } - - picture->bitplane = GST_VAAPI_BITPLANE_NEW( - decoder, - (seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2 - ); - if (!picture->bitplane) - return FALSE; - - n = 0; - for (y = 0; y < seq_hdr->mb_height; y++) - for (x = 0; x < seq_hdr->mb_width; x++, n++) - pack_bitplanes(picture->bitplane, n, bitplanes, x, y, seq_hdr->mb_stride); - if (n & 1) /* move last nibble to the high order */ - picture->bitplane->data[n/2] <<= 4; - } - return TRUE; + n = 0; + for (y = 0; y < seq_hdr->mb_height; y++) + for (x = 0; x < seq_hdr->mb_width; x++, n++) + pack_bitplanes (picture->bitplane, n, bitplanes, x, y, + seq_hdr->mb_stride); + if (n & 1) /* move last nibble to the high order */ + picture->bitplane->data[n / 2] <<= 4; + } + return TRUE; } static GstVaapiDecoderStatus -decode_slice_chunk(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu, +decode_slice_chunk (GstVaapiDecoderVC1 * decoder, GstVC1BDU * ebdu, guint slice_addr, guint header_size) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVaapiPicture * const picture = priv->current_picture; - GstVaapiSlice *slice; - VASliceParameterBufferVC1 *slice_param; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVaapiPicture *const picture = priv->current_picture; + GstVaapiSlice *slice; + VASliceParameterBufferVC1 *slice_param; - slice = GST_VAAPI_SLICE_NEW(VC1, decoder, - ebdu->data + ebdu->sc_offset, - ebdu->size + ebdu->offset - ebdu->sc_offset); - if (!slice) { - GST_ERROR("failed to allocate slice"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - gst_vaapi_picture_add_slice(picture, slice); + slice = GST_VAAPI_SLICE_NEW (VC1, decoder, + ebdu->data + ebdu->sc_offset, + ebdu->size + ebdu->offset - ebdu->sc_offset); + if (!slice) { + GST_ERROR ("failed to allocate slice"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + gst_vaapi_picture_add_slice (picture, slice); - /* Fill in VASliceParameterBufferVC1 */ - slice_param = slice->param; - slice_param->macroblock_offset = 8 * (ebdu->offset - ebdu->sc_offset) + - header_size; - slice_param->slice_vertical_position = slice_addr; - return GST_VAAPI_DECODER_STATUS_SUCCESS; + /* Fill in VASliceParameterBufferVC1 */ + slice_param = slice->param; + slice_param->macroblock_offset = 8 * (ebdu->offset - ebdu->sc_offset) + + header_size; + slice_param->slice_vertical_position = slice_addr; + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) +decode_frame (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, GstVC1BDU * ebdu) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr; - GstVC1ParserResult result; - GstVaapiPicture * const picture = priv->current_picture; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr; + GstVC1ParserResult result; + GstVaapiPicture *const picture = priv->current_picture; - memset(frame_hdr, 0, sizeof(*frame_hdr)); - result = gst_vc1_parse_frame_header( - rbdu->data + rbdu->offset, - rbdu->size, - frame_hdr, - &priv->seq_hdr, - priv->bitplanes - ); - if (result != GST_VC1_PARSER_OK) { - GST_ERROR("failed to parse frame layer"); - return get_status(result); - } + memset (frame_hdr, 0, sizeof (*frame_hdr)); + result = gst_vc1_parse_frame_header (rbdu->data + rbdu->offset, + rbdu->size, frame_hdr, &priv->seq_hdr, priv->bitplanes); + if (result != GST_VC1_PARSER_OK) { + GST_ERROR ("failed to parse frame layer"); + return get_status (result); + } - switch (frame_hdr->ptype) { + switch (frame_hdr->ptype) { case GST_VC1_PICTURE_TYPE_I: - picture->type = GST_VAAPI_PICTURE_TYPE_I; - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - break; + picture->type = GST_VAAPI_PICTURE_TYPE_I; + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + break; case GST_VC1_PICTURE_TYPE_SKIPPED: case GST_VC1_PICTURE_TYPE_P: - picture->type = GST_VAAPI_PICTURE_TYPE_P; - GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); - break; + picture->type = GST_VAAPI_PICTURE_TYPE_P; + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_REFERENCE); + break; case GST_VC1_PICTURE_TYPE_B: - picture->type = GST_VAAPI_PICTURE_TYPE_B; - break; + picture->type = GST_VAAPI_PICTURE_TYPE_B; + break; case GST_VC1_PICTURE_TYPE_BI: - picture->type = GST_VAAPI_PICTURE_TYPE_BI; - break; + picture->type = GST_VAAPI_PICTURE_TYPE_BI; + break; default: - GST_ERROR("unsupported picture type %d", frame_hdr->ptype); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } + GST_ERROR ("unsupported picture type %d", frame_hdr->ptype); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } - /* Update presentation time */ - if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) { - picture->poc = priv->last_non_b_picture ? - (priv->last_non_b_picture->poc + 1) : priv->next_poc; - priv->next_poc = picture->poc + 1; - gst_vaapi_picture_replace(&priv->last_non_b_picture, picture); - } - else if (!priv->last_non_b_picture) - picture->poc = priv->next_poc++; - else { /* B or BI */ - picture->poc = priv->last_non_b_picture->poc++; - priv->next_poc = priv->last_non_b_picture->poc + 1; - } - picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts; + /* Update presentation time */ + if (GST_VAAPI_PICTURE_IS_REFERENCE (picture)) { + picture->poc = priv->last_non_b_picture ? + (priv->last_non_b_picture->poc + 1) : priv->next_poc; + priv->next_poc = picture->poc + 1; + gst_vaapi_picture_replace (&priv->last_non_b_picture, picture); + } else if (!priv->last_non_b_picture) + picture->poc = priv->next_poc++; + else { /* B or BI */ + picture->poc = priv->last_non_b_picture->poc++; + priv->next_poc = priv->last_non_b_picture->poc + 1; + } + picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts; - if (!fill_picture(decoder, picture)) - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - return decode_slice_chunk(decoder, ebdu, 0, frame_hdr->header_size); + if (!fill_picture (decoder, picture)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + return decode_slice_chunk (decoder, ebdu, 0, frame_hdr->header_size); } static GstVaapiDecoderStatus -decode_slice(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) +decode_slice (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, GstVC1BDU * ebdu) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVC1SliceHdr slice_hdr; - GstVC1ParserResult result; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVC1SliceHdr slice_hdr; + GstVC1ParserResult result; - memset(&slice_hdr, 0, sizeof(slice_hdr)); - result = gst_vc1_parse_slice_header( - rbdu->data + rbdu->offset, - rbdu->size, - &slice_hdr, - &priv->seq_hdr - ); - if (result != GST_VC1_PARSER_OK) { - GST_ERROR("failed to parse slice layer"); - return get_status(result); - } - return decode_slice_chunk(decoder, ebdu, slice_hdr.slice_addr, - slice_hdr.header_size); + memset (&slice_hdr, 0, sizeof (slice_hdr)); + result = gst_vc1_parse_slice_header (rbdu->data + rbdu->offset, + rbdu->size, &slice_hdr, &priv->seq_hdr); + if (result != GST_VC1_PARSER_OK) { + GST_ERROR ("failed to parse slice layer"); + return get_status (result); + } + return decode_slice_chunk (decoder, ebdu, slice_hdr.slice_addr, + slice_hdr.header_size); } static gboolean -decode_rbdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) +decode_rbdu (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, GstVC1BDU * ebdu) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - guint8 *rbdu_buffer; - guint i, j, rbdu_buffer_size; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + guint8 *rbdu_buffer; + guint i, j, rbdu_buffer_size; - /* BDU are encapsulated in advanced profile mode only */ - if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) { - memcpy(rbdu, ebdu, sizeof(*rbdu)); - return TRUE; - } - - /* Reallocate unescaped bitstream buffer */ - rbdu_buffer = priv->rbdu_buffer; - if (!rbdu_buffer || ebdu->size > priv->rbdu_buffer_size) { - rbdu_buffer = g_realloc(priv->rbdu_buffer, ebdu->size); - if (!rbdu_buffer) - return FALSE; - priv->rbdu_buffer = rbdu_buffer; - priv->rbdu_buffer_size = ebdu->size; - } - - /* Unescape bitstream buffer */ - if (ebdu->size < 4) { - memcpy(rbdu_buffer, ebdu->data + ebdu->offset, ebdu->size); - rbdu_buffer_size = ebdu->size; - } - else { - guint8 * const bdu_buffer = ebdu->data + ebdu->offset; - for (i = 0, j = 0; i < ebdu->size; i++) { - if (i >= 2 && i < ebdu->size - 1 && - bdu_buffer[i - 1] == 0x00 && - bdu_buffer[i - 2] == 0x00 && - bdu_buffer[i ] == 0x03 && - bdu_buffer[i + 1] <= 0x03) - i++; - rbdu_buffer[j++] = bdu_buffer[i]; - } - rbdu_buffer_size = j; - } - - /* Reconstruct RBDU */ - rbdu->type = ebdu->type; - rbdu->size = rbdu_buffer_size; - rbdu->sc_offset = 0; - rbdu->offset = 0; - rbdu->data = rbdu_buffer; + /* BDU are encapsulated in advanced profile mode only */ + if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) { + memcpy (rbdu, ebdu, sizeof (*rbdu)); return TRUE; + } + + /* Reallocate unescaped bitstream buffer */ + rbdu_buffer = priv->rbdu_buffer; + if (!rbdu_buffer || ebdu->size > priv->rbdu_buffer_size) { + rbdu_buffer = g_realloc (priv->rbdu_buffer, ebdu->size); + if (!rbdu_buffer) + return FALSE; + priv->rbdu_buffer = rbdu_buffer; + priv->rbdu_buffer_size = ebdu->size; + } + + /* Unescape bitstream buffer */ + if (ebdu->size < 4) { + memcpy (rbdu_buffer, ebdu->data + ebdu->offset, ebdu->size); + rbdu_buffer_size = ebdu->size; + } else { + guint8 *const bdu_buffer = ebdu->data + ebdu->offset; + for (i = 0, j = 0; i < ebdu->size; i++) { + if (i >= 2 && i < ebdu->size - 1 && + bdu_buffer[i - 1] == 0x00 && + bdu_buffer[i - 2] == 0x00 && + bdu_buffer[i] == 0x03 && bdu_buffer[i + 1] <= 0x03) + i++; + rbdu_buffer[j++] = bdu_buffer[i]; + } + rbdu_buffer_size = j; + } + + /* Reconstruct RBDU */ + rbdu->type = ebdu->type; + rbdu->size = rbdu_buffer_size; + rbdu->sc_offset = 0; + rbdu->offset = 0; + rbdu->data = rbdu_buffer; + return TRUE; } static GstVaapiDecoderStatus -decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu) +decode_ebdu (GstVaapiDecoderVC1 * decoder, GstVC1BDU * ebdu) { - GstVaapiDecoderStatus status; - GstVC1BDU rbdu; + GstVaapiDecoderStatus status; + GstVC1BDU rbdu; - if (!decode_rbdu(decoder, &rbdu, ebdu)) - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + if (!decode_rbdu (decoder, &rbdu, ebdu)) + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - switch (ebdu->type) { + switch (ebdu->type) { case GST_VC1_SEQUENCE: - status = decode_sequence(decoder, &rbdu, ebdu); - break; + status = decode_sequence (decoder, &rbdu, ebdu); + break; case GST_VC1_ENTRYPOINT: - status = decode_entry_point(decoder, &rbdu, ebdu); - break; + status = decode_entry_point (decoder, &rbdu, ebdu); + break; case GST_VC1_FRAME: - status = decode_frame(decoder, &rbdu, ebdu); - break; + status = decode_frame (decoder, &rbdu, ebdu); + break; case GST_VC1_SLICE: - status = decode_slice(decoder, &rbdu, ebdu); - break; + status = decode_slice (decoder, &rbdu, ebdu); + break; case GST_VC1_END_OF_SEQ: - status = decode_sequence_end(decoder); - break; + status = decode_sequence_end (decoder); + break; case GST_VC1_FIELD_USER: case GST_VC1_FRAME_USER: case GST_VC1_ENTRY_POINT_USER: case GST_VC1_SEQUENCE_USER: - /* Let's just ignore them */ - status = GST_VAAPI_DECODER_STATUS_SUCCESS; - break; + /* Let's just ignore them */ + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; default: - GST_WARNING("unsupported BDU type %d", ebdu->type); - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + GST_WARNING ("unsupported BDU type %d", ebdu->type); + status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + break; + } + return status; +} + +static GstVaapiDecoderStatus +decode_buffer (GstVaapiDecoderVC1 * decoder, guchar * buf, guint buf_size) +{ + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVC1BDU ebdu; + + if (priv->has_codec_data) { + ebdu.type = GST_VC1_FRAME; + ebdu.sc_offset = 0; + ebdu.offset = 0; + } else { + ebdu.type = buf[3]; + ebdu.sc_offset = 0; + ebdu.offset = 4; + } + ebdu.data = buf; + ebdu.size = buf_size - ebdu.offset; + return decode_ebdu (decoder, &ebdu); +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_vc1_decode_codec_data (GstVaapiDecoder * base_decoder, + const guchar * buf, guint buf_size) +{ + GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder); + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr; + GstVaapiDecoderStatus status; + GstVC1ParserResult result; + GstVC1BDU ebdu; + GstCaps *caps; + GstStructure *structure; + guint ofs; + gint width, height; + guint32 format; + gint version; + const gchar *s; + + priv->has_codec_data = TRUE; + + width = GST_VAAPI_DECODER_WIDTH (decoder); + height = GST_VAAPI_DECODER_HEIGHT (decoder); + if (!width || !height) { + GST_ERROR ("failed to parse size from codec-data"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + caps = GST_VAAPI_DECODER_CODEC_STATE (decoder)->caps; + structure = gst_caps_get_structure (caps, 0); + s = gst_structure_get_string (structure, "format"); + if (s && strlen (s) == 4) { + format = GST_MAKE_FOURCC (s[0], s[1], s[2], s[3]); + } else { + /* Try to determine format from "wmvversion" property */ + if (gst_structure_get_int (structure, "wmvversion", &version)) + format = (version >= 1 && version <= 3) ? + GST_MAKE_FOURCC ('W', 'M', 'V', ('0' + version)) : 0; + else + format = 0; + } + if (!format) { + GST_ERROR ("failed to parse profile from codec-data"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; + } + + /* WMV3 -- expecting sequence header */ + if (format == GST_MAKE_FOURCC ('W', 'M', 'V', '3')) { + seq_hdr->struct_c.coded_width = width; + seq_hdr->struct_c.coded_height = height; + ebdu.type = GST_VC1_SEQUENCE; + ebdu.size = buf_size; + ebdu.sc_offset = 0; + ebdu.offset = 0; + ebdu.data = (guint8 *) buf; + return decode_ebdu (decoder, &ebdu); + } + + /* WVC1 -- expecting bitstream data units */ + if (format != GST_MAKE_FOURCC ('W', 'V', 'C', '1')) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + seq_hdr->advanced.max_coded_width = width; + seq_hdr->advanced.max_coded_height = height; + + ofs = 0; + do { + result = gst_vc1_identify_next_bdu (buf + ofs, buf_size - ofs, &ebdu); + + switch (result) { + case GST_VC1_PARSER_NO_BDU_END: + /* Assume the EBDU is complete within codec-data bounds */ + ebdu.size = buf_size - ofs - ebdu.offset; + // fall-through + case GST_VC1_PARSER_OK: + status = decode_ebdu (decoder, &ebdu); + ofs += ebdu.offset + ebdu.size; + break; + default: + status = get_status (result); break; } - return status; + } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size); + return status; } static GstVaapiDecoderStatus -decode_buffer(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size) +ensure_decoder (GstVaapiDecoderVC1 * decoder) { - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVC1BDU ebdu; + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; - if (priv->has_codec_data) { - ebdu.type = GST_VC1_FRAME; - ebdu.sc_offset = 0; - ebdu.offset = 0; - } - else { - ebdu.type = buf[3]; - ebdu.sc_offset = 0; - ebdu.offset = 4; - } - ebdu.data = buf; - ebdu.size = buf_size - ebdu.offset; - return decode_ebdu(decoder, &ebdu); -} + if (!priv->is_opened) { + priv->is_opened = gst_vaapi_decoder_vc1_open (decoder); + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; -static GstVaapiDecoderStatus -gst_vaapi_decoder_vc1_decode_codec_data(GstVaapiDecoder *base_decoder, - const guchar *buf, guint buf_size) -{ - GstVaapiDecoderVC1 * const decoder = - GST_VAAPI_DECODER_VC1_CAST(base_decoder); - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; - GstVaapiDecoderStatus status; - GstVC1ParserResult result; - GstVC1BDU ebdu; - GstCaps *caps; - GstStructure *structure; - guint ofs; - gint width, height; - guint32 format; - gint version; - const gchar *s; - - priv->has_codec_data = TRUE; - - width = GST_VAAPI_DECODER_WIDTH(decoder); - height = GST_VAAPI_DECODER_HEIGHT(decoder); - if (!width || !height) { - GST_ERROR("failed to parse size from codec-data"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; - } - - caps = GST_VAAPI_DECODER_CODEC_STATE(decoder)->caps; - structure = gst_caps_get_structure(caps, 0); - s = gst_structure_get_string(structure, "format"); - if (s && strlen(s) == 4) { - format = GST_MAKE_FOURCC(s[0], s[1], s[2], s[3]); - } else { - /* Try to determine format from "wmvversion" property */ - if (gst_structure_get_int(structure, "wmvversion", &version)) - format = (version >= 1 && version <= 3) ? - GST_MAKE_FOURCC('W','M','V',('0'+version)) : 0; - else - format = 0; - } - if (!format) { - GST_ERROR("failed to parse profile from codec-data"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; - } - - /* WMV3 -- expecting sequence header */ - if (format == GST_MAKE_FOURCC('W','M','V','3')) { - seq_hdr->struct_c.coded_width = width; - seq_hdr->struct_c.coded_height = height; - ebdu.type = GST_VC1_SEQUENCE; - ebdu.size = buf_size; - ebdu.sc_offset = 0; - ebdu.offset = 0; - ebdu.data = (guint8 *)buf; - return decode_ebdu(decoder, &ebdu); - } - - /* WVC1 -- expecting bitstream data units */ - if (format != GST_MAKE_FOURCC('W','V','C','1')) - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - seq_hdr->advanced.max_coded_width = width; - seq_hdr->advanced.max_coded_height = height; - - ofs = 0; - do { - result = gst_vc1_identify_next_bdu( - buf + ofs, - buf_size - ofs, - &ebdu - ); - - switch (result) { - case GST_VC1_PARSER_NO_BDU_END: - /* Assume the EBDU is complete within codec-data bounds */ - ebdu.size = buf_size - ofs - ebdu.offset; - // fall-through - case GST_VC1_PARSER_OK: - status = decode_ebdu(decoder, &ebdu); - ofs += ebdu.offset + ebdu.size; - break; - default: - status = get_status(result); - break; - } - } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size); - return status; -} - -static GstVaapiDecoderStatus -ensure_decoder(GstVaapiDecoderVC1 *decoder) -{ - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVaapiDecoderStatus status; - - if (!priv->is_opened) { - priv->is_opened = gst_vaapi_decoder_vc1_open(decoder); - if (!priv->is_opened) - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC; - - status = gst_vaapi_decoder_decode_codec_data( - GST_VAAPI_DECODER_CAST(decoder)); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; + status = + gst_vaapi_decoder_decode_codec_data (GST_VAAPI_DECODER_CAST (decoder)); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static inline gint -scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp) +scan_for_start_code (GstAdapter * adapter, guint ofs, guint size, guint32 * scp) { - return (gint)gst_adapter_masked_scan_uint32_peek(adapter, - 0xffffff00, 0x00000100, ofs, size, scp); + return (gint) gst_adapter_masked_scan_uint32_peek (adapter, + 0xffffff00, 0x00000100, ofs, size, scp); } static GstVaapiDecoderStatus -gst_vaapi_decoder_vc1_parse(GstVaapiDecoder *base_decoder, - GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit) +gst_vaapi_decoder_vc1_parse (GstVaapiDecoder * base_decoder, + GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderVC1 * const decoder = - GST_VAAPI_DECODER_VC1_CAST(base_decoder); - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVaapiDecoderStatus status; - guint8 bdu_type; - guint size, buf_size, flags = 0; - gint ofs; + GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder); + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; + guint8 bdu_type; + guint size, buf_size, flags = 0; + gint ofs; - status = ensure_decoder(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; + status = ensure_decoder (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; - size = gst_adapter_available(adapter); + size = gst_adapter_available (adapter); - if (priv->has_codec_data) { - // Assume demuxer sends out plain frames - if (size < 1) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - buf_size = size; - bdu_type = GST_VC1_FRAME; + if (priv->has_codec_data) { + // Assume demuxer sends out plain frames + if (size < 1) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + buf_size = size; + bdu_type = GST_VC1_FRAME; + } else { + if (size < 4) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + ofs = scan_for_start_code (adapter, 0, size, NULL); + if (ofs < 0) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + gst_adapter_flush (adapter, ofs); + size -= ofs; + + ofs = G_UNLIKELY (size < 8) ? -1 : + scan_for_start_code (adapter, 4, size - 4, NULL); + if (ofs < 0) { + // Assume the whole packet is present if end-of-stream + if (!at_eos) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + ofs = size; } - else { - if (size < 4) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + buf_size = ofs; + gst_adapter_copy (adapter, &bdu_type, 3, 1); + } - ofs = scan_for_start_code(adapter, 0, size, NULL); - if (ofs < 0) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - gst_adapter_flush(adapter, ofs); - size -= ofs; + unit->size = buf_size; - ofs = G_UNLIKELY(size < 8) ? -1 : - scan_for_start_code(adapter, 4, size - 4, NULL); - if (ofs < 0) { - // Assume the whole packet is present if end-of-stream - if (!at_eos) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - ofs = size; - } - buf_size = ofs; - gst_adapter_copy(adapter, &bdu_type, 3, 1); - } - - unit->size = buf_size; - - /* Check for new picture layer */ - switch (bdu_type) { + /* Check for new picture layer */ + switch (bdu_type) { case GST_VC1_END_OF_SEQ: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; - flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; - break; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END; + break; case GST_VC1_SEQUENCE: case GST_VC1_ENTRYPOINT: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - break; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; case GST_VC1_FRAME: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; - break; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + break; case GST_VC1_SLICE: - flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; - break; - } - GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + break; + } + GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base_decoder, - GstVaapiDecoderUnit *unit) +gst_vaapi_decoder_vc1_decode (GstVaapiDecoder * base_decoder, + GstVaapiDecoderUnit * unit) { - GstVaapiDecoderVC1 * const decoder = - GST_VAAPI_DECODER_VC1_CAST(base_decoder); - GstVaapiDecoderStatus status; - GstBuffer * const buffer = - GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer; - GstMapInfo map_info; + GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder); + GstVaapiDecoderStatus status; + 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; + 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; - } + 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; + 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_vc1_start_frame(GstVaapiDecoder *base_decoder, - GstVaapiDecoderUnit *unit) +gst_vaapi_decoder_vc1_start_frame (GstVaapiDecoder * base_decoder, + GstVaapiDecoderUnit * unit) { - GstVaapiDecoderVC1 * const decoder = - GST_VAAPI_DECODER_VC1_CAST(base_decoder); - GstVaapiDecoderVC1Private * const priv = &decoder->priv; - GstVaapiDecoderStatus status; - GstVaapiPicture *picture; + GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder); + GstVaapiDecoderVC1Private *const priv = &decoder->priv; + GstVaapiDecoderStatus status; + GstVaapiPicture *picture; - status = ensure_context(decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_ERROR("failed to reset context"); - return status; - } + status = ensure_context (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_ERROR ("failed to reset context"); + return status; + } - picture = GST_VAAPI_PICTURE_NEW(VC1, 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); + picture = GST_VAAPI_PICTURE_NEW (VC1, 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); - /* Update cropping rectangle */ - do { - GstVC1AdvancedSeqHdr *adv_hdr; - GstVaapiRectangle crop_rect; + /* Update cropping rectangle */ + do { + GstVC1AdvancedSeqHdr *adv_hdr; + GstVaapiRectangle crop_rect; - if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) - break; + if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) + break; - adv_hdr = &priv->seq_hdr.advanced; - if (!adv_hdr->display_ext) - break; + adv_hdr = &priv->seq_hdr.advanced; + if (!adv_hdr->display_ext) + break; - crop_rect.x = 0; - crop_rect.y = 0; - crop_rect.width = adv_hdr->disp_horiz_size; - crop_rect.height = adv_hdr->disp_vert_size; - if (crop_rect.width <= priv->width && crop_rect.height <= priv->height) - gst_vaapi_picture_set_crop_rect(picture, &crop_rect); - } while (0); + crop_rect.x = 0; + crop_rect.y = 0; + crop_rect.width = adv_hdr->disp_horiz_size; + crop_rect.height = adv_hdr->disp_vert_size; + if (crop_rect.width <= priv->width && crop_rect.height <= priv->height) + gst_vaapi_picture_set_crop_rect (picture, &crop_rect); + } while (0); - if (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, &priv->seq_hdr)) { - GST_ERROR("failed to allocate bitplanes"); - return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; - } - return GST_VAAPI_DECODER_STATUS_SUCCESS; + if (!gst_vc1_bitplanes_ensure_size (priv->bitplanes, &priv->seq_hdr)) { + GST_ERROR ("failed to allocate bitplanes"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static GstVaapiDecoderStatus -gst_vaapi_decoder_vc1_end_frame(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_vc1_end_frame (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderVC1 * const decoder = - GST_VAAPI_DECODER_VC1_CAST(base_decoder); + GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder); - return decode_current_picture(decoder); + return decode_current_picture (decoder); } static GstVaapiDecoderStatus -gst_vaapi_decoder_vc1_flush(GstVaapiDecoder *base_decoder) +gst_vaapi_decoder_vc1_flush (GstVaapiDecoder * base_decoder) { - GstVaapiDecoderVC1 * const decoder = - GST_VAAPI_DECODER_VC1_CAST(base_decoder); - GstVaapiDecoderVC1Private * const priv = &decoder->priv; + GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder); + GstVaapiDecoderVC1Private *const priv = &decoder->priv; - gst_vaapi_dpb_flush(priv->dpb); - return GST_VAAPI_DECODER_STATUS_SUCCESS; + gst_vaapi_dpb_flush (priv->dpb); + return GST_VAAPI_DECODER_STATUS_SUCCESS; } static void -gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass) +gst_vaapi_decoder_vc1_class_init (GstVaapiDecoderVC1Class * klass) { - GstVaapiMiniObjectClass * const object_class = - GST_VAAPI_MINI_OBJECT_CLASS(klass); - GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass); + GstVaapiMiniObjectClass *const object_class = + GST_VAAPI_MINI_OBJECT_CLASS (klass); + GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof(GstVaapiDecoderVC1); - object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize; + object_class->size = sizeof (GstVaapiDecoderVC1); + object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; - decoder_class->create = gst_vaapi_decoder_vc1_create; - decoder_class->destroy = gst_vaapi_decoder_vc1_destroy; - decoder_class->parse = gst_vaapi_decoder_vc1_parse; - decoder_class->decode = gst_vaapi_decoder_vc1_decode; - decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame; - decoder_class->end_frame = gst_vaapi_decoder_vc1_end_frame; - decoder_class->flush = gst_vaapi_decoder_vc1_flush; + decoder_class->create = gst_vaapi_decoder_vc1_create; + decoder_class->destroy = gst_vaapi_decoder_vc1_destroy; + decoder_class->parse = gst_vaapi_decoder_vc1_parse; + decoder_class->decode = gst_vaapi_decoder_vc1_decode; + decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame; + decoder_class->end_frame = gst_vaapi_decoder_vc1_end_frame; + decoder_class->flush = gst_vaapi_decoder_vc1_flush; - decoder_class->decode_codec_data = - gst_vaapi_decoder_vc1_decode_codec_data; + decoder_class->decode_codec_data = gst_vaapi_decoder_vc1_decode_codec_data; } static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_vc1_class(void) +gst_vaapi_decoder_vc1_class (void) { - static GstVaapiDecoderVC1Class g_class; - static gsize g_class_init = FALSE; + static GstVaapiDecoderVC1Class g_class; + static gsize g_class_init = FALSE; - if (g_once_init_enter(&g_class_init)) { - gst_vaapi_decoder_vc1_class_init(&g_class); - g_once_init_leave(&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS(&g_class); + if (g_once_init_enter (&g_class_init)) { + gst_vaapi_decoder_vc1_class_init (&g_class); + g_once_init_leave (&g_class_init, TRUE); + } + return GST_VAAPI_DECODER_CLASS (&g_class); } /** @@ -1437,7 +1439,7 @@ gst_vaapi_decoder_vc1_class(void) * Return value: the newly allocated #GstVaapiDecoder object */ GstVaapiDecoder * -gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps) +gst_vaapi_decoder_vc1_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new(gst_vaapi_decoder_vc1_class(), display, caps); + return gst_vaapi_decoder_new (gst_vaapi_decoder_vc1_class (), display, caps); } diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 8a295a5f8e..98bedcb3b6 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -45,192 +45,184 @@ } while (0) static gboolean -_gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image); +_gst_vaapi_image_map (GstVaapiImage * image, GstVaapiImageRaw * raw_image); + +static gboolean _gst_vaapi_image_unmap (GstVaapiImage * image); static gboolean -_gst_vaapi_image_unmap(GstVaapiImage *image); - -static gboolean -_gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image); +_gst_vaapi_image_set_image (GstVaapiImage * image, const VAImage * va_image); /* * VAImage wrapper */ static gboolean -vaapi_image_is_linear(const VAImage *va_image) +vaapi_image_is_linear (const VAImage * va_image) { - guint i, width, height, width2, height2, data_size; + guint i, width, height, width2, height2, data_size; - for (i = 1; i < va_image->num_planes; i++) - if (va_image->offsets[i] < va_image->offsets[i - 1]) - return FALSE; + for (i = 1; i < va_image->num_planes; i++) + if (va_image->offsets[i] < va_image->offsets[i - 1]) + return FALSE; - width = va_image->width; - height = va_image->height; - width2 = (width + 1) / 2; - height2 = (height + 1) / 2; + width = va_image->width; + height = va_image->height; + width2 = (width + 1) / 2; + height2 = (height + 1) / 2; - switch (va_image->format.fourcc) { - case VA_FOURCC('N','V','1','2'): - case VA_FOURCC('Y','V','1','2'): - case VA_FOURCC('I','4','2','0'): - data_size = width * height + 2 * width2 * height2; - break; - case VA_FOURCC('Y','U','Y','2'): - case VA_FOURCC('U','Y','V','Y'): - data_size = 2 * width * height; - break; - case VA_FOURCC('Y','8','0','0'): - data_size = width * height; - break; - case VA_FOURCC('A','Y','U','V'): - case VA_FOURCC('A','R','G','B'): - case VA_FOURCC('R','G','B','A'): - case VA_FOURCC('A','B','G','R'): - case VA_FOURCC('B','G','R','A'): - case VA_FOURCC('X','R','G','B'): - case VA_FOURCC('R','G','B','X'): - case VA_FOURCC('X','B','G','R'): - case VA_FOURCC('B','G','R','X'): - data_size = 4 * width * height; - break; + switch (va_image->format.fourcc) { + case VA_FOURCC ('N', 'V', '1', '2'): + case VA_FOURCC ('Y', 'V', '1', '2'): + case VA_FOURCC ('I', '4', '2', '0'): + data_size = width * height + 2 * width2 * height2; + break; + case VA_FOURCC ('Y', 'U', 'Y', '2'): + case VA_FOURCC ('U', 'Y', 'V', 'Y'): + data_size = 2 * width * height; + break; + case VA_FOURCC ('Y', '8', '0', '0'): + data_size = width * height; + break; + case VA_FOURCC ('A', 'Y', 'U', 'V'): + case VA_FOURCC ('A', 'R', 'G', 'B'): + case VA_FOURCC ('R', 'G', 'B', 'A'): + case VA_FOURCC ('A', 'B', 'G', 'R'): + case VA_FOURCC ('B', 'G', 'R', 'A'): + case VA_FOURCC ('X', 'R', 'G', 'B'): + case VA_FOURCC ('R', 'G', 'B', 'X'): + case VA_FOURCC ('X', 'B', 'G', 'R'): + case VA_FOURCC ('B', 'G', 'R', 'X'): + data_size = 4 * width * height; + break; default: - g_error("FIXME: incomplete formats %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS(va_image->format.fourcc)); - break; - } - return va_image->data_size == data_size; + g_error ("FIXME: incomplete formats %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (va_image->format.fourcc)); + break; + } + return va_image->data_size == data_size; } static void -gst_vaapi_image_destroy(GstVaapiImage *image) +gst_vaapi_image_destroy (GstVaapiImage * image) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image); - VAImageID image_id; - VAStatus status; + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (image); + VAImageID image_id; + VAStatus status; - _gst_vaapi_image_unmap(image); + _gst_vaapi_image_unmap (image); - image_id = GST_VAAPI_OBJECT_ID(image); - GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id)); + image_id = GST_VAAPI_OBJECT_ID (image); + GST_DEBUG ("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (image_id)); - if (image_id != VA_INVALID_ID) { - GST_VAAPI_DISPLAY_LOCK(display); - status = vaDestroyImage(GST_VAAPI_DISPLAY_VADISPLAY(display), image_id); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaDestroyImage()")) - g_warning("failed to destroy image %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(image_id)); - GST_VAAPI_OBJECT_ID(image) = VA_INVALID_ID; - } + if (image_id != VA_INVALID_ID) { + GST_VAAPI_DISPLAY_LOCK (display); + status = vaDestroyImage (GST_VAAPI_DISPLAY_VADISPLAY (display), image_id); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaDestroyImage()")) + g_warning ("failed to destroy image %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (image_id)); + GST_VAAPI_OBJECT_ID (image) = VA_INVALID_ID; + } } static gboolean -_gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format) +_gst_vaapi_image_create (GstVaapiImage * image, GstVideoFormat format) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image); - const VAImageFormat *va_format; - VAStatus status; + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (image); + const VAImageFormat *va_format; + VAStatus status; - if (!gst_vaapi_display_has_image_format(display, format)) - return FALSE; + if (!gst_vaapi_display_has_image_format (display, format)) + return FALSE; - va_format = gst_vaapi_video_format_to_va_format(format); - if (!va_format) - return FALSE; + va_format = gst_vaapi_video_format_to_va_format (format); + if (!va_format) + return FALSE; - GST_VAAPI_DISPLAY_LOCK(display); - status = vaCreateImage( - GST_VAAPI_DISPLAY_VADISPLAY(display), - (VAImageFormat *)va_format, - image->width, - image->height, - &image->internal_image - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (status != VA_STATUS_SUCCESS || - image->internal_image.format.fourcc != va_format->fourcc) - return FALSE; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaCreateImage (GST_VAAPI_DISPLAY_VADISPLAY (display), + (VAImageFormat *) va_format, + image->width, image->height, &image->internal_image); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (status != VA_STATUS_SUCCESS || + image->internal_image.format.fourcc != va_format->fourcc) + return FALSE; - image->internal_format = format; - return TRUE; + image->internal_format = format; + return TRUE; } static gboolean -gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format, +gst_vaapi_image_create (GstVaapiImage * image, GstVideoFormat format, guint width, guint height) { - const VAImageFormat *va_format; - VAImageID image_id; + const VAImageFormat *va_format; + VAImageID image_id; - image->format = format; - image->width = width; - image->height = height; + image->format = format; + image->width = width; + image->height = height; - if (!_gst_vaapi_image_create(image, format)) { - switch (format) { - case GST_VIDEO_FORMAT_I420: - format = GST_VIDEO_FORMAT_YV12; - break; - case GST_VIDEO_FORMAT_YV12: - format = GST_VIDEO_FORMAT_I420; - break; - default: - format = 0; - break; - } - if (!format || !_gst_vaapi_image_create(image, format)) - return FALSE; + if (!_gst_vaapi_image_create (image, format)) { + switch (format) { + case GST_VIDEO_FORMAT_I420: + format = GST_VIDEO_FORMAT_YV12; + break; + case GST_VIDEO_FORMAT_YV12: + format = GST_VIDEO_FORMAT_I420; + break; + default: + format = 0; + break; } - image->image = image->internal_image; - image_id = image->image.image_id; + if (!format || !_gst_vaapi_image_create (image, format)) + return FALSE; + } + image->image = image->internal_image; + image_id = image->image.image_id; - if (image->format != image->internal_format) { - switch (image->format) { - case GST_VIDEO_FORMAT_YV12: - case GST_VIDEO_FORMAT_I420: - va_format = gst_vaapi_video_format_to_va_format(image->format); - if (!va_format) - return FALSE; - image->image.format = *va_format; - SWAP_UINT(image->image.offsets[1], image->image.offsets[2]); - SWAP_UINT(image->image.pitches[1], image->image.pitches[2]); - break; - default: - break; - } + if (image->format != image->internal_format) { + switch (image->format) { + case GST_VIDEO_FORMAT_YV12: + case GST_VIDEO_FORMAT_I420: + va_format = gst_vaapi_video_format_to_va_format (image->format); + if (!va_format) + return FALSE; + image->image.format = *va_format; + SWAP_UINT (image->image.offsets[1], image->image.offsets[2]); + SWAP_UINT (image->image.pitches[1], image->image.pitches[2]); + break; + default: + break; } - image->is_linear = vaapi_image_is_linear(&image->image); + } + image->is_linear = vaapi_image_is_linear (&image->image); - GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id)); - GST_VAAPI_OBJECT_ID(image) = image_id; - return TRUE; + GST_DEBUG ("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (image_id)); + GST_VAAPI_OBJECT_ID (image) = image_id; + return TRUE; } static void -gst_vaapi_image_init(GstVaapiImage *image) +gst_vaapi_image_init (GstVaapiImage * image) { - image->internal_image.image_id = VA_INVALID_ID; - image->internal_image.buf = VA_INVALID_ID; - image->image.image_id = VA_INVALID_ID; - image->image.buf = VA_INVALID_ID; + image->internal_image.image_id = VA_INVALID_ID; + image->internal_image.buf = VA_INVALID_ID; + image->image.image_id = VA_INVALID_ID; + image->image.buf = VA_INVALID_ID; } static void -gst_vaapi_image_class_init(GstVaapiImageClass *klass) +gst_vaapi_image_class_init (GstVaapiImageClass * klass) { - GstVaapiObjectClass * const object_class = - GST_VAAPI_OBJECT_CLASS(klass); + GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); - object_class->init = (GstVaapiObjectInitFunc)gst_vaapi_image_init; + object_class->init = (GstVaapiObjectInitFunc) gst_vaapi_image_init; } #define gst_vaapi_image_finalize gst_vaapi_image_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( - GstVaapiImage, - gst_vaapi_image, - gst_vaapi_image_class_init(&g_class)) +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiImage, + gst_vaapi_image, gst_vaapi_image_class_init (&g_class)) /** * gst_vaapi_image_new: @@ -244,33 +236,28 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( * * Return value: the newly allocated #GstVaapiImage object */ -GstVaapiImage * -gst_vaapi_image_new( - GstVaapiDisplay *display, - GstVideoFormat format, - guint width, - guint height -) + GstVaapiImage *gst_vaapi_image_new (GstVaapiDisplay * display, + GstVideoFormat format, guint width, guint height) { - GstVaapiImage *image; + GstVaapiImage *image; - g_return_val_if_fail(width > 0, NULL); - g_return_val_if_fail(height > 0, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); - GST_DEBUG("format %s, size %ux%u", gst_vaapi_video_format_to_string(format), - width, height); + GST_DEBUG ("format %s, size %ux%u", gst_vaapi_video_format_to_string (format), + width, height); - image = gst_vaapi_object_new(gst_vaapi_image_class(), display); - if (!image) - return NULL; + image = gst_vaapi_object_new (gst_vaapi_image_class (), display); + if (!image) + return NULL; - if (!gst_vaapi_image_create(image, format, width, height)) - goto error; - return image; + if (!gst_vaapi_image_create (image, format, width, height)) + goto error; + return image; error: - gst_vaapi_object_unref(image); - return NULL; + gst_vaapi_object_unref (image); + return NULL; } /** @@ -286,30 +273,30 @@ error: * Return value: the newly allocated #GstVaapiImage object */ GstVaapiImage * -gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image) +gst_vaapi_image_new_with_image (GstVaapiDisplay * display, VAImage * va_image) { - GstVaapiImage *image; + GstVaapiImage *image; - g_return_val_if_fail(va_image, NULL); - g_return_val_if_fail(va_image->image_id != VA_INVALID_ID, NULL); - g_return_val_if_fail(va_image->buf != VA_INVALID_ID, NULL); + g_return_val_if_fail (va_image, NULL); + g_return_val_if_fail (va_image->image_id != VA_INVALID_ID, NULL); + g_return_val_if_fail (va_image->buf != VA_INVALID_ID, NULL); - GST_DEBUG("VA image 0x%08x, format %" GST_FOURCC_FORMAT ", size %ux%u", - va_image->image_id, - GST_FOURCC_ARGS(va_image->format.fourcc), - va_image->width, va_image->height); + GST_DEBUG ("VA image 0x%08x, format %" GST_FOURCC_FORMAT ", size %ux%u", + va_image->image_id, + GST_FOURCC_ARGS (va_image->format.fourcc), + va_image->width, va_image->height); - image = gst_vaapi_object_new(gst_vaapi_image_class(), display); - if (!image) - return NULL; + image = gst_vaapi_object_new (gst_vaapi_image_class (), display); + if (!image) + return NULL; - if (!_gst_vaapi_image_set_image(image, va_image)) - goto error; - return image; + if (!_gst_vaapi_image_set_image (image, va_image)) + goto error; + return image; error: - gst_vaapi_object_unref(image); - return NULL; + gst_vaapi_object_unref (image); + return NULL; } /** @@ -321,11 +308,11 @@ error: * Return value: the underlying VA image id */ GstVaapiID -gst_vaapi_image_get_id(GstVaapiImage *image) +gst_vaapi_image_get_id (GstVaapiImage * image) { - g_return_val_if_fail(image != NULL, VA_INVALID_ID); + g_return_val_if_fail (image != NULL, VA_INVALID_ID); - return GST_VAAPI_OBJECT_ID(image); + return GST_VAAPI_OBJECT_ID (image); } /** @@ -338,14 +325,14 @@ gst_vaapi_image_get_id(GstVaapiImage *image) * Return value: %TRUE on success */ gboolean -gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image) +gst_vaapi_image_get_image (GstVaapiImage * image, VAImage * va_image) { - g_return_val_if_fail(image != NULL, FALSE); + g_return_val_if_fail (image != NULL, FALSE); - if (va_image) - *va_image = image->image; + if (va_image) + *va_image = image->image; - return TRUE; + return TRUE; } /* @@ -363,55 +350,55 @@ gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image) * Return value: %TRUE on success */ gboolean -_gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) +_gst_vaapi_image_set_image (GstVaapiImage * image, const VAImage * va_image) { - GstVideoFormat format; - VAImage alt_va_image; - const VAImageFormat *alt_va_format; + GstVideoFormat format; + VAImage alt_va_image; + const VAImageFormat *alt_va_format; - format = gst_vaapi_video_format_from_va_format(&va_image->format); - if (format == GST_VIDEO_FORMAT_UNKNOWN) - return FALSE; + format = gst_vaapi_video_format_from_va_format (&va_image->format); + if (format == GST_VIDEO_FORMAT_UNKNOWN) + return FALSE; - image->internal_image = *va_image; - image->internal_format = format; - image->is_linear = vaapi_image_is_linear(va_image); - image->image = *va_image; - image->format = format; - image->width = va_image->width; - image->height = va_image->height; + image->internal_image = *va_image; + image->internal_format = format; + image->is_linear = vaapi_image_is_linear (va_image); + image->image = *va_image; + image->format = format; + image->width = va_image->width; + image->height = va_image->height; - GST_VAAPI_OBJECT_ID(image) = va_image->image_id; + GST_VAAPI_OBJECT_ID (image) = va_image->image_id; - /* Try to linearize image */ - if (!image->is_linear) { - switch (format) { - case GST_VIDEO_FORMAT_I420: - format = GST_VIDEO_FORMAT_YV12; - break; - case GST_VIDEO_FORMAT_YV12: - format = GST_VIDEO_FORMAT_I420; - break; - default: - format = 0; - break; - } - if (format && - (alt_va_format = gst_vaapi_video_format_to_va_format(format))) { - alt_va_image = *va_image; - alt_va_image.format = *alt_va_format; - SWAP_UINT(alt_va_image.offsets[1], alt_va_image.offsets[2]); - SWAP_UINT(alt_va_image.pitches[1], alt_va_image.pitches[2]); - if (vaapi_image_is_linear(&alt_va_image)) { - image->image = alt_va_image; - image->format = format; - image->is_linear = TRUE; - GST_DEBUG("linearized image to %s format", - gst_vaapi_video_format_to_string(format)); - } - } + /* Try to linearize image */ + if (!image->is_linear) { + switch (format) { + case GST_VIDEO_FORMAT_I420: + format = GST_VIDEO_FORMAT_YV12; + break; + case GST_VIDEO_FORMAT_YV12: + format = GST_VIDEO_FORMAT_I420; + break; + default: + format = 0; + break; } - return TRUE; + if (format && + (alt_va_format = gst_vaapi_video_format_to_va_format (format))) { + alt_va_image = *va_image; + alt_va_image.format = *alt_va_format; + SWAP_UINT (alt_va_image.offsets[1], alt_va_image.offsets[2]); + SWAP_UINT (alt_va_image.pitches[1], alt_va_image.pitches[2]); + if (vaapi_image_is_linear (&alt_va_image)) { + image->image = alt_va_image; + image->format = format; + image->is_linear = TRUE; + GST_DEBUG ("linearized image to %s format", + gst_vaapi_video_format_to_string (format)); + } + } + } + return TRUE; } /** @@ -423,11 +410,11 @@ _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image) * Return value: the #GstVideoFormat */ GstVideoFormat -gst_vaapi_image_get_format(GstVaapiImage *image) +gst_vaapi_image_get_format (GstVaapiImage * image) { - g_return_val_if_fail(image != NULL, 0); + g_return_val_if_fail (image != NULL, 0); - return image->format; + return image->format; } /** @@ -439,11 +426,11 @@ gst_vaapi_image_get_format(GstVaapiImage *image) * Return value: the image width, in pixels */ guint -gst_vaapi_image_get_width(GstVaapiImage *image) +gst_vaapi_image_get_width (GstVaapiImage * image) { - g_return_val_if_fail(image != NULL, 0); + g_return_val_if_fail (image != NULL, 0); - return image->width; + return image->width; } /** @@ -455,11 +442,11 @@ gst_vaapi_image_get_width(GstVaapiImage *image) * Return value: the image height, in pixels. */ guint -gst_vaapi_image_get_height(GstVaapiImage *image) +gst_vaapi_image_get_height (GstVaapiImage * image) { - g_return_val_if_fail(image != NULL, 0); + g_return_val_if_fail (image != NULL, 0); - return image->height; + return image->height; } /** @@ -471,15 +458,16 @@ gst_vaapi_image_get_height(GstVaapiImage *image) * Retrieves the dimensions of a #GstVaapiImage. */ void -gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) +gst_vaapi_image_get_size (GstVaapiImage * image, guint * pwidth, + guint * pheight) { - g_return_if_fail(image != NULL); + g_return_if_fail (image != NULL); - if (pwidth) - *pwidth = image->width; + if (pwidth) + *pwidth = image->width; - if (pheight) - *pheight = image->height; + if (pheight) + *pheight = image->height; } /** @@ -493,11 +481,11 @@ gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight) * Return value: %TRUE if image data planes are allocated from a single buffer */ gboolean -gst_vaapi_image_is_linear(GstVaapiImage *image) +gst_vaapi_image_is_linear (GstVaapiImage * image) { - g_return_val_if_fail(image != NULL, FALSE); + g_return_val_if_fail (image != NULL, FALSE); - return image->is_linear; + return image->is_linear; } /** @@ -509,17 +497,17 @@ gst_vaapi_image_is_linear(GstVaapiImage *image) * Return value: %TRUE if the @image is mapped */ static inline gboolean -_gst_vaapi_image_is_mapped(GstVaapiImage *image) +_gst_vaapi_image_is_mapped (GstVaapiImage * image) { - return image->image_data != NULL; + return image->image_data != NULL; } gboolean -gst_vaapi_image_is_mapped(GstVaapiImage *image) +gst_vaapi_image_is_mapped (GstVaapiImage * image) { - g_return_val_if_fail(image != NULL, FALSE); + g_return_val_if_fail (image != NULL, FALSE); - return _gst_vaapi_image_is_mapped(image); + return _gst_vaapi_image_is_mapped (image); } /** @@ -532,51 +520,48 @@ gst_vaapi_image_is_mapped(GstVaapiImage *image) * Return value: %TRUE on success */ gboolean -gst_vaapi_image_map(GstVaapiImage *image) +gst_vaapi_image_map (GstVaapiImage * image) { - g_return_val_if_fail(image != NULL, FALSE); + g_return_val_if_fail (image != NULL, FALSE); - return _gst_vaapi_image_map(image, NULL); + return _gst_vaapi_image_map (image, NULL); } gboolean -_gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image) +_gst_vaapi_image_map (GstVaapiImage * image, GstVaapiImageRaw * raw_image) { - GstVaapiDisplay *display; - VAStatus status; - guint i; + GstVaapiDisplay *display; + VAStatus status; + guint i; - if (_gst_vaapi_image_is_mapped(image)) - goto map_success; + if (_gst_vaapi_image_is_mapped (image)) + goto map_success; - display = GST_VAAPI_OBJECT_DISPLAY(image); - if (!display) - return FALSE; + display = GST_VAAPI_OBJECT_DISPLAY (image); + if (!display) + return FALSE; - GST_VAAPI_DISPLAY_LOCK(display); - status = vaMapBuffer( - GST_VAAPI_DISPLAY_VADISPLAY(display), - image->image.buf, - (void **)&image->image_data - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaMapBuffer()")) - return FALSE; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaMapBuffer (GST_VAAPI_DISPLAY_VADISPLAY (display), + image->image.buf, (void **) &image->image_data); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaMapBuffer()")) + return FALSE; map_success: - if (raw_image) { - const VAImage * const va_image = &image->image; - raw_image->format = image->format; - raw_image->width = va_image->width; - raw_image->height = va_image->height; - raw_image->num_planes = va_image->num_planes; - for (i = 0; i < raw_image->num_planes; i++) { - raw_image->pixels[i] = (guchar *)image->image_data + - va_image->offsets[i]; - raw_image->stride[i] = va_image->pitches[i]; - } + if (raw_image) { + const VAImage *const va_image = &image->image; + raw_image->format = image->format; + raw_image->width = va_image->width; + raw_image->height = va_image->height; + raw_image->num_planes = va_image->num_planes; + for (i = 0; i < raw_image->num_planes; i++) { + raw_image->pixels[i] = (guchar *) image->image_data + + va_image->offsets[i]; + raw_image->stride[i] = va_image->pitches[i]; } - return TRUE; + } + return TRUE; } /** @@ -589,37 +574,35 @@ map_success: * Return value: %TRUE on success */ gboolean -gst_vaapi_image_unmap(GstVaapiImage *image) +gst_vaapi_image_unmap (GstVaapiImage * image) { - g_return_val_if_fail(image != NULL, FALSE); + g_return_val_if_fail (image != NULL, FALSE); - return _gst_vaapi_image_unmap(image); + return _gst_vaapi_image_unmap (image); } gboolean -_gst_vaapi_image_unmap(GstVaapiImage *image) +_gst_vaapi_image_unmap (GstVaapiImage * image) { - GstVaapiDisplay *display; - VAStatus status; + GstVaapiDisplay *display; + VAStatus status; - if (!_gst_vaapi_image_is_mapped(image)) - return TRUE; - - display = GST_VAAPI_OBJECT_DISPLAY(image); - if (!display) - return FALSE; - - GST_VAAPI_DISPLAY_LOCK(display); - status = vaUnmapBuffer( - GST_VAAPI_DISPLAY_VADISPLAY(display), - image->image.buf - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaUnmapBuffer()")) - return FALSE; - - image->image_data = NULL; + if (!_gst_vaapi_image_is_mapped (image)) return TRUE; + + display = GST_VAAPI_OBJECT_DISPLAY (image); + if (!display) + return FALSE; + + GST_VAAPI_DISPLAY_LOCK (display); + status = vaUnmapBuffer (GST_VAAPI_DISPLAY_VADISPLAY (display), + image->image.buf); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaUnmapBuffer()")) + return FALSE; + + image->image_data = NULL; + return TRUE; } /** @@ -632,12 +615,12 @@ _gst_vaapi_image_unmap(GstVaapiImage *image) * Return value: the number of planes available in the @image */ guint -gst_vaapi_image_get_plane_count(GstVaapiImage *image) +gst_vaapi_image_get_plane_count (GstVaapiImage * image) { - g_return_val_if_fail(image != NULL, 0); - g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0); + g_return_val_if_fail (image != NULL, 0); + g_return_val_if_fail (_gst_vaapi_image_is_mapped (image), 0); - return image->image.num_planes; + return image->image.num_planes; } /** @@ -651,13 +634,13 @@ gst_vaapi_image_get_plane_count(GstVaapiImage *image) * Return value: the pixels data of the specified @plane */ guchar * -gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane) +gst_vaapi_image_get_plane (GstVaapiImage * image, guint plane) { - g_return_val_if_fail(image != NULL, NULL); - g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL); - g_return_val_if_fail(plane < image->image.num_planes, NULL); + g_return_val_if_fail (image != NULL, NULL); + g_return_val_if_fail (_gst_vaapi_image_is_mapped (image), NULL); + g_return_val_if_fail (plane < image->image.num_planes, NULL); - return image->image_data + image->image.offsets[plane]; + return image->image_data + image->image.offsets[plane]; } /** @@ -671,13 +654,13 @@ gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane) * Return value: the line size (stride) of the specified plane */ guint -gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane) +gst_vaapi_image_get_pitch (GstVaapiImage * image, guint plane) { - g_return_val_if_fail(image != NULL, 0); - g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0); - g_return_val_if_fail(plane < image->image.num_planes, 0); + g_return_val_if_fail (image != NULL, 0); + g_return_val_if_fail (_gst_vaapi_image_is_mapped (image), 0); + g_return_val_if_fail (plane < image->image.num_planes, 0); - return image->image.pitches[plane]; + return image->image.pitches[plane]; } /** @@ -691,198 +674,177 @@ gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane) * Return value: the whole image data size of the @image */ guint -gst_vaapi_image_get_data_size(GstVaapiImage *image) +gst_vaapi_image_get_data_size (GstVaapiImage * image) { - g_return_val_if_fail(image != NULL, 0); + g_return_val_if_fail (image != NULL, 0); - return image->image.data_size; + return image->image.data_size; } #include static gboolean -init_image_from_video_meta(GstVaapiImageRaw *raw_image, GstVideoMeta *vmeta) +init_image_from_video_meta (GstVaapiImageRaw * raw_image, GstVideoMeta * vmeta) { - GST_FIXME("map from GstVideoMeta + add fini_image_from_buffer()"); - return FALSE; + GST_FIXME ("map from GstVideoMeta + add fini_image_from_buffer()"); + return FALSE; } static gboolean -init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer) +init_image_from_buffer (GstVaapiImageRaw * raw_image, GstBuffer * buffer) { - GstVideoMeta * const vmeta = gst_buffer_get_video_meta(buffer); + GstVideoMeta *const vmeta = gst_buffer_get_video_meta (buffer); - return vmeta ? init_image_from_video_meta(raw_image, vmeta) : FALSE; + return vmeta ? init_image_from_video_meta (raw_image, vmeta) : FALSE; } /* Copy N lines of an image */ static inline void -memcpy_pic( - guchar *dst, - guint dst_stride, - const guchar *src, - guint src_stride, - guint len, - guint height -) +memcpy_pic (guchar * dst, + guint dst_stride, + const guchar * src, guint src_stride, guint len, guint height) { - guint i; + guint i; - for (i = 0; i < height; i++) { - memcpy(dst, src, len); - dst += dst_stride; - src += src_stride; - } + for (i = 0; i < height; i++) { + memcpy (dst, src, len); + dst += dst_stride; + src += src_stride; + } } /* Copy NV12 images */ static void -copy_image_NV12( - GstVaapiImageRaw *dst_image, - GstVaapiImageRaw *src_image, - const GstVaapiRectangle *rect -) +copy_image_NV12 (GstVaapiImageRaw * dst_image, + GstVaapiImageRaw * src_image, const GstVaapiRectangle * rect) { - guchar *dst, *src; - guint dst_stride, src_stride; + guchar *dst, *src; + guint dst_stride, src_stride; - /* Y plane */ - dst_stride = dst_image->stride[0]; - dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x; - src_stride = src_image->stride[0]; - src = src_image->pixels[0] + rect->y * src_stride + rect->x; - memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height); + /* Y plane */ + dst_stride = dst_image->stride[0]; + dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x; + src_stride = src_image->stride[0]; + src = src_image->pixels[0] + rect->y * src_stride + rect->x; + memcpy_pic (dst, dst_stride, src, src_stride, rect->width, rect->height); - /* UV plane */ - dst_stride = dst_image->stride[1]; - dst = dst_image->pixels[1] + (rect->y / 2) * dst_stride + (rect->x & -2); - src_stride = src_image->stride[1]; - src = src_image->pixels[1] + (rect->y / 2) * src_stride + (rect->x & -2); - memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height / 2); + /* UV plane */ + dst_stride = dst_image->stride[1]; + dst = dst_image->pixels[1] + (rect->y / 2) * dst_stride + (rect->x & -2); + src_stride = src_image->stride[1]; + src = src_image->pixels[1] + (rect->y / 2) * src_stride + (rect->x & -2); + memcpy_pic (dst, dst_stride, src, src_stride, rect->width, rect->height / 2); } /* Copy YV12 images */ static void -copy_image_YV12( - GstVaapiImageRaw *dst_image, - GstVaapiImageRaw *src_image, - const GstVaapiRectangle *rect -) +copy_image_YV12 (GstVaapiImageRaw * dst_image, + GstVaapiImageRaw * src_image, const GstVaapiRectangle * rect) { - guchar *dst, *src; - guint dst_stride, src_stride; - guint i, x, y, w, h; + guchar *dst, *src; + guint dst_stride, src_stride; + guint i, x, y, w, h; - /* Y plane */ - dst_stride = dst_image->stride[0]; - dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x; - src_stride = src_image->stride[0]; - src = src_image->pixels[0] + rect->y * src_stride + rect->x; - memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height); + /* Y plane */ + dst_stride = dst_image->stride[0]; + dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x; + src_stride = src_image->stride[0]; + src = src_image->pixels[0] + rect->y * src_stride + rect->x; + memcpy_pic (dst, dst_stride, src, src_stride, rect->width, rect->height); - /* U/V planes */ - x = rect->x / 2; - y = rect->y / 2; - w = rect->width / 2; - h = rect->height / 2; - for (i = 1; i < dst_image->num_planes; i++) { - dst_stride = dst_image->stride[i]; - dst = dst_image->pixels[i] + y * dst_stride + x; - src_stride = src_image->stride[i]; - src = src_image->pixels[i] + y * src_stride + x; - memcpy_pic(dst, dst_stride, src, src_stride, w, h); - } + /* U/V planes */ + x = rect->x / 2; + y = rect->y / 2; + w = rect->width / 2; + h = rect->height / 2; + for (i = 1; i < dst_image->num_planes; i++) { + dst_stride = dst_image->stride[i]; + dst = dst_image->pixels[i] + y * dst_stride + x; + src_stride = src_image->stride[i]; + src = src_image->pixels[i] + y * src_stride + x; + memcpy_pic (dst, dst_stride, src, src_stride, w, h); + } } /* Copy YUY2 images */ static void -copy_image_YUY2( - GstVaapiImageRaw *dst_image, - GstVaapiImageRaw *src_image, - const GstVaapiRectangle *rect -) +copy_image_YUY2 (GstVaapiImageRaw * dst_image, + GstVaapiImageRaw * src_image, const GstVaapiRectangle * rect) { - guchar *dst, *src; - guint dst_stride, src_stride; + guchar *dst, *src; + guint dst_stride, src_stride; - /* YUV 4:2:2, full vertical resolution */ - dst_stride = dst_image->stride[0]; - dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x * 2; - src_stride = src_image->stride[0]; - src = src_image->pixels[0] + rect->y * src_stride + rect->x * 2; - memcpy_pic(dst, dst_stride, src, src_stride, rect->width * 2, rect->height); + /* YUV 4:2:2, full vertical resolution */ + dst_stride = dst_image->stride[0]; + dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x * 2; + src_stride = src_image->stride[0]; + src = src_image->pixels[0] + rect->y * src_stride + rect->x * 2; + memcpy_pic (dst, dst_stride, src, src_stride, rect->width * 2, rect->height); } /* Copy RGBA images */ static void -copy_image_RGBA( - GstVaapiImageRaw *dst_image, - GstVaapiImageRaw *src_image, - const GstVaapiRectangle *rect -) +copy_image_RGBA (GstVaapiImageRaw * dst_image, + GstVaapiImageRaw * src_image, const GstVaapiRectangle * rect) { - guchar *dst, *src; - guint dst_stride, src_stride; + guchar *dst, *src; + guint dst_stride, src_stride; - dst_stride = dst_image->stride[0]; - dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x; - src_stride = src_image->stride[0]; - src = src_image->pixels[0] + rect->y * src_stride + rect->x; - memcpy_pic(dst, dst_stride, src, src_stride, 4 * rect->width, rect->height); + dst_stride = dst_image->stride[0]; + dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x; + src_stride = src_image->stride[0]; + src = src_image->pixels[0] + rect->y * src_stride + rect->x; + memcpy_pic (dst, dst_stride, src, src_stride, 4 * rect->width, rect->height); } static gboolean -copy_image( - GstVaapiImageRaw *dst_image, - GstVaapiImageRaw *src_image, - const GstVaapiRectangle *rect -) +copy_image (GstVaapiImageRaw * dst_image, + GstVaapiImageRaw * src_image, const GstVaapiRectangle * rect) { - GstVaapiRectangle default_rect; + GstVaapiRectangle default_rect; - if (dst_image->format != src_image->format || - dst_image->width != src_image->width || - dst_image->height != src_image->height) - return FALSE; + if (dst_image->format != src_image->format || + dst_image->width != src_image->width || + dst_image->height != src_image->height) + return FALSE; - if (rect) { - if (rect->x >= src_image->width || - rect->x + rect->width > src_image->width || - rect->y >= src_image->height || - rect->y + rect->height > src_image->height) - return FALSE; - } - else { - default_rect.x = 0; - default_rect.y = 0; - default_rect.width = src_image->width; - default_rect.height = src_image->height; - rect = &default_rect; - } + if (rect) { + if (rect->x >= src_image->width || + rect->x + rect->width > src_image->width || + rect->y >= src_image->height || + rect->y + rect->height > src_image->height) + return FALSE; + } else { + default_rect.x = 0; + default_rect.y = 0; + default_rect.width = src_image->width; + default_rect.height = src_image->height; + rect = &default_rect; + } - switch (dst_image->format) { + switch (dst_image->format) { case GST_VIDEO_FORMAT_NV12: - copy_image_NV12(dst_image, src_image, rect); - break; + copy_image_NV12 (dst_image, src_image, rect); + break; case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_I420: - copy_image_YV12(dst_image, src_image, rect); - break; + copy_image_YV12 (dst_image, src_image, rect); + break; case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_UYVY: - copy_image_YUY2(dst_image, src_image, rect); - break; + copy_image_YUY2 (dst_image, src_image, rect); + break; case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_RGBA: case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_BGRA: - copy_image_RGBA(dst_image, src_image, rect); - break; + copy_image_RGBA (dst_image, src_image, rect); + break; default: - GST_ERROR("unsupported image format for copy"); - return FALSE; - } - return TRUE; + GST_ERROR ("unsupported image format for copy"); + return FALSE; + } + return TRUE; } /** @@ -898,34 +860,31 @@ copy_image( * Return value: %TRUE on success */ gboolean -gst_vaapi_image_get_buffer( - GstVaapiImage *image, - GstBuffer *buffer, - GstVaapiRectangle *rect -) +gst_vaapi_image_get_buffer (GstVaapiImage * image, + GstBuffer * buffer, GstVaapiRectangle * rect) { - GstVaapiImageRaw dst_image, src_image; - gboolean success; + GstVaapiImageRaw dst_image, src_image; + gboolean success; - g_return_val_if_fail(image != NULL, FALSE); - g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE); + g_return_val_if_fail (image != NULL, FALSE); + g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); - if (!init_image_from_buffer(&dst_image, buffer)) - return FALSE; - if (dst_image.format != image->format) - return FALSE; - if (dst_image.width != image->width || dst_image.height != image->height) - return FALSE; + if (!init_image_from_buffer (&dst_image, buffer)) + return FALSE; + if (dst_image.format != image->format) + return FALSE; + if (dst_image.width != image->width || dst_image.height != image->height) + return FALSE; - if (!_gst_vaapi_image_map(image, &src_image)) - return FALSE; + if (!_gst_vaapi_image_map (image, &src_image)) + return FALSE; - success = copy_image(&dst_image, &src_image, rect); + success = copy_image (&dst_image, &src_image, rect); - if (!_gst_vaapi_image_unmap(image)) - return FALSE; + if (!_gst_vaapi_image_unmap (image)) + return FALSE; - return success; + return success; } /** @@ -941,26 +900,23 @@ gst_vaapi_image_get_buffer( * Return value: %TRUE on success */ gboolean -gst_vaapi_image_get_raw( - GstVaapiImage *image, - GstVaapiImageRaw *dst_image, - GstVaapiRectangle *rect -) +gst_vaapi_image_get_raw (GstVaapiImage * image, + GstVaapiImageRaw * dst_image, GstVaapiRectangle * rect) { - GstVaapiImageRaw src_image; - gboolean success; + GstVaapiImageRaw src_image; + gboolean success; - g_return_val_if_fail(image != NULL, FALSE); + g_return_val_if_fail (image != NULL, FALSE); - if (!_gst_vaapi_image_map(image, &src_image)) - return FALSE; + if (!_gst_vaapi_image_map (image, &src_image)) + return FALSE; - success = copy_image(dst_image, &src_image, rect); + success = copy_image (dst_image, &src_image, rect); - if (!_gst_vaapi_image_unmap(image)) - return FALSE; + if (!_gst_vaapi_image_unmap (image)) + return FALSE; - return success; + return success; } /** @@ -976,34 +932,31 @@ gst_vaapi_image_get_raw( * Return value: %TRUE on success */ gboolean -gst_vaapi_image_update_from_buffer( - GstVaapiImage *image, - GstBuffer *buffer, - GstVaapiRectangle *rect -) +gst_vaapi_image_update_from_buffer (GstVaapiImage * image, + GstBuffer * buffer, GstVaapiRectangle * rect) { - GstVaapiImageRaw dst_image, src_image; - gboolean success; + GstVaapiImageRaw dst_image, src_image; + gboolean success; - g_return_val_if_fail(image != NULL, FALSE); - g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE); + g_return_val_if_fail (image != NULL, FALSE); + g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); - if (!init_image_from_buffer(&src_image, buffer)) - return FALSE; - if (src_image.format != image->format) - return FALSE; - if (src_image.width != image->width || src_image.height != image->height) - return FALSE; + if (!init_image_from_buffer (&src_image, buffer)) + return FALSE; + if (src_image.format != image->format) + return FALSE; + if (src_image.width != image->width || src_image.height != image->height) + return FALSE; - if (!_gst_vaapi_image_map(image, &dst_image)) - return FALSE; + if (!_gst_vaapi_image_map (image, &dst_image)) + return FALSE; - success = copy_image(&dst_image, &src_image, rect); + success = copy_image (&dst_image, &src_image, rect); - if (!_gst_vaapi_image_unmap(image)) - return FALSE; + if (!_gst_vaapi_image_unmap (image)) + return FALSE; - return success; + return success; } /** @@ -1020,26 +973,23 @@ gst_vaapi_image_update_from_buffer( * Return value: %TRUE on success */ gboolean -gst_vaapi_image_update_from_raw( - GstVaapiImage *image, - GstVaapiImageRaw *src_image, - GstVaapiRectangle *rect -) +gst_vaapi_image_update_from_raw (GstVaapiImage * image, + GstVaapiImageRaw * src_image, GstVaapiRectangle * rect) { - GstVaapiImageRaw dst_image; - gboolean success; + GstVaapiImageRaw dst_image; + gboolean success; - g_return_val_if_fail(image != NULL, FALSE); + g_return_val_if_fail (image != NULL, FALSE); - if (!_gst_vaapi_image_map(image, &dst_image)) - return FALSE; + if (!_gst_vaapi_image_map (image, &dst_image)) + return FALSE; - success = copy_image(&dst_image, src_image, rect); + success = copy_image (&dst_image, src_image, rect); - if (!_gst_vaapi_image_unmap(image)) - return FALSE; + if (!_gst_vaapi_image_unmap (image)) + return FALSE; - return success; + return success; } /** @@ -1053,23 +1003,23 @@ gst_vaapi_image_update_from_raw( * Return value: %TRUE on success */ gboolean -gst_vaapi_image_copy(GstVaapiImage *dst_image, GstVaapiImage *src_image) +gst_vaapi_image_copy (GstVaapiImage * dst_image, GstVaapiImage * src_image) { - GstVaapiImageRaw dst_image_raw, src_image_raw; - gboolean success = FALSE; + GstVaapiImageRaw dst_image_raw, src_image_raw; + gboolean success = FALSE; - g_return_val_if_fail(dst_image != NULL, FALSE); - g_return_val_if_fail(src_image != NULL, FALSE); + g_return_val_if_fail (dst_image != NULL, FALSE); + g_return_val_if_fail (src_image != NULL, FALSE); - if (!_gst_vaapi_image_map(dst_image, &dst_image_raw)) - goto end; - if (!_gst_vaapi_image_map(src_image, &src_image_raw)) - goto end; + if (!_gst_vaapi_image_map (dst_image, &dst_image_raw)) + goto end; + if (!_gst_vaapi_image_map (src_image, &src_image_raw)) + goto end; - success = copy_image(&dst_image_raw, &src_image_raw, NULL); + success = copy_image (&dst_image_raw, &src_image_raw, NULL); end: - _gst_vaapi_image_unmap(src_image); - _gst_vaapi_image_unmap(dst_image); - return success; + _gst_vaapi_image_unmap (src_image); + _gst_vaapi_image_unmap (dst_image); + return success; } diff --git a/gst-libs/gst/vaapi/gstvaapiparser_frame.c b/gst-libs/gst/vaapi/gstvaapiparser_frame.c index 11bc2febbf..1f75e814bb 100644 --- a/gst-libs/gst/vaapi/gstvaapiparser_frame.c +++ b/gst-libs/gst/vaapi/gstvaapiparser_frame.c @@ -29,40 +29,40 @@ #include "gstvaapiparser_frame.h" static inline const GstVaapiMiniObjectClass * -gst_vaapi_parser_frame_class(void) +gst_vaapi_parser_frame_class (void) { - static const GstVaapiMiniObjectClass GstVaapiParserFrameClass = { - sizeof(GstVaapiParserFrame), - (GDestroyNotify)gst_vaapi_parser_frame_free - }; - return &GstVaapiParserFrameClass; + static const GstVaapiMiniObjectClass GstVaapiParserFrameClass = { + sizeof (GstVaapiParserFrame), + (GDestroyNotify) gst_vaapi_parser_frame_free + }; + return &GstVaapiParserFrameClass; } static inline gboolean -alloc_units(GArray **units_ptr, guint size) +alloc_units (GArray ** units_ptr, guint size) { - GArray *units; + GArray *units; - units = g_array_sized_new(FALSE, FALSE, sizeof(GstVaapiDecoderUnit), size); - *units_ptr = units; - return units != NULL; + units = g_array_sized_new (FALSE, FALSE, sizeof (GstVaapiDecoderUnit), size); + *units_ptr = units; + return units != NULL; } static inline void -free_units(GArray **units_ptr) +free_units (GArray ** units_ptr) { - GArray * const units = *units_ptr; - guint i; + GArray *const units = *units_ptr; + guint i; - if (units) { - for (i = 0; i < units->len; i++) { - GstVaapiDecoderUnit * const unit = - &g_array_index(units, GstVaapiDecoderUnit, i); - gst_vaapi_decoder_unit_clear(unit); - } - g_array_free(units, TRUE); - *units_ptr = NULL; + if (units) { + for (i = 0; i < units->len; i++) { + GstVaapiDecoderUnit *const unit = + &g_array_index (units, GstVaapiDecoderUnit, i); + gst_vaapi_decoder_unit_clear (unit); } + g_array_free (units, TRUE); + *units_ptr = NULL; + } } /** @@ -75,32 +75,32 @@ free_units(GArray **units_ptr) * Returns: The newly allocated #GstVaapiParserFrame */ GstVaapiParserFrame * -gst_vaapi_parser_frame_new(guint width, guint height) +gst_vaapi_parser_frame_new (guint width, guint height) { - GstVaapiParserFrame *frame; - guint num_slices; + GstVaapiParserFrame *frame; + guint num_slices; - frame = (GstVaapiParserFrame *) - gst_vaapi_mini_object_new(gst_vaapi_parser_frame_class()); - if (!frame) - return NULL; + frame = (GstVaapiParserFrame *) + gst_vaapi_mini_object_new (gst_vaapi_parser_frame_class ()); + if (!frame) + return NULL; - if (!height) - height = 1088; - num_slices = (height + 15) / 16; + if (!height) + height = 1088; + num_slices = (height + 15) / 16; - if (!alloc_units(&frame->pre_units, 16)) - goto error; - if (!alloc_units(&frame->units, num_slices)) - goto error; - if (!alloc_units(&frame->post_units, 1)) - goto error; - frame->output_offset = 0; - return frame; + if (!alloc_units (&frame->pre_units, 16)) + goto error; + if (!alloc_units (&frame->units, num_slices)) + goto error; + if (!alloc_units (&frame->post_units, 1)) + goto error; + frame->output_offset = 0; + return frame; error: - gst_vaapi_parser_frame_unref(frame); - return NULL; + gst_vaapi_parser_frame_unref (frame); + return NULL; } /** @@ -114,11 +114,11 @@ error: * sub-classes. */ void -gst_vaapi_parser_frame_free(GstVaapiParserFrame *frame) +gst_vaapi_parser_frame_free (GstVaapiParserFrame * frame) { - free_units(&frame->units); - free_units(&frame->pre_units); - free_units(&frame->post_units); + free_units (&frame->units); + free_units (&frame->pre_units); + free_units (&frame->post_units); } /** @@ -129,19 +129,19 @@ gst_vaapi_parser_frame_free(GstVaapiParserFrame *frame) * Appends unit to the @frame. */ void -gst_vaapi_parser_frame_append_unit(GstVaapiParserFrame *frame, - GstVaapiDecoderUnit *unit) +gst_vaapi_parser_frame_append_unit (GstVaapiParserFrame * frame, + GstVaapiDecoderUnit * unit) { - GArray **unit_array_ptr; + GArray **unit_array_ptr; - unit->offset = frame->output_offset; - frame->output_offset += unit->size; + unit->offset = frame->output_offset; + frame->output_offset += unit->size; - if (GST_VAAPI_DECODER_UNIT_IS_SLICE(unit)) - unit_array_ptr = &frame->units; - else if (GST_VAAPI_DECODER_UNIT_IS_FRAME_END(unit)) - unit_array_ptr = &frame->post_units; - else - unit_array_ptr = &frame->pre_units; - g_array_append_val(*unit_array_ptr, *unit); + if (GST_VAAPI_DECODER_UNIT_IS_SLICE (unit)) + unit_array_ptr = &frame->units; + else if (GST_VAAPI_DECODER_UNIT_IS_FRAME_END (unit)) + unit_array_ptr = &frame->post_units; + else + unit_array_ptr = &frame->pre_units; + g_array_append_val (*unit_array_ptr, *unit); } diff --git a/gst-libs/gst/vaapi/gstvaapipixmap.c b/gst-libs/gst/vaapi/gstvaapipixmap.c index e01d033401..aba117c53e 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap.c +++ b/gst-libs/gst/vaapi/gstvaapipixmap.c @@ -39,61 +39,61 @@ #undef gst_vaapi_pixmap_replace static inline GstVaapiPixmap * -gst_vaapi_pixmap_new_internal(const GstVaapiPixmapClass *pixmap_class, - GstVaapiDisplay *display) +gst_vaapi_pixmap_new_internal (const GstVaapiPixmapClass * pixmap_class, + GstVaapiDisplay * display) { - g_assert(pixmap_class->create != NULL); - g_assert(pixmap_class->render != NULL); + g_assert (pixmap_class->create != NULL); + g_assert (pixmap_class->render != NULL); - return gst_vaapi_object_new(GST_VAAPI_OBJECT_CLASS(pixmap_class), display); + return gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (pixmap_class), display); } GstVaapiPixmap * -gst_vaapi_pixmap_new(const GstVaapiPixmapClass *pixmap_class, - GstVaapiDisplay *display, GstVideoFormat format, guint width, guint height) +gst_vaapi_pixmap_new (const GstVaapiPixmapClass * pixmap_class, + GstVaapiDisplay * display, GstVideoFormat format, guint width, guint height) { - GstVaapiPixmap *pixmap; + GstVaapiPixmap *pixmap; - g_return_val_if_fail(format != GST_VIDEO_FORMAT_UNKNOWN && - format != GST_VIDEO_FORMAT_ENCODED, NULL); - g_return_val_if_fail(width > 0, NULL); - g_return_val_if_fail(height > 0, NULL); + g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN && + format != GST_VIDEO_FORMAT_ENCODED, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); - pixmap = gst_vaapi_pixmap_new_internal(pixmap_class, display); - if (!pixmap) - return NULL; + pixmap = gst_vaapi_pixmap_new_internal (pixmap_class, display); + if (!pixmap) + return NULL; - pixmap->format = format; - pixmap->width = width; - pixmap->height = height; - if (!pixmap_class->create(pixmap)) - goto error; - return pixmap; + pixmap->format = format; + pixmap->width = width; + pixmap->height = height; + if (!pixmap_class->create (pixmap)) + goto error; + return pixmap; error: - gst_vaapi_pixmap_unref_internal(pixmap); - return NULL; + gst_vaapi_pixmap_unref_internal (pixmap); + return NULL; } GstVaapiPixmap * -gst_vaapi_pixmap_new_from_native(const GstVaapiPixmapClass *pixmap_class, - GstVaapiDisplay *display, gpointer native_pixmap) +gst_vaapi_pixmap_new_from_native (const GstVaapiPixmapClass * pixmap_class, + GstVaapiDisplay * display, gpointer native_pixmap) { - GstVaapiPixmap *pixmap; + GstVaapiPixmap *pixmap; - pixmap = gst_vaapi_pixmap_new_internal(pixmap_class, display); - if (!pixmap) - return NULL; + pixmap = gst_vaapi_pixmap_new_internal (pixmap_class, display); + if (!pixmap) + return NULL; - GST_VAAPI_OBJECT_ID(pixmap) = GPOINTER_TO_SIZE(native_pixmap); - pixmap->use_foreign_pixmap = TRUE; - if (!pixmap_class->create(pixmap)) - goto error; - return pixmap; + GST_VAAPI_OBJECT_ID (pixmap) = GPOINTER_TO_SIZE (native_pixmap); + pixmap->use_foreign_pixmap = TRUE; + if (!pixmap_class->create (pixmap)) + goto error; + return pixmap; error: - gst_vaapi_pixmap_unref_internal(pixmap); - return NULL; + gst_vaapi_pixmap_unref_internal (pixmap); + return NULL; } /** @@ -105,9 +105,9 @@ error: * Returns: The same @pixmap argument */ GstVaapiPixmap * -gst_vaapi_pixmap_ref(GstVaapiPixmap *pixmap) +gst_vaapi_pixmap_ref (GstVaapiPixmap * pixmap) { - return gst_vaapi_pixmap_ref_internal(pixmap); + return gst_vaapi_pixmap_ref_internal (pixmap); } /** @@ -118,9 +118,9 @@ gst_vaapi_pixmap_ref(GstVaapiPixmap *pixmap) * the reference count reaches zero, the pixmap will be free'd. */ void -gst_vaapi_pixmap_unref(GstVaapiPixmap *pixmap) +gst_vaapi_pixmap_unref (GstVaapiPixmap * pixmap) { - gst_vaapi_pixmap_unref_internal(pixmap); + gst_vaapi_pixmap_unref_internal (pixmap); } /** @@ -133,10 +133,10 @@ gst_vaapi_pixmap_unref(GstVaapiPixmap *pixmap) * valid pixmap. However, @new_pixmap can be NULL. */ void -gst_vaapi_pixmap_replace(GstVaapiPixmap **old_pixmap_ptr, - GstVaapiPixmap *new_pixmap) +gst_vaapi_pixmap_replace (GstVaapiPixmap ** old_pixmap_ptr, + GstVaapiPixmap * new_pixmap) { - gst_vaapi_pixmap_replace_internal(old_pixmap_ptr, new_pixmap); + gst_vaapi_pixmap_replace_internal (old_pixmap_ptr, new_pixmap); } /** @@ -148,11 +148,11 @@ gst_vaapi_pixmap_replace(GstVaapiPixmap **old_pixmap_ptr, * Return value: the parent #GstVaapiDisplay object */ GstVaapiDisplay * -gst_vaapi_pixmap_get_display(GstVaapiPixmap *pixmap) +gst_vaapi_pixmap_get_display (GstVaapiPixmap * pixmap) { - g_return_val_if_fail(pixmap != NULL, NULL); + g_return_val_if_fail (pixmap != NULL, NULL); - return GST_VAAPI_OBJECT_DISPLAY(pixmap); + return GST_VAAPI_OBJECT_DISPLAY (pixmap); } /** @@ -164,11 +164,11 @@ gst_vaapi_pixmap_get_display(GstVaapiPixmap *pixmap) * Return value: the format of the @pixmap */ GstVideoFormat -gst_vaapi_pixmap_get_format(GstVaapiPixmap *pixmap) +gst_vaapi_pixmap_get_format (GstVaapiPixmap * pixmap) { - g_return_val_if_fail(pixmap != NULL, GST_VIDEO_FORMAT_UNKNOWN); + g_return_val_if_fail (pixmap != NULL, GST_VIDEO_FORMAT_UNKNOWN); - return GST_VAAPI_PIXMAP_FORMAT(pixmap); + return GST_VAAPI_PIXMAP_FORMAT (pixmap); } /** @@ -180,11 +180,11 @@ gst_vaapi_pixmap_get_format(GstVaapiPixmap *pixmap) * Return value: the width of the @pixmap, in pixels */ guint -gst_vaapi_pixmap_get_width(GstVaapiPixmap *pixmap) +gst_vaapi_pixmap_get_width (GstVaapiPixmap * pixmap) { - g_return_val_if_fail(pixmap != NULL, 0); + g_return_val_if_fail (pixmap != NULL, 0); - return GST_VAAPI_PIXMAP_WIDTH(pixmap); + return GST_VAAPI_PIXMAP_WIDTH (pixmap); } /** @@ -196,11 +196,11 @@ gst_vaapi_pixmap_get_width(GstVaapiPixmap *pixmap) * Return value: the height of the @pixmap, in pixels */ guint -gst_vaapi_pixmap_get_height(GstVaapiPixmap *pixmap) +gst_vaapi_pixmap_get_height (GstVaapiPixmap * pixmap) { - g_return_val_if_fail(pixmap != NULL, 0); + g_return_val_if_fail (pixmap != NULL, 0); - return GST_VAAPI_PIXMAP_HEIGHT(pixmap); + return GST_VAAPI_PIXMAP_HEIGHT (pixmap); } /** @@ -212,15 +212,16 @@ gst_vaapi_pixmap_get_height(GstVaapiPixmap *pixmap) * Retrieves the dimensions of a #GstVaapiPixmap. */ void -gst_vaapi_pixmap_get_size(GstVaapiPixmap *pixmap, guint *width, guint *height) +gst_vaapi_pixmap_get_size (GstVaapiPixmap * pixmap, guint * width, + guint * height) { - g_return_if_fail(pixmap != NULL); + g_return_if_fail (pixmap != NULL); - if (width) - *width = GST_VAAPI_PIXMAP_WIDTH(pixmap); + if (width) + *width = GST_VAAPI_PIXMAP_WIDTH (pixmap); - if (height) - *height = GST_VAAPI_PIXMAP_HEIGHT(pixmap); + if (height) + *height = GST_VAAPI_PIXMAP_HEIGHT (pixmap); } /** @@ -240,21 +241,21 @@ gst_vaapi_pixmap_get_size(GstVaapiPixmap *pixmap, guint *width, guint *height) * Return value: %TRUE on success */ gboolean -gst_vaapi_pixmap_put_surface(GstVaapiPixmap *pixmap, GstVaapiSurface *surface, - const GstVaapiRectangle *crop_rect, guint flags) +gst_vaapi_pixmap_put_surface (GstVaapiPixmap * pixmap, + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) { - GstVaapiRectangle src_rect; + GstVaapiRectangle src_rect; - g_return_val_if_fail(pixmap != NULL, FALSE); - g_return_val_if_fail(surface != NULL, FALSE); + g_return_val_if_fail (pixmap != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); - if (!crop_rect) { - src_rect.x = 0; - src_rect.y = 0; - src_rect.width = GST_VAAPI_SURFACE_WIDTH(surface); - src_rect.height = GST_VAAPI_SURFACE_HEIGHT(surface); - crop_rect = &src_rect; - } - return GST_VAAPI_PIXMAP_GET_CLASS(pixmap)->render(pixmap, surface, - crop_rect, flags); + if (!crop_rect) { + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = GST_VAAPI_SURFACE_WIDTH (surface); + src_rect.height = GST_VAAPI_SURFACE_HEIGHT (surface); + crop_rect = &src_rect; + } + return GST_VAAPI_PIXMAP_GET_CLASS (pixmap)->render (pixmap, surface, + crop_rect, flags); } diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c index 4a14f80c41..9ffccd9d8c 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c +++ b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c @@ -38,134 +38,131 @@ #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiPixmapX11Class GstVaapiPixmapX11Class; +typedef struct _GstVaapiPixmapX11Class GstVaapiPixmapX11Class; -struct _GstVaapiPixmapX11 { - GstVaapiPixmap parent_instance; +struct _GstVaapiPixmapX11 +{ + GstVaapiPixmap parent_instance; }; -struct _GstVaapiPixmapX11Class { - GstVaapiPixmapClass parent_class; +struct _GstVaapiPixmapX11Class +{ + GstVaapiPixmapClass parent_class; }; static gboolean -gst_vaapi_pixmap_x11_create_from_xid(GstVaapiPixmap *pixmap, Pixmap xid) +gst_vaapi_pixmap_x11_create_from_xid (GstVaapiPixmap * pixmap, Pixmap xid) { - guint depth; - gboolean success; + guint depth; + gboolean success; - if (!xid) - return FALSE; + if (!xid) + return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(pixmap); - success = x11_get_geometry(GST_VAAPI_OBJECT_NATIVE_DISPLAY(pixmap), xid, - NULL, NULL, &pixmap->width, &pixmap->height, &depth); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(pixmap); - if (!success) - return FALSE; + GST_VAAPI_OBJECT_LOCK_DISPLAY (pixmap); + success = x11_get_geometry (GST_VAAPI_OBJECT_NATIVE_DISPLAY (pixmap), xid, + NULL, NULL, &pixmap->width, &pixmap->height, &depth); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (pixmap); + if (!success) + return FALSE; - pixmap->format = gst_vaapi_display_x11_get_pixmap_format( - GST_VAAPI_OBJECT_DISPLAY_X11(pixmap), depth); - if (pixmap->format == GST_VIDEO_FORMAT_UNKNOWN) - return FALSE; - return TRUE; + pixmap->format = + gst_vaapi_display_x11_get_pixmap_format (GST_VAAPI_OBJECT_DISPLAY_X11 + (pixmap), depth); + if (pixmap->format == GST_VIDEO_FORMAT_UNKNOWN) + return FALSE; + return TRUE; } static gboolean -gst_vaapi_pixmap_x11_create(GstVaapiPixmap *pixmap) +gst_vaapi_pixmap_x11_create (GstVaapiPixmap * pixmap) { - GstVaapiDisplayX11 * const display = - GST_VAAPI_DISPLAY_X11(GST_VAAPI_OBJECT_DISPLAY(pixmap)); - Display * const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY(display); - Window rootwin; - Pixmap xid; - guint depth; + GstVaapiDisplayX11 *const display = + GST_VAAPI_DISPLAY_X11 (GST_VAAPI_OBJECT_DISPLAY (pixmap)); + Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (display); + Window rootwin; + Pixmap xid; + guint depth; - if (pixmap->use_foreign_pixmap) - return gst_vaapi_pixmap_x11_create_from_xid(pixmap, - GST_VAAPI_OBJECT_ID(pixmap)); + if (pixmap->use_foreign_pixmap) + return gst_vaapi_pixmap_x11_create_from_xid (pixmap, + GST_VAAPI_OBJECT_ID (pixmap)); - depth = gst_vaapi_display_x11_get_pixmap_depth(display, pixmap->format); - if (!depth) - return FALSE; + depth = gst_vaapi_display_x11_get_pixmap_depth (display, pixmap->format); + if (!depth) + return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(pixmap); - rootwin = RootWindow(dpy, DefaultScreen(dpy)); - xid = XCreatePixmap(dpy, rootwin, pixmap->width, pixmap->height, depth); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(pixmap); + GST_VAAPI_OBJECT_LOCK_DISPLAY (pixmap); + rootwin = RootWindow (dpy, DefaultScreen (dpy)); + xid = XCreatePixmap (dpy, rootwin, pixmap->width, pixmap->height, depth); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (pixmap); - GST_DEBUG("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(xid)); - GST_VAAPI_OBJECT_ID(pixmap) = xid; - return xid != None; + GST_DEBUG ("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (xid)); + GST_VAAPI_OBJECT_ID (pixmap) = xid; + return xid != None; } static void -gst_vaapi_pixmap_x11_destroy(GstVaapiPixmap *pixmap) +gst_vaapi_pixmap_x11_destroy (GstVaapiPixmap * pixmap) { - const Pixmap xid = GST_VAAPI_OBJECT_ID(pixmap); + const Pixmap xid = GST_VAAPI_OBJECT_ID (pixmap); - if (xid) { - if (!pixmap->use_foreign_pixmap) { - GST_VAAPI_OBJECT_LOCK_DISPLAY(pixmap); - XFreePixmap(GST_VAAPI_OBJECT_NATIVE_DISPLAY(pixmap), xid); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(pixmap); - } - GST_VAAPI_OBJECT_ID(pixmap) = None; + if (xid) { + if (!pixmap->use_foreign_pixmap) { + GST_VAAPI_OBJECT_LOCK_DISPLAY (pixmap); + XFreePixmap (GST_VAAPI_OBJECT_NATIVE_DISPLAY (pixmap), xid); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (pixmap); } + GST_VAAPI_OBJECT_ID (pixmap) = None; + } } static gboolean -gst_vaapi_pixmap_x11_render(GstVaapiPixmap *pixmap, GstVaapiSurface *surface, - const GstVaapiRectangle *crop_rect, guint flags) +gst_vaapi_pixmap_x11_render (GstVaapiPixmap * pixmap, GstVaapiSurface * surface, + const GstVaapiRectangle * crop_rect, guint flags) { - VASurfaceID surface_id; - VAStatus status; + VASurfaceID surface_id; + VAStatus status; - surface_id = GST_VAAPI_OBJECT_ID(surface); - if (surface_id == VA_INVALID_ID) - return FALSE; + surface_id = GST_VAAPI_OBJECT_ID (surface); + if (surface_id == VA_INVALID_ID) + return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY(pixmap); - status = vaPutSurface( - GST_VAAPI_OBJECT_VADISPLAY(pixmap), - surface_id, - GST_VAAPI_OBJECT_ID(pixmap), - crop_rect->x, crop_rect->y, - crop_rect->width, crop_rect->height, - 0, 0, - GST_VAAPI_PIXMAP_WIDTH(pixmap), - GST_VAAPI_PIXMAP_HEIGHT(pixmap), - NULL, 0, - from_GstVaapiSurfaceRenderFlags(flags) - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(pixmap); - if (!vaapi_check_status(status, "vaPutSurface() [pixmap]")) - return FALSE; - return TRUE; + GST_VAAPI_OBJECT_LOCK_DISPLAY (pixmap); + status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (pixmap), + surface_id, + GST_VAAPI_OBJECT_ID (pixmap), + crop_rect->x, crop_rect->y, + crop_rect->width, crop_rect->height, + 0, 0, + GST_VAAPI_PIXMAP_WIDTH (pixmap), + GST_VAAPI_PIXMAP_HEIGHT (pixmap), + NULL, 0, from_GstVaapiSurfaceRenderFlags (flags) + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (pixmap); + if (!vaapi_check_status (status, "vaPutSurface() [pixmap]")) + return FALSE; + return TRUE; } void -gst_vaapi_pixmap_x11_class_init(GstVaapiPixmapX11Class *klass) +gst_vaapi_pixmap_x11_class_init (GstVaapiPixmapX11Class * klass) { - GstVaapiObjectClass * const object_class = - GST_VAAPI_OBJECT_CLASS(klass); - GstVaapiPixmapClass * const pixmap_class = - GST_VAAPI_PIXMAP_CLASS(klass); + GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); + GstVaapiPixmapClass *const pixmap_class = GST_VAAPI_PIXMAP_CLASS (klass); - object_class->finalize = (GstVaapiObjectFinalizeFunc) - gst_vaapi_pixmap_x11_destroy; + object_class->finalize = (GstVaapiObjectFinalizeFunc) + gst_vaapi_pixmap_x11_destroy; - pixmap_class->create = gst_vaapi_pixmap_x11_create; - pixmap_class->render = gst_vaapi_pixmap_x11_render; + pixmap_class->create = gst_vaapi_pixmap_x11_create; + pixmap_class->render = gst_vaapi_pixmap_x11_render; } #define gst_vaapi_pixmap_x11_finalize \ gst_vaapi_pixmap_x11_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( - GstVaapiPixmapX11, - gst_vaapi_pixmap_x11, - gst_vaapi_pixmap_x11_class_init(&g_class)) +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiPixmapX11, + gst_vaapi_pixmap_x11, gst_vaapi_pixmap_x11_class_init (&g_class)) /** * gst_vaapi_pixmap_x11_new: @@ -179,17 +176,17 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE( * * Return value: the newly allocated #GstVaapiPixmap object */ -GstVaapiPixmap * -gst_vaapi_pixmap_x11_new(GstVaapiDisplay *display, GstVideoFormat format, - guint width, guint height) + GstVaapiPixmap *gst_vaapi_pixmap_x11_new (GstVaapiDisplay * display, + GstVideoFormat format, guint width, guint height) { - GST_DEBUG("new pixmap, format %s, size %ux%u", - gst_vaapi_video_format_to_string(format), width, height); + GST_DEBUG ("new pixmap, format %s, size %ux%u", + gst_vaapi_video_format_to_string (format), width, height); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); - return gst_vaapi_pixmap_new(GST_VAAPI_PIXMAP_CLASS( - gst_vaapi_pixmap_x11_class()), display, format, width, height); + return + gst_vaapi_pixmap_new (GST_VAAPI_PIXMAP_CLASS (gst_vaapi_pixmap_x11_class + ()), display, format, width, height); } /** @@ -205,15 +202,16 @@ gst_vaapi_pixmap_x11_new(GstVaapiDisplay *display, GstVideoFormat format, * Return value: the newly allocated #GstVaapiPixmap object */ GstVaapiPixmap * -gst_vaapi_pixmap_x11_new_with_xid(GstVaapiDisplay *display, Pixmap xid) +gst_vaapi_pixmap_x11_new_with_xid (GstVaapiDisplay * display, Pixmap xid) { - GST_DEBUG("new pixmap from xid 0x%08x", (guint)xid); + GST_DEBUG ("new pixmap from xid 0x%08x", (guint) xid); - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); - g_return_val_if_fail(xid != None, NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); + g_return_val_if_fail (xid != None, NULL); - return gst_vaapi_pixmap_new_from_native(GST_VAAPI_PIXMAP_CLASS( - gst_vaapi_pixmap_x11_class()), display, GSIZE_TO_POINTER(xid)); + return + gst_vaapi_pixmap_new_from_native (GST_VAAPI_PIXMAP_CLASS + (gst_vaapi_pixmap_x11_class ()), display, GSIZE_TO_POINTER (xid)); } /** @@ -227,11 +225,11 @@ gst_vaapi_pixmap_x11_new_with_xid(GstVaapiDisplay *display, Pixmap xid) * Return value: the underlying X11 Pixmap bound to @pixmap. */ Pixmap -gst_vaapi_pixmap_x11_get_xid(GstVaapiPixmapX11 *pixmap) +gst_vaapi_pixmap_x11_get_xid (GstVaapiPixmapX11 * pixmap) { - g_return_val_if_fail(pixmap != NULL, None); + g_return_val_if_fail (pixmap != NULL, None); - return GST_VAAPI_OBJECT_ID(pixmap); + return GST_VAAPI_OBJECT_ID (pixmap); } /** @@ -245,9 +243,9 @@ gst_vaapi_pixmap_x11_get_xid(GstVaapiPixmapX11 *pixmap) * caller (foreign pixmap) */ gboolean -gst_vaapi_pixmap_x11_is_foreign_xid(GstVaapiPixmapX11 *pixmap) +gst_vaapi_pixmap_x11_is_foreign_xid (GstVaapiPixmapX11 * pixmap) { - g_return_val_if_fail(pixmap != NULL, FALSE); + g_return_val_if_fail (pixmap != NULL, FALSE); - return GST_VAAPI_PIXMAP(pixmap)->use_foreign_pixmap; + return GST_VAAPI_PIXMAP (pixmap)->use_foreign_pixmap; } diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 5ebbb8a6ef..3db05c9071 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -34,172 +34,153 @@ #include "gstvaapiprofile.h" #include "gstvaapiworkarounds.h" -typedef struct _GstVaapiCodecMap GstVaapiCodecMap; -typedef struct _GstVaapiProfileMap GstVaapiProfileMap; -typedef struct _GstVaapiEntrypointMap GstVaapiEntrypointMap; +typedef struct _GstVaapiCodecMap GstVaapiCodecMap; +typedef struct _GstVaapiProfileMap GstVaapiProfileMap; +typedef struct _GstVaapiEntrypointMap GstVaapiEntrypointMap; -struct _GstVaapiCodecMap { - GstVaapiCodec codec; - const gchar *name; +struct _GstVaapiCodecMap +{ + GstVaapiCodec codec; + const gchar *name; }; -struct _GstVaapiProfileMap { - GstVaapiProfile profile; - VAProfile va_profile; - const char *media_str; - const gchar *profile_str; +struct _GstVaapiProfileMap +{ + GstVaapiProfile profile; + VAProfile va_profile; + const char *media_str; + const gchar *profile_str; }; -struct _GstVaapiEntrypointMap { - GstVaapiEntrypoint entrypoint; - VAEntrypoint va_entrypoint; +struct _GstVaapiEntrypointMap +{ + GstVaapiEntrypoint entrypoint; + VAEntrypoint va_entrypoint; }; /* Codecs */ static const GstVaapiCodecMap gst_vaapi_codecs[] = { - { GST_VAAPI_CODEC_MPEG1, "mpeg1" }, - { GST_VAAPI_CODEC_MPEG2, "mpeg2" }, - { GST_VAAPI_CODEC_MPEG4, "mpeg4" }, - { GST_VAAPI_CODEC_H263, "h263" }, - { GST_VAAPI_CODEC_H264, "h264" }, - { GST_VAAPI_CODEC_WMV3, "wmv3" }, - { GST_VAAPI_CODEC_VC1, "vc1" }, - { GST_VAAPI_CODEC_JPEG, "jpeg" }, - { GST_VAAPI_CODEC_VP8, "vp8" }, - { GST_VAAPI_CODEC_H265, "h265" }, - { GST_VAAPI_CODEC_VP9, "vp9" }, - { 0, } + {GST_VAAPI_CODEC_MPEG1, "mpeg1"}, + {GST_VAAPI_CODEC_MPEG2, "mpeg2"}, + {GST_VAAPI_CODEC_MPEG4, "mpeg4"}, + {GST_VAAPI_CODEC_H263, "h263"}, + {GST_VAAPI_CODEC_H264, "h264"}, + {GST_VAAPI_CODEC_WMV3, "wmv3"}, + {GST_VAAPI_CODEC_VC1, "vc1"}, + {GST_VAAPI_CODEC_JPEG, "jpeg"}, + {GST_VAAPI_CODEC_VP8, "vp8"}, + {GST_VAAPI_CODEC_H265, "h265"}, + {GST_VAAPI_CODEC_VP9, "vp9"}, + {0,} }; /* Profiles */ static const GstVaapiProfileMap gst_vaapi_profiles[] = { - { GST_VAAPI_PROFILE_MPEG2_SIMPLE, VAProfileMPEG2Simple, - "video/mpeg, mpegversion=2", "simple" - }, - { GST_VAAPI_PROFILE_MPEG2_MAIN, VAProfileMPEG2Main, - "video/mpeg, mpegversion=2", "main" - }, - { GST_VAAPI_PROFILE_MPEG4_SIMPLE, VAProfileMPEG4Simple, - "video/mpeg, mpegversion=4", "simple" - }, - { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, - "video/mpeg, mpegversion=4", "advanced-simple" - }, - { GST_VAAPI_PROFILE_MPEG4_MAIN, VAProfileMPEG4Main, - "video/mpeg, mpegversion=4", "main" - }, - { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, - "video/x-divx, divxversion=5", "advanced-simple" - }, - { GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, - "video/x-xvid", "advanced-simple" - }, + {GST_VAAPI_PROFILE_MPEG2_SIMPLE, VAProfileMPEG2Simple, + "video/mpeg, mpegversion=2", "simple"}, + {GST_VAAPI_PROFILE_MPEG2_MAIN, VAProfileMPEG2Main, + "video/mpeg, mpegversion=2", "main"}, + {GST_VAAPI_PROFILE_MPEG4_SIMPLE, VAProfileMPEG4Simple, + "video/mpeg, mpegversion=4", "simple"}, + {GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, + "video/mpeg, mpegversion=4", "advanced-simple"}, + {GST_VAAPI_PROFILE_MPEG4_MAIN, VAProfileMPEG4Main, + "video/mpeg, mpegversion=4", "main"}, + {GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, + "video/x-divx, divxversion=5", "advanced-simple"}, + {GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, + "video/x-xvid", "advanced-simple"}, #if VA_CHECK_VERSION(0,30,0) - { GST_VAAPI_PROFILE_H263_BASELINE, VAProfileH263Baseline, - "video/x-h263, variant=itu, h263version=h263", "baseline" - }, + {GST_VAAPI_PROFILE_H263_BASELINE, VAProfileH263Baseline, + "video/x-h263, variant=itu, h263version=h263", "baseline"}, #endif - { GST_VAAPI_PROFILE_H264_BASELINE, VAProfileH264Baseline, - "video/x-h264", "baseline" - }, + {GST_VAAPI_PROFILE_H264_BASELINE, VAProfileH264Baseline, + "video/x-h264", "baseline"}, #if VA_CHECK_VERSION(0,31,1) - { GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE, - VAProfileH264ConstrainedBaseline, - "video/x-h264", "constrained-baseline" - }, + {GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE, + VAProfileH264ConstrainedBaseline, + "video/x-h264", "constrained-baseline"}, #endif - { GST_VAAPI_PROFILE_H264_MAIN, VAProfileH264Main, - "video/x-h264", "main" - }, - { GST_VAAPI_PROFILE_H264_HIGH, VAProfileH264High, - "video/x-h264", "high" - }, + {GST_VAAPI_PROFILE_H264_MAIN, VAProfileH264Main, + "video/x-h264", "main"}, + {GST_VAAPI_PROFILE_H264_HIGH, VAProfileH264High, + "video/x-h264", "high"}, #if VA_CHECK_VERSION(0,35,2) - { GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH, VAProfileH264MultiviewHigh, - "video/x-h264", "multiview-high" - }, - { GST_VAAPI_PROFILE_H264_STEREO_HIGH, VAProfileH264StereoHigh, - "video/x-h264", "stereo-high" - }, + {GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH, VAProfileH264MultiviewHigh, + "video/x-h264", "multiview-high"}, + {GST_VAAPI_PROFILE_H264_STEREO_HIGH, VAProfileH264StereoHigh, + "video/x-h264", "stereo-high"}, #endif - { GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, - "video/x-wmv, wmvversion=3", "simple" - }, - { GST_VAAPI_PROFILE_VC1_MAIN, VAProfileVC1Main, - "video/x-wmv, wmvversion=3", "main" - }, - { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, - "video/x-wmv, wmvversion=3, format=(string)WVC1", "advanced" - }, + {GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, + "video/x-wmv, wmvversion=3", "simple"}, + {GST_VAAPI_PROFILE_VC1_MAIN, VAProfileVC1Main, + "video/x-wmv, wmvversion=3", "main"}, + {GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, + "video/x-wmv, wmvversion=3, format=(string)WVC1", "advanced"}, #if VA_CHECK_VERSION(0,32,0) - { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline, - "image/jpeg", NULL - }, + {GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline, + "image/jpeg", NULL}, #endif #if VA_CHECK_VERSION(0,35,0) - { GST_VAAPI_PROFILE_VP8, VAProfileVP8Version0_3, - "video/x-vp8", NULL - }, + {GST_VAAPI_PROFILE_VP8, VAProfileVP8Version0_3, + "video/x-vp8", NULL}, #endif #if VA_CHECK_VERSION(0,37,0) - { GST_VAAPI_PROFILE_H265_MAIN, VAProfileHEVCMain, - "video/x-h265", "main" - }, - { GST_VAAPI_PROFILE_H265_MAIN10, VAProfileHEVCMain10, - "video/x-h265", "main-10" - }, + {GST_VAAPI_PROFILE_H265_MAIN, VAProfileHEVCMain, + "video/x-h265", "main"}, + {GST_VAAPI_PROFILE_H265_MAIN10, VAProfileHEVCMain10, + "video/x-h265", "main-10"}, #endif #if VA_CHECK_VERSION(0,38,0) - { GST_VAAPI_PROFILE_VP9, VAProfileVP9Profile0, - "video/x-vp9", NULL - }, + {GST_VAAPI_PROFILE_VP9, VAProfileVP9Profile0, + "video/x-vp9", NULL}, #endif - { 0, } + {0,} }; /* Entry-points */ static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = { - { GST_VAAPI_ENTRYPOINT_VLD, VAEntrypointVLD }, - { GST_VAAPI_ENTRYPOINT_IDCT, VAEntrypointIDCT }, - { GST_VAAPI_ENTRYPOINT_MOCO, VAEntrypointMoComp }, + {GST_VAAPI_ENTRYPOINT_VLD, VAEntrypointVLD}, + {GST_VAAPI_ENTRYPOINT_IDCT, VAEntrypointIDCT}, + {GST_VAAPI_ENTRYPOINT_MOCO, VAEntrypointMoComp}, #if VA_CHECK_VERSION(0,30,0) - { GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, VAEntrypointEncSlice }, - { GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, VAEntrypointEncPicture }, + {GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, VAEntrypointEncSlice}, + {GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, VAEntrypointEncPicture}, #endif - { 0, } + {0,} }; static const GstVaapiCodecMap * -get_codecs_map(GstVaapiCodec codec) +get_codecs_map (GstVaapiCodec codec) { - const GstVaapiCodecMap *m; + const GstVaapiCodecMap *m; - for (m = gst_vaapi_codecs; m->codec; m++) - if (m->codec == codec) - return m; - return NULL; + for (m = gst_vaapi_codecs; m->codec; m++) + if (m->codec == codec) + return m; + return NULL; } static const GstVaapiProfileMap * -get_profiles_map(GstVaapiProfile profile) +get_profiles_map (GstVaapiProfile profile) { - const GstVaapiProfileMap *m; + const GstVaapiProfileMap *m; - for (m = gst_vaapi_profiles; m->profile; m++) - if (m->profile == profile) - return m; - return NULL; + for (m = gst_vaapi_profiles; m->profile; m++) + if (m->profile == profile) + return m; + return NULL; } static const GstVaapiEntrypointMap * -get_entrypoints_map(GstVaapiEntrypoint entrypoint) +get_entrypoints_map (GstVaapiEntrypoint entrypoint) { - const GstVaapiEntrypointMap *m; + const GstVaapiEntrypointMap *m; - for (m = gst_vaapi_entrypoints; m->entrypoint; m++) - if (m->entrypoint == entrypoint) - return m; - return NULL; + for (m = gst_vaapi_entrypoints; m->entrypoint; m++) + if (m->entrypoint == entrypoint) + return m; + return NULL; } /** @@ -211,11 +192,11 @@ get_entrypoints_map(GstVaapiEntrypoint entrypoint) * Return value: the statically allocated string representation of @codec */ const gchar * -gst_vaapi_codec_get_name(GstVaapiCodec codec) +gst_vaapi_codec_get_name (GstVaapiCodec codec) { - const GstVaapiCodecMap * const m = get_codecs_map(codec); + const GstVaapiCodecMap *const m = get_codecs_map (codec); - return m ? m->name : NULL; + return m ? m->name : NULL; } /** @@ -229,14 +210,14 @@ gst_vaapi_codec_get_name(GstVaapiCodec codec) * Return value: the #GstVaapiProfile describing the @profile */ GstVaapiProfile -gst_vaapi_profile(VAProfile profile) +gst_vaapi_profile (VAProfile profile) { - const GstVaapiProfileMap *m; + const GstVaapiProfileMap *m; - for (m = gst_vaapi_profiles; m->profile; m++) - if (m->va_profile == profile) - return m->profile; - return 0; + for (m = gst_vaapi_profiles; m->profile; m++) + if (m->va_profile == profile) + return m->profile; + return 0; } /** @@ -248,11 +229,11 @@ gst_vaapi_profile(VAProfile profile) * Return value: the statically allocated string representation of @profile */ const gchar * -gst_vaapi_profile_get_name(GstVaapiProfile profile) +gst_vaapi_profile_get_name (GstVaapiProfile profile) { - const GstVaapiProfileMap * const m = get_profiles_map(profile); + const GstVaapiProfileMap *const m = get_profiles_map (profile); - return m ? m->profile_str : NULL; + return m ? m->profile_str : NULL; } /** @@ -266,11 +247,11 @@ gst_vaapi_profile_get_name(GstVaapiProfile profile) * @profile media type */ const gchar * -gst_vaapi_profile_get_media_type_name(GstVaapiProfile profile) +gst_vaapi_profile_get_media_type_name (GstVaapiProfile profile) { - const GstVaapiProfileMap * const m = get_profiles_map(profile); + const GstVaapiProfileMap *const m = get_profiles_map (profile); - return m ? m->media_str : NULL; + return m ? m->media_str : NULL; } /** @@ -283,73 +264,81 @@ gst_vaapi_profile_get_media_type_name(GstVaapiProfile profile) * Return value: the #GstVaapiProfile described in @buffer */ static GstVaapiProfile -gst_vaapi_profile_from_codec_data_h264(GstBuffer *buffer) +gst_vaapi_profile_from_codec_data_h264 (GstBuffer * buffer) { - /* MPEG-4 Part 15: Advanced Video Coding (AVC) file format */ - guchar buf[3]; + /* MPEG-4 Part 15: Advanced Video Coding (AVC) file format */ + guchar buf[3]; - if (gst_buffer_extract(buffer, 0, buf, sizeof(buf)) != sizeof(buf)) - return 0; - - if (buf[0] != 1) /* configurationVersion = 1 */ - return 0; - - switch (buf[1]) { /* AVCProfileIndication */ - case 66: return ((buf[2] & 0x40) ? - GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE : - GST_VAAPI_PROFILE_H264_BASELINE); - case 77: return GST_VAAPI_PROFILE_H264_MAIN; - case 100: return GST_VAAPI_PROFILE_H264_HIGH; - case 118: return GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH; - case 128: return GST_VAAPI_PROFILE_H264_STEREO_HIGH; - - } + if (gst_buffer_extract (buffer, 0, buf, sizeof (buf)) != sizeof (buf)) return 0; + + if (buf[0] != 1) /* configurationVersion = 1 */ + return 0; + + switch (buf[1]) { /* AVCProfileIndication */ + case 66: + return ((buf[2] & 0x40) ? + GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE : + GST_VAAPI_PROFILE_H264_BASELINE); + case 77: + return GST_VAAPI_PROFILE_H264_MAIN; + case 100: + return GST_VAAPI_PROFILE_H264_HIGH; + case 118: + return GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH; + case 128: + return GST_VAAPI_PROFILE_H264_STEREO_HIGH; + + } + return 0; } static GstVaapiProfile -gst_vaapi_profile_from_codec_data_h265(GstBuffer *buffer) +gst_vaapi_profile_from_codec_data_h265 (GstBuffer * buffer) { - /* ISO/IEC 14496-15: HEVC file format */ - guchar buf[3]; + /* ISO/IEC 14496-15: HEVC file format */ + guchar buf[3]; - if (gst_buffer_extract(buffer, 0, buf, sizeof(buf)) != sizeof(buf)) - return 0; - - if (buf[0] != 1) /* configurationVersion = 1 */ - return 0; - - if (buf[1] & 0xc0) /* general_profile_space = 0 */ - return 0; - - switch (buf[1] & 0x1f) { /* HEVCProfileIndication */ - case 1: return GST_VAAPI_PROFILE_H265_MAIN; - case 2: return GST_VAAPI_PROFILE_H265_MAIN10; - case 3: return GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; - } + if (gst_buffer_extract (buffer, 0, buf, sizeof (buf)) != sizeof (buf)) return 0; + + if (buf[0] != 1) /* configurationVersion = 1 */ + return 0; + + if (buf[1] & 0xc0) /* general_profile_space = 0 */ + return 0; + + switch (buf[1] & 0x1f) { /* HEVCProfileIndication */ + case 1: + return GST_VAAPI_PROFILE_H265_MAIN; + case 2: + return GST_VAAPI_PROFILE_H265_MAIN10; + case 3: + return GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; + } + return 0; } static GstVaapiProfile -gst_vaapi_profile_from_codec_data(GstVaapiCodec codec, GstBuffer *buffer) +gst_vaapi_profile_from_codec_data (GstVaapiCodec codec, GstBuffer * buffer) { - GstVaapiProfile profile; + GstVaapiProfile profile; - if (!codec || !buffer) - return 0; + if (!codec || !buffer) + return 0; - switch (codec) { + switch (codec) { case GST_VAAPI_CODEC_H264: - profile = gst_vaapi_profile_from_codec_data_h264(buffer); - break; + profile = gst_vaapi_profile_from_codec_data_h264 (buffer); + break; case GST_VAAPI_CODEC_H265: - profile = gst_vaapi_profile_from_codec_data_h265(buffer); - break; + profile = gst_vaapi_profile_from_codec_data_h265 (buffer); + break; default: - profile = 0; - break; - } - return profile; + profile = 0; + break; + } + return profile; } /** @@ -363,62 +352,60 @@ gst_vaapi_profile_from_codec_data(GstVaapiCodec codec, GstBuffer *buffer) * Return value: the #GstVaapiProfile describing the @caps */ GstVaapiProfile -gst_vaapi_profile_from_caps(const GstCaps *caps) +gst_vaapi_profile_from_caps (const GstCaps * caps) { - const GstVaapiProfileMap *m; - GstCaps *caps_test; - GstStructure *structure; - const gchar *profile_str; - GstVaapiProfile profile, best_profile; - GstBuffer *codec_data = NULL; - const gchar *name; - gsize namelen; + const GstVaapiProfileMap *m; + GstCaps *caps_test; + GstStructure *structure; + const gchar *profile_str; + GstVaapiProfile profile, best_profile; + GstBuffer *codec_data = NULL; + const gchar *name; + gsize namelen; - if (!caps) - return 0; + if (!caps) + return 0; - structure = gst_caps_get_structure(caps, 0); - if (!structure) - return 0; + structure = gst_caps_get_structure (caps, 0); + if (!structure) + return 0; - name = gst_structure_get_name(structure); - namelen = strlen(name); + name = gst_structure_get_name (structure); + namelen = strlen (name); - profile_str = gst_structure_get_string(structure, "profile"); - if (!profile_str) { - const GValue *v_codec_data; - v_codec_data = gst_structure_get_value(structure, "codec_data"); - if (v_codec_data) - codec_data = gst_value_get_buffer(v_codec_data); + profile_str = gst_structure_get_string (structure, "profile"); + if (!profile_str) { + const GValue *v_codec_data; + v_codec_data = gst_structure_get_value (structure, "codec_data"); + if (v_codec_data) + codec_data = gst_value_get_buffer (v_codec_data); + } + + profile = 0; + best_profile = 0; + for (m = gst_vaapi_profiles; !profile && m->profile; m++) { + if (strncmp (name, m->media_str, namelen) != 0) + continue; + caps_test = gst_caps_from_string (m->media_str); + if (gst_caps_is_always_compatible (caps, caps_test)) { + best_profile = m->profile; + if (profile_str && m->profile_str && + strcmp (profile_str, m->profile_str) == 0) + profile = best_profile; } - - profile = 0; - best_profile = 0; - for (m = gst_vaapi_profiles; !profile && m->profile; m++) { - if (strncmp(name, m->media_str, namelen) != 0) - continue; - caps_test = gst_caps_from_string(m->media_str); - if (gst_caps_is_always_compatible(caps, caps_test)) { - best_profile = m->profile; - if (profile_str && m->profile_str && - strcmp(profile_str, m->profile_str) == 0) - profile = best_profile; - } - if (!profile) { - profile = gst_vaapi_profile_from_codec_data( - gst_vaapi_profile_get_codec(m->profile), - codec_data - ); - if (!profile && - WORKAROUND_QTDEMUX_NO_H263_PROFILES && - strncmp(name, "video/x-h263", namelen) == 0) { - /* HACK: qtdemux does not report profiles for h263 */ - profile = m->profile; - } - } - gst_caps_unref(caps_test); + if (!profile) { + profile = + gst_vaapi_profile_from_codec_data (gst_vaapi_profile_get_codec + (m->profile), codec_data); + if (!profile && WORKAROUND_QTDEMUX_NO_H263_PROFILES + && strncmp (name, "video/x-h263", namelen) == 0) { + /* HACK: qtdemux does not report profiles for h263 */ + profile = m->profile; + } } - return profile ? profile : best_profile; + gst_caps_unref (caps_test); + } + return profile ? profile : best_profile; } /** @@ -432,11 +419,11 @@ gst_vaapi_profile_from_caps(const GstCaps *caps) * Return value: the VA profile, or -1 if none was found */ VAProfile -gst_vaapi_profile_get_va_profile(GstVaapiProfile profile) +gst_vaapi_profile_get_va_profile (GstVaapiProfile profile) { - const GstVaapiProfileMap * const m = get_profiles_map(profile); + const GstVaapiProfileMap *const m = get_profiles_map (profile); - return m ? m->va_profile : (VAProfile)-1; + return m ? m->va_profile : (VAProfile) - 1; } /** @@ -449,29 +436,25 @@ gst_vaapi_profile_get_va_profile(GstVaapiProfile profile) * Return value: the newly allocated #GstCaps, or %NULL if none was found */ GstCaps * -gst_vaapi_profile_get_caps(GstVaapiProfile profile) +gst_vaapi_profile_get_caps (GstVaapiProfile profile) { - const GstVaapiProfileMap *m; - GstCaps *out_caps, *caps; + const GstVaapiProfileMap *m; + GstCaps *out_caps, *caps; - out_caps = gst_caps_new_empty(); - if (!out_caps) - return NULL; + out_caps = gst_caps_new_empty (); + if (!out_caps) + return NULL; - for (m = gst_vaapi_profiles; m->profile; m++) { - if (m->profile != profile) - continue; - caps = gst_caps_from_string(m->media_str); - if (!caps) - continue; - gst_caps_set_simple( - caps, - "profile", G_TYPE_STRING, m->profile_str, - NULL - ); - out_caps = gst_caps_merge(out_caps, caps); - } - return out_caps; + for (m = gst_vaapi_profiles; m->profile; m++) { + if (m->profile != profile) + continue; + caps = gst_caps_from_string (m->media_str); + if (!caps) + continue; + gst_caps_set_simple (caps, "profile", G_TYPE_STRING, m->profile_str, NULL); + out_caps = gst_caps_merge (out_caps, caps); + } + return out_caps; } /** @@ -483,26 +466,26 @@ gst_vaapi_profile_get_caps(GstVaapiProfile profile) * Return value: the #GstVaapiCodec from @profile */ GstVaapiCodec -gst_vaapi_profile_get_codec(GstVaapiProfile profile) +gst_vaapi_profile_get_codec (GstVaapiProfile profile) { - GstVaapiCodec codec; + GstVaapiCodec codec; - switch (profile) { + switch (profile) { case GST_VAAPI_PROFILE_VC1_SIMPLE: case GST_VAAPI_PROFILE_VC1_MAIN: - codec = GST_VAAPI_CODEC_WMV3; - break; + codec = GST_VAAPI_CODEC_WMV3; + break; case GST_VAAPI_PROFILE_VC1_ADVANCED: - codec = GST_VAAPI_CODEC_VC1; - break; + codec = GST_VAAPI_CODEC_VC1; + break; case GST_VAAPI_PROFILE_JPEG_BASELINE: - codec = GST_VAAPI_CODEC_JPEG; - break; + codec = GST_VAAPI_CODEC_JPEG; + break; default: - codec = (guint32)profile & GST_MAKE_FOURCC(0xff,0xff,0xff,0); - break; - } - return codec; + codec = (guint32) profile & GST_MAKE_FOURCC (0xff, 0xff, 0xff, 0); + break; + } + return codec; } /** @@ -516,14 +499,14 @@ gst_vaapi_profile_get_codec(GstVaapiProfile profile) * Return value: the #GstVaapiEntrypoint describing the @entrypoint */ GstVaapiEntrypoint -gst_vaapi_entrypoint(VAEntrypoint entrypoint) +gst_vaapi_entrypoint (VAEntrypoint entrypoint) { - const GstVaapiEntrypointMap *m; + const GstVaapiEntrypointMap *m; - for (m = gst_vaapi_entrypoints; m->entrypoint; m++) - if (m->va_entrypoint == entrypoint) - return m->entrypoint; - return 0; + for (m = gst_vaapi_entrypoints; m->entrypoint; m++) + if (m->va_entrypoint == entrypoint) + return m->entrypoint; + return 0; } /** @@ -537,9 +520,9 @@ gst_vaapi_entrypoint(VAEntrypoint entrypoint) * Return value: the VA entry-point, or -1 if none was found */ VAEntrypoint -gst_vaapi_entrypoint_get_va_entrypoint(GstVaapiEntrypoint entrypoint) +gst_vaapi_entrypoint_get_va_entrypoint (GstVaapiEntrypoint entrypoint) { - const GstVaapiEntrypointMap * const m = get_entrypoints_map(entrypoint); + const GstVaapiEntrypointMap *const m = get_entrypoints_map (entrypoint); - return m ? m->va_entrypoint : (VAEntrypoint)-1; + return m ? m->va_entrypoint : (VAEntrypoint) - 1; } diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 370ff8716f..021de15d47 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -38,20 +38,21 @@ #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass; +typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass; /** * GstVaapiSubpicture: * * A VA subpicture wrapper */ -struct _GstVaapiSubpicture { - /*< private >*/ - GstVaapiObject parent_instance; +struct _GstVaapiSubpicture +{ + /*< private > */ + GstVaapiObject parent_instance; - GstVaapiImage *image; - guint flags; - gfloat global_alpha; + GstVaapiImage *image; + guint flags; + gfloat global_alpha; }; /** @@ -59,66 +60,62 @@ struct _GstVaapiSubpicture { * * A VA subpicture wrapper class */ -struct _GstVaapiSubpictureClass { - /*< private >*/ - GstVaapiObjectClass parent_class; +struct _GstVaapiSubpictureClass +{ + /*< private > */ + GstVaapiObjectClass parent_class; }; static void -gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture) +gst_vaapi_subpicture_destroy (GstVaapiSubpicture * subpicture) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture); - VASubpictureID subpicture_id; - VAStatus status; + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (subpicture); + VASubpictureID subpicture_id; + VAStatus status; - subpicture_id = GST_VAAPI_OBJECT_ID(subpicture); - GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(subpicture_id)); + subpicture_id = GST_VAAPI_OBJECT_ID (subpicture); + GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (subpicture_id)); - if (subpicture_id != VA_INVALID_ID) { - if (display) { - GST_VAAPI_DISPLAY_LOCK(display); - status = vaDestroySubpicture( - GST_VAAPI_DISPLAY_VADISPLAY(display), - subpicture_id - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaDestroySubpicture()")) - g_warning("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(subpicture_id)); - } - GST_VAAPI_OBJECT_ID(subpicture) = VA_INVALID_ID; + if (subpicture_id != VA_INVALID_ID) { + if (display) { + GST_VAAPI_DISPLAY_LOCK (display); + status = vaDestroySubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), + subpicture_id); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaDestroySubpicture()")) + g_warning ("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (subpicture_id)); } - gst_vaapi_object_replace(&subpicture->image, NULL); + GST_VAAPI_OBJECT_ID (subpicture) = VA_INVALID_ID; + } + gst_vaapi_object_replace (&subpicture->image, NULL); } static gboolean -gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture, - GstVaapiImage *image) +gst_vaapi_subpicture_create (GstVaapiSubpicture * subpicture, + GstVaapiImage * image) { - GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture); - VASubpictureID subpicture_id; - VAStatus status; + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (subpicture); + VASubpictureID subpicture_id; + VAStatus status; - GST_VAAPI_DISPLAY_LOCK(display); - status = vaCreateSubpicture( - GST_VAAPI_DISPLAY_VADISPLAY(display), - GST_VAAPI_OBJECT_ID(image), - &subpicture_id - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaCreateSubpicture()")) - return FALSE; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaCreateSubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_OBJECT_ID (image), &subpicture_id); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaCreateSubpicture()")) + return FALSE; - GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(subpicture_id)); - GST_VAAPI_OBJECT_ID(subpicture) = subpicture_id; - subpicture->image = gst_vaapi_object_ref(image); - return TRUE; + GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (subpicture_id)); + GST_VAAPI_OBJECT_ID (subpicture) = subpicture_id; + subpicture->image = gst_vaapi_object_ref (image); + return TRUE; } #define gst_vaapi_subpicture_finalize gst_vaapi_subpicture_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiSubpicture, gst_vaapi_subpicture) +GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture) /** * gst_vaapi_subpicture_new: @@ -130,38 +127,38 @@ GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiSubpicture, gst_vaapi_subpicture) * * Return value: the newly allocated #GstVaapiSubpicture object */ -GstVaapiSubpicture * -gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags) + GstVaapiSubpicture *gst_vaapi_subpicture_new (GstVaapiImage * image, + guint flags) { - GstVaapiSubpicture *subpicture; - GstVaapiDisplay *display; - GstVideoFormat format; - guint va_flags; + GstVaapiSubpicture *subpicture; + GstVaapiDisplay *display; + GstVideoFormat format; + guint va_flags; - g_return_val_if_fail(image != NULL, NULL); + g_return_val_if_fail (image != NULL, NULL); - GST_DEBUG("create from image %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(image))); + GST_DEBUG ("create from image %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (image))); - display = GST_VAAPI_OBJECT_DISPLAY(image); - format = GST_VAAPI_IMAGE_FORMAT(image); - if (!gst_vaapi_display_has_subpicture_format(display, format, &va_flags)) - return NULL; - if (flags & ~va_flags) - return NULL; + display = GST_VAAPI_OBJECT_DISPLAY (image); + format = GST_VAAPI_IMAGE_FORMAT (image); + if (!gst_vaapi_display_has_subpicture_format (display, format, &va_flags)) + return NULL; + if (flags & ~va_flags) + return NULL; - subpicture = gst_vaapi_object_new(gst_vaapi_subpicture_class(), display); - if (!subpicture) - return NULL; + subpicture = gst_vaapi_object_new (gst_vaapi_subpicture_class (), display); + if (!subpicture) + return NULL; - subpicture->global_alpha = 1.0f; - if (!gst_vaapi_subpicture_set_image(subpicture, image)) - goto error; - return subpicture; + subpicture->global_alpha = 1.0f; + if (!gst_vaapi_subpicture_set_image (subpicture, image)) + goto error; + return subpicture; error: - gst_vaapi_object_unref(subpicture); - return NULL; + gst_vaapi_object_unref (subpicture); + return NULL; } /** @@ -177,80 +174,80 @@ error: * Return value: the newly allocated #GstVaapiSubpicture object */ GstVaapiSubpicture * -gst_vaapi_subpicture_new_from_overlay_rectangle( - GstVaapiDisplay *display, - GstVideoOverlayRectangle *rect -) +gst_vaapi_subpicture_new_from_overlay_rectangle (GstVaapiDisplay * display, + GstVideoOverlayRectangle * rect) { - GstVaapiSubpicture *subpicture; - GstVideoFormat format; - GstVaapiImage *image; - GstVaapiImageRaw raw_image; - GstBuffer *buffer; - guint8 *data; - gfloat global_alpha; - guint width, height, stride; - guint hw_flags, flags; - GstVideoMeta *vmeta; - GstMapInfo map_info; + GstVaapiSubpicture *subpicture; + GstVideoFormat format; + GstVaapiImage *image; + GstVaapiImageRaw raw_image; + GstBuffer *buffer; + guint8 *data; + gfloat global_alpha; + guint width, height, stride; + guint hw_flags, flags; + GstVideoMeta *vmeta; + GstMapInfo map_info; - g_return_val_if_fail(GST_IS_VIDEO_OVERLAY_RECTANGLE(rect), NULL); + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rect), NULL); - /* XXX: use gst_vaapi_image_format_from_video() */ + /* XXX: use gst_vaapi_image_format_from_video() */ #if G_BYTE_ORDER == G_LITTLE_ENDIAN - format = GST_VIDEO_FORMAT_BGRA; + format = GST_VIDEO_FORMAT_BGRA; #else - format = GST_VIDEO_FORMAT_ARGB; + format = GST_VIDEO_FORMAT_ARGB; #endif - if (!gst_vaapi_display_has_subpicture_format(display, format, &hw_flags)) - return NULL; + if (!gst_vaapi_display_has_subpicture_format (display, format, &hw_flags)) + return NULL; - flags = hw_flags & from_GstVideoOverlayFormatFlags( - gst_video_overlay_rectangle_get_flags(rect)); + flags = + hw_flags & + from_GstVideoOverlayFormatFlags (gst_video_overlay_rectangle_get_flags + (rect)); - buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect, - to_GstVideoOverlayFormatFlags(flags)); - if (!buffer) - return NULL; + buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rect, + to_GstVideoOverlayFormatFlags (flags)); + if (!buffer) + return NULL; - vmeta = gst_buffer_get_video_meta(buffer); - if (!vmeta) - return NULL; - width = vmeta->width; - height = vmeta->height; + vmeta = gst_buffer_get_video_meta (buffer); + if (!vmeta) + return NULL; + width = vmeta->width; + height = vmeta->height; - if (!gst_video_meta_map(vmeta, 0, &map_info, (gpointer *)&data, - (gint *)&stride, GST_MAP_READ)) - return NULL; + if (!gst_video_meta_map (vmeta, 0, &map_info, (gpointer *) & data, + (gint *) & stride, GST_MAP_READ)) + return NULL; - image = gst_vaapi_image_new(display, format, width, height); - if (!image) - return NULL; + image = gst_vaapi_image_new (display, format, width, height); + if (!image) + return NULL; - raw_image.format = format; - raw_image.width = width; - raw_image.height = height; - raw_image.num_planes = 1; - raw_image.pixels[0] = data; - raw_image.stride[0] = stride; - if (!gst_vaapi_image_update_from_raw(image, &raw_image, NULL)) { - GST_WARNING("could not update VA image with subtitle data"); - gst_vaapi_object_unref(image); - return NULL; - } + raw_image.format = format; + raw_image.width = width; + raw_image.height = height; + raw_image.num_planes = 1; + raw_image.pixels[0] = data; + raw_image.stride[0] = stride; + if (!gst_vaapi_image_update_from_raw (image, &raw_image, NULL)) { + GST_WARNING ("could not update VA image with subtitle data"); + gst_vaapi_object_unref (image); + return NULL; + } - subpicture = gst_vaapi_subpicture_new(image, flags); - gst_vaapi_object_unref(image); - gst_video_meta_unmap(vmeta, 0, &map_info); - if (!subpicture) - return NULL; + subpicture = gst_vaapi_subpicture_new (image, flags); + gst_vaapi_object_unref (image); + gst_video_meta_unmap (vmeta, 0, &map_info); + if (!subpicture) + return NULL; - if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) { - global_alpha = gst_video_overlay_rectangle_get_global_alpha(rect); - if (!gst_vaapi_subpicture_set_global_alpha(subpicture, global_alpha)) - return NULL; - } - return subpicture; + if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA) { + global_alpha = gst_video_overlay_rectangle_get_global_alpha (rect); + if (!gst_vaapi_subpicture_set_global_alpha (subpicture, global_alpha)) + return NULL; + } + return subpicture; } /** @@ -262,11 +259,11 @@ gst_vaapi_subpicture_new_from_overlay_rectangle( * Return value: the underlying VA subpicture id */ GstVaapiID -gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture) +gst_vaapi_subpicture_get_id (GstVaapiSubpicture * subpicture) { - g_return_val_if_fail(subpicture != NULL, VA_INVALID_ID); + g_return_val_if_fail (subpicture != NULL, VA_INVALID_ID); - return GST_VAAPI_OBJECT_ID(subpicture); + return GST_VAAPI_OBJECT_ID (subpicture); } /** @@ -278,11 +275,11 @@ gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture) * Return value: the @subpicture flags */ guint -gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture) +gst_vaapi_subpicture_get_flags (GstVaapiSubpicture * subpicture) { - g_return_val_if_fail(subpicture != NULL, 0); + g_return_val_if_fail (subpicture != NULL, 0); - return subpicture->flags; + return subpicture->flags; } /** @@ -294,11 +291,11 @@ gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture) * Return value: the #GstVaapiImage this @subpicture is bound to */ GstVaapiImage * -gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture) +gst_vaapi_subpicture_get_image (GstVaapiSubpicture * subpicture) { - g_return_val_if_fail(subpicture != NULL, NULL); + g_return_val_if_fail (subpicture != NULL, NULL); - return subpicture->image; + return subpicture->image; } /** @@ -312,14 +309,14 @@ gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture) * Return value: %TRUE on success */ gboolean -gst_vaapi_subpicture_set_image(GstVaapiSubpicture *subpicture, - GstVaapiImage *image) +gst_vaapi_subpicture_set_image (GstVaapiSubpicture * subpicture, + GstVaapiImage * image) { - g_return_val_if_fail(subpicture != NULL, FALSE); - g_return_val_if_fail(image != NULL, FALSE); + g_return_val_if_fail (subpicture != NULL, FALSE); + g_return_val_if_fail (image != NULL, FALSE); - gst_vaapi_subpicture_destroy(subpicture); - return gst_vaapi_subpicture_create(subpicture, image); + gst_vaapi_subpicture_destroy (subpicture); + return gst_vaapi_subpicture_create (subpicture, image); } /** @@ -331,11 +328,11 @@ gst_vaapi_subpicture_set_image(GstVaapiSubpicture *subpicture, * Return value: the global_alpha value of this @subpicture */ gfloat -gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture) +gst_vaapi_subpicture_get_global_alpha (GstVaapiSubpicture * subpicture) { - g_return_val_if_fail(subpicture != NULL, 1.0); + g_return_val_if_fail (subpicture != NULL, 1.0); - return subpicture->global_alpha; + return subpicture->global_alpha; } /** @@ -350,32 +347,29 @@ gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture) * Return value: %TRUE if global_alpha could be set, %FALSE otherwise */ gboolean -gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture, +gst_vaapi_subpicture_set_global_alpha (GstVaapiSubpicture * subpicture, gfloat global_alpha) { - GstVaapiDisplay *display; - VAStatus status; + GstVaapiDisplay *display; + VAStatus status; - g_return_val_if_fail(subpicture != NULL, FALSE); + g_return_val_if_fail (subpicture != NULL, FALSE); - if (!(subpicture->flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA)) - return FALSE; + if (!(subpicture->flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA)) + return FALSE; - if (subpicture->global_alpha == global_alpha) - return TRUE; - - display = GST_VAAPI_OBJECT_DISPLAY(subpicture); - - GST_VAAPI_DISPLAY_LOCK(display); - status = vaSetSubpictureGlobalAlpha( - GST_VAAPI_DISPLAY_VADISPLAY(display), - GST_VAAPI_OBJECT_ID(subpicture), - global_alpha - ); - GST_VAAPI_DISPLAY_UNLOCK(display); - if (!vaapi_check_status(status, "vaSetSubpictureGlobalAlpha()")) - return FALSE; - - subpicture->global_alpha = global_alpha; + if (subpicture->global_alpha == global_alpha) return TRUE; + + display = GST_VAAPI_OBJECT_DISPLAY (subpicture); + + GST_VAAPI_DISPLAY_LOCK (display); + status = vaSetSubpictureGlobalAlpha (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_OBJECT_ID (subpicture), global_alpha); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaSetSubpictureGlobalAlpha()")) + return FALSE; + + subpicture->global_alpha = global_alpha; + return TRUE; } From 81b7776451332012160d71fed437ee3718cbaaf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Jan 2016 13:28:30 +0100 Subject: [PATCH 2265/3781] add doap descriptor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DOAP (Description of a Project) is an RDF Schema and XML vocabulary to describe software projects, in particular free and open source software. The description is used in GStreamer as in many other open source projects. This patch adds the doap description of this project. Signed-off-by: Víctor Manuel Jáquez Leal --- gstreamer-vaapi.doap | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 gstreamer-vaapi.doap diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap new file mode 100644 index 0000000000..eb2f42d075 --- /dev/null +++ b/gstreamer-vaapi.doap @@ -0,0 +1,39 @@ + + + GStreamer VA-API + gstreamer-vaapi + a set of VA-API based elements for GStreamer + + GStreamer VA-API is a collection of VA-API based plugin with video + processing elements for GStreamer. + + + + + C + + + + + + + + + + + + Sreerenj Balachandran + + + + + Victor Jaquez + + > + + From 8defb2436cdc582011eae3c38d53e485235b597f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 25 Jan 2016 16:06:03 +0100 Subject: [PATCH 2266/3781] add gst-common submodule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pointing to branch 1.6 Signed-off-by: Víctor Manuel Jáquez Leal --- .gitmodules | 3 +++ common | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 common diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..a6b1edac4c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "common"] + path = common + url = git://anongit.freedesktop.org/gstreamer/common diff --git a/common b/common new file mode 160000 index 0000000000..66235917b4 --- /dev/null +++ b/common @@ -0,0 +1 @@ +Subproject commit 66235917b47e6f933f8bd32376662a54f17eb609 From 495206334758ed260b2ab9fba8ace9b0de0881f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Jan 2016 19:35:24 +0100 Subject: [PATCH 2267/3781] use gst-common submodule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is 'the' big change in gstreamer-vaapi autoconf. Now it uses the official GStreamer common submodule. The documentation generation has been disable temporarily since it needs a major rework, which will be done in the following commit. Signed-off-by: Víctor Manuel Jáquez Leal --- ChangeLog | 1 + Makefile.am | 8 +- autogen.sh | 141 +++++++++++++++++++------- configure.ac | 272 +++++++++++++++++++++++++++++++++++---------------- 4 files changed, 300 insertions(+), 122 deletions(-) create mode 100644 ChangeLog diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000000..30c993fb95 --- /dev/null +++ b/ChangeLog @@ -0,0 +1 @@ +EMPTY FILE diff --git a/Makefile.am b/Makefile.am index 1f2bcdb440..fad0a41c63 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,15 +1,15 @@ -ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} +ACLOCAL_AMFLAGS = -I m4 -I common/m4 ${ACLOCAL_FLAGS} -AUTOMAKE_OPTIONS = foreign +SUBDIRS = gst-libs gst tests common -SUBDIRS = gst-libs gst tests docs +DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ $(GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL) \ $(GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN) \ $(GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL) \ - $(srcdir)/gtk-doc.make $(srcdir)/m4/gtk-doc.m4 \ + $(srcdir)/autoregen.sh $(srcdir)/INSTALL \ $(NULL) -include $(top_srcdir)/git.mk diff --git a/autogen.sh b/autogen.sh index 245970a49a..d88efbb27f 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,55 +1,124 @@ #!/bin/sh +# +# gstreamer-vaapi autogen.sh +# +# Run this to generate all the initial makefiles, etc. +# +# This file has been generated from common/autogen.sh.in via common/update-autogen -PROJECT="gstreamer-vaapi" -test -n "$srcdir" || srcdir="`dirname \"$0\"`" +test -n "$srcdir" || srcdir=`dirname "$0"` test -n "$srcdir" || srcdir=. -if ! test -f "$srcdir/configure.ac"; then - echo "Failed to find the top-level $PROJECT directory" - exit 1 -fi - -olddir="`pwd`" +olddir=`pwd` cd "$srcdir" -mkdir -p m4 +package=gstreamer-vaapi +srcfile=gstreamer-vaapi.doap -GIT=`which git` -if test -z "$GIT"; then - echo "*** No git found ***" - exit 1 -else - submodule_init="no" - for ext_module in codecparsers; do - if test ! -f ext/${ext_module}/autogen.sh; then - submodule_init="yes" - fi - done - if test "$submodule_init" = "yes"; then - $GIT submodule init +# Make sure we have common +if test ! -f common/gst-autogen.sh; +then + echo "+ Setting up common submodule" + git submodule init +fi +git submodule update + +# source helper functions +if test ! -f common/gst-autogen.sh; +then + echo There is something wrong with your source tree. + echo You are missing common/gst-autogen.sh + exit 1 +fi +. common/gst-autogen.sh + +# install pre-commit hook for doing clean commits +if test ! \( -x .git/hooks/pre-commit -a -L .git/hooks/pre-commit \); +then + rm -f .git/hooks/pre-commit + if ! ln -s ../../common/hooks/pre-commit.hook .git/hooks/pre-commit 2> /dev/null + then + echo "Failed to create commit hook symlink, copying instead ..." + cp common/hooks/pre-commit.hook .git/hooks/pre-commit fi - $GIT submodule update fi -GTKDOCIZE=`which gtkdocize` -if test -z "$GTKDOCIZE"; then - echo "*** No gtk-doc support ***" - echo "EXTRA_DIST =" > gtk-doc.make -else - gtkdocize || exit $? +# GNU gettext automake support doesn't get along with git. +# https://bugzilla.gnome.org/show_bug.cgi?id=661128 +if test -d po ; then + touch -t 200001010000 po/gstreamer-vaapi-1.0.pot fi -AUTORECONF=`which autoreconf` -if test -z "$AUTORECONF"; then - echo "*** No autoreconf found ***" +CONFIGURE_DEF_OPT='--enable-maintainer-mode --enable-gtk-doc' + +if test "x$package" = "xgstreamer"; then + CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --enable-docbook --enable-failing-tests --enable-poisoning" +elif test "x$package" = "xgst-plugins-bad"; then + CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-player-tests" +fi + +autogen_options $@ + +printf "+ check for build tools" +if test -z "$NOCHECK"; then + echo + + printf " checking for autoreconf ... " + echo + which "autoreconf" 2>/dev/null || { + echo "not found! Please install the autoconf package." exit 1 + } + + printf " checking for pkg-config ... " + echo + which "pkg-config" 2>/dev/null || { + echo "not found! Please install pkg-config." + exit 1 + } else - autoreconf -v --install || exit $? + echo ": skipped version checks" fi +# if no arguments specified then this will be printed +if test -z "$*" && test -z "$NOCONFIGURE"; then + echo "+ checking for autogen.sh options" + echo " This autogen script will automatically run ./configure as:" + echo " ./configure $CONFIGURE_DEF_OPT" + echo " To pass any additional options, please specify them on the $0" + echo " command line." +fi + +toplevel_check $srcfile + +# autopoint +if test -d po && grep ^AM_GNU_GETTEXT_VERSION configure.ac >/dev/null ; then + tool_run "autopoint" "--force" +fi + +# aclocal +if test -f acinclude.m4; then rm acinclude.m4; fi + +autoreconf --force --install || exit 1 + +test -n "$NOCONFIGURE" && { + echo "+ skipping configure stage for package $package, as requested." + echo "+ autogen.sh done." + exit 0 +} + cd "$olddir" -if test -z "$NO_CONFIGURE"; then - $srcdir/configure "$@" && echo "Now type 'make' to compile $PROJECT." -fi +echo "+ running configure ... " +test ! -z "$CONFIGURE_DEF_OPT" && echo " default flags: $CONFIGURE_DEF_OPT" +test ! -z "$CONFIGURE_EXT_OPT" && echo " external flags: $CONFIGURE_EXT_OPT" +echo + +echo "$srcdir/configure" $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT +"$srcdir/configure" $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT || { + echo " configure failed" + exit 1 +} + +echo "Now type 'make' to compile $package." diff --git a/configure.ac b/configure.ac index 8689f0a59f..299d7523e3 100644 --- a/configure.ac +++ b/configure.ac @@ -2,16 +2,19 @@ m4_define([gst_vaapi_major_version], [0]) m4_define([gst_vaapi_minor_version], [7]) m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_pre_version], [1]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) -m4_if(gst_vaapi_pre_version, [0], [], [ -m4_append([gst_vaapi_version], gst_vaapi_pre_version, [.pre]) -]) +m4_if(gst_vaapi_nano_version, [0], [], + [m4_append([gst_vaapi_version], gst_vaapi_nano_version, [.])]) # Configure defaults m4_define([default_glapi], [any]) +dnl - library source changed -> increment REVISION +dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 +dnl - interfaces added -> increment AGE +dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number m4_define([gst_vaapi_lt_current], [7]) m4_define([gst_vaapi_lt_revision], [0]) @@ -44,25 +47,41 @@ AC_INIT([GStreamer VA-API Plug-ins], [gst_vaapi_version], [http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer], [gstreamer-vaapi]) +dnl define the output header for config AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([build-aux]) -AC_CANONICAL_TARGET +AG_GST_INIT +dnl initialize automake AM_INIT_AUTOMAKE([-Wno-portability 1.14 no-dist-gzip dist-xz tar-ustar subdir-objects]) -dnl Use pretty build output +dnl define PACKAGE_VERSION_* variables +AS_VERSION + +dnl check if this is a release version +AS_NANO(GST_GIT="no", GST_GIT="yes") + +dnl AM_MAINTAINER_MODE only provides the option to configure to enable it +AM_MAINTAINER_MODE([enable]) + +dnl use pretty build output by default AM_SILENT_RULES([yes]) -dnl Check for tools -AC_PROG_CC -AM_PROG_CC_C_O +dnl our libraries and install dirs use GST_API_VERSION in the filename +dnl to allow side-by-side installation of different API versions +GST_API_VERSION=1.0 +AC_SUBST([GST_API_VERSION]) +AC_DEFINE_UNQUOTED([GST_API_VERSION], ["$GST_API_VERSION"], + [GStreamer API Version]) -AC_ARG_VAR([GIT], [Path to git program, if any]) -AC_PATH_PROG([GIT], [git]) -AM_CONDITIONAL([HAVE_GIT], [test -n "$GIT"]) +AG_GST_LIBTOOL_PREPARE + +dnl CURRENT, REVISION, AGE +dnl sets GST_LT_LDFLAGS +AS_LIBTOOL(GST, gst_vaapi_lt_current, gst_vaapi_lt_revision, gst_vaapi_lt_age) dnl *** required versions of GStreamer stuff *** GLIB_REQ=glib_version @@ -79,9 +98,20 @@ VAAPI_DRM_REQ=va_api_drm_version VAAPI_X11_REQ=va_api_x11_version VAAPI_WLD_REQ=va_api_wld_version -dnl Initialize libtool -LT_PREREQ([2.2.6]) -LT_INIT +dnl *** autotools stuff **** + +dnl allow for different autotools +AS_AUTOTOOLS_ALTERNATE + +dnl Add parameters for aclocal +AC_SUBST([ACLOCAL_AMFLAGS], ["-I m4 -I common/m4"]) + +dnl *** check for arguments to configure *** + +AG_GST_ARG_DISABLE_FATAL_WARNINGS +AG_GST_ARG_DEBUG + +AG_GST_ARG_WITH_PKG_CONFIG_PATH AC_ARG_ENABLE([encoders], AS_HELP_STRING([--enable-encoders], @@ -118,65 +148,99 @@ AC_ARG_WITH([glapi], [build with the specified OpenGL APIs @<:@default=default_glapi@:>@]), [GLAPI="$with_glapi"], [GLAPI=default_glapi]) -dnl Check for basic libraries +dnl *** checks for platform *** + +dnl * hardware/architecture * + +dnl check CPU type +AG_GST_ARCH + +dnl *** checks for programs *** + +dnl find a compiler +AC_PROG_CC +AC_PROG_CC_STDC + +dnl check if the compiler supports '-c' and '-o' options +AM_PROG_CC_C_O + +dnl check for git command for version generation in libgstvaapi +AC_PATH_PROG([GIT], [git]) +AM_CONDITIONAL([HAVE_GIT], [test -n "$GIT"]) + +dnl check for documentation tools +GTK_DOC_CHECK([$GTKDOC_REQ]) +AG_GST_PLUGIN_DOCS([$GTKDOC_REQ]) + +dnl *** checks for libraries *** +dnl check for libm, for sin() etc. AC_CHECK_LIB([m], [tan]) -dnl Check for Gtk doc -# gtkdocize greps for '^GTK_DOC_CHECK', so it needs to be on its own line -m4_ifdef([GTK_DOC_CHECK], [ -GTK_DOC_CHECK([$GTKDOC_REQ], [--flavour no-tmpl])], [ -AM_CONDITIONAL([ENABLE_GTK_DOC], [false])]) - -dnl Check for GLib -PKG_CHECK_MODULES([GLIB], [glib-2.0 >= $GLIB_REQ]) - dnl Check to see if dlopen is in default libraries (like Solaris, which dnl has it in libc), or if libdl is needed to get it. AC_CHECK_FUNC([dlopen], [], [ AC_CHECK_LIB([dl], [dlopen], [DLOPEN_LIBS="-ldl"])]) AC_SUBST([DLOPEN_LIBS]) +dnl define LIBDIR so we can inform people where we live +AS_AC_EXPAND([LIBDIR], [$libdir]) +AC_DEFINE_UNQUOTED([LIBDIR], ["$LIBDIR"], [library dir]) + +dnl set location of plugin directory +AG_GST_SET_PLUGINDIR + +dnl *** checks for header files *** + +dnl *** checks for types/defines *** + +dnl *** checks for structures *** + +dnl *** checks for compiler characteristics *** + +dnl *** checks for library functions *** + +dnl *** checks for headers *** + +dnl *** checks for dependency libraries *** + dnl --------------------------------------------------------------------------- dnl -- GStreamer -- dnl --------------------------------------------------------------------------- -GST_PKG_VERSION="1.0" -AC_SUBST([GST_PKG_VERSION]) -AC_DEFINE_UNQUOTED([GST_PKG_VERSION_S], ["$GST_PKG_VERSION"], - [Defined to the string representation of GStreamer API version]) +dnl GLib is required +AG_GST_GLIB_CHECK([$GLIB_REQ]) -dnl GStreamer Core -PKG_CHECK_MODULES([GST], [gstreamer-$GST_PKG_VERSION >= $GST_REQ]) +dnl checks for gstreamer +dnl uninstalled is selected preferentially -- see pkg-config(1) +AG_GST_CHECK_GST([$GST_API_VERSION], [$GST_REQ], [yes]) +dnl back compatibility AC_MSG_CHECKING([for GStreamer API version]) -gst_api_version=`$PKG_CONFIG --modversion "gstreamer-$GST_PKG_VERSION"` +gst_api_version=`$PKG_CONFIG --modversion "gstreamer-$GST_API_VERSION"` gst_major_version=`echo "$gst_api_version" | cut -d'.' -f1` gst_minor_version=`echo "$gst_api_version" | cut -d'.' -f2` -GST_API_VERSION="${gst_major_version}.${gst_minor_version}" -AC_MSG_RESULT([$GST_API_VERSION]) -AC_DEFINE_UNQUOTED([GST_API_VERSION_S], ["$GST_API_VERSION"], +GST_VERSION="${gst_major_version}.${gst_minor_version}" +AC_MSG_RESULT([$GST_VERSION]) +AC_DEFINE_UNQUOTED([GST_API_VERSION_S], ["$GST_VERSION"], [Defined to the string representation of GStreamer version]) -PKG_CHECK_MODULES([GST_BASE], [gstreamer-base-$GST_PKG_VERSION >= $GST_REQ]) +AG_GST_CHECK_GST_BASE([$GST_API_VERSION], [$GST_REQ], [yes]) +AG_GST_CHECK_GST_PLUGINS_BASE([$GST_API_VERSION], [$GST_PBREQ], [yes]) -dnl GStreamer -base plugins -PKG_CHECK_MODULES([GST_PLUGINS_BASE], - [gstreamer-plugins-base-$GST_PKG_VERSION >= $GST_PBREQ]) +dnl gst_dmabuf_memory_get_fd (gstreamer-allocators) +AG_GST_CHECK_MODULES([GST_ALLOCATORS], + [gstreamer-allocators-$GST_API_VERSION], [$GST_PBREQ], [yes]) -dnl ... gst_dmabuf_memory_get_fd (gstreamer-allocators) -PKG_CHECK_MODULES([GST_ALLOCATORS], - [gstreamer-allocators-$GST_PKG_VERSION >= $GST_PBREQ]) - -dnl ... GstVideoOverlayComposition (gstreamer-video) -PKG_CHECK_MODULES([GST_VIDEO], - [gstreamer-video-$GST_PKG_VERSION >= $GST_PBREQ]) +dnl GstVideoOverlayComposition (gstreamer-video) +AG_GST_CHECK_MODULES([GST_VIDEO], + [gstreamer-video-$GST_API_VERSION], [$GST_PBREQ], [yes]) dnl ... GStreamer base utils (gstreamer-pbutils) -PKG_CHECK_MODULES([GST_PBUTILS], - [gstreamer-pbutils-$GST_PKG_VERSION >= $GST_PBREQ]) +AG_GST_CHECK_MODULES([GST_PBUTILS], + [gstreamer-pbutils-$GST_API_VERSION], [$GST_PBREQ], [yes]) -dnl ... bitstream parsers -PKG_CHECK_MODULES([GST_CODEC_PARSERS], - [gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PBADREQ]) +dnl bitstream parsers (gstreamer-codecparsers) +AG_GST_CHECK_MODULES([GST_CODEC_PARSERS], + [gstreamer-codecparsers-$GST_API_VERSION], [$GST_PBADREQ], [yes]) dnl ... VP9 parser, with required extensions HAVE_GST_VP9_PARSER=0 @@ -211,7 +275,7 @@ dnl ... opengl helper libraries HAVE_GSTGL=0 if test "x$enable_opengl" = "xyes"; then PKG_CHECK_MODULES([GST_GL], - [gstreamer-gl-$GST_PKG_VERSION >= $GST_PBADREQ], + [gstreamer-gl-$GST_API_VERSION >= $GST_PBADREQ], [ HAVE_GSTGL=1 AC_CACHE_CHECK([for GStreamer OpenGL helper libraries], @@ -249,34 +313,6 @@ if test "x$enable_egl" = "xyes" -a $HAVE_GSTGL -ne 1; then enable_egl="no" fi -dnl GST_ALL_LDFLAGS: -dnl LDFLAGS really should only contain flags, not libs - they get added before -dnl whatevertarget_LIBS and -L flags here affect the rest of the linking -GST_ALL_LDFLAGS="-no-undefined" -AC_SUBST([GST_ALL_LDFLAGS]) - -dnl GST_PLUGIN_LDFLAGS: -dnl this really should only contain flags, not libs - they get added before -dnl whatevertarget_LIBS and -L flags here affect the rest of the linking -GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^([_]*gst_plugin_desc|gst_.*_get_type)\$\$' $GST_ALL_LDFLAGS" -AC_SUBST([GST_PLUGIN_LDFLAGS]) - -dnl Check for the GStreamer plugins directory -AC_ARG_VAR([GST_PLUGIN_PATH_1_0], - [installation path for gstreamer-vaapi plugin elements for GStreamer 1.0]) -AC_MSG_CHECKING([for GStreamer plugins directory]) -if test -n "$GST_PLUGIN_PATH_1_0"; then - GST_PLUGINS_DIR="$GST_PLUGIN_PATH_1_0" -else - GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-$GST_PKG_VERSION --variable pluginsdir` - if test -z "$GST_PLUGINS_DIR"; then - GST_PLUGINS_DIR="\$(libdir)/gstreamer-$GST_PKG_VERSION" - fi -fi -AC_MSG_RESULT([$GST_PLUGINS_DIR]) -plugindir="$GST_PLUGINS_DIR" -AC_SUBST([plugindir]) - dnl --------------------------------------------------------------------------- dnl -- Renderers -- dnl --------------------------------------------------------------------------- @@ -820,6 +856,77 @@ if test $USE_WAYLAND -eq 1; then [], [USE_WAYLAND=0]) fi +dnl *** finalize CFLAGS, LDFLAGS, LIBS + +# set by AG_GST_PARSE_SUBSYSTEM_DISABLES above +dnl make sure it doesn't complain about unused variables if debugging is disabled +NO_WARNINGS="" +AG_GST_CHECK_GST_DEBUG_DISABLED([NO_WARNINGS="-Wno-unused"], [ + -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls + -Wwrite-strings -Wformat-security -Wold-style-definition + -Winit-self -Wmissing-include-dirs -Waddress -Wno-multichar + -Wnested-externs $NO_WARNINGS]) + +dnl define an ERROR_CFLAGS Makefile variable +AG_GST_SET_ERROR_CFLAGS([$FATAL_WARNINGS], [$NO_WARNINGS]) + +dnl define correct level for debugging messages +AG_GST_SET_LEVEL_DEFAULT([$GST_GIT]) + +dnl Overview: +dnl GST_OPTION_CFLAGS: common flags for profiling, debugging, errors, ... +dnl GST_*: flags shared by built objects to link against GStreamer +dnl GST_ALL_LDFLAGS: linker flags shared by all +dnl GST_LIB_LDFLAGS: additional linker flags for all libaries +dnl GST_LT_LDFLAGS: library versioning of our libraries +dnl GST_PLUGIN_LDFLAGS: flags to be used for all plugins + +dnl GST_OPTION_CFLAGS +if test "x$USE_DEBUG" = xyes; then + PROFILE_CFLAGS="-g" +fi +AC_SUBST([PROFILE_CFLAGS]) + +if test "x$GST_GIT" = "xyes"; then + DEPRECATED_CFLAGS="-DGST_DISABLE_DEPRECATED" +else + DEPRECATED_CFLAGS="" +fi +AC_SUBST([DEPRECATED_CFLAGS]) + +dnl every flag in GST_OPTION_CFLAGS and GST_OPTION_CXXFLAGS can be overridden +dnl at make time with e.g. make ERROR_CFLAGS="" +GST_OPTION_CFLAGS="\$(WARNING_CFLAGS) \$(ERROR_CFLAGS) \$(DEBUG_CFLAGS) \$(PROFILE_CFLAGS) \$(DEPRECATED_CFLAGS)" +AC_SUBST([GST_OPTION_CFLAGS]) + +dnl FIXME: do we want to rename to GST_ALL_* ? +dnl prefer internal headers to already installed ones +dnl also add builddir include for enumtypes and marshal +dnl add GST_OPTION_CFLAGS, but overridable +GST_CFLAGS="$GST_CFLAGS -DGST_USE_UNSTABLE_API" +GST_CFLAGS="$GST_CFLAGS $GLIB_EXTRA_CFLAGS \$(GST_OPTION_CFLAGS)" +AC_SUBST([GST_CFLAGS]) + +dnl LDFLAGS really should only contain flags, not libs - they get added before +dnl whatevertarget_LIBS and -L flags here affect the rest of the linking +GST_ALL_LDFLAGS="-no-undefined" +if test "x${enable_Bsymbolic}" = "xyes"; then + GST_ALL_LDFLAGS="$GST_ALL_LDFLAGS -Wl,-Bsymbolic-functions" +fi +AC_SUBST([GST_ALL_LDFLAGS]) + +dnl GST_LIB_LDFLAGS +dnl linker flags shared by all libraries +dnl LDFLAGS modifier defining exported symbols from built libraries +dnl (export _gst_foo but not __gst_foo) +GST_LIB_LDFLAGS="-export-symbols-regex ^_?\(gst_\|Gst\|GST_\).*" +AC_SUBST([GST_LIB_LDFLAGS]) + +dnl this really should only contain flags, not libs - they get added before +dnl whatevertarget_LIBS and -L flags here affect the rest of the linking +GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^[_]*gst_plugin_.*' $GST_ALL_LDFLAGS" +AC_SUBST([GST_PLUGIN_LDFLAGS]) + dnl --------------------------------------------------------------------------- dnl -- Generate files and summary -- dnl --------------------------------------------------------------------------- @@ -894,9 +1001,10 @@ AC_DEFINE_UNQUOTED([GST_VAAPI_MAJOR_VERSION_S], ["0"], AC_CONFIG_FILES([ Makefile + common/Makefile + common/m4/Makefile docs/Makefile docs/reference/Makefile - docs/reference/plugins/Makefile docs/reference/plugins/plugins-docs.xml gst-libs/Makefile gst-libs/gst/Makefile @@ -924,7 +1032,7 @@ echo echo $PACKAGE configuration summary: echo echo Installation Prefix .............. : ${prefix} -echo GStreamer API version ............ : $GST_API_VERSION +echo GStreamer API version ............ : $GST_VERSION echo VA-API version ................... : $VA_VERSION_STR echo Video encoding ................... : $(yesno $USE_ENCODERS) echo Video outputs .................... : $VIDEO_OUTPUTS From d675816ed0b053077696818253774bd3c55218ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Jan 2016 15:39:09 +0100 Subject: [PATCH 2268/3781] resurrect gtk-doc machinery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Our auto-generated documentation has been a bit neglected. This patch replaces the 'normal' gtk-doc with the one used in GStreamer, which is adapted for plugins, elements and libraries. This patch also re-enables documentation generation. Signed-off-by: Víctor Manuel Jáquez Leal --- Makefile.am | 2 +- configure.ac | 5 +- docs/Makefile.am | 18 ++- docs/plugins/Makefile.am | 90 ++++++++++++++ .../gstreamer-vaapi-plugins-docs.xml.in} | 2 +- .../gstreamer-vaapi-plugins.types} | 0 docs/reference/Makefile.am | 3 - docs/reference/plugins/Makefile.am | 116 ------------------ docs/reference/plugins/plugins-sections.txt | 41 ------- docs/reference/plugins/plugins.types | 9 -- docs/version.entities.in | 2 + 11 files changed, 111 insertions(+), 177 deletions(-) create mode 100644 docs/plugins/Makefile.am rename docs/{reference/plugins/plugins-docs.xml.in => plugins/gstreamer-vaapi-plugins-docs.xml.in} (95%) rename docs/{reference/plugins/plugins-overrides.txt => plugins/gstreamer-vaapi-plugins.types} (100%) delete mode 100644 docs/reference/Makefile.am delete mode 100644 docs/reference/plugins/Makefile.am delete mode 100644 docs/reference/plugins/plugins-sections.txt delete mode 100644 docs/reference/plugins/plugins.types create mode 100644 docs/version.entities.in diff --git a/Makefile.am b/Makefile.am index fad0a41c63..5db5e1f7d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ACLOCAL_AMFLAGS = -I m4 -I common/m4 ${ACLOCAL_FLAGS} -SUBDIRS = gst-libs gst tests common +SUBDIRS = gst-libs gst tests common docs DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc diff --git a/configure.ac b/configure.ac index 299d7523e3..fd9be8aba5 100644 --- a/configure.ac +++ b/configure.ac @@ -1004,8 +1004,9 @@ AC_CONFIG_FILES([ common/Makefile common/m4/Makefile docs/Makefile - docs/reference/Makefile - docs/reference/plugins/plugins-docs.xml + docs/version.entities + docs/plugins/Makefile + docs/plugins/gstreamer-vaapi-plugins-docs.xml gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/base/Makefile diff --git a/docs/Makefile.am b/docs/Makefile.am index 1feb33d768..dfe9c3a659 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -1,9 +1,19 @@ -SUBDIRS = - if ENABLE_GTK_DOC -SUBDIRS += reference +if ENABLE_PLUGIN_DOCS +PLUGIN_DOCS_DIRS = plugins +else +PLUGIN_DOCS_DIRS = +endif +else +PLUGIN_DOCS_DIRS = plugins endif -DIST_SUBDIRS = reference +SUBDIRS = $(PLUGIN_DOCS_DIRS) +DIST_SUBDIRS = plugins + +EXTRA_DIST = version.entities.in + +upload: + @if test "x$(SUBDIRS)" != x; then for a in $(SUBDIRS); do cd $$a; make upload; cd ..; done; fi -include $(top_srcdir)/git.mk diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am new file mode 100644 index 0000000000..c0409ab839 --- /dev/null +++ b/docs/plugins/Makefile.am @@ -0,0 +1,90 @@ +GST_DOC_SCANOBJ = $(top_srcdir)/common/gstdoc-scangobj + +## Process this file with automake to produce Makefile.in + +# The name of the module, e.g. 'glib'. +MODULE=gstreamer-vaapi +DOC_MODULE=$(MODULE)-plugins + +# for upload-doc.mak +DOC=$(MODULE)-plugins +FORMATS=html +html: html-build.stamp +include $(top_srcdir)/common/upload-doc.mak + +# The top-level SGML file. You can change this if you want to. +DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting the functions and macros. +DOC_SOURCE_DIR = $(top_srcdir)/gst + +# Extra options to supply to gtkdoc-scan. +SCAN_OPTIONS = --deprecated-guards="GST_VAAPI_DISABLE_DEPRECATED" + +# Extra options to supply to gtkdoc-mkdb. +MKDB_OPTIONS = --sgml-mode --source-suffixes=c,h,cc,m + +# Extra options to supply to gtkdoc-fixref. +FIXXREF_OPTIONS=--extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html \ + --extra-dir=$(GST_PREFIX)/share/gtk-doc/html \ + --extra-dir=$(GSTPB_PREFIX)/share/gtk-doc/html + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB = $(top_srcdir)/gst/*/*.h +CFILE_GLOB = $(top_srcdir)/gst/*/*.c + +# Header files to ignore when scanning. +IGNORE_HFILES = +EXTRA_HFILES = + +# we add all .h files of elements that have signals/args we want +# sadly this also pulls in the private methods - maybe we should +# move those around in the source ? +# +# also, we should add some stuff here conditionally based on whether +# or not the plugin will actually build +# but I'm not sure about that - it might be this Just Works given that +# the registry won't have the element +# -> it just works (TM) (ensonic) + +# FIXME: not ported yet +# $(top_srcdir)/ext/gnomevfs/gstgnomevfssink.c + +# example code that needs to be converted to xml and placed in xml/ +EXAMPLE_CFILES = + +# Images to copy into HTML directory. +HTML_IMAGES = + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +content_files = + +# Other files to distribute. +extra_files = + +# CFLAGS and LDFLAGS for compiling scan program. Only needed if your app/lib +# contains GtkObjects/GObjects and you want to document signals and properties. +GTKDOC_CFLAGS = -DGST_USE_UNSTABLE_API $(GST_PLUGINS_BAD_CFLAGS) $(GST_BASE_CFLAGS) -I$(top_builddir) -I$(top_builddir)/gst-libs/ +GTKDOC_LIBS = $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la $(top_builddir)/gst/vaapi/libgstvaapi.la $(GST_BASE_LIBS) + +# If you need to override some of the declarations, place them in this file +# and uncomment this line. +#DOC_OVERRIDES = $(DOC_MODULE)-overrides.txt +DOC_OVERRIDES = + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/common/gtk-doc-plugins.mak + +SUBDIRS = + +# Extra clean files so that maintainer-clean removes *everything* +MAINTAINERCLEANFILES = \ + gstreamer-vaapi-plugins.* \ + *.stamp inspect \ + $(NULL) + +-include $(top_srcdir)/git.mk diff --git a/docs/reference/plugins/plugins-docs.xml.in b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in similarity index 95% rename from docs/reference/plugins/plugins-docs.xml.in rename to docs/plugins/gstreamer-vaapi-plugins-docs.xml.in index ee1a53ab35..99332e67d9 100644 --- a/docs/reference/plugins/plugins-docs.xml.in +++ b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in @@ -10,7 +10,7 @@ - gst-plugins-vaapi Plugins + gstreamer-vaapi Plugins diff --git a/docs/reference/plugins/plugins-overrides.txt b/docs/plugins/gstreamer-vaapi-plugins.types similarity index 100% rename from docs/reference/plugins/plugins-overrides.txt rename to docs/plugins/gstreamer-vaapi-plugins.types diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am deleted file mode 100644 index 41143a195b..0000000000 --- a/docs/reference/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = plugins - --include $(top_srcdir)/git.mk diff --git a/docs/reference/plugins/Makefile.am b/docs/reference/plugins/Makefile.am deleted file mode 100644 index 87addf9490..0000000000 --- a/docs/reference/plugins/Makefile.am +++ /dev/null @@ -1,116 +0,0 @@ -## Process this file with automake to produce Makefile.in - -# We require automake 1.6 at least. -AUTOMAKE_OPTIONS = 1.6 - -# This is a blank Makefile.am for using gtk-doc. -# Copy this to your project's API docs directory and modify the variables to -# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples -# of using the various options. - -# The name of the module, e.g. 'glib'. -DOC_MODULE = plugins - -# The top-level SGML file. You can change this if you want to. -DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml - -# The directory containing the source code. Relative to $(srcdir). -# gtk-doc will search all .c & .h files beneath here for inline comments -# documenting the functions and macros. -# e.g. DOC_SOURCE_DIR=../../../gtk -DOC_SOURCE_DIR = $(top_srcdir)/gst - -# Extra options to pass to gtkdoc-scangobj. Not normally needed. -SCANGOBJ_OPTIONS = --type-init-func="gst_init(NULL, NULL)" - -# Extra options to supply to gtkdoc-scan. -# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" -SCAN_OPTIONS = --deprecated-guards="GST_VAAPI_DISABLE_DEPRECATED" - -# Extra options to supply to gtkdoc-mkdb. -# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml -MKDB_OPTIONS = --sgml-mode --output-format=xml --name-space=$(DOC_MODULE) - -# Extra options to supply to gtkdoc-mktmpl -# e.g. MKTMPL_OPTIONS=--only-section-tmpl -MKTMPL_OPTIONS = - -# Extra options to supply to gtkdoc-fixref. Not normally needed. -# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html -FIXXREF_OPTIONS = \ - --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib \ - --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/gobject \ - --extra-dir=$(CAIRO_PREFIX)/share/gtk-doc/html/cairo \ - --extra-dir=$(PANGO_PREFIX)/share/gtk-doc/html/pango - -# Used for dependencies. The docs will be rebuilt if any of these change. -# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h -# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB = $(top_srcdir)/gst/*/*.h -CFILE_GLOB = $(top_srcdir)/gst/*/*.c - -# Header files to ignore when scanning. -# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h -IGNORE_HFILES = \ - $(NULL) - -EXTRA_HFILES = \ - $(NULL) - -# Images to copy into HTML directory. -# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png -HTML_IMAGES = \ - $(NULL) - -# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). -# e.g. content_files=running.sgml building.sgml changes-2.0.sgml -content_files = \ - $(NULL) - -# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded -# These files must be listed here *and* in content_files -# e.g. expand_content_files=running.sgml -expand_content_files = \ - $(NULL) - -# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. -# Only needed if you are using gtkdoc-scangobj to dynamically query widget -# signals and properties. -# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) -# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) - -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/gst-libs \ - -I$(top_srcdir)/gst-libs/gst/vaapi \ - $(GLIB_CFLAGS) \ - $(GST_CFLAGS) \ - $(NULL) - -gtkdoc_vaapi_libs = \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la \ - $(NULL) - -if USE_X11 -gtkdoc_vaapi_libs += \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11.la \ - $(NULL) -endif - -GTKDOC_LIBS = \ - $(gtkdoc_vaapi_libs) \ - $(top_builddir)/gst/vaapi/libgstvaapi.la \ - $(GLIB_LIBS) \ - $(GST_LIBS) \ - $(NULL) - -# This includes the standard gtk-doc make rules, copied by gtkdocize. -include $(top_srcdir)/gtk-doc.make - -# Other files to distribute -# e.g. EXTRA_DIST += version.xml.in -EXTRA_DIST += \ - $(DOC_MODULE)-docs.xml.in \ - $(NULL) - --include $(top_srcdir)/git.mk diff --git a/docs/reference/plugins/plugins-sections.txt b/docs/reference/plugins/plugins-sections.txt deleted file mode 100644 index 110c90a62c..0000000000 --- a/docs/reference/plugins/plugins-sections.txt +++ /dev/null @@ -1,41 +0,0 @@ -
-gstvaapisink -GstVaapiSink -GstVaapiSink - -GST_VAAPISINK -GST_IS_VAAPISINK -GST_TYPE_VAAPISINK -gst_vaapisink_get_type -GST_VAAPISINK_CLASS -GST_IS_VAAPISINK_CLASS -GST_VAAPISINK_GET_CLASS -
- -
-gstvaapidecode -GstVaapiDecode -GstVaapiDecode - -GST_VAAPIDECODE -GST_IS_VAAPIDECODE -GST_TYPE_VAAPIDECODE -gst_vaapidecode_get_type -GST_VAAPIDECODE_CLASS -GST_IS_VAAPIDECODE_CLASS -GST_VAAPIDECODE_GET_CLASS -
- -
-gstvaapipostproc -GstVaapiPostproc -GstVaapiPostproc - -GST_VAAPIPOSTPROC -GST_IS_VAAPIPOSTPROC -GST_TYPE_VAAPIPOSTPROC -gst_vaapipostproc_get_type -GST_VAAPIPOSTPROC_CLASS -GST_IS_VAAPIPOSTPROC_CLASS -GST_VAAPIPOSTPROC_GET_CLASS -
diff --git a/docs/reference/plugins/plugins.types b/docs/reference/plugins/plugins.types deleted file mode 100644 index 375d7c6b94..0000000000 --- a/docs/reference/plugins/plugins.types +++ /dev/null @@ -1,9 +0,0 @@ -#include - -#include -#include -#include - -gst_vaapidecode_get_type -gst_vaapipostproc_get_type -gst_vaapisink_get_type diff --git a/docs/version.entities.in b/docs/version.entities.in new file mode 100644 index 0000000000..286989f56e --- /dev/null +++ b/docs/version.entities.in @@ -0,0 +1,2 @@ + + From 9b8fb25b8c6ddfa7fd70a7ca79a468dae1376351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Jan 2016 20:41:27 +0100 Subject: [PATCH 2269/3781] docs: update plugin documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update all the documentation of elements of the vaapi plugin. Signed-off-by: Víctor Manuel Jáquez Leal --- .../gstreamer-vaapi-plugins-docs.xml.in | 17 ++- .../gstreamer-vaapi-plugins-sections.txt | 135 ++++++++++++++++++ gst/vaapi/gstvaapidecode.c | 21 ++- gst/vaapi/gstvaapidecodebin.c | 22 ++- gst/vaapi/gstvaapiencode_h264.c | 14 ++ gst/vaapi/gstvaapiencode_h265.c | 14 ++ gst/vaapi/gstvaapiencode_jpeg.c | 14 ++ gst/vaapi/gstvaapiencode_mpeg2.c | 14 ++ gst/vaapi/gstvaapiencode_vp8.c | 14 ++ gst/vaapi/gstvaapipostproc.c | 16 ++- gst/vaapi/gstvaapisink.c | 11 +- 11 files changed, 279 insertions(+), 13 deletions(-) create mode 100644 docs/plugins/gstreamer-vaapi-plugins-sections.txt diff --git a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in index 99332e67d9..5070eb6e8f 100644 --- a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in +++ b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in @@ -9,11 +9,22 @@ GStreamer VA-API Plugins @GST_API_VERSION@ Plugins Reference Manual + + gstreamer-vaapi Elements + + + + + + + + + + + gstreamer-vaapi Plugins - - - + diff --git a/docs/plugins/gstreamer-vaapi-plugins-sections.txt b/docs/plugins/gstreamer-vaapi-plugins-sections.txt new file mode 100644 index 0000000000..c18e462177 --- /dev/null +++ b/docs/plugins/gstreamer-vaapi-plugins-sections.txt @@ -0,0 +1,135 @@ +
+element-vaapidecode +vaapidecode + +GST_IS_VAAPIDECODE +GST_IS_VAAPIDECODE_CLASS +GST_TYPE_VAAPIDECODE +GST_VAAPIDECODE +GST_VAAPIDECODE_CLASS +GST_VAAPIDECODE_GET_CLASS +GstVaapiDecode +GstVaapiDecodeClass +gst_vaapidecode_get_type +
+ +
+element-vaapidecodebin +vaapidecodebin + +GST_IS_AUTO_DETECT +GST_IS_AUTO_DETECT_CLASS +GST_TYPE_VAAPI_DECODE_BIN +GST_VAAPI_DECODE_BIN +GST_VAAPI_DECODE_BIN_CLASS +GST_VAAPI_DECODE_BIN_GET_CLASS +GstVaapiDecodeBin +GstVaapiDecodeBinClass +gst_vaapi_decode_bin_get_type +
+ +
+element-vaapipostproc +vaapipostproc +GstVaapiDeinterlaceMode + +GST_IS_VAAPIPOSTPROC +GST_IS_VAAPIPOSTPROC_CLASS +GST_TYPE_VAAPIPOSTPROC +GST_VAAPIPOSTPROC +GST_VAAPIPOSTPROC_CLASS +GST_VAAPIPOSTPROC_GET_CLASS +GstVaapiPostproc +GstVaapiPostprocClass +gst_vaapipostproc_get_type +
+ +
+element-vaapisink +vaapisink + +GST_IS_VAAPISINK +GST_IS_VAAPISINK_CLASS +GST_TYPE_VAAPISINK +GST_VAAPISINK +GST_VAAPISINK_CLASS +GST_VAAPISINK_GET_CLASS +GstVaapiSink +GstVaapiSinkClass +gst_vaapisink_get_type +
+ +
+element-vaapiencode_h264 +vaapiencode_h264 + +GST_IS_VAAPIENCODE_H264 +GST_IS_VAAPIENCODE_H264_CLASS +GST_TYPE_VAAPIENCODE_H264 +GST_VAAPIENCODE_H264 +GST_VAAPIENCODE_H264_CLASS +GST_VAAPIENCODE_H264_GET_CLASS +GstVaapiEncodeH264 +GstVaapiEncodeH264Class +gst_vaapiencode_h264_get_type +
+ +
+element-vaapiencode_h265 +vaapiencode_h265 + +GST_IS_VAAPIENCODE_H265 +GST_IS_VAAPIENCODE_H265_CLASS +GST_TYPE_VAAPIENCODE_H265 +GST_VAAPIENCODE_H265 +GST_VAAPIENCODE_H265_CLASS +GST_VAAPIENCODE_H265_GET_CLASS +GstVaapiEncodeH265 +GstVaapiEncodeH265Class +gst_vaapiencode_h265_get_type +
+ +
+element-vaapiencode_jpeg +vaapiencode_jpeg + +GST_IS_VAAPIENCODE_JPEG +GST_IS_VAAPIENCODE_JPEG_CLASS +GST_TYPE_VAAPIENCODE_JPEG +GST_VAAPIENCODE_JPEG +GST_VAAPIENCODE_JPEG_CLASS +GST_VAAPIENCODE_JPEG_GET_CLASS +GstVaapiEncodeJpeg +GstVaapiEncodeJpegClass +gst_vaapiencode_jpeg_get_type +
+ +
+element-vaapiencode_mpeg2 +vaapiencode_mpeg2 + +GST_IS_VAAPIENCODE_MPEG2 +GST_IS_VAAPIENCODE_MPEG2_CLASS +GST_TYPE_VAAPIENCODE_MPEG2 +GST_VAAPIENCODE_MPEG2 +GST_VAAPIENCODE_MPEG2_CLASS +GST_VAAPIENCODE_MPEG2_GET_CLASS +GstVaapiEncodeMpeg2 +GstVaapiEncodeMpeg2Class +gst_vaapiencode_mpeg2_get_type +
+ +
+element-vaapiencode_vp8 +vaapiencode_vp8 + +GST_IS_VAAPIENCODE_VP8 +GST_IS_VAAPIENCODE_VP8_CLASS +GST_TYPE_VAAPIENCODE_VP8 +GST_VAAPIENCODE_VP8 +GST_VAAPIENCODE_VP8_CLASS +GST_VAAPIENCODE_VP8_GET_CLASS +GstVaapiEncodeVP8 +GstVaapiEncodeVP8Class +gst_vaapiencode_vp8_get_type +
diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index de61d14c4f..3fa3c17576 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -23,11 +23,28 @@ */ /** - * SECTION:gstvaapidecode + * SECTION:element-vaapidecode * @short_description: A VA-API based video decoder * * vaapidecode decodes from raw bitstreams to surfaces suitable for - * the vaapisink element. + * the vaapisink or vaapipostproc elements using the installed VA-API + * back-end. + * + * In the case of OpenGL based elements, the buffers have the + * #GstVideoGLTextureUploadMeta meta, which efficiently copies the + * content of the VA-API surface into a GL texture. + * + * Also it can deliver normal video buffers that can be rendered or + * processed by other elements, but the performance would be rather + * bad. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=~/big_buck_bunny.mov ! qtdemux ! h264parse ! vaapidecode ! vaapisink + * ]| + * */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 9ab354f93f..5eaee5e7f4 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -21,6 +21,26 @@ * Boston, MA 02110-1301 USA */ +/** + * SECTION:element-vaapidecodebin + * @short_description: A VA-API based video decoder with a + * post-processor + * + * vaapidecodebin is similar #GstVaapiDecode, but it is composed by + * the vaapidecode, a #GstQueue, and the #GstVaapiPostproc, if it is + * available and functional in the setup. + * + * It offers the functionality of #GstVaapiDecode and the many options + * of #GstVaapiPostproc. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=~/big_buck_bunny.mov ! qtdemux ! h264parse ! vaapidecodebin ! vaapisink + * ]| + * + */ + #include "gstcompat.h" #include #include @@ -32,7 +52,7 @@ #include "gstvaapipluginbase.h" #define GST_PLUGIN_NAME "vaapidecodebin" -#define GST_PLUGIN_DESC "A Bin of VA-API elements: vaapidecode ! queue ! vaapipostproc" +#define GST_PLUGIN_DESC "A VA-API based bin with a decoder and a postprocessor" GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapi_decode_bin); #define GST_CAT_DEFAULT gst_debug_vaapi_decode_bin diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 7800786150..1c37ca7b39 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -21,6 +21,20 @@ * Boston, MA 02110-1301 USA */ +/** + * SECTION:element-vaapiencode_h264 + * @short_description: A VA-API based H.264 video encoder + * + * Encodes raw video streams into H.264 bitstreams. + * + * + * Example launch line + * |[ + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapiencode_h264 ! mp4mux ! filesink location=test.mp4 + * ]| + * + */ + #include "gstcompat.h" #include #include diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 964048a54b..f7324451fe 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -20,6 +20,20 @@ * Boston, MA 02110-1301 USA */ +/** + * SECTION:element-vaapiencode_h265 + * @short_description: A VA-API based HEVC video encoder + * + * Encodes raw video streams into HEVC bitstreams. + * + * + * Example launch line + * |[ + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapiencode_h265 ! matroskamux ! filesink location=test.mkv + * ]| + * + */ + #include "gstcompat.h" #include #include diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index d9dd34510a..086d155c7c 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -20,6 +20,20 @@ * Boston, MA 02110-1301 USA */ +/** + * SECTION:element-vaapiencode_jpeg + * @short_description: A VA-API based JPEG image encoder + * + * Encodes raw images into JPEG images. + * + * + * Example launch line + * |[ + * gst-launch-1.0 -ev videotestsrc num-buffers=1 ! timeoverlay ! vaapiencode_jpeg ! filesink location=test.jpg + * ]| + * + */ + #include "gstcompat.h" #include #include diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 5584c60185..9f2a23bb43 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -21,6 +21,20 @@ * Boston, MA 02110-1301 USA */ +/** + * SECTION:element-vaapiencode_mpeg2 + * @short_description: A VA-API based MPEG2 video encoder + * + * Encodes raw video streams into MPEG2 bitstreams. + * + * + * Example launch line + * |[ + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapiencode_mpeg2 ! matroskamux ! filesink location=test.mkv + * ]| + * + */ + #include "gstcompat.h" #include #include diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 366cdfd894..276a58400e 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -20,6 +20,20 @@ * Boston, MA 02110-1301 USA */ +/** + * SECTION:element-vaapiencode_vp8 + * @short_description: A VA-API based VP8 video encoder + * + * Encodes raw video streams into VP8 bitstreams. + * + * + * Example launch line + * |[ + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapiencode_vp8 ! matroskamux ! filesink location=test.mkv + * ]| + * + */ + #include "gstcompat.h" #include #include diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 9583c27eae..7d968a4a91 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -21,12 +21,18 @@ */ /** - * SECTION:gstvaapipostproc - * @short_description: A video postprocessing filter + * SECTION:element-vaapipostproc + * @short_description: A VA-API base video postprocessing filter * * vaapipostproc consists in various postprocessing algorithms to be - * applied to VA surfaces. So far, only basic bob deinterlacing is - * implemented. + * applied to VA surfaces. + * + * + * Example launch line + * |[ + * gst-launch-1.0 videotestsrc ! vaapipostproc ! video/x-raw width=1920, height=1080 ! vaapisink + * ]| + * */ #include "gstcompat.h" @@ -39,7 +45,7 @@ #include "gstvaapivideomemory.h" #define GST_PLUGIN_NAME "vaapipostproc" -#define GST_PLUGIN_DESC "A video postprocessing filter" +#define GST_PLUGIN_DESC "A VA-API video postprocessing filter" GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapipostproc); #define GST_CAT_DEFAULT gst_debug_vaapipostproc diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index f7fb5a2f6a..c73b2bb7c0 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -23,12 +23,19 @@ */ /** - * SECTION:gstvaapisink - * @short_description: A VA-API based videosink + * SECTION:element-vaapisink + * @short_description: A VA-API based video sink * * vaapisink renders video frames to a drawable (X #Window) on a local * display using the Video Acceleration (VA) API. The element will * create its own internal window and render into it. + * + * + * Example launch line + * |[ + * gst-launch-1.0 videotestsrc ! vaapisink + * ]| + * */ #include "gstcompat.h" From d76d78cc8ea73c53e893f11753bd2ce21623f71a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 3 Feb 2016 16:45:18 +0100 Subject: [PATCH 2270/3781] libs: fix compiler warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After setting the release flags, the compiler warns about a couple initialized variables. Also marked a couple of set variables as unused, because they are only used for assertion. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 9289eac917..0a34d7ed26 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -323,6 +323,8 @@ decode_sequence (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, if (par_n > 0 && par_d > 0) gst_vaapi_decoder_set_pixel_aspect_ratio (base_decoder, par_n, par_d); + width = 0; + height = 0; switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: case GST_VC1_PROFILE_MAIN: @@ -348,6 +350,7 @@ decode_sequence (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, priv->size_changed = TRUE; } + profile = GST_VAAPI_PROFILE_UNKNOWN; switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: profile = GST_VAAPI_PROFILE_VC1_SIMPLE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 7ad5637986..289a311bb4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1000,7 +1000,7 @@ _check_sps_pps_status (GstVaapiEncoderH264 * encoder, const guint8 * nal, guint32 size) { guint8 nal_type; - gsize ret; + G_GNUC_UNUSED gsize ret; /* FIXME */ gboolean has_subset_sps; g_assert (size); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index bae7577ccd..9d3f0b7831 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -835,7 +835,7 @@ _check_vps_sps_pps_status (GstVaapiEncoderH265 * encoder, const guint8 * nal, guint32 size) { guint8 nal_type; - gsize ret; + G_GNUC_UNUSED gsize ret; /* FIXME */ g_assert (size); if (encoder->vps_data && encoder->sps_data && encoder->pps_data) From 11221fe868bb08e0acf046bfa81dc2781c2a2d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 3 Feb 2016 16:53:41 +0100 Subject: [PATCH 2271/3781] Release 1.6.0 --- configure.ac | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index fd9be8aba5..d2d2b3ec4c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number -m4_define([gst_vaapi_major_version], [0]) -m4_define([gst_vaapi_minor_version], [7]) -m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_nano_version], [1]) +m4_define([gst_vaapi_major_version], [1]) +m4_define([gst_vaapi_minor_version], [6]) +m4_define([gst_vaapi_micro_version], [0]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,9 +16,9 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [7]) +m4_define([gst_vaapi_lt_current], [600]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [0]) +m4_define([gst_vaapi_lt_age], [600]) # glib version number m4_define([glib_version], [2.32]) From ee20a96c6894c361d0938b44ed27c115b05fb261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 3 Feb 2016 17:06:48 +0100 Subject: [PATCH 2272/3781] Back to development MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- common | 2 +- configure.ac | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/common b/common index 66235917b4..e97c9bb012 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 66235917b47e6f933f8bd32376662a54f17eb609 +Subproject commit e97c9bb0122006fda8f5387cea1be452e23944e3 diff --git a/configure.ac b/configure.ac index d2d2b3ec4c..d1412b4be7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [6]) +m4_define([gst_vaapi_minor_version], [7]) m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [600]) +m4_define([gst_vaapi_lt_current], [700]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [600]) +m4_define([gst_vaapi_lt_age], [700]) # glib version number m4_define([glib_version], [2.32]) # gstreamer version number -m4_define([gst_version], [1.6.3]) -m4_define([gst_plugins_base_version], [1.6.3]) -m4_define([gst_plugins_bad_version], [1.6.3]) +m4_define([gst_version], [1.7.1.1]) +m4_define([gst_plugins_base_version], [1.7.1.1]) +m4_define([gst_plugins_bad_version], [1.7.1.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) From f1bdf09cb4cc874e644b1a7ac81b536dc8fae1dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 3 Feb 2016 18:02:21 +0100 Subject: [PATCH 2273/3781] build: remove vp9 parser check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the VP9 parser was added in gst-plugins-bad 1.7.1 we can remove safely the check of the parser, as we did for the others. Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/configure.ac b/configure.ac index d1412b4be7..98d07e6cea 100644 --- a/configure.ac +++ b/configure.ac @@ -242,32 +242,6 @@ dnl bitstream parsers (gstreamer-codecparsers) AG_GST_CHECK_MODULES([GST_CODEC_PARSERS], [gstreamer-codecparsers-$GST_API_VERSION], [$GST_PBADREQ], [yes]) -dnl ... VP9 parser, with required extensions -HAVE_GST_VP9_PARSER=0 -AC_CACHE_CHECK([for VP9 parser], - [ac_cv_have_gst_vp9_parser], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS" - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include - ]], - [[ -GstVp9FrameHdr frame_hdr; - ]]) - ], - [ac_cv_have_gst_vp9_parser="yes"], - [ac_cv_have_gst_vp9_parser="no"]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) -AS_IF([test "x$ac_cv_have_gst_vp9_parser" = "xyes"], [HAVE_GST_VP9_PARSER=1]) - AS_IF([test "x$enable_glx" = "xyes" -o "x$enable_egl" = "xyes"], [enable_opengl="yes"], [enable_opengl="no"]) @@ -649,8 +623,7 @@ slice_param.slice_data_flag = 0; CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) -AS_IF([test "x$ac_cv_have_vp9_decoding_api" = "xyes"], - [USE_VP9_DECODER=$HAVE_GST_VP9_PARSER]) +AS_IF([test "x$ac_cv_have_vp9_decoding_api" = "xyes"], [USE_VP9_DECODER=1]) dnl Check for va_dec_hevc.h header saved_CPPFLAGS="$CPPFLAGS" From db6125be746c056b4b7681b570ab78c73e817962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 3 Feb 2016 18:42:36 +0100 Subject: [PATCH 2274/3781] Use new AG_GST_ARG_ENABLE_EXTRA_CHECKS #define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 98d07e6cea..fccbbbae89 100644 --- a/configure.ac +++ b/configure.ac @@ -109,6 +109,7 @@ AC_SUBST([ACLOCAL_AMFLAGS], ["-I m4 -I common/m4"]) dnl *** check for arguments to configure *** AG_GST_ARG_DISABLE_FATAL_WARNINGS +AG_GST_ARG_ENABLE_EXTRA_CHECKS AG_GST_ARG_DEBUG AG_GST_ARG_WITH_PKG_CONFIG_PATH From 77ddde41d95a7b7b17b9f288c009232e02d2e90e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 3 Feb 2016 19:07:40 +0100 Subject: [PATCH 2275/3781] rename encoders to vaapi{codec}enc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trying to comply with GStreamer's element names, this patch renames the encoders using the name format vaapi{codec}enc. In this way, the plugin documentation is linked correctly. Signed-off-by: Víctor Manuel Jáquez Leal --- .../gstreamer-vaapi-plugins-docs.xml.in | 10 +++++----- .../gstreamer-vaapi-plugins-sections.txt | 20 +++++++++---------- gst/vaapi/gstvaapi.c | 10 +++++----- gst/vaapi/gstvaapiencode_h264.c | 6 +++--- gst/vaapi/gstvaapiencode_h265.c | 6 +++--- gst/vaapi/gstvaapiencode_jpeg.c | 6 +++--- gst/vaapi/gstvaapiencode_mpeg2.c | 6 +++--- gst/vaapi/gstvaapiencode_vp8.c | 6 +++--- 8 files changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in index 5070eb6e8f..6626e0e443 100644 --- a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in +++ b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in @@ -15,11 +15,11 @@ - - - - - + + + + +
diff --git a/docs/plugins/gstreamer-vaapi-plugins-sections.txt b/docs/plugins/gstreamer-vaapi-plugins-sections.txt index c18e462177..bdd34f2c91 100644 --- a/docs/plugins/gstreamer-vaapi-plugins-sections.txt +++ b/docs/plugins/gstreamer-vaapi-plugins-sections.txt @@ -60,8 +60,8 @@ gst_vaapisink_get_type
-element-vaapiencode_h264 -vaapiencode_h264 +element-vaapih264enc +vaapih264enc GST_IS_VAAPIENCODE_H264 GST_IS_VAAPIENCODE_H264_CLASS @@ -75,8 +75,8 @@ gst_vaapiencode_h264_get_type
-element-vaapiencode_h265 -vaapiencode_h265 +element-vaapih265enc +vaapih265enc GST_IS_VAAPIENCODE_H265 GST_IS_VAAPIENCODE_H265_CLASS @@ -90,8 +90,8 @@ gst_vaapiencode_h265_get_type
-element-vaapiencode_jpeg -vaapiencode_jpeg +element-vaapijpegenc +vaapijpegenc GST_IS_VAAPIENCODE_JPEG GST_IS_VAAPIENCODE_JPEG_CLASS @@ -105,8 +105,8 @@ gst_vaapiencode_jpeg_get_type
-element-vaapiencode_mpeg2 -vaapiencode_mpeg2 +element-vaapimpeg2enc +vaapimpeg2enc GST_IS_VAAPIENCODE_MPEG2 GST_IS_VAAPIENCODE_MPEG2_CLASS @@ -120,8 +120,8 @@ gst_vaapiencode_mpeg2_get_type
-element-vaapiencode_vp8 -vaapiencode_vp8 +element-vaapivp8enc +vaapivp8enc GST_IS_VAAPIENCODE_VP8 GST_IS_VAAPIENCODE_VP8_CLASS diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index a64cb64573..dc9726098d 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -60,22 +60,22 @@ plugin_init (GstPlugin * plugin) gst_element_register (plugin, "vaapisink", GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); #if USE_ENCODERS - gst_element_register (plugin, "vaapiencode_h264", + gst_element_register (plugin, "vaapih264enc", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_H264); - gst_element_register (plugin, "vaapiencode_mpeg2", + gst_element_register (plugin, "vaapimpeg2enc", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_MPEG2); #endif #if USE_JPEG_ENCODER - gst_element_register (plugin, "vaapiencode_jpeg", + gst_element_register (plugin, "vaapijpegenc", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_JPEG); #endif #if USE_VP8_ENCODER - gst_element_register (plugin, "vaapiencode_vp8", + gst_element_register (plugin, "vaapivp8enc", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_VP8); #endif #if USE_H265_ENCODER - gst_element_register (plugin, "vaapiencode_h265", + gst_element_register (plugin, "vaapih265enc", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_H265); #endif diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 1c37ca7b39..b4027ab192 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -22,7 +22,7 @@ */ /** - * SECTION:element-vaapiencode_h264 + * SECTION:element-vaapih264enc * @short_description: A VA-API based H.264 video encoder * * Encodes raw video streams into H.264 bitstreams. @@ -30,7 +30,7 @@ * * Example launch line * |[ - * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapiencode_h264 ! mp4mux ! filesink location=test.mp4 + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapih264enc ! mp4mux ! filesink location=test.mp4 * ]| * */ @@ -43,7 +43,7 @@ #include "gstvaapipluginutil.h" #include "gstvaapivideomemory.h" -#define GST_PLUGIN_NAME "vaapiencode_h264" +#define GST_PLUGIN_NAME "vaapih264enc" #define GST_PLUGIN_DESC "A VA-API based H.264 video encoder" GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index f7324451fe..b5e5bf7c07 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -21,7 +21,7 @@ */ /** - * SECTION:element-vaapiencode_h265 + * SECTION:element-vaapih265enc * @short_description: A VA-API based HEVC video encoder * * Encodes raw video streams into HEVC bitstreams. @@ -29,7 +29,7 @@ * * Example launch line * |[ - * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapiencode_h265 ! matroskamux ! filesink location=test.mkv + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapih265enc ! matroskamux ! filesink location=test.mkv * ]| * */ @@ -42,7 +42,7 @@ #include "gstvaapipluginutil.h" #include "gstvaapivideomemory.h" -#define GST_PLUGIN_NAME "vaapiencode_h265" +#define GST_PLUGIN_NAME "vaapih265enc" #define GST_PLUGIN_DESC "A VA-API based H.265 video encoder" GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h265_encode_debug); diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 086d155c7c..902a12f644 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -21,7 +21,7 @@ */ /** - * SECTION:element-vaapiencode_jpeg + * SECTION:element-vaapijpegenc * @short_description: A VA-API based JPEG image encoder * * Encodes raw images into JPEG images. @@ -29,7 +29,7 @@ * * Example launch line * |[ - * gst-launch-1.0 -ev videotestsrc num-buffers=1 ! timeoverlay ! vaapiencode_jpeg ! filesink location=test.jpg + * gst-launch-1.0 -ev videotestsrc num-buffers=1 ! timeoverlay ! vaapijpegenc ! filesink location=test.jpg * ]| * */ @@ -41,7 +41,7 @@ #include "gstvaapipluginutil.h" #include "gstvaapivideomemory.h" -#define GST_PLUGIN_NAME "vaapiencode_jpeg" +#define GST_PLUGIN_NAME "vaapijpegenc" #define GST_PLUGIN_DESC "A VA-API based JPEG video encoder" GST_DEBUG_CATEGORY_STATIC (gst_vaapi_jpeg_encode_debug); diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 9f2a23bb43..791adff34a 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -22,7 +22,7 @@ */ /** - * SECTION:element-vaapiencode_mpeg2 + * SECTION:element-vaapimpeg2enc * @short_description: A VA-API based MPEG2 video encoder * * Encodes raw video streams into MPEG2 bitstreams. @@ -30,7 +30,7 @@ * * Example launch line * |[ - * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapiencode_mpeg2 ! matroskamux ! filesink location=test.mkv + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapimpeg2enc ! matroskamux ! filesink location=test.mkv * ]| * */ @@ -42,7 +42,7 @@ #include "gstvaapipluginutil.h" #include "gstvaapivideomemory.h" -#define GST_PLUGIN_NAME "vaapiencode_mpeg2" +#define GST_PLUGIN_NAME "vaapimpeg2enc" #define GST_PLUGIN_DESC "A VA-API based MPEG-2 video encoder" GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 276a58400e..db5ead4eb6 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -21,7 +21,7 @@ */ /** - * SECTION:element-vaapiencode_vp8 + * SECTION:element-vaapivp8enc * @short_description: A VA-API based VP8 video encoder * * Encodes raw video streams into VP8 bitstreams. @@ -29,7 +29,7 @@ * * Example launch line * |[ - * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapiencode_vp8 ! matroskamux ! filesink location=test.mkv + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapivp8enc ! matroskamux ! filesink location=test.mkv * ]| * */ @@ -41,7 +41,7 @@ #include "gstvaapipluginutil.h" #include "gstvaapivideomemory.h" -#define GST_PLUGIN_NAME "vaapiencode_vp8" +#define GST_PLUGIN_NAME "vaapivp8enc" #define GST_PLUGIN_DESC "A VA-API based VP8 video encoder" GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp8_encode_debug); From d9beeafe4bab91570ec6860dd3348e7b9e8c9c5c Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Fri, 5 Feb 2016 18:11:29 -0300 Subject: [PATCH 2276/3781] Automatic update of common submodule From e97c9bb to b64f03f --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index e97c9bb012..b64f03f609 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit e97c9bb0122006fda8f5387cea1be452e23944e3 +Subproject commit b64f03f6090245624608beb5d2fff335e23a01c0 From 1f6d29641d25d7c0d4de499ea3fc3c694cf0af7c Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 4 Feb 2016 10:16:00 +0200 Subject: [PATCH 2277/3781] vaapisink: Fix wrong caps advertising The get_caps() should only report the supported formats. https://bugzilla.gnome.org/show_bug.cgi?id=761147 --- gst/vaapi/gstvaapisink.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index c73b2bb7c0..8f42e09600 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1206,18 +1206,32 @@ gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) { GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); GstCaps *out_caps, *raw_caps; + static const char surface_caps_str[] = + GST_VAAPI_MAKE_ENC_SURFACE_CAPS ";" + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE + "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + "{ ENCODED, NV12, I420, YV12 }"); - out_caps = gst_static_pad_template_get_caps (&gst_vaapisink_sink_factory); - if (!out_caps) - return NULL; + GstCapsFeatures *const features = + gst_caps_features_new + (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL); + + out_caps = gst_caps_from_string (surface_caps_str); if (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)) { raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE (sink)); if (raw_caps) { + GstCaps *feature_caps; + out_caps = gst_caps_make_writable (out_caps); + gst_caps_append (out_caps, gst_caps_copy (raw_caps)); + + feature_caps = gst_caps_copy (raw_caps); + gst_caps_set_features (feature_caps, 0, features); + gst_caps_append (out_caps, feature_caps); } } return out_caps; From ba701d59184e5ae42a2c6497a3feab26bc665b55 Mon Sep 17 00:00:00 2001 From: Vineeth TM Date: Mon, 15 Feb 2016 10:01:54 +0900 Subject: [PATCH 2278/3781] tests: simple-encoder: fix build error argument mismatch of gsize with 'long unsigned int' https://bugzilla.gnome.org/show_bug.cgi?id=762055 --- tests/simple-encoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/simple-encoder.c b/tests/simple-encoder.c index b424d69206..b827604f9a 100644 --- a/tests/simple-encoder.c +++ b/tests/simple-encoder.c @@ -442,7 +442,8 @@ app_run (App * app) app->read_frames++; id = gst_vaapi_surface_get_id (surface); - g_debug ("input frame %d, surface id = %lu", app->read_frames, id); + g_debug ("input frame %d, surface id = %" G_GSIZE_FORMAT, app->read_frames, + id); gst_vaapi_surface_proxy_unref (proxy); } From 60ebfbc59536658ba1635f99a18e692a7d1b4506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 Feb 2016 18:00:49 +0100 Subject: [PATCH 2279/3781] libs: fix build error gst_vaapi_buffer_proxy_{acquire_handle,release_handle,finalize,class} functions are used only when libva's API version is greater than 0.36.0 This patch guards those functions completely rather than just their content. The patch is a continuation of commit 38f8fea4 Original-patch-by: Vineeth TM https://bugzilla.gnome.org/show_bug.cgi?id=762055 --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index aba9d301f5..358a34e944 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -77,10 +77,10 @@ to_GstVaapiBufferMemoryType (guint va_type) return type; } +#if VA_CHECK_VERSION (0,36,0) static gboolean gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) { -#if VA_CHECK_VERSION (0,36,0) const guint mem_type = proxy->va_info.mem_type; VAStatus va_status; @@ -99,15 +99,12 @@ gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) if (proxy->va_info.mem_type != mem_type) return FALSE; return TRUE; -#else - return FALSE; -#endif } +/* VA_CHECK_VERSION (0,36,0) */ static gboolean gst_vaapi_buffer_proxy_release_handle (GstVaapiBufferProxy * proxy) { -#if VA_CHECK_VERSION (0,36,0) VAStatus va_status; if (!proxy->va_info.handle) @@ -123,11 +120,9 @@ gst_vaapi_buffer_proxy_release_handle (GstVaapiBufferProxy * proxy) if (!vaapi_check_status (va_status, "vaReleaseBufferHandle()")) return FALSE; return TRUE; -#else - return FALSE; -#endif } +/* VA_CHECK_VERSION (0,36,0) */ static void gst_vaapi_buffer_proxy_finalize (GstVaapiBufferProxy * proxy) { @@ -140,6 +135,7 @@ gst_vaapi_buffer_proxy_finalize (GstVaapiBufferProxy * proxy) gst_vaapi_object_replace (&proxy->parent, NULL); } +/* VA_CHECK_VERSION (0,36,0) */ static inline const GstVaapiMiniObjectClass * gst_vaapi_buffer_proxy_class (void) { @@ -149,6 +145,7 @@ gst_vaapi_buffer_proxy_class (void) }; return &GstVaapiBufferProxyClass; } +#endif GstVaapiBufferProxy * gst_vaapi_buffer_proxy_new (guintptr handle, guint type, gsize size, From 7bd9b2aa5ce49eb0e34a9ffc6fec15622a33a85b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 16 Feb 2016 14:36:39 +0200 Subject: [PATCH 2280/3781] configure: Fix setting of extra compiler warning flags --- configure.ac | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index fccbbbae89..a70d9b125b 100644 --- a/configure.ac +++ b/configure.ac @@ -834,15 +834,10 @@ dnl *** finalize CFLAGS, LDFLAGS, LIBS # set by AG_GST_PARSE_SUBSYSTEM_DISABLES above dnl make sure it doesn't complain about unused variables if debugging is disabled -NO_WARNINGS="" -AG_GST_CHECK_GST_DEBUG_DISABLED([NO_WARNINGS="-Wno-unused"], [ - -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls - -Wwrite-strings -Wformat-security -Wold-style-definition - -Winit-self -Wmissing-include-dirs -Waddress -Wno-multichar - -Wnested-externs $NO_WARNINGS]) +AG_GST_CHECK_GST_DEBUG_DISABLED([NO_WARNINGS="-Wno-unused"], [NO_WARNINGS=""]) dnl define an ERROR_CFLAGS Makefile variable -AG_GST_SET_ERROR_CFLAGS([$FATAL_WARNINGS], [$NO_WARNINGS]) +AG_GST_SET_ERROR_CFLAGS([$FATAL_WARNINGS], [-Wmissing-declarations -Wmissing-prototypes -Wredundant-decls -Wwrite-strings -Wformat-security -Wold-style-definition -Winit-self -Wmissing-include-dirs -Waddress -Wno-multichar -Wnested-externs $NO_WARNINGS]) dnl define correct level for debugging messages AG_GST_SET_LEVEL_DEFAULT([$GST_GIT]) From 734b8bad8fde71f0e1ee197b771ebfd0629be3c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 16 Feb 2016 15:09:01 +0200 Subject: [PATCH 2281/3781] vaapi: Fix various compiler warnings and disable -Wredundant-decls for now --- configure.ac | 3 ++- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 2 +- gst-libs/gst/vaapi/gstvaapifilter.c | 6 +++--- gst/vaapi/gstvaapidecodebin.c | 2 +- gst/vaapi/gstvaapipluginutil.c | 4 ++-- 8 files changed, 12 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index a70d9b125b..65dd2fa8e0 100644 --- a/configure.ac +++ b/configure.ac @@ -837,7 +837,8 @@ dnl make sure it doesn't complain about unused variables if debugging is disable AG_GST_CHECK_GST_DEBUG_DISABLED([NO_WARNINGS="-Wno-unused"], [NO_WARNINGS=""]) dnl define an ERROR_CFLAGS Makefile variable -AG_GST_SET_ERROR_CFLAGS([$FATAL_WARNINGS], [-Wmissing-declarations -Wmissing-prototypes -Wredundant-decls -Wwrite-strings -Wformat-security -Wold-style-definition -Winit-self -Wmissing-include-dirs -Waddress -Wno-multichar -Wnested-externs $NO_WARNINGS]) +dnl FIXME Add -Wredundant-decls again if considered useful and warnings are fixed +AG_GST_SET_ERROR_CFLAGS([$FATAL_WARNINGS], [-Wmissing-declarations -Wmissing-prototypes -Wwrite-strings -Wformat-security -Wold-style-definition -Winit-self -Wmissing-include-dirs -Waddress -Wno-multichar -Wnested-externs $NO_WARNINGS]) dnl define correct level for debugging messages AG_GST_SET_LEVEL_DEFAULT([$GST_GIT]) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index b828a9fe4a..46d1e8e1e4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -365,7 +365,7 @@ copy_quant_matrix (guint8 dst[64], const guint8 src[64]) static const char * get_profile_str (GstVaapiProfile profile) { - char *str; + const char *str; switch (profile) { case GST_VAAPI_PROFILE_MPEG2_SIMPLE: diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 9ab340debc..76360c7599 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -456,7 +456,7 @@ decode_gop (GstVaapiDecoderMpeg4 * decoder, const guint8 * buf, guint buf_size) return GST_VAAPI_DECODER_STATUS_SUCCESS; } -void +static void calculate_pts_diff (GstVaapiDecoderMpeg4 * decoder, GstMpeg4VideoObjectLayer * vol_hdr, GstMpeg4VideoObjectPlane * vop_hdr) { diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index 0a50740625..8bfb5c1592 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -572,7 +572,7 @@ decode_buffer (GstVaapiDecoderVp8 * decoder, const guchar * buf, guint buf_size) return decode_picture (decoder, buf, buf_size); } -GstVaapiDecoderStatus +static GstVaapiDecoderStatus gst_vaapi_decoder_vp8_decode (GstVaapiDecoder * base_decoder, GstVaapiDecoderUnit * unit) { diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index ecb449143e..c8b6599555 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -647,7 +647,7 @@ decode_buffer (GstVaapiDecoderVp9 * decoder, const guchar * buf, guint buf_size) return decode_picture (decoder, buf, size); } -GstVaapiDecoderStatus +static GstVaapiDecoderStatus gst_vaapi_decoder_vp9_decode (GstVaapiDecoder * base_decoder, GstVaapiDecoderUnit * unit) { diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index df9c801e0b..e2f269c6ac 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -79,7 +79,7 @@ struct _GstVaapiFilter /* --- VPP Types --- */ /* ------------------------------------------------------------------------- */ -GType +static GType gst_vaapi_scale_method_get_type (void) { static gsize g_type = 0; @@ -725,7 +725,7 @@ ensure_operations (GstVaapiFilter * filter) } /* Find whether the VPP operation is supported or not */ -GstVaapiFilterOpData * +static GstVaapiFilterOpData * find_operation (GstVaapiFilter * filter, GstVaapiFilterOp op) { guint i; @@ -905,7 +905,7 @@ op_set_deinterlace (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, /* Update skin tone enhancement */ #if USE_VA_VPP -gboolean +static gboolean op_set_skintone_unlocked (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, gboolean value) { diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 5eaee5e7f4..84a547b768 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -461,7 +461,7 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) static gboolean gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) { - gchar *missing_factory = NULL; + const gchar *missing_factory = NULL; GstPad *pad, *ghostpad; GstPadTemplate *tmpl; diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 5293c8744b..13c48afb53 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -358,7 +358,7 @@ gst_vaapi_value_set_format_list (GValue * value, GArray * formats) return TRUE; } -void +static void set_video_template_caps (GstCaps * caps) { GstStructure *const structure = gst_caps_get_structure (caps, 0); @@ -662,7 +662,7 @@ gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, * gst_vaapi_display_unref () after use. **/ GstVaapiDisplay * -gst_vaapi_create_test_display () +gst_vaapi_create_test_display (void) { return gst_vaapi_create_display (GST_VAAPI_DISPLAY_TYPE_ANY, NULL); } From b54ac96c2791f3744616395ddef8d2e3b6428a7f Mon Sep 17 00:00:00 2001 From: Vineeth TM Date: Tue, 16 Feb 2016 08:15:40 +0900 Subject: [PATCH 2282/3781] vaapisink: Fix capsfeature memory leak caps feature allocated is not being freeing in some cases https://bugzilla.gnome.org/show_bug.cgi?id=762111 --- gst/vaapi/gstvaapisink.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 8f42e09600..4da72bc0c2 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1212,10 +1212,6 @@ gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, "{ ENCODED, NV12, I420, YV12 }"); - GstCapsFeatures *const features = - gst_caps_features_new - (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL); - out_caps = gst_caps_from_string (surface_caps_str); if (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)) { @@ -1224,6 +1220,9 @@ gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) (sink)); if (raw_caps) { GstCaps *feature_caps; + GstCapsFeatures *const features = + gst_caps_features_new + (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL); out_caps = gst_caps_make_writable (out_caps); From 26abec3e26e5028e04c13eb775c2524167fbc4fd Mon Sep 17 00:00:00 2001 From: Vineeth TM Date: Tue, 16 Feb 2016 08:48:43 +0900 Subject: [PATCH 2283/3781] vaapidecode: Fix capsfeature memory leak https://bugzilla.gnome.org/show_bug.cgi?id=762116 --- gst/vaapi/gstvaapidecode.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3fa3c17576..7e216aeb40 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -251,8 +251,11 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) state = gst_video_decoder_set_output_state (vdec, format, ref_state->info.width, ref_state->info.height, ref_state); - if (!state || state->info.width == 0 || state->info.height == 0) + if (!state || state->info.width == 0 || state->info.height == 0) { + if (features) + gst_caps_features_free (features); return FALSE; + } vi = &state->info; From 38fbe5899943afe4a08b664136484fe270fcbb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 16 Feb 2016 15:44:48 +0000 Subject: [PATCH 2284/3781] vaapisink: post message for application for unhandled keyboard/mouse events Makes (most) keyboard shortcuts work in gst-play-1.0 when the video window has focus. --- gst/vaapi/gstvaapisink.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 4da72bc0c2..0bdc714497 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -865,7 +865,13 @@ gst_vaapisink_navigation_send_event (GstNavigation * navigation, (gdouble) y * yscale, NULL); } - gst_pad_send_event (peer, event); + if (!gst_pad_send_event (peer, gst_event_ref (event))) { + /* If upstream didn't handle the event we'll post a message with it + * for the application in case it wants to do something with it */ + gst_element_post_message (GST_ELEMENT_CAST (sink), + gst_navigation_message_new_event (GST_OBJECT_CAST (sink), event)); + } + gst_event_unref (event); gst_object_unref (peer); } } From ac01304ceca6bac4aca14d05a78fa5cb37423057 Mon Sep 17 00:00:00 2001 From: Vineeth TM Date: Wed, 17 Feb 2016 17:20:08 +0900 Subject: [PATCH 2285/3781] vaapidecode: Fix videocodec state memory leak When state is not NULL and either width/height of video info is 0, then state leaks https://bugzilla.gnome.org/show_bug.cgi?id=762173 --- gst/vaapi/gstvaapidecode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 7e216aeb40..2c236c341c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -254,6 +254,8 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) if (!state || state->info.width == 0 || state->info.height == 0) { if (features) gst_caps_features_free (features); + if (state) + gst_video_codec_state_unref (state); return FALSE; } From 733c9b6fba036ad359de8ed50e3549049e3007b5 Mon Sep 17 00:00:00 2001 From: Vineeth TM Date: Wed, 17 Feb 2016 17:15:28 +0900 Subject: [PATCH 2286/3781] vaapipluginbase: Fix structure memory leak config structure is not being freed in all cases https://bugzilla.gnome.org/show_bug.cgi?id=762172 --- gst/vaapi/gstvaapipluginbase.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 9e878cea24..9c52bcc3fb 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -575,6 +575,8 @@ gst_vaapi_plugin_base_set_pool_config (GstBufferPool * pool, if (!gst_buffer_pool_config_has_option (config, option)) { gst_buffer_pool_config_add_option (config, option); return gst_buffer_pool_set_config (pool, config); + } else { + gst_structure_free (config); } return TRUE; } From ce1ab4673c9dedaa9e9d9ead7ff78e25087ea8d6 Mon Sep 17 00:00:00 2001 From: Lim Siew Hoon Date: Wed, 17 Feb 2016 15:40:54 +0200 Subject: [PATCH 2287/3781] Add icamerasrc as dmabuf capable peer element icamerasrc is another gstreamer plugin using to capture RAW frames from camera device. It is based on libcamhal library. There are some properties available to control icamera behavior. Signed-off-by: Lim Siew Hoon Tested & Reviewed: Zhu Haiyang https://bugzilla.gnome.org/show_bug.cgi?id=759481 Fixme: This is the similar workaround we done for v4l2src. The workaround will be removed once we fix #755072 --- gst/vaapi/gstvaapipluginbase.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 9c52bcc3fb..cb477ca33e 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -375,12 +375,19 @@ has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad) if (GST_IS_PUSH_SRC (element)) { element_name = gst_element_get_name (element); - if (!element_name || sscanf (element_name, "v4l2src%d", &v) != 1) + if (!element_name) + break; + + if ((sscanf (element_name, "v4l2src%d", &v) != 1) + && (sscanf (element_name, "camerasrc%d", &v) != 1)) break; v = 0; g_object_get (element, "io-mode", &v, NULL); - is_dmabuf_capable = v == 5; /* "dmabuf-import" enum value */ + if (strncmp (element_name, "camerasrc", 9) == 0) + is_dmabuf_capable = v == 3; + else + is_dmabuf_capable = v == 5; /* "dmabuf-import" enum value */ break; } else if (GST_IS_BASE_TRANSFORM (element)) { element_name = gst_element_get_name (element); From 24bc53456c118ce0960adb6aa958861b599a56ad Mon Sep 17 00:00:00 2001 From: Vineeth TM Date: Thu, 18 Feb 2016 10:13:53 +0900 Subject: [PATCH 2288/3781] vaapisink: Fix event,pad,structure memory leaks https://bugzilla.gnome.org/show_bug.cgi?id=762229 --- gst/vaapi/gstvaapisink.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 0bdc714497..6663065d41 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -836,6 +836,11 @@ gst_vaapisink_navigation_send_event (GstNavigation * navigation, GstVaapiSink *const sink = GST_VAAPISINK (navigation); GstPad *peer; + if (!sink->window) { + gst_structure_free (structure); + return; + } + if ((peer = gst_pad_get_peer (GST_VAAPI_PLUGIN_BASE_SINK_PAD (sink)))) { GstEvent *event; GstVaapiRectangle *disp_rect = &sink->display_rect; @@ -843,9 +848,6 @@ gst_vaapisink_navigation_send_event (GstNavigation * navigation, event = gst_event_new_navigation (structure); - if (!sink->window) - return; - /* We calculate scaling using the original video frames geometry to include pixel aspect ratio scaling. */ xscale = (gdouble) sink->video_width / disp_rect->width; From 056a69cf2a730a387a51c0aa5c3089198006bade Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Fri, 19 Feb 2016 11:10:25 -0300 Subject: [PATCH 2289/3781] vaapidecoder_h264: fix parsing of NALU aligned data Don't assume the whole buffer is a single NAL, instead look for the next start code in case there are multiple NALs per buffer. https://bugzilla.gnome.org/show_bug.cgi?id=762328 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 5f08e07f57..670e79bb9f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4382,9 +4382,12 @@ gst_vaapi_decoder_h264_parse (GstVaapiDecoder * base_decoder, if (size < 4) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_NALU) + if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_NALU) { buf_size = size; - else { + ofs = scan_for_start_code (adapter, 4, size - 4, NULL); + if (ofs > 0) + buf_size = ofs; + } else { ofs = scan_for_start_code (adapter, 0, size, NULL); if (ofs < 0) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; From 1f71503fc9701ad7b5ed7884d4d585146baaf4e0 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Fri, 19 Feb 2016 19:03:44 -0300 Subject: [PATCH 2290/3781] vaapidecoder_h265: fix parsing of NALU aligned data Don't assume the whole buffer is a single NAL, instead look for the next start code in case there are multiple NALs per buffer. https://bugzilla.gnome.org/show_bug.cgi?id=762328 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 6170b6a54c..aec4bb8d84 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2779,9 +2779,12 @@ gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder, } else { if (size < 4) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H265_NALU) + if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H265_NALU) { buf_size = size; - else { + ofs = scan_for_start_code (adapter, 4, size - 4, NULL); + if (ofs > 0) + buf_size = ofs; + } else { ofs = scan_for_start_code (adapter, 0, size, NULL); if (ofs < 0) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; From 5b5ebc0a15099582d32e09ff8929338c048d9ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 17 Feb 2016 12:51:45 +0100 Subject: [PATCH 2291/3781] plugins: remove deprecated code Since we are only supporting current GStreamer version, since 1.3 gst_buffer_pool_config_add_option() checks if the option to add is already set. There is no need to do it ourselves. --- gst/vaapi/gstvaapipluginbase.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index cb477ca33e..622853d352 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -570,8 +570,6 @@ error_pool_config: } } -/* XXXX: GStreamer 1.2 doesn't check, in gst_buffer_pool_set_config() - if the config option is already set */ static inline gboolean gst_vaapi_plugin_base_set_pool_config (GstBufferPool * pool, const gchar * option) @@ -579,13 +577,8 @@ gst_vaapi_plugin_base_set_pool_config (GstBufferPool * pool, GstStructure *config; config = gst_buffer_pool_get_config (pool); - if (!gst_buffer_pool_config_has_option (config, option)) { - gst_buffer_pool_config_add_option (config, option); - return gst_buffer_pool_set_config (pool, config); - } else { - gst_structure_free (config); - } - return TRUE; + gst_buffer_pool_config_add_option (config, option); + return gst_buffer_pool_set_config (pool, config); } /** From 6034734d733e8514e2aaa6d4d625b70985317b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 17 Feb 2016 13:43:48 +0100 Subject: [PATCH 2292/3781] vaapidecode: use video decoder getcaps() The usage of getcaps() vmethod is preferred than to handle manually the sink's caps query. In order to avoid function declarations, this patch moves the class_init() method to the end of the file. --- gst/vaapi/gstvaapidecode.c | 120 ++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 70 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 2c236c341c..ed68ccb95f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -136,10 +136,6 @@ static gboolean gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, const GstVideoCodecState * new_state); -static gboolean -gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query); -static gboolean -gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query); static gboolean gst_vaapidecode_negotiate (GstVaapiDecode * decode); static void @@ -946,52 +942,6 @@ gst_vaapidecode_parse (GstVideoDecoder * vdec, return ret; } -static void -gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) -{ - GObjectClass *const object_class = G_OBJECT_CLASS (klass); - GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); - GstVideoDecoderClass *const vdec_class = GST_VIDEO_DECODER_CLASS (klass); - GstPadTemplate *pad_template; - - GST_DEBUG_CATEGORY_INIT (gst_debug_vaapidecode, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - - gst_vaapi_plugin_base_class_init (GST_VAAPI_PLUGIN_BASE_CLASS (klass)); - - object_class->finalize = gst_vaapidecode_finalize; - - vdec_class->open = GST_DEBUG_FUNCPTR (gst_vaapidecode_open); - vdec_class->close = GST_DEBUG_FUNCPTR (gst_vaapidecode_close); - vdec_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapidecode_set_format); - vdec_class->flush = GST_DEBUG_FUNCPTR (gst_vaapidecode_flush); - vdec_class->parse = GST_DEBUG_FUNCPTR (gst_vaapidecode_parse); - vdec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapidecode_handle_frame); - vdec_class->finish = GST_DEBUG_FUNCPTR (gst_vaapidecode_finish); - vdec_class->drain = GST_DEBUG_FUNCPTR (gst_vaapidecode_drain); - vdec_class->decide_allocation = - GST_DEBUG_FUNCPTR (gst_vaapidecode_decide_allocation); - vdec_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_src_query); - vdec_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_query); - - gst_element_class_set_static_metadata (element_class, - "VA-API decoder", - "Codec/Decoder/Video", - GST_PLUGIN_DESC, - "Gwenole Beauchesne , " - "Halley Zhao , " - "Sreerenj Balachandran , " - "Wind Yuan "); - - /* sink pad */ - pad_template = gst_static_pad_template_get (&gst_vaapidecode_sink_factory); - gst_element_class_add_pad_template (element_class, pad_template); - - /* src pad */ - pad_template = gst_static_pad_template_get (&gst_vaapidecode_src_factory); - gst_element_class_add_pad_template (element_class, pad_template); -} - static gboolean gst_vaapidecode_ensure_allowed_caps (GstVaapiDecode * decode) { @@ -1052,16 +1002,16 @@ error_no_memory: } static GstCaps * -gst_vaapidecode_get_caps (GstPad * pad) +gst_vaapidecode_sink_getcaps (GstVideoDecoder * vdec, GstCaps * filter) { - GstVaapiDecode *const decode = GST_VAAPIDECODE (GST_OBJECT_PARENT (pad)); + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); if (decode->allowed_caps) goto bail; /* if we haven't a display yet, return our pad's template caps */ if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)) - return gst_pad_get_pad_template_caps (pad); + return gst_pad_get_pad_template_caps (GST_VIDEO_DECODER_SINK_PAD (vdec)); /* if the allowed caps calculation fails, return an empty caps, so * the auto-plug can try other decoder */ @@ -1080,23 +1030,6 @@ gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query) GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (decode); switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_CAPS:{ - GstCaps *caps, *filter = NULL; - GstPad *pad = GST_VIDEO_DECODER_SINK_PAD (vdec); - - gst_query_parse_caps (query, &filter); - caps = gst_vaapidecode_get_caps (pad); - - if (filter) { - GstCaps *tmp = caps; - caps = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (tmp); - } - - gst_query_set_caps_result (query, caps); - gst_caps_unref (caps); - break; - } case GST_QUERY_CONTEXT:{ ret = gst_vaapi_handle_context_query (query, plugin->display); break; @@ -1150,6 +1083,53 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) return ret; } +static void +gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstVideoDecoderClass *const vdec_class = GST_VIDEO_DECODER_CLASS (klass); + GstPadTemplate *pad_template; + + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapidecode, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + gst_vaapi_plugin_base_class_init (GST_VAAPI_PLUGIN_BASE_CLASS (klass)); + + object_class->finalize = gst_vaapidecode_finalize; + + vdec_class->open = GST_DEBUG_FUNCPTR (gst_vaapidecode_open); + vdec_class->close = GST_DEBUG_FUNCPTR (gst_vaapidecode_close); + vdec_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapidecode_set_format); + vdec_class->flush = GST_DEBUG_FUNCPTR (gst_vaapidecode_flush); + vdec_class->parse = GST_DEBUG_FUNCPTR (gst_vaapidecode_parse); + vdec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapidecode_handle_frame); + vdec_class->finish = GST_DEBUG_FUNCPTR (gst_vaapidecode_finish); + vdec_class->drain = GST_DEBUG_FUNCPTR (gst_vaapidecode_drain); + vdec_class->decide_allocation = + GST_DEBUG_FUNCPTR (gst_vaapidecode_decide_allocation); + vdec_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_src_query); + vdec_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_query); + vdec_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_getcaps); + + gst_element_class_set_static_metadata (element_class, + "VA-API decoder", + "Codec/Decoder/Video", + GST_PLUGIN_DESC, + "Gwenole Beauchesne , " + "Halley Zhao , " + "Sreerenj Balachandran , " + "Wind Yuan "); + + /* sink pad */ + pad_template = gst_static_pad_template_get (&gst_vaapidecode_sink_factory); + gst_element_class_add_pad_template (element_class, pad_template); + + /* src pad */ + pad_template = gst_static_pad_template_get (&gst_vaapidecode_src_factory); + gst_element_class_add_pad_template (element_class, pad_template); +} + static void gst_vaapidecode_init (GstVaapiDecode * decode) { From ffd5028a38da45ed7e67c377590078534aca3078 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Tue, 23 Feb 2016 10:55:02 +0200 Subject: [PATCH 2293/3781] decoder: hevc: Fill dependent slice segment headers while parsing Copy the data into the dependent slice segment header from the corresponding independent slice segment header during parsing. Previously the reference to the "previous" independent header was held through the parsing phase and then dereferenced during the decoding phase. This caused all dependent headers to be populated with the data of the AU's last independent header instead of the proper corresponding header. https://bugzilla.gnome.org/show_bug.cgi?id=762352 Changes since v1: - Reworded commit message --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 36 +++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index aec4bb8d84..cd6b66a39a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1601,18 +1601,10 @@ init_picture_refs (GstVaapiDecoderH265 * decoder, memset (priv->RefPicList1, 0, sizeof (GstVaapiPictureH265 *) * 16); priv->RefPicList0_count = priv->RefPicList1_count = 0; - if (slice_hdr->dependent_slice_segment_flag) { - GstH265SliceHdr *tmp = &priv->prev_independent_slice_pi->data.slice_hdr; - num_ref_idx_l0_active_minus1 = tmp->num_ref_idx_l0_active_minus1; - num_ref_idx_l1_active_minus1 = tmp->num_ref_idx_l1_active_minus1; - ref_pic_list_modification = &tmp->ref_pic_list_modification; - type = tmp->type; - } else { - num_ref_idx_l0_active_minus1 = slice_hdr->num_ref_idx_l0_active_minus1; - num_ref_idx_l1_active_minus1 = slice_hdr->num_ref_idx_l1_active_minus1; - ref_pic_list_modification = &slice_hdr->ref_pic_list_modification; - type = slice_hdr->type; - } + num_ref_idx_l0_active_minus1 = slice_hdr->num_ref_idx_l0_active_minus1; + num_ref_idx_l1_active_minus1 = slice_hdr->num_ref_idx_l1_active_minus1; + ref_pic_list_modification = &slice_hdr->ref_pic_list_modification; + type = slice_hdr->type; /* decoding process for reference picture list construction needs to be * invoked only for P and B slice */ @@ -2434,7 +2426,6 @@ fill_slice (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture, GstVaapiSlice * slice, GstVaapiParserInfoH265 * pi, GstVaapiDecoderUnit * unit) { - GstVaapiDecoderH265Private *const priv = &decoder->priv; VASliceParameterBufferHEVC *const slice_param = slice->param; GstH265SliceHdr *slice_hdr = &pi->data.slice_hdr; @@ -2455,11 +2446,6 @@ fill_slice (GstVaapiDecoderH265 * decoder, COPY_LFF (dependent_slice_segment_flag); - /* use most recent independent slice segment header syntax elements - * for filling the missing fields in dependent slice segment header */ - if (slice_hdr->dependent_slice_segment_flag) - slice_hdr = &priv->prev_independent_slice_pi->data.slice_hdr; - COPY_LFF (mvd_l1_zero_flag); COPY_LFF (cabac_init_flag); COPY_LFF (collocated_from_l0_flag); @@ -2731,6 +2717,18 @@ ensure_decoder (GstVaapiDecoderH265 * decoder) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static void +populate_dependent_slice_hdr (GstVaapiParserInfoH265 * pi, + GstVaapiParserInfoH265 * indep_pi) +{ + GstH265SliceHdr *slice_hdr = &pi->data.slice_hdr; + GstH265SliceHdr *indep_slice_hdr = &indep_pi->data.slice_hdr; + + memcpy (&slice_hdr->type, &indep_slice_hdr->type, + offsetof (GstH265SliceHdr, num_entry_point_offsets) - + offsetof (GstH265SliceHdr, type)); +} + static GstVaapiDecoderStatus gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder, GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit) @@ -2928,6 +2926,8 @@ gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder, if (!pi->data.slice_hdr.dependent_slice_segment_flag) gst_vaapi_parser_info_h265_replace (&priv->prev_independent_slice_pi, pi); + else + populate_dependent_slice_hdr (pi, priv->prev_independent_slice_pi); break; default: /* Fix */ From b52cfea76fbf6e269cddcc4f846d8a5946105565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 24 Feb 2016 12:36:33 +0100 Subject: [PATCH 2294/3781] build: add m4 directory Instead of rely on the automatic creation of m4 directory by aclocal, we already control it. Later we could create our own m4 scripts in order to unclutter configure.ac https://bugzilla.gnome.org/show_bug.cgi?id=762528 --- Makefile.am | 4 ++-- configure.ac | 1 + m4/Makefile.am | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 m4/Makefile.am diff --git a/Makefile.am b/Makefile.am index 5db5e1f7d6..87f8a3616e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ -ACLOCAL_AMFLAGS = -I m4 -I common/m4 ${ACLOCAL_FLAGS} +ACLOCAL_AMFLAGS = -I m4 -I common/m4 -SUBDIRS = gst-libs gst tests common docs +SUBDIRS = gst-libs gst tests m4 common docs DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc diff --git a/configure.ac b/configure.ac index 65dd2fa8e0..d7c2022046 100644 --- a/configure.ac +++ b/configure.ac @@ -973,6 +973,7 @@ AC_CONFIG_FILES([ Makefile common/Makefile common/m4/Makefile + m4/Makefile docs/Makefile docs/version.entities docs/plugins/Makefile diff --git a/m4/Makefile.am b/m4/Makefile.am new file mode 100644 index 0000000000..af864e3bbb --- /dev/null +++ b/m4/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = $(wildcard *.m4) From 6725cbd2b3809ce0b5a8fe812cad10be7b478b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 26 Feb 2016 12:42:46 +0200 Subject: [PATCH 2295/3781] Automatic update of common submodule From b64f03f to 6f2d209 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index b64f03f609..6f2d2093e8 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit b64f03f6090245624608beb5d2fff335e23a01c0 +Subproject commit 6f2d2093e84cc0eb99b634fa281822ebb9507285 From 0bae36bb88324c9cbc94477ef8a0c2be797db18d Mon Sep 17 00:00:00 2001 From: Lim Siew Hoon Date: Mon, 29 Feb 2016 11:55:27 +0200 Subject: [PATCH 2296/3781] Add memset to initialize value for VAEncSliceParameterBufferJPEG https://bugzilla.gnome.org/show_bug.cgi?id=762850 --- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index c2b0181f8c..f669d8383c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -393,6 +393,8 @@ fill_slices (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture) 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; From 861ef4d218b40391ae752dae43ac8b8e3cd5f5ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 1 Mar 2016 11:35:49 +0100 Subject: [PATCH 2297/3781] vaapidecode: intersect with filter in getcaps() In commit 6034734d I forgot to add the caps filter intersection in the getcaps() vmethod generating a regression when a capsfilter is set in the pipeline. This commit adds the caps filter intersection. --- gst/vaapi/gstvaapidecode.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ed68ccb95f..8b40baf333 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1005,13 +1005,16 @@ static GstCaps * gst_vaapidecode_sink_getcaps (GstVideoDecoder * vdec, GstCaps * filter) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstCaps *tmp, *caps = NULL; if (decode->allowed_caps) goto bail; /* if we haven't a display yet, return our pad's template caps */ - if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)) - return gst_pad_get_pad_template_caps (GST_VIDEO_DECODER_SINK_PAD (vdec)); + if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)) { + caps = gst_pad_get_pad_template_caps (GST_VIDEO_DECODER_SINK_PAD (vdec)); + goto bail; + } /* if the allowed caps calculation fails, return an empty caps, so * the auto-plug can try other decoder */ @@ -1019,7 +1022,16 @@ gst_vaapidecode_sink_getcaps (GstVideoDecoder * vdec, GstCaps * filter) return gst_caps_new_empty (); bail: - return gst_caps_ref (decode->allowed_caps); + if (!caps) + caps = gst_caps_ref (decode->allowed_caps); + + if (filter) { + tmp = caps; + caps = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (tmp); + } + + return caps; } static gboolean From ae9efc7db65117c622481a1897164365272ead2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 1 Mar 2016 16:14:47 +0200 Subject: [PATCH 2298/3781] configure: Use AG_GST_SET_PACKAGE_RELEASE_DATETIME_WITH_NANO to set release date --- configure.ac | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure.ac b/configure.ac index d7c2022046..b3a0527b41 100644 --- a/configure.ac +++ b/configure.ac @@ -114,6 +114,10 @@ AG_GST_ARG_DEBUG AG_GST_ARG_WITH_PKG_CONFIG_PATH +AG_GST_SET_PACKAGE_RELEASE_DATETIME_WITH_NANO([$PACKAGE_VERSION_NANO], + ["${srcdir}/gstreamer-vaapi.doap"], + [$PACKAGE_VERSION_MAJOR.$PACKAGE_VERSION_MINOR.$PACKAGE_VERSION_MICRO]) + AC_ARG_ENABLE([encoders], AS_HELP_STRING([--enable-encoders], [enable video encoders @<:@default=yes@:>@]), From 7a1a11e7fb534444b0f1a619f2dec0151b3be3f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 1 Mar 2016 19:23:51 +0200 Subject: [PATCH 2299/3781] Release 1.7.90 --- ChangeLog | 21487 ++++++++++++++++++++++++++++++++++++++++- NEWS | 387 +- configure.ac | 14 +- gstreamer-vaapi.doap | 18 + 4 files changed, 21512 insertions(+), 394 deletions(-) diff --git a/ChangeLog b/ChangeLog index 30c993fb95..8e05f29eb7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1 +1,21486 @@ -EMPTY FILE +=== release 1.7.90 === + +2016-03-01 Sebastian Dröge + + * configure.ac: + releasing 1.7.90 + +2016-03-01 16:14:47 +0200 Sebastian Dröge + + * configure.ac: + configure: Use AG_GST_SET_PACKAGE_RELEASE_DATETIME_WITH_NANO to set release date + +2016-03-01 11:35:49 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: intersect with filter in getcaps() + In commit 6034734d I forgot to add the caps filter intersection in the + getcaps() vmethod generating a regression when a capsfilter is set in the + pipeline. + This commit adds the caps filter intersection. + +2016-02-29 11:55:27 +0200 Lim Siew Hoon + + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + Add memset to initialize value for VAEncSliceParameterBufferJPEG + https://bugzilla.gnome.org/show_bug.cgi?id=762850 + +2016-02-26 12:42:46 +0200 Sebastian Dröge + + * common: + Automatic update of common submodule + From b64f03f to 6f2d209 + +2016-02-24 12:36:33 +0100 Víctor Manuel Jáquez Leal + + * Makefile.am: + * configure.ac: + * m4/Makefile.am: + build: add m4 directory + Instead of rely on the automatic creation of m4 directory by aclocal, we + already control it. Later we could create our own m4 scripts in order to + unclutter configure.ac + https://bugzilla.gnome.org/show_bug.cgi?id=762528 + +2016-02-23 10:55:02 +0200 Scott D Phillips + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Fill dependent slice segment headers while parsing + Copy the data into the dependent slice segment header from the + corresponding independent slice segment header during parsing. + Previously the reference to the "previous" independent header was + held through the parsing phase and then dereferenced during the + decoding phase. This caused all dependent headers to be populated + with the data of the AU's last independent header instead of the + proper corresponding header. + https://bugzilla.gnome.org/show_bug.cgi?id=762352 + Changes since v1: + - Reworded commit message + +2016-02-17 13:43:48 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: use video decoder getcaps() + The usage of getcaps() vmethod is preferred than to handle manually the sink's + caps query. + In order to avoid function declarations, this patch moves the class_init() + method to the end of the file. + +2016-02-17 12:51:45 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: remove deprecated code + Since we are only supporting current GStreamer version, since 1.3 + gst_buffer_pool_config_add_option() checks if the option to add is + already set. There is no need to do it ourselves. + +2016-02-19 19:03:44 -0300 Thiago Santos + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + vaapidecoder_h265: fix parsing of NALU aligned data + Don't assume the whole buffer is a single NAL, instead look for the + next start code in case there are multiple NALs per buffer. + https://bugzilla.gnome.org/show_bug.cgi?id=762328 + +2016-02-19 11:10:25 -0300 Thiago Santos + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + vaapidecoder_h264: fix parsing of NALU aligned data + Don't assume the whole buffer is a single NAL, instead look for the + next start code in case there are multiple NALs per buffer. + https://bugzilla.gnome.org/show_bug.cgi?id=762328 + +2016-02-18 10:13:53 +0900 Vineeth TM + + * gst/vaapi/gstvaapisink.c: + vaapisink: Fix event,pad,structure memory leaks + https://bugzilla.gnome.org/show_bug.cgi?id=762229 + +2016-02-17 15:40:54 +0200 Lim Siew Hoon + + * gst/vaapi/gstvaapipluginbase.c: + Add icamerasrc as dmabuf capable peer element + icamerasrc is another gstreamer plugin using to capture RAW + frames from camera device. It is based on libcamhal library. + There are some properties available to control icamera behavior. + Signed-off-by: Lim Siew Hoon + Tested & Reviewed: Zhu Haiyang + https://bugzilla.gnome.org/show_bug.cgi?id=759481 + Fixme: This is the similar workaround we done for v4l2src. + The workaround will be removed once we fix #755072 + +2016-02-17 17:15:28 +0900 Vineeth TM + + * gst/vaapi/gstvaapipluginbase.c: + vaapipluginbase: Fix structure memory leak + config structure is not being freed in all cases + https://bugzilla.gnome.org/show_bug.cgi?id=762172 + +2016-02-17 17:20:08 +0900 Vineeth TM + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Fix videocodec state memory leak + When state is not NULL and either width/height of video info is 0, then state leaks + https://bugzilla.gnome.org/show_bug.cgi?id=762173 + +2016-02-16 15:44:48 +0000 Tim-Philipp Müller + + * gst/vaapi/gstvaapisink.c: + vaapisink: post message for application for unhandled keyboard/mouse events + Makes (most) keyboard shortcuts work in gst-play-1.0 when + the video window has focus. + +2016-02-16 08:48:43 +0900 Vineeth TM + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Fix capsfeature memory leak + https://bugzilla.gnome.org/show_bug.cgi?id=762116 + +2016-02-16 08:15:40 +0900 Vineeth TM + + * gst/vaapi/gstvaapisink.c: + vaapisink: Fix capsfeature memory leak + caps feature allocated is not being freeing in some cases + https://bugzilla.gnome.org/show_bug.cgi?id=762111 + +2016-02-16 15:09:01 +0200 Sebastian Dröge + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapipluginutil.c: + vaapi: Fix various compiler warnings and disable -Wredundant-decls for now + +2016-02-16 14:36:39 +0200 Sebastian Dröge + + * configure.ac: + configure: Fix setting of extra compiler warning flags + +2016-02-15 18:00:49 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + libs: fix build error + gst_vaapi_buffer_proxy_{acquire_handle,release_handle,finalize,class} + functions are used only when libva's API version is greater than 0.36.0 + This patch guards those functions completely rather than just their + content. The patch is a continuation of commit 38f8fea4 + Original-patch-by: Vineeth TM + https://bugzilla.gnome.org/show_bug.cgi?id=762055 + +2016-02-15 10:01:54 +0900 Vineeth TM + + * tests/simple-encoder.c: + tests: simple-encoder: fix build error + argument mismatch of gsize with 'long unsigned int' + https://bugzilla.gnome.org/show_bug.cgi?id=762055 + +2016-02-04 10:16:00 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapisink.c: + vaapisink: Fix wrong caps advertising + The get_caps() should only report the supported formats. + https://bugzilla.gnome.org/show_bug.cgi?id=761147 + +2016-02-05 18:11:29 -0300 Thiago Santos + + * common: + Automatic update of common submodule + From e97c9bb to b64f03f + +2016-02-03 19:07:40 +0100 Víctor Manuel Jáquez Leal + + * docs/plugins/gstreamer-vaapi-plugins-docs.xml.in: + * docs/plugins/gstreamer-vaapi-plugins-sections.txt: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + rename encoders to vaapi{codec}enc + Trying to comply with GStreamer's element names, this patch renames the + encoders using the name format vaapi{codec}enc. + In this way, the plugin documentation is linked correctly. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-02-03 18:42:36 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + Use new AG_GST_ARG_ENABLE_EXTRA_CHECKS #define + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-02-03 18:02:21 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: remove vp9 parser check + Since the VP9 parser was added in gst-plugins-bad 1.7.1 we can remove safely + the check of the parser, as we did for the others. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-02-03 17:06:48 +0100 Víctor Manuel Jáquez Leal + + * common: + * configure.ac: + Back to development + Signed-off-by: Víctor Manuel Jáquez Leal + +=== release 1.6.0 === + +2016-02-03 16:53:41 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + Release 1.6.0 + +2016-02-03 16:45:18 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: fix compiler warnings + After setting the release flags, the compiler warns about a couple + initialized variables. + Also marked a couple of set variables as unused, because they are only + used for assertion. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-29 20:41:27 +0100 Víctor Manuel Jáquez Leal + + * docs/plugins/gstreamer-vaapi-plugins-docs.xml.in: + * docs/plugins/gstreamer-vaapi-plugins-sections.txt: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + docs: update plugin documentation + Update all the documentation of elements of the vaapi plugin. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-29 15:39:09 +0100 Víctor Manuel Jáquez Leal + + * Makefile.am: + * configure.ac: + * docs/Makefile.am: + * docs/plugins/Makefile.am: + * docs/plugins/gstreamer-vaapi-plugins-docs.xml.in: + * docs/plugins/gstreamer-vaapi-plugins.types: + * docs/reference/Makefile.am: + * docs/reference/plugins/Makefile.am: + * docs/reference/plugins/plugins-docs.xml.in: + * docs/reference/plugins/plugins-overrides.txt: + * docs/reference/plugins/plugins-sections.txt: + * docs/reference/plugins/plugins.types: + * docs/version.entities.in: + resurrect gtk-doc machinery + Our auto-generated documentation has been a bit neglected. This patch replaces + the 'normal' gtk-doc with the one used in GStreamer, which is adapted for + plugins, elements and libraries. + This patch also re-enables documentation generation. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-28 19:35:24 +0100 Víctor Manuel Jáquez Leal + + * ChangeLog: + * Makefile.am: + * autogen.sh: + * configure.ac: + use gst-common submodule + This is 'the' big change in gstreamer-vaapi autoconf. Now it uses the official + GStreamer common submodule. + The documentation generation has been disable temporarily since it needs a + major rework, which will be done in the following commit. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-25 16:06:03 +0100 Víctor Manuel Jáquez Leal + + * .gitmodules: + * common: + add gst-common submodule + Pointing to branch 1.6 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-28 13:28:30 +0100 Víctor Manuel Jáquez Leal + + * gstreamer-vaapi.doap: + add doap descriptor + DOAP (Description of a Project) is an RDF Schema and XML vocabulary to + describe software projects, in particular free and open source software. + The description is used in GStreamer as in many other open source projects. + This patch adds the doap description of this project. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-02-03 11:50:13 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiparser_frame.c: + * gst-libs/gst/vaapi/gstvaapipixmap.c: + * gst-libs/gst/vaapi/gstvaapipixmap_x11.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + libs: humongous code style fix + As part of the upstreaming process of gstreamer-vaapi into the GStreamer + umbrella, we need to comply with the project's code style. This meant to + change a lot of code. + It was decided to use a single massive patch to update the code style. + I would like to apologize with the original developers of this code because of + the history breakage. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-02-03 11:04:15 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst/vaapi/gstvaapivideomemory.c: + libs: small refactors to enhance the code style + As gst-indent generated ugly code in these cases, this patch changes the used + idiomatic into other one. + No functional changes were introduced. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-02-02 17:59:57 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicodedbufferpool.c: + * gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_egl.c: + libs: small code style fixes + This a set of small code style fixes detected as-is by gst-indent. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-02-02 17:50:19 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicodedbufferpool.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapitexture_egl.c: + * gst-libs/gst/vaapi/gstvaapitexture_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: trivial comment style fixes + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-02-02 17:31:02 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicodedbuffer.c: + * gst-libs/gst/vaapi/gstvaapiwindow_egl.c: + libs: avoid gst-indent mess up + Guard pieces of code to avoid gst-ident to mess up the following code. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-02-03 12:17:59 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapivideomemory.c: + plugins: fix code style + Minor code style changes by executing gst-indent in gst/vaapi directory. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-02-01 13:22:10 +0000 Tim-Philipp Müller + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + Fix some more compiler warning + Two (false) compiler warnings about variables potentially + being used uninitialized, and one about a variable being + set but not used. + https://bugzilla.gnome.org/show_bug.cgi?id=759192 + +2016-02-01 13:02:13 +0000 Tim-Philipp Müller + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipostproc.c: + * tests/simple-encoder.c: + * tests/test-filter.c: + vaapi: fix 'ISO C90 forbids mixed declarations and code' compiler warnings + Declare variables at the beginning of a code block, which + is how it's done in GStreamer. + https://bugzilla.gnome.org/show_bug.cgi?id=759192 + +2016-01-28 14:21:04 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Fix crop rectangle setting + Align with software vp9dec behaviour: Add crop rectangle + only if display_width/display_height is less than the + frame_hdr->width/frame_hdr->height + +2016-01-27 08:56:45 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Fix renegotiation for resolution change + Always renegotiate the pool if the immediate frame which going + to be pushed has a different un-cropped resolution than the already + configured one. + +2016-01-29 15:51:49 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.h: + plugins: use the same pre-processor macro + In gstvaapipluginbase.c we are using the macro USE_GST_GL_HELPERS to guard the + code related with GstGL. Nonetheless, in gstvaapipluginbase.h we are using + HAVE_GST_GL_GL_H macro in order to include the GstGLContext's header. + We should use only one to be homogeneous. This patch sets USE_GST_GL_HELPERS + in the header file. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-29 18:06:29 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: update a deprecated function + Somehow this didn't show up earlier, but gst_adapter_prev_timestamp() got + deprecated since GStreamer 1.0. + This patch replace it with gst_adapter_prev_pts() + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-29 13:13:56 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: honor configure's cache + The user might enable --config-cache when calling configure script. If so, our + configuration variables will not be correctly calculated. + This patch extracts the value of our variables either from the cache or from + the operation result. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-28 19:12:13 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: use common version variables + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-28 19:01:43 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: hard-code an unneeded macro + That macro is required for EGL's dynamic module loading, but since + gstreamer-vaapi doesn't creates dynamic modules, it is not required anymore. + That code in gst-libs/gst/vaapi/gstvaapidisplay_egl.c should be removed. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-28 17:14:51 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: refactorization of dependency tracking + This patch tries to avoid branching in configure.ac using a more functional + approach in macros usage. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-29 12:34:30 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: check for OpenGL either GLX or EGL are requested + Refactor some code in configure.ac to centralize $enable_opengl definition. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-28 16:55:44 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: indent and add square braces + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-28 16:50:39 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: upgrade autotools version dependency + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-29 11:14:34 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: enhance string comparisons + Add a 'x' as a prefix in string comparisons to watch out for edge cases where + the string is empty or undefined. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-28 14:29:16 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: remove unused variables + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-27 19:00:51 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: remove check for old version of gstreamer + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-27 17:55:02 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: remove GStreamer's parsers checks + This patch removes almost all the parsers check since they are already in place, + with the exception of the VP9 parser, since it was merged in Gstreamer 1.7. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-29 12:11:17 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + * gst/vaapi/Makefile.am: + build: add gstreamer-pbutils dependency + This dependency was added in gstvaapidecodebin with the call + gst_missing_element_message_new(). + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-27 17:53:59 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: fix variable declaration + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-27 17:47:32 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/Makefile.am: + build: fix when HEVC decoder is disabled + This a very pathological situation: when we have a HEVC encoder but not a HEVC + decoder. + The encoder needs functions that are only available when the decoder is + enabled. + This patch moves the utils functions into the generic sources, such as the + rest of the utils. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-27 17:20:31 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/Makefile.am: + build: remove unused EGL specific sources + These Makefile variables are not used at all. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-27 17:19:32 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/Makefile.am: + build: remove check for GStreamer 1.2 + Since we are working for current stable GStreamer 1.6 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-26 11:49:40 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiparse.h: + Remove more video parser crufts + This header is not used anymore since it declares parsers that are + already in GStreamer 1.6 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-25 12:43:15 +0000 Tim-Philipp Müller + + * configure.ac: + * docs/reference/Makefile.am: + * docs/reference/libs/Makefile.am: + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-overrides.txt: + * docs/reference/libs/libs-sections.txt: + docs: remove library documentation which is non-public now + https://bugzilla.gnome.org/show_bug.cgi?id=759192 + +2016-01-25 12:40:49 +0000 Tim-Philipp Müller + + * Makefile.am: + * configure.ac: + * debian.upstream/Makefile.am: + * debian.upstream/changelog.in: + * debian.upstream/compat: + * debian.upstream/control.in: + * debian.upstream/copyright: + * debian.upstream/gstreamer-vaapi-doc.install.in: + * debian.upstream/gstreamer-vaapi.install.in: + * debian.upstream/rules: + Remove debian.upstream packaging + https://bugzilla.gnome.org/show_bug.cgi?id=759192 + +2016-01-22 19:27:13 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst/vaapi/gstcompat.h: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapisink.c: + Remove old gst version guards + As gstreamer-vaapi now only supports from GStreamer 1.6, this patch removes + all the old GStreamer version guards. + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-22 19:23:43 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiparse.c: + Remove video parser crufts + We forgot to remove gstvaapiparse.c when we removed all the videoparser + machinery. + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-12-09 19:52:33 +0100 Víctor Manuel Jáquez Leal + + * docs/reference/libs/Makefile.am: + * docs/reference/plugins/Makefile.am: + * gst-libs/gst/vaapi/Makefile.am: + * gst/vaapi/Makefile.am: + * tests/Makefile.am: + libs: remove versioning + Since we don't install libraries anymore, it makes no sense to keep + versioning them according to the gstreamer's version. + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-12-09 16:59:16 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + * debian.upstream/Makefile.am: + * debian.upstream/control.in: + * debian.upstream/libgstvaapi-dev.install.in: + * debian.upstream/libgstvaapi-drm.install.in: + * debian.upstream/libgstvaapi-glx.install.in: + * debian.upstream/libgstvaapi-wayland.install.in: + * debian.upstream/libgstvaapi-x11.install.in: + * debian.upstream/libgstvaapi.install.in: + * gst-libs/gst/vaapi/Makefile.am: + * tests/Makefile.am: + libs: make libraries no installables + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-12-09 15:37:39 +0100 Víctor Manuel Jáquez Leal + + * debian.upstream/libgstvaapi-dev.install.in: + * gst-libs/gst/vaapi/Makefile.am: + Do not install libgstvaapi headers + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-19 10:40:54 +0200 Sreerenj Balachandran + + * Makefile.am: + * configure.ac: + * patches/Makefile.am: + * patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch: + * patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch: + * patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch: + * patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch: + * patches/videoparsers/0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch: + * patches/videoparsers/0006-h265parse-include-gstvaapiparse.h.patch: + * patches/videoparsers/0007-h265parse-fix-build-with-GStreamer-1.5.patch: + * patches/videoparsers/Makefile.am: + * patches/videoparsers/series.frag: + Remove videoparser patches + +2015-12-09 15:18:11 +0100 Víctor Manuel Jáquez Leal + + * Makefile.am: + * configure.ac: + * debian.upstream/libgstvaapi-dev.install.in: + * pkgconfig/Makefile.am: + * pkgconfig/gstreamer-vaapi-drm.pc.in: + * pkgconfig/gstreamer-vaapi-glx.pc.in: + * pkgconfig/gstreamer-vaapi-wayland.pc.in: + * pkgconfig/gstreamer-vaapi-x11.pc.in: + * pkgconfig/gstreamer-vaapi.pc.in: + Remove pkg-config files + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-12-09 13:24:30 +0100 Víctor Manuel Jáquez Leal + + * .gitmodules: + * Makefile.am: + * configure.ac: + * ext/Makefile.am: + * ext/codecparsers: + * gst-libs/gst/Makefile.am: + * gst-libs/gst/codecparsers/Makefile.am: + * gst-libs/gst/vaapi/Makefile.am: + * gst/vaapi/Makefile.am: + Remove codecparsers submodule + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-12-08 00:36:36 +0200 Sreerenj Balachandran + + * .gitmodules: + * autogen.sh: + * configure.ac: + * debian.upstream/libgstvaapi.install.in: + * ext/Makefile.am: + * ext/libvpx/Makefile.am: + * ext/libvpx/gstlibvpx.c: + * ext/libvpx/gstlibvpx.h: + * ext/libvpx/libgstcodecparsers_vpx.vers: + * ext/libvpx/sources.frag: + * ext/libvpx/upstream: + * gst-libs/gst/codecparsers/Makefile.am: + * gst-libs/gst/codecparsers/gstvaapilibvpx.c: + Remove libvpx submodule + We will be using upstream codecparsers always. + No more internal libvpx ! + +2015-12-09 14:12:22 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + build: fix check for GstJpegParser + Right now the local JPEG parser is always compiled because the check for the + upstreamed version is broken: it looks for an non existent symbol: + GstJpegImage. + This patch changes that check for< GstJpegFrameHdr. + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-10-28 09:56:46 +0100 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: free the frame in frame_release_callback() + This basically reverts 62c3888b76afc69f714a020957e8c5dd9d98f561 (wayland: + decouple wl_buffer from frame). + Otherwise the frame may be overwritten while it is still used by the + compositer: + The frame done callback (frame_done_callback()) is called, when the + compositor is done processing the frame and hands it to the hardware. + The buffer release callback (frame_release_callback()) is called when the + buffer memory is no longer used. + This can be quite some time later: E.g. if weston (with the DRM backend) + puts the buffer on a hardware plane, then then buffer release callback is + called when the kernel is done with the buffer. This is usually when the + next frame is shown, so most likely after the frame done callback for the + next frame! + Since 70eff01d36a2870cbf06ffb91c2a941e8cb6b804 "wayland: sync() when + destroy()" the mentioned possible leak should no longer be a problem, so + reverting this change should cause no leaking buffers. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=758848 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-01-14 17:36:24 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: check ANY caps at transform_caps() + When transforming downstream caps we should check for ANY caps from peer pad, + otherwise we get a segmentation fault. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=759893 + +2016-01-13 19:17:02 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: ignore frame if its upload failed + When gst_vaapi_plugin_base_get_input_buffer() fail to copy the input buffer + into a VAAPI buffer, the return value is GST_FLOW_NOT_SUPPORTED, and it was + ignored by the vaapisink, leading to a segmentation fault. + This patch ignores the frame that generated the GST_FLOW_NOT_SUPPORTED + returned by gst_vaapi_plugin_base_get_input_buffer(), avoiding the + segmentation fault, but doing and effort to continue rendering. This is + the same behavior of ximagesink. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=759332 + +2015-12-09 18:24:50 +0200 Joel Holdsworth + + * configure.ac: + build: Don't ignore GST_PLUGIN_PATH_1_0 even if the directory doesn't exist yet + https://bugzilla.gnome.org/show_bug.cgi?id=759184 + +2015-12-08 16:14:11 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h: + Add 10 HEVC 10 bit decoding support + Only supporting vaapidecode ! vaapisink combination for now. + Missing dependencies: + 1: No support for P010 video format in GStreamer + 2: No support for P010 vaGetImage()/vaPutimage() in vaapi-intel-driver + 3: As a result of 1&2 , we have no support for Vaapi Video memory mapping + through GstVideoMeta. + Right now we only set chroma format (YUV420 with more than 8 bits per channel) + for surface pool and keeping GST_VIDEO_FORMAT as ENCODED. The underlying format + of the surfaces is implementation (driver) defined, which is P010. + +2001-01-01 04:59:28 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + gstvaapisurfacepool: Add new API to create surface pool based on chroma type + This new API gst_vaapi_surface_pool_new_with_chroma_type() is for + creating a new GstVaapiVideoPool of GstVaapiSurfaces with the specified + chroam type and dimensions. The underlying format of the surfaces is + implementation (driver) defined. + +2015-12-07 19:06:28 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + Add definitions for YUV420 with more than 8 bits per channel + +2015-12-07 17:26:24 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + gstvaapiporfile: Fix string representation of HEVCMain10 profile + +2015-12-07 16:17:11 +0200 Sreerenj Balachandran + + * configure.ac: + Bump version for development + +=== release 0.7.0 === + +2015-12-07 12:52:10 +0200 Sreerenj Balachandran + + * configure.ac: + 0.7.0 + +2015-12-07 12:49:05 +0200 Sreerenj Balachandran + + * NEWS: + NEWS: Updates + +2015-12-07 12:47:04 +0200 Sreerenj Balachandran + + * AUTHORS: + AUTHORS: Update + +2015-12-07 12:39:23 +0200 Sreerenj Balachandran + + * README: + README: Update + +2015-11-26 10:34:12 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapitexture_glx.c: + texture: detect GL version and use the proper API + When receiving the texture from the application or the video sink, we must + know it size and border. To query the texture the API has changed according to + the OpenGL version used in the GL context of the application/vsink. + This patch checks the current context API type and queries the texture + according to this detected API. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=753099 + +2015-11-26 10:19:32 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapitexture_glx.c: + texture: check for expected target and format + gst_vaapi_texture_glx_new_wrapped() only handles a GL_TEXTURE_2D target and + formats GL_RGBA or GL_BGRA. + This patch adds a debugging verification of those values. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=753099 + +2015-11-26 10:26:10 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + libs: add gl3_bind_texture_2d() + Since OpenGL3.1 removed the fixed pipelines[1] enabling 2D textures is not + needed. In particular, the Intel's Mesa implementation complains if it is + called. + This patch add a new binding function for 2D textures, without enabling + gl3_bind_texture_2d()[2]. + 1. https://www.opengl.org/wiki/Fixed_Function_Pipeline + 2. https://www.opengl.org/wiki/Common_Mistakes#OOP_and_hidden_binding + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=753099 + +2015-11-26 10:14:45 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + libs: add gl_get_current_api() + In order to know which OpenGL API use, we must detect the API type of current + context. This patch adds the function gl_get_current_api() which returns the + OpenGL API type. + This function is an adaptation of gst_gl_context_get_current_gl_api() from + GstGL. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=753099 + +2015-11-27 12:29:11 +0200 Sreerenj Balachandran + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + build: Add gmodule dependency for libgstvaapi_egl + https://bugzilla.gnome.org/show_bug.cgi?id=756259 + +2015-11-27 14:24:55 +0200 Sreerenj Balachandran + + * patches/videoparsers/0005-h265parse-include-gstvaapiparse.h.patch: + * patches/videoparsers/0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch: + * patches/videoparsers/0006-h265parse-fix-build-with-GStreamer-1.5.patch: + * patches/videoparsers/0006-h265parse-include-gstvaapiparse.h.patch: + * patches/videoparsers/0007-h265parse-fix-build-with-GStreamer-1.5.patch: + * patches/videoparsers/series.frag: + patches/videoparsers: h264: Disable passthorugh mode enabling + This is a quick fix for regression introduced by the upstream + commit e8908f5aeef952566f6bccde743c7735d3f8c6ef in h264 videoparser. + The patch is disabling the passthrough mode, otherwise it will + break multi-layer mvc stream parsing. + https://bugzilla.gnome.org/show_bug.cgi?id=758656 + +2015-11-25 15:12:53 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/Makefile.am: + * patches/videoparsers/Makefile.am: + * patches/videoparsers/series.frag: + build: add gsth265parse patches conditionally + As gsth265parse was added in GStreamer 1.4, and gstreamer-vaapi still support + GStreamer 1.2, the patching of gsth265parse must be conditional to the target + GStreamer version. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=755525 + +2015-11-25 15:11:28 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/Makefile.am: + build: declare correctly parse lib built files + This is a continuation of commit fc8a0d12 + When declaring BUILT_SOURCES, those files should not be distributed. This + patch avoids the distribution of the generated source code. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=755525 + +2015-11-24 17:14:20 +0200 Sreerenj Balachandran + + * ext/libvpx/sources.frag: + build: libvpx: Add missing source file + +2015-11-23 17:21:23 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: Correctly detect the caps change + This is a quick fix for regression introuduced by the + commit 757833230bc73b8e3b4e31649e4618ba802bea51 + With out this, the gst_vaapipostproc_create() will + never get invoked. + https://bugzilla.gnome.org/show_bug.cgi?id=758543 + +2015-11-18 20:48:30 +0100 Víctor Manuel Jáquez Leal + + * ext/libvpx/Makefile.am: + * ext/libvpx/sources.frag: + build: libvpx: update the sources lists + `make dist` broke since commit f06798 (libvpx: Update the submodule to + libvpx-1.4.0) because the sources.frag does not contain all the module + sources. + This patch updates thoroughly the sources. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=755525 + +2015-11-16 17:49:01 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: don't set caps change at first set + When the source caps change, the filter is destroyed and recreated. + Nonetheless, this happens every time the vaapipostproc starts, since the caps + change detection algorithm does not take in consideration when the caps are + set by first time. + This patch intents to be an optimization, to avoid a useless filter + destroy-creation cycle when the sources caps are set for first time. + The new helper function video_info_update() is a refactorization to avoid + duplicated code. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=758007 + +2015-11-12 16:13:25 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: params video_info_changed() callers + The signature is video_info_changed(old_vip, new_vip). Nonetheless the callers + swapped the the order. This didn't raise problems since the comparison of both + structures were not affected by its semantics. + But still it would be better to fix this to keep the coherence of the code. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=758007 + +2015-09-24 10:35:44 +0000 Víctor Manuel Jáquez Leal + + * gst/vaapi/Makefile.am: + build: declare real built files + When runnig the `make dist` target from a clean tree, it fails because + if could not find the copied files from codecparsers submodule. + They weren't copied because they weren't declared as built sources. + This patch removes the stamp mechanism and use the actual file list to copy + as the built sources. Also it fixes the duplication of the parser files. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=755525 + +2015-11-17 19:37:07 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Fix last/golden/altref frame index setting + Always fill VADecPictureParameterBufferVP9 last/golden/altref indices + based on what ever reference frame indices encoded in frame header. + +2015-08-25 16:01:51 +0000 Víctor Manuel Jáquez Leal + + * debian.upstream/rules: + debian: remove custom parallel compilation + In order to build a debian package with upstream source, the user should + do + ./autogen.sh + cp -a debian.upstream debian + debuild -eDEB_BUILD_OPTIONS="parallel=8" -us -uc -b + The environment variable DEB_BUILD_OPTIONS="parallel=8" is the canonical + way to make a parallel build (-j8 in this case). + This commit removes the script in debian/rules that detects the number of + cpus, requested by the environment variable DEBIAN_BUILD_NCPUS, which is not + official in debian. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=754087 + +2015-11-16 18:22:55 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Fix PTS calculation of cloned frames + +2015-11-16 18:22:33 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Avoid unnecessary show_frame flag checking while doing picture output + We always set GST_VAAPI_PICTURE_FLAG_SKIPPED for DECODE_ONLY frames and the + gstvaapidecoder base calss is reponsible for handling those frames later on. + No need for explicit verification of frame header's show_frame in order to + do picture outputing. + +2015-11-16 18:22:14 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Fix ref picture update while doing repeat frame + Don't try to do frame decoding and reference picture update + while receiving a vp9 frame having show_existing_frame flag + set as TRUE. + +2015-11-16 18:21:56 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Add repeat-frame display handling + If vp9 frame header come up with show_existing_frame flag set, + we should duplicate the existing decoded frame as current frame to + be displayed. + +2015-11-12 11:07:38 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: add me as element co-author + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757957 + +2015-11-12 12:47:01 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: try to get display from decoder + Rather than create a dummy display, if none has propagated as a context, we + should try to get the one from vaapidecode. + As the bin is already in READY state, the vaapidecode should be also in that + state. That means that the contexts have been negotiated, and it should have + already a display. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757957 + +2015-11-11 19:04:25 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapidecodebin.h: + vaapidecodebin: add postprocessor dynamically + The former approach to left the bin unfinished has some problems: the context + cannot be shared because the vaapidecode is unlinked in many cases, leading to + creating a VADisplay twice. + Initially the bin is fully functional, constructed as + (-----------------------------------) + | vaapidecodebin | + | (-------------) (-------) | + |<--| vaapidecode |--->| queue |--->| + | (-------------) (-------) | + (-----------------------------------) + When the context is shared and the VADisplay has VPP capabilities, before + changing to READY state, the bin is reconfigured dynamically, adding the + vaapipostproc element afeter the queue: + (--------------------------------------------------------) + | vaapidecodebin | + | (-------------) (-------) (---------------) | + |<--| vaapidecode |--->| queue |--->| vaapipostproc |--->| + | (-------------) (-------) (---------------) | + (--------------------------------------------------------) + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757957 + +2015-11-11 16:33:24 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: delay the bin configuration + Delay the bin configuration until changing to READY state. This is because we + should add the vaapipostproc element until the vaapidecode has emitted the + HAVE_CONTEXT message, so de gst_bin_add() could set the context set to + vaapipostproc. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757957 + +2015-11-13 19:39:56 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Add crop rectangle support. + Set crop rectange if: + There is display_width and display_height which is different from actual width/height + or + The changed resolution is less than the actual configured dimension of surfaces + +2015-11-13 19:23:05 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Fix the context and surface pool reset for multi resolution video + Unlike other decoders, vp9 decoder doesn't need to reset the + whole context and surfaces for each resolution change. Context + reset only needed if resolution of any frame is greater than + what actullay configured. 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. + +2015-11-13 18:58:33 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Fill the VADecPictureParameterBufferVP9 width/height from frame header + Always fill width/height of VADecPictureParameterBufferVP9 from frame header. + Preliminary fix for supproting multi resolution video decode. + +2015-11-13 18:51:27 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Add comments for corner case fixes and fix couple of indentations. + +2015-11-13 18:41:53 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Set lossless flag from frame header + +2015-11-13 18:40:52 +0200 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch d9f25 + d9f2527: codecparsers: vp9: Set lossless flag in frame header + +2015-11-11 19:16:16 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + libs: vp9: remove unused symbols + clang complains about a couple variables and one label which were not + used. This patch removes them. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757958 + +2015-11-10 19:00:22 +0200 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch da251bb + da251bb: codecparsers: vp9: Optimize the memory allocation + f5759f4: codecparsers: vp9: Fix the wrong memcpy of probability arrays + +2015-11-05 12:58:52 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugin: guard pointers to pad query functions + Since gstreamer 1.4 is not required to have pad query functions if the query + vmethods are used. + This patch guards out the pad query functions for gstreamer < 1.4 + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757629 + +2015-11-05 12:39:55 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: use pad query vmethods + GstVideoEncoder, the base class of vaapiencode, added support for pad queries + as virtual methods since gstreamer 1.4. This patch enables those vmethods, + while keeps support for previous versions of gstreamer. + This patch is relevant since GstVideoEncoder takes care of other queries that + we are currently ignoring. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757629 + +2015-10-28 13:01:04 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: return pad's template caps if no display + A caps query can occur before the element has a display. In that case, the + element can return its pad's template. But when the element already has a + display, and the caps probe fails, the element shall return an empty caps, so + the auto-plug could try with another decoder. + If the element has a display and the caps probe works, then the computed caps + should be returned. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-10-28 12:59:02 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + plugins: don't create display at caps query + Caps query can happen before the element has a bus. The display creation should + be should occur on the context negotiation, when the bus is already configured. + Then at caps query no display should be created. + Instead of force the display creation, we graciously fail the allowed_caps() + creation. + This change only applies for vaapidecode and vaapisink. The vaapipostroc, as a + basetransform descendant, seems to be not affected by this, nor the encoders. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-11-04 21:38:42 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + plugins: fix context query handling + The current context query handling design is flawed: the function + gst_vaapi_reply_to_query() returns FALSE either if the query is not a + GST_CONTEXT_QUERY of if the query could not be handled correctly. But the + pad query function should handle differently each case. + This patch changes the gst_vaapi_reply_to_query() for + gst_vaapi_handle_context_query() and changes it usage in all the vaapi plugins + to match the correct context query handling. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-11-04 20:37:05 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugin: don't lose previous context at query + When processing the GST_CONTEXT_QUERY we should not lose the previous + context in the query, we should only add our display structure. + This patch copies the old context, if it is there, and stamp our display on + it. Otherwise, a new context is created. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-11-04 20:29:03 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + vaapivideocontext: add gst_vaapi_video_context_set_display() + This function set the display to an already created context. This function is + going to be used later. + Also, gst_vaapi_video_context_new_with_display() now uses this function. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-10-30 12:27:16 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + plugins: check if display is set in sync + Since the context messages are sync'ed, the display assignation happens in the + same thread, hence we can know if the display was found or not as soon we call + for it. + In order to take advantage of it, gst_vaapi_video_context_prepare() receives, + as a new parameter, the address of the plugin's display, and reports back if + the display was found and set. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-10-30 12:33:48 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapivideocontext.c: + plugins: set display through context + Instead of setting the display to the plugin directly after its creation, do + it through the gstreamer's context mechanism, avoiding double assignations. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-11-02 18:20:07 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + vaapivideocontext: rename context structure + The context structure is named "display" which is too generic. The contrary + happens, for example, with GstGL, what uses the same name as the context, and + its logs make more sense. + This patch renames the context structure with the same name as the + context, thus GST_PTR_FORMAT can pretty print it. + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-11-04 19:02:34 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + vaapivideocontext: refactor gst_vaapi_video_context_prepare() + First, refactorized run_context_query() into _gst_context_run_query(), adding + a new parameter: the pad direction, in order to simplify the code. + Second, added a new helper function: _gst_context_query(), which is a generic + context query function. It isolates the operation of running the query and + sets the context if found, also it enhances the logs. + _gst_context_query() is similar to the one used in GstGL. Perhaps, in the + future this helper function will be merged into the core libraries of + GStreamer. + Finally, gst_vaapi_video_context_prepare() was rewritten to use + _gst_context_query(). + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-10-30 11:18:47 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + vaapivideocontext: refactor context category debug + Refactor the extraction GST_CAT_CONTEXT logging using a only once + initializator, so we could get the debug category from different code + paths, safely. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-10-23 11:17:01 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + gstvaapivideocontext: fix indentation + gst-indent does not handle correctly some expression like function + declaration with attributes, breaking the following expressions. + This patch makes gst-indent to ignore the attributed function + declartion so the followed function definition is not mangled, such + as happened in commit b4154a + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-11-02 16:48:27 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugin: chain up set_context() vmethod + Since Gstreamer 1.7, set_context() vmethod needs to be chained up with + the parent class in order to broadcast all its contexts when the element + is added into a bin: + http://cgit.freedesktop.org/gstreamer/gstreamer/commit/?id=d5ded1588920c4471eefe055d09095d9e5e989b5 + There is no need to guard the call, because before GStreamer 1.7, the + set_context() vmethod was NULL in the element class, hence the conditional + call make it safe. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757598 + +2015-11-06 10:20:34 +0100 Víctor Manuel Jáquez Leal + + * tests/simple-encoder.c: + tests: simple-encoder: remove dead code + The caps creation for codec state configuration is not used. Let's remove it. + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-11-02 19:05:07 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: fix a leaked display instance + The display returned by gst_vaapi_video_context_get_display() increments the + references. Thus, we have to unref the returned display. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757595 + +2015-11-04 16:50:44 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + libs: remove unneeded headers + Since gstvaapidisplay_glx.h do not expose gl.h/glx.h structures, it is not + required to include them in the header. It is not also required to include + them in gstvaapidisplay_glx.c, since gstvaapiutils_glx.h includes them and + exposes their structures (e.g. GLXPixmap). + Nonetheless, glext.h neither glxext.h are required to include, they are + already included conditionally by gl.h and glx.h, respectively. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757577 + +2015-11-06 19:18:54 +0200 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch 0ea6792 + 0ea6792: codecparsers: vp9: Add header comments + 347ffc7: codecparsers: vp9: Use g_slice_free() for releasing memory allocated from the slice allocator + +2015-11-06 15:19:38 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + VP9: plugins: Add VP9 decoder + +2015-11-06 15:12:51 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.h: + VP9: libgstvaapi: Add VP9 decoder + +2015-11-06 14:57:00 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + VP9: gstvaapiprofile: Add profile definitions + +2015-11-06 14:39:22 +0200 Sreerenj Balachandran + + * configure.ac: + VP9: build: Check availability of vp9 decoder APIs + +2015-11-06 14:24:08 +0200 Sreerenj Balachandran + + * configure.ac: + * ext/Makefile.am: + * gst-libs/gst/codecparsers/Makefile.am: + VP9: Allow building vp9 codecparser internally + +2015-11-06 12:38:46 +0200 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch commit ac5dc1a + ac5dc1a: codecparsers: vp9: Add vp9 codec parser + e7d9217: codecparser: h264: initialize parsing structures + 403d400: codecparser: h265: initialize parsing structures + +2015-11-04 15:37:34 +0100 Víctor Manuel Jáquez Leal + + * configure.ac: + configure.ac: don't use an undefined variable + If the environment lacks of gstreamer development packages, this error will + be reported to the user: "gstreamer- was not found" + This is because we are using an undefined variable in the printed message. The + fix simple changes the variable for the hard-coded string "1.0". + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=757283 + +2015-10-16 15:55:40 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: relax guards for memory:VASurface capsfeature + Though caps features are supported since GStreamer 1.2, there are some + issues with the features caps negotiation in that version. Nonetheless, + those issues are fixed in GStreamer 1.4. So, the memoy:VASurface caps + feature negotiation is relaxed for GStreamer 1.4. + The guard is the same as in vaapisink's caps template. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=756686 + +2015-10-15 18:18:36 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: decide allocation doesn't update srccaps + The received caps query will bring the already negotiated caps, so they are + not expected to change. + This patch removes this verification which is dead code path. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=756686 + +2015-10-14 20:30:30 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + vaapidecode: use caps to check the features + Instead of calling gst_vaapi_find_preferred_caps_feature(), which is + expensive, we check the caps from the allocation query, to check the + negotiated feature. + In order to do this verification a new utility function has been implemented: + gst_vaapi_caps_feature_contains(). + As this new function shared its logic with gst_caps_has_vaapi_surface(), both + have been refactorized. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=756686 + +2015-10-14 20:22:43 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: set format before decide allocation + There is a regression from commit 3d8e5e. It was expected the buffer pool + allocation occur before the caps negotiation, but it is not. + This patch fixes this regression: the caps negotiation is done regardless the + allocation query from downstream. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=756686 + +2015-10-16 20:21:50 +0800 Lim Siew Hoon + + * configure.ac: + build: check for patch and fix yasm check + Add configure checking for GNU patch tools and fixed configure + checking YASM to correct sequence. + Signed-off-by: Lim Siew Hoon + https://bugzilla.gnome.org/show_bug.cgi?id=756690 + +2015-10-15 19:20:21 +0300 Sreerenj Balachandran + + * ext/libvpx/Makefile.am: + build: Remove disable-md5 option for libvpx build + The configure option --disable-md5 was provided in libvpx-1.3.0 which + has been removed in 1.4.0. + +2015-10-15 19:00:26 +0300 Sreerenj Balachandran + + * ext/libvpx/upstream: + libvpx: Update the submodule to libvpx-1.4.0 + libvpx git commit: c74bf6d889992c3cabe017ec353ca85c323107cd + +2015-10-15 10:59:08 +0300 Sreerenj Balachandran + + * configure.ac: + configure: mark support for GStreamer 1.2 as obsolete. + Support for GStreamer 1.2 is obsolete. i.e. it is no longer supported. + Our goal is to support the last two stable versions of GStreamer which + are 1.4 and 1.6 at the moment. + We still keep the 1.2 specific codes until the next gstreamer-vaapi-0.7 + release and will get rid of those in 0.8. + +2015-10-12 14:13:03 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Fix buffer copy assertion + Don't try to copy the NULL buffer-codec_data. + +2015-09-28 14:57:33 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + build: allow builds against GStreamer 1.7.x + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-09-23 16:02:46 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstcompat.h: + gstcompat: add gst_buffer_copy_deep() if gst < 1.5 + gst_buffer_copy_deep() was added in GStreamer 1.5. If want to use it we should + add an implementation if gstreamer-vaapi is linked to previous versions. + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-09-23 12:13:41 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: simplify copy of GstVideoCodecState + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-09-14 19:21:08 +0200 Víctor Manuel Jáquez Leal + + * patches/videoparsers/0006-h265parse-fix-build-with-GStreamer-1.5.patch: + * patches/videoparsers/series.frag: + patches/videoparsers: h265parser: more API fences + Add more API fences according with its version and refresh the patch. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=754845 + +2015-09-14 19:19:56 +0200 Víctor Manuel Jáquez Leal + + * patches/videoparsers/0001-h265parse-include-gstvaapiparse.h.patch: + * patches/videoparsers/0005-h265parse-include-gstvaapiparse.h.patch: + * patches/videoparsers/series.frag: + patches/videoparsers: h265parser: rename patch keeping number + Refresh the patch and rename it in order to keep the patch number. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=754845 + +2015-09-14 19:18:33 +0200 Víctor Manuel Jáquez Leal + + * patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch: + patches/videoparsers: h264parser: more API fences and refresh + Add more API fences according with its version and refresh the patch. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=754845 + +2015-09-14 19:16:51 +0200 Víctor Manuel Jáquez Leal + + * patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch: + * patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch: + * patches/videoparsers/series.frag: + patches/videoparsers: h264parser: fix description and refresh + Fix a typo in the patch description and refresh it in order to avoid the + creation of .orig files and break the distcheck target. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=754845 + +2015-09-14 19:15:18 +0200 Víctor Manuel Jáquez Leal + + * patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch: + * patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch: + patches/videoparsers: h264parser: refresh patches + In order to avoid the creation of .orig files and break the distcheck target. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=754845 + +2015-09-15 16:53:31 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/Makefile.am: + build: link libgstvaapi_parse against codec parser + GST_CODEC_PARSER_* variables are defined if builtin codec parsers are disabled + when running configure. + Right now, libgstcodecparsers links only to libgstvaapi, but libgstvaapi_parse + need it if builtin codec parsers are disabled. + This patch adds GST_CODEC_PARSER_* variables to libgstvaapi_parse + compilation. If builtin codec parsers are enable, this variable is null, so it + should work using libgstvaapi, as normal. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=754845 + +2015-09-11 16:35:30 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + build: verify for H264 MVC and H265 SPS + Currently the H264 and H265 parsers look for MVC and SPS respectively, and + the required symbols for those were added in GStreamer 1.5 + If we try to compile in GStreamer < 1.4, without enabling the builtin codec + parsers, the compilation fails, because the lack of those symbols. + This patch verifies if the installed H264 and H265 parsers have those symbols. If + they do not, the specific built in codec parsers are enabled and used. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=754845 + +2015-09-11 16:49:16 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: initialize PPS's slice_group_id + When the GstVaapiParserInfoH264 is allocated, the memory is not initialized, + so it contains random data. + When gst_h264_parser_parse_pps() fails, the PPS structure keeps slice_group_id + pointer uninitialized, leading to a segmentation fault when the memory is + freed. + This patch prevents this by initializing the slice_group_id before the PPS + parsing. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=754845 + +2015-09-15 11:01:29 +0300 Mark Nauwelaerts + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: proper numerator and denominator for forced latency framerate + https://bugzilla.gnome.org/show_bug.cgi?id=755040 + +2015-09-11 20:51:42 +0300 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch commit f9e284b + dae1a84: h264parse/h265parse: Fix negotiation crash + 45a9f8a: codecparsers: h265 : Fix default scaling list values + 28eaaf5: codecparsers: h265: Fix the selection of Active Ref Pic Set + Signed-off-by: Sreerenj Balachandran + +2015-09-04 22:19:55 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Don't flush dpb for EOS/EOB nal + Explicit flushing of dpb for EOS and EOB nal decoding is wrong, + the dpb_add() itself will handle the flusing(if needed) of dpb + for end of sequence and end of bitstream. + https://bugzilla.gnome.org/show_bug.cgi?id=754010 + +2015-09-04 22:11:10 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Fix the dpb_add() based on C.5.2.3 + Follow the spec as it is in C.5.2.3, add the decoded frame to dpb + just after the PicLatencyCnt setting of existing dpb frames. + https://bugzilla.gnome.org/show_bug.cgi?id=754010 + +2015-09-04 22:02:55 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Fix the picture addition in dpb() based on spec H265 v3 (04/2015) + This fix is based on the V3 vesion of spec which was missing in older versions. + When the current picture has PicOutputFlag equal to 1, for each picture in the + DPB that is marked as "needed for output" and follows the current picture in output order, + the associated variable PicLatencyCount is set equal to PicLatencyCount + 1 (C.5.2.3). + https://bugzilla.gnome.org/show_bug.cgi?id=754010 + +2015-09-04 22:00:36 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: h265: Fix indentation + +2015-06-13 01:39:31 +1000 Jan Schmidt + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.c: + multiview: initial attempt at stereo/multiview support + Add support for marking caps and buffers for multiview or + stereoscopic output. + https://bugzilla.gnome.org/show_bug.cgi?id=750835 + +2015-08-28 17:12:12 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: remove unused functions + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=754250 + +2015-08-31 13:11:54 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: remove (another) unused variable + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-08-28 17:10:40 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: remove unused variable + Thus silence the compilation warnings. + +2015-08-28 16:06:08 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: compilation fix + gst_vaapi_decoder_state_changed() returns void. This patch fixes the + compilation where the toolchain uses restrictive flags as clang. + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-08-29 00:27:05 +0300 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: renegotiate if caps are not equal + The use of gst_caps_is_always_compatible() for this optimization may lead to + false positives. It is better to stick to gst_caps_is_strictly_equal() to know + if it is required a re-negotiation. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=750835 + +2015-08-29 00:18:57 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: Rework the re-negotiation code to handle multi resoultion videos + Delaying the pool re-negotiation untill we push all decoded (and queued) + frames downstream. Otherwise for the multi-resolution videos, the + GstVideoVideoMemory will be having wrong resolution and which leads + to nasty behaviours, especially when using software renderers. + sample media file: RAP_B_Bossen_1.bin + case explained: + The first SPS Nal will report resoultion of 448x256 and having crop rectangles to + get the final resoultion 416x240. + Starting from 25 th frame, the resolution will change to 416x240. But parser + elements won't report this since the effective croped resolution is same in + both cases. Here the core libgstvaapi will detect this through it's internal + parsing and do all context/pool destory/reset stuffs. Also it will notify this + change to plugins in advance. But if the plugin try to do re-negotiaion of pool + immediately, this will not sync with the resolution of already decoded and queued + frames and which will lead to failure in gst_video_frame_map() in downstream(if we use the + software renderer). So we have to delay the pool renegotiation in vaapidecode, + untill we push all decoded frames downstream. + https://bugzilla.gnome.org/show_bug.cgi?id=753914 + +2015-08-28 23:43:47 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Always keep a copy of input codec state + Currently we are sharing the input GstVideoCodecState with + GstVaapiDecoder(gst-libs/gst/vaapi) by just doing ref and unref for + each caps change. This is troublesome in many cases, for eg: if + resoultion changes with in a singe stream. Because, when ever there + is a resolution change, GstVideoDecoder will first change the Codec_state->caps + fields with new resolution, but since we are using the same codecstate (ref) + in gstvaapidecode.c, the caps check for input caps change will always fail. + https://bugzilla.gnome.org/show_bug.cgi?id=753914 + +2015-08-26 07:25:03 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Fix the scaling list scan order + The default scan order of scaling lists are up-right-diagonal + as per hevc specification. Use the newly implemented + uprightdiagonal_to_raster conversion codecparser APIs to + get the the scaling_list values in raster order, which is + what the VA intel driver requires. + +2015-08-26 07:20:09 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: sync with the codecparser changes + The Tile Scanning Conversion process (spec 6-3 and 6-4) is implemented + in codecparsers now. Remove the duplication from gstvaapidecoder_h265 + +2015-08-26 07:04:22 +0300 Sreerenj Balachandran + + * patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch: + patches/Videoparsers: update patch to fix build with older GStreamer 1.2 stacks + +2015-08-26 06:57:36 +0300 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch commit 69550f1 + c207c6d: codecparsers: h265: Fix tile row and column parsing + 47074c5: codecparsers: h265: Add APIs for up-right-diagonal/raster scan conversion + cd28b18: codecparsers: h265: Fix the range of delta_chroma_log2_weight_denom + 1746bbe: videoparsers: Use gst_base_parse_merge_tags() + 2f0932b: h264parse: Clear SPS info after processing + f57d6b0: videoparsers: enable accept-template flag + +2015-08-25 15:38:42 +0000 Víctor Manuel Jáquez Leal + + * debian.upstream/control.in: + debian: add yasm as build dependency + As the compilation of libvpx (for vp8 parser) is enabled by default, + yasm is required by default too. + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-08-14 19:21:04 +0800 Lim Siew Hoon + + * debian.upstream/rules: + debian: remove --with-gstreamer-api option + It is no longer valid in gstreamer-vaapi. + Signed-off-by: Lim Siew Hoon + [removed unused GST_API_VERSION variable] + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=753618 + +2015-08-24 19:22:14 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: rename is_cancelled to sync_failed + Since commit 065a18a3, the semantics of the variable is_cancelled did not make + sense. This commit renames this variable to sync_failed. + +2015-08-13 15:12:44 -0400 Olivier Crete + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: Don't return GST_FLOW_ERROR on flushing + Setting the sink to flushing causes gst_vaapi_window_wayland_sync() to + return FALSE which makes gst_vaapi_window_wayland_render() return + FALSE which ends up posting an ERROR message in + gst_vaapisink_show_frame_unlocked(). Solution is to just return TRUE + in the EBUSY case. + https://bugzilla.gnome.org/show_bug.cgi?id=753598 + +2015-08-06 12:28:51 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + Revert "Marking rank of vaapidecodebin as GST_RANK_MARGINAL for now." + This reverts commit 3ccb198b513dc6ad287fe44117d03bec4d6a966a. + +2015-07-06 20:22:57 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: check for postproc instance + If the VPP's deinterlace-method is set, first we should check if the postproc + is already instanced to set it. Otherwise we just store it until the VPP is + added into the bin. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=749554 + +2015-08-06 18:48:13 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + vaapidecodebin: ensure VPP before going to READY + There are sometimes that the VA-API display context is not shared among the + pipeline, but it is important to know it before going to READY state (when the + pipeline is already linked). + One instance of this case is this: + gst-launch-1.0 filesrc location=media ! decodebin ! vaapipostproc ! vaapisink + This patch adds a new function in gstvaapipluginutil called + gst_vaapi_create_test_display(). Its purpose is to create a disposable VA-API + display, which only will be used for verify if the VAEntrypointVideoProc is + available by the hardware. Afterwards, it should be unrefed. + If the vaapidecodebin is going to READY state, and the element still doesn't + know if VPP is available, the last resort is to create a new instance of the + VA-API display and test for it. + https://bugzilla.gnome.org/show_bug.cgi?id=749554 + +2015-08-06 12:39:52 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: post an error message if fails + If the construction of the bin fails, post an error message in the bus. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=749554 + +2015-08-06 12:36:07 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapidecodebin.h: + vaapidecodebin: has_vpp as a tri-state variable + has_vpp can be UNKNOWN while the context message hasn't being received. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=749554 + +2015-08-03 16:33:02 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + gstvaapivideomemory: native format with no derived image + If USE_NATIVE_FORMATS is defined we bail out before configuring the surface + info based on the derived image configuration. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=744042 + +2015-07-23 20:07:59 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + * gst/vaapi/gstvaapivideomemory.c: + surface pool config based on video info + First added the function gst_vaapi_video_format_get_best_native(), which + returns the best native format that matches a particular chroma type: + YUV 4:2:0 -> NV12, YUV 4:2:2 -> YUY2, YUV 4:0:0 -> Y800 + RGB32 chroma and encoded format map to NV12 too. + That format is used to configure, initially, the surface's pool for the + allocator. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=744042 + +2015-07-23 16:03:43 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + gstvaapivideomemory: refactor gst_vaapi_video_allocator_new() + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=744042 + +2015-06-19 15:51:07 +0200 Victor Jaquez + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + gstvaapiencoder: validate chroma according to the VA's RT format + Before, only YUV420 color space where supported. With this patch, the + encoder is queried to know the supported formats and admits YUV422 + color space if its available. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=744042 + +2015-08-13 05:07:52 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Add calculation of WpOffsetHalfRangeC + This is necessary for finding ChromaOffsetL0/ChromaOffsetL1 + prediction weight table values with out using any hard coding. + Fixme: We don't have parser API for sps_range_extension, so + assumed zero value for high_precision_offsets_enabled_flag. + Signed-off-by: Sreerenj Balachandran + +2015-08-13 04:09:44 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Fix ChromaOffsetL0/ChromaOffsetL1 calculation + Based on ITU-T rec H265(4/2015): 7-56 + This was a wrong equation in rec H265 (4/2013): 7-44... + Signed-off-by: Sreerenj Balachandran + +2015-08-13 04:08:03 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Fix default value assignment of pred_weight_table + +2015-08-13 03:48:43 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Fix the value assigning for delta_chroma_log2_weight_denom + Assign only if ChromaArrayType != 0.. + Signed-off-by: Sreerenj Balachandran + +2015-08-13 03:06:32 +0300 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch commit 1c70432 + 8e98b41: codecparsers: h265: Fix the range of delta_chroma_log2_weight_denom + 839c5bc: codecparsers: h265: Fix the parsing of ref_pic_lists_modification + Signed-off-by: Sreerenj Balachandran + +2015-08-11 08:09:10 +0300 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch commit c18b8ad + 8a03e67: videoparsers: h265: Avoid skipping of EOS and EOB nals + a033083: videoparsers: h265: Fix the frame start detection code + Signed-off-by: Sreerenj Balachandran + +2015-08-10 05:50:50 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Add SEI parsing + Signed-off-by: Sreerenj Balachandran + +2015-08-07 08:43:44 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Workaround to recognize wrongly encoded main profile streams + HACK: This is a work-around to identify some main profile streams having wrong profile_idc. + There are some wrongly encoded main profile streams(eg: ENTP_C_LG_3.bin) which doesn't + have any of the profile_idc values mentioned in Annex-A, instead general_profile_idc + has been set as zero and having general_profile_compatibility_flag[general_profile_idc] + is TRUE. Assuming them as MAIN profile for now. + https://bugzilla.gnome.org/show_bug.cgi?id=753226 + Signed-off-by: Sreerenj Balachandran + +2015-08-07 08:41:57 +0300 Sreerenj Balachandran + + * patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch: + patches/videoparsers: Fix the wrong source file path + This is something wrongly typed in commit 6d7b631 + +2015-08-07 08:34:55 +0300 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch commit b8d8be4 + ee7e81b: h264parse: Don't discard first AU delimiter + 3690fb9: h264parse: Add more NAL types for debugging output + 108d368: h265parse: Avoid checking for Non Mandatory VPS NAL + ace61048: h265parse: expose compatible profiles to downstream + Signed-off-by: Sreerenj Balachandran + +2015-08-06 13:07:53 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + gstvaapivideocontext: remove unused parameter + gst_vaapi_video_context_prepare() received an unused parameter. This patch + removes it and the structure passed by the caller. + This a left over of "Removal of gstreamer-1.0 support" (commit 8b36e25f). + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-08-06 04:01:24 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Fix decoding of stream when it has temporal sublayers + We are calculating the dpb size based on max_dec_pic_buffering. + But if there are more than one temporal sublayers, we are supposed + to use the max_dec_pic_buffering[max_sub_layers_minus] for dpb + size calculation (Assuming HighestTid as max_sub_layers_minus). + Sample streams: TSCL_A_VIDYO_5.bin, TSCL_B_VIDYO_4.bin + https://bugzilla.gnome.org/show_bug.cgi?id=753226 + Signed-off-by: Sreerenj Balachandran + +2015-08-05 14:11:12 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + refactor vaapi caps strings for pad templates + Refactor the main vaapi caps strings into three macros: + GST_VAAPI_MAKE_SURFACE_CAPS, GST_VAAPI_MAKE_ENC_SURFACE_CAPS and + GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS. + Those are in gstvaapipluginutil.h so all the elements could use them, instead + of re-declaring them every time. + No functional changes. + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-08-05 14:15:07 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + gstvaapipostproc: fix code style + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-08-05 05:23:20 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Fix the decoding of dependent slice segment + Decoding process for reference picture list construction needs to be + invoked only for P and B slice and the value for slice_type of dependent slice + segment should be taken from the previous independent slice segment header + of the same pic. + https://bugzilla.gnome.org/show_bug.cgi?id=753226 + Signed-off-by: Sreerenj Balachandran + +2015-06-22 17:38:41 +0200 Victor Jaquez + + * gst/vaapi/gstvaapipluginbase.c: + plugins: reduce the noise of warnings + Those messagse should be attached to the object, also the lack of + caps is not an error, in particular in the case of JPEG encoding. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=744042 + +2015-06-23 17:49:51 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + gstvaapicontext: fix the JPEG encoder attribs value + When we query for the VAConfigAttribEncJPEG, we get a value which packs the + VAConfigAttribValEncJPEG structure, but we did not assign it. This patch + assigns the returned value to the attribute. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=744042 + +2015-06-18 17:37:46 +0200 Victor Jaquez + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + gstvaapiencoder: framerate 0/1 is valid too + Framerate 0/1 is valid, and it is particularly useful for picture + encoding, such as jpeg. This patch makes the encoder to admit that + framerate. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=744042 + +2015-07-03 09:35:16 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostroc: GLTextureUploadMeta in sink template + Advertise GLTextureUploadMeta in sink caps template. + https://bugzilla.gnome.org/show_bug.cgi?id=752130 + +2015-07-23 13:11:40 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapiuploader.h: + remove gstvaapiuploader + Working on bug #744042 I realized that the gstvaapiuploader is practically not + used. + This patch removes the gstvaapiuploader and add the method + gst_vaapi_plugin_base_get_allowed_raw_caps () that returns the raw caps that + the system can handle, which is used by vaapisink and vaapipostproc. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=752777 + +2015-07-27 18:49:13 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: don't lost GLTextureUpload on seek + When seeking, the decoder is reset, but the buffer pool is not + re-negotiated, but in reset_full() the code forgets if the negotiated buffer + pool has the GLTextureUpload meta. + The decoder knows that GLTextureUpload meta was negotiated in + decide_allocation(), but this method is not called when seeking. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=752929 + +2015-07-21 18:45:56 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: don't use gst_pad_get_allowed_caps() + gst_pad_get_allowed_caps() query the pad and the peer pad. In the case + decoders, that is OK, but in the case of the postproc might lead loops, + since the gst_base_transform_query_caps() forwards the query upstream + and forth. + Instead of gst_pad_get_allowed_caps() we only query the peer with + gst_pad_peer_query_caps() using the pad's template as filter. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=752558 + +2015-07-22 12:40:19 +0300 Sreerenj Balachandran + + * README: + README: updates + +2015-07-22 09:45:26 +0300 Sreerenj Balachandran + + * patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch: + * patches/videoparsers/series.frag: + patches/videoparsers: h264parse: Disable 3D video support for GStremaer < 1.5 + All API/ABI changes for S3D/MVC are added in 1.5, backporting + them to older verison is not recommended. + Signed-off-by: Sreerenj Balachandran + +2015-07-22 09:41:34 +0300 Sreerenj Balachandran + + * patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch: + patches/Videoparsers: update patch to fix build with older GStreamer 1.2 stacks + +2015-07-22 09:38:42 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + decoder: jpeg: Align with new API/ABI changes in codecparser + Signed-off-by: Sreerenj Balachandran + +2015-07-22 09:31:02 +0300 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch commit 800bdb2 + ed13220: mpegvideometa: add meta transform function + 18d5efd: codecparsers: jpeg: add some padding to ScanHdr struct + 7a51722: codecparsers: jpeg: fix docs for table parsing functions + 06b8ded: codecparsers: jpeg: fix validity checking of data parsed + 387a39d: codecparsers: jpeg: fix up API + db9d6a9: codecparsers: jpeg: tweak API a little + bb6951e: codecparsers: jpeg: hide gst_jpeg_scan_for_marker_code() + f33c30c: codecparsers: jpeg: fix and optimize scan for next marker code + 4658c30: codecparsers: jpeg: fix calculation of segment size + 759bcb9: codecparsers: jpeg: fix default Huffman tables generation + b4811ee: codecparsers: jpeg: add JPEG bitstream parser + 9422464: h264parse: fix typo in log message + 9e793a0: h264parse: Move PAR calcs, and use them for stereoscopic half-aspect + 77704ce: nalutils: trivial patch to check if + 8bb9249: codecparsers: mpeg4: actually return full number of bits of resync marker + 7862f95: Revert "codecparsers: remove ignored increment of return" + 54017b1: h264parse: Add support for passing stereoscopic/multiview info + 8667ee4: h264parse: Don't switch to passthrough on set_caps() + Signed-off-by: Sreerenj Balachandran + +2015-06-29 14:27:56 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: track previous reference frames. + Improve closure of gaps in frame_num by strictly following and trying + to fill them with previous reference frames. So, they are now tracked + thus avoiding insertion of dummy ("greenish") frames. + +2015-06-29 13:16:09 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix integration of second field into the DPB. + If the new picture to be added to the DPB is not a first field, then + it shall be the second field of the previous picture that was added + before. + This removes the need for dpb_find_picture() now that we track the + immediately preceding decoded picture, in decode order. + +2015-07-06 14:38:26 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix closure of "other-field" gap. + When a dummy "other-field" is inserted, it is assumed to inherit the + reference flags from the first field, and the sliding window decoded + reference picture marking process is also executed so that corrupted + frames are moved out as early as possible. + While doing so, we also try to output frames that now contain a single + valid field picture, prior to inserting any other picture into the DPB. + Note: this may be superfluous currently based on the fact that dpb_add() + combines the two most recent pairable fields, but this process would be + further simplified later on. + +2015-06-24 13:58:17 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: track corrupted frames. + Mark the picture as "corrupted" if it is reconstructed from corrupted + references or if those references are fake, e.g. resulting from lost + frames. + This is useful for notifying the upper layer, or downstream elements, + that the decoded frame may contain artefacts. + https://bugzilla.gnome.org/show_bug.cgi?id=703921 + +2015-06-24 13:48:46 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst/vaapi/gstvaapidecode.c: + decoder: add initial infrastructure for marking corrupted output. + Add initial infrastructure in core codec library and vaapidecode to mark + corrupted frames as such. A corrupted frame is such a frame that was + reconstructed from invalid references for instance. + https://bugzilla.gnome.org/show_bug.cgi?id=751434 + Signed-off-by: Gwenole Beauchesne + +2015-07-15 18:18:49 +0300 Sreerenj Balachandran + + * configure.ac: + Bump version for development + +=== release 0.6.0 === + +2015-07-15 15:49:38 +0300 Sreerenj Balachandran + + * configure.ac: + 0.6.0 + +2015-07-15 15:49:19 +0300 Sreerenj Balachandran + + * NEWS: + NEWS: updates + +2015-07-14 19:39:20 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + vaapidecoder: no wmv profiles gstreamer 1.4/1.2 + This patch fix the auto-plugging problem in gstreamer 1.2 and gstreamer 1.4 + Right now there is not a primary ranked parser for vc1 and the demuxers + delivers caps without specifying the profile. This situation is not an issue + for avdec_vc1 but for vaapidecode it is, which refuses to negotiate without a + explicit profile defined in the negotiated caps. + Nonetheless, in gstreamer 1.5 it seems not to be a problem since the + negotiation admits caps subsets try outs. + This patch solves the issue ignoring the profile negotiation in the caps. For + gstreamer < 1.5 the profile string is not handled, so the auto-plugging get + done without the vc1 parser, such as happens in gstreamer 1.5. + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-07-07 20:57:20 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapi.c: + Marking rank of vaapidecodebin as GST_RANK_MARGINAL for now. + Unfortunately vaapidecodebin element is not seems to be stable + enough for autoplugging ahead of vaapidecode. + Lowering the rank for now (cosidering the immediate 0.6 release). + See this: https://bugzilla.gnome.org/show_bug.cgi?id=749554 + Signed-off-by: Sreerenj Balachandran + +2015-07-07 13:32:18 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + build: Add missing CFLAGS to Makefile.am + +2015-07-03 15:07:02 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapifilter.c: + gstvaapifilter: Only register STE property if it supported by corresponding VA library + Fix the regression introduced in commit eb465fb. + VAProcFilterSkinToneEnhancement is avaialbe from VA >= 0.36. + Signed-off-by: Sreerenj Balachandran + +2015-07-02 17:49:25 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: no format convert on GL tex upload meta + When GL texture upload meta is negotiated, vaapipostproc shall not modify the + color format of the buffer. + https://bugzilla.gnome.org/show_bug.cgi?id=748184 + +2015-07-03 12:42:09 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapifilter.c: + gstvaapifilter: Add guard for VAProcFilterSkinToneEnhancement + VAProcFilterSkinToneEnhancement is avaialbe from VA >= 0.36. + Signed-off-by: Sreerenj Balachandran + +2015-07-02 21:57:38 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + encoder:h265: Fix the check for packed-header support + Use VA_ENC_PACKED_HEADER_* definition for checking. + Signed-off-by: Sreerenj Balachandran + +2015-07-02 21:37:56 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder:h264: Fix the check for packed-header support + Use VA_ENC_PACKED_HEADER_* definition for checking. + Signed-off-by: Sreerenj Balachandran + +2015-07-02 21:00:14 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: submit SEI buffering_period() and picture_timing() messages for CBR mode + One buffering_period() SEI message shall be present in every IDR access unit + when NalHrdBpPresentFlag is inferred to be equal to 1. This is the case when we + use a non-CQP mode, e.g. CBR. In other words, when + nal_hrd_parameters_present_flag is set to 1. + One picture_timing() SEI messages shall be present in every access unit + if CpbDpbDelaysPresentFlag is equal to 1 or pic_struct_present_flag is equal to 1 + https://bugzilla.gnome.org/show_bug.cgi?id=722734 + https://bugzilla.gnome.org/show_bug.cgi?id=751831 + Signed-off-by: Sreerenj Balachandran + +2015-07-01 14:16:50 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: notify if vpp is disabled + When the system is aware that VPP is not available by the VA driver, + it would be useful to notify to the user that the disable-vpp property + has changed. + https://bugzilla.gnome.org/show_bug.cgi?id=749554 + +2015-07-01 14:17:17 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapidecodebin.h: + vaapidecodebin: enable vpp if it is available + Instead of creating and adding VPP into the bin at setup, we wait until + we are sure the VA driver supports it. We know that when the VA video + context is received by the bin. Afterwards, it is decided to instanciate + and link the VPP or not. + This is more efficient and safer than waiting the VPP to fail and then + disable it. + https://bugzilla.gnome.org/show_bug.cgi?id=749554 + +2015-07-02 12:29:32 +0300 Sreerenj Balachandran + + * tests/test-display.c: + * tests/test-windows.c: + tests: Fix compilation while enabling egl as the only renderer in build + Include missing header files gstvaapidisplay_egl.h and gstvaapiwindow_egl.h. + +2015-07-02 10:45:50 +0300 Sreerenj Balachandran + + * configure.ac: + configure: fix the build while enabling egl as the only renderer + +2015-07-02 10:25:25 +0300 Sreerenj Balachandran + + * configure.ac: + libs: Bump library major version + +2015-06-30 09:44:18 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideometa.c: + gst/vaapi: Switch to upstreram like indentation. + gst-indent for all gst/vaapi/*.c source files + +2015-06-30 09:35:37 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapidecodebin.h: + vaapidecodebin: Add property to disable VPP + Adding a new propery "disable-vpp", enabling it will prevent + the insertion of vaapipostproc child element. + This is helpful in debugging, specifically to narrow-down the + vaapidecodebin/vaapipostproc related negotiation issues. + No support for run-time disabling for now. + https://bugzilla.gnome.org/show_bug.cgi?id=745901 + +2015-06-29 13:35:59 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: Fix wrong selection of passthrough mode. + The Current code path is falling back to passthorugh mode if there is no + vpp property set by the user explictily. But we should not use the + passthrough mode if the negotiated src pad caps have a differnt color space + format than sink pad caps (Even though the user didn't set the format property + explicitly). + https://bugzilla.gnome.org/show_bug.cgi?id=748184 + Signed-off-by: Sreerenj Balachandran + +2015-06-29 13:20:28 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: prevent advanced-deinterlacing of non-native video formats. + This is a workaround to deal with the va-intel-driver for non-native + formats while doing advanced deinterlacing. The format of reference surfaces must + be same as the format used by the driver internally for motion adaptive + deinterlacing and motion compensated deinterlacing. + A permanent solution could be to do the color space conversion internally + for reference surfaces. + https://bugzilla.gnome.org/show_bug.cgi?id=730925 + Signed-off-by: Sreerenj Balachandran + +2015-06-29 13:06:30 +0300 Simon Farnsworth + + * gst/vaapi/gstvaapisink.c: + Work around ABBA deadlock between vaapisink and vaapipostproc + vaapisink takes the display lock, then does a gst_buffer_replace which can + take the lock on the gst_vaapi_video_pool. + vaapipostproc asks the gst_vaapi_video_pool for a new surface. This takes + the lock on the gst_vaapi_video_pool; if you're unlucky, there are no free + surfaces, which means that gst_vaapi_surface_create is + called. gst_vaapi_surface_create takes the display lock. + If vaapisink and vaapipostproc are in different threads, and this happens, + you get a deadlock. vaapisink holds the display lock, and wants the + gst_vaapi_video_pool lock. vaapipostproc holds the gst_vaapi_video_pool lock + and wants the display lock. + Work around this by releasing the display lock in vaapisink around the + gst_buffer_replace. + https://bugzilla.gnome.org/show_bug.cgi?id=738249 + Signed-off-by: Simon Farnsworth + Signed-off-by: Sreerenj Balachandran + +2015-04-29 16:34:07 +0200 Jacobo Aragunde Pérez + + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapidecodebin.h: + vaapidecodebin: expose deinterlace-method property from inner vaapipostproc + https://bugzilla.gnome.org/show_bug.cgi?id=745901 + +2015-05-19 11:24:10 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: log negotiated caps + +2015-05-18 14:30:22 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: remove useless debug message + +2015-02-12 12:31:57 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: log negotiated src/sink caps + +2015-05-07 15:57:26 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: error handling if rendering fails + This patch enhance the code path when an error is found when rendering a + buffer. + If the video meta doesn't contain a surface proxy or a surface, a warning + message is printed. + If the rendering backend fails, a error message is posted in the bus. + https://bugzilla.gnome.org/show_bug.cgi?id=749382 + +2015-06-18 14:55:12 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapisink.c: + vaapisink: Fix the conditional pad template creation. + +2015-06-18 13:19:26 +0300 Sreerenj Balachandran + + * tests/Makefile.am: + build: Don't build simple-encoder test program if there is no VA Encoding support + This will fix the build error against older VA-APIs <= 0.32 + +2015-06-18 12:20:37 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapicompat.h: + Fix build error for older VA-API versions + Provide guards for VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM and + VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME which are only availble from + VA >= 0.36. + +2015-06-17 14:20:37 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapisink.c: + vaapisink: Fix the capsfeature advertisement in padtemplate + This fixes the regression introduced in 64acc74. + If a pad supports multiple set of capsfeatures, it needs to add + multiple equal structures with different feature sets to the caps. + Because caps structures with the same name but with a non-equal + set of caps features are not compatible. + Without this patch, playbin will autoplug xvimagesink instead of vaapisink. + https://bugzilla.gnome.org/show_bug.cgi?id=750095 + +2015-06-17 12:41:28 +0300 Adrian Cox + + * gst/vaapi/gstvaapisink.c: + vaapisink: Expose the overlay capability for compatibility with dvbsuboverlay. + https://bugzilla.gnome.org/show_bug.cgi?id=750095 + Signed-off-by: Sreerenj Balachandran + Signed-off-by: Gwenole Beauchesne + +2015-06-17 09:53:29 +0300 Olivier Crete + + * gst/vaapi/gstvaapipluginbase.c: + vaapipluginbase: Override downstream allocation reply if no pool + If the downstream replied without a pool, then override it. + https://bugzilla.gnome.org/show_bug.cgi?id=748559 + +2015-06-09 15:15:31 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: add color balance interface + https://bugzilla.gnome.org/show_bug.cgi?id=720376 + +2015-05-22 18:13:25 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: add skin tone enhancement + Added the 'skin-tone-enhancement' property to vaapostproc. + https://bugzilla.gnome.org/show_bug.cgi?id=744088 + +2015-05-20 18:02:37 +0200 Víctor Manuel Jáquez Leal + + * docs/reference/libs/libs-docs.xml.in: + doc: add VA-API reference in freedesktop + +2015-06-04 19:03:44 +0200 Víctor Manuel Jáquez Leal + + * patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch: + * patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch: + * patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch: + patches/videoparsers: rebase all the h264parse patches + In order to avoid the creation of .orig files and break the distcheck target + +2015-06-04 18:29:15 +0200 Víctor Manuel Jáquez Leal + + * ext/libvpx/Makefile.am: + build: don't build in parallel libvpx + This fixes the distcheck -j XX target. + +2015-06-02 08:52:53 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + encoder: jpeg: Fix the packed header generation + This is a work-around to satisfy the va-intel-driver. + Normalize the quality factor and scale QM values (only for packed header + generation) 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. + https://bugzilla.gnome.org/show_bug.cgi?id=748335 + Signed-off-by: Sreerenj Balachandran + +2015-06-02 11:46:00 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix uninitialized variables in avcC mode. + Fix uninitialized variables when decoding SPS and PPS NAL units from + "codec-data" buffers. This is particularly important when seeking ops + are involved, and the new persistent states are used more often. + https://bugzilla.gnome.org/show_bug.cgi?id=750094 + +2015-06-01 18:39:18 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: remove unneeded casting + And a code-style fix + +2015-05-21 19:38:33 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: calculate decoding latency + This is a naïve approach to the calculation of the VA-API decoding latency. It + takes into consideration when the frame-rate has some insane value. + https://bugzilla.gnome.org/show_bug.cgi?id=740419 + +2015-05-21 23:16:14 +1000 Jan Schmidt + + * configure.ac: + configure: Compiling against libgstgl requires libgstvideo + Fix detection of the GstGL helper headers in uninstalled + builds. + +2015-05-28 10:52:48 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + encoder: hevc: Fix the size over-flow for encoded buffer. + The approximation of 6 times compression ratio migh not + work in all cases. Especially when enabling I frames. + Provide large enough size for coded-buffer creation. + +2015-05-28 10:43:20 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + encoder: vp8: Fix the size over-flow for encoded buffer. + The approximation of 4 times compression ratio will not + work in all cases. Especially when enabling I frames. + Provide large enough size for coded-buffer creation. + +2015-05-28 05:43:49 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + encoder: hevc: fix bug in multi slice encoding. + This is a work-around for satisfying the VA-Intel driver. + The driver only support slices begin from CTU row start address. + Multi-Slice encoding also requires a fix in va-intel-driver: + http://lists.freedesktop.org/archives/libva/2015-May/003351.html + https://bugzilla.gnome.org/show_bug.cgi?id=749854 + Signed-off-by: Sreerenj Balachandran + +2015-03-12 22:57:22 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: add initial support for loss of pictures. + Implement decoding process for gaps in frame_num (8.5.2). This + also somewhat supports unintentional loss of pictures. + https://bugzilla.gnome.org/show_bug.cgi?id=745048 + https://bugzilla.gnome.org/show_bug.cgi?id=703921 + Original-patch-by: Wind Yuan + [fixed derivation of POC, ensured clone is valid for reference, + actually fixed detection of gaps in FrameNum by PrevRefFrameNum] + Signed-off-by: Gwenole Beauchesne + +2015-05-22 11:42:52 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: add support for missing first field. + Try to identify missing first fields too, thus disregarding any + intermediate gaps in frames. We also assume that we keep the same + field sequence, i.e. if previous frames were in top-field-first + (TFF) order, then so are subsequent frames. + Note that insertion of dummy first fields need to operate in two + steps: (i) create the original first field that the current field + will inherit from, and (ii) submit that field into the DPB prior + to initializing the current (other) field POC values but after any + reference flag was set. i.e. copy reference flags from the child + (other field) to the parent (first field). + https://bugzilla.gnome.org/show_bug.cgi?id=745048 + +2015-05-07 14:00:58 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: add support for missing second field. + Interlaced H.264 video frames always have two fields to decode and + display. However, in some cases, e.g. packet loss, one of the field + can be missing. This perturbs the reference picture marking process, + whereby the number of references available in DPB no longer matches + the expected value. + This patch adds initial support for missing field within a decoded + frame. The current strategy taken is to find out the nearest field, + by POC value, and with the same parity. + https://bugzilla.gnome.org/show_bug.cgi?id=745048 + +2015-05-22 17:06:11 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: improve tracking of "top-field-first" flag. + Try to maintain a "top-field-first" (TFF) flag, even if the H.264 standard + does not mandate it. This will be useful for tracking missing fields, and + also for more correct _split_fields() implementation for frames in the DPB. + +2015-05-05 11:56:11 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: skip all pictures prior the first I-frame. + Don't try to decode pictures until the first I-frame is received within + the currently active sequence. There is no point is decoding and then + displaying frames with artifacts. + +2015-05-12 15:36:10 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix processing of EOSEQ NAL. + Fix decoding of end_of_seq() NAL unit so that to not submit the current + picture for decoding again. This is pretty vintage code that dates back + before the existing of the whole decoder units machinery. + One issue that could be arising if that code was kept is that we could + have submitted a picture, and subsequently a GstVideoCodec frame, twice. + Once without the decode_only flag set, and once with that flag set. The + end result is that the GstVideoDecoder would release the codec frame + twice, thus releasing stale data. + In short, the piece of code that is removed by this patch is for once + completely obsolete for a while, and secondly error-prone in corner + cases. + +2013-02-28 15:26:36 +0800 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + decoder: add utility function to clone picture objects. + https://bugzilla.gnome.org/show_bug.cgi?id=703921 + Signed-off-by: Wind Yuan + [added cosmetic changes, fixed propagation of "one-field" flag to + children, fixed per-codec clone modes (h264)] + Signed-off-by: Gwenole Beauchesne + +2015-05-27 23:49:18 +0300 Alban Browaeys + + * gst/vaapi/Makefile.am: + build: don't compile HEVC encoder if not supported + Fix: + (gst-plugin-scanner:16681): GStreamer-WARNING **: Failed to load plugin '/usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstvaapi.so': /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstvaapi.so: undefined symbol: gst_vaapi_encoder_h265_get_default_properties + https://bugzilla.gnome.org/show_bug.cgi?id=749954 + Signed-off-by: Alban Browaeys + Signed-off-by: Sreerenj Balachandran + +2015-05-27 23:43:16 +0300 Alban Browaeys + + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + HEVC: decode: add missing va_dec_hevc header + Signed-off-by: Alban Browaeys + Signed-off-by: Sreerenj Balachandran + https://bugzilla.gnome.org/show_bug.cgi?id=749953 + +2015-05-26 13:28:32 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix PTS cache for GOP start. + If the GOP temporal sequence number (TSN) is interpolated from a valid + PTS, then we need to compensate that PTS corresponding to the start of + GOP with the next picture to be decoded, which shall be an I-frame, + based on its sequence number. + https://bugzilla.gnome.org/show_bug.cgi?id=748676 + +2015-05-27 10:49:56 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: avoid crash when seeking with debug logs + Move down the debug message when the state of the decoder is verified + so the slice header is not NULL. + +2014-12-17 00:41:10 +1100 Jan Schmidt + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: Avoid crashes and warnings on re-opened decoder after a seek + Reset state and add some checks for safe state to avoid a crash and + a warning after the decoder is destroyed/recreated during a seek. + +2015-05-26 10:21:59 +0300 Sreerenj Balachandran + + * patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch: + * patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch: + * patches/videoparsers/series.frag: + patches/videoparsers: Rebase the patch on top of gst-vaapi-branch commit 20ee952 + Signed-off-by: Sreerenj Balachandran + +2015-05-26 10:03:20 +0300 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch commit 20ee952 + b7dded3: h264parse: don't consider unknown stream-format as avc + 5110ad9: h264parse: fix up handling of input caps corner cases + e51db3e: h264parse: Remove dead code + 3d739d0: codecparser: h265: Fix the number of tile rows/columns parsing + 8482957: h265parse: Fix profile, tier and level setting in caps + 4649acb: h265parse: Fix the memory freeing of stored VPS nals + f2beeb7: h265parse: Fix source caps to report cropped dimensions + 6886a31: h264parse: Fix profile and level setting in caps + 5286c1a: h264parse: Consider SEI NALU as "HEADER" packets + eb97854: videoparsers: h264: bit-exact sync with upstream, minor changes here and there + 53074fc: build: Upgrade GStreamer dependency to 1.0 + Signed-off-by: Sreerenj Balachandran + +2015-05-26 06:01:10 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + HEVC: decode: Replace clip3 implementation with glib CLAMP macro + Signed-off-by: Sreerenj Balachandran + +2015-05-26 05:33:33 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + HEVC: decode: Update Cropping Rectangle + Signed-off-by: Sreerenj Balachandran + +2015-05-25 11:58:20 +0300 Sreerenj Balachandran + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_h265.h: + HEVC_Encode: Add HEVC(h265) Encoder plugin + https://bugzilla.gnome.org/show_bug.cgi?id=748874 + Signed-off-by: Sreerenj Balachandran + +2015-05-25 11:38:34 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + HEVC_Encode: Add HEVC(h265) encoder to core libgstvaapi + https://bugzilla.gnome.org/show_bug.cgi?id=748874 + Signed-off-by: Sreerenj Balachandran + +2015-05-25 11:26:14 +0300 Sreerenj Balachandran + + * configure.ac: + HEVC_Encode: build: Check availability of VA APIs for H265 encoding. + Signed-off-by: Sreerenj Balachandran + https://bugzilla.gnome.org/show_bug.cgi?id=748874 + +2015-05-25 10:58:52 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.h: + gstvaapiutils_h265: Add H265 Tier specific utility functions + -- New API: gst_vaapi_utils_h265_get_tier_from_string() + -- New API: gst_vaapi_utils_h265_get_tier_string() + https://bugzilla.gnome.org/show_bug.cgi?id=748874 + Signed-off-by: Sreerenj Balachandran + +2015-05-19 10:57:42 +0200 Víctor Manuel Jáquez Leal + + * docs/reference/plugins/Makefile.am: + doc: conditional linking for scanner + Add x11 library only if it is enabled. + https://bugzilla.gnome.org/show_bug.cgi?id=749018 + +2015-05-19 10:37:13 +0200 Víctor Manuel Jáquez Leal + + * docs/reference/plugins/plugins.types: + doc: fix scanner compilation warning + https://bugzilla.gnome.org/show_bug.cgi?id=749018 + +2015-05-06 16:19:23 +0200 Víctor Manuel Jáquez Leal + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + doc: update sections and symbols + https://bugzilla.gnome.org/show_bug.cgi?id=749018 + +2015-05-13 10:38:24 +0200 Víctor Manuel Jáquez Leal + + * .gitignore: + * Makefile.am: + * debian.upstream/Makefile.am: + * docs/Makefile.am: + * docs/reference/Makefile.am: + * docs/reference/libs/Makefile.am: + * docs/reference/plugins/Makefile.am: + * ext/Makefile.am: + * ext/libvpx/Makefile.am: + * git.mk: + * gst-libs/Makefile.am: + * gst-libs/gst/Makefile.am: + * gst-libs/gst/base/Makefile.am: + * gst-libs/gst/codecparsers/Makefile.am: + * gst-libs/gst/vaapi/Makefile.am: + * gst/Makefile.am: + * gst/vaapi/Makefile.am: + * patches/Makefile.am: + * patches/videoparsers/Makefile.am: + * pkgconfig/Makefile.am: + * tests/Makefile.am: + build: use git.mk + This patch handles dinamically the gitignore files with git.mk[1]. + Removed the automake variable MAINTAINERCLANFILES in most of the + Makefile.am files since now it is handled by the top one. + 1. https://github.com/behdad/git.mk/blob/master/git.mk + https://bugzilla.gnome.org/show_bug.cgi?id=749321 + +2015-05-07 11:28:15 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: sync() when destroy() + Before pushing a the new frame, the render() method calls sync() to flush the + pending frames. Nonetheless, the last pushed frame never gets rendered, leading + to a memory leak too. + This patch calls sync() in the destroy() to flush the pending frames before + destroying the window. + Also a is_cancelled flag is added. This flag tells to not flush the event + queue again since the method failed previously or were cancelled by the user. + https://bugzilla.gnome.org/show_bug.cgi?id=749078 + +2015-05-07 15:55:40 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst/vaapi/gstvaapisink.c: + vaapisink: implement unlock/unlock_stop for wayland + Otherwise wl_display_dispatch_queue() might prevent the pipeline from + shutting down. This can happen e.g. if the wayland compositor exits while + the pipeline is running. + Changes: + * renamed unlock()/unlock_stop() to unblock()/unblock_cancel() in gstvaapiwindow + * splitted the patch removing wl_display_dispatch_queue() + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=747492 + https://bugzilla.gnome.org/show_bug.cgi?id=749078 + +2015-05-07 12:33:34 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: wl_display_dispatch_queue() can block forever. + wl_display_dispatch_queue() might prevent the pipeline from shutting + down. This can happen e.g. if the wayland compositor exits while the + pipeline is running. + This patch replaces it with these steps: + - With wl_display_prepare_read() all threads announce their intention + to read. + - wl_display_read_events() is thread save. On threads reads, the other + wait for it to finish. + - With wl_display_dispatch_queue_pending() each thread dispatches its + own events. + wl_display_dispatch_queue_pending() was defined since wayland 1.0.2 + Original-patch-by: Michael Olbrich + * stripped out the unlock() unlock_stop() logic + * stripped out the poll handling + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=749078 + https://bugzilla.gnome.org/show_bug.cgi?id=747492 + +2015-05-07 18:30:33 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: rename frame for last_frame + Since frame in the private data means the last frame sent, it would + semantically better use last_frame. + Also, this patch makes use of g_atomic_pointer_{compare_and_exchange, set}() + functions. + https://bugzilla.gnome.org/show_bug.cgi?id=749078 + +2015-05-07 11:18:12 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: use a counter as sync flag + Wayland window has a pointer to the last pushed frame and use it to set the + flag for stopping the queue dispatch loop. This may lead to memory leaks, + since we are not keeping track of all the queued frames structures. + This patch removes the last pushed frame pointer and change the binary flag + for an atomic counter, keeping track of number of queued frames and use it for + the queue dispatch loop. + https://bugzilla.gnome.org/show_bug.cgi?id=749078 + +2015-05-07 10:36:17 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: decouple wl_buffer from frame + This patch takes out the wayland's buffer from the the frame structure. The + buffer is queued to wayland and destroyed in the "release" callback. The + frame is freed in the surface's "done" callback. + In this way a buffer may be leaked but not the whole frame structure. + - surface 'done' callback is used to throttle the rendering operation and to + unallocate the frame, but not the buffer. + - buffer 'release' callback is used to destroy wl_buffer. + Original-patch-by: Zhao Halley + * code rebase + * kept the the event_queue for buffer's proxy + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=749078 + +2015-05-14 16:22:36 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix indentation + +2015-05-13 11:54:01 +0200 Víctor Manuel Jáquez Leal + + * debian.upstream/Makefile.am: + * ext/libvpx/Makefile.am: + * gst-libs/gst/vaapi/Makefile.am: + * gst/vaapi/Makefile.am: + * tests/Makefile.am: + build: fix make distcheck + This patch fixes several issues found when running the `make distcheck` + target: + - In commit c561b8da, the update of gstcompat.h in Makefile.am was + forgotten. + - In commit c5756a91 add the simple_encoder_source_h in EXTRA_DIST was + forgotten. + - vpx.build.stamp is not generated at all, only vpx.configure.stamp. + - The make target distcleancheck failed because some autogenerated files + were not handled with the DISTCLEANFILES variable. + Note: `make distcheck -jXX` is not currently supported. + +2015-05-13 13:28:17 +0200 Víctor Manuel Jáquez Leal + + * patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch: + * patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch: + * patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch: + h264parse: update patches with upstream + These patches didn't applied cleanly, breaking the `make distcleancheck` + target. Re-sync'ed the patches against the current git's submodule. + +2015-05-12 16:04:33 +0200 Gwenole Beauchesne + + * tests/simple-encoder.c: + tests: simple-encoder: fix build warnings on 64-bit platforms. + Add a cosmetic change to replace VAAPI buffer with VA buffer and most + importantly fix warnings spitted out during build on 64-bit platforms. + ../../tests/simple-encoder.c:211:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘gssize’ [-Wformat=] + g_warning ("Invalid VAAPI buffer size (%d)", size); + ^ + ../../tests/simple-encoder.c:217:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘gssize’ [-Wformat=] + g_warning ("Failed to create output buffer of size %d", size); + ^ + +2015-05-08 15:54:09 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapivideocontext.h: + plugins: remove gstreamer-0.10 crumbs + GstVideoContext was used in gstreamer-0.10, which is not supported anymore. + Still, its definition was still in the code. This patch removes it. + https://bugzilla.gnome.org/show_bug.cgi?id=749113 + +2015-05-05 13:08:25 +0200 Víctor Manuel Jáquez Leal + + * tests/Makefile.am: + * tests/simple-encoder.c: + * tests/y4mreader.c: + * tests/y4mreader.h: + tests: add simple-encoder program + This patch adds a simple-encoder test program that uses libgstvaapi for video + encoding to elementary (raw) streams. Input stream is raw YUV in the Y4M + format. That can be from a regular file or standard input when the input + filename is "-". + Usage: simple-encoder [options]* + Options: + --output|-o output file name + --codec|-c codec to use for video encoding + --bitrate|-b desired bitrate (kbps) + By default, and as an initial patch, the encoded stream shall conform to the + minimally supported profile. That is "Constrained Baseline Profile" for H.264 + and "Simple Profile" for MPEG-2. Though, those are the defaults to be + generated by libgstvaapi. + You can find Y4M sample files here http://samples.mplayerhq.hu/yuv4mpeg2/ + Original-patch-by: Changzhi Wei + * general code clean-up + * removed the yuv reader thread + * re-wrote the y4m file parser + * updated used API fixed some wrong usage + * fixed a lot of memory leaks + * added the bitrate setting + * keep fps' numerator and denominator + * simplified the thread control + * removed custom logging and use glib + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=719528 + +2015-05-05 13:02:19 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.h: + libs: trivial documentation fix + GST_VAAPI_ENCODER_STATUS_NO_SURFACE and GST_VAAPI_ENCODER_STATUS_NO_BUFFER + are not errors, so they do not have the ERROR namespace. + This patch fixes this typo in documentation. + +2015-02-15 15:01:03 +0000 Simon Farnsworth + + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + window: Correct prototype to match implementation + On s390x, guintptr and GstVaapiID are not compatible types. The + implementation of gst_vaapi_window_new_internal() and all its callers + seem to assume that its third argument is a GstVaapiID, while the + header gives it guintptr type. + https://bugzilla.gnome.org/show_bug.cgi?id=744559 + +2015-05-04 14:24:43 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + vaapidecode: add guards for disabled codecs. + Fix link when building plugin elements without HEVC support. e.g. don't + try to call into gst_vaapi_decoder_h265_set_alignment() if there is no + support HEVC enabled in libgstvaapi. + Also, drop disabled codecs from static template caps. Add the missing + HEVC static template caps into vaapidecodebin too. + +2015-04-30 13:29:48 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + * gst-libs/gst/vaapi/glibcompat.h: + build: upgrade glib dependency to 2.32 + Since bug #745728 was fixed the oldest supported version of GStreamer is + 1.2. That GStreamer release requires glib 2.32, so we can upgrade our + requirement too. + This patch changes the required version of glib in configure.ac and removes + the hacks in glibcompat.h + https://bugzilla.gnome.org/show_bug.cgi?id=748698 + +2015-04-30 13:21:08 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: check if the pool config is already set + In commit 97b768, a regression for GStreamer 1.2 was introduced: + GStreamer 1.2 doesn't check, in gst_buffer_pool_set_config() if the + config option is already set. This patch adds an inline function to + first verify if the option is not in the pool config berfore add it. + +2015-04-29 12:39:50 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: tune up a couple of log messages + In order to reduce the noise, the query type log was downgrade from INFO to + DEBUG, and the shared display address log message is assigned to the object. + +2015-04-29 12:27:43 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: check gst_buffer_pool_set_config() + Check the return value of gst_buffer_pool_set_config(). If it fails an error + message is posted in the bus. + +2015-04-29 12:24:52 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: more specific log message + Be more specific in the log message about the reason of creating a new pool. + +2015-04-29 12:22:29 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: delete unused variable + need_pool is a boolean variable extracted from the allocation query, but it is + not used afterwards. + +2015-04-27 19:21:12 -0400 Olivier Crete + + * gst/vaapi/gstvaapipluginbase.c: + vaapipluginbase: Update the pool if there was no pool in the downstream reply + Fix regression introduced by bd866479, the query after decide_allocation() + always needs a pool in the first slot. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=748559 + +2015-04-27 20:50:19 -0400 Olivier Crete + + * gst/vaapi/gstvaapivideobufferpool.c: + videopool: Free members before chaining up finalize + The finalize function in GObject frees the object memory, so + everything else needs to have been freed before. + https://bugzilla.gnome.org/show_bug.cgi?id=748563 + +2015-04-27 20:31:50 -0400 Olivier Crete + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + wayland: don't leak the registry proxy + Release the registry proxy when closing the display. + https://bugzilla.gnome.org/show_bug.cgi?id=748564 + +2015-04-21 17:17:06 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: refactor _sync() method and rename callback + This patch only intends to improve readability: in the method + gst_vaapi_window_wayland_sync() the if/do instructions are squashed into a + single while loop. + Also renames the frame_redraw_callback() callback into frame_done_callback(), + which is a bit more aligned to Wayland API. + +2015-02-03 16:52:06 +0100 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: free frame in buffer release callback + The Wayland compositor may still use the buffer when the frame done + callback is called. + This patch destroys the frame (which contains the buffer) until the + release callback is called. The draw termination callback only controls + the display queue dispatching. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=747492 + +2015-04-21 10:00:36 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: refactor gst_vaapidecode_internal_flush() + This a cosmetic refactor: gst_vaapidecode_internal_flush() removes its only + label; gst_vaapidecode_finish() is more readable and gst_vaapidecode_purge() + shares the same error message of gst_vaapidecode_internal_flush() when flush + fails. + +2015-04-20 13:27:27 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: refactor gst_vaapidecode_destroy() + Add the method gst_vaapidecode_purge(). This method releases the + flushed frames from the decoder. + This new method add more readablity to gst_vaapidecode_destroy() + +2015-04-16 12:53:18 -0400 Olivier Crete + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Tell the base class about released frames on close + The base class needs to be informed about frames that were still queued + in the decoder on release, otherwise they are leaked. + https://bugzilla.gnome.org/show_bug.cgi?id=747999 + +2015-04-19 11:19:03 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: reduce logging noise + When a frame is rejected by downstream, the message is logged twice. This + patch removes one of those logging messages. + Also, the reject of a frame doesn't mean an alarming error. This patch demotes + the log message from error to info. + +2015-04-16 20:18:13 -0400 Olivier Crete + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Use the GstVideoDecoder error reporting function + This way, the decoder won't stop on the first decoding error, + in most cases it can recover after some glitchiness. + https://bugzilla.gnome.org/show_bug.cgi?id=744620 + +2015-04-17 19:10:35 +0000 Olivier Crete + + * gst/vaapi/gstvaapipluginbase.c: + vaapipluginbase: The allocation query can return without a pool + It is possible to return the min/max/size without actually providing + a pool. This way the source knows how many buffers downstream needs. + https://bugzilla.gnome.org/show_bug.cgi?id=748076 + +2015-04-17 16:45:22 +0300 Sreerenj Balachandran + + * ext/Makefile.am: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapiparse.c: + * gst/vaapi/gstvaapiparse.h: + * patches/videoparsers/0001-h265parse-include-gstvaapiparse.h.patch: + * patches/videoparsers/series.frag: + plugins: Add h265 videoparser element "vaapiparse_h265" + This is a mirror of h265parse element in upstream gst-plugins-bad. + There could be additional patches but all should go to upstream. + This is for making development faster. + Note: vaapiparse_h265 will get build only for GStreamer version >= 1.4 + +2015-04-17 15:44:04 +0300 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch commit 43a0368 + 45f1c28: codecparser: h265: Fix nal unit size checking + f25987b: codecparser: h265: Calculate crop rectangle dimensions + 639573a: codecparser: h265: Fix parsing multiple SEI messages in a single SEI Nal + 4c8ec41: Add h265 videoparser plugin source files + +2015-04-17 10:10:10 +0200 Gwenole Beauchesne + + * autogen.sh: + autogen: drop videoutils submodule. + +2015-04-17 10:36:25 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: cosmetics. + Mostly coding style updates. Avoid integer signess inconsistencies. + Optimize dpb_find_lowest_poc() to align with original h264's decoder. + +2015-04-16 14:13:59 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Add Support for tiled video decoding + Based up on the value of uniform_spacing_flag in Picture Parameter Set, + the tile column width and tile row height should be calculated. + Equations: 6-1, 6-2 + Tiled video Descriptions: 7.3.2.3, 7.4.3.3 + +2015-04-16 14:13:21 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: hevc: Fix decoding when there are RASL pictures present. + -- Set NoRaslOutputFlag based on EOS and EOB Nal units + -- Fix PicOutputFlag setting for RASL picture + -- Fix prev_poc_lsb/prev_poc_msb calculation + -- Drop the RASL frames if NoRaslOutputFlag is TRUE for the associated IRAP picture + -- Fixed couple of crashes and added cosmetics + +2015-04-14 10:54:54 +0100 Martin Sherburn + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + display: drm: fix race condition setting device type + There is a race condition where g_drm_device_type can be left set to + DRM_DEVICE_RENDERNODES when it shouldn't. + If thread 1 comes in and falls into the last else statement setting up both + RENDERNODES and LEGACY types. And begins to process the first type (RENDERNODES), + it sets g_drm_device_type = RENDERNODES. + Now when thread 2 comes in and sees g_drm_device_type is RENDERNODES, it queues + up that type to be tried but then encounters the lock and has to wait until the + first thread finishes. Once the lock is acquired it will then proceed to ONLY try + RENDERNODES and fail it. But it doesn't try LEGACY. And from then on, all future + attempts will only try RENDERNODES. + So to avoid this situation I have simply moved the acquisition of the lock higher + up in the attached patch. + https://bugzilla.gnome.org/show_bug.cgi?id=747914 + +2015-04-15 15:26:12 -0400 Olivier Crete + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: Don't create filter on caps query + The problem with this is that creating the filter causes the display to + be selected, and the caps query happens while linking the element. So, + if the downstream or upstream element is using a specific display + object, it won't be propagated correctly to the postproc as it already + has a display at this point. + https://bugzilla.gnome.org/show_bug.cgi?id=747945 + +2015-04-15 15:20:17 -0400 Olivier Crete + + * gst-libs/gst/vaapi/gstvaapivideopool.c: + videopool: Release lock while allocating new object + The video pool can be accessed with the display lock held, for example, + when releasing a buffer from inside vaapisink_render, but allocating + a new object can may also take the display lock. Which means a possible + deadlock. + https://bugzilla.gnome.org/show_bug.cgi?id=747944 + +2015-04-15 17:26:43 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: use GstVideoSink vmethod show_frame() + vaapisink inherits from GstVideoSink, in order to use its functionality (such + as ::show-preroll-frame property), we should use its vmethod show_frame(), + rather than call ourselves render() and preroll(). + +2015-04-15 18:16:47 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: add 'handoff' signal + This patch adds the signal ::handoff and the property signal-handoffs. If the + property is set TRUE, the signal ::handoff is emitted just after the buffer is + rendered. + Based on Zhao Halley + https://bugzilla.gnome.org/show_bug.cgi?id=747905 + +2015-04-14 10:17:16 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + HEVC: silence the compiler + Fixed a couple of clang complains. + +2015-02-02 16:42:43 +0100 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: destroy vpp buffer pool on resize + Otherwise the old buffers with the old size are used. + https://bugzilla.gnome.org/show_bug.cgi?id=747491 + +2015-04-14 10:08:47 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + build: don't compile HEVC if not supported + HEVC decoding was added recently libva-1.5. + This patch avoids HEVC decoding support in libgstvaapi if it is not available + in the installed libva. + https://bugzilla.gnome.org/show_bug.cgi?id=747831 + +2015-04-13 16:04:59 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Update Author name in plugin metadata + +2015-04-13 15:43:30 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + plugins: Add HEVC decoder + Signed-off-by: Sreerenj Balachandran + +2015-04-13 15:41:45 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.h: + HEVC: Add HEVC(h265) decoder to core libgstvaapi + Signed-off-by: Sreerenj Balachandran + +2015-04-13 14:53:46 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.h: + * gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h: + HEVC: Add codec utility methods to core libgstvaapi + Signed-off-by: Sreerenj Balachandran + +2015-04-13 14:52:53 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + HEVC: gstvaapiprofile: Add profile definitions + Signed-off-by: Sreerenj Balachandran + +2015-04-13 14:52:14 +0300 Sreerenj Balachandran + + * configure.ac: + HEVC: build: Check availability of h265 decoder APIs + Signed-off-by: Sreerenj Balachandran + +2015-04-13 14:51:51 +0300 Sreerenj Balachandran + + * configure.ac: + * ext/Makefile.am: + * gst-libs/gst/codecparsers/Makefile.am: + HEVC: Allow to build h265 codecparser internally + Signed-off-by: Sreerenj Balachandran + +2015-04-08 18:05:20 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + guard buffer export API if not available + The support for buffer exports in VA-API was added in version 0.36. These + interfaces are for interop with EGL, OpenCL, etc. + GStreamer-VAAPI uses it for a dmabuf memory allocator. Though, gstreamer-vaapi + has to support VA-API versions ranging from 0.30.4, which doesn't support it. + This patch guards all the buffer exports handling (and dmabuf allocator) if + the detected VA-API version is below 0.36. + https://bugzilla.gnome.org/show_bug.cgi?id=746405 + +2015-04-13 11:29:35 +0300 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: Update to gst-vaapi-branch commit 9bc72b0 + 767bf22: codecparsers: h265: add helpers to convert quantization matrices + 71c8e93: codecparser: h265: skip byte alignment bits while parsing slice header + 3bf0355: codecparsre: h265: Fix the NumDeltaPocs calculation + 10e2087: codecparser: h265: Fix the NumPocTotalCurr calculatio + 2d753b8: codecparser: h265: Fix nal size calculation for EOS and EOB + +2014-12-11 12:02:38 +0100 Michael Olbrich + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: unref video codec frame twice + We get one reference when the frame is passed to decode_handle_frame() + and create another one in gst_vaapi_decoder_push_frame(). + Usually the frame is handled in gst_vaapidecode_push_decoded_frame(). + Here the frame is always released twice: + gst_video_decoder_finish_frame() + gst_video_codec_frame_unref() or + gst_video_decoder_drop_frame() + gst_video_codec_frame_unref(). + In gst_vaapidecode_reset_full() both references to the frame must be + released as well. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=743226 + +2015-04-08 18:20:34 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + libs: remove unused variables + clang reports these unused variables. Let's get rid of them. + This patch is a missing part of commit c82e5173 + https://bugzilla.gnome.org/show_bug.cgi?id=747312 + +2015-04-03 20:38:07 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + decoder: mpeg4: remove an spurious comparison + The member size in GstMpeg4Packet is gsize which is unsigned, which cannot be + less than zero. Hence this pre-condition test is a no-op. This patch removes + that code. + https://bugzilla.gnome.org/show_bug.cgi?id=747312 + +2015-04-03 20:33:44 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: casts slice_param->slice_type + slice_type in slice_param is defined as (char *), but it is compared against a + signed integer. clang complains about this comparison. + This patch casts the variable. + https://bugzilla.gnome.org/show_bug.cgi?id=747312 + +2015-04-03 20:31:47 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + encoder: avoid GstVaapiCodedBuffer redefinition + The symbol GstVaapiCodedBuffer is already defined in + gst-libs/gst/vaapi/gstvaapicodedbuffer.h which is loaded, at the end, by + gstvaapiencoder_objects.h. Clang complains about the symbol re-definition. + This patch removes that redefinition. + https://bugzilla.gnome.org/show_bug.cgi?id=747312 + +2015-04-03 20:28:22 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: remove unused variables + clang reports these unused variables. Let's get rid of them. + https://bugzilla.gnome.org/show_bug.cgi?id=747312 + +2015-04-03 20:27:24 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + encoder: mpeg2: use fabsf() instead of abs() + The member value in frame_rate_tab is float, the result of the abs() function + should be float too. But abs() only manages integers. + This patch replaces abs() with fabsf() to handle correctly the possible floats + values. + https://bugzilla.gnome.org/show_bug.cgi?id=747312 + +2015-04-03 20:02:29 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + decoder: cast GST_VAAPI_DECODER_STATUS_DROP_FRAME + Since GST_VAAPI_DECODER_STATUS_DROP_FRAME is not part of the enum + GstVaapiDecoderStatus, we need to cast it to avoid compiler complains. + https://bugzilla.gnome.org/show_bug.cgi?id=747312 + +2015-04-04 00:40:29 +0300 Sreerenj Balachandran + + * README: + Update README + +2015-04-04 00:06:56 +0300 Sreerenj Balachandran + + * .gitmodules: + * README: + Changing source code download links from https://gitorious to https://github + -- gitmodules: Change gstreamer-codecparsers submodule source download link + -- README: Change the gstreamer-vaapi webpage link + +2015-04-03 23:30:24 +0300 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 1f792e4 + 87f4a7e: bytereader: add gst_byte_reader_peek_sub_reader() and _get_sub_reader() + 7d8ba7a: bytereader: use unchecked inline variant for get_remaining in more places + 2528ea6: bytereader: add gst_byte_reader_masked_scan_uint32_peek + 2b92a67: h264parse: reset the parser information when caps changes + 05eee86: codecparsers: Indent file + e27a38b: codecparsers: Add READ_UE_MAX macro + 2036471: Constify some static arrays everywhere + +2015-04-03 17:45:08 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideoconverter_x11.c: + Remove the gstvaapivideoconverter_*.c source files missed in commit 51b1e4a + +2015-04-03 17:09:08 +0300 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + * gst/vaapi/gstvaapivideoconverter_glx.h: + * gst/vaapi/gstvaapivideoconverter_x11.h: + * gst/vaapi/gstvaapivideomemory.h: + * gst/vaapi/gstvaapivideometa_texture.c: + Removal of gstreamer-1.0 support + The support for GStreamer 1.0 has been obsoleted in 0.5.10 release. + GStreamer 1.2 is the a minimal requirement for building the gstreamer-vaapi. + This patch removes all the pre-processor conditional code compilation guarded + for gstreamer-1.0. + Thus, all the video converters were removed too. + https://bugzilla.gnome.org/show_bug.cgi?id=745728 + Signed-off-by: Gwenole Beauchesne + Signed-off-by: Sreerenj Balachandran + +2015-04-03 17:08:30 +0300 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstcompat.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/sysdeps.h: + * gst/vaapi/gstcompat.h: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiparse.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideoconverter_x11.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa_texture.c: + * tests/codec.c: + update and move gstcompat.h + The purpose of gstcompat.h is to couple the API differences among + gstreamer-1.0 and gstreamer-0.10. Since gstreamer-0.10 is obsolete, the code + in this compatibility layer shall be removed. + Nevertheless, the gstcompat.h header should be kept, if new incompatibilites + appear in the future, but it shall live in gst/vaapi, not in gst-libs. + This patch removes the crumbs defined gstcompat.h and moves it to gst/vaapi. + In order to avoid layer violations, gstcompat.h includes sysdeps.h and all + the includes in gst/vaapi of sysdeps.h are replaced with gstcompat.h + https://bugzilla.gnome.org/show_bug.cgi?id=745728 + Signed-off-by: Gwenole Beauchesne + Signed-off-by: Sreerenj Balachandran + +2015-04-03 17:05:45 +0300 Víctor Manuel Jáquez Leal + + * configure.ac: + * gst/vaapi/Makefile.am: + autotools: remove gstreamer-1.0 support + This patch only removes the support of gstreamer-1.0 in the autotools + scripts. No other files are touched. + In the automake file all the converters were deprecated. + https://bugzilla.gnome.org/show_bug.cgi?id=745728 + Signed-off-by: Gwenole Beauchesne + Signed-off-by: Sreerenj Balachandran + +2015-04-03 17:03:38 +0300 Sreerenj Balachandran + + * .gitmodules: + * ext/Makefile.am: + * ext/videoutils: + Remove the gstreamer-videoutils submodule + +2015-04-03 17:01:45 +0300 Víctor Manuel Jáquez Leal + + * configure.ac: + * gst-libs/gst/Makefile.am: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/video/Makefile.am: + * gst/vaapi/Makefile.am: + * tests/Makefile.am: + Remove libgstvaapi-videoutils.so + This library was intended to add the base classes for video decoders which + where not included in gstreamer-0.10. + Since the support of gstreamer-0.10 is deprecated those classes are not + required, thus the whole library is removed. + https://bugzilla.gnome.org/show_bug.cgi?id=745728 + https://bugzilla.gnome.org/show_bug.cgi?id=732666 + Signed-off-by: Gwenole Beauchesne + +2015-04-03 16:55:43 +0300 Víctor Manuel Jáquez Leal + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapicontext_overlay.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * tests/test-subpicture.c: + Remove HAVE_GST_VIDEO_OVERLAY_HWCAPS macro + This macro guarded the use of HAVE_GST_VIDEO_OVERLAY_HWCAPS, which was not + defined before gstreamer 0.10.35. Since the support of gstreamer-0.10 is + deprecated these guards are not required. + https://bugzilla.gnome.org/show_bug.cgi?id=745728 + https://bugzilla.gnome.org/show_bug.cgi?id=732666 + Signed-off-by: Gwenole Beauchesne + +2015-04-03 16:55:27 +0300 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstcompat.h: + * gst-libs/gst/vaapi/gstvaapicontext_overlay.c: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapidownload.h: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiparse.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiupload.h: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideoconverter_x11.c: + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa.h: + * tests/test-filter.c: + * tests/test-subpicture.c: + Removal of gstreamer-0.10 support + This patch removes all the pre-processor conditional code compilation guarded + for gstreamer-0.10. + https://bugzilla.gnome.org/show_bug.cgi?id=745728 + https://bugzilla.gnome.org/show_bug.cgi?id=732666 + Signed-off-by: Gwenole Beauchesne + +2015-04-03 16:54:54 +0300 Víctor Manuel Jáquez Leal + + * configure.ac: + * debian.upstream/control.in: + * gst-libs/gst/video/Makefile.am: + * gst/vaapi/Makefile.am: + autotools: remove gstreamer-0.10 support + This patch only removes the support of gstreamer-0.10 in the autotools + scripts. No other files are touched. + The configuration parameter --gstreamer-api was deleted since now it is always + auto-detected. + The verification of vmethod query in GstBaseSinkClass was removed since it was + added in gstreamer 0.10.35. The same case for GstVideoOverlayComposition and + its format flags. + The precious variable GST_PLUGIN_PATH was removed, while GST_PLUGIN_PATH_1_0 + remained. + The automake files were changed accordingly. + Removed, in debian/control, the vaapiupload and vaapidownload descriptions. + https://bugzilla.gnome.org/show_bug.cgi?id=732666 + https://bugzilla.gnome.org/show_bug.cgi?id=745728 + Signed-off-by: Gwenole Beauchesne + +2015-03-16 23:38:18 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: add drain() vmethod + In GStremer v1.6 a new vmethod drain() was added in GstVideoDecoder + class. This patch implements this new method. + https://bugzilla.gnome.org/show_bug.cgi?id=742922 + Signed-off-by: Víctor Manuel Jáquez Leal + Signed-off-by: Sreerenj Balachandran + +2015-03-16 23:37:29 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: remove vmethod reset() + Since in bug #745728 the support for GStreamer 1.0 is going to be dropped, + this patch removes the method reset() which was deprecated in GStreamer 1.2. + https://bugzilla.gnome.org/show_bug.cgi?id=742922 + Signed-off-by: Víctor Manuel Jáquez Leal + Signed-off-by: Sreerenj Balachandran + +2015-03-16 23:36:33 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: handle flush() vmethod + Since GStreamer 1.2 the vmethod reset() in GstVideoDecoderClass was deprecated + and flush() was added. + This patch set the vmethod flush() if the installed GStreamer version is 1.2 or + superior. Otherwise, reset() is set. + v2: 1) In order to avoid symbol collision, the old method gst_vaapidecode_flush() + was renamed to gst_vaapidecode_internal_flush(). + 2) The new vmethod flush() always do a hard full reset. + v3: 1) Call gst_vaapidecode_internal_flush() first in flush() vmethod, in order to + gather all collected data with gst_video_decoder_have_frame() + https://bugzilla.gnome.org/show_bug.cgi?id=742922 + Signed-off-by: Víctor Manuel Jáquez Leal + Signed-off-by: Sreerenj Balachandran + +2015-03-16 23:10:53 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: call the correct query function + In commit 2f8c115 (vaapidecode: use the query virtual methods in 1.4) + a bug was introduced: when calling the parent's query function of the + src pad, the one of the sink pad is called instead. This patch fixes + this issue. + https://bugzilla.gnome.org/show_bug.cgi?id=746248 + +2015-03-15 00:36:45 +0200 Sreerenj Balachandran + + * .gitmodules: + gitmodules: Use https:// url instead of git:// for submodules. + Gitorious is failing to clone repositories over git:// url. + +2015-03-14 22:12:19 +0200 Julien Isorce + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + vaapidisplay: mark X11 display as compatible with EGL + GST_GL_WINDOW=x11 GST_GL_API=gles2 GST_GL_PLATFORM=egl + gst-launch-1.0 ... ! vaapidecode ! glimagesink + https://bugzilla.gnome.org/show_bug.cgi?id=745902 + Signed-off-by: Víctor Manuel Jáquez Leal + +2015-03-06 15:20:01 +0200 Olivier Crete + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Don't crash if a buffer outlives the decoder + Sometimes, for example, when switching video streams but keeping + the same sink, the surface will be released after the decoder is + stopped and replaced. This caused a crash because the release + callback was called on an invalid pointer. + The patch adding an additional reference to the decoder object in the buffer. + https://bugzilla.gnome.org/show_bug.cgi?id=745189 + Signed-off-by: Olivier Crete + Signed-off-by: Sreerenj Balachandran + +2015-03-06 14:31:21 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: clean-ups (indentation, drop unused variables) + +2015-03-06 14:09:22 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: use the query virtual methods in 1.4 + GstVideoDecoder, the base class of vaapidecode, added support for + pad queries as virtual methods. This patch enables the use of that + support, while keeping support for lower versions of gstreamer. + This patch is important because GstVideoDecoder takes care of other + queries that might be important in the pipeline managing. + v2: 1) rebase to current master + 2) fix indentation with gst-indent + 3) simplify the patch layout + 4) fix the context query + 5) initialise the filter to NULL + 6) improve the query log message for gst-1.2 + https://bugzilla.gnome.org/show_bug.cgi?id=744406 + +2015-03-06 12:16:17 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: always activate buffer pool + The vaapipostproc has a proxy flag to know if the the buffer pool is + already active. But this fails in some situations where it is needed + to renegotiate the buffer pool. + This patch removes that flag so the renegotiation is done whenever is + required. + https://bugzilla.gnome.org/show_bug.cgi?id=745535 + +2015-03-02 17:04:20 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix minor memory leak in debug mode. + The gst_video_colorimetry_to_string() function returns a newly created + string that represents the GstVideoColorimetry value. So, that needs + to be released after usage, in e.g. GST_DEBUG(). + +2015-03-03 12:37:41 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecodebin.h: + vaapidecodebin: Avoid usage of "__" prefix in macro names + Avoiding "__" prefix usage in Header File Guards as per + C standard recommendation. + +2015-03-03 12:31:11 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapi.c: + plugins: Disable vaapidecodebin for GStreamer < 1.4 + There are autoplugging issues in GStreamer-1.2. + Lets disable vaapidecodebin untill we get some workarounds for this. + +2015-03-02 15:19:40 +0200 Sreerenj Balachandran + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapidecodebin.h: + plugins: Add a vaapidecodebin element + Add a "vaapidecodebin" element to vaapi plugins. + Child Elements: "vaapidecode ! queue ! vaapipostproc" + The Reasons for implementing a new bin element: + -- Help to Autoplug Hardware Accelerated Video Postprocessing element in playbin + with out any dependency to upstream gstreamer. + This is to overcome the *unacceptable* delay in upstream gstreamer to get new + features in. Eg: https://bugzilla.gnome.org/show_bug.cgi?id=687182. + Also customers using older gstreamer versions (1.2 and 1.4) will get the + benefit of autoplugging, hardware accelerated deinterlacing support etc. + -- Help to maintain a single thread implementation in vaapidecode. + This will result a dead-lock free vaapidecode in most of the cases. + More details here: https://bugzilla.gnome.org/show_bug.cgi?id=742605 + https://bugzilla.gnome.org/show_bug.cgi?id=745216 + +2015-03-02 14:59:16 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: re-indent (gst-indent) gstvaapidecode.c + +2015-03-02 14:46:38 +0200 Simon Farnsworth + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: Switch back to Single thread implementation + Because the decoder uses the thread from handle_frame() to decode a frame, + the src pad task creates an unsolveable AB-BA deadlock between + handle_frame() waiting for a free surface and decode_loop() pushing + decoded frames out. + Instead, have handle_frame() take responsibility for pushing surfaces, + and remove the deadlock completely. If you need a separate thread + downstream, you can insert a queue between vaapidecode and its downstream + to get one. + Another justification for the single thread implementation is, + there are two many point of locking in gstreamer-vaapi's current + implementation which can lead to deadlocks. + https://bugzilla.gnome.org/show_bug.cgi?id=742605 + Signed-off-by: Simon Farnsworth + Signed-off-by: Víctor Manuel Jáquez Leal + Signed-off-by: Sreerenj Balachandran + +2015-03-02 13:28:41 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginbase.c: + plugins: fix detection of upstream v4l2src element. + Improve check for upstream element that requires DMABUF buffer pool, + e.g. v4l2src element. In particular, make sure to traverse through + any additional capsfilter for instance. + Note: the traversal to the top-most upstream element could be made + more generic, but we are insofar only interested in supporting pipes + similar to v4l2src or v4l2src ! capsfilter, e.g. with an explicit + specification for a desired video camera format, or resolution. + +2015-03-02 11:12:53 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + plugins: fix allocation of DMABUF memory. + The dmabuf allocator would close the DMABUF handle passed in the init + function gst_dmabuf_allocator_alloc(). So, we need to dup() it so that + to avoid a double close, ultimately in the underlying driver that owns + the DMABUF handle. + +2015-02-26 12:28:02 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: keep src caps and output state in sync + vaapidecode keeps an output state that use the format + GST_VIDEO_FORMAT_ENCODED, while it crafts a different src caps + for a correct negotiation. + I don't see the rational behind this decoupling, it looks like + unnecessary complexity. This patch simplify this logic keeping + in sync the output state and the src caps. + This patch improves the readability of the function + gst_vaapidecode_update_src_caps() and simplify its logic. Also, + the patch validates if the buffer pool has the configuration for + the GL texture upload meta, in order to set the caps feature + meta:GLTextureUpload. Otherwise, the I420 format is set back. + https://bugzilla.gnome.org/show_bug.cgi?id=744618 + Signed-off-by: Víctor Manuel Jáquez Leal + Signed-off-by: Sreerenj Balachandran + +2015-02-26 12:26:54 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: upload meta only if feature and allocation + When vaapidecode finishes the decoding of a frame and pushes it, + if, in the decide_allocation() method, it is determined if the + next element supports the GL texture upload meta feature, the + decoder adds the buffer's meta. + Nonetheless, in the same spirit of the commit 71d3ce4d, the + determination if the next element supports the GL texture upload + meta needs to check both the preferred caps feature *and* if the + allocation query request the API type. + This patch, first removes the unused variable need_pool, and + determines the attribute has_texture_upload_meta using the + preferred caps feature *and* the allocation query. + Also, the feature passed to GstVaapPluginBase is not longer + determined by has_texture_upload_meta, but by the computed + preferred one. + https://bugzilla.gnome.org/show_bug.cgi?id=744618 + Signed-off-by: Víctor Manuel Jáquez Leal + Signed-off-by: Sreerenj Balachandran + +2015-02-26 12:24:55 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + vaapidecode: delayed src caps negotiation + Currently the src caps are set immediately after the sink caps are set, but in + that moment the pipeline might not fully constructed and the video sink has + not negotiated its supported caps and features. As a consequence, in many cases + of playback, the least optimized caps feature is forced. This is partially the + responsible of bug #744039. + Also, vaapidecode doesn't attend the reconfigure events from downstream, + which is a problem too, since the video sink can be changed with different + caps features. + This patch delays the src caps, setting them until the first frame arrives to + the decoder, assuming until that very moment the whole pipeline is already + negotiated. Particularly, it checks if the src pad needs to be reconfigured, + as a consequence of a reconfiguration event from downstream. + A key part of this patch is the new GstVaapiCapsFeature + GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED, which is returned when the src pad + doesn't have a peer yet. Also, for a better report of the caps allowed + through the src pad and its peer, this patch uses gst_pad_get_allowed_caps() + instead of gst_pad_peer_query_caps() when looking for the preferred feature. + v3: move the input_state unref to close(), since videodecoder resets at + some events such as navigation. + v4: a) the state_changed() callback replaces the input_state if the media + changed, so this case is also handled. + b) since the parameter ref_state in gst_vaapidecode_update_src_caps() is + always the input_state, the parameter were removed. + c) there were a lot of repeated code handling the input_state, so I + refactored it with the function gst_vaapi_decode_input_state_replace(). + https://bugzilla.gnome.org/show_bug.cgi?id=744618 + Signed-off-by: Víctor Manuel Jáquez Leal + Signed-off-by: Sreerenj Balachandran + +2015-02-24 17:14:33 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + encoder: h264: add support for more than 2 views + Add support for H.264 MVC Multiview High profile encoding with + more than 2 views. All views within the same accesss unit are + provided in increasing order of view order index (VOIdx). + Upto 10 view are supported for now. + A new property "view-ids" has been provided for the plugins to + set the view ids (which is an array of guint values) to be used + for mvc encoding. + https://bugzilla.gnome.org/show_bug.cgi?id=732453 + +2015-02-23 16:55:36 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: upload meta only if feature and allocation + Working on bug #743687, I realized that vaapidecode always adds to its buffer + pool the config option GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META if + the decide_allocation()'s query has GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE. + Nevertheless, there are occasions where the query has the API type, but the + last negotiated caps don't have the feature meta:GstVideoGLTextureUploadMeta. + Under this contradiction, vaapidecode adds the GLTextureUploadMeta API to its + buffer pool configuration, and adds its buffer's meta to each output buffer, + even if the negotiated caps feature is memory:SystemMemory with I420 color + format. + This kind of output buffers chokes ClutterAutoVideosSink, since it uses a map + that relates caps <-> GL upload method. If it receives a buffer with color + format I420, it assumes that it doesn't have a texture upload meta, because + only those with RGB color format has it. Our buffers, with I420 format, say + that they have the upload meta too. In that case the mapped method is a dummy + one which does nothing. I reported this issue in bug #744039 (the patch, + obviously, was rejected). + This patch workarounds the problem: the buffer pool's configuration option + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META is set if and only if the + query has the GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE *and* the negotiated + caps feature is meta:GstVideoGLTextureUploadMeta. + I have tested these patches with gst-master (1.5), gst-1.4 and gst-1.2 and + in all they seem to work correctly. + https://bugzilla.gnome.org/show_bug.cgi?id=744618 + [adapted to fit current EGL changes] + Signed-off-by: Gwenole Beauchesne + +2015-02-20 15:13:03 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapitexture_glx.c: + * gst-libs/gst/vaapi/gstvaapitexture_priv.h: + * gst/vaapi/gstvaapivideometa_texture.c: + plugins: add support for GstVideoGLTextureOrientation. + Add support for GstVideoGLTextureOrientation modes. In particular, + add orientation flags to the GstVaapiTexture wrapper and the GLX + implementations. Default mode is that texture memory is laid out + with top lines first, left row first. Flags indicate whether the + X or Y axis need to be inverted. + +2015-02-09 21:09:07 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapivideometa_texture.c: + plugins: add support for BGRA textures. + Some frameworks (EFL) expect BGRA textures for storage. However, + adding support for that broadly into GStreamer framework implies + two kinds of hacks: (i) libgstgl helpers currently do not support + BGRA textures correctly, (ii) we need to better parse downstream + suggested caps and intersect them with what the VA plugin elements + can offer to them for GL texturing. + +2015-01-23 09:31:57 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + plugins: fix support for Wayland/EGL running alongside X11. + When multiple display servers are available, the glimagesink element + (from GStreamer 1.4) may not be able to derive a global display in + Wayland. Rather, a "window"-specific display is created. In this case, + the GstGLDisplay handle available through GstGLContext is invalid. + So, try to improve heuristics for display server characterisation in + those particular situations. + +2015-02-20 15:29:17 +0100 Gwenole Beauchesne + + * configure.ac: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideometa_texture.c: + plugins: add initial support for EGL. + Add initial support for EGL through GstVideoGLTextureUploadMeta. + Fix gst_vaapi_ensure_display() to allocate a GstVaapiDisplay off the + downstream supplied GstGLContext configuration, i.e. use its native + display handle to create a GstVaapiDisplay of type X11 or Wayland ; + and use the desired OpenGL API to allocate the GstVaapiDisplayEGL + wrapper. + https://bugzilla.gnome.org/show_bug.cgi?id=741079 + +2014-12-09 11:46:58 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideometa_texture.c: + plugins: track video texture size changes. + Sync video texture sizes to GstVideoGLTextureUploadMeta private date, + i.e. GstVaapiVideoMetaTexture, on a regular basis. In particular, we + now update the texture size from the GstVideoMeta, if any, or reset + to some defaults otherwise. + +2014-12-03 15:45:52 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipluginutil.c: + plugins: ensure VA display matches GL context expectations. + If a GstGLContext is supplied by the downstream element, then make + sure that the VA plugin element gets a compatible display to what + is requested by the GL context. e.g. re-allocate a VA/GLX display + when a GLX context is provided by the downstream element. + +2014-12-03 14:14:30 +0100 Gwenole Beauchesne + + * configure.ac: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: record downstream GstGLContext. + Record GL context supplied by downstream elements. This can be useful, + and further needed, to enforce run-time check that the GL context is + compatible for use by libgstvaapi. e.g. check that we don't create a + VA/GLX display for EGL/X11 contexts. + https://bugzilla.gnome.org/show_bug.cgi?id=725643 + Original-path-by: Matthew Waters + +2014-12-01 14:52:39 +0100 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/output.c: + egl: update tests. + Add initial support for EGL to tests. The new EGL backend can be selected + through the --egl command line option. The OpenGL|ES version can further + be selected with the --gles-version command line option, where the default + of 0 means "desktop" OpenGL. + +2015-01-27 16:21:04 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.h: + * gst-libs/gst/vaapi/gstvaapiwindow_egl.c: + * gst-libs/gst/vaapi/gstvaapiwindow_egl.h: + egl: add windowing support. + This provides for some basic EGL window abstraction. + +2015-01-24 08:29:57 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst-libs/gst/vaapi/gstvaapitexture_egl.c: + * gst-libs/gst/vaapi/gstvaapitexture_egl.h: + egl: add texture abstraction. + Add GstVaapiTextureEGL abstraction that can create its own GL texture, + or import a foreign allocated one, while still allowing updates from a + VA surface. + +2014-12-09 18:14:56 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapisurface_egl.c: + * gst-libs/gst/vaapi/gstvaapisurface_egl.h: + egl: allow for EGLImage imports into VA Surfaces. + Add helpers to import EGLImage objects into VA surfaces. There are + two operational modes: (i) gst_vaapi_surface_new_from_egl_image(), + which allows for implicit conversion from EGLImage to a VA surface + in native video format, and (ii) gst_vaapi_surface_new_with_egl_image(), + which exactly wraps the source EGLImage, typically in RGBA format + with linear storage. + Note: in case of (i), the EGLImage can be disposed right after the + VA surface creation call, unlike in (ii) where the user shall ensure + that the EGLImage is live until the associated VA surface is no longer + needed. + https://bugzilla.gnome.org/show_bug.cgi?id=743847 + +2015-02-20 15:27:53 +0100 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/egl_compat.h: + * gst-libs/gst/vaapi/egl_vtable.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.h: + * gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.h: + * gst-libs/gst/vaapi/ogl_compat.h: + Add initial support for EGL. + Add initial support for EGL to libgstvaapi core library. The target + display server and the desired OpenGL API can be programmatically + selected at run-time. + A comprehensive set of EGL utilities are provided to support those + dynamic selection needs, but also most importantly to ensure that + the GL command stream is executed from within a single thread. + https://bugzilla.gnome.org/show_bug.cgi?id=743846 + +2015-01-30 21:38:07 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapivalue.c: + libs: initialize GValues in a thread-safe manner. + +2015-01-30 21:35:10 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapivalue.c: + libs: re-indent all GValue related source code. + +2015-01-22 22:45:24 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: partially revert 0777f35. + Reset the VA decoder after updating the base plugin caps, and most + importantly, after GstVideoDecoder negotiation. The reason behind + this is that the negotiation could trigger a last decide_allocation() + where we could actually derive a new GstVaapiDisplay to use from the + downstream element. e.g. GLX backend. + +2015-02-19 13:37:09 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Caps query should return the list of all supported caps. + Query caps filtering should be always done on top of allowed caps instead + of existing fixed caps on a particular pad. + This fixes the mvc stream decoding when there is a base view(high profile) + and non-base view(stereo-high profile). + +2015-02-18 13:36:16 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: intersect filter from query caps + According to documentation[1] when receiving a GST_QUERY_CAPS + the return value should be all formats that this elements supports, + taking into account limitations of peer elements further downstream + or upstream, sorted by order of preference, highest preference first. + This patch add those limitations intersecting with the received + filter in the query. Also takes into account the already negotiated + caps. Also adds the processing of the query on the SRC pad. + 1. http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-nego-getcaps.html + https://bugzilla.gnome.org/show_bug.cgi?id=744406 + +2015-02-18 11:46:11 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst/vaapi/gstvaapivideomemory.c: + Fix compiler warnings + This patch fixes some warnings that gcc 4.9 reports. + https://bugzilla.gnome.org/show_bug.cgi?id=744411 + +2015-02-18 11:22:21 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Use GST_DEBUG_FUNCPTR for gst_vaapidecode_query() + Hence the function name is shown in the gst-inspect-1.0 information + rather than the memory address. + https://bugzilla.gnome.org/show_bug.cgi?id=744330 + +2015-02-18 11:21:35 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: log flow error name + https://bugzilla.gnome.org/show_bug.cgi?id=744387 + +2015-02-18 11:20:42 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + VC1: decoder: Ignore VC1 user BDU's + Don't return error if the processed BDU is a user one, just ignore them. + https://bugzilla.gnome.org/show_bug.cgi?id=741237 + Signed-off-by: Sreerenj Balachandran + +2015-02-18 11:19:26 +0200 Olivier Crete + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + vaapidecode: Emit error GstMessage when returning a GST_FLOW_ERROR + This is required in GStreamer, elements should never return + GST_FLOW_ERROR without posting an ERROR message on the bus. + https://bugzilla.gnome.org/show_bug.cgi?id=744620 + +2015-02-13 13:45:32 +0200 Sreerenj Balachandran + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiencode_vp8.h: + plugins: Add VP8 Encoder + +2015-02-13 13:42:04 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.h: + Add VP8 Encoder to core libgstvaapi. + +2015-02-13 13:40:19 +0200 Sreerenj Balachandran + + * configure.ac: + configure: Add Check for VP8 Encoding API + +2015-02-10 11:40:16 +0200 Lim Siew Hoon + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: vc1: Rounding control handling for VC1 simple and Main profile + Added rounding control handling for VC1 simple and Main profile + based on VC1 standard spec: section 8.3.7 + https://bugzilla.gnome.org/show_bug.cgi?id=743958 + Signed-off-by: Lim Siew Hoon + Signed-off-by: Sreerenj Balachandran + +2015-02-06 12:10:51 +0200 Sreerenj Balachandran + + * gst/vaapi/Makefile.am: + build: fix make dist when certain conditionals not met. + Fix typo which was preventing the inclusion of jpeg encoder + source files from make dist (when there is no jpeg encoder + API support in libva). + +2015-02-05 13:08:53 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + encoder: jpeg: Fix the sampling factor calculation for ENCODED format. + If the incoming raw video format is GST_VIDEO_FORMAT_ENCODED, + use native YUV420 format (which is i420) as default. + +2015-02-05 12:13:38 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + encoder: Only support YUV420 native format as input for now + Practically we should be able to support more formats, for eg: + JPEG Encoder can support YUV422, RGBA and all. + But this is causing more issues which need proper fix here and there. + +2015-02-04 18:34:59 +0200 Olivier Crete + + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Check the condition after taking the lock + Otherwise the condition could become true before the lock + is taken and the g_cond_signal() could be called + before the g_cond_wait(), so the g_cond_wait() is never + awoken. + https://bugzilla.gnome.org/show_bug.cgi?id=740645 + +2015-02-04 11:18:29 +0200 Sreerenj Balachandran + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_jpeg.h: + plugins: Add JPEG encoder element + +2015-02-04 11:17:58 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapicontext.c: + gstvaapicontext: Add VAConfigAttribValEncJPEG to the attribute list using for VAConfig creation. + +2015-02-04 11:17:27 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapicontext.c: + gstvaapicontext: Don't use the unsupported Ratecontrol attributes for vaCreateConfig + Don't add the VAConfigAttribRateControl to the attribute list using + for the vaCreateConfig if it is not supported by the driver. + +2015-02-04 11:17:06 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + gstvaapiencoder: Use hardcoded packed_raw_data flag for JPEG Encoding + +2015-02-04 11:16:37 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + gstvaapiencoder: Fix crash when handling rate control mask + Having a ratecontrol_mask equal to zero is not a bug, but the driver + might not be supporting any kind of rate control mechanisms. + Eg: JPEG Encoding + +2015-02-04 11:16:05 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h: + encoder: Add JPEG Encoder + +2015-02-04 11:15:38 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + encoder_objects: Add QuantizationMatrix and JPEGHuffmanTable + +2015-02-04 11:15:00 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + Encode: Add support for Picture level Entrypoint + This is useful for JPEG encoding which is utilizing picture level + entrypoint instead of slice level entrypoint like h264,mpeg2 etc. + +2015-02-04 11:14:15 +0200 Sreerenj Balachandran + + * configure.ac: + configure: Add Check for JPEG encoding API + +2015-02-03 13:08:53 +0200 Sreerenj Balachandran + + * AUTHORS: + AUTHORS: Updates + +2015-02-03 13:08:01 +0200 Sreerenj Balachandran + + * configure.ac: + Bump version for development. + +=== release 0.5.10 === + +2015-02-03 10:00:42 +0200 Sreerenj Balachandran + + * configure.ac: + 0.5.10 + +2015-02-03 10:00:23 +0200 Sreerenj Balachandran + + * NEWS: + NEWS: Updates + +2015-02-02 11:43:58 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapivideometa_texture.c: + Fix compilation error if there is no GL/gl.h header file installed + +2015-01-28 18:09:40 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.h: + plugins: drop leftover declaration. + GstVaapiVideoMemory quark is not needed any more, and the actual + implementation was already removed bfore the merge. i.e. this is + an oversight for a hunk that was not meant to be pushed. + +2015-01-26 18:30:47 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideobufferpool.h: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: add support for dma_buf exports (v4l2src). + Allow v4l2src element to connected to vaapipostproc or vaapisink when + "io-mode" is set to "dmabuf-import". In practice, this is a more likely + operational mode with uvcvideo. Supporting v4lsrc with "io-mode" set + to "dmabuf" could work, but with more demanding driver or kernel reqs. + Note: with GStreamer 1.4, v4l2src (gst-plugins-good) needs to be built + with --without-libv4l2. + https://bugzilla.gnome.org/show_bug.cgi?id=743635 + +2014-01-23 05:00:09 -0500 Wind Yuan + + * configure.ac: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapipluginbase.c: + plugins: add support for dma_buf imports. + Allow imports of v4l2 buffers into VA surfaces for further operation + with vaapi plugins, e.g. vaapipostproc or vaapiencode_* elements. + https://bugzilla.gnome.org/show_bug.cgi?id=735362 + [fixed memory leaks, ported to new dma_buf infrastructure, cleanups] + Signed-off-by: Gwenole Beauchesne + +2014-09-15 15:27:50 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + * gst-libs/gst/vaapi/gstvaapisurface_drm.h: + surface: add support for GEM buffer imports. + Add support for GEM buffer imports. This is useful for VA/EGL interop + with legacy Mesa implementations, or when it is desired or required to + support outbound textures for instance. + https://bugzilla.gnome.org/show_bug.cgi?id=736718 + +2014-09-15 15:25:09 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + * gst-libs/gst/vaapi/gstvaapisurface_drm.h: + surface: add support for dma_buf imports. + Add new gst_vaapi_surface_new_with_dma_buf_handle() helper function + to allow for creating VA surfaces from a foreign DRM PRIME fd. The + resulting VA surface owns the supplied buffer handle. + https://bugzilla.gnome.org/show_bug.cgi?id=735362 + +2015-01-27 11:19:58 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + surface: add initial support for foreign buffer imports. + Add gst_vaapi_surface_new_from_buffer_proxy() helper function to + create a VA surface from an external buffer provided throug the + new GstVaapiBufferProxy object. + +2014-09-15 13:47:53 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy.h: + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + * gst-libs/gst/vaapi/gstvaapisurface_drm.h: + surface: add support for GEM buffer exports. + Add support for GEM buffer exports. This will only work with VA drivers + based off libdrm, e.g. the Intel HD Graphics VA driver. This is needed + to support interop with EGL and the "Desktop" GL specification. Indeed, + the EXT_image_dma_buf_import extension is not going to be supported in + Desktop GL, due to the lack of support for GL_TEXTURE_EXTERNAL_OES targets + there. + This is useful for implementing VA/EGL interop with legacy Mesa stacks, + in Desktop OpenGL context. + https://bugzilla.gnome.org/show_bug.cgi?id=736717 + +2014-09-15 11:48:05 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy.h: + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + * gst-libs/gst/vaapi/gstvaapisurface_drm.h: + surface: add support for dma_buf exports. + Use the new VA buffer export APIs to allow for a VA surface to be + exposed as a plain PRIME fd. This is in view to simplifying interop + with EGL or OpenCL for instance. + https://bugzilla.gnome.org/show_bug.cgi?id=735364 + +2014-09-15 10:58:51 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy.h: + * gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h: + Add abstraction for exported VA buffers. + The VA buffer export APIs work for a particular lifetime starting from + vaAcquireBufferHandle() and ending with vaReleaseBufferHandle(). As such, + it could be much more convenient to support implicit releases by simply + having a refcount reaching zero. + https://bugzilla.gnome.org/show_bug.cgi?id=736721 + +2015-01-28 18:25:09 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + Add missing header file to Makefile + Add gstvaapitexture_glx.h to Makefile.am + +2015-01-27 11:44:12 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + * tests/test-surfaces.c: + videopool: add optional flags for surface pool allocation. + Reword surface pool allocation helpers so that to allow for a simple + form, e.g. gst_vaapi_surface_pool_new(format, width, height); and a + somewhat more elaborated/flexible form with optional allocation flags + and precise GstVideoInfo specification. + This is an API/ABI change, and SONAME version needs to be bumped. + +2015-01-26 23:21:56 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapivideopool_priv.h: + videopool: re-indent all GstVaapiVideoPool related source code. + +2014-12-10 20:13:21 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + window: add toplevel display indirection for visualid and colormap. + Add GstVaapiDisplay::get_{visual_id,colormap}() helpers to help determine + the best suitable window visual id and colormap. This is an indirection in + view to supporting EGL and custom/generic replacements. + +2014-12-10 19:58:10 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + window: add toplevel API to determine the colormap. + Add GstVaapiWindowClass::get_colormap() hook to help determine the + currently active colormap bound to the supplied window, or actually + create it if it does not already exist yet. + +2014-12-10 19:36:12 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + window: add toplevel API to determine a visual id. + Add GstVaapiWindowClass::get_visual_id() function hook to help find + the best suitable visual id for the supplied window. While doing so, + also simplify the process by which an X11 window is created with a + desired Visual, i.e. now use a visual id instead of a Visual object. + +2014-12-10 18:12:24 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + window: add generic helper to create windows. + Add a new generic helper function gst_vaapi_window_new() to create + a window without having the caller to check for the display type + himself. i.e. internally, there is now a GstVaapiDisplayClass hook + to create windows, and the actual backend implementation fills it in. + Add new generic helper functions gst_vaapi_texture_new_wrapped() + This is a simplification in view to supporting EGL. + +2014-12-03 11:39:24 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst/vaapi/gstvaapivideometa_texture.c: + display: add utility function to check for OpenGL rendering. + Add gst_vaapi_display_has_opengl() helper function to help determining + whether the display can support OpenGL context to be bound to it, i.e. + if the class is of type GST_VAAPI_DISPLAY_TYPE_GLX. + +2014-12-10 18:02:55 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideometa_texture.c: + display: refine the meaning of display type. + Make gst_vaapi_display_get_display_type() return the actual VA display + type. Conversely, add a gst_vaapi_display_get_class_type() function to + return the type of the GstVaapiDisplay instance. The former is used to + identify the display server onto which the application is running, and + the latter to identify the original object class. + +2014-12-02 11:23:29 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + display: cosmetics (helper macros, new internal API names). + Add more helper macros to the top-level GstVaapiDisplay interfaces. + Rename a few others used internally for improved consistency. + +2014-12-01 17:08:29 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapipixmap_x11.c: + * gst-libs/gst/vaapi/gstvaapitexture_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + display: record native display object. + Record the underlying native display instance into the toplevel + GstVaapiDisplay object. This is useful for fast lookups to the + underlying native display, e.g. for creating an EGL display. + +2014-12-01 16:54:32 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.h: + display: use a recursive mutex for the display cache. + Use a recursive mutex for the display cache so that a 3rdparty display + object could be initialized during the initialization of the parent + display. + +2014-12-04 14:36:35 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapitexture_glx.c: + * gst-libs/gst/vaapi/gstvaapitexture_priv.h: + texture: add generic helper to create textures. + Add new generic helper functions gst_vaapi_texture_new_wrapped() + and gst_vaapi_texture_new() to create a texture without having + the caller to uselessly check for the display type himself. i.e. + internally, there is now a GstVaapiDisplayClass hook to create + textures, and the actual backend implementation fills it in. + This is a simplification in view to supporting EGL. + +2014-10-23 17:44:23 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapitexture_glx.c: + * gst-libs/gst/vaapi/gstvaapitexture_glx.h: + * gst-libs/gst/vaapi/gstvaapitexture_priv.h: + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideometa_texture.c: + * tests/test-textures.c: + texture: move to core libgstvaapi base library. + GstVaapiTexture is a generic abstraction that could be moved to the + core libgstvaapi library. While doing this, no extra dependency needs + to be added. This means that a GstVaapitextureClass is now available + for any specific code that needs to be added, e.g. creation of the + underlying GL texture objects, or backend dependent ways to upload + a surface to the texture object. + Generic OpenGL data types (GLuint, GLenum) are also replaced with a + plain guint. + https://bugzilla.gnome.org/show_bug.cgi?id=736715 + +2014-10-23 13:11:54 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapitexture.c: + texture: drop support for VA/GLX interfaces. + The VA/GLX interfaces are obsolete. They used to exist for XvBA, and + ease of use, but they had other caveats to deal with. It's now better + to move on to legacy mode, whereby VA/GLX interop is two be provided + through (i) X11 Pixmap, and (ii) other modern means of buffer sharing. + https://bugzilla.gnome.org/show_bug.cgi?id=736711 + +2014-10-23 11:56:31 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideometa_texture.c: + * tests/test-textures.c: + texture: add support for cropping rectangle during transfer. + The gst_vaapi_texture_put_surface() function is missing a crop_rect + argument that would be used during transfer for cropping the source + surface to the desired dimensions. + Note: from a user point-of-view, he should create the GstVaapiTexture + object with the cropped size. That's the default behaviour in software + decoding pipelines that we need to cope with. + This is an API/ABI change, and SONAME version needs to be bumped. + https://bugzilla.gnome.org/show_bug.cgi?id=736712 + +2014-10-23 11:22:10 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + texture: re-indent all GstVaapiTexture related source code. + +2015-01-27 11:16:34 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + surface: add more fine-grained allocation helper. + Add new gst_vaapi_surface_new_full() helper function that allocates + VA surface from a GstVideoInfo template in argument. Additional flags + may include ways to + - allocate linear storage (GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE) ; + - allocate with fixed strides (GST_VAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) ; + - allocate with fixed offsets (GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS). + +2014-09-15 14:57:57 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + surface: re-indent all GstVaapiSurface related source code. + +2015-01-23 16:44:34 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + surfaceproxy: add helper to create a wrapped surface object. + Add new gst_vaapi_surface_proxy_new() helper to wrap a surface into + a proxy. The main use case for that is to convey additional information + at the proxy level that would not be suitable to the plain surface. + +2015-01-23 16:37:06 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + surfaceproxy: re-indent all GstVaapiSurfaceProxy related source code. + +2015-01-27 18:02:56 +0100 Gwenole Beauchesne + + * configure.ac: + libs: bump library major version. + +2014-12-04 14:36:35 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapitypes.h: + libs: re-introduce a GST_VAAPI_ID_INVALID value. + Re-introduce a GST_VAAPI_ID_INVALID value that represents + a non-zero and invalid id. This is useful to have a value + that is still invalid for cases where zero could actually + be a valid value. + +2014-12-02 16:51:20 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiminiobject.c: + * gst-libs/gst/vaapi/gstvaapiminiobject.h: + libs: expose GstVaapiMiniObject APIs to all backends. + Make it possible to have all libgstvaapi backends (libs) access to a + common GstVaapiMiniObject API and implementation. This is a minor step + towards full exposure when needed, but restrict it to libgstvaapi at + this time. + +2014-12-02 14:15:49 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiminiobject.c: + * gst-libs/gst/vaapi/gstvaapiminiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + libs: re-indent all GstVaapiObject related source code. + Re-indent and provide additional minor cosmetical changes to the + GstVaapiMiniObject and GstVaapiObject source files. + +2015-01-27 16:25:21 +0200 Simon Farnsworth + + * gst/vaapi/gstvaapipluginutil.c: + pluginutil: Fix clearing of subtitle overlay + dvbsuboverlay signals no subtitles present by not setting + GstVideoOverlayCompositionMeta on a buffer. + Detect this, and remove subtitles whenever we have no overlay composition to + hand. + Signed-off-by: Simon Farnsworth + +2015-01-27 16:06:02 +0200 Michael Olbrich + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: clear state on stop + Otherwise restarting may fail because the state of vaapipluginbase and + vaapipostproc don't match. e.g. gst_vaapipostproc_set_caps() will skip + initailization and not call gst_vaapi_plugin_base_set_caps() + +2015-01-27 14:50:12 +0200 Michael Olbrich + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: don't print an error message for GST_FLOW_FLUSHING + +2015-01-27 12:38:45 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + gstvaapiencoder: Fix the negotiation issue with _ENCODED format handling + Don't error out for the video format GST_VIDEO_FORMAT_ENCODED with in gstvaapiencoder, + since the vaaapi context creation (gstvaapicontext.c) can still use the + default chroma type which is YUV420. + https://bugzilla.gnome.org/show_bug.cgi?id=743567 + https://bugzilla.gnome.org/show_bug.cgi?id=743035 + +2015-01-21 18:31:22 +0200 Sreerenj Balachandran + + * patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch: + * patches/videoparsers/series.frag: + h264parse: drop patches merged upstream. + 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch + +2015-01-21 18:26:12 +0200 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit d3b5c1b + 8194cac: h264parse: parse SPS subset + 64b7f52: h264parse: expose stereo-high profile + 774360a: h264parse: add initial support for MVC NAL units + 258478f: h264parser: fix stack smashing + +2015-01-19 11:30:12 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapivideometa_texture.c: + Fix compilation error if there is no GL/gl.h header file installed + +2015-01-15 16:23:24 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: commit updated srcpad caps to base plugin. + Make sure that the GstVaapiPluginBase instance receives the new src + pad caps whenever they get updated from within the GstVaapiDecoder + decode routines. + This also ensures that downstream elements receive correctly sized + SW decoded buffers if needed. + https://bugs.tizen.org/jira/browse/TC-114 + +2015-01-15 16:19:59 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: always reset decoder on ::set_format(). + Split GstVideoDecoder::set_format() handler to first update the sink + pad caps and reset the active VA decoder instance based on those, and + then update the src pad caps whenever possible, e.g. when the caps + specify a valid video resolution. + +2015-01-15 16:14:13 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: don't crash when trying to allocate 0x0 images. + In some occasions, a buffer pool is created for pre-initialization + purposes regardless of whether a valid image size is available or + not. However, during actual decode stage, the vaapidecode element + is expected to update the srcpad caps with the new dimensions, thus + also triggering a reset of the underlying bufferpool. + +2015-01-15 00:00:16 +0200 Sreerenj Balachandran + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 191cb2f + 347605a: h264parse: expose compatible profiles to downstream + d1ea97e: h264parse: Fix periodic SPS/PPS sending work after a seek + 24a3126: Revert "h264parse: expose compatible profiles to downstream" + 8661740: h264parse: expose compatible profiles to downstream + 8b7ef3f: codecparsers: fix some compiler warnings + +2014-11-27 12:11:03 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: Fix the period between I/P frames + If the key-frame period is set as one, then ip_period shuld be zero + https://bugzilla.gnome.org/show_bug.cgi?id=734992 + +2014-11-27 11:21:03 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: Provide intra_idr_period value for VAEncSequenceParameterBufferH264 + https://bugzilla.gnome.org/show_bug.cgi?id=734993 + +2014-11-27 11:14:50 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapisink.c: + vaapisink: Protect the X11 API invokations with proper locking + https://bugzilla.gnome.org/show_bug.cgi?id=739808 + +2014-11-27 11:13:20 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix pixel-aspect-ratio in encoded stream. + Really report sample aspect ratio (SAR) as present, and make it match + what we have obtained from the user as pixel-aspect-ratio (PAR). i.e. + really make sure VUI parameter aspect_ratio_info_present_flag is set + to TRUE and that the indication from aspect_ratio_idc is Extended_SAR. + This is a leftover from git commit a12662f. + https://bugzilla.gnome.org/show_bug.cgi?id=740360 + +2014-11-25 11:46:12 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + decoder: mpeg4: fix uninitialized variables. + Fix gst_vaapi_decoder_mpeg4_parse() to initialize the packet type to + GST_MPEG4_USER_DATA so that a parse error would result in skipping + that packet. Also fix gst_vaapi_decoder_mpeg4_decode_codec_data() to + initialize status to GST_VAAPI_DECODER_STATUS_SUCCESS. + +2014-11-25 11:41:49 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix profile limits. + Fix ensure_profile_limits() to lower profile to the desired limits, + only if the latter are actually known and the profile needed to be + changed to fit. + +2014-11-24 15:14:37 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix out caps for GLMemory. + If the best downstream capsfeature turns out to be GLMemory, then make + sure to propagate RGBA video format in caps to that element. This fixes + the following pipeline: ... ! vaapipostproc ! glimagesink. + +2014-11-24 14:25:33 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix check for compatible src pad capsfilters. + When an explicit output video format is selected, from an src pad + capsfilter, make sure that the downstream element actually supports + that format. In particular, fix crash with the following pipelines: + ... ! vaapipostproc ! video/x-raw,format=XXX ! xvimagesink ; where + XXX is a format not supported by xvimagesink. + While doing so, also reduce the set of src pad filter caps to the + actual set of allowed src pad caps. + +2014-11-24 14:10:11 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapiuploader.h: + plugins: re-indent all video processing related source code. + +2014-11-24 13:20:33 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + plugins: further fixes to the new "current" storage tracker. + The ensure_surface() and ensure_image() functions shall only relate + to the underlying backing store. The actual current flags are to be + updated only through ensure_{surface,image}_is_current() or very other + particular cases in GstMemory hooks. + +2014-11-21 15:43:35 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + plugins: fix "current" video memory flags. + If the surface proxy is updated into the GstVaapiVideoMemory, then + it is assumed it is the most current representation of the current + video frame. Likewise, make a few more arrangements to have the + "current " flags set more consistently. + +2014-11-21 15:23:13 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + * gst/vaapi/gstvaapivideometa.c: + plugins: ensure VA surface is current prior to using it. + When interacting with SW elements, the buffers and underlying video + memory could be mapped as read/write. However, we need to use those + buffers again as plain VA surfaces, we have to make sure the VA image + is thus committed back to VA surface memory. + This fixes pipelines involving avdec_* and vaapi{postproc,sink}. + +2013-07-12 06:34:15 -0400 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + plugins: enable memory maps for read & write. + Hence vaapisink can display buffers decoded by gst-libav, or HW decoded + buffers can be further processed in-place, e.g. with a textoverlay. + https://bugzilla.gnome.org/show_bug.cgi?id=704078 + [ported to current git master branch, amended commit message] + Signed-off-by: Gwenole Beauchesne + +2014-11-18 14:57:02 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + plugins: preserve framerate when updating src caps video format. + In the current implementation, gst_video_info_set_format() would reset + the whole GstVideoInfo structure first, prior to setting video format + and size. So, coleteral information like framerate or pixel-aspect- + ratio are lost. + Provide and use a unique gst_video_info_change_format() for overcome + this issue, i.e. only have it change the format and video size, and + copy over the rest of the fields. + https://bugzilla.gnome.org/show_bug.cgi?id=734665 + +2014-11-18 14:07:57 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapi.c: + vaapidecode: increase the rank to GST_RANK_PRIMARY + 1 + This is for helping decodebin to autoplug the vaapidecode element. + Decodebin is selecting decoder elements only based on rank and caps. + Without overriding the autoplug-* signals there is no way to autoplug + HW decoders inside decodebin. An easier soulution is to raise the + rank of vaapidecode, so that it gets selected first. + https://bugzilla.gnome.org/show_bug.cgi?id=739332 + +2014-11-12 07:46:53 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst/vaapi/gstvaapidecode.c: + vaapidecode: only expose supported profiles when needed. + JPEG and VP8 codecs do not really support the concept of "profile". So, + don't try to expose any set that wouldn't be supported by jpegparse, or + ivfparse for instance. + https://bugzilla.gnome.org/show_bug.cgi?id=739713 + https://bugzilla.gnome.org/show_bug.cgi?id=739714 + +2014-11-13 15:13:24 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + decoder: h264: add initial support for repeat-first-field (RFF) flag. + Use the SEI pic_timing() message to track and propagate down the repeat + first field (RFF) flag. This is only initial support as there is one + other condition that could induce the RFF flag, which is not handled + yet. + +2014-11-13 15:05:19 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix picture ordering count type 0 with previous MMCO5. + Fix the decoding process for picture order count type 0 when the previous + picture had a memory_management_control_operation = 5. In particular, fix + the actual variable type for prev_pic_structure to hold the full bits of + the picture structure. + In practice, this used to work though, due to the underlying type used to + express a gboolean. + +2014-11-13 15:00:21 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix detection of top-field-first (TFF) flag. + Use the SEI pic_timing() message to track the pic_struct variable when + present, or infer it from the regular slice header flags field_pic_flag + and bottom_field_flag. This fixes temporal sequence ordering when the + output pictures are to be displayed. + https://bugzilla.gnome.org/show_bug.cgi?id=739291 + +2014-11-14 09:54:02 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 3d05d9f. + 1241840 h264: fix derivation of MaxPicNum variable + 3bd718e h264: fix GstH264ParserResult documentation typo + b021609 h264parse: set the HEADER flag on buffers containing SPS or PPS + b08e4be h264parse: don't unnecesarily set src_caps + +2014-11-03 19:20:43 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: Add string representation of VPP functions to ElementFactoy Klass + Added the same Klass specifications used in other upstream + video postprocessing elements like videoconvert, videoscale, + videobalance and deinterlace. + An example use case is for this is to help the playsink + to autoplug the hardware accelerated deinterlacer. + +2014-11-03 19:19:20 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: Tweak the output video format setting to enable the autoplugging + This is a workaround until auto-plugging is fixed when + format=ENCODED + memory:VASurface caps feature are provided. + Use the downstream negotiated video format as the output video format + if the user didn't ask for the colorspace conversion explicitly. + Usecase: This will help to connect elements like videoscale, videorate etc + to vaapipostproc. + https://bugzilla.gnome.org/show_bug.cgi?id=739443 + +2014-10-29 17:30:30 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: allow user defined scaling mode. + Add new "scale-method" property to expose the scaling mode to use during + video processing. Note that this is only a hint, and the actual behaviour + may differ from implementation (VA driver) to implementation. + +2014-10-29 16:57:12 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + filter: add initial support for high quality scaling. + Add support for video scaling options in VPP pipelines. Only the + DEFAULT mode is bound to exist. Others might be folded into that + mode. + +2014-10-29 16:35:46 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + filter: re-indent all GstVaapiFilter related source code. + +2014-10-29 15:45:50 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit f9d3bde. + 2218b02 h264parse: expose parsed profile and level to downstream + 3dbfab4 h264parse: return flushing if we get chained while being set to READY + d40fa8b h264: fix frame packing SEI parsing + 32d40be h264: Use proper bit_reader api while parsing buffering_period SEI + b3e022e h264: initialize some fields of pic_timing structure + a70661d vc1: fix expected level in sequence-layer parsing unit test + 6cee88d vc1: fix level values for simple/main profile + 356c189 vc1: add unit test for sequence-layer parsing + ab9f641 vc1: take care of endianness when parsing sequence-layer + 8dc8e35 mpeg4: fix vlc table used for sprite trajectory + +2014-10-29 15:46:47 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Expose the supported profiles as caps to upstream + This will allows the playbin to fallback to Software Decoder + if the Hardware Decoder does not support a particular profile. + https://bugzilla.gnome.org/show_bug.cgi?id=730997 + +2014-10-29 15:46:12 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + encode: Attach the codec-data to out caps only based on negotiated caps + Attach the codec_data to out_caps only if downstream needed. + For eg: h264 encoder doesn't need to stuff codec_data to the + src caps if the negotiated caps has a stream format of byte-stream. + https://bugzilla.gnome.org/show_bug.cgi?id=734902 + +2014-10-29 15:45:44 +0200 Sreerenj Balachandran + + * configure.ac: + configure: echoing installation prefix path + +2014-09-24 10:14:24 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + display: add support for DRM Render-Nodes. + Add support for DRM Render-Nodes. This is a new feature that appeared + in kernel 3.12 for experimentation purposes, but was later declared + stable enough in kernel 3.15 for getting enabled by default. + This allows headless usages without authentication at all, i.e. usages + through plain ssh connections is possible. + +2014-09-24 13:44:43 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: clean-ups (indentation, drop unused variables). + +2014-09-24 13:39:55 +0200 Gwenole Beauchesne + + * configure.ac: + * gst/vaapi/gstvaapisink.c: + vaapisink: fix GstNavigation "key-press" / "key-release" events. + Fix arguments to XkbKeycodeToKeysym() for converting an X11 keycode + to a KeySym. In particular, there is no such Window argument. Also + make sure to check for, and use, the correct header + where that new function is defined. Otherwise, default to the older + XKeycodeToKeysym() function. + +2014-09-24 13:23:17 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix GstNavigation "mouse-move" event. + Really use the motion event coordinates to propagate the "mouse-move" + event to upper layer, instead of those from a button event. Those are + technically the same though. + +2014-09-16 14:25:40 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapisink.c: + vaapisink: implement the GstNavigation interface + This is useful for things like DVD menus, where key/mouse events + would need to be forwarded from the upstream sink element. + https://bugzilla.gnome.org/show_bug.cgi?id=711479 + +2014-03-13 18:38:33 +0000 Simon Farnsworth + + * gst/vaapi/gstvaapipluginbase.c: + vaapipostproc: fix deinterlacing from non VA memory buffers. + When we copy a buffer because we're moving it into VA-API memory, we + need to copy flags. Otherwise, interlaced YUV buffers from a capture + source (e.g. V4L2) don't get flagged as interlaced. + https://bugzilla.gnome.org/show_bug.cgi?id=726270 + Signed-off-by: Simon Farnsworth + [reversed order of gst_buffer_copy_into() flags to match <1.0 code] + Signed-off-by: Gwenole Beauchesne + +2014-08-22 15:22:32 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: add support for GLTextureUploadMeta output. + This allows for vaapipostproc to be chained to the glimagesink element + for instance. + https://bugzilla.gnome.org/show_bug.cgi?id=735231 + +2014-08-22 15:22:32 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: add support for "download" capability. + Allow implicit conversions to raw video formats, while still keeping + VA surfaces underneath. This allows for chaining the vaapipostproc + element to a software-only element that takes care of maps/unmaps. + e.g. xvimagesink. + https://bugzilla.gnome.org/show_bug.cgi?id=720174 + +2014-08-22 18:10:54 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: use pooled vaapi video meta. + Use pooled GstVaapiVideoMeta information, i.e. always allocate that on + video buffer allocation. Also optimize copy of additional metadata info + into the resulting video buffer: only copy the video cropping info and + the source surface proxy. + https://bugzilla.gnome.org/show_bug.cgi?id=720311 + Signed-off-by: Sreerenj Balachandran + [fixed proxy leak, fixed double free on error, optimized meta copy] + Signed-off-by: Gwenole Beauchesne + +2014-08-22 15:17:29 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix passthrough mode. + If no explicit output surface format is supplied try to keep the one + supplied through the sink pad caps. This avoids a useless copy, even + if things are kept in GPU memory. + This is a performance regression from git commit dfa70b9. + +2014-07-05 21:00:34 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: fix output buffer to have a GstVaapiVideoMemory. + https://bugzilla.gnome.org/show_bug.cgi?id=720311 + [used new infrastructure through base decide_allocation() impl] + Signed-off-by: Gwenole Beauchesne + +2014-08-22 11:13:36 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: enable advanced deinterlacing with same format. + If only advanced deinterlacing is requested, i.e. deinterlacing is + the only active algorithm to apply with source and output surface + formats being the same, then make sure to enable VPP processing. + Otherwise, allow fallback to bob-deinterlacing with simple rendering + flags alteration. + +2014-08-21 15:04:20 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: avoid NULL pointer unref if GstVaapiImage creation failed. + https://bugzilla.gnome.org/show_bug.cgi?id=735156 + +2014-08-22 13:25:03 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + plugins: fix memory leaks. + +2014-08-21 14:10:36 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: factor out decide_allocation() hook. + Add a default decide_allocation() hook to GstVaapiPluginBase. The caps + feature argument can be used to force a bufferpool with a specific kind + of memory. + +2014-08-21 11:12:39 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideobufferpool.h: + * gst/vaapi/gstvaapivideomemory.c: + plugins: allow bufferpool to not allocate vaapi video meta. + Add GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC params flag that + can be used to disable early allocations of vaapi video metas on buffers, + thus delagating that to the bufferpool user. + +2014-08-21 10:45:31 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideobuffer.h: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideobufferpool.h: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideoconverter_glx.h: + * gst/vaapi/gstvaapivideoconverter_x11.c: + * gst/vaapi/gstvaapivideoconverter_x11.h: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa.h: + * gst/vaapi/gstvaapivideometa_texture.c: + * gst/vaapi/gstvaapivideometa_texture.h: + plugins: re-indent all GstVaapiVideo* related source code. + +2014-08-22 15:12:46 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + surfaceproxy: fix copy to propagate view_id. + Fix gst_vaapi_surface_proxy_copy() to copy the view-id element, thus + fixing random frames skipped when vaapipostproc element is used in + passthrough mode. In that mode, GstMemory is copied, thus including + the underlying GstVaapiVideoMeta and associated GstVaapiSurfaceProxy. + +2014-08-20 16:38:45 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix detection of output surface format changes. + Default to I420 format for output surfaces so that to match the usual + GStreamer pipelines. Though, internally, we could still opt for NV12 + surface formats, i.e. default format=ENCODED is a hint for that, thus + delegating the decision to the VA driver. + +2014-08-20 10:59:53 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix construction of allowed sink pad caps. + Fix construction of the set of caps allowed on the sink pad to filter + out unsupported raw video caps with GStreamer >= 1.2. + +2014-08-20 10:37:02 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: improve heuristics for detecting native VA surfaces. + Use the new gst_caps_has_vaapi_surface() helper function to detect + whether the sink pad caps contain native VA surfaces, or not, i.e. + no raw video caps. + Also rename is_raw_yuv to get_va_surfaces to make the variable more + explicit as we just want a way to differentiate raw video caps from + VA surfaces actually. + +2014-08-12 18:33:25 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: disable discontinuity detection code. + The "discontinuity" tracking code, whereby lost frames are tentatively + detected, is inoperant if the sink pad buffer timestamps are not right + to begin with. + This is a temporary workaround until the following bug is fixed: + https://bugzilla.gnome.org/show_bug.cgi?id=734386 + +2014-08-07 14:57:26 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix heuristic for detecting discontinuity. + In order to make the discontinuity detection code useful, we need to + detect the lost frames in the history as early as the previous frame. + This is because some VA implementations only support one reference + frame for advanced deinterlacing. + In practice, turn the condition for detecting new frame that is beyond + the previous frame from field_duration*2 to field_duration*3, i.e. + nothing received for the past frame and a half because of possible + rounding errors when calculating the field-duration either in this + element (vaapipostproc), or from the upstream element (parser element). + This is a regression introduced with commit faefd62. + https://bugzilla.gnome.org/show_bug.cgi?id=734135 + +2014-08-20 11:43:08 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: fix detection of raw video caps. + Use the new gst_caps_has_vaapi_surface() helper function to better + detect raw video caps, and in particular those from RGB colorspace. + https://bugzilla.gnome.org/show_bug.cgi?id=734665 + +2014-08-20 11:30:41 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + plugins: add helper for detecting VA surfaces in caps. + Introduce new gst_caps_has_vaapi_surface() helper function to detect + whether the supplied caps has VA surfaces. With GStreamer >= 1.2, this + implies a check for memory:VASurface caps features, and format=ENCODED + for earlier versions of GStreamer. + +2014-08-12 13:01:57 +0300 Sebastian Dröge + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: start the decoder task again after finishing + This allows the element to accept data again after draining without + a hard reset or caps change happening in between. + https://bugzilla.gnome.org/show_bug.cgi?id=734616 + +2014-08-12 13:00:03 +0300 Sebastian Dröge + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: unlock condition variables before shutting down the element + Otherwise threads might wait for them, causing the shutdown of the element + to deadlock on the streaming thread. + https://bugzilla.gnome.org/show_bug.cgi?id=734616 + +2014-08-11 17:15:24 +0300 Sebastian Dröge + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: reset decoder_finish variable after stopping the decoder thread + Otherwise the element is not usable again after draining/EOS. + https://bugzilla.gnome.org/show_bug.cgi?id=734616 + +2014-08-11 17:14:53 +0300 Sebastian Dröge + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: don't try flushing the decoder instance if we didn't create one yet + This otherwise results in unnecessary error messages. + https://bugzilla.gnome.org/show_bug.cgi?id=734616 + +2014-08-01 06:32:32 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst/vaapi/Makefile.am: + build: fix with --no-undefined linker flags. + https://bugzilla.gnome.org/show_bug.cgi?id=729352 + +2014-01-23 15:44:09 +0000 Changzhi Wei + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: add support for GstColorBalance interface. + https://bugzilla.gnome.org/show_bug.cgi?id=722390 + [fixed channel names, simplified range factor, fixed memory leak] + Signed-off-by: Gwenole Beauchesne + +2014-01-23 15:23:00 +0000 Changzhi Wei + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: add support for colorbalance adjustment. + https://bugzilla.gnome.org/show_bug.cgi?id=722390 + [fixed and simplified tracking of colorbalance value changes] + Signed-off-by: Gwenole Beauchesne + +2014-07-31 13:18:21 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: improve installation of properties. + Simplify the creation and installation process of properties, by first + accumulating them into a g_properties[] array, and next calling into + g_object_class_install_properties(). + Also add missing docs and flags to some properties. + +2014-07-31 10:48:15 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: code clean-ups. + Move code around in a more logical way. Introduce GST_VAAPISINK_CAST() + helper macro and use it wherever we know the object is a GstBaseSink or + any base class. Drop explicit initializers for values that have defaults + set to zero. + +2014-07-31 10:37:57 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: re-indent all GstVaapiSink related source code. + +2014-07-30 17:27:50 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: introduce separate backends. + Introduce new backends vtable so that to have clean separation between + display dependent code and common base code. That's a "soft" separation, + we don't really need dedicated objects. + https://bugzilla.gnome.org/show_bug.cgi?id=722248 + +2014-07-30 16:47:20 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: drop unused "synchronous" mode. + Support for X11 "synchronous" mode was never implemented, and was only + to be useful for debugging. Drop that altogether, that's not going to + be useful in practice. + https://bugzilla.gnome.org/show_bug.cgi?id=733985 + +2014-07-30 17:32:29 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: drop unused variables. + Drop obsolete, and now unused, video_buffer_pool and video_buffer_size + variables. They got merged into the GstVaapiPluginBase object. + +2014-07-30 16:35:32 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: drop GLX rendering and fancy effects. + Rendering with GLX in vaapisink is kind of useless nowadays, including + OpenGL related fancy effects. Plain VA/GLX interfaces are also getting + deprecated in favor of EGL, or more direct buffer sharing with actual + GL textures. + Should testing of interop with GLX be needed, one could still be using + the modern cluttersink or glimagesink elements. + https://bugzilla.gnome.org/show_bug.cgi?id=733984 + +2013-11-05 14:01:11 +0100 Holger Kaelberer + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: listen to window size changes on X11. + Allow dynamic changes to the window, e.g. performed by the user, and + make sure to refresh its contents, while preserving aspect ratio. + In practice, Expose and ConfigureNotify events are tracked in X11 + display mode by default. This occurs in a separte event thread, and + this is similar to what xvimagesink does. Any of those events will + trigger a reconfiguration of the window "soft" size, subsequently + the render-rect when necessary, and finally _expose() the result. + The default of handle_events=true can be changed programatically via + gst_x_overlay_handle_events(). + Thanks to Fabrice Bellet for rebasing the patch. + https://bugzilla.gnome.org/show_bug.cgi?id=711478 + [dropped XInitThreads(), cleaned up the code a little] + Signed-off-by: Gwenole Beauchesne + +2014-07-29 15:47:46 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: decode and output all pending frames on normal EOS. + The gst_vaapidecode_decode_loop() function is called within a separate + task to fetch and output all frames that were decoded so far. So, if + the decoder_loop_status is forcibly set to EOS when _finish() is called, + then we are bound to exist the task without submitting the pending + frames. + If the downstream element error'ed out, then the gst_pad_push() would + propagate up an error and so we will get it right for cutting off + _finish() early in that case. + This is a regression from 6003596. + https://bugzilla.gnome.org/show_bug.cgi?id=733897 + +2014-07-29 13:24:52 +0200 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2014-07-29 10:31:58 +0200 Gwenole Beauchesne + + * AUTHORS: + AUTHORS: updates. + +2014-07-29 10:31:15 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2014-07-29 16:22:01 +1000 Matthew Waters + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: properly return from decode loop on downstream errors. + Fixes a hang/race on shutdown where _decode_loop() had already completed + its execution and _finish() was waiting on a GCond for decode_loop() + to complete. Also fixes the possible race where _finish() is called + but _decode_loop() endlessly returns before signalling completion + iff the decoder instance returns GST_FLOW_OK. + Found with: ... ! vaapidecode ! {glimagesink,cluttersink} + https://bugzilla.gnome.org/show_bug.cgi?id=733897 + [factored out GST_VIDEO_DECODER_STREAM_UNLOCK() call] + Signed-off-by: Gwenole Beauchesne + +2014-07-28 18:45:49 +0200 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.5.9. + +2014-07-28 18:31:09 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix GstVideoOverlay::expose() implementation. + Now that we always track the currently active video buffer, it is + not necessary to automatically increase its reference since this is + implicitly performed in ::show_frame() through the get_input_buffer() + helper from GstVaapiPluginBase class. + This is a regression from a26df80. + +2014-07-28 18:00:19 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.c: + vaapidecode: simplify bufferpool configuration. + Rework the logics behind the configuration of an adequate bufferpool, + especially when OpenGL meta or additional capsfeatures are needed. + Besides, for GStreamer >= 1.4, the first capsfeatures that gets matched, + and that is not system memory, is now selected by default. + +2014-07-28 16:43:47 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix auto-plugging of vaapisink element. + Make sure to propagate memory:VASurface capsfeature to srcpad caps + only for GStreamer >= 1.5 as the plug-in elements in GStreamer 1.4 + core currently miss additional patches available in 1.5-git (1.6). + This is a temporary workaround. + +2014-07-28 15:54:46 +0300 Sreerenj Balachandran + + * configure.ac: + configure: allow builds against GStreamer git (1.5.x). + https://bugzilla.gnome.org/show_bug.cgi?id=733688 + +2014-07-28 14:20:33 +0200 Gwenole Beauchesne + + * configure.ac: + configure: fix build with GStreamer 1.4.0 release. + +2014-03-04 19:40:59 +0100 Gwenole Beauchesne + + * configure.ac: + * debian.upstream/Makefile.am: + * debian.upstream/control.in: + debian: fix packaging for new naming scheme. + +2014-07-28 11:52:06 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2014-07-28 11:39:11 +0200 Gwenole Beauchesne + + * configure.ac: + configure: mark support for GStreamer < 1.2 as deprecated. + Supporting anything thing below GStreamer 1.2 is asking for trouble + for keeping up with the required facilities to make efficient pipelines. + Users are invited to upgrade to the very latest GStreamer 1.2.x release, + at the minimum. + +2014-07-28 11:35:24 +0200 Gwenole Beauchesne + + * configure.ac: + configure: mark support for GStreamer 0.10 as obsolete. + Support for GStreamer 0.10 is obsolete. i.e. it is no longer supported + and may actually be removed altogether for a future release. There is + no real point to maintain a build for such an ancient GStreamer version + that is not even supported upstream. + +2014-07-28 10:25:26 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: allow a specific view component to be displayed. + If a multiview stream is decoded, multiple view components are submitted + as is downstream. It is the responsibility of the sink element to display + the required view components. By default, always select the frame buffer + that matches the view-id of the very first frame to be displayed. + However, introduce a "view-id" property to allow the selection of a + specific view component of interest to display. + +2014-07-28 10:09:34 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: always keep the last displayed buffer around. + Always record the VA surface that is currently being rendered, no matter + the fact we are using texturedblit or overlay. That's because in some + occasions, we need to refresh or resize the displayed contents based on + new events. e.g. user-resized window. + Besides, it's simpler to track the last video buffer in GstVaapiSink than + through the base sink "last-sample". + +2014-07-25 11:13:29 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapisink.c: + vaapisink: add support for "display-name" property. + Add a "display-name" property to vaapisink so that the end user could + select the desired output. Keep "display-name" in-line with the existing + "display" (GstVaapiDisplayXXX type). + So, for X11 or GLX, the "display-name" is the usual display name as we + know for XOpenDisplay(); for Wayland, the "display-name" is the name used + for wl_display_connect(); and for DRM, the "display-name" is actually the + DRI device name. + https://bugzilla.gnome.org/show_bug.cgi?id=722247 + +2014-07-25 17:29:40 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + window: make gst_vaapi_window_reconfigure() thread-safe. + Ensure the X11 implementation for GstVaapiWindow::get_geometry() is + thread-safe by default, so that upper layer users don't need to handle + that explicitly. + +2013-07-29 09:28:28 +0200 Holger Kaelberer + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + window: allow for updating size from current geometry. + Add gst_vaapi_window_reconfigure() interface to force an update of + the GstVaapiWindow "soft" size, based on the current geometry of the + underlying native window. + This can be useful for instance to synchronize the window size when + the user changed it. + Thanks to Fabrice Bellet for rebasing the patch. + [changed interface to gst_vaapi_window_reconfigure()] + Signed-off-by: Gwenole Beauchesne + +2014-07-25 16:53:41 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.c: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + window: re-indent all GstVaapiWindow related source code. + +2014-07-25 11:24:39 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + display: add interface to retrieve the display name. + Add gst_vaapi_display_get_display_name() helper function to determine + the name associated with the underlying native display. Note that for + raw DRM backends, the display name is actually the device path. + +2014-07-25 10:55:53 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + display: fix comparison of X11 display names. + Make sure to not only compare display host names, but also the actual + display number. The screen number does not need to be checked at this + time. + +2014-07-25 15:52:06 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapivideobufferpool.c: + vaapidecode: add support for VideoAlignment bufferpool option. + Always add VideoAlignment bufferpool option if the downstream element + expects its own pool to be used but does not offer it through a proper + propose_allocation() implementation for instance, and that the ALLOCATION + query does not expose the availability of the Video Meta API. + This fixes propagation of video buffer stride information to Firefox. + +2014-07-25 15:44:58 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: always prefer native VA surface formats. + Make sure to always prefer native internal formats for the VA surfaces + that get allocated. Also disable "direct-rendering" mode in this case. + This is needed so that to make sure that anything that gets out of the + decoder, or anything that gets into the encoder, is in native format + for the hardware, and thus the driver doesn't need to perform implicit + conversions in there. Interop with SW elements is still available with + fast implementations of VA imaging APIs. + +2014-07-24 11:58:29 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: disallow memory shares across buffers, use a copy. + Forbid shares of GstMemory instances, and rather make copy of it. This + effectively copies the GstMemory structure and enclosed metadata, but + this does not copy the VA surface contents itself. It should though. + This fixes preroll and makes sure to not download garbage for the first + frame when a SW rendering sink is used. + +2014-07-24 06:46:22 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: use an image pool to cache objects. + Use an image pool to hold VA images to be used for downloads/uploads + of contents for the associated surface. + This is an optmization for size. So, instead of creating as many VA + images as there are buffers (then VA surfaces) allocated, we only + maintain a minimal set of live VA images, thus preserving memory + resources. + +2014-07-24 00:14:04 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: forbid R/W mappings if non direct-rendering mode. + Disable read-write mappings if "direct-rendering" is not supported. + Since the ordering of read and write operations is not specified, + this would require to always download the VA surface on _map(), then + commit the temporary VA image back to the VA surface on _unmap(). + Some SW decoding plug-in elements still use R/W mappings though. + https://bugzilla.gnome.org/show_bug.cgi?id=733242 + +2014-07-23 23:49:53 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: minor code clean-ups. + Fix error messages introduced in the previous commit for the _map() + imaplementation. Also use the new get_image_data() helper function + to determine the base pixels data buffer from a GstVaapiImage when + updating the video info structure from it. + +2014-07-23 18:54:13 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: add support for raw pixels mappings. + Allow raw pixels of the whole frame to be mapped read-only. i.e. in + cases where the buffer pool is allocated without VideoMeta API, thus + individual planes cannot be mapped. + This is initial support for Firefox >= 30. + https://bugzilla.gnome.org/show_bug.cgi?id=731886 + +2014-07-03 18:41:11 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: fix determination of the surface pool format. + While creating the vaapi video allocator, make sure the associated + surface pool has correct format instead of defaulting to NV12 video + format even though there is no direct rendering support. + https://bugzilla.gnome.org/show_bug.cgi?id=732691 + +2014-07-23 18:01:21 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: fix association of surface to proxy. + Make sure to always update the VA surface pointer whenever the proxy + changes. This used to only work when the VA surface is written to, in + interop with SW element ("upload" feature), and this now fixes cases + when the VA surface is needed for reading, in interop with SW element + ("download" feature). + +2014-07-23 10:23:06 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapivideomemory.c: + plugins: expose I420 format for interop with SW elements. + Always expose I420 format by default when the VA surface could be + mapped for interoperability with non harware accelerated elements. + However, the default behaviour remains the auto-plugging of vaapi + elements, down to the sink. + Side effect: "direct-rendering" mode is also disabled most of the + times as plain memcpy() from uncached speculative write combining + memory is not going to be efficient enough. + +2014-07-22 18:54:29 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapivideomemory.c: + plugins: allow download capability to vaapidecode element. + Fix support for VA surface download capability in vaapidecode element + for GStreamer >= 1.2. This is a fix to supporting libva-vdpau-driver, + but also the libva-intel-driver while performing hardware accelerated + conversions from the native VA surface format (NV12) to the desired + output VA image format. + For instance, this fixes pipelines involving vaapidecode ! xvimagesink. + https://bugzilla.gnome.org/show_bug.cgi?id=733243 + +2014-07-17 01:51:36 +0200 Fabrice Bellet + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + decoder: mpeg4: fix picture decoder return value for skipped frames. + The picture decoder should return GST_VAAPI_DECODER_STATUS_DROP_FRAME + when a frame should be skipped, so the stream processing is not stalled. + https://bugzilla.gnome.org/show_bug.cgi?id=733324 + +2014-07-04 15:13:32 +1000 Jan Schmidt + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + decoder: mpeg2: respect any input PTS provided for a frame. + The timestamp generator in gstvaapidecoder_mpeg2.c always interpolated + frame timestamps within a GOP, even when it's been fed input PTS for + every frame. + That leads to incorrect output timestamps in some situations - for example + live playback where input timestamps have been scaled based on arrival time + from the network and don't exactly match the framerate. + https://bugzilla.gnome.org/show_bug.cgi?id=732719 + +2014-01-22 08:20:59 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiobject.c: + GstVaapiObject: make gst_vaapi_object_new() more robust. + Forbid GstVaapiObject to be created without an associated klass spec. + It is mandatory that the subclass implements an adequate .finalize() + hook, so it shall provide a valid GstVaapiObjectClass. + https://bugzilla.gnome.org/show_bug.cgi?id=722757 + [made non-NULL klass argument to gst_vaapi_object_new() a requirement] + Signed-off-by: Gwenole Beauchesne + +2014-01-21 15:43:57 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiobject.c: + GstVaapiObject: initialize the derived object data with init() hook. + Call the subclass .init() function in gst_vaapi_object_new(), if + needed. The default behaviour is to zero initialize the subclass + object data, then the .init() function can be used to initialize + fields to non-default values, e.g. VA object ids to VA_INVALID_ID. + Also fix the gst_vaapi_object_new() description, which was merely + copied from GstVaapiMiniObject. + https://bugzilla.gnome.org/show_bug.cgi?id=722757 + [changed to always zero initialize the subclass] + Signed-off-by: Gwenole Beauchesne + +2014-06-13 21:45:04 +0100 Lionel Landwerlin + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: make decoder work with playbin + When playbin/decodebin builds the pipeline, it puts decoders and sinks + into different bins and forwards the queries from bins to bins. So in + the initials steps the pipeline is built iteratively by playbin and + looks like this : + [filesrc] + [filesrc] -> [typefind] + [filesrc] -> [typefind] -> [demuxer] + [filesrc] -> [typefind] -> [demuxer] -> [decoder] + At this point the decoder is asked for its SRC caps and it will make a + choice based on what gst_pad_peer_query_caps() returns. The problem is + that the caps returns at that point includes caps features like ANY, + essentially because playbin can plug in additional elements like + videoscale, videoconv or deinterlace. + This patch adds a another call to + gst_vaapi_find_preferred_caps_feature() when the decoder decides its + allocation, to make sure we asks the downstream elements when the + entire pipeline has been built. + https://bugzilla.gnome.org/show_bug.cgi?id=731645 + +2014-06-27 11:57:11 +0100 Simon Farnsworth + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: don't let tmp_rect go out of scope. + A compiler change showed me that tmp_rect went out of scope before + it was used. Move it to the beginning of the function instead. + https://bugzilla.gnome.org/show_bug.cgi?id=726363 + Signed-off-by: Simon Farnsworth + [added guards for GStreamer 0.10 builds] + Signed-off-by: Gwenole Beauchesne + +2014-07-03 22:44:40 +0200 Gwenole Beauchesne + + * AUTHORS: + AUTHORS: updates. + +2014-07-03 22:34:35 +0200 Gwenole Beauchesne + + * README: + README: updates. + Drop references to deprecated plugins (vaapiupload, vaapidownload), + mention that support for GStreamer 0.10 is deprecated, make overview + more descriptive in certain aspects. + +2014-07-03 22:21:39 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2014-07-03 19:42:02 +0200 Gwenole Beauchesne + + * README: + * configure.ac: + build: mention that support for GStreamer 0.10 is deprecated. + +2014-07-03 17:17:00 +0200 Gwenole Beauchesne + + * configure.ac: + * gst/vaapi/gstvaapidecode.c: + build: fix for GStreamer 0.10. + +2014-07-03 18:01:09 +0200 Gwenole Beauchesne + + * patches/videoparsers/0002-h264parse-fix-build-with-GStreamer-1.2.patch: + * patches/videoparsers/0002-h264parse-fix-build-with-older-GStreamer-1.x-stacks.patch: + * patches/videoparsers/series.frag: + build: fix for GStreamer 1.0.x. + +2014-07-03 13:48:48 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: detect incorrectly paired fields in frames. + When a DPB flush is required, e.g. at a natural and of stream or issued + explicitly through an IDR, try to detect any frame left in the DPB that + is interlaced but does not contain two decoded fields. In that case, mark + the picture as having a single field only. + This avoids a hang while decoding tv_cut.mkv. + +2014-07-03 11:13:33 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: simplify the DPB output process. + Simplify the dpb_output() function to exclusively rely on the frame store + buffer to output, since this is now always provided. Besides, also fix + cases where split fields would not be displayed. + This is a regression from f48b1e0. + +2014-07-01 17:20:44 +0200 Gwenole Beauchesne + + * patches/videoparsers/0003-h264parse-fix-and-optimize-NAL-collection-function.patch: + * patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch: + * patches/videoparsers/0006-h264parse-improve-conditions-for-skipping-NAL-units.patch: + * patches/videoparsers/0007-h264parse-fix-collection-of-access-units-to-preserve.patch: + * patches/videoparsers/series.frag: + h264parse: drop patches merged upstream. + 0003-h264parse-fix-and-optimize-NAL-collection-function.patch + 0005-h264parse-introduce-new-state-tracking-variables.patch + 0006-h264parse-improve-conditions-for-skipping-NAL-units.patch + 0007-h264parse-fix-collection-of-access-units-to-preserve.patch + +2014-07-01 17:18:08 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix memory leak in PPS. + Cope with latest changes from codecparsers/h264. It is now required + to explicitly clear the GstH264PPS structure as it could contain + additional allocations (slice_group_ids). + +2014-07-01 17:13:56 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 2d53b69. + c4ace00 h264parse: fix collection of access units to preserve config headers + 0f9f7c9 h264parse: improve conditions for skipping NAL units + 9ffb25c h264parse: introduce new state tracking variables + 64955d3 h264parse: fix and optimize NAL collection function + 13cd2a3 h264: clarifications and documentation fixes + 53e7dd1 h264: fix identification of EOSEQ and EOS NALs + 18f0de0 h264: fix memory leak in GstH264PPS + fdcb54c h264: fix typo in GstH264VUIParams description + fd4dae9 vp8: move up built-in range decoder private data + +2014-06-30 19:01:35 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + decoder: propagate MVC metadata ("view-id", head of multiview set). + Add new GstVaapiSurfaceProxy flag FFB, which means "first frame in + bundle", and really expresses the first view component of a multi + view coded frame. e.g. in H.264 MVC, the surface proxy has flag FFB + set if VOIdx = 0. + Likewise, new API is exposed to retrieve the associated "view-id". + +2014-06-30 18:46:45 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + decoder: propagate "one-field" flags. + Allow decoders to set the "one-field" attribute when the decoded frame + genuinely has a single field, or if the second field was mis-decoded but + we still want to display the first field. + +2014-06-30 18:34:45 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + decoder: output decoded frames only once. + Make sure to output the decoded picture, and push the associated + GstVideoCodecFrame, only once. The frame fully represents what needs + to be output, included for interlaced streams. Otherwise, the base + GstVideoDecoder class would release the frame twice. + Anyway, the general process is to output decoded frames only when + they are complete. By complete, we mean a full frame was decoded or + both fields of a frame were decoded. + +2014-06-30 16:12:52 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: decode current picture earlier. + Slightly optimize decoding process by submitting the current VA surface + for decoding earlier to the hardware, and perform the reference picture + marking process and DPB update process afterwards. + This is a minor optimization to let the video decode engine kick in work + earlier, thus improving parallel resources utilization. + +2014-06-30 16:09:17 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix output of second field when first field is not in DPB. + Fix decoding of interlaced streams where a first field (e.g. B-slice) + was immediately output and the current decoded field is to be paired + with that former frame, which is no longer in DPB. + https://bugzilla.gnome.org/show_bug.cgi?id=701340 + +2014-06-30 11:06:29 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: slightly optimize the process to detect new pictures. + Optimize the process to detect new pictures or start of new access + units by checking if the previous NAL unit was the end of a picture, + or the end of the previous access unit. + +2014-06-13 15:42:53 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: handle access unit ("au") optimization. + Optimize parsing when buffers are supplied with access unit alignment. + This helps determining faster when the end of an access unit is reached. + +2014-06-28 07:25:35 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix tracking of DPB size changes. + Add support for MVC streams with multiple SPS and subset SPS headers + emitted regularly, e.g. at around every I-frame. Track the maximum + number of views in ensure_context() and really reset the DPB size to + the expected value, always. i.e. even if it decreased. dpb_reset() + only cares of ensuring the DPB allocation. + +2014-06-27 20:44:24 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix the DPB compaction process. + Fix the compaction process when the DPB is cleared for a specific + view, i.e. fix the process of filling in the holes resulting from + removing frame buffers matching the current picture. + +2014-06-27 16:38:03 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: generate new SPS only when codec config changed. + It is not necessary to periodically send SPS or subset SPS headers. + This is up to the upper layer (e.g. transport layer) to decide on + if/how to periodically submit those. For now, only generate new SPS + or subset SPS headers when the codec config changed. + Note: the upper layer could readily determine the config headers + (SPS/PPS) through the gst_vaapi_encoder_h264_get_codec_data() function. + https://bugzilla.gnome.org/show_bug.cgi?id=732083 + Signed-off-by: Gwenole Beauchesne + +2014-06-27 18:43:27 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: track encoder config changes. + Track and report when encoder configuration changed. For now, this covers + resolution, profile/level and bitrate changes. + +2014-06-27 13:15:13 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: add pixel-aspect-ratio to VUI parameters. + Report sample aspect ratio (SAR) as present, and make it match what + we have obtained from the user as pixel-aspect-ratio (PAR). i.e. the + VUI parameter aspect_ratio_info_present_flag now defaults to TRUE. + +2014-06-27 00:49:34 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix number of anchor and non-anchor reference pictures. + Set the value of num_anchor_refs_l0, num_anchor_refs_l1, num_non_anchor_refs_l0, + and num_non_anchor_refs_l1 to zero since the inter-view prediction is not yet + supported. + +2014-06-27 10:37:38 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix timing_info_present_flag value in subset SPS. + When the seq_parameter_set_data() syntax structure is present in a subset + sequence parameter set and vui_parameters_present_flag is equal to 1, then + timing_info_present_flag shall be equal to 0 (H.7.4.2.1.1). + +2014-06-26 14:39:52 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: add cpbBrNalFactor values for MVC profiles. + +2014-06-26 14:51:32 +0200 Gwenole Beauchesne + + * patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch: + h264parse: fix detection of access unit boundaries for MVC. + The gst_h264_parse_collect_nal() function is a misnomer. In reality, + this function is used to determine access unit boundaries, i.e. that + is the key function for alignment=au output format generation. + +2014-06-26 14:49:53 +0200 Gwenole Beauchesne + + * patches/videoparsers/0007-h264parse-fix-collection-of-access-units-to-preserve.patch: + * patches/videoparsers/series.frag: + h264parse: fix collection of access units to preserve config headers. + Always use a GstAdapter when collecting access units (alignment="au") + in either byte-stream or avcC format. This is required to properly + preserve config headers like SPS and PPS when invalid or broken NAL + units are subsequently parsed. + More precisely, this fixes scenario like: + + where we used to reset the output frame buffer when an invalid or + broken NAL is parsed, i.e. SPS and PPS NAL units were lost, thus + preventing the next slice unit to be decoded, should this also + represent any valid data. + https://bugzilla.gnome.org/show_bug.cgi?id=732203 + +2014-06-26 14:48:08 +0200 Gwenole Beauchesne + + * patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch: + * patches/videoparsers/0006-h264parse-improve-conditions-for-skipping-NAL-units.patch: + * patches/videoparsers/series.frag: + h264parse: improve conditions for skipping NAL units. + Carefully track cases when skipping broken or invalid NAL units is + necessary. In particular, always allow NAL units to be processed + and let that gst_h264_parse_process_nal() function decide on whether + the current NAL needs to be dropped or not. + This fixes parsing of streams with SEI NAL buffering_period() message + inserted between SPS and PPS, or SPS-Ext NAL following a traditional + SPS NAL unit, among other cases too. + Practical examples from the H.264 AVC conformance suite include + alphaconformanceG, CVSE2_Sony_B, CVSE3_Sony_H, CVSEFDFT3_Sony_E + when parsing in stream-format=byte-stream,alignment=au mode. + https://bugzilla.gnome.org/show_bug.cgi?id=732203 + +2014-06-26 14:45:34 +0200 Gwenole Beauchesne + + * patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch: + * patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch: + * patches/videoparsers/series.frag: + h264parse: introduce new state tracking variables. + Improve parser state tracking by introducing new flags reflecting + it: "got-sps", "got-pps" and "got-slice". This is an addition for + robustness purposes. + Older have_sps and have_pps variables are kept because they have + a different meaning. i.e. they are used for deciding on when to + submit updated caps or not, and rather mean "have new SPS/PPS to + be submitted?" + +2014-06-26 14:39:30 +0200 Gwenole Beauchesne + + * patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch: + * patches/videoparsers/series.frag: + h264parse: default to byte-stream/nalu format (Annex B). + Always default to stream-format=byte-stream,alignment=nalu if avcC + format was not detected. This is the natural stream format specified + in the standard (Annex.B): a series of NAL units prefixed with the + usual start code. + https://bugzilla.gnome.org/show_bug.cgi?id=732167 + +2014-06-26 14:37:58 +0200 Gwenole Beauchesne + + * patches/videoparsers/0003-h264parse-fix-and-optimize-NAL-collection-function.patch: + * patches/videoparsers/series.frag: + h264parse: fix and optimize NAL collection function. + Use gst_h264_parser_identify_nalu_unchecked() to identify the next + NAL unit. We don't want to parse the full NAL unit, but only the + header bytes and possibly the first RBSP byte for identifying the + first_mb_in_slice syntax element. + Also fix check for failure when returning from that function. The + only success condition for that is GST_H264_PARSER_OK, so use it. + https://bugzilla.gnome.org/show_bug.cgi?id=732154 + +2014-06-26 11:39:38 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix NAL unit types in packed headers. + Submit Prefix NAL headers (nal_unit_type = 14) before every packed + slice header (nal_unit_type = 1 or 5) only for the base view. In non + base views, a Coded Slice Extension NAL header (nal_unit_type = 20) + is required, with an appropriate nal_unit_header_mvc_extension() in + the NAL header bytes. + https://bugzilla.gnome.org/show_bug.cgi?id=732083 + +2014-06-25 22:05:52 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: add missing field in packed Subset SPS header. + Write the missing num_level_values_signalled_minus1 syntax element + into the packed header for subset sequence parameter set. + https://bugzilla.gnome.org/show_bug.cgi?id=732083 + +2014-06-25 22:26:32 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix marking of non-reference picture into DPB. + Fix search for a picture in the DPB that has a lower POC value than + the current picture. The dpb_find_lowest_poc() function will return + a picture with the lowest POC in DPB and that is marked as "needed + for output", but an additional check against the actual POC value + of the current picture is needed. + This is a regression from 1c46990. + https://bugzilla.gnome.org/show_bug.cgi?id=732130 + +2014-06-19 17:08:47 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix DPB clear when no decoding actually started. + Fix dpb_clear() to clear previous frame buffers only if they actually + exist to begin with. If the decoder bailed out early, e.g. when it + does not support a specific profile, that array of previous frames + might not be allocated beforehand. + +2014-02-06 08:30:10 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + * gst/vaapi/gstvaapidecode.c: + decoder: h264: add support for NALU "alignment" optimization. + We can avoid scanning for start codes again if the bitstream is fed + in NALU chunks. Currently, we always scan for start codes, and keep + track of remaining bits in a GstAdapter, even if, in practice, we + are likely receiving one GstBuffer per NAL unit. i.e. h264parse with + "nal" alignment. + https://bugzilla.gnome.org/show_bug.cgi?id=723284 + [use gst_adapter_available_fast() to determine the top buffer size] + Signed-off-by: Gwenole Beauchesne + +2014-06-18 18:53:51 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix caps to report interlace-mode accordingly. + The `vaapipostproc' element could never determine if the H.264 stream + was interlaced, and thus always assumed it to be progressive. Fix the + H.264 decoder to report interlace-mode accordingly, thus allowing the + vaapipostproc element to automatically enable deinterlacing. + +2014-06-19 13:35:23 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: don't crash with dynamic framerate (0/1). + Avoid reaching an assert if dynamic framerates (0/1) are used. One + way to solve this problem is to just stick field_duration to zero. + However, this means that, in presence of interlaced streams, the + very first field will never be displayed if precise presentation + timestamps are honoured. + https://bugzilla.gnome.org/show_bug.cgi?id=729604 + +2014-02-07 12:27:50 +0000 Simon Farnsworth + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: create filter surface pool if it does not exist yet. + ensure_srcpad_buffer_pool() tries to avoid unnecessarily deleting and + recreating filter_pool. Unfortunately, this also meant it didn't create + it if it did not exist. + Fix it to always create the buffer pool if it does not exist. + https://bugzilla.gnome.org/show_bug.cgi?id=723834 + Signed-off-by: Simon Farnsworth + +2013-12-12 10:01:13 +0800 Zhao, Halley + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: reset deinterlacer state when there is a discontinuity. + Reset deinterlacer state, i.e. past reference frames used for advanced + deinterlacing, when there is some discontinuity detected in the course + of processing source buffers. + This fixes support for advanced deinterlacing when a seek occurred. + https://bugzilla.gnome.org/show_bug.cgi?id=720375 + [fixed type of pts_diff variable, fetch previous buffer PTS from the + history buffer, reduce heuristic for detecting discontinuity] + Signed-off-by: Gwenole Beauchesne + +2014-06-18 16:16:34 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: add support for crop regions in VPP mode. + Apply video cropping regions stored in GstVideoCropMeta, or in older + GstVaapiSurfaceProxy representation, to VPP pipelines. In non-VPP modes, + the crop meta are already propagated to the output buffers. + https://bugzilla.gnome.org/show_bug.cgi?id=720730 + +2014-03-14 17:49:40 +0000 Simon Farnsworth + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: make deinterlace-mode behave as expected. + deinterlace-mode didn't behave in the way you'd expect if you have + past experience of the deinterlace element. There were two bugs: + 1. "auto" mode wouldn't deinterlace "interleaved" buffers, only "mixed". + 2. "force" mode wouldn't deinterlace "mixed" buffers flagged as progressive. + Fix these up, and add assertions and error messages to detect cases that + aren't handled. + https://bugzilla.gnome.org/show_bug.cgi?id=726361 + Signed-off-by: Simon Farnsworth + Signed-off-by: Gwenole Beauchesne + +2014-01-15 16:36:29 +0000 Matthieu Bouron + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: do not discard video info props when the format changed. + gst_video_info_set_format() does not preserve video info properties. In + order to keep important information in the caps such as interlace mode, + framerate, pixel aspect ratio, ... we need to manually copy back those + properties after setting the new video format. + https://bugzilla.gnome.org/show_bug.cgi?id=722276 + +2014-02-23 01:43:39 +1100 Matthew Waters + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: plug a memory leak. + It can happen that there is a pool provided that does not advertise + the vappivideometa. We should unref that pool before using our own. + Discovered with vaapidecode ! {glimagesink,cluttersink} + https://bugzilla.gnome.org/show_bug.cgi?id=724957 + [fixed compilation by adding the missing semi-colon] + Signed-off-by: Gwenole Beauchesne + +2014-06-18 13:47:36 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: parse source data until a frame is obtained. + Parse any pending data until a complete frame is obtained. This is a + memory optimization to avoid expansion of video packets stuffed into + the GstAdapter, and a fix to EOS condition to detect there is actually + pending data that needs to be decoded, and subsequently output. + https://bugzilla.gnome.org/show_bug.cgi?id=731831 + +2014-06-05 15:32:29 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix multiple slices support in packed headers mode. + Handle packedi slice headers and packed raw data on a per-slice basis, + which is necessary for multi slice encoding. + +2014-06-05 15:30:38 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + encoder: add infrastructure for per-slice handling of packed headers. + The packed slice header and packed raw data need to be paired with + the submission of VAEncSliceHeaderParameterBuffer. So handle them + on a per-slice basis insted of a per-picture basis. + [removed useless initializer] + Signed-off-by: Gwenole Beauchesne + +2014-03-07 17:40:34 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix initialization with "drm" display type. + Force early initializatin of the GstVaapiDisplay so that to make sure + that the sink element display object is presented first to upstream + elements, as it will be correctly featuring the requested display type + by the user. + Otherwise, we might end up in situations where a VA/X11 display is + initialized in vaapidecode, then we try VA/DRM display in vaapisink + (as requested by the "display" property), but this would cause a failure + because we cannot acquire a DRM display that was previously acquired + through another backend (e.g. VA/X11). + +2014-03-07 17:38:14 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginbase.c: + plugins: fix initialization with foreign context. + When a new display is settled through GstElement::set_context() (>= 1.2), + or GstVideoContext::set_context() (<= 1.0), then we shall also update the + associated display type. + +2014-04-28 17:44:03 +0200 Gwenole Beauchesne + + * Makefile.am: + * configure.ac: + * ext/Makefile.am: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapiparse.c: + * gst/vaapi/gstvaapiparse.h: + * patches/Makefile.am: + * patches/videoparsers/0001-plugins-compile-the-built-in-video-parsers-as-vaapip.patch: + * patches/videoparsers/0002-h264parse-fix-build-with-GStreamer-1.2.patch: + * patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch: + * patches/videoparsers/Makefile.am: + * patches/videoparsers/series.frag: + plugins: add built-in video parsers as "vaapiparse" element. + The built-in video parsers elements are built into a single DSO named + libgstvaapi_parse.so. The various video parsers could be accessed as + vaapiparse_CODEC. + For now, this only includes a modified version of h264parse so that to + support H.264 MVC encoded streams. + +2014-06-13 11:36:56 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: cope with new gst_h264_quant_matrix_*() interfaces. + New gst_h264_quant_matrix_*_get_raster_from_zigzag() were renamed + from gst_h264_video_quant_matrix_*_get_raster_from_zigzag(). + +2014-06-13 11:34:07 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit d6325ac. + 7d8d045 h264parse: use new gst_h264_video_calculate_framerate() + d2f965a h264parse: set field_pic_flag when parsing a slice header + 24c15b8 Import h264parse + a9283e5 bytereader: Use concistant derefence method + a8252c6 bytereader: Use pointer instead of index access + b1bebfc Import GstBitReader and GstByteReader + 2f58788 h264: recognize SVC NAL units + 4335da5 h264: fix SPS copy code for MVC + cf9b6dc h264: fix quantization matrix conversion routine names + b11ce2a h264: add gst_h264_video_calculate_framerate() + 126dc6f add C++ guards for MPEG-4 and VP8 parsers + +2014-06-10 18:30:21 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: factor out DPB pruning for MVC. + Factor out the removal process of unused inter-view only reference + pictures from the DPB, prior to the possible insertion of the current + picture. + Ideally, the compiler could still opt for generating two loops. But + at least, the code is now clearer for maintenance. + +2014-06-10 17:42:58 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: clean-ups. + Fix GST_VAAPI_PICTURE_IS_{INTER_VIEW,ANCHOR}() definitions to use + the base GST_VAAPI_PICTURE_FLAG_IS_SET() macro. + +2014-06-10 16:07:51 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: improve pruning of unused MVC inter-view frames. + Improve process for the removal of pictures from DPB before possible + insertion of the current picture (C.4.4) for H.264 MVC inter-view only + reference components. In particular, handle cases where picture to be + inserted is not the last one of the access unit and if it was already + output and is no longer marked as used for reference, including for + decoding next view components within the same access unit. + +2014-06-03 17:36:38 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: improve DPB bumping process for MVC. + While invoking the DPB bumping process in presence of many views, + it could be necessary to output previous pictures that are ready, + in a whole. i.e. emitting all view components from the very first + view order index zero to the very last one in its original access + unit; and not starting from the view order index of the picture + that caused the DPB bumping process to be invoked. + As a reminder, the maximum number of frames in DPB for MultiView + High profile with more than 2 views is not necessarily a multiple + of the number of views. + This fixes decoding of MVCNV-4.264. + +2014-06-06 17:56:06 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix inter-view references array growth. + Let the utility layer handle dynamic growth of the inter-view pictures + array. By definition, setting a new size to the array will effectively + grow the array, but would also fill in the newly created elements with + empty entries (NULL), thus also increasing the reported length, which + is not correct. + +2014-06-03 17:36:38 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: reduce ReferenceFrames entries to the essential set. + When decoding Multiview High profile streams with a large number of + views, it is not possible to make the VAPictureParameterBufferH264. + ReferenceFrames[] array hold the complete DPB, with all possibly + active pictures to be used for inter-view prediction in the current + access unit. + So reduce the scope of the ReferenceFrames[] array to only include + the set of reference pictures that are going to be used for decoding + the current picture. Basically, this is a union of all RefPicListX[] + array, for all slices constituting the decoded picture. + +2014-06-04 19:10:44 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix MVC inter-view prediction process. + The inter-view reference components and inter-view only reference + components that are included in the reference picture lists shall + be considered as not being marked as "used for short-term reference" + or "used for long-term reference". This means that reference flags + should all be removed from VAPictureH264.flags. + This fixes decoding of MVCNV-2.264. + +2014-06-04 19:03:18 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix detection of profile changes for MVC. + If the VA driver exposes ad-hoc H.264 MVC profiles, then we have to + be careful to detect profiles changes and not reset the underlying + VA context erroneously. In MVC situations, we could indeed get a + profile_idc change for every SPS that gets activated, alternatively + (base-view -> non-base view -> base-view, etc.). + An improved fix would be to characterize the exact profile to use + once and for all when SPS NAL units are parsed. This would also + allow for fallbacks to a base-view decoding only mode. + +2014-06-03 14:30:39 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: drop extraneous definitions. + Re-use definitions from the codecparser headers instead of duplicating + them here again. That covers NALU definitions and slice types. + +2014-04-01 11:26:04 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: remove unnecessary calcualtion of max_pic_order_cnt. + https://bugzilla.gnome.org/show_bug.cgi?id=727418 + +2014-04-01 14:23:56 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: don't allow CABAC with Extended profile. + The H.264 specification does not support CABAC entropy coding for the + Extended profile. + https://bugzilla.gnome.org/show_bug.cgi?id=727418 + +2014-05-07 00:12:39 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: use packed headers mode for MVC encoding. + Exclusively use VA drivers that support raw packed headers for encoding. + i.e. simply submit packed headers Subset SPS and Prefix NAL units. This + provides for better compatibility accross the various VA drivers and HW + generations since no particular API is needed beyond what readily exists. + +2014-05-07 00:09:45 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: add support for packed slice headers. + https://bugzilla.gnome.org/show_bug.cgi?id=722905 + +2014-05-07 00:09:19 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: store subset sps to generate the codec-data + Store the SubsetSPS nal unit which we need for MVC specific + codec_data generation. + +2014-05-07 00:08:33 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix MVC pipeline hang while encoding with B-frames. + Since we are encoding each view independently from each other, we + need a higher number of pre-allocated surfaces to be used as the + reconstructed frames. For Stereo High profile encoding, this means + to effectively double the number of frames to be stored in the DPB. + +2014-02-17 15:51:43 +0800 Li Xiaowei + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst/vaapi/gstvaapiencode_h264.c: + encoder: h264: add initial support for H.264 Stereo High profile. + Add initial support for Subset SPS, Prefix NAL and Slice Extension NAL + for non-base-view streams encoding, and the usual SPS, PPS and Slice + NALs for base-view encoding. + The H.264 Stereo High profile encoding mode will be turned on when the + "num-views" parameter is set to 2. The source (raw) YUV frames will be + considered as Left/Right view, alternatively. + Each of the two views has its own frames reordering pool and reference + frames list management system. Inter-view references are not supported + yet, so the views are encoded independently from each other. + Signed-off-by: Li Xiaowei + [limited to Stereo High profile per the definition of MAX_NUM_VIEWS] + Signed-off-by: Gwenole Beauchesne + +2014-02-17 11:10:26 +0800 Li Xiaowei + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: wrap pools for refs and frames reordering. + Create structures to maintain the reference frames list (RefPool) and + frames reordering (ReorderPool) logic. + This is a prerequisite for H.264 MVC support. + Signed-off-by: Li Xiaowei + +2014-02-14 15:33:15 +0800 Li Xiaowei + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: add provisional support for subset SPS headers. + Add provisions to write subset SPS headers to the bitstream in view + to supporting the H.264 MVC specification. + This assumes the libva "staging" branch is in use. + Signed-off-by: Li Xiaowei + +2013-12-18 13:47:32 +0800 Li Xiaowei + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + utils: add H.264 MVC profiles. + Add "MultiView High" and "Stereo High" definitions. + Signed-off-by: Li Xiaowei + [require VA-API >= 0.35.2 for MVC profiles] + Signed-off-by: Gwenole Beauchesne + +2014-06-02 16:25:03 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + utils: only enable VP8 profiles for newer VA-API versions. + VP8 decoding API appeared in VA-API >= 0.35.0. So, disable mappings + involving VP8 codec on earlier versions of the API. + +2014-05-22 10:04:46 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: compute view ids only once per slice. + Optimize lookups of view ids / view order indices by caching the result + of the calculatiosn right into the GstVaapiParserInfoH264 struct. This + terribly simplifies is_new_access_unit() and find_first_field() functions. + +2014-05-21 17:57:00 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: add support for MVC interlaced streams. + Fix support for MVC Stereo High profile streams with interlaced frames. + Also improve the detection logic of the first field. + +2014-05-20 18:08:15 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: add MVC profiles compatibility logic. + Add safe fallbacks for MVC profiles: + - all MultiView High profile streams with 2 views at most can be decoded + with a Stereo High profile compliant decoder ; + - all Stereo High profile streams with only progressive views can be + decoded with a MultiView High profile compliant decoder ; + - all drivers that support slice-level decoding could normally support + MVC profiles when the DPB holds at most 16 frames. + +2014-05-02 14:58:45 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + decoder: h264: add initial support for MVC. + https://bugzilla.gnome.org/show_bug.cgi?id=721772 + +2014-05-01 19:16:09 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: dynamically allocate the DPB. + Dynamically allocate the Decoded Picture Buffer (DPB) and add provisions + for supporting the MVC allocation requirements. + +2014-05-01 19:33:40 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix detection of access unit boundaries. + In order to have a stricter conforming implementation, we need to carefully + detect access unit boundaries. Additional operations could be necessary to + perform at those boundaries. + +2013-03-13 11:44:38 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: detect the first VCL NAL unit of a picture for MVC. + Detect the first VCL NAL unit of a picture for MVC, based on the + view_id as per H.7.4.1.2.4. Note that we only need to detect new + view components. + Signed-off-by: Gwenole Beauchesne + +2013-10-31 19:32:55 +0800 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: properly handle Prefix NAL units. + Always cache the previous NAL unit so that we could check whether + there is a Prefix NAL unit immediately preceding the current slice + or IDR NAL unit. In that case, the NAL unit metadata is copied into + the current NAL unit. Otherwise, some default values are inferred, + tentatively. e.g. view_id shall be set to 0 and inter_view_flag to 1. + [infer default values for slice if previous NAL was not a Prefix] + Signed-off-by: Gwenole Beauchesne + +2013-02-28 15:59:55 +0800 Xiaowei Li + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: add support for MVC base views. + Allow decoding for base views of MVC encoded streams. For now, just skip + the slice extension and prefix NAL units, and skip non-base view frames. + Signed-off-by: Xiaowei Li + [fixed memory leak, improved check for MVC NAL units] + Signed-off-by: Gwenole Beauchesne + +2014-05-04 14:49:28 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: simplify storage of decoded picture into DPB. + Factor out process by which the decoded picture with the lowest POC + is found, and possibly output. Likewise, the storage and marking of + a reference decoded, or non-reference decoded picture, into the DPB + could also be simplified as they mostly share the same operations. + +2014-05-02 22:40:16 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: minor clean-ups. + Make init_picture_ref_lists() more consistent with other functions + related to the reference marking process by supplying the current + picture as argument. + +2014-05-20 11:36:40 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + display: add utility function to query VA driver name. + Add gst_vaapi_display_get_vendor_string() helper function to query + the underlying VA driver name. The display object owns the resulting + string, so it shall not be deallocated. + That function is thread-safe. It could be used for debugging purposes, + for instance. + +2014-03-07 14:50:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.h: + display: make cache maintenance really MT-safe. + Make sure to initialize one GstVaapiDisplay at a time, even in threaded + environments. This makes sure the display cache is also consistent + during the whole display creation process. In the former implementation, + there were risks that display cache got updated in another thread. + +2014-05-03 15:56:51 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + context: allow dynamic growth of VA surfaces pool. + Add support for dynamic growth of the VA surfaces pool. For decoding, + this implies the recreation of the underlying VA context, as per the + requirement from VA-API. Besides, only increases are supported, not + shrinks. + +2014-05-03 15:47:53 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + context: reset VA context if VA surfaces set changed. + It is a requirement from VA-API specification that the VA context got + from vaCreateContext(), for decoding purposes, binds the supplied set + of VA surfaces. This means that if the set of VA surfaces is to be + changed for the current decode session, then the VA context needs to + be recreated with the new set of VA surfaces. + +2014-05-12 19:23:04 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix assignment of LongTermFrameIdx. + Complement fix committed as e95a42e. + The H.264 AVC standard has to say: if the field is part of a reference + frame or a complementary reference field pair, and the other field of + the same reference frame or complementary reference field pair is also + marked as "used for long-term reference", the reference frame or + complementary reference field pair is also marked as "used for long-term + reference" and assigned LongTermFrameIdx equal to long_term_frame_idx. + This fixes decoding of MR9_BT_B in strict mode. + https://bugs.freedesktop.org/show_bug.cgi?id=64624 + https://bugzilla.gnome.org/show_bug.cgi?id=724518 + +2014-05-10 06:23:29 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + decoder: h264: properly support grayscale formats. + Request the correct chroma format for decoding grayscale streams. + i.e. make lookups of the VA chroma format more generic, thus possibly + supporting more formats in the future. + This means that, if a VA driver doesn't support grayscale formats, + it is now going to fail. We cannot safely assume that maybe grayscale + was implemented on top of some YUV 4:2:0 with the chroma components + all set to 0x80. + +2014-02-06 11:14:09 +0000 Simon Farnsworth + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * tests/test-filter.c: + build: fix source file modes. + A few source files are marked executable in error - fix them + https://bugzilla.gnome.org/show_bug.cgi?id=723748 + Signed-off-by: Simon Farnsworth + +2014-04-29 13:22:47 +0300 Sreerenj Balachandran + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + * gst/vaapi/gstvaapidecode.c: + build: fix conditional compilation of VP8 decoder. + https://bugzilla.gnome.org/show_bug.cgi?id=729170 + [added check for VASliceParameterBufferBase fields] + Signed-off-by: Gwenole Beauchesne + +2014-04-27 08:55:24 +0200 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/Makefile.am: + build: fix make dist for codecparsers. + +2014-04-28 09:42:13 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit eaa3f7e. + h264: fix parsing of slice groups for map type = 2 + +2014-04-26 22:35:49 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi branch commit f44edfc. + h264: fix derivation of default scaling lists + +2013-05-24 19:00:54 +0800 Cong Zhong + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix long-term reference picture marking process. + Fix reference picture marking process with memory_management_control_op + set to 3 and 6, i.e. assign LongTermFrameIdx to a short-term reference + picture, or the current picture. + This fixes decoding of FRExt_MMCO4_Sony_B. + https://bugs.freedesktop.org/show_bug.cgi?id=64624 + https://bugzilla.gnome.org/show_bug.cgi?id=724518 + [squashed, edited to use GST_VAAPI_PICTURE_IS_COMPLETE() macro] + Signed-off-by: Gwenole Beauchesne + +2014-04-26 20:21:46 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix initialization of RefPicLists for multiple slices. + The initialization of reference picture lists (8.2.4.2) applies to all + slices. So, the RefPicList0/1 lists need to be constructed prior to + each slice submission to the HW decoder. + This fixes decoding of video sequences where frames are encoded with + multiple slices of different types, e.g. 4 slices in this order I, P, + I, and P. More precisely, CABAST3_Sony_E and CABASTBR3_Sony_B. + https://bugzilla.gnome.org/show_bug.cgi?id=724518 + +2013-06-04 15:01:46 +0800 Zhong Cong + + * ext/codecparsers: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: skip SPS extension and auxiliary slice NALs. + When NAL units of type 13 (SPS extension) or type 19 (auxiliary slice) + are present in a video, decoders shall perform the (optional) decoding + process specified for these NAL units or shall ignore them (7.4.1). + Implement option 2 (skip) for now, as alpha composition is not + supported yet during the decoding process. + This fixes decoding of the primary coded video in alphaconformanceG. + https://bugzilla.gnome.org/show_bug.cgi?id=703928 + https://bugzilla.gnome.org/show_bug.cgi?id=728869 + https://bugzilla.gnome.org/show_bug.cgi?id=724518 + [skip NAL units earlier, i.e. at parsing time] + Signed-off-by: Gwenole Beauchesne + +2013-03-07 11:32:20 +0800 Li Xiaowei + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix slice data bit offset with MVC NAL units. + When MVC slice NAL units (coded slice extension and prefix NAL) are + present, the number of NAL header bytes is 3, not 1 as usual. + Signed-off-by: Li Xiaowei + Signed-off-by: Gwenole Beauchesne + +2014-04-25 19:11:03 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix activation of picture and sequence parameters. + At the time the first VCL NAL unit of a primary coded picture is found, + and if that NAL unit was parsed to be an SPS or PPS, then the entries + in the parser may have been overriden. This means that, when the picture + is to be decoded, slice_hdr->pps could point to an invalid (the next) + PPS entry. + So, one way to solve this problem is to not use the parser PPS and + SPS info but rather maintain our own activation chain in the decoder. + https://bugzilla.gnome.org/show_bug.cgi?id=724519 + https://bugzilla.gnome.org/show_bug.cgi?id=724518 + +2014-04-25 16:24:01 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: retain SEI messages until the end of frame. + Retain the SEI messages that were parsed from the access unit until we + have completely decoded the current frame. This is done so that we can + peek at that data whenever necessary during decoding. e.g. for exposing + 3D stereoscopic information at a later stage. + +2014-04-25 14:23:11 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: add support for grayscale encoded clips. + Fix support for grayscale encoded video clips, and possibly others if + the underlying driver supports the non-YUV 4:2:0 formats. i.e. defer + the decision that a surface with the desired chroma format is not + supported to the actual VA driver implementation. + https://bugzilla.gnome.org/show_bug.cgi?id=728144 + +2014-04-25 14:16:24 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + decoder: default to YUV 4:2:0 VA surfaces. + Cope with context changes to support non-YUV 4:2:0 VA surfaces. Still, + make sure all codecs use YUV 4:2:0 output format for now, by default. + +2014-04-25 13:57:02 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: re-indent GstVaapiDecoder base object. + +2014-04-25 13:47:53 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + encoder: derive chroma type from video format. + Cope with previous VA context change to derive the correct surface chroma + type from the input video format. + +2014-04-25 13:45:31 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + context: add support for non-YUV 4:2:0 formats. + Don't force allocation of VA surfaces in YUV 4:2:0 format. Rather, allow + for the upper layer to specify the desired chroma type. If the chroma + type field is not set (or yields zero), then YUV 4:2:0 format is used + by default. + +2014-04-22 19:53:50 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + vp8: fix per-segment deblocking filter level in relative mode. + Fix possible bug when a per-segment deblocking filter level value + needs to be set in non-absolute mode, i.e. when the loop filter update + value is negative in delta mode. + Also clamp the resulting filter level value to 0..63 range. + +2014-04-22 17:25:15 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + vp8: fix check for disabling the loop filter (again). + Improve condition to disable the loop filter. The previous heuristic + used to check all filter levels, for all segments. It turns out that + only the base filter_level value defined in the frame header needs + to be checked. + This fixes 00-comprehensive-013. + +2014-04-21 18:02:21 +0200 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/Makefile.am: + * gst/vaapi/Makefile.am: + build: fix make dist with certain conditionals not met. + Fix generation of source tarballs when certain conditionals are not + met. e.g. always include all buildable codecparsers sources in the + distribution tarball, fix plug-in element sources set to include X11 + and encoder bits. + +2014-04-21 17:34:59 +0200 Gwenole Beauchesne + + * ext/Makefile.am: + build: add missing files for GStreamer 0.10. + Add missing GstVideoEncoder implementation files to fix build with ancient + GStreamer 0.10 stack. + https://bugzilla.gnome.org/show_bug.cgi?id=723964 + +2014-04-19 10:17:20 +0200 Gwenole Beauchesne + + * ext/Makefile.am: + build: add missing files for VP8 bitstream parser. + Fix make dist for building the VP8 bitstream parser. + +2014-04-21 17:49:38 +0200 Gwenole Beauchesne + + * configure.ac: + * ext/libvpx/Makefile.am: + * gst-libs/gst/codecparsers/Makefile.am: + vp8: allow compilation without the built-in libvpx. + The built-in libvpx serves multiple purposes, among which the most + important ones could be: track the most up-to-date, and optimized, + range decoder; allow for future hybrid implementations (non-VLD); + and have a completely independent range decoder implementation. + +2014-04-21 17:28:27 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + vp8: propagate PTS from demux frame. + gst_adapter_prev_pts() is forbidden within libgstvaapi. Besides, the demuxer + or parser would already have determined the PTS from a previous stage. + +2014-04-19 07:49:30 +0200 Gwenole Beauchesne + + * Makefile.am: + * debian.upstream/libgstvaapi.install.in: + * ext/libvpx/Makefile.am: + * ext/libvpx/sources.frag: + * gst-libs/gst/codecparsers/Makefile.am: + vp8: fix compilation with built-in libvpx. + Apply correct patch from fd.o #722760 to fix several issues: update the + license terms to LGPLv2.1+, fix dependencies to built-in libvpx and fix + make dist. + +2014-02-13 21:17:23 +0100 Gwenole Beauchesne + + * .gitmodules: + * autogen.sh: + * configure.ac: + * ext/Makefile.am: + * ext/libvpx/Makefile.am: + * ext/libvpx/gstlibvpx.c: + * ext/libvpx/gstlibvpx.h: + * ext/libvpx/libgstcodecparsers_vpx.vers: + * ext/libvpx/sources.frag: + * ext/libvpx/upstream: + * gst-libs/gst/codecparsers/Makefile.am: + * gst-libs/gst/codecparsers/gstvaapilibvpx.c: + vp8: use range decoder from libvpx. + Add libvpx submodule that tracks the upstream version 1.3.0. This is + needed to build a libgstcodecparsers_vpx.so library with all symbols + placed into the GSTREAMER namespace. + +2014-04-04 19:17:17 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + vp8: fix check for disabling the loop filter. + +2013-12-27 07:18:24 +0800 Zhao, Halley + + * configure.ac: + * ext/Makefile.am: + * gst-libs/gst/codecparsers/Makefile.am: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.h: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst/vaapi/gstvaapidecode.c: + Add initial VP8 decoder. + https://bugzilla.gnome.org/show_bug.cgi?id=722761 + [complete overhaul, fixed support for resolution changes] + Signed-off-by: Gwenole Beauchesne + +2014-03-21 15:15:37 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: cope with new gst_h264_parser_parse_sei() interface. + The gst_h264_parse_parse_sei() function now returns an array of SEI + messages, instead of a single SEI message. Reason: it is allowed to + have several SEI messages packed into a single SEI NAL unit, instead + of multiple NAL units. + +2014-04-18 19:36:16 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit a454f86. + b2eb5f6 vp8: rename dboolhuff symbols + b74a881 vp8: add GStreamer native utilities + 2940ac6 add VP8 bitstream parser + +2014-04-18 19:16:56 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit d459bc5. + d459bc5 h264: set framerate even for interlaced videos + c78b82c h264: add support for Recovery Point SEI message + 7693bac h264: add support for Frame Packing Arrangement SEI message + 31fafa7 h264: add support for Stereo Video Information SEI message + 8b113a6 h264: parse seq_parameter_set_mvc_extension() + 040f9b8 h264: parse MVC syntax elements + cc18ef3 h264: add nal_reader_skip_long() helper + 7e76a48 h264: fix slice_header() parsing for MVC + caf46d8 h264: add gst_h264_parse_nalu_header() helper + f75074e h264: add gst_h264_parse_sps_data() helper + 798c397 h264: clean-up gst_h264_parser_parse_sei_message() + 4e36737 h264: fix skipping of unsupported SEI messages + 5300766 h264: fix SEI buffering_period() parsing + +2014-03-21 15:09:14 +0100 Gwenole Beauchesne + + * ext/codecparsers: + * gst-libs/gst/codecparsers/Makefile.am: + codecparsers: update to gst-vaapi-branch commit 8fadf40. + 8fadf40 h264: Fix multiple SEI messages in one SEI RBSP parsing. + 644825f h265: remove trailling 0x00 bytes as the spec doesn't allow them + 95f9f0f h264: remove trailling 0x00 bytes as the spec doesn't allow them + 766007b h265: Initialize pointer correctly that is never assigned but freed in error cases + 8ec5816 h265: Fix segfault when parsing HRD parameter + 5b1730f h265: Fix segfault when parsing VPS + 983b7f7 h265: prevent to overrun chroma_weight_l0_flag + 7ba641d h265: Fix debug output + d9f9f9b h264: not all startcodes should have 3-byte 0 prefix + +2014-02-04 18:35:28 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix robustness patch for bytestream format. + Fix parser and decoder state to sync at the right locations. This is + because we could reset the parser state, while the decoder state was + not copied yet, e.g. when parsing several NAL units from multiple frames + whereas the current frame was not decoded yet. + This is a regression brought in by commit 6fe5496. + +2014-02-18 06:56:51 +0100 Gwenole Beauchesne + + * configure.ac: + * pkgconfig/Makefile.am: + * pkgconfig/gstreamer-vaapi-drm.pc.in: + * pkgconfig/gstreamer-vaapi-glx.pc.in: + * pkgconfig/gstreamer-vaapi-wayland.pc.in: + * pkgconfig/gstreamer-vaapi-x11.pc.in: + build: fix pkgconfig file names (again). + It turns out it is more convenient to have only pkgconfig files named + after the installed GStreamer API version (1.0) instead of using all + possible subsequent names from that (1.0, 1.2, 1.4). i.e. they conflict + altogether anyway, so align pkgconfig file names to that. + +2014-02-07 09:43:51 +0100 Gwenole Beauchesne + + * debian.upstream/libgstvaapi-dev.install.in: + * gst-libs/gst/vaapi/Makefile.am: + * pkgconfig/gstreamer-vaapi.pc.in: + build: fix packaging for GStreamer 1.2. + Fix gstreamer-vaapi includedir for GStreamer 1.2 setups. i.e. use + the pkgconfig version (1.0) instead of the intended API version (1.2). + libgstvaapi1.0-dev and libgstvaapi1.2-dev packages will now conflict, + as would core GStreamer 1.0 and GStreamer 1.2 dev packages anyway. + +2014-01-24 11:27:30 +0100 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2014-01-24 10:55:39 +0100 Gwenole Beauchesne + + * debian.upstream/control.in: + debian: fix trailing whitespace in description. + +2014-01-23 23:24:55 +0100 Gwenole Beauchesne + + * debian.upstream/control.in: + * debian.upstream/copyright: + debian: fix package description. + Try to improve package description for the compiled plug-in elements + available in there. e.g. only display vaapidownload and vaapiupload + for GStreamer 0.10 builds, display vaapiencode_* elements when VA + encoding is enabled, etc. + Also increase the copyright notice date. + +2014-01-23 22:47:19 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + build: fix warnings on 64-bit platforms. + +2014-01-23 22:44:09 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + build: fix for older versions of VA-API (< 0.34.0). + Fix build with older versions of VA-API (< 0.34.0), or versions without + good enough headers for encoding support for instance. + +2014-01-23 19:36:14 +0100 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.5.8. + +2014-01-23 19:32:28 +0100 Gwenole Beauchesne + + * README: + README: updates. + VA-API up to 0.34.0 is actually supported. Mention new video encoding + support. Update copyright years, list of supported Intel HD Graphics + hardware. + +2014-01-23 19:18:13 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2014-01-20 14:16:56 +0100 Gwenole Beauchesne + + * tests/test-filter.c: + tests: test-filter: fix "deinterlace" option parse. + Default to GST_VAAPI_DEINTERLACE_METHOD_NONE if no "deinterlace" option + string was provided, i.e. if it remained set to NULL. + +2014-01-23 18:41:24 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiutils_core.c: + * gst-libs/gst/vaapi/gstvaapiutils_core.h: + libs: factor out usages of vaGetConfigAttributes(). + Add gst_vaapi_get_config_attribute() helper function that takes a + GstVaapiDisplay and the rest of the arguments with VA types. The aim + is to have thread-safe VA helpers by default. + +2014-01-23 17:41:02 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + libs: re-indent all source code related to VA utilities. + +2014-01-23 17:06:08 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/libgstvaapi_priv_check.h: + libs: add missing file (libgstvaapi_priv_check.h). + +2014-01-23 15:13:06 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + encoder: notify the encoder of the submitted packed headers. + Make sure to configure the encoder with the set of packed headers we + intend to generate and submit. i.e. make selection of packed headers + to submit more robust. + +2014-01-23 15:10:11 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + encoder: fix and factor out check for supported rate-control modes. + Cache the first compatible GstVaapiProfile found if the encoder is not + configured yet. Next, factor out the code to check for the supported + rate-control modes by moving out vaGetConfigAttributes() to a separate + function, while also making sure that the attribute type is actually + supported by the encoder. + Also fix the default set of supported rate control modes to not the + "none" variant. It's totally useless to expose it at this point. + +2014-01-23 14:01:33 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + context: move rate-control mode to encoder specific config. + Move usage-specific config out of the common GstVaapiContextInfo. + Create a specialized config for encoding and move rate-control mode + to there. + +2014-01-23 13:30:41 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + context: introduce concept of usage. + Introduce GstVaapiContextUsage so that to explicitly determine the + usage of a VA context. This is useful in view to simplifying the + creation of VA context for VPP too. + +2014-01-23 11:44:12 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + context: fix get_attribute() value result. + Unknown attributes, or attributes that are not supported for the given + profile/entrypoint pair have a return value of VA_ATTRIB_NOT_SUPPORTED. + So, return failure in this case. + +2014-01-23 10:59:20 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapicontext_overlay.c: + * gst-libs/gst/vaapi/gstvaapicontext_overlay.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + context: move overlay composition to separate files. + Move GstVideoOverlayComposition handling to separate source files. + This helps keeing GstVaapiContext core implementation to the bare + minimal, i.e. simpy helpers to create a VA context and handle pool + of associated VA surfaces. + +2014-01-23 09:41:07 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + context: clean-ups. Strip down APIs. + Improve documentation and debug messages. Clean-up APIs, i.e. strip + them down to the minimal set of interfaces. They are private, so no + need expose getters for instance. + +2014-01-23 09:27:38 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + context: re-indent all GstVaapiContext related source code. + +2014-01-23 10:20:40 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplaycache.h: + * gst-libs/gst/vaapi/gstvaapiminiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapipixmap_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + libs: check that private headers remain private. + Make sure that libgstvaapi private headers remain internally used to + build libgstvaapi libraries only. All header dependencies were reviewed + and checks for IN_LIBGSTVAAPI definition were added accordingly. + Also rename GST_VAAPI_CORE definition to IN_LIBGSTVAAPI_CORE to keep + consistency. + +2014-01-22 19:04:58 +0100 Gwenole Beauchesne + + * configure.ac: + Bump library major version. + Bump the library major version due to API/ABI changes that occurred in + the imaging API. In particular, GstVaapiDisplay interfaces no longer + expose any GstCaps but provide GArray based ones e.g. to determine the + set of supported decode/encode profiles. + +2014-01-22 18:54:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/glibcompat.h: + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapicodedbufferpool.c: + * gst-libs/gst/vaapi/gstvaapicodedbufferpool.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapipixmap_x11.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264.h: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_mpeg2.h: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + * gst/vaapi/gstvaapivideometa_texture.c: + * tests/simple-decoder.c: + legal: update copyright notice dates. + +2014-01-22 18:49:20 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264.h: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_mpeg2.h: + legal: add per-file authorship information. + +2014-01-22 18:11:26 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: fix video codec frame number in standalone mode. + Set a valid GstVideoCodecFrame.system_frame_number when decoding a + stream in standalone mode. While we are at it, improve the debugging + messages to also include that frame number. + +2014-01-17 16:56:53 +0800 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + decoder: fix crash on invalid pointer for GST_DEBUG(). + When decoding failed, or that the frame was dropped, the associated + surface proxy is not guaranteed to be present. Thus, the GST_DEBUG() + message needs to check whether the proxy is actually present or not. + https://bugzilla.gnome.org/show_bug.cgi?id=722403 + [fixed gst_vaapi_surface_proxy_get_surface_id() to return VA_INVALID_ID] + Signed-off-by: Gwenole Beauchesne + +2014-01-22 17:07:24 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: disable NAL HRD parameters for now. + Don't emit NAL HRD parameters for now in the SPS headers because the + SEI buffering_period() and picture_timing() messages are not handled + yet. Some additional changes are necessary to get it right. + https://bugzilla.gnome.org/show_bug.cgi?id=722734 + +2014-01-21 19:04:41 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h: + encoder: h264: fix default CPB buffer size. + Fix default CPB buffer size to something more reasonable (1500 ms) + and that still fits the level limits. This is a non configurable + property for now. The initial CPB removal delay is also fixed to + 750 ms. + https://bugzilla.gnome.org/show_bug.cgi?id=722087 + +2014-01-22 14:43:24 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix bitrate encoding for HRD conformance. + Round down the calculated, or supplied, bitrate (kbps) into a multiple + of the HRD bitrate scale factor. Use a bitrate scale factor of 64 so + that to have less losses in precision. Likewise, don't round up because + that could be a strict constraint imposed by the user. + +2014-01-22 11:25:13 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix level lookup constraints wrt. bitrate. + Fix the level calculation involving bitrate limits. Since we are + targetting NAL HRD conformance, the check against MaxBR from the + Table A-1 limits shall involve cpbBrNalFactor depending on the + active profile. + +2014-01-21 18:01:20 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: submit sequence parameter only once. + Submit sequence parameter buffers only once, or when the bitstream + was reconfigured in a way that requires such. Always submit packed + sequence parameter buffers at I-frame period, if the VA driver needs + those. + https://bugzilla.gnome.org/show_bug.cgi?id=722737 + +2014-01-21 18:35:17 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + encoder: h264: only submit packed headers when required. + Make sure to submit the packed headers only if the underlying VA driver + requires those. Currently, only handle packed sequence and picture + headers. + https://bugzilla.gnome.org/show_bug.cgi?id=722737 + +2014-01-21 17:35:24 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix ip_period value in sequence parameter. + The VAEncSequenceParameterBuffer.ip_period value reprents the distance + between the I-frame and the next P-frame. So, this also accounts for + any additional B-frame in the middle of it. + This fixes rate control heuristics for certain VA drivers. + https://bugzilla.gnome.org/show_bug.cgi?id=722735 + +2014-01-21 17:04:40 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix level when bitrate is automatically computed. + Fix level characterisation when the bitrate is automatically computed + from the active coding tools. i.e. ensure the bitrate once the profile + is completely characterized but before the level calculation process. + +2014-01-21 16:05:22 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: clean-ups. + Document and rename a few functions here and there. Drop code that + caps num_bframes variable in reset_properties() since they shall + have been checked beforehand, during properties initialization. + +2014-01-21 15:28:34 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: clean-up bitwriter related utilities. + Clean-up GstBitWriter related utility functions and simplify notations. + While we are at it, also make bitstream writing more robust should an + overflow occur. We could later optimize for writing headers capped to + their maximum possible size by using the _unchecked() helper variants. + +2014-01-21 15:23:01 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + encoder: h264: completely remove private headers. + Drop private header since it was originally used to expose internals + to the plugin element. The proper interface is now the properties API, + thus rendering private headers totally obsolete. + +2014-01-15 15:54:32 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix PPS header packing with profile < high. + Fix PPS header packing when profile is below High since 8x8 transform + mode and scaling lists are High Profile features. + +2014-01-15 15:46:19 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: always emit VUI parameters for framerate. + Always emit VUI parameters for timing_info, which includes framerate + information. + +2014-01-15 15:10:48 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: really fix frame cropping rectangle calculation. + Make frame cropping rectangle calculation future proof, i.e. exactly + follow the specification (7-18) to (7-21), and subsampling definitions + from Table 6-1. + https://bugzilla.gnome.org/show_bug.cgi?id=722089 + https://bugzilla.gnome.org/show_bug.cgi?id=722238 + +2014-01-15 12:09:14 +0100 Holger Kaelberer + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: set csc render flags from sinkpad caps. + This maps GstVideoColorimetry information in vaapisink's sinkpad caps + to GST_VAAPI_COLOR_STANDARD_* flags, if per-buffer information was not + available. + https://bugzilla.gnome.org/show_bug.cgi?id=722255 + [factored out code, added SMPTE240M, handle per-buffer flags] + Signed-off-by: Gwenole Beauchesne + +2012-03-28 15:05:26 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst/vaapi/gstvaapipostproc.c: + surface: rework render flags. + Pack render flags per category and provide more flags into the color + standard category. In particular, cover for SMPTE-240M. + +2013-12-13 04:14:41 +0800 Zhao, Halley + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: add support for colorbalance filters. + Add support for hue, saturation, brightness and constrat adjustments. + Also fix cap info local copy to match the really expected cap subtype + of interest. + https://bugzilla.gnome.org/show_bug.cgi?id=720376 + Signed-off-by: Gwenole Beauchesne + +2013-12-12 08:38:12 +0800 Zhao, Halley + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix support for "sharpen" filter. + Fix copy/paste error when submitting the "sharpen" value to the + GstVaapiFilter instance. + https://bugzilla.gnome.org/show_bug.cgi?id=720375 + Signed-off-by: Gwenole Beauchesne + +2013-12-20 12:05:42 +0000 Lionel Landwerlin + + * configure.ac: + * pkgconfig/gstreamer-vaapi-drm.pc.in: + * pkgconfig/gstreamer-vaapi-glx.pc.in: + * pkgconfig/gstreamer-vaapi-wayland.pc.in: + * pkgconfig/gstreamer-vaapi-x11.pc.in: + * pkgconfig/gstreamer-vaapi.pc.in: + pkgconfig: plugin dir should use PKG version not API version. + Fix the pluginsdir and includedir variables in the generated pkgconfig + (.pc) files. The location needs to be built with the PKG version in + mind instead of the API version. + While we are at it, also fix the PKG version for GStreamer >= 1.3. + https://bugzilla.gnome.org/show_bug.cgi?id=720820 + [additional fixes for includedir and pkg requirements] + Signed-off-by: Gwenole Beauchesne + +2014-01-15 10:05:45 +0100 Holger Kaelberer + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix display initialization in GstVideoOverlay implementation. + When gst_vaapisink_video_overlay_set_window_handle() is called early, + before the pipeline has been set to PLAYING, the display has not yet + been initialized and _PLUGIN_BASE_DISPLAY_TYPE() is not yet + up-to-date. For this reason the foreign XID is not attached. + Now _ensure_display() is called earlier. + https://bugzilla.gnome.org/show_bug.cgi?id=722244 + Signed-off-by: Gwenole Beauchesne + +2013-10-09 13:47:54 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapisink.c: + vaapisink: expose the raw video formats in static caps template. + Expose all raw video formats in the static caps template since the + vaapisink is supporting raw data. We will get the exact set of formats + supported by the driver dynamically through the _get_caps() routine. + https://bugzilla.gnome.org/show_bug.cgi?id=703271 + https://bugzilla.gnome.org/show_bug.cgi?id=720737 + Signed-off-by: Gwenole Beauchesne + +2013-12-11 18:08:26 +0000 Matthieu Bouron + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: query downstream caps features like GLTextureUploadMeta. + Fix vaapidecode to correctly report caps features downstream, when + a custom pipeline is built manually. + https://bugzilla.gnome.org/show_bug.cgi?id=719372 + Signed-off-by: Gwenole Beauchesne + +2013-12-17 15:27:10 +0000 Matthieu Bouron + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: add system memory caps to template caps. + Since vaapidecode provides buffer that can be mapped as regular memory, + those caps should be added to the template caps. That only applies to + GStreamer >= 1.2. + https://bugzilla.gnome.org/show_bug.cgi?id=720608 + Signed-off-by: Gwenole Beauchesne + +2013-12-17 10:26:03 +0800 Wind Yuan + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix hang on SIGINT. + vaapidecode hangs when pipeline is stopped without any EOS, e.g. when + +C is pressed, thus causing the srcpad task to keep running and + locked. This fixes a deadlock on state change from PAUSED to READY. + https://bugzilla.gnome.org/show_bug.cgi?id=720584 + Signed-off-by: Gwenole Beauchesne + +2013-12-17 04:23:42 -0500 Wind Yuan + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: fix possible hang on SIGINT. + vaapiencode might hang when the pipeline is stopped without any EOS, + e.g. when +C is pressed, thus causing the srcpad task to keep + running and locked. This fixes a possible deadlock on state change + from PAUSED to READY. + https://bugzilla.gnome.org/show_bug.cgi?id=720584 + Signed-off-by: Gwenole Beauchesne + +2014-01-14 16:33:04 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: fix typo in error message. + Fix incomplete error message in gst_vaapiencode_push_frame(). + +2014-01-14 19:08:36 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + plugins: add helpers to create video caps with features. + Add gst_vaapi_video_format_new_template_caps_with_features() helper + function to add the supplied caps feature string on GStreamer >= 1.2. + Add gst_vaapi_find_preferred_caps_feature() helper function to discover + the "best" caps feature to use for the supplied pad. In practice, we + will always favor memory:VASurface first, then meta:GLTextureUploadMeta, + and finally the system memory caps. + https://bugzilla.gnome.org/show_bug.cgi?id=719372 + +2014-01-09 11:54:11 +0000 Matthieu Bouron + + * gst/vaapi/gstvaapivideometa_texture.c: + plugins: don't apply overlay composition in GLTextureUpload function. + The GLTextureUpload function is not in charge of doing the overlay + composition if any. + https://bugzilla.gnome.org/show_bug.cgi?id=721859 + Signed-off-by: Gwenole Beauchesne + +2014-01-14 13:47:52 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + encoder: re-order submission of VA objects. + Change the submission order of VA objects so that to make that process + more logical. i.e. submit sequence parameter first, if any; next the + packed headers associated to sequece, picture or slices; and finally + the actual picture and associated slices. + +2014-01-14 12:01:11 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + encoder: clean-up objects. + Various clean-ups to improve consistency and readability: rename some + variables, drop unused macro definitions, drop initialization of vars + that are zero-initialized from the base class, drop un-necessary casts, + allocate GPtrArrays with a destroy function. + +2014-01-13 13:41:35 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix frame cropping rectangle calculation. + Fix frame cropping rectangle calculation to handle horizontal resolutions + that don't match a multiple of 16 pixels, but also the vertical resolution + that was incorrectly computed for progressive sequences too. + https://bugzilla.gnome.org/show_bug.cgi?id=722089 + +2014-01-13 11:49:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: improve automatic bitrate calculation. + For non "Constant-QP" modes, we could provide more reasonable heuristics + for the target bitrate. In general, 48 bits per macroblock with all the + useful coding tools enable looks safe enough. Then, this rate is raised + by +10% to +15% for each coding tool that is disabled. + https://bugzilla.gnome.org/show_bug.cgi?id=719699 + +2014-01-13 11:11:25 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: support "high-compression" tuning option. + Add support for "high-compression" tuning option. First, determine the + largest supported profile by the hardware. Next, check any target limit + set by the user. Then, enable each individual coding tool based on the + resulting profile_idc value to use. + https://bugzilla.gnome.org/show_bug.cgi?id=719696 + +2014-01-12 22:24:04 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.h: + * gst/vaapi/gstvaapiencode_h264.c: + encoder: h264: allow target decoder constraints. + Allow user to precise the largest profile to use for encoding due + to target decoder constraints. For instance, if CABAC entropy coding + mode is requested by "constrained-baseline" profile only is desired, + then an error is returned during codec configuration. + Also make sure that the suitable profile we derived actually matches + what the HW can cope with. + https://bugzilla.gnome.org/show_bug.cgi?id=719694 + +2014-01-12 22:14:11 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: refine size of coded buffer. + Refine the heuristic to determine the maximum size of a coded buffer + to account for the exact number of slices. set_context_info() is the + last step during codec reconfiguration, no additional change is done + afterwards, so re-using the num_slices field here is fine. + https://bugzilla.gnome.org/show_bug.cgi?id=719953 + +2013-12-13 17:36:08 +0800 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + encoder: h264: expose more coding tools. + Add new H.264 coding tools to improve compression: + - "cabac": enable CABAC entropy coding (default: FALSE); + - "dct8x8": enable spatial transform 8x8 (default: FALSE). + https://bugzilla.gnome.org/show_bug.cgi?id=719693 + Signed-off-by: Gwenole Beauchesne + +2014-01-10 18:18:25 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + encoder: h264: derive profile and level from active coding tools. + Automatically derive the minimum profile and level to be used for + encoding, based on the activated coding tools. The encoder will + be trying to generate a bitstream that has the best chances to be + decoded on most platforms by default. + Also change the default profile to "constrained-baseline" so that + to ensure maximum compatibility when the stream is decoded. + https://bugzilla.gnome.org/show_bug.cgi?id=719691 + +2014-01-10 17:02:44 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + encoder: h264: fix hardware profile lookup. + Fix lookup for a suitable HW profile, as to be used by the underlying + hardware, based on heuristics that lead to characterize the SW profile, + i.e. the one used by the SW level encoding logic. + Also fix constraint_set0_flag (A.2.1) and constraint_set1_flag (A.2.2) + as they should respectively match the baseline and main profile. + https://bugzilla.gnome.org/show_bug.cgi?id=719827 + +2014-01-10 14:46:15 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + encoder: h264: support only the byte-stream format. + The libgstvaapi core encoders are meant to support raw bitstreams only. + Henceforth, we are always producing a stream in "byte-stream" format. + However, the "codec-data" buffer which holds SPS and PPS headers is + always available. The "lengthSizeMinusOne" field is always set to 3 + so that in-place "byte-stream" format to "avc" format conversion could + be performed. + +2014-01-10 14:05:40 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + * gst/vaapi/gstvaapiencode_h264.c: + encoder: h264: clean-ups. + Various clean-ups to improve consistency and readability: rename some + variables, drop unused macro definitions, drop initialization of vars + that are zero-initialized from the base class, drop un-necessary casts. + +2014-01-13 17:11:15 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + encoder: mpeg2: fix hardware profile lookup. + Fix lookup for a suitable HW profile, as to be used by the underlying + hardware, based on heuristics that lead to characterize the SW profile, + i.e. the one used by the SW level encoding logic. + +2014-01-13 16:56:04 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h: + encoder: mpeg2: derive profile and level from active coding tools. + Automatically derive the minimum profile and level to be used for + encoding, based on the activated coding tools. Improve lookup for + the best suitable level with the new MPEG-2 helper functions. + Also change the default profile to "simple" so that to ensure maximum + compatibility when the stream is decoded. + https://bugzilla.gnome.org/show_bug.cgi?id=719703 + +2014-01-13 14:41:15 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h: + encoder: mpeg2: clean-ups. + Various clean-ups to improve consistency and readability: drop unused + macro definitions, drop initialization of vars that are zero-initialized + from the base class, drop un-necessary casts. + +2014-01-13 10:48:25 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + encoder: add tuning options API. + Add encoder "tune" option to override the default behaviour that is to + favor maximum decoder compatibility at the expense of lower compression + ratios. + Expected tuning options to be developed are: + - "high-compression": improve compression, target best-in-class decoders; + - "low-latency": tune for low-latency decoding; + - "low-power": tune for encoding in low power / resources conditions. + +2014-01-12 23:17:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + encoder: fix bitrate units to match kbps. + Bitrate is expressed in kilobits per second (kbps). So, this exactly + means in multiple of 1000 bits, not 1024 bits. + https://bugzilla.gnome.org/show_bug.cgi?id=722086 + +2014-01-12 21:57:20 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + encoder: clean-ups. + Drop obsolete and unused macros. Add a few doc comments. Slightly + improve indentation of a few leftovers. + +2014-01-12 18:52:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + encoder: filter out the supported set of rate-control properties. + Only expose the exact static set of supported rate-control properties + to the upper layer. For instance, if the GstVaapiEncoderXXX class does + only support CQP rate control, then only add it the the exposed enum + type. + Add helper macros and functions to build a GType for an enum subset. + +2014-01-10 13:23:48 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + encoder: add keyframe period API. + Add gst_vaapi_encoder_set_keyframe_period() interface to allow the + user control the maximum distance between two keyframes. This new + property can only be set prior to gst_vaapi_encoder_set_codec_state(). + A value of zero for "keyframe-period" gets it re-evaluated to the + actual framerate during encoder reconfiguration. + +2014-01-10 12:01:51 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + encoder: improve codec reconfiguration. + Improve codec reconfiguration to be performed only through a single + function. That is, remove the _set_context_info() hook as subclass + should not alter the parent GstVaapiContextInfo itself. Besides, the + VA context is constructed only at the final stages of reconfigure(). + +2014-01-10 11:30:25 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicodedbufferpool.c: + * gst-libs/gst/vaapi/gstvaapicodedbufferpool.h: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + encoder: fix possible memory leak of coded buffer pools. + Fix gst_vaapi_encoder_reconfigure_internal() to re-/allocate the coded + buffer pool only if the coded buffer size actually changed. + +2014-01-10 10:54:22 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + encoder: add video codec-state API. + Add interface to communicate the encoder resolution and related info + like framerate, interlaced vs. progressive, etc. This new interface + supersedes gst_vaapi_encoder_set_format() and doesn't use any GstCaps + but rather use GstVideoCodecState. + Note that gst_vaapi_encoder_set_codec_state() is also a synchronization + point for codec config. This means that the encoder is reconfigured + there to match the latest properties. + +2014-01-13 17:18:42 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: don't crash on NULL encoder on _finish(). + Don't try to destroy an encoder, in GstVideoEncoder::finish() handler, + if it was not created in the first place. Return "not-negotiated" error + since this means we did not even reach GstVideoEncoder::set_format(), + where the encoder could have been created. + This fixes a crash when the vaapiencode_* plug-in elements get deallocated + and that we failed to negotiate either pad. + https://bugzilla.gnome.org/show_bug.cgi?id=719704 + +2014-01-09 18:20:24 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: use more GstVaapiPluginBase facilities. + Avoid duplication of pad references or query functions since they are + provided through the GstVaapiPluginBase object. + +2014-01-09 18:10:35 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264.h: + * gst/vaapi/gstvaapiencode_mpeg2.c: + vaapiencode: fix negotiation process of output caps. + The specified caps in gst_video_encoder_set_output_state() function + arguments should not contain any resolution, pixel-aspect-ratio, + framerate, codec-data et al. Those rather should be set through the + returned GstVideoCodecState. This means that output caps creation + could be delayed until before gst_video_encoder_finish_frame() is + called. + This greatly simplifies the GstVideoEncoder::set_format() callback + by the way. + +2014-01-08 18:56:23 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: make GstVaapiEncode an abstract type. + Make base GstVaapiEncode class an abstract type so that we cannot + create an instance from it without going through any of the codec + specific derived class. + +2014-01-09 10:09:38 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + vaapiencode: rename a few member functions. + Rename a few member functions to make them more consistent: + - alloc_encoder(): now reduced to allocate the encoder object only; + - alloc_buffer(): allocate buffer from srcpad, and copy bitstream. + +2014-01-08 18:36:46 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264.h: + * gst/vaapi/gstvaapiencode_mpeg2.c: + vaapiencode: update for new properties API. + Update MPEG-2 and H.264 encode elements to cope with the new core + libgstvaapi properties API. i.e. all configurable properties are now + directly handled at the GstVaapiEncoder level. + Besides, this also makes sure to not use or modify the GstVaapiEncoder + private definitions directly. Private data need to remain private. + https://bugzilla.gnome.org/show_bug.cgi?id=719529 + +2014-01-06 17:46:40 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + encoder: add properties API. + Add interface to communicate configurable properties to the encoder. + This covers both the common ones (rate-control, bitrate), and the + codec specific properties. + https://bugzilla.gnome.org/show_bug.cgi?id=719529 + +2014-01-06 18:01:33 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + encoder: add bitrate API. + Add gst_vaapi_encoder_set_bitrate() interface to allow the user control + the bitrate for encoding. Currently, changing this parameter is only + valid before the first frame is encoded. Should the value be modified + afterwards, then GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED is + returned. + https://bugzilla.gnome.org/show_bug.cgi?id=719529 + +2014-01-06 15:10:36 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + encoder: add rate control API. + Add gst_vaapi_encoder_set_rate_control() interface to request a new + rate control mode for encoding. Changing the rate control mode is + only valid prior to encoding the very first frame. Afterwards, an + error ("operation-failed") is issued. + https://bugzilla.gnome.org/show_bug.cgi?id=719529 + +2014-01-03 16:57:25 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + vaapiencode: fix indentation. + +2014-01-03 16:57:09 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst/vaapi/gstvaapiencode.h: + encoder: fix indentation. + +2014-01-13 16:20:06 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h: + utils: add new MPEG-2 helper functions. + Add various helper functions to convert profile, level, chroma formats + from gstreamer-vaapi world and the MPEG-2 specification world. + +2014-01-10 19:49:52 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + utils: h264: don't use fatal asserts. + Replace g_assert() with a g_debug() so that to not make the program + abort when an unsupported value is supplied. + +2014-01-10 19:37:44 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.h: + utils: h264: add helpers for profile and level string mappings. + Add profile and level helper functions to convert to/from strings. + +2014-01-10 18:27:20 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h: + utils: h264: expose levels in public header. + Instal header but only expose the + H.264 levels in there. The additional helper functions are meant + to be private for now. + +2014-01-09 09:27:40 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + codec: add helper macros to maintain object refcount. + Add gst_vaapi_mini_object_{ref,unref,replace}() helper macros so that + to avoid explicit casts to GstVaapiMiniObject in all caller sites. + +2014-01-09 09:30:49 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + codec: re-indent decoder objects. + +2014-01-09 09:10:21 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + codec: re-indent base codec objects. + +2014-01-03 12:49:05 +0000 Matthieu Bouron + + * gst/vaapi/gstvaapipluginbase.c: + plugins: do not free debug category in finalize method. + Fixes a crash when multiple vaapidecode elements are finalized since + the debug category is created once in the class init method. + This is a regression from git commit 7e58d60. + https://bugzilla.gnome.org/show_bug.cgi?id=721390 + Signed-off-by: Gwenole Beauchesne + +2014-01-02 11:35:30 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/glibcompat.h: + * tests/simple-decoder.c: + tests: simple-decoder: don't use deprecated g_thread_create(). + Use g_thread_try_new() instead of the deprecated g_thread_create() + function. Provide compatibility glue for any GLib version < 2.31.2. + +2014-01-02 11:17:28 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapipixmap_x11.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst/vaapi/gstvaapiencode.c: + Fix printf()-like formats. + Fix formts for various GST_DEBUG et al. invocations. More precisely, + make size_t arguments use the %zu format specifier accordingly; force + XID formats to be a 32-bit unsigned integer; and fix the format used + for gst_vaapi_create_surface_with_format() error cases since we have + been using strings nowadays. + +2013-12-21 07:38:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + utils: format: drop unused helper functions. + The following helper functions are no longer used, thus are removed: + - gst_vaapi_video_format_from_structure() + - gst_vaapi_video_format_from_caps() + - gst_vaapi_video_format_to_caps() + +2013-12-21 07:29:50 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + utils: re-indent GstVideoFormat related helpers. + +2013-12-21 08:27:30 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidownload.c: + download: use GstVideoInfo facilities to build output caps. + Use standard GstVideoInfo related functions to build the output caps, + thus directly preserving additional fields as needed, instead of + manually copying them over through gst_vaapi_append_surface_caps(). + Also ensure that the input caps are fixated first. + +2013-12-21 10:41:22 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapiuploader.c: + plugins: factor out construction of template caps. + Add new helper functions to build video template caps. + - gst_vaapi_video_format_new_template_caps(): + create GstCaps with size, frame rate and PAR to full range + - gst_vaapi_video_format_new_template_caps_from_list(): + try to create a "simplified" list from the supplied formats + +2013-12-21 06:41:34 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + plugins: factor out construction of GValue from GstVideoFormat. + Add new helper functions to build GValues from GstVideoFormat: + - gst_vaapi_value_set_format(): + build a GValue from the supplied video format + - gst_vaapi_value_set_format_list(): + build a GValue list from the supplied array of video formats + +2013-12-21 06:22:30 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + plugins: re-indent common and video context creation utils. + +2013-12-20 15:31:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst/vaapi/gstvaapidecode.c: + * tests/test-display.c: + display: don't use GstCaps for decode or encode profiles list. + Replace gst_vaapi_display_get_{decode,encode}_caps() APIs with more + more convenient APIs that return an array of GstVaapiProfile instead + of GstCaps: gst_vaapi_display_get_{decode,encode}_profiles(). + +2013-12-20 15:15:05 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapiuploader.c: + * tests/test-display.c: + display: don't use GstCaps for image or subpicture formats list. + Replace gst_vaapi_display_get_{image,subpicture}_caps() APIs, that + returned GstCaps, with more convenient APIs that return an array of + GstVideoFormat: gst_vaapi_display_get_{image,subpicture}_formats(). + +2013-12-20 14:01:45 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + display: allocate queried resources on-demand. + Allocate the set of decoders or encoders on-demand, when they are + queried. Likewise for VA display attributes, image and subpicture + formats. + +2013-12-20 13:27:07 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.h: + display: re-indent all GstVaapiDisplay related source code. + +2013-12-20 16:04:19 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + utils: add helper functions to get codec or profile name. + +2013-12-20 17:08:23 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapiuploader.c: + plugins: fix permissions for certain files. + Drop the execute bit for gstvaapiuploader.c and gstvaapipostproc.[ch] + files. + +2013-12-12 17:01:29 +0000 Matthieu Bouron + + * gst/vaapi/gstvaapivideometa_texture.c: + plugins: implement GLTextureUploadMeta user data copy. + Makes the copies of a buffer reference their own GLTextureUploadMeta + user data and prevent the original buffer accessing already freed + memory if its copies has been released and freed. + https://bugzilla.gnome.org/show_bug.cgi?id=720336 + [Propagate the original meta texture to the copy too] + Signed-off-by: Gwenole Beauchesne + +2013-12-17 18:52:23 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + plugins: factor out support for raw YUV buffers on sink pads. + Factor out propose_allocation() hooks, creation of video buffer pool + for the sink pad, conversion from raw YUV buffers to VA surface backed + buffers. Update vaapidecode, vaapiencode and vaapipostproc to cope + with the new GstVaapiPluginBase abilities. + +2013-12-17 18:46:07 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstcompat.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: factor out pad caps. + +2013-12-13 16:03:08 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: factor out video context sharing code. + +2013-12-13 13:24:24 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: factor out GstImplementsInterface. + +2013-12-13 12:00:35 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + plugins: check type of display obtained from neighbours. + Fix display creation code to check that any display obtained from a + neighbour actually has the type we expect. Note: if display type is + set to "any", we can then accept any VA display type. + +2013-12-13 11:52:47 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + * gst/vaapi/gstvaapiupload.c: + plugins: factor out display creation process. + Move common VA display creation code to GstVaapiPluginBase, with the + default display type remaining "any". Also add a "display-changed" + hook so that subclasses could perform additional tasks when/if the + VA display changed, due to a new display type request for instance. + All plug-ins are updated to cope with the new internal APIs. + +2013-12-13 10:24:26 +0100 Gwenole Beauchesne + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapidownload.h: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiupload.h: + plugins: add new base object, store display in there. + Introduce a new GstVaapiPluginBase object that will contain all common + data structures and perform all common tasks. First step is to have a + single place to hold VA displays. + While we are at it, also make sure to store and subsequently release + the appropriate debug category for the subclasses. + +2013-12-11 14:04:27 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst/vaapi/gstvaapivideometa_texture.c: + * gst/vaapi/gstvaapivideometa_texture.h: + plugins: fix GLTextureUploadMeta to work with different texture ids. + The GLTextureUploadMeta implementation assumed that for each upload() + sequence, the supplied texture id is always the same as the one that + was previously cached into the underlying GstVaapiTexture. Cope with + any texture id change the expense to recreate the underlying VA/GLX + resources. + https://bugzilla.gnome.org/show_bug.cgi?id=719643 + +2013-12-11 13:25:51 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideometa_texture.c: + plugins: allow builds without GLX enabled for GStreamer 1.2. + Don't try to build GLTextureUploadMeta related code if GLX is not + enabled during GStreamer >= 1.2 builds. + +2013-11-20 17:20:07 +0000 Matthieu Bouron + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideobufferpool.h: + * gst/vaapi/gstvaapivideometa_texture.c: + * gst/vaapi/gstvaapivideometa_texture.h: + plugins: request GLTextureUpload meta on buffers in the buffer pool. + Requesting the GLTextureUpload meta on buffers in the bufferpool + prevents such metas from being de-allocated when buffers are released + in the sink. + This is particulary useful in terms of performance when using the + GLTextureUploadMeta API since the GstVaapiTexture associated with + the target texture is stored in the meta. + https://bugzilla.gnome.org/show_bug.cgi?id=712558 + Signed-off-by: Gwenole Beauchesne + +2013-12-11 10:51:03 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideometa_texture.c: + plugins: robustify GstVideoGLTextureUploadMeta implementation. + Make GstVideoGLTextureUploadMeta::upload() implementation more robust + when the GstVaapiTexture associated with the supplied texture id could + not be created. + +2013-12-10 16:14:27 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: improve robustness when packets are missing. + Improve robustness when some expected packets where not received yet + or that were not correctly decoded. For example, don't try to decode + a picture if there was no valid frame headers parsed so far. + https://bugs.freedesktop.org/show_bug.cgi?id=57902 + +2013-12-10 14:20:55 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix decoding of BA3_SVA_C.264. + Conformance test Base_Ext_Main_profiles/BA3_SVA_C.264 complys with + extended profile specifications. However, the SPS header has the + constraint_set1_flag syntax element set to 1. This means that, if + a Main profile compliant decoder is available, then it should be + able to decode this stream. + This changes makes it possible to fall-back from Extended profile + to Main profile if constraint_set1_flag is set to 1. + https://bugzilla.gnome.org/show_bug.cgi?id=720190 + +2013-12-10 11:13:01 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + utils: h264: add more profiles. + Add extended profile (A.2.3), high 4:2:2 profile (A.2.6), high 4:2:2 + profiles (A.2.7, A.2.10), scalable profiles (G.10.1.1, G.10.1.2) and + multiview profiles (H.10.1.1, H.10.1.2). + Document "Constrained Baseline" and "High 10" profiles. + +2013-12-10 15:21:51 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit e7d0e18. + e7d0e18 h264: complete set of NAL unit types + +2013-12-06 15:08:26 +0800 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + decoder: h264: add support for constrained baseline profile. + Recognize streams marked as conforming to the "Constrained Baseline + Profile". If VA driver supports that as is, fine. Otherwise, fallback + to baseline, main or high profile. + Constrained Baseline Profile conveys coding tools that are common + to baseline profile and main profile. + https://bugzilla.gnome.org/show_bug.cgi?id=719947 + [Added fallbacks to main and high profiles] + Signed-off-by: Gwenole Beauchesne + +2013-12-09 12:46:45 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + decoder: h264: fix decoding of scaling lists. + The GStreamer codecparser layer now parses the scaling lists in zigzag + scan order, as expected, so that to match the original bitstream layout + and specification. However, further convert the scaling lists into + raster scan order to fit the existing practice in most VA drivers. + https://bugzilla.gnome.org/show_bug.cgi?id=706406 + +2013-12-09 12:07:28 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 177c73b. + a7e3255 add H.265 (HEVC) bitstream parser + 177c73b h264: fix picture level scaling lists derivation (rule B) + 14733f1 h264: fix parsing of VCL HRD parameters + 59a0b47 h264: store quantization matrices in zig-zag order + ffb6e26 h264: add helpers to convert quantization matrices + c78a504 mpeg2: also initialize debug category in parse_sequence_header() + 719d1b0 mpeg2: turn internal consistency check into a g_assert() + 5241d8e all: remove some unused functions + 18eb312 all: fix for GST_DISABLE_GST_DEBUG + 963c04a all: make warnings more meaningful + +2013-12-06 19:05:52 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.h: + utils: add helpers for H.264 levels. + - gst_vaapi_utils_h264_get_level(): + Returns GstVaapiLevelH264 from H.264 level_idc value + - gst_vaapi_utils_h264_get_level_idc(): + Returns H.264 level_idc value from GstVaapiLevelH264 + - gst_vaapi_utils_h264_get_level_limits(): + Returns level limits as specified in Table A-1 of the H.264 standard + - gst_vaapi_utils_h264_get_level_limits_table(): + Returns the Table A-1 specification + +2013-12-06 17:34:52 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + utils: add new H.264 profiles. + Add "Constrained Baseline Profile" and "High 10 Profile" definitions + and helper functiions. + +2013-12-06 17:21:52 +0100 Gwenole Beauchesne + + utils: add new H.264 helper functions. + * Profiles: + - gst_vaapi_utils_h264_get_profile(): + Returns GstVaapiProfile from H.264 profile_idc value + - gst_vaapi_utils_h264_get_profile_idc(): + Returns H.264 profile_idc value from GstVaapiProfile + * Chroma formats: + - gst_vaapi_utils_h264_get_chroma_type(): + Returns GstVaapiChromaType from H.264 chroma_format_idc value + - gst_vaapi_utils_h264_get_chroma_format_idc(): + Returns H.264 chroma_format_idc value from GstVaapiChromaType + +2013-12-03 11:05:17 +0000 Matthieu Bouron + + * gst-libs/gst/base/Makefile.am: + * gst-libs/gst/vaapi/Makefile.am: + Fix missing files in distribution tarball. + https://bugzilla.gnome.org/show_bug.cgi?id=719776 + [Additional fixes and clean-ups] + Signed-off-by: Gwenole Beauchesne + +2013-12-05 18:13:54 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + encoder: fix computation of max coded buffer size (again). + The previous fix was only valid to express the maximum size of the + macroblock layer, i.e. without any headers. Now, also account for + the slice headers and top picture header, but also any other header + we might stuff into the VA coded buffer, e.g. sequence headers. + +2013-12-04 19:10:13 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + encoder: fix computation of max coded buffer size. + Fix coded buffer size for each codec. A generic issue was that the + number of macroblocks was incorrectly computed. The second issue was + specific to MPEG-2 were the max number of bits per macroblock, and + as defined by the standard, was incorrectly mapped to the (lower) + H.264 requirement. i.e. 4608 bits vs. 3200 bits limit. + +2013-12-04 18:48:35 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + encoder: simplify VA context initialization process. + Change get_context_info() into a set_context_info() function that + initializes common defaults into the base class, thus allowing the + subclasses to specialize the context info further on. + The set_context_info() hook is also the location where additional + context specific data could be initialized. At this point, we are + guaranteed to have valid video resolution size and framerate. i.e. + gst_vaapi_encoder_set_format() was called beforehand. + +2013-11-26 14:38:23 +0800 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + encoder: fix mpeg2 compilation error. + https://bugzilla.gnome.org/show_bug.cgi?id=719746 + Signed-off-by: Gwenole Beauchesne + +2013-12-04 17:55:18 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst/vaapi/gstvaapiencode.c: + encoder: clean-ups and document public APIs. + Clean public APIs up so that to better align with the decoder APIs. + Most importantly, gst_vaapi_encoder_get_buffer() is changed to only + return the VA coded buffer proxy. Also provide useful documentation + for the public APIs. + +2013-12-04 17:05:17 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + encoder: avoid extra allocations of GstVaapiEncoderSyncPic objects. + Kill GstVaapiEncoderSyncPic objects that are internally and temporarily + allocated. Rather, associate a GstVaapiEncPicture to a coded buffer + through GstVaapiCodedBufferProxy user-data facility. + Besides, use a GAsyncQueue to maintain a thread-safe queue object of + coded buffers. + Partial fix for the following report: + https://bugzilla.gnome.org/show_bug.cgi?id=719530 + +2013-12-03 17:04:43 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst/vaapi/gstvaapiencode.c: + encoder: refactor status codes. + Drop obsolete or unused status codes. Align some status codes with the + decoder counterparts. + +2013-12-04 11:54:40 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + encoder: fix subclassing process. + Fix the GstVaapiEncoderClass parent class type. Make sure to validate + subclass hooks as early as possible, i.e. in gst_vaapi_encoder_init(), + thus avoiding useless run-time checks. Also simplify the subclass + initialization process to be less error prone. + +2013-12-03 16:11:46 +0100 Gwenole Beauchesne + + encoder: rework GstVaapiCodedBuffer and related proxy. + Refactor the GstVaapiCodedBuffer APIs so that to more clearly separate + public and private interfaces. Besides, the map/unmap APIs should not + be exposed as is but appropriate accessors should be provided instead. + * GstVaapiCodedBuffer: VA coded buffer abstraction + - gst_vaapi_coded_buffer_get_size(): get coded buffer size. + - gst_vaapi_coded_buffer_copy_into(): copy coded buffer into GstBuffer + * GstVaapiCodedBufferPool: pool of VA coded buffer objects + - gst_vaapi_coded_buffer_pool_new(): create a pool of coded buffers of + the specified max size, and bound to the supplied encoder + * GstVaapiCodedBufferProxy: pool-allocated VA coded buffer object proxy + - gst_vaapi_coded_buffer_proxy_new_from_pool(): create coded buf from pool + - gst_vaapi_coded_buffer_proxy_get_buffer(): get underlying coded buffer + - gst_vaapi_coded_buffer_proxy_get_buffer_size(): get coded buffer size + Rationale: more optimized transfer functions might be provided in the + future, thus rendering the map/unmap mechanism obsolete or sub-optimal. + https://bugzilla.gnome.org/show_bug.cgi?id=719775 + +2013-11-29 14:02:52 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + plugins: fix reference leaks of VA display objects. + Fix GstElement::set_context() implementation for all plug-in elements + to avoid leaking an extra reference to the VA display, thus preventing + correct cleanup of VA resources in GStreamer 1.2 builds. + +2013-11-29 13:56:12 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapivideocontext.c: + plugins: simplify gst_vaapi_ensure_display(). + Return earlier if the creation of a VA display failed. Likewise, simplify + gst_vaapi_video_context_propagate() now that we are guaranteed to have a + valid VA display. + +2013-11-28 19:08:28 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + plugins: fix memory leaks through GstVideoMeta maps. + When GstVideoMeta maps were used, the supporting functions incorrectly + used gst_buffer_get_memory() instead of gst_buffer_peek_memory(), thus + always increasing the associated GstMemory reference count and giving + zero chance to actually release that, and subsequently the VA display. + +2013-11-28 14:15:44 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiuploader.c: + plugins: use G_PARAM_STATIC_STRINGS. + This avoids a few string copies during initialization. + +2013-11-28 17:28:11 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideometa.c: + plugins: simplify VA video meta to only reference surface proxies. + Simplify GstVaapiVideoMeta to only hold a surface proxy, which is + now allocated from a surface pool. This also means that the local + reference to the VA surface is also gone, as it could be extracted + from the associated surface proxy. + +2013-11-28 16:51:37 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideobuffer.h: + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa.h: + plugins: drop obsolete functions. + Drop the following functions that are not longer used: + - gst_vaapi_video_buffer_new_with_surface() + - gst_vaapi_video_meta_new_with_surface() + - gst_vaapi_video_meta_set_surface() + - gst_vaapi_video_meta_set_surface_from_pool() + +2013-11-28 16:37:31 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideometa.c: + plugins: allow VA video meta to be allocated from surface proxy pools. + Fix gst_vaapi_video_meta_new_from_pool() to allocate VA surface proxies + from surface pools instead of plain VA surfaces. This is to simplify + allocations now that surface proxies are created from a surface pool. + +2013-11-28 17:25:05 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + surfaceproxy: add copy function. + Add gst_vaapi_surface_proxy_copy() function that creates a new surface + proxy with the same information from the parent proxy, except that the + user-defined destroy notify function is not copied over. + The underlying VA surface is pushed back to the video pool only when + the last reference to the parent surface proxy is released. + +2013-11-28 15:56:53 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + * gst/vaapi/gstvaapiencode.c: + vaapiencode: optimize _handle_frame() to avoid extra allocation. + Optimize gst_vaapiencode_handle_frame() to avoid extra memory allocation, + and in particular the GstVaapiEncObjUserData object. i.e. directly use + the VA surface proxy from the source buffer. This also makes the user + data attached to the GstVideoCodecFrame more consistent between both + the decoder and encoder plug-in elements. + +2013-11-28 15:14:43 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: fix memory leaks in _push_frame() on error. + Simplify gst_vaapiencode_push_frame(), while also removing the call + to gst_video_encoder_negotiate() since this is implicit in _finish() + if caps changed. Also fixed memory leaks that occured on error. + +2013-11-28 13:57:54 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264.h: + * gst/vaapi/gstvaapiencode_mpeg2.c: + vaapiencode: additional clean-ups. + Constify pointers wherever possible. Drop unused variables, and use + consistent variable names. Fix gst_vaapiencode_h264_allocate_buffer() + to correctly report errors, especially when in-place conversion from + bytestream to avcC format failed. + +2013-11-28 13:26:40 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264.h: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_mpeg2.h: + vaapiencode: move common properties to base class. + Move "rate-control" mode and "bitrate" properties to the GstVaapiEncode + base class. The actual range of supported rate control modes is currently + implemented as a plug-in element hook. This ought to be determined from + the GstVaapiEncoder object instead, i.e. from libgstvaapi. + +2013-11-28 10:54:36 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + vaapiencode: fix plugin description and debug name. + Align the plug-in debug category to its actual name. i.e. enable debug + logs through vaapiencode_ where is mpeg2, h264, etc. Fix + the plug-in element description to make it more consistent with other + VA-API plug-ins. + +2013-11-27 16:27:31 +0100 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/video/Makefile.am: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + vaapiencode: add initial support for GStreamer 0.10. + +2013-11-27 16:25:59 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstcompat.h: + libs: add more GstBuffer compat glue for GStreamer 0.10. + Add gst_buffer_new_allocate() and gst_buffer_fill() implementations. + Fix gst_buffer_new_wrapped_full() implementation to handle the destroy + notify function. + +2013-11-27 15:56:51 +0100 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/video/Makefile.am: + libs: always use built-in videoutils for GStreamer 0.10. + GStreamer 0.10.36 is the latest and ultimate version to be released + from the GStreamer 0.10 branch. i.e. no further releases are to be + made. So, we can safely enable the built-in videoutils replacement + now that they are in sync with the 0.10 branch. + +2013-11-27 15:47:38 +0100 Gwenole Beauchesne + + * ext/videoutils: + videoutils: update to master commit d4a15a5. + d4a15a5 video: fix compiler warning in header with C++11 / clang-3.1 + 86096cc videodecoder: minor cosmetic changes to align a bit more with master + b4b8b52 videodecoder: allow parse function to not use all data on adapter + 2145495 videodecoder: warn if frame list gets long + 36c3753 videodecoder: Also use the object lock to protect the output_state + 518c93d videodecoder: fix seeking again + 185fb63 video: Correct usage of the base class stream lock + 170e944 videodecoder: Expose _negotiate function + +2013-11-26 12:06:07 +0000 Matthieu Bouron + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * tests/Makefile.am: + Fix build with GStreamer >= 1.3. + http://bugzilla.gnome.org/show_bug.cgi?id=715183 + Signed-off-by: Gwenole Beauchesne + +2013-11-26 17:56:59 +0100 Gwenole Beauchesne + + * configure.ac: + configure: disable encoders with GStreamer 0.10. + Don't try to build video encoders for GStreamer 0.10. Support code is + not there yet, and probably will never for such an ancient version. + +2013-11-26 17:26:44 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: fix error handling while allocating output buffers. + Fix default GstVideoEncoder::allocate_buffer() implementation to properly + unmap the coded buffer prior to returning an error. + +2013-11-26 17:11:22 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: fix error handling in _finish() hook. + Fix GstVideoEncoder::finish() implementation to really return possible + errors instead of GST_FLOW_OK. That is, fix check for timeout status. + +2013-11-26 16:34:14 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264.h: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_mpeg2.h: + vaapiencode: minor clean-ups. + Add a GST_VAAPIENCODE_CAST() helper to avoid run-time checks against + the GObject type system. We are guaranteed to only deal with the same + plug-in element object. + +2013-11-26 15:31:03 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + vaapiencode: fix support for raw YUV sink buffers. + Allow vaapiencode plug-in elements to encode from raw YUV buffers. + The most efficient way to do so is to let the vaapiencode elements + allocate a buffer pool, and subsequently buffers from it. This means + that upstream elements are expected to honour downstream pools. + If upstream elements insist on providing their own allocated buffers + to the vaapiencode elements, then it possibly would be more efficient + to insert a vaapipostproc element before the vaapiencode element. + This is because vaapipostproc currently has better support than other + elements for "foreign" raw YUV buffers. + +2013-11-26 15:12:59 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: fix support for GStreamer 1.2. + +2013-11-07 17:42:21 +0800 Wind Yuan + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + vaapiencode: initial port to GStreamer 1.2. + Signed-off-by: Gwenole Beauchesne + +2013-11-20 16:21:32 +0800 XuGuangxin + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_mpeg2.h: + plugins: add mpeg2 encoder element. + Add GstVaapiEncodeMPEG2 element object. The actual plug-in element + is called "vaapiencode_mpeg2". + Valid properties: + - rate-control: rate control mode (default: cqp - constant QP) + - bitrate: desired bitrate in kbps (default: auto-calculated) + - key-period: maximal distance between two key frames (default: 30) + - max-bframes: number of B-frames between I and P (default: 2) + - quantizer: constant quantizer (default: 8) + Signed-off-by: Gwenole Beauchesne + +2013-07-29 16:02:56 +0800 Wind Yuan + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264.h: + plugins: add h264 encoder element. + Add GstVaapiEncodeH264 element object. The actual plug-in element + is called "vaapiencode_h264". + Valid properties: + - rate-control: rate control mode (default: none) + - bitrate: desired bitrate in kbps (default: auto-calculated) + - key-period: maximal distance between two key frames (default: 30) + - num-slices: number of slices per frame (default: 1) + - max-bframes: number of B-frames between I and P (default: 0) + - min-qp: minimal quantizer (default: 1) + - init-qp: initial quantizer (default: 26) + Signed-off-by: Gwenole Beauchesne + +2013-07-29 13:44:48 +0800 Wind Yuan + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + plugins: add base encoder element. + vaapiencode element is based on GstVideoEncoder APIs. + Signed-off-by: Gwenole Beauchesne + +2013-11-20 16:20:15 +0800 XuGuangxin + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h: + encoder: add mpeg2 encoder. + Add initial support for MPEG-2 encoding. I/P/B frames are supported. + Signed-off-by: Gwenole Beauchesne + +2013-07-29 15:46:11 +0800 Wind Yuan + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h: + encoder: add h264 encoder. + Signed-off-by: Gwenole Beauchesne + +2013-07-29 13:34:06 +0800 Wind Yuan + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + Add initial infrastructure for video encoding. + Add initial API for video encoding: only basic interfaces and small + encoder objects are implemented so far. + Signed-off-by: Gwenole Beauchesne + +2013-07-29 15:41:23 +0800 Wind Yuan + + * configure.ac: + * gst-libs/gst/Makefile.am: + * gst-libs/gst/base/Makefile.am: + * gst-libs/gst/base/gstbitwriter.c: + * gst-libs/gst/base/gstbitwriter.h: + * gst-libs/gst/vaapi/Makefile.am: + libs: add generic bitstream writer. + GstBitWriter provides a bit writer that can write any number of bits + to a pre-allocated memory buffer. Helper functions are also provided + to write any number of bits from 8, 16, 32 and 64 bit variables. + Signed-off-by: Gwenole Beauchesne + +2013-07-12 22:07:59 +0800 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + libs: add support for rate-control to GstVaapiContext. + Extend GstVaapiContextInfo structure to hold the desired rate control + mode for encoding purposes. For decoding purposes, this field is not + used and it is initialized to GST_VAAPI_RATECONTROL_NONE. + Signed-off-by: Gwenole Beauchesne + +2013-07-12 21:33:32 +0800 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + libs: add rate-control attributes. + Add GstVaapiRateControl types and GType values in view to supporting + rate controls for encoding. This is meant to be used for instance in + GstVaapiContext. + Signed-off-by: Gwenole Beauchesne + +2013-11-22 11:56:51 +0100 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2013-11-22 11:28:09 +0100 Gwenole Beauchesne + + * gst/vaapi/Makefile.am: + build: fix for Wayland headers not in standard include dirs. + Fix build when Wayland headers don't live in plain system include dirs + like /usr/include but rather in /usr/include/wayland for instance. + Original patch written by Dominique Leuenberger + https://bugzilla.gnome.org/show_bug.cgi?id=712282 + +2013-11-14 10:58:37 +0000 Ross Burton + + * gst-libs/gst/vaapi/Makefile.am: + build: link libgstvaapi-wayland against videoutils. + This library is using symbols that don't exist in GStreamer 0.10 so + it needs to link to built-in implementation (libgstvaapi-videoutils). + https://bugzilla.gnome.org/show_bug.cgi?id=712282 + Signed-off-by: Ross Burton + Signed-off-by: Gwenole Beauchesne + +2013-11-22 11:15:57 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst/vaapi/gstvaapipostproc.c: + vaapostproc: fix memory leaks. + Destroy VPP output surface pool on exit. Also avoid a possible crash + in double-free situation caused by insufficiently reference counted + array of formats returned during initialization. + +2013-11-22 10:19:06 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: fix and optimize advanced deinterlacing mode. + Fix advanced deinterlacing modes with VPP to track only up to 2 past + reference buffers. This used to be 3 past reference buffers but this + doesn't fit with the existing decode pipeline that only has 4 extra + scratch surfaces. + Also optimize references tracking to be only enabled when needed, i.e. + when advanced deinterlacing mode is used. This means that we don't + need to track past references for basic bob or weave deinterlacing. + +2013-11-22 10:04:45 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix "mixed" mode deinterlacing. + In "mixed" interlaced streams, the buffer contains additional flags that + specify whether the frame contained herein is interlaced or not. This means + that we can alternatively get progressive or interlaced frames. Make sure + to disable deinterlacing at the VPP level when the source buffer is no longer + interlaced. + +2013-11-22 09:49:30 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix memory leaks with advanced deinterlacing. + Fix memory leaks with advanced deinterlacing, i.e. when we keep track + of past buffers. Completely reset the deinterlace state, thus destroying + any buffer currently held, on _start(), _stop() and _destroy(). + +2013-11-22 06:59:51 +0100 Gwenole Beauchesne + + * README: + README: updates. + - GStreamer 1.2 APIs are supported ; + - Video Processing (VA/VPP) features. + +2013-11-22 06:45:22 +0100 Gwenole Beauchesne + + * README: + README: update for GStreamer >= 1.0.x and VPP features. + +2013-11-22 06:37:12 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/glibcompat.h: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.h: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapiminiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapivideopool_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.c: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.h: + * gst/vaapi/gstvaapidownload.h: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapisink.h: + * gst/vaapi/gstvaapivideoconverter_glx.h: + * tests/image.c: + * tests/image.h: + * tests/output.h: + * tests/test-display.c: + * tests/test-jpeg.c: + * tests/test-jpeg.h: + * tests/test-mpeg4.c: + * tests/test-mpeg4.h: + * tests/test-surfaces.c: + * tests/test-windows.c: + legal: update copyright notice dates. + +2013-11-22 05:57:18 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/glibcompat.h: + * gst-libs/gst/vaapi/gstcompat.h: + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidebug.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.c: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.h: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimage_priv.h: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapiminiobject.c: + * gst-libs/gst/vaapi/gstvaapiminiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapiparser_frame.c: + * gst-libs/gst/vaapi/gstvaapiparser_frame.h: + * gst-libs/gst/vaapi/gstvaapipixmap.c: + * gst-libs/gst/vaapi/gstvaapipixmap.h: + * gst-libs/gst/vaapi/gstvaapipixmap_priv.h: + * gst-libs/gst/vaapi/gstvaapipixmap_x11.c: + * gst-libs/gst/vaapi/gstvaapipixmap_x11.h: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapivideopool_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.c: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapiworkarounds.h: + * gst-libs/gst/vaapi/sysdeps.h: + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapidownload.h: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiupload.h: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapiuploader.h: + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideobuffer.h: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideobufferpool.h: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideoconverter_glx.h: + * gst/vaapi/gstvaapivideoconverter_x11.c: + * gst/vaapi/gstvaapivideoconverter_x11.h: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa.h: + * gst/vaapi/gstvaapivideometa_texture.c: + * gst/vaapi/gstvaapivideometa_texture.h: + * tests/codec.c: + * tests/codec.h: + * tests/decoder.c: + * tests/decoder.h: + * tests/image.c: + * tests/image.h: + * tests/output.c: + * tests/output.h: + * tests/simple-decoder.c: + * tests/test-decode.c: + * tests/test-decode.h: + * tests/test-display.c: + * tests/test-filter.c: + * tests/test-h264.c: + * tests/test-h264.h: + * tests/test-jpeg.c: + * tests/test-jpeg.h: + * tests/test-mpeg2.c: + * tests/test-mpeg2.h: + * tests/test-mpeg4.c: + * tests/test-mpeg4.h: + * tests/test-surfaces.c: + * tests/test-textures.c: + * tests/test-vc1.c: + * tests/test-vc1.h: + * tests/test-windows.c: + legal: add per-file authorship information. + Credit original authors on a per-file basis as we cannot expect people + to know all country-specific rules, or bother browsing through the git + history. + +2013-11-21 23:52:43 +0100 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.5.7. + +2013-11-21 23:51:59 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-11-21 23:17:59 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.h: + decoder: don't include obsolete headers. + The header was removed from the public + set of APIs. So, don't make public headers (gstvaapidecoder.h) depend + on private files. + +2013-11-18 16:20:43 +0100 Gwenole Beauchesne + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: add initial support for GStreamer 1.2. + Port vaapipostproc element to GStreamer 1.2. Support is quite minimal + right now so that to cope with auto-plugging issues/regressions. e.g. + this happens when the correct set of expected caps are being exposed. + This means that, currently, the proposed caps are not fully accurate. + +2013-11-01 10:22:17 +0800 Halley Zhao + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: add support for denoise and sharpen filters. + Signed-off-by: Gwenole Beauchesne + +2013-11-21 19:52:56 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: add support for advanced deinterlacing. + Add initial support for advanced deinterlacing. The history buffer + size is arbitrarily set to 3 references for now. + +2013-11-21 22:32:03 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix deinterlacing with VPP. + Fix basic deinterlacing flags provided to gst_vaapi_set_deinterlacing() + for the first field. Render flags were supplied instead of the actual + deinterlacing flags (deint_flags). + +2013-11-21 15:08:55 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix transform caps. + Fix GstBaseTransform::transform_caps() implementation to always return + the complete set of allowed sink pad caps (unfixated) even if the src + pad caps we are getting are fixated. Rationale: there are just so many + possible combinations, and it was wrong to provide a unique set anyway. + As a side effect, this greatly simplifies the ability to derive src pad + caps from fixated sink pad caps. + +2013-11-01 10:31:13 +0800 Halley Zhao + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + filter: add helper to specify references for deinterlacing. + Add gst_vaapi_fitler_set_deinterlacing_references() API to submit the + list of surfaces used for forward or backward reference in advanced + deinterlacing mode, e.g. Motion-Adaptive, Motion-Compensated. + The list of surfaces used as deinterlacing references shall be live + until the next call to gst_vaapi_filter_process(). + Signed-off-by: Gwenole Beauchesne + +2013-11-21 18:44:46 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst/vaapi/gstvaapipostproc.c: + * tests/test-filter.c: + filter: fix semantics of deinterlacing flags. + Fix deinterlacing flags to make more sense. The TFF (top-field-first) + flag is meant to specify the organization of reference frames used in + advanced deinterlacing modes. Introduce the more explicit flag TOPFIELD + to specify that the top-field of the supplied input surface is to be + used for deinterlacing. Conversely, if not set, this means that the + bottom field of the supplied input surface will be used instead. + +2013-11-21 17:20:28 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + filter: add helpers to check for supported/active operation. + Add a couple of helper functions: + - gst_vaapi_filter_has_operation(): checks whether the VA driver + advertises support for the supplied operation ; + - gst_vaapi_filter_use_operation(): checks whether the supplied + operation was already enabled to its non-default value. + +2013-11-20 15:10:17 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + libs: fix GstVaapiSurfaceProxy destroy notify call site. + The user-defined destroy notify function is meant to be called only when + the surface proxy was fully released, i.e. once it actually released the + VA surface back to the underlying pool. + +2013-08-29 13:44:22 +0800 XuGuangxin + + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool_priv.h: + libs: make GstVaapiVideoPool thread-safe. + https://bugzilla.gnome.org/show_bug.cgi?id=707108 + Signed-off-by: Gwenole Beauchesne + +2013-08-29 14:04:06 +0800 XuGuangxin + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + libs: robustify decoder objects and surface proxy initialization. + Fix GstVaapiPicture, GstVaapiSlice and GstVaapiSurfaceProxy initialization + sequences to have the expected default values set beforehand in case of an + error raising up further during creation. i.e. make it possible to cleanly + destroy those partially initialized objects. + https://bugzilla.gnome.org/show_bug.cgi?id=707108 + Signed-off-by: Gwenole Beauchesne + +2013-11-21 11:01:41 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix decoder flush. + There are situations where gst_video_decoder_flush() is called, and + this subsequently produces a gst_video_decoder_reset() that kills the + currently active GstVideoCodecFrame. This means that it no longer + exists by the time we reach GstVideoDecoder::finish() callback, thus + possibly resulting in a crash if we assumed spare data was still + available for decode (current_frame_size > 0). + Try to honour GstVideoDecoder::reset() behaviour from GStreamer 1.0 + that means a flush, thus performing the actual operations there like + calling gst_video_decoder_have_frame() if pending data is available. + +2013-11-20 19:21:05 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: fix dead-locks with decoder task. + Review all interactions between the main video decoder stream thread + and the decode task to derive a correct sequence of operations for + decoding. Also avoid extra atomic operations that become implicit under + the GstVideoDecoder stream lock. + +2013-08-29 14:12:10 +0800 XuGuangxin + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix hard reset for seek cases. + Fix hard reset for seek cases by flushing the GstVaapiDecoder queue + and completely purge any decoded output frame that may come out from + it. At this stage, the GstVaapiDecoder shall be in a complete clean + state to start decoding over new buffers. + Signed-off-by: Gwenole Beauchesne + +2013-08-29 14:12:10 +0800 XuGuangxin + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: drop decode timeout, always wait for a free surface. + vaapidecode used to wait up to one second past the expected time of + presentation for the last decoded frame. This is not realistic in + practice when it comes to video pause/resume. Changed behaviour to + unconditionnally wait for a free VA surface prior to continuing the + decoding. The decode task will continue pushing the output frames to + the downstream element while also reporting errors at the same time + to the main thread. + https://bugzilla.gnome.org/show_bug.cgi?id=707108 + Signed-off-by: Gwenole Beauchesne + +2013-11-20 10:56:28 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix srcpad caps for GStreamer 1.2. + The srcpad caps exposed for GStreamer 1.2 were missing any useful info + like framerate, pixel-aspect-ratio, interlace-mode et al. Not to mention + that it relied on possibly un-initialized data. Fix srcpad caps to be + initialized from a sanitized copy of GstVideoDecoder output state caps. + Note: the correct way to expose the srcpad caps triggers an additional + issue in core GStreamer auto-plugging capabilities as the correct caps + to be exposed should be format=ENCODED with memory:VASurface caps feature + at the minimum. In some situations, we could determine the underlying + VA surface format, but this is not always possible. e.g. cases where it + is not allowed to expose the underlying VA surface data, or when the + VA driver implementation cannot actually provide such information. + +2013-11-20 10:45:23 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + plugins: streamline VA formats exposed in caps to a realistic set. + Currently, the decoder only supports YUV 4:2:0 output. So, expose the + output formats for GStreamer 1.2 in caps to a realistic subset. This + means NV12, I420 or YV12 but also ENCODED if we cannot determine the + underlying VA surface format, or if it is actually not allowed to get + access to the surface contents. + +2013-11-20 10:37:36 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + plugins: expose the expected format for GstVideoGLTextureUploadMeta. + Fix vaapidecode srcpad caps to only expose RGBA video format for the + meta:GstVideoGLTextureUploadMeta feature. That's only what is supported + so far. Besides, drop this meta from the vaapisink sinkpad caps since + we really don't support that for rendering. + https://bugzilla.gnome.org/show_bug.cgi?id=711828 + +2013-11-18 18:25:21 +0100 Gwenole Beauchesne + + * configure.ac: + configure: automatically detect GStreamer API version. + Automatically detect GStreamer API version. The --with-gstreamer-api + configure option now defaults to "autodetect" and configure then tries + to derive the GStreamer API version from the highest version based on + what pkg-config --modversion would report. + https://bugzilla.gnome.org/show_bug.cgi?id=711657 + +2013-11-01 13:43:11 +0800 Wind Yuan + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix support for raw YUV data upload on GStreamer 1.0. + Fix raw YUV data uploaded as in the following pipeline: + $ gst-launch-1.0 filesrc video.yuv ! videoparse ! vaapipostproc ! vaapisink + The main reason why it failed was that the videoparse element simply + allocates GstBuffer with raw data chunk'ed off the sink pad without + any prior knowledge of the actual frame info. i.e. it basically just + calls gst_adapter_take_buffer(). + We could avoid the extra copy performed in vaapipostproc if the videoparse + element was aware of the downstream pool and bothers copying line by + line, for each plane. This means that, for a single frame per buffer, + the optimizatin will be to allocate the video buffer downstream, map + it, and copy each line that is coming through until we need to fills + in the successive planes. + Still, optimized raw YUV uploads already worked with the following: + $ gst-launch-1.0 videotestsrc ! vaapipostproc ! vaapisink + https://bugzilla.gnome.org/show_bug.cgi?id=711250 + [clean-ups, fixed error cases to unmap and unref outbuf] + Signed-off-by: Gwenole Beauchesne + +2013-11-16 07:02:24 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: try to downgrade deinterlace-method when needed. + If the currently selected deinterlacing method is not supported by the + underlying hardware, then try to downgrade the method to a supported one. + At the minimum, basic bob-deinterlacing shall always be supported. + +2013-11-15 19:04:07 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: add initial support for deinterlacing with VPP. + Allow basic bob-deinterlacing to work when VPP is enabled. Currently, + this only covers bob-deinterlacing when the output pixel format is + explicitly set. + +2013-11-15 17:14:04 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix build on 64-bit platforms with GStreamer 0.10. + The size argument for GstBaseTransform::transform_size() hook is a + guint in GStreamer 0.10 APIs but a gsize in GStreamer >= 1.0.X APIs. + +2013-10-18 18:08:25 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: add initial support for scaling. + Add initial support for basic scaling with size specified through the + "width" and "height" properties. If either user-provided dimension is + zero and "force-aspect-ratio" is set to true (the default), then the + other dimension is scaled to preserve the aspect ratio. + +2013-10-18 18:08:25 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: add initial support for color conversion. + If VPP is available, we always try to implicitly convert the source + buffer to the "native" surface format for the underlying accelerator. + This means that no optimization is performed yet to propagate raw YUV + buffers to the downstream element as is, if VPP is available. i.e. it + will always cause a color conversion. + +2013-10-16 11:23:03 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix bug when user disabled deinterlacing. + Fix pipeline error / hang when the user disabled deinterlacing through + the deinterlace-mode=disabled property setting. + +2013-10-16 11:20:50 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: factor out operations to be applied into flags. + Even if we only support deinterlacing for now, use flags to specify + which filters are to be applied to each frame we receive in transform(). + This is preparatory work for integrating new filters. + +2013-10-04 15:37:24 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: add support for raw YUV video source buffers. + Allow video processing from raw YUV buffers coming from the sink pad, + while still producing a VA surface for the downstream elements. + +2013-10-04 16:00:56 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: add support for "mixed" interlace mode. + Add support for "mixed" interlace-mode, whereby the video frame buffer + shall be deinterlaced only if its flags mention that's actually an + interlaced frame buffer. + +2013-10-03 19:04:07 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstcompat.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideobuffer.h: + vaapipostproc: rework plug-in element. + Rewrite the vaapipostproc plug-in element so that it derives from + GstBaseTransform, thus simplifying the caps negotiation process. + +2013-10-09 17:25:10 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: fix and optimize check for buffer pool allocator params. + Reset the buffer pool allocator only if the config caps changed in a + sensible way: format or resolution change. i.e. don't bother with + other caps like colorimetry et al. as this doesn't affect the way to + allocate VA surfaces or images. + +2013-10-09 10:33:55 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + plugins: enable memory maps for read & write with direct-rendering. + Enable read and write mappings only if direct-rendering is supported. + Otherwise, this means that we may need to download data from the VA + surface first for correctness, even if the VA surface doesn't need to + be read at all. i.e. sometimes, READWRITE mappings are meant for + surfaces that are written to first, and read afterwards for further + processing. + https://bugzilla.gnome.org/show_bug.cgi?id=704078 + +2013-10-09 10:06:40 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + plugins: fix check for direct-rendering support. + Fix check for direct-rendering if the creation of VA surfaces with + an explicit pixel format is not support, e.g. VA-API < 0.34.0, and + that we tried to allocate a VA surface based on the corresponding + chroma type. i.e. in that particular case, we have to make sure that + the derived image has actually the expected format. + +2013-10-09 09:47:18 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: fix buffer pool reset_buffer() to reset memory resources. + Fix GstVaapiVideoBufferPool::reset_buffer() to reset the underlying + memory resources, and more particularly the VA surface proxy. Most + importantly, the GstVaapiVideoMeta is retained. Cached surface in + memory are released, thus triggering a new allocation the next time + we need to map the buffer. + +2013-10-09 09:33:56 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: fix GstVaapiVideoMemory to allocate VA surface proxies. + Make sure GstVaapiVideoMemory allocates VA surface proxies from a + pool stored in the parent VA memory allocator. + This fixes the following scenario: + - VA video buffer 1 is allocated from a buffer pool + - Another video buffer is created, and inherits info from buffer 1 + - Buffer 1 is released, thus pushing it back to the buffer pool + - New buffer alloc request comes it, this yields buffer 1 back + - At this stage, buffers 1 and 2 still share the same underlying VA + surface, but buffer 2 was already submitted downstream for further + processing, thus conflicting with additional processing we were + about to perform on buffer 1. + Maybe the core GstBufferPool implementation should have been fixed + instead to actually make sure that the returned GstBuffer memory we + found from the pool is writable? + +2013-10-04 19:34:32 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapiuploader.c: + plugins: create a proxy for GstVaapiUploader allocated buffers. + Always make sure to allocate a VA surface proxy for GstVaapiUploader + allocated buffers, i.e. make gst_vaapi_uploader_get_buffer() allocate + a proxy surface. + This fixes cases where we want to retain the underlying surface longer, + instead of releasing it back to the surface pool right away. + +2013-10-04 19:30:36 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + plugins: add helper function to disable deinterlacing in caps. + Add gst_caps_set_interlaced() helper function that would reset the + interlace-mode field to "progressive" for GStreamer >= 1.0, or the + interlaced field to "false" for GStreamer 0.10. + +2013-10-01 18:26:39 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapifilter.c: + filter: fix memory leak of VPP operations. + Fix ensure_operations() to release the VPP operations array if non + NULL, prior to returning to the caller. The former function was also + renamed to a more meaningful get_operations() since the caller owns + the returned array that needs to be released. + +2013-09-04 13:53:25 +0800 Zhao Halley + + * gst-libs/gst/vaapi/gstvaapifilter.c: + filter: fix first-time operation lookup. + Fix first-time operation lookup through find_operation() if the set + of supported operations was not initially determined through the + gst_vaapi_filter_get_operations() helper function. + Signed-off-by: Gwenole Beauchesne + +2013-09-04 13:53:25 +0800 Zhao Halley + + * gst-libs/gst/vaapi/gstvaapifilter.c: + filter: fix colorbalance related subtypes. + Fix intiialization of GstVaapiFilterOpData for colorbalance related + operations. In particular, fill in the va_subtype field accordingly. + Signed-off-by: Gwenole Beauchesne + +2013-09-30 17:08:12 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + filter: fix VA-API 0.34.0 symbol guards. + VASurfaceAttrib and VAProcFilterParameterBufferType are symbols + that need to be guarded for libva 0.34 and 0.33, respectively. + https://bugzilla.gnome.org/show_bug.cgi?id=709102 + Signed-off-by: Gwenole Beauchesne + +2013-10-01 17:57:11 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapisink.c: + plugins: hanle the context query in any pad. + Also this patch simplifies the code, since now the query is common for the + decoder and the sink. + https://bugzilla.gnome.org/show_bug.cgi?id=709200 + +2013-10-01 12:09:44 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + plugins: query upstream element for a GstContext. + Fix gst_vaapi_video_context_prepare() to also query upstream elements + for a valid GstContext. Improve comments regarding the steps used to + lookup or build that context, thus conforming to the GstContext API + recommendations. + https://bugzilla.gnome.org/show_bug.cgi?id=709112 + Signed-off-by: Gwenole Beauchesne + +2013-09-26 15:21:24 +0200 Gwenole Beauchesne + + * configure.ac: + * debian.upstream/control.in: + Fix detection and packaging of GStreamer 1.2.x builds. + The GStreamer 1.2.x packages sticked to the naming convention for 1.0.x + packages, i.e. -1.0 suffix. However, for gstreamer-vaapi packaging + purposes, update the versioning to -1.2 suffix instead. + +2013-07-15 13:41:00 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapivideometa_texture.c: + * gst/vaapi/gstvaapivideometa_texture.h: + plugins: add support for GstVideoGLTextureUploadMeta. + If the allocation meta GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE is + requested, and more specifically under a GLX configuration, then add + the GstVideoGLTextureUploadMeta to the output buffer. + https://bugzilla.gnome.org/show_bug.cgi?id=703236 + Signed-off-by: Gwenole Beauchesne + +2013-07-04 11:03:52 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: add support for GstCaps features. + Move VA video buffer memory from "video/x-surface,type=vaapi" format, + as expressed in caps, to the more standard use of caps features. i.e. + add "memory:VASurface" feature attribute to the associated caps. + https://bugzilla.gnome.org/show_bug.cgi?id=703271 + Signed-off-by: Gwenole Beauchesne + +2013-07-12 12:58:57 -0400 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + plugins: improve ::query() debugging messages. + Fix gst_vaapidecode_query() to correctly display the query type name, + instead of randomly displaying that we shared the underlying display. + Also add debug info for the GstVaapiSink::query() handler, i.e. the + supplied query type name actually. + Signed-off-by: Gwenole Beauchesne + +2013-07-12 12:58:57 -0400 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + plugins: add support for GstContext API. + Add support for the new GstContext API from GStreamer 1.2.x. + - implement the GstElement::set_context() hook ; + - reply to the `context' query from downstream elements. + https://bugzilla.gnome.org/show_bug.cgi?id=703235 + Signed-off-by: Gwenole Beauchesne + +2013-05-22 12:07:52 -0400 Víctor Manuel Jáquez Leal + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + plugins: add compat layer for GstVideoContext. + Add thin compatibility layer for the deprecated GstVideoContext API. + For GStreamer API >= 1.2, this involves the following two functions: + - gst_vaapi_video_context_prepare(): queries if a context is already + set in the pipeline ; + - gst_vaapi_video_context_propagate(): propagates the newly-created + context to the rest of the pipeline. + https://bugzilla.gnome.org/show_bug.cgi?id=703235 + Signed-off-by: Gwenole Beauchesne + +2013-05-21 12:42:39 -0400 Víctor Manuel Jáquez Leal + + * configure.ac: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapivideobuffer.c: + plugins: initial port to GStreamer 1.2. + Port vaapidecode and vaapisink plugins to GStreamer API >= 1.2. This + is rather minimalistic so that to test the basic functionality. + Disable vaapipostproc plugin for now as further polishing is needed. + Also disable GstVideoContext interface support since this API is now + gone in 1.2.x. This is preparatory work for GstContext support. + https://bugzilla.gnome.org/show_bug.cgi?id=703235 + Signed-off-by: Gwenole Beauchesne + +2013-09-24 16:21:11 +0200 Gwenole Beauchesne + + * tests/simple-decoder.c: + tests: simple-decoder: fix for non-X11 backends. + Don't try to create pixmaps if we have not requested that feature. This + fixes execution for non-X11 backends, and most specifically DRM video + output mode. + +2013-09-24 16:22:59 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit b33bd32. + b33bd32 jpeg: fix and optimize scan for next marker code + +2013-09-23 19:14:56 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: fix calculation of MCU count. + Fix calculation of MCU count for image sizes that are not a multiple + of 8 pixels in either dimension, but also for non-common sampling + factors like 4:2:2 in non-interleaved mode. + +2013-09-23 16:49:41 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + jpeg: add support for multiscan images. + Add support for images with multiple scans per frame. The Huffman table + can be updated before SOS, and thus possibly requiring multiple uploads + of Huffman tables to the VA driver. So, the latter must be able to cope + with multiple VA buffers of type 'huffman-table' and with the correct + sequential order. + +2013-09-23 11:41:52 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: improve robustness when packets are missing. + Improve robustness when some expected packets where not received yet + or that were not correctly decoded. For example, don't try to decode + a picture if there was no valid frame headers. + +2013-09-20 16:46:43 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: minor clean-ups. + Improve debugging and error messages. Rename a few variables to fit the + existing naming conventions. Change some fatal asserts to non-fatal + error codes. + +2013-09-20 10:12:08 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + jpeg: rework and optimize parser. + Split the input buffer data into decoder units that represent a JPEG + segment. Handle scan decoder unit specifically so that it can include + both the scan header (SOS) but also any other ECS or RSTi segment. + That way, we parse the input buffer stream only once at the gst-vaapi + level instead of (i) in gst_vaapi_decoder_jpeg_parse() to split the + stream into frames SOI .. EOI and (ii) in decode_buffer() to further + determine segment boundaries and decode them. + In practice, this is a +15 to +25% performance improvement. + +2013-09-17 14:29:54 +0800 Junfeng Xu + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: handle comment segments. + Fix decode_buffer() function to gracefully skip comment (COM) segments. + This fixes decoding of streams generated by certain cameras, e.g. like + the Logitech Pro C920. + https://bugzilla.gnome.org/show_bug.cgi?id=708208 + Signed-off-by: Junfeng Xu + +2013-09-18 17:59:44 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: fix determination of image bounds. + Look for the exact image bounds characterised by the and + markers. Use the gst_jpeg_parse() codec parser utility function to + optimize the lookup for the next marker segment. + https://bugzilla.gnome.org/show_bug.cgi?id=707447 + +2013-09-10 15:46:09 +0800 Junfeng Xu + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: fix calculation of offset to next marker segment. + Fix calculation of the offset to the next marker segment since the + correction of the codecparser part to match the API specification. + i.e. the GstJpegMarkerSegment.size field represents the size in bytes + of the segment minus any marker prefix. + https://bugzilla.gnome.org/show_bug.cgi?id=707447 + Signed-off-by: Junfeng Xu + +2013-09-20 18:30:18 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 23c7dde. + 23c7dde jpeg: fix calculation of segment size + +2013-08-31 16:00:05 +0200 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2013-08-31 15:47:33 +0200 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.5.6. + +2013-08-31 15:46:25 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-08-15 17:59:37 +0800 Wind Yuan + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + configure: fix detection of VA/JPEG decoding API. + Fix detection of VA/JPEG decoding API with non-standard libva packages. + More precisely, some packages were shipping with a header that + did not include . + https://bugzilla.gnome.org/show_bug.cgi?id=706055 + Signed-off-by: Gwenole Beauchesne + +2013-04-18 19:49:42 +0800 Zhao Halley + + * gst/vaapi/gstvaapisink.c: + vaapisink: ensure the uploader is setup for upstream allocated buffers. + In GStreamer 0.10 builds, make sure that the GstVaapiUploader helper + is setup in case upstream elements allocate buffers themselves without + honouring our GstVaapiSink::bufer_alloc() hook. + In particular, this fixes support for OGG video streams with WebKit. + https://bugzilla.gnome.org/show_bug.cgi?id=703934 + Signed-off-by: Gwenole Beauchesne + +2013-08-29 19:07:34 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: simplify get_render_buffer() for GStreamer 0.10 builds. + Implement and use gst_vaapisink_get_render_buffer() for GStreamer 0.10 + builds as well. + +2013-08-29 18:34:57 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: handle raw buffers not created from VA video buffer pool. + Handle raw video buffers that were not created from a VA video buffer + pool. Use the generic GstVideo API to copy buffers in GStreamer 1.0.x + builds instead of the GstVaapiUploader. + https://bugs.freedesktop.org/show_bug.cgi?id=55818 + +2013-08-29 19:33:02 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: remove extraneous size information from allowed caps. + Fix _getcaps() implementation to not report codecs with size information + filled in the returned caps. That's totally useless nowadays. Ideally, + this is a hint to insert a video parser element, thus allowing future + optimizations, but this is not a strict requirement for gstreamer-vaapi, + which is able to parse the elementary bitstreams itself. + https://bugzilla.gnome.org/show_bug.cgi?id=704734 + +2013-07-30 14:05:39 +0800 Guangxin.Xu + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: submit the last frame from output adapter to decoder. + If there is no frame delimiter at the end of the stream, e.g. no + end-of-stream or end-of-sequence marker, and that the current frame + was fully parsed correctly, then assume that last frame is complete + and submit it to the decoder. + https://bugzilla.gnome.org/show_bug.cgi?id=705123 + Signed-off-by: Guangxin.Xu + Signed-off-by: Gwenole Beauchesne + +2013-08-29 11:55:05 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: push all decoded frames from within the task. + Make sure to push all decoded frames from the task so that the unlying + VA surfaces could all be rendered from the same thread. + +2013-08-27 18:24:12 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: render the raw surface if VPP failed. + As a last resort, if video processing capabilities (VPP) are not available, + or they did not produce anything conclusive enough, then try to fallback to + the original rendering code path whereby the whole VA surface is rendered + as is, no matter of video cropping or deinterlacing requests. + Note: under those conditions, the visual outcome won't be correct but at + least, something gets displayed instead of bailing out. + +2013-08-27 18:20:08 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: add supporting for video processing. + Try to use VA/VPP processing capabilities to handle video cropping and + additional rendering flags that may not be directly supported by the + underlying hardware when exposing a suitable Wayland buffer for the + supplied VA surface. e.g. deinterlacing, different color primaries than + BT.601, etc. + +2013-08-27 16:26:22 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: add new frame redraw infrastructure. + Update the frame redraw infrastructure with a new FrameState stucture + holds all the necessary information used to display the next pending + surface. + While we are at it, delay the sync operation down to when it is actually + needed. That way, we keep performing additional tasks meanwhile. + +2013-08-27 18:06:10 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + filter: allow specification of render target regions. + Add support for rendering the source surface to a particular region within + the supplied target surface. The default background color is black. + +2013-08-26 17:14:33 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideobuffer.c: + decode: fix creation of GLX video buffers for GStreamer 0.10. + Fix creation of GstVaapiVideoBuffer objects (i) to have that type for real; + and (ii) to correctly extract the GstSurfaceConverter from the video buffer + object meta. + This fixes support for cluttersink with GStreamer 0.10 builds. + +2013-08-26 16:15:49 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: disable video cropping as picture_display_extension() is missing. + Disable video cropping in MPEG-2 codec because it is partially implemented + and actually because nobody implements it that way, and the standard spec + does not specify the display process either anyway. + Most notably, there are two possible use cases for sequence_display_extension() + horizontal_display_size & vertical_display_size: (i) guesstimating the + pixel-aspect-ratio, or (ii) implement some kind of span & scan process + in conjunction with picture_display_extension() information. + https://bugzilla.gnome.org/show_bug.cgi?id=704848 + +2013-08-16 16:58:58 +0100 Simon Farnsworth + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: allow scaling to ignore aspect ratio. + Other GStreamer sinks, like xvimagesink, have a force-aspect-ratio property, + which allows you to say that you don't want the sink to respect aspect + ratio. Add the same property to vaapisink. + http://lists.freedesktop.org/archives/libva/2012-September/001298.html + Signed-off-by: Simon Farnsworth + +2013-05-14 15:19:04 +0800 Wind Yuan + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix memory leak of GstVaapiUploader instance. + Make sure gst_vaapisink_ensure_uploader() checks for the existence + of a former GstVaapiUploader instance prior to forcibly creating a + new one. + https://bugzilla.gnome.org/show_bug.cgi?id=703980 + +2013-07-31 16:49:20 +0800 Guangxin.Xu + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix get_caps() implementation for GStreamer 1.0. + Fix GstBaseSink::get_caps() implementation for GStreamer 1.0.X builds + by honouring the filter caps argument. More precisely, this fixes the + following pipeline: gst-launch-1.0 videotestsrc ! vaapisink + https://bugzilla.gnome.org/show_bug.cgi?id=705192 + Signed-off-by: Guangxin.Xu + Signed-off-by: Gwenole Beauchesne + +2013-08-26 11:31:06 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + mpeg4: fix double definition of GstVaapiDecoderMpeg4Class. + This fixes the following issue: + CC libgstvaapi_0.10_la-gstvaapidecoder_mpeg4.lo + gstvaapidecoder_mpeg4.c:113: error: redefinition of typedef + 'GstVaapiDecoderMpeg4Class' + gstvaapidecoder_mpeg4.c:44: note: previous declaration of + 'GstVaapiDecoderMpeg4Class' was here + make[5]: *** [libgstvaapi_0.10_la-gstvaapidecoder_mpeg4.lo] Error 1 + make[5]: Leaving directory + `/builddir/build/BUILD/gstreamer-vaapi-0.5.5.1/gst-libs/gst/vaapi' + https://bugzilla.gnome.org/show_bug.cgi?id=705148 + +2013-07-30 15:59:40 +0200 Gwenole Beauchesne + + * tests/test-filter.c: + tests: filter: add support for deinterlacing. + Add --deinterlace option to enable deinterlacing through explicit VA/VPP + deinterlacing filter. However, if --deinterlace option is not set but the + --deinterlace-flags option is set with "top-field-first", then the very + basic bob deinterlacing filter is set through VA/VPP proc pipeline flags. + +2013-07-17 17:29:41 +0800 Zhao Halley + + * tests/test-filter.c: + tests: filter: add support for denoising and sharpening. + Add --denoise option to enable noise reduction with the level specified + as the option value (float). Likewise, add --sharpen option to enable + sharpening. + Signed-off-by: Gwenole Beauchesne + +2013-07-24 14:31:34 +0200 Gwenole Beauchesne + + * tests/test-filter.c: + tests: filter: add support for frame cropping. + Add support for frame cropping through the --crop-rect|-c argument. + The format used is either 'x' , with origin at (0,0) ; + or full specification with '('? ',' ')'? 'x' . + +2013-07-23 18:00:26 +0200 Gwenole Beauchesne + + * tests/test-filter.c: + tests: filter: dump supported operations and formats. + +2013-07-08 16:54:55 +0800 Zhao Halley + + * tests/Makefile.am: + * tests/test-filter.c: + tests: add initial test for video processing. + Add minimal test case for video processing: scaling and color format + conversion. + Signed-off-by: Gwenole Beauchesne + +2013-07-29 09:23:50 +0800 Zhao Halley + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + filter: add initial support for deinterlacing. + Add basic deinterlacing support, i.e. bob-deinterlacing whereby only + the selected field from the input surface is kept for the target surface. + Setting gst_vaapi_filter_set_deinterlacing() method argument to + GST_VAAPI_DEINTERLACE_METHOD_NONE means to disable deinterlacing. + Also move GstVaapiDeinterlaceMethod definition from vaapipostproc plug-in + to libgstvaapi core library. + Signed-off-by: Gwenole Beauchesne + +2013-07-17 17:40:41 +0800 Zhao Halley + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + filter: add support for color balance adjustment. + Add ProcAmp (color balance) adjustments for hue, saturation, brightness + and contrast. The respective range for each filter shall be the same as + for the VA display attributes. + Signed-off-by: Gwenole Beauchesne + +2013-07-17 17:37:16 +0800 Zhao Halley + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + filter: add support for sharpening. + Sharpening is configured with a float value. The supported range is + -1.0 .. 1.0 with 0.0 being the default, and that means no sharpening + operation at all. + Signed-off-by: Gwenole Beauchesne + +2013-07-17 17:29:41 +0800 Zhao Halley + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + filter: add support for denoising. + Noise reduction is configured with a float value. The supported range + is 0.0 .. 1.0 with 0.0 being the default, and that means no denoise + operation at all. + Signed-off-by: Gwenole Beauchesne + +2013-07-24 14:22:28 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + filter: add support for frame cropping. + Frame cropping is defined with a GstVaapiRectangle value. The default + behaviour is to treat the source surface as a whole + +2013-07-25 13:55:15 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapifilter.c: + filter: add helper functions. + Add helper functions to ensure an operation VA buffer is allocated to + the right size; that filter caps get parsed and assigned to the right + operation too; and that float parameters are correctly scaled to fit + the reported range from the VA driver. + +2013-07-23 15:52:45 +0200 Gwenole Beauchesne + + * configure.ac: + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + Add initial infrastructure for video processing. + Add initial API for video processing: only scaling and color format + conversion operations are supported. + +2013-07-24 11:53:38 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + libs: add gst_vaapi_video_format_from_string() helper. + Add gst_vaapi_video_format_from_string() helper function to convert from + a video format string representation to a suitable GstVideoFormat. This + is just an alias to gst_video_format_from_string() for GStreamer 1.0.x + builds, and a proper iteration over all GstVideoFormat string representations + otherwise for earlier GStreamer 0.10.x builds. + +2013-07-24 11:37:23 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + libs: add gst_vaapi_video_format_from_va_fourcc() helper. + Add gst_vaapi_video_format_from_va_fourcc() helper that converts from a + VA fourcc value to a suitable GstVideoFormat. + +2013-07-24 11:41:05 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + libs: add type definitions for GstVaapiPoint and GstVaapiRectangle. + Add helper functions to describe GstVaapiPoint and GstVaapiRectangle + structures as a standard GType. This could be useful to have them + described as a GValue later on. + +2013-07-26 13:57:35 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidisplaycache.h: + libs: drop some public APIs. + Don't expose GstVaapiContext APIs and make them totally private to + libgstvaapi core library. That API would also tend to disappear in + a future revision. Likewise, don't expose GstVaapiDisplayCache API + but keep symbols visible so that the various render backends could + share a common display cache implementation in libgstvaapi. + Try to clean-up the documentation from any stale entry too. + +2013-08-23 18:35:42 +0200 Gwenole Beauchesne + + * tests/image.c: + * tests/image.h: + tests: image: allow creation of images with interleaved patterns. + Add image_generate_full() function to create interleaved color rectangles. + If flags is zero, the whole frame is generated with a unique pattern. If + flags is non-zero, then each field is handled individually. + +2013-08-23 16:25:39 +0200 Gwenole Beauchesne + + * tests/image.c: + tests: image: fix conversion from RGB to YUV. + Fix RGB to YUV conversion to preserve full data range. + +2013-07-26 13:12:28 +0200 Gwenole Beauchesne + + * tests/image.c: + tests: image: try to upload images through vaDeriveImage() too. + On some platforms, vaPutImage() would fail even if it does not involve + color format conversion or scaling, whereas copying raw pixels through + vaDeriveImage() could work instead. + +2013-07-26 10:05:06 +0200 Gwenole Beauchesne + + * tests/image.c: + tests: image: add support for packed YUV formats. + Add support for packed YUV 4:2:2 formats, i.e. YUY2 and UYVY. + +2013-07-25 18:10:40 +0200 Gwenole Beauchesne + + * tests/image.c: + tests: image: fix generation of I420/YV12 images. + U/V planes were reversed, thus producing invalid images. + +2013-07-24 13:55:04 +0200 Gwenole Beauchesne + + * tests/image.c: + tests: image: fix string representation for GstVideoFormat. + +2013-07-26 12:57:19 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimage_priv.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + image: clean image API up. + Don't expose functions that reference a GstVaapiImageRaw, those are + meant to be internal only for implementing subpictures sync. Also add + a few private definitions to avoid functions calls for retrieving + image size and format information. + +2013-07-26 11:43:49 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + image: add gst_vaapi_image_copy() helper. + Add gst_vaapi_image_copy() helper function to copy images of same format + and size. + +2013-07-22 14:53:51 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideoconverter_x11.c: + plugins: handle video cropping in X11 pixmap converter. + Use GstVideoCropMeta in GStreamer 1.0 or any other render rectangle + we could decode from the stream. + +2013-07-22 11:58:33 +0200 Gwenole Beauchesne + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideoconverter_x11.c: + * gst/vaapi/gstvaapivideoconverter_x11.h: + plugins: add support for "x11-pixmap" video converter type. + Install a new video converter that supports X11 pixmap targets for X11 + backends only, or make the GLX converter creation function chain up to + the X11 converter whenever requested. + +2013-07-22 09:36:08 +0200 Gwenole Beauchesne + + * tests/simple-decoder.c: + tests: simple-decoder: add support for pixmap API. + Add support for the new render-to-pixmap API. Avoid flickering on + platforms supporting video overlay by keeping up to 2 intermediate + pixmaps. + +2013-07-22 09:12:21 +0200 Gwenole Beauchesne + + * tests/simple-decoder.c: + tests: simple-decoder: add support for video cropping. + Handle video cropping information attached to a VA surface proxy. + +2013-07-22 09:03:30 +0200 Gwenole Beauchesne + + * tests/output.c: + * tests/output.h: + * tests/test-decode.c: + tests: add support for render-to-pixmap. + Add --pixmap option to test-decode so that to allow copies of VA + surface to an intermediate pixmap and rendering from that pixmap. + Only X11 backends are supported for now. + +2013-07-22 09:00:38 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + x11: implement pixmap rendering with RENDER extension. + Use hardware accelerated XRenderComposite() function, from the RENDER + extension, to blit a pixmap to screen. Besides, this can also support + cropping and scaling. + +2013-07-19 15:05:34 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapipixmap_x11.c: + * gst-libs/gst/vaapi/gstvaapipixmap_x11.h: + x11: implement pixmap API. + Implement the new render-to-pixmap API. The only supported pixmap format + that will work is xRGB, with native byte ordering. Others might work but + they were not tested. + +2013-07-22 10:10:40 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + x11: update x11_get_geometry() helper function with depth output. + Allow x11_get_geometry() utility function to also return the depth + assigned to the X drawable. + +2013-07-22 10:00:21 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapipixmap.c: + * gst-libs/gst/vaapi/gstvaapipixmap.h: + * gst-libs/gst/vaapi/gstvaapipixmap_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + Add initial Pixmap API. + Add API to transfer VA urfaces to native pixmaps. Also add an API to + render a native pixmap, for completeness. In general, rendering to + pixmap would only be useful to certain VA drivers and use cases on + X11 display servers. e.g. GLX_EXT_texture_from_pixmap (TFP) handled + in an upper layer. + +2013-07-22 15:15:48 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + libs: add and expose gst_vaapi_video_format_to_string() helper. + This is just a wrapper over gst_video_format_to_string() for older + GStreamer 0.10 builds. + +2013-07-18 02:54:54 -0300 Emilio López + + * gst/vaapi/gstvaapipluginutil.c: + plugins: fix display type comparison in gst_vaapi_create_display(). + After the code got moved to create the gst_vaapi_create_display() helper, + this comparison was not updated to dereference the newly-created + pointer, so the code was comparing the pointer itself to the type, and + therefore failing to retrieve the VA display. + This fixes the following error (and gets gst-vaapi decoding again): + ERROR vaapidecode gstvaapidecode.c:807:gst_vaapidecode_ensure_allowed_caps: failed to retrieve VA display + https://bugzilla.gnome.org/show_bug.cgi?id=704410 + Signed-off-by: Emilio López + +2013-07-17 11:07:39 +0200 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2013-07-15 17:49:31 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: don't output dummy pictures. + Mark dummy pictures as output already so that we don't try to submit + them to the upper layer since this is purely internal / temporary + picture for helping the decoder. + +2013-07-15 17:43:34 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + decoder: dispose GstVideoCodecFrame earlier. + Once the picture was output, it is no longer necessary to keep an extra + reference to the underlying GstVideoCodecFrame. So, we can release it + earlier, and maybe subsequently release the associate surface proxy + earlier. + +2013-07-15 14:47:01 +0200 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.5.5. + +2013-07-15 14:42:33 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapiuploader.c: + * tests/image.c: + * tests/test-display.c: + Fix new video format API. + Fix new internal video format API, based on GstVideoFormat, to not + clobber with system symbols. So replace the gst_video_format_* prefix + with gst_vaapi_video_format_ prefix, even if the format type remains + GstVideoFormat. + +2013-07-15 14:05:45 +0200 Gwenole Beauchesne + + * configure.ac: + Bump library major version. + Bump the library major version due to API/ABI changes that occurred in + the imaging API. In particular, GstVaapiImageFormat type was replaced + with the standard GstVideoFormat type. All dependent APIs were updated + to match this change. + +2013-07-15 13:44:43 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-06-11 15:11:34 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + decoder: fix memory leak when processing interlaced pictures. + Fix memory leak when processing interlaced pictures and that occurs + because the first field, represented as a GstVideoCodecFrame, never + gets released. i.e. when the picture is completed, this is generally + the case when the second field is successfully decoded, we need to + propagate the GstVideoCodecFrame of the first field to the original + GstVideoDecoder so that it could reclaim memory. + Otherwise, we keep accumulating the first fields into GstVideoDecoder + private frames list until the end-of-stream is reached. The frames + are eventually released there, but too late, i.e. too much memory + may have been consumed. + https://bugzilla.gnome.org/show_bug.cgi?id=701257 + +2013-07-15 11:58:31 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + plugins: simlpify gst_vaapi_create_display() helper. + Simplify gst_vaapi_create_display() helper as gst_vaapi_display_XXX_new() + performs the necessary validation checks for the underlying VA display + prior to returning to the caller. So, if an error occurred, then NULL is + really returned in that case. + +2013-05-24 05:04:01 -0400 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: add gst_vaapi_create_display() helper. + https://bugzilla.gnome.org/show_bug.cgi?id=703235 + Signed-off-by: Gwenole Beauchesne + +2013-07-12 17:47:07 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideobufferpool.c: + plugins: don't reallocate pool allocator for the same caps. + If the video buffer pool config doesn't have new caps, then it's not + necessary to reinstantiate the allocator. That could be a costly + operation as we could do some extra heavy checking in there. + +2013-07-12 17:14:49 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + plugins: fix ref counting of GstVaapiVideoMemory allocator. + Fix reference counting issue whereby gst_memory_init() does not hold + an extra reference to the GstAllocator. So, there could be situations + where the last instance of GstVaapiVideoAllocator gets released before + a dangling GstVaapiVideoMemory object, thus possibly leading to a crash. + +2013-07-12 15:15:07 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapiuploader.c: + vaapiupload: use implicit color conversion to NV12. + Always perform conversion of sources buffers to NV12 since this is + the way we tested for this capability in ensure_allowed_caps(). This + also saves memory bandwidth for further rendering. However, this may + not preserve quality since the YUV buffers are down-sampled to 4:2:0. + +2013-07-12 15:01:01 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapivideopool.c: + pool: fix deallocation of video pools. + The queue of free objects to used was deallocated with g_queue_free_full(). + However, this convenience function shall only be used if the original queue + was allocated with g_queue_new(). This caused memory corruption, eventually + leading to a crash. + The correct solution is to pair the g_queue_init() with the corresponding + g_queue_clear(), while iterating over all free objects to deallocate them. + +2013-03-13 17:44:52 +0800 Wind Yuan + + * gst/vaapi/gstvaapidownload.c: + vaapidownload: fix src caps format error. + This fixes direct linking of vaapidownload element to xvimagesink with + VA drivers supporting vaGetImage() from the native VA surface format to + a different VA image format. i.e. color conversion during download. + http://bugzilla.gnome.org/show_bug.cgi?id=703937 + Signed-off-by: Gwenole Beauchesne + +2013-07-11 18:26:37 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidownload.c: + vaapidownload: fix debug string for image formats. + The image is now expressed as a standard GstVideoFormat, which is not + a FOURCC but rather a regular enum value. + This is a regression introduced in commit 09397fa. + +2013-04-24 10:39:03 +0800 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapiimage.c: + image: add support for raw YUY2/UYVY image copies. + Implement raw image copies for YUY2 format. Add support for UYVY format + too, with the same copy function as for YUY2. Even though components + ordering differs, copying line strides is essentially the same. + https://bugzilla.gnome.org/show_bug.cgi?id=703939 + https://bugzilla.gnome.org/show_bug.cgi?id=703940 + Signed-off-by: Gwenole Beauchesne + +2013-07-10 15:15:11 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapiuploader.c: + plugins: clean-up video uploader helper. + Fix gst_vaapi_uploader_get_buffer() to not assign caps since they + were already negotiated beforehand, and they are not used from the + buffer in upstream elements. + Clean-up gst_vaapi_uploader_ensure_caps() to use the new image caps + represented as a GstVideoInfo. + +2013-07-10 15:03:43 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapiuploader.c: + plugins: use GstVideoInfo in video uploader helper. + +2013-07-10 10:34:24 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + plugins: allow creation of VA surfaces with explicit pixel format. + Adapt GstVaapiVideoMemory allocator to support creation of VA surfaces + with an explicit pixel format. This allows for direct rendering to + VA surface memory from a software decoder. + +2013-07-10 14:20:30 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + surface: fix surface pool creation with an explicit pixel format. + Fix creation of surface pool objects to honour explicit pixel format + specification. If this operation is not supported, then fallback to + the older interface with chroma format. + +2013-07-10 13:58:55 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + surface: try to determine the underlying VA surface format. + If a VA surface was allocated with the chroma-format interface, try to + determine the underlying pixel format on gst_vaapi_surface_get_format(), + or return GST_VIDEO_FORMAT_ENCODED if this is not a supported operation. + +2013-07-09 19:08:37 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + surface: allow creation with explicit pixel format. + Make it possible to create VA surfaces with a specific pixel format. + This is a new capability brought in by VA-API >= 0.34.0. If that + capability is not built-in (e.g. using VA-API < 0.34.0), then + gst_vaapi_surface_new_with_format() will return NULL. + +2013-07-10 09:48:40 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + surface: add helper function to get chroma type from GstVideoFormat. + Add gst_video_format_get_chroma_type() helper function to determine + the GstVaapiChromaType from a standard GStreamer video format. It is + possible to reconstruct that from GstVideoFormatInfo but it is much + simpler (and faster?) to use the local GstVideoFormatMap table. + +2013-07-09 19:13:39 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + surface: add new chroma formats. + Add new chroma formats available with VA-API >= 0.34.0. In particular, + this includes "RGB" chroma formats, and more YUV subsampled formats. + Also add a new from_GstVaapiChromaType() helper function to convert + libgstvaapi chroma type to VA chroma format. + +2013-07-10 13:32:15 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + pool: fix image pool to check for the video format to use. + Make gst_vaapi_image_pool_new() succeed, and thus returning a valid + image pool object, only if the underlying VA display does support the + requested VA image format. + +2013-07-10 13:07:37 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapiuploader.c: + * tests/Makefile.am: + * tests/test-surfaces.c: + Use GstVideoInfo for video pools. + Get rid of GstCaps to create surface/image pool, and use GstVideoInfo + structures instead. Those are smaller, and allows for streamlining + libgstvaapi more. + +2013-07-09 18:03:36 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/video-format.c: + Add more video formats. + Add new video format mappings to VA image formats: + - YUV: packed YUV (YUY2, UYVY), grayscale (Y800) ; + - RGB: 32-bit RGB without alpha channel (XRGB, XBGR, RGBX, BGRX). + +2013-07-10 15:52:20 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimage.c: + image: fix debug message with video format. + Fix debug message string with image format expressed with GstVideoFormat + instead of the obsolete format that turned out to be a fourcc. + This is a regression from git commit e61c5fc. + +2013-07-09 15:28:31 +0200 Gwenole Beauchesne + + * tests/image.c: + * tests/image.h: + * tests/test-display.c: + * tests/test-textures.c: + * tests/test-windows.c: + tests: port to new video format API. + +2013-07-09 15:44:35 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapivideomemory.c: + plugins: port to new video format API. + +2013-07-09 16:26:11 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimage.c: + libs: use GstVideoInfo wherever possible. + In particular, use gst_video_info_from_caps() helper function in VA image + for implementating gst_vaapi_image_get_buffer() [vaapidownload] and + gst_vaapi_image_update_from_buffer() [subpictures] in GStreamer 0.10 builds. + +2013-07-09 16:38:05 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + libs: drop GstVaapiImageFormat helpers. + Drop GstVaapiImageFormat helpers since everything was moved to the new + GstVideoFormat based API. Don't bother with backwards compatibility and + just bump the library major version afterwards. + +2013-07-09 14:03:01 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + libs: port to new video format API. + +2013-07-09 15:29:59 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + Add new video format API. + Leverage GstVideoFormat utilities from core GStreamer to provide an + adaptation layer to VA image formats. + +2013-07-09 11:13:59 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-07-08 18:32:00 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix creation of GLX texture. + Fix creation of GLX texture, to not depend on the GstCaps video size that + could be wrong, especially in presence of frame cropping. So, use the size + from the source VA surfaces. + An optimization could be to reduce the texture size to the actual visible + size on screen. i.e. scale down the texture size to match the screen dimensions, + while preserving the VA surface aspect ratio. However, some VA drivers don't + honour that. + +2013-02-18 16:28:27 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: add support for video cropping. + If the stream has a sequence_display_extenion, then attach the + display_horizontal/display_vertical dimension as the cropping + rectangle width/height to the GstVaapiPicture. + Signed-off-by: Gwenole Beauchesne + +2013-02-18 15:05:37 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: add support for video cropping. + If the Advanced profile has display_extension fields, then set the display + width/height dimension as cropping rectangle to the GstVaapiPicture. + Signed-off-by: Gwenole Beauchesne + +2013-02-15 18:50:26 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: add support for video cropping. + If the encoded stream has the frame_cropping_flag set, then associate + the cropping rectangle to GstVaapiPicture. + Signed-off-by: Gwenole Beauchesne + +2013-07-08 17:01:21 +0200 Gwenole Beauchesne + + * tests/decoder.c: + * tests/decoder.h: + * tests/test-decode.c: + * tests/test-subpicture.c: + tests: add basic support for video cropping. + Change generic decoder of sample I-frame to return a GstVaapiSurfaceProxy + instead of a plain GstVaapiSurface. This means that we can now retrieve + the frame cropping rectangle from the surface proxy, along with additional + information if ever needed. + +2013-07-08 14:50:42 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapivideometa.c: + plugins: add support for video cropping. + Add support for GstVideoCropMeta in GStreamer >= 1.0.x builds and gst-vaapi + specific meta information to hold video cropping details. Make the sink + support video cropping in X11 and GLX modes. + +2013-02-15 18:24:24 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa.h: + plugins: add helper functions to set the render rectangle. + Some video clips may have a clipping region that needs to propogate to + the renderer. These helper functions make it possible to attach that + clipping region, as a GstVaapiRectangle, the the video meta associated + with the buffer. + Signed-off-by: Sreerenj Balachandran + signed-off-by: Gwenole Beauchesne + +2013-07-08 14:47:24 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + surfaceproxy: allow for NULL cropping rectangle. + Make it possible associate an empty cropping rectangle to the surface + proxy, thus resetting any cropping rectangle that was previously set. + This allows for returning plain NULL when no cropping rectangle was + initially set up to the surface proxy, or if it was reset to defaults. + +2013-07-08 11:41:59 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + surfaceproxy: clean-up helper macros. + Always use the GST_VAAPI_SURFACE_PROXY() helper macro to cast from a + proxy macro argument to a GstVaapiSurfaceProxy pointer. + +2013-07-08 11:43:27 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + surface: add simple surface info accessors as helper macros. + Add helper macros to retrieve the VA surface information like size + (width, height) or chroma type. This is a micro-optimization to avoid + useless function calls and NULL pointer re-checks in internal routines. + +2013-02-15 18:42:12 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + decoder: add support for video cropping. + Add gst_vaapi_picture_set_crop_rect() helper function to copy the video + cropping information from raw bitstreams to each picture being decoded. + Also add helper function to surface proxy to propagate that information + outside of libgstvaapi. e.g. plug-in elements or standalone applications. + Signed-off-by: Sreerenj Balachandran + Signed-off-by: Gwenole Beauchesne + +2013-07-08 17:30:30 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit f90de0a. + f90de0a h264: fix calculation of the frame cropping rectangle + 535515c h264: parse the cropping rectangle separately + +2013-07-05 19:03:41 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 0f68a71. + 0f68a71 mpeg2: fix video packet header size checks + +2013-06-07 20:08:43 +0800 Zhong Cong + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: reset quantization matrices on new sequence headers. + The MPEG-2 standard specifies (6.3.7) that all quantisation matrices + shall be reset to their default values when a Sequence_Header() is + decoded. + Signed-off-by: Gwenole Beauchesne + +2013-07-05 15:49:34 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: cope with latest codecparser changes. + Fix build with newer MPEG-2 codecparser where GstMpegVideoPacket are + used in individual header parsers. Also use the new slice parsing API. + +2013-07-05 17:51:26 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit dddd182. + dddd182 mpeg2: add slice header parsing API + 94e6228 mpeg2: add sequence scalable extension parsing API + 531134f mpeg2: add new API that takes GstMpegVideoPacket arguments + 4b135d3 h264: fix the return value type for the SEI palyload parsing methods + +2013-06-27 12:25:44 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapisink.c: + vaapisink: expose the raw video formats in static caps template. + Expose all raw video formats in the static caps template since the + vaapisink is supporting raw data. We will get the exact set of formats + supported by the driver dynamically through the _get_caps() routine. + This also fixes an inconsistency wrt. GStreamer 0.10 builds. + https://bugzilla.gnome.org/show_bug.cgi?id=702178 + Signed-off-by: Gwenole Beauchesne + +2013-06-27 13:53:46 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: add "use-glx" property for OpenGL rendering. + Now that VA/GLX capable buffers are generated by default on X11, thus + depending on a VA/GLX display, we stil want to use vaPutSurface() for + rendering since it is faster. + Anyway, OpenGL rendering in vaapisink was only meant for testing and + enabling "fancy" effects to play with. This has no real value. So, + disable OpenGL rendering by default. + +2013-06-06 05:36:03 -0400 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: try to allocate a GLX display first over an X11 one. + If the gstreamer-vaapi plug-in elements are built with GLX support, then + try to allocate a GstVaapiDisplayGLX first before resorting to a VA/X11 + display next. + https://bugzilla.gnome.org/show_bug.cgi?id=701742 + +2013-04-25 17:07:13 +0100 Lionel Landwerlin + + * configure.ac: + configure: use GST_PLUGIN_PATH_1_0 instead of GST_PLUGIN_PATH for Gst 1.0. + jhbuild sets $GST_PLUGIN_PATH_1_0 which overrides $GST_PLUGIN_PATH. + https://bugzilla.gnome.org/show_bug.cgi?id=698858 + Signed-off-by: Gwenole Beauchesne + +2013-04-27 15:15:49 +0800 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapiimage.c: + image: fix wrong check for rect bounds in copy_image(). + +2013-06-14 13:41:14 +0200 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2013-06-14 11:47:50 +0200 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.5.4. + +2013-06-14 11:43:46 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-06-14 11:39:54 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/codecparsers/Makefile.am: + configure: always build the MPEG-4 parser. + Always build the MPEG-4 parser for now as there are also core fixes + included in the parser that cannot be tested for with API checks. + +2013-06-14 11:32:36 +0200 Gwenole Beauchesne + + * configure.ac: + configure: add --enable-builtin-codecparsers [default="yes"] option. + Add flag to have all codecparsers built-in, thus ensuring that the + resulting binaries have all the necessary bug fixes and this is what + the QA has been testing anyway. + Of course, for a completely up-to-date Linux distribution, you could + also opt for --disable-builtin-codecparsers and use the system ones. + Though, some core fixes could be missing, and those cannot be tested + for with API checks. + +2013-06-14 11:14:23 +0200 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 843ce3e. + 843ce3e jpeg: fix default Huffman tables generation. + 8655187 mpeg2: fix the pixel-aspect-ratio calculation + 21099dc mpeg2: actually store video bitrate values + dd02087 mpeg2: fix picture packet extension size check + 25948e9 mpeg2: increase min size for picture coding ext + f1f5a40 ensure the debug category is properly initialized + +2013-06-12 14:16:17 +0100 Gwenole Beauchesne + + * debian.upstream/Makefile.am: + debian: fix list of generated files for .deb packaging. + +2013-06-12 13:48:26 +0100 Gwenole Beauchesne + + * configure.ac: + * debian.upstream/Makefile.am: + * debian.upstream/control.in: + debian: fix libgstvaapi -dev package name. + Fix libgstvaapi -dev package name so that to allow installation of both + GStreamer 0.10 and 1.0.x based packages. + +2013-06-05 17:42:00 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-05-31 11:09:40 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + wayland: fix memory leak of display resources. + +2013-06-04 07:14:22 +0800 Zhao Halley + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix build without VA/GLX support. + +2013-06-05 11:01:51 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: allow buffer mappings to GstVaapiSurfaceProxy. + Allow plain gst_buffer_map() interface to work with gstreamer-vaapi + video buffers, i.e. expose the underlying GstVaapiSurfaceProxy to the + caller. This is the only sensible enough thing to do in this mode as + the underlying surface pixels need to be extracted through an explicit + call to the gst_video_frame_map() function instead. + A possible use-case of this is to implement a "handoff" signal handler + to fakesink or identity element for further processing. + +2013-06-03 10:22:44 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + plugins: silence check for direct-rendering mode in video memory. + Fix gst_vaapi_video_allocator_new() to silently check for direct-rendering + mode support, and not trigger fatal-criticals if either test surface or + image could not be created. Typical case: pixel format mismatch, e.g. NV12 + supported by most hardware vs. I420 supported by most software decoders. + +2013-06-03 10:06:29 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + plugins: improve video memory flags safety checks. + On map, ensure we have GST_MAP_WRITE flags since this is only what we + support for now. Likewise, on unmap, make sure that the VA image is + unmapped for either read or write, while still committing it to the + VA surface if write was requested. + +2013-05-30 18:17:07 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + surface: fix memory leak through unreleased parent context. + Break the circular references between GstVaapiContext and its children + GstVaapiSurfaces. Since the VA surfaces held an extra reference to the + context, which holds a reference to its VA surfaces, then none of those + were released. + How does this impact support for subpictures? + The only situation when the parent context needs to disappear is when + it is replaced with another one because of a resolution change in the + video stream for instance, or a normal destroy. In this case, it does + not really matter to apply subpictures to the peer surfaces since they + are either gone, or those that are left in the pipe can probably bear + a reinstantiation of the subpictures for it. + So, parent_context is set to NULL when the parent context is destroyed, + other VA surfaces can still get subpictures attached to them, individually + not as a whole. i.e. subpictures for surface S1 will be created from + active composition buffers and associated to S1, subpictures for S2 will + be created from the next active composition buffers, etc. We don't try + to cache the subpictures in those cases (pending surfaces until EOS + is reached, or pending surfaces until new surfaces matching new VA context + get to be used instead). + +2013-05-27 14:01:48 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix one-time initialization when display property is set. + Fix gst_vaapisink_ensure_display() to perform one-time initialization + tasks even if the `display' property was explicitly set. + +2013-05-27 15:59:08 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + window: fix GLX window initialization. + Make sure to create the GLX context once the window object has completed + its creation. Since gl_resize() relies on the newly created window size, + then we cannot simply overload the GstVaapiWindowClass::create() hook. + So, we just call into gst_vaapi_window_glx_ensure_context() once the + window object is created in the gst_vaapi_window_glx_new*() functions. + +2013-05-27 17:18:40 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + display: validate display types. + +2013-05-27 16:13:33 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + display: drop internal NAME_PREFIX, store the real display name. + Always store a valid display name/device path, instead of adding a + particular prefix. i.e. make it simply a strdup(), or "" if it was + initially NULL. + +2013-05-27 13:17:31 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.h: + display: make it possible to lookup the display cache by type. + Make it possible to add extra an extra filter to most of display cache + lookup functions so that the GstVaapiDisplay instance can really match + a compatible and existing display by type, instead of relying on extra + string tags (e.g. "X11:" prefix, etc.). + +2013-05-24 16:19:23 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + display: cope with new display cache API. + +2013-05-24 16:12:01 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.h: + display: rework display cache API. + Simplify display cache API, while making it more flexible. We can now create + custom lookup functions with gst_vaapi_display_cache_lookup_custom(). + +2013-05-24 15:05:45 +0200 Gwenole Beauchesne + + * tests/test-display.c: + tests: improve check for display cache. + Improve check for display cache infrastructure. In particular, for X11 and + GLX backends, we need to make sure that we can create a GstVaapiDisplayX11 + from another GstVaapiDisplayGLX, i.e. underlying X11 and VA displays can be + shared. Besides, allocating a GstVaapiDisplayGLX while a GstVaapiDisplayX11 + already exists will have to generate different VA displays. + +2013-05-15 10:33:16 +0800 Zhao Halley + + * gst/vaapi/gstvaapiuploader.c: + uploader: fix memory leak in GStreamer 0.10 builds. + In GStreamer 0.10 builds, gst_vaapi_uploader_get_buffer() was used + but it exhibited a memory leak because the surface generated for the + GstVaapiVideoMeta totally lost its parent video pool. So, it was not + possible to release that surface back to the parent pool when the meta + gets released, and the memory consumption kept growing. + Signed-off-by: Gwenole Beauchesne + +2013-05-23 18:56:43 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideometa.c: + plugins: fix gst_vaapi_video_meta_new_from_pool(). + Since GST_VAAPI_IS_xxx_VIDEO_POOL() was only testing for NULL and not + the underlying object type, the gst_vaapi_video_meta_new_from_pool() + was hereby totally broken. Fixed this regression by using the newly + provided gst_vaapi_video_pool_get_object_type() function. + +2013-05-23 18:22:50 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideometa.c: + plugins: cope with GST_VAAPI_IS_xxx() macros removal. + +2013-05-23 18:19:24 +0200 Gwenole Beauchesne + + * tests/decoder.c: + tests: cope with GST_VAAPI_IS_xxx() macros removal. + +2013-05-23 18:45:23 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapivideopool_priv.h: + libs: add query for GstVaapiVideoPool object types. + Add API to identify the underlying GstVaapiVideoPool object type. + +2013-05-23 18:15:48 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + libs: drop GST_VAAPI_IS_xxx() helper macros. + Drop obsolete GST_VAAPI_IS_xxx() helper macros since we are no longer + deriving from GObject and so those were only checking for whether the + argument was NULL or not. This is now irrelevant, and even confusing + to some extent, because we no longer have type checking. + Note: this incurs more type checking (review) but the libgstvaapi is + rather small, so this is manageable. + +2013-05-07 18:52:28 +0200 Gwenole Beauchesne + + * configure.ac: + Bump library major version. + The whole libgstvaapi libraries got a major refresh to get rid of GObject. + This is a fundamental change that requires a new SONAME. More changes are + underway to streamline the core libraries. + So far, the net result is a reduction of .text size (code) by 32KB, i.e. -10%. + On one particular test (sintel HD trailer), the total number of executed + instruction was reduced by 8%. + +2013-05-07 18:37:24 +0200 Gwenole Beauchesne + + * docs/reference/libs/Makefile.am: + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * docs/reference/libs/libs.core.types: + * docs/reference/libs/libs.glx.types: + * docs/reference/libs/libs.x11.types: + docs: cope with removed APIs. + Some APIs are dead because they are no longer based on GObject. + +2013-05-06 14:43:38 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideometa.c: + plugins: cope with new GstVaapiMiniObject objects. + +2013-05-07 11:45:10 +0200 Gwenole Beauchesne + + * tests/decoder.c: + * tests/image.c: + * tests/output.c: + * tests/simple-decoder.c: + * tests/test-decode.c: + * tests/test-display.c: + * tests/test-subpicture.c: + * tests/test-surfaces.c: + * tests/test-textures.c: + * tests/test-windows.c: + tests: cope with new GstVaapiMiniObject objects. + +2013-05-07 15:38:51 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + display: fix set_synchronous() to lock display. + +2013-05-03 19:02:23 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + videopool: simplify creation of video objects pool. + +2013-05-07 18:17:10 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapitypes.h: + libs: simplify GstVaapiID definitions. + Make GstVaapiID a gsize instead of guessing an underlying integer large + enough to hold all bits of a pointer. Also drop GST_VAAPI_ID_NONE since + this is plain zero and that it is no longer passed as varargs. + +2013-05-02 16:11:53 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapi_priv.h: + * gst-libs/gst/vaapi/gstvaapiparamspecs.c: + * gst-libs/gst/vaapi/gstvaapiparamspecs.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + libs: drop obsolete function helpers and objects. + Drop obsolete GstVaapiID related function helpers for passing them as + GValues. + +2013-05-07 11:39:34 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + libs: use GstVaapiMiniObject for display objects. + +2013-05-06 14:07:17 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.h: + libs: use GstVaapiMiniObject for video decoders. + Port GstVaapiDecoder and GstVaapiDecoder{MPEG2,MPEG4,JPEG,H264,VC1} to + GstVaapiMiniObject. Add gst_vaapi_decoder_set_codec_state_changed_func() + helper function to let the user add a callback to a function triggered + whenever the codec state (e.g. caps) changes. + +2013-05-03 11:01:12 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapivideopool_priv.h: + libs: use GstVaapiMiniObject for video object pools. + Port GstVaapiVideoPool, GstVaapiSurfacePool and GstVaapiImagePool to + GstVaapiMiniObject. Drop gst_vaapi_video_pool_get_caps() since it was + no longer used for a long time. Make object allocators static, i.e. + local to the shared library. + +2013-04-30 17:22:00 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + libs: use GstVaapiObject for texture objects. + +2013-04-30 17:20:14 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.c: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + libs: use GstVaapiObject for window objects. + +2013-04-30 17:22:15 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + libs: use GstVaapiObject for VA objects. + +2013-04-30 17:20:46 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + Port GstVaapiObject to GstVaapiMiniObject. + +2013-04-30 10:28:30 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiminiobject.c: + * gst-libs/gst/vaapi/gstvaapiminiobject.h: + libs: refine GstVaapiMiniObject. + Drop support for user-defined data since this capability was not used + so far and GstVaapiMiniObject represents the smallest reference counted + object type. Add missing GST_VAAPI_MINI_OBJECT_CLASS() helper macro. + Besides, since GstVaapiMiniObject is a libgstvaapi internal object, it + is also possible to further simplify the layout of the object. i.e. merge + GstVaapiMiniObjectBase into GstVaapiMiniObject. + +2013-05-07 16:43:51 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: update picture size from the bitstream. + Propagate the picture size from the bitstream to the GstVaapiDecoder, + and subsequent user who installed a signal on notify::caps. This fixes + decoding of TS streams when the demuxer failed to extract the required + information. + +2013-04-25 14:16:01 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: fix raw decoding mode. + Fix gst_vaapi_decoder_get_surface() to actually transfer ownership of the + surface proxy to the caller. + +2013-04-25 13:56:18 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst/vaapi/gstvaapidecode.c: + decoder: add gst_vaapi_decoder_get_frame_with_timeout(). + Add gst_vaapi_decoder_get_frame_with_timeout() helper function that will + wait for a frame to be decoded, until the specified timeout in microseconds, + prior to returning to the caller. + This is a fix to performance regression from 851cc0, whereby the vaapidecode + loop executed on the srcpad task was called to often, thus starving all CPU + resources. + +2013-04-19 14:38:59 +0200 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2013-04-18 19:09:45 +0200 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.5.3. + +2013-04-18 19:08:39 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-04-18 15:55:26 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: rework heuristics to detect decode timeout. + Rework heuristics to detect when downstream element ran into errors, + and thus failing to release any VA surface in due time for the current + frame to get decoded. In particular, recalibrate the render time base + when the first frame gets submitted downstream, or when there is no + timestamp that could be inferred. + +2013-04-18 15:50:02 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstcompat.h: + * gst/vaapi/gstvaapidecode.c: + vaapidecode: rework GstVideoDecoder::handle_frame() with a task. + Rework GstVideoDecoder::handle_frame() to decode the current frame, + while possibly waiting for a free surface, and separately submit all + decoded frames from a task. This makes it possible to pop and render + decoded frames as soon as possible. + +2013-04-18 10:06:15 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: use gst_object_unref() wherever applicable. + Use gst_object_unref() wherever applicable, e.g. objects derived from + GstElement, GstVideoPool, etc. + +2013-04-17 14:21:16 +0200 Gwenole Beauchesne + + * docs/reference/plugins/plugins-docs.xml.in: + * docs/reference/plugins/plugins-sections.txt: + * docs/reference/plugins/plugins.types: + docs: drop obsolete plug-ins. + Drop documentation for obsolete plug-ins, even for GStreamer 0.10. + i.e. vaapiupload and vaapidownload are no longer the recommended + plug-ins to use. + +2013-04-17 13:17:26 +0200 Gwenole Beauchesne + + * debian.upstream/rules: + debian: fix build of GStreamer 0.10 packages. + Fix build of Debian packages to scan the actual GStreamer API version + from the generated changelog file. + +2013-04-17 10:58:04 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: minor clean-ups. + Use g_clear_object() wherever appropriate and remove dead-code. + +2013-04-17 10:53:03 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix reference counting buf for passthrough mode. + Fix reference counting bug for passthrough mode, whereby the input buffer + was propagated as is downstream through gst_pad_push() without increasing + its reference count before. The was a problem when gst_pad_push() returns + an error and we further decrease the reference count of the input buffer. + +2013-04-17 10:18:45 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstcompat.h: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: port to GStreamer 1.0. + Add support for interlaced streams with GStreamer 1.0 too. Basically, + this enables vaapipostproc, though it is not auto-plugged yet. We also + make sure to reply to CAPS queries, and happily handle CAPS events. + +2013-04-17 10:14:55 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: fix GstVideoCodecFrame flags for interlaced contents. + Fix support for interlaced contents with GStreamer 0.10. In particular, + propagate GstVaapiSurfaceProxy frame flags to GstVideoCodecFrame flags + correctly. + This is a regression from commit 87e5717. + +2013-04-16 13:23:41 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.c: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapiparser_frame.c: + * gst-libs/gst/vaapi/gstvaapiparser_frame.h: + decoder: rename GstVaapiDecoderFrame to GstVaapiParserFrame. + Rename GstVaapiDecoderFrame to GstVaapiParserFrame because this data + structure was only useful to parsing and a proper GstvaapiDecoderFrame + instance will be created instead. + +2013-04-16 19:09:30 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: export presentation timestamp for raw decoding mode. + Fix regression from 0.4-branch whereby GstVaapiSurfaceProxy no longer + held any information about the expected presentation timestamp, frame + duration or additional flags like interlaced or top-field-first. + +2013-04-16 18:56:24 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + decoder: use new GstVaapiSurfaceProxy utility functions. + Use new GstVaapiSurfaceProxy internal helper functions to propagate the + necessary GstVideoCodecFrame flags to vaapidecode (GStreamer 0.10). + Also make GstVaapiDecoder push_frame() operate similarly to drop_frame(). + i.e. increase the GstVideoCodecFrame reference count in push_frame rather + than gst_vaapi_picture_output(). + +2013-04-16 18:35:48 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + surfaceproxy: add more attributes for raw decoding modes. + Add more attributes for raw decoding modes, i.e. directly through the + libgstvaapi helper library. In particular, add presentation timestamp, + duration and a couple of flags (interlaced, TFF, RFF, one-field). + +2013-04-16 13:48:00 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst/vaapi/gstvaapidecode.c: + * tests/simple-decoder.c: + surfaceproxy: drop user-data support from GstVaapiSurfaceProxy. + Drop user-data support from GstVaapiSurfaceProxy. Rather make it explicit + to call some user-provided function when the surface proxy is released. + +2013-04-15 12:52:51 +0400 Víctor Manuel Jáquez Leal + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + build: link libgstvaapi-glx-1.0.so against libdl. + Ensure libgstvaapi-glx*.so builds against libdl since dlsym() is used + to resolve glXGetProcAddress() from GLX libraries. This fix builds on + Fedora 17. + https://bugzilla.gnome.org/show_bug.cgi?id=698046 + Signed-off-by: Gwenole Beauchesne + +2013-04-15 14:22:57 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: fix gst_vaapi_decoder_get_codec_state(). + Fix previous commit whereby gst_vaapi_decoder_get_codec_state() was + supposed to make GstVaapiDecoder own the return GstVideoCodecState + object. Only comment was updated, not the actual code. + +2013-04-15 13:58:58 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst/vaapi/gstvaapidecode.c: + decoder: make gst_vaapi_decoder_get_codec_state() return the original state. + Make gst_vaapi_decoder_get_codec_state() return the original codec state, + i.e. make the GstVaapiDecoder object own the return state so that callers + that want an extra reference to it would just gst_video_codec_state_ref() + it before usage. This aligns the behaviour with what we had before with + gst_vaapi_decoder_get_caps(). + This is an ABI incompatible change, library major version was bumped from + previous release (0.5.2). + +2013-04-15 13:52:19 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideobufferpool.h: + * gst/vaapi/gstvaapivideoconverter_glx.h: + plugins: mark a few more functions as internal. + Mark the following functions are internal, i.e. private to the vaapi plug-in: + - gst_vaapi_video_buffer_pool_get_type() + - gst_vaapi_video_converter_glx_get_type() + - gst_vaapi_video_converter_glx_new() + +2013-04-15 13:48:43 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideobuffer.c: + plugins: implement GstSurfaceMeta API. + Implement GstSurfaceMeta API for GStreamer 1.0.x. Even though this is + an unstable/deprecated API, this makes it possible to support Clutter + sink with minimal changes. Tested against clutter-gst 1.9.92. + +2013-04-12 17:12:43 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: optimize GstVideoOverlayInterface::expose(). + When render-mode is "overlay", then it is not really useful to peek into + the GstBaseSink::last_buffer, since we have our own video_buffer already + recorded and maintained into GstVaapiSink. + +2013-04-12 17:05:06 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix memory leak of GstSample objects. + Fix memory leak of GstSample objects in GstVideoOverlayInterface::expose(). + This also fixes extra unreferencing of the underlying GstBuffer in the common + path afterwards (for both 0.10 or 1.0). + +2013-04-12 13:44:52 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstcompat.h: + * gst/vaapi/gstvaapi.c: + plugins: fix description for gst-inspect. + Fix the name of the plug-in element reported to gst-inspect-1.0. i.e. we + need an explicit definition for GStreamer >= 1.0 because the GST_PLUGIN_DEFINE + incorrectly uses #name for creating the plug-in name, instead of using macro + expansion (and let further expansion of macros) through e.g. G_STRINGIFY(). + +2013-04-11 09:24:44 +0200 Gwenole Beauchesne + + * README: + README: updates. + Update build requirements for GStreamer 1.0.x support. Add section for + ways to report bugs. + +2013-04-10 16:54:01 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-04-10 15:31:41 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst/vaapi/Makefile.am: + Fix make dist to include all source files, in any case. + Fix make dist to allow build for either GStreamer 0.10 or 1.0. i.e. make + sure to include all source files in either case while generating source + tarballs. + +2013-04-10 15:21:57 +0200 Gwenole Beauchesne + + * configure.ac: + Bump library major version. + Bump library major version, while preserving a major version of 0 for + GStreamer 1.0 based libraries, and a major version of 2 for GStreamer + 0.10 based librarieS. + +2013-04-10 14:37:42 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: implement direct-rendering mode for raw YUV buffer uploads. + Allow direct-rendering (writes) into target VA surfaces. + +2013-04-09 16:02:06 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: implement uploads from raw YUV buffers for GStreamer 1.0. + Implement GstVideoMeta::{,un}map() to support raw YUV buffer upload when + the last component is unmapped. Downloads are not supported yet. The aim + was to first support SW decoding + HW accelerated rendering (vaapisink). + e.g. for Wayland. + +2013-04-03 11:10:41 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: submit all decoded frames before decoding a new one. + Make sure to purge all pending frames that were already decoded prior + to decoding a new one. This helps release VA surfaces as early as + possible. + +2013-04-02 16:12:16 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: reply to CAPS queries. + Handle GST_QUERY_CAPS, which is the GStreamer 1.0 mechanism to retrieve + the set of allowed caps, i.e. it works similar to GstPad::get_caps(). + This fixes fallback to SW decoding if no HW decoder is available. + +2013-03-20 11:26:38 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: fix unpaired GstBuffer map/unmaps. + This possibly fixes a few memory leaks along the way. + +2013-03-20 14:40:57 +0100 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/gstcompat.h: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + * gst/vaapi/gstvaapiuploader.c: + * tests/codec.c: + Allow build against either GStreamer API (0.10 or 1.0). + Introduce a new configure option --with-gstreamer-api that determines + the desired GStreamer API to use. By default, GStreamer 1.0 is selected. + Also integrate more compatibility glue into gstcompat.h and plugins. + +2012-11-08 16:41:22 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + plugins: use new video buffer pools. + Use new GstVaapiVideoBufferPool to maintain video buffers. Implement + GstBaseSink::propose_allocation() to expose that pool to upstream + elements; and also implement GstVideoDecoder::decide_allocation() to + actually use that pool (from downstream), if any, or create one. + Signed-off-by: Gwenole Beauchesne + +2012-11-08 16:41:22 +0200 Sreerenj Balachandran + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideobufferpool.h: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: add GstVaapiVideoMemory and GstVaapiVideoBufferPool objects. + Add initial support for GstVaapiVideoMemory backed buffer pool. The memory + object currently holds a reference to GstVaapiVideoMeta. + Signed-off-by: Gwenole Beauchesne + +2013-04-04 17:36:45 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa.h: + plugins: allow copies of GstVaapiVideoMeta objects. + Make it possible to copy GstVaapiVideoMeta objects, unless they contain VA + objects created from GstVaapiVideoPool. This is mostly useful to clone a + GstVaapiVideoMeta object containing a VA surface proxy so that to alter its + rendering flags. + +2013-04-04 16:16:31 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideometa.c: + plugins: make it possible to clear VA objects from GstVaapiVideoMeta. + Fix GstVaapiVideoMeta to allow VA objects to be destroyed when they are + reset to NULL. i.e. make gst_vaapi_video_meta_set_{image,surface}() and + gst_vaapi_video_meta_set_surface_proxy() actually clear VA objects when + argument is NULL. + +2012-09-03 14:00:25 +0300 Sreerenj Balachandran + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa.h: + plugins: initial port to GStreamer 1.0. + Port vaapidecode and vaapisink plugins to GStreamer API >= 1.0. This + is rather minimalistic so that to test the basic functionality. + Disable vaapiupload, vaapidownload and vaapipostproc plugins. The latter + needs polishing wrt. to GStreamer 1.x functionality and the former are + totally phased out in favor of GstVaapiVideoMemory map/unmap facilities, + which are yet to be implemented. + Signed-off-by: Gwenole Beauchesne + +2013-03-21 10:12:09 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstcompat.h: + * tests/codec.c: + * tests/decoder.c: + * tests/simple-decoder.c: + * tests/test-subpicture.c: + tests: add support for GStreamer 1.0. + +2012-09-04 15:12:18 +0300 Sreerenj Balachandran + + * configure.ac: + * gst-libs/gst/vaapi/gstcompat.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + Add initial support for GStreamer 1.0. + This integrates support for GStreamer API >= 1.0 only in the libgstvaapi + core decoding library. The changes are kept rather minimal here so that + the library retains as little dependency as possible on core GStreamer + functionality. + Signed-off-by: Gwenole Beauchesne + +2013-04-03 15:58:57 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: improve check for raw YUV format mode. + Improve check for raw YUV format modes by avoiding checks against strings + ("video/x-raw-yuv") for each new GstBuffer allocation. In the usual case, + GstBaseSink::set_caps() is called first and if VA surface format mode is + used, then GstBaseSink::buffer_alloc() is not called. If the latter is + called before set_caps(), then we just make a full check. This one is + pretty rare though, e.g. it usually happens once for custom pipelines. + +2013-04-03 15:06:46 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + plugins: don't fail if there is no overlay composition to apply. + Fix gst_vaapi_apply_composition() to not fail if no overlay composition + was found. i.e. return success (TRUE). This was harmless though extra + debug messages are not nice. + This is a regression introduced by commit 95b8659. + +2013-04-03 14:59:33 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: expose the exact set of supported HW decoders. + Don't return static caps that don't mean anything for the underlying codecs + that are actually supported for decoding. i.e. always allocate a VA display + and retrieve the exact set of HW decoders available. That VA display may be + re-used later on during negotiation through GstVideoContext "prepare-context". + This fixes fallback to SW decoding if no HW decoder is available. + +2013-04-03 13:08:55 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + decoder: drop obsolete functions. + Drop the following functions that are now obsolete: + - gst_vaapi_context_get_surface() + - gst_vaapi_context_put_surface() + - gst_vaapi_context_find_surface_by_id() + - gst_vaapi_surface_proxy_new() + - gst_vaapi_surface_proxy_get_context() + - gst_vaapi_surface_proxy_set_context() + - gst_vaapi_surface_proxy_set_surface() + This is an API change. + +2013-04-03 13:14:59 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: delegate surface size check to VA context reset. + Now that the surface pool is reference counted in the surface proxy wrapper, + we can safely ignore surface size checks in gst_vaapi_decoder_ensure_context(). + Besides, this check is already performed in gst_vaapi_context_reset_full(). + +2013-04-03 11:37:44 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + decoder: simplify acquisition/release of spare surface. + Introduce gst_vaapi_surface_proxy_new_from_pool() to allocate a new surface + proxy from the context surface pool. This change also makes sure to retain + the parent surface pool in the proxy. + Besides, it was also totally useless to attach/detach parent context to + VA surface each time we acquire/release it. Since the whole context owns + all associated VA surfaces, we can mark this as such only once and for all. + +2013-03-29 10:39:37 +0100 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2013-03-28 10:18:51 +0100 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.5.2. + +2013-03-28 10:15:53 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-03-26 18:57:00 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapisink.c: + plugins: fix usage of gst_vaapi_reply_to_query(). + Make gst_vaapi_reply_to_query() first check whether the query argument + is actually a video-context query, i.e. with type GST_QUERY_TYPE_CUSTOM. + Then, make sure vaapisink propagates the query to the parent class if + it is not a video-context query. + +2013-03-26 18:45:53 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideobuffer.h: + plugins: streamline video buffers. + Add new gst_vaapi_video_buffer_new() helper function that allocates a video + buffer from a GstVaapiVideoMeta. Also remove obsolete and useless function + gst_vaapi_video_buffer_get_meta(). + +2013-03-26 10:31:10 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapivideometa.c: + * gst-libs/gst/vaapi/gstvaapivideometa.h: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapivideobuffer.h: + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa.h: + plugins: integrate GstVaapiVideoMeta from libgstvaapi. + Move GstVaapiVideoMeta from core libgstvaapi decoding library to the + actual plugin elements. That's only useful there. Also inline reference + counting code from GstVaapiMiniObject. + +2013-03-21 17:17:53 +0100 Gwenole Beauchesne + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipluginbuffer.c: + * gst/vaapi/gstvaapipluginbuffer.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideobuffer.h: + plugins: drop gstvaapipluginbuffer.[ch] helper files. + Move all gst_vaapi_video_buffer_new*() helpers from gstvaapipluginbuffer.[ch] + to gstvaapivideobuffer.[ch], and drop the obsolete files. + +2013-03-21 17:06:43 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * docs/reference/libs/libs.core.types: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidownload.h: + * gst/vaapi/gstvaapipluginbuffer.c: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideobuffer.h: + * gst/vaapi/gstvaapivideoconverter_glx.h: + plugins: integrate GstVaapiVideoBuffer from libgstvaapi. + Move GstVaapiVideoBuffer from core libgstvaapi decoding library to the + actual plugin elements. That's only useful there. + +2013-03-21 16:32:43 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapivideoconverter_glx.c: + plugins: use common helper function to apply compositions. + Use common gst_vaapi_apply_composition() helper function to apply compositions + attached to a buffer in vaapisink or GstVaapiVideoConverterGLX. + +2013-03-21 16:09:42 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapipluginbuffer.c: + * gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapivideoconverter_glx.h: + plugins: integrate GstVaapiVideoConverterGLX from libgstvaapi. + Make sure libgstvaapi core decoding library doesn't include un-needed + dependencies. So, move out GstVaapiVideoConverterGLX to plugins instead. + Besides, even if the vaapisink element is not used, we are bound to have + a correctly populated GstSurfaceBuffer from vaapidecode. + Also clean-up the file along the way. + +2013-03-21 13:32:15 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: fix use of possibly uninitialized variable. + In decode_codec_data(), force initialization of format to zero so that + we can catch up cases where codec-data has neither "format" nor "wmvversion" + fields, thus making it possible to gracefully fail in this case. + +2013-03-21 13:43:46 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: propagate buffer data as a const guchar * pointer (cosmetics). + +2013-03-21 14:36:40 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: sanitize codec-data decoding. + Add a new GstVaapiDecoder::decode_codec_data() hook to actually decode + codec-data in the decoder sub-class. Provide a common shared helper + function to do the actual work and delegating further to the sub-class. + +2013-03-21 13:41:28 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.c: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.h: + decoder: get rid of GstVaapiDecoderUnit::buffer field. + Drop GstVaapiDecoderUnit buffer field (GstBuffer) since it's totally + useless nowadays as creating sub-buffers doesn't bring any value. It + actually means more memory allocations. We can't do without that in + JPEG and MPEG-4:2 decoders. + +2013-03-21 13:28:05 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: sanitize uses of codec frame input buffer (cosmetics). + Alias GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer to a simple + "buffer" variable. + +2013-03-20 17:34:38 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: add helper function to apply a composition buffer. + Simplify application of a composition buffer to a GstVaapiSurface, and + all its peers, until that function is eventually promoted to libgstvaapi. + +2013-03-20 13:42:15 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix support for raw YUV buffers. + If the raw YUV buffer was created from vaapisink, through the buffer_alloc() + hook, then it will have a valid GstVaapiVideoMeta object attached to it. + However, we previously assumed in that case that it was a "native" VA buffer, + thus not calling into GstVaapiUploader::process(). + +2013-03-20 18:41:40 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstcompat.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: use modern GstElement metadata information. + Use gst_element_class_set_static_metadata() from GStreamer 1.0, which + basically is the same as gst_element_class_set_details_simple() in + GStreamer 0.10 context. + +2013-03-20 18:04:39 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: move up interfaces (cosmetics). + Move GstImplementsInterface and GstVideoContext support functions up + so that to keep a clear separation between the plugin element and its + interface hooks. + +2013-03-20 12:57:18 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiuploader.c: + plugins: upgrade to newer APIs (GstVideoInfo based helpers). + Use GstVideoInfo and gst_video_info_from_caps() helper wherever possible. + Also use the newly added gst_vaapi_image_format_from_structure() helper + in GstVaapiUploader::ensure_allowed_caps(). + +2013-03-20 14:02:48 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginbuffer.c: + plugins: fix creation of video buffer from another source buffer. + gst_vaapi_video_buffer_new_from_buffer() needs to reference the source + buffer video meta since it would be unreference'd from the get_buffer() + helper function. For other cases, we still use (steal) the newly created + video meta. + +2013-03-20 11:57:03 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginbuffer.c: + * gst/vaapi/gstvaapipluginutil.c: + plugins: include "sysdeps.h" header instead of "config.h". + +2013-03-20 18:33:23 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstcompat.h: + * tests/codec.c: + tests: modernize GstTypeFind functions. + Use the GstTypeFind hooks from GStreamer 1.0. They look safer and + exactly correspond to the expected behaviour. + +2013-03-20 11:57:57 +0100 Gwenole Beauchesne + + * tests/image.c: + * tests/image.h: + * tests/test-decode.c: + * tests/test-display.c: + * tests/test-h264.c: + * tests/test-h264.h: + * tests/test-jpeg.c: + * tests/test-jpeg.h: + * tests/test-mpeg2.c: + * tests/test-mpeg2.h: + * tests/test-mpeg4.c: + * tests/test-mpeg4.h: + * tests/test-textures.c: + * tests/test-vc1.c: + * tests/test-vc1.h: + * tests/test-windows.c: + tests: fix license templates. + +2013-03-20 11:53:59 +0100 Gwenole Beauchesne + + * tests/test-display.c: + tests: use gst_vaapi_image_format_from_structure() in test-display. + Use gst_vaapi_image_format_from_structure() helper in test-display and + then extract a VAImageFormat from it instead of relying on GstCaps for + YUV and RGB formats. + +2013-03-20 11:50:15 +0100 Gwenole Beauchesne + + * tests/codec.c: + * tests/decoder.c: + * tests/output.c: + * tests/test-decode.c: + * tests/test-display.c: + * tests/test-subpicture.c: + * tests/test-textures.c: + * tests/test-windows.c: + tests: include "sysdeps.h" header instead of "config.h". + +2013-03-20 18:25:05 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstcompat.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + subpicture: use gst_video_overlay_rectangle_get_pixels_unscaled_raw(). + Use newer gst_video_overlay_rectangle_get_pixels_unscaled_raw() helper + function with GStreamer 0.10 compatible semantics, or that tries to + approach the current meaning. Basically, this is also just about moving + the helper to gstcompat.h. + +2013-03-20 11:10:31 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + image: add gst_vaapi_image_format_from_structure() helper. + Add helper function to convert video formats from a GstStructure to a + plain GstVaapiImageFormat. + +2013-03-20 18:12:18 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstcompat.h: + * gst-libs/gst/vaapi/sysdeps.h: + sysdeps: split out GStreamer API compatibility glue to "gstcompat.h". + +2013-03-20 11:56:15 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/sysdeps.h: + sysdeps: add more standard includes by default. + +2013-03-20 14:43:46 +0100 Gwenole Beauchesne + + * configure.ac: + configure: improve GStreamer API version checks. + +2013-03-20 11:44:10 +0100 Gwenole Beauchesne + + * configure.ac: + * debian.upstream/Makefile.am: + * debian.upstream/changelog.in: + * debian.upstream/control.in: + * debian.upstream/gstreamer-vaapi-doc.install.in: + * debian.upstream/libgstvaapi-dev.install.in: + * debian.upstream/libgstvaapi-drm.install.in: + * debian.upstream/libgstvaapi-glx.install.in: + * debian.upstream/libgstvaapi-wayland.install.in: + * debian.upstream/libgstvaapi-x11.install.in: + * debian.upstream/libgstvaapi.install.in: + * docs/reference/libs/Makefile.am: + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/plugins/Makefile.am: + * docs/reference/plugins/plugins-docs.xml.in: + * gst-libs/gst/vaapi/Makefile.am: + * gst/vaapi/Makefile.am: + * pkgconfig/Makefile.am: + * pkgconfig/gstreamer-vaapi-drm.pc.in: + * pkgconfig/gstreamer-vaapi-glx.pc.in: + * pkgconfig/gstreamer-vaapi-wayland.pc.in: + * pkgconfig/gstreamer-vaapi-x11.pc.in: + * pkgconfig/gstreamer-vaapi.pc.in: + * tests/Makefile.am: + configure: rename GST_MAJORMINOR to GST_API_VERSION. + +2013-03-20 11:28:06 +0100 Gwenole Beauchesne + + * configure.ac: + configure: improve check for H.264 codecparser. + +2013-02-26 00:38:24 +0100 Holger Kaelberer + + * gst/vaapi/gstvaapiuploader.c: + vaapiupload: fix illegal write in ensure_image(). + Fix ensure_image() to only zero-initialize the first line of each plane. + Properly initializing each plane to their full vertical resolution would + require to actually compute it based on the image format. + In particular, for NV12 images, the UV plane has half vertical resolution + vs. the Y plane. So using the full image height to initialize the UV plane + will obviously lead to a buffer overflow. Likewise for other YUV format. + Since ensure_image() is only a helper function to initialize something, + and not necessarily the whole thing, it is fine to initializ the first + line only. Besides, the target surface is not rendered either. + Signed-off-by: Gwenole Beauchesne + +2013-02-17 16:28:47 +0800 Xiang, Haihao + + * gst-libs/gst/codecparsers/Makefile.am: + * gst-libs/gst/video/Makefile.am: + build: fix compiling of local GstVideoDecoder and codecparsers. + Generated source files were missing a dependency on the complete set of + generated header files. e.g. gstvideodecoder.c requires gstvideoutils.h + to build and almost every codec parser source depends on parserutils.h. + https://bugs.freedesktop.org/show_bug.cgi?id=59575 + Signed-off-by: Xiang, Haihao + Signed-off-by: Gwenole Beauchesne + +2013-02-08 11:56:54 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: set {luma,chroma}_log2_weight_denom to 0 if no pred_weight_table(). + Force luma_log2_weight_denom and chroma_log2_weight_denom to zero if + there is no pred_weight_table() that was parsed. + This is a workaround for the VA intel-driver on Ivy Bridge. + +2013-02-07 15:42:55 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: use new profile definitions from codecparsers. + +2013-02-07 15:29:44 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 500bc02. + 500bc02 h264: add profile enums + +2013-02-06 15:27:18 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-02-06 15:21:27 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 31b1c57. + 8957fb7 mpeg2: add helpers to convert quantization matrices + 07c4034 mpeg2: store quantization matrices in zigzag scan order + +2013-01-31 11:32:24 +0100 Gwenole Beauchesne + + * tests/simple-decoder.c: + tests: simple-decoder: fix build on older platforms. + Make simple-decoder build and execute correctly on older platforms, + and more precisely older versions of glib. + +2013-01-31 11:30:12 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/glibcompat.h: + glibcompat: add replacement for g_async_queue_timeout_pop(). + g_async_queue_timeout_pop() appeared in glib 2.31.18. Implement it as + g_async_queue_timed_pop() with a GTimeVal as the final time to wait for + new data to arrive in the queue. + +2013-01-31 11:25:18 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/glibcompat.h: + glibcompat: add replacement for g_cond_wait(). + +2013-01-30 18:38:38 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix decoding of 4K videos. + Account for slice_vertical_position_extension when vertical_size > 2800. + +2013-01-30 18:54:13 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix decoding of sequence_end(). + There shall be only one place to call decode_current_picture(), and this + is in the end_frame() hook. The EOS unit is processed after end_frame() + so this means we cannot have a valid picture to decode/output at this + point. + +2013-01-30 15:10:06 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: improve robustness when packets are missing. + Improve robustness when some expected packets where not received yet + or that were not correctly decoded. For example, don't try to decode + a picture if there was no valid sequence or picture headers. + +2013-01-30 18:58:01 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: handle decode-only frames in raw API mode. + Fix gst_vaapi_decoder_get_surface() to only return frames with a valid + surface proxy, i.e. with a valid VA surface. This means that any frame + marked as decode-only is simply skipped. + +2013-01-30 16:33:48 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: allow frames to be dropped. + If the decoder was not able to decode a frame because insufficient + information was available, e.g. missing sequence or picture header, + then allow the frame to be gracefully dropped without generating + any error. + It is also possible that a frame is not meant to be displayed but + only used as a reference, so dropping that frame is also a valid + operation since GstVideoDecoder base class has extra references to + that GstVideoCodecFrame that needs to be released. + +2013-01-30 16:26:07 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: handle decode-only frames. + Decode-only frames may not have a valid surface proxy. So, simply discard + them gracefully, i.e. don't create meta data information. GstVideoDecoder + base class will properly handle this case and won't try to push any buffer + to downstream elements. + +2013-01-24 00:49:17 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: add support for post-seek semantics reset. + Implement GstVideoDecoder::reset() as a destruction of the VA decoder + and the creation of a new VA decoder. + Signed-off-by: Gwenole Beauchesne + +2013-01-30 09:38:07 +0100 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2013-01-30 09:37:38 +0100 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.5.1. + +2013-01-24 00:48:26 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: implement GstVaapiDecoder::flush() as a DPB flush. + +2013-01-24 17:34:43 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_frame.h: + decoder: fix documentation for GstVaapiDecoderFrame. + Drop superfluous reference to prev_slice member. + +2013-01-29 16:18:13 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: assume current frame is complete at end-of-stream. + Assume we got a complete frame when the end-of-stream is reached and that + the current codec frame contains at least one slice data unit. + +2013-01-29 14:14:45 +0100 Gwenole Beauchesne + + * NEWS: + * README: + * debian.upstream/copyright: + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.h: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.c: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.c: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapiminiobject.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/sysdeps.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipluginbuffer.c: + * gst/vaapi/gstvaapipluginbuffer.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiuploader.c: + * tests/output.c: + * tests/test-decode.c: + * tests/test-subpicture.c: + legal: fix year for some copyright notices (2013). + +2013-01-29 14:03:27 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.h: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h: + * gst/vaapi/gstvaapidecode.h: + * gst/vaapi/gstvaapisink.h: + * tests/test-subpicture.c: + legal: fix year for some copyright notices (2012). + +2013-01-29 14:00:04 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapiparamspecs.c: + * gst-libs/gst/vaapi/gstvaapiparamspecs.h: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + * tests/test-display.c: + * tests/test-surfaces.c: + * tests/test-windows.c: + legal: add Intel copyright on modified files. + +2013-01-29 13:37:41 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-01-28 18:09:09 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: use a local event queue to avoid lock contention. + This improves performance when rendering several surfaces from within + the same process. e.g. a tee of vaapidecode'd buffers to vaapisink. + +2013-01-28 17:28:58 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: fix thread-safe issues. + The Wayland API is not fully thread-safe and client applications shall + perform locking themselves on key functions. Besides, make sure to + release the lock if the _render() function fails. + +2013-01-28 16:37:28 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: really wait until the pending redraw completed. + Introduce gst_vaapi_window_wayland_sync() helper function to wait for + the completion of the redraw request. Use it in _render() function to + actually block until the previous draw request is completed. + +2013-01-23 10:10:35 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: fix frame_redraw callback. + The redraw callback needs to be attached to the surface prior to the + commit. Otherwise, the callback notifies the next surface repaint, + which is not the desired behaviour. i.e. we want to be notified for + the surface we have just filled. + Another isse was the redraw_pending was reset before the actual completion + of the frame redraw callback function, thus causing concurrency issues. + e.g. the callback could have been called again, but with a NULL buffer. + +2013-01-28 14:45:28 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + wayland: fix display sharing. + When the Wayland display is shared, we still have to create our own local + shell and compositor objects, since they are not propagated from the cache. + Likewise, we also need to determine the display size or vaapisink would + fail to account for the display aspect ratio, and will try to create a 0x0 + window. + +2013-01-24 17:38:53 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 21a098e. + 21a098e vc1: fix bitplanes decoding (DIFF6 or NORM6) [residual] + f8c836a vc1: fix bitplanes decoding (DIFF6 or NORM6) + +2013-01-23 16:38:24 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: handle frames with multiple slices. + +2013-01-23 17:01:34 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 3fba492. + 3fba492 vc1: add API to parse slice headers + +2013-01-23 11:11:25 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: handle CLOSED_ENTRY. + When CLOSED_ENTRY == 0, and if the B pictures that follow an entry-point + lack a reference anchor picture, these B pictures shall be discarded. + https://bugs.freedesktop.org/show_bug.cgi?id=59505 + +2013-01-23 10:25:52 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: cope with latest codecparser changes. + Fix build with newer VC-1 codecparser where dqsbedge was renamed to + dqbedge, and now represents either DQSBEDGE or DQDBEDGE depending on + the actual value of DQPROFILE. + +2013-01-23 10:24:04 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 3d2c67c. + 3d2c67c vc1: simplify GstVC1VopDquant structure + +2013-01-22 10:51:40 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit 5d33da8. + 5d33da8 vc1: fix bitplanes decoding + 562bdc4 vc1: fix VOPDQUANT parser for DQUANT == 2 + 0b13d2b vc1: fix calculation of ALTPQUANT + ba88e63 vc1: fix parser for DQPROFILE in VOPDQUANT + +2013-01-22 15:47:09 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: fix size of encapsulated BDU. + Fix size of encapsulated BDUs since GstVC1BDU.size actually represents + the size of the BDU data, starting from offset, i.e. after any start + code is parsed. + This fixes a buffer overflow during the unescaping process. + +2013-01-11 17:08:00 +0800 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: fix decoding of WMV3 videos in AVI format. + The AVI demuxer (avidemux) does not set a proper "format" attribute + to the generated caps. So, try to recover the video codec format from + the "wmvversion" property instead. + Signed-off-by: Gwenole Beauchesne + +2013-01-22 13:28:13 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: review and report errors accordingly. + Use GST_ERROR() to report real errors instead of hiding them into + GST_DEBUG(). + +2013-01-22 13:50:39 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: don't create GstBuffers for all decoder units. + Don't create temporary GstBuffers for all decoder units, even if they + are lightweight "sub-buffers", since it is not really necessary to keep + the buffer data around. + +2013-01-22 16:03:18 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: implement flush() hook. + Make it a simple DPB flush. + +2013-01-22 13:44:32 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: implement {start,end}_frame() hooks. + Implement GstVaapiDecoder.start_frame() and end_frame() semantics so + that to create new VA context earlier and submit VA pictures to the + HW for decoding as soon as possible. i.e. don't wait for the next + frame to start decoding the previous one. + +2013-01-22 09:30:04 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: fix next POC for new sequence layers. + Fix next POC when a new sequence layer is reached. At this point, we + need to reset any previous reference picture, i.e. non B-frame. + +2012-08-02 17:15:26 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: port to common GstVaapiDpb interface. + Use GstVaapiDpb interface instead of maintaining our own prev and next + picture pointers. While doing so, try to derive a sensible POC value. + Signed-off-by: Gwenole Beauchesne + +2013-01-15 17:10:56 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: fix decode_sequence_end() to return success, not EOS. + +2013-01-18 17:00:18 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: simplify gst_vaapi_decoder_get_surface(). + Avoid extraenous branches, i.e. immediately return with success once we + have a decoded frame available. + +2013-01-18 16:56:15 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: optimize and clean decode_step() up. + Avoid usage of goto. Simplify decode_step() process to first accumulate all + pending buffers into the GstAdapter, and then parse and decode units from + that input adapter. Stop the process once a frame is fully decoded or an + error occurred. + +2013-01-18 14:46:23 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: move "vaapi" debug init to libgstvaapi_init_once(). + +2013-01-18 14:17:34 +0100 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiversion.h.in: + display: dump gstreamer-vaapi version for debugging purposes. + +2013-01-18 14:30:48 +0100 Gwenole Beauchesne + + * tests/Makefile.am: + tests: simple-decoder: fix build with built-in videoutils. + Fix build with built-in videoutils, i.e. when system GStreamer installation + does not know about GstVideoDecoder API. + +2013-01-18 10:35:44 +0100 Gwenole Beauchesne + + * tests/simple-decoder.c: + tests: simple-decoder: flush decoded frames at EOS. + Flush the remaining decoded frames when an end-of-stream is reached. + +2013-01-18 10:25:14 +0100 Gwenole Beauchesne + + * tests/simple-decoder.c: + tests: simple-decoder: drop use of GstVaapiVideoMeta. + Don't use GstVaapiVideoMeta since that object is not guaranteed to live + in libgstvaapi forever. Rather, that'd move to plugin elements at some + point. + +2013-01-16 13:53:43 +0100 Gwenole Beauchesne + + * tests/simple-decoder.c: + tests: simple-decoder: add benchmark mode. + Add --benchmark option to enable benchmark mode where rendering is not + synchronized with presentation timestamps of the decoded surfaces. + +2013-01-16 13:29:06 +0100 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/simple-decoder.c: + tests: simple-decoder: honour framerate from the bitstream. + Try to honour the framerate from the bitstream, or cap the playback to + 60 fps by default. + +2013-01-15 18:49:28 +0100 Gwenole Beauchesne + + * tests/simple-decoder.c: + tests: simple-decoder: set window size to the surface dimensions. + Set the window size to the decoded surface dimensions, if the user has + not requested the application to run in full-screen mode. Besides, no + effort is made to preserve aspect ratio or to center the video within + the mapped window. + +2013-01-15 17:33:18 +0100 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/simple-decoder.c: + tests: add simple decoder application. + Add simple decoder application to show off decoding capabilities from + raw bitstreams, for debugging or performance evaluation purposes. + +2013-01-15 17:30:57 +0100 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/codec.c: + * tests/codec.h: + tests: add codec helper utils. + Add helper functions to determine the codec type from a specific file + or utility functions to convert from codec type to GstCaps or from + codec name to codec type. + +2013-01-15 17:47:13 +0100 Gwenole Beauchesne + + * tests/output.c: + tests: allow fullscreen mode. + Add new --fullscreen|-f option to create new windows in fullscreen mode. + +2013-01-17 18:35:58 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: implement GstVaapiDecoder::flush() as a DPB flush. + +2013-01-17 18:07:03 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: handle end-of-stream NALU. + Handle NAL unit to actually flush any pending picture + from the DPB. + +2013-01-17 18:22:49 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: handle EOS events. + Flush all decoded frames to downstream when EOS is received. This is + performed by implementing GstVideoDecoder::finish() hook. + +2013-01-17 18:19:14 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: split gvd_handle_frame() into decode/push frames. + Split GstVideoDecoder::handle_frame() implementation into two functions: + (i) one for decoding the provided GstVideoCodecFrame and (ii) another one + for purging all decoded frames and submit them downstream. + +2013-01-17 18:33:32 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + decoder: add GstVaapiDecoder::flush() hook. + +2013-01-15 17:21:50 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: fix check for end-of-stream in raw API mode. + Make sure to immediately return GST_VAAPI_DECODER_STATUS_END_OF_STREAM + if the end-of-stream was already reached at the previous iteration. + +2013-01-15 16:55:29 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: make decode_step() return once the frame is decoded. + Make sure we always have a free surface left to use for decoding the + current frame. This means that decode_step() has to return once a frame + gets decoded. If the current adapter contains more buffers with valid + frames, they will get parsed and decoded on subsequent iterations. + +2013-01-17 15:47:17 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-branch commit b47983a. + 8840c2d h264: zero-initialize SPS VUI parameters + +2013-01-15 09:21:36 +0100 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2013-01-15 09:21:08 +0100 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.5.0. + +2013-01-14 11:48:58 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + docs: expose new interfaces. + +2013-01-14 12:58:20 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2013-01-14 10:58:49 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + dpb: cosmetics (clean-ups). + +2013-01-14 10:46:25 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + dpb: port to GstVaapiMiniObject. + +2013-01-14 10:21:53 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + dpb: drop GstVaapiDpb2 interface, keep only one class. + Keep only one DPB interface and rename gst_vaapi_dpb2_get_references() + to gst_vaapi_dpb_get_neighbours() so that to retrieve pictures in DPB + around the specified picture POC. + +2012-08-02 15:56:54 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + dpb: rename GstVaapiDpbMpeg2 to GstVaapiDpb2. + Move GstVaapiDpbMpeg2 API to a more generic version that could also be + useful to other decoders that require 2 reference pictures, e.g. VC-1. + Signed-off-by: Gwenole Beauchesne + +2013-01-11 16:04:30 +0100 Gwenole Beauchesne + + * configure.ac: + Bump version for pre-release. + +2013-01-11 15:57:09 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2012-07-20 12:36:33 +0200 Holger Kaelberer + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/sysdeps.h: + * tests/test-subpicture.c: + overlay: fix build without advanced GstVideoOverlayFormatFlags. + Check for global-alpha support in GstVideoOverlayComposition API. + Signed-off-by: Gwenole Beauchesne + +2013-01-04 10:19:56 +0100 Gwenole Beauchesne + + * tests/test-subpicture.c: + tests: add support for global-alpha subpictures. + Add --global-alpha option to test-subpicture. + +2013-01-10 13:09:28 +0100 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/test-subpicture.c: + tests: use GstVideoOverlayComposition API for subpicture test. + +2013-01-10 11:26:17 +0100 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/test-subpicture.c: + tests: use common decoder helpers for subpicture test. + Use common decoder helpers for subpicture test, thus allowing to decode + sample images in an alternate format. + +2013-01-10 11:22:38 +0100 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/decoder.c: + * tests/decoder.h: + * tests/test-decode.c: + tests: add decoder helpers. + +2013-01-11 15:19:45 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + overlay: fix ordering of composition layers. + Make sure to maintain the association order of composition layers when + GstVideoOverlayRectangle objects are kept around (cached). + +2012-05-15 10:24:08 +0200 Holger Kaelberer + + * gst-libs/gst/vaapi/gstvaapicontext.c: + overlay: fix support for global-alpha. + Fix support for global-alpha subpictures. The previous changes brought + the ability to check for GstVideoOverlayRectangle changes by comparing + the underlying pixel buffer pointers. If sequence number and pixel data + did not change, then this is an indication that only the global-alpha + value changed. Now, try to update the underlying VA subpicture global-alpha + value. + Signed-off-by: Gwenole Beauchesne + +2013-01-11 11:53:05 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + overlay: detect render-rect changes. + Don't re-upload VA subpicture if only the render rectangle changed. + Rather deassociate the subpicture and re-associate it with the new + render rectangle. + +2013-01-11 11:12:26 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + overlay: fix check for pixels buffer change. + A GstVideoOverlayRectangle is created whenever the underlying pixels data + change. However, when global-alpha is supported, it is possible to re-use + the same GstVideoOverlayRectangle but with a change to the global-alpha + value. This process causes a change of sequence number, so we can no longer + check for that. + Still, if sequence numbers did not change, then there was no change in + global-alpha either. So, we need a way to compare the underlying GstBuffer + pointers. There is no API to retrieve the original pixels buffer from + a GstVideoOverlayRectangle. So, we use the following heuristics: + 1. Use gst_video_overlay_rectangle_get_pixels_unscaled_argb() with the same + format flags from which the GstVideoOverlayRectangle was created. This + will work if there was no prior consumer of the GstVideoOverlayRectangle + with alternate (non-"native") format flags. + 2. In overlay_rectangle_has_changed_pixels(), we have to use the same + gst_video_overlay_rectangle_get_pixels_unscaled_argb() function but + with flags that match the subpicture. This is needed to cope with + platforms that don't support global-alpha in HW, so the gst-video + layer takes care of that and fixes this up with a possibly new + GstBuffer, and hence pixels data (or) in-place by caching the current + global-alpha value applied. So we have to determine the rectangle + was previously used, based on what previous flags were used to + retrieve the ARGB pixels buffer. + +2013-01-10 18:42:37 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + overlay: optimize cache at the GstVideoOverlayRectangle level. + We previously assumed that an overlay composition changed if the number + of overlay rectangles in there actually changed, or that the rectangle + was updated, and thus its seqnum was also updated. + Now, we can cope with cases where the GstVideoOverlayComposition grew + by one or a few more overlay rectangles, and the initial overlay rectangles + are kept as is. + +2013-01-10 13:41:39 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + overlay: simplify caching of GstVideoOverlayComposition objects. + Create the GPtrArray once in the _init() function and destroy it only + in the _finalize() function. Then use overlay_clear() to remove all + subpicture associations for intermediate updates, don't recreate the + GPtrArray. + Make GstVaapiOverlayRectangle a reference counted object. Also make + sure that overlay_rectangle_new() actually creates and associates the + VA subpicture. + +2012-05-15 10:24:08 +0200 Holger Kaelberer + + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + overlay: add support for global-alpha. + Handle global-alpha from GstVideoOverlayComposition API. Likewise, + the same code path could also work for premultiplied-alpha but this + was not tested. + Signed-off-by: Gwenole Beauchesne + +2012-05-15 10:24:08 +0200 Holger Kaelberer + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * tests/image.c: + * tests/test-subpicture.c: + subpicture: add support for global-alpha. + Add the necessary helpers in GstVaapiDisplay to determine whether subpictures + with global alpha are supported or not. Also add accessors in GstVaapiSubpicture + to address this feature. + Signed-off-by: Gwenole Beauchesne + +2013-01-04 09:41:25 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + subpicture: add premultiplied-alpha and global-alpha feature flags. + Add premultiplied-alpha and global-alpha feature flags, along with converters + between VA-API and gstreamer-vaapi definitions. Another round of helpers is + also necessary for GstVideoOverlayComposition API. + +2013-01-03 18:02:49 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: allow image/subpicture formats with additional flags. + Introduce new GstVaapiFormatInfo to store the actual GstVaapiImageFormat + and any additional flags needed. Currently, all flags are set to zero. + +2013-01-11 13:34:45 +0100 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/Makefile.am: + * gst-libs/gst/video/Makefile.am: + * tests/Makefile.am: + libs: fix build of submodule wrappers. + Make sure to build codecparsers/ and videoutils/ sources against the + newly generated headers when out-of-source builds are used. + +2013-01-11 14:11:39 +0100 Gwenole Beauchesne + + * configure.ac: + configure: fix checks for packages installed in non-standard roots. + +2013-01-10 10:12:25 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiminiobject.c: + decoder: fix mini object implementation on 64-bit systems. + Use GPOINTER_TO_SIZE() instead of GPOINTER_TO_UINT() while manipulating + pointers. The latter is meant to be 32-bit only, not uintptr_t like size. + Only a gsize can hold all bits of a pointer. + Thanks to Ouping Zhang for spotting this error. + +2013-01-09 16:05:39 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: optimize scan for the end of the frame. + Heuristic: if the second start-code is available, check whether that + one marks the start of a new frame because e.g. this is a sequence + or picture header. This doesn't save much, since we already cache the + results. + +2013-01-09 13:44:18 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: optimize scan for start codes. + Accelerate scan for start codes by skipping up to 3 bytes per iteration. + A start code prefix is defined by the following bytes: 00 00 01. Thus, + for any group of 3 bytes (xx yy zz), we have the following possible cases: + 1. If zz != 1, this cannot be a start code, then skip 3 bytes; + 2. If yy != 0, this cannot be a start code, then skip 2 bytes; + 3. If xx != 0 or zz != 1, this cannot be a start code, then skip 1 byte; + 4. xx == 00, yy == 00, zz == 1, we have match! + This algorithm requires to peek bytes from the adapter. This increases the + amount of bytes copied to a temporary buffer, but this process is much faster + than scanning for all the bytes and using shift/masks. So, overall, this is + a win. + +2013-01-08 16:41:44 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: drop useless gst_adapter_peek(). + Drop useless gst_adapter_peek() since the returned buffer was not used + and this could incur superfluous memcpy(). + +2013-01-07 16:07:38 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: cosmetics: move parse_slice() down. + +2013-01-07 15:24:51 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: avoid too many allocations of parser info objects. + Move parsing back to decoding step, but keep functions separate for now. + This is needed for future optimizations that may introduce some meta data + for parsed info attached to codec frames. + +2013-01-07 14:04:22 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_unit.c: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.h: + decoder: decoder units are no longer dynamically allocated objects. + +2013-01-07 13:59:07 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.c: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.h: + decoder: optimize pre-allocation of decoder units. + Optimize pre-allocation of decoder units, thus avoiding un-necessary + memory reallocations. The heuristic used is that we could have around + one slice unit per macroblock line. + +2013-01-07 13:41:59 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.c: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.c: + decoder: use an array of units instead of a single-linked list. + Use a GArray to hold decoder units in a frame, instead of a single-linked + list. This makes 'append' calls faster, but not that much. At least, this + makes things clearer. + +2013-01-07 11:13:07 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.c: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: refactor decoder unit API. + Allocate decoder unit earlier in the main parse() function and don't + delegate this task to derived classes. The ultimate purpose is to get + rid of dynamic allocation of decoder units. + +2013-01-07 10:48:27 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: introduce parser info instead of MPEG-2 specific decoder unit. + Use a new GstVaapiParserInfoMpeg2 data structure instead of deriving + from GstVaapiDecoderUnit for MPEG-2 specific parser information. + +2013-01-07 10:22:54 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: introduce parser info instead of H.264 specific decoder unit. + Use a new GstVaapiParserInfoH264 data structure instead of deriving + from GstVaapiDecoderUnit for H.264 specific parser information. + +2013-01-05 12:33:06 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: set default values for some header fields. + The SPS, PPS and slice headers are not fully zero-initialized in the + codecparsers/ library. Rather, the standard upstream behaviour is to + initialize only certain syntax elements with some inferred values if + they are not present in the bitstream. + At the gstreamer-vaapi decoder level, we need to further initialize + certain syntax elements with some sensible default values so that to + not complicate VA drivers that just pass those verbatim to the HW, + and also avoid an memset() of the whole decoder unit. + Signed-off-by: Sreerenj Balachandran + Signed-off-by: Gwenole Beauchesne + +2013-01-06 19:05:49 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-rebased commit b47983a. + b47983a h264: add inferred value for slice_beta_offset_div2 + +2013-01-05 17:55:47 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipluginbuffer.c: + * gst/vaapi/gstvaapipluginbuffer.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiuploader.c: + plugins: cope with new GstVaapiVideoMeta API. + Update plugin elements with the new GstVaapiVideoMeta API. + This also fixes support for subpictures/overlay because GstVideoDecoder + generates a sub-buffer from the GstVaapiVideoBuffer. So, that sub-buffer + is marked as read-only. However, when comes in the textoverlay element + for example, it checks whether the input buffer is writable. Since that + buffer read-only, then a new GstBuffer is created. Since gst_buffer_copy() + does not preserve the parent field, the generated buffer in textoverlay + is not exploitable because we lost all VA specific information. + Now, with GstVaapiVideoMeta information attached to a standard GstBuffer, + all information are preserved through gst_buffer_copy() since the latter + does copy metadata (qdata in this case). + +2013-01-05 17:37:13 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + videobuffer: wrap video meta into a surface buffer. + Make GstVaapiVideoBuffer a simple wrapper for video meta. This buffer is + no longer necessary but for compatibility with GStreamer 0.10 APIs or users + expecting a GstSurfaceBuffer like Clutter. + +2013-01-05 08:31:24 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapivideometa.c: + * gst-libs/gst/vaapi/gstvaapivideometa.h: + videobuffer: add video meta information. + Add new GstVaapiVideoMeta object that holds all information needed to + convey gst-vaapi specific data as a GstBuffer. + +2013-01-03 13:10:33 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix calculation of the time-out value. + Fix calculation of the time-out value for cases where no VA surface is + available for decoding. In this case, we need to wait until downstream + sink consumed at least one surface. The time-out was miscalculated as + it was always set to + one second, which is not suitable + for streams with larger gaps. + +2013-01-03 13:05:47 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + decoder: always use the calculated presentation timestamp. + Use PTS value computed by the decoder, which could also be derived from + the GstVideoCodecFrame PTS. This makes it possible to fix up the PTS if + the original one was miscomputed or only represented a DTS instead. + +2013-01-02 17:33:15 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: don't create sub-buffer for slice data. + +2013-01-03 11:16:44 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: create new context when encoded resolution changes. + Create a new VA context if the encoded surface size changes because we + need to keep the underlying surface pool until the last one was released. + Otherwise, either of the following cases could have happened: (i) release + a VA surface to an inexistent pool, or (ii) release VA surface to an + existing surface pool, but with different size. + +2013-01-02 17:23:53 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: don't create sub-buffer for slice data. + Avoid creating a GstBuffer for slice data. Rather, directly use the codec + frame input buffer data. This is possible because the codec frame is valid + until end_frame() where we submit the VA buffers for decoding. Anyway, the + slice data buffer is copied into the VA buffer when it is created. + +2013-01-02 14:45:50 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: minor clean-ups. + Drop explicit initialization of most fields that are implicitly set to + zero. Remove some useless checks for NULL pointers. + +2013-01-02 14:18:31 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: optimize scan for the second start code. + Optimize scan for the second start code, on the next parse() call so that + to avoid scanning again earlier bytes where we didn't find any start code. + +2013-01-02 14:10:20 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: use sequence_display_extension() to compute PAR. + Also compute pixel-aspect-ratio from sequence_display_extension(), + should it exist in the bitstream. + +2013-01-02 14:02:29 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: handle sequence_display_extension(). + +2012-12-27 15:18:55 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: implement {start,end}_frame() hooks. + Implement GstVaapiDecoder.start_frame() and end_frame() semantics so + that to create new VA context earlier and submit VA pictures to the + HW for decoding as soon as possible. i.e. don't wait for the next + frame to start decoding the previous one. + +2012-12-27 14:54:29 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: parse slice() header earlier. + Parse slice() header and first macroblock position earlier in _parse() + function instead of waiting for the _decode() stage. This doesn't change + anything but readability. + +2012-12-27 14:41:04 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: add codec specific decoder unit. + Introduce new GstVaapiDecoderUnitMpeg2 object, which holds the standard + GstMpegVideoPacket and additional parsed header info. Besides, we now + parse as early as in the _parse() function so that to avoid un-necessary + creation of sub-buffers in _decode() for video packets that are not slices. + +2012-12-27 18:52:43 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.c: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.h: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.h: + decoder: introduce lists of units to decode before/after frame. + Theory of operations: all units marked as "slice" are moved to the "units" + list. Since this list only contains slice data units, the prev_slice pointer + was removed. Besides, we now maintain two extra lists of units to be decoded + before or after slice data units. + In particular, all units in the "pre_units" list will be decoded before + GstVaapiDecoder::start_frame() is called and units in the "post_units" + list will be decoded after GstVaapiDecoder::end_frame() is called. + +2013-01-02 16:06:18 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + decoder: drop useless checks for codec objects. + Codec objects are used internally only and they are bound to be created + with a valid GstVaapiDecoder object. + +2012-12-27 10:35:45 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: use GST_ERROR to print error messages. + +2012-12-27 09:55:14 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: avoid double release of frame on error. + Don't call gst_video_decoder_drop_frame() if gst_video_decoder_finish_frame() + was already called before and it returned an error. In that case, we were + releasing the frame again, thus leading to a "double-free" condition. + +2012-12-21 14:29:01 +0100 Gwenole Beauchesne + + * .gitmodules: + * autogen.sh: + * configure.ac: + * ext/Makefile.am: + * ext/videoutils: + * gst-libs/gst/Makefile.am: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/video/Makefile.am: + * gst/vaapi/Makefile.am: + Add videoutils submodule for GstVideoDecoder APIs. + +2012-12-18 16:36:01 +0100 Gwenole Beauchesne + + * configure.ac: + configure: check for GstVideoDecoder API. + GstVideoDecoder API is part of an unreleased GStreamer 0.10 stack. In particular, + this is only available in git 0.10 branch or GStreamer >= 1.0 stack. Interested + parties may either use upstream git 0.10 branch or backport the necessary support + for GstVideoDecoder API, thus including helper tools like GstVideoCodecFrame et al. + +2012-12-18 16:21:31 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs.core.types: + docs: remove obsolete gst_vaapi_surface_proxy_get_type(). + GstVaapiSurfaceProxy is no longer based on the GType system. + +2012-12-18 16:17:22 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + docs: fix entries for GstVaapiSurfaceProxy. + +2012-12-18 15:29:58 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2012-12-18 15:15:52 +0100 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + Bump library major version. + Increase library major so that to cope with API/ABI incompatible changes + since 0.4.x series and avoid user issues. + +2012-12-13 16:02:52 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + surfaceproxy: minor clean-ups. + +2012-12-13 15:51:24 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + surfaceproxy: drop accessors to obsolete attributes. + Make GstVaapiSurfaceProxy only a thin wrapper around a VA context and a + VA surface. i.e. drop any other attribute like timestamp, duration, + interlaced or top-field-first. + +2012-12-13 15:34:10 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst/vaapi/gstvaapidecode.c: + decoder: maintain decoded frames as GstVideoCodecFrame objects. + Maintain decoded surfaces as GstVideoCodecFrame objects instead of + GstVaapiSurfaceProxy objects. The latter will tend to be reduced to + the strict minimum: a context and a surface. + +2012-12-13 14:30:18 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: output all decoded frames as soon as possible. + Make sure to push all decoded frames downstream as soon as possible. + This makes sure we don't need to wait for a new frame to be ready to + be decoded before receiving new decoded frames. + This also separates the decode process and the output process. The latter + could be moved to a specific GstTask later on. + +2012-12-13 14:27:18 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + decoder: add gst_vaapi_decoder_get_frame() API. + Add new gst_vaapi_decoder_get_frame() function meant to be used with + gst_vaapi_decoder_decode(). The purpose is to return the next decoded + frame as a GstVideoCodecFrame and the associated GstVaapiSurfaceProxy + as the user-data object. + +2012-12-13 15:47:27 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: use GstBuffer flags for TFF. + Determine whether the buffer represents the top-field only by checking for + the GST_VIDEO_BUFFER_TFF flag instead of relying on the GstVaapiSurfaceProxy + flag. Also trust "interlaced" caps to determine whether the input frame + is interleaved or not. + +2012-12-13 13:27:33 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: handle video sub-buffers. + Intermediate elements may produce a sub-buffer from a valid GstVaapiVideoBuffer + for non raw YUV cases. Make sure vaapipostproc now understands those buffers. + +2012-12-18 14:57:36 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: optimize initialization process of decoder units. + Decoder units were zero-initialized, including the SPS/PPS/slice headers. + The latter don't require zero-initialization since the codecparsers/ lib + will do so for key variables already. This is not a great value per se but + at least it makes it possible to check whether the default initialization + decisions made in the codecparsers/ lib were right or not. + This can be reverted if this exposes too many issues. + +2012-12-13 11:48:06 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: minor clean-ups. + Drop explicit initialization of most fields that are implicitly set to + zero. Drop helper macros for casting to GstVaapiPictureH264 or + GstVaapiFrameStore. Also remove some useless checks for NULL pointers. + +2012-12-07 17:45:03 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: drop GstVaapiSliceH264 object. + Use standard GstVaapiSlice object from now on since we already have + parsed and recorded the slice headers (GstH264SliceHdr decode units). + +2012-12-13 10:47:25 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: detect new pictures from decode-units. + Update is_new_picture() to cope with GstVaapiDecoderUnitH264, instead + of assuming frame boundaries when first_mb_in_slice is zero. + +2012-12-13 10:21:46 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: implement {start,end}_frame() hooks. + Implement GstVaapiDecoder.start_frame() and end_frame() semantics so + that to create new VA context earlier and submit VA pictures to the + HW for decoding as soon as possible. i.e. don't wait for the next + frame to start decoding the previous one. + +2012-12-12 18:33:52 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: optimize scan for the second start code. + Optimize scan for the second start code, on the next parse() call so that + to avoid scanning again earlier bytes where we didn't find any start code. + +2012-12-06 17:25:01 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: add codec specific decoder unit. + Introduce new GstVaapiDecoderUnitH264 object, which holds the standard + NAL unit header (GstH264NalUnit) and additional parsed header info. + Besides, we now parse headers as early as in the _parse() function so + that to avoid un-necessary creation of sub-buffers in _decode() for + NAL units that are not slices. + This is a performance win by ~+1.1% only. + +2012-12-04 11:01:42 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: handle sub video-buffers. + Intermediate elements may produce a sub-buffer from a valid GstVaapiVideoBuffer + for non raw YUV cases. Make sure vaapisink now understands those buffers. + +2012-12-12 15:22:32 +0100 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: use gst_vaapi_decoder_get_codec_state(). + Directly use the GstVideoCodecState associated with the VA decoder + instead of parsing caps again. + Signed-off-by: Sreerenj Balachandran + Signed-off-by: Gwenole Beauchesne + +2012-12-04 14:53:15 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: use more standard helpers. + Use g_clear_object() [glib >= 2.28] and gst_caps_replace() helper functions + in more places. + +2012-12-04 14:45:29 +0100 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: move to GstVideoDecoder base class. + Make vaapidecode derive from the standard GstVideoDecoder base element + class. This simplifies the code to the strict minimum for the decoder + element and makes it easier to port to GStreamer 1.x API. + Signed-off-by: Sreerenj Balachandran + Signed-off-by: Gwenole Beauchesne + +2012-12-06 14:02:25 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: initial port to new GstVaapiDecoder API + +2012-12-06 14:02:21 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: initial port to new GstVaapiDecoder API + +2012-12-06 14:02:17 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: initial port to new GstVaapiDecoder API + +2012-12-17 09:47:20 -0800 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + mpeg4: initial port to new GstVaapiDecoder API + +2012-12-06 14:01:46 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: initial port to new GstVaapiDecoder API. + +2012-12-12 15:09:21 +0100 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + decoder: use GstVideoCodecState. + Use standard GstVideoCodecState throughout GstVaapiDecoder and expose + it with a new gst_vaapi_decoder_get_codec_state() function. This makes + it possible to drop picture size (width, height) information, framerate + (fps_n, fps_d) information, pixel aspect ratio (par_n, par_d) information, + and interlace mode (is_interlaced field). + This is a new API with backwards compatibility maintained. In particular, + gst_vaapi_decoder_get_caps() is still available. + Signed-off-by: Sreerenj Balachandran + Signed-off-by: Gwenole Beauchesne + +2012-12-12 13:44:07 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * tests/test-decode.c: + * tests/test-subpicture.c: + decoder: update gst_vaapi_decoder_get_surface() semantics. + Align gst_vaapi_decoder_get_surface() semantics with the rest of the + API. That is, return a GstVaapiDecoderStatus and the decoded surface + as a handle to GstVaapiSurfaceProxy in parameter. + This is an API/ABI change. + +2012-12-07 16:40:44 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: use standard helper functions. + Use g_clear_object(), gst_buffer_replace() and gst_caps_replace() + whenever necessary. + +2012-11-29 15:06:00 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + decoder: expose new parse/decode API. + Introduce new decoding process whereby a GstVideoCodecFrame is created + first. Next, input stream buffers are accumulated into a GstAdapter, + that is then passed to the _parse() function. The GstVaapiDecoder object + accumulates all parsed units and when a complete frame or field is + detected, that GstVideoCodecFrame is passed to the _decode() function. + Ultimately, the caller receives a GstVaapiSurfaceProxy if decoding + process was successful. + +2012-12-13 10:20:35 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + decoder: add {start,end}_frame() hooks. + The start_frame() hook is called prior to traversing all decode-units + for decoding. The unit argument represents the first slice in the frame. + Some codecs (e.g. H.264) need to wait for the first slice in order to + determine the actual VA context parameters. + +2012-12-06 13:57:42 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: add new GstVaapiDecoder API. + Split decoding process into two steps: (i) parse incoming bitstreams + into simple decoder-units until the frame or field is complete; and + (ii) decode the whole frame or field at once. + This is an ABI change. + +2012-12-05 10:51:41 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.c: + * gst-libs/gst/vaapi/gstvaapidecoder_frame.h: + decoder: add new "decoder-frame" object. + Introduce a new GstVaapiDecoderFrame that is just a list of decoder units + (GstVaapiDecoderUnit objects) that constitute a frame. This object is just + an extension to GstVideoCodecFrame for VA decoder purposes. It is available + as the user-data member element. + This is a libgstvaapi internal object. + +2012-12-06 09:44:01 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.c: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.h: + decoder: add new "decoder-unit" object. + Introduce GstVaapiDecoderUnit which represents a fragment of the source + stream to be decoded. For instance, a decode-unit will be a NAL unit for + H.264 streams, an EBDU for VC-1 streams, and a video packet for MPEG-2 + streams. + This is a libgstvaapi internal object. + +2012-12-03 14:09:01 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + Port GstVaapiFrameStore to GstVaapiMiniObject. + +2012-12-03 11:19:08 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + Port codec objects to GstVaapiMiniObject. + +2012-12-03 13:46:28 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbuffer.c: + * tests/test-decode.c: + * tests/test-subpicture.c: + surfaceproxy: port to GstVaapiMiniObject. + GstVaapiSurfaceProxy does not use any particular functionality from + GObject. Actually, it only needs a basic object type with reference + counting. + This is an API and ABI change. + +2012-11-30 17:25:07 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiminiobject.c: + * gst-libs/gst/vaapi/gstvaapiminiobject.h: + Add GstVaapiMiniObject. + Introduce a new reference counted object that is very lightweight and + also provides flags and user-data functionalities. Initialization and + finalization times are reduced by up to a factor 5x vs GstMiniObject + from GStreamer 0.10 stack. + This is a libgstvaapi internal object. + +2012-12-17 02:51:17 -0800 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/test-decode.c: + * tests/test-mpeg4.c: + * tests/test-mpeg4.h: + tests: add test for MPEG-4:2 decoding. + +2012-12-17 04:42:29 -0800 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: initialize VA context before allocating the first slice. + Fix decode_slice() to ensure a VA context exists prior to creating a + new GstVaapiSliceH264, which invokes vaCreateBuffer() with some VA + context ID. i.e. the latter was not initialized, thus causing failures + on Cedar Trail for example. + +2012-12-05 09:15:32 +0800 Zhao Halley + + * configure.ac: + configure: install plugin elements in GST_PLUGIN_PATH, if set. + If GST_PLUGIN_PATH environment variable exists and points to a valid + directory, then use it as the system installation path for gst-vaapi + plugin elements. + Signed-off-by: Gwenole Beauchesne + +2012-12-17 14:27:56 +0100 Gwenole Beauchesne + + * configure.ac: + configure: downgrade glib required version to 2.28. + +2012-12-17 09:41:24 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/glibcompat.h: + * gst/vaapi/gstvaapi.c: + libs: fix compatibility with glib 2.28. + Always prefer non deprecated APIs by default and provide compatibility + glue for older glib versions when necessary. + +2012-12-17 10:10:55 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + libs: use glib >= 2.32 semantics for mutexes. + Use glib >= 2.32 semantics for GMutex and GRecMutex wrt. initialization + and termination. Basically, the new mutex objects can be used as static + mutex objects from the deprecated APIs, e.g. GStaticMutex and GStaticRecMutex. + +2012-12-17 04:15:53 -0800 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + libs: only export gst_vaapi_*() symbols. + This fixes symbol clashes between the gst-vaapi built-in codecparsers/ + library and the system-provided one, mainly used by videoparses/. Now, + only symbols with the gst_vaapi_* prefix will be exported, if they are + not marked as "hidden" to libgstvaapi. + +2012-11-20 18:21:41 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiuploader.c: + vaapiupload: reset direct-rendering to zero when changing caps. + Make sure to reset direct-rendering flag to zero when caps are changed, + and only derive it to one when the next checks succeed. + +2012-11-20 14:42:24 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiupload.c: + vaapiupload: fix sink caps to report the supported set of YUV caps. + Try to allocate the GstVaapiUploader helper object prior to listing the + supported image formats. Otherwise, only a single generic caps is output + with no particular pixel format referenced in there. + +2012-11-20 14:32:40 +0100 Zhao Halley + + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiupload.h: + vaapiupload: use new GstVaapiUploader helper. + Use GstVaapiUploader helper that automatically handles direct rendering + mode, thus making the "direct-rendering" property obsolete and hence it + is now removed. + The "direct-rendering" level 2, i.e. exposing VA surface buffers, was never + really well supported and it could actually trigger degraded performance. + Signed-off-by: Gwenole Beauchesne + +2012-11-20 15:50:56 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapiuploader.h: + vaapisink: compute and expose the supported set of YUV caps. + Make vaapisink expose only the set of supported caps for raw YUV buffers. + Add gst_vaapi_uploader_get_caps() helper function to determine the set + of supported YUV caps as source (for images). This function actually + tries to zero and upload each image to a 64x64 test surface. Of course, + this relies on VA drivers to not claim success if vaPutImage() is not + correctly supported. + +2012-11-20 14:28:55 +0100 Gwenole Beauchesne + + * NEWS: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + * gst/vaapi/gstvaapiuploader.c: + * gst/vaapi/gstvaapiuploader.h: + vaapisink: add support for raw YUV buffers. + Add new GstVaapiUploader helper to upload raw YUV buffers to VA surfaces. + It is up to the caller to negotiate source caps (for images) and output + caps (for surfaces). gst_vaapi_uploader_has_direct_rendering() is available + to help decide between the creation of a GstVaapiVideoBuffer or a regular + GstBuffer on sink pads. + Signed-off-by: Zhao Halley + Signed-off-by: Gwenole Beauchesne + +2012-11-20 14:36:29 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimage.c: + image: fix GstVaapiImage map and unmap. + Fix gst_vaapi_image_map() to return TRUE and the GstVaapiImageRaw + structure correctly filled in if the image was already mapped. + Likewise, make gst_vaapi_image_unmap() return TRUE if the image + was already unmapped. + +2012-10-30 13:15:45 +0800 Wind Yuan + + * NEWS: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + videobuffer: fix memory leak for surface and image. + Fix reference leak of surface and image in GstVaapiVideoBuffer wrapper, + thus resulting on actual memory leak of GstVaapiImage when using them + for downloads/uploads from VA surfaces and more specifically surfaces + when the pipeline is shutdown. i.e. vaTerminate() was never called + because the resources were not unreferenced, and thus not deallocated + in the end. + Signed-off-by: Gwenole Beauchesne + +2012-11-19 10:04:52 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2012-11-16 18:00:10 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix picture size in macroblocks. + The picture size signalled by sps->{width,height} is the actual size with + cropping applied, not the original size derived from pic_width_in_mbs_minus1 + and pic_height_in_map_units_minus1. VA driver expects that original size, + uncropped. + There is another issue pending: frame cropping information needs to be + taken care of. + +2012-11-16 16:18:52 +0100 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/Makefile.am: + codecparsers: always build parserutils first. + Fix commit 18245b4 so that to link and build parserutils.[ch] first. + This is needed since that's the common dependency for actual codec + parsers (gstvc1parser.c for instance). + +2012-11-15 17:50:45 +0100 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/Makefile.am: + codecparsers: always build the VC-1 parser library. + ... this is useful to make sure pixel-aspect-ratio and framerate + information are correctly parsed since we have no means to detect + that at configure time. + +2012-11-08 11:40:47 +0200 Sreerenj Balachandran + + * configure.ac: + * gst-libs/gst/codecparsers/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix PAR calculation from commit bd11bae. + Invoke gst_mpeg_video_finalise_mpeg2_sequence_header() to get the + correct PAR values. While doing so, require a newer version of the + bitstream parser library. + Note: it may be necessary to also parse the Sequence_Display_Extension() + header. + Signed-off-by: Sreerenj Balachandran + Signed-off-by: Gwenole Beauchesne + +2012-11-15 15:00:43 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + Fix build with the GNU gold linker. + In particular, fix libgstvaapi-glx DSO dependencies to include libgstbase + and libgstvideo libs, e.g. for gst_video_buffer_get_overlay_composition(). + +2012-11-02 18:18:37 +0000 Rob Bradford + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: port to 1.0 version of the protocol. + This patch updates to relect the 1.0 version of the protocol. The main + changes are the switch to wl_registry for global object notifications + and the way that the event queue and file descriptor is processed. + Signed-off-by: Gwenole Beauchesne + +2012-11-14 19:22:13 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix incorrect integration of previous commit (4d31e1e). + git am got confused somehow, though the end result doesn't change at + all since we require both SPS and PPS to be parsed prior to decoding + the first slice. + +2012-11-14 18:40:47 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: start decoding slices after first SPS/PPS activation. + Only start decoding slices when at least one SPS and PPS got activated. + This fixes cases when a source represents a substream of another stream + and no SPS and PPS was inserted before the first slice of the generated + substream. + +2012-11-14 14:25:34 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix VAPictureParameterBufferH264.ReferenceFrames[] construction. + ... for interlaced streams. The short_ref[] and long_ref[] arrays may + contain up to 32 fields but VA ReferenceFrames[] array expects up to + 16 reference frames, thus including both fields. + +2012-11-14 10:27:12 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix interlaced stream decoding with MMCO. + Fix decoding of interlaced streams when adaptive_ref_pic_marking_mode_flag + is equal to 1, i.e. when memory management control operations are used. In + particular, when field_pic_flag is set to 0, the new reference flags shall + be applied to both fields. + +2012-11-13 17:14:39 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: add initial support for interlaced streams. + Decoded frames are only output when they are complete, i.e. when both + fields are decoded. This also means that the "interlaced" caps is not + propagated to vaapipostproc or vaapisink elements. Another limitation + is that interlaced bitstreams with MMCO are unlikely to work. + +2012-11-13 16:35:30 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: split remove_reference_at() into finer units. + Split remove_reference_at() into a function that actually removes the + specified entry from the short-term or long-term reference picture array, + and a function that sets reference flags to the desired value, possibly + zero. The latters marks the picture as "unused for reference". + +2012-10-23 14:04:22 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + decoder: fix gst_vaapi_picture_new_field() object type. + Fix gst_vaapi_picture_new_field() to preserve the original picture type. + e.g. gst_vaapi_picture_new_field() with a GstVaapiPictureH264 argument + shall generate a GstVaapiPictureH264 object. + +2012-11-13 14:04:31 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: add picture structure for reference picture marking process. + Introduce new `structure' field to the H.264 specific picture structure + so that to simplify the reference picture marking process. That local + picture structure is derived from the original picture structure, as + defined by the syntax elements field_pic_flag and bottom_field_flag. + +2012-11-02 15:14:58 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: introduce new frame store structure. + The frame store represents a Decoded Picture Buffer entry, which can + hold up to two fields. So far, the frame store is only used to hold + full frames. + +2012-11-13 10:10:31 +0100 Gwenole Beauchesne + + * ext/codecparsers: + codecparsers: update to gst-vaapi-rebased commit 73d6aab. + 73d6aab h264: fix rbsp_more_data() implementation + 25d04cf h264: fix error code for invalid size parsed in SPS + 84798e5 fix FSF address + +2012-10-31 16:37:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: minor clean-ups. + Move DPB flush up if the current picture to decode is an IDR. Besides, + don't bother to check for IDR pictures in dpb_add() function since an + explicit DPB flush was already performed in this case. + +2012-10-31 14:24:09 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: simplify reference picture marking process. + ... to build the short_ref[] and long_ref[] lists from the DPB, instead + of maintaining them separately. This avoids refs/unrefs while making it + possible to generate the list based on the actual picture structure. + This also ensures that the list of generated ReferenceFrames[] actually + matches what reference frames are available in the DPB. i.e. short_ref[] + and long_ref[] entries are implied from the DPB, so there is no risk of + having "dangling" references. + +2012-10-31 11:52:03 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: introduce per-field POC in GstVaapiPictureH264. + Use the POC member available in the GstVaapiPicture base class and + get rid of the dependency on the local VAPictureH264 TopFieldOrderCnt + and BottomFieldOrderCnt. Rather, use a simple field_poc[] array + initialized to INT_MAX, so that to simplify picture POC calculation + for non frame pictures. + +2012-10-31 11:45:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: introduce GST_VAAPI_PICTURE_{SHORT,LONG}_TERM_REFERENCE flags. + Further get rid of GstVaapiPictureH264-local VAPictureH264.flags for + reference bits, thus simplifying the reference picture marking process + to only track a single set of reference flags. Also introduce a new + long_term_frame_idx member. + +2012-10-31 11:33:40 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: introduce GST_VAAPI_PICTURE_FLAG_IDR flag. + +2012-10-31 10:56:15 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fill in GstVaapiPicture structure. + ... and get rid of local VAPictureH264.flags fields in GstVaapiPictureH264. + +2012-10-31 11:07:48 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: add vaapi_fill_picture() helper. + Add vaapi_fill_picture() helper function to convert GstVaapiPictureH264 + to VAPictureH264 structure. This is preparatory work to get rid of the + local VAPictureH264 member in GstVaapiPictureH264. + +2012-10-26 16:12:05 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix activation order of picture and sequence parameters. + Delay ensure_context() until we actually need a VA context for allocating + new VA surfaces, and then GstVaapiPictures, but also when a real activation + of a new picture parameter set occurs, thus also implying an activation + of the related sequence parameter set. + The most important thing was to drop the global pps and sps pointers since + they may not have matched the currently activated picture parameter or + sequence parameter sets at the specified decode point. + Anoter positive side-effect is that this cleans up all occurrences of + decode_current_picture() to only keep those useful in decode_picture(), + before a new picture is allocated, or in decode_sequence_end() when + an end-of-stream or end-of-sequence condition occurred. + +2012-10-26 13:17:43 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix scaling list generation. + ... aka fix regression from efaab79. In particular, ScalingList8x8[] + array was partially copied to the VAIQMatrixBufferH264. While we are + at it, also improve bounds checking and avoid copying 8x8 scaling + lists if transform_8x8_mode_flag is set to 0. + +2012-10-24 18:23:09 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix detection of picture boundaries. + Strictly follow the standard (7.4.1.2.4) to detect the first VCL NAL + unit of a primary coded picture. + +2012-10-23 14:50:14 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: optimize handling of scaling lists. + Don't copy scaling lists twice to an intermediate state. Rather, directly + use the scaling lists from GstH264PPS since they would match those provided + by SPS header, if necessary. i.e. if PPS-specific scaling lists are not + available in the bitstream. + +2012-10-23 10:33:50 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: simplify code when MMCO is 5. + Remove exit_picture() and exit_picture_poc() since PicOrderCnt(CurrPic) + is now updated accordingly to the standard. Besides, MMCO = 5 specific + operations are moved up to exec_ref_pic_marking_adaptive_mmco_5(). + +2012-10-22 11:52:13 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix MMCO-based reference picture marking process. + Fix adaptive memory control decoded reference picture marking process + implementation for operations 2 to 6, thus also fixing support for + long-term reference pictures. + +2012-10-22 10:50:29 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: move MMCO handlers out of the loop (cosmetics). + This change only splits each individual MMCO handler into several functions + dedicated for each operation. This is needed to perform further work later + on. + +2012-10-17 15:49:23 +0200 Gwenole Beauchesne + + * Makefile.am: + debian: fix make dist for packaging. + bzip2 tarballs are now used, so update the deb.upstream dependencies + to include dist-bzip2 instead of plain old dist, and use the correct + tar extract options to handle that format. + +2012-10-17 15:42:17 +0200 Gwenole Beauchesne + + * configure.ac: + configure: generate bzip2 tarballs in ustar format by default. + +2012-10-17 15:38:14 +0200 Gwenole Beauchesne + + * configure.ac: + configure: bump glib required version to 2.31.2. + Use new Thread API. In particular, g_mutex_init() and g_cond_init() + rather than g_mutex_new() and g_cond_new() respectively. + +2012-10-04 17:39:53 +0100 Rob Bradford + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: adopt non-deprecrated glib locking primitive pattern. + The use of heap allocated GMutex/GCond is deprecated. Instead place them + inside the structure they are locking. + These changes switch to use g_mutex_init/g_cond_init rather than the heap + allocation functions. + Because we cannot test for a NULL pointer for the GMutex/GCond we must + initialise inside the GObject _init function and clear inside the _finalize + which is guaranteed to only be called once and after the object is no longer + in use. + +2012-10-17 14:52:35 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix compiler warnings. + Don't care of the return value for gst_vaapi_decoder_put_buffer() + during destruction of the element. Don't print out (uninitialised) + error code when allocation of video buffer failed. + +2012-10-16 16:52:04 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: add flag to compile with strict DPB ordering mode. + Allow build with strict DPB ordering mode whereby evicted entries + are replaced by the next entries, in order instead of optimizing + it away with the last entry in the DPB. + This is only useful for debugging purpose, against a reference SW + decoder for example. + +2012-10-16 16:46:17 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: drop extra code covered by built-in codecparsers. + GstH264SliceHdr.n_emulation_prevention_bytes is bound to exist now that + a newer version of codecparsers/ are used if the system provided one is + now recent enough to have those required extensions. + +2012-10-16 16:43:43 +0200 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/Makefile.am: + codecparsers: fix generation of symlinks. + Try to improve dependencies while generating symlinks to externally + maintained copy of codecparsers (derived from upstream git master + tree). + +2012-10-11 15:04:12 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: use framerate information from bitstream parser. + +2012-09-27 18:05:46 +0100 Simon Farnsworth + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: use pixel-aspect-ratio from bitstream parser. + Signed-off-by: Simon Farnsworth + Signed-off-by: Gwenole Beauchesne + +2012-09-27 18:05:46 +0100 Simon Farnsworth + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: use pixel-aspec-ratio information from bitstream parser. + Signed-off-by: Simon Farnsworth + Signed-off-by: Gwenole Beauchesne + +2012-10-11 13:49:14 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/codecparsers/Makefile.am: + codecparsers: h264: use submodule sources. + Use newer sources from the codecparsers/ submodule for + - GstH264SliceHdr.n_emulation_prevention_bytes: EPBs; + - GstH264VUIParams.{par_n,par_d}: pixel-aspect-ratio. + +2012-10-11 13:23:02 +0200 Gwenole Beauchesne + + * .gitignore: + * configure.ac: + * gst-libs/gst/codecparsers/Makefile.am: + * gst-libs/gst/codecparsers/gstjpegparser.c: + * gst-libs/gst/codecparsers/gstjpegparser.h: + * gst-libs/gst/vaapi/Makefile.am: + codecparsers: jpeg: use submodule sources. + +2012-10-11 10:03:14 +0200 Gwenole Beauchesne + + * .gitmodules: + * Makefile.am: + * autogen.sh: + * configure.ac: + * ext/Makefile.am: + * ext/codecparsers: + Add codecparsers submodule. + +2012-10-11 14:17:12 +0200 Gwenole Beauchesne + + * .gitignore: + .gitignore: updates. + +2012-10-11 13:40:37 +0200 Gwenole Beauchesne + + * autogen.sh: + autogen: fix check for gtkdocize and autoreconf. + If gtkdocize or autoreconf programs were not found, then the autogen.sh + script would fail to report that correctly because test -z was not passed + any argument (empty string "" in this case). + +2012-09-27 18:05:46 +0100 Simon Farnsworth + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: use pixel-aspect-ratio from SPS header. + Propagate pixel-aspect-ratio determined by the GStreamer codecparser + from the sequence headers. + Signed-off-by: Simon Farnsworth + Signed-off-by: Gwenole Beauchesne + +2012-10-10 10:35:20 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: add decode_nalu() helper function. + Split decode_buffer() into the core infrastructure that determines + the NAL units contained in the adapter and the actual function that + decodes the NAL unit. + +2012-10-10 10:31:39 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix end-of-stream conditions (flush). + Decode pending data in the adapter prior to processing the actual + code for end-of-stream. + +2012-10-10 09:45:03 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: add decode_packet() helper function. + Split decode_buffer() into the core infrastructure that determines + the packets contained in the adapter and the actual function that + decodes the packet data. + +2012-10-09 15:34:18 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix end-of-stream conditions (flush). + Decode pending data in the adapter prior to processing the actual + code for end-of-stream. Initial code from Feng Yuan. + +2012-10-09 15:40:49 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix memory leak of empty packets. + Fix memory leakage of empty packets, i.e. packets that only contain + the start code prefix. In particular, free empty user-data packets. + Besides, the codec parser will already fail gracefully if the packet + to parse does not have the minimum required size. So, we can also + completely drop the block of code that used to handle packets of size 4 + (including the start code). + +2012-10-09 15:01:38 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix return value for "no-data" conditions. + Fix return value when the second scan for start code fails. This means + there is not enough data to determine the full extents of the current + packet and the function shall return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA + in this case, instead of GST_VAAPI_DECODER_STATUS_SUCCESS. + +2012-10-09 14:48:00 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: refine semantics of gst_vaapi_decoder_put_buffer(). + Improve the semantics for gst_vaapi_decoder_put_buffer() when an empty + buffer is passed on. An empty buffer is a buffer with a NULL data pointer + or with a size equals to zero. In this case, that buffer is simply + skipped and the function returns TRUE. A NULL buffer argument still + marks the end-of-stream. + +2012-10-09 14:40:00 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: drop unused functions. + +2012-08-26 22:29:04 -0400 Wind Yuan + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: flush buffers when receiving EOS. + Signed-off-by: Gwenole Beauchesne + +2012-10-05 13:36:27 +0200 Gwenole Beauchesne + + * debian.upstream/Makefile.am: + debian: fix make dist for packaging. + +2012-10-05 12:06:27 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: cosmetics (remove tabs). + +2012-10-04 17:39:52 +0100 Rob Bradford + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: add support for windowed mode. + Rather than always making the surface fullscreen instead implement the + set_fullscreen vfunc on GstVaapiWindow and then set the shell surface + fullscreen on not depending on that. + Reviewed-by: Joe Konno + Signed-off-by: Gwenole Beauchesne + +2012-10-01 09:21:03 +0200 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2012-09-28 17:54:03 +0200 Gwenole Beauchesne + + * README: + * configure.ac: + Fix and document build dependencies better. + +2012-09-28 17:41:42 +0200 Gwenole Beauchesne + + * debian.upstream/control.in: + debian: fix GStreamer build dependencies. + +2012-09-28 17:39:43 +0200 Gwenole Beauchesne + + * configure.ac: + * debian.upstream/control.in: + debian: fix Wayland build dependencies. + +2012-09-28 17:38:17 +0200 Gwenole Beauchesne + + * debian.upstream/control.in: + debian: fix conditional build of packages. + Make it still possible to build package even if one of the build dependencies + for a specific video backend is not available. + +2012-09-27 11:08:58 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + utils: drop unused GLX helpers. + Remove helpers for GL_ARB_fragment_program and GL_ARB_multitexture + extensions since they are not used throughout gstreamer-vaapi. + +2012-09-27 11:04:24 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + utils: fix build with version >= 85. + Mesa recently updated the header version to Khronos version 85. + This caused the PFNGLMULTITEXCOORD2FPROC definition to be moved out of the + GL_VERSION_1_3_DEPRECATED block. However, since also defines + GL_VERSION_1_3 to 1, the definitions in are then not enabled, + thus leaving PFNGLMULTITEXCOORD2FPROC undefined as well. + Provide a PFNGLMULTITEXCOORD2FPROC replacement as an interim solution for + newer versions of the header. + +2012-09-26 16:33:16 +0200 Gwenole Beauchesne + + * configure.ac: + configure: update VA-API version requirements. + VA/DRM and VA/Wayland API are now promoted to VA-API 0.33.0 (libva 1.1.0). + +2012-09-21 16:43:38 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: review and report errors accordingly. + Use GST_ERROR() to report real errors instead of hiding them into + GST_DEBUG(). + +2012-09-20 17:58:21 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: exclusively use GstAdapter, drop sub-buffer hack. + Maintaining the sub-buffer is rather suboptimal especially since we + were also maintaining a GstAdapter. Now, we only use the GstAdapter + thus requiring minor extra parsing when receiving avcC buffers. + +2012-09-20 16:18:27 +0200 Gwenole Beauchesne + + * README: + README: updates. + +2012-09-20 16:02:39 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2012-09-20 14:38:15 +0200 Gwenole Beauchesne + + * debian.upstream/gstreamer-vaapi.install.in: + debian: fix packaging on recent Ubuntu platforms. + Use explicit GStreamer plugins path. + +2012-09-17 17:55:43 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs.core.types: + docs: fix build for make dist. + +2012-09-14 10:30:35 -0400 Kristian Høgsberg + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: set opaque region for YUV surface. + This allows the compositor to optimize redraws and cull away changes + obscured by the video surface. + Signed-off-by: Gwenole Beauchesne + +2012-09-14 17:30:19 +0200 Gwenole Beauchesne + + * configure.ac: + configure: fix check for libva-glx and libva-drm. + +2012-09-12 13:42:49 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/glibcompat.h: + glibcompat: add replacement for g_cond_wait_until(). + +2012-09-12 13:41:47 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: include "sysdeps.h" instead of "config.h". + +2012-09-12 10:40:06 +0200 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/gstjpegparser.c: + codecparsers: jpeg: add missing includes. + +2012-09-11 17:03:33 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst/vaapi/gstvaapidecode.c: + vaapidecode: don't reset decoder if codec type is the same. + Reset, i.e. destroy then create, the decoder in _setcaps() handler only + if the underlying codec type actually changed. This makes it possible + to be more tolerant with certain MPEG-2 streams that get parsed to + form caps that are compatible with the previous state but minor changes + to "codec-data". + +2012-09-11 16:41:32 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: simplify codec lookup from caps. + Add new gst_vaapi_codec_from_caps() helper to determine codec type from + the specified caps. Don't globally expose this function since this is + really trivial and only used in the vaapidecode element. + +2012-09-11 15:54:20 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: improve "no free surface" conditions. + Previously, vaapidecode would wait up to one second until a free surface + is available, or it aborts decoding. Now, vaapidecode waits until the + last decoded surface was to be presented, plus one second. Besides, end + times are now expressed relative to the monotonic clock. + +2012-09-11 10:59:33 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst/vaapi/gstvaapidecode.c: + decoder: propagate buffer duration downstream. + +2012-09-11 10:59:10 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + surfaceproxy: add "duration" property. + +2012-09-10 18:26:51 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: cope with new GstVaapiContextInfo based API. + Update decoders to report the maximum number of reference frames to use. + +2012-09-10 18:17:10 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + context: JPEG codec does not need any reference frame. + +2012-09-10 18:15:02 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + context: allow number of reference frames to be set. + Make it possible to specify the maximum number of references to use within + a single VA context. This helps reducing GPU memory allocations to the useful + number of references to be used. + +2012-09-07 16:41:16 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix deinterlace-{mode,method} types definition. + +2012-09-07 16:15:40 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + mpeg4: fix debug info for unsupported profile. + +2012-09-07 16:14:11 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + libs: fix build in strict ISO C mode. + +2012-09-07 16:11:12 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: fix build in strict ISO C mode. + +2012-09-07 15:31:09 +0200 Gwenole Beauchesne + + * pkgconfig/gstreamer-vaapi-glx.pc.in: + * pkgconfig/gstreamer-vaapi-x11.pc.in: + * pkgconfig/gstreamer-vaapi.pc.in: + pkgconfig: fix dependencies and slightly improve description. + Drop @LIBVA_EXTRA_{CFLAGS,LIBS}@ substitutions and slightly improve + descriptions with clearer renderer names. + +2012-09-04 13:54:19 +0200 Philip Lorenz + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: acquire lock only if the mutex exists. + When playback stops the GstVaapiDecode object is reset into a clean + state. However, surfaces may still be referenced by library users and + unreferencing them after the reset triggers an access to an unset mutex. + Signed-off-by: Gwenole Beauchesne + +2012-09-07 11:58:53 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: drop extraneous return for void function. + +2012-09-07 11:57:59 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimage.c: + image: don't use (void *) pointer arithmetic. + +2012-09-04 13:40:04 +0200 Philip Lorenz + + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst/vaapi/gstvaapipostproc.h: + Do not forward declare enums. + Forward declaring enums is not allowed by the C standard and aborts + compilation if the header file is included in a C++ project. + Signed-off-by: Gwenole Beauchesne + +2012-09-07 11:44:44 +0200 Gwenole Beauchesne + + * configure.ac: + configure: fix check for VA/DRM API. + +2012-09-04 11:53:18 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix calculation of window size. + If either dimension is out-of-bounds, then scale window to fit the + display size, even if the output is to be rotated. Use the standard + gst_video_sink_center_rect() function to center and scale the window + wrt. the outer (display) bounds. + +2012-08-28 02:45:22 -0400 Wind Yuan + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: add video rotation support. + Signed-off-by: Gwenole Beauchesne + +2012-09-06 11:47:40 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.h: + pluginutils: add G_PRIMITIVE_SWAP() helper macro. + This macro helps swapping variables while maintaining the correct underlying + and primitive type. + +2012-09-06 11:51:41 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: fix display aspect ratio when display is rotated. + +2012-09-06 11:50:21 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + display: fix physical display size when display is rotated. + +2012-08-30 16:27:56 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapivalue.c: + display: fix GstVaapiRotation enumeration of values. + +2012-08-29 13:18:05 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapivideosink.c: + * gst-libs/gst/vaapi/gstvaapivideosink.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + vaapisink: drop obsolete GstVaapiVideoSink interface. + This interface was deprecated since 0.3.x series when the GstVideoContext + interface was added to the main GStreamer APIs. + +2012-08-27 18:34:27 +0300 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: automatically detect overlay rendering mode. + Retain the VA surface until another surface is to be displayed only + if VA display rendering mode is determined to be "overlay" mode. + +2012-08-24 16:30:33 +0300 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: retain VA surface until another one is displayed. + Keep VA surface proxy associated with the surface that is currently + being displayed. This makes sure that surface is not released back + to the pool of surfaces free to use for decoding. This is necessary + with VA driver implementations that support rendering to an overlay + pipe. Otherwise, there could be cases where we are decoding into a + surface that is being displayed, hence some flickering. + +2012-08-24 14:54:16 +0300 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.h: + vaapisink: fix build with older toolchains. + Don't re-declare GstVaapiTexture if USE_GLX mode is set. + +2012-08-29 10:13:58 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: partially revert 8ebe4d6. + Don't try to fix up the initial values, this could make things worse. + Simply assume the driver does not support the capability in this case. + +2012-08-28 16:08:34 +0200 Gwenole Beauchesne + + * tests/test-display.c: + tests: dump VA display properties. + +2012-08-28 18:11:32 +0300 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: fix validation process of properties during discovery. + Some VA drivers (e.g. EMGD) can have completely random values for initial + display attributes. So, try to improve the discovery process to check the + initial display attribute values actually fall within valid bounds. If not, + try to reset those to some sensible values like the default value reported + through vaQueryDisplayAttributes(). + +2012-08-28 13:59:50 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + display: add color balance properties. + Add support for hue, saturation, brightness and contrast attributes. + +2012-08-28 14:05:16 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: initialize default attribute values. + Ensure the display attribute is actually supported by trying to retrieve + its current value during GstVaapiDisplay creation. + +2012-08-28 11:09:56 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: raise "notify" for property changes. + +2012-08-28 10:55:59 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + display: expose display attributes as GObject properties. + Expose VA display "render-mode" and "rotation" attributes as standard + GObject properties. + +2012-08-28 16:24:15 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: install properties in batch. + Use g_object_class_install_properties() to install GstVaapiDisplay properties. + It is useful to maintain properties as GParamSpec so that to be able to raise + "notify" signals by id instead of by name in the future. + +2012-08-27 19:00:37 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: fix gst_vaapi_display_has_property(). + Append the "render-mode" and "rotation" properties, should they be supported + by the underlying VA driver. + +2012-08-22 02:18:11 -0400 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + display: add support for rotation modes. + Signed-off-by: Gwenole Beauchesne + +2012-08-27 18:11:37 +0300 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + display: add support for rendering modes. + A rendering mode can be "overlay" or "texture"'ed blit. + The former mode implies that a VA surface used for rendering can't be + re-used right away for decoding, so the sink shall make provisions to + retain the associated surface proxy until the next surface is to be + displayed. + The latter mode implies that the VA surface is implicitly copied to an + intermediate backing store, or back buffer of a frame buffer, so the + associated surface proxy can be disposed right away. + +2012-08-27 17:02:49 +0300 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + display: add initial support for display attributes. + The VA display attributes are mapped to properties so that to maintain the + GStreamer terminology. Properties are to be identified by name, but internal + functions are available to lookup the property by the actual VA display + attribute type. + +2012-08-24 11:36:16 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: fix end-of-image (EOI) handler. + decode_current_picture() was converted to return a gboolean instead + of a GstVaapiDecoderStatus, so we were not getting out of the decode + loop as expected, or could cause an error instead. + Signed-off-by: Gwenole Beauchesne + +2012-08-24 18:41:47 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: include start code into VA slice data buffer. + Integrate the start code prefix in the slice data buffer that is submitted + to the hardware. VA-API specifies that slice_data_offset is the offset to + the first byte of slice data. And, for MPEG-2, slice() data begins with + the slice_start_code. Some VA driver implementations (EMGD) expect this. + +2012-06-28 01:08:03 +0900 Javier Jardón + + * autogen.sh: + autogen: fix configure script generation when srcdir != builddir. + This patch allows for regenerating the configure script from a build + directory that is not the actual source directory. + Signed-off-by: Gwenole Beauchesne + +2012-06-28 00:22:03 +0900 Javier Jardón + + * configure.ac: + configure: use new libtool syntax. + This now requires libtool >= 2.2 to regenerate the configure script. + Signed-off-by: Gwenole Beauchesne + +2012-08-08 12:50:41 +0900 Javier Jardón + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: use g_object_notify_by_pspec(). + Use g_object_notify_by_pspec() instead of g_object_notify() so that to + avoid a property name lookup. i.e. this makes notifications faster to + the `vaapidecode' element. + Signed-off-by: Gwenole Beauchesne + +2012-08-06 19:21:03 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: handle de-interlacing flags. + VA/Wayland API was updated to allow flags for bob deinterlacing. + More elaborated filters will require a complete VA/VPP pipeline. + +2012-08-02 18:27:48 +0200 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/gstjpegparser.c: + jpeg: fix default quantization tables. + Two elements in the luminance quantization table were wrong. So, + gst_jpeg_get_default_quantization_tables() now reconstructs tables + in zig-zag order from the standard ones (Tables K.1 and K.2). + +2012-08-02 15:17:57 +0200 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/gstjpegparser.c: + jpeg: compute default Huffman tables. + ... instead of having them pre-calculated. This saves around 1.5 KB + of data in the DSO but requires gst_jpeg_get_default_huffman_tables() + to do more work. Though, the client application may have to call that + function at most once, only. + +2012-08-01 18:30:27 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: drop VAProfileNone entries from debug messages. + +2012-07-31 18:24:14 +0800 Yan Yin + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: query for supported display attributes. + Signed-off-by: Gwenole Beauchesne + +2012-07-31 18:22:48 +0800 Yan Yin + + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + utils: add string_of_VADisplayAttributeType() helper. + Signed-off-by: Gwenole Beauchesne + +2012-08-01 15:46:35 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: handle VA/DRM API. + This is not useful in practice but for raw performance evaluation when + the sink is invoked with display=drm sync=false. fakesink could also be + used though. + +2012-08-01 15:46:19 +0200 Gwenole Beauchesne + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapipluginutil.c: + plugins: add support for headless pipelines. + +2012-08-01 15:44:49 +0200 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/output.c: + * tests/test-display.c: + * tests/test-windows.c: + tests: add support for headless decoding. + +2012-08-01 15:44:02 +0200 Gwenole Beauchesne + + * NEWS: + * configure.ac: + * debian.upstream/Makefile.am: + * debian.upstream/control.in: + * debian.upstream/libgstvaapi-drm.install.in: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.c: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.h: + * pkgconfig/Makefile.am: + * pkgconfig/gstreamer-vaapi-drm.pc.in: + Add initial support for VA/DRM. + +2012-07-31 17:58:43 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + Fix build without X11 (again). + Don't try to build libgstvaapi-x11.so.* if X11 was disabled. Also shuffle + files list wrt. x11, glx and wayland backends. + +2012-07-31 11:51:57 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: update to the latest VA-API changes (0.32.1+). + +2012-07-27 14:27:05 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst/vaapi/gstvaapisink.c: + wayland: implement display ::get_size*() hooks. + +2012-07-27 10:45:41 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + plugins: prefer X11 rendering over GLX. + Prefer X11 display over GLX so that "vaapisink" uses X11, i.e. vaPutSurface(), + for rendering instead of texturing. + +2012-07-26 09:28:51 -0400 Kristian Høgsberg + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: use scale fullscreen method. + This makes the compositor scale the surface to fit and preserves aspect + ratio. + Signed-off-by: Gwenole Beauchesne + +2012-07-26 09:27:47 -0400 Kristian Høgsberg + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: respond to ping/pong protocol so we're not deemed unresponsive. + Signed-off-by: Gwenole Beauchesne + +2012-07-25 10:39:04 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + wayland: fix double disconnect of display. + +2012-07-24 19:58:55 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + wayland: mangle display name for cache lookups. + +2012-07-24 15:43:44 +0200 Gwenole Beauchesne + + * configure.ac: + * debian.upstream/Makefile.am: + * debian.upstream/control.in: + * debian.upstream/libgstvaapi-wayland.install.in: + * pkgconfig/Makefile.am: + * pkgconfig/gstreamer-vaapi-wayland.pc.in: + wayland: add packaging files. + +2012-07-24 15:07:48 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapisink.c: + * pkgconfig/Makefile.am: + Fix build without X11. + +2012-07-24 09:45:25 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapisink.c: + plugins: add support for Wayland. + +2012-07-23 12:56:33 +0200 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/output.c: + * tests/test-display.c: + * tests/test-windows.c: + tests: add support for Wayland. + +2012-07-19 10:27:23 +0200 Sreerenj Balachandran + + * NEWS: + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.h: + Add initial support for VA/Wayland. + Signed-off-by: Gwenole Beauchesne + +2012-07-25 15:11:51 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginbuffer.c: + plugins: fix creation of video buffer from surface proxy. + Fix a regression introduced with commit 8ef490a. + +2012-07-25 14:51:28 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginbuffer.c: + * gst/vaapi/gstvaapipluginutil.c: + plugins: use new display types more. + In particular, simplify gst_vaapi_reply_to_query() with display types. + Likewise for creating new video buffers. + +2012-07-25 10:02:29 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: fix display type selection and propagation. + If vaapisink is in the GStreamer pipeline, then we shall allocate a + unique GstVaapiDisplay and propagate it upstream. i.e. subsequent + queries from vaapidecode shall get a valid answer from vaapisink. + +2012-07-25 11:37:26 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: fix destruction of mutex. + +2012-07-25 09:16:02 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapisink.c: + display: add display types. + Move display types from gstvaapipluginutil.* to gstvaapidisplay.* so that + we could simplify characterization of a GstVaapiDisplay. Also rename "auto" + type to "any", and add a "display-type" attribute. + +2012-07-24 19:43:40 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + display: use prefixed display names for cache lookups. + This improves display name comparisons by always allocating a valid display + name. This also helps to disambiguate lookups by name in the global display + cache, should a new backend be implemented. + +2012-07-24 16:14:51 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.h: + plugins: declare helper functions as internal. + +2012-07-24 14:31:25 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipluginbuffer.c: + * gst/vaapi/gstvaapipluginbuffer.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapiupload.c: + videobuffer: drop deprecated functions. + Move video buffer creation routines to plugin elements. That exclusively + uses *_typed_new*() variants. + +2012-07-24 14:09:09 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h: + videobuffer: mark video buffer creation routines as deprecated. + The vdeo buffer creation routines shall actually be internal to gstreamer-vaapi + plugin elements. So deprecate any explicit creation routines that are not the + new *_typed_new*() variants. + +2012-07-24 13:52:06 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h: + videobuffer: factor out base and GLX implementations. + Introduce new typed constructors internal to gstreamer-vaapi plugin elements. + This avoids duplication of code, and makes it possible to further implement + generic video buffer creation routines that automatically map to base or GLX + variants. + +2012-07-24 10:58:32 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + utils: fix gl_create_context() with parent context set. + If GLX window was created from a foreign Display, then that same Display shall + be used for subsequent glXMakeCurrent(). This means that gl_create_context() + will now use the same Display that the parent, if available. + This fixes cluttersink with the Intel GenX VA driver. + +2012-07-23 18:37:38 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + pluginutils: improve automatic display type selection. + +2012-07-23 18:01:26 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + pluginutils: cosmetics (indentation fixes). + +2012-07-23 17:54:58 +0200 Gwenole Beauchesne + + * configure.ac: + configure: simplify video outputs summary. + +2012-07-23 17:49:08 +0200 Gwenole Beauchesne + + * configure.ac: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + configure: drop check for --enable-vaapisink-glx. + vaapisink is now built with support for multiple display types, whenever + they are enabled. The new "display" attribute is used to select a particular + renderer. + +2012-07-23 16:15:38 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapiupload.c: + * tests/test-display.c: + configure: drop check for --enable-vaapi-glx. + This flag is obsolete. It was meant to explicitly enable/disable VA/GLX API + support, or fallback to TFP+FBO if this API is not found. Now, we check for + the VA/GLX API by default if --enable-glx is set. If this API is not found, + we now default to use TFP+FBO. + Note: TFP+FBO, i.e. using vaPutSurface() is now also a deprecated usage and + will be removed in the future. If GLX rendering is requested, then the VA/GLX + API shall be used as it covers most usages. e.g. AMD driver can't render to + an X pixmap yet. + +2012-07-23 15:20:23 +0200 Gwenole Beauchesne + + * tests/output.c: + tests: allow GLX output, if available and selected. + +2012-07-23 15:17:03 +0200 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/output.c: + * tests/output.h: + * tests/test-decode.c: + * tests/test-subpicture.c: + * tests/test-surfaces.c: + tests: use common display and window creation routines. + Add new --output option to select the renderer. Use --list-outputs to + print a list of supported renderers. + +2012-07-23 14:15:42 +0200 Gwenole Beauchesne + + * tests/Makefile.am: + tests: move encoded bitstreams to libutils.la. + +2012-07-23 14:11:16 +0200 Gwenole Beauchesne + + * tests/Makefile.am: + tests: build convenience library for common utilities. + +2012-07-20 16:37:01 +0200 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/test-display.c: + tests: simplify build with various display options. + +2012-07-23 13:28:42 +0200 Gwenole Beauchesne + + * configure.ac: + configure: improve checks for X11. + +2012-07-20 15:57:26 +0200 Gwenole Beauchesne + + * tests/Makefile.am: + configure: fix previous commit for GLX deps. + +2012-07-20 14:44:27 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + configure: improve checks for GLX. + +2012-07-20 11:45:15 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapiutils.h: + Drop support for obsolete VA-API versions < 0.30.4. + +2012-07-20 11:16:27 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/Makefile.am: + * gst-libs/gst/gstutils_version.h.in: + * gst/vaapi/gstvaapisink.c: + vaapisink: drop checks for new APIs used by default. + GStreamer -base plugins >= 0.10.31 are now required, so the checks for + new APIs like GstXOverlay::set_window_handle() and ::set_render_rectangle() + are no longer necessary. + +2012-07-20 14:05:23 +0200 Gwenole Beauchesne + + * configure.ac: + configure: cosmetics and some minor changes. + - Better grouping of feature checks + - Sort list of config files to generate + +2012-07-19 17:55:00 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + Use standard G_GNUC_INTERNAL keyword instead of attribute_hidden. + +2012-07-19 17:41:25 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiutils_tsb.c: + * gst-libs/gst/vaapi/gstvaapiutils_tsb.h: + Drop obsolete GstVaapiTSB. + It has been replaced with a GstAdapter and gst_adapter_prev_pts(). + +2012-07-19 17:27:06 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + docs: add missing entries for the JPEG decoder. + +2012-07-19 17:16:28 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * tests/test-decode.c: + * tests/test-subpicture.c: + Drop all references to USE_CODEC_PARSERS. + +2012-07-19 17:00:36 +0200 Gwenole Beauchesne + + * NEWS: + * configure.ac: + * docs/reference/libs/libs-sections.txt: + * docs/reference/libs/libs.core.types: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + * tests/test-decode.c: + * tests/test-subpicture.c: + Drop FFmpeg-based decoders. + GStreamer codecparsers-based decoders are the only supported decoders now. + Though, FFmpeg decoders are still available in gstreamer-vaapi 0.3.x series. + +2012-07-01 05:55:05 +0900 Javier Jardón + + * configure.ac: + * debian.upstream/control.in: + configure: bump glib required version to 2.28. + Signed-off-by: Gwenole Beauchesne + +2012-06-29 08:45:47 +0900 Javier Jardón + + * gst/vaapi/gstvaapidecode.h: + * gst/vaapi/gstvaapidownload.h: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapisink.h: + * gst/vaapi/gstvaapiupload.h: + plugins: declare _get_type() functions as const. + Declaring a function as const enables better optimization of calls to + the function. + Signed-off-by: Gwenole Beauchesne + +2012-07-01 05:50:17 +0900 Javier Jardón + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: use g_clear_object() wherever applicable. + Signed-off-by: Gwenole Beauchesne + +2012-06-29 15:19:51 +0900 Javier Jardón + + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.h: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.h: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiparamspecs.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapivalue.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapivideosink.h: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + libs: declare _get_type() functions as const. + Declaring a function as const enables better optimization of calls + to the function. + Signed-off-by: Gwenole Beauchesne + +2012-07-01 05:34:15 +0900 Javier Jardón + + * gst-libs/gst/vaapi/glibcompat.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + libs: use g_clear_object() wherever applicable. + This is a preferred thread-safe version. Also add an inline version of + g_clear_object() if compiling with glib < 2.28. + Signed-off-by: Gwenole Beauchesne + +2012-07-01 06:02:22 +0900 Javier Jardón + + * .gitignore: + * configure.ac: + * docs/reference/libs/Makefile.am: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapimarshal.list: + * gst-libs/gst/vaapi/gstvaapiobject.c: + libs: use generic g_cclosure_marshal_VOID__VOID(). + Signed-off-by: Gwenole Beauchesne + +2012-07-19 14:29:33 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/glibcompat.h: + glibcompat: drop explicit check for g_list_free_full(). + +2012-07-19 13:58:31 +0200 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2012-07-19 13:57:05 +0200 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/Makefile.am: + jpeg: fix make dist. + +2012-06-28 00:39:10 +0900 Javier Jardón + + * autogen.sh: + * configure.ac: + * docs/Makefile.am: + configure: fix build without gtk-doc support. + Also do not generate tamplate files as all the documentation is inline. + Drop un-needed code in autogen.sh as well. + Signed-off-by: Gwenole Beauchesne + +2012-06-28 00:27:31 +0900 Javier Jardón + + * Makefile.am: + * autogen.sh: + * configure.ac: + configure: put m4 macros and autogenerated files into m4/ directory. + Signed-off-by: Gwenole Beauchesne + +2012-06-28 00:20:12 +0900 Javier Jardón + + * configure.ac: + configure: drop deprecated autoconf macros. + Bump autoconf required version to 2.58, needed for AS_HELP_STRING macro. + Signed-off-by: Gwenole Beauchesne + +2012-06-28 00:04:19 +0900 Javier Jardón + + * configure.ac: + configure: don't use AC_SUBST for some variables. + PKG_CHECK_MODULES already does this for us. + Signed-off-by: Gwenole Beauchesne + +2012-07-19 11:43:03 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapiupload.c: + plugins: add support for GstImplementsInterface. + +2012-07-01 02:58:36 +0900 Javier Jardón + + * configure.ac: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: use G_DEFINE_TYPE_* instead of deprecated GST_BOILERPLATE_*. + Signed-off-by: Gwenole Beauchesne + +2012-07-01 03:57:13 +0900 Javier Jardón + + * configure.ac: + * gst/vaapi/gstvaapisink.c: + plugins: do not use deprecated GStreamer -base symbols. + Bump GStreamer plugins -base required version to 0.10.31, needed for + gst_x_overlay_got_window_handle(). + Signed-off-by: Gwenole Beauchesne + +2012-07-01 03:57:13 +0900 Javier Jardón + + * configure.ac: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: do not use deprecated core GStreamer symbols. + Bump GStreamer required version to 0.10.14, needed for + gst_element_class_set_details_simple(). + Signed-off-by: Gwenole Beauchesne + +2012-07-19 10:54:33 +0200 Gwenole Beauchesne + + * tests/test-decode.c: + tests: fix build without JPEG decoder support. + +2012-07-17 13:44:45 +0200 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/test-decode.c: + * tests/test-jpeg.c: + * tests/test-jpeg.h: + tests: add test for JPEG decoding. + +2012-07-17 13:43:32 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: update to match latest parser API. + +2012-07-16 17:35:19 +0200 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/gstjpegparser.c: + * gst-libs/gst/codecparsers/gstjpegparser.h: + codecparsers: jpeg: tweak parser API. + ... to allow for more consistent parsing API among various codec parsers. + In particular, drop use of GList. + +2012-07-16 16:24:04 +0200 Gwenole Beauchesne + + * configure.ac: + jpeg: fix configure check for VA/JPEG decoding API. + +2012-06-26 15:18:53 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + jpeg: fix build with VA-API < 0.32.0. + +2012-06-26 15:04:58 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2012-06-26 15:02:44 +0200 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2012-06-26 14:46:40 +0200 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.3.7. + +2012-06-26 13:34:39 +0200 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2012-06-25 16:07:55 +0800 Yan Yin + + * gst/vaapi/gstvaapipluginutil.c: + vaapiplugin: fix build when compiling without GLX. + Signed-off-by: Gwenole Beauchesne + +2012-06-26 11:03:25 +0200 Gwenole Beauchesne + + * configure.ac: + configure: disable FFmpeg-based decoders. + FFmpeg decoders are still available through the --enable-ffmpeg option + but are no longer maintained. + +2012-06-25 17:25:44 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + Fix build with recent GStreamer stack. + +2012-06-25 17:10:49 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: update to current VA/JPEG decoding API. + +2012-06-21 16:06:47 +0200 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/gstjpegparser.c: + * gst-libs/gst/codecparsers/gstjpegparser.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + codecparsers: jpeg: track valid quantization and Huffman tables. + Add valid flag to GstJpegQuantTable and GstJpegHuffmanTable so that + to determine whether a table actually changed since the last user + synchronization point. That way, this makes it possible for some + hardware accelerated decoding solution to upload only those tables + that changed. + +2012-06-05 10:10:22 +0800 Wind Yuan + + * gst-libs/gst/codecparsers/gstjpegparser.c: + codecparsers: jpeg: use U_READ_UINT*() wherever possible. + Use GstByteReader *_unchecked() variants as much as possible. + Signed-off-by: Gwenole Beauchesne + +2012-06-04 16:20:13 +0800 Wind Yuan + + * gst-libs/gst/codecparsers/gstjpegparser.c: + * gst-libs/gst/codecparsers/gstjpegparser.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: add new GstJpegHuffmanTables structure. + Add new GstJpegHuffmanTables helper structure to hold all possible + AC/DC Huffman tables available to all components. + Signed-off-by: Gwenole Beauchesne + +2012-06-04 15:52:19 +0800 Wind Yuan + + * gst-libs/gst/codecparsers/gstjpegparser.c: + * gst-libs/gst/codecparsers/gstjpegparser.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: make gst_jpeg_parse() support multiple scans. + gst_jpeg_parse() now gathers all scans available in the supplied + buffer. A scan comprises of the scan header and any entropy-coded + segments or restart marker following it. The size and offset to + the associated data (ECS + RST segments) are append to a new + GstJpegScanOffsetSize structure. + Signed-off-by: Gwenole Beauchesne + +2012-04-19 23:50:14 +0800 Wind Yuan + + * gst-libs/gst/codecparsers/gstjpegparser.c: + * gst-libs/gst/codecparsers/gstjpegparser.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + jpeg: update to match latest parser API. + Signed-off-by: Gwenole Beauchesne + +2012-04-13 01:58:39 -0400 Gwenole Beauchesne + + * gst-libs/gst/codecparsers/gstjpegparser.h: + jpeg: simplify and optimize parser API. + +2012-04-18 22:30:45 -0400 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + mpeg: fix picture used to determine backward_reference_vop_coding_type. + Complete fix brought by bf9f77b1afb0829b97e2d502057aec973c5fd7f5 + but Gwenole did not apply all the bits. + Signed-off-by: Gwenole Beauchesne + +2012-04-27 04:13:00 -0400 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + mpeg4: map Simple_Scalable profile to Advanced_Simple profile. + Signed-off-by: Gwenole Beauchesne + +2012-04-27 04:10:17 -0400 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + mpeg4: handle skipped frames (vop_hdr->coded = 0). + Gracefully skip non VOP coded frames. + Signed-off-by: Gwenole Beauchesne + +2012-04-26 04:00:41 -0400 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + mpeg4: fix timestamp issues on too fast playback. + Improve generation of presentation timestamps to be less sensitive + to input stream errors. In practise, GOP is also a synchronization + point for PTS calculation. + Signed-off-by: Gwenole Beauchesne + +2012-04-16 10:02:29 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + Fix build without JPEG decoder. + +2012-04-12 11:48:24 +0200 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + mpeg4: fix VOP coding type of backward reference pictures. + Signed-off-by: Gwenole Beauchesne + +2012-04-11 23:02:45 -0400 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + mpeg4: fix handling of temporal reference distances. + TRD and TRB fields are not large enough to hold the difference of PTS + expressed with nanosecond resolution. So, compute them from the original + VOP info. + Signed-off-by: Gwenole Beauchesne + +2012-04-12 11:00:22 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + dpb: mpeg2: cosmetics. + Define MAX_MPEG2_REFERENCES to 2 and avoid magic numbers all around. + +2012-02-10 00:21:04 +0800 Wind Yuan + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst/vaapi/gstvaapidecode.c: + Add initial JPEG decoder. + Signed-off-by: Gwenole Beauchesne + +2012-02-10 00:21:04 +0800 Wind Yuan + + * configure.ac: + * gst-libs/gst/Makefile.am: + * gst-libs/gst/codecparsers/Makefile.am: + * gst-libs/gst/codecparsers/gstjpegparser.c: + * gst-libs/gst/codecparsers/gstjpegparser.h: + * gst-libs/gst/vaapi/Makefile.am: + codecparsers: add JPEG parser. + Signed-off-by: Gwenole Beauchesne + +2012-04-10 13:29:10 +0200 Wind Yuan + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix VA display type. + Fix typo whereby plain VADisplay type was used instead of the GstVaapiDisplay + wrapper. + Signed-off-by: Gwenole Beauchesne + +2012-04-10 14:28:31 +0200 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix includes when compiling for a single API. + +2012-04-02 18:42:12 +0200 Gwenole Beauchesne + + * NEWS: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix calculation of macroblock_offset. + Fix decoding of streams with extra slice() information before the first + macroblock(). e.g. this fixes sony-ct3.bs from conformance test. + +2012-04-02 18:09:21 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix interpolation of GOP TSN from new PTS. + New GOP TSN base could be mis-calculated. In particular, this fixes + decoding of uruseiyatsura.vob from . + +2012-04-02 16:07:58 +0200 Gwenole Beauchesne + + * NEWS: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + mpeg2: fix decoding of high profile streams. + Allow MPEG-2 High profile streams only if the HW supports that profile + or no High profile specific bits are used, and thus Main profile could + be used instead. i.e. chroma_format is 4:2:0, intra_dc_precision is not + set to 11 and no sequence_scalable_extension() was parsed. + +2012-04-02 14:51:06 +0200 Gwenole Beauchesne + + * NEWS: + * gst/vaapi/gstvaapidecode.c: + vaapidecode: report unsupported codec profiles. + Try to gracefully abort when the HW does not support the requested + profile. There is no fallback unless profiles are correctly parsed + and matched through caps beforehand. + +2012-02-07 15:23:22 +0100 Holger Kaelberer + + * NEWS: + * gst/vaapi/gstvaapisink.c: + vaapisink: don't resize a 'foreign' X-window. + Don't forcibly resize foreign X windows. The user is responsible for + their size and vaapisink shall not change this. + Signed-off-by: Gwenole Beauchesne + +2012-02-07 15:21:05 +0100 Holger Kaelberer + + * NEWS: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: recalculate render rect only if caps are negotiated. + Fix gst_vaapisink_xoverlay_set_window_handle() when it is called before + caps got negotiated. Besides, when a foreign window is provided by the + user, so should the render rect. + Signed-off-by: Gwenole Beauchesne + +2012-04-02 13:07:34 +0200 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2012-04-02 10:07:33 +0200 Gwenole Beauchesne + + * configure.ac: + 0.3.6. + +2012-04-02 12:52:54 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * docs/reference/plugins/plugins-docs.xml.in: + * docs/reference/plugins/plugins-sections.txt: + * docs/reference/plugins/plugins.types: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapipostproc.c: + Fix a few documentation issues. + +2012-04-02 10:05:57 +0200 Gwenole Beauchesne + + * NEWS: + * README: + Update introduction and changelog. + +2012-04-02 11:29:53 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: allocate dummy picture for first field based I-frame. + In P-pictures, prediction shall be made from the two most recently + decoded reference fields. However, when the first I-frame is a field, + the next field of the current picture could be a P-picture but only a + single field was decoded so far. In this case, create a dummy picture + with POC = -1 that will be used as reference. + Some VA drivers would error out if P-pictures don't have a forward + reference picture. This is true in general but not in this very specific + initial case. + +2012-04-02 10:43:30 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix simple to main profile fallback. + Allow fallback from simple to main profile when the HW decoder does + not support the former profile and that no sequence_header_extension() + is available to point out this. + +2012-03-30 03:04:40 -0400 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + mpeg4: improve error checking while decoding packets. + decode_picture() could return an error when an MPEG-4 profile is not + supported for example. In this case, the underlying VA context is not + allocated and no other proper action can be taken. Likewise on exit + from decode_slice(). + Signed-off-by: Gwenole Beauchesne + +2012-03-30 17:03:28 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + decoder: use POC to maintain the DPB. + Introduce a POC field in GstVaapiPicture so that to store simpler sequential + numbers. A signed 32-bit integer should be enough for 1 year of continuous + video streaming at 60 Hz. + Use this new POC value to maintain the DPB, instead of 64-bit timestamps. + This also aligns with H.264 that will be migrated to GstVaapiDpb infrastructure. + +2012-03-30 16:23:33 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: rework generation of presentation timestamps. + Always prefer PTS from the demuxer layer for GOP times. If this is invalid, + i.e. demuxer could not determine the PTS or the generated PTS is lower than + max PTS from past pictures, then try to fix it up based on the duration of + a frame. + For picture PTS, simply use the GOP PTS formerly computed then use TSN to + reconstruct a current time. Also now handle wrapped TSN correctly. + +2012-03-30 17:07:39 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: ignore empty user-data packets. + Fix tcela-8.bits conformance test. + +2012-03-29 11:13:20 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: review and report errors accordingly. + Use GST_ERROR() to report real errors instead of hiding them into + GST_DEBUG(). + +2012-03-28 19:15:47 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix invalid interlaced frame in progressive sequence. + Some streams, badly constructed, could have signaled an interlaced + frame while the sequence was meant to be progressive. Warn and force + frame to be progressive in this case. + +2012-03-28 16:08:29 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + mpeg2: add support for interlaced streams. + Pictures are submitted to the HW for rendering only when both fields + are decoded or current picture is a full frame. + +2012-03-28 14:36:30 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: add new decoded picture buffer infrastructure. + Decoded pictures are now maintained into DPB, similarly to H.264. + The same mechanism could be re-used for VC-1 and MPEG-4:2 codecs. + +2012-03-28 17:50:28 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + decoder: add first-field flag to picture. + Add first-field (FF) flag to GstVaapiPicture, thus not requiring is_first_field + member in each decoder. Rather, when a GstVaapiPicture is created, it is considered + as the first field. Any subsequent allocated field will become the second field. + +2012-03-28 16:05:58 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + decoder: allow pictures to be cloned for field decoding. + Add gst_vaapi_picture_new_field() function that clones a picture, while + preserving the parent picture surface. i.e. the surface proxy reference + count is increased and other fields copied as is. Besides, the picture + is reset into a "non-output" mode. + +2012-03-28 16:07:44 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + decoder: rework picture field flags. + Add top-field-first (TFF) and interlaced flags to GstVaapiPicture so they + could be propagated to the surface proxy when it is pushed for rendering. + Besides, top and bottom fields are now expressed with picture structure flags + from GstVaapiSurfaceRenderFlags. + +2012-03-28 14:28:26 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + decoder: add OUTPUT flag to pictures. + Allow pictures to be marked as output gst_vaapi_picture_output(). + +2012-03-28 14:24:40 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: fix semantics of SKIPPED pictures. + If GstVaapiPicture has flag SKIPPED set, this means gst_vaapi_picture_output() + will not push the underlying surface for rendering. Besides, VC-1 skipped P-frame + has nothing to do with rendering. This only means that the currently decoded + picture is just a copy of its reference picture. + +2012-03-28 15:16:17 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: get "interlaced" attribute from surface proxy. + Add new "interlaced" attribute to GstVaapiSurfaceProxy. Use this in + vaapipostproc so that to handles cases where bitstream is interlaced + but almost only frame pictures are generated. In this case, we should + not be alternating between top/bottom fields. + +2012-03-26 14:37:24 +0200 Gwenole Beauchesne + + * README: + * debian.upstream/control.in: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: add new element for video postprocessing. + Add vaapipostproc element for video postprocessing. So far, only basic + bob deinterlacing is implemented. Interlaced mode is automatically + detected based on sink caps ("interlaced" field). + +2012-03-26 12:01:36 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapisink.c: + videobuffer: add surface render flags. + Allow rendering flags, as a combination of GstVaapiSurfaceRenderFlags, + to be set to the video buffer. In particular, this is mostly useful for + basic deinterlacing. + +2012-03-23 17:13:58 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicompat.h: + compat: add compatibility glue with VA-API 0.34+ (WIP). + +2012-03-23 17:11:18 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: skip all Filler Data NALs. + +2012-03-22 03:28:22 -0400 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + mpeg4: check for decoder status prior to decoding packet. + Make sure there is a VA surface free prior to decoding the current frame. + Signed-off-by: Gwenole Beauchesne + +2012-03-15 04:58:04 -0400 Wind Yuan + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + decode: delay NEWSEGMENT event if vaapidecode element was not linked. + Rationale: playbin2 links all elements at run-time. Once vaapidecode + is created and a NEWSEGMENT event arrives, downstream element may not + be ready yet. So, delay this event until next element is chained in, + otherwise basesink could output "Received buffer without a new-segment. + Assuming timestamps start from 0". + Signed-off-by: Gwenole Beauchesne + +2012-03-13 20:33:41 -0400 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix GOP timestamps when incorrect data is received. + Some streams have incorrect GOP timestamps, or nothing set at all. + i.e. GOP time is 00:00:00 for all GOPs. Try to recover in this case + from demuxer timestamps, which are monotonic. + Signed-off-by: Gwenole Beauchesne + +2012-03-13 02:03:31 -0400 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: don't decode anything before the first sequence_header(). + Skip all pictures prior to the first sequence_header(). Besides, + skip all picture_data() if there was no prior picture_header(). + Signed-off-by: Gwenole Beauchesne + +2012-02-07 15:57:14 +0100 Holger Kaelberer + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + ffmpeg: add support for interlaced streams. + Evaluate interlaced stream properties. + Signed-off-by: Gwenole Beauchesne + +2012-02-07 15:54:15 +0100 Holger Kaelberer + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: propagate interlaced and TFF properties downstream. + Propagate "interlaced" caps downstream and set "tff" buffer flag + appropriately to output buffers for interlaced pictures. + Signed-off-by: Gwenole Beauchesne + +2012-02-07 15:54:15 +0100 Holger Kaelberer + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: maintain caps for interlaced streams. + Extend GstVaapiDecoder base object to maintain caps with "interlaced" + property. + Signed-off-by: Gwenole Beauchesne + +2012-02-07 15:54:15 +0100 Holger Kaelberer + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + surfaceproxy: add TFF property. + Add TFF (top-field-first) property to GstVaapiSurfaceProxy. + Signed-off-by: Gwenole Beauchesne + +2012-03-16 14:21:36 +0100 Gwenole Beauchesne + + * AUTHORS: + AUTHORS: update to match current authors. + +2012-02-28 11:58:21 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix is_first_field calculation. + Reset is_first_field for frame pictures. Factor out locations where + the flag is updated. + +2012-02-24 12:56:48 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: catch incorrect picture_structure from bitstreams. + Assume "frame" picture structure if the syntax element was zero or if + progressive_frame is set. + +2012-02-24 12:53:30 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix slice_vertical_position calculation (again). + VA-API expects slice_vertical_position as the initial position from the + bitstream. i.e. the direct slice() information. VA drivers will be fixed + accordingly. + +2012-03-02 15:03:57 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + Revert "vaapidecode: fix another pad template ref leak" (Holger Kaelberer) + This reverts commit 2f127d6af473afd647a2c88f75faafd1cd718437. + For gst_element_class_get_pad_template(), no unreferencing is necessary + according to the GStreamer documentation. + +2012-03-02 13:41:16 +0100 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix slice_data_bit_offset calculation. + Unlike what VA-API documentation defines, the slice_data_bit_offset + represents the offset to the first macroblock in the slice data, minus + any emulation prevention bytes in the slice_header(). + This fix copes with binary-only VA drivers that won't be fixed any + time soon. Besides, this aligns with the current FFmpeg behaviour + that was based on those proprietary drivers implementing the API + incorrectly. + +2012-02-21 02:11:20 -0500 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: skip all Access Unit (AU) NALs. + Signed-off-by: Gwenole Beauchesne + +2012-02-29 03:08:46 -0500 Wind Yuan + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix modification process of reference picture lists. + Construction of RefPicList0/1 could be off by one element. + Signed-off-by: Gwenole Beauchesne + +2012-02-12 11:21:52 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix size calculation from sequence_extension(). + Original values from sequence_header() are 12-bit and the remaining + 2 most significant bits are coming from sequence_extension(). + Signed-off-by: Gwenole Beauchesne + +2012-02-23 16:39:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix slice_vertical_position calculation. + Make sure to adjust slice_vertical_position if picture structure + is a top or bottom field. + +2012-02-23 16:23:27 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + decoder: add picture structure flags. + +2012-02-23 14:42:38 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix decoding at end-of-sequence. + +2012-02-23 14:17:34 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix slice_horizontal_position calculation. + +2012-02-23 16:14:02 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: drop useless mb_y and mb_height members. + +2012-02-23 11:19:48 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix decoding of multiple slices with same slice_vertical_position. + 6.3.15 says that "some slices may have the same slice_vertical_position, + since slices may start and finish anywhere". So, we can't submit the current + picture to the HW right away since subsequent slices would be missing. + +2012-02-15 14:08:44 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimage.c: + image: fix source stride in picture copy. + +2012-02-13 10:10:35 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + decoder: fix double buffer free with some VA drivers. + vaRenderPicture() implicitly disposes VA buffers. Some VA drivers would + push the VA buffer object into a list of free buffers to be re-used. However, + reference pictures (and data) that was kept would explicitly release the VA + buffer object later on, thus possibly destroying a valid (re-used) object. + Besides, some other VA drivers don't support correctly the vaRenderPicture() + semantics for VA buffers disposal and would leak memory if there is no explicit + vaDestroyBuffer(). The temporary workaround is to explcitily destroy VA buffers + right after vaRenderPicture(). All VA drivers need to be aligned. + +2012-02-08 18:08:49 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: complete any current picture decoder before SPS / PPS change. + This ensures the VA context is clear when the encoded resolution + changes. i.e. make sure older picture is decoded with the older + VA context before it changes. + +2012-02-08 18:07:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: create VA context earlier when SPS is parsed. + +2012-02-08 17:57:29 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: don't allocate too big data structures on stack. + +2012-02-07 11:07:15 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/glibcompat.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + glib: map deprecated API to glib >= 2.32 equivalents. + GStaticMutex and GStaticRecMutex are now replaced with GMutex and + GRecMutex, which no longer require any prior call to g_thread_init(). + +2012-02-07 10:01:01 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + glib: fix includes. + +2012-02-07 10:05:53 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + cosmetics: fix warnings (drop unused variables). + +2012-02-06 16:11:38 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix another pad template ref leak. + +2012-02-06 15:54:09 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + mpeg2: fix crash when there is no free surface to decode into. + +2012-01-31 16:38:58 +0800 Zhao Halley + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: skip profiles which have no entrypoints. + Signed-off-by: Gwenole Beauchesne + +2012-02-05 18:28:51 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiupload.c: + vaapiupload: use g_object_unref() for GstVaapiImage. + +2012-02-05 18:24:08 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + plugins: fix pad template ref leaks. + +2012-02-02 09:23:15 +0100 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2012-02-01 23:34:09 +0100 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.3.4. + +2012-02-01 23:32:47 +0100 Gwenole Beauchesne + + * README: + README: updates. + Mention codecparsers-based decoders, FFmpeg is now optional. Update + list of support HW. + +2012-02-01 23:28:23 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2012-01-31 11:34:17 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + decoder: allocate proxy surface earlier. + This simplifies gst_vaapi_picture_output() to only update the presentation + timestamp and submit the proxy to the decoder for output. + +2012-01-31 11:26:37 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + decoder: fix memory leak of VA objects on exit. + On sequence end, if the last decoded picture is not output for rendering, + then the proxy surface is not created. In this case, the original surface + must be released explicitly to the context. + +2012-01-31 10:47:36 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: use GstAdapter to track input sequence. + This fixes possible memory leaks and improves performance by removing + some extra copies. + +2012-01-30 18:25:03 +0100 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/glibcompat.h: + * gst-libs/gst/vaapi/sysdeps.h: + Add glib compatibility glue for older versions. + +2012-01-30 18:12:59 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiparamspecs.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideosink.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/sysdeps.h: + Add header for system-dependent definitions. + +2012-01-30 10:15:32 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + decoder: optimize slice data buffers initialization. + VA drivers may have a faster means to transfer user buffers to GPU + buffers than using memcpy(). In particular, on Intel Gen graphics, we + can use pwrite(). This provides for faster upload of bitstream and can + help higher bitrates. + vaapi_create_buffer() helper function was also updated to allow for + un-mapped buffers and pre-initialized data for buffers. + +2012-01-27 17:28:50 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: simplify RefPicList reconstruction. + +2012-01-27 16:08:03 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: flush DPB when the end of the sequence is reached. + +2012-01-24 15:38:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: handle Decoded Picture Buffer (DPB). + +2012-01-24 09:20:25 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix pred_weight_table() reconstruction. + Only the explicit pred_weight_table(), possibly with the inferred default + values, shall be required. e.g. don't fill in the table if weighted_pred_flag + is not set for P/SP slices. + +2012-01-23 15:03:07 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: execute reference picture marking process (MMCO). + +2012-01-23 15:20:51 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: fix presentation timestamps. + +2012-01-18 13:38:34 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: execute reference picture marking process (sliding window). + +2012-01-17 10:42:49 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: handle avcC format for decoding buffers. + +2011-11-25 14:37:00 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: handle codec-data. + Signed-off-by: Gwenole Beauchesne + +2011-08-12 17:43:55 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + * gst/vaapi/gstvaapidecode.c: + * tests/test-decode.c: + Add initial H.264 decoder. + +2012-01-26 15:28:42 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + decoder: retain proxy surface until the GstVaapiPicture is destroyed. + Keep a valid reference to the proxy in GstVaapiPicture so that frames + marked as "used for reference" could be kept during the lifetime of the + picture. i.e. don't release them too soon as they could be re-used right + away. + +2012-01-26 15:19:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: properly reference count pictures. + This fixes cases where a GstVaapiPicture would be destroyed whereas + there is still a valid instance of it in either prev, current or + next picture. + +2012-01-26 14:54:31 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: simplify output of decoded frames. + Drop obsolete gst_vaapi_decoder_push_surface() that was no longer used. + Change gst_vaapi_decoder_push_surface_proxy() semantics to assume PTS + is already set correctly and reference count increased, if necessary. + +2012-01-26 09:48:11 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: rework the internal VA objects API. + The new API simplifies a lot reference counting and makes it more + flexible for future additions/changes. The GstVaapiCodecInfo is + also gone. Rather, new helper macros are provided to allocate + picture, slice and quantization matrix parameter buffers. + +2012-01-24 10:21:45 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: allow slices to be attached to pictures later. + +2011-11-21 18:39:49 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: add ref_count to GstVaapiPicture. + +2012-01-23 11:48:42 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: cap window size to the maximum display size. + +2012-01-18 10:23:41 +0100 Zhao Halley + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiworkarounds.h: + profile: match video/x-h263 as H.263 Baseline profile. + HACK: qtdemux does not report profiles for H.263. So, assume plain + "video/x-h263" is H.263 Baseline profile. + Signed-off-by: Gwenole Beauchesne + +2012-01-18 10:22:58 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiworkarounds.h: + display: report H.263 Baseline profile. + HACK: expose GST_VAAPI_PROFILE_H263_BASELINE for decoding if MPEG-4:2 Simple + profile (VAProfileMPEG4Simple) is supported. + +2012-01-24 10:06:37 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiworkarounds.h: + Add template for workarounds. + +2012-01-18 10:47:56 +0100 Gwenole Beauchesne + + * tests/test-decode.c: + tests: error out if FFmpeg|codecparsers are not supported. + +2012-01-18 10:42:38 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + surface: don't expose gst_vaapi_surface_get_parent_context(). + gst_vaapi_surface_get_parent_context() was not meant to be exposed globally. + It's just an internal helper function. However, it's still possible to get + the parent context through the "parent-context" property. + +2012-01-16 14:19:00 +0100 Gwenole Beauchesne + + * tests/Makefile.am: + * tests/test-subpicture.c: + tests: fix build without FFmpeg. + +2012-01-16 14:09:57 +0100 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2012-01-16 11:05:31 +0100 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.3.3. + +2012-01-16 11:03:51 +0100 Gwenole Beauchesne + + * README: + * debian.upstream/copyright: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapidownload.h: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiupload.h: + * tests/test-decode.c: + legal: fix year for some copyright notices. + +2012-01-16 10:42:55 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst/vaapi/gstvaapidownload.h: + * gst/vaapi/gstvaapisink.h: + * gst/vaapi/gstvaapiupload.h: + * tests/test-decode.c: + legal: add Intel copyright on modified files. + +2012-01-16 10:41:10 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapi_priv.h: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidebug.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapiparamspecs.c: + * gst-libs/gst/vaapi/gstvaapiparamspecs.h: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapivideosink.c: + * gst-libs/gst/vaapi/gstvaapivideosink.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapidownload.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiupload.h: + * tests/image.c: + * tests/image.h: + * tests/test-decode.c: + * tests/test-decode.h: + * tests/test-display.c: + * tests/test-h264.c: + * tests/test-h264.h: + * tests/test-mpeg2.c: + * tests/test-mpeg2.h: + * tests/test-surfaces.c: + * tests/test-textures.c: + * tests/test-vc1.c: + * tests/test-vc1.h: + * tests/test-windows.c: + legal: fix copyright notices to include "Copyright" term. + +2011-12-09 16:44:03 +0800 Zhao Halley + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h: + mpeg4: replace GstVaapiTSB with GstAdapter (gst-plugins-base >= 0.10.24). + Signed-off-by: Gwenole Beauchesne + +2011-12-09 16:28:11 +0800 Zhao Halley + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h: + * gst/vaapi/gstvaapidecode.c: + Add initial MPEG-4 decoder. + Signed-off-by: Gwenole Beauchesne + +2011-11-18 15:41:40 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.h: + vc1: replace GstVaapiTSB with GstAdapter (gst-plugins-base >= 0.10.24). + Signed-off-by: Gwenole Beauchesne + +2011-10-07 11:50:20 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: fix codec-data decoding for WMV3 format. + +2011-10-07 11:12:33 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: fix presentation timestamps. + +2011-10-06 15:59:22 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: fix MV mode packing. + +2011-10-05 16:41:57 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: handle codec-data. + +2011-10-05 15:56:36 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: handle encapsulated bitstreams. + +2011-10-04 17:51:51 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: fix bitplanes decoding. + +2011-10-04 14:15:55 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: fix BFRACTION reconstruction. + +2011-09-30 17:16:23 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + vc1: fix framerate calculation. + +2011-09-30 13:40:11 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.h: + * gst/vaapi/gstvaapidecode.c: + * tests/test-decode.c: + Add initial VC-1 decoder. + +2012-01-09 17:37:34 +0100 Zhao Halley + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix first field detection. + Signed-off-by: Gwenole Beauchesne + +2012-01-06 16:44:09 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix quantisation matrix construction. + +2011-11-18 15:06:07 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h: + mpeg2: replace GstVaapiTSB API with GstAdapter (gst-plugins-base >= 0.10.24). + Signed-off-by: Gwenole Beauchesne + +2011-09-14 18:11:57 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: fix packets spanning over two buffers. + +2011-09-12 18:20:00 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: ignore system start codes (PES headers). + +2011-09-12 18:02:53 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + mpeg2: handle closed_gop. + +2011-08-05 11:55:11 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h: + * gst/vaapi/gstvaapidecode.c: + * tests/test-decode.c: + Add initial MPEG-2 decoder. + +2011-08-12 10:21:19 +0200 Gwenole Beauchesne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * tests/test-decode.c: + Allow conditional build of GStreamer/FFmpeg bitstream parsers. + +2011-08-05 11:53:50 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Add VA decoder helpers. + +2011-08-05 11:52:43 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.h: + decoder: add new error codes. + GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: for unsupported profile + GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: for unsupported chroma format + +2011-09-12 13:00:59 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiutils_tsb.c: + * gst-libs/gst/vaapi/gstvaapiutils_tsb.h: + Add timestamp buffer store helper utils. + +2011-08-04 17:29:41 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + Add VA buffer helpers. + +2012-01-13 15:03:38 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + utils: slight improvements to gl_bind_texture(). + +2012-01-13 14:13:55 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + utils: pretty-print output of gl_get_error_string(). + +2012-01-13 14:03:29 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + utils: rewrite gl_perspective() as per OpenGL FAQ 9.085. + +2012-01-13 12:09:07 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils.c: + utils: simplify string of VAProfile/VAEntrypoint. + +2012-01-13 11:46:55 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + utils: drop string_of_FOURCC() in favor of standard GST_FOURCC_* helpers. + +2012-01-12 17:18:47 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2012-01-12 15:34:59 +0100 Gwenole Beauchesne + + * tests/test-decode.c: + tests: check for shared VA displays (display cache). + +2012-01-12 15:30:04 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: always free VA display cache if it is empty. + +2012-01-12 15:03:04 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + display: use VA display cache for X11 and GLX winsys. + +2012-01-12 12:46:34 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.h: + display: implement a VA display cache. + +2012-01-11 14:13:06 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + vaapiplugin: fix gst_vaapi_ensure_display() to use system defaults. + This ensures the display name provided to gst_vaapi_display_*_new() + maps to the system defaults, instead of forcing "" that could be different + from the current DISPLAY name. + +2011-08-26 15:44:25 -0400 Nicolas Dufresne + + * gst/vaapi/gstvaapiupload.c: + vaapiupload: only set caps on newly created buffers. + Signed-off-by: Gwenole Beauchesne + +2012-01-11 14:11:30 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: ensure VA display in GstBaseSink::start() hook. + This ensures a VA display is ready by the time upstream elements request + for it. + +2011-08-26 15:44:46 -0400 Nicolas Dufresne + + * gst/vaapi/gstvaapisink.c: + vaapisink: don't leak GL texture. + Signed-off-by: Gwenole Beauchesne + +2012-01-09 16:51:35 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix calculation of render region. + +2012-01-09 11:23:39 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: automatically fit video to window. + +2012-01-09 10:37:30 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: implement GstXOverlay::set_render_rectangle(). + +2012-01-09 11:04:21 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + window: always check geometry when the window is mapped. + +2012-01-06 17:51:59 +0100 Zhao Halley + + * gst-libs/gst/vaapi/gstvaapiutils.c: + Add missing profiles from VA-API 0.32.0. + Signed-off-by: Gwenole Beauchesne + +2012-01-06 16:48:15 +0100 Gwenole Beauchesne + + * .gitignore: + .gitignore: add test-subpicture. + +2012-01-06 11:23:21 +0100 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2012-01-06 11:20:48 +0100 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.3.2. + +2012-01-06 11:18:55 +0100 Gwenole Beauchesne + + * tests/Makefile.am: + tests: fix make dist (ship with test-subpicture-data.h). + +2012-01-05 17:35:12 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2012-01-05 17:09:35 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: fix possible leak of VA surfaces. + Under some circumstances, we could have leaked a surface, thus not + releasing it to the pool of available surfaces in the VA context. + The strategy is now to use a proxy earlier and automatically ref/unref + whenever necessary. In particular, during the lifetime needed for FFmpeg. + +2012-01-05 16:59:57 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + surfaceproxy: add helper to retrieve the VA surface ID. + +2012-01-05 16:44:44 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + surfaceproxy: simplify destruction. + Also make sure to always make sure to release the surface back to the + pool of surfaces in the associated VA context, if any. + +2012-01-05 16:26:49 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix deinitialization order. + +2012-01-05 14:50:26 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapicontext.c: + context: avoid self reference loops with surfaces. + +2012-01-05 11:23:01 +0100 Gwenole Beauchesne + + * debian.upstream/control.in: + debian: update control.in description for new plugins. + +2012-01-05 11:01:56 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiupload.c: + vaapiupload: use new gst_vaapi_append_surface_caps() helper. + This also fixes extra structures, beyond the one at index 0, to hold + the right additional values. + +2012-01-05 10:55:34 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiupload.c: + vaapiupload: fix sink (YUV) caps to not report type and opengl fields. + +2012-01-05 10:50:59 +0100 Gwenole Beauchesne + + * README: + * docs/reference/plugins/plugins-docs.xml.in: + * docs/reference/plugins/plugins-sections.txt: + * docs/reference/plugins/plugins.types: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidownload.c: + * gst/vaapi/gstvaapidownload.h: + vaapidownload: add new plugin to download pixels from VA surfaces. + +2012-01-05 11:00:39 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + vaapipluingutils: add helper to append surface caps to YUV caps. + +2012-01-05 10:29:48 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + image: add helpers to extract pixels to user buffers. + +2012-01-04 11:34:34 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimage.c: + image: simplify initialization of raw images from video buffers. + +2012-01-04 11:29:11 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimage.c: + image: fix update from NV12 buffers. + +2012-01-03 18:16:35 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiupload.c: + vaapiupload: fix memory leak in _init() function. + +2012-01-03 14:34:09 +0100 Gwenole Beauchesne + + * NEWS: + * README: + * debian.upstream/control.in: + * docs/reference/plugins/plugins-docs.xml.in: + * docs/reference/plugins/plugins-sections.txt: + * docs/reference/plugins/plugins.types: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapiconvert.c: + * gst/vaapi/gstvaapiconvert.h: + * gst/vaapi/gstvaapiupload.c: + * gst/vaapi/gstvaapiupload.h: + Rename vaapiconvert element to vaapiupload. + +2012-01-03 13:54:03 +0100 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2012-01-03 13:42:12 +0100 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.3.1. + +2011-12-14 15:22:24 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2011-12-14 14:40:37 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapisink.c: + surface: apply composition to the parent context, if requested. + +2011-12-14 14:35:13 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + context: make it possible to apply composition globally. + +2011-12-14 14:13:58 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + surface: fix associate subpicture to not report deassociation errors. + +2011-12-14 13:46:26 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + surface: fix typo in debug message. + +2011-12-14 13:16:21 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + subpicture: add helper to create subpicture from GstVideoOverlayRectangle. + +2011-12-13 16:53:15 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + surface: record parent context. + +2011-12-13 15:59:02 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + Fix warnings. + +2011-12-13 15:51:58 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst/vaapi/gstvaapisink.c: + Rename gst_vaapi_surface_update_composition() to gst_vaapi_surface_set_subpictures_from_composition(). + +2011-12-13 13:40:55 +0100 Gwenole Beauchesne + + * configure.ac: + configure: check for GstVideoOverlayComposition. + +2011-12-12 18:42:44 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2011-11-25 15:00:25 -0500 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + converter: add support for GstVideoOverlayComposition planes. + Signed-off-by: Gwenole Beauchesne + +2011-11-23 16:45:46 -0300 Thibault Saunier + + * gst/vaapi/gstvaapisink.c: + vaapisink: handle GstVideoOverlayComposition planes. + Signed-off-by: Gwenole Beauchesne + +2011-12-12 18:27:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + surface: use unscaled overlay rectangle for blending. + +2011-12-12 18:37:13 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + surface: fix VA image leak when an error occurred. + +2011-11-25 14:59:56 -0500 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + surface: add helper to handle GstVideoOverlayComposition. + This helper resets the subpictures to reflect the current composition + layers provided with the buffers. + Signed-off-by: Gwenole Beauchesne + +2011-12-12 18:13:19 +0100 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * gst/vaapi/gstvaapiconvert.c: + image: add gst_vaapi_image_format_from_video() helper. + +2011-12-12 16:34:07 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + image: allow updates from GstVaapiImageRaw. + +2011-12-12 14:34:03 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst/vaapi/gstvaapiconvert.c: + * tests/test-subpicture.c: + image: allow partial updates. + +2011-12-12 15:31:52 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + subpicture: fix doc for gst_vaapi_subpicture_set_image(). + +2011-12-12 13:39:20 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: fix has_image_format() to check against subpicture formats. + +2011-10-17 18:43:15 +0200 Gwenole Beauchesne + + * tests/test-subpicture.c: + tests: fix subpicture test. + +2011-10-14 13:00:12 -0300 Thibault Saunier + + * tests/Makefile.am: + * tests/test-subpicture-data.c: + * tests/test-subpicture-data.h: + * tests/test-subpicture.c: + tests: add test for subpictures. + Signed-off-by: Gwenole Beauchesne + +2011-11-25 12:28:04 -0500 Nicolas Dufresne + + * gst/vaapi/gstvaapiconvert.c: + * gst/vaapi/gstvaapidecode.c: + Add missing video context queries. + Signed-off-by: Gwenole Beauchesne + +2011-12-12 13:22:07 +0100 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2011-12-12 10:04:32 +0100 Gwenole Beauchesne + + * gst-libs/gst/video/Makefile.am: + * gst-libs/gst/video/gstbasevideocodec.c: + * gst-libs/gst/video/gstbasevideocodec.h: + * gst-libs/gst/video/gstbasevideodecoder.c: + * gst-libs/gst/video/gstbasevideodecoder.h: + * gst-libs/gst/video/gstbasevideoutils.c: + * gst-libs/gst/video/gstbasevideoutils.h: + Drop unused copy of GstBaseVideoDecoder. + +2011-12-09 11:46:45 +0100 Gwenole Beauchesne + + * NEWS: + * configure.ac: + 0.3.0. + +2011-12-09 11:38:43 +0100 Gwenole Beauchesne + + * README: + README: update dependencies. + +2011-12-09 11:38:34 +0100 Gwenole Beauchesne + + * NEWS: + NEWS: updates. + +2011-12-09 11:20:04 +0100 Gwenole Beauchesne + + * configure.ac: + configure: check for GstBaseSink 'query' vfunc. + +2011-12-09 10:45:20 +0100 Gwenole Beauchesne + + * gst/vaapi/Makefile.am: + vaapiplugin: include local build dir to CFLAGS for generated files. + +2011-12-09 10:44:52 +0100 Gwenole Beauchesne + + * autogen.sh: + autogen: don't configure if NO_CONFIGURE variable is set. + +2011-12-08 11:54:59 +0100 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: return sink caps template if decoder is in NULL state. + Otherwise, the decoder would always create its own X display instead + of probing it from the downstream element, which is not reliable. + e.g. DISPLAY is not :0 or when running on Wayland. + Signed-off-by: Gwenole Beauchesne + +2011-12-08 15:44:09 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiconvert.c: + * gst/vaapi/gstvaapidecode.c: + vaapiplugin: properly set surface type to "vaapi" in caps. + +2011-12-08 15:16:14 +0100 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + decoder: drop unused headers. + +2011-11-04 19:47:25 -0400 Nicolas Dufresne + + * gst/vaapi/gstvaapiconvert.c: + * gst/vaapi/gstvaapidecode.c: + vaapiplugin: properly set opengl support in caps. + Signed-off-by: Gwenole Beauchesne + +2011-11-04 20:07:52 -0400 Nicolas Dufresne + + * gst/vaapi/gstvaapiconvert.c: + * gst/vaapi/gstvaapidecode.c: + vaapiplugin: allocate GLX buffers when supported. + Signed-off-by: Gwenole Beauchesne + +2011-11-04 19:47:09 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer_glx.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer_glx.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer_priv.h: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.c: + * gst-libs/gst/vaapi/gstvaapivideoconverter_glx.h: + videobuffer: add GLX buffer support. + Signed-off-by: Gwenole Beauchesne + +2011-10-06 16:06:15 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + Port to GstSurfaceBuffer interface. + Signed-off-by: Gwenole Beauchesne + +2011-10-06 16:04:37 -0400 Nicolas Dufresne + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + Don't use downstream buffer allocation. + With the new video/x-surface abstraction, we can't rely on having a VA + specific sink downstream. Also, there was no particular reason to do that. + Signed-off-by: Gwenole Beauchesne + +2011-11-04 17:16:23 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst/vaapi/gstvaapiconvert.c: + * gst/vaapi/gstvaapisink.c: + * tests/Makefile.am: + * tests/test-surfaces.c: + Change caps to use new video/x-surface generic type. + Signed-off-by: Gwenole Beauchesne + +2011-11-04 16:50:15 -0400 Nicolas Dufresne + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiutils_gst.c: + * gst-libs/gst/vaapi/gstvaapiutils_gst.h: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapiconvert.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + Port to GstVideoContext interface. + This new interface allows for upstream and downstream display sharing + that works in both static and dynamic pipelines. + Signed-off-by: Gwenole Beauchesne + +2011-12-08 14:57:36 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: use GST_ERROR to print error messages. + +2011-12-08 13:30:51 +0100 Gwenole Beauchesne + + * gst/vaapi/Makefile.am: + vaapiplugin: link against VA/GLX when enabled. + +2011-12-07 19:09:55 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapiconvert.c: + * gst/vaapi/gstvaapisink.c: + Add Intel copyright information. + +2011-12-07 19:04:09 +0100 Gwenole Beauchesne + + * gst/vaapi/gstvaapisink.c: + vaapisink: allow compatibility with gst-plugins-base < 0.10.31. + +2011-12-07 18:40:35 +0100 Gwenole Beauchesne + + * .gitignore: + * configure.ac: + * gst-libs/gst/Makefile.am: + * gst-libs/gst/gstutils_version.h.in: + Add new GStreamer version check utilities. + +2011-07-28 11:14:49 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapisink.c: + vaapisink: replace the deprecated xoverlay API with the new one. + Signed-off-by: Gwenole Beauchesne + +2011-12-07 17:31:09 +0100 Gwenole Beauchesne + + * configure.ac: + configure: allow for pre-releases. + +2011-10-13 17:08:13 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: destroy display on creation failure. + This allows element to detect that the display creation has actually + failed. + Signed-off-by: Gwenole Beauchesne + +2011-10-13 17:07:35 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + display: don't crash when config is empty. + Signed-off-by: Gwenole Beauchesne + +2011-12-07 14:42:14 +0100 Gwenole Beauchesne + + * README: + * debian.upstream/copyright: + doc: mention Collabora copyrights. + +2011-12-07 14:40:20 +0100 Gwenole Beauchesne + + * .gitignore: + .gitignore: refine for generated docs. + +2011-09-14 15:12:41 -0400 Nicolas Dufresne + + * configure.ac: + * docs/reference/plugins/Makefile.am: + * gst/Makefile.am: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapiconvert.c: + * gst/vaapi/gstvaapiconvert.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + * gst/vaapiconvert/Makefile.am: + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapiconvert/gstvaapiconvert.h: + * gst/vaapidecode/Makefile.am: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapidecode/gstvaapidecode.h: + * gst/vaapisink/Makefile.am: + * gst/vaapisink/gstvaapisink.c: + * gst/vaapisink/gstvaapisink.h: + Group all plugins into the same bundle + Signed-off-by: Gwenole Beauchesne + +2011-07-21 14:31:30 +0200 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2011-12-07 14:17:32 +0100 Gwenole Beauchesne + + * configure.ac: + * debian.upstream/control.in: + debian: build against upstream libva packages. + +2011-12-07 13:52:17 +0100 Gwenole Beauchesne + + * docs/reference/libs/Makefile.am: + * docs/reference/plugins/Makefile.am: + * tests/Makefile.am: + Fix build on Ubuntu 11.10 (Oneric). + +2011-12-07 13:14:28 +0100 Gwenole Beauchesne + + * NEWS: + 0.2.7. + +2011-09-12 16:20:16 -0400 Nicolas Dufresne + + * .gitignore: + Adding ignore file + Signed-off-by: Gwenole Beauchesne + +2011-10-24 16:18:16 -0400 Nicolas Dufresne + + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapisink/gstvaapisink.c: + Update license in plugin definition + Signed-off-by: Gwenole Beauchesne + +2011-10-12 14:00:50 +0200 Gwenole Beauchesne + + * NEWS: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + decoder: fix use of invalid data at the end-of-stream. + +2011-10-19 14:47:31 +0200 Gwenole Beauchesne + + * gst/vaapiconvert/gstvaapiconvert.c: + vaapiconvert: fix some warnings. + +2011-10-19 14:43:56 +0200 Gwenole Beauchesne + + * configure.ac: + * debian.upstream/changelog.in: + * debian.upstream/control.in: + * debian.upstream/copyright: + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapisink/gstvaapisink.c: + Update with my current e-mail address. + +2011-10-19 14:39:21 +0200 Gwenole Beauchesne + + * NEWS: + * README: + Splitted-Desktop systems relicensed plugins and tests to LGPL v2.1+. + +2011-10-18 09:18:20 +0200 warly + + * tests/image.c: + * tests/image.h: + * tests/test-decode.c: + * tests/test-decode.h: + * tests/test-display.c: + * tests/test-h264.c: + * tests/test-h264.h: + * tests/test-mpeg2.c: + * tests/test-mpeg2.h: + * tests/test-surfaces.c: + * tests/test-textures.c: + * tests/test-vc1.c: + * tests/test-vc1.h: + * tests/test-windows.c: + switch tests licence to LGPL v2.1+ + +2011-10-18 09:06:52 +0200 warly + + * COPYING: + * README: + * debian.upstream/copyright: + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapiconvert/gstvaapiconvert.h: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapidecode/gstvaapidecode.h: + * gst/vaapisink/gstvaapisink.c: + * gst/vaapisink/gstvaapisink.h: + move plugins to LGPL v2.1+ + +2011-09-14 13:07:18 +0200 Gwenole Beauchesne + + * gst/vaapidecode/gstvaapidecode.c: + vaapidecode: fix sink caps to not expose size information. + This fixes this particular issue: + GStreamer-WARNING **: pad vaapidecode0:sink returned caps which are not + a real subset of its template caps + +2011-09-14 11:34:05 +0200 Gwenole Beauchesne + + * NEWS: + * gst/vaapidecode/gstvaapidecode.c: + vaapidecode: fix decoding of MPEG-2 PS files. + +2011-09-12 13:00:04 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/Makefile.am: + Cosmetics (sort source files). + +2011-09-08 14:50:24 +0200 Gwenole Beauchesne + + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapiconvert/gstvaapiconvert.h: + vaapiconvert: fix direct-rendering caps detection. + +2011-09-08 14:40:08 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapiimage.c: + Fix gst_vaapi_image_new_with_image(). + +2011-09-08 13:09:17 +0200 Gwenole Beauchesne + + * gst/vaapiconvert/gstvaapiconvert.c: + vaapiconvert: warn when surface failed to be updated with image. + +2011-09-06 18:34:33 +0200 Gwenole Beauchesne + + * gst/vaapiconvert/gstvaapiconvert.c: + vaapiconvert: fix autodetection for vaDeriveImage() support. + +2011-09-06 17:47:10 +0200 Gwenole Beauchesne + + * gst/vaapiconvert/gstvaapiconvert.c: + vaapiconvert: fix memory leak (VA surface image). + +2011-09-05 16:20:20 +0200 Gwenole Beauchesne + + * NEWS: + * gst/vaapiconvert/gstvaapiconvert.c: + vaapiconvert: fix direct-rendering mode. + +2011-09-06 16:49:43 +0200 Gwenole Beauchesne + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + Add gst_vaapi_video_buffer_new_from_buffer(). + Add helper function to bind a foreign buffer into a GstVaapiVideoBuffer. + Any image, surface or surface proxy will be inherited from the source buffer + if it is a GstVaapiVideoBuffer. + +2011-09-05 17:23:05 +0200 Gwenole Beauchesne + + * gst/vaapiconvert/gstvaapiconvert.c: + vaapiconvert: protect access to direct_rendering. + +2011-09-05 16:18:14 +0200 Gwenole Beauchesne + + * gst/vaapiconvert/gstvaapiconvert.c: + vaapiconvert: use gst_vaapi_display_lookup_downstream() helper to get a VA display. + +2011-08-01 14:15:39 +0200 Gwenole Beauchesne + + * NEWS: + * README: + * debian.upstream/copyright: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapidecode/gstvaapidecode.h: + Add Intel copyright information. + +2011-07-22 15:59:00 +0200 Gwenole Beauchesne + + * NEWS: + Updates. + +2011-07-22 15:55:47 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Fix build with newer FFmpeg versions. + +2011-07-22 15:39:51 +0200 Gwenole Beauchesne + + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapidecode/gstvaapidecode.h: + Fix decoding of MPEG-2 TS files. + +2011-07-22 15:34:48 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + Report caps update only once per video resolution change. + +2011-07-22 15:33:13 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapisurface.h: + Add canonical form (type name) of VA surface caps. + +2011-07-22 15:42:16 +0200 Gwenole Beauchesne + + * configure.ac: + Bump version for development. + +2011-07-19 17:38:40 +0200 Gwenole Beauchesne + + * configure.ac: + Use pretty build output with automake >= 1.11. + +2011-07-15 16:08:08 +0200 Gwenole Beauchesne + + * gst/vaapiconvert/Makefile.am: + * gst/vaapidecode/Makefile.am: + * gst/vaapisink/Makefile.am: + * tests/Makefile.am: + Fix build with libva headers not in a standard include dir. + +2011-06-14 15:59:08 +0200 Gwenole Beauchesne + + * configure.ac: + 0.2.6. + +2011-06-14 13:52:56 +0200 Gwenole Beauchesne + + * gst-libs/gst/vaapi/gstvaapi_priv.h: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidebug.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapiparamspecs.c: + * gst-libs/gst/vaapi/gstvaapiparamspecs.h: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_gst.c: + * gst-libs/gst/vaapi/gstvaapiutils_gst.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapivideosink.c: + * gst-libs/gst/vaapi/gstvaapivideosink.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapiconvert/gstvaapiconvert.h: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapidecode/gstvaapidecode.h: + * gst/vaapisink/gstvaapisink.c: + * gst/vaapisink/gstvaapisink.h: + * tests/image.c: + * tests/image.h: + * tests/test-decode.c: + * tests/test-decode.h: + * tests/test-display.c: + * tests/test-h264.c: + * tests/test-h264.h: + * tests/test-mpeg2.c: + * tests/test-mpeg2.h: + * tests/test-surfaces.c: + * tests/test-textures.c: + * tests/test-vc1.c: + * tests/test-vc1.h: + * tests/test-windows.c: + Update copyright notice. + +2011-06-14 13:51:41 +0200 Gwenole Beauchesne + + * NEWS: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideosink.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Fix licensing terms. + +2010-07-20 11:23:16 +0000 gb + + * NEWS: + 0.2.5. + +2010-07-20 11:21:37 +0000 gb + + * debian.upstream/copyright: + Fix license terms... + +2010-07-01 13:19:29 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + Render pretty background only in use-reflection=true mode. + +2010-07-01 11:43:22 +0000 gb + + * NEWS: + Updates. + +2010-07-01 11:41:23 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + Drop the GLX 1.3 requirement. + +2010-07-01 11:38:28 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + Call the GLX/Pixmap related functions through the vtable. + +2010-07-01 11:11:18 +0000 gb + + * NEWS: + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Drop dependency on libavformat. + +2010-06-22 15:15:46 +0000 gb + + * gst-libs/gst/video/gstbasevideodecoder.c: + * gst-libs/gst/video/gstbasevideodecoder.h: + Add gst_base_video_decoder_update_src_caps(). Don't forcibly set "interlaced" field if upstream elements did not have any. + +2010-06-22 14:06:25 +0000 gb + + * gst-libs/gst/video/gstbasevideodecoder.c: + * gst-libs/gst/video/gstbasevideoutils.c: + * gst-libs/gst/video/gstbasevideoutils.h: + Drop superfluous functions. + +2010-06-22 13:57:33 +0000 gb + + * gst-libs/gst/video/gstbasevideodecoder.c: + Really drop any dependency on libgstvideo. i.e. inline the helpers. + +2010-06-22 13:48:30 +0000 gb + + * gst-libs/gst/video/gstbasevideodecoder.c: + Further drop dependency on libgstvideo. + +2010-06-22 12:57:06 +0000 gb + + * gst-libs/gst/video/Makefile.am: + * gst-libs/gst/video/gstbasevideocodec.c: + * gst-libs/gst/video/gstbasevideocodec.h: + * gst-libs/gst/video/gstbasevideodecoder.c: + * gst-libs/gst/video/gstbasevideodecoder.h: + * gst-libs/gst/video/gstbasevideoutils.c: + * gst-libs/gst/video/gstbasevideoutils.h: + Add GstBaseVideoDecoder from gst-plugins-bad git. + +2010-06-15 12:36:16 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + Fix GLX version check. + +2010-06-14 14:46:41 +0000 gb + + * NEWS: + * configure.ac: + Bump version for development. + +2010-06-14 14:14:42 +0000 gb + + * NEWS: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Fix decoding of some H.264 streams. e.g. Ice Age 2 trailer. + +2010-06-14 12:58:22 +0000 gb + + * NEWS: + Update changelog. + +2010-06-14 09:20:37 +0000 gb + + * gst-libs/gst/vaapi/gstvaapicompat.h: + Fix build with older VA-API 0.29-sds. + +2010-05-18 11:22:54 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + * gst/vaapisink/gstvaapisink.h: + Fix upscaling in foreign window (Totem). + +2010-05-17 12:32:34 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + Soft validate caps since we only care about video/x-vaapi-surface as input. _setcaps() will check for other fields. + +2010-05-17 08:55:51 +0000 gb + + * NEWS: + * gst/vaapisink/gstvaapisink.c: + Fix video rendering rect within an embedder window (Totem). + +2010-05-17 08:28:28 +0000 gb + + * NEWS: + * gst/vaapisink/gstvaapisink.c: + Disable GLX rendering when vaapisink uses a foreign X window. + +2010-05-17 08:24:42 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + Simplify GLX rendering code. + +2010-05-17 07:32:10 +0000 gb + + * configure.ac: + Bump version for development. + +2010-05-16 21:44:17 +0000 gb + + * NEWS: + 0.2.3. + +2010-05-16 21:35:14 +0000 gb + + * gst/vaapidecode/gstvaapidecode.c: + Wait for at most one second for a VA surface to become available. + +2010-05-16 21:18:37 +0000 gb + + * README: + * configure.ac: + Build-Requires: gstreamer0.10 >= 0.10.10 for gst_caps_merge(). + +2010-05-16 21:17:49 +0000 gb + + * NEWS: + * README: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + Fix decoder caps to report codec aliases. + +2010-05-16 21:04:32 +0000 gb + + * NEWS: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapidecode/gstvaapidecode.h: + Fix VC-1 decoding through the playbin2 pipeline. + +2010-05-15 15:33:20 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Regularly update and expose decoder caps. + +2010-05-15 09:43:28 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Add mechanism to reinsert buffer leftovers into the queue. + +2010-05-15 06:59:54 +0000 gb + + * NEWS: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + Fix memory leak of encoded buffers. + +2010-05-15 05:36:15 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + Check for out-of-free-surfaces condition. + +2010-05-15 04:35:00 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.h: + Change GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN value to something more generic (-1). + +2010-05-15 04:25:32 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + Improve debug info for gst_vaapisink_ensure_render_rect(). + +2010-05-14 05:02:05 +0000 gb + + * configure.ac: + Bump version for development. + +2010-05-13 21:52:22 +0000 gb + + * NEWS: + 0.2.2. + +2010-05-13 21:39:58 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Improve previous fix. + +2010-05-13 21:27:43 +0000 gb + + * NEWS: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Fix a crash in the FFmpeg decoder on close. + +2010-05-13 16:41:55 +0000 gb + + * README: + Sort platforms by name. + +2010-05-13 09:40:52 +0000 gb + + * NEWS: + * configure.ac: + Bump version for development. + +2010-05-13 09:38:47 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + Add debug info for _show_frame(). + +2010-05-13 07:19:46 +0000 gb + + * Makefile.am: + Nuke older build dir. + +2010-05-13 07:19:21 +0000 gb + + * debian.upstream/control.in: + Fix packaging deps. + +2010-05-13 06:12:37 +0000 gb + + * NEWS: + Cosmetics. + +2010-05-13 06:11:42 +0000 gb + + * NEWS: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + Fix OpenGL texture internal format (Clutter). + +2010-05-13 04:40:40 +0000 gb + + * NEWS: + Respin release. + +2010-05-13 04:27:44 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + Debug video & display PARs. + +2010-05-13 04:22:31 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + Use XGetGeometry() to retrieve the window size. + +2010-05-12 19:40:30 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + Move code around. + +2010-05-12 19:35:45 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + Ensure VA display is created prior to initializing the window from a specific XID. Also move code down. + +2010-05-12 19:18:04 +0000 gb + + * README: + Drop obsolete comment. + +2010-05-12 19:14:59 +0000 gb + + * NEWS: + 0.2.1. + +2010-05-12 19:14:35 +0000 gb + + * gst/vaapidecode/gstvaapidecode.c: + Fix GstVaapiDisplay refcounting in vaapidecode. + +2010-05-12 14:10:38 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_gst.c: + Fix comment. + +2010-05-12 12:58:53 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + * gst/vaapisink/gstvaapisink.h: + Fix render rect when the foreign window size changes. + +2010-05-12 11:43:50 +0000 gb + + * NEWS: + * configure.ac: + * gst/vaapisink/Makefile.am: + * gst/vaapisink/gstvaapisink.c: + Add GstXOverlay interface to vaapisink (e.g. for Totem). + +2010-05-12 10:51:21 +0000 gb + + * README: + Update deps to match configure.ac versions. + +2010-05-12 09:34:37 +0000 gb + + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapisink/gstvaapisink.c: + Cosmetics. + +2010-05-12 09:22:49 +0000 gb + + * NEWS: + * gst/vaapidecode/Makefile.am: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapidecode/gstvaapidecode.h: + Fix vaapidecode to expose the HW supported caps only. + +2010-05-12 08:32:34 +0000 gb + + * gst/vaapidecode/gstvaapidecode.c: + Initialize decoder earlier. + +2010-05-12 08:02:45 +0000 gb + + * NEWS: + * README: + * gst/vaapidecode/gstvaapidecode.c: + Fix integration within the playbin2 pipeline. + +2010-05-12 08:02:19 +0000 gb + + * docs/reference/libs/Makefile.am: + Exclude gstvaapiutils_gst.h from docs for now. + +2010-05-12 08:00:09 +0000 gb + + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapisink/gstvaapisink.c: + Raise VA-API plugins ranks. + +2010-05-12 07:57:55 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiutils_gst.c: + * gst-libs/gst/vaapi/gstvaapiutils_gst.h: + Add gst_vaapi_display_lookup_downstream() helper. + +2010-05-11 16:23:17 +0000 gb + + * gst/vaapidecode/gstvaapidecode.c: + Use fixed caps on the src pad, they are not meant to change from video/x-vaapi-surface. + +2010-05-11 16:19:30 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst/vaapisink/gstvaapisink.c: + Expose VA display through GstVaapiVideoBuffer. + +2010-05-11 16:09:49 +0000 gb + + * gst/vaapidecode/gstvaapidecode.c: + Simplify gst_vaapidecode_set_caps() and fix memory leak. + +2010-05-11 12:06:59 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + Expose video pool display. + +2010-05-11 12:03:13 +0000 gb + + * gst-libs/gst/vaapi/gstvaapivideosink.c: + Stop iteration if there is no more element to examine. + +2010-05-10 09:32:47 +0000 gb + + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapisink/gstvaapisink.c: + Improve plugin details. + +2010-05-07 06:35:31 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapisink/gstvaapisink.c: + Factor out VA surface caps. + +2010-05-05 15:36:25 +0000 gb + + * gst/vaapidecode/gstvaapidecode.c: + Add gst_vaapidecode_ensure_display() helper for set-caps. + +2010-05-05 12:57:59 +0000 gb + + * configure.ac: + Bump version for development. + +2010-05-05 12:29:28 +0000 gb + + * NEWS: + Really make it 0.2.0. + +2010-05-05 12:28:59 +0000 gb + + * README: + More docs. + +2010-05-05 11:48:31 +0000 gb + + * docs/reference/libs/Makefile.am: + Don't exclude GstVaapiParamSpecs. + +2010-05-05 11:44:06 +0000 gb + + * docs/reference/libs/Makefile.am: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + Fix docs. + +2010-05-05 06:06:02 +0000 gb + + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapisink/gstvaapisink.c: + Lower plugins rank for now since playbin2 auto-plugging is not working properly. User applications will have to create their own pipeline or with some hacks around playbin2. + +2010-05-04 15:03:47 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + Really link all helper libraries with libtool -no-undefined. + +2010-05-04 15:02:29 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + Link helper libraries with libtool -no-undefined. + +2010-05-04 14:59:27 +0000 gb + + * configure.ac: + * debian.upstream/gstreamer-vaapi.install.in: + * gst/vaapiconvert/Makefile.am: + * gst/vaapidecode/Makefile.am: + * gst/vaapisink/Makefile.am: + Don't build plugins with SONAME. Make them plain *.so. + +2010-05-04 08:59:27 +0000 gb + + * README: + Improve documentation for release. + +2010-05-03 22:50:56 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + Fix build with older VA-API 0.29. + +2010-05-03 22:43:01 +0000 gb + + * NEWS: + 0.2.0. + +2010-05-03 22:42:46 +0000 gb + + * tests/Makefile.am: + Fix make dist. + +2010-05-03 22:36:34 +0000 gb + + * docs/reference/libs/Makefile.am: + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * docs/reference/libs/libs.core.types: + * docs/reference/plugins/Makefile.am: + * docs/reference/plugins/plugins-docs.xml.in: + * docs/reference/plugins/plugins-sections.txt: + * docs/reference/plugins/plugins.types: + Add missing docs. + +2010-05-03 22:34:53 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + Fix doc. + +2010-05-03 22:28:02 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h: + * gst/vaapidecode/gstvaapidecode.c: + * tests/test-decode.c: + Rename gst_vaapi_decoder_ffmpeg_new_from_caps() to plain gst_vaapi_decoder_ffmpeg_new(). + +2010-05-03 22:02:41 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Extract framerate information from caps. + +2010-05-03 21:49:35 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Move caps initialization to parent class. + +2010-05-03 21:25:46 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + Simplify. + +2010-05-03 21:25:26 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Fix doc. + +2010-05-03 21:14:01 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + More simplifications. + +2010-05-03 20:55:17 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * tests/test-decode.c: + Simplify GstVaapiDecoder API. + +2010-05-03 20:40:27 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.h: + Drop obsolete defs. + +2010-05-03 20:34:57 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.h: + Drop obsolete decls. + +2010-05-03 17:36:01 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst/vaapidecode/gstvaapidecode.c: + Add more aliases for MPEG-4 decoding. + +2010-05-03 17:04:00 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Use avctx->coded_{width,height} info to create the VA context. + +2010-05-03 16:54:23 +0000 gb + + * tests/test-decode.c: + * tests/test-decode.h: + Use gst_vaapi_decoder_ffmpeg_new_from_caps(). + +2010-05-03 16:41:13 +0000 gb + + * tests/test-decode.c: + * tests/test-decode.h: + * tests/test-h264.c: + * tests/test-h264.h: + * tests/test-mpeg2.c: + * tests/test-mpeg2.h: + * tests/test-vc1.c: + * tests/test-vc1.h: + Simplify tests info. + +2010-05-03 16:17:51 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Try to improve heuristics to use an AVCodecContextParser. + +2010-05-03 15:35:22 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Fix VC-1 decoding, it does not require any specific parser. + +2010-05-03 15:34:22 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + Fix VC-1 detection with older gstreamer libs (no "fourcc" field, but a "format" one). + +2010-05-03 15:29:18 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Use size information from the demuxer, whenever available. i.e. fix WMV3 decoding. + +2010-05-03 15:11:32 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapidecode/gstvaapidecode.h: + Add gst_vaapi_decoder_ffmpeg_new_from_caps() helper. + +2010-05-03 14:53:18 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + Improve WMV3 detection yet further. + +2010-05-03 13:44:41 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + Fix detection of plain old WMV3 contents. + +2010-05-03 12:25:07 +0000 gb + + * tests/test-vc1.c: + Add End-of-Sequence start code. + +2010-05-03 11:44:23 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst/vaapidecode/gstvaapidecode.c: + Fix VC-1 detection. + +2010-05-03 08:51:28 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + Fix build with older gstreamer libs where gst_buffer_unref() is not a plain function. + +2010-05-03 08:34:57 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Drop obsolete (and wrong) code. + +2010-05-03 08:33:23 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Cosmetics (spelling). + +2010-05-03 08:32:46 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Try to fix timestamps (step 1). Looks OK on H55. + +2010-05-03 07:10:04 +0000 gb + + * debian.upstream/Makefile.am: + Ship with COPYING.LIB. + +2010-05-03 07:07:27 +0000 gb + + * COPYING.LIB: + * NEWS: + * README: + * gst-libs/gst/vaapi/gstvaapi_priv.h: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidebug.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapiparamspecs.c: + * gst-libs/gst/vaapi/gstvaapiparamspecs.h: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapivalue.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapivideosink.h: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + Relicense gst-libs/ code to LGPL v2.1+. + +2010-05-03 06:49:43 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + Drop extraneous comma. + +2010-05-03 06:49:19 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + Drop variant=itu field to help codec detection. + +2010-04-30 15:50:19 +0000 gb + + * gst/vaapidecode/gstvaapidecode.c: + Decode as many surfaces as possible in gst_vaapidecode_step(). + +2010-04-30 15:37:28 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapidecode/gstvaapidecode.h: + * tests/test-decode.c: + Drop excessive threading that over-complicates synchronisation. MPEG-2 & H.264 videos now play but there are other problems (timestamps). + +2010-04-30 13:13:50 +0000 gb + + * configure.ac: + 0.2.0. + +2010-04-30 12:04:12 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Move VA context reset to AVCodecContext.get_context() as the surface sizes can change. + +2010-04-30 09:52:29 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + Fix gst_vaapi_display_has_{decoder,encoder}() to check for the entrypoint too. + +2010-04-30 09:48:41 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + Add GST_VAAPI_ENTRYPOINT_SLICE_ENCODE. + +2010-04-30 08:18:07 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Document H.264 / AVC1 format case better. + +2010-04-29 23:09:07 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Fix H.264 decoding with AVC1 format bitstreams. + +2010-04-29 22:00:37 +0000 gb + + * gst/vaapidecode/gstvaapidecode.c: + Complete initialization of the GstVaapiVideoBuffer. Some frames start to show up. + +2010-04-29 21:59:14 +0000 gb + + * gst/vaapisink/gstvaapisink.c: + Add missing GstBaseSink::buffer_alloc() override. i.e. make sure to allocate a GstVaapiVideoBuffer instead of a plain GstBuffer from the peer pad. + +2010-04-29 21:56:10 +0000 gb + + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + Export gst_vaapi_video_buffer_new(). + +2010-04-29 21:12:30 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + Fix gst_vaapi_profile_get_caps() to include the "profile" field. + +2010-04-29 17:56:42 +0000 gb + + * configure.ac: + Fix comment. + +2010-04-29 17:55:58 +0000 gb + + * NEWS: + * configure.ac: + * gst/Makefile.am: + * gst/vaapidecode/Makefile.am: + * gst/vaapidecode/gstvaapidecode.c: + * gst/vaapidecode/gstvaapidecode.h: + Add FFmpeg/VAAPI decoder for the new `vaapidecode' element. + +2010-04-29 17:51:57 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + Add gst_vaapi_decoder_pause(). + +2010-04-29 17:11:32 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Use a GstTask with start/stop semantics for the decoder thread. + +2010-04-29 16:08:46 +0000 gb + + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + Drop extraneous var. + +2010-04-29 15:45:44 +0000 gb + + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + Add support for GstVaapiSurfaceProxy to GstVaapiVideoBuffer. + +2010-04-29 14:58:45 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + Fix gst_vaapi_decoder_get_surface() status. + +2010-04-29 14:28:43 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Try to set correct timestamps to the decoded surface proxy. + +2010-04-29 12:52:27 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * tests/test-decode.c: + Add timestamps to GstVaapiSurfaceProxy. + +2010-04-29 09:43:40 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + Fix GstVaapiDecoder::destroy(): GASyncQueue is not a GObject, likewise for GstBuffer. + +2010-04-29 09:40:38 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Fix destructor, av_parser_close() does destroy the struct already, unliker avcodec_close()... + +2010-04-29 09:35:54 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + Prefer profile from codec-data if any was found there. + +2010-04-29 09:34:54 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + Improve heuristics to find the best profile. Use the highest one if no explicit match on "profile" field. + +2010-04-28 23:09:52 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + Make sure gst_vaapi_decoder_get_surface() gets unblocked on error. + +2010-04-28 22:30:50 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Fix VC-1 codec initialization, it really needs an extradata buffer. + +2010-04-28 22:16:10 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Split decoder creation with actual resources allocation and codec setup (probe). This fixes a memory leak (avctx, pctx) on destroy and most interestingly makes it possible to detect unsupported codecs. + +2010-04-28 21:58:58 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Move gst_vaapi_decoder_ffmpeg_create() call to object constructor. + +2010-04-28 21:50:44 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * tests/test-decode.c: + Add "codec-data" property for additional codec data. e.g. VC-1 sequence headers for elementary streams. + +2010-04-28 21:20:19 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Cosmetics (weird indentation). + +2010-04-28 21:15:55 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Cosmetics (extraneous variable, debug message). + +2010-04-28 09:07:45 +0000 gb + + * configure.ac: + Fix check for VA-API enabled FFmpeg. + +2010-04-27 15:26:19 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + - Add PTS and framerate information. - Simplify parsing with an AVCodeParserContext. + +2010-04-27 11:59:23 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + Add more error codes. Fix documentation. + +2010-04-26 13:30:27 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + Fix gst_vaapi_profile_get_codec(). Improve gst_vaapi_profile_from_caps() for H.264 & caps with "codec-data". + +2010-04-26 11:44:32 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * tests/test-decode.c: + Handle user end-of-streams. Add gst_vaapi_decoder_{start,stop}() helpers. + +2010-04-26 11:36:12 +0000 gb + + * tests/test-vc1.c: + Drop useless End-of-Sequence marker. + +2010-04-26 08:53:18 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + Flush stream only if avcodec_decode_video() read something. Otherwise, we might still have to seek into the stream. i.e. keep the data longer. + +2010-04-26 08:40:27 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + Use a recursive mutex so that a single thread can lock several times. This fixes decoding of MPEG-2 and H.264 because those created a GstVaapiContext later through avcodec_decode_video() that was a protected call. + +2010-04-26 08:15:58 +0000 gb + + * tests/test-h264.c: + * tests/test-vc1.c: + Regenerate correct clips. + +2010-04-23 16:11:55 +0000 gb + + * tests/Makefile.am: + * tests/test-decode.c: + * tests/test-h264.c: + * tests/test-h264.h: + * tests/test-mpeg2.c: + * tests/test-mpeg2.h: + * tests/test-vc1.c: + * tests/test-vc1.h: + Add decoder demos. Use -c (mpeg2|h264|vc1) to select the codec. + XXX: only VC-1 decoding works at this time because of awful + bugs left in GstVaapiDecoderFfmpeg et al. + +2010-04-23 16:05:58 +0000 gb + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + Add initial (multithreaded) decoder based on FFmpeg. + There are tons of bugs left: + - Decoder API not nice enough with error conditions + - FFmpeg parser is sometimes broken + - Packets queue can be lost + +2010-04-23 16:00:50 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + Add surface proxy that holds a reference to the parent surface and that returns the surface to that context on destruction. + +2010-04-23 15:59:31 +0000 gb + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + Add VA context abstraction. + +2010-04-23 10:58:19 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.h: + Fix VA profiles definitions for gst_vaapi_profile_get_codec() to work. + +2010-04-21 15:03:31 +0000 gb + + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + Add a means to cap the number of objects allocated in the pool. + +2010-04-21 15:02:23 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + Add VA entrypoint abstraction. + +2010-04-20 13:36:04 +0000 gb + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * tests/test-display.c: + Add VA profile abstraction. + +2010-04-20 07:51:23 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + Fix OpenGL rendering on G45 systems. + +2010-04-16 13:47:30 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + Fix gl_create_context() to find a GLXFBConfig compatible with the parent GL context. + +2010-04-02 11:27:23 +0000 gb + + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + Fix TFP logic and simplify the FBO model. i.e. it's not necessary to create another texture (and storage) for the TFP, simply a new texture name. + +2010-04-01 16:11:54 +0000 gb + + * gst-libs/gst/vaapi/gstvaapitexture.c: + Fix get-out conditions. + +2010-04-01 15:38:59 +0000 gb + + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + The shared GL context in GstVaapiTexture is only useful for cases where TFP+FBO are used, thus avoiding the need fully preserve the states and call into glGet*() functions that need synchronization. + +2010-04-01 13:55:19 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + Shorter structs. + +2010-04-01 13:41:24 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * tests/test-windows.c: + Make more helpers internal, thus reducing .text size further. Add gst_vaapi_display_x11_get_screen() helper along the way. + +2010-04-01 09:47:59 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapi_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Move GST_VAAPI_DISPLAY_VADISPLAY() and GST_VAAPI_DISPLAY_{LOCK,UNLOCK}() to gstvaapidisplay_priv.h. + +2010-03-31 15:25:19 +0000 gb + + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + Improve handling of GL contexts. + +2010-03-30 16:41:21 +0000 gb + + * configure.ac: + Simplify summary. + +2010-03-30 13:33:12 +0000 gb + + * configure.ac: + Bump version for development. + +2010-03-30 13:29:34 +0000 gb + + * configure.ac: + * debian.upstream/Makefile.am: + * debian.upstream/control.in: + Rename -dev package to libgstvaapi-dev. + +2010-03-30 13:17:12 +0000 gb + + * NEWS: + * README: + Updates. + +2010-03-30 13:05:31 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils.c: + Fix build with VA-API < 0.30. + +2010-03-30 13:01:34 +0000 gb + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * tests/test-display.c: + Enable build without VA/GLX extensions. i.e. fallback to TFP + FBO. + +2010-03-30 12:59:15 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + Add TFP and FBO helpers. + +2010-03-30 12:55:27 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + Cosmetics. Make vaapi_check_status() use GST_DEBUG() for error messages. + +2010-03-30 08:13:34 +0000 gb + + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Use a shorter function name. + +2010-03-30 08:11:50 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + Add gst_vaapi_surface_query_status() wrapper. + +2010-03-30 07:50:11 +0000 gb + + * docs/reference/plugins/Makefile.am: + Fix leftover during migration. + +2010-03-30 07:46:47 +0000 gb + + * Makefile.am: + * configure.ac: + * docs/reference/plugins/Makefile.am: + * gst/Makefile.am: + * gst/vaapiconvert/Makefile.am: + * gst/vaapiconvert/gstvaapiconvert.c: + * gst/vaapiconvert/gstvaapiconvert.h: + * gst/vaapisink/Makefile.am: + * gst/vaapisink/gstvaapisink.c: + * gst/vaapisink/gstvaapisink.h: + * sys/Makefile.am: + * sys/vaapiconvert/Makefile.am: + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapiconvert/gstvaapiconvert.h: + * sys/vaapisink/Makefile.am: + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Rename to gst/ as sys/ was too vague. + +2010-03-30 07:39:16 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + Try to not reference VA-API types directly. + +2010-03-29 16:24:37 +0000 gb + + * sys/vaapisink/gstvaapisink.c: + Fix reflection code to preserve aspect ratio. + +2010-03-29 16:17:38 +0000 gb + + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Fix fullscreen mode. + +2010-03-29 15:59:44 +0000 gb + + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Add OpenGL reflection effect ("use-reflection"). + +2010-03-29 15:51:54 +0000 gb + + * configure.ac: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + Use a projection suitable for rotation around the Y axis. + +2010-03-29 15:03:30 +0000 gb + + * configure.ac: + * sys/vaapisink/Makefile.am: + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Don't build vaapisink/gl by default. However, if this is enabled, use the GL renderer by default. + +2010-03-29 14:50:52 +0000 gb + + * configure.ac: + * debian.upstream/Makefile.am: + * debian.upstream/control.in: + * debian.upstream/libgstvaapi-glx.install.in: + Add libgstvaapi-glx-0 package. + +2010-03-29 14:47:49 +0000 gb + + * pkgconfig/Makefile.am: + Really fix make distclean. + +2010-03-29 14:43:22 +0000 gb + + * docs/reference/libs/Makefile.am: + Fix make dist. + +2010-03-29 14:42:57 +0000 gb + + * pkgconfig/Makefile.am: + Fix make distclean. + +2010-03-29 14:40:26 +0000 gb + + * tests/Makefile.am: + Fix make dist. + +2010-03-29 14:31:17 +0000 gb + + * docs/reference/libs/Makefile.am: + * docs/reference/libs/libs.core.types: + * docs/reference/libs/libs.glx.types: + * docs/reference/libs/libs.types: + * docs/reference/libs/libs.x11.types: + Fix doc build. + +2010-03-29 14:21:51 +0000 gb + + * sys/vaapisink/gstvaapisink.h: + Fix build without GLX. + +2010-03-29 14:13:55 +0000 gb + + * NEWS: + 0.1.2. + +2010-03-29 14:13:26 +0000 gb + + * sys/vaapisink/Makefile.am: + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Add VA/GLX support to vaapisink. + +2010-03-29 13:40:27 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + Add glXSwapBuffers() workaround for NVIDIA. + +2010-03-29 13:27:16 +0000 gb + + * tests/Makefile.am: + * tests/test-textures.c: + Improve VA/GLX textures test. + +2010-03-29 12:51:38 +0000 gb + + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + Fix texture rendering. + +2010-03-29 11:25:20 +0000 gb + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapitexture.c: + Fix documentation. + +2010-03-29 10:40:26 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + Add gst_vaapi_window_glx_put_texture() helper. + +2010-03-29 09:09:30 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + Fix typos. + +2010-03-26 17:00:45 +0000 gb + + * tests/image.c: + * tests/image.h: + * tests/test-windows.c: + Move code around. + +2010-03-26 16:52:07 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + Add initial VA/GLX texture abstraction though the API is not good enough yet. + +2010-03-26 15:22:00 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + Add gst_vaapi_object_{,un}lock_display() helpers. + +2010-03-26 15:16:01 +0000 gb + + * tests/Makefile.am: + * tests/image.c: + * tests/image.h: + * tests/test-windows.c: + Factor out image utilities. + +2010-03-26 11:54:43 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + MT-Safe: lock display. + +2010-03-26 11:50:31 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + Make sure window resize completed prior to resizing the GL viewport. + +2010-03-26 11:39:20 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + gstvaapicompat.h is a private header, don't install it. + +2010-03-26 11:35:20 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + Add gst_vaapi_display_{sync,flush}() helpers. + +2010-03-26 11:30:54 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Add "synchronous" mode. + +2010-03-26 11:02:12 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + Only add _display suffix to open & close members because they could be #define to some arbitrary value. lock/unlock are safe names. + +2010-03-26 10:09:23 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + Restore GLX context only if there is one. + +2010-03-26 09:41:12 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + Add gst_vaapi_window_glx_make_current(). Handle X11 window size changes and reset the GL viewport. + +2010-03-26 08:35:24 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + Check GstVaapiWindow::render() is available prior to calling it. + +2010-03-26 08:10:23 +0000 gb + + * tests/Makefile.am: + * tests/test-display.c: + * tests/test-textures.c: + Add VA/GLX display tests. + +2010-03-26 08:00:32 +0000 gb + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + Fix compile flags. + +2010-03-25 17:39:06 +0000 gb + + * docs/reference/libs/Makefile.am: + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * docs/reference/libs/libs.types: + Add missing API documentation. + +2010-03-25 17:28:49 +0000 gb + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * pkgconfig/Makefile.am: + * pkgconfig/gstreamer-vaapi-glx.pc.in: + * tests/Makefile.am: + * tests/test-textures.c: + Add initial VA/GLX support. + +2010-03-25 17:21:56 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Add missing includes (for vaapi_check_status()). + +2010-03-25 17:21:13 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidebug.h: + Only enable GST_DEBUG() if DEBUG is defined. Drop old D(bug()) stuff. + +2010-03-25 17:18:36 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + Add gst_vaapi_window_x11_is_foreign_xid() helper. + +2010-03-25 17:18:06 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + Allow derived classes to specify custom Visual and Colormap. + +2010-03-25 13:54:06 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Allow window creation with a specific visual (e.g. for GLX support). + +2010-03-25 13:21:19 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + Fix return value on error (though it's the same in the end). + +2010-03-25 12:39:54 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + Simplify initialization of VADisplay. + +2010-03-25 10:04:39 +0000 gb + + * configure.ac: + Move __attribute__((visibility("hidden"))) check down. + +2010-03-25 09:49:17 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * tests/test-surfaces.c: + Restore the gst_vaapi_{surface,image,subpicture}_get_id() interfaces. + +2010-03-25 09:39:17 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Use the parent display object, no need to maintain another one. + In the end, libgstvaapi-x11 reduced by 1 KB in .text vs. 0.1.1. + +2010-03-25 09:37:40 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + Add more internal helpers. + +2010-03-24 17:40:19 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Rename to GST_VAAPI_OBJECT_DISPLAY(). + +2010-03-24 17:38:23 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiparamspecs.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + All GstVaapiID are initialized to GST_VAAPI_ID_NONE by default. Besides, all GstVaapiObject derived class shall initialize "id" to a valid value. + +2010-03-24 17:22:18 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Make GstVaapiWindow* derive from GstVaapiObject. + +2010-03-24 16:37:35 +0000 gb + + * configure.ac: + Factor out use gstreamer-vaapi (PACKAGE name). + +2010-03-24 16:35:36 +0000 gb + + * configure.ac: + Improve versioning summary. + +2010-03-24 16:27:36 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + gstvaapicompat.h is now a private header (not installed). + +2010-03-24 16:25:56 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Include gstvaapicompat.h in source files only, not headers. + +2010-03-24 16:21:20 +0000 gb + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * sys/vaapiconvert/Makefile.am: + * sys/vaapisink/Makefile.am: + * tests/Makefile.am: + Drop tedious LIBVA_EXTRA_{CFLAGS,LIBS} definitions in Makefile.am. Override CFLAGS & LIBS instead. + +2010-03-24 16:17:49 +0000 gb + + * NEWS: + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * gst-libs/gst/vaapi/gstvaapiparamspecs.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * pkgconfig/gstreamer-vaapi-x11.pc.in: + * pkgconfig/gstreamer-vaapi.pc.in: + * sys/vaapiconvert/Makefile.am: + * sys/vaapisink/Makefile.am: + * tests/Makefile.am: + Add compatibility with the original VA-API 0.29. + +2010-03-24 15:18:33 +0000 gb + + * gst-libs/gst/vaapi/gstvaapivalue.h: + Add missing file (gstvaapivalue.h). + +2010-03-24 15:12:56 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + Fix g_warning() invocation. + +2010-03-24 15:11:26 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurface.c: + Deassociate subpictures while destroying the surface. + +2010-03-24 14:57:33 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurface.c: + Fix destruction order of subpictures. They should be destroyed first. + +2010-03-24 14:46:33 +0000 gb + + * NEWS: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * tests/test-windows.c: + Add support for AYUV format. + +2010-03-24 14:36:39 +0000 gb + + * tests/test-windows.c: + Simplify upload process and fallback to subpictures. + +2010-03-24 13:44:01 +0000 gb + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiparamspecs.c: + Fix documentation. + +2010-03-24 13:37:38 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiparamspecs.c: + * gst-libs/gst/vaapi/gstvaapitypes.c: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + Move GValue specific stuff to a dedicated file. + +2010-03-24 13:22:25 +0000 gb + + * tests/test-surfaces.c: + Cosmetics (lowercase for consistency). + +2010-03-24 13:21:54 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiobject.c: + Cosmetics (vertical alignment). + +2010-03-24 13:20:34 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiobject.c: + Fix return value on error. + +2010-03-24 13:19:58 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * tests/test-surfaces.c: + Move "id" down to the GstVaapiObject base. + +2010-03-24 12:59:22 +0000 gb + + * gst-libs/gst/vaapi/gstvaapitypes.c: + Cosmetics (drop extraneous empty line). + +2010-03-24 12:57:54 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiparamspecs.c: + * gst-libs/gst/vaapi/gstvaapiparamspecs.h: + Add GParamSpecs for GstVaapiID. + +2010-03-24 12:54:52 +0000 gb + + * docs/reference/libs/libs.types: + Drop gst_vaapi_id_get_type(). + +2010-03-24 12:38:40 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapitypes.h: + Add GST_VAAPI_ID_FORMAT() and GST_VAAPI_ID_ARGS() helpers. + +2010-03-24 09:52:43 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * docs/reference/libs/libs.types: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapitypes.c: + * gst-libs/gst/vaapi/gstvaapitypes.h: + Add GstVaapiID abstraction. + +2010-03-24 09:22:00 +0000 gb + + * docs/reference/libs/libs.types: + Sort types. + +2010-03-24 08:35:27 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + Drop useless include (). + +2010-03-24 08:34:11 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + Optimize GST_VAAPI_OBJECT_GET_DISPLAY to avoid a run-time check. + +2010-03-24 08:32:12 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Move private definitions and accessors to gstvaapiobject_priv.h. + +2010-03-24 08:16:32 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideosink.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Fix short descriptions. + +2010-03-23 18:45:09 +0000 gb + + * Makefile.am: + * configure.ac: + * debian.upstream/Makefile.am: + * debian.upstream/changelog.in: + * debian.upstream/compat: + * debian.upstream/control.in: + * debian.upstream/copyright: + * debian.upstream/gstreamer-vaapi-doc.install.in: + * debian.upstream/gstreamer-vaapi.install.in: + * debian.upstream/libgstvaapi-dev.install.in: + * debian.upstream/libgstvaapi-x11.install.in: + * debian.upstream/libgstvaapi.install.in: + * debian.upstream/rules: + * debian/Makefile.am: + * debian/changelog.in: + * debian/compat: + * debian/control.in: + * debian/copyright: + * debian/gstreamer-vaapi-doc.install.in: + * debian/gstreamer-vaapi.install.in: + * debian/libgstvaapi-dev.install.in: + * debian/libgstvaapi-x11.install.in: + * debian/libgstvaapi.install.in: + * debian/rules: + Generate upstream packages through make deb.upstream. + +2010-03-23 17:40:03 +0000 gb + + * configure.ac: + Bump version for development. + +2010-03-23 17:29:47 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + Use a black background for new windows. + +2010-03-23 17:18:35 +0000 gb + + * NEWS: + 0.1.1. + +2010-03-23 17:12:40 +0000 gb + + * configure.ac: + * docs/reference/libs/libs.types: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapimarshal.list: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * tests/test-surfaces.c: + Add "destroy" signal. + +2010-03-23 16:25:20 +0000 gb + + * docs/reference/libs/libs-docs.xml.in: + Improve gst-plugins-vaapi Library reference template. + +2010-03-23 16:21:28 +0000 gb + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Make GstVaapi{Surface,Image,Subpicture} derive from a GstVaapiObject. + +2010-03-23 16:11:21 +0000 gb + + * sys/vaapisink/gstvaapisink.c: + Fix return value. + +2010-03-23 15:34:51 +0000 gb + + * sys/vaapisink/gstvaapisink.c: + Make sure VA display is valid when created with an explicit "display" name. + +2010-03-23 15:28:50 +0000 gb + + * sys/vaapisink/gstvaapisink.c: + Use plain "display" property for the X11 display name. + +2010-03-23 15:22:47 +0000 gb + + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapisink/gstvaapisink.c: + Document vaapiconvert & vaapisink plugins. + +2010-03-23 14:19:21 +0000 gb + + * configure.ac: + * docs/reference/Makefile.am: + * docs/reference/plugins/Makefile.am: + * docs/reference/plugins/plugins-docs.xml.in: + * docs/reference/plugins/plugins-overrides.txt: + * docs/reference/plugins/plugins-sections.txt: + * docs/reference/plugins/plugins.types: + Add plugins documentation template. + +2010-03-23 14:06:42 +0000 gb + + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Don't export gst_vaapisink_get_display(). + +2010-03-23 13:32:36 +0000 gb + + * configure.ac: + * docs/reference/libs/libs-docs.xml.in: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + Drop introspection annotations since they require gtk-doc >= 1.12. + +2010-03-23 10:51:35 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurface.c: + Add note about the fact that the surface holds an extra reference to the subpicture. + +2010-03-23 10:49:33 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + Improve debugging messages. + +2010-03-23 10:48:58 +0000 gb + + * tests/test-windows.c: + Unref subpicture earlier as the surface is supposed to hold a reference to it. + +2010-03-23 10:36:20 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * tests/test-windows.c: + Add gst_vaapi_surface_{,de}associate_subpicture() API. + +2010-03-23 08:13:37 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Wait for MapNotify or UnmapNotify events on foreign windows too. + +2010-03-23 07:42:05 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Check whether the foreign XID is mapped at binding time. + +2010-03-23 07:34:15 +0000 gb + + * sys/vaapisink/gstvaapisink.c: + Add missing includes. + +2010-03-23 07:31:04 +0000 gb + + * configure.ac: + * debian/Makefile.am: + * debian/control.in: + * debian/gstreamer-vaapi-doc.install.in: + * debian/rules: + Add -doc package. + +2010-03-23 06:41:29 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Fix warnings (drop extraneous var). + +2010-03-23 06:40:27 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + Add GST_VAAPI_WINDOW_XWINDOW() helper macro. + +2010-03-22 16:59:29 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + Shorten condition. + +2010-03-22 16:57:20 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Try to improve switch to fullscreen mode. + +2010-03-22 16:01:34 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Improve display locking and rework X event wait functions. + +2010-03-22 13:06:41 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + Move _GstVaapiWindowPrivate declaration to gstvaapiwindow_priv.h. + +2010-03-22 13:05:05 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + Add private API to set window size & fullscreen modes without triggering any notification or virtual functions. This is useful for derived class to fix up sizes whenever appropriate. + +2010-03-22 12:47:13 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + Add gst_vaapi_window_get_fullscreen() helper and "fullscreen" property. + +2010-03-22 12:39:02 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Add gst_vaapi_window_get_display() to base. + +2010-03-22 12:16:47 +0000 gb + + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Add GstVaapiPoint & GstVaapiRectangle data structures. + +2010-03-22 12:05:11 +0000 gb + + * NEWS: + 0.1.1. + +2010-03-22 12:03:26 +0000 gb + + * NEWS: + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Allow `vaapisink` to render videos in fullscreen mode. + +2010-03-22 10:51:49 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Add gst_vaapi_window_set_fullscreen() API. + +2010-03-22 10:03:24 +0000 gb + + * sys/vaapisink/gstvaapisink.c: + Size window so that to respect the video and pixel aspect ratio. + +2010-03-22 09:32:01 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * tests/test-display.c: + Add gst_vaapi_display_get_pixel_aspect_ratio(). + +2010-03-22 08:45:03 +0000 gb + + * docs/reference/libs/libs-sections.txt: + Updates. + +2010-03-22 08:44:38 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * tests/test-display.c: + Add display size accessors. + +2010-03-22 08:03:12 +0000 gb + + * configure.ac: + * debian/control.in: + Build-Requires: gstreamer-plugins-base >= 0.10.16. + +2010-03-21 08:45:09 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + Fix documentation of *Class'es. + +2010-03-21 08:38:17 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Move GstVaapiSurfaceRenderFlags conversion to get_PutSurface_flags_from_GstVaapiSurfaceRenderFlags(). + +2010-03-21 08:22:46 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + Move GstVaapiSurfaceRenderFlags to gstvaapisurface.h since this will also be useful for e.g. a gstvaapitexture.h. + +2010-03-21 08:12:52 +0000 gb + + * docs/reference/libs/libs-sections.txt: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * sys/vaapisink/gstvaapisink.c: + * tests/test-windows.c: + Rename gst_vaapi_window_put_surface_full() to plain gst_vaapi_window_put_surface(). + +2010-03-19 17:15:16 +0000 gb + + * docs/reference/libs/Makefile.am: + Fix make dist for --enable-gtk-doc builds. + +2010-03-19 17:13:59 +0000 gb + + * autogen.sh: + Improve autogen.sh. + +2010-03-19 17:11:20 +0000 gb + + * Makefile.am: + * autogen.sh: + Generate gtk-doc.make from gtkdocize. + +2010-03-19 17:04:51 +0000 gb + + * Makefile.am: + * NEWS: + * configure.ac: + * docs/Makefile.am: + * docs/reference/Makefile.am: + * docs/reference/libs/Makefile.am: + * docs/reference/libs/libs-docs.xml.in: + * docs/reference/libs/libs-overrides.txt: + * docs/reference/libs/libs-sections.txt: + * docs/reference/libs/libs.types: + Document public API for libgstvaapi-*.so.*. + +2010-03-19 16:41:52 +0000 gb + + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + Document GstVaapiVideoBuffer. + +2010-03-19 16:08:48 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + Document surface & image pools. Drop obsolete gst_vaapi_video_pool_new() function. + +2010-03-19 15:45:21 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapivideosink.c: + * gst-libs/gst/vaapi/gstvaapivideosink.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + Add tedious documentation. + +2010-03-19 10:42:11 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + Beautify append_formats(). + +2010-03-19 10:38:45 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + Simplify GstVaapiDisplay (use GArray). + +2010-03-19 08:42:51 +0000 gb + + * NEWS: + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapiconvert/gstvaapiconvert.h: + Factor out direct-rendering infrastructure. + +2010-03-18 16:18:17 +0000 gb + + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapiconvert/gstvaapiconvert.h: + Allow user to specify inout-buffers & derive-image optimizations. + +2010-03-18 15:58:28 +0000 gb + + * sys/vaapiconvert/gstvaapiconvert.c: + Reduce number of debug messaged printed out. + +2010-03-18 15:53:50 +0000 gb + + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapiconvert/gstvaapiconvert.h: + Add vaDeriveImage() optimization. + +2010-03-18 15:52:20 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + Fix gst_vaapi_image_create() from a foreign VA image. + +2010-03-18 15:28:59 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + Add gst_vaapi_surface_derive_image() API. + +2010-03-18 13:49:50 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Make it possible to bin an X11 window to GstVaapiWindowX11 with plain g_object_new() and "xid" property. i.e. get foreign window size in gst_vaapi_window_x11_create(). + +2010-03-18 13:08:17 +0000 gb + + * tests/test-windows.c: + Try YV12 & I420 image formats too. + +2010-03-18 12:59:55 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + Split map/unmap functions into internal functions that don't check preconditions. + +2010-03-18 12:56:53 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + Improve gst_vaapi_image_new() sanity checks. + +2010-03-18 12:52:58 +0000 gb + + * tests/test-windows.c: + Fix typo. + +2010-03-18 08:45:57 +0000 gb + + * sys/vaapiconvert/gstvaapiconvert.c: + Check if our inout buffer is still alive or default to a separate output buffer. + +2010-03-18 08:16:59 +0000 gb + + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapiconvert/gstvaapiconvert.h: + Factor out buffers negotiation and optimization checks. + +2010-03-18 08:02:25 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * sys/vaapiconvert/gstvaapiconvert.h: + Use gtypes. + +2010-03-17 10:43:02 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + Optimize gst_vaapi_image_is_linear() and simplify gst_vaapi_image_update_from_buffer(). + +2010-03-17 07:59:31 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Add VA display locking utilities. + +2010-03-17 07:20:19 +0000 gb + + * sys/vaapisink/gstvaapisink.c: + Initialize the X window in a ::set_caps() handler. Also fix build with GStreamer < 0.10.25. i.e. use preroll/render hooks. + +2010-03-17 07:17:17 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * tests/test-windows.c: + Don't show window by default during creation. + +2010-03-17 06:49:27 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Fix gst_vaapi_window_x11_destroy(). + +2010-03-16 17:57:57 +0000 gb + + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapiconvert/gstvaapiconvert.h: + Alias sink & src pad buffers whenever possible. + +2010-03-16 17:57:23 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + Extend GstVaapiImage API with *_get_image(), *_is_linear(), *_get_data_size(). + +2010-03-16 17:10:02 +0000 gb + + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + Make GstVaapiVideoBuffer handle two pools. i.e. both image & surface at the same time. + +2010-03-16 14:37:47 +0000 gb + + * sys/vaapiconvert/gstvaapiconvert.c: + Fix image & surface size cache. + +2010-03-16 14:12:40 +0000 gb + + * configure.ac: + Move gstreamer-vaapi package versioning to the top. + +2010-03-16 14:11:46 +0000 gb + + * configure.ac: + Bump version for development. + +2010-03-16 14:07:53 +0000 gb + + * configure.ac: + Cosmetics (shorten lines). + +2010-03-16 13:58:43 +0000 gb + + * NEWS: + * README: + Update docs. + +2010-03-16 13:53:54 +0000 gb + + * debian/Makefile.am: + * debian/changelog.in: + * debian/compat: + * debian/control.in: + * debian/copyright: + * debian/gstreamer-vaapi.install.in: + * debian/libgstvaapi-dev.install.in: + * debian/libgstvaapi-x11.install.in: + * debian/libgstvaapi.install.in: + * debian/rules: + Add debian packaging. + +2010-03-16 13:53:09 +0000 gb + + * Makefile.am: + * configure.ac: + Add debian packaging. + +2010-03-16 10:13:36 +0000 gb + + * pkgconfig/Makefile.am: + Silence GNU make extensions warning. + +2010-03-16 09:59:03 +0000 gb + + * configure.ac: + Add AM_PROG_CC_C_O, thus fixing this warning: tests/Makefile.am:16: compiling `test-display.c' with per-target flags requires `AM_PROG_CC_C_O' in `configure.ac' + +2010-03-16 09:57:25 +0000 gb + + * Makefile.am: + * configure.ac: + * pkgconfig/Makefile.am: + * pkgconfig/gstreamer-vaapi-x11.pc.in: + * pkgconfig/gstreamer-vaapi.pc.in: + Add pkgconfig files. + +2010-03-16 09:39:07 +0000 gb + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * sys/vaapisink/Makefile.am: + * tests/Makefile.am: + Split X11 support to libgstvaapi-x11-*.so.* + +2010-03-16 09:21:15 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + Don't install private headers. + +2010-03-16 09:18:57 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidebug.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + Fix header guards. + +2010-03-16 09:17:41 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidebug.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/vaapi_debug.h: + Rename vaapi_debug.h to gstvaapidebug.h. + +2010-03-16 09:15:48 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/vaapi_debug.h: + * gst-libs/gst/vaapi/vaapi_utils.c: + * gst-libs/gst/vaapi/vaapi_utils.h: + Move vaapi_utils.* to gstvaapiutils.* + +2010-03-16 09:13:16 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + Cosmetics (remove an extra line). + +2010-03-16 09:12:47 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Move X11 utilties to gstvaapiutils_x11.[ch]. + +2010-03-16 09:03:10 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapisinkbase.c: + * gst-libs/gst/vaapi/gstvaapisinkbase.h: + * gst-libs/gst/vaapi/gstvaapivideosink.c: + * gst-libs/gst/vaapi/gstvaapivideosink.h: + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapisink/gstvaapisink.c: + Rename GstVaapiSinkBase to GstVaapiVideoSink. + +2010-03-16 08:49:16 +0000 gb + + * configure.ac: + * tests/Makefile.am: + * tests/examples/Makefile.am: + * tests/examples/generic/Makefile.am: + * tests/examples/generic/test-display.c: + * tests/examples/generic/test-surfaces.c: + * tests/examples/generic/test-windows.c: + * tests/test-display.c: + * tests/test-surfaces.c: + * tests/test-windows.c: + Move tests to top-level tests/ directory. + +2010-03-16 08:43:16 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapiconvert/gstvaapiconvert.h: + Handle I420 formats internally in GstVaapiImage. + +2010-03-15 17:44:35 +0000 gb + + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapiconvert/gstvaapiconvert.h: + Implement I420 (resp. YV12) with YV12 (resp. I420) if the driver does not. + +2010-03-15 17:43:29 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + Implement I420 and YV12 if the underlying implementation does not. + +2010-03-15 17:10:56 +0000 gb + + * sys/vaapiconvert/Makefile.am: + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapiconvert/gstvaapiconvert.h: + Add initial vaapiconvert plugin. + +2010-03-15 17:09:12 +0000 gb + + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Display frames. + +2010-03-15 16:57:37 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + Factor out. + +2010-03-15 16:57:01 +0000 gb + + * tests/examples/generic/test-windows.c: + Generate R/G/B rects. + +2010-03-15 16:13:51 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + Add gst_vaapi_surface_sync(). + +2010-03-15 16:13:37 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + Cosmetics (reverse args order). + +2010-03-15 15:55:20 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + Cosmetics. + +2010-03-15 15:12:27 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + * tests/examples/generic/Makefile.am: + * tests/examples/generic/test-windows.c: + Add VA/X11 window abstraction. + +2010-03-15 14:57:57 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + Add VA and X11 display accessors. + +2010-03-15 14:57:30 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + Fix preconditions. + +2010-03-15 13:32:37 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + Cosmetics. + +2010-03-15 11:49:03 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + Add gst_vaapi_{get,put}_image() API. + +2010-03-15 10:27:10 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + Add gst_vaapi_image_update_from_buffer() helper. + +2010-03-12 23:53:48 +0000 gb + + * sys/vaapisink/Makefile.am: + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Implement GstVaapiSinkBase interface and integrate with GST_DEBUG better. + +2010-03-12 23:50:09 +0000 gb + + * tests/examples/generic/Makefile.am: + * tests/examples/generic/test-surfaces.c: + Add surface tests. + +2010-03-12 23:48:50 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapivideobuffer.c: + * gst-libs/gst/vaapi/gstvaapivideobuffer.h: + Add basic GstVaapiVideoBuffer. + +2010-03-12 23:47:47 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool.h: + Add GstVaapiImagePool and factor out GstVaapiSurfacePool from a base GstVaapiVideoPool. + +2010-03-12 22:32:35 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + Simplify format conversion code. + +2010-03-12 22:28:01 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + Add gst_vaapi_image_format_from_caps() helper. + +2010-03-12 17:45:18 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + Add VA surface pool (lazy allocator). + +2010-03-12 17:39:11 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + Add gst_vaapi_surface_get_size() helper. + +2010-03-12 10:52:08 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + Avoid use of GstStaticCaps since older gstreamer versions (0.10.22) write to it. + +2010-03-11 15:35:43 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + Reset display-name if the user provided his own X11 display. + +2010-03-11 15:21:43 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * tests/examples/generic/test-display.c: + Add gst_vaapi_display_x11_new_with_display() API. + +2010-03-11 15:04:18 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.h: + Fix *_GET_CLASS() definitions... + +2010-03-11 15:01:00 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * tests/examples/generic/test-display.c: + API change: gst_vaapi_display_x11_new() now takes an X11 display name. + +2010-03-11 13:58:32 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + Use GstVaapiChromaType abstraction. + +2010-03-11 12:30:12 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + New refcounting policy. All getters return a reference, not a copy. So the user shall reference the object itself, should he wish so. + +2010-03-11 12:14:10 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + Don't warn on failure, just return an appropriate error or value. + +2010-03-11 12:11:36 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + Filter out any format that is not supported by the library (libgstvaapi). Also sort the formats by HW preference. + +2010-03-11 10:50:27 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapisinkbase.c: + * gst-libs/gst/vaapi/gstvaapisinkbase.h: + Add helper interface that all VA-API sinks must implement. e.g. vaapisink. + +2010-03-10 13:13:51 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/vaapi_debug.h: + Use GST_DEBUG. + +2010-03-10 13:10:59 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + Fix GstVaapiImage and GstVaapiSubpicture initialization. + +2010-03-10 13:02:45 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurface.c: + Fix GstVaapiSurface initialization, override constructed() method, not constructor(). GObject C is awful... + +2010-03-10 12:25:38 +0000 gb + + * tests/examples/generic/test-display.c: + Dump caps. + +2010-03-10 12:25:19 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + Fix GstVaapiDisplay initialization. + +2010-03-10 10:43:31 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + Get VA image & subpicture formats as GstCaps. + +2010-03-10 10:41:12 +0000 gb + + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + Add helper to convert from GstVaapiImageFormat to GstCaps. + +2010-03-09 12:00:32 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + Cosmetics (drop unused variables). + +2010-03-05 17:11:52 +0000 gb + + * configure.ac: + * sys/vaapiconvert/Makefile.am: + * sys/vaapiconvert/gstvaapiconvert.c: + * sys/vaapiconvert/gstvaapiconvert.h: + * sys/vaapisink/Makefile.am: + * sys/vaapisink/gstvaapisink.c: + * sys/vaapisink/gstvaapisink.h: + Add boilerplate for vaapiconvert and vaapisink elements. + +2010-03-05 15:29:04 +0000 gb + + * configure.ac: + * sys/Makefile.am: + * sys/vaapiconvert/Makefile.am: + Add vaapiconvert element hierarchy. + +2010-03-05 15:26:36 +0000 gb + + * sys/vaapi/Makefile.am: + * sys/vaapisink/Makefile.am: + Rename to vaapisink. + +2010-03-05 10:07:22 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurface.c: + Shorter code (and more correct). + +2010-03-05 10:04:55 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + Add helper to get GstVaapiDisplay from a surface. + +2010-03-05 08:52:20 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + Fix subpicture formats list length. + +2010-03-04 17:41:34 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + Add utilities to check whether a VA-API driver supports specific image or subpicture format. Likewise for VA profile. + +2010-03-04 17:40:47 +0000 gb + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + Cosmetics (more checks, includes). + +2010-03-04 17:39:58 +0000 gb + + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + Really add VA subpicture abstraction. + +2010-03-04 17:39:01 +0000 gb + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimageformat.c: + * gst-libs/gst/vaapi/gstvaapiimageformat.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + Add VA surface, image, subpicture abstractions. Ported over from Gnash. + +2010-01-25 16:15:01 +0000 gb + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/vaapi_debug.h: + * gst-libs/gst/vaapi/vaapi_utils.c: + * gst-libs/gst/vaapi/vaapi_utils.h: + * tests/examples/generic/Makefile.am: + * tests/examples/generic/test-display.c: + Add initial VA display abstraction. + +2010-01-25 15:04:10 +0000 gb + + * Makefile.am: + * configure.ac: + * tests/Makefile.am: + * tests/examples/Makefile.am: + * tests/examples/generic/Makefile.am: + Add tests infrastructure. + +2010-01-25 14:59:37 +0000 gb + + * configure.ac: + Clean up VA-API checks. + +2010-01-25 13:49:55 +0000 gb + + * configure.ac: + Check for __attribute__((visibility("hidden"))). + diff --git a/NEWS b/NEWS index a17ea5fd62..1fee7899fa 100644 --- a/NEWS +++ b/NEWS @@ -1,386 +1 @@ -gst-vaapi NEWS -- summary of changes. 2015-12-07 -Copyright (C) 2010-2011 Splitted-Desktop Systems -Copyright (C) 2011-2015 Intel Corporation -Copyright (C) 2011 Collabora - -Version 0.7 - 07.Dec.2015 -* Add VP9 Decoder -* Improvements to HEVC(H265) decoder - + Fix the decoding of dependent slice segment - + Fix decoding of stream when it has temporal sublayers - + Added Workaround to recognize wrongly encoded main profile streams - + Add SEI Header parsing - + Fix the value assigning for delta_chroma_log2_weight_denom - + Fix default value assignment of pred_weight_table - + Fix ChromaOffsetL0/ChromaOffsetL1 calculation - + Add calculation of WpOffsetHalfRangeC - + Fix the scaling list scan order - + Fix the picture addition in dpb() based on spec H265 v3 (04/2015) - + Fix the dpb_add() based on C.5.2.3 - + Fix flushing of dpb for EOS/EOB nal -* Added infrastructure for handling corrupted pictures in h264 decoder [#703921, #751434] -* Add number of fixes and optimizations to GstContext sharing [#757598] -* Add API for dynamic detection of OpenGL API in use [#753099] -* Make vaapidecode + glimagesink combination work with opengl3 [#753099] -* Fix segfault in vaapipostproc [#752558] -* Fix seeking while using GLTextureUpload for rendering [#752929] -* Ported JPEG decoder to new API/ABI changes in codecparser -* Removed gstvaapiuploader [#752777] -* Fix 0/1 frame-rate handling in encoder [#744042] -* Validate chroma sampling according to the VA's RT format in Encoder [#744042] -* Number of improvements in vaapi video memory handling [#744042] -* Stabilization of vaapidecodebin [#749554, #757957] -* Wayland fixes: Don't return GST_FLOW_ERROR on flushing [#753598] -* Add yasm as build dependency -* Remvoved custom(non-official) debian parallel compilation option -* Fix multi-resolution video handling in vaapidecode [#753914] -* Adding stereoscopic/multiview upstream API support [#750835] -* Fixed fps calculation for for forced latency framerate [#755040] -* Fix build issues while disabling built-in codecparsers [#754845] -* Mark support for GStreamer 1.2 as obsolete -* Update libvpx submodule to 1.4.0 -* Fix caps negotiation for meta:GstVideoGLTextureUploadMeta [#756686] -* Fixed leaked display instance in vaapidecodebin [#757595] - -Version 0.6 - 15.Jul.2015 -* Add HEVC(H265) Decoder -* Add HEVC(H265) Encoder -* Add VP8 Encoder -* Add JPEG Encoder -* Add support for EGL [#743846, #743847, #741079] -* Add a vaapidecodebin(vaapidecode->queue->vaapipostproc) element [#745216] -* Add skin-tone-enhancement feature in vaapipostproc [#744088] -* Add support for H.264 MVC Multiview High profile encoding with more than 2 views [#732453] -* Add support for GstVideoGLTextureOrientation in plugins -* Add support for BGRA textures in plugins -* Removed all GStreamer 0.10 and 1.0 specific code sections [#745728,#732666] -* Add support for loss of picturers in h264 decoder [#745048,#703921] -* Add a simple-encoder test program that uses libgstvaapi for video encoding [#719528] -* Add finer wayland frame control and many other optimizations [#719528, #749078, #747492#] -* Add scaling of quality factor and Qantization tables for JPEG encoder [#748335] -* Add GstColorBalance interface in vaapipostproc [#720376] -* Add a handoff signal to vaapisink [#747905] -* Add rounding control handling for VC1 simple and Main profile [#743958] -* Record glconext supplied by downstream to enable run-time compatibility check [#725643] -* Switch back to single thread implementation in vaapidecode [#742605] -* Set decoding latency in vaapidecode by assuming realtime performance fo the HW decoding [#740419] -* Allow vaapidecode to connect with glimagesink, mark x11 display as compatible with EGL [#745902] -* Allow decoding of VC1 streams which contain user BDUs [#741237] -* Use git.mk, a small Makefile to autogenerate .gitignore files -* Expose the overlay capability in vaapisink for compatibility with dvbsuboverlay [#750095] -* Enable VPP element in vaapidecodebin only if there is HW support [#749554] -* Fix autoplugging of vaapidecode in playbin for wmv/asf streams -* Fix multi-slice hevc encoding [#749854] -* Fix ABBA deadlock between vaapisink and vaapipostproc if running in different threds [#738249] -* Fix Seeking failure while using navseek in pipeline [#738677] -* Fix PTS cache for MPEG2 GOP start [#748676] -* Fix the wrong selection of passthrough mode in vaapipostproc [#748184] -* Fix GstVaapiVideoPool related dead-lock [#747944] -* Fix the race condition while setting drm device type [#747914] -* Fix crash in vaapidecode if buffer outlives the decoder [#745189] -* Fix memory leak in vaapidecode [#743226] -* Fix multiple caps negotiation issues with vaapi elements [#744618] -* Improve check for upstream element that requires DMABUF buffer pool -* Fix vaapisink memory leak in debug mode -* Fix crash when seeking mpeg2 strems -* Fix support for Wayland/EGL running alongside X11 - -Version 0.5.10 - 3.Feb.2015 -* Add support for DRM Render-Nodes for headless operation -* Add support for VA surface buffer sharing with DMABUF and GEM handles -* Add support for v4l2src with io-mode={dmabuf,dmabuf-import} -* Drop support for VA/GLX specific APIs in libgstvaapi and vaapisink [#736711] -* Improvements to H.264 codecs - + Fix profile limits for encoding - + Fix pixel-aspect-ratio in the encoded stream - + Add decoding support for interlaced streams with repeat-first-field (RFF) - + Fix decoding of interlaced streams in top-field-first order (TFF) [#739291] - + Fix decoding of UK DVB-T2 streams [#739291] -* Improvements to plugin elements - + Add support for dma_buf imports (Wind Yuan) [#735362] - + Allow for SW decoding fallbacks with unsupported profiles [#730997] - + Make vaapipostproc work with SW elements (+Victor Jaquez) [#720174, #704078] - + Allow vaapipostproc to integrate with GL downstream elements [#735231] - + Add support for high-quality scaling to vaapipostproc ("scale-method=hq") - + Fix advanced deinterlacing when it is the unique filter applied - + Add GstColorBalance interface to vaapisink (Changzhi Wei) [#722390] - + Implement the GstNavigation interface into vaapisink [#711479] - + Allow rescaling of X11 window for vaapisink (Holger Kaelberer) [#711478] - + Optimizations to vaapidecode thread handling (Sebastian Dröge) [#734616] - + Fix deinterlacing from non VA memory buffers (Simon Farnsworth) [#726270] - + Fix clearing of subtitle overlay (Simon Farnsworth) - + Fix clearing of vaapipostproc state during restart (Michael Olbrich) - -Version 0.5.9 - 29.Jul.2014 -* Add VP8 decoder (+Halley Zhao) -* Add H.264 MVC decoder and encoder (+Sreerenj Balachandran, Xiaowei Li) -* Fix support for Firefox >= 30 when built with GStreamer 1.0 APIs -* Fix MPEG-4:2 decoder hang on skipped frames (Fabrice Bellet) [#733324] -* Fix MPEG-2 decoder to propagate PTS from demuxer (Jan Schmidt) [#732719] -* Improvements to H.264 decoder - + Add support for grayscale encoded clips - + Add minor optimizations to the parsing process - + Make support for interlaced streams more robust [#701340] - + Fix multiple slices decoding with varying slice types [#724518] - + Fix parsing of multiple SEI messages in single NAL units (Aurelien Zanelli) -* Improvements to plugin elements - + Add download capability to vaapidecode [#733243] - + Add support for crop regions in VPP mode [#720730] - + Allow selection of a particular "display-name" for vaapisink [#722247] - + Fix support for headless pipelines, e.g. vaapisink display="drm" mode - + Fix creation of output surface pool for vaapipostproc (Simon Farnsworth) - + Fix vaapipostproc "deinterlace-mode" semantics (Simon Farnsworth) [#726361] - + Fix memory leak in vaapidecode ! {glimagesink,cluttersink} (Matthew Waters) - + Fix vaapidecode hang when downstream errors out (Matthew Waters) [#733897] - -Version 0.5.8 - 23.Jan.2014 -* Add H.264 video encoding (+Feng Yuan) -* Add MPEG-2 video encoding (+Guangxin Xu) -* Add initial support for GStreamer 1.3 (Matthieu Bouron) -* Add support for H.264 Constrained Baseline profile (Feng Yuan) -* Add support for colorbalance adjustment in vaapipostproc (Halley Zhao) -* Add color space conversion in vaapisink (Holger Kaelberer) [#722255] -* Fix OpenGL interop with clutter-gst and glimagesink elements (Matthieu Bouron) -* Fix decoding of H.264 quantization matrices (+Cong Zhong) [#706406] -* Fix robustness of H.264 decoder when packets are missing -* Fix hang in vaapidecode on SIGINT [+C] (Fen Yuan) [#720584] -* Fix vaapisink initialization with foreign window (Holger Kaelberer) [#722244] -* Fix Sharpening filter in vaapipostproc (Halley Zhao) [#720375] - -Version 0.5.7 - 21.Nov.2013 -* Add support for GStreamer 1.2 (+Victor Jaquez, Sreerenj Balachandran) -* Add support for video processing (VA/VPP) (+Halley Zhao) - + Scaling and color conversion - + Image enhancement filters: Sharpening, Noise Reduction - + Advanced deinterlacing: Motion-Adaptive, Motion-Compensated -* Fix vaapidecode pause/resume/seek capabilities (+Guangxin Xu) -* JPEG decoder bug fixes and improvements - + Add support for multiscan images - + Improve overall performance by +12% - + Fix robustness and tolerance to missing packets - + Fix detection of image boundaries (Junfeng Xu) - + Fix decoding from Logitech Pro C920 cameras (Junfeng Xu) - -Version 0.5.6 - 29.Aug.2013 -* Add render-to-pixmap API to bypass VA/GLX in clutter-gst -* Add initial support for video-processing APIs (+Halley Zhao) -* Add support for video cropping and deinterlacing to the Wayland backend -* Add "force-aspect-ratio" property to vaapisink (Simon Farnsworth) -* Fix support for clutter-gst in GStreamer 0.10 builds -* Fix HW accelerated rendering with SW decoded pipelines -* Fix videotestsrc ! vaapisink pipelines (Guangxin Xu) -* Fix memory leak of raw video uploader objects (Feng Yuan) -* Fix decoding without a video parser element before `vaapidecde' -* Fix regression in MPEG-2 decoder due to incomplete video cropping support -* Fix dead-lock condition on Wayland when the end-of-stream is reached - -Version 0.5.5 - 15.Jul.2013 -* Allow creation of video surfaces with an explicit pixel format -* Allocate VA/GLX capable buffers by default on X11 servers (Victor Jaquez) -* Add support for video cropping in MPEG-2, VC-1 and H.264 codecs (+Sreerenj) -* Fix memory leak when processing interlaced pictures -* Fix creation of VA/GLX textures when video cropping is used -* Fix raw image copies in vaapidownload / vaapiupload (Feng Yuan) -* Fix MPEG-2 quantization matrices reset on new sequence headers (Cong Zhong) -* Fix direct linking of vaapidownload element to xvimagesink (Feng Yuan) -* Fix memory corruption in video pool implementation, e.g. for clutter-gst - -Version 0.5.4 - 14.Jun.2013 -* Streamline core libgstvaapi decoding library (API/ABI changes) -* Use built-in codecparsers by default (or --disable-builtin-codecparsers) -* Fix default Huffman tables generation (Feng Yuan) -* Fix destruction of Wayland display resources -* Fix explicit specification of display type to vaapisink -* Fix memory leak in vaapiupload in GStreamer 0.10 builds (Halley Zhao) -* Fix performance regression caused by improper use of GstTask callback -* Fix raw decoding mode to transfer ownership of surface proxy to caller - -Version 0.5.3 - 18.Apr.2013 -* Add support for GStreamer 1.0.x API (+Sreerenj Balachandran) -* Fix build on Fedora 17 (Víctor Manuel Jáquez) -* Fix vaapidecode heuristics to detect decode timeouts -* Fix fallback to sofware decoding if no hardware decoder is available -* Fix regression in raw decoding mode whereby PTS or picture flags were lost - -Version 0.5.2 - 28.Mar.2013 -* Add support for video seek/reset (+Sreerenj Balachandran) -* Improve MPEG-2 decoder robustness when packets are missing -* Fix support for raw YUV buffers in vaapisink -* Fix build on older Linux distributions with glib < 2.32 -* Fix decoding of MPEG-2 videos with height > 2800 pixels -* Fix MPEG-2 decoding with explicit quantization matrices set (Cong Zhong) -* Fix illegal write in vaapiupload for NV12 surfaces (Holger Kaelberer) - -Version 0.5.1 - 29.Jan.2013 -* Add simple decoder demo that only uses libgstvaapi -* Fix thread-safety issues in the Wayland renderer -* Fix VC-1 decoding bugs #692461, #692312, #692271, #692270, #692267 -* Fix decoding of VC-1 videos in AVI containers (Feng Yuan) -* Fix H.264 parser to zero-initialize key syntax elements -* Fix MPEG-2, H.264 and VC-1 decoders to submit all decoded frames on - -Version 0.5.0 - 15.Jan.2013 -* Optimize MPEG-2 and H.264 decoders -* Use GstVideoDecoder API for vaapidecode (+Sreerenj Balachandran) -* Add support for raw YUV buffers in vaapisink (+Halley Zhao) -* Add support for global-alpha subpictures/overlay (+Holger Kaelberer) -* Fix calculation of the vaapidecode time-out for a surface to get released - -Version 0.4.2 - 18.Dec.2012 -* Fix H.264 decoding on Cedar Trail platforms -* Fix MPEG-4 decoding at end-of-stream (Feng Yuan) -* Fix MPEG-4 decoding when a buffer contains multiple packets (Feng Yuan) -* Fix memory leak in GstVaapiVideoBuffer for images and surfaces (Feng Yuan) -* Fix symbols collision between built-in codecparsers/ and system library -* Use GST_PLUGIN_PATH, if set, to install plugin elements (Halley Zhao) - -Version 0.4.1 - 27.Nov.2012 -* Add support for H.264 interlaced streams -* Add support for Wayland 1.0 protocol (Robert Bradford) -* Add upstream bitstream parsers library (codecparsers) -* Fix build with the GNU gold linker -* Fix detection of H.264 picture boundaries -* Fix memory leak in MPEG-2 decoder for empty user-data packets -* Fix H.264 decoder with MMCO-based reference picture marking process -* Decode pending packets when an end-of-stream is received (+Feng Yuan) -* Use pixel-aspect-ratio from bitstream parsers (Simon Farnsworth) - -Version 0.4.0 - 05.Oct.2012 -* Add support for video rotation -* Add new video display APIs: Wayland and raw DRM for headless pipelines -* Drop FFmpeg-based decoders, only use codecparsers-based ones -* Only reset decoder if meaningful caps changed, e.g. size -* Allocate the minimal number of video surfaces useful for decoding -* Fix vaapisink to scale video down to fit the screen dimensions -* Fix vaapidecode crash when trying to release inexistent lock (Philip Lorenz) - -Version 0.3.8 - 20.Sep.2012 -* Disable FFmpeg-based decoders by default -* Add JPEG decoder (based on codecparsers) -* Fix crash when destroying GstVaapiDisplay objects early -* Fix GLX rendering with FBO + texture-from-pixmap (fallback for VA/GLX) -* Fix rendering with EMGD driver when overlay mode is used -* Fix MPEG-2 decoding on Intel Atom platforms with EMGD driver -* Fix release of dangling proxy surfaces when decoder is reset (Philip Lorenz) - -Version 0.3.7 - 26.Jun.2012 -* Fix vaapidecode to report unsupported codec profiles -* Fix MPEG-2 decoding of streams with extra slice() information -* Map MPEG-2 compatible High profile streams to Main profile -* Map MPEG-4 Simple Scalable profile streams to Advanced Simple (Feng Yuan) -* Fix various MPEG-4 decoding bugs (timestamps, reference frames) (Feng Yuan) -* Don't forcibly resize user provided X windows (Holger Kaelberer) -* Recalculate render rect only if caps are negotiated (Holger Kaelberer) - -Version 0.3.6 - 02.Apr.2012 -* Add support for decoding MPEG-2 interlaced streams -* Add support for interlaced streams with FFmpeg decoders (Holger Kaelberer) -* Add vaapipostproc element for video postprocessing (e.g. deinterlacing) -* Skip all H.264 Filler Data NALs -* Fix crashes in MPEG-4 decoder (Feng Yuan) -* Fix fallback from MPEG-2 Simple to Main profile -* Improve decoding of misformed MPEG-2 streams (+Feng Yuan) -* Avoid a hang in playbin2 for some MPEG-2 TS streams (Feng Yuan) - -Version 0.3.5 - 02.Mar.2012 -* Fix H.264 decoding when emulation prevention bytes are detected -* Skip all H.264 Access Unit (AU) NALs (Feng Yuan) -* Fix modification process of H.264 reference picture lists (Feng Yuan) -* Fix MPEG-2 stream size calculation (Sreerenj Balachandran) -* Fix MPEG-2 decoding on Intel Gen with multiple slices per MB line -* Fix crash when downloading/uploading VA images on PowerVR (Cedar Trail) -* Fix double buffer free issues with some VA drivers -* Fix crash when there is no free surface available for decoding -* Skip profiles which have no entrypoints (Halley Zhao) -* Fix minor memory leaks in plug-in elements - -Version 0.3.4 - 01.Feb.2012 -* Add H.264 decoder (based on codecparsers) -* Add workaround for qtdemux not exposing H.263 profiles (Halley Zhao) -* Alias H.263 Baseline profile to MPEG-4:2 Simple profile (Halley Zhao) -* Use optimized path to submit slice data buffers -* Fix possible memory leak in MPEG-2 decoder -* Fix vaapisink to cap window size to the maximum display size -* Fix MPEG-2, MPEG-4 and VC-1 decoders to refcount reference surfaces properly - -Version 0.3.3 - 16.Jan.2012 -* Add MPEG-2, MPEG-4 and VC-1 decoders (based on codecparsers) -* Add support for GstXOverlay::set_render_rectangle() in vaapisink -* Fix memory leak of GL texture (Nicolas Dufresne) -* Fix vaapisink to automatically fit video to window -* Fix vaapiupload to only set caps on newly created buffers (Nicolas Dufresne) -* Fix gst_vaapi_ensure_display() to honour DISPLAY environment variable - -Version 0.3.2 - 06.Jan.2012 -* Rename vaapiconvert element to vaapiupload -* Fix vaapiupload from NV12 buffers -* Fix possible leaks of VA surfaces in FFmpeg decoder -* Fix memory leak in vaapiupload initialization function -* Fix possible crash in vaapidecode deinitialization code -* Add vaapidownload element to convert from VA surfaces to YUV pixels - -Version 0.3.1 - 16.Dec.2011 -* Fix check for supported VA images -* Add support for partial VA image updates -* Add support for new subtitle/overlay infrastructure (Thibault Saunier) -* Add missing video context queries in vaapisink/vaapiconvert (Nicolas Dufresne) - -Version 0.3.0 - 09.Dec.2011 -* Group all plugins into the same bundle -* Use new XOverlay API (Sreerenj Balachandran) -* Use new GstVideoContext and GstSurfaceBuffer API (Nicolas Dufresne) -* Fix vaapidecode sink caps if decoder is in NULL state (Sreerenj Balachandran) -* Fix auto-plugging and downstream buffer allocation (Nicolas Dufresne) -* Fix crash in VA display init if no VA configs were found (Nicolas Dufresne) - -Version 0.2.7 - 07.Dec.2011 -* Relicense plugins and tests to LGPL v2.1 (SDS) -* Fix MPEG-2 decoding from TS & PS streams -* Fix build with newer versions of FFmpeg -* Fix vaapiconvert direct-rendering modes -* Fix use of invalid data at the end-of-stream - -Version 0.2.6 - 14.Jun.2011 -* Fix licensing terms (LGPL v2.1) - -Version 0.2.5 - 20.Jul.2010 -* Fix build with older VA-API 0.29-sds -* Fix decoding of some H.264 streams. e.g. Ice Age 2 trailer -* Fix VA/GLX support with texture-from-pixmap and GLX version < 1.3 - -Version 0.2.4 - 18.May.2010 -* Fix video rendering rect within an embedder window (Totem) -* Disable GLX rendering when vaapisink uses a foreign X window - -Version 0.2.3 - 16.May.2010 -* Fix memory leak of encoded buffers -* Fix decoder caps to report codec aliases -* Fix VC-1 decoding through the playbin2 pipeline - -Version 0.2.2 - 14.May.2010 -* Fix packaging dependencies -* Fix a crash in the FFmpeg decoder on close -* Fix OpenGL texture internal format (Clutter) -* Fix foreign window size for embedding (Totem) - -Version 0.2.1 - 12.May.2010 -* Fix integration within the playbin2 pipeline -* Fix vaapidecode to expose the HW supported caps only -* Add GstXOverlay interface to vaapisink (Totem media player) - -Version 0.2.0 - 05.May.2010 -* Relicense gst-libs/ code to LGPL v2.1+ -* Add FFmpeg/VAAPI decoder for the new `vaapidecode' element - -Version 0.1.2 - 30.Mar.2010 -* Add AYUV image format -* Add compatibility with the original VA-API 0.29 -* Add OpenGL support through VA/GLX extensions or TFP+FBO fallback - -Version 0.1.1 - 23.Mar.2010 -* Document public API for libgstvaapi-*.so.* -* Optimize `vaapiconvert' pipeline (direct-rendering) -* Allow `vaapisink` to render videos in fullscreen mode - -Version 0.1.0 - 16.Mar.2010 -* Initial release +This is gstreamer-vaapi 1.7.90. diff --git a/configure.ac b/configure.ac index b3a0527b41..c4484dccf6 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [7]) -m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [1]) +m4_define([gst_vaapi_micro_version], [90]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [700]) +m4_define([gst_vaapi_lt_current], [790]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [700]) +m4_define([gst_vaapi_lt_age], [790]) # glib version number m4_define([glib_version], [2.32]) # gstreamer version number -m4_define([gst_version], [1.7.1.1]) -m4_define([gst_plugins_base_version], [1.7.1.1]) -m4_define([gst_plugins_bad_version], [1.7.1.1]) +m4_define([gst_version], [1.7.90]) +m4_define([gst_plugins_base_version], [1.7.90]) +m4_define([gst_plugins_bad_version], [1.7.90]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index eb2f42d075..f037532999 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,24 @@ + + + 1.7.90 + master + 2016-03-01 + + + + + + + 1.6.0 + master + 2016-02-14 + + + + Sreerenj Balachandran From ad9be973102c41f98d18743714234b6b5eddb56a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 4 Mar 2016 09:12:13 +0200 Subject: [PATCH 2300/3781] build: Dist gstreamer-vaapi.doap and configure.ac/autogen.sh https://bugzilla.gnome.org/show_bug.cgi?id=763067 --- Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile.am b/Makefile.am index 87f8a3616e..fcff854416 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,4 +12,8 @@ MAINTAINERCLEANFILES = \ $(srcdir)/autoregen.sh $(srcdir)/INSTALL \ $(NULL) +EXTRA_DIST = \ + configure.ac autogen.sh \ + gstreamer-vaapi.doap + -include $(top_srcdir)/git.mk From 1eabfad5c3fc2b4f5b6f5b74849086780068b216 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 4 Mar 2016 10:51:42 +0200 Subject: [PATCH 2301/3781] decoder: vp9: Assign values for profile and bit_depth from frame header bit_depth field has added only in VA-API 0.39.0, added version check. --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index c8b6599555..33a9b2cc57 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -288,7 +288,10 @@ fill_picture (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture) 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 (frame_hdr, 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) == From 548528c8172e1d2192de10fdb93458de8ef61749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Mar 2016 10:47:56 +0100 Subject: [PATCH 2302/3781] plugins: proxy information from downstream caps Propagate to upstream the downstream information, such as fps, par, etc. This will fix several "getcaps" critical warnings in gst-validate. https://bugzilla.gnome.org/show_bug.cgi?id=763300 --- gst/vaapi/gstvaapidecode.c | 17 +++++------------ gst/vaapi/gstvaapiencode.c | 29 +++++++---------------------- 2 files changed, 12 insertions(+), 34 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 8b40baf333..ad167f3427 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1005,16 +1005,14 @@ static GstCaps * gst_vaapidecode_sink_getcaps (GstVideoDecoder * vdec, GstCaps * filter) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - GstCaps *tmp, *caps = NULL; + GstCaps *result; if (decode->allowed_caps) goto bail; /* if we haven't a display yet, return our pad's template caps */ - if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)) { - caps = gst_pad_get_pad_template_caps (GST_VIDEO_DECODER_SINK_PAD (vdec)); + if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)) goto bail; - } /* if the allowed caps calculation fails, return an empty caps, so * the auto-plug can try other decoder */ @@ -1022,16 +1020,11 @@ gst_vaapidecode_sink_getcaps (GstVideoDecoder * vdec, GstCaps * filter) return gst_caps_new_empty (); bail: - if (!caps) - caps = gst_caps_ref (decode->allowed_caps); + result = gst_video_decoder_proxy_getcaps (vdec, decode->allowed_caps, filter); - if (filter) { - tmp = caps; - caps = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (tmp); - } + GST_DEBUG_OBJECT (decode, "Returning sink caps %" GST_PTR_FORMAT, result); - return caps; + return result; } static gboolean diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index a9a477053f..78ab5521d3 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -339,32 +339,17 @@ gst_vaapiencode_buffer_loop (GstVaapiEncode * encode) gst_pad_pause_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); } -static GstCaps * -gst_vaapiencode_get_caps_impl (GstVideoEncoder * venc) -{ - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (venc); - GstCaps *caps; - - if (plugin->sinkpad_caps) - caps = gst_caps_ref (plugin->sinkpad_caps); - else { - caps = gst_pad_get_pad_template_caps (plugin->sinkpad); - } - return caps; -} - static GstCaps * gst_vaapiencode_get_caps (GstVideoEncoder * venc, GstCaps * filter) { - GstCaps *caps, *out_caps; + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (venc); + GstCaps *result; - out_caps = gst_vaapiencode_get_caps_impl (venc); - if (out_caps && filter) { - caps = gst_caps_intersect_full (out_caps, filter, GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (out_caps); - out_caps = caps; - } - return out_caps; + result = gst_video_encoder_proxy_getcaps (venc, plugin->sinkpad_caps, filter); + + GST_DEBUG_OBJECT (venc, "Returning sink caps %" GST_PTR_FORMAT, result); + + return result; } static gboolean From 805a4733bf213a1fbbdda5ccc951574cfc221fdd Mon Sep 17 00:00:00 2001 From: Vineeth TM Date: Wed, 9 Mar 2016 14:13:24 +0900 Subject: [PATCH 2303/3781] vaapidisplay: Fix uninitialized value error for VA attribute https://bugzilla.gnome.org/show_bug.cgi?id=763362 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 9de677b185..34f2faf425 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1798,7 +1798,7 @@ get_attribute (GstVaapiDisplay * display, VADisplayAttribType type, gint * value) { GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - VADisplayAttribute attr; + VADisplayAttribute attr = { 0, }; VAStatus status; attr.type = type; @@ -1814,7 +1814,7 @@ static gboolean set_attribute (GstVaapiDisplay * display, VADisplayAttribType type, gint value) { GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - VADisplayAttribute attr; + VADisplayAttribute attr = { 0, }; VAStatus status; attr.type = type; From 1608eff3e58e27a607bc9e2b7154386eeabb1bc5 Mon Sep 17 00:00:00 2001 From: Vineeth TM Date: Wed, 9 Mar 2016 11:03:28 +0900 Subject: [PATCH 2304/3781] plugins: fix gstgl and vaapi memory leaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1\ Unref gl_display and gl_window as soon they are not needed. 2\ Remove an unneeded display type check, since is handled by gst_vaapi_created_display_from_handle() 3\ Unref vaapi's display if the display cannot be bind to a GL API. Modified-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=763354 --- gst/vaapi/gstvaapipluginutil.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 13c48afb53..a8d6a30271 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -174,14 +174,14 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; #endif } + gst_object_unref (gl_window); break; } default: display_type = GST_VAAPI_DISPLAY_TYPE_ANY; break; } - if (!display_type) - return NULL; + gst_object_unref (gl_display); display = gst_vaapi_create_display_from_handle (display_type, native_display); if (!display) @@ -209,8 +209,10 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) out_display = NULL; break; } - if (!out_display) + if (!out_display) { + gst_vaapi_display_unref (display); return NULL; + } gst_vaapi_display_egl_set_gl_context (GST_VAAPI_DISPLAY_EGL (out_display), GSIZE_TO_POINTER (gst_gl_context_get_gl_context (gl_context))); break; From 2b47bf8c741e7cb0fd5a9705bdf826a1f87af72b Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Fri, 4 Mar 2016 20:17:20 -0300 Subject: [PATCH 2305/3781] vaapidecoder_h264: plug leak of h264 parsing info If something goes wrong while parsing, the info object is being leaked https://bugzilla.gnome.org/show_bug.cgi?id=763121 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 670e79bb9f..3df0df958c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4440,7 +4440,7 @@ gst_vaapi_decoder_h264_parse (GstVaapiDecoder * base_decoder, buf, 0, buf_size, &pi->nalu); status = get_status (result); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; + goto exit; switch (pi->nalu.type) { case GST_H264_NAL_SPS: @@ -4470,7 +4470,7 @@ gst_vaapi_decoder_h264_parse (GstVaapiDecoder * base_decoder, break; } if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; + goto exit; flags = 0; if (at_au_end) { @@ -4545,6 +4545,10 @@ gst_vaapi_decoder_h264_parse (GstVaapiDecoder * base_decoder, pi->flags = flags; gst_vaapi_parser_info_h264_replace (&priv->prev_pi, pi); return GST_VAAPI_DECODER_STATUS_SUCCESS; + +exit: + gst_vaapi_parser_info_h264_unref (pi); + return status; } static GstVaapiDecoderStatus From 0a9161ac3a089146cefcfca416f4a889d39e9f4a Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Fri, 4 Mar 2016 20:17:54 -0300 Subject: [PATCH 2306/3781] vaapidecoder_h265: plug leak of h265 parsing info If something goes wrong while parsing, the info object is being leaked https://bugzilla.gnome.org/show_bug.cgi?id=763121 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index cd6b66a39a..3c5a9d9144 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2828,7 +2828,7 @@ gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder, buf, 0, buf_size, &pi->nalu); status = get_status (result); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; + goto exit; switch (pi->nalu.type) { case GST_H265_NAL_VPS: status = parse_vps (decoder, unit); @@ -2866,7 +2866,7 @@ gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder, break; } if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; + goto exit; flags = 0; if (at_au_end) { flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END | @@ -2941,6 +2941,10 @@ gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder, pi->flags = flags; gst_vaapi_parser_info_h265_replace (&priv->prev_pi, pi); return GST_VAAPI_DECODER_STATUS_SUCCESS; + +exit: + gst_vaapi_parser_info_h265_unref (pi); + return status; } static GstVaapiDecoderStatus From 499329bdc16020805a62f9ca338dd20b27b9ce30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Mar 2016 18:55:39 +0100 Subject: [PATCH 2307/3781] build: handle git ignore in m4 directory --- m4/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/m4/Makefile.am b/m4/Makefile.am index af864e3bbb..398f95103f 100644 --- a/m4/Makefile.am +++ b/m4/Makefile.am @@ -1 +1,3 @@ EXTRA_DIST = $(wildcard *.m4) + +-include $(top_srcdir)/git.mk From 4c048b8c6c056e27539c8594d2c4b1caef68d19f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Mar 2016 18:58:13 +0100 Subject: [PATCH 2308/3781] build: git ignore gtkdoc generated files --- docs/plugins/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index c0409ab839..e0cb471375 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -85,6 +85,8 @@ SUBDIRS = MAINTAINERCLEANFILES = \ gstreamer-vaapi-plugins.* \ *.stamp inspect \ + gstreamer-vaapi-plugins-overrides.txt \ + gstreamer-vaapi-plugins-sections.new \ $(NULL) -include $(top_srcdir)/git.mk From 8aa880786d6d3bc55202f0507781caa7eac89c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Mar 2016 12:47:49 +0100 Subject: [PATCH 2309/3781] vaapidecode: remove unused function declaration There is no need to pre-declare gst_vaapidecode_update_sink_caps(). And fixed code-style of the other pre-declared functions. --- gst/vaapi/gstvaapidecode.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ad167f3427..aeb97c367b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -128,14 +128,10 @@ G_DEFINE_TYPE_WITH_CODE( GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) /* *INDENT-ON* */ -static gboolean -gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps); -static gboolean gst_vaapidecode_update_src_caps (GstVaapiDecode * decode); - -static gboolean -gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, +static gboolean gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, + GstCaps * caps); +static gboolean gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, const GstVideoCodecState * new_state); - static gboolean gst_vaapidecode_negotiate (GstVaapiDecode * decode); static void From 96ac9bee8ecae2532ff9a53d0a6f3015adc63ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Mar 2016 18:41:49 +0100 Subject: [PATCH 2310/3781] vaapidecode: register decoder with internal GType Don't expose the the vaapidecode GType, instead expose a function which will register element. This is the first step to split the decoder by codecs. https://bugzilla.gnome.org/show_bug.cgi?id=734093 --- gst/vaapi/gstvaapi.c | 4 ++-- gst/vaapi/gstvaapidecode.c | 45 ++++++++++++++++++++++++++++---------- gst/vaapi/gstvaapidecode.h | 3 +-- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index dc9726098d..aabddc3590 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -53,8 +53,8 @@ static gboolean plugin_init (GstPlugin * plugin) { - gst_element_register (plugin, "vaapidecode", - GST_RANK_PRIMARY + 1, GST_TYPE_VAAPIDECODE); + gst_vaapidecode_register (plugin); + gst_element_register (plugin, "vaapipostproc", GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); gst_element_register (plugin, "vaapisink", diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index aeb97c367b..3c219ec0c1 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -120,14 +120,10 @@ static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS(gst_vaapidecode_src_caps_str)); - -G_DEFINE_TYPE_WITH_CODE( - GstVaapiDecode, - gst_vaapidecode, - GST_TYPE_VIDEO_DECODER, - GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES) /* *INDENT-ON* */ +static GstElementClass *parent_class = NULL; + static gboolean gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps); static gboolean gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, @@ -815,7 +811,7 @@ gst_vaapidecode_finalize (GObject * object) g_mutex_clear (&decode->surface_ready_mutex); gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (object)); - G_OBJECT_CLASS (gst_vaapidecode_parent_class)->finalize (object); + G_OBJECT_CLASS (parent_class)->finalize (object); } static gboolean @@ -1036,8 +1032,7 @@ gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query) break; } default:{ - ret = GST_VIDEO_DECODER_CLASS (gst_vaapidecode_parent_class)->sink_query - (vdec, query); + ret = GST_VIDEO_DECODER_CLASS (parent_class)->sink_query (vdec, query); break; } } @@ -1075,8 +1070,7 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) break; } default:{ - ret = GST_VIDEO_DECODER_CLASS (gst_vaapidecode_parent_class)->src_query - (vdec, query); + ret = GST_VIDEO_DECODER_CLASS (parent_class)->src_query (vdec, query); break; } } @@ -1095,6 +1089,8 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) GST_DEBUG_CATEGORY_INIT (gst_debug_vaapidecode, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + parent_class = g_type_class_peek_parent (klass); + gst_vaapi_plugin_base_class_init (GST_VAAPI_PLUGIN_BASE_CLASS (klass)); object_class->finalize = gst_vaapidecode_finalize; @@ -1147,3 +1143,30 @@ gst_vaapidecode_init (GstVaapiDecode * decode) gst_video_decoder_set_packetized (vdec, FALSE); } + +gboolean +gst_vaapidecode_register (GstPlugin * plugin) +{ + GType type; + GTypeInfo typeinfo = { + sizeof (GstVaapiDecodeClass), + NULL, + NULL, + (GClassInitFunc) gst_vaapidecode_class_init, + NULL, + NULL, + sizeof (GstVaapiDecode), + 0, + (GInstanceInitFunc) gst_vaapidecode_init, + }; + + type = g_type_from_name ("GstVaapiDecode"); + if (!type) { + type = g_type_register_static (GST_TYPE_VIDEO_DECODER, "GstVaapiDecode", + &typeinfo, 0); + gst_vaapi_plugin_base_init_interfaces (type); + } + + return + gst_element_register (plugin, "vaapidecode", GST_RANK_PRIMARY + 1, type); +} diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 13c57bc0fa..55d4b36dcc 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -81,8 +81,7 @@ struct _GstVaapiDecodeClass { GstVaapiPluginBaseClass parent_class; }; -GType -gst_vaapidecode_get_type(void) G_GNUC_CONST; +gboolean gst_vaapidecode_register (GstPlugin * plugin); G_END_DECLS From 1e1d3b1d09517e4b95dd2b1733fd441f0c7b9529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Mar 2016 20:25:08 +0100 Subject: [PATCH 2311/3781] vaapidecode: split out jpeg decoder Split, as a different element, the JPEG decoder. https://bugzilla.gnome.org/show_bug.cgi?id=734093 --- gst/vaapi/gstvaapidecode.c | 96 +++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 22 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3c219ec0c1..7798363ba3 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -76,6 +76,9 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapidecode); #define GST_CAT_DEFAULT gst_debug_vaapidecode +#define GST_VAAPI_DECODE_PARAMS_QDATA \ + g_quark_from_static_string("vaapidec-params") + /* Default templates */ #define GST_CAPS_CODEC(CODEC) CODEC "; " @@ -94,9 +97,6 @@ static const char gst_vaapidecode_sink_caps_str[] = #if USE_VP8_DECODER GST_CAPS_CODEC("video/x-vp8") #endif -#if USE_JPEG_DECODER - GST_CAPS_CODEC("image/jpeg") -#endif #if USE_VP9_DECODER GST_CAPS_CODEC("video/x-vp9") #endif @@ -107,13 +107,6 @@ static const char gst_vaapidecode_src_caps_str[] = GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" GST_VIDEO_CAPS_MAKE("{ I420, YV12, NV12 }"); -static GstStaticPadTemplate gst_vaapidecode_sink_factory = - GST_STATIC_PAD_TEMPLATE( - "sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS(gst_vaapidecode_sink_caps_str)); - static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_STATIC_PAD_TEMPLATE( "src", @@ -122,6 +115,23 @@ static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_STATIC_CAPS(gst_vaapidecode_src_caps_str)); /* *INDENT-ON* */ +typedef struct _GstVaapiDecoderMap GstVaapiDecoderMap; +struct _GstVaapiDecoderMap +{ + guint codec; + guint rank; + const gchar *name; + const gchar *caps_str; +}; + +static const GstVaapiDecoderMap vaapi_decode_map[] = { +#if USE_JPEG_DECODER + {GST_VAAPI_CODEC_JPEG, GST_RANK_MARGINAL, "jpeg", "image/jpeg"}, +#endif + {0 /* the rest */ , GST_RANK_PRIMARY + 1, NULL, + gst_vaapidecode_sink_caps_str}, +}; + static GstElementClass *parent_class = NULL; static gboolean gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, @@ -1085,6 +1095,9 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVideoDecoderClass *const vdec_class = GST_VIDEO_DECODER_CLASS (klass); GstPadTemplate *pad_template; + GstVaapiDecoderMap *map; + gchar *name, *longname; + GstCaps *caps; GST_DEBUG_CATEGORY_INIT (gst_debug_vaapidecode, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); @@ -1109,17 +1122,31 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_query); vdec_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_getcaps); - gst_element_class_set_static_metadata (element_class, - "VA-API decoder", - "Codec/Decoder/Video", - GST_PLUGIN_DESC, + map = (GstVaapiDecoderMap *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass), + GST_VAAPI_DECODE_PARAMS_QDATA); + + if (map->codec) { + name = g_ascii_strup (map->name, -1); + longname = g_strdup_printf ("VA-API %s decoder", name); + g_free (name); + } else { + longname = g_strdup ("VA-API decoder"); + } + + gst_element_class_set_static_metadata (element_class, longname, + "Codec/Decoder/Video", GST_PLUGIN_DESC, "Gwenole Beauchesne , " "Halley Zhao , " "Sreerenj Balachandran , " "Wind Yuan "); + g_free (longname); + /* sink pad */ - pad_template = gst_static_pad_template_get (&gst_vaapidecode_sink_factory); + caps = gst_caps_from_string (map->caps_str); + pad_template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, + caps); + gst_caps_unref (caps); gst_element_class_add_pad_template (element_class, pad_template); /* src pad */ @@ -1147,6 +1174,10 @@ gst_vaapidecode_init (GstVaapiDecode * decode) gboolean gst_vaapidecode_register (GstPlugin * plugin) { + gboolean ret = FALSE; + guint i, codec, rank; + gchar *type_name, *element_name; + const gchar *name; GType type; GTypeInfo typeinfo = { sizeof (GstVaapiDecodeClass), @@ -1160,13 +1191,34 @@ gst_vaapidecode_register (GstPlugin * plugin) (GInstanceInitFunc) gst_vaapidecode_init, }; - type = g_type_from_name ("GstVaapiDecode"); - if (!type) { - type = g_type_register_static (GST_TYPE_VIDEO_DECODER, "GstVaapiDecode", - &typeinfo, 0); - gst_vaapi_plugin_base_init_interfaces (type); + for (i = 0; i < G_N_ELEMENTS (vaapi_decode_map); i++) { + codec = vaapi_decode_map[i].codec; + rank = vaapi_decode_map[i].rank; + name = vaapi_decode_map[i].name; + + if (codec) { + type_name = g_strdup_printf ("GstVaapiDecode_%s", name); + element_name = g_strdup_printf ("vaapi%sdec", name); + } else { + type_name = g_strdup ("GstVaapiDecode"); + element_name = g_strdup_printf ("vaapidecode"); + } + + type = g_type_from_name (type_name); + if (!type) { + /* create the gtype now */ + type = g_type_register_static (GST_TYPE_VIDEO_DECODER, type_name, + &typeinfo, 0); + gst_vaapi_plugin_base_init_interfaces (type); + g_type_set_qdata (type, GST_VAAPI_DECODE_PARAMS_QDATA, + (gpointer) & vaapi_decode_map[i]); + } + + ret |= gst_element_register (plugin, element_name, rank, type); + + g_free (element_name); + g_free (type_name); } - return - gst_element_register (plugin, "vaapidecode", GST_RANK_PRIMARY + 1, type); + return ret; } From 1b11e357d8b15e28bbb7061537f7782b9fb783b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Mar 2016 20:26:31 +0100 Subject: [PATCH 2312/3781] vaapidecodebin: don't handle jpeg decoding As JPEG decoder has been split and demoted, it cannot be handled by vaapidecodebin Added a fixme comment regarding the future removal of vaapidecode. https://bugzilla.gnome.org/show_bug.cgi?id=734093 --- gst/vaapi/gstvaapidecodebin.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 84a547b768..3468ae1229 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -98,9 +98,6 @@ static const char gst_vaapi_decode_bin_sink_caps_str[] = GST_CAPS_CODEC("video/x-wmv") #if USE_VP8_DECODER GST_CAPS_CODEC("video/x-vp8") -#endif -#if USE_JPEG_DECODER - GST_CAPS_CODEC("image/jpeg") #endif ; /* *INDENT-ON* */ @@ -466,6 +463,11 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) GstPadTemplate *tmpl; /* create the decoder */ + /* @FIXME: "vaapidecode" is going to be removed soon: (bug + * #734093). Instead there are going to be a set of elements + * "vaapi{codec}dec". We will need a mechanism to automatically + * select de correct decoder based on caps. + */ vaapidecbin->decoder = gst_element_factory_make ("vaapidecode", "vaapidecode"); if (!vaapidecbin->decoder) { From a486942ba2d44ba2f60fec25175c681786021b48 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 11 Mar 2016 17:44:07 +0200 Subject: [PATCH 2313/3781] decoder: h265: Fix offset calculation in codec_data parsing https://bugzilla.gnome.org/show_bug.cgi?id=762922 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 3c5a9d9144..fd8250ada1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2688,6 +2688,7 @@ gst_vaapi_decoder_h265_decode_codec_data (GstVaapiDecoder * goto cleanup; break; } + ofs = pi->nalu.offset + pi->nalu.size; gst_vaapi_parser_info_h265_replace (&pi, NULL); } } From b044d4acd8e8125bd359a120efb9280e632011d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 15 Mar 2016 12:39:20 +0200 Subject: [PATCH 2314/3781] Release 1.7.91 --- ChangeLog | 120 +++++++++++++++++++++++++++++++++++++++++-- NEWS | 2 +- configure.ac | 10 ++-- gstreamer-vaapi.doap | 9 ++++ 4 files changed, 132 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8e05f29eb7..b96e1fe5bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,123 @@ -=== release 1.7.90 === +=== release 1.7.91 === -2016-03-01 Sebastian Dröge +2016-03-15 Sebastian Dröge * configure.ac: - releasing 1.7.90 + releasing 1.7.91 + +2016-03-11 17:44:07 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: h265: Fix offset calculation in codec_data parsing + https://bugzilla.gnome.org/show_bug.cgi?id=762922 + +2016-03-09 20:26:31 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: don't handle jpeg decoding + As JPEG decoder has been split and demoted, it cannot be handled by + vaapidecodebin + Added a fixme comment regarding the future removal of vaapidecode. + https://bugzilla.gnome.org/show_bug.cgi?id=734093 + +2016-03-09 20:25:08 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: split out jpeg decoder + Split, as a different element, the JPEG decoder. + https://bugzilla.gnome.org/show_bug.cgi?id=734093 + +2016-03-09 18:41:49 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: register decoder with internal GType + Don't expose the the vaapidecode GType, instead expose a function + which will register element. + This is the first step to split the decoder by codecs. + https://bugzilla.gnome.org/show_bug.cgi?id=734093 + +2016-03-10 12:47:49 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: remove unused function declaration + There is no need to pre-declare gst_vaapidecode_update_sink_caps(). And fixed + code-style of the other pre-declared functions. + +2016-03-09 18:58:13 +0100 Víctor Manuel Jáquez Leal + + * docs/plugins/Makefile.am: + build: git ignore gtkdoc generated files + +2016-03-09 18:55:39 +0100 Víctor Manuel Jáquez Leal + + * m4/Makefile.am: + build: handle git ignore in m4 directory + +2016-03-04 20:17:54 -0300 Thiago Santos + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + vaapidecoder_h265: plug leak of h265 parsing info + If something goes wrong while parsing, the info object is + being leaked + https://bugzilla.gnome.org/show_bug.cgi?id=763121 + +2016-03-04 20:17:20 -0300 Thiago Santos + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + vaapidecoder_h264: plug leak of h264 parsing info + If something goes wrong while parsing, the info object is + being leaked + https://bugzilla.gnome.org/show_bug.cgi?id=763121 + +2016-03-09 11:03:28 +0900 Vineeth TM + + * gst/vaapi/gstvaapipluginutil.c: + plugins: fix gstgl and vaapi memory leaks + 1\ Unref gl_display and gl_window as soon they are not needed. + 2\ Remove an unneeded display type check, since is handled by + gst_vaapi_created_display_from_handle() + 3\ Unref vaapi's display if the display cannot be bind to a GL API. + Modified-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=763354 + +2016-03-09 14:13:24 +0900 Vineeth TM + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + vaapidisplay: Fix uninitialized value error for VA attribute + https://bugzilla.gnome.org/show_bug.cgi?id=763362 + +2016-03-08 10:47:56 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode.c: + plugins: proxy information from downstream caps + Propagate to upstream the downstream information, such as fps, par, etc. + This will fix several "getcaps" critical warnings in gst-validate. + https://bugzilla.gnome.org/show_bug.cgi?id=763300 + +2016-03-04 10:51:42 +0200 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Assign values for profile and bit_depth from frame header + bit_depth field has added only in VA-API 0.39.0, added version check. + +2016-03-04 09:12:13 +0200 Sebastian Dröge + + * Makefile.am: + build: Dist gstreamer-vaapi.doap and configure.ac/autogen.sh + https://bugzilla.gnome.org/show_bug.cgi?id=763067 + +=== release 1.7.90 === + +2016-03-01 19:23:51 +0200 Sebastian Dröge + + * ChangeLog: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + Release 1.7.90 2016-03-01 16:14:47 +0200 Sebastian Dröge diff --git a/NEWS b/NEWS index 1fee7899fa..8ce250f293 100644 --- a/NEWS +++ b/NEWS @@ -1 +1 @@ -This is gstreamer-vaapi 1.7.90. +This is gstreamer-vaapi 1.7.91. diff --git a/configure.ac b/configure.ac index c4484dccf6..8054f11385 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [7]) -m4_define([gst_vaapi_micro_version], [90]) +m4_define([gst_vaapi_micro_version], [91]) m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) @@ -16,7 +16,7 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [790]) +m4_define([gst_vaapi_lt_current], [791]) m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [790]) @@ -24,9 +24,9 @@ m4_define([gst_vaapi_lt_age], [790]) m4_define([glib_version], [2.32]) # gstreamer version number -m4_define([gst_version], [1.7.90]) -m4_define([gst_plugins_base_version], [1.7.90]) -m4_define([gst_plugins_bad_version], [1.7.90]) +m4_define([gst_version], [1.7.91]) +m4_define([gst_plugins_base_version], [1.7.91]) +m4_define([gst_plugins_bad_version], [1.7.91]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index f037532999..79ecca14d1 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,15 @@ + + + 1.7.91 + master + 2016-03-15 + + + + 1.7.90 From 4f62bf5a5e729ca851223b82d88a7f8c0b321de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Mar 2016 13:11:05 +0200 Subject: [PATCH 2315/3781] Release 1.8.0 --- ChangeLog | 16 +- NEWS | 787 ++++++++++++++++++++++++++++++++++++++++++- configure.ac | 14 +- gstreamer-vaapi.doap | 9 + 4 files changed, 815 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index b96e1fe5bb..0804da3801 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,19 @@ -=== release 1.7.91 === +=== release 1.8.0 === -2016-03-15 Sebastian Dröge +2016-03-24 Sebastian Dröge * configure.ac: - releasing 1.7.91 + releasing 1.8.0 + +=== release 1.7.91 === + +2016-03-15 12:39:20 +0200 Sebastian Dröge + + * ChangeLog: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + Release 1.7.91 2016-03-11 17:44:07 +0200 Sreerenj Balachandran diff --git a/NEWS b/NEWS index 8ce250f293..ee7f213e57 100644 --- a/NEWS +++ b/NEWS @@ -1 +1,786 @@ -This is gstreamer-vaapi 1.7.91. +# GStreamer 1.8 Release Notes + +**GStreamer 1.8.0 was released on 24 March 2016.** + +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 new features, bug fixes and other +improvements. + +See [https://gstreamer.freedesktop.org/releases/1.8/][latest] for the latest +version of this document. + +*Last updated: Thursday 24 March 2016, 10:00 UTC [(log)][gitlog]* + +[latest]: https://gstreamer.freedesktop.org/releases/1.8/ +[gitlog]: https://cgit.freedesktop.org/gstreamer/www/log/src/htdocs/releases/1.8/release-notes-1.8.md + +## Highlights + +- **Hardware-accelerated zero-copy video decoding on Android** + +- **New video capture source for Android using the android.hardware.Camera API** + +- **Windows Media reverse playback** support (ASF/WMV/WMA) + +- **New tracing system** provides support for more sophisticated debugging tools + +- **New high-level GstPlayer playback convenience API** + +- **Initial support for the new [Vulkan][vulkan] API**, see + [Matthew Waters' blog post][vulkan-in-gstreamer] for more details + +- **Improved Opus audio codec support**: Support for more than two channels; MPEG-TS demuxer/muxer can now handle Opus; + [sample-accurate][opus-sample-accurate] encoding/decoding/transmuxing with + Ogg, Matroska, ISOBMFF (Quicktime/MP4), and MPEG-TS as container; + [new codec utility functions for Opus header and caps handling][opus-codec-utils] + in pbutils library. The Opus encoder/decoder elements were also moved to + gst-plugins-base (from -bad), and the opus RTP depayloader/payloader to -good. + + [opus-sample-accurate]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstaudiometa.html#GstAudioClippingMeta + [opus-codec-utils]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstpbutilscodecutils.html + +- **GStreamer VAAPI module now released and maintained as part of the GStreamer project** + + [vulkan]: https://www.khronos.org/vulkan + [vulkan-in-gstreamer]: http://ystreet00.blogspot.co.uk/2016/02/vulkan-in-gstreamer.html + +## Major new features and changes + +### Noteworthy new API, features and other changes + +- New GstVideoAffineTransformationMeta meta for adding a simple 4x4 affine + transformation matrix to video buffers + +- [g\_autoptr()](https://developer.gnome.org/glib/stable/glib-Miscellaneous-Macros.html#g-autoptr) + support for all types is exposed in GStreamer headers now, in combination + with a sufficiently-new GLib version (i.e. 2.44 or later). This is primarily + for the benefit of application developers who would like to make use of + this, the GStreamer codebase itself will not be using g_autoptr() for + the time being due to portability issues. + +- GstContexts are now automatically propagated to elements added to a bin + or pipeline, and elements now maintain a list of contexts set on them. + The list of contexts set on an element can now be queried using the new functions + [gst\_element\_get\_context()](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#gst-element-get-context) + and [gst\_element\_get\_contexts()](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#gst-element-get-contexts). GstContexts are used to share context-specific configuration objects + between elements and can also be used by applications to set context-specific + configuration objects on elements, e.g. for OpenGL or Hardware-accelerated + video decoding. + +- New [GST\_BUFFER\_DTS\_OR\_PTS()](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstBuffer.html#GST-BUFFER-DTS-OR-PTS:CAPS) + convenience macro that returns the decode timestamp if one is set and + otherwise returns the presentation timestamp + +- New GstPadEventFullFunc that returns a GstFlowReturn instead of a gboolean. + This new API is mostly for internal use and was added to fix a race condition + where occasionally internal flow error messages were posted on the bus when + sticky events were propagated at just the wrong moment whilst the pipeline + was shutting down. This happened primarily when the pipeline was shut down + immediately after starting it up. GStreamer would not know that the reason + the events could not be propagated was because the pipeline was shutting down + and not some other problem, and now the flow error allows GStreamer to know + the reason for the failure (and that there's no reason to post an error + message). This is particularly useful for queue-like elements which may need + to asynchronously propagate a previous flow return from downstream. + +- Pipeline dumps in form of "dot files" now also show pad properties that + differ from their default value, the same as it does for elements. This is + useful for elements with pad subclasses that provide additional properties, + e.g. videomixer or compositor. + +- Pad probes are now guaranteed to be called in the order they were added + (before they were called in reverse order, but no particular order was + documented or guaranteed) + +- Plugins can now have dependencies on device nodes (not just regular files) + and also have a prefix filter. This is useful for plugins that expose + features (elements) based on available devices, such as the video4linux + plugin does with video decoders on certain embedded systems. + +- gst\_segment\_to\_position() has been deprecated and been replaced by the + better-named gst\_segment\_position\_from\_running\_time(). At the same time + gst\_segment\_position\_from\_stream\_time() was added, as well as \_full() + variants of both to deal with negative stream time. + +- GstController: the interpolation control source gained a new monotonic cubic + interpolation mode that, unlike the existing cubic mode, will never overshoot + the min/max y values set. + +- GstNetAddressMeta: can now be read from buffers in language bindings as well, + via the new gst\_buffer\_get\_net\_address\_meta() function + +- ID3 tag PRIV frames are now extraced into a new GST\_TAG\_PRIVATE\_DATA tag + +- gst-launch-1.0 and gst\_parse\_launch() now warn in the most common case if + a dynamic pad link could not be resolved, instead of just silently + waiting to see if a suitable pad appears later, which is often perceived + by users as hanging -- they are now notified when this happens and can check + their pipeline. + +- GstRTSPConnection now also parses custom RTSP message headers and retains + them for the application instead of just ignoring them + +- rtspsrc handling of authentication over tunneled connections (e.g. RTSP over HTTP) + was fixed + +- gst\_video\_convert\_sample() now crops if there is a crop meta on the input buffer + +- The debugging system printf functions are now exposed for general use, which + supports special printf format specifiers such as GST\_PTR\_FORMAT and + GST\_SEGMENT\_FORMAT to print GStreamer-related objects. This is handy for + systems that want to prepare some debug log information to be output at a + later point in time. The GStreamer-OpenGL subsystem is making use of these + new functions, which are [gst\_info\_vasprintf()][gst_info_vasprintf], + [gst\_info\_strdup\_vprintf()][gst_info_strdup_vprintf] and + [gst\_info\_strdup\_printf()][gst_info_strdup_printf]. + +- videoparse: "strides", "offsets" and "framesize" properties have been added to + allow parsing raw data with strides and padding that do not match GStreamer + defaults. + +- GstPreset reads presets from the directories given in GST\_PRESET\_PATH now. + Presets are read from there after presets in the system path, but before + application and user paths. + +[gst_info_vasprintf]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-info-vasprintf +[gst_info_strdup_vprintf]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-info-strdup-vprintf +[gst_info_strdup_printf]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-info-strdup-printf + +### New Elements + +- [netsim](): a new (resurrected) element to simulate network jitter and + packet dropping / duplication. + +- New VP9 RTP payloader/depayloader elements: rtpvp9pay/rtpvp9depay + +- New [videoframe_audiolevel]() element, a video frame synchronized audio level element + +- New spandsp-based tone generator source + +- New NVIDIA NVENC-based H.264 encoder for GPU-accelerated video encoding on + suitable NVIDIA hardware + +- [rtspclientsink](), a new RTSP RECORD sink element, was added to gst-rtsp-server + +- [alsamidisrc](), a new ALSA MIDI sequencer source element + +### Noteworthy element features and additions + +- *identity*: new ["drop-buffer-flags"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-identity.html#GstIdentity--drop-buffer-flags) + property to drop buffers based on buffer flags. This can be used to drop all + non-keyframe buffers, for example. + +- *multiqueue*: various fixes and improvements, in particular special handling + for sparse streams such as substitle streams, to make sure we don't overread + them any more. For sparse streams it can be normal that there's no buffer for + a long period of time, so having no buffer queued is perfectly normal. Before + we would often unnecessarily try to fill the subtitle stream queue, which + could lead to much more data being queued in multiqueue than necessary. + +- *multiqueue*/*queue*: When dealing with time limits, these elements now use the + new ["GST_BUFFER_DTS_OR_PTS"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstBuffer.html#GST-BUFFER-DTS-OR-PTS:CAPS) + and ["gst_segment_to_running_time_full()"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstSegment.html#gst-segment-to-running-time-full) + API, resulting in more accurate levels, especially when dealing with non-raw + streams (where reordering happens, and we want to use the increasing DTS as + opposed to the non-continuously increasing PTS) and out-of-segment input/output. + Previously all encoded buffers before the segment start, which can happen when + doing ACCURATE seeks, were not taken into account in the queue level calculation. + +- *multiqueue*: New ["use-interleave"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-multiqueue.html#GstMultiQueue--use-interleave) + property which allows the size of the queues to be optimized based on the input + streams interleave. This should only be used with input streams which are properly + timestamped. It will be used in the future decodebin3 element. + +- *queue2*: new ["avg-in-rate"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-queue2.html#GstQueue2--avg-in-rate) + property that returns the average input rate in bytes per second + +- audiotestsrc now supports all audio formats and is no longer artificially + limited with regard to the number of channels or sample rate + +- gst-libav (ffmpeg codec wrapper): map and enable JPEG2000 decoder + +- multisocketsink can, on request, send a custom GstNetworkMessage event + upstream whenever data is received from a client on a socket. Similarly, + socketsrc will, on request, pick up GstNetworkMessage events from downstream + and send any data contained within them via the socket. This allows for + simple bidirectional communication. + +- matroska muxer and demuxer now support the ProRes video format + +- Improved VP8/VP9 decoding performance on multi-core systems by enabling + multi-threaded decoding in the libvpx-based decoders on such systems + +- appsink has a new ["wait-on-eos"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-appsink.html#GstAppSink--wait-on-eos) + property, so in cases where it is uncertain if an appsink will have a consumer for + its buffers when it receives an EOS this can be set to FALSE to ensure that the + appsink will not hang. + +- rtph264pay and rtph265pay have a new "config-interval" mode -1 that will + re-send the setup data (SPS/PPS/VPS) before every keyframe to ensure + optimal coverage and the shortest possibly start-up time for a new client + +- mpegtsmux can now mux H.265/HEVC video as well + +- The MXF muxer was ported to 1.x and produces more standard conformant files now + that can be handled by more other software; The MXF demuxer got improved + support for seek tables (IndexTableSegments). + +### Plugin moves + +- The rtph265pay/depay RTP payloader/depayloader elements for H.265/HEVC video + from the rtph265 plugin in -bad have been moved into the existing rtp plugin + in gst-plugins-good. + +- The mpg123 plugin containing a libmpg123 based audio decoder element has + been moved from -bad to -ugly. + +- The Opus encoder/decoder elements have been moved to gst-plugins-base and + the RTP payloader to gst-plugins-good, both coming from gst-plugins-bad. + +### New tracing tools for developers + +A new tracing subsystem API has been added to GStreamer, which provides +external tracers with the possibility to strategically hook into GStreamer +internals and collect data that can be evaluated later. These tracers are a +new type of plugin features, and GStreamer core ships with a few example +tracers (latency, stats, rusage, log) to start with. Tracers can be loaded +and configured at start-up via an environment variable (GST\_TRACER\_PLUGINS). + +Background: While GStreamer provides plenty of data on what's going on in a +pipeline via its debug log, that data is not necessarily structured enough to +be generally useful, and the overhead to enable logging output for all data +required might be too high in many cases. The new tracing system allows tracers +to just obtain the data needed at the right spot with as little overhead as +possible, which will be particularly useful on embedded systems. + +Of course it has always been possible to do performance benchmarks and debug +memory leaks, memory consumption and invalid memory access using standard +operating system tools, but there are some things that are difficult to track +with the standard tools, and the new tracing system helps with that. Examples +are things such as latency handling, buffer flow, ownership transfer of +events and buffers from element to element, caps negotiation, etc. + +For some background on the new tracing system, watch Stefan Sauer's +GStreamer Conference talk ["A new tracing subsystem for GStreamer"][tracer-0] +and for a more specific example how it can be useful have a look at +Thiago Santos's lightning talk ["Analyzing caps negotiation using GstTracer"][tracer-1] +and his ["GstTracer experiments"][tracer-2] blog post. There was also a Google +Summer of Code project in 2015 that used tracing system for a graphical +GStreamer debugging tool ["gst-debugger"][tracer-3]. + +This is all still very much work in progress, but we hope this will provide the +foundation for a whole suite of new debugging tools for GStreamer pipelines. + +[tracer-0]: https://gstconf.ubicast.tv/videos/a-new-tracing-subsystem-for-gstreamer/ +[tracer-1]: https://gstconf.ubicast.tv/videos/analyzing-caps-negotiation-using-gsttracer/ +[tracer-2]: http://blog.thiagoss.com/2015/07/23/gsttracer-experiments/ +[tracer-3]: https://git.gnome.org/browse/gst-debugger + +### GstPlayer: a new high-level API for cross-platform multimedia playback + +GStreamer has had reasonably high-level API for multimedia playback +in the form of the playbin element for a long time. This allowed application +developers to just configure a URI to play, and playbin would take care of +everything else. This works well, but there is still way too much to do on +the application-side to implement a fully-featured playback application, and +too much general GStreamer pipeline API exposed, making it less accessible +to application developers. + +Enter GstPlayer. GstPlayer's aim is to provide an even higher-level abstraction +of a fully-featured playback API but specialised for its specific use case. It +also provides easy integration with and examples for Gtk+, Qt, Android, OS/X, +iOS and Windows. Watch Sebastian's [GstPlayer talk at the GStreamer Conference][gstplayer-talk] +for more information, or check out the [GstPlayer API reference][gstplayer-api] +and [GstPlayer examples][gstplayer-examples]. + +[gstplayer-api]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/player.html +[gstplayer-talk]: https://gstconf.ubicast.tv/videos/gstplayer-a-simple-cross-platform-api-for-all-your-media-playback-needs-part-1/ +[gstplayer-examples]: https://github.com/sdroege/gst-player/ + +### Adaptive streaming: DASH, HLS and MSS improvements + +- dashdemux now supports loading external xml nodes pointed from its MPD. + +- Content protection nodes parsing support for PlayReady WRM in mssdemux. + +- Reverse playback was improved to respect seek start and stop positions. + +- Adaptive demuxers (hlsdemux, dashdemux, mssdemux) now support the SNAP_AFTER + and SNAP_BEFORE seek flags which will jump to the nearest fragment boundary + when executing a seek, which means playback resumes more quickly after a seek. + +### Audio library improvements + +- audio conversion, quantization and channel up/downmixing functionality + has been moved from the audioconvert element into the audio library and + is now available as public API in form of [GstAudioConverter][audio-0], + [GstAudioQuantize][audio-1] and [GstAudioChannelMixer][audio-2]. + Audio resampling will follow in future releases. + +- [gst\_audio\_channel\_get\_fallback\_mask()][audio-3] can be used + to retrieve a default channel mask for a given number of channels as last + resort if the layout is unknown + +- A new [GstAudioClippingMeta][audio-4] meta was added for specifying clipping + on encoded audio buffers + +- A new GstAudioVisualizer base class for audio visualisation elements; + most of the existing visualisers have been ported over to the new base class. + This new base class lives in the pbutils library rather than the audio library, + since we'd have had to make libgstaudio depend on libgstvideo otherwise, + which was deemed undesirable. + +[audio-0]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-GstAudioConverter.html +[audio-1]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-GstAudioQuantize.html +[audio-2]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstaudiochannels.html#gst-audio-channel-mix-new +[audio-3]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstaudiochannels.html#gst-audio-channel-get-fallback-mask +[audio-4]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstaudiometa.html#GstAudioClippingMeta + +### GStreamer OpenGL support improvements + +#### Better OpenGL Shader support + +[GstGLShader][shader] has been revamped to allow more OpenGL shader types +by utilizing a new GstGLSLStage object. Each stage holds an OpenGL pipeline +stage such as a vertex, fragment or a geometry shader that are all compiled +separately into a program that is executed. + +The glshader element has also received a revamp as a result of the changes in +the library. It does not take file locations for the vertex and fragment +shaders anymore. Instead it takes the strings directly leaving the file +management to the application. + +A new [example][liveshader-example] was added utilizing the new shader +infrastructure showcasing live shader edits. + +[shader]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-gstglshader.html +[liveshader-example]: https://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/tests/examples/gtk/glliveshader.c + +#### OpenGL GLMemory rework + +[GstGLMemory] was extensively reworked to support the addition of multiple +texture targets required for zero-copy integration with the Android +MediaCodec elements. This work was also used to provide IOSurface based +GLMemory on OS X for zero-copy with OS X's VideoToolbox decoder (vtdec) and +AV Foundation video source (avfvideosrc). There are also patches in bugzilla +for GstGLMemoryEGL specifically aimed at improving the decoding performance on +the Raspberry Pi. + +[GstGLMemory]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-gstglmemory.html + +A texture-target field was added to video/x-raw(memory:GLMemory) caps to signal +the texture target contained in the GLMemory. Its values can be 2D, rectangle +or external-oes. glcolorconvert can convert between the different formats as +required and different elements will accept or produce different targets. e.g. +glimagesink can take and render external-oes textures directly as required for +effecient zero-copy on android. + +A generic GL allocation framework was also implemented to support the generic +allocation of OpenGL buffers and textures which is used extensively by +GstGLBufferPool. + +#### OpenGL DMABuf import uploader + +There is now a DMABuf uploader available for automatic selection that will +attempt to import the upstream provided DMABuf. The uploader will import into +2D textures with the necesarry format. YUV to RGB conversion is still provided +by glcolorconvert to avoid the laxer restrictions with external-oes textures. + +#### OpenGL queries + +Queries of various aspects of the OpenGL runtime such as timers, number of +samples or the current timestamp are not possible. The GstGLQuery object uses a +delayed debug system to delay the debug output to later to avoid expensive calls +to the glGet\* family of functions directly after finishing a query. It is +currently used to output the time taken to perform various operations of texture +uploads and downloads in GstGLMemory. + +#### New OpenGL elements + +glcolorbalance has been created mirroring the videobalance elements. +glcolorbalance provides the exact same interface as videobalance so can be used +as a GPU accelerated replacement. glcolorbalance has been added to glsinkbin so +usage with playsink/playbin will use it automatically instead of videobalance +where possible. + +glvideoflip, which is the OpenGL equiavalant of videoflip, implements the exact +same interface and functionality as videoflip. + +#### EGL implementation now selects OpenGL 3.x + +The EGL implementation can now select OpenGL 3.x contexts. + +#### OpenGL API removal + +The GstGLDownload library object was removed as it was not used by anything. +Everything is performed by GstGLMemory or in the gldownloadelement. + +The GstGLUploadMeta library object was removed as it was not being used and we +don't want to promote the use of GstVideoGLTextureUploadMeta. + +#### OpenGL: Other miscellaneous changes + +- The EGL implementation can now select OpenGL 3.x contexts. This brings + OpenGL 3.x to e.g. wayland and other EGL systems. + +- glstereomix/glstereosplit are now built and are usable on OpenGL ES systems + +- The UYVY/YUY2 to RGBA and RGBA to UYVY/YUY2 shaders were fixed removing the + sawtooth pattern and luma bleeding. + +- We now utilize the GL\_APPLE\_sync extension on iOS devices which improves + performance of OpenGL applications, especially with multiple OpenGL + contexts. + +- glcolorconvert now uses a bufferpool to avoid costly + glGenTextures/glDeleteTextures for every frame. + +- glvideomixer now has full glBlendFunc and glBlendEquation support per input. + +- gltransformation now support navigation events so your weird transformations + also work with DVD menus. + +- qmlglsink can now run on iOS, OS X and Android in addition to the already + supported Linux platform. + +- glimagesink now posts unhandled keyboard and mouse events (on backends that + support user input, current only X11) on the bus for the application. + +### Initial GStreamer Vulkan support + +Some new elements, vulkansink and vulkanupload have been implemented utilizing +the new Vulkan API. The implementation is currently limited to X11 platforms +(via xcb) and does not perform any scaling of the stream's contents to the size +of the available output. + +A lot of infrasctructure work has been undertaken to support using Vulkan in +GStreamer in the future. A number of GstMemory subclasses have been created for +integrating Vulkan's GPU memory handling along with VkBuffer's and VkImage's +that can be passed between elements. Some GStreamer refcounted wrappers for +global objects such as VkInstance, VkDevice, VkQueue, etc have also been +implemented along with GstContext integration for sharing these objects with the +application. + +### GStreamer VAAPI support for hardware-accelerated video decoding and encoding on Intel (and other) platforms + +#### GStreamer VAAPI is now part of upstream GStreamer + +The GStreamer-VAAPI module which provides support for hardware-accelerated +video decoding, encoding and post-processing on Intel graphics hardware +on Linux has moved from its previous home at the [Intel Open Source Technology Center][iostc] +to the upstream GStreamer repositories, where it will in future be maintained +as part of the upstream GStreamer project and released in lockstep with the +other GStreamer modules. The current maintainers will continue to spearhead +the development at the new location: + +[http://cgit.freedesktop.org/gstreamer/gstreamer-vaapi/][gst-vaapi-git] + +[gst-vaapi-git]: http://cgit.freedesktop.org/gstreamer/gstreamer-vaapi/ + +GStreamer-VAAPI relies heavily on certain GStreamer infrastructure API that +is still in flux such as the OpenGL integration API or the codec parser +libraries, and one of the goals of the move was to be able to leverage +new developments early and provide tighter integration with the latest +developments of those APIs and other graphics-related APIs provided by +GStreamer, which should hopefully improve performance even further and in +some cases might also provide better stability. + +Thanks to everyone involved in making this move happen! + +#### GStreamer VAAPI: Bug tracking + +Bugs had already been tracked on [GNOME bugzilla](bgo) but will be moved +from the gstreamer-vaapi product into a new gstreamer-vaapi component of +the GStreamer product in bugzilla. Please file new bugs against the new +component in the GStreamer product from now on. + +#### GStreamer VAAPI: Pending patches + +The code base has been re-indented to the GStreamer code style, which +affected some files more than others. This means that some of the patches +in bugzilla might not apply any longer, so if you have any unmerged patches +sitting in bugzilla please consider checking if they still apply cleany and +refresh them if not. Sorry for any inconvenience this may cause. + +#### GStreamer VAAPI: New versioning scheme and supported GStreamer versions + +The version numbering has been changed to match the GStreamer version +numbering to avoid confusion: there is a new gstreamer-vaapi 1.6.0 release +and a 1.6 branch that is roughly equivalent to the previous 0.7.0 version. +Future releases 1.7.x and 1.8.x will be made alongside GStreamer releases. + +While it was possible and supported by previous releases to build against +a whole range of different GStreamer versions (such as 1.2, 1.4, 1.6 or 1.7/1.8), +in the future there will only be one target branch, so that git master will +track GStreamer git master, 1.8.x will target GStreamer 1.8, and +1.6.x will target the 1.6 series. + +[iostc]: http://01.org +[bgo]: http://bugzilla.gnome.og + +#### GStreamer VAAPI: Miscellaneous changes + +All GStreamer-VAAPI functionality is now provided solely by its GStreamer +elements. There is no more public library exposing GstVaapi API, this API +was only ever meant for private use by the elements. Parts of it may be +resurrected again in future if needed, but for now it has all been made +private. + +GStreamer-VAAPI now unconditionally uses the codecparser library in +gst-plugins-bad instead of shipping its own internal copy. Similarly, +it no longer ships its own codec parsers but relies on the upstream +codec parser elements. + +The GStreamer-VAAPI encoder elements have been renamed from vaapiencode_foo +to vaapifooenc, so encoders are now called vaapih264enc, vaapih265enc, +vaapimpeg2enc, vaapijpegenc, and vaapivp8enc. With this change we now follow +the standard names in GStreamer, and the plugin documentation is generated +correctly. + +In the case of the decoders, only the jpeg decoder has been split from the +general decoding element vaapidecode: vaapijpegdec. This is the first step to +split per codec each decoding element. The vaapijpegdec has also been given +marginal rank for the time being. + +#### GStreamer VAAPI: New features in 1.8: 10-bit H.265/HEVC decoding support + +Support for decoding 10-bit H.265/HEVC has been added. For the time being +this only works in combination with vaapisink though, until support for the +P010 video format used internally is added to GStreamer and to the +vaGetImage()/vaPutimage() API in the vaapi-intel-driver. + +Several fixes for memory leaks, build errors, and in the internal +video parsing. + +Finally, vaapisink now posts the unhandled keyboard and mouse events to the +application. + +### GStreamer Video 4 Linux Support + +Colorimetry support has been enhanced even more. It will now properly select +default values when not specified by the driver. The range of color formats +supported by GStreamer has been greatly improved. Notably, support for +multi-planar I420 has been added along with all the new and non-ambiguous RGB +formats that got added in recent kernels. + +The device provider now exposes a variety of properties as found in the udev +database. + +The video decoder is now able to negotiate the downstream format. + +Elements that are dynamically created from /dev/video\* now track changes on +these devices to ensure the registry stay up to date. + +All this and various bug fixes that improve both stability and correctness. + +### GStreamer Editing Services + +Added APIs to handle asset proxying support. Proxy creation is not the +responsibility of GES itself, but GES provides all the needed features +for it to be cleanly handled at a higher level. + +Added support for changing playback rate. This means that now, whenever a +user adds a 'pitch' element (as it is the only known element to change playback +rate through properties), GES will handle everything internally. This change +introduced a new media-duration-factor property in NleObject which will +lead to tweaking of seek events so they have the proper playback range to be +requested upstream. + +Construction of NLE objects has been reworked making copy/pasting fully +functional and allowing users to set properties on effects right after +creating them. + +Rework of the title source to add more flexibility in text positioning, +and letting the user get feedback about rendered text positioning. + +Report nlecomposition structural issues (coming from user programing mistakes) +into ERROR messages on the bus. + +Add GI/pythyon testsuite in GES itself, making sure the API is working as expected +in python, and allowing writing tests faster. + +### GstValidate + +Added support to run tests inside gdb. + +Added a 'smart' reporting mode where we give as much information as possible about +critical errors. + +Uses GstTracer now instead of a LD\_PRELOAD library. + +## Miscellaneous + +- encodebin now works with "encoder-muxers" such as wavenc + +- gst-play-1.0 acquired a new keyboard shortcut: '0' seeks back to the start + +- gst-play-1.0 supports two new command line switches: -v for verbose output + and --flags to configure the playbin flags to use. + +## Build and Dependencies + +- The GLib dependency requirement was bumped to 2.40 + +- The -Bsymbolic configure check now works with clang as well + +- ffmpeg is now required as libav provider, incompatible changes were + introduced that make it no longer viable to support both FFmpeg and Libav + as libav providers. Most major distros have switched to FFmpeg or are in + the process of switching to it anyway, so we don't expect this to be a + problem, and there is still an internal copy of ffmpeg that can be used + as fallback if needed. + +- The internal ffmpeg snapshot is now FFMpeg 3.0, but it should be possible + to build against 2.8 as well for the time being. + +## Platform-specific improvements + +### Android + +- Zero-copy video decoding on Android using the hardware-accelerated decoders + has been implemented, and is fully integrated with the GStreamer OpenGL stack + +- ahcsrc, a new camera source element, has been merged and can be used to + capture video on android devices. It uses the android.hardware.Camera Java + API to capture from the system's cameras. + +- The OpenGL-based QML video sink can now also be used on Android + +- New tinyalsasink element, which is mainly useful for Android but can also + be used on other platforms. + +### OS/X and iOS + +- The system clock now uses mach\_absolute\_time() on OSX/iOS, which is + the preferred high-resolution monotonic clock to be used on Apple platforms + +- The OpenGL-based QML video sink can now also be used on OS X and iOS (with + some Qt build system massaging) + +- New IOSurface based memory implementation in avfvideosrc and vtdec on OS X + for zerocopy with OpenGL. The previously used OpenGL extension + GL_APPLE_ycbcr_422 is not compatible with GL 3.x core contexts. + +- New GstAppleCoreVideoMemory wrapping CVPixelBuffer's + +- avfvideosrc now supports renegotiation. + +### Windows + +- Various bugs with UDP and multicast were fixed on Windows, mostly related to + gst-rtsp-server. + +- A few bugs in directsoundsrc and directsoundsink were fixed that could cause + the element to lock up. Also the "mute" property on the sink was fixed, and + a new "device" property for device selection was added to the source. + +## Known Issues + +- Building GStreamer applications with the Android NDK r11 is currently not + supported due to incompatible changes in the NDK. This is expected to be + fixed for 1.8.1. + [Bugzilla #763999](https://bugzilla.gnome.org/show_bug.cgi?id=763999) + +- vp8enc crashes on 32 bit Windows, but was working fine in 1.6. 64 bit + Windows is unaffected. + [Bugzilla #763663](https://bugzilla.gnome.org/show_bug.cgi?id=763663) + +## Contributors + +Adam Miartus, Alban Bedel, Aleix Conchillo Flaqué, Aleksander Wabik, +Alessandro Decina, Alex Ashley, Alex Dizengof, Alex Henrie, Alistair Buxton, +Andreas Cadhalpun, Andreas Frisch, André Draszik, Anthony G. Basile, +Antoine Jacoutot, Anton Bondarenko, Antonio Ospite, Arjen Veenhuizen, +Arnaud Vrac, Arun Raghavan, Athanasios Oikonomou, Aurélien Zanelli, Ben Iofel, +Bob Holcomb, Branko Subasic, Carlos Rafael Giani, Chris Bass, Csaba Toth, +Daniel Kamil Kozar, Danilo Cesar Lemes de Paula, Dave Craig, David Fernandez, +David Schleef, David Svensson Fors, David Waring, David Wu, Duncan Palmer, +Edward Hervey, Egor Zaharov, Etienne Peron, Eunhae Choi, Evan Callaway, +Evan Nemerson, Fabian Orccon, Florent Thiéry, Florin Apostol, Frédéric Wang, +George Kiagiadakis, George Yunaev, Göran Jönsson, Graham Leggett, +Guillaume Desmottes, Guillaume Marquebielle, Haihua Hu, Havard Graff, +Heinrich Fink, Holger Kaelberer, HoonHee Lee, Hugues Fruchet, Hyunil Park, +Hyunjun Ko, Ilya Konstantinov, James Stevenson, Jan Alexander Steffens (heftig), +Jan Schmidt, Jason Litzinger, Jens Georg, Jimmy Ohn, Joan Pau Beltran, +Joe Gorse, John Chang, John Slade, Jose Antonio Santos Cadenas, Josep Torra, +Julian Bouzas, Julien Isorce, Julien Moutte, Justin Kim, Kazunori Kobayashi, +Koop Mast, Lim Siew Hoon, Linus Svensson, Lubosz Sarnecki, Luis de Bethencourt, +Lukasz Forynski, Manasa Athreya, Marcel Holtmann, Marcin Kolny, Marcus Prebble, +Mark Nauwelaerts, Maroš Ondrášek, Martin Kelly, Matej Knopp, Mathias Hasselmann, +Mathieu Duponchelle, Matt Crane, Matthew Marsh, Matthew Waters, Matthieu Bouron, +Mersad Jelacic, Michael Olbrich, Miguel París Díaz, Mikhail Fludkov, +Mischa Spiegelmock, Nicola Murino, Nicolas Dufresne, Nicolas Huet, +Nirbheek Chauhan, Ognyan Tonchev, Olivier Crête, Pablo Anton, Pankaj Darak, +Paolo Pettinato, Patricia Muscalu, Paul Arzelier, Pavel Bludov, Perry Hung, +Peter Korsgaard, Peter Seiderer, Petr Viktorin, Philippe Normand, +Philippe Renon, Philipp Zabel, Philip Van Hoof, Philip Withnall, Piotr Drąg, +plamot, Polochon\_street, Prashant Gotarne, Rajat Verma, Ramiro Polla, +Ravi Kiran K N, Reynaldo H. Verdejo Pinochet, Robert Swain, Romain Picard, +Roman Nowicki, Ross Burton, Ryan Hendrickson, Santiago Carot-Nemesio, +Scott D Phillips, Sebastian Dröge, Sebastian Rasmussen, Sergey Borovkov, +Seungha Yang, Sjors Gielen, Song Bing, Sreerenj Balachandran, Srimanta Panda, +Stavros Vagionitis, Stefan Sauer, Steven Hoving, Stian Selnes, Suhwang Kim, +Thiago Santos, Thibault Saunier, Thijs Vermeir, Thomas Bluemel, Thomas Roos, +Thomas Vander Stichele, Tim-Philipp Müller, Tim Sheridan, Ting-Wei Lan, +Tom Deseyn, Vanessa Chipirrás Navalón, Víctor Manuel Jáquez Leal, +Vincent Dehors, Vincent Penquerc'h, Vineeth T M, Vivia Nikolaidou, +Wang Xin-yu (王昕宇), William Manley, Wim Taymans, Wonchul Lee, Xavi Artigas, +Xavier Claessens, Youness Alaoui, + +... and many others who have contributed bug reports, translations, sent +suggestions or helped testing. + +## Bugs fixed in 1.8 + +More than [~700 bugs][bugs-fixed-in-1.8] have been fixed during +the development of 1.8. + +This list does not include issues that have been cherry-picked into the +stable 1.6 branch and fixed there as well, all fixes that ended up in the +1.6 branch are also included in 1.8. + +This list also does not include issues that have been fixed without a bug +report in bugzilla, so the actual number of fixes is much higher. + +[bugs-fixed-in-1.8]: https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&classification=Platform&limit=0&list_id=107311&order=bug_id&product=GStreamer&query_format=advanced&resolution=FIXED&target_milestone=1.6.1&target_milestone=1.6.2&target_milestone=1.6.3&target_milestone=1.7.0&target_milestone=1.7.1&target_milestone=1.7.2&target_milestone=1.7.3&target_milestone=1.7.4&target_milestone=1.7.90&target_milestone=1.7.91&target_milestone=1.7.92&target_milestone=1.7.x&target_milestone=1.8.0 + +## Stable 1.8 branch + +After the 1.8.0 release there will be several 1.8.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.8.x bug-fix releases will be made from the git 1.8 branch, which +is a stable branch. + +### 1.8.0 + +1.8.0 was released on 24 March 2016. + +### 1.8.1 + +The first 1.8 bug-fix release (1.8.1) is planned for April 2016. + +## Schedule for 1.10 + +Our next major feature release will be 1.10, and 1.9 will be the unstable +development version leading up to the stable 1.10 release. The development +of 1.9/1.10 will happen in the git master branch. + +The plan for the 1.10 development cycle is yet to be confirmed, but it is +expected that feature freeze will be around late July or early August, +followed by several 1.9 pre-releases and the new 1.10 stable release +in September. + +1.10 will be backwards-compatible to the stable 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 Sebastian Dröge, Nicolas Dufresne, Edward Hervey, Víctor +Manuel Jáquez Leal, Arun Raghavan, Thiago Santos, Thibault Saunier, Jan +Schmidt and Matthew Waters.* + +*License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)* diff --git a/configure.ac b/configure.ac index 8054f11385..7ca566c2f7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [7]) -m4_define([gst_vaapi_micro_version], [91]) +m4_define([gst_vaapi_minor_version], [8]) +m4_define([gst_vaapi_micro_version], [0]) m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [791]) +m4_define([gst_vaapi_lt_current], [800]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [790]) +m4_define([gst_vaapi_lt_age], [800]) # glib version number m4_define([glib_version], [2.32]) # gstreamer version number -m4_define([gst_version], [1.7.91]) -m4_define([gst_plugins_base_version], [1.7.91]) -m4_define([gst_plugins_bad_version], [1.7.91]) +m4_define([gst_version], [1.8.0]) +m4_define([gst_plugins_base_version], [1.8.0]) +m4_define([gst_plugins_bad_version], [1.8.0]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 79ecca14d1..2b928a33c5 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,15 @@ + + + 1.8.0 + master + 2016-03-24 + + + + 1.7.91 From f36555f71ad1e83d3201e7bb0d1d683af0554491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Mar 2016 13:34:18 +0200 Subject: [PATCH 2316/3781] Back to development --- configure.ac | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 7ca566c2f7..005728b998 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [8]) +m4_define([gst_vaapi_minor_version], [9]) m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [800]) +m4_define([gst_vaapi_lt_current], [900]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [800]) +m4_define([gst_vaapi_lt_age], [900]) # glib version number m4_define([glib_version], [2.32]) # gstreamer version number -m4_define([gst_version], [1.8.0]) -m4_define([gst_plugins_base_version], [1.8.0]) -m4_define([gst_plugins_bad_version], [1.8.0]) +m4_define([gst_version], [1.9.0.1]) +m4_define([gst_plugins_base_version], [1.9.0.1]) +m4_define([gst_plugins_bad_version], [1.9.0.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) From 3ec92867288dd89ad7fde98fb5157259647bb010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 24 Mar 2016 13:36:24 +0100 Subject: [PATCH 2317/3781] vaapidecode: GST_VAAPIDECODE macro is a cast This patch is the continuation of commit 1e1d3b1d because the function gst_vaapidecode_get_type() got undefined since then. Now, the macro GST_VAAPIDECODE is a simple cast to the GstVaapiDecode structure. The rest of the GObject handling macros were deleted too. --- gst/vaapi/gstvaapidecode.h | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 55d4b36dcc..691e231f5f 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -30,29 +30,7 @@ G_BEGIN_DECLS -#define GST_TYPE_VAAPIDECODE \ - (gst_vaapidecode_get_type()) - -#define GST_VAAPIDECODE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_TYPE_VAAPIDECODE, \ - GstVaapiDecode)) - -#define GST_VAAPIDECODE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_TYPE_VAAPIDECODE, \ - GstVaapiDecodeClass)) - -#define GST_IS_VAAPIDECODE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VAAPIDECODE)) - -#define GST_IS_VAAPIDECODE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VAAPIDECODE)) - -#define GST_VAAPIDECODE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_TYPE_VAAPIDECODE, \ - GstVaapiDecodeClass)) +#define GST_VAAPIDECODE(obj) ((GstVaapiDecode *)(obj)) typedef struct _GstVaapiDecode GstVaapiDecode; typedef struct _GstVaapiDecodeClass GstVaapiDecodeClass; From c2aa405a3eeabd3621414d4d5f0190223461d96a Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 24 Mar 2016 15:08:27 +0200 Subject: [PATCH 2318/3781] vaapidecode: Delay the output format setting until we have a decoded surface This will help to consoidate the out caps negotiation to a single place, which will make the code simpler, allows to get the exact decoded format if needed and the selected chroma type too. https://bugzilla.gnome.org/show_bug.cgi?id=753914 --- gst/vaapi/gstvaapidecode.c | 46 ++++++++++++-------------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 7798363ba3..0a49ff585e 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -329,10 +329,17 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) { proxy = gst_video_codec_frame_get_user_data (out_frame); - /* reconfigure if un-cropped surface resolution changed */ - if (is_surface_resolution_changed (vdec, - GST_VAAPI_SURFACE_PROXY_SURFACE (proxy))) - gst_vaapidecode_negotiate (decode); + if (G_UNLIKELY (!decode->active) || + gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec)) || + decode->do_renego || + is_surface_resolution_changed (vdec, + GST_VAAPI_SURFACE_PROXY_SURFACE (proxy))) { + if (!gst_vaapidecode_negotiate (decode)) + return GST_FLOW_ERROR; + + decode->active = TRUE; + decode->do_renego = FALSE; + } gst_vaapi_surface_proxy_set_destroy_notify (proxy, (GDestroyNotify) gst_vaapidecode_release, gst_object_ref (decode)); @@ -427,9 +434,6 @@ gst_vaapidecode_negotiate (GstVaapiDecode * decode) GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); - if (!decode->do_renego) - return TRUE; - GST_DEBUG_OBJECT (decode, "Input codec state changed, doing renegotiation"); if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) @@ -441,8 +445,6 @@ gst_vaapidecode_negotiate (GstVaapiDecode * decode) if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) return FALSE; - decode->do_renego = FALSE; - return TRUE; } @@ -464,12 +466,6 @@ gst_vaapidecode_push_all_decoded_frames (GstVaapiDecode * decode) return ret; break; case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: - /* Delayed the pool re-negotiation untill we push all decoded (and queued) - * frames downstream. Otherwise for the multi-resolution videos, the - * GstVideoVideoMemory will be having wrong resolution. - * commit 6eba201f3252eba6a99ab7da7a4c662091a3e884 */ - if (!gst_vaapidecode_negotiate (decode)) - return GST_FLOW_ERROR; return GST_FLOW_OK; default: GST_VIDEO_DECODER_ERROR (vdec, 1, STREAM, DECODE, ("Decoding failed"), @@ -486,28 +482,11 @@ gst_vaapidecode_handle_frame (GstVideoDecoder * vdec, { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstVaapiDecoderStatus status; - GstVaapiPluginBase *plugin; GstFlowReturn ret; if (!decode->input_state) goto not_negotiated; - if (G_UNLIKELY (!decode->active) || - gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec))) { - GST_DEBUG_OBJECT (decode, "activating the decoder"); - if (!gst_vaapidecode_update_src_caps (decode)) - goto not_negotiated; - - if (!gst_video_decoder_negotiate (vdec)) - goto not_negotiated; - - plugin = GST_VAAPI_PLUGIN_BASE (vdec); - if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) - goto not_negotiated; - - decode->active = TRUE; - } - /* Decode current frame */ for (;;) { status = gst_vaapi_decoder_decode (decode->decoder, frame); @@ -843,6 +822,9 @@ gst_vaapidecode_open (GstVideoDecoder * vdec) success = gst_vaapidecode_ensure_display (decode); if (old_display) gst_vaapi_display_unref (old_display); + + decode->do_renego = TRUE; + return success; } From 859a2b2f4f15fda98fd831555295f37f0db07802 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 24 Mar 2016 15:08:50 +0200 Subject: [PATCH 2319/3781] Make vaapidecode to advertise the cropped values in srcpad, but negotiate pool only if needed -- Maintaing decoded surface resoluton and actual display resoultion separately -- Before pushing every frames downstream, check for the requirement of pool negoation and output_state negotiation: This is needed to avoid multiple issuses with cropping, multi-resoluton video handling, more complex multi resolution decode scenarios for vp9decode, possible wrong behaviour from upstream element to report uncropped values etc. Due to these reasons, We can't just reliably use the resolution change notification from libgstvaapi for pool renegotiation too. This is slight overhead, but safe enough. Optimization could be possible though. https://bugzilla.gnome.org/show_bug.cgi?id=753914 --- gst/vaapi/gstvaapidecode.c | 136 ++++++++++++++++++++++++++++----- gst/vaapi/gstvaapidecode.h | 5 +- gst/vaapi/gstvaapipluginbase.c | 26 ++++++- gst/vaapi/gstvaapipluginbase.h | 2 +- gst/vaapi/gstvaapipostproc.c | 2 +- 5 files changed, 145 insertions(+), 26 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 0a49ff585e..d82d5d921d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -140,6 +140,7 @@ static gboolean gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, const GstVideoCodecState * new_state); static gboolean gst_vaapidecode_negotiate (GstVaapiDecode * decode); +/* get invoked only if actural VASurface size (not the cropped values) changed */ static void gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, const GstVideoCodecState * codec_state, gpointer user_data) @@ -153,7 +154,7 @@ gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, if (!gst_vaapidecode_update_sink_caps (decode, decode->input_state->caps)) return; - decode->do_renego = TRUE; + decode->do_pool_renego = TRUE; } static GstVideoCodecState * @@ -218,6 +219,7 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) GstVideoFormat format = GST_VIDEO_FORMAT_I420; GstClockTime latency; gint fps_d, fps_n; + guint width, height; if (!decode->input_state) return FALSE; @@ -247,8 +249,16 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) break; } + width = GST_VIDEO_INFO_WIDTH (&decode->display_info); + height = GST_VIDEO_INFO_HEIGHT (&decode->display_info); + + if (!width || !height) { + width = ref_state->info.width; + height = ref_state->info.height; + } + state = gst_video_decoder_set_output_state (vdec, format, - ref_state->info.width, ref_state->info.height, ref_state); + width, height, ref_state); if (!state || state->info.width == 0 || state->info.height == 0) { if (features) gst_caps_features_free (features); @@ -281,6 +291,7 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) latency = gst_util_uint64_scale (2 * GST_SECOND, fps_d, fps_n); gst_video_decoder_set_latency (vdec, latency, latency); + decode->do_outstate_renego = FALSE; return TRUE; } @@ -293,26 +304,83 @@ gst_vaapidecode_release (GstVaapiDecode * decode) gst_object_unref (decode); } +/* check whether the decoded surface size has changed */ static gboolean -is_surface_resolution_changed (GstVideoDecoder * vdec, +is_surface_resolution_changed (GstVaapiDecode * decode, GstVaapiSurface * surface) { + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); + GstVideoInfo *vinfo = &decode->decoded_info; + GstVideoFormat format = GST_VIDEO_FORMAT_ENCODED; guint surface_width, surface_height; - guint configured_width, configured_height; GstVideoCodecState *state; - gboolean ret = FALSE; + + g_return_val_if_fail (surface != NULL, FALSE); gst_vaapi_surface_get_size (surface, &surface_width, &surface_height); + if (GST_VIDEO_INFO_WIDTH (vinfo) == surface_width + && GST_VIDEO_INFO_HEIGHT (vinfo) == surface_height) + return FALSE; + state = gst_video_decoder_get_output_state (vdec); - configured_width = GST_VIDEO_INFO_WIDTH (&state->info); - configured_height = GST_VIDEO_INFO_HEIGHT (&state->info); - gst_video_codec_state_unref (state); + if (state) { + /* Fixme: Get exact surface format usings gst_vaapi_surface_get_format () */ + format = GST_VIDEO_INFO_FORMAT (&state->info); + gst_video_codec_state_unref (state); + } + gst_video_info_set_format (vinfo, format, surface_width, surface_height); - if (surface_width != configured_width || surface_height != configured_height) - ret = TRUE; + return TRUE; +} - return ret; +/* check whether display resolution changed */ +static gboolean +is_display_resolution_changed (GstVaapiDecode * decode, + const GstVaapiRectangle * crop_rect) +{ + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); + GstVideoFormat format = GST_VIDEO_FORMAT_ENCODED; + GstVideoCodecState *state; + GstVideoInfo *vinfo; + guint display_width = GST_VIDEO_INFO_WIDTH (&decode->decoded_info); + guint display_height = GST_VIDEO_INFO_HEIGHT (&decode->decoded_info); + + if (crop_rect) { + display_width = crop_rect->width; + display_height = crop_rect->height; + } + state = gst_video_decoder_get_output_state (vdec); + if (G_UNLIKELY (!state)) + goto set_display_res; + vinfo = &state->info; + format = GST_VIDEO_INFO_FORMAT (vinfo); + + if (GST_VIDEO_INFO_FORMAT (&decode->display_info) == GST_VIDEO_FORMAT_UNKNOWN) + decode->display_info = *vinfo; + + if (!crop_rect) { + display_width = GST_VIDEO_INFO_WIDTH (&decode->decoded_info); + display_height = GST_VIDEO_INFO_HEIGHT (&decode->decoded_info); + + if (G_UNLIKELY (display_width != + GST_VIDEO_INFO_WIDTH (&decode->display_info) + || display_height != GST_VIDEO_INFO_HEIGHT (&decode->display_info))) + goto set_display_res; + } + + if (GST_VIDEO_INFO_WIDTH (vinfo) == display_width + && GST_VIDEO_INFO_HEIGHT (vinfo) == display_height) { + gst_video_codec_state_unref (state); + return FALSE; + } + +set_display_res: + gst_video_info_set_format (&decode->display_info, format, display_width, + display_height); + if (state) + gst_video_codec_state_unref (state); + return TRUE; } static GstFlowReturn @@ -328,17 +396,29 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) { proxy = gst_video_codec_frame_get_user_data (out_frame); + crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy); + + /* in theory, we are not supposed to check the surface resolution + * change here since it should be advertised before from ligstvaapi. + * But there are issues with it especially for some vp9 streams where + * upstream element set un-cropped values in set_format() which make + * everything a mess. So better doing the explicit check here irrespective + * of what notification we get from upstream or libgstvaapi */ + decode->do_pool_renego = + is_surface_resolution_changed (decode, + GST_VAAPI_SURFACE_PROXY_SURFACE (proxy)); + + decode->do_outstate_renego = + is_display_resolution_changed (decode, crop_rect); if (G_UNLIKELY (!decode->active) || gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec)) || - decode->do_renego || - is_surface_resolution_changed (vdec, - GST_VAAPI_SURFACE_PROXY_SURFACE (proxy))) { + decode->do_outstate_renego || decode->do_pool_renego) { + if (!gst_vaapidecode_negotiate (decode)) return GST_FLOW_ERROR; decode->active = TRUE; - decode->do_renego = FALSE; } gst_vaapi_surface_proxy_set_destroy_notify (proxy, @@ -372,7 +452,6 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, GST_VIDEO_BUFFER_FLAG_FIRST_IN_BUNDLE); } - crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy); if (crop_rect) { GstVideoCropMeta *const crop_meta = gst_buffer_add_video_crop_meta (out_frame->output_buffer); @@ -616,8 +695,22 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); #endif - return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), - query, 0); + if (decode->do_pool_renego) { + gboolean ret; + + caps = gst_caps_copy (caps); + gst_caps_set_simple (caps, "width", G_TYPE_INT, + GST_VIDEO_INFO_WIDTH (&decode->decoded_info), "height", G_TYPE_INT, + GST_VIDEO_INFO_HEIGHT (&decode->decoded_info), NULL); + ret = + gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), + query, 0, caps); + gst_caps_unref (caps); + decode->do_pool_renego = FALSE; + return ret; + } else { + return TRUE; + } } static inline gboolean @@ -823,8 +916,6 @@ gst_vaapidecode_open (GstVideoDecoder * vdec) if (old_display) gst_vaapi_display_unref (old_display); - decode->do_renego = TRUE; - return success; } @@ -1146,10 +1237,15 @@ gst_vaapidecode_init (GstVaapiDecode * decode) decode->decoder = NULL; decode->decoder_caps = NULL; decode->allowed_caps = NULL; + decode->do_outstate_renego = TRUE; + decode->do_pool_renego = TRUE; g_mutex_init (&decode->surface_ready_mutex); g_cond_init (&decode->surface_ready); + gst_video_info_init (&decode->decoded_info); + gst_video_info_init (&decode->display_info); + gst_video_decoder_set_packetized (vdec, FALSE); } diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 691e231f5f..7946bf8348 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -41,6 +41,8 @@ struct _GstVaapiDecode { GstCaps *sinkpad_caps; GstCaps *srcpad_caps; + GstVideoInfo decoded_info; + GstVideoInfo display_info; GstVaapiDecoder *decoder; GMutex surface_ready_mutex; GCond surface_ready; @@ -51,7 +53,8 @@ struct _GstVaapiDecode { GstVideoCodecState *input_state; volatile gboolean active; - volatile gboolean do_renego; + volatile gboolean do_outstate_renego; + volatile gboolean do_pool_renego; }; struct _GstVaapiDecodeClass { diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 622853d352..5fa2c71f47 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -587,6 +587,8 @@ gst_vaapi_plugin_base_set_pool_config (GstBufferPool * pool, * @query: the allocation query to parse * @feature: the desired #GstVaapiCapsFeature, or zero to find the * preferred one + * @preferred_caps: the desired #GstCaps, or NULL to find the + * preferred one from query * * Decides allocation parameters for the downstream elements. * @@ -594,11 +596,12 @@ gst_vaapi_plugin_base_set_pool_config (GstBufferPool * pool, */ gboolean gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, - GstQuery * query, guint feature) + GstQuery * query, guint feature, GstCaps * preferred_caps) { GstCaps *caps = NULL; GstBufferPool *pool; GstStructure *config; + GstQuery *new_query; GstVideoInfo vi; guint size, min, max; gboolean update_pool = FALSE; @@ -613,6 +616,15 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gst_query_parse_allocation (query, &caps, NULL); + /* Make sure new caps get advertised to all downstream elements */ + if (preferred_caps) { + new_query = gst_query_new_allocation (preferred_caps, FALSE); + if (!gst_pad_peer_query (GST_VAAPI_PLUGIN_BASE_SRC_PAD (plugin), new_query)) { + GST_DEBUG ("didn't get downstream ALLOCATION hints"); + } + gst_query_unref (new_query); + } + /* We don't need any GL context beyond this point if not requested so explicitly through GstVideoGLTextureUploadMeta */ gst_object_replace (&plugin->gl_context, NULL); @@ -657,7 +669,11 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, goto error_ensure_display; gst_video_info_init (&vi); - gst_video_info_from_caps (&vi, caps); + if (!preferred_caps) + gst_video_info_from_caps (&vi, caps); + else + gst_video_info_from_caps (&vi, preferred_caps); + if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_I420, GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); @@ -690,7 +706,11 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, goto error_create_pool; config = gst_buffer_pool_get_config (pool); - gst_buffer_pool_config_set_params (config, caps, size, min, max); + if (!preferred_caps) + gst_buffer_pool_config_set_params (config, caps, size, min, max); + else + gst_buffer_pool_config_set_params (config, preferred_caps, size, min, + max); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); if (!gst_buffer_pool_set_config (pool, config)) diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 27c7491cb4..5be15ae0c6 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -213,7 +213,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, - GstQuery * query, guint feature); + GstQuery * query, guint feature, GstCaps *preferred_caps); G_GNUC_INTERNAL GstFlowReturn diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 7d968a4a91..70e4d50b0f 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1339,7 +1339,7 @@ static gboolean gst_vaapipostproc_decide_allocation (GstBaseTransform * trans, GstQuery * query) { return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (trans), - query, 0); + query, 0, NULL); } static void From 6b17ed90601e3849c657d9c233f247cff744d3f6 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 24 Mar 2016 15:09:15 +0200 Subject: [PATCH 2320/3781] vaapidecode: Derive and save the decoded surface format After the decoding of first frame, try to extract the exact decoded surface format using vaDeriveImage and keep this as the format in decoded_info. https://bugzilla.gnome.org/show_bug.cgi?id=753914 --- gst/vaapi/gstvaapidecode.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d82d5d921d..9739b3f521 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -309,11 +309,9 @@ static gboolean is_surface_resolution_changed (GstVaapiDecode * decode, GstVaapiSurface * surface) { - GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); GstVideoInfo *vinfo = &decode->decoded_info; - GstVideoFormat format = GST_VIDEO_FORMAT_ENCODED; + GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; guint surface_width, surface_height; - GstVideoCodecState *state; g_return_val_if_fail (surface != NULL, FALSE); @@ -323,12 +321,13 @@ is_surface_resolution_changed (GstVaapiDecode * decode, && GST_VIDEO_INFO_HEIGHT (vinfo) == surface_height) return FALSE; - state = gst_video_decoder_get_output_state (vdec); - if (state) { - /* Fixme: Get exact surface format usings gst_vaapi_surface_get_format () */ - format = GST_VIDEO_INFO_FORMAT (&state->info); - gst_video_codec_state_unref (state); - } + /* doing gst_vaapi_surface_get_format() only if necessary since it execute + * vaDeriveImage in the backgrorund . This will usually get executed only once */ + format = + (GST_VIDEO_INFO_FORMAT (vinfo) == + GST_VIDEO_FORMAT_UNKNOWN) ? gst_vaapi_surface_get_format (surface) : + GST_VIDEO_INFO_FORMAT (vinfo); + gst_video_info_set_format (vinfo, format, surface_width, surface_height); return TRUE; @@ -340,9 +339,9 @@ is_display_resolution_changed (GstVaapiDecode * decode, const GstVaapiRectangle * crop_rect) { GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); - GstVideoFormat format = GST_VIDEO_FORMAT_ENCODED; GstVideoCodecState *state; GstVideoInfo *vinfo; + GstVideoFormat format = GST_VIDEO_INFO_FORMAT (&decode->decoded_info); guint display_width = GST_VIDEO_INFO_WIDTH (&decode->decoded_info); guint display_height = GST_VIDEO_INFO_HEIGHT (&decode->decoded_info); @@ -360,9 +359,6 @@ is_display_resolution_changed (GstVaapiDecode * decode, decode->display_info = *vinfo; if (!crop_rect) { - display_width = GST_VIDEO_INFO_WIDTH (&decode->decoded_info); - display_height = GST_VIDEO_INFO_HEIGHT (&decode->decoded_info); - if (G_UNLIKELY (display_width != GST_VIDEO_INFO_WIDTH (&decode->display_info) || display_height != GST_VIDEO_INFO_HEIGHT (&decode->display_info))) From 959d14ce8a9e0de184dfc7e73090e5287fa1f11e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 24 Mar 2016 15:09:43 +0200 Subject: [PATCH 2321/3781] vaapidecode: Fix decide_allocation handling Set the already configured pool in decide_allocation query in cases where pool renegotiation is not required. https://bugzilla.gnome.org/show_bug.cgi?id=753914 --- gst/vaapi/gstvaapidecode.c | 38 +++++++++++++++++++++++++++++----- gst/vaapi/gstvaapipluginbase.c | 27 ++++++++++++------------ 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9739b3f521..1dbabe1926 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -399,7 +399,10 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, * But there are issues with it especially for some vp9 streams where * upstream element set un-cropped values in set_format() which make * everything a mess. So better doing the explicit check here irrespective - * of what notification we get from upstream or libgstvaapi */ + * of what notification we get from upstream or libgstvaapi.Also, even if + * we received notification from libgstvaapi, the frame we are going to + * be pushed at this point might not have the notified resolution if there + * are queued frames in decoded picture buffer. */ decode->do_pool_renego = is_surface_resolution_changed (decode, GST_VAAPI_SURFACE_PROXY_SURFACE (proxy)); @@ -680,6 +683,7 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstCaps *caps = NULL; + gboolean ret = FALSE; gst_query_parse_allocation (query, &caps, NULL); decode->has_texture_upload_meta = FALSE; @@ -692,21 +696,45 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) #endif if (decode->do_pool_renego) { - gboolean ret; - caps = gst_caps_copy (caps); + /* Always use un-cropped dimension of decoded surface for pool negotiation */ gst_caps_set_simple (caps, "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH (&decode->decoded_info), "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT (&decode->decoded_info), NULL); + ret = gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), query, 0, caps); + gst_caps_unref (caps); decode->do_pool_renego = FALSE; - return ret; } else { - return TRUE; + /* No need to renegotiate the pool, set the previously configured pool in query */ + guint size, min, max; + GstStructure *config; + GstVaapiPluginBase *plugin = GST_VAAPI_PLUGIN_BASE (vdec); + GstBufferPool *pool = plugin->srcpad_buffer_pool; + + if (G_UNLIKELY (!pool)) { + GST_ERROR ("Failed to find configured VaapiVideoBufferPool! "); + return ret; + } + + config = gst_buffer_pool_get_config (pool); + if (!config + || !gst_buffer_pool_config_get_params (config, NULL, &size, &min, &max)) + return ret; + gst_structure_free (config); + + if (gst_query_get_n_allocation_pools (query) > 0) + gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); + else + gst_query_add_allocation_pool (query, pool, size, min, max); + + ret = TRUE; } + + return ret; } static inline gboolean diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 5fa2c71f47..e764cea629 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -601,8 +601,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GstCaps *caps = NULL; GstBufferPool *pool; GstStructure *config; - GstQuery *new_query; GstVideoInfo vi; + GstQuery *old_query = NULL, *new_query = NULL; guint size, min, max; gboolean update_pool = FALSE; gboolean has_video_meta = FALSE; @@ -614,17 +614,18 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, g_return_val_if_fail (plugin->display != NULL, FALSE); - gst_query_parse_allocation (query, &caps, NULL); - /* Make sure new caps get advertised to all downstream elements */ if (preferred_caps) { - new_query = gst_query_new_allocation (preferred_caps, FALSE); + new_query = gst_query_new_allocation (preferred_caps, TRUE); if (!gst_pad_peer_query (GST_VAAPI_PLUGIN_BASE_SRC_PAD (plugin), new_query)) { GST_DEBUG ("didn't get downstream ALLOCATION hints"); } - gst_query_unref (new_query); + old_query = query; + query = new_query; } + gst_query_parse_allocation (query, &caps, NULL); + /* We don't need any GL context beyond this point if not requested so explicitly through GstVideoGLTextureUploadMeta */ gst_object_replace (&plugin->gl_context, NULL); @@ -669,10 +670,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, goto error_ensure_display; gst_video_info_init (&vi); - if (!preferred_caps) - gst_video_info_from_caps (&vi, caps); - else - gst_video_info_from_caps (&vi, preferred_caps); + gst_video_info_from_caps (&vi, caps); if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_I420, @@ -706,11 +704,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, goto error_create_pool; config = gst_buffer_pool_get_config (pool); - if (!preferred_caps) - gst_buffer_pool_config_set_params (config, caps, size, min, max); - else - gst_buffer_pool_config_set_params (config, preferred_caps, size, min, - max); + gst_buffer_pool_config_set_params (config, caps, size, min, max); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); if (!gst_buffer_pool_set_config (pool, config)) @@ -737,6 +731,11 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, } #endif + if (old_query) + query = old_query; + if (new_query) + gst_query_unref (new_query); + if (update_pool) gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); else From ddddb0415b181e3ca8cc70e843b821fb01d504c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 28 Mar 2016 13:13:56 +0200 Subject: [PATCH 2322/3781] gltextureupload: use an array for texture type Instead of using a single value for the texture type, use an array with 4 elements, just as the GstVideoGLTextureUploadMeta, avoiding a buffer overflow. https://bugzilla.gnome.org/show_bug.cgi?id=764231 --- gst/vaapi/gstvaapivideometa_texture.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 9608d6578e..01e33852fd 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -40,7 +40,7 @@ struct _GstVaapiVideoMetaTexture { GstVaapiTexture *texture; - GstVideoGLTextureType texture_type; + GstVideoGLTextureType texture_type[4]; guint gl_format; guint width; guint height; @@ -73,15 +73,17 @@ static gboolean meta_texture_ensure_format (GstVaapiVideoMetaTexture * meta, GstVideoFormat format) { + memset (meta->texture_type, 0, sizeof (meta->texture_type)); + switch (format) { case GST_VIDEO_FORMAT_RGBA: meta->gl_format = GL_RGBA; - meta->texture_type = GST_VIDEO_GL_TEXTURE_TYPE_RGBA; + meta->texture_type[0] = GST_VIDEO_GL_TEXTURE_TYPE_RGBA; break; case GST_VIDEO_FORMAT_BGRA: meta->gl_format = GL_BGRA_EXT; /* FIXME: add GST_VIDEO_GL_TEXTURE_TYPE_BGRA extension */ - meta->texture_type = GST_VIDEO_GL_TEXTURE_TYPE_RGBA; + meta->texture_type[0] = GST_VIDEO_GL_TEXTURE_TYPE_RGBA; break; default: goto error_unsupported_format; @@ -155,7 +157,7 @@ meta_texture_copy (GstVaapiVideoMetaTexture * meta) if (!copy) return NULL; - copy->texture_type = meta->texture_type; + memcpy (copy->texture_type, meta->texture_type, sizeof (meta->texture_type)); copy->gl_format = meta->gl_format; copy->width = meta->width; copy->height = meta->height; @@ -220,7 +222,7 @@ gst_buffer_add_texture_upload_meta (GstBuffer * buffer) meta = gst_buffer_add_video_gl_texture_upload_meta (buffer, GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, - 1, &meta_texture->texture_type, gst_vaapi_texture_upload, + 1, meta_texture->texture_type, gst_vaapi_texture_upload, meta_texture, (GBoxedCopyFunc) meta_texture_copy, (GBoxedFreeFunc) meta_texture_free); if (!meta) From b64eaaad4d3be38030f8370f6e5c58bc830a813e Mon Sep 17 00:00:00 2001 From: Stephen Date: Sun, 27 Mar 2016 09:11:00 +0000 Subject: [PATCH 2323/3781] libs: x11: allows 30-bit colour depth The colour depth is clamped to 24 when it is not equal {15,16,24,32}. But this fails with the NVIDIA binary driver as it doesn't advertise a TrueColor visual with a depth of 24 (only 30 and 32). Allowing the depth to be 30, lets everything work as expected. https://bugzilla.gnome.org/show_bug.cgi?id=764256 --- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index a4f943c9c9..0f3f4d9994 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -90,7 +90,7 @@ x11_create_window (Display * dpy, guint w, guint h, guint vid, Colormap cmap) XGetWindowAttributes (dpy, rootwin, &wattr); depth = wattr.depth; - if (depth != 15 && depth != 16 && depth != 24 && depth != 32) + if (depth != 15 && depth != 16 && depth != 24 && depth != 30 && depth != 32) depth = 24; xswa_mask = CWBorderPixel | CWBackPixel; From eea3f0cdb24215fb93edfda8e7ef6e8357ef0b34 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Tue, 29 Mar 2016 14:34:00 +0300 Subject: [PATCH 2324/3781] Add P010 video format support The P010 video format is the native format used by the vaapi intel driver for HEVCMain10 decode . Add support for planes and images of this video format. https://bugzilla.gnome.org/show_bug.cgi?id=759181 --- gst-libs/gst/vaapi/gstvaapiimage.c | 3 +++ gst-libs/gst/vaapi/video-format.c | 5 +++++ gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapipluginutil.h | 4 ++-- gst/vaapi/gstvaapisink.c | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 98bedcb3b6..b1f530112d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -94,6 +94,9 @@ vaapi_image_is_linear (const VAImage * va_image) case VA_FOURCC ('B', 'G', 'R', 'X'): data_size = 4 * width * height; break; + case VA_FOURCC ('P', '0', '1', '0'): + data_size = 2 * (width * height + 2 * width2 * height2); + break; default: g_error ("FIXME: incomplete formats %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (va_image->format.fourcc)); diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 9a6edd47a1..265df5a1b5 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -50,7 +50,9 @@ typedef struct { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } /* Image formats, listed in HW order preference */ +/* *INDENT-OFF* */ static const GstVideoFormatMap gst_vaapi_video_formats[] = { + DEF_YUV (P010_10LE, ('P', '0', '1', '0'), LSB, 24, 420_10BPP), DEF_YUV (NV12, ('N', 'V', '1', '2'), LSB, 12, 420), DEF_YUV (YV12, ('Y', 'V', '1', '2'), LSB, 12, 420), DEF_YUV (I420, ('I', '4', '2', '0'), LSB, 12, 420), @@ -79,6 +81,7 @@ static const GstVideoFormatMap gst_vaapi_video_formats[] = { DEF_YUV (GRAY8, ('Y', '8', '0', '0'), LSB, 8, 400), {0,} }; +/* *INDENT-ON* */ #undef DEF_RGB #undef DEF_YUV @@ -298,6 +301,8 @@ gst_vaapi_video_format_get_best_native (GstVideoFormat format) case GST_VAAPI_CHROMA_TYPE_YUV420: case GST_VAAPI_CHROMA_TYPE_RGB32: /* GstVideoGLTextureUploadMeta */ return GST_VIDEO_FORMAT_NV12; + case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: + return GST_VIDEO_FORMAT_P010_10LE; default: return GST_VIDEO_FORMAT_UNKNOWN; }; diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1dbabe1926..f060e8bdef 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -105,7 +105,7 @@ static const char gst_vaapidecode_sink_caps_str[] = static const char gst_vaapidecode_src_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ";" GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" - GST_VIDEO_CAPS_MAKE("{ I420, YV12, NV12 }"); + GST_VIDEO_CAPS_MAKE("{ I420, YV12, NV12, P010_10LE }"); static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_STATIC_PAD_TEMPLATE( diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index d46f2dbb7b..4b1968097f 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -104,11 +104,11 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps, #define GST_VAAPI_MAKE_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12, P010_10LE }") #define GST_VAAPI_MAKE_ENC_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, P010_10LE }") #define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 6663065d41..638c8d82e1 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -68,7 +68,7 @@ static const char gst_vaapisink_sink_caps_str[] = GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - "{ ENCODED, NV12, I420, YV12 }") ";" + "{ ENCODED, NV12, I420, YV12, P010_10LE }") ";" GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, GST_VIDEO_FORMATS_ALL) ";" From 75a20deab46a40442b64d53218f37825647401fb Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 29 Mar 2016 14:34:37 +0300 Subject: [PATCH 2325/3781] vaapidecode: Use video format derived from decoded surface as default src pad format Use the surface format derived from first decoded surface to negotiate the downstream video format capabilities. https://bugzilla.gnome.org/show_bug.cgi?id=759181 --- gst/vaapi/gstvaapidecode.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f060e8bdef..d7305c3531 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -215,7 +215,7 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) GstVideoCodecState *state, *ref_state; GstVaapiCapsFeature feature; GstCapsFeatures *features = NULL; - GstVideoInfo *vi; + GstVideoInfo *vi, *decoded_info; GstVideoFormat format = GST_VIDEO_FORMAT_I420; GstClockTime latency; gint fps_d, fps_n; @@ -226,9 +226,13 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) ref_state = decode->input_state; + decoded_info = + (GST_VIDEO_INFO_FORMAT (&decode->decoded_info) != + GST_VIDEO_FORMAT_UNKNOWN) ? &decode->decoded_info : &ref_state->info; + feature = gst_vaapi_find_preferred_caps_feature (GST_VIDEO_DECODER_SRC_PAD (vdec), - GST_VIDEO_INFO_FORMAT (&ref_state->info), &format); + GST_VIDEO_INFO_FORMAT (decoded_info), &format); if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) return FALSE; From fd04a7c046c46b808c11d0dd523fa4524192b861 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 29 Mar 2016 15:02:46 +0300 Subject: [PATCH 2326/3781] gst/vaapi: keep precedence for NV12 over I420 Use NV12 as default "assumption" format all over. NV12 is the default high priority format used my most of the vaapi-drivers. --- gst/vaapi/gstvaapidecode.c | 4 ++-- gst/vaapi/gstvaapipluginbase.c | 2 +- gst/vaapi/gstvaapipluginutil.c | 2 +- gst/vaapi/gstvaapipluginutil.h | 2 +- gst/vaapi/gstvaapivideomemory.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d7305c3531..7dac9b6268 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -105,7 +105,7 @@ static const char gst_vaapidecode_sink_caps_str[] = static const char gst_vaapidecode_src_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ";" GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" - GST_VIDEO_CAPS_MAKE("{ I420, YV12, NV12, P010_10LE }"); + GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, P010_10LE }"); static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_STATIC_PAD_TEMPLATE( @@ -216,7 +216,7 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) GstVaapiCapsFeature feature; GstCapsFeatures *features = NULL; GstVideoInfo *vi, *decoded_info; - GstVideoFormat format = GST_VIDEO_FORMAT_I420; + GstVideoFormat format = GST_VIDEO_FORMAT_NV12; GstClockTime latency; gint fps_d, fps_n; guint width, height; diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e764cea629..c2dc4c98ec 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -673,7 +673,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gst_video_info_from_caps (&vi, caps); if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) - gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_I420, + gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); if (gst_query_get_n_allocation_pools (query) > 0) { diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index a8d6a30271..dc81d0eac8 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -461,7 +461,7 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, } out_format = format == GST_VIDEO_FORMAT_ENCODED ? - GST_VIDEO_FORMAT_I420 : format; + GST_VIDEO_FORMAT_NV12 : format; gl_texture_upload_caps = new_gl_texture_upload_meta_caps (); if (!gl_texture_upload_caps) diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 4b1968097f..58db50f6f0 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -104,7 +104,7 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps, #define GST_VAAPI_MAKE_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12, P010_10LE }") + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, P010_10LE }") #define GST_VAAPI_MAKE_ENC_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 00f6a85d11..c7f8ee1b42 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -716,7 +716,7 @@ allocator_configure_image_info (GstVaapiDisplay * display, vinfo = &allocator->video_info; if (GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) - gst_video_info_set_format (&allocator->image_info, GST_VIDEO_FORMAT_I420, + gst_video_info_set_format (&allocator->image_info, GST_VIDEO_FORMAT_NV12, GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); else allocator->image_info = *vinfo; From 35fe2abc3e37776f3ad5dba9c073e29804d3f192 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 29 Mar 2016 15:34:38 +0300 Subject: [PATCH 2327/3781] video-format: Keep the HW order preference while mapping to GstVideoFormats --- gst-libs/gst/vaapi/video-format.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 265df5a1b5..78fb4dab9d 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -52,7 +52,6 @@ typedef struct /* Image formats, listed in HW order preference */ /* *INDENT-OFF* */ static const GstVideoFormatMap gst_vaapi_video_formats[] = { - DEF_YUV (P010_10LE, ('P', '0', '1', '0'), LSB, 24, 420_10BPP), DEF_YUV (NV12, ('N', 'V', '1', '2'), LSB, 12, 420), DEF_YUV (YV12, ('Y', 'V', '1', '2'), LSB, 12, 420), DEF_YUV (I420, ('I', '4', '2', '0'), LSB, 12, 420), @@ -79,6 +78,7 @@ static const GstVideoFormatMap gst_vaapi_video_formats[] = { 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), #endif DEF_YUV (GRAY8, ('Y', '8', '0', '0'), LSB, 8, 400), + DEF_YUV (P010_10LE, ('P', '0', '1', '0'), LSB, 24, 420_10BPP), {0,} }; /* *INDENT-ON* */ From c009d29c008c36156dc7f22b91cb491216d95822 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 30 Mar 2016 14:37:21 +0300 Subject: [PATCH 2328/3781] decoder: h265: Fix offset calculation when there is more than one vps/sps/pps present in codec_data The array_completeness, reserved bit and num_nal_units fields in HEVCDecoderConfigurationRecord will be present for each VPS/SPS/PPS array list, but not for each occurance of similar headers. https://bugzilla.gnome.org/show_bug.cgi?id=764274 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index fd8250ada1..0dac7dbfcd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2650,13 +2650,15 @@ gst_vaapi_decoder_h265_decode_codec_data (GstVaapiDecoder * ofs = 23; for (i = 0; i < num_nal_arrays; i++) { num_nals = GST_READ_UINT16_BE (buf + ofs + 1); + ofs += 3; + for (j = 0; j < num_nals; j++) { pi = gst_vaapi_parser_info_h265_new (); if (!pi) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; unit.parsed_info = pi; result = gst_h265_parser_identify_nalu_hevc (priv->parser, - buf, ofs + 3, buf_size, 2, &pi->nalu); + buf, ofs, buf_size, 2, &pi->nalu); if (result != GST_H265_PARSER_OK) { status = get_status (result); goto cleanup; From aac0f505007749d75858bb0ff676f4ba7a0341d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 29 Mar 2016 13:50:00 +0200 Subject: [PATCH 2329/3781] docs: generate vaapijpegdec documentation https://bugzilla.gnome.org/show_bug.cgi?id=764314 --- .../gstreamer-vaapi-plugins-docs.xml.in | 1 + .../gstreamer-vaapi-plugins-sections.txt | 15 +++++------ gst/vaapi/gstvaapidecode.c | 25 +++++++++++++++++++ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in index 6626e0e443..c9cb5fc1f4 100644 --- a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in +++ b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in @@ -12,6 +12,7 @@ gstreamer-vaapi Elements + diff --git a/docs/plugins/gstreamer-vaapi-plugins-sections.txt b/docs/plugins/gstreamer-vaapi-plugins-sections.txt index bdd34f2c91..e3bc8e4031 100644 --- a/docs/plugins/gstreamer-vaapi-plugins-sections.txt +++ b/docs/plugins/gstreamer-vaapi-plugins-sections.txt @@ -2,15 +2,16 @@ element-vaapidecode vaapidecode -GST_IS_VAAPIDECODE -GST_IS_VAAPIDECODE_CLASS -GST_TYPE_VAAPIDECODE -GST_VAAPIDECODE -GST_VAAPIDECODE_CLASS -GST_VAAPIDECODE_GET_CLASS GstVaapiDecode GstVaapiDecodeClass -gst_vaapidecode_get_type +
+ +
+element-vaapijpegdec +vaapijpegdec + +GstVaapiDecode_jpeg +GstVaapiDecode_jpegClass
diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 7dac9b6268..0f7f3ea830 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -47,6 +47,31 @@ * */ +/** + * SECTION:element-vaapijpegdec + * @short_description: A VA-API based JPEG image decoder + * + * vaapijpegdec decodes a JPEG image to surfaces suitable for the + * vaapisink or vaapipostproc elements using the installed VA-API + * back-end. + * + * In the case of OpenGL based elements, the buffers have the + * #GstVideoGLTextureUploadMeta meta, which efficiently copies the + * content of the VA-API surface into a GL texture. + * + * Also it can deliver normal video buffers that can be rendered or + * processed by other elements, but the performance would be rather + * bad. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=~/image.jpeg ! jpegparse ! vaapijpegdec ! imagefreeze ! vaapisink + * ]| + * + */ + #include "gstcompat.h" #include From fe08f7ecdc788c1060eee57b7a69c8a46301239e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Mar 2016 17:42:55 +0100 Subject: [PATCH 2330/3781] vaapidecode: move gst_vaapidecode_negotiate() code With it we can remove a function declaration, making the code a bit more readable. https://bugzilla.gnome.org/show_bug.cgi?id=764316 --- gst/vaapi/gstvaapidecode.c | 41 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 0f7f3ea830..eb25ec8a04 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -163,7 +163,6 @@ static gboolean gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps); static gboolean gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, const GstVideoCodecState * new_state); -static gboolean gst_vaapidecode_negotiate (GstVaapiDecode * decode); /* get invoked only if actural VASurface size (not the cropped values) changed */ static void @@ -408,6 +407,26 @@ set_display_res: return TRUE; } +static gboolean +gst_vaapidecode_negotiate (GstVaapiDecode * decode) +{ + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); + + GST_DEBUG_OBJECT (decode, "Input codec state changed, doing renegotiation"); + + if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) + return FALSE; + if (!gst_vaapidecode_update_src_caps (decode)) + return FALSE; + if (!gst_video_decoder_negotiate (vdec)) + return FALSE; + if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) + return FALSE; + + return TRUE; +} + static GstFlowReturn gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, GstVideoCodecFrame * out_frame) @@ -535,26 +554,6 @@ error_commit_buffer: } } -static gboolean -gst_vaapidecode_negotiate (GstVaapiDecode * decode) -{ - GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); - - GST_DEBUG_OBJECT (decode, "Input codec state changed, doing renegotiation"); - - if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) - return FALSE; - if (!gst_vaapidecode_update_src_caps (decode)) - return FALSE; - if (!gst_video_decoder_negotiate (vdec)) - return FALSE; - if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) - return FALSE; - - return TRUE; -} - static GstFlowReturn gst_vaapidecode_push_all_decoded_frames (GstVaapiDecode * decode) { From d4f00383ed7f944eb55e780c15b6f39464097dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 29 Mar 2016 14:25:55 +0200 Subject: [PATCH 2331/3781] unify caps template for VAAPI encoders and decoders There is no difference in VAAPI surface caps between encoders and decoders. Thus, the patch makes a simplification by removing encoders specific caps and shares the same definition of VAAPI surfaces caps for all the elements. --- gst/vaapi/gstvaapiencode_h264.c | 2 +- gst/vaapi/gstvaapiencode_h265.c | 2 +- gst/vaapi/gstvaapiencode_jpeg.c | 2 +- gst/vaapi/gstvaapiencode_mpeg2.c | 2 +- gst/vaapi/gstvaapiencode_vp8.c | 2 +- gst/vaapi/gstvaapipluginutil.h | 4 ---- gst/vaapi/gstvaapisink.c | 4 ++-- 7 files changed, 7 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index b4027ab192..ba7a1e5287 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -56,7 +56,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_h264_sink_caps_str[] = - GST_VAAPI_MAKE_ENC_SURFACE_CAPS ", " + GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index b5e5bf7c07..f48adbf400 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -55,7 +55,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h265_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_h265_sink_caps_str[] = - GST_VAAPI_MAKE_ENC_SURFACE_CAPS ", " + GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 902a12f644..58c057ae01 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -52,7 +52,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_jpeg_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_jpeg_sink_caps_str[] = - GST_VAAPI_MAKE_ENC_SURFACE_CAPS ", " + GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 791adff34a..c060061fa0 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -54,7 +54,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = - GST_VAAPI_MAKE_ENC_SURFACE_CAPS ", " + GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index db5ead4eb6..cc9beb36a9 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -52,7 +52,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp8_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_vp8_sink_caps_str[] = - GST_VAAPI_MAKE_ENC_SURFACE_CAPS ", " + GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 58db50f6f0..0e62b1f0a9 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -106,10 +106,6 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps, GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, P010_10LE }") -#define GST_VAAPI_MAKE_ENC_SURFACE_CAPS \ - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, P010_10LE }") - #define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 638c8d82e1..8d7b6e0ca4 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -64,7 +64,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapisink); /* Default template */ /* *INDENT-OFF* */ static const char gst_vaapisink_sink_caps_str[] = - GST_VAAPI_MAKE_ENC_SURFACE_CAPS ";" + GST_VAAPI_MAKE_SURFACE_CAPS ";" GST_VIDEO_CAPS_MAKE_WITH_FEATURES ( GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, @@ -1215,7 +1215,7 @@ gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); GstCaps *out_caps, *raw_caps; static const char surface_caps_str[] = - GST_VAAPI_MAKE_ENC_SURFACE_CAPS ";" + GST_VAAPI_MAKE_SURFACE_CAPS ";" GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, "{ ENCODED, NV12, I420, YV12 }"); From 45145d73dd7d0bf2563f4d857667e7cb508834b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 3 Feb 2016 20:34:49 +0100 Subject: [PATCH 2332/3781] build: possibility to disable tests The configuration option --disable-examples will disable the compilation of the sample apps in tests/ directory. --- Makefile.am | 8 +++++++- configure.ac | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index fcff854416..a6a4a42338 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,12 @@ ACLOCAL_AMFLAGS = -I m4 -I common/m4 -SUBDIRS = gst-libs gst tests m4 common docs +if BUILD_EXAMPLES +SUBDIRS_TESTS = tests +else +SUBDIRS_TESTS = +endif + +SUBDIRS = gst-libs gst $(SUBDIRS_TESTS) m4 common docs DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc diff --git a/configure.ac b/configure.ac index 005728b998..71356f6902 100644 --- a/configure.ac +++ b/configure.ac @@ -112,6 +112,8 @@ AG_GST_ARG_DISABLE_FATAL_WARNINGS AG_GST_ARG_ENABLE_EXTRA_CHECKS AG_GST_ARG_DEBUG +AG_GST_ARG_EXAMPLES + AG_GST_ARG_WITH_PKG_CONFIG_PATH AG_GST_SET_PACKAGE_RELEASE_DATETIME_WITH_NANO([$PACKAGE_VERSION_NANO], From 4e5cf53ee037889f9a694f644bc0560f937de12d Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 1 Apr 2016 13:57:45 +0300 Subject: [PATCH 2333/3781] gstvaapiporfile: Add more VP9 profile definitions https://bugzilla.gnome.org/show_bug.cgi?id=764082 --- gst-libs/gst/vaapi/gstvaapiprofile.c | 12 ++++++++++-- gst-libs/gst/vaapi/gstvaapiprofile.h | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 3db05c9071..89d8929e64 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -132,8 +132,16 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h265", "main-10"}, #endif #if VA_CHECK_VERSION(0,38,0) - {GST_VAAPI_PROFILE_VP9, VAProfileVP9Profile0, - "video/x-vp9", NULL}, + {GST_VAAPI_PROFILE_VP9_0, VAProfileVP9Profile0, + "video/x-vp9", "profile0"}, +#endif +#if VA_CHECK_VERSION(0,39,0) + {GST_VAAPI_PROFILE_VP9_1, VAProfileVP9Profile1, + "video/x-vp9", "profile1"}, + {GST_VAAPI_PROFILE_VP9_2, VAProfileVP9Profile2, + "video/x-vp9", "profile2"}, + {GST_VAAPI_PROFILE_VP9_3, VAProfileVP9Profile3, + "video/x-vp9", "profile3"}, #endif {0,} }; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 8bc340e2e0..c77777f0d2 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -131,8 +131,14 @@ typedef enum { * H.265 main 10 profile [A.3.3] * @GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE: * H.265 main still picture profile [A.3.4] - * @GST_VAAPI_PROFILE_VP9: - * VP9 prfile 0 + * @GST_VAAPI_PROFILE_VP9_0: + * VP9 prfile 0, bitdepth=8, 420 + * @GST_VAAPI_PROFILE_VP9_1: + * VP9 prfile 1, bitdepth=8, 422/444/440/RGB + * @GST_VAAPI_PROFILE_VP9_2: + * VP9 prfile 2, bitdepth=10/12, 420 + * @GST_VAAPI_PROFILE_VP9_3: + * VP9 prfile 3 bitdepth=10/12, 422/444/440/RGB * * The set of all profiles for #GstVaapiProfile. */ @@ -169,7 +175,10 @@ typedef enum { GST_VAAPI_PROFILE_H265_MAIN10 = GST_VAAPI_MAKE_PROFILE(H265,2), GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE = GST_VAAPI_MAKE_PROFILE(H265,3), - GST_VAAPI_PROFILE_VP9 = GST_VAAPI_MAKE_PROFILE(VP9,1), + GST_VAAPI_PROFILE_VP9_0 = GST_VAAPI_MAKE_PROFILE(VP9,1), + GST_VAAPI_PROFILE_VP9_1 = GST_VAAPI_MAKE_PROFILE(VP9,2), + GST_VAAPI_PROFILE_VP9_2 = GST_VAAPI_MAKE_PROFILE(VP9,3), + GST_VAAPI_PROFILE_VP9_3 = GST_VAAPI_MAKE_PROFILE(VP9,4), } GstVaapiProfile; /** From 641e9a47f6dd25cf4d7ec45b31366ad9b2a42411 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 1 Apr 2016 13:59:59 +0300 Subject: [PATCH 2334/3781] decoder: vp9 : Add 10bit decoding support (Profile2) https://bugzilla.gnome.org/show_bug.cgi?id=764082 --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 33 +++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 33a9b2cc57..d0be616838 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -153,14 +153,44 @@ gst_vaapi_decoder_vp9_create (GstVaapiDecoder * base_decoder) return TRUE; } +/* 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: + g_debug ("unsupported profile_idc value"); + profile = GST_VAAPI_PROFILE_UNKNOWN; + break; + } + return profile; +} + static GstVaapiDecoderStatus ensure_context (GstVaapiDecoderVp9 * decoder) { GstVaapiDecoderVp9Private *const priv = &decoder->priv; - const GstVaapiProfile profile = GST_VAAPI_PROFILE_VP9; + GstVp9FrameHdr *frame_hdr = &priv->frame_hdr; + 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)) @@ -292,6 +322,7 @@ fill_picture (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture) #if VA_CHECK_VERSION (0, 39, 0) COPY_FIELD (frame_hdr, 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) == From 80c3bfe4485b98596489eb2f5eb3836fc5ec0bea Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 1 Apr 2016 14:00:28 +0300 Subject: [PATCH 2335/3781] decoder: vp9: Align with the ABI changes in vp9 codecparser The subsampling_x, subsampling_y, bit_depth, color_space and color_range fileds are moved from GstVp9FrameHdr to the global GstVp9Parser structure. These fields are only present in keyframe or intra-only frame, no need to duplicate them for inter-frames. https://bugzilla.gnome.org/show_bug.cgi?id=764082 --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index d0be616838..a93154a54e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -291,8 +291,8 @@ fill_picture (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture) #define COPY_BFM(a, s, f) \ pic_param->a.bits.f = (s)->f - COPY_BFM (pic_fields, frame_hdr, subsampling_x); - COPY_BFM (pic_fields, frame_hdr, subsampling_y); + 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); @@ -320,7 +320,7 @@ fill_picture (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture) COPY_FIELD (frame_hdr, first_partition_size); COPY_FIELD (frame_hdr, profile); #if VA_CHECK_VERSION (0, 39, 0) - COPY_FIELD (frame_hdr, bit_depth); + COPY_FIELD (parser, bit_depth); #endif g_assert (G_N_ELEMENTS (pic_param->mb_segment_tree_probs) == From 506c9e2b5bbc50730b0083598b346b0fcc41ec78 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Fri, 18 Mar 2016 20:00:52 -0300 Subject: [PATCH 2336/3781] vaapidecode: add stop function Clear any status on the current stream: stored frames, caps and decoder configuration https://bugzilla.gnome.org/show_bug.cgi?id=763460 --- gst/vaapi/gstvaapidecode.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index eb25ec8a04..c3ac9b1ea1 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -937,8 +937,6 @@ gst_vaapidecode_finalize (GObject * object) { GstVaapiDecode *const decode = GST_VAAPIDECODE (object); - gst_caps_replace (&decode->sinkpad_caps, NULL); - gst_caps_replace (&decode->srcpad_caps, NULL); gst_caps_replace (&decode->allowed_caps, NULL); g_cond_clear (&decode->surface_ready); @@ -976,12 +974,25 @@ gst_vaapidecode_close (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - gst_vaapi_decode_input_state_replace (decode, NULL); gst_vaapidecode_destroy (decode); gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (decode)); return TRUE; } +static gboolean +gst_vaapidecode_stop (GstVideoDecoder * vdec) +{ + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + + gst_vaapidecode_purge (decode); + gst_vaapi_decode_input_state_replace (decode, NULL); + gst_vaapi_decoder_replace (&decode->decoder, NULL); + gst_caps_replace (&decode->decoder_caps, NULL); + gst_caps_replace (&decode->sinkpad_caps, NULL); + gst_caps_replace (&decode->srcpad_caps, NULL); + return TRUE; +} + static gboolean gst_vaapidecode_flush (GstVideoDecoder * vdec) { @@ -1235,6 +1246,7 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->open = GST_DEBUG_FUNCPTR (gst_vaapidecode_open); vdec_class->close = GST_DEBUG_FUNCPTR (gst_vaapidecode_close); + vdec_class->stop = GST_DEBUG_FUNCPTR (gst_vaapidecode_stop); vdec_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapidecode_set_format); vdec_class->flush = GST_DEBUG_FUNCPTR (gst_vaapidecode_flush); vdec_class->parse = GST_DEBUG_FUNCPTR (gst_vaapidecode_parse); From bb0b8ce7ab97939aadf2d40c09e6323c37bae4e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 7 Apr 2016 18:03:42 +0200 Subject: [PATCH 2337/3781] surface: destroy derived image If gst_vaapi_image_new_with_image() fails, the created derived image should be destroyed, otherwise the surface cannot be processed because is being used. https://bugzilla.gnome.org/show_bug.cgi?id=764607 --- gst-libs/gst/vaapi/gstvaapisurface.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 9900c78138..cefb2a6ace 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -624,6 +624,7 @@ gst_vaapi_surface_derive_image (GstVaapiSurface * surface) GstVaapiDisplay *display; VAImage va_image; VAStatus status; + GstVaapiImage *image; g_return_val_if_fail (surface != NULL, NULL); @@ -640,7 +641,10 @@ gst_vaapi_surface_derive_image (GstVaapiSurface * surface) if (va_image.image_id == VA_INVALID_ID || va_image.buf == VA_INVALID_ID) return NULL; - return gst_vaapi_image_new_with_image (display, &va_image); + image = gst_vaapi_image_new_with_image (display, &va_image); + if (!image) + vaDestroyImage (GST_VAAPI_DISPLAY_VADISPLAY (display), va_image.image_id); + return image; } /** From 1e32d62c1e27e4df5d127c30fd3b6084e2db8483 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Wed, 13 Apr 2016 14:09:00 +0200 Subject: [PATCH 2338/3781] libs: fix deleting a GstVaapiCodedBufferPool object Call gst_vaapi_video_pool_finalize() in coded_buffer_pool_finalize(). Otherwise it is not called when the pool is destroyed and all objects referenced by the GstVaapiVideoPool are never released. https://bugzilla.gnome.org/show_bug.cgi?id=764993 --- gst-libs/gst/vaapi/gstvaapicodedbufferpool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c index e2475536de..a46d5016de 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c @@ -54,6 +54,7 @@ coded_buffer_pool_init (GstVaapiCodedBufferPool * pool, static void coded_buffer_pool_finalize (GstVaapiCodedBufferPool * pool) { + gst_vaapi_video_pool_finalize (GST_VAAPI_VIDEO_POOL (pool)); gst_vaapi_object_replace (&pool->context, NULL); } From f61b728ae157b5f163d28ff2b588087c93ad6a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 13 Apr 2016 20:33:32 +0200 Subject: [PATCH 2339/3781] plugins: fix compilation when EGL/GLX is disabled The compiler might complain of gst_vaapi_create_display_from_handle() being unused if both EGL and GLX are disabled. This patch avoid that compilation error. --- gst/vaapi/gstvaapipluginutil.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index dc81d0eac8..cc878e324d 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -103,6 +103,7 @@ gst_vaapi_create_display (GstVaapiDisplayType display_type, return display; } +#if USE_GST_GL_HELPERS static GstVaapiDisplay * gst_vaapi_create_display_from_handle (GstVaapiDisplayType display_type, gpointer handle) @@ -122,6 +123,7 @@ gst_vaapi_create_display_from_handle (GstVaapiDisplayType display_type, } return NULL; } +#endif static GstVaapiDisplay * gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) From 6ec2a09729716cdfdef9a9e2e6d6919b512d6992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 13 Apr 2016 15:44:20 +0200 Subject: [PATCH 2340/3781] plugins: disable GL_TEXTURE_UPLOAD if no EGL/GLX The plugins should not expose the feature meta:GstVideoGLTextureUploadMeta in their caps templates if they were not compiled either with GLX or EGL support. --- gst/vaapi/gstvaapidecode.c | 2 ++ gst/vaapi/gstvaapidecodebin.c | 2 ++ gst/vaapi/gstvaapipostproc.c | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index c3ac9b1ea1..3dbc2fae88 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -129,7 +129,9 @@ static const char gst_vaapidecode_sink_caps_str[] = static const char gst_vaapidecode_src_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ";" +#if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" +#endif GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, P010_10LE }"); static GstStaticPadTemplate gst_vaapidecode_src_factory = diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 3468ae1229..93fa8b2217 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -106,8 +106,10 @@ static const char gst_vaapi_decode_bin_sink_caps_str[] = static const char gst_vaapi_decode_bin_src_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " +#if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " +#endif GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 70e4d50b0f..62deb0eb79 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -55,7 +55,9 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapipostproc); static const char gst_vaapipostproc_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES "; " +#if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS "; " +#endif GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_MODES; /* *INDENT-ON* */ @@ -64,7 +66,9 @@ static const char gst_vaapipostproc_sink_caps_str[] = static const char gst_vaapipostproc_src_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " +#if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS "; " +#endif GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ From 5f5e4dcbdf9712624d6e89cf79323f91d68b0b8b Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Thu, 14 Apr 2016 10:04:47 +0100 Subject: [PATCH 2341/3781] Automatic update of common submodule From 6f2d209 to ac2f647 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 6f2d2093e8..ac2f647695 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 6f2d2093e84cc0eb99b634fa281822ebb9507285 +Subproject commit ac2f647695e7bd4b433ea108ee1d0e23901797d4 From 8169c6afb1bc1ee7ba78e091bb31876ca6f9b5f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 14 Apr 2016 15:46:32 +0200 Subject: [PATCH 2342/3781] remove custom allocation query When resolving bug 753914, a custom allocation query was added, overlapping the responsibilities of GstVideoDecoder. But with the merge of the patches from bug 764421 this overlapping was not required anymore. This patch restores this situation setting the allocation_caps in the GstVideoCodecState when needed. https://bugzilla.gnome.org/show_bug.cgi?id=764316 --- gst/vaapi/gstvaapidecode.c | 61 +++++++++++----------------------- gst/vaapi/gstvaapipluginbase.c | 21 +----------- gst/vaapi/gstvaapipluginbase.h | 2 +- gst/vaapi/gstvaapipostproc.c | 2 +- 4 files changed, 23 insertions(+), 63 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3dbc2fae88..4fba8fe9ba 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -241,11 +241,13 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) GstVideoCodecState *state, *ref_state; GstVaapiCapsFeature feature; GstCapsFeatures *features = NULL; + GstCaps *allocation_caps; GstVideoInfo *vi, *decoded_info; GstVideoFormat format = GST_VIDEO_FORMAT_NV12; GstClockTime latency; gint fps_d, fps_n; guint width, height; + const gchar *format_str; if (!decode->input_state) return FALSE; @@ -302,6 +304,22 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) state->caps = gst_video_info_to_caps (vi); if (features) gst_caps_set_features (state->caps, 0, features); + + /* Allocation query is different from pad's caps */ + allocation_caps = NULL; + if (GST_VIDEO_INFO_WIDTH (decoded_info) != width + || GST_VIDEO_INFO_HEIGHT (decoded_info) != height) { + allocation_caps = gst_caps_copy (state->caps); + format_str = gst_video_format_to_string (format); + gst_caps_set_simple (allocation_caps, + "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH (decoded_info), + "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT (decoded_info), + "format", G_TYPE_STRING, format_str, NULL); + GST_INFO_OBJECT (decode, "new alloc caps = %" GST_PTR_FORMAT, + allocation_caps); + } + gst_caps_replace (&state->allocation_caps, allocation_caps); + GST_INFO_OBJECT (decode, "new src caps = %" GST_PTR_FORMAT, state->caps); gst_caps_replace (&decode->srcpad_caps, state->caps); gst_video_codec_state_unref (state); @@ -713,7 +731,6 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstCaps *caps = NULL; - gboolean ret = FALSE; gst_query_parse_allocation (query, &caps, NULL); decode->has_texture_upload_meta = FALSE; @@ -725,46 +742,8 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); #endif - if (decode->do_pool_renego) { - caps = gst_caps_copy (caps); - /* Always use un-cropped dimension of decoded surface for pool negotiation */ - gst_caps_set_simple (caps, "width", G_TYPE_INT, - GST_VIDEO_INFO_WIDTH (&decode->decoded_info), "height", G_TYPE_INT, - GST_VIDEO_INFO_HEIGHT (&decode->decoded_info), NULL); - - ret = - gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), - query, 0, caps); - - gst_caps_unref (caps); - decode->do_pool_renego = FALSE; - } else { - /* No need to renegotiate the pool, set the previously configured pool in query */ - guint size, min, max; - GstStructure *config; - GstVaapiPluginBase *plugin = GST_VAAPI_PLUGIN_BASE (vdec); - GstBufferPool *pool = plugin->srcpad_buffer_pool; - - if (G_UNLIKELY (!pool)) { - GST_ERROR ("Failed to find configured VaapiVideoBufferPool! "); - return ret; - } - - config = gst_buffer_pool_get_config (pool); - if (!config - || !gst_buffer_pool_config_get_params (config, NULL, &size, &min, &max)) - return ret; - gst_structure_free (config); - - if (gst_query_get_n_allocation_pools (query) > 0) - gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); - else - gst_query_add_allocation_pool (query, pool, size, min, max); - - ret = TRUE; - } - - return ret; + return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), + query, 0); } static inline gboolean diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index c2dc4c98ec..16cc449035 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -587,8 +587,6 @@ gst_vaapi_plugin_base_set_pool_config (GstBufferPool * pool, * @query: the allocation query to parse * @feature: the desired #GstVaapiCapsFeature, or zero to find the * preferred one - * @preferred_caps: the desired #GstCaps, or NULL to find the - * preferred one from query * * Decides allocation parameters for the downstream elements. * @@ -596,13 +594,12 @@ gst_vaapi_plugin_base_set_pool_config (GstBufferPool * pool, */ gboolean gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, - GstQuery * query, guint feature, GstCaps * preferred_caps) + GstQuery * query, guint feature) { GstCaps *caps = NULL; GstBufferPool *pool; GstStructure *config; GstVideoInfo vi; - GstQuery *old_query = NULL, *new_query = NULL; guint size, min, max; gboolean update_pool = FALSE; gboolean has_video_meta = FALSE; @@ -614,16 +611,6 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, g_return_val_if_fail (plugin->display != NULL, FALSE); - /* Make sure new caps get advertised to all downstream elements */ - if (preferred_caps) { - new_query = gst_query_new_allocation (preferred_caps, TRUE); - if (!gst_pad_peer_query (GST_VAAPI_PLUGIN_BASE_SRC_PAD (plugin), new_query)) { - GST_DEBUG ("didn't get downstream ALLOCATION hints"); - } - old_query = query; - query = new_query; - } - gst_query_parse_allocation (query, &caps, NULL); /* We don't need any GL context beyond this point if not requested @@ -671,7 +658,6 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gst_video_info_init (&vi); gst_video_info_from_caps (&vi, caps); - if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); @@ -731,11 +717,6 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, } #endif - if (old_query) - query = old_query; - if (new_query) - gst_query_unref (new_query); - if (update_pool) gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); else diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 5be15ae0c6..27c7491cb4 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -213,7 +213,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, - GstQuery * query, guint feature, GstCaps *preferred_caps); + GstQuery * query, guint feature); G_GNUC_INTERNAL GstFlowReturn diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 62deb0eb79..9d2dac7107 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1343,7 +1343,7 @@ static gboolean gst_vaapipostproc_decide_allocation (GstBaseTransform * trans, GstQuery * query) { return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (trans), - query, 0, NULL); + query, 0); } static void From 3478b27c926f28e2d225c7884f7d8f2988bb76a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 28 Mar 2016 15:30:28 +0200 Subject: [PATCH 2343/3781] vaapidecode: remove spurious class variables active, do_pool_renego and do_outstate_renego class variables were used to indicate when negotiate downstream once, but now that each time a new surface resolution is pop out a renegotation verified, these variable are not required anymore. https://bugzilla.gnome.org/show_bug.cgi?id=764316 --- gst/vaapi/gstvaapidecode.c | 22 +++++----------------- gst/vaapi/gstvaapidecode.h | 3 --- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4fba8fe9ba..f4430491be 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -179,8 +179,6 @@ gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, return; if (!gst_vaapidecode_update_sink_caps (decode, decode->input_state->caps)) return; - - decode->do_pool_renego = TRUE; } static GstVideoCodecState * @@ -339,7 +337,6 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) latency = gst_util_uint64_scale (2 * GST_SECOND, fps_d, fps_n); gst_video_decoder_set_latency (vdec, latency, latency); - decode->do_outstate_renego = FALSE; return TRUE; } @@ -457,6 +454,7 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, const GstVaapiRectangle *crop_rect; GstVaapiVideoMeta *meta; guint flags, out_flags = 0; + gboolean alloc_renegotiate, caps_renegotiate; if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) { proxy = gst_video_codec_frame_get_user_data (out_frame); @@ -471,21 +469,15 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, * we received notification from libgstvaapi, the frame we are going to * be pushed at this point might not have the notified resolution if there * are queued frames in decoded picture buffer. */ - decode->do_pool_renego = - is_surface_resolution_changed (decode, + alloc_renegotiate = is_surface_resolution_changed (decode, GST_VAAPI_SURFACE_PROXY_SURFACE (proxy)); + caps_renegotiate = is_display_resolution_changed (decode, crop_rect); - decode->do_outstate_renego = - is_display_resolution_changed (decode, crop_rect); - - if (G_UNLIKELY (!decode->active) || - gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec)) || - decode->do_outstate_renego || decode->do_pool_renego) { + if (gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec)) + || alloc_renegotiate || caps_renegotiate) { if (!gst_vaapidecode_negotiate (decode)) return GST_FLOW_ERROR; - - decode->active = TRUE; } gst_vaapi_surface_proxy_set_destroy_notify (proxy, @@ -887,8 +879,6 @@ gst_vaapidecode_destroy (GstVaapiDecode * decode) gst_vaapi_decoder_replace (&decode->decoder, NULL); gst_caps_replace (&decode->decoder_caps, NULL); - decode->active = FALSE; - gst_vaapidecode_release (gst_object_ref (decode)); } @@ -1282,8 +1272,6 @@ gst_vaapidecode_init (GstVaapiDecode * decode) decode->decoder = NULL; decode->decoder_caps = NULL; decode->allowed_caps = NULL; - decode->do_outstate_renego = TRUE; - decode->do_pool_renego = TRUE; g_mutex_init (&decode->surface_ready_mutex); g_cond_init (&decode->surface_ready); diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 7946bf8348..94d45e404d 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -52,9 +52,6 @@ struct _GstVaapiDecode { guint has_texture_upload_meta : 1; GstVideoCodecState *input_state; - volatile gboolean active; - volatile gboolean do_outstate_renego; - volatile gboolean do_pool_renego; }; struct _GstVaapiDecodeClass { From 80eb682b64db758d22e4adc66c5942e36a1a701d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 14 Apr 2016 16:10:02 +0200 Subject: [PATCH 2344/3781] vaapidecode: init {decoded,display}_info at open() It is required to initialize {decoded,display}_info variables when the decoder is open, not only at instance initialization. https://bugzilla.gnome.org/show_bug.cgi?id=764316 --- gst/vaapi/gstvaapidecode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f4430491be..f4b1ef7cab 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -927,6 +927,9 @@ gst_vaapidecode_open (GstVideoDecoder * vdec) if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (decode))) return FALSE; + gst_video_info_init (&decode->decoded_info); + gst_video_info_init (&decode->display_info); + /* Let GstVideoContext ask for a proper display to its neighbours */ /* Note: steal old display that may be allocated from get_caps() so that to retain a reference to it, thus avoiding extra @@ -1276,9 +1279,6 @@ gst_vaapidecode_init (GstVaapiDecode * decode) g_mutex_init (&decode->surface_ready_mutex); g_cond_init (&decode->surface_ready); - gst_video_info_init (&decode->decoded_info); - gst_video_info_init (&decode->display_info); - gst_video_decoder_set_packetized (vdec, FALSE); } From ade0c7bb43b87061393ee08cce9b06824339542a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 25 Mar 2016 15:31:28 +0100 Subject: [PATCH 2345/3781] vaapidecode: code style fixes No functional changes. https://bugzilla.gnome.org/show_bug.cgi?id=764316 --- gst/vaapi/gstvaapidecode.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f4b1ef7cab..facf825bca 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -287,8 +287,8 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) height = ref_state->info.height; } - state = gst_video_decoder_set_output_state (vdec, format, - width, height, ref_state); + state = gst_video_decoder_set_output_state (vdec, format, width, height, + ref_state); if (!state || state->info.width == 0 || state->info.height == 0) { if (features) gst_caps_features_free (features); @@ -450,6 +450,7 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstVaapiSurfaceProxy *proxy; + GstVaapiSurface *surface; GstFlowReturn ret; const GstVaapiRectangle *crop_rect; GstVaapiVideoMeta *meta; @@ -458,6 +459,7 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) { proxy = gst_video_codec_frame_get_user_data (out_frame); + surface = GST_VAAPI_SURFACE_PROXY_SURFACE (proxy); crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy); /* in theory, we are not supposed to check the surface resolution @@ -469,8 +471,7 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, * we received notification from libgstvaapi, the frame we are going to * be pushed at this point might not have the notified resolution if there * are queued frames in decoded picture buffer. */ - alloc_renegotiate = is_surface_resolution_changed (decode, - GST_VAAPI_SURFACE_PROXY_SURFACE (proxy)); + alloc_renegotiate = is_surface_resolution_changed (decode, surface); caps_renegotiate = is_display_resolution_changed (decode, crop_rect); if (gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec)) From 3e97d719358aaaec2616e16ddf7e6d36a7604f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 14 Apr 2016 16:22:25 +0200 Subject: [PATCH 2346/3781] vaapidecode: always a valid format in decoded_info Always set a valid format in decoded_info class variable. https://bugzilla.gnome.org/show_bug.cgi?id=764316 --- gst/vaapi/gstvaapidecode.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index facf825bca..83dd481897 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -355,7 +355,7 @@ is_surface_resolution_changed (GstVaapiDecode * decode, GstVaapiSurface * surface) { GstVideoInfo *vinfo = &decode->decoded_info; - GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; + GstVideoFormat surface_format; guint surface_width, surface_height; g_return_val_if_fail (surface != NULL, FALSE); @@ -366,14 +366,22 @@ is_surface_resolution_changed (GstVaapiDecode * decode, && GST_VIDEO_INFO_HEIGHT (vinfo) == surface_height) return FALSE; - /* doing gst_vaapi_surface_get_format() only if necessary since it execute - * vaDeriveImage in the backgrorund . This will usually get executed only once */ - format = - (GST_VIDEO_INFO_FORMAT (vinfo) == - GST_VIDEO_FORMAT_UNKNOWN) ? gst_vaapi_surface_get_format (surface) : - GST_VIDEO_INFO_FORMAT (vinfo); + /* doing gst_vaapi_surface_get_format() only if necessary since it + * execute vaDeriveImage in the background. This will usually get + * executed only once */ + surface_format = GST_VIDEO_INFO_FORMAT (vinfo); + if (surface_format == GST_VIDEO_FORMAT_UNKNOWN) { + surface_format = gst_vaapi_surface_get_format (surface); - gst_video_info_set_format (vinfo, format, surface_width, surface_height); + /* if the VA context delivers a currently unrecognized format + * (ICM3, e.g.), we can assume NV12 "safely" */ + if (surface_format == GST_VIDEO_FORMAT_UNKNOWN + || surface_format == GST_VIDEO_FORMAT_ENCODED) + surface_format = GST_VIDEO_FORMAT_NV12; + } + + gst_video_info_set_format (vinfo, surface_format, surface_width, + surface_height); return TRUE; } From 737fca4ddf8bcc4c15ae4a1fb278428686bec530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 14 Apr 2016 16:31:34 +0200 Subject: [PATCH 2347/3781] vaapidecode: decoded_info is valid at src caps update As decoded_info is assured to be valid when gst_vaapidecode_update_src_caps() is called, then we don't need to verify or replace it with the sinkpad info (reference state). https://bugzilla.gnome.org/show_bug.cgi?id=764316 --- gst/vaapi/gstvaapidecode.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 83dd481897..d01101a35b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -240,7 +240,7 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) GstVaapiCapsFeature feature; GstCapsFeatures *features = NULL; GstCaps *allocation_caps; - GstVideoInfo *vi, *decoded_info; + GstVideoInfo *vi; GstVideoFormat format = GST_VIDEO_FORMAT_NV12; GstClockTime latency; gint fps_d, fps_n; @@ -252,13 +252,9 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) ref_state = decode->input_state; - decoded_info = - (GST_VIDEO_INFO_FORMAT (&decode->decoded_info) != - GST_VIDEO_FORMAT_UNKNOWN) ? &decode->decoded_info : &ref_state->info; - feature = gst_vaapi_find_preferred_caps_feature (GST_VIDEO_DECODER_SRC_PAD (vdec), - GST_VIDEO_INFO_FORMAT (decoded_info), &format); + GST_VIDEO_INFO_FORMAT (&decode->decoded_info), &format); if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) return FALSE; @@ -305,13 +301,13 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) /* Allocation query is different from pad's caps */ allocation_caps = NULL; - if (GST_VIDEO_INFO_WIDTH (decoded_info) != width - || GST_VIDEO_INFO_HEIGHT (decoded_info) != height) { + if (GST_VIDEO_INFO_WIDTH (&decode->decoded_info) != width + || GST_VIDEO_INFO_HEIGHT (&decode->decoded_info) != height) { allocation_caps = gst_caps_copy (state->caps); format_str = gst_video_format_to_string (format); gst_caps_set_simple (allocation_caps, - "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH (decoded_info), - "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT (decoded_info), + "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH (&decode->decoded_info), + "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT (&decode->decoded_info), "format", G_TYPE_STRING, format_str, NULL); GST_INFO_OBJECT (decode, "new alloc caps = %" GST_PTR_FORMAT, allocation_caps); From 49a59f00eb0808bd4f6e503582a543ebff001d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 14 Apr 2016 16:43:07 +0200 Subject: [PATCH 2348/3781] vaapidecode: keep only display_{width,height} Instead of keeping the structure GstVideoInfo when we are using its width and height, we only keep these two guints. https://bugzilla.gnome.org/show_bug.cgi?id=764316 --- gst/vaapi/gstvaapidecode.c | 27 ++++++++++++--------------- gst/vaapi/gstvaapidecode.h | 4 +++- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d01101a35b..cdf5c15c51 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -275,8 +275,8 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) break; } - width = GST_VIDEO_INFO_WIDTH (&decode->display_info); - height = GST_VIDEO_INFO_HEIGHT (&decode->display_info); + width = decode->display_width; + height = decode->display_height; if (!width || !height) { width = ref_state->info.width; @@ -390,27 +390,23 @@ is_display_resolution_changed (GstVaapiDecode * decode, GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); GstVideoCodecState *state; GstVideoInfo *vinfo; - GstVideoFormat format = GST_VIDEO_INFO_FORMAT (&decode->decoded_info); - guint display_width = GST_VIDEO_INFO_WIDTH (&decode->decoded_info); - guint display_height = GST_VIDEO_INFO_HEIGHT (&decode->decoded_info); + guint display_width, display_height; + display_width = GST_VIDEO_INFO_WIDTH (&decode->decoded_info); + display_height = GST_VIDEO_INFO_HEIGHT (&decode->decoded_info); if (crop_rect) { display_width = crop_rect->width; display_height = crop_rect->height; } + state = gst_video_decoder_get_output_state (vdec); if (G_UNLIKELY (!state)) goto set_display_res; vinfo = &state->info; - format = GST_VIDEO_INFO_FORMAT (vinfo); - - if (GST_VIDEO_INFO_FORMAT (&decode->display_info) == GST_VIDEO_FORMAT_UNKNOWN) - decode->display_info = *vinfo; if (!crop_rect) { - if (G_UNLIKELY (display_width != - GST_VIDEO_INFO_WIDTH (&decode->display_info) - || display_height != GST_VIDEO_INFO_HEIGHT (&decode->display_info))) + if (G_UNLIKELY (display_width != decode->display_width + || display_height != decode->display_height)) goto set_display_res; } @@ -421,10 +417,10 @@ is_display_resolution_changed (GstVaapiDecode * decode, } set_display_res: - gst_video_info_set_format (&decode->display_info, format, display_width, - display_height); if (state) gst_video_codec_state_unref (state); + decode->display_width = display_width; + decode->display_height = display_height; return TRUE; } @@ -932,8 +928,9 @@ gst_vaapidecode_open (GstVideoDecoder * vdec) if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (decode))) return FALSE; + decode->display_width = 0; + decode->display_height = 0; gst_video_info_init (&decode->decoded_info); - gst_video_info_init (&decode->display_info); /* Let GstVideoContext ask for a proper display to its neighbours */ /* Note: steal old display that may be allocated from get_caps() diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 94d45e404d..9496e7da73 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -42,7 +42,6 @@ struct _GstVaapiDecode { GstCaps *sinkpad_caps; GstCaps *srcpad_caps; GstVideoInfo decoded_info; - GstVideoInfo display_info; GstVaapiDecoder *decoder; GMutex surface_ready_mutex; GCond surface_ready; @@ -51,6 +50,9 @@ struct _GstVaapiDecode { guint current_frame_size; guint has_texture_upload_meta : 1; + guint display_width; + guint display_height; + GstVideoCodecState *input_state; }; From aa168041218d2ac8890d96719b3c16c3ee898824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 14 Apr 2016 17:02:23 +0200 Subject: [PATCH 2349/3781] vaapidecode: refactor is_display_resolution_changed() Make the comparisons more readable and simple. https://bugzilla.gnome.org/show_bug.cgi?id=764316 --- gst/vaapi/gstvaapidecode.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index cdf5c15c51..6b904e41e7 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -389,8 +389,8 @@ is_display_resolution_changed (GstVaapiDecode * decode, { GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); GstVideoCodecState *state; - GstVideoInfo *vinfo; guint display_width, display_height; + guint negotiated_width, negotiated_height; display_width = GST_VIDEO_INFO_WIDTH (&decode->decoded_info); display_height = GST_VIDEO_INFO_HEIGHT (&decode->decoded_info); @@ -402,23 +402,17 @@ is_display_resolution_changed (GstVaapiDecode * decode, state = gst_video_decoder_get_output_state (vdec); if (G_UNLIKELY (!state)) goto set_display_res; - vinfo = &state->info; - if (!crop_rect) { - if (G_UNLIKELY (display_width != decode->display_width - || display_height != decode->display_height)) - goto set_display_res; - } + negotiated_width = GST_VIDEO_INFO_WIDTH (&state->info); + negotiated_height = GST_VIDEO_INFO_HEIGHT (&state->info); + gst_video_codec_state_unref (state); - if (GST_VIDEO_INFO_WIDTH (vinfo) == display_width - && GST_VIDEO_INFO_HEIGHT (vinfo) == display_height) { - gst_video_codec_state_unref (state); + if ((display_width == negotiated_width && display_height == negotiated_height) + && (decode->display_width == negotiated_width + && decode->display_height == negotiated_height)) return FALSE; - } set_display_res: - if (state) - gst_video_codec_state_unref (state); decode->display_width = display_width; decode->display_height = display_height; return TRUE; From 8c260701514ad3d5a7cf2952cd8a55f9f10f4ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 31 Mar 2016 16:39:08 +0200 Subject: [PATCH 2350/3781] vaapidecode: use macros for GstVideoInfo Instead of accessing directly to the members of the structure, use the macros. --- gst/vaapi/gstvaapidecode.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6b904e41e7..fd2ca111d7 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -279,13 +279,15 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) height = decode->display_height; if (!width || !height) { - width = ref_state->info.width; - height = ref_state->info.height; + width = GST_VIDEO_INFO_WIDTH (&ref_state->info); + height = GST_VIDEO_INFO_HEIGHT (&ref_state->info); } state = gst_video_decoder_set_output_state (vdec, format, width, height, ref_state); - if (!state || state->info.width == 0 || state->info.height == 0) { + if (!state + || GST_VIDEO_INFO_WIDTH (&state->info) == 0 + || GST_VIDEO_INFO_HEIGHT (&state->info) == 0) { if (features) gst_caps_features_free (features); if (state) From ce6275020e7c1ff7af646857933f93726b73053a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 28 Mar 2016 19:26:02 +0200 Subject: [PATCH 2351/3781] plugin: simplify caps feature selection This patch simplifies the function gst_vaapi_find_preferred_caps_feature(). Instead of intersecting custom caps to find the preferred feature, the peer caps are traversed in order to find the preferred feature, according to an ordered feature priority list. In the case of GLTextureUploadMeta, the colour format is computed using GstVideoInfo of the selected fixed caps. https://bugzilla.gnome.org/show_bug.cgi?id=765223 --- gst/vaapi/gstvaapipluginutil.c | 91 ++++++++++------------------------ 1 file changed, 27 insertions(+), 64 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index cc878e324d..c190affba9 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -432,55 +432,30 @@ gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, return caps; } -static GstCaps * -new_gl_texture_upload_meta_caps (void) -{ - return - gst_caps_from_string (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, - "{ RGBA, BGRA }")); -} - GstVaapiCapsFeature gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, GstVideoFormat * out_format_ptr) { - GstVaapiCapsFeature feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; - guint i, num_structures; + GstVaapiCapsFeature feature = GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED; + guint i, j, num_structures; GstCaps *caps = NULL; - GstCaps *gl_texture_upload_caps = NULL; - GstCaps *sysmem_caps = NULL; - GstCaps *vaapi_caps = NULL; GstCaps *out_caps, *templ; GstVideoFormat out_format; + static const guint feature_list[] = { GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE, + GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META, + GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY, + }; templ = gst_pad_get_pad_template_caps (pad); out_caps = gst_pad_peer_query_caps (pad, templ); gst_caps_unref (templ); - if (!out_caps) { - feature = GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED; + if (!out_caps) goto cleanup; - } out_format = format == GST_VIDEO_FORMAT_ENCODED ? GST_VIDEO_FORMAT_NV12 : format; - gl_texture_upload_caps = new_gl_texture_upload_meta_caps (); - if (!gl_texture_upload_caps) - goto cleanup; - - vaapi_caps = - gst_vaapi_video_format_new_template_caps_with_features (out_format, - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE); - if (!vaapi_caps) - goto cleanup; - - sysmem_caps = - gst_vaapi_video_format_new_template_caps_with_features (out_format, - GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY); - if (!sysmem_caps) - goto cleanup; - + feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; num_structures = gst_caps_get_size (out_caps); for (i = 0; i < num_structures; i++) { GstCapsFeatures *const features = gst_caps_get_features (out_caps, i); @@ -490,21 +465,19 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, if (gst_caps_features_is_any (features)) continue; + gst_caps_replace (&caps, NULL); caps = gst_caps_new_full (gst_structure_copy (structure), NULL); if (!caps) continue; gst_caps_set_features (caps, 0, gst_caps_features_copy (features)); - if (gst_caps_can_intersect (caps, vaapi_caps) && - feature < GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) - feature = GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE; - else if (gst_caps_can_intersect (caps, gl_texture_upload_caps) && - feature < GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) - feature = GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META; - else if (gst_caps_can_intersect (caps, sysmem_caps) && - feature < GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) - feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; - gst_caps_replace (&caps, NULL); + for (j = 0; j < G_N_ELEMENTS (feature_list); j++) { + if (gst_vaapi_caps_feature_contains (caps, feature_list[j]) + && feature < feature_list[j]) { + feature = feature_list[j]; + break; + } + } /* Stop at the first match, the caps should already be sorted out by preference order from downstream elements */ @@ -512,35 +485,25 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, break; } + if (!caps) + goto cleanup; + if (out_format_ptr) { if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) { - GstStructure *structure; - gchar *format_str; - out_format = GST_VIDEO_FORMAT_UNKNOWN; - do { - caps = gst_caps_intersect_full (out_caps, gl_texture_upload_caps, - GST_CAPS_INTERSECT_FIRST); - if (!caps) - break; - structure = gst_caps_get_structure (caps, 0); - if (!structure) - break; - if (!gst_structure_get (structure, "format", G_TYPE_STRING, - &format_str, NULL)) - break; - out_format = gst_video_format_from_string (format_str); - g_free (format_str); - } while (0); - if (!out_format) + GstVideoInfo vinfo; + if (!gst_caps_is_fixed (caps)) + caps = gst_caps_fixate (caps); + + gst_video_info_from_caps (&vinfo, caps); + out_format = GST_VIDEO_INFO_FORMAT (&vinfo); + + if (out_format == GST_VIDEO_FORMAT_UNKNOWN) goto cleanup; } *out_format_ptr = out_format; } cleanup: - gst_caps_replace (&gl_texture_upload_caps, NULL); - gst_caps_replace (&sysmem_caps, NULL); - gst_caps_replace (&vaapi_caps, NULL); gst_caps_replace (&caps, NULL); gst_caps_replace (&out_caps, NULL); return feature; From b41db95c4efd28d4a2a7937cc0e84e854c0e4d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 29 Mar 2016 13:28:27 +0200 Subject: [PATCH 2352/3781] plugin: honour negotiated format Instead of setting the requested format by the caller, the function gst_vaapi_find_preferred_caps_feature() now returns, in the output parameter, the negotiated format. A new helper function was added: gst_vaapi_find_preferred_format(), which, given the format list from the negotiated caps, will choose the best one, if possible, given the native format. https://bugzilla.gnome.org/show_bug.cgi?id=765223 --- gst/vaapi/gstvaapipluginutil.c | 78 ++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index c190affba9..f313d44ff5 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -432,6 +432,52 @@ gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, return caps; } +static GstVideoFormat +gst_vaapi_find_preferred_format (const GValue * format_list, + GstVideoFormat native_format) +{ + const GValue *frmt; + GstVideoFormat out_format; + guint i; + + /* if one format, that is the one */ + if (G_VALUE_HOLDS_STRING (format_list)) + return gst_video_format_from_string (g_value_get_string (format_list)); + + if (!GST_VALUE_HOLDS_LIST (format_list)) { + GST_ERROR ("negotiated caps do not have a valid format"); + return GST_VIDEO_FORMAT_UNKNOWN; + } + + if (native_format == GST_VIDEO_FORMAT_UNKNOWN + || native_format == GST_VIDEO_FORMAT_ENCODED) { + native_format = GST_VIDEO_FORMAT_NV12; /* default VA format */ + } + + /* search our native format in the list */ + for (i = 0; i < gst_value_list_get_size (format_list); i++) { + frmt = gst_value_list_get_value (format_list, i); + out_format = gst_video_format_from_string (g_value_get_string (frmt)); + + /* GStreamer do not handle encoded formats nicely. Try the next + * one. */ + if (out_format == GST_VIDEO_FORMAT_ENCODED) + continue; + + if (native_format == out_format) + return out_format; + } + + /* just pick the first valid format in the list */ + i = 0; + do { + frmt = gst_value_list_get_value (format_list, i++); + out_format = gst_video_format_from_string (g_value_get_string (frmt)); + } while (out_format == GST_VIDEO_FORMAT_ENCODED); + + return out_format; +} + GstVaapiCapsFeature gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, GstVideoFormat * out_format_ptr) @@ -440,7 +486,6 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, guint i, j, num_structures; GstCaps *caps = NULL; GstCaps *out_caps, *templ; - GstVideoFormat out_format; static const guint feature_list[] = { GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE, GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META, GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY, @@ -452,9 +497,6 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, if (!out_caps) goto cleanup; - out_format = format == GST_VIDEO_FORMAT_ENCODED ? - GST_VIDEO_FORMAT_NV12 : format; - feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; num_structures = gst_caps_get_size (out_caps); for (i = 0; i < num_structures; i++) { @@ -489,17 +531,27 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, goto cleanup; if (out_format_ptr) { - if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) { - GstVideoInfo vinfo; - if (!gst_caps_is_fixed (caps)) - caps = gst_caps_fixate (caps); + GstVideoFormat out_format; + GstStructure *structure; + const GValue *format_list; - gst_video_info_from_caps (&vinfo, caps); - out_format = GST_VIDEO_INFO_FORMAT (&vinfo); + /* if the best feature is SystemMemory, we should use the first + * caps in the peer caps set, which is the preferred by + * downstream. */ + if (feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) + gst_caps_replace (&caps, out_caps); + + /* use the first caps, which is the preferred by downstream. */ + structure = gst_caps_get_structure (caps, 0); + if (!structure) + goto cleanup; + format_list = gst_structure_get_value (structure, "format"); + if (!format_list) + goto cleanup; + out_format = gst_vaapi_find_preferred_format (format_list, format); + if (out_format == GST_VIDEO_FORMAT_UNKNOWN) + goto cleanup; - if (out_format == GST_VIDEO_FORMAT_UNKNOWN) - goto cleanup; - } *out_format_ptr = out_format; } From 79ec3d00ef9938b3799d3cb29983d703411467db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 18 Apr 2016 17:17:58 +0200 Subject: [PATCH 2353/3781] vaapidecode: warns if driver will do color conversions If the downstream feature is system memory, the surface has to be mapped, hence a warning message is logged saying that the driver has to do color conversions. This might be troublesome because not all the color conversion combinations are supported by the VA-API drivers, and there is not a reliable way to know them before hand. https://bugzilla.gnome.org/show_bug.cgi?id=765223 --- gst/vaapi/gstvaapidecode.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index fd2ca111d7..27ff0626eb 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -259,6 +259,14 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) return FALSE; + if ((feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY || + feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) + && format != GST_VIDEO_INFO_FORMAT (&decode->decoded_info)) { + GST_FIXME_OBJECT (decode, "validate if driver can convert from %s to %s", + gst_video_format_to_string (GST_VIDEO_INFO_FORMAT + (&decode->decoded_info)), gst_video_format_to_string (format)); + } + switch (feature) { #if (USE_GLX || USE_EGL) case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: From 2d7d38cb9c4ec3e61aaa83d92103b95d0cf380d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 18 Apr 2016 17:28:51 +0200 Subject: [PATCH 2354/3781] plugin: remove function parameter The native format parameter in gst_vaapi_find_preferred_caps_feature() can be saved if the out format is used for both: in and out. Thus the code is more readable. https://bugzilla.gnome.org/show_bug.cgi?id=765223 --- gst/vaapi/gstvaapidecode.c | 5 +++-- gst/vaapi/gstvaapipluginbase.c | 4 +--- gst/vaapi/gstvaapipluginutil.c | 4 ++-- gst/vaapi/gstvaapipluginutil.h | 2 +- gst/vaapi/gstvaapipostproc.c | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 27ff0626eb..6bf21268e4 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -241,7 +241,7 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) GstCapsFeatures *features = NULL; GstCaps *allocation_caps; GstVideoInfo *vi; - GstVideoFormat format = GST_VIDEO_FORMAT_NV12; + GstVideoFormat format; GstClockTime latency; gint fps_d, fps_n; guint width, height; @@ -252,9 +252,10 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) ref_state = decode->input_state; + format = GST_VIDEO_INFO_FORMAT (&decode->decoded_info); feature = gst_vaapi_find_preferred_caps_feature (GST_VIDEO_DECODER_SRC_PAD (vdec), - GST_VIDEO_INFO_FORMAT (&decode->decoded_info), &format); + &format); if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) return FALSE; diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 16cc449035..5b80a9c51c 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -621,9 +621,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, goto error_no_caps; if (!feature) - feature = - gst_vaapi_find_preferred_caps_feature (plugin->srcpad, - GST_VIDEO_FORMAT_ENCODED, NULL); + feature = gst_vaapi_find_preferred_caps_feature (plugin->srcpad, NULL); has_video_meta = gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index f313d44ff5..50240cb5d8 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -479,7 +479,7 @@ gst_vaapi_find_preferred_format (const GValue * format_list, } GstVaapiCapsFeature -gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, +gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat * out_format_ptr) { GstVaapiCapsFeature feature = GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED; @@ -548,7 +548,7 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, format_list = gst_structure_get_value (structure, "format"); if (!format_list) goto cleanup; - out_format = gst_vaapi_find_preferred_format (format_list, format); + out_format = gst_vaapi_find_preferred_format (format_list, *out_format_ptr); if (out_format == GST_VIDEO_FORMAT_UNKNOWN) goto cleanup; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 0e62b1f0a9..f1244033c2 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -84,7 +84,7 @@ gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, G_GNUC_INTERNAL GstVaapiCapsFeature -gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat format, +gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstVideoFormat * out_format_ptr); G_GNUC_INTERNAL diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 9d2dac7107..9f066e46cc 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1125,7 +1125,7 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, feature = gst_vaapi_find_preferred_caps_feature (GST_BASE_TRANSFORM_SRC_PAD (trans), - out_format, &out_format); + &out_format); gst_video_info_change_format (&vi, out_format, width, height); out_caps = gst_video_info_to_caps (&vi); From 8d42c95b0f706a1bf1649bfafef607fc951e5027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 29 Mar 2016 14:17:54 +0200 Subject: [PATCH 2355/3781] plugin: use allowed caps filter from element Instead of using the srcpad template caps for filtering the peer caps, the function gst_vaapi_find_preferred_caps_feature(), now receives a new parameter for the element's allowed caps. With this modification, the vaapipostproc element simplifies a bit its code. https://bugzilla.gnome.org/show_bug.cgi?id=765223 --- gst/vaapi/gstvaapidecode.c | 8 +++++--- gst/vaapi/gstvaapipluginbase.c | 3 ++- gst/vaapi/gstvaapipluginutil.c | 12 ++++++------ gst/vaapi/gstvaapipluginutil.h | 2 +- gst/vaapi/gstvaapipostproc.c | 25 ++++++++----------------- 5 files changed, 22 insertions(+), 28 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6bf21268e4..7857a0a09a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -236,6 +236,8 @@ static gboolean gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) { GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); + GstPad *const srcpad = GST_VIDEO_DECODER_SRC_PAD (vdec); + GstCaps *templ; GstVideoCodecState *state, *ref_state; GstVaapiCapsFeature feature; GstCapsFeatures *features = NULL; @@ -253,9 +255,9 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) ref_state = decode->input_state; format = GST_VIDEO_INFO_FORMAT (&decode->decoded_info); - feature = - gst_vaapi_find_preferred_caps_feature (GST_VIDEO_DECODER_SRC_PAD (vdec), - &format); + templ = gst_pad_get_pad_template_caps (srcpad); + feature = gst_vaapi_find_preferred_caps_feature (srcpad, templ, &format); + gst_caps_unref (templ); if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) return FALSE; diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 5b80a9c51c..34138b293b 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -621,7 +621,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, goto error_no_caps; if (!feature) - feature = gst_vaapi_find_preferred_caps_feature (plugin->srcpad, NULL); + feature = gst_vaapi_find_preferred_caps_feature (plugin->srcpad, caps, + NULL); has_video_meta = gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 50240cb5d8..f774916d5d 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -479,24 +479,24 @@ gst_vaapi_find_preferred_format (const GValue * format_list, } GstVaapiCapsFeature -gst_vaapi_find_preferred_caps_feature (GstPad * pad, +gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstCaps * allowed_caps, GstVideoFormat * out_format_ptr) { GstVaapiCapsFeature feature = GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED; guint i, j, num_structures; - GstCaps *caps = NULL; - GstCaps *out_caps, *templ; + GstCaps *out_caps, *caps = NULL; static const guint feature_list[] = { GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE, GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META, GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY, }; - templ = gst_pad_get_pad_template_caps (pad); - out_caps = gst_pad_peer_query_caps (pad, templ); - gst_caps_unref (templ); + out_caps = gst_pad_peer_query_caps (pad, allowed_caps); if (!out_caps) goto cleanup; + if (gst_caps_is_any (out_caps) || gst_caps_is_empty (out_caps)) + goto cleanup; + feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; num_structures = gst_caps_get_size (out_caps); for (i = 0; i < num_structures; i++) { diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index f1244033c2..1589638d76 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -84,7 +84,7 @@ gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format, G_GNUC_INTERNAL GstVaapiCapsFeature -gst_vaapi_find_preferred_caps_feature (GstPad * pad, +gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstCaps * allowed_caps, GstVideoFormat * out_format_ptr); G_GNUC_INTERNAL diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 9f066e46cc..53b2b70a79 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1105,29 +1105,20 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, * if the user didn't explicitly ask for colorspace conversion. * Use a filter caps which contain all raw video formats, (excluding * GST_VIDEO_FORMAT_ENCODED) */ + out_format = GST_VIDEO_FORMAT_UNKNOWN; if (postproc->format != DEFAULT_FORMAT) out_format = postproc->format; - else { - GstCaps *peer_caps; - GstVideoInfo peer_vi; - peer_caps = - gst_pad_peer_query_caps (GST_BASE_TRANSFORM_SRC_PAD (trans), - postproc->allowed_srcpad_caps); - if (gst_caps_is_any (peer_caps) || gst_caps_is_empty (peer_caps)) - return peer_caps; - if (!gst_caps_is_fixed (peer_caps)) - peer_caps = gst_caps_fixate (peer_caps); - gst_video_info_from_caps (&peer_vi, peer_caps); - out_format = GST_VIDEO_INFO_FORMAT (&peer_vi); - if (peer_caps) - gst_caps_unref (peer_caps); - } feature = gst_vaapi_find_preferred_caps_feature (GST_BASE_TRANSFORM_SRC_PAD (trans), - &out_format); - gst_video_info_change_format (&vi, out_format, width, height); + postproc->allowed_srcpad_caps, + (out_format == GST_VIDEO_FORMAT_UNKNOWN) ? &out_format : NULL); + if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) + return gst_pad_peer_query_caps (GST_BASE_TRANSFORM_SRC_PAD (trans), + postproc->allowed_srcpad_caps); + + gst_video_info_change_format (&vi, out_format, width, height); out_caps = gst_video_info_to_caps (&vi); if (!out_caps) return NULL; From 7f0bf0872819467804d9add28578c570383efcbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Mar 2016 16:42:04 +0100 Subject: [PATCH 2356/3781] vaapidecode: bail early if not caps in decide_allocation() --- gst/vaapi/gstvaapidecode.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 7857a0a09a..1d8e6f9cad 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -733,7 +733,12 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) GstCaps *caps = NULL; gst_query_parse_allocation (query, &caps, NULL); + decode->has_texture_upload_meta = FALSE; + + if (!caps) + goto error_no_caps; + #if (USE_GLX || USE_EGL) decode->has_texture_upload_meta = gst_query_find_allocation_meta (query, @@ -744,6 +749,13 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), query, 0); + + /* ERRORS */ +error_no_caps: + { + GST_ERROR_OBJECT (decode, "no caps specified"); + return FALSE; + } } static inline gboolean From c5c60e2a33c89f8a825c108e8e005e34113fa850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Mar 2016 16:43:16 +0100 Subject: [PATCH 2357/3781] plugins: remove param in gst_vaapi_plugin_base_decide_allocation() --- gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapipluginbase.c | 9 +++------ gst/vaapi/gstvaapipluginbase.h | 2 +- gst/vaapi/gstvaapipostproc.c | 2 +- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1d8e6f9cad..5d73ae6eff 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -748,7 +748,7 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) #endif return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), - query, 0); + query); /* ERRORS */ error_no_caps: diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 34138b293b..055bf7e3cc 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -594,7 +594,7 @@ gst_vaapi_plugin_base_set_pool_config (GstBufferPool * pool, */ gboolean gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, - GstQuery * query, guint feature) + GstQuery * query) { GstCaps *caps = NULL; GstBufferPool *pool; @@ -620,17 +620,14 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!caps) goto error_no_caps; - if (!feature) - feature = gst_vaapi_find_preferred_caps_feature (plugin->srcpad, caps, - NULL); - has_video_meta = gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); #if (USE_GLX || USE_EGL) has_texture_upload_meta = gst_query_find_allocation_meta (query, GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx) && - (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); + gst_vaapi_caps_feature_contains (caps, + GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); #if USE_GST_GL_HELPERS if (has_texture_upload_meta) { diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 27c7491cb4..ce76d519fc 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -213,7 +213,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, - GstQuery * query, guint feature); + GstQuery * query); G_GNUC_INTERNAL GstFlowReturn diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 53b2b70a79..a567b0b344 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1334,7 +1334,7 @@ static gboolean gst_vaapipostproc_decide_allocation (GstBaseTransform * trans, GstQuery * query) { return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (trans), - query, 0); + query); } static void From 3531dfa35eec482098c17f3124b8d36ad33029c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 5 Apr 2016 13:07:14 +0200 Subject: [PATCH 2358/3781] vaapidecode: caps negotiation checks Check that GLUploadTexture is not negotatiated if gstreamer-vaapi is not compiled with GL support. --- gst/vaapi/gstvaapidecode.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 5d73ae6eff..a9603babc8 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -262,6 +262,12 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) return FALSE; +#if (!USE_GLX && !USE_EGL) + /* This is a very pathological situation. Should not happen. */ + if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) + return FALSE; +#endif + if ((feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY || feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) && format != GST_VIDEO_INFO_FORMAT (&decode->decoded_info)) { @@ -271,13 +277,11 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) } switch (feature) { -#if (USE_GLX || USE_EGL) case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: features = gst_caps_features_new (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); break; -#endif case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE: features = gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL); From eb911e9eabb646a35f73be094fa2f94ddf8bf53a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 5 Apr 2016 13:37:40 +0200 Subject: [PATCH 2359/3781] vaapidecode: move GstCapsFeatures near to its use Move the handling of the GstCapsFeatures just after it is used, in order to avoid handling its memory. --- gst/vaapi/gstvaapidecode.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a9603babc8..0559e75dd9 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -240,14 +240,14 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) GstCaps *templ; GstVideoCodecState *state, *ref_state; GstVaapiCapsFeature feature; - GstCapsFeatures *features = NULL; + GstCapsFeatures *features; GstCaps *allocation_caps; GstVideoInfo *vi; GstVideoFormat format; GstClockTime latency; gint fps_d, fps_n; guint width, height; - const gchar *format_str; + const gchar *format_str, *feature_str; if (!decode->input_state) return FALSE; @@ -276,20 +276,6 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) (&decode->decoded_info)), gst_video_format_to_string (format)); } - switch (feature) { - case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: - features = - gst_caps_features_new - (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); - break; - case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE: - features = - gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL); - break; - default: - break; - } - width = decode->display_width; height = decode->display_height; @@ -303,18 +289,25 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) if (!state || GST_VIDEO_INFO_WIDTH (&state->info) == 0 || GST_VIDEO_INFO_HEIGHT (&state->info) == 0) { - if (features) - gst_caps_features_free (features); if (state) gst_video_codec_state_unref (state); return FALSE; } vi = &state->info; - state->caps = gst_video_info_to_caps (vi); - if (features) - gst_caps_set_features (state->caps, 0, features); + + switch (feature) { + case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: + case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE:{ + feature_str = gst_vaapi_caps_feature_to_string (feature); + features = gst_caps_features_new (feature_str, NULL); + gst_caps_set_features (state->caps, 0, features); + break; + } + default: + break; + } /* Allocation query is different from pad's caps */ allocation_caps = NULL; From 23a9a7291a88e868ff77f881a3e9b2f8d0ae8abd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 5 Apr 2016 13:09:37 +0200 Subject: [PATCH 2360/3781] vaapidecode: improve code readability No functional changes. --- gst/vaapi/gstvaapidecode.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 0559e75dd9..8dfb133e08 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -286,11 +286,12 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) state = gst_video_decoder_set_output_state (vdec, format, width, height, ref_state); - if (!state - || GST_VIDEO_INFO_WIDTH (&state->info) == 0 + if (!state) + return FALSE; + + if (GST_VIDEO_INFO_WIDTH (&state->info) == 0 || GST_VIDEO_INFO_HEIGHT (&state->info) == 0) { - if (state) - gst_video_codec_state_unref (state); + gst_video_codec_state_unref (state); return FALSE; } From e519f2ea79c4bc174c9bd495d86acaf749933705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 15 Apr 2016 17:57:25 +0200 Subject: [PATCH 2361/3781] vaapipostproc: resize if negotiated and allocation caps are different Since commit 859a2b2, in vaapidecode, allocation query can be different from the negotiated caps. When connecting the vaapidecoder to the vaapipostprocessor, the last one will resize the frame to the negotiated, if and only if, some other parameter is activated to avoid the passthrough. If it is not, the surface won't be mapped into a image. If not, the image won't be resized and the output buffer would be mapped. This patch will break the passthrough if the allocation query is different from the negotiation caps, forcing the resizing. https://bugzilla.gnome.org/show_bug.cgi?id=765095 --- gst/vaapi/gstvaapipostproc.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index a567b0b344..0aecace810 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1321,7 +1321,33 @@ gst_vaapipostproc_propose_allocation (GstBaseTransform * trans, { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (trans); + GstCaps *allocation_caps; + GstStructure *structure; + gint allocation_width, allocation_height; + gint negotiated_width, negotiated_height; + negotiated_width = GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info); + negotiated_height = GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info); + + if (negotiated_width == 0 || negotiated_height == 0) + goto bail; + + allocation_caps = NULL; + gst_query_parse_allocation (query, &allocation_caps, NULL); + if (!allocation_caps) + goto bail; + + structure = gst_caps_get_structure (allocation_caps, 0); + if (!gst_structure_get_int (structure, "width", &allocation_width)) + goto bail; + if (!gst_structure_get_int (structure, "height", &allocation_height)) + goto bail; + + if (allocation_width != negotiated_width + || allocation_height != negotiated_height) + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SIZE; + +bail: /* Let vaapidecode allocate the video buffers */ if (postproc->get_va_surfaces) return FALSE; From bccdda84b73653c96672161905ba60a9ed9b6557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 21 Apr 2016 12:57:30 +0200 Subject: [PATCH 2362/3781] plugins: rework set_context() vmethod definition In bug 757598 was added the set_context() vmethod chain up in GstVaapiPluginBase. But it is buggy, since the parent_class address is assigned to the last element which called gst_vaapi_plugin_base_class_init(). No error has shown up since none of the element's base classes redefined set_context() vmethod from GstElement, so always the correct function was called. Still this code is wrong and this patch make it right. Since set_context() is the same code, a macro is used to implement that code in all the gst-vaapi elements. https://bugzilla.gnome.org/show_bug.cgi?id=765368 --- gst/vaapi/gstvaapidecode.c | 2 ++ gst/vaapi/gstvaapiencode.c | 3 +++ gst/vaapi/gstvaapipluginbase.c | 29 ++++++++++++++--------------- gst/vaapi/gstvaapipluginbase.h | 15 +++++++++++++++ gst/vaapi/gstvaapipostproc.c | 3 +++ gst/vaapi/gstvaapisink.c | 3 +++ 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 8dfb133e08..6b24c2d326 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -160,6 +160,7 @@ static const GstVaapiDecoderMap vaapi_decode_map[] = { }; static GstElementClass *parent_class = NULL; +GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT (parent_class); static gboolean gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps); @@ -1263,6 +1264,7 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) longname = g_strdup ("VA-API decoder"); } + element_class->set_context = gst_vaapi_base_set_context; gst_element_class_set_static_metadata (element_class, longname, "Codec/Decoder/Video", GST_PLUGIN_DESC, "Gwenole Beauchesne , " diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 78ab5521d3..9d79fd10af 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -44,6 +44,8 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstVaapiEncode, gst_vaapiencode, GST_TYPE_VIDEO_ENCODER, GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES); +GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT (gst_vaapiencode_parent_class); + enum { PROP_0, @@ -629,6 +631,7 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) object_class->finalize = gst_vaapiencode_finalize; + element_class->set_context = gst_vaapi_base_set_context; element_class->change_state = GST_DEBUG_FUNCPTR (gst_vaapiencode_change_state); diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 055bf7e3cc..e762e1eec6 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -35,8 +35,6 @@ /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) -static gpointer plugin_parent_class = NULL; - /* GstVideoContext interface */ static void plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) @@ -57,18 +55,25 @@ plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) gst_vaapi_display_unref (display); } -static void -plugin_set_context (GstElement * element, GstContext * context) +/** + * gst_vaapi_plugin_base_set_context: + * @plugin: a #GstVaapiPluginBase instance + * @context: a #GstContext to set + * + * This is a common set_context() element's vmethod for all the + * GStreamer VA-API elements. + * + * It normally should be used through the macro + * #GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT() + **/ +void +gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, + GstContext * context) { - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); - GstElementClass *element_class = GST_ELEMENT_CLASS (plugin_parent_class); GstVaapiDisplay *display = NULL; if (gst_vaapi_video_context_get_display (context, &display)) plugin_set_display (plugin, display); - - if (element_class->set_context) - element_class->set_context (element, context); } void @@ -180,14 +185,8 @@ error_create_proxy: void gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) { - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - klass->has_interface = default_has_interface; klass->display_changed = default_display_changed; - - plugin_parent_class = g_type_class_peek_parent (klass); - - element_class->set_context = GST_DEBUG_FUNCPTR (plugin_set_context); } void diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index ce76d519fc..d51a5dc850 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -102,6 +102,16 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (gst_vaapi_display_replace(&GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin), \ (new_display))) +#define GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT(parent_class) \ + static void \ + gst_vaapi_base_set_context (GstElement * element, GstContext * context) \ + { \ + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); \ + \ + gst_vaapi_plugin_base_set_context (plugin, context); \ + GST_ELEMENT_CLASS (parent_class)->set_context (element, context); \ + } + struct _GstVaapiPluginBase { /*< private >*/ @@ -220,6 +230,11 @@ GstFlowReturn gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, GstBuffer * inbuf, GstBuffer ** outbuf_ptr); +G_GNUC_INTERNAL +void +gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, + GstContext * context); + G_GNUC_INTERNAL void gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 0aecace810..a5f8a3304f 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -96,6 +96,8 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiPostproc, gst_vaapipostproc, G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE, gst_vaapipostproc_colorbalance_init)); +GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT (gst_vaapipostproc_parent_class); + static GstVideoFormat native_formats[] = { GST_VIDEO_FORMAT_NV12, GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_I420 }; @@ -1522,6 +1524,7 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) trans_class->prepare_output_buffer = gst_vaapipostproc_prepare_output_buffer; + element_class->set_context = gst_vaapi_base_set_context; gst_element_class_set_static_metadata (element_class, "VA-API video postprocessing", "Filter/Converter/Video;Filter/Converter/Video/Scaler;" diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 8d7b6e0ca4..c7b0ca0a01 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -107,6 +107,8 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiSink, G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION, gst_vaapisink_navigation_iface_init)); +GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT (gst_vaapisink_parent_class); + enum { HANDOFF_SIGNAL, @@ -1663,6 +1665,7 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_vaapisink_show_frame); + element_class->set_context = gst_vaapi_base_set_context; element_class->set_bus = gst_vaapisink_set_bus; gst_element_class_set_static_metadata (element_class, "VA-API sink", "Sink/Video", GST_PLUGIN_DESC, From 53851b0e73a15071a08763d9219540432f0bddbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 21 Apr 2016 15:14:47 +0200 Subject: [PATCH 2363/3781] vaapidecode: search driver in whitelist If the backend driver vendor string is not in a white-list, and the environment variable GST_VAAPI_ALL_DRIVERS is not set either, the decoder will change it state from NULL to READY, hence the auto-plug mechanism will look for another decoder. This patch assumes the GstContext has already being shared along the pipeline and the element has a valid GstVaapiDisplay instance. https://bugzilla.gnome.org/show_bug.cgi?id=764673 --- gst/vaapi/gstvaapidecode.c | 3 +- gst/vaapi/gstvaapipluginbase.c | 54 ++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginbase.h | 33 +++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6b24c2d326..c8274829b3 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -160,7 +160,7 @@ static const GstVaapiDecoderMap vaapi_decode_map[] = { }; static GstElementClass *parent_class = NULL; -GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT (parent_class); +GST_VAAPI_PLUGIN_BASE_DEFINE_VMETHODS (parent_class); static gboolean gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps); @@ -1265,6 +1265,7 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) } element_class->set_context = gst_vaapi_base_set_context; + element_class->change_state = GST_DEBUG_FUNCPTR (gst_vaapi_base_change_state); gst_element_class_set_static_metadata (element_class, longname, "Codec/Decoder/Video", GST_PLUGIN_DESC, "Gwenole Beauchesne , " diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e762e1eec6..2863589fbf 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -35,6 +35,9 @@ /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) +/* Environment variable for disable driver white-list */ +#define GST_VAAPI_ALL_DRIVERS_ENV "GST_VAAPI_ALL_DRIVERS" + /* GstVideoContext interface */ static void plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) @@ -76,6 +79,57 @@ gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, plugin_set_display (plugin, display); } +/** + * gst_vaapi_plugin_base_driver_is_whitelisted: + * @plugin: a #GstVaapiPluginBase instance + * + * Looks the VA-API driver vendors in an internal white-list. + * + * Returns: %TRUE if driver is in the white-list, otherwise %FALSE + **/ +gboolean +gst_vaapi_plugin_base_driver_is_whitelisted (GstVaapiPluginBase * plugin) +{ + const gchar *vendor; + guint i; + GstVaapiDisplay *display; + static const gchar *whitelist[] = { + "Intel i965 driver", + "mesa gallium vaapi", + NULL + }; + + if (g_getenv (GST_VAAPI_ALL_DRIVERS_ENV)) + return TRUE; + + display = GST_VAAPI_PLUGIN_BASE_DISPLAY (plugin); + if (!display) + goto no_display; + vendor = gst_vaapi_display_get_vendor_string (display); + if (!vendor) + goto no_vendor; + for (i = 0; whitelist[i]; i++) { + if (g_ascii_strncasecmp (vendor, whitelist[i], strlen (whitelist[i])) == 0) + return TRUE; + } + + GST_ERROR ("Unsupported VA driver: %s. Export environment variable " + GST_VAAPI_ALL_DRIVERS_ENV " to bypass", vendor); + return FALSE; + + /* ERRORS */ +no_display: + { + GST_WARNING_OBJECT (plugin, "no VA-API display available"); + return FALSE; + } +no_vendor: + { + GST_WARNING_OBJECT (plugin, "no VA-API driver vendor description"); + return FALSE; + } +} + void gst_vaapi_plugin_base_init_interfaces (GType g_define_type_id) { diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index d51a5dc850..0694bf74c7 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -102,6 +102,10 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (gst_vaapi_display_replace(&GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin), \ (new_display))) +#define GST_VAAPI_PLUGIN_BASE_DEFINE_VMETHODS(parent_class) \ + GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT(parent_class) \ + GST_VAAPI_PLUGIN_BASE_DEFINE_CHANGE_STATE(parent_class) + #define GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT(parent_class) \ static void \ gst_vaapi_base_set_context (GstElement * element, GstContext * context) \ @@ -112,6 +116,31 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; GST_ELEMENT_CLASS (parent_class)->set_context (element, context); \ } +#define GST_VAAPI_PLUGIN_BASE_DEFINE_CHANGE_STATE(parent_class) \ + static GstStateChangeReturn \ + gst_vaapi_base_change_state (GstElement * element, \ + GstStateChange transition) \ + { \ + GstStateChangeReturn ret; \ + \ + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, \ + transition); \ + if (ret == GST_STATE_CHANGE_FAILURE) \ + return ret; \ + \ + switch (transition) { \ + case GST_STATE_CHANGE_NULL_TO_READY:{ \ + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); \ + if (!gst_vaapi_plugin_base_driver_is_whitelisted (plugin)) \ + ret = GST_STATE_CHANGE_FAILURE; \ + break; \ + } \ + default: \ + break; \ + } \ + return ret; \ + } + struct _GstVaapiPluginBase { /*< private >*/ @@ -230,6 +259,10 @@ GstFlowReturn gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, GstBuffer * inbuf, GstBuffer ** outbuf_ptr); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_driver_is_whitelisted (GstVaapiPluginBase * plugin); + G_GNUC_INTERNAL void gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, From 8a443f0a188fcf0d638c29b3c13928325dfde960 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Fri, 11 Mar 2016 08:58:51 +0000 Subject: [PATCH 2364/3781] various gst-indent --- gst/vaapi/gstvaapipostproc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index a5f8a3304f..a2c033c9a7 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1298,8 +1298,8 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, } static gboolean -gst_vaapipostproc_query (GstBaseTransform * trans, GstPadDirection direction, - GstQuery * query) +gst_vaapipostproc_query (GstBaseTransform * trans, + GstPadDirection direction, GstQuery * query) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); @@ -1793,10 +1793,11 @@ typedef struct } ColorBalanceChannel; ColorBalanceChannel cb_channels[] = { - {GST_VAAPI_FILTER_OP_HUE, "VA_FILTER_HUE"}, - {GST_VAAPI_FILTER_OP_SATURATION, "VA_FILTER_SATURATION"}, - {GST_VAAPI_FILTER_OP_BRIGHTNESS, "VA_FILTER_BRIGHTNESS"}, - {GST_VAAPI_FILTER_OP_CONTRAST, "VA_FILTER_CONTRAST"}, + { + GST_VAAPI_FILTER_OP_HUE, "VA_FILTER_HUE"}, { + GST_VAAPI_FILTER_OP_SATURATION, "VA_FILTER_SATURATION"}, { + GST_VAAPI_FILTER_OP_BRIGHTNESS, "VA_FILTER_BRIGHTNESS"}, { + GST_VAAPI_FILTER_OP_CONTRAST, "VA_FILTER_CONTRAST"}, }; static void @@ -1846,8 +1847,8 @@ gst_vaapipostproc_colorbalance_list_channels (GstColorBalance * balance) } static gfloat * -cb_get_value_ptr (GstVaapiPostproc * postproc, GstColorBalanceChannel * channel, - GstVaapiPostprocFlags * flags) +cb_get_value_ptr (GstVaapiPostproc * postproc, + GstColorBalanceChannel * channel, GstVaapiPostprocFlags * flags) { guint i; gfloat *ret = NULL; From 910bacc55ccadf2ea4fa7ecf5c3e53c9eee7db3b Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Sat, 26 Sep 2015 06:25:12 +0100 Subject: [PATCH 2365/3781] vaapipostproc: already have a surface proxy if dmabuf https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapipostproc.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index a2c033c9a7..4757d8325c 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -647,13 +647,15 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, if (!outbuf_meta) goto error_create_meta; - proxy = - gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL - (postproc->filter_pool)); - if (!proxy) - goto error_create_proxy; - gst_vaapi_video_meta_set_surface_proxy (outbuf_meta, proxy); - gst_vaapi_surface_proxy_unref (proxy); + if (!gst_vaapi_video_meta_get_surface_proxy (outbuf_meta)) { + proxy = + gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL + (postproc->filter_pool)); + if (!proxy) + goto error_create_proxy; + gst_vaapi_video_meta_set_surface_proxy (outbuf_meta, proxy); + gst_vaapi_surface_proxy_unref (proxy); + } if (deint) { deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD); From 1dbcc8a0e199f2da6a0ab8e949f13341916128a3 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Sun, 4 Oct 2015 23:44:16 +0100 Subject: [PATCH 2366/3781] gstvaapisurface_drm: release image when done Otherwise intel-vaapi-driver will fail to process the exported surface because it will find it is currently derived, so considered as busy. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index 1a2ba20d28..426019a35a 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -36,11 +36,20 @@ gst_vaapi_surface_get_drm_buf_handle (GstVaapiSurface * surface, guint type) if (!image) goto error_derive_image; + if (type == GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF) + proxy = + gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), + image->internal_image.buf, type, NULL, NULL); + else proxy = gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), image->internal_image.buf, type, gst_vaapi_object_unref, image); if (!proxy) goto error_alloc_export_buffer; + + if (type == GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF) + gst_vaapi_object_unref (image); + return proxy; /* ERRORS */ From 8e7ebaa505a4a6554549d47c454d17a2eb31269a Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Fri, 27 Nov 2015 05:09:10 +0000 Subject: [PATCH 2367/3781] gstvaapisurface: explicitely clear TILING flag if dmabuf https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst-libs/gst/vaapi/gstvaapisurface.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index cefb2a6ace..07f8a29270 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -159,7 +159,10 @@ gst_vaapi_surface_create_full (GstVaapiSurface * surface, extbuf.pixel_format = va_format->fourcc; extbuf.width = GST_VIDEO_INFO_WIDTH (vip); extbuf.height = GST_VIDEO_INFO_HEIGHT (vip); - extbuf_needed = ! !(flags & GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); + if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE) { + extbuf.flags &= ~VA_SURFACE_EXTBUF_DESC_ENABLE_TILING; + extbuf_needed = TRUE; + } extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vip); if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) { From 7ddc7ea0bcb051685de8478abf6daa317774fb2d Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 27 Apr 2016 17:06:09 +0300 Subject: [PATCH 2368/3781] encoder: h265: Add CBR Encoding support https://bugzilla.gnome.org/show_bug.cgi?id=749852 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 165 ++++++++++++++++++++-- 1 file changed, 152 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 9d3f0b7831..4f1db1d1b4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -45,12 +45,22 @@ /* Define the maximum IDR period */ #define MAX_IDR_PERIOD 512 +/* Default CPB length (in milliseconds) */ +#define DEFAULT_CPB_LENGTH 1500 + +/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ +#define SX_BITRATE 6 + +/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */ +#define SX_CPB_SIZE 4 + /* 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 (CQP)) | \ + GST_VAAPI_RATECONTROL_MASK (CBR) /* Supported set of tuning options, within this implementation */ #define SUPPORTED_TUNE_OPTIONS \ @@ -137,6 +147,8 @@ struct _GstVaapiEncoderH265 GstBuffer *pps_data; guint bitrate_bits; // bitrate (bits) + guint cpb_length; // length of CPB buffer (ms) + guint cpb_length_bits; // length of CPB buffer (bits) /* Crop rectangle */ guint conformance_window_flag:1; @@ -413,7 +425,8 @@ bs_write_vps (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, static gboolean bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, - const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile) + const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile, + const VAEncMiscParameterHRD * hrd_params) { guint32 video_parameter_set_id = 0; guint32 max_sub_layers_minus1 = 0; @@ -424,6 +437,8 @@ bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, guint32 num_short_term_ref_pic_sets = 0; guint32 long_term_ref_pics_present_flag = 0; guint32 sps_extension_flag = 0; + guint32 nal_hrd_parameters_present_flag = 0; + guint maxNumSubLayers = 1, i; /* video_parameter_set_id */ WRITE_UINT32 (bs, video_parameter_set_id, 4); @@ -550,8 +565,45 @@ bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, /* vui_hrd_parameters_present_flag */ vui_hrd_parameters_present_flag = seq_param->bits_per_second > 0; - vui_hrd_parameters_present_flag = FALSE; /* XXX: disabled for now */ WRITE_UINT32 (bs, vui_hrd_parameters_present_flag, 1); + + if (vui_hrd_parameters_present_flag) { + nal_hrd_parameters_present_flag = 1; + /* nal_hrd_parameters_present_flag */ + WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1); + /* vcl_hrd_parameters_present_flag */ + WRITE_UINT32 (bs, 0, 1); + + if (nal_hrd_parameters_present_flag) { + /* sub_pic_hrd_params_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* bit_rate_scale */ + WRITE_UINT32 (bs, SX_BITRATE - 6, 4); + /* cpb_size_scale */ + WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4); + /* initial_cpb_removal_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + /* au_cpb_removal_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + /* dpb_output_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + + for (i = 0; i < maxNumSubLayers; i++) { + /* fixed_pic_rate_general_flag */ + WRITE_UINT32 (bs, 0, 1); + /* fixed_pic_rate_within_cvs_flag */ + WRITE_UINT32 (bs, 0, 1); + /* low_delay_hrd_flag */ + WRITE_UINT32 (bs, 1, 1); + /* bit_rate_value_minus1 */ + WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1); + /* cpb_size_value_minus1 */ + WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1); + /* cbr_flag */ + WRITE_UINT32 (bs, 1, 1); + } + } + } } /* bitstream_restriction_flag */ WRITE_UINT32 (bs, seq_param->vui_fields.bits.bitstream_restriction_flag, 1); @@ -572,9 +624,10 @@ bs_error: static gboolean bs_write_sps (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, - const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile) + const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile, + const VAEncMiscParameterHRD * hrd_params) { - if (!bs_write_sps_data (bs, encoder, picture, seq_param, profile)) + if (!bs_write_sps_data (bs, encoder, picture, seq_param, profile, hrd_params)) return FALSE; /* rbsp_trailing_bits */ @@ -805,7 +858,8 @@ bs_write_slice (GstBitWriter * bs, (slice_param->slice_fields.bits.slice_sao_luma_flag || slice_param->slice_fields.bits.slice_sao_chroma_flag || !slice_deblocking_filter_disabled_flag)) - WRITE_UINT32 (bs, slice_param->slice_fields.bits. + WRITE_UINT32 (bs, + slice_param->slice_fields.bits. slice_loop_filter_across_slices_enabled_flag, 1); } @@ -1115,6 +1169,19 @@ set_key_frame (GstVaapiEncPicture * picture, set_i_frame (picture, encoder); } +/* Fills in VA HRD parameters */ +static void +fill_hrd_params (GstVaapiEncoderH265 * encoder, VAEncMiscParameterHRD * hrd) +{ + if (encoder->bitrate_bits > 0) { + hrd->buffer_size = encoder->cpb_length_bits; + hrd->initial_buffer_fullness = hrd->buffer_size / 2; + } else { + hrd->buffer_size = 0; + hrd->initial_buffer_fullness = 0; + } +} + /* Adds the supplied video parameter set header (VPS) to the list of packed headers to pass down as-is to the encoder */ static gboolean @@ -1178,14 +1245,17 @@ add_packed_sequence_header (GstVaapiEncoderH265 * encoder, const VAEncSequenceParameterBufferHEVC *const seq_param = sequence->param; GstVaapiProfile profile = encoder->profile; + VAEncMiscParameterHRD hrd_params; guint32 data_bit_size; guint8 *data; + fill_hrd_params (encoder, &hrd_params); + gst_bit_writer_init (&bs, 128 * 8); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H265_NAL_SPS); - bs_write_sps (&bs, encoder, picture, seq_param, profile); + bs_write_sps (&bs, encoder, picture, seq_param, profile, &hrd_params); g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); @@ -1754,6 +1824,25 @@ error_create_packed_seq_hdr: } } +static gboolean +ensure_misc_params (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncMiscParam *misc = NULL; + + /* HRD params for rate control */ + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) { + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); + g_assert (misc); + if (!misc) + return FALSE; + fill_hrd_params (encoder, misc->data); + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + } + + return TRUE; +} + /* Generates and submits PPS header accordingly into the bitstream */ static gboolean ensure_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, @@ -1778,6 +1867,7 @@ ensure_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, return TRUE; } + /* Generates slice headers */ static gboolean ensure_slices (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) @@ -1809,6 +1899,38 @@ ensure_slices (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) return TRUE; } +/* Normalizes bitrate (and CPB size) for HRD conformance */ +static void +ensure_bitrate_hrd (GstVaapiEncoderH265 * encoder) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + guint bitrate, cpb_size; + + if (!base_encoder->bitrate) { + encoder->bitrate_bits = 0; + return; + } + + /* Round down bitrate. This is a hard limit mandated by the user */ + g_assert (SX_BITRATE >= 6); + bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1); + if (bitrate != encoder->bitrate_bits) { + GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate); + encoder->bitrate_bits = bitrate; + encoder->config_changed = TRUE; + } + + /* Round up CPB size. This is an HRD compliance detail */ + g_assert (SX_CPB_SIZE >= 4); + cpb_size = gst_util_uint64_scale (bitrate, encoder->cpb_length, 1000) & + ~((1U << SX_CPB_SIZE) - 1); + if (cpb_size != encoder->cpb_length_bits) { + GST_DEBUG ("HRD CPB size: %u bits", cpb_size); + encoder->cpb_length_bits = cpb_size; + encoder->config_changed = TRUE; + } +} + /* Estimates a good enough bitrate if none was supplied */ static void ensure_bitrate (GstVaapiEncoderH265 * encoder) @@ -1817,8 +1939,6 @@ ensure_bitrate (GstVaapiEncoderH265 * encoder) switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { case GST_VAAPI_RATECONTROL_CBR: - case GST_VAAPI_RATECONTROL_VBR: - case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: if (!base_encoder->bitrate) { /* Fixme: Provide better estimation */ /* Using a 1/6 compression ratio */ @@ -1834,6 +1954,7 @@ ensure_bitrate (GstVaapiEncoderH265 * encoder) base_encoder->bitrate = 0; break; } + ensure_bitrate_hrd (encoder); } /* Constructs profile, tier and level information based on user-defined limits */ @@ -1859,11 +1980,11 @@ ensure_profile_tier_level (GstVaapiEncoderH265 * encoder) if (!ensure_tier (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + /* Ensure bitrate if not set already and derive the right level to use */ + ensure_bitrate (encoder); + if (!ensure_level (encoder)) - /* Ensure bitrate if not set already and derive the right level to use */ - ensure_bitrate (encoder); - if (!ensure_level (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; if (encoder->profile != profile || encoder->level != level || encoder->tier != tier) { @@ -1953,6 +2074,8 @@ gst_vaapi_encoder_h265_encode (GstVaapiEncoder * base_encoder, 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_slices (encoder, picture)) @@ -2408,6 +2531,9 @@ gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES: encoder->num_slices = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH: + encoder->cpb_length = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -2508,6 +2634,19 @@ gst_vaapi_encoder_h265_get_default_properties (void) "Number of Slices", "Number of slices per frame", 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH265:cpb-length: + * + * The size of the CPB buffer in milliseconds. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH, + g_param_spec_uint ("cpb-length", + "CPB Length", "Length of the CPB buffer in milliseconds", + 1, 10000, DEFAULT_CPB_LENGTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } From 018ea8b2fc193f64bcaf8f2a58e67d6a806dfce9 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 27 Apr 2016 17:10:26 +0300 Subject: [PATCH 2369/3781] encoder: h265: Enable cu_qp_delta_enabled_flag for CBR It seems driver requires enablement of cu_qp_delta_enabled_flag for modifying QP values to controll the CBR mode bitrate. https://bugzilla.gnome.org/show_bug.cgi?id=749852 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 4f1db1d1b4..0a5a291d67 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1637,6 +1637,10 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, pic_param->pic_fields.bits.reference_pic_flag = TRUE; pic_param->pic_fields.bits.sign_data_hiding_enabled_flag = FALSE; pic_param->pic_fields.bits.transform_skip_enabled_flag = TRUE; + /* it seems driver requires enablement of cu_qp_delta_enabled_flag + * to modifiy QP values in CBR mode encoding */ + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) + pic_param->pic_fields.bits.cu_qp_delta_enabled_flag = TRUE; pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag = TRUE; if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) From 74ebee5339529fd08eedcac24966f1406f8f3109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Apr 2016 12:48:44 +0200 Subject: [PATCH 2370/3781] tests: inforce gstreamer code-style --- tests/codec.c | 214 +-- tests/decoder.c | 212 +-- tests/image.c | 676 +++---- tests/output.c | 253 ++- tests/simple-decoder.c | 1037 +++++----- tests/test-decode.c | 161 +- tests/test-display.c | 722 ++++--- tests/test-filter.c | 613 +++--- tests/test-h264.c | 2033 ++++++++++---------- tests/test-jpeg.c | 13 +- tests/test-mpeg2.c | 3233 +++++++++++++++---------------- tests/test-mpeg4.c | 3277 +++++++++++++++---------------- tests/test-subpicture-data.c | 3 +- tests/test-subpicture.c | 207 +- tests/test-surfaces.c | 124 +- tests/test-textures.c | 241 ++- tests/test-vc1.c | 3491 +++++++++++++++++----------------- tests/test-windows.c | 280 ++- 18 files changed, 8345 insertions(+), 8445 deletions(-) diff --git a/tests/codec.c b/tests/codec.c index b30c0af4b5..d14981ac8e 100644 --- a/tests/codec.c +++ b/tests/codec.c @@ -24,170 +24,172 @@ #include #include "codec.h" -typedef struct { - const gchar *codec_str; - GstVaapiCodec codec; - const gchar *caps_str; +typedef struct +{ + const gchar *codec_str; + GstVaapiCodec codec; + const gchar *caps_str; } CodecMap; static const CodecMap g_codec_map[] = { - { "h264", GST_VAAPI_CODEC_H264, - "video/x-h264" }, - { "jpeg", GST_VAAPI_CODEC_JPEG, - "image/jpeg" }, - { "mpeg2", GST_VAAPI_CODEC_MPEG2, - "video/mpeg, mpegversion=2" }, - { "mpeg4", GST_VAAPI_CODEC_MPEG4, - "video/mpeg, mpegversion=4" }, - { "wmv3", GST_VAAPI_CODEC_VC1, - "video/x-wmv, wmvversion=3" }, - { "vc1", GST_VAAPI_CODEC_VC1, - "video/x-wmv, wmvversion=3, format=(string)WVC1" }, - { NULL, } + {"h264", GST_VAAPI_CODEC_H264, + "video/x-h264"}, + {"jpeg", GST_VAAPI_CODEC_JPEG, + "image/jpeg"}, + {"mpeg2", GST_VAAPI_CODEC_MPEG2, + "video/mpeg, mpegversion=2"}, + {"mpeg4", GST_VAAPI_CODEC_MPEG4, + "video/mpeg, mpegversion=4"}, + {"wmv3", GST_VAAPI_CODEC_VC1, + "video/x-wmv, wmvversion=3"}, + {"vc1", GST_VAAPI_CODEC_VC1, + "video/x-wmv, wmvversion=3, format=(string)WVC1"}, + {NULL,} }; static const CodecMap * -get_codec_map(GstVaapiCodec codec) +get_codec_map (GstVaapiCodec codec) { - const CodecMap *m; + const CodecMap *m; - if (codec) { - for (m = g_codec_map; m->codec_str != NULL; m++) { - if (m->codec == codec) - return m; - } + if (codec) { + for (m = g_codec_map; m->codec_str != NULL; m++) { + if (m->codec == codec) + return m; } - return NULL; + } + return NULL; } const gchar * -string_from_codec(GstVaapiCodec codec) +string_from_codec (GstVaapiCodec codec) { - const CodecMap * const m = get_codec_map(codec); + const CodecMap *const m = get_codec_map (codec); - return m ? m->codec_str : NULL; + return m ? m->codec_str : NULL; } GstCaps * -caps_from_codec(GstVaapiCodec codec) +caps_from_codec (GstVaapiCodec codec) { - const CodecMap * const m = get_codec_map(codec); + const CodecMap *const m = get_codec_map (codec); - return m ? gst_caps_from_string(m->caps_str) : NULL; + return m ? gst_caps_from_string (m->caps_str) : NULL; } GstVaapiCodec -identify_codec_from_string(const gchar *codec_str) +identify_codec_from_string (const gchar * codec_str) { - const CodecMap *m; + const CodecMap *m; - if (codec_str) { - for (m = g_codec_map; m->codec_str != NULL; m++) { - if (g_ascii_strcasecmp(m->codec_str, codec_str) == 0) - return m->codec; - } + if (codec_str) { + for (m = g_codec_map; m->codec_str != NULL; m++) { + if (g_ascii_strcasecmp (m->codec_str, codec_str) == 0) + return m->codec; } - return 0; + } + return 0; } -typedef struct { - GMappedFile *file; - guint8 *data; - guint size; - guint probability; - GstCaps *caps; - GstTypeFind type_find; +typedef struct +{ + GMappedFile *file; + guint8 *data; + guint size; + guint probability; + GstCaps *caps; + GstTypeFind type_find; } CodecIdentifier; static const guint8 * -codec_identifier_peek(gpointer data, gint64 offset, guint size) +codec_identifier_peek (gpointer data, gint64 offset, guint size) { - CodecIdentifier * const cip = data; + CodecIdentifier *const cip = data; - if (offset >= 0 && offset + size <= cip->size) - return cip->data + offset; - if (offset < 0 && ((gint)cip->size + offset) >= 0) - return &cip->data[cip->size + offset]; - return NULL; + if (offset >= 0 && offset + size <= cip->size) + return cip->data + offset; + if (offset < 0 && ((gint) cip->size + offset) >= 0) + return &cip->data[cip->size + offset]; + return NULL; } static void -codec_identifier_suggest(gpointer data, guint probability, GstCaps *caps) +codec_identifier_suggest (gpointer data, guint probability, GstCaps * caps) { - CodecIdentifier * const cip = data; + CodecIdentifier *const cip = data; - if (cip->probability < probability) { - cip->probability = probability; - gst_caps_replace(&cip->caps, caps); - } + if (cip->probability < probability) { + cip->probability = probability; + gst_caps_replace (&cip->caps, caps); + } } static void -codec_identifier_free(CodecIdentifier *cip) +codec_identifier_free (CodecIdentifier * cip) { - if (!cip) - return; + if (!cip) + return; - if (cip->file) { - g_mapped_file_unref(cip->file); - cip->file = NULL; - } - gst_caps_replace(&cip->caps, NULL); - g_slice_free(CodecIdentifier, cip); + if (cip->file) { + g_mapped_file_unref (cip->file); + cip->file = NULL; + } + gst_caps_replace (&cip->caps, NULL); + g_slice_free (CodecIdentifier, cip); } static CodecIdentifier * -codec_identifier_new(const gchar *filename) +codec_identifier_new (const gchar * filename) { - CodecIdentifier *cip; - GstTypeFind *tfp; + CodecIdentifier *cip; + GstTypeFind *tfp; - cip = g_slice_new0(CodecIdentifier); - if (!cip) - return NULL; + cip = g_slice_new0 (CodecIdentifier); + if (!cip) + return NULL; - cip->file = g_mapped_file_new(filename, FALSE, NULL); - if (!cip->file) - goto error; + cip->file = g_mapped_file_new (filename, FALSE, NULL); + if (!cip->file) + goto error; - cip->size = g_mapped_file_get_length(cip->file); - cip->data = (guint8 *)g_mapped_file_get_contents(cip->file); - if (!cip->data) - goto error; + cip->size = g_mapped_file_get_length (cip->file); + cip->data = (guint8 *) g_mapped_file_get_contents (cip->file); + if (!cip->data) + goto error; - tfp = &cip->type_find; - tfp->peek = codec_identifier_peek; - tfp->suggest = codec_identifier_suggest; - tfp->data = cip; - return cip; + tfp = &cip->type_find; + tfp->peek = codec_identifier_peek; + tfp->suggest = codec_identifier_suggest; + tfp->data = cip; + return cip; error: - codec_identifier_free(cip); - return NULL; + codec_identifier_free (cip); + return NULL; } GstVaapiCodec -identify_codec(const gchar *filename) +identify_codec (const gchar * filename) { - CodecIdentifier *cip; - GList *type_list, *l; - guint32 codec = 0; + CodecIdentifier *cip; + GList *type_list, *l; + guint32 codec = 0; - cip = codec_identifier_new(filename); - if (!cip) - return 0; + cip = codec_identifier_new (filename); + if (!cip) + return 0; - type_list = gst_type_find_factory_get_list(); - for (l = type_list; l != NULL; l = l->next) { - GstTypeFindFactory * const factory = GST_TYPE_FIND_FACTORY(l->data); - gst_type_find_factory_call_function(factory, &cip->type_find); - } - g_list_free(type_list); + type_list = gst_type_find_factory_get_list (); + for (l = type_list; l != NULL; l = l->next) { + GstTypeFindFactory *const factory = GST_TYPE_FIND_FACTORY (l->data); + gst_type_find_factory_call_function (factory, &cip->type_find); + } + g_list_free (type_list); - if (cip->probability >= GST_TYPE_FIND_LIKELY) - codec = gst_vaapi_profile_get_codec( - gst_vaapi_profile_from_caps(cip->caps)); + if (cip->probability >= GST_TYPE_FIND_LIKELY) + codec = + gst_vaapi_profile_get_codec (gst_vaapi_profile_from_caps (cip->caps)); - codec_identifier_free(cip); - return codec; + codec_identifier_free (cip); + return codec; } diff --git a/tests/decoder.c b/tests/decoder.c index 2ca72806e5..6679cc10c9 100644 --- a/tests/decoder.c +++ b/tests/decoder.c @@ -34,169 +34,169 @@ #include "test-h264.h" #include "test-vc1.h" -typedef void (*GetVideoInfoFunc)(VideoDecodeInfo *info); +typedef void (*GetVideoInfoFunc) (VideoDecodeInfo * info); typedef struct _CodecDefs CodecDefs; -struct _CodecDefs { - const gchar *codec_str; - GetVideoInfoFunc get_video_info; +struct _CodecDefs +{ + const gchar *codec_str; + GetVideoInfoFunc get_video_info; }; static const CodecDefs g_codec_defs[] = { #define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info } - INIT_FUNCS(jpeg), - INIT_FUNCS(mpeg2), - INIT_FUNCS(mpeg4), - INIT_FUNCS(h264), - INIT_FUNCS(vc1), + INIT_FUNCS (jpeg), + INIT_FUNCS (mpeg2), + INIT_FUNCS (mpeg4), + INIT_FUNCS (h264), + INIT_FUNCS (vc1), #undef INIT_FUNCS - { NULL, } + {NULL,} }; static const CodecDefs * -find_codec_defs(const gchar *codec_str) +find_codec_defs (const gchar * codec_str) { - const CodecDefs *c; - for (c = g_codec_defs; c->codec_str; c++) - if (strcmp(codec_str, c->codec_str) == 0) - return c; - return NULL; + const CodecDefs *c; + for (c = g_codec_defs; c->codec_str; c++) + if (strcmp (codec_str, c->codec_str) == 0) + return c; + return NULL; } static inline const CodecDefs * -get_codec_defs(GstVaapiDecoder *decoder) +get_codec_defs (GstVaapiDecoder * decoder) { - return gst_vaapi_decoder_get_user_data(decoder); + return gst_vaapi_decoder_get_user_data (decoder); } static inline void -set_codec_defs(GstVaapiDecoder *decoder, const CodecDefs *c) +set_codec_defs (GstVaapiDecoder * decoder, const CodecDefs * c) { - gst_vaapi_decoder_set_user_data(decoder, (gpointer)c); + gst_vaapi_decoder_set_user_data (decoder, (gpointer) c); } GstVaapiDecoder * -decoder_new(GstVaapiDisplay *display, const gchar *codec_name) +decoder_new (GstVaapiDisplay * display, const gchar * codec_name) { - GstVaapiDecoder *decoder; - const CodecDefs *codec; - GstCaps *caps; - VideoDecodeInfo info; + GstVaapiDecoder *decoder; + const CodecDefs *codec; + GstCaps *caps; + VideoDecodeInfo info; - if (!codec_name) - codec_name = "h264"; + if (!codec_name) + codec_name = "h264"; - codec = find_codec_defs(codec_name); - if (!codec) { - GST_ERROR("failed to find %s codec data", codec_name); - return NULL; - } + codec = find_codec_defs (codec_name); + if (!codec) { + GST_ERROR ("failed to find %s codec data", codec_name); + return NULL; + } - codec->get_video_info(&info); - caps = gst_vaapi_profile_get_caps(info.profile); - if (!caps) { - GST_ERROR("failed to create decoder caps"); - return NULL; - } + codec->get_video_info (&info); + caps = gst_vaapi_profile_get_caps (info.profile); + if (!caps) { + GST_ERROR ("failed to create decoder caps"); + return NULL; + } - if (info.width > 0 && info.height > 0) - gst_caps_set_simple(caps, - "width", G_TYPE_INT, info.width, - "height", G_TYPE_INT, info.height, - NULL); + if (info.width > 0 && info.height > 0) + gst_caps_set_simple (caps, + "width", G_TYPE_INT, info.width, + "height", G_TYPE_INT, info.height, NULL); - switch (gst_vaapi_profile_get_codec(info.profile)) { + switch (gst_vaapi_profile_get_codec (info.profile)) { case GST_VAAPI_CODEC_H264: - decoder = gst_vaapi_decoder_h264_new(display, caps); - break; + decoder = gst_vaapi_decoder_h264_new (display, caps); + break; #if USE_JPEG_DECODER case GST_VAAPI_CODEC_JPEG: - decoder = gst_vaapi_decoder_jpeg_new(display, caps); - break; + decoder = gst_vaapi_decoder_jpeg_new (display, caps); + break; #endif case GST_VAAPI_CODEC_MPEG2: - decoder = gst_vaapi_decoder_mpeg2_new(display, caps); - break; + decoder = gst_vaapi_decoder_mpeg2_new (display, caps); + break; case GST_VAAPI_CODEC_MPEG4: - decoder = gst_vaapi_decoder_mpeg4_new(display, caps); - break; + decoder = gst_vaapi_decoder_mpeg4_new (display, caps); + break; case GST_VAAPI_CODEC_VC1: - decoder = gst_vaapi_decoder_vc1_new(display, caps); - break; + decoder = gst_vaapi_decoder_vc1_new (display, caps); + break; default: - decoder = NULL; - break; - } - gst_caps_unref(caps); - if (!decoder) { - GST_ERROR("failed to create %s decoder", codec->codec_str); - return NULL; - } + decoder = NULL; + break; + } + gst_caps_unref (caps); + if (!decoder) { + GST_ERROR ("failed to create %s decoder", codec->codec_str); + return NULL; + } - set_codec_defs(decoder, codec); - return decoder; + set_codec_defs (decoder, codec); + return decoder; } gboolean -decoder_put_buffers(GstVaapiDecoder *decoder) +decoder_put_buffers (GstVaapiDecoder * decoder) { - const CodecDefs *codec; - VideoDecodeInfo info; - GstBuffer *buffer; - gboolean success; + const CodecDefs *codec; + VideoDecodeInfo info; + GstBuffer *buffer; + gboolean success; - g_return_val_if_fail(decoder != NULL, FALSE); + g_return_val_if_fail (decoder != NULL, FALSE); - codec = get_codec_defs(decoder); - g_return_val_if_fail(codec != NULL, FALSE); + codec = get_codec_defs (decoder); + g_return_val_if_fail (codec != NULL, FALSE); - codec->get_video_info(&info); - buffer = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY, - (guchar *)info.data, info.data_size, 0, info.data_size, NULL, NULL); - if (!buffer) { - GST_ERROR("failed to create encoded data buffer"); - return FALSE; - } + codec->get_video_info (&info); + buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, + (guchar *) info.data, info.data_size, 0, info.data_size, NULL, NULL); + if (!buffer) { + GST_ERROR ("failed to create encoded data buffer"); + return FALSE; + } - success = gst_vaapi_decoder_put_buffer(decoder, buffer); - gst_buffer_unref(buffer); - if (!success) { - GST_ERROR("failed to send video data to the decoder"); - return FALSE; - } + success = gst_vaapi_decoder_put_buffer (decoder, buffer); + gst_buffer_unref (buffer); + if (!success) { + GST_ERROR ("failed to send video data to the decoder"); + return FALSE; + } - if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) { - GST_ERROR("failed to submit to the decoder"); - return FALSE; - } - return TRUE; + if (!gst_vaapi_decoder_put_buffer (decoder, NULL)) { + GST_ERROR ("failed to submit to the decoder"); + return FALSE; + } + return TRUE; } GstVaapiSurfaceProxy * -decoder_get_surface(GstVaapiDecoder *decoder) +decoder_get_surface (GstVaapiDecoder * decoder) { - GstVaapiSurfaceProxy *proxy; - GstVaapiDecoderStatus status; + GstVaapiSurfaceProxy *proxy; + GstVaapiDecoderStatus status; - g_return_val_if_fail(decoder != NULL, NULL); + g_return_val_if_fail (decoder != NULL, NULL); - status = gst_vaapi_decoder_get_surface(decoder, &proxy); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_ERROR("failed to get decoded surface (decoder status %d)", status); - return NULL; - } - return proxy; + status = gst_vaapi_decoder_get_surface (decoder, &proxy); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { + GST_ERROR ("failed to get decoded surface (decoder status %d)", status); + return NULL; + } + return proxy; } const gchar * -decoder_get_codec_name(GstVaapiDecoder *decoder) +decoder_get_codec_name (GstVaapiDecoder * decoder) { - const CodecDefs *codec; + const CodecDefs *codec; - g_return_val_if_fail(decoder != NULL, NULL); + g_return_val_if_fail (decoder != NULL, NULL); - codec = get_codec_defs(decoder); - g_return_val_if_fail(codec != NULL, FALSE); + codec = get_codec_defs (decoder); + g_return_val_if_fail (codec != NULL, FALSE); - return codec->codec_str; + return codec->codec_str; } diff --git a/tests/image.c b/tests/image.c index 9a6b6e7fb6..1304471000 100644 --- a/tests/image.c +++ b/tests/image.c @@ -25,460 +25,376 @@ #include "image.h" static gboolean -image_draw_rectangle( - GstVaapiImage *image, - gint x, - gint y, - guint width, - guint height, - guint32 color, - guint32 flags -); +image_draw_rectangle (GstVaapiImage * image, + gint x, gint y, guint width, guint height, guint32 color, guint32 flags); static gboolean -image_draw_color_rectangles( - GstVaapiImage *image, - guint width, - guint height, - const guint32 colors[4], - guint32 flags - ) +image_draw_color_rectangles (GstVaapiImage * image, + guint width, guint height, const guint32 colors[4], guint32 flags) { - const guint w = width / 2; - const guint h = height / 2; + const guint w = width / 2; + const guint h = height / 2; - if (!image_draw_rectangle(image, 0, 0, w, h, colors[0], flags)) - return FALSE; - if (!image_draw_rectangle(image, w, 0, w, h, colors[1], flags)) - return FALSE; - if (!image_draw_rectangle(image, 0, h, w, h, colors[2], flags)) - return FALSE; - if (!image_draw_rectangle(image, w, h, w, h, colors[3], flags)) - return FALSE; - return TRUE; + if (!image_draw_rectangle (image, 0, 0, w, h, colors[0], flags)) + return FALSE; + if (!image_draw_rectangle (image, w, 0, w, h, colors[1], flags)) + return FALSE; + if (!image_draw_rectangle (image, 0, h, w, h, colors[2], flags)) + return FALSE; + if (!image_draw_rectangle (image, w, h, w, h, colors[3], flags)) + return FALSE; + return TRUE; } GstVaapiImage * -image_generate( - GstVaapiDisplay *display, - GstVideoFormat format, - guint width, - guint height -) +image_generate (GstVaapiDisplay * display, + GstVideoFormat format, guint width, guint height) { - return image_generate_full(display, format, width, height, 0); + return image_generate_full (display, format, width, height, 0); } GstVaapiImage * -image_generate_full( - GstVaapiDisplay *display, - GstVideoFormat format, - guint width, - guint height, - guint32 flags -) +image_generate_full (GstVaapiDisplay * display, + GstVideoFormat format, guint width, guint height, guint32 flags) { - GstVaapiImage *image; + GstVaapiImage *image; - static const guint32 rgb_colors[4] = - { 0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000 }; - static const guint32 bgr_colors[4] = - { 0xff000000, 0xff0000ff, 0xff00ff00, 0xffff0000 }; - static const guint32 inv_colors[4] = - { 0xffdeadc0, 0xffdeadc0, 0xffdeadc0, 0xffdeadc0 }; + static const guint32 rgb_colors[4] = + { 0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000 }; + static const guint32 bgr_colors[4] = + { 0xff000000, 0xff0000ff, 0xff00ff00, 0xffff0000 }; + static const guint32 inv_colors[4] = + { 0xffdeadc0, 0xffdeadc0, 0xffdeadc0, 0xffdeadc0 }; - image = gst_vaapi_image_new(display, format, width, height); - if (!image) - return NULL; + image = gst_vaapi_image_new (display, format, width, height); + if (!image) + return NULL; - if (flags) { - if (!image_draw_color_rectangles(image, width, height, - ((flags & GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) ? - rgb_colors : inv_colors), - GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)) - goto error; + if (flags) { + if (!image_draw_color_rectangles (image, width, height, + ((flags & GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) ? + rgb_colors : inv_colors), + GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)) + goto error; - if (!image_draw_color_rectangles(image, width, height, - ((flags & GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) ? - bgr_colors : inv_colors), - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)) - goto error; - } - else if (!image_draw_color_rectangles(image, width, height, rgb_colors, 0)) - goto error; - return image; + if (!image_draw_color_rectangles (image, width, height, + ((flags & GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) ? + bgr_colors : inv_colors), + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)) + goto error; + } else if (!image_draw_color_rectangles (image, width, height, rgb_colors, 0)) + goto error; + return image; error: - gst_vaapi_object_unref(image); - return NULL; + gst_vaapi_object_unref (image); + return NULL; } -typedef void (*DrawRectFunc)( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -); +typedef void (*DrawRectFunc) (guchar * pixels[3], + guint stride[3], gint x, gint y, guint width, guint height, guint32 color); -static void draw_rect_ARGB( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) +static void +draw_rect_ARGB (guchar * pixels[3], + guint stride[3], gint x, gint y, guint width, guint height, guint32 color) { - guint i, j; + guint i, j; - color = GUINT32_TO_BE(color); + color = GUINT32_TO_BE (color); - for (j = 0; j < height; j++) { - guint32 *p = (guint32 *)(pixels[0] + (y + j) * stride[0] + x * 4); - for (i = 0; i < width; i++) - p[i] = color; + for (j = 0; j < height; j++) { + guint32 *p = (guint32 *) (pixels[0] + (y + j) * stride[0] + x * 4); + for (i = 0; i < width; i++) + p[i] = color; + } +} + +static void +draw_rect_BGRA (guchar * pixels[3], + guint stride[3], gint x, gint y, guint width, guint height, guint32 color) +{ + // Converts ARGB color to BGRA + color = GUINT32_SWAP_LE_BE (color); + + draw_rect_ARGB (pixels, stride, x, y, width, height, color); +} + +static void +draw_rect_RGBA (guchar * pixels[3], + guint stride[3], gint x, gint y, guint width, guint height, guint32 color) +{ + // Converts ARGB color to RGBA + color = ((color >> 24) & 0xff) | ((color & 0xffffff) << 8); + + draw_rect_ARGB (pixels, stride, x, y, width, height, color); +} + +static void +draw_rect_ABGR (guchar * pixels[3], + guint stride[3], gint x, gint y, guint width, guint height, guint32 color) +{ + // Converts ARGB color to ABGR + color = ((color & 0xff00ff00) | + ((color >> 16) & 0xff) | ((color & 0xff) << 16)); + + draw_rect_ARGB (pixels, stride, x, y, width, height, color); +} + +static void +draw_rect_NV12 ( // Y, UV planes + guchar * pixels[3], + guint stride[3], gint x, gint y, guint width, guint height, guint32 color) +{ + const guchar Y = color >> 16; + const guchar Cb = color >> 8; + const guchar Cr = color; + guchar *dst; + guint i, j; + + dst = pixels[0] + y * stride[0] + x; + for (j = 0; j < height; j++, dst += stride[0]) + for (i = 0; i < width; i++) + dst[i] = Y; + + x /= 2; + y /= 2; + width /= 2; + height /= 2; + + dst = pixels[1] + y * stride[1] + x * 2; + for (j = 0; j < height; j++, dst += stride[1]) + for (i = 0; i < width; i++) { + dst[2 * i + 0] = Cb; + dst[2 * i + 1] = Cr; } } -static void draw_rect_BGRA( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) +static void +draw_rect_YV12 ( // Y, V, U planes + guchar * pixels[3], + guint stride[3], gint x, gint y, guint width, guint height, guint32 color) { - // Converts ARGB color to BGRA - color = GUINT32_SWAP_LE_BE(color); + const guchar Y = color >> 16; + const guchar Cb = color >> 8; + const guchar Cr = color; + guchar *pY, *pU, *pV; + guint i, j; - draw_rect_ARGB(pixels, stride, x, y, width, height, color); -} + pY = pixels[0] + y * stride[0] + x; + for (j = 0; j < height; j++, pY += stride[0]) + for (i = 0; i < width; i++) + pY[i] = Y; -static void draw_rect_RGBA( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - // Converts ARGB color to RGBA - color = ((color >> 24) & 0xff) | ((color & 0xffffff) << 8); + x /= 2; + y /= 2; + width /= 2; + height /= 2; - draw_rect_ARGB(pixels, stride, x, y, width, height, color); -} - -static void draw_rect_ABGR( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - // Converts ARGB color to ABGR - color = ((color & 0xff00ff00) | - ((color >> 16) & 0xff) | - ((color & 0xff) << 16)); - - draw_rect_ARGB(pixels, stride, x, y, width, height, color); -} - -static void draw_rect_NV12( // Y, UV planes - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - const guchar Y = color >> 16; - const guchar Cb = color >> 8; - const guchar Cr = color; - guchar *dst; - guint i, j; - - dst = pixels[0] + y * stride[0] + x; - for (j = 0; j < height; j++, dst += stride[0]) - for (i = 0; i < width; i++) - dst[i] = Y; - - x /= 2; - y /= 2; - width /= 2; - height /= 2; - - dst = pixels[1] + y * stride[1] + x * 2; - for (j = 0; j < height; j++, dst += stride[1]) - for (i = 0; i < width; i++) { - dst[2*i + 0] = Cb; - dst[2*i + 1] = Cr; - } -} - -static void draw_rect_YV12( // Y, V, U planes - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - const guchar Y = color >> 16; - const guchar Cb = color >> 8; - const guchar Cr = color; - guchar *pY, *pU, *pV; - guint i, j; - - pY = pixels[0] + y * stride[0] + x; - for (j = 0; j < height; j++, pY += stride[0]) - for (i = 0; i < width; i++) - pY[i] = Y; - - x /= 2; - y /= 2; - width /= 2; - height /= 2; - - pV = pixels[1] + y * stride[1] + x; - pU = pixels[2] + y * stride[2] + x; - for (j = 0; j < height; j++, pU += stride[1], pV += stride[2]) - for (i = 0; i < width; i++) { - pU[i] = Cb; - pV[i] = Cr; - } -} - -static void draw_rect_I420( // Y, U, V planes - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) -{ - guchar *new_pixels[3] = { pixels[0], pixels[2], pixels[1] }; - guint new_stride[3] = { stride[0], stride[2], stride[1] }; - - draw_rect_YV12(new_pixels, new_stride, x, y, width, height, color); -} - -static void draw_rect_YUV422(guchar *pixels[3], guint stride[3], - gint x, gint y, guint width, guint height, guint32 color) -{ - guint i, j; - - width /= 2; - for (j = 0; j < height; j++) { - guint32 * const p = (guint32 *) - (pixels[0] + (y + j) * stride[0] + x * 2); - for (i = 0; i < width; i++) - p[i] = color; + pV = pixels[1] + y * stride[1] + x; + pU = pixels[2] + y * stride[2] + x; + for (j = 0; j < height; j++, pU += stride[1], pV += stride[2]) + for (i = 0; i < width; i++) { + pU[i] = Cb; + pV[i] = Cr; } } -static void draw_rect_YUY2(guchar *pixels[3], guint stride[3], +static void +draw_rect_I420 ( // Y, U, V planes + guchar * pixels[3], + guint stride[3], gint x, gint y, guint width, guint height, guint32 color) +{ + guchar *new_pixels[3] = { pixels[0], pixels[2], pixels[1] }; + guint new_stride[3] = { stride[0], stride[2], stride[1] }; + + draw_rect_YV12 (new_pixels, new_stride, x, y, width, height, color); +} + +static void +draw_rect_YUV422 (guchar * pixels[3], guint stride[3], gint x, gint y, guint width, guint height, guint32 color) { - const guchar Y = color >> 16; - const guchar Cb = color >> 8; - const guchar Cr = color; + guint i, j; - color = (Y << 24) | (Cb << 16) | (Y << 8) | Cr; - draw_rect_YUV422(pixels, stride, x, y, width, height, GUINT32_TO_BE(color)); + width /= 2; + for (j = 0; j < height; j++) { + guint32 *const p = (guint32 *) + (pixels[0] + (y + j) * stride[0] + x * 2); + for (i = 0; i < width; i++) + p[i] = color; + } } -static void draw_rect_UYVY(guchar *pixels[3], guint stride[3], +static void +draw_rect_YUY2 (guchar * pixels[3], guint stride[3], gint x, gint y, guint width, guint height, guint32 color) { - const guchar Y = color >> 16; - const guchar Cb = color >> 8; - const guchar Cr = color; + const guchar Y = color >> 16; + const guchar Cb = color >> 8; + const guchar Cr = color; - color = (Cb << 24) | (Y << 16) | (Cr << 8) | Y; - draw_rect_YUV422(pixels, stride, x, y, width, height, GUINT32_TO_BE(color)); + color = (Y << 24) | (Cb << 16) | (Y << 8) | Cr; + draw_rect_YUV422 (pixels, stride, x, y, width, height, GUINT32_TO_BE (color)); } -static void draw_rect_AYUV( - guchar *pixels[3], - guint stride[3], - gint x, - gint y, - guint width, - guint height, - guint32 color -) +static void +draw_rect_UYVY (guchar * pixels[3], guint stride[3], + gint x, gint y, guint width, guint height, guint32 color) { - guint i, j; + const guchar Y = color >> 16; + const guchar Cb = color >> 8; + const guchar Cr = color; - color = color | 0xff000000; - - for (j = 0; j < height; j++) { - guint32 *p = (guint32 *)(pixels[0] + (y + j) * stride[0] + x * 4); - for (i = 0; i < width; i++) - p[i] = color; - } + color = (Cb << 24) | (Y << 16) | (Cr << 8) | Y; + draw_rect_YUV422 (pixels, stride, x, y, width, height, GUINT32_TO_BE (color)); } -static inline guint32 argb2yuv(guint32 color) +static void +draw_rect_AYUV (guchar * pixels[3], + guint stride[3], gint x, gint y, guint width, guint height, guint32 color) { - const gint32 r = (color >> 16) & 0xff; - const gint32 g = (color >> 8) & 0xff; - const gint32 b = (color ) & 0xff; + guint i, j; - const guint32 y = (( 306 * r + 601 * g + 116 * b) >> 10); - const guint32 u = ((-172 * r - 339 * g + 512 * b) >> 10) + 128; - const guint32 v = (( 512 * r - 428 * g - 83 * b) >> 10) + 128; + color = color | 0xff000000; - return (y << 16) | (u << 8) | v; + for (j = 0; j < height; j++) { + guint32 *p = (guint32 *) (pixels[0] + (y + j) * stride[0] + x * 4); + for (i = 0; i < width; i++) + p[i] = color; + } +} + +static inline guint32 +argb2yuv (guint32 color) +{ + const gint32 r = (color >> 16) & 0xff; + const gint32 g = (color >> 8) & 0xff; + const gint32 b = (color) & 0xff; + + const guint32 y = ((306 * r + 601 * g + 116 * b) >> 10); + const guint32 u = ((-172 * r - 339 * g + 512 * b) >> 10) + 128; + const guint32 v = ((512 * r - 428 * g - 83 * b) >> 10) + 128; + + return (y << 16) | (u << 8) | v; } gboolean -image_draw_rectangle( - GstVaapiImage *image, - gint x, - gint y, - guint width, - guint height, - guint32 color, - guint32 flags -) +image_draw_rectangle (GstVaapiImage * image, + gint x, gint y, guint width, guint height, guint32 color, guint32 flags) { - const GstVideoFormat image_format = gst_vaapi_image_get_format(image); - const guint image_width = gst_vaapi_image_get_width(image); - const guint image_height = gst_vaapi_image_get_height(image); - GstVaapiDisplay *display; - guchar *pixels[3]; - guint stride[3]; - DrawRectFunc draw_rect = NULL; - guint i; + const GstVideoFormat image_format = gst_vaapi_image_get_format (image); + const guint image_width = gst_vaapi_image_get_width (image); + const guint image_height = gst_vaapi_image_get_height (image); + GstVaapiDisplay *display; + guchar *pixels[3]; + guint stride[3]; + DrawRectFunc draw_rect = NULL; + guint i; - static const struct { - GstVideoFormat format; - DrawRectFunc draw_rect; - } - map[] = { + static const struct + { + GstVideoFormat format; + DrawRectFunc draw_rect; + } + map[] = { #define _(FORMAT) { GST_VIDEO_FORMAT_##FORMAT, draw_rect_##FORMAT } - _(ARGB), + _(ARGB), _(BGRA), - _(RGBA), - _(ABGR), - _(NV12), - _(YV12), - _(I420), - _(YUY2), - _(UYVY), - _(AYUV), + _(RGBA), _(ABGR), _(NV12), _(YV12), _(I420), _(YUY2), _(UYVY), _(AYUV), #undef _ - { 0, } - }; + { + 0,} + }; - for (i = 0; !draw_rect && map[i].format; i++) - if (map[i].format == image_format) - draw_rect = map[i].draw_rect; - if (!draw_rect) - return FALSE; + for (i = 0; !draw_rect && map[i].format; i++) + if (map[i].format == image_format) + draw_rect = map[i].draw_rect; + if (!draw_rect) + return FALSE; - if (x < 0) - x = 0; - if (y < 0) - y = 0; - if (width > image_width - x) - width = image_width - x; - if (height > image_height - y) - height = image_height - y; + if (x < 0) + x = 0; + if (y < 0) + y = 0; + if (width > image_width - x) + width = image_width - x; + if (height > image_height - y) + height = image_height - y; - display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(image)); - if (!display) - return FALSE; + display = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (image)); + if (!display) + return FALSE; - if (!gst_vaapi_image_map(image)) - return FALSE; + if (!gst_vaapi_image_map (image)) + return FALSE; - for (i = 0; i < gst_vaapi_image_get_plane_count(image); i++) { - pixels[i] = gst_vaapi_image_get_plane(image, i); - stride[i] = gst_vaapi_image_get_pitch(image, i); - switch (flags) { - case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: - pixels[i] += stride[i]; - // fall-through - case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: - stride[i] *= 2; - break; - } + for (i = 0; i < gst_vaapi_image_get_plane_count (image); i++) { + pixels[i] = gst_vaapi_image_get_plane (image, i); + stride[i] = gst_vaapi_image_get_pitch (image, i); + switch (flags) { + case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: + pixels[i] += stride[i]; + // fall-through + case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: + stride[i] *= 2; + break; } + } - if (flags) - y /= 2, height /= 2; + if (flags) + y /= 2, height /= 2; - if (gst_vaapi_video_format_is_yuv(image_format)) - color = argb2yuv(color); + if (gst_vaapi_video_format_is_yuv (image_format)) + color = argb2yuv (color); - draw_rect(pixels, stride, x, y, width, height, color); - return gst_vaapi_image_unmap(image); + draw_rect (pixels, stride, x, y, width, height, color); + return gst_vaapi_image_unmap (image); } gboolean -image_upload(GstVaapiImage *image, GstVaapiSurface *surface) +image_upload (GstVaapiImage * image, GstVaapiSurface * surface) { - GstVaapiDisplay *display; - GstVideoFormat format; - GstVaapiImage *surface_image; - GstVaapiSubpicture *subpicture; - gboolean success; + GstVaapiDisplay *display; + GstVideoFormat format; + GstVaapiImage *surface_image; + GstVaapiSubpicture *subpicture; + gboolean success; - display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); - if (!display) - return FALSE; + display = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); + if (!display) + return FALSE; - format = gst_vaapi_image_get_format(image); - if (!format) - return FALSE; + format = gst_vaapi_image_get_format (image); + if (!format) + return FALSE; - if (gst_vaapi_surface_put_image(surface, image)) - return TRUE; - - surface_image = gst_vaapi_surface_derive_image(surface); - if (surface_image) { - success = gst_vaapi_image_copy(surface_image, image); - gst_vaapi_object_unref(surface_image); - if (success) - return TRUE; - } - - g_print("could not upload %s image to surface\n", - gst_vaapi_video_format_to_string(format)); - - if (!gst_vaapi_display_has_subpicture_format(display, format, NULL)) - return FALSE; - - g_print("trying as a subpicture\n"); - - subpicture = gst_vaapi_subpicture_new(image, 0); - if (!subpicture) - g_error("could not create VA subpicture"); - - if (!gst_vaapi_surface_associate_subpicture(surface, subpicture, - NULL, NULL)) - g_error("could not associate subpicture to surface"); - - /* The surface holds a reference to the subpicture. This is safe */ - gst_vaapi_object_unref(subpicture); + if (gst_vaapi_surface_put_image (surface, image)) return TRUE; + + surface_image = gst_vaapi_surface_derive_image (surface); + if (surface_image) { + success = gst_vaapi_image_copy (surface_image, image); + gst_vaapi_object_unref (surface_image); + if (success) + return TRUE; + } + + g_print ("could not upload %s image to surface\n", + gst_vaapi_video_format_to_string (format)); + + if (!gst_vaapi_display_has_subpicture_format (display, format, NULL)) + return FALSE; + + g_print ("trying as a subpicture\n"); + + subpicture = gst_vaapi_subpicture_new (image, 0); + if (!subpicture) + g_error ("could not create VA subpicture"); + + if (!gst_vaapi_surface_associate_subpicture (surface, subpicture, NULL, NULL)) + g_error ("could not associate subpicture to surface"); + + /* The surface holds a reference to the subpicture. This is safe */ + gst_vaapi_object_unref (subpicture); + return TRUE; } diff --git a/tests/output.c b/tests/output.c index 579e885068..b15dedec77 100644 --- a/tests/output.c +++ b/tests/output.c @@ -48,34 +48,30 @@ static const VideoOutputInfo *g_video_output; static const VideoOutputInfo g_video_outputs[] = { - /* Video outputs are sorted in test order for automatic characterisation */ + /* Video outputs are sorted in test order for automatic characterisation */ #if USE_WAYLAND - { "wayland", - gst_vaapi_display_wayland_new, - gst_vaapi_window_wayland_new - }, + {"wayland", + gst_vaapi_display_wayland_new, + gst_vaapi_window_wayland_new}, #endif #if USE_X11 - { "x11", - gst_vaapi_display_x11_new, - gst_vaapi_window_x11_new, - gst_vaapi_pixmap_x11_new - }, + {"x11", + gst_vaapi_display_x11_new, + gst_vaapi_window_x11_new, + gst_vaapi_pixmap_x11_new}, #endif #if USE_GLX - { "glx", - gst_vaapi_display_glx_new, - gst_vaapi_window_glx_new, - gst_vaapi_pixmap_x11_new - }, + {"glx", + gst_vaapi_display_glx_new, + gst_vaapi_window_glx_new, + gst_vaapi_pixmap_x11_new}, #endif #if USE_DRM - { "drm", - gst_vaapi_display_drm_new, - gst_vaapi_window_drm_new - }, + {"drm", + gst_vaapi_display_drm_new, + gst_vaapi_window_drm_new}, #endif - { NULL, } + {NULL,} }; static gchar *g_output_name; @@ -86,163 +82,164 @@ static gboolean g_egl_mode = FALSE; static guint g_gles_version; static GOptionEntry g_options[] = { - { "list-outputs", 0, - 0, - G_OPTION_ARG_NONE, &g_list_outputs, - "list video outputs", NULL }, - { "output", 'o', - 0, - G_OPTION_ARG_STRING, &g_output_name, - "video output name", NULL }, - { "fullscreen", 'f', - 0, - G_OPTION_ARG_NONE, &g_fullscreen, - "fullscreen mode", NULL }, - { "egl", 0, - 0, - G_OPTION_ARG_NONE, &g_egl_mode, - "enable EGL rendering", NULL }, - { "gles-version", 0, - 0, - G_OPTION_ARG_INT, &g_gles_version, - "OpenGL|ES version (in --egl mode)", NULL }, - { NULL, } + {"list-outputs", 0, + 0, + G_OPTION_ARG_NONE, &g_list_outputs, + "list video outputs", NULL}, + {"output", 'o', + 0, + G_OPTION_ARG_STRING, &g_output_name, + "video output name", NULL}, + {"fullscreen", 'f', + 0, + G_OPTION_ARG_NONE, &g_fullscreen, + "fullscreen mode", NULL}, + {"egl", 0, + 0, + G_OPTION_ARG_NONE, &g_egl_mode, + "enable EGL rendering", NULL}, + {"gles-version", 0, + 0, + G_OPTION_ARG_INT, &g_gles_version, + "OpenGL|ES version (in --egl mode)", NULL}, + {NULL,} }; static void -list_outputs(void) +list_outputs (void) { - const VideoOutputInfo *o; + const VideoOutputInfo *o; - g_print("Video outputs:"); - for (o = g_video_outputs; o->name != NULL; o++) - g_print(" %s", o->name); - g_print("\n"); + g_print ("Video outputs:"); + for (o = g_video_outputs; o->name != NULL; o++) + g_print (" %s", o->name); + g_print ("\n"); } gboolean -video_output_init(int *argc, char *argv[], GOptionEntry *options) +video_output_init (int *argc, char *argv[], GOptionEntry * options) { - GOptionContext *ctx; - gboolean success; + GOptionContext *ctx; + gboolean success; #if !GLIB_CHECK_VERSION(2,31,0) - if (!g_thread_supported()) - g_thread_init(NULL); + if (!g_thread_supported ()) + g_thread_init (NULL); #endif - ctx = g_option_context_new("- test options"); - if (!ctx) - return FALSE; + ctx = g_option_context_new ("- test options"); + if (!ctx) + return FALSE; - g_option_context_add_group(ctx, gst_init_get_option_group()); - g_option_context_add_main_entries(ctx, g_options, NULL); - if (options) - g_option_context_add_main_entries(ctx, options, NULL); - success = g_option_context_parse(ctx, argc, &argv, NULL); - g_option_context_free(ctx); + g_option_context_add_group (ctx, gst_init_get_option_group ()); + g_option_context_add_main_entries (ctx, g_options, NULL); + if (options) + g_option_context_add_main_entries (ctx, options, NULL); + success = g_option_context_parse (ctx, argc, &argv, NULL); + g_option_context_free (ctx); - if (g_list_outputs) { - list_outputs(); - exit(0); - } - return success; + if (g_list_outputs) { + list_outputs (); + exit (0); + } + return success; } void -video_output_exit(void) +video_output_exit (void) { - g_free(g_output_name); - gst_deinit(); + g_free (g_output_name); + gst_deinit (); } const VideoOutputInfo * -video_output_lookup(const gchar *output_name) +video_output_lookup (const gchar * output_name) { - const VideoOutputInfo *o; + const VideoOutputInfo *o; - if (!output_name) - return NULL; - - for (o = g_video_outputs; o->name != NULL; o++) { - if (g_ascii_strcasecmp(o->name, output_name) == 0) - return o; - } + if (!output_name) return NULL; + + for (o = g_video_outputs; o->name != NULL; o++) { + if (g_ascii_strcasecmp (o->name, output_name) == 0) + return o; + } + return NULL; } GstVaapiDisplay * -video_output_create_display(const gchar *display_name) +video_output_create_display (const gchar * display_name) { - const VideoOutputInfo *o = g_video_output; - GstVaapiDisplay *egl_display, *display = NULL; + const VideoOutputInfo *o = g_video_output; + GstVaapiDisplay *egl_display, *display = NULL; - if (!o) { - if (g_output_name) - o = video_output_lookup(g_output_name); - else { - for (o = g_video_outputs; o->name != NULL; o++) { - display = o->create_display(display_name); - if (display) { - if (gst_vaapi_display_get_display(display)) - break; - gst_vaapi_display_unref(display); - display = NULL; - } - } + if (!o) { + if (g_output_name) + o = video_output_lookup (g_output_name); + else { + for (o = g_video_outputs; o->name != NULL; o++) { + display = o->create_display (display_name); + if (display) { + if (gst_vaapi_display_get_display (display)) + break; + gst_vaapi_display_unref (display); + display = NULL; } - if (!o || !o->name) - return NULL; - g_print("Using %s video output\n", o->name); - g_video_output = o; + } } + if (!o || !o->name) + return NULL; + g_print ("Using %s video output\n", o->name); + g_video_output = o; + } - if (!display) - display = o->create_display(display_name); + if (!display) + display = o->create_display (display_name); - if (g_egl_mode) { + if (g_egl_mode) { #if USE_EGL - egl_display = gst_vaapi_display_egl_new (display, g_gles_version); + egl_display = gst_vaapi_display_egl_new (display, g_gles_version); #else - egl_display = NULL; - g_print("error: unsupported EGL renderering mode\n"); + egl_display = NULL; + g_print ("error: unsupported EGL renderering mode\n"); #endif - gst_vaapi_display_unref (display); - if (!egl_display) - return NULL; - display = egl_display; - } - return display; + gst_vaapi_display_unref (display); + if (!egl_display) + return NULL; + display = egl_display; + } + return display; } GstVaapiWindow * -video_output_create_window(GstVaapiDisplay *display, guint width, guint height) +video_output_create_window (GstVaapiDisplay * display, guint width, + guint height) { - GstVaapiWindow *window; + GstVaapiWindow *window; - if (!g_video_output) - return NULL; + if (!g_video_output) + return NULL; #if USE_EGL - if (g_egl_mode) - window = gst_vaapi_window_egl_new(display, width, height); - else + if (g_egl_mode) + window = gst_vaapi_window_egl_new (display, width, height); + else #endif - window = g_video_output->create_window(display, width, height); - if (!window) - return NULL; + window = g_video_output->create_window (display, width, height); + if (!window) + return NULL; - /* Force fullscreen mode, should this be requested by the user */ - if (g_fullscreen) - gst_vaapi_window_set_fullscreen(window, TRUE); - return window; + /* Force fullscreen mode, should this be requested by the user */ + if (g_fullscreen) + gst_vaapi_window_set_fullscreen (window, TRUE); + return window; } GstVaapiPixmap * -video_output_create_pixmap(GstVaapiDisplay *display, GstVideoFormat format, +video_output_create_pixmap (GstVaapiDisplay * display, GstVideoFormat format, guint width, guint height) { - if (!g_video_output || !g_video_output->create_pixmap) - return NULL; - return g_video_output->create_pixmap(display, format, width, height); + if (!g_video_output || !g_video_output->create_pixmap) + return NULL; + return g_video_output->create_pixmap (display, format, width, height); } diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index b8af44d7cd..52aab388e2 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -44,211 +44,214 @@ static gboolean g_use_pixmap; static gboolean g_benchmark; static GOptionEntry g_options[] = { - { "codec", 'c', - 0, - G_OPTION_ARG_STRING, &g_codec_str, - "suggested codec", NULL }, - { "pixmap", 0, - 0, - G_OPTION_ARG_NONE, &g_use_pixmap, - "use render-to-pixmap", NULL }, - { "benchmark", 0, - 0, - G_OPTION_ARG_NONE, &g_benchmark, - "benchmark mode", NULL }, - { NULL, } + {"codec", 'c', + 0, + G_OPTION_ARG_STRING, &g_codec_str, + "suggested codec", NULL}, + {"pixmap", 0, + 0, + G_OPTION_ARG_NONE, &g_use_pixmap, + "use render-to-pixmap", NULL}, + {"benchmark", 0, + 0, + G_OPTION_ARG_NONE, &g_benchmark, + "benchmark mode", NULL}, + {NULL,} }; -typedef enum { - APP_RUNNING, - APP_GOT_EOS, - APP_GOT_ERROR, +typedef enum +{ + APP_RUNNING, + APP_GOT_EOS, + APP_GOT_ERROR, } AppEvent; -typedef enum { - APP_ERROR_NONE, - APP_ERROR_DECODER, - APP_ERROR_RENDERER, +typedef enum +{ + APP_ERROR_NONE, + APP_ERROR_DECODER, + APP_ERROR_RENDERER, } AppError; -typedef struct { - GstVaapiSurfaceProxy *proxy; - GstClockTime pts; - GstClockTime duration; +typedef struct +{ + GstVaapiSurfaceProxy *proxy; + GstClockTime pts; + GstClockTime duration; } RenderFrame; -typedef struct { - GMutex mutex; - GMappedFile *file; - gchar *file_name; - guint file_offset; - guint file_size; - guchar *file_data; - GstVaapiDisplay *display; - GstVaapiDecoder *decoder; - GThread *decoder_thread; - volatile gboolean decoder_thread_cancel; - GCond decoder_ready; - GAsyncQueue *decoder_queue; - GstVaapiCodec codec; - guint fps_n; - guint fps_d; - guint32 frame_duration; - guint surface_width; - guint surface_height; - GstVaapiPixmap *pixmaps[2]; - guint pixmap_id; - guint pixmap_width; - guint pixmap_height; - GstVaapiWindow *window; - guint window_width; - guint window_height; - GThread *render_thread; - volatile gboolean render_thread_cancel; - GCond render_ready; - RenderFrame *last_frame; - GError *error; - AppEvent event; - GCond event_cond; - GTimer *timer; - guint32 num_frames; +typedef struct +{ + GMutex mutex; + GMappedFile *file; + gchar *file_name; + guint file_offset; + guint file_size; + guchar *file_data; + GstVaapiDisplay *display; + GstVaapiDecoder *decoder; + GThread *decoder_thread; + volatile gboolean decoder_thread_cancel; + GCond decoder_ready; + GAsyncQueue *decoder_queue; + GstVaapiCodec codec; + guint fps_n; + guint fps_d; + guint32 frame_duration; + guint surface_width; + guint surface_height; + GstVaapiPixmap *pixmaps[2]; + guint pixmap_id; + guint pixmap_width; + guint pixmap_height; + GstVaapiWindow *window; + guint window_width; + guint window_height; + GThread *render_thread; + volatile gboolean render_thread_cancel; + GCond render_ready; + RenderFrame *last_frame; + GError *error; + AppEvent event; + GCond event_cond; + GTimer *timer; + guint32 num_frames; } App; static inline RenderFrame * -render_frame_new(void) +render_frame_new (void) { - return g_slice_new(RenderFrame); + return g_slice_new (RenderFrame); } static void -render_frame_free(RenderFrame *rfp) +render_frame_free (RenderFrame * rfp) { - if (G_UNLIKELY(!rfp)) - return; - gst_vaapi_surface_proxy_replace(&rfp->proxy, NULL); - g_slice_free(RenderFrame, rfp); + if (G_UNLIKELY (!rfp)) + return; + gst_vaapi_surface_proxy_replace (&rfp->proxy, NULL); + g_slice_free (RenderFrame, rfp); } static inline void -render_frame_replace(RenderFrame **rfp_ptr, RenderFrame *new_rfp) +render_frame_replace (RenderFrame ** rfp_ptr, RenderFrame * new_rfp) { - if (*rfp_ptr) - render_frame_free(*rfp_ptr); - *rfp_ptr = new_rfp; + if (*rfp_ptr) + render_frame_free (*rfp_ptr); + *rfp_ptr = new_rfp; } #define APP_ERROR app_error_quark() static GQuark -app_error_quark(void) +app_error_quark (void) { - static gsize g_quark; + static gsize g_quark; - if (g_once_init_enter(&g_quark)) { - gsize quark = (gsize)g_quark_from_static_string("AppError"); - g_once_init_leave(&g_quark, quark); - } - return g_quark; + if (g_once_init_enter (&g_quark)) { + gsize quark = (gsize) g_quark_from_static_string ("AppError"); + g_once_init_leave (&g_quark, quark); + } + return g_quark; } static void -app_send_error(App *app, GError *error) +app_send_error (App * app, GError * error) { - g_mutex_lock(&app->mutex); - app->error = error; - app->event = APP_GOT_ERROR; - g_cond_signal(&app->event_cond); - g_mutex_unlock(&app->mutex); + g_mutex_lock (&app->mutex); + app->error = error; + app->event = APP_GOT_ERROR; + g_cond_signal (&app->event_cond); + g_mutex_unlock (&app->mutex); } static void -app_send_eos(App *app) +app_send_eos (App * app) { - g_mutex_lock(&app->mutex); - app->event = APP_GOT_EOS; - g_cond_signal(&app->event_cond); - g_mutex_unlock(&app->mutex); + g_mutex_lock (&app->mutex); + app->event = APP_GOT_EOS; + g_cond_signal (&app->event_cond); + g_mutex_unlock (&app->mutex); } static const gchar * -get_decoder_status_string(GstVaapiDecoderStatus status) +get_decoder_status_string (GstVaapiDecoderStatus status) { - const gchar *str; + const gchar *str; #define DEFINE_STATUS(status, status_string) \ case GST_VAAPI_DECODER_STATUS_##status: \ str = status_string; \ break - switch (status) { - DEFINE_STATUS(SUCCESS, ""); - DEFINE_STATUS(END_OF_STREAM, ""); - DEFINE_STATUS(ERROR_ALLOCATION_FAILED, "allocation failed"); - DEFINE_STATUS(ERROR_INIT_FAILED, "initialization failed"); - DEFINE_STATUS(ERROR_UNSUPPORTED_CODEC, "unsupported codec"); - DEFINE_STATUS(ERROR_NO_DATA, "not enough data"); - DEFINE_STATUS(ERROR_NO_SURFACE, "no surface vailable"); - DEFINE_STATUS(ERROR_INVALID_SURFACE, "invalid surface"); - DEFINE_STATUS(ERROR_BITSTREAM_PARSER, "bitstream parser error"); - DEFINE_STATUS(ERROR_UNSUPPORTED_PROFILE, - "unsupported profile"); - DEFINE_STATUS(ERROR_UNSUPPORTED_CHROMA_FORMAT, - "unsupported chroma-format"); - DEFINE_STATUS(ERROR_INVALID_PARAMETER, "invalid parameter"); + switch (status) { + DEFINE_STATUS (SUCCESS, ""); + DEFINE_STATUS (END_OF_STREAM, ""); + DEFINE_STATUS (ERROR_ALLOCATION_FAILED, "allocation failed"); + DEFINE_STATUS (ERROR_INIT_FAILED, "initialization failed"); + DEFINE_STATUS (ERROR_UNSUPPORTED_CODEC, "unsupported codec"); + DEFINE_STATUS (ERROR_NO_DATA, "not enough data"); + DEFINE_STATUS (ERROR_NO_SURFACE, "no surface vailable"); + DEFINE_STATUS (ERROR_INVALID_SURFACE, "invalid surface"); + DEFINE_STATUS (ERROR_BITSTREAM_PARSER, "bitstream parser error"); + DEFINE_STATUS (ERROR_UNSUPPORTED_PROFILE, "unsupported profile"); + DEFINE_STATUS (ERROR_UNSUPPORTED_CHROMA_FORMAT, + "unsupported chroma-format"); + DEFINE_STATUS (ERROR_INVALID_PARAMETER, "invalid parameter"); default: - str = ""; - break; - } + str = ""; + break; + } #undef DEFINE_STATUS - return str; + return str; } static const gchar * -get_error_string(AppError error) +get_error_string (AppError error) { - const gchar *str; + const gchar *str; #define DEFINE_ERROR(error, error_string) \ case APP_ERROR_##error: \ str = error_string; \ break - switch (error) { - DEFINE_ERROR(NONE, ""); - DEFINE_ERROR(DECODER, "decoder"); - DEFINE_ERROR(RENDERER, "renderer"); + switch (error) { + DEFINE_ERROR (NONE, ""); + DEFINE_ERROR (DECODER, "decoder"); + DEFINE_ERROR (RENDERER, "renderer"); default: - str = "unknown"; - break; - } + str = "unknown"; + break; + } #undef DEFINE_ERROR - return str; + return str; } static void -decoder_release(App *app) +decoder_release (App * app) { - g_mutex_lock(&app->mutex); - g_cond_signal(&app->decoder_ready); - g_mutex_unlock(&app->mutex); + g_mutex_lock (&app->mutex); + g_cond_signal (&app->decoder_ready); + g_mutex_unlock (&app->mutex); } static gpointer -decoder_thread(gpointer data) +decoder_thread (gpointer data) { - App * const app = data; - GError *error = NULL; - GstVaapiDecoderStatus status; - GstVaapiSurfaceProxy *proxy; - RenderFrame *rfp; - GstBuffer *buffer; - GstClockTime pts; - gboolean got_surface, got_eos = FALSE; - gint64 end_time; - guint ofs; + App *const app = data; + GError *error = NULL; + GstVaapiDecoderStatus status; + GstVaapiSurfaceProxy *proxy; + RenderFrame *rfp; + GstBuffer *buffer; + GstClockTime pts; + gboolean got_surface, got_eos = FALSE; + gint64 end_time; + guint ofs; - g_print("Decoder thread started\n"); + g_print ("Decoder thread started\n"); #define SEND_ERROR(...) \ do { \ @@ -256,236 +259,235 @@ decoder_thread(gpointer data) goto send_error; \ } while (0) - pts = g_get_monotonic_time(); - ofs = 0; - while (!app->decoder_thread_cancel) { - if (G_UNLIKELY(ofs == app->file_size)) - buffer = NULL; - else { - const gsize size = MIN(4096, app->file_size - ofs); - buffer = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY, - app->file_data, app->file_size, ofs, size, NULL, NULL); - if (!buffer) - SEND_ERROR("failed to allocate new buffer"); - ofs += size; - } - if (!gst_vaapi_decoder_put_buffer(app->decoder, buffer)) - SEND_ERROR("failed to push buffer to decoder"); - gst_buffer_replace(&buffer, NULL); - - get_surface: - status = gst_vaapi_decoder_get_surface(app->decoder, &proxy); - switch (status) { - case GST_VAAPI_DECODER_STATUS_SUCCESS: - gst_vaapi_surface_proxy_set_destroy_notify(proxy, - (GDestroyNotify)decoder_release, app); - rfp = render_frame_new(); - if (!rfp) - SEND_ERROR("failed to allocate render frame"); - rfp->proxy = proxy; - rfp->pts = pts; - rfp->duration = app->frame_duration; - pts += app->frame_duration; - g_async_queue_push(app->decoder_queue, rfp); - break; - case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: - /* nothing to do, just continue to the next iteration */ - break; - case GST_VAAPI_DECODER_STATUS_END_OF_STREAM: - gst_vaapi_decoder_flush(app->decoder); - if (got_eos) - goto send_eos; - got_eos = TRUE; - break; - case GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE: - end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND; - g_mutex_lock(&app->mutex); - got_surface = g_cond_wait_until(&app->decoder_ready, &app->mutex, - end_time); - g_mutex_unlock(&app->mutex); - if (got_surface) - goto get_surface; - SEND_ERROR("failed to acquire a surface within one second"); - break; - default: - SEND_ERROR("%s", get_decoder_status_string(status)); - break; - } + pts = g_get_monotonic_time (); + ofs = 0; + while (!app->decoder_thread_cancel) { + if (G_UNLIKELY (ofs == app->file_size)) + buffer = NULL; + else { + const gsize size = MIN (4096, app->file_size - ofs); + buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, + app->file_data, app->file_size, ofs, size, NULL, NULL); + if (!buffer) + SEND_ERROR ("failed to allocate new buffer"); + ofs += size; } - return NULL; + if (!gst_vaapi_decoder_put_buffer (app->decoder, buffer)) + SEND_ERROR ("failed to push buffer to decoder"); + gst_buffer_replace (&buffer, NULL); + + get_surface: + status = gst_vaapi_decoder_get_surface (app->decoder, &proxy); + switch (status) { + case GST_VAAPI_DECODER_STATUS_SUCCESS: + gst_vaapi_surface_proxy_set_destroy_notify (proxy, + (GDestroyNotify) decoder_release, app); + rfp = render_frame_new (); + if (!rfp) + SEND_ERROR ("failed to allocate render frame"); + rfp->proxy = proxy; + rfp->pts = pts; + rfp->duration = app->frame_duration; + pts += app->frame_duration; + g_async_queue_push (app->decoder_queue, rfp); + break; + case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: + /* nothing to do, just continue to the next iteration */ + break; + case GST_VAAPI_DECODER_STATUS_END_OF_STREAM: + gst_vaapi_decoder_flush (app->decoder); + if (got_eos) + goto send_eos; + got_eos = TRUE; + break; + case GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE: + end_time = g_get_monotonic_time () + G_TIME_SPAN_SECOND; + g_mutex_lock (&app->mutex); + got_surface = g_cond_wait_until (&app->decoder_ready, &app->mutex, + end_time); + g_mutex_unlock (&app->mutex); + if (got_surface) + goto get_surface; + SEND_ERROR ("failed to acquire a surface within one second"); + break; + default: + SEND_ERROR ("%s", get_decoder_status_string (status)); + break; + } + } + return NULL; #undef SEND_ERROR send_eos: - app_send_eos(app); - return NULL; + app_send_eos (app); + return NULL; send_error: - app_send_error(app, error); - return NULL; + app_send_error (app, error); + return NULL; } static void -app_set_framerate(App *app, guint fps_n, guint fps_d) +app_set_framerate (App * app, guint fps_n, guint fps_d) { - if (!fps_n || !fps_d) - return; + if (!fps_n || !fps_d) + return; - g_mutex_lock(&app->mutex); - if (fps_n != app->fps_n || fps_d != app->fps_d) { - app->fps_n = fps_n; - app->fps_d = fps_d; - app->frame_duration = gst_util_uint64_scale( - GST_TIME_AS_USECONDS(GST_SECOND), fps_d, fps_n); - } - g_mutex_unlock(&app->mutex); + g_mutex_lock (&app->mutex); + if (fps_n != app->fps_n || fps_d != app->fps_d) { + app->fps_n = fps_n; + app->fps_d = fps_d; + app->frame_duration = + gst_util_uint64_scale (GST_TIME_AS_USECONDS (GST_SECOND), fps_d, fps_n); + } + g_mutex_unlock (&app->mutex); } static void -handle_decoder_state_changes(GstVaapiDecoder *decoder, - const GstVideoCodecState *codec_state, gpointer user_data) +handle_decoder_state_changes (GstVaapiDecoder * decoder, + const GstVideoCodecState * codec_state, gpointer user_data) { - App * const app = user_data; + App *const app = user_data; - g_assert(app->decoder == decoder); - app_set_framerate(app, codec_state->info.fps_n, codec_state->info.fps_d); + g_assert (app->decoder == decoder); + app_set_framerate (app, codec_state->info.fps_n, codec_state->info.fps_d); } static gboolean -start_decoder(App *app) +start_decoder (App * app) { - GstCaps *caps; + GstCaps *caps; - app->file = g_mapped_file_new(app->file_name, FALSE, NULL); - if (!app->file) - return FALSE; + app->file = g_mapped_file_new (app->file_name, FALSE, NULL); + if (!app->file) + return FALSE; - app->file_size = g_mapped_file_get_length(app->file); - app->file_data = (guint8 *)g_mapped_file_get_contents(app->file); - if (!app->file_data) - return FALSE; + app->file_size = g_mapped_file_get_length (app->file); + app->file_data = (guint8 *) g_mapped_file_get_contents (app->file); + if (!app->file_data) + return FALSE; - caps = caps_from_codec(app->codec); - switch (app->codec) { + caps = caps_from_codec (app->codec); + switch (app->codec) { case GST_VAAPI_CODEC_H264: - app->decoder = gst_vaapi_decoder_h264_new(app->display, caps); - break; + app->decoder = gst_vaapi_decoder_h264_new (app->display, caps); + break; #if USE_JPEG_DECODER case GST_VAAPI_CODEC_JPEG: - app->decoder = gst_vaapi_decoder_jpeg_new(app->display, caps); - break; + app->decoder = gst_vaapi_decoder_jpeg_new (app->display, caps); + break; #endif case GST_VAAPI_CODEC_MPEG2: - app->decoder = gst_vaapi_decoder_mpeg2_new(app->display, caps); - break; + app->decoder = gst_vaapi_decoder_mpeg2_new (app->display, caps); + break; case GST_VAAPI_CODEC_MPEG4: - app->decoder = gst_vaapi_decoder_mpeg4_new(app->display, caps); - break; + app->decoder = gst_vaapi_decoder_mpeg4_new (app->display, caps); + break; case GST_VAAPI_CODEC_VC1: - app->decoder = gst_vaapi_decoder_vc1_new(app->display, caps); - break; + app->decoder = gst_vaapi_decoder_vc1_new (app->display, caps); + break; default: - app->decoder = NULL; - break; - } - if (!app->decoder) - return FALSE; + app->decoder = NULL; + break; + } + if (!app->decoder) + return FALSE; - gst_vaapi_decoder_set_codec_state_changed_func(app->decoder, - handle_decoder_state_changes, app); + gst_vaapi_decoder_set_codec_state_changed_func (app->decoder, + handle_decoder_state_changes, app); - g_timer_start(app->timer); + g_timer_start (app->timer); - app->decoder_thread = g_thread_try_new("Decoder Thread", decoder_thread, - app, NULL); - if (!app->decoder_thread) - return FALSE; - return TRUE; + app->decoder_thread = g_thread_try_new ("Decoder Thread", decoder_thread, + app, NULL); + if (!app->decoder_thread) + return FALSE; + return TRUE; } static gboolean -stop_decoder(App *app) +stop_decoder (App * app) { - g_timer_stop(app->timer); + g_timer_stop (app->timer); - app->decoder_thread_cancel = TRUE; - g_thread_join(app->decoder_thread); - g_print("Decoder thread stopped\n"); - return TRUE; + app->decoder_thread_cancel = TRUE; + g_thread_join (app->decoder_thread); + g_print ("Decoder thread stopped\n"); + return TRUE; } static void -ensure_window_size(App *app, GstVaapiSurface *surface) +ensure_window_size (App * app, GstVaapiSurface * surface) { - guint width, height; + guint width, height; - if (gst_vaapi_window_get_fullscreen(app->window)) - return; + if (gst_vaapi_window_get_fullscreen (app->window)) + return; - gst_vaapi_surface_get_size(surface, &width, &height); - if (app->surface_width == width && app->surface_height == height) - return; - app->surface_width = width; - app->surface_height = height; + gst_vaapi_surface_get_size (surface, &width, &height); + if (app->surface_width == width && app->surface_height == height) + return; + app->surface_width = width; + app->surface_height = height; - gst_vaapi_window_set_size(app->window, width, height); - gst_vaapi_window_get_size(app->window, - &app->window_width, &app->window_height); + gst_vaapi_window_set_size (app->window, width, height); + gst_vaapi_window_get_size (app->window, + &app->window_width, &app->window_height); } static gboolean -ensure_pixmaps(App *app, GstVaapiSurface *surface, - const GstVaapiRectangle *crop_rect) +ensure_pixmaps (App * app, GstVaapiSurface * surface, + const GstVaapiRectangle * crop_rect) { - GstVaapiPixmap *pixmaps[G_N_ELEMENTS(app->pixmaps)]; - guint num_pixmaps, i, width, height; - gboolean success = FALSE; + GstVaapiPixmap *pixmaps[G_N_ELEMENTS (app->pixmaps)]; + guint num_pixmaps, i, width, height; + gboolean success = FALSE; - if (crop_rect) { - width = crop_rect->width; - height = crop_rect->height; - } - else - gst_vaapi_surface_get_size(surface, &width, &height); - if (app->pixmap_width == width && app->pixmap_height == height) - return TRUE; + if (crop_rect) { + width = crop_rect->width; + height = crop_rect->height; + } else + gst_vaapi_surface_get_size (surface, &width, &height); + if (app->pixmap_width == width && app->pixmap_height == height) + return TRUE; - for (i = 0, num_pixmaps = 0; i < G_N_ELEMENTS(pixmaps); i++) { - GstVaapiPixmap * const pixmap = - video_output_create_pixmap(app->display, GST_VIDEO_FORMAT_xRGB, - width, height); - if (!pixmap) - goto end; - pixmaps[num_pixmaps++] = pixmap; - } + for (i = 0, num_pixmaps = 0; i < G_N_ELEMENTS (pixmaps); i++) { + GstVaapiPixmap *const pixmap = + video_output_create_pixmap (app->display, GST_VIDEO_FORMAT_xRGB, + width, height); + if (!pixmap) + goto end; + pixmaps[num_pixmaps++] = pixmap; + } - for (i = 0; i < num_pixmaps; i++) - gst_vaapi_pixmap_replace(&app->pixmaps[i], pixmaps[i]); - app->pixmap_width = width; - app->pixmap_height = height; - success = TRUE; + for (i = 0; i < num_pixmaps; i++) + gst_vaapi_pixmap_replace (&app->pixmaps[i], pixmaps[i]); + app->pixmap_width = width; + app->pixmap_height = height; + success = TRUE; end: - for (i = 0; i < num_pixmaps; i++) - gst_vaapi_pixmap_replace(&pixmaps[i], NULL); - return success; + for (i = 0; i < num_pixmaps; i++) + gst_vaapi_pixmap_replace (&pixmaps[i], NULL); + return success; } static inline void -renderer_wait_until(App *app, GstClockTime pts) +renderer_wait_until (App * app, GstClockTime pts) { - g_mutex_lock(&app->mutex); - do { - } while (g_cond_wait_until(&app->render_ready, &app->mutex, pts)); - g_mutex_unlock(&app->mutex); + g_mutex_lock (&app->mutex); + do { + } while (g_cond_wait_until (&app->render_ready, &app->mutex, pts)); + g_mutex_unlock (&app->mutex); } static gboolean -renderer_process(App *app, RenderFrame *rfp) +renderer_process (App * app, RenderFrame * rfp) { - GError *error = NULL; - GstVaapiSurface *surface; - const GstVaapiRectangle *crop_rect; + GError *error = NULL; + GstVaapiSurface *surface; + const GstVaapiRectangle *crop_rect; #define SEND_ERROR(...) \ do { \ @@ -493,290 +495,289 @@ renderer_process(App *app, RenderFrame *rfp) goto send_error; \ } while (0) - surface = gst_vaapi_surface_proxy_get_surface(rfp->proxy); - if (!surface) - SEND_ERROR("failed to get decoded surface from render frame"); + surface = gst_vaapi_surface_proxy_get_surface (rfp->proxy); + if (!surface) + SEND_ERROR ("failed to get decoded surface from render frame"); - ensure_window_size(app, surface); + ensure_window_size (app, surface); - crop_rect = gst_vaapi_surface_proxy_get_crop_rect(rfp->proxy); - if (g_use_pixmap && !ensure_pixmaps(app, surface, crop_rect)) - SEND_ERROR("failed to create intermediate pixmaps"); + crop_rect = gst_vaapi_surface_proxy_get_crop_rect (rfp->proxy); + if (g_use_pixmap && !ensure_pixmaps (app, surface, crop_rect)) + SEND_ERROR ("failed to create intermediate pixmaps"); - if (!gst_vaapi_surface_sync(surface)) - SEND_ERROR("failed to sync decoded surface"); + if (!gst_vaapi_surface_sync (surface)) + SEND_ERROR ("failed to sync decoded surface"); - if (G_LIKELY(!g_benchmark)) - renderer_wait_until(app, rfp->pts); + if (G_LIKELY (!g_benchmark)) + renderer_wait_until (app, rfp->pts); - if (G_UNLIKELY(g_use_pixmap)) { - GstVaapiPixmap * const pixmap = app->pixmaps[app->pixmap_id]; + if (G_UNLIKELY (g_use_pixmap)) { + GstVaapiPixmap *const pixmap = app->pixmaps[app->pixmap_id]; - if (!gst_vaapi_pixmap_put_surface(pixmap, surface, crop_rect, - GST_VAAPI_PICTURE_STRUCTURE_FRAME)) - SEND_ERROR("failed to render to pixmap"); + if (!gst_vaapi_pixmap_put_surface (pixmap, surface, crop_rect, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + SEND_ERROR ("failed to render to pixmap"); - if (!gst_vaapi_window_put_pixmap(app->window, pixmap, NULL, NULL)) - SEND_ERROR("failed to render surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(pixmap)); + if (!gst_vaapi_window_put_pixmap (app->window, pixmap, NULL, NULL)) + SEND_ERROR ("failed to render surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (pixmap)); - app->pixmap_id = (app->pixmap_id + 1) % G_N_ELEMENTS(app->pixmaps); - } - else if (!gst_vaapi_window_put_surface(app->window, surface, - crop_rect, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) - SEND_ERROR("failed to render surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); + app->pixmap_id = (app->pixmap_id + 1) % G_N_ELEMENTS (app->pixmaps); + } else if (!gst_vaapi_window_put_surface (app->window, surface, + crop_rect, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + SEND_ERROR ("failed to render surface %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (gst_vaapi_surface_get_id (surface))); - app->num_frames++; + app->num_frames++; - render_frame_replace(&app->last_frame, rfp); - return TRUE; + render_frame_replace (&app->last_frame, rfp); + return TRUE; #undef SEND_ERROR send_error: - app_send_error(app, error); - return FALSE; + app_send_error (app, error); + return FALSE; } static gpointer -renderer_thread(gpointer data) +renderer_thread (gpointer data) { - App * const app = data; - RenderFrame *rfp; + App *const app = data; + RenderFrame *rfp; - g_print("Render thread started\n"); + g_print ("Render thread started\n"); - while (!app->render_thread_cancel) { - rfp = g_async_queue_timeout_pop(app->decoder_queue, 1000000); - if (rfp && !renderer_process(app, rfp)) - break; - } - return NULL; + while (!app->render_thread_cancel) { + rfp = g_async_queue_timeout_pop (app->decoder_queue, 1000000); + if (rfp && !renderer_process (app, rfp)) + break; + } + return NULL; } static gboolean -flush_decoder_queue(App *app) +flush_decoder_queue (App * app) { - RenderFrame *rfp; + RenderFrame *rfp; - /* Flush pending surfaces */ - do { - rfp = g_async_queue_try_pop(app->decoder_queue); - if (!rfp) - return TRUE; - } while (renderer_process(app, rfp)); + /* Flush pending surfaces */ + do { + rfp = g_async_queue_try_pop (app->decoder_queue); + if (!rfp) + return TRUE; + } while (renderer_process (app, rfp)); + return FALSE; +} + +static gboolean +start_renderer (App * app) +{ + app->render_thread = g_thread_try_new ("Renderer Thread", renderer_thread, + app, NULL); + if (!app->render_thread) return FALSE; + return TRUE; } static gboolean -start_renderer(App *app) +stop_renderer (App * app) { - app->render_thread = g_thread_try_new("Renderer Thread", renderer_thread, - app, NULL); - if (!app->render_thread) - return FALSE; - return TRUE; -} + app->render_thread_cancel = TRUE; + g_thread_join (app->render_thread); -static gboolean -stop_renderer(App *app) -{ - app->render_thread_cancel = TRUE; - g_thread_join(app->render_thread); + g_print ("Render thread stopped\n"); - g_print("Render thread stopped\n"); - - flush_decoder_queue(app); - render_frame_replace(&app->last_frame, NULL); - return TRUE; + flush_decoder_queue (app); + render_frame_replace (&app->last_frame, NULL); + return TRUE; } static void -app_free(App *app) +app_free (App * app) { - guint i; + guint i; - if (!app) - return; + if (!app) + return; - if (app->file) { - g_mapped_file_unref(app->file); - app->file = NULL; - } - g_free(app->file_name); + if (app->file) { + g_mapped_file_unref (app->file); + app->file = NULL; + } + g_free (app->file_name); - for (i = 0; i < G_N_ELEMENTS(app->pixmaps); i++) - gst_vaapi_pixmap_replace(&app->pixmaps[i], NULL); - gst_vaapi_decoder_replace(&app->decoder, NULL); - gst_vaapi_window_replace(&app->window, NULL); - gst_vaapi_display_replace(&app->display, NULL); + for (i = 0; i < G_N_ELEMENTS (app->pixmaps); i++) + gst_vaapi_pixmap_replace (&app->pixmaps[i], NULL); + gst_vaapi_decoder_replace (&app->decoder, NULL); + gst_vaapi_window_replace (&app->window, NULL); + gst_vaapi_display_replace (&app->display, NULL); - if (app->decoder_queue) { - g_async_queue_unref(app->decoder_queue); - app->decoder_queue = NULL; - } - g_cond_clear(&app->decoder_ready); + if (app->decoder_queue) { + g_async_queue_unref (app->decoder_queue); + app->decoder_queue = NULL; + } + g_cond_clear (&app->decoder_ready); - if (app->timer) { - g_timer_destroy(app->timer); - app->timer = NULL; - } + if (app->timer) { + g_timer_destroy (app->timer); + app->timer = NULL; + } - g_cond_clear(&app->render_ready); - g_cond_clear(&app->event_cond); - g_mutex_clear(&app->mutex); - g_slice_free(App, app); + g_cond_clear (&app->render_ready); + g_cond_clear (&app->event_cond); + g_mutex_clear (&app->mutex); + g_slice_free (App, app); } static App * -app_new(void) +app_new (void) { - App *app; + App *app; - app = g_slice_new0(App); - if (!app) - return NULL; + app = g_slice_new0 (App); + if (!app) + return NULL; - g_mutex_init(&app->mutex); - g_cond_init(&app->event_cond); - g_cond_init(&app->decoder_ready); - g_cond_init(&app->render_ready); + g_mutex_init (&app->mutex); + g_cond_init (&app->event_cond); + g_cond_init (&app->decoder_ready); + g_cond_init (&app->render_ready); - app_set_framerate(app, 60, 1); - app->window_width = 640; - app->window_height = 480; + app_set_framerate (app, 60, 1); + app->window_width = 640; + app->window_height = 480; - app->decoder_queue = g_async_queue_new_full( - (GDestroyNotify)render_frame_free); - if (!app->decoder_queue) - goto error; + app->decoder_queue = g_async_queue_new_full ( + (GDestroyNotify) render_frame_free); + if (!app->decoder_queue) + goto error; - app->timer = g_timer_new(); - if (!app->timer) - goto error; - return app; + app->timer = g_timer_new (); + if (!app->timer) + goto error; + return app; error: - app_free(app); - return NULL; + app_free (app); + return NULL; } static gboolean -app_check_events(App *app) +app_check_events (App * app) { - GError *error = NULL; - gboolean stop = FALSE; + GError *error = NULL; + gboolean stop = FALSE; - do { - g_mutex_lock(&app->mutex); - while (app->event == APP_RUNNING) - g_cond_wait(&app->event_cond, &app->mutex); + do { + g_mutex_lock (&app->mutex); + while (app->event == APP_RUNNING) + g_cond_wait (&app->event_cond, &app->mutex); - switch (app->event) { - case APP_GOT_ERROR: - error = app->error; - app->error = NULL; - /* fall-through */ - case APP_GOT_EOS: - stop = TRUE; - break; - default: - break; - } - g_mutex_unlock(&app->mutex); - } while (!stop); - - if (!error) - return TRUE; - - g_message("%s error: %s", get_error_string(error->code), error->message); - g_error_free(error); - return FALSE; -} - -static gboolean -app_run(App *app, int argc, char *argv[]) -{ - if (argc < 2) { - g_message("no bitstream file specified"); - return FALSE; + switch (app->event) { + case APP_GOT_ERROR: + error = app->error; + app->error = NULL; + /* fall-through */ + case APP_GOT_EOS: + stop = TRUE; + break; + default: + break; } - app->file_name = g_strdup(argv[1]); + g_mutex_unlock (&app->mutex); + } while (!stop); - if (!g_file_test(app->file_name, G_FILE_TEST_IS_REGULAR)) { - g_message("failed to find file '%s'", app->file_name); - return FALSE; - } - - app->codec = identify_codec(app->file_name); - if (!app->codec) { - app->codec = identify_codec_from_string(g_codec_str); - if (!app->codec) { - g_message("failed to identify codec for '%s'", app->file_name); - return FALSE; - } - } - - g_print("Simple decoder (%s bitstream)\n", string_from_codec(app->codec)); - - app->display = video_output_create_display(NULL); - if (!app->display) { - g_message("failed to create VA display"); - return FALSE; - } - - app->window = video_output_create_window(app->display, - app->window_width, app->window_height); - if (!app->window) { - g_message("failed to create window"); - return FALSE; - } - - gst_vaapi_window_show(app->window); - - if (!start_decoder(app)) { - g_message("failed to start decoder thread"); - return FALSE; - } - - if (!start_renderer(app)) { - g_message("failed to start renderer thread"); - return FALSE; - } - - app_check_events(app); - - stop_renderer(app); - stop_decoder(app); - - g_print("Decoded %u frames", app->num_frames); - if (g_benchmark) { - const gdouble elapsed = g_timer_elapsed(app->timer, NULL); - g_print(" in %.2f sec (%.1f fps)\n", - elapsed, (gdouble)app->num_frames / elapsed); - } - g_print("\n"); + if (!error) return TRUE; + + g_message ("%s error: %s", get_error_string (error->code), error->message); + g_error_free (error); + return FALSE; +} + +static gboolean +app_run (App * app, int argc, char *argv[]) +{ + if (argc < 2) { + g_message ("no bitstream file specified"); + return FALSE; + } + app->file_name = g_strdup (argv[1]); + + if (!g_file_test (app->file_name, G_FILE_TEST_IS_REGULAR)) { + g_message ("failed to find file '%s'", app->file_name); + return FALSE; + } + + app->codec = identify_codec (app->file_name); + if (!app->codec) { + app->codec = identify_codec_from_string (g_codec_str); + if (!app->codec) { + g_message ("failed to identify codec for '%s'", app->file_name); + return FALSE; + } + } + + g_print ("Simple decoder (%s bitstream)\n", string_from_codec (app->codec)); + + app->display = video_output_create_display (NULL); + if (!app->display) { + g_message ("failed to create VA display"); + return FALSE; + } + + app->window = video_output_create_window (app->display, + app->window_width, app->window_height); + if (!app->window) { + g_message ("failed to create window"); + return FALSE; + } + + gst_vaapi_window_show (app->window); + + if (!start_decoder (app)) { + g_message ("failed to start decoder thread"); + return FALSE; + } + + if (!start_renderer (app)) { + g_message ("failed to start renderer thread"); + return FALSE; + } + + app_check_events (app); + + stop_renderer (app); + stop_decoder (app); + + g_print ("Decoded %u frames", app->num_frames); + if (g_benchmark) { + const gdouble elapsed = g_timer_elapsed (app->timer, NULL); + g_print (" in %.2f sec (%.1f fps)\n", + elapsed, (gdouble) app->num_frames / elapsed); + } + g_print ("\n"); + return TRUE; } int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { - App *app; - gint ret; + App *app; + gint ret; - if (!video_output_init(&argc, argv, g_options)) - g_error("failed to initialize video output subsystem"); + if (!video_output_init (&argc, argv, g_options)) + g_error ("failed to initialize video output subsystem"); - app = app_new(); - if (!app) - g_error("failed to create application context"); + app = app_new (); + if (!app) + g_error ("failed to create application context"); - ret = !app_run(app, argc, argv); + ret = !app_run (app, argc, argv); - app_free(app); - g_free(g_codec_str); - video_output_exit(); - return ret; + app_free (app); + g_free (g_codec_str); + video_output_exit (); + return ret; } diff --git a/tests/test-decode.c b/tests/test-decode.c index db75fd828d..882bfd2e2b 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -31,115 +31,114 @@ /* Set to 1 to check display cache works (shared VA display) */ #define CHECK_DISPLAY_CACHE 1 -static inline void pause(void) +static inline void +pause (void) { - g_print("Press any key to continue...\n"); - getchar(); + g_print ("Press any key to continue...\n"); + getchar (); } static gchar *g_codec_str; static gboolean g_use_pixmap; static GOptionEntry g_options[] = { - { "codec", 'c', - 0, - G_OPTION_ARG_STRING, &g_codec_str, - "codec to test", NULL }, - { "pixmap", 0, - 0, - G_OPTION_ARG_NONE, &g_use_pixmap, - "use render-to-pixmap", NULL }, - { NULL, } + {"codec", 'c', + 0, + G_OPTION_ARG_STRING, &g_codec_str, + "codec to test", NULL}, + {"pixmap", 0, + 0, + G_OPTION_ARG_NONE, &g_use_pixmap, + "use render-to-pixmap", NULL}, + {NULL,} }; int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { - GstVaapiDisplay *display, *display2; - GstVaapiWindow *window; - GstVaapiPixmap *pixmap = NULL; - GstVaapiDecoder *decoder; - GstVaapiSurfaceProxy *proxy; - GstVaapiSurface *surface; - const GstVaapiRectangle *crop_rect; + GstVaapiDisplay *display, *display2; + GstVaapiWindow *window; + GstVaapiPixmap *pixmap = NULL; + GstVaapiDecoder *decoder; + GstVaapiSurfaceProxy *proxy; + GstVaapiSurface *surface; + const GstVaapiRectangle *crop_rect; - static const guint win_width = 640; - static const guint win_height = 480; + static const guint win_width = 640; + static const guint win_height = 480; - if (!video_output_init(&argc, argv, g_options)) - g_error("failed to initialize video output subsystem"); + if (!video_output_init (&argc, argv, g_options)) + g_error ("failed to initialize video output subsystem"); - g_print("Test decode\n"); + g_print ("Test decode\n"); - display = video_output_create_display(NULL); - if (!display) - g_error("could not create VA display"); + display = video_output_create_display (NULL); + if (!display) + g_error ("could not create VA display"); - if (CHECK_DISPLAY_CACHE) - display2 = video_output_create_display(NULL); - else - display2 = gst_vaapi_display_ref(display); - if (!display2) - g_error("could not create second VA display"); + if (CHECK_DISPLAY_CACHE) + display2 = video_output_create_display (NULL); + else + display2 = gst_vaapi_display_ref (display); + if (!display2) + g_error ("could not create second VA display"); - window = video_output_create_window(display, win_width, win_height); - if (!window) - g_error("could not create window"); + window = video_output_create_window (display, win_width, win_height); + if (!window) + g_error ("could not create window"); - decoder = decoder_new(display, g_codec_str); - if (!decoder) - g_error("could not create decoder"); + decoder = decoder_new (display, g_codec_str); + if (!decoder) + g_error ("could not create decoder"); - g_print("Decode %s sample frame\n", decoder_get_codec_name(decoder)); + g_print ("Decode %s sample frame\n", decoder_get_codec_name (decoder)); - if (!decoder_put_buffers(decoder)) - g_error("could not fill decoder with sample data"); + if (!decoder_put_buffers (decoder)) + g_error ("could not fill decoder with sample data"); - proxy = decoder_get_surface(decoder); - if (!proxy) - g_error("could not get decoded surface"); + proxy = decoder_get_surface (decoder); + if (!proxy) + g_error ("could not get decoded surface"); - surface = gst_vaapi_surface_proxy_get_surface(proxy); - crop_rect = gst_vaapi_surface_proxy_get_crop_rect(proxy); + surface = gst_vaapi_surface_proxy_get_surface (proxy); + crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy); - gst_vaapi_window_show(window); + gst_vaapi_window_show (window); - if (g_use_pixmap) { - guint width, height; + if (g_use_pixmap) { + guint width, height; - if (crop_rect) { - width = crop_rect->width; - height = crop_rect->height; - } - else - gst_vaapi_surface_get_size(surface, &width, &height); + if (crop_rect) { + width = crop_rect->width; + height = crop_rect->height; + } else + gst_vaapi_surface_get_size (surface, &width, &height); - pixmap = video_output_create_pixmap(display, GST_VIDEO_FORMAT_xRGB, - width, height); - if (!pixmap) - g_error("could not create pixmap"); + pixmap = video_output_create_pixmap (display, GST_VIDEO_FORMAT_xRGB, + width, height); + if (!pixmap) + g_error ("could not create pixmap"); - if (!gst_vaapi_pixmap_put_surface(pixmap, surface, crop_rect, - GST_VAAPI_PICTURE_STRUCTURE_FRAME)) - g_error("could not render to pixmap"); - - if (!gst_vaapi_window_put_pixmap(window, pixmap, NULL, NULL)) - g_error("could not render pixmap"); - } - else if (!gst_vaapi_window_put_surface(window, surface, crop_rect, NULL, + if (!gst_vaapi_pixmap_put_surface (pixmap, surface, crop_rect, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) - g_error("could not render surface"); + g_error ("could not render to pixmap"); - pause(); + if (!gst_vaapi_window_put_pixmap (window, pixmap, NULL, NULL)) + g_error ("could not render pixmap"); + } else if (!gst_vaapi_window_put_surface (window, surface, crop_rect, NULL, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + g_error ("could not render surface"); - if (pixmap) - gst_vaapi_pixmap_unref(pixmap); - gst_vaapi_surface_proxy_unref(proxy); - gst_vaapi_decoder_unref(decoder); - gst_vaapi_window_unref(window); - gst_vaapi_display_unref(display); - gst_vaapi_display_unref(display2); - g_free(g_codec_str); - video_output_exit(); - return 0; + pause (); + + if (pixmap) + gst_vaapi_pixmap_unref (pixmap); + gst_vaapi_surface_proxy_unref (proxy); + gst_vaapi_decoder_unref (decoder); + gst_vaapi_window_unref (window); + gst_vaapi_display_unref (display); + gst_vaapi_display_unref (display2); + g_free (g_codec_str); + video_output_exit (); + return 0; } diff --git a/tests/test-display.c b/tests/test-display.c index 2ab97dc961..4a995b25f6 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -54,514 +54,512 @@ #define CHECK_DISPLAY_CACHE 1 static void -print_value(const GValue *value, const gchar *name) +print_value (const GValue * value, const gchar * name) { - gchar *value_string; + gchar *value_string; - value_string = g_strdup_value_contents(value); - if (!value_string) - return; - g_print(" %s: %s\n", name, value_string); - g_free(value_string); + value_string = g_strdup_value_contents (value); + if (!value_string) + return; + g_print (" %s: %s\n", name, value_string); + g_free (value_string); } static void -print_profiles(GArray *profiles, const gchar *name) +print_profiles (GArray * profiles, const gchar * name) { - GstVaapiCodec codec; - const gchar *codec_name, *profile_name; - guint i; + GstVaapiCodec codec; + const gchar *codec_name, *profile_name; + guint i; - g_print("%u %s caps\n", profiles->len, name); + g_print ("%u %s caps\n", profiles->len, name); - for (i = 0; i < profiles->len; i++) { - const GstVaapiProfile profile = - g_array_index(profiles, GstVaapiProfile, i); + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index (profiles, GstVaapiProfile, i); - codec = gst_vaapi_profile_get_codec(profile); - if (!codec) - continue; + codec = gst_vaapi_profile_get_codec (profile); + if (!codec) + continue; - codec_name = gst_vaapi_codec_get_name(codec); - if (!codec_name) - continue; + codec_name = gst_vaapi_codec_get_name (codec); + if (!codec_name) + continue; - profile_name = gst_vaapi_profile_get_name(profile); - if (!profile_name) - continue; + profile_name = gst_vaapi_profile_get_name (profile); + if (!profile_name) + continue; - g_print(" %s: %s profile\n", codec_name, profile_name); - } + g_print (" %s: %s profile\n", codec_name, profile_name); + } } static void -print_format_yuv(const VAImageFormat *va_format) +print_format_yuv (const VAImageFormat * va_format) { - const guint32 fourcc = va_format->fourcc; + const guint32 fourcc = va_format->fourcc; - g_print(" fourcc '%c%c%c%c'", - fourcc & 0xff, - (fourcc >> 8) & 0xff, - (fourcc >> 16) & 0xff, - (fourcc >> 24) & 0xff); + g_print (" fourcc '%c%c%c%c'", + fourcc & 0xff, + (fourcc >> 8) & 0xff, (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff); } static void -print_format_rgb(const VAImageFormat *va_format) +print_format_rgb (const VAImageFormat * va_format) { - g_print(" %d bits per pixel, %s endian,", - va_format->bits_per_pixel, - va_format->byte_order == VA_MSB_FIRST ? "big" : "little"); - g_print(" %s masks", va_format->alpha_mask ? "rgba" : "rgb"); - g_print(" 0x%08x 0x%08x 0x%08x", - va_format->red_mask, va_format->green_mask, va_format->blue_mask); - if (va_format->alpha_mask) - g_print(" 0x%08x", va_format->alpha_mask); + g_print (" %d bits per pixel, %s endian,", + va_format->bits_per_pixel, + va_format->byte_order == VA_MSB_FIRST ? "big" : "little"); + g_print (" %s masks", va_format->alpha_mask ? "rgba" : "rgb"); + g_print (" 0x%08x 0x%08x 0x%08x", + va_format->red_mask, va_format->green_mask, va_format->blue_mask); + if (va_format->alpha_mask) + g_print (" 0x%08x", va_format->alpha_mask); } static void -print_formats(GArray *formats, const gchar *name) +print_formats (GArray * formats, const gchar * name) { - guint i; + guint i; - g_print("%u %s caps\n", formats->len, name); + g_print ("%u %s caps\n", formats->len, name); - for (i = 0; i < formats->len; i++) { - const GstVideoFormat format = g_array_index(formats, GstVideoFormat, i); - const VAImageFormat *va_format; + for (i = 0; i < formats->len; i++) { + const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); + const VAImageFormat *va_format; - g_print(" %s:", gst_vaapi_video_format_to_string(format)); + g_print (" %s:", gst_vaapi_video_format_to_string (format)); - va_format = gst_vaapi_video_format_to_va_format(format); - if (!va_format) - g_error("could not determine VA format"); + va_format = gst_vaapi_video_format_to_va_format (format); + if (!va_format) + g_error ("could not determine VA format"); - if (gst_vaapi_video_format_is_yuv(format)) - print_format_yuv(va_format); - else - print_format_rgb(va_format); - g_print("\n"); - } + if (gst_vaapi_video_format_is_yuv (format)) + print_format_yuv (va_format); + else + print_format_rgb (va_format); + g_print ("\n"); + } } typedef struct _GstVaapiDisplayProperty GstVaapiDisplayProperty; -struct _GstVaapiDisplayProperty { - const gchar *name; - GValue value; +struct _GstVaapiDisplayProperty +{ + const gchar *name; + GValue value; }; static void -gst_vaapi_display_property_free(GstVaapiDisplayProperty *prop) +gst_vaapi_display_property_free (GstVaapiDisplayProperty * prop) { - if (!prop) - return; - g_value_unset(&prop->value); - g_slice_free(GstVaapiDisplayProperty, prop); + if (!prop) + return; + g_value_unset (&prop->value); + g_slice_free (GstVaapiDisplayProperty, prop); } static GstVaapiDisplayProperty * -gst_vaapi_display_property_new(const gchar *name) +gst_vaapi_display_property_new (const gchar * name) { - GstVaapiDisplayProperty *prop; + GstVaapiDisplayProperty *prop; - prop = g_slice_new0(GstVaapiDisplayProperty); - if (!prop) - return NULL; - prop->name = name; - return prop; + prop = g_slice_new0 (GstVaapiDisplayProperty); + if (!prop) + return NULL; + prop->name = name; + return prop; } static void -free_property_cb(gpointer data, gpointer user_data) +free_property_cb (gpointer data, gpointer user_data) { - gst_vaapi_display_property_free(data); + gst_vaapi_display_property_free (data); } static void -dump_properties(GstVaapiDisplay *display) +dump_properties (GstVaapiDisplay * display) { - GstVaapiDisplayProperty *prop; - GPtrArray *properties; - guint i; + GstVaapiDisplayProperty *prop; + GPtrArray *properties; + guint i; - static const gchar *g_properties[] = { - GST_VAAPI_DISPLAY_PROP_RENDER_MODE, - GST_VAAPI_DISPLAY_PROP_ROTATION, - GST_VAAPI_DISPLAY_PROP_HUE, - GST_VAAPI_DISPLAY_PROP_SATURATION, - GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, - GST_VAAPI_DISPLAY_PROP_CONTRAST, - NULL - }; + static const gchar *g_properties[] = { + GST_VAAPI_DISPLAY_PROP_RENDER_MODE, + GST_VAAPI_DISPLAY_PROP_ROTATION, + GST_VAAPI_DISPLAY_PROP_HUE, + GST_VAAPI_DISPLAY_PROP_SATURATION, + GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, + GST_VAAPI_DISPLAY_PROP_CONTRAST, + NULL + }; - properties = g_ptr_array_new(); - if (!properties) - return; + properties = g_ptr_array_new (); + if (!properties) + return; - for (i = 0; g_properties[i] != NULL; i++) { - const gchar * const name = g_properties[i]; + for (i = 0; g_properties[i] != NULL; i++) { + const gchar *const name = g_properties[i]; - if (!gst_vaapi_display_has_property(display, name)) - continue; - - prop = gst_vaapi_display_property_new(name); - if (!prop) { - GST_ERROR("failed to allocate GstVaapiDisplayProperty"); - goto end; - } + if (!gst_vaapi_display_has_property (display, name)) + continue; - if (!gst_vaapi_display_get_property(display, name, &prop->value)) { - GST_ERROR("failed to get property '%s'", name); - goto end; - } - g_ptr_array_add(properties, prop); + prop = gst_vaapi_display_property_new (name); + if (!prop) { + GST_ERROR ("failed to allocate GstVaapiDisplayProperty"); + goto end; } - g_print("%u properties\n", properties->len); - for (i = 0; i < properties->len; i++) { - prop = g_ptr_array_index(properties, i); - print_value(&prop->value, prop->name); + if (!gst_vaapi_display_get_property (display, name, &prop->value)) { + GST_ERROR ("failed to get property '%s'", name); + goto end; } + g_ptr_array_add (properties, prop); + } + + g_print ("%u properties\n", properties->len); + for (i = 0; i < properties->len; i++) { + prop = g_ptr_array_index (properties, i); + print_value (&prop->value, prop->name); + } end: - if (properties) { - g_ptr_array_foreach(properties, free_property_cb, NULL); - g_ptr_array_free(properties, TRUE); - } + if (properties) { + g_ptr_array_foreach (properties, free_property_cb, NULL); + g_ptr_array_free (properties, TRUE); + } } static void -dump_info(GstVaapiDisplay *display) +dump_info (GstVaapiDisplay * display) { - GArray *profiles, *formats; + GArray *profiles, *formats; - profiles = gst_vaapi_display_get_decode_profiles(display); - if (!profiles) - g_error("could not get VA decode profiles"); + profiles = gst_vaapi_display_get_decode_profiles (display); + if (!profiles) + g_error ("could not get VA decode profiles"); - print_profiles(profiles, "decoders"); - g_array_unref(profiles); + print_profiles (profiles, "decoders"); + g_array_unref (profiles); - profiles = gst_vaapi_display_get_encode_profiles(display); - if (!profiles) - g_error("could not get VA encode profiles"); + profiles = gst_vaapi_display_get_encode_profiles (display); + if (!profiles) + g_error ("could not get VA encode profiles"); - print_profiles(profiles, "encoders"); - g_array_unref(profiles); + print_profiles (profiles, "encoders"); + g_array_unref (profiles); - formats = gst_vaapi_display_get_image_formats(display); - if (!formats) - g_error("could not get VA image formats"); + formats = gst_vaapi_display_get_image_formats (display); + if (!formats) + g_error ("could not get VA image formats"); - print_formats(formats, "image"); - g_array_unref(formats); + print_formats (formats, "image"); + g_array_unref (formats); - formats = gst_vaapi_display_get_subpicture_formats(display); - if (!formats) - g_error("could not get VA subpicture formats"); + formats = gst_vaapi_display_get_subpicture_formats (display); + if (!formats) + g_error ("could not get VA subpicture formats"); - print_formats(formats, "subpicture"); - g_array_unref(formats); + print_formats (formats, "subpicture"); + g_array_unref (formats); - dump_properties(display); + dump_properties (display); } int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { - GstVaapiDisplay *display, *display2; - guint width, height, par_n, par_d; + GstVaapiDisplay *display, *display2; + guint width, height, par_n, par_d; - gst_init(&argc, &argv); + gst_init (&argc, &argv); #if USE_DRM - g_print("#\n"); - g_print("# Create display with gst_vaapi_display_drm_new()\n"); - g_print("#\n"); - { - display = gst_vaapi_display_drm_new(NULL); - if (!display) - g_error("could not create Gst/VA display"); + g_print ("#\n"); + g_print ("# Create display with gst_vaapi_display_drm_new()\n"); + g_print ("#\n"); + { + display = gst_vaapi_display_drm_new (NULL); + if (!display) + g_error ("could not create Gst/VA display"); - dump_info(display); - gst_vaapi_display_unref(display); - } - g_print("\n"); + dump_info (display); + gst_vaapi_display_unref (display); + } + g_print ("\n"); - g_print("#\n"); - g_print("# Create display with gst_vaapi_display_drm_new_with_device()\n"); - g_print("#\n"); - { - int drm_device; + g_print ("#\n"); + g_print ("# Create display with gst_vaapi_display_drm_new_with_device()\n"); + g_print ("#\n"); + { + int drm_device; - drm_device = open(DRM_DEVICE_PATH, O_RDWR|O_CLOEXEC); - if (drm_device < 0) - g_error("could not open DRM device"); + drm_device = open (DRM_DEVICE_PATH, O_RDWR | O_CLOEXEC); + if (drm_device < 0) + g_error ("could not open DRM device"); - display = gst_vaapi_display_drm_new_with_device(drm_device); - if (!display) - g_error("could not create Gst/VA display"); + display = gst_vaapi_display_drm_new_with_device (drm_device); + if (!display) + g_error ("could not create Gst/VA display"); - dump_info(display); - gst_vaapi_display_unref(display); - close(drm_device); - } - g_print("\n"); + dump_info (display); + gst_vaapi_display_unref (display); + close (drm_device); + } + g_print ("\n"); - g_print("#\n"); - g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayDRM()]\n"); - g_print("#\n"); - { - int drm_device; - VADisplay va_display; + g_print ("#\n"); + g_print + ("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayDRM()]\n"); + g_print ("#\n"); + { + int drm_device; + VADisplay va_display; - drm_device = open(DRM_DEVICE_PATH, O_RDWR|O_CLOEXEC); - if (drm_device < 0) - g_error("could not open DRM device"); + drm_device = open (DRM_DEVICE_PATH, O_RDWR | O_CLOEXEC); + if (drm_device < 0) + g_error ("could not open DRM device"); - va_display = vaGetDisplayDRM(drm_device); - if (!va_display) - g_error("could not create VA display"); + va_display = vaGetDisplayDRM (drm_device); + if (!va_display) + g_error ("could not create VA display"); - display = gst_vaapi_display_new_with_display(va_display); - if (!display) - g_error("could not create Gst/VA display"); + display = gst_vaapi_display_new_with_display (va_display); + if (!display) + g_error ("could not create Gst/VA display"); - dump_info(display); - gst_vaapi_display_unref(display); - close(drm_device); - } - g_print("\n"); + dump_info (display); + gst_vaapi_display_unref (display); + close (drm_device); + } + g_print ("\n"); #endif #if USE_X11 - g_print("#\n"); - g_print("# Create display with gst_vaapi_display_x11_new()\n"); - g_print("#\n"); - { - display = gst_vaapi_display_x11_new(NULL); - if (!display) - g_error("could not create Gst/VA display"); + g_print ("#\n"); + g_print ("# Create display with gst_vaapi_display_x11_new()\n"); + g_print ("#\n"); + { + display = gst_vaapi_display_x11_new (NULL); + if (!display) + g_error ("could not create Gst/VA display"); - if (CHECK_DISPLAY_CACHE) { - display2 = gst_vaapi_display_x11_new(NULL); + if (CHECK_DISPLAY_CACHE) { + display2 = gst_vaapi_display_x11_new (NULL); - /* Check for the same X11 display */ - g_assert(gst_vaapi_display_x11_get_display( - GST_VAAPI_DISPLAY_X11(display)) == - gst_vaapi_display_x11_get_display( - GST_VAAPI_DISPLAY_X11(display2))); + /* Check for the same X11 display */ + g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 + (display)) == + gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2))); - /* Check for the same VA display */ - g_assert(gst_vaapi_display_get_display(display) == - gst_vaapi_display_get_display(display2)); + /* Check for the same VA display */ + g_assert (gst_vaapi_display_get_display (display) == + gst_vaapi_display_get_display (display2)); - gst_vaapi_display_unref(display2); + gst_vaapi_display_unref (display2); #if USE_GLX - display2 = gst_vaapi_display_glx_new(NULL); + display2 = gst_vaapi_display_glx_new (NULL); - /* Check for the different X11 display */ - /* XXX: it is also desired to cache underlying X11 displays */ - g_assert(gst_vaapi_display_x11_get_display( - GST_VAAPI_DISPLAY_X11(display)) != - gst_vaapi_display_x11_get_display( - GST_VAAPI_DISPLAY_X11(display2))); + /* Check for the different X11 display */ + /* XXX: it is also desired to cache underlying X11 displays */ + g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 + (display)) != + gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2))); - /* Check for different VA display */ - g_assert(gst_vaapi_display_get_display(display) != - gst_vaapi_display_get_display(display2)); + /* Check for different VA display */ + g_assert (gst_vaapi_display_get_display (display) != + gst_vaapi_display_get_display (display2)); - gst_vaapi_display_unref(display2); + gst_vaapi_display_unref (display2); #endif - } - - gst_vaapi_display_get_size(display, &width, &height); - g_print("Display size: %ux%u\n", width, height); - - gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d); - g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); - - dump_info(display); - gst_vaapi_display_unref(display); } - g_print("\n"); - g_print("#\n"); - g_print("# Create display with gst_vaapi_display_x11_new_with_display()\n"); - g_print("#\n"); - { - Display *x11_display; + gst_vaapi_display_get_size (display, &width, &height); + g_print ("Display size: %ux%u\n", width, height); - x11_display = XOpenDisplay(NULL); - if (!x11_display) - g_error("could not create X11 display"); + gst_vaapi_display_get_pixel_aspect_ratio (display, &par_n, &par_d); + g_print ("Pixel aspect ratio: %u/%u\n", par_n, par_d); - display = gst_vaapi_display_x11_new_with_display(x11_display); - if (!display) - g_error("could not create Gst/VA display"); + dump_info (display); + gst_vaapi_display_unref (display); + } + g_print ("\n"); - if (CHECK_DISPLAY_CACHE) { - display2 = gst_vaapi_display_x11_new_with_display(x11_display); + g_print ("#\n"); + g_print ("# Create display with gst_vaapi_display_x11_new_with_display()\n"); + g_print ("#\n"); + { + Display *x11_display; - /* Check for the same VA display */ - g_assert(gst_vaapi_display_get_display(display) == - gst_vaapi_display_get_display(display2)); + x11_display = XOpenDisplay (NULL); + if (!x11_display) + g_error ("could not create X11 display"); - gst_vaapi_display_unref(display2); - } + display = gst_vaapi_display_x11_new_with_display (x11_display); + if (!display) + g_error ("could not create Gst/VA display"); - dump_info(display); - gst_vaapi_display_unref(display); - XCloseDisplay(x11_display); + if (CHECK_DISPLAY_CACHE) { + display2 = gst_vaapi_display_x11_new_with_display (x11_display); + + /* Check for the same VA display */ + g_assert (gst_vaapi_display_get_display (display) == + gst_vaapi_display_get_display (display2)); + + gst_vaapi_display_unref (display2); } - g_print("\n"); - g_print("#\n"); - g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplay()]\n"); - g_print("#\n"); - { - Display *x11_display; - VADisplay va_display; + dump_info (display); + gst_vaapi_display_unref (display); + XCloseDisplay (x11_display); + } + g_print ("\n"); - x11_display = XOpenDisplay(NULL); - if (!x11_display) - g_error("could not create X11 display"); + g_print ("#\n"); + g_print + ("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplay()]\n"); + g_print ("#\n"); + { + Display *x11_display; + VADisplay va_display; - va_display = vaGetDisplay(x11_display); - if (!va_display) - g_error("could not create VA display"); + x11_display = XOpenDisplay (NULL); + if (!x11_display) + g_error ("could not create X11 display"); - display = gst_vaapi_display_new_with_display(va_display); - if (!display) - g_error("could not create Gst/VA display"); + va_display = vaGetDisplay (x11_display); + if (!va_display) + g_error ("could not create VA display"); - dump_info(display); - gst_vaapi_display_unref(display); - XCloseDisplay(x11_display); - } - g_print("\n"); + display = gst_vaapi_display_new_with_display (va_display); + if (!display) + g_error ("could not create Gst/VA display"); + + dump_info (display); + gst_vaapi_display_unref (display); + XCloseDisplay (x11_display); + } + g_print ("\n"); #endif #if USE_GLX - g_print("#\n"); - g_print("# Create display with gst_vaapi_display_glx_new()\n"); - g_print("#\n"); - { - display = gst_vaapi_display_glx_new(NULL); - if (!display) - g_error("could not create Gst/VA display"); + g_print ("#\n"); + g_print ("# Create display with gst_vaapi_display_glx_new()\n"); + g_print ("#\n"); + { + display = gst_vaapi_display_glx_new (NULL); + if (!display) + g_error ("could not create Gst/VA display"); - if (CHECK_DISPLAY_CACHE) { - display2 = gst_vaapi_display_glx_new(NULL); + if (CHECK_DISPLAY_CACHE) { + display2 = gst_vaapi_display_glx_new (NULL); - /* Check for the same X11 display */ - g_assert(gst_vaapi_display_x11_get_display( - GST_VAAPI_DISPLAY_X11(display)) == - gst_vaapi_display_x11_get_display( - GST_VAAPI_DISPLAY_X11(display2))); + /* Check for the same X11 display */ + g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 + (display)) == + gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2))); - /* Check for the same VA display */ - g_assert(gst_vaapi_display_get_display(display) == - gst_vaapi_display_get_display(display2)); + /* Check for the same VA display */ + g_assert (gst_vaapi_display_get_display (display) == + gst_vaapi_display_get_display (display2)); - gst_vaapi_display_unref(display2); + gst_vaapi_display_unref (display2); - display2 = gst_vaapi_display_x11_new(NULL); + display2 = gst_vaapi_display_x11_new (NULL); - /* Check for the same X11 display */ - g_assert(gst_vaapi_display_x11_get_display( - GST_VAAPI_DISPLAY_X11(display)) == - gst_vaapi_display_x11_get_display( - GST_VAAPI_DISPLAY_X11(display2))); + /* Check for the same X11 display */ + g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 + (display)) == + gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2))); - /* Check for the same VA display */ - g_assert(gst_vaapi_display_get_display(display) == - gst_vaapi_display_get_display(display2)); + /* Check for the same VA display */ + g_assert (gst_vaapi_display_get_display (display) == + gst_vaapi_display_get_display (display2)); - gst_vaapi_display_unref(display2); - } - - gst_vaapi_display_get_size(display, &width, &height); - g_print("Display size: %ux%u\n", width, height); - - gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d); - g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); - - dump_info(display); - gst_vaapi_display_unref(display); + gst_vaapi_display_unref (display2); } - g_print("\n"); - g_print("#\n"); - g_print("# Create display with gst_vaapi_display_glx_new_with_display()\n"); - g_print("#\n"); - { - Display *x11_display; + gst_vaapi_display_get_size (display, &width, &height); + g_print ("Display size: %ux%u\n", width, height); - x11_display = XOpenDisplay(NULL); - if (!x11_display) - g_error("could not create X11 display"); + gst_vaapi_display_get_pixel_aspect_ratio (display, &par_n, &par_d); + g_print ("Pixel aspect ratio: %u/%u\n", par_n, par_d); - display = gst_vaapi_display_glx_new_with_display(x11_display); - if (!display) - g_error("could not create Gst/VA display"); + dump_info (display); + gst_vaapi_display_unref (display); + } + g_print ("\n"); - dump_info(display); - gst_vaapi_display_unref(display); - XCloseDisplay(x11_display); - } - g_print("\n"); + g_print ("#\n"); + g_print ("# Create display with gst_vaapi_display_glx_new_with_display()\n"); + g_print ("#\n"); + { + Display *x11_display; + + x11_display = XOpenDisplay (NULL); + if (!x11_display) + g_error ("could not create X11 display"); + + display = gst_vaapi_display_glx_new_with_display (x11_display); + if (!display) + g_error ("could not create Gst/VA display"); + + dump_info (display); + gst_vaapi_display_unref (display); + XCloseDisplay (x11_display); + } + g_print ("\n"); #ifdef HAVE_VA_VA_GLX_H - g_print("#\n"); - g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayGLX()]\n"); - g_print("#\n"); - { - Display *x11_display; - VADisplay va_display; + g_print ("#\n"); + g_print + ("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayGLX()]\n"); + g_print ("#\n"); + { + Display *x11_display; + VADisplay va_display; - x11_display = XOpenDisplay(NULL); - if (!x11_display) - g_error("could not create X11 display"); + x11_display = XOpenDisplay (NULL); + if (!x11_display) + g_error ("could not create X11 display"); - va_display = vaGetDisplayGLX(x11_display); - if (!va_display) - g_error("could not create VA display"); + va_display = vaGetDisplayGLX (x11_display); + if (!va_display) + g_error ("could not create VA display"); - display = gst_vaapi_display_new_with_display(va_display); - if (!display) - g_error("could not create Gst/VA display"); + display = gst_vaapi_display_new_with_display (va_display); + if (!display) + g_error ("could not create Gst/VA display"); - dump_info(display); - gst_vaapi_display_unref(display); - XCloseDisplay(x11_display); - } - g_print("\n"); + dump_info (display); + gst_vaapi_display_unref (display); + XCloseDisplay (x11_display); + } + g_print ("\n"); #endif #endif #if USE_WAYLAND - g_print("#\n"); - g_print("# Create display with gst_vaapi_display_wayland_new()\n"); - g_print("#\n"); - { - display = gst_vaapi_display_wayland_new(NULL); - if (!display) - g_error("could not create Gst/VA display"); + g_print ("#\n"); + g_print ("# Create display with gst_vaapi_display_wayland_new()\n"); + g_print ("#\n"); + { + display = gst_vaapi_display_wayland_new (NULL); + if (!display) + g_error ("could not create Gst/VA display"); - gst_vaapi_display_get_size(display, &width, &height); - g_print("Display size: %ux%u\n", width, height); + gst_vaapi_display_get_size (display, &width, &height); + g_print ("Display size: %ux%u\n", width, height); - gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d); - g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); + gst_vaapi_display_get_pixel_aspect_ratio (display, &par_n, &par_d); + g_print ("Pixel aspect ratio: %u/%u\n", par_n, par_d); - dump_info(display); - gst_vaapi_display_unref(display); - } - g_print("\n"); + dump_info (display); + gst_vaapi_display_unref (display); + } + g_print ("\n"); #endif - gst_deinit(); - return 0; + gst_deinit (); + return 0; } diff --git a/tests/test-filter.c b/tests/test-filter.c index 0f681e8d6e..f83068273a 100644 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -38,419 +38,418 @@ static gchar *g_deinterlace_str; static gchar *g_deinterlace_flags_str; static GOptionEntry g_options[] = { - { "src-format", 's', - 0, - G_OPTION_ARG_STRING, &g_src_format_str, - "source surface format", NULL }, - { "crop-rect", 'c', - 0, - G_OPTION_ARG_STRING, &g_crop_rect_str, - "cropping rectangle", NULL }, - { "denoise", 0, - 0, - G_OPTION_ARG_STRING, &g_denoise_str, - "set noise reduction level", NULL }, - { "sharpen", 0, - 0, - G_OPTION_ARG_STRING, &g_sharpen_str, - "set sharpening level", NULL }, - { "deinterlace", 0, - 0, - G_OPTION_ARG_STRING, &g_deinterlace_str, - "enable deinterlacing", NULL }, - { "deinterlace-flags", 0, - 0, - G_OPTION_ARG_STRING, &g_deinterlace_flags_str, - "deinterlacing flags", NULL }, - { NULL, } + {"src-format", 's', + 0, + G_OPTION_ARG_STRING, &g_src_format_str, + "source surface format", NULL}, + {"crop-rect", 'c', + 0, + G_OPTION_ARG_STRING, &g_crop_rect_str, + "cropping rectangle", NULL}, + {"denoise", 0, + 0, + G_OPTION_ARG_STRING, &g_denoise_str, + "set noise reduction level", NULL}, + {"sharpen", 0, + 0, + G_OPTION_ARG_STRING, &g_sharpen_str, + "set sharpening level", NULL}, + {"deinterlace", 0, + 0, + G_OPTION_ARG_STRING, &g_deinterlace_str, + "enable deinterlacing", NULL}, + {"deinterlace-flags", 0, + 0, + G_OPTION_ARG_STRING, &g_deinterlace_flags_str, + "deinterlacing flags", NULL}, + {NULL,} }; #define APP_ERROR app_error_quark() static GQuark -app_error_quark(void) +app_error_quark (void) { - static gsize g_quark; + static gsize g_quark; - if (g_once_init_enter(&g_quark)) { - gsize quark = (gsize)g_quark_from_static_string("AppError"); - g_once_init_leave(&g_quark, quark); - } - return g_quark; + if (g_once_init_enter (&g_quark)) { + gsize quark = (gsize) g_quark_from_static_string ("AppError"); + g_once_init_leave (&g_quark, quark); + } + return g_quark; } -typedef enum { - APP_ERROR_NONE, - APP_ERROR_CREATE_TEST_SURFACE, +typedef enum +{ + APP_ERROR_NONE, + APP_ERROR_CREATE_TEST_SURFACE, } AppError; static inline void -pause(void) +pause (void) { - g_print("Press any key to continue...\n"); - getchar(); + g_print ("Press any key to continue...\n"); + getchar (); } static GstVaapiSurface * -create_test_surface(GstVaapiDisplay *display, guint width, guint height, - guint flags, GError **error_ptr) +create_test_surface (GstVaapiDisplay * display, guint width, guint height, + guint flags, GError ** error_ptr) { - GstVideoFormat format = GST_VIDEO_FORMAT_I420; - GstVaapiSurface *surface = NULL; - GstVaapiImage *image = NULL; - GError *error = NULL; + GstVideoFormat format = GST_VIDEO_FORMAT_I420; + GstVaapiSurface *surface = NULL; + GstVaapiImage *image = NULL; + GError *error = NULL; - if (g_src_format_str) { - format = gst_video_format_from_string(g_src_format_str); - if (format == GST_VIDEO_FORMAT_UNKNOWN) - goto error_invalid_format; - } + if (g_src_format_str) { + format = gst_video_format_from_string (g_src_format_str); + if (format == GST_VIDEO_FORMAT_UNKNOWN) + goto error_invalid_format; + } - surface = gst_vaapi_surface_new_with_format(display, format, width, height); - if (!surface) - goto error_create_surface; + surface = gst_vaapi_surface_new_with_format (display, format, width, height); + if (!surface) + goto error_create_surface; - image = image_generate_full(display, format, width, height, flags); - if (!image) - goto error_create_image; + image = image_generate_full (display, format, width, height, flags); + if (!image) + goto error_create_image; - if (!image_upload(image, surface)) - goto error_upload_image; + if (!image_upload (image, surface)) + goto error_upload_image; - gst_vaapi_object_unref(image); - return surface; + gst_vaapi_object_unref (image); + return surface; - /* ERRORS */ + /* ERRORS */ error_invalid_format: - error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, - "unknown format %s", g_src_format_str); - goto error_cleanup; + error = g_error_new (APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, + "unknown format %s", g_src_format_str); + goto error_cleanup; error_create_surface: - error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, - "unsupported format %s", gst_vaapi_video_format_to_string(format)); - goto error_cleanup; + error = g_error_new (APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, + "unsupported format %s", gst_vaapi_video_format_to_string (format)); + goto error_cleanup; error_create_image: - error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, - "unsupported %s image", gst_vaapi_video_format_to_string(format)); - goto error_cleanup; + error = g_error_new (APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, + "unsupported %s image", gst_vaapi_video_format_to_string (format)); + goto error_cleanup; error_upload_image: - error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, - "failed to upload %s image", gst_vaapi_video_format_to_string(format)); - goto error_cleanup; + error = g_error_new (APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, + "failed to upload %s image", gst_vaapi_video_format_to_string (format)); + goto error_cleanup; error_cleanup: - if (image) - gst_vaapi_object_unref(image); - if (surface) - gst_vaapi_object_unref(surface); - if (error_ptr) - *error_ptr = error; - else - g_error_free(error); - return NULL; + if (image) + gst_vaapi_object_unref (image); + if (surface) + gst_vaapi_object_unref (surface); + if (error_ptr) + *error_ptr = error; + else + g_error_free (error); + return NULL; } static void -dump_operation(GstVaapiFilterOpInfo *op_info) +dump_operation (GstVaapiFilterOpInfo * op_info) { - GParamSpec * const pspec = op_info->pspec; - GValue value = G_VALUE_INIT; - gchar *value_str; + GParamSpec *const pspec = op_info->pspec; + GValue value = G_VALUE_INIT; + gchar *value_str; - if (!op_info) - return; + if (!op_info) + return; - g_print(" %s: ", g_param_spec_get_name(pspec)); - g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - g_param_value_set_default(pspec, &value); - value_str = g_strdup_value_contents(&value); - g_print("%s (default: %s)\n", G_VALUE_TYPE_NAME(&value), - value_str ? value_str : ""); - g_free(value_str); + g_print (" %s: ", g_param_spec_get_name (pspec)); + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + g_param_value_set_default (pspec, &value); + value_str = g_strdup_value_contents (&value); + g_print ("%s (default: %s)\n", G_VALUE_TYPE_NAME (&value), + value_str ? value_str : ""); + g_free (value_str); } static void -dump_operations(GstVaapiFilter *filter) +dump_operations (GstVaapiFilter * filter) { - GPtrArray * const ops = gst_vaapi_filter_get_operations(filter); - guint i; + GPtrArray *const ops = gst_vaapi_filter_get_operations (filter); + guint i; - if (!ops) - return; + if (!ops) + return; - g_print("%u operations\n", ops->len); - for (i = 0; i < ops->len; i++) - dump_operation(g_ptr_array_index(ops, i)); - g_ptr_array_unref(ops); + g_print ("%u operations\n", ops->len); + for (i = 0; i < ops->len; i++) + dump_operation (g_ptr_array_index (ops, i)); + g_ptr_array_unref (ops); } static void -dump_formats(GstVaapiFilter *filter) +dump_formats (GstVaapiFilter * filter) { - GArray * const formats = gst_vaapi_filter_get_formats(filter); - guint i; + GArray *const formats = gst_vaapi_filter_get_formats (filter); + guint i; - if (!formats) - return; + if (!formats) + return; - g_print("%u formats\n", formats->len); - for (i = 0; i < formats->len; i++) { - GstVideoFormat format = g_array_index(formats, GstVideoFormat, i); - g_print(" %s\n", gst_vaapi_video_format_to_string(format)); - } - g_array_unref(formats); + g_print ("%u formats\n", formats->len); + for (i = 0; i < formats->len; i++) { + GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); + g_print (" %s\n", gst_vaapi_video_format_to_string (format)); + } + g_array_unref (formats); } static gboolean -parse_double(const gchar *str, gdouble *out_value_ptr) +parse_double (const gchar * str, gdouble * out_value_ptr) { - gchar *endptr = NULL; - gdouble out_value; + gchar *endptr = NULL; + gdouble out_value; - g_return_val_if_fail(out_value_ptr != NULL, FALSE); + g_return_val_if_fail (out_value_ptr != NULL, FALSE); - errno = 0; - out_value = g_ascii_strtod(str, &endptr); - if (!endptr || *endptr != '\0' || errno == ERANGE) - return FALSE; - - *out_value_ptr = out_value; - return TRUE; -} - -static gboolean -parse_crop_rect(const gchar *str, GstVaapiRectangle *crop_rect) -{ - if (str) { - // Format: 'x' - if (sscanf(str, "%ux%u", &crop_rect->width, &crop_rect->height) == 2) { - crop_rect->x = 0; - crop_rect->y = 0; - return TRUE; - } - - // Format: '('? ',' ')'? 'x' - if (sscanf(str, "(%d,%d):%ux%u", &crop_rect->x, &crop_rect->y, - &crop_rect->width, &crop_rect->height) == 4 || - sscanf(str, "%d,%d:%ux%u", &crop_rect->x, &crop_rect->y, - &crop_rect->width, &crop_rect->height) == 4) - return TRUE; - } + errno = 0; + out_value = g_ascii_strtod (str, &endptr); + if (!endptr || *endptr != '\0' || errno == ERANGE) return FALSE; + + *out_value_ptr = out_value; + return TRUE; } static gboolean -parse_enum(const gchar *str, GType type, gint default_value, - gint *out_value_ptr) +parse_crop_rect (const gchar * str, GstVaapiRectangle * crop_rect) { - gint out_value = default_value; - - g_return_val_if_fail(out_value_ptr != NULL, FALSE); - - if (str) { - const GEnumValue *enum_value; - GEnumClass * const enum_class = g_type_class_ref(type); - - if (!enum_class) - return FALSE; - - enum_value = g_enum_get_value_by_nick(enum_class, str); - if (enum_value) - out_value = enum_value->value; - g_type_class_unref(enum_class); - - if (!enum_value) - return FALSE; + if (str) { + // Format: 'x' + if (sscanf (str, "%ux%u", &crop_rect->width, &crop_rect->height) == 2) { + crop_rect->x = 0; + crop_rect->y = 0; + return TRUE; } - *out_value_ptr = out_value; - return TRUE; + // Format: '('? ',' ')'? 'x' + if (sscanf (str, "(%d,%d):%ux%u", &crop_rect->x, &crop_rect->y, + &crop_rect->width, &crop_rect->height) == 4 || + sscanf (str, "%d,%d:%ux%u", &crop_rect->x, &crop_rect->y, + &crop_rect->width, &crop_rect->height) == 4) + return TRUE; + } + return FALSE; } static gboolean -parse_flags(const gchar *str, GType type, guint *out_value_ptr) +parse_enum (const gchar * str, GType type, gint default_value, + gint * out_value_ptr) { - gchar **tokens = NULL; - gint i, value, out_value = 0; - gboolean success = FALSE; + gint out_value = default_value; - g_return_val_if_fail(out_value_ptr != NULL, FALSE); + g_return_val_if_fail (out_value_ptr != NULL, FALSE); - if (str) { - tokens = g_strsplit(str, ",", 32); - if (!tokens) - return FALSE; + if (str) { + const GEnumValue *enum_value; + GEnumClass *const enum_class = g_type_class_ref (type); - for (i = 0; tokens[i] != NULL; i++) { - if (!parse_enum(tokens[i], type, 0, &value)) - goto end; - out_value |= value; - } + if (!enum_class) + return FALSE; + + enum_value = g_enum_get_value_by_nick (enum_class, str); + if (enum_value) + out_value = enum_value->value; + g_type_class_unref (enum_class); + + if (!enum_value) + return FALSE; + } + *out_value_ptr = out_value; + return TRUE; +} + +static gboolean +parse_flags (const gchar * str, GType type, guint * out_value_ptr) +{ + gchar **tokens = NULL; + gint i, value, out_value = 0; + gboolean success = FALSE; + + g_return_val_if_fail (out_value_ptr != NULL, FALSE); + + if (str) { + tokens = g_strsplit (str, ",", 32); + if (!tokens) + return FALSE; + + for (i = 0; tokens[i] != NULL; i++) { + if (!parse_enum (tokens[i], type, 0, &value)) + goto end; + out_value |= value; } - *out_value_ptr = out_value; - success = TRUE; + } + *out_value_ptr = out_value; + success = TRUE; end: - g_strfreev(tokens); - return success; + g_strfreev (tokens); + return success; } static inline gboolean -parse_deinterlace(const gchar *str, GstVaapiDeinterlaceMethod *deinterlace_ptr) +parse_deinterlace (const gchar * str, + GstVaapiDeinterlaceMethod * deinterlace_ptr) { - g_return_val_if_fail(deinterlace_ptr != NULL, FALSE); + g_return_val_if_fail (deinterlace_ptr != NULL, FALSE); - if (!str) { - *deinterlace_ptr = GST_VAAPI_DEINTERLACE_METHOD_NONE; - return TRUE; - } - return parse_enum(str, GST_VAAPI_TYPE_DEINTERLACE_METHOD, - GST_VAAPI_DEINTERLACE_METHOD_NONE, (gint *)deinterlace_ptr); + if (!str) { + *deinterlace_ptr = GST_VAAPI_DEINTERLACE_METHOD_NONE; + return TRUE; + } + return parse_enum (str, GST_VAAPI_TYPE_DEINTERLACE_METHOD, + GST_VAAPI_DEINTERLACE_METHOD_NONE, (gint *) deinterlace_ptr); } static inline gboolean -parse_deinterlace_flags(const gchar *str, guint *deinterlace_flags_ptr) +parse_deinterlace_flags (const gchar * str, guint * deinterlace_flags_ptr) { - return parse_flags(str, GST_VAAPI_TYPE_DEINTERLACE_FLAGS, - deinterlace_flags_ptr); + return parse_flags (str, GST_VAAPI_TYPE_DEINTERLACE_FLAGS, + deinterlace_flags_ptr); } int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { - GstVaapiDisplay *display; - GstVaapiWindow *window; - GstVaapiSurface *src_surface, *dst_surface; - GstVaapiFilter *filter = NULL; - GstVaapiFilterStatus status; - GstVaapiDeinterlaceMethod deinterlace_method; - guint deinterlace_flags = 0; - guint filter_flags = 0; - guint surface_flags = 0; - gdouble denoise_level, sharpen_level; - GError *error = NULL; + GstVaapiDisplay *display; + GstVaapiWindow *window; + GstVaapiSurface *src_surface, *dst_surface; + GstVaapiFilter *filter = NULL; + GstVaapiFilterStatus status; + GstVaapiDeinterlaceMethod deinterlace_method; + guint deinterlace_flags = 0; + guint filter_flags = 0; + guint surface_flags = 0; + gdouble denoise_level, sharpen_level; + GError *error = NULL; - static const guint src_width = 320; - static const guint src_height = 240; - static const guint dst_width = 480; - static const guint dst_height = 360; - static const guint win_width = 640; - static const guint win_height = 480; + static const guint src_width = 320; + static const guint src_height = 240; + static const guint dst_width = 480; + static const guint dst_height = 360; + static const guint win_width = 640; + static const guint win_height = 480; - if (!video_output_init(&argc, argv, g_options)) - g_error("failed to initialize video output subsystem"); + if (!video_output_init (&argc, argv, g_options)) + g_error ("failed to initialize video output subsystem"); - if (g_denoise_str && !parse_double(g_denoise_str, &denoise_level)) - g_error("failed to parse noise reduction level"); + if (g_denoise_str && !parse_double (g_denoise_str, &denoise_level)) + g_error ("failed to parse noise reduction level"); - if (g_sharpen_str && !parse_double(g_sharpen_str, &sharpen_level)) - g_error("failed to parse sharpening level"); + if (g_sharpen_str && !parse_double (g_sharpen_str, &sharpen_level)) + g_error ("failed to parse sharpening level"); - if (!parse_deinterlace(g_deinterlace_str, &deinterlace_method)) - g_error("failed to parse deinterlace method `%s'", g_deinterlace_str); + if (!parse_deinterlace (g_deinterlace_str, &deinterlace_method)) + g_error ("failed to parse deinterlace method `%s'", g_deinterlace_str); - if (!parse_deinterlace_flags(g_deinterlace_flags_str, &deinterlace_flags)) - g_error("failed to parse deinterlace flags `%s'", - g_deinterlace_flags_str); + if (!parse_deinterlace_flags (g_deinterlace_flags_str, &deinterlace_flags)) + g_error ("failed to parse deinterlace flags `%s'", g_deinterlace_flags_str); - display = video_output_create_display(NULL); - if (!display) - g_error("failed to create VA display"); + display = video_output_create_display (NULL); + if (!display) + g_error ("failed to create VA display"); - window = video_output_create_window(display, win_width, win_height); - if (!window) - g_error("failed to create window"); + window = video_output_create_window (display, win_width, win_height); + if (!window) + g_error ("failed to create window"); - filter = gst_vaapi_filter_new(display); - if (!filter) - g_error("failed to create video processing pipeline"); + filter = gst_vaapi_filter_new (display); + if (!filter) + g_error ("failed to create video processing pipeline"); - dump_operations(filter); - dump_formats(filter); + dump_operations (filter); + dump_formats (filter); - if (g_crop_rect_str) { - GstVaapiRectangle crop_rect; + if (g_crop_rect_str) { + GstVaapiRectangle crop_rect; - if (!parse_crop_rect(g_crop_rect_str, &crop_rect)) - g_error("failed to parse cropping rectangle"); + if (!parse_crop_rect (g_crop_rect_str, &crop_rect)) + g_error ("failed to parse cropping rectangle"); - printf("Frame cropping: (%d,%d), size %ux%u\n", - crop_rect.x, crop_rect.y, crop_rect.width, crop_rect.height); + printf ("Frame cropping: (%d,%d), size %ux%u\n", + crop_rect.x, crop_rect.y, crop_rect.width, crop_rect.height); - if (!gst_vaapi_filter_set_cropping_rectangle(filter, &crop_rect)) - g_error("failed to set cropping rectangle"); - } + if (!gst_vaapi_filter_set_cropping_rectangle (filter, &crop_rect)) + g_error ("failed to set cropping rectangle"); + } - if (g_denoise_str) { - printf("Noise reduction level: %f\n", denoise_level); + if (g_denoise_str) { + printf ("Noise reduction level: %f\n", denoise_level); - if (!gst_vaapi_filter_set_denoising_level(filter, denoise_level)) - g_error("failed to set denoising level"); - } + if (!gst_vaapi_filter_set_denoising_level (filter, denoise_level)) + g_error ("failed to set denoising level"); + } - if (g_sharpen_str) { - printf("Sharpening level: %f\n", sharpen_level); + if (g_sharpen_str) { + printf ("Sharpening level: %f\n", sharpen_level); - if (!gst_vaapi_filter_set_sharpening_level(filter, sharpen_level)) - g_error("failed to set sharpening level"); - } + if (!gst_vaapi_filter_set_sharpening_level (filter, sharpen_level)) + g_error ("failed to set sharpening level"); + } - if (deinterlace_method != GST_VAAPI_DEINTERLACE_METHOD_NONE) { - printf("Enable deinterlacing: %s\n", g_deinterlace_str); + if (deinterlace_method != GST_VAAPI_DEINTERLACE_METHOD_NONE) { + printf ("Enable deinterlacing: %s\n", g_deinterlace_str); - if (!gst_vaapi_filter_set_deinterlacing(filter, deinterlace_method, - deinterlace_flags)) - g_error("failed to set deinterlacing method"); - } - else if (deinterlace_flags) { - if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD) - filter_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; - else - filter_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; - } + if (!gst_vaapi_filter_set_deinterlacing (filter, deinterlace_method, + deinterlace_flags)) + g_error ("failed to set deinterlacing method"); + } else if (deinterlace_flags) { + if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD) + filter_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + else + filter_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + } - if (deinterlace_method != GST_VAAPI_DEINTERLACE_METHOD_NONE || - deinterlace_flags) { - if (!(deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD)) - surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD | - GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; - else if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD) - surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; - else - surface_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; - } + if (deinterlace_method != GST_VAAPI_DEINTERLACE_METHOD_NONE || + deinterlace_flags) { + if (!(deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD)) + surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD | + GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + else if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD) + surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; + else + surface_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; + } - src_surface = create_test_surface(display, src_width, src_height, - surface_flags, &error); - if (!src_surface) - g_error("failed to create source VA surface: %s", error->message); + src_surface = create_test_surface (display, src_width, src_height, + surface_flags, &error); + if (!src_surface) + g_error ("failed to create source VA surface: %s", error->message); - dst_surface = gst_vaapi_surface_new(display, GST_VAAPI_CHROMA_TYPE_YUV420, - dst_width, dst_height); - if (!dst_surface) - g_error("failed to create target VA surface"); + dst_surface = gst_vaapi_surface_new (display, GST_VAAPI_CHROMA_TYPE_YUV420, + dst_width, dst_height); + if (!dst_surface) + g_error ("failed to create target VA surface"); - status = gst_vaapi_filter_process(filter, src_surface, dst_surface, - filter_flags); - if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) - g_error("failed to process video filters"); + status = gst_vaapi_filter_process (filter, src_surface, dst_surface, + filter_flags); + if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) + g_error ("failed to process video filters"); - gst_vaapi_window_show(window); + gst_vaapi_window_show (window); - if (!gst_vaapi_window_put_surface(window, dst_surface, NULL, NULL, - GST_VAAPI_PICTURE_STRUCTURE_FRAME)) - g_error("failed to render target surface"); + if (!gst_vaapi_window_put_surface (window, dst_surface, NULL, NULL, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + g_error ("failed to render target surface"); - pause(); + pause (); - gst_vaapi_filter_unref(filter); - gst_vaapi_object_unref(dst_surface); - gst_vaapi_object_unref(src_surface); - gst_vaapi_window_unref(window); - gst_vaapi_display_unref(display); - video_output_exit(); - g_free(g_src_format_str); - g_free(g_crop_rect_str); - g_free(g_denoise_str); - g_free(g_sharpen_str); - g_free(g_deinterlace_str); - g_free(g_deinterlace_flags_str); - return 0; + gst_vaapi_filter_unref (filter); + gst_vaapi_object_unref (dst_surface); + gst_vaapi_object_unref (src_surface); + gst_vaapi_window_unref (window); + gst_vaapi_display_unref (display); + video_output_exit (); + g_free (g_src_format_str); + g_free (g_crop_rect_str); + g_free (g_denoise_str); + g_free (g_sharpen_str); + g_free (g_deinterlace_str); + g_free (g_deinterlace_flags_str); + return 0; } diff --git a/tests/test-h264.c b/tests/test-h264.c index d24889111a..d94dc42c0d 100644 --- a/tests/test-h264.c +++ b/tests/test-h264.c @@ -28,1023 +28,1024 @@ /* Data dump of a 320x240 H.264 video clip (h264.mp4), it has a single frame */ static const guchar h264_clip[H264_CLIP_DATA_SIZE] = { - 0x00, 0x00, 0x01, 0x67, 0x4d, 0x40, 0x0d, 0xab, 0x40, 0xa0, 0xfd, 0x80, - 0x88, 0x00, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0xc4, 0x78, - 0xa1, 0x55, 0x00, 0x00, 0x01, 0x68, 0xee, 0x32, 0xc8, 0x00, 0x00, 0x01, - 0x65, 0x88, 0x82, 0x00, 0x45, 0xbb, 0x9d, 0x38, 0x9b, 0xe8, 0x48, 0xef, - 0xed, 0xa7, 0xd7, 0x9c, 0x19, 0x9b, 0x5a, 0xca, 0x00, 0x0d, 0x54, 0x0c, - 0xe3, 0xd5, 0xad, 0xa9, 0x5d, 0x71, 0x24, 0x83, 0xbb, 0x36, 0x4d, 0xb1, - 0xf5, 0x0f, 0xc6, 0x66, 0xb6, 0x6d, 0x1d, 0xa5, 0x45, 0xfc, 0xa0, 0x4c, - 0xbf, 0xfb, 0x2f, 0x5c, 0x1a, 0x5a, 0x3b, 0x29, 0xe0, 0x35, 0x95, 0x44, - 0x8e, 0x2f, 0x22, 0xd3, 0x3a, 0x48, 0x88, 0x7d, 0x32, 0x97, 0xff, 0xd8, - 0x54, 0x7f, 0x7f, 0x65, 0x57, 0x71, 0xaf, 0xba, 0x17, 0xe0, 0x12, 0x24, - 0xc9, 0x5b, 0xaa, 0xc7, 0xd5, 0x27, 0xc9, 0x64, 0x5d, 0x5e, 0xa0, 0xea, - 0x57, 0xd2, 0x7d, 0x55, 0x6c, 0xf2, 0x44, 0x2f, 0x4b, 0x5d, 0xbd, 0x62, - 0xb9, 0xc2, 0xfa, 0x1e, 0x8f, 0xbc, 0x57, 0x5f, 0xc1, 0x2d, 0xb3, 0x9a, - 0x0e, 0x58, 0x75, 0xf7, 0x08, 0xdf, 0x2d, 0xda, 0xc1, 0xa5, 0x55, 0x76, - 0x06, 0xaf, 0x92, 0x28, 0x43, 0xc5, 0x20, 0x16, 0x96, 0xf5, 0x79, 0x1e, - 0x88, 0x77, 0xb3, 0x4e, 0xb8, 0x4f, 0x3e, 0x51, 0x3c, 0xcf, 0xc0, 0x28, - 0xda, 0xb8, 0xa3, 0x1d, 0xed, 0x8e, 0x04, 0x74, 0x82, 0xc1, 0x5d, 0xa8, - 0x3c, 0x25, 0xd2, 0x84, 0x0b, 0x34, 0x40, 0x8b, 0x7f, 0xee, 0xae, 0xf8, - 0xde, 0x6e, 0x28, 0xf6, 0xfc, 0xfc, 0x14, 0x7e, 0x95, 0xd9, 0xd8, 0x2c, - 0x09, 0x49, 0x27, 0x64, 0x13, 0x83, 0x5c, 0x6f, 0xd4, 0x09, 0x48, 0xa8, - 0xd4, 0x1b, 0x6e, 0x4d, 0x05, 0x0a, 0xbe, 0x27, 0xff, 0xf4, 0x27, 0x04, - 0x41, 0xa0, 0x23, 0x61, 0xe6, 0x26, 0x32, 0xf4, 0xa3, 0xca, 0x97, 0xfc, - 0xeb, 0x6b, 0x45, 0x35, 0x13, 0x69, 0xd9, 0x41, 0x0f, 0xa6, 0xc0, 0xbe, - 0xd5, 0xfa, 0x28, 0xa6, 0x4f, 0x62, 0x3e, 0x1f, 0xcb, 0x98, 0x0a, 0x70, - 0x09, 0xc1, 0xe3, 0x69, 0x30, 0x20, 0xe7, 0xd5, 0x1c, 0xf0, 0x7e, 0x52, - 0x1d, 0x6a, 0xdd, 0x14, 0x58, 0x5e, 0x7a, 0x35, 0x57, 0xa1, 0xe6, 0x83, - 0x46, 0x57, 0x6e, 0x57, 0x7f, 0x72, 0x5d, 0x0c, 0x0c, 0xf4, 0x40, 0x11, - 0x8c, 0xbb, 0xdf, 0xd1, 0x54, 0xfb, 0x7d, 0xf7, 0x03, 0xb9, 0x4e, 0xa3, - 0x76, 0x4c, 0xce, 0xfb, 0x9e, 0x39, 0x02, 0xf0, 0x48, 0xb5, 0x8c, 0x36, - 0x6e, 0x93, 0x79, 0x48, 0xcc, 0x28, 0xec, 0xd7, 0xb8, 0x02, 0xe5, 0xa3, - 0x37, 0x01, 0xe1, 0x3c, 0x40, 0x8f, 0x68, 0x27, 0xbc, 0xec, 0x6b, 0x59, - 0xb9, 0xfe, 0xb8, 0x67, 0x68, 0x83, 0x99, 0x97, 0x1e, 0xcc, 0x4e, 0x23, - 0x82, 0x26, 0x93, 0x7b, 0x7a, 0x9e, 0xdc, 0x42, 0xca, 0x1b, 0x3e, 0x13, - 0x19, 0x45, 0x03, 0x40, 0xab, 0xd2, 0xda, 0x6b, 0x6c, 0x26, 0xdb, 0xe3, - 0x72, 0x06, 0x89, 0xea, 0x03, 0x95, 0xe3, 0x14, 0xe1, 0x4a, 0x16, 0x58, - 0x2d, 0x67, 0xaa, 0xbf, 0xbe, 0x37, 0x54, 0x19, 0xb1, 0x57, 0x61, 0x85, - 0x82, 0x5f, 0x63, 0x33, 0xe2, 0xf8, 0x7f, 0x4f, 0x21, 0x44, 0x8a, 0x0e, - 0x21, 0x2b, 0x12, 0x99, 0x4d, 0xd9, 0x2e, 0xea, 0x36, 0x2d, 0x45, 0xcb, - 0xe2, 0xfe, 0xdd, 0x03, 0x3b, 0x08, 0x58, 0x60, 0x1e, 0xb2, 0xfa, 0x3b, - 0x89, 0xa5, 0x03, 0xde, 0xab, 0x71, 0x32, 0x48, 0x46, 0x2c, 0xfb, 0x2b, - 0x84, 0x83, 0xc9, 0xff, 0xf6, 0xf5, 0x2f, 0xe7, 0x2f, 0x6a, 0x5d, 0x86, - 0xe2, 0x48, 0x23, 0x6d, 0x84, 0x60, 0x9b, 0xc0, 0x25, 0x1e, 0xff, 0x94, - 0xe8, 0xf4, 0xd0, 0x4e, 0x11, 0x60, 0xda, 0x20, 0xa8, 0xfd, 0xf3, 0x00, - 0x4f, 0x0e, 0x4f, 0xa2, 0xeb, 0xe1, 0xa8, 0xb3, 0x47, 0x35, 0x62, 0x83, - 0x6f, 0x08, 0x6b, 0xb8, 0x82, 0x04, 0xcc, 0x63, 0x69, 0xd7, 0xba, 0x10, - 0xd4, 0x51, 0xe6, 0xb5, 0x34, 0xe8, 0x7d, 0xaf, 0x87, 0xcf, 0x1d, 0xeb, - 0x46, 0xc1, 0xcd, 0xcb, 0xf2, 0x3b, 0x3e, 0xa0, 0x61, 0xc7, 0x68, 0x86, - 0x0b, 0x9f, 0x0b, 0x59, 0xc0, 0x79, 0x4e, 0xcc, 0x79, 0x91, 0xa0, 0xe8, - 0x80, 0x6c, 0xbd, 0x35, 0x12, 0x71, 0x2f, 0x5e, 0xa4, 0xfc, 0xe6, 0x51, - 0xe0, 0xbe, 0x41, 0x1a, 0x19, 0x60, 0xd8, 0xac, 0xcd, 0x93, 0x05, 0x70, - 0xa0, 0xda, 0x53, 0x4e, 0x5a, 0x6d, 0x9b, 0x3f, 0x28, 0x73, 0x87, 0x6f, - 0x6d, 0x41, 0x5a, 0x13, 0xd0, 0xea, 0x19, 0xb3, 0xb7, 0xf1, 0x75, 0x92, - 0xae, 0x43, 0x9d, 0xe3, 0xa7, 0x4d, 0x5a, 0x52, 0x36, 0xce, 0x6b, 0x1e, - 0x2b, 0x2e, 0xab, 0x0c, 0xd7, 0xe4, 0x1c, 0x44, 0x72, 0x9d, 0x86, 0xb6, - 0xeb, 0xe5, 0x80, 0xc4, 0x45, 0x21, 0x8b, 0xe0, 0xe0, 0x9d, 0x09, 0xfa, - 0x0b, 0x59, 0x0c, 0x2c, 0x9d, 0x97, 0x15, 0x56, 0xd0, 0x21, 0xd8, 0x90, - 0xb4, 0x89, 0xc4, 0x96, 0x76, 0xf1, 0x64, 0xa5, 0x85, 0x2a, 0x13, 0xfb, - 0xfa, 0x11, 0x1e, 0x2d, 0x63, 0xc2, 0x9a, 0x87, 0x99, 0x2c, 0x18, 0xb8, - 0xeb, 0x6a, 0x5c, 0x68, 0x26, 0x63, 0xcc, 0x1b, 0x1a, 0x5c, 0x7f, 0x0d, - 0x45, 0xcc, 0x56, 0x46, 0x92, 0xbb, 0x76, 0xf2, 0x2e, 0x52, 0x05, 0x3c, - 0xe3, 0xbb, 0x59, 0x9b, 0x89, 0x03, 0x0d, 0x48, 0xb1, 0xdc, 0x78, 0x04, - 0x03, 0x24, 0xf4, 0x62, 0xcf, 0xb1, 0xc6, 0x64, 0x05, 0xbd, 0x89, 0x94, - 0x1a, 0x8d, 0xc1, 0xbe, 0xac, 0xe0, 0xed, 0x89, 0xf3, 0x47, 0x81, 0x82, - 0xb9, 0x64, 0xcc, 0x8e, 0xc4, 0x1e, 0xa9, 0xf6, 0xde, 0x8d, 0xb7, 0x33, - 0xba, 0x5b, 0x49, 0x0d, 0x0a, 0x16, 0x96, 0x7d, 0x89, 0x82, 0xe0, 0x5a, - 0x08, 0x55, 0xbd, 0xce, 0xca, 0xc0, 0x46, 0x1a, 0x6b, 0xf9, 0x7d, 0x03, - 0xe8, 0x35, 0x69, 0x7d, 0x87, 0xc9, 0x71, 0x01, 0x7e, 0xa8, 0x3a, 0x9c, - 0xd5, 0xe2, 0x71, 0xa6, 0xc7, 0xe2, 0x2d, 0xf3, 0x6f, 0x74, 0x0f, 0x3e, - 0x03, 0x70, 0x5e, 0xec, 0x8c, 0x66, 0xf9, 0x71, 0x9a, 0xd2, 0x56, 0x57, - 0x37, 0xcd, 0x50, 0x55, 0x97, 0xea, 0x67, 0x20, 0x59, 0x06, 0x4d, 0x22, - 0xa0, 0x85, 0x90, 0xb3, 0x59, 0x15, 0x75, 0x0d, 0x70, 0xbd, 0xb5, 0x7d, - 0x72, 0xaa, 0xea, 0xfc, 0x9d, 0x08, 0x8d, 0xdf, 0x31, 0x21, 0x2d, 0xef, - 0x00, 0x24, 0x6c, 0xae, 0x82, 0x6e, 0x1a, 0x4b, 0x28, 0xa5, 0x6d, 0x98, - 0xeb, 0x50, 0x87, 0x6f, 0x1b, 0xa5, 0xba, 0x1c, 0xda, 0x59, 0xb8, 0x4c, - 0x17, 0xe3, 0xd5, 0x10, 0x46, 0x94, 0x91, 0xed, 0x0b, 0xd3, 0xfc, 0x06, - 0x81, 0x60, 0x88, 0x5f, 0x58, 0x81, 0x26, 0x54, 0xdc, 0xd5, 0x7c, 0xbe, - 0x30, 0x04, 0x17, 0x84, 0x76, 0xe8, 0xb6, 0x8a, 0xec, 0x84, 0x02, 0xcf, - 0xc7, 0xda, 0x2d, 0x2e, 0x31, 0xc2, 0x77, 0x31, 0x54, 0x32, 0xbd, 0x77, - 0xa2, 0xa5, 0x5d, 0xec, 0x1c, 0x27, 0xf6, 0xec, 0xc8, 0x3f, 0xeb, 0x1a, - 0x24, 0xcb, 0x74, 0xd0, 0xb3, 0x52, 0xa8, 0x8f, 0x4c, 0x26, 0xbf, 0x68, - 0xb2, 0x87, 0xf3, 0xa8, 0xa9, 0x4f, 0x71, 0x57, 0xc7, 0xa8, 0x34, 0x5a, - 0x01, 0x68, 0xae, 0x5c, 0xb3, 0xd8, 0x23, 0x6b, 0xea, 0x18, 0xdf, 0xa9, - 0xe5, 0xc4, 0x11, 0x49, 0x2b, 0xfa, 0xa8, 0xf3, 0x8f, 0x80, 0x47, 0xa0, - 0x19, 0xc7, 0x20, 0xef, 0xbf, 0xed, 0xe1, 0x38, 0x8b, 0x16, 0x54, 0x36, - 0x60, 0x8b, 0x04, 0x26, 0x9c, 0x6b, 0x1a, 0x95, 0x4c, 0x94, 0x6a, 0x53, - 0xcf, 0xb4, 0x4b, 0x38, 0x3a, 0x15, 0x26, 0x94, 0x10, 0x1c, 0x35, 0xe4, - 0x57, 0x80, 0x19, 0xad, 0x1f, 0x82, 0xe8, 0x47, 0xe4, 0x90, 0xa2, 0x42, - 0x30, 0x43, 0x15, 0x92, 0x2b, 0x39, 0xfb, 0x7b, 0xb3, 0xdb, 0xc7, 0x5b, - 0x79, 0x5e, 0x91, 0xba, 0x38, 0x74, 0xd6, 0x00, 0x26, 0xa5, 0x8f, 0xa4, - 0x31, 0xe6, 0x7b, 0xeb, 0x52, 0xc2, 0xe2, 0xa1, 0x6b, 0x5f, 0x17, 0xf1, - 0x15, 0xc9, 0x4b, 0x44, 0x93, 0x77, 0x28, 0xdf, 0x2a, 0xc0, 0xb5, 0x97, - 0xfc, 0xbe, 0x2e, 0x72, 0x53, 0x58, 0xf9, 0x33, 0x3a, 0xb0, 0x6e, 0xaf, - 0x0c, 0x1b, 0xcf, 0x71, 0x37, 0x6b, 0x4a, 0x9a, 0x66, 0x16, 0x90, 0x43, - 0x9b, 0x70, 0x0d, 0x8f, 0xd3, 0x04, 0x4b, 0x14, 0xf2, 0x58, 0x9f, 0x64, - 0x33, 0x21, 0xdc, 0x02, 0x8a, 0x5b, 0xd6, 0x80, 0x9c, 0x22, 0xc8, 0x39, - 0x7d, 0x2d, 0x7c, 0x09, 0x4e, 0x6a, 0x8c, 0x8d, 0x0c, 0xc4, 0xfe, 0x6f, - 0x8c, 0x50, 0xf2, 0x75, 0xc0, 0x12, 0x6f, 0xd3, 0x9d, 0x07, 0xc0, 0xe9, - 0xdf, 0x36, 0xa2, 0x6f, 0xca, 0x14, 0x5b, 0x0f, 0x5a, 0xd8, 0x35, 0x72, - 0x07, 0x08, 0x80, 0xba, 0x2f, 0x61, 0x7f, 0xb0, 0x5e, 0xbb, 0xb1, 0x47, - 0x6a, 0xbd, 0x6a, 0xe4, 0xb6, 0xa2, 0xec, 0x2e, 0x27, 0x43, 0xbc, 0xd7, - 0x2c, 0x2c, 0xf3, 0x6c, 0x12, 0x4c, 0x86, 0x5a, 0x38, 0xa4, 0x87, 0xa8, - 0xe1, 0x70, 0x17, 0x15, 0xd0, 0x2b, 0x87, 0xdb, 0x87, 0xc0, 0x85, 0x57, - 0x30, 0x31, 0x16, 0x07, 0x9b, 0x72, 0x07, 0xf5, 0x18, 0x6d, 0xd1, 0x8d, - 0x31, 0xa1, 0x25, 0x6a, 0xb4, 0xf3, 0x07, 0x5f, 0x0c, 0x99, 0x33, 0x68, - 0xbf, 0x2c, 0xa1, 0xfd, 0xde, 0x16, 0x2d, 0x4a, 0x5a, 0xa0, 0x7e, 0xe5, - 0x9b, 0x89, 0x4a, 0x8d, 0xe7, 0x18, 0x21, 0x32, 0x47, 0x3c, 0x9d, 0x48, - 0xab, 0x7d, 0xca, 0xb4, 0x63, 0xd9, 0xfd, 0x29, 0x2d, 0x4c, 0xf1, 0xf2, - 0x20, 0x0a, 0x91, 0x2e, 0x2c, 0xa1, 0x49, 0x83, 0x73, 0x15, 0xa0, 0x7d, - 0x6e, 0xae, 0x51, 0x45, 0x0d, 0x09, 0x1f, 0x8f, 0x61, 0x42, 0xbd, 0x24, - 0xcd, 0x3e, 0xe8, 0x66, 0x84, 0xc6, 0x97, 0x08, 0x7b, 0x72, 0x73, 0x7e, - 0xe7, 0x99, 0x05, 0xab, 0x63, 0xff, 0x3c, 0x44, 0xa1, 0xc0, 0x1b, 0xfc, - 0xff, 0x27, 0xe9, 0x45, 0x82, 0x75, 0x82, 0x6f, 0x9c, 0x65, 0xef, 0x67, - 0xd6, 0x00, 0xd1, 0x9f, 0x61, 0x9f, 0x38, 0xdd, 0x7f, 0x5f, 0x4d, 0x67, - 0x5b, 0x5d, 0xff, 0x98, 0x6b, 0x13, 0xe0, 0xe7, 0x69, 0xcb, 0x7f, 0x7c, - 0x11, 0x91, 0xe0, 0x05, 0xb9, 0x64, 0xd0, 0xb7, 0x91, 0xe5, 0xd4, 0x3a, - 0x47, 0x05, 0x25, 0x4f, 0x15, 0x46, 0xaf, 0x41, 0x9e, 0xc7, 0x49, 0x15, - 0x17, 0xd1, 0x9c, 0x28, 0xef, 0x80, 0xa3, 0x8b, 0x60, 0xcc, 0x60, 0xeb, - 0x96, 0x36, 0x3a, 0x23, 0x94, 0xf3, 0x6c, 0xe5, 0x3f, 0xe8, 0x8b, 0x5c, - 0x8c, 0xfe, 0x6f, 0x91, 0x65, 0x19, 0xa1, 0x4d, 0x45, 0x7b, 0x06, 0x0f, - 0x71, 0xb7, 0x9a, 0x8d, 0x8e, 0x82, 0x7b, 0x68, 0x44, 0xa4, 0xa6, 0xc3, - 0xe5, 0x67, 0x9f, 0x6c, 0xd0, 0xe4, 0xe8, 0x37, 0x08, 0x6b, 0xbb, 0xa0, - 0x3a, 0xd0, 0xa9, 0xd9, 0x04, 0xaa, 0x91, 0xac, 0x71, 0xff, 0xec, 0x7e, - 0xaf, 0xa9, 0x99, 0xa2, 0x8d, 0x91, 0x95, 0xb3, 0xd8, 0xe4, 0xf3, 0x3f, - 0xa6, 0x4b, 0x0c, 0x19, 0x23, 0xf7, 0xa7, 0xcd, 0x4c, 0x41, 0x28, 0x63, - 0x9f, 0x0b, 0x8f, 0x70, 0x70, 0xbd, 0x25, 0x16, 0x8e, 0x86, 0x8a, 0x69, - 0xe3, 0x6a, 0xd4, 0x98, 0x42, 0x56, 0x15, 0x2d, 0x3d, 0xdb, 0x17, 0x1b, - 0x23, 0x58, 0x82, 0x56, 0x11, 0x97, 0x85, 0xf2, 0x68, 0x95, 0x92, 0xd5, - 0x9e, 0x91, 0x05, 0x70, 0xc8, 0x96, 0xb2, 0x73, 0x6d, 0x1e, 0x12, 0x8c, - 0xa0, 0xe4, 0x1a, 0x84, 0x5b, 0xb4, 0x32, 0xf7, 0x9e, 0x08, 0xd0, 0x6c, - 0x42, 0xf0, 0x0b, 0xc4, 0x1f, 0xe0, 0xbb, 0x71, 0xe1, 0x2d, 0x86, 0xd7, - 0x77, 0x24, 0x43, 0x53, 0x0c, 0x88, 0x21, 0x75, 0x95, 0xd0, 0xfe, 0x10, - 0x23, 0xcd, 0xba, 0x77, 0x3d, 0x9b, 0x0f, 0xb2, 0xe2, 0xcc, 0x0f, 0x94, - 0xe0, 0x66, 0x90, 0x0e, 0xf7, 0x6a, 0x3c, 0x9f, 0xc0, 0xf6, 0x98, 0x1c, - 0x4c, 0x9f, 0x25, 0xc4, 0xeb, 0x1d, 0x91, 0x32, 0x29, 0x34, 0x2a, 0xb0, - 0x7e, 0x1c, 0x09, 0x77, 0x13, 0x83, 0xfa, 0xcf, 0x24, 0xa2, 0x5f, 0x79, - 0x78, 0x64, 0xf7, 0x45, 0x81, 0xbe, 0x6a, 0x82, 0x26, 0xfd, 0xe7, 0xc3, - 0x61, 0x41, 0x27, 0xcc, 0x99, 0x69, 0x77, 0xc8, 0xa7, 0xf3, 0x52, 0x01, - 0xa7, 0x8c, 0x0b, 0x7d, 0x86, 0x8d, 0xbb, 0x31, 0xd6, 0x67, 0xf9, 0xa7, - 0x8f, 0x76, 0xb6, 0x74, 0x26, 0x43, 0x35, 0xb8, 0x83, 0x7c, 0x16, 0x34, - 0x88, 0x0c, 0xb6, 0xec, 0xf0, 0x01, 0x8c, 0x1c, 0xe5, 0x52, 0xd4, 0xca, - 0x01, 0x2e, 0xb5, 0x87, 0xc1, 0xc1, 0x1b, 0xa3, 0x02, 0x17, 0x13, 0xd3, - 0x35, 0xe8, 0x80, 0xe1, 0xd1, 0x01, 0x9c, 0x0a, 0x62, 0x7d, 0x98, 0x7c, - 0x68, 0xa4, 0x8e, 0x3a, 0x50, 0x4b, 0x95, 0x59, 0xa3, 0x11, 0xf6, 0xa3, - 0xde, 0x92, 0x65, 0x00, 0xa0, 0xe8, 0x32, 0xf0, 0xc3, 0x77, 0x68, 0x0b, - 0xed, 0xc1, 0x69, 0xd2, 0x6e, 0xce, 0x80, 0xe4, 0x56, 0x9b, 0x15, 0xbf, - 0x3c, 0x4a, 0x38, 0x26, 0xf6, 0x6a, 0xdb, 0x62, 0x7a, 0xab, 0xb1, 0x77, - 0x75, 0x0d, 0xa7, 0xa4, 0xcf, 0x5e, 0x2d, 0xea, 0x24, 0x84, 0xbd, 0x83, - 0x8e, 0xaa, 0x91, 0xe1, 0x72, 0x5f, 0x7f, 0x26, 0x54, 0x4f, 0xab, 0xa6, - 0x50, 0x22, 0x68, 0x8c, 0xa6, 0x06, 0x67, 0x3c, 0x3e, 0x93, 0x9a, 0xc2, - 0x53, 0x15, 0x08, 0x1a, 0x3c, 0xb3, 0x3f, 0xf0, 0x83, 0xf5, 0x0d, 0x9c, - 0xe3, 0x76, 0x11, 0x45, 0x21, 0x6b, 0x65, 0x97, 0xea, 0x3c, 0xdb, 0x0d, - 0xcd, 0x6e, 0xb7, 0x26, 0x7b, 0x82, 0x63, 0x35, 0x7e, 0x76, 0xf4, 0xb8, - 0x0e, 0xe5, 0x1d, 0x95, 0x94, 0x1c, 0x60, 0xc7, 0xea, 0x9c, 0x1c, 0x73, - 0x75, 0x0e, 0x9b, 0x5f, 0x78, 0x09, 0x4f, 0x90, 0x31, 0x5c, 0xc8, 0x5b, - 0x78, 0xce, 0xb3, 0x3e, 0x31, 0x61, 0x90, 0xba, 0xe0, 0xe1, 0x57, 0x1d, - 0x71, 0x80, 0x92, 0x6b, 0x75, 0xe1, 0x34, 0x95, 0xeb, 0x88, 0xe4, 0x0b, - 0x72, 0xdc, 0x34, 0x24, 0x3b, 0x6d, 0x94, 0xc9, 0xe9, 0x8d, 0x38, 0x72, - 0x9c, 0x61, 0x6e, 0x07, 0xd7, 0x35, 0xa1, 0x74, 0xc2, 0x0c, 0x36, 0xc3, - 0x54, 0xd3, 0xe5, 0xd1, 0x08, 0x8e, 0x24, 0x77, 0xf5, 0x61, 0xcf, 0x69, - 0x9b, 0x27, 0x70, 0xe7, 0x52, 0xf6, 0xef, 0x66, 0x8f, 0x0e, 0x8b, 0xc0, - 0xf3, 0x64, 0x2a, 0xa8, 0xff, 0xcc, 0xd9, 0x61, 0x53, 0xac, 0x36, 0x23, - 0x4f, 0x3c, 0x0f, 0xe0, 0xec, 0xad, 0xc5, 0x35, 0x3f, 0x3b, 0x74, 0x26, - 0x84, 0x48, 0xd1, 0xfe, 0x72, 0x01, 0xea, 0x4d, 0x03, 0x46, 0x66, 0x5a, - 0xc4, 0x0a, 0x55, 0x43, 0x61, 0x36, 0x6a, 0xc1, 0xd2, 0x74, 0x0a, 0x8f, - 0x01, 0xb2, 0xc2, 0xaa, 0xd7, 0x2d, 0x0a, 0x0f, 0x67, 0xa1, 0x25, 0x7d, - 0x45, 0x60, 0x0f, 0x06, 0xfb, 0x8f, 0x8b, 0xe0, 0x4a, 0x8c, 0xd7, 0x19, - 0xac, 0xcc, 0x47, 0xa2, 0x7c, 0x30, 0x90, 0x94, 0x81, 0xab, 0xde, 0x38, - 0xb8, 0xc9, 0xdb, 0x63, 0x9c, 0xcb, 0xdd, 0x71, 0xde, 0x4f, 0x1e, 0x43, - 0x08, 0xe4, 0xe3, 0x83, 0x86, 0x0f, 0x34, 0xb7, 0x1e, 0x53, 0xc1, 0xde, - 0x46, 0xf1, 0x70, 0xf5, 0xd8, 0x47, 0xd2, 0x9b, 0x44, 0x88, 0x85, 0x8e, - 0x32, 0xa9, 0x0c, 0x09, 0x2f, 0xd0, 0xe4, 0x4b, 0x30, 0x3a, 0x2e, 0x65, - 0x0c, 0xff, 0xb4, 0x0d, 0xa8, 0x8f, 0x61, 0x3e, 0x7e, 0x90, 0x66, 0xbb, - 0xf6, 0xbe, 0xfd, 0x7d, 0xe4, 0xdc, 0x2c, 0x59, 0x87, 0x81, 0x60, 0x96, - 0xd7, 0x1d, 0x10, 0x02, 0x35, 0xdd, 0x16, 0x4c, 0xe9, 0x2d, 0x52, 0x45, - 0xdd, 0x3f, 0xc9, 0xff, 0x8d, 0x19, 0xad, 0x02, 0x74, 0xf1, 0x09, 0x99, - 0x94, 0x66, 0x2e, 0x8b, 0xa3, 0xdc, 0x3d, 0xf3, 0xf5, 0x85, 0xf2, 0x60, - 0x7d, 0x9d, 0xe0, 0xd3, 0x0f, 0xa4, 0x92, 0xf3, 0x55, 0xbc, 0x7b, 0x20, - 0x6b, 0xf6, 0xc4, 0xc4, 0x0f, 0x8a, 0xd7, 0x5a, 0x02, 0xb0, 0xb7, 0x78, - 0xb4, 0x9e, 0xb6, 0x93, 0x95, 0x2e, 0x76, 0x06, 0x1e, 0x34, 0x5d, 0x34, - 0x77, 0x77, 0x6d, 0x32, 0xbb, 0x46, 0xad, 0x43, 0xd7, 0x72, 0x61, 0x33, - 0x4f, 0x98, 0xe9, 0x56, 0x3a, 0x96, 0x89, 0x6e, 0x1f, 0xaf, 0x6b, 0xa0, - 0x9a, 0xe4, 0x42, 0x5a, 0xb3, 0xb8, 0x2a, 0xe1, 0x2d, 0xa6, 0x32, 0xa2, - 0x01, 0xf5, 0x3a, 0x9a, 0xbb, 0x06, 0x76, 0x0b, 0xa8, 0xac, 0x02, 0x96, - 0x0c, 0x58, 0xd3, 0x64, 0xc8, 0xe2, 0xae, 0x6c, 0xf7, 0xa7, 0x32, 0x4b, - 0x51, 0x50, 0x11, 0x90, 0xcf, 0x37, 0xed, 0xd2, 0xa0, 0xa4, 0x97, 0xb3, - 0x45, 0x1d, 0x7d, 0xf3, 0xff, 0xde, 0x9f, 0x80, 0xa9, 0x61, 0xac, 0x37, - 0x7f, 0x5d, 0xc9, 0xf6, 0xdc, 0x26, 0xd0, 0x65, 0xf2, 0xdc, 0x0c, 0x1a, - 0xcb, 0xde, 0x6b, 0x77, 0xf3, 0x08, 0xa4, 0x93, 0xab, 0x2a, 0xdf, 0x18, - 0x1a, 0xc7, 0xa6, 0xa1, 0x7e, 0x43, 0x75, 0xca, 0x88, 0xcc, 0x6f, 0xa2, - 0x85, 0x0e, 0xb0, 0xd5, 0xcd, 0x8a, 0xff, 0xc1, 0x57, 0x20, 0x66, 0xf7, - 0x19, 0x7a, 0x52, 0x5b, 0x46, 0x87, 0x5f, 0xf7, 0x77, 0xe2, 0xab, 0x4e, - 0x4a, 0xce, 0x8f, 0x3f, 0xe6, 0x9f, 0x88, 0x3a, 0x33, 0x65, 0x3c, 0x3a, - 0x41, 0xc3, 0x8e, 0xee, 0x79, 0xe7, 0x2c, 0xb0, 0x3b, 0x93, 0x82, 0xa0, - 0x1a, 0x71, 0x0e, 0xf6, 0x31, 0xc5, 0x6f, 0xc1, 0xa8, 0x32, 0x89, 0x3b, - 0x33, 0x68, 0x53, 0x81, 0x15, 0x70, 0x5e, 0x22, 0xdc, 0x99, 0xc6, 0x88, - 0xf8, 0x11, 0x06, 0x56, 0x1f, 0x80, 0x7e, 0x0b, 0x27, 0x90, 0xfc, 0x97, - 0x76, 0x61, 0xdc, 0x30, 0x5d, 0x34, 0x4e, 0x83, 0x85, 0xce, 0xe2, 0x91, - 0x4d, 0x8d, 0x92, 0x88, 0x26, 0xa0, 0xde, 0x47, 0x82, 0xd2, 0xa8, 0xa5, - 0xe7, 0x27, 0x0c, 0x45, 0x41, 0x85, 0xa1, 0x12, 0xcb, 0x3a, 0x74, 0x53, - 0x93, 0x77, 0xd0, 0x8b, 0x42, 0x8d, 0x00, 0xca, 0x44, 0x67, 0xa0, 0x6a, - 0xbd, 0xcd, 0x4a, 0x3c, 0xfe, 0x6c, 0xa1, 0x48, 0x26, 0x0d, 0x51, 0x54, - 0x59, 0xc9, 0xf9, 0x51, 0x5c, 0xd3, 0x55, 0xf0, 0x72, 0x77, 0xdb, 0x52, - 0xee, 0x0a, 0x5e, 0x8a, 0xf0, 0xbe, 0x9a, 0x37, 0xa0, 0x1b, 0x94, 0xe3, - 0x2d, 0x17, 0xc4, 0xbe, 0x9c, 0xad, 0x9c, 0xd1, 0xc6, 0xbc, 0x36, 0x5c, - 0x3b, 0xe3, 0x2e, 0x66, 0x29, 0x0c, 0x3a, 0x3d, 0xe7, 0xe3, 0xf3, 0x58, - 0x70, 0x3e, 0x59, 0xb2, 0x6c, 0x91, 0x14, 0xfe, 0x9e, 0x5e, 0x5d, 0xb2, - 0x7b, 0x46, 0x66, 0x46, 0x55, 0xe2, 0x78, 0x47, 0xeb, 0xdf, 0x2b, 0xb4, - 0xf2, 0xb2, 0x14, 0xbe, 0x64, 0x9e, 0x17, 0x16, 0x9f, 0xf5, 0x6a, 0xdd, - 0x25, 0xa1, 0x55, 0x6e, 0xb1, 0xfa, 0x09, 0xd0, 0x97, 0x7c, 0x13, 0xde, - 0x1d, 0xd4, 0x94, 0x19, 0xde, 0x8b, 0x4d, 0xe7, 0xee, 0x1f, 0xdf, 0xe5, - 0x3b, 0xdd, 0xbd, 0x13, 0x9c, 0xec, 0xcd, 0xb6, 0xb6, 0xbb, 0x3f, 0xbd, - 0x54, 0xca, 0x47, 0x5c, 0x05, 0x3c, 0x03, 0x30, 0x9d, 0x56, 0xf6, 0xc6, - 0x48, 0x6b, 0x74, 0x49, 0x58, 0xa2, 0xd8, 0x45, 0x42, 0x6f, 0xe4, 0x46, - 0x27, 0x92, 0x83, 0x78, 0x97, 0x55, 0x5b, 0x82, 0xce, 0x2a, 0x08, 0x41, - 0xb9, 0x7a, 0x66, 0x0f, 0x3c, 0x5b, 0xdf, 0x8d, 0x1d, 0x02, 0x11, 0xa4, - 0xa7, 0x0a, 0x80, 0x1e, 0xbb, 0x7a, 0xc9, 0x2f, 0xb9, 0x35, 0xc8, 0xd7, - 0x98, 0x04, 0x29, 0xaa, 0x4b, 0x88, 0x66, 0x73, 0xe4, 0x59, 0xc4, 0x3e, - 0x50, 0xad, 0xe5, 0x64, 0x54, 0xf0, 0x29, 0x38, 0xee, 0xc0, 0x00, 0xc4, - 0x22, 0x16, 0xf2, 0xc5, 0x46, 0x5c, 0xee, 0x9e, 0xf2, 0x9a, 0xe7, 0xfd, - 0x62, 0x50, 0xa2, 0xeb, 0x47, 0x56, 0x4c, 0xe4, 0x75, 0x46, 0xe4, 0xd5, - 0x25, 0xec, 0xe0, 0x35, 0x33, 0x31, 0x34, 0x1b, 0xcb, 0x72, 0x78, 0x1c, - 0x4d, 0x3a, 0x19, 0x2e, 0xc4, 0xb7, 0xa4, 0x80, 0xd2, 0x91, 0xeb, 0x2a, - 0x1d, 0xf2, 0xd1, 0xa3, 0xae, 0xac, 0x41, 0xae, 0xc2, 0x44, 0xd2, 0x3f, - 0xb4, 0x87, 0x8d, 0x69, 0x6c, 0x67, 0xd6, 0x85, 0xee, 0xd6, 0x3b, 0x03, - 0xdc, 0x58, 0x46, 0x07, 0x73, 0xb4, 0xb0, 0x3f, 0x5e, 0xc1, 0x13, 0x2c, - 0x36, 0x58, 0xd0, 0x1c, 0x34, 0x3e, 0x01, 0x88, 0xfa, 0xb1, 0x9a, 0x03, - 0x85, 0x4f, 0x4c, 0xd2, 0xac, 0xd9, 0x12, 0x09, 0xaa, 0x5f, 0x20, 0x06, - 0x1f, 0x0a, 0x44, 0x28, 0x50, 0xd1, 0x8f, 0x51, 0x8a, 0x1d, 0xfa, 0xaa, - 0x46, 0x33, 0xac, 0x0c, 0xb3, 0x10, 0xcf, 0x24, 0x4d, 0x0f, 0xcd, 0xee, - 0xd9, 0x64, 0x4a, 0x1a, 0x84, 0x0f, 0xff, 0x48, 0x8d, 0x79, 0xd4, 0x43, - 0x70, 0x1c, 0x7e, 0x7e, 0x12, 0x43, 0x51, 0x4a, 0x7e, 0x45, 0x9e, 0xa4, - 0x3c, 0x12, 0xbd, 0x95, 0xe9, 0xd6, 0xd4, 0x3f, 0xbf, 0x03, 0xae, 0x9e, - 0x24, 0x1a, 0x36, 0xbd, 0xea, 0x5d, 0x65, 0xff, 0x9f, 0x95, 0x70, 0xda, - 0xb0, 0x53, 0x6a, 0x5f, 0x64, 0x7b, 0xb6, 0x7a, 0x8d, 0xa2, 0xd4, 0x9c, - 0xb1, 0xf9, 0xe6, 0x14, 0x62, 0x3b, 0xe7, 0x5b, 0x40, 0x9d, 0xf4, 0x19, - 0xb5, 0x50, 0xc8, 0xbd, 0x76, 0xd3, 0xbc, 0x0e, 0x6d, 0x62, 0x91, 0x73, - 0x3e, 0x7f, 0xbf, 0xd0, 0xf0, 0x33, 0xf8, 0x6a, 0x9f, 0xa6, 0xad, 0xc3, - 0xa0, 0x8f, 0x45, 0x99, 0x86, 0xa7, 0x49, 0x18, 0x8a, 0xed, 0xf1, 0x7d, - 0x39, 0xf4, 0xb4, 0xf9, 0x82, 0x62, 0xd0, 0xa1, 0xb8, 0x3f, 0xe8, 0x25, - 0xf7, 0xb1, 0x59, 0xce, 0x31, 0xba, 0x1d, 0x0b, 0x1f, 0x3d, 0x6c, 0x8b, - 0xd2, 0xc5, 0x4e, 0x8e, 0xe8, 0x09, 0x9e, 0x1f, 0xf3, 0x67, 0x6f, 0x09, - 0x03, 0x9d, 0xfe, 0x57, 0x6d, 0x9b, 0xce, 0x99, 0x7b, 0x01, 0x04, 0x52, - 0xf5, 0x41, 0x7e, 0x38, 0x56, 0xb8, 0x71, 0x44, 0x43, 0x2c, 0x5e, 0x92, - 0x9d, 0x95, 0xff, 0x0b, 0xf8, 0xfa, 0x89, 0x2c, 0x58, 0xde, 0xc5, 0x4e, - 0x02, 0xe3, 0x82, 0xf7, 0xdc, 0x92, 0xa8, 0x7c, 0x39, 0x32, 0x76, 0x68, - 0x9c, 0x73, 0x75, 0x1f, 0xbc, 0x6b, 0x46, 0x33, 0x5a, 0xdb, 0x94, 0x8c, - 0x76, 0x79, 0x7e, 0x9b, 0xcc, 0x37, 0xeb, 0xed, 0xdc, 0xd5, 0xee, 0x2b, - 0x30, 0x3f, 0x7b, 0x9b, 0xac, 0x38, 0x8f, 0xf1, 0x5e, 0xec, 0xa0, 0x46, - 0x2c, 0xd1, 0x27, 0x19, 0x60, 0xec, 0xe2, 0xa7, 0x45, 0x61, 0x2d, 0xa8, - 0x7e, 0xa9, 0xf8, 0x93, 0xa4, 0x23, 0x3e, 0xd8, 0x9c, 0xcc, 0xb3, 0xee, - 0xc3, 0x1c, 0xfb, 0xbb, 0xad, 0xec, 0x73, 0x66, 0x31, 0x5d, 0x88, 0x9a, - 0xec, 0x84, 0x91, 0x1e, 0x58, 0xdd, 0xb0, 0x01, 0x46, 0x18, 0x43, 0x64, - 0xe2, 0xad, 0xac, 0x5a, 0x63, 0x4c, 0x32, 0x6b, 0xfd, 0xff, 0x66, 0x6d, - 0xb4, 0x66, 0x88, 0xec, 0xfe, 0x23, 0xaa, 0x3a, 0x2a, 0xd5, 0xff, 0xed, - 0x3a, 0x13, 0x9a, 0xae, 0x73, 0xc5, 0x62, 0x32, 0x47, 0x89, 0x19, 0x7f, - 0x2c, 0x88, 0x62, 0x34, 0xc2, 0x90, 0xa9, 0x59, 0x7c, 0x45, 0xdb, 0x98, - 0xaf, 0xf4, 0xba, 0x4e, 0x45, 0x55, 0xfc, 0x70, 0xa9, 0xfd, 0xb4, 0xa3, - 0xd9, 0xa8, 0xfb, 0xe2, 0xe6, 0xf9, 0x60, 0xc1, 0x42, 0x70, 0x3d, 0xa5, - 0x28, 0xcc, 0xd3, 0x54, 0x87, 0xda, 0x93, 0x91, 0x42, 0xa8, 0x8b, 0x62, - 0xf3, 0x4e, 0xb7, 0x86, 0xfa, 0x52, 0x19, 0x69, 0xe3, 0x6c, 0xd1, 0xc3, - 0x23, 0x82, 0xf7, 0x1d, 0xa1, 0x80, 0x92, 0xcd, 0x5e, 0x1a, 0x62, 0x3e, - 0x1b, 0x31, 0x9d, 0x0d, 0xa8, 0x25, 0x3e, 0x83, 0xae, 0x36, 0xce, 0xfd, - 0xac, 0xf7, 0x35, 0x7f, 0x74, 0xf4, 0x66, 0xa3, 0x5f, 0x00, 0xe5, 0x30, - 0xc1, 0x11, 0x70, 0x00, 0xb5, 0xd9, 0xd4, 0x6e, 0x95, 0xc4, 0xbc, 0x5b, - 0x7d, 0x62, 0x6c, 0xd5, 0xc0, 0x1e, 0x81, 0xc0, 0x61, 0x69, 0x13, 0x63, - 0xbc, 0x7f, 0x70, 0x3f, 0x3d, 0x96, 0x18, 0x39, 0xef, 0x51, 0xc6, 0xe9, - 0xcc, 0x59, 0xda, 0xc7, 0x5d, 0xb5, 0x59, 0xb0, 0xf2, 0x99, 0x5a, 0x36, - 0x21, 0x0d, 0xcc, 0x97, 0x16, 0x2b, 0x61, 0x3d, 0x0a, 0xd1, 0x6e, 0x05, - 0x86, 0x42, 0xff, 0xd8, 0xa7, 0x5c, 0x02, 0xcf, 0x90, 0x6b, 0x4e, 0xee, - 0x4e, 0xca, 0xdb, 0xd3, 0xfe, 0x7e, 0x9b, 0xe2, 0xf0, 0xa3, 0x45, 0x6d, - 0xa9, 0x92, 0xba, 0xce, 0xc6, 0x2e, 0x0a, 0xbc, 0xb2, 0x7a, 0x57, 0x07, - 0x33, 0xc2, 0xa7, 0x16, 0x25, 0x06, 0x36, 0x83, 0x35, 0x31, 0x87, 0x18, - 0x83, 0xa3, 0xc2, 0x88, 0x55, 0xcc, 0xe4, 0x84, 0x4c, 0xce, 0xb9, 0xeb, - 0xd5, 0xb2, 0xbe, 0x3d, 0x76, 0x85, 0x10, 0x07, 0x83, 0xfa, 0x1c, 0x42, - 0xbc, 0xa3, 0x4c, 0x29, 0x49, 0xe6, 0xc0, 0x30, 0x59, 0xe0, 0xc6, 0xbe, - 0xa7, 0x48, 0x4a, 0xcf, 0x0e, 0x8e, 0xb7, 0x38, 0xf2, 0xa6, 0x26, 0xd3, - 0x88, 0x06, 0x99, 0x46, 0x19, 0x65, 0x1c, 0x91, 0x8e, 0xae, 0x90, 0x78, - 0x77, 0x7f, 0xe0, 0xc2, 0x51, 0x6f, 0xb6, 0x44, 0x15, 0xf9, 0xc5, 0x8a, - 0x6c, 0x33, 0xd5, 0x90, 0x17, 0xc2, 0xca, 0x4e, 0xe1, 0x1f, 0xef, 0x02, - 0x43, 0x05, 0x3f, 0x1e, 0xb1, 0x13, 0x23, 0x1f, 0xd6, 0xc2, 0xac, 0xc4, - 0x49, 0x7a, 0x86, 0x06, 0x4b, 0xa1, 0x55, 0x6a, 0x75, 0x91, 0x4e, 0x6b, - 0x86, 0x95, 0xa7, 0xbc, 0xdc, 0x64, 0xdb, 0x81, 0xc6, 0xa5, 0x33, 0x38, - 0x98, 0xbb, 0xac, 0x03, 0xf0, 0xba, 0x49, 0xcf, 0x1c, 0xce, 0xe2, 0x3d, - 0xe5, 0x06, 0xbc, 0x5e, 0xd0, 0xf7, 0x1c, 0xbb, 0x52, 0xa1, 0x47, 0x98, - 0x12, 0xef, 0x1c, 0xb9, 0x53, 0xec, 0x67, 0x2c, 0xf0, 0x7d, 0x85, 0x9e, - 0x45, 0x87, 0x00, 0x67, 0x2f, 0xa5, 0x19, 0x9f, 0x3e, 0x20, 0x8c, 0xe9, - 0xfa, 0x8a, 0xd8, 0x02, 0x6e, 0x16, 0xc4, 0x43, 0xff, 0x08, 0x3f, 0xf3, - 0x76, 0x53, 0x95, 0x17, 0x6e, 0x74, 0xfe, 0x7e, 0x87, 0x66, 0xc9, 0xe8, - 0x8d, 0x21, 0xea, 0xd2, 0x4d, 0xc7, 0x9c, 0x5a, 0xef, 0xd5, 0xe1, 0x12, - 0x85, 0x22, 0x40, 0x3c, 0x9d, 0x89, 0x4f, 0x12, 0xb5, 0x01, 0x95, 0x0e, - 0x9b, 0xd3, 0x38, 0x5e, 0x21, 0x5a, 0x4e, 0x7e, 0xce, 0xf7, 0xa6, 0x5a, - 0x63, 0x78, 0x40, 0xba, 0x9f, 0x29, 0xf0, 0x75, 0xb6, 0x8b, 0xd9, 0x4c, - 0xab, 0xb9, 0xf4, 0xe9, 0x1f, 0x39, 0x01, 0xb3, 0xfc, 0x2c, 0xa4, 0x74, - 0xa9, 0xa9, 0x90, 0xed, 0x77, 0xd8, 0x0c, 0x6d, 0x5c, 0x7b, 0xfc, 0xbd, - 0x96, 0x96, 0xcb, 0x9b, 0x9f, 0x88, 0x86, 0x5c, 0x3c, 0x0a, 0xde, 0x28, - 0x7c, 0xf0, 0x91, 0x1c, 0x06, 0x52, 0xbe, 0xad, 0xc8, 0xef, 0xa5, 0xd3, - 0x1e, 0x29, 0xbd, 0x1d, 0xd5, 0xba, 0xf4, 0x83, 0x2d, 0x36, 0x9a, 0x8c, - 0x8d, 0x83, 0xac, 0x3f, 0xea, 0xd2, 0x2e, 0xfb, 0xf1, 0xaa, 0x7a, 0x2e, - 0xce, 0xd3, 0x90, 0x9f, 0x3c, 0x2c, 0xee, 0xed, 0xf8, 0xfc, 0x3c, 0x0e, - 0x5f, 0xd1, 0xda, 0x9c, 0x32, 0x52, 0xcd, 0x09, 0xa1, 0x53, 0x33, 0x37, - 0xe0, 0x37, 0x95, 0xb2, 0x8d, 0x03, 0x46, 0x1f, 0xb5, 0x99, 0x65, 0x54, - 0x61, 0xa2, 0xdc, 0xe9, 0x87, 0x4d, 0x41, 0xdf, 0xd1, 0xb5, 0x2c, 0x7a, - 0x46, 0x08, 0x5e, 0x0f, 0xcc, 0x80, 0x96, 0x52, 0x98, 0xa0, 0x82, 0x52, - 0x6d, 0x62, 0x6f, 0xd9, 0x48, 0xc1, 0x36, 0x0c, 0x5c, 0x7f, 0xad, 0x2c, - 0x27, 0xcf, 0x17, 0xee, 0xfa, 0xca, 0x14, 0xe7, 0x88, 0xc4, 0x20, 0xb2, - 0xa1, 0xd2, 0x66, 0xe8, 0x81, 0xce, 0x35, 0x2b, 0x30, 0x54, 0x16, 0x9e, - 0x42, 0x77, 0x16, 0x3b, 0x84, 0x77, 0x42, 0x71, 0x33, 0xf8, 0x62, 0x9e, - 0xd4, 0x1d, 0x1d, 0xf3, 0x91, 0x60, 0x97, 0xd8, 0x10, 0x29, 0xc8, 0xf9, - 0xfa, 0xca, 0x0a, 0xe9, 0x50, 0xe1, 0xcc, 0xa7, 0xe3, 0x77, 0xc2, 0x93, - 0x68, 0x50, 0x1a, 0x98, 0xd7, 0x68, 0x40, 0x80, 0x12, 0x64, 0xa7, 0x1d, - 0xb4, 0x52, 0x85, 0x7b, 0x0e, 0x85, 0x0a, 0x59, 0x6a, 0xc8, 0xe4, 0x4b, - 0xff, 0xd7, 0x0d, 0x7d, 0x9e, 0xef, 0x07, 0x2f, 0x6d, 0x46, 0x05, 0xf9, - 0x05, 0xb1, 0x97, 0x94, 0x23, 0xc5, 0x2a, 0x99, 0xcc, 0x9c, 0xc2, 0x82, - 0x97, 0xbc, 0x24, 0x9b, 0xe4, 0xf2, 0xb3, 0x12, 0x84, 0xa0, 0x2a, 0xc4, - 0x7d, 0x29, 0x4d, 0xa4, 0x97, 0xd0, 0x85, 0xa6, 0x39, 0x18, 0xd2, 0xfb, - 0xa7, 0x08, 0x53, 0x75, 0x6b, 0xbd, 0xe3, 0x98, 0x4c, 0x94, 0xdd, 0xd4, - 0x86, 0x94, 0xc2, 0x6a, 0x14, 0x23, 0xdd, 0x69, 0xae, 0x53, 0xec, 0x83, - 0x58, 0x8e, 0x87, 0x7b, 0xf1, 0xcf, 0xff, 0x34, 0xda, 0x39, 0x67, 0xba, - 0x90, 0xc5, 0xec, 0xe0, 0xb3, 0xad, 0xad, 0x3d, 0x4c, 0x8e, 0x3f, 0x08, - 0x62, 0x80, 0x5b, 0x2d, 0xf8, 0xe1, 0x67, 0x61, 0x79, 0xf5, 0xc9, 0xbe, - 0x74, 0x1b, 0x72, 0x02, 0x56, 0xc6, 0xf8, 0xd5, 0x87, 0x3a, 0x08, 0x7b, - 0x35, 0x8f, 0xdf, 0xdf, 0x87, 0x3e, 0x09, 0xf7, 0xd2, 0x74, 0xbb, 0xec, - 0x8c, 0x49, 0x0c, 0xb5, 0x3a, 0x6b, 0x33, 0x43, 0x52, 0xe2, 0x2f, 0x71, - 0x3e, 0x6f, 0x59, 0x52, 0x50, 0x8f, 0xdb, 0xa6, 0x52, 0xa7, 0x5d, 0xda, - 0x16, 0x71, 0xb2, 0x52, 0xd7, 0x3e, 0x2d, 0xf6, 0x98, 0x53, 0x0f, 0x8f, - 0xc1, 0x79, 0xd0, 0xcf, 0xe0, 0xc8, 0x22, 0x27, 0x41, 0x14, 0xe8, 0xb8, - 0xed, 0x65, 0x3c, 0xaa, 0x11, 0x72, 0x41, 0xa8, 0xd8, 0x0b, 0x35, 0x81, - 0xec, 0xa6, 0x12, 0x30, 0x23, 0x0b, 0x71, 0x7a, 0x28, 0xd9, 0x01, 0x82, - 0x35, 0xd1, 0x64, 0x6d, 0xf3, 0x63, 0x69, 0x78, 0xb4, 0x93, 0x1e, 0x05, - 0xc9, 0xb3, 0xbc, 0xb6, 0xc4, 0x5e, 0xb6, 0x2a, 0x6e, 0xec, 0x91, 0x4a, - 0x5c, 0xa2, 0x5c, 0xea, 0x2b, 0xe3, 0x33, 0x1a, 0xb3, 0x70, 0xd5, 0x39, - 0x77, 0x3e, 0xa2, 0x96, 0xd5, 0x10, 0x75, 0x8a, 0x91, 0xc6, 0xbc, 0xb6, - 0x86, 0xa6, 0x8f, 0xd3, 0x50, 0x09, 0xa3, 0x9a, 0x1f, 0xd0, 0xd7, 0xd7, - 0x23, 0xa0, 0x32, 0xd0, 0x69, 0x33, 0x2f, 0x18, 0xf2, 0x6f, 0xe2, 0xbc, - 0x2f, 0x7f, 0xf5, 0x46, 0x81, 0x2e, 0xad, 0x14, 0xc9, 0x57, 0x10, 0xa4, - 0x71, 0xa9, 0xa4, 0x05, 0x50, 0xcb, 0x93, 0xc7, 0x53, 0x84, 0x68, 0xa5, - 0x7c, 0x65, 0xc0, 0xe0, 0x37, 0xd6, 0xc3, 0xbb, 0x36, 0xef, 0x22, 0x9e, - 0x09, 0x32, 0xa5, 0xa6, 0x73, 0x61, 0xb6, 0x3c, 0x5a, 0xbe, 0x2f, 0x63, - 0x01, 0x35, 0xfe, 0xd8, 0x98, 0xd5, 0x7e, 0xfd, 0x68, 0xd8, 0x96, 0x51, - 0x6e, 0x3a, 0x17, 0x90, 0x16, 0xeb, 0x03, 0xfa, 0x0a, 0x83, 0x1a, 0xc9, - 0x48, 0x14, 0x31, 0x32, 0x07, 0x7d, 0xa8, 0xa8, 0x64, 0xd8, 0xba, 0xcf, - 0x87, 0xc5, 0x0e, 0xc3, 0x1c, 0x5b, 0xfe, 0x31, 0x98, 0xea, 0x25, 0x29, - 0x9c, 0x77, 0xf2, 0x9f, 0x5e, 0x16, 0x11, 0x6b, 0x29, 0x08, 0xab, 0xb0, - 0x57, 0xd8, 0x3d, 0x85, 0xdc, 0x3b, 0x69, 0xea, 0xd5, 0xe6, 0x90, 0xfa, - 0x95, 0x8d, 0xcc, 0x3c, 0x2d, 0x86, 0x07, 0xc6, 0x7e, 0x8d, 0xc4, 0x7a, - 0x3a, 0xcd, 0x61, 0xa4, 0x1f, 0xd9, 0x6f, 0x07, 0xa3, 0x45, 0xe8, 0x41, - 0xed, 0x51, 0x14, 0xe4, 0x3d, 0x20, 0x3b, 0x11, 0x9e, 0x93, 0xc3, 0x2e, - 0xcd, 0x29, 0x85, 0xf0, 0x61, 0x68, 0x8e, 0x19, 0xdc, 0x20, 0x0a, 0xbd, - 0xc0, 0x15, 0x90, 0x08, 0x96, 0xcf, 0x9b, 0xf3, 0xb5, 0x7b, 0xe4, 0x9a, - 0x97, 0x22, 0x93, 0x40, 0xd4, 0xde, 0x7a, 0x6e, 0x6b, 0xc4, 0x16, 0x9e, - 0x1c, 0x98, 0x9b, 0x83, 0x6e, 0x4d, 0xde, 0x11, 0x4f, 0x22, 0xed, 0x2d, - 0xe1, 0xb3, 0xfa, 0x86, 0xb0, 0xd2, 0x53, 0xd2, 0x34, 0x8a, 0x58, 0xdc, - 0x8c, 0xd9, 0x60, 0xd3, 0x46, 0x0a, 0xde, 0x48, 0xa3, 0xda, 0x5b, 0x74, - 0x3e, 0x4c, 0x51, 0xa6, 0x02, 0x20, 0xc6, 0x0d, 0xdb, 0x13, 0x42, 0xad, - 0xc6, 0x90, 0xb1, 0xe0, 0xb0, 0xac, 0xdc, 0xa7, 0x48, 0xf8, 0x2d, 0x8f, - 0xd7, 0xd9, 0x10, 0xeb, 0xd8, 0xdb, 0xf0, 0x53, 0x67, 0xa9, 0x03, 0x3e, - 0x97, 0xbf, 0xe6, 0xc3, 0xa8, 0x87, 0x3a, 0x91, 0xb8, 0xcf, 0x88, 0x5b, - 0x0d, 0x06, 0xe1, 0xe2, 0x39, 0x74, 0xc8, 0x59, 0xe0, 0x90, 0x9f, 0xc9, - 0x0a, 0x74, 0xa3, 0xb2, 0xae, 0x69, 0x79, 0xfa, 0x0d, 0xf2, 0xee, 0xde, - 0xec, 0x88, 0xbf, 0x09, 0x54, 0xd6, 0xbe, 0xbb, 0x25, 0x91, 0xe4, 0x66, - 0xd2, 0x08, 0x78, 0xda, 0x9d, 0x07, 0xc3, 0x0b, 0x3f, 0x1a, 0xd9, 0xf4, - 0xb2, 0x2d, 0x69, 0x74, 0xb1, 0x78, 0x5f, 0xc1, 0xaf, 0x7f, 0x6d, 0x17, - 0xfc, 0x2c, 0x67, 0x62, 0xce, 0xb4, 0x41, 0x6e, 0x21, 0x4b, 0x5c, 0x77, - 0xa1, 0x1f, 0xfe, 0xe6, 0x28, 0xc8, 0x52, 0xd1, 0x8e, 0x66, 0x88, 0x65, - 0x0c, 0x58, 0xec, 0x1c, 0x71, 0x4c, 0x8a, 0xc0, 0xef, 0x3e, 0x34, 0xf7, - 0x90, 0x67, 0x28, 0x16, 0x20, 0x3a, 0x2c, 0x3f, 0x51, 0x53, 0x15, 0x1c, - 0x6c, 0x75, 0x0e, 0xe1, 0xb4, 0xf3, 0x7f, 0x60, 0x3a, 0x81, 0x34, 0x82, - 0x51, 0x5e, 0x75, 0xb0, 0x5c, 0x37, 0x87, 0x2d, 0xd5, 0xc5, 0x2c, 0xab, - 0x33, 0x8a, 0x60, 0x49, 0x2c, 0xde, 0x90, 0x12, 0x11, 0x1f, 0x4b, 0x27, - 0x15, 0x92, 0xa2, 0xf1, 0x1a, 0xde, 0x35, 0x34, 0x4d, 0x52, 0xcd, 0xc0, - 0x71, 0x46, 0x7f, 0x3e, 0x21, 0x92, 0x5f, 0xc8, 0x25, 0xd4, 0x2c, 0xf4, - 0xd9, 0x38, 0xde, 0xa5, 0xae, 0x83, 0xe3, 0x50, 0x9b, 0x1b, 0xad, 0x4b, - 0xd8, 0x3f, 0x0a, 0x23, 0x40, 0x1e, 0x46, 0x7a, 0x71, 0x06, 0xac, 0x9e, - 0x06, 0xb8, 0x96, 0xef, 0x07, 0xef, 0x38, 0xe9, 0x79, 0xaa, 0x64, 0x44, - 0xa9, 0xa3, 0xc5, 0x1d, 0x5d, 0xd3, 0xa7, 0x01, 0xef, 0xf6, 0x3b, 0x15, - 0x00, 0x0c, 0xf7, 0x59, 0x4a, 0x1c, 0x12, 0x20, 0x89, 0xa8, 0x4e, 0x7b, - 0xf8, 0x9d, 0x02, 0xa6, 0x5e, 0x19, 0x7e, 0xb8, 0x5f, 0x46, 0xd9, 0xb1, - 0xbe, 0x25, 0x2c, 0x3c, 0xe7, 0x5d, 0x3b, 0x3f, 0x6f, 0x6e, 0x94, 0x83, - 0xc3, 0x8e, 0x85, 0x65, 0xff, 0xe9, 0x8e, 0x32, 0xcc, 0x68, 0x51, 0x14, - 0xbf, 0x94, 0x21, 0x3f, 0x85, 0xa8, 0x76, 0x44, 0xe6, 0xca, 0x20, 0x84, - 0xec, 0x83, 0x84, 0x64, 0xfb, 0x80, 0x01, 0x73, 0x76, 0x21, 0xd3, 0xf0, - 0x7b, 0x74, 0x5c, 0xbf, 0x71, 0xe6, 0x34, 0xff, 0x58, 0xe8, 0x6f, 0x88, - 0xa6, 0xad, 0xcf, 0x93, 0x2a, 0xc5, 0xc5, 0x23, 0x32, 0xc8, 0xec, 0xbd, - 0xf9, 0x54, 0x3d, 0xda, 0xe4, 0x81, 0x74, 0x94, 0xbf, 0x36, 0x72, 0x11, - 0xf0, 0x8a, 0x8f, 0x1b, 0x55, 0x47, 0x70, 0x7d, 0x61, 0xf0, 0x7b, 0x11, - 0x56, 0xdb, 0xbc, 0xe5, 0x72, 0xf2, 0xbd, 0x0b, 0xa0, 0x80, 0x03, 0x1a, - 0xc6, 0xe9, 0xfc, 0xcd, 0xde, 0x42, 0xae, 0x1a, 0x7d, 0x90, 0x5d, 0x21, - 0x5b, 0x3d, 0x69, 0x6f, 0x42, 0x42, 0xf2, 0x8a, 0xc8, 0xfc, 0xb9, 0xa9, - 0xdf, 0x18, 0xc4, 0x97, 0x91, 0x21, 0x28, 0xfd, 0x82, 0x8a, 0xe7, 0xac, - 0xe5, 0x5d, 0x33, 0x7b, 0x78, 0x0a, 0x48, 0x43, 0xfe, 0xfe, 0xcf, 0x09, - 0x5f, 0xed, 0x18, 0x33, 0x0c, 0xab, 0x8a, 0x5d, 0x63, 0xd5, 0x43, 0x0b, - 0xde, 0x75, 0x56, 0xef, 0x11, 0x05, 0x8c, 0xbb, 0xc0, 0x10, 0x4e, 0x85, - 0x70, 0xe1, 0x7e, 0x62, 0xb6, 0x3a, 0x84, 0x80, 0x17, 0xab, 0x38, 0x59, - 0x0b, 0xe2, 0xb1, 0x31, 0xb8, 0xb5, 0xf5, 0xad, 0xf6, 0xbf, 0x5b, 0xfb, - 0x69, 0xc8, 0xb3, 0xce, 0x65, 0xd4, 0x8e, 0x04, 0xc5, 0xc4, 0x09, 0xba, - 0x36, 0xc9, 0x90, 0xe0, 0xc2, 0x21, 0x3a, 0x94, 0x83, 0xa5, 0xd1, 0xb2, - 0xe1, 0xae, 0x6a, 0x28, 0x22, 0x59, 0x79, 0x72, 0x82, 0x42, 0x89, 0x42, - 0x9c, 0xc3, 0xdf, 0x8d, 0x15, 0x22, 0x14, 0xb3, 0xfd, 0x2a, 0x85, 0xbe, - 0xd3, 0x12, 0xa5, 0x3b, 0x0c, 0x99, 0xb2, 0xe5, 0x43, 0x8d, 0xd7, 0xc0, - 0xa1, 0xb6, 0xb2, 0xae, 0x42, 0x4a, 0xc0, 0xe5, 0x09, 0xa2, 0xf6, 0xa4, - 0xbc, 0x01, 0xee, 0x94, 0xd2, 0x0b, 0xeb, 0x28, 0x80, 0xc9, 0x7a, 0x07, - 0xd7, 0x4b, 0xee, 0x01, 0x10, 0x48, 0xcc, 0xc6, 0x03, 0x99, 0x9d, 0x67, - 0x2a, 0xbd, 0xa0, 0x6f, 0x51, 0xa4, 0x75, 0x50, 0xe1, 0x84, 0x8e, 0xda, - 0x7b, 0x5e, 0x9e, 0x78, 0x18, 0x2a, 0x6b, 0xfa, 0xef, 0x87, 0x81, 0xe9, - 0x48, 0x3f, 0x29, 0x2d, 0xfb, 0x15, 0xd2, 0x15, 0xb5, 0x5c, 0xed, 0x45, - 0x48, 0x30, 0xec, 0x00, 0x55, 0x15, 0x13, 0xc7, 0x11, 0xc4, 0x29, 0xef, - 0x0f, 0xa8, 0xa6, 0xef, 0x19, 0x41, 0xc2, 0xb6, 0x11, 0xdc, 0xe8, 0xf4, - 0xa7, 0x03, 0x80, 0x2d, 0x92, 0xad, 0x7e, 0x7e, 0x8a, 0x71, 0xa4, 0x6c, - 0x16, 0xb9, 0x84, 0xf5, 0x8d, 0x94, 0xc5, 0xd5, 0x82, 0x29, 0x42, 0x22, - 0x1f, 0x06, 0xca, 0xdd, 0xbf, 0x74, 0x0f, 0x14, 0x79, 0x26, 0x9c, 0x79, - 0x30, 0xcb, 0x01, 0x02, 0x76, 0x22, 0x4f, 0x54, 0xff, 0x49, 0xa3, 0x03, - 0x35, 0x23, 0x45, 0x91, 0xac, 0xed, 0x13, 0x31, 0xa4, 0x4e, 0x51, 0xe8, - 0x9c, 0x5b, 0xe4, 0xcf, 0x41, 0xd3, 0xa0, 0x86, 0x7f, 0x3a, 0x4d, 0xaf, - 0xa7, 0x49, 0x63, 0x47, 0x86, 0x08, 0x88, 0xcf, 0x01, 0x7a, 0xc4, 0xf5, - 0x29, 0x67, 0x8a, 0xd4, 0xdd, 0x6a, 0x6d, 0x81, 0xb8, 0x29, 0x9d, 0x7c, - 0x32, 0x4e, 0x8f, 0x0c, 0x9f, 0x8c, 0x7e, 0x76, 0xa3, 0xd4, 0x32, 0x80, - 0xd0, 0x79, 0x7d, 0x56, 0x99, 0x6d, 0x0b, 0x88, 0xfc, 0x98, 0xdb, 0xaf, - 0x13, 0xf3, 0xb2, 0x20, 0x3f, 0x19, 0xe1, 0x83, 0x70, 0xd2, 0x26, 0xd0, - 0xd2, 0xad, 0x11, 0xeb, 0x3b, 0x31, 0x03, 0x55, 0x62, 0xca, 0xb5, 0x87, - 0x31, 0x7a, 0x11, 0x4c, 0xf2, 0xc3, 0xc2, 0x1c, 0x42, 0x94, 0x7b, 0xe6, - 0x29, 0x86, 0x70, 0x8e, 0x51, 0x4a, 0xa3, 0xf2, 0xf0, 0xed, 0xa1, 0xc6, - 0x18, 0xff, 0xf2, 0xff, 0xe0, 0x07, 0x85, 0xf1, 0x93, 0x5a, 0x83, 0x1c, - 0x4c, 0xa9, 0x9b, 0xc5, 0x0c, 0xc4, 0xf0, 0xde, 0x71, 0x93, 0x78, 0xd1, - 0x3b, 0xcc, 0x5b, 0x51, 0x1f, 0xd7, 0x21, 0x12, 0x57, 0xd5, 0x2a, 0xea, - 0x64, 0x08, 0x0e, 0xf0, 0x3d, 0x42, 0xe7, 0xdf, 0xc8, 0xea, 0x42, 0x2b, - 0x41, 0x55, 0x85, 0xb8, 0x54, 0xa4, 0xc9, 0x3f, 0xce, 0xfc, 0x1a, 0xde, - 0x73, 0x08, 0xaa, 0x09, 0x25, 0x08, 0xa0, 0xdc, 0x64, 0xb7, 0xe7, 0xcc, - 0xde, 0x85, 0xa6, 0xc3, 0xe9, 0xe1, 0x43, 0x71, 0x86, 0x05, 0x55, 0x86, - 0x47, 0xf8, 0x71, 0xbd, 0xf5, 0xd7, 0x38, 0x64, 0x7f, 0x71, 0x63, 0xe1, - 0x22, 0x39, 0x99, 0xc3, 0xdf, 0x27, 0x5d, 0xdd, 0xd0, 0x57, 0x99, 0xd5, - 0x97, 0xcd, 0xd4, 0x2e, 0xc1, 0x25, 0x3d, 0x2e, 0x03, 0x0b, 0x04, 0x20, - 0x70, 0xec, 0x46, 0x6c, 0x4b, 0x55, 0x16, 0x02, 0x00, 0x71, 0xfd, 0x8a, - 0xa0, 0x1e, 0x5f, 0x41, 0xe6, 0x96, 0x58, 0xbe, 0x02, 0x73, 0x91, 0x71, - 0xb2, 0x7e, 0xc4, 0xcd, 0xce, 0xa5, 0x26, 0xee, 0xff, 0x8c, 0x9a, 0x4c, - 0xf4, 0x0a, 0x89, 0xba, 0x14, 0x6e, 0x06, 0x86, 0xb0, 0xba, 0x41, 0xdd, - 0x27, 0xf8, 0xc3, 0x46, 0x4f, 0x39, 0xac, 0x2c, 0x8a, 0x69, 0x09, 0xb7, - 0x36, 0x0f, 0xe0, 0x8d, 0x31, 0x0f, 0xc3, 0xee, 0x3a, 0x6a, 0x9e, 0x96, - 0x91, 0xf5, 0x6a, 0x12, 0x98, 0x5a, 0xc3, 0xf3, 0xb8, 0x9b, 0x07, 0xdb, - 0x8e, 0x2a, 0xb0, 0x91, 0x86, 0xb5, 0xc7, 0xe9, 0x06, 0xe1, 0x4e, 0x83, - 0x28, 0x3a, 0x0e, 0x67, 0xe5, 0x7e, 0x88, 0x2a, 0x31, 0xd2, 0xfe, 0xf6, - 0x19, 0x3d, 0x09, 0xd1, 0xef, 0x5d, 0xe1, 0x15, 0x2d, 0xb4, 0xec, 0x23, - 0xc2, 0x0c, 0x7a, 0xbf, 0xd3, 0x6f, 0xf7, 0x8a, 0x3b, 0x3a, 0x0f, 0x20, - 0xc4, 0x78, 0xbe, 0x46, 0x30, 0x0f, 0xc2, 0xd0, 0x8c, 0x23, 0xb7, 0xfa, - 0x3c, 0x19, 0x35, 0x53, 0x5f, 0xf9, 0x94, 0xf5, 0x23, 0xbe, 0xb3, 0x56, - 0x42, 0xa1, 0x27, 0xff, 0xac, 0xbf, 0x72, 0x7e, 0x89, 0xbe, 0xb9, 0x6d, - 0x2d, 0xc4, 0x3f, 0x6c, 0x7f, 0xc4, 0x7e, 0x01, 0x09, 0xc8, 0x35, 0x80, - 0x99, 0x8f, 0x1c, 0x43, 0xd3, 0xb2, 0x4a, 0xb7, 0x08, 0x06, 0x63, 0xcd, - 0x8a, 0x5e, 0x64, 0xa2, 0x93, 0xa5, 0x15, 0xa0, 0x38, 0xa0, 0xf2, 0x1c, - 0xab, 0xe1, 0x2d, 0x19, 0x30, 0xee, 0x9b, 0x87, 0x42, 0x54, 0xfb, 0xcc, - 0xfe, 0x2a, 0xcd, 0x54, 0xf5, 0xeb, 0x52, 0x6b, 0xd4, 0x1d, 0xa3, 0x7c, - 0xec, 0xf2, 0x56, 0x51, 0x54, 0xab, 0x66, 0xb0, 0x73, 0x49, 0x3e, 0xc4, - 0x89, 0xac, 0xb0, 0xc1, 0x41, 0x6f, 0x19, 0xd6, 0x41, 0xbd, 0xc2, 0xe2, - 0x1a, 0x56, 0xb3, 0x01, 0xc9, 0xdf, 0x46, 0xe7, 0xa1, 0x42, 0xfa, 0x1c, - 0x18, 0x86, 0xe2, 0x07, 0xe4, 0xfe, 0x19, 0x03, 0x7d, 0xc4, 0x51, 0x78, - 0x29, 0x68, 0x73, 0x70, 0x82, 0x98, 0x34, 0x2e, 0x41, 0x59, 0xd5, 0x20, - 0x36, 0xe3, 0xe5, 0x2c, 0xbe, 0x76, 0x23, 0x5d, 0xb1, 0xf0, 0xda, 0xee, - 0x65, 0x54, 0xd9, 0xa1, 0x77, 0x6e, 0xd8, 0x56, 0xcb, 0x6a, 0x35, 0xb5, - 0xaa, 0x97, 0x22, 0x28, 0x4d, 0x74, 0x13, 0x96, 0x59, 0x3d, 0x3a, 0xe2, - 0x26, 0xde, 0xd3, 0xc7, 0xed, 0x97, 0x98, 0xa8, 0x4a, 0x6b, 0x4b, 0xd1, - 0x52, 0xca, 0x84, 0xd6, 0x19, 0x7a, 0x6c, 0x0d, 0xb4, 0x28, 0x4f, 0xb1, - 0xa2, 0xcc, 0x07, 0x08, 0x57, 0xc9, 0x32, 0xd4, 0xe0, 0xef, 0x96, 0x9a, - 0x31, 0x1e, 0x68, 0x1d, 0x7b, 0x57, 0x26, 0x62, 0xa4, 0x26, 0xaf, 0xc7, - 0xd0, 0xab, 0xb6, 0x9e, 0x00, 0x6d, 0xfe, 0x29, 0x30, 0x53, 0xcd, 0xb8, - 0x4e, 0x30, 0x4e, 0xa5, 0xcc, 0xf6, 0xab, 0xca, 0x4d, 0x74, 0x40, 0xc2, - 0xb4, 0xfb, 0x3f, 0x75, 0x0a, 0x9d, 0x88, 0xa3, 0xb0, 0x5b, 0x4e, 0x88, - 0x50, 0x90, 0xcb, 0x5c, 0xcd, 0xc7, 0xff, 0x75, 0x97, 0xc4, 0x1b, 0xe9, - 0x03, 0x8a, 0xa7, 0x62, 0x32, 0x98, 0x60, 0x39, 0x56, 0xe5, 0x25, 0xed, - 0xba, 0x58, 0x67, 0xa3, 0xe8, 0x23, 0xd1, 0x55, 0xb3, 0xa5, 0xc0, 0xc9, - 0x75, 0x14, 0x91, 0xe6, 0x7d, 0x0e, 0xe3, 0xac, 0xc8, 0x6b, 0xa7, 0xdb, - 0x36, 0xe8, 0x44, 0x92, 0x72, 0xf2, 0x6d, 0x10, 0xeb, 0xd0, 0x7a, 0xdd, - 0x00, 0x9b, 0xf8, 0x65, 0xaa, 0xef, 0xed, 0xfb, 0x84, 0x5f, 0xfb, 0xd8, - 0xe9, 0xa8, 0x71, 0xab, 0x20, 0x98, 0x4f, 0x21, 0x7d, 0x33, 0xe2, 0xb1, - 0x3f, 0x95, 0x9c, 0x28, 0xf5, 0xd5, 0x83, 0x01, 0xe9, 0x71, 0x68, 0xa9, - 0x3d, 0x9e, 0x49, 0xfb, 0x6c, 0x83, 0x5f, 0x48, 0x9d, 0x91, 0x00, 0xab, - 0x54, 0x17, 0x11, 0x5b, 0x9d, 0x0a, 0x17, 0x8e, 0x3a, 0xbc, 0xd5, 0x33, - 0xcd, 0x2a, 0x5b, 0x14, 0x39, 0xe4, 0x30, 0x45, 0xde, 0x6e, 0xde, 0x92, - 0x7f, 0xb5, 0x91, 0x5d, 0x5b, 0xe4, 0x18, 0x17, 0x7c, 0x22, 0x1e, 0x2d, - 0x97, 0x8b, 0x6f, 0xe0, 0x54, 0x2e, 0x25, 0xbc, 0x5f, 0xef, 0x27, 0x1b, - 0x95, 0x71, 0xcc, 0x29, 0x96, 0x30, 0x82, 0xb1, 0x99, 0x98, 0x28, 0x36, - 0x5f, 0xd6, 0xf9, 0x13, 0xb3, 0x3d, 0x14, 0x91, 0x8a, 0x2f, 0xbf, 0x6e, - 0x8c, 0x57, 0xf6, 0x8e, 0x32, 0xf2, 0xd3, 0xa5, 0x1b, 0x2b, 0xba, 0xc8, - 0x0d, 0xa4, 0xd3, 0xc2, 0x16, 0x1f, 0x5f, 0xb6, 0x89, 0x77, 0xa9, 0xf3, - 0x7b, 0xb8, 0x11, 0x23, 0x41, 0xd6, 0xe0, 0x47, 0x3c, 0x94, 0xe0, 0xed, - 0xa9, 0xb1, 0x0e, 0x90, 0x38, 0xdd, 0x60, 0xcd, 0x75, 0x00, 0x36, 0x3a, - 0x42, 0xbb, 0xfd, 0xd7, 0xc6, 0x16, 0x38, 0xb4, 0xc0, 0x1d, 0xb6, 0x46, - 0x5c, 0x2f, 0x70, 0x95, 0x8d, 0x74, 0x68, 0xb2, 0xb5, 0xae, 0x73, 0x22, - 0xa1, 0xca, 0x5d, 0xd4, 0x28, 0x1a, 0xd2, 0x19, 0x1c, 0x43, 0x5e, 0x12, - 0x16, 0x15, 0xb4, 0x97, 0x64, 0x10, 0x07, 0x48, 0xf8, 0xe3, 0xfb, 0x3e, - 0xa5, 0x05, 0xcd, 0xc1, 0x29, 0xf0, 0x67, 0xb7, 0x24, 0x02, 0xac, 0x76, - 0x91, 0x64, 0x63, 0x46, 0xfb, 0xfd, 0xaa, 0x5b, 0x3f, 0xeb, 0xe0, 0xb2, - 0x5a, 0x8d, 0xde, 0xdc, 0x92, 0x0c, 0x1e, 0xfc, 0x82, 0x55, 0xc7, 0x8a, - 0xe3, 0x28, 0x57, 0xfe, 0x10, 0xe1, 0xa3, 0x5a, 0x9e, 0x67, 0x86, 0xf4, - 0xa5, 0xf5, 0xa0, 0xbd, 0xa4, 0x3c, 0xda, 0xf3, 0x83, 0x27, 0x2f, 0x55, - 0x73, 0xb6, 0x74, 0x3e, 0xd3, 0xc9, 0x84, 0x1d, 0xff, 0x61, 0x01, 0x56, - 0x30, 0x2a, 0x23, 0x57, 0xbc, 0x88, 0xa7, 0x2f, 0x6f, 0x95, 0x91, 0x4e, - 0x5b, 0x41, 0xd9, 0x95, 0x1f, 0x09, 0x95, 0x79, 0x36, 0xe3, 0x7f, 0xbd, - 0x4b, 0x09, 0x4e, 0x7f, 0x6a, 0x58, 0x6e, 0xd0, 0x60, 0xaf, 0xf1, 0x8f, - 0x4c, 0xc5, 0x5a, 0x5c, 0xb7, 0x74, 0x83, 0x3c, 0xb3, 0x7e, 0xdc, 0x76, - 0x89, 0xa5, 0xca, 0xd7, 0x75, 0x35, 0xb2, 0x4c, 0x0a, 0x67, 0x2b, 0x7a, - 0xe8, 0xac, 0x9e, 0x26, 0xa3, 0xae, 0x87, 0x66, 0x12, 0x4e, 0x74, 0xc8, - 0xd8, 0x6d, 0x89, 0x9c, 0x34, 0x63, 0x61, 0x33, 0x1b, 0x6a, 0x78, 0x7f, - 0x2f, 0xa7, 0x9b, 0xe7, 0x42, 0x0d, 0xcb, 0xc9, 0xf0, 0xa6, 0xb5, 0x38, - 0x66, 0x80, 0xca, 0x7a, 0xa9, 0xe4, 0x93, 0xe3, 0xfc, 0x7d, 0x38, 0x7d, - 0x7a, 0x2c, 0x03, 0xb4, 0x35, 0xde, 0x1b, 0x2e, 0x29, 0x24, 0x40, 0x93, - 0x6c, 0x52, 0x21, 0xd6, 0x70, 0x88, 0xfd, 0xc7, 0x5c, 0x94, 0x95, 0xc0, - 0x03, 0xce, 0x1b, 0xb3, 0x0e, 0x87, 0xac, 0xa0, 0x88, 0xcd, 0x20, 0x3d, - 0x88, 0x6f, 0xac, 0x29, 0x2e, 0xcc, 0x7d, 0xa7, 0x09, 0x16, 0xc0, 0xcc, - 0x55, 0x43, 0x19, 0xdc, 0x5e, 0xc4, 0xe5, 0x7c, 0xfb, 0x50, 0x01, 0x41, - 0xe1, 0x70, 0x84, 0x3e, 0x60, 0x88, 0x05, 0x27, 0x4b, 0x6c, 0x59, 0x9a, - 0x01, 0x50, 0xec, 0x74, 0x6a, 0x98, 0x57, 0xfe, 0xf5, 0x63, 0xc3, 0x60, - 0x55, 0x23, 0x33, 0xf9, 0x2d, 0xf0, 0x68, 0xff, 0xad, 0x61, 0xdb, 0x5e, - 0xdb, 0x0c, 0x54, 0x68, 0x8c, 0x4b, 0x64, 0x94, 0x3c, 0xa8, 0xb1, 0x31, - 0x61, 0xf3, 0xb3, 0xed, 0x8f, 0xd5, 0x07, 0x27, 0xbf, 0xa3, 0xa2, 0x42, - 0x4a, 0xa1, 0x5e, 0xc9, 0xb3, 0x9a, 0x0f, 0xbb, 0xf7, 0xc7, 0x4d, 0x0b, - 0xee, 0xbd, 0xce, 0x9e, 0x8c, 0x14, 0x7e, 0x06, 0x6e, 0x6d, 0x9b, 0xdd, - 0x22, 0xc6, 0xc2, 0x62, 0xa5, 0x45, 0xc1, 0xe1, 0x97, 0xe2, 0x50, 0x25, - 0xcc, 0x9b, 0xc4, 0x5d, 0x2d, 0x45, 0x10, 0xad, 0xa8, 0x4f, 0x27, 0xc3, - 0x1a, 0x2c, 0xef, 0x38, 0x2d, 0xa7, 0xaf, 0xe5, 0x23, 0x7a, 0x8f, 0xbf, - 0x9c, 0xd0, 0xb6, 0x31, 0x5c, 0xaa, 0xd2, 0x8c, 0xd8, 0x91, 0x00, 0xa1, - 0x8b, 0x4d, 0x3e, 0x27, 0x22, 0x6c, 0x0f, 0x64, 0x95, 0x89, 0xa6, 0x29, - 0x90, 0xf9, 0xa9, 0x24, 0x24, 0xb8, 0x71, 0x56, 0x7a, 0xc5, 0xa9, 0x26, - 0x9f, 0xf6, 0x2a, 0xa6, 0xf1, 0xca, 0x2a, 0x17, 0x14, 0x8c, 0x8d, 0xf2, - 0x44, 0x7d, 0x49, 0x4e, 0x9b, 0x4f, 0xef, 0x72, 0x7e, 0xe8, 0x0f, 0x45, - 0xb3, 0x3d, 0x61, 0xf5, 0x9d, 0x3f, 0x9a, 0xe3, 0x93, 0xdd, 0x3d, 0x02, - 0x84, 0x7d, 0xd4, 0x84, 0xa8, 0x23, 0xe9, 0x43, 0xb6, 0x66, 0xf2, 0xb7, - 0x35, 0xcf, 0xa3, 0x2f, 0xbe, 0x48, 0x0e, 0xaa, 0xfe, 0xe9, 0x7e, 0xb0, - 0x4d, 0xb3, 0x6b, 0x69, 0xdc, 0xef, 0x20, 0xec, 0xce, 0x6c, 0xad, 0x7a, - 0x20, 0x35, 0xf2, 0xfd, 0x09, 0xe1, 0xdb, 0xca, 0x2a, 0x55, 0xf7, 0x60, - 0xca, 0xf3, 0x85, 0x12, 0xe6, 0x05, 0x4f, 0xc8, 0x6e, 0x76, 0xda, 0x5f, - 0x45, 0x1e, 0xed, 0xdf, 0x57, 0x4c, 0xeb, 0x7e, 0x28, 0xf7, 0x39, 0xc4, - 0xd0, 0x10, 0x32, 0xa9, 0xcc, 0x25, 0xd9, 0x0b, 0x8c, 0x8a, 0xf6, 0x6c, - 0x84, 0xde, 0x09, 0x8c, 0xf6, 0xa4, 0x95, 0xb3, 0x65, 0x5e, 0x49, 0x36, - 0x8c, 0x51, 0x85, 0x62, 0xcc, 0xe6, 0x2a, 0x3d, 0xdc, 0x68, 0x08, 0x41, - 0x73, 0x18, 0x74, 0x10, 0xe5, 0x18, 0xfa, 0xbe, 0x2f, 0xaa, 0x98, 0x3c, - 0x7c, 0x44, 0x43, 0x3f, 0xd6, 0x27, 0xd3, 0x28, 0xf0, 0x2b, 0xeb, 0xf2, - 0x46, 0xfc, 0xf6, 0x3f, 0xc7, 0xa8, 0xc0, 0xf0, 0x17, 0xef, 0x35, 0xde, - 0x55, 0x30, 0xef, 0xf7, 0x7b, 0x57, 0xf3, 0x9f, 0x00, 0xb5, 0x49, 0x1e, - 0xc4, 0x6a, 0xea, 0x0e, 0x40, 0x95, 0x47, 0x55, 0x32, 0x4f, 0x4f, 0x24, - 0x5a, 0x10, 0xaa, 0x1f, 0x5b, 0x9b, 0xc1, 0xb3, 0xaa, 0xa3, 0x40, 0x32, - 0x56, 0x80, 0xbf, 0x38, 0xbc, 0x89, 0xad, 0xa8, 0x0e, 0x8f, 0x8e, 0x14, - 0x17, 0x5a, 0x9b, 0x25, 0x85, 0x85, 0xa7, 0x43, 0xc8, 0x19, 0x21, 0xf9, - 0xa3, 0xdc, 0xb9, 0xc8, 0x70, 0x7b, 0xc8, 0x42, 0x38, 0x50, 0xb9, 0xcf, - 0x90, 0x6e, 0x88, 0x7f, 0x5a, 0x56, 0xc8, 0xd7, 0x84, 0x7b, 0x69, 0xe1, - 0x31, 0x6d, 0xe9, 0xc7, 0x7f, 0x39, 0x78, 0x52, 0xa2, 0x0c, 0xc7, 0x3b, - 0x89, 0x05, 0x9d, 0x66, 0xc6, 0xea, 0x48, 0x75, 0xa5, 0xd6, 0x89, 0x8e, - 0x47, 0xdf, 0x81, 0x28, 0x94, 0xc7, 0x98, 0xd4, 0x1c, 0x6f, 0x95, 0xdd, - 0x20, 0x74, 0xe9, 0xde, 0xb5, 0x3b, 0x87, 0xa1, 0x1a, 0x1e, 0xee, 0xc7, - 0xbc, 0xa4, 0x12, 0x30, 0x92, 0x60, 0x9f, 0x0d, 0x4d, 0x23, 0x1f, 0xa0, - 0xea, 0x07, 0x84, 0x10, 0xb3, 0xd3, 0x2a, 0x2f, 0x27, 0xdb, 0x27, 0x76, - 0xb8, 0x43, 0xe2, 0x9a, 0xfc, 0x9b, 0x81, 0x43, 0xd2, 0xbc, 0xc2, 0xbb, - 0x40, 0xbd, 0xe8, 0x10, 0xd5, 0xca, 0xd2, 0x10, 0x5e, 0x18, 0xfe, 0x45, - 0x1d, 0xc2, 0xf9, 0x99, 0x50, 0xbe, 0x7e, 0xca, 0x1a, 0x45, 0x17, 0x99, - 0x03, 0x9d, 0x2b, 0x68, 0xb7, 0x76, 0x3e, 0x68, 0x41, 0x81, 0x6d, 0xe3, - 0x77, 0xbe, 0x4e, 0xc9, 0x41, 0xb7, 0x8a, 0xb7, 0xa7, 0x59, 0xfa, 0x04, - 0x7b, 0xde, 0xd0, 0x3f, 0x7a, 0x57, 0xa3, 0xf1, 0x9e, 0x0a, 0x66, 0x98, - 0xb0, 0xc1, 0xc2, 0xb4, 0x7a, 0x3b, 0x2f, 0x54, 0x3b, 0x66, 0xe6, 0x6b, - 0xc5, 0x2c, 0xa1, 0xb1, 0xd2, 0xee, 0xd8, 0x30, 0xf3, 0xa9, 0x2f, 0xe8, - 0xf0, 0x3e, 0xd8, 0x2b, 0x9a, 0x75, 0x58, 0x59, 0xc7, 0x3a, 0x39, 0xa1, - 0x58, 0x19, 0x87, 0x3f, 0x90, 0xe5, 0xb3, 0xb6, 0xfe, 0x39, 0x34, 0xc8, - 0x4c, 0x21, 0x7b, 0x96, 0x9e, 0x3e, 0x38, 0x48, 0x3e, 0xaa, 0x0b, 0x1b, - 0xbf, 0xa9, 0x45, 0x83, 0x8e, 0x38, 0xf3, 0x96, 0xb8, 0x24, 0x23, 0xc1, - 0xd3, 0x5c, 0x77, 0xeb, 0x6f, 0xf8, 0x16, 0xa8, 0x94, 0xbc, 0xab, 0x2a, - 0x20, 0x52, 0xec, 0x9a, 0x5c, 0xd9, 0x99, 0xb4, 0x84, 0x50, 0x90, 0xbb, - 0xf7, 0x80, 0x51, 0x61, 0x95, 0x61, 0xaa, 0x03, 0xd6, 0xd4, 0xa9, 0x73, - 0x86, 0x3b, 0xf1, 0x7e, 0xca, 0x7c, 0xfb, 0xf9, 0x33, 0xe6, 0x96, 0x66, - 0x13, 0x7a, 0x35, 0xae, 0x71, 0xcc, 0x13, 0x4b, 0x5e, 0x73, 0xbd, 0xf8, - 0xf2, 0x5e, 0x51, 0x5c, 0x50, 0x09, 0x3c, 0x59, 0xfa, 0xd0, 0xd4, 0x8e, - 0xe0, 0x21, 0xb4, 0x97, 0xa4, 0x7d, 0xeb, 0x17, 0xef, 0x4c, 0xf4, 0xd0, - 0x0b, 0xf5, 0x42, 0xaf, 0x07, 0x8e, 0xe9, 0x5f, 0x2b, 0xce, 0xb4, 0xf9, - 0x17, 0xea, 0x9e, 0x83, 0x94, 0xf5, 0x1d, 0x49, 0x91, 0x42, 0x65, 0x84, - 0x77, 0x56, 0xc0, 0x4f, 0x67, 0x37, 0xed, 0xa3, 0x18, 0x22, 0x69, 0xd7, - 0x40, 0xfb, 0x39, 0xfd, 0xc2, 0x37, 0x68, 0x98, 0x30, 0x6a, 0x33, 0xad, - 0x2f, 0xf2, 0x3d, 0x5c, 0xe0, 0x4a, 0x29, 0x38, 0xe5, 0xe0, 0x5c, 0xb3, - 0x79, 0xd5, 0x8c, 0xcd, 0x25, 0xad, 0xab, 0xd3, 0x75, 0x2f, 0x54, 0x3a, - 0xfe, 0x8e, 0x0d, 0x3f, 0xfa, 0x6e, 0xcc, 0x80, 0x26, 0x08, 0x7f, 0xa3, - 0x9e, 0xba, 0x80, 0x4c, 0x36, 0x4c, 0x4d, 0x74, 0xc0, 0x3f, 0xd1, 0xb3, - 0xad, 0xa3, 0xc8, 0xcf, 0x7a, 0x73, 0xb7, 0x09, 0x67, 0x3b, 0xf8, 0x6f, - 0x7a, 0x26, 0x57, 0x65, 0x83, 0xcf, 0x18, 0x3c, 0x86, 0x2c, 0xb4, 0xcd, - 0xe8, 0x74, 0xfa, 0x63, 0xd4, 0xb4, 0x36, 0x36, 0xd9, 0xb0, 0xeb, 0x29, - 0xe3, 0x3a, 0x7f, 0x06, 0x80, 0x29, 0x4c, 0x86, 0x94, 0x49, 0x42, 0x22, - 0x57, 0x0c, 0x4f, 0xfa, 0x08, 0xb5, 0x12, 0xbe, 0x76, 0xf5, 0x52, 0x10, - 0x47, 0x48, 0x1f, 0xbd, 0x87, 0x51, 0xd1, 0x39, 0xc8, 0x50, 0x7c, 0xfa, - 0x92, 0xe7, 0xea, 0x40, 0x55, 0xf7, 0x61, 0x9f, 0x19, 0xc2, 0x65, 0x23, - 0x6d, 0xe0, 0x41, 0xb9, 0x5b, 0xb7, 0x8c, 0x9a, 0xee, 0x50, 0x53, 0xa6, - 0xe8, 0x80, 0x14, 0x8c, 0xeb, 0x2a, 0xc1, 0x44, 0xda, 0x6d, 0x90, 0x96, - 0xb8, 0xf1, 0xc4, 0x0d, 0xf1, 0xd8, 0x8e, 0xd0, 0xb4, 0x73, 0x49, 0xe5, - 0x34, 0xab, 0x00, 0x0f, 0x0b, 0x7b, 0xc3, 0x7d, 0x53, 0x1d, 0x75, 0xef, - 0x27, 0xfb, 0xdf, 0x29, 0xfd, 0x61, 0xb3, 0x71, 0x25, 0xac, 0x62, 0x2d, - 0xaa, 0x1a, 0x2a, 0x55, 0x6e, 0x11, 0x50, 0x4b, 0x2c, 0x3d, 0xd8, 0x8d, - 0xb9, 0xcb, 0xc2, 0x21, 0x77, 0x4e, 0x40, 0x56, 0x45, 0xc1, 0x07, 0x79, - 0xdb, 0x66, 0x2f, 0x6d, 0x4d, 0xac, 0x2b, 0x2d, 0x29, 0xff, 0xa1, 0x79, - 0x10, 0x03, 0x72, 0x09, 0xe8, 0xe9, 0x31, 0xd5, 0x6f, 0x42, 0x97, 0x3e, - 0x09, 0xf0, 0x4a, 0xb5, 0xe6, 0x73, 0x94, 0xc1, 0xb4, 0x94, 0xa1, 0xd9, - 0x44, 0xe8, 0x50, 0xe2, 0x6c, 0x82, 0xea, 0x89, 0x06, 0xd6, 0x44, 0xe9, - 0x53, 0xd0, 0x5c, 0xcf, 0x0a, 0x3b, 0x89, 0x50, 0x8d, 0x1e, 0x44, 0xbd, - 0xb2, 0xb6, 0x68, 0xf4, 0xbb, 0x2d, 0x65, 0x95, 0x5c, 0xb5, 0xdc, 0xe2, - 0xb7, 0x70, 0x86, 0xfd, 0x5b, 0xcc, 0x99, 0x41, 0x5d, 0x22, 0x11, 0xa8, - 0x22, 0x8c, 0xc1, 0x73, 0x70, 0x5b, 0x31, 0x11, 0xc3, 0xdb, 0x7f, 0xca, - 0x2b, 0xcb, 0xeb, 0x7d, 0x2b, 0xd1, 0x32, 0xe6, 0xf8, 0x22, 0x22, 0x69, - 0xea, 0xb7, 0xcd, 0x25, 0x22, 0x33, 0x2f, 0x83, 0x3f, 0xb7, 0x2d, 0x22, - 0x61, 0x24, 0x01, 0xb3, 0xe9, 0xd0, 0xf6, 0x21, 0xe6, 0x2d, 0xea, 0x0e, - 0x53, 0x7a, 0x97, 0xcd, 0xcf, 0x6c, 0xe2, 0xd5, 0x8b, 0xdc, 0xe9, 0xe0, - 0xfd, 0xd0, 0xa0, 0xbf, 0xa5, 0x39, 0x7e, 0xd4, 0xdd, 0xfe, 0x1a, 0xce, - 0xb0, 0x85, 0x8e, 0xc1, 0x05, 0x36, 0xf9, 0xd3, 0x6a, 0x35, 0xab, 0x53, - 0x1d, 0xc2, 0xa0, 0xfa, 0xc2, 0x6b, 0x8b, 0x8c, 0x2d, 0x5d, 0x5f, 0xb8, - 0x18, 0x43, 0x53, 0xb9, 0x5d, 0x08, 0x07, 0xd1, 0x8f, 0xc6, 0xe9, 0xef, - 0xaf, 0x3b, 0xbb, 0x60, 0xaa, 0x28, 0xac, 0x4c, 0x03, 0x5d, 0xc8, 0x05, - 0xba, 0x82, 0x5c, 0xcb, 0xc6, 0x2a, 0x13, 0xf6, 0xfc, 0x54, 0xf3, 0xea, - 0x20, 0xce, 0xcf, 0x05, 0x00, 0xb9, 0x98, 0x0b, 0x9f, 0x96, 0xe0, 0x7b, - 0x85, 0x8e, 0x43, 0xbd, 0xf2, 0x3e, 0x17, 0x19, 0x8d, 0x23, 0x72, 0x85, - 0x93, 0xdf, 0x3a, 0x21, 0x94, 0x34, 0x32, 0x53, 0x02, 0xba, 0x34, 0xba, - 0xa5, 0x2e, 0x5c, 0x0b, 0x1e, 0x3f, 0xa9, 0x83, 0x92, 0x63, 0x0b, 0x12, - 0xc9, 0xf8, 0x35, 0xef, 0x78, 0xa0, 0xee, 0xc0, 0xbb, 0x14, 0xd4, 0x68, - 0x39, 0xa0, 0x00, 0x38, 0x77, 0x1e, 0xfc, 0x94, 0xb4, 0xd4, 0xc1, 0x98, - 0xe1, 0x43, 0x8e, 0xc6, 0xa7, 0x58, 0x33, 0x1b, 0xa3, 0x73, 0xf7, 0x4c, - 0x49, 0x9d, 0xc0, 0xb8, 0xbf, 0x30, 0x84, 0x2e, 0x5a, 0x8b, 0x6c, 0xa5, - 0xde, 0xb5, 0x6a, 0x79, 0x67, 0x54, 0xe7, 0x8c, 0x3c, 0xf3, 0x70, 0x1b, - 0x3d, 0x35, 0x23, 0x65, 0x17, 0xc9, 0x74, 0x11, 0x0b, 0xb1, 0x64, 0xc0, - 0x65, 0xa3, 0x9e, 0x5a, 0x7b, 0xa2, 0xda, 0xe1, 0xf4, 0xeb, 0xb8, 0x13, - 0x90, 0x30, 0xc1, 0x72, 0x6a, 0x2a, 0x13, 0xe3, 0x36, 0xe1, 0x05, 0x47, - 0x56, 0x42, 0xf2, 0x59, 0x44, 0x12, 0x23, 0x27, 0xe4, 0xfe, 0xae, 0x83, - 0x39, 0x0f, 0x4c, 0x85, 0x3f, 0xaf, 0x97, 0x2e, 0xae, 0x3c, 0x12, 0x0e, - 0xfd, 0x5b, 0xfd, 0x8e, 0x58, 0x58, 0x4a, 0xbd, 0x05, 0x98, 0x6b, 0x82, - 0x03, 0x02, 0x0a, 0x2d, 0x1c, 0x19, 0x0f, 0x95, 0x12, 0x5d, 0x8c, 0x1e, - 0x7b, 0x49, 0xbb, 0x83, 0xe2, 0xd2, 0x53, 0x60, 0xe1, 0xab, 0xd2, 0x8b, - 0x02, 0xeb, 0x49, 0x27, 0xd7, 0xda, 0x22, 0xd3, 0x26, 0x6f, 0x3e, 0x5b, - 0x3f, 0x33, 0xcb, 0xa8, 0x08, 0x98, 0xa6, 0xc5, 0x35, 0xc1, 0x81, 0xc1, - 0xd6, 0x28, 0xe5, 0xba, 0x50, 0xe9, 0x14, 0x1a, 0x0b, 0x0a, 0x8a, 0x9e, - 0xa3, 0xaa, 0xbc, 0x3b, 0x38, 0x5b, 0xe0, 0x1f, 0xf6, 0xb8, 0x95, 0x79, - 0xa4, 0x45, 0x5f, 0xc4, 0x63, 0x86, 0xd0, 0x15, 0xe0, 0x25, 0x6e, 0x5f, - 0x8d, 0x75, 0x25, 0x67, 0xea, 0xf3, 0x92, 0x33, 0xd1, 0x07, 0xf3, 0x43, - 0x21, 0x42, 0x40, 0x70, 0x9b, 0x8e, 0x0b, 0x41, 0x54, 0x30, 0x73, 0xd0, - 0x49, 0xe4, 0x70, 0xf6, 0xd3, 0x7d, 0x59, 0xd6, 0x1f, 0x06, 0xfc, 0x12, - 0x89, 0x9f, 0x26, 0x09, 0x34, 0xf6, 0x64, 0x56, 0x37, 0x68, 0x59, 0x33, - 0x9c, 0xa0, 0xfa, 0x65, 0x70, 0xb3, 0xe1, 0x29, 0xd1, 0x5b, 0xaf, 0xe7, - 0xa5, 0x39, 0x64, 0x38, 0x8b, 0xb1, 0xd6, 0xce, 0xa4, 0xb4, 0xb6, 0xdb, - 0x01, 0xb4, 0xf9, 0xb7, 0x1f, 0x8f, 0xcd, 0x28, 0xe6, 0x27, 0x47, 0xf2, - 0x53, 0x1d, 0xea, 0xb4, 0x53, 0xfa, 0xe0, 0x22, 0xea, 0xc5, 0xd2, 0xfc, - 0x4e, 0x45, 0xcf, 0xef, 0xaa, 0xea, 0xaf, 0x7e, 0x77, 0xe2, 0x39, 0x1c, - 0x5d, 0x9c, 0x77, 0x7b, 0x71, 0xb5, 0x11, 0xef, 0xc7, 0xf8, 0xba, 0x2b, - 0x7b, 0x15, 0xfa, 0x2d, 0xd5, 0xd8, 0xe0, 0xee, 0xbe, 0x10, 0xd6, 0xdb, - 0x47, 0xf1, 0x11, 0xcc, 0x35, 0x4c, 0x2d, 0xa8, 0x12, 0x12, 0x23, 0x78, - 0x0b, 0xd3, 0xb8, 0x90, 0x8a, 0x1d, 0xc4, 0x90, 0x4b, 0x7e, 0x35, 0xb9, - 0x9f, 0x5b, 0x68, 0x97, 0x9c, 0x09, 0xc3, 0x0d, 0x0a, 0x20, 0xd9, 0x25, - 0x07, 0xeb, 0x56, 0xb5, 0xd6, 0x93, 0x31, 0x3d, 0x71, 0x7c, 0x0f, 0x48, - 0x26, 0x32, 0x0f, 0x1b, 0x43, 0x75, 0xc2, 0xcd, 0xf6, 0xaa, 0x88, 0x38, - 0x7b, 0xe9, 0xc0, 0x98, 0x51, 0xa4, 0x06, 0x15, 0x7f, 0x11, 0x0b, 0x91, - 0xcb, 0x59, 0x92, 0x1c, 0xa1, 0x44, 0x63, 0xa4, 0x3a, 0xad, 0xd7, 0x1d, - 0x9e, 0x63, 0xfb, 0xb9, 0x7d, 0x43, 0x80, 0x79, 0xe8, 0x01, 0xba, 0x08, - 0x47, 0x78, 0x57, 0xd6, 0x0b, 0x38, 0x94, 0x64, 0xac, 0x64, 0x77, 0xdc, - 0xb8, 0xa9, 0xa5, 0xa2, 0x62, 0x70, 0x36, 0x4f, 0x39, 0xd9, 0xae, 0x2f, - 0x15, 0xd3, 0x07, 0xc4, 0x01, 0x03, 0x96, 0x5e, 0x51, 0xa7, 0x15, 0x2a, - 0x9d, 0x22, 0x74, 0xae, 0x8a, 0xd4, 0xb9, 0x91, 0xed, 0xad, 0xa7, 0x76, - 0xad, 0x38, 0x33, 0xef, 0x3c, 0xe4, 0xd0, 0x7c, 0x6e, 0x53, 0xae, 0x0c, - 0x7a, 0xdf, 0x2c, 0x18, 0xeb, 0xc4, 0x8c, 0xfe, 0xab, 0x10, 0xcd, 0xaf, - 0x8f, 0x88, 0x3f, 0xac, 0xe3, 0x20, 0xed, 0x0c, 0x62, 0x81, 0x2e, 0x12, - 0xa9, 0xa5, 0xe7, 0xd5, 0x3a, 0xef, 0x40, 0xb4, 0x91, 0x52, 0x4c, 0xfd, - 0xd5, 0xb8, 0x98, 0x19, 0xcd, 0x1b, 0xa9, 0x17, 0xe7, 0x9a, 0xda, 0x8a, - 0xb4, 0x8f, 0x1a, 0x5c, 0x78, 0xd2, 0x28, 0x7a, 0xb6, 0x66, 0xac, 0x73, - 0xd4, 0x11, 0xc0, 0x81, 0xff, 0x71, 0x57, 0x4c, 0x23, 0x90, 0x2a, 0xd8, - 0x67, 0x7a, 0x6a, 0x58, 0xb7, 0x5b, 0xbe, 0x80, 0x62, 0x17, 0x10, 0x90, - 0xc1, 0xb7, 0x2c, 0xbe, 0xbe, 0x97, 0x2e, 0x85, 0x36, 0x07, 0x8e, 0x63, - 0xfc, 0x38, 0xc5, 0x66, 0x20, 0x33, 0x2b, 0xe8, 0x25, 0x25, 0xc1, 0x11, - 0xba, 0x5b, 0x12, 0xd9, 0x06, 0x4d, 0xfc, 0x49, 0x20, 0x27, 0x6b, 0x79, - 0x92, 0x8b, 0xde, 0x22, 0x39, 0xf9, 0x2e, 0xc9, 0x1b, 0xb9, 0x97, 0x2f, - 0xc3, 0x37, 0xf5, 0xa3, 0x6b, 0xd3, 0x3b, 0x94, 0xa5, 0x56, 0xb7, 0x81, - 0x7c, 0x9d, 0x28, 0xff, 0x57, 0xe7, 0x02, 0xa1, 0xd1, 0x3a, 0x3d, 0xac, - 0x74, 0x45, 0xb3, 0xab, 0x95, 0xec, 0x68, 0x8a, 0x9c, 0xf7, 0x43, 0xa4, - 0x14, 0x0d, 0x68, 0x40, 0x5f, 0x7e, 0x25, 0x8a, 0x47, 0x3f, 0x9c, 0xaf, - 0x88, 0x0b, 0x4a, 0xc0, 0x98, 0xc2, 0x57, 0xf4, 0xde, 0x04, 0x09, 0x37, - 0x9c, 0x87, 0x83, 0xb6, 0xa5, 0xa8, 0x5e, 0xc4, 0xec, 0x2e, 0xfd, 0xc9, - 0xf3, 0x85, 0x4f, 0x7d, 0xb8, 0xba, 0x6e, 0x6d, 0xc0, 0xd2, 0x37, 0xb2, - 0xba, 0x17, 0xad, 0x29, 0xf8, 0x71, 0x74, 0x0c, 0x93, 0x1e, 0x07, 0x34, - 0xec, 0xc3, 0x5f, 0x15, 0x21, 0x49, 0x0f, 0xa7, 0x7e, 0x72, 0x79, 0x66, - 0xfd, 0x3e, 0x29, 0xce, 0x12, 0xeb, 0x57, 0x88, 0xd8, 0xcc, 0x14, 0x96, - 0x33, 0x44, 0x64, 0x6c, 0x34, 0x55, 0xb3, 0x76, 0xc9, 0xa7, 0x3f, 0x7b, - 0x16, 0x9d, 0x7e, 0x95, 0x4c, 0xfa, 0xc9, 0x46, 0x17, 0x18, 0x18, 0x78, - 0xe7, 0xfb, 0x6b, 0x86, 0xf4, 0x25, 0x3a, 0x0b, 0x4a, 0xcd, 0x1a, 0x51, - 0xde, 0xa4, 0x45, 0xdd, 0xdb, 0xc9, 0x9f, 0xa9, 0xc3, 0x58, 0xb2, 0x43, - 0x90, 0x8b, 0xc1, 0x59, 0x47, 0x1a, 0x89, 0xcb, 0x9c, 0x6d, 0x46, 0x1f, - 0x0d, 0xe9, 0xfa, 0xd8, 0xe9, 0xde, 0xdb, 0xf5, 0x22, 0x9b, 0xe3, 0xef, - 0xb4, 0x0c, 0xc7, 0x34, 0xd0, 0x2a, 0x0f, 0x0b, 0x8e, 0x11, 0x88, 0x91, - 0xb7, 0xce, 0x92, 0xf2, 0x83, 0x3c, 0xd2, 0xf8, 0x42, 0x32, 0x82, 0x48, - 0xad, 0x67, 0x44, 0x45, 0x59, 0xac, 0x57, 0xb7, 0x7e, 0x1b, 0xce, 0xca, - 0x51, 0xfb, 0x1b, 0x12, 0x39, 0xaf, 0xe4, 0xfb, 0xdb, 0xc5, 0xb7, 0xcc, - 0x4a, 0x5d, 0xc4, 0xa6, 0x95, 0xaf, 0x5b, 0x39, 0x4e, 0x47, 0xc5, 0x50, - 0x67, 0x92, 0x84, 0x62, 0xeb, 0x81, 0x77, 0x24, 0xda, 0x27, 0x64, 0xfe, - 0xe4, 0x83, 0x40, 0x33, 0xc8, 0xb1, 0xaa, 0xbb, 0xbf, 0x13, 0xc3, 0x18, - 0x9a, 0x24, 0x06, 0xbd, 0x0a, 0x07, 0xa3, 0xd6, 0xd8, 0x38, 0x32, 0x73, - 0x8d, 0x40, 0x5f, 0xc2, 0x3f, 0xeb, 0xd2, 0x0e, 0x3d, 0x6d, 0xf5, 0x72, - 0x5a, 0xa6, 0x56, 0x22, 0x41, 0xe5, 0x0c, 0xb5, 0x0c, 0xda, 0xcd, 0x46, - 0xbc, 0xd7, 0x98, 0x89, 0x5e, 0x97, 0x54, 0x4f, 0x4b, 0xc0, 0x27, 0x51, - 0x0d, 0x20, 0x3f, 0x55, 0x78, 0xdc, 0x5a, 0x79, 0x08, 0xed, 0xd3, 0xaa, - 0x9c, 0xc3, 0x7d, 0x75, 0x76, 0x81, 0xa4, 0xe0, 0xfc, 0x90, 0x6a, 0x83, - 0x37, 0x53, 0xb8, 0xb5, 0xd9, 0x7a, 0xd9, 0x7d, 0xeb, 0x50, 0x72, 0xd3, - 0x5d, 0xed, 0x22, 0xfb, 0x6e, 0x67, 0x79, 0x9c, 0xb9, 0xea, 0xac, 0xc1, - 0x6d, 0x68, 0xf5, 0x12, 0xaa, 0x54, 0x90, 0xd8, 0x7f, 0xe0, 0xf4, 0xdd, - 0x3b, 0x88, 0xe3, 0xec, 0x7f, 0x1c, 0x2b, 0x08, 0x32, 0xc6, 0x05, 0x53, - 0xae, 0xa4, 0x46, 0xa7, 0xf3, 0xe6, 0xcb, 0xe7, 0x04, 0xc1, 0x52, 0xa7, - 0xfe, 0x68, 0x55, 0xc1, 0x91, 0xb2, 0x9a, 0x3b, 0x05, 0xc6, 0xae, 0x15, - 0x89, 0xdc, 0xb2, 0x0b, 0xeb, 0x19, 0x96, 0x62, 0xe3, 0x67, 0xc5, 0xdc, - 0xf5, 0xe8, 0xbe, 0x16, 0xbe, 0xf6, 0xe4, 0x0b, 0xeb, 0x99, 0x82, 0x65, - 0x0a, 0x97, 0xf5, 0xc2, 0x19, 0x1c, 0x1e, 0xa1, 0xf1, 0x75, 0x06, 0xa7, - 0xdb, 0x97, 0x68, 0x94, 0x0b, 0xea, 0xc4, 0xda, 0x70, 0x72, 0x3e, 0x9f, - 0xfc, 0x20, 0x4e, 0x54, 0xfb, 0x18, 0x01, 0x74, 0x9a, 0x24, 0x1d, 0x20, - 0x3a, 0x25, 0xe1, 0xd8, 0xaf, 0xe3, 0x76, 0xe0, 0x47, 0x53, 0x86, 0xd9, - 0x3f, 0xc2, 0x46, 0x4a, 0x02, 0x05, 0xaf, 0xbf, 0x49, 0x12, 0x22, 0x66, - 0x81, 0xf5, 0x9d, 0xdd, 0xae, 0x7f, 0xf5, 0x99, 0x2b, 0x89, 0xa6, 0x25, - 0x30, 0xd6, 0xb3, 0x00, 0xa4, 0x62, 0xd2, 0xb3, 0x8e, 0xdd, 0xc2, 0x04, - 0x62, 0x17, 0x44, 0xa3, 0x62, 0xf7, 0x8c, 0x56, 0x00, 0x4f, 0x98, 0xfe, - 0x7a, 0xdf, 0x9d, 0x47, 0xab, 0xc9, 0xb7, 0x0e, 0x0d, 0x02, 0x54, 0x6a, - 0xab, 0xf9, 0x22, 0xb9, 0x11, 0xb3, 0xec, 0x17, 0xb9, 0xc9, 0x86, 0xf6, - 0x66, 0x97, 0x1f, 0xa9, 0x38, 0xd8, 0x66, 0x8e, 0x41, 0xd9, 0x9a, 0x35, - 0xfd, 0x19, 0x64, 0xcb, 0x1e, 0x77, 0x80, 0xd4, 0x6d, 0xea, 0x00, 0xf5, - 0x9b, 0xc9, 0x55, 0xef, 0x80, 0x14, 0x79, 0xab, 0xf5, 0x5e, 0xb0, 0x4b, - 0x73, 0x52, 0x17, 0x2a, 0xd7, 0x68, 0x79, 0x6a, 0xf1, 0xc0, 0x04, 0xce, - 0x33, 0xd2, 0x18, 0xad, 0x39, 0x4d, 0xda, 0x40, 0x49, 0xce, 0x00, 0xca, - 0x89, 0xf3, 0xbd, 0x13, 0xe5, 0x7a, 0x03, 0x99, 0xa3, 0x4b, 0x29, 0xcd, - 0x18, 0xbd, 0xc8, 0xd7, 0x30, 0xcd, 0x4f, 0x65, 0xdc, 0xca, 0xc2, 0x9f, - 0x84, 0x2d, 0x83, 0xf6, 0x69, 0x0d, 0x55, 0x08, 0x5b, 0x6c, 0x87, 0x53, - 0xda, 0x13, 0x2a, 0x34, 0xf7, 0xea, 0x13, 0xec, 0x14, 0x90, 0xe8, 0x94, - 0xdc, 0xa6, 0xcf, 0xe9, 0x9b, 0x99, 0x63, 0x48, 0xf3, 0x34, 0xac, 0xf2, - 0x78, 0x76, 0x90, 0x46, 0xd8, 0x7d, 0x2b, 0xc1, 0xd2, 0xdd, 0xf1, 0xda, - 0x23, 0xc8, 0x3c, 0xd6, 0x58, 0x2e, 0xaf, 0x2c, 0xf6, 0x8a, 0xb3, 0x93, - 0x0e, 0x4f, 0x82, 0x7e, 0x26, 0x88, 0x0b, 0x3b, 0xe4, 0xe9, 0x85, 0x2b, - 0x99, 0xca, 0xdc, 0xad, 0x84, 0x26, 0xee, 0x35, 0x6a, 0x50, 0xc4, 0xae, - 0x95, 0x30, 0x0d, 0x09, 0xef, 0xdb, 0x4b, 0x4c, 0x9b, 0x0f, 0x04, 0x0a, - 0x6e, 0xf0, 0x92, 0x43, 0x06, 0xb9, 0x73, 0x16, 0x79, 0x15, 0x3f, 0x08, - 0xcc, 0x78, 0x2b, 0x35, 0x8c, 0xa3, 0x2a, 0x6e, 0xf6, 0x5c, 0x61, 0xf3, - 0xc6, 0x4b, 0x8a, 0xbc, 0x75, 0x1f, 0x4a, 0x00, 0x4e, 0x5f, 0x9e, 0x24, - 0x03, 0x2d, 0x86, 0x26, 0xa7, 0x78, 0xb7, 0xc3, 0x6f, 0x74, 0x6d, 0x32, - 0x34, 0xcd, 0x37, 0x42, 0x56, 0x24, 0x83, 0x7f, 0xa8, 0x1b, 0x9b, 0xae, - 0x97, 0x55, 0x2d, 0xba, 0x67, 0x75, 0x67, 0xca, 0xa5, 0xd1, 0x6e, 0xd6, - 0x48, 0xaf, 0xeb, 0x71, 0xdc, 0x31, 0xfb, 0x3b, 0xe3, 0x7c, 0x64, 0x9d, - 0xe5, 0x5a, 0xe4, 0x87, 0x6e, 0xed, 0xed, 0xca, 0xb6, 0x51, 0xfd, 0x73, - 0xef, 0x7c, 0xbc, 0x15, 0x69, 0xfd, 0x9f, 0x1f, 0x0f, 0x17, 0x1a, 0x8d, - 0x73, 0x61, 0x7d, 0xf1, 0x09, 0x97, 0x06, 0xbe, 0x90, 0x38, 0xdf, 0xac, - 0xfd, 0xe2, 0x87, 0xe8, 0xc1, 0xc3, 0x9b, 0x83, 0x79, 0xa6, 0xdd, 0x6d, - 0x58, 0x4d, 0x03, 0x26, 0x99, 0x1d, 0x2e, 0x47, 0xb0, 0x20, 0x3f, 0x84, - 0xaf, 0xfa, 0xf9, 0xf1, 0x62, 0xd5, 0x80, 0xb8, 0x6e, 0x69, 0x7e, 0x53, - 0x80, 0x05, 0xc4, 0x2f, 0xba, 0xed, 0x0d, 0x75, 0xca, 0x01, 0xde, 0x6e, - 0xf0, 0xd3, 0x23, 0x9b, 0x1e, 0xae, 0x02, 0x57, 0xeb, 0x40, 0xf2, 0x55, - 0x89, 0xd7, 0x70, 0xd6, 0x45, 0xe7, 0x67, 0xd3, 0x3e, 0x21, 0xda, 0xb6, - 0xae, 0xe5, 0xe6, 0x82, 0x0c, 0x3e, 0x3e, 0xe8, 0xbe, 0x85, 0x3d, 0x79, - 0x75, 0x90, 0x9b, 0x9c, 0x01, 0x88, 0x8d, 0x5a, 0x34, 0x1d, 0x10, 0x83, - 0x85, 0x08, 0xea, 0x88, 0x51, 0x29, 0xea, 0x95, 0x40, 0x2f, 0x16, 0x90, - 0xec, 0x1b, 0xb7, 0x22, 0x81, 0xcb, 0x1b, 0x8c, 0xf5, 0xe2, 0xfd, 0xcb, - 0x1f, 0xe7, 0xb0, 0x4b, 0x4d, 0x7c, 0x7d, 0x11, 0x17, 0x20, 0x89, 0x8b, - 0x4a, 0x80, 0xa3, 0x10, 0x6f, 0x68, 0x09, 0x01, 0x68, 0x86, 0x3b, 0x2a, - 0xfb, 0x48, 0x80, 0xa0, 0xd1, 0xdb, 0x3f, 0x91, 0x44, 0x58, 0x83, 0xc6, - 0x85, 0x77, 0x6b, 0xb1, 0x35, 0x4a, 0x03, 0xa2, 0xcf, 0x2f, 0xbd, 0xcd, - 0x4b, 0xfa, 0x5a, 0x5e, 0x8f, 0x8b, 0x95, 0x62, 0xaa, 0xe7, 0x3b, 0x54, - 0xb1, 0xec, 0xd5, 0x85, 0x4f, 0xd9, 0x59, 0x56, 0xb4, 0xec, 0xc1, 0x21, - 0xc5, 0xa6, 0x35, 0x1d, 0x7b, 0x60, 0xe1, 0xb1, 0x7c, 0x8f, 0x47, 0xa1, - 0xf1, 0x13, 0x4b, 0xaf, 0x23, 0xcb, 0x5e, 0xe2, 0x74, 0x16, 0x16, 0x96, - 0x3b, 0xff, 0xbf, 0x26, 0x5f, 0x68, 0xd5, 0x64, 0xc6, 0x62, 0xaf, 0x4a, - 0xfc, 0x0f, 0x27, 0x3e, 0x96, 0x5b, 0x7c, 0xeb, 0x78, 0x81, 0x3c, 0x0a, - 0x63, 0xd5, 0x6b, 0x3c, 0xa9, 0xd4, 0x37, 0x03, 0x3b, 0x5c, 0x62, 0x7a, - 0xd5, 0x69, 0xbe, 0x44, 0x50, 0xab, 0x0a, 0x54, 0x31, 0x5c, 0x44, 0x52, - 0xfe, 0xde, 0xbb, 0x10, 0x80, 0x79, 0xb2, 0x69, 0xc5, 0x75, 0x8b, 0xba, - 0x1d, 0x4d, 0x2d, 0xfa, 0xc8, 0x0e, 0xc0, 0xaf, 0xc2, 0x31, 0xa1, 0x53, - 0xc7, 0x9f, 0x3e, 0x1f, 0x38, 0x8c, 0x1e, 0x00, 0x78, 0x76, 0xb6, 0xb5, - 0x68, 0xa4, 0x68, 0xe9, 0xba, 0xda, 0x97, 0xca, 0x16, 0xde, 0xba, 0xa1, - 0xb7, 0x17, 0x26, 0xb3, 0x4b, 0x4b, 0x4e, 0x21, 0x9c, 0xaf, 0xce, 0xf0, - 0x52, 0x41, 0x13, 0x87, 0x75, 0xc4, 0xd7, 0x34, 0x0c, 0x2d, 0xfe, 0xc1, - 0xb6, 0x60, 0x84, 0xd2, 0x57, 0xc2, 0xb2, 0x6c, 0xa6, 0x97, 0x51, 0xea, - 0x49, 0x07, 0x7d, 0xac, 0x15, 0x75, 0x71, 0x67, 0x2c, 0xdf, 0x09, 0x0c, - 0x63, 0x38, 0x6a, 0x25, 0xf3, 0x9b, 0x5d, 0x5d, 0x63, 0xe7, 0x20, 0xa3, - 0xf5, 0x6f, 0x8c, 0x77, 0x91, 0xb0, 0x6d, 0xad, 0x01, 0x1d, 0x40, 0x65, - 0xcd, 0x31, 0xbf, 0xb2, 0x0a, 0x1f, 0xf9, 0xb0, 0x34, 0x7f, 0x6a, 0xfe, - 0xca, 0x2e, 0x28, 0xc4, 0x5b, 0xdb, 0xa9, 0xd4, 0xdc, 0xe6, 0x3a, 0x0a, - 0xeb, 0xe2, 0xc5, 0xb8, 0xbe, 0xad, 0x8d, 0x7d, 0xa2, 0x5e, 0x88, 0xad, - 0xb8, 0xda, 0x41, 0x12, 0x1f, 0xc5, 0x85, 0xa1, 0x83, 0x3d, 0xc7, 0xbb, - 0x6d, 0x55, 0x63, 0xd0, 0x8b, 0x06, 0x76, 0x96, 0xf5, 0x0b, 0xd9, 0x2f, - 0x45, 0xf4, 0x9b, 0xc8, 0x18, 0xba, 0xbd, 0x30, 0xdc, 0x4d, 0x47, 0xde, - 0xbc, 0xc0, 0xc0, 0xca, 0x9f, 0xd7, 0xda, 0xcb, 0xd8, 0xdd, 0x7e, 0x98, - 0x25, 0xfd, 0x9f, 0xa4, 0x22, 0x5d, 0x4b, 0x63, 0x1b, 0xfa, 0x78, 0xdb, - 0x3d, 0x39, 0xcc, 0x26, 0x00, 0x70, 0x0e, 0xac, 0xf7, 0x30, 0xc0, 0x8c, - 0x97, 0xbe, 0x57, 0xeb, 0x1a, 0xc0, 0xfd, 0x4c, 0x81, 0x69, 0x54, 0x1b, - 0xd4, 0x8c, 0xb2, 0xe7, 0xf0, 0x5f, 0x0e, 0x46, 0x95, 0x7a, 0x2b, 0x0c, - 0x69, 0x37, 0x89, 0x45, 0x6a, 0xb2, 0x9f, 0xa8, 0x99, 0xd2, 0x6c, 0xa0, - 0x9d, 0xc0, 0x36, 0x65, 0x2f, 0x37, 0xe3, 0xc8, 0xba, 0x4f, 0xd2, 0x4c, - 0x69, 0x2e, 0x15, 0x2c, 0x92, 0x13, 0x44, 0x96, 0xa5, 0xe9, 0x90, 0x24, - 0x0a, 0x94, 0x44, 0x16, 0x6a, 0x8e, 0x4a, 0x7b, 0xf4, 0x65, 0x41, 0xd0, - 0x4e, 0xf3, 0xf2, 0x6d, 0x8e, 0xc0, 0x70, 0xdf, 0x56, 0x2f, 0x11, 0x80, - 0x03, 0x42, 0xb5, 0x9c, 0x59, 0xea, 0xe1, 0x2d, 0xc7, 0xd1, 0x29, 0x4a, - 0xce, 0x78, 0x83, 0x8f, 0x9b, 0xd4, 0x6b, 0x91, 0xd8, 0x7b, 0xd1, 0x03, - 0xc1, 0xe8, 0x84, 0xbc, 0xca, 0x64, 0xdd, 0xac, 0xdd, 0x39, 0xaf, 0x7c, - 0x5d, 0x7a, 0x5f, 0xc3, 0x8b, 0x0f, 0xd7, 0x18, 0x43, 0x4a, 0x8e, 0x3f, - 0x2f, 0x02, 0x91, 0xa2, 0xdc, 0x3e, 0x2c, 0x9c, 0x3b, 0x3c, 0xe3, 0xd4, - 0x9a, 0xb3, 0x59, 0x43, 0xd4, 0x75, 0x1c, 0x4b, 0x0b, 0xad, 0x84, 0x2d, - 0xbd, 0x05, 0x66, 0xdb, 0x0a, 0xda, 0x77, 0x75, 0x46, 0x78, 0x99, 0x44, - 0xdf, 0x12, 0x58, 0xa9, 0x3a, 0x5f, 0x04, 0x18, 0x81, 0xa2, 0x2d, 0xcf, - 0x9c, 0x35, 0x8d, 0x67, 0x73, 0x9e, 0x8d, 0xe4, 0xc9, 0x9d, 0x15, 0x80, - 0xe3, 0x36, 0xf9, 0xbd, 0xf2, 0x65, 0xb2, 0x10, 0xa9, 0xe8, 0x2a, 0x03, - 0x9d, 0x03, 0x11, 0xe5, 0xcc, 0x32, 0x12, 0xef, 0xee, 0x22, 0xa3, 0x0c, - 0x35, 0x28, 0xc0, 0x17, 0x9b, 0x43, 0x75, 0x5f, 0x2c, 0xbf, 0xeb, 0xc4, - 0xf2, 0xa0, 0x6e, 0xcb, 0x06, 0x1c, 0x5c, 0xd9, 0xe8, 0x56, 0xaf, 0xe4, - 0x2c, 0x6a, 0x8a, 0x9e, 0xea, 0x34, 0x60, 0x09, 0x94, 0xe7, 0xb2, 0x50, - 0x4b, 0xc9, 0xeb, 0xce, 0xd2, 0x7f, 0x1d, 0xc1, 0x22, 0xe1, 0x71, 0x1f, - 0xac, 0xb7, 0xb9, 0x5c, 0x8e, 0x44, 0xe9, 0x51, 0x58, 0x5c, 0x0e, 0x12, - 0x34, 0xb5, 0xab, 0xa1, 0x0d, 0xf1, 0xc6, 0x71, 0xf0, 0x51, 0x6f, 0xa8, - 0x72, 0xde, 0xad, 0x42, 0xe6, 0x39, 0x28, 0xb0, 0x66, 0xf8, 0xcb, 0x09, - 0xb2, 0x82, 0x5a, 0x02, 0x15, 0xca, 0x17, 0xa9, 0x63, 0xd8, 0xac, 0x18, - 0x49, 0xf7, 0xfa, 0x6d, 0xad, 0x3f, 0xf5, 0x2a, 0xd2, 0x1a, 0x9e, 0x4f, - 0xdc, 0xb1, 0xb5, 0x5b, 0x93, 0x59, 0x44, 0x72, 0x0c, 0xf4, 0x7e, 0xe4, - 0x62, 0x10, 0x64, 0xad, 0x2d, 0xb0, 0x2e, 0xcb, 0xf8, 0xd9, 0xbb, 0xf9, - 0xfc, 0xc5, 0xe1, 0x31, 0x6e, 0x0e, 0x8b, 0x12, 0x62, 0x25, 0x92, 0xd6, - 0xb0, 0x0d, 0x78, 0x7e, 0x03, 0x13, 0x65, 0xe0, 0xa3, 0x5d, 0x33, 0xc7, - 0x04, 0x8b, 0xe7, 0x45, 0xa8, 0x9f, 0xd1, 0x70, 0x27, 0x32, 0x6e, 0x50, - 0x48, 0x6a, 0xd3, 0x32, 0xcb, 0xca, 0xd5, 0xcd, 0xd4, 0x0a, 0x76, 0x8e, - 0x6b, 0xb1, 0x73, 0x68, 0x38, 0xf5, 0x73, 0xb2, 0x46, 0x7a, 0xb5, 0xff, - 0xea, 0x52, 0xc9, 0x5b, 0x56, 0xff, 0xf0, 0x35, 0x4b, 0xae, 0x88, 0x61, - 0x8a, 0x3c, 0xb9, 0x78, 0x1c, 0x51, 0xaa, 0x5d, 0xaf, 0xe0, 0xe7, 0x8c, - 0x03, 0x85, 0x6a, 0x1f, 0xca, 0xb9, 0x8c, 0xf4, 0x37, 0xea, 0xae, 0x54, - 0xf1, 0xb8, 0x4c, 0x94, 0x42, 0xcf, 0x2a, 0x8d, 0x13, 0xef, 0x66, 0xf8, - 0x1b, 0xbe, 0x5d, 0x9a, 0x24, 0x12, 0xb5, 0xe8, 0xe8, 0x44, 0x6b, 0x95, - 0xd6, 0xed, 0x98, 0xd8, 0x10, 0xeb, 0x19, 0xe5, 0x42, 0x01, 0xaa, 0x1c, - 0x6a, 0x62, 0xd2, 0xf0, 0xc3, 0x33, 0x4d, 0xf0, 0x3e, 0x76, 0x8d, 0xec, - 0xbb, 0xb9, 0xeb, 0x14, 0x77, 0x02, 0x39, 0xb7, 0x75, 0x21, 0x3a, 0xa5, - 0xef, 0x04, 0xb3, 0x20, 0x50, 0xaf, 0xed, 0x99, 0x0b, 0xec, 0x12, 0x6d, - 0xad, 0x9f, 0x23, 0x02, 0xc0, 0x01, 0x5a, 0xfe, 0xfc, 0xee, 0xa9, 0xc1, - 0x23, 0x51, 0x71, 0xb0, 0xe6, 0xee, 0xcc, 0xcd, 0x6a, 0x59, 0xcf, 0xad, - 0xff, 0x4b, 0x36, 0xbf, 0x2a, 0xaf, 0x56, 0xae, 0xd7, 0x35, 0x47, 0xc4, - 0x11, 0xef, 0x66, 0x18, 0xd1, 0xec, 0x2a, 0x5c, 0xca, 0xfe, 0x8f, 0x8b, - 0xa2, 0x80, 0x57, 0x42, 0xe5, 0xa5, 0xb4, 0x7a, 0x34, 0xd0, 0x1b, 0xca, - 0xb3, 0x7f, 0x2c, 0x54, 0x47, 0x50, 0xf0, 0xdd, 0xde, 0x87, 0xc0, 0x8f, - 0x3a, 0x79, 0x49, 0x50, 0xe9, 0x4a, 0xe2, 0x74, 0x08, 0x18, 0x61, 0xaa, - 0x17, 0xe4, 0x44, 0xdf, 0xeb, 0xf8, 0x2f, 0x5f, 0x06, 0x19, 0x06, 0x13, - 0xec, 0x14, 0x47, 0x04, 0x51, 0x03, 0x55, 0x62, 0x78, 0x73, 0x7d, 0xe9, - 0x15, 0xff, 0xd3, 0xb2, 0x5c, 0x54, 0x79, 0xca, 0x58, 0x10, 0x86, 0x66, - 0x4d, 0x6a, 0x73, 0x13, 0x20, 0x60, 0xd1, 0xaa, 0x54, 0xa8, 0xf3, 0x45, - 0x1c, 0x02, 0x23, 0xc6, 0x43, 0xee, 0xb4, 0xf4, 0xed, 0xa3, 0x59, 0xb7, - 0xb3, 0x4e, 0xda, 0xdf, 0x5f, 0x12, 0xed, 0xb0, 0x03, 0x93, 0xc7, 0xb7, - 0xa9, 0x52, 0xdb, 0x91, 0x39, 0x4f, 0x0d, 0x6d, 0x31, 0x08, 0xf5, 0x91, - 0x90, 0xe5, 0x11, 0xbf, 0x33, 0x4d, 0x3f, 0x7b, 0xc8, 0x46, 0xbf, 0x8f, - 0x27, 0x61, 0xc3, 0x6c, 0xea, 0xfa, 0xaf, 0xeb, 0x92, 0xd1, 0x86, 0xb4, - 0x50, 0x64, 0x6c, 0xba, 0xdf, 0x1f, 0xe9, 0xc6, 0x2f, 0xad, 0x8d, 0x95, - 0xe7, 0xfe, 0xcb, 0xbf, 0xcc, 0xba, 0xbd, 0xcc, 0x62, 0x85, 0x62, 0x7a, - 0x96, 0x85, 0x02, 0x1c, 0xc1, 0x8f, 0x4b, 0xfc, 0x4f, 0xea, 0x69, 0x8b, - 0x1c, 0x83, 0x81, 0x34, 0x15, 0x12, 0x16, 0x6f, 0x9c, 0x0e, 0xa4, 0x83, - 0xb6, 0x28, 0x2f, 0xd7, 0x6d, 0x2e, 0x98, 0x6a, 0xe7, 0x6f, 0x53, 0x83, - 0x18, 0x43, 0x75, 0x25, 0x97, 0x14, 0x15, 0x8d, 0x2f, 0x7f, 0x72, 0x1a, - 0x07, 0x42, 0x2a, 0x7a, 0xe4, 0x7e, 0xc4, 0x7a, 0x6a, 0xc9, 0x0f, 0xeb, - 0x4b, 0x60, 0x56, 0x15, 0x51, 0x23, 0x5d, 0xfa, 0x0e, 0x56, 0x06, 0x35, - 0x89, 0x89, 0x77, 0x55, 0xd3, 0xd7, 0x22, 0x2f, 0x41, 0xc5, 0x70, 0x3f, - 0x57, 0x80, 0xc6, 0xab, 0x30, 0x7e, 0xd8, 0x2b, 0xd2, 0xd2, 0xa2, 0xfc, - 0xf9, 0x32, 0x22, 0x9e, 0x63, 0x67, 0x8a, 0x55, 0xac, 0x4e, 0x66, 0x98, - 0xe6, 0x20, 0xea, 0xbd, 0x64, 0xe9, 0xd5, 0x06, 0x33, 0x33, 0xbf, 0xe2, - 0x89, 0x49, 0x91, 0x92, 0x4e, 0xf9, 0xcc, 0x23, 0xad, 0x26, 0x1a, 0xb1, - 0x01, 0x40, 0x9b, 0x3f, 0x30, 0x5c, 0x88, 0xaf, 0xce, 0x83, 0xc3, 0x45, - 0x90, 0xdc, 0xa6, 0x20, 0x3e, 0x15, 0x96, 0x25, 0xdf, 0xe1, 0xa6, 0xd6, - 0x78, 0xaf, 0xda, 0xc0, 0x0c, 0xf1, 0x21, 0x03, 0xf9, 0x7f, 0xb5, 0xfd, - 0x59, 0x20, 0x3d, 0x73, 0xad, 0xfb, 0x2b, 0x5f, 0x88, 0xbc, 0x17, 0xaf, - 0x1c, 0xaa, 0x5d, 0x17, 0x8f, 0xb7, 0x60, 0x9c, 0xc7, 0xc4, 0xe4, 0xf4, - 0xdb, 0xa9, 0x39, 0xb0, 0xd1, 0xb4, 0x6b, 0x4b, 0x20, 0xaf, 0xd5, 0xcc, - 0xd9, 0x68, 0x17, 0x4c, 0x9a, 0xd4, 0x35, 0x25, 0x17, 0x3b, 0xc3, 0x41, - 0x7b, 0x05, 0xe9, 0xe8, 0xdd, 0x02, 0x9d, 0x0f, 0x6a, 0xd7, 0xf5, 0xfa, - 0xae, 0xf2, 0x5b, 0xfe, 0xc4, 0x44, 0x62, 0xd6, 0xc4, 0x8e, 0x4b, 0x28, - 0x6a, 0x87, 0x3c, 0xe3, 0xf8, 0x01, 0xb5, 0xf9, 0x77, 0x4e, 0x07, 0x8f, - 0x40, 0x02, 0x72, 0x81, 0xa9, 0x6e, 0xa8, 0x84, 0x1f, 0xfe, 0x2e, 0x06, - 0x83, 0xb8, 0x14, 0x2b, 0xf8, 0x6e, 0x8b, 0xb2, 0xed, 0xff, 0xc5, 0x90, - 0x09, 0x86, 0xef, 0xe7, 0x64, 0xb3, 0x3f, 0x10, 0xe1, 0x47, 0xff, 0x4f, - 0xac, 0x76, 0x45, 0xa8, 0xba, 0xac, 0xab, 0x82, 0x07, 0x86, 0x8a, 0x24, - 0xf5, 0xc0, 0x01, 0x5f, 0x54, 0x8b, 0xdc, 0xbd, 0xd6, 0x28, 0x05, 0x56, - 0xfd, 0x13, 0xdf, 0x93, 0x9b, 0x68, 0x03, 0x90, 0x2c, 0x08, 0xcc, 0x0b, - 0xf9, 0x14, 0x44, 0x84, 0x79, 0x15, 0xab, 0xbc, 0x54, 0x1b, 0x76, 0xe3, - 0xfa, 0xf8, 0x32, 0xab, 0xf2, 0xcd, 0xed, 0x04, 0x15, 0x94, 0xb4, 0xb3, - 0xcc, 0x09, 0xf1, 0xb2, 0x35, 0x60, 0x0b, 0x05, 0xa1, 0x31, 0xd6, 0x6d, - 0xc6, 0x46, 0x6d, 0xe4, 0xe7, 0xbc, 0x5f, 0x3a, 0x72, 0xfd, 0x42, 0xb0, - 0x0e, 0xbb, 0xd2, 0xeb, 0x50, 0x26, 0x60, 0x38, 0xd6, 0x96, 0x1b, 0x5b, - 0x9d, 0xcc, 0xb4, 0x98, 0x9f, 0xe8, 0xf2, 0x95, 0xa3, 0x11, 0x9a, 0xcb, - 0x6d, 0x56, 0x87, 0x4b, 0x95, 0xb9, 0x41, 0xa3, 0x89, 0x2d, 0x2c, 0x29, - 0xe8, 0x29, 0x86, 0x47, 0x3e, 0x91, 0x2a, 0x59, 0x7d, 0x9c, 0x03, 0x9d, - 0x2d, 0xff, 0x05, 0x50, 0x21, 0x88, 0x12, 0x55, 0x2b, 0x25, 0x0c, 0x0c, - 0x59, 0xa9, 0x1f, 0xbd, 0x1c, 0xa0, 0xf9, 0xc2, 0x23, 0x4b, 0xaa, 0xbe, - 0x10, 0x4f, 0xf7, 0x5a, 0x25, 0x49, 0xb2, 0xc8, 0xdc, 0xf7, 0xb1, 0x45, - 0xdf, 0xbb, 0x15, 0xd9, 0x48, 0x49, 0x01, 0x27, 0xf6, 0xdc, 0x59, 0x48, - 0xb7, 0xd7, 0x5e, 0x46, 0xde, 0x2c, 0x27, 0x64, 0xf9, 0xc2, 0xc5, 0x37, - 0x21, 0x9a, 0xbf, 0x62, 0x14, 0xdd, 0x13, 0x26, 0x9f, 0x62, 0x65, 0x55, - 0xe8, 0xd7, 0x6f, 0x10, 0x5c, 0xd7, 0x19, 0x16, 0x1b, 0x87, 0xd3, 0x74, - 0xd2, 0x8a, 0x89, 0x15, 0x17, 0xd8, 0x83, 0x8f, 0x3f, 0x38, 0x98, 0x9b, - 0x25, 0x03, 0xc7, 0x7c, 0x35, 0x88, 0x53, 0x48, 0xca, 0xd6, 0x4d, 0x20, - 0x23, 0x54, 0x15, 0x51, 0xda, 0xfb, 0x7e, 0x41, 0xbc, 0x88, 0xf5, 0x53, - 0xf6, 0xe2, 0x54, 0xe6, 0xa8, 0xb1, 0x04, 0xac, 0xd1, 0xd6, 0x37, 0xd2, - 0xa9, 0x6f, 0x96, 0xc0, 0x6a, 0xb1, 0xd4, 0xcf, 0x1e, 0xda, 0xda, 0x72, - 0x43, 0xaa, 0x7b, 0x7d, 0x39, 0x19, 0x11, 0x06, 0x2a, 0x73, 0x87, 0xe6, - 0xdb, 0x8a, 0xcf, 0x66, 0xf2, 0x77, 0xc9, 0x0a, 0xe2, 0x13, 0x90, 0xd6, - 0x1b, 0xa6, 0xfb, 0xfd, 0xda, 0x63, 0x80, 0x81, 0x55, 0x7a, 0x4b, 0xea, - 0x79, 0x4d, 0xa9, 0x46, 0x2b, 0xb1, 0xa5, 0x98, 0x8d, 0x34, 0x32, 0x07, - 0xc6, 0xff, 0x98, 0x17, 0xd1, 0x55, 0x85, 0xc6, 0x8d, 0x0a, 0x3b, 0x58, - 0x1e, 0x82, 0x24, 0xa2, 0xef, 0x83, 0xed, 0xf6, 0xe2, 0x79, 0x1b, 0x2b, - 0x46, 0x7e, 0x94, 0x5b, 0xc8, 0x5a, 0x93, 0xef, 0xca, 0x76, 0xc7, 0xef, - 0x71, 0xce, 0x15, 0x33, 0x91, 0xef, 0x46, 0xa9, 0x58, 0xd8, 0x6d, 0xa9, - 0x47, 0x45, 0x35, 0xbb, 0xce, 0x96, 0xb7, 0x44, 0xd4, 0x7a, 0x90, 0xd4, - 0xcb, 0x18, 0xbc, 0x7b, 0x64, 0xf3, 0x8e, 0xf5, 0xd5, 0xf7, 0x82, 0xdb, - 0xff, 0xd6, 0x50, 0x17, 0xdf, 0x9a, 0x11, 0x75, 0x85, 0x36, 0xc8, 0x0c, - 0x44, 0xcc, 0xdc, 0x76, 0xfc, 0x9f, 0x3e, 0x84, 0x8f, 0xea, 0xc6, 0xb1, - 0xfa, 0x97, 0x75, 0x31, 0xe8, 0xc2, 0x81, 0x7b, 0x39, 0x14, 0xad, 0xdf, - 0x67, 0xf2, 0x44, 0xe0, 0xc4, 0x7a, 0x21, 0x63, 0x74, 0x73, 0x41, 0xf4, - 0xb5, 0xbd, 0x87, 0x36, 0xd0, 0x64, 0xb6, 0x8e, 0x98, 0xd2, 0x79, 0x5f, - 0x4d, 0x22, 0x8c, 0xc1, 0x41, 0x4c, 0xea, 0xb7, 0xab, 0x4b, 0x2e, 0xca, - 0x35, 0x14, 0xd3, 0x90, 0x9e, 0xd6, 0x94, 0x3e, 0x7e, 0xe4, 0x57, 0x09, - 0x22, 0x3c, 0xe6, 0xbe, 0x04, 0x95, 0x75, 0xf8, 0xe0, 0x42, 0xe9, 0xe2, - 0x5e, 0x2e, 0x2a, 0xc6, 0x48, 0x55, 0x42, 0x39, 0xc4, 0x81, 0x6a, 0xc6, - 0x19, 0xea, 0x4c, 0x63, 0x60, 0x11, 0xdf, 0xe7, 0xde, 0x4d, 0x0f, 0xec, - 0x0c, 0x8f, 0x21, 0xe7, 0x94, 0x72, 0x24, 0x4d, 0xc0, 0x44, 0x30, 0x63, - 0x18, 0x06, 0x9b, 0xb9, 0x63, 0xc2, 0x94, 0x6d, 0x78, 0xba, 0x36, 0x58, - 0xe3, 0x07, 0x0f, 0xd4, 0x16, 0xe5, 0xc7, 0x58, 0xb1, 0x5e, 0x96, 0x25, - 0x80, 0xc0, 0x0c, 0x4d, 0xf1, 0xda, 0x8b, 0xc6, 0x66, 0x56, 0x1e, 0x7c, - 0x64, 0x6b, 0x2c, 0xb2, 0x8c, 0xed, 0x07, 0xa7, 0x52, 0x70, 0xbd, 0x68, - 0xd3, 0x48, 0x18, 0x38, 0xa6, 0x60, 0x18, 0x97, 0x4a, 0xd0, 0x88, 0xed, - 0x4c, 0x99, 0xad, 0x88, 0x56, 0xec, 0x2b, 0xd7, 0xb4, 0xd6, 0xc6, 0x43, - 0x58, 0xf6, 0x9b, 0xfb, 0x28, 0xa7, 0xb4, 0xaa, 0x61, 0xc4, 0x09, 0x0b, - 0xa7, 0x51, 0x7a, 0xd3, 0x2f, 0x84, 0xeb, 0x9e, 0xc9, 0xc9, 0xac, 0x7e, - 0x80, 0x2e, 0xa6, 0x88, 0x84, 0xd2, 0x54, 0xca, 0xe6, 0xf1, 0x7c, 0x97, - 0x7c, 0x8a, 0x8a, 0x66, 0x7f, 0x00, 0x4b, 0x73, 0x3f, 0x2e, 0xfb, 0xcc, - 0xe5, 0x07, 0xe6, 0x4e, 0xa1, 0x8e, 0xfc, 0x62, 0xb7, 0xd7, 0xbe, 0xa4, - 0x4a, 0x65, 0xd7, 0xe2, 0xaa, 0x0c, 0xdd, 0x93, 0x93, 0x63, 0x56, 0x46, - 0xe5, 0xe5, 0xf5, 0x47, 0xb1, 0xe4, 0x4e, 0x60, 0x97, 0x83, 0x82, 0x23, - 0x84, 0x37, 0x20, 0xbd, 0xb5, 0x8b, 0x9d, 0x5d, 0xc8, 0xca, 0xe1, 0xa8, - 0x5a, 0xc4, 0xaa, 0xe2, 0x79, 0xda, 0x1d, 0x48, 0x60, 0x4c, 0x2e, 0x06, - 0x95, 0xb4, 0x76, 0x42, 0xa0, 0x6e, 0x52, 0x52, 0x0f, 0xf8, 0x24, 0x81, - 0x21, 0x6f, 0x67, 0x27, 0x9e, 0xe5, 0xf9, 0x9b, 0x8c, 0x82, 0x90, 0x90, - 0xdd, 0xe7, 0xd4, 0x24, 0x54, 0xa7, 0x26, 0x41, 0xd2, 0x54, 0x50, 0x6a, - 0x66, 0xf0, 0xd5, 0x68, 0xaf, 0xd1, 0xd2, 0x00, 0x66, 0xa1, 0x9e, 0x1b, - 0xab, 0xe6, 0x43, 0xa2, 0xb8, 0x05, 0x2f, 0xae, 0x9b, 0xce, 0x15, 0xa2, - 0x5b, 0xd1, 0xb5, 0x53, 0x66, 0x6e, 0xc9, 0x44, 0x7b, 0x8c, 0x5d, 0x94, - 0x63, 0x3c, 0xa5, 0xc5, 0x81, 0x48, 0xd7, 0x98, 0x6b, 0xb7, 0xce, 0xe4, - 0xd9, 0xaf, 0x1c, 0xa9, 0x76, 0x8c, 0x1b, 0x4b, 0x5c, 0x1e, 0x9c, 0x98, - 0xef, 0x74, 0x40, 0xe3, 0xf1, 0x48, 0x8c, 0x14, 0x66, 0xe4, 0x7d, 0xbd, - 0xff, 0xcf, 0xae, 0xf8, 0x36, 0x79, 0x83, 0x76, 0xe7, 0x66, 0x36, 0x12, - 0x60, 0x17, 0x2f, 0xb0, 0x2f, 0x22, 0x32, 0x4b, 0x42, 0x65, 0xed, 0x76, - 0x6e, 0x4c, 0x9d, 0xb9, 0x54, 0x9b, 0x98, 0x8b, 0x79, 0x8b, 0x0e, 0xaf, - 0x9c, 0x8c, 0xa9, 0x58, 0xaa, 0xa2, 0xde, 0x1a, 0x9b, 0x6d, 0x75, 0x0f, - 0xd2, 0xd4, 0x28, 0xdc, 0xca, 0xcd, 0x91, 0x66, 0xd0, 0xd9, 0xab, 0x3c, - 0x22, 0x55, 0x36, 0x87, 0x4f, 0x41, 0x24, 0x5c, 0xee, 0x5a, 0x54, 0x1a, - 0xe0, 0xf5, 0x2c, 0x01, 0x98, 0xa3, 0x54, 0x6e, 0x6f, 0xdc, 0x88, 0xf7, - 0x86, 0xba, 0xe2, 0x8d, 0x84, 0x95, 0x78, 0x84, 0x8c, 0xc1, 0xae, 0x8c, - 0x7f, 0xa7, 0x91, 0xbc, 0x6d, 0x3b, 0x48, 0x7a, 0x42, 0xa0, 0xc0, 0x0a, - 0xfe, 0xda, 0xbc, 0xe7, 0xa6, 0x76, 0xcb, 0xca, 0x68, 0xb0, 0xda, 0xb3, - 0x2e, 0x4c, 0x57, 0x50, 0xeb, 0xbb, 0x0a, 0x35, 0x94, 0x80, 0xab, 0xcf, - 0xa7, 0xdc, 0xab, 0x31, 0x54, 0xef, 0xe0, 0x77, 0xa5, 0x7e, 0x9e, 0x76, - 0x96, 0x62, 0x92, 0x25, 0xf1, 0xa1, 0xa5, 0x91, 0x06, 0x9e, 0x2f, 0x81, - 0xd8, 0x5f, 0x2e, 0xe4, 0xe8, 0xda, 0x9f, 0xe1, 0x62, 0xe1, 0x30, 0xd0, - 0x16, 0x02, 0xc6, 0xeb, 0x3a, 0x43, 0x4e, 0x64, 0x07, 0x77, 0xf2, 0xda, - 0x0d, 0xf5, 0xd3, 0x1c, 0x26, 0x4c, 0xcd, 0xa4, 0xb3, 0xc5, 0xd6, 0x73, - 0xb4, 0xbc, 0xc0, 0x07, 0x64, 0x98, 0xfb, 0xf6, 0x32, 0xe4, 0xe1, 0xca, - 0x74, 0x4c, 0x64, 0xad, 0x04, 0x53, 0x1b, 0x99, 0x24, 0x7b, 0x2e, 0xd7, - 0x3e, 0x07, 0xba, 0x7a, 0x08, 0x7b, 0xb1, 0xb0, 0x11, 0x3f, 0x4e, 0x66, - 0xd8, 0xa5, 0x4e, 0x72, 0x67, 0xa6, 0xbe, 0x38, 0x76, 0xcf, 0x72, 0x07, - 0x9a, 0x57, 0x2f, 0x29, 0x6d, 0x55, 0xcd, 0x69, 0xed, 0xcf, 0x59, 0x5e, - 0xd9, 0xe5, 0x29, 0x5b, 0xd0, 0x4d, 0x85, 0xea, 0x44, 0x0c, 0xac, 0x2d, - 0x76, 0x28, 0x65, 0x39, 0x2a, 0xfc, 0x9f, 0xe8, 0xd8, 0xce, 0x5c, 0x56, - 0xc0, 0x33, 0xa4, 0xcc, 0x32, 0xa6, 0x00, 0xd8, 0x9d, 0x9d, 0x0a, 0x28, - 0x27, 0x15, 0x42, 0x8e, 0xeb, 0xb0, 0xef, 0x6f, 0xb8, 0x93, 0xe2, 0xdf, - 0x6e, 0x17, 0x46, 0x67, 0x59, 0x05, 0x92, 0xad, 0x87, 0xc6, 0x06, 0x35, - 0xc8, 0x4c, 0x05, 0x1c, 0x9f, 0xf4, 0xa4, 0xa4, 0xa1, 0x8d, 0x11, 0xc7, - 0xab, 0x4b, 0x9b, 0x3a, 0x71, 0xcb, 0x2d, 0x1f, 0xec, 0x61, 0xa0, 0x66, - 0x5f, 0x3d, 0xa3, 0x95, 0x39, 0x7f, 0x98, 0x34, 0x79, 0x32, 0x15, 0x94, - 0xa0, 0x16, 0xa4, 0xf3, 0x45, 0x7b, 0x31, 0xfe, 0xf2, 0xe3, 0x65, 0x01, - 0xc1, 0xf7, 0xcd, 0xcb, 0x59, 0x52, 0xbb, 0xf6, 0xa4, 0x12, 0x22, 0x9e, - 0x5f, 0xd0, 0x50, 0x8a, 0x43, 0x62, 0xfd, 0x22, 0x21, 0xfb, 0xae, 0x08, - 0x57, 0xc7, 0x00, 0xa6, 0x48, 0x2e, 0xcb, 0x0b, 0x76, 0x08, 0xf9, 0xd4, - 0x14, 0x9a, 0xb5, 0xcd, 0xb8, 0x33, 0xc3, 0x0d, 0x2a, 0x3a, 0xf0, 0xe2, - 0x5f, 0x0e, 0x1f, 0xa1, 0x1c, 0x71, 0x38, 0x2e, 0x8e, 0x93, 0x13, 0x27, - 0xa2, 0x4a, 0xdc, 0x95, 0x1e, 0x26, 0x30, 0x5f, 0xdd, 0xc4, 0x15, 0x8e, - 0xa8, 0xfd, 0x80, 0xf4, 0x9e, 0x31, 0x80, 0xc9, 0xa0, 0xf7, 0x61, 0xb5, - 0x55, 0x40, 0xb4, 0x7f, 0xd8, 0xb2, 0x6b, 0x58, 0xba, 0x34, 0xba, 0x78, - 0xa0, 0xee, 0xa2, 0xc4, 0x73, 0x19, 0xc7, 0xdf, 0x1b, 0x46, 0x3c, 0xe0, - 0x7c, 0xb3, 0xf9, 0x7c, 0x35, 0xd5, 0xf0, 0xbf, 0x2c, 0xed, 0xa4, 0x20, - 0x95, 0x0b, 0x05, 0x7a, 0xce, 0xdc, 0x81, 0x95, 0xf3, 0x12, 0x8a, 0x7f, - 0xcb, 0xa8, 0xdc, 0x77, 0xbf, 0x8b, 0xdf, 0xf6, 0xb0, 0xce, 0xce, 0x0b, - 0xdf, 0xe9, 0xcf, 0x92, 0x02, 0x20, 0x82, 0x81, 0x9c, 0x03, 0x72, 0xe8, - 0x41, 0x6b, 0xbe, 0xb6, 0x87, 0x8b, 0xf9, 0x9e, 0x49, 0x77, 0xc5, 0xcf, - 0x73, 0x9d, 0xf6, 0x1c, 0x42, 0x7c, 0xa8, 0xbb, 0xe3, 0x24, 0x70, 0x9f, - 0xef, 0x28, 0xce, 0x45, 0x13, 0x13, 0x5f, 0xad, 0x02, 0x2a, 0xb4, 0x14, - 0x80, 0x66, 0xe1, 0x6b, 0x29, 0x72, 0x77, 0xa3, 0x04, 0x36, 0x28, 0x8d, - 0xc6, 0x39, 0xa3, 0x29, 0x59, 0xbf, 0x1e, 0x69, 0xcc, 0x8f, 0x25, 0x28, - 0xb8, 0x24, 0x7c, 0xea, 0xe9, 0x4c, 0x43, 0x6e, 0x6c, 0x7b, 0x1d, 0x41, - 0x7f, 0xd9, 0xd9, 0x59, 0x1e, 0x45, 0x76, 0xcc, 0x26, 0x6e, 0xe1, 0x80, - 0x73, 0x4d, 0x79, 0x3c, 0x5c, 0x1d, 0x78, 0xf3, 0xf9, 0x75, 0x2c, 0x9d, - 0x9d, 0x8e, 0x90, 0x23, 0xf3, 0xf9, 0xd7, 0x68, 0x14, 0xf3, 0x09, 0x2f, - 0xa1, 0x86, 0xb1, 0x9d, 0xe2, 0x3c, 0xd3, 0x16, 0xc4, 0xdf, 0x7c, 0xcf, - 0xc5, 0xf2, 0x3e, 0x67, 0x8b, 0xc8, 0x3e, 0x23, 0x17, 0xbf, 0x75, 0x1e, - 0xf3, 0x35, 0xee, 0x9f, 0x14, 0xae, 0xc1, 0x5b, 0xe7, 0x92, 0x68, 0xb8, - 0x0f, 0x95, 0x67, 0x1b, 0x55, 0xe7, 0x90, 0x6f, 0x72, 0xa0, 0x78, 0xd2, - 0x57, 0xca, 0x0a, 0x92, 0x62, 0x8d, 0x20, 0x52, 0x84, 0xb3, 0xae, 0x8e, - 0x22, 0x3d, 0x36, 0x3a, 0xfe, 0x68, 0x2d, 0x89, 0x8f, 0x51, 0x5b, 0x87, - 0x87, 0x21, 0x69, 0x1a, 0x90, 0x97, 0x9e, 0x2f, 0x91, 0xae, 0x32, 0x17, - 0x08, 0x0b, 0x3e, 0x65, 0x8a, 0xaa, 0x8e, 0xf3, 0x7b, 0x43, 0xc4, 0x2d, - 0x05, 0xac, 0x7a, 0xd9, 0x29, 0x41, 0xf8, 0x80, 0x64, 0x99, 0x98, 0xc3, - 0xb8, 0x4b, 0x4a, 0x4b, 0x48, 0x2a, 0xbd, 0x38, 0x42, 0x3a, 0xf1, 0x67, - 0x03, 0x1d, 0xd8, 0x00, 0x50, 0xc9, 0xce, 0x3a, 0x34, 0xe5, 0xac, 0x5f, - 0x36, 0x55, 0xf4, 0xf2, 0xa6, 0x09, 0x04, 0x20, 0x64, 0x56, 0xa1, 0x15, - 0x65, 0x4d, 0x07, 0x7e, 0x47, 0xf7, 0x34, 0x30, 0x3a, 0xbe, 0x49, 0xc1, - 0x75, 0xa3, 0x7d, 0xe5, 0x0e, 0xba, 0xdf, 0x81, 0xc0, 0x94, 0xf8, 0xec, - 0x1d, 0x81, 0x63, 0x48, 0x12, 0x16, 0x82, 0x12, 0x8b, 0x2a, 0xf7, 0x6e, - 0x23, 0xa4, 0x11, 0x8b, 0x70, 0xb3, 0x8a, 0xce, 0xd0, 0xdf, 0xc4, 0x6f, - 0x65, 0x01, 0xe4, 0x6e, 0x61, 0x58, 0x78, 0x2a, 0x4b, 0x9a, 0x1b, 0x65, - 0x94, 0xc4, 0xc5, 0x9d, 0x95, 0xc6, 0x12, 0x6f, 0xfc, 0x8a, 0x5e, 0x7f, - 0xc8, 0xbe, 0xa9, 0xf0, 0x65, 0xb9, 0xa7, 0xe5, 0xa9, 0x39, 0xc3, 0x7a, - 0x79, 0x05, 0x72, 0x77, 0x1f, 0xf7, 0x2b, 0x29, 0xf5, 0xb9, 0xce, 0x20, - 0x82, 0x01, 0x21, 0xa0, 0x0c, 0xd5, 0x7c, 0x7b, 0xe5, 0x9a, 0xea, 0xdb, - 0x71, 0xa6, 0xef, 0x57, 0xca, 0x0d, 0x55, 0x3e, 0x3c, 0x9e, 0xac, 0x6c, - 0x18, 0x4e, 0xe9, 0xc4, 0x67, 0x00, 0x1d, 0xc3, 0xf6, 0x88, 0x9d, 0xd5, - 0xb4, 0x1a, 0xa8, 0xde, 0xfa, 0x8c, 0xe8, 0xb5, 0x8a, 0xec, 0x6c, 0x94, - 0x62, 0x63, 0x00, 0xaf, 0x8a, 0x91, 0x4b, 0x1b, 0x01, 0x90, 0x72, 0xa5, - 0x0a, 0x03, 0x50, 0xc7, 0x0d, 0x66, 0xaf, 0xca, 0xae, 0xe5, 0x7f, 0x00, - 0x00, 0x01, 0x0a + 0x00, 0x00, 0x01, 0x67, 0x4d, 0x40, 0x0d, 0xab, 0x40, 0xa0, 0xfd, 0x80, + 0x88, 0x00, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0xc4, 0x78, + 0xa1, 0x55, 0x00, 0x00, 0x01, 0x68, 0xee, 0x32, 0xc8, 0x00, 0x00, 0x01, + 0x65, 0x88, 0x82, 0x00, 0x45, 0xbb, 0x9d, 0x38, 0x9b, 0xe8, 0x48, 0xef, + 0xed, 0xa7, 0xd7, 0x9c, 0x19, 0x9b, 0x5a, 0xca, 0x00, 0x0d, 0x54, 0x0c, + 0xe3, 0xd5, 0xad, 0xa9, 0x5d, 0x71, 0x24, 0x83, 0xbb, 0x36, 0x4d, 0xb1, + 0xf5, 0x0f, 0xc6, 0x66, 0xb6, 0x6d, 0x1d, 0xa5, 0x45, 0xfc, 0xa0, 0x4c, + 0xbf, 0xfb, 0x2f, 0x5c, 0x1a, 0x5a, 0x3b, 0x29, 0xe0, 0x35, 0x95, 0x44, + 0x8e, 0x2f, 0x22, 0xd3, 0x3a, 0x48, 0x88, 0x7d, 0x32, 0x97, 0xff, 0xd8, + 0x54, 0x7f, 0x7f, 0x65, 0x57, 0x71, 0xaf, 0xba, 0x17, 0xe0, 0x12, 0x24, + 0xc9, 0x5b, 0xaa, 0xc7, 0xd5, 0x27, 0xc9, 0x64, 0x5d, 0x5e, 0xa0, 0xea, + 0x57, 0xd2, 0x7d, 0x55, 0x6c, 0xf2, 0x44, 0x2f, 0x4b, 0x5d, 0xbd, 0x62, + 0xb9, 0xc2, 0xfa, 0x1e, 0x8f, 0xbc, 0x57, 0x5f, 0xc1, 0x2d, 0xb3, 0x9a, + 0x0e, 0x58, 0x75, 0xf7, 0x08, 0xdf, 0x2d, 0xda, 0xc1, 0xa5, 0x55, 0x76, + 0x06, 0xaf, 0x92, 0x28, 0x43, 0xc5, 0x20, 0x16, 0x96, 0xf5, 0x79, 0x1e, + 0x88, 0x77, 0xb3, 0x4e, 0xb8, 0x4f, 0x3e, 0x51, 0x3c, 0xcf, 0xc0, 0x28, + 0xda, 0xb8, 0xa3, 0x1d, 0xed, 0x8e, 0x04, 0x74, 0x82, 0xc1, 0x5d, 0xa8, + 0x3c, 0x25, 0xd2, 0x84, 0x0b, 0x34, 0x40, 0x8b, 0x7f, 0xee, 0xae, 0xf8, + 0xde, 0x6e, 0x28, 0xf6, 0xfc, 0xfc, 0x14, 0x7e, 0x95, 0xd9, 0xd8, 0x2c, + 0x09, 0x49, 0x27, 0x64, 0x13, 0x83, 0x5c, 0x6f, 0xd4, 0x09, 0x48, 0xa8, + 0xd4, 0x1b, 0x6e, 0x4d, 0x05, 0x0a, 0xbe, 0x27, 0xff, 0xf4, 0x27, 0x04, + 0x41, 0xa0, 0x23, 0x61, 0xe6, 0x26, 0x32, 0xf4, 0xa3, 0xca, 0x97, 0xfc, + 0xeb, 0x6b, 0x45, 0x35, 0x13, 0x69, 0xd9, 0x41, 0x0f, 0xa6, 0xc0, 0xbe, + 0xd5, 0xfa, 0x28, 0xa6, 0x4f, 0x62, 0x3e, 0x1f, 0xcb, 0x98, 0x0a, 0x70, + 0x09, 0xc1, 0xe3, 0x69, 0x30, 0x20, 0xe7, 0xd5, 0x1c, 0xf0, 0x7e, 0x52, + 0x1d, 0x6a, 0xdd, 0x14, 0x58, 0x5e, 0x7a, 0x35, 0x57, 0xa1, 0xe6, 0x83, + 0x46, 0x57, 0x6e, 0x57, 0x7f, 0x72, 0x5d, 0x0c, 0x0c, 0xf4, 0x40, 0x11, + 0x8c, 0xbb, 0xdf, 0xd1, 0x54, 0xfb, 0x7d, 0xf7, 0x03, 0xb9, 0x4e, 0xa3, + 0x76, 0x4c, 0xce, 0xfb, 0x9e, 0x39, 0x02, 0xf0, 0x48, 0xb5, 0x8c, 0x36, + 0x6e, 0x93, 0x79, 0x48, 0xcc, 0x28, 0xec, 0xd7, 0xb8, 0x02, 0xe5, 0xa3, + 0x37, 0x01, 0xe1, 0x3c, 0x40, 0x8f, 0x68, 0x27, 0xbc, 0xec, 0x6b, 0x59, + 0xb9, 0xfe, 0xb8, 0x67, 0x68, 0x83, 0x99, 0x97, 0x1e, 0xcc, 0x4e, 0x23, + 0x82, 0x26, 0x93, 0x7b, 0x7a, 0x9e, 0xdc, 0x42, 0xca, 0x1b, 0x3e, 0x13, + 0x19, 0x45, 0x03, 0x40, 0xab, 0xd2, 0xda, 0x6b, 0x6c, 0x26, 0xdb, 0xe3, + 0x72, 0x06, 0x89, 0xea, 0x03, 0x95, 0xe3, 0x14, 0xe1, 0x4a, 0x16, 0x58, + 0x2d, 0x67, 0xaa, 0xbf, 0xbe, 0x37, 0x54, 0x19, 0xb1, 0x57, 0x61, 0x85, + 0x82, 0x5f, 0x63, 0x33, 0xe2, 0xf8, 0x7f, 0x4f, 0x21, 0x44, 0x8a, 0x0e, + 0x21, 0x2b, 0x12, 0x99, 0x4d, 0xd9, 0x2e, 0xea, 0x36, 0x2d, 0x45, 0xcb, + 0xe2, 0xfe, 0xdd, 0x03, 0x3b, 0x08, 0x58, 0x60, 0x1e, 0xb2, 0xfa, 0x3b, + 0x89, 0xa5, 0x03, 0xde, 0xab, 0x71, 0x32, 0x48, 0x46, 0x2c, 0xfb, 0x2b, + 0x84, 0x83, 0xc9, 0xff, 0xf6, 0xf5, 0x2f, 0xe7, 0x2f, 0x6a, 0x5d, 0x86, + 0xe2, 0x48, 0x23, 0x6d, 0x84, 0x60, 0x9b, 0xc0, 0x25, 0x1e, 0xff, 0x94, + 0xe8, 0xf4, 0xd0, 0x4e, 0x11, 0x60, 0xda, 0x20, 0xa8, 0xfd, 0xf3, 0x00, + 0x4f, 0x0e, 0x4f, 0xa2, 0xeb, 0xe1, 0xa8, 0xb3, 0x47, 0x35, 0x62, 0x83, + 0x6f, 0x08, 0x6b, 0xb8, 0x82, 0x04, 0xcc, 0x63, 0x69, 0xd7, 0xba, 0x10, + 0xd4, 0x51, 0xe6, 0xb5, 0x34, 0xe8, 0x7d, 0xaf, 0x87, 0xcf, 0x1d, 0xeb, + 0x46, 0xc1, 0xcd, 0xcb, 0xf2, 0x3b, 0x3e, 0xa0, 0x61, 0xc7, 0x68, 0x86, + 0x0b, 0x9f, 0x0b, 0x59, 0xc0, 0x79, 0x4e, 0xcc, 0x79, 0x91, 0xa0, 0xe8, + 0x80, 0x6c, 0xbd, 0x35, 0x12, 0x71, 0x2f, 0x5e, 0xa4, 0xfc, 0xe6, 0x51, + 0xe0, 0xbe, 0x41, 0x1a, 0x19, 0x60, 0xd8, 0xac, 0xcd, 0x93, 0x05, 0x70, + 0xa0, 0xda, 0x53, 0x4e, 0x5a, 0x6d, 0x9b, 0x3f, 0x28, 0x73, 0x87, 0x6f, + 0x6d, 0x41, 0x5a, 0x13, 0xd0, 0xea, 0x19, 0xb3, 0xb7, 0xf1, 0x75, 0x92, + 0xae, 0x43, 0x9d, 0xe3, 0xa7, 0x4d, 0x5a, 0x52, 0x36, 0xce, 0x6b, 0x1e, + 0x2b, 0x2e, 0xab, 0x0c, 0xd7, 0xe4, 0x1c, 0x44, 0x72, 0x9d, 0x86, 0xb6, + 0xeb, 0xe5, 0x80, 0xc4, 0x45, 0x21, 0x8b, 0xe0, 0xe0, 0x9d, 0x09, 0xfa, + 0x0b, 0x59, 0x0c, 0x2c, 0x9d, 0x97, 0x15, 0x56, 0xd0, 0x21, 0xd8, 0x90, + 0xb4, 0x89, 0xc4, 0x96, 0x76, 0xf1, 0x64, 0xa5, 0x85, 0x2a, 0x13, 0xfb, + 0xfa, 0x11, 0x1e, 0x2d, 0x63, 0xc2, 0x9a, 0x87, 0x99, 0x2c, 0x18, 0xb8, + 0xeb, 0x6a, 0x5c, 0x68, 0x26, 0x63, 0xcc, 0x1b, 0x1a, 0x5c, 0x7f, 0x0d, + 0x45, 0xcc, 0x56, 0x46, 0x92, 0xbb, 0x76, 0xf2, 0x2e, 0x52, 0x05, 0x3c, + 0xe3, 0xbb, 0x59, 0x9b, 0x89, 0x03, 0x0d, 0x48, 0xb1, 0xdc, 0x78, 0x04, + 0x03, 0x24, 0xf4, 0x62, 0xcf, 0xb1, 0xc6, 0x64, 0x05, 0xbd, 0x89, 0x94, + 0x1a, 0x8d, 0xc1, 0xbe, 0xac, 0xe0, 0xed, 0x89, 0xf3, 0x47, 0x81, 0x82, + 0xb9, 0x64, 0xcc, 0x8e, 0xc4, 0x1e, 0xa9, 0xf6, 0xde, 0x8d, 0xb7, 0x33, + 0xba, 0x5b, 0x49, 0x0d, 0x0a, 0x16, 0x96, 0x7d, 0x89, 0x82, 0xe0, 0x5a, + 0x08, 0x55, 0xbd, 0xce, 0xca, 0xc0, 0x46, 0x1a, 0x6b, 0xf9, 0x7d, 0x03, + 0xe8, 0x35, 0x69, 0x7d, 0x87, 0xc9, 0x71, 0x01, 0x7e, 0xa8, 0x3a, 0x9c, + 0xd5, 0xe2, 0x71, 0xa6, 0xc7, 0xe2, 0x2d, 0xf3, 0x6f, 0x74, 0x0f, 0x3e, + 0x03, 0x70, 0x5e, 0xec, 0x8c, 0x66, 0xf9, 0x71, 0x9a, 0xd2, 0x56, 0x57, + 0x37, 0xcd, 0x50, 0x55, 0x97, 0xea, 0x67, 0x20, 0x59, 0x06, 0x4d, 0x22, + 0xa0, 0x85, 0x90, 0xb3, 0x59, 0x15, 0x75, 0x0d, 0x70, 0xbd, 0xb5, 0x7d, + 0x72, 0xaa, 0xea, 0xfc, 0x9d, 0x08, 0x8d, 0xdf, 0x31, 0x21, 0x2d, 0xef, + 0x00, 0x24, 0x6c, 0xae, 0x82, 0x6e, 0x1a, 0x4b, 0x28, 0xa5, 0x6d, 0x98, + 0xeb, 0x50, 0x87, 0x6f, 0x1b, 0xa5, 0xba, 0x1c, 0xda, 0x59, 0xb8, 0x4c, + 0x17, 0xe3, 0xd5, 0x10, 0x46, 0x94, 0x91, 0xed, 0x0b, 0xd3, 0xfc, 0x06, + 0x81, 0x60, 0x88, 0x5f, 0x58, 0x81, 0x26, 0x54, 0xdc, 0xd5, 0x7c, 0xbe, + 0x30, 0x04, 0x17, 0x84, 0x76, 0xe8, 0xb6, 0x8a, 0xec, 0x84, 0x02, 0xcf, + 0xc7, 0xda, 0x2d, 0x2e, 0x31, 0xc2, 0x77, 0x31, 0x54, 0x32, 0xbd, 0x77, + 0xa2, 0xa5, 0x5d, 0xec, 0x1c, 0x27, 0xf6, 0xec, 0xc8, 0x3f, 0xeb, 0x1a, + 0x24, 0xcb, 0x74, 0xd0, 0xb3, 0x52, 0xa8, 0x8f, 0x4c, 0x26, 0xbf, 0x68, + 0xb2, 0x87, 0xf3, 0xa8, 0xa9, 0x4f, 0x71, 0x57, 0xc7, 0xa8, 0x34, 0x5a, + 0x01, 0x68, 0xae, 0x5c, 0xb3, 0xd8, 0x23, 0x6b, 0xea, 0x18, 0xdf, 0xa9, + 0xe5, 0xc4, 0x11, 0x49, 0x2b, 0xfa, 0xa8, 0xf3, 0x8f, 0x80, 0x47, 0xa0, + 0x19, 0xc7, 0x20, 0xef, 0xbf, 0xed, 0xe1, 0x38, 0x8b, 0x16, 0x54, 0x36, + 0x60, 0x8b, 0x04, 0x26, 0x9c, 0x6b, 0x1a, 0x95, 0x4c, 0x94, 0x6a, 0x53, + 0xcf, 0xb4, 0x4b, 0x38, 0x3a, 0x15, 0x26, 0x94, 0x10, 0x1c, 0x35, 0xe4, + 0x57, 0x80, 0x19, 0xad, 0x1f, 0x82, 0xe8, 0x47, 0xe4, 0x90, 0xa2, 0x42, + 0x30, 0x43, 0x15, 0x92, 0x2b, 0x39, 0xfb, 0x7b, 0xb3, 0xdb, 0xc7, 0x5b, + 0x79, 0x5e, 0x91, 0xba, 0x38, 0x74, 0xd6, 0x00, 0x26, 0xa5, 0x8f, 0xa4, + 0x31, 0xe6, 0x7b, 0xeb, 0x52, 0xc2, 0xe2, 0xa1, 0x6b, 0x5f, 0x17, 0xf1, + 0x15, 0xc9, 0x4b, 0x44, 0x93, 0x77, 0x28, 0xdf, 0x2a, 0xc0, 0xb5, 0x97, + 0xfc, 0xbe, 0x2e, 0x72, 0x53, 0x58, 0xf9, 0x33, 0x3a, 0xb0, 0x6e, 0xaf, + 0x0c, 0x1b, 0xcf, 0x71, 0x37, 0x6b, 0x4a, 0x9a, 0x66, 0x16, 0x90, 0x43, + 0x9b, 0x70, 0x0d, 0x8f, 0xd3, 0x04, 0x4b, 0x14, 0xf2, 0x58, 0x9f, 0x64, + 0x33, 0x21, 0xdc, 0x02, 0x8a, 0x5b, 0xd6, 0x80, 0x9c, 0x22, 0xc8, 0x39, + 0x7d, 0x2d, 0x7c, 0x09, 0x4e, 0x6a, 0x8c, 0x8d, 0x0c, 0xc4, 0xfe, 0x6f, + 0x8c, 0x50, 0xf2, 0x75, 0xc0, 0x12, 0x6f, 0xd3, 0x9d, 0x07, 0xc0, 0xe9, + 0xdf, 0x36, 0xa2, 0x6f, 0xca, 0x14, 0x5b, 0x0f, 0x5a, 0xd8, 0x35, 0x72, + 0x07, 0x08, 0x80, 0xba, 0x2f, 0x61, 0x7f, 0xb0, 0x5e, 0xbb, 0xb1, 0x47, + 0x6a, 0xbd, 0x6a, 0xe4, 0xb6, 0xa2, 0xec, 0x2e, 0x27, 0x43, 0xbc, 0xd7, + 0x2c, 0x2c, 0xf3, 0x6c, 0x12, 0x4c, 0x86, 0x5a, 0x38, 0xa4, 0x87, 0xa8, + 0xe1, 0x70, 0x17, 0x15, 0xd0, 0x2b, 0x87, 0xdb, 0x87, 0xc0, 0x85, 0x57, + 0x30, 0x31, 0x16, 0x07, 0x9b, 0x72, 0x07, 0xf5, 0x18, 0x6d, 0xd1, 0x8d, + 0x31, 0xa1, 0x25, 0x6a, 0xb4, 0xf3, 0x07, 0x5f, 0x0c, 0x99, 0x33, 0x68, + 0xbf, 0x2c, 0xa1, 0xfd, 0xde, 0x16, 0x2d, 0x4a, 0x5a, 0xa0, 0x7e, 0xe5, + 0x9b, 0x89, 0x4a, 0x8d, 0xe7, 0x18, 0x21, 0x32, 0x47, 0x3c, 0x9d, 0x48, + 0xab, 0x7d, 0xca, 0xb4, 0x63, 0xd9, 0xfd, 0x29, 0x2d, 0x4c, 0xf1, 0xf2, + 0x20, 0x0a, 0x91, 0x2e, 0x2c, 0xa1, 0x49, 0x83, 0x73, 0x15, 0xa0, 0x7d, + 0x6e, 0xae, 0x51, 0x45, 0x0d, 0x09, 0x1f, 0x8f, 0x61, 0x42, 0xbd, 0x24, + 0xcd, 0x3e, 0xe8, 0x66, 0x84, 0xc6, 0x97, 0x08, 0x7b, 0x72, 0x73, 0x7e, + 0xe7, 0x99, 0x05, 0xab, 0x63, 0xff, 0x3c, 0x44, 0xa1, 0xc0, 0x1b, 0xfc, + 0xff, 0x27, 0xe9, 0x45, 0x82, 0x75, 0x82, 0x6f, 0x9c, 0x65, 0xef, 0x67, + 0xd6, 0x00, 0xd1, 0x9f, 0x61, 0x9f, 0x38, 0xdd, 0x7f, 0x5f, 0x4d, 0x67, + 0x5b, 0x5d, 0xff, 0x98, 0x6b, 0x13, 0xe0, 0xe7, 0x69, 0xcb, 0x7f, 0x7c, + 0x11, 0x91, 0xe0, 0x05, 0xb9, 0x64, 0xd0, 0xb7, 0x91, 0xe5, 0xd4, 0x3a, + 0x47, 0x05, 0x25, 0x4f, 0x15, 0x46, 0xaf, 0x41, 0x9e, 0xc7, 0x49, 0x15, + 0x17, 0xd1, 0x9c, 0x28, 0xef, 0x80, 0xa3, 0x8b, 0x60, 0xcc, 0x60, 0xeb, + 0x96, 0x36, 0x3a, 0x23, 0x94, 0xf3, 0x6c, 0xe5, 0x3f, 0xe8, 0x8b, 0x5c, + 0x8c, 0xfe, 0x6f, 0x91, 0x65, 0x19, 0xa1, 0x4d, 0x45, 0x7b, 0x06, 0x0f, + 0x71, 0xb7, 0x9a, 0x8d, 0x8e, 0x82, 0x7b, 0x68, 0x44, 0xa4, 0xa6, 0xc3, + 0xe5, 0x67, 0x9f, 0x6c, 0xd0, 0xe4, 0xe8, 0x37, 0x08, 0x6b, 0xbb, 0xa0, + 0x3a, 0xd0, 0xa9, 0xd9, 0x04, 0xaa, 0x91, 0xac, 0x71, 0xff, 0xec, 0x7e, + 0xaf, 0xa9, 0x99, 0xa2, 0x8d, 0x91, 0x95, 0xb3, 0xd8, 0xe4, 0xf3, 0x3f, + 0xa6, 0x4b, 0x0c, 0x19, 0x23, 0xf7, 0xa7, 0xcd, 0x4c, 0x41, 0x28, 0x63, + 0x9f, 0x0b, 0x8f, 0x70, 0x70, 0xbd, 0x25, 0x16, 0x8e, 0x86, 0x8a, 0x69, + 0xe3, 0x6a, 0xd4, 0x98, 0x42, 0x56, 0x15, 0x2d, 0x3d, 0xdb, 0x17, 0x1b, + 0x23, 0x58, 0x82, 0x56, 0x11, 0x97, 0x85, 0xf2, 0x68, 0x95, 0x92, 0xd5, + 0x9e, 0x91, 0x05, 0x70, 0xc8, 0x96, 0xb2, 0x73, 0x6d, 0x1e, 0x12, 0x8c, + 0xa0, 0xe4, 0x1a, 0x84, 0x5b, 0xb4, 0x32, 0xf7, 0x9e, 0x08, 0xd0, 0x6c, + 0x42, 0xf0, 0x0b, 0xc4, 0x1f, 0xe0, 0xbb, 0x71, 0xe1, 0x2d, 0x86, 0xd7, + 0x77, 0x24, 0x43, 0x53, 0x0c, 0x88, 0x21, 0x75, 0x95, 0xd0, 0xfe, 0x10, + 0x23, 0xcd, 0xba, 0x77, 0x3d, 0x9b, 0x0f, 0xb2, 0xe2, 0xcc, 0x0f, 0x94, + 0xe0, 0x66, 0x90, 0x0e, 0xf7, 0x6a, 0x3c, 0x9f, 0xc0, 0xf6, 0x98, 0x1c, + 0x4c, 0x9f, 0x25, 0xc4, 0xeb, 0x1d, 0x91, 0x32, 0x29, 0x34, 0x2a, 0xb0, + 0x7e, 0x1c, 0x09, 0x77, 0x13, 0x83, 0xfa, 0xcf, 0x24, 0xa2, 0x5f, 0x79, + 0x78, 0x64, 0xf7, 0x45, 0x81, 0xbe, 0x6a, 0x82, 0x26, 0xfd, 0xe7, 0xc3, + 0x61, 0x41, 0x27, 0xcc, 0x99, 0x69, 0x77, 0xc8, 0xa7, 0xf3, 0x52, 0x01, + 0xa7, 0x8c, 0x0b, 0x7d, 0x86, 0x8d, 0xbb, 0x31, 0xd6, 0x67, 0xf9, 0xa7, + 0x8f, 0x76, 0xb6, 0x74, 0x26, 0x43, 0x35, 0xb8, 0x83, 0x7c, 0x16, 0x34, + 0x88, 0x0c, 0xb6, 0xec, 0xf0, 0x01, 0x8c, 0x1c, 0xe5, 0x52, 0xd4, 0xca, + 0x01, 0x2e, 0xb5, 0x87, 0xc1, 0xc1, 0x1b, 0xa3, 0x02, 0x17, 0x13, 0xd3, + 0x35, 0xe8, 0x80, 0xe1, 0xd1, 0x01, 0x9c, 0x0a, 0x62, 0x7d, 0x98, 0x7c, + 0x68, 0xa4, 0x8e, 0x3a, 0x50, 0x4b, 0x95, 0x59, 0xa3, 0x11, 0xf6, 0xa3, + 0xde, 0x92, 0x65, 0x00, 0xa0, 0xe8, 0x32, 0xf0, 0xc3, 0x77, 0x68, 0x0b, + 0xed, 0xc1, 0x69, 0xd2, 0x6e, 0xce, 0x80, 0xe4, 0x56, 0x9b, 0x15, 0xbf, + 0x3c, 0x4a, 0x38, 0x26, 0xf6, 0x6a, 0xdb, 0x62, 0x7a, 0xab, 0xb1, 0x77, + 0x75, 0x0d, 0xa7, 0xa4, 0xcf, 0x5e, 0x2d, 0xea, 0x24, 0x84, 0xbd, 0x83, + 0x8e, 0xaa, 0x91, 0xe1, 0x72, 0x5f, 0x7f, 0x26, 0x54, 0x4f, 0xab, 0xa6, + 0x50, 0x22, 0x68, 0x8c, 0xa6, 0x06, 0x67, 0x3c, 0x3e, 0x93, 0x9a, 0xc2, + 0x53, 0x15, 0x08, 0x1a, 0x3c, 0xb3, 0x3f, 0xf0, 0x83, 0xf5, 0x0d, 0x9c, + 0xe3, 0x76, 0x11, 0x45, 0x21, 0x6b, 0x65, 0x97, 0xea, 0x3c, 0xdb, 0x0d, + 0xcd, 0x6e, 0xb7, 0x26, 0x7b, 0x82, 0x63, 0x35, 0x7e, 0x76, 0xf4, 0xb8, + 0x0e, 0xe5, 0x1d, 0x95, 0x94, 0x1c, 0x60, 0xc7, 0xea, 0x9c, 0x1c, 0x73, + 0x75, 0x0e, 0x9b, 0x5f, 0x78, 0x09, 0x4f, 0x90, 0x31, 0x5c, 0xc8, 0x5b, + 0x78, 0xce, 0xb3, 0x3e, 0x31, 0x61, 0x90, 0xba, 0xe0, 0xe1, 0x57, 0x1d, + 0x71, 0x80, 0x92, 0x6b, 0x75, 0xe1, 0x34, 0x95, 0xeb, 0x88, 0xe4, 0x0b, + 0x72, 0xdc, 0x34, 0x24, 0x3b, 0x6d, 0x94, 0xc9, 0xe9, 0x8d, 0x38, 0x72, + 0x9c, 0x61, 0x6e, 0x07, 0xd7, 0x35, 0xa1, 0x74, 0xc2, 0x0c, 0x36, 0xc3, + 0x54, 0xd3, 0xe5, 0xd1, 0x08, 0x8e, 0x24, 0x77, 0xf5, 0x61, 0xcf, 0x69, + 0x9b, 0x27, 0x70, 0xe7, 0x52, 0xf6, 0xef, 0x66, 0x8f, 0x0e, 0x8b, 0xc0, + 0xf3, 0x64, 0x2a, 0xa8, 0xff, 0xcc, 0xd9, 0x61, 0x53, 0xac, 0x36, 0x23, + 0x4f, 0x3c, 0x0f, 0xe0, 0xec, 0xad, 0xc5, 0x35, 0x3f, 0x3b, 0x74, 0x26, + 0x84, 0x48, 0xd1, 0xfe, 0x72, 0x01, 0xea, 0x4d, 0x03, 0x46, 0x66, 0x5a, + 0xc4, 0x0a, 0x55, 0x43, 0x61, 0x36, 0x6a, 0xc1, 0xd2, 0x74, 0x0a, 0x8f, + 0x01, 0xb2, 0xc2, 0xaa, 0xd7, 0x2d, 0x0a, 0x0f, 0x67, 0xa1, 0x25, 0x7d, + 0x45, 0x60, 0x0f, 0x06, 0xfb, 0x8f, 0x8b, 0xe0, 0x4a, 0x8c, 0xd7, 0x19, + 0xac, 0xcc, 0x47, 0xa2, 0x7c, 0x30, 0x90, 0x94, 0x81, 0xab, 0xde, 0x38, + 0xb8, 0xc9, 0xdb, 0x63, 0x9c, 0xcb, 0xdd, 0x71, 0xde, 0x4f, 0x1e, 0x43, + 0x08, 0xe4, 0xe3, 0x83, 0x86, 0x0f, 0x34, 0xb7, 0x1e, 0x53, 0xc1, 0xde, + 0x46, 0xf1, 0x70, 0xf5, 0xd8, 0x47, 0xd2, 0x9b, 0x44, 0x88, 0x85, 0x8e, + 0x32, 0xa9, 0x0c, 0x09, 0x2f, 0xd0, 0xe4, 0x4b, 0x30, 0x3a, 0x2e, 0x65, + 0x0c, 0xff, 0xb4, 0x0d, 0xa8, 0x8f, 0x61, 0x3e, 0x7e, 0x90, 0x66, 0xbb, + 0xf6, 0xbe, 0xfd, 0x7d, 0xe4, 0xdc, 0x2c, 0x59, 0x87, 0x81, 0x60, 0x96, + 0xd7, 0x1d, 0x10, 0x02, 0x35, 0xdd, 0x16, 0x4c, 0xe9, 0x2d, 0x52, 0x45, + 0xdd, 0x3f, 0xc9, 0xff, 0x8d, 0x19, 0xad, 0x02, 0x74, 0xf1, 0x09, 0x99, + 0x94, 0x66, 0x2e, 0x8b, 0xa3, 0xdc, 0x3d, 0xf3, 0xf5, 0x85, 0xf2, 0x60, + 0x7d, 0x9d, 0xe0, 0xd3, 0x0f, 0xa4, 0x92, 0xf3, 0x55, 0xbc, 0x7b, 0x20, + 0x6b, 0xf6, 0xc4, 0xc4, 0x0f, 0x8a, 0xd7, 0x5a, 0x02, 0xb0, 0xb7, 0x78, + 0xb4, 0x9e, 0xb6, 0x93, 0x95, 0x2e, 0x76, 0x06, 0x1e, 0x34, 0x5d, 0x34, + 0x77, 0x77, 0x6d, 0x32, 0xbb, 0x46, 0xad, 0x43, 0xd7, 0x72, 0x61, 0x33, + 0x4f, 0x98, 0xe9, 0x56, 0x3a, 0x96, 0x89, 0x6e, 0x1f, 0xaf, 0x6b, 0xa0, + 0x9a, 0xe4, 0x42, 0x5a, 0xb3, 0xb8, 0x2a, 0xe1, 0x2d, 0xa6, 0x32, 0xa2, + 0x01, 0xf5, 0x3a, 0x9a, 0xbb, 0x06, 0x76, 0x0b, 0xa8, 0xac, 0x02, 0x96, + 0x0c, 0x58, 0xd3, 0x64, 0xc8, 0xe2, 0xae, 0x6c, 0xf7, 0xa7, 0x32, 0x4b, + 0x51, 0x50, 0x11, 0x90, 0xcf, 0x37, 0xed, 0xd2, 0xa0, 0xa4, 0x97, 0xb3, + 0x45, 0x1d, 0x7d, 0xf3, 0xff, 0xde, 0x9f, 0x80, 0xa9, 0x61, 0xac, 0x37, + 0x7f, 0x5d, 0xc9, 0xf6, 0xdc, 0x26, 0xd0, 0x65, 0xf2, 0xdc, 0x0c, 0x1a, + 0xcb, 0xde, 0x6b, 0x77, 0xf3, 0x08, 0xa4, 0x93, 0xab, 0x2a, 0xdf, 0x18, + 0x1a, 0xc7, 0xa6, 0xa1, 0x7e, 0x43, 0x75, 0xca, 0x88, 0xcc, 0x6f, 0xa2, + 0x85, 0x0e, 0xb0, 0xd5, 0xcd, 0x8a, 0xff, 0xc1, 0x57, 0x20, 0x66, 0xf7, + 0x19, 0x7a, 0x52, 0x5b, 0x46, 0x87, 0x5f, 0xf7, 0x77, 0xe2, 0xab, 0x4e, + 0x4a, 0xce, 0x8f, 0x3f, 0xe6, 0x9f, 0x88, 0x3a, 0x33, 0x65, 0x3c, 0x3a, + 0x41, 0xc3, 0x8e, 0xee, 0x79, 0xe7, 0x2c, 0xb0, 0x3b, 0x93, 0x82, 0xa0, + 0x1a, 0x71, 0x0e, 0xf6, 0x31, 0xc5, 0x6f, 0xc1, 0xa8, 0x32, 0x89, 0x3b, + 0x33, 0x68, 0x53, 0x81, 0x15, 0x70, 0x5e, 0x22, 0xdc, 0x99, 0xc6, 0x88, + 0xf8, 0x11, 0x06, 0x56, 0x1f, 0x80, 0x7e, 0x0b, 0x27, 0x90, 0xfc, 0x97, + 0x76, 0x61, 0xdc, 0x30, 0x5d, 0x34, 0x4e, 0x83, 0x85, 0xce, 0xe2, 0x91, + 0x4d, 0x8d, 0x92, 0x88, 0x26, 0xa0, 0xde, 0x47, 0x82, 0xd2, 0xa8, 0xa5, + 0xe7, 0x27, 0x0c, 0x45, 0x41, 0x85, 0xa1, 0x12, 0xcb, 0x3a, 0x74, 0x53, + 0x93, 0x77, 0xd0, 0x8b, 0x42, 0x8d, 0x00, 0xca, 0x44, 0x67, 0xa0, 0x6a, + 0xbd, 0xcd, 0x4a, 0x3c, 0xfe, 0x6c, 0xa1, 0x48, 0x26, 0x0d, 0x51, 0x54, + 0x59, 0xc9, 0xf9, 0x51, 0x5c, 0xd3, 0x55, 0xf0, 0x72, 0x77, 0xdb, 0x52, + 0xee, 0x0a, 0x5e, 0x8a, 0xf0, 0xbe, 0x9a, 0x37, 0xa0, 0x1b, 0x94, 0xe3, + 0x2d, 0x17, 0xc4, 0xbe, 0x9c, 0xad, 0x9c, 0xd1, 0xc6, 0xbc, 0x36, 0x5c, + 0x3b, 0xe3, 0x2e, 0x66, 0x29, 0x0c, 0x3a, 0x3d, 0xe7, 0xe3, 0xf3, 0x58, + 0x70, 0x3e, 0x59, 0xb2, 0x6c, 0x91, 0x14, 0xfe, 0x9e, 0x5e, 0x5d, 0xb2, + 0x7b, 0x46, 0x66, 0x46, 0x55, 0xe2, 0x78, 0x47, 0xeb, 0xdf, 0x2b, 0xb4, + 0xf2, 0xb2, 0x14, 0xbe, 0x64, 0x9e, 0x17, 0x16, 0x9f, 0xf5, 0x6a, 0xdd, + 0x25, 0xa1, 0x55, 0x6e, 0xb1, 0xfa, 0x09, 0xd0, 0x97, 0x7c, 0x13, 0xde, + 0x1d, 0xd4, 0x94, 0x19, 0xde, 0x8b, 0x4d, 0xe7, 0xee, 0x1f, 0xdf, 0xe5, + 0x3b, 0xdd, 0xbd, 0x13, 0x9c, 0xec, 0xcd, 0xb6, 0xb6, 0xbb, 0x3f, 0xbd, + 0x54, 0xca, 0x47, 0x5c, 0x05, 0x3c, 0x03, 0x30, 0x9d, 0x56, 0xf6, 0xc6, + 0x48, 0x6b, 0x74, 0x49, 0x58, 0xa2, 0xd8, 0x45, 0x42, 0x6f, 0xe4, 0x46, + 0x27, 0x92, 0x83, 0x78, 0x97, 0x55, 0x5b, 0x82, 0xce, 0x2a, 0x08, 0x41, + 0xb9, 0x7a, 0x66, 0x0f, 0x3c, 0x5b, 0xdf, 0x8d, 0x1d, 0x02, 0x11, 0xa4, + 0xa7, 0x0a, 0x80, 0x1e, 0xbb, 0x7a, 0xc9, 0x2f, 0xb9, 0x35, 0xc8, 0xd7, + 0x98, 0x04, 0x29, 0xaa, 0x4b, 0x88, 0x66, 0x73, 0xe4, 0x59, 0xc4, 0x3e, + 0x50, 0xad, 0xe5, 0x64, 0x54, 0xf0, 0x29, 0x38, 0xee, 0xc0, 0x00, 0xc4, + 0x22, 0x16, 0xf2, 0xc5, 0x46, 0x5c, 0xee, 0x9e, 0xf2, 0x9a, 0xe7, 0xfd, + 0x62, 0x50, 0xa2, 0xeb, 0x47, 0x56, 0x4c, 0xe4, 0x75, 0x46, 0xe4, 0xd5, + 0x25, 0xec, 0xe0, 0x35, 0x33, 0x31, 0x34, 0x1b, 0xcb, 0x72, 0x78, 0x1c, + 0x4d, 0x3a, 0x19, 0x2e, 0xc4, 0xb7, 0xa4, 0x80, 0xd2, 0x91, 0xeb, 0x2a, + 0x1d, 0xf2, 0xd1, 0xa3, 0xae, 0xac, 0x41, 0xae, 0xc2, 0x44, 0xd2, 0x3f, + 0xb4, 0x87, 0x8d, 0x69, 0x6c, 0x67, 0xd6, 0x85, 0xee, 0xd6, 0x3b, 0x03, + 0xdc, 0x58, 0x46, 0x07, 0x73, 0xb4, 0xb0, 0x3f, 0x5e, 0xc1, 0x13, 0x2c, + 0x36, 0x58, 0xd0, 0x1c, 0x34, 0x3e, 0x01, 0x88, 0xfa, 0xb1, 0x9a, 0x03, + 0x85, 0x4f, 0x4c, 0xd2, 0xac, 0xd9, 0x12, 0x09, 0xaa, 0x5f, 0x20, 0x06, + 0x1f, 0x0a, 0x44, 0x28, 0x50, 0xd1, 0x8f, 0x51, 0x8a, 0x1d, 0xfa, 0xaa, + 0x46, 0x33, 0xac, 0x0c, 0xb3, 0x10, 0xcf, 0x24, 0x4d, 0x0f, 0xcd, 0xee, + 0xd9, 0x64, 0x4a, 0x1a, 0x84, 0x0f, 0xff, 0x48, 0x8d, 0x79, 0xd4, 0x43, + 0x70, 0x1c, 0x7e, 0x7e, 0x12, 0x43, 0x51, 0x4a, 0x7e, 0x45, 0x9e, 0xa4, + 0x3c, 0x12, 0xbd, 0x95, 0xe9, 0xd6, 0xd4, 0x3f, 0xbf, 0x03, 0xae, 0x9e, + 0x24, 0x1a, 0x36, 0xbd, 0xea, 0x5d, 0x65, 0xff, 0x9f, 0x95, 0x70, 0xda, + 0xb0, 0x53, 0x6a, 0x5f, 0x64, 0x7b, 0xb6, 0x7a, 0x8d, 0xa2, 0xd4, 0x9c, + 0xb1, 0xf9, 0xe6, 0x14, 0x62, 0x3b, 0xe7, 0x5b, 0x40, 0x9d, 0xf4, 0x19, + 0xb5, 0x50, 0xc8, 0xbd, 0x76, 0xd3, 0xbc, 0x0e, 0x6d, 0x62, 0x91, 0x73, + 0x3e, 0x7f, 0xbf, 0xd0, 0xf0, 0x33, 0xf8, 0x6a, 0x9f, 0xa6, 0xad, 0xc3, + 0xa0, 0x8f, 0x45, 0x99, 0x86, 0xa7, 0x49, 0x18, 0x8a, 0xed, 0xf1, 0x7d, + 0x39, 0xf4, 0xb4, 0xf9, 0x82, 0x62, 0xd0, 0xa1, 0xb8, 0x3f, 0xe8, 0x25, + 0xf7, 0xb1, 0x59, 0xce, 0x31, 0xba, 0x1d, 0x0b, 0x1f, 0x3d, 0x6c, 0x8b, + 0xd2, 0xc5, 0x4e, 0x8e, 0xe8, 0x09, 0x9e, 0x1f, 0xf3, 0x67, 0x6f, 0x09, + 0x03, 0x9d, 0xfe, 0x57, 0x6d, 0x9b, 0xce, 0x99, 0x7b, 0x01, 0x04, 0x52, + 0xf5, 0x41, 0x7e, 0x38, 0x56, 0xb8, 0x71, 0x44, 0x43, 0x2c, 0x5e, 0x92, + 0x9d, 0x95, 0xff, 0x0b, 0xf8, 0xfa, 0x89, 0x2c, 0x58, 0xde, 0xc5, 0x4e, + 0x02, 0xe3, 0x82, 0xf7, 0xdc, 0x92, 0xa8, 0x7c, 0x39, 0x32, 0x76, 0x68, + 0x9c, 0x73, 0x75, 0x1f, 0xbc, 0x6b, 0x46, 0x33, 0x5a, 0xdb, 0x94, 0x8c, + 0x76, 0x79, 0x7e, 0x9b, 0xcc, 0x37, 0xeb, 0xed, 0xdc, 0xd5, 0xee, 0x2b, + 0x30, 0x3f, 0x7b, 0x9b, 0xac, 0x38, 0x8f, 0xf1, 0x5e, 0xec, 0xa0, 0x46, + 0x2c, 0xd1, 0x27, 0x19, 0x60, 0xec, 0xe2, 0xa7, 0x45, 0x61, 0x2d, 0xa8, + 0x7e, 0xa9, 0xf8, 0x93, 0xa4, 0x23, 0x3e, 0xd8, 0x9c, 0xcc, 0xb3, 0xee, + 0xc3, 0x1c, 0xfb, 0xbb, 0xad, 0xec, 0x73, 0x66, 0x31, 0x5d, 0x88, 0x9a, + 0xec, 0x84, 0x91, 0x1e, 0x58, 0xdd, 0xb0, 0x01, 0x46, 0x18, 0x43, 0x64, + 0xe2, 0xad, 0xac, 0x5a, 0x63, 0x4c, 0x32, 0x6b, 0xfd, 0xff, 0x66, 0x6d, + 0xb4, 0x66, 0x88, 0xec, 0xfe, 0x23, 0xaa, 0x3a, 0x2a, 0xd5, 0xff, 0xed, + 0x3a, 0x13, 0x9a, 0xae, 0x73, 0xc5, 0x62, 0x32, 0x47, 0x89, 0x19, 0x7f, + 0x2c, 0x88, 0x62, 0x34, 0xc2, 0x90, 0xa9, 0x59, 0x7c, 0x45, 0xdb, 0x98, + 0xaf, 0xf4, 0xba, 0x4e, 0x45, 0x55, 0xfc, 0x70, 0xa9, 0xfd, 0xb4, 0xa3, + 0xd9, 0xa8, 0xfb, 0xe2, 0xe6, 0xf9, 0x60, 0xc1, 0x42, 0x70, 0x3d, 0xa5, + 0x28, 0xcc, 0xd3, 0x54, 0x87, 0xda, 0x93, 0x91, 0x42, 0xa8, 0x8b, 0x62, + 0xf3, 0x4e, 0xb7, 0x86, 0xfa, 0x52, 0x19, 0x69, 0xe3, 0x6c, 0xd1, 0xc3, + 0x23, 0x82, 0xf7, 0x1d, 0xa1, 0x80, 0x92, 0xcd, 0x5e, 0x1a, 0x62, 0x3e, + 0x1b, 0x31, 0x9d, 0x0d, 0xa8, 0x25, 0x3e, 0x83, 0xae, 0x36, 0xce, 0xfd, + 0xac, 0xf7, 0x35, 0x7f, 0x74, 0xf4, 0x66, 0xa3, 0x5f, 0x00, 0xe5, 0x30, + 0xc1, 0x11, 0x70, 0x00, 0xb5, 0xd9, 0xd4, 0x6e, 0x95, 0xc4, 0xbc, 0x5b, + 0x7d, 0x62, 0x6c, 0xd5, 0xc0, 0x1e, 0x81, 0xc0, 0x61, 0x69, 0x13, 0x63, + 0xbc, 0x7f, 0x70, 0x3f, 0x3d, 0x96, 0x18, 0x39, 0xef, 0x51, 0xc6, 0xe9, + 0xcc, 0x59, 0xda, 0xc7, 0x5d, 0xb5, 0x59, 0xb0, 0xf2, 0x99, 0x5a, 0x36, + 0x21, 0x0d, 0xcc, 0x97, 0x16, 0x2b, 0x61, 0x3d, 0x0a, 0xd1, 0x6e, 0x05, + 0x86, 0x42, 0xff, 0xd8, 0xa7, 0x5c, 0x02, 0xcf, 0x90, 0x6b, 0x4e, 0xee, + 0x4e, 0xca, 0xdb, 0xd3, 0xfe, 0x7e, 0x9b, 0xe2, 0xf0, 0xa3, 0x45, 0x6d, + 0xa9, 0x92, 0xba, 0xce, 0xc6, 0x2e, 0x0a, 0xbc, 0xb2, 0x7a, 0x57, 0x07, + 0x33, 0xc2, 0xa7, 0x16, 0x25, 0x06, 0x36, 0x83, 0x35, 0x31, 0x87, 0x18, + 0x83, 0xa3, 0xc2, 0x88, 0x55, 0xcc, 0xe4, 0x84, 0x4c, 0xce, 0xb9, 0xeb, + 0xd5, 0xb2, 0xbe, 0x3d, 0x76, 0x85, 0x10, 0x07, 0x83, 0xfa, 0x1c, 0x42, + 0xbc, 0xa3, 0x4c, 0x29, 0x49, 0xe6, 0xc0, 0x30, 0x59, 0xe0, 0xc6, 0xbe, + 0xa7, 0x48, 0x4a, 0xcf, 0x0e, 0x8e, 0xb7, 0x38, 0xf2, 0xa6, 0x26, 0xd3, + 0x88, 0x06, 0x99, 0x46, 0x19, 0x65, 0x1c, 0x91, 0x8e, 0xae, 0x90, 0x78, + 0x77, 0x7f, 0xe0, 0xc2, 0x51, 0x6f, 0xb6, 0x44, 0x15, 0xf9, 0xc5, 0x8a, + 0x6c, 0x33, 0xd5, 0x90, 0x17, 0xc2, 0xca, 0x4e, 0xe1, 0x1f, 0xef, 0x02, + 0x43, 0x05, 0x3f, 0x1e, 0xb1, 0x13, 0x23, 0x1f, 0xd6, 0xc2, 0xac, 0xc4, + 0x49, 0x7a, 0x86, 0x06, 0x4b, 0xa1, 0x55, 0x6a, 0x75, 0x91, 0x4e, 0x6b, + 0x86, 0x95, 0xa7, 0xbc, 0xdc, 0x64, 0xdb, 0x81, 0xc6, 0xa5, 0x33, 0x38, + 0x98, 0xbb, 0xac, 0x03, 0xf0, 0xba, 0x49, 0xcf, 0x1c, 0xce, 0xe2, 0x3d, + 0xe5, 0x06, 0xbc, 0x5e, 0xd0, 0xf7, 0x1c, 0xbb, 0x52, 0xa1, 0x47, 0x98, + 0x12, 0xef, 0x1c, 0xb9, 0x53, 0xec, 0x67, 0x2c, 0xf0, 0x7d, 0x85, 0x9e, + 0x45, 0x87, 0x00, 0x67, 0x2f, 0xa5, 0x19, 0x9f, 0x3e, 0x20, 0x8c, 0xe9, + 0xfa, 0x8a, 0xd8, 0x02, 0x6e, 0x16, 0xc4, 0x43, 0xff, 0x08, 0x3f, 0xf3, + 0x76, 0x53, 0x95, 0x17, 0x6e, 0x74, 0xfe, 0x7e, 0x87, 0x66, 0xc9, 0xe8, + 0x8d, 0x21, 0xea, 0xd2, 0x4d, 0xc7, 0x9c, 0x5a, 0xef, 0xd5, 0xe1, 0x12, + 0x85, 0x22, 0x40, 0x3c, 0x9d, 0x89, 0x4f, 0x12, 0xb5, 0x01, 0x95, 0x0e, + 0x9b, 0xd3, 0x38, 0x5e, 0x21, 0x5a, 0x4e, 0x7e, 0xce, 0xf7, 0xa6, 0x5a, + 0x63, 0x78, 0x40, 0xba, 0x9f, 0x29, 0xf0, 0x75, 0xb6, 0x8b, 0xd9, 0x4c, + 0xab, 0xb9, 0xf4, 0xe9, 0x1f, 0x39, 0x01, 0xb3, 0xfc, 0x2c, 0xa4, 0x74, + 0xa9, 0xa9, 0x90, 0xed, 0x77, 0xd8, 0x0c, 0x6d, 0x5c, 0x7b, 0xfc, 0xbd, + 0x96, 0x96, 0xcb, 0x9b, 0x9f, 0x88, 0x86, 0x5c, 0x3c, 0x0a, 0xde, 0x28, + 0x7c, 0xf0, 0x91, 0x1c, 0x06, 0x52, 0xbe, 0xad, 0xc8, 0xef, 0xa5, 0xd3, + 0x1e, 0x29, 0xbd, 0x1d, 0xd5, 0xba, 0xf4, 0x83, 0x2d, 0x36, 0x9a, 0x8c, + 0x8d, 0x83, 0xac, 0x3f, 0xea, 0xd2, 0x2e, 0xfb, 0xf1, 0xaa, 0x7a, 0x2e, + 0xce, 0xd3, 0x90, 0x9f, 0x3c, 0x2c, 0xee, 0xed, 0xf8, 0xfc, 0x3c, 0x0e, + 0x5f, 0xd1, 0xda, 0x9c, 0x32, 0x52, 0xcd, 0x09, 0xa1, 0x53, 0x33, 0x37, + 0xe0, 0x37, 0x95, 0xb2, 0x8d, 0x03, 0x46, 0x1f, 0xb5, 0x99, 0x65, 0x54, + 0x61, 0xa2, 0xdc, 0xe9, 0x87, 0x4d, 0x41, 0xdf, 0xd1, 0xb5, 0x2c, 0x7a, + 0x46, 0x08, 0x5e, 0x0f, 0xcc, 0x80, 0x96, 0x52, 0x98, 0xa0, 0x82, 0x52, + 0x6d, 0x62, 0x6f, 0xd9, 0x48, 0xc1, 0x36, 0x0c, 0x5c, 0x7f, 0xad, 0x2c, + 0x27, 0xcf, 0x17, 0xee, 0xfa, 0xca, 0x14, 0xe7, 0x88, 0xc4, 0x20, 0xb2, + 0xa1, 0xd2, 0x66, 0xe8, 0x81, 0xce, 0x35, 0x2b, 0x30, 0x54, 0x16, 0x9e, + 0x42, 0x77, 0x16, 0x3b, 0x84, 0x77, 0x42, 0x71, 0x33, 0xf8, 0x62, 0x9e, + 0xd4, 0x1d, 0x1d, 0xf3, 0x91, 0x60, 0x97, 0xd8, 0x10, 0x29, 0xc8, 0xf9, + 0xfa, 0xca, 0x0a, 0xe9, 0x50, 0xe1, 0xcc, 0xa7, 0xe3, 0x77, 0xc2, 0x93, + 0x68, 0x50, 0x1a, 0x98, 0xd7, 0x68, 0x40, 0x80, 0x12, 0x64, 0xa7, 0x1d, + 0xb4, 0x52, 0x85, 0x7b, 0x0e, 0x85, 0x0a, 0x59, 0x6a, 0xc8, 0xe4, 0x4b, + 0xff, 0xd7, 0x0d, 0x7d, 0x9e, 0xef, 0x07, 0x2f, 0x6d, 0x46, 0x05, 0xf9, + 0x05, 0xb1, 0x97, 0x94, 0x23, 0xc5, 0x2a, 0x99, 0xcc, 0x9c, 0xc2, 0x82, + 0x97, 0xbc, 0x24, 0x9b, 0xe4, 0xf2, 0xb3, 0x12, 0x84, 0xa0, 0x2a, 0xc4, + 0x7d, 0x29, 0x4d, 0xa4, 0x97, 0xd0, 0x85, 0xa6, 0x39, 0x18, 0xd2, 0xfb, + 0xa7, 0x08, 0x53, 0x75, 0x6b, 0xbd, 0xe3, 0x98, 0x4c, 0x94, 0xdd, 0xd4, + 0x86, 0x94, 0xc2, 0x6a, 0x14, 0x23, 0xdd, 0x69, 0xae, 0x53, 0xec, 0x83, + 0x58, 0x8e, 0x87, 0x7b, 0xf1, 0xcf, 0xff, 0x34, 0xda, 0x39, 0x67, 0xba, + 0x90, 0xc5, 0xec, 0xe0, 0xb3, 0xad, 0xad, 0x3d, 0x4c, 0x8e, 0x3f, 0x08, + 0x62, 0x80, 0x5b, 0x2d, 0xf8, 0xe1, 0x67, 0x61, 0x79, 0xf5, 0xc9, 0xbe, + 0x74, 0x1b, 0x72, 0x02, 0x56, 0xc6, 0xf8, 0xd5, 0x87, 0x3a, 0x08, 0x7b, + 0x35, 0x8f, 0xdf, 0xdf, 0x87, 0x3e, 0x09, 0xf7, 0xd2, 0x74, 0xbb, 0xec, + 0x8c, 0x49, 0x0c, 0xb5, 0x3a, 0x6b, 0x33, 0x43, 0x52, 0xe2, 0x2f, 0x71, + 0x3e, 0x6f, 0x59, 0x52, 0x50, 0x8f, 0xdb, 0xa6, 0x52, 0xa7, 0x5d, 0xda, + 0x16, 0x71, 0xb2, 0x52, 0xd7, 0x3e, 0x2d, 0xf6, 0x98, 0x53, 0x0f, 0x8f, + 0xc1, 0x79, 0xd0, 0xcf, 0xe0, 0xc8, 0x22, 0x27, 0x41, 0x14, 0xe8, 0xb8, + 0xed, 0x65, 0x3c, 0xaa, 0x11, 0x72, 0x41, 0xa8, 0xd8, 0x0b, 0x35, 0x81, + 0xec, 0xa6, 0x12, 0x30, 0x23, 0x0b, 0x71, 0x7a, 0x28, 0xd9, 0x01, 0x82, + 0x35, 0xd1, 0x64, 0x6d, 0xf3, 0x63, 0x69, 0x78, 0xb4, 0x93, 0x1e, 0x05, + 0xc9, 0xb3, 0xbc, 0xb6, 0xc4, 0x5e, 0xb6, 0x2a, 0x6e, 0xec, 0x91, 0x4a, + 0x5c, 0xa2, 0x5c, 0xea, 0x2b, 0xe3, 0x33, 0x1a, 0xb3, 0x70, 0xd5, 0x39, + 0x77, 0x3e, 0xa2, 0x96, 0xd5, 0x10, 0x75, 0x8a, 0x91, 0xc6, 0xbc, 0xb6, + 0x86, 0xa6, 0x8f, 0xd3, 0x50, 0x09, 0xa3, 0x9a, 0x1f, 0xd0, 0xd7, 0xd7, + 0x23, 0xa0, 0x32, 0xd0, 0x69, 0x33, 0x2f, 0x18, 0xf2, 0x6f, 0xe2, 0xbc, + 0x2f, 0x7f, 0xf5, 0x46, 0x81, 0x2e, 0xad, 0x14, 0xc9, 0x57, 0x10, 0xa4, + 0x71, 0xa9, 0xa4, 0x05, 0x50, 0xcb, 0x93, 0xc7, 0x53, 0x84, 0x68, 0xa5, + 0x7c, 0x65, 0xc0, 0xe0, 0x37, 0xd6, 0xc3, 0xbb, 0x36, 0xef, 0x22, 0x9e, + 0x09, 0x32, 0xa5, 0xa6, 0x73, 0x61, 0xb6, 0x3c, 0x5a, 0xbe, 0x2f, 0x63, + 0x01, 0x35, 0xfe, 0xd8, 0x98, 0xd5, 0x7e, 0xfd, 0x68, 0xd8, 0x96, 0x51, + 0x6e, 0x3a, 0x17, 0x90, 0x16, 0xeb, 0x03, 0xfa, 0x0a, 0x83, 0x1a, 0xc9, + 0x48, 0x14, 0x31, 0x32, 0x07, 0x7d, 0xa8, 0xa8, 0x64, 0xd8, 0xba, 0xcf, + 0x87, 0xc5, 0x0e, 0xc3, 0x1c, 0x5b, 0xfe, 0x31, 0x98, 0xea, 0x25, 0x29, + 0x9c, 0x77, 0xf2, 0x9f, 0x5e, 0x16, 0x11, 0x6b, 0x29, 0x08, 0xab, 0xb0, + 0x57, 0xd8, 0x3d, 0x85, 0xdc, 0x3b, 0x69, 0xea, 0xd5, 0xe6, 0x90, 0xfa, + 0x95, 0x8d, 0xcc, 0x3c, 0x2d, 0x86, 0x07, 0xc6, 0x7e, 0x8d, 0xc4, 0x7a, + 0x3a, 0xcd, 0x61, 0xa4, 0x1f, 0xd9, 0x6f, 0x07, 0xa3, 0x45, 0xe8, 0x41, + 0xed, 0x51, 0x14, 0xe4, 0x3d, 0x20, 0x3b, 0x11, 0x9e, 0x93, 0xc3, 0x2e, + 0xcd, 0x29, 0x85, 0xf0, 0x61, 0x68, 0x8e, 0x19, 0xdc, 0x20, 0x0a, 0xbd, + 0xc0, 0x15, 0x90, 0x08, 0x96, 0xcf, 0x9b, 0xf3, 0xb5, 0x7b, 0xe4, 0x9a, + 0x97, 0x22, 0x93, 0x40, 0xd4, 0xde, 0x7a, 0x6e, 0x6b, 0xc4, 0x16, 0x9e, + 0x1c, 0x98, 0x9b, 0x83, 0x6e, 0x4d, 0xde, 0x11, 0x4f, 0x22, 0xed, 0x2d, + 0xe1, 0xb3, 0xfa, 0x86, 0xb0, 0xd2, 0x53, 0xd2, 0x34, 0x8a, 0x58, 0xdc, + 0x8c, 0xd9, 0x60, 0xd3, 0x46, 0x0a, 0xde, 0x48, 0xa3, 0xda, 0x5b, 0x74, + 0x3e, 0x4c, 0x51, 0xa6, 0x02, 0x20, 0xc6, 0x0d, 0xdb, 0x13, 0x42, 0xad, + 0xc6, 0x90, 0xb1, 0xe0, 0xb0, 0xac, 0xdc, 0xa7, 0x48, 0xf8, 0x2d, 0x8f, + 0xd7, 0xd9, 0x10, 0xeb, 0xd8, 0xdb, 0xf0, 0x53, 0x67, 0xa9, 0x03, 0x3e, + 0x97, 0xbf, 0xe6, 0xc3, 0xa8, 0x87, 0x3a, 0x91, 0xb8, 0xcf, 0x88, 0x5b, + 0x0d, 0x06, 0xe1, 0xe2, 0x39, 0x74, 0xc8, 0x59, 0xe0, 0x90, 0x9f, 0xc9, + 0x0a, 0x74, 0xa3, 0xb2, 0xae, 0x69, 0x79, 0xfa, 0x0d, 0xf2, 0xee, 0xde, + 0xec, 0x88, 0xbf, 0x09, 0x54, 0xd6, 0xbe, 0xbb, 0x25, 0x91, 0xe4, 0x66, + 0xd2, 0x08, 0x78, 0xda, 0x9d, 0x07, 0xc3, 0x0b, 0x3f, 0x1a, 0xd9, 0xf4, + 0xb2, 0x2d, 0x69, 0x74, 0xb1, 0x78, 0x5f, 0xc1, 0xaf, 0x7f, 0x6d, 0x17, + 0xfc, 0x2c, 0x67, 0x62, 0xce, 0xb4, 0x41, 0x6e, 0x21, 0x4b, 0x5c, 0x77, + 0xa1, 0x1f, 0xfe, 0xe6, 0x28, 0xc8, 0x52, 0xd1, 0x8e, 0x66, 0x88, 0x65, + 0x0c, 0x58, 0xec, 0x1c, 0x71, 0x4c, 0x8a, 0xc0, 0xef, 0x3e, 0x34, 0xf7, + 0x90, 0x67, 0x28, 0x16, 0x20, 0x3a, 0x2c, 0x3f, 0x51, 0x53, 0x15, 0x1c, + 0x6c, 0x75, 0x0e, 0xe1, 0xb4, 0xf3, 0x7f, 0x60, 0x3a, 0x81, 0x34, 0x82, + 0x51, 0x5e, 0x75, 0xb0, 0x5c, 0x37, 0x87, 0x2d, 0xd5, 0xc5, 0x2c, 0xab, + 0x33, 0x8a, 0x60, 0x49, 0x2c, 0xde, 0x90, 0x12, 0x11, 0x1f, 0x4b, 0x27, + 0x15, 0x92, 0xa2, 0xf1, 0x1a, 0xde, 0x35, 0x34, 0x4d, 0x52, 0xcd, 0xc0, + 0x71, 0x46, 0x7f, 0x3e, 0x21, 0x92, 0x5f, 0xc8, 0x25, 0xd4, 0x2c, 0xf4, + 0xd9, 0x38, 0xde, 0xa5, 0xae, 0x83, 0xe3, 0x50, 0x9b, 0x1b, 0xad, 0x4b, + 0xd8, 0x3f, 0x0a, 0x23, 0x40, 0x1e, 0x46, 0x7a, 0x71, 0x06, 0xac, 0x9e, + 0x06, 0xb8, 0x96, 0xef, 0x07, 0xef, 0x38, 0xe9, 0x79, 0xaa, 0x64, 0x44, + 0xa9, 0xa3, 0xc5, 0x1d, 0x5d, 0xd3, 0xa7, 0x01, 0xef, 0xf6, 0x3b, 0x15, + 0x00, 0x0c, 0xf7, 0x59, 0x4a, 0x1c, 0x12, 0x20, 0x89, 0xa8, 0x4e, 0x7b, + 0xf8, 0x9d, 0x02, 0xa6, 0x5e, 0x19, 0x7e, 0xb8, 0x5f, 0x46, 0xd9, 0xb1, + 0xbe, 0x25, 0x2c, 0x3c, 0xe7, 0x5d, 0x3b, 0x3f, 0x6f, 0x6e, 0x94, 0x83, + 0xc3, 0x8e, 0x85, 0x65, 0xff, 0xe9, 0x8e, 0x32, 0xcc, 0x68, 0x51, 0x14, + 0xbf, 0x94, 0x21, 0x3f, 0x85, 0xa8, 0x76, 0x44, 0xe6, 0xca, 0x20, 0x84, + 0xec, 0x83, 0x84, 0x64, 0xfb, 0x80, 0x01, 0x73, 0x76, 0x21, 0xd3, 0xf0, + 0x7b, 0x74, 0x5c, 0xbf, 0x71, 0xe6, 0x34, 0xff, 0x58, 0xe8, 0x6f, 0x88, + 0xa6, 0xad, 0xcf, 0x93, 0x2a, 0xc5, 0xc5, 0x23, 0x32, 0xc8, 0xec, 0xbd, + 0xf9, 0x54, 0x3d, 0xda, 0xe4, 0x81, 0x74, 0x94, 0xbf, 0x36, 0x72, 0x11, + 0xf0, 0x8a, 0x8f, 0x1b, 0x55, 0x47, 0x70, 0x7d, 0x61, 0xf0, 0x7b, 0x11, + 0x56, 0xdb, 0xbc, 0xe5, 0x72, 0xf2, 0xbd, 0x0b, 0xa0, 0x80, 0x03, 0x1a, + 0xc6, 0xe9, 0xfc, 0xcd, 0xde, 0x42, 0xae, 0x1a, 0x7d, 0x90, 0x5d, 0x21, + 0x5b, 0x3d, 0x69, 0x6f, 0x42, 0x42, 0xf2, 0x8a, 0xc8, 0xfc, 0xb9, 0xa9, + 0xdf, 0x18, 0xc4, 0x97, 0x91, 0x21, 0x28, 0xfd, 0x82, 0x8a, 0xe7, 0xac, + 0xe5, 0x5d, 0x33, 0x7b, 0x78, 0x0a, 0x48, 0x43, 0xfe, 0xfe, 0xcf, 0x09, + 0x5f, 0xed, 0x18, 0x33, 0x0c, 0xab, 0x8a, 0x5d, 0x63, 0xd5, 0x43, 0x0b, + 0xde, 0x75, 0x56, 0xef, 0x11, 0x05, 0x8c, 0xbb, 0xc0, 0x10, 0x4e, 0x85, + 0x70, 0xe1, 0x7e, 0x62, 0xb6, 0x3a, 0x84, 0x80, 0x17, 0xab, 0x38, 0x59, + 0x0b, 0xe2, 0xb1, 0x31, 0xb8, 0xb5, 0xf5, 0xad, 0xf6, 0xbf, 0x5b, 0xfb, + 0x69, 0xc8, 0xb3, 0xce, 0x65, 0xd4, 0x8e, 0x04, 0xc5, 0xc4, 0x09, 0xba, + 0x36, 0xc9, 0x90, 0xe0, 0xc2, 0x21, 0x3a, 0x94, 0x83, 0xa5, 0xd1, 0xb2, + 0xe1, 0xae, 0x6a, 0x28, 0x22, 0x59, 0x79, 0x72, 0x82, 0x42, 0x89, 0x42, + 0x9c, 0xc3, 0xdf, 0x8d, 0x15, 0x22, 0x14, 0xb3, 0xfd, 0x2a, 0x85, 0xbe, + 0xd3, 0x12, 0xa5, 0x3b, 0x0c, 0x99, 0xb2, 0xe5, 0x43, 0x8d, 0xd7, 0xc0, + 0xa1, 0xb6, 0xb2, 0xae, 0x42, 0x4a, 0xc0, 0xe5, 0x09, 0xa2, 0xf6, 0xa4, + 0xbc, 0x01, 0xee, 0x94, 0xd2, 0x0b, 0xeb, 0x28, 0x80, 0xc9, 0x7a, 0x07, + 0xd7, 0x4b, 0xee, 0x01, 0x10, 0x48, 0xcc, 0xc6, 0x03, 0x99, 0x9d, 0x67, + 0x2a, 0xbd, 0xa0, 0x6f, 0x51, 0xa4, 0x75, 0x50, 0xe1, 0x84, 0x8e, 0xda, + 0x7b, 0x5e, 0x9e, 0x78, 0x18, 0x2a, 0x6b, 0xfa, 0xef, 0x87, 0x81, 0xe9, + 0x48, 0x3f, 0x29, 0x2d, 0xfb, 0x15, 0xd2, 0x15, 0xb5, 0x5c, 0xed, 0x45, + 0x48, 0x30, 0xec, 0x00, 0x55, 0x15, 0x13, 0xc7, 0x11, 0xc4, 0x29, 0xef, + 0x0f, 0xa8, 0xa6, 0xef, 0x19, 0x41, 0xc2, 0xb6, 0x11, 0xdc, 0xe8, 0xf4, + 0xa7, 0x03, 0x80, 0x2d, 0x92, 0xad, 0x7e, 0x7e, 0x8a, 0x71, 0xa4, 0x6c, + 0x16, 0xb9, 0x84, 0xf5, 0x8d, 0x94, 0xc5, 0xd5, 0x82, 0x29, 0x42, 0x22, + 0x1f, 0x06, 0xca, 0xdd, 0xbf, 0x74, 0x0f, 0x14, 0x79, 0x26, 0x9c, 0x79, + 0x30, 0xcb, 0x01, 0x02, 0x76, 0x22, 0x4f, 0x54, 0xff, 0x49, 0xa3, 0x03, + 0x35, 0x23, 0x45, 0x91, 0xac, 0xed, 0x13, 0x31, 0xa4, 0x4e, 0x51, 0xe8, + 0x9c, 0x5b, 0xe4, 0xcf, 0x41, 0xd3, 0xa0, 0x86, 0x7f, 0x3a, 0x4d, 0xaf, + 0xa7, 0x49, 0x63, 0x47, 0x86, 0x08, 0x88, 0xcf, 0x01, 0x7a, 0xc4, 0xf5, + 0x29, 0x67, 0x8a, 0xd4, 0xdd, 0x6a, 0x6d, 0x81, 0xb8, 0x29, 0x9d, 0x7c, + 0x32, 0x4e, 0x8f, 0x0c, 0x9f, 0x8c, 0x7e, 0x76, 0xa3, 0xd4, 0x32, 0x80, + 0xd0, 0x79, 0x7d, 0x56, 0x99, 0x6d, 0x0b, 0x88, 0xfc, 0x98, 0xdb, 0xaf, + 0x13, 0xf3, 0xb2, 0x20, 0x3f, 0x19, 0xe1, 0x83, 0x70, 0xd2, 0x26, 0xd0, + 0xd2, 0xad, 0x11, 0xeb, 0x3b, 0x31, 0x03, 0x55, 0x62, 0xca, 0xb5, 0x87, + 0x31, 0x7a, 0x11, 0x4c, 0xf2, 0xc3, 0xc2, 0x1c, 0x42, 0x94, 0x7b, 0xe6, + 0x29, 0x86, 0x70, 0x8e, 0x51, 0x4a, 0xa3, 0xf2, 0xf0, 0xed, 0xa1, 0xc6, + 0x18, 0xff, 0xf2, 0xff, 0xe0, 0x07, 0x85, 0xf1, 0x93, 0x5a, 0x83, 0x1c, + 0x4c, 0xa9, 0x9b, 0xc5, 0x0c, 0xc4, 0xf0, 0xde, 0x71, 0x93, 0x78, 0xd1, + 0x3b, 0xcc, 0x5b, 0x51, 0x1f, 0xd7, 0x21, 0x12, 0x57, 0xd5, 0x2a, 0xea, + 0x64, 0x08, 0x0e, 0xf0, 0x3d, 0x42, 0xe7, 0xdf, 0xc8, 0xea, 0x42, 0x2b, + 0x41, 0x55, 0x85, 0xb8, 0x54, 0xa4, 0xc9, 0x3f, 0xce, 0xfc, 0x1a, 0xde, + 0x73, 0x08, 0xaa, 0x09, 0x25, 0x08, 0xa0, 0xdc, 0x64, 0xb7, 0xe7, 0xcc, + 0xde, 0x85, 0xa6, 0xc3, 0xe9, 0xe1, 0x43, 0x71, 0x86, 0x05, 0x55, 0x86, + 0x47, 0xf8, 0x71, 0xbd, 0xf5, 0xd7, 0x38, 0x64, 0x7f, 0x71, 0x63, 0xe1, + 0x22, 0x39, 0x99, 0xc3, 0xdf, 0x27, 0x5d, 0xdd, 0xd0, 0x57, 0x99, 0xd5, + 0x97, 0xcd, 0xd4, 0x2e, 0xc1, 0x25, 0x3d, 0x2e, 0x03, 0x0b, 0x04, 0x20, + 0x70, 0xec, 0x46, 0x6c, 0x4b, 0x55, 0x16, 0x02, 0x00, 0x71, 0xfd, 0x8a, + 0xa0, 0x1e, 0x5f, 0x41, 0xe6, 0x96, 0x58, 0xbe, 0x02, 0x73, 0x91, 0x71, + 0xb2, 0x7e, 0xc4, 0xcd, 0xce, 0xa5, 0x26, 0xee, 0xff, 0x8c, 0x9a, 0x4c, + 0xf4, 0x0a, 0x89, 0xba, 0x14, 0x6e, 0x06, 0x86, 0xb0, 0xba, 0x41, 0xdd, + 0x27, 0xf8, 0xc3, 0x46, 0x4f, 0x39, 0xac, 0x2c, 0x8a, 0x69, 0x09, 0xb7, + 0x36, 0x0f, 0xe0, 0x8d, 0x31, 0x0f, 0xc3, 0xee, 0x3a, 0x6a, 0x9e, 0x96, + 0x91, 0xf5, 0x6a, 0x12, 0x98, 0x5a, 0xc3, 0xf3, 0xb8, 0x9b, 0x07, 0xdb, + 0x8e, 0x2a, 0xb0, 0x91, 0x86, 0xb5, 0xc7, 0xe9, 0x06, 0xe1, 0x4e, 0x83, + 0x28, 0x3a, 0x0e, 0x67, 0xe5, 0x7e, 0x88, 0x2a, 0x31, 0xd2, 0xfe, 0xf6, + 0x19, 0x3d, 0x09, 0xd1, 0xef, 0x5d, 0xe1, 0x15, 0x2d, 0xb4, 0xec, 0x23, + 0xc2, 0x0c, 0x7a, 0xbf, 0xd3, 0x6f, 0xf7, 0x8a, 0x3b, 0x3a, 0x0f, 0x20, + 0xc4, 0x78, 0xbe, 0x46, 0x30, 0x0f, 0xc2, 0xd0, 0x8c, 0x23, 0xb7, 0xfa, + 0x3c, 0x19, 0x35, 0x53, 0x5f, 0xf9, 0x94, 0xf5, 0x23, 0xbe, 0xb3, 0x56, + 0x42, 0xa1, 0x27, 0xff, 0xac, 0xbf, 0x72, 0x7e, 0x89, 0xbe, 0xb9, 0x6d, + 0x2d, 0xc4, 0x3f, 0x6c, 0x7f, 0xc4, 0x7e, 0x01, 0x09, 0xc8, 0x35, 0x80, + 0x99, 0x8f, 0x1c, 0x43, 0xd3, 0xb2, 0x4a, 0xb7, 0x08, 0x06, 0x63, 0xcd, + 0x8a, 0x5e, 0x64, 0xa2, 0x93, 0xa5, 0x15, 0xa0, 0x38, 0xa0, 0xf2, 0x1c, + 0xab, 0xe1, 0x2d, 0x19, 0x30, 0xee, 0x9b, 0x87, 0x42, 0x54, 0xfb, 0xcc, + 0xfe, 0x2a, 0xcd, 0x54, 0xf5, 0xeb, 0x52, 0x6b, 0xd4, 0x1d, 0xa3, 0x7c, + 0xec, 0xf2, 0x56, 0x51, 0x54, 0xab, 0x66, 0xb0, 0x73, 0x49, 0x3e, 0xc4, + 0x89, 0xac, 0xb0, 0xc1, 0x41, 0x6f, 0x19, 0xd6, 0x41, 0xbd, 0xc2, 0xe2, + 0x1a, 0x56, 0xb3, 0x01, 0xc9, 0xdf, 0x46, 0xe7, 0xa1, 0x42, 0xfa, 0x1c, + 0x18, 0x86, 0xe2, 0x07, 0xe4, 0xfe, 0x19, 0x03, 0x7d, 0xc4, 0x51, 0x78, + 0x29, 0x68, 0x73, 0x70, 0x82, 0x98, 0x34, 0x2e, 0x41, 0x59, 0xd5, 0x20, + 0x36, 0xe3, 0xe5, 0x2c, 0xbe, 0x76, 0x23, 0x5d, 0xb1, 0xf0, 0xda, 0xee, + 0x65, 0x54, 0xd9, 0xa1, 0x77, 0x6e, 0xd8, 0x56, 0xcb, 0x6a, 0x35, 0xb5, + 0xaa, 0x97, 0x22, 0x28, 0x4d, 0x74, 0x13, 0x96, 0x59, 0x3d, 0x3a, 0xe2, + 0x26, 0xde, 0xd3, 0xc7, 0xed, 0x97, 0x98, 0xa8, 0x4a, 0x6b, 0x4b, 0xd1, + 0x52, 0xca, 0x84, 0xd6, 0x19, 0x7a, 0x6c, 0x0d, 0xb4, 0x28, 0x4f, 0xb1, + 0xa2, 0xcc, 0x07, 0x08, 0x57, 0xc9, 0x32, 0xd4, 0xe0, 0xef, 0x96, 0x9a, + 0x31, 0x1e, 0x68, 0x1d, 0x7b, 0x57, 0x26, 0x62, 0xa4, 0x26, 0xaf, 0xc7, + 0xd0, 0xab, 0xb6, 0x9e, 0x00, 0x6d, 0xfe, 0x29, 0x30, 0x53, 0xcd, 0xb8, + 0x4e, 0x30, 0x4e, 0xa5, 0xcc, 0xf6, 0xab, 0xca, 0x4d, 0x74, 0x40, 0xc2, + 0xb4, 0xfb, 0x3f, 0x75, 0x0a, 0x9d, 0x88, 0xa3, 0xb0, 0x5b, 0x4e, 0x88, + 0x50, 0x90, 0xcb, 0x5c, 0xcd, 0xc7, 0xff, 0x75, 0x97, 0xc4, 0x1b, 0xe9, + 0x03, 0x8a, 0xa7, 0x62, 0x32, 0x98, 0x60, 0x39, 0x56, 0xe5, 0x25, 0xed, + 0xba, 0x58, 0x67, 0xa3, 0xe8, 0x23, 0xd1, 0x55, 0xb3, 0xa5, 0xc0, 0xc9, + 0x75, 0x14, 0x91, 0xe6, 0x7d, 0x0e, 0xe3, 0xac, 0xc8, 0x6b, 0xa7, 0xdb, + 0x36, 0xe8, 0x44, 0x92, 0x72, 0xf2, 0x6d, 0x10, 0xeb, 0xd0, 0x7a, 0xdd, + 0x00, 0x9b, 0xf8, 0x65, 0xaa, 0xef, 0xed, 0xfb, 0x84, 0x5f, 0xfb, 0xd8, + 0xe9, 0xa8, 0x71, 0xab, 0x20, 0x98, 0x4f, 0x21, 0x7d, 0x33, 0xe2, 0xb1, + 0x3f, 0x95, 0x9c, 0x28, 0xf5, 0xd5, 0x83, 0x01, 0xe9, 0x71, 0x68, 0xa9, + 0x3d, 0x9e, 0x49, 0xfb, 0x6c, 0x83, 0x5f, 0x48, 0x9d, 0x91, 0x00, 0xab, + 0x54, 0x17, 0x11, 0x5b, 0x9d, 0x0a, 0x17, 0x8e, 0x3a, 0xbc, 0xd5, 0x33, + 0xcd, 0x2a, 0x5b, 0x14, 0x39, 0xe4, 0x30, 0x45, 0xde, 0x6e, 0xde, 0x92, + 0x7f, 0xb5, 0x91, 0x5d, 0x5b, 0xe4, 0x18, 0x17, 0x7c, 0x22, 0x1e, 0x2d, + 0x97, 0x8b, 0x6f, 0xe0, 0x54, 0x2e, 0x25, 0xbc, 0x5f, 0xef, 0x27, 0x1b, + 0x95, 0x71, 0xcc, 0x29, 0x96, 0x30, 0x82, 0xb1, 0x99, 0x98, 0x28, 0x36, + 0x5f, 0xd6, 0xf9, 0x13, 0xb3, 0x3d, 0x14, 0x91, 0x8a, 0x2f, 0xbf, 0x6e, + 0x8c, 0x57, 0xf6, 0x8e, 0x32, 0xf2, 0xd3, 0xa5, 0x1b, 0x2b, 0xba, 0xc8, + 0x0d, 0xa4, 0xd3, 0xc2, 0x16, 0x1f, 0x5f, 0xb6, 0x89, 0x77, 0xa9, 0xf3, + 0x7b, 0xb8, 0x11, 0x23, 0x41, 0xd6, 0xe0, 0x47, 0x3c, 0x94, 0xe0, 0xed, + 0xa9, 0xb1, 0x0e, 0x90, 0x38, 0xdd, 0x60, 0xcd, 0x75, 0x00, 0x36, 0x3a, + 0x42, 0xbb, 0xfd, 0xd7, 0xc6, 0x16, 0x38, 0xb4, 0xc0, 0x1d, 0xb6, 0x46, + 0x5c, 0x2f, 0x70, 0x95, 0x8d, 0x74, 0x68, 0xb2, 0xb5, 0xae, 0x73, 0x22, + 0xa1, 0xca, 0x5d, 0xd4, 0x28, 0x1a, 0xd2, 0x19, 0x1c, 0x43, 0x5e, 0x12, + 0x16, 0x15, 0xb4, 0x97, 0x64, 0x10, 0x07, 0x48, 0xf8, 0xe3, 0xfb, 0x3e, + 0xa5, 0x05, 0xcd, 0xc1, 0x29, 0xf0, 0x67, 0xb7, 0x24, 0x02, 0xac, 0x76, + 0x91, 0x64, 0x63, 0x46, 0xfb, 0xfd, 0xaa, 0x5b, 0x3f, 0xeb, 0xe0, 0xb2, + 0x5a, 0x8d, 0xde, 0xdc, 0x92, 0x0c, 0x1e, 0xfc, 0x82, 0x55, 0xc7, 0x8a, + 0xe3, 0x28, 0x57, 0xfe, 0x10, 0xe1, 0xa3, 0x5a, 0x9e, 0x67, 0x86, 0xf4, + 0xa5, 0xf5, 0xa0, 0xbd, 0xa4, 0x3c, 0xda, 0xf3, 0x83, 0x27, 0x2f, 0x55, + 0x73, 0xb6, 0x74, 0x3e, 0xd3, 0xc9, 0x84, 0x1d, 0xff, 0x61, 0x01, 0x56, + 0x30, 0x2a, 0x23, 0x57, 0xbc, 0x88, 0xa7, 0x2f, 0x6f, 0x95, 0x91, 0x4e, + 0x5b, 0x41, 0xd9, 0x95, 0x1f, 0x09, 0x95, 0x79, 0x36, 0xe3, 0x7f, 0xbd, + 0x4b, 0x09, 0x4e, 0x7f, 0x6a, 0x58, 0x6e, 0xd0, 0x60, 0xaf, 0xf1, 0x8f, + 0x4c, 0xc5, 0x5a, 0x5c, 0xb7, 0x74, 0x83, 0x3c, 0xb3, 0x7e, 0xdc, 0x76, + 0x89, 0xa5, 0xca, 0xd7, 0x75, 0x35, 0xb2, 0x4c, 0x0a, 0x67, 0x2b, 0x7a, + 0xe8, 0xac, 0x9e, 0x26, 0xa3, 0xae, 0x87, 0x66, 0x12, 0x4e, 0x74, 0xc8, + 0xd8, 0x6d, 0x89, 0x9c, 0x34, 0x63, 0x61, 0x33, 0x1b, 0x6a, 0x78, 0x7f, + 0x2f, 0xa7, 0x9b, 0xe7, 0x42, 0x0d, 0xcb, 0xc9, 0xf0, 0xa6, 0xb5, 0x38, + 0x66, 0x80, 0xca, 0x7a, 0xa9, 0xe4, 0x93, 0xe3, 0xfc, 0x7d, 0x38, 0x7d, + 0x7a, 0x2c, 0x03, 0xb4, 0x35, 0xde, 0x1b, 0x2e, 0x29, 0x24, 0x40, 0x93, + 0x6c, 0x52, 0x21, 0xd6, 0x70, 0x88, 0xfd, 0xc7, 0x5c, 0x94, 0x95, 0xc0, + 0x03, 0xce, 0x1b, 0xb3, 0x0e, 0x87, 0xac, 0xa0, 0x88, 0xcd, 0x20, 0x3d, + 0x88, 0x6f, 0xac, 0x29, 0x2e, 0xcc, 0x7d, 0xa7, 0x09, 0x16, 0xc0, 0xcc, + 0x55, 0x43, 0x19, 0xdc, 0x5e, 0xc4, 0xe5, 0x7c, 0xfb, 0x50, 0x01, 0x41, + 0xe1, 0x70, 0x84, 0x3e, 0x60, 0x88, 0x05, 0x27, 0x4b, 0x6c, 0x59, 0x9a, + 0x01, 0x50, 0xec, 0x74, 0x6a, 0x98, 0x57, 0xfe, 0xf5, 0x63, 0xc3, 0x60, + 0x55, 0x23, 0x33, 0xf9, 0x2d, 0xf0, 0x68, 0xff, 0xad, 0x61, 0xdb, 0x5e, + 0xdb, 0x0c, 0x54, 0x68, 0x8c, 0x4b, 0x64, 0x94, 0x3c, 0xa8, 0xb1, 0x31, + 0x61, 0xf3, 0xb3, 0xed, 0x8f, 0xd5, 0x07, 0x27, 0xbf, 0xa3, 0xa2, 0x42, + 0x4a, 0xa1, 0x5e, 0xc9, 0xb3, 0x9a, 0x0f, 0xbb, 0xf7, 0xc7, 0x4d, 0x0b, + 0xee, 0xbd, 0xce, 0x9e, 0x8c, 0x14, 0x7e, 0x06, 0x6e, 0x6d, 0x9b, 0xdd, + 0x22, 0xc6, 0xc2, 0x62, 0xa5, 0x45, 0xc1, 0xe1, 0x97, 0xe2, 0x50, 0x25, + 0xcc, 0x9b, 0xc4, 0x5d, 0x2d, 0x45, 0x10, 0xad, 0xa8, 0x4f, 0x27, 0xc3, + 0x1a, 0x2c, 0xef, 0x38, 0x2d, 0xa7, 0xaf, 0xe5, 0x23, 0x7a, 0x8f, 0xbf, + 0x9c, 0xd0, 0xb6, 0x31, 0x5c, 0xaa, 0xd2, 0x8c, 0xd8, 0x91, 0x00, 0xa1, + 0x8b, 0x4d, 0x3e, 0x27, 0x22, 0x6c, 0x0f, 0x64, 0x95, 0x89, 0xa6, 0x29, + 0x90, 0xf9, 0xa9, 0x24, 0x24, 0xb8, 0x71, 0x56, 0x7a, 0xc5, 0xa9, 0x26, + 0x9f, 0xf6, 0x2a, 0xa6, 0xf1, 0xca, 0x2a, 0x17, 0x14, 0x8c, 0x8d, 0xf2, + 0x44, 0x7d, 0x49, 0x4e, 0x9b, 0x4f, 0xef, 0x72, 0x7e, 0xe8, 0x0f, 0x45, + 0xb3, 0x3d, 0x61, 0xf5, 0x9d, 0x3f, 0x9a, 0xe3, 0x93, 0xdd, 0x3d, 0x02, + 0x84, 0x7d, 0xd4, 0x84, 0xa8, 0x23, 0xe9, 0x43, 0xb6, 0x66, 0xf2, 0xb7, + 0x35, 0xcf, 0xa3, 0x2f, 0xbe, 0x48, 0x0e, 0xaa, 0xfe, 0xe9, 0x7e, 0xb0, + 0x4d, 0xb3, 0x6b, 0x69, 0xdc, 0xef, 0x20, 0xec, 0xce, 0x6c, 0xad, 0x7a, + 0x20, 0x35, 0xf2, 0xfd, 0x09, 0xe1, 0xdb, 0xca, 0x2a, 0x55, 0xf7, 0x60, + 0xca, 0xf3, 0x85, 0x12, 0xe6, 0x05, 0x4f, 0xc8, 0x6e, 0x76, 0xda, 0x5f, + 0x45, 0x1e, 0xed, 0xdf, 0x57, 0x4c, 0xeb, 0x7e, 0x28, 0xf7, 0x39, 0xc4, + 0xd0, 0x10, 0x32, 0xa9, 0xcc, 0x25, 0xd9, 0x0b, 0x8c, 0x8a, 0xf6, 0x6c, + 0x84, 0xde, 0x09, 0x8c, 0xf6, 0xa4, 0x95, 0xb3, 0x65, 0x5e, 0x49, 0x36, + 0x8c, 0x51, 0x85, 0x62, 0xcc, 0xe6, 0x2a, 0x3d, 0xdc, 0x68, 0x08, 0x41, + 0x73, 0x18, 0x74, 0x10, 0xe5, 0x18, 0xfa, 0xbe, 0x2f, 0xaa, 0x98, 0x3c, + 0x7c, 0x44, 0x43, 0x3f, 0xd6, 0x27, 0xd3, 0x28, 0xf0, 0x2b, 0xeb, 0xf2, + 0x46, 0xfc, 0xf6, 0x3f, 0xc7, 0xa8, 0xc0, 0xf0, 0x17, 0xef, 0x35, 0xde, + 0x55, 0x30, 0xef, 0xf7, 0x7b, 0x57, 0xf3, 0x9f, 0x00, 0xb5, 0x49, 0x1e, + 0xc4, 0x6a, 0xea, 0x0e, 0x40, 0x95, 0x47, 0x55, 0x32, 0x4f, 0x4f, 0x24, + 0x5a, 0x10, 0xaa, 0x1f, 0x5b, 0x9b, 0xc1, 0xb3, 0xaa, 0xa3, 0x40, 0x32, + 0x56, 0x80, 0xbf, 0x38, 0xbc, 0x89, 0xad, 0xa8, 0x0e, 0x8f, 0x8e, 0x14, + 0x17, 0x5a, 0x9b, 0x25, 0x85, 0x85, 0xa7, 0x43, 0xc8, 0x19, 0x21, 0xf9, + 0xa3, 0xdc, 0xb9, 0xc8, 0x70, 0x7b, 0xc8, 0x42, 0x38, 0x50, 0xb9, 0xcf, + 0x90, 0x6e, 0x88, 0x7f, 0x5a, 0x56, 0xc8, 0xd7, 0x84, 0x7b, 0x69, 0xe1, + 0x31, 0x6d, 0xe9, 0xc7, 0x7f, 0x39, 0x78, 0x52, 0xa2, 0x0c, 0xc7, 0x3b, + 0x89, 0x05, 0x9d, 0x66, 0xc6, 0xea, 0x48, 0x75, 0xa5, 0xd6, 0x89, 0x8e, + 0x47, 0xdf, 0x81, 0x28, 0x94, 0xc7, 0x98, 0xd4, 0x1c, 0x6f, 0x95, 0xdd, + 0x20, 0x74, 0xe9, 0xde, 0xb5, 0x3b, 0x87, 0xa1, 0x1a, 0x1e, 0xee, 0xc7, + 0xbc, 0xa4, 0x12, 0x30, 0x92, 0x60, 0x9f, 0x0d, 0x4d, 0x23, 0x1f, 0xa0, + 0xea, 0x07, 0x84, 0x10, 0xb3, 0xd3, 0x2a, 0x2f, 0x27, 0xdb, 0x27, 0x76, + 0xb8, 0x43, 0xe2, 0x9a, 0xfc, 0x9b, 0x81, 0x43, 0xd2, 0xbc, 0xc2, 0xbb, + 0x40, 0xbd, 0xe8, 0x10, 0xd5, 0xca, 0xd2, 0x10, 0x5e, 0x18, 0xfe, 0x45, + 0x1d, 0xc2, 0xf9, 0x99, 0x50, 0xbe, 0x7e, 0xca, 0x1a, 0x45, 0x17, 0x99, + 0x03, 0x9d, 0x2b, 0x68, 0xb7, 0x76, 0x3e, 0x68, 0x41, 0x81, 0x6d, 0xe3, + 0x77, 0xbe, 0x4e, 0xc9, 0x41, 0xb7, 0x8a, 0xb7, 0xa7, 0x59, 0xfa, 0x04, + 0x7b, 0xde, 0xd0, 0x3f, 0x7a, 0x57, 0xa3, 0xf1, 0x9e, 0x0a, 0x66, 0x98, + 0xb0, 0xc1, 0xc2, 0xb4, 0x7a, 0x3b, 0x2f, 0x54, 0x3b, 0x66, 0xe6, 0x6b, + 0xc5, 0x2c, 0xa1, 0xb1, 0xd2, 0xee, 0xd8, 0x30, 0xf3, 0xa9, 0x2f, 0xe8, + 0xf0, 0x3e, 0xd8, 0x2b, 0x9a, 0x75, 0x58, 0x59, 0xc7, 0x3a, 0x39, 0xa1, + 0x58, 0x19, 0x87, 0x3f, 0x90, 0xe5, 0xb3, 0xb6, 0xfe, 0x39, 0x34, 0xc8, + 0x4c, 0x21, 0x7b, 0x96, 0x9e, 0x3e, 0x38, 0x48, 0x3e, 0xaa, 0x0b, 0x1b, + 0xbf, 0xa9, 0x45, 0x83, 0x8e, 0x38, 0xf3, 0x96, 0xb8, 0x24, 0x23, 0xc1, + 0xd3, 0x5c, 0x77, 0xeb, 0x6f, 0xf8, 0x16, 0xa8, 0x94, 0xbc, 0xab, 0x2a, + 0x20, 0x52, 0xec, 0x9a, 0x5c, 0xd9, 0x99, 0xb4, 0x84, 0x50, 0x90, 0xbb, + 0xf7, 0x80, 0x51, 0x61, 0x95, 0x61, 0xaa, 0x03, 0xd6, 0xd4, 0xa9, 0x73, + 0x86, 0x3b, 0xf1, 0x7e, 0xca, 0x7c, 0xfb, 0xf9, 0x33, 0xe6, 0x96, 0x66, + 0x13, 0x7a, 0x35, 0xae, 0x71, 0xcc, 0x13, 0x4b, 0x5e, 0x73, 0xbd, 0xf8, + 0xf2, 0x5e, 0x51, 0x5c, 0x50, 0x09, 0x3c, 0x59, 0xfa, 0xd0, 0xd4, 0x8e, + 0xe0, 0x21, 0xb4, 0x97, 0xa4, 0x7d, 0xeb, 0x17, 0xef, 0x4c, 0xf4, 0xd0, + 0x0b, 0xf5, 0x42, 0xaf, 0x07, 0x8e, 0xe9, 0x5f, 0x2b, 0xce, 0xb4, 0xf9, + 0x17, 0xea, 0x9e, 0x83, 0x94, 0xf5, 0x1d, 0x49, 0x91, 0x42, 0x65, 0x84, + 0x77, 0x56, 0xc0, 0x4f, 0x67, 0x37, 0xed, 0xa3, 0x18, 0x22, 0x69, 0xd7, + 0x40, 0xfb, 0x39, 0xfd, 0xc2, 0x37, 0x68, 0x98, 0x30, 0x6a, 0x33, 0xad, + 0x2f, 0xf2, 0x3d, 0x5c, 0xe0, 0x4a, 0x29, 0x38, 0xe5, 0xe0, 0x5c, 0xb3, + 0x79, 0xd5, 0x8c, 0xcd, 0x25, 0xad, 0xab, 0xd3, 0x75, 0x2f, 0x54, 0x3a, + 0xfe, 0x8e, 0x0d, 0x3f, 0xfa, 0x6e, 0xcc, 0x80, 0x26, 0x08, 0x7f, 0xa3, + 0x9e, 0xba, 0x80, 0x4c, 0x36, 0x4c, 0x4d, 0x74, 0xc0, 0x3f, 0xd1, 0xb3, + 0xad, 0xa3, 0xc8, 0xcf, 0x7a, 0x73, 0xb7, 0x09, 0x67, 0x3b, 0xf8, 0x6f, + 0x7a, 0x26, 0x57, 0x65, 0x83, 0xcf, 0x18, 0x3c, 0x86, 0x2c, 0xb4, 0xcd, + 0xe8, 0x74, 0xfa, 0x63, 0xd4, 0xb4, 0x36, 0x36, 0xd9, 0xb0, 0xeb, 0x29, + 0xe3, 0x3a, 0x7f, 0x06, 0x80, 0x29, 0x4c, 0x86, 0x94, 0x49, 0x42, 0x22, + 0x57, 0x0c, 0x4f, 0xfa, 0x08, 0xb5, 0x12, 0xbe, 0x76, 0xf5, 0x52, 0x10, + 0x47, 0x48, 0x1f, 0xbd, 0x87, 0x51, 0xd1, 0x39, 0xc8, 0x50, 0x7c, 0xfa, + 0x92, 0xe7, 0xea, 0x40, 0x55, 0xf7, 0x61, 0x9f, 0x19, 0xc2, 0x65, 0x23, + 0x6d, 0xe0, 0x41, 0xb9, 0x5b, 0xb7, 0x8c, 0x9a, 0xee, 0x50, 0x53, 0xa6, + 0xe8, 0x80, 0x14, 0x8c, 0xeb, 0x2a, 0xc1, 0x44, 0xda, 0x6d, 0x90, 0x96, + 0xb8, 0xf1, 0xc4, 0x0d, 0xf1, 0xd8, 0x8e, 0xd0, 0xb4, 0x73, 0x49, 0xe5, + 0x34, 0xab, 0x00, 0x0f, 0x0b, 0x7b, 0xc3, 0x7d, 0x53, 0x1d, 0x75, 0xef, + 0x27, 0xfb, 0xdf, 0x29, 0xfd, 0x61, 0xb3, 0x71, 0x25, 0xac, 0x62, 0x2d, + 0xaa, 0x1a, 0x2a, 0x55, 0x6e, 0x11, 0x50, 0x4b, 0x2c, 0x3d, 0xd8, 0x8d, + 0xb9, 0xcb, 0xc2, 0x21, 0x77, 0x4e, 0x40, 0x56, 0x45, 0xc1, 0x07, 0x79, + 0xdb, 0x66, 0x2f, 0x6d, 0x4d, 0xac, 0x2b, 0x2d, 0x29, 0xff, 0xa1, 0x79, + 0x10, 0x03, 0x72, 0x09, 0xe8, 0xe9, 0x31, 0xd5, 0x6f, 0x42, 0x97, 0x3e, + 0x09, 0xf0, 0x4a, 0xb5, 0xe6, 0x73, 0x94, 0xc1, 0xb4, 0x94, 0xa1, 0xd9, + 0x44, 0xe8, 0x50, 0xe2, 0x6c, 0x82, 0xea, 0x89, 0x06, 0xd6, 0x44, 0xe9, + 0x53, 0xd0, 0x5c, 0xcf, 0x0a, 0x3b, 0x89, 0x50, 0x8d, 0x1e, 0x44, 0xbd, + 0xb2, 0xb6, 0x68, 0xf4, 0xbb, 0x2d, 0x65, 0x95, 0x5c, 0xb5, 0xdc, 0xe2, + 0xb7, 0x70, 0x86, 0xfd, 0x5b, 0xcc, 0x99, 0x41, 0x5d, 0x22, 0x11, 0xa8, + 0x22, 0x8c, 0xc1, 0x73, 0x70, 0x5b, 0x31, 0x11, 0xc3, 0xdb, 0x7f, 0xca, + 0x2b, 0xcb, 0xeb, 0x7d, 0x2b, 0xd1, 0x32, 0xe6, 0xf8, 0x22, 0x22, 0x69, + 0xea, 0xb7, 0xcd, 0x25, 0x22, 0x33, 0x2f, 0x83, 0x3f, 0xb7, 0x2d, 0x22, + 0x61, 0x24, 0x01, 0xb3, 0xe9, 0xd0, 0xf6, 0x21, 0xe6, 0x2d, 0xea, 0x0e, + 0x53, 0x7a, 0x97, 0xcd, 0xcf, 0x6c, 0xe2, 0xd5, 0x8b, 0xdc, 0xe9, 0xe0, + 0xfd, 0xd0, 0xa0, 0xbf, 0xa5, 0x39, 0x7e, 0xd4, 0xdd, 0xfe, 0x1a, 0xce, + 0xb0, 0x85, 0x8e, 0xc1, 0x05, 0x36, 0xf9, 0xd3, 0x6a, 0x35, 0xab, 0x53, + 0x1d, 0xc2, 0xa0, 0xfa, 0xc2, 0x6b, 0x8b, 0x8c, 0x2d, 0x5d, 0x5f, 0xb8, + 0x18, 0x43, 0x53, 0xb9, 0x5d, 0x08, 0x07, 0xd1, 0x8f, 0xc6, 0xe9, 0xef, + 0xaf, 0x3b, 0xbb, 0x60, 0xaa, 0x28, 0xac, 0x4c, 0x03, 0x5d, 0xc8, 0x05, + 0xba, 0x82, 0x5c, 0xcb, 0xc6, 0x2a, 0x13, 0xf6, 0xfc, 0x54, 0xf3, 0xea, + 0x20, 0xce, 0xcf, 0x05, 0x00, 0xb9, 0x98, 0x0b, 0x9f, 0x96, 0xe0, 0x7b, + 0x85, 0x8e, 0x43, 0xbd, 0xf2, 0x3e, 0x17, 0x19, 0x8d, 0x23, 0x72, 0x85, + 0x93, 0xdf, 0x3a, 0x21, 0x94, 0x34, 0x32, 0x53, 0x02, 0xba, 0x34, 0xba, + 0xa5, 0x2e, 0x5c, 0x0b, 0x1e, 0x3f, 0xa9, 0x83, 0x92, 0x63, 0x0b, 0x12, + 0xc9, 0xf8, 0x35, 0xef, 0x78, 0xa0, 0xee, 0xc0, 0xbb, 0x14, 0xd4, 0x68, + 0x39, 0xa0, 0x00, 0x38, 0x77, 0x1e, 0xfc, 0x94, 0xb4, 0xd4, 0xc1, 0x98, + 0xe1, 0x43, 0x8e, 0xc6, 0xa7, 0x58, 0x33, 0x1b, 0xa3, 0x73, 0xf7, 0x4c, + 0x49, 0x9d, 0xc0, 0xb8, 0xbf, 0x30, 0x84, 0x2e, 0x5a, 0x8b, 0x6c, 0xa5, + 0xde, 0xb5, 0x6a, 0x79, 0x67, 0x54, 0xe7, 0x8c, 0x3c, 0xf3, 0x70, 0x1b, + 0x3d, 0x35, 0x23, 0x65, 0x17, 0xc9, 0x74, 0x11, 0x0b, 0xb1, 0x64, 0xc0, + 0x65, 0xa3, 0x9e, 0x5a, 0x7b, 0xa2, 0xda, 0xe1, 0xf4, 0xeb, 0xb8, 0x13, + 0x90, 0x30, 0xc1, 0x72, 0x6a, 0x2a, 0x13, 0xe3, 0x36, 0xe1, 0x05, 0x47, + 0x56, 0x42, 0xf2, 0x59, 0x44, 0x12, 0x23, 0x27, 0xe4, 0xfe, 0xae, 0x83, + 0x39, 0x0f, 0x4c, 0x85, 0x3f, 0xaf, 0x97, 0x2e, 0xae, 0x3c, 0x12, 0x0e, + 0xfd, 0x5b, 0xfd, 0x8e, 0x58, 0x58, 0x4a, 0xbd, 0x05, 0x98, 0x6b, 0x82, + 0x03, 0x02, 0x0a, 0x2d, 0x1c, 0x19, 0x0f, 0x95, 0x12, 0x5d, 0x8c, 0x1e, + 0x7b, 0x49, 0xbb, 0x83, 0xe2, 0xd2, 0x53, 0x60, 0xe1, 0xab, 0xd2, 0x8b, + 0x02, 0xeb, 0x49, 0x27, 0xd7, 0xda, 0x22, 0xd3, 0x26, 0x6f, 0x3e, 0x5b, + 0x3f, 0x33, 0xcb, 0xa8, 0x08, 0x98, 0xa6, 0xc5, 0x35, 0xc1, 0x81, 0xc1, + 0xd6, 0x28, 0xe5, 0xba, 0x50, 0xe9, 0x14, 0x1a, 0x0b, 0x0a, 0x8a, 0x9e, + 0xa3, 0xaa, 0xbc, 0x3b, 0x38, 0x5b, 0xe0, 0x1f, 0xf6, 0xb8, 0x95, 0x79, + 0xa4, 0x45, 0x5f, 0xc4, 0x63, 0x86, 0xd0, 0x15, 0xe0, 0x25, 0x6e, 0x5f, + 0x8d, 0x75, 0x25, 0x67, 0xea, 0xf3, 0x92, 0x33, 0xd1, 0x07, 0xf3, 0x43, + 0x21, 0x42, 0x40, 0x70, 0x9b, 0x8e, 0x0b, 0x41, 0x54, 0x30, 0x73, 0xd0, + 0x49, 0xe4, 0x70, 0xf6, 0xd3, 0x7d, 0x59, 0xd6, 0x1f, 0x06, 0xfc, 0x12, + 0x89, 0x9f, 0x26, 0x09, 0x34, 0xf6, 0x64, 0x56, 0x37, 0x68, 0x59, 0x33, + 0x9c, 0xa0, 0xfa, 0x65, 0x70, 0xb3, 0xe1, 0x29, 0xd1, 0x5b, 0xaf, 0xe7, + 0xa5, 0x39, 0x64, 0x38, 0x8b, 0xb1, 0xd6, 0xce, 0xa4, 0xb4, 0xb6, 0xdb, + 0x01, 0xb4, 0xf9, 0xb7, 0x1f, 0x8f, 0xcd, 0x28, 0xe6, 0x27, 0x47, 0xf2, + 0x53, 0x1d, 0xea, 0xb4, 0x53, 0xfa, 0xe0, 0x22, 0xea, 0xc5, 0xd2, 0xfc, + 0x4e, 0x45, 0xcf, 0xef, 0xaa, 0xea, 0xaf, 0x7e, 0x77, 0xe2, 0x39, 0x1c, + 0x5d, 0x9c, 0x77, 0x7b, 0x71, 0xb5, 0x11, 0xef, 0xc7, 0xf8, 0xba, 0x2b, + 0x7b, 0x15, 0xfa, 0x2d, 0xd5, 0xd8, 0xe0, 0xee, 0xbe, 0x10, 0xd6, 0xdb, + 0x47, 0xf1, 0x11, 0xcc, 0x35, 0x4c, 0x2d, 0xa8, 0x12, 0x12, 0x23, 0x78, + 0x0b, 0xd3, 0xb8, 0x90, 0x8a, 0x1d, 0xc4, 0x90, 0x4b, 0x7e, 0x35, 0xb9, + 0x9f, 0x5b, 0x68, 0x97, 0x9c, 0x09, 0xc3, 0x0d, 0x0a, 0x20, 0xd9, 0x25, + 0x07, 0xeb, 0x56, 0xb5, 0xd6, 0x93, 0x31, 0x3d, 0x71, 0x7c, 0x0f, 0x48, + 0x26, 0x32, 0x0f, 0x1b, 0x43, 0x75, 0xc2, 0xcd, 0xf6, 0xaa, 0x88, 0x38, + 0x7b, 0xe9, 0xc0, 0x98, 0x51, 0xa4, 0x06, 0x15, 0x7f, 0x11, 0x0b, 0x91, + 0xcb, 0x59, 0x92, 0x1c, 0xa1, 0x44, 0x63, 0xa4, 0x3a, 0xad, 0xd7, 0x1d, + 0x9e, 0x63, 0xfb, 0xb9, 0x7d, 0x43, 0x80, 0x79, 0xe8, 0x01, 0xba, 0x08, + 0x47, 0x78, 0x57, 0xd6, 0x0b, 0x38, 0x94, 0x64, 0xac, 0x64, 0x77, 0xdc, + 0xb8, 0xa9, 0xa5, 0xa2, 0x62, 0x70, 0x36, 0x4f, 0x39, 0xd9, 0xae, 0x2f, + 0x15, 0xd3, 0x07, 0xc4, 0x01, 0x03, 0x96, 0x5e, 0x51, 0xa7, 0x15, 0x2a, + 0x9d, 0x22, 0x74, 0xae, 0x8a, 0xd4, 0xb9, 0x91, 0xed, 0xad, 0xa7, 0x76, + 0xad, 0x38, 0x33, 0xef, 0x3c, 0xe4, 0xd0, 0x7c, 0x6e, 0x53, 0xae, 0x0c, + 0x7a, 0xdf, 0x2c, 0x18, 0xeb, 0xc4, 0x8c, 0xfe, 0xab, 0x10, 0xcd, 0xaf, + 0x8f, 0x88, 0x3f, 0xac, 0xe3, 0x20, 0xed, 0x0c, 0x62, 0x81, 0x2e, 0x12, + 0xa9, 0xa5, 0xe7, 0xd5, 0x3a, 0xef, 0x40, 0xb4, 0x91, 0x52, 0x4c, 0xfd, + 0xd5, 0xb8, 0x98, 0x19, 0xcd, 0x1b, 0xa9, 0x17, 0xe7, 0x9a, 0xda, 0x8a, + 0xb4, 0x8f, 0x1a, 0x5c, 0x78, 0xd2, 0x28, 0x7a, 0xb6, 0x66, 0xac, 0x73, + 0xd4, 0x11, 0xc0, 0x81, 0xff, 0x71, 0x57, 0x4c, 0x23, 0x90, 0x2a, 0xd8, + 0x67, 0x7a, 0x6a, 0x58, 0xb7, 0x5b, 0xbe, 0x80, 0x62, 0x17, 0x10, 0x90, + 0xc1, 0xb7, 0x2c, 0xbe, 0xbe, 0x97, 0x2e, 0x85, 0x36, 0x07, 0x8e, 0x63, + 0xfc, 0x38, 0xc5, 0x66, 0x20, 0x33, 0x2b, 0xe8, 0x25, 0x25, 0xc1, 0x11, + 0xba, 0x5b, 0x12, 0xd9, 0x06, 0x4d, 0xfc, 0x49, 0x20, 0x27, 0x6b, 0x79, + 0x92, 0x8b, 0xde, 0x22, 0x39, 0xf9, 0x2e, 0xc9, 0x1b, 0xb9, 0x97, 0x2f, + 0xc3, 0x37, 0xf5, 0xa3, 0x6b, 0xd3, 0x3b, 0x94, 0xa5, 0x56, 0xb7, 0x81, + 0x7c, 0x9d, 0x28, 0xff, 0x57, 0xe7, 0x02, 0xa1, 0xd1, 0x3a, 0x3d, 0xac, + 0x74, 0x45, 0xb3, 0xab, 0x95, 0xec, 0x68, 0x8a, 0x9c, 0xf7, 0x43, 0xa4, + 0x14, 0x0d, 0x68, 0x40, 0x5f, 0x7e, 0x25, 0x8a, 0x47, 0x3f, 0x9c, 0xaf, + 0x88, 0x0b, 0x4a, 0xc0, 0x98, 0xc2, 0x57, 0xf4, 0xde, 0x04, 0x09, 0x37, + 0x9c, 0x87, 0x83, 0xb6, 0xa5, 0xa8, 0x5e, 0xc4, 0xec, 0x2e, 0xfd, 0xc9, + 0xf3, 0x85, 0x4f, 0x7d, 0xb8, 0xba, 0x6e, 0x6d, 0xc0, 0xd2, 0x37, 0xb2, + 0xba, 0x17, 0xad, 0x29, 0xf8, 0x71, 0x74, 0x0c, 0x93, 0x1e, 0x07, 0x34, + 0xec, 0xc3, 0x5f, 0x15, 0x21, 0x49, 0x0f, 0xa7, 0x7e, 0x72, 0x79, 0x66, + 0xfd, 0x3e, 0x29, 0xce, 0x12, 0xeb, 0x57, 0x88, 0xd8, 0xcc, 0x14, 0x96, + 0x33, 0x44, 0x64, 0x6c, 0x34, 0x55, 0xb3, 0x76, 0xc9, 0xa7, 0x3f, 0x7b, + 0x16, 0x9d, 0x7e, 0x95, 0x4c, 0xfa, 0xc9, 0x46, 0x17, 0x18, 0x18, 0x78, + 0xe7, 0xfb, 0x6b, 0x86, 0xf4, 0x25, 0x3a, 0x0b, 0x4a, 0xcd, 0x1a, 0x51, + 0xde, 0xa4, 0x45, 0xdd, 0xdb, 0xc9, 0x9f, 0xa9, 0xc3, 0x58, 0xb2, 0x43, + 0x90, 0x8b, 0xc1, 0x59, 0x47, 0x1a, 0x89, 0xcb, 0x9c, 0x6d, 0x46, 0x1f, + 0x0d, 0xe9, 0xfa, 0xd8, 0xe9, 0xde, 0xdb, 0xf5, 0x22, 0x9b, 0xe3, 0xef, + 0xb4, 0x0c, 0xc7, 0x34, 0xd0, 0x2a, 0x0f, 0x0b, 0x8e, 0x11, 0x88, 0x91, + 0xb7, 0xce, 0x92, 0xf2, 0x83, 0x3c, 0xd2, 0xf8, 0x42, 0x32, 0x82, 0x48, + 0xad, 0x67, 0x44, 0x45, 0x59, 0xac, 0x57, 0xb7, 0x7e, 0x1b, 0xce, 0xca, + 0x51, 0xfb, 0x1b, 0x12, 0x39, 0xaf, 0xe4, 0xfb, 0xdb, 0xc5, 0xb7, 0xcc, + 0x4a, 0x5d, 0xc4, 0xa6, 0x95, 0xaf, 0x5b, 0x39, 0x4e, 0x47, 0xc5, 0x50, + 0x67, 0x92, 0x84, 0x62, 0xeb, 0x81, 0x77, 0x24, 0xda, 0x27, 0x64, 0xfe, + 0xe4, 0x83, 0x40, 0x33, 0xc8, 0xb1, 0xaa, 0xbb, 0xbf, 0x13, 0xc3, 0x18, + 0x9a, 0x24, 0x06, 0xbd, 0x0a, 0x07, 0xa3, 0xd6, 0xd8, 0x38, 0x32, 0x73, + 0x8d, 0x40, 0x5f, 0xc2, 0x3f, 0xeb, 0xd2, 0x0e, 0x3d, 0x6d, 0xf5, 0x72, + 0x5a, 0xa6, 0x56, 0x22, 0x41, 0xe5, 0x0c, 0xb5, 0x0c, 0xda, 0xcd, 0x46, + 0xbc, 0xd7, 0x98, 0x89, 0x5e, 0x97, 0x54, 0x4f, 0x4b, 0xc0, 0x27, 0x51, + 0x0d, 0x20, 0x3f, 0x55, 0x78, 0xdc, 0x5a, 0x79, 0x08, 0xed, 0xd3, 0xaa, + 0x9c, 0xc3, 0x7d, 0x75, 0x76, 0x81, 0xa4, 0xe0, 0xfc, 0x90, 0x6a, 0x83, + 0x37, 0x53, 0xb8, 0xb5, 0xd9, 0x7a, 0xd9, 0x7d, 0xeb, 0x50, 0x72, 0xd3, + 0x5d, 0xed, 0x22, 0xfb, 0x6e, 0x67, 0x79, 0x9c, 0xb9, 0xea, 0xac, 0xc1, + 0x6d, 0x68, 0xf5, 0x12, 0xaa, 0x54, 0x90, 0xd8, 0x7f, 0xe0, 0xf4, 0xdd, + 0x3b, 0x88, 0xe3, 0xec, 0x7f, 0x1c, 0x2b, 0x08, 0x32, 0xc6, 0x05, 0x53, + 0xae, 0xa4, 0x46, 0xa7, 0xf3, 0xe6, 0xcb, 0xe7, 0x04, 0xc1, 0x52, 0xa7, + 0xfe, 0x68, 0x55, 0xc1, 0x91, 0xb2, 0x9a, 0x3b, 0x05, 0xc6, 0xae, 0x15, + 0x89, 0xdc, 0xb2, 0x0b, 0xeb, 0x19, 0x96, 0x62, 0xe3, 0x67, 0xc5, 0xdc, + 0xf5, 0xe8, 0xbe, 0x16, 0xbe, 0xf6, 0xe4, 0x0b, 0xeb, 0x99, 0x82, 0x65, + 0x0a, 0x97, 0xf5, 0xc2, 0x19, 0x1c, 0x1e, 0xa1, 0xf1, 0x75, 0x06, 0xa7, + 0xdb, 0x97, 0x68, 0x94, 0x0b, 0xea, 0xc4, 0xda, 0x70, 0x72, 0x3e, 0x9f, + 0xfc, 0x20, 0x4e, 0x54, 0xfb, 0x18, 0x01, 0x74, 0x9a, 0x24, 0x1d, 0x20, + 0x3a, 0x25, 0xe1, 0xd8, 0xaf, 0xe3, 0x76, 0xe0, 0x47, 0x53, 0x86, 0xd9, + 0x3f, 0xc2, 0x46, 0x4a, 0x02, 0x05, 0xaf, 0xbf, 0x49, 0x12, 0x22, 0x66, + 0x81, 0xf5, 0x9d, 0xdd, 0xae, 0x7f, 0xf5, 0x99, 0x2b, 0x89, 0xa6, 0x25, + 0x30, 0xd6, 0xb3, 0x00, 0xa4, 0x62, 0xd2, 0xb3, 0x8e, 0xdd, 0xc2, 0x04, + 0x62, 0x17, 0x44, 0xa3, 0x62, 0xf7, 0x8c, 0x56, 0x00, 0x4f, 0x98, 0xfe, + 0x7a, 0xdf, 0x9d, 0x47, 0xab, 0xc9, 0xb7, 0x0e, 0x0d, 0x02, 0x54, 0x6a, + 0xab, 0xf9, 0x22, 0xb9, 0x11, 0xb3, 0xec, 0x17, 0xb9, 0xc9, 0x86, 0xf6, + 0x66, 0x97, 0x1f, 0xa9, 0x38, 0xd8, 0x66, 0x8e, 0x41, 0xd9, 0x9a, 0x35, + 0xfd, 0x19, 0x64, 0xcb, 0x1e, 0x77, 0x80, 0xd4, 0x6d, 0xea, 0x00, 0xf5, + 0x9b, 0xc9, 0x55, 0xef, 0x80, 0x14, 0x79, 0xab, 0xf5, 0x5e, 0xb0, 0x4b, + 0x73, 0x52, 0x17, 0x2a, 0xd7, 0x68, 0x79, 0x6a, 0xf1, 0xc0, 0x04, 0xce, + 0x33, 0xd2, 0x18, 0xad, 0x39, 0x4d, 0xda, 0x40, 0x49, 0xce, 0x00, 0xca, + 0x89, 0xf3, 0xbd, 0x13, 0xe5, 0x7a, 0x03, 0x99, 0xa3, 0x4b, 0x29, 0xcd, + 0x18, 0xbd, 0xc8, 0xd7, 0x30, 0xcd, 0x4f, 0x65, 0xdc, 0xca, 0xc2, 0x9f, + 0x84, 0x2d, 0x83, 0xf6, 0x69, 0x0d, 0x55, 0x08, 0x5b, 0x6c, 0x87, 0x53, + 0xda, 0x13, 0x2a, 0x34, 0xf7, 0xea, 0x13, 0xec, 0x14, 0x90, 0xe8, 0x94, + 0xdc, 0xa6, 0xcf, 0xe9, 0x9b, 0x99, 0x63, 0x48, 0xf3, 0x34, 0xac, 0xf2, + 0x78, 0x76, 0x90, 0x46, 0xd8, 0x7d, 0x2b, 0xc1, 0xd2, 0xdd, 0xf1, 0xda, + 0x23, 0xc8, 0x3c, 0xd6, 0x58, 0x2e, 0xaf, 0x2c, 0xf6, 0x8a, 0xb3, 0x93, + 0x0e, 0x4f, 0x82, 0x7e, 0x26, 0x88, 0x0b, 0x3b, 0xe4, 0xe9, 0x85, 0x2b, + 0x99, 0xca, 0xdc, 0xad, 0x84, 0x26, 0xee, 0x35, 0x6a, 0x50, 0xc4, 0xae, + 0x95, 0x30, 0x0d, 0x09, 0xef, 0xdb, 0x4b, 0x4c, 0x9b, 0x0f, 0x04, 0x0a, + 0x6e, 0xf0, 0x92, 0x43, 0x06, 0xb9, 0x73, 0x16, 0x79, 0x15, 0x3f, 0x08, + 0xcc, 0x78, 0x2b, 0x35, 0x8c, 0xa3, 0x2a, 0x6e, 0xf6, 0x5c, 0x61, 0xf3, + 0xc6, 0x4b, 0x8a, 0xbc, 0x75, 0x1f, 0x4a, 0x00, 0x4e, 0x5f, 0x9e, 0x24, + 0x03, 0x2d, 0x86, 0x26, 0xa7, 0x78, 0xb7, 0xc3, 0x6f, 0x74, 0x6d, 0x32, + 0x34, 0xcd, 0x37, 0x42, 0x56, 0x24, 0x83, 0x7f, 0xa8, 0x1b, 0x9b, 0xae, + 0x97, 0x55, 0x2d, 0xba, 0x67, 0x75, 0x67, 0xca, 0xa5, 0xd1, 0x6e, 0xd6, + 0x48, 0xaf, 0xeb, 0x71, 0xdc, 0x31, 0xfb, 0x3b, 0xe3, 0x7c, 0x64, 0x9d, + 0xe5, 0x5a, 0xe4, 0x87, 0x6e, 0xed, 0xed, 0xca, 0xb6, 0x51, 0xfd, 0x73, + 0xef, 0x7c, 0xbc, 0x15, 0x69, 0xfd, 0x9f, 0x1f, 0x0f, 0x17, 0x1a, 0x8d, + 0x73, 0x61, 0x7d, 0xf1, 0x09, 0x97, 0x06, 0xbe, 0x90, 0x38, 0xdf, 0xac, + 0xfd, 0xe2, 0x87, 0xe8, 0xc1, 0xc3, 0x9b, 0x83, 0x79, 0xa6, 0xdd, 0x6d, + 0x58, 0x4d, 0x03, 0x26, 0x99, 0x1d, 0x2e, 0x47, 0xb0, 0x20, 0x3f, 0x84, + 0xaf, 0xfa, 0xf9, 0xf1, 0x62, 0xd5, 0x80, 0xb8, 0x6e, 0x69, 0x7e, 0x53, + 0x80, 0x05, 0xc4, 0x2f, 0xba, 0xed, 0x0d, 0x75, 0xca, 0x01, 0xde, 0x6e, + 0xf0, 0xd3, 0x23, 0x9b, 0x1e, 0xae, 0x02, 0x57, 0xeb, 0x40, 0xf2, 0x55, + 0x89, 0xd7, 0x70, 0xd6, 0x45, 0xe7, 0x67, 0xd3, 0x3e, 0x21, 0xda, 0xb6, + 0xae, 0xe5, 0xe6, 0x82, 0x0c, 0x3e, 0x3e, 0xe8, 0xbe, 0x85, 0x3d, 0x79, + 0x75, 0x90, 0x9b, 0x9c, 0x01, 0x88, 0x8d, 0x5a, 0x34, 0x1d, 0x10, 0x83, + 0x85, 0x08, 0xea, 0x88, 0x51, 0x29, 0xea, 0x95, 0x40, 0x2f, 0x16, 0x90, + 0xec, 0x1b, 0xb7, 0x22, 0x81, 0xcb, 0x1b, 0x8c, 0xf5, 0xe2, 0xfd, 0xcb, + 0x1f, 0xe7, 0xb0, 0x4b, 0x4d, 0x7c, 0x7d, 0x11, 0x17, 0x20, 0x89, 0x8b, + 0x4a, 0x80, 0xa3, 0x10, 0x6f, 0x68, 0x09, 0x01, 0x68, 0x86, 0x3b, 0x2a, + 0xfb, 0x48, 0x80, 0xa0, 0xd1, 0xdb, 0x3f, 0x91, 0x44, 0x58, 0x83, 0xc6, + 0x85, 0x77, 0x6b, 0xb1, 0x35, 0x4a, 0x03, 0xa2, 0xcf, 0x2f, 0xbd, 0xcd, + 0x4b, 0xfa, 0x5a, 0x5e, 0x8f, 0x8b, 0x95, 0x62, 0xaa, 0xe7, 0x3b, 0x54, + 0xb1, 0xec, 0xd5, 0x85, 0x4f, 0xd9, 0x59, 0x56, 0xb4, 0xec, 0xc1, 0x21, + 0xc5, 0xa6, 0x35, 0x1d, 0x7b, 0x60, 0xe1, 0xb1, 0x7c, 0x8f, 0x47, 0xa1, + 0xf1, 0x13, 0x4b, 0xaf, 0x23, 0xcb, 0x5e, 0xe2, 0x74, 0x16, 0x16, 0x96, + 0x3b, 0xff, 0xbf, 0x26, 0x5f, 0x68, 0xd5, 0x64, 0xc6, 0x62, 0xaf, 0x4a, + 0xfc, 0x0f, 0x27, 0x3e, 0x96, 0x5b, 0x7c, 0xeb, 0x78, 0x81, 0x3c, 0x0a, + 0x63, 0xd5, 0x6b, 0x3c, 0xa9, 0xd4, 0x37, 0x03, 0x3b, 0x5c, 0x62, 0x7a, + 0xd5, 0x69, 0xbe, 0x44, 0x50, 0xab, 0x0a, 0x54, 0x31, 0x5c, 0x44, 0x52, + 0xfe, 0xde, 0xbb, 0x10, 0x80, 0x79, 0xb2, 0x69, 0xc5, 0x75, 0x8b, 0xba, + 0x1d, 0x4d, 0x2d, 0xfa, 0xc8, 0x0e, 0xc0, 0xaf, 0xc2, 0x31, 0xa1, 0x53, + 0xc7, 0x9f, 0x3e, 0x1f, 0x38, 0x8c, 0x1e, 0x00, 0x78, 0x76, 0xb6, 0xb5, + 0x68, 0xa4, 0x68, 0xe9, 0xba, 0xda, 0x97, 0xca, 0x16, 0xde, 0xba, 0xa1, + 0xb7, 0x17, 0x26, 0xb3, 0x4b, 0x4b, 0x4e, 0x21, 0x9c, 0xaf, 0xce, 0xf0, + 0x52, 0x41, 0x13, 0x87, 0x75, 0xc4, 0xd7, 0x34, 0x0c, 0x2d, 0xfe, 0xc1, + 0xb6, 0x60, 0x84, 0xd2, 0x57, 0xc2, 0xb2, 0x6c, 0xa6, 0x97, 0x51, 0xea, + 0x49, 0x07, 0x7d, 0xac, 0x15, 0x75, 0x71, 0x67, 0x2c, 0xdf, 0x09, 0x0c, + 0x63, 0x38, 0x6a, 0x25, 0xf3, 0x9b, 0x5d, 0x5d, 0x63, 0xe7, 0x20, 0xa3, + 0xf5, 0x6f, 0x8c, 0x77, 0x91, 0xb0, 0x6d, 0xad, 0x01, 0x1d, 0x40, 0x65, + 0xcd, 0x31, 0xbf, 0xb2, 0x0a, 0x1f, 0xf9, 0xb0, 0x34, 0x7f, 0x6a, 0xfe, + 0xca, 0x2e, 0x28, 0xc4, 0x5b, 0xdb, 0xa9, 0xd4, 0xdc, 0xe6, 0x3a, 0x0a, + 0xeb, 0xe2, 0xc5, 0xb8, 0xbe, 0xad, 0x8d, 0x7d, 0xa2, 0x5e, 0x88, 0xad, + 0xb8, 0xda, 0x41, 0x12, 0x1f, 0xc5, 0x85, 0xa1, 0x83, 0x3d, 0xc7, 0xbb, + 0x6d, 0x55, 0x63, 0xd0, 0x8b, 0x06, 0x76, 0x96, 0xf5, 0x0b, 0xd9, 0x2f, + 0x45, 0xf4, 0x9b, 0xc8, 0x18, 0xba, 0xbd, 0x30, 0xdc, 0x4d, 0x47, 0xde, + 0xbc, 0xc0, 0xc0, 0xca, 0x9f, 0xd7, 0xda, 0xcb, 0xd8, 0xdd, 0x7e, 0x98, + 0x25, 0xfd, 0x9f, 0xa4, 0x22, 0x5d, 0x4b, 0x63, 0x1b, 0xfa, 0x78, 0xdb, + 0x3d, 0x39, 0xcc, 0x26, 0x00, 0x70, 0x0e, 0xac, 0xf7, 0x30, 0xc0, 0x8c, + 0x97, 0xbe, 0x57, 0xeb, 0x1a, 0xc0, 0xfd, 0x4c, 0x81, 0x69, 0x54, 0x1b, + 0xd4, 0x8c, 0xb2, 0xe7, 0xf0, 0x5f, 0x0e, 0x46, 0x95, 0x7a, 0x2b, 0x0c, + 0x69, 0x37, 0x89, 0x45, 0x6a, 0xb2, 0x9f, 0xa8, 0x99, 0xd2, 0x6c, 0xa0, + 0x9d, 0xc0, 0x36, 0x65, 0x2f, 0x37, 0xe3, 0xc8, 0xba, 0x4f, 0xd2, 0x4c, + 0x69, 0x2e, 0x15, 0x2c, 0x92, 0x13, 0x44, 0x96, 0xa5, 0xe9, 0x90, 0x24, + 0x0a, 0x94, 0x44, 0x16, 0x6a, 0x8e, 0x4a, 0x7b, 0xf4, 0x65, 0x41, 0xd0, + 0x4e, 0xf3, 0xf2, 0x6d, 0x8e, 0xc0, 0x70, 0xdf, 0x56, 0x2f, 0x11, 0x80, + 0x03, 0x42, 0xb5, 0x9c, 0x59, 0xea, 0xe1, 0x2d, 0xc7, 0xd1, 0x29, 0x4a, + 0xce, 0x78, 0x83, 0x8f, 0x9b, 0xd4, 0x6b, 0x91, 0xd8, 0x7b, 0xd1, 0x03, + 0xc1, 0xe8, 0x84, 0xbc, 0xca, 0x64, 0xdd, 0xac, 0xdd, 0x39, 0xaf, 0x7c, + 0x5d, 0x7a, 0x5f, 0xc3, 0x8b, 0x0f, 0xd7, 0x18, 0x43, 0x4a, 0x8e, 0x3f, + 0x2f, 0x02, 0x91, 0xa2, 0xdc, 0x3e, 0x2c, 0x9c, 0x3b, 0x3c, 0xe3, 0xd4, + 0x9a, 0xb3, 0x59, 0x43, 0xd4, 0x75, 0x1c, 0x4b, 0x0b, 0xad, 0x84, 0x2d, + 0xbd, 0x05, 0x66, 0xdb, 0x0a, 0xda, 0x77, 0x75, 0x46, 0x78, 0x99, 0x44, + 0xdf, 0x12, 0x58, 0xa9, 0x3a, 0x5f, 0x04, 0x18, 0x81, 0xa2, 0x2d, 0xcf, + 0x9c, 0x35, 0x8d, 0x67, 0x73, 0x9e, 0x8d, 0xe4, 0xc9, 0x9d, 0x15, 0x80, + 0xe3, 0x36, 0xf9, 0xbd, 0xf2, 0x65, 0xb2, 0x10, 0xa9, 0xe8, 0x2a, 0x03, + 0x9d, 0x03, 0x11, 0xe5, 0xcc, 0x32, 0x12, 0xef, 0xee, 0x22, 0xa3, 0x0c, + 0x35, 0x28, 0xc0, 0x17, 0x9b, 0x43, 0x75, 0x5f, 0x2c, 0xbf, 0xeb, 0xc4, + 0xf2, 0xa0, 0x6e, 0xcb, 0x06, 0x1c, 0x5c, 0xd9, 0xe8, 0x56, 0xaf, 0xe4, + 0x2c, 0x6a, 0x8a, 0x9e, 0xea, 0x34, 0x60, 0x09, 0x94, 0xe7, 0xb2, 0x50, + 0x4b, 0xc9, 0xeb, 0xce, 0xd2, 0x7f, 0x1d, 0xc1, 0x22, 0xe1, 0x71, 0x1f, + 0xac, 0xb7, 0xb9, 0x5c, 0x8e, 0x44, 0xe9, 0x51, 0x58, 0x5c, 0x0e, 0x12, + 0x34, 0xb5, 0xab, 0xa1, 0x0d, 0xf1, 0xc6, 0x71, 0xf0, 0x51, 0x6f, 0xa8, + 0x72, 0xde, 0xad, 0x42, 0xe6, 0x39, 0x28, 0xb0, 0x66, 0xf8, 0xcb, 0x09, + 0xb2, 0x82, 0x5a, 0x02, 0x15, 0xca, 0x17, 0xa9, 0x63, 0xd8, 0xac, 0x18, + 0x49, 0xf7, 0xfa, 0x6d, 0xad, 0x3f, 0xf5, 0x2a, 0xd2, 0x1a, 0x9e, 0x4f, + 0xdc, 0xb1, 0xb5, 0x5b, 0x93, 0x59, 0x44, 0x72, 0x0c, 0xf4, 0x7e, 0xe4, + 0x62, 0x10, 0x64, 0xad, 0x2d, 0xb0, 0x2e, 0xcb, 0xf8, 0xd9, 0xbb, 0xf9, + 0xfc, 0xc5, 0xe1, 0x31, 0x6e, 0x0e, 0x8b, 0x12, 0x62, 0x25, 0x92, 0xd6, + 0xb0, 0x0d, 0x78, 0x7e, 0x03, 0x13, 0x65, 0xe0, 0xa3, 0x5d, 0x33, 0xc7, + 0x04, 0x8b, 0xe7, 0x45, 0xa8, 0x9f, 0xd1, 0x70, 0x27, 0x32, 0x6e, 0x50, + 0x48, 0x6a, 0xd3, 0x32, 0xcb, 0xca, 0xd5, 0xcd, 0xd4, 0x0a, 0x76, 0x8e, + 0x6b, 0xb1, 0x73, 0x68, 0x38, 0xf5, 0x73, 0xb2, 0x46, 0x7a, 0xb5, 0xff, + 0xea, 0x52, 0xc9, 0x5b, 0x56, 0xff, 0xf0, 0x35, 0x4b, 0xae, 0x88, 0x61, + 0x8a, 0x3c, 0xb9, 0x78, 0x1c, 0x51, 0xaa, 0x5d, 0xaf, 0xe0, 0xe7, 0x8c, + 0x03, 0x85, 0x6a, 0x1f, 0xca, 0xb9, 0x8c, 0xf4, 0x37, 0xea, 0xae, 0x54, + 0xf1, 0xb8, 0x4c, 0x94, 0x42, 0xcf, 0x2a, 0x8d, 0x13, 0xef, 0x66, 0xf8, + 0x1b, 0xbe, 0x5d, 0x9a, 0x24, 0x12, 0xb5, 0xe8, 0xe8, 0x44, 0x6b, 0x95, + 0xd6, 0xed, 0x98, 0xd8, 0x10, 0xeb, 0x19, 0xe5, 0x42, 0x01, 0xaa, 0x1c, + 0x6a, 0x62, 0xd2, 0xf0, 0xc3, 0x33, 0x4d, 0xf0, 0x3e, 0x76, 0x8d, 0xec, + 0xbb, 0xb9, 0xeb, 0x14, 0x77, 0x02, 0x39, 0xb7, 0x75, 0x21, 0x3a, 0xa5, + 0xef, 0x04, 0xb3, 0x20, 0x50, 0xaf, 0xed, 0x99, 0x0b, 0xec, 0x12, 0x6d, + 0xad, 0x9f, 0x23, 0x02, 0xc0, 0x01, 0x5a, 0xfe, 0xfc, 0xee, 0xa9, 0xc1, + 0x23, 0x51, 0x71, 0xb0, 0xe6, 0xee, 0xcc, 0xcd, 0x6a, 0x59, 0xcf, 0xad, + 0xff, 0x4b, 0x36, 0xbf, 0x2a, 0xaf, 0x56, 0xae, 0xd7, 0x35, 0x47, 0xc4, + 0x11, 0xef, 0x66, 0x18, 0xd1, 0xec, 0x2a, 0x5c, 0xca, 0xfe, 0x8f, 0x8b, + 0xa2, 0x80, 0x57, 0x42, 0xe5, 0xa5, 0xb4, 0x7a, 0x34, 0xd0, 0x1b, 0xca, + 0xb3, 0x7f, 0x2c, 0x54, 0x47, 0x50, 0xf0, 0xdd, 0xde, 0x87, 0xc0, 0x8f, + 0x3a, 0x79, 0x49, 0x50, 0xe9, 0x4a, 0xe2, 0x74, 0x08, 0x18, 0x61, 0xaa, + 0x17, 0xe4, 0x44, 0xdf, 0xeb, 0xf8, 0x2f, 0x5f, 0x06, 0x19, 0x06, 0x13, + 0xec, 0x14, 0x47, 0x04, 0x51, 0x03, 0x55, 0x62, 0x78, 0x73, 0x7d, 0xe9, + 0x15, 0xff, 0xd3, 0xb2, 0x5c, 0x54, 0x79, 0xca, 0x58, 0x10, 0x86, 0x66, + 0x4d, 0x6a, 0x73, 0x13, 0x20, 0x60, 0xd1, 0xaa, 0x54, 0xa8, 0xf3, 0x45, + 0x1c, 0x02, 0x23, 0xc6, 0x43, 0xee, 0xb4, 0xf4, 0xed, 0xa3, 0x59, 0xb7, + 0xb3, 0x4e, 0xda, 0xdf, 0x5f, 0x12, 0xed, 0xb0, 0x03, 0x93, 0xc7, 0xb7, + 0xa9, 0x52, 0xdb, 0x91, 0x39, 0x4f, 0x0d, 0x6d, 0x31, 0x08, 0xf5, 0x91, + 0x90, 0xe5, 0x11, 0xbf, 0x33, 0x4d, 0x3f, 0x7b, 0xc8, 0x46, 0xbf, 0x8f, + 0x27, 0x61, 0xc3, 0x6c, 0xea, 0xfa, 0xaf, 0xeb, 0x92, 0xd1, 0x86, 0xb4, + 0x50, 0x64, 0x6c, 0xba, 0xdf, 0x1f, 0xe9, 0xc6, 0x2f, 0xad, 0x8d, 0x95, + 0xe7, 0xfe, 0xcb, 0xbf, 0xcc, 0xba, 0xbd, 0xcc, 0x62, 0x85, 0x62, 0x7a, + 0x96, 0x85, 0x02, 0x1c, 0xc1, 0x8f, 0x4b, 0xfc, 0x4f, 0xea, 0x69, 0x8b, + 0x1c, 0x83, 0x81, 0x34, 0x15, 0x12, 0x16, 0x6f, 0x9c, 0x0e, 0xa4, 0x83, + 0xb6, 0x28, 0x2f, 0xd7, 0x6d, 0x2e, 0x98, 0x6a, 0xe7, 0x6f, 0x53, 0x83, + 0x18, 0x43, 0x75, 0x25, 0x97, 0x14, 0x15, 0x8d, 0x2f, 0x7f, 0x72, 0x1a, + 0x07, 0x42, 0x2a, 0x7a, 0xe4, 0x7e, 0xc4, 0x7a, 0x6a, 0xc9, 0x0f, 0xeb, + 0x4b, 0x60, 0x56, 0x15, 0x51, 0x23, 0x5d, 0xfa, 0x0e, 0x56, 0x06, 0x35, + 0x89, 0x89, 0x77, 0x55, 0xd3, 0xd7, 0x22, 0x2f, 0x41, 0xc5, 0x70, 0x3f, + 0x57, 0x80, 0xc6, 0xab, 0x30, 0x7e, 0xd8, 0x2b, 0xd2, 0xd2, 0xa2, 0xfc, + 0xf9, 0x32, 0x22, 0x9e, 0x63, 0x67, 0x8a, 0x55, 0xac, 0x4e, 0x66, 0x98, + 0xe6, 0x20, 0xea, 0xbd, 0x64, 0xe9, 0xd5, 0x06, 0x33, 0x33, 0xbf, 0xe2, + 0x89, 0x49, 0x91, 0x92, 0x4e, 0xf9, 0xcc, 0x23, 0xad, 0x26, 0x1a, 0xb1, + 0x01, 0x40, 0x9b, 0x3f, 0x30, 0x5c, 0x88, 0xaf, 0xce, 0x83, 0xc3, 0x45, + 0x90, 0xdc, 0xa6, 0x20, 0x3e, 0x15, 0x96, 0x25, 0xdf, 0xe1, 0xa6, 0xd6, + 0x78, 0xaf, 0xda, 0xc0, 0x0c, 0xf1, 0x21, 0x03, 0xf9, 0x7f, 0xb5, 0xfd, + 0x59, 0x20, 0x3d, 0x73, 0xad, 0xfb, 0x2b, 0x5f, 0x88, 0xbc, 0x17, 0xaf, + 0x1c, 0xaa, 0x5d, 0x17, 0x8f, 0xb7, 0x60, 0x9c, 0xc7, 0xc4, 0xe4, 0xf4, + 0xdb, 0xa9, 0x39, 0xb0, 0xd1, 0xb4, 0x6b, 0x4b, 0x20, 0xaf, 0xd5, 0xcc, + 0xd9, 0x68, 0x17, 0x4c, 0x9a, 0xd4, 0x35, 0x25, 0x17, 0x3b, 0xc3, 0x41, + 0x7b, 0x05, 0xe9, 0xe8, 0xdd, 0x02, 0x9d, 0x0f, 0x6a, 0xd7, 0xf5, 0xfa, + 0xae, 0xf2, 0x5b, 0xfe, 0xc4, 0x44, 0x62, 0xd6, 0xc4, 0x8e, 0x4b, 0x28, + 0x6a, 0x87, 0x3c, 0xe3, 0xf8, 0x01, 0xb5, 0xf9, 0x77, 0x4e, 0x07, 0x8f, + 0x40, 0x02, 0x72, 0x81, 0xa9, 0x6e, 0xa8, 0x84, 0x1f, 0xfe, 0x2e, 0x06, + 0x83, 0xb8, 0x14, 0x2b, 0xf8, 0x6e, 0x8b, 0xb2, 0xed, 0xff, 0xc5, 0x90, + 0x09, 0x86, 0xef, 0xe7, 0x64, 0xb3, 0x3f, 0x10, 0xe1, 0x47, 0xff, 0x4f, + 0xac, 0x76, 0x45, 0xa8, 0xba, 0xac, 0xab, 0x82, 0x07, 0x86, 0x8a, 0x24, + 0xf5, 0xc0, 0x01, 0x5f, 0x54, 0x8b, 0xdc, 0xbd, 0xd6, 0x28, 0x05, 0x56, + 0xfd, 0x13, 0xdf, 0x93, 0x9b, 0x68, 0x03, 0x90, 0x2c, 0x08, 0xcc, 0x0b, + 0xf9, 0x14, 0x44, 0x84, 0x79, 0x15, 0xab, 0xbc, 0x54, 0x1b, 0x76, 0xe3, + 0xfa, 0xf8, 0x32, 0xab, 0xf2, 0xcd, 0xed, 0x04, 0x15, 0x94, 0xb4, 0xb3, + 0xcc, 0x09, 0xf1, 0xb2, 0x35, 0x60, 0x0b, 0x05, 0xa1, 0x31, 0xd6, 0x6d, + 0xc6, 0x46, 0x6d, 0xe4, 0xe7, 0xbc, 0x5f, 0x3a, 0x72, 0xfd, 0x42, 0xb0, + 0x0e, 0xbb, 0xd2, 0xeb, 0x50, 0x26, 0x60, 0x38, 0xd6, 0x96, 0x1b, 0x5b, + 0x9d, 0xcc, 0xb4, 0x98, 0x9f, 0xe8, 0xf2, 0x95, 0xa3, 0x11, 0x9a, 0xcb, + 0x6d, 0x56, 0x87, 0x4b, 0x95, 0xb9, 0x41, 0xa3, 0x89, 0x2d, 0x2c, 0x29, + 0xe8, 0x29, 0x86, 0x47, 0x3e, 0x91, 0x2a, 0x59, 0x7d, 0x9c, 0x03, 0x9d, + 0x2d, 0xff, 0x05, 0x50, 0x21, 0x88, 0x12, 0x55, 0x2b, 0x25, 0x0c, 0x0c, + 0x59, 0xa9, 0x1f, 0xbd, 0x1c, 0xa0, 0xf9, 0xc2, 0x23, 0x4b, 0xaa, 0xbe, + 0x10, 0x4f, 0xf7, 0x5a, 0x25, 0x49, 0xb2, 0xc8, 0xdc, 0xf7, 0xb1, 0x45, + 0xdf, 0xbb, 0x15, 0xd9, 0x48, 0x49, 0x01, 0x27, 0xf6, 0xdc, 0x59, 0x48, + 0xb7, 0xd7, 0x5e, 0x46, 0xde, 0x2c, 0x27, 0x64, 0xf9, 0xc2, 0xc5, 0x37, + 0x21, 0x9a, 0xbf, 0x62, 0x14, 0xdd, 0x13, 0x26, 0x9f, 0x62, 0x65, 0x55, + 0xe8, 0xd7, 0x6f, 0x10, 0x5c, 0xd7, 0x19, 0x16, 0x1b, 0x87, 0xd3, 0x74, + 0xd2, 0x8a, 0x89, 0x15, 0x17, 0xd8, 0x83, 0x8f, 0x3f, 0x38, 0x98, 0x9b, + 0x25, 0x03, 0xc7, 0x7c, 0x35, 0x88, 0x53, 0x48, 0xca, 0xd6, 0x4d, 0x20, + 0x23, 0x54, 0x15, 0x51, 0xda, 0xfb, 0x7e, 0x41, 0xbc, 0x88, 0xf5, 0x53, + 0xf6, 0xe2, 0x54, 0xe6, 0xa8, 0xb1, 0x04, 0xac, 0xd1, 0xd6, 0x37, 0xd2, + 0xa9, 0x6f, 0x96, 0xc0, 0x6a, 0xb1, 0xd4, 0xcf, 0x1e, 0xda, 0xda, 0x72, + 0x43, 0xaa, 0x7b, 0x7d, 0x39, 0x19, 0x11, 0x06, 0x2a, 0x73, 0x87, 0xe6, + 0xdb, 0x8a, 0xcf, 0x66, 0xf2, 0x77, 0xc9, 0x0a, 0xe2, 0x13, 0x90, 0xd6, + 0x1b, 0xa6, 0xfb, 0xfd, 0xda, 0x63, 0x80, 0x81, 0x55, 0x7a, 0x4b, 0xea, + 0x79, 0x4d, 0xa9, 0x46, 0x2b, 0xb1, 0xa5, 0x98, 0x8d, 0x34, 0x32, 0x07, + 0xc6, 0xff, 0x98, 0x17, 0xd1, 0x55, 0x85, 0xc6, 0x8d, 0x0a, 0x3b, 0x58, + 0x1e, 0x82, 0x24, 0xa2, 0xef, 0x83, 0xed, 0xf6, 0xe2, 0x79, 0x1b, 0x2b, + 0x46, 0x7e, 0x94, 0x5b, 0xc8, 0x5a, 0x93, 0xef, 0xca, 0x76, 0xc7, 0xef, + 0x71, 0xce, 0x15, 0x33, 0x91, 0xef, 0x46, 0xa9, 0x58, 0xd8, 0x6d, 0xa9, + 0x47, 0x45, 0x35, 0xbb, 0xce, 0x96, 0xb7, 0x44, 0xd4, 0x7a, 0x90, 0xd4, + 0xcb, 0x18, 0xbc, 0x7b, 0x64, 0xf3, 0x8e, 0xf5, 0xd5, 0xf7, 0x82, 0xdb, + 0xff, 0xd6, 0x50, 0x17, 0xdf, 0x9a, 0x11, 0x75, 0x85, 0x36, 0xc8, 0x0c, + 0x44, 0xcc, 0xdc, 0x76, 0xfc, 0x9f, 0x3e, 0x84, 0x8f, 0xea, 0xc6, 0xb1, + 0xfa, 0x97, 0x75, 0x31, 0xe8, 0xc2, 0x81, 0x7b, 0x39, 0x14, 0xad, 0xdf, + 0x67, 0xf2, 0x44, 0xe0, 0xc4, 0x7a, 0x21, 0x63, 0x74, 0x73, 0x41, 0xf4, + 0xb5, 0xbd, 0x87, 0x36, 0xd0, 0x64, 0xb6, 0x8e, 0x98, 0xd2, 0x79, 0x5f, + 0x4d, 0x22, 0x8c, 0xc1, 0x41, 0x4c, 0xea, 0xb7, 0xab, 0x4b, 0x2e, 0xca, + 0x35, 0x14, 0xd3, 0x90, 0x9e, 0xd6, 0x94, 0x3e, 0x7e, 0xe4, 0x57, 0x09, + 0x22, 0x3c, 0xe6, 0xbe, 0x04, 0x95, 0x75, 0xf8, 0xe0, 0x42, 0xe9, 0xe2, + 0x5e, 0x2e, 0x2a, 0xc6, 0x48, 0x55, 0x42, 0x39, 0xc4, 0x81, 0x6a, 0xc6, + 0x19, 0xea, 0x4c, 0x63, 0x60, 0x11, 0xdf, 0xe7, 0xde, 0x4d, 0x0f, 0xec, + 0x0c, 0x8f, 0x21, 0xe7, 0x94, 0x72, 0x24, 0x4d, 0xc0, 0x44, 0x30, 0x63, + 0x18, 0x06, 0x9b, 0xb9, 0x63, 0xc2, 0x94, 0x6d, 0x78, 0xba, 0x36, 0x58, + 0xe3, 0x07, 0x0f, 0xd4, 0x16, 0xe5, 0xc7, 0x58, 0xb1, 0x5e, 0x96, 0x25, + 0x80, 0xc0, 0x0c, 0x4d, 0xf1, 0xda, 0x8b, 0xc6, 0x66, 0x56, 0x1e, 0x7c, + 0x64, 0x6b, 0x2c, 0xb2, 0x8c, 0xed, 0x07, 0xa7, 0x52, 0x70, 0xbd, 0x68, + 0xd3, 0x48, 0x18, 0x38, 0xa6, 0x60, 0x18, 0x97, 0x4a, 0xd0, 0x88, 0xed, + 0x4c, 0x99, 0xad, 0x88, 0x56, 0xec, 0x2b, 0xd7, 0xb4, 0xd6, 0xc6, 0x43, + 0x58, 0xf6, 0x9b, 0xfb, 0x28, 0xa7, 0xb4, 0xaa, 0x61, 0xc4, 0x09, 0x0b, + 0xa7, 0x51, 0x7a, 0xd3, 0x2f, 0x84, 0xeb, 0x9e, 0xc9, 0xc9, 0xac, 0x7e, + 0x80, 0x2e, 0xa6, 0x88, 0x84, 0xd2, 0x54, 0xca, 0xe6, 0xf1, 0x7c, 0x97, + 0x7c, 0x8a, 0x8a, 0x66, 0x7f, 0x00, 0x4b, 0x73, 0x3f, 0x2e, 0xfb, 0xcc, + 0xe5, 0x07, 0xe6, 0x4e, 0xa1, 0x8e, 0xfc, 0x62, 0xb7, 0xd7, 0xbe, 0xa4, + 0x4a, 0x65, 0xd7, 0xe2, 0xaa, 0x0c, 0xdd, 0x93, 0x93, 0x63, 0x56, 0x46, + 0xe5, 0xe5, 0xf5, 0x47, 0xb1, 0xe4, 0x4e, 0x60, 0x97, 0x83, 0x82, 0x23, + 0x84, 0x37, 0x20, 0xbd, 0xb5, 0x8b, 0x9d, 0x5d, 0xc8, 0xca, 0xe1, 0xa8, + 0x5a, 0xc4, 0xaa, 0xe2, 0x79, 0xda, 0x1d, 0x48, 0x60, 0x4c, 0x2e, 0x06, + 0x95, 0xb4, 0x76, 0x42, 0xa0, 0x6e, 0x52, 0x52, 0x0f, 0xf8, 0x24, 0x81, + 0x21, 0x6f, 0x67, 0x27, 0x9e, 0xe5, 0xf9, 0x9b, 0x8c, 0x82, 0x90, 0x90, + 0xdd, 0xe7, 0xd4, 0x24, 0x54, 0xa7, 0x26, 0x41, 0xd2, 0x54, 0x50, 0x6a, + 0x66, 0xf0, 0xd5, 0x68, 0xaf, 0xd1, 0xd2, 0x00, 0x66, 0xa1, 0x9e, 0x1b, + 0xab, 0xe6, 0x43, 0xa2, 0xb8, 0x05, 0x2f, 0xae, 0x9b, 0xce, 0x15, 0xa2, + 0x5b, 0xd1, 0xb5, 0x53, 0x66, 0x6e, 0xc9, 0x44, 0x7b, 0x8c, 0x5d, 0x94, + 0x63, 0x3c, 0xa5, 0xc5, 0x81, 0x48, 0xd7, 0x98, 0x6b, 0xb7, 0xce, 0xe4, + 0xd9, 0xaf, 0x1c, 0xa9, 0x76, 0x8c, 0x1b, 0x4b, 0x5c, 0x1e, 0x9c, 0x98, + 0xef, 0x74, 0x40, 0xe3, 0xf1, 0x48, 0x8c, 0x14, 0x66, 0xe4, 0x7d, 0xbd, + 0xff, 0xcf, 0xae, 0xf8, 0x36, 0x79, 0x83, 0x76, 0xe7, 0x66, 0x36, 0x12, + 0x60, 0x17, 0x2f, 0xb0, 0x2f, 0x22, 0x32, 0x4b, 0x42, 0x65, 0xed, 0x76, + 0x6e, 0x4c, 0x9d, 0xb9, 0x54, 0x9b, 0x98, 0x8b, 0x79, 0x8b, 0x0e, 0xaf, + 0x9c, 0x8c, 0xa9, 0x58, 0xaa, 0xa2, 0xde, 0x1a, 0x9b, 0x6d, 0x75, 0x0f, + 0xd2, 0xd4, 0x28, 0xdc, 0xca, 0xcd, 0x91, 0x66, 0xd0, 0xd9, 0xab, 0x3c, + 0x22, 0x55, 0x36, 0x87, 0x4f, 0x41, 0x24, 0x5c, 0xee, 0x5a, 0x54, 0x1a, + 0xe0, 0xf5, 0x2c, 0x01, 0x98, 0xa3, 0x54, 0x6e, 0x6f, 0xdc, 0x88, 0xf7, + 0x86, 0xba, 0xe2, 0x8d, 0x84, 0x95, 0x78, 0x84, 0x8c, 0xc1, 0xae, 0x8c, + 0x7f, 0xa7, 0x91, 0xbc, 0x6d, 0x3b, 0x48, 0x7a, 0x42, 0xa0, 0xc0, 0x0a, + 0xfe, 0xda, 0xbc, 0xe7, 0xa6, 0x76, 0xcb, 0xca, 0x68, 0xb0, 0xda, 0xb3, + 0x2e, 0x4c, 0x57, 0x50, 0xeb, 0xbb, 0x0a, 0x35, 0x94, 0x80, 0xab, 0xcf, + 0xa7, 0xdc, 0xab, 0x31, 0x54, 0xef, 0xe0, 0x77, 0xa5, 0x7e, 0x9e, 0x76, + 0x96, 0x62, 0x92, 0x25, 0xf1, 0xa1, 0xa5, 0x91, 0x06, 0x9e, 0x2f, 0x81, + 0xd8, 0x5f, 0x2e, 0xe4, 0xe8, 0xda, 0x9f, 0xe1, 0x62, 0xe1, 0x30, 0xd0, + 0x16, 0x02, 0xc6, 0xeb, 0x3a, 0x43, 0x4e, 0x64, 0x07, 0x77, 0xf2, 0xda, + 0x0d, 0xf5, 0xd3, 0x1c, 0x26, 0x4c, 0xcd, 0xa4, 0xb3, 0xc5, 0xd6, 0x73, + 0xb4, 0xbc, 0xc0, 0x07, 0x64, 0x98, 0xfb, 0xf6, 0x32, 0xe4, 0xe1, 0xca, + 0x74, 0x4c, 0x64, 0xad, 0x04, 0x53, 0x1b, 0x99, 0x24, 0x7b, 0x2e, 0xd7, + 0x3e, 0x07, 0xba, 0x7a, 0x08, 0x7b, 0xb1, 0xb0, 0x11, 0x3f, 0x4e, 0x66, + 0xd8, 0xa5, 0x4e, 0x72, 0x67, 0xa6, 0xbe, 0x38, 0x76, 0xcf, 0x72, 0x07, + 0x9a, 0x57, 0x2f, 0x29, 0x6d, 0x55, 0xcd, 0x69, 0xed, 0xcf, 0x59, 0x5e, + 0xd9, 0xe5, 0x29, 0x5b, 0xd0, 0x4d, 0x85, 0xea, 0x44, 0x0c, 0xac, 0x2d, + 0x76, 0x28, 0x65, 0x39, 0x2a, 0xfc, 0x9f, 0xe8, 0xd8, 0xce, 0x5c, 0x56, + 0xc0, 0x33, 0xa4, 0xcc, 0x32, 0xa6, 0x00, 0xd8, 0x9d, 0x9d, 0x0a, 0x28, + 0x27, 0x15, 0x42, 0x8e, 0xeb, 0xb0, 0xef, 0x6f, 0xb8, 0x93, 0xe2, 0xdf, + 0x6e, 0x17, 0x46, 0x67, 0x59, 0x05, 0x92, 0xad, 0x87, 0xc6, 0x06, 0x35, + 0xc8, 0x4c, 0x05, 0x1c, 0x9f, 0xf4, 0xa4, 0xa4, 0xa1, 0x8d, 0x11, 0xc7, + 0xab, 0x4b, 0x9b, 0x3a, 0x71, 0xcb, 0x2d, 0x1f, 0xec, 0x61, 0xa0, 0x66, + 0x5f, 0x3d, 0xa3, 0x95, 0x39, 0x7f, 0x98, 0x34, 0x79, 0x32, 0x15, 0x94, + 0xa0, 0x16, 0xa4, 0xf3, 0x45, 0x7b, 0x31, 0xfe, 0xf2, 0xe3, 0x65, 0x01, + 0xc1, 0xf7, 0xcd, 0xcb, 0x59, 0x52, 0xbb, 0xf6, 0xa4, 0x12, 0x22, 0x9e, + 0x5f, 0xd0, 0x50, 0x8a, 0x43, 0x62, 0xfd, 0x22, 0x21, 0xfb, 0xae, 0x08, + 0x57, 0xc7, 0x00, 0xa6, 0x48, 0x2e, 0xcb, 0x0b, 0x76, 0x08, 0xf9, 0xd4, + 0x14, 0x9a, 0xb5, 0xcd, 0xb8, 0x33, 0xc3, 0x0d, 0x2a, 0x3a, 0xf0, 0xe2, + 0x5f, 0x0e, 0x1f, 0xa1, 0x1c, 0x71, 0x38, 0x2e, 0x8e, 0x93, 0x13, 0x27, + 0xa2, 0x4a, 0xdc, 0x95, 0x1e, 0x26, 0x30, 0x5f, 0xdd, 0xc4, 0x15, 0x8e, + 0xa8, 0xfd, 0x80, 0xf4, 0x9e, 0x31, 0x80, 0xc9, 0xa0, 0xf7, 0x61, 0xb5, + 0x55, 0x40, 0xb4, 0x7f, 0xd8, 0xb2, 0x6b, 0x58, 0xba, 0x34, 0xba, 0x78, + 0xa0, 0xee, 0xa2, 0xc4, 0x73, 0x19, 0xc7, 0xdf, 0x1b, 0x46, 0x3c, 0xe0, + 0x7c, 0xb3, 0xf9, 0x7c, 0x35, 0xd5, 0xf0, 0xbf, 0x2c, 0xed, 0xa4, 0x20, + 0x95, 0x0b, 0x05, 0x7a, 0xce, 0xdc, 0x81, 0x95, 0xf3, 0x12, 0x8a, 0x7f, + 0xcb, 0xa8, 0xdc, 0x77, 0xbf, 0x8b, 0xdf, 0xf6, 0xb0, 0xce, 0xce, 0x0b, + 0xdf, 0xe9, 0xcf, 0x92, 0x02, 0x20, 0x82, 0x81, 0x9c, 0x03, 0x72, 0xe8, + 0x41, 0x6b, 0xbe, 0xb6, 0x87, 0x8b, 0xf9, 0x9e, 0x49, 0x77, 0xc5, 0xcf, + 0x73, 0x9d, 0xf6, 0x1c, 0x42, 0x7c, 0xa8, 0xbb, 0xe3, 0x24, 0x70, 0x9f, + 0xef, 0x28, 0xce, 0x45, 0x13, 0x13, 0x5f, 0xad, 0x02, 0x2a, 0xb4, 0x14, + 0x80, 0x66, 0xe1, 0x6b, 0x29, 0x72, 0x77, 0xa3, 0x04, 0x36, 0x28, 0x8d, + 0xc6, 0x39, 0xa3, 0x29, 0x59, 0xbf, 0x1e, 0x69, 0xcc, 0x8f, 0x25, 0x28, + 0xb8, 0x24, 0x7c, 0xea, 0xe9, 0x4c, 0x43, 0x6e, 0x6c, 0x7b, 0x1d, 0x41, + 0x7f, 0xd9, 0xd9, 0x59, 0x1e, 0x45, 0x76, 0xcc, 0x26, 0x6e, 0xe1, 0x80, + 0x73, 0x4d, 0x79, 0x3c, 0x5c, 0x1d, 0x78, 0xf3, 0xf9, 0x75, 0x2c, 0x9d, + 0x9d, 0x8e, 0x90, 0x23, 0xf3, 0xf9, 0xd7, 0x68, 0x14, 0xf3, 0x09, 0x2f, + 0xa1, 0x86, 0xb1, 0x9d, 0xe2, 0x3c, 0xd3, 0x16, 0xc4, 0xdf, 0x7c, 0xcf, + 0xc5, 0xf2, 0x3e, 0x67, 0x8b, 0xc8, 0x3e, 0x23, 0x17, 0xbf, 0x75, 0x1e, + 0xf3, 0x35, 0xee, 0x9f, 0x14, 0xae, 0xc1, 0x5b, 0xe7, 0x92, 0x68, 0xb8, + 0x0f, 0x95, 0x67, 0x1b, 0x55, 0xe7, 0x90, 0x6f, 0x72, 0xa0, 0x78, 0xd2, + 0x57, 0xca, 0x0a, 0x92, 0x62, 0x8d, 0x20, 0x52, 0x84, 0xb3, 0xae, 0x8e, + 0x22, 0x3d, 0x36, 0x3a, 0xfe, 0x68, 0x2d, 0x89, 0x8f, 0x51, 0x5b, 0x87, + 0x87, 0x21, 0x69, 0x1a, 0x90, 0x97, 0x9e, 0x2f, 0x91, 0xae, 0x32, 0x17, + 0x08, 0x0b, 0x3e, 0x65, 0x8a, 0xaa, 0x8e, 0xf3, 0x7b, 0x43, 0xc4, 0x2d, + 0x05, 0xac, 0x7a, 0xd9, 0x29, 0x41, 0xf8, 0x80, 0x64, 0x99, 0x98, 0xc3, + 0xb8, 0x4b, 0x4a, 0x4b, 0x48, 0x2a, 0xbd, 0x38, 0x42, 0x3a, 0xf1, 0x67, + 0x03, 0x1d, 0xd8, 0x00, 0x50, 0xc9, 0xce, 0x3a, 0x34, 0xe5, 0xac, 0x5f, + 0x36, 0x55, 0xf4, 0xf2, 0xa6, 0x09, 0x04, 0x20, 0x64, 0x56, 0xa1, 0x15, + 0x65, 0x4d, 0x07, 0x7e, 0x47, 0xf7, 0x34, 0x30, 0x3a, 0xbe, 0x49, 0xc1, + 0x75, 0xa3, 0x7d, 0xe5, 0x0e, 0xba, 0xdf, 0x81, 0xc0, 0x94, 0xf8, 0xec, + 0x1d, 0x81, 0x63, 0x48, 0x12, 0x16, 0x82, 0x12, 0x8b, 0x2a, 0xf7, 0x6e, + 0x23, 0xa4, 0x11, 0x8b, 0x70, 0xb3, 0x8a, 0xce, 0xd0, 0xdf, 0xc4, 0x6f, + 0x65, 0x01, 0xe4, 0x6e, 0x61, 0x58, 0x78, 0x2a, 0x4b, 0x9a, 0x1b, 0x65, + 0x94, 0xc4, 0xc5, 0x9d, 0x95, 0xc6, 0x12, 0x6f, 0xfc, 0x8a, 0x5e, 0x7f, + 0xc8, 0xbe, 0xa9, 0xf0, 0x65, 0xb9, 0xa7, 0xe5, 0xa9, 0x39, 0xc3, 0x7a, + 0x79, 0x05, 0x72, 0x77, 0x1f, 0xf7, 0x2b, 0x29, 0xf5, 0xb9, 0xce, 0x20, + 0x82, 0x01, 0x21, 0xa0, 0x0c, 0xd5, 0x7c, 0x7b, 0xe5, 0x9a, 0xea, 0xdb, + 0x71, 0xa6, 0xef, 0x57, 0xca, 0x0d, 0x55, 0x3e, 0x3c, 0x9e, 0xac, 0x6c, + 0x18, 0x4e, 0xe9, 0xc4, 0x67, 0x00, 0x1d, 0xc3, 0xf6, 0x88, 0x9d, 0xd5, + 0xb4, 0x1a, 0xa8, 0xde, 0xfa, 0x8c, 0xe8, 0xb5, 0x8a, 0xec, 0x6c, 0x94, + 0x62, 0x63, 0x00, 0xaf, 0x8a, 0x91, 0x4b, 0x1b, 0x01, 0x90, 0x72, 0xa5, + 0x0a, 0x03, 0x50, 0xc7, 0x0d, 0x66, 0xaf, 0xca, 0xae, 0xe5, 0x7f, 0x00, + 0x00, 0x01, 0x0a }; -void h264_get_video_info(VideoDecodeInfo *info) +void +h264_get_video_info (VideoDecodeInfo * info) { - info->profile = GST_VAAPI_PROFILE_H264_MAIN; - info->width = H264_CLIP_WIDTH; - info->height = H264_CLIP_HEIGHT; - info->data = h264_clip; - info->data_size = H264_CLIP_DATA_SIZE; + info->profile = GST_VAAPI_PROFILE_H264_MAIN; + info->width = H264_CLIP_WIDTH; + info->height = H264_CLIP_HEIGHT; + info->data = h264_clip; + info->data_size = H264_CLIP_DATA_SIZE; } diff --git a/tests/test-jpeg.c b/tests/test-jpeg.c index 3e4b11db0b..f3bd4a1410 100644 --- a/tests/test-jpeg.c +++ b/tests/test-jpeg.c @@ -2071,11 +2071,12 @@ static const guchar jpeg_clip[JPEG_CLIP_DATA_SIZE] = { 0xd9 }; -void jpeg_get_video_info(VideoDecodeInfo *info) +void +jpeg_get_video_info (VideoDecodeInfo * info) { - info->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; - info->width = JPEG_CLIP_WIDTH; - info->height = JPEG_CLIP_HEIGHT; - info->data = jpeg_clip; - info->data_size = JPEG_CLIP_DATA_SIZE; + info->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; + info->width = JPEG_CLIP_WIDTH; + info->height = JPEG_CLIP_HEIGHT; + info->data = jpeg_clip; + info->data_size = JPEG_CLIP_DATA_SIZE; } diff --git a/tests/test-mpeg2.c b/tests/test-mpeg2.c index 0e9de2075e..16e69b7362 100644 --- a/tests/test-mpeg2.c +++ b/tests/test-mpeg2.c @@ -28,1623 +28,1624 @@ /* Data dump of a 320x240 MPEG-2 video clip (mpeg2.m2v), it has a single frame */ static const guchar mpeg2_clip[MPEG2_CLIP_DATA_SIZE] = { - 0x00, 0x00, 0x01, 0xb3, 0x14, 0x00, 0xf0, 0x12, 0x07, 0x53, 0x23, 0x80, - 0x00, 0x00, 0x01, 0xb5, 0x14, 0x8a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x01, 0xb5, 0x2b, 0x02, 0x02, 0x02, 0x05, 0x02, 0x07, 0x80, 0x00, 0x00, - 0x01, 0xb8, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, - 0xff, 0xf8, 0x00, 0x00, 0x01, 0xb5, 0x8f, 0xff, 0xf7, 0x5d, 0x80, 0x00, - 0x00, 0x01, 0x01, 0x43, 0xf8, 0x90, 0x03, 0xee, 0x36, 0xd4, 0x92, 0x85, - 0x86, 0x37, 0x48, 0x01, 0xb3, 0xf7, 0x9a, 0x1d, 0x5c, 0x38, 0xb1, 0x95, - 0xb9, 0x42, 0x43, 0xb2, 0xc2, 0x51, 0x24, 0x31, 0xb2, 0xed, 0x20, 0x73, - 0xd9, 0x08, 0xcc, 0x5b, 0xe2, 0x39, 0xbc, 0xdb, 0x12, 0xb7, 0x8c, 0x31, - 0xbf, 0x6c, 0x00, 0xc3, 0xeb, 0xc3, 0xd0, 0x6c, 0x3e, 0x16, 0xde, 0xa8, - 0x89, 0xf3, 0xc1, 0x17, 0xda, 0x5a, 0x4f, 0xca, 0xb0, 0x6b, 0x7c, 0x07, - 0xbb, 0x6c, 0x95, 0x8f, 0x74, 0x35, 0xaa, 0x45, 0x65, 0xb4, 0x35, 0xbf, - 0xd4, 0x22, 0xab, 0xfe, 0x80, 0x07, 0x7c, 0xed, 0x7a, 0x97, 0x2b, 0xaf, - 0x2f, 0x72, 0x64, 0x81, 0x86, 0x0f, 0x6f, 0x9a, 0x7b, 0x02, 0x10, 0x07, - 0x76, 0x2f, 0x01, 0x30, 0x01, 0x2d, 0x21, 0x37, 0x89, 0xbc, 0x74, 0x00, - 0xf4, 0xc3, 0x6b, 0xa4, 0x1f, 0x65, 0xa7, 0xb6, 0xff, 0x6d, 0x9f, 0x6f, - 0x6f, 0x77, 0xa8, 0x5b, 0xa7, 0x95, 0x90, 0x2e, 0x2b, 0x71, 0xec, 0x35, - 0xf4, 0x96, 0x92, 0x33, 0xa9, 0x92, 0x48, 0xdf, 0xcf, 0x50, 0x39, 0x13, - 0xd1, 0xbd, 0x25, 0x4f, 0xbe, 0x5b, 0x10, 0x25, 0x6e, 0x14, 0xdc, 0x5e, - 0xe0, 0x7b, 0x7a, 0x3d, 0x04, 0x2f, 0xf2, 0xb8, 0x84, 0x38, 0xdd, 0x16, - 0x94, 0xdb, 0x46, 0xfd, 0xdf, 0x3a, 0x00, 0x7a, 0xf9, 0x49, 0x45, 0xb7, - 0x52, 0xe9, 0x03, 0x9a, 0x4a, 0x40, 0xf8, 0x14, 0xdc, 0xa7, 0x4d, 0xf7, - 0xbc, 0x25, 0x04, 0xa0, 0x04, 0x2a, 0x81, 0x6d, 0xda, 0x36, 0x67, 0x1b, - 0xb8, 0x48, 0x96, 0xb7, 0x49, 0xea, 0xd9, 0x1c, 0x8d, 0xf8, 0xfb, 0x80, - 0x07, 0x50, 0x9c, 0x13, 0x43, 0xae, 0x94, 0x07, 0x36, 0xff, 0x8b, 0x00, - 0x1c, 0x8a, 0x35, 0x00, 0x20, 0x49, 0x40, 0xdb, 0x74, 0x05, 0x82, 0x10, - 0x03, 0xcd, 0x28, 0x29, 0x06, 0x56, 0xf1, 0x2f, 0xc0, 0x03, 0xd1, 0x22, - 0x26, 0xd0, 0x08, 0x0a, 0x03, 0x4d, 0x27, 0x37, 0x5d, 0x2f, 0x36, 0xb7, - 0xe9, 0xef, 0x7a, 0x00, 0xd0, 0x83, 0xe5, 0x14, 0x65, 0x8a, 0x62, 0xd9, - 0xe2, 0x31, 0xb8, 0x3e, 0xef, 0x15, 0xbd, 0xdc, 0xb8, 0xf4, 0xa3, 0x4a, - 0xb9, 0x36, 0x1c, 0xde, 0xe7, 0x41, 0x08, 0x01, 0xb8, 0x79, 0xe0, 0x11, - 0x4a, 0xbe, 0x07, 0xca, 0xdf, 0x2d, 0xea, 0x5d, 0x11, 0x99, 0xb0, 0x2c, - 0x3a, 0x6e, 0x41, 0xaa, 0x5b, 0x23, 0xf2, 0xb5, 0x5a, 0x41, 0xcd, 0xd8, - 0x42, 0xad, 0xf7, 0x78, 0xc8, 0x2d, 0xdc, 0x51, 0x70, 0x72, 0xcc, 0xd8, - 0xb4, 0x75, 0x85, 0x43, 0x94, 0x25, 0xbd, 0x5e, 0xf9, 0x3c, 0x49, 0xbc, - 0xe5, 0xa3, 0x2b, 0xb8, 0x49, 0x0a, 0x26, 0xd2, 0xa7, 0xea, 0x8d, 0xfd, - 0xb1, 0xf7, 0xdd, 0x22, 0x8b, 0xef, 0xce, 0x5a, 0x51, 0x66, 0x64, 0x33, - 0x8a, 0x85, 0x53, 0xc0, 0x7b, 0x51, 0x22, 0x34, 0xe8, 0xd7, 0xd0, 0x09, - 0x8f, 0x5a, 0x53, 0xb8, 0x54, 0x1b, 0x4b, 0x2c, 0xbb, 0xaa, 0x18, 0xd5, - 0x69, 0x6d, 0xd2, 0xfa, 0xba, 0x5b, 0x7c, 0x67, 0xc9, 0x37, 0x51, 0x02, - 0x37, 0x8a, 0x6a, 0xec, 0x2b, 0x03, 0x94, 0xe4, 0x1e, 0xad, 0xce, 0x96, - 0x95, 0x84, 0x34, 0x5a, 0x38, 0x63, 0x58, 0x90, 0x44, 0x0e, 0xa1, 0x35, - 0xf4, 0xa0, 0xf3, 0xe1, 0x55, 0x0a, 0x46, 0x12, 0x5b, 0x93, 0x2c, 0x0c, - 0x95, 0x51, 0x62, 0x94, 0x34, 0x34, 0x2d, 0xaa, 0x36, 0x8d, 0xf3, 0xbb, - 0x0e, 0xe3, 0x37, 0x54, 0x02, 0x32, 0x83, 0x29, 0xd0, 0xea, 0xce, 0x7e, - 0x95, 0x3c, 0x26, 0x9a, 0xd0, 0xcb, 0x9c, 0xba, 0xa8, 0x49, 0x8e, 0x2d, - 0x68, 0x4d, 0x65, 0xa9, 0xaa, 0x05, 0xb2, 0x8c, 0x37, 0xe9, 0x5e, 0xfc, - 0x00, 0x7a, 0xe7, 0x4e, 0x1e, 0xa3, 0xe5, 0x9b, 0xb9, 0x42, 0x52, 0xc3, - 0xe3, 0x3f, 0x3f, 0x39, 0x86, 0x59, 0xb8, 0x80, 0x2a, 0xa9, 0x65, 0x3d, - 0xa9, 0xd4, 0xfb, 0xf4, 0xf9, 0x65, 0x1e, 0xa9, 0x62, 0x6c, 0x18, 0x30, - 0xf8, 0xdb, 0x5f, 0xb7, 0x8e, 0xde, 0xe7, 0x1b, 0xe2, 0x84, 0xc0, 0x86, - 0xe3, 0x71, 0x37, 0x0a, 0x0b, 0x29, 0xbc, 0xe4, 0x33, 0x31, 0xbd, 0x1c, - 0xf3, 0x40, 0x1e, 0xee, 0x3b, 0x4c, 0x5f, 0xd0, 0x21, 0x00, 0x36, 0x96, - 0x3c, 0x7b, 0x76, 0xbd, 0xe9, 0xb5, 0xfd, 0x74, 0x81, 0xb6, 0xba, 0xdc, - 0x25, 0x14, 0xde, 0x6f, 0xda, 0x80, 0x1f, 0xa4, 0xf3, 0x08, 0x0b, 0x38, - 0x68, 0x6b, 0x75, 0x48, 0xdc, 0x52, 0x27, 0x1e, 0xf6, 0xa8, 0x0a, 0xaf, - 0x91, 0xb9, 0x68, 0x48, 0x67, 0x8b, 0x70, 0xf7, 0xc7, 0x96, 0x3a, 0x5f, - 0x59, 0x22, 0x59, 0xe2, 0xdc, 0xd7, 0x0c, 0xb9, 0x40, 0x07, 0xad, 0xf0, - 0x7e, 0x82, 0x74, 0x8c, 0x01, 0x6a, 0xe9, 0x63, 0x75, 0xcf, 0x59, 0x43, - 0xa1, 0x92, 0x04, 0x37, 0x86, 0xe2, 0xa5, 0x74, 0x50, 0x90, 0x1c, 0x43, - 0x3c, 0x6d, 0xf0, 0x18, 0xdb, 0xf6, 0xce, 0x24, 0x28, 0x29, 0xb9, 0xb4, - 0xac, 0xc0, 0x29, 0xbd, 0x2d, 0xab, 0xb6, 0xa3, 0x6a, 0xdf, 0xa6, 0x8e, - 0x73, 0xc5, 0xbb, 0x99, 0x90, 0x04, 0x66, 0x17, 0xea, 0xa7, 0xb7, 0xa5, - 0xe4, 0xa7, 0x6e, 0x69, 0x41, 0xbf, 0x9a, 0x60, 0xf3, 0xe0, 0xc6, 0x41, - 0x74, 0x02, 0xbe, 0x38, 0x7e, 0x50, 0x4a, 0xff, 0xd9, 0x2d, 0x0d, 0x29, - 0x7c, 0x1b, 0xaa, 0x27, 0x5c, 0x00, 0xdb, 0xfa, 0x20, 0x5b, 0xe2, 0x52, - 0xe5, 0x8f, 0x11, 0xa6, 0xd8, 0x58, 0x6a, 0x52, 0x15, 0x6d, 0x0b, 0xb5, - 0x40, 0xb6, 0x4d, 0xf0, 0x35, 0xb3, 0x76, 0xfa, 0xfe, 0x4b, 0xd0, 0x08, - 0x31, 0xb4, 0x40, 0x1a, 0xab, 0x62, 0x80, 0x84, 0x01, 0x35, 0xe0, 0x9b, - 0xff, 0xb2, 0x12, 0x19, 0x53, 0x94, 0x96, 0xd2, 0xdd, 0xbb, 0x0a, 0x66, - 0xd0, 0x1a, 0x36, 0x21, 0x40, 0x85, 0xff, 0x1b, 0x8f, 0x9e, 0xa6, 0x2a, - 0xb7, 0x75, 0xe3, 0x09, 0x0d, 0xb4, 0x18, 0xd4, 0xdd, 0xaf, 0x0e, 0x70, - 0xba, 0x4a, 0x56, 0xe5, 0x11, 0x4f, 0x95, 0x28, 0x0a, 0xa8, 0xc6, 0xf4, - 0x77, 0xf3, 0x79, 0x52, 0x4b, 0x4a, 0x5a, 0xb7, 0x3e, 0x7e, 0x6d, 0x24, - 0x23, 0x44, 0x2d, 0x5b, 0xc2, 0x2d, 0x76, 0x6d, 0xa4, 0x3a, 0xdd, 0x61, - 0x30, 0x00, 0xfe, 0x61, 0x26, 0x46, 0xfa, 0x10, 0x03, 0xf2, 0x2e, 0x00, - 0x16, 0xfd, 0xb1, 0xfe, 0xdb, 0x32, 0x95, 0xa5, 0x08, 0xaf, 0x9c, 0xc1, - 0xc5, 0x28, 0x6b, 0x7a, 0x80, 0x02, 0xd1, 0x16, 0xfb, 0xbc, 0x56, 0xe0, - 0x5e, 0x8f, 0x75, 0x0d, 0x81, 0xac, 0x13, 0x21, 0xa4, 0x8a, 0x48, 0x63, - 0x62, 0x42, 0xe3, 0x7e, 0xc1, 0xe0, 0x0f, 0xf9, 0x00, 0x72, 0x28, 0x4d, - 0x14, 0xfb, 0x92, 0x1d, 0x8e, 0xb6, 0xa6, 0x58, 0x5d, 0xf4, 0xac, 0x7e, - 0x40, 0x15, 0x80, 0x19, 0x7b, 0x3d, 0xf3, 0x65, 0xc2, 0xa7, 0x2e, 0xc3, - 0xee, 0xc5, 0x28, 0xe6, 0x4f, 0xf8, 0xbf, 0x6f, 0x97, 0x0b, 0xe3, 0xae, - 0xf5, 0x4a, 0x2f, 0x69, 0x61, 0x63, 0x5b, 0xb6, 0x46, 0x00, 0x63, 0x74, - 0x4a, 0xdc, 0xd7, 0xe5, 0x4c, 0x42, 0xdb, 0x1d, 0xe3, 0x7b, 0xa4, 0xd7, - 0x8d, 0x28, 0x32, 0x35, 0x99, 0x75, 0x4b, 0x78, 0x64, 0x0c, 0x8d, 0xfc, - 0xa0, 0x00, 0x9c, 0x59, 0x10, 0x89, 0x79, 0x77, 0xc8, 0xa7, 0x95, 0x0d, - 0xc7, 0x96, 0x51, 0x87, 0xc5, 0xad, 0x84, 0x01, 0x1b, 0xaf, 0xdc, 0x40, - 0xa1, 0x79, 0xce, 0x52, 0xe5, 0x93, 0x1e, 0x56, 0x55, 0x01, 0xec, 0xf5, - 0x6f, 0xd0, 0xa4, 0x6f, 0xe8, 0x01, 0xef, 0xc4, 0xde, 0x49, 0xef, 0x5b, - 0x36, 0x6c, 0x3a, 0xa5, 0x2e, 0x56, 0xee, 0xdd, 0x98, 0x62, 0x5a, 0x15, - 0xb4, 0xb4, 0x6e, 0xfd, 0x44, 0x21, 0x96, 0x31, 0xba, 0x1f, 0x62, 0x20, - 0x0f, 0x98, 0x00, 0x00, 0x01, 0x02, 0x43, 0xf8, 0x37, 0x13, 0x05, 0xdd, - 0xbe, 0xa9, 0x4b, 0x6c, 0xa2, 0xbc, 0xc5, 0x6e, 0x6c, 0x21, 0x12, 0x23, - 0x77, 0x3e, 0x68, 0x05, 0xa2, 0xdf, 0x8e, 0xcf, 0x02, 0xe1, 0x60, 0x73, - 0x79, 0x09, 0x08, 0x0e, 0x74, 0x25, 0x49, 0x1b, 0xcc, 0x42, 0xca, 0x21, - 0xb7, 0x90, 0xdf, 0x40, 0x10, 0xff, 0xe7, 0x1d, 0x2e, 0x92, 0x59, 0x94, - 0x80, 0x94, 0xbf, 0x16, 0xe7, 0xdc, 0x34, 0xb6, 0xd7, 0xb0, 0xd9, 0x2d, - 0x50, 0x81, 0xc5, 0x35, 0x0f, 0x6a, 0x6f, 0xd4, 0xea, 0xfd, 0x5e, 0xa0, - 0x03, 0x0a, 0xad, 0xc9, 0xee, 0x5f, 0x8e, 0x78, 0xb2, 0xc0, 0xc0, 0xe2, - 0xbd, 0x4a, 0x46, 0xd5, 0xed, 0x27, 0x2e, 0xe1, 0xea, 0x13, 0x76, 0xd1, - 0xc1, 0x65, 0x90, 0x99, 0xb6, 0x00, 0x1a, 0x24, 0x9e, 0x12, 0x87, 0xc8, - 0x14, 0x96, 0x10, 0xda, 0x60, 0x74, 0xd0, 0x2d, 0x85, 0x30, 0xaa, 0xdf, - 0x15, 0xff, 0x9c, 0x02, 0xaa, 0x36, 0xdb, 0x2d, 0xdb, 0x9b, 0xa0, 0x10, - 0xc4, 0x94, 0x87, 0x1b, 0x3e, 0x02, 0x17, 0xfc, 0x6b, 0x88, 0x70, 0xf4, - 0x21, 0x37, 0x7c, 0x5c, 0x9c, 0xba, 0xda, 0xac, 0x13, 0x59, 0x1f, 0x1b, - 0xca, 0x2b, 0x30, 0x5e, 0xe3, 0xa2, 0x78, 0xd0, 0xe2, 0x43, 0x7b, 0x87, - 0x53, 0x70, 0xbc, 0xa1, 0xb0, 0xf8, 0x12, 0xde, 0x44, 0x01, 0xf8, 0xaa, - 0x94, 0xf9, 0x43, 0x71, 0x51, 0xb4, 0x3f, 0x20, 0x9e, 0x6c, 0x49, 0x03, - 0x75, 0x76, 0x86, 0x42, 0x96, 0x95, 0x2b, 0x5a, 0x07, 0xb6, 0xfc, 0x97, - 0x8d, 0xfa, 0x7f, 0xa3, 0xcd, 0x91, 0xe6, 0x78, 0xc2, 0xc2, 0x5b, 0x77, - 0x7b, 0x48, 0xf6, 0x3d, 0x03, 0x21, 0xbd, 0x62, 0x58, 0x16, 0xb1, 0xbc, - 0xdc, 0xe7, 0xce, 0x77, 0x2b, 0xf4, 0x05, 0x7d, 0x29, 0x30, 0x69, 0xf2, - 0x37, 0x55, 0xd8, 0x00, 0x73, 0x3b, 0x89, 0x02, 0xad, 0x2c, 0x84, 0x3d, - 0xb0, 0x43, 0x25, 0x6c, 0x2c, 0x4a, 0xab, 0xe8, 0xde, 0x7d, 0xe3, 0x40, - 0x1d, 0x3f, 0xb7, 0x89, 0x90, 0x35, 0x1d, 0x76, 0xa8, 0xd2, 0x6c, 0x2d, - 0x28, 0x5b, 0x78, 0xb7, 0xf3, 0x7e, 0x57, 0xcc, 0x22, 0x49, 0xdd, 0x2a, - 0xa0, 0xd2, 0x83, 0x29, 0x6d, 0xf6, 0x3d, 0xbe, 0x73, 0x1c, 0x80, 0x10, - 0x45, 0x25, 0xa9, 0x5e, 0xad, 0xe0, 0xc5, 0xf2, 0x00, 0x70, 0x27, 0x84, - 0xd8, 0xa7, 0xee, 0xee, 0x59, 0x9b, 0x83, 0x40, 0x79, 0x22, 0xb5, 0x38, - 0x0c, 0xc5, 0x6e, 0x8c, 0xa0, 0x16, 0x87, 0x90, 0xa3, 0x6f, 0xed, 0x2f, - 0x0f, 0xf3, 0x59, 0x20, 0x13, 0x0f, 0x2d, 0x4e, 0x0a, 0x30, 0x39, 0x84, - 0xd3, 0x69, 0x8b, 0x92, 0x04, 0x17, 0x8e, 0x81, 0x1b, 0x15, 0x6e, 0x8e, - 0x29, 0xb8, 0x9c, 0x39, 0x53, 0x12, 0x5a, 0x51, 0x65, 0x42, 0xa4, 0x2b, - 0xd2, 0x9c, 0xdb, 0x38, 0x9e, 0x7a, 0x8b, 0x42, 0x4b, 0x2c, 0x30, 0xe4, - 0x6e, 0x88, 0x53, 0x7a, 0x27, 0xc6, 0xf0, 0xe8, 0x21, 0x00, 0x45, 0x28, - 0x92, 0xb5, 0x46, 0x1e, 0x7b, 0x64, 0x32, 0x6c, 0x9e, 0x31, 0x15, 0x15, - 0xb7, 0xe1, 0x68, 0x52, 0x80, 0x8a, 0xd1, 0xcd, 0xa2, 0x6d, 0xe6, 0x3f, - 0x65, 0xaa, 0x33, 0x0a, 0xc9, 0x12, 0x05, 0xa8, 0xd0, 0x86, 0x6c, 0x37, - 0xc6, 0xd8, 0x85, 0x94, 0x07, 0x36, 0x7e, 0xad, 0xeb, 0x92, 0x45, 0x2d, - 0xb6, 0x69, 0x99, 0xb8, 0x50, 0x16, 0xdc, 0x30, 0x43, 0x00, 0x77, 0x3a, - 0x80, 0x0c, 0x59, 0x1c, 0xd9, 0xcf, 0xc6, 0xd6, 0xf4, 0x11, 0xb0, 0x00, - 0xf4, 0x5e, 0x15, 0xe2, 0x91, 0x07, 0xb7, 0xad, 0xc9, 0x99, 0xed, 0x53, - 0x03, 0x22, 0xea, 0xcb, 0x40, 0x44, 0x3c, 0x73, 0x78, 0x31, 0x91, 0xbd, - 0x75, 0x04, 0x2f, 0xf7, 0xde, 0xc9, 0x20, 0x73, 0x61, 0x69, 0xcd, 0x82, - 0x90, 0x7c, 0x90, 0x86, 0xdd, 0x32, 0x25, 0x75, 0xd9, 0x03, 0x10, 0xec, - 0xb7, 0xc0, 0x73, 0x74, 0x76, 0x65, 0xce, 0x6c, 0xd0, 0x83, 0x65, 0x90, - 0x34, 0x7b, 0x70, 0xdc, 0x1d, 0xe6, 0x70, 0x46, 0x4c, 0xe0, 0xaf, 0x1a, - 0xdd, 0xcd, 0x04, 0x20, 0x08, 0xda, 0x62, 0x04, 0xaa, 0xcf, 0x45, 0x52, - 0x4b, 0x68, 0x37, 0x21, 0x21, 0xb6, 0xda, 0x01, 0x52, 0xe1, 0x0a, 0x96, - 0xdf, 0x21, 0x7c, 0x8f, 0xf5, 0x8d, 0x6f, 0x60, 0x85, 0xfe, 0x0e, 0x11, - 0x08, 0x66, 0xd2, 0x11, 0x4b, 0x58, 0x6c, 0xa9, 0x55, 0xbd, 0x08, 0xb9, - 0x48, 0xbd, 0xd3, 0x82, 0x90, 0xc8, 0x07, 0xb6, 0x81, 0xad, 0xe7, 0x37, - 0xd0, 0xa5, 0x18, 0x07, 0x36, 0x5e, 0x4a, 0x76, 0x72, 0x42, 0xbe, 0x44, - 0xb6, 0xd6, 0x8a, 0x8c, 0xbc, 0xda, 0xf7, 0x3a, 0xe6, 0x50, 0xbc, 0xa9, - 0xe8, 0x74, 0xa4, 0xb6, 0x89, 0xf8, 0xad, 0x03, 0x5b, 0xa3, 0x98, 0x96, - 0x69, 0x25, 0x5a, 0xc2, 0x3a, 0x8a, 0xc3, 0x70, 0xa1, 0xf1, 0x1e, 0x9b, - 0x21, 0xc1, 0x95, 0xae, 0xae, 0x27, 0x79, 0x4b, 0x09, 0x11, 0xba, 0xe4, - 0x6c, 0x00, 0xb3, 0xaf, 0x32, 0x6d, 0x1c, 0x41, 0xf3, 0x96, 0x58, 0x01, - 0xfb, 0x73, 0x3a, 0xc4, 0x90, 0x96, 0x48, 0x60, 0xf9, 0x63, 0x7e, 0x28, - 0x8b, 0x28, 0x9e, 0xa6, 0x1b, 0x03, 0x15, 0x64, 0x41, 0xad, 0xec, 0xbe, - 0x5d, 0xaf, 0x15, 0x9a, 0xfc, 0x81, 0xb7, 0x0e, 0xa9, 0xea, 0xd9, 0xba, - 0xcb, 0x61, 0xa5, 0xd0, 0xc5, 0x1c, 0xde, 0x87, 0xcf, 0x8f, 0xed, 0x11, - 0x98, 0x2f, 0x29, 0x69, 0x70, 0x02, 0xb7, 0xe4, 0x85, 0xcf, 0x05, 0xa3, - 0x1a, 0xf2, 0x17, 0x11, 0x93, 0x7d, 0xb0, 0x06, 0x7b, 0x99, 0xa4, 0x7e, - 0xa9, 0x03, 0x99, 0x2a, 0x79, 0xc7, 0x3f, 0x52, 0xde, 0x29, 0x94, 0xa5, - 0x8a, 0x4b, 0x8d, 0xe3, 0xdf, 0xf9, 0x6f, 0xba, 0x80, 0x3d, 0x15, 0xfe, - 0x00, 0x7d, 0x9e, 0xfc, 0x7b, 0x91, 0x93, 0x62, 0xe9, 0x3f, 0x9c, 0xcf, - 0x27, 0x07, 0xdb, 0x46, 0x16, 0x5a, 0xc6, 0xe2, 0x8b, 0xfb, 0xe8, 0x02, - 0x37, 0x88, 0x77, 0xc4, 0x1c, 0x95, 0x64, 0xaf, 0xde, 0x6c, 0xf2, 0x85, - 0x41, 0xc5, 0xb2, 0xb6, 0x57, 0xcb, 0x28, 0xf4, 0x89, 0x19, 0xd1, 0x96, - 0x50, 0xa6, 0xfc, 0xf7, 0xfc, 0x53, 0xfd, 0xc8, 0xf9, 0x9c, 0x3e, 0x06, - 0x27, 0x39, 0x78, 0xd4, 0x01, 0x5c, 0xa8, 0xa7, 0x0e, 0x6f, 0xd4, 0x42, - 0x01, 0x0b, 0xfc, 0xfe, 0x04, 0xb8, 0x84, 0xf9, 0x6c, 0xf0, 0x2c, 0xa6, - 0xc9, 0xfd, 0xdb, 0xfe, 0xfa, 0x72, 0xb6, 0x84, 0x38, 0xd4, 0x7f, 0xa8, - 0xea, 0xda, 0x44, 0xe0, 0x01, 0x9f, 0xb8, 0xbd, 0x72, 0x86, 0x99, 0x52, - 0x42, 0x14, 0x6e, 0xbd, 0x86, 0xee, 0x12, 0xe4, 0x6e, 0xbd, 0x86, 0xee, - 0x12, 0xe4, 0x6e, 0x90, 0x07, 0xbe, 0xfd, 0xf3, 0xcc, 0x86, 0x3e, 0xd4, - 0x92, 0x01, 0x87, 0x64, 0x5f, 0x16, 0xe9, 0x09, 0xef, 0x9d, 0x7d, 0xb6, - 0xbf, 0x68, 0xd5, 0x6d, 0x6d, 0xe0, 0x80, 0x14, 0x68, 0x20, 0x80, 0xaf, - 0xde, 0x73, 0xce, 0x50, 0xc9, 0xc4, 0x3b, 0x68, 0xcf, 0x46, 0xdd, 0x4b, - 0x3d, 0xb5, 0x54, 0xdb, 0x1b, 0xe7, 0x00, 0x3d, 0xfa, 0x40, 0x07, 0x8f, - 0xc7, 0x11, 0xf1, 0x5e, 0x55, 0x5a, 0xe7, 0x47, 0x47, 0xe4, 0x9e, 0x6a, - 0x88, 0x10, 0xdf, 0x17, 0x11, 0xf1, 0x84, 0x6b, 0xd0, 0x05, 0x84, 0xe9, - 0x3f, 0x44, 0xe9, 0x62, 0x5c, 0x1a, 0xdf, 0x4e, 0x00, 0x78, 0x00, 0xbb, - 0xb1, 0x3d, 0x63, 0x9f, 0xc6, 0x3e, 0x9a, 0xb2, 0xed, 0x19, 0xb1, 0xb1, - 0x00, 0x39, 0x00, 0x71, 0xf2, 0x00, 0xe0, 0x01, 0x97, 0x4e, 0xce, 0xf9, - 0xcd, 0xc8, 0x31, 0xf6, 0xea, 0x24, 0x31, 0xa0, 0xe8, 0xdc, 0xd4, 0xac, - 0x2e, 0xc6, 0x00, 0x00, 0x01, 0x03, 0x43, 0xf9, 0x6d, 0x84, 0xef, 0x3a, - 0x09, 0x80, 0x07, 0x34, 0x90, 0xde, 0x07, 0x7f, 0x39, 0x63, 0x7b, 0xb7, - 0x1b, 0xc6, 0xf3, 0x32, 0xc0, 0x8d, 0xe0, 0xbb, 0x14, 0x2a, 0x56, 0xf2, - 0x02, 0xdc, 0x4f, 0xe5, 0xf3, 0x3c, 0x7c, 0xdc, 0x5a, 0x1c, 0x7a, 0x37, - 0x04, 0xa6, 0x48, 0xad, 0xe3, 0xa1, 0x6d, 0xd7, 0x6d, 0x55, 0x38, 0x32, - 0x35, 0x87, 0xed, 0x02, 0x9b, 0x47, 0x21, 0xeb, 0x93, 0xd6, 0x56, 0xae, - 0x97, 0x24, 0x9b, 0xe2, 0x35, 0xb3, 0x83, 0x99, 0x46, 0xdd, 0xf0, 0x00, - 0xec, 0x80, 0x58, 0x51, 0xb0, 0x0a, 0x56, 0x5f, 0x6b, 0x05, 0x70, 0x2b, - 0x22, 0x00, 0x8f, 0x82, 0xc9, 0x76, 0xd2, 0x5b, 0x50, 0xe8, 0x64, 0x8b, - 0x42, 0x5b, 0x15, 0x0e, 0xad, 0x9c, 0x39, 0xae, 0x0d, 0x6d, 0xf1, 0x73, - 0x12, 0xdf, 0x4b, 0x0e, 0x09, 0x6f, 0x46, 0xec, 0x00, 0x3d, 0x8f, 0xe0, - 0xa0, 0xb5, 0x59, 0xe0, 0xde, 0x6e, 0xfe, 0x4d, 0x00, 0x18, 0x37, 0xd0, - 0x7b, 0x04, 0x2f, 0xf0, 0x7f, 0xb9, 0x94, 0x00, 0x68, 0x9e, 0xa9, 0x1b, - 0x40, 0x1c, 0xc0, 0x3d, 0x90, 0xd6, 0xec, 0x10, 0x9c, 0xe9, 0x44, 0x35, - 0x6e, 0x57, 0xb3, 0xed, 0xe7, 0x5d, 0xb1, 0xc0, 0x3d, 0x0e, 0xbd, 0x59, - 0xe8, 0x85, 0xaf, 0x83, 0x72, 0xb7, 0x1d, 0x9d, 0xbb, 0xcb, 0x8a, 0x1a, - 0x6c, 0x3f, 0x10, 0xf1, 0x8a, 0xb5, 0xae, 0x15, 0x8f, 0x17, 0xcf, 0x2f, - 0x2c, 0x31, 0x66, 0x15, 0x1b, 0x48, 0x54, 0x29, 0xb7, 0x71, 0x75, 0xbe, - 0xbb, 0x9f, 0xbd, 0x8a, 0x99, 0x29, 0xc3, 0x9f, 0x90, 0xaa, 0x36, 0x9d, - 0x47, 0xb7, 0xb2, 0xe7, 0x1d, 0xf3, 0x1d, 0x90, 0xf3, 0xcd, 0xe6, 0x5b, - 0x43, 0x46, 0x0d, 0x6f, 0x9a, 0x13, 0x76, 0x90, 0xed, 0xa1, 0xf6, 0xb7, - 0xbe, 0x70, 0x21, 0x7f, 0xbb, 0xb9, 0x88, 0x01, 0x0b, 0x73, 0x6a, 0x24, - 0x5a, 0xd3, 0x96, 0xe4, 0x02, 0x9b, 0xf4, 0xda, 0xe9, 0xb6, 0x94, 0x12, - 0x73, 0x57, 0xef, 0xaf, 0x77, 0x16, 0xf1, 0x14, 0x70, 0x6b, 0x71, 0x30, - 0x53, 0x88, 0x97, 0xb7, 0x76, 0x60, 0x23, 0xff, 0xea, 0xbe, 0x18, 0xea, - 0x12, 0x10, 0xda, 0x7d, 0xb8, 0xc7, 0xce, 0x73, 0xb4, 0x87, 0x16, 0x1d, - 0xb2, 0xaa, 0x90, 0xda, 0x5e, 0xe5, 0xd1, 0xad, 0x8e, 0x8e, 0xb7, 0xd5, - 0xbe, 0x60, 0x03, 0x39, 0x82, 0x34, 0xce, 0xe4, 0x83, 0x9f, 0x46, 0x0f, - 0x6f, 0x35, 0x7f, 0x2f, 0x97, 0x21, 0x45, 0x5f, 0x35, 0x81, 0xd6, 0x40, - 0xea, 0x58, 0x69, 0x0d, 0xbd, 0xe0, 0x03, 0xae, 0x60, 0xb8, 0x6f, 0x0f, - 0xd0, 0xdf, 0x2a, 0x5e, 0x6a, 0x87, 0x1a, 0x65, 0x3c, 0xe6, 0xe6, 0xff, - 0xf2, 0x00, 0x38, 0xf6, 0xc1, 0x5d, 0x85, 0xd8, 0xfb, 0xa8, 0xe2, 0xd6, - 0x07, 0x84, 0x1e, 0x18, 0xdb, 0xe4, 0x34, 0xbc, 0x6e, 0xb7, 0x42, 0x7e, - 0xcb, 0x9e, 0x0d, 0xf8, 0xc9, 0x22, 0x65, 0x94, 0x2e, 0xd4, 0x58, 0xa7, - 0x0d, 0x6b, 0xcd, 0x84, 0x67, 0xc7, 0xd9, 0x42, 0x0b, 0x2b, 0xd4, 0x63, - 0x67, 0x72, 0x48, 0x89, 0x28, 0xd4, 0x76, 0xbe, 0x2d, 0x94, 0xaa, 0x7a, - 0x8c, 0x6c, 0xb5, 0x05, 0x5c, 0x84, 0xa2, 0x90, 0x29, 0xb7, 0x6f, 0x4e, - 0x0d, 0x6c, 0x4a, 0x6c, 0xc0, 0x29, 0xb9, 0x20, 0x13, 0x69, 0x22, 0x48, - 0xdd, 0x42, 0x6e, 0xd8, 0x57, 0x8b, 0x74, 0x7f, 0xe6, 0x09, 0x23, 0x4e, - 0x1c, 0xfb, 0x03, 0x3b, 0xf3, 0xb1, 0xc8, 0x4d, 0x1a, 0xd9, 0x4b, 0xe5, - 0xb6, 0x46, 0xe1, 0x80, 0x84, 0x00, 0xc0, 0x7b, 0x7e, 0x78, 0x5e, 0x51, - 0x7c, 0x45, 0x8d, 0xec, 0x3d, 0xf0, 0xcd, 0x7d, 0x28, 0x02, 0x35, 0x88, - 0xdb, 0x3b, 0x7d, 0x13, 0x36, 0xf7, 0x02, 0x43, 0xf3, 0x35, 0x27, 0x85, - 0x6f, 0x6e, 0x45, 0x80, 0x07, 0x0f, 0xe6, 0x96, 0x13, 0x82, 0x7c, 0xec, - 0x40, 0x82, 0xc0, 0xe6, 0xe4, 0xea, 0xf9, 0x73, 0x94, 0x00, 0x67, 0x00, - 0xa6, 0xc9, 0xda, 0x41, 0x7f, 0x06, 0x7a, 0xeb, 0x7f, 0x34, 0xf7, 0x94, - 0x5f, 0x1c, 0x3c, 0x13, 0x3f, 0xe8, 0xa8, 0xde, 0xaf, 0xeb, 0x97, 0xfd, - 0xd6, 0xed, 0xb4, 0x21, 0x6c, 0x24, 0xb7, 0x43, 0xee, 0xe9, 0x7b, 0xcc, - 0xb4, 0x26, 0x79, 0xcb, 0x65, 0xf4, 0x1c, 0xd4, 0x80, 0x3a, 0xde, 0x54, - 0x0c, 0x20, 0xe7, 0xc3, 0xae, 0xe4, 0xa0, 0x53, 0x73, 0x3b, 0x0c, 0x74, - 0x9c, 0xca, 0x17, 0x6b, 0x57, 0x09, 0xf0, 0xe9, 0xe7, 0x3c, 0x6d, 0x6f, - 0x88, 0x26, 0x82, 0x17, 0xfc, 0x6e, 0x4f, 0x04, 0xa5, 0x56, 0xe9, 0x1b, - 0x37, 0x6c, 0xc6, 0xbc, 0x88, 0xfe, 0xc4, 0x4d, 0x7a, 0xc9, 0x50, 0x3a, - 0xc9, 0x29, 0x9b, 0x14, 0x28, 0x60, 0x4b, 0x75, 0x3f, 0xbd, 0x3f, 0x9f, - 0x39, 0xe6, 0x1b, 0x8a, 0xa7, 0x4b, 0x10, 0x65, 0x52, 0x82, 0xe0, 0xd6, - 0xf4, 0x26, 0x51, 0x78, 0x1d, 0x5b, 0x95, 0x0d, 0x53, 0x2b, 0x7e, 0x2f, - 0xe8, 0xf9, 0x9d, 0x47, 0xf6, 0x58, 0xe9, 0x30, 0xe2, 0xc3, 0xe1, 0x6d, - 0xdc, 0x50, 0x03, 0xdb, 0xcc, 0x94, 0x00, 0x5d, 0xe0, 0x07, 0xb6, 0x2f, - 0x97, 0xef, 0xc6, 0x3a, 0xc2, 0xc0, 0x99, 0xe7, 0x65, 0x89, 0x1b, 0x4e, - 0x59, 0x1f, 0xe7, 0xae, 0xc0, 0x1e, 0x61, 0x92, 0x5f, 0x55, 0xaa, 0x51, - 0xcc, 0xf6, 0x4e, 0x32, 0x56, 0x76, 0x99, 0x2b, 0x6e, 0xe8, 0x5c, 0xc9, - 0xe2, 0xa8, 0x78, 0x4b, 0x76, 0x85, 0xf3, 0x34, 0x5c, 0x52, 0x8e, 0xa5, - 0xed, 0x4a, 0x87, 0x9e, 0x3e, 0x90, 0x9b, 0xcf, 0xec, 0x57, 0x4b, 0x60, - 0x5a, 0xc9, 0x69, 0x0c, 0x63, 0x7a, 0x01, 0x26, 0x88, 0xb9, 0x32, 0x82, - 0x48, 0x02, 0x1b, 0x2c, 0xbe, 0x95, 0xb9, 0x2f, 0xe1, 0x4b, 0x6c, 0x4e, - 0x03, 0xdb, 0xc7, 0xce, 0xcf, 0x67, 0xf1, 0x1f, 0x83, 0xca, 0xb6, 0x20, - 0x06, 0xcd, 0xb8, 0xd9, 0xcb, 0x94, 0xb0, 0xa1, 0x88, 0xdc, 0xf9, 0x2c, - 0x4a, 0xb6, 0x85, 0x14, 0x42, 0x6c, 0xbb, 0x0d, 0x48, 0xd6, 0x51, 0x8f, - 0x21, 0x4a, 0xd4, 0x74, 0x6f, 0xdf, 0x89, 0x76, 0xf2, 0xe7, 0xcd, 0x32, - 0xc4, 0x4b, 0x52, 0xca, 0x5c, 0x08, 0x2c, 0x6b, 0x76, 0x88, 0xa4, 0x41, - 0x62, 0xed, 0x96, 0x71, 0xb0, 0xa4, 0x37, 0x2d, 0x91, 0x60, 0x69, 0x6d, - 0xee, 0x00, 0x18, 0x6f, 0x20, 0x0d, 0x48, 0xff, 0xd7, 0x2c, 0xb5, 0x4b, - 0x27, 0xf3, 0x91, 0xf3, 0x6a, 0x20, 0x04, 0xc5, 0x95, 0x10, 0x36, 0x0f, - 0x6f, 0x4c, 0x00, 0xc0, 0x57, 0x3e, 0xc0, 0x16, 0xcd, 0xba, 0x30, 0xcc, - 0x28, 0xed, 0xa7, 0xcf, 0x35, 0x94, 0xe0, 0xb6, 0x39, 0xdc, 0xb1, 0x25, - 0x09, 0x42, 0xd1, 0x8d, 0x7c, 0x87, 0x20, 0x53, 0x7b, 0xc0, 0x1b, 0x5d, - 0x00, 0x7f, 0xc3, 0xdf, 0xc6, 0xa1, 0x68, 0x61, 0x3c, 0xdb, 0x65, 0xf1, - 0x2d, 0xbd, 0xc3, 0x7c, 0x6c, 0x01, 0xa0, 0x9e, 0xd3, 0x9d, 0xd9, 0xd8, - 0xeb, 0x73, 0x5f, 0x76, 0xdd, 0x41, 0xe1, 0x6d, 0xcf, 0x00, 0x64, 0x44, - 0xea, 0x6c, 0x36, 0xdb, 0x40, 0x95, 0x2e, 0x9b, 0x42, 0x5b, 0x32, 0x36, - 0xba, 0x8b, 0x9b, 0x8e, 0xb4, 0x78, 0x6d, 0x87, 0x1e, 0xda, 0x08, 0xb3, - 0x75, 0x64, 0x6f, 0xeb, 0x3f, 0xcf, 0x7e, 0x85, 0x77, 0x8f, 0xcd, 0x55, - 0x87, 0x48, 0x75, 0x4a, 0x48, 0x6e, 0x00, 0xb0, 0x06, 0xe0, 0x07, 0xdc, - 0xd2, 0x33, 0xa7, 0x38, 0x54, 0x92, 0x1b, 0xa9, 0x5c, 0xa5, 0x64, 0x31, - 0x07, 0x37, 0x88, 0x00, 0x36, 0x20, 0x88, 0xa5, 0x8b, 0x90, 0xfc, 0xe2, - 0xcb, 0x24, 0x55, 0x01, 0xec, 0x6e, 0x37, 0xcf, 0xcf, 0xf0, 0x55, 0x99, - 0xf1, 0xe7, 0x4f, 0x77, 0x7b, 0x22, 0xc1, 0xab, 0x4f, 0x83, 0x23, 0x3f, - 0x8e, 0x37, 0x5c, 0x81, 0xf0, 0xea, 0x95, 0x0b, 0xad, 0x5c, 0x65, 0x41, - 0xad, 0xc0, 0x02, 0xe1, 0x53, 0xfc, 0x2a, 0x6b, 0xe8, 0x6d, 0xd7, 0x86, - 0xa1, 0x4d, 0xdc, 0x23, 0x00, 0x3c, 0xe8, 0x01, 0xb8, 0x03, 0x8f, 0x3e, - 0xfd, 0xf9, 0xda, 0x51, 0xb3, 0x99, 0xce, 0xd8, 0x71, 0x43, 0x46, 0x64, - 0x6f, 0x82, 0x11, 0x25, 0x11, 0xb9, 0x74, 0x0f, 0x1d, 0x46, 0x37, 0xb1, - 0x00, 0x68, 0x44, 0xa0, 0x0e, 0xc4, 0x60, 0x9f, 0x9e, 0xcc, 0x5b, 0x35, - 0xff, 0x9d, 0xd4, 0x37, 0x00, 0xc2, 0x7e, 0x14, 0x38, 0xa3, 0xe8, 0x5b, - 0x6f, 0xe4, 0x41, 0xb2, 0x46, 0x84, 0x8f, 0x49, 0x11, 0x80, 0x00, 0x00, - 0x01, 0x04, 0x43, 0xf9, 0x8e, 0xd8, 0xe7, 0x69, 0x90, 0x2f, 0x79, 0x44, - 0x6c, 0xf5, 0xf4, 0x47, 0x79, 0x4e, 0x1e, 0xb2, 0x59, 0x54, 0x21, 0x18, - 0x3d, 0xd3, 0x49, 0x98, 0x1a, 0x07, 0x35, 0x22, 0x72, 0x71, 0xd1, 0x70, - 0xe2, 0xd5, 0x75, 0x0a, 0x50, 0xd6, 0xf3, 0x52, 0xc6, 0xf1, 0xd1, 0xbc, - 0xba, 0xa0, 0x16, 0x17, 0xea, 0x39, 0xb4, 0x7c, 0xd3, 0x0d, 0x92, 0x8f, - 0x92, 0x27, 0x8b, 0x58, 0x28, 0x9f, 0xbc, 0xcd, 0xba, 0x52, 0x87, 0x5c, - 0x52, 0xdb, 0x41, 0x13, 0xb9, 0xcc, 0x42, 0x74, 0xa3, 0xeb, 0x86, 0x6d, - 0x55, 0x3a, 0xd6, 0x71, 0xf2, 0x2a, 0x33, 0xa3, 0x9b, 0xf2, 0xde, 0xee, - 0xd7, 0x3e, 0x15, 0x95, 0x81, 0x1f, 0x8d, 0xe4, 0x44, 0xba, 0x14, 0x7c, - 0xb2, 0xb7, 0xb1, 0x10, 0xab, 0x32, 0xdf, 0x09, 0x15, 0x5b, 0xb3, 0xda, - 0xfd, 0x79, 0x12, 0xb9, 0x28, 0x45, 0x92, 0x42, 0x13, 0x72, 0xcb, 0x16, - 0x12, 0x58, 0x54, 0x46, 0xfc, 0x88, 0x03, 0xf4, 0xb4, 0x9f, 0x54, 0x05, - 0x51, 0x7c, 0x9d, 0xe2, 0xa8, 0x58, 0x59, 0x6c, 0xa2, 0x93, 0xda, 0x1b, - 0xa8, 0x13, 0xb2, 0xc5, 0x6f, 0x47, 0x25, 0x15, 0xce, 0x5c, 0xa0, 0x94, - 0x01, 0x19, 0x6d, 0x04, 0xbf, 0xfd, 0x56, 0xf1, 0xd0, 0x0c, 0x15, 0x6f, - 0xa3, 0x77, 0x0f, 0x56, 0xd0, 0xe6, 0xe8, 0xb3, 0xcf, 0xac, 0xd4, 0xf5, - 0x29, 0xba, 0x1b, 0xf8, 0x39, 0xb0, 0xcc, 0x9f, 0x3a, 0xe9, 0xa4, 0x26, - 0xee, 0xbf, 0x3f, 0x09, 0x08, 0x6d, 0x34, 0xb9, 0x5a, 0x1b, 0xe4, 0xb7, - 0x53, 0xd8, 0x10, 0xbf, 0xdf, 0x98, 0x4b, 0xd8, 0xb3, 0xc5, 0xa8, 0xef, - 0x3c, 0xae, 0xc5, 0x08, 0x59, 0x49, 0x32, 0x8c, 0x6e, 0x74, 0x2e, 0xd2, - 0x4b, 0x21, 0xac, 0x37, 0xf5, 0x69, 0xf9, 0x52, 0x5c, 0x88, 0x4b, 0x6c, - 0x4f, 0xa0, 0x16, 0xf3, 0xe7, 0x68, 0x04, 0x1b, 0x8b, 0xe2, 0x91, 0x09, - 0x0c, 0xb9, 0x00, 0x0d, 0xf0, 0x5c, 0x04, 0xcf, 0xfd, 0x5a, 0x49, 0x67, - 0xe1, 0x31, 0xfc, 0x19, 0xb4, 0x30, 0xd7, 0x1b, 0x3d, 0x14, 0xef, 0x14, - 0xac, 0xc6, 0x23, 0x41, 0xe0, 0x73, 0x7e, 0x53, 0x78, 0xdf, 0xb7, 0x3f, - 0x1c, 0x73, 0x20, 0x6a, 0xe6, 0x72, 0x60, 0xe2, 0x62, 0xa5, 0xf5, 0x6d, - 0xbf, 0x6c, 0x84, 0x7f, 0xad, 0x4e, 0x2c, 0x80, 0x4e, 0xf3, 0x32, 0xe6, - 0xc3, 0xe9, 0x49, 0x06, 0xb6, 0x69, 0xc6, 0x4f, 0x8e, 0x04, 0x3d, 0xf3, - 0x29, 0x36, 0x5e, 0x73, 0x7c, 0xcc, 0x96, 0x2a, 0x15, 0x51, 0x67, 0x85, - 0x8d, 0x89, 0xfa, 0x7c, 0x84, 0x39, 0x80, 0x5b, 0x3b, 0x52, 0x54, 0x6f, - 0x57, 0x69, 0xb9, 0xb6, 0x37, 0xf4, 0x70, 0x07, 0x22, 0xe7, 0xc7, 0xdb, - 0x78, 0x7b, 0xc2, 0x73, 0x2c, 0xb1, 0x17, 0xf1, 0x1b, 0xe7, 0x3f, 0x7e, - 0xb7, 0xfc, 0x47, 0x9e, 0x41, 0x17, 0x28, 0xed, 0x3a, 0xc6, 0xf7, 0xbf, - 0xe7, 0x82, 0x0f, 0xf6, 0x4a, 0x2e, 0x00, 0x41, 0xba, 0xb7, 0x28, 0x5b, - 0x7b, 0xad, 0xda, 0x4e, 0xb7, 0x25, 0x0c, 0xb5, 0x0a, 0x6e, 0x5c, 0x8b, - 0xb2, 0xc6, 0xe1, 0xe3, 0x10, 0x5c, 0xb2, 0x04, 0x2b, 0x7f, 0x9e, 0x2d, - 0xf3, 0xf3, 0x03, 0x87, 0x86, 0x96, 0xdd, 0x61, 0x38, 0xed, 0x77, 0xcc, - 0x35, 0x60, 0xfb, 0x64, 0xa6, 0x0d, 0x1f, 0x69, 0x6d, 0x39, 0xb4, 0x01, - 0xb0, 0x9f, 0xf7, 0x2f, 0xd0, 0x9d, 0x7f, 0x0a, 0xeb, 0x69, 0xe0, 0x4c, - 0xa8, 0xdd, 0x27, 0x15, 0x9d, 0xed, 0x0b, 0x57, 0xea, 0x96, 0x03, 0x26, - 0xd2, 0x2b, 0xa2, 0x90, 0xf6, 0x36, 0xf0, 0x0c, 0x4b, 0x00, 0x06, 0x72, - 0xb7, 0xa6, 0x02, 0x17, 0xf8, 0x91, 0x63, 0xa4, 0x80, 0x3d, 0x37, 0xdf, - 0x78, 0x33, 0x21, 0xe4, 0xd5, 0x2a, 0x20, 0x4b, 0x7d, 0x7b, 0xe6, 0x02, - 0x0f, 0xf5, 0x80, 0x2c, 0xfe, 0x66, 0x89, 0xe2, 0x69, 0x59, 0x9b, 0xef, - 0xed, 0xe7, 0x27, 0x91, 0xf6, 0x93, 0xf6, 0x54, 0xa0, 0x11, 0x4b, 0x5b, - 0xe5, 0x30, 0x10, 0xbf, 0xea, 0xbe, 0xd8, 0x37, 0xf5, 0x62, 0x6d, 0xbe, - 0x0d, 0xd8, 0xfa, 0x7f, 0xb8, 0x00, 0x77, 0xef, 0x9e, 0x69, 0x47, 0xa3, - 0xb8, 0xf3, 0xc8, 0x32, 0x87, 0xe9, 0x52, 0x2b, 0x73, 0xce, 0x6e, 0x26, - 0x45, 0x08, 0x2d, 0xb8, 0xf2, 0xa2, 0x23, 0x7e, 0xbf, 0x1f, 0x9b, 0x73, - 0x53, 0x60, 0x4c, 0x29, 0x46, 0x52, 0xdb, 0xa4, 0x00, 0xa4, 0x8b, 0x9f, - 0x7e, 0x05, 0x88, 0x9a, 0xe9, 0x46, 0x51, 0x5f, 0x4f, 0x73, 0x37, 0xcc, - 0xf9, 0xfa, 0x85, 0xa9, 0xe3, 0x9b, 0xe7, 0x22, 0xe0, 0x01, 0xf6, 0x8a, - 0x8f, 0xd0, 0x9b, 0x78, 0xc4, 0x2c, 0x04, 0x68, 0x53, 0x7b, 0x5a, 0xa4, - 0x52, 0x0e, 0x4d, 0x30, 0x05, 0x7c, 0xae, 0x9e, 0x1d, 0x60, 0xd0, 0xb6, - 0xf2, 0x72, 0x82, 0x17, 0xfd, 0x57, 0x5c, 0x81, 0xb7, 0x4c, 0x29, 0xb0, - 0x85, 0xec, 0x2b, 0xc6, 0x46, 0xf3, 0x80, 0x14, 0xf0, 0xf0, 0x07, 0x3f, - 0x4e, 0x7d, 0xb1, 0xd0, 0x27, 0x7a, 0x7e, 0x2b, 0xa5, 0x2e, 0x15, 0x29, - 0xd5, 0xb2, 0xfc, 0x3e, 0x00, 0x3a, 0xf7, 0xbb, 0x64, 0x41, 0xdd, 0x3a, - 0x2e, 0x21, 0xc7, 0x16, 0xaa, 0x17, 0x55, 0xbe, 0xac, 0x00, 0xab, 0xa7, - 0x7c, 0x80, 0x57, 0xbd, 0xbf, 0x68, 0x11, 0xf9, 0xd0, 0xfc, 0x29, 0x00, - 0x8a, 0x34, 0x92, 0xdf, 0x37, 0x00, 0x75, 0xed, 0xee, 0x00, 0xfb, 0xdb, - 0x33, 0xa8, 0x47, 0xed, 0xf6, 0x2e, 0x87, 0x1d, 0x31, 0xce, 0x88, 0x54, - 0x29, 0xbd, 0x47, 0x3e, 0x0b, 0x15, 0x33, 0x4c, 0x09, 0x2e, 0xa5, 0xbe, - 0x2d, 0xbe, 0x6a, 0xc2, 0xd0, 0x25, 0xbf, 0x9b, 0x57, 0x66, 0xf0, 0x63, - 0xb2, 0x05, 0x0f, 0x0b, 0x6d, 0x2f, 0x2e, 0xd0, 0x29, 0xb6, 0x88, 0xdd, - 0xeb, 0x80, 0x09, 0xec, 0x2c, 0x07, 0xb6, 0x4f, 0x16, 0x8e, 0x12, 0x08, - 0x3f, 0xd8, 0x00, 0xfb, 0x39, 0x4a, 0x3d, 0x60, 0x8e, 0x64, 0xd7, 0x14, - 0xb0, 0xed, 0x2e, 0x5b, 0x43, 0x28, 0xe6, 0xdc, 0xc5, 0x80, 0x53, 0x4c, - 0x94, 0xb4, 0x6f, 0x29, 0x1b, 0x9b, 0x7e, 0xa4, 0xe3, 0x32, 0xd4, 0x8b, - 0x78, 0x8f, 0x4e, 0x4d, 0x01, 0xc2, 0x98, 0x6a, 0x0d, 0x2c, 0xf0, 0xc5, - 0x6f, 0x68, 0x22, 0xf6, 0x23, 0xe9, 0x05, 0x5e, 0xf2, 0x8e, 0xab, 0xd6, - 0xba, 0x2c, 0x0f, 0x85, 0x4b, 0x0a, 0x94, 0x28, 0x7b, 0x69, 0x00, 0x5e, - 0x4f, 0x00, 0x6a, 0x00, 0xe3, 0xdb, 0xb1, 0x79, 0xb4, 0x73, 0x85, 0x93, - 0xd7, 0x8e, 0x7b, 0x3f, 0x2a, 0x6c, 0x40, 0x1c, 0x51, 0x8d, 0xfa, 0x34, - 0x01, 0x0f, 0xdf, 0x5f, 0x44, 0x89, 0xcc, 0x90, 0xbb, 0x43, 0xde, 0xf2, - 0xc7, 0xdf, 0x5a, 0xd4, 0x2c, 0xae, 0x34, 0xbf, 0x06, 0xd9, 0xe5, 0xbb, - 0x4b, 0x6f, 0xf2, 0x77, 0x29, 0xc4, 0x85, 0xb6, 0x7e, 0xe2, 0xd8, 0x8d, - 0xfa, 0xc8, 0x00, 0x9c, 0x01, 0xc8, 0xbd, 0xd8, 0x1d, 0x1d, 0x90, 0x98, - 0x12, 0xd9, 0x40, 0x08, 0x7f, 0xfa, 0x46, 0x11, 0x49, 0xe2, 0x64, 0x2a, - 0x79, 0x98, 0xb4, 0xab, 0x4a, 0x8d, 0x98, 0x9e, 0x25, 0xb4, 0xf6, 0x5d, - 0xba, 0x55, 0x3d, 0xbf, 0x9b, 0x80, 0x3b, 0xf8, 0x70, 0x02, 0xf2, 0x30, - 0x03, 0xbb, 0xde, 0xad, 0xa5, 0x66, 0x80, 0x1e, 0x4e, 0x26, 0xbb, 0x50, - 0xba, 0x7e, 0xd4, 0x48, 0x58, 0x4b, 0x79, 0xa2, 0x27, 0x0f, 0xf7, 0xeb, - 0x48, 0xfd, 0x5a, 0x32, 0xc4, 0xeb, 0x72, 0x2c, 0x38, 0xed, 0xb5, 0x61, - 0x0a, 0x37, 0xe9, 0x7f, 0x9d, 0xbf, 0x5f, 0xef, 0xb8, 0xbd, 0xf5, 0xed, - 0xf6, 0xc8, 0x15, 0x87, 0x48, 0x14, 0xdf, 0x9f, 0x80, 0x1e, 0xf5, 0xa0, - 0x05, 0x14, 0x8d, 0xec, 0x2c, 0xe2, 0xe3, 0xed, 0xc1, 0x0e, 0x79, 0x47, - 0x13, 0x0b, 0xa9, 0xe0, 0x5a, 0xb4, 0x8b, 0xa4, 0xe3, 0x4e, 0x0a, 0x4b, - 0x63, 0x3e, 0x7f, 0x0a, 0x4a, 0xa7, 0x37, 0xcd, 0xfb, 0xb9, 0xc2, 0xdd, - 0xc6, 0xeb, 0xec, 0x1b, 0x92, 0x59, 0xfb, 0x39, 0xbe, 0x96, 0x00, 0xfc, - 0x5e, 0x09, 0xf7, 0x13, 0x38, 0xe8, 0x6a, 0x68, 0x05, 0x44, 0xcc, 0x7d, - 0x01, 0x5e, 0xd2, 0x8e, 0x1a, 0xad, 0xf3, 0x5f, 0xee, 0x7b, 0x7d, 0x44, - 0x5d, 0x15, 0x62, 0x25, 0x9b, 0xa1, 0x86, 0x14, 0x6f, 0x89, 0x41, 0x25, - 0x56, 0xfb, 0x57, 0xf0, 0x8b, 0x84, 0x5f, 0xbf, 0x7b, 0xc6, 0x8c, 0x47, - 0x64, 0x87, 0x3a, 0x21, 0x54, 0x7d, 0x3d, 0xb8, 0x7b, 0x78, 0x05, 0xa4, - 0xc9, 0xa1, 0x91, 0x1a, 0x1f, 0xa4, 0xfa, 0x52, 0xb7, 0xe4, 0x88, 0x00, - 0x15, 0x0a, 0x16, 0x96, 0xac, 0x55, 0x7d, 0x7e, 0x99, 0x86, 0xd2, 0xce, - 0xb0, 0x6d, 0x09, 0x6f, 0x19, 0xe7, 0x3d, 0xac, 0x8e, 0x7e, 0xd5, 0x36, - 0x9f, 0x86, 0xd5, 0x0b, 0x6f, 0x60, 0x00, 0xe8, 0x8b, 0x08, 0xc8, 0xfd, - 0x99, 0xa5, 0x96, 0xeb, 0x26, 0x45, 0x0b, 0xaa, 0x73, 0x7c, 0x9f, 0xda, - 0xd0, 0x06, 0xdf, 0x42, 0x27, 0x62, 0xc0, 0x45, 0xe6, 0xfb, 0x56, 0x0c, - 0x26, 0x4b, 0x0a, 0x2d, 0xa7, 0x93, 0x27, 0x42, 0x16, 0x0f, 0x53, 0x69, - 0xd0, 0x69, 0xc5, 0xb7, 0x3d, 0xb2, 0x4c, 0x58, 0xdf, 0x24, 0x01, 0xf9, - 0x3b, 0xa1, 0x04, 0x6e, 0xc4, 0xfc, 0x6a, 0x5b, 0x3c, 0xe3, 0xb7, 0x83, - 0x43, 0xe0, 0x65, 0xb0, 0xab, 0x65, 0x46, 0xfd, 0x38, 0x00, 0x8c, 0x8a, - 0x08, 0x3f, 0xcc, 0x00, 0xfc, 0x8e, 0xf0, 0x0b, 0x34, 0x11, 0xc0, 0x13, - 0x8f, 0x20, 0x31, 0x0a, 0x53, 0xb4, 0x7e, 0x9f, 0xe8, 0xde, 0x0f, 0xfb, - 0xcd, 0x00, 0x4a, 0x47, 0xd7, 0x79, 0x41, 0xf8, 0x01, 0x66, 0x49, 0x6e, - 0xd3, 0xc0, 0x72, 0x19, 0x09, 0x2d, 0xef, 0xdd, 0x1d, 0x04, 0xbe, 0x19, - 0x80, 0x2b, 0xc7, 0x07, 0x6a, 0x0e, 0x45, 0x43, 0x9b, 0xd6, 0xe3, 0x6f, - 0x39, 0x15, 0x60, 0xca, 0x6c, 0xab, 0x47, 0x37, 0x6c, 0xa6, 0xd6, 0x00, - 0x00, 0x01, 0x05, 0x43, 0xf9, 0x7d, 0x74, 0xbc, 0x58, 0xed, 0x01, 0x5e, - 0xd0, 0x82, 0x99, 0x05, 0xde, 0x29, 0x32, 0x84, 0xea, 0x9f, 0x46, 0x37, - 0x4e, 0x3e, 0x5b, 0x4c, 0xb6, 0x0e, 0x68, 0x2b, 0xdd, 0xc6, 0x95, 0x92, - 0xc5, 0x4d, 0xf0, 0x6e, 0x02, 0x9b, 0xc7, 0xc5, 0xd3, 0xa3, 0x7c, 0xf1, - 0x6e, 0xbb, 0x25, 0x90, 0x22, 0x69, 0xb2, 0x21, 0x46, 0xb3, 0x0b, 0xe7, - 0x9a, 0xfd, 0x76, 0x5a, 0xa6, 0xcf, 0x38, 0x8e, 0x9b, 0xa7, 0x19, 0x50, - 0xc8, 0xdd, 0x93, 0x43, 0x9e, 0x1e, 0xed, 0xb1, 0x66, 0x07, 0x2a, 0xa5, - 0x6d, 0xbb, 0x45, 0xba, 0x7d, 0x44, 0xce, 0x3b, 0xd2, 0xe5, 0x9d, 0x47, - 0xd7, 0x75, 0x77, 0x89, 0x15, 0x0f, 0x02, 0x75, 0xb9, 0x4d, 0x27, 0x45, - 0x3d, 0xb7, 0x2e, 0xa8, 0x1c, 0xdf, 0x96, 0xda, 0x6d, 0x88, 0xde, 0xcd, - 0xdc, 0x80, 0x1f, 0xf2, 0xfc, 0x92, 0x41, 0xf5, 0xf1, 0x02, 0xe0, 0xda, - 0x84, 0x36, 0xf2, 0xdc, 0x97, 0xc7, 0x04, 0x8b, 0x1b, 0x03, 0x9d, 0x05, - 0x7b, 0xf4, 0x6d, 0x9e, 0x18, 0x85, 0xb4, 0x5a, 0x38, 0x86, 0xdc, 0xd4, - 0xa9, 0x1b, 0xeb, 0x67, 0x37, 0xfd, 0xd6, 0x3b, 0xb7, 0xe4, 0x2c, 0xcc, - 0xd7, 0x98, 0x8f, 0xb2, 0x15, 0x0b, 0x44, 0x54, 0x6f, 0x1a, 0x08, 0x60, - 0x0d, 0x55, 0xbb, 0x02, 0x2a, 0xe5, 0xf2, 0xf4, 0x36, 0xd4, 0x6e, 0x56, - 0xc3, 0x1d, 0x29, 0x2f, 0x25, 0x6f, 0x42, 0x50, 0xea, 0xa4, 0x36, 0xd8, - 0x7b, 0x7b, 0xc4, 0x82, 0x17, 0xfa, 0xd7, 0xe4, 0x40, 0xb4, 0x46, 0xb4, - 0x8d, 0xd6, 0xf5, 0xa6, 0xbe, 0xd1, 0x85, 0x41, 0xed, 0xe8, 0x2a, 0xe5, - 0xe7, 0x49, 0x76, 0xda, 0xde, 0x66, 0x54, 0x73, 0xac, 0xbe, 0x3a, 0x89, - 0xe2, 0x39, 0xae, 0x87, 0x69, 0xed, 0x27, 0x37, 0xb4, 0x45, 0x00, 0x3e, - 0x84, 0x5e, 0x57, 0x01, 0x20, 0x00, 0xf9, 0x99, 0x38, 0x9e, 0x0a, 0x5c, - 0x21, 0x37, 0x9b, 0x81, 0xcd, 0xdb, 0xe9, 0xf3, 0xfd, 0xc7, 0x1e, 0x72, - 0x51, 0xb2, 0x58, 0xdc, 0x22, 0x63, 0x72, 0x8d, 0xac, 0xce, 0x6f, 0xd2, - 0x11, 0xb8, 0x04, 0x1f, 0xed, 0xc1, 0x1d, 0xca, 0x13, 0xe7, 0xbb, 0x56, - 0x0c, 0x19, 0x31, 0xaf, 0xc5, 0x00, 0x74, 0xf2, 0x31, 0x88, 0x1b, 0x37, - 0xbf, 0x3b, 0x76, 0x1e, 0x03, 0x88, 0x52, 0xa3, 0x72, 0xf9, 0x40, 0x07, - 0x3b, 0xf1, 0x99, 0x60, 0x4c, 0x32, 0xdb, 0x28, 0x4a, 0xa9, 0x2e, 0x35, - 0x9c, 0x60, 0x20, 0x80, 0x9f, 0x5e, 0xd2, 0xcf, 0x1e, 0x05, 0xc5, 0xf0, - 0xbc, 0x92, 0x1b, 0x53, 0xdb, 0xaa, 0xad, 0x45, 0x21, 0xab, 0x7b, 0xf7, - 0x99, 0xcf, 0x1b, 0x0c, 0xca, 0x39, 0x3d, 0xb5, 0xd3, 0x28, 0xca, 0x76, - 0xd2, 0xe9, 0x66, 0x36, 0x57, 0x99, 0xf1, 0xcd, 0xbe, 0x55, 0x3f, 0x69, - 0x66, 0xc1, 0xaa, 0x3e, 0x01, 0xcd, 0xe8, 0xfa, 0x7e, 0x80, 0x33, 0xc2, - 0x7c, 0xf3, 0x0a, 0xe1, 0xd6, 0x63, 0xa8, 0x0a, 0xe4, 0xb6, 0x94, 0x10, - 0x18, 0xd9, 0x79, 0xdb, 0xf4, 0xa2, 0x75, 0xf4, 0x2a, 0x7c, 0x9b, 0x84, - 0x38, 0x8a, 0xda, 0x35, 0xe7, 0xe4, 0xca, 0x4a, 0x6f, 0x85, 0xd0, 0x21, - 0x7f, 0xd3, 0xd7, 0x77, 0xc2, 0x18, 0xb7, 0xc2, 0xd6, 0xfa, 0xef, 0xd2, - 0xcf, 0xf8, 0x8d, 0x45, 0x01, 0x14, 0xb2, 0xc8, 0x34, 0x63, 0x7c, 0x75, - 0x17, 0x72, 0x12, 0xa2, 0x92, 0x0e, 0x6e, 0x8d, 0x90, 0x5f, 0x3a, 0xed, - 0x30, 0x2a, 0x3e, 0x36, 0x1a, 0x1d, 0x1b, 0x7e, 0x40, 0xc7, 0x56, 0xfa, - 0x46, 0xee, 0xd8, 0x08, 0x20, 0x27, 0x40, 0x1c, 0x79, 0x4a, 0x17, 0xd6, - 0x3e, 0xda, 0x17, 0x36, 0x55, 0xa1, 0x4d, 0xec, 0x85, 0xcd, 0xf7, 0x17, - 0xbc, 0x10, 0x2d, 0x2f, 0x6d, 0x0f, 0xc7, 0x9a, 0xf1, 0x87, 0x06, 0x50, - 0x96, 0xf0, 0xfd, 0x02, 0x10, 0x06, 0x8a, 0xe8, 0x41, 0x0b, 0x63, 0xf7, - 0x3c, 0x26, 0xd6, 0xf7, 0x3f, 0xcd, 0x84, 0x7d, 0x12, 0x84, 0x3b, 0x57, - 0xc4, 0x7f, 0xab, 0x71, 0x4c, 0x00, 0xab, 0x76, 0x5f, 0x57, 0xa5, 0xcf, - 0x16, 0xe4, 0xb8, 0x40, 0xd7, 0x80, 0x0c, 0x6a, 0xb7, 0xe7, 0xb5, 0xd5, - 0xd7, 0x8e, 0x28, 0xc4, 0x57, 0xc9, 0x4e, 0xb4, 0xba, 0x5d, 0x6f, 0xa0, - 0xe6, 0x0b, 0xff, 0x8a, 0x17, 0x79, 0xf2, 0x59, 0x2c, 0x37, 0x3a, 0xe6, - 0xba, 0x18, 0x7c, 0x2e, 0x01, 0xed, 0xe5, 0xba, 0xe4, 0x00, 0xe3, 0xa1, - 0x7d, 0x3e, 0xd8, 0x3c, 0xed, 0xb2, 0x85, 0x18, 0x5b, 0x7a, 0x3c, 0x73, - 0xc1, 0x03, 0xf3, 0x39, 0xe2, 0xd9, 0x88, 0x71, 0x3b, 0xbe, 0x3c, 0xe9, - 0x67, 0xc0, 0xe2, 0xe0, 0x14, 0xd9, 0x77, 0x41, 0x08, 0x01, 0xab, 0xe2, - 0x10, 0x9b, 0x91, 0xe0, 0x67, 0x89, 0x72, 0xb7, 0xe4, 0x7e, 0x3a, 0x00, - 0xb3, 0x5d, 0x85, 0xd9, 0x6c, 0x52, 0x8b, 0xbe, 0xb0, 0x08, 0x6e, 0x98, - 0x03, 0xed, 0x78, 0x03, 0xf1, 0x66, 0x3b, 0x8c, 0x83, 0x97, 0x30, 0x9a, - 0x5a, 0x40, 0xe9, 0x6c, 0x3e, 0x86, 0xb7, 0xe9, 0x10, 0x40, 0xfd, 0x40, - 0x07, 0x3d, 0xf0, 0x00, 0xf3, 0x8f, 0x61, 0x5a, 0xec, 0x85, 0xf2, 0xff, - 0x24, 0x29, 0xc6, 0x87, 0x7e, 0x83, 0x24, 0x6d, 0x60, 0x04, 0xa0, 0x0e, - 0x7d, 0xfa, 0x17, 0xb8, 0xf9, 0xe5, 0x92, 0x4c, 0x97, 0xcd, 0xf9, 0x13, - 0x6d, 0x32, 0x1c, 0xdd, 0x9f, 0x27, 0xad, 0x50, 0xb6, 0xea, 0x16, 0x7c, - 0xb5, 0x5b, 0xfc, 0xda, 0x00, 0xf3, 0xe3, 0xbe, 0x39, 0xf2, 0xe1, 0xef, - 0xe4, 0xb5, 0xcc, 0x78, 0x01, 0xf3, 0x88, 0x3b, 0xe5, 0x09, 0xf2, 0x42, - 0xac, 0x4b, 0x54, 0x7d, 0xad, 0xd4, 0xe2, 0xec, 0x15, 0xb8, 0x64, 0x08, - 0xb9, 0xb4, 0xf1, 0x9e, 0x10, 0x2d, 0xbe, 0xb6, 0x00, 0x8f, 0xa8, 0x00, - 0xc0, 0x01, 0x16, 0xef, 0x3c, 0xf2, 0x85, 0xf9, 0x63, 0xc4, 0x8b, 0x72, - 0x53, 0x43, 0xcb, 0x5c, 0x52, 0x4b, 0x6e, 0x04, 0x0f, 0xd3, 0x00, 0xb3, - 0x28, 0xbe, 0xdf, 0x75, 0xf2, 0x1d, 0x15, 0x6c, 0x8d, 0xbb, 0xe5, 0xba, - 0xb7, 0xd6, 0x42, 0x98, 0xee, 0x79, 0x6c, 0xb6, 0x37, 0xf8, 0xdd, 0xd8, - 0x00, 0x26, 0x5a, 0x09, 0x80, 0x06, 0xe9, 0x67, 0xab, 0x7d, 0x14, 0x10, - 0x3f, 0x38, 0x8c, 0x08, 0x3f, 0xae, 0x00, 0xf3, 0x04, 0x08, 0x23, 0xf0, - 0x84, 0xd3, 0x3e, 0x5f, 0xb2, 0x10, 0x38, 0x42, 0x7d, 0x85, 0x86, 0xb8, - 0x6b, 0x7e, 0xaa, 0x00, 0x27, 0x00, 0x7e, 0x2c, 0x01, 0xc8, 0x03, 0xb7, - 0x82, 0x10, 0x03, 0x3f, 0x6a, 0x4c, 0xeb, 0xae, 0xa9, 0x50, 0xcb, 0x4d, - 0xda, 0x81, 0x2d, 0xed, 0xb0, 0x3a, 0xd5, 0x6e, 0x9d, 0x2e, 0xb6, 0xda, - 0x5d, 0xa8, 0xde, 0x62, 0x28, 0x9e, 0x48, 0xbf, 0x71, 0x62, 0xc4, 0xf7, - 0xa0, 0x3d, 0xde, 0x5e, 0xfb, 0x74, 0x74, 0x85, 0x0e, 0x92, 0x23, 0x74, - 0xdb, 0x2e, 0x16, 0xc7, 0x22, 0x36, 0xcd, 0xab, 0x61, 0xd3, 0xcb, 0x69, - 0x21, 0xa7, 0x54, 0x83, 0xd5, 0x95, 0xb1, 0xe0, 0x21, 0x00, 0x35, 0xd6, - 0xc0, 0xe8, 0x00, 0x6f, 0x65, 0x9e, 0xb9, 0x24, 0x66, 0xc3, 0x70, 0x53, - 0xa8, 0x03, 0x0f, 0x7f, 0xaf, 0x5b, 0x1c, 0x5c, 0x57, 0xd2, 0x03, 0xec, - 0x93, 0x24, 0x2e, 0xa8, 0xe3, 0x83, 0x1b, 0xe6, 0xe6, 0x91, 0x1e, 0x44, - 0xfb, 0x80, 0x5a, 0xf1, 0x24, 0xd7, 0x16, 0xfa, 0xf9, 0x03, 0x89, 0x96, - 0x19, 0xb3, 0x03, 0x0a, 0x19, 0x1b, 0xed, 0x0a, 0x1d, 0x69, 0x21, 0xbf, - 0x18, 0xbd, 0xc0, 0x06, 0x8f, 0xf8, 0x7c, 0xa1, 0xab, 0x3e, 0x28, 0xa4, - 0x04, 0xb0, 0x03, 0x31, 0x47, 0x8e, 0x6f, 0x2e, 0x50, 0x03, 0xea, 0x92, - 0x78, 0xd2, 0xc9, 0x4d, 0xc9, 0x00, 0xc6, 0xa3, 0x7e, 0x9b, 0xfe, 0x2b, - 0x3b, 0xeb, 0x8b, 0xbd, 0xc1, 0xd7, 0x31, 0xcf, 0xd8, 0x62, 0x15, 0x2a, - 0x1c, 0x7b, 0x75, 0xb2, 0x76, 0x45, 0x17, 0xed, 0xbf, 0xee, 0x2e, 0x96, - 0x99, 0x8f, 0xd2, 0xe2, 0x42, 0xc7, 0x0d, 0x6e, 0x01, 0x13, 0x1c, 0x00, - 0xa4, 0x4f, 0xb7, 0x6e, 0xd8, 0x38, 0x02, 0x9d, 0xe1, 0x66, 0xd3, 0xd5, - 0x20, 0xd6, 0xfa, 0x8c, 0x17, 0x80, 0x0f, 0x38, 0x9f, 0x8c, 0xa9, 0x15, - 0x4d, 0xc9, 0x25, 0x1a, 0x31, 0x54, 0xa6, 0xf3, 0x9e, 0x9c, 0xcd, 0x58, - 0xa3, 0x91, 0x51, 0x28, 0x5b, 0x72, 0xd2, 0xe5, 0x95, 0xbc, 0x00, 0x0e, - 0x7e, 0xef, 0x23, 0x47, 0xe3, 0xf5, 0xce, 0x2a, 0x13, 0xc3, 0xd5, 0x14, - 0x04, 0x45, 0x29, 0x29, 0xbe, 0x72, 0x00, 0xf7, 0x0d, 0x17, 0xed, 0xc7, - 0x7c, 0x00, 0xaa, 0x4e, 0x35, 0xea, 0xf2, 0xc7, 0x42, 0xa9, 0x47, 0x9e, - 0xde, 0xf3, 0x3a, 0x7f, 0x3b, 0xcb, 0xd3, 0x06, 0x5c, 0x26, 0x96, 0xa3, - 0x0b, 0x43, 0xda, 0xae, 0xa7, 0xbf, 0x31, 0x34, 0xc4, 0x1b, 0x38, 0xbc, - 0x42, 0xae, 0xd0, 0xc5, 0x6e, 0xbd, 0xbb, 0xb2, 0xe1, 0xb4, 0x34, 0xc4, - 0x56, 0xa5, 0xa8, 0x8a, 0xdf, 0x40, 0x8d, 0x39, 0xfe, 0xf1, 0xcc, 0x94, - 0x68, 0x79, 0x99, 0xdd, 0x8e, 0x8a, 0x5a, 0xab, 0xa8, 0xd5, 0x29, 0xb9, - 0xc0, 0x0e, 0x05, 0x80, 0x19, 0x73, 0x3a, 0x31, 0x00, 0x25, 0x8f, 0xda, - 0x4c, 0x94, 0x38, 0xed, 0xf5, 0x6e, 0x48, 0x8e, 0x9f, 0xf1, 0xcb, 0xb7, - 0xad, 0xb4, 0x05, 0x7c, 0xc2, 0x60, 0xdf, 0x06, 0xf9, 0x71, 0xa0, 0x02, - 0x6d, 0x15, 0xaf, 0xb2, 0x0c, 0x86, 0xf1, 0xb2, 0xdf, 0x46, 0xc7, 0xb7, - 0x9a, 0x2c, 0xcb, 0xe9, 0x30, 0xa8, 0xa0, 0x53, 0x25, 0x31, 0xf5, 0x51, - 0x80, 0x00, 0x00, 0x01, 0x06, 0x43, 0xf8, 0xce, 0x95, 0xb6, 0x28, 0x43, - 0x6a, 0xca, 0xf1, 0x3b, 0x30, 0xc4, 0x1c, 0x79, 0x7e, 0x81, 0x8d, 0x9b, - 0x67, 0x9f, 0x09, 0x81, 0x4d, 0xd8, 0x13, 0x08, 0x2e, 0x3f, 0xc5, 0x5b, - 0xc6, 0x45, 0x6f, 0x08, 0x73, 0x68, 0x2b, 0x2b, 0xa4, 0xcc, 0xf1, 0xa3, - 0x47, 0x35, 0x3d, 0x3a, 0x3b, 0xad, 0x4b, 0x24, 0x1b, 0x55, 0xb6, 0x5d, - 0x00, 0xb2, 0xda, 0xb0, 0x31, 0x25, 0x2d, 0xb9, 0xe4, 0xdc, 0x6c, 0x49, - 0x92, 0x44, 0x65, 0x92, 0x45, 0xad, 0xf7, 0xb4, 0x10, 0xbf, 0xc8, 0x67, - 0xa3, 0x07, 0xf6, 0x40, 0x10, 0x23, 0x97, 0x58, 0x1b, 0x23, 0xbc, 0xd6, - 0xc0, 0x08, 0xd1, 0xba, 0xcf, 0x04, 0x2f, 0xf1, 0x36, 0x12, 0x9b, 0xc0, - 0x7b, 0x60, 0x21, 0x80, 0x53, 0xa0, 0x5a, 0x3b, 0x32, 0x97, 0xe1, 0x4b, - 0x6e, 0x95, 0x58, 0x50, 0x00, 0xd5, 0xac, 0xf6, 0xf6, 0x91, 0x64, 0x23, - 0x76, 0x9b, 0x9e, 0x2a, 0x8a, 0xd5, 0xa8, 0x01, 0xee, 0x3b, 0x24, 0xf5, - 0xa7, 0x85, 0x37, 0xab, 0xea, 0xdc, 0x76, 0xba, 0xa8, 0x4c, 0xaa, 0x93, - 0xc4, 0x63, 0x78, 0xc4, 0xbb, 0xce, 0x52, 0x87, 0x52, 0xa4, 0x54, 0x09, - 0x6d, 0x00, 0x4a, 0xe5, 0xf5, 0x46, 0xb1, 0xad, 0xfa, 0xd8, 0x1c, 0x68, - 0x16, 0xde, 0x33, 0x01, 0x08, 0x02, 0xbb, 0x76, 0x6a, 0xf8, 0xe4, 0x01, - 0xf3, 0x7a, 0x23, 0x29, 0x3b, 0x81, 0x66, 0xba, 0x86, 0xce, 0x5c, 0x74, - 0x3c, 0xf0, 0xc6, 0xf9, 0xe7, 0x40, 0x84, 0x00, 0xce, 0x10, 0x58, 0x5e, - 0xcd, 0xc5, 0xa3, 0x8b, 0x4a, 0x31, 0x87, 0x01, 0x8c, 0x9b, 0x48, 0x4d, - 0x67, 0xc6, 0xfa, 0xc7, 0x48, 0xd5, 0xd2, 0xa4, 0x6d, 0x52, 0x99, 0x24, - 0xbe, 0xa8, 0x8d, 0xd7, 0x12, 0xe7, 0xff, 0x5c, 0xee, 0x2e, 0x69, 0xf7, - 0xc9, 0x7c, 0xff, 0x63, 0x0a, 0x1e, 0xc9, 0x93, 0x75, 0x22, 0x7c, 0xd7, - 0x1e, 0x80, 0x12, 0x4b, 0xbc, 0xdd, 0xa7, 0x7e, 0x8e, 0x28, 0xf3, 0xca, - 0x6c, 0xef, 0xbe, 0x77, 0x99, 0x28, 0x51, 0x93, 0x64, 0x90, 0x05, 0x45, - 0x97, 0x02, 0x9b, 0xb0, 0x4e, 0x00, 0x34, 0x73, 0xfc, 0x94, 0xe5, 0xa8, - 0xe0, 0x17, 0xb5, 0x0e, 0x5b, 0x2b, 0xec, 0xa7, 0x9d, 0x31, 0xdd, 0x87, - 0xc3, 0xc7, 0xea, 0x7a, 0xb6, 0xa7, 0xab, 0x7a, 0x64, 0xd3, 0x63, 0x79, - 0x72, 0x80, 0x1b, 0xde, 0x72, 0xcc, 0x87, 0xad, 0xcd, 0xe5, 0x66, 0x05, - 0xdc, 0x90, 0x86, 0xde, 0x9d, 0xdb, 0x7d, 0x85, 0x09, 0x36, 0x4a, 0x04, - 0xdc, 0xe7, 0x79, 0x76, 0xda, 0x79, 0xfa, 0xf2, 0xe7, 0xa2, 0xb7, 0x0b, - 0x8b, 0x7e, 0xbb, 0x5d, 0xda, 0x2c, 0xa6, 0xe4, 0x20, 0x3d, 0xe5, 0x24, - 0x2e, 0xaa, 0x01, 0x07, 0x8c, 0x69, 0xa8, 0x2f, 0x45, 0x53, 0x29, 0xd4, - 0x3a, 0x8a, 0x7b, 0xc8, 0x45, 0x07, 0xd0, 0xa2, 0x9b, 0x43, 0x9a, 0x69, - 0x73, 0x1b, 0xaa, 0x55, 0x8a, 0x80, 0x11, 0x28, 0x0b, 0x9b, 0x4c, 0x03, - 0x2f, 0x88, 0x9e, 0x38, 0x57, 0x83, 0x63, 0xdf, 0xca, 0xc2, 0x5d, 0x95, - 0xba, 0xbc, 0x82, 0x10, 0x05, 0x3e, 0x44, 0x00, 0x87, 0x2e, 0x7a, 0x29, - 0x71, 0xa1, 0xbb, 0x9b, 0xc9, 0xd8, 0x7d, 0xc7, 0xe5, 0x08, 0xbe, 0x52, - 0xca, 0xdc, 0xc8, 0xbf, 0x4b, 0xef, 0x89, 0x06, 0xd2, 0xa7, 0x2b, 0x14, - 0x24, 0xa8, 0xde, 0xc7, 0x6c, 0x8e, 0x15, 0x24, 0x2c, 0x27, 0x05, 0x80, - 0x0c, 0x4e, 0x6c, 0x1d, 0xed, 0xe7, 0x8f, 0x3c, 0x81, 0x0b, 0xc4, 0xb4, - 0x0a, 0x56, 0x4d, 0x34, 0x3a, 0x56, 0xfc, 0x87, 0xe3, 0xdd, 0x4c, 0xe6, - 0xc3, 0xf3, 0x0d, 0xb8, 0x90, 0xb2, 0x91, 0x5b, 0xef, 0x8e, 0x78, 0xa0, - 0x40, 0xfd, 0x31, 0x60, 0x0f, 0x3b, 0xd7, 0x28, 0x0f, 0x77, 0x97, 0x72, - 0x36, 0x96, 0x57, 0x92, 0xb7, 0xc6, 0x5d, 0xef, 0x99, 0xaf, 0x7f, 0x0f, - 0x2c, 0xbc, 0xfc, 0x29, 0xdb, 0x49, 0xa5, 0xb5, 0x5e, 0xd9, 0x9f, 0xf2, - 0x38, 0x8e, 0x39, 0xb2, 0x06, 0x3b, 0x9e, 0x66, 0x68, 0xe0, 0xd1, 0xa1, - 0x2c, 0x17, 0xb5, 0xbc, 0xb1, 0xb2, 0x37, 0xfd, 0x08, 0xfb, 0x71, 0xdb, - 0xf7, 0xe0, 0x5c, 0xb1, 0x01, 0x14, 0x01, 0x39, 0x2e, 0x59, 0x65, 0xf1, - 0x66, 0xff, 0x60, 0xb7, 0x67, 0xc7, 0xbd, 0xcc, 0x4a, 0x08, 0x80, 0x09, - 0xb6, 0x24, 0xb5, 0x42, 0x46, 0xb7, 0xce, 0x00, 0x09, 0xb6, 0x80, 0x2d, - 0x00, 0x75, 0xef, 0xaf, 0xa1, 0x86, 0x88, 0x73, 0xec, 0x4a, 0x14, 0x3a, - 0x84, 0x37, 0xd0, 0xfd, 0xb2, 0xf6, 0xee, 0x6c, 0x4a, 0x02, 0xad, 0x2b, - 0x14, 0x20, 0x73, 0x74, 0x94, 0x03, 0x46, 0xec, 0x0c, 0x6f, 0xd4, 0xdd, - 0x27, 0xda, 0x6b, 0x3e, 0x53, 0x35, 0xb0, 0xe0, 0x05, 0x36, 0xb5, 0xd2, - 0x93, 0xa5, 0x24, 0xb5, 0xc6, 0x51, 0xbb, 0x9d, 0x5b, 0x0e, 0x01, 0x89, - 0x09, 0x2d, 0x44, 0x86, 0x56, 0xa7, 0x0a, 0x67, 0x19, 0x37, 0xbc, 0x9a, - 0xd7, 0x4a, 0x5b, 0x62, 0x9f, 0x9c, 0x6d, 0x54, 0x3a, 0x56, 0x6c, 0xdb, - 0xe2, 0xf0, 0x08, 0x40, 0x13, 0x15, 0xab, 0x00, 0x9f, 0x61, 0x25, 0xb3, - 0x00, 0xe0, 0x9c, 0x84, 0xb6, 0xdc, 0xab, 0x76, 0x40, 0xa5, 0xcb, 0xb2, - 0x10, 0x9a, 0x20, 0x75, 0xb0, 0x94, 0xc1, 0xd6, 0xb7, 0xdb, 0x77, 0xe6, - 0x21, 0x2d, 0xbe, 0x20, 0x00, 0xaf, 0x8a, 0x00, 0x4d, 0x04, 0x7d, 0x39, - 0x9b, 0x0e, 0xaa, 0xf7, 0x3a, 0xf9, 0x58, 0x30, 0x3a, 0x6d, 0x54, 0x29, - 0xbe, 0x99, 0xf0, 0xf7, 0x7b, 0xb8, 0xde, 0x70, 0xa2, 0x8b, 0x2e, 0x85, - 0x37, 0x75, 0xcf, 0xa4, 0x0d, 0xd7, 0x4a, 0x19, 0x6c, 0x8b, 0x15, 0xb8, - 0xee, 0xa7, 0xb7, 0x20, 0x03, 0xe6, 0xc2, 0xd4, 0xe2, 0xd6, 0xff, 0x23, - 0x73, 0x2a, 0x9f, 0xe0, 0xb1, 0xbe, 0x90, 0x2b, 0x8d, 0xe7, 0xad, 0xdd, - 0xcd, 0xa0, 0x2a, 0xda, 0xb1, 0x02, 0x0a, 0xa7, 0x04, 0x2d, 0x6f, 0xa4, - 0x80, 0x21, 0xfb, 0x80, 0x58, 0x29, 0xce, 0xaf, 0xc8, 0x54, 0x36, 0xad, - 0x1a, 0xdb, 0x88, 0xbf, 0x5d, 0x12, 0x00, 0xf7, 0x67, 0x31, 0x3f, 0x59, - 0x32, 0x01, 0x03, 0x6b, 0x72, 0x89, 0x70, 0x05, 0xbc, 0xc4, 0xf5, 0x87, - 0xb6, 0x3c, 0xcf, 0x3d, 0x84, 0xb8, 0xdf, 0x24, 0x01, 0xcf, 0x1b, 0xf5, - 0xeb, 0x70, 0x8d, 0xe7, 0x40, 0x05, 0x35, 0x2c, 0xaf, 0x74, 0x3a, 0x24, - 0xb4, 0x7b, 0x79, 0x72, 0x2f, 0x00, 0x06, 0x9f, 0x51, 0x46, 0xe3, 0xa5, - 0x28, 0x39, 0x1d, 0x6b, 0xed, 0x52, 0xcf, 0x48, 0x5c, 0x6f, 0x42, 0x00, - 0xfa, 0x8a, 0xfe, 0x77, 0x66, 0x73, 0x65, 0x96, 0x13, 0x24, 0xab, 0x4b, - 0x1f, 0x03, 0x0f, 0x6f, 0x2a, 0x08, 0x00, 0x5b, 0xf5, 0xe3, 0x91, 0x35, - 0xfd, 0x7b, 0x29, 0xd2, 0xe5, 0xda, 0x04, 0x15, 0x9b, 0x2c, 0x0c, 0x28, - 0x63, 0x77, 0x5a, 0x95, 0x6b, 0x69, 0xb4, 0x38, 0xda, 0x4b, 0x6f, 0x18, - 0x03, 0x97, 0x67, 0xc8, 0x97, 0x71, 0xc7, 0xb2, 0x1c, 0x5c, 0x73, 0x89, - 0xa8, 0x34, 0xb6, 0xf9, 0x29, 0x1f, 0x8e, 0x40, 0x1d, 0x5f, 0xa3, 0xed, - 0xc3, 0xae, 0x5d, 0x9c, 0x3b, 0x26, 0xc8, 0x7c, 0x3c, 0xc2, 0xdb, 0xe8, - 0x40, 0x05, 0x9e, 0xfd, 0x88, 0xfe, 0x40, 0x0a, 0xf3, 0xe2, 0x55, 0xe2, - 0x93, 0xb8, 0xe2, 0x07, 0xbd, 0xf3, 0x4c, 0x45, 0xa1, 0x0d, 0xe7, 0x6f, - 0x45, 0x4e, 0x84, 0x6c, 0x15, 0xaf, 0x7e, 0x57, 0x64, 0x44, 0xd8, 0xf9, - 0xa5, 0x6e, 0x5f, 0x52, 0xdb, 0x93, 0x97, 0x5f, 0x28, 0x96, 0xc1, 0x95, - 0x62, 0x2b, 0x48, 0xb8, 0x1c, 0x55, 0x60, 0x00, 0x00, 0x01, 0x07, 0x43, - 0xf9, 0xef, 0xbc, 0xbd, 0xf1, 0x2e, 0xf8, 0x28, 0xda, 0x7b, 0x6b, 0xe9, - 0xf8, 0x44, 0xed, 0xfc, 0xf3, 0xe1, 0x2d, 0x92, 0x40, 0xa6, 0xf6, 0xa0, - 0x0f, 0xc5, 0x69, 0x17, 0xdb, 0x08, 0xe2, 0x62, 0x0d, 0x41, 0x5b, 0xd5, - 0x93, 0x9b, 0x03, 0xaf, 0xe7, 0x16, 0x20, 0x4b, 0x5c, 0x08, 0x1f, 0x9e, - 0x44, 0xe0, 0x01, 0x87, 0xff, 0xdf, 0xe2, 0x0a, 0xdb, 0x0a, 0xf3, 0xdb, - 0xc6, 0xba, 0xcd, 0x87, 0x00, 0x4f, 0xc0, 0x49, 0x54, 0xa0, 0xc6, 0xf2, - 0xec, 0xb9, 0x6b, 0x78, 0xef, 0x94, 0x3e, 0x56, 0xfe, 0x39, 0x92, 0x3b, - 0x12, 0x4f, 0x09, 0x1b, 0x66, 0x82, 0x17, 0xfc, 0xcd, 0x6c, 0xfc, 0xca, - 0x55, 0xb0, 0x25, 0xbd, 0x28, 0x98, 0x4f, 0x17, 0xb4, 0xb0, 0xa7, 0xbb, - 0x10, 0x30, 0xf5, 0xb2, 0xdf, 0x4a, 0xdc, 0x96, 0x1b, 0x91, 0xb0, 0xd8, - 0xb1, 0xbb, 0xc4, 0x69, 0x3f, 0xe7, 0x93, 0x00, 0x06, 0x90, 0xb4, 0x08, - 0x6f, 0x99, 0x4f, 0xd4, 0x21, 0x15, 0x00, 0xa8, 0xdf, 0x53, 0x13, 0x6b, - 0xf2, 0xcc, 0x50, 0x11, 0x66, 0x2a, 0x8d, 0x3e, 0xc0, 0x29, 0xbe, 0x64, - 0xf2, 0xab, 0xa9, 0x2a, 0xc6, 0xde, 0xc2, 0xca, 0x21, 0xab, 0x69, 0x43, - 0xeb, 0x7e, 0xc0, 0x52, 0x91, 0xf6, 0xe9, 0x9a, 0x03, 0xca, 0x61, 0x55, - 0xbd, 0x30, 0x9d, 0x04, 0x1f, 0xeb, 0x22, 0x0a, 0xa0, 0x15, 0x8e, 0x88, - 0x64, 0x35, 0x40, 0x21, 0x30, 0xb0, 0xb2, 0x9b, 0xc2, 0xcf, 0xc9, 0xab, - 0xe1, 0x36, 0xb7, 0xd3, 0xa3, 0x9e, 0x00, 0xff, 0xb7, 0xc3, 0xc3, 0x2c, - 0x77, 0x2e, 0x31, 0x22, 0x9c, 0x66, 0x9f, 0xe2, 0xb2, 0x36, 0xce, 0x2b, - 0x6c, 0x80, 0x03, 0x36, 0xb3, 0x9b, 0xbc, 0x8e, 0x47, 0xe9, 0xc0, 0x0f, - 0x40, 0x1a, 0x64, 0xf6, 0x75, 0xa1, 0xe7, 0xf0, 0x2e, 0x5e, 0xf3, 0x4e, - 0x54, 0xb1, 0x56, 0xa1, 0x47, 0x14, 0xad, 0xf1, 0xaf, 0xfb, 0xf8, 0x14, - 0x67, 0x13, 0x75, 0x28, 0x09, 0x40, 0x0f, 0xbc, 0xaf, 0x39, 0x07, 0x15, - 0x12, 0x4d, 0xa3, 0xcb, 0x18, 0xde, 0xfb, 0xe0, 0xc1, 0x5e, 0xd9, 0xd3, - 0xf6, 0x86, 0x43, 0x70, 0xf1, 0x84, 0xc2, 0x9b, 0xca, 0xce, 0x5e, 0x00, - 0xe8, 0x50, 0x8e, 0x44, 0xbf, 0x27, 0xea, 0x4a, 0x2f, 0xcf, 0xbc, 0x83, - 0x40, 0x71, 0xc6, 0xc8, 0x64, 0xa0, 0x2a, 0x88, 0x5b, 0x72, 0x24, 0xb8, - 0xe5, 0xf5, 0x91, 0xaa, 0x07, 0xc8, 0xdf, 0x8e, 0xe3, 0x2b, 0x85, 0xbe, - 0xdc, 0x1e, 0x92, 0x6c, 0x83, 0x42, 0x80, 0xb6, 0xe8, 0x80, 0x34, 0xf8, - 0x9d, 0xf2, 0xf5, 0xf3, 0x79, 0x6a, 0x6d, 0x2e, 0xad, 0x03, 0x9b, 0x97, - 0x92, 0x7b, 0x3b, 0xaf, 0x30, 0x08, 0x67, 0x7e, 0x7b, 0x02, 0xe1, 0xb2, - 0xd9, 0xe1, 0x1b, 0x36, 0x6c, 0xc9, 0x69, 0x41, 0x76, 0x92, 0x9b, 0xbe, - 0xd6, 0xde, 0xd4, 0x8d, 0xfb, 0x2e, 0x1c, 0x00, 0x6e, 0x2b, 0xcb, 0xac, - 0x41, 0xa9, 0xb1, 0xd6, 0xca, 0x36, 0xd2, 0xcf, 0x2d, 0x91, 0x2c, 0xd7, - 0xa9, 0x61, 0x13, 0x99, 0x7d, 0x43, 0x1b, 0x86, 0x46, 0x80, 0x16, 0xf7, - 0x75, 0x02, 0x2b, 0xf6, 0x44, 0x1f, 0x5b, 0xd4, 0x13, 0x45, 0x3e, 0xdc, - 0x09, 0xb8, 0xaa, 0x10, 0x74, 0x89, 0x59, 0xb7, 0x58, 0x04, 0xea, 0xda, - 0x77, 0x63, 0xf3, 0x26, 0xe8, 0x64, 0x27, 0xb9, 0xda, 0x50, 0xd3, 0xb6, - 0xc3, 0xe0, 0x50, 0xd6, 0xeb, 0x79, 0x80, 0x1d, 0x80, 0x59, 0x2d, 0x1a, - 0x51, 0x3e, 0x7c, 0x73, 0x74, 0x34, 0x3a, 0xba, 0xd4, 0xb0, 0x21, 0xb9, - 0x50, 0xcf, 0x7b, 0xb5, 0x7c, 0x33, 0x6e, 0x6c, 0x01, 0x10, 0xdb, 0x60, - 0x51, 0x8c, 0xee, 0xd2, 0x7c, 0xfb, 0x97, 0x00, 0x45, 0xe6, 0xe5, 0x38, - 0x08, 0x54, 0x0e, 0x2c, 0x09, 0x6b, 0x6d, 0x87, 0x36, 0xd4, 0xbb, 0x57, - 0xd6, 0x52, 0x9b, 0xaa, 0xe5, 0xe1, 0xc2, 0xf7, 0x02, 0xcc, 0xdd, 0x4b, - 0x02, 0xcc, 0x1a, 0xdc, 0xf1, 0x33, 0x78, 0xdc, 0xcc, 0x41, 0xcf, 0x8f, - 0xf2, 0xb0, 0xbf, 0x16, 0x5e, 0x26, 0x10, 0x66, 0x3f, 0x03, 0x0f, 0xb5, - 0x4b, 0x2a, 0x9e, 0x31, 0xa5, 0xba, 0x1b, 0x7e, 0xb1, 0x61, 0x9a, 0x16, - 0x08, 0x5f, 0xf0, 0xbb, 0x84, 0x34, 0x29, 0xb5, 0xd9, 0x05, 0xd7, 0x62, - 0x06, 0xa1, 0x3a, 0xe4, 0x21, 0x2e, 0x36, 0x7e, 0xd1, 0xdc, 0x73, 0xc7, - 0x3a, 0x80, 0x4d, 0xc5, 0x26, 0x69, 0xf4, 0xf3, 0xa5, 0x95, 0xb7, 0xe5, - 0xbb, 0xc5, 0x72, 0x51, 0xa5, 0xc4, 0xee, 0xb8, 0x02, 0x23, 0x1e, 0x70, - 0x5c, 0x66, 0xd0, 0xdf, 0x89, 0x16, 0x68, 0xaa, 0x21, 0x22, 0x84, 0x8a, - 0xb8, 0x6a, 0x8f, 0x0c, 0x6a, 0xce, 0xd3, 0x0f, 0x1a, 0xb2, 0x2d, 0x6f, - 0x4e, 0x2b, 0x34, 0x01, 0xe0, 0xb8, 0xe7, 0xb8, 0x22, 0xed, 0x76, 0xc2, - 0xd4, 0x72, 0xcb, 0x03, 0x1b, 0xc5, 0x7c, 0x75, 0xce, 0xf4, 0x7e, 0xd0, - 0xa2, 0xca, 0xa5, 0xc2, 0xa8, 0xe8, 0xca, 0xb7, 0x9b, 0x43, 0xae, 0x12, - 0x1b, 0xfa, 0xe7, 0xfb, 0xb0, 0x41, 0xfc, 0xf2, 0x38, 0x03, 0xec, 0xe3, - 0x6c, 0x1d, 0x2b, 0xf8, 0xaf, 0x2d, 0x42, 0x30, 0x94, 0xdf, 0xb3, 0x9d, - 0xaa, 0xaa, 0xdf, 0xcf, 0x3d, 0x9b, 0xdb, 0xec, 0x8a, 0x02, 0x2d, 0x38, - 0x7b, 0x7e, 0xb4, 0x00, 0x6d, 0x01, 0x07, 0xf6, 0x3f, 0x84, 0x77, 0xe0, - 0x25, 0x00, 0x25, 0xec, 0xd9, 0x00, 0x47, 0x06, 0xb5, 0x40, 0xf6, 0xa8, - 0x1e, 0xdf, 0xd9, 0x78, 0x03, 0x2d, 0xa1, 0xc5, 0x56, 0xe4, 0xe0, 0x19, - 0xc4, 0x66, 0xe0, 0x0c, 0x5a, 0xdb, 0xb6, 0xed, 0xea, 0xe2, 0x99, 0x1b, - 0x99, 0xc7, 0xe1, 0xb9, 0x62, 0x2c, 0x96, 0x49, 0xb6, 0x0d, 0x8b, 0x1b, - 0x8f, 0xf6, 0xd0, 0x03, 0xcf, 0x77, 0xe4, 0x99, 0x4f, 0x9b, 0x2c, 0x59, - 0xb2, 0xc0, 0xa6, 0x50, 0xaa, 0xd1, 0x2a, 0x37, 0xeb, 0x05, 0x02, 0x17, - 0xfb, 0xa6, 0xcf, 0x41, 0xad, 0xea, 0x25, 0x36, 0x54, 0x6f, 0xce, 0xdf, - 0xcf, 0x69, 0xae, 0x14, 0xe5, 0xc5, 0x39, 0xe2, 0xe0, 0xb7, 0x38, 0xd2, - 0xbf, 0x15, 0x2c, 0xda, 0x75, 0xb0, 0x69, 0x71, 0xbe, 0xde, 0x20, 0x10, - 0x80, 0x2f, 0xdd, 0xf3, 0xd6, 0x22, 0xb6, 0x3c, 0x5f, 0x37, 0x16, 0x42, - 0x65, 0x29, 0xb8, 0x5b, 0x78, 0x09, 0x97, 0xa0, 0x4d, 0x00, 0x34, 0x6d, - 0xbd, 0xc4, 0x14, 0x2f, 0x41, 0x30, 0x01, 0x26, 0x94, 0xde, 0x2c, 0x8d, - 0xd0, 0x05, 0x62, 0x3d, 0x95, 0xda, 0x1b, 0x39, 0xe3, 0x69, 0x70, 0xe3, - 0x8b, 0x29, 0xbd, 0x58, 0x80, 0x0a, 0x75, 0xcf, 0x2c, 0x26, 0x6b, 0x96, - 0x90, 0x95, 0xa7, 0x8d, 0x97, 0x87, 0xca, 0x00, 0x34, 0x2f, 0xd1, 0x2b, - 0x10, 0x99, 0x54, 0x84, 0xdf, 0x3c, 0x01, 0xb8, 0x9c, 0xf2, 0xae, 0x97, - 0x1d, 0x16, 0xd7, 0xcc, 0x40, 0x1c, 0xc5, 0xba, 0x70, 0xf6, 0xf3, 0x7c, - 0x7f, 0x2d, 0xf9, 0xf8, 0x13, 0x7d, 0xa5, 0x01, 0xe3, 0xf1, 0xe8, 0x56, - 0x54, 0x45, 0x5c, 0x2d, 0x1a, 0xcf, 0x8d, 0x22, 0x00, 0x3a, 0xfb, 0xe5, - 0x15, 0xd8, 0xbc, 0x2a, 0xcb, 0xaf, 0x4b, 0x32, 0xf0, 0xf8, 0x6c, 0x83, - 0x4e, 0x1a, 0xde, 0x4c, 0x10, 0x00, 0xb0, 0x48, 0x01, 0xb0, 0x05, 0xb7, - 0xdf, 0x38, 0xd8, 0xb5, 0x09, 0xd8, 0x4d, 0xba, 0x93, 0x15, 0x5b, 0xe7, - 0xf3, 0xd9, 0xfc, 0x98, 0x6d, 0x90, 0x71, 0xc3, 0x4e, 0x18, 0x1a, 0x48, - 0x6c, 0x77, 0x2d, 0x8a, 0xad, 0xfb, 0x80, 0x07, 0x4b, 0xc7, 0x66, 0xf0, - 0xfc, 0x0c, 0xb3, 0x1e, 0x51, 0x44, 0x8a, 0xde, 0x64, 0x00, 0xb3, 0xdf, - 0x8f, 0x61, 0x78, 0x6f, 0x1d, 0xe4, 0x2d, 0x2c, 0xd8, 0x53, 0xcc, 0x0e, - 0xb5, 0xbe, 0x32, 0xff, 0x69, 0x40, 0x1e, 0x57, 0x3b, 0x1d, 0x4a, 0xbb, - 0x26, 0xe3, 0xcf, 0xee, 0x87, 0xe2, 0x4a, 0x74, 0x30, 0xe4, 0x6e, 0x50, - 0x00, 0x9f, 0x8c, 0x7a, 0x0a, 0xe9, 0xc3, 0x00, 0x2d, 0x7c, 0xc9, 0x6d, - 0xfc, 0x5b, 0x2d, 0x92, 0x51, 0xaa, 0x53, 0x7d, 0x01, 0x93, 0x55, 0x20, - 0x1b, 0x6e, 0xae, 0x64, 0xa4, 0xc8, 0xdf, 0xa6, 0xe0, 0x8b, 0xf6, 0x23, - 0x7d, 0x3d, 0xba, 0xf6, 0x78, 0xbf, 0x25, 0xf2, 0xdd, 0xa8, 0xbb, 0xa3, - 0x64, 0x5a, 0x52, 0xa4, 0x29, 0xa8, 0xfb, 0x00, 0x3b, 0x7e, 0x76, 0x41, - 0xef, 0xd9, 0xcf, 0x92, 0xcf, 0x37, 0x87, 0x2f, 0x94, 0x87, 0x59, 0x14, - 0x62, 0xb7, 0x91, 0x82, 0x7e, 0xae, 0xc3, 0x7e, 0x66, 0x4c, 0x2f, 0x05, - 0x3a, 0x19, 0x34, 0xad, 0xa6, 0x94, 0x70, 0xc6, 0xf5, 0x60, 0x09, 0x67, - 0x42, 0xdf, 0xb1, 0xdf, 0x3a, 0xa1, 0xd4, 0x6d, 0x44, 0x90, 0xba, 0x3c, - 0x73, 0x59, 0x6d, 0xd0, 0x13, 0x5b, 0xec, 0xfb, 0x08, 0xe9, 0xd9, 0xdd, - 0x10, 0x00, 0xf4, 0x5e, 0x5b, 0x2e, 0x3f, 0x45, 0xc0, 0x45, 0x00, 0x6d, - 0xb4, 0xd2, 0x6a, 0x9e, 0x50, 0xf6, 0xf2, 0x1f, 0x40, 0x07, 0xe2, 0xfa, - 0x4c, 0x00, 0x3e, 0x14, 0xe9, 0x25, 0x9e, 0xce, 0xc2, 0x91, 0xd0, 0x37, - 0xd6, 0x8f, 0x6e, 0x6f, 0xf5, 0xf9, 0xcf, 0x0e, 0xf3, 0x88, 0x04, 0x3b, - 0x9c, 0xd2, 0x61, 0xb1, 0x52, 0x98, 0xa5, 0x29, 0xfe, 0x8d, 0xb8, 0x00, - 0x4e, 0xe7, 0x0b, 0xda, 0x65, 0x45, 0xb8, 0x1d, 0x0d, 0x54, 0x55, 0x21, - 0x2b, 0x38, 0xc3, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, 0xf3, 0xc0, 0x0f, - 0xbd, 0x85, 0x00, 0x3b, 0xfb, 0x8a, 0xeb, 0x9e, 0x5c, 0x74, 0x97, 0xca, - 0x4d, 0xd3, 0x21, 0x32, 0x45, 0x52, 0xbd, 0x20, 0xe6, 0xfb, 0x10, 0x20, - 0x01, 0x6b, 0xaf, 0xd7, 0xa9, 0xcf, 0xd1, 0xd7, 0x6f, 0xee, 0x72, 0x65, - 0xdc, 0x86, 0x87, 0x4a, 0xa5, 0x15, 0xe2, 0xdf, 0x0a, 0x7d, 0xf3, 0xb2, - 0x44, 0x1c, 0x51, 0x48, 0xde, 0x82, 0x6d, 0x7c, 0x6e, 0x51, 0xf5, 0xbc, - 0xa2, 0xa5, 0x2d, 0xbe, 0x71, 0x1e, 0xdf, 0x61, 0x7d, 0x2a, 0xc3, 0xe6, - 0xaf, 0x56, 0x13, 0xd6, 0x1d, 0xf9, 0x88, 0x77, 0x8c, 0x6d, 0x54, 0x0c, - 0x20, 0x26, 0xff, 0xdd, 0x80, 0x02, 0xd2, 0x43, 0x6a, 0xd5, 0x73, 0xb5, - 0xef, 0x50, 0xa9, 0x13, 0x50, 0x23, 0x56, 0x95, 0x42, 0x47, 0x35, 0xdf, - 0x34, 0x50, 0x03, 0x7f, 0xb7, 0xd8, 0x4b, 0x9e, 0xa3, 0x2a, 0x89, 0xc0, - 0xba, 0x55, 0xbb, 0x4a, 0x0b, 0x2d, 0xb9, 0x6d, 0x5b, 0x2b, 0x03, 0x29, - 0x24, 0x0e, 0x6f, 0xd2, 0x80, 0x3b, 0x50, 0x05, 0x7f, 0xcf, 0x8d, 0xc3, - 0x87, 0x76, 0xfd, 0x93, 0x89, 0x60, 0x23, 0xff, 0xed, 0xfd, 0x46, 0xf8, - 0x80, 0xb3, 0x40, 0x1e, 0x09, 0xf8, 0xb4, 0x2e, 0x68, 0x8d, 0x14, 0xfb, - 0x01, 0x28, 0x01, 0x75, 0xc4, 0x86, 0xfd, 0xa9, 0xbd, 0xf9, 0x80, 0x3b, - 0xef, 0x9b, 0x68, 0xeb, 0x7b, 0x73, 0xf7, 0x38, 0x48, 0x5a, 0x07, 0x5b, - 0x0e, 0x38, 0x75, 0x6f, 0xca, 0x42, 0xaf, 0x3f, 0xce, 0xbf, 0xef, 0xb6, - 0x86, 0x71, 0x2d, 0x11, 0xed, 0x31, 0xc3, 0x49, 0xae, 0xe1, 0x57, 0x42, - 0x54, 0x63, 0x68, 0x4c, 0x90, 0x0b, 0x62, 0xd2, 0xdb, 0xf1, 0x6e, 0xa4, - 0xfb, 0x25, 0x8d, 0xf7, 0xd7, 0x72, 0xf7, 0x38, 0x01, 0xef, 0x74, 0x5b, - 0xb0, 0x65, 0xe0, 0x57, 0xcf, 0x7d, 0xee, 0x45, 0x3c, 0x08, 0x40, 0x08, - 0x13, 0x1b, 0xe4, 0xc0, 0x0f, 0xd4, 0x01, 0x18, 0x03, 0xef, 0xa7, 0x28, - 0x17, 0x5f, 0x6f, 0x19, 0x07, 0x1f, 0x29, 0x70, 0x2a, 0xa3, 0x7e, 0x94, - 0x00, 0x5b, 0x98, 0x23, 0x9e, 0x70, 0x50, 0x9e, 0x60, 0xc0, 0xfe, 0x37, - 0x62, 0x43, 0xec, 0x2c, 0x30, 0x2d, 0xbc, 0x1e, 0x85, 0x51, 0x06, 0x3f, - 0x98, 0xa1, 0x97, 0xf4, 0xad, 0x89, 0x86, 0x1f, 0xea, 0x31, 0xbf, 0xcf, - 0x40, 0x0f, 0xe6, 0x70, 0xfd, 0xb2, 0x51, 0xf4, 0xdb, 0x64, 0x8d, 0xc9, - 0xf7, 0xec, 0x00, 0xf1, 0xd6, 0xed, 0x81, 0xb1, 0x68, 0xc8, 0xdd, 0xe1, - 0x58, 0x00, 0x65, 0xe6, 0xf2, 0xf2, 0x9e, 0x4c, 0x96, 0xac, 0xf0, 0x6f, - 0x9f, 0x09, 0x9d, 0x09, 0xf8, 0x5a, 0x90, 0x25, 0xda, 0x1d, 0x29, 0xf0, - 0x6b, 0x75, 0x82, 0x1f, 0xfd, 0x4d, 0x84, 0x2a, 0xc2, 0x1a, 0xad, 0xe1, - 0xf9, 0x2f, 0xb8, 0xf4, 0x0a, 0xd7, 0x64, 0x56, 0x5e, 0x6d, 0xcc, 0x7f, - 0x25, 0x86, 0xcb, 0x76, 0x44, 0x90, 0x2a, 0x01, 0xed, 0xde, 0x7e, 0xa0, - 0xb7, 0xdf, 0x4a, 0x38, 0x29, 0x98, 0x4d, 0x37, 0xad, 0x76, 0xcf, 0x16, - 0xeb, 0x90, 0xb2, 0x9b, 0x5c, 0x1a, 0xdf, 0x8e, 0xe5, 0x5c, 0x6d, 0xa8, - 0x14, 0xb2, 0x7a, 0xd2, 0xdb, 0xd6, 0xc7, 0xcf, 0x9a, 0x92, 0xd0, 0xbd, - 0x76, 0xec, 0xd0, 0xa8, 0xb5, 0x4a, 0x0c, 0xaa, 0xd8, 0xbb, 0x80, 0x16, - 0x53, 0x37, 0x65, 0x0b, 0xa3, 0x42, 0xda, 0x02, 0x1f, 0xfd, 0x66, 0x3e, - 0x50, 0xab, 0x72, 0x12, 0x49, 0x05, 0xb6, 0xf9, 0xf9, 0x8d, 0xd7, 0x00, - 0x29, 0x6f, 0x4c, 0xd2, 0x78, 0xb1, 0x49, 0x02, 0x56, 0xbf, 0x0a, 0xb0, - 0x24, 0x63, 0x59, 0xde, 0xcf, 0x2b, 0x2b, 0xd4, 0x00, 0x53, 0x04, 0x41, - 0x4e, 0xb6, 0x82, 0x3f, 0xfe, 0x64, 0xa0, 0x51, 0xed, 0x97, 0x6d, 0xcd, - 0xdd, 0x93, 0x46, 0x95, 0x9c, 0x19, 0x36, 0x8d, 0xa5, 0x9a, 0x51, 0x61, - 0x2d, 0xd8, 0xee, 0x00, 0x1e, 0xbb, 0xaa, 0xf7, 0x0f, 0xae, 0x97, 0x33, - 0x5e, 0xf0, 0xc3, 0xd6, 0x15, 0x09, 0x2d, 0xd0, 0xdd, 0xc3, 0x9b, 0xaf, - 0xac, 0xa4, 0x5c, 0xba, 0x96, 0x45, 0x59, 0xba, 0x31, 0xba, 0x1c, 0xbe, - 0x6f, 0x9e, 0xdc, 0x00, 0x85, 0xdb, 0x0d, 0x42, 0x8e, 0x09, 0x6a, 0x74, - 0x9f, 0xf2, 0xfc, 0xe5, 0xd6, 0x86, 0xa7, 0x46, 0x50, 0xf0, 0x11, 0x9e, - 0x5b, 0x0a, 0xaf, 0xfb, 0xf5, 0x24, 0x09, 0x8f, 0xb2, 0x10, 0xe8, 0xca, - 0xd0, 0xda, 0x9e, 0xd8, 0xc4, 0xf9, 0xef, 0xa4, 0x08, 0x5d, 0x29, 0x14, - 0x2a, 0x36, 0xfb, 0x40, 0x2b, 0x17, 0xc7, 0x21, 0xe1, 0x16, 0x64, 0x73, - 0xe0, 0x5e, 0xfe, 0xa0, 0x59, 0x4d, 0x57, 0x69, 0xf6, 0x13, 0x9c, 0x72, - 0x81, 0x69, 0x13, 0x40, 0xea, 0xd4, 0x67, 0x37, 0xdb, 0x1e, 0xed, 0xd0, - 0x4a, 0xff, 0x9c, 0xca, 0x58, 0x40, 0xef, 0x05, 0x6b, 0x64, 0xde, 0x8a, - 0xbc, 0xc7, 0xd9, 0x14, 0x08, 0xdb, 0x9e, 0xf2, 0x4a, 0x30, 0x07, 0x33, - 0x88, 0x96, 0x85, 0x37, 0x87, 0xc8, 0x68, 0x8f, 0x6c, 0x7e, 0x84, 0xdb, - 0x68, 0x7a, 0x04, 0x23, 0x7d, 0x02, 0x82, 0x10, 0x03, 0x89, 0xf6, 0xc9, - 0x94, 0x12, 0x3f, 0xf7, 0x1d, 0x39, 0x77, 0x8e, 0x19, 0xb2, 0x90, 0xdb, - 0xe6, 0x8f, 0x90, 0x57, 0xd7, 0xae, 0x65, 0x0a, 0xc1, 0x56, 0x1a, 0xa7, - 0x9f, 0x06, 0xc0, 0xb6, 0x88, 0x53, 0x71, 0xd0, 0x30, 0x53, 0x7e, 0xe9, - 0xe9, 0xd1, 0x1c, 0x5e, 0x3b, 0xc7, 0x83, 0x16, 0xdf, 0x46, 0xf7, 0x9f, - 0xc8, 0x08, 0x3f, 0x95, 0xcf, 0xf8, 0x4a, 0x50, 0x49, 0xff, 0xde, 0x2c, - 0x80, 0x96, 0x00, 0x65, 0x12, 0x5b, 0xe0, 0x62, 0xac, 0x77, 0x9e, 0xdc, - 0x83, 0x12, 0x4a, 0x54, 0xf0, 0x6f, 0xb7, 0x7b, 0xc0, 0x41, 0xfc, 0x40, - 0x01, 0x16, 0x20, 0x04, 0x37, 0x99, 0x28, 0x59, 0x8b, 0x69, 0x29, 0xad, - 0x4e, 0x24, 0xb6, 0x14, 0xba, 0xdf, 0xec, 0x25, 0x41, 0xbe, 0x8a, 0xde, - 0x30, 0x01, 0xf3, 0xc1, 0x04, 0x06, 0x40, 0x1f, 0xfc, 0x8a, 0x77, 0x8d, - 0xe1, 0xf5, 0x60, 0x08, 0xaa, 0x07, 0xc0, 0xa6, 0xf5, 0x90, 0xaa, 0x00, - 0x2e, 0x6f, 0xcb, 0xe0, 0x0f, 0x90, 0x10, 0x00, 0xeb, 0x8e, 0x3e, 0xba, - 0x09, 0x7f, 0xf7, 0x49, 0xce, 0xa3, 0x0e, 0xb4, 0x9b, 0xe3, 0x0e, 0x6d, - 0x4e, 0xad, 0xbc, 0x29, 0x5b, 0xf0, 0x00, 0x0c, 0x3d, 0xba, 0x7f, 0xdb, - 0x8c, 0xf8, 0xce, 0x20, 0xfd, 0xe7, 0x7c, 0xa6, 0x2d, 0x0d, 0x39, 0xac, - 0xff, 0x0a, 0xe1, 0xfd, 0x57, 0xd7, 0xe4, 0x91, 0x77, 0x5f, 0xb9, 0x61, - 0xb6, 0xda, 0x87, 0xa0, 0xe0, 0x96, 0xe0, 0x89, 0xf2, 0xe4, 0xd8, 0xb5, - 0x00, 0x95, 0x1c, 0xad, 0xab, 0xce, 0x80, 0x3b, 0x00, 0x32, 0xc1, 0x5b, - 0x2c, 0x04, 0x6f, 0xfa, 0x7f, 0x91, 0x98, 0x34, 0x9a, 0x6d, 0x89, 0x02, - 0xdb, 0xcf, 0x44, 0x76, 0xda, 0x42, 0x46, 0xe5, 0xb0, 0x39, 0x5b, 0xfd, - 0x1f, 0xf7, 0xea, 0x82, 0x07, 0xe7, 0xf1, 0x08, 0x9e, 0xd7, 0x06, 0x79, - 0x79, 0xce, 0x57, 0xbc, 0x1c, 0x1d, 0x83, 0x2d, 0x6e, 0xf8, 0x03, 0x2e, - 0x78, 0x00, 0x4d, 0xce, 0x6f, 0x9d, 0x0c, 0x80, 0x3d, 0x0b, 0x0c, 0x87, - 0xb7, 0x8d, 0x04, 0x00, 0x2a, 0x73, 0xc0, 0x1b, 0x39, 0xef, 0xf9, 0x17, - 0x69, 0x6b, 0x99, 0xca, 0xd3, 0x62, 0xd3, 0x6c, 0x50, 0x96, 0xf9, 0xd8, - 0xae, 0x35, 0xdf, 0x13, 0x20, 0x8b, 0x85, 0xa6, 0x4c, 0x45, 0x8b, 0x36, - 0xae, 0x97, 0x7c, 0x5b, 0x67, 0xd8, 0x6b, 0xf7, 0x69, 0x08, 0xa6, 0xea, - 0xe4, 0xbb, 0xb6, 0xd0, 0x29, 0xbf, 0xa5, 0x80, 0x17, 0x7d, 0x4d, 0xf7, - 0xbb, 0xf3, 0xc3, 0xb9, 0x8a, 0x86, 0xa0, 0xc9, 0x85, 0x17, 0x10, 0xf3, - 0xc3, 0x15, 0xbc, 0x68, 0x03, 0x22, 0x37, 0x5d, 0x7b, 0x0a, 0x70, 0x05, - 0xbe, 0xd6, 0x93, 0x79, 0x78, 0xdd, 0x32, 0x40, 0xf1, 0xc5, 0x2b, 0x64, - 0x00, 0x71, 0xf6, 0xe6, 0x7b, 0xc5, 0x78, 0x9d, 0xb0, 0x9b, 0x77, 0x6a, - 0xdd, 0x58, 0x92, 0x14, 0x10, 0x34, 0xb6, 0xe6, 0x00, 0x36, 0x23, 0x70, - 0x66, 0x2d, 0xef, 0x6f, 0xed, 0xdc, 0x21, 0xd9, 0x0f, 0xa5, 0x86, 0xb2, - 0x7e, 0xd7, 0xf3, 0xbb, 0xb7, 0xc5, 0xb7, 0x7d, 0x37, 0x6d, 0xad, 0xf5, - 0xba, 0x00, 0x39, 0xde, 0x65, 0xdd, 0xe7, 0x30, 0x10, 0xc0, 0x18, 0x50, - 0xa7, 0x18, 0x92, 0xe6, 0xed, 0x1a, 0xef, 0xd5, 0x8d, 0x90, 0x01, 0xe7, - 0x64, 0x77, 0x89, 0xc5, 0xf6, 0x32, 0xd0, 0xff, 0x67, 0x47, 0x48, 0x90, - 0x83, 0x4d, 0xd8, 0x4b, 0xad, 0xe6, 0xc5, 0x3a, 0x74, 0x22, 0x4e, 0x84, - 0x70, 0x34, 0xd9, 0xc6, 0x7e, 0xf6, 0xd3, 0x82, 0x9a, 0xe7, 0xed, 0x79, - 0x8f, 0x5e, 0x72, 0xa2, 0xb8, 0xcd, 0x28, 0x98, 0x1c, 0x3a, 0x94, 0x06, - 0xdb, 0x48, 0xda, 0xd6, 0xfb, 0xa4, 0x4e, 0x05, 0x70, 0x46, 0xda, 0xef, - 0x7a, 0xfc, 0x53, 0x04, 0xf2, 0xf9, 0x0e, 0x98, 0x52, 0x87, 0xc8, 0x3e, - 0xd6, 0x6f, 0x60, 0x07, 0xa4, 0x71, 0x3d, 0xe6, 0xbf, 0x8c, 0x53, 0x03, - 0xac, 0xb1, 0x46, 0x14, 0x54, 0x1d, 0x06, 0xb7, 0x20, 0x00, 0xf7, 0xa7, - 0x77, 0xb1, 0xd3, 0x99, 0x8a, 0x82, 0xf4, 0x80, 0xbe, 0x72, 0xca, 0x38, - 0xa3, 0xe1, 0xde, 0xad, 0x97, 0xd9, 0xe2, 0xfd, 0xf9, 0x90, 0xc9, 0x46, - 0xa9, 0xb5, 0x10, 0xc8, 0x04, 0x1e, 0xa3, 0x98, 0xf1, 0x66, 0xdf, 0xa3, - 0x00, 0x58, 0xef, 0x97, 0x59, 0xcf, 0xd7, 0xdd, 0xfb, 0x4e, 0x99, 0x6a, - 0x80, 0xe3, 0x0f, 0x38, 0x61, 0x4d, 0xc0, 0xae, 0xeb, 0x32, 0xb8, 0x43, - 0xa1, 0x45, 0x16, 0x91, 0x0b, 0x0a, 0x6c, 0xde, 0xcb, 0x4c, 0x20, 0x4c, - 0x39, 0x74, 0xa8, 0x56, 0x8e, 0xf0, 0x02, 0xdb, 0xa7, 0xf1, 0x9c, 0xc7, - 0x50, 0x0b, 0x7b, 0xda, 0x74, 0x2e, 0xa2, 0xc7, 0x43, 0xd9, 0xc6, 0x6d, - 0xf9, 0xf3, 0x74, 0xcc, 0x36, 0x62, 0x8d, 0xa6, 0x1e, 0x8a, 0x58, 0x6b, - 0x27, 0x79, 0x5f, 0x83, 0x69, 0xe1, 0x65, 0x56, 0xee, 0x7c, 0xba, 0x8b, - 0xd9, 0x72, 0x00, 0x45, 0x98, 0x61, 0x67, 0x31, 0x7d, 0xe0, 0x57, 0xbd, - 0x58, 0x13, 0xb0, 0xeb, 0x3d, 0x51, 0x15, 0x86, 0x55, 0x80, 0x00, 0x00, - 0x01, 0x09, 0x43, 0xf1, 0xf9, 0x49, 0xf9, 0x85, 0x04, 0xad, 0x6e, 0xaf, - 0x32, 0x6e, 0x16, 0xdf, 0x2a, 0x77, 0x52, 0x11, 0xf8, 0xb7, 0x60, 0xe5, - 0x32, 0xc8, 0x58, 0xc2, 0xca, 0x4a, 0xa1, 0x2d, 0xf6, 0xba, 0x47, 0x22, - 0x00, 0x2d, 0x00, 0x7d, 0xbb, 0xbc, 0xdd, 0x4b, 0x49, 0xdd, 0x88, 0xe6, - 0x07, 0x2e, 0x07, 0xc3, 0xa5, 0x1a, 0x8d, 0xe5, 0xb8, 0xa6, 0xf3, 0x55, - 0x5b, 0xc0, 0xf7, 0x49, 0xde, 0xf0, 0x42, 0x36, 0x4b, 0xe0, 0xb6, 0x2b, - 0x6f, 0x73, 0xf4, 0x51, 0x1c, 0x01, 0xe7, 0xdb, 0x9a, 0x13, 0x7b, 0xf9, - 0x15, 0x1c, 0x4f, 0x04, 0x80, 0x03, 0xdd, 0x2f, 0x8a, 0x15, 0x0e, 0xa7, - 0xb7, 0xa8, 0x16, 0x45, 0xf6, 0xfa, 0x11, 0x4d, 0xf8, 0x82, 0xcc, 0x36, - 0xe6, 0xbf, 0x2f, 0x95, 0x55, 0x86, 0x7e, 0xad, 0x3d, 0x4b, 0x90, 0x21, - 0xba, 0x22, 0x7b, 0xa0, 0x0f, 0xbe, 0x9f, 0x77, 0x73, 0xc5, 0x8f, 0x7f, - 0x2f, 0x7d, 0x9b, 0x1f, 0xb1, 0xfa, 0xfd, 0x44, 0x43, 0xca, 0x8e, 0x0b, - 0x56, 0xe7, 0x75, 0xf2, 0xa3, 0x02, 0xab, 0x2d, 0x44, 0x6f, 0xd8, 0x73, - 0xae, 0x23, 0x7f, 0x04, 0xee, 0x3e, 0x00, 0x0a, 0x5d, 0xcf, 0x4b, 0x38, - 0xc9, 0x03, 0xc0, 0x4b, 0x0a, 0x43, 0x0a, 0xad, 0xf0, 0x40, 0x03, 0xb8, - 0xe7, 0xf9, 0xfb, 0x58, 0x7a, 0x6d, 0xd9, 0x9b, 0x57, 0x07, 0x15, 0x8a, - 0x6d, 0x0a, 0x46, 0xfd, 0x0f, 0xf4, 0x16, 0x00, 0x6b, 0xc7, 0xff, 0xb1, - 0x51, 0xf2, 0x9f, 0x78, 0xcd, 0x00, 0xb7, 0x6e, 0x53, 0xa9, 0x34, 0x3e, - 0x9b, 0x0e, 0x1b, 0x1b, 0xf2, 0x63, 0xe4, 0x11, 0x82, 0xa4, 0x80, 0x94, - 0x00, 0x66, 0x52, 0x51, 0x25, 0x9e, 0x16, 0xab, 0x3d, 0x23, 0x48, 0x0e, - 0x35, 0xbf, 0xae, 0x08, 0xfa, 0xb8, 0x10, 0x3f, 0x2c, 0x4e, 0x8b, 0xe3, - 0xbb, 0x40, 0x8e, 0x3e, 0x38, 0xeb, 0x88, 0xf9, 0xb0, 0xf0, 0xf7, 0xed, - 0xab, 0x14, 0x32, 0x14, 0xdf, 0x50, 0xf9, 0xf8, 0xc0, 0x02, 0x8e, 0x1c, - 0xe8, 0xb0, 0x11, 0xff, 0xee, 0xdb, 0x69, 0x60, 0x3c, 0x58, 0x52, 0x12, - 0x5b, 0xf2, 0xfe, 0x80, 0x53, 0x5b, 0xf4, 0x38, 0x03, 0xc7, 0xc0, 0x04, - 0xff, 0xe1, 0x7f, 0xdf, 0xb4, 0xc8, 0x08, 0xc0, 0x0a, 0xb4, 0x0c, 0xa6, - 0x07, 0x50, 0x1c, 0xd1, 0x88, 0x58, 0xd1, 0xb5, 0xb9, 0x75, 0x1d, 0xd3, - 0xf5, 0x7c, 0x21, 0x49, 0x4e, 0x1f, 0x5b, 0x38, 0x5b, 0xae, 0xcf, 0x04, - 0x3d, 0xbf, 0xce, 0x9f, 0x71, 0x0f, 0x00, 0x2e, 0xfb, 0xbb, 0x1d, 0x65, - 0x01, 0xe6, 0xbc, 0x46, 0xbb, 0x60, 0xca, 0x58, 0x45, 0x25, 0xb7, 0xce, - 0x3a, 0xe8, 0x02, 0xbe, 0xdc, 0x4f, 0x2c, 0x62, 0xc3, 0x15, 0xbf, 0x5c, - 0x00, 0x30, 0x17, 0xa0, 0x80, 0x05, 0x59, 0xef, 0xff, 0x16, 0x22, 0x4f, - 0xd7, 0x5c, 0x3d, 0xc8, 0x66, 0xd4, 0x27, 0x9d, 0x4d, 0x8b, 0x50, 0x68, - 0xd6, 0xfc, 0xd0, 0xfa, 0xf1, 0x7f, 0x24, 0x67, 0x71, 0x21, 0xd9, 0x5e, - 0x4f, 0xec, 0xc9, 0x93, 0x21, 0x74, 0x3c, 0x74, 0x6e, 0x82, 0x6f, 0x3b, - 0xa8, 0x43, 0xad, 0xa2, 0x96, 0xb5, 0xbc, 0x8f, 0xeb, 0x1c, 0x22, 0x47, - 0x64, 0xf5, 0x3e, 0xda, 0xa3, 0x4b, 0x6b, 0x08, 0xce, 0x00, 0x33, 0xf7, - 0x9b, 0x25, 0x0c, 0xaf, 0x32, 0x19, 0x46, 0xb7, 0xa7, 0x42, 0x01, 0xaf, - 0x7c, 0xb8, 0x03, 0xde, 0x79, 0x93, 0x80, 0xa2, 0xb2, 0x0c, 0x81, 0xa5, - 0xd6, 0xc1, 0xf7, 0x37, 0x0a, 0x44, 0x3d, 0x4a, 0x87, 0x86, 0x00, 0xd5, - 0x96, 0x4b, 0xae, 0x46, 0x4a, 0x52, 0xb7, 0xd0, 0xec, 0x5e, 0x11, 0xb8, - 0x7e, 0xbf, 0xac, 0x2c, 0xad, 0xe7, 0x1f, 0x93, 0x8b, 0x76, 0xa3, 0x8f, - 0x8a, 0x51, 0x94, 0xb4, 0x2b, 0x0f, 0x8d, 0xc0, 0xe6, 0x68, 0x19, 0xca, - 0x9e, 0x25, 0x29, 0x29, 0xb0, 0xf1, 0x28, 0xa1, 0x6e, 0xb7, 0x72, 0x06, - 0x45, 0x58, 0x9e, 0x10, 0x68, 0x4b, 0x52, 0x46, 0xcc, 0x7b, 0xb6, 0xe2, - 0x50, 0xab, 0x0a, 0x02, 0xeb, 0x5d, 0x87, 0x2d, 0xf5, 0x6d, 0xcf, 0xa0, - 0x5b, 0x7d, 0x61, 0x6b, 0xcd, 0xe2, 0xd9, 0x2f, 0x83, 0xf0, 0xaa, 0x10, - 0x31, 0xb7, 0xe4, 0xc8, 0x47, 0x94, 0xde, 0x02, 0xb5, 0xfb, 0x2e, 0x5b, - 0x16, 0x9d, 0xa0, 0x5b, 0x69, 0x23, 0x7e, 0x7b, 0x23, 0x75, 0xbb, 0x29, - 0xd0, 0xbf, 0x7f, 0x3b, 0x4b, 0x0c, 0x30, 0xda, 0x7b, 0x61, 0xd9, 0x39, - 0x14, 0x23, 0x70, 0xc8, 0x55, 0x31, 0xd4, 0xc7, 0x1c, 0x4c, 0x51, 0x81, - 0x67, 0xb7, 0xa0, 0x32, 0xb7, 0xa2, 0x8a, 0x8d, 0xea, 0xf6, 0xcb, 0xe5, - 0x78, 0xd8, 0xa7, 0xd2, 0xd5, 0xd2, 0x1c, 0x58, 0xe1, 0xed, 0xb7, 0x87, - 0xf9, 0x11, 0x95, 0x50, 0x72, 0x6e, 0x17, 0xa3, 0x09, 0x88, 0x31, 0xb9, - 0x76, 0x1b, 0xf3, 0x9b, 0x54, 0x05, 0x77, 0x8d, 0xc2, 0xe1, 0x30, 0x71, - 0xfe, 0xad, 0xd2, 0x17, 0x40, 0x0e, 0x05, 0xbe, 0x97, 0x46, 0x9a, 0x6b, - 0xb3, 0x32, 0x94, 0x04, 0x50, 0xf2, 0xef, 0x8c, 0x29, 0x93, 0x6e, 0xde, - 0x5c, 0xc2, 0x7f, 0x34, 0x9d, 0x81, 0x92, 0x72, 0xfc, 0x9b, 0x47, 0x0d, - 0x28, 0xf0, 0x98, 0xce, 0x45, 0x7c, 0xe8, 0x00, 0xfe, 0x1a, 0x19, 0x49, - 0xce, 0xe4, 0xc4, 0xd8, 0x1b, 0x64, 0xcb, 0x4a, 0x0d, 0x62, 0xe7, 0xef, - 0x59, 0xef, 0xbb, 0x25, 0x1c, 0x82, 0xf4, 0xc9, 0x29, 0xe3, 0x92, 0x92, - 0x1b, 0x1c, 0x33, 0xe1, 0xfd, 0xdb, 0x40, 0x47, 0xe6, 0xe5, 0x51, 0x83, - 0x0d, 0x18, 0x10, 0xd4, 0xd2, 0x73, 0x74, 0x08, 0x96, 0x71, 0x45, 0xe4, - 0xd4, 0x1c, 0x4f, 0x3f, 0x21, 0xd7, 0xc5, 0xb1, 0xdd, 0xa0, 0x0e, 0xbe, - 0x9d, 0x63, 0xed, 0x0d, 0xb3, 0xcf, 0x75, 0x29, 0xe3, 0xf7, 0x6c, 0xf4, - 0xb5, 0x97, 0x94, 0xb9, 0x66, 0x1b, 0xe2, 0x05, 0x1c, 0xdd, 0x5e, 0x45, - 0xc7, 0x6f, 0xe6, 0x4a, 0x59, 0x53, 0x75, 0x4c, 0x1e, 0x70, 0x4d, 0x61, - 0xa6, 0x95, 0x1b, 0xf1, 0x9e, 0xf2, 0x89, 0x99, 0x32, 0xca, 0x39, 0x43, - 0x4e, 0x6f, 0xd3, 0x1f, 0xde, 0xb4, 0x10, 0x3f, 0x2f, 0xee, 0xe2, 0x37, - 0xb7, 0xbc, 0xa5, 0xe6, 0xf5, 0x9d, 0xfb, 0x6b, 0xf5, 0xf9, 0x4f, 0x85, - 0xe5, 0x92, 0x2d, 0x09, 0x2d, 0xbe, 0x46, 0x6c, 0x9b, 0x23, 0xcb, 0x19, - 0x85, 0x86, 0x96, 0x88, 0xa5, 0x37, 0xbf, 0xff, 0x3b, 0x8c, 0x00, 0x79, - 0x77, 0xe3, 0xa1, 0x14, 0xf0, 0x0b, 0x45, 0xba, 0xd5, 0x79, 0xa6, 0xc9, - 0x61, 0x45, 0xda, 0x07, 0xb6, 0x67, 0xa4, 0x6c, 0x39, 0x45, 0x8d, 0xfd, - 0xc4, 0x00, 0xb0, 0x01, 0xf8, 0x8f, 0x6b, 0xcf, 0x9b, 0xaa, 0x5b, 0x16, - 0x21, 0x52, 0x7e, 0xc6, 0xc1, 0x90, 0xf1, 0xad, 0xf9, 0x59, 0x1d, 0xf1, - 0xf6, 0xf8, 0xf8, 0xf6, 0x99, 0x49, 0x86, 0xee, 0x75, 0xc6, 0x61, 0xb7, - 0x2d, 0x5a, 0xbb, 0x0f, 0xda, 0x79, 0xf5, 0xbb, 0xc2, 0xa0, 0x92, 0x7e, - 0xbf, 0x90, 0x0b, 0x61, 0x44, 0xed, 0x26, 0xe5, 0x91, 0xd9, 0x52, 0x69, - 0x95, 0x0b, 0x2e, 0x84, 0x56, 0xc9, 0xd8, 0xae, 0x45, 0x2e, 0x0a, 0x7c, - 0xb4, 0x9b, 0x15, 0x20, 0xfa, 0x6d, 0x2c, 0x28, 0xe6, 0xd2, 0x15, 0x1b, - 0x4d, 0xa5, 0x14, 0xdf, 0x3f, 0x9f, 0x3d, 0x89, 0xba, 0x87, 0x41, 0xaa, - 0x56, 0x0d, 0x56, 0xdf, 0x95, 0xf3, 0xdf, 0x2b, 0xf3, 0x68, 0xc7, 0x60, - 0xc9, 0x4b, 0x38, 0xaa, 0x71, 0x4d, 0x9f, 0xa9, 0x39, 0xdc, 0x5c, 0x29, - 0x7f, 0x57, 0x52, 0xdd, 0x42, 0x9b, 0xa5, 0x9d, 0x3f, 0x7e, 0x2c, 0xb7, - 0x61, 0x41, 0xd0, 0xa8, 0x54, 0x54, 0x0d, 0x38, 0x29, 0xa1, 0xb5, 0xab, - 0x4f, 0x6f, 0x3f, 0xd3, 0x89, 0xd7, 0x55, 0xe4, 0xed, 0xe7, 0x69, 0x35, - 0x06, 0x59, 0x22, 0x97, 0x4b, 0xfd, 0xb2, 0x74, 0x21, 0xf2, 0x45, 0x7d, - 0x50, 0xa3, 0xea, 0xa0, 0xf6, 0xe8, 0xfd, 0x44, 0x65, 0xe8, 0x07, 0x2f, - 0x55, 0xa6, 0xae, 0x52, 0xb1, 0x0a, 0x46, 0xe1, 0x3d, 0xdc, 0x60, 0xbf, - 0x38, 0x6c, 0x28, 0xf3, 0x0a, 0x85, 0x94, 0x3e, 0x56, 0x43, 0x19, 0xb7, - 0xaa, 0xf3, 0x79, 0xcc, 0x9c, 0x61, 0x94, 0xab, 0x62, 0x0c, 0x0a, 0x6d, - 0x80, 0x64, 0x59, 0x1b, 0x88, 0xe7, 0xec, 0x3c, 0x9d, 0x9c, 0xd7, 0xda, - 0xba, 0x8a, 0x34, 0x6b, 0x73, 0x5d, 0xd9, 0x07, 0xbd, 0xbc, 0xb8, 0xa2, - 0xee, 0x63, 0xae, 0x07, 0x5a, 0x85, 0x1e, 0x87, 0xd1, 0x8c, 0x80, 0x07, - 0xd1, 0xde, 0xd3, 0x9c, 0x2c, 0xb5, 0x58, 0x34, 0xb2, 0xe4, 0x0a, 0x8c, - 0xda, 0x63, 0x7d, 0xd1, 0x22, 0xc8, 0x9a, 0xec, 0xd3, 0x0d, 0x01, 0xc7, - 0x2f, 0xe4, 0xe8, 0x1f, 0x28, 0xcd, 0x81, 0x03, 0x55, 0xba, 0x93, 0xfe, - 0xff, 0x6b, 0xce, 0xcd, 0xef, 0x64, 0xd9, 0x8f, 0x9b, 0x2e, 0xdb, 0x38, - 0xc3, 0xe2, 0x0e, 0x29, 0xb8, 0x3f, 0x7e, 0x48, 0xc2, 0x3b, 0xd9, 0xb2, - 0xd3, 0xea, 0xef, 0x26, 0xe4, 0xae, 0x42, 0x8a, 0xa7, 0xdf, 0x02, 0x9b, - 0x3f, 0x26, 0x7c, 0xf4, 0x23, 0x5e, 0x3a, 0x4e, 0x21, 0xa9, 0x6c, 0xb4, - 0x62, 0x4a, 0x1a, 0xc0, 0xd6, 0x8c, 0x4b, 0x95, 0xbc, 0x4f, 0xde, 0x5c, - 0xec, 0x82, 0xde, 0xe2, 0xe9, 0x8e, 0x9c, 0xad, 0xa9, 0x87, 0xd2, 0x1b, - 0x5b, 0xee, 0x88, 0x92, 0xc8, 0x78, 0xd3, 0x88, 0x4d, 0xdf, 0x13, 0x3a, - 0xff, 0x7c, 0xe5, 0x76, 0x65, 0x4a, 0x1e, 0x9e, 0x56, 0x22, 0xd0, 0x21, - 0x07, 0x8f, 0x6f, 0x3b, 0xb6, 0x39, 0xef, 0xf2, 0x33, 0xc7, 0x24, 0xd4, - 0x38, 0x2d, 0x93, 0x69, 0x2a, 0xca, 0xda, 0x71, 0x6c, 0x7b, 0xf5, 0x42, - 0x92, 0x0f, 0x85, 0x46, 0xd9, 0xfc, 0xe7, 0x9f, 0x7e, 0x46, 0x0e, 0x48, - 0x5d, 0x64, 0x7e, 0xdf, 0x9c, 0x97, 0x8d, 0x94, 0x62, 0x1b, 0x84, 0xb4, - 0xa7, 0x05, 0x36, 0x98, 0xfb, 0xa2, 0x5d, 0x73, 0x85, 0xa3, 0x69, 0xea, - 0x50, 0x71, 0xd5, 0x88, 0xcd, 0xb4, 0x23, 0x3a, 0xf1, 0x96, 0x1b, 0xb2, - 0x04, 0x0e, 0x87, 0xfa, 0xb6, 0x67, 0xe4, 0xd7, 0x3a, 0x79, 0x50, 0xc3, - 0x12, 0x97, 0xbe, 0x07, 0x33, 0xba, 0x51, 0x1d, 0x24, 0x7d, 0x1d, 0xaf, - 0xd4, 0x2c, 0xe6, 0xe6, 0xcc, 0x9e, 0x7a, 0xb4, 0x26, 0xca, 0x7a, 0x50, - 0x1e, 0xb3, 0x8d, 0x6c, 0x00, 0x00, 0x01, 0x0a, 0x43, 0xf9, 0x00, 0x03, - 0xbf, 0xe0, 0xb1, 0x5c, 0x93, 0xba, 0x30, 0x72, 0x79, 0xf1, 0x4d, 0x53, - 0xac, 0x3e, 0x58, 0x53, 0x6f, 0xf9, 0x99, 0xc9, 0x1e, 0xf5, 0x2c, 0x80, - 0x4f, 0x96, 0xd8, 0xba, 0x81, 0x8a, 0x39, 0xbd, 0x28, 0x03, 0x87, 0xb8, - 0x8c, 0x29, 0xd6, 0xe4, 0x09, 0xdf, 0x3b, 0xaf, 0xa5, 0xa1, 0xf1, 0x55, - 0x21, 0xc3, 0x1b, 0xce, 0x08, 0xcf, 0x21, 0x4b, 0x2f, 0x8c, 0x6f, 0x1b, - 0x70, 0x9e, 0x4f, 0x8e, 0x50, 0x9c, 0xb1, 0x15, 0xbc, 0x74, 0x1c, 0xde, - 0xd0, 0xee, 0xf1, 0xd3, 0x20, 0x66, 0x61, 0x44, 0xda, 0x15, 0x21, 0x55, - 0xbd, 0x68, 0x03, 0xc7, 0xf1, 0xd7, 0x98, 0xbd, 0x4a, 0x7d, 0x97, 0x97, - 0xbe, 0xee, 0x97, 0x22, 0x42, 0xa8, 0xc8, 0x14, 0xde, 0x14, 0x9b, 0xce, - 0xad, 0x6b, 0x76, 0x51, 0x69, 0x90, 0x28, 0xa3, 0xda, 0x21, 0x52, 0x52, - 0x5b, 0x46, 0x1f, 0x15, 0xbf, 0xa0, 0x7b, 0x25, 0x11, 0xdf, 0x61, 0x20, - 0x13, 0xfe, 0x22, 0x14, 0x58, 0x70, 0xd2, 0xdb, 0xca, 0xda, 0x01, 0x53, - 0xdd, 0xb6, 0x20, 0xc2, 0xe7, 0x8b, 0x71, 0x04, 0x3a, 0x0a, 0xe6, 0x6e, - 0xec, 0x0d, 0x59, 0x12, 0x4f, 0x14, 0xad, 0xba, 0x02, 0x17, 0xfd, 0x3b, - 0x69, 0x2e, 0x92, 0x58, 0x2a, 0xd8, 0xa4, 0x26, 0xac, 0x2b, 0x15, 0xbf, - 0xb6, 0x80, 0x3b, 0x00, 0x5f, 0xec, 0x00, 0x5f, 0xfc, 0x8f, 0xe2, 0x74, - 0xa8, 0x4f, 0xc1, 0x62, 0x35, 0x61, 0x97, 0x13, 0x72, 0x9e, 0x10, 0xdf, - 0x6e, 0x11, 0xff, 0xe7, 0xa0, 0x06, 0x6f, 0xe5, 0xeb, 0xa3, 0x39, 0x79, - 0x97, 0x64, 0xa8, 0x9c, 0x5c, 0x59, 0x07, 0xb7, 0xe4, 0xfe, 0xf9, 0x00, - 0x35, 0xf6, 0x9c, 0xf9, 0xa4, 0x2e, 0x90, 0x3a, 0x49, 0x3b, 0xe4, 0x71, - 0x46, 0xd2, 0xa4, 0x3d, 0xbd, 0x0f, 0xfb, 0xed, 0x9f, 0x04, 0x70, 0x0a, - 0xfe, 0x05, 0x6d, 0x2f, 0xf2, 0x41, 0x5f, 0xc6, 0x61, 0x84, 0x0c, 0xcf, - 0xc2, 0x55, 0xb8, 0x78, 0x63, 0x67, 0xd3, 0xcc, 0xdf, 0x3b, 0x6a, 0x0f, - 0x74, 0x58, 0x81, 0x6d, 0xae, 0x5b, 0xa5, 0xd5, 0x0a, 0x6f, 0x9e, 0x2b, - 0x9a, 0x00, 0xf8, 0x8d, 0x9c, 0x65, 0x5b, 0x57, 0x79, 0x47, 0x48, 0x5d, - 0x55, 0x1a, 0x4a, 0x6f, 0x00, 0x2d, 0x61, 0x91, 0x47, 0x42, 0xc7, 0x48, - 0x51, 0xed, 0xea, 0xf5, 0xdc, 0x00, 0x3a, 0xec, 0x8a, 0x44, 0xec, 0x9f, - 0x00, 0x05, 0x3d, 0x90, 0x33, 0xbe, 0x6e, 0x69, 0xf0, 0x38, 0xb3, 0x2a, - 0x78, 0x94, 0xde, 0x0b, 0xfd, 0x40, 0x2d, 0xd7, 0xeb, 0x90, 0x35, 0x2e, - 0xd5, 0x83, 0x08, 0x4d, 0x35, 0x76, 0x54, 0xb0, 0x30, 0x29, 0xb0, 0xb0, - 0xb6, 0xfa, 0x36, 0xd7, 0xc8, 0xf9, 0x7d, 0x0a, 0xa0, 0x6d, 0xae, 0x27, - 0x10, 0x04, 0xdc, 0x40, 0x85, 0xb1, 0x5b, 0x81, 0xd6, 0x00, 0x19, 0x59, - 0x9a, 0xf0, 0x9b, 0x04, 0xcb, 0x81, 0x87, 0x05, 0xb6, 0x5f, 0xa7, 0x40, - 0x16, 0x08, 0x13, 0xcc, 0x81, 0x31, 0x0c, 0x84, 0xba, 0xdb, 0x4b, 0xe6, - 0xb2, 0x90, 0xd9, 0xd8, 0x39, 0xba, 0x78, 0x80, 0x07, 0xc2, 0x1d, 0x32, - 0xbe, 0x06, 0xcd, 0x47, 0x86, 0x0c, 0x94, 0x69, 0xe1, 0x8d, 0xbb, 0xdc, - 0xd0, 0x03, 0x9a, 0x40, 0x2a, 0xa5, 0x86, 0xe2, 0x26, 0xcf, 0x0d, 0x96, - 0x51, 0xc1, 0x8d, 0x92, 0xd7, 0xfd, 0x76, 0x0a, 0xc7, 0x28, 0xcc, 0x0f, - 0xe7, 0x22, 0x3e, 0x87, 0x43, 0xf4, 0x60, 0x62, 0x16, 0x5b, 0x6b, 0x22, - 0x6d, 0xf6, 0x23, 0x47, 0x62, 0x5a, 0xb6, 0xd8, 0x2b, 0xa8, 0xe9, 0xb7, - 0x76, 0x97, 0x4d, 0xd5, 0xb6, 0x90, 0xdb, 0x3f, 0xd4, 0x25, 0xb6, 0xd4, - 0xb6, 0xef, 0x32, 0x47, 0x45, 0x2c, 0xa3, 0xb3, 0xbd, 0x2b, 0x68, 0x1f, - 0x0a, 0x66, 0xe3, 0x00, 0x0f, 0xa1, 0x39, 0xf4, 0x6a, 0x20, 0x7e, 0x4a, - 0xa8, 0x70, 0xd5, 0x0d, 0x6b, 0x26, 0x5f, 0xbb, 0xf3, 0x64, 0xa1, 0x8b, - 0x5d, 0xbb, 0x2c, 0x08, 0x92, 0x17, 0xe0, 0xd4, 0xb9, 0xcb, 0xce, 0xf7, - 0x14, 0x24, 0x81, 0x66, 0x42, 0x13, 0x77, 0x40, 0x32, 0xa0, 0x5b, 0x7a, - 0x50, 0x0c, 0xcd, 0x24, 0xd6, 0xcb, 0xb5, 0x63, 0x9d, 0x28, 0x61, 0xb9, - 0xdb, 0xb0, 0xc8, 0x83, 0x07, 0x1e, 0x16, 0xdd, 0xb7, 0xe0, 0x00, 0x92, - 0xbd, 0xd2, 0x3a, 0xcf, 0xd0, 0x09, 0x2d, 0xa8, 0x7c, 0x58, 0x89, 0x14, - 0x22, 0xa3, 0x73, 0xfb, 0xb7, 0xdc, 0x40, 0x99, 0x2d, 0x01, 0x54, 0x9a, - 0x85, 0x1c, 0x37, 0x29, 0xc3, 0x4e, 0x6f, 0x57, 0xd7, 0x90, 0x8f, 0x81, - 0x62, 0x5d, 0xcb, 0xac, 0x01, 0x27, 0x90, 0xbc, 0xa9, 0x03, 0xd6, 0x02, - 0x27, 0xfe, 0x5b, 0x22, 0xf8, 0x28, 0xf6, 0xdd, 0xba, 0x23, 0x7c, 0xad, - 0xef, 0x7d, 0x9e, 0x27, 0x8c, 0xb9, 0x07, 0xee, 0xd7, 0x73, 0xbc, 0xef, - 0xe8, 0xe8, 0xa5, 0x7a, 0x37, 0x93, 0xd3, 0x45, 0x66, 0x27, 0x28, 0x19, - 0x6e, 0x6f, 0x9c, 0x18, 0x32, 0xd6, 0xd9, 0x78, 0x82, 0x81, 0x0b, 0xfe, - 0xab, 0xa0, 0xc2, 0xe5, 0x2a, 0xd2, 0x11, 0x5e, 0x25, 0xb6, 0x9c, 0xe5, - 0xef, 0x15, 0xaa, 0xe7, 0x02, 0x40, 0x01, 0x9b, 0xbb, 0x5f, 0xa1, 0x45, - 0x1c, 0x16, 0xc3, 0x4a, 0x23, 0x71, 0xdb, 0xbd, 0xbd, 0x79, 0x96, 0xd2, - 0x63, 0xb2, 0x3e, 0x2c, 0xb2, 0xd3, 0x51, 0x26, 0xf8, 0xb7, 0x4c, 0x49, - 0x31, 0xca, 0x65, 0x29, 0x10, 0xe4, 0xb1, 0x47, 0x35, 0x3f, 0x5e, 0x9f, - 0xc9, 0x75, 0x21, 0x72, 0xfe, 0xa2, 0xae, 0x12, 0xa8, 0xc6, 0xeb, 0xba, - 0xce, 0xc5, 0xde, 0x7a, 0xb4, 0x11, 0xbf, 0xf3, 0x75, 0xcf, 0x92, 0xcc, - 0xc0, 0xe8, 0x54, 0xab, 0x0b, 0x69, 0x67, 0x0f, 0xad, 0xd1, 0x9d, 0xed, - 0x17, 0x97, 0xbe, 0x86, 0xdc, 0x29, 0x4a, 0xbf, 0xaa, 0x36, 0x1c, 0x53, - 0x59, 0xed, 0xf1, 0x1c, 0xf7, 0xef, 0x1d, 0xc9, 0x40, 0x73, 0xb7, 0x56, - 0x3a, 0x64, 0x18, 0x16, 0x59, 0x61, 0x8d, 0x9c, 0x51, 0x05, 0xdd, 0x4a, - 0x27, 0x98, 0x34, 0x3a, 0xf2, 0xa9, 0x91, 0x0a, 0x2b, 0x00, 0xb6, 0x5d, - 0xef, 0x51, 0x5d, 0x62, 0x14, 0x4e, 0x92, 0xd2, 0xb1, 0xc7, 0xda, 0x58, - 0xe5, 0x0c, 0x66, 0xca, 0x16, 0x73, 0x7d, 0x22, 0x27, 0x09, 0x9a, 0x27, - 0xdf, 0x4d, 0x28, 0xb9, 0xba, 0xa8, 0x64, 0x2c, 0xe2, 0x8a, 0x88, 0x53, - 0x5b, 0xf5, 0xe2, 0x68, 0x18, 0x15, 0x24, 0xfd, 0x43, 0x6e, 0xd4, 0x43, - 0xb7, 0x16, 0x0e, 0x29, 0x5b, 0x17, 0x5b, 0x78, 0x78, 0x19, 0xe5, 0x3f, - 0x75, 0xcb, 0xbb, 0x46, 0x28, 0xd8, 0x73, 0x65, 0x8e, 0x77, 0x22, 0xb7, - 0x4d, 0x86, 0x0d, 0xbb, 0x6a, 0x98, 0x30, 0x60, 0x4b, 0x26, 0x1b, 0xb3, - 0xe1, 0xfa, 0x2b, 0xf2, 0x26, 0xa9, 0x52, 0xec, 0xda, 0x76, 0x49, 0x10, - 0x86, 0x31, 0xb4, 0xdf, 0x67, 0xfb, 0xbd, 0xf3, 0x5f, 0xaa, 0x52, 0x47, - 0xd9, 0x09, 0x67, 0x34, 0xde, 0x54, 0x4c, 0xb7, 0x28, 0x4e, 0x43, 0xc0, - 0x7c, 0xd6, 0x71, 0xa4, 0xe9, 0x76, 0xc8, 0xa7, 0x93, 0x6c, 0x98, 0xb4, - 0xb1, 0xb0, 0x74, 0x69, 0x6d, 0x02, 0x5b, 0xbb, 0xd8, 0x52, 0x71, 0xaf, - 0xbc, 0xc5, 0x50, 0xec, 0x94, 0xa8, 0x8a, 0x94, 0xb9, 0x3c, 0x5b, 0x95, - 0xc8, 0xb7, 0x0a, 0x7d, 0x97, 0x31, 0x0e, 0xb2, 0x3a, 0xa9, 0x91, 0x4b, - 0x29, 0x61, 0x5e, 0xac, 0xc4, 0xfa, 0x2a, 0x41, 0x83, 0x2e, 0x9a, 0x92, - 0x0e, 0x1e, 0x48, 0x6d, 0xdf, 0x63, 0x5f, 0x7b, 0xe6, 0xeb, 0xf7, 0x4f, - 0x9f, 0x89, 0x46, 0x42, 0x8b, 0x96, 0x8c, 0x60, 0xf6, 0x84, 0xb2, 0x9c, - 0xde, 0x5d, 0xdd, 0xf9, 0x85, 0xad, 0x9f, 0xa8, 0xa7, 0x59, 0xfa, 0x0c, - 0x1a, 0x16, 0xd7, 0xf3, 0xf3, 0xc7, 0x1c, 0xc9, 0x3a, 0xe0, 0x6d, 0xb5, - 0xd8, 0xb0, 0xe0, 0xc4, 0x6a, 0xba, 0x92, 0x45, 0x3e, 0x9e, 0x62, 0x42, - 0xfc, 0x4f, 0x6c, 0x1c, 0x3e, 0xf2, 0x65, 0x48, 0x75, 0x42, 0xe8, 0xd8, - 0x54, 0x61, 0x8d, 0x39, 0xbf, 0x5b, 0xf3, 0xce, 0x77, 0xf0, 0x27, 0x20, - 0x91, 0x68, 0x4c, 0xfc, 0xde, 0x52, 0x4e, 0x20, 0x66, 0x6c, 0x1b, 0x4a, - 0xa7, 0xc1, 0x8d, 0xcf, 0x13, 0xa2, 0x80, 0x0f, 0xdd, 0x82, 0xe6, 0x17, - 0x16, 0xe4, 0x18, 0x71, 0xa7, 0x28, 0x63, 0x73, 0x1d, 0x2b, 0x8a, 0x2c, - 0xa3, 0xcd, 0x7c, 0x85, 0x2c, 0x6e, 0x87, 0xb3, 0x8d, 0xcd, 0xba, 0xa3, - 0xe4, 0xa6, 0xe2, 0x50, 0xa6, 0x50, 0xa6, 0xdb, 0x75, 0x6d, 0x6e, 0xbf, - 0xc7, 0x96, 0x3b, 0x83, 0x90, 0xa7, 0x22, 0x19, 0x31, 0x14, 0x6a, 0x35, - 0x4e, 0xf3, 0x10, 0x29, 0xce, 0xb7, 0x6d, 0x3c, 0x3e, 0xf6, 0xb6, 0x0c, - 0x19, 0x69, 0xed, 0x5e, 0xdc, 0x11, 0xc6, 0x24, 0x09, 0x99, 0x6a, 0x16, - 0x16, 0x18, 0xda, 0x66, 0xaf, 0x9d, 0x36, 0x8d, 0x43, 0xc9, 0x8a, 0xc4, - 0x65, 0x68, 0x68, 0x16, 0xdf, 0x2b, 0xa7, 0x4e, 0xaf, 0x4f, 0xb2, 0x53, - 0x8a, 0xb6, 0xa5, 0xa4, 0x82, 0xe1, 0x2d, 0xac, 0xe3, 0xbc, 0xe3, 0x92, - 0xe6, 0x28, 0x0f, 0x10, 0xe1, 0x9e, 0x8d, 0x83, 0xab, 0xae, 0x32, 0x49, - 0x11, 0x20, 0xd0, 0x82, 0x9a, 0xcf, 0x8d, 0x7c, 0x73, 0x8d, 0xb6, 0xa8, - 0x10, 0x7d, 0x01, 0xab, 0x07, 0x30, 0x7d, 0x6d, 0xe6, 0x6b, 0x9d, 0xb6, - 0xbe, 0x8c, 0x08, 0x6a, 0x16, 0x72, 0xb2, 0x94, 0x04, 0x64, 0x85, 0xc0, - 0x92, 0xda, 0xae, 0x5d, 0xc6, 0x62, 0x71, 0xa1, 0x36, 0x86, 0x36, 0x0c, - 0xdd, 0xc9, 0x2b, 0xc2, 0xa0, 0x67, 0x84, 0x64, 0xc3, 0x00, 0x00, 0x00, - 0x01, 0x0b, 0x43, 0xf9, 0x16, 0xdf, 0x37, 0xad, 0x9e, 0xa7, 0x46, 0xde, - 0xf0, 0xfc, 0xc2, 0xef, 0x8b, 0x71, 0xd3, 0xcf, 0x16, 0x92, 0x8a, 0x6f, - 0x57, 0xc8, 0x21, 0x7f, 0xc8, 0x16, 0xb5, 0xbc, 0xb8, 0x52, 0xda, 0x43, - 0x6f, 0x16, 0x37, 0x5b, 0xd7, 0x0f, 0x0a, 0x1e, 0x1a, 0xd2, 0x53, 0x39, - 0xa0, 0x5b, 0x6c, 0x9f, 0x8b, 0x72, 0x7a, 0xca, 0xdc, 0xa9, 0x25, 0xc9, - 0x00, 0x20, 0x43, 0xa8, 0x09, 0x69, 0xed, 0x3a, 0x1f, 0x23, 0x4d, 0x2d, - 0xbe, 0x59, 0x84, 0x04, 0x99, 0x40, 0x47, 0x0c, 0x85, 0x85, 0x97, 0x49, - 0x2d, 0xda, 0x04, 0x3f, 0xfa, 0xb4, 0x92, 0xdc, 0x48, 0x08, 0x40, 0x0e, - 0x4e, 0x2b, 0xd7, 0x6d, 0x25, 0x95, 0x09, 0x4d, 0xe9, 0x39, 0xcb, 0xc9, - 0xb8, 0x43, 0xb1, 0xb1, 0xa3, 0x09, 0x0c, 0x8e, 0x46, 0xfa, 0x72, 0x10, - 0x76, 0x66, 0xdf, 0x0d, 0xb2, 0x2b, 0x68, 0x00, 0x6c, 0x28, 0x00, 0xf9, - 0xe4, 0x45, 0x35, 0x6a, 0x62, 0xd2, 0x21, 0x19, 0xe0, 0x66, 0x80, 0x47, - 0x69, 0xc1, 0x2a, 0x8c, 0x45, 0xc8, 0x2f, 0x2e, 0x2d, 0x38, 0xa5, 0x1b, - 0x83, 0x61, 0x55, 0xbd, 0x29, 0x17, 0xef, 0x84, 0x4f, 0x9b, 0xc3, 0xa0, - 0xf8, 0x6b, 0x84, 0xf5, 0x5f, 0xd1, 0x6e, 0xf3, 0xa1, 0xf9, 0x64, 0x9b, - 0x32, 0x14, 0x75, 0x52, 0xeb, 0x79, 0xf1, 0xe4, 0xe3, 0x0a, 0xa1, 0x54, - 0xb2, 0x89, 0x5e, 0x8d, 0x56, 0x1a, 0xdf, 0x82, 0xed, 0xfb, 0xc7, 0x41, - 0xe6, 0x58, 0x96, 0x1a, 0xae, 0x0b, 0x1c, 0x35, 0x0a, 0x18, 0xde, 0x64, - 0x5f, 0x39, 0xc7, 0xbe, 0x47, 0x66, 0xc3, 0xe6, 0xd5, 0x88, 0x51, 0xd4, - 0xf0, 0xca, 0xde, 0x88, 0x01, 0x87, 0xc7, 0x3d, 0x7f, 0x5d, 0xf3, 0xcf, - 0x2f, 0xe4, 0x99, 0x4c, 0x78, 0xa7, 0x65, 0x80, 0x16, 0x66, 0x2d, 0x57, - 0xa0, 0xca, 0x12, 0xdc, 0x3a, 0x2f, 0xa1, 0x1e, 0x5b, 0xcf, 0x57, 0x4e, - 0xdd, 0x4d, 0x89, 0x2d, 0x91, 0x70, 0xfa, 0xb2, 0x54, 0xa7, 0x96, 0xdd, - 0xb7, 0x12, 0x6c, 0x84, 0x30, 0x2d, 0xb7, 0xa5, 0x37, 0x9d, 0xf9, 0x78, - 0xeb, 0x64, 0xa1, 0x1b, 0x29, 0x5a, 0x80, 0x2b, 0x6c, 0x93, 0xf3, 0xce, - 0x61, 0x61, 0x85, 0xd9, 0x09, 0x2d, 0x8c, 0x57, 0x19, 0xf0, 0x29, 0xd3, - 0x24, 0x1b, 0x4f, 0xda, 0xfd, 0xa3, 0x49, 0xb6, 0xd5, 0xad, 0xa3, 0x87, - 0xe8, 0x9c, 0xe7, 0x78, 0x88, 0x00, 0x28, 0xce, 0x24, 0xbb, 0x54, 0xe1, - 0xb4, 0xe2, 0x13, 0x2b, 0x16, 0xd6, 0x8a, 0xdd, 0xc4, 0x6e, 0x35, 0xd8, - 0x9e, 0x7b, 0x46, 0xe9, 0xb8, 0xec, 0xc9, 0x2a, 0xad, 0xa8, 0x83, 0x6b, - 0x74, 0xfe, 0x6b, 0x80, 0x1c, 0xfc, 0x58, 0xee, 0xdf, 0x06, 0xe6, 0x3f, - 0x87, 0xf3, 0xc6, 0x44, 0x89, 0x29, 0x32, 0xa2, 0x4a, 0x59, 0xd5, 0x0f, - 0x6f, 0x31, 0x27, 0x96, 0xee, 0xa0, 0x52, 0x17, 0x5b, 0x50, 0x73, 0xf7, - 0x6e, 0x14, 0x03, 0xdd, 0x96, 0x14, 0x30, 0xea, 0xa3, 0x5b, 0x7d, 0xaa, - 0x95, 0xb7, 0xa3, 0x5b, 0xe9, 0x7f, 0x8d, 0x14, 0x26, 0x9a, 0xbe, 0x30, - 0xb9, 0x06, 0x96, 0xdb, 0xb6, 0x93, 0xba, 0xe9, 0xda, 0x09, 0x7f, 0xf5, - 0xed, 0xa8, 0xa7, 0x0e, 0x56, 0xf2, 0x7b, 0x60, 0x81, 0x0e, 0x96, 0xd0, - 0xd5, 0xbe, 0x28, 0xde, 0xfb, 0xea, 0xe7, 0x39, 0xe2, 0x78, 0x7e, 0x50, - 0xd9, 0xbf, 0x33, 0x49, 0xf6, 0x1c, 0x7b, 0xd6, 0x5c, 0xb9, 0x4a, 0x0a, - 0x66, 0xb7, 0x9d, 0x80, 0x53, 0x6d, 0x00, 0x29, 0xb2, 0xb6, 0xa2, 0xb9, - 0x04, 0x1f, 0xec, 0x7e, 0xf6, 0xed, 0x51, 0xc8, 0xe2, 0xa2, 0x8d, 0x2e, - 0xc5, 0x18, 0x59, 0xc9, 0x5b, 0xa5, 0x2c, 0xfb, 0x65, 0x9a, 0x19, 0x71, - 0x08, 0xe9, 0x6d, 0x90, 0x27, 0x92, 0xe2, 0xb5, 0x1f, 0xde, 0x60, 0x91, - 0x1d, 0x3d, 0xf7, 0x02, 0xc5, 0x74, 0x24, 0x53, 0xec, 0x38, 0xed, 0xa5, - 0xfa, 0x36, 0xc9, 0xba, 0x47, 0xc7, 0xde, 0x94, 0x32, 0xf1, 0x82, 0x77, - 0x9b, 0x14, 0x36, 0x06, 0x00, 0x8e, 0x37, 0x63, 0x7a, 0x0d, 0xf9, 0xde, - 0x67, 0x1d, 0x5f, 0x82, 0xb6, 0x9c, 0x98, 0x4e, 0x7c, 0xd4, 0x2d, 0x50, - 0xa3, 0x88, 0x6a, 0xdb, 0x78, 0xea, 0x77, 0xbf, 0x97, 0xbe, 0x81, 0x10, - 0x3b, 0x6c, 0xbf, 0xb1, 0xdb, 0x06, 0x78, 0x04, 0xb4, 0x12, 0x08, 0x40, - 0x0d, 0xb4, 0xd9, 0x60, 0x62, 0x3a, 0xd2, 0xd5, 0x61, 0xd4, 0xa2, 0x86, - 0x9e, 0xdc, 0xec, 0xa0, 0x06, 0x9d, 0xf3, 0xa9, 0x06, 0xa8, 0x04, 0xb5, - 0x7c, 0x07, 0xd3, 0xa0, 0x53, 0x03, 0x1a, 0x46, 0xb6, 0x08, 0xd3, 0x87, - 0x88, 0xdb, 0x82, 0xf9, 0x90, 0xac, 0xfc, 0xae, 0x19, 0x9c, 0x13, 0x57, - 0xc5, 0xba, 0x3b, 0x08, 0x3d, 0x42, 0x7c, 0x01, 0x56, 0x6c, 0x42, 0x9b, - 0xe7, 0x46, 0x87, 0xd8, 0x90, 0x30, 0xca, 0x02, 0xe6, 0xfa, 0xc1, 0x16, - 0xc0, 0x06, 0x64, 0x4e, 0xcd, 0x72, 0x14, 0xbb, 0xca, 0xae, 0x4d, 0x92, - 0xa1, 0xe8, 0x96, 0xc0, 0xa6, 0x74, 0xa6, 0x9c, 0xab, 0x4a, 0x6f, 0x33, - 0x9d, 0x39, 0xef, 0xa0, 0xeb, 0x42, 0xf6, 0x45, 0x1c, 0x77, 0xab, 0x76, - 0x1d, 0xef, 0xe4, 0x56, 0x2a, 0x16, 0x93, 0x12, 0x48, 0x65, 0x2d, 0x46, - 0x36, 0x5f, 0x90, 0x43, 0xff, 0x87, 0x59, 0xab, 0x12, 0xe4, 0x2a, 0x4d, - 0x2e, 0x55, 0x85, 0x21, 0xda, 0x16, 0xd8, 0x1f, 0xbc, 0x13, 0x9d, 0x92, - 0xec, 0x1b, 0x99, 0x72, 0x9d, 0x9a, 0x35, 0x4b, 0x3a, 0x05, 0x36, 0x67, - 0x36, 0x97, 0x4a, 0x46, 0xfd, 0x07, 0x3e, 0xe0, 0x16, 0x3e, 0xf1, 0x26, - 0x01, 0x2e, 0xf3, 0xa1, 0xd5, 0xd2, 0xc2, 0xce, 0xa3, 0x06, 0xfa, 0xb7, - 0x0e, 0x0b, 0xe0, 0x4f, 0x59, 0x93, 0x62, 0x17, 0x67, 0x73, 0x26, 0x62, - 0x6a, 0x06, 0x8d, 0xbe, 0x0c, 0x3b, 0xb8, 0x2f, 0x87, 0x64, 0xa3, 0x91, - 0xdc, 0xcd, 0x54, 0x28, 0x79, 0x0d, 0x83, 0xde, 0x62, 0x47, 0xa5, 0x38, - 0x9b, 0x2a, 0x98, 0x32, 0x9c, 0x8d, 0x11, 0xab, 0x46, 0xb6, 0xcf, 0xb2, - 0x72, 0x86, 0x6c, 0xa5, 0xfe, 0xd1, 0x12, 0xc2, 0xa3, 0x40, 0x0b, 0x6e, - 0x99, 0x71, 0x03, 0x26, 0x86, 0xa2, 0x56, 0x77, 0xdf, 0x37, 0xec, 0x5d, - 0x1d, 0x24, 0x51, 0x8d, 0x8b, 0xaf, 0xc1, 0x69, 0x07, 0xaa, 0x0c, 0x18, - 0xc4, 0x6a, 0xad, 0xd5, 0xe7, 0xc3, 0x8c, 0x7c, 0xcd, 0x2d, 0x69, 0x86, - 0x0f, 0x3e, 0x14, 0xa8, 0x4b, 0x6d, 0xa2, 0x77, 0xce, 0xd8, 0xeb, 0xd8, - 0x0f, 0x16, 0xd9, 0x2c, 0x88, 0x51, 0xed, 0xc2, 0x8f, 0x36, 0xc3, 0x10, - 0x75, 0x56, 0xec, 0xe7, 0x2f, 0x17, 0x7c, 0xaa, 0x4a, 0x02, 0x22, 0xd1, - 0x0f, 0x62, 0x14, 0xc5, 0x2e, 0x37, 0x7e, 0xc9, 0xc4, 0xb8, 0x90, 0x2f, - 0xd4, 0x05, 0xed, 0x9c, 0xc3, 0x76, 0xd5, 0x08, 0x4b, 0x1b, 0xaa, 0xe9, - 0xe5, 0x8b, 0x54, 0xa4, 0x6e, 0x7e, 0xd7, 0x64, 0x0e, 0x94, 0xe2, 0xcb, - 0xa5, 0x14, 0x35, 0xa0, 0x61, 0x4d, 0xaa, 0x96, 0x5b, 0x6a, 0xb9, 0xb7, - 0xf6, 0x19, 0x30, 0xb2, 0xea, 0xad, 0x6c, 0x5b, 0xcb, 0x8c, 0xcf, 0x2b, - 0x14, 0xea, 0xa8, 0x5c, 0x52, 0xce, 0x6e, 0x98, 0xae, 0xd0, 0xdb, 0x2d, - 0x19, 0x25, 0x42, 0xc8, 0x6d, 0xcc, 0xfc, 0xf5, 0x96, 0xee, 0xd1, 0xe3, - 0x68, 0x53, 0x38, 0xd9, 0x9c, 0xde, 0xff, 0xc4, 0xe6, 0xc3, 0x68, 0x59, - 0xed, 0x88, 0x57, 0x3b, 0x95, 0x77, 0x3c, 0x06, 0x23, 0x54, 0x25, 0xdc, - 0xf2, 0xe5, 0xe7, 0x8e, 0x1f, 0x94, 0x39, 0xf2, 0x53, 0x9b, 0xe8, 0x00, - 0x81, 0xfa, 0xa0, 0x0f, 0xbe, 0x40, 0x1e, 0xfd, 0xb8, 0x8e, 0x16, 0xe3, - 0x4d, 0x97, 0xae, 0x05, 0xee, 0x43, 0x2c, 0x7e, 0x5b, 0x03, 0xe5, 0x38, - 0x7b, 0x54, 0x65, 0x1b, 0xf9, 0xe9, 0x13, 0x1e, 0x91, 0x47, 0x14, 0x79, - 0x74, 0xa6, 0x4b, 0xd5, 0xc1, 0x56, 0xaa, 0x84, 0x54, 0x59, 0x11, 0x61, - 0x45, 0x0c, 0x6f, 0xba, 0x02, 0x07, 0xe7, 0x80, 0x59, 0x9f, 0xda, 0xe1, - 0x19, 0x34, 0x38, 0xde, 0x5f, 0x61, 0x97, 0x65, 0xc8, 0x62, 0xda, 0x3c, - 0xb4, 0x8d, 0xec, 0x7e, 0x08, 0xa4, 0x70, 0x06, 0xbf, 0xf8, 0xfa, 0xfe, - 0xe8, 0x76, 0x4b, 0x86, 0xc8, 0x4c, 0xcc, 0x83, 0x1b, 0xcd, 0x22, 0x73, - 0x1d, 0xcb, 0x9f, 0x96, 0x51, 0xd2, 0x37, 0x08, 0x87, 0x99, 0xb9, 0xb3, - 0xd1, 0xbf, 0x92, 0x02, 0x07, 0xe6, 0x7d, 0xa0, 0x03, 0x3f, 0xe3, 0xf8, - 0xf8, 0xf9, 0xca, 0x95, 0x1d, 0xe6, 0x85, 0xe3, 0x9f, 0x0b, 0x85, 0x50, - 0xc5, 0x6f, 0xd0, 0x00, 0x05, 0x20, 0x0e, 0x44, 0xfd, 0x40, 0x1f, 0xf7, - 0xaf, 0xeb, 0x40, 0x8e, 0xb8, 0xc2, 0xec, 0x31, 0x57, 0x74, 0x29, 0xbb, - 0xe0, 0x0c, 0x39, 0xdf, 0x8e, 0xe5, 0xde, 0x10, 0x22, 0xc0, 0x2e, 0x36, - 0x92, 0x25, 0xd1, 0x3f, 0x05, 0x50, 0x92, 0x88, 0x48, 0xd6, 0x20, 0x5f, - 0x06, 0x39, 0xf7, 0x28, 0x4e, 0x36, 0x5c, 0x24, 0xc9, 0x6b, 0x00, 0x00, - 0x00, 0x01, 0x0c, 0x43, 0xd4, 0x08, 0x1f, 0xa2, 0x01, 0x61, 0x14, 0x5e, - 0x67, 0xf0, 0x4e, 0xcf, 0xd6, 0xf2, 0xfe, 0x71, 0x0c, 0xe2, 0x54, 0xda, - 0xb6, 0x8c, 0x0a, 0xad, 0xd1, 0x00, 0x63, 0x8f, 0x22, 0x88, 0x22, 0xbb, - 0xbb, 0x4e, 0x04, 0x50, 0x0f, 0xb9, 0x5f, 0x25, 0x0f, 0xfd, 0xf9, 0xe4, - 0x28, 0x25, 0xbe, 0xad, 0xa2, 0xdc, 0x00, 0xd0, 0x00, 0x45, 0x9c, 0x50, - 0xc0, 0xe8, 0x6e, 0xbe, 0xad, 0x32, 0xfe, 0xe5, 0x26, 0xc2, 0x86, 0x54, - 0x63, 0xc8, 0x82, 0x7f, 0xc8, 0x03, 0xd0, 0xfb, 0x6f, 0xec, 0x10, 0x80, - 0x2a, 0xbf, 0xcc, 0x02, 0x27, 0x75, 0x2c, 0x0d, 0x3d, 0xbc, 0x2a, 0x93, - 0x65, 0x28, 0x02, 0x23, 0xdb, 0x8b, 0x74, 0xc2, 0xe9, 0x09, 0xbf, 0xc9, - 0x70, 0x10, 0x80, 0x1e, 0x47, 0xa4, 0x0d, 0xab, 0x52, 0x0e, 0x3a, 0x8d, - 0xa1, 0x6c, 0x2e, 0x2c, 0x59, 0xb4, 0x36, 0xda, 0x53, 0x0c, 0xfc, 0x57, - 0x00, 0x0c, 0x24, 0x39, 0x9c, 0xb7, 0x8d, 0xf4, 0x2d, 0xb7, 0x85, 0xda, - 0xdc, 0x0d, 0xf2, 0xb9, 0x03, 0x12, 0x42, 0x44, 0x6f, 0x75, 0xb2, 0xf6, - 0xfe, 0xcd, 0x0a, 0x0f, 0x35, 0xbc, 0xe6, 0x97, 0x8a, 0x42, 0xa6, 0x52, - 0x5a, 0x37, 0xd3, 0x04, 0xbf, 0xf3, 0x6b, 0xac, 0x0d, 0xf3, 0xdd, 0xd9, - 0x26, 0x1e, 0x36, 0x5a, 0x54, 0x3c, 0x6b, 0x4c, 0x2e, 0xa1, 0x29, 0x59, - 0x46, 0xf7, 0x7d, 0xbe, 0x35, 0xcf, 0xfe, 0xbb, 0x45, 0xe9, 0xd2, 0xeb, - 0x89, 0xfc, 0xef, 0x7c, 0xbe, 0x58, 0x6c, 0xa9, 0xe7, 0x13, 0x33, 0x32, - 0x18, 0x7c, 0x0b, 0x6f, 0x9d, 0x4e, 0x32, 0xe7, 0x19, 0x96, 0x0f, 0xb9, - 0x0e, 0xa6, 0x42, 0xce, 0x5a, 0x5d, 0x6a, 0x28, 0x88, 0xe7, 0x4f, 0x2b, - 0x90, 0x73, 0xed, 0x98, 0xaf, 0x53, 0xcb, 0x44, 0x08, 0x6b, 0x30, 0x38, - 0x5e, 0x6c, 0x88, 0x02, 0xb9, 0x57, 0xd6, 0x37, 0x9c, 0x98, 0x61, 0x49, - 0x46, 0xa6, 0x52, 0x99, 0x99, 0x23, 0x7d, 0x90, 0x05, 0x84, 0x52, 0x38, - 0xaf, 0xa8, 0x94, 0xf6, 0x2c, 0x11, 0x00, 0x17, 0x08, 0x98, 0xe3, 0x66, - 0xf2, 0x62, 0xc5, 0xf2, 0x0c, 0xa1, 0x4d, 0xf2, 0x27, 0x49, 0x38, 0x73, - 0x8b, 0x1e, 0x54, 0x87, 0x81, 0x4d, 0xd1, 0xca, 0x00, 0x64, 0xe7, 0x29, - 0x0a, 0x94, 0xdc, 0xc5, 0x9e, 0x51, 0xf5, 0x42, 0x0d, 0x75, 0x84, 0x30, - 0xc6, 0xf4, 0xf2, 0x2e, 0x54, 0xf4, 0x56, 0xe9, 0x90, 0xaa, 0x49, 0x6c, - 0x9e, 0xe0, 0x2d, 0xb3, 0xd4, 0x14, 0xf8, 0x00, 0x31, 0x88, 0xdd, 0xf2, - 0x3b, 0xaf, 0x3a, 0x59, 0x0d, 0xb2, 0x55, 0xfa, 0x1b, 0x62, 0xd0, 0xb2, - 0x43, 0x22, 0x64, 0x64, 0x39, 0xbe, 0x54, 0x4e, 0xf3, 0x11, 0x43, 0x0f, - 0x48, 0xbe, 0xad, 0xa3, 0xad, 0xd1, 0x53, 0xf2, 0xa0, 0x53, 0x71, 0xac, - 0x3a, 0xa8, 0x4a, 0x94, 0xdd, 0x17, 0xec, 0x58, 0x6a, 0x06, 0x29, 0x4a, - 0x39, 0xa1, 0x4e, 0x8c, 0xe3, 0x68, 0xa0, 0x16, 0xf1, 0xc6, 0xcd, 0x09, - 0x2e, 0x4a, 0xbe, 0xad, 0xfa, 0x64, 0x01, 0xb8, 0x9a, 0x00, 0xeb, 0xee, - 0x00, 0xe7, 0x7d, 0xfc, 0xa4, 0x28, 0xcc, 0x00, 0x3d, 0x17, 0xc3, 0x9d, - 0x07, 0x95, 0x84, 0xed, 0xb8, 0xb4, 0x07, 0x8b, 0x6b, 0x7e, 0x71, 0xdf, - 0xcb, 0xf2, 0x10, 0x8a, 0x6f, 0xd3, 0x20, 0x0a, 0x14, 0x10, 0x40, 0x4c, - 0x8f, 0xdd, 0xf3, 0xa0, 0x11, 0x73, 0xb9, 0xb0, 0x05, 0x4a, 0xb4, 0x34, - 0x62, 0xb7, 0x36, 0x6c, 0xe3, 0x7c, 0xb2, 0xe0, 0x6a, 0xee, 0xc0, 0x86, - 0x98, 0x5e, 0xe4, 0x25, 0xb7, 0xf2, 0x89, 0x08, 0x3e, 0xf4, 0x55, 0x40, - 0x47, 0xff, 0xd8, 0x27, 0x5d, 0xce, 0x48, 0x08, 0xff, 0xfb, 0xf8, 0x99, - 0xa5, 0x04, 0x94, 0x5b, 0x74, 0x2e, 0x80, 0x1f, 0x00, 0x1b, 0x23, 0xe5, - 0x02, 0x64, 0x76, 0x76, 0xa5, 0x94, 0x4c, 0xcd, 0x2e, 0x12, 0x9b, 0x37, - 0x34, 0x0c, 0x11, 0x4e, 0x0c, 0xbd, 0x0a, 0x17, 0x2e, 0x20, 0xdf, 0xd6, - 0xe6, 0x6d, 0x01, 0x1d, 0x48, 0xdd, 0x4b, 0x00, 0x0f, 0x05, 0x0a, 0xe1, - 0x36, 0x06, 0x42, 0x2c, 0x7c, 0xc0, 0xc1, 0x9e, 0x72, 0x16, 0x18, 0xde, - 0xb0, 0xc6, 0xf6, 0xcf, 0x6f, 0xce, 0x7b, 0x26, 0x4d, 0x4d, 0x7d, 0x18, - 0x55, 0x33, 0x65, 0xbb, 0x14, 0x08, 0x7d, 0xb5, 0xb8, 0xcb, 0x5d, 0xc7, - 0x1b, 0x60, 0xec, 0x99, 0x2c, 0x0e, 0x1e, 0x03, 0x36, 0xeb, 0x48, 0xff, - 0x62, 0x05, 0xb8, 0x58, 0xd4, 0x15, 0x3c, 0xb6, 0xd3, 0xa0, 0xd9, 0xa9, - 0xe2, 0xad, 0x97, 0x90, 0x42, 0xff, 0x5d, 0xbc, 0x20, 0x5e, 0x24, 0x2e, - 0xfa, 0x12, 0x98, 0x87, 0xb5, 0x53, 0x9b, 0x41, 0x22, 0xf4, 0x5f, 0x7c, - 0xef, 0x96, 0xd8, 0x32, 0x4e, 0x9c, 0x62, 0x8d, 0xfd, 0xac, 0x29, 0xbd, - 0x29, 0x19, 0xd3, 0xeb, 0xfd, 0xee, 0xd1, 0x7b, 0x75, 0x64, 0x7c, 0x5c, - 0xd9, 0x92, 0x4a, 0xba, 0x9e, 0x70, 0x9a, 0x90, 0x39, 0xb8, 0x2b, 0x09, - 0xf9, 0x64, 0x09, 0xb1, 0x70, 0xe1, 0xa7, 0x44, 0x3c, 0x21, 0xae, 0x74, - 0xd7, 0x08, 0xce, 0x67, 0x36, 0xd4, 0x3b, 0x69, 0x91, 0xd2, 0x58, 0x7a, - 0xc2, 0x83, 0x94, 0xb6, 0x89, 0x1b, 0x3a, 0x54, 0x56, 0xf4, 0xdc, 0xf6, - 0x15, 0xaf, 0xa2, 0xb2, 0x40, 0x09, 0x6c, 0x31, 0x16, 0xa1, 0xc3, 0xce, - 0x39, 0xb0, 0xe5, 0x79, 0x3d, 0xf5, 0xf2, 0x2f, 0xe9, 0x23, 0xa2, 0xa5, - 0x3c, 0x29, 0xbb, 0x3c, 0xdd, 0x14, 0x2f, 0x71, 0x0b, 0x3b, 0x3c, 0xae, - 0x38, 0xfa, 0x12, 0x35, 0x02, 0x5b, 0x3a, 0xce, 0xd3, 0x8e, 0x8b, 0x02, - 0x43, 0xb0, 0x3e, 0x0f, 0x2a, 0xfa, 0xb4, 0xc8, 0x53, 0x6d, 0xb5, 0x6b, - 0x6d, 0xce, 0xae, 0x5d, 0x18, 0x7c, 0x2d, 0x42, 0x9a, 0xfd, 0xd8, 0xfb, - 0x37, 0x28, 0x4d, 0xa5, 0x9c, 0x15, 0xea, 0xdc, 0x8e, 0xb2, 0xe7, 0x50, - 0xe8, 0x3e, 0x86, 0x8c, 0x21, 0x04, 0xb5, 0xb7, 0x11, 0xf0, 0xb1, 0xc7, - 0x0f, 0x30, 0xf2, 0xda, 0x6b, 0x68, 0xde, 0xcc, 0xf3, 0x72, 0xee, 0xbe, - 0x8e, 0xc2, 0xce, 0x90, 0x90, 0xdc, 0xd1, 0x40, 0x61, 0xd6, 0xdb, 0xb4, - 0xe0, 0xc1, 0xc8, 0xcc, 0x08, 0x60, 0x0b, 0x99, 0xa3, 0x4e, 0xab, 0xa3, - 0x1b, 0x1b, 0xdf, 0xe7, 0x61, 0xc0, 0x3c, 0x33, 0x2c, 0x09, 0x0d, 0x62, - 0x56, 0x2b, 0x76, 0x75, 0x72, 0xda, 0x99, 0x96, 0x8d, 0xb6, 0x16, 0xd8, - 0xf2, 0x9b, 0xce, 0x92, 0x0f, 0x6d, 0x8e, 0x7d, 0xc7, 0x9b, 0x32, 0x0d, - 0x2f, 0x10, 0xb8, 0xa5, 0x9c, 0xce, 0x26, 0x00, 0x1f, 0xfb, 0x48, 0x81, - 0xa6, 0xdc, 0xb9, 0xb3, 0xd4, 0xe6, 0x89, 0x52, 0x94, 0xd9, 0x66, 0xcc, - 0x79, 0x4d, 0xd3, 0x99, 0x67, 0x05, 0xa4, 0x0b, 0x53, 0xdb, 0xd4, 0x80, - 0x37, 0x14, 0xef, 0xaf, 0x5b, 0xc3, 0xbd, 0xf9, 0xca, 0x96, 0xbb, 0x1f, - 0xbc, 0x2d, 0x93, 0x5d, 0x77, 0x28, 0x6a, 0x96, 0xde, 0x9f, 0xe4, 0x47, - 0xbf, 0xfc, 0x01, 0x8f, 0x5f, 0x0e, 0x76, 0xaa, 0x19, 0x86, 0xbd, 0xff, - 0xb1, 0xbe, 0x90, 0xb6, 0xc1, 0x05, 0xf1, 0xbf, 0x1f, 0x1c, 0x00, 0x56, - 0xf9, 0x2e, 0x69, 0x3a, 0xf3, 0xd1, 0x99, 0xa5, 0x87, 0xa8, 0x79, 0x92, - 0x16, 0x10, 0xdc, 0xbd, 0x07, 0x00, 0xe4, 0x84, 0xde, 0x68, 0x89, 0xe5, - 0x57, 0x42, 0x9b, 0xe9, 0x80, 0x14, 0xfc, 0x8a, 0x77, 0x28, 0x2a, 0x3a, - 0x87, 0x4f, 0x37, 0x17, 0x71, 0x12, 0x1b, 0x0e, 0xf5, 0x6e, 0xc8, 0x01, - 0x3f, 0xce, 0x7c, 0x90, 0x26, 0xfb, 0x75, 0xfb, 0xf2, 0x79, 0x92, 0x9b, - 0x13, 0xf0, 0xb6, 0x0f, 0x5b, 0x5b, 0xd9, 0x80, 0x3c, 0xff, 0xe7, 0xc9, - 0x07, 0x7a, 0x9d, 0xc9, 0x40, 0x27, 0x2e, 0x66, 0xdb, 0x51, 0x74, 0xe1, - 0xd5, 0x50, 0xe8, 0xad, 0xee, 0xfe, 0x3f, 0xa2, 0x9e, 0x2c, 0x5e, 0x76, - 0xf7, 0xc0, 0x1e, 0x73, 0x39, 0xc7, 0xc8, 0x90, 0x38, 0x3a, 0xad, 0x44, - 0x38, 0x31, 0xbc, 0xde, 0xc4, 0x0a, 0xb8, 0x55, 0x2c, 0x34, 0xe8, 0x8d, - 0xca, 0xe7, 0x70, 0x88, 0x58, 0x5b, 0x7f, 0x34, 0x00, 0x78, 0x23, 0x90, - 0x03, 0x5e, 0xfd, 0xe7, 0xce, 0x5a, 0x4d, 0xe6, 0xbf, 0x76, 0xed, 0xa6, - 0x17, 0x87, 0x7a, 0x1c, 0xdd, 0xd0, 0x04, 0xd8, 0x29, 0xfb, 0x5f, 0xc6, - 0xec, 0x85, 0x2f, 0x96, 0xd5, 0xf2, 0x0b, 0xc0, 0xc6, 0xbb, 0xe8, 0x47, - 0x70, 0x03, 0xa2, 0x27, 0xba, 0xc1, 0x38, 0xaa, 0x66, 0x13, 0x95, 0x64, - 0xb1, 0x69, 0x41, 0x10, 0xb6, 0xf8, 0xb7, 0xb8, 0x8a, 0x46, 0xaf, 0x93, - 0xe3, 0x61, 0xf3, 0x97, 0x73, 0x1e, 0x67, 0x9c, 0x3a, 0xc5, 0x68, 0x7b, - 0xb8, 0xe9, 0x54, 0xa1, 0xb4, 0x04, 0x4d, 0xcd, 0x33, 0x31, 0x16, 0x46, - 0xfe, 0xd4, 0x00, 0xe9, 0xdc, 0x7c, 0x08, 0x7e, 0xe4, 0xbb, 0x52, 0x07, - 0xea, 0x54, 0x92, 0x0d, 0x6f, 0x0f, 0x7b, 0xc7, 0x6f, 0x4e, 0xeb, 0x50, - 0x11, 0xff, 0xef, 0x74, 0xcc, 0x43, 0xce, 0xaa, 0xdc, 0x91, 0x41, 0xc2, - 0xc8, 0xb3, 0x71, 0x00, 0x8c, 0x9d, 0xed, 0xc9, 0x10, 0xea, 0x6a, 0xe4, - 0x5a, 0x18, 0xdc, 0x20, 0x0a, 0x3a, 0xf6, 0x7f, 0x0e, 0xa2, 0x5c, 0x3b, - 0x76, 0xcc, 0xab, 0x2c, 0x4a, 0x50, 0x6f, 0x83, 0x79, 0xfc, 0x8a, 0x9e, - 0x4e, 0x8e, 0x74, 0xa1, 0x35, 0x5b, 0x33, 0x11, 0x12, 0x37, 0xd7, 0x00, - 0x40, 0xff, 0x79, 0xa2, 0x1d, 0x5d, 0x5d, 0x2a, 0xd9, 0x5e, 0xe3, 0x0d, - 0xa1, 0x6d, 0xf6, 0x00, 0x05, 0xdf, 0x34, 0x01, 0xb8, 0x03, 0xce, 0x6f, - 0x7d, 0x82, 0x47, 0xfe, 0x38, 0xda, 0x62, 0x1f, 0x0b, 0x81, 0xad, 0xf0, - 0xbe, 0xbe, 0xff, 0x22, 0x44, 0xed, 0xdf, 0x83, 0x16, 0xd8, 0xe7, 0x66, - 0xa1, 0x86, 0xdf, 0xca, 0x25, 0x28, 0xf8, 0xdf, 0x5c, 0x9f, 0x5e, 0xff, - 0xe2, 0xb7, 0xae, 0xf9, 0xe6, 0x8d, 0x2a, 0xd5, 0x36, 0x40, 0xc6, 0xf6, - 0x36, 0xbf, 0x97, 0xc3, 0x6e, 0x96, 0x4a, 0x6d, 0xa0, 0x7d, 0x8a, 0x4a, - 0x60, 0x00, 0x00, 0x01, 0x0d, 0x43, 0xf7, 0xdd, 0x8a, 0x78, 0x80, 0x06, - 0xc0, 0x0d, 0x05, 0x73, 0x52, 0x25, 0x20, 0x02, 0x10, 0x03, 0xf7, 0x2b, - 0x8d, 0x50, 0xea, 0x6d, 0xa5, 0x95, 0x43, 0x65, 0x6f, 0x4c, 0x00, 0xf8, - 0x5b, 0x80, 0x1b, 0x77, 0xcf, 0xcd, 0xdc, 0xa3, 0xe7, 0x9f, 0x0b, 0x24, - 0x3a, 0xfe, 0xa5, 0x29, 0x43, 0x1a, 0x10, 0x34, 0x89, 0xcd, 0xde, 0x5f, - 0xc5, 0xa7, 0x77, 0x37, 0xc9, 0x21, 0x8a, 0x61, 0xc1, 0x2d, 0xf3, 0xe0, - 0x07, 0xc0, 0x0d, 0x78, 0xe7, 0xe4, 0x88, 0xff, 0x6f, 0x68, 0x85, 0xf9, - 0x3e, 0x6d, 0x96, 0x6e, 0x2a, 0x40, 0xe9, 0x21, 0x77, 0xc1, 0xbc, 0x34, - 0xfc, 0x56, 0xe7, 0x96, 0x64, 0xb2, 0xac, 0xa5, 0x8e, 0x52, 0x82, 0x02, - 0x5b, 0xf8, 0x7d, 0xcb, 0xe7, 0x95, 0x60, 0x62, 0x4b, 0x2c, 0x21, 0x56, - 0xd9, 0x06, 0xd6, 0xfa, 0xb0, 0x02, 0x1c, 0x80, 0x09, 0x1c, 0x28, 0x89, - 0xf5, 0x10, 0xf8, 0x1d, 0x67, 0x7c, 0xf6, 0xee, 0xa4, 0x35, 0xda, 0x5e, - 0x54, 0x1c, 0xa3, 0x61, 0x4d, 0x98, 0x10, 0x3f, 0x4b, 0xf9, 0xa0, 0x0f, - 0xfe, 0x33, 0x3d, 0x88, 0xf9, 0x46, 0x49, 0xdb, 0xf2, 0x24, 0xe3, 0x4b, - 0xb8, 0xaa, 0xd9, 0xc2, 0xe2, 0x94, 0xde, 0x7b, 0xe1, 0xcd, 0xf1, 0x80, - 0x1c, 0x8a, 0xec, 0x01, 0x0f, 0xf0, 0x43, 0xb5, 0xd8, 0x1b, 0x39, 0x9d, - 0x87, 0x28, 0x0a, 0xa8, 0xdf, 0x46, 0xfb, 0x7f, 0x7e, 0x77, 0xfe, 0x40, - 0x31, 0xf4, 0x63, 0xae, 0x3b, 0xf3, 0x77, 0xc1, 0x0a, 0x40, 0xb6, 0xfa, - 0x37, 0xf7, 0xe7, 0xbf, 0xa8, 0x03, 0x71, 0x62, 0x44, 0xe8, 0x62, 0x6b, - 0xd4, 0x39, 0x3f, 0x08, 0x98, 0x32, 0x48, 0xdf, 0x3f, 0xfe, 0x0b, 0x00, - 0x10, 0x67, 0x57, 0x66, 0x0c, 0xa5, 0xe1, 0x65, 0x9e, 0xd3, 0x23, 0xba, - 0xe5, 0xf6, 0xda, 0x02, 0x29, 0x0b, 0x6b, 0xdb, 0x31, 0xf4, 0xbf, 0x06, - 0xfe, 0x5f, 0xdf, 0xbe, 0xfd, 0xb2, 0x75, 0xd6, 0xd4, 0x2d, 0x65, 0x88, - 0x89, 0xe8, 0xde, 0x08, 0x00, 0xf5, 0xe2, 0x3d, 0x9c, 0xfe, 0x79, 0xc9, - 0x13, 0xf0, 0xee, 0xe0, 0xea, 0x03, 0x56, 0xfa, 0x3f, 0xd5, 0xc0, 0x82, - 0x02, 0x7e, 0xdc, 0x9a, 0x5c, 0x39, 0x49, 0xf9, 0x21, 0xdb, 0x25, 0x2e, - 0x0d, 0x6f, 0x8d, 0x75, 0x67, 0x44, 0x0e, 0x6a, 0x84, 0x3d, 0x72, 0x98, - 0x38, 0xe1, 0xc3, 0x5b, 0x93, 0x78, 0x82, 0x66, 0xbb, 0x89, 0x83, 0xe2, - 0x5c, 0x6c, 0x2c, 0x34, 0xa8, 0xda, 0x11, 0x45, 0xe0, 0x87, 0x53, 0x2b, - 0x8e, 0x53, 0x35, 0x15, 0x2a, 0x1c, 0x1a, 0x90, 0xe6, 0xa3, 0xfb, 0xb6, - 0xed, 0xb6, 0x00, 0x46, 0x5d, 0x28, 0x28, 0x31, 0xbd, 0x8e, 0x77, 0x78, - 0xa2, 0xf5, 0xd8, 0x17, 0x69, 0xcd, 0xe0, 0x3e, 0xd2, 0xfd, 0x51, 0x20, - 0x5e, 0xcd, 0xca, 0xa8, 0x71, 0x68, 0xde, 0x97, 0xee, 0xb6, 0x92, 0x14, - 0x5b, 0x76, 0xce, 0x9d, 0xc0, 0x9d, 0x57, 0x00, 0xaa, 0xa0, 0xd8, 0x31, - 0xbc, 0xe0, 0xa9, 0x38, 0xe1, 0xda, 0x50, 0x48, 0xc8, 0xad, 0xf4, 0x0e, - 0x45, 0xe6, 0xfd, 0x26, 0xc7, 0xe1, 0x55, 0x1e, 0xb5, 0xd9, 0xa1, 0xd4, - 0x3c, 0x7c, 0x94, 0xa3, 0xda, 0x00, 0x27, 0xf9, 0xf6, 0xfa, 0x8a, 0x23, - 0x77, 0x5f, 0x14, 0x11, 0x00, 0x13, 0xae, 0xc8, 0x84, 0x7e, 0xf8, 0x8e, - 0x81, 0x1b, 0xc6, 0xae, 0xc8, 0x34, 0xa2, 0x8b, 0x6a, 0x44, 0x18, 0xda, - 0x13, 0x65, 0x6f, 0xe6, 0xe0, 0x38, 0xdb, 0x23, 0x6d, 0xd2, 0xe0, 0x16, - 0xd9, 0x3d, 0xdd, 0x08, 0x12, 0x3b, 0x68, 0x69, 0xb6, 0x8f, 0x2d, 0xb7, - 0xda, 0xaf, 0xb4, 0xc0, 0x82, 0xc6, 0x34, 0x51, 0xa4, 0xa6, 0x34, 0xaa, - 0xde, 0xde, 0xcc, 0x32, 0xcb, 0x35, 0x06, 0xd8, 0x55, 0x42, 0xd4, 0x7b, - 0x75, 0xbe, 0x94, 0x02, 0xdf, 0x99, 0x5e, 0xfc, 0x0c, 0x8e, 0xda, 0x52, - 0xd0, 0xc5, 0xb1, 0xb9, 0xe4, 0x68, 0xff, 0x97, 0xdd, 0x2c, 0xe5, 0x5d, - 0xdf, 0x27, 0x2c, 0xc2, 0xce, 0x3e, 0xb6, 0xbe, 0xb9, 0xbe, 0xde, 0xd8, - 0xee, 0x02, 0x6c, 0xc9, 0x0a, 0x83, 0x21, 0x50, 0x73, 0x73, 0xd3, 0x64, - 0x96, 0x46, 0x76, 0xa5, 0x6f, 0xde, 0xdb, 0xa4, 0x7f, 0x8f, 0x67, 0x6d, - 0xa3, 0xd2, 0xb8, 0x47, 0x75, 0xca, 0x02, 0x27, 0x48, 0x88, 0xdc, 0xdc, - 0xc9, 0x74, 0x5a, 0x84, 0x7e, 0x04, 0xf6, 0x28, 0x5d, 0xc1, 0xb0, 0xe9, - 0x69, 0x96, 0x84, 0x94, 0xc9, 0xec, 0x08, 0x5f, 0xe3, 0xc7, 0x3d, 0x6e, - 0xd3, 0xca, 0xd0, 0x33, 0x1f, 0x80, 0x03, 0x57, 0x4d, 0x8a, 0x13, 0x2b, - 0x55, 0x2c, 0xe3, 0x9e, 0xa9, 0x0f, 0x8d, 0xf6, 0xd5, 0x5a, 0xb4, 0xb9, - 0xc3, 0xa9, 0xc1, 0x0d, 0xea, 0x48, 0x6a, 0x92, 0x5b, 0xd5, 0x81, 0xf3, - 0x49, 0x2d, 0xd1, 0x51, 0xe0, 0x07, 0x06, 0xe2, 0x01, 0x08, 0x40, 0x17, - 0x28, 0xf3, 0xb6, 0xad, 0x24, 0xb2, 0xc3, 0x48, 0xfe, 0x7a, 0x58, 0x0a, - 0xdd, 0xd7, 0x25, 0x78, 0xe2, 0xab, 0x68, 0x11, 0xcb, 0xc5, 0x73, 0x56, - 0x3c, 0xc5, 0x49, 0x1d, 0xdf, 0x6f, 0xdb, 0x03, 0x52, 0xdd, 0x90, 0xa9, - 0x47, 0x4b, 0x5a, 0xb7, 0x61, 0x02, 0xfd, 0x1d, 0xde, 0x84, 0x95, 0x9b, - 0xd6, 0x5b, 0x4a, 0x42, 0xd1, 0x17, 0xc5, 0xae, 0x94, 0xda, 0xc6, 0xeb, - 0x9c, 0xc1, 0x74, 0x54, 0xcc, 0x2c, 0x62, 0xef, 0x12, 0xc2, 0xcf, 0x19, - 0x46, 0x9e, 0x1a, 0xcb, 0x0d, 0xe3, 0xe4, 0x46, 0x98, 0x78, 0xe1, 0x4e, - 0xb3, 0x74, 0x69, 0x34, 0xaa, 0xa8, 0xc7, 0x9e, 0x70, 0x89, 0x9e, 0xd3, - 0x9b, 0x46, 0xd5, 0x82, 0x7a, 0xb9, 0xe6, 0x30, 0xe0, 0xca, 0xd8, 0xdc, - 0x67, 0x0e, 0xce, 0x27, 0x8e, 0x45, 0x7f, 0xa2, 0xd2, 0x9a, 0x0e, 0x6a, - 0x3e, 0x37, 0xae, 0x13, 0xb6, 0xdf, 0x2c, 0xc8, 0x33, 0xf1, 0x9b, 0x4b, - 0xa1, 0x6c, 0x65, 0x33, 0x87, 0xc4, 0x81, 0x17, 0xb7, 0xe9, 0xe7, 0x0d, - 0x90, 0x61, 0x25, 0xab, 0x7d, 0xcd, 0x49, 0x29, 0x43, 0x25, 0x3b, 0x0b, - 0x83, 0x8f, 0x24, 0x35, 0x7c, 0x4d, 0xd7, 0xee, 0x94, 0x36, 0xc9, 0xae, - 0x86, 0x95, 0x4b, 0xa5, 0x9e, 0x30, 0x35, 0x6b, 0x45, 0x6b, 0x6e, 0xe7, - 0x5d, 0xd8, 0x03, 0x9b, 0x4e, 0x5b, 0xb2, 0xd3, 0x90, 0x86, 0xd5, 0xed, - 0x91, 0x40, 0xea, 0xa3, 0x9b, 0x35, 0x48, 0x92, 0xc0, 0x82, 0xda, 0xf9, - 0xf9, 0xd3, 0xc0, 0x22, 0xf5, 0x3d, 0x86, 0xb6, 0xe5, 0xc5, 0xb8, 0x68, - 0x52, 0x1a, 0x74, 0x39, 0x97, 0x9e, 0x88, 0x3e, 0xd9, 0xbc, 0xc5, 0x29, - 0x2e, 0x49, 0x4c, 0xcb, 0x42, 0x62, 0x95, 0x68, 0x53, 0x73, 0xfa, 0x97, - 0x8e, 0xe4, 0xdf, 0x49, 0x14, 0x34, 0x31, 0xba, 0x3f, 0x4e, 0xb0, 0x01, - 0xc8, 0x9c, 0x27, 0xe9, 0x65, 0x07, 0xf4, 0x56, 0x13, 0xa8, 0x0a, 0xdf, - 0x43, 0x4e, 0x0b, 0x68, 0x1a, 0x53, 0x73, 0xf0, 0x06, 0x35, 0x6f, 0xa3, - 0x7f, 0x47, 0x00, 0x5a, 0x01, 0x67, 0xdc, 0x8a, 0xef, 0x8d, 0x10, 0xf3, - 0xa4, 0xb8, 0x41, 0x73, 0xe7, 0x98, 0xd3, 0xa6, 0x15, 0x61, 0x43, 0xea, - 0xb7, 0x98, 0x12, 0xe0, 0x01, 0x0f, 0xb0, 0x8e, 0x5f, 0xe1, 0x38, 0x93, - 0x09, 0x46, 0x36, 0x0f, 0x6c, 0x98, 0x47, 0xd8, 0xfd, 0xc1, 0xf6, 0xbb, - 0x0c, 0x33, 0x4a, 0x1e, 0x32, 0x8e, 0x39, 0xbb, 0x80, 0x0f, 0x28, 0xb0, - 0x06, 0x20, 0x0f, 0xf8, 0xe2, 0x71, 0xb0, 0x75, 0xd2, 0x75, 0xd7, 0x24, - 0x0f, 0xa5, 0xc2, 0xa1, 0x51, 0xb9, 0xf2, 0xf9, 0x49, 0x29, 0x29, 0xbc, - 0x5c, 0x86, 0x61, 0x4d, 0xfb, 0x01, 0x5c, 0x00, 0x19, 0x77, 0xdf, 0x29, - 0x81, 0xa6, 0xb9, 0xf2, 0x4c, 0x5f, 0x16, 0xf9, 0x5c, 0x81, 0xdd, 0x6d, - 0xf1, 0x5c, 0xca, 0x43, 0xb2, 0x29, 0x29, 0xbe, 0x9e, 0x00, 0xd8, 0x58, - 0x20, 0x80, 0xb7, 0x06, 0x91, 0xc9, 0xd0, 0x67, 0x13, 0x6f, 0x16, 0x3a, - 0xc2, 0x6d, 0x01, 0xc8, 0xf4, 0x28, 0x6b, 0x7c, 0xaf, 0x8b, 0x75, 0xdf, - 0x17, 0x9c, 0x09, 0xb9, 0xcf, 0x95, 0x40, 0x11, 0x5d, 0xb0, 0xa8, 0xd8, - 0xec, 0x3f, 0x00, 0x06, 0x4a, 0xd9, 0x50, 0xd6, 0xfd, 0x57, 0xbc, 0xde, - 0xb9, 0xc7, 0xae, 0x06, 0x6c, 0x55, 0xcb, 0x02, 0x2c, 0x2d, 0xbe, 0x82, - 0x00, 0xec, 0x50, 0x01, 0xd3, 0xbb, 0x27, 0x9a, 0x3e, 0xf6, 0xf1, 0x3b, - 0xa1, 0xf9, 0x4a, 0xc3, 0xa2, 0xc9, 0x32, 0x14, 0x3d, 0xbc, 0xe7, 0xc6, - 0xf3, 0xfe, 0x82, 0x9d, 0xcb, 0xdc, 0x59, 0x30, 0xcd, 0xdb, 0xae, 0x1e, - 0x9e, 0x45, 0xc0, 0xf8, 0x30, 0x9a, 0xdd, 0xbf, 0xf6, 0x75, 0xf5, 0xbc, - 0x0a, 0xe3, 0x32, 0x1d, 0x26, 0xdb, 0x15, 0xc8, 0x7a, 0xac, 0x1b, 0x42, - 0x9b, 0xcc, 0xb8, 0xa7, 0x27, 0x80, 0x1e, 0xd9, 0x86, 0xc6, 0xf8, 0x7f, - 0x5f, 0x8e, 0x5f, 0xc0, 0xa1, 0x3b, 0x47, 0x57, 0x6b, 0xb2, 0xec, 0x83, - 0x8f, 0x80, 0x72, 0x36, 0xe0, 0x05, 0xe0, 0x0f, 0x2e, 0x91, 0xfc, 0x9e, - 0xeb, 0x95, 0x51, 0xfb, 0x62, 0xdc, 0xcb, 0x69, 0x90, 0xbd, 0x18, 0xad, - 0x8b, 0x8d, 0x70, 0x02, 0x69, 0xc7, 0x02, 0xdd, 0x40, 0x7b, 0x16, 0x2a, - 0xc4, 0x32, 0x1e, 0x50, 0xc0, 0xa8, 0xde, 0xa8, 0x00, 0xab, 0x6f, 0xf7, - 0xb1, 0x7d, 0x8a, 0x96, 0x8f, 0x86, 0xf3, 0xce, 0xe9, 0x65, 0x5a, 0x85, - 0xd5, 0x28, 0x96, 0xda, 0xda, 0x9b, 0x61, 0x4c, 0xee, 0x96, 0xdf, 0x9d, - 0xe8, 0xd0, 0x02, 0x87, 0x6a, 0xf7, 0x46, 0xae, 0xe8, 0xbd, 0xde, 0x70, - 0xb1, 0x9e, 0x5f, 0xa8, 0xbe, 0x2d, 0xe3, 0xdf, 0x79, 0xfe, 0xce, 0x11, - 0xc1, 0x92, 0xd7, 0xa2, 0x78, 0xa9, 0xde, 0x2d, 0xf4, 0x37, 0x89, 0x80, - 0x82, 0x02, 0xbb, 0xce, 0xc7, 0x58, 0x4c, 0xb2, 0x3d, 0x33, 0x24, 0xa1, - 0x11, 0x0a, 0x81, 0x4c, 0xbf, 0xdd, 0x84, 0x4f, 0x7e, 0xf4, 0x5b, 0xe2, - 0x2c, 0xb8, 0x66, 0x6d, 0x86, 0x60, 0xf0, 0x89, 0x1b, 0x1e, 0x83, 0xae, - 0x69, 0x0a, 0xb3, 0x85, 0x40, 0x2d, 0xbe, 0x98, 0xbe, 0xef, 0xc7, 0x2f, - 0x9f, 0x3d, 0xdd, 0xd3, 0xb8, 0xd9, 0x29, 0x86, 0x5b, 0xb4, 0x7e, 0x53, - 0x92, 0x28, 0xe6, 0xf2, 0xdf, 0x4e, 0x34, 0x01, 0xac, 0xf8, 0x9f, 0x99, - 0xfb, 0xdd, 0xd4, 0x95, 0x6e, 0xd2, 0xc9, 0xa7, 0xa0, 0xd6, 0xe7, 0x11, - 0x26, 0xfd, 0xc8, 0xc2, 0x05, 0xfb, 0x60, 0x6e, 0x65, 0x7e, 0x5b, 0xbb, - 0x20, 0x61, 0x69, 0x5b, 0x38, 0x03, 0x17, 0x71, 0xf4, 0xf7, 0xdc, 0x0f, - 0x87, 0xad, 0xce, 0x7a, 0x90, 0xd4, 0x0d, 0xc9, 0x62, 0xf8, 0xb7, 0x4f, - 0x12, 0xb9, 0xd9, 0xb2, 0x84, 0xa4, 0x58, 0x42, 0x69, 0x18, 0x05, 0x30, - 0x00, 0x00, 0x01, 0x0e, 0x43, 0xfa, 0xd0, 0x87, 0x4c, 0x11, 0xbc, 0xe4, - 0x90, 0xb2, 0xea, 0x14, 0x60, 0x5b, 0x78, 0x70, 0x02, 0x7e, 0x7a, 0x00, - 0x75, 0xd1, 0x02, 0xef, 0x35, 0x60, 0x22, 0x00, 0x26, 0x5b, 0x8f, 0xbb, - 0x80, 0x60, 0xc3, 0x14, 0xc3, 0xe1, 0x61, 0x81, 0x8d, 0xed, 0x7e, 0xa0, - 0x16, 0x00, 0x2d, 0x23, 0x5d, 0xe9, 0x2d, 0x2a, 0xae, 0x75, 0xa0, 0x66, - 0xcb, 0x2a, 0x16, 0x59, 0x29, 0xbb, 0x82, 0x78, 0xe7, 0x3d, 0xf8, 0x00, - 0xb2, 0x55, 0xab, 0x86, 0x3e, 0x1f, 0x1f, 0x4a, 0x91, 0x14, 0x69, 0x6d, - 0xf3, 0x59, 0x24, 0xd3, 0x2d, 0x21, 0x9c, 0xde, 0x45, 0x95, 0xf5, 0x27, - 0x82, 0xc6, 0xf5, 0x72, 0xed, 0x00, 0x2f, 0x79, 0x16, 0x41, 0x7c, 0xdf, - 0xdd, 0xef, 0x34, 0xcb, 0x84, 0x13, 0x09, 0xee, 0x8b, 0x92, 0xcb, 0x5d, - 0xe4, 0xa8, 0x72, 0xb7, 0xbf, 0xb5, 0xdb, 0xc4, 0x55, 0x83, 0x2e, 0xab, - 0xd6, 0x50, 0x11, 0x01, 0xed, 0xc5, 0xb6, 0x80, 0x5b, 0x65, 0xb4, 0xb4, - 0x59, 0x9b, 0x91, 0x14, 0x9b, 0x4b, 0xb4, 0xf2, 0xdb, 0xad, 0x9b, 0xb5, - 0xf2, 0x05, 0x98, 0x52, 0x4b, 0xfa, 0x18, 0x59, 0xde, 0xad, 0xb3, 0xa7, - 0x9a, 0x18, 0xa4, 0x86, 0xf4, 0x23, 0x7d, 0x0c, 0x5c, 0x2d, 0x03, 0x29, - 0x71, 0x65, 0x18, 0x43, 0x6f, 0x2c, 0x00, 0xb7, 0xe7, 0xcb, 0x24, 0xcc, - 0x71, 0x63, 0x4a, 0x1a, 0xde, 0x96, 0x48, 0xbb, 0x2e, 0x51, 0xb5, 0x21, - 0x85, 0xca, 0x49, 0x6c, 0x79, 0x2e, 0xba, 0x47, 0x5b, 0x07, 0x87, 0xd8, - 0x50, 0x61, 0x43, 0xeb, 0x68, 0xfe, 0x77, 0x87, 0x67, 0x94, 0xf0, 0xa7, - 0xd4, 0xac, 0xae, 0xdc, 0x85, 0x4f, 0x56, 0xfc, 0x08, 0x03, 0x59, 0x00, - 0x1e, 0x6f, 0xff, 0x79, 0xe2, 0x04, 0x08, 0x22, 0x67, 0x2b, 0x40, 0x4b, - 0x69, 0xbc, 0xac, 0x41, 0xd0, 0x3e, 0xb7, 0xe3, 0x8f, 0xaf, 0x0f, 0x22, - 0x66, 0x9a, 0x65, 0x83, 0x53, 0x2a, 0x12, 0x4a, 0x6f, 0xe8, 0x24, 0xc7, - 0x67, 0x7e, 0x56, 0xed, 0x43, 0xab, 0xdc, 0x1c, 0xa4, 0x30, 0xe8, 0xdf, - 0x9c, 0xc0, 0x14, 0x13, 0xc0, 0x16, 0x0a, 0xb7, 0x9e, 0xf6, 0xd1, 0xaa, - 0x23, 0x2d, 0xd3, 0x0e, 0xb4, 0x38, 0x64, 0x81, 0x2d, 0xc8, 0xe8, 0x01, - 0x66, 0xc9, 0x7c, 0x57, 0xc4, 0xf6, 0xe6, 0x52, 0x75, 0x02, 0xdb, 0xfc, - 0xdb, 0xf0, 0x23, 0x05, 0xab, 0xd0, 0x32, 0x1c, 0x69, 0xde, 0x0c, 0x04, - 0xd0, 0x0b, 0x5f, 0x35, 0x60, 0x0a, 0x83, 0xa1, 0x94, 0x2c, 0xb3, 0xa3, - 0x7b, 0x5f, 0xae, 0xe8, 0x94, 0xe3, 0x16, 0x0d, 0x2e, 0x42, 0xd2, 0x86, - 0x41, 0x8d, 0xc7, 0x71, 0x3f, 0xe3, 0xbe, 0x0d, 0xa5, 0x8c, 0x2a, 0xc9, - 0x43, 0x1b, 0x47, 0x2d, 0xe3, 0x2d, 0x94, 0x30, 0x2d, 0xb3, 0x95, 0x4f, - 0x6f, 0x73, 0xf3, 0x5f, 0xf7, 0x22, 0x0a, 0xee, 0x65, 0x3b, 0x03, 0xf9, - 0x17, 0x7a, 0xd4, 0xa3, 0x13, 0x39, 0xb1, 0x55, 0x47, 0x16, 0xdc, 0xc1, - 0x55, 0xff, 0x41, 0x1d, 0x70, 0x4f, 0x09, 0xd8, 0x28, 0x53, 0x9c, 0x48, - 0x89, 0x14, 0x32, 0x37, 0xbb, 0x11, 0x1c, 0x00, 0xe5, 0xff, 0xfe, 0x32, - 0x4a, 0x52, 0x9b, 0xc7, 0xdb, 0xda, 0x89, 0x36, 0xe0, 0xd3, 0x62, 0x55, - 0xb3, 0x46, 0xa0, 0xda, 0x31, 0xbe, 0x6e, 0x47, 0xf6, 0x76, 0xe6, 0x6e, - 0x65, 0xc3, 0x91, 0x75, 0x0d, 0x44, 0x08, 0x6d, 0x31, 0x34, 0xc2, 0xe0, - 0x04, 0x55, 0xad, 0x47, 0x90, 0x9b, 0xed, 0x09, 0x15, 0x08, 0xdc, 0xfc, - 0xd9, 0x9c, 0xf9, 0x97, 0x2c, 0xe7, 0xbc, 0x97, 0x75, 0xd1, 0xc9, 0x61, - 0x6a, 0x85, 0xd6, 0xf2, 0xd5, 0x04, 0x0b, 0xa6, 0x37, 0xa5, 0x76, 0x52, - 0x2f, 0x6e, 0x16, 0xe9, 0xe9, 0x4b, 0x40, 0xb6, 0xcc, 0x2d, 0x7e, 0xc4, - 0x61, 0x4f, 0x7d, 0xa0, 0x93, 0xff, 0x85, 0x81, 0xca, 0x16, 0xd9, 0x3a, - 0x1b, 0xb9, 0x64, 0x0a, 0xab, 0x63, 0x67, 0x90, 0xe6, 0xfc, 0xc3, 0xa5, - 0x17, 0x12, 0x10, 0xd0, 0x90, 0xde, 0x84, 0xd3, 0x79, 0x0e, 0xc0, 0xb9, - 0x46, 0x8c, 0x64, 0x00, 0x7f, 0x27, 0x5f, 0x3a, 0x57, 0x86, 0x8f, 0x6a, - 0x37, 0x2e, 0xf5, 0x29, 0x41, 0x11, 0x10, 0xe2, 0x9b, 0x59, 0x67, 0x92, - 0x56, 0xb3, 0xa2, 0x5f, 0x56, 0xfd, 0x4c, 0xda, 0x47, 0xf3, 0x87, 0x82, - 0x38, 0x01, 0xc5, 0xcb, 0x76, 0x80, 0x8a, 0xc3, 0x7c, 0x22, 0xb6, 0xaf, - 0x70, 0x42, 0x00, 0x8d, 0x7b, 0xac, 0x0a, 0x00, 0xa8, 0xce, 0xaa, 0x84, - 0xa9, 0x97, 0xd0, 0xb8, 0xd9, 0xf4, 0x10, 0xbf, 0xc4, 0x02, 0xaa, 0x58, - 0x24, 0xff, 0xde, 0x79, 0x96, 0x12, 0x92, 0xd2, 0x53, 0x77, 0x72, 0xd7, - 0x60, 0x9b, 0x3d, 0x3d, 0xb7, 0x5e, 0x9e, 0x0f, 0xb8, 0x00, 0x30, 0x56, - 0xe8, 0x80, 0x85, 0xff, 0x53, 0x40, 0xe6, 0xef, 0x80, 0x85, 0xff, 0x53, - 0x40, 0xe2, 0x43, 0x7e, 0x50, 0xa0, 0x07, 0xd7, 0x39, 0xa8, 0x13, 0xa2, - 0x6e, 0x3a, 0xf8, 0x99, 0x97, 0x03, 0x06, 0xd6, 0xeb, 0x60, 0x7e, 0xe3, - 0xad, 0xa1, 0x92, 0x81, 0x9b, 0x20, 0x5d, 0xc5, 0x02, 0x9b, 0x9e, 0x5f, - 0x1b, 0xd4, 0xce, 0x22, 0x17, 0x65, 0x00, 0x3d, 0xef, 0xe6, 0x49, 0x60, - 0x65, 0xb2, 0x2f, 0x8a, 0x63, 0x5f, 0x96, 0xd0, 0xfb, 0x43, 0x0b, 0xee, - 0xa6, 0x6a, 0x9c, 0x58, 0xd0, 0xd3, 0x9b, 0x73, 0x9b, 0xb0, 0xf0, 0x39, - 0xbc, 0xe2, 0x4c, 0xfb, 0x91, 0x84, 0x57, 0x48, 0x11, 0x6d, 0xba, 0x1b, - 0x43, 0xc3, 0xda, 0x77, 0x60, 0x89, 0xed, 0x74, 0xf0, 0x1e, 0xf5, 0xce, - 0x07, 0x00, 0x89, 0x06, 0xd3, 0xbc, 0x1b, 0xa2, 0x21, 0x3f, 0xe2, 0x7a, - 0x2b, 0xc3, 0x21, 0x72, 0x9c, 0xd5, 0xbf, 0x00, 0x2a, 0x13, 0xc6, 0xad, - 0x18, 0xaa, 0x61, 0x84, 0x34, 0x28, 0x94, 0xd0, 0xda, 0xd2, 0xdb, 0xc7, - 0xcc, 0x59, 0x72, 0x18, 0x30, 0x68, 0xca, 0x12, 0x8d, 0x5b, 0x83, 0xe6, - 0xe8, 0xc0, 0xca, 0x64, 0x08, 0x2d, 0x15, 0xb6, 0xee, 0xe3, 0xb8, 0x20, - 0xcd, 0xa1, 0x98, 0xb5, 0x03, 0x69, 0x34, 0x35, 0xb1, 0x3f, 0x26, 0xe4, - 0xa5, 0x85, 0x5b, 0x28, 0x0d, 0x58, 0x60, 0x73, 0x76, 0x6a, 0x9b, 0x69, - 0x09, 0xb9, 0x12, 0x63, 0x9d, 0x10, 0x87, 0x4e, 0xf5, 0x6d, 0x99, 0x27, - 0xb3, 0xf2, 0xa3, 0x73, 0xe2, 0xe4, 0xcd, 0x84, 0x35, 0x91, 0x91, 0xf1, - 0x83, 0x9b, 0xba, 0x47, 0xce, 0x31, 0xfe, 0x74, 0x74, 0x4b, 0xb2, 0x25, - 0x38, 0x71, 0xea, 0xdc, 0xc5, 0xb3, 0xdc, 0x0c, 0x41, 0xf4, 0x3a, 0x48, - 0x54, 0x3e, 0x9e, 0x36, 0xd6, 0xe9, 0x5a, 0x6c, 0x75, 0x50, 0x95, 0x83, - 0x7d, 0x5b, 0x6f, 0xde, 0x9b, 0x1c, 0x20, 0x56, 0x40, 0x1e, 0x3d, 0xf8, - 0xff, 0xcb, 0xa1, 0xde, 0x2a, 0xd9, 0xe4, 0x36, 0x65, 0x2f, 0xc2, 0xb7, - 0x87, 0x03, 0x8c, 0x00, 0x18, 0x37, 0x85, 0xe2, 0xbc, 0xfa, 0xe9, 0xcf, - 0xe3, 0x81, 0x98, 0x6d, 0x43, 0x31, 0x10, 0x79, 0x0d, 0xbe, 0x89, 0xf7, - 0xf9, 0x23, 0x7b, 0x91, 0xb1, 0xef, 0xe6, 0x3e, 0x17, 0x45, 0x73, 0x9b, - 0x09, 0xb2, 0x51, 0xd4, 0x61, 0x2d, 0xbc, 0x3f, 0xc7, 0x52, 0x2e, 0xee, - 0x8f, 0xba, 0x56, 0x64, 0x91, 0x0a, 0x38, 0x07, 0xb6, 0xd5, 0x6d, 0xcf, - 0x33, 0xe7, 0xdb, 0xdb, 0x65, 0x43, 0xae, 0x65, 0x0e, 0xdb, 0x6c, 0xa9, - 0x4e, 0xd3, 0x8a, 0x28, 0x63, 0x73, 0x5a, 0x4e, 0x29, 0x42, 0x56, 0x36, - 0x4d, 0xfb, 0xa0, 0x06, 0x3e, 0xd0, 0x8d, 0xf5, 0x76, 0xa7, 0x32, 0x95, - 0x09, 0xd5, 0xee, 0xdc, 0x57, 0x80, 0xac, 0x34, 0x63, 0x0f, 0xf8, 0x03, - 0x51, 0x1f, 0x3d, 0x3b, 0x9e, 0x74, 0x53, 0xec, 0x0f, 0x9c, 0x08, 0xde, - 0x03, 0xc9, 0xf6, 0x16, 0xb1, 0x54, 0xa4, 0x3c, 0x39, 0x8e, 0x7c, 0x8a, - 0x00, 0x45, 0xef, 0x1e, 0x47, 0xe2, 0xf1, 0x88, 0xee, 0x2e, 0x51, 0x77, - 0x9f, 0x2c, 0x7e, 0x97, 0xb5, 0x35, 0x24, 0xb4, 0x60, 0xc5, 0x6f, 0x25, - 0x9c, 0x5f, 0x62, 0x2f, 0xdf, 0xab, 0xe7, 0x64, 0x01, 0x26, 0x3c, 0x8d, - 0x97, 0x5e, 0xe9, 0x56, 0xd3, 0x4c, 0xe4, 0xac, 0xa8, 0x3a, 0xdc, 0x56, - 0x29, 0x65, 0x94, 0x34, 0x6c, 0x3d, 0xaa, 0x94, 0xdf, 0xb3, 0x13, 0xf0, - 0x23, 0x3e, 0xb7, 0x9e, 0x33, 0xb7, 0x6a, 0x21, 0xaf, 0x14, 0xf7, 0x6f, - 0x96, 0x18, 0xa7, 0x4b, 0x12, 0x01, 0x03, 0xaa, 0x36, 0x7f, 0xe8, 0x91, - 0x0e, 0x11, 0x5c, 0x25, 0xfc, 0xb8, 0xeb, 0xc3, 0xf8, 0xce, 0xde, 0xee, - 0x0a, 0xfc, 0xc3, 0xe5, 0x19, 0xad, 0xf1, 0x8e, 0x30, 0x02, 0xde, 0x05, - 0x23, 0x8c, 0x81, 0x9b, 0x20, 0xc2, 0xbf, 0x43, 0xfc, 0x1b, 0xe9, 0x7f, - 0x04, 0x57, 0x80, 0x3d, 0xeb, 0x81, 0x73, 0x45, 0x67, 0xea, 0x3a, 0x75, - 0xbd, 0xcd, 0xcc, 0x85, 0x50, 0x31, 0xe5, 0x4b, 0x95, 0x8e, 0xec, 0xc4, - 0x92, 0x40, 0x9b, 0x16, 0xb6, 0x74, 0x07, 0xed, 0xf4, 0x72, 0x3c, 0x50, - 0xa5, 0xdb, 0x69, 0x5f, 0x9d, 0x97, 0x23, 0xf5, 0xcb, 0x16, 0x7e, 0xcb, - 0xa8, 0x71, 0xcc, 0xa0, 0x0b, 0x7e, 0x1f, 0x2f, 0x4f, 0x8f, 0x83, 0xf2, - 0xe3, 0xdd, 0xae, 0xcd, 0x94, 0xaa, 0x36, 0x0c, 0xb0, 0x7a, 0x37, 0x50, - 0x8b, 0x9d, 0x00, 0x31, 0xea, 0x91, 0xb4, 0x5c, 0x95, 0x30, 0x3b, 0x3e, - 0x9f, 0x57, 0xbb, 0x98, 0x5a, 0x2f, 0x95, 0x87, 0xa8, 0x4a, 0x58, 0x8d, - 0xe5, 0x00, 0x1a, 0x11, 0xbd, 0xb0, 0x57, 0x5c, 0x4c, 0xeb, 0x21, 0x77, - 0xcb, 0x80, 0xc8, 0x34, 0xb4, 0x1b, 0x5b, 0x91, 0xf5, 0x65, 0x52, 0x15, - 0x29, 0x9d, 0xa5, 0xd6, 0xfe, 0xac, 0x47, 0x12, 0x08, 0x5f, 0xdc, 0xf3, - 0x7c, 0x8a, 0xa9, 0xbc, 0x75, 0xb6, 0xa5, 0x8b, 0x68, 0xd0, 0xd4, 0x6e, - 0x37, 0xb7, 0x02, 0x38, 0xe8, 0xcd, 0x74, 0x44, 0x9e, 0x5b, 0x14, 0xf8, - 0xad, 0xe8, 0xc0, 0x15, 0x09, 0xe4, 0x00, 0xac, 0x56, 0x11, 0xc8, 0x95, - 0xe7, 0x4a, 0x01, 0x63, 0x89, 0xcf, 0x7e, 0xb8, 0x11, 0x00, 0x10, 0x6c, - 0x3c, 0xcc, 0x2f, 0xd5, 0xbd, 0x00, 0x01, 0x8f, 0xb7, 0x5e, 0xe2, 0xdd, - 0xd0, 0x93, 0x76, 0xc0, 0x09, 0x97, 0x9e, 0x39, 0xf2, 0x7a, 0x96, 0xe0, - 0x20, 0x30, 0x31, 0xb9, 0xc5, 0x87, 0x49, 0x2c, 0x09, 0x09, 0x8d, 0x3c, - 0x93, 0x12, 0x84, 0xb7, 0xf2, 0x0f, 0x79, 0x3e, 0xb7, 0xe3, 0x1d, 0x64, - 0x0d, 0xd5, 0x32, 0xf8, 0x58, 0xde, 0x97, 0xb1, 0x64, 0x07, 0x5a, 0xe9, - 0x98, 0x12, 0x61, 0xb6, 0xd3, 0xdb, 0xea, 0xa0, 0x05, 0xe2, 0x63, 0xb3, - 0xbb, 0xe7, 0x12, 0x19, 0x9a, 0xec, 0xc7, 0xe8, 0x18, 0x94, 0xfb, 0xe4, - 0xe9, 0x4e, 0xba, 0x91, 0x42, 0x1b, 0xe0, 0xc2, 0x83, 0xa6, 0x6a, 0xe0, - 0xfc, 0x0e, 0xdf, 0xd5, 0x3d, 0xbb, 0x37, 0xf2, 0x5e, 0x2b, 0x1b, 0x92, - 0x6b, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x43, 0xfd, 0x0a, 0x00, 0xf4, 0x58, - 0xaf, 0xbf, 0xbf, 0x02, 0x2d, 0x72, 0xa2, 0x9b, 0x98, 0xeb, 0x6b, 0xe4, - 0xc3, 0x96, 0xc9, 0x0b, 0x46, 0xf4, 0x06, 0xf1, 0xd7, 0x0b, 0xa5, 0x14, - 0x5c, 0xcb, 0xb2, 0x19, 0x4e, 0xa7, 0x97, 0x5b, 0x9b, 0xc3, 0x80, 0x0f, - 0x9f, 0xab, 0x9a, 0xa3, 0x1d, 0xa9, 0x53, 0x2d, 0xc4, 0x52, 0xea, 0x14, - 0xa3, 0x56, 0x37, 0x20, 0x52, 0xe7, 0x31, 0xcf, 0xd3, 0x51, 0x03, 0xf7, - 0xbe, 0x13, 0x2e, 0xd0, 0xc2, 0xc7, 0x51, 0xed, 0xf2, 0x99, 0x52, 0xac, - 0xf0, 0x2d, 0xb8, 0x60, 0xfb, 0x5b, 0xf5, 0x02, 0xaa, 0x6f, 0x36, 0x65, - 0x88, 0x50, 0x74, 0x42, 0x86, 0x9c, 0x1a, 0x81, 0xad, 0xe4, 0x00, 0x1e, - 0x4e, 0xfe, 0x3e, 0xf9, 0x32, 0x45, 0x29, 0x03, 0xae, 0xf9, 0x5d, 0x96, - 0x18, 0x58, 0xf8, 0xbe, 0x0d, 0xe1, 0xc0, 0x17, 0x6f, 0x04, 0x6e, 0x78, - 0x32, 0xe5, 0x5b, 0x53, 0x74, 0x53, 0xcb, 0xc9, 0xa1, 0xf4, 0x39, 0xf2, - 0x17, 0x6c, 0x6d, 0x9f, 0x02, 0xbb, 0xcf, 0xa7, 0xd6, 0xc1, 0x7c, 0x82, - 0x30, 0x02, 0x55, 0x0f, 0x0e, 0x85, 0x00, 0x90, 0xe5, 0xb6, 0x2f, 0x83, - 0x67, 0x31, 0x66, 0x92, 0x55, 0xb9, 0xb0, 0x3a, 0x2b, 0x7f, 0x41, 0xff, - 0x40, 0x03, 0xfe, 0x85, 0xf0, 0xf3, 0x28, 0x23, 0xff, 0xef, 0x0f, 0x0f, - 0xd3, 0x62, 0x8f, 0xa1, 0xa5, 0xb0, 0x14, 0xb8, 0x2a, 0x71, 0xc8, 0x98, - 0x01, 0x2e, 0x6c, 0xd5, 0x74, 0xe3, 0x30, 0xaf, 0x5b, 0x4e, 0x0d, 0x46, - 0xe3, 0xf1, 0x7b, 0xff, 0xd2, 0x29, 0xb5, 0xd0, 0xb3, 0x37, 0xc9, 0xdb, - 0xbc, 0xee, 0x39, 0xe5, 0xee, 0x01, 0x8b, 0x61, 0x34, 0x29, 0xbd, 0x0f, - 0xdf, 0xbd, 0xd8, 0xb8, 0xea, 0x1d, 0x9f, 0x8c, 0xf3, 0xde, 0x7c, 0xa9, - 0xa7, 0x87, 0x45, 0x2c, 0xc3, 0x94, 0x63, 0x6a, 0x64, 0xd5, 0xa8, 0xda, - 0xa4, 0xdc, 0x02, 0xdb, 0xe3, 0xf5, 0xf0, 0xe0, 0x04, 0x80, 0x06, 0xaf, - 0xaf, 0x50, 0x26, 0xf1, 0xbc, 0x4a, 0xe5, 0x85, 0x93, 0x6d, 0x54, 0x50, - 0xb6, 0xfc, 0xff, 0xf5, 0xcc, 0xcb, 0x0c, 0x37, 0xc6, 0x4a, 0xdf, 0xa5, - 0x48, 0xb9, 0xc5, 0x22, 0x7c, 0xf7, 0x95, 0x16, 0xc9, 0xb3, 0x31, 0x0d, - 0xb4, 0xf3, 0xec, 0xb1, 0x56, 0x24, 0x29, 0x5b, 0xe4, 0x80, 0x0d, 0xfe, - 0x01, 0x04, 0x06, 0x7f, 0xb3, 0x39, 0x15, 0xc8, 0xc0, 0xe2, 0x0b, 0x97, - 0xcc, 0xb0, 0x20, 0x29, 0xb0, 0x32, 0x66, 0x3b, 0x25, 0x0a, 0x7b, 0x64, - 0xf9, 0xe5, 0x24, 0x4f, 0x16, 0xfc, 0x30, 0xbd, 0xc0, 0x07, 0x9f, 0xfd, - 0xe7, 0x3c, 0xd4, 0x6a, 0x49, 0x64, 0x32, 0x37, 0x91, 0x22, 0xf7, 0xc1, - 0x17, 0x34, 0x40, 0x8e, 0xea, 0x17, 0x25, 0xe7, 0x16, 0xf3, 0xd6, 0x6c, - 0x35, 0x3c, 0xae, 0x1e, 0xb0, 0xa3, 0x9b, 0xe9, 0xc0, 0x05, 0x70, 0x57, - 0x0f, 0xdf, 0x8f, 0xe4, 0x01, 0xe6, 0x87, 0x1a, 0x5d, 0x94, 0xc9, 0xbe, - 0x5b, 0x96, 0x5b, 0x2c, 0x6f, 0x94, 0x49, 0xf8, 0xf8, 0x9a, 0xa1, 0x73, - 0x9c, 0x36, 0xda, 0x1a, 0x5c, 0x25, 0x37, 0x6e, 0x5a, 0x9f, 0x9a, 0x15, - 0x56, 0x94, 0xcc, 0xfb, 0x1b, 0x0e, 0x96, 0x00, 0x5b, 0x4d, 0xc0, 0x15, - 0xaa, 0x43, 0xc3, 0x21, 0xed, 0x88, 0xae, 0x05, 0x77, 0x00, 0x06, 0x7a, - 0xaa, 0x48, 0x46, 0xfa, 0xaf, 0xbd, 0xd9, 0xfc, 0x12, 0x46, 0xd3, 0x34, - 0x30, 0x0c, 0xf9, 0xfb, 0x66, 0xc0, 0xf3, 0xa6, 0x48, 0x6c, 0x94, 0xa3, - 0xea, 0x37, 0xcd, 0x36, 0xf9, 0xbf, 0x05, 0xe5, 0x08, 0x84, 0x02, 0xb5, - 0xb4, 0x96, 0xdc, 0xc8, 0xbe, 0x87, 0x10, 0xd9, 0xc3, 0x9b, 0xfa, 0x6f, - 0xc0, 0xbf, 0x70, 0x02, 0x3f, 0x69, 0xbd, 0x08, 0xed, 0x41, 0x10, 0x01, - 0x30, 0x51, 0xaa, 0x80, 0x91, 0xff, 0x92, 0xfe, 0xe0, 0xe5, 0xaa, 0xdb, - 0x3f, 0xff, 0x34, 0x01, 0xf6, 0x91, 0x08, 0xc2, 0x62, 0x9f, 0x69, 0xbc, - 0x71, 0xbf, 0x9d, 0x26, 0xd2, 0xad, 0x85, 0x41, 0xad, 0xe4, 0x3b, 0xf8, - 0x04, 0x1f, 0xd9, 0x00, 0x12, 0x00, 0x5b, 0x68, 0x64, 0x36, 0x3c, 0xca, - 0x38, 0x3f, 0xc8, 0xe4, 0xa5, 0xf8, 0x37, 0xe8, 0x2f, 0x91, 0x3b, 0xcf, - 0xb8, 0xb8, 0x06, 0x60, 0xc7, 0x5e, 0xdd, 0xa8, 0x93, 0x53, 0x15, 0x23, - 0xee, 0x20, 0xc2, 0x1b, 0x79, 0xef, 0x90, 0x52, 0x5d, 0xa0, 0x03, 0x46, - 0xca, 0x95, 0x16, 0x7a, 0xb7, 0xf1, 0x30, 0x07, 0x74, 0x10, 0x40, 0x5c, - 0x4f, 0xf7, 0xda, 0x20, 0xf5, 0xcf, 0x7e, 0x9c, 0x1f, 0x6c, 0x2a, 0x9b, - 0x62, 0xac, 0x92, 0xa0, 0xc1, 0xed, 0xf2, 0x8e, 0x13, 0x8b, 0xb7, 0x6f, - 0x81, 0x8b, 0x3c, 0x5b, 0xf4, 0xf9, 0x10, 0x48, 0x20, 0x80, 0xe7, 0xd3, - 0x3e, 0x5d, 0x9c, 0xe9, 0x76, 0xde, 0x36, 0xbf, 0x4d, 0xab, 0x7c, 0xe9, - 0x4b, 0x9a, 0x7a, 0xa5, 0x3d, 0x5b, 0xf3, 0x5f, 0xcc, 0x20, 0x76, 0xf7, - 0x49, 0x7c, 0x26, 0x6d, 0x1f, 0x06, 0x6b, 0x75, 0x17, 0xde, 0x9b, 0xe8, - 0x3e, 0x05, 0xb6, 0xaa, 0xa7, 0xb7, 0xc4, 0xe3, 0x83, 0x76, 0x65, 0x40, - 0x08, 0xee, 0x2b, 0x7b, 0xf8, 0x08, 0x40, 0x15, 0xa2, 0xce, 0x90, 0xf0, - 0x43, 0x00, 0x68, 0x14, 0x79, 0x3e, 0x58, 0x49, 0x6f, 0x17, 0x26, 0xf9, - 0xe1, 0x6a, 0x3b, 0xf3, 0x6b, 0xac, 0xf0, 0xa0, 0x6d, 0xbd, 0xc6, 0x4b, - 0xd0, 0x81, 0x32, 0x5a, 0x11, 0x1d, 0xc6, 0x85, 0x02, 0x27, 0xfd, 0x6a, - 0xfa, 0x48, 0xde, 0xb5, 0x0f, 0x6f, 0x41, 0x49, 0xe0, 0x73, 0x74, 0x71, - 0x9c, 0xce, 0xdd, 0xf8, 0xa1, 0x7e, 0xdb, 0xef, 0xc8, 0x4d, 0x59, 0xb3, - 0x56, 0xc1, 0xc9, 0x2c, 0xad, 0x81, 0xe6, 0x68, 0xbf, 0x7f, 0x6d, 0x81, - 0x59, 0xf3, 0x5d, 0xbc, 0x51, 0xc1, 0xc6, 0x58, 0x78, 0x49, 0x4c, 0xfd, - 0x3a, 0xd1, 0x5c, 0x77, 0x65, 0x83, 0x03, 0xbf, 0x92, 0xcd, 0xb0, 0xf3, - 0xf7, 0x39, 0x59, 0x00, 0x46, 0x5a, 0xb6, 0xbd, 0xc7, 0x89, 0xeb, 0xef, - 0xca, 0xe5, 0x5a, 0x56, 0xe0, 0x87, 0x88, 0xc7, 0xe4, 0x3c, 0x02, 0x57, - 0x6e, 0xfa, 0x16, 0xda, 0xb7, 0x54, 0x6f, 0x9b, 0x43, 0xde, 0x2a, 0xf8, - 0xc3, 0x62, 0x14, 0x12, 0x91, 0xbd, 0x35, 0xda, 0x44, 0x30, 0xcd, 0xf4, - 0xd7, 0xd2, 0xbd, 0x2a, 0x92, 0xdb, 0x83, 0xdc, 0xb9, 0x5d, 0x73, 0x9a, - 0x3e, 0x58, 0xf7, 0xdd, 0x88, 0x4c, 0x38, 0xb1, 0x81, 0x55, 0xba, 0x76, - 0x00, 0x1b, 0x07, 0x27, 0x8e, 0xf9, 0xd4, 0x1a, 0x73, 0x65, 0x5b, 0xa0, - 0xf5, 0x6f, 0x90, 0x58, 0xa3, 0x0b, 0xf5, 0x83, 0x82, 0xd4, 0x84, 0xc7, - 0x7f, 0x39, 0x0b, 0xf5, 0x80, 0x7c, 0x6b, 0xea, 0x67, 0x56, 0xcb, 0x68, - 0x61, 0xb8, 0x97, 0x4a, 0x1c, 0xa3, 0xce, 0x68, 0xf7, 0x57, 0xd8, 0xf8, - 0x81, 0xa9, 0x9a, 0x51, 0x0d, 0x19, 0x1c, 0xc1, 0xe8, 0xde, 0x19, 0x08, - 0x19, 0x14, 0xb0, 0x98, 0x9b, 0xe8, 0x39, 0xb9, 0xcf, 0x2b, 0x70, 0x95, - 0x28, 0xc0, 0xa0, 0xd6, 0xed, 0x2b, 0xde, 0xf9, 0x66, 0x21, 0xe0, 0x88, - 0x00, 0x95, 0x54, 0x2a, 0x61, 0xed, 0xc0, 0x2b, 0x08, 0x13, 0x3d, 0x75, - 0x2c, 0x24, 0xc6, 0x9a, 0xca, 0x14, 0x07, 0x37, 0xf6, 0x90, 0x02, 0x5f, - 0x20, 0x02, 0xd0, 0x06, 0xd3, 0xd9, 0xdb, 0x68, 0x0f, 0x7b, 0x27, 0xf0, - 0xfc, 0xe2, 0x4a, 0xb7, 0xf7, 0x76, 0x67, 0x85, 0xb1, 0xbd, 0x4f, 0x6f, - 0xd0, 0x40, 0x03, 0x9e, 0x78, 0x9b, 0xba, 0xa3, 0x41, 0x0b, 0xfd, 0x67, - 0x3a, 0x78, 0x4e, 0x6c, 0x5b, 0x7c, 0x63, 0x7d, 0x7b, 0xeb, 0x01, 0x07, - 0xf9, 0x7f, 0xff, 0x57, 0xeb, 0xac, 0x02, 0x7c, 0xec, 0xde, 0x1f, 0x83, - 0x0e, 0x5c, 0xd9, 0x24, 0x81, 0x8d, 0xf3, 0x90, 0x02, 0x3f, 0xf0, 0x81, - 0x00, 0x0d, 0xb3, 0xe3, 0xec, 0xfe, 0x51, 0x4c, 0x7f, 0x3d, 0x75, 0x90, - 0x9f, 0xce, 0xca, 0x86, 0x9b, 0x69, 0x85, 0xaa, 0x54, 0x34, 0x73, 0x46, - 0xda, 0xba, 0x57, 0x81, 0x88, 0xde, 0x5e, 0xae, 0x2a, 0x92, 0x9b, 0xf8, - 0x90, 0x02, 0x12, 0x33, 0xc0, 0x1d, 0x80, 0x36, 0x7c, 0x17, 0x2c, 0x1b, - 0x25, 0xeb, 0x9b, 0x24, 0xfd, 0xc2, 0xb4, 0x6c, 0xc1, 0xcd, 0xc9, 0xfa, - 0xf5, 0xbf, 0x04, 0x5e, 0x05, 0xf5, 0xcc, 0x3a, 0xa6, 0xe4, 0x78, 0x75, - 0x18, 0x3e, 0x58, 0xdf, 0xba, 0x3e, 0x5f, 0x48, 0xbf, 0x7f, 0x71, 0x7d, - 0xdd, 0x1b, 0x4b, 0xe7, 0x9b, 0xa6, 0x0c, 0xfd, 0x69, 0xd2, 0x05, 0x37, - 0xe6, 0xbf, 0xee, 0x02, 0x08, 0x16, 0x0b, 0xff, 0x74, 0x81, 0x5b, 0xc0, - 0xa3, 0x2f, 0x86, 0xdb, 0x6c, 0x21, 0xd6, 0xe7, 0xa8, 0xed, 0xb0, 0x96, - 0x3d, 0xb0, 0xdf, 0xc5, 0xad, 0xfc, 0x61, 0xe0, 0x63, 0x32, 0x90, 0xed, - 0x6d, 0x7e, 0xdb, 0xa0, 0x0c, 0x1d, 0xf7, 0x16, 0xb2, 0x06, 0x4f, 0xe8, - 0x92, 0xb2, 0xd0, 0xc2, 0x07, 0x19, 0x8b, 0xeb, 0x5b, 0xec, 0x80, 0x0b, - 0x5d, 0xef, 0xcf, 0xd8, 0x01, 0xcd, 0x17, 0x2a, 0x93, 0x60, 0x87, 0x11, - 0xcc, 0xe9, 0xd6, 0xa7, 0xe2, 0xcd, 0x7f, 0x12, 0x52, 0x86, 0x8c, 0xd6, - 0xf1, 0x20, 0x05, 0xa2, 0x27, 0xb8, 0x02, 0xa1, 0x64, 0x1d, 0xd3, 0x83, - 0x93, 0xe0, 0x5e, 0xe5, 0xca, 0x34, 0x3b, 0x69, 0x25, 0x2b, 0x67, 0x3f, - 0x25, 0x4f, 0x11, 0xed, 0x16, 0x0d, 0x24, 0x37, 0xf1, 0x28, 0x08, 0x5f, - 0xef, 0x38, 0x8b, 0xe3, 0x2d, 0xa4, 0xa8, 0xdd, 0xdf, 0x28, 0x00, 0xee, - 0x8a, 0xc0, 0x4c, 0x00, 0x3a, 0xa9, 0xea, 0xdc, 0xfe, 0xf1, 0xf4, 0x5e, - 0x72, 0xe7, 0xca, 0x36, 0x57, 0x2e, 0x6c, 0xb0, 0x22, 0x95, 0x5b, 0xed, - 0x40, 0x04, 0xa2, 0xa8, 0x01, 0x79, 0x1b, 0x31, 0xcf, 0x01, 0x13, 0xec, - 0x48, 0xa3, 0x29, 0x6a, 0x32, 0xb6, 0x8e, 0xa4, 0x0d, 0x7d, 0x21, 0x58, - 0xca, 0x94, 0x5b, 0x7b, 0xf9, 0x76, 0xfb, 0xc0, 0x06, 0x25, 0x06, 0x5b, - 0x3e, 0x84, 0xe9, 0xc4, 0x18, 0x4d, 0x59, 0xab, 0x42, 0x92, 0x37, 0x80, - 0x00, 0x77, 0xf0, 0x2f, 0x3d, 0xc5, 0xf5, 0xc3, 0xf8, 0xd8, 0xb2, 0xe4, - 0x7b, 0xf2, 0x6a, 0x51, 0x95, 0x06, 0x5f, 0x16, 0xfa, 0xc7, 0xd3, 0xbd, - 0xe0, 0x8b, 0xec, 0x27, 0xe6, 0x0e, 0x0e, 0xb9, 0xde, 0x57, 0x39, 0x69, - 0x51, 0x2d, 0xa5, 0x14, 0xd8, 0xa5, 0xc0, 0x06, 0x40, 0x0f, 0x1f, 0xf1, - 0x40, 0x2c, 0xc2, 0xd3, 0x2b, 0xb8, 0x7a, 0xe7, 0x9d, 0xbe, 0x7a, 0x36, - 0x16, 0x43, 0xad, 0xe3, 0xf5, 0x7c, 0xf5, 0x66, 0xc0, 0xca, 0xb9, 0x02, - 0xdb, 0x29, 0x4e, 0x46, 0xfe, 0x72, 0xe7, 0x4d, 0x00, 0xb3, 0x2c, 0xf0, - 0xef, 0x61, 0xa0, 0x97, 0xff, 0xb6, 0x2a, 0x05, 0xb7, 0xea, 0x88, 0x21, - 0xd8, 0x2b, 0xdb, 0x9e, 0x08, 0x0a, 0x02, 0x5d, 0xe6, 0xb8, 0xf9, 0x0a, - 0xa5, 0x0c, 0x2c, 0x7b, 0x7e, 0x5a, 0x9a, 0x01, 0x5c, 0xe2, 0x60, 0x04, - 0x22, 0xf7, 0x24, 0x21, 0xa4, 0x6f, 0xd3, 0xe0, 0x0f, 0x81, 0x0b, 0xfd, - 0x33, 0x9b, 0x6b, 0xc6, 0xc4, 0x90, 0x99, 0x92, 0x87, 0x86, 0x5b, 0xb5, - 0x59, 0x65, 0x20, 0x13, 0xac, 0xb0, 0x34, 0x3c, 0xf9, 0x5a, 0xf2, 0xcd, - 0x4a, 0xad, 0xf4, 0x12, 0x7c, 0x11, 0x7b, 0xcb, 0x8e, 0xb2, 0x9a, 0xeb, - 0x21, 0xa9, 0x12, 0x87, 0xe2, 0xee, 0xcb, 0x55, 0x15, 0x46, 0xb7, 0xe6, - 0x71, 0x1e, 0xcf, 0xf8, 0x00, 0x71, 0xd7, 0xb6, 0x3d, 0x60, 0xd0, 0x42, - 0x00, 0x69, 0x69, 0x48, 0x51, 0x61, 0xf6, 0xac, 0x85, 0x1e, 0x5b, 0x7d, - 0xcf, 0xe4, 0x89, 0xc0, 0x03, 0x0e, 0xe3, 0x9f, 0xb2, 0x29, 0xab, 0xc0, - 0x01, 0xec, 0x27, 0xe6, 0xeb, 0xcf, 0x44, 0xb0, 0xb8, 0x91, 0x1b, 0xd7, - 0xfd, 0xfd, 0xde, 0x00, 0xdf, 0xe6, 0x13, 0xd7, 0xf5, 0x09, 0xde, 0x46, - 0xd3, 0x2d, 0x2f, 0x7f, 0x6a, 0x64, 0x50, 0xe3, 0x8b, 0x6e, 0x9b, 0x2f, - 0x2f, 0xc3, 0x28, 0x00, 0xd0, 0xf5, 0x6e, 0x8a, 0x54, 0x95, 0x58, 0x00, - 0x00, 0x01, 0xb7 + 0x00, 0x00, 0x01, 0xb3, 0x14, 0x00, 0xf0, 0x12, 0x07, 0x53, 0x23, 0x80, + 0x00, 0x00, 0x01, 0xb5, 0x14, 0x8a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xb5, 0x2b, 0x02, 0x02, 0x02, 0x05, 0x02, 0x07, 0x80, 0x00, 0x00, + 0x01, 0xb8, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, + 0xff, 0xf8, 0x00, 0x00, 0x01, 0xb5, 0x8f, 0xff, 0xf7, 0x5d, 0x80, 0x00, + 0x00, 0x01, 0x01, 0x43, 0xf8, 0x90, 0x03, 0xee, 0x36, 0xd4, 0x92, 0x85, + 0x86, 0x37, 0x48, 0x01, 0xb3, 0xf7, 0x9a, 0x1d, 0x5c, 0x38, 0xb1, 0x95, + 0xb9, 0x42, 0x43, 0xb2, 0xc2, 0x51, 0x24, 0x31, 0xb2, 0xed, 0x20, 0x73, + 0xd9, 0x08, 0xcc, 0x5b, 0xe2, 0x39, 0xbc, 0xdb, 0x12, 0xb7, 0x8c, 0x31, + 0xbf, 0x6c, 0x00, 0xc3, 0xeb, 0xc3, 0xd0, 0x6c, 0x3e, 0x16, 0xde, 0xa8, + 0x89, 0xf3, 0xc1, 0x17, 0xda, 0x5a, 0x4f, 0xca, 0xb0, 0x6b, 0x7c, 0x07, + 0xbb, 0x6c, 0x95, 0x8f, 0x74, 0x35, 0xaa, 0x45, 0x65, 0xb4, 0x35, 0xbf, + 0xd4, 0x22, 0xab, 0xfe, 0x80, 0x07, 0x7c, 0xed, 0x7a, 0x97, 0x2b, 0xaf, + 0x2f, 0x72, 0x64, 0x81, 0x86, 0x0f, 0x6f, 0x9a, 0x7b, 0x02, 0x10, 0x07, + 0x76, 0x2f, 0x01, 0x30, 0x01, 0x2d, 0x21, 0x37, 0x89, 0xbc, 0x74, 0x00, + 0xf4, 0xc3, 0x6b, 0xa4, 0x1f, 0x65, 0xa7, 0xb6, 0xff, 0x6d, 0x9f, 0x6f, + 0x6f, 0x77, 0xa8, 0x5b, 0xa7, 0x95, 0x90, 0x2e, 0x2b, 0x71, 0xec, 0x35, + 0xf4, 0x96, 0x92, 0x33, 0xa9, 0x92, 0x48, 0xdf, 0xcf, 0x50, 0x39, 0x13, + 0xd1, 0xbd, 0x25, 0x4f, 0xbe, 0x5b, 0x10, 0x25, 0x6e, 0x14, 0xdc, 0x5e, + 0xe0, 0x7b, 0x7a, 0x3d, 0x04, 0x2f, 0xf2, 0xb8, 0x84, 0x38, 0xdd, 0x16, + 0x94, 0xdb, 0x46, 0xfd, 0xdf, 0x3a, 0x00, 0x7a, 0xf9, 0x49, 0x45, 0xb7, + 0x52, 0xe9, 0x03, 0x9a, 0x4a, 0x40, 0xf8, 0x14, 0xdc, 0xa7, 0x4d, 0xf7, + 0xbc, 0x25, 0x04, 0xa0, 0x04, 0x2a, 0x81, 0x6d, 0xda, 0x36, 0x67, 0x1b, + 0xb8, 0x48, 0x96, 0xb7, 0x49, 0xea, 0xd9, 0x1c, 0x8d, 0xf8, 0xfb, 0x80, + 0x07, 0x50, 0x9c, 0x13, 0x43, 0xae, 0x94, 0x07, 0x36, 0xff, 0x8b, 0x00, + 0x1c, 0x8a, 0x35, 0x00, 0x20, 0x49, 0x40, 0xdb, 0x74, 0x05, 0x82, 0x10, + 0x03, 0xcd, 0x28, 0x29, 0x06, 0x56, 0xf1, 0x2f, 0xc0, 0x03, 0xd1, 0x22, + 0x26, 0xd0, 0x08, 0x0a, 0x03, 0x4d, 0x27, 0x37, 0x5d, 0x2f, 0x36, 0xb7, + 0xe9, 0xef, 0x7a, 0x00, 0xd0, 0x83, 0xe5, 0x14, 0x65, 0x8a, 0x62, 0xd9, + 0xe2, 0x31, 0xb8, 0x3e, 0xef, 0x15, 0xbd, 0xdc, 0xb8, 0xf4, 0xa3, 0x4a, + 0xb9, 0x36, 0x1c, 0xde, 0xe7, 0x41, 0x08, 0x01, 0xb8, 0x79, 0xe0, 0x11, + 0x4a, 0xbe, 0x07, 0xca, 0xdf, 0x2d, 0xea, 0x5d, 0x11, 0x99, 0xb0, 0x2c, + 0x3a, 0x6e, 0x41, 0xaa, 0x5b, 0x23, 0xf2, 0xb5, 0x5a, 0x41, 0xcd, 0xd8, + 0x42, 0xad, 0xf7, 0x78, 0xc8, 0x2d, 0xdc, 0x51, 0x70, 0x72, 0xcc, 0xd8, + 0xb4, 0x75, 0x85, 0x43, 0x94, 0x25, 0xbd, 0x5e, 0xf9, 0x3c, 0x49, 0xbc, + 0xe5, 0xa3, 0x2b, 0xb8, 0x49, 0x0a, 0x26, 0xd2, 0xa7, 0xea, 0x8d, 0xfd, + 0xb1, 0xf7, 0xdd, 0x22, 0x8b, 0xef, 0xce, 0x5a, 0x51, 0x66, 0x64, 0x33, + 0x8a, 0x85, 0x53, 0xc0, 0x7b, 0x51, 0x22, 0x34, 0xe8, 0xd7, 0xd0, 0x09, + 0x8f, 0x5a, 0x53, 0xb8, 0x54, 0x1b, 0x4b, 0x2c, 0xbb, 0xaa, 0x18, 0xd5, + 0x69, 0x6d, 0xd2, 0xfa, 0xba, 0x5b, 0x7c, 0x67, 0xc9, 0x37, 0x51, 0x02, + 0x37, 0x8a, 0x6a, 0xec, 0x2b, 0x03, 0x94, 0xe4, 0x1e, 0xad, 0xce, 0x96, + 0x95, 0x84, 0x34, 0x5a, 0x38, 0x63, 0x58, 0x90, 0x44, 0x0e, 0xa1, 0x35, + 0xf4, 0xa0, 0xf3, 0xe1, 0x55, 0x0a, 0x46, 0x12, 0x5b, 0x93, 0x2c, 0x0c, + 0x95, 0x51, 0x62, 0x94, 0x34, 0x34, 0x2d, 0xaa, 0x36, 0x8d, 0xf3, 0xbb, + 0x0e, 0xe3, 0x37, 0x54, 0x02, 0x32, 0x83, 0x29, 0xd0, 0xea, 0xce, 0x7e, + 0x95, 0x3c, 0x26, 0x9a, 0xd0, 0xcb, 0x9c, 0xba, 0xa8, 0x49, 0x8e, 0x2d, + 0x68, 0x4d, 0x65, 0xa9, 0xaa, 0x05, 0xb2, 0x8c, 0x37, 0xe9, 0x5e, 0xfc, + 0x00, 0x7a, 0xe7, 0x4e, 0x1e, 0xa3, 0xe5, 0x9b, 0xb9, 0x42, 0x52, 0xc3, + 0xe3, 0x3f, 0x3f, 0x39, 0x86, 0x59, 0xb8, 0x80, 0x2a, 0xa9, 0x65, 0x3d, + 0xa9, 0xd4, 0xfb, 0xf4, 0xf9, 0x65, 0x1e, 0xa9, 0x62, 0x6c, 0x18, 0x30, + 0xf8, 0xdb, 0x5f, 0xb7, 0x8e, 0xde, 0xe7, 0x1b, 0xe2, 0x84, 0xc0, 0x86, + 0xe3, 0x71, 0x37, 0x0a, 0x0b, 0x29, 0xbc, 0xe4, 0x33, 0x31, 0xbd, 0x1c, + 0xf3, 0x40, 0x1e, 0xee, 0x3b, 0x4c, 0x5f, 0xd0, 0x21, 0x00, 0x36, 0x96, + 0x3c, 0x7b, 0x76, 0xbd, 0xe9, 0xb5, 0xfd, 0x74, 0x81, 0xb6, 0xba, 0xdc, + 0x25, 0x14, 0xde, 0x6f, 0xda, 0x80, 0x1f, 0xa4, 0xf3, 0x08, 0x0b, 0x38, + 0x68, 0x6b, 0x75, 0x48, 0xdc, 0x52, 0x27, 0x1e, 0xf6, 0xa8, 0x0a, 0xaf, + 0x91, 0xb9, 0x68, 0x48, 0x67, 0x8b, 0x70, 0xf7, 0xc7, 0x96, 0x3a, 0x5f, + 0x59, 0x22, 0x59, 0xe2, 0xdc, 0xd7, 0x0c, 0xb9, 0x40, 0x07, 0xad, 0xf0, + 0x7e, 0x82, 0x74, 0x8c, 0x01, 0x6a, 0xe9, 0x63, 0x75, 0xcf, 0x59, 0x43, + 0xa1, 0x92, 0x04, 0x37, 0x86, 0xe2, 0xa5, 0x74, 0x50, 0x90, 0x1c, 0x43, + 0x3c, 0x6d, 0xf0, 0x18, 0xdb, 0xf6, 0xce, 0x24, 0x28, 0x29, 0xb9, 0xb4, + 0xac, 0xc0, 0x29, 0xbd, 0x2d, 0xab, 0xb6, 0xa3, 0x6a, 0xdf, 0xa6, 0x8e, + 0x73, 0xc5, 0xbb, 0x99, 0x90, 0x04, 0x66, 0x17, 0xea, 0xa7, 0xb7, 0xa5, + 0xe4, 0xa7, 0x6e, 0x69, 0x41, 0xbf, 0x9a, 0x60, 0xf3, 0xe0, 0xc6, 0x41, + 0x74, 0x02, 0xbe, 0x38, 0x7e, 0x50, 0x4a, 0xff, 0xd9, 0x2d, 0x0d, 0x29, + 0x7c, 0x1b, 0xaa, 0x27, 0x5c, 0x00, 0xdb, 0xfa, 0x20, 0x5b, 0xe2, 0x52, + 0xe5, 0x8f, 0x11, 0xa6, 0xd8, 0x58, 0x6a, 0x52, 0x15, 0x6d, 0x0b, 0xb5, + 0x40, 0xb6, 0x4d, 0xf0, 0x35, 0xb3, 0x76, 0xfa, 0xfe, 0x4b, 0xd0, 0x08, + 0x31, 0xb4, 0x40, 0x1a, 0xab, 0x62, 0x80, 0x84, 0x01, 0x35, 0xe0, 0x9b, + 0xff, 0xb2, 0x12, 0x19, 0x53, 0x94, 0x96, 0xd2, 0xdd, 0xbb, 0x0a, 0x66, + 0xd0, 0x1a, 0x36, 0x21, 0x40, 0x85, 0xff, 0x1b, 0x8f, 0x9e, 0xa6, 0x2a, + 0xb7, 0x75, 0xe3, 0x09, 0x0d, 0xb4, 0x18, 0xd4, 0xdd, 0xaf, 0x0e, 0x70, + 0xba, 0x4a, 0x56, 0xe5, 0x11, 0x4f, 0x95, 0x28, 0x0a, 0xa8, 0xc6, 0xf4, + 0x77, 0xf3, 0x79, 0x52, 0x4b, 0x4a, 0x5a, 0xb7, 0x3e, 0x7e, 0x6d, 0x24, + 0x23, 0x44, 0x2d, 0x5b, 0xc2, 0x2d, 0x76, 0x6d, 0xa4, 0x3a, 0xdd, 0x61, + 0x30, 0x00, 0xfe, 0x61, 0x26, 0x46, 0xfa, 0x10, 0x03, 0xf2, 0x2e, 0x00, + 0x16, 0xfd, 0xb1, 0xfe, 0xdb, 0x32, 0x95, 0xa5, 0x08, 0xaf, 0x9c, 0xc1, + 0xc5, 0x28, 0x6b, 0x7a, 0x80, 0x02, 0xd1, 0x16, 0xfb, 0xbc, 0x56, 0xe0, + 0x5e, 0x8f, 0x75, 0x0d, 0x81, 0xac, 0x13, 0x21, 0xa4, 0x8a, 0x48, 0x63, + 0x62, 0x42, 0xe3, 0x7e, 0xc1, 0xe0, 0x0f, 0xf9, 0x00, 0x72, 0x28, 0x4d, + 0x14, 0xfb, 0x92, 0x1d, 0x8e, 0xb6, 0xa6, 0x58, 0x5d, 0xf4, 0xac, 0x7e, + 0x40, 0x15, 0x80, 0x19, 0x7b, 0x3d, 0xf3, 0x65, 0xc2, 0xa7, 0x2e, 0xc3, + 0xee, 0xc5, 0x28, 0xe6, 0x4f, 0xf8, 0xbf, 0x6f, 0x97, 0x0b, 0xe3, 0xae, + 0xf5, 0x4a, 0x2f, 0x69, 0x61, 0x63, 0x5b, 0xb6, 0x46, 0x00, 0x63, 0x74, + 0x4a, 0xdc, 0xd7, 0xe5, 0x4c, 0x42, 0xdb, 0x1d, 0xe3, 0x7b, 0xa4, 0xd7, + 0x8d, 0x28, 0x32, 0x35, 0x99, 0x75, 0x4b, 0x78, 0x64, 0x0c, 0x8d, 0xfc, + 0xa0, 0x00, 0x9c, 0x59, 0x10, 0x89, 0x79, 0x77, 0xc8, 0xa7, 0x95, 0x0d, + 0xc7, 0x96, 0x51, 0x87, 0xc5, 0xad, 0x84, 0x01, 0x1b, 0xaf, 0xdc, 0x40, + 0xa1, 0x79, 0xce, 0x52, 0xe5, 0x93, 0x1e, 0x56, 0x55, 0x01, 0xec, 0xf5, + 0x6f, 0xd0, 0xa4, 0x6f, 0xe8, 0x01, 0xef, 0xc4, 0xde, 0x49, 0xef, 0x5b, + 0x36, 0x6c, 0x3a, 0xa5, 0x2e, 0x56, 0xee, 0xdd, 0x98, 0x62, 0x5a, 0x15, + 0xb4, 0xb4, 0x6e, 0xfd, 0x44, 0x21, 0x96, 0x31, 0xba, 0x1f, 0x62, 0x20, + 0x0f, 0x98, 0x00, 0x00, 0x01, 0x02, 0x43, 0xf8, 0x37, 0x13, 0x05, 0xdd, + 0xbe, 0xa9, 0x4b, 0x6c, 0xa2, 0xbc, 0xc5, 0x6e, 0x6c, 0x21, 0x12, 0x23, + 0x77, 0x3e, 0x68, 0x05, 0xa2, 0xdf, 0x8e, 0xcf, 0x02, 0xe1, 0x60, 0x73, + 0x79, 0x09, 0x08, 0x0e, 0x74, 0x25, 0x49, 0x1b, 0xcc, 0x42, 0xca, 0x21, + 0xb7, 0x90, 0xdf, 0x40, 0x10, 0xff, 0xe7, 0x1d, 0x2e, 0x92, 0x59, 0x94, + 0x80, 0x94, 0xbf, 0x16, 0xe7, 0xdc, 0x34, 0xb6, 0xd7, 0xb0, 0xd9, 0x2d, + 0x50, 0x81, 0xc5, 0x35, 0x0f, 0x6a, 0x6f, 0xd4, 0xea, 0xfd, 0x5e, 0xa0, + 0x03, 0x0a, 0xad, 0xc9, 0xee, 0x5f, 0x8e, 0x78, 0xb2, 0xc0, 0xc0, 0xe2, + 0xbd, 0x4a, 0x46, 0xd5, 0xed, 0x27, 0x2e, 0xe1, 0xea, 0x13, 0x76, 0xd1, + 0xc1, 0x65, 0x90, 0x99, 0xb6, 0x00, 0x1a, 0x24, 0x9e, 0x12, 0x87, 0xc8, + 0x14, 0x96, 0x10, 0xda, 0x60, 0x74, 0xd0, 0x2d, 0x85, 0x30, 0xaa, 0xdf, + 0x15, 0xff, 0x9c, 0x02, 0xaa, 0x36, 0xdb, 0x2d, 0xdb, 0x9b, 0xa0, 0x10, + 0xc4, 0x94, 0x87, 0x1b, 0x3e, 0x02, 0x17, 0xfc, 0x6b, 0x88, 0x70, 0xf4, + 0x21, 0x37, 0x7c, 0x5c, 0x9c, 0xba, 0xda, 0xac, 0x13, 0x59, 0x1f, 0x1b, + 0xca, 0x2b, 0x30, 0x5e, 0xe3, 0xa2, 0x78, 0xd0, 0xe2, 0x43, 0x7b, 0x87, + 0x53, 0x70, 0xbc, 0xa1, 0xb0, 0xf8, 0x12, 0xde, 0x44, 0x01, 0xf8, 0xaa, + 0x94, 0xf9, 0x43, 0x71, 0x51, 0xb4, 0x3f, 0x20, 0x9e, 0x6c, 0x49, 0x03, + 0x75, 0x76, 0x86, 0x42, 0x96, 0x95, 0x2b, 0x5a, 0x07, 0xb6, 0xfc, 0x97, + 0x8d, 0xfa, 0x7f, 0xa3, 0xcd, 0x91, 0xe6, 0x78, 0xc2, 0xc2, 0x5b, 0x77, + 0x7b, 0x48, 0xf6, 0x3d, 0x03, 0x21, 0xbd, 0x62, 0x58, 0x16, 0xb1, 0xbc, + 0xdc, 0xe7, 0xce, 0x77, 0x2b, 0xf4, 0x05, 0x7d, 0x29, 0x30, 0x69, 0xf2, + 0x37, 0x55, 0xd8, 0x00, 0x73, 0x3b, 0x89, 0x02, 0xad, 0x2c, 0x84, 0x3d, + 0xb0, 0x43, 0x25, 0x6c, 0x2c, 0x4a, 0xab, 0xe8, 0xde, 0x7d, 0xe3, 0x40, + 0x1d, 0x3f, 0xb7, 0x89, 0x90, 0x35, 0x1d, 0x76, 0xa8, 0xd2, 0x6c, 0x2d, + 0x28, 0x5b, 0x78, 0xb7, 0xf3, 0x7e, 0x57, 0xcc, 0x22, 0x49, 0xdd, 0x2a, + 0xa0, 0xd2, 0x83, 0x29, 0x6d, 0xf6, 0x3d, 0xbe, 0x73, 0x1c, 0x80, 0x10, + 0x45, 0x25, 0xa9, 0x5e, 0xad, 0xe0, 0xc5, 0xf2, 0x00, 0x70, 0x27, 0x84, + 0xd8, 0xa7, 0xee, 0xee, 0x59, 0x9b, 0x83, 0x40, 0x79, 0x22, 0xb5, 0x38, + 0x0c, 0xc5, 0x6e, 0x8c, 0xa0, 0x16, 0x87, 0x90, 0xa3, 0x6f, 0xed, 0x2f, + 0x0f, 0xf3, 0x59, 0x20, 0x13, 0x0f, 0x2d, 0x4e, 0x0a, 0x30, 0x39, 0x84, + 0xd3, 0x69, 0x8b, 0x92, 0x04, 0x17, 0x8e, 0x81, 0x1b, 0x15, 0x6e, 0x8e, + 0x29, 0xb8, 0x9c, 0x39, 0x53, 0x12, 0x5a, 0x51, 0x65, 0x42, 0xa4, 0x2b, + 0xd2, 0x9c, 0xdb, 0x38, 0x9e, 0x7a, 0x8b, 0x42, 0x4b, 0x2c, 0x30, 0xe4, + 0x6e, 0x88, 0x53, 0x7a, 0x27, 0xc6, 0xf0, 0xe8, 0x21, 0x00, 0x45, 0x28, + 0x92, 0xb5, 0x46, 0x1e, 0x7b, 0x64, 0x32, 0x6c, 0x9e, 0x31, 0x15, 0x15, + 0xb7, 0xe1, 0x68, 0x52, 0x80, 0x8a, 0xd1, 0xcd, 0xa2, 0x6d, 0xe6, 0x3f, + 0x65, 0xaa, 0x33, 0x0a, 0xc9, 0x12, 0x05, 0xa8, 0xd0, 0x86, 0x6c, 0x37, + 0xc6, 0xd8, 0x85, 0x94, 0x07, 0x36, 0x7e, 0xad, 0xeb, 0x92, 0x45, 0x2d, + 0xb6, 0x69, 0x99, 0xb8, 0x50, 0x16, 0xdc, 0x30, 0x43, 0x00, 0x77, 0x3a, + 0x80, 0x0c, 0x59, 0x1c, 0xd9, 0xcf, 0xc6, 0xd6, 0xf4, 0x11, 0xb0, 0x00, + 0xf4, 0x5e, 0x15, 0xe2, 0x91, 0x07, 0xb7, 0xad, 0xc9, 0x99, 0xed, 0x53, + 0x03, 0x22, 0xea, 0xcb, 0x40, 0x44, 0x3c, 0x73, 0x78, 0x31, 0x91, 0xbd, + 0x75, 0x04, 0x2f, 0xf7, 0xde, 0xc9, 0x20, 0x73, 0x61, 0x69, 0xcd, 0x82, + 0x90, 0x7c, 0x90, 0x86, 0xdd, 0x32, 0x25, 0x75, 0xd9, 0x03, 0x10, 0xec, + 0xb7, 0xc0, 0x73, 0x74, 0x76, 0x65, 0xce, 0x6c, 0xd0, 0x83, 0x65, 0x90, + 0x34, 0x7b, 0x70, 0xdc, 0x1d, 0xe6, 0x70, 0x46, 0x4c, 0xe0, 0xaf, 0x1a, + 0xdd, 0xcd, 0x04, 0x20, 0x08, 0xda, 0x62, 0x04, 0xaa, 0xcf, 0x45, 0x52, + 0x4b, 0x68, 0x37, 0x21, 0x21, 0xb6, 0xda, 0x01, 0x52, 0xe1, 0x0a, 0x96, + 0xdf, 0x21, 0x7c, 0x8f, 0xf5, 0x8d, 0x6f, 0x60, 0x85, 0xfe, 0x0e, 0x11, + 0x08, 0x66, 0xd2, 0x11, 0x4b, 0x58, 0x6c, 0xa9, 0x55, 0xbd, 0x08, 0xb9, + 0x48, 0xbd, 0xd3, 0x82, 0x90, 0xc8, 0x07, 0xb6, 0x81, 0xad, 0xe7, 0x37, + 0xd0, 0xa5, 0x18, 0x07, 0x36, 0x5e, 0x4a, 0x76, 0x72, 0x42, 0xbe, 0x44, + 0xb6, 0xd6, 0x8a, 0x8c, 0xbc, 0xda, 0xf7, 0x3a, 0xe6, 0x50, 0xbc, 0xa9, + 0xe8, 0x74, 0xa4, 0xb6, 0x89, 0xf8, 0xad, 0x03, 0x5b, 0xa3, 0x98, 0x96, + 0x69, 0x25, 0x5a, 0xc2, 0x3a, 0x8a, 0xc3, 0x70, 0xa1, 0xf1, 0x1e, 0x9b, + 0x21, 0xc1, 0x95, 0xae, 0xae, 0x27, 0x79, 0x4b, 0x09, 0x11, 0xba, 0xe4, + 0x6c, 0x00, 0xb3, 0xaf, 0x32, 0x6d, 0x1c, 0x41, 0xf3, 0x96, 0x58, 0x01, + 0xfb, 0x73, 0x3a, 0xc4, 0x90, 0x96, 0x48, 0x60, 0xf9, 0x63, 0x7e, 0x28, + 0x8b, 0x28, 0x9e, 0xa6, 0x1b, 0x03, 0x15, 0x64, 0x41, 0xad, 0xec, 0xbe, + 0x5d, 0xaf, 0x15, 0x9a, 0xfc, 0x81, 0xb7, 0x0e, 0xa9, 0xea, 0xd9, 0xba, + 0xcb, 0x61, 0xa5, 0xd0, 0xc5, 0x1c, 0xde, 0x87, 0xcf, 0x8f, 0xed, 0x11, + 0x98, 0x2f, 0x29, 0x69, 0x70, 0x02, 0xb7, 0xe4, 0x85, 0xcf, 0x05, 0xa3, + 0x1a, 0xf2, 0x17, 0x11, 0x93, 0x7d, 0xb0, 0x06, 0x7b, 0x99, 0xa4, 0x7e, + 0xa9, 0x03, 0x99, 0x2a, 0x79, 0xc7, 0x3f, 0x52, 0xde, 0x29, 0x94, 0xa5, + 0x8a, 0x4b, 0x8d, 0xe3, 0xdf, 0xf9, 0x6f, 0xba, 0x80, 0x3d, 0x15, 0xfe, + 0x00, 0x7d, 0x9e, 0xfc, 0x7b, 0x91, 0x93, 0x62, 0xe9, 0x3f, 0x9c, 0xcf, + 0x27, 0x07, 0xdb, 0x46, 0x16, 0x5a, 0xc6, 0xe2, 0x8b, 0xfb, 0xe8, 0x02, + 0x37, 0x88, 0x77, 0xc4, 0x1c, 0x95, 0x64, 0xaf, 0xde, 0x6c, 0xf2, 0x85, + 0x41, 0xc5, 0xb2, 0xb6, 0x57, 0xcb, 0x28, 0xf4, 0x89, 0x19, 0xd1, 0x96, + 0x50, 0xa6, 0xfc, 0xf7, 0xfc, 0x53, 0xfd, 0xc8, 0xf9, 0x9c, 0x3e, 0x06, + 0x27, 0x39, 0x78, 0xd4, 0x01, 0x5c, 0xa8, 0xa7, 0x0e, 0x6f, 0xd4, 0x42, + 0x01, 0x0b, 0xfc, 0xfe, 0x04, 0xb8, 0x84, 0xf9, 0x6c, 0xf0, 0x2c, 0xa6, + 0xc9, 0xfd, 0xdb, 0xfe, 0xfa, 0x72, 0xb6, 0x84, 0x38, 0xd4, 0x7f, 0xa8, + 0xea, 0xda, 0x44, 0xe0, 0x01, 0x9f, 0xb8, 0xbd, 0x72, 0x86, 0x99, 0x52, + 0x42, 0x14, 0x6e, 0xbd, 0x86, 0xee, 0x12, 0xe4, 0x6e, 0xbd, 0x86, 0xee, + 0x12, 0xe4, 0x6e, 0x90, 0x07, 0xbe, 0xfd, 0xf3, 0xcc, 0x86, 0x3e, 0xd4, + 0x92, 0x01, 0x87, 0x64, 0x5f, 0x16, 0xe9, 0x09, 0xef, 0x9d, 0x7d, 0xb6, + 0xbf, 0x68, 0xd5, 0x6d, 0x6d, 0xe0, 0x80, 0x14, 0x68, 0x20, 0x80, 0xaf, + 0xde, 0x73, 0xce, 0x50, 0xc9, 0xc4, 0x3b, 0x68, 0xcf, 0x46, 0xdd, 0x4b, + 0x3d, 0xb5, 0x54, 0xdb, 0x1b, 0xe7, 0x00, 0x3d, 0xfa, 0x40, 0x07, 0x8f, + 0xc7, 0x11, 0xf1, 0x5e, 0x55, 0x5a, 0xe7, 0x47, 0x47, 0xe4, 0x9e, 0x6a, + 0x88, 0x10, 0xdf, 0x17, 0x11, 0xf1, 0x84, 0x6b, 0xd0, 0x05, 0x84, 0xe9, + 0x3f, 0x44, 0xe9, 0x62, 0x5c, 0x1a, 0xdf, 0x4e, 0x00, 0x78, 0x00, 0xbb, + 0xb1, 0x3d, 0x63, 0x9f, 0xc6, 0x3e, 0x9a, 0xb2, 0xed, 0x19, 0xb1, 0xb1, + 0x00, 0x39, 0x00, 0x71, 0xf2, 0x00, 0xe0, 0x01, 0x97, 0x4e, 0xce, 0xf9, + 0xcd, 0xc8, 0x31, 0xf6, 0xea, 0x24, 0x31, 0xa0, 0xe8, 0xdc, 0xd4, 0xac, + 0x2e, 0xc6, 0x00, 0x00, 0x01, 0x03, 0x43, 0xf9, 0x6d, 0x84, 0xef, 0x3a, + 0x09, 0x80, 0x07, 0x34, 0x90, 0xde, 0x07, 0x7f, 0x39, 0x63, 0x7b, 0xb7, + 0x1b, 0xc6, 0xf3, 0x32, 0xc0, 0x8d, 0xe0, 0xbb, 0x14, 0x2a, 0x56, 0xf2, + 0x02, 0xdc, 0x4f, 0xe5, 0xf3, 0x3c, 0x7c, 0xdc, 0x5a, 0x1c, 0x7a, 0x37, + 0x04, 0xa6, 0x48, 0xad, 0xe3, 0xa1, 0x6d, 0xd7, 0x6d, 0x55, 0x38, 0x32, + 0x35, 0x87, 0xed, 0x02, 0x9b, 0x47, 0x21, 0xeb, 0x93, 0xd6, 0x56, 0xae, + 0x97, 0x24, 0x9b, 0xe2, 0x35, 0xb3, 0x83, 0x99, 0x46, 0xdd, 0xf0, 0x00, + 0xec, 0x80, 0x58, 0x51, 0xb0, 0x0a, 0x56, 0x5f, 0x6b, 0x05, 0x70, 0x2b, + 0x22, 0x00, 0x8f, 0x82, 0xc9, 0x76, 0xd2, 0x5b, 0x50, 0xe8, 0x64, 0x8b, + 0x42, 0x5b, 0x15, 0x0e, 0xad, 0x9c, 0x39, 0xae, 0x0d, 0x6d, 0xf1, 0x73, + 0x12, 0xdf, 0x4b, 0x0e, 0x09, 0x6f, 0x46, 0xec, 0x00, 0x3d, 0x8f, 0xe0, + 0xa0, 0xb5, 0x59, 0xe0, 0xde, 0x6e, 0xfe, 0x4d, 0x00, 0x18, 0x37, 0xd0, + 0x7b, 0x04, 0x2f, 0xf0, 0x7f, 0xb9, 0x94, 0x00, 0x68, 0x9e, 0xa9, 0x1b, + 0x40, 0x1c, 0xc0, 0x3d, 0x90, 0xd6, 0xec, 0x10, 0x9c, 0xe9, 0x44, 0x35, + 0x6e, 0x57, 0xb3, 0xed, 0xe7, 0x5d, 0xb1, 0xc0, 0x3d, 0x0e, 0xbd, 0x59, + 0xe8, 0x85, 0xaf, 0x83, 0x72, 0xb7, 0x1d, 0x9d, 0xbb, 0xcb, 0x8a, 0x1a, + 0x6c, 0x3f, 0x10, 0xf1, 0x8a, 0xb5, 0xae, 0x15, 0x8f, 0x17, 0xcf, 0x2f, + 0x2c, 0x31, 0x66, 0x15, 0x1b, 0x48, 0x54, 0x29, 0xb7, 0x71, 0x75, 0xbe, + 0xbb, 0x9f, 0xbd, 0x8a, 0x99, 0x29, 0xc3, 0x9f, 0x90, 0xaa, 0x36, 0x9d, + 0x47, 0xb7, 0xb2, 0xe7, 0x1d, 0xf3, 0x1d, 0x90, 0xf3, 0xcd, 0xe6, 0x5b, + 0x43, 0x46, 0x0d, 0x6f, 0x9a, 0x13, 0x76, 0x90, 0xed, 0xa1, 0xf6, 0xb7, + 0xbe, 0x70, 0x21, 0x7f, 0xbb, 0xb9, 0x88, 0x01, 0x0b, 0x73, 0x6a, 0x24, + 0x5a, 0xd3, 0x96, 0xe4, 0x02, 0x9b, 0xf4, 0xda, 0xe9, 0xb6, 0x94, 0x12, + 0x73, 0x57, 0xef, 0xaf, 0x77, 0x16, 0xf1, 0x14, 0x70, 0x6b, 0x71, 0x30, + 0x53, 0x88, 0x97, 0xb7, 0x76, 0x60, 0x23, 0xff, 0xea, 0xbe, 0x18, 0xea, + 0x12, 0x10, 0xda, 0x7d, 0xb8, 0xc7, 0xce, 0x73, 0xb4, 0x87, 0x16, 0x1d, + 0xb2, 0xaa, 0x90, 0xda, 0x5e, 0xe5, 0xd1, 0xad, 0x8e, 0x8e, 0xb7, 0xd5, + 0xbe, 0x60, 0x03, 0x39, 0x82, 0x34, 0xce, 0xe4, 0x83, 0x9f, 0x46, 0x0f, + 0x6f, 0x35, 0x7f, 0x2f, 0x97, 0x21, 0x45, 0x5f, 0x35, 0x81, 0xd6, 0x40, + 0xea, 0x58, 0x69, 0x0d, 0xbd, 0xe0, 0x03, 0xae, 0x60, 0xb8, 0x6f, 0x0f, + 0xd0, 0xdf, 0x2a, 0x5e, 0x6a, 0x87, 0x1a, 0x65, 0x3c, 0xe6, 0xe6, 0xff, + 0xf2, 0x00, 0x38, 0xf6, 0xc1, 0x5d, 0x85, 0xd8, 0xfb, 0xa8, 0xe2, 0xd6, + 0x07, 0x84, 0x1e, 0x18, 0xdb, 0xe4, 0x34, 0xbc, 0x6e, 0xb7, 0x42, 0x7e, + 0xcb, 0x9e, 0x0d, 0xf8, 0xc9, 0x22, 0x65, 0x94, 0x2e, 0xd4, 0x58, 0xa7, + 0x0d, 0x6b, 0xcd, 0x84, 0x67, 0xc7, 0xd9, 0x42, 0x0b, 0x2b, 0xd4, 0x63, + 0x67, 0x72, 0x48, 0x89, 0x28, 0xd4, 0x76, 0xbe, 0x2d, 0x94, 0xaa, 0x7a, + 0x8c, 0x6c, 0xb5, 0x05, 0x5c, 0x84, 0xa2, 0x90, 0x29, 0xb7, 0x6f, 0x4e, + 0x0d, 0x6c, 0x4a, 0x6c, 0xc0, 0x29, 0xb9, 0x20, 0x13, 0x69, 0x22, 0x48, + 0xdd, 0x42, 0x6e, 0xd8, 0x57, 0x8b, 0x74, 0x7f, 0xe6, 0x09, 0x23, 0x4e, + 0x1c, 0xfb, 0x03, 0x3b, 0xf3, 0xb1, 0xc8, 0x4d, 0x1a, 0xd9, 0x4b, 0xe5, + 0xb6, 0x46, 0xe1, 0x80, 0x84, 0x00, 0xc0, 0x7b, 0x7e, 0x78, 0x5e, 0x51, + 0x7c, 0x45, 0x8d, 0xec, 0x3d, 0xf0, 0xcd, 0x7d, 0x28, 0x02, 0x35, 0x88, + 0xdb, 0x3b, 0x7d, 0x13, 0x36, 0xf7, 0x02, 0x43, 0xf3, 0x35, 0x27, 0x85, + 0x6f, 0x6e, 0x45, 0x80, 0x07, 0x0f, 0xe6, 0x96, 0x13, 0x82, 0x7c, 0xec, + 0x40, 0x82, 0xc0, 0xe6, 0xe4, 0xea, 0xf9, 0x73, 0x94, 0x00, 0x67, 0x00, + 0xa6, 0xc9, 0xda, 0x41, 0x7f, 0x06, 0x7a, 0xeb, 0x7f, 0x34, 0xf7, 0x94, + 0x5f, 0x1c, 0x3c, 0x13, 0x3f, 0xe8, 0xa8, 0xde, 0xaf, 0xeb, 0x97, 0xfd, + 0xd6, 0xed, 0xb4, 0x21, 0x6c, 0x24, 0xb7, 0x43, 0xee, 0xe9, 0x7b, 0xcc, + 0xb4, 0x26, 0x79, 0xcb, 0x65, 0xf4, 0x1c, 0xd4, 0x80, 0x3a, 0xde, 0x54, + 0x0c, 0x20, 0xe7, 0xc3, 0xae, 0xe4, 0xa0, 0x53, 0x73, 0x3b, 0x0c, 0x74, + 0x9c, 0xca, 0x17, 0x6b, 0x57, 0x09, 0xf0, 0xe9, 0xe7, 0x3c, 0x6d, 0x6f, + 0x88, 0x26, 0x82, 0x17, 0xfc, 0x6e, 0x4f, 0x04, 0xa5, 0x56, 0xe9, 0x1b, + 0x37, 0x6c, 0xc6, 0xbc, 0x88, 0xfe, 0xc4, 0x4d, 0x7a, 0xc9, 0x50, 0x3a, + 0xc9, 0x29, 0x9b, 0x14, 0x28, 0x60, 0x4b, 0x75, 0x3f, 0xbd, 0x3f, 0x9f, + 0x39, 0xe6, 0x1b, 0x8a, 0xa7, 0x4b, 0x10, 0x65, 0x52, 0x82, 0xe0, 0xd6, + 0xf4, 0x26, 0x51, 0x78, 0x1d, 0x5b, 0x95, 0x0d, 0x53, 0x2b, 0x7e, 0x2f, + 0xe8, 0xf9, 0x9d, 0x47, 0xf6, 0x58, 0xe9, 0x30, 0xe2, 0xc3, 0xe1, 0x6d, + 0xdc, 0x50, 0x03, 0xdb, 0xcc, 0x94, 0x00, 0x5d, 0xe0, 0x07, 0xb6, 0x2f, + 0x97, 0xef, 0xc6, 0x3a, 0xc2, 0xc0, 0x99, 0xe7, 0x65, 0x89, 0x1b, 0x4e, + 0x59, 0x1f, 0xe7, 0xae, 0xc0, 0x1e, 0x61, 0x92, 0x5f, 0x55, 0xaa, 0x51, + 0xcc, 0xf6, 0x4e, 0x32, 0x56, 0x76, 0x99, 0x2b, 0x6e, 0xe8, 0x5c, 0xc9, + 0xe2, 0xa8, 0x78, 0x4b, 0x76, 0x85, 0xf3, 0x34, 0x5c, 0x52, 0x8e, 0xa5, + 0xed, 0x4a, 0x87, 0x9e, 0x3e, 0x90, 0x9b, 0xcf, 0xec, 0x57, 0x4b, 0x60, + 0x5a, 0xc9, 0x69, 0x0c, 0x63, 0x7a, 0x01, 0x26, 0x88, 0xb9, 0x32, 0x82, + 0x48, 0x02, 0x1b, 0x2c, 0xbe, 0x95, 0xb9, 0x2f, 0xe1, 0x4b, 0x6c, 0x4e, + 0x03, 0xdb, 0xc7, 0xce, 0xcf, 0x67, 0xf1, 0x1f, 0x83, 0xca, 0xb6, 0x20, + 0x06, 0xcd, 0xb8, 0xd9, 0xcb, 0x94, 0xb0, 0xa1, 0x88, 0xdc, 0xf9, 0x2c, + 0x4a, 0xb6, 0x85, 0x14, 0x42, 0x6c, 0xbb, 0x0d, 0x48, 0xd6, 0x51, 0x8f, + 0x21, 0x4a, 0xd4, 0x74, 0x6f, 0xdf, 0x89, 0x76, 0xf2, 0xe7, 0xcd, 0x32, + 0xc4, 0x4b, 0x52, 0xca, 0x5c, 0x08, 0x2c, 0x6b, 0x76, 0x88, 0xa4, 0x41, + 0x62, 0xed, 0x96, 0x71, 0xb0, 0xa4, 0x37, 0x2d, 0x91, 0x60, 0x69, 0x6d, + 0xee, 0x00, 0x18, 0x6f, 0x20, 0x0d, 0x48, 0xff, 0xd7, 0x2c, 0xb5, 0x4b, + 0x27, 0xf3, 0x91, 0xf3, 0x6a, 0x20, 0x04, 0xc5, 0x95, 0x10, 0x36, 0x0f, + 0x6f, 0x4c, 0x00, 0xc0, 0x57, 0x3e, 0xc0, 0x16, 0xcd, 0xba, 0x30, 0xcc, + 0x28, 0xed, 0xa7, 0xcf, 0x35, 0x94, 0xe0, 0xb6, 0x39, 0xdc, 0xb1, 0x25, + 0x09, 0x42, 0xd1, 0x8d, 0x7c, 0x87, 0x20, 0x53, 0x7b, 0xc0, 0x1b, 0x5d, + 0x00, 0x7f, 0xc3, 0xdf, 0xc6, 0xa1, 0x68, 0x61, 0x3c, 0xdb, 0x65, 0xf1, + 0x2d, 0xbd, 0xc3, 0x7c, 0x6c, 0x01, 0xa0, 0x9e, 0xd3, 0x9d, 0xd9, 0xd8, + 0xeb, 0x73, 0x5f, 0x76, 0xdd, 0x41, 0xe1, 0x6d, 0xcf, 0x00, 0x64, 0x44, + 0xea, 0x6c, 0x36, 0xdb, 0x40, 0x95, 0x2e, 0x9b, 0x42, 0x5b, 0x32, 0x36, + 0xba, 0x8b, 0x9b, 0x8e, 0xb4, 0x78, 0x6d, 0x87, 0x1e, 0xda, 0x08, 0xb3, + 0x75, 0x64, 0x6f, 0xeb, 0x3f, 0xcf, 0x7e, 0x85, 0x77, 0x8f, 0xcd, 0x55, + 0x87, 0x48, 0x75, 0x4a, 0x48, 0x6e, 0x00, 0xb0, 0x06, 0xe0, 0x07, 0xdc, + 0xd2, 0x33, 0xa7, 0x38, 0x54, 0x92, 0x1b, 0xa9, 0x5c, 0xa5, 0x64, 0x31, + 0x07, 0x37, 0x88, 0x00, 0x36, 0x20, 0x88, 0xa5, 0x8b, 0x90, 0xfc, 0xe2, + 0xcb, 0x24, 0x55, 0x01, 0xec, 0x6e, 0x37, 0xcf, 0xcf, 0xf0, 0x55, 0x99, + 0xf1, 0xe7, 0x4f, 0x77, 0x7b, 0x22, 0xc1, 0xab, 0x4f, 0x83, 0x23, 0x3f, + 0x8e, 0x37, 0x5c, 0x81, 0xf0, 0xea, 0x95, 0x0b, 0xad, 0x5c, 0x65, 0x41, + 0xad, 0xc0, 0x02, 0xe1, 0x53, 0xfc, 0x2a, 0x6b, 0xe8, 0x6d, 0xd7, 0x86, + 0xa1, 0x4d, 0xdc, 0x23, 0x00, 0x3c, 0xe8, 0x01, 0xb8, 0x03, 0x8f, 0x3e, + 0xfd, 0xf9, 0xda, 0x51, 0xb3, 0x99, 0xce, 0xd8, 0x71, 0x43, 0x46, 0x64, + 0x6f, 0x82, 0x11, 0x25, 0x11, 0xb9, 0x74, 0x0f, 0x1d, 0x46, 0x37, 0xb1, + 0x00, 0x68, 0x44, 0xa0, 0x0e, 0xc4, 0x60, 0x9f, 0x9e, 0xcc, 0x5b, 0x35, + 0xff, 0x9d, 0xd4, 0x37, 0x00, 0xc2, 0x7e, 0x14, 0x38, 0xa3, 0xe8, 0x5b, + 0x6f, 0xe4, 0x41, 0xb2, 0x46, 0x84, 0x8f, 0x49, 0x11, 0x80, 0x00, 0x00, + 0x01, 0x04, 0x43, 0xf9, 0x8e, 0xd8, 0xe7, 0x69, 0x90, 0x2f, 0x79, 0x44, + 0x6c, 0xf5, 0xf4, 0x47, 0x79, 0x4e, 0x1e, 0xb2, 0x59, 0x54, 0x21, 0x18, + 0x3d, 0xd3, 0x49, 0x98, 0x1a, 0x07, 0x35, 0x22, 0x72, 0x71, 0xd1, 0x70, + 0xe2, 0xd5, 0x75, 0x0a, 0x50, 0xd6, 0xf3, 0x52, 0xc6, 0xf1, 0xd1, 0xbc, + 0xba, 0xa0, 0x16, 0x17, 0xea, 0x39, 0xb4, 0x7c, 0xd3, 0x0d, 0x92, 0x8f, + 0x92, 0x27, 0x8b, 0x58, 0x28, 0x9f, 0xbc, 0xcd, 0xba, 0x52, 0x87, 0x5c, + 0x52, 0xdb, 0x41, 0x13, 0xb9, 0xcc, 0x42, 0x74, 0xa3, 0xeb, 0x86, 0x6d, + 0x55, 0x3a, 0xd6, 0x71, 0xf2, 0x2a, 0x33, 0xa3, 0x9b, 0xf2, 0xde, 0xee, + 0xd7, 0x3e, 0x15, 0x95, 0x81, 0x1f, 0x8d, 0xe4, 0x44, 0xba, 0x14, 0x7c, + 0xb2, 0xb7, 0xb1, 0x10, 0xab, 0x32, 0xdf, 0x09, 0x15, 0x5b, 0xb3, 0xda, + 0xfd, 0x79, 0x12, 0xb9, 0x28, 0x45, 0x92, 0x42, 0x13, 0x72, 0xcb, 0x16, + 0x12, 0x58, 0x54, 0x46, 0xfc, 0x88, 0x03, 0xf4, 0xb4, 0x9f, 0x54, 0x05, + 0x51, 0x7c, 0x9d, 0xe2, 0xa8, 0x58, 0x59, 0x6c, 0xa2, 0x93, 0xda, 0x1b, + 0xa8, 0x13, 0xb2, 0xc5, 0x6f, 0x47, 0x25, 0x15, 0xce, 0x5c, 0xa0, 0x94, + 0x01, 0x19, 0x6d, 0x04, 0xbf, 0xfd, 0x56, 0xf1, 0xd0, 0x0c, 0x15, 0x6f, + 0xa3, 0x77, 0x0f, 0x56, 0xd0, 0xe6, 0xe8, 0xb3, 0xcf, 0xac, 0xd4, 0xf5, + 0x29, 0xba, 0x1b, 0xf8, 0x39, 0xb0, 0xcc, 0x9f, 0x3a, 0xe9, 0xa4, 0x26, + 0xee, 0xbf, 0x3f, 0x09, 0x08, 0x6d, 0x34, 0xb9, 0x5a, 0x1b, 0xe4, 0xb7, + 0x53, 0xd8, 0x10, 0xbf, 0xdf, 0x98, 0x4b, 0xd8, 0xb3, 0xc5, 0xa8, 0xef, + 0x3c, 0xae, 0xc5, 0x08, 0x59, 0x49, 0x32, 0x8c, 0x6e, 0x74, 0x2e, 0xd2, + 0x4b, 0x21, 0xac, 0x37, 0xf5, 0x69, 0xf9, 0x52, 0x5c, 0x88, 0x4b, 0x6c, + 0x4f, 0xa0, 0x16, 0xf3, 0xe7, 0x68, 0x04, 0x1b, 0x8b, 0xe2, 0x91, 0x09, + 0x0c, 0xb9, 0x00, 0x0d, 0xf0, 0x5c, 0x04, 0xcf, 0xfd, 0x5a, 0x49, 0x67, + 0xe1, 0x31, 0xfc, 0x19, 0xb4, 0x30, 0xd7, 0x1b, 0x3d, 0x14, 0xef, 0x14, + 0xac, 0xc6, 0x23, 0x41, 0xe0, 0x73, 0x7e, 0x53, 0x78, 0xdf, 0xb7, 0x3f, + 0x1c, 0x73, 0x20, 0x6a, 0xe6, 0x72, 0x60, 0xe2, 0x62, 0xa5, 0xf5, 0x6d, + 0xbf, 0x6c, 0x84, 0x7f, 0xad, 0x4e, 0x2c, 0x80, 0x4e, 0xf3, 0x32, 0xe6, + 0xc3, 0xe9, 0x49, 0x06, 0xb6, 0x69, 0xc6, 0x4f, 0x8e, 0x04, 0x3d, 0xf3, + 0x29, 0x36, 0x5e, 0x73, 0x7c, 0xcc, 0x96, 0x2a, 0x15, 0x51, 0x67, 0x85, + 0x8d, 0x89, 0xfa, 0x7c, 0x84, 0x39, 0x80, 0x5b, 0x3b, 0x52, 0x54, 0x6f, + 0x57, 0x69, 0xb9, 0xb6, 0x37, 0xf4, 0x70, 0x07, 0x22, 0xe7, 0xc7, 0xdb, + 0x78, 0x7b, 0xc2, 0x73, 0x2c, 0xb1, 0x17, 0xf1, 0x1b, 0xe7, 0x3f, 0x7e, + 0xb7, 0xfc, 0x47, 0x9e, 0x41, 0x17, 0x28, 0xed, 0x3a, 0xc6, 0xf7, 0xbf, + 0xe7, 0x82, 0x0f, 0xf6, 0x4a, 0x2e, 0x00, 0x41, 0xba, 0xb7, 0x28, 0x5b, + 0x7b, 0xad, 0xda, 0x4e, 0xb7, 0x25, 0x0c, 0xb5, 0x0a, 0x6e, 0x5c, 0x8b, + 0xb2, 0xc6, 0xe1, 0xe3, 0x10, 0x5c, 0xb2, 0x04, 0x2b, 0x7f, 0x9e, 0x2d, + 0xf3, 0xf3, 0x03, 0x87, 0x86, 0x96, 0xdd, 0x61, 0x38, 0xed, 0x77, 0xcc, + 0x35, 0x60, 0xfb, 0x64, 0xa6, 0x0d, 0x1f, 0x69, 0x6d, 0x39, 0xb4, 0x01, + 0xb0, 0x9f, 0xf7, 0x2f, 0xd0, 0x9d, 0x7f, 0x0a, 0xeb, 0x69, 0xe0, 0x4c, + 0xa8, 0xdd, 0x27, 0x15, 0x9d, 0xed, 0x0b, 0x57, 0xea, 0x96, 0x03, 0x26, + 0xd2, 0x2b, 0xa2, 0x90, 0xf6, 0x36, 0xf0, 0x0c, 0x4b, 0x00, 0x06, 0x72, + 0xb7, 0xa6, 0x02, 0x17, 0xf8, 0x91, 0x63, 0xa4, 0x80, 0x3d, 0x37, 0xdf, + 0x78, 0x33, 0x21, 0xe4, 0xd5, 0x2a, 0x20, 0x4b, 0x7d, 0x7b, 0xe6, 0x02, + 0x0f, 0xf5, 0x80, 0x2c, 0xfe, 0x66, 0x89, 0xe2, 0x69, 0x59, 0x9b, 0xef, + 0xed, 0xe7, 0x27, 0x91, 0xf6, 0x93, 0xf6, 0x54, 0xa0, 0x11, 0x4b, 0x5b, + 0xe5, 0x30, 0x10, 0xbf, 0xea, 0xbe, 0xd8, 0x37, 0xf5, 0x62, 0x6d, 0xbe, + 0x0d, 0xd8, 0xfa, 0x7f, 0xb8, 0x00, 0x77, 0xef, 0x9e, 0x69, 0x47, 0xa3, + 0xb8, 0xf3, 0xc8, 0x32, 0x87, 0xe9, 0x52, 0x2b, 0x73, 0xce, 0x6e, 0x26, + 0x45, 0x08, 0x2d, 0xb8, 0xf2, 0xa2, 0x23, 0x7e, 0xbf, 0x1f, 0x9b, 0x73, + 0x53, 0x60, 0x4c, 0x29, 0x46, 0x52, 0xdb, 0xa4, 0x00, 0xa4, 0x8b, 0x9f, + 0x7e, 0x05, 0x88, 0x9a, 0xe9, 0x46, 0x51, 0x5f, 0x4f, 0x73, 0x37, 0xcc, + 0xf9, 0xfa, 0x85, 0xa9, 0xe3, 0x9b, 0xe7, 0x22, 0xe0, 0x01, 0xf6, 0x8a, + 0x8f, 0xd0, 0x9b, 0x78, 0xc4, 0x2c, 0x04, 0x68, 0x53, 0x7b, 0x5a, 0xa4, + 0x52, 0x0e, 0x4d, 0x30, 0x05, 0x7c, 0xae, 0x9e, 0x1d, 0x60, 0xd0, 0xb6, + 0xf2, 0x72, 0x82, 0x17, 0xfd, 0x57, 0x5c, 0x81, 0xb7, 0x4c, 0x29, 0xb0, + 0x85, 0xec, 0x2b, 0xc6, 0x46, 0xf3, 0x80, 0x14, 0xf0, 0xf0, 0x07, 0x3f, + 0x4e, 0x7d, 0xb1, 0xd0, 0x27, 0x7a, 0x7e, 0x2b, 0xa5, 0x2e, 0x15, 0x29, + 0xd5, 0xb2, 0xfc, 0x3e, 0x00, 0x3a, 0xf7, 0xbb, 0x64, 0x41, 0xdd, 0x3a, + 0x2e, 0x21, 0xc7, 0x16, 0xaa, 0x17, 0x55, 0xbe, 0xac, 0x00, 0xab, 0xa7, + 0x7c, 0x80, 0x57, 0xbd, 0xbf, 0x68, 0x11, 0xf9, 0xd0, 0xfc, 0x29, 0x00, + 0x8a, 0x34, 0x92, 0xdf, 0x37, 0x00, 0x75, 0xed, 0xee, 0x00, 0xfb, 0xdb, + 0x33, 0xa8, 0x47, 0xed, 0xf6, 0x2e, 0x87, 0x1d, 0x31, 0xce, 0x88, 0x54, + 0x29, 0xbd, 0x47, 0x3e, 0x0b, 0x15, 0x33, 0x4c, 0x09, 0x2e, 0xa5, 0xbe, + 0x2d, 0xbe, 0x6a, 0xc2, 0xd0, 0x25, 0xbf, 0x9b, 0x57, 0x66, 0xf0, 0x63, + 0xb2, 0x05, 0x0f, 0x0b, 0x6d, 0x2f, 0x2e, 0xd0, 0x29, 0xb6, 0x88, 0xdd, + 0xeb, 0x80, 0x09, 0xec, 0x2c, 0x07, 0xb6, 0x4f, 0x16, 0x8e, 0x12, 0x08, + 0x3f, 0xd8, 0x00, 0xfb, 0x39, 0x4a, 0x3d, 0x60, 0x8e, 0x64, 0xd7, 0x14, + 0xb0, 0xed, 0x2e, 0x5b, 0x43, 0x28, 0xe6, 0xdc, 0xc5, 0x80, 0x53, 0x4c, + 0x94, 0xb4, 0x6f, 0x29, 0x1b, 0x9b, 0x7e, 0xa4, 0xe3, 0x32, 0xd4, 0x8b, + 0x78, 0x8f, 0x4e, 0x4d, 0x01, 0xc2, 0x98, 0x6a, 0x0d, 0x2c, 0xf0, 0xc5, + 0x6f, 0x68, 0x22, 0xf6, 0x23, 0xe9, 0x05, 0x5e, 0xf2, 0x8e, 0xab, 0xd6, + 0xba, 0x2c, 0x0f, 0x85, 0x4b, 0x0a, 0x94, 0x28, 0x7b, 0x69, 0x00, 0x5e, + 0x4f, 0x00, 0x6a, 0x00, 0xe3, 0xdb, 0xb1, 0x79, 0xb4, 0x73, 0x85, 0x93, + 0xd7, 0x8e, 0x7b, 0x3f, 0x2a, 0x6c, 0x40, 0x1c, 0x51, 0x8d, 0xfa, 0x34, + 0x01, 0x0f, 0xdf, 0x5f, 0x44, 0x89, 0xcc, 0x90, 0xbb, 0x43, 0xde, 0xf2, + 0xc7, 0xdf, 0x5a, 0xd4, 0x2c, 0xae, 0x34, 0xbf, 0x06, 0xd9, 0xe5, 0xbb, + 0x4b, 0x6f, 0xf2, 0x77, 0x29, 0xc4, 0x85, 0xb6, 0x7e, 0xe2, 0xd8, 0x8d, + 0xfa, 0xc8, 0x00, 0x9c, 0x01, 0xc8, 0xbd, 0xd8, 0x1d, 0x1d, 0x90, 0x98, + 0x12, 0xd9, 0x40, 0x08, 0x7f, 0xfa, 0x46, 0x11, 0x49, 0xe2, 0x64, 0x2a, + 0x79, 0x98, 0xb4, 0xab, 0x4a, 0x8d, 0x98, 0x9e, 0x25, 0xb4, 0xf6, 0x5d, + 0xba, 0x55, 0x3d, 0xbf, 0x9b, 0x80, 0x3b, 0xf8, 0x70, 0x02, 0xf2, 0x30, + 0x03, 0xbb, 0xde, 0xad, 0xa5, 0x66, 0x80, 0x1e, 0x4e, 0x26, 0xbb, 0x50, + 0xba, 0x7e, 0xd4, 0x48, 0x58, 0x4b, 0x79, 0xa2, 0x27, 0x0f, 0xf7, 0xeb, + 0x48, 0xfd, 0x5a, 0x32, 0xc4, 0xeb, 0x72, 0x2c, 0x38, 0xed, 0xb5, 0x61, + 0x0a, 0x37, 0xe9, 0x7f, 0x9d, 0xbf, 0x5f, 0xef, 0xb8, 0xbd, 0xf5, 0xed, + 0xf6, 0xc8, 0x15, 0x87, 0x48, 0x14, 0xdf, 0x9f, 0x80, 0x1e, 0xf5, 0xa0, + 0x05, 0x14, 0x8d, 0xec, 0x2c, 0xe2, 0xe3, 0xed, 0xc1, 0x0e, 0x79, 0x47, + 0x13, 0x0b, 0xa9, 0xe0, 0x5a, 0xb4, 0x8b, 0xa4, 0xe3, 0x4e, 0x0a, 0x4b, + 0x63, 0x3e, 0x7f, 0x0a, 0x4a, 0xa7, 0x37, 0xcd, 0xfb, 0xb9, 0xc2, 0xdd, + 0xc6, 0xeb, 0xec, 0x1b, 0x92, 0x59, 0xfb, 0x39, 0xbe, 0x96, 0x00, 0xfc, + 0x5e, 0x09, 0xf7, 0x13, 0x38, 0xe8, 0x6a, 0x68, 0x05, 0x44, 0xcc, 0x7d, + 0x01, 0x5e, 0xd2, 0x8e, 0x1a, 0xad, 0xf3, 0x5f, 0xee, 0x7b, 0x7d, 0x44, + 0x5d, 0x15, 0x62, 0x25, 0x9b, 0xa1, 0x86, 0x14, 0x6f, 0x89, 0x41, 0x25, + 0x56, 0xfb, 0x57, 0xf0, 0x8b, 0x84, 0x5f, 0xbf, 0x7b, 0xc6, 0x8c, 0x47, + 0x64, 0x87, 0x3a, 0x21, 0x54, 0x7d, 0x3d, 0xb8, 0x7b, 0x78, 0x05, 0xa4, + 0xc9, 0xa1, 0x91, 0x1a, 0x1f, 0xa4, 0xfa, 0x52, 0xb7, 0xe4, 0x88, 0x00, + 0x15, 0x0a, 0x16, 0x96, 0xac, 0x55, 0x7d, 0x7e, 0x99, 0x86, 0xd2, 0xce, + 0xb0, 0x6d, 0x09, 0x6f, 0x19, 0xe7, 0x3d, 0xac, 0x8e, 0x7e, 0xd5, 0x36, + 0x9f, 0x86, 0xd5, 0x0b, 0x6f, 0x60, 0x00, 0xe8, 0x8b, 0x08, 0xc8, 0xfd, + 0x99, 0xa5, 0x96, 0xeb, 0x26, 0x45, 0x0b, 0xaa, 0x73, 0x7c, 0x9f, 0xda, + 0xd0, 0x06, 0xdf, 0x42, 0x27, 0x62, 0xc0, 0x45, 0xe6, 0xfb, 0x56, 0x0c, + 0x26, 0x4b, 0x0a, 0x2d, 0xa7, 0x93, 0x27, 0x42, 0x16, 0x0f, 0x53, 0x69, + 0xd0, 0x69, 0xc5, 0xb7, 0x3d, 0xb2, 0x4c, 0x58, 0xdf, 0x24, 0x01, 0xf9, + 0x3b, 0xa1, 0x04, 0x6e, 0xc4, 0xfc, 0x6a, 0x5b, 0x3c, 0xe3, 0xb7, 0x83, + 0x43, 0xe0, 0x65, 0xb0, 0xab, 0x65, 0x46, 0xfd, 0x38, 0x00, 0x8c, 0x8a, + 0x08, 0x3f, 0xcc, 0x00, 0xfc, 0x8e, 0xf0, 0x0b, 0x34, 0x11, 0xc0, 0x13, + 0x8f, 0x20, 0x31, 0x0a, 0x53, 0xb4, 0x7e, 0x9f, 0xe8, 0xde, 0x0f, 0xfb, + 0xcd, 0x00, 0x4a, 0x47, 0xd7, 0x79, 0x41, 0xf8, 0x01, 0x66, 0x49, 0x6e, + 0xd3, 0xc0, 0x72, 0x19, 0x09, 0x2d, 0xef, 0xdd, 0x1d, 0x04, 0xbe, 0x19, + 0x80, 0x2b, 0xc7, 0x07, 0x6a, 0x0e, 0x45, 0x43, 0x9b, 0xd6, 0xe3, 0x6f, + 0x39, 0x15, 0x60, 0xca, 0x6c, 0xab, 0x47, 0x37, 0x6c, 0xa6, 0xd6, 0x00, + 0x00, 0x01, 0x05, 0x43, 0xf9, 0x7d, 0x74, 0xbc, 0x58, 0xed, 0x01, 0x5e, + 0xd0, 0x82, 0x99, 0x05, 0xde, 0x29, 0x32, 0x84, 0xea, 0x9f, 0x46, 0x37, + 0x4e, 0x3e, 0x5b, 0x4c, 0xb6, 0x0e, 0x68, 0x2b, 0xdd, 0xc6, 0x95, 0x92, + 0xc5, 0x4d, 0xf0, 0x6e, 0x02, 0x9b, 0xc7, 0xc5, 0xd3, 0xa3, 0x7c, 0xf1, + 0x6e, 0xbb, 0x25, 0x90, 0x22, 0x69, 0xb2, 0x21, 0x46, 0xb3, 0x0b, 0xe7, + 0x9a, 0xfd, 0x76, 0x5a, 0xa6, 0xcf, 0x38, 0x8e, 0x9b, 0xa7, 0x19, 0x50, + 0xc8, 0xdd, 0x93, 0x43, 0x9e, 0x1e, 0xed, 0xb1, 0x66, 0x07, 0x2a, 0xa5, + 0x6d, 0xbb, 0x45, 0xba, 0x7d, 0x44, 0xce, 0x3b, 0xd2, 0xe5, 0x9d, 0x47, + 0xd7, 0x75, 0x77, 0x89, 0x15, 0x0f, 0x02, 0x75, 0xb9, 0x4d, 0x27, 0x45, + 0x3d, 0xb7, 0x2e, 0xa8, 0x1c, 0xdf, 0x96, 0xda, 0x6d, 0x88, 0xde, 0xcd, + 0xdc, 0x80, 0x1f, 0xf2, 0xfc, 0x92, 0x41, 0xf5, 0xf1, 0x02, 0xe0, 0xda, + 0x84, 0x36, 0xf2, 0xdc, 0x97, 0xc7, 0x04, 0x8b, 0x1b, 0x03, 0x9d, 0x05, + 0x7b, 0xf4, 0x6d, 0x9e, 0x18, 0x85, 0xb4, 0x5a, 0x38, 0x86, 0xdc, 0xd4, + 0xa9, 0x1b, 0xeb, 0x67, 0x37, 0xfd, 0xd6, 0x3b, 0xb7, 0xe4, 0x2c, 0xcc, + 0xd7, 0x98, 0x8f, 0xb2, 0x15, 0x0b, 0x44, 0x54, 0x6f, 0x1a, 0x08, 0x60, + 0x0d, 0x55, 0xbb, 0x02, 0x2a, 0xe5, 0xf2, 0xf4, 0x36, 0xd4, 0x6e, 0x56, + 0xc3, 0x1d, 0x29, 0x2f, 0x25, 0x6f, 0x42, 0x50, 0xea, 0xa4, 0x36, 0xd8, + 0x7b, 0x7b, 0xc4, 0x82, 0x17, 0xfa, 0xd7, 0xe4, 0x40, 0xb4, 0x46, 0xb4, + 0x8d, 0xd6, 0xf5, 0xa6, 0xbe, 0xd1, 0x85, 0x41, 0xed, 0xe8, 0x2a, 0xe5, + 0xe7, 0x49, 0x76, 0xda, 0xde, 0x66, 0x54, 0x73, 0xac, 0xbe, 0x3a, 0x89, + 0xe2, 0x39, 0xae, 0x87, 0x69, 0xed, 0x27, 0x37, 0xb4, 0x45, 0x00, 0x3e, + 0x84, 0x5e, 0x57, 0x01, 0x20, 0x00, 0xf9, 0x99, 0x38, 0x9e, 0x0a, 0x5c, + 0x21, 0x37, 0x9b, 0x81, 0xcd, 0xdb, 0xe9, 0xf3, 0xfd, 0xc7, 0x1e, 0x72, + 0x51, 0xb2, 0x58, 0xdc, 0x22, 0x63, 0x72, 0x8d, 0xac, 0xce, 0x6f, 0xd2, + 0x11, 0xb8, 0x04, 0x1f, 0xed, 0xc1, 0x1d, 0xca, 0x13, 0xe7, 0xbb, 0x56, + 0x0c, 0x19, 0x31, 0xaf, 0xc5, 0x00, 0x74, 0xf2, 0x31, 0x88, 0x1b, 0x37, + 0xbf, 0x3b, 0x76, 0x1e, 0x03, 0x88, 0x52, 0xa3, 0x72, 0xf9, 0x40, 0x07, + 0x3b, 0xf1, 0x99, 0x60, 0x4c, 0x32, 0xdb, 0x28, 0x4a, 0xa9, 0x2e, 0x35, + 0x9c, 0x60, 0x20, 0x80, 0x9f, 0x5e, 0xd2, 0xcf, 0x1e, 0x05, 0xc5, 0xf0, + 0xbc, 0x92, 0x1b, 0x53, 0xdb, 0xaa, 0xad, 0x45, 0x21, 0xab, 0x7b, 0xf7, + 0x99, 0xcf, 0x1b, 0x0c, 0xca, 0x39, 0x3d, 0xb5, 0xd3, 0x28, 0xca, 0x76, + 0xd2, 0xe9, 0x66, 0x36, 0x57, 0x99, 0xf1, 0xcd, 0xbe, 0x55, 0x3f, 0x69, + 0x66, 0xc1, 0xaa, 0x3e, 0x01, 0xcd, 0xe8, 0xfa, 0x7e, 0x80, 0x33, 0xc2, + 0x7c, 0xf3, 0x0a, 0xe1, 0xd6, 0x63, 0xa8, 0x0a, 0xe4, 0xb6, 0x94, 0x10, + 0x18, 0xd9, 0x79, 0xdb, 0xf4, 0xa2, 0x75, 0xf4, 0x2a, 0x7c, 0x9b, 0x84, + 0x38, 0x8a, 0xda, 0x35, 0xe7, 0xe4, 0xca, 0x4a, 0x6f, 0x85, 0xd0, 0x21, + 0x7f, 0xd3, 0xd7, 0x77, 0xc2, 0x18, 0xb7, 0xc2, 0xd6, 0xfa, 0xef, 0xd2, + 0xcf, 0xf8, 0x8d, 0x45, 0x01, 0x14, 0xb2, 0xc8, 0x34, 0x63, 0x7c, 0x75, + 0x17, 0x72, 0x12, 0xa2, 0x92, 0x0e, 0x6e, 0x8d, 0x90, 0x5f, 0x3a, 0xed, + 0x30, 0x2a, 0x3e, 0x36, 0x1a, 0x1d, 0x1b, 0x7e, 0x40, 0xc7, 0x56, 0xfa, + 0x46, 0xee, 0xd8, 0x08, 0x20, 0x27, 0x40, 0x1c, 0x79, 0x4a, 0x17, 0xd6, + 0x3e, 0xda, 0x17, 0x36, 0x55, 0xa1, 0x4d, 0xec, 0x85, 0xcd, 0xf7, 0x17, + 0xbc, 0x10, 0x2d, 0x2f, 0x6d, 0x0f, 0xc7, 0x9a, 0xf1, 0x87, 0x06, 0x50, + 0x96, 0xf0, 0xfd, 0x02, 0x10, 0x06, 0x8a, 0xe8, 0x41, 0x0b, 0x63, 0xf7, + 0x3c, 0x26, 0xd6, 0xf7, 0x3f, 0xcd, 0x84, 0x7d, 0x12, 0x84, 0x3b, 0x57, + 0xc4, 0x7f, 0xab, 0x71, 0x4c, 0x00, 0xab, 0x76, 0x5f, 0x57, 0xa5, 0xcf, + 0x16, 0xe4, 0xb8, 0x40, 0xd7, 0x80, 0x0c, 0x6a, 0xb7, 0xe7, 0xb5, 0xd5, + 0xd7, 0x8e, 0x28, 0xc4, 0x57, 0xc9, 0x4e, 0xb4, 0xba, 0x5d, 0x6f, 0xa0, + 0xe6, 0x0b, 0xff, 0x8a, 0x17, 0x79, 0xf2, 0x59, 0x2c, 0x37, 0x3a, 0xe6, + 0xba, 0x18, 0x7c, 0x2e, 0x01, 0xed, 0xe5, 0xba, 0xe4, 0x00, 0xe3, 0xa1, + 0x7d, 0x3e, 0xd8, 0x3c, 0xed, 0xb2, 0x85, 0x18, 0x5b, 0x7a, 0x3c, 0x73, + 0xc1, 0x03, 0xf3, 0x39, 0xe2, 0xd9, 0x88, 0x71, 0x3b, 0xbe, 0x3c, 0xe9, + 0x67, 0xc0, 0xe2, 0xe0, 0x14, 0xd9, 0x77, 0x41, 0x08, 0x01, 0xab, 0xe2, + 0x10, 0x9b, 0x91, 0xe0, 0x67, 0x89, 0x72, 0xb7, 0xe4, 0x7e, 0x3a, 0x00, + 0xb3, 0x5d, 0x85, 0xd9, 0x6c, 0x52, 0x8b, 0xbe, 0xb0, 0x08, 0x6e, 0x98, + 0x03, 0xed, 0x78, 0x03, 0xf1, 0x66, 0x3b, 0x8c, 0x83, 0x97, 0x30, 0x9a, + 0x5a, 0x40, 0xe9, 0x6c, 0x3e, 0x86, 0xb7, 0xe9, 0x10, 0x40, 0xfd, 0x40, + 0x07, 0x3d, 0xf0, 0x00, 0xf3, 0x8f, 0x61, 0x5a, 0xec, 0x85, 0xf2, 0xff, + 0x24, 0x29, 0xc6, 0x87, 0x7e, 0x83, 0x24, 0x6d, 0x60, 0x04, 0xa0, 0x0e, + 0x7d, 0xfa, 0x17, 0xb8, 0xf9, 0xe5, 0x92, 0x4c, 0x97, 0xcd, 0xf9, 0x13, + 0x6d, 0x32, 0x1c, 0xdd, 0x9f, 0x27, 0xad, 0x50, 0xb6, 0xea, 0x16, 0x7c, + 0xb5, 0x5b, 0xfc, 0xda, 0x00, 0xf3, 0xe3, 0xbe, 0x39, 0xf2, 0xe1, 0xef, + 0xe4, 0xb5, 0xcc, 0x78, 0x01, 0xf3, 0x88, 0x3b, 0xe5, 0x09, 0xf2, 0x42, + 0xac, 0x4b, 0x54, 0x7d, 0xad, 0xd4, 0xe2, 0xec, 0x15, 0xb8, 0x64, 0x08, + 0xb9, 0xb4, 0xf1, 0x9e, 0x10, 0x2d, 0xbe, 0xb6, 0x00, 0x8f, 0xa8, 0x00, + 0xc0, 0x01, 0x16, 0xef, 0x3c, 0xf2, 0x85, 0xf9, 0x63, 0xc4, 0x8b, 0x72, + 0x53, 0x43, 0xcb, 0x5c, 0x52, 0x4b, 0x6e, 0x04, 0x0f, 0xd3, 0x00, 0xb3, + 0x28, 0xbe, 0xdf, 0x75, 0xf2, 0x1d, 0x15, 0x6c, 0x8d, 0xbb, 0xe5, 0xba, + 0xb7, 0xd6, 0x42, 0x98, 0xee, 0x79, 0x6c, 0xb6, 0x37, 0xf8, 0xdd, 0xd8, + 0x00, 0x26, 0x5a, 0x09, 0x80, 0x06, 0xe9, 0x67, 0xab, 0x7d, 0x14, 0x10, + 0x3f, 0x38, 0x8c, 0x08, 0x3f, 0xae, 0x00, 0xf3, 0x04, 0x08, 0x23, 0xf0, + 0x84, 0xd3, 0x3e, 0x5f, 0xb2, 0x10, 0x38, 0x42, 0x7d, 0x85, 0x86, 0xb8, + 0x6b, 0x7e, 0xaa, 0x00, 0x27, 0x00, 0x7e, 0x2c, 0x01, 0xc8, 0x03, 0xb7, + 0x82, 0x10, 0x03, 0x3f, 0x6a, 0x4c, 0xeb, 0xae, 0xa9, 0x50, 0xcb, 0x4d, + 0xda, 0x81, 0x2d, 0xed, 0xb0, 0x3a, 0xd5, 0x6e, 0x9d, 0x2e, 0xb6, 0xda, + 0x5d, 0xa8, 0xde, 0x62, 0x28, 0x9e, 0x48, 0xbf, 0x71, 0x62, 0xc4, 0xf7, + 0xa0, 0x3d, 0xde, 0x5e, 0xfb, 0x74, 0x74, 0x85, 0x0e, 0x92, 0x23, 0x74, + 0xdb, 0x2e, 0x16, 0xc7, 0x22, 0x36, 0xcd, 0xab, 0x61, 0xd3, 0xcb, 0x69, + 0x21, 0xa7, 0x54, 0x83, 0xd5, 0x95, 0xb1, 0xe0, 0x21, 0x00, 0x35, 0xd6, + 0xc0, 0xe8, 0x00, 0x6f, 0x65, 0x9e, 0xb9, 0x24, 0x66, 0xc3, 0x70, 0x53, + 0xa8, 0x03, 0x0f, 0x7f, 0xaf, 0x5b, 0x1c, 0x5c, 0x57, 0xd2, 0x03, 0xec, + 0x93, 0x24, 0x2e, 0xa8, 0xe3, 0x83, 0x1b, 0xe6, 0xe6, 0x91, 0x1e, 0x44, + 0xfb, 0x80, 0x5a, 0xf1, 0x24, 0xd7, 0x16, 0xfa, 0xf9, 0x03, 0x89, 0x96, + 0x19, 0xb3, 0x03, 0x0a, 0x19, 0x1b, 0xed, 0x0a, 0x1d, 0x69, 0x21, 0xbf, + 0x18, 0xbd, 0xc0, 0x06, 0x8f, 0xf8, 0x7c, 0xa1, 0xab, 0x3e, 0x28, 0xa4, + 0x04, 0xb0, 0x03, 0x31, 0x47, 0x8e, 0x6f, 0x2e, 0x50, 0x03, 0xea, 0x92, + 0x78, 0xd2, 0xc9, 0x4d, 0xc9, 0x00, 0xc6, 0xa3, 0x7e, 0x9b, 0xfe, 0x2b, + 0x3b, 0xeb, 0x8b, 0xbd, 0xc1, 0xd7, 0x31, 0xcf, 0xd8, 0x62, 0x15, 0x2a, + 0x1c, 0x7b, 0x75, 0xb2, 0x76, 0x45, 0x17, 0xed, 0xbf, 0xee, 0x2e, 0x96, + 0x99, 0x8f, 0xd2, 0xe2, 0x42, 0xc7, 0x0d, 0x6e, 0x01, 0x13, 0x1c, 0x00, + 0xa4, 0x4f, 0xb7, 0x6e, 0xd8, 0x38, 0x02, 0x9d, 0xe1, 0x66, 0xd3, 0xd5, + 0x20, 0xd6, 0xfa, 0x8c, 0x17, 0x80, 0x0f, 0x38, 0x9f, 0x8c, 0xa9, 0x15, + 0x4d, 0xc9, 0x25, 0x1a, 0x31, 0x54, 0xa6, 0xf3, 0x9e, 0x9c, 0xcd, 0x58, + 0xa3, 0x91, 0x51, 0x28, 0x5b, 0x72, 0xd2, 0xe5, 0x95, 0xbc, 0x00, 0x0e, + 0x7e, 0xef, 0x23, 0x47, 0xe3, 0xf5, 0xce, 0x2a, 0x13, 0xc3, 0xd5, 0x14, + 0x04, 0x45, 0x29, 0x29, 0xbe, 0x72, 0x00, 0xf7, 0x0d, 0x17, 0xed, 0xc7, + 0x7c, 0x00, 0xaa, 0x4e, 0x35, 0xea, 0xf2, 0xc7, 0x42, 0xa9, 0x47, 0x9e, + 0xde, 0xf3, 0x3a, 0x7f, 0x3b, 0xcb, 0xd3, 0x06, 0x5c, 0x26, 0x96, 0xa3, + 0x0b, 0x43, 0xda, 0xae, 0xa7, 0xbf, 0x31, 0x34, 0xc4, 0x1b, 0x38, 0xbc, + 0x42, 0xae, 0xd0, 0xc5, 0x6e, 0xbd, 0xbb, 0xb2, 0xe1, 0xb4, 0x34, 0xc4, + 0x56, 0xa5, 0xa8, 0x8a, 0xdf, 0x40, 0x8d, 0x39, 0xfe, 0xf1, 0xcc, 0x94, + 0x68, 0x79, 0x99, 0xdd, 0x8e, 0x8a, 0x5a, 0xab, 0xa8, 0xd5, 0x29, 0xb9, + 0xc0, 0x0e, 0x05, 0x80, 0x19, 0x73, 0x3a, 0x31, 0x00, 0x25, 0x8f, 0xda, + 0x4c, 0x94, 0x38, 0xed, 0xf5, 0x6e, 0x48, 0x8e, 0x9f, 0xf1, 0xcb, 0xb7, + 0xad, 0xb4, 0x05, 0x7c, 0xc2, 0x60, 0xdf, 0x06, 0xf9, 0x71, 0xa0, 0x02, + 0x6d, 0x15, 0xaf, 0xb2, 0x0c, 0x86, 0xf1, 0xb2, 0xdf, 0x46, 0xc7, 0xb7, + 0x9a, 0x2c, 0xcb, 0xe9, 0x30, 0xa8, 0xa0, 0x53, 0x25, 0x31, 0xf5, 0x51, + 0x80, 0x00, 0x00, 0x01, 0x06, 0x43, 0xf8, 0xce, 0x95, 0xb6, 0x28, 0x43, + 0x6a, 0xca, 0xf1, 0x3b, 0x30, 0xc4, 0x1c, 0x79, 0x7e, 0x81, 0x8d, 0x9b, + 0x67, 0x9f, 0x09, 0x81, 0x4d, 0xd8, 0x13, 0x08, 0x2e, 0x3f, 0xc5, 0x5b, + 0xc6, 0x45, 0x6f, 0x08, 0x73, 0x68, 0x2b, 0x2b, 0xa4, 0xcc, 0xf1, 0xa3, + 0x47, 0x35, 0x3d, 0x3a, 0x3b, 0xad, 0x4b, 0x24, 0x1b, 0x55, 0xb6, 0x5d, + 0x00, 0xb2, 0xda, 0xb0, 0x31, 0x25, 0x2d, 0xb9, 0xe4, 0xdc, 0x6c, 0x49, + 0x92, 0x44, 0x65, 0x92, 0x45, 0xad, 0xf7, 0xb4, 0x10, 0xbf, 0xc8, 0x67, + 0xa3, 0x07, 0xf6, 0x40, 0x10, 0x23, 0x97, 0x58, 0x1b, 0x23, 0xbc, 0xd6, + 0xc0, 0x08, 0xd1, 0xba, 0xcf, 0x04, 0x2f, 0xf1, 0x36, 0x12, 0x9b, 0xc0, + 0x7b, 0x60, 0x21, 0x80, 0x53, 0xa0, 0x5a, 0x3b, 0x32, 0x97, 0xe1, 0x4b, + 0x6e, 0x95, 0x58, 0x50, 0x00, 0xd5, 0xac, 0xf6, 0xf6, 0x91, 0x64, 0x23, + 0x76, 0x9b, 0x9e, 0x2a, 0x8a, 0xd5, 0xa8, 0x01, 0xee, 0x3b, 0x24, 0xf5, + 0xa7, 0x85, 0x37, 0xab, 0xea, 0xdc, 0x76, 0xba, 0xa8, 0x4c, 0xaa, 0x93, + 0xc4, 0x63, 0x78, 0xc4, 0xbb, 0xce, 0x52, 0x87, 0x52, 0xa4, 0x54, 0x09, + 0x6d, 0x00, 0x4a, 0xe5, 0xf5, 0x46, 0xb1, 0xad, 0xfa, 0xd8, 0x1c, 0x68, + 0x16, 0xde, 0x33, 0x01, 0x08, 0x02, 0xbb, 0x76, 0x6a, 0xf8, 0xe4, 0x01, + 0xf3, 0x7a, 0x23, 0x29, 0x3b, 0x81, 0x66, 0xba, 0x86, 0xce, 0x5c, 0x74, + 0x3c, 0xf0, 0xc6, 0xf9, 0xe7, 0x40, 0x84, 0x00, 0xce, 0x10, 0x58, 0x5e, + 0xcd, 0xc5, 0xa3, 0x8b, 0x4a, 0x31, 0x87, 0x01, 0x8c, 0x9b, 0x48, 0x4d, + 0x67, 0xc6, 0xfa, 0xc7, 0x48, 0xd5, 0xd2, 0xa4, 0x6d, 0x52, 0x99, 0x24, + 0xbe, 0xa8, 0x8d, 0xd7, 0x12, 0xe7, 0xff, 0x5c, 0xee, 0x2e, 0x69, 0xf7, + 0xc9, 0x7c, 0xff, 0x63, 0x0a, 0x1e, 0xc9, 0x93, 0x75, 0x22, 0x7c, 0xd7, + 0x1e, 0x80, 0x12, 0x4b, 0xbc, 0xdd, 0xa7, 0x7e, 0x8e, 0x28, 0xf3, 0xca, + 0x6c, 0xef, 0xbe, 0x77, 0x99, 0x28, 0x51, 0x93, 0x64, 0x90, 0x05, 0x45, + 0x97, 0x02, 0x9b, 0xb0, 0x4e, 0x00, 0x34, 0x73, 0xfc, 0x94, 0xe5, 0xa8, + 0xe0, 0x17, 0xb5, 0x0e, 0x5b, 0x2b, 0xec, 0xa7, 0x9d, 0x31, 0xdd, 0x87, + 0xc3, 0xc7, 0xea, 0x7a, 0xb6, 0xa7, 0xab, 0x7a, 0x64, 0xd3, 0x63, 0x79, + 0x72, 0x80, 0x1b, 0xde, 0x72, 0xcc, 0x87, 0xad, 0xcd, 0xe5, 0x66, 0x05, + 0xdc, 0x90, 0x86, 0xde, 0x9d, 0xdb, 0x7d, 0x85, 0x09, 0x36, 0x4a, 0x04, + 0xdc, 0xe7, 0x79, 0x76, 0xda, 0x79, 0xfa, 0xf2, 0xe7, 0xa2, 0xb7, 0x0b, + 0x8b, 0x7e, 0xbb, 0x5d, 0xda, 0x2c, 0xa6, 0xe4, 0x20, 0x3d, 0xe5, 0x24, + 0x2e, 0xaa, 0x01, 0x07, 0x8c, 0x69, 0xa8, 0x2f, 0x45, 0x53, 0x29, 0xd4, + 0x3a, 0x8a, 0x7b, 0xc8, 0x45, 0x07, 0xd0, 0xa2, 0x9b, 0x43, 0x9a, 0x69, + 0x73, 0x1b, 0xaa, 0x55, 0x8a, 0x80, 0x11, 0x28, 0x0b, 0x9b, 0x4c, 0x03, + 0x2f, 0x88, 0x9e, 0x38, 0x57, 0x83, 0x63, 0xdf, 0xca, 0xc2, 0x5d, 0x95, + 0xba, 0xbc, 0x82, 0x10, 0x05, 0x3e, 0x44, 0x00, 0x87, 0x2e, 0x7a, 0x29, + 0x71, 0xa1, 0xbb, 0x9b, 0xc9, 0xd8, 0x7d, 0xc7, 0xe5, 0x08, 0xbe, 0x52, + 0xca, 0xdc, 0xc8, 0xbf, 0x4b, 0xef, 0x89, 0x06, 0xd2, 0xa7, 0x2b, 0x14, + 0x24, 0xa8, 0xde, 0xc7, 0x6c, 0x8e, 0x15, 0x24, 0x2c, 0x27, 0x05, 0x80, + 0x0c, 0x4e, 0x6c, 0x1d, 0xed, 0xe7, 0x8f, 0x3c, 0x81, 0x0b, 0xc4, 0xb4, + 0x0a, 0x56, 0x4d, 0x34, 0x3a, 0x56, 0xfc, 0x87, 0xe3, 0xdd, 0x4c, 0xe6, + 0xc3, 0xf3, 0x0d, 0xb8, 0x90, 0xb2, 0x91, 0x5b, 0xef, 0x8e, 0x78, 0xa0, + 0x40, 0xfd, 0x31, 0x60, 0x0f, 0x3b, 0xd7, 0x28, 0x0f, 0x77, 0x97, 0x72, + 0x36, 0x96, 0x57, 0x92, 0xb7, 0xc6, 0x5d, 0xef, 0x99, 0xaf, 0x7f, 0x0f, + 0x2c, 0xbc, 0xfc, 0x29, 0xdb, 0x49, 0xa5, 0xb5, 0x5e, 0xd9, 0x9f, 0xf2, + 0x38, 0x8e, 0x39, 0xb2, 0x06, 0x3b, 0x9e, 0x66, 0x68, 0xe0, 0xd1, 0xa1, + 0x2c, 0x17, 0xb5, 0xbc, 0xb1, 0xb2, 0x37, 0xfd, 0x08, 0xfb, 0x71, 0xdb, + 0xf7, 0xe0, 0x5c, 0xb1, 0x01, 0x14, 0x01, 0x39, 0x2e, 0x59, 0x65, 0xf1, + 0x66, 0xff, 0x60, 0xb7, 0x67, 0xc7, 0xbd, 0xcc, 0x4a, 0x08, 0x80, 0x09, + 0xb6, 0x24, 0xb5, 0x42, 0x46, 0xb7, 0xce, 0x00, 0x09, 0xb6, 0x80, 0x2d, + 0x00, 0x75, 0xef, 0xaf, 0xa1, 0x86, 0x88, 0x73, 0xec, 0x4a, 0x14, 0x3a, + 0x84, 0x37, 0xd0, 0xfd, 0xb2, 0xf6, 0xee, 0x6c, 0x4a, 0x02, 0xad, 0x2b, + 0x14, 0x20, 0x73, 0x74, 0x94, 0x03, 0x46, 0xec, 0x0c, 0x6f, 0xd4, 0xdd, + 0x27, 0xda, 0x6b, 0x3e, 0x53, 0x35, 0xb0, 0xe0, 0x05, 0x36, 0xb5, 0xd2, + 0x93, 0xa5, 0x24, 0xb5, 0xc6, 0x51, 0xbb, 0x9d, 0x5b, 0x0e, 0x01, 0x89, + 0x09, 0x2d, 0x44, 0x86, 0x56, 0xa7, 0x0a, 0x67, 0x19, 0x37, 0xbc, 0x9a, + 0xd7, 0x4a, 0x5b, 0x62, 0x9f, 0x9c, 0x6d, 0x54, 0x3a, 0x56, 0x6c, 0xdb, + 0xe2, 0xf0, 0x08, 0x40, 0x13, 0x15, 0xab, 0x00, 0x9f, 0x61, 0x25, 0xb3, + 0x00, 0xe0, 0x9c, 0x84, 0xb6, 0xdc, 0xab, 0x76, 0x40, 0xa5, 0xcb, 0xb2, + 0x10, 0x9a, 0x20, 0x75, 0xb0, 0x94, 0xc1, 0xd6, 0xb7, 0xdb, 0x77, 0xe6, + 0x21, 0x2d, 0xbe, 0x20, 0x00, 0xaf, 0x8a, 0x00, 0x4d, 0x04, 0x7d, 0x39, + 0x9b, 0x0e, 0xaa, 0xf7, 0x3a, 0xf9, 0x58, 0x30, 0x3a, 0x6d, 0x54, 0x29, + 0xbe, 0x99, 0xf0, 0xf7, 0x7b, 0xb8, 0xde, 0x70, 0xa2, 0x8b, 0x2e, 0x85, + 0x37, 0x75, 0xcf, 0xa4, 0x0d, 0xd7, 0x4a, 0x19, 0x6c, 0x8b, 0x15, 0xb8, + 0xee, 0xa7, 0xb7, 0x20, 0x03, 0xe6, 0xc2, 0xd4, 0xe2, 0xd6, 0xff, 0x23, + 0x73, 0x2a, 0x9f, 0xe0, 0xb1, 0xbe, 0x90, 0x2b, 0x8d, 0xe7, 0xad, 0xdd, + 0xcd, 0xa0, 0x2a, 0xda, 0xb1, 0x02, 0x0a, 0xa7, 0x04, 0x2d, 0x6f, 0xa4, + 0x80, 0x21, 0xfb, 0x80, 0x58, 0x29, 0xce, 0xaf, 0xc8, 0x54, 0x36, 0xad, + 0x1a, 0xdb, 0x88, 0xbf, 0x5d, 0x12, 0x00, 0xf7, 0x67, 0x31, 0x3f, 0x59, + 0x32, 0x01, 0x03, 0x6b, 0x72, 0x89, 0x70, 0x05, 0xbc, 0xc4, 0xf5, 0x87, + 0xb6, 0x3c, 0xcf, 0x3d, 0x84, 0xb8, 0xdf, 0x24, 0x01, 0xcf, 0x1b, 0xf5, + 0xeb, 0x70, 0x8d, 0xe7, 0x40, 0x05, 0x35, 0x2c, 0xaf, 0x74, 0x3a, 0x24, + 0xb4, 0x7b, 0x79, 0x72, 0x2f, 0x00, 0x06, 0x9f, 0x51, 0x46, 0xe3, 0xa5, + 0x28, 0x39, 0x1d, 0x6b, 0xed, 0x52, 0xcf, 0x48, 0x5c, 0x6f, 0x42, 0x00, + 0xfa, 0x8a, 0xfe, 0x77, 0x66, 0x73, 0x65, 0x96, 0x13, 0x24, 0xab, 0x4b, + 0x1f, 0x03, 0x0f, 0x6f, 0x2a, 0x08, 0x00, 0x5b, 0xf5, 0xe3, 0x91, 0x35, + 0xfd, 0x7b, 0x29, 0xd2, 0xe5, 0xda, 0x04, 0x15, 0x9b, 0x2c, 0x0c, 0x28, + 0x63, 0x77, 0x5a, 0x95, 0x6b, 0x69, 0xb4, 0x38, 0xda, 0x4b, 0x6f, 0x18, + 0x03, 0x97, 0x67, 0xc8, 0x97, 0x71, 0xc7, 0xb2, 0x1c, 0x5c, 0x73, 0x89, + 0xa8, 0x34, 0xb6, 0xf9, 0x29, 0x1f, 0x8e, 0x40, 0x1d, 0x5f, 0xa3, 0xed, + 0xc3, 0xae, 0x5d, 0x9c, 0x3b, 0x26, 0xc8, 0x7c, 0x3c, 0xc2, 0xdb, 0xe8, + 0x40, 0x05, 0x9e, 0xfd, 0x88, 0xfe, 0x40, 0x0a, 0xf3, 0xe2, 0x55, 0xe2, + 0x93, 0xb8, 0xe2, 0x07, 0xbd, 0xf3, 0x4c, 0x45, 0xa1, 0x0d, 0xe7, 0x6f, + 0x45, 0x4e, 0x84, 0x6c, 0x15, 0xaf, 0x7e, 0x57, 0x64, 0x44, 0xd8, 0xf9, + 0xa5, 0x6e, 0x5f, 0x52, 0xdb, 0x93, 0x97, 0x5f, 0x28, 0x96, 0xc1, 0x95, + 0x62, 0x2b, 0x48, 0xb8, 0x1c, 0x55, 0x60, 0x00, 0x00, 0x01, 0x07, 0x43, + 0xf9, 0xef, 0xbc, 0xbd, 0xf1, 0x2e, 0xf8, 0x28, 0xda, 0x7b, 0x6b, 0xe9, + 0xf8, 0x44, 0xed, 0xfc, 0xf3, 0xe1, 0x2d, 0x92, 0x40, 0xa6, 0xf6, 0xa0, + 0x0f, 0xc5, 0x69, 0x17, 0xdb, 0x08, 0xe2, 0x62, 0x0d, 0x41, 0x5b, 0xd5, + 0x93, 0x9b, 0x03, 0xaf, 0xe7, 0x16, 0x20, 0x4b, 0x5c, 0x08, 0x1f, 0x9e, + 0x44, 0xe0, 0x01, 0x87, 0xff, 0xdf, 0xe2, 0x0a, 0xdb, 0x0a, 0xf3, 0xdb, + 0xc6, 0xba, 0xcd, 0x87, 0x00, 0x4f, 0xc0, 0x49, 0x54, 0xa0, 0xc6, 0xf2, + 0xec, 0xb9, 0x6b, 0x78, 0xef, 0x94, 0x3e, 0x56, 0xfe, 0x39, 0x92, 0x3b, + 0x12, 0x4f, 0x09, 0x1b, 0x66, 0x82, 0x17, 0xfc, 0xcd, 0x6c, 0xfc, 0xca, + 0x55, 0xb0, 0x25, 0xbd, 0x28, 0x98, 0x4f, 0x17, 0xb4, 0xb0, 0xa7, 0xbb, + 0x10, 0x30, 0xf5, 0xb2, 0xdf, 0x4a, 0xdc, 0x96, 0x1b, 0x91, 0xb0, 0xd8, + 0xb1, 0xbb, 0xc4, 0x69, 0x3f, 0xe7, 0x93, 0x00, 0x06, 0x90, 0xb4, 0x08, + 0x6f, 0x99, 0x4f, 0xd4, 0x21, 0x15, 0x00, 0xa8, 0xdf, 0x53, 0x13, 0x6b, + 0xf2, 0xcc, 0x50, 0x11, 0x66, 0x2a, 0x8d, 0x3e, 0xc0, 0x29, 0xbe, 0x64, + 0xf2, 0xab, 0xa9, 0x2a, 0xc6, 0xde, 0xc2, 0xca, 0x21, 0xab, 0x69, 0x43, + 0xeb, 0x7e, 0xc0, 0x52, 0x91, 0xf6, 0xe9, 0x9a, 0x03, 0xca, 0x61, 0x55, + 0xbd, 0x30, 0x9d, 0x04, 0x1f, 0xeb, 0x22, 0x0a, 0xa0, 0x15, 0x8e, 0x88, + 0x64, 0x35, 0x40, 0x21, 0x30, 0xb0, 0xb2, 0x9b, 0xc2, 0xcf, 0xc9, 0xab, + 0xe1, 0x36, 0xb7, 0xd3, 0xa3, 0x9e, 0x00, 0xff, 0xb7, 0xc3, 0xc3, 0x2c, + 0x77, 0x2e, 0x31, 0x22, 0x9c, 0x66, 0x9f, 0xe2, 0xb2, 0x36, 0xce, 0x2b, + 0x6c, 0x80, 0x03, 0x36, 0xb3, 0x9b, 0xbc, 0x8e, 0x47, 0xe9, 0xc0, 0x0f, + 0x40, 0x1a, 0x64, 0xf6, 0x75, 0xa1, 0xe7, 0xf0, 0x2e, 0x5e, 0xf3, 0x4e, + 0x54, 0xb1, 0x56, 0xa1, 0x47, 0x14, 0xad, 0xf1, 0xaf, 0xfb, 0xf8, 0x14, + 0x67, 0x13, 0x75, 0x28, 0x09, 0x40, 0x0f, 0xbc, 0xaf, 0x39, 0x07, 0x15, + 0x12, 0x4d, 0xa3, 0xcb, 0x18, 0xde, 0xfb, 0xe0, 0xc1, 0x5e, 0xd9, 0xd3, + 0xf6, 0x86, 0x43, 0x70, 0xf1, 0x84, 0xc2, 0x9b, 0xca, 0xce, 0x5e, 0x00, + 0xe8, 0x50, 0x8e, 0x44, 0xbf, 0x27, 0xea, 0x4a, 0x2f, 0xcf, 0xbc, 0x83, + 0x40, 0x71, 0xc6, 0xc8, 0x64, 0xa0, 0x2a, 0x88, 0x5b, 0x72, 0x24, 0xb8, + 0xe5, 0xf5, 0x91, 0xaa, 0x07, 0xc8, 0xdf, 0x8e, 0xe3, 0x2b, 0x85, 0xbe, + 0xdc, 0x1e, 0x92, 0x6c, 0x83, 0x42, 0x80, 0xb6, 0xe8, 0x80, 0x34, 0xf8, + 0x9d, 0xf2, 0xf5, 0xf3, 0x79, 0x6a, 0x6d, 0x2e, 0xad, 0x03, 0x9b, 0x97, + 0x92, 0x7b, 0x3b, 0xaf, 0x30, 0x08, 0x67, 0x7e, 0x7b, 0x02, 0xe1, 0xb2, + 0xd9, 0xe1, 0x1b, 0x36, 0x6c, 0xc9, 0x69, 0x41, 0x76, 0x92, 0x9b, 0xbe, + 0xd6, 0xde, 0xd4, 0x8d, 0xfb, 0x2e, 0x1c, 0x00, 0x6e, 0x2b, 0xcb, 0xac, + 0x41, 0xa9, 0xb1, 0xd6, 0xca, 0x36, 0xd2, 0xcf, 0x2d, 0x91, 0x2c, 0xd7, + 0xa9, 0x61, 0x13, 0x99, 0x7d, 0x43, 0x1b, 0x86, 0x46, 0x80, 0x16, 0xf7, + 0x75, 0x02, 0x2b, 0xf6, 0x44, 0x1f, 0x5b, 0xd4, 0x13, 0x45, 0x3e, 0xdc, + 0x09, 0xb8, 0xaa, 0x10, 0x74, 0x89, 0x59, 0xb7, 0x58, 0x04, 0xea, 0xda, + 0x77, 0x63, 0xf3, 0x26, 0xe8, 0x64, 0x27, 0xb9, 0xda, 0x50, 0xd3, 0xb6, + 0xc3, 0xe0, 0x50, 0xd6, 0xeb, 0x79, 0x80, 0x1d, 0x80, 0x59, 0x2d, 0x1a, + 0x51, 0x3e, 0x7c, 0x73, 0x74, 0x34, 0x3a, 0xba, 0xd4, 0xb0, 0x21, 0xb9, + 0x50, 0xcf, 0x7b, 0xb5, 0x7c, 0x33, 0x6e, 0x6c, 0x01, 0x10, 0xdb, 0x60, + 0x51, 0x8c, 0xee, 0xd2, 0x7c, 0xfb, 0x97, 0x00, 0x45, 0xe6, 0xe5, 0x38, + 0x08, 0x54, 0x0e, 0x2c, 0x09, 0x6b, 0x6d, 0x87, 0x36, 0xd4, 0xbb, 0x57, + 0xd6, 0x52, 0x9b, 0xaa, 0xe5, 0xe1, 0xc2, 0xf7, 0x02, 0xcc, 0xdd, 0x4b, + 0x02, 0xcc, 0x1a, 0xdc, 0xf1, 0x33, 0x78, 0xdc, 0xcc, 0x41, 0xcf, 0x8f, + 0xf2, 0xb0, 0xbf, 0x16, 0x5e, 0x26, 0x10, 0x66, 0x3f, 0x03, 0x0f, 0xb5, + 0x4b, 0x2a, 0x9e, 0x31, 0xa5, 0xba, 0x1b, 0x7e, 0xb1, 0x61, 0x9a, 0x16, + 0x08, 0x5f, 0xf0, 0xbb, 0x84, 0x34, 0x29, 0xb5, 0xd9, 0x05, 0xd7, 0x62, + 0x06, 0xa1, 0x3a, 0xe4, 0x21, 0x2e, 0x36, 0x7e, 0xd1, 0xdc, 0x73, 0xc7, + 0x3a, 0x80, 0x4d, 0xc5, 0x26, 0x69, 0xf4, 0xf3, 0xa5, 0x95, 0xb7, 0xe5, + 0xbb, 0xc5, 0x72, 0x51, 0xa5, 0xc4, 0xee, 0xb8, 0x02, 0x23, 0x1e, 0x70, + 0x5c, 0x66, 0xd0, 0xdf, 0x89, 0x16, 0x68, 0xaa, 0x21, 0x22, 0x84, 0x8a, + 0xb8, 0x6a, 0x8f, 0x0c, 0x6a, 0xce, 0xd3, 0x0f, 0x1a, 0xb2, 0x2d, 0x6f, + 0x4e, 0x2b, 0x34, 0x01, 0xe0, 0xb8, 0xe7, 0xb8, 0x22, 0xed, 0x76, 0xc2, + 0xd4, 0x72, 0xcb, 0x03, 0x1b, 0xc5, 0x7c, 0x75, 0xce, 0xf4, 0x7e, 0xd0, + 0xa2, 0xca, 0xa5, 0xc2, 0xa8, 0xe8, 0xca, 0xb7, 0x9b, 0x43, 0xae, 0x12, + 0x1b, 0xfa, 0xe7, 0xfb, 0xb0, 0x41, 0xfc, 0xf2, 0x38, 0x03, 0xec, 0xe3, + 0x6c, 0x1d, 0x2b, 0xf8, 0xaf, 0x2d, 0x42, 0x30, 0x94, 0xdf, 0xb3, 0x9d, + 0xaa, 0xaa, 0xdf, 0xcf, 0x3d, 0x9b, 0xdb, 0xec, 0x8a, 0x02, 0x2d, 0x38, + 0x7b, 0x7e, 0xb4, 0x00, 0x6d, 0x01, 0x07, 0xf6, 0x3f, 0x84, 0x77, 0xe0, + 0x25, 0x00, 0x25, 0xec, 0xd9, 0x00, 0x47, 0x06, 0xb5, 0x40, 0xf6, 0xa8, + 0x1e, 0xdf, 0xd9, 0x78, 0x03, 0x2d, 0xa1, 0xc5, 0x56, 0xe4, 0xe0, 0x19, + 0xc4, 0x66, 0xe0, 0x0c, 0x5a, 0xdb, 0xb6, 0xed, 0xea, 0xe2, 0x99, 0x1b, + 0x99, 0xc7, 0xe1, 0xb9, 0x62, 0x2c, 0x96, 0x49, 0xb6, 0x0d, 0x8b, 0x1b, + 0x8f, 0xf6, 0xd0, 0x03, 0xcf, 0x77, 0xe4, 0x99, 0x4f, 0x9b, 0x2c, 0x59, + 0xb2, 0xc0, 0xa6, 0x50, 0xaa, 0xd1, 0x2a, 0x37, 0xeb, 0x05, 0x02, 0x17, + 0xfb, 0xa6, 0xcf, 0x41, 0xad, 0xea, 0x25, 0x36, 0x54, 0x6f, 0xce, 0xdf, + 0xcf, 0x69, 0xae, 0x14, 0xe5, 0xc5, 0x39, 0xe2, 0xe0, 0xb7, 0x38, 0xd2, + 0xbf, 0x15, 0x2c, 0xda, 0x75, 0xb0, 0x69, 0x71, 0xbe, 0xde, 0x20, 0x10, + 0x80, 0x2f, 0xdd, 0xf3, 0xd6, 0x22, 0xb6, 0x3c, 0x5f, 0x37, 0x16, 0x42, + 0x65, 0x29, 0xb8, 0x5b, 0x78, 0x09, 0x97, 0xa0, 0x4d, 0x00, 0x34, 0x6d, + 0xbd, 0xc4, 0x14, 0x2f, 0x41, 0x30, 0x01, 0x26, 0x94, 0xde, 0x2c, 0x8d, + 0xd0, 0x05, 0x62, 0x3d, 0x95, 0xda, 0x1b, 0x39, 0xe3, 0x69, 0x70, 0xe3, + 0x8b, 0x29, 0xbd, 0x58, 0x80, 0x0a, 0x75, 0xcf, 0x2c, 0x26, 0x6b, 0x96, + 0x90, 0x95, 0xa7, 0x8d, 0x97, 0x87, 0xca, 0x00, 0x34, 0x2f, 0xd1, 0x2b, + 0x10, 0x99, 0x54, 0x84, 0xdf, 0x3c, 0x01, 0xb8, 0x9c, 0xf2, 0xae, 0x97, + 0x1d, 0x16, 0xd7, 0xcc, 0x40, 0x1c, 0xc5, 0xba, 0x70, 0xf6, 0xf3, 0x7c, + 0x7f, 0x2d, 0xf9, 0xf8, 0x13, 0x7d, 0xa5, 0x01, 0xe3, 0xf1, 0xe8, 0x56, + 0x54, 0x45, 0x5c, 0x2d, 0x1a, 0xcf, 0x8d, 0x22, 0x00, 0x3a, 0xfb, 0xe5, + 0x15, 0xd8, 0xbc, 0x2a, 0xcb, 0xaf, 0x4b, 0x32, 0xf0, 0xf8, 0x6c, 0x83, + 0x4e, 0x1a, 0xde, 0x4c, 0x10, 0x00, 0xb0, 0x48, 0x01, 0xb0, 0x05, 0xb7, + 0xdf, 0x38, 0xd8, 0xb5, 0x09, 0xd8, 0x4d, 0xba, 0x93, 0x15, 0x5b, 0xe7, + 0xf3, 0xd9, 0xfc, 0x98, 0x6d, 0x90, 0x71, 0xc3, 0x4e, 0x18, 0x1a, 0x48, + 0x6c, 0x77, 0x2d, 0x8a, 0xad, 0xfb, 0x80, 0x07, 0x4b, 0xc7, 0x66, 0xf0, + 0xfc, 0x0c, 0xb3, 0x1e, 0x51, 0x44, 0x8a, 0xde, 0x64, 0x00, 0xb3, 0xdf, + 0x8f, 0x61, 0x78, 0x6f, 0x1d, 0xe4, 0x2d, 0x2c, 0xd8, 0x53, 0xcc, 0x0e, + 0xb5, 0xbe, 0x32, 0xff, 0x69, 0x40, 0x1e, 0x57, 0x3b, 0x1d, 0x4a, 0xbb, + 0x26, 0xe3, 0xcf, 0xee, 0x87, 0xe2, 0x4a, 0x74, 0x30, 0xe4, 0x6e, 0x50, + 0x00, 0x9f, 0x8c, 0x7a, 0x0a, 0xe9, 0xc3, 0x00, 0x2d, 0x7c, 0xc9, 0x6d, + 0xfc, 0x5b, 0x2d, 0x92, 0x51, 0xaa, 0x53, 0x7d, 0x01, 0x93, 0x55, 0x20, + 0x1b, 0x6e, 0xae, 0x64, 0xa4, 0xc8, 0xdf, 0xa6, 0xe0, 0x8b, 0xf6, 0x23, + 0x7d, 0x3d, 0xba, 0xf6, 0x78, 0xbf, 0x25, 0xf2, 0xdd, 0xa8, 0xbb, 0xa3, + 0x64, 0x5a, 0x52, 0xa4, 0x29, 0xa8, 0xfb, 0x00, 0x3b, 0x7e, 0x76, 0x41, + 0xef, 0xd9, 0xcf, 0x92, 0xcf, 0x37, 0x87, 0x2f, 0x94, 0x87, 0x59, 0x14, + 0x62, 0xb7, 0x91, 0x82, 0x7e, 0xae, 0xc3, 0x7e, 0x66, 0x4c, 0x2f, 0x05, + 0x3a, 0x19, 0x34, 0xad, 0xa6, 0x94, 0x70, 0xc6, 0xf5, 0x60, 0x09, 0x67, + 0x42, 0xdf, 0xb1, 0xdf, 0x3a, 0xa1, 0xd4, 0x6d, 0x44, 0x90, 0xba, 0x3c, + 0x73, 0x59, 0x6d, 0xd0, 0x13, 0x5b, 0xec, 0xfb, 0x08, 0xe9, 0xd9, 0xdd, + 0x10, 0x00, 0xf4, 0x5e, 0x5b, 0x2e, 0x3f, 0x45, 0xc0, 0x45, 0x00, 0x6d, + 0xb4, 0xd2, 0x6a, 0x9e, 0x50, 0xf6, 0xf2, 0x1f, 0x40, 0x07, 0xe2, 0xfa, + 0x4c, 0x00, 0x3e, 0x14, 0xe9, 0x25, 0x9e, 0xce, 0xc2, 0x91, 0xd0, 0x37, + 0xd6, 0x8f, 0x6e, 0x6f, 0xf5, 0xf9, 0xcf, 0x0e, 0xf3, 0x88, 0x04, 0x3b, + 0x9c, 0xd2, 0x61, 0xb1, 0x52, 0x98, 0xa5, 0x29, 0xfe, 0x8d, 0xb8, 0x00, + 0x4e, 0xe7, 0x0b, 0xda, 0x65, 0x45, 0xb8, 0x1d, 0x0d, 0x54, 0x55, 0x21, + 0x2b, 0x38, 0xc3, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, 0xf3, 0xc0, 0x0f, + 0xbd, 0x85, 0x00, 0x3b, 0xfb, 0x8a, 0xeb, 0x9e, 0x5c, 0x74, 0x97, 0xca, + 0x4d, 0xd3, 0x21, 0x32, 0x45, 0x52, 0xbd, 0x20, 0xe6, 0xfb, 0x10, 0x20, + 0x01, 0x6b, 0xaf, 0xd7, 0xa9, 0xcf, 0xd1, 0xd7, 0x6f, 0xee, 0x72, 0x65, + 0xdc, 0x86, 0x87, 0x4a, 0xa5, 0x15, 0xe2, 0xdf, 0x0a, 0x7d, 0xf3, 0xb2, + 0x44, 0x1c, 0x51, 0x48, 0xde, 0x82, 0x6d, 0x7c, 0x6e, 0x51, 0xf5, 0xbc, + 0xa2, 0xa5, 0x2d, 0xbe, 0x71, 0x1e, 0xdf, 0x61, 0x7d, 0x2a, 0xc3, 0xe6, + 0xaf, 0x56, 0x13, 0xd6, 0x1d, 0xf9, 0x88, 0x77, 0x8c, 0x6d, 0x54, 0x0c, + 0x20, 0x26, 0xff, 0xdd, 0x80, 0x02, 0xd2, 0x43, 0x6a, 0xd5, 0x73, 0xb5, + 0xef, 0x50, 0xa9, 0x13, 0x50, 0x23, 0x56, 0x95, 0x42, 0x47, 0x35, 0xdf, + 0x34, 0x50, 0x03, 0x7f, 0xb7, 0xd8, 0x4b, 0x9e, 0xa3, 0x2a, 0x89, 0xc0, + 0xba, 0x55, 0xbb, 0x4a, 0x0b, 0x2d, 0xb9, 0x6d, 0x5b, 0x2b, 0x03, 0x29, + 0x24, 0x0e, 0x6f, 0xd2, 0x80, 0x3b, 0x50, 0x05, 0x7f, 0xcf, 0x8d, 0xc3, + 0x87, 0x76, 0xfd, 0x93, 0x89, 0x60, 0x23, 0xff, 0xed, 0xfd, 0x46, 0xf8, + 0x80, 0xb3, 0x40, 0x1e, 0x09, 0xf8, 0xb4, 0x2e, 0x68, 0x8d, 0x14, 0xfb, + 0x01, 0x28, 0x01, 0x75, 0xc4, 0x86, 0xfd, 0xa9, 0xbd, 0xf9, 0x80, 0x3b, + 0xef, 0x9b, 0x68, 0xeb, 0x7b, 0x73, 0xf7, 0x38, 0x48, 0x5a, 0x07, 0x5b, + 0x0e, 0x38, 0x75, 0x6f, 0xca, 0x42, 0xaf, 0x3f, 0xce, 0xbf, 0xef, 0xb6, + 0x86, 0x71, 0x2d, 0x11, 0xed, 0x31, 0xc3, 0x49, 0xae, 0xe1, 0x57, 0x42, + 0x54, 0x63, 0x68, 0x4c, 0x90, 0x0b, 0x62, 0xd2, 0xdb, 0xf1, 0x6e, 0xa4, + 0xfb, 0x25, 0x8d, 0xf7, 0xd7, 0x72, 0xf7, 0x38, 0x01, 0xef, 0x74, 0x5b, + 0xb0, 0x65, 0xe0, 0x57, 0xcf, 0x7d, 0xee, 0x45, 0x3c, 0x08, 0x40, 0x08, + 0x13, 0x1b, 0xe4, 0xc0, 0x0f, 0xd4, 0x01, 0x18, 0x03, 0xef, 0xa7, 0x28, + 0x17, 0x5f, 0x6f, 0x19, 0x07, 0x1f, 0x29, 0x70, 0x2a, 0xa3, 0x7e, 0x94, + 0x00, 0x5b, 0x98, 0x23, 0x9e, 0x70, 0x50, 0x9e, 0x60, 0xc0, 0xfe, 0x37, + 0x62, 0x43, 0xec, 0x2c, 0x30, 0x2d, 0xbc, 0x1e, 0x85, 0x51, 0x06, 0x3f, + 0x98, 0xa1, 0x97, 0xf4, 0xad, 0x89, 0x86, 0x1f, 0xea, 0x31, 0xbf, 0xcf, + 0x40, 0x0f, 0xe6, 0x70, 0xfd, 0xb2, 0x51, 0xf4, 0xdb, 0x64, 0x8d, 0xc9, + 0xf7, 0xec, 0x00, 0xf1, 0xd6, 0xed, 0x81, 0xb1, 0x68, 0xc8, 0xdd, 0xe1, + 0x58, 0x00, 0x65, 0xe6, 0xf2, 0xf2, 0x9e, 0x4c, 0x96, 0xac, 0xf0, 0x6f, + 0x9f, 0x09, 0x9d, 0x09, 0xf8, 0x5a, 0x90, 0x25, 0xda, 0x1d, 0x29, 0xf0, + 0x6b, 0x75, 0x82, 0x1f, 0xfd, 0x4d, 0x84, 0x2a, 0xc2, 0x1a, 0xad, 0xe1, + 0xf9, 0x2f, 0xb8, 0xf4, 0x0a, 0xd7, 0x64, 0x56, 0x5e, 0x6d, 0xcc, 0x7f, + 0x25, 0x86, 0xcb, 0x76, 0x44, 0x90, 0x2a, 0x01, 0xed, 0xde, 0x7e, 0xa0, + 0xb7, 0xdf, 0x4a, 0x38, 0x29, 0x98, 0x4d, 0x37, 0xad, 0x76, 0xcf, 0x16, + 0xeb, 0x90, 0xb2, 0x9b, 0x5c, 0x1a, 0xdf, 0x8e, 0xe5, 0x5c, 0x6d, 0xa8, + 0x14, 0xb2, 0x7a, 0xd2, 0xdb, 0xd6, 0xc7, 0xcf, 0x9a, 0x92, 0xd0, 0xbd, + 0x76, 0xec, 0xd0, 0xa8, 0xb5, 0x4a, 0x0c, 0xaa, 0xd8, 0xbb, 0x80, 0x16, + 0x53, 0x37, 0x65, 0x0b, 0xa3, 0x42, 0xda, 0x02, 0x1f, 0xfd, 0x66, 0x3e, + 0x50, 0xab, 0x72, 0x12, 0x49, 0x05, 0xb6, 0xf9, 0xf9, 0x8d, 0xd7, 0x00, + 0x29, 0x6f, 0x4c, 0xd2, 0x78, 0xb1, 0x49, 0x02, 0x56, 0xbf, 0x0a, 0xb0, + 0x24, 0x63, 0x59, 0xde, 0xcf, 0x2b, 0x2b, 0xd4, 0x00, 0x53, 0x04, 0x41, + 0x4e, 0xb6, 0x82, 0x3f, 0xfe, 0x64, 0xa0, 0x51, 0xed, 0x97, 0x6d, 0xcd, + 0xdd, 0x93, 0x46, 0x95, 0x9c, 0x19, 0x36, 0x8d, 0xa5, 0x9a, 0x51, 0x61, + 0x2d, 0xd8, 0xee, 0x00, 0x1e, 0xbb, 0xaa, 0xf7, 0x0f, 0xae, 0x97, 0x33, + 0x5e, 0xf0, 0xc3, 0xd6, 0x15, 0x09, 0x2d, 0xd0, 0xdd, 0xc3, 0x9b, 0xaf, + 0xac, 0xa4, 0x5c, 0xba, 0x96, 0x45, 0x59, 0xba, 0x31, 0xba, 0x1c, 0xbe, + 0x6f, 0x9e, 0xdc, 0x00, 0x85, 0xdb, 0x0d, 0x42, 0x8e, 0x09, 0x6a, 0x74, + 0x9f, 0xf2, 0xfc, 0xe5, 0xd6, 0x86, 0xa7, 0x46, 0x50, 0xf0, 0x11, 0x9e, + 0x5b, 0x0a, 0xaf, 0xfb, 0xf5, 0x24, 0x09, 0x8f, 0xb2, 0x10, 0xe8, 0xca, + 0xd0, 0xda, 0x9e, 0xd8, 0xc4, 0xf9, 0xef, 0xa4, 0x08, 0x5d, 0x29, 0x14, + 0x2a, 0x36, 0xfb, 0x40, 0x2b, 0x17, 0xc7, 0x21, 0xe1, 0x16, 0x64, 0x73, + 0xe0, 0x5e, 0xfe, 0xa0, 0x59, 0x4d, 0x57, 0x69, 0xf6, 0x13, 0x9c, 0x72, + 0x81, 0x69, 0x13, 0x40, 0xea, 0xd4, 0x67, 0x37, 0xdb, 0x1e, 0xed, 0xd0, + 0x4a, 0xff, 0x9c, 0xca, 0x58, 0x40, 0xef, 0x05, 0x6b, 0x64, 0xde, 0x8a, + 0xbc, 0xc7, 0xd9, 0x14, 0x08, 0xdb, 0x9e, 0xf2, 0x4a, 0x30, 0x07, 0x33, + 0x88, 0x96, 0x85, 0x37, 0x87, 0xc8, 0x68, 0x8f, 0x6c, 0x7e, 0x84, 0xdb, + 0x68, 0x7a, 0x04, 0x23, 0x7d, 0x02, 0x82, 0x10, 0x03, 0x89, 0xf6, 0xc9, + 0x94, 0x12, 0x3f, 0xf7, 0x1d, 0x39, 0x77, 0x8e, 0x19, 0xb2, 0x90, 0xdb, + 0xe6, 0x8f, 0x90, 0x57, 0xd7, 0xae, 0x65, 0x0a, 0xc1, 0x56, 0x1a, 0xa7, + 0x9f, 0x06, 0xc0, 0xb6, 0x88, 0x53, 0x71, 0xd0, 0x30, 0x53, 0x7e, 0xe9, + 0xe9, 0xd1, 0x1c, 0x5e, 0x3b, 0xc7, 0x83, 0x16, 0xdf, 0x46, 0xf7, 0x9f, + 0xc8, 0x08, 0x3f, 0x95, 0xcf, 0xf8, 0x4a, 0x50, 0x49, 0xff, 0xde, 0x2c, + 0x80, 0x96, 0x00, 0x65, 0x12, 0x5b, 0xe0, 0x62, 0xac, 0x77, 0x9e, 0xdc, + 0x83, 0x12, 0x4a, 0x54, 0xf0, 0x6f, 0xb7, 0x7b, 0xc0, 0x41, 0xfc, 0x40, + 0x01, 0x16, 0x20, 0x04, 0x37, 0x99, 0x28, 0x59, 0x8b, 0x69, 0x29, 0xad, + 0x4e, 0x24, 0xb6, 0x14, 0xba, 0xdf, 0xec, 0x25, 0x41, 0xbe, 0x8a, 0xde, + 0x30, 0x01, 0xf3, 0xc1, 0x04, 0x06, 0x40, 0x1f, 0xfc, 0x8a, 0x77, 0x8d, + 0xe1, 0xf5, 0x60, 0x08, 0xaa, 0x07, 0xc0, 0xa6, 0xf5, 0x90, 0xaa, 0x00, + 0x2e, 0x6f, 0xcb, 0xe0, 0x0f, 0x90, 0x10, 0x00, 0xeb, 0x8e, 0x3e, 0xba, + 0x09, 0x7f, 0xf7, 0x49, 0xce, 0xa3, 0x0e, 0xb4, 0x9b, 0xe3, 0x0e, 0x6d, + 0x4e, 0xad, 0xbc, 0x29, 0x5b, 0xf0, 0x00, 0x0c, 0x3d, 0xba, 0x7f, 0xdb, + 0x8c, 0xf8, 0xce, 0x20, 0xfd, 0xe7, 0x7c, 0xa6, 0x2d, 0x0d, 0x39, 0xac, + 0xff, 0x0a, 0xe1, 0xfd, 0x57, 0xd7, 0xe4, 0x91, 0x77, 0x5f, 0xb9, 0x61, + 0xb6, 0xda, 0x87, 0xa0, 0xe0, 0x96, 0xe0, 0x89, 0xf2, 0xe4, 0xd8, 0xb5, + 0x00, 0x95, 0x1c, 0xad, 0xab, 0xce, 0x80, 0x3b, 0x00, 0x32, 0xc1, 0x5b, + 0x2c, 0x04, 0x6f, 0xfa, 0x7f, 0x91, 0x98, 0x34, 0x9a, 0x6d, 0x89, 0x02, + 0xdb, 0xcf, 0x44, 0x76, 0xda, 0x42, 0x46, 0xe5, 0xb0, 0x39, 0x5b, 0xfd, + 0x1f, 0xf7, 0xea, 0x82, 0x07, 0xe7, 0xf1, 0x08, 0x9e, 0xd7, 0x06, 0x79, + 0x79, 0xce, 0x57, 0xbc, 0x1c, 0x1d, 0x83, 0x2d, 0x6e, 0xf8, 0x03, 0x2e, + 0x78, 0x00, 0x4d, 0xce, 0x6f, 0x9d, 0x0c, 0x80, 0x3d, 0x0b, 0x0c, 0x87, + 0xb7, 0x8d, 0x04, 0x00, 0x2a, 0x73, 0xc0, 0x1b, 0x39, 0xef, 0xf9, 0x17, + 0x69, 0x6b, 0x99, 0xca, 0xd3, 0x62, 0xd3, 0x6c, 0x50, 0x96, 0xf9, 0xd8, + 0xae, 0x35, 0xdf, 0x13, 0x20, 0x8b, 0x85, 0xa6, 0x4c, 0x45, 0x8b, 0x36, + 0xae, 0x97, 0x7c, 0x5b, 0x67, 0xd8, 0x6b, 0xf7, 0x69, 0x08, 0xa6, 0xea, + 0xe4, 0xbb, 0xb6, 0xd0, 0x29, 0xbf, 0xa5, 0x80, 0x17, 0x7d, 0x4d, 0xf7, + 0xbb, 0xf3, 0xc3, 0xb9, 0x8a, 0x86, 0xa0, 0xc9, 0x85, 0x17, 0x10, 0xf3, + 0xc3, 0x15, 0xbc, 0x68, 0x03, 0x22, 0x37, 0x5d, 0x7b, 0x0a, 0x70, 0x05, + 0xbe, 0xd6, 0x93, 0x79, 0x78, 0xdd, 0x32, 0x40, 0xf1, 0xc5, 0x2b, 0x64, + 0x00, 0x71, 0xf6, 0xe6, 0x7b, 0xc5, 0x78, 0x9d, 0xb0, 0x9b, 0x77, 0x6a, + 0xdd, 0x58, 0x92, 0x14, 0x10, 0x34, 0xb6, 0xe6, 0x00, 0x36, 0x23, 0x70, + 0x66, 0x2d, 0xef, 0x6f, 0xed, 0xdc, 0x21, 0xd9, 0x0f, 0xa5, 0x86, 0xb2, + 0x7e, 0xd7, 0xf3, 0xbb, 0xb7, 0xc5, 0xb7, 0x7d, 0x37, 0x6d, 0xad, 0xf5, + 0xba, 0x00, 0x39, 0xde, 0x65, 0xdd, 0xe7, 0x30, 0x10, 0xc0, 0x18, 0x50, + 0xa7, 0x18, 0x92, 0xe6, 0xed, 0x1a, 0xef, 0xd5, 0x8d, 0x90, 0x01, 0xe7, + 0x64, 0x77, 0x89, 0xc5, 0xf6, 0x32, 0xd0, 0xff, 0x67, 0x47, 0x48, 0x90, + 0x83, 0x4d, 0xd8, 0x4b, 0xad, 0xe6, 0xc5, 0x3a, 0x74, 0x22, 0x4e, 0x84, + 0x70, 0x34, 0xd9, 0xc6, 0x7e, 0xf6, 0xd3, 0x82, 0x9a, 0xe7, 0xed, 0x79, + 0x8f, 0x5e, 0x72, 0xa2, 0xb8, 0xcd, 0x28, 0x98, 0x1c, 0x3a, 0x94, 0x06, + 0xdb, 0x48, 0xda, 0xd6, 0xfb, 0xa4, 0x4e, 0x05, 0x70, 0x46, 0xda, 0xef, + 0x7a, 0xfc, 0x53, 0x04, 0xf2, 0xf9, 0x0e, 0x98, 0x52, 0x87, 0xc8, 0x3e, + 0xd6, 0x6f, 0x60, 0x07, 0xa4, 0x71, 0x3d, 0xe6, 0xbf, 0x8c, 0x53, 0x03, + 0xac, 0xb1, 0x46, 0x14, 0x54, 0x1d, 0x06, 0xb7, 0x20, 0x00, 0xf7, 0xa7, + 0x77, 0xb1, 0xd3, 0x99, 0x8a, 0x82, 0xf4, 0x80, 0xbe, 0x72, 0xca, 0x38, + 0xa3, 0xe1, 0xde, 0xad, 0x97, 0xd9, 0xe2, 0xfd, 0xf9, 0x90, 0xc9, 0x46, + 0xa9, 0xb5, 0x10, 0xc8, 0x04, 0x1e, 0xa3, 0x98, 0xf1, 0x66, 0xdf, 0xa3, + 0x00, 0x58, 0xef, 0x97, 0x59, 0xcf, 0xd7, 0xdd, 0xfb, 0x4e, 0x99, 0x6a, + 0x80, 0xe3, 0x0f, 0x38, 0x61, 0x4d, 0xc0, 0xae, 0xeb, 0x32, 0xb8, 0x43, + 0xa1, 0x45, 0x16, 0x91, 0x0b, 0x0a, 0x6c, 0xde, 0xcb, 0x4c, 0x20, 0x4c, + 0x39, 0x74, 0xa8, 0x56, 0x8e, 0xf0, 0x02, 0xdb, 0xa7, 0xf1, 0x9c, 0xc7, + 0x50, 0x0b, 0x7b, 0xda, 0x74, 0x2e, 0xa2, 0xc7, 0x43, 0xd9, 0xc6, 0x6d, + 0xf9, 0xf3, 0x74, 0xcc, 0x36, 0x62, 0x8d, 0xa6, 0x1e, 0x8a, 0x58, 0x6b, + 0x27, 0x79, 0x5f, 0x83, 0x69, 0xe1, 0x65, 0x56, 0xee, 0x7c, 0xba, 0x8b, + 0xd9, 0x72, 0x00, 0x45, 0x98, 0x61, 0x67, 0x31, 0x7d, 0xe0, 0x57, 0xbd, + 0x58, 0x13, 0xb0, 0xeb, 0x3d, 0x51, 0x15, 0x86, 0x55, 0x80, 0x00, 0x00, + 0x01, 0x09, 0x43, 0xf1, 0xf9, 0x49, 0xf9, 0x85, 0x04, 0xad, 0x6e, 0xaf, + 0x32, 0x6e, 0x16, 0xdf, 0x2a, 0x77, 0x52, 0x11, 0xf8, 0xb7, 0x60, 0xe5, + 0x32, 0xc8, 0x58, 0xc2, 0xca, 0x4a, 0xa1, 0x2d, 0xf6, 0xba, 0x47, 0x22, + 0x00, 0x2d, 0x00, 0x7d, 0xbb, 0xbc, 0xdd, 0x4b, 0x49, 0xdd, 0x88, 0xe6, + 0x07, 0x2e, 0x07, 0xc3, 0xa5, 0x1a, 0x8d, 0xe5, 0xb8, 0xa6, 0xf3, 0x55, + 0x5b, 0xc0, 0xf7, 0x49, 0xde, 0xf0, 0x42, 0x36, 0x4b, 0xe0, 0xb6, 0x2b, + 0x6f, 0x73, 0xf4, 0x51, 0x1c, 0x01, 0xe7, 0xdb, 0x9a, 0x13, 0x7b, 0xf9, + 0x15, 0x1c, 0x4f, 0x04, 0x80, 0x03, 0xdd, 0x2f, 0x8a, 0x15, 0x0e, 0xa7, + 0xb7, 0xa8, 0x16, 0x45, 0xf6, 0xfa, 0x11, 0x4d, 0xf8, 0x82, 0xcc, 0x36, + 0xe6, 0xbf, 0x2f, 0x95, 0x55, 0x86, 0x7e, 0xad, 0x3d, 0x4b, 0x90, 0x21, + 0xba, 0x22, 0x7b, 0xa0, 0x0f, 0xbe, 0x9f, 0x77, 0x73, 0xc5, 0x8f, 0x7f, + 0x2f, 0x7d, 0x9b, 0x1f, 0xb1, 0xfa, 0xfd, 0x44, 0x43, 0xca, 0x8e, 0x0b, + 0x56, 0xe7, 0x75, 0xf2, 0xa3, 0x02, 0xab, 0x2d, 0x44, 0x6f, 0xd8, 0x73, + 0xae, 0x23, 0x7f, 0x04, 0xee, 0x3e, 0x00, 0x0a, 0x5d, 0xcf, 0x4b, 0x38, + 0xc9, 0x03, 0xc0, 0x4b, 0x0a, 0x43, 0x0a, 0xad, 0xf0, 0x40, 0x03, 0xb8, + 0xe7, 0xf9, 0xfb, 0x58, 0x7a, 0x6d, 0xd9, 0x9b, 0x57, 0x07, 0x15, 0x8a, + 0x6d, 0x0a, 0x46, 0xfd, 0x0f, 0xf4, 0x16, 0x00, 0x6b, 0xc7, 0xff, 0xb1, + 0x51, 0xf2, 0x9f, 0x78, 0xcd, 0x00, 0xb7, 0x6e, 0x53, 0xa9, 0x34, 0x3e, + 0x9b, 0x0e, 0x1b, 0x1b, 0xf2, 0x63, 0xe4, 0x11, 0x82, 0xa4, 0x80, 0x94, + 0x00, 0x66, 0x52, 0x51, 0x25, 0x9e, 0x16, 0xab, 0x3d, 0x23, 0x48, 0x0e, + 0x35, 0xbf, 0xae, 0x08, 0xfa, 0xb8, 0x10, 0x3f, 0x2c, 0x4e, 0x8b, 0xe3, + 0xbb, 0x40, 0x8e, 0x3e, 0x38, 0xeb, 0x88, 0xf9, 0xb0, 0xf0, 0xf7, 0xed, + 0xab, 0x14, 0x32, 0x14, 0xdf, 0x50, 0xf9, 0xf8, 0xc0, 0x02, 0x8e, 0x1c, + 0xe8, 0xb0, 0x11, 0xff, 0xee, 0xdb, 0x69, 0x60, 0x3c, 0x58, 0x52, 0x12, + 0x5b, 0xf2, 0xfe, 0x80, 0x53, 0x5b, 0xf4, 0x38, 0x03, 0xc7, 0xc0, 0x04, + 0xff, 0xe1, 0x7f, 0xdf, 0xb4, 0xc8, 0x08, 0xc0, 0x0a, 0xb4, 0x0c, 0xa6, + 0x07, 0x50, 0x1c, 0xd1, 0x88, 0x58, 0xd1, 0xb5, 0xb9, 0x75, 0x1d, 0xd3, + 0xf5, 0x7c, 0x21, 0x49, 0x4e, 0x1f, 0x5b, 0x38, 0x5b, 0xae, 0xcf, 0x04, + 0x3d, 0xbf, 0xce, 0x9f, 0x71, 0x0f, 0x00, 0x2e, 0xfb, 0xbb, 0x1d, 0x65, + 0x01, 0xe6, 0xbc, 0x46, 0xbb, 0x60, 0xca, 0x58, 0x45, 0x25, 0xb7, 0xce, + 0x3a, 0xe8, 0x02, 0xbe, 0xdc, 0x4f, 0x2c, 0x62, 0xc3, 0x15, 0xbf, 0x5c, + 0x00, 0x30, 0x17, 0xa0, 0x80, 0x05, 0x59, 0xef, 0xff, 0x16, 0x22, 0x4f, + 0xd7, 0x5c, 0x3d, 0xc8, 0x66, 0xd4, 0x27, 0x9d, 0x4d, 0x8b, 0x50, 0x68, + 0xd6, 0xfc, 0xd0, 0xfa, 0xf1, 0x7f, 0x24, 0x67, 0x71, 0x21, 0xd9, 0x5e, + 0x4f, 0xec, 0xc9, 0x93, 0x21, 0x74, 0x3c, 0x74, 0x6e, 0x82, 0x6f, 0x3b, + 0xa8, 0x43, 0xad, 0xa2, 0x96, 0xb5, 0xbc, 0x8f, 0xeb, 0x1c, 0x22, 0x47, + 0x64, 0xf5, 0x3e, 0xda, 0xa3, 0x4b, 0x6b, 0x08, 0xce, 0x00, 0x33, 0xf7, + 0x9b, 0x25, 0x0c, 0xaf, 0x32, 0x19, 0x46, 0xb7, 0xa7, 0x42, 0x01, 0xaf, + 0x7c, 0xb8, 0x03, 0xde, 0x79, 0x93, 0x80, 0xa2, 0xb2, 0x0c, 0x81, 0xa5, + 0xd6, 0xc1, 0xf7, 0x37, 0x0a, 0x44, 0x3d, 0x4a, 0x87, 0x86, 0x00, 0xd5, + 0x96, 0x4b, 0xae, 0x46, 0x4a, 0x52, 0xb7, 0xd0, 0xec, 0x5e, 0x11, 0xb8, + 0x7e, 0xbf, 0xac, 0x2c, 0xad, 0xe7, 0x1f, 0x93, 0x8b, 0x76, 0xa3, 0x8f, + 0x8a, 0x51, 0x94, 0xb4, 0x2b, 0x0f, 0x8d, 0xc0, 0xe6, 0x68, 0x19, 0xca, + 0x9e, 0x25, 0x29, 0x29, 0xb0, 0xf1, 0x28, 0xa1, 0x6e, 0xb7, 0x72, 0x06, + 0x45, 0x58, 0x9e, 0x10, 0x68, 0x4b, 0x52, 0x46, 0xcc, 0x7b, 0xb6, 0xe2, + 0x50, 0xab, 0x0a, 0x02, 0xeb, 0x5d, 0x87, 0x2d, 0xf5, 0x6d, 0xcf, 0xa0, + 0x5b, 0x7d, 0x61, 0x6b, 0xcd, 0xe2, 0xd9, 0x2f, 0x83, 0xf0, 0xaa, 0x10, + 0x31, 0xb7, 0xe4, 0xc8, 0x47, 0x94, 0xde, 0x02, 0xb5, 0xfb, 0x2e, 0x5b, + 0x16, 0x9d, 0xa0, 0x5b, 0x69, 0x23, 0x7e, 0x7b, 0x23, 0x75, 0xbb, 0x29, + 0xd0, 0xbf, 0x7f, 0x3b, 0x4b, 0x0c, 0x30, 0xda, 0x7b, 0x61, 0xd9, 0x39, + 0x14, 0x23, 0x70, 0xc8, 0x55, 0x31, 0xd4, 0xc7, 0x1c, 0x4c, 0x51, 0x81, + 0x67, 0xb7, 0xa0, 0x32, 0xb7, 0xa2, 0x8a, 0x8d, 0xea, 0xf6, 0xcb, 0xe5, + 0x78, 0xd8, 0xa7, 0xd2, 0xd5, 0xd2, 0x1c, 0x58, 0xe1, 0xed, 0xb7, 0x87, + 0xf9, 0x11, 0x95, 0x50, 0x72, 0x6e, 0x17, 0xa3, 0x09, 0x88, 0x31, 0xb9, + 0x76, 0x1b, 0xf3, 0x9b, 0x54, 0x05, 0x77, 0x8d, 0xc2, 0xe1, 0x30, 0x71, + 0xfe, 0xad, 0xd2, 0x17, 0x40, 0x0e, 0x05, 0xbe, 0x97, 0x46, 0x9a, 0x6b, + 0xb3, 0x32, 0x94, 0x04, 0x50, 0xf2, 0xef, 0x8c, 0x29, 0x93, 0x6e, 0xde, + 0x5c, 0xc2, 0x7f, 0x34, 0x9d, 0x81, 0x92, 0x72, 0xfc, 0x9b, 0x47, 0x0d, + 0x28, 0xf0, 0x98, 0xce, 0x45, 0x7c, 0xe8, 0x00, 0xfe, 0x1a, 0x19, 0x49, + 0xce, 0xe4, 0xc4, 0xd8, 0x1b, 0x64, 0xcb, 0x4a, 0x0d, 0x62, 0xe7, 0xef, + 0x59, 0xef, 0xbb, 0x25, 0x1c, 0x82, 0xf4, 0xc9, 0x29, 0xe3, 0x92, 0x92, + 0x1b, 0x1c, 0x33, 0xe1, 0xfd, 0xdb, 0x40, 0x47, 0xe6, 0xe5, 0x51, 0x83, + 0x0d, 0x18, 0x10, 0xd4, 0xd2, 0x73, 0x74, 0x08, 0x96, 0x71, 0x45, 0xe4, + 0xd4, 0x1c, 0x4f, 0x3f, 0x21, 0xd7, 0xc5, 0xb1, 0xdd, 0xa0, 0x0e, 0xbe, + 0x9d, 0x63, 0xed, 0x0d, 0xb3, 0xcf, 0x75, 0x29, 0xe3, 0xf7, 0x6c, 0xf4, + 0xb5, 0x97, 0x94, 0xb9, 0x66, 0x1b, 0xe2, 0x05, 0x1c, 0xdd, 0x5e, 0x45, + 0xc7, 0x6f, 0xe6, 0x4a, 0x59, 0x53, 0x75, 0x4c, 0x1e, 0x70, 0x4d, 0x61, + 0xa6, 0x95, 0x1b, 0xf1, 0x9e, 0xf2, 0x89, 0x99, 0x32, 0xca, 0x39, 0x43, + 0x4e, 0x6f, 0xd3, 0x1f, 0xde, 0xb4, 0x10, 0x3f, 0x2f, 0xee, 0xe2, 0x37, + 0xb7, 0xbc, 0xa5, 0xe6, 0xf5, 0x9d, 0xfb, 0x6b, 0xf5, 0xf9, 0x4f, 0x85, + 0xe5, 0x92, 0x2d, 0x09, 0x2d, 0xbe, 0x46, 0x6c, 0x9b, 0x23, 0xcb, 0x19, + 0x85, 0x86, 0x96, 0x88, 0xa5, 0x37, 0xbf, 0xff, 0x3b, 0x8c, 0x00, 0x79, + 0x77, 0xe3, 0xa1, 0x14, 0xf0, 0x0b, 0x45, 0xba, 0xd5, 0x79, 0xa6, 0xc9, + 0x61, 0x45, 0xda, 0x07, 0xb6, 0x67, 0xa4, 0x6c, 0x39, 0x45, 0x8d, 0xfd, + 0xc4, 0x00, 0xb0, 0x01, 0xf8, 0x8f, 0x6b, 0xcf, 0x9b, 0xaa, 0x5b, 0x16, + 0x21, 0x52, 0x7e, 0xc6, 0xc1, 0x90, 0xf1, 0xad, 0xf9, 0x59, 0x1d, 0xf1, + 0xf6, 0xf8, 0xf8, 0xf6, 0x99, 0x49, 0x86, 0xee, 0x75, 0xc6, 0x61, 0xb7, + 0x2d, 0x5a, 0xbb, 0x0f, 0xda, 0x79, 0xf5, 0xbb, 0xc2, 0xa0, 0x92, 0x7e, + 0xbf, 0x90, 0x0b, 0x61, 0x44, 0xed, 0x26, 0xe5, 0x91, 0xd9, 0x52, 0x69, + 0x95, 0x0b, 0x2e, 0x84, 0x56, 0xc9, 0xd8, 0xae, 0x45, 0x2e, 0x0a, 0x7c, + 0xb4, 0x9b, 0x15, 0x20, 0xfa, 0x6d, 0x2c, 0x28, 0xe6, 0xd2, 0x15, 0x1b, + 0x4d, 0xa5, 0x14, 0xdf, 0x3f, 0x9f, 0x3d, 0x89, 0xba, 0x87, 0x41, 0xaa, + 0x56, 0x0d, 0x56, 0xdf, 0x95, 0xf3, 0xdf, 0x2b, 0xf3, 0x68, 0xc7, 0x60, + 0xc9, 0x4b, 0x38, 0xaa, 0x71, 0x4d, 0x9f, 0xa9, 0x39, 0xdc, 0x5c, 0x29, + 0x7f, 0x57, 0x52, 0xdd, 0x42, 0x9b, 0xa5, 0x9d, 0x3f, 0x7e, 0x2c, 0xb7, + 0x61, 0x41, 0xd0, 0xa8, 0x54, 0x54, 0x0d, 0x38, 0x29, 0xa1, 0xb5, 0xab, + 0x4f, 0x6f, 0x3f, 0xd3, 0x89, 0xd7, 0x55, 0xe4, 0xed, 0xe7, 0x69, 0x35, + 0x06, 0x59, 0x22, 0x97, 0x4b, 0xfd, 0xb2, 0x74, 0x21, 0xf2, 0x45, 0x7d, + 0x50, 0xa3, 0xea, 0xa0, 0xf6, 0xe8, 0xfd, 0x44, 0x65, 0xe8, 0x07, 0x2f, + 0x55, 0xa6, 0xae, 0x52, 0xb1, 0x0a, 0x46, 0xe1, 0x3d, 0xdc, 0x60, 0xbf, + 0x38, 0x6c, 0x28, 0xf3, 0x0a, 0x85, 0x94, 0x3e, 0x56, 0x43, 0x19, 0xb7, + 0xaa, 0xf3, 0x79, 0xcc, 0x9c, 0x61, 0x94, 0xab, 0x62, 0x0c, 0x0a, 0x6d, + 0x80, 0x64, 0x59, 0x1b, 0x88, 0xe7, 0xec, 0x3c, 0x9d, 0x9c, 0xd7, 0xda, + 0xba, 0x8a, 0x34, 0x6b, 0x73, 0x5d, 0xd9, 0x07, 0xbd, 0xbc, 0xb8, 0xa2, + 0xee, 0x63, 0xae, 0x07, 0x5a, 0x85, 0x1e, 0x87, 0xd1, 0x8c, 0x80, 0x07, + 0xd1, 0xde, 0xd3, 0x9c, 0x2c, 0xb5, 0x58, 0x34, 0xb2, 0xe4, 0x0a, 0x8c, + 0xda, 0x63, 0x7d, 0xd1, 0x22, 0xc8, 0x9a, 0xec, 0xd3, 0x0d, 0x01, 0xc7, + 0x2f, 0xe4, 0xe8, 0x1f, 0x28, 0xcd, 0x81, 0x03, 0x55, 0xba, 0x93, 0xfe, + 0xff, 0x6b, 0xce, 0xcd, 0xef, 0x64, 0xd9, 0x8f, 0x9b, 0x2e, 0xdb, 0x38, + 0xc3, 0xe2, 0x0e, 0x29, 0xb8, 0x3f, 0x7e, 0x48, 0xc2, 0x3b, 0xd9, 0xb2, + 0xd3, 0xea, 0xef, 0x26, 0xe4, 0xae, 0x42, 0x8a, 0xa7, 0xdf, 0x02, 0x9b, + 0x3f, 0x26, 0x7c, 0xf4, 0x23, 0x5e, 0x3a, 0x4e, 0x21, 0xa9, 0x6c, 0xb4, + 0x62, 0x4a, 0x1a, 0xc0, 0xd6, 0x8c, 0x4b, 0x95, 0xbc, 0x4f, 0xde, 0x5c, + 0xec, 0x82, 0xde, 0xe2, 0xe9, 0x8e, 0x9c, 0xad, 0xa9, 0x87, 0xd2, 0x1b, + 0x5b, 0xee, 0x88, 0x92, 0xc8, 0x78, 0xd3, 0x88, 0x4d, 0xdf, 0x13, 0x3a, + 0xff, 0x7c, 0xe5, 0x76, 0x65, 0x4a, 0x1e, 0x9e, 0x56, 0x22, 0xd0, 0x21, + 0x07, 0x8f, 0x6f, 0x3b, 0xb6, 0x39, 0xef, 0xf2, 0x33, 0xc7, 0x24, 0xd4, + 0x38, 0x2d, 0x93, 0x69, 0x2a, 0xca, 0xda, 0x71, 0x6c, 0x7b, 0xf5, 0x42, + 0x92, 0x0f, 0x85, 0x46, 0xd9, 0xfc, 0xe7, 0x9f, 0x7e, 0x46, 0x0e, 0x48, + 0x5d, 0x64, 0x7e, 0xdf, 0x9c, 0x97, 0x8d, 0x94, 0x62, 0x1b, 0x84, 0xb4, + 0xa7, 0x05, 0x36, 0x98, 0xfb, 0xa2, 0x5d, 0x73, 0x85, 0xa3, 0x69, 0xea, + 0x50, 0x71, 0xd5, 0x88, 0xcd, 0xb4, 0x23, 0x3a, 0xf1, 0x96, 0x1b, 0xb2, + 0x04, 0x0e, 0x87, 0xfa, 0xb6, 0x67, 0xe4, 0xd7, 0x3a, 0x79, 0x50, 0xc3, + 0x12, 0x97, 0xbe, 0x07, 0x33, 0xba, 0x51, 0x1d, 0x24, 0x7d, 0x1d, 0xaf, + 0xd4, 0x2c, 0xe6, 0xe6, 0xcc, 0x9e, 0x7a, 0xb4, 0x26, 0xca, 0x7a, 0x50, + 0x1e, 0xb3, 0x8d, 0x6c, 0x00, 0x00, 0x01, 0x0a, 0x43, 0xf9, 0x00, 0x03, + 0xbf, 0xe0, 0xb1, 0x5c, 0x93, 0xba, 0x30, 0x72, 0x79, 0xf1, 0x4d, 0x53, + 0xac, 0x3e, 0x58, 0x53, 0x6f, 0xf9, 0x99, 0xc9, 0x1e, 0xf5, 0x2c, 0x80, + 0x4f, 0x96, 0xd8, 0xba, 0x81, 0x8a, 0x39, 0xbd, 0x28, 0x03, 0x87, 0xb8, + 0x8c, 0x29, 0xd6, 0xe4, 0x09, 0xdf, 0x3b, 0xaf, 0xa5, 0xa1, 0xf1, 0x55, + 0x21, 0xc3, 0x1b, 0xce, 0x08, 0xcf, 0x21, 0x4b, 0x2f, 0x8c, 0x6f, 0x1b, + 0x70, 0x9e, 0x4f, 0x8e, 0x50, 0x9c, 0xb1, 0x15, 0xbc, 0x74, 0x1c, 0xde, + 0xd0, 0xee, 0xf1, 0xd3, 0x20, 0x66, 0x61, 0x44, 0xda, 0x15, 0x21, 0x55, + 0xbd, 0x68, 0x03, 0xc7, 0xf1, 0xd7, 0x98, 0xbd, 0x4a, 0x7d, 0x97, 0x97, + 0xbe, 0xee, 0x97, 0x22, 0x42, 0xa8, 0xc8, 0x14, 0xde, 0x14, 0x9b, 0xce, + 0xad, 0x6b, 0x76, 0x51, 0x69, 0x90, 0x28, 0xa3, 0xda, 0x21, 0x52, 0x52, + 0x5b, 0x46, 0x1f, 0x15, 0xbf, 0xa0, 0x7b, 0x25, 0x11, 0xdf, 0x61, 0x20, + 0x13, 0xfe, 0x22, 0x14, 0x58, 0x70, 0xd2, 0xdb, 0xca, 0xda, 0x01, 0x53, + 0xdd, 0xb6, 0x20, 0xc2, 0xe7, 0x8b, 0x71, 0x04, 0x3a, 0x0a, 0xe6, 0x6e, + 0xec, 0x0d, 0x59, 0x12, 0x4f, 0x14, 0xad, 0xba, 0x02, 0x17, 0xfd, 0x3b, + 0x69, 0x2e, 0x92, 0x58, 0x2a, 0xd8, 0xa4, 0x26, 0xac, 0x2b, 0x15, 0xbf, + 0xb6, 0x80, 0x3b, 0x00, 0x5f, 0xec, 0x00, 0x5f, 0xfc, 0x8f, 0xe2, 0x74, + 0xa8, 0x4f, 0xc1, 0x62, 0x35, 0x61, 0x97, 0x13, 0x72, 0x9e, 0x10, 0xdf, + 0x6e, 0x11, 0xff, 0xe7, 0xa0, 0x06, 0x6f, 0xe5, 0xeb, 0xa3, 0x39, 0x79, + 0x97, 0x64, 0xa8, 0x9c, 0x5c, 0x59, 0x07, 0xb7, 0xe4, 0xfe, 0xf9, 0x00, + 0x35, 0xf6, 0x9c, 0xf9, 0xa4, 0x2e, 0x90, 0x3a, 0x49, 0x3b, 0xe4, 0x71, + 0x46, 0xd2, 0xa4, 0x3d, 0xbd, 0x0f, 0xfb, 0xed, 0x9f, 0x04, 0x70, 0x0a, + 0xfe, 0x05, 0x6d, 0x2f, 0xf2, 0x41, 0x5f, 0xc6, 0x61, 0x84, 0x0c, 0xcf, + 0xc2, 0x55, 0xb8, 0x78, 0x63, 0x67, 0xd3, 0xcc, 0xdf, 0x3b, 0x6a, 0x0f, + 0x74, 0x58, 0x81, 0x6d, 0xae, 0x5b, 0xa5, 0xd5, 0x0a, 0x6f, 0x9e, 0x2b, + 0x9a, 0x00, 0xf8, 0x8d, 0x9c, 0x65, 0x5b, 0x57, 0x79, 0x47, 0x48, 0x5d, + 0x55, 0x1a, 0x4a, 0x6f, 0x00, 0x2d, 0x61, 0x91, 0x47, 0x42, 0xc7, 0x48, + 0x51, 0xed, 0xea, 0xf5, 0xdc, 0x00, 0x3a, 0xec, 0x8a, 0x44, 0xec, 0x9f, + 0x00, 0x05, 0x3d, 0x90, 0x33, 0xbe, 0x6e, 0x69, 0xf0, 0x38, 0xb3, 0x2a, + 0x78, 0x94, 0xde, 0x0b, 0xfd, 0x40, 0x2d, 0xd7, 0xeb, 0x90, 0x35, 0x2e, + 0xd5, 0x83, 0x08, 0x4d, 0x35, 0x76, 0x54, 0xb0, 0x30, 0x29, 0xb0, 0xb0, + 0xb6, 0xfa, 0x36, 0xd7, 0xc8, 0xf9, 0x7d, 0x0a, 0xa0, 0x6d, 0xae, 0x27, + 0x10, 0x04, 0xdc, 0x40, 0x85, 0xb1, 0x5b, 0x81, 0xd6, 0x00, 0x19, 0x59, + 0x9a, 0xf0, 0x9b, 0x04, 0xcb, 0x81, 0x87, 0x05, 0xb6, 0x5f, 0xa7, 0x40, + 0x16, 0x08, 0x13, 0xcc, 0x81, 0x31, 0x0c, 0x84, 0xba, 0xdb, 0x4b, 0xe6, + 0xb2, 0x90, 0xd9, 0xd8, 0x39, 0xba, 0x78, 0x80, 0x07, 0xc2, 0x1d, 0x32, + 0xbe, 0x06, 0xcd, 0x47, 0x86, 0x0c, 0x94, 0x69, 0xe1, 0x8d, 0xbb, 0xdc, + 0xd0, 0x03, 0x9a, 0x40, 0x2a, 0xa5, 0x86, 0xe2, 0x26, 0xcf, 0x0d, 0x96, + 0x51, 0xc1, 0x8d, 0x92, 0xd7, 0xfd, 0x76, 0x0a, 0xc7, 0x28, 0xcc, 0x0f, + 0xe7, 0x22, 0x3e, 0x87, 0x43, 0xf4, 0x60, 0x62, 0x16, 0x5b, 0x6b, 0x22, + 0x6d, 0xf6, 0x23, 0x47, 0x62, 0x5a, 0xb6, 0xd8, 0x2b, 0xa8, 0xe9, 0xb7, + 0x76, 0x97, 0x4d, 0xd5, 0xb6, 0x90, 0xdb, 0x3f, 0xd4, 0x25, 0xb6, 0xd4, + 0xb6, 0xef, 0x32, 0x47, 0x45, 0x2c, 0xa3, 0xb3, 0xbd, 0x2b, 0x68, 0x1f, + 0x0a, 0x66, 0xe3, 0x00, 0x0f, 0xa1, 0x39, 0xf4, 0x6a, 0x20, 0x7e, 0x4a, + 0xa8, 0x70, 0xd5, 0x0d, 0x6b, 0x26, 0x5f, 0xbb, 0xf3, 0x64, 0xa1, 0x8b, + 0x5d, 0xbb, 0x2c, 0x08, 0x92, 0x17, 0xe0, 0xd4, 0xb9, 0xcb, 0xce, 0xf7, + 0x14, 0x24, 0x81, 0x66, 0x42, 0x13, 0x77, 0x40, 0x32, 0xa0, 0x5b, 0x7a, + 0x50, 0x0c, 0xcd, 0x24, 0xd6, 0xcb, 0xb5, 0x63, 0x9d, 0x28, 0x61, 0xb9, + 0xdb, 0xb0, 0xc8, 0x83, 0x07, 0x1e, 0x16, 0xdd, 0xb7, 0xe0, 0x00, 0x92, + 0xbd, 0xd2, 0x3a, 0xcf, 0xd0, 0x09, 0x2d, 0xa8, 0x7c, 0x58, 0x89, 0x14, + 0x22, 0xa3, 0x73, 0xfb, 0xb7, 0xdc, 0x40, 0x99, 0x2d, 0x01, 0x54, 0x9a, + 0x85, 0x1c, 0x37, 0x29, 0xc3, 0x4e, 0x6f, 0x57, 0xd7, 0x90, 0x8f, 0x81, + 0x62, 0x5d, 0xcb, 0xac, 0x01, 0x27, 0x90, 0xbc, 0xa9, 0x03, 0xd6, 0x02, + 0x27, 0xfe, 0x5b, 0x22, 0xf8, 0x28, 0xf6, 0xdd, 0xba, 0x23, 0x7c, 0xad, + 0xef, 0x7d, 0x9e, 0x27, 0x8c, 0xb9, 0x07, 0xee, 0xd7, 0x73, 0xbc, 0xef, + 0xe8, 0xe8, 0xa5, 0x7a, 0x37, 0x93, 0xd3, 0x45, 0x66, 0x27, 0x28, 0x19, + 0x6e, 0x6f, 0x9c, 0x18, 0x32, 0xd6, 0xd9, 0x78, 0x82, 0x81, 0x0b, 0xfe, + 0xab, 0xa0, 0xc2, 0xe5, 0x2a, 0xd2, 0x11, 0x5e, 0x25, 0xb6, 0x9c, 0xe5, + 0xef, 0x15, 0xaa, 0xe7, 0x02, 0x40, 0x01, 0x9b, 0xbb, 0x5f, 0xa1, 0x45, + 0x1c, 0x16, 0xc3, 0x4a, 0x23, 0x71, 0xdb, 0xbd, 0xbd, 0x79, 0x96, 0xd2, + 0x63, 0xb2, 0x3e, 0x2c, 0xb2, 0xd3, 0x51, 0x26, 0xf8, 0xb7, 0x4c, 0x49, + 0x31, 0xca, 0x65, 0x29, 0x10, 0xe4, 0xb1, 0x47, 0x35, 0x3f, 0x5e, 0x9f, + 0xc9, 0x75, 0x21, 0x72, 0xfe, 0xa2, 0xae, 0x12, 0xa8, 0xc6, 0xeb, 0xba, + 0xce, 0xc5, 0xde, 0x7a, 0xb4, 0x11, 0xbf, 0xf3, 0x75, 0xcf, 0x92, 0xcc, + 0xc0, 0xe8, 0x54, 0xab, 0x0b, 0x69, 0x67, 0x0f, 0xad, 0xd1, 0x9d, 0xed, + 0x17, 0x97, 0xbe, 0x86, 0xdc, 0x29, 0x4a, 0xbf, 0xaa, 0x36, 0x1c, 0x53, + 0x59, 0xed, 0xf1, 0x1c, 0xf7, 0xef, 0x1d, 0xc9, 0x40, 0x73, 0xb7, 0x56, + 0x3a, 0x64, 0x18, 0x16, 0x59, 0x61, 0x8d, 0x9c, 0x51, 0x05, 0xdd, 0x4a, + 0x27, 0x98, 0x34, 0x3a, 0xf2, 0xa9, 0x91, 0x0a, 0x2b, 0x00, 0xb6, 0x5d, + 0xef, 0x51, 0x5d, 0x62, 0x14, 0x4e, 0x92, 0xd2, 0xb1, 0xc7, 0xda, 0x58, + 0xe5, 0x0c, 0x66, 0xca, 0x16, 0x73, 0x7d, 0x22, 0x27, 0x09, 0x9a, 0x27, + 0xdf, 0x4d, 0x28, 0xb9, 0xba, 0xa8, 0x64, 0x2c, 0xe2, 0x8a, 0x88, 0x53, + 0x5b, 0xf5, 0xe2, 0x68, 0x18, 0x15, 0x24, 0xfd, 0x43, 0x6e, 0xd4, 0x43, + 0xb7, 0x16, 0x0e, 0x29, 0x5b, 0x17, 0x5b, 0x78, 0x78, 0x19, 0xe5, 0x3f, + 0x75, 0xcb, 0xbb, 0x46, 0x28, 0xd8, 0x73, 0x65, 0x8e, 0x77, 0x22, 0xb7, + 0x4d, 0x86, 0x0d, 0xbb, 0x6a, 0x98, 0x30, 0x60, 0x4b, 0x26, 0x1b, 0xb3, + 0xe1, 0xfa, 0x2b, 0xf2, 0x26, 0xa9, 0x52, 0xec, 0xda, 0x76, 0x49, 0x10, + 0x86, 0x31, 0xb4, 0xdf, 0x67, 0xfb, 0xbd, 0xf3, 0x5f, 0xaa, 0x52, 0x47, + 0xd9, 0x09, 0x67, 0x34, 0xde, 0x54, 0x4c, 0xb7, 0x28, 0x4e, 0x43, 0xc0, + 0x7c, 0xd6, 0x71, 0xa4, 0xe9, 0x76, 0xc8, 0xa7, 0x93, 0x6c, 0x98, 0xb4, + 0xb1, 0xb0, 0x74, 0x69, 0x6d, 0x02, 0x5b, 0xbb, 0xd8, 0x52, 0x71, 0xaf, + 0xbc, 0xc5, 0x50, 0xec, 0x94, 0xa8, 0x8a, 0x94, 0xb9, 0x3c, 0x5b, 0x95, + 0xc8, 0xb7, 0x0a, 0x7d, 0x97, 0x31, 0x0e, 0xb2, 0x3a, 0xa9, 0x91, 0x4b, + 0x29, 0x61, 0x5e, 0xac, 0xc4, 0xfa, 0x2a, 0x41, 0x83, 0x2e, 0x9a, 0x92, + 0x0e, 0x1e, 0x48, 0x6d, 0xdf, 0x63, 0x5f, 0x7b, 0xe6, 0xeb, 0xf7, 0x4f, + 0x9f, 0x89, 0x46, 0x42, 0x8b, 0x96, 0x8c, 0x60, 0xf6, 0x84, 0xb2, 0x9c, + 0xde, 0x5d, 0xdd, 0xf9, 0x85, 0xad, 0x9f, 0xa8, 0xa7, 0x59, 0xfa, 0x0c, + 0x1a, 0x16, 0xd7, 0xf3, 0xf3, 0xc7, 0x1c, 0xc9, 0x3a, 0xe0, 0x6d, 0xb5, + 0xd8, 0xb0, 0xe0, 0xc4, 0x6a, 0xba, 0x92, 0x45, 0x3e, 0x9e, 0x62, 0x42, + 0xfc, 0x4f, 0x6c, 0x1c, 0x3e, 0xf2, 0x65, 0x48, 0x75, 0x42, 0xe8, 0xd8, + 0x54, 0x61, 0x8d, 0x39, 0xbf, 0x5b, 0xf3, 0xce, 0x77, 0xf0, 0x27, 0x20, + 0x91, 0x68, 0x4c, 0xfc, 0xde, 0x52, 0x4e, 0x20, 0x66, 0x6c, 0x1b, 0x4a, + 0xa7, 0xc1, 0x8d, 0xcf, 0x13, 0xa2, 0x80, 0x0f, 0xdd, 0x82, 0xe6, 0x17, + 0x16, 0xe4, 0x18, 0x71, 0xa7, 0x28, 0x63, 0x73, 0x1d, 0x2b, 0x8a, 0x2c, + 0xa3, 0xcd, 0x7c, 0x85, 0x2c, 0x6e, 0x87, 0xb3, 0x8d, 0xcd, 0xba, 0xa3, + 0xe4, 0xa6, 0xe2, 0x50, 0xa6, 0x50, 0xa6, 0xdb, 0x75, 0x6d, 0x6e, 0xbf, + 0xc7, 0x96, 0x3b, 0x83, 0x90, 0xa7, 0x22, 0x19, 0x31, 0x14, 0x6a, 0x35, + 0x4e, 0xf3, 0x10, 0x29, 0xce, 0xb7, 0x6d, 0x3c, 0x3e, 0xf6, 0xb6, 0x0c, + 0x19, 0x69, 0xed, 0x5e, 0xdc, 0x11, 0xc6, 0x24, 0x09, 0x99, 0x6a, 0x16, + 0x16, 0x18, 0xda, 0x66, 0xaf, 0x9d, 0x36, 0x8d, 0x43, 0xc9, 0x8a, 0xc4, + 0x65, 0x68, 0x68, 0x16, 0xdf, 0x2b, 0xa7, 0x4e, 0xaf, 0x4f, 0xb2, 0x53, + 0x8a, 0xb6, 0xa5, 0xa4, 0x82, 0xe1, 0x2d, 0xac, 0xe3, 0xbc, 0xe3, 0x92, + 0xe6, 0x28, 0x0f, 0x10, 0xe1, 0x9e, 0x8d, 0x83, 0xab, 0xae, 0x32, 0x49, + 0x11, 0x20, 0xd0, 0x82, 0x9a, 0xcf, 0x8d, 0x7c, 0x73, 0x8d, 0xb6, 0xa8, + 0x10, 0x7d, 0x01, 0xab, 0x07, 0x30, 0x7d, 0x6d, 0xe6, 0x6b, 0x9d, 0xb6, + 0xbe, 0x8c, 0x08, 0x6a, 0x16, 0x72, 0xb2, 0x94, 0x04, 0x64, 0x85, 0xc0, + 0x92, 0xda, 0xae, 0x5d, 0xc6, 0x62, 0x71, 0xa1, 0x36, 0x86, 0x36, 0x0c, + 0xdd, 0xc9, 0x2b, 0xc2, 0xa0, 0x67, 0x84, 0x64, 0xc3, 0x00, 0x00, 0x00, + 0x01, 0x0b, 0x43, 0xf9, 0x16, 0xdf, 0x37, 0xad, 0x9e, 0xa7, 0x46, 0xde, + 0xf0, 0xfc, 0xc2, 0xef, 0x8b, 0x71, 0xd3, 0xcf, 0x16, 0x92, 0x8a, 0x6f, + 0x57, 0xc8, 0x21, 0x7f, 0xc8, 0x16, 0xb5, 0xbc, 0xb8, 0x52, 0xda, 0x43, + 0x6f, 0x16, 0x37, 0x5b, 0xd7, 0x0f, 0x0a, 0x1e, 0x1a, 0xd2, 0x53, 0x39, + 0xa0, 0x5b, 0x6c, 0x9f, 0x8b, 0x72, 0x7a, 0xca, 0xdc, 0xa9, 0x25, 0xc9, + 0x00, 0x20, 0x43, 0xa8, 0x09, 0x69, 0xed, 0x3a, 0x1f, 0x23, 0x4d, 0x2d, + 0xbe, 0x59, 0x84, 0x04, 0x99, 0x40, 0x47, 0x0c, 0x85, 0x85, 0x97, 0x49, + 0x2d, 0xda, 0x04, 0x3f, 0xfa, 0xb4, 0x92, 0xdc, 0x48, 0x08, 0x40, 0x0e, + 0x4e, 0x2b, 0xd7, 0x6d, 0x25, 0x95, 0x09, 0x4d, 0xe9, 0x39, 0xcb, 0xc9, + 0xb8, 0x43, 0xb1, 0xb1, 0xa3, 0x09, 0x0c, 0x8e, 0x46, 0xfa, 0x72, 0x10, + 0x76, 0x66, 0xdf, 0x0d, 0xb2, 0x2b, 0x68, 0x00, 0x6c, 0x28, 0x00, 0xf9, + 0xe4, 0x45, 0x35, 0x6a, 0x62, 0xd2, 0x21, 0x19, 0xe0, 0x66, 0x80, 0x47, + 0x69, 0xc1, 0x2a, 0x8c, 0x45, 0xc8, 0x2f, 0x2e, 0x2d, 0x38, 0xa5, 0x1b, + 0x83, 0x61, 0x55, 0xbd, 0x29, 0x17, 0xef, 0x84, 0x4f, 0x9b, 0xc3, 0xa0, + 0xf8, 0x6b, 0x84, 0xf5, 0x5f, 0xd1, 0x6e, 0xf3, 0xa1, 0xf9, 0x64, 0x9b, + 0x32, 0x14, 0x75, 0x52, 0xeb, 0x79, 0xf1, 0xe4, 0xe3, 0x0a, 0xa1, 0x54, + 0xb2, 0x89, 0x5e, 0x8d, 0x56, 0x1a, 0xdf, 0x82, 0xed, 0xfb, 0xc7, 0x41, + 0xe6, 0x58, 0x96, 0x1a, 0xae, 0x0b, 0x1c, 0x35, 0x0a, 0x18, 0xde, 0x64, + 0x5f, 0x39, 0xc7, 0xbe, 0x47, 0x66, 0xc3, 0xe6, 0xd5, 0x88, 0x51, 0xd4, + 0xf0, 0xca, 0xde, 0x88, 0x01, 0x87, 0xc7, 0x3d, 0x7f, 0x5d, 0xf3, 0xcf, + 0x2f, 0xe4, 0x99, 0x4c, 0x78, 0xa7, 0x65, 0x80, 0x16, 0x66, 0x2d, 0x57, + 0xa0, 0xca, 0x12, 0xdc, 0x3a, 0x2f, 0xa1, 0x1e, 0x5b, 0xcf, 0x57, 0x4e, + 0xdd, 0x4d, 0x89, 0x2d, 0x91, 0x70, 0xfa, 0xb2, 0x54, 0xa7, 0x96, 0xdd, + 0xb7, 0x12, 0x6c, 0x84, 0x30, 0x2d, 0xb7, 0xa5, 0x37, 0x9d, 0xf9, 0x78, + 0xeb, 0x64, 0xa1, 0x1b, 0x29, 0x5a, 0x80, 0x2b, 0x6c, 0x93, 0xf3, 0xce, + 0x61, 0x61, 0x85, 0xd9, 0x09, 0x2d, 0x8c, 0x57, 0x19, 0xf0, 0x29, 0xd3, + 0x24, 0x1b, 0x4f, 0xda, 0xfd, 0xa3, 0x49, 0xb6, 0xd5, 0xad, 0xa3, 0x87, + 0xe8, 0x9c, 0xe7, 0x78, 0x88, 0x00, 0x28, 0xce, 0x24, 0xbb, 0x54, 0xe1, + 0xb4, 0xe2, 0x13, 0x2b, 0x16, 0xd6, 0x8a, 0xdd, 0xc4, 0x6e, 0x35, 0xd8, + 0x9e, 0x7b, 0x46, 0xe9, 0xb8, 0xec, 0xc9, 0x2a, 0xad, 0xa8, 0x83, 0x6b, + 0x74, 0xfe, 0x6b, 0x80, 0x1c, 0xfc, 0x58, 0xee, 0xdf, 0x06, 0xe6, 0x3f, + 0x87, 0xf3, 0xc6, 0x44, 0x89, 0x29, 0x32, 0xa2, 0x4a, 0x59, 0xd5, 0x0f, + 0x6f, 0x31, 0x27, 0x96, 0xee, 0xa0, 0x52, 0x17, 0x5b, 0x50, 0x73, 0xf7, + 0x6e, 0x14, 0x03, 0xdd, 0x96, 0x14, 0x30, 0xea, 0xa3, 0x5b, 0x7d, 0xaa, + 0x95, 0xb7, 0xa3, 0x5b, 0xe9, 0x7f, 0x8d, 0x14, 0x26, 0x9a, 0xbe, 0x30, + 0xb9, 0x06, 0x96, 0xdb, 0xb6, 0x93, 0xba, 0xe9, 0xda, 0x09, 0x7f, 0xf5, + 0xed, 0xa8, 0xa7, 0x0e, 0x56, 0xf2, 0x7b, 0x60, 0x81, 0x0e, 0x96, 0xd0, + 0xd5, 0xbe, 0x28, 0xde, 0xfb, 0xea, 0xe7, 0x39, 0xe2, 0x78, 0x7e, 0x50, + 0xd9, 0xbf, 0x33, 0x49, 0xf6, 0x1c, 0x7b, 0xd6, 0x5c, 0xb9, 0x4a, 0x0a, + 0x66, 0xb7, 0x9d, 0x80, 0x53, 0x6d, 0x00, 0x29, 0xb2, 0xb6, 0xa2, 0xb9, + 0x04, 0x1f, 0xec, 0x7e, 0xf6, 0xed, 0x51, 0xc8, 0xe2, 0xa2, 0x8d, 0x2e, + 0xc5, 0x18, 0x59, 0xc9, 0x5b, 0xa5, 0x2c, 0xfb, 0x65, 0x9a, 0x19, 0x71, + 0x08, 0xe9, 0x6d, 0x90, 0x27, 0x92, 0xe2, 0xb5, 0x1f, 0xde, 0x60, 0x91, + 0x1d, 0x3d, 0xf7, 0x02, 0xc5, 0x74, 0x24, 0x53, 0xec, 0x38, 0xed, 0xa5, + 0xfa, 0x36, 0xc9, 0xba, 0x47, 0xc7, 0xde, 0x94, 0x32, 0xf1, 0x82, 0x77, + 0x9b, 0x14, 0x36, 0x06, 0x00, 0x8e, 0x37, 0x63, 0x7a, 0x0d, 0xf9, 0xde, + 0x67, 0x1d, 0x5f, 0x82, 0xb6, 0x9c, 0x98, 0x4e, 0x7c, 0xd4, 0x2d, 0x50, + 0xa3, 0x88, 0x6a, 0xdb, 0x78, 0xea, 0x77, 0xbf, 0x97, 0xbe, 0x81, 0x10, + 0x3b, 0x6c, 0xbf, 0xb1, 0xdb, 0x06, 0x78, 0x04, 0xb4, 0x12, 0x08, 0x40, + 0x0d, 0xb4, 0xd9, 0x60, 0x62, 0x3a, 0xd2, 0xd5, 0x61, 0xd4, 0xa2, 0x86, + 0x9e, 0xdc, 0xec, 0xa0, 0x06, 0x9d, 0xf3, 0xa9, 0x06, 0xa8, 0x04, 0xb5, + 0x7c, 0x07, 0xd3, 0xa0, 0x53, 0x03, 0x1a, 0x46, 0xb6, 0x08, 0xd3, 0x87, + 0x88, 0xdb, 0x82, 0xf9, 0x90, 0xac, 0xfc, 0xae, 0x19, 0x9c, 0x13, 0x57, + 0xc5, 0xba, 0x3b, 0x08, 0x3d, 0x42, 0x7c, 0x01, 0x56, 0x6c, 0x42, 0x9b, + 0xe7, 0x46, 0x87, 0xd8, 0x90, 0x30, 0xca, 0x02, 0xe6, 0xfa, 0xc1, 0x16, + 0xc0, 0x06, 0x64, 0x4e, 0xcd, 0x72, 0x14, 0xbb, 0xca, 0xae, 0x4d, 0x92, + 0xa1, 0xe8, 0x96, 0xc0, 0xa6, 0x74, 0xa6, 0x9c, 0xab, 0x4a, 0x6f, 0x33, + 0x9d, 0x39, 0xef, 0xa0, 0xeb, 0x42, 0xf6, 0x45, 0x1c, 0x77, 0xab, 0x76, + 0x1d, 0xef, 0xe4, 0x56, 0x2a, 0x16, 0x93, 0x12, 0x48, 0x65, 0x2d, 0x46, + 0x36, 0x5f, 0x90, 0x43, 0xff, 0x87, 0x59, 0xab, 0x12, 0xe4, 0x2a, 0x4d, + 0x2e, 0x55, 0x85, 0x21, 0xda, 0x16, 0xd8, 0x1f, 0xbc, 0x13, 0x9d, 0x92, + 0xec, 0x1b, 0x99, 0x72, 0x9d, 0x9a, 0x35, 0x4b, 0x3a, 0x05, 0x36, 0x67, + 0x36, 0x97, 0x4a, 0x46, 0xfd, 0x07, 0x3e, 0xe0, 0x16, 0x3e, 0xf1, 0x26, + 0x01, 0x2e, 0xf3, 0xa1, 0xd5, 0xd2, 0xc2, 0xce, 0xa3, 0x06, 0xfa, 0xb7, + 0x0e, 0x0b, 0xe0, 0x4f, 0x59, 0x93, 0x62, 0x17, 0x67, 0x73, 0x26, 0x62, + 0x6a, 0x06, 0x8d, 0xbe, 0x0c, 0x3b, 0xb8, 0x2f, 0x87, 0x64, 0xa3, 0x91, + 0xdc, 0xcd, 0x54, 0x28, 0x79, 0x0d, 0x83, 0xde, 0x62, 0x47, 0xa5, 0x38, + 0x9b, 0x2a, 0x98, 0x32, 0x9c, 0x8d, 0x11, 0xab, 0x46, 0xb6, 0xcf, 0xb2, + 0x72, 0x86, 0x6c, 0xa5, 0xfe, 0xd1, 0x12, 0xc2, 0xa3, 0x40, 0x0b, 0x6e, + 0x99, 0x71, 0x03, 0x26, 0x86, 0xa2, 0x56, 0x77, 0xdf, 0x37, 0xec, 0x5d, + 0x1d, 0x24, 0x51, 0x8d, 0x8b, 0xaf, 0xc1, 0x69, 0x07, 0xaa, 0x0c, 0x18, + 0xc4, 0x6a, 0xad, 0xd5, 0xe7, 0xc3, 0x8c, 0x7c, 0xcd, 0x2d, 0x69, 0x86, + 0x0f, 0x3e, 0x14, 0xa8, 0x4b, 0x6d, 0xa2, 0x77, 0xce, 0xd8, 0xeb, 0xd8, + 0x0f, 0x16, 0xd9, 0x2c, 0x88, 0x51, 0xed, 0xc2, 0x8f, 0x36, 0xc3, 0x10, + 0x75, 0x56, 0xec, 0xe7, 0x2f, 0x17, 0x7c, 0xaa, 0x4a, 0x02, 0x22, 0xd1, + 0x0f, 0x62, 0x14, 0xc5, 0x2e, 0x37, 0x7e, 0xc9, 0xc4, 0xb8, 0x90, 0x2f, + 0xd4, 0x05, 0xed, 0x9c, 0xc3, 0x76, 0xd5, 0x08, 0x4b, 0x1b, 0xaa, 0xe9, + 0xe5, 0x8b, 0x54, 0xa4, 0x6e, 0x7e, 0xd7, 0x64, 0x0e, 0x94, 0xe2, 0xcb, + 0xa5, 0x14, 0x35, 0xa0, 0x61, 0x4d, 0xaa, 0x96, 0x5b, 0x6a, 0xb9, 0xb7, + 0xf6, 0x19, 0x30, 0xb2, 0xea, 0xad, 0x6c, 0x5b, 0xcb, 0x8c, 0xcf, 0x2b, + 0x14, 0xea, 0xa8, 0x5c, 0x52, 0xce, 0x6e, 0x98, 0xae, 0xd0, 0xdb, 0x2d, + 0x19, 0x25, 0x42, 0xc8, 0x6d, 0xcc, 0xfc, 0xf5, 0x96, 0xee, 0xd1, 0xe3, + 0x68, 0x53, 0x38, 0xd9, 0x9c, 0xde, 0xff, 0xc4, 0xe6, 0xc3, 0x68, 0x59, + 0xed, 0x88, 0x57, 0x3b, 0x95, 0x77, 0x3c, 0x06, 0x23, 0x54, 0x25, 0xdc, + 0xf2, 0xe5, 0xe7, 0x8e, 0x1f, 0x94, 0x39, 0xf2, 0x53, 0x9b, 0xe8, 0x00, + 0x81, 0xfa, 0xa0, 0x0f, 0xbe, 0x40, 0x1e, 0xfd, 0xb8, 0x8e, 0x16, 0xe3, + 0x4d, 0x97, 0xae, 0x05, 0xee, 0x43, 0x2c, 0x7e, 0x5b, 0x03, 0xe5, 0x38, + 0x7b, 0x54, 0x65, 0x1b, 0xf9, 0xe9, 0x13, 0x1e, 0x91, 0x47, 0x14, 0x79, + 0x74, 0xa6, 0x4b, 0xd5, 0xc1, 0x56, 0xaa, 0x84, 0x54, 0x59, 0x11, 0x61, + 0x45, 0x0c, 0x6f, 0xba, 0x02, 0x07, 0xe7, 0x80, 0x59, 0x9f, 0xda, 0xe1, + 0x19, 0x34, 0x38, 0xde, 0x5f, 0x61, 0x97, 0x65, 0xc8, 0x62, 0xda, 0x3c, + 0xb4, 0x8d, 0xec, 0x7e, 0x08, 0xa4, 0x70, 0x06, 0xbf, 0xf8, 0xfa, 0xfe, + 0xe8, 0x76, 0x4b, 0x86, 0xc8, 0x4c, 0xcc, 0x83, 0x1b, 0xcd, 0x22, 0x73, + 0x1d, 0xcb, 0x9f, 0x96, 0x51, 0xd2, 0x37, 0x08, 0x87, 0x99, 0xb9, 0xb3, + 0xd1, 0xbf, 0x92, 0x02, 0x07, 0xe6, 0x7d, 0xa0, 0x03, 0x3f, 0xe3, 0xf8, + 0xf8, 0xf9, 0xca, 0x95, 0x1d, 0xe6, 0x85, 0xe3, 0x9f, 0x0b, 0x85, 0x50, + 0xc5, 0x6f, 0xd0, 0x00, 0x05, 0x20, 0x0e, 0x44, 0xfd, 0x40, 0x1f, 0xf7, + 0xaf, 0xeb, 0x40, 0x8e, 0xb8, 0xc2, 0xec, 0x31, 0x57, 0x74, 0x29, 0xbb, + 0xe0, 0x0c, 0x39, 0xdf, 0x8e, 0xe5, 0xde, 0x10, 0x22, 0xc0, 0x2e, 0x36, + 0x92, 0x25, 0xd1, 0x3f, 0x05, 0x50, 0x92, 0x88, 0x48, 0xd6, 0x20, 0x5f, + 0x06, 0x39, 0xf7, 0x28, 0x4e, 0x36, 0x5c, 0x24, 0xc9, 0x6b, 0x00, 0x00, + 0x00, 0x01, 0x0c, 0x43, 0xd4, 0x08, 0x1f, 0xa2, 0x01, 0x61, 0x14, 0x5e, + 0x67, 0xf0, 0x4e, 0xcf, 0xd6, 0xf2, 0xfe, 0x71, 0x0c, 0xe2, 0x54, 0xda, + 0xb6, 0x8c, 0x0a, 0xad, 0xd1, 0x00, 0x63, 0x8f, 0x22, 0x88, 0x22, 0xbb, + 0xbb, 0x4e, 0x04, 0x50, 0x0f, 0xb9, 0x5f, 0x25, 0x0f, 0xfd, 0xf9, 0xe4, + 0x28, 0x25, 0xbe, 0xad, 0xa2, 0xdc, 0x00, 0xd0, 0x00, 0x45, 0x9c, 0x50, + 0xc0, 0xe8, 0x6e, 0xbe, 0xad, 0x32, 0xfe, 0xe5, 0x26, 0xc2, 0x86, 0x54, + 0x63, 0xc8, 0x82, 0x7f, 0xc8, 0x03, 0xd0, 0xfb, 0x6f, 0xec, 0x10, 0x80, + 0x2a, 0xbf, 0xcc, 0x02, 0x27, 0x75, 0x2c, 0x0d, 0x3d, 0xbc, 0x2a, 0x93, + 0x65, 0x28, 0x02, 0x23, 0xdb, 0x8b, 0x74, 0xc2, 0xe9, 0x09, 0xbf, 0xc9, + 0x70, 0x10, 0x80, 0x1e, 0x47, 0xa4, 0x0d, 0xab, 0x52, 0x0e, 0x3a, 0x8d, + 0xa1, 0x6c, 0x2e, 0x2c, 0x59, 0xb4, 0x36, 0xda, 0x53, 0x0c, 0xfc, 0x57, + 0x00, 0x0c, 0x24, 0x39, 0x9c, 0xb7, 0x8d, 0xf4, 0x2d, 0xb7, 0x85, 0xda, + 0xdc, 0x0d, 0xf2, 0xb9, 0x03, 0x12, 0x42, 0x44, 0x6f, 0x75, 0xb2, 0xf6, + 0xfe, 0xcd, 0x0a, 0x0f, 0x35, 0xbc, 0xe6, 0x97, 0x8a, 0x42, 0xa6, 0x52, + 0x5a, 0x37, 0xd3, 0x04, 0xbf, 0xf3, 0x6b, 0xac, 0x0d, 0xf3, 0xdd, 0xd9, + 0x26, 0x1e, 0x36, 0x5a, 0x54, 0x3c, 0x6b, 0x4c, 0x2e, 0xa1, 0x29, 0x59, + 0x46, 0xf7, 0x7d, 0xbe, 0x35, 0xcf, 0xfe, 0xbb, 0x45, 0xe9, 0xd2, 0xeb, + 0x89, 0xfc, 0xef, 0x7c, 0xbe, 0x58, 0x6c, 0xa9, 0xe7, 0x13, 0x33, 0x32, + 0x18, 0x7c, 0x0b, 0x6f, 0x9d, 0x4e, 0x32, 0xe7, 0x19, 0x96, 0x0f, 0xb9, + 0x0e, 0xa6, 0x42, 0xce, 0x5a, 0x5d, 0x6a, 0x28, 0x88, 0xe7, 0x4f, 0x2b, + 0x90, 0x73, 0xed, 0x98, 0xaf, 0x53, 0xcb, 0x44, 0x08, 0x6b, 0x30, 0x38, + 0x5e, 0x6c, 0x88, 0x02, 0xb9, 0x57, 0xd6, 0x37, 0x9c, 0x98, 0x61, 0x49, + 0x46, 0xa6, 0x52, 0x99, 0x99, 0x23, 0x7d, 0x90, 0x05, 0x84, 0x52, 0x38, + 0xaf, 0xa8, 0x94, 0xf6, 0x2c, 0x11, 0x00, 0x17, 0x08, 0x98, 0xe3, 0x66, + 0xf2, 0x62, 0xc5, 0xf2, 0x0c, 0xa1, 0x4d, 0xf2, 0x27, 0x49, 0x38, 0x73, + 0x8b, 0x1e, 0x54, 0x87, 0x81, 0x4d, 0xd1, 0xca, 0x00, 0x64, 0xe7, 0x29, + 0x0a, 0x94, 0xdc, 0xc5, 0x9e, 0x51, 0xf5, 0x42, 0x0d, 0x75, 0x84, 0x30, + 0xc6, 0xf4, 0xf2, 0x2e, 0x54, 0xf4, 0x56, 0xe9, 0x90, 0xaa, 0x49, 0x6c, + 0x9e, 0xe0, 0x2d, 0xb3, 0xd4, 0x14, 0xf8, 0x00, 0x31, 0x88, 0xdd, 0xf2, + 0x3b, 0xaf, 0x3a, 0x59, 0x0d, 0xb2, 0x55, 0xfa, 0x1b, 0x62, 0xd0, 0xb2, + 0x43, 0x22, 0x64, 0x64, 0x39, 0xbe, 0x54, 0x4e, 0xf3, 0x11, 0x43, 0x0f, + 0x48, 0xbe, 0xad, 0xa3, 0xad, 0xd1, 0x53, 0xf2, 0xa0, 0x53, 0x71, 0xac, + 0x3a, 0xa8, 0x4a, 0x94, 0xdd, 0x17, 0xec, 0x58, 0x6a, 0x06, 0x29, 0x4a, + 0x39, 0xa1, 0x4e, 0x8c, 0xe3, 0x68, 0xa0, 0x16, 0xf1, 0xc6, 0xcd, 0x09, + 0x2e, 0x4a, 0xbe, 0xad, 0xfa, 0x64, 0x01, 0xb8, 0x9a, 0x00, 0xeb, 0xee, + 0x00, 0xe7, 0x7d, 0xfc, 0xa4, 0x28, 0xcc, 0x00, 0x3d, 0x17, 0xc3, 0x9d, + 0x07, 0x95, 0x84, 0xed, 0xb8, 0xb4, 0x07, 0x8b, 0x6b, 0x7e, 0x71, 0xdf, + 0xcb, 0xf2, 0x10, 0x8a, 0x6f, 0xd3, 0x20, 0x0a, 0x14, 0x10, 0x40, 0x4c, + 0x8f, 0xdd, 0xf3, 0xa0, 0x11, 0x73, 0xb9, 0xb0, 0x05, 0x4a, 0xb4, 0x34, + 0x62, 0xb7, 0x36, 0x6c, 0xe3, 0x7c, 0xb2, 0xe0, 0x6a, 0xee, 0xc0, 0x86, + 0x98, 0x5e, 0xe4, 0x25, 0xb7, 0xf2, 0x89, 0x08, 0x3e, 0xf4, 0x55, 0x40, + 0x47, 0xff, 0xd8, 0x27, 0x5d, 0xce, 0x48, 0x08, 0xff, 0xfb, 0xf8, 0x99, + 0xa5, 0x04, 0x94, 0x5b, 0x74, 0x2e, 0x80, 0x1f, 0x00, 0x1b, 0x23, 0xe5, + 0x02, 0x64, 0x76, 0x76, 0xa5, 0x94, 0x4c, 0xcd, 0x2e, 0x12, 0x9b, 0x37, + 0x34, 0x0c, 0x11, 0x4e, 0x0c, 0xbd, 0x0a, 0x17, 0x2e, 0x20, 0xdf, 0xd6, + 0xe6, 0x6d, 0x01, 0x1d, 0x48, 0xdd, 0x4b, 0x00, 0x0f, 0x05, 0x0a, 0xe1, + 0x36, 0x06, 0x42, 0x2c, 0x7c, 0xc0, 0xc1, 0x9e, 0x72, 0x16, 0x18, 0xde, + 0xb0, 0xc6, 0xf6, 0xcf, 0x6f, 0xce, 0x7b, 0x26, 0x4d, 0x4d, 0x7d, 0x18, + 0x55, 0x33, 0x65, 0xbb, 0x14, 0x08, 0x7d, 0xb5, 0xb8, 0xcb, 0x5d, 0xc7, + 0x1b, 0x60, 0xec, 0x99, 0x2c, 0x0e, 0x1e, 0x03, 0x36, 0xeb, 0x48, 0xff, + 0x62, 0x05, 0xb8, 0x58, 0xd4, 0x15, 0x3c, 0xb6, 0xd3, 0xa0, 0xd9, 0xa9, + 0xe2, 0xad, 0x97, 0x90, 0x42, 0xff, 0x5d, 0xbc, 0x20, 0x5e, 0x24, 0x2e, + 0xfa, 0x12, 0x98, 0x87, 0xb5, 0x53, 0x9b, 0x41, 0x22, 0xf4, 0x5f, 0x7c, + 0xef, 0x96, 0xd8, 0x32, 0x4e, 0x9c, 0x62, 0x8d, 0xfd, 0xac, 0x29, 0xbd, + 0x29, 0x19, 0xd3, 0xeb, 0xfd, 0xee, 0xd1, 0x7b, 0x75, 0x64, 0x7c, 0x5c, + 0xd9, 0x92, 0x4a, 0xba, 0x9e, 0x70, 0x9a, 0x90, 0x39, 0xb8, 0x2b, 0x09, + 0xf9, 0x64, 0x09, 0xb1, 0x70, 0xe1, 0xa7, 0x44, 0x3c, 0x21, 0xae, 0x74, + 0xd7, 0x08, 0xce, 0x67, 0x36, 0xd4, 0x3b, 0x69, 0x91, 0xd2, 0x58, 0x7a, + 0xc2, 0x83, 0x94, 0xb6, 0x89, 0x1b, 0x3a, 0x54, 0x56, 0xf4, 0xdc, 0xf6, + 0x15, 0xaf, 0xa2, 0xb2, 0x40, 0x09, 0x6c, 0x31, 0x16, 0xa1, 0xc3, 0xce, + 0x39, 0xb0, 0xe5, 0x79, 0x3d, 0xf5, 0xf2, 0x2f, 0xe9, 0x23, 0xa2, 0xa5, + 0x3c, 0x29, 0xbb, 0x3c, 0xdd, 0x14, 0x2f, 0x71, 0x0b, 0x3b, 0x3c, 0xae, + 0x38, 0xfa, 0x12, 0x35, 0x02, 0x5b, 0x3a, 0xce, 0xd3, 0x8e, 0x8b, 0x02, + 0x43, 0xb0, 0x3e, 0x0f, 0x2a, 0xfa, 0xb4, 0xc8, 0x53, 0x6d, 0xb5, 0x6b, + 0x6d, 0xce, 0xae, 0x5d, 0x18, 0x7c, 0x2d, 0x42, 0x9a, 0xfd, 0xd8, 0xfb, + 0x37, 0x28, 0x4d, 0xa5, 0x9c, 0x15, 0xea, 0xdc, 0x8e, 0xb2, 0xe7, 0x50, + 0xe8, 0x3e, 0x86, 0x8c, 0x21, 0x04, 0xb5, 0xb7, 0x11, 0xf0, 0xb1, 0xc7, + 0x0f, 0x30, 0xf2, 0xda, 0x6b, 0x68, 0xde, 0xcc, 0xf3, 0x72, 0xee, 0xbe, + 0x8e, 0xc2, 0xce, 0x90, 0x90, 0xdc, 0xd1, 0x40, 0x61, 0xd6, 0xdb, 0xb4, + 0xe0, 0xc1, 0xc8, 0xcc, 0x08, 0x60, 0x0b, 0x99, 0xa3, 0x4e, 0xab, 0xa3, + 0x1b, 0x1b, 0xdf, 0xe7, 0x61, 0xc0, 0x3c, 0x33, 0x2c, 0x09, 0x0d, 0x62, + 0x56, 0x2b, 0x76, 0x75, 0x72, 0xda, 0x99, 0x96, 0x8d, 0xb6, 0x16, 0xd8, + 0xf2, 0x9b, 0xce, 0x92, 0x0f, 0x6d, 0x8e, 0x7d, 0xc7, 0x9b, 0x32, 0x0d, + 0x2f, 0x10, 0xb8, 0xa5, 0x9c, 0xce, 0x26, 0x00, 0x1f, 0xfb, 0x48, 0x81, + 0xa6, 0xdc, 0xb9, 0xb3, 0xd4, 0xe6, 0x89, 0x52, 0x94, 0xd9, 0x66, 0xcc, + 0x79, 0x4d, 0xd3, 0x99, 0x67, 0x05, 0xa4, 0x0b, 0x53, 0xdb, 0xd4, 0x80, + 0x37, 0x14, 0xef, 0xaf, 0x5b, 0xc3, 0xbd, 0xf9, 0xca, 0x96, 0xbb, 0x1f, + 0xbc, 0x2d, 0x93, 0x5d, 0x77, 0x28, 0x6a, 0x96, 0xde, 0x9f, 0xe4, 0x47, + 0xbf, 0xfc, 0x01, 0x8f, 0x5f, 0x0e, 0x76, 0xaa, 0x19, 0x86, 0xbd, 0xff, + 0xb1, 0xbe, 0x90, 0xb6, 0xc1, 0x05, 0xf1, 0xbf, 0x1f, 0x1c, 0x00, 0x56, + 0xf9, 0x2e, 0x69, 0x3a, 0xf3, 0xd1, 0x99, 0xa5, 0x87, 0xa8, 0x79, 0x92, + 0x16, 0x10, 0xdc, 0xbd, 0x07, 0x00, 0xe4, 0x84, 0xde, 0x68, 0x89, 0xe5, + 0x57, 0x42, 0x9b, 0xe9, 0x80, 0x14, 0xfc, 0x8a, 0x77, 0x28, 0x2a, 0x3a, + 0x87, 0x4f, 0x37, 0x17, 0x71, 0x12, 0x1b, 0x0e, 0xf5, 0x6e, 0xc8, 0x01, + 0x3f, 0xce, 0x7c, 0x90, 0x26, 0xfb, 0x75, 0xfb, 0xf2, 0x79, 0x92, 0x9b, + 0x13, 0xf0, 0xb6, 0x0f, 0x5b, 0x5b, 0xd9, 0x80, 0x3c, 0xff, 0xe7, 0xc9, + 0x07, 0x7a, 0x9d, 0xc9, 0x40, 0x27, 0x2e, 0x66, 0xdb, 0x51, 0x74, 0xe1, + 0xd5, 0x50, 0xe8, 0xad, 0xee, 0xfe, 0x3f, 0xa2, 0x9e, 0x2c, 0x5e, 0x76, + 0xf7, 0xc0, 0x1e, 0x73, 0x39, 0xc7, 0xc8, 0x90, 0x38, 0x3a, 0xad, 0x44, + 0x38, 0x31, 0xbc, 0xde, 0xc4, 0x0a, 0xb8, 0x55, 0x2c, 0x34, 0xe8, 0x8d, + 0xca, 0xe7, 0x70, 0x88, 0x58, 0x5b, 0x7f, 0x34, 0x00, 0x78, 0x23, 0x90, + 0x03, 0x5e, 0xfd, 0xe7, 0xce, 0x5a, 0x4d, 0xe6, 0xbf, 0x76, 0xed, 0xa6, + 0x17, 0x87, 0x7a, 0x1c, 0xdd, 0xd0, 0x04, 0xd8, 0x29, 0xfb, 0x5f, 0xc6, + 0xec, 0x85, 0x2f, 0x96, 0xd5, 0xf2, 0x0b, 0xc0, 0xc6, 0xbb, 0xe8, 0x47, + 0x70, 0x03, 0xa2, 0x27, 0xba, 0xc1, 0x38, 0xaa, 0x66, 0x13, 0x95, 0x64, + 0xb1, 0x69, 0x41, 0x10, 0xb6, 0xf8, 0xb7, 0xb8, 0x8a, 0x46, 0xaf, 0x93, + 0xe3, 0x61, 0xf3, 0x97, 0x73, 0x1e, 0x67, 0x9c, 0x3a, 0xc5, 0x68, 0x7b, + 0xb8, 0xe9, 0x54, 0xa1, 0xb4, 0x04, 0x4d, 0xcd, 0x33, 0x31, 0x16, 0x46, + 0xfe, 0xd4, 0x00, 0xe9, 0xdc, 0x7c, 0x08, 0x7e, 0xe4, 0xbb, 0x52, 0x07, + 0xea, 0x54, 0x92, 0x0d, 0x6f, 0x0f, 0x7b, 0xc7, 0x6f, 0x4e, 0xeb, 0x50, + 0x11, 0xff, 0xef, 0x74, 0xcc, 0x43, 0xce, 0xaa, 0xdc, 0x91, 0x41, 0xc2, + 0xc8, 0xb3, 0x71, 0x00, 0x8c, 0x9d, 0xed, 0xc9, 0x10, 0xea, 0x6a, 0xe4, + 0x5a, 0x18, 0xdc, 0x20, 0x0a, 0x3a, 0xf6, 0x7f, 0x0e, 0xa2, 0x5c, 0x3b, + 0x76, 0xcc, 0xab, 0x2c, 0x4a, 0x50, 0x6f, 0x83, 0x79, 0xfc, 0x8a, 0x9e, + 0x4e, 0x8e, 0x74, 0xa1, 0x35, 0x5b, 0x33, 0x11, 0x12, 0x37, 0xd7, 0x00, + 0x40, 0xff, 0x79, 0xa2, 0x1d, 0x5d, 0x5d, 0x2a, 0xd9, 0x5e, 0xe3, 0x0d, + 0xa1, 0x6d, 0xf6, 0x00, 0x05, 0xdf, 0x34, 0x01, 0xb8, 0x03, 0xce, 0x6f, + 0x7d, 0x82, 0x47, 0xfe, 0x38, 0xda, 0x62, 0x1f, 0x0b, 0x81, 0xad, 0xf0, + 0xbe, 0xbe, 0xff, 0x22, 0x44, 0xed, 0xdf, 0x83, 0x16, 0xd8, 0xe7, 0x66, + 0xa1, 0x86, 0xdf, 0xca, 0x25, 0x28, 0xf8, 0xdf, 0x5c, 0x9f, 0x5e, 0xff, + 0xe2, 0xb7, 0xae, 0xf9, 0xe6, 0x8d, 0x2a, 0xd5, 0x36, 0x40, 0xc6, 0xf6, + 0x36, 0xbf, 0x97, 0xc3, 0x6e, 0x96, 0x4a, 0x6d, 0xa0, 0x7d, 0x8a, 0x4a, + 0x60, 0x00, 0x00, 0x01, 0x0d, 0x43, 0xf7, 0xdd, 0x8a, 0x78, 0x80, 0x06, + 0xc0, 0x0d, 0x05, 0x73, 0x52, 0x25, 0x20, 0x02, 0x10, 0x03, 0xf7, 0x2b, + 0x8d, 0x50, 0xea, 0x6d, 0xa5, 0x95, 0x43, 0x65, 0x6f, 0x4c, 0x00, 0xf8, + 0x5b, 0x80, 0x1b, 0x77, 0xcf, 0xcd, 0xdc, 0xa3, 0xe7, 0x9f, 0x0b, 0x24, + 0x3a, 0xfe, 0xa5, 0x29, 0x43, 0x1a, 0x10, 0x34, 0x89, 0xcd, 0xde, 0x5f, + 0xc5, 0xa7, 0x77, 0x37, 0xc9, 0x21, 0x8a, 0x61, 0xc1, 0x2d, 0xf3, 0xe0, + 0x07, 0xc0, 0x0d, 0x78, 0xe7, 0xe4, 0x88, 0xff, 0x6f, 0x68, 0x85, 0xf9, + 0x3e, 0x6d, 0x96, 0x6e, 0x2a, 0x40, 0xe9, 0x21, 0x77, 0xc1, 0xbc, 0x34, + 0xfc, 0x56, 0xe7, 0x96, 0x64, 0xb2, 0xac, 0xa5, 0x8e, 0x52, 0x82, 0x02, + 0x5b, 0xf8, 0x7d, 0xcb, 0xe7, 0x95, 0x60, 0x62, 0x4b, 0x2c, 0x21, 0x56, + 0xd9, 0x06, 0xd6, 0xfa, 0xb0, 0x02, 0x1c, 0x80, 0x09, 0x1c, 0x28, 0x89, + 0xf5, 0x10, 0xf8, 0x1d, 0x67, 0x7c, 0xf6, 0xee, 0xa4, 0x35, 0xda, 0x5e, + 0x54, 0x1c, 0xa3, 0x61, 0x4d, 0x98, 0x10, 0x3f, 0x4b, 0xf9, 0xa0, 0x0f, + 0xfe, 0x33, 0x3d, 0x88, 0xf9, 0x46, 0x49, 0xdb, 0xf2, 0x24, 0xe3, 0x4b, + 0xb8, 0xaa, 0xd9, 0xc2, 0xe2, 0x94, 0xde, 0x7b, 0xe1, 0xcd, 0xf1, 0x80, + 0x1c, 0x8a, 0xec, 0x01, 0x0f, 0xf0, 0x43, 0xb5, 0xd8, 0x1b, 0x39, 0x9d, + 0x87, 0x28, 0x0a, 0xa8, 0xdf, 0x46, 0xfb, 0x7f, 0x7e, 0x77, 0xfe, 0x40, + 0x31, 0xf4, 0x63, 0xae, 0x3b, 0xf3, 0x77, 0xc1, 0x0a, 0x40, 0xb6, 0xfa, + 0x37, 0xf7, 0xe7, 0xbf, 0xa8, 0x03, 0x71, 0x62, 0x44, 0xe8, 0x62, 0x6b, + 0xd4, 0x39, 0x3f, 0x08, 0x98, 0x32, 0x48, 0xdf, 0x3f, 0xfe, 0x0b, 0x00, + 0x10, 0x67, 0x57, 0x66, 0x0c, 0xa5, 0xe1, 0x65, 0x9e, 0xd3, 0x23, 0xba, + 0xe5, 0xf6, 0xda, 0x02, 0x29, 0x0b, 0x6b, 0xdb, 0x31, 0xf4, 0xbf, 0x06, + 0xfe, 0x5f, 0xdf, 0xbe, 0xfd, 0xb2, 0x75, 0xd6, 0xd4, 0x2d, 0x65, 0x88, + 0x89, 0xe8, 0xde, 0x08, 0x00, 0xf5, 0xe2, 0x3d, 0x9c, 0xfe, 0x79, 0xc9, + 0x13, 0xf0, 0xee, 0xe0, 0xea, 0x03, 0x56, 0xfa, 0x3f, 0xd5, 0xc0, 0x82, + 0x02, 0x7e, 0xdc, 0x9a, 0x5c, 0x39, 0x49, 0xf9, 0x21, 0xdb, 0x25, 0x2e, + 0x0d, 0x6f, 0x8d, 0x75, 0x67, 0x44, 0x0e, 0x6a, 0x84, 0x3d, 0x72, 0x98, + 0x38, 0xe1, 0xc3, 0x5b, 0x93, 0x78, 0x82, 0x66, 0xbb, 0x89, 0x83, 0xe2, + 0x5c, 0x6c, 0x2c, 0x34, 0xa8, 0xda, 0x11, 0x45, 0xe0, 0x87, 0x53, 0x2b, + 0x8e, 0x53, 0x35, 0x15, 0x2a, 0x1c, 0x1a, 0x90, 0xe6, 0xa3, 0xfb, 0xb6, + 0xed, 0xb6, 0x00, 0x46, 0x5d, 0x28, 0x28, 0x31, 0xbd, 0x8e, 0x77, 0x78, + 0xa2, 0xf5, 0xd8, 0x17, 0x69, 0xcd, 0xe0, 0x3e, 0xd2, 0xfd, 0x51, 0x20, + 0x5e, 0xcd, 0xca, 0xa8, 0x71, 0x68, 0xde, 0x97, 0xee, 0xb6, 0x92, 0x14, + 0x5b, 0x76, 0xce, 0x9d, 0xc0, 0x9d, 0x57, 0x00, 0xaa, 0xa0, 0xd8, 0x31, + 0xbc, 0xe0, 0xa9, 0x38, 0xe1, 0xda, 0x50, 0x48, 0xc8, 0xad, 0xf4, 0x0e, + 0x45, 0xe6, 0xfd, 0x26, 0xc7, 0xe1, 0x55, 0x1e, 0xb5, 0xd9, 0xa1, 0xd4, + 0x3c, 0x7c, 0x94, 0xa3, 0xda, 0x00, 0x27, 0xf9, 0xf6, 0xfa, 0x8a, 0x23, + 0x77, 0x5f, 0x14, 0x11, 0x00, 0x13, 0xae, 0xc8, 0x84, 0x7e, 0xf8, 0x8e, + 0x81, 0x1b, 0xc6, 0xae, 0xc8, 0x34, 0xa2, 0x8b, 0x6a, 0x44, 0x18, 0xda, + 0x13, 0x65, 0x6f, 0xe6, 0xe0, 0x38, 0xdb, 0x23, 0x6d, 0xd2, 0xe0, 0x16, + 0xd9, 0x3d, 0xdd, 0x08, 0x12, 0x3b, 0x68, 0x69, 0xb6, 0x8f, 0x2d, 0xb7, + 0xda, 0xaf, 0xb4, 0xc0, 0x82, 0xc6, 0x34, 0x51, 0xa4, 0xa6, 0x34, 0xaa, + 0xde, 0xde, 0xcc, 0x32, 0xcb, 0x35, 0x06, 0xd8, 0x55, 0x42, 0xd4, 0x7b, + 0x75, 0xbe, 0x94, 0x02, 0xdf, 0x99, 0x5e, 0xfc, 0x0c, 0x8e, 0xda, 0x52, + 0xd0, 0xc5, 0xb1, 0xb9, 0xe4, 0x68, 0xff, 0x97, 0xdd, 0x2c, 0xe5, 0x5d, + 0xdf, 0x27, 0x2c, 0xc2, 0xce, 0x3e, 0xb6, 0xbe, 0xb9, 0xbe, 0xde, 0xd8, + 0xee, 0x02, 0x6c, 0xc9, 0x0a, 0x83, 0x21, 0x50, 0x73, 0x73, 0xd3, 0x64, + 0x96, 0x46, 0x76, 0xa5, 0x6f, 0xde, 0xdb, 0xa4, 0x7f, 0x8f, 0x67, 0x6d, + 0xa3, 0xd2, 0xb8, 0x47, 0x75, 0xca, 0x02, 0x27, 0x48, 0x88, 0xdc, 0xdc, + 0xc9, 0x74, 0x5a, 0x84, 0x7e, 0x04, 0xf6, 0x28, 0x5d, 0xc1, 0xb0, 0xe9, + 0x69, 0x96, 0x84, 0x94, 0xc9, 0xec, 0x08, 0x5f, 0xe3, 0xc7, 0x3d, 0x6e, + 0xd3, 0xca, 0xd0, 0x33, 0x1f, 0x80, 0x03, 0x57, 0x4d, 0x8a, 0x13, 0x2b, + 0x55, 0x2c, 0xe3, 0x9e, 0xa9, 0x0f, 0x8d, 0xf6, 0xd5, 0x5a, 0xb4, 0xb9, + 0xc3, 0xa9, 0xc1, 0x0d, 0xea, 0x48, 0x6a, 0x92, 0x5b, 0xd5, 0x81, 0xf3, + 0x49, 0x2d, 0xd1, 0x51, 0xe0, 0x07, 0x06, 0xe2, 0x01, 0x08, 0x40, 0x17, + 0x28, 0xf3, 0xb6, 0xad, 0x24, 0xb2, 0xc3, 0x48, 0xfe, 0x7a, 0x58, 0x0a, + 0xdd, 0xd7, 0x25, 0x78, 0xe2, 0xab, 0x68, 0x11, 0xcb, 0xc5, 0x73, 0x56, + 0x3c, 0xc5, 0x49, 0x1d, 0xdf, 0x6f, 0xdb, 0x03, 0x52, 0xdd, 0x90, 0xa9, + 0x47, 0x4b, 0x5a, 0xb7, 0x61, 0x02, 0xfd, 0x1d, 0xde, 0x84, 0x95, 0x9b, + 0xd6, 0x5b, 0x4a, 0x42, 0xd1, 0x17, 0xc5, 0xae, 0x94, 0xda, 0xc6, 0xeb, + 0x9c, 0xc1, 0x74, 0x54, 0xcc, 0x2c, 0x62, 0xef, 0x12, 0xc2, 0xcf, 0x19, + 0x46, 0x9e, 0x1a, 0xcb, 0x0d, 0xe3, 0xe4, 0x46, 0x98, 0x78, 0xe1, 0x4e, + 0xb3, 0x74, 0x69, 0x34, 0xaa, 0xa8, 0xc7, 0x9e, 0x70, 0x89, 0x9e, 0xd3, + 0x9b, 0x46, 0xd5, 0x82, 0x7a, 0xb9, 0xe6, 0x30, 0xe0, 0xca, 0xd8, 0xdc, + 0x67, 0x0e, 0xce, 0x27, 0x8e, 0x45, 0x7f, 0xa2, 0xd2, 0x9a, 0x0e, 0x6a, + 0x3e, 0x37, 0xae, 0x13, 0xb6, 0xdf, 0x2c, 0xc8, 0x33, 0xf1, 0x9b, 0x4b, + 0xa1, 0x6c, 0x65, 0x33, 0x87, 0xc4, 0x81, 0x17, 0xb7, 0xe9, 0xe7, 0x0d, + 0x90, 0x61, 0x25, 0xab, 0x7d, 0xcd, 0x49, 0x29, 0x43, 0x25, 0x3b, 0x0b, + 0x83, 0x8f, 0x24, 0x35, 0x7c, 0x4d, 0xd7, 0xee, 0x94, 0x36, 0xc9, 0xae, + 0x86, 0x95, 0x4b, 0xa5, 0x9e, 0x30, 0x35, 0x6b, 0x45, 0x6b, 0x6e, 0xe7, + 0x5d, 0xd8, 0x03, 0x9b, 0x4e, 0x5b, 0xb2, 0xd3, 0x90, 0x86, 0xd5, 0xed, + 0x91, 0x40, 0xea, 0xa3, 0x9b, 0x35, 0x48, 0x92, 0xc0, 0x82, 0xda, 0xf9, + 0xf9, 0xd3, 0xc0, 0x22, 0xf5, 0x3d, 0x86, 0xb6, 0xe5, 0xc5, 0xb8, 0x68, + 0x52, 0x1a, 0x74, 0x39, 0x97, 0x9e, 0x88, 0x3e, 0xd9, 0xbc, 0xc5, 0x29, + 0x2e, 0x49, 0x4c, 0xcb, 0x42, 0x62, 0x95, 0x68, 0x53, 0x73, 0xfa, 0x97, + 0x8e, 0xe4, 0xdf, 0x49, 0x14, 0x34, 0x31, 0xba, 0x3f, 0x4e, 0xb0, 0x01, + 0xc8, 0x9c, 0x27, 0xe9, 0x65, 0x07, 0xf4, 0x56, 0x13, 0xa8, 0x0a, 0xdf, + 0x43, 0x4e, 0x0b, 0x68, 0x1a, 0x53, 0x73, 0xf0, 0x06, 0x35, 0x6f, 0xa3, + 0x7f, 0x47, 0x00, 0x5a, 0x01, 0x67, 0xdc, 0x8a, 0xef, 0x8d, 0x10, 0xf3, + 0xa4, 0xb8, 0x41, 0x73, 0xe7, 0x98, 0xd3, 0xa6, 0x15, 0x61, 0x43, 0xea, + 0xb7, 0x98, 0x12, 0xe0, 0x01, 0x0f, 0xb0, 0x8e, 0x5f, 0xe1, 0x38, 0x93, + 0x09, 0x46, 0x36, 0x0f, 0x6c, 0x98, 0x47, 0xd8, 0xfd, 0xc1, 0xf6, 0xbb, + 0x0c, 0x33, 0x4a, 0x1e, 0x32, 0x8e, 0x39, 0xbb, 0x80, 0x0f, 0x28, 0xb0, + 0x06, 0x20, 0x0f, 0xf8, 0xe2, 0x71, 0xb0, 0x75, 0xd2, 0x75, 0xd7, 0x24, + 0x0f, 0xa5, 0xc2, 0xa1, 0x51, 0xb9, 0xf2, 0xf9, 0x49, 0x29, 0x29, 0xbc, + 0x5c, 0x86, 0x61, 0x4d, 0xfb, 0x01, 0x5c, 0x00, 0x19, 0x77, 0xdf, 0x29, + 0x81, 0xa6, 0xb9, 0xf2, 0x4c, 0x5f, 0x16, 0xf9, 0x5c, 0x81, 0xdd, 0x6d, + 0xf1, 0x5c, 0xca, 0x43, 0xb2, 0x29, 0x29, 0xbe, 0x9e, 0x00, 0xd8, 0x58, + 0x20, 0x80, 0xb7, 0x06, 0x91, 0xc9, 0xd0, 0x67, 0x13, 0x6f, 0x16, 0x3a, + 0xc2, 0x6d, 0x01, 0xc8, 0xf4, 0x28, 0x6b, 0x7c, 0xaf, 0x8b, 0x75, 0xdf, + 0x17, 0x9c, 0x09, 0xb9, 0xcf, 0x95, 0x40, 0x11, 0x5d, 0xb0, 0xa8, 0xd8, + 0xec, 0x3f, 0x00, 0x06, 0x4a, 0xd9, 0x50, 0xd6, 0xfd, 0x57, 0xbc, 0xde, + 0xb9, 0xc7, 0xae, 0x06, 0x6c, 0x55, 0xcb, 0x02, 0x2c, 0x2d, 0xbe, 0x82, + 0x00, 0xec, 0x50, 0x01, 0xd3, 0xbb, 0x27, 0x9a, 0x3e, 0xf6, 0xf1, 0x3b, + 0xa1, 0xf9, 0x4a, 0xc3, 0xa2, 0xc9, 0x32, 0x14, 0x3d, 0xbc, 0xe7, 0xc6, + 0xf3, 0xfe, 0x82, 0x9d, 0xcb, 0xdc, 0x59, 0x30, 0xcd, 0xdb, 0xae, 0x1e, + 0x9e, 0x45, 0xc0, 0xf8, 0x30, 0x9a, 0xdd, 0xbf, 0xf6, 0x75, 0xf5, 0xbc, + 0x0a, 0xe3, 0x32, 0x1d, 0x26, 0xdb, 0x15, 0xc8, 0x7a, 0xac, 0x1b, 0x42, + 0x9b, 0xcc, 0xb8, 0xa7, 0x27, 0x80, 0x1e, 0xd9, 0x86, 0xc6, 0xf8, 0x7f, + 0x5f, 0x8e, 0x5f, 0xc0, 0xa1, 0x3b, 0x47, 0x57, 0x6b, 0xb2, 0xec, 0x83, + 0x8f, 0x80, 0x72, 0x36, 0xe0, 0x05, 0xe0, 0x0f, 0x2e, 0x91, 0xfc, 0x9e, + 0xeb, 0x95, 0x51, 0xfb, 0x62, 0xdc, 0xcb, 0x69, 0x90, 0xbd, 0x18, 0xad, + 0x8b, 0x8d, 0x70, 0x02, 0x69, 0xc7, 0x02, 0xdd, 0x40, 0x7b, 0x16, 0x2a, + 0xc4, 0x32, 0x1e, 0x50, 0xc0, 0xa8, 0xde, 0xa8, 0x00, 0xab, 0x6f, 0xf7, + 0xb1, 0x7d, 0x8a, 0x96, 0x8f, 0x86, 0xf3, 0xce, 0xe9, 0x65, 0x5a, 0x85, + 0xd5, 0x28, 0x96, 0xda, 0xda, 0x9b, 0x61, 0x4c, 0xee, 0x96, 0xdf, 0x9d, + 0xe8, 0xd0, 0x02, 0x87, 0x6a, 0xf7, 0x46, 0xae, 0xe8, 0xbd, 0xde, 0x70, + 0xb1, 0x9e, 0x5f, 0xa8, 0xbe, 0x2d, 0xe3, 0xdf, 0x79, 0xfe, 0xce, 0x11, + 0xc1, 0x92, 0xd7, 0xa2, 0x78, 0xa9, 0xde, 0x2d, 0xf4, 0x37, 0x89, 0x80, + 0x82, 0x02, 0xbb, 0xce, 0xc7, 0x58, 0x4c, 0xb2, 0x3d, 0x33, 0x24, 0xa1, + 0x11, 0x0a, 0x81, 0x4c, 0xbf, 0xdd, 0x84, 0x4f, 0x7e, 0xf4, 0x5b, 0xe2, + 0x2c, 0xb8, 0x66, 0x6d, 0x86, 0x60, 0xf0, 0x89, 0x1b, 0x1e, 0x83, 0xae, + 0x69, 0x0a, 0xb3, 0x85, 0x40, 0x2d, 0xbe, 0x98, 0xbe, 0xef, 0xc7, 0x2f, + 0x9f, 0x3d, 0xdd, 0xd3, 0xb8, 0xd9, 0x29, 0x86, 0x5b, 0xb4, 0x7e, 0x53, + 0x92, 0x28, 0xe6, 0xf2, 0xdf, 0x4e, 0x34, 0x01, 0xac, 0xf8, 0x9f, 0x99, + 0xfb, 0xdd, 0xd4, 0x95, 0x6e, 0xd2, 0xc9, 0xa7, 0xa0, 0xd6, 0xe7, 0x11, + 0x26, 0xfd, 0xc8, 0xc2, 0x05, 0xfb, 0x60, 0x6e, 0x65, 0x7e, 0x5b, 0xbb, + 0x20, 0x61, 0x69, 0x5b, 0x38, 0x03, 0x17, 0x71, 0xf4, 0xf7, 0xdc, 0x0f, + 0x87, 0xad, 0xce, 0x7a, 0x90, 0xd4, 0x0d, 0xc9, 0x62, 0xf8, 0xb7, 0x4f, + 0x12, 0xb9, 0xd9, 0xb2, 0x84, 0xa4, 0x58, 0x42, 0x69, 0x18, 0x05, 0x30, + 0x00, 0x00, 0x01, 0x0e, 0x43, 0xfa, 0xd0, 0x87, 0x4c, 0x11, 0xbc, 0xe4, + 0x90, 0xb2, 0xea, 0x14, 0x60, 0x5b, 0x78, 0x70, 0x02, 0x7e, 0x7a, 0x00, + 0x75, 0xd1, 0x02, 0xef, 0x35, 0x60, 0x22, 0x00, 0x26, 0x5b, 0x8f, 0xbb, + 0x80, 0x60, 0xc3, 0x14, 0xc3, 0xe1, 0x61, 0x81, 0x8d, 0xed, 0x7e, 0xa0, + 0x16, 0x00, 0x2d, 0x23, 0x5d, 0xe9, 0x2d, 0x2a, 0xae, 0x75, 0xa0, 0x66, + 0xcb, 0x2a, 0x16, 0x59, 0x29, 0xbb, 0x82, 0x78, 0xe7, 0x3d, 0xf8, 0x00, + 0xb2, 0x55, 0xab, 0x86, 0x3e, 0x1f, 0x1f, 0x4a, 0x91, 0x14, 0x69, 0x6d, + 0xf3, 0x59, 0x24, 0xd3, 0x2d, 0x21, 0x9c, 0xde, 0x45, 0x95, 0xf5, 0x27, + 0x82, 0xc6, 0xf5, 0x72, 0xed, 0x00, 0x2f, 0x79, 0x16, 0x41, 0x7c, 0xdf, + 0xdd, 0xef, 0x34, 0xcb, 0x84, 0x13, 0x09, 0xee, 0x8b, 0x92, 0xcb, 0x5d, + 0xe4, 0xa8, 0x72, 0xb7, 0xbf, 0xb5, 0xdb, 0xc4, 0x55, 0x83, 0x2e, 0xab, + 0xd6, 0x50, 0x11, 0x01, 0xed, 0xc5, 0xb6, 0x80, 0x5b, 0x65, 0xb4, 0xb4, + 0x59, 0x9b, 0x91, 0x14, 0x9b, 0x4b, 0xb4, 0xf2, 0xdb, 0xad, 0x9b, 0xb5, + 0xf2, 0x05, 0x98, 0x52, 0x4b, 0xfa, 0x18, 0x59, 0xde, 0xad, 0xb3, 0xa7, + 0x9a, 0x18, 0xa4, 0x86, 0xf4, 0x23, 0x7d, 0x0c, 0x5c, 0x2d, 0x03, 0x29, + 0x71, 0x65, 0x18, 0x43, 0x6f, 0x2c, 0x00, 0xb7, 0xe7, 0xcb, 0x24, 0xcc, + 0x71, 0x63, 0x4a, 0x1a, 0xde, 0x96, 0x48, 0xbb, 0x2e, 0x51, 0xb5, 0x21, + 0x85, 0xca, 0x49, 0x6c, 0x79, 0x2e, 0xba, 0x47, 0x5b, 0x07, 0x87, 0xd8, + 0x50, 0x61, 0x43, 0xeb, 0x68, 0xfe, 0x77, 0x87, 0x67, 0x94, 0xf0, 0xa7, + 0xd4, 0xac, 0xae, 0xdc, 0x85, 0x4f, 0x56, 0xfc, 0x08, 0x03, 0x59, 0x00, + 0x1e, 0x6f, 0xff, 0x79, 0xe2, 0x04, 0x08, 0x22, 0x67, 0x2b, 0x40, 0x4b, + 0x69, 0xbc, 0xac, 0x41, 0xd0, 0x3e, 0xb7, 0xe3, 0x8f, 0xaf, 0x0f, 0x22, + 0x66, 0x9a, 0x65, 0x83, 0x53, 0x2a, 0x12, 0x4a, 0x6f, 0xe8, 0x24, 0xc7, + 0x67, 0x7e, 0x56, 0xed, 0x43, 0xab, 0xdc, 0x1c, 0xa4, 0x30, 0xe8, 0xdf, + 0x9c, 0xc0, 0x14, 0x13, 0xc0, 0x16, 0x0a, 0xb7, 0x9e, 0xf6, 0xd1, 0xaa, + 0x23, 0x2d, 0xd3, 0x0e, 0xb4, 0x38, 0x64, 0x81, 0x2d, 0xc8, 0xe8, 0x01, + 0x66, 0xc9, 0x7c, 0x57, 0xc4, 0xf6, 0xe6, 0x52, 0x75, 0x02, 0xdb, 0xfc, + 0xdb, 0xf0, 0x23, 0x05, 0xab, 0xd0, 0x32, 0x1c, 0x69, 0xde, 0x0c, 0x04, + 0xd0, 0x0b, 0x5f, 0x35, 0x60, 0x0a, 0x83, 0xa1, 0x94, 0x2c, 0xb3, 0xa3, + 0x7b, 0x5f, 0xae, 0xe8, 0x94, 0xe3, 0x16, 0x0d, 0x2e, 0x42, 0xd2, 0x86, + 0x41, 0x8d, 0xc7, 0x71, 0x3f, 0xe3, 0xbe, 0x0d, 0xa5, 0x8c, 0x2a, 0xc9, + 0x43, 0x1b, 0x47, 0x2d, 0xe3, 0x2d, 0x94, 0x30, 0x2d, 0xb3, 0x95, 0x4f, + 0x6f, 0x73, 0xf3, 0x5f, 0xf7, 0x22, 0x0a, 0xee, 0x65, 0x3b, 0x03, 0xf9, + 0x17, 0x7a, 0xd4, 0xa3, 0x13, 0x39, 0xb1, 0x55, 0x47, 0x16, 0xdc, 0xc1, + 0x55, 0xff, 0x41, 0x1d, 0x70, 0x4f, 0x09, 0xd8, 0x28, 0x53, 0x9c, 0x48, + 0x89, 0x14, 0x32, 0x37, 0xbb, 0x11, 0x1c, 0x00, 0xe5, 0xff, 0xfe, 0x32, + 0x4a, 0x52, 0x9b, 0xc7, 0xdb, 0xda, 0x89, 0x36, 0xe0, 0xd3, 0x62, 0x55, + 0xb3, 0x46, 0xa0, 0xda, 0x31, 0xbe, 0x6e, 0x47, 0xf6, 0x76, 0xe6, 0x6e, + 0x65, 0xc3, 0x91, 0x75, 0x0d, 0x44, 0x08, 0x6d, 0x31, 0x34, 0xc2, 0xe0, + 0x04, 0x55, 0xad, 0x47, 0x90, 0x9b, 0xed, 0x09, 0x15, 0x08, 0xdc, 0xfc, + 0xd9, 0x9c, 0xf9, 0x97, 0x2c, 0xe7, 0xbc, 0x97, 0x75, 0xd1, 0xc9, 0x61, + 0x6a, 0x85, 0xd6, 0xf2, 0xd5, 0x04, 0x0b, 0xa6, 0x37, 0xa5, 0x76, 0x52, + 0x2f, 0x6e, 0x16, 0xe9, 0xe9, 0x4b, 0x40, 0xb6, 0xcc, 0x2d, 0x7e, 0xc4, + 0x61, 0x4f, 0x7d, 0xa0, 0x93, 0xff, 0x85, 0x81, 0xca, 0x16, 0xd9, 0x3a, + 0x1b, 0xb9, 0x64, 0x0a, 0xab, 0x63, 0x67, 0x90, 0xe6, 0xfc, 0xc3, 0xa5, + 0x17, 0x12, 0x10, 0xd0, 0x90, 0xde, 0x84, 0xd3, 0x79, 0x0e, 0xc0, 0xb9, + 0x46, 0x8c, 0x64, 0x00, 0x7f, 0x27, 0x5f, 0x3a, 0x57, 0x86, 0x8f, 0x6a, + 0x37, 0x2e, 0xf5, 0x29, 0x41, 0x11, 0x10, 0xe2, 0x9b, 0x59, 0x67, 0x92, + 0x56, 0xb3, 0xa2, 0x5f, 0x56, 0xfd, 0x4c, 0xda, 0x47, 0xf3, 0x87, 0x82, + 0x38, 0x01, 0xc5, 0xcb, 0x76, 0x80, 0x8a, 0xc3, 0x7c, 0x22, 0xb6, 0xaf, + 0x70, 0x42, 0x00, 0x8d, 0x7b, 0xac, 0x0a, 0x00, 0xa8, 0xce, 0xaa, 0x84, + 0xa9, 0x97, 0xd0, 0xb8, 0xd9, 0xf4, 0x10, 0xbf, 0xc4, 0x02, 0xaa, 0x58, + 0x24, 0xff, 0xde, 0x79, 0x96, 0x12, 0x92, 0xd2, 0x53, 0x77, 0x72, 0xd7, + 0x60, 0x9b, 0x3d, 0x3d, 0xb7, 0x5e, 0x9e, 0x0f, 0xb8, 0x00, 0x30, 0x56, + 0xe8, 0x80, 0x85, 0xff, 0x53, 0x40, 0xe6, 0xef, 0x80, 0x85, 0xff, 0x53, + 0x40, 0xe2, 0x43, 0x7e, 0x50, 0xa0, 0x07, 0xd7, 0x39, 0xa8, 0x13, 0xa2, + 0x6e, 0x3a, 0xf8, 0x99, 0x97, 0x03, 0x06, 0xd6, 0xeb, 0x60, 0x7e, 0xe3, + 0xad, 0xa1, 0x92, 0x81, 0x9b, 0x20, 0x5d, 0xc5, 0x02, 0x9b, 0x9e, 0x5f, + 0x1b, 0xd4, 0xce, 0x22, 0x17, 0x65, 0x00, 0x3d, 0xef, 0xe6, 0x49, 0x60, + 0x65, 0xb2, 0x2f, 0x8a, 0x63, 0x5f, 0x96, 0xd0, 0xfb, 0x43, 0x0b, 0xee, + 0xa6, 0x6a, 0x9c, 0x58, 0xd0, 0xd3, 0x9b, 0x73, 0x9b, 0xb0, 0xf0, 0x39, + 0xbc, 0xe2, 0x4c, 0xfb, 0x91, 0x84, 0x57, 0x48, 0x11, 0x6d, 0xba, 0x1b, + 0x43, 0xc3, 0xda, 0x77, 0x60, 0x89, 0xed, 0x74, 0xf0, 0x1e, 0xf5, 0xce, + 0x07, 0x00, 0x89, 0x06, 0xd3, 0xbc, 0x1b, 0xa2, 0x21, 0x3f, 0xe2, 0x7a, + 0x2b, 0xc3, 0x21, 0x72, 0x9c, 0xd5, 0xbf, 0x00, 0x2a, 0x13, 0xc6, 0xad, + 0x18, 0xaa, 0x61, 0x84, 0x34, 0x28, 0x94, 0xd0, 0xda, 0xd2, 0xdb, 0xc7, + 0xcc, 0x59, 0x72, 0x18, 0x30, 0x68, 0xca, 0x12, 0x8d, 0x5b, 0x83, 0xe6, + 0xe8, 0xc0, 0xca, 0x64, 0x08, 0x2d, 0x15, 0xb6, 0xee, 0xe3, 0xb8, 0x20, + 0xcd, 0xa1, 0x98, 0xb5, 0x03, 0x69, 0x34, 0x35, 0xb1, 0x3f, 0x26, 0xe4, + 0xa5, 0x85, 0x5b, 0x28, 0x0d, 0x58, 0x60, 0x73, 0x76, 0x6a, 0x9b, 0x69, + 0x09, 0xb9, 0x12, 0x63, 0x9d, 0x10, 0x87, 0x4e, 0xf5, 0x6d, 0x99, 0x27, + 0xb3, 0xf2, 0xa3, 0x73, 0xe2, 0xe4, 0xcd, 0x84, 0x35, 0x91, 0x91, 0xf1, + 0x83, 0x9b, 0xba, 0x47, 0xce, 0x31, 0xfe, 0x74, 0x74, 0x4b, 0xb2, 0x25, + 0x38, 0x71, 0xea, 0xdc, 0xc5, 0xb3, 0xdc, 0x0c, 0x41, 0xf4, 0x3a, 0x48, + 0x54, 0x3e, 0x9e, 0x36, 0xd6, 0xe9, 0x5a, 0x6c, 0x75, 0x50, 0x95, 0x83, + 0x7d, 0x5b, 0x6f, 0xde, 0x9b, 0x1c, 0x20, 0x56, 0x40, 0x1e, 0x3d, 0xf8, + 0xff, 0xcb, 0xa1, 0xde, 0x2a, 0xd9, 0xe4, 0x36, 0x65, 0x2f, 0xc2, 0xb7, + 0x87, 0x03, 0x8c, 0x00, 0x18, 0x37, 0x85, 0xe2, 0xbc, 0xfa, 0xe9, 0xcf, + 0xe3, 0x81, 0x98, 0x6d, 0x43, 0x31, 0x10, 0x79, 0x0d, 0xbe, 0x89, 0xf7, + 0xf9, 0x23, 0x7b, 0x91, 0xb1, 0xef, 0xe6, 0x3e, 0x17, 0x45, 0x73, 0x9b, + 0x09, 0xb2, 0x51, 0xd4, 0x61, 0x2d, 0xbc, 0x3f, 0xc7, 0x52, 0x2e, 0xee, + 0x8f, 0xba, 0x56, 0x64, 0x91, 0x0a, 0x38, 0x07, 0xb6, 0xd5, 0x6d, 0xcf, + 0x33, 0xe7, 0xdb, 0xdb, 0x65, 0x43, 0xae, 0x65, 0x0e, 0xdb, 0x6c, 0xa9, + 0x4e, 0xd3, 0x8a, 0x28, 0x63, 0x73, 0x5a, 0x4e, 0x29, 0x42, 0x56, 0x36, + 0x4d, 0xfb, 0xa0, 0x06, 0x3e, 0xd0, 0x8d, 0xf5, 0x76, 0xa7, 0x32, 0x95, + 0x09, 0xd5, 0xee, 0xdc, 0x57, 0x80, 0xac, 0x34, 0x63, 0x0f, 0xf8, 0x03, + 0x51, 0x1f, 0x3d, 0x3b, 0x9e, 0x74, 0x53, 0xec, 0x0f, 0x9c, 0x08, 0xde, + 0x03, 0xc9, 0xf6, 0x16, 0xb1, 0x54, 0xa4, 0x3c, 0x39, 0x8e, 0x7c, 0x8a, + 0x00, 0x45, 0xef, 0x1e, 0x47, 0xe2, 0xf1, 0x88, 0xee, 0x2e, 0x51, 0x77, + 0x9f, 0x2c, 0x7e, 0x97, 0xb5, 0x35, 0x24, 0xb4, 0x60, 0xc5, 0x6f, 0x25, + 0x9c, 0x5f, 0x62, 0x2f, 0xdf, 0xab, 0xe7, 0x64, 0x01, 0x26, 0x3c, 0x8d, + 0x97, 0x5e, 0xe9, 0x56, 0xd3, 0x4c, 0xe4, 0xac, 0xa8, 0x3a, 0xdc, 0x56, + 0x29, 0x65, 0x94, 0x34, 0x6c, 0x3d, 0xaa, 0x94, 0xdf, 0xb3, 0x13, 0xf0, + 0x23, 0x3e, 0xb7, 0x9e, 0x33, 0xb7, 0x6a, 0x21, 0xaf, 0x14, 0xf7, 0x6f, + 0x96, 0x18, 0xa7, 0x4b, 0x12, 0x01, 0x03, 0xaa, 0x36, 0x7f, 0xe8, 0x91, + 0x0e, 0x11, 0x5c, 0x25, 0xfc, 0xb8, 0xeb, 0xc3, 0xf8, 0xce, 0xde, 0xee, + 0x0a, 0xfc, 0xc3, 0xe5, 0x19, 0xad, 0xf1, 0x8e, 0x30, 0x02, 0xde, 0x05, + 0x23, 0x8c, 0x81, 0x9b, 0x20, 0xc2, 0xbf, 0x43, 0xfc, 0x1b, 0xe9, 0x7f, + 0x04, 0x57, 0x80, 0x3d, 0xeb, 0x81, 0x73, 0x45, 0x67, 0xea, 0x3a, 0x75, + 0xbd, 0xcd, 0xcc, 0x85, 0x50, 0x31, 0xe5, 0x4b, 0x95, 0x8e, 0xec, 0xc4, + 0x92, 0x40, 0x9b, 0x16, 0xb6, 0x74, 0x07, 0xed, 0xf4, 0x72, 0x3c, 0x50, + 0xa5, 0xdb, 0x69, 0x5f, 0x9d, 0x97, 0x23, 0xf5, 0xcb, 0x16, 0x7e, 0xcb, + 0xa8, 0x71, 0xcc, 0xa0, 0x0b, 0x7e, 0x1f, 0x2f, 0x4f, 0x8f, 0x83, 0xf2, + 0xe3, 0xdd, 0xae, 0xcd, 0x94, 0xaa, 0x36, 0x0c, 0xb0, 0x7a, 0x37, 0x50, + 0x8b, 0x9d, 0x00, 0x31, 0xea, 0x91, 0xb4, 0x5c, 0x95, 0x30, 0x3b, 0x3e, + 0x9f, 0x57, 0xbb, 0x98, 0x5a, 0x2f, 0x95, 0x87, 0xa8, 0x4a, 0x58, 0x8d, + 0xe5, 0x00, 0x1a, 0x11, 0xbd, 0xb0, 0x57, 0x5c, 0x4c, 0xeb, 0x21, 0x77, + 0xcb, 0x80, 0xc8, 0x34, 0xb4, 0x1b, 0x5b, 0x91, 0xf5, 0x65, 0x52, 0x15, + 0x29, 0x9d, 0xa5, 0xd6, 0xfe, 0xac, 0x47, 0x12, 0x08, 0x5f, 0xdc, 0xf3, + 0x7c, 0x8a, 0xa9, 0xbc, 0x75, 0xb6, 0xa5, 0x8b, 0x68, 0xd0, 0xd4, 0x6e, + 0x37, 0xb7, 0x02, 0x38, 0xe8, 0xcd, 0x74, 0x44, 0x9e, 0x5b, 0x14, 0xf8, + 0xad, 0xe8, 0xc0, 0x15, 0x09, 0xe4, 0x00, 0xac, 0x56, 0x11, 0xc8, 0x95, + 0xe7, 0x4a, 0x01, 0x63, 0x89, 0xcf, 0x7e, 0xb8, 0x11, 0x00, 0x10, 0x6c, + 0x3c, 0xcc, 0x2f, 0xd5, 0xbd, 0x00, 0x01, 0x8f, 0xb7, 0x5e, 0xe2, 0xdd, + 0xd0, 0x93, 0x76, 0xc0, 0x09, 0x97, 0x9e, 0x39, 0xf2, 0x7a, 0x96, 0xe0, + 0x20, 0x30, 0x31, 0xb9, 0xc5, 0x87, 0x49, 0x2c, 0x09, 0x09, 0x8d, 0x3c, + 0x93, 0x12, 0x84, 0xb7, 0xf2, 0x0f, 0x79, 0x3e, 0xb7, 0xe3, 0x1d, 0x64, + 0x0d, 0xd5, 0x32, 0xf8, 0x58, 0xde, 0x97, 0xb1, 0x64, 0x07, 0x5a, 0xe9, + 0x98, 0x12, 0x61, 0xb6, 0xd3, 0xdb, 0xea, 0xa0, 0x05, 0xe2, 0x63, 0xb3, + 0xbb, 0xe7, 0x12, 0x19, 0x9a, 0xec, 0xc7, 0xe8, 0x18, 0x94, 0xfb, 0xe4, + 0xe9, 0x4e, 0xba, 0x91, 0x42, 0x1b, 0xe0, 0xc2, 0x83, 0xa6, 0x6a, 0xe0, + 0xfc, 0x0e, 0xdf, 0xd5, 0x3d, 0xbb, 0x37, 0xf2, 0x5e, 0x2b, 0x1b, 0x92, + 0x6b, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x43, 0xfd, 0x0a, 0x00, 0xf4, 0x58, + 0xaf, 0xbf, 0xbf, 0x02, 0x2d, 0x72, 0xa2, 0x9b, 0x98, 0xeb, 0x6b, 0xe4, + 0xc3, 0x96, 0xc9, 0x0b, 0x46, 0xf4, 0x06, 0xf1, 0xd7, 0x0b, 0xa5, 0x14, + 0x5c, 0xcb, 0xb2, 0x19, 0x4e, 0xa7, 0x97, 0x5b, 0x9b, 0xc3, 0x80, 0x0f, + 0x9f, 0xab, 0x9a, 0xa3, 0x1d, 0xa9, 0x53, 0x2d, 0xc4, 0x52, 0xea, 0x14, + 0xa3, 0x56, 0x37, 0x20, 0x52, 0xe7, 0x31, 0xcf, 0xd3, 0x51, 0x03, 0xf7, + 0xbe, 0x13, 0x2e, 0xd0, 0xc2, 0xc7, 0x51, 0xed, 0xf2, 0x99, 0x52, 0xac, + 0xf0, 0x2d, 0xb8, 0x60, 0xfb, 0x5b, 0xf5, 0x02, 0xaa, 0x6f, 0x36, 0x65, + 0x88, 0x50, 0x74, 0x42, 0x86, 0x9c, 0x1a, 0x81, 0xad, 0xe4, 0x00, 0x1e, + 0x4e, 0xfe, 0x3e, 0xf9, 0x32, 0x45, 0x29, 0x03, 0xae, 0xf9, 0x5d, 0x96, + 0x18, 0x58, 0xf8, 0xbe, 0x0d, 0xe1, 0xc0, 0x17, 0x6f, 0x04, 0x6e, 0x78, + 0x32, 0xe5, 0x5b, 0x53, 0x74, 0x53, 0xcb, 0xc9, 0xa1, 0xf4, 0x39, 0xf2, + 0x17, 0x6c, 0x6d, 0x9f, 0x02, 0xbb, 0xcf, 0xa7, 0xd6, 0xc1, 0x7c, 0x82, + 0x30, 0x02, 0x55, 0x0f, 0x0e, 0x85, 0x00, 0x90, 0xe5, 0xb6, 0x2f, 0x83, + 0x67, 0x31, 0x66, 0x92, 0x55, 0xb9, 0xb0, 0x3a, 0x2b, 0x7f, 0x41, 0xff, + 0x40, 0x03, 0xfe, 0x85, 0xf0, 0xf3, 0x28, 0x23, 0xff, 0xef, 0x0f, 0x0f, + 0xd3, 0x62, 0x8f, 0xa1, 0xa5, 0xb0, 0x14, 0xb8, 0x2a, 0x71, 0xc8, 0x98, + 0x01, 0x2e, 0x6c, 0xd5, 0x74, 0xe3, 0x30, 0xaf, 0x5b, 0x4e, 0x0d, 0x46, + 0xe3, 0xf1, 0x7b, 0xff, 0xd2, 0x29, 0xb5, 0xd0, 0xb3, 0x37, 0xc9, 0xdb, + 0xbc, 0xee, 0x39, 0xe5, 0xee, 0x01, 0x8b, 0x61, 0x34, 0x29, 0xbd, 0x0f, + 0xdf, 0xbd, 0xd8, 0xb8, 0xea, 0x1d, 0x9f, 0x8c, 0xf3, 0xde, 0x7c, 0xa9, + 0xa7, 0x87, 0x45, 0x2c, 0xc3, 0x94, 0x63, 0x6a, 0x64, 0xd5, 0xa8, 0xda, + 0xa4, 0xdc, 0x02, 0xdb, 0xe3, 0xf5, 0xf0, 0xe0, 0x04, 0x80, 0x06, 0xaf, + 0xaf, 0x50, 0x26, 0xf1, 0xbc, 0x4a, 0xe5, 0x85, 0x93, 0x6d, 0x54, 0x50, + 0xb6, 0xfc, 0xff, 0xf5, 0xcc, 0xcb, 0x0c, 0x37, 0xc6, 0x4a, 0xdf, 0xa5, + 0x48, 0xb9, 0xc5, 0x22, 0x7c, 0xf7, 0x95, 0x16, 0xc9, 0xb3, 0x31, 0x0d, + 0xb4, 0xf3, 0xec, 0xb1, 0x56, 0x24, 0x29, 0x5b, 0xe4, 0x80, 0x0d, 0xfe, + 0x01, 0x04, 0x06, 0x7f, 0xb3, 0x39, 0x15, 0xc8, 0xc0, 0xe2, 0x0b, 0x97, + 0xcc, 0xb0, 0x20, 0x29, 0xb0, 0x32, 0x66, 0x3b, 0x25, 0x0a, 0x7b, 0x64, + 0xf9, 0xe5, 0x24, 0x4f, 0x16, 0xfc, 0x30, 0xbd, 0xc0, 0x07, 0x9f, 0xfd, + 0xe7, 0x3c, 0xd4, 0x6a, 0x49, 0x64, 0x32, 0x37, 0x91, 0x22, 0xf7, 0xc1, + 0x17, 0x34, 0x40, 0x8e, 0xea, 0x17, 0x25, 0xe7, 0x16, 0xf3, 0xd6, 0x6c, + 0x35, 0x3c, 0xae, 0x1e, 0xb0, 0xa3, 0x9b, 0xe9, 0xc0, 0x05, 0x70, 0x57, + 0x0f, 0xdf, 0x8f, 0xe4, 0x01, 0xe6, 0x87, 0x1a, 0x5d, 0x94, 0xc9, 0xbe, + 0x5b, 0x96, 0x5b, 0x2c, 0x6f, 0x94, 0x49, 0xf8, 0xf8, 0x9a, 0xa1, 0x73, + 0x9c, 0x36, 0xda, 0x1a, 0x5c, 0x25, 0x37, 0x6e, 0x5a, 0x9f, 0x9a, 0x15, + 0x56, 0x94, 0xcc, 0xfb, 0x1b, 0x0e, 0x96, 0x00, 0x5b, 0x4d, 0xc0, 0x15, + 0xaa, 0x43, 0xc3, 0x21, 0xed, 0x88, 0xae, 0x05, 0x77, 0x00, 0x06, 0x7a, + 0xaa, 0x48, 0x46, 0xfa, 0xaf, 0xbd, 0xd9, 0xfc, 0x12, 0x46, 0xd3, 0x34, + 0x30, 0x0c, 0xf9, 0xfb, 0x66, 0xc0, 0xf3, 0xa6, 0x48, 0x6c, 0x94, 0xa3, + 0xea, 0x37, 0xcd, 0x36, 0xf9, 0xbf, 0x05, 0xe5, 0x08, 0x84, 0x02, 0xb5, + 0xb4, 0x96, 0xdc, 0xc8, 0xbe, 0x87, 0x10, 0xd9, 0xc3, 0x9b, 0xfa, 0x6f, + 0xc0, 0xbf, 0x70, 0x02, 0x3f, 0x69, 0xbd, 0x08, 0xed, 0x41, 0x10, 0x01, + 0x30, 0x51, 0xaa, 0x80, 0x91, 0xff, 0x92, 0xfe, 0xe0, 0xe5, 0xaa, 0xdb, + 0x3f, 0xff, 0x34, 0x01, 0xf6, 0x91, 0x08, 0xc2, 0x62, 0x9f, 0x69, 0xbc, + 0x71, 0xbf, 0x9d, 0x26, 0xd2, 0xad, 0x85, 0x41, 0xad, 0xe4, 0x3b, 0xf8, + 0x04, 0x1f, 0xd9, 0x00, 0x12, 0x00, 0x5b, 0x68, 0x64, 0x36, 0x3c, 0xca, + 0x38, 0x3f, 0xc8, 0xe4, 0xa5, 0xf8, 0x37, 0xe8, 0x2f, 0x91, 0x3b, 0xcf, + 0xb8, 0xb8, 0x06, 0x60, 0xc7, 0x5e, 0xdd, 0xa8, 0x93, 0x53, 0x15, 0x23, + 0xee, 0x20, 0xc2, 0x1b, 0x79, 0xef, 0x90, 0x52, 0x5d, 0xa0, 0x03, 0x46, + 0xca, 0x95, 0x16, 0x7a, 0xb7, 0xf1, 0x30, 0x07, 0x74, 0x10, 0x40, 0x5c, + 0x4f, 0xf7, 0xda, 0x20, 0xf5, 0xcf, 0x7e, 0x9c, 0x1f, 0x6c, 0x2a, 0x9b, + 0x62, 0xac, 0x92, 0xa0, 0xc1, 0xed, 0xf2, 0x8e, 0x13, 0x8b, 0xb7, 0x6f, + 0x81, 0x8b, 0x3c, 0x5b, 0xf4, 0xf9, 0x10, 0x48, 0x20, 0x80, 0xe7, 0xd3, + 0x3e, 0x5d, 0x9c, 0xe9, 0x76, 0xde, 0x36, 0xbf, 0x4d, 0xab, 0x7c, 0xe9, + 0x4b, 0x9a, 0x7a, 0xa5, 0x3d, 0x5b, 0xf3, 0x5f, 0xcc, 0x20, 0x76, 0xf7, + 0x49, 0x7c, 0x26, 0x6d, 0x1f, 0x06, 0x6b, 0x75, 0x17, 0xde, 0x9b, 0xe8, + 0x3e, 0x05, 0xb6, 0xaa, 0xa7, 0xb7, 0xc4, 0xe3, 0x83, 0x76, 0x65, 0x40, + 0x08, 0xee, 0x2b, 0x7b, 0xf8, 0x08, 0x40, 0x15, 0xa2, 0xce, 0x90, 0xf0, + 0x43, 0x00, 0x68, 0x14, 0x79, 0x3e, 0x58, 0x49, 0x6f, 0x17, 0x26, 0xf9, + 0xe1, 0x6a, 0x3b, 0xf3, 0x6b, 0xac, 0xf0, 0xa0, 0x6d, 0xbd, 0xc6, 0x4b, + 0xd0, 0x81, 0x32, 0x5a, 0x11, 0x1d, 0xc6, 0x85, 0x02, 0x27, 0xfd, 0x6a, + 0xfa, 0x48, 0xde, 0xb5, 0x0f, 0x6f, 0x41, 0x49, 0xe0, 0x73, 0x74, 0x71, + 0x9c, 0xce, 0xdd, 0xf8, 0xa1, 0x7e, 0xdb, 0xef, 0xc8, 0x4d, 0x59, 0xb3, + 0x56, 0xc1, 0xc9, 0x2c, 0xad, 0x81, 0xe6, 0x68, 0xbf, 0x7f, 0x6d, 0x81, + 0x59, 0xf3, 0x5d, 0xbc, 0x51, 0xc1, 0xc6, 0x58, 0x78, 0x49, 0x4c, 0xfd, + 0x3a, 0xd1, 0x5c, 0x77, 0x65, 0x83, 0x03, 0xbf, 0x92, 0xcd, 0xb0, 0xf3, + 0xf7, 0x39, 0x59, 0x00, 0x46, 0x5a, 0xb6, 0xbd, 0xc7, 0x89, 0xeb, 0xef, + 0xca, 0xe5, 0x5a, 0x56, 0xe0, 0x87, 0x88, 0xc7, 0xe4, 0x3c, 0x02, 0x57, + 0x6e, 0xfa, 0x16, 0xda, 0xb7, 0x54, 0x6f, 0x9b, 0x43, 0xde, 0x2a, 0xf8, + 0xc3, 0x62, 0x14, 0x12, 0x91, 0xbd, 0x35, 0xda, 0x44, 0x30, 0xcd, 0xf4, + 0xd7, 0xd2, 0xbd, 0x2a, 0x92, 0xdb, 0x83, 0xdc, 0xb9, 0x5d, 0x73, 0x9a, + 0x3e, 0x58, 0xf7, 0xdd, 0x88, 0x4c, 0x38, 0xb1, 0x81, 0x55, 0xba, 0x76, + 0x00, 0x1b, 0x07, 0x27, 0x8e, 0xf9, 0xd4, 0x1a, 0x73, 0x65, 0x5b, 0xa0, + 0xf5, 0x6f, 0x90, 0x58, 0xa3, 0x0b, 0xf5, 0x83, 0x82, 0xd4, 0x84, 0xc7, + 0x7f, 0x39, 0x0b, 0xf5, 0x80, 0x7c, 0x6b, 0xea, 0x67, 0x56, 0xcb, 0x68, + 0x61, 0xb8, 0x97, 0x4a, 0x1c, 0xa3, 0xce, 0x68, 0xf7, 0x57, 0xd8, 0xf8, + 0x81, 0xa9, 0x9a, 0x51, 0x0d, 0x19, 0x1c, 0xc1, 0xe8, 0xde, 0x19, 0x08, + 0x19, 0x14, 0xb0, 0x98, 0x9b, 0xe8, 0x39, 0xb9, 0xcf, 0x2b, 0x70, 0x95, + 0x28, 0xc0, 0xa0, 0xd6, 0xed, 0x2b, 0xde, 0xf9, 0x66, 0x21, 0xe0, 0x88, + 0x00, 0x95, 0x54, 0x2a, 0x61, 0xed, 0xc0, 0x2b, 0x08, 0x13, 0x3d, 0x75, + 0x2c, 0x24, 0xc6, 0x9a, 0xca, 0x14, 0x07, 0x37, 0xf6, 0x90, 0x02, 0x5f, + 0x20, 0x02, 0xd0, 0x06, 0xd3, 0xd9, 0xdb, 0x68, 0x0f, 0x7b, 0x27, 0xf0, + 0xfc, 0xe2, 0x4a, 0xb7, 0xf7, 0x76, 0x67, 0x85, 0xb1, 0xbd, 0x4f, 0x6f, + 0xd0, 0x40, 0x03, 0x9e, 0x78, 0x9b, 0xba, 0xa3, 0x41, 0x0b, 0xfd, 0x67, + 0x3a, 0x78, 0x4e, 0x6c, 0x5b, 0x7c, 0x63, 0x7d, 0x7b, 0xeb, 0x01, 0x07, + 0xf9, 0x7f, 0xff, 0x57, 0xeb, 0xac, 0x02, 0x7c, 0xec, 0xde, 0x1f, 0x83, + 0x0e, 0x5c, 0xd9, 0x24, 0x81, 0x8d, 0xf3, 0x90, 0x02, 0x3f, 0xf0, 0x81, + 0x00, 0x0d, 0xb3, 0xe3, 0xec, 0xfe, 0x51, 0x4c, 0x7f, 0x3d, 0x75, 0x90, + 0x9f, 0xce, 0xca, 0x86, 0x9b, 0x69, 0x85, 0xaa, 0x54, 0x34, 0x73, 0x46, + 0xda, 0xba, 0x57, 0x81, 0x88, 0xde, 0x5e, 0xae, 0x2a, 0x92, 0x9b, 0xf8, + 0x90, 0x02, 0x12, 0x33, 0xc0, 0x1d, 0x80, 0x36, 0x7c, 0x17, 0x2c, 0x1b, + 0x25, 0xeb, 0x9b, 0x24, 0xfd, 0xc2, 0xb4, 0x6c, 0xc1, 0xcd, 0xc9, 0xfa, + 0xf5, 0xbf, 0x04, 0x5e, 0x05, 0xf5, 0xcc, 0x3a, 0xa6, 0xe4, 0x78, 0x75, + 0x18, 0x3e, 0x58, 0xdf, 0xba, 0x3e, 0x5f, 0x48, 0xbf, 0x7f, 0x71, 0x7d, + 0xdd, 0x1b, 0x4b, 0xe7, 0x9b, 0xa6, 0x0c, 0xfd, 0x69, 0xd2, 0x05, 0x37, + 0xe6, 0xbf, 0xee, 0x02, 0x08, 0x16, 0x0b, 0xff, 0x74, 0x81, 0x5b, 0xc0, + 0xa3, 0x2f, 0x86, 0xdb, 0x6c, 0x21, 0xd6, 0xe7, 0xa8, 0xed, 0xb0, 0x96, + 0x3d, 0xb0, 0xdf, 0xc5, 0xad, 0xfc, 0x61, 0xe0, 0x63, 0x32, 0x90, 0xed, + 0x6d, 0x7e, 0xdb, 0xa0, 0x0c, 0x1d, 0xf7, 0x16, 0xb2, 0x06, 0x4f, 0xe8, + 0x92, 0xb2, 0xd0, 0xc2, 0x07, 0x19, 0x8b, 0xeb, 0x5b, 0xec, 0x80, 0x0b, + 0x5d, 0xef, 0xcf, 0xd8, 0x01, 0xcd, 0x17, 0x2a, 0x93, 0x60, 0x87, 0x11, + 0xcc, 0xe9, 0xd6, 0xa7, 0xe2, 0xcd, 0x7f, 0x12, 0x52, 0x86, 0x8c, 0xd6, + 0xf1, 0x20, 0x05, 0xa2, 0x27, 0xb8, 0x02, 0xa1, 0x64, 0x1d, 0xd3, 0x83, + 0x93, 0xe0, 0x5e, 0xe5, 0xca, 0x34, 0x3b, 0x69, 0x25, 0x2b, 0x67, 0x3f, + 0x25, 0x4f, 0x11, 0xed, 0x16, 0x0d, 0x24, 0x37, 0xf1, 0x28, 0x08, 0x5f, + 0xef, 0x38, 0x8b, 0xe3, 0x2d, 0xa4, 0xa8, 0xdd, 0xdf, 0x28, 0x00, 0xee, + 0x8a, 0xc0, 0x4c, 0x00, 0x3a, 0xa9, 0xea, 0xdc, 0xfe, 0xf1, 0xf4, 0x5e, + 0x72, 0xe7, 0xca, 0x36, 0x57, 0x2e, 0x6c, 0xb0, 0x22, 0x95, 0x5b, 0xed, + 0x40, 0x04, 0xa2, 0xa8, 0x01, 0x79, 0x1b, 0x31, 0xcf, 0x01, 0x13, 0xec, + 0x48, 0xa3, 0x29, 0x6a, 0x32, 0xb6, 0x8e, 0xa4, 0x0d, 0x7d, 0x21, 0x58, + 0xca, 0x94, 0x5b, 0x7b, 0xf9, 0x76, 0xfb, 0xc0, 0x06, 0x25, 0x06, 0x5b, + 0x3e, 0x84, 0xe9, 0xc4, 0x18, 0x4d, 0x59, 0xab, 0x42, 0x92, 0x37, 0x80, + 0x00, 0x77, 0xf0, 0x2f, 0x3d, 0xc5, 0xf5, 0xc3, 0xf8, 0xd8, 0xb2, 0xe4, + 0x7b, 0xf2, 0x6a, 0x51, 0x95, 0x06, 0x5f, 0x16, 0xfa, 0xc7, 0xd3, 0xbd, + 0xe0, 0x8b, 0xec, 0x27, 0xe6, 0x0e, 0x0e, 0xb9, 0xde, 0x57, 0x39, 0x69, + 0x51, 0x2d, 0xa5, 0x14, 0xd8, 0xa5, 0xc0, 0x06, 0x40, 0x0f, 0x1f, 0xf1, + 0x40, 0x2c, 0xc2, 0xd3, 0x2b, 0xb8, 0x7a, 0xe7, 0x9d, 0xbe, 0x7a, 0x36, + 0x16, 0x43, 0xad, 0xe3, 0xf5, 0x7c, 0xf5, 0x66, 0xc0, 0xca, 0xb9, 0x02, + 0xdb, 0x29, 0x4e, 0x46, 0xfe, 0x72, 0xe7, 0x4d, 0x00, 0xb3, 0x2c, 0xf0, + 0xef, 0x61, 0xa0, 0x97, 0xff, 0xb6, 0x2a, 0x05, 0xb7, 0xea, 0x88, 0x21, + 0xd8, 0x2b, 0xdb, 0x9e, 0x08, 0x0a, 0x02, 0x5d, 0xe6, 0xb8, 0xf9, 0x0a, + 0xa5, 0x0c, 0x2c, 0x7b, 0x7e, 0x5a, 0x9a, 0x01, 0x5c, 0xe2, 0x60, 0x04, + 0x22, 0xf7, 0x24, 0x21, 0xa4, 0x6f, 0xd3, 0xe0, 0x0f, 0x81, 0x0b, 0xfd, + 0x33, 0x9b, 0x6b, 0xc6, 0xc4, 0x90, 0x99, 0x92, 0x87, 0x86, 0x5b, 0xb5, + 0x59, 0x65, 0x20, 0x13, 0xac, 0xb0, 0x34, 0x3c, 0xf9, 0x5a, 0xf2, 0xcd, + 0x4a, 0xad, 0xf4, 0x12, 0x7c, 0x11, 0x7b, 0xcb, 0x8e, 0xb2, 0x9a, 0xeb, + 0x21, 0xa9, 0x12, 0x87, 0xe2, 0xee, 0xcb, 0x55, 0x15, 0x46, 0xb7, 0xe6, + 0x71, 0x1e, 0xcf, 0xf8, 0x00, 0x71, 0xd7, 0xb6, 0x3d, 0x60, 0xd0, 0x42, + 0x00, 0x69, 0x69, 0x48, 0x51, 0x61, 0xf6, 0xac, 0x85, 0x1e, 0x5b, 0x7d, + 0xcf, 0xe4, 0x89, 0xc0, 0x03, 0x0e, 0xe3, 0x9f, 0xb2, 0x29, 0xab, 0xc0, + 0x01, 0xec, 0x27, 0xe6, 0xeb, 0xcf, 0x44, 0xb0, 0xb8, 0x91, 0x1b, 0xd7, + 0xfd, 0xfd, 0xde, 0x00, 0xdf, 0xe6, 0x13, 0xd7, 0xf5, 0x09, 0xde, 0x46, + 0xd3, 0x2d, 0x2f, 0x7f, 0x6a, 0x64, 0x50, 0xe3, 0x8b, 0x6e, 0x9b, 0x2f, + 0x2f, 0xc3, 0x28, 0x00, 0xd0, 0xf5, 0x6e, 0x8a, 0x54, 0x95, 0x58, 0x00, + 0x00, 0x01, 0xb7 }; -void mpeg2_get_video_info(VideoDecodeInfo *info) +void +mpeg2_get_video_info (VideoDecodeInfo * info) { - info->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; - info->width = MPEG2_CLIP_WIDTH; - info->height = MPEG2_CLIP_HEIGHT; - info->data = mpeg2_clip; - info->data_size = MPEG2_CLIP_DATA_SIZE; + info->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE; + info->width = MPEG2_CLIP_WIDTH; + info->height = MPEG2_CLIP_HEIGHT; + info->data = mpeg2_clip; + info->data_size = MPEG2_CLIP_DATA_SIZE; } diff --git a/tests/test-mpeg4.c b/tests/test-mpeg4.c index 240b86ea03..270359b47e 100644 --- a/tests/test-mpeg4.c +++ b/tests/test-mpeg4.c @@ -28,1646 +28,1647 @@ /* Data dump of a 320x240 MPEG-4 video clip (mpeg4.m4v), it has a single frame */ static const guchar mpeg4_clip[MPEG4_CLIP_DATA_SIZE] = { - 0x00, 0x00, 0x01, 0xb0, 0x01, 0x00, 0x00, 0x01, 0xb5, 0x89, 0x13, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0xc4, 0x8d, 0x88, 0x00, - 0xcd, 0x0a, 0x04, 0x1e, 0x14, 0x43, 0x00, 0x00, 0x01, 0xb2, 0x4c, 0x61, - 0x76, 0x63, 0x35, 0x34, 0x2e, 0x36, 0x32, 0x2e, 0x31, 0x30, 0x30, 0x00, - 0x00, 0x01, 0xb3, 0x00, 0x10, 0x07, 0x00, 0x00, 0x01, 0xb6, 0x10, 0x60, - 0x85, 0x85, 0x41, 0x08, 0x78, 0xab, 0x44, 0x81, 0x29, 0x06, 0xd1, 0xd2, - 0x4d, 0xe9, 0x2d, 0x55, 0xe0, 0x95, 0x36, 0x42, 0x10, 0x71, 0xfc, 0xa0, - 0x4f, 0x8b, 0x9a, 0x0a, 0xd8, 0x84, 0xca, 0x81, 0x18, 0x48, 0x80, 0xf0, - 0xd0, 0x0b, 0x97, 0x12, 0x83, 0x01, 0x47, 0x13, 0x97, 0x59, 0xfe, 0x22, - 0x5b, 0x9d, 0x88, 0xfb, 0x38, 0x46, 0x2e, 0x29, 0x11, 0x39, 0xb3, 0x7a, - 0x08, 0x02, 0x5f, 0x16, 0xf6, 0x52, 0x8d, 0x3e, 0x33, 0x2f, 0x12, 0x04, - 0xb5, 0x5d, 0xa0, 0x88, 0xcd, 0xe2, 0xeb, 0x7a, 0xd9, 0xc0, 0x61, 0x30, - 0xbd, 0x4e, 0xce, 0x8a, 0xb8, 0xe6, 0xbf, 0x14, 0x43, 0xed, 0x8d, 0xd8, - 0x4d, 0x74, 0x47, 0x69, 0x5b, 0x23, 0x9c, 0xb5, 0xad, 0x82, 0x06, 0xfb, - 0xfe, 0x9d, 0xec, 0x5d, 0x70, 0x49, 0x0b, 0xca, 0x95, 0x5f, 0xb3, 0xec, - 0x0e, 0x6c, 0x0c, 0xdc, 0x68, 0x7b, 0xfc, 0x0f, 0xad, 0xbe, 0xcd, 0xd2, - 0x58, 0xbf, 0x38, 0x4e, 0x30, 0x2e, 0x49, 0x7c, 0x95, 0x52, 0xb9, 0x3a, - 0xc2, 0xfa, 0x69, 0x46, 0xf1, 0x14, 0x0e, 0x48, 0xd3, 0xa5, 0xa0, 0xc2, - 0x6f, 0x29, 0x19, 0x61, 0x21, 0xaf, 0x0e, 0x32, 0x79, 0x06, 0x49, 0x06, - 0x10, 0xf1, 0xb1, 0xef, 0x51, 0xf3, 0xa7, 0x14, 0x0f, 0xf2, 0x90, 0xaa, - 0x3d, 0xde, 0xcb, 0x20, 0x71, 0xd1, 0x35, 0x30, 0x86, 0xc3, 0x21, 0x7f, - 0xff, 0x70, 0xd2, 0xf4, 0x96, 0xac, 0xb1, 0x19, 0xff, 0x5f, 0xfe, 0xf3, - 0x0a, 0xc3, 0x94, 0x0b, 0x10, 0xe6, 0xe7, 0x55, 0x54, 0x36, 0x6d, 0x2a, - 0x35, 0x2d, 0x27, 0xa9, 0xd9, 0xb3, 0x7c, 0x37, 0x71, 0x85, 0x96, 0x2c, - 0x2e, 0xdc, 0x6a, 0xd9, 0x9c, 0x51, 0xfe, 0x4a, 0x8a, 0xd2, 0x90, 0x13, - 0x02, 0x19, 0x72, 0x86, 0x33, 0xf9, 0x11, 0x0c, 0x77, 0x2f, 0x57, 0x79, - 0xc6, 0x9b, 0x2b, 0x8a, 0x79, 0x36, 0xf0, 0xa9, 0x15, 0xa4, 0xae, 0x11, - 0x0e, 0x73, 0xe5, 0xca, 0x35, 0x74, 0x03, 0x2a, 0x41, 0x9b, 0xab, 0x53, - 0xe5, 0x9e, 0x11, 0x8b, 0x69, 0x7b, 0x45, 0x9a, 0xa2, 0x94, 0xf2, 0x14, - 0x50, 0x5b, 0x0a, 0x1b, 0x4a, 0x9e, 0xdd, 0x6b, 0x53, 0x52, 0xcf, 0x23, - 0x57, 0x37, 0xca, 0x0d, 0x2c, 0x0b, 0x50, 0xc7, 0x60, 0xe3, 0xf6, 0x44, - 0x1a, 0x1e, 0x0d, 0x4a, 0x79, 0xa9, 0x8c, 0x66, 0xed, 0x2a, 0x6f, 0x23, - 0x73, 0x39, 0x6d, 0x5e, 0x77, 0xa1, 0xa6, 0x1f, 0xdb, 0xe8, 0x0c, 0x97, - 0x8b, 0x38, 0xd6, 0xfd, 0x5e, 0x16, 0x7a, 0x67, 0x77, 0xb7, 0xab, 0x0a, - 0x46, 0xfb, 0xf1, 0x05, 0x62, 0xcd, 0xc2, 0xec, 0x11, 0x14, 0xa8, 0xa2, - 0x07, 0x39, 0xdb, 0x03, 0x96, 0x74, 0xa8, 0x18, 0x4e, 0x3f, 0x12, 0x53, - 0xff, 0xff, 0x9e, 0xff, 0xc1, 0x59, 0x9a, 0x1e, 0x68, 0x89, 0xbf, 0x5d, - 0x7e, 0x08, 0xba, 0xa4, 0x3a, 0xc0, 0x62, 0x0a, 0xd6, 0x94, 0xb5, 0x3d, - 0x2d, 0x62, 0x4b, 0x3f, 0x57, 0xed, 0x05, 0x7f, 0xfe, 0x1e, 0x29, 0x0d, - 0x00, 0xa7, 0x4c, 0xe6, 0x16, 0xd7, 0x96, 0x5a, 0x6f, 0xae, 0x35, 0xcc, - 0xcf, 0x4b, 0xb9, 0x1a, 0x5b, 0xb5, 0x44, 0x0e, 0xcb, 0x20, 0x71, 0x9c, - 0x50, 0xa4, 0x18, 0x84, 0xaa, 0x0b, 0xea, 0xb5, 0xa3, 0x3e, 0x14, 0x82, - 0xdd, 0x14, 0x8a, 0x38, 0xb0, 0x7b, 0xf5, 0x11, 0x42, 0x91, 0xbd, 0xec, - 0x96, 0x9e, 0x68, 0xba, 0xa6, 0xdb, 0xb4, 0xd0, 0xd8, 0xa6, 0x86, 0xea, - 0x01, 0xf3, 0x7f, 0xfb, 0xd8, 0xf9, 0x68, 0xe5, 0x51, 0xd5, 0x3d, 0xe6, - 0x62, 0xeb, 0x95, 0x71, 0xd5, 0x69, 0x6a, 0x8d, 0x8b, 0x29, 0x47, 0x10, - 0xd8, 0x0c, 0x0b, 0xab, 0x68, 0x71, 0xf6, 0xa7, 0x17, 0x9d, 0xa8, 0xca, - 0xed, 0xe2, 0xcb, 0xbd, 0x3a, 0xb5, 0x86, 0x94, 0x48, 0x50, 0x73, 0xcf, - 0xb6, 0x70, 0x4b, 0xfe, 0xb4, 0xab, 0x6b, 0x19, 0x9a, 0xda, 0x89, 0x3d, - 0x9b, 0xd9, 0x2d, 0xb7, 0x8b, 0xd0, 0xd0, 0xf9, 0xa6, 0x81, 0xba, 0x59, - 0x39, 0x33, 0xb0, 0xa8, 0xb2, 0x95, 0xd9, 0x10, 0x2e, 0x0c, 0x13, 0x48, - 0xee, 0x96, 0x0e, 0x2d, 0xcb, 0x71, 0x72, 0xb8, 0xba, 0xf5, 0x01, 0xea, - 0xc6, 0x7a, 0xdc, 0xf7, 0x91, 0xe8, 0xc0, 0x4e, 0x92, 0x75, 0xc2, 0xf9, - 0x42, 0xc6, 0xd8, 0xf7, 0xea, 0xc1, 0x13, 0x14, 0xdc, 0x94, 0xb6, 0x4d, - 0x99, 0x9c, 0xbc, 0x2c, 0x5d, 0x71, 0x38, 0xc7, 0xe9, 0x44, 0x05, 0x0d, - 0x30, 0x1d, 0xad, 0x3a, 0x13, 0x17, 0x65, 0x36, 0xf0, 0xaf, 0x67, 0xed, - 0x83, 0x6e, 0x2c, 0x50, 0x7d, 0x3c, 0x1f, 0x2a, 0x03, 0x6d, 0x0e, 0x6e, - 0xe2, 0xea, 0x79, 0x50, 0xea, 0x38, 0xe1, 0x6f, 0x7f, 0xde, 0x9c, 0x32, - 0x99, 0xb0, 0x9d, 0xb1, 0x73, 0x03, 0xc2, 0xf0, 0xfe, 0x07, 0xaa, 0x64, - 0xf6, 0x29, 0xd4, 0x59, 0x10, 0xd9, 0x20, 0x8b, 0xaa, 0x6b, 0xc2, 0xfb, - 0x4d, 0x07, 0x85, 0x9d, 0xee, 0x76, 0xd3, 0x53, 0xb5, 0x15, 0x78, 0x97, - 0xd7, 0xeb, 0x20, 0xe8, 0x2e, 0x53, 0xcb, 0xc8, 0x74, 0x62, 0xea, 0x9b, - 0x4e, 0x53, 0xe5, 0x9b, 0xaa, 0x19, 0x2d, 0xcd, 0xf4, 0x2d, 0x6b, 0x6a, - 0xe6, 0xf8, 0xa6, 0x5b, 0x41, 0x6e, 0x36, 0xd6, 0xcb, 0x3f, 0xdf, 0x87, - 0x41, 0xd5, 0x43, 0xab, 0xd5, 0xb8, 0x1b, 0x29, 0x3c, 0x7d, 0x2f, 0xef, - 0x59, 0xbe, 0xe7, 0x4b, 0x7f, 0xce, 0xac, 0x8a, 0xdd, 0x3c, 0x74, 0x42, - 0x2f, 0x64, 0x47, 0xf3, 0x3a, 0xad, 0x55, 0x85, 0x89, 0x59, 0x6b, 0x25, - 0x97, 0x30, 0xb3, 0xd5, 0x6a, 0x56, 0x0e, 0x05, 0x48, 0x24, 0x36, 0x79, - 0x34, 0x43, 0x30, 0xcc, 0x56, 0x9d, 0x6d, 0xbb, 0x33, 0x17, 0xb2, 0x73, - 0x90, 0x92, 0x43, 0xc2, 0xba, 0x47, 0x98, 0x9d, 0x67, 0x03, 0x47, 0xe2, - 0xb5, 0xad, 0xb3, 0xe5, 0xdb, 0x62, 0x37, 0xea, 0x6e, 0x45, 0x84, 0xc3, - 0x05, 0x2b, 0x09, 0xdd, 0x93, 0x38, 0xde, 0xf1, 0xb8, 0x81, 0x15, 0xe8, - 0x9c, 0xa0, 0x22, 0xa3, 0xef, 0x50, 0xa8, 0x19, 0x10, 0xac, 0xad, 0x7d, - 0xce, 0x8a, 0x8f, 0x9f, 0x4a, 0x89, 0xd1, 0xb3, 0x2d, 0xb7, 0xdb, 0xda, - 0x48, 0x35, 0x32, 0xcb, 0x30, 0xf0, 0xec, 0x1a, 0x97, 0x8e, 0xd3, 0x09, - 0x1b, 0xf1, 0x22, 0x75, 0x5e, 0x37, 0xe1, 0x10, 0x73, 0x4b, 0x0a, 0xe5, - 0xb3, 0xc1, 0xc9, 0x10, 0x64, 0xc0, 0x64, 0xad, 0x52, 0xc6, 0x0b, 0xfb, - 0xef, 0xff, 0xd8, 0x5b, 0xf8, 0x36, 0x9b, 0x62, 0xf3, 0xf0, 0x44, 0x01, - 0x36, 0x1b, 0x05, 0xa4, 0x3e, 0xd8, 0x30, 0xc1, 0x4a, 0x0c, 0x39, 0x03, - 0x7f, 0x56, 0x3c, 0x56, 0x55, 0xbd, 0x05, 0x62, 0xca, 0x51, 0xea, 0xf0, - 0xa8, 0xe8, 0xcd, 0x26, 0x83, 0x37, 0x9b, 0x8a, 0xf1, 0xbb, 0xe4, 0x41, - 0xdf, 0xfd, 0x32, 0xc4, 0x7c, 0xb2, 0x07, 0x20, 0xc2, 0x65, 0xc4, 0xb1, - 0xdb, 0x71, 0xbc, 0x03, 0x4a, 0xb5, 0x29, 0x68, 0xdb, 0x73, 0xb7, 0x38, - 0x8a, 0x71, 0x40, 0x9a, 0xfe, 0x90, 0x14, 0x25, 0xe1, 0xea, 0xec, 0x4e, - 0xad, 0x85, 0xb1, 0xae, 0x0c, 0x94, 0xa9, 0x06, 0x1a, 0x94, 0xde, 0xb5, - 0x78, 0x1e, 0xff, 0x41, 0x85, 0x4d, 0xbc, 0x36, 0x2d, 0x6c, 0x2f, 0x30, - 0x0c, 0xc8, 0x8e, 0xc6, 0xcf, 0x0f, 0x44, 0x60, 0x30, 0x8a, 0xab, 0x4d, - 0x6e, 0xce, 0x9b, 0xe6, 0x88, 0x84, 0x62, 0xf6, 0x41, 0x46, 0xd0, 0xe1, - 0xb4, 0xfe, 0x67, 0x2f, 0x98, 0xca, 0xa7, 0x14, 0xcb, 0xaa, 0x78, 0x86, - 0x08, 0x80, 0x24, 0x39, 0x27, 0x08, 0x41, 0x05, 0x89, 0x59, 0xfc, 0xff, - 0xd6, 0xee, 0xee, 0x33, 0x7f, 0x78, 0x6e, 0x95, 0xa9, 0x3c, 0x33, 0xc5, - 0x37, 0x7a, 0xbe, 0xd1, 0x9b, 0xc6, 0x54, 0x9e, 0x72, 0xd1, 0x51, 0x69, - 0x0e, 0xbd, 0x28, 0x84, 0x10, 0xaf, 0x3b, 0x41, 0x8b, 0x07, 0x83, 0x28, - 0x08, 0x82, 0xc4, 0xd5, 0x31, 0x37, 0xbb, 0x37, 0x96, 0x6f, 0x22, 0xdd, - 0x5a, 0x23, 0x71, 0x92, 0xe4, 0xaa, 0x44, 0x81, 0x19, 0xaf, 0x49, 0x14, - 0x0e, 0x87, 0x92, 0xd4, 0x36, 0xc5, 0x5e, 0x71, 0x75, 0x58, 0xa1, 0xac, - 0x95, 0x65, 0xa7, 0x45, 0x3f, 0x11, 0x3a, 0xd6, 0xff, 0x31, 0xab, 0x9a, - 0xbf, 0x46, 0x47, 0x15, 0x61, 0x4f, 0x2d, 0x40, 0x0b, 0xf9, 0xb7, 0x0a, - 0x4f, 0x25, 0x6c, 0xe2, 0x94, 0x50, 0x17, 0xdb, 0x36, 0x74, 0x77, 0xa5, - 0xab, 0x01, 0x00, 0xa1, 0x11, 0xe3, 0x2a, 0x58, 0xe7, 0x60, 0x79, 0x6b, - 0x91, 0xa9, 0xb1, 0x47, 0xd9, 0xb0, 0xae, 0xf4, 0x65, 0xda, 0xb0, 0x30, - 0xd0, 0xc1, 0x77, 0xe7, 0x76, 0x72, 0x42, 0xde, 0x02, 0x3c, 0xec, 0xaf, - 0x63, 0x15, 0xd6, 0x7b, 0x76, 0x64, 0x0b, 0x55, 0xd5, 0xf7, 0x88, 0x05, - 0xe4, 0xae, 0x7f, 0xc5, 0x2c, 0x5c, 0x24, 0x5c, 0x50, 0x6f, 0x5b, 0x9e, - 0x37, 0x78, 0x13, 0x44, 0x6c, 0x56, 0xdf, 0xbd, 0xc5, 0x05, 0x85, 0x55, - 0x62, 0x61, 0xef, 0xd5, 0x28, 0xbb, 0x37, 0x2e, 0x59, 0x69, 0x47, 0x0d, - 0x9f, 0xa8, 0x24, 0xaa, 0xe4, 0x52, 0xa6, 0x5e, 0xc4, 0x04, 0x22, 0xd4, - 0xac, 0xe7, 0xf2, 0xdb, 0x17, 0xfd, 0xf1, 0x66, 0xdc, 0xea, 0xd3, 0xb9, - 0xc0, 0x71, 0x98, 0x46, 0x6a, 0x9e, 0x1f, 0x6f, 0xd1, 0xe6, 0xff, 0xca, - 0x51, 0x07, 0x14, 0x84, 0x32, 0xa5, 0xfb, 0x75, 0x57, 0x35, 0x7d, 0x63, - 0x64, 0xa8, 0x2f, 0x10, 0x57, 0x1c, 0x6e, 0x2b, 0xf7, 0xfc, 0x58, 0xa5, - 0xb6, 0x24, 0x91, 0x9c, 0x35, 0x40, 0x88, 0x64, 0x0c, 0x35, 0x54, 0x7b, - 0x26, 0x7f, 0x39, 0x24, 0x53, 0xe2, 0xb2, 0x83, 0x4f, 0x48, 0x71, 0x0f, - 0xb7, 0x23, 0xef, 0xfb, 0xf6, 0x36, 0x97, 0x4a, 0xa7, 0xf1, 0x4d, 0x24, - 0x8b, 0x2e, 0x0c, 0x12, 0xda, 0x56, 0xf5, 0x4e, 0xea, 0x9c, 0x8a, 0x8b, - 0x20, 0xe3, 0x8b, 0xad, 0xc5, 0xb9, 0x04, 0x55, 0x38, 0x09, 0x63, 0x6f, - 0xf7, 0xca, 0x73, 0x06, 0xc5, 0xa8, 0x91, 0xce, 0x71, 0x60, 0xcc, 0x18, - 0x2a, 0x1f, 0x88, 0xcd, 0xff, 0xea, 0xa7, 0xa1, 0x5f, 0xfc, 0x06, 0x27, - 0x44, 0x46, 0x2a, 0xf3, 0xe0, 0x49, 0x6c, 0x13, 0xcf, 0xe1, 0x11, 0x82, - 0xd2, 0xe2, 0x30, 0x39, 0xb5, 0x0c, 0x9d, 0x52, 0xa6, 0x2f, 0x2c, 0xa8, - 0xbb, 0xaa, 0x77, 0x1a, 0xc1, 0xb2, 0x8c, 0x06, 0x23, 0x45, 0xb9, 0xa8, - 0x91, 0xcb, 0x2c, 0xf7, 0x8b, 0x24, 0x9d, 0x06, 0x37, 0xf0, 0xd3, 0x01, - 0x82, 0x91, 0x59, 0x67, 0xa4, 0xcc, 0xfc, 0xcd, 0xb4, 0x45, 0x11, 0x25, - 0x46, 0x88, 0x2d, 0x31, 0x7d, 0x0a, 0xa2, 0x35, 0xb9, 0x6a, 0xeb, 0x40, - 0x26, 0x28, 0x34, 0xc7, 0xde, 0x49, 0x51, 0xc4, 0x5f, 0xee, 0x14, 0x53, - 0x88, 0x6a, 0xd1, 0x4a, 0xf6, 0x02, 0xa1, 0x75, 0xcd, 0x1e, 0xea, 0x24, - 0xf1, 0x42, 0xc4, 0xab, 0x1c, 0x36, 0xce, 0x6f, 0x5a, 0xa5, 0xab, 0xfb, - 0xb6, 0x48, 0x55, 0x6a, 0xcb, 0x2c, 0x22, 0xa1, 0x06, 0x1a, 0xf0, 0xbf, - 0x2e, 0x20, 0x40, 0x72, 0x7d, 0xea, 0xde, 0x8c, 0x46, 0x88, 0xb1, 0x6e, - 0xe1, 0x5f, 0xb9, 0x56, 0xea, 0x0d, 0x29, 0x80, 0xb5, 0x22, 0x91, 0x6c, - 0xbf, 0x36, 0xb0, 0x9b, 0x90, 0xe9, 0x40, 0xa3, 0xea, 0xb3, 0xed, 0x4f, - 0x54, 0x73, 0x85, 0x22, 0x61, 0xc0, 0xe2, 0xa6, 0x6e, 0x95, 0x41, 0xc8, - 0x89, 0xf0, 0xcc, 0x11, 0xf0, 0xfa, 0x25, 0x87, 0x61, 0xdb, 0xb7, 0xd1, - 0xb5, 0x7b, 0x65, 0xb0, 0x3d, 0xcd, 0xd5, 0x84, 0x01, 0x8f, 0xd4, 0x8a, - 0x84, 0xfb, 0x72, 0x6f, 0x96, 0xee, 0x8b, 0xc8, 0xa3, 0x31, 0x48, 0x22, - 0x28, 0xe4, 0x93, 0xb7, 0x70, 0xdd, 0x27, 0x9e, 0xf5, 0x3f, 0xe6, 0x20, - 0xdb, 0xc1, 0x98, 0x26, 0x8d, 0x13, 0x98, 0xab, 0x4a, 0xeb, 0xae, 0xf2, - 0xea, 0x15, 0x89, 0x05, 0x46, 0x93, 0xb6, 0x58, 0x93, 0xf5, 0x0d, 0x8a, - 0x21, 0x4b, 0xea, 0xea, 0x81, 0xba, 0x33, 0x83, 0x11, 0xea, 0x79, 0xa5, - 0x51, 0x14, 0x81, 0x5b, 0x0b, 0xa6, 0x6b, 0x2a, 0xc3, 0x51, 0x7f, 0xb6, - 0xad, 0x60, 0x88, 0xa4, 0x60, 0xe7, 0x08, 0x94, 0x2d, 0x51, 0xee, 0xce, - 0xe6, 0xe6, 0x95, 0x14, 0xf7, 0xbd, 0x0a, 0x55, 0xca, 0x9a, 0x98, 0xdc, - 0xfc, 0x0b, 0x6f, 0x12, 0xa8, 0xb5, 0xb9, 0xc9, 0xff, 0x7e, 0xb5, 0xc4, - 0x71, 0x42, 0x0a, 0x1a, 0x99, 0xa5, 0x5f, 0x9c, 0xd5, 0x28, 0xef, 0x41, - 0x1e, 0xd2, 0x33, 0x58, 0x3c, 0xc0, 0x36, 0xcb, 0x2b, 0xda, 0xa3, 0x16, - 0x43, 0x62, 0x3b, 0xf9, 0x01, 0x82, 0xb2, 0xd4, 0x58, 0x7e, 0xa6, 0x47, - 0xe5, 0xf1, 0x56, 0x23, 0x85, 0x70, 0x6d, 0x88, 0x23, 0xcf, 0x6a, 0x79, - 0x14, 0xff, 0x6c, 0x92, 0x77, 0x76, 0xf5, 0x6e, 0x13, 0x8d, 0xeb, 0x19, - 0xa1, 0xec, 0xb6, 0xce, 0x1b, 0x38, 0xbb, 0x6a, 0x62, 0x9b, 0xe9, 0x36, - 0x56, 0xb7, 0xca, 0x34, 0xdd, 0x42, 0x1a, 0x23, 0x06, 0x1a, 0xba, 0x82, - 0x68, 0xd8, 0xf5, 0x28, 0x20, 0xee, 0x33, 0x14, 0x44, 0x8d, 0xa6, 0x6f, - 0xfe, 0x91, 0x5e, 0xa7, 0x8c, 0x2d, 0x78, 0xb4, 0x8a, 0x3f, 0xad, 0xe9, - 0xd1, 0x1e, 0xfc, 0x2b, 0x0c, 0xad, 0x0e, 0xf0, 0x4a, 0x2f, 0x10, 0x04, - 0x90, 0x40, 0xc6, 0xb0, 0xb6, 0xdf, 0x25, 0xcc, 0xac, 0xdc, 0xb6, 0xf2, - 0x7f, 0xb4, 0x6f, 0x81, 0xb6, 0x16, 0x16, 0x77, 0x01, 0x8e, 0x08, 0xc2, - 0x0a, 0xb1, 0xfd, 0x49, 0xbe, 0x12, 0xbf, 0x14, 0xfe, 0x5d, 0x9f, 0xde, - 0xa9, 0x92, 0xca, 0x1e, 0x40, 0xe3, 0x43, 0x50, 0x7c, 0xef, 0xfe, 0xe2, - 0x3c, 0x58, 0x12, 0xb3, 0x60, 0xb6, 0x6d, 0x54, 0xe2, 0x4a, 0xaf, 0xb6, - 0xca, 0x46, 0xbf, 0x35, 0xb5, 0x4b, 0xb3, 0xe4, 0x39, 0x6a, 0x20, 0x60, - 0xa8, 0x36, 0x02, 0x0a, 0x68, 0xa8, 0x7b, 0xfd, 0xc0, 0xe9, 0x9e, 0xfe, - 0x06, 0xbd, 0x0f, 0x60, 0x30, 0xd4, 0x19, 0x2d, 0x25, 0x4e, 0x3e, 0x2f, - 0x10, 0x6d, 0xd1, 0x07, 0xdf, 0xd1, 0x06, 0x7f, 0xb6, 0xdb, 0xde, 0x7e, - 0x7f, 0xa4, 0x69, 0x08, 0xe3, 0xff, 0x0f, 0xf7, 0xd5, 0xa9, 0x73, 0x32, - 0x55, 0xa8, 0x73, 0xfa, 0xa6, 0xf0, 0x36, 0x0b, 0x4e, 0xdb, 0xd8, 0x78, - 0xeb, 0xa7, 0xe8, 0x32, 0x0c, 0x5a, 0xac, 0x11, 0x3c, 0x9a, 0x37, 0xfc, - 0x9e, 0xb5, 0x16, 0xd9, 0xdc, 0xa8, 0x2f, 0x03, 0x80, 0x9c, 0xc5, 0x65, - 0xbd, 0x1b, 0xff, 0xf4, 0x09, 0xda, 0x70, 0xe8, 0xa0, 0x20, 0x01, 0xef, - 0x89, 0x35, 0x4d, 0x2a, 0x55, 0x29, 0x5e, 0x9b, 0xa6, 0x9c, 0x36, 0xed, - 0x89, 0x82, 0x00, 0x8e, 0x93, 0xd2, 0x30, 0x3b, 0xf7, 0x5a, 0xf7, 0x7f, - 0x8d, 0xc2, 0xdb, 0xaa, 0x6d, 0x5e, 0x7d, 0x46, 0xa9, 0xdc, 0x50, 0x22, - 0x02, 0xd8, 0x15, 0x82, 0x36, 0x09, 0x1f, 0x60, 0xb4, 0x79, 0x18, 0x10, - 0x3e, 0x0c, 0x1c, 0x49, 0x95, 0x4a, 0x1b, 0x4a, 0x82, 0xd1, 0x3b, 0x22, - 0x10, 0x34, 0x4d, 0x0b, 0x13, 0xff, 0x1a, 0xd5, 0x00, 0xc6, 0xfb, 0xf0, - 0x60, 0x4d, 0x0c, 0x42, 0x11, 0x78, 0x21, 0x01, 0xef, 0xab, 0xfb, 0x03, - 0xd6, 0x5b, 0x10, 0x71, 0x42, 0x8b, 0xef, 0xf1, 0x6a, 0xa6, 0x72, 0x8e, - 0x3d, 0x81, 0xb0, 0x31, 0x1c, 0x3c, 0x52, 0xe6, 0x1f, 0x00, 0x00, 0x8a, - 0x08, 0x6c, 0x46, 0x25, 0x2c, 0x3c, 0x1e, 0x03, 0xc3, 0xc0, 0x1e, 0x9a, - 0x8c, 0x1a, 0x70, 0x55, 0xba, 0xb6, 0x14, 0x3a, 0x44, 0xa9, 0x28, 0xe8, - 0x4a, 0x9d, 0xef, 0xf5, 0x22, 0xa5, 0x89, 0x22, 0xa8, 0x46, 0xaf, 0xdb, - 0xf1, 0x6c, 0x62, 0x76, 0xee, 0x2a, 0xc5, 0x2b, 0x15, 0x22, 0x84, 0x22, - 0xee, 0x14, 0x88, 0x9d, 0x74, 0xb9, 0xbe, 0x40, 0x5d, 0x55, 0x5e, 0xc0, - 0x5c, 0x5d, 0xff, 0x16, 0x42, 0xfd, 0xd2, 0xc9, 0xc8, 0xbe, 0xd1, 0x91, - 0xd9, 0xdd, 0x36, 0x05, 0xb7, 0x03, 0x6b, 0xc1, 0x93, 0x94, 0x2e, 0x55, - 0x31, 0x55, 0xbc, 0x5f, 0xff, 0xac, 0x92, 0xf2, 0xc9, 0x0f, 0x47, 0xa2, - 0x33, 0xe4, 0x9c, 0xb5, 0x32, 0xb9, 0x9b, 0xe4, 0x62, 0x83, 0xa3, 0xfc, - 0xcf, 0x6c, 0xe8, 0xd9, 0x9e, 0xf0, 0x52, 0xf4, 0x44, 0x0d, 0x60, 0x4e, - 0x78, 0x0f, 0xff, 0xa9, 0xe6, 0x45, 0xd4, 0x39, 0x9f, 0x96, 0x32, 0x6d, - 0x22, 0x3e, 0x13, 0x25, 0x89, 0xbf, 0x61, 0x77, 0xad, 0xf6, 0x4f, 0xe6, - 0xc0, 0xf5, 0x17, 0x57, 0xfc, 0xbd, 0x0e, 0x77, 0x0f, 0x8b, 0xd8, 0xfe, - 0x36, 0xab, 0x21, 0x65, 0xf3, 0x2a, 0x14, 0x75, 0x1c, 0x34, 0x5b, 0xc1, - 0x14, 0xc3, 0x56, 0xaa, 0x2b, 0xbe, 0x53, 0xb7, 0xad, 0x0c, 0x97, 0x27, - 0x66, 0x3c, 0x5c, 0xea, 0xad, 0x55, 0xdc, 0xc6, 0xc0, 0xa2, 0x95, 0x05, - 0xbc, 0x58, 0xd4, 0x06, 0x09, 0x06, 0xc9, 0xdb, 0xf6, 0x35, 0x65, 0x69, - 0x4b, 0x3f, 0xd5, 0xb5, 0x1f, 0x2a, 0x1e, 0x95, 0x00, 0x9d, 0x7a, 0x85, - 0x7a, 0xb1, 0x5a, 0x1e, 0x49, 0xc7, 0x20, 0x3f, 0xf7, 0x1b, 0xbb, 0xc4, - 0x7d, 0x18, 0x90, 0x97, 0xc8, 0x79, 0xb1, 0x96, 0x96, 0x2d, 0x35, 0x6d, - 0x9c, 0x24, 0xed, 0x36, 0xec, 0x39, 0x92, 0xa9, 0x6b, 0x6c, 0xa6, 0xe2, - 0xd6, 0x3c, 0x8a, 0xa0, 0xfb, 0x12, 0xa9, 0x56, 0xd4, 0xff, 0xaa, 0xc4, - 0xbe, 0x05, 0x4c, 0x0d, 0xc1, 0x2d, 0x97, 0xa4, 0xf3, 0x4c, 0xa8, 0xd8, - 0x5a, 0xd1, 0x57, 0x34, 0x36, 0xb3, 0xb2, 0x83, 0x0d, 0x32, 0xdf, 0x13, - 0x21, 0xf6, 0xc5, 0xaa, 0x80, 0xfd, 0x1b, 0x25, 0xc2, 0xd4, 0x45, 0x70, - 0x6f, 0x2c, 0x45, 0x5e, 0x2b, 0x53, 0x8c, 0xe7, 0x73, 0x9f, 0x8a, 0x25, - 0x1c, 0xa2, 0x92, 0xd8, 0x8c, 0x35, 0xc0, 0x5a, 0x2e, 0xd8, 0x91, 0xd0, - 0xf4, 0x7d, 0xdb, 0xeb, 0xc2, 0xc4, 0x1e, 0xb5, 0x0f, 0xba, 0x0c, 0x83, - 0x70, 0x12, 0x07, 0x62, 0x10, 0xf4, 0x18, 0xb1, 0x96, 0x7c, 0xaf, 0xd4, - 0xb3, 0xe1, 0xdf, 0xb5, 0x1f, 0xa9, 0xb9, 0x01, 0x2e, 0xd8, 0x69, 0xc6, - 0xb7, 0x93, 0x48, 0xad, 0x36, 0xb3, 0x93, 0xa1, 0xdf, 0xd0, 0xa0, 0x40, - 0x46, 0xa2, 0x4e, 0xff, 0xf7, 0xfc, 0xb3, 0x25, 0x29, 0x94, 0x4e, 0x17, - 0xf2, 0x2f, 0x8c, 0xb5, 0xc2, 0xcf, 0xe0, 0x7b, 0x71, 0x7c, 0x6e, 0x58, - 0xb7, 0x01, 0x82, 0x42, 0xca, 0xb9, 0x25, 0xc9, 0x92, 0x4c, 0x44, 0x68, - 0xf1, 0x83, 0x4d, 0x92, 0x45, 0x28, 0xd5, 0x06, 0xaf, 0x54, 0x03, 0x90, - 0x90, 0xfd, 0x20, 0x18, 0x32, 0x3b, 0x83, 0xa8, 0x36, 0xad, 0xef, 0xf9, - 0xe6, 0x3d, 0x03, 0x9b, 0x3a, 0x08, 0xc6, 0x24, 0x9d, 0xb1, 0xc4, 0xb4, - 0x42, 0xdc, 0x37, 0xf8, 0xd4, 0xbd, 0x20, 0x1d, 0xfd, 0x3e, 0x6b, 0x36, - 0xd5, 0xe0, 0x50, 0x75, 0x9f, 0xa7, 0xdb, 0xe0, 0x45, 0x58, 0x3c, 0xbf, - 0x45, 0xc9, 0x0f, 0x0f, 0x70, 0x7a, 0x5a, 0x24, 0xb3, 0x27, 0x4b, 0x27, - 0xb1, 0x74, 0x1c, 0xf1, 0x55, 0x5c, 0x68, 0x4f, 0x9a, 0x2d, 0xe8, 0x2d, - 0x8b, 0xdc, 0x53, 0x8f, 0x6d, 0x01, 0xce, 0x61, 0x6b, 0x3d, 0xe0, 0x2b, - 0x20, 0xc7, 0x84, 0xc3, 0xa2, 0xe1, 0xfe, 0x45, 0x62, 0x0a, 0x94, 0x7f, - 0xa3, 0x0a, 0x7c, 0xa0, 0x32, 0x9f, 0x52, 0xd6, 0x00, 0xa5, 0xca, 0xba, - 0x0a, 0xbc, 0x40, 0x1c, 0x02, 0xde, 0xa0, 0x8c, 0x39, 0x0f, 0x55, 0x7f, - 0x9f, 0xf8, 0x14, 0xfd, 0x2a, 0x99, 0x45, 0x65, 0xcf, 0x4c, 0xe8, 0xe6, - 0x02, 0x49, 0x89, 0x3d, 0x70, 0x3b, 0x8a, 0x1e, 0xd9, 0x5d, 0x1e, 0x88, - 0x3f, 0x2c, 0x95, 0x1a, 0x23, 0x5d, 0x26, 0x5d, 0xbc, 0xd2, 0xdb, 0x10, - 0xb8, 0xff, 0x87, 0x57, 0xb6, 0x02, 0x2f, 0xae, 0x7b, 0x61, 0x6e, 0xf8, - 0xae, 0x4d, 0x35, 0x00, 0x4a, 0xa5, 0xe2, 0x5b, 0x5e, 0x66, 0xe5, 0x6c, - 0xb7, 0xf9, 0x6b, 0x55, 0x41, 0x5c, 0x9b, 0x39, 0xd9, 0xd1, 0xb3, 0x5a, - 0xbc, 0x2d, 0xc2, 0x53, 0x07, 0xb7, 0x32, 0x11, 0x0b, 0x99, 0x6c, 0xab, - 0x43, 0xcf, 0x96, 0x46, 0x5b, 0xe1, 0x62, 0x35, 0x12, 0xf7, 0x78, 0x80, - 0x1c, 0x60, 0xd0, 0xfe, 0x87, 0xb2, 0x41, 0xb2, 0x0e, 0x2f, 0x14, 0xa1, - 0x87, 0xc9, 0x8f, 0x0b, 0xf4, 0x6f, 0x9a, 0xa2, 0x28, 0x37, 0xd9, 0x29, - 0xb3, 0xde, 0xa9, 0x56, 0x57, 0xfc, 0x6b, 0x29, 0x6f, 0xdb, 0x0f, 0x17, - 0xea, 0x09, 0x40, 0x9e, 0x70, 0xcd, 0x68, 0xcb, 0x1f, 0x4e, 0xe6, 0x49, - 0x11, 0x23, 0x46, 0x27, 0x37, 0x59, 0x65, 0x7f, 0x55, 0xeb, 0x5d, 0x6b, - 0xa8, 0xed, 0xc9, 0xd2, 0xce, 0xa8, 0x11, 0x14, 0x3d, 0x38, 0x4f, 0xda, - 0x4a, 0xa7, 0x5b, 0xaa, 0xb7, 0xad, 0x6f, 0xf6, 0x6a, 0x05, 0xe7, 0xec, - 0xb0, 0x2a, 0x2a, 0x14, 0x05, 0xa5, 0xa7, 0x87, 0xdb, 0xf0, 0xf5, 0xaf, - 0xc9, 0x9c, 0x1b, 0x72, 0x59, 0x14, 0x20, 0xe0, 0xc6, 0x83, 0x0d, 0x7b, - 0x71, 0xbc, 0x2b, 0x90, 0xa9, 0x71, 0x4a, 0x32, 0x21, 0x25, 0x1b, 0x20, - 0x86, 0xcf, 0x25, 0xd5, 0x9d, 0xf7, 0x86, 0x6b, 0x63, 0x34, 0xa9, 0xfd, - 0xe5, 0x03, 0x9d, 0x9c, 0xbb, 0x7b, 0x5b, 0xd9, 0xe9, 0x21, 0x22, 0x91, - 0xba, 0x30, 0xb0, 0x60, 0xac, 0x4b, 0x11, 0xb9, 0x4b, 0x52, 0xb1, 0x39, - 0xde, 0xf3, 0xf3, 0x6f, 0x49, 0x23, 0x87, 0xe0, 0xcd, 0x89, 0x1a, 0x5e, - 0x24, 0xb4, 0xc5, 0x66, 0x4a, 0x9e, 0x6e, 0xa4, 0x2d, 0xd5, 0x11, 0x6e, - 0x16, 0xb5, 0x00, 0x9f, 0x35, 0x40, 0x15, 0x07, 0xc8, 0x80, 0x1c, 0x30, - 0xc0, 0x38, 0xc6, 0x25, 0xf3, 0x4c, 0xb3, 0xb3, 0x9b, 0xc6, 0x79, 0xce, - 0xa2, 0xec, 0x2c, 0xfc, 0x19, 0x18, 0x83, 0x9b, 0x00, 0xa2, 0x97, 0x45, - 0x3a, 0x81, 0xcd, 0x86, 0xa0, 0x3a, 0x10, 0xbc, 0xda, 0xb6, 0xd5, 0xa6, - 0x6f, 0xb6, 0xf3, 0x4b, 0x39, 0xc5, 0x36, 0xa1, 0x80, 0x24, 0x33, 0x5c, - 0xb9, 0x6e, 0x6c, 0xe5, 0x88, 0xc9, 0xc5, 0xad, 0x81, 0xc2, 0xf2, 0xd1, - 0x05, 0xa6, 0x53, 0xc6, 0xb9, 0x8d, 0x15, 0xaf, 0x67, 0xa2, 0x29, 0x2a, - 0x90, 0xe1, 0xc1, 0x1f, 0xc1, 0x00, 0x7d, 0xa5, 0x5f, 0x62, 0xb3, 0x68, - 0x15, 0xfe, 0xd1, 0xcd, 0x19, 0xa0, 0x21, 0x80, 0x89, 0xaa, 0xd7, 0x9e, - 0x1c, 0x3d, 0xf5, 0x57, 0x50, 0x05, 0x8d, 0x96, 0x54, 0x3e, 0x4e, 0xae, - 0x29, 0x6b, 0xca, 0x60, 0x6b, 0x30, 0x1c, 0xa4, 0x8c, 0x83, 0x0c, 0x82, - 0x0b, 0x1b, 0x0b, 0x95, 0x08, 0x39, 0x77, 0x2b, 0x58, 0xc6, 0x42, 0xa5, - 0xd0, 0xc9, 0x0a, 0xa6, 0x83, 0x06, 0xe0, 0xf9, 0x5f, 0xfd, 0xd6, 0xe0, - 0x84, 0x93, 0x33, 0xa1, 0xfc, 0x2c, 0x0e, 0xbd, 0x85, 0x9a, 0xa6, 0xf5, - 0x6e, 0x51, 0x88, 0x31, 0x01, 0x46, 0x12, 0xab, 0x92, 0x03, 0x16, 0x08, - 0x4c, 0xed, 0x0e, 0x53, 0xec, 0x60, 0x18, 0x13, 0x6d, 0x1f, 0x66, 0x23, - 0xf9, 0xda, 0x38, 0x15, 0xb6, 0x16, 0x84, 0x60, 0x6c, 0xf4, 0x98, 0xd9, - 0x7e, 0x29, 0x66, 0xf3, 0x7f, 0xbf, 0xaa, 0x43, 0xd4, 0x21, 0xaa, 0x10, - 0x13, 0x20, 0x7c, 0x74, 0x07, 0x87, 0x59, 0xa3, 0xf2, 0xf6, 0xb5, 0x3d, - 0x5b, 0xde, 0xf2, 0x9b, 0x33, 0xbc, 0xbc, 0xf4, 0xe0, 0xd9, 0x15, 0x06, - 0x27, 0x0a, 0xa3, 0xe2, 0xe6, 0x5b, 0xf6, 0x6a, 0xb9, 0x23, 0x6a, 0x21, - 0x6e, 0x65, 0xb7, 0xd2, 0xa1, 0x0d, 0x42, 0xc5, 0xc4, 0x70, 0x38, 0x3c, - 0x05, 0x68, 0xf4, 0x7b, 0xf9, 0xbe, 0x69, 0xa5, 0x83, 0xf5, 0xd8, 0x6a, - 0x49, 0xc0, 0xf3, 0xca, 0x46, 0xfb, 0xa0, 0xa8, 0xff, 0xc6, 0xc2, 0xc7, - 0xf9, 0x60, 0x58, 0xbb, 0xce, 0x11, 0x3f, 0x00, 0x00, 0x8f, 0x08, 0x2c, - 0x44, 0x23, 0x2c, 0x98, 0x78, 0x6c, 0x19, 0x42, 0x65, 0x15, 0x07, 0x47, - 0x10, 0xe1, 0x26, 0x35, 0x5b, 0x2a, 0x65, 0xd0, 0x33, 0x94, 0xd1, 0x02, - 0x63, 0xad, 0xf0, 0x31, 0x60, 0xf1, 0x06, 0x82, 0xa8, 0xb8, 0x95, 0x71, - 0xc7, 0x97, 0x06, 0x13, 0xcf, 0x99, 0x98, 0x1e, 0xa8, 0xa6, 0xbb, 0x17, - 0x46, 0x86, 0xb8, 0x5c, 0x52, 0x22, 0x72, 0x65, 0x7a, 0x38, 0xee, 0xea, - 0xfa, 0x19, 0x39, 0x60, 0x45, 0x5f, 0x91, 0x1f, 0x51, 0x2c, 0xbd, 0x06, - 0x13, 0xad, 0xad, 0x08, 0x3d, 0xd1, 0x06, 0x6c, 0xed, 0xea, 0x85, 0xce, - 0x29, 0x4b, 0x99, 0xe4, 0x2c, 0x92, 0x31, 0xb0, 0x3b, 0xdd, 0x2b, 0xab, - 0x03, 0x02, 0xeb, 0x2b, 0x40, 0xe9, 0x64, 0x5a, 0x4a, 0xd5, 0x47, 0xb9, - 0x28, 0x6b, 0xde, 0x53, 0x47, 0xe3, 0xe9, 0x58, 0x6a, 0x4d, 0xdf, 0xce, - 0x5e, 0xf0, 0x96, 0xc4, 0x71, 0xc3, 0x78, 0xc2, 0xc5, 0x9d, 0x53, 0x28, - 0x2f, 0x4d, 0x09, 0x7f, 0xeb, 0x6c, 0x78, 0x6d, 0xef, 0x7a, 0x64, 0x42, - 0xbb, 0x8a, 0x64, 0xcf, 0x68, 0x87, 0x2f, 0x59, 0x51, 0x63, 0x5e, 0xb3, - 0xd8, 0x86, 0xdd, 0xb2, 0xf2, 0x86, 0xc4, 0x5d, 0x37, 0x87, 0x3c, 0x67, - 0xf9, 0x0b, 0x6f, 0x69, 0x2f, 0x2d, 0xe8, 0x30, 0xd6, 0x5a, 0x93, 0xed, - 0x64, 0xf5, 0x95, 0x42, 0x72, 0xb8, 0x84, 0x3a, 0x47, 0xc1, 0x38, 0x9d, - 0xae, 0xe2, 0x30, 0x4c, 0x38, 0xfe, 0x99, 0x25, 0xbd, 0x37, 0xe6, 0x86, - 0xa6, 0x8b, 0x7a, 0xb9, 0xb0, 0xaf, 0xb3, 0xcd, 0x63, 0x94, 0x89, 0x7e, - 0xfb, 0xc0, 0x91, 0xd2, 0x29, 0x5a, 0x46, 0x15, 0xb1, 0x1b, 0xec, 0xb1, - 0x00, 0x56, 0x9c, 0x57, 0x9d, 0x86, 0xea, 0x08, 0xbb, 0xcb, 0xd9, 0x43, - 0x20, 0xab, 0xa5, 0x86, 0x06, 0xe5, 0xcb, 0x72, 0x8d, 0xe6, 0xf0, 0xd1, - 0xf4, 0xff, 0xfb, 0xad, 0x30, 0x6f, 0xd2, 0xb5, 0x4a, 0x25, 0xec, 0x0c, - 0xc1, 0x82, 0xa2, 0xa2, 0x3c, 0x50, 0x9c, 0x35, 0x82, 0xf7, 0x2c, 0xd6, - 0x75, 0x86, 0xf9, 0x2e, 0xe9, 0x6c, 0x2a, 0x88, 0xf9, 0x65, 0xeb, 0xf8, - 0xf2, 0xc8, 0x08, 0xdb, 0xe0, 0x44, 0x4a, 0xc3, 0x3f, 0x99, 0x2d, 0xf0, - 0x81, 0xd4, 0x52, 0xfe, 0xf2, 0xc0, 0xaa, 0x12, 0x97, 0x2a, 0x2f, 0xf8, - 0xe3, 0x8a, 0x20, 0xe2, 0xe7, 0x99, 0xc5, 0xb9, 0xce, 0x76, 0x5a, 0x22, - 0xe2, 0x90, 0x4a, 0x86, 0x3d, 0xe1, 0xd3, 0x0a, 0x12, 0xe1, 0x6b, 0x69, - 0x6c, 0x2c, 0xcc, 0xc1, 0xcc, 0xf2, 0xfc, 0x85, 0xaa, 0x0a, 0x86, 0xd5, - 0x48, 0x30, 0x9d, 0x1e, 0xa8, 0x1c, 0x4c, 0x5a, 0xc9, 0x75, 0x17, 0x39, - 0x2a, 0x29, 0x01, 0x69, 0x8c, 0xe9, 0x56, 0x91, 0xb6, 0x3d, 0xf0, 0xfc, - 0xbc, 0x20, 0x37, 0x58, 0x52, 0xa7, 0xdd, 0x5f, 0xda, 0x1d, 0x6c, 0x37, - 0x03, 0x83, 0x22, 0x01, 0xd0, 0x86, 0xa9, 0x2d, 0x51, 0x29, 0x66, 0x83, - 0x1a, 0xd0, 0xca, 0x50, 0x4b, 0x2a, 0x10, 0x47, 0x5a, 0xd8, 0x32, 0xf8, - 0x57, 0x79, 0x0b, 0x4d, 0x8a, 0x43, 0xba, 0xf9, 0x4d, 0x3c, 0xbe, 0x29, - 0x05, 0xb1, 0x53, 0x3c, 0xc8, 0xa5, 0xb2, 0x2c, 0xad, 0x7c, 0x33, 0x17, - 0x9d, 0x38, 0x9d, 0x9f, 0x79, 0x2b, 0x0a, 0x7c, 0x39, 0xab, 0x21, 0x92, - 0xc9, 0x3c, 0x8c, 0xac, 0x52, 0x13, 0x41, 0x48, 0xcf, 0xd5, 0x89, 0x49, - 0xeb, 0x34, 0xb7, 0x55, 0x33, 0xc9, 0xfd, 0x5f, 0x54, 0x59, 0x81, 0xe0, - 0x38, 0xc5, 0x7f, 0x28, 0x22, 0xd6, 0x74, 0xad, 0x6e, 0x44, 0x0b, 0x42, - 0x2f, 0x21, 0x1b, 0x7a, 0x73, 0x45, 0xad, 0xa8, 0x5f, 0xf8, 0xad, 0x95, - 0x17, 0xbc, 0xbe, 0xe5, 0xc1, 0x97, 0x01, 0x86, 0x81, 0xc8, 0x7a, 0x0f, - 0x05, 0x01, 0x98, 0x06, 0x2b, 0xf9, 0x7e, 0xb0, 0x3f, 0x57, 0x59, 0x53, - 0x83, 0x8f, 0x16, 0x65, 0xfc, 0xf8, 0x31, 0x54, 0xb7, 0x01, 0x83, 0x8d, - 0x80, 0xc1, 0x52, 0xca, 0xd4, 0xee, 0xac, 0x8b, 0x90, 0xb4, 0xdf, 0x0d, - 0x47, 0x88, 0x47, 0xe9, 0x02, 0x11, 0x7a, 0x61, 0xc2, 0xb6, 0x26, 0xf8, - 0xab, 0x7f, 0x36, 0xf1, 0x78, 0xbc, 0xb4, 0x09, 0x82, 0x52, 0xe6, 0x6f, - 0x16, 0xa0, 0x92, 0x54, 0x84, 0x6d, 0xd2, 0xaa, 0xca, 0x74, 0x8d, 0x27, - 0x6f, 0xdb, 0x3f, 0xff, 0x79, 0xbb, 0xb8, 0x1d, 0x77, 0xfe, 0xe8, 0x79, - 0x43, 0x83, 0xab, 0x88, 0x60, 0x1a, 0x10, 0xc4, 0xa4, 0x89, 0x01, 0x13, - 0x1a, 0xd9, 0xbf, 0x04, 0x46, 0xfb, 0x9f, 0xac, 0xce, 0xfe, 0xf2, 0x50, - 0x24, 0x55, 0xe3, 0x2b, 0x8f, 0x1b, 0xf4, 0x55, 0xaa, 0xb4, 0xaf, 0xd9, - 0xa0, 0xac, 0x43, 0x4b, 0x2a, 0x25, 0xc3, 0x6e, 0x28, 0x05, 0x70, 0x58, - 0x30, 0x11, 0xf7, 0x22, 0x7b, 0x20, 0x32, 0x1f, 0x45, 0x11, 0x41, 0x50, - 0x78, 0xb7, 0x3a, 0x1c, 0x83, 0x04, 0x62, 0x97, 0x0b, 0x78, 0xd5, 0x2a, - 0xa6, 0x0a, 0x3c, 0xd8, 0xb8, 0x47, 0x06, 0xd5, 0x41, 0x09, 0x21, 0x73, - 0x52, 0xf3, 0xec, 0xa8, 0xcc, 0x9c, 0x1b, 0x67, 0x03, 0xd6, 0xe8, 0x6e, - 0xa6, 0x39, 0x41, 0x2b, 0xdf, 0x12, 0xee, 0x33, 0x17, 0x4d, 0xff, 0xd6, - 0xd4, 0xc5, 0xfd, 0xff, 0xd0, 0xef, 0xfd, 0x11, 0x77, 0x4e, 0x06, 0x51, - 0xe8, 0x1c, 0xf3, 0x2c, 0xe2, 0xb5, 0x7e, 0xad, 0xa9, 0xf2, 0xf9, 0x2f, - 0x26, 0x67, 0x56, 0xed, 0x0e, 0x54, 0x38, 0x4c, 0x10, 0x82, 0x00, 0x94, - 0xd6, 0x65, 0x54, 0xac, 0x77, 0xea, 0xb7, 0x1a, 0x05, 0x5b, 0x73, 0xde, - 0xd1, 0xbd, 0xe3, 0x19, 0xb8, 0xc6, 0xe2, 0x3c, 0x2b, 0xf0, 0xb4, 0x61, - 0x9f, 0x7d, 0x50, 0xde, 0x7b, 0x42, 0xd7, 0xb0, 0xf2, 0x61, 0x6d, 0x47, - 0x95, 0x4e, 0x35, 0x92, 0x2c, 0xbe, 0xc5, 0xad, 0xa6, 0x9e, 0xa2, 0x97, - 0x9e, 0x61, 0x56, 0xf8, 0xac, 0x41, 0xd6, 0x40, 0xa1, 0x5a, 0x0a, 0x40, - 0x80, 0x96, 0x98, 0x7e, 0x90, 0x79, 0xe1, 0xff, 0xb2, 0x83, 0x23, 0x8b, - 0x71, 0x4e, 0xcc, 0xb2, 0xae, 0x08, 0xe0, 0x20, 0xe1, 0x35, 0x6e, 0xd4, - 0x2b, 0x67, 0x8c, 0x31, 0x72, 0x5f, 0xd9, 0x3f, 0x7f, 0x6c, 0x05, 0x60, - 0x15, 0xe7, 0x01, 0x90, 0x81, 0x00, 0x61, 0x88, 0x25, 0x0d, 0x81, 0xb9, - 0x04, 0x65, 0x6a, 0xd3, 0x62, 0x78, 0xad, 0x81, 0xc8, 0xe7, 0x32, 0x81, - 0x76, 0xa7, 0xd1, 0xca, 0x1c, 0xe2, 0x91, 0x14, 0xb4, 0x18, 0x12, 0xc7, - 0x25, 0xe1, 0x04, 0x1b, 0x83, 0xed, 0x1d, 0x8f, 0x59, 0xd6, 0xbd, 0xb9, - 0x60, 0xf9, 0x0a, 0xb4, 0xf4, 0xd2, 0x68, 0x87, 0x30, 0x39, 0x06, 0x22, - 0x06, 0x48, 0xfc, 0x1a, 0x8e, 0xd3, 0x8f, 0xc1, 0x4f, 0x35, 0x46, 0xf9, - 0x6f, 0x51, 0xbe, 0xa8, 0x88, 0x8b, 0x6e, 0x8d, 0xc1, 0x86, 0x94, 0x72, - 0x02, 0x9a, 0xe8, 0x58, 0xd9, 0x5c, 0xf9, 0xe4, 0x47, 0x27, 0x1d, 0x06, - 0x4e, 0x01, 0xbc, 0xe0, 0x29, 0xf8, 0x4b, 0x18, 0x6a, 0x51, 0x98, 0x08, - 0x95, 0x40, 0xc9, 0x40, 0xeb, 0x1b, 0x77, 0x53, 0x87, 0xf2, 0xa3, 0xf3, - 0x39, 0x2e, 0x0c, 0xb8, 0x36, 0x7a, 0xd4, 0xf9, 0x50, 0x05, 0x9d, 0x65, - 0xcd, 0x86, 0xb0, 0x64, 0xe3, 0xb4, 0xc9, 0xb4, 0x46, 0x10, 0x58, 0x10, - 0x78, 0x9c, 0x72, 0x59, 0xdb, 0x36, 0x7a, 0x4b, 0x2d, 0xf5, 0x82, 0x2a, - 0x9b, 0x01, 0x24, 0xa3, 0x69, 0x8b, 0x87, 0xa9, 0x15, 0x04, 0x34, 0x8d, - 0xed, 0x9e, 0xb1, 0xb8, 0x86, 0xd9, 0x65, 0xef, 0x83, 0x6d, 0xc3, 0xe6, - 0xc2, 0x18, 0x8f, 0xf0, 0x82, 0x94, 0x3f, 0xd0, 0xf3, 0x8d, 0x66, 0x4c, - 0xea, 0xd3, 0x92, 0x77, 0x80, 0x4f, 0xa6, 0x42, 0x98, 0x30, 0x90, 0x3b, - 0xc6, 0xbc, 0x0c, 0x58, 0xae, 0x95, 0x2b, 0xba, 0xdb, 0x55, 0x16, 0x42, - 0xc8, 0xba, 0xe3, 0x10, 0x61, 0xa7, 0x8c, 0xaf, 0x49, 0xbc, 0x16, 0xb7, - 0x81, 0x57, 0x0b, 0x2d, 0xb1, 0x4c, 0x91, 0x10, 0x8a, 0xb3, 0x83, 0x30, - 0xf4, 0x20, 0xb2, 0xcf, 0xf3, 0xc9, 0x18, 0xd4, 0x89, 0x27, 0x03, 0xfd, - 0x56, 0x55, 0xb7, 0x6a, 0x3f, 0x12, 0x28, 0x07, 0x07, 0xa1, 0x60, 0x88, - 0xbc, 0x7a, 0xab, 0xdc, 0x6c, 0xb9, 0x26, 0x2b, 0x34, 0xdf, 0xf9, 0x9e, - 0x44, 0x1d, 0x95, 0x95, 0xe8, 0x2a, 0x03, 0xa2, 0xd0, 0x62, 0x73, 0x62, - 0x1a, 0xa1, 0xe8, 0x43, 0x6c, 0xb5, 0x8c, 0xef, 0x76, 0xd1, 0xc7, 0x96, - 0xed, 0xa8, 0xed, 0x50, 0x54, 0xa4, 0xc8, 0xb3, 0x2d, 0xef, 0x22, 0x8a, - 0x75, 0x3f, 0xfe, 0x9e, 0x6f, 0x60, 0x80, 0xc2, 0x56, 0x9b, 0xda, 0xa7, - 0x54, 0x42, 0xbd, 0xee, 0xf1, 0x9b, 0x17, 0xbe, 0xaa, 0x14, 0x28, 0xc5, - 0xf0, 0x58, 0x26, 0x4d, 0x37, 0x74, 0x0c, 0x4d, 0xfe, 0xff, 0x94, 0x6f, - 0xdb, 0x79, 0x16, 0x91, 0x49, 0x56, 0x00, 0x82, 0x63, 0xa0, 0x38, 0x24, - 0xe7, 0xb0, 0x72, 0xa3, 0x35, 0x85, 0xd4, 0x56, 0xe6, 0xa9, 0xc8, 0xb4, - 0x9c, 0xc2, 0x97, 0x0b, 0x41, 0x08, 0x78, 0xda, 0xa8, 0xad, 0x2a, 0x55, - 0x19, 0x54, 0x48, 0xc7, 0xb1, 0x16, 0x67, 0x3b, 0xf0, 0x26, 0xa5, 0xd3, - 0xdf, 0x2c, 0x62, 0xef, 0xfd, 0xfe, 0xe8, 0x31, 0x14, 0xca, 0xb1, 0x13, - 0x61, 0x74, 0x74, 0x95, 0x9f, 0x35, 0xf0, 0xfd, 0x37, 0xd2, 0x31, 0xec, - 0x0e, 0xd9, 0xbe, 0x85, 0xb2, 0x4e, 0xff, 0xeb, 0x16, 0x95, 0x61, 0xe0, - 0x60, 0x83, 0x32, 0x0d, 0xf4, 0xe2, 0x3a, 0xb9, 0xe4, 0x95, 0xb6, 0x07, - 0x4d, 0x68, 0x18, 0x40, 0x1f, 0xd8, 0x0c, 0x87, 0xe0, 0xe0, 0x29, 0x80, - 0xe3, 0x21, 0x9c, 0x14, 0xa2, 0x3b, 0x2c, 0xfa, 0x2a, 0x54, 0x1e, 0x35, - 0x7b, 0x55, 0xd5, 0xef, 0xef, 0xa2, 0x29, 0xcc, 0x04, 0x70, 0x61, 0x30, - 0xc1, 0x76, 0xd4, 0x67, 0xb3, 0x29, 0x66, 0xc0, 0x33, 0xd5, 0xf9, 0x51, - 0xda, 0x0b, 0x41, 0xbf, 0xfa, 0xa8, 0x9b, 0x51, 0x99, 0x30, 0xc9, 0x6a, - 0x0f, 0x87, 0x1e, 0x1d, 0x0e, 0xac, 0x5f, 0xe0, 0xaa, 0x4d, 0xde, 0xaf, - 0x3a, 0x38, 0xf1, 0x02, 0x82, 0x08, 0x71, 0x9d, 0xde, 0x2f, 0xbc, 0xe4, - 0x14, 0x2e, 0x3c, 0x52, 0x0a, 0xa2, 0xe5, 0x1d, 0xb4, 0x14, 0xca, 0x86, - 0x03, 0x87, 0x18, 0x10, 0x0b, 0xf7, 0x96, 0x67, 0x09, 0x77, 0xf2, 0x2c, - 0x6f, 0x86, 0x1b, 0xe1, 0x54, 0x3a, 0x9e, 0x8c, 0xce, 0x29, 0x45, 0xf4, - 0x4a, 0x3c, 0x50, 0x84, 0x44, 0x04, 0x70, 0x7c, 0x98, 0x01, 0xd4, 0xac, - 0xb7, 0x6f, 0x95, 0x62, 0xbb, 0x2d, 0xc5, 0x3b, 0xde, 0xa8, 0x99, 0x10, - 0x41, 0xc1, 0x69, 0x58, 0x6c, 0x58, 0x2c, 0x59, 0xb9, 0xf9, 0xb2, 0x02, - 0xb2, 0xea, 0x95, 0xf9, 0x6a, 0xeb, 0xaf, 0x3a, 0xa1, 0x40, 0x5a, 0xb3, - 0x77, 0xa2, 0x1b, 0x05, 0xf1, 0x5a, 0x72, 0xea, 0x93, 0x2f, 0xab, 0x4c, - 0x37, 0xd6, 0x9b, 0xcf, 0xcb, 0xd8, 0xcc, 0xc2, 0xdc, 0x6f, 0x34, 0x15, - 0xc5, 0xa5, 0x86, 0x09, 0xf0, 0xa8, 0xc2, 0xd3, 0x52, 0xa6, 0x50, 0xe4, - 0x31, 0x06, 0x0a, 0x4d, 0x17, 0xf9, 0xb2, 0xdc, 0xea, 0xf6, 0xdd, 0x51, - 0xd4, 0x5c, 0xa7, 0x05, 0xf3, 0xf9, 0xe6, 0xae, 0x94, 0x92, 0x89, 0x85, - 0x09, 0x38, 0x9d, 0xab, 0x3f, 0xcd, 0x5e, 0xac, 0x87, 0xb6, 0xf5, 0x67, - 0xc2, 0xdc, 0x99, 0x61, 0x23, 0xcc, 0xb1, 0xcf, 0x25, 0xb8, 0xdb, 0x3c, - 0x2d, 0xdf, 0xe6, 0x16, 0x4e, 0x5b, 0x6f, 0xa7, 0x14, 0xfc, 0x44, 0xe1, - 0x68, 0x31, 0x3c, 0xb0, 0xb8, 0x2f, 0xd3, 0xa5, 0xc5, 0x9c, 0xad, 0x77, - 0xb7, 0x83, 0x2e, 0x11, 0xbf, 0x2d, 0x17, 0x46, 0x8f, 0xa5, 0x0e, 0xa6, - 0xcf, 0xb5, 0x9a, 0x2f, 0x57, 0xca, 0x58, 0x86, 0x0b, 0x90, 0x3b, 0xb0, - 0x93, 0x19, 0x2b, 0xfd, 0xa1, 0xb9, 0xaa, 0x48, 0x0b, 0x61, 0xa7, 0xf5, - 0x4a, 0x7d, 0x6d, 0x07, 0x68, 0xc3, 0xa7, 0x05, 0xca, 0xa7, 0x0a, 0xd0, - 0x03, 0xba, 0xeb, 0x6d, 0x60, 0x44, 0x07, 0x82, 0xff, 0x8d, 0xaf, 0xe0, - 0x30, 0x16, 0xf7, 0xbb, 0x98, 0x1c, 0x6f, 0xaf, 0x00, 0x9a, 0x93, 0xa9, - 0xa3, 0x7d, 0x0e, 0xbc, 0xc8, 0x2b, 0x75, 0x95, 0xad, 0xfd, 0x29, 0xe5, - 0xa7, 0xfb, 0x8b, 0x85, 0x8a, 0x07, 0x65, 0xcd, 0x6a, 0xa5, 0x6a, 0xef, - 0x6f, 0xd4, 0x4f, 0x40, 0xe3, 0x9c, 0xef, 0x78, 0x1c, 0x9c, 0x3a, 0x01, - 0xd9, 0xdf, 0x0f, 0xe7, 0xb4, 0xb1, 0x92, 0xcf, 0x16, 0x74, 0x67, 0xd0, - 0x61, 0xaa, 0x63, 0xfd, 0xe8, 0xf9, 0x5b, 0x5e, 0x1b, 0xf7, 0xbf, 0x24, - 0xce, 0x68, 0x44, 0x90, 0x07, 0x42, 0xc5, 0x41, 0xfd, 0x2a, 0xd6, 0xd5, - 0x8e, 0x0d, 0xac, 0x58, 0xb0, 0x66, 0xf7, 0x3a, 0x83, 0x10, 0x97, 0x99, - 0xad, 0xb4, 0xa9, 0x36, 0x96, 0x34, 0xd4, 0x03, 0x7a, 0x56, 0x8b, 0x27, - 0xea, 0xdc, 0x85, 0x44, 0x97, 0x0a, 0xc0, 0xae, 0xe0, 0x0a, 0xa6, 0xbe, - 0x5a, 0xde, 0xe2, 0x8b, 0x9c, 0xdc, 0x1b, 0xad, 0x6d, 0xb1, 0x7a, 0x0c, - 0x35, 0x32, 0x07, 0x53, 0x7c, 0x70, 0x5b, 0x8a, 0x6f, 0x95, 0x5b, 0xb7, - 0x00, 0x86, 0xf6, 0x4f, 0x37, 0x0d, 0x29, 0x3a, 0xaa, 0x46, 0x7f, 0xa3, - 0xd9, 0xbf, 0xfa, 0x9c, 0x60, 0x7c, 0xab, 0xbd, 0x1b, 0xdb, 0x60, 0x2c, - 0x41, 0x82, 0xa6, 0x96, 0x77, 0xd1, 0xed, 0x88, 0x99, 0xf5, 0xfc, 0x88, - 0x64, 0xdd, 0xec, 0x0d, 0xa3, 0xc5, 0x21, 0x0c, 0x75, 0x5a, 0xa2, 0x0f, - 0xb2, 0x96, 0x7e, 0xef, 0x20, 0x70, 0x48, 0x7c, 0x52, 0xb5, 0x97, 0x11, - 0xcb, 0x41, 0x38, 0x2e, 0xb3, 0xf8, 0x55, 0x2e, 0x62, 0x8d, 0xe8, 0xa1, - 0xf1, 0xe7, 0xb5, 0xa5, 0x8f, 0x6d, 0x50, 0x6c, 0x51, 0x44, 0x21, 0xfe, - 0x45, 0xbe, 0x1f, 0x95, 0x94, 0x96, 0x4a, 0xe3, 0xa3, 0xf4, 0xfd, 0xfb, - 0x6c, 0x76, 0xb5, 0xb7, 0x9d, 0xda, 0xbc, 0xdc, 0x43, 0x39, 0xa5, 0xaa, - 0x11, 0xcd, 0x2a, 0x2c, 0x04, 0x8a, 0x1e, 0x35, 0x89, 0x3e, 0x5e, 0xd6, - 0x49, 0x31, 0x3e, 0xcf, 0xc4, 0x12, 0x3f, 0x08, 0xe3, 0xaf, 0xea, 0x7e, - 0xf0, 0x13, 0x89, 0x54, 0xa0, 0xb6, 0xca, 0x0c, 0x4c, 0x57, 0xb5, 0x4f, - 0xe8, 0x2d, 0xdb, 0x2a, 0xab, 0xfe, 0x69, 0x8b, 0xe5, 0xd9, 0xca, 0x37, - 0xbf, 0xbd, 0xde, 0x2c, 0xbc, 0xa1, 0xc2, 0x20, 0x10, 0x32, 0x03, 0xb9, - 0x8a, 0xb8, 0xaf, 0xea, 0xfc, 0x1f, 0x67, 0xe7, 0xba, 0xa3, 0xf1, 0x45, - 0xbc, 0x2c, 0x58, 0x34, 0xa0, 0x94, 0x7d, 0xa6, 0x1b, 0x4c, 0xc8, 0xe3, - 0xe3, 0x6f, 0xc0, 0xf0, 0x92, 0xdb, 0x0e, 0x12, 0x06, 0x12, 0x73, 0xd4, - 0x21, 0x6c, 0x6f, 0x73, 0x19, 0xe6, 0x08, 0x1e, 0x11, 0x7f, 0x3d, 0x64, - 0x0c, 0x41, 0x82, 0xa4, 0x1c, 0xd6, 0x39, 0xb1, 0x19, 0x89, 0xba, 0x59, - 0x87, 0xdb, 0x17, 0x17, 0x30, 0xaa, 0xb5, 0xce, 0xdd, 0x2d, 0x91, 0x7e, - 0xcb, 0xef, 0xc5, 0x97, 0x61, 0x40, 0x25, 0x0a, 0x87, 0x62, 0x40, 0xe5, - 0x88, 0xd3, 0x5f, 0x8d, 0x7d, 0x4e, 0x37, 0x9b, 0x62, 0x98, 0xb0, 0x14, - 0xb0, 0x16, 0xe0, 0xd0, 0x60, 0x19, 0x58, 0x1f, 0x04, 0x0c, 0xd4, 0xc3, - 0xc4, 0xf8, 0x59, 0xb6, 0x87, 0x9b, 0x91, 0x96, 0xb0, 0x15, 0xca, 0x46, - 0xdb, 0xa0, 0x55, 0x40, 0x31, 0x1d, 0xf8, 0x18, 0x4b, 0x04, 0x36, 0xd3, - 0xa9, 0x6c, 0x7f, 0x85, 0x7d, 0x06, 0x02, 0x8d, 0x45, 0x1d, 0x02, 0x1c, - 0xc0, 0x10, 0x3b, 0x4b, 0xfa, 0x37, 0x70, 0xc0, 0x7f, 0xd2, 0x06, 0xc2, - 0x82, 0x61, 0x20, 0x79, 0xa3, 0x82, 0xe0, 0xff, 0xe0, 0xdd, 0xcc, 0xfa, - 0xbf, 0xe7, 0x95, 0x96, 0x37, 0x65, 0xa1, 0xec, 0xfb, 0x01, 0xee, 0x0e, - 0x17, 0x50, 0x56, 0x5a, 0x0c, 0x70, 0xd3, 0x3e, 0x89, 0x36, 0xae, 0x38, - 0xef, 0xca, 0xa2, 0x3b, 0xc2, 0x62, 0x41, 0x00, 0x03, 0x7c, 0x01, 0x83, - 0xb0, 0x61, 0x04, 0xbc, 0x41, 0x67, 0xfb, 0xe6, 0x70, 0xa8, 0xaf, 0x6d, - 0xf9, 0x2b, 0x7a, 0x2a, 0xa6, 0x41, 0x84, 0x30, 0x36, 0x3f, 0xd5, 0x7f, - 0x2e, 0xd2, 0xc4, 0x7e, 0xc1, 0x06, 0x76, 0x5e, 0xac, 0x0c, 0x09, 0x4f, - 0x5b, 0x9a, 0x47, 0xe3, 0x7d, 0x05, 0xb3, 0x62, 0x81, 0x0b, 0xd2, 0xf9, - 0xa9, 0xab, 0xaf, 0x34, 0xa7, 0x51, 0x9f, 0x38, 0x0c, 0xac, 0x18, 0x4b, - 0x11, 0x81, 0x01, 0x8f, 0xb1, 0xdf, 0x17, 0x8e, 0xee, 0x52, 0xc1, 0xe6, - 0x2e, 0xa2, 0xf1, 0x1a, 0x70, 0x63, 0x4d, 0x03, 0xe5, 0xff, 0xf6, 0x78, - 0x20, 0x83, 0x0e, 0xc4, 0x31, 0x24, 0x0c, 0x34, 0xcb, 0x63, 0xe2, 0xee, - 0x70, 0x3e, 0x63, 0x54, 0x29, 0x25, 0xff, 0xf0, 0xaf, 0x43, 0x40, 0x48, - 0x1f, 0x87, 0x77, 0xb6, 0xdb, 0x6a, 0x1d, 0x5e, 0x8d, 0x4d, 0xaf, 0x70, - 0xb6, 0xa0, 0x6b, 0x08, 0x61, 0x0c, 0x7e, 0x07, 0xd2, 0xd4, 0xa3, 0xf6, - 0xcb, 0x75, 0x16, 0x64, 0x2a, 0x69, 0x8f, 0x20, 0x69, 0x8f, 0x0d, 0x9a, - 0xc3, 0x07, 0xd8, 0x59, 0x07, 0x99, 0xae, 0x64, 0x3e, 0x9b, 0x6c, 0x5f, - 0x48, 0x2b, 0x4f, 0xd0, 0xe9, 0x25, 0x79, 0x2a, 0xac, 0x37, 0x20, 0x66, - 0x41, 0x6b, 0x43, 0x48, 0xa2, 0xa7, 0x62, 0x7f, 0x85, 0x97, 0xf9, 0x36, - 0xd4, 0x52, 0x5b, 0x27, 0x68, 0x6d, 0x82, 0x63, 0x23, 0xd4, 0x9f, 0x12, - 0x87, 0xe9, 0x03, 0xf1, 0xd3, 0x25, 0xf9, 0x3c, 0x20, 0x2a, 0xd6, 0xb7, - 0x89, 0x3f, 0x2c, 0xbd, 0xa0, 0x61, 0x4e, 0xc0, 0x54, 0x30, 0x1e, 0x0d, - 0xcc, 0x8d, 0x02, 0xe0, 0x33, 0x56, 0x7c, 0x10, 0x07, 0x55, 0x19, 0x56, - 0xe6, 0x9b, 0xef, 0xbf, 0x70, 0x1f, 0x5e, 0x00, 0x52, 0x15, 0x2f, 0x5e, - 0x58, 0xb1, 0xb3, 0x40, 0xca, 0x5a, 0xf2, 0x62, 0xd2, 0xc8, 0xa2, 0x28, - 0x9a, 0x5d, 0xf5, 0xac, 0xb6, 0xc9, 0xce, 0x69, 0x59, 0x50, 0x72, 0x64, - 0x2c, 0x29, 0x2e, 0x2f, 0x61, 0xb0, 0x6e, 0x7e, 0xa4, 0x4e, 0x59, 0x40, - 0xb7, 0xd4, 0x73, 0x49, 0x4a, 0x8a, 0xd4, 0x19, 0x26, 0x23, 0x8f, 0x18, - 0x1f, 0xa4, 0x6f, 0x2c, 0x0f, 0x67, 0xba, 0xd5, 0x42, 0xa6, 0x22, 0x9d, - 0x1a, 0x87, 0x71, 0xd4, 0x4b, 0xe5, 0x7b, 0x6f, 0xa3, 0x5c, 0xdb, 0xf5, - 0x25, 0xbd, 0xe6, 0xa2, 0xab, 0x28, 0x11, 0x75, 0xf7, 0xfa, 0x89, 0x63, - 0x85, 0x3d, 0x31, 0xda, 0xa1, 0x1c, 0x20, 0xaa, 0x66, 0xb4, 0xad, 0x3f, - 0x6c, 0xcc, 0xcd, 0x0f, 0xf2, 0x55, 0xe5, 0x47, 0x37, 0x14, 0x6e, 0xe0, - 0x2d, 0xd6, 0x68, 0x20, 0xe8, 0x29, 0xbe, 0xd3, 0x21, 0xe5, 0xf9, 0x66, - 0x0e, 0x5a, 0xbc, 0xca, 0xbc, 0x97, 0x81, 0xc6, 0x99, 0x16, 0xab, 0x2c, - 0x6f, 0x9f, 0x6d, 0xbf, 0x4f, 0xf9, 0x66, 0xe6, 0x0d, 0xed, 0x40, 0xb0, - 0x88, 0x54, 0x7c, 0x73, 0xbe, 0x1b, 0x60, 0x22, 0xa8, 0x54, 0xa0, 0x3f, - 0xdf, 0x7d, 0x78, 0x89, 0x1f, 0x44, 0x42, 0x33, 0xff, 0xf4, 0x05, 0xaa, - 0x5d, 0x5b, 0x36, 0x10, 0xd5, 0x35, 0x90, 0x3f, 0x6b, 0xf7, 0x18, 0xdd, - 0xc2, 0xdf, 0x72, 0xe9, 0x65, 0xa0, 0x54, 0xa8, 0xae, 0x62, 0x90, 0xec, - 0x1c, 0x64, 0x42, 0x3e, 0x12, 0x1b, 0xcd, 0x2c, 0xe7, 0x3f, 0xfe, 0x8e, - 0x16, 0xeb, 0x4d, 0xf5, 0x15, 0xee, 0x08, 0xaa, 0x00, 0x49, 0x31, 0xf3, - 0x43, 0xc6, 0xfa, 0x38, 0x6d, 0x4d, 0x51, 0x54, 0x45, 0x2b, 0x20, 0x5e, - 0x06, 0xc7, 0x42, 0xd8, 0x40, 0x1c, 0x82, 0x20, 0x19, 0xde, 0xf3, 0xfb, - 0x3d, 0x10, 0xe6, 0x14, 0x89, 0x8b, 0xd6, 0xeb, 0x72, 0x78, 0x82, 0xca, - 0x16, 0xbf, 0x00, 0x00, 0x99, 0x08, 0x2c, 0x2c, 0x88, 0x5a, 0x0f, 0x05, - 0x00, 0xd8, 0xea, 0x23, 0xa0, 0xa6, 0x2e, 0x19, 0x40, 0xf8, 0xc1, 0x66, - 0xe6, 0xa2, 0x9b, 0x7c, 0x4a, 0x43, 0x22, 0x52, 0x8f, 0x08, 0xc2, 0x57, - 0x06, 0xf4, 0x78, 0x5c, 0x0f, 0x17, 0x00, 0x6c, 0x3a, 0xbb, 0x6a, 0xd4, - 0x23, 0x19, 0x04, 0xa2, 0x82, 0x51, 0x13, 0x9b, 0x31, 0x8c, 0x66, 0x76, - 0x4f, 0xdb, 0xab, 0xaf, 0xc5, 0x86, 0x01, 0x6c, 0xc5, 0x4d, 0x35, 0xf0, - 0xe6, 0xac, 0x37, 0x93, 0xa7, 0x14, 0x6a, 0xee, 0xd9, 0x7b, 0x02, 0x22, - 0xb5, 0x65, 0xd1, 0x84, 0xc9, 0x87, 0x21, 0xe6, 0xd7, 0x1e, 0xea, 0xc3, - 0x45, 0x53, 0x08, 0x31, 0x57, 0xfe, 0xc2, 0x06, 0x73, 0xbd, 0x5e, 0x58, - 0x59, 0x7b, 0x02, 0x83, 0x42, 0x4f, 0xd1, 0x41, 0x58, 0xa0, 0xb9, 0x57, - 0xa0, 0x8d, 0x24, 0x02, 0xb9, 0x7f, 0x4a, 0x6f, 0x29, 0xf7, 0xa4, 0x35, - 0xe9, 0x93, 0x4c, 0x3d, 0x2d, 0xe1, 0x6c, 0x51, 0x69, 0x27, 0x20, 0xc0, - 0x12, 0x8b, 0xa7, 0x5b, 0xda, 0xa1, 0x69, 0xca, 0x4a, 0xb9, 0xf1, 0xae, - 0xfa, 0xf9, 0x9d, 0xca, 0x36, 0xf8, 0xba, 0x55, 0xe5, 0x06, 0x13, 0x0a, - 0x30, 0xad, 0x8c, 0xcb, 0x66, 0xd9, 0xce, 0xa0, 0x9c, 0x90, 0x8d, 0xd1, - 0x98, 0xa9, 0x8d, 0xd1, 0x3c, 0x50, 0x3a, 0xef, 0xe1, 0x65, 0x44, 0x13, - 0x12, 0x9e, 0xca, 0x20, 0xea, 0x9f, 0x6c, 0x62, 0x55, 0x3c, 0xfa, 0x14, - 0x73, 0xa5, 0x40, 0x90, 0x2f, 0x12, 0x3d, 0xd1, 0xf3, 0x4a, 0xd6, 0xbf, - 0x67, 0x27, 0xcb, 0x62, 0x2b, 0x96, 0x07, 0x9c, 0x0d, 0x94, 0x3e, 0xfb, - 0x08, 0x6d, 0x45, 0x96, 0xc5, 0x9d, 0x26, 0x97, 0xcd, 0xd9, 0xa8, 0xcf, - 0xac, 0x3f, 0x57, 0xe6, 0x9a, 0xe5, 0xb7, 0x2e, 0xad, 0x14, 0x73, 0xb3, - 0xb1, 0x1c, 0x0b, 0x53, 0x2c, 0xe7, 0xc1, 0x97, 0xbf, 0x55, 0x11, 0x37, - 0xf9, 0x3f, 0xbd, 0xe5, 0xe7, 0x96, 0xb2, 0x06, 0xb9, 0xd3, 0x10, 0xcd, - 0xbe, 0x03, 0x1e, 0x88, 0x94, 0x07, 0xd8, 0x36, 0x88, 0xd1, 0x06, 0x60, - 0x2c, 0xf2, 0x41, 0x03, 0x0b, 0x2f, 0x8b, 0x69, 0x5c, 0x52, 0xa7, 0x54, - 0xe8, 0x2b, 0xfa, 0x16, 0x13, 0x4f, 0x97, 0xe2, 0x0e, 0xf6, 0xf3, 0xcc, - 0xf9, 0x5c, 0xe2, 0xdd, 0x92, 0xae, 0xe7, 0x19, 0x0b, 0xcb, 0xe2, 0x5c, - 0x51, 0x72, 0xf3, 0x07, 0x1f, 0x6a, 0x7b, 0xf2, 0xf3, 0x92, 0xca, 0x81, - 0x48, 0xa4, 0x71, 0x5a, 0xd5, 0x43, 0xdd, 0xd5, 0xaf, 0xb0, 0x3e, 0x52, - 0xd9, 0xbf, 0x7f, 0xc0, 0xe2, 0xae, 0x29, 0x50, 0x0b, 0x75, 0x07, 0xaa, - 0x44, 0x00, 0x65, 0xe9, 0x53, 0x2a, 0x14, 0x64, 0xed, 0xda, 0xb8, 0x79, - 0x7d, 0x30, 0x45, 0x11, 0x7e, 0x04, 0x40, 0x48, 0xbf, 0x4a, 0x87, 0x9f, - 0x83, 0x6b, 0xe6, 0xe2, 0xa6, 0x90, 0x4f, 0xf2, 0xf3, 0xd6, 0xc1, 0x10, - 0xab, 0xa0, 0xc3, 0x56, 0xfa, 0x72, 0xc5, 0x96, 0x23, 0xb0, 0x6c, 0x6e, - 0x1a, 0x36, 0x0e, 0x30, 0xa5, 0x0f, 0x65, 0xf7, 0x7b, 0xce, 0x59, 0x45, - 0x6d, 0x68, 0x59, 0x22, 0x2e, 0x28, 0x19, 0x47, 0x2a, 0xc7, 0xc1, 0x5a, - 0xdb, 0x00, 0x42, 0xf6, 0x14, 0x52, 0x38, 0x79, 0x74, 0x5b, 0xd5, 0x4b, - 0x59, 0xbf, 0xf5, 0x19, 0xca, 0x28, 0x41, 0x55, 0xea, 0x56, 0x17, 0xe4, - 0xfe, 0xe7, 0xaa, 0xd2, 0xde, 0xdb, 0x17, 0x9d, 0x1b, 0x19, 0x5a, 0xd2, - 0xc0, 0x62, 0xde, 0x2d, 0x4b, 0x7d, 0x46, 0x56, 0x57, 0xca, 0x9b, 0x55, - 0x4f, 0xe0, 0xdf, 0xb8, 0x32, 0x7f, 0xc7, 0xa6, 0x45, 0x2f, 0x14, 0xec, - 0xe5, 0x67, 0x7c, 0x89, 0x47, 0xa6, 0x2e, 0x81, 0x75, 0x2a, 0x02, 0xd0, - 0xe0, 0x0d, 0x71, 0x92, 0xf0, 0x84, 0x21, 0x96, 0x97, 0x5c, 0xac, 0x31, - 0xa5, 0x9b, 0x7f, 0x2a, 0xfd, 0x45, 0x6e, 0x08, 0xa0, 0xc1, 0x21, 0x5c, - 0x04, 0x54, 0xa5, 0x8c, 0xaa, 0xc2, 0xd9, 0x64, 0x1c, 0xcb, 0xdc, 0xaa, - 0x79, 0xdb, 0xcf, 0x83, 0x8c, 0x85, 0x66, 0xda, 0xd6, 0x58, 0xd9, 0xf9, - 0xd0, 0xf1, 0x43, 0x71, 0x1e, 0x6f, 0x62, 0x10, 0x5b, 0xca, 0x29, 0x16, - 0xb0, 0x6e, 0xc1, 0xf3, 0x0a, 0xd3, 0x36, 0xce, 0xa7, 0xf7, 0x93, 0xf8, - 0x18, 0x44, 0xbc, 0x97, 0x60, 0x30, 0x4e, 0xa2, 0x41, 0x23, 0xcc, 0xaa, - 0x56, 0xaf, 0xe5, 0xfe, 0x55, 0x58, 0x45, 0x9b, 0x17, 0xd3, 0x52, 0x15, - 0x98, 0x0a, 0xa0, 0xcd, 0x83, 0x0f, 0xb4, 0x75, 0xb8, 0x5e, 0xc2, 0xe9, - 0x2f, 0xfb, 0xa6, 0xda, 0x9d, 0x45, 0xd4, 0x24, 0x61, 0xa5, 0x29, 0x77, - 0xa2, 0xba, 0x20, 0x5e, 0xaa, 0x9c, 0xe2, 0xfd, 0xb5, 0xe6, 0xbd, 0x8c, - 0x1b, 0x53, 0x78, 0xa6, 0xf4, 0x32, 0x15, 0xa9, 0xc3, 0xe8, 0x2b, 0xc5, - 0xde, 0xbe, 0x4b, 0x0c, 0xb7, 0x78, 0xf2, 0x1e, 0x30, 0x5e, 0x39, 0x39, - 0x84, 0x7f, 0x36, 0x32, 0xa9, 0x1d, 0xff, 0x0f, 0x6f, 0x6c, 0xa2, 0x61, - 0x62, 0x1a, 0x84, 0x98, 0xbb, 0x00, 0x58, 0xfa, 0xdf, 0xab, 0x53, 0x63, - 0x12, 0x18, 0xec, 0x54, 0xd8, 0xc1, 0xbf, 0x00, 0x90, 0xae, 0x0c, 0x90, - 0x03, 0xda, 0x1e, 0x16, 0x8e, 0x93, 0xa9, 0x50, 0xdb, 0x73, 0xed, 0x59, - 0x2e, 0x95, 0xd9, 0xcd, 0x9c, 0x41, 0x8b, 0x02, 0x48, 0xb5, 0x38, 0xf9, - 0x5e, 0x49, 0xff, 0xf9, 0x6e, 0x45, 0xc9, 0x09, 0xc3, 0x2e, 0xfa, 0x8d, - 0xf1, 0x18, 0xbc, 0x4c, 0x55, 0x52, 0xc7, 0xdc, 0xb3, 0xb8, 0xb9, 0xe6, - 0xc2, 0x39, 0x6e, 0x55, 0xe5, 0x09, 0x47, 0xe5, 0xec, 0x64, 0x4f, 0xf6, - 0x43, 0xa6, 0xad, 0xbd, 0x50, 0x88, 0x96, 0x83, 0x8c, 0x83, 0x31, 0x20, - 0x28, 0x44, 0x32, 0xe8, 0xa3, 0xb8, 0xdc, 0xe0, 0x30, 0x8b, 0x2d, 0xe4, - 0x29, 0xcd, 0x31, 0x49, 0xc2, 0x18, 0x8e, 0x25, 0x95, 0x5b, 0x3c, 0xd2, - 0x25, 0x0d, 0x15, 0x41, 0x88, 0x24, 0x92, 0xca, 0x59, 0xb9, 0x16, 0x3a, - 0x5d, 0x6c, 0x2d, 0x6c, 0x30, 0x8e, 0xc4, 0x74, 0xcc, 0x5d, 0x85, 0xda, - 0xdd, 0x56, 0xb5, 0x8a, 0xf3, 0x79, 0x99, 0x67, 0x65, 0xf5, 0x9b, 0x9a, - 0xa4, 0x8d, 0x00, 0x84, 0x3b, 0x06, 0xee, 0x6a, 0xa6, 0x4b, 0x04, 0x14, - 0x3b, 0xa8, 0xdb, 0x88, 0xd6, 0xe1, 0x40, 0x24, 0x26, 0x3e, 0x12, 0xbf, - 0xfa, 0xa3, 0x1a, 0x2d, 0x5c, 0x3d, 0xab, 0xdb, 0x0d, 0xf1, 0x46, 0x7f, - 0x54, 0x83, 0x04, 0xa2, 0x3a, 0x0c, 0x3e, 0x2f, 0x1f, 0x87, 0xaa, 0x93, - 0x02, 0x9b, 0x99, 0xc9, 0x7a, 0x59, 0x94, 0xd5, 0x2c, 0xd0, 0x56, 0xdb, - 0xa1, 0xce, 0xe0, 0xb0, 0x60, 0xfd, 0x3e, 0xd8, 0xb3, 0xe1, 0x0d, 0x50, - 0x1a, 0xa3, 0xe5, 0x4d, 0x07, 0xdc, 0xd8, 0x0a, 0xd9, 0x38, 0x89, 0x6e, - 0x70, 0x37, 0x04, 0x90, 0xbc, 0x0a, 0x45, 0x7e, 0xf8, 0xf1, 0x40, 0xe4, - 0xb7, 0xfe, 0xfe, 0xa9, 0x52, 0x55, 0x39, 0x7b, 0x57, 0x06, 0x09, 0x51, - 0x4c, 0x0c, 0x5c, 0x23, 0x8f, 0x9a, 0xcd, 0x4a, 0x94, 0x7c, 0xc6, 0x29, - 0x52, 0xdd, 0x56, 0x37, 0x6f, 0x2a, 0xfc, 0x8a, 0x0a, 0xd4, 0xe8, 0x6c, - 0x5a, 0x2d, 0x58, 0x1c, 0x91, 0x54, 0x0f, 0x87, 0xdb, 0x83, 0x91, 0x17, - 0xd8, 0x91, 0xbb, 0xfe, 0x22, 0x9c, 0xf6, 0xef, 0xd3, 0xee, 0x86, 0xe1, - 0xf0, 0x30, 0xc0, 0x58, 0x54, 0xdf, 0x49, 0x0e, 0xd1, 0x04, 0xf3, 0x67, - 0xc7, 0xcc, 0xcf, 0x0e, 0x8b, 0xb7, 0x6a, 0x89, 0x0b, 0x95, 0x12, 0xa2, - 0x6a, 0x1c, 0x6c, 0x4f, 0xa5, 0x64, 0x3f, 0xdc, 0x83, 0x88, 0x36, 0xcd, - 0x42, 0x4a, 0xe1, 0xe0, 0x29, 0xda, 0xc2, 0xe6, 0x95, 0xa5, 0xf9, 0x60, - 0xf8, 0x74, 0x99, 0x36, 0xb3, 0x50, 0xda, 0x59, 0x24, 0xf4, 0x80, 0xc8, - 0x77, 0x4f, 0xac, 0x23, 0x03, 0x02, 0x18, 0x84, 0xad, 0x2a, 0x61, 0xf0, - 0x7c, 0xda, 0xa0, 0x37, 0xbf, 0xcd, 0x65, 0xbb, 0x27, 0xb3, 0x7b, 0xc4, - 0xd0, 0x1e, 0x23, 0xff, 0x70, 0xe4, 0x3c, 0x2c, 0x06, 0x15, 0xb6, 0x11, - 0xbc, 0xd2, 0x26, 0xc5, 0x7e, 0xf6, 0x62, 0x29, 0x30, 0xa0, 0xe5, 0xab, - 0xde, 0x70, 0x98, 0x24, 0xe7, 0xe1, 0x27, 0x0d, 0xf4, 0xe1, 0xd5, 0x6a, - 0xcb, 0x7e, 0x59, 0xde, 0xe7, 0x8b, 0x69, 0xa2, 0xb9, 0xde, 0xd0, 0xd0, - 0x1f, 0x3f, 0xff, 0xb8, 0x44, 0x51, 0xf6, 0xfa, 0x75, 0x55, 0x3e, 0xe6, - 0x7a, 0x77, 0x7a, 0xe2, 0x6c, 0x45, 0x0a, 0x9a, 0xf0, 0x70, 0xc6, 0x4a, - 0x53, 0xc7, 0x2b, 0xf6, 0x6a, 0x89, 0xef, 0x5e, 0x2c, 0x1e, 0xd4, 0x6b, - 0x9a, 0x07, 0x18, 0x51, 0x33, 0x65, 0xa9, 0x9a, 0xf9, 0xbf, 0x40, 0xa3, - 0xe9, 0x1d, 0x7a, 0x64, 0xc7, 0xac, 0x29, 0xe2, 0x39, 0xcb, 0x57, 0x8b, - 0x53, 0xc3, 0xd1, 0x2f, 0xfa, 0xa8, 0x7c, 0xb6, 0xc6, 0xd7, 0x8b, 0x22, - 0xb6, 0x72, 0x86, 0xa0, 0x24, 0xbf, 0xfa, 0x5b, 0xd1, 0x11, 0x7e, 0xc1, - 0x59, 0x90, 0x3b, 0x58, 0x03, 0x39, 0xbb, 0x25, 0x63, 0x8c, 0xe6, 0x08, - 0xbd, 0x2d, 0xe7, 0x78, 0x1c, 0x2d, 0x4c, 0x7c, 0x06, 0x0a, 0xd9, 0x31, - 0x98, 0x90, 0x23, 0x8e, 0xc7, 0x60, 0x1c, 0x9c, 0x70, 0x5c, 0xd3, 0x0d, - 0xb3, 0xa9, 0x58, 0x0f, 0x6d, 0x0e, 0xa7, 0xcb, 0x27, 0xe5, 0xd0, 0xdb, - 0xa3, 0x60, 0xec, 0x2c, 0x0a, 0xe2, 0x50, 0xfd, 0xb5, 0x41, 0x08, 0x4a, - 0x49, 0x9e, 0xd6, 0x77, 0xde, 0xf6, 0x5d, 0x5a, 0x4f, 0x2a, 0x61, 0x61, - 0xcf, 0xd4, 0x96, 0x0d, 0xfb, 0x0a, 0x83, 0x50, 0x62, 0x61, 0x6a, 0x44, - 0x94, 0xb8, 0xab, 0x57, 0xf7, 0xf9, 0xb9, 0xc4, 0x39, 0x65, 0xbc, 0x0d, - 0x4e, 0xf0, 0x38, 0xc3, 0x7d, 0x1f, 0xeb, 0x3f, 0x80, 0x6b, 0xe5, 0x90, - 0xb9, 0xa2, 0xce, 0x6a, 0xa6, 0x18, 0x40, 0xc9, 0x59, 0x5e, 0xee, 0xf7, - 0x41, 0x84, 0xe4, 0xf1, 0x47, 0x85, 0x7d, 0x8a, 0x38, 0x1f, 0xb7, 0xee, - 0xd5, 0x18, 0xa2, 0xdb, 0xc5, 0xef, 0x65, 0xce, 0xae, 0x1b, 0x9f, 0xb4, - 0xe1, 0x00, 0x7d, 0xfb, 0x6f, 0xf3, 0x76, 0xde, 0x73, 0x54, 0xde, 0xcc, - 0x35, 0x04, 0x43, 0x18, 0x79, 0x7a, 0xd6, 0xa5, 0xd9, 0xc0, 0x45, 0x19, - 0x87, 0x93, 0xb3, 0xd0, 0x09, 0xe4, 0x0b, 0x4a, 0xa8, 0xa8, 0xd6, 0xe0, - 0x14, 0x25, 0x71, 0xce, 0x58, 0xbc, 0xbd, 0x32, 0x44, 0x8d, 0x08, 0x1e, - 0x2a, 0x44, 0xa1, 0x0f, 0xff, 0xa6, 0xed, 0x42, 0x62, 0xb3, 0x40, 0xb6, - 0xff, 0x81, 0xef, 0x3d, 0xa8, 0x0a, 0xe4, 0x44, 0x78, 0x8a, 0x74, 0xde, - 0x4e, 0x37, 0x1b, 0xc9, 0x14, 0x14, 0xb8, 0x6c, 0xcf, 0x84, 0x0b, 0x2d, - 0x58, 0x44, 0xfd, 0x25, 0x95, 0x18, 0x55, 0x70, 0xbc, 0xb4, 0x9b, 0xd2, - 0xcc, 0xd6, 0x3e, 0x57, 0x7d, 0xf5, 0x2d, 0x72, 0xce, 0xa8, 0xab, 0x88, - 0xa1, 0xc6, 0x74, 0x05, 0x9c, 0x4b, 0x75, 0xb1, 0xf2, 0x55, 0x5a, 0x05, - 0xd4, 0x41, 0xea, 0xa8, 0x0c, 0x1b, 0x74, 0x1c, 0xa5, 0x4f, 0x70, 0x18, - 0x4d, 0x29, 0x6a, 0x9c, 0x9b, 0xe8, 0x5a, 0x36, 0xe0, 0x89, 0x64, 0xfa, - 0xdd, 0xe8, 0x69, 0x41, 0x20, 0xba, 0x7c, 0x50, 0x9c, 0x4a, 0xad, 0x48, - 0xa2, 0xc9, 0x93, 0x09, 0x0b, 0x29, 0x6f, 0x43, 0x5c, 0xe6, 0x89, 0xf7, - 0x20, 0xb4, 0xa6, 0x96, 0xcf, 0x6f, 0xd1, 0xd8, 0x50, 0x75, 0x5d, 0xf5, - 0x04, 0x52, 0xdf, 0x2d, 0xcf, 0x02, 0xb4, 0xd4, 0xcb, 0x62, 0x30, 0xa9, - 0x4c, 0x6f, 0xd0, 0x72, 0x9a, 0x6c, 0x9b, 0x9f, 0xb7, 0xc5, 0xab, 0x4b, - 0x2a, 0xf0, 0xf1, 0x50, 0xef, 0xb1, 0x9f, 0x45, 0xe5, 0x28, 0x50, 0x48, - 0x15, 0x72, 0xca, 0x0e, 0x30, 0x3f, 0x6e, 0x37, 0xc5, 0x0d, 0xb5, 0xed, - 0x24, 0xef, 0x39, 0xc0, 0xad, 0x6e, 0xe6, 0x26, 0xf2, 0x08, 0x5b, 0xc3, - 0x6b, 0x74, 0x99, 0x55, 0x20, 0xa6, 0xfe, 0x78, 0x0b, 0xb1, 0x50, 0x7d, - 0x7f, 0xcc, 0x9c, 0x0f, 0x7d, 0x44, 0x5c, 0x0b, 0x14, 0x4b, 0x04, 0x01, - 0x05, 0x42, 0xec, 0x6e, 0x46, 0x70, 0xa6, 0x70, 0xb6, 0x74, 0x18, 0x2b, - 0xf2, 0xcb, 0x0e, 0x99, 0xe0, 0xeb, 0xde, 0x9c, 0x9f, 0xcd, 0xad, 0x12, - 0xcc, 0x9d, 0x5e, 0x40, 0xe0, 0x89, 0x02, 0x44, 0x1b, 0xce, 0xd0, 0xdc, - 0x98, 0xf8, 0xf1, 0xa9, 0xf6, 0x55, 0xa6, 0x67, 0x79, 0x54, 0xa9, 0xf7, - 0xf8, 0x56, 0xbf, 0x2a, 0xc3, 0x51, 0x18, 0x37, 0x18, 0xf4, 0x0e, 0xdb, - 0xd1, 0x7d, 0xe9, 0xa0, 0xd8, 0x85, 0xae, 0x0d, 0x9c, 0x58, 0x2d, 0x01, - 0xa8, 0xf1, 0xb1, 0xf8, 0x40, 0x1f, 0xaa, 0x69, 0x7e, 0xfa, 0x95, 0x73, - 0xb7, 0xa2, 0xa0, 0x7b, 0xfd, 0xaf, 0xfb, 0x77, 0x3f, 0xd9, 0xfc, 0xb6, - 0x6c, 0xd5, 0xaf, 0x62, 0x37, 0x0b, 0xd9, 0xff, 0x94, 0xdc, 0xcf, 0xde, - 0x14, 0xf6, 0x1f, 0x08, 0xa0, 0xc1, 0x0c, 0x21, 0x07, 0xc9, 0xc1, 0x8b, - 0x55, 0x07, 0x4a, 0xf9, 0x15, 0xa0, 0x0f, 0x78, 0x47, 0x12, 0xba, 0xd2, - 0xd3, 0x08, 0xa8, 0xeb, 0xc3, 0xc0, 0xb5, 0x49, 0x9d, 0x7c, 0x7b, 0x4f, - 0x05, 0x85, 0x7c, 0x2c, 0x21, 0x18, 0x5a, 0x21, 0xa5, 0x16, 0xf5, 0xe5, - 0x9a, 0x2e, 0xdf, 0xf3, 0xcb, 0x4f, 0xac, 0x55, 0xb6, 0x79, 0x64, 0x40, - 0x97, 0x76, 0xe1, 0x96, 0x25, 0xce, 0xa1, 0x87, 0x86, 0xbf, 0x23, 0x0b, - 0xc9, 0x04, 0x64, 0xcc, 0x07, 0x96, 0x62, 0xbd, 0xb8, 0x39, 0x6d, 0xba, - 0x54, 0xc3, 0x52, 0x72, 0x70, 0x0a, 0x8e, 0x75, 0x7a, 0x55, 0x81, 0xc0, - 0x31, 0x18, 0x7a, 0xaa, 0x87, 0x23, 0xff, 0xb5, 0xe2, 0xbf, 0x46, 0x76, - 0x29, 0x41, 0xc9, 0xfb, 0x21, 0xe2, 0xf7, 0xca, 0x24, 0x05, 0xba, 0xd3, - 0x8d, 0xe4, 0x8b, 0x80, 0x53, 0x6c, 0xa9, 0x46, 0x9a, 0xb0, 0x60, 0x7c, - 0x52, 0x0c, 0xa1, 0x52, 0x61, 0xf6, 0xeb, 0x65, 0xbe, 0xde, 0xc1, 0xc0, - 0x71, 0xb2, 0x2c, 0x88, 0x1c, 0x64, 0x67, 0xf5, 0x45, 0xb3, 0x70, 0x92, - 0xd1, 0xa4, 0xb9, 0x73, 0x9d, 0x80, 0x92, 0xc8, 0xb8, 0xb0, 0x24, 0xb6, - 0x56, 0x81, 0xf4, 0xbe, 0xb7, 0x15, 0x2f, 0x96, 0xa9, 0xee, 0xfa, 0x22, - 0xa8, 0x2a, 0x95, 0x2a, 0x4c, 0x05, 0x76, 0x01, 0x84, 0x01, 0xea, 0x46, - 0xd3, 0xa7, 0x98, 0x3e, 0x65, 0xab, 0x3d, 0x54, 0x2c, 0xd6, 0xed, 0x9d, - 0x2d, 0x9e, 0x11, 0x75, 0x67, 0xa2, 0x10, 0x1a, 0x85, 0xe5, 0x4c, 0x0f, - 0x07, 0xe9, 0x7f, 0x99, 0x39, 0xbe, 0x61, 0x4f, 0xbb, 0xc0, 0xea, 0xfd, - 0x4a, 0x8c, 0xc0, 0xdc, 0x18, 0x80, 0x5d, 0x01, 0x87, 0x42, 0x3b, 0x69, - 0xe6, 0xab, 0xf2, 0x65, 0x5e, 0xbf, 0xeb, 0x61, 0xec, 0xa5, 0x5d, 0x0e, - 0xa0, 0xd8, 0x0c, 0xe0, 0x2d, 0x44, 0x77, 0x15, 0x28, 0x8a, 0x5b, 0x52, - 0x0a, 0x80, 0x62, 0x14, 0x53, 0x21, 0x0b, 0x66, 0x70, 0x46, 0xc5, 0x61, - 0xea, 0x6f, 0xe3, 0x71, 0x4a, 0x84, 0x5c, 0xbd, 0x14, 0x0b, 0x0b, 0x81, - 0xbc, 0x3f, 0x57, 0x54, 0x0e, 0x19, 0xcf, 0x28, 0xed, 0x57, 0x24, 0xc9, - 0xde, 0x74, 0xb3, 0xca, 0x46, 0xfa, 0x0e, 0xf1, 0x00, 0x54, 0x8c, 0x0f, - 0x00, 0x39, 0xaf, 0x70, 0xb3, 0x2d, 0xc9, 0x9d, 0xdd, 0xac, 0x97, 0xfe, - 0x44, 0x65, 0x8a, 0x4a, 0xb3, 0x31, 0x6d, 0x53, 0x85, 0x9e, 0x06, 0x21, - 0x27, 0x34, 0x49, 0x6f, 0xc0, 0xf0, 0x50, 0x0c, 0xa6, 0xc9, 0x7f, 0x7d, - 0x7c, 0xac, 0xbf, 0x64, 0xf4, 0x96, 0x77, 0xb3, 0xc0, 0xc8, 0x41, 0xc2, - 0x28, 0x31, 0x18, 0xee, 0xa8, 0x40, 0x44, 0x79, 0x68, 0xa8, 0xb0, 0xb2, - 0x21, 0x17, 0x0f, 0xc4, 0x64, 0xd5, 0xa4, 0x82, 0x41, 0x7a, 0xb4, 0xfb, - 0x80, 0x5f, 0xfe, 0x69, 0x8b, 0x64, 0x0e, 0xa4, 0x51, 0xa5, 0x58, 0x8f, - 0x42, 0xd2, 0xd8, 0x3c, 0x05, 0x09, 0x7d, 0xeb, 0x3e, 0x89, 0x32, 0x0d, - 0x87, 0x2d, 0xc5, 0x0d, 0x0c, 0xb0, 0xb7, 0x5b, 0x07, 0x07, 0x80, 0x90, - 0x5f, 0xd8, 0x23, 0x83, 0xc2, 0x7f, 0xd6, 0x23, 0xb4, 0xd4, 0x5c, 0xa8, - 0xb9, 0x8f, 0x34, 0xde, 0xf1, 0x7e, 0x16, 0xe9, 0x68, 0xe3, 0x14, 0x4a, - 0x0f, 0x9b, 0xff, 0xd9, 0xf1, 0xf8, 0x21, 0xfa, 0x7c, 0x70, 0xc4, 0xd1, - 0xfa, 0x8a, 0x59, 0xc5, 0x3f, 0xb8, 0xb2, 0x0a, 0x1f, 0x03, 0x02, 0x4e, - 0xf5, 0xf6, 0x6a, 0xa6, 0x2e, 0x8a, 0xf3, 0xba, 0x5e, 0x08, 0x23, 0xd9, - 0xf4, 0x4d, 0x65, 0x05, 0x32, 0x98, 0x8e, 0x56, 0x74, 0x19, 0x06, 0x03, - 0x06, 0xc1, 0xc1, 0x81, 0x52, 0x61, 0xf0, 0x1f, 0x5b, 0x80, 0xaa, 0x12, - 0x32, 0xa3, 0x4c, 0x5c, 0xc4, 0x8d, 0xd2, 0x5f, 0xd5, 0x03, 0x70, 0x23, - 0xa5, 0xbf, 0x06, 0x3a, 0x21, 0xf0, 0x96, 0xdf, 0x93, 0x63, 0x6c, 0xb0, - 0x1f, 0x76, 0x75, 0xa5, 0x59, 0xe5, 0xe4, 0xbc, 0x0f, 0x68, 0x89, 0x99, - 0xab, 0x16, 0x29, 0x06, 0x3a, 0xb5, 0xd0, 0x86, 0xae, 0x87, 0x8d, 0x6c, - 0xc0, 0xdb, 0x92, 0xa8, 0xea, 0x3e, 0x87, 0x20, 0xc4, 0xe7, 0x57, 0x00, - 0x00, 0xa3, 0x08, 0x6c, 0x98, 0x37, 0x15, 0x17, 0x84, 0x04, 0xc9, 0x9b, - 0x63, 0x15, 0xb0, 0xca, 0xa4, 0xda, 0xce, 0x08, 0x92, 0xc5, 0x5e, 0xe0, - 0x13, 0x04, 0xb0, 0xd6, 0x3b, 0x06, 0x08, 0x45, 0xd6, 0x7f, 0x47, 0x40, - 0x63, 0xe8, 0xe7, 0xb7, 0xbb, 0xee, 0x92, 0x51, 0xbe, 0x03, 0xe5, 0xc0, - 0x0e, 0x81, 0x75, 0x07, 0x82, 0x80, 0x64, 0xb9, 0x47, 0x38, 0x06, 0x98, - 0x52, 0x81, 0x7a, 0xd3, 0x82, 0xae, 0xf6, 0x3c, 0x94, 0x27, 0xc5, 0xb0, - 0xeb, 0x61, 0x58, 0x46, 0x56, 0xcd, 0x12, 0x93, 0x34, 0x9e, 0xe8, 0x29, - 0xfd, 0x31, 0x51, 0x7a, 0x94, 0x7d, 0xf7, 0xb9, 0xc9, 0x44, 0x55, 0x3b, - 0x14, 0xa9, 0x06, 0x21, 0x4b, 0x00, 0xbb, 0x66, 0xf8, 0xc8, 0x64, 0xf5, - 0x65, 0xd5, 0x25, 0xb6, 0xec, 0x90, 0x6e, 0xba, 0xdb, 0xe4, 0x32, 0x86, - 0x98, 0x57, 0xe0, 0x71, 0x8a, 0x4a, 0xac, 0x3e, 0x48, 0x5e, 0x5f, 0x8c, - 0x56, 0xf5, 0xac, 0xad, 0xfa, 0x0d, 0x94, 0x87, 0x9c, 0xb3, 0xa1, 0xc2, - 0x83, 0xe5, 0xf7, 0xae, 0x84, 0x29, 0x8d, 0x02, 0x18, 0x97, 0x82, 0x51, - 0x73, 0x6a, 0xe8, 0xde, 0x74, 0x71, 0x8b, 0x77, 0xec, 0xa0, 0x81, 0x9e, - 0x83, 0x09, 0x82, 0xf8, 0x33, 0x05, 0xed, 0x97, 0x80, 0x70, 0x8d, 0xf6, - 0x7f, 0xd6, 0x59, 0x2e, 0x9b, 0xf4, 0x0b, 0xcf, 0xef, 0x8b, 0x64, 0x0e, - 0x16, 0x70, 0x7b, 0x4e, 0x3d, 0x6c, 0x20, 0xd8, 0xad, 0x91, 0x13, 0xf9, - 0x15, 0x01, 0x0f, 0x5b, 0x28, 0x78, 0x56, 0x37, 0x69, 0x48, 0x3e, 0x47, - 0xff, 0x60, 0xb4, 0x10, 0x92, 0x7d, 0x85, 0x60, 0x19, 0xad, 0xb3, 0x41, - 0xc9, 0x04, 0x88, 0x5d, 0xf4, 0xd8, 0xb3, 0x57, 0xe5, 0xe5, 0x97, 0xed, - 0x86, 0xb9, 0xb2, 0x67, 0xb0, 0x1f, 0x23, 0xff, 0xb6, 0xc5, 0xba, 0xf8, - 0xd8, 0xa7, 0x71, 0xe1, 0xf0, 0x4b, 0x69, 0x58, 0x38, 0x14, 0x6a, 0xd5, - 0xe3, 0x3e, 0xd5, 0x57, 0x1a, 0x55, 0xf5, 0x57, 0x3b, 0x7b, 0xee, 0xc8, - 0x1e, 0x86, 0xb7, 0xe5, 0x40, 0xb7, 0x32, 0x10, 0xc7, 0xe0, 0xca, 0x07, - 0x49, 0xcb, 0xd0, 0xb1, 0x91, 0x41, 0x2e, 0xdb, 0x3d, 0x03, 0x30, 0x60, - 0xa4, 0x30, 0xd0, 0x52, 0xe5, 0x6e, 0xd6, 0xa3, 0x69, 0x59, 0xaa, 0xd1, - 0x62, 0xca, 0x76, 0xaf, 0x6d, 0xa0, 0xb4, 0x12, 0x4d, 0xe5, 0x56, 0x5d, - 0x6e, 0xa8, 0x06, 0x26, 0x59, 0xc2, 0x14, 0xc2, 0xfb, 0x42, 0x4f, 0xbb, - 0xe2, 0xa2, 0xcb, 0x99, 0x27, 0xa7, 0x4a, 0xa2, 0xdc, 0x9c, 0x06, 0x13, - 0x15, 0x54, 0xad, 0x2a, 0x95, 0x3d, 0x37, 0xc8, 0x22, 0x73, 0xa0, 0xc1, - 0x48, 0x47, 0x1d, 0x30, 0x39, 0x2c, 0xdb, 0x39, 0xbc, 0xce, 0xf2, 0x5d, - 0xe6, 0xad, 0x6c, 0x58, 0x4e, 0x2a, 0x6f, 0xf1, 0xa6, 0xb1, 0x9f, 0xb0, - 0x6a, 0x61, 0xbb, 0x79, 0xd9, 0x78, 0x1a, 0x39, 0xd9, 0x5b, 0xa4, 0xd0, - 0xb1, 0x24, 0x2f, 0x03, 0x6d, 0x79, 0x07, 0xda, 0xb1, 0x64, 0x1c, 0xe2, - 0x37, 0x6e, 0xd2, 0xd8, 0xcf, 0x6f, 0x72, 0x5c, 0xe0, 0x89, 0xcb, 0x65, - 0x44, 0x1c, 0x9c, 0x3e, 0x20, 0xd4, 0xfb, 0x2a, 0x2e, 0x20, 0x0c, 0x4f, - 0x6d, 0x66, 0xb1, 0x64, 0xfa, 0x14, 0x44, 0xae, 0x3d, 0xcf, 0x36, 0x80, - 0xe6, 0xdb, 0x9b, 0xd5, 0x91, 0x14, 0x74, 0x84, 0x60, 0x3f, 0x53, 0xd6, - 0x7c, 0x1c, 0x87, 0xad, 0x21, 0x9d, 0x88, 0x02, 0x94, 0x58, 0x57, 0x14, - 0x95, 0xf2, 0xcb, 0xde, 0x62, 0x2a, 0xba, 0x23, 0xc8, 0xff, 0x27, 0x25, - 0x8b, 0xdc, 0xea, 0x84, 0x15, 0x11, 0x33, 0xeb, 0x8e, 0x65, 0xd7, 0x6d, - 0x03, 0x2e, 0xc7, 0x50, 0xc9, 0x71, 0x45, 0x47, 0x16, 0xe0, 0x3b, 0x0c, - 0xab, 0x9b, 0xf5, 0x5e, 0x1f, 0x4d, 0x05, 0x68, 0x81, 0xaa, 0xf5, 0x5f, - 0xf5, 0x17, 0xbb, 0xd2, 0xc9, 0x01, 0xc3, 0x60, 0xdc, 0xc1, 0x92, 0xdf, - 0xb7, 0x8c, 0x5f, 0x77, 0x39, 0xa1, 0xea, 0x0e, 0xdb, 0x3b, 0xca, 0x1c, - 0x98, 0x69, 0xf6, 0x4f, 0x36, 0x39, 0x2a, 0xdb, 0xf9, 0xfe, 0x7a, 0x42, - 0xbf, 0x7a, 0xad, 0x39, 0x44, 0x5d, 0x30, 0xe7, 0xdc, 0xa5, 0x63, 0xdc, - 0x53, 0x56, 0xde, 0x0c, 0xe3, 0xce, 0x5a, 0xdd, 0xd9, 0x16, 0xe3, 0x1e, - 0xf6, 0x96, 0xd5, 0x94, 0xac, 0xbc, 0xe6, 0x15, 0x05, 0xa6, 0x77, 0xf8, - 0x9c, 0x7c, 0xd7, 0xd8, 0xfd, 0xde, 0x5a, 0x1d, 0x87, 0x76, 0xc5, 0xaa, - 0xc1, 0xb1, 0xe4, 0xda, 0x6c, 0x14, 0xec, 0x56, 0x2d, 0x51, 0xf5, 0x08, - 0xf8, 0x32, 0xec, 0x0e, 0x40, 0x4f, 0x6d, 0x0d, 0xe3, 0x2a, 0x90, 0x29, - 0xaa, 0x54, 0x51, 0x81, 0xc3, 0x41, 0xda, 0x6c, 0xf6, 0xc0, 0xf4, 0xb9, - 0x7f, 0xfa, 0xae, 0x39, 0x61, 0x15, 0x82, 0xf7, 0x1b, 0x1f, 0x7e, 0xa9, - 0xd1, 0xf3, 0x28, 0xe2, 0x9c, 0x88, 0x3b, 0x62, 0x38, 0x04, 0xc6, 0xe1, - 0x69, 0x76, 0xbc, 0xdf, 0x87, 0xb1, 0x8a, 0x1d, 0x6f, 0xad, 0xc9, 0x50, - 0x43, 0x41, 0xa0, 0x25, 0x46, 0x2d, 0xa9, 0x2c, 0x69, 0xa5, 0x7d, 0x46, - 0xd5, 0x55, 0xbf, 0xcb, 0xdb, 0xd9, 0x7a, 0xc0, 0x13, 0x46, 0x60, 0x44, - 0xab, 0xda, 0xa8, 0x7d, 0x6a, 0xbb, 0x77, 0x6e, 0x1b, 0x45, 0xde, 0x11, - 0x98, 0x63, 0x8c, 0xe2, 0x52, 0xee, 0x5c, 0x9f, 0x56, 0xae, 0x7a, 0xa1, - 0xc6, 0x65, 0x53, 0x2c, 0x0d, 0x70, 0xfb, 0x1d, 0x33, 0xa9, 0x4b, 0x9a, - 0xea, 0xed, 0xaa, 0xd0, 0xf9, 0x94, 0x1d, 0xbe, 0x58, 0x1d, 0xa0, 0x93, - 0x4a, 0x16, 0x58, 0xdc, 0xb4, 0x3f, 0x57, 0x15, 0x26, 0x8b, 0x45, 0xfe, - 0x80, 0xa6, 0x05, 0x67, 0x41, 0x92, 0x8e, 0xa2, 0x50, 0x38, 0x96, 0xa0, - 0x4c, 0xab, 0x74, 0xdd, 0xec, 0x44, 0x0c, 0x09, 0xa1, 0x7c, 0x3e, 0x05, - 0x6c, 0xdc, 0xc9, 0xec, 0xc9, 0x14, 0x20, 0x29, 0xa7, 0x83, 0x08, 0x30, - 0x96, 0xae, 0x60, 0x07, 0x08, 0xeb, 0xf0, 0x19, 0x6d, 0x18, 0xa2, 0x80, - 0xc1, 0x5d, 0x2e, 0xc1, 0xd4, 0x6d, 0x08, 0x0f, 0x26, 0x20, 0x25, 0x24, - 0xfa, 0x55, 0x6c, 0x30, 0xd6, 0x29, 0xfb, 0x7f, 0xcc, 0xf4, 0x25, 0xaf, - 0xd1, 0x11, 0x2d, 0x78, 0x4d, 0x06, 0x05, 0x10, 0x42, 0xad, 0x97, 0xfc, - 0x4b, 0xd8, 0x1e, 0x0f, 0xb2, 0x28, 0xb4, 0x18, 0x39, 0xfc, 0x45, 0x03, - 0x4c, 0x07, 0x29, 0x30, 0xcc, 0xd8, 0x27, 0x8b, 0x81, 0x44, 0x25, 0x08, - 0xca, 0x95, 0x03, 0x2c, 0xd7, 0xd2, 0xc6, 0xbb, 0xad, 0xec, 0xb7, 0xaa, - 0xd6, 0xed, 0x85, 0x6b, 0x15, 0x80, 0x9a, 0x82, 0x37, 0x87, 0x0c, 0x32, - 0x9d, 0x8c, 0x6d, 0x2a, 0x8a, 0x5b, 0xfd, 0xe6, 0xe4, 0xea, 0xfc, 0x93, - 0x54, 0x85, 0x82, 0xc5, 0x6c, 0xa8, 0xd5, 0x05, 0x97, 0x50, 0xdb, 0x96, - 0x52, 0xce, 0x93, 0xbf, 0xec, 0x04, 0x4f, 0xc5, 0x32, 0xff, 0xf2, 0x96, - 0x67, 0x50, 0x8a, 0x48, 0xe4, 0x9c, 0x79, 0x64, 0xcd, 0x86, 0xc0, 0x61, - 0x2c, 0x7a, 0x98, 0x4a, 0x2e, 0x2c, 0x4c, 0xa2, 0x0f, 0x52, 0x87, 0x8a, - 0x31, 0x65, 0x1e, 0xa8, 0xff, 0x62, 0x00, 0x60, 0x8c, 0x35, 0x02, 0x88, - 0x20, 0x36, 0xc9, 0x5a, 0x8e, 0xa1, 0xe2, 0x3b, 0x7a, 0x8a, 0x40, 0xe7, - 0x4c, 0x9a, 0x2e, 0x06, 0x48, 0xcb, 0x25, 0xff, 0x2f, 0x08, 0x2c, 0xa9, - 0x67, 0xff, 0xdf, 0x88, 0x1e, 0xed, 0xfc, 0x95, 0x12, 0xe2, 0x22, 0x90, - 0x7c, 0x78, 0x01, 0xc1, 0x79, 0x83, 0xc5, 0x43, 0xc0, 0xf3, 0x3a, 0x5c, - 0xc2, 0xc1, 0xd4, 0xe7, 0xed, 0x29, 0xd2, 0xbb, 0xa1, 0xa1, 0x60, 0xb1, - 0xae, 0xa9, 0xfa, 0xe4, 0x46, 0x5d, 0x5c, 0x16, 0xad, 0x85, 0xdd, 0x06, - 0x82, 0x39, 0x7d, 0x06, 0x5f, 0x3c, 0xc3, 0x19, 0xd1, 0x01, 0x4b, 0x2a, - 0x27, 0xb2, 0x50, 0xf1, 0x61, 0x17, 0x73, 0x8e, 0x15, 0x0f, 0x81, 0x00, - 0x74, 0x5d, 0xef, 0xfa, 0xf9, 0x20, 0xfd, 0xbf, 0x8d, 0xeb, 0x7f, 0xb7, - 0xd2, 0x21, 0x94, 0xa8, 0x18, 0x2a, 0xe0, 0xc5, 0x82, 0x40, 0xfe, 0xdb, - 0xf4, 0xe3, 0xf6, 0xff, 0xaa, 0x54, 0x7f, 0x7f, 0xcf, 0x49, 0xda, 0xb4, - 0x11, 0x1a, 0x0e, 0x00, 0x88, 0x30, 0xad, 0x26, 0x80, 0xf0, 0xe9, 0xac, - 0x9c, 0xf2, 0xb2, 0xc5, 0x94, 0xe6, 0xfe, 0xa8, 0xdb, 0xc0, 0x2b, 0x46, - 0xfb, 0x88, 0xca, 0x8b, 0x40, 0x54, 0xfe, 0xdf, 0x91, 0xbd, 0xf8, 0x5b, - 0x68, 0x08, 0x11, 0x40, 0xe3, 0x04, 0x7a, 0x91, 0x23, 0x41, 0xda, 0x61, - 0x29, 0x53, 0x49, 0x3d, 0x32, 0x15, 0x70, 0x41, 0xdd, 0x53, 0x81, 0xc2, - 0x90, 0xf0, 0x12, 0x92, 0x83, 0xc5, 0x6c, 0xaa, 0x99, 0x89, 0x41, 0x94, - 0x35, 0xda, 0x54, 0xa8, 0x1c, 0x94, 0x7f, 0x49, 0x59, 0x2f, 0x52, 0x55, - 0xba, 0xb1, 0x56, 0x16, 0x83, 0xe4, 0x40, 0x0e, 0x49, 0x82, 0xe4, 0xca, - 0x81, 0xe0, 0xe0, 0x17, 0x69, 0x84, 0x93, 0xa1, 0xed, 0x64, 0xae, 0xd2, - 0x48, 0x0b, 0x6d, 0xbb, 0xa1, 0xed, 0x9f, 0xee, 0x7a, 0x69, 0x6a, 0x8c, - 0xbc, 0x58, 0xaf, 0xb0, 0x39, 0xd1, 0x10, 0x2d, 0x77, 0xbf, 0x82, 0x37, - 0x95, 0x5c, 0xdb, 0xe6, 0x44, 0x76, 0x43, 0x92, 0xff, 0xf9, 0xa6, 0x3a, - 0x51, 0xa5, 0xbb, 0xa8, 0xa1, 0x5e, 0x80, 0xb4, 0x9b, 0x68, 0x0f, 0xa5, - 0x2d, 0x07, 0x17, 0xb0, 0xc3, 0x53, 0xbc, 0x2c, 0xaa, 0x63, 0x59, 0x11, - 0xcf, 0x4c, 0x2a, 0x02, 0x7a, 0x5a, 0x88, 0x16, 0xeb, 0xa9, 0x4a, 0xdc, - 0x91, 0x84, 0xc9, 0x6f, 0xef, 0xe4, 0xf6, 0xab, 0xf7, 0x9a, 0xe7, 0x91, - 0x96, 0xf0, 0x45, 0xc5, 0x05, 0x4a, 0x41, 0xc6, 0x0b, 0x32, 0xa9, 0xb2, - 0xbe, 0xb3, 0xcd, 0xb2, 0xf1, 0x47, 0xf9, 0x3a, 0x87, 0x90, 0x45, 0x31, - 0xf6, 0x61, 0xa0, 0x0e, 0xac, 0xc1, 0xc8, 0x92, 0x10, 0xdb, 0x4e, 0xd4, - 0x0e, 0xa7, 0xbf, 0x7d, 0x0b, 0x0d, 0x5b, 0x03, 0x93, 0xe2, 0xff, 0x62, - 0x44, 0xca, 0x18, 0x2e, 0x55, 0x31, 0x69, 0xca, 0xb0, 0xbe, 0x88, 0x80, - 0xe3, 0x2a, 0xe2, 0x6c, 0x8c, 0x7b, 0xd9, 0xf9, 0x76, 0x48, 0xa7, 0x76, - 0x15, 0x6f, 0xf8, 0x8b, 0x88, 0x14, 0xe8, 0x3e, 0x3f, 0xff, 0x6a, 0xd4, - 0x85, 0x72, 0xa5, 0x6f, 0x7f, 0x68, 0x14, 0xf5, 0xe7, 0xa1, 0x48, 0x72, - 0x84, 0x18, 0x9b, 0xec, 0x8c, 0x1c, 0xcc, 0x0f, 0x6c, 0xcb, 0x6a, 0xe5, - 0x7d, 0x9c, 0xe2, 0xd0, 0x12, 0x31, 0x6f, 0x83, 0x95, 0xf8, 0x8e, 0x2c, - 0xe3, 0x7a, 0xcb, 0x05, 0x93, 0xcd, 0x2d, 0x18, 0x52, 0x8a, 0x2c, 0x8d, - 0x79, 0x03, 0x90, 0x12, 0xb3, 0x4a, 0xea, 0xbd, 0xe0, 0x80, 0xa7, 0x0d, - 0xd4, 0x10, 0xd9, 0xef, 0x7f, 0x00, 0x00, 0xa8, 0x08, 0x6c, 0x82, 0x69, - 0x41, 0xb8, 0x5c, 0x0f, 0x0f, 0x00, 0x7a, 0xa0, 0x78, 0xb8, 0x02, 0x5d, - 0x57, 0x54, 0x23, 0x87, 0x44, 0x41, 0x0b, 0x18, 0x4a, 0x10, 0x07, 0x4a, - 0x64, 0xd2, 0xc2, 0xe5, 0x4d, 0x03, 0xc5, 0x40, 0x1b, 0x08, 0x83, 0x10, - 0x21, 0xe0, 0xec, 0x75, 0xfd, 0xfb, 0x42, 0x55, 0x4a, 0x3c, 0x9e, 0xb4, - 0x41, 0x63, 0x41, 0x5b, 0xe9, 0x10, 0x7f, 0xda, 0x8c, 0x15, 0x06, 0x45, - 0x8f, 0x0b, 0xa0, 0x73, 0x76, 0x20, 0xe1, 0x6f, 0x96, 0x5e, 0xd8, 0x15, - 0xa8, 0x25, 0x66, 0xcc, 0x12, 0x40, 0x3b, 0xf7, 0xb4, 0x15, 0xbf, 0x1f, - 0x7e, 0xa1, 0x2e, 0x67, 0xa1, 0xe4, 0x06, 0x0d, 0x1b, 0xee, 0x02, 0xb8, - 0x2c, 0x1f, 0x0f, 0x87, 0xe9, 0x47, 0xbf, 0x94, 0x74, 0x3a, 0x2f, 0x5b, - 0xaa, 0x5b, 0xdf, 0x49, 0xef, 0x59, 0x38, 0xb7, 0xd0, 0xee, 0xe8, 0x08, - 0x37, 0x8a, 0xcb, 0xc4, 0x81, 0x1f, 0x3e, 0x94, 0xb5, 0x53, 0x7f, 0xfc, - 0x2d, 0x52, 0x1f, 0xb3, 0xfb, 0xeb, 0x43, 0xa4, 0xd7, 0x5b, 0x51, 0x98, - 0xa7, 0x85, 0x78, 0xab, 0xc4, 0x45, 0xe0, 0xb2, 0x53, 0x2d, 0x87, 0xd5, - 0x00, 0xc1, 0xf2, 0xbc, 0xdf, 0xb0, 0x5a, 0x20, 0x33, 0x47, 0x09, 0xb7, - 0xb8, 0x20, 0xb3, 0x3f, 0x57, 0x0d, 0x9a, 0xcd, 0x8a, 0x54, 0x81, 0x50, - 0xb0, 0x20, 0x7a, 0x8f, 0x52, 0xfa, 0xfd, 0x89, 0x80, 0xa7, 0x10, 0x26, - 0x96, 0xa2, 0x6b, 0x15, 0xf2, 0x6c, 0x81, 0xa2, 0x90, 0x7c, 0x98, 0x01, - 0xd2, 0x06, 0xd1, 0xf2, 0xbd, 0x10, 0xd3, 0xa7, 0x48, 0xa7, 0xbb, 0x7d, - 0x7e, 0xd2, 0xf6, 0xb6, 0x1e, 0x2e, 0x97, 0xc5, 0x4b, 0xe2, 0x30, 0x60, - 0xac, 0x58, 0x10, 0x36, 0x41, 0x29, 0x52, 0xc5, 0x6c, 0xfa, 0x6e, 0xa0, - 0xbd, 0xe4, 0xe8, 0x30, 0xd3, 0xb8, 0x45, 0x30, 0x85, 0xb3, 0x20, 0xc1, - 0x0f, 0xc0, 0x7c, 0x7e, 0x3e, 0x1f, 0x52, 0xec, 0x9f, 0xc5, 0x5d, 0x6c, - 0x7a, 0x93, 0xdf, 0xea, 0x9f, 0x96, 0x48, 0x1e, 0x03, 0x1b, 0x10, 0x03, - 0xd0, 0x61, 0xa8, 0x7c, 0x06, 0xf2, 0xb1, 0xf2, 0xa4, 0xea, 0xd4, 0xe6, - 0x81, 0xbd, 0xff, 0x1a, 0x96, 0x77, 0x99, 0x10, 0x77, 0x46, 0xc8, 0x41, - 0x18, 0xc4, 0x33, 0xf2, 0x31, 0x00, 0x35, 0x03, 0x81, 0xe8, 0x38, 0x0f, - 0x89, 0x0a, 0x30, 0x7e, 0xd5, 0x52, 0xcf, 0x90, 0x32, 0x6e, 0xc8, 0x22, - 0xb6, 0x0f, 0x97, 0xff, 0xda, 0x60, 0x79, 0xb3, 0x78, 0xa6, 0x18, 0x5b, - 0x38, 0x75, 0xb0, 0x57, 0x03, 0x41, 0x24, 0xb8, 0xbf, 0xec, 0x97, 0x16, - 0xc8, 0xad, 0x52, 0x8d, 0xfb, 0x4b, 0x5b, 0xcf, 0xa2, 0x02, 0x78, 0x05, - 0x70, 0x16, 0xe1, 0x4b, 0x5a, 0x69, 0xb6, 0xae, 0x7c, 0x3a, 0xe7, 0x56, - 0x5a, 0xac, 0x85, 0xc1, 0xf0, 0x19, 0xa0, 0x80, 0x5e, 0x3b, 0x1d, 0xb0, - 0x07, 0x4b, 0xff, 0x0b, 0xa3, 0x1b, 0x1b, 0xf0, 0xe3, 0xc3, 0x86, 0x53, - 0xef, 0x50, 0xa8, 0x1b, 0x60, 0x6a, 0x0c, 0x46, 0x0a, 0x56, 0x95, 0x88, - 0x29, 0x9b, 0x6a, 0xef, 0x34, 0xb3, 0x46, 0xf5, 0x6e, 0xf1, 0x6e, 0xa8, - 0x46, 0x56, 0x56, 0x16, 0x5f, 0xd2, 0xda, 0xa4, 0x12, 0x1c, 0x4c, 0x99, - 0xcc, 0x04, 0x45, 0x54, 0x0c, 0x67, 0x2e, 0xf5, 0x47, 0xf5, 0x7b, 0x64, - 0xab, 0xf2, 0xe9, 0x5e, 0x03, 0x8c, 0x49, 0x7a, 0xa6, 0x87, 0xbe, 0x8a, - 0x6d, 0x53, 0x33, 0xb9, 0xb1, 0x65, 0xc9, 0x43, 0x93, 0x03, 0x44, 0xd9, - 0xbd, 0xf0, 0x37, 0x6c, 0xd5, 0x69, 0x13, 0x4c, 0x2d, 0xf6, 0x71, 0xae, - 0xff, 0x9d, 0x2c, 0xe8, 0xd9, 0x4f, 0x20, 0xd0, 0xbc, 0x1e, 0x96, 0x49, - 0xe5, 0x28, 0x61, 0x2a, 0xc8, 0x60, 0x30, 0x9e, 0xd8, 0x16, 0x2a, 0x63, - 0x95, 0x5f, 0x2f, 0x54, 0x95, 0x7f, 0x7b, 0x1a, 0x49, 0x96, 0xfd, 0x2f, - 0xd1, 0x66, 0x5f, 0x7e, 0x02, 0xb2, 0xa8, 0x02, 0xea, 0x79, 0xbf, 0x02, - 0x9e, 0x16, 0x0b, 0x83, 0xf8, 0xa7, 0x03, 0xdc, 0x5f, 0x3a, 0x6f, 0xb6, - 0x8a, 0xc5, 0x4c, 0x71, 0x3e, 0x7e, 0xf7, 0xb2, 0xf6, 0x6e, 0x71, 0x18, - 0xad, 0x2a, 0x3e, 0xf7, 0x87, 0x16, 0x7a, 0x75, 0x0e, 0x20, 0xb6, 0xc4, - 0x60, 0x8d, 0x21, 0x86, 0x27, 0x32, 0xf5, 0x64, 0x3c, 0x6d, 0x7c, 0xc9, - 0xe1, 0x9c, 0x98, 0x0c, 0x4e, 0x68, 0x18, 0x6f, 0x6a, 0xcd, 0x7e, 0xcb, - 0x8d, 0x54, 0x36, 0x42, 0xc4, 0x7d, 0x0e, 0x34, 0x6e, 0x16, 0x0c, 0x40, - 0xd5, 0xa0, 0xc1, 0xfa, 0xad, 0x51, 0x44, 0x16, 0x3f, 0xcc, 0x44, 0xb5, - 0x8b, 0x76, 0x83, 0x05, 0x52, 0xab, 0x1a, 0x60, 0x79, 0xec, 0xc9, 0x9e, - 0xbe, 0x9b, 0x39, 0xc5, 0x2b, 0xc8, 0x86, 0x88, 0xad, 0xa2, 0x2b, 0x06, - 0x38, 0x70, 0xc5, 0xd8, 0x1a, 0xc4, 0xc3, 0x86, 0xb5, 0x68, 0x56, 0xd7, - 0xb9, 0xbc, 0x93, 0xab, 0xf0, 0xf2, 0x91, 0x33, 0x6a, 0xbf, 0x6c, 0xb3, - 0x64, 0xf5, 0xb8, 0x51, 0xd9, 0x6f, 0xb8, 0x1b, 0x8d, 0xc1, 0x84, 0xda, - 0x33, 0x0b, 0xd2, 0x31, 0xfe, 0x15, 0xaf, 0x91, 0x6e, 0x64, 0xb2, 0xf2, - 0x40, 0xd4, 0x2c, 0xa6, 0xbf, 0x6a, 0x50, 0x34, 0xbd, 0x03, 0x42, 0x08, - 0xe3, 0x54, 0xa1, 0x5a, 0x59, 0x60, 0x6c, 0x36, 0x06, 0x1a, 0xd7, 0xb4, - 0xa8, 0x7c, 0xae, 0xe0, 0x88, 0x9f, 0xfe, 0xbf, 0x35, 0x78, 0xb5, 0x9d, - 0x05, 0xba, 0xc0, 0xab, 0x67, 0xcc, 0xa6, 0xe1, 0x5e, 0x45, 0x0c, 0x32, - 0xa5, 0x19, 0x6f, 0xff, 0xc0, 0x76, 0x72, 0x95, 0x83, 0x10, 0xda, 0x8f, - 0x83, 0x29, 0xc6, 0x6f, 0x07, 0x11, 0xa9, 0x95, 0x7e, 0xec, 0xef, 0x27, - 0x78, 0x27, 0x2f, 0x98, 0x5a, 0x5f, 0x22, 0x89, 0xbc, 0x93, 0x54, 0xa0, - 0x9c, 0x59, 0x60, 0xdc, 0x8e, 0x76, 0x46, 0xa4, 0x6b, 0x59, 0xa9, 0xfc, - 0xb5, 0x9d, 0xea, 0xcb, 0x6a, 0xdd, 0xe8, 0x38, 0xcc, 0x08, 0xdd, 0x4c, - 0x1f, 0xa7, 0xfa, 0x9b, 0x89, 0x59, 0x52, 0x56, 0x8f, 0x85, 0x92, 0x40, - 0xa1, 0x1d, 0x66, 0x66, 0x95, 0x66, 0xae, 0x19, 0x93, 0x9b, 0x2d, 0x57, - 0x7f, 0xf2, 0xde, 0x46, 0xa7, 0x33, 0xd1, 0x4f, 0x6d, 0xa8, 0x7b, 0x06, - 0x40, 0xef, 0x03, 0x11, 0x70, 0xb1, 0x5f, 0xcb, 0xf0, 0x71, 0xdf, 0x54, - 0x70, 0x66, 0x50, 0xe0, 0xfc, 0x0c, 0x10, 0x42, 0x1a, 0x6a, 0x10, 0x34, - 0x75, 0x9b, 0x8c, 0x8f, 0x53, 0xb7, 0x9e, 0x0f, 0x9a, 0xb3, 0x59, 0xcc, - 0x0e, 0xed, 0xff, 0x86, 0xe4, 0x03, 0xfe, 0xfd, 0x17, 0xf1, 0x65, 0x2b, - 0x71, 0x1a, 0xd5, 0x1f, 0x41, 0x2a, 0x1b, 0x08, 0x0c, 0x2a, 0x4e, 0xc9, - 0x78, 0xf9, 0x52, 0xaa, 0xaf, 0xff, 0xff, 0xd5, 0x97, 0x8f, 0xff, 0x36, - 0x35, 0x6c, 0x9d, 0xe5, 0xd1, 0x4c, 0x42, 0xd4, 0x67, 0x1b, 0x0f, 0xcd, - 0x03, 0x60, 0x1d, 0xb7, 0xdb, 0x44, 0xa6, 0x73, 0xdc, 0x96, 0x65, 0xe4, - 0xb6, 0xa3, 0x44, 0x16, 0x82, 0xbc, 0x0e, 0x2a, 0x07, 0x01, 0xe1, 0x19, - 0xa1, 0xf3, 0x0d, 0x34, 0x1f, 0xd0, 0x32, 0x9d, 0xbd, 0xff, 0x32, 0xb3, - 0xf4, 0x70, 0xb2, 0x0d, 0xd4, 0x0d, 0xbc, 0x1e, 0x87, 0x46, 0x01, 0x6e, - 0x59, 0x53, 0x8e, 0x1b, 0xf9, 0x7b, 0x36, 0x2d, 0x98, 0x20, 0x78, 0x40, - 0x48, 0xa7, 0x9b, 0xde, 0x5d, 0xcf, 0x6b, 0x79, 0x99, 0x29, 0x58, 0x31, - 0x15, 0x7b, 0xe3, 0xec, 0xfc, 0x61, 0x85, 0x79, 0xad, 0xa0, 0x0f, 0x6e, - 0xd2, 0x8a, 0x54, 0xa5, 0x48, 0x6c, 0x0c, 0x71, 0xc2, 0xcb, 0xd2, 0x62, - 0xcb, 0x56, 0x6c, 0x52, 0x39, 0xd9, 0x6e, 0xf0, 0xa9, 0x44, 0xcc, 0x5a, - 0x73, 0x9c, 0x1b, 0xe8, 0x30, 0xd4, 0xcc, 0xea, 0xb5, 0x38, 0x5b, 0x58, - 0x6a, 0x22, 0x1c, 0x15, 0x52, 0x8a, 0x1c, 0x18, 0xbb, 0xeb, 0xfe, 0xdd, - 0xe4, 0x1b, 0x96, 0xde, 0x72, 0xf4, 0x92, 0x08, 0x80, 0xe3, 0x2a, 0x8e, - 0x18, 0x4c, 0xa3, 0xad, 0xfd, 0x42, 0xf5, 0x44, 0x8a, 0x54, 0xf1, 0x17, - 0x4a, 0xc9, 0x6e, 0x80, 0x85, 0x73, 0xe9, 0xd6, 0x09, 0x0a, 0xb3, 0xe5, - 0xb2, 0x7f, 0x11, 0xe9, 0x6d, 0x4e, 0xdc, 0x2d, 0xa6, 0xff, 0x30, 0x6f, - 0x9a, 0x1b, 0xfc, 0x1f, 0x22, 0x00, 0x74, 0xc7, 0x09, 0x97, 0x52, 0xda, - 0x1b, 0xfe, 0x2e, 0x59, 0xd5, 0x96, 0x94, 0x6e, 0x65, 0x50, 0x53, 0x97, - 0x62, 0xe0, 0x67, 0xe1, 0xb5, 0xec, 0xce, 0x94, 0x69, 0x50, 0x3e, 0x5f, - 0xff, 0x64, 0x98, 0x6d, 0xa5, 0x79, 0x34, 0x71, 0x4a, 0xb8, 0x4b, 0x8b, - 0xce, 0xf0, 0x55, 0x9e, 0xef, 0x55, 0x9a, 0xe2, 0xaa, 0xa2, 0xa0, 0x83, - 0x8b, 0x44, 0xe6, 0x17, 0x55, 0x9f, 0x66, 0xab, 0xa1, 0xff, 0xfd, 0x03, - 0xcc, 0xc0, 0xf6, 0xd3, 0x50, 0xac, 0x04, 0x4b, 0x31, 0x3b, 0x36, 0x78, - 0x19, 0x12, 0x49, 0x90, 0xad, 0x6d, 0xbb, 0xa8, 0xd1, 0x06, 0xc3, 0x61, - 0x61, 0x6c, 0x68, 0xbb, 0x01, 0x97, 0x99, 0xdf, 0xe0, 0xdc, 0xb5, 0x7d, - 0xec, 0x47, 0x43, 0x64, 0x20, 0x2e, 0xe5, 0xa9, 0x15, 0xab, 0x8d, 0x4d, - 0x06, 0x1c, 0x7f, 0xf3, 0x17, 0xfb, 0x2a, 0xf7, 0xd6, 0xe5, 0xa8, 0x6f, - 0xb0, 0xaf, 0x01, 0xc6, 0x0e, 0x83, 0xc1, 0x7f, 0xc6, 0xdf, 0xef, 0xfd, - 0xac, 0xc5, 0x3c, 0x1c, 0x31, 0x9a, 0x06, 0x98, 0x2c, 0xea, 0xe3, 0x75, - 0x3a, 0xa1, 0x16, 0x03, 0x13, 0x99, 0x06, 0x10, 0x6e, 0xa7, 0xd0, 0x78, - 0x28, 0x05, 0xee, 0xfa, 0x72, 0xb0, 0xce, 0x7e, 0xdf, 0x7e, 0xd4, 0x56, - 0xf9, 0x42, 0x81, 0xb5, 0xa0, 0x24, 0x49, 0xdd, 0x8d, 0x6d, 0x6f, 0xd3, - 0xdc, 0xea, 0x8c, 0xf7, 0x3b, 0xc8, 0xb9, 0x68, 0x6c, 0x89, 0x40, 0x30, - 0x9f, 0x5e, 0x1e, 0x2c, 0x48, 0xd0, 0x1b, 0x92, 0xd1, 0xdb, 0x2c, 0x29, - 0xd0, 0xeb, 0xca, 0xbb, 0xe9, 0x09, 0x2d, 0x11, 0x41, 0xf2, 0x60, 0x07, - 0xe1, 0xfc, 0xcb, 0x56, 0xc0, 0xcd, 0x4e, 0x8a, 0x46, 0xc2, 0x52, 0x5f, - 0x2b, 0xdd, 0x69, 0x85, 0x48, 0xbb, 0xa0, 0xad, 0xde, 0xa1, 0x5e, 0xdb, - 0xb8, 0xa5, 0x42, 0x90, 0x7c, 0xf8, 0x01, 0xc5, 0x6a, 0x43, 0xdf, 0x67, - 0xb3, 0xdd, 0x93, 0xb4, 0x9b, 0x6a, 0x28, 0xbc, 0xa2, 0xb3, 0x7d, 0x56, - 0x88, 0x96, 0x5e, 0xde, 0x70, 0xd8, 0x24, 0x74, 0xe5, 0xcd, 0xfe, 0x5c, - 0x9f, 0x99, 0x94, 0x44, 0x11, 0x78, 0x0c, 0x13, 0xc3, 0x34, 0xaa, 0x96, - 0x5c, 0x2d, 0x81, 0xea, 0x8e, 0xf0, 0x60, 0x1b, 0x29, 0x3e, 0xbf, 0xb5, - 0x94, 0xbe, 0x02, 0x0d, 0xc8, 0x04, 0x4a, 0x89, 0x78, 0x54, 0x57, 0xa6, - 0x25, 0xb3, 0x1e, 0x1e, 0x66, 0x72, 0x5d, 0xdd, 0x2b, 0x5e, 0x23, 0x83, - 0x30, 0x61, 0x39, 0x60, 0x2d, 0x35, 0x65, 0x11, 0x72, 0xda, 0x8a, 0xf0, - 0x91, 0xd2, 0xc3, 0x51, 0x8a, 0x57, 0xa2, 0x0b, 0x77, 0xb5, 0x4d, 0xec, - 0x92, 0x52, 0x04, 0x16, 0xd5, 0x0a, 0x67, 0x56, 0x0f, 0x4d, 0x28, 0x25, - 0x7f, 0xb6, 0xb8, 0x07, 0x08, 0xe2, 0x40, 0x29, 0x8b, 0x87, 0xd8, 0x97, - 0xc0, 0x6f, 0xc9, 0x13, 0x16, 0xfa, 0xad, 0x4b, 0x41, 0x13, 0xd6, 0xf0, - 0x39, 0x47, 0x41, 0x86, 0x81, 0x79, 0xb1, 0xfe, 0x37, 0xf8, 0xc7, 0x97, - 0x9b, 0xde, 0xea, 0x07, 0x8e, 0x02, 0x10, 0x84, 0xde, 0x26, 0xf2, 0x72, - 0xc8, 0xa5, 0x5b, 0x5e, 0xaa, 0x41, 0x51, 0x7d, 0x39, 0x20, 0x8a, 0x36, - 0x90, 0xb4, 0x18, 0x56, 0x26, 0xf2, 0x68, 0xd7, 0x35, 0x1d, 0x58, 0x90, - 0x81, 0x7f, 0x67, 0x64, 0xc4, 0x40, 0xf9, 0x9f, 0xfd, 0xc8, 0x89, 0xcd, - 0x9a, 0xad, 0x46, 0x1a, 0xdf, 0x31, 0x93, 0xcb, 0x22, 0xc2, 0xab, 0xc3, - 0x51, 0x46, 0x15, 0x69, 0xc1, 0xb8, 0x30, 0x81, 0xf6, 0xd3, 0xb6, 0x3f, - 0xfa, 0xa8, 0x5b, 0x79, 0xc5, 0xe6, 0xc9, 0xe8, 0x55, 0x20, 0x70, 0xa4, - 0x1f, 0x5e, 0x00, 0x74, 0x2d, 0x2d, 0xb2, 0x10, 0x08, 0x9b, 0xbc, 0xc5, - 0x11, 0x6e, 0x85, 0x1c, 0x21, 0x43, 0xc5, 0xa8, 0xca, 0x4e, 0x2b, 0x61, - 0x3e, 0xc0, 0x56, 0xf9, 0x4a, 0x84, 0x35, 0x1a, 0x33, 0xf4, 0x9a, 0xdf, - 0xe5, 0xb4, 0xa8, 0xd4, 0x45, 0x4a, 0x4f, 0x53, 0x4a, 0xbd, 0xf2, 0xbf, - 0xf3, 0x54, 0x29, 0x92, 0x58, 0x86, 0xd4, 0x61, 0x55, 0xab, 0xc9, 0x96, - 0x6e, 0x2d, 0x11, 0x70, 0x83, 0x92, 0x1e, 0x6c, 0x34, 0x03, 0x68, 0xec, - 0x14, 0xa3, 0xcc, 0xfb, 0x23, 0xc1, 0xe3, 0x0d, 0xa6, 0xf2, 0x34, 0xf9, - 0xd6, 0xdb, 0xf4, 0x37, 0x53, 0x42, 0xc5, 0x18, 0x88, 0xac, 0x18, 0xe8, - 0x70, 0xba, 0x07, 0xc1, 0x05, 0xba, 0xdb, 0x6d, 0xf6, 0x4d, 0x02, 0xed, - 0xfe, 0x34, 0xd6, 0x6f, 0x51, 0x40, 0xdd, 0x71, 0xb0, 0x7a, 0x2d, 0x13, - 0x8f, 0x75, 0x5b, 0x10, 0x72, 0xc6, 0xc9, 0x33, 0xea, 0x55, 0xe2, 0x85, - 0x23, 0x94, 0xdc, 0xf9, 0x6f, 0xa4, 0x0e, 0x51, 0x0d, 0x01, 0x76, 0xa8, - 0x7c, 0x07, 0x84, 0x7d, 0x05, 0x3a, 0x46, 0x34, 0xb9, 0x5c, 0x59, 0xae, - 0xac, 0x91, 0x8f, 0xf0, 0x3b, 0xf4, 0xc0, 0x56, 0x63, 0x62, 0x2a, 0x90, - 0xec, 0x04, 0xd8, 0xd7, 0xe9, 0x5f, 0x43, 0xc0, 0x62, 0x17, 0xd9, 0x4d, - 0x9c, 0x4c, 0x17, 0x60, 0x18, 0x91, 0x38, 0xe9, 0x23, 0x0c, 0x0e, 0x7a, - 0x55, 0x83, 0x91, 0x07, 0xff, 0xda, 0xa7, 0x8b, 0xc2, 0xb1, 0xb6, 0x60, - 0x71, 0x80, 0x28, 0x64, 0xd2, 0xbe, 0x35, 0xcb, 0x65, 0x24, 0x9d, 0x99, - 0xd0, 0x61, 0xa8, 0xb9, 0x20, 0x3c, 0x1f, 0xfc, 0xaa, 0x82, 0x11, 0x7b, - 0x4d, 0xea, 0x74, 0xea, 0x59, 0x10, 0x7d, 0x14, 0xe7, 0x95, 0x78, 0x15, - 0x22, 0x26, 0x29, 0xe6, 0x28, 0x06, 0x21, 0x28, 0xac, 0x75, 0x7b, 0xd6, - 0x38, 0x22, 0x42, 0xc4, 0x59, 0xc8, 0x72, 0x6a, 0xc8, 0x42, 0xd4, 0x4d, - 0x3e, 0x95, 0x16, 0xcb, 0xd0, 0xe6, 0x14, 0xa3, 0xa7, 0xcc, 0xe5, 0x69, - 0xbd, 0xb8, 0x8b, 0x57, 0x44, 0xb1, 0xde, 0x3c, 0xf4, 0xf2, 0x75, 0x6d, - 0x7f, 0x9f, 0x93, 0xd0, 0x92, 0x2f, 0xce, 0xb9, 0x0c, 0x12, 0x95, 0x79, - 0x3b, 0x4a, 0xe1, 0x52, 0x8d, 0x29, 0x95, 0x67, 0xb6, 0x91, 0xcb, 0xe3, - 0xe6, 0x3c, 0xab, 0xaa, 0x3f, 0xfb, 0x3f, 0x2f, 0xef, 0x61, 0x57, 0x61, - 0x2a, 0x91, 0xb9, 0x95, 0xc1, 0x56, 0x06, 0xfe, 0x20, 0x26, 0xda, 0x5b, - 0xed, 0x2c, 0x56, 0x8c, 0x0c, 0x52, 0xcc, 0xa1, 0xc1, 0x59, 0x50, 0xb5, - 0x12, 0xff, 0x8e, 0x39, 0x3d, 0xb9, 0x85, 0xa5, 0x44, 0xbd, 0xb2, 0xa2, - 0x0e, 0x0c, 0x9d, 0x48, 0x25, 0x7c, 0xbb, 0x15, 0x4f, 0x37, 0x77, 0x2e, - 0xb3, 0xa9, 0xf5, 0xbd, 0xad, 0xfd, 0x9d, 0xbc, 0x91, 0x7d, 0xd1, 0x10, - 0xf2, 0x16, 0xda, 0x2b, 0x35, 0xfd, 0x0e, 0x2e, 0x72, 0xff, 0x46, 0xfb, - 0xfe, 0x2e, 0x0c, 0x26, 0x55, 0x26, 0x66, 0x28, 0xea, 0x2f, 0x96, 0xd8, - 0x82, 0xcc, 0xbc, 0x92, 0x70, 0x38, 0x58, 0x12, 0x64, 0x7e, 0xd4, 0x6d, - 0xaf, 0xfb, 0xb6, 0x73, 0x24, 0xc4, 0x01, 0xec, 0x2b, 0x07, 0x08, 0x82, - 0x7f, 0xcf, 0x2b, 0x69, 0x53, 0x68, 0x5a, 0x58, 0x97, 0xa4, 0xe8, 0x2d, - 0x4f, 0x91, 0xd9, 0x5c, 0xc1, 0xc5, 0x0f, 0xb2, 0x4d, 0xf4, 0xf5, 0xb1, - 0x07, 0x3f, 0x2b, 0x86, 0x83, 0xcd, 0xc8, 0xcf, 0xb3, 0xea, 0x0b, 0x6d, - 0xd5, 0x35, 0x0c, 0x93, 0x96, 0xda, 0x1a, 0xed, 0x06, 0x05, 0xc2, 0xe3, - 0xd6, 0xea, 0x6f, 0xe6, 0xcd, 0xa3, 0x60, 0xeb, 0x9c, 0x9a, 0x33, 0x52, - 0x55, 0xaa, 0x41, 0x2d, 0x7d, 0x4c, 0x0f, 0x05, 0xff, 0x1b, 0x25, 0xed, - 0x7b, 0x1b, 0xf7, 0x94, 0x33, 0x73, 0xd6, 0x29, 0xec, 0x6a, 0xdb, 0xd1, - 0x17, 0x14, 0x6f, 0x00, 0xa0, 0x31, 0x19, 0x87, 0x5a, 0xdf, 0xd5, 0x74, - 0x7a, 0xda, 0x6f, 0x6c, 0xbf, 0xfe, 0xe6, 0xe7, 0xec, 0x2a, 0xc5, 0x5e, - 0x47, 0xe0, 0xd7, 0x3a, 0x0f, 0x91, 0xff, 0xd8, 0xa5, 0xa1, 0xbb, 0x70, - 0x73, 0x37, 0xeb, 0x68, 0x80, 0x83, 0x32, 0x01, 0x0a, 0x27, 0x14, 0xaa, - 0xb8, 0xaf, 0x85, 0xe5, 0x93, 0x0b, 0x24, 0x53, 0x54, 0xc1, 0xb5, 0x92, - 0xbc, 0xdb, 0x73, 0xf9, 0xfa, 0xdf, 0xbe, 0xd6, 0x35, 0xf5, 0x00, 0xad, - 0x11, 0x4b, 0x22, 0xf6, 0x40, 0xd4, 0xc7, 0x2c, 0xc7, 0xc7, 0x2c, 0xff, - 0x7b, 0xb7, 0x18, 0x59, 0x41, 0x65, 0x50, 0xdd, 0x5a, 0xf7, 0xb4, 0x2c, - 0x37, 0x1b, 0x2c, 0xcb, 0xce, 0x66, 0x4d, 0xaa, 0x3b, 0x7b, 0x6f, 0x3a, - 0xb5, 0xbb, 0x8a, 0x54, 0x82, 0xdd, 0x46, 0xcb, 0xd8, 0x43, 0xf5, 0xf1, - 0x71, 0xb7, 0x2a, 0x84, 0x4b, 0x45, 0x23, 0x64, 0x65, 0x78, 0x68, 0xc9, - 0x86, 0xf8, 0xaf, 0x3c, 0xad, 0x54, 0xdd, 0xfe, 0x6e, 0xe7, 0xae, 0xc2, - 0xc4, 0xd1, 0x18, 0x77, 0xed, 0x07, 0x07, 0x86, 0x7e, 0xd4, 0xea, 0xb6, - 0x54, 0xdd, 0xe3, 0x0d, 0x22, 0x9a, 0x8a, 0x2e, 0x6b, 0xe2, 0x2e, 0x86, - 0xe0, 0xf9, 0x3f, 0xfd, 0x93, 0x10, 0x07, 0x57, 0x7c, 0x0f, 0x09, 0xff, - 0x9f, 0xd8, 0xef, 0x26, 0xf5, 0xbc, 0x52, 0x86, 0xf2, 0x61, 0x5e, 0x91, - 0xa6, 0xd3, 0x0d, 0xe2, 0x9d, 0x2f, 0x4f, 0x2f, 0x87, 0x13, 0x8d, 0x62, - 0x29, 0x27, 0x03, 0xd0, 0xd7, 0x4c, 0x25, 0x0b, 0x56, 0xfb, 0x1b, 0x26, - 0x40, 0x61, 0x11, 0x8e, 0x77, 0xa8, 0xa4, 0x66, 0xa9, 0x2b, 0xd0, 0xd8, - 0x3c, 0x07, 0xc7, 0xff, 0xee, 0xbd, 0xfa, 0x3a, 0xcd, 0x67, 0xec, 0x97, - 0xc0, 0x30, 0xc1, 0x53, 0x1e, 0x9f, 0xb9, 0xe5, 0x11, 0x72, 0xce, 0x60, - 0x88, 0x0b, 0x65, 0x34, 0x7a, 0x3e, 0xf7, 0x71, 0xac, 0xf6, 0x6f, 0xf9, - 0x0a, 0xa1, 0x64, 0xea, 0x00, 0xf7, 0x46, 0xfb, 0xa3, 0x75, 0x00, 0xfa, - 0x1f, 0xfd, 0xa9, 0x27, 0xf6, 0xe8, 0x7f, 0x6d, 0x94, 0x3c, 0x1c, 0x71, - 0x4f, 0x62, 0x25, 0xa2, 0x90, 0x5a, 0xa3, 0xf6, 0x18, 0x68, 0x3d, 0xad, - 0x49, 0x72, 0x49, 0x8d, 0x6f, 0x14, 0x62, 0xc8, 0xdc, 0xbd, 0x98, 0x61, - 0x32, 0xbf, 0xd2, 0xd2, 0xfd, 0xaa, 0x24, 0x8a, 0x3d, 0xb6, 0xcf, 0x14, - 0xdf, 0x07, 0x01, 0xb0, 0x3e, 0x6c, 0x00, 0xe9, 0xa5, 0xa5, 0xc0, 0x63, - 0xcd, 0xb7, 0xbb, 0xb6, 0x55, 0x1e, 0xc5, 0xa5, 0x9d, 0x40, 0x1c, 0x18, - 0x58, 0x41, 0x6d, 0x5c, 0x0e, 0x31, 0x4a, 0xe8, 0x67, 0x17, 0x20, 0x5d, - 0xa6, 0xb4, 0x72, 0xa5, 0x1c, 0xce, 0xc9, 0xfd, 0x5f, 0x6d, 0xea, 0x00, - 0x63, 0x46, 0x25, 0x2f, 0x52, 0xe5, 0x56, 0xc6, 0xee, 0xcd, 0xf4, 0xce, - 0xdc, 0x9d, 0xde, 0x54, 0x1d, 0x53, 0xa0, 0xc0, 0x92, 0xaf, 0x9b, 0x66, - 0xf0, 0xb1, 0x54, 0xcf, 0x5f, 0xa8, 0xf7, 0xaf, 0x32, 0x28, 0x02, 0x36, - 0xe8, 0x8a, 0xa6, 0x05, 0x85, 0x9a, 0x8d, 0xcd, 0xa8, 0xf9, 0x01, 0x19, - 0x61, 0x5a, 0xc9, 0xcb, 0xb5, 0xb2, 0xcf, 0xeb, 0x7b, 0xb3, 0x3f, 0x37, - 0x4b, 0x1b, 0xfe, 0x62, 0x1e, 0xf3, 0xc1, 0xab, 0xf5, 0x23, 0xb4, 0x8b, - 0xee, 0xe2, 0x3f, 0xa8, 0x43, 0xcf, 0x59, 0xce, 0xca, 0x1b, 0x03, 0x05, - 0x26, 0x1a, 0x64, 0x7f, 0x7d, 0x7c, 0xc3, 0x5e, 0xcf, 0x40, 0x64, 0x36, - 0xdd, 0xbc, 0xec, 0xed, 0xa1, 0xce, 0x99, 0x54, 0x40, 0x41, 0xcd, 0x8b, - 0xaf, 0x36, 0xaf, 0xc4, 0x00, 0xc3, 0x52, 0x65, 0x9a, 0x58, 0x54, 0xa3, - 0x80, 0xed, 0x90, 0xd7, 0x01, 0x82, 0x7b, 0x4b, 0x32, 0x3f, 0x4a, 0xc8, - 0xf1, 0x5f, 0xbe, 0x0a, 0xd4, 0xfd, 0xd9, 0xe6, 0x3c, 0xc7, 0x3c, 0xd6, - 0x6d, 0x95, 0x1d, 0xa1, 0xce, 0xf0, 0x15, 0xc1, 0x69, 0xec, 0x2f, 0x65, - 0xbe, 0xf9, 0x5a, 0x42, 0xcc, 0x5a, 0x71, 0x7d, 0xb5, 0x60, 0x46, 0x50, - 0x1b, 0x81, 0x52, 0xa0, 0x62, 0x25, 0xe6, 0x15, 0xe4, 0xaa, 0x6e, 0xd8, - 0x05, 0x45, 0x0b, 0x55, 0x51, 0x4e, 0x36, 0xda, 0xdc, 0xea, 0x25, 0xfb, - 0x5f, 0x1e, 0x99, 0x2c, 0xa7, 0xa6, 0x31, 0x8a, 0x18, 0xf1, 0x67, 0x51, - 0x7b, 0xd8, 0x22, 0x92, 0xc0, 0x5a, 0x18, 0x4d, 0x35, 0x8a, 0xdb, 0x6c, - 0xfd, 0x47, 0xd9, 0xb3, 0xd9, 0xeb, 0x7a, 0x59, 0x64, 0xb1, 0x68, 0x80, - 0x85, 0x34, 0xd4, 0x71, 0x4a, 0xb2, 0xa8, 0xce, 0xf7, 0x4d, 0x9f, 0x51, - 0xbe, 0x8e, 0x73, 0x54, 0x5d, 0x81, 0xc4, 0x58, 0xf4, 0xcf, 0xd9, 0x54, - 0x8a, 0x9a, 0xd2, 0xdb, 0xab, 0x6e, 0x77, 0x3b, 0x6c, 0xed, 0x80, 0xe2, - 0xa0, 0x5a, 0xc6, 0x79, 0xbb, 0x4b, 0x3d, 0xef, 0x56, 0xb2, 0xa1, 0x0e, - 0x01, 0xc5, 0x60, 0xb5, 0x86, 0xbd, 0xab, 0xd8, 0xa2, 0x29, 0x84, 0x8b, - 0x52, 0x52, 0xa1, 0x4e, 0x89, 0x95, 0xf3, 0x69, 0x6d, 0xb9, 0x7b, 0x6a, - 0x81, 0xb1, 0xef, 0xb4, 0x8b, 0x33, 0xda, 0xbf, 0xed, 0xb1, 0x02, 0x3e, - 0x0a, 0xb7, 0xed, 0x59, 0x44, 0x51, 0xef, 0xad, 0xc8, 0x8e, 0x93, 0xce, - 0x6b, 0x18, 0x1d, 0x7a, 0xb7, 0xf2, 0x51, 0xb0, 0x9d, 0x16, 0x8b, 0x68, - 0x7b, 0xbb, 0x32, 0x20, 0xf6, 0x1a, 0x27, 0xbb, 0x00, 0x00, 0xb2, 0x08, - 0x2c, 0x2d, 0x8f, 0x37, 0xa3, 0xa1, 0x28, 0x90, 0x74, 0x5d, 0x01, 0xe2, - 0xa0, 0x0d, 0x16, 0x27, 0x77, 0x8a, 0x68, 0xa5, 0x31, 0x23, 0x80, 0xc2, - 0x00, 0xeb, 0xa0, 0xf0, 0xb0, 0x0b, 0x97, 0x03, 0xc5, 0xc0, 0x1a, 0x2c, - 0x5d, 0x2b, 0x60, 0xe1, 0x99, 0x00, 0xb8, 0xa6, 0x10, 0x26, 0x66, 0x6a, - 0x3b, 0x56, 0x26, 0x6b, 0xff, 0x45, 0x2b, 0x12, 0x21, 0xb7, 0x9c, 0x25, - 0x26, 0x2c, 0xa2, 0x64, 0x43, 0x03, 0x3f, 0x94, 0x86, 0xc0, 0xb6, 0x43, - 0xea, 0x99, 0x26, 0xb9, 0x03, 0xc4, 0x7c, 0xee, 0xfe, 0xa0, 0x94, 0xab, - 0x0f, 0x19, 0x56, 0x8d, 0xed, 0x32, 0x2b, 0x79, 0x33, 0xa5, 0x52, 0x20, - 0xe4, 0x5c, 0x1c, 0xa5, 0xea, 0x37, 0xf9, 0x3f, 0x72, 0xd2, 0xb5, 0xc2, - 0x95, 0x74, 0x6c, 0xfe, 0xf1, 0x7e, 0x8a, 0xcc, 0xa6, 0x03, 0x89, 0x9b, - 0x12, 0x19, 0x54, 0x56, 0x1e, 0x0e, 0xe8, 0xfe, 0x6a, 0xf9, 0x79, 0x7f, - 0xda, 0xd7, 0xae, 0x68, 0x70, 0x02, 0x14, 0x4b, 0xfc, 0xf0, 0x73, 0xba, - 0x83, 0x3d, 0x3b, 0x78, 0x6c, 0x1c, 0x60, 0xf3, 0x02, 0x58, 0xed, 0xb4, - 0xac, 0x8f, 0x15, 0x66, 0x87, 0xd5, 0x46, 0xa9, 0xea, 0xf1, 0x98, 0x1e, - 0xfa, 0x74, 0x6c, 0x1f, 0x6f, 0x03, 0xdc, 0xd0, 0xef, 0xc0, 0xc4, 0xc2, - 0xfe, 0x01, 0x76, 0xbd, 0x32, 0x38, 0x39, 0xf7, 0xec, 0x2a, 0x51, 0x9d, - 0xde, 0xdd, 0x92, 0xcc, 0x97, 0x9c, 0xaa, 0x44, 0x4c, 0xe4, 0x05, 0x78, - 0x08, 0x16, 0x2a, 0x2f, 0xd5, 0x78, 0xa3, 0xd3, 0x7a, 0xb1, 0x5d, 0x85, - 0x4b, 0xc5, 0xb9, 0x41, 0x2c, 0x48, 0xa8, 0x0f, 0x2a, 0x03, 0xe9, 0x18, - 0x6c, 0x76, 0xca, 0xb1, 0xcb, 0x0a, 0x47, 0x2c, 0x30, 0xac, 0x15, 0x97, - 0xfd, 0x5e, 0x27, 0x8d, 0x15, 0x6e, 0x2d, 0x00, 0x45, 0x97, 0x08, 0x38, - 0x5b, 0x03, 0xea, 0xd2, 0xa6, 0xbb, 0x8a, 0x4b, 0x65, 0x9f, 0xc9, 0x16, - 0xbe, 0xf6, 0x62, 0x98, 0xd2, 0x22, 0xc5, 0x21, 0xe8, 0x30, 0xa8, 0xd5, - 0xbb, 0x5c, 0xe9, 0xbc, 0x06, 0x5b, 0xeb, 0xd5, 0x2d, 0xf2, 0x07, 0xfa, - 0x80, 0xc2, 0x17, 0x54, 0xa1, 0xef, 0x51, 0x0a, 0x08, 0x97, 0x35, 0xef, - 0x4d, 0xfc, 0xc2, 0xb4, 0xf6, 0x7d, 0x9a, 0x8f, 0xb7, 0x9c, 0xf4, 0x0d, - 0x02, 0xc6, 0x97, 0xdf, 0x03, 0x01, 0xf5, 0x9e, 0x0f, 0x62, 0x99, 0xc5, - 0xb6, 0x2f, 0xd8, 0x04, 0xc6, 0xe2, 0x6b, 0x5f, 0x1b, 0xa6, 0x07, 0xcc, - 0x48, 0xd4, 0xd6, 0xdb, 0xff, 0xf3, 0xbb, 0x23, 0x7a, 0xa7, 0xb6, 0xf5, - 0x70, 0x46, 0xaa, 0x14, 0x01, 0x03, 0x0b, 0x88, 0x6a, 0xc1, 0xb8, 0x98, - 0x72, 0xa3, 0xff, 0xbe, 0x51, 0x3c, 0xa9, 0xa8, 0xa6, 0xdb, 0x6f, 0x24, - 0x9e, 0x11, 0x77, 0x76, 0x85, 0x91, 0x0a, 0xd4, 0x51, 0xb6, 0xa0, 0x21, - 0xa6, 0x79, 0x5b, 0x81, 0xe2, 0x96, 0xe5, 0xa5, 0x88, 0x03, 0x6e, 0xb9, - 0xc2, 0xd7, 0x3e, 0xdc, 0xb0, 0x9b, 0x4b, 0xf6, 0x0e, 0x7b, 0x2a, 0x89, - 0x7f, 0xe4, 0x45, 0x9b, 0x50, 0x15, 0x15, 0x03, 0x02, 0x67, 0xf6, 0x08, - 0x1a, 0x5e, 0x3e, 0xd0, 0xeb, 0xd2, 0xb3, 0xe1, 0xaa, 0x69, 0xba, 0xc1, - 0x6a, 0x92, 0xbb, 0x7a, 0x53, 0xd3, 0xe3, 0x96, 0x44, 0xbc, 0x81, 0x0d, - 0xb6, 0xb7, 0xdf, 0x9f, 0xbe, 0xca, 0x88, 0xab, 0xea, 0x97, 0xc5, 0xa8, - 0x8a, 0xa3, 0x90, 0x05, 0xdd, 0xbd, 0x80, 0xe3, 0x0e, 0xdc, 0x39, 0x66, - 0x84, 0x9c, 0xd4, 0xe9, 0x98, 0x67, 0xc5, 0x7e, 0xf6, 0x5b, 0x60, 0x8a, - 0x89, 0x6e, 0x50, 0xe5, 0x49, 0xe3, 0x23, 0xc2, 0xd8, 0x25, 0xd2, 0xdc, - 0xb8, 0xa6, 0x42, 0xd3, 0x5b, 0x95, 0xa9, 0xd9, 0x60, 0x88, 0x02, 0x57, - 0x56, 0x5e, 0xca, 0xa4, 0x89, 0x4a, 0xa2, 0x91, 0xf3, 0x2a, 0xbf, 0xe1, - 0x13, 0xaa, 0x99, 0xa1, 0xe0, 0x11, 0x2b, 0xc3, 0x14, 0x3b, 0xd2, 0xdc, - 0xc1, 0xd9, 0x75, 0x2a, 0x4b, 0x98, 0x20, 0x9b, 0xce, 0x45, 0xef, 0x43, - 0x9d, 0xd8, 0xa0, 0x18, 0x4c, 0x68, 0xc5, 0x95, 0x2e, 0x67, 0x01, 0x4c, - 0xa7, 0x18, 0xfc, 0xef, 0xff, 0x88, 0x3b, 0x27, 0xba, 0x8e, 0x0d, 0xca, - 0xf8, 0x09, 0x0a, 0x33, 0xef, 0x6c, 0xd8, 0xdc, 0x6d, 0x45, 0x99, 0xa1, - 0xe2, 0xda, 0xb2, 0xd6, 0x50, 0xe3, 0x17, 0x07, 0xc9, 0xff, 0xed, 0x66, - 0x19, 0xab, 0x7b, 0x7b, 0xcc, 0xb0, 0x15, 0xeb, 0x72, 0xde, 0x40, 0xdf, - 0xa0, 0x92, 0x5d, 0x56, 0x01, 0xb6, 0x62, 0x85, 0xa7, 0x69, 0x2c, 0x51, - 0xea, 0x8c, 0x0a, 0x03, 0x83, 0x73, 0x1c, 0x2c, 0xb8, 0x2a, 0x98, 0xc1, - 0xc3, 0x38, 0xd2, 0x76, 0x65, 0xc8, 0xa1, 0xa9, 0xe9, 0x93, 0xb6, 0x2c, - 0x06, 0xff, 0x85, 0x7b, 0x98, 0x0b, 0x55, 0x7e, 0xa5, 0xa9, 0xd5, 0x72, - 0x34, 0x1c, 0x7b, 0xc5, 0x70, 0x92, 0x83, 0x10, 0x09, 0x43, 0xd5, 0xb2, - 0x49, 0x32, 0xc5, 0xea, 0x10, 0x60, 0x4f, 0x0c, 0x40, 0x82, 0xac, 0x14, - 0xdd, 0xeb, 0x5d, 0x99, 0xcd, 0x10, 0x75, 0x7c, 0x97, 0xf6, 0xe7, 0xbd, - 0xc0, 0x5a, 0xf9, 0xe2, 0xd5, 0x8a, 0x19, 0xf5, 0xa5, 0x6b, 0xca, 0x57, - 0x45, 0x67, 0xf1, 0xa4, 0xbe, 0x82, 0x03, 0x45, 0xa5, 0x93, 0xa5, 0x51, - 0x7b, 0x57, 0x42, 0x0b, 0x53, 0x4d, 0x0f, 0x61, 0x7b, 0x19, 0x27, 0xe7, - 0xe1, 0xb5, 0x9a, 0x53, 0x22, 0x3b, 0xcd, 0x05, 0xa1, 0x2c, 0x6c, 0x70, - 0xc2, 0xde, 0xfa, 0x9d, 0x2b, 0x2c, 0xc8, 0x5a, 0x86, 0xc0, 0xef, 0x04, - 0x50, 0x4b, 0xda, 0xf5, 0xc5, 0xd7, 0x99, 0x4b, 0xef, 0xef, 0xbf, 0x32, - 0x32, 0xa4, 0x3c, 0xcf, 0x52, 0xdd, 0xc8, 0x6e, 0x86, 0xa0, 0xb4, 0x21, - 0x62, 0x55, 0x4a, 0xbd, 0x2f, 0xb1, 0x2e, 0x95, 0xee, 0xea, 0xc5, 0xb3, - 0xf4, 0xd2, 0x90, 0x5a, 0x6a, 0xd8, 0xe1, 0xa5, 0x2d, 0xfb, 0x8c, 0xfe, - 0x95, 0x60, 0x8a, 0x87, 0x94, 0x37, 0x07, 0x19, 0xbf, 0x6b, 0x65, 0x80, - 0xad, 0x8a, 0x36, 0xad, 0x31, 0x4f, 0x14, 0x44, 0x6b, 0x95, 0x02, 0x4a, - 0xd3, 0xf7, 0x5e, 0xfa, 0x99, 0x9e, 0x2b, 0x9d, 0xc9, 0xdd, 0x2c, 0xa3, - 0x7e, 0x23, 0xe2, 0x95, 0x18, 0x16, 0xb0, 0x65, 0xd4, 0x5e, 0x28, 0x9b, - 0x11, 0x62, 0x9e, 0xd3, 0xdd, 0xbd, 0x5f, 0x9d, 0xa1, 0xa6, 0x2d, 0x05, - 0x69, 0xe3, 0x55, 0x65, 0xa0, 0xcc, 0xae, 0x70, 0x57, 0xe5, 0xa4, 0xc5, - 0xfe, 0xfa, 0x68, 0xe2, 0xf9, 0xbc, 0xb1, 0x1a, 0xf6, 0xec, 0x47, 0x78, - 0x36, 0xc0, 0xb6, 0xb5, 0x2a, 0x8e, 0x4c, 0x10, 0x4b, 0x57, 0x0f, 0x31, - 0x12, 0xe8, 0xab, 0xca, 0x15, 0xf1, 0x6e, 0x5a, 0x4a, 0x70, 0xd3, 0x78, - 0xae, 0x01, 0x8f, 0xec, 0x5e, 0x75, 0x15, 0xd8, 0x50, 0x73, 0xaf, 0xbb, - 0xf2, 0xda, 0x57, 0x2a, 0x9a, 0x8d, 0x48, 0x77, 0x68, 0x2a, 0x46, 0x10, - 0x69, 0x15, 0x75, 0x89, 0x8e, 0xc6, 0xb9, 0x6f, 0x51, 0x92, 0x2c, 0x44, - 0x86, 0x5e, 0x5e, 0xcc, 0xa1, 0x95, 0xb4, 0xd8, 0x38, 0xc4, 0x6b, 0xf7, - 0xa8, 0x26, 0x96, 0x08, 0xb6, 0x23, 0x28, 0x06, 0x08, 0x92, 0xce, 0xcc, - 0x0f, 0x3d, 0x2e, 0x81, 0x49, 0xcb, 0x2f, 0x09, 0x68, 0x25, 0x3a, 0xd3, - 0x3f, 0xe5, 0x46, 0x6e, 0x11, 0x6f, 0x16, 0xf5, 0x4f, 0xff, 0x4d, 0x23, - 0xe8, 0xc8, 0xf7, 0x2d, 0x4b, 0xaa, 0x6c, 0x9b, 0x81, 0xea, 0x18, 0xa7, - 0xb9, 0xd0, 0x60, 0x9e, 0x07, 0x0d, 0xde, 0xc1, 0xb6, 0x1a, 0x84, 0x45, - 0xaf, 0xf2, 0x77, 0x77, 0x7d, 0xef, 0x40, 0x23, 0x7d, 0x96, 0xf4, 0x09, - 0x9c, 0x1b, 0x8e, 0xc1, 0x99, 0x00, 0xe1, 0x1a, 0x6c, 0xd1, 0x2d, 0x51, - 0x6f, 0x68, 0x78, 0xab, 0xa9, 0xfe, 0x8a, 0xf0, 0x0b, 0x16, 0xe6, 0x29, - 0xd0, 0xe4, 0x05, 0x58, 0xda, 0x78, 0x3e, 0xc8, 0x8d, 0xb5, 0xa8, 0x70, - 0x8d, 0x72, 0x7d, 0x8d, 0x34, 0xaa, 0x95, 0x5f, 0xde, 0x23, 0x36, 0x78, - 0x30, 0xf8, 0x18, 0x10, 0xf0, 0x7f, 0x3c, 0xc2, 0xa2, 0xea, 0x1f, 0xfc, - 0x6e, 0x20, 0xb7, 0x77, 0x3c, 0x32, 0xcc, 0xf0, 0xe4, 0x1f, 0x2a, 0x00, - 0x71, 0x88, 0x86, 0x0c, 0x1f, 0x89, 0x39, 0x41, 0xe0, 0xbf, 0xe9, 0x56, - 0x81, 0x43, 0x59, 0xa3, 0x86, 0x96, 0x45, 0x2f, 0x9a, 0x51, 0xd0, 0x71, - 0x91, 0x6f, 0x24, 0xfb, 0x7e, 0x53, 0x80, 0x24, 0xac, 0x55, 0xff, 0x91, - 0x36, 0x38, 0x03, 0xa0, 0xc3, 0xb0, 0x38, 0x07, 0x80, 0xc6, 0x5c, 0x4e, - 0x5e, 0x85, 0x53, 0x1c, 0xb7, 0x28, 0x2a, 0x7f, 0x8a, 0x73, 0x35, 0x60, - 0x48, 0x06, 0x10, 0x41, 0x06, 0x12, 0xc0, 0x3c, 0x47, 0x6f, 0x9e, 0xfd, - 0x1e, 0x24, 0xe9, 0x53, 0x4c, 0x2d, 0xbc, 0xed, 0x0e, 0xd9, 0x1b, 0xd2, - 0xa0, 0xe0, 0xb3, 0xc0, 0xc2, 0xa0, 0xd8, 0xc0, 0x1c, 0x67, 0xff, 0xfe, - 0x6d, 0x2c, 0x50, 0x22, 0xa3, 0xaf, 0xe9, 0x44, 0x8a, 0x5d, 0x3b, 0x1b, - 0xbf, 0x17, 0x51, 0x80, 0x2d, 0x28, 0x7c, 0xaf, 0x8a, 0x6b, 0x5f, 0xc8, - 0x60, 0xa1, 0x03, 0x70, 0x81, 0xb0, 0xdc, 0x0f, 0x03, 0xfd, 0x8b, 0x0c, - 0x26, 0x68, 0x78, 0x3c, 0x54, 0xd8, 0xf4, 0xbd, 0x21, 0x73, 0x0d, 0x7e, - 0x28, 0xbe, 0x69, 0xaf, 0xc6, 0xa7, 0xa4, 0xbf, 0x1b, 0xe9, 0x5c, 0xa3, - 0x62, 0x63, 0x43, 0xf0, 0x43, 0xd6, 0x1a, 0x00, 0xcd, 0x1f, 0xfe, 0xc6, - 0xdb, 0x67, 0xca, 0xd5, 0x96, 0x45, 0x96, 0x9b, 0x3e, 0x1a, 0x35, 0x9b, - 0x46, 0xc0, 0x28, 0x38, 0x09, 0x1a, 0x9e, 0x78, 0x20, 0xc4, 0xd9, 0xdd, - 0xf8, 0x96, 0x9d, 0x4f, 0x67, 0x33, 0x92, 0xc0, 0x2a, 0x6f, 0x17, 0x01, - 0x06, 0x44, 0x76, 0xd8, 0x57, 0xf1, 0xf7, 0xae, 0xff, 0x59, 0xe6, 0x31, - 0xb2, 0xd5, 0xfd, 0xe2, 0xd8, 0x5b, 0x38, 0x22, 0x6e, 0xf5, 0x40, 0x2b, - 0x82, 0xd2, 0xe2, 0xee, 0x3f, 0x34, 0xe5, 0x85, 0x14, 0x9c, 0xd0, 0x65, - 0xe7, 0x37, 0x39, 0x0b, 0x34, 0x44, 0xbd, 0x5c, 0xb6, 0x06, 0xca, 0x38, - 0x0c, 0x35, 0x75, 0x47, 0x6e, 0xf6, 0xed, 0x5c, 0xa0, 0x4c, 0x0a, 0x35, - 0x58, 0xa1, 0x8c, 0xf7, 0xa7, 0x33, 0xd0, 0xab, 0x09, 0x08, 0x2a, 0x90, - 0x30, 0xba, 0x6a, 0xb5, 0xfe, 0x70, 0x97, 0x82, 0x63, 0xc3, 0xfd, 0xea, - 0x5d, 0x52, 0x8b, 0xa4, 0x6b, 0xf5, 0x77, 0x0d, 0x93, 0xa5, 0xb5, 0xb5, - 0x7b, 0x92, 0xed, 0x9d, 0x0f, 0x11, 0xdb, 0x62, 0x28, 0x08, 0xe7, 0x9a, - 0xc2, 0x28, 0x98, 0xf5, 0x29, 0x72, 0x4f, 0x84, 0x3e, 0x55, 0x7f, 0xdf, - 0x8f, 0xeb, 0x1e, 0xac, 0x2f, 0x67, 0xd3, 0x7b, 0xdd, 0xfa, 0xa2, 0xa0, - 0x2c, 0xd2, 0x2d, 0xfe, 0xe8, 0x77, 0xf5, 0x01, 0xe8, 0x31, 0x00, 0x83, - 0xd1, 0x33, 0x0c, 0x4f, 0x31, 0xe9, 0xe9, 0x88, 0x9a, 0x40, 0x8b, 0x88, - 0x86, 0xca, 0x14, 0x3c, 0x2e, 0xaa, 0xc6, 0xbd, 0x99, 0xd1, 0xc6, 0xa5, - 0x9e, 0xa2, 0x0a, 0xbf, 0x64, 0xbc, 0xb5, 0x1f, 0xa7, 0xc3, 0x80, 0xb5, - 0x95, 0x32, 0x8d, 0x6d, 0x5e, 0x0c, 0x29, 0xea, 0x88, 0x51, 0xb6, 0x32, - 0x06, 0x04, 0x41, 0x24, 0x7f, 0xff, 0x2a, 0x1d, 0x0f, 0xf0, 0x4a, 0x12, - 0x94, 0xe5, 0x64, 0xb0, 0xb6, 0x33, 0x2a, 0xe1, 0xe3, 0x0a, 0x14, 0x15, - 0x68, 0x73, 0xbf, 0xff, 0x80, 0x40, 0x4f, 0x55, 0xe0, 0x44, 0x63, 0xca, - 0x94, 0xeb, 0x79, 0x24, 0xef, 0xfe, 0xbe, 0xfe, 0xf3, 0x9d, 0x78, 0x5b, - 0x12, 0x22, 0x8f, 0x2e, 0x87, 0x83, 0x17, 0x26, 0x87, 0x68, 0x31, 0xa2, - 0xbe, 0x21, 0xe1, 0xb7, 0x1b, 0x46, 0xef, 0xb5, 0xcd, 0xe1, 0xb2, 0x25, - 0xa2, 0x01, 0x44, 0x35, 0x6f, 0xf7, 0x50, 0xf1, 0x00, 0xa8, 0xdb, 0x65, - 0xfe, 0xa8, 0xd7, 0x17, 0xc3, 0xf9, 0x26, 0xa9, 0xf8, 0x79, 0x74, 0x91, - 0x74, 0x04, 0xde, 0x10, 0xc7, 0xda, 0x7f, 0x9c, 0xca, 0xb7, 0x68, 0xbc, - 0x90, 0x29, 0x30, 0xc7, 0xbf, 0x43, 0xbd, 0xd5, 0x08, 0x0d, 0xf0, 0xd9, - 0xf1, 0x4a, 0xc6, 0xa7, 0x57, 0x25, 0x13, 0x97, 0x53, 0x6f, 0x54, 0xa3, - 0x5e, 0x2c, 0x8b, 0x88, 0x01, 0x84, 0xeb, 0x13, 0x46, 0xcd, 0x98, 0x8f, - 0xa8, 0x8a, 0x46, 0xa1, 0xb9, 0xb0, 0x0f, 0x1f, 0xa5, 0x06, 0x4b, 0x82, - 0x09, 0x67, 0x93, 0x30, 0x0a, 0x71, 0xd2, 0xaf, 0x48, 0x57, 0xcf, 0xad, - 0x2f, 0xea, 0x82, 0xbd, 0xd5, 0x70, 0x58, 0x61, 0x4f, 0x64, 0xe2, 0xf1, - 0x7e, 0x94, 0xc3, 0x96, 0x10, 0xc1, 0x48, 0x38, 0x10, 0xd2, 0x97, 0xdb, - 0xb3, 0xca, 0xd5, 0xd4, 0xfe, 0xb1, 0x69, 0xdb, 0x7b, 0x60, 0x12, 0x32, - 0x9e, 0xea, 0xf2, 0x45, 0x34, 0xc9, 0x49, 0x85, 0xa2, 0xad, 0x6f, 0x13, - 0x59, 0xdf, 0x27, 0x55, 0x58, 0xb5, 0x19, 0x66, 0xc8, 0x5a, 0xc7, 0x68, - 0x88, 0x06, 0x2d, 0x04, 0x63, 0x26, 0x07, 0xd2, 0xc4, 0x83, 0xd6, 0xbd, - 0x73, 0xf7, 0xc9, 0xfc, 0x1a, 0x71, 0x15, 0xe5, 0x0d, 0xf4, 0xf9, 0xcf, - 0xb3, 0xbe, 0x06, 0x1c, 0x17, 0xf3, 0xac, 0x7f, 0x85, 0xaa, 0x17, 0xb8, - 0xcf, 0x9b, 0xab, 0xda, 0x22, 0x81, 0x8f, 0xd0, 0x61, 0xa6, 0xf6, 0xf9, - 0x21, 0x78, 0x41, 0x80, 0xc8, 0x2f, 0x99, 0xf8, 0x13, 0xb2, 0x7c, 0x1c, - 0xa5, 0xe3, 0x54, 0xe7, 0x65, 0x31, 0xa2, 0xd5, 0x1f, 0xcc, 0xfc, 0x9b, - 0xed, 0x67, 0x88, 0xf6, 0x6c, 0xb9, 0x0b, 0x25, 0x41, 0x8a, 0x22, 0x8f, - 0x01, 0x00, 0x61, 0x3a, 0x6a, 0x94, 0xc5, 0x20, 0x53, 0x33, 0xa5, 0x42, - 0x2f, 0x50, 0xce, 0x88, 0xa0, 0xe3, 0x2c, 0x79, 0x28, 0x7d, 0x95, 0x4f, - 0x2f, 0x9b, 0xde, 0xee, 0xaf, 0x14, 0x5f, 0x7b, 0xa7, 0xa9, 0x3f, 0xf2, - 0x28, 0x63, 0xd5, 0x6b, 0x06, 0xe8, 0xd1, 0xae, 0xed, 0x8b, 0x1e, 0xab, - 0x2f, 0x4e, 0xde, 0x2a, 0x51, 0xbf, 0xf6, 0x31, 0x66, 0x95, 0x6a, 0xff, - 0x9d, 0x45, 0x41, 0x81, 0x7c, 0x68, 0x47, 0x6b, 0x04, 0xba, 0xa1, 0xbd, - 0x6d, 0x3e, 0x79, 0xac, 0xba, 0xaa, 0xfe, 0xfa, 0x7d, 0x5c, 0x25, 0xcc, - 0xd2, 0xac, 0xca, 0x1e, 0x83, 0x0a, 0xd5, 0x81, 0xee, 0x61, 0x60, 0x14, - 0x53, 0x9d, 0xd5, 0xb3, 0x92, 0xa1, 0x79, 0x66, 0x3c, 0xa0, 0x19, 0x7d, - 0xfe, 0xfe, 0x7a, 0xd0, 0xf3, 0x3f, 0x46, 0xe8, 0xf8, 0x1b, 0xa9, 0xd8, - 0xa5, 0x40, 0x10, 0x30, 0xb1, 0xc5, 0xc3, 0x4d, 0x35, 0x85, 0x8c, 0x2a, - 0x1f, 0x42, 0xd6, 0x16, 0xff, 0xf6, 0x15, 0x76, 0x2d, 0x67, 0x83, 0x60, - 0x71, 0x94, 0xac, 0xfe, 0xdc, 0xf5, 0xd9, 0xee, 0x76, 0xd9, 0xee, 0xca, - 0xa3, 0xa4, 0x26, 0x71, 0x5b, 0x2d, 0xb3, 0x1a, 0x5b, 0x3a, 0xa6, 0xfd, - 0x45, 0x5f, 0xb5, 0x04, 0xa1, 0xce, 0x03, 0x10, 0xaf, 0xa1, 0xe6, 0x08, - 0x0a, 0x94, 0xfd, 0xba, 0x56, 0x57, 0xbd, 0xbc, 0xa8, 0x6d, 0x13, 0xf4, - 0xfd, 0xad, 0xff, 0xd1, 0xcf, 0xf6, 0x76, 0xcc, 0x5b, 0x11, 0x5b, 0xd3, - 0x60, 0xfa, 0xbf, 0xfe, 0xa9, 0x75, 0x4c, 0x2d, 0xe7, 0x7e, 0xb7, 0x3a, - 0x8a, 0x3d, 0x16, 0x98, 0x51, 0x14, 0xef, 0x2e, 0xf2, 0x2f, 0xc9, 0xce, - 0x83, 0x04, 0xf7, 0xdc, 0xde, 0xa1, 0x0e, 0x51, 0x49, 0xd9, 0x78, 0x88, - 0x2c, 0xda, 0xf7, 0xa5, 0xd5, 0xef, 0xd0, 0x40, 0xf3, 0x25, 0x9c, 0x37, - 0xd0, 0x5a, 0xef, 0x30, 0x8b, 0x7b, 0xa5, 0x1d, 0xe3, 0xe5, 0xac, 0xe5, - 0xda, 0x6b, 0xa8, 0x2c, 0x5b, 0xa0, 0xc1, 0x41, 0x7b, 0xba, 0x59, 0x83, - 0x62, 0xb3, 0x4b, 0xd3, 0xcb, 0xb6, 0xae, 0xb5, 0xde, 0x28, 0xf4, 0x29, - 0xdf, 0xde, 0xb8, 0xbd, 0xf6, 0xd9, 0x92, 0xaf, 0x56, 0x82, 0x65, 0x14, - 0x37, 0xf0, 0xea, 0xc9, 0x3d, 0xc5, 0x2b, 0xf5, 0x63, 0x6f, 0xb6, 0xdb, - 0xc4, 0xde, 0x97, 0x57, 0x53, 0xd9, 0x9f, 0x8b, 0xcb, 0x61, 0x0c, 0x74, - 0xe5, 0xd4, 0x4e, 0x6c, 0x5b, 0x5a, 0x8d, 0x5a, 0x81, 0x11, 0x2d, 0x3a, - 0x7c, 0x7e, 0x23, 0x8f, 0x92, 0x6c, 0x68, 0x3d, 0x65, 0xb5, 0x0a, 0x47, - 0x0a, 0xbd, 0x7f, 0xfe, 0x12, 0xcc, 0x2a, 0x68, 0x35, 0xdf, 0x8b, 0x07, - 0xc3, 0xf1, 0x1d, 0x31, 0x78, 0x82, 0x3c, 0x05, 0x5d, 0x69, 0x5f, 0xd4, - 0xfb, 0xbe, 0xdb, 0xef, 0xf8, 0x96, 0x50, 0xb1, 0x62, 0xe4, 0xca, 0xc4, - 0x81, 0x1b, 0x1a, 0xd2, 0xd1, 0xeb, 0x73, 0xbe, 0xf6, 0xfb, 0x14, 0xb7, - 0x7d, 0xdb, 0x7d, 0xda, 0xa4, 0x6c, 0x12, 0x97, 0x8c, 0x07, 0x24, 0x42, - 0x98, 0xa8, 0x39, 0x01, 0x0d, 0x8e, 0x20, 0x32, 0xb5, 0x65, 0x78, 0x99, - 0x21, 0x65, 0x96, 0x45, 0x0c, 0xd0, 0xf5, 0x74, 0x56, 0xcc, 0x1b, 0xa0, - 0x06, 0x21, 0x36, 0xd8, 0x33, 0x62, 0x5c, 0x61, 0xb6, 0xbe, 0x90, 0xb9, - 0x86, 0xf3, 0x68, 0x19, 0xc5, 0xfd, 0x96, 0x5e, 0x5f, 0xd8, 0xa0, 0xaf, - 0x71, 0x72, 0xa0, 0x16, 0x19, 0x04, 0xb1, 0xd0, 0x43, 0x6d, 0x3c, 0x6d, - 0x86, 0x8b, 0xfd, 0xff, 0xee, 0xd0, 0x56, 0xfa, 0x4b, 0x91, 0x0f, 0xbb, - 0x9a, 0x0c, 0x36, 0x5a, 0x15, 0x06, 0xe6, 0x47, 0xe5, 0xec, 0x04, 0x1a, - 0xce, 0x02, 0x2b, 0x4d, 0xfc, 0xb7, 0x7e, 0xd2, 0xac, 0x93, 0xa5, 0xb7, - 0xd7, 0x3b, 0x67, 0x86, 0x70, 0x04, 0x8a, 0x96, 0xa4, 0x80, 0xf0, 0x90, - 0x07, 0xa9, 0x79, 0x45, 0x9e, 0x06, 0x05, 0xa3, 0x63, 0x56, 0xd2, 0x30, - 0x01, 0xec, 0xc1, 0xeb, 0x25, 0xe0, 0xca, 0x7f, 0x3d, 0x9c, 0x53, 0xfe, - 0x64, 0xe0, 0x14, 0x10, 0x03, 0x83, 0xa7, 0x13, 0x82, 0x83, 0x1b, 0x66, - 0xeb, 0x49, 0xb6, 0xf0, 0x19, 0x1f, 0xb2, 0x15, 0x7b, 0x62, 0x1f, 0x06, - 0xda, 0x0c, 0x13, 0x96, 0x2e, 0x1e, 0x0e, 0xd2, 0x32, 0xd3, 0x63, 0x82, - 0xff, 0x55, 0x33, 0x9e, 0x6b, 0xd6, 0xac, 0x6d, 0x6d, 0x06, 0x0a, 0x82, - 0x43, 0x09, 0x4b, 0xb2, 0xe0, 0x83, 0x5b, 0x1e, 0x27, 0x9c, 0x97, 0xff, - 0x8a, 0x1a, 0x6f, 0x7a, 0x88, 0x18, 0x22, 0xfd, 0xff, 0x74, 0x0b, 0x28, - 0x07, 0xcb, 0x80, 0x1c, 0xbc, 0x98, 0x04, 0x02, 0xc6, 0xcc, 0xaa, 0x03, - 0xde, 0xf3, 0x2a, 0x44, 0x0d, 0x9b, 0x39, 0x7c, 0xbd, 0xf4, 0xc0, 0x46, - 0x04, 0x91, 0x1a, 0x6d, 0xdc, 0xcf, 0x83, 0x21, 0xfc, 0xe8, 0xe2, 0x21, - 0xbf, 0x44, 0x0c, 0x34, 0x58, 0x7f, 0x9b, 0xf1, 0x24, 0xae, 0xcf, 0x64, - 0xe6, 0x69, 0x66, 0x0d, 0xef, 0xca, 0xfd, 0xfe, 0x29, 0x52, 0x82, 0x95, - 0x87, 0x40, 0x24, 0xaf, 0xbd, 0xe2, 0xe6, 0xda, 0xc1, 0x01, 0x3f, 0xdb, - 0x6e, 0xf6, 0x5c, 0x62, 0xec, 0x80, 0xaf, 0xa0, 0xc1, 0x58, 0xa9, 0x6a, - 0xaf, 0x65, 0x51, 0xef, 0x63, 0xd0, 0x04, 0x36, 0x0b, 0xe4, 0x80, 0x84, - 0xaf, 0xe9, 0x14, 0xab, 0x64, 0x40, 0x56, 0xce, 0xee, 0x83, 0x22, 0x96, - 0xe4, 0xb7, 0xa5, 0x9c, 0x52, 0xa0, 0x04, 0x06, 0x40, 0x0d, 0x05, 0x20, - 0xec, 0x7c, 0x0c, 0x57, 0xf6, 0xc1, 0x15, 0x27, 0x43, 0xb8, 0x54, 0xa2, - 0x54, 0x3f, 0xf0, 0x7a, 0x7a, 0x53, 0x83, 0x01, 0xb5, 0x6a, 0x14, 0x25, - 0x82, 0x53, 0x4b, 0x83, 0x08, 0x9d, 0x2f, 0xbb, 0xd3, 0x5b, 0xab, 0x62, - 0xc0, 0xc1, 0x41, 0x40, 0x86, 0x0c, 0x1f, 0xa4, 0xbb, 0xef, 0xa5, 0x56, - 0xca, 0xad, 0xe9, 0x5d, 0xda, 0x59, 0x61, 0xa3, 0xc3, 0x5f, 0xfe, 0xfe, - 0x2f, 0xff, 0x9e, 0x6b, 0x0f, 0xbf, 0x00, 0x00, 0xbc, 0x08, 0x6c, 0x78, - 0x3a, 0xa9, 0x82, 0x10, 0x8c, 0x5f, 0xf4, 0xbf, 0x03, 0x03, 0xd1, 0xea, - 0xb0, 0x2d, 0x14, 0xb6, 0x5b, 0xff, 0xde, 0x72, 0x15, 0x15, 0xe6, 0x47, - 0x8e, 0xc7, 0xc2, 0x52, 0x71, 0x24, 0x7e, 0xda, 0xbf, 0x34, 0x5b, 0x8c, - 0x4f, 0xee, 0x63, 0x7c, 0xbd, 0x43, 0x3b, 0x43, 0x91, 0x14, 0x15, 0xe6, - 0x46, 0xcd, 0x63, 0x4c, 0xab, 0xd8, 0xaf, 0xfe, 0xa5, 0x9a, 0xc9, 0x63, - 0x4a, 0xea, 0x86, 0x03, 0xb4, 0x2f, 0x0b, 0x6c, 0x0f, 0x80, 0xe9, 0x79, - 0x77, 0xe8, 0x84, 0x5d, 0x8a, 0xb1, 0x42, 0x85, 0x49, 0xd8, 0xe5, 0x68, - 0x44, 0xed, 0x03, 0x21, 0xb0, 0x8a, 0x0f, 0x95, 0xff, 0xd8, 0x9c, 0x38, - 0xb1, 0x63, 0x8d, 0x82, 0x9d, 0x35, 0x8d, 0x8f, 0x93, 0x7e, 0x72, 0xa9, - 0x6b, 0x29, 0x2c, 0xbc, 0x9d, 0x07, 0x6b, 0xf9, 0x90, 0xe6, 0x0d, 0x80, - 0xa3, 0xa3, 0xc9, 0x42, 0x00, 0x1d, 0x1c, 0xb4, 0xce, 0x7f, 0x4b, 0x12, - 0xef, 0xa0, 0xe2, 0xcb, 0x6d, 0xe5, 0xfe, 0x0d, 0xb1, 0x4f, 0x75, 0x4e, - 0x87, 0x80, 0x24, 0x56, 0x3d, 0x06, 0x4a, 0x07, 0x87, 0xca, 0x73, 0x13, - 0xf8, 0xbd, 0x3c, 0x9a, 0x06, 0x15, 0x6c, 0xb1, 0x12, 0xdd, 0xf8, 0xdb, - 0x0a, 0xc3, 0x82, 0xd1, 0x6a, 0x1e, 0x15, 0x9a, 0xe6, 0xc6, 0x40, 0x74, - 0x4b, 0x54, 0x24, 0x0f, 0xb5, 0xb6, 0x55, 0xf9, 0xab, 0xfe, 0xf9, 0xa5, - 0x28, 0xef, 0xcd, 0x40, 0xd0, 0xc0, 0x7f, 0xd4, 0xb4, 0x7f, 0x91, 0x33, - 0x4d, 0xee, 0x62, 0xbd, 0x5d, 0x96, 0x2a, 0x8d, 0x51, 0x11, 0xc9, 0x54, - 0x0a, 0x01, 0xa0, 0x10, 0xc0, 0xf8, 0xf4, 0x03, 0x52, 0xeb, 0x29, 0xf6, - 0x4c, 0xce, 0x8e, 0x13, 0x4d, 0xb1, 0xa6, 0xb0, 0xd7, 0x83, 0x70, 0xdc, - 0x18, 0x84, 0x5a, 0x07, 0x07, 0xca, 0xcb, 0x27, 0xf6, 0x2d, 0x43, 0xae, - 0xa3, 0x51, 0x51, 0x03, 0x05, 0x53, 0xd2, 0x6f, 0xe2, 0xca, 0x61, 0x86, - 0x9a, 0xa5, 0xed, 0x88, 0x04, 0x86, 0xd3, 0xa6, 0xf6, 0x2a, 0x4c, 0xdd, - 0x5f, 0x92, 0x62, 0xd6, 0x92, 0x2e, 0x64, 0x2e, 0xa6, 0xc1, 0x25, 0xac, - 0x10, 0x47, 0xed, 0xfb, 0xa2, 0x23, 0x5e, 0x93, 0x7e, 0x49, 0x2d, 0x05, - 0xaa, 0x82, 0x32, 0x7c, 0x48, 0x5f, 0x0b, 0x57, 0x2c, 0xca, 0x56, 0xb6, - 0x49, 0x56, 0xe0, 0xdd, 0x18, 0x30, 0x98, 0x5e, 0x3e, 0x95, 0x5b, 0x11, - 0x2d, 0xea, 0x9d, 0x97, 0x5a, 0xce, 0x70, 0xa9, 0x07, 0x46, 0x2a, 0x41, - 0x5c, 0x16, 0x10, 0xcd, 0xf6, 0x6a, 0x8f, 0x41, 0x62, 0x3d, 0x31, 0x7a, - 0xa1, 0xea, 0xb1, 0xb9, 0x67, 0xba, 0xb5, 0x10, 0x37, 0x66, 0xef, 0x49, - 0x3c, 0x16, 0x21, 0x44, 0x7f, 0xdd, 0xef, 0xf9, 0x9a, 0xb0, 0xd9, 0x69, - 0x36, 0x2d, 0x61, 0xe1, 0x9d, 0xc6, 0x7e, 0x9e, 0x6e, 0x20, 0xe8, 0x7a, - 0x4a, 0x7c, 0x43, 0xf1, 0xe4, 0xfa, 0x65, 0x4d, 0xed, 0xeb, 0x3f, 0xf1, - 0x5e, 0xc5, 0x97, 0x15, 0x8d, 0x5a, 0xb9, 0xf6, 0xbc, 0xa5, 0x84, 0xf7, - 0x14, 0xf9, 0x46, 0xde, 0x5b, 0xfc, 0x45, 0x61, 0x2b, 0x85, 0x8c, 0x24, - 0xf4, 0xcb, 0xbc, 0x95, 0x47, 0x42, 0xa3, 0xb4, 0x3f, 0x4c, 0xa0, 0x45, - 0xe2, 0x21, 0x12, 0x70, 0x52, 0x18, 0x15, 0x83, 0x7d, 0x2a, 0xa0, 0x0c, - 0x6c, 0x21, 0xb2, 0x3e, 0xf2, 0x98, 0x06, 0x1a, 0x2e, 0x55, 0xbd, 0x8d, - 0xed, 0x6e, 0x30, 0xc5, 0xee, 0x60, 0xdb, 0x7a, 0xa5, 0x49, 0x60, 0x74, - 0x0c, 0x40, 0xd4, 0xb8, 0x84, 0x80, 0x98, 0xa6, 0xde, 0x6d, 0xe8, 0xac, - 0x2f, 0x26, 0x4f, 0x9e, 0x54, 0xd3, 0x76, 0x01, 0x9f, 0xb5, 0x85, 0x48, - 0xb9, 0x6c, 0x96, 0x86, 0x80, 0x26, 0xae, 0xd6, 0xef, 0x51, 0x51, 0xac, - 0xe3, 0xd3, 0x5c, 0x73, 0xcf, 0x8d, 0xb6, 0x4b, 0x51, 0x94, 0x23, 0xa0, - 0xe3, 0x06, 0x99, 0x63, 0xe5, 0xe0, 0x43, 0xec, 0x71, 0x68, 0x87, 0x9d, - 0x9d, 0xe0, 0x6e, 0x0b, 0x7b, 0x56, 0xa8, 0xb6, 0xe6, 0x96, 0xec, 0xdf, - 0x66, 0x96, 0x58, 0x88, 0x3d, 0x96, 0x72, 0xc1, 0x14, 0x8d, 0x44, 0x89, - 0x9b, 0x4d, 0xd1, 0xc6, 0xde, 0x5d, 0x2d, 0xb8, 0x05, 0x14, 0xd4, 0x76, - 0x44, 0x0a, 0x4c, 0x97, 0xd3, 0x54, 0xee, 0xd8, 0xf1, 0x5b, 0x00, 0xa6, - 0x1f, 0x0f, 0xcb, 0xb7, 0x6c, 0x69, 0x66, 0xd5, 0x1b, 0xce, 0xb7, 0xb7, - 0x92, 0x87, 0x28, 0xcc, 0x27, 0x38, 0xca, 0x71, 0xf3, 0x7a, 0xbf, 0x87, - 0xe5, 0xdf, 0xc6, 0x50, 0x6e, 0x46, 0x27, 0x3f, 0x68, 0x72, 0x56, 0x0c, - 0x44, 0x44, 0x47, 0x54, 0xa3, 0x7c, 0x20, 0xf7, 0x7c, 0x3d, 0xd8, 0xd7, - 0x62, 0x39, 0x7f, 0x7b, 0x60, 0x54, 0xba, 0x6c, 0xbf, 0x54, 0x93, 0xb2, - 0xa9, 0xdf, 0x0e, 0xd2, 0x40, 0xe7, 0x24, 0xbd, 0x02, 0x4a, 0x79, 0x4b, - 0x4c, 0x0d, 0x7c, 0x12, 0x47, 0x3e, 0x37, 0x79, 0x65, 0x9a, 0x2a, 0x1e, - 0x0f, 0xda, 0x50, 0xb6, 0x07, 0xcd, 0xc2, 0xc5, 0xeb, 0x79, 0x7d, 0x01, - 0x1d, 0x40, 0x31, 0x0b, 0x57, 0xca, 0xa9, 0x33, 0x79, 0xf2, 0xad, 0x51, - 0x9b, 0xbc, 0xe4, 0x92, 0x44, 0x40, 0xc2, 0x75, 0x58, 0xc4, 0xe1, 0xfe, - 0xfe, 0x5f, 0xe6, 0x7f, 0xcc, 0x42, 0xc9, 0xc9, 0xc8, 0xc4, 0x99, 0x67, - 0x83, 0x4d, 0xee, 0x83, 0x10, 0x24, 0x93, 0x3c, 0xd2, 0xa1, 0xea, 0x66, - 0x6a, 0x94, 0xcc, 0x37, 0xa5, 0x9d, 0x5f, 0xb9, 0xfa, 0x0c, 0x73, 0x73, - 0xd6, 0x9f, 0x3e, 0x59, 0x5a, 0xc2, 0xa2, 0xab, 0x71, 0x40, 0x8b, 0x49, - 0x68, 0x72, 0x1b, 0x03, 0x10, 0x28, 0x91, 0x49, 0x79, 0x76, 0xb4, 0x5a, - 0x58, 0xdb, 0x4d, 0x83, 0x2f, 0xa2, 0x2d, 0x43, 0x21, 0xfb, 0x12, 0x35, - 0x96, 0x29, 0x7b, 0x17, 0x36, 0xb0, 0xc7, 0xbb, 0xea, 0x8e, 0xf2, 0xc0, - 0x2d, 0xd0, 0xe5, 0x70, 0xf0, 0x50, 0x92, 0xae, 0x64, 0xd2, 0xcc, 0x59, - 0x3d, 0xcd, 0xea, 0x15, 0xa5, 0x97, 0xb0, 0x36, 0x04, 0x85, 0xed, 0x3f, - 0xf2, 0x03, 0x0d, 0x98, 0xf7, 0x27, 0x27, 0xf5, 0x16, 0xa9, 0x42, 0x76, - 0xd7, 0x69, 0x9b, 0xa3, 0x69, 0x5a, 0xcf, 0x14, 0xa2, 0xe7, 0x06, 0x9f, - 0x77, 0x96, 0xcb, 0x96, 0xf0, 0x6d, 0xc5, 0xe5, 0xde, 0x5a, 0xb8, 0x2d, - 0xe3, 0x58, 0x10, 0x73, 0x07, 0x37, 0x9f, 0xbf, 0xe7, 0x3a, 0xa6, 0x87, - 0x92, 0x07, 0x96, 0x88, 0x84, 0x1d, 0xb9, 0xb8, 0xb5, 0xee, 0xdd, 0xda, - 0x36, 0xc1, 0x12, 0x1a, 0x76, 0xee, 0x95, 0x22, 0xea, 0x22, 0x45, 0x90, - 0x48, 0x09, 0x69, 0x60, 0x6e, 0xb6, 0x9d, 0xf4, 0x6c, 0xb2, 0x25, 0xca, - 0x78, 0x4d, 0x29, 0x7b, 0xb3, 0x96, 0xa2, 0x97, 0xb2, 0xc8, 0x88, 0x94, - 0xfc, 0x83, 0x2c, 0xa9, 0x8a, 0xde, 0xf3, 0x18, 0x92, 0x77, 0xf5, 0x68, - 0x79, 0x3f, 0x78, 0xb7, 0xca, 0x21, 0x54, 0xe8, 0xcf, 0x82, 0xae, 0x3d, - 0x49, 0xef, 0xaa, 0x99, 0x7d, 0x19, 0x62, 0x74, 0x41, 0xc5, 0x17, 0xaa, - 0x38, 0xb5, 0xe2, 0x92, 0xbc, 0x31, 0x27, 0xbd, 0x77, 0xa4, 0xcd, 0x8f, - 0x07, 0xa0, 0xa3, 0x07, 0x02, 0x9c, 0x46, 0x03, 0x4d, 0xa4, 0x82, 0x06, - 0xdf, 0x36, 0x88, 0xb5, 0x0a, 0xd7, 0x06, 0xf8, 0xcb, 0x5d, 0x06, 0x1a, - 0x93, 0xee, 0x34, 0x01, 0xc9, 0x34, 0x44, 0x55, 0xec, 0xe1, 0xae, 0x5b, - 0xa7, 0xc9, 0x44, 0x8d, 0x7f, 0xc9, 0x95, 0x01, 0x86, 0x4b, 0xbc, 0xb0, - 0xe6, 0xaf, 0x56, 0x5b, 0xd0, 0x39, 0xd2, 0xa1, 0x14, 0x05, 0xb1, 0x1c, - 0x4a, 0x0f, 0xc7, 0xda, 0x24, 0x0e, 0x75, 0x8c, 0x2a, 0x50, 0x58, 0x8e, - 0x16, 0x5b, 0xce, 0x5d, 0x1b, 0xe2, 0xe1, 0x61, 0x78, 0xe1, 0x1c, 0xc9, - 0x84, 0x49, 0x86, 0x3f, 0x46, 0x07, 0xe9, 0x7c, 0x97, 0x99, 0x64, 0x66, - 0x8e, 0x22, 0x32, 0x49, 0x43, 0x62, 0x30, 0xa4, 0xc3, 0x45, 0x4a, 0x36, - 0xcd, 0xb3, 0xb0, 0xda, 0x22, 0x26, 0x24, 0x00, 0x70, 0xfd, 0xa5, 0x7f, - 0xf0, 0xfc, 0x40, 0xa9, 0x98, 0x0e, 0xbe, 0xaa, 0x16, 0x6a, 0x74, 0x5c, - 0x2d, 0x8a, 0x56, 0xcc, 0x02, 0xa6, 0x11, 0x2e, 0xf3, 0x65, 0x94, 0x38, - 0xe2, 0xc6, 0xec, 0x43, 0xc0, 0xd0, 0x16, 0x8a, 0x2a, 0x44, 0xc6, 0x3e, - 0x4e, 0x39, 0xef, 0x2e, 0x6f, 0x97, 0x2b, 0x88, 0xfb, 0x2d, 0x97, 0xdc, - 0x11, 0x14, 0x1e, 0x1f, 0x7c, 0x4b, 0x4c, 0xa8, 0x21, 0xb3, 0xa9, 0x7b, - 0xfb, 0x26, 0xcf, 0x36, 0x8f, 0x1a, 0x63, 0x93, 0xbe, 0x90, 0x19, 0x01, - 0x58, 0x76, 0x04, 0x45, 0xa3, 0x01, 0xe3, 0x1b, 0x19, 0x2f, 0xd1, 0x05, - 0x56, 0x97, 0x33, 0x41, 0x58, 0xa1, 0x7d, 0xbf, 0x9f, 0x0f, 0x69, 0x21, - 0x5f, 0x70, 0x15, 0xf8, 0x65, 0x14, 0xa2, 0x43, 0x19, 0x9a, 0xc4, 0x62, - 0x75, 0xbe, 0xec, 0xd5, 0xe5, 0x2d, 0xa8, 0x6d, 0x01, 0x22, 0xab, 0x2c, - 0x75, 0x5b, 0x17, 0x02, 0x28, 0xfa, 0xa6, 0xfa, 0x71, 0xce, 0x08, 0x0c, - 0x50, 0x32, 0x58, 0x57, 0xc1, 0x51, 0x8a, 0x01, 0xa0, 0x80, 0xde, 0x07, - 0xcc, 0xe9, 0x6f, 0xb7, 0x90, 0x19, 0x76, 0xaa, 0x82, 0x9e, 0x87, 0xa0, - 0x24, 0xf0, 0x28, 0x95, 0x32, 0xc6, 0xfd, 0x22, 0xb6, 0xac, 0x95, 0x7e, - 0xa3, 0x63, 0x64, 0xfd, 0x40, 0x1c, 0xa8, 0xa0, 0xef, 0x83, 0xe5, 0x40, - 0x0e, 0xa0, 0x1d, 0x06, 0xc0, 0x36, 0x95, 0xb5, 0x63, 0xce, 0xe6, 0xad, - 0x0b, 0x28, 0x75, 0xb2, 0x2c, 0xb0, 0x70, 0x16, 0x31, 0x1f, 0xda, 0x4e, - 0xda, 0x81, 0x03, 0xd8, 0x0e, 0x03, 0xe9, 0x7e, 0x39, 0xa5, 0xed, 0x37, - 0x14, 0x17, 0x6e, 0xa2, 0x9c, 0xb2, 0xd9, 0xd0, 0x70, 0x74, 0x50, 0x64, - 0x2d, 0xa7, 0xde, 0x76, 0xa9, 0x51, 0xc8, 0x33, 0xe4, 0x01, 0x3d, 0xa6, - 0x0b, 0xc2, 0x00, 0x80, 0xce, 0xe4, 0x1c, 0x26, 0x6a, 0x23, 0xe6, 0x4b, - 0xb5, 0x1d, 0x02, 0x7b, 0xd3, 0x21, 0x9e, 0x04, 0x1f, 0x97, 0xb6, 0x20, - 0xb7, 0x14, 0xb5, 0xd1, 0xb7, 0xb9, 0xb9, 0xcb, 0x51, 0xac, 0x37, 0xd0, - 0x4b, 0x4c, 0x63, 0x77, 0xa4, 0xd5, 0xc9, 0x87, 0x10, 0x36, 0x3f, 0x10, - 0x68, 0x29, 0xf4, 0x11, 0x53, 0x66, 0xfc, 0x3a, 0xdb, 0x1b, 0xe7, 0x56, - 0x5f, 0x4b, 0x54, 0x6e, 0x60, 0x2d, 0x04, 0x8a, 0xc7, 0x89, 0xa8, 0x95, - 0x7b, 0xf6, 0x74, 0xb6, 0x4a, 0xd0, 0xe4, 0xae, 0xa8, 0xbc, 0xe4, 0xbf, - 0x0e, 0x57, 0x52, 0x1d, 0x02, 0x50, 0x5e, 0xd1, 0x23, 0xc1, 0xf3, 0x29, - 0xc7, 0xd6, 0x34, 0x9c, 0xb0, 0x72, 0x54, 0x8b, 0x64, 0x9d, 0x5d, 0xcb, - 0x89, 0x40, 0x77, 0xdb, 0x5a, 0x1f, 0x6f, 0xae, 0xdf, 0x2a, 0x1c, 0xab, - 0xde, 0x07, 0x9e, 0xd9, 0x11, 0x06, 0x60, 0xc3, 0x57, 0x9e, 0xe4, 0xef, - 0x54, 0x85, 0x91, 0x00, 0x00, 0xc1, 0x08, 0x6c, 0x37, 0x01, 0xaf, 0x67, - 0xc1, 0x16, 0x4e, 0xf3, 0x6a, 0x94, 0x75, 0x75, 0xea, 0xe0, 0xc2, 0x71, - 0x28, 0x84, 0x0c, 0xad, 0x58, 0xf8, 0x15, 0x99, 0xed, 0xfe, 0x5f, 0xe6, - 0x32, 0xba, 0x8f, 0x28, 0xb7, 0xf2, 0xd6, 0x3d, 0xaa, 0x14, 0xb6, 0x04, - 0x00, 0xaf, 0xc5, 0x88, 0x84, 0x14, 0xa0, 0xa6, 0x4c, 0x91, 0xb5, 0x4a, - 0xa6, 0xb7, 0xc8, 0x1f, 0xde, 0xdd, 0x96, 0x70, 0x18, 0x93, 0x0a, 0x81, - 0x84, 0xe1, 0x9b, 0xc9, 0x58, 0x57, 0xea, 0x20, 0x37, 0x3c, 0x96, 0xd8, - 0x06, 0x2c, 0xa5, 0xb2, 0xd9, 0x7b, 0x7d, 0xfd, 0x11, 0x73, 0x4a, 0x94, - 0x82, 0xdc, 0x2f, 0x99, 0x2a, 0x30, 0x4b, 0x16, 0xab, 0x9e, 0x6c, 0x31, - 0x03, 0x0f, 0x55, 0xb0, 0xda, 0x5f, 0x6c, 0xfb, 0x29, 0xda, 0x57, 0xea, - 0xcc, 0xac, 0xac, 0x94, 0x7d, 0xb7, 0xf4, 0x1c, 0x5d, 0x18, 0x06, 0x02, - 0x8d, 0x66, 0x73, 0x4a, 0xcb, 0x7e, 0xac, 0x3b, 0x2d, 0x16, 0x06, 0x7a, - 0x55, 0x85, 0xb7, 0xdf, 0xb3, 0xfd, 0x51, 0xfd, 0x8a, 0x25, 0xe2, 0xd6, - 0x40, 0xec, 0x12, 0x06, 0xbb, 0x77, 0xec, 0xeb, 0x5f, 0xff, 0xf7, 0x33, - 0x69, 0x69, 0x6f, 0x6b, 0x62, 0x0f, 0x2c, 0x5e, 0x83, 0x21, 0xc0, 0x60, - 0x96, 0x2a, 0x9b, 0xdf, 0x75, 0x42, 0x35, 0x19, 0xde, 0xe2, 0xe8, 0xe7, - 0x83, 0x7d, 0x58, 0x69, 0x37, 0xd2, 0x43, 0x87, 0x1e, 0x6d, 0x7c, 0x9d, - 0xab, 0x59, 0x09, 0x6a, 0xd3, 0xa8, 0xcf, 0x0b, 0x1a, 0x00, 0xd4, 0xfe, - 0xcc, 0xf7, 0xa6, 0x45, 0x12, 0x2e, 0xba, 0x04, 0x40, 0x97, 0x37, 0x39, - 0x67, 0x94, 0x59, 0x44, 0x54, 0x37, 0xa2, 0x83, 0xa5, 0x5e, 0x0e, 0xaf, - 0x4a, 0x73, 0x96, 0x12, 0x8d, 0xc1, 0xd8, 0x2b, 0x37, 0xdf, 0xff, 0xba, - 0xa2, 0x85, 0x90, 0xc3, 0x65, 0x30, 0x0e, 0xd6, 0xd9, 0x2e, 0x53, 0x24, - 0x68, 0x3f, 0x55, 0x47, 0x76, 0x2f, 0xac, 0x87, 0xb2, 0x5e, 0x83, 0x12, - 0x2e, 0xa0, 0x2c, 0x04, 0xc0, 0xf8, 0x76, 0xd0, 0x18, 0xd5, 0x38, 0xa3, - 0x99, 0x7b, 0xd5, 0x94, 0x54, 0x21, 0x5f, 0x97, 0xc5, 0x93, 0x37, 0x34, - 0xb6, 0x6a, 0xdc, 0x58, 0xaa, 0xca, 0xb0, 0x23, 0x9e, 0x06, 0x20, 0x20, - 0x02, 0x17, 0xe2, 0x65, 0x55, 0x96, 0x5b, 0xdd, 0xbb, 0xea, 0x58, 0x05, - 0x1a, 0x60, 0x6e, 0x59, 0xd0, 0xdc, 0x0a, 0xe1, 0x82, 0x98, 0x85, 0xbd, - 0xe8, 0x3e, 0x4f, 0xff, 0x65, 0x7b, 0xa7, 0x53, 0x16, 0xb2, 0x91, 0x23, - 0x61, 0xec, 0x84, 0xaa, 0x71, 0x65, 0x89, 0xe7, 0xed, 0x8e, 0x72, 0x4e, - 0x95, 0x7b, 0x27, 0x03, 0x7b, 0x22, 0x20, 0x60, 0x8c, 0x20, 0xfc, 0x7f, - 0x58, 0x68, 0x3e, 0xf6, 0x95, 0xd0, 0xea, 0x41, 0x13, 0xc8, 0x7b, 0x46, - 0x88, 0x8f, 0xbb, 0xff, 0x50, 0xf5, 0x0d, 0x44, 0x8e, 0x0a, 0xad, 0xce, - 0x4e, 0xbd, 0x53, 0x19, 0xe2, 0x51, 0x07, 0xc3, 0xff, 0x2b, 0x51, 0x8d, - 0x96, 0xcc, 0xc4, 0x1c, 0x9f, 0x85, 0x92, 0x5a, 0x32, 0xba, 0x0c, 0x26, - 0xe1, 0x08, 0x7c, 0x0c, 0xa0, 0x7c, 0xa8, 0x79, 0x9f, 0xad, 0xf9, 0x37, - 0xf7, 0x8b, 0xdd, 0x51, 0x96, 0xdb, 0x3d, 0x3f, 0xa3, 0x75, 0x1d, 0xa5, - 0x62, 0xb1, 0xb8, 0x28, 0xd2, 0x46, 0xc1, 0x54, 0x24, 0x35, 0x95, 0x43, - 0x29, 0xe2, 0xb5, 0x6a, 0xef, 0xef, 0x4b, 0x7c, 0xbc, 0x0f, 0x30, 0xad, - 0xb0, 0x54, 0x82, 0xa3, 0x00, 0x50, 0x5c, 0x04, 0x51, 0xe4, 0xf4, 0xd9, - 0xe2, 0xc6, 0x47, 0x05, 0x7c, 0xca, 0x36, 0x58, 0xd0, 0x73, 0xc8, 0x65, - 0xec, 0x5a, 0x50, 0x5a, 0xbb, 0x78, 0x41, 0x48, 0xd8, 0x8e, 0x58, 0x0a, - 0xdc, 0x4f, 0x9e, 0xdd, 0x06, 0x43, 0x3d, 0xfc, 0xf5, 0xe7, 0x2d, 0x50, - 0x38, 0xd0, 0x7c, 0xbf, 0xfe, 0xc5, 0xad, 0x6c, 0xdd, 0xe6, 0x2e, 0x2e, - 0x38, 0x61, 0x5c, 0xf2, 0x56, 0x22, 0xb6, 0x11, 0xe4, 0x9d, 0x36, 0x78, - 0xf8, 0x85, 0x44, 0x01, 0x07, 0xed, 0xdb, 0x61, 0x67, 0x61, 0xa2, 0x74, - 0xb8, 0x1e, 0x52, 0x79, 0x1c, 0x99, 0x7f, 0xe7, 0x0a, 0x6c, 0x0a, 0xc6, - 0x3f, 0xed, 0x5b, 0xcb, 0x71, 0x6b, 0x4d, 0x57, 0x23, 0xe0, 0x87, 0x8a, - 0xfe, 0x55, 0x29, 0x62, 0x85, 0xd0, 0x93, 0x22, 0xb4, 0xee, 0xcb, 0x2e, - 0x21, 0x36, 0x34, 0x65, 0x1c, 0x23, 0xdb, 0x18, 0x0f, 0xe2, 0xbc, 0x50, - 0xa2, 0xf7, 0x9c, 0xbb, 0xb5, 0x1d, 0xde, 0xc4, 0x41, 0xc0, 0x58, 0xbb, - 0x4a, 0xc3, 0xea, 0x99, 0xa0, 0x60, 0xe0, 0xbf, 0x71, 0x7a, 0x0c, 0x1c, - 0xb7, 0x4b, 0x38, 0x1c, 0x95, 0x47, 0xa0, 0x96, 0xe6, 0xf9, 0x59, 0xaf, - 0xb5, 0xbc, 0x37, 0xc9, 0x09, 0x87, 0x81, 0xdc, 0x1f, 0x33, 0xea, 0x05, - 0xd5, 0x97, 0x53, 0x7c, 0x92, 0x7f, 0xa5, 0x28, 0x9c, 0x63, 0x64, 0x07, - 0xab, 0x9c, 0xe5, 0x05, 0xa9, 0x64, 0x87, 0x98, 0x0e, 0x2f, 0x67, 0x6a, - 0xf5, 0x56, 0x32, 0xa9, 0x4a, 0x1e, 0x4b, 0x3f, 0xe0, 0x76, 0x3c, 0xcf, - 0xc6, 0xc5, 0xf3, 0xeb, 0x8e, 0x7a, 0x55, 0x17, 0xa8, 0xf9, 0x28, 0x56, - 0x24, 0xc0, 0x2e, 0x07, 0xf7, 0xdc, 0xc5, 0x2c, 0x0f, 0x98, 0x52, 0x86, - 0xfe, 0xfa, 0xf7, 0xb0, 0x66, 0xa4, 0x18, 0x86, 0x33, 0x2c, 0xda, 0x39, - 0xd9, 0xfc, 0x69, 0xa9, 0x14, 0xf2, 0x44, 0x53, 0x91, 0x61, 0x13, 0x42, - 0xd3, 0x0f, 0x7d, 0x97, 0xfe, 0xe2, 0x64, 0x9f, 0xfc, 0x80, 0x66, 0xfa, - 0x74, 0xdd, 0xb2, 0x70, 0xea, 0xc3, 0xc6, 0xff, 0xa5, 0xc0, 0x6f, 0xfc, - 0x52, 0xa7, 0x67, 0xbd, 0x16, 0x42, 0xb8, 0x30, 0x26, 0x98, 0x4e, 0xd0, - 0x7e, 0x3e, 0x50, 0x86, 0x0d, 0xd7, 0x5e, 0x71, 0x6b, 0x4f, 0xa8, 0x92, - 0xfb, 0x5a, 0x2c, 0xef, 0x40, 0xd7, 0x3c, 0xa3, 0x9c, 0xec, 0x07, 0x07, - 0x3c, 0x01, 0x32, 0xda, 0x55, 0x9c, 0xc3, 0x57, 0xb2, 0x29, 0x95, 0x0f, - 0x48, 0x76, 0xc0, 0xeb, 0x7a, 0x8a, 0x52, 0xd3, 0x6b, 0xf1, 0x70, 0xdb, - 0x48, 0x92, 0x2b, 0x53, 0x59, 0xcc, 0xa1, 0xe7, 0x3b, 0x91, 0x7b, 0xf2, - 0x4a, 0x6f, 0x0c, 0x20, 0x5b, 0x2a, 0x8f, 0xf2, 0xe4, 0xb0, 0xae, 0x59, - 0xc5, 0xc8, 0x65, 0xba, 0x53, 0x56, 0xe5, 0x58, 0x2b, 0x2a, 0xd4, 0x98, - 0xba, 0x0b, 0xc0, 0xc9, 0x70, 0x60, 0xae, 0x15, 0x16, 0x7c, 0x6c, 0x45, - 0x19, 0x83, 0x7b, 0xd5, 0xbd, 0x0a, 0x69, 0xff, 0x6d, 0xcc, 0x5a, 0xb2, - 0x39, 0x53, 0x24, 0xd9, 0x5a, 0x5a, 0x72, 0x8a, 0x4b, 0xe6, 0xd5, 0x6d, - 0x66, 0x31, 0xd8, 0x86, 0xaf, 0xda, 0xa4, 0x15, 0x20, 0xb5, 0xeb, 0xf2, - 0xd4, 0x77, 0xa3, 0x2b, 0x38, 0x44, 0x70, 0x19, 0x48, 0x29, 0xbd, 0x73, - 0x33, 0x01, 0x4e, 0xcd, 0xe1, 0x50, 0x14, 0x95, 0x0b, 0xd6, 0xce, 0x64, - 0x78, 0x9e, 0x07, 0x4e, 0x4d, 0x4e, 0x2a, 0x55, 0xef, 0xe3, 0x31, 0x85, - 0xfb, 0xb6, 0x87, 0x51, 0x4f, 0xea, 0x9e, 0xd1, 0xb9, 0x5a, 0xe1, 0x68, - 0xf4, 0xbd, 0x28, 0xfd, 0x55, 0xdd, 0x05, 0x30, 0x29, 0xd5, 0x4e, 0xa8, - 0x4a, 0x5d, 0xff, 0x6c, 0x2c, 0x88, 0xa7, 0x06, 0xe1, 0x6d, 0x44, 0x93, - 0xfc, 0x0f, 0xc0, 0xcf, 0x3b, 0xde, 0x8d, 0xb7, 0xf5, 0x1f, 0xec, 0x11, - 0x51, 0x03, 0xe4, 0x40, 0x0e, 0x2c, 0xd9, 0x18, 0x6b, 0xfb, 0x33, 0x81, - 0xed, 0xe4, 0x88, 0xa7, 0xbd, 0xe6, 0xea, 0xc1, 0xc0, 0x38, 0x3d, 0x23, - 0x2b, 0x10, 0x38, 0xa4, 0xc6, 0x43, 0xe0, 0x41, 0x1f, 0x0f, 0x75, 0x5e, - 0x7c, 0x72, 0xc6, 0xb5, 0x32, 0xee, 0x6c, 0x5e, 0xf6, 0x55, 0xa7, 0x11, - 0xe0, 0x6e, 0x04, 0x5e, 0x5d, 0xb1, 0xf8, 0x20, 0x96, 0x68, 0x29, 0x87, - 0xcc, 0x02, 0x9b, 0xd2, 0xb7, 0x9e, 0x56, 0xae, 0x81, 0xbf, 0xb1, 0x3d, - 0xc9, 0x39, 0x83, 0x6d, 0xdd, 0x0e, 0x43, 0xd0, 0x28, 0x58, 0x02, 0x03, - 0x48, 0x40, 0xd2, 0xf1, 0xd8, 0x8e, 0x3d, 0xd4, 0xe3, 0xe1, 0xc1, 0x72, - 0xd8, 0xa8, 0x41, 0x2e, 0x8d, 0x37, 0xf9, 0x6f, 0x7d, 0x63, 0x25, 0x5b, - 0x73, 0x32, 0x52, 0xad, 0xf0, 0x71, 0xf0, 0x63, 0x82, 0xf6, 0xf3, 0x19, - 0x12, 0xd8, 0x11, 0x8b, 0x59, 0x5d, 0xaa, 0x3d, 0x67, 0x9c, 0xe7, 0xd8, - 0x62, 0xcf, 0x16, 0x5a, 0xa1, 0x6c, 0xdd, 0xff, 0xb4, 0xa8, 0x3d, 0x2a, - 0x33, 0x09, 0xd9, 0x33, 0xd8, 0x3b, 0x12, 0x04, 0x96, 0x98, 0xfc, 0x54, - 0xce, 0x27, 0xac, 0xc5, 0x59, 0xe6, 0x98, 0xfc, 0x8d, 0x5e, 0x5b, 0x7f, - 0xfb, 0x85, 0x43, 0x85, 0xa9, 0x5e, 0x81, 0x50, 0xb0, 0xbd, 0x1d, 0xa7, - 0x1d, 0x77, 0xea, 0xcb, 0xbe, 0x9c, 0x4a, 0x85, 0x41, 0xfb, 0x0a, 0xad, - 0xfe, 0x2f, 0x27, 0x2f, 0xb0, 0xac, 0xc8, 0x83, 0x13, 0x7b, 0x3d, 0x47, - 0x1c, 0x68, 0xaa, 0xae, 0x59, 0xee, 0x61, 0xbb, 0xc0, 0xb0, 0x31, 0x89, - 0x69, 0x84, 0x9a, 0x3e, 0x4e, 0x3f, 0x2e, 0xd5, 0x5a, 0x59, 0x20, 0x80, - 0xaa, 0x61, 0x64, 0x6c, 0x3d, 0x93, 0xe2, 0x0a, 0x8d, 0x02, 0xea, 0x2d, - 0xd5, 0x00, 0xb6, 0x61, 0xca, 0x0e, 0x03, 0x10, 0xaa, 0x65, 0xda, 0xc0, - 0x56, 0x96, 0xf5, 0xbd, 0x89, 0xff, 0xdf, 0x31, 0x57, 0xdf, 0x44, 0x53, - 0x90, 0x19, 0x06, 0x01, 0x11, 0x4c, 0x60, 0x41, 0x1d, 0x03, 0x2f, 0x31, - 0xbf, 0x7c, 0x3e, 0x99, 0x76, 0xb4, 0x57, 0x92, 0xde, 0x87, 0x85, 0xa3, - 0x6d, 0xd5, 0x12, 0x95, 0x03, 0x8c, 0x0c, 0x42, 0x08, 0x92, 0x0c, 0x1f, - 0x08, 0x41, 0xf8, 0xe2, 0x37, 0xaa, 0xff, 0xe5, 0x43, 0x8c, 0x97, 0x16, - 0xfd, 0x85, 0xb1, 0x62, 0xb5, 0x0a, 0x3a, 0x36, 0x02, 0xb8, 0x60, 0x89, - 0x70, 0x1c, 0x12, 0x13, 0x2a, 0x91, 0x50, 0xf3, 0xcd, 0x34, 0xde, 0x42, - 0xd9, 0x73, 0xb6, 0xdb, 0x3a, 0xba, 0x90, 0x60, 0x9c, 0x82, 0xda, 0x72, - 0x36, 0x18, 0x15, 0x88, 0x69, 0xc4, 0x94, 0xfb, 0xe6, 0x39, 0x83, 0xe5, - 0xe7, 0x36, 0x4e, 0xff, 0x3a, 0xbf, 0x6e, 0xe7, 0xca, 0x8e, 0x23, 0xe2, - 0xe5, 0x4a, 0xb9, 0x41, 0x4d, 0x99, 0x2c, 0x0e, 0xd8, 0x5d, 0x47, 0x4d, - 0xb9, 0x30, 0x6a, 0x0a, 0x46, 0xea, 0x66, 0xd9, 0x03, 0xdf, 0xd6, 0x2f, - 0xa4, 0x2d, 0x1e, 0x7b, 0x93, 0xdf, 0x9e, 0x42, 0xc2, 0x82, 0xc1, 0xc3, - 0x61, 0xb0, 0x31, 0x08, 0xff, 0xc0, 0xd5, 0x80, 0x35, 0x47, 0x42, 0x4f, - 0x99, 0x80, 0xe1, 0xf3, 0x00, 0x67, 0xdb, 0x6e, 0xa9, 0xbe, 0x9d, 0x96, - 0x6e, 0x29, 0xc4, 0x63, 0x72, 0xd0, 0xef, 0x01, 0x85, 0x65, 0xe0, 0x05, - 0xe1, 0x6b, 0x62, 0x90, 0x37, 0x8d, 0x0e, 0xbe, 0xa3, 0x0b, 0x7f, 0x9e, - 0xe7, 0xad, 0x35, 0x79, 0xca, 0x0c, 0x34, 0x1d, 0x7b, 0xec, 0x88, 0x93, - 0x27, 0xd6, 0x5f, 0x88, 0xa7, 0x91, 0x40, 0x71, 0x83, 0xa0, 0xf0, 0x3f, - 0xe2, 0xb3, 0xea, 0x0e, 0x49, 0x01, 0x8a, 0xa4, 0x91, 0xa4, 0xcd, 0xf3, - 0x6a, 0xd6, 0x4b, 0x7e, 0xce, 0x67, 0xb7, 0x73, 0x57, 0x05, 0x77, 0xc2, - 0xc0, 0x90, 0x5d, 0x81, 0xfa, 0x46, 0x07, 0xea, 0x24, 0x1c, 0xfa, 0x55, - 0x19, 0xaa, 0x56, 0xb2, 0x55, 0xea, 0x8f, 0x00, 0x93, 0xbf, 0xb1, 0x03, - 0xb0, 0xb5, 0xb1, 0xa8, 0x96, 0x23, 0xb2, 0x20, 0x36, 0x25, 0x45, 0x59, - 0x7b, 0xbb, 0xd6, 0x4b, 0x6c, 0x97, 0x0b, 0x6e, 0xcf, 0x59, 0x99, 0xe0, - 0x7c, 0xbf, 0xfe, 0xc6, 0xfe, 0x53, 0x36, 0xed, 0x63, 0xbe, 0x2b, 0xc5, - 0x02, 0x24, 0xec, 0x0e, 0xe5, 0x1b, 0x82, 0xb8, 0xc1, 0x8d, 0xf7, 0xbe, - 0x5e, 0xcc, 0xf8, 0x79, 0xc5, 0x7a, 0xa3, 0xcb, 0xdb, 0xfb, 0x6d, 0xa5, - 0xb3, 0x88, 0xd0, 0x69, 0x58, 0x74, 0x16, 0x8a, 0x63, 0x1d, 0xdf, 0xb4, - 0xcd, 0xbf, 0x51, 0x81, 0xfb, 0x1b, 0xad, 0xc2, 0xd9, 0xd5, 0x84, 0x4c, - 0x51, 0x88, 0xc1, 0x85, 0x65, 0xe6, 0x76, 0x38, 0xc2, 0x66, 0xde, 0xf8, - 0xb7, 0x7d, 0xad, 0x29, 0x92, 0xd5, 0xd1, 0xe5, 0x59, 0x1f, 0xfb, 0xa0, - 0xf9, 0x5f, 0xfd, 0x89, 0x12, 0x09, 0x50, 0xbf, 0x2f, 0x19, 0x6b, 0x97, - 0xf3, 0x0b, 0x57, 0xe8, 0x83, 0x22, 0xd2, 0x4c, 0x2b, 0x02, 0x78, 0x2c, - 0x14, 0x0f, 0x00, 0xe6, 0xb6, 0x5c, 0xd2, 0x86, 0x2f, 0xdb, 0xd5, 0xbc, - 0x57, 0xdb, 0xab, 0xce, 0xb7, 0x7e, 0x1c, 0x62, 0xe5, 0x42, 0xb9, 0x56, - 0x24, 0x30, 0x3c, 0x1d, 0xe0, 0x39, 0x2e, 0xda, 0xb0, 0x38, 0x14, 0xd3, - 0xb1, 0xad, 0x88, 0xe7, 0xe0, 0x7a, 0x39, 0x6d, 0x48, 0x75, 0x80, 0xf9, - 0x70, 0x03, 0xad, 0x92, 0x10, 0x10, 0x16, 0x36, 0xa8, 0x96, 0x21, 0x54, - 0x9a, 0xd6, 0x25, 0xb0, 0x3f, 0xdf, 0xcf, 0x75, 0x4f, 0x6e, 0xc9, 0xd8, - 0x8e, 0x61, 0x52, 0x01, 0xb8, 0x31, 0x17, 0x03, 0x40, 0xdc, 0xdd, 0xf3, - 0x25, 0x8c, 0xb0, 0x04, 0x3c, 0x1e, 0xe3, 0x17, 0xeb, 0xf7, 0xfe, 0xc1, - 0xba, 0x85, 0xb0, 0x3b, 0x06, 0x23, 0x18, 0x00, 0x6c, 0xdf, 0xa5, 0xf6, - 0xe3, 0x3e, 0x98, 0xce, 0xf8, 0x3c, 0xd9, 0xca, 0x9b, 0x22, 0x30, 0x36, - 0xc9, 0x5e, 0x62, 0x3b, 0xaa, 0x30, 0x18, 0xe8, 0xc9, 0xb2, 0xfb, 0x9f, - 0x57, 0x55, 0x02, 0xb3, 0xde, 0x51, 0xe6, 0x04, 0x0e, 0x6f, 0x7f, 0xe5, - 0x83, 0xc6, 0x73, 0x17, 0xcd, 0xca, 0x37, 0xd0, 0xf4, 0x04, 0xda, 0x58, - 0x68, 0x2c, 0xb4, 0xa9, 0xed, 0xb0, 0x84, 0x90, 0x7d, 0xa1, 0x05, 0xac, - 0xdc, 0xbf, 0x4d, 0xe5, 0xff, 0x7f, 0xb2, 0x77, 0x64, 0xcb, 0xce, 0x68, - 0x2d, 0xc2, 0xd3, 0x45, 0xec, 0x5e, 0x28, 0xcb, 0x68, 0xba, 0xf2, 0x13, - 0xd7, 0xd3, 0x81, 0xa6, 0xcb, 0x92, 0xe3, 0x54, 0xb5, 0x6d, 0x56, 0x5b, - 0xe2, 0xcd, 0xdd, 0x43, 0x3a, 0x0e, 0x2b, 0x0f, 0x11, 0x19, 0x0c, 0x00, - 0x1c, 0x07, 0x47, 0x82, 0x5a, 0xbd, 0x4d, 0xf1, 0xc9, 0x70, 0x78, 0xa6, - 0x6a, 0xdc, 0xdc, 0x88, 0xe4, 0x50, 0x09, 0x0b, 0x85, 0x93, 0xdc, 0x42, - 0x66, 0x61, 0x94, 0xc7, 0xa9, 0x12, 0x83, 0x16, 0xab, 0xb9, 0xec, 0x6f, - 0x8c, 0x36, 0xa2, 0xc1, 0x12, 0xd8, 0x8d, 0xe2, 0x42, 0xf2, 0xf6, 0xcb, - 0x9a, 0xf3, 0x09, 0x98, 0xd6, 0x4b, 0xdb, 0xe0, 0xe1, 0x86, 0xb9, 0xd9, - 0x3a, 0xbf, 0xff, 0x74, 0xa9, 0xac, 0x30, 0x2f, 0xa0, 0xdf, 0x1f, 0x24, - 0xe8, 0xf0, 0x0f, 0x26, 0x1c, 0xab, 0xdb, 0x14, 0x56, 0xc3, 0xc9, 0xfd, - 0xad, 0xf3, 0xfc, 0x2a, 0x52, 0xa7, 0x17, 0xd5, 0x20, 0xc4, 0x49, 0x97, - 0x76, 0x26, 0x0f, 0xdb, 0x53, 0x1b, 0x66, 0x52, 0xd5, 0xca, 0xc5, 0x07, - 0x5c, 0xa0, 0x97, 0x13, 0x16, 0xdc, 0xba, 0xcf, 0xb7, 0xfc, 0xdd, 0x51, - 0x04, 0x55, 0x25, 0x96, 0xc0, 0xf6, 0x74, 0x1c, 0x64, 0xd0, 0x30, 0xd9, - 0x5e, 0x7c, 0x08, 0xe4, 0x83, 0x0a, 0xbc, 0x07, 0x38, 0x31, 0x32, 0xae, - 0x88, 0x49, 0xcb, 0x35, 0x40, 0x7c, 0x3d, 0xe4, 0x2e, 0x8a, 0x40, 0xc8, - 0x29, 0xcb, 0x57, 0xec, 0xd5, 0x0a, 0x71, 0x9e, 0xc2, 0xb2, 0xd0, 0xf3, - 0x85, 0x80, 0x96, 0x17, 0x23, 0x7a, 0xc9, 0x73, 0x4d, 0xc2, 0xbd, 0x63, - 0x8a, 0x78, 0x6b, 0x88, 0xc2, 0x85, 0x1b, 0x10, 0xab, 0x63, 0xc0, 0x66, - 0xd3, 0x27, 0x61, 0x8a, 0x94, 0x78, 0x3d, 0x6c, 0xb9, 0x8f, 0xf2, 0xa5, - 0xcf, 0x75, 0x7d, 0x47, 0x3e, 0x0c, 0x13, 0x0e, 0xc0, 0x30, 0x21, 0x8e, - 0xf0, 0x78, 0xd8, 0x90, 0x5f, 0x76, 0x96, 0xec, 0xdf, 0x2b, 0x6d, 0x76, - 0xdb, 0x62, 0xaf, 0xca, 0x68, 0x80, 0x88, 0x20, 0xfd, 0x27, 0xc0, 0x30, - 0x7a, 0x0a, 0x7b, 0x63, 0x02, 0x00, 0x7b, 0xc9, 0xdd, 0x47, 0x37, 0x92, - 0x07, 0x2a, 0x40, 0x40, 0x63, 0x6c, 0x76, 0xde, 0xea, 0x49, 0x0b, 0x73, - 0x9f, 0x55, 0x89, 0x23, 0x19, 0x36, 0x46, 0x27, 0xb3, 0xd3, 0xbf, 0x11, - 0x74, 0x88, 0x96, 0x35, 0x64, 0x40, 0x90, 0xae, 0x4c, 0x80, 0xf8, 0x21, - 0xf0, 0x03, 0xd5, 0x09, 0x13, 0x92, 0x6a, 0xaf, 0xb7, 0xff, 0xad, 0x6e, - 0xd4, 0x73, 0xd0, 0x36, 0x51, 0xc2, 0xd0, 0xb4, 0x29, 0x35, 0x85, 0xa5, - 0x5a, 0x36, 0x47, 0xa1, 0x21, 0x30, 0x0e, 0x1e, 0x0f, 0x63, 0x29, 0x44, - 0xb9, 0xf5, 0x78, 0x97, 0xdf, 0x1c, 0x71, 0xbd, 0x9a, 0xdb, 0x32, 0x45, - 0x3f, 0xed, 0xd2, 0xcc, 0xcc, 0x52, 0x2c, 0x5d, 0x21, 0x7a, 0x9f, 0x24, - 0xc1, 0xb7, 0xd3, 0xb5, 0x3f, 0xbd, 0x46, 0xb7, 0x25, 0x96, 0x06, 0xb4, - 0x12, 0x5d, 0xb2, 0xb3, 0xb5, 0xb1, 0x69, 0x67, 0x96, 0x53, 0x27, 0x77, - 0xa0, 0x8d, 0xc2, 0x22, 0x6a, 0x32, 0x25, 0xcf, 0x4e, 0x4e, 0x0f, 0xcb, - 0x0d, 0xe4, 0xc9, 0x29, 0x60, 0x30, 0x9d, 0x54, 0x56, 0xc2, 0xa5, 0x32, - 0x49, 0xce, 0xf6, 0xce, 0xa2, 0xe8, 0x2d, 0x3e, 0xf8, 0x70, 0x3f, 0xcf, - 0x2f, 0x41, 0xc5, 0xfe, 0x57, 0x56, 0x40, 0x38, 0xbe, 0xa0, 0xfa, 0xdf, - 0xfe, 0x8e, 0x7d, 0xf0, 0x02, 0xec, 0xd2, 0xbf, 0x46, 0x58, 0x1d, 0x81, - 0x91, 0xc5, 0x6c, 0x7b, 0xe6, 0x09, 0x26, 0xb1, 0x3d, 0x7d, 0x65, 0x0d, - 0x4b, 0x31, 0x40, 0xac, 0xbb, 0x7f, 0xe0, 0xed, 0xa4, 0x96, 0x03, 0x15, - 0x32, 0x5d, 0x4a, 0xea, 0x2a, 0xaf, 0xd6, 0xe7, 0xc2, 0x98, 0x67, 0xd8, - 0x0d, 0xcd, 0x4a, 0xbc, 0x98, 0x3f, 0x65, 0x3b, 0x38, 0xa1, 0x6d, 0xf0, - 0x7e, 0x59, 0x7d, 0x43, 0x75, 0xbc, 0x05, 0x01, 0x28, 0xc8, 0x93, 0x41, - 0x97, 0x10, 0x93, 0xe5, 0x9f, 0x06, 0x5f, 0xec, 0x55, 0x08, 0xda, 0xf3, - 0x2d, 0x76, 0x5b, 0x04, 0x45, 0x07, 0xb5, 0x2f, 0xb4, 0x0c, 0x8b, 0x5a, - 0xe7, 0x0b, 0x31, 0x45, 0x81, 0x92, 0xe2, 0x61, 0x9b, 0x17, 0x66, 0xa7, - 0xdc, 0x47, 0x7e, 0x59, 0x72, 0x2d, 0x2e, 0xf6, 0x55, 0xe8, 0x72, 0x46, - 0x8c, 0x6f, 0x2d, 0x67, 0x7d, 0xf1, 0xcc, 0xdc, 0x50, 0xb1, 0x5e, 0x77, - 0xdc, 0x94, 0x18, 0x4e, 0x92, 0xa0, 0x61, 0xba, 0x71, 0x11, 0x4e, 0xc2, - 0xaa, 0x6d, 0x0b, 0xf3, 0x1f, 0x62, 0xff, 0x77, 0xbf, 0x5d, 0x7e, 0x8b, - 0x8d, 0x74, 0x16, 0xb7, 0xa8, 0x9f, 0xd7, 0xcf, 0xde, 0x5a, 0xa7, 0xaa, - 0x51, 0xf2, 0x72, 0xce, 0x9e, 0xbd, 0xdf, 0x7f, 0x23, 0x70, 0xa8, 0xae, - 0x4d, 0xf0, 0x8b, 0x9b, 0x50, 0x3f, 0x97, 0x95, 0x64, 0x51, 0x2a, 0x25, - 0x3d, 0x50, 0x6a, 0x48, 0x43, 0x73, 0x56, 0xec, 0x0d, 0x0a, 0x60, 0xaf, - 0xd2, 0xb6, 0x25, 0xcf, 0x96, 0x69, 0x5e, 0x45, 0xbb, 0x22, 0xfc, 0x22, - 0x94, 0xc3, 0x65, 0x17, 0x9d, 0xbd, 0x84, 0x8a, 0x79, 0x29, 0xfe, 0xb6, - 0x18, 0x81, 0x46, 0x0d, 0x5a, 0x04, 0x26, 0x20, 0xe5, 0xaa, 0xde, 0xa5, - 0x6d, 0x98, 0xd7, 0xa7, 0x20, 0x32, 0x2f, 0x45, 0xe8, 0x6c, 0xa7, 0x98, - 0x0c, 0x27, 0x0e, 0x00, 0xc1, 0x08, 0x4b, 0x56, 0x3f, 0x00, 0xf1, 0x27, - 0xea, 0xdb, 0xbb, 0xa9, 0xda, 0x03, 0x7b, 0x28, 0xdb, 0xb1, 0x5e, 0x45, - 0x83, 0x85, 0x05, 0xa1, 0x60, 0x30, 0x81, 0x82, 0x19, 0x78, 0x22, 0x84, - 0x36, 0x58, 0xff, 0x71, 0xb2, 0xe6, 0xea, 0xac, 0xca, 0xb4, 0x2c, 0x5a, - 0xdd, 0x80, 0xaf, 0xda, 0xa4, 0x4c, 0x4c, 0x46, 0x05, 0x18, 0x1c, 0x05, - 0x00, 0xf9, 0x52, 0xa1, 0xe3, 0x1f, 0x4e, 0x3f, 0x6e, 0xfb, 0x44, 0xb4, - 0xab, 0x7b, 0xdc, 0x02, 0xbe, 0xf5, 0xd2, 0xb6, 0xd4, 0x40, 0xeb, 0x0b, - 0x33, 0xc0, 0xc2, 0xbe, 0xde, 0xd9, 0x10, 0x18, 0x69, 0x48, 0x9b, 0x08, - 0x62, 0x48, 0x07, 0x97, 0x01, 0xc6, 0x23, 0x23, 0xff, 0xdc, 0xcb, 0xfc, - 0xf6, 0x49, 0x8a, 0x77, 0x76, 0xf6, 0xc2, 0xc8, 0x22, 0xe2, 0x89, 0x4b, - 0x41, 0xc6, 0x21, 0x30, 0x92, 0x98, 0x49, 0xc0, 0xfc, 0xb9, 0x96, 0x95, - 0xb5, 0xdb, 0x14, 0xfa, 0xf7, 0x9a, 0xb5, 0xe5, 0x0d, 0xd7, 0x70, 0x39, - 0x00, 0x3c, 0x43, 0x6c, 0x20, 0x89, 0x7f, 0x2f, 0x6e, 0xd9, 0xe5, 0x20, - 0x61, 0xa4, 0x73, 0xd8, 0x88, 0x11, 0xd6, 0x52, 0x2d, 0x09, 0xc0, 0xc0, - 0x18, 0x3d, 0x68, 0x0d, 0x25, 0x1d, 0x03, 0x21, 0x8c, 0xd5, 0x78, 0x81, - 0x4f, 0xac, 0x92, 0xac, 0x1b, 0x16, 0x03, 0x05, 0x77, 0x2f, 0x6b, 0xdf, - 0x0c, 0xa6, 0x16, 0x32, 0xf3, 0xbb, 0x51, 0x40, 0xa4, 0xc9, 0x72, 0xad, - 0xd0, 0x51, 0xe0, 0x96, 0xa7, 0x26, 0x03, 0x0e, 0x28, 0xfa, 0xe7, 0x17, - 0x52, 0x1f, 0xc6, 0x6f, 0xe0, 0x2d, 0x85, 0xc2, 0x38, 0x1f, 0x83, 0xa0, - 0x0d, 0x49, 0xa9, 0xcb, 0xc0, 0xd0, 0xf1, 0x81, 0xf7, 0xf5, 0xbf, 0x2f, - 0xba, 0xaf, 0x59, 0xfd, 0xe4, 0xf7, 0xb0, 0x6f, 0xb9, 0xbe, 0x1b, 0xe8, - 0x2b, 0x8b, 0x41, 0x8e, 0x8b, 0x13, 0x82, 0x95, 0x30, 0x8c, 0x91, 0x50, - 0x87, 0xaa, 0x77, 0xcd, 0xea, 0x65, 0x0a, 0x16, 0xda, 0x20, 0xce, 0xdb, - 0xc0, 0xdb, 0x3b, 0xaa, 0x01, 0x6c, 0x9a, 0x44, 0xa9, 0xa0, 0xc9, 0x53, - 0x14, 0xdf, 0xc1, 0x81, 0x34, 0x42, 0x9e, 0xe0, 0x32, 0x8b, 0x28, 0x8a, - 0x19, 0xcb, 0xd0, 0xc1, 0xe6, 0x9a, 0x1f, 0xf8, 0x49, 0x4c, 0x98, 0xbd, - 0x37, 0xe7, 0xd8, 0x67, 0x25, 0x86, 0xe2, 0xc8, 0xac, 0x0e, 0x44, 0x41, - 0x68, 0x61, 0x05, 0x08, 0x29, 0x4b, 0x84, 0xa6, 0x2f, 0xb7, 0xfd, 0xd8, - 0xa4, 0xa9, 0x15, 0x52, 0xba, 0xd2, 0x08, 0xa1, 0xc0, 0x5b, 0x7d, 0x9d, - 0x33, 0x53, 0x0f, 0x20, 0x1a, 0x59, 0x8d, 0x81, 0xc9, 0x6c, 0xac, 0x41, - 0xdd, 0x2d, 0x88, 0xb3, 0x3f, 0x7d, 0x79, 0xfb, 0x43, 0xd1, 0x16, 0x82, - 0x41, 0x4f, 0x88, 0xe5, 0xc1, 0xff, 0x8b, 0xaa, 0x76, 0xb5, 0x5e, 0xe0, - 0x74, 0x39, 0xf5, 0xfd, 0xd4, 0x2b, 0x66, 0x8a, 0x8f, 0x17, 0x01, 0xb0, - 0x0f, 0x4c, 0x0d, 0xd2, 0xf2, 0xa2, 0xe2, 0xda, 0x58, 0xaa, 0xf0, 0xae, - 0xf2, 0xae, 0x1b, 0x28, 0xe8, 0x24, 0x86, 0xf1, 0xd3, 0x40, 0xc0, 0x88, - 0xac, 0x3a, 0x49, 0xff, 0x27, 0x6c, 0x18, 0x6f, 0xbe, 0x07, 0x25, 0x10, - 0x7f, 0x41, 0x83, 0x90, 0xf7, 0x54, 0x28, 0xe8, 0x08, 0x2b, 0x5a, 0xe8, - 0x6e, 0xa0, 0x58, 0xad, 0x85, 0x4c, 0x2c, 0xeb, 0x7b, 0xc0, 0x64, 0x7c, - 0xa8, 0x79, 0xc9, 0x16, 0x38, 0x0c, 0xe5, 0x6a, 0x87, 0x40, 0xab, 0x10, - 0xf9, 0xef, 0x6b, 0x3e, 0x2f, 0x4f, 0xad, 0x29, 0xb4, 0x71, 0x9c, 0xfd, - 0xec, 0xf8, 0x38, 0xc0, 0x51, 0x45, 0xda, 0x8c, 0x3c, 0x18, 0xde, 0xca, - 0xec, 0x01, 0xe2, 0x47, 0xea, 0x7d, 0xdf, 0xa9, 0xb2, 0xb6, 0xcd, 0xd9, - 0xe5, 0xe8, 0x83, 0xf5, 0xa7, 0xc3, 0x40, 0x4a, 0xd5, 0x77, 0x9f, 0x58, - 0x2d, 0xf4, 0xc3, 0x67, 0x7c, 0xdb, 0x4a, 0xdb, 0x9d, 0xcf, 0x7b, 0x2c, - 0x03, 0x33, 0xd3, 0x96, 0xd0, 0x28, 0x58, 0xa7, 0x4a, 0xb0, 0x44, 0x52, - 0x5a, 0x58, 0x59, 0xa0, 0xc4, 0x50, 0x10, 0x07, 0x4a, 0x82, 0x00, 0x95, - 0x14, 0xfe, 0x29, 0x4f, 0xb8, 0xad, 0x46, 0x7e, 0x37, 0xe5, 0xfd, 0x27, - 0x3d, 0x60, 0xdf, 0x30, 0x39, 0x06, 0x21, 0x16, 0x81, 0xe6, 0x47, 0x80, - 0xdd, 0xd2, 0xe5, 0x79, 0x38, 0x38, 0xac, 0x51, 0xcf, 0x5b, 0x53, 0xf9, - 0x11, 0x79, 0x9d, 0x2c, 0x1c, 0x66, 0xf2, 0x83, 0x10, 0x07, 0xf0, 0x86, - 0x25, 0xab, 0xd6, 0x9b, 0x63, 0x14, 0xa6, 0x2e, 0x8d, 0xcf, 0x34, 0xa8, - 0x0a, 0xef, 0xb9, 0x65, 0x9d, 0xc2, 0xac, 0xc5, 0x83, 0xdc, 0x02, 0x26, + 0x00, 0x00, 0x01, 0xb0, 0x01, 0x00, 0x00, 0x01, 0xb5, 0x89, 0x13, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0xc4, 0x8d, 0x88, 0x00, + 0xcd, 0x0a, 0x04, 0x1e, 0x14, 0x43, 0x00, 0x00, 0x01, 0xb2, 0x4c, 0x61, + 0x76, 0x63, 0x35, 0x34, 0x2e, 0x36, 0x32, 0x2e, 0x31, 0x30, 0x30, 0x00, + 0x00, 0x01, 0xb3, 0x00, 0x10, 0x07, 0x00, 0x00, 0x01, 0xb6, 0x10, 0x60, + 0x85, 0x85, 0x41, 0x08, 0x78, 0xab, 0x44, 0x81, 0x29, 0x06, 0xd1, 0xd2, + 0x4d, 0xe9, 0x2d, 0x55, 0xe0, 0x95, 0x36, 0x42, 0x10, 0x71, 0xfc, 0xa0, + 0x4f, 0x8b, 0x9a, 0x0a, 0xd8, 0x84, 0xca, 0x81, 0x18, 0x48, 0x80, 0xf0, + 0xd0, 0x0b, 0x97, 0x12, 0x83, 0x01, 0x47, 0x13, 0x97, 0x59, 0xfe, 0x22, + 0x5b, 0x9d, 0x88, 0xfb, 0x38, 0x46, 0x2e, 0x29, 0x11, 0x39, 0xb3, 0x7a, + 0x08, 0x02, 0x5f, 0x16, 0xf6, 0x52, 0x8d, 0x3e, 0x33, 0x2f, 0x12, 0x04, + 0xb5, 0x5d, 0xa0, 0x88, 0xcd, 0xe2, 0xeb, 0x7a, 0xd9, 0xc0, 0x61, 0x30, + 0xbd, 0x4e, 0xce, 0x8a, 0xb8, 0xe6, 0xbf, 0x14, 0x43, 0xed, 0x8d, 0xd8, + 0x4d, 0x74, 0x47, 0x69, 0x5b, 0x23, 0x9c, 0xb5, 0xad, 0x82, 0x06, 0xfb, + 0xfe, 0x9d, 0xec, 0x5d, 0x70, 0x49, 0x0b, 0xca, 0x95, 0x5f, 0xb3, 0xec, + 0x0e, 0x6c, 0x0c, 0xdc, 0x68, 0x7b, 0xfc, 0x0f, 0xad, 0xbe, 0xcd, 0xd2, + 0x58, 0xbf, 0x38, 0x4e, 0x30, 0x2e, 0x49, 0x7c, 0x95, 0x52, 0xb9, 0x3a, + 0xc2, 0xfa, 0x69, 0x46, 0xf1, 0x14, 0x0e, 0x48, 0xd3, 0xa5, 0xa0, 0xc2, + 0x6f, 0x29, 0x19, 0x61, 0x21, 0xaf, 0x0e, 0x32, 0x79, 0x06, 0x49, 0x06, + 0x10, 0xf1, 0xb1, 0xef, 0x51, 0xf3, 0xa7, 0x14, 0x0f, 0xf2, 0x90, 0xaa, + 0x3d, 0xde, 0xcb, 0x20, 0x71, 0xd1, 0x35, 0x30, 0x86, 0xc3, 0x21, 0x7f, + 0xff, 0x70, 0xd2, 0xf4, 0x96, 0xac, 0xb1, 0x19, 0xff, 0x5f, 0xfe, 0xf3, + 0x0a, 0xc3, 0x94, 0x0b, 0x10, 0xe6, 0xe7, 0x55, 0x54, 0x36, 0x6d, 0x2a, + 0x35, 0x2d, 0x27, 0xa9, 0xd9, 0xb3, 0x7c, 0x37, 0x71, 0x85, 0x96, 0x2c, + 0x2e, 0xdc, 0x6a, 0xd9, 0x9c, 0x51, 0xfe, 0x4a, 0x8a, 0xd2, 0x90, 0x13, + 0x02, 0x19, 0x72, 0x86, 0x33, 0xf9, 0x11, 0x0c, 0x77, 0x2f, 0x57, 0x79, + 0xc6, 0x9b, 0x2b, 0x8a, 0x79, 0x36, 0xf0, 0xa9, 0x15, 0xa4, 0xae, 0x11, + 0x0e, 0x73, 0xe5, 0xca, 0x35, 0x74, 0x03, 0x2a, 0x41, 0x9b, 0xab, 0x53, + 0xe5, 0x9e, 0x11, 0x8b, 0x69, 0x7b, 0x45, 0x9a, 0xa2, 0x94, 0xf2, 0x14, + 0x50, 0x5b, 0x0a, 0x1b, 0x4a, 0x9e, 0xdd, 0x6b, 0x53, 0x52, 0xcf, 0x23, + 0x57, 0x37, 0xca, 0x0d, 0x2c, 0x0b, 0x50, 0xc7, 0x60, 0xe3, 0xf6, 0x44, + 0x1a, 0x1e, 0x0d, 0x4a, 0x79, 0xa9, 0x8c, 0x66, 0xed, 0x2a, 0x6f, 0x23, + 0x73, 0x39, 0x6d, 0x5e, 0x77, 0xa1, 0xa6, 0x1f, 0xdb, 0xe8, 0x0c, 0x97, + 0x8b, 0x38, 0xd6, 0xfd, 0x5e, 0x16, 0x7a, 0x67, 0x77, 0xb7, 0xab, 0x0a, + 0x46, 0xfb, 0xf1, 0x05, 0x62, 0xcd, 0xc2, 0xec, 0x11, 0x14, 0xa8, 0xa2, + 0x07, 0x39, 0xdb, 0x03, 0x96, 0x74, 0xa8, 0x18, 0x4e, 0x3f, 0x12, 0x53, + 0xff, 0xff, 0x9e, 0xff, 0xc1, 0x59, 0x9a, 0x1e, 0x68, 0x89, 0xbf, 0x5d, + 0x7e, 0x08, 0xba, 0xa4, 0x3a, 0xc0, 0x62, 0x0a, 0xd6, 0x94, 0xb5, 0x3d, + 0x2d, 0x62, 0x4b, 0x3f, 0x57, 0xed, 0x05, 0x7f, 0xfe, 0x1e, 0x29, 0x0d, + 0x00, 0xa7, 0x4c, 0xe6, 0x16, 0xd7, 0x96, 0x5a, 0x6f, 0xae, 0x35, 0xcc, + 0xcf, 0x4b, 0xb9, 0x1a, 0x5b, 0xb5, 0x44, 0x0e, 0xcb, 0x20, 0x71, 0x9c, + 0x50, 0xa4, 0x18, 0x84, 0xaa, 0x0b, 0xea, 0xb5, 0xa3, 0x3e, 0x14, 0x82, + 0xdd, 0x14, 0x8a, 0x38, 0xb0, 0x7b, 0xf5, 0x11, 0x42, 0x91, 0xbd, 0xec, + 0x96, 0x9e, 0x68, 0xba, 0xa6, 0xdb, 0xb4, 0xd0, 0xd8, 0xa6, 0x86, 0xea, + 0x01, 0xf3, 0x7f, 0xfb, 0xd8, 0xf9, 0x68, 0xe5, 0x51, 0xd5, 0x3d, 0xe6, + 0x62, 0xeb, 0x95, 0x71, 0xd5, 0x69, 0x6a, 0x8d, 0x8b, 0x29, 0x47, 0x10, + 0xd8, 0x0c, 0x0b, 0xab, 0x68, 0x71, 0xf6, 0xa7, 0x17, 0x9d, 0xa8, 0xca, + 0xed, 0xe2, 0xcb, 0xbd, 0x3a, 0xb5, 0x86, 0x94, 0x48, 0x50, 0x73, 0xcf, + 0xb6, 0x70, 0x4b, 0xfe, 0xb4, 0xab, 0x6b, 0x19, 0x9a, 0xda, 0x89, 0x3d, + 0x9b, 0xd9, 0x2d, 0xb7, 0x8b, 0xd0, 0xd0, 0xf9, 0xa6, 0x81, 0xba, 0x59, + 0x39, 0x33, 0xb0, 0xa8, 0xb2, 0x95, 0xd9, 0x10, 0x2e, 0x0c, 0x13, 0x48, + 0xee, 0x96, 0x0e, 0x2d, 0xcb, 0x71, 0x72, 0xb8, 0xba, 0xf5, 0x01, 0xea, + 0xc6, 0x7a, 0xdc, 0xf7, 0x91, 0xe8, 0xc0, 0x4e, 0x92, 0x75, 0xc2, 0xf9, + 0x42, 0xc6, 0xd8, 0xf7, 0xea, 0xc1, 0x13, 0x14, 0xdc, 0x94, 0xb6, 0x4d, + 0x99, 0x9c, 0xbc, 0x2c, 0x5d, 0x71, 0x38, 0xc7, 0xe9, 0x44, 0x05, 0x0d, + 0x30, 0x1d, 0xad, 0x3a, 0x13, 0x17, 0x65, 0x36, 0xf0, 0xaf, 0x67, 0xed, + 0x83, 0x6e, 0x2c, 0x50, 0x7d, 0x3c, 0x1f, 0x2a, 0x03, 0x6d, 0x0e, 0x6e, + 0xe2, 0xea, 0x79, 0x50, 0xea, 0x38, 0xe1, 0x6f, 0x7f, 0xde, 0x9c, 0x32, + 0x99, 0xb0, 0x9d, 0xb1, 0x73, 0x03, 0xc2, 0xf0, 0xfe, 0x07, 0xaa, 0x64, + 0xf6, 0x29, 0xd4, 0x59, 0x10, 0xd9, 0x20, 0x8b, 0xaa, 0x6b, 0xc2, 0xfb, + 0x4d, 0x07, 0x85, 0x9d, 0xee, 0x76, 0xd3, 0x53, 0xb5, 0x15, 0x78, 0x97, + 0xd7, 0xeb, 0x20, 0xe8, 0x2e, 0x53, 0xcb, 0xc8, 0x74, 0x62, 0xea, 0x9b, + 0x4e, 0x53, 0xe5, 0x9b, 0xaa, 0x19, 0x2d, 0xcd, 0xf4, 0x2d, 0x6b, 0x6a, + 0xe6, 0xf8, 0xa6, 0x5b, 0x41, 0x6e, 0x36, 0xd6, 0xcb, 0x3f, 0xdf, 0x87, + 0x41, 0xd5, 0x43, 0xab, 0xd5, 0xb8, 0x1b, 0x29, 0x3c, 0x7d, 0x2f, 0xef, + 0x59, 0xbe, 0xe7, 0x4b, 0x7f, 0xce, 0xac, 0x8a, 0xdd, 0x3c, 0x74, 0x42, + 0x2f, 0x64, 0x47, 0xf3, 0x3a, 0xad, 0x55, 0x85, 0x89, 0x59, 0x6b, 0x25, + 0x97, 0x30, 0xb3, 0xd5, 0x6a, 0x56, 0x0e, 0x05, 0x48, 0x24, 0x36, 0x79, + 0x34, 0x43, 0x30, 0xcc, 0x56, 0x9d, 0x6d, 0xbb, 0x33, 0x17, 0xb2, 0x73, + 0x90, 0x92, 0x43, 0xc2, 0xba, 0x47, 0x98, 0x9d, 0x67, 0x03, 0x47, 0xe2, + 0xb5, 0xad, 0xb3, 0xe5, 0xdb, 0x62, 0x37, 0xea, 0x6e, 0x45, 0x84, 0xc3, + 0x05, 0x2b, 0x09, 0xdd, 0x93, 0x38, 0xde, 0xf1, 0xb8, 0x81, 0x15, 0xe8, + 0x9c, 0xa0, 0x22, 0xa3, 0xef, 0x50, 0xa8, 0x19, 0x10, 0xac, 0xad, 0x7d, + 0xce, 0x8a, 0x8f, 0x9f, 0x4a, 0x89, 0xd1, 0xb3, 0x2d, 0xb7, 0xdb, 0xda, + 0x48, 0x35, 0x32, 0xcb, 0x30, 0xf0, 0xec, 0x1a, 0x97, 0x8e, 0xd3, 0x09, + 0x1b, 0xf1, 0x22, 0x75, 0x5e, 0x37, 0xe1, 0x10, 0x73, 0x4b, 0x0a, 0xe5, + 0xb3, 0xc1, 0xc9, 0x10, 0x64, 0xc0, 0x64, 0xad, 0x52, 0xc6, 0x0b, 0xfb, + 0xef, 0xff, 0xd8, 0x5b, 0xf8, 0x36, 0x9b, 0x62, 0xf3, 0xf0, 0x44, 0x01, + 0x36, 0x1b, 0x05, 0xa4, 0x3e, 0xd8, 0x30, 0xc1, 0x4a, 0x0c, 0x39, 0x03, + 0x7f, 0x56, 0x3c, 0x56, 0x55, 0xbd, 0x05, 0x62, 0xca, 0x51, 0xea, 0xf0, + 0xa8, 0xe8, 0xcd, 0x26, 0x83, 0x37, 0x9b, 0x8a, 0xf1, 0xbb, 0xe4, 0x41, + 0xdf, 0xfd, 0x32, 0xc4, 0x7c, 0xb2, 0x07, 0x20, 0xc2, 0x65, 0xc4, 0xb1, + 0xdb, 0x71, 0xbc, 0x03, 0x4a, 0xb5, 0x29, 0x68, 0xdb, 0x73, 0xb7, 0x38, + 0x8a, 0x71, 0x40, 0x9a, 0xfe, 0x90, 0x14, 0x25, 0xe1, 0xea, 0xec, 0x4e, + 0xad, 0x85, 0xb1, 0xae, 0x0c, 0x94, 0xa9, 0x06, 0x1a, 0x94, 0xde, 0xb5, + 0x78, 0x1e, 0xff, 0x41, 0x85, 0x4d, 0xbc, 0x36, 0x2d, 0x6c, 0x2f, 0x30, + 0x0c, 0xc8, 0x8e, 0xc6, 0xcf, 0x0f, 0x44, 0x60, 0x30, 0x8a, 0xab, 0x4d, + 0x6e, 0xce, 0x9b, 0xe6, 0x88, 0x84, 0x62, 0xf6, 0x41, 0x46, 0xd0, 0xe1, + 0xb4, 0xfe, 0x67, 0x2f, 0x98, 0xca, 0xa7, 0x14, 0xcb, 0xaa, 0x78, 0x86, + 0x08, 0x80, 0x24, 0x39, 0x27, 0x08, 0x41, 0x05, 0x89, 0x59, 0xfc, 0xff, + 0xd6, 0xee, 0xee, 0x33, 0x7f, 0x78, 0x6e, 0x95, 0xa9, 0x3c, 0x33, 0xc5, + 0x37, 0x7a, 0xbe, 0xd1, 0x9b, 0xc6, 0x54, 0x9e, 0x72, 0xd1, 0x51, 0x69, + 0x0e, 0xbd, 0x28, 0x84, 0x10, 0xaf, 0x3b, 0x41, 0x8b, 0x07, 0x83, 0x28, + 0x08, 0x82, 0xc4, 0xd5, 0x31, 0x37, 0xbb, 0x37, 0x96, 0x6f, 0x22, 0xdd, + 0x5a, 0x23, 0x71, 0x92, 0xe4, 0xaa, 0x44, 0x81, 0x19, 0xaf, 0x49, 0x14, + 0x0e, 0x87, 0x92, 0xd4, 0x36, 0xc5, 0x5e, 0x71, 0x75, 0x58, 0xa1, 0xac, + 0x95, 0x65, 0xa7, 0x45, 0x3f, 0x11, 0x3a, 0xd6, 0xff, 0x31, 0xab, 0x9a, + 0xbf, 0x46, 0x47, 0x15, 0x61, 0x4f, 0x2d, 0x40, 0x0b, 0xf9, 0xb7, 0x0a, + 0x4f, 0x25, 0x6c, 0xe2, 0x94, 0x50, 0x17, 0xdb, 0x36, 0x74, 0x77, 0xa5, + 0xab, 0x01, 0x00, 0xa1, 0x11, 0xe3, 0x2a, 0x58, 0xe7, 0x60, 0x79, 0x6b, + 0x91, 0xa9, 0xb1, 0x47, 0xd9, 0xb0, 0xae, 0xf4, 0x65, 0xda, 0xb0, 0x30, + 0xd0, 0xc1, 0x77, 0xe7, 0x76, 0x72, 0x42, 0xde, 0x02, 0x3c, 0xec, 0xaf, + 0x63, 0x15, 0xd6, 0x7b, 0x76, 0x64, 0x0b, 0x55, 0xd5, 0xf7, 0x88, 0x05, + 0xe4, 0xae, 0x7f, 0xc5, 0x2c, 0x5c, 0x24, 0x5c, 0x50, 0x6f, 0x5b, 0x9e, + 0x37, 0x78, 0x13, 0x44, 0x6c, 0x56, 0xdf, 0xbd, 0xc5, 0x05, 0x85, 0x55, + 0x62, 0x61, 0xef, 0xd5, 0x28, 0xbb, 0x37, 0x2e, 0x59, 0x69, 0x47, 0x0d, + 0x9f, 0xa8, 0x24, 0xaa, 0xe4, 0x52, 0xa6, 0x5e, 0xc4, 0x04, 0x22, 0xd4, + 0xac, 0xe7, 0xf2, 0xdb, 0x17, 0xfd, 0xf1, 0x66, 0xdc, 0xea, 0xd3, 0xb9, + 0xc0, 0x71, 0x98, 0x46, 0x6a, 0x9e, 0x1f, 0x6f, 0xd1, 0xe6, 0xff, 0xca, + 0x51, 0x07, 0x14, 0x84, 0x32, 0xa5, 0xfb, 0x75, 0x57, 0x35, 0x7d, 0x63, + 0x64, 0xa8, 0x2f, 0x10, 0x57, 0x1c, 0x6e, 0x2b, 0xf7, 0xfc, 0x58, 0xa5, + 0xb6, 0x24, 0x91, 0x9c, 0x35, 0x40, 0x88, 0x64, 0x0c, 0x35, 0x54, 0x7b, + 0x26, 0x7f, 0x39, 0x24, 0x53, 0xe2, 0xb2, 0x83, 0x4f, 0x48, 0x71, 0x0f, + 0xb7, 0x23, 0xef, 0xfb, 0xf6, 0x36, 0x97, 0x4a, 0xa7, 0xf1, 0x4d, 0x24, + 0x8b, 0x2e, 0x0c, 0x12, 0xda, 0x56, 0xf5, 0x4e, 0xea, 0x9c, 0x8a, 0x8b, + 0x20, 0xe3, 0x8b, 0xad, 0xc5, 0xb9, 0x04, 0x55, 0x38, 0x09, 0x63, 0x6f, + 0xf7, 0xca, 0x73, 0x06, 0xc5, 0xa8, 0x91, 0xce, 0x71, 0x60, 0xcc, 0x18, + 0x2a, 0x1f, 0x88, 0xcd, 0xff, 0xea, 0xa7, 0xa1, 0x5f, 0xfc, 0x06, 0x27, + 0x44, 0x46, 0x2a, 0xf3, 0xe0, 0x49, 0x6c, 0x13, 0xcf, 0xe1, 0x11, 0x82, + 0xd2, 0xe2, 0x30, 0x39, 0xb5, 0x0c, 0x9d, 0x52, 0xa6, 0x2f, 0x2c, 0xa8, + 0xbb, 0xaa, 0x77, 0x1a, 0xc1, 0xb2, 0x8c, 0x06, 0x23, 0x45, 0xb9, 0xa8, + 0x91, 0xcb, 0x2c, 0xf7, 0x8b, 0x24, 0x9d, 0x06, 0x37, 0xf0, 0xd3, 0x01, + 0x82, 0x91, 0x59, 0x67, 0xa4, 0xcc, 0xfc, 0xcd, 0xb4, 0x45, 0x11, 0x25, + 0x46, 0x88, 0x2d, 0x31, 0x7d, 0x0a, 0xa2, 0x35, 0xb9, 0x6a, 0xeb, 0x40, + 0x26, 0x28, 0x34, 0xc7, 0xde, 0x49, 0x51, 0xc4, 0x5f, 0xee, 0x14, 0x53, + 0x88, 0x6a, 0xd1, 0x4a, 0xf6, 0x02, 0xa1, 0x75, 0xcd, 0x1e, 0xea, 0x24, + 0xf1, 0x42, 0xc4, 0xab, 0x1c, 0x36, 0xce, 0x6f, 0x5a, 0xa5, 0xab, 0xfb, + 0xb6, 0x48, 0x55, 0x6a, 0xcb, 0x2c, 0x22, 0xa1, 0x06, 0x1a, 0xf0, 0xbf, + 0x2e, 0x20, 0x40, 0x72, 0x7d, 0xea, 0xde, 0x8c, 0x46, 0x88, 0xb1, 0x6e, + 0xe1, 0x5f, 0xb9, 0x56, 0xea, 0x0d, 0x29, 0x80, 0xb5, 0x22, 0x91, 0x6c, + 0xbf, 0x36, 0xb0, 0x9b, 0x90, 0xe9, 0x40, 0xa3, 0xea, 0xb3, 0xed, 0x4f, + 0x54, 0x73, 0x85, 0x22, 0x61, 0xc0, 0xe2, 0xa6, 0x6e, 0x95, 0x41, 0xc8, + 0x89, 0xf0, 0xcc, 0x11, 0xf0, 0xfa, 0x25, 0x87, 0x61, 0xdb, 0xb7, 0xd1, + 0xb5, 0x7b, 0x65, 0xb0, 0x3d, 0xcd, 0xd5, 0x84, 0x01, 0x8f, 0xd4, 0x8a, + 0x84, 0xfb, 0x72, 0x6f, 0x96, 0xee, 0x8b, 0xc8, 0xa3, 0x31, 0x48, 0x22, + 0x28, 0xe4, 0x93, 0xb7, 0x70, 0xdd, 0x27, 0x9e, 0xf5, 0x3f, 0xe6, 0x20, + 0xdb, 0xc1, 0x98, 0x26, 0x8d, 0x13, 0x98, 0xab, 0x4a, 0xeb, 0xae, 0xf2, + 0xea, 0x15, 0x89, 0x05, 0x46, 0x93, 0xb6, 0x58, 0x93, 0xf5, 0x0d, 0x8a, + 0x21, 0x4b, 0xea, 0xea, 0x81, 0xba, 0x33, 0x83, 0x11, 0xea, 0x79, 0xa5, + 0x51, 0x14, 0x81, 0x5b, 0x0b, 0xa6, 0x6b, 0x2a, 0xc3, 0x51, 0x7f, 0xb6, + 0xad, 0x60, 0x88, 0xa4, 0x60, 0xe7, 0x08, 0x94, 0x2d, 0x51, 0xee, 0xce, + 0xe6, 0xe6, 0x95, 0x14, 0xf7, 0xbd, 0x0a, 0x55, 0xca, 0x9a, 0x98, 0xdc, + 0xfc, 0x0b, 0x6f, 0x12, 0xa8, 0xb5, 0xb9, 0xc9, 0xff, 0x7e, 0xb5, 0xc4, + 0x71, 0x42, 0x0a, 0x1a, 0x99, 0xa5, 0x5f, 0x9c, 0xd5, 0x28, 0xef, 0x41, + 0x1e, 0xd2, 0x33, 0x58, 0x3c, 0xc0, 0x36, 0xcb, 0x2b, 0xda, 0xa3, 0x16, + 0x43, 0x62, 0x3b, 0xf9, 0x01, 0x82, 0xb2, 0xd4, 0x58, 0x7e, 0xa6, 0x47, + 0xe5, 0xf1, 0x56, 0x23, 0x85, 0x70, 0x6d, 0x88, 0x23, 0xcf, 0x6a, 0x79, + 0x14, 0xff, 0x6c, 0x92, 0x77, 0x76, 0xf5, 0x6e, 0x13, 0x8d, 0xeb, 0x19, + 0xa1, 0xec, 0xb6, 0xce, 0x1b, 0x38, 0xbb, 0x6a, 0x62, 0x9b, 0xe9, 0x36, + 0x56, 0xb7, 0xca, 0x34, 0xdd, 0x42, 0x1a, 0x23, 0x06, 0x1a, 0xba, 0x82, + 0x68, 0xd8, 0xf5, 0x28, 0x20, 0xee, 0x33, 0x14, 0x44, 0x8d, 0xa6, 0x6f, + 0xfe, 0x91, 0x5e, 0xa7, 0x8c, 0x2d, 0x78, 0xb4, 0x8a, 0x3f, 0xad, 0xe9, + 0xd1, 0x1e, 0xfc, 0x2b, 0x0c, 0xad, 0x0e, 0xf0, 0x4a, 0x2f, 0x10, 0x04, + 0x90, 0x40, 0xc6, 0xb0, 0xb6, 0xdf, 0x25, 0xcc, 0xac, 0xdc, 0xb6, 0xf2, + 0x7f, 0xb4, 0x6f, 0x81, 0xb6, 0x16, 0x16, 0x77, 0x01, 0x8e, 0x08, 0xc2, + 0x0a, 0xb1, 0xfd, 0x49, 0xbe, 0x12, 0xbf, 0x14, 0xfe, 0x5d, 0x9f, 0xde, + 0xa9, 0x92, 0xca, 0x1e, 0x40, 0xe3, 0x43, 0x50, 0x7c, 0xef, 0xfe, 0xe2, + 0x3c, 0x58, 0x12, 0xb3, 0x60, 0xb6, 0x6d, 0x54, 0xe2, 0x4a, 0xaf, 0xb6, + 0xca, 0x46, 0xbf, 0x35, 0xb5, 0x4b, 0xb3, 0xe4, 0x39, 0x6a, 0x20, 0x60, + 0xa8, 0x36, 0x02, 0x0a, 0x68, 0xa8, 0x7b, 0xfd, 0xc0, 0xe9, 0x9e, 0xfe, + 0x06, 0xbd, 0x0f, 0x60, 0x30, 0xd4, 0x19, 0x2d, 0x25, 0x4e, 0x3e, 0x2f, + 0x10, 0x6d, 0xd1, 0x07, 0xdf, 0xd1, 0x06, 0x7f, 0xb6, 0xdb, 0xde, 0x7e, + 0x7f, 0xa4, 0x69, 0x08, 0xe3, 0xff, 0x0f, 0xf7, 0xd5, 0xa9, 0x73, 0x32, + 0x55, 0xa8, 0x73, 0xfa, 0xa6, 0xf0, 0x36, 0x0b, 0x4e, 0xdb, 0xd8, 0x78, + 0xeb, 0xa7, 0xe8, 0x32, 0x0c, 0x5a, 0xac, 0x11, 0x3c, 0x9a, 0x37, 0xfc, + 0x9e, 0xb5, 0x16, 0xd9, 0xdc, 0xa8, 0x2f, 0x03, 0x80, 0x9c, 0xc5, 0x65, + 0xbd, 0x1b, 0xff, 0xf4, 0x09, 0xda, 0x70, 0xe8, 0xa0, 0x20, 0x01, 0xef, + 0x89, 0x35, 0x4d, 0x2a, 0x55, 0x29, 0x5e, 0x9b, 0xa6, 0x9c, 0x36, 0xed, + 0x89, 0x82, 0x00, 0x8e, 0x93, 0xd2, 0x30, 0x3b, 0xf7, 0x5a, 0xf7, 0x7f, + 0x8d, 0xc2, 0xdb, 0xaa, 0x6d, 0x5e, 0x7d, 0x46, 0xa9, 0xdc, 0x50, 0x22, + 0x02, 0xd8, 0x15, 0x82, 0x36, 0x09, 0x1f, 0x60, 0xb4, 0x79, 0x18, 0x10, + 0x3e, 0x0c, 0x1c, 0x49, 0x95, 0x4a, 0x1b, 0x4a, 0x82, 0xd1, 0x3b, 0x22, + 0x10, 0x34, 0x4d, 0x0b, 0x13, 0xff, 0x1a, 0xd5, 0x00, 0xc6, 0xfb, 0xf0, + 0x60, 0x4d, 0x0c, 0x42, 0x11, 0x78, 0x21, 0x01, 0xef, 0xab, 0xfb, 0x03, + 0xd6, 0x5b, 0x10, 0x71, 0x42, 0x8b, 0xef, 0xf1, 0x6a, 0xa6, 0x72, 0x8e, + 0x3d, 0x81, 0xb0, 0x31, 0x1c, 0x3c, 0x52, 0xe6, 0x1f, 0x00, 0x00, 0x8a, + 0x08, 0x6c, 0x46, 0x25, 0x2c, 0x3c, 0x1e, 0x03, 0xc3, 0xc0, 0x1e, 0x9a, + 0x8c, 0x1a, 0x70, 0x55, 0xba, 0xb6, 0x14, 0x3a, 0x44, 0xa9, 0x28, 0xe8, + 0x4a, 0x9d, 0xef, 0xf5, 0x22, 0xa5, 0x89, 0x22, 0xa8, 0x46, 0xaf, 0xdb, + 0xf1, 0x6c, 0x62, 0x76, 0xee, 0x2a, 0xc5, 0x2b, 0x15, 0x22, 0x84, 0x22, + 0xee, 0x14, 0x88, 0x9d, 0x74, 0xb9, 0xbe, 0x40, 0x5d, 0x55, 0x5e, 0xc0, + 0x5c, 0x5d, 0xff, 0x16, 0x42, 0xfd, 0xd2, 0xc9, 0xc8, 0xbe, 0xd1, 0x91, + 0xd9, 0xdd, 0x36, 0x05, 0xb7, 0x03, 0x6b, 0xc1, 0x93, 0x94, 0x2e, 0x55, + 0x31, 0x55, 0xbc, 0x5f, 0xff, 0xac, 0x92, 0xf2, 0xc9, 0x0f, 0x47, 0xa2, + 0x33, 0xe4, 0x9c, 0xb5, 0x32, 0xb9, 0x9b, 0xe4, 0x62, 0x83, 0xa3, 0xfc, + 0xcf, 0x6c, 0xe8, 0xd9, 0x9e, 0xf0, 0x52, 0xf4, 0x44, 0x0d, 0x60, 0x4e, + 0x78, 0x0f, 0xff, 0xa9, 0xe6, 0x45, 0xd4, 0x39, 0x9f, 0x96, 0x32, 0x6d, + 0x22, 0x3e, 0x13, 0x25, 0x89, 0xbf, 0x61, 0x77, 0xad, 0xf6, 0x4f, 0xe6, + 0xc0, 0xf5, 0x17, 0x57, 0xfc, 0xbd, 0x0e, 0x77, 0x0f, 0x8b, 0xd8, 0xfe, + 0x36, 0xab, 0x21, 0x65, 0xf3, 0x2a, 0x14, 0x75, 0x1c, 0x34, 0x5b, 0xc1, + 0x14, 0xc3, 0x56, 0xaa, 0x2b, 0xbe, 0x53, 0xb7, 0xad, 0x0c, 0x97, 0x27, + 0x66, 0x3c, 0x5c, 0xea, 0xad, 0x55, 0xdc, 0xc6, 0xc0, 0xa2, 0x95, 0x05, + 0xbc, 0x58, 0xd4, 0x06, 0x09, 0x06, 0xc9, 0xdb, 0xf6, 0x35, 0x65, 0x69, + 0x4b, 0x3f, 0xd5, 0xb5, 0x1f, 0x2a, 0x1e, 0x95, 0x00, 0x9d, 0x7a, 0x85, + 0x7a, 0xb1, 0x5a, 0x1e, 0x49, 0xc7, 0x20, 0x3f, 0xf7, 0x1b, 0xbb, 0xc4, + 0x7d, 0x18, 0x90, 0x97, 0xc8, 0x79, 0xb1, 0x96, 0x96, 0x2d, 0x35, 0x6d, + 0x9c, 0x24, 0xed, 0x36, 0xec, 0x39, 0x92, 0xa9, 0x6b, 0x6c, 0xa6, 0xe2, + 0xd6, 0x3c, 0x8a, 0xa0, 0xfb, 0x12, 0xa9, 0x56, 0xd4, 0xff, 0xaa, 0xc4, + 0xbe, 0x05, 0x4c, 0x0d, 0xc1, 0x2d, 0x97, 0xa4, 0xf3, 0x4c, 0xa8, 0xd8, + 0x5a, 0xd1, 0x57, 0x34, 0x36, 0xb3, 0xb2, 0x83, 0x0d, 0x32, 0xdf, 0x13, + 0x21, 0xf6, 0xc5, 0xaa, 0x80, 0xfd, 0x1b, 0x25, 0xc2, 0xd4, 0x45, 0x70, + 0x6f, 0x2c, 0x45, 0x5e, 0x2b, 0x53, 0x8c, 0xe7, 0x73, 0x9f, 0x8a, 0x25, + 0x1c, 0xa2, 0x92, 0xd8, 0x8c, 0x35, 0xc0, 0x5a, 0x2e, 0xd8, 0x91, 0xd0, + 0xf4, 0x7d, 0xdb, 0xeb, 0xc2, 0xc4, 0x1e, 0xb5, 0x0f, 0xba, 0x0c, 0x83, + 0x70, 0x12, 0x07, 0x62, 0x10, 0xf4, 0x18, 0xb1, 0x96, 0x7c, 0xaf, 0xd4, + 0xb3, 0xe1, 0xdf, 0xb5, 0x1f, 0xa9, 0xb9, 0x01, 0x2e, 0xd8, 0x69, 0xc6, + 0xb7, 0x93, 0x48, 0xad, 0x36, 0xb3, 0x93, 0xa1, 0xdf, 0xd0, 0xa0, 0x40, + 0x46, 0xa2, 0x4e, 0xff, 0xf7, 0xfc, 0xb3, 0x25, 0x29, 0x94, 0x4e, 0x17, + 0xf2, 0x2f, 0x8c, 0xb5, 0xc2, 0xcf, 0xe0, 0x7b, 0x71, 0x7c, 0x6e, 0x58, + 0xb7, 0x01, 0x82, 0x42, 0xca, 0xb9, 0x25, 0xc9, 0x92, 0x4c, 0x44, 0x68, + 0xf1, 0x83, 0x4d, 0x92, 0x45, 0x28, 0xd5, 0x06, 0xaf, 0x54, 0x03, 0x90, + 0x90, 0xfd, 0x20, 0x18, 0x32, 0x3b, 0x83, 0xa8, 0x36, 0xad, 0xef, 0xf9, + 0xe6, 0x3d, 0x03, 0x9b, 0x3a, 0x08, 0xc6, 0x24, 0x9d, 0xb1, 0xc4, 0xb4, + 0x42, 0xdc, 0x37, 0xf8, 0xd4, 0xbd, 0x20, 0x1d, 0xfd, 0x3e, 0x6b, 0x36, + 0xd5, 0xe0, 0x50, 0x75, 0x9f, 0xa7, 0xdb, 0xe0, 0x45, 0x58, 0x3c, 0xbf, + 0x45, 0xc9, 0x0f, 0x0f, 0x70, 0x7a, 0x5a, 0x24, 0xb3, 0x27, 0x4b, 0x27, + 0xb1, 0x74, 0x1c, 0xf1, 0x55, 0x5c, 0x68, 0x4f, 0x9a, 0x2d, 0xe8, 0x2d, + 0x8b, 0xdc, 0x53, 0x8f, 0x6d, 0x01, 0xce, 0x61, 0x6b, 0x3d, 0xe0, 0x2b, + 0x20, 0xc7, 0x84, 0xc3, 0xa2, 0xe1, 0xfe, 0x45, 0x62, 0x0a, 0x94, 0x7f, + 0xa3, 0x0a, 0x7c, 0xa0, 0x32, 0x9f, 0x52, 0xd6, 0x00, 0xa5, 0xca, 0xba, + 0x0a, 0xbc, 0x40, 0x1c, 0x02, 0xde, 0xa0, 0x8c, 0x39, 0x0f, 0x55, 0x7f, + 0x9f, 0xf8, 0x14, 0xfd, 0x2a, 0x99, 0x45, 0x65, 0xcf, 0x4c, 0xe8, 0xe6, + 0x02, 0x49, 0x89, 0x3d, 0x70, 0x3b, 0x8a, 0x1e, 0xd9, 0x5d, 0x1e, 0x88, + 0x3f, 0x2c, 0x95, 0x1a, 0x23, 0x5d, 0x26, 0x5d, 0xbc, 0xd2, 0xdb, 0x10, + 0xb8, 0xff, 0x87, 0x57, 0xb6, 0x02, 0x2f, 0xae, 0x7b, 0x61, 0x6e, 0xf8, + 0xae, 0x4d, 0x35, 0x00, 0x4a, 0xa5, 0xe2, 0x5b, 0x5e, 0x66, 0xe5, 0x6c, + 0xb7, 0xf9, 0x6b, 0x55, 0x41, 0x5c, 0x9b, 0x39, 0xd9, 0xd1, 0xb3, 0x5a, + 0xbc, 0x2d, 0xc2, 0x53, 0x07, 0xb7, 0x32, 0x11, 0x0b, 0x99, 0x6c, 0xab, + 0x43, 0xcf, 0x96, 0x46, 0x5b, 0xe1, 0x62, 0x35, 0x12, 0xf7, 0x78, 0x80, + 0x1c, 0x60, 0xd0, 0xfe, 0x87, 0xb2, 0x41, 0xb2, 0x0e, 0x2f, 0x14, 0xa1, + 0x87, 0xc9, 0x8f, 0x0b, 0xf4, 0x6f, 0x9a, 0xa2, 0x28, 0x37, 0xd9, 0x29, + 0xb3, 0xde, 0xa9, 0x56, 0x57, 0xfc, 0x6b, 0x29, 0x6f, 0xdb, 0x0f, 0x17, + 0xea, 0x09, 0x40, 0x9e, 0x70, 0xcd, 0x68, 0xcb, 0x1f, 0x4e, 0xe6, 0x49, + 0x11, 0x23, 0x46, 0x27, 0x37, 0x59, 0x65, 0x7f, 0x55, 0xeb, 0x5d, 0x6b, + 0xa8, 0xed, 0xc9, 0xd2, 0xce, 0xa8, 0x11, 0x14, 0x3d, 0x38, 0x4f, 0xda, + 0x4a, 0xa7, 0x5b, 0xaa, 0xb7, 0xad, 0x6f, 0xf6, 0x6a, 0x05, 0xe7, 0xec, + 0xb0, 0x2a, 0x2a, 0x14, 0x05, 0xa5, 0xa7, 0x87, 0xdb, 0xf0, 0xf5, 0xaf, + 0xc9, 0x9c, 0x1b, 0x72, 0x59, 0x14, 0x20, 0xe0, 0xc6, 0x83, 0x0d, 0x7b, + 0x71, 0xbc, 0x2b, 0x90, 0xa9, 0x71, 0x4a, 0x32, 0x21, 0x25, 0x1b, 0x20, + 0x86, 0xcf, 0x25, 0xd5, 0x9d, 0xf7, 0x86, 0x6b, 0x63, 0x34, 0xa9, 0xfd, + 0xe5, 0x03, 0x9d, 0x9c, 0xbb, 0x7b, 0x5b, 0xd9, 0xe9, 0x21, 0x22, 0x91, + 0xba, 0x30, 0xb0, 0x60, 0xac, 0x4b, 0x11, 0xb9, 0x4b, 0x52, 0xb1, 0x39, + 0xde, 0xf3, 0xf3, 0x6f, 0x49, 0x23, 0x87, 0xe0, 0xcd, 0x89, 0x1a, 0x5e, + 0x24, 0xb4, 0xc5, 0x66, 0x4a, 0x9e, 0x6e, 0xa4, 0x2d, 0xd5, 0x11, 0x6e, + 0x16, 0xb5, 0x00, 0x9f, 0x35, 0x40, 0x15, 0x07, 0xc8, 0x80, 0x1c, 0x30, + 0xc0, 0x38, 0xc6, 0x25, 0xf3, 0x4c, 0xb3, 0xb3, 0x9b, 0xc6, 0x79, 0xce, + 0xa2, 0xec, 0x2c, 0xfc, 0x19, 0x18, 0x83, 0x9b, 0x00, 0xa2, 0x97, 0x45, + 0x3a, 0x81, 0xcd, 0x86, 0xa0, 0x3a, 0x10, 0xbc, 0xda, 0xb6, 0xd5, 0xa6, + 0x6f, 0xb6, 0xf3, 0x4b, 0x39, 0xc5, 0x36, 0xa1, 0x80, 0x24, 0x33, 0x5c, + 0xb9, 0x6e, 0x6c, 0xe5, 0x88, 0xc9, 0xc5, 0xad, 0x81, 0xc2, 0xf2, 0xd1, + 0x05, 0xa6, 0x53, 0xc6, 0xb9, 0x8d, 0x15, 0xaf, 0x67, 0xa2, 0x29, 0x2a, + 0x90, 0xe1, 0xc1, 0x1f, 0xc1, 0x00, 0x7d, 0xa5, 0x5f, 0x62, 0xb3, 0x68, + 0x15, 0xfe, 0xd1, 0xcd, 0x19, 0xa0, 0x21, 0x80, 0x89, 0xaa, 0xd7, 0x9e, + 0x1c, 0x3d, 0xf5, 0x57, 0x50, 0x05, 0x8d, 0x96, 0x54, 0x3e, 0x4e, 0xae, + 0x29, 0x6b, 0xca, 0x60, 0x6b, 0x30, 0x1c, 0xa4, 0x8c, 0x83, 0x0c, 0x82, + 0x0b, 0x1b, 0x0b, 0x95, 0x08, 0x39, 0x77, 0x2b, 0x58, 0xc6, 0x42, 0xa5, + 0xd0, 0xc9, 0x0a, 0xa6, 0x83, 0x06, 0xe0, 0xf9, 0x5f, 0xfd, 0xd6, 0xe0, + 0x84, 0x93, 0x33, 0xa1, 0xfc, 0x2c, 0x0e, 0xbd, 0x85, 0x9a, 0xa6, 0xf5, + 0x6e, 0x51, 0x88, 0x31, 0x01, 0x46, 0x12, 0xab, 0x92, 0x03, 0x16, 0x08, + 0x4c, 0xed, 0x0e, 0x53, 0xec, 0x60, 0x18, 0x13, 0x6d, 0x1f, 0x66, 0x23, + 0xf9, 0xda, 0x38, 0x15, 0xb6, 0x16, 0x84, 0x60, 0x6c, 0xf4, 0x98, 0xd9, + 0x7e, 0x29, 0x66, 0xf3, 0x7f, 0xbf, 0xaa, 0x43, 0xd4, 0x21, 0xaa, 0x10, + 0x13, 0x20, 0x7c, 0x74, 0x07, 0x87, 0x59, 0xa3, 0xf2, 0xf6, 0xb5, 0x3d, + 0x5b, 0xde, 0xf2, 0x9b, 0x33, 0xbc, 0xbc, 0xf4, 0xe0, 0xd9, 0x15, 0x06, + 0x27, 0x0a, 0xa3, 0xe2, 0xe6, 0x5b, 0xf6, 0x6a, 0xb9, 0x23, 0x6a, 0x21, + 0x6e, 0x65, 0xb7, 0xd2, 0xa1, 0x0d, 0x42, 0xc5, 0xc4, 0x70, 0x38, 0x3c, + 0x05, 0x68, 0xf4, 0x7b, 0xf9, 0xbe, 0x69, 0xa5, 0x83, 0xf5, 0xd8, 0x6a, + 0x49, 0xc0, 0xf3, 0xca, 0x46, 0xfb, 0xa0, 0xa8, 0xff, 0xc6, 0xc2, 0xc7, + 0xf9, 0x60, 0x58, 0xbb, 0xce, 0x11, 0x3f, 0x00, 0x00, 0x8f, 0x08, 0x2c, + 0x44, 0x23, 0x2c, 0x98, 0x78, 0x6c, 0x19, 0x42, 0x65, 0x15, 0x07, 0x47, + 0x10, 0xe1, 0x26, 0x35, 0x5b, 0x2a, 0x65, 0xd0, 0x33, 0x94, 0xd1, 0x02, + 0x63, 0xad, 0xf0, 0x31, 0x60, 0xf1, 0x06, 0x82, 0xa8, 0xb8, 0x95, 0x71, + 0xc7, 0x97, 0x06, 0x13, 0xcf, 0x99, 0x98, 0x1e, 0xa8, 0xa6, 0xbb, 0x17, + 0x46, 0x86, 0xb8, 0x5c, 0x52, 0x22, 0x72, 0x65, 0x7a, 0x38, 0xee, 0xea, + 0xfa, 0x19, 0x39, 0x60, 0x45, 0x5f, 0x91, 0x1f, 0x51, 0x2c, 0xbd, 0x06, + 0x13, 0xad, 0xad, 0x08, 0x3d, 0xd1, 0x06, 0x6c, 0xed, 0xea, 0x85, 0xce, + 0x29, 0x4b, 0x99, 0xe4, 0x2c, 0x92, 0x31, 0xb0, 0x3b, 0xdd, 0x2b, 0xab, + 0x03, 0x02, 0xeb, 0x2b, 0x40, 0xe9, 0x64, 0x5a, 0x4a, 0xd5, 0x47, 0xb9, + 0x28, 0x6b, 0xde, 0x53, 0x47, 0xe3, 0xe9, 0x58, 0x6a, 0x4d, 0xdf, 0xce, + 0x5e, 0xf0, 0x96, 0xc4, 0x71, 0xc3, 0x78, 0xc2, 0xc5, 0x9d, 0x53, 0x28, + 0x2f, 0x4d, 0x09, 0x7f, 0xeb, 0x6c, 0x78, 0x6d, 0xef, 0x7a, 0x64, 0x42, + 0xbb, 0x8a, 0x64, 0xcf, 0x68, 0x87, 0x2f, 0x59, 0x51, 0x63, 0x5e, 0xb3, + 0xd8, 0x86, 0xdd, 0xb2, 0xf2, 0x86, 0xc4, 0x5d, 0x37, 0x87, 0x3c, 0x67, + 0xf9, 0x0b, 0x6f, 0x69, 0x2f, 0x2d, 0xe8, 0x30, 0xd6, 0x5a, 0x93, 0xed, + 0x64, 0xf5, 0x95, 0x42, 0x72, 0xb8, 0x84, 0x3a, 0x47, 0xc1, 0x38, 0x9d, + 0xae, 0xe2, 0x30, 0x4c, 0x38, 0xfe, 0x99, 0x25, 0xbd, 0x37, 0xe6, 0x86, + 0xa6, 0x8b, 0x7a, 0xb9, 0xb0, 0xaf, 0xb3, 0xcd, 0x63, 0x94, 0x89, 0x7e, + 0xfb, 0xc0, 0x91, 0xd2, 0x29, 0x5a, 0x46, 0x15, 0xb1, 0x1b, 0xec, 0xb1, + 0x00, 0x56, 0x9c, 0x57, 0x9d, 0x86, 0xea, 0x08, 0xbb, 0xcb, 0xd9, 0x43, + 0x20, 0xab, 0xa5, 0x86, 0x06, 0xe5, 0xcb, 0x72, 0x8d, 0xe6, 0xf0, 0xd1, + 0xf4, 0xff, 0xfb, 0xad, 0x30, 0x6f, 0xd2, 0xb5, 0x4a, 0x25, 0xec, 0x0c, + 0xc1, 0x82, 0xa2, 0xa2, 0x3c, 0x50, 0x9c, 0x35, 0x82, 0xf7, 0x2c, 0xd6, + 0x75, 0x86, 0xf9, 0x2e, 0xe9, 0x6c, 0x2a, 0x88, 0xf9, 0x65, 0xeb, 0xf8, + 0xf2, 0xc8, 0x08, 0xdb, 0xe0, 0x44, 0x4a, 0xc3, 0x3f, 0x99, 0x2d, 0xf0, + 0x81, 0xd4, 0x52, 0xfe, 0xf2, 0xc0, 0xaa, 0x12, 0x97, 0x2a, 0x2f, 0xf8, + 0xe3, 0x8a, 0x20, 0xe2, 0xe7, 0x99, 0xc5, 0xb9, 0xce, 0x76, 0x5a, 0x22, + 0xe2, 0x90, 0x4a, 0x86, 0x3d, 0xe1, 0xd3, 0x0a, 0x12, 0xe1, 0x6b, 0x69, + 0x6c, 0x2c, 0xcc, 0xc1, 0xcc, 0xf2, 0xfc, 0x85, 0xaa, 0x0a, 0x86, 0xd5, + 0x48, 0x30, 0x9d, 0x1e, 0xa8, 0x1c, 0x4c, 0x5a, 0xc9, 0x75, 0x17, 0x39, + 0x2a, 0x29, 0x01, 0x69, 0x8c, 0xe9, 0x56, 0x91, 0xb6, 0x3d, 0xf0, 0xfc, + 0xbc, 0x20, 0x37, 0x58, 0x52, 0xa7, 0xdd, 0x5f, 0xda, 0x1d, 0x6c, 0x37, + 0x03, 0x83, 0x22, 0x01, 0xd0, 0x86, 0xa9, 0x2d, 0x51, 0x29, 0x66, 0x83, + 0x1a, 0xd0, 0xca, 0x50, 0x4b, 0x2a, 0x10, 0x47, 0x5a, 0xd8, 0x32, 0xf8, + 0x57, 0x79, 0x0b, 0x4d, 0x8a, 0x43, 0xba, 0xf9, 0x4d, 0x3c, 0xbe, 0x29, + 0x05, 0xb1, 0x53, 0x3c, 0xc8, 0xa5, 0xb2, 0x2c, 0xad, 0x7c, 0x33, 0x17, + 0x9d, 0x38, 0x9d, 0x9f, 0x79, 0x2b, 0x0a, 0x7c, 0x39, 0xab, 0x21, 0x92, + 0xc9, 0x3c, 0x8c, 0xac, 0x52, 0x13, 0x41, 0x48, 0xcf, 0xd5, 0x89, 0x49, + 0xeb, 0x34, 0xb7, 0x55, 0x33, 0xc9, 0xfd, 0x5f, 0x54, 0x59, 0x81, 0xe0, + 0x38, 0xc5, 0x7f, 0x28, 0x22, 0xd6, 0x74, 0xad, 0x6e, 0x44, 0x0b, 0x42, + 0x2f, 0x21, 0x1b, 0x7a, 0x73, 0x45, 0xad, 0xa8, 0x5f, 0xf8, 0xad, 0x95, + 0x17, 0xbc, 0xbe, 0xe5, 0xc1, 0x97, 0x01, 0x86, 0x81, 0xc8, 0x7a, 0x0f, + 0x05, 0x01, 0x98, 0x06, 0x2b, 0xf9, 0x7e, 0xb0, 0x3f, 0x57, 0x59, 0x53, + 0x83, 0x8f, 0x16, 0x65, 0xfc, 0xf8, 0x31, 0x54, 0xb7, 0x01, 0x83, 0x8d, + 0x80, 0xc1, 0x52, 0xca, 0xd4, 0xee, 0xac, 0x8b, 0x90, 0xb4, 0xdf, 0x0d, + 0x47, 0x88, 0x47, 0xe9, 0x02, 0x11, 0x7a, 0x61, 0xc2, 0xb6, 0x26, 0xf8, + 0xab, 0x7f, 0x36, 0xf1, 0x78, 0xbc, 0xb4, 0x09, 0x82, 0x52, 0xe6, 0x6f, + 0x16, 0xa0, 0x92, 0x54, 0x84, 0x6d, 0xd2, 0xaa, 0xca, 0x74, 0x8d, 0x27, + 0x6f, 0xdb, 0x3f, 0xff, 0x79, 0xbb, 0xb8, 0x1d, 0x77, 0xfe, 0xe8, 0x79, + 0x43, 0x83, 0xab, 0x88, 0x60, 0x1a, 0x10, 0xc4, 0xa4, 0x89, 0x01, 0x13, + 0x1a, 0xd9, 0xbf, 0x04, 0x46, 0xfb, 0x9f, 0xac, 0xce, 0xfe, 0xf2, 0x50, + 0x24, 0x55, 0xe3, 0x2b, 0x8f, 0x1b, 0xf4, 0x55, 0xaa, 0xb4, 0xaf, 0xd9, + 0xa0, 0xac, 0x43, 0x4b, 0x2a, 0x25, 0xc3, 0x6e, 0x28, 0x05, 0x70, 0x58, + 0x30, 0x11, 0xf7, 0x22, 0x7b, 0x20, 0x32, 0x1f, 0x45, 0x11, 0x41, 0x50, + 0x78, 0xb7, 0x3a, 0x1c, 0x83, 0x04, 0x62, 0x97, 0x0b, 0x78, 0xd5, 0x2a, + 0xa6, 0x0a, 0x3c, 0xd8, 0xb8, 0x47, 0x06, 0xd5, 0x41, 0x09, 0x21, 0x73, + 0x52, 0xf3, 0xec, 0xa8, 0xcc, 0x9c, 0x1b, 0x67, 0x03, 0xd6, 0xe8, 0x6e, + 0xa6, 0x39, 0x41, 0x2b, 0xdf, 0x12, 0xee, 0x33, 0x17, 0x4d, 0xff, 0xd6, + 0xd4, 0xc5, 0xfd, 0xff, 0xd0, 0xef, 0xfd, 0x11, 0x77, 0x4e, 0x06, 0x51, + 0xe8, 0x1c, 0xf3, 0x2c, 0xe2, 0xb5, 0x7e, 0xad, 0xa9, 0xf2, 0xf9, 0x2f, + 0x26, 0x67, 0x56, 0xed, 0x0e, 0x54, 0x38, 0x4c, 0x10, 0x82, 0x00, 0x94, + 0xd6, 0x65, 0x54, 0xac, 0x77, 0xea, 0xb7, 0x1a, 0x05, 0x5b, 0x73, 0xde, + 0xd1, 0xbd, 0xe3, 0x19, 0xb8, 0xc6, 0xe2, 0x3c, 0x2b, 0xf0, 0xb4, 0x61, + 0x9f, 0x7d, 0x50, 0xde, 0x7b, 0x42, 0xd7, 0xb0, 0xf2, 0x61, 0x6d, 0x47, + 0x95, 0x4e, 0x35, 0x92, 0x2c, 0xbe, 0xc5, 0xad, 0xa6, 0x9e, 0xa2, 0x97, + 0x9e, 0x61, 0x56, 0xf8, 0xac, 0x41, 0xd6, 0x40, 0xa1, 0x5a, 0x0a, 0x40, + 0x80, 0x96, 0x98, 0x7e, 0x90, 0x79, 0xe1, 0xff, 0xb2, 0x83, 0x23, 0x8b, + 0x71, 0x4e, 0xcc, 0xb2, 0xae, 0x08, 0xe0, 0x20, 0xe1, 0x35, 0x6e, 0xd4, + 0x2b, 0x67, 0x8c, 0x31, 0x72, 0x5f, 0xd9, 0x3f, 0x7f, 0x6c, 0x05, 0x60, + 0x15, 0xe7, 0x01, 0x90, 0x81, 0x00, 0x61, 0x88, 0x25, 0x0d, 0x81, 0xb9, + 0x04, 0x65, 0x6a, 0xd3, 0x62, 0x78, 0xad, 0x81, 0xc8, 0xe7, 0x32, 0x81, + 0x76, 0xa7, 0xd1, 0xca, 0x1c, 0xe2, 0x91, 0x14, 0xb4, 0x18, 0x12, 0xc7, + 0x25, 0xe1, 0x04, 0x1b, 0x83, 0xed, 0x1d, 0x8f, 0x59, 0xd6, 0xbd, 0xb9, + 0x60, 0xf9, 0x0a, 0xb4, 0xf4, 0xd2, 0x68, 0x87, 0x30, 0x39, 0x06, 0x22, + 0x06, 0x48, 0xfc, 0x1a, 0x8e, 0xd3, 0x8f, 0xc1, 0x4f, 0x35, 0x46, 0xf9, + 0x6f, 0x51, 0xbe, 0xa8, 0x88, 0x8b, 0x6e, 0x8d, 0xc1, 0x86, 0x94, 0x72, + 0x02, 0x9a, 0xe8, 0x58, 0xd9, 0x5c, 0xf9, 0xe4, 0x47, 0x27, 0x1d, 0x06, + 0x4e, 0x01, 0xbc, 0xe0, 0x29, 0xf8, 0x4b, 0x18, 0x6a, 0x51, 0x98, 0x08, + 0x95, 0x40, 0xc9, 0x40, 0xeb, 0x1b, 0x77, 0x53, 0x87, 0xf2, 0xa3, 0xf3, + 0x39, 0x2e, 0x0c, 0xb8, 0x36, 0x7a, 0xd4, 0xf9, 0x50, 0x05, 0x9d, 0x65, + 0xcd, 0x86, 0xb0, 0x64, 0xe3, 0xb4, 0xc9, 0xb4, 0x46, 0x10, 0x58, 0x10, + 0x78, 0x9c, 0x72, 0x59, 0xdb, 0x36, 0x7a, 0x4b, 0x2d, 0xf5, 0x82, 0x2a, + 0x9b, 0x01, 0x24, 0xa3, 0x69, 0x8b, 0x87, 0xa9, 0x15, 0x04, 0x34, 0x8d, + 0xed, 0x9e, 0xb1, 0xb8, 0x86, 0xd9, 0x65, 0xef, 0x83, 0x6d, 0xc3, 0xe6, + 0xc2, 0x18, 0x8f, 0xf0, 0x82, 0x94, 0x3f, 0xd0, 0xf3, 0x8d, 0x66, 0x4c, + 0xea, 0xd3, 0x92, 0x77, 0x80, 0x4f, 0xa6, 0x42, 0x98, 0x30, 0x90, 0x3b, + 0xc6, 0xbc, 0x0c, 0x58, 0xae, 0x95, 0x2b, 0xba, 0xdb, 0x55, 0x16, 0x42, + 0xc8, 0xba, 0xe3, 0x10, 0x61, 0xa7, 0x8c, 0xaf, 0x49, 0xbc, 0x16, 0xb7, + 0x81, 0x57, 0x0b, 0x2d, 0xb1, 0x4c, 0x91, 0x10, 0x8a, 0xb3, 0x83, 0x30, + 0xf4, 0x20, 0xb2, 0xcf, 0xf3, 0xc9, 0x18, 0xd4, 0x89, 0x27, 0x03, 0xfd, + 0x56, 0x55, 0xb7, 0x6a, 0x3f, 0x12, 0x28, 0x07, 0x07, 0xa1, 0x60, 0x88, + 0xbc, 0x7a, 0xab, 0xdc, 0x6c, 0xb9, 0x26, 0x2b, 0x34, 0xdf, 0xf9, 0x9e, + 0x44, 0x1d, 0x95, 0x95, 0xe8, 0x2a, 0x03, 0xa2, 0xd0, 0x62, 0x73, 0x62, + 0x1a, 0xa1, 0xe8, 0x43, 0x6c, 0xb5, 0x8c, 0xef, 0x76, 0xd1, 0xc7, 0x96, + 0xed, 0xa8, 0xed, 0x50, 0x54, 0xa4, 0xc8, 0xb3, 0x2d, 0xef, 0x22, 0x8a, + 0x75, 0x3f, 0xfe, 0x9e, 0x6f, 0x60, 0x80, 0xc2, 0x56, 0x9b, 0xda, 0xa7, + 0x54, 0x42, 0xbd, 0xee, 0xf1, 0x9b, 0x17, 0xbe, 0xaa, 0x14, 0x28, 0xc5, + 0xf0, 0x58, 0x26, 0x4d, 0x37, 0x74, 0x0c, 0x4d, 0xfe, 0xff, 0x94, 0x6f, + 0xdb, 0x79, 0x16, 0x91, 0x49, 0x56, 0x00, 0x82, 0x63, 0xa0, 0x38, 0x24, + 0xe7, 0xb0, 0x72, 0xa3, 0x35, 0x85, 0xd4, 0x56, 0xe6, 0xa9, 0xc8, 0xb4, + 0x9c, 0xc2, 0x97, 0x0b, 0x41, 0x08, 0x78, 0xda, 0xa8, 0xad, 0x2a, 0x55, + 0x19, 0x54, 0x48, 0xc7, 0xb1, 0x16, 0x67, 0x3b, 0xf0, 0x26, 0xa5, 0xd3, + 0xdf, 0x2c, 0x62, 0xef, 0xfd, 0xfe, 0xe8, 0x31, 0x14, 0xca, 0xb1, 0x13, + 0x61, 0x74, 0x74, 0x95, 0x9f, 0x35, 0xf0, 0xfd, 0x37, 0xd2, 0x31, 0xec, + 0x0e, 0xd9, 0xbe, 0x85, 0xb2, 0x4e, 0xff, 0xeb, 0x16, 0x95, 0x61, 0xe0, + 0x60, 0x83, 0x32, 0x0d, 0xf4, 0xe2, 0x3a, 0xb9, 0xe4, 0x95, 0xb6, 0x07, + 0x4d, 0x68, 0x18, 0x40, 0x1f, 0xd8, 0x0c, 0x87, 0xe0, 0xe0, 0x29, 0x80, + 0xe3, 0x21, 0x9c, 0x14, 0xa2, 0x3b, 0x2c, 0xfa, 0x2a, 0x54, 0x1e, 0x35, + 0x7b, 0x55, 0xd5, 0xef, 0xef, 0xa2, 0x29, 0xcc, 0x04, 0x70, 0x61, 0x30, + 0xc1, 0x76, 0xd4, 0x67, 0xb3, 0x29, 0x66, 0xc0, 0x33, 0xd5, 0xf9, 0x51, + 0xda, 0x0b, 0x41, 0xbf, 0xfa, 0xa8, 0x9b, 0x51, 0x99, 0x30, 0xc9, 0x6a, + 0x0f, 0x87, 0x1e, 0x1d, 0x0e, 0xac, 0x5f, 0xe0, 0xaa, 0x4d, 0xde, 0xaf, + 0x3a, 0x38, 0xf1, 0x02, 0x82, 0x08, 0x71, 0x9d, 0xde, 0x2f, 0xbc, 0xe4, + 0x14, 0x2e, 0x3c, 0x52, 0x0a, 0xa2, 0xe5, 0x1d, 0xb4, 0x14, 0xca, 0x86, + 0x03, 0x87, 0x18, 0x10, 0x0b, 0xf7, 0x96, 0x67, 0x09, 0x77, 0xf2, 0x2c, + 0x6f, 0x86, 0x1b, 0xe1, 0x54, 0x3a, 0x9e, 0x8c, 0xce, 0x29, 0x45, 0xf4, + 0x4a, 0x3c, 0x50, 0x84, 0x44, 0x04, 0x70, 0x7c, 0x98, 0x01, 0xd4, 0xac, + 0xb7, 0x6f, 0x95, 0x62, 0xbb, 0x2d, 0xc5, 0x3b, 0xde, 0xa8, 0x99, 0x10, + 0x41, 0xc1, 0x69, 0x58, 0x6c, 0x58, 0x2c, 0x59, 0xb9, 0xf9, 0xb2, 0x02, + 0xb2, 0xea, 0x95, 0xf9, 0x6a, 0xeb, 0xaf, 0x3a, 0xa1, 0x40, 0x5a, 0xb3, + 0x77, 0xa2, 0x1b, 0x05, 0xf1, 0x5a, 0x72, 0xea, 0x93, 0x2f, 0xab, 0x4c, + 0x37, 0xd6, 0x9b, 0xcf, 0xcb, 0xd8, 0xcc, 0xc2, 0xdc, 0x6f, 0x34, 0x15, + 0xc5, 0xa5, 0x86, 0x09, 0xf0, 0xa8, 0xc2, 0xd3, 0x52, 0xa6, 0x50, 0xe4, + 0x31, 0x06, 0x0a, 0x4d, 0x17, 0xf9, 0xb2, 0xdc, 0xea, 0xf6, 0xdd, 0x51, + 0xd4, 0x5c, 0xa7, 0x05, 0xf3, 0xf9, 0xe6, 0xae, 0x94, 0x92, 0x89, 0x85, + 0x09, 0x38, 0x9d, 0xab, 0x3f, 0xcd, 0x5e, 0xac, 0x87, 0xb6, 0xf5, 0x67, + 0xc2, 0xdc, 0x99, 0x61, 0x23, 0xcc, 0xb1, 0xcf, 0x25, 0xb8, 0xdb, 0x3c, + 0x2d, 0xdf, 0xe6, 0x16, 0x4e, 0x5b, 0x6f, 0xa7, 0x14, 0xfc, 0x44, 0xe1, + 0x68, 0x31, 0x3c, 0xb0, 0xb8, 0x2f, 0xd3, 0xa5, 0xc5, 0x9c, 0xad, 0x77, + 0xb7, 0x83, 0x2e, 0x11, 0xbf, 0x2d, 0x17, 0x46, 0x8f, 0xa5, 0x0e, 0xa6, + 0xcf, 0xb5, 0x9a, 0x2f, 0x57, 0xca, 0x58, 0x86, 0x0b, 0x90, 0x3b, 0xb0, + 0x93, 0x19, 0x2b, 0xfd, 0xa1, 0xb9, 0xaa, 0x48, 0x0b, 0x61, 0xa7, 0xf5, + 0x4a, 0x7d, 0x6d, 0x07, 0x68, 0xc3, 0xa7, 0x05, 0xca, 0xa7, 0x0a, 0xd0, + 0x03, 0xba, 0xeb, 0x6d, 0x60, 0x44, 0x07, 0x82, 0xff, 0x8d, 0xaf, 0xe0, + 0x30, 0x16, 0xf7, 0xbb, 0x98, 0x1c, 0x6f, 0xaf, 0x00, 0x9a, 0x93, 0xa9, + 0xa3, 0x7d, 0x0e, 0xbc, 0xc8, 0x2b, 0x75, 0x95, 0xad, 0xfd, 0x29, 0xe5, + 0xa7, 0xfb, 0x8b, 0x85, 0x8a, 0x07, 0x65, 0xcd, 0x6a, 0xa5, 0x6a, 0xef, + 0x6f, 0xd4, 0x4f, 0x40, 0xe3, 0x9c, 0xef, 0x78, 0x1c, 0x9c, 0x3a, 0x01, + 0xd9, 0xdf, 0x0f, 0xe7, 0xb4, 0xb1, 0x92, 0xcf, 0x16, 0x74, 0x67, 0xd0, + 0x61, 0xaa, 0x63, 0xfd, 0xe8, 0xf9, 0x5b, 0x5e, 0x1b, 0xf7, 0xbf, 0x24, + 0xce, 0x68, 0x44, 0x90, 0x07, 0x42, 0xc5, 0x41, 0xfd, 0x2a, 0xd6, 0xd5, + 0x8e, 0x0d, 0xac, 0x58, 0xb0, 0x66, 0xf7, 0x3a, 0x83, 0x10, 0x97, 0x99, + 0xad, 0xb4, 0xa9, 0x36, 0x96, 0x34, 0xd4, 0x03, 0x7a, 0x56, 0x8b, 0x27, + 0xea, 0xdc, 0x85, 0x44, 0x97, 0x0a, 0xc0, 0xae, 0xe0, 0x0a, 0xa6, 0xbe, + 0x5a, 0xde, 0xe2, 0x8b, 0x9c, 0xdc, 0x1b, 0xad, 0x6d, 0xb1, 0x7a, 0x0c, + 0x35, 0x32, 0x07, 0x53, 0x7c, 0x70, 0x5b, 0x8a, 0x6f, 0x95, 0x5b, 0xb7, + 0x00, 0x86, 0xf6, 0x4f, 0x37, 0x0d, 0x29, 0x3a, 0xaa, 0x46, 0x7f, 0xa3, + 0xd9, 0xbf, 0xfa, 0x9c, 0x60, 0x7c, 0xab, 0xbd, 0x1b, 0xdb, 0x60, 0x2c, + 0x41, 0x82, 0xa6, 0x96, 0x77, 0xd1, 0xed, 0x88, 0x99, 0xf5, 0xfc, 0x88, + 0x64, 0xdd, 0xec, 0x0d, 0xa3, 0xc5, 0x21, 0x0c, 0x75, 0x5a, 0xa2, 0x0f, + 0xb2, 0x96, 0x7e, 0xef, 0x20, 0x70, 0x48, 0x7c, 0x52, 0xb5, 0x97, 0x11, + 0xcb, 0x41, 0x38, 0x2e, 0xb3, 0xf8, 0x55, 0x2e, 0x62, 0x8d, 0xe8, 0xa1, + 0xf1, 0xe7, 0xb5, 0xa5, 0x8f, 0x6d, 0x50, 0x6c, 0x51, 0x44, 0x21, 0xfe, + 0x45, 0xbe, 0x1f, 0x95, 0x94, 0x96, 0x4a, 0xe3, 0xa3, 0xf4, 0xfd, 0xfb, + 0x6c, 0x76, 0xb5, 0xb7, 0x9d, 0xda, 0xbc, 0xdc, 0x43, 0x39, 0xa5, 0xaa, + 0x11, 0xcd, 0x2a, 0x2c, 0x04, 0x8a, 0x1e, 0x35, 0x89, 0x3e, 0x5e, 0xd6, + 0x49, 0x31, 0x3e, 0xcf, 0xc4, 0x12, 0x3f, 0x08, 0xe3, 0xaf, 0xea, 0x7e, + 0xf0, 0x13, 0x89, 0x54, 0xa0, 0xb6, 0xca, 0x0c, 0x4c, 0x57, 0xb5, 0x4f, + 0xe8, 0x2d, 0xdb, 0x2a, 0xab, 0xfe, 0x69, 0x8b, 0xe5, 0xd9, 0xca, 0x37, + 0xbf, 0xbd, 0xde, 0x2c, 0xbc, 0xa1, 0xc2, 0x20, 0x10, 0x32, 0x03, 0xb9, + 0x8a, 0xb8, 0xaf, 0xea, 0xfc, 0x1f, 0x67, 0xe7, 0xba, 0xa3, 0xf1, 0x45, + 0xbc, 0x2c, 0x58, 0x34, 0xa0, 0x94, 0x7d, 0xa6, 0x1b, 0x4c, 0xc8, 0xe3, + 0xe3, 0x6f, 0xc0, 0xf0, 0x92, 0xdb, 0x0e, 0x12, 0x06, 0x12, 0x73, 0xd4, + 0x21, 0x6c, 0x6f, 0x73, 0x19, 0xe6, 0x08, 0x1e, 0x11, 0x7f, 0x3d, 0x64, + 0x0c, 0x41, 0x82, 0xa4, 0x1c, 0xd6, 0x39, 0xb1, 0x19, 0x89, 0xba, 0x59, + 0x87, 0xdb, 0x17, 0x17, 0x30, 0xaa, 0xb5, 0xce, 0xdd, 0x2d, 0x91, 0x7e, + 0xcb, 0xef, 0xc5, 0x97, 0x61, 0x40, 0x25, 0x0a, 0x87, 0x62, 0x40, 0xe5, + 0x88, 0xd3, 0x5f, 0x8d, 0x7d, 0x4e, 0x37, 0x9b, 0x62, 0x98, 0xb0, 0x14, + 0xb0, 0x16, 0xe0, 0xd0, 0x60, 0x19, 0x58, 0x1f, 0x04, 0x0c, 0xd4, 0xc3, + 0xc4, 0xf8, 0x59, 0xb6, 0x87, 0x9b, 0x91, 0x96, 0xb0, 0x15, 0xca, 0x46, + 0xdb, 0xa0, 0x55, 0x40, 0x31, 0x1d, 0xf8, 0x18, 0x4b, 0x04, 0x36, 0xd3, + 0xa9, 0x6c, 0x7f, 0x85, 0x7d, 0x06, 0x02, 0x8d, 0x45, 0x1d, 0x02, 0x1c, + 0xc0, 0x10, 0x3b, 0x4b, 0xfa, 0x37, 0x70, 0xc0, 0x7f, 0xd2, 0x06, 0xc2, + 0x82, 0x61, 0x20, 0x79, 0xa3, 0x82, 0xe0, 0xff, 0xe0, 0xdd, 0xcc, 0xfa, + 0xbf, 0xe7, 0x95, 0x96, 0x37, 0x65, 0xa1, 0xec, 0xfb, 0x01, 0xee, 0x0e, + 0x17, 0x50, 0x56, 0x5a, 0x0c, 0x70, 0xd3, 0x3e, 0x89, 0x36, 0xae, 0x38, + 0xef, 0xca, 0xa2, 0x3b, 0xc2, 0x62, 0x41, 0x00, 0x03, 0x7c, 0x01, 0x83, + 0xb0, 0x61, 0x04, 0xbc, 0x41, 0x67, 0xfb, 0xe6, 0x70, 0xa8, 0xaf, 0x6d, + 0xf9, 0x2b, 0x7a, 0x2a, 0xa6, 0x41, 0x84, 0x30, 0x36, 0x3f, 0xd5, 0x7f, + 0x2e, 0xd2, 0xc4, 0x7e, 0xc1, 0x06, 0x76, 0x5e, 0xac, 0x0c, 0x09, 0x4f, + 0x5b, 0x9a, 0x47, 0xe3, 0x7d, 0x05, 0xb3, 0x62, 0x81, 0x0b, 0xd2, 0xf9, + 0xa9, 0xab, 0xaf, 0x34, 0xa7, 0x51, 0x9f, 0x38, 0x0c, 0xac, 0x18, 0x4b, + 0x11, 0x81, 0x01, 0x8f, 0xb1, 0xdf, 0x17, 0x8e, 0xee, 0x52, 0xc1, 0xe6, + 0x2e, 0xa2, 0xf1, 0x1a, 0x70, 0x63, 0x4d, 0x03, 0xe5, 0xff, 0xf6, 0x78, + 0x20, 0x83, 0x0e, 0xc4, 0x31, 0x24, 0x0c, 0x34, 0xcb, 0x63, 0xe2, 0xee, + 0x70, 0x3e, 0x63, 0x54, 0x29, 0x25, 0xff, 0xf0, 0xaf, 0x43, 0x40, 0x48, + 0x1f, 0x87, 0x77, 0xb6, 0xdb, 0x6a, 0x1d, 0x5e, 0x8d, 0x4d, 0xaf, 0x70, + 0xb6, 0xa0, 0x6b, 0x08, 0x61, 0x0c, 0x7e, 0x07, 0xd2, 0xd4, 0xa3, 0xf6, + 0xcb, 0x75, 0x16, 0x64, 0x2a, 0x69, 0x8f, 0x20, 0x69, 0x8f, 0x0d, 0x9a, + 0xc3, 0x07, 0xd8, 0x59, 0x07, 0x99, 0xae, 0x64, 0x3e, 0x9b, 0x6c, 0x5f, + 0x48, 0x2b, 0x4f, 0xd0, 0xe9, 0x25, 0x79, 0x2a, 0xac, 0x37, 0x20, 0x66, + 0x41, 0x6b, 0x43, 0x48, 0xa2, 0xa7, 0x62, 0x7f, 0x85, 0x97, 0xf9, 0x36, + 0xd4, 0x52, 0x5b, 0x27, 0x68, 0x6d, 0x82, 0x63, 0x23, 0xd4, 0x9f, 0x12, + 0x87, 0xe9, 0x03, 0xf1, 0xd3, 0x25, 0xf9, 0x3c, 0x20, 0x2a, 0xd6, 0xb7, + 0x89, 0x3f, 0x2c, 0xbd, 0xa0, 0x61, 0x4e, 0xc0, 0x54, 0x30, 0x1e, 0x0d, + 0xcc, 0x8d, 0x02, 0xe0, 0x33, 0x56, 0x7c, 0x10, 0x07, 0x55, 0x19, 0x56, + 0xe6, 0x9b, 0xef, 0xbf, 0x70, 0x1f, 0x5e, 0x00, 0x52, 0x15, 0x2f, 0x5e, + 0x58, 0xb1, 0xb3, 0x40, 0xca, 0x5a, 0xf2, 0x62, 0xd2, 0xc8, 0xa2, 0x28, + 0x9a, 0x5d, 0xf5, 0xac, 0xb6, 0xc9, 0xce, 0x69, 0x59, 0x50, 0x72, 0x64, + 0x2c, 0x29, 0x2e, 0x2f, 0x61, 0xb0, 0x6e, 0x7e, 0xa4, 0x4e, 0x59, 0x40, + 0xb7, 0xd4, 0x73, 0x49, 0x4a, 0x8a, 0xd4, 0x19, 0x26, 0x23, 0x8f, 0x18, + 0x1f, 0xa4, 0x6f, 0x2c, 0x0f, 0x67, 0xba, 0xd5, 0x42, 0xa6, 0x22, 0x9d, + 0x1a, 0x87, 0x71, 0xd4, 0x4b, 0xe5, 0x7b, 0x6f, 0xa3, 0x5c, 0xdb, 0xf5, + 0x25, 0xbd, 0xe6, 0xa2, 0xab, 0x28, 0x11, 0x75, 0xf7, 0xfa, 0x89, 0x63, + 0x85, 0x3d, 0x31, 0xda, 0xa1, 0x1c, 0x20, 0xaa, 0x66, 0xb4, 0xad, 0x3f, + 0x6c, 0xcc, 0xcd, 0x0f, 0xf2, 0x55, 0xe5, 0x47, 0x37, 0x14, 0x6e, 0xe0, + 0x2d, 0xd6, 0x68, 0x20, 0xe8, 0x29, 0xbe, 0xd3, 0x21, 0xe5, 0xf9, 0x66, + 0x0e, 0x5a, 0xbc, 0xca, 0xbc, 0x97, 0x81, 0xc6, 0x99, 0x16, 0xab, 0x2c, + 0x6f, 0x9f, 0x6d, 0xbf, 0x4f, 0xf9, 0x66, 0xe6, 0x0d, 0xed, 0x40, 0xb0, + 0x88, 0x54, 0x7c, 0x73, 0xbe, 0x1b, 0x60, 0x22, 0xa8, 0x54, 0xa0, 0x3f, + 0xdf, 0x7d, 0x78, 0x89, 0x1f, 0x44, 0x42, 0x33, 0xff, 0xf4, 0x05, 0xaa, + 0x5d, 0x5b, 0x36, 0x10, 0xd5, 0x35, 0x90, 0x3f, 0x6b, 0xf7, 0x18, 0xdd, + 0xc2, 0xdf, 0x72, 0xe9, 0x65, 0xa0, 0x54, 0xa8, 0xae, 0x62, 0x90, 0xec, + 0x1c, 0x64, 0x42, 0x3e, 0x12, 0x1b, 0xcd, 0x2c, 0xe7, 0x3f, 0xfe, 0x8e, + 0x16, 0xeb, 0x4d, 0xf5, 0x15, 0xee, 0x08, 0xaa, 0x00, 0x49, 0x31, 0xf3, + 0x43, 0xc6, 0xfa, 0x38, 0x6d, 0x4d, 0x51, 0x54, 0x45, 0x2b, 0x20, 0x5e, + 0x06, 0xc7, 0x42, 0xd8, 0x40, 0x1c, 0x82, 0x20, 0x19, 0xde, 0xf3, 0xfb, + 0x3d, 0x10, 0xe6, 0x14, 0x89, 0x8b, 0xd6, 0xeb, 0x72, 0x78, 0x82, 0xca, + 0x16, 0xbf, 0x00, 0x00, 0x99, 0x08, 0x2c, 0x2c, 0x88, 0x5a, 0x0f, 0x05, + 0x00, 0xd8, 0xea, 0x23, 0xa0, 0xa6, 0x2e, 0x19, 0x40, 0xf8, 0xc1, 0x66, + 0xe6, 0xa2, 0x9b, 0x7c, 0x4a, 0x43, 0x22, 0x52, 0x8f, 0x08, 0xc2, 0x57, + 0x06, 0xf4, 0x78, 0x5c, 0x0f, 0x17, 0x00, 0x6c, 0x3a, 0xbb, 0x6a, 0xd4, + 0x23, 0x19, 0x04, 0xa2, 0x82, 0x51, 0x13, 0x9b, 0x31, 0x8c, 0x66, 0x76, + 0x4f, 0xdb, 0xab, 0xaf, 0xc5, 0x86, 0x01, 0x6c, 0xc5, 0x4d, 0x35, 0xf0, + 0xe6, 0xac, 0x37, 0x93, 0xa7, 0x14, 0x6a, 0xee, 0xd9, 0x7b, 0x02, 0x22, + 0xb5, 0x65, 0xd1, 0x84, 0xc9, 0x87, 0x21, 0xe6, 0xd7, 0x1e, 0xea, 0xc3, + 0x45, 0x53, 0x08, 0x31, 0x57, 0xfe, 0xc2, 0x06, 0x73, 0xbd, 0x5e, 0x58, + 0x59, 0x7b, 0x02, 0x83, 0x42, 0x4f, 0xd1, 0x41, 0x58, 0xa0, 0xb9, 0x57, + 0xa0, 0x8d, 0x24, 0x02, 0xb9, 0x7f, 0x4a, 0x6f, 0x29, 0xf7, 0xa4, 0x35, + 0xe9, 0x93, 0x4c, 0x3d, 0x2d, 0xe1, 0x6c, 0x51, 0x69, 0x27, 0x20, 0xc0, + 0x12, 0x8b, 0xa7, 0x5b, 0xda, 0xa1, 0x69, 0xca, 0x4a, 0xb9, 0xf1, 0xae, + 0xfa, 0xf9, 0x9d, 0xca, 0x36, 0xf8, 0xba, 0x55, 0xe5, 0x06, 0x13, 0x0a, + 0x30, 0xad, 0x8c, 0xcb, 0x66, 0xd9, 0xce, 0xa0, 0x9c, 0x90, 0x8d, 0xd1, + 0x98, 0xa9, 0x8d, 0xd1, 0x3c, 0x50, 0x3a, 0xef, 0xe1, 0x65, 0x44, 0x13, + 0x12, 0x9e, 0xca, 0x20, 0xea, 0x9f, 0x6c, 0x62, 0x55, 0x3c, 0xfa, 0x14, + 0x73, 0xa5, 0x40, 0x90, 0x2f, 0x12, 0x3d, 0xd1, 0xf3, 0x4a, 0xd6, 0xbf, + 0x67, 0x27, 0xcb, 0x62, 0x2b, 0x96, 0x07, 0x9c, 0x0d, 0x94, 0x3e, 0xfb, + 0x08, 0x6d, 0x45, 0x96, 0xc5, 0x9d, 0x26, 0x97, 0xcd, 0xd9, 0xa8, 0xcf, + 0xac, 0x3f, 0x57, 0xe6, 0x9a, 0xe5, 0xb7, 0x2e, 0xad, 0x14, 0x73, 0xb3, + 0xb1, 0x1c, 0x0b, 0x53, 0x2c, 0xe7, 0xc1, 0x97, 0xbf, 0x55, 0x11, 0x37, + 0xf9, 0x3f, 0xbd, 0xe5, 0xe7, 0x96, 0xb2, 0x06, 0xb9, 0xd3, 0x10, 0xcd, + 0xbe, 0x03, 0x1e, 0x88, 0x94, 0x07, 0xd8, 0x36, 0x88, 0xd1, 0x06, 0x60, + 0x2c, 0xf2, 0x41, 0x03, 0x0b, 0x2f, 0x8b, 0x69, 0x5c, 0x52, 0xa7, 0x54, + 0xe8, 0x2b, 0xfa, 0x16, 0x13, 0x4f, 0x97, 0xe2, 0x0e, 0xf6, 0xf3, 0xcc, + 0xf9, 0x5c, 0xe2, 0xdd, 0x92, 0xae, 0xe7, 0x19, 0x0b, 0xcb, 0xe2, 0x5c, + 0x51, 0x72, 0xf3, 0x07, 0x1f, 0x6a, 0x7b, 0xf2, 0xf3, 0x92, 0xca, 0x81, + 0x48, 0xa4, 0x71, 0x5a, 0xd5, 0x43, 0xdd, 0xd5, 0xaf, 0xb0, 0x3e, 0x52, + 0xd9, 0xbf, 0x7f, 0xc0, 0xe2, 0xae, 0x29, 0x50, 0x0b, 0x75, 0x07, 0xaa, + 0x44, 0x00, 0x65, 0xe9, 0x53, 0x2a, 0x14, 0x64, 0xed, 0xda, 0xb8, 0x79, + 0x7d, 0x30, 0x45, 0x11, 0x7e, 0x04, 0x40, 0x48, 0xbf, 0x4a, 0x87, 0x9f, + 0x83, 0x6b, 0xe6, 0xe2, 0xa6, 0x90, 0x4f, 0xf2, 0xf3, 0xd6, 0xc1, 0x10, + 0xab, 0xa0, 0xc3, 0x56, 0xfa, 0x72, 0xc5, 0x96, 0x23, 0xb0, 0x6c, 0x6e, + 0x1a, 0x36, 0x0e, 0x30, 0xa5, 0x0f, 0x65, 0xf7, 0x7b, 0xce, 0x59, 0x45, + 0x6d, 0x68, 0x59, 0x22, 0x2e, 0x28, 0x19, 0x47, 0x2a, 0xc7, 0xc1, 0x5a, + 0xdb, 0x00, 0x42, 0xf6, 0x14, 0x52, 0x38, 0x79, 0x74, 0x5b, 0xd5, 0x4b, + 0x59, 0xbf, 0xf5, 0x19, 0xca, 0x28, 0x41, 0x55, 0xea, 0x56, 0x17, 0xe4, + 0xfe, 0xe7, 0xaa, 0xd2, 0xde, 0xdb, 0x17, 0x9d, 0x1b, 0x19, 0x5a, 0xd2, + 0xc0, 0x62, 0xde, 0x2d, 0x4b, 0x7d, 0x46, 0x56, 0x57, 0xca, 0x9b, 0x55, + 0x4f, 0xe0, 0xdf, 0xb8, 0x32, 0x7f, 0xc7, 0xa6, 0x45, 0x2f, 0x14, 0xec, + 0xe5, 0x67, 0x7c, 0x89, 0x47, 0xa6, 0x2e, 0x81, 0x75, 0x2a, 0x02, 0xd0, + 0xe0, 0x0d, 0x71, 0x92, 0xf0, 0x84, 0x21, 0x96, 0x97, 0x5c, 0xac, 0x31, + 0xa5, 0x9b, 0x7f, 0x2a, 0xfd, 0x45, 0x6e, 0x08, 0xa0, 0xc1, 0x21, 0x5c, + 0x04, 0x54, 0xa5, 0x8c, 0xaa, 0xc2, 0xd9, 0x64, 0x1c, 0xcb, 0xdc, 0xaa, + 0x79, 0xdb, 0xcf, 0x83, 0x8c, 0x85, 0x66, 0xda, 0xd6, 0x58, 0xd9, 0xf9, + 0xd0, 0xf1, 0x43, 0x71, 0x1e, 0x6f, 0x62, 0x10, 0x5b, 0xca, 0x29, 0x16, + 0xb0, 0x6e, 0xc1, 0xf3, 0x0a, 0xd3, 0x36, 0xce, 0xa7, 0xf7, 0x93, 0xf8, + 0x18, 0x44, 0xbc, 0x97, 0x60, 0x30, 0x4e, 0xa2, 0x41, 0x23, 0xcc, 0xaa, + 0x56, 0xaf, 0xe5, 0xfe, 0x55, 0x58, 0x45, 0x9b, 0x17, 0xd3, 0x52, 0x15, + 0x98, 0x0a, 0xa0, 0xcd, 0x83, 0x0f, 0xb4, 0x75, 0xb8, 0x5e, 0xc2, 0xe9, + 0x2f, 0xfb, 0xa6, 0xda, 0x9d, 0x45, 0xd4, 0x24, 0x61, 0xa5, 0x29, 0x77, + 0xa2, 0xba, 0x20, 0x5e, 0xaa, 0x9c, 0xe2, 0xfd, 0xb5, 0xe6, 0xbd, 0x8c, + 0x1b, 0x53, 0x78, 0xa6, 0xf4, 0x32, 0x15, 0xa9, 0xc3, 0xe8, 0x2b, 0xc5, + 0xde, 0xbe, 0x4b, 0x0c, 0xb7, 0x78, 0xf2, 0x1e, 0x30, 0x5e, 0x39, 0x39, + 0x84, 0x7f, 0x36, 0x32, 0xa9, 0x1d, 0xff, 0x0f, 0x6f, 0x6c, 0xa2, 0x61, + 0x62, 0x1a, 0x84, 0x98, 0xbb, 0x00, 0x58, 0xfa, 0xdf, 0xab, 0x53, 0x63, + 0x12, 0x18, 0xec, 0x54, 0xd8, 0xc1, 0xbf, 0x00, 0x90, 0xae, 0x0c, 0x90, + 0x03, 0xda, 0x1e, 0x16, 0x8e, 0x93, 0xa9, 0x50, 0xdb, 0x73, 0xed, 0x59, + 0x2e, 0x95, 0xd9, 0xcd, 0x9c, 0x41, 0x8b, 0x02, 0x48, 0xb5, 0x38, 0xf9, + 0x5e, 0x49, 0xff, 0xf9, 0x6e, 0x45, 0xc9, 0x09, 0xc3, 0x2e, 0xfa, 0x8d, + 0xf1, 0x18, 0xbc, 0x4c, 0x55, 0x52, 0xc7, 0xdc, 0xb3, 0xb8, 0xb9, 0xe6, + 0xc2, 0x39, 0x6e, 0x55, 0xe5, 0x09, 0x47, 0xe5, 0xec, 0x64, 0x4f, 0xf6, + 0x43, 0xa6, 0xad, 0xbd, 0x50, 0x88, 0x96, 0x83, 0x8c, 0x83, 0x31, 0x20, + 0x28, 0x44, 0x32, 0xe8, 0xa3, 0xb8, 0xdc, 0xe0, 0x30, 0x8b, 0x2d, 0xe4, + 0x29, 0xcd, 0x31, 0x49, 0xc2, 0x18, 0x8e, 0x25, 0x95, 0x5b, 0x3c, 0xd2, + 0x25, 0x0d, 0x15, 0x41, 0x88, 0x24, 0x92, 0xca, 0x59, 0xb9, 0x16, 0x3a, + 0x5d, 0x6c, 0x2d, 0x6c, 0x30, 0x8e, 0xc4, 0x74, 0xcc, 0x5d, 0x85, 0xda, + 0xdd, 0x56, 0xb5, 0x8a, 0xf3, 0x79, 0x99, 0x67, 0x65, 0xf5, 0x9b, 0x9a, + 0xa4, 0x8d, 0x00, 0x84, 0x3b, 0x06, 0xee, 0x6a, 0xa6, 0x4b, 0x04, 0x14, + 0x3b, 0xa8, 0xdb, 0x88, 0xd6, 0xe1, 0x40, 0x24, 0x26, 0x3e, 0x12, 0xbf, + 0xfa, 0xa3, 0x1a, 0x2d, 0x5c, 0x3d, 0xab, 0xdb, 0x0d, 0xf1, 0x46, 0x7f, + 0x54, 0x83, 0x04, 0xa2, 0x3a, 0x0c, 0x3e, 0x2f, 0x1f, 0x87, 0xaa, 0x93, + 0x02, 0x9b, 0x99, 0xc9, 0x7a, 0x59, 0x94, 0xd5, 0x2c, 0xd0, 0x56, 0xdb, + 0xa1, 0xce, 0xe0, 0xb0, 0x60, 0xfd, 0x3e, 0xd8, 0xb3, 0xe1, 0x0d, 0x50, + 0x1a, 0xa3, 0xe5, 0x4d, 0x07, 0xdc, 0xd8, 0x0a, 0xd9, 0x38, 0x89, 0x6e, + 0x70, 0x37, 0x04, 0x90, 0xbc, 0x0a, 0x45, 0x7e, 0xf8, 0xf1, 0x40, 0xe4, + 0xb7, 0xfe, 0xfe, 0xa9, 0x52, 0x55, 0x39, 0x7b, 0x57, 0x06, 0x09, 0x51, + 0x4c, 0x0c, 0x5c, 0x23, 0x8f, 0x9a, 0xcd, 0x4a, 0x94, 0x7c, 0xc6, 0x29, + 0x52, 0xdd, 0x56, 0x37, 0x6f, 0x2a, 0xfc, 0x8a, 0x0a, 0xd4, 0xe8, 0x6c, + 0x5a, 0x2d, 0x58, 0x1c, 0x91, 0x54, 0x0f, 0x87, 0xdb, 0x83, 0x91, 0x17, + 0xd8, 0x91, 0xbb, 0xfe, 0x22, 0x9c, 0xf6, 0xef, 0xd3, 0xee, 0x86, 0xe1, + 0xf0, 0x30, 0xc0, 0x58, 0x54, 0xdf, 0x49, 0x0e, 0xd1, 0x04, 0xf3, 0x67, + 0xc7, 0xcc, 0xcf, 0x0e, 0x8b, 0xb7, 0x6a, 0x89, 0x0b, 0x95, 0x12, 0xa2, + 0x6a, 0x1c, 0x6c, 0x4f, 0xa5, 0x64, 0x3f, 0xdc, 0x83, 0x88, 0x36, 0xcd, + 0x42, 0x4a, 0xe1, 0xe0, 0x29, 0xda, 0xc2, 0xe6, 0x95, 0xa5, 0xf9, 0x60, + 0xf8, 0x74, 0x99, 0x36, 0xb3, 0x50, 0xda, 0x59, 0x24, 0xf4, 0x80, 0xc8, + 0x77, 0x4f, 0xac, 0x23, 0x03, 0x02, 0x18, 0x84, 0xad, 0x2a, 0x61, 0xf0, + 0x7c, 0xda, 0xa0, 0x37, 0xbf, 0xcd, 0x65, 0xbb, 0x27, 0xb3, 0x7b, 0xc4, + 0xd0, 0x1e, 0x23, 0xff, 0x70, 0xe4, 0x3c, 0x2c, 0x06, 0x15, 0xb6, 0x11, + 0xbc, 0xd2, 0x26, 0xc5, 0x7e, 0xf6, 0x62, 0x29, 0x30, 0xa0, 0xe5, 0xab, + 0xde, 0x70, 0x98, 0x24, 0xe7, 0xe1, 0x27, 0x0d, 0xf4, 0xe1, 0xd5, 0x6a, + 0xcb, 0x7e, 0x59, 0xde, 0xe7, 0x8b, 0x69, 0xa2, 0xb9, 0xde, 0xd0, 0xd0, + 0x1f, 0x3f, 0xff, 0xb8, 0x44, 0x51, 0xf6, 0xfa, 0x75, 0x55, 0x3e, 0xe6, + 0x7a, 0x77, 0x7a, 0xe2, 0x6c, 0x45, 0x0a, 0x9a, 0xf0, 0x70, 0xc6, 0x4a, + 0x53, 0xc7, 0x2b, 0xf6, 0x6a, 0x89, 0xef, 0x5e, 0x2c, 0x1e, 0xd4, 0x6b, + 0x9a, 0x07, 0x18, 0x51, 0x33, 0x65, 0xa9, 0x9a, 0xf9, 0xbf, 0x40, 0xa3, + 0xe9, 0x1d, 0x7a, 0x64, 0xc7, 0xac, 0x29, 0xe2, 0x39, 0xcb, 0x57, 0x8b, + 0x53, 0xc3, 0xd1, 0x2f, 0xfa, 0xa8, 0x7c, 0xb6, 0xc6, 0xd7, 0x8b, 0x22, + 0xb6, 0x72, 0x86, 0xa0, 0x24, 0xbf, 0xfa, 0x5b, 0xd1, 0x11, 0x7e, 0xc1, + 0x59, 0x90, 0x3b, 0x58, 0x03, 0x39, 0xbb, 0x25, 0x63, 0x8c, 0xe6, 0x08, + 0xbd, 0x2d, 0xe7, 0x78, 0x1c, 0x2d, 0x4c, 0x7c, 0x06, 0x0a, 0xd9, 0x31, + 0x98, 0x90, 0x23, 0x8e, 0xc7, 0x60, 0x1c, 0x9c, 0x70, 0x5c, 0xd3, 0x0d, + 0xb3, 0xa9, 0x58, 0x0f, 0x6d, 0x0e, 0xa7, 0xcb, 0x27, 0xe5, 0xd0, 0xdb, + 0xa3, 0x60, 0xec, 0x2c, 0x0a, 0xe2, 0x50, 0xfd, 0xb5, 0x41, 0x08, 0x4a, + 0x49, 0x9e, 0xd6, 0x77, 0xde, 0xf6, 0x5d, 0x5a, 0x4f, 0x2a, 0x61, 0x61, + 0xcf, 0xd4, 0x96, 0x0d, 0xfb, 0x0a, 0x83, 0x50, 0x62, 0x61, 0x6a, 0x44, + 0x94, 0xb8, 0xab, 0x57, 0xf7, 0xf9, 0xb9, 0xc4, 0x39, 0x65, 0xbc, 0x0d, + 0x4e, 0xf0, 0x38, 0xc3, 0x7d, 0x1f, 0xeb, 0x3f, 0x80, 0x6b, 0xe5, 0x90, + 0xb9, 0xa2, 0xce, 0x6a, 0xa6, 0x18, 0x40, 0xc9, 0x59, 0x5e, 0xee, 0xf7, + 0x41, 0x84, 0xe4, 0xf1, 0x47, 0x85, 0x7d, 0x8a, 0x38, 0x1f, 0xb7, 0xee, + 0xd5, 0x18, 0xa2, 0xdb, 0xc5, 0xef, 0x65, 0xce, 0xae, 0x1b, 0x9f, 0xb4, + 0xe1, 0x00, 0x7d, 0xfb, 0x6f, 0xf3, 0x76, 0xde, 0x73, 0x54, 0xde, 0xcc, + 0x35, 0x04, 0x43, 0x18, 0x79, 0x7a, 0xd6, 0xa5, 0xd9, 0xc0, 0x45, 0x19, + 0x87, 0x93, 0xb3, 0xd0, 0x09, 0xe4, 0x0b, 0x4a, 0xa8, 0xa8, 0xd6, 0xe0, + 0x14, 0x25, 0x71, 0xce, 0x58, 0xbc, 0xbd, 0x32, 0x44, 0x8d, 0x08, 0x1e, + 0x2a, 0x44, 0xa1, 0x0f, 0xff, 0xa6, 0xed, 0x42, 0x62, 0xb3, 0x40, 0xb6, + 0xff, 0x81, 0xef, 0x3d, 0xa8, 0x0a, 0xe4, 0x44, 0x78, 0x8a, 0x74, 0xde, + 0x4e, 0x37, 0x1b, 0xc9, 0x14, 0x14, 0xb8, 0x6c, 0xcf, 0x84, 0x0b, 0x2d, + 0x58, 0x44, 0xfd, 0x25, 0x95, 0x18, 0x55, 0x70, 0xbc, 0xb4, 0x9b, 0xd2, + 0xcc, 0xd6, 0x3e, 0x57, 0x7d, 0xf5, 0x2d, 0x72, 0xce, 0xa8, 0xab, 0x88, + 0xa1, 0xc6, 0x74, 0x05, 0x9c, 0x4b, 0x75, 0xb1, 0xf2, 0x55, 0x5a, 0x05, + 0xd4, 0x41, 0xea, 0xa8, 0x0c, 0x1b, 0x74, 0x1c, 0xa5, 0x4f, 0x70, 0x18, + 0x4d, 0x29, 0x6a, 0x9c, 0x9b, 0xe8, 0x5a, 0x36, 0xe0, 0x89, 0x64, 0xfa, + 0xdd, 0xe8, 0x69, 0x41, 0x20, 0xba, 0x7c, 0x50, 0x9c, 0x4a, 0xad, 0x48, + 0xa2, 0xc9, 0x93, 0x09, 0x0b, 0x29, 0x6f, 0x43, 0x5c, 0xe6, 0x89, 0xf7, + 0x20, 0xb4, 0xa6, 0x96, 0xcf, 0x6f, 0xd1, 0xd8, 0x50, 0x75, 0x5d, 0xf5, + 0x04, 0x52, 0xdf, 0x2d, 0xcf, 0x02, 0xb4, 0xd4, 0xcb, 0x62, 0x30, 0xa9, + 0x4c, 0x6f, 0xd0, 0x72, 0x9a, 0x6c, 0x9b, 0x9f, 0xb7, 0xc5, 0xab, 0x4b, + 0x2a, 0xf0, 0xf1, 0x50, 0xef, 0xb1, 0x9f, 0x45, 0xe5, 0x28, 0x50, 0x48, + 0x15, 0x72, 0xca, 0x0e, 0x30, 0x3f, 0x6e, 0x37, 0xc5, 0x0d, 0xb5, 0xed, + 0x24, 0xef, 0x39, 0xc0, 0xad, 0x6e, 0xe6, 0x26, 0xf2, 0x08, 0x5b, 0xc3, + 0x6b, 0x74, 0x99, 0x55, 0x20, 0xa6, 0xfe, 0x78, 0x0b, 0xb1, 0x50, 0x7d, + 0x7f, 0xcc, 0x9c, 0x0f, 0x7d, 0x44, 0x5c, 0x0b, 0x14, 0x4b, 0x04, 0x01, + 0x05, 0x42, 0xec, 0x6e, 0x46, 0x70, 0xa6, 0x70, 0xb6, 0x74, 0x18, 0x2b, + 0xf2, 0xcb, 0x0e, 0x99, 0xe0, 0xeb, 0xde, 0x9c, 0x9f, 0xcd, 0xad, 0x12, + 0xcc, 0x9d, 0x5e, 0x40, 0xe0, 0x89, 0x02, 0x44, 0x1b, 0xce, 0xd0, 0xdc, + 0x98, 0xf8, 0xf1, 0xa9, 0xf6, 0x55, 0xa6, 0x67, 0x79, 0x54, 0xa9, 0xf7, + 0xf8, 0x56, 0xbf, 0x2a, 0xc3, 0x51, 0x18, 0x37, 0x18, 0xf4, 0x0e, 0xdb, + 0xd1, 0x7d, 0xe9, 0xa0, 0xd8, 0x85, 0xae, 0x0d, 0x9c, 0x58, 0x2d, 0x01, + 0xa8, 0xf1, 0xb1, 0xf8, 0x40, 0x1f, 0xaa, 0x69, 0x7e, 0xfa, 0x95, 0x73, + 0xb7, 0xa2, 0xa0, 0x7b, 0xfd, 0xaf, 0xfb, 0x77, 0x3f, 0xd9, 0xfc, 0xb6, + 0x6c, 0xd5, 0xaf, 0x62, 0x37, 0x0b, 0xd9, 0xff, 0x94, 0xdc, 0xcf, 0xde, + 0x14, 0xf6, 0x1f, 0x08, 0xa0, 0xc1, 0x0c, 0x21, 0x07, 0xc9, 0xc1, 0x8b, + 0x55, 0x07, 0x4a, 0xf9, 0x15, 0xa0, 0x0f, 0x78, 0x47, 0x12, 0xba, 0xd2, + 0xd3, 0x08, 0xa8, 0xeb, 0xc3, 0xc0, 0xb5, 0x49, 0x9d, 0x7c, 0x7b, 0x4f, + 0x05, 0x85, 0x7c, 0x2c, 0x21, 0x18, 0x5a, 0x21, 0xa5, 0x16, 0xf5, 0xe5, + 0x9a, 0x2e, 0xdf, 0xf3, 0xcb, 0x4f, 0xac, 0x55, 0xb6, 0x79, 0x64, 0x40, + 0x97, 0x76, 0xe1, 0x96, 0x25, 0xce, 0xa1, 0x87, 0x86, 0xbf, 0x23, 0x0b, + 0xc9, 0x04, 0x64, 0xcc, 0x07, 0x96, 0x62, 0xbd, 0xb8, 0x39, 0x6d, 0xba, + 0x54, 0xc3, 0x52, 0x72, 0x70, 0x0a, 0x8e, 0x75, 0x7a, 0x55, 0x81, 0xc0, + 0x31, 0x18, 0x7a, 0xaa, 0x87, 0x23, 0xff, 0xb5, 0xe2, 0xbf, 0x46, 0x76, + 0x29, 0x41, 0xc9, 0xfb, 0x21, 0xe2, 0xf7, 0xca, 0x24, 0x05, 0xba, 0xd3, + 0x8d, 0xe4, 0x8b, 0x80, 0x53, 0x6c, 0xa9, 0x46, 0x9a, 0xb0, 0x60, 0x7c, + 0x52, 0x0c, 0xa1, 0x52, 0x61, 0xf6, 0xeb, 0x65, 0xbe, 0xde, 0xc1, 0xc0, + 0x71, 0xb2, 0x2c, 0x88, 0x1c, 0x64, 0x67, 0xf5, 0x45, 0xb3, 0x70, 0x92, + 0xd1, 0xa4, 0xb9, 0x73, 0x9d, 0x80, 0x92, 0xc8, 0xb8, 0xb0, 0x24, 0xb6, + 0x56, 0x81, 0xf4, 0xbe, 0xb7, 0x15, 0x2f, 0x96, 0xa9, 0xee, 0xfa, 0x22, + 0xa8, 0x2a, 0x95, 0x2a, 0x4c, 0x05, 0x76, 0x01, 0x84, 0x01, 0xea, 0x46, + 0xd3, 0xa7, 0x98, 0x3e, 0x65, 0xab, 0x3d, 0x54, 0x2c, 0xd6, 0xed, 0x9d, + 0x2d, 0x9e, 0x11, 0x75, 0x67, 0xa2, 0x10, 0x1a, 0x85, 0xe5, 0x4c, 0x0f, + 0x07, 0xe9, 0x7f, 0x99, 0x39, 0xbe, 0x61, 0x4f, 0xbb, 0xc0, 0xea, 0xfd, + 0x4a, 0x8c, 0xc0, 0xdc, 0x18, 0x80, 0x5d, 0x01, 0x87, 0x42, 0x3b, 0x69, + 0xe6, 0xab, 0xf2, 0x65, 0x5e, 0xbf, 0xeb, 0x61, 0xec, 0xa5, 0x5d, 0x0e, + 0xa0, 0xd8, 0x0c, 0xe0, 0x2d, 0x44, 0x77, 0x15, 0x28, 0x8a, 0x5b, 0x52, + 0x0a, 0x80, 0x62, 0x14, 0x53, 0x21, 0x0b, 0x66, 0x70, 0x46, 0xc5, 0x61, + 0xea, 0x6f, 0xe3, 0x71, 0x4a, 0x84, 0x5c, 0xbd, 0x14, 0x0b, 0x0b, 0x81, + 0xbc, 0x3f, 0x57, 0x54, 0x0e, 0x19, 0xcf, 0x28, 0xed, 0x57, 0x24, 0xc9, + 0xde, 0x74, 0xb3, 0xca, 0x46, 0xfa, 0x0e, 0xf1, 0x00, 0x54, 0x8c, 0x0f, + 0x00, 0x39, 0xaf, 0x70, 0xb3, 0x2d, 0xc9, 0x9d, 0xdd, 0xac, 0x97, 0xfe, + 0x44, 0x65, 0x8a, 0x4a, 0xb3, 0x31, 0x6d, 0x53, 0x85, 0x9e, 0x06, 0x21, + 0x27, 0x34, 0x49, 0x6f, 0xc0, 0xf0, 0x50, 0x0c, 0xa6, 0xc9, 0x7f, 0x7d, + 0x7c, 0xac, 0xbf, 0x64, 0xf4, 0x96, 0x77, 0xb3, 0xc0, 0xc8, 0x41, 0xc2, + 0x28, 0x31, 0x18, 0xee, 0xa8, 0x40, 0x44, 0x79, 0x68, 0xa8, 0xb0, 0xb2, + 0x21, 0x17, 0x0f, 0xc4, 0x64, 0xd5, 0xa4, 0x82, 0x41, 0x7a, 0xb4, 0xfb, + 0x80, 0x5f, 0xfe, 0x69, 0x8b, 0x64, 0x0e, 0xa4, 0x51, 0xa5, 0x58, 0x8f, + 0x42, 0xd2, 0xd8, 0x3c, 0x05, 0x09, 0x7d, 0xeb, 0x3e, 0x89, 0x32, 0x0d, + 0x87, 0x2d, 0xc5, 0x0d, 0x0c, 0xb0, 0xb7, 0x5b, 0x07, 0x07, 0x80, 0x90, + 0x5f, 0xd8, 0x23, 0x83, 0xc2, 0x7f, 0xd6, 0x23, 0xb4, 0xd4, 0x5c, 0xa8, + 0xb9, 0x8f, 0x34, 0xde, 0xf1, 0x7e, 0x16, 0xe9, 0x68, 0xe3, 0x14, 0x4a, + 0x0f, 0x9b, 0xff, 0xd9, 0xf1, 0xf8, 0x21, 0xfa, 0x7c, 0x70, 0xc4, 0xd1, + 0xfa, 0x8a, 0x59, 0xc5, 0x3f, 0xb8, 0xb2, 0x0a, 0x1f, 0x03, 0x02, 0x4e, + 0xf5, 0xf6, 0x6a, 0xa6, 0x2e, 0x8a, 0xf3, 0xba, 0x5e, 0x08, 0x23, 0xd9, + 0xf4, 0x4d, 0x65, 0x05, 0x32, 0x98, 0x8e, 0x56, 0x74, 0x19, 0x06, 0x03, + 0x06, 0xc1, 0xc1, 0x81, 0x52, 0x61, 0xf0, 0x1f, 0x5b, 0x80, 0xaa, 0x12, + 0x32, 0xa3, 0x4c, 0x5c, 0xc4, 0x8d, 0xd2, 0x5f, 0xd5, 0x03, 0x70, 0x23, + 0xa5, 0xbf, 0x06, 0x3a, 0x21, 0xf0, 0x96, 0xdf, 0x93, 0x63, 0x6c, 0xb0, + 0x1f, 0x76, 0x75, 0xa5, 0x59, 0xe5, 0xe4, 0xbc, 0x0f, 0x68, 0x89, 0x99, + 0xab, 0x16, 0x29, 0x06, 0x3a, 0xb5, 0xd0, 0x86, 0xae, 0x87, 0x8d, 0x6c, + 0xc0, 0xdb, 0x92, 0xa8, 0xea, 0x3e, 0x87, 0x20, 0xc4, 0xe7, 0x57, 0x00, + 0x00, 0xa3, 0x08, 0x6c, 0x98, 0x37, 0x15, 0x17, 0x84, 0x04, 0xc9, 0x9b, + 0x63, 0x15, 0xb0, 0xca, 0xa4, 0xda, 0xce, 0x08, 0x92, 0xc5, 0x5e, 0xe0, + 0x13, 0x04, 0xb0, 0xd6, 0x3b, 0x06, 0x08, 0x45, 0xd6, 0x7f, 0x47, 0x40, + 0x63, 0xe8, 0xe7, 0xb7, 0xbb, 0xee, 0x92, 0x51, 0xbe, 0x03, 0xe5, 0xc0, + 0x0e, 0x81, 0x75, 0x07, 0x82, 0x80, 0x64, 0xb9, 0x47, 0x38, 0x06, 0x98, + 0x52, 0x81, 0x7a, 0xd3, 0x82, 0xae, 0xf6, 0x3c, 0x94, 0x27, 0xc5, 0xb0, + 0xeb, 0x61, 0x58, 0x46, 0x56, 0xcd, 0x12, 0x93, 0x34, 0x9e, 0xe8, 0x29, + 0xfd, 0x31, 0x51, 0x7a, 0x94, 0x7d, 0xf7, 0xb9, 0xc9, 0x44, 0x55, 0x3b, + 0x14, 0xa9, 0x06, 0x21, 0x4b, 0x00, 0xbb, 0x66, 0xf8, 0xc8, 0x64, 0xf5, + 0x65, 0xd5, 0x25, 0xb6, 0xec, 0x90, 0x6e, 0xba, 0xdb, 0xe4, 0x32, 0x86, + 0x98, 0x57, 0xe0, 0x71, 0x8a, 0x4a, 0xac, 0x3e, 0x48, 0x5e, 0x5f, 0x8c, + 0x56, 0xf5, 0xac, 0xad, 0xfa, 0x0d, 0x94, 0x87, 0x9c, 0xb3, 0xa1, 0xc2, + 0x83, 0xe5, 0xf7, 0xae, 0x84, 0x29, 0x8d, 0x02, 0x18, 0x97, 0x82, 0x51, + 0x73, 0x6a, 0xe8, 0xde, 0x74, 0x71, 0x8b, 0x77, 0xec, 0xa0, 0x81, 0x9e, + 0x83, 0x09, 0x82, 0xf8, 0x33, 0x05, 0xed, 0x97, 0x80, 0x70, 0x8d, 0xf6, + 0x7f, 0xd6, 0x59, 0x2e, 0x9b, 0xf4, 0x0b, 0xcf, 0xef, 0x8b, 0x64, 0x0e, + 0x16, 0x70, 0x7b, 0x4e, 0x3d, 0x6c, 0x20, 0xd8, 0xad, 0x91, 0x13, 0xf9, + 0x15, 0x01, 0x0f, 0x5b, 0x28, 0x78, 0x56, 0x37, 0x69, 0x48, 0x3e, 0x47, + 0xff, 0x60, 0xb4, 0x10, 0x92, 0x7d, 0x85, 0x60, 0x19, 0xad, 0xb3, 0x41, + 0xc9, 0x04, 0x88, 0x5d, 0xf4, 0xd8, 0xb3, 0x57, 0xe5, 0xe5, 0x97, 0xed, + 0x86, 0xb9, 0xb2, 0x67, 0xb0, 0x1f, 0x23, 0xff, 0xb6, 0xc5, 0xba, 0xf8, + 0xd8, 0xa7, 0x71, 0xe1, 0xf0, 0x4b, 0x69, 0x58, 0x38, 0x14, 0x6a, 0xd5, + 0xe3, 0x3e, 0xd5, 0x57, 0x1a, 0x55, 0xf5, 0x57, 0x3b, 0x7b, 0xee, 0xc8, + 0x1e, 0x86, 0xb7, 0xe5, 0x40, 0xb7, 0x32, 0x10, 0xc7, 0xe0, 0xca, 0x07, + 0x49, 0xcb, 0xd0, 0xb1, 0x91, 0x41, 0x2e, 0xdb, 0x3d, 0x03, 0x30, 0x60, + 0xa4, 0x30, 0xd0, 0x52, 0xe5, 0x6e, 0xd6, 0xa3, 0x69, 0x59, 0xaa, 0xd1, + 0x62, 0xca, 0x76, 0xaf, 0x6d, 0xa0, 0xb4, 0x12, 0x4d, 0xe5, 0x56, 0x5d, + 0x6e, 0xa8, 0x06, 0x26, 0x59, 0xc2, 0x14, 0xc2, 0xfb, 0x42, 0x4f, 0xbb, + 0xe2, 0xa2, 0xcb, 0x99, 0x27, 0xa7, 0x4a, 0xa2, 0xdc, 0x9c, 0x06, 0x13, + 0x15, 0x54, 0xad, 0x2a, 0x95, 0x3d, 0x37, 0xc8, 0x22, 0x73, 0xa0, 0xc1, + 0x48, 0x47, 0x1d, 0x30, 0x39, 0x2c, 0xdb, 0x39, 0xbc, 0xce, 0xf2, 0x5d, + 0xe6, 0xad, 0x6c, 0x58, 0x4e, 0x2a, 0x6f, 0xf1, 0xa6, 0xb1, 0x9f, 0xb0, + 0x6a, 0x61, 0xbb, 0x79, 0xd9, 0x78, 0x1a, 0x39, 0xd9, 0x5b, 0xa4, 0xd0, + 0xb1, 0x24, 0x2f, 0x03, 0x6d, 0x79, 0x07, 0xda, 0xb1, 0x64, 0x1c, 0xe2, + 0x37, 0x6e, 0xd2, 0xd8, 0xcf, 0x6f, 0x72, 0x5c, 0xe0, 0x89, 0xcb, 0x65, + 0x44, 0x1c, 0x9c, 0x3e, 0x20, 0xd4, 0xfb, 0x2a, 0x2e, 0x20, 0x0c, 0x4f, + 0x6d, 0x66, 0xb1, 0x64, 0xfa, 0x14, 0x44, 0xae, 0x3d, 0xcf, 0x36, 0x80, + 0xe6, 0xdb, 0x9b, 0xd5, 0x91, 0x14, 0x74, 0x84, 0x60, 0x3f, 0x53, 0xd6, + 0x7c, 0x1c, 0x87, 0xad, 0x21, 0x9d, 0x88, 0x02, 0x94, 0x58, 0x57, 0x14, + 0x95, 0xf2, 0xcb, 0xde, 0x62, 0x2a, 0xba, 0x23, 0xc8, 0xff, 0x27, 0x25, + 0x8b, 0xdc, 0xea, 0x84, 0x15, 0x11, 0x33, 0xeb, 0x8e, 0x65, 0xd7, 0x6d, + 0x03, 0x2e, 0xc7, 0x50, 0xc9, 0x71, 0x45, 0x47, 0x16, 0xe0, 0x3b, 0x0c, + 0xab, 0x9b, 0xf5, 0x5e, 0x1f, 0x4d, 0x05, 0x68, 0x81, 0xaa, 0xf5, 0x5f, + 0xf5, 0x17, 0xbb, 0xd2, 0xc9, 0x01, 0xc3, 0x60, 0xdc, 0xc1, 0x92, 0xdf, + 0xb7, 0x8c, 0x5f, 0x77, 0x39, 0xa1, 0xea, 0x0e, 0xdb, 0x3b, 0xca, 0x1c, + 0x98, 0x69, 0xf6, 0x4f, 0x36, 0x39, 0x2a, 0xdb, 0xf9, 0xfe, 0x7a, 0x42, + 0xbf, 0x7a, 0xad, 0x39, 0x44, 0x5d, 0x30, 0xe7, 0xdc, 0xa5, 0x63, 0xdc, + 0x53, 0x56, 0xde, 0x0c, 0xe3, 0xce, 0x5a, 0xdd, 0xd9, 0x16, 0xe3, 0x1e, + 0xf6, 0x96, 0xd5, 0x94, 0xac, 0xbc, 0xe6, 0x15, 0x05, 0xa6, 0x77, 0xf8, + 0x9c, 0x7c, 0xd7, 0xd8, 0xfd, 0xde, 0x5a, 0x1d, 0x87, 0x76, 0xc5, 0xaa, + 0xc1, 0xb1, 0xe4, 0xda, 0x6c, 0x14, 0xec, 0x56, 0x2d, 0x51, 0xf5, 0x08, + 0xf8, 0x32, 0xec, 0x0e, 0x40, 0x4f, 0x6d, 0x0d, 0xe3, 0x2a, 0x90, 0x29, + 0xaa, 0x54, 0x51, 0x81, 0xc3, 0x41, 0xda, 0x6c, 0xf6, 0xc0, 0xf4, 0xb9, + 0x7f, 0xfa, 0xae, 0x39, 0x61, 0x15, 0x82, 0xf7, 0x1b, 0x1f, 0x7e, 0xa9, + 0xd1, 0xf3, 0x28, 0xe2, 0x9c, 0x88, 0x3b, 0x62, 0x38, 0x04, 0xc6, 0xe1, + 0x69, 0x76, 0xbc, 0xdf, 0x87, 0xb1, 0x8a, 0x1d, 0x6f, 0xad, 0xc9, 0x50, + 0x43, 0x41, 0xa0, 0x25, 0x46, 0x2d, 0xa9, 0x2c, 0x69, 0xa5, 0x7d, 0x46, + 0xd5, 0x55, 0xbf, 0xcb, 0xdb, 0xd9, 0x7a, 0xc0, 0x13, 0x46, 0x60, 0x44, + 0xab, 0xda, 0xa8, 0x7d, 0x6a, 0xbb, 0x77, 0x6e, 0x1b, 0x45, 0xde, 0x11, + 0x98, 0x63, 0x8c, 0xe2, 0x52, 0xee, 0x5c, 0x9f, 0x56, 0xae, 0x7a, 0xa1, + 0xc6, 0x65, 0x53, 0x2c, 0x0d, 0x70, 0xfb, 0x1d, 0x33, 0xa9, 0x4b, 0x9a, + 0xea, 0xed, 0xaa, 0xd0, 0xf9, 0x94, 0x1d, 0xbe, 0x58, 0x1d, 0xa0, 0x93, + 0x4a, 0x16, 0x58, 0xdc, 0xb4, 0x3f, 0x57, 0x15, 0x26, 0x8b, 0x45, 0xfe, + 0x80, 0xa6, 0x05, 0x67, 0x41, 0x92, 0x8e, 0xa2, 0x50, 0x38, 0x96, 0xa0, + 0x4c, 0xab, 0x74, 0xdd, 0xec, 0x44, 0x0c, 0x09, 0xa1, 0x7c, 0x3e, 0x05, + 0x6c, 0xdc, 0xc9, 0xec, 0xc9, 0x14, 0x20, 0x29, 0xa7, 0x83, 0x08, 0x30, + 0x96, 0xae, 0x60, 0x07, 0x08, 0xeb, 0xf0, 0x19, 0x6d, 0x18, 0xa2, 0x80, + 0xc1, 0x5d, 0x2e, 0xc1, 0xd4, 0x6d, 0x08, 0x0f, 0x26, 0x20, 0x25, 0x24, + 0xfa, 0x55, 0x6c, 0x30, 0xd6, 0x29, 0xfb, 0x7f, 0xcc, 0xf4, 0x25, 0xaf, + 0xd1, 0x11, 0x2d, 0x78, 0x4d, 0x06, 0x05, 0x10, 0x42, 0xad, 0x97, 0xfc, + 0x4b, 0xd8, 0x1e, 0x0f, 0xb2, 0x28, 0xb4, 0x18, 0x39, 0xfc, 0x45, 0x03, + 0x4c, 0x07, 0x29, 0x30, 0xcc, 0xd8, 0x27, 0x8b, 0x81, 0x44, 0x25, 0x08, + 0xca, 0x95, 0x03, 0x2c, 0xd7, 0xd2, 0xc6, 0xbb, 0xad, 0xec, 0xb7, 0xaa, + 0xd6, 0xed, 0x85, 0x6b, 0x15, 0x80, 0x9a, 0x82, 0x37, 0x87, 0x0c, 0x32, + 0x9d, 0x8c, 0x6d, 0x2a, 0x8a, 0x5b, 0xfd, 0xe6, 0xe4, 0xea, 0xfc, 0x93, + 0x54, 0x85, 0x82, 0xc5, 0x6c, 0xa8, 0xd5, 0x05, 0x97, 0x50, 0xdb, 0x96, + 0x52, 0xce, 0x93, 0xbf, 0xec, 0x04, 0x4f, 0xc5, 0x32, 0xff, 0xf2, 0x96, + 0x67, 0x50, 0x8a, 0x48, 0xe4, 0x9c, 0x79, 0x64, 0xcd, 0x86, 0xc0, 0x61, + 0x2c, 0x7a, 0x98, 0x4a, 0x2e, 0x2c, 0x4c, 0xa2, 0x0f, 0x52, 0x87, 0x8a, + 0x31, 0x65, 0x1e, 0xa8, 0xff, 0x62, 0x00, 0x60, 0x8c, 0x35, 0x02, 0x88, + 0x20, 0x36, 0xc9, 0x5a, 0x8e, 0xa1, 0xe2, 0x3b, 0x7a, 0x8a, 0x40, 0xe7, + 0x4c, 0x9a, 0x2e, 0x06, 0x48, 0xcb, 0x25, 0xff, 0x2f, 0x08, 0x2c, 0xa9, + 0x67, 0xff, 0xdf, 0x88, 0x1e, 0xed, 0xfc, 0x95, 0x12, 0xe2, 0x22, 0x90, + 0x7c, 0x78, 0x01, 0xc1, 0x79, 0x83, 0xc5, 0x43, 0xc0, 0xf3, 0x3a, 0x5c, + 0xc2, 0xc1, 0xd4, 0xe7, 0xed, 0x29, 0xd2, 0xbb, 0xa1, 0xa1, 0x60, 0xb1, + 0xae, 0xa9, 0xfa, 0xe4, 0x46, 0x5d, 0x5c, 0x16, 0xad, 0x85, 0xdd, 0x06, + 0x82, 0x39, 0x7d, 0x06, 0x5f, 0x3c, 0xc3, 0x19, 0xd1, 0x01, 0x4b, 0x2a, + 0x27, 0xb2, 0x50, 0xf1, 0x61, 0x17, 0x73, 0x8e, 0x15, 0x0f, 0x81, 0x00, + 0x74, 0x5d, 0xef, 0xfa, 0xf9, 0x20, 0xfd, 0xbf, 0x8d, 0xeb, 0x7f, 0xb7, + 0xd2, 0x21, 0x94, 0xa8, 0x18, 0x2a, 0xe0, 0xc5, 0x82, 0x40, 0xfe, 0xdb, + 0xf4, 0xe3, 0xf6, 0xff, 0xaa, 0x54, 0x7f, 0x7f, 0xcf, 0x49, 0xda, 0xb4, + 0x11, 0x1a, 0x0e, 0x00, 0x88, 0x30, 0xad, 0x26, 0x80, 0xf0, 0xe9, 0xac, + 0x9c, 0xf2, 0xb2, 0xc5, 0x94, 0xe6, 0xfe, 0xa8, 0xdb, 0xc0, 0x2b, 0x46, + 0xfb, 0x88, 0xca, 0x8b, 0x40, 0x54, 0xfe, 0xdf, 0x91, 0xbd, 0xf8, 0x5b, + 0x68, 0x08, 0x11, 0x40, 0xe3, 0x04, 0x7a, 0x91, 0x23, 0x41, 0xda, 0x61, + 0x29, 0x53, 0x49, 0x3d, 0x32, 0x15, 0x70, 0x41, 0xdd, 0x53, 0x81, 0xc2, + 0x90, 0xf0, 0x12, 0x92, 0x83, 0xc5, 0x6c, 0xaa, 0x99, 0x89, 0x41, 0x94, + 0x35, 0xda, 0x54, 0xa8, 0x1c, 0x94, 0x7f, 0x49, 0x59, 0x2f, 0x52, 0x55, + 0xba, 0xb1, 0x56, 0x16, 0x83, 0xe4, 0x40, 0x0e, 0x49, 0x82, 0xe4, 0xca, + 0x81, 0xe0, 0xe0, 0x17, 0x69, 0x84, 0x93, 0xa1, 0xed, 0x64, 0xae, 0xd2, + 0x48, 0x0b, 0x6d, 0xbb, 0xa1, 0xed, 0x9f, 0xee, 0x7a, 0x69, 0x6a, 0x8c, + 0xbc, 0x58, 0xaf, 0xb0, 0x39, 0xd1, 0x10, 0x2d, 0x77, 0xbf, 0x82, 0x37, + 0x95, 0x5c, 0xdb, 0xe6, 0x44, 0x76, 0x43, 0x92, 0xff, 0xf9, 0xa6, 0x3a, + 0x51, 0xa5, 0xbb, 0xa8, 0xa1, 0x5e, 0x80, 0xb4, 0x9b, 0x68, 0x0f, 0xa5, + 0x2d, 0x07, 0x17, 0xb0, 0xc3, 0x53, 0xbc, 0x2c, 0xaa, 0x63, 0x59, 0x11, + 0xcf, 0x4c, 0x2a, 0x02, 0x7a, 0x5a, 0x88, 0x16, 0xeb, 0xa9, 0x4a, 0xdc, + 0x91, 0x84, 0xc9, 0x6f, 0xef, 0xe4, 0xf6, 0xab, 0xf7, 0x9a, 0xe7, 0x91, + 0x96, 0xf0, 0x45, 0xc5, 0x05, 0x4a, 0x41, 0xc6, 0x0b, 0x32, 0xa9, 0xb2, + 0xbe, 0xb3, 0xcd, 0xb2, 0xf1, 0x47, 0xf9, 0x3a, 0x87, 0x90, 0x45, 0x31, + 0xf6, 0x61, 0xa0, 0x0e, 0xac, 0xc1, 0xc8, 0x92, 0x10, 0xdb, 0x4e, 0xd4, + 0x0e, 0xa7, 0xbf, 0x7d, 0x0b, 0x0d, 0x5b, 0x03, 0x93, 0xe2, 0xff, 0x62, + 0x44, 0xca, 0x18, 0x2e, 0x55, 0x31, 0x69, 0xca, 0xb0, 0xbe, 0x88, 0x80, + 0xe3, 0x2a, 0xe2, 0x6c, 0x8c, 0x7b, 0xd9, 0xf9, 0x76, 0x48, 0xa7, 0x76, + 0x15, 0x6f, 0xf8, 0x8b, 0x88, 0x14, 0xe8, 0x3e, 0x3f, 0xff, 0x6a, 0xd4, + 0x85, 0x72, 0xa5, 0x6f, 0x7f, 0x68, 0x14, 0xf5, 0xe7, 0xa1, 0x48, 0x72, + 0x84, 0x18, 0x9b, 0xec, 0x8c, 0x1c, 0xcc, 0x0f, 0x6c, 0xcb, 0x6a, 0xe5, + 0x7d, 0x9c, 0xe2, 0xd0, 0x12, 0x31, 0x6f, 0x83, 0x95, 0xf8, 0x8e, 0x2c, + 0xe3, 0x7a, 0xcb, 0x05, 0x93, 0xcd, 0x2d, 0x18, 0x52, 0x8a, 0x2c, 0x8d, + 0x79, 0x03, 0x90, 0x12, 0xb3, 0x4a, 0xea, 0xbd, 0xe0, 0x80, 0xa7, 0x0d, + 0xd4, 0x10, 0xd9, 0xef, 0x7f, 0x00, 0x00, 0xa8, 0x08, 0x6c, 0x82, 0x69, + 0x41, 0xb8, 0x5c, 0x0f, 0x0f, 0x00, 0x7a, 0xa0, 0x78, 0xb8, 0x02, 0x5d, + 0x57, 0x54, 0x23, 0x87, 0x44, 0x41, 0x0b, 0x18, 0x4a, 0x10, 0x07, 0x4a, + 0x64, 0xd2, 0xc2, 0xe5, 0x4d, 0x03, 0xc5, 0x40, 0x1b, 0x08, 0x83, 0x10, + 0x21, 0xe0, 0xec, 0x75, 0xfd, 0xfb, 0x42, 0x55, 0x4a, 0x3c, 0x9e, 0xb4, + 0x41, 0x63, 0x41, 0x5b, 0xe9, 0x10, 0x7f, 0xda, 0x8c, 0x15, 0x06, 0x45, + 0x8f, 0x0b, 0xa0, 0x73, 0x76, 0x20, 0xe1, 0x6f, 0x96, 0x5e, 0xd8, 0x15, + 0xa8, 0x25, 0x66, 0xcc, 0x12, 0x40, 0x3b, 0xf7, 0xb4, 0x15, 0xbf, 0x1f, + 0x7e, 0xa1, 0x2e, 0x67, 0xa1, 0xe4, 0x06, 0x0d, 0x1b, 0xee, 0x02, 0xb8, + 0x2c, 0x1f, 0x0f, 0x87, 0xe9, 0x47, 0xbf, 0x94, 0x74, 0x3a, 0x2f, 0x5b, + 0xaa, 0x5b, 0xdf, 0x49, 0xef, 0x59, 0x38, 0xb7, 0xd0, 0xee, 0xe8, 0x08, + 0x37, 0x8a, 0xcb, 0xc4, 0x81, 0x1f, 0x3e, 0x94, 0xb5, 0x53, 0x7f, 0xfc, + 0x2d, 0x52, 0x1f, 0xb3, 0xfb, 0xeb, 0x43, 0xa4, 0xd7, 0x5b, 0x51, 0x98, + 0xa7, 0x85, 0x78, 0xab, 0xc4, 0x45, 0xe0, 0xb2, 0x53, 0x2d, 0x87, 0xd5, + 0x00, 0xc1, 0xf2, 0xbc, 0xdf, 0xb0, 0x5a, 0x20, 0x33, 0x47, 0x09, 0xb7, + 0xb8, 0x20, 0xb3, 0x3f, 0x57, 0x0d, 0x9a, 0xcd, 0x8a, 0x54, 0x81, 0x50, + 0xb0, 0x20, 0x7a, 0x8f, 0x52, 0xfa, 0xfd, 0x89, 0x80, 0xa7, 0x10, 0x26, + 0x96, 0xa2, 0x6b, 0x15, 0xf2, 0x6c, 0x81, 0xa2, 0x90, 0x7c, 0x98, 0x01, + 0xd2, 0x06, 0xd1, 0xf2, 0xbd, 0x10, 0xd3, 0xa7, 0x48, 0xa7, 0xbb, 0x7d, + 0x7e, 0xd2, 0xf6, 0xb6, 0x1e, 0x2e, 0x97, 0xc5, 0x4b, 0xe2, 0x30, 0x60, + 0xac, 0x58, 0x10, 0x36, 0x41, 0x29, 0x52, 0xc5, 0x6c, 0xfa, 0x6e, 0xa0, + 0xbd, 0xe4, 0xe8, 0x30, 0xd3, 0xb8, 0x45, 0x30, 0x85, 0xb3, 0x20, 0xc1, + 0x0f, 0xc0, 0x7c, 0x7e, 0x3e, 0x1f, 0x52, 0xec, 0x9f, 0xc5, 0x5d, 0x6c, + 0x7a, 0x93, 0xdf, 0xea, 0x9f, 0x96, 0x48, 0x1e, 0x03, 0x1b, 0x10, 0x03, + 0xd0, 0x61, 0xa8, 0x7c, 0x06, 0xf2, 0xb1, 0xf2, 0xa4, 0xea, 0xd4, 0xe6, + 0x81, 0xbd, 0xff, 0x1a, 0x96, 0x77, 0x99, 0x10, 0x77, 0x46, 0xc8, 0x41, + 0x18, 0xc4, 0x33, 0xf2, 0x31, 0x00, 0x35, 0x03, 0x81, 0xe8, 0x38, 0x0f, + 0x89, 0x0a, 0x30, 0x7e, 0xd5, 0x52, 0xcf, 0x90, 0x32, 0x6e, 0xc8, 0x22, + 0xb6, 0x0f, 0x97, 0xff, 0xda, 0x60, 0x79, 0xb3, 0x78, 0xa6, 0x18, 0x5b, + 0x38, 0x75, 0xb0, 0x57, 0x03, 0x41, 0x24, 0xb8, 0xbf, 0xec, 0x97, 0x16, + 0xc8, 0xad, 0x52, 0x8d, 0xfb, 0x4b, 0x5b, 0xcf, 0xa2, 0x02, 0x78, 0x05, + 0x70, 0x16, 0xe1, 0x4b, 0x5a, 0x69, 0xb6, 0xae, 0x7c, 0x3a, 0xe7, 0x56, + 0x5a, 0xac, 0x85, 0xc1, 0xf0, 0x19, 0xa0, 0x80, 0x5e, 0x3b, 0x1d, 0xb0, + 0x07, 0x4b, 0xff, 0x0b, 0xa3, 0x1b, 0x1b, 0xf0, 0xe3, 0xc3, 0x86, 0x53, + 0xef, 0x50, 0xa8, 0x1b, 0x60, 0x6a, 0x0c, 0x46, 0x0a, 0x56, 0x95, 0x88, + 0x29, 0x9b, 0x6a, 0xef, 0x34, 0xb3, 0x46, 0xf5, 0x6e, 0xf1, 0x6e, 0xa8, + 0x46, 0x56, 0x56, 0x16, 0x5f, 0xd2, 0xda, 0xa4, 0x12, 0x1c, 0x4c, 0x99, + 0xcc, 0x04, 0x45, 0x54, 0x0c, 0x67, 0x2e, 0xf5, 0x47, 0xf5, 0x7b, 0x64, + 0xab, 0xf2, 0xe9, 0x5e, 0x03, 0x8c, 0x49, 0x7a, 0xa6, 0x87, 0xbe, 0x8a, + 0x6d, 0x53, 0x33, 0xb9, 0xb1, 0x65, 0xc9, 0x43, 0x93, 0x03, 0x44, 0xd9, + 0xbd, 0xf0, 0x37, 0x6c, 0xd5, 0x69, 0x13, 0x4c, 0x2d, 0xf6, 0x71, 0xae, + 0xff, 0x9d, 0x2c, 0xe8, 0xd9, 0x4f, 0x20, 0xd0, 0xbc, 0x1e, 0x96, 0x49, + 0xe5, 0x28, 0x61, 0x2a, 0xc8, 0x60, 0x30, 0x9e, 0xd8, 0x16, 0x2a, 0x63, + 0x95, 0x5f, 0x2f, 0x54, 0x95, 0x7f, 0x7b, 0x1a, 0x49, 0x96, 0xfd, 0x2f, + 0xd1, 0x66, 0x5f, 0x7e, 0x02, 0xb2, 0xa8, 0x02, 0xea, 0x79, 0xbf, 0x02, + 0x9e, 0x16, 0x0b, 0x83, 0xf8, 0xa7, 0x03, 0xdc, 0x5f, 0x3a, 0x6f, 0xb6, + 0x8a, 0xc5, 0x4c, 0x71, 0x3e, 0x7e, 0xf7, 0xb2, 0xf6, 0x6e, 0x71, 0x18, + 0xad, 0x2a, 0x3e, 0xf7, 0x87, 0x16, 0x7a, 0x75, 0x0e, 0x20, 0xb6, 0xc4, + 0x60, 0x8d, 0x21, 0x86, 0x27, 0x32, 0xf5, 0x64, 0x3c, 0x6d, 0x7c, 0xc9, + 0xe1, 0x9c, 0x98, 0x0c, 0x4e, 0x68, 0x18, 0x6f, 0x6a, 0xcd, 0x7e, 0xcb, + 0x8d, 0x54, 0x36, 0x42, 0xc4, 0x7d, 0x0e, 0x34, 0x6e, 0x16, 0x0c, 0x40, + 0xd5, 0xa0, 0xc1, 0xfa, 0xad, 0x51, 0x44, 0x16, 0x3f, 0xcc, 0x44, 0xb5, + 0x8b, 0x76, 0x83, 0x05, 0x52, 0xab, 0x1a, 0x60, 0x79, 0xec, 0xc9, 0x9e, + 0xbe, 0x9b, 0x39, 0xc5, 0x2b, 0xc8, 0x86, 0x88, 0xad, 0xa2, 0x2b, 0x06, + 0x38, 0x70, 0xc5, 0xd8, 0x1a, 0xc4, 0xc3, 0x86, 0xb5, 0x68, 0x56, 0xd7, + 0xb9, 0xbc, 0x93, 0xab, 0xf0, 0xf2, 0x91, 0x33, 0x6a, 0xbf, 0x6c, 0xb3, + 0x64, 0xf5, 0xb8, 0x51, 0xd9, 0x6f, 0xb8, 0x1b, 0x8d, 0xc1, 0x84, 0xda, + 0x33, 0x0b, 0xd2, 0x31, 0xfe, 0x15, 0xaf, 0x91, 0x6e, 0x64, 0xb2, 0xf2, + 0x40, 0xd4, 0x2c, 0xa6, 0xbf, 0x6a, 0x50, 0x34, 0xbd, 0x03, 0x42, 0x08, + 0xe3, 0x54, 0xa1, 0x5a, 0x59, 0x60, 0x6c, 0x36, 0x06, 0x1a, 0xd7, 0xb4, + 0xa8, 0x7c, 0xae, 0xe0, 0x88, 0x9f, 0xfe, 0xbf, 0x35, 0x78, 0xb5, 0x9d, + 0x05, 0xba, 0xc0, 0xab, 0x67, 0xcc, 0xa6, 0xe1, 0x5e, 0x45, 0x0c, 0x32, + 0xa5, 0x19, 0x6f, 0xff, 0xc0, 0x76, 0x72, 0x95, 0x83, 0x10, 0xda, 0x8f, + 0x83, 0x29, 0xc6, 0x6f, 0x07, 0x11, 0xa9, 0x95, 0x7e, 0xec, 0xef, 0x27, + 0x78, 0x27, 0x2f, 0x98, 0x5a, 0x5f, 0x22, 0x89, 0xbc, 0x93, 0x54, 0xa0, + 0x9c, 0x59, 0x60, 0xdc, 0x8e, 0x76, 0x46, 0xa4, 0x6b, 0x59, 0xa9, 0xfc, + 0xb5, 0x9d, 0xea, 0xcb, 0x6a, 0xdd, 0xe8, 0x38, 0xcc, 0x08, 0xdd, 0x4c, + 0x1f, 0xa7, 0xfa, 0x9b, 0x89, 0x59, 0x52, 0x56, 0x8f, 0x85, 0x92, 0x40, + 0xa1, 0x1d, 0x66, 0x66, 0x95, 0x66, 0xae, 0x19, 0x93, 0x9b, 0x2d, 0x57, + 0x7f, 0xf2, 0xde, 0x46, 0xa7, 0x33, 0xd1, 0x4f, 0x6d, 0xa8, 0x7b, 0x06, + 0x40, 0xef, 0x03, 0x11, 0x70, 0xb1, 0x5f, 0xcb, 0xf0, 0x71, 0xdf, 0x54, + 0x70, 0x66, 0x50, 0xe0, 0xfc, 0x0c, 0x10, 0x42, 0x1a, 0x6a, 0x10, 0x34, + 0x75, 0x9b, 0x8c, 0x8f, 0x53, 0xb7, 0x9e, 0x0f, 0x9a, 0xb3, 0x59, 0xcc, + 0x0e, 0xed, 0xff, 0x86, 0xe4, 0x03, 0xfe, 0xfd, 0x17, 0xf1, 0x65, 0x2b, + 0x71, 0x1a, 0xd5, 0x1f, 0x41, 0x2a, 0x1b, 0x08, 0x0c, 0x2a, 0x4e, 0xc9, + 0x78, 0xf9, 0x52, 0xaa, 0xaf, 0xff, 0xff, 0xd5, 0x97, 0x8f, 0xff, 0x36, + 0x35, 0x6c, 0x9d, 0xe5, 0xd1, 0x4c, 0x42, 0xd4, 0x67, 0x1b, 0x0f, 0xcd, + 0x03, 0x60, 0x1d, 0xb7, 0xdb, 0x44, 0xa6, 0x73, 0xdc, 0x96, 0x65, 0xe4, + 0xb6, 0xa3, 0x44, 0x16, 0x82, 0xbc, 0x0e, 0x2a, 0x07, 0x01, 0xe1, 0x19, + 0xa1, 0xf3, 0x0d, 0x34, 0x1f, 0xd0, 0x32, 0x9d, 0xbd, 0xff, 0x32, 0xb3, + 0xf4, 0x70, 0xb2, 0x0d, 0xd4, 0x0d, 0xbc, 0x1e, 0x87, 0x46, 0x01, 0x6e, + 0x59, 0x53, 0x8e, 0x1b, 0xf9, 0x7b, 0x36, 0x2d, 0x98, 0x20, 0x78, 0x40, + 0x48, 0xa7, 0x9b, 0xde, 0x5d, 0xcf, 0x6b, 0x79, 0x99, 0x29, 0x58, 0x31, + 0x15, 0x7b, 0xe3, 0xec, 0xfc, 0x61, 0x85, 0x79, 0xad, 0xa0, 0x0f, 0x6e, + 0xd2, 0x8a, 0x54, 0xa5, 0x48, 0x6c, 0x0c, 0x71, 0xc2, 0xcb, 0xd2, 0x62, + 0xcb, 0x56, 0x6c, 0x52, 0x39, 0xd9, 0x6e, 0xf0, 0xa9, 0x44, 0xcc, 0x5a, + 0x73, 0x9c, 0x1b, 0xe8, 0x30, 0xd4, 0xcc, 0xea, 0xb5, 0x38, 0x5b, 0x58, + 0x6a, 0x22, 0x1c, 0x15, 0x52, 0x8a, 0x1c, 0x18, 0xbb, 0xeb, 0xfe, 0xdd, + 0xe4, 0x1b, 0x96, 0xde, 0x72, 0xf4, 0x92, 0x08, 0x80, 0xe3, 0x2a, 0x8e, + 0x18, 0x4c, 0xa3, 0xad, 0xfd, 0x42, 0xf5, 0x44, 0x8a, 0x54, 0xf1, 0x17, + 0x4a, 0xc9, 0x6e, 0x80, 0x85, 0x73, 0xe9, 0xd6, 0x09, 0x0a, 0xb3, 0xe5, + 0xb2, 0x7f, 0x11, 0xe9, 0x6d, 0x4e, 0xdc, 0x2d, 0xa6, 0xff, 0x30, 0x6f, + 0x9a, 0x1b, 0xfc, 0x1f, 0x22, 0x00, 0x74, 0xc7, 0x09, 0x97, 0x52, 0xda, + 0x1b, 0xfe, 0x2e, 0x59, 0xd5, 0x96, 0x94, 0x6e, 0x65, 0x50, 0x53, 0x97, + 0x62, 0xe0, 0x67, 0xe1, 0xb5, 0xec, 0xce, 0x94, 0x69, 0x50, 0x3e, 0x5f, + 0xff, 0x64, 0x98, 0x6d, 0xa5, 0x79, 0x34, 0x71, 0x4a, 0xb8, 0x4b, 0x8b, + 0xce, 0xf0, 0x55, 0x9e, 0xef, 0x55, 0x9a, 0xe2, 0xaa, 0xa2, 0xa0, 0x83, + 0x8b, 0x44, 0xe6, 0x17, 0x55, 0x9f, 0x66, 0xab, 0xa1, 0xff, 0xfd, 0x03, + 0xcc, 0xc0, 0xf6, 0xd3, 0x50, 0xac, 0x04, 0x4b, 0x31, 0x3b, 0x36, 0x78, + 0x19, 0x12, 0x49, 0x90, 0xad, 0x6d, 0xbb, 0xa8, 0xd1, 0x06, 0xc3, 0x61, + 0x61, 0x6c, 0x68, 0xbb, 0x01, 0x97, 0x99, 0xdf, 0xe0, 0xdc, 0xb5, 0x7d, + 0xec, 0x47, 0x43, 0x64, 0x20, 0x2e, 0xe5, 0xa9, 0x15, 0xab, 0x8d, 0x4d, + 0x06, 0x1c, 0x7f, 0xf3, 0x17, 0xfb, 0x2a, 0xf7, 0xd6, 0xe5, 0xa8, 0x6f, + 0xb0, 0xaf, 0x01, 0xc6, 0x0e, 0x83, 0xc1, 0x7f, 0xc6, 0xdf, 0xef, 0xfd, + 0xac, 0xc5, 0x3c, 0x1c, 0x31, 0x9a, 0x06, 0x98, 0x2c, 0xea, 0xe3, 0x75, + 0x3a, 0xa1, 0x16, 0x03, 0x13, 0x99, 0x06, 0x10, 0x6e, 0xa7, 0xd0, 0x78, + 0x28, 0x05, 0xee, 0xfa, 0x72, 0xb0, 0xce, 0x7e, 0xdf, 0x7e, 0xd4, 0x56, + 0xf9, 0x42, 0x81, 0xb5, 0xa0, 0x24, 0x49, 0xdd, 0x8d, 0x6d, 0x6f, 0xd3, + 0xdc, 0xea, 0x8c, 0xf7, 0x3b, 0xc8, 0xb9, 0x68, 0x6c, 0x89, 0x40, 0x30, + 0x9f, 0x5e, 0x1e, 0x2c, 0x48, 0xd0, 0x1b, 0x92, 0xd1, 0xdb, 0x2c, 0x29, + 0xd0, 0xeb, 0xca, 0xbb, 0xe9, 0x09, 0x2d, 0x11, 0x41, 0xf2, 0x60, 0x07, + 0xe1, 0xfc, 0xcb, 0x56, 0xc0, 0xcd, 0x4e, 0x8a, 0x46, 0xc2, 0x52, 0x5f, + 0x2b, 0xdd, 0x69, 0x85, 0x48, 0xbb, 0xa0, 0xad, 0xde, 0xa1, 0x5e, 0xdb, + 0xb8, 0xa5, 0x42, 0x90, 0x7c, 0xf8, 0x01, 0xc5, 0x6a, 0x43, 0xdf, 0x67, + 0xb3, 0xdd, 0x93, 0xb4, 0x9b, 0x6a, 0x28, 0xbc, 0xa2, 0xb3, 0x7d, 0x56, + 0x88, 0x96, 0x5e, 0xde, 0x70, 0xd8, 0x24, 0x74, 0xe5, 0xcd, 0xfe, 0x5c, + 0x9f, 0x99, 0x94, 0x44, 0x11, 0x78, 0x0c, 0x13, 0xc3, 0x34, 0xaa, 0x96, + 0x5c, 0x2d, 0x81, 0xea, 0x8e, 0xf0, 0x60, 0x1b, 0x29, 0x3e, 0xbf, 0xb5, + 0x94, 0xbe, 0x02, 0x0d, 0xc8, 0x04, 0x4a, 0x89, 0x78, 0x54, 0x57, 0xa6, + 0x25, 0xb3, 0x1e, 0x1e, 0x66, 0x72, 0x5d, 0xdd, 0x2b, 0x5e, 0x23, 0x83, + 0x30, 0x61, 0x39, 0x60, 0x2d, 0x35, 0x65, 0x11, 0x72, 0xda, 0x8a, 0xf0, + 0x91, 0xd2, 0xc3, 0x51, 0x8a, 0x57, 0xa2, 0x0b, 0x77, 0xb5, 0x4d, 0xec, + 0x92, 0x52, 0x04, 0x16, 0xd5, 0x0a, 0x67, 0x56, 0x0f, 0x4d, 0x28, 0x25, + 0x7f, 0xb6, 0xb8, 0x07, 0x08, 0xe2, 0x40, 0x29, 0x8b, 0x87, 0xd8, 0x97, + 0xc0, 0x6f, 0xc9, 0x13, 0x16, 0xfa, 0xad, 0x4b, 0x41, 0x13, 0xd6, 0xf0, + 0x39, 0x47, 0x41, 0x86, 0x81, 0x79, 0xb1, 0xfe, 0x37, 0xf8, 0xc7, 0x97, + 0x9b, 0xde, 0xea, 0x07, 0x8e, 0x02, 0x10, 0x84, 0xde, 0x26, 0xf2, 0x72, + 0xc8, 0xa5, 0x5b, 0x5e, 0xaa, 0x41, 0x51, 0x7d, 0x39, 0x20, 0x8a, 0x36, + 0x90, 0xb4, 0x18, 0x56, 0x26, 0xf2, 0x68, 0xd7, 0x35, 0x1d, 0x58, 0x90, + 0x81, 0x7f, 0x67, 0x64, 0xc4, 0x40, 0xf9, 0x9f, 0xfd, 0xc8, 0x89, 0xcd, + 0x9a, 0xad, 0x46, 0x1a, 0xdf, 0x31, 0x93, 0xcb, 0x22, 0xc2, 0xab, 0xc3, + 0x51, 0x46, 0x15, 0x69, 0xc1, 0xb8, 0x30, 0x81, 0xf6, 0xd3, 0xb6, 0x3f, + 0xfa, 0xa8, 0x5b, 0x79, 0xc5, 0xe6, 0xc9, 0xe8, 0x55, 0x20, 0x70, 0xa4, + 0x1f, 0x5e, 0x00, 0x74, 0x2d, 0x2d, 0xb2, 0x10, 0x08, 0x9b, 0xbc, 0xc5, + 0x11, 0x6e, 0x85, 0x1c, 0x21, 0x43, 0xc5, 0xa8, 0xca, 0x4e, 0x2b, 0x61, + 0x3e, 0xc0, 0x56, 0xf9, 0x4a, 0x84, 0x35, 0x1a, 0x33, 0xf4, 0x9a, 0xdf, + 0xe5, 0xb4, 0xa8, 0xd4, 0x45, 0x4a, 0x4f, 0x53, 0x4a, 0xbd, 0xf2, 0xbf, + 0xf3, 0x54, 0x29, 0x92, 0x58, 0x86, 0xd4, 0x61, 0x55, 0xab, 0xc9, 0x96, + 0x6e, 0x2d, 0x11, 0x70, 0x83, 0x92, 0x1e, 0x6c, 0x34, 0x03, 0x68, 0xec, + 0x14, 0xa3, 0xcc, 0xfb, 0x23, 0xc1, 0xe3, 0x0d, 0xa6, 0xf2, 0x34, 0xf9, + 0xd6, 0xdb, 0xf4, 0x37, 0x53, 0x42, 0xc5, 0x18, 0x88, 0xac, 0x18, 0xe8, + 0x70, 0xba, 0x07, 0xc1, 0x05, 0xba, 0xdb, 0x6d, 0xf6, 0x4d, 0x02, 0xed, + 0xfe, 0x34, 0xd6, 0x6f, 0x51, 0x40, 0xdd, 0x71, 0xb0, 0x7a, 0x2d, 0x13, + 0x8f, 0x75, 0x5b, 0x10, 0x72, 0xc6, 0xc9, 0x33, 0xea, 0x55, 0xe2, 0x85, + 0x23, 0x94, 0xdc, 0xf9, 0x6f, 0xa4, 0x0e, 0x51, 0x0d, 0x01, 0x76, 0xa8, + 0x7c, 0x07, 0x84, 0x7d, 0x05, 0x3a, 0x46, 0x34, 0xb9, 0x5c, 0x59, 0xae, + 0xac, 0x91, 0x8f, 0xf0, 0x3b, 0xf4, 0xc0, 0x56, 0x63, 0x62, 0x2a, 0x90, + 0xec, 0x04, 0xd8, 0xd7, 0xe9, 0x5f, 0x43, 0xc0, 0x62, 0x17, 0xd9, 0x4d, + 0x9c, 0x4c, 0x17, 0x60, 0x18, 0x91, 0x38, 0xe9, 0x23, 0x0c, 0x0e, 0x7a, + 0x55, 0x83, 0x91, 0x07, 0xff, 0xda, 0xa7, 0x8b, 0xc2, 0xb1, 0xb6, 0x60, + 0x71, 0x80, 0x28, 0x64, 0xd2, 0xbe, 0x35, 0xcb, 0x65, 0x24, 0x9d, 0x99, + 0xd0, 0x61, 0xa8, 0xb9, 0x20, 0x3c, 0x1f, 0xfc, 0xaa, 0x82, 0x11, 0x7b, + 0x4d, 0xea, 0x74, 0xea, 0x59, 0x10, 0x7d, 0x14, 0xe7, 0x95, 0x78, 0x15, + 0x22, 0x26, 0x29, 0xe6, 0x28, 0x06, 0x21, 0x28, 0xac, 0x75, 0x7b, 0xd6, + 0x38, 0x22, 0x42, 0xc4, 0x59, 0xc8, 0x72, 0x6a, 0xc8, 0x42, 0xd4, 0x4d, + 0x3e, 0x95, 0x16, 0xcb, 0xd0, 0xe6, 0x14, 0xa3, 0xa7, 0xcc, 0xe5, 0x69, + 0xbd, 0xb8, 0x8b, 0x57, 0x44, 0xb1, 0xde, 0x3c, 0xf4, 0xf2, 0x75, 0x6d, + 0x7f, 0x9f, 0x93, 0xd0, 0x92, 0x2f, 0xce, 0xb9, 0x0c, 0x12, 0x95, 0x79, + 0x3b, 0x4a, 0xe1, 0x52, 0x8d, 0x29, 0x95, 0x67, 0xb6, 0x91, 0xcb, 0xe3, + 0xe6, 0x3c, 0xab, 0xaa, 0x3f, 0xfb, 0x3f, 0x2f, 0xef, 0x61, 0x57, 0x61, + 0x2a, 0x91, 0xb9, 0x95, 0xc1, 0x56, 0x06, 0xfe, 0x20, 0x26, 0xda, 0x5b, + 0xed, 0x2c, 0x56, 0x8c, 0x0c, 0x52, 0xcc, 0xa1, 0xc1, 0x59, 0x50, 0xb5, + 0x12, 0xff, 0x8e, 0x39, 0x3d, 0xb9, 0x85, 0xa5, 0x44, 0xbd, 0xb2, 0xa2, + 0x0e, 0x0c, 0x9d, 0x48, 0x25, 0x7c, 0xbb, 0x15, 0x4f, 0x37, 0x77, 0x2e, + 0xb3, 0xa9, 0xf5, 0xbd, 0xad, 0xfd, 0x9d, 0xbc, 0x91, 0x7d, 0xd1, 0x10, + 0xf2, 0x16, 0xda, 0x2b, 0x35, 0xfd, 0x0e, 0x2e, 0x72, 0xff, 0x46, 0xfb, + 0xfe, 0x2e, 0x0c, 0x26, 0x55, 0x26, 0x66, 0x28, 0xea, 0x2f, 0x96, 0xd8, + 0x82, 0xcc, 0xbc, 0x92, 0x70, 0x38, 0x58, 0x12, 0x64, 0x7e, 0xd4, 0x6d, + 0xaf, 0xfb, 0xb6, 0x73, 0x24, 0xc4, 0x01, 0xec, 0x2b, 0x07, 0x08, 0x82, + 0x7f, 0xcf, 0x2b, 0x69, 0x53, 0x68, 0x5a, 0x58, 0x97, 0xa4, 0xe8, 0x2d, + 0x4f, 0x91, 0xd9, 0x5c, 0xc1, 0xc5, 0x0f, 0xb2, 0x4d, 0xf4, 0xf5, 0xb1, + 0x07, 0x3f, 0x2b, 0x86, 0x83, 0xcd, 0xc8, 0xcf, 0xb3, 0xea, 0x0b, 0x6d, + 0xd5, 0x35, 0x0c, 0x93, 0x96, 0xda, 0x1a, 0xed, 0x06, 0x05, 0xc2, 0xe3, + 0xd6, 0xea, 0x6f, 0xe6, 0xcd, 0xa3, 0x60, 0xeb, 0x9c, 0x9a, 0x33, 0x52, + 0x55, 0xaa, 0x41, 0x2d, 0x7d, 0x4c, 0x0f, 0x05, 0xff, 0x1b, 0x25, 0xed, + 0x7b, 0x1b, 0xf7, 0x94, 0x33, 0x73, 0xd6, 0x29, 0xec, 0x6a, 0xdb, 0xd1, + 0x17, 0x14, 0x6f, 0x00, 0xa0, 0x31, 0x19, 0x87, 0x5a, 0xdf, 0xd5, 0x74, + 0x7a, 0xda, 0x6f, 0x6c, 0xbf, 0xfe, 0xe6, 0xe7, 0xec, 0x2a, 0xc5, 0x5e, + 0x47, 0xe0, 0xd7, 0x3a, 0x0f, 0x91, 0xff, 0xd8, 0xa5, 0xa1, 0xbb, 0x70, + 0x73, 0x37, 0xeb, 0x68, 0x80, 0x83, 0x32, 0x01, 0x0a, 0x27, 0x14, 0xaa, + 0xb8, 0xaf, 0x85, 0xe5, 0x93, 0x0b, 0x24, 0x53, 0x54, 0xc1, 0xb5, 0x92, + 0xbc, 0xdb, 0x73, 0xf9, 0xfa, 0xdf, 0xbe, 0xd6, 0x35, 0xf5, 0x00, 0xad, + 0x11, 0x4b, 0x22, 0xf6, 0x40, 0xd4, 0xc7, 0x2c, 0xc7, 0xc7, 0x2c, 0xff, + 0x7b, 0xb7, 0x18, 0x59, 0x41, 0x65, 0x50, 0xdd, 0x5a, 0xf7, 0xb4, 0x2c, + 0x37, 0x1b, 0x2c, 0xcb, 0xce, 0x66, 0x4d, 0xaa, 0x3b, 0x7b, 0x6f, 0x3a, + 0xb5, 0xbb, 0x8a, 0x54, 0x82, 0xdd, 0x46, 0xcb, 0xd8, 0x43, 0xf5, 0xf1, + 0x71, 0xb7, 0x2a, 0x84, 0x4b, 0x45, 0x23, 0x64, 0x65, 0x78, 0x68, 0xc9, + 0x86, 0xf8, 0xaf, 0x3c, 0xad, 0x54, 0xdd, 0xfe, 0x6e, 0xe7, 0xae, 0xc2, + 0xc4, 0xd1, 0x18, 0x77, 0xed, 0x07, 0x07, 0x86, 0x7e, 0xd4, 0xea, 0xb6, + 0x54, 0xdd, 0xe3, 0x0d, 0x22, 0x9a, 0x8a, 0x2e, 0x6b, 0xe2, 0x2e, 0x86, + 0xe0, 0xf9, 0x3f, 0xfd, 0x93, 0x10, 0x07, 0x57, 0x7c, 0x0f, 0x09, 0xff, + 0x9f, 0xd8, 0xef, 0x26, 0xf5, 0xbc, 0x52, 0x86, 0xf2, 0x61, 0x5e, 0x91, + 0xa6, 0xd3, 0x0d, 0xe2, 0x9d, 0x2f, 0x4f, 0x2f, 0x87, 0x13, 0x8d, 0x62, + 0x29, 0x27, 0x03, 0xd0, 0xd7, 0x4c, 0x25, 0x0b, 0x56, 0xfb, 0x1b, 0x26, + 0x40, 0x61, 0x11, 0x8e, 0x77, 0xa8, 0xa4, 0x66, 0xa9, 0x2b, 0xd0, 0xd8, + 0x3c, 0x07, 0xc7, 0xff, 0xee, 0xbd, 0xfa, 0x3a, 0xcd, 0x67, 0xec, 0x97, + 0xc0, 0x30, 0xc1, 0x53, 0x1e, 0x9f, 0xb9, 0xe5, 0x11, 0x72, 0xce, 0x60, + 0x88, 0x0b, 0x65, 0x34, 0x7a, 0x3e, 0xf7, 0x71, 0xac, 0xf6, 0x6f, 0xf9, + 0x0a, 0xa1, 0x64, 0xea, 0x00, 0xf7, 0x46, 0xfb, 0xa3, 0x75, 0x00, 0xfa, + 0x1f, 0xfd, 0xa9, 0x27, 0xf6, 0xe8, 0x7f, 0x6d, 0x94, 0x3c, 0x1c, 0x71, + 0x4f, 0x62, 0x25, 0xa2, 0x90, 0x5a, 0xa3, 0xf6, 0x18, 0x68, 0x3d, 0xad, + 0x49, 0x72, 0x49, 0x8d, 0x6f, 0x14, 0x62, 0xc8, 0xdc, 0xbd, 0x98, 0x61, + 0x32, 0xbf, 0xd2, 0xd2, 0xfd, 0xaa, 0x24, 0x8a, 0x3d, 0xb6, 0xcf, 0x14, + 0xdf, 0x07, 0x01, 0xb0, 0x3e, 0x6c, 0x00, 0xe9, 0xa5, 0xa5, 0xc0, 0x63, + 0xcd, 0xb7, 0xbb, 0xb6, 0x55, 0x1e, 0xc5, 0xa5, 0x9d, 0x40, 0x1c, 0x18, + 0x58, 0x41, 0x6d, 0x5c, 0x0e, 0x31, 0x4a, 0xe8, 0x67, 0x17, 0x20, 0x5d, + 0xa6, 0xb4, 0x72, 0xa5, 0x1c, 0xce, 0xc9, 0xfd, 0x5f, 0x6d, 0xea, 0x00, + 0x63, 0x46, 0x25, 0x2f, 0x52, 0xe5, 0x56, 0xc6, 0xee, 0xcd, 0xf4, 0xce, + 0xdc, 0x9d, 0xde, 0x54, 0x1d, 0x53, 0xa0, 0xc0, 0x92, 0xaf, 0x9b, 0x66, + 0xf0, 0xb1, 0x54, 0xcf, 0x5f, 0xa8, 0xf7, 0xaf, 0x32, 0x28, 0x02, 0x36, + 0xe8, 0x8a, 0xa6, 0x05, 0x85, 0x9a, 0x8d, 0xcd, 0xa8, 0xf9, 0x01, 0x19, + 0x61, 0x5a, 0xc9, 0xcb, 0xb5, 0xb2, 0xcf, 0xeb, 0x7b, 0xb3, 0x3f, 0x37, + 0x4b, 0x1b, 0xfe, 0x62, 0x1e, 0xf3, 0xc1, 0xab, 0xf5, 0x23, 0xb4, 0x8b, + 0xee, 0xe2, 0x3f, 0xa8, 0x43, 0xcf, 0x59, 0xce, 0xca, 0x1b, 0x03, 0x05, + 0x26, 0x1a, 0x64, 0x7f, 0x7d, 0x7c, 0xc3, 0x5e, 0xcf, 0x40, 0x64, 0x36, + 0xdd, 0xbc, 0xec, 0xed, 0xa1, 0xce, 0x99, 0x54, 0x40, 0x41, 0xcd, 0x8b, + 0xaf, 0x36, 0xaf, 0xc4, 0x00, 0xc3, 0x52, 0x65, 0x9a, 0x58, 0x54, 0xa3, + 0x80, 0xed, 0x90, 0xd7, 0x01, 0x82, 0x7b, 0x4b, 0x32, 0x3f, 0x4a, 0xc8, + 0xf1, 0x5f, 0xbe, 0x0a, 0xd4, 0xfd, 0xd9, 0xe6, 0x3c, 0xc7, 0x3c, 0xd6, + 0x6d, 0x95, 0x1d, 0xa1, 0xce, 0xf0, 0x15, 0xc1, 0x69, 0xec, 0x2f, 0x65, + 0xbe, 0xf9, 0x5a, 0x42, 0xcc, 0x5a, 0x71, 0x7d, 0xb5, 0x60, 0x46, 0x50, + 0x1b, 0x81, 0x52, 0xa0, 0x62, 0x25, 0xe6, 0x15, 0xe4, 0xaa, 0x6e, 0xd8, + 0x05, 0x45, 0x0b, 0x55, 0x51, 0x4e, 0x36, 0xda, 0xdc, 0xea, 0x25, 0xfb, + 0x5f, 0x1e, 0x99, 0x2c, 0xa7, 0xa6, 0x31, 0x8a, 0x18, 0xf1, 0x67, 0x51, + 0x7b, 0xd8, 0x22, 0x92, 0xc0, 0x5a, 0x18, 0x4d, 0x35, 0x8a, 0xdb, 0x6c, + 0xfd, 0x47, 0xd9, 0xb3, 0xd9, 0xeb, 0x7a, 0x59, 0x64, 0xb1, 0x68, 0x80, + 0x85, 0x34, 0xd4, 0x71, 0x4a, 0xb2, 0xa8, 0xce, 0xf7, 0x4d, 0x9f, 0x51, + 0xbe, 0x8e, 0x73, 0x54, 0x5d, 0x81, 0xc4, 0x58, 0xf4, 0xcf, 0xd9, 0x54, + 0x8a, 0x9a, 0xd2, 0xdb, 0xab, 0x6e, 0x77, 0x3b, 0x6c, 0xed, 0x80, 0xe2, + 0xa0, 0x5a, 0xc6, 0x79, 0xbb, 0x4b, 0x3d, 0xef, 0x56, 0xb2, 0xa1, 0x0e, + 0x01, 0xc5, 0x60, 0xb5, 0x86, 0xbd, 0xab, 0xd8, 0xa2, 0x29, 0x84, 0x8b, + 0x52, 0x52, 0xa1, 0x4e, 0x89, 0x95, 0xf3, 0x69, 0x6d, 0xb9, 0x7b, 0x6a, + 0x81, 0xb1, 0xef, 0xb4, 0x8b, 0x33, 0xda, 0xbf, 0xed, 0xb1, 0x02, 0x3e, + 0x0a, 0xb7, 0xed, 0x59, 0x44, 0x51, 0xef, 0xad, 0xc8, 0x8e, 0x93, 0xce, + 0x6b, 0x18, 0x1d, 0x7a, 0xb7, 0xf2, 0x51, 0xb0, 0x9d, 0x16, 0x8b, 0x68, + 0x7b, 0xbb, 0x32, 0x20, 0xf6, 0x1a, 0x27, 0xbb, 0x00, 0x00, 0xb2, 0x08, + 0x2c, 0x2d, 0x8f, 0x37, 0xa3, 0xa1, 0x28, 0x90, 0x74, 0x5d, 0x01, 0xe2, + 0xa0, 0x0d, 0x16, 0x27, 0x77, 0x8a, 0x68, 0xa5, 0x31, 0x23, 0x80, 0xc2, + 0x00, 0xeb, 0xa0, 0xf0, 0xb0, 0x0b, 0x97, 0x03, 0xc5, 0xc0, 0x1a, 0x2c, + 0x5d, 0x2b, 0x60, 0xe1, 0x99, 0x00, 0xb8, 0xa6, 0x10, 0x26, 0x66, 0x6a, + 0x3b, 0x56, 0x26, 0x6b, 0xff, 0x45, 0x2b, 0x12, 0x21, 0xb7, 0x9c, 0x25, + 0x26, 0x2c, 0xa2, 0x64, 0x43, 0x03, 0x3f, 0x94, 0x86, 0xc0, 0xb6, 0x43, + 0xea, 0x99, 0x26, 0xb9, 0x03, 0xc4, 0x7c, 0xee, 0xfe, 0xa0, 0x94, 0xab, + 0x0f, 0x19, 0x56, 0x8d, 0xed, 0x32, 0x2b, 0x79, 0x33, 0xa5, 0x52, 0x20, + 0xe4, 0x5c, 0x1c, 0xa5, 0xea, 0x37, 0xf9, 0x3f, 0x72, 0xd2, 0xb5, 0xc2, + 0x95, 0x74, 0x6c, 0xfe, 0xf1, 0x7e, 0x8a, 0xcc, 0xa6, 0x03, 0x89, 0x9b, + 0x12, 0x19, 0x54, 0x56, 0x1e, 0x0e, 0xe8, 0xfe, 0x6a, 0xf9, 0x79, 0x7f, + 0xda, 0xd7, 0xae, 0x68, 0x70, 0x02, 0x14, 0x4b, 0xfc, 0xf0, 0x73, 0xba, + 0x83, 0x3d, 0x3b, 0x78, 0x6c, 0x1c, 0x60, 0xf3, 0x02, 0x58, 0xed, 0xb4, + 0xac, 0x8f, 0x15, 0x66, 0x87, 0xd5, 0x46, 0xa9, 0xea, 0xf1, 0x98, 0x1e, + 0xfa, 0x74, 0x6c, 0x1f, 0x6f, 0x03, 0xdc, 0xd0, 0xef, 0xc0, 0xc4, 0xc2, + 0xfe, 0x01, 0x76, 0xbd, 0x32, 0x38, 0x39, 0xf7, 0xec, 0x2a, 0x51, 0x9d, + 0xde, 0xdd, 0x92, 0xcc, 0x97, 0x9c, 0xaa, 0x44, 0x4c, 0xe4, 0x05, 0x78, + 0x08, 0x16, 0x2a, 0x2f, 0xd5, 0x78, 0xa3, 0xd3, 0x7a, 0xb1, 0x5d, 0x85, + 0x4b, 0xc5, 0xb9, 0x41, 0x2c, 0x48, 0xa8, 0x0f, 0x2a, 0x03, 0xe9, 0x18, + 0x6c, 0x76, 0xca, 0xb1, 0xcb, 0x0a, 0x47, 0x2c, 0x30, 0xac, 0x15, 0x97, + 0xfd, 0x5e, 0x27, 0x8d, 0x15, 0x6e, 0x2d, 0x00, 0x45, 0x97, 0x08, 0x38, + 0x5b, 0x03, 0xea, 0xd2, 0xa6, 0xbb, 0x8a, 0x4b, 0x65, 0x9f, 0xc9, 0x16, + 0xbe, 0xf6, 0x62, 0x98, 0xd2, 0x22, 0xc5, 0x21, 0xe8, 0x30, 0xa8, 0xd5, + 0xbb, 0x5c, 0xe9, 0xbc, 0x06, 0x5b, 0xeb, 0xd5, 0x2d, 0xf2, 0x07, 0xfa, + 0x80, 0xc2, 0x17, 0x54, 0xa1, 0xef, 0x51, 0x0a, 0x08, 0x97, 0x35, 0xef, + 0x4d, 0xfc, 0xc2, 0xb4, 0xf6, 0x7d, 0x9a, 0x8f, 0xb7, 0x9c, 0xf4, 0x0d, + 0x02, 0xc6, 0x97, 0xdf, 0x03, 0x01, 0xf5, 0x9e, 0x0f, 0x62, 0x99, 0xc5, + 0xb6, 0x2f, 0xd8, 0x04, 0xc6, 0xe2, 0x6b, 0x5f, 0x1b, 0xa6, 0x07, 0xcc, + 0x48, 0xd4, 0xd6, 0xdb, 0xff, 0xf3, 0xbb, 0x23, 0x7a, 0xa7, 0xb6, 0xf5, + 0x70, 0x46, 0xaa, 0x14, 0x01, 0x03, 0x0b, 0x88, 0x6a, 0xc1, 0xb8, 0x98, + 0x72, 0xa3, 0xff, 0xbe, 0x51, 0x3c, 0xa9, 0xa8, 0xa6, 0xdb, 0x6f, 0x24, + 0x9e, 0x11, 0x77, 0x76, 0x85, 0x91, 0x0a, 0xd4, 0x51, 0xb6, 0xa0, 0x21, + 0xa6, 0x79, 0x5b, 0x81, 0xe2, 0x96, 0xe5, 0xa5, 0x88, 0x03, 0x6e, 0xb9, + 0xc2, 0xd7, 0x3e, 0xdc, 0xb0, 0x9b, 0x4b, 0xf6, 0x0e, 0x7b, 0x2a, 0x89, + 0x7f, 0xe4, 0x45, 0x9b, 0x50, 0x15, 0x15, 0x03, 0x02, 0x67, 0xf6, 0x08, + 0x1a, 0x5e, 0x3e, 0xd0, 0xeb, 0xd2, 0xb3, 0xe1, 0xaa, 0x69, 0xba, 0xc1, + 0x6a, 0x92, 0xbb, 0x7a, 0x53, 0xd3, 0xe3, 0x96, 0x44, 0xbc, 0x81, 0x0d, + 0xb6, 0xb7, 0xdf, 0x9f, 0xbe, 0xca, 0x88, 0xab, 0xea, 0x97, 0xc5, 0xa8, + 0x8a, 0xa3, 0x90, 0x05, 0xdd, 0xbd, 0x80, 0xe3, 0x0e, 0xdc, 0x39, 0x66, + 0x84, 0x9c, 0xd4, 0xe9, 0x98, 0x67, 0xc5, 0x7e, 0xf6, 0x5b, 0x60, 0x8a, + 0x89, 0x6e, 0x50, 0xe5, 0x49, 0xe3, 0x23, 0xc2, 0xd8, 0x25, 0xd2, 0xdc, + 0xb8, 0xa6, 0x42, 0xd3, 0x5b, 0x95, 0xa9, 0xd9, 0x60, 0x88, 0x02, 0x57, + 0x56, 0x5e, 0xca, 0xa4, 0x89, 0x4a, 0xa2, 0x91, 0xf3, 0x2a, 0xbf, 0xe1, + 0x13, 0xaa, 0x99, 0xa1, 0xe0, 0x11, 0x2b, 0xc3, 0x14, 0x3b, 0xd2, 0xdc, + 0xc1, 0xd9, 0x75, 0x2a, 0x4b, 0x98, 0x20, 0x9b, 0xce, 0x45, 0xef, 0x43, + 0x9d, 0xd8, 0xa0, 0x18, 0x4c, 0x68, 0xc5, 0x95, 0x2e, 0x67, 0x01, 0x4c, + 0xa7, 0x18, 0xfc, 0xef, 0xff, 0x88, 0x3b, 0x27, 0xba, 0x8e, 0x0d, 0xca, + 0xf8, 0x09, 0x0a, 0x33, 0xef, 0x6c, 0xd8, 0xdc, 0x6d, 0x45, 0x99, 0xa1, + 0xe2, 0xda, 0xb2, 0xd6, 0x50, 0xe3, 0x17, 0x07, 0xc9, 0xff, 0xed, 0x66, + 0x19, 0xab, 0x7b, 0x7b, 0xcc, 0xb0, 0x15, 0xeb, 0x72, 0xde, 0x40, 0xdf, + 0xa0, 0x92, 0x5d, 0x56, 0x01, 0xb6, 0x62, 0x85, 0xa7, 0x69, 0x2c, 0x51, + 0xea, 0x8c, 0x0a, 0x03, 0x83, 0x73, 0x1c, 0x2c, 0xb8, 0x2a, 0x98, 0xc1, + 0xc3, 0x38, 0xd2, 0x76, 0x65, 0xc8, 0xa1, 0xa9, 0xe9, 0x93, 0xb6, 0x2c, + 0x06, 0xff, 0x85, 0x7b, 0x98, 0x0b, 0x55, 0x7e, 0xa5, 0xa9, 0xd5, 0x72, + 0x34, 0x1c, 0x7b, 0xc5, 0x70, 0x92, 0x83, 0x10, 0x09, 0x43, 0xd5, 0xb2, + 0x49, 0x32, 0xc5, 0xea, 0x10, 0x60, 0x4f, 0x0c, 0x40, 0x82, 0xac, 0x14, + 0xdd, 0xeb, 0x5d, 0x99, 0xcd, 0x10, 0x75, 0x7c, 0x97, 0xf6, 0xe7, 0xbd, + 0xc0, 0x5a, 0xf9, 0xe2, 0xd5, 0x8a, 0x19, 0xf5, 0xa5, 0x6b, 0xca, 0x57, + 0x45, 0x67, 0xf1, 0xa4, 0xbe, 0x82, 0x03, 0x45, 0xa5, 0x93, 0xa5, 0x51, + 0x7b, 0x57, 0x42, 0x0b, 0x53, 0x4d, 0x0f, 0x61, 0x7b, 0x19, 0x27, 0xe7, + 0xe1, 0xb5, 0x9a, 0x53, 0x22, 0x3b, 0xcd, 0x05, 0xa1, 0x2c, 0x6c, 0x70, + 0xc2, 0xde, 0xfa, 0x9d, 0x2b, 0x2c, 0xc8, 0x5a, 0x86, 0xc0, 0xef, 0x04, + 0x50, 0x4b, 0xda, 0xf5, 0xc5, 0xd7, 0x99, 0x4b, 0xef, 0xef, 0xbf, 0x32, + 0x32, 0xa4, 0x3c, 0xcf, 0x52, 0xdd, 0xc8, 0x6e, 0x86, 0xa0, 0xb4, 0x21, + 0x62, 0x55, 0x4a, 0xbd, 0x2f, 0xb1, 0x2e, 0x95, 0xee, 0xea, 0xc5, 0xb3, + 0xf4, 0xd2, 0x90, 0x5a, 0x6a, 0xd8, 0xe1, 0xa5, 0x2d, 0xfb, 0x8c, 0xfe, + 0x95, 0x60, 0x8a, 0x87, 0x94, 0x37, 0x07, 0x19, 0xbf, 0x6b, 0x65, 0x80, + 0xad, 0x8a, 0x36, 0xad, 0x31, 0x4f, 0x14, 0x44, 0x6b, 0x95, 0x02, 0x4a, + 0xd3, 0xf7, 0x5e, 0xfa, 0x99, 0x9e, 0x2b, 0x9d, 0xc9, 0xdd, 0x2c, 0xa3, + 0x7e, 0x23, 0xe2, 0x95, 0x18, 0x16, 0xb0, 0x65, 0xd4, 0x5e, 0x28, 0x9b, + 0x11, 0x62, 0x9e, 0xd3, 0xdd, 0xbd, 0x5f, 0x9d, 0xa1, 0xa6, 0x2d, 0x05, + 0x69, 0xe3, 0x55, 0x65, 0xa0, 0xcc, 0xae, 0x70, 0x57, 0xe5, 0xa4, 0xc5, + 0xfe, 0xfa, 0x68, 0xe2, 0xf9, 0xbc, 0xb1, 0x1a, 0xf6, 0xec, 0x47, 0x78, + 0x36, 0xc0, 0xb6, 0xb5, 0x2a, 0x8e, 0x4c, 0x10, 0x4b, 0x57, 0x0f, 0x31, + 0x12, 0xe8, 0xab, 0xca, 0x15, 0xf1, 0x6e, 0x5a, 0x4a, 0x70, 0xd3, 0x78, + 0xae, 0x01, 0x8f, 0xec, 0x5e, 0x75, 0x15, 0xd8, 0x50, 0x73, 0xaf, 0xbb, + 0xf2, 0xda, 0x57, 0x2a, 0x9a, 0x8d, 0x48, 0x77, 0x68, 0x2a, 0x46, 0x10, + 0x69, 0x15, 0x75, 0x89, 0x8e, 0xc6, 0xb9, 0x6f, 0x51, 0x92, 0x2c, 0x44, + 0x86, 0x5e, 0x5e, 0xcc, 0xa1, 0x95, 0xb4, 0xd8, 0x38, 0xc4, 0x6b, 0xf7, + 0xa8, 0x26, 0x96, 0x08, 0xb6, 0x23, 0x28, 0x06, 0x08, 0x92, 0xce, 0xcc, + 0x0f, 0x3d, 0x2e, 0x81, 0x49, 0xcb, 0x2f, 0x09, 0x68, 0x25, 0x3a, 0xd3, + 0x3f, 0xe5, 0x46, 0x6e, 0x11, 0x6f, 0x16, 0xf5, 0x4f, 0xff, 0x4d, 0x23, + 0xe8, 0xc8, 0xf7, 0x2d, 0x4b, 0xaa, 0x6c, 0x9b, 0x81, 0xea, 0x18, 0xa7, + 0xb9, 0xd0, 0x60, 0x9e, 0x07, 0x0d, 0xde, 0xc1, 0xb6, 0x1a, 0x84, 0x45, + 0xaf, 0xf2, 0x77, 0x77, 0x7d, 0xef, 0x40, 0x23, 0x7d, 0x96, 0xf4, 0x09, + 0x9c, 0x1b, 0x8e, 0xc1, 0x99, 0x00, 0xe1, 0x1a, 0x6c, 0xd1, 0x2d, 0x51, + 0x6f, 0x68, 0x78, 0xab, 0xa9, 0xfe, 0x8a, 0xf0, 0x0b, 0x16, 0xe6, 0x29, + 0xd0, 0xe4, 0x05, 0x58, 0xda, 0x78, 0x3e, 0xc8, 0x8d, 0xb5, 0xa8, 0x70, + 0x8d, 0x72, 0x7d, 0x8d, 0x34, 0xaa, 0x95, 0x5f, 0xde, 0x23, 0x36, 0x78, + 0x30, 0xf8, 0x18, 0x10, 0xf0, 0x7f, 0x3c, 0xc2, 0xa2, 0xea, 0x1f, 0xfc, + 0x6e, 0x20, 0xb7, 0x77, 0x3c, 0x32, 0xcc, 0xf0, 0xe4, 0x1f, 0x2a, 0x00, + 0x71, 0x88, 0x86, 0x0c, 0x1f, 0x89, 0x39, 0x41, 0xe0, 0xbf, 0xe9, 0x56, + 0x81, 0x43, 0x59, 0xa3, 0x86, 0x96, 0x45, 0x2f, 0x9a, 0x51, 0xd0, 0x71, + 0x91, 0x6f, 0x24, 0xfb, 0x7e, 0x53, 0x80, 0x24, 0xac, 0x55, 0xff, 0x91, + 0x36, 0x38, 0x03, 0xa0, 0xc3, 0xb0, 0x38, 0x07, 0x80, 0xc6, 0x5c, 0x4e, + 0x5e, 0x85, 0x53, 0x1c, 0xb7, 0x28, 0x2a, 0x7f, 0x8a, 0x73, 0x35, 0x60, + 0x48, 0x06, 0x10, 0x41, 0x06, 0x12, 0xc0, 0x3c, 0x47, 0x6f, 0x9e, 0xfd, + 0x1e, 0x24, 0xe9, 0x53, 0x4c, 0x2d, 0xbc, 0xed, 0x0e, 0xd9, 0x1b, 0xd2, + 0xa0, 0xe0, 0xb3, 0xc0, 0xc2, 0xa0, 0xd8, 0xc0, 0x1c, 0x67, 0xff, 0xfe, + 0x6d, 0x2c, 0x50, 0x22, 0xa3, 0xaf, 0xe9, 0x44, 0x8a, 0x5d, 0x3b, 0x1b, + 0xbf, 0x17, 0x51, 0x80, 0x2d, 0x28, 0x7c, 0xaf, 0x8a, 0x6b, 0x5f, 0xc8, + 0x60, 0xa1, 0x03, 0x70, 0x81, 0xb0, 0xdc, 0x0f, 0x03, 0xfd, 0x8b, 0x0c, + 0x26, 0x68, 0x78, 0x3c, 0x54, 0xd8, 0xf4, 0xbd, 0x21, 0x73, 0x0d, 0x7e, + 0x28, 0xbe, 0x69, 0xaf, 0xc6, 0xa7, 0xa4, 0xbf, 0x1b, 0xe9, 0x5c, 0xa3, + 0x62, 0x63, 0x43, 0xf0, 0x43, 0xd6, 0x1a, 0x00, 0xcd, 0x1f, 0xfe, 0xc6, + 0xdb, 0x67, 0xca, 0xd5, 0x96, 0x45, 0x96, 0x9b, 0x3e, 0x1a, 0x35, 0x9b, + 0x46, 0xc0, 0x28, 0x38, 0x09, 0x1a, 0x9e, 0x78, 0x20, 0xc4, 0xd9, 0xdd, + 0xf8, 0x96, 0x9d, 0x4f, 0x67, 0x33, 0x92, 0xc0, 0x2a, 0x6f, 0x17, 0x01, + 0x06, 0x44, 0x76, 0xd8, 0x57, 0xf1, 0xf7, 0xae, 0xff, 0x59, 0xe6, 0x31, + 0xb2, 0xd5, 0xfd, 0xe2, 0xd8, 0x5b, 0x38, 0x22, 0x6e, 0xf5, 0x40, 0x2b, + 0x82, 0xd2, 0xe2, 0xee, 0x3f, 0x34, 0xe5, 0x85, 0x14, 0x9c, 0xd0, 0x65, + 0xe7, 0x37, 0x39, 0x0b, 0x34, 0x44, 0xbd, 0x5c, 0xb6, 0x06, 0xca, 0x38, + 0x0c, 0x35, 0x75, 0x47, 0x6e, 0xf6, 0xed, 0x5c, 0xa0, 0x4c, 0x0a, 0x35, + 0x58, 0xa1, 0x8c, 0xf7, 0xa7, 0x33, 0xd0, 0xab, 0x09, 0x08, 0x2a, 0x90, + 0x30, 0xba, 0x6a, 0xb5, 0xfe, 0x70, 0x97, 0x82, 0x63, 0xc3, 0xfd, 0xea, + 0x5d, 0x52, 0x8b, 0xa4, 0x6b, 0xf5, 0x77, 0x0d, 0x93, 0xa5, 0xb5, 0xb5, + 0x7b, 0x92, 0xed, 0x9d, 0x0f, 0x11, 0xdb, 0x62, 0x28, 0x08, 0xe7, 0x9a, + 0xc2, 0x28, 0x98, 0xf5, 0x29, 0x72, 0x4f, 0x84, 0x3e, 0x55, 0x7f, 0xdf, + 0x8f, 0xeb, 0x1e, 0xac, 0x2f, 0x67, 0xd3, 0x7b, 0xdd, 0xfa, 0xa2, 0xa0, + 0x2c, 0xd2, 0x2d, 0xfe, 0xe8, 0x77, 0xf5, 0x01, 0xe8, 0x31, 0x00, 0x83, + 0xd1, 0x33, 0x0c, 0x4f, 0x31, 0xe9, 0xe9, 0x88, 0x9a, 0x40, 0x8b, 0x88, + 0x86, 0xca, 0x14, 0x3c, 0x2e, 0xaa, 0xc6, 0xbd, 0x99, 0xd1, 0xc6, 0xa5, + 0x9e, 0xa2, 0x0a, 0xbf, 0x64, 0xbc, 0xb5, 0x1f, 0xa7, 0xc3, 0x80, 0xb5, + 0x95, 0x32, 0x8d, 0x6d, 0x5e, 0x0c, 0x29, 0xea, 0x88, 0x51, 0xb6, 0x32, + 0x06, 0x04, 0x41, 0x24, 0x7f, 0xff, 0x2a, 0x1d, 0x0f, 0xf0, 0x4a, 0x12, + 0x94, 0xe5, 0x64, 0xb0, 0xb6, 0x33, 0x2a, 0xe1, 0xe3, 0x0a, 0x14, 0x15, + 0x68, 0x73, 0xbf, 0xff, 0x80, 0x40, 0x4f, 0x55, 0xe0, 0x44, 0x63, 0xca, + 0x94, 0xeb, 0x79, 0x24, 0xef, 0xfe, 0xbe, 0xfe, 0xf3, 0x9d, 0x78, 0x5b, + 0x12, 0x22, 0x8f, 0x2e, 0x87, 0x83, 0x17, 0x26, 0x87, 0x68, 0x31, 0xa2, + 0xbe, 0x21, 0xe1, 0xb7, 0x1b, 0x46, 0xef, 0xb5, 0xcd, 0xe1, 0xb2, 0x25, + 0xa2, 0x01, 0x44, 0x35, 0x6f, 0xf7, 0x50, 0xf1, 0x00, 0xa8, 0xdb, 0x65, + 0xfe, 0xa8, 0xd7, 0x17, 0xc3, 0xf9, 0x26, 0xa9, 0xf8, 0x79, 0x74, 0x91, + 0x74, 0x04, 0xde, 0x10, 0xc7, 0xda, 0x7f, 0x9c, 0xca, 0xb7, 0x68, 0xbc, + 0x90, 0x29, 0x30, 0xc7, 0xbf, 0x43, 0xbd, 0xd5, 0x08, 0x0d, 0xf0, 0xd9, + 0xf1, 0x4a, 0xc6, 0xa7, 0x57, 0x25, 0x13, 0x97, 0x53, 0x6f, 0x54, 0xa3, + 0x5e, 0x2c, 0x8b, 0x88, 0x01, 0x84, 0xeb, 0x13, 0x46, 0xcd, 0x98, 0x8f, + 0xa8, 0x8a, 0x46, 0xa1, 0xb9, 0xb0, 0x0f, 0x1f, 0xa5, 0x06, 0x4b, 0x82, + 0x09, 0x67, 0x93, 0x30, 0x0a, 0x71, 0xd2, 0xaf, 0x48, 0x57, 0xcf, 0xad, + 0x2f, 0xea, 0x82, 0xbd, 0xd5, 0x70, 0x58, 0x61, 0x4f, 0x64, 0xe2, 0xf1, + 0x7e, 0x94, 0xc3, 0x96, 0x10, 0xc1, 0x48, 0x38, 0x10, 0xd2, 0x97, 0xdb, + 0xb3, 0xca, 0xd5, 0xd4, 0xfe, 0xb1, 0x69, 0xdb, 0x7b, 0x60, 0x12, 0x32, + 0x9e, 0xea, 0xf2, 0x45, 0x34, 0xc9, 0x49, 0x85, 0xa2, 0xad, 0x6f, 0x13, + 0x59, 0xdf, 0x27, 0x55, 0x58, 0xb5, 0x19, 0x66, 0xc8, 0x5a, 0xc7, 0x68, + 0x88, 0x06, 0x2d, 0x04, 0x63, 0x26, 0x07, 0xd2, 0xc4, 0x83, 0xd6, 0xbd, + 0x73, 0xf7, 0xc9, 0xfc, 0x1a, 0x71, 0x15, 0xe5, 0x0d, 0xf4, 0xf9, 0xcf, + 0xb3, 0xbe, 0x06, 0x1c, 0x17, 0xf3, 0xac, 0x7f, 0x85, 0xaa, 0x17, 0xb8, + 0xcf, 0x9b, 0xab, 0xda, 0x22, 0x81, 0x8f, 0xd0, 0x61, 0xa6, 0xf6, 0xf9, + 0x21, 0x78, 0x41, 0x80, 0xc8, 0x2f, 0x99, 0xf8, 0x13, 0xb2, 0x7c, 0x1c, + 0xa5, 0xe3, 0x54, 0xe7, 0x65, 0x31, 0xa2, 0xd5, 0x1f, 0xcc, 0xfc, 0x9b, + 0xed, 0x67, 0x88, 0xf6, 0x6c, 0xb9, 0x0b, 0x25, 0x41, 0x8a, 0x22, 0x8f, + 0x01, 0x00, 0x61, 0x3a, 0x6a, 0x94, 0xc5, 0x20, 0x53, 0x33, 0xa5, 0x42, + 0x2f, 0x50, 0xce, 0x88, 0xa0, 0xe3, 0x2c, 0x79, 0x28, 0x7d, 0x95, 0x4f, + 0x2f, 0x9b, 0xde, 0xee, 0xaf, 0x14, 0x5f, 0x7b, 0xa7, 0xa9, 0x3f, 0xf2, + 0x28, 0x63, 0xd5, 0x6b, 0x06, 0xe8, 0xd1, 0xae, 0xed, 0x8b, 0x1e, 0xab, + 0x2f, 0x4e, 0xde, 0x2a, 0x51, 0xbf, 0xf6, 0x31, 0x66, 0x95, 0x6a, 0xff, + 0x9d, 0x45, 0x41, 0x81, 0x7c, 0x68, 0x47, 0x6b, 0x04, 0xba, 0xa1, 0xbd, + 0x6d, 0x3e, 0x79, 0xac, 0xba, 0xaa, 0xfe, 0xfa, 0x7d, 0x5c, 0x25, 0xcc, + 0xd2, 0xac, 0xca, 0x1e, 0x83, 0x0a, 0xd5, 0x81, 0xee, 0x61, 0x60, 0x14, + 0x53, 0x9d, 0xd5, 0xb3, 0x92, 0xa1, 0x79, 0x66, 0x3c, 0xa0, 0x19, 0x7d, + 0xfe, 0xfe, 0x7a, 0xd0, 0xf3, 0x3f, 0x46, 0xe8, 0xf8, 0x1b, 0xa9, 0xd8, + 0xa5, 0x40, 0x10, 0x30, 0xb1, 0xc5, 0xc3, 0x4d, 0x35, 0x85, 0x8c, 0x2a, + 0x1f, 0x42, 0xd6, 0x16, 0xff, 0xf6, 0x15, 0x76, 0x2d, 0x67, 0x83, 0x60, + 0x71, 0x94, 0xac, 0xfe, 0xdc, 0xf5, 0xd9, 0xee, 0x76, 0xd9, 0xee, 0xca, + 0xa3, 0xa4, 0x26, 0x71, 0x5b, 0x2d, 0xb3, 0x1a, 0x5b, 0x3a, 0xa6, 0xfd, + 0x45, 0x5f, 0xb5, 0x04, 0xa1, 0xce, 0x03, 0x10, 0xaf, 0xa1, 0xe6, 0x08, + 0x0a, 0x94, 0xfd, 0xba, 0x56, 0x57, 0xbd, 0xbc, 0xa8, 0x6d, 0x13, 0xf4, + 0xfd, 0xad, 0xff, 0xd1, 0xcf, 0xf6, 0x76, 0xcc, 0x5b, 0x11, 0x5b, 0xd3, + 0x60, 0xfa, 0xbf, 0xfe, 0xa9, 0x75, 0x4c, 0x2d, 0xe7, 0x7e, 0xb7, 0x3a, + 0x8a, 0x3d, 0x16, 0x98, 0x51, 0x14, 0xef, 0x2e, 0xf2, 0x2f, 0xc9, 0xce, + 0x83, 0x04, 0xf7, 0xdc, 0xde, 0xa1, 0x0e, 0x51, 0x49, 0xd9, 0x78, 0x88, + 0x2c, 0xda, 0xf7, 0xa5, 0xd5, 0xef, 0xd0, 0x40, 0xf3, 0x25, 0x9c, 0x37, + 0xd0, 0x5a, 0xef, 0x30, 0x8b, 0x7b, 0xa5, 0x1d, 0xe3, 0xe5, 0xac, 0xe5, + 0xda, 0x6b, 0xa8, 0x2c, 0x5b, 0xa0, 0xc1, 0x41, 0x7b, 0xba, 0x59, 0x83, + 0x62, 0xb3, 0x4b, 0xd3, 0xcb, 0xb6, 0xae, 0xb5, 0xde, 0x28, 0xf4, 0x29, + 0xdf, 0xde, 0xb8, 0xbd, 0xf6, 0xd9, 0x92, 0xaf, 0x56, 0x82, 0x65, 0x14, + 0x37, 0xf0, 0xea, 0xc9, 0x3d, 0xc5, 0x2b, 0xf5, 0x63, 0x6f, 0xb6, 0xdb, + 0xc4, 0xde, 0x97, 0x57, 0x53, 0xd9, 0x9f, 0x8b, 0xcb, 0x61, 0x0c, 0x74, + 0xe5, 0xd4, 0x4e, 0x6c, 0x5b, 0x5a, 0x8d, 0x5a, 0x81, 0x11, 0x2d, 0x3a, + 0x7c, 0x7e, 0x23, 0x8f, 0x92, 0x6c, 0x68, 0x3d, 0x65, 0xb5, 0x0a, 0x47, + 0x0a, 0xbd, 0x7f, 0xfe, 0x12, 0xcc, 0x2a, 0x68, 0x35, 0xdf, 0x8b, 0x07, + 0xc3, 0xf1, 0x1d, 0x31, 0x78, 0x82, 0x3c, 0x05, 0x5d, 0x69, 0x5f, 0xd4, + 0xfb, 0xbe, 0xdb, 0xef, 0xf8, 0x96, 0x50, 0xb1, 0x62, 0xe4, 0xca, 0xc4, + 0x81, 0x1b, 0x1a, 0xd2, 0xd1, 0xeb, 0x73, 0xbe, 0xf6, 0xfb, 0x14, 0xb7, + 0x7d, 0xdb, 0x7d, 0xda, 0xa4, 0x6c, 0x12, 0x97, 0x8c, 0x07, 0x24, 0x42, + 0x98, 0xa8, 0x39, 0x01, 0x0d, 0x8e, 0x20, 0x32, 0xb5, 0x65, 0x78, 0x99, + 0x21, 0x65, 0x96, 0x45, 0x0c, 0xd0, 0xf5, 0x74, 0x56, 0xcc, 0x1b, 0xa0, + 0x06, 0x21, 0x36, 0xd8, 0x33, 0x62, 0x5c, 0x61, 0xb6, 0xbe, 0x90, 0xb9, + 0x86, 0xf3, 0x68, 0x19, 0xc5, 0xfd, 0x96, 0x5e, 0x5f, 0xd8, 0xa0, 0xaf, + 0x71, 0x72, 0xa0, 0x16, 0x19, 0x04, 0xb1, 0xd0, 0x43, 0x6d, 0x3c, 0x6d, + 0x86, 0x8b, 0xfd, 0xff, 0xee, 0xd0, 0x56, 0xfa, 0x4b, 0x91, 0x0f, 0xbb, + 0x9a, 0x0c, 0x36, 0x5a, 0x15, 0x06, 0xe6, 0x47, 0xe5, 0xec, 0x04, 0x1a, + 0xce, 0x02, 0x2b, 0x4d, 0xfc, 0xb7, 0x7e, 0xd2, 0xac, 0x93, 0xa5, 0xb7, + 0xd7, 0x3b, 0x67, 0x86, 0x70, 0x04, 0x8a, 0x96, 0xa4, 0x80, 0xf0, 0x90, + 0x07, 0xa9, 0x79, 0x45, 0x9e, 0x06, 0x05, 0xa3, 0x63, 0x56, 0xd2, 0x30, + 0x01, 0xec, 0xc1, 0xeb, 0x25, 0xe0, 0xca, 0x7f, 0x3d, 0x9c, 0x53, 0xfe, + 0x64, 0xe0, 0x14, 0x10, 0x03, 0x83, 0xa7, 0x13, 0x82, 0x83, 0x1b, 0x66, + 0xeb, 0x49, 0xb6, 0xf0, 0x19, 0x1f, 0xb2, 0x15, 0x7b, 0x62, 0x1f, 0x06, + 0xda, 0x0c, 0x13, 0x96, 0x2e, 0x1e, 0x0e, 0xd2, 0x32, 0xd3, 0x63, 0x82, + 0xff, 0x55, 0x33, 0x9e, 0x6b, 0xd6, 0xac, 0x6d, 0x6d, 0x06, 0x0a, 0x82, + 0x43, 0x09, 0x4b, 0xb2, 0xe0, 0x83, 0x5b, 0x1e, 0x27, 0x9c, 0x97, 0xff, + 0x8a, 0x1a, 0x6f, 0x7a, 0x88, 0x18, 0x22, 0xfd, 0xff, 0x74, 0x0b, 0x28, + 0x07, 0xcb, 0x80, 0x1c, 0xbc, 0x98, 0x04, 0x02, 0xc6, 0xcc, 0xaa, 0x03, + 0xde, 0xf3, 0x2a, 0x44, 0x0d, 0x9b, 0x39, 0x7c, 0xbd, 0xf4, 0xc0, 0x46, + 0x04, 0x91, 0x1a, 0x6d, 0xdc, 0xcf, 0x83, 0x21, 0xfc, 0xe8, 0xe2, 0x21, + 0xbf, 0x44, 0x0c, 0x34, 0x58, 0x7f, 0x9b, 0xf1, 0x24, 0xae, 0xcf, 0x64, + 0xe6, 0x69, 0x66, 0x0d, 0xef, 0xca, 0xfd, 0xfe, 0x29, 0x52, 0x82, 0x95, + 0x87, 0x40, 0x24, 0xaf, 0xbd, 0xe2, 0xe6, 0xda, 0xc1, 0x01, 0x3f, 0xdb, + 0x6e, 0xf6, 0x5c, 0x62, 0xec, 0x80, 0xaf, 0xa0, 0xc1, 0x58, 0xa9, 0x6a, + 0xaf, 0x65, 0x51, 0xef, 0x63, 0xd0, 0x04, 0x36, 0x0b, 0xe4, 0x80, 0x84, + 0xaf, 0xe9, 0x14, 0xab, 0x64, 0x40, 0x56, 0xce, 0xee, 0x83, 0x22, 0x96, + 0xe4, 0xb7, 0xa5, 0x9c, 0x52, 0xa0, 0x04, 0x06, 0x40, 0x0d, 0x05, 0x20, + 0xec, 0x7c, 0x0c, 0x57, 0xf6, 0xc1, 0x15, 0x27, 0x43, 0xb8, 0x54, 0xa2, + 0x54, 0x3f, 0xf0, 0x7a, 0x7a, 0x53, 0x83, 0x01, 0xb5, 0x6a, 0x14, 0x25, + 0x82, 0x53, 0x4b, 0x83, 0x08, 0x9d, 0x2f, 0xbb, 0xd3, 0x5b, 0xab, 0x62, + 0xc0, 0xc1, 0x41, 0x40, 0x86, 0x0c, 0x1f, 0xa4, 0xbb, 0xef, 0xa5, 0x56, + 0xca, 0xad, 0xe9, 0x5d, 0xda, 0x59, 0x61, 0xa3, 0xc3, 0x5f, 0xfe, 0xfe, + 0x2f, 0xff, 0x9e, 0x6b, 0x0f, 0xbf, 0x00, 0x00, 0xbc, 0x08, 0x6c, 0x78, + 0x3a, 0xa9, 0x82, 0x10, 0x8c, 0x5f, 0xf4, 0xbf, 0x03, 0x03, 0xd1, 0xea, + 0xb0, 0x2d, 0x14, 0xb6, 0x5b, 0xff, 0xde, 0x72, 0x15, 0x15, 0xe6, 0x47, + 0x8e, 0xc7, 0xc2, 0x52, 0x71, 0x24, 0x7e, 0xda, 0xbf, 0x34, 0x5b, 0x8c, + 0x4f, 0xee, 0x63, 0x7c, 0xbd, 0x43, 0x3b, 0x43, 0x91, 0x14, 0x15, 0xe6, + 0x46, 0xcd, 0x63, 0x4c, 0xab, 0xd8, 0xaf, 0xfe, 0xa5, 0x9a, 0xc9, 0x63, + 0x4a, 0xea, 0x86, 0x03, 0xb4, 0x2f, 0x0b, 0x6c, 0x0f, 0x80, 0xe9, 0x79, + 0x77, 0xe8, 0x84, 0x5d, 0x8a, 0xb1, 0x42, 0x85, 0x49, 0xd8, 0xe5, 0x68, + 0x44, 0xed, 0x03, 0x21, 0xb0, 0x8a, 0x0f, 0x95, 0xff, 0xd8, 0x9c, 0x38, + 0xb1, 0x63, 0x8d, 0x82, 0x9d, 0x35, 0x8d, 0x8f, 0x93, 0x7e, 0x72, 0xa9, + 0x6b, 0x29, 0x2c, 0xbc, 0x9d, 0x07, 0x6b, 0xf9, 0x90, 0xe6, 0x0d, 0x80, + 0xa3, 0xa3, 0xc9, 0x42, 0x00, 0x1d, 0x1c, 0xb4, 0xce, 0x7f, 0x4b, 0x12, + 0xef, 0xa0, 0xe2, 0xcb, 0x6d, 0xe5, 0xfe, 0x0d, 0xb1, 0x4f, 0x75, 0x4e, + 0x87, 0x80, 0x24, 0x56, 0x3d, 0x06, 0x4a, 0x07, 0x87, 0xca, 0x73, 0x13, + 0xf8, 0xbd, 0x3c, 0x9a, 0x06, 0x15, 0x6c, 0xb1, 0x12, 0xdd, 0xf8, 0xdb, + 0x0a, 0xc3, 0x82, 0xd1, 0x6a, 0x1e, 0x15, 0x9a, 0xe6, 0xc6, 0x40, 0x74, + 0x4b, 0x54, 0x24, 0x0f, 0xb5, 0xb6, 0x55, 0xf9, 0xab, 0xfe, 0xf9, 0xa5, + 0x28, 0xef, 0xcd, 0x40, 0xd0, 0xc0, 0x7f, 0xd4, 0xb4, 0x7f, 0x91, 0x33, + 0x4d, 0xee, 0x62, 0xbd, 0x5d, 0x96, 0x2a, 0x8d, 0x51, 0x11, 0xc9, 0x54, + 0x0a, 0x01, 0xa0, 0x10, 0xc0, 0xf8, 0xf4, 0x03, 0x52, 0xeb, 0x29, 0xf6, + 0x4c, 0xce, 0x8e, 0x13, 0x4d, 0xb1, 0xa6, 0xb0, 0xd7, 0x83, 0x70, 0xdc, + 0x18, 0x84, 0x5a, 0x07, 0x07, 0xca, 0xcb, 0x27, 0xf6, 0x2d, 0x43, 0xae, + 0xa3, 0x51, 0x51, 0x03, 0x05, 0x53, 0xd2, 0x6f, 0xe2, 0xca, 0x61, 0x86, + 0x9a, 0xa5, 0xed, 0x88, 0x04, 0x86, 0xd3, 0xa6, 0xf6, 0x2a, 0x4c, 0xdd, + 0x5f, 0x92, 0x62, 0xd6, 0x92, 0x2e, 0x64, 0x2e, 0xa6, 0xc1, 0x25, 0xac, + 0x10, 0x47, 0xed, 0xfb, 0xa2, 0x23, 0x5e, 0x93, 0x7e, 0x49, 0x2d, 0x05, + 0xaa, 0x82, 0x32, 0x7c, 0x48, 0x5f, 0x0b, 0x57, 0x2c, 0xca, 0x56, 0xb6, + 0x49, 0x56, 0xe0, 0xdd, 0x18, 0x30, 0x98, 0x5e, 0x3e, 0x95, 0x5b, 0x11, + 0x2d, 0xea, 0x9d, 0x97, 0x5a, 0xce, 0x70, 0xa9, 0x07, 0x46, 0x2a, 0x41, + 0x5c, 0x16, 0x10, 0xcd, 0xf6, 0x6a, 0x8f, 0x41, 0x62, 0x3d, 0x31, 0x7a, + 0xa1, 0xea, 0xb1, 0xb9, 0x67, 0xba, 0xb5, 0x10, 0x37, 0x66, 0xef, 0x49, + 0x3c, 0x16, 0x21, 0x44, 0x7f, 0xdd, 0xef, 0xf9, 0x9a, 0xb0, 0xd9, 0x69, + 0x36, 0x2d, 0x61, 0xe1, 0x9d, 0xc6, 0x7e, 0x9e, 0x6e, 0x20, 0xe8, 0x7a, + 0x4a, 0x7c, 0x43, 0xf1, 0xe4, 0xfa, 0x65, 0x4d, 0xed, 0xeb, 0x3f, 0xf1, + 0x5e, 0xc5, 0x97, 0x15, 0x8d, 0x5a, 0xb9, 0xf6, 0xbc, 0xa5, 0x84, 0xf7, + 0x14, 0xf9, 0x46, 0xde, 0x5b, 0xfc, 0x45, 0x61, 0x2b, 0x85, 0x8c, 0x24, + 0xf4, 0xcb, 0xbc, 0x95, 0x47, 0x42, 0xa3, 0xb4, 0x3f, 0x4c, 0xa0, 0x45, + 0xe2, 0x21, 0x12, 0x70, 0x52, 0x18, 0x15, 0x83, 0x7d, 0x2a, 0xa0, 0x0c, + 0x6c, 0x21, 0xb2, 0x3e, 0xf2, 0x98, 0x06, 0x1a, 0x2e, 0x55, 0xbd, 0x8d, + 0xed, 0x6e, 0x30, 0xc5, 0xee, 0x60, 0xdb, 0x7a, 0xa5, 0x49, 0x60, 0x74, + 0x0c, 0x40, 0xd4, 0xb8, 0x84, 0x80, 0x98, 0xa6, 0xde, 0x6d, 0xe8, 0xac, + 0x2f, 0x26, 0x4f, 0x9e, 0x54, 0xd3, 0x76, 0x01, 0x9f, 0xb5, 0x85, 0x48, + 0xb9, 0x6c, 0x96, 0x86, 0x80, 0x26, 0xae, 0xd6, 0xef, 0x51, 0x51, 0xac, + 0xe3, 0xd3, 0x5c, 0x73, 0xcf, 0x8d, 0xb6, 0x4b, 0x51, 0x94, 0x23, 0xa0, + 0xe3, 0x06, 0x99, 0x63, 0xe5, 0xe0, 0x43, 0xec, 0x71, 0x68, 0x87, 0x9d, + 0x9d, 0xe0, 0x6e, 0x0b, 0x7b, 0x56, 0xa8, 0xb6, 0xe6, 0x96, 0xec, 0xdf, + 0x66, 0x96, 0x58, 0x88, 0x3d, 0x96, 0x72, 0xc1, 0x14, 0x8d, 0x44, 0x89, + 0x9b, 0x4d, 0xd1, 0xc6, 0xde, 0x5d, 0x2d, 0xb8, 0x05, 0x14, 0xd4, 0x76, + 0x44, 0x0a, 0x4c, 0x97, 0xd3, 0x54, 0xee, 0xd8, 0xf1, 0x5b, 0x00, 0xa6, + 0x1f, 0x0f, 0xcb, 0xb7, 0x6c, 0x69, 0x66, 0xd5, 0x1b, 0xce, 0xb7, 0xb7, + 0x92, 0x87, 0x28, 0xcc, 0x27, 0x38, 0xca, 0x71, 0xf3, 0x7a, 0xbf, 0x87, + 0xe5, 0xdf, 0xc6, 0x50, 0x6e, 0x46, 0x27, 0x3f, 0x68, 0x72, 0x56, 0x0c, + 0x44, 0x44, 0x47, 0x54, 0xa3, 0x7c, 0x20, 0xf7, 0x7c, 0x3d, 0xd8, 0xd7, + 0x62, 0x39, 0x7f, 0x7b, 0x60, 0x54, 0xba, 0x6c, 0xbf, 0x54, 0x93, 0xb2, + 0xa9, 0xdf, 0x0e, 0xd2, 0x40, 0xe7, 0x24, 0xbd, 0x02, 0x4a, 0x79, 0x4b, + 0x4c, 0x0d, 0x7c, 0x12, 0x47, 0x3e, 0x37, 0x79, 0x65, 0x9a, 0x2a, 0x1e, + 0x0f, 0xda, 0x50, 0xb6, 0x07, 0xcd, 0xc2, 0xc5, 0xeb, 0x79, 0x7d, 0x01, + 0x1d, 0x40, 0x31, 0x0b, 0x57, 0xca, 0xa9, 0x33, 0x79, 0xf2, 0xad, 0x51, + 0x9b, 0xbc, 0xe4, 0x92, 0x44, 0x40, 0xc2, 0x75, 0x58, 0xc4, 0xe1, 0xfe, + 0xfe, 0x5f, 0xe6, 0x7f, 0xcc, 0x42, 0xc9, 0xc9, 0xc8, 0xc4, 0x99, 0x67, + 0x83, 0x4d, 0xee, 0x83, 0x10, 0x24, 0x93, 0x3c, 0xd2, 0xa1, 0xea, 0x66, + 0x6a, 0x94, 0xcc, 0x37, 0xa5, 0x9d, 0x5f, 0xb9, 0xfa, 0x0c, 0x73, 0x73, + 0xd6, 0x9f, 0x3e, 0x59, 0x5a, 0xc2, 0xa2, 0xab, 0x71, 0x40, 0x8b, 0x49, + 0x68, 0x72, 0x1b, 0x03, 0x10, 0x28, 0x91, 0x49, 0x79, 0x76, 0xb4, 0x5a, + 0x58, 0xdb, 0x4d, 0x83, 0x2f, 0xa2, 0x2d, 0x43, 0x21, 0xfb, 0x12, 0x35, + 0x96, 0x29, 0x7b, 0x17, 0x36, 0xb0, 0xc7, 0xbb, 0xea, 0x8e, 0xf2, 0xc0, + 0x2d, 0xd0, 0xe5, 0x70, 0xf0, 0x50, 0x92, 0xae, 0x64, 0xd2, 0xcc, 0x59, + 0x3d, 0xcd, 0xea, 0x15, 0xa5, 0x97, 0xb0, 0x36, 0x04, 0x85, 0xed, 0x3f, + 0xf2, 0x03, 0x0d, 0x98, 0xf7, 0x27, 0x27, 0xf5, 0x16, 0xa9, 0x42, 0x76, + 0xd7, 0x69, 0x9b, 0xa3, 0x69, 0x5a, 0xcf, 0x14, 0xa2, 0xe7, 0x06, 0x9f, + 0x77, 0x96, 0xcb, 0x96, 0xf0, 0x6d, 0xc5, 0xe5, 0xde, 0x5a, 0xb8, 0x2d, + 0xe3, 0x58, 0x10, 0x73, 0x07, 0x37, 0x9f, 0xbf, 0xe7, 0x3a, 0xa6, 0x87, + 0x92, 0x07, 0x96, 0x88, 0x84, 0x1d, 0xb9, 0xb8, 0xb5, 0xee, 0xdd, 0xda, + 0x36, 0xc1, 0x12, 0x1a, 0x76, 0xee, 0x95, 0x22, 0xea, 0x22, 0x45, 0x90, + 0x48, 0x09, 0x69, 0x60, 0x6e, 0xb6, 0x9d, 0xf4, 0x6c, 0xb2, 0x25, 0xca, + 0x78, 0x4d, 0x29, 0x7b, 0xb3, 0x96, 0xa2, 0x97, 0xb2, 0xc8, 0x88, 0x94, + 0xfc, 0x83, 0x2c, 0xa9, 0x8a, 0xde, 0xf3, 0x18, 0x92, 0x77, 0xf5, 0x68, + 0x79, 0x3f, 0x78, 0xb7, 0xca, 0x21, 0x54, 0xe8, 0xcf, 0x82, 0xae, 0x3d, + 0x49, 0xef, 0xaa, 0x99, 0x7d, 0x19, 0x62, 0x74, 0x41, 0xc5, 0x17, 0xaa, + 0x38, 0xb5, 0xe2, 0x92, 0xbc, 0x31, 0x27, 0xbd, 0x77, 0xa4, 0xcd, 0x8f, + 0x07, 0xa0, 0xa3, 0x07, 0x02, 0x9c, 0x46, 0x03, 0x4d, 0xa4, 0x82, 0x06, + 0xdf, 0x36, 0x88, 0xb5, 0x0a, 0xd7, 0x06, 0xf8, 0xcb, 0x5d, 0x06, 0x1a, + 0x93, 0xee, 0x34, 0x01, 0xc9, 0x34, 0x44, 0x55, 0xec, 0xe1, 0xae, 0x5b, + 0xa7, 0xc9, 0x44, 0x8d, 0x7f, 0xc9, 0x95, 0x01, 0x86, 0x4b, 0xbc, 0xb0, + 0xe6, 0xaf, 0x56, 0x5b, 0xd0, 0x39, 0xd2, 0xa1, 0x14, 0x05, 0xb1, 0x1c, + 0x4a, 0x0f, 0xc7, 0xda, 0x24, 0x0e, 0x75, 0x8c, 0x2a, 0x50, 0x58, 0x8e, + 0x16, 0x5b, 0xce, 0x5d, 0x1b, 0xe2, 0xe1, 0x61, 0x78, 0xe1, 0x1c, 0xc9, + 0x84, 0x49, 0x86, 0x3f, 0x46, 0x07, 0xe9, 0x7c, 0x97, 0x99, 0x64, 0x66, + 0x8e, 0x22, 0x32, 0x49, 0x43, 0x62, 0x30, 0xa4, 0xc3, 0x45, 0x4a, 0x36, + 0xcd, 0xb3, 0xb0, 0xda, 0x22, 0x26, 0x24, 0x00, 0x70, 0xfd, 0xa5, 0x7f, + 0xf0, 0xfc, 0x40, 0xa9, 0x98, 0x0e, 0xbe, 0xaa, 0x16, 0x6a, 0x74, 0x5c, + 0x2d, 0x8a, 0x56, 0xcc, 0x02, 0xa6, 0x11, 0x2e, 0xf3, 0x65, 0x94, 0x38, + 0xe2, 0xc6, 0xec, 0x43, 0xc0, 0xd0, 0x16, 0x8a, 0x2a, 0x44, 0xc6, 0x3e, + 0x4e, 0x39, 0xef, 0x2e, 0x6f, 0x97, 0x2b, 0x88, 0xfb, 0x2d, 0x97, 0xdc, + 0x11, 0x14, 0x1e, 0x1f, 0x7c, 0x4b, 0x4c, 0xa8, 0x21, 0xb3, 0xa9, 0x7b, + 0xfb, 0x26, 0xcf, 0x36, 0x8f, 0x1a, 0x63, 0x93, 0xbe, 0x90, 0x19, 0x01, + 0x58, 0x76, 0x04, 0x45, 0xa3, 0x01, 0xe3, 0x1b, 0x19, 0x2f, 0xd1, 0x05, + 0x56, 0x97, 0x33, 0x41, 0x58, 0xa1, 0x7d, 0xbf, 0x9f, 0x0f, 0x69, 0x21, + 0x5f, 0x70, 0x15, 0xf8, 0x65, 0x14, 0xa2, 0x43, 0x19, 0x9a, 0xc4, 0x62, + 0x75, 0xbe, 0xec, 0xd5, 0xe5, 0x2d, 0xa8, 0x6d, 0x01, 0x22, 0xab, 0x2c, + 0x75, 0x5b, 0x17, 0x02, 0x28, 0xfa, 0xa6, 0xfa, 0x71, 0xce, 0x08, 0x0c, + 0x50, 0x32, 0x58, 0x57, 0xc1, 0x51, 0x8a, 0x01, 0xa0, 0x80, 0xde, 0x07, + 0xcc, 0xe9, 0x6f, 0xb7, 0x90, 0x19, 0x76, 0xaa, 0x82, 0x9e, 0x87, 0xa0, + 0x24, 0xf0, 0x28, 0x95, 0x32, 0xc6, 0xfd, 0x22, 0xb6, 0xac, 0x95, 0x7e, + 0xa3, 0x63, 0x64, 0xfd, 0x40, 0x1c, 0xa8, 0xa0, 0xef, 0x83, 0xe5, 0x40, + 0x0e, 0xa0, 0x1d, 0x06, 0xc0, 0x36, 0x95, 0xb5, 0x63, 0xce, 0xe6, 0xad, + 0x0b, 0x28, 0x75, 0xb2, 0x2c, 0xb0, 0x70, 0x16, 0x31, 0x1f, 0xda, 0x4e, + 0xda, 0x81, 0x03, 0xd8, 0x0e, 0x03, 0xe9, 0x7e, 0x39, 0xa5, 0xed, 0x37, + 0x14, 0x17, 0x6e, 0xa2, 0x9c, 0xb2, 0xd9, 0xd0, 0x70, 0x74, 0x50, 0x64, + 0x2d, 0xa7, 0xde, 0x76, 0xa9, 0x51, 0xc8, 0x33, 0xe4, 0x01, 0x3d, 0xa6, + 0x0b, 0xc2, 0x00, 0x80, 0xce, 0xe4, 0x1c, 0x26, 0x6a, 0x23, 0xe6, 0x4b, + 0xb5, 0x1d, 0x02, 0x7b, 0xd3, 0x21, 0x9e, 0x04, 0x1f, 0x97, 0xb6, 0x20, + 0xb7, 0x14, 0xb5, 0xd1, 0xb7, 0xb9, 0xb9, 0xcb, 0x51, 0xac, 0x37, 0xd0, + 0x4b, 0x4c, 0x63, 0x77, 0xa4, 0xd5, 0xc9, 0x87, 0x10, 0x36, 0x3f, 0x10, + 0x68, 0x29, 0xf4, 0x11, 0x53, 0x66, 0xfc, 0x3a, 0xdb, 0x1b, 0xe7, 0x56, + 0x5f, 0x4b, 0x54, 0x6e, 0x60, 0x2d, 0x04, 0x8a, 0xc7, 0x89, 0xa8, 0x95, + 0x7b, 0xf6, 0x74, 0xb6, 0x4a, 0xd0, 0xe4, 0xae, 0xa8, 0xbc, 0xe4, 0xbf, + 0x0e, 0x57, 0x52, 0x1d, 0x02, 0x50, 0x5e, 0xd1, 0x23, 0xc1, 0xf3, 0x29, + 0xc7, 0xd6, 0x34, 0x9c, 0xb0, 0x72, 0x54, 0x8b, 0x64, 0x9d, 0x5d, 0xcb, + 0x89, 0x40, 0x77, 0xdb, 0x5a, 0x1f, 0x6f, 0xae, 0xdf, 0x2a, 0x1c, 0xab, + 0xde, 0x07, 0x9e, 0xd9, 0x11, 0x06, 0x60, 0xc3, 0x57, 0x9e, 0xe4, 0xef, + 0x54, 0x85, 0x91, 0x00, 0x00, 0xc1, 0x08, 0x6c, 0x37, 0x01, 0xaf, 0x67, + 0xc1, 0x16, 0x4e, 0xf3, 0x6a, 0x94, 0x75, 0x75, 0xea, 0xe0, 0xc2, 0x71, + 0x28, 0x84, 0x0c, 0xad, 0x58, 0xf8, 0x15, 0x99, 0xed, 0xfe, 0x5f, 0xe6, + 0x32, 0xba, 0x8f, 0x28, 0xb7, 0xf2, 0xd6, 0x3d, 0xaa, 0x14, 0xb6, 0x04, + 0x00, 0xaf, 0xc5, 0x88, 0x84, 0x14, 0xa0, 0xa6, 0x4c, 0x91, 0xb5, 0x4a, + 0xa6, 0xb7, 0xc8, 0x1f, 0xde, 0xdd, 0x96, 0x70, 0x18, 0x93, 0x0a, 0x81, + 0x84, 0xe1, 0x9b, 0xc9, 0x58, 0x57, 0xea, 0x20, 0x37, 0x3c, 0x96, 0xd8, + 0x06, 0x2c, 0xa5, 0xb2, 0xd9, 0x7b, 0x7d, 0xfd, 0x11, 0x73, 0x4a, 0x94, + 0x82, 0xdc, 0x2f, 0x99, 0x2a, 0x30, 0x4b, 0x16, 0xab, 0x9e, 0x6c, 0x31, + 0x03, 0x0f, 0x55, 0xb0, 0xda, 0x5f, 0x6c, 0xfb, 0x29, 0xda, 0x57, 0xea, + 0xcc, 0xac, 0xac, 0x94, 0x7d, 0xb7, 0xf4, 0x1c, 0x5d, 0x18, 0x06, 0x02, + 0x8d, 0x66, 0x73, 0x4a, 0xcb, 0x7e, 0xac, 0x3b, 0x2d, 0x16, 0x06, 0x7a, + 0x55, 0x85, 0xb7, 0xdf, 0xb3, 0xfd, 0x51, 0xfd, 0x8a, 0x25, 0xe2, 0xd6, + 0x40, 0xec, 0x12, 0x06, 0xbb, 0x77, 0xec, 0xeb, 0x5f, 0xff, 0xf7, 0x33, + 0x69, 0x69, 0x6f, 0x6b, 0x62, 0x0f, 0x2c, 0x5e, 0x83, 0x21, 0xc0, 0x60, + 0x96, 0x2a, 0x9b, 0xdf, 0x75, 0x42, 0x35, 0x19, 0xde, 0xe2, 0xe8, 0xe7, + 0x83, 0x7d, 0x58, 0x69, 0x37, 0xd2, 0x43, 0x87, 0x1e, 0x6d, 0x7c, 0x9d, + 0xab, 0x59, 0x09, 0x6a, 0xd3, 0xa8, 0xcf, 0x0b, 0x1a, 0x00, 0xd4, 0xfe, + 0xcc, 0xf7, 0xa6, 0x45, 0x12, 0x2e, 0xba, 0x04, 0x40, 0x97, 0x37, 0x39, + 0x67, 0x94, 0x59, 0x44, 0x54, 0x37, 0xa2, 0x83, 0xa5, 0x5e, 0x0e, 0xaf, + 0x4a, 0x73, 0x96, 0x12, 0x8d, 0xc1, 0xd8, 0x2b, 0x37, 0xdf, 0xff, 0xba, + 0xa2, 0x85, 0x90, 0xc3, 0x65, 0x30, 0x0e, 0xd6, 0xd9, 0x2e, 0x53, 0x24, + 0x68, 0x3f, 0x55, 0x47, 0x76, 0x2f, 0xac, 0x87, 0xb2, 0x5e, 0x83, 0x12, + 0x2e, 0xa0, 0x2c, 0x04, 0xc0, 0xf8, 0x76, 0xd0, 0x18, 0xd5, 0x38, 0xa3, + 0x99, 0x7b, 0xd5, 0x94, 0x54, 0x21, 0x5f, 0x97, 0xc5, 0x93, 0x37, 0x34, + 0xb6, 0x6a, 0xdc, 0x58, 0xaa, 0xca, 0xb0, 0x23, 0x9e, 0x06, 0x20, 0x20, + 0x02, 0x17, 0xe2, 0x65, 0x55, 0x96, 0x5b, 0xdd, 0xbb, 0xea, 0x58, 0x05, + 0x1a, 0x60, 0x6e, 0x59, 0xd0, 0xdc, 0x0a, 0xe1, 0x82, 0x98, 0x85, 0xbd, + 0xe8, 0x3e, 0x4f, 0xff, 0x65, 0x7b, 0xa7, 0x53, 0x16, 0xb2, 0x91, 0x23, + 0x61, 0xec, 0x84, 0xaa, 0x71, 0x65, 0x89, 0xe7, 0xed, 0x8e, 0x72, 0x4e, + 0x95, 0x7b, 0x27, 0x03, 0x7b, 0x22, 0x20, 0x60, 0x8c, 0x20, 0xfc, 0x7f, + 0x58, 0x68, 0x3e, 0xf6, 0x95, 0xd0, 0xea, 0x41, 0x13, 0xc8, 0x7b, 0x46, + 0x88, 0x8f, 0xbb, 0xff, 0x50, 0xf5, 0x0d, 0x44, 0x8e, 0x0a, 0xad, 0xce, + 0x4e, 0xbd, 0x53, 0x19, 0xe2, 0x51, 0x07, 0xc3, 0xff, 0x2b, 0x51, 0x8d, + 0x96, 0xcc, 0xc4, 0x1c, 0x9f, 0x85, 0x92, 0x5a, 0x32, 0xba, 0x0c, 0x26, + 0xe1, 0x08, 0x7c, 0x0c, 0xa0, 0x7c, 0xa8, 0x79, 0x9f, 0xad, 0xf9, 0x37, + 0xf7, 0x8b, 0xdd, 0x51, 0x96, 0xdb, 0x3d, 0x3f, 0xa3, 0x75, 0x1d, 0xa5, + 0x62, 0xb1, 0xb8, 0x28, 0xd2, 0x46, 0xc1, 0x54, 0x24, 0x35, 0x95, 0x43, + 0x29, 0xe2, 0xb5, 0x6a, 0xef, 0xef, 0x4b, 0x7c, 0xbc, 0x0f, 0x30, 0xad, + 0xb0, 0x54, 0x82, 0xa3, 0x00, 0x50, 0x5c, 0x04, 0x51, 0xe4, 0xf4, 0xd9, + 0xe2, 0xc6, 0x47, 0x05, 0x7c, 0xca, 0x36, 0x58, 0xd0, 0x73, 0xc8, 0x65, + 0xec, 0x5a, 0x50, 0x5a, 0xbb, 0x78, 0x41, 0x48, 0xd8, 0x8e, 0x58, 0x0a, + 0xdc, 0x4f, 0x9e, 0xdd, 0x06, 0x43, 0x3d, 0xfc, 0xf5, 0xe7, 0x2d, 0x50, + 0x38, 0xd0, 0x7c, 0xbf, 0xfe, 0xc5, 0xad, 0x6c, 0xdd, 0xe6, 0x2e, 0x2e, + 0x38, 0x61, 0x5c, 0xf2, 0x56, 0x22, 0xb6, 0x11, 0xe4, 0x9d, 0x36, 0x78, + 0xf8, 0x85, 0x44, 0x01, 0x07, 0xed, 0xdb, 0x61, 0x67, 0x61, 0xa2, 0x74, + 0xb8, 0x1e, 0x52, 0x79, 0x1c, 0x99, 0x7f, 0xe7, 0x0a, 0x6c, 0x0a, 0xc6, + 0x3f, 0xed, 0x5b, 0xcb, 0x71, 0x6b, 0x4d, 0x57, 0x23, 0xe0, 0x87, 0x8a, + 0xfe, 0x55, 0x29, 0x62, 0x85, 0xd0, 0x93, 0x22, 0xb4, 0xee, 0xcb, 0x2e, + 0x21, 0x36, 0x34, 0x65, 0x1c, 0x23, 0xdb, 0x18, 0x0f, 0xe2, 0xbc, 0x50, + 0xa2, 0xf7, 0x9c, 0xbb, 0xb5, 0x1d, 0xde, 0xc4, 0x41, 0xc0, 0x58, 0xbb, + 0x4a, 0xc3, 0xea, 0x99, 0xa0, 0x60, 0xe0, 0xbf, 0x71, 0x7a, 0x0c, 0x1c, + 0xb7, 0x4b, 0x38, 0x1c, 0x95, 0x47, 0xa0, 0x96, 0xe6, 0xf9, 0x59, 0xaf, + 0xb5, 0xbc, 0x37, 0xc9, 0x09, 0x87, 0x81, 0xdc, 0x1f, 0x33, 0xea, 0x05, + 0xd5, 0x97, 0x53, 0x7c, 0x92, 0x7f, 0xa5, 0x28, 0x9c, 0x63, 0x64, 0x07, + 0xab, 0x9c, 0xe5, 0x05, 0xa9, 0x64, 0x87, 0x98, 0x0e, 0x2f, 0x67, 0x6a, + 0xf5, 0x56, 0x32, 0xa9, 0x4a, 0x1e, 0x4b, 0x3f, 0xe0, 0x76, 0x3c, 0xcf, + 0xc6, 0xc5, 0xf3, 0xeb, 0x8e, 0x7a, 0x55, 0x17, 0xa8, 0xf9, 0x28, 0x56, + 0x24, 0xc0, 0x2e, 0x07, 0xf7, 0xdc, 0xc5, 0x2c, 0x0f, 0x98, 0x52, 0x86, + 0xfe, 0xfa, 0xf7, 0xb0, 0x66, 0xa4, 0x18, 0x86, 0x33, 0x2c, 0xda, 0x39, + 0xd9, 0xfc, 0x69, 0xa9, 0x14, 0xf2, 0x44, 0x53, 0x91, 0x61, 0x13, 0x42, + 0xd3, 0x0f, 0x7d, 0x97, 0xfe, 0xe2, 0x64, 0x9f, 0xfc, 0x80, 0x66, 0xfa, + 0x74, 0xdd, 0xb2, 0x70, 0xea, 0xc3, 0xc6, 0xff, 0xa5, 0xc0, 0x6f, 0xfc, + 0x52, 0xa7, 0x67, 0xbd, 0x16, 0x42, 0xb8, 0x30, 0x26, 0x98, 0x4e, 0xd0, + 0x7e, 0x3e, 0x50, 0x86, 0x0d, 0xd7, 0x5e, 0x71, 0x6b, 0x4f, 0xa8, 0x92, + 0xfb, 0x5a, 0x2c, 0xef, 0x40, 0xd7, 0x3c, 0xa3, 0x9c, 0xec, 0x07, 0x07, + 0x3c, 0x01, 0x32, 0xda, 0x55, 0x9c, 0xc3, 0x57, 0xb2, 0x29, 0x95, 0x0f, + 0x48, 0x76, 0xc0, 0xeb, 0x7a, 0x8a, 0x52, 0xd3, 0x6b, 0xf1, 0x70, 0xdb, + 0x48, 0x92, 0x2b, 0x53, 0x59, 0xcc, 0xa1, 0xe7, 0x3b, 0x91, 0x7b, 0xf2, + 0x4a, 0x6f, 0x0c, 0x20, 0x5b, 0x2a, 0x8f, 0xf2, 0xe4, 0xb0, 0xae, 0x59, + 0xc5, 0xc8, 0x65, 0xba, 0x53, 0x56, 0xe5, 0x58, 0x2b, 0x2a, 0xd4, 0x98, + 0xba, 0x0b, 0xc0, 0xc9, 0x70, 0x60, 0xae, 0x15, 0x16, 0x7c, 0x6c, 0x45, + 0x19, 0x83, 0x7b, 0xd5, 0xbd, 0x0a, 0x69, 0xff, 0x6d, 0xcc, 0x5a, 0xb2, + 0x39, 0x53, 0x24, 0xd9, 0x5a, 0x5a, 0x72, 0x8a, 0x4b, 0xe6, 0xd5, 0x6d, + 0x66, 0x31, 0xd8, 0x86, 0xaf, 0xda, 0xa4, 0x15, 0x20, 0xb5, 0xeb, 0xf2, + 0xd4, 0x77, 0xa3, 0x2b, 0x38, 0x44, 0x70, 0x19, 0x48, 0x29, 0xbd, 0x73, + 0x33, 0x01, 0x4e, 0xcd, 0xe1, 0x50, 0x14, 0x95, 0x0b, 0xd6, 0xce, 0x64, + 0x78, 0x9e, 0x07, 0x4e, 0x4d, 0x4e, 0x2a, 0x55, 0xef, 0xe3, 0x31, 0x85, + 0xfb, 0xb6, 0x87, 0x51, 0x4f, 0xea, 0x9e, 0xd1, 0xb9, 0x5a, 0xe1, 0x68, + 0xf4, 0xbd, 0x28, 0xfd, 0x55, 0xdd, 0x05, 0x30, 0x29, 0xd5, 0x4e, 0xa8, + 0x4a, 0x5d, 0xff, 0x6c, 0x2c, 0x88, 0xa7, 0x06, 0xe1, 0x6d, 0x44, 0x93, + 0xfc, 0x0f, 0xc0, 0xcf, 0x3b, 0xde, 0x8d, 0xb7, 0xf5, 0x1f, 0xec, 0x11, + 0x51, 0x03, 0xe4, 0x40, 0x0e, 0x2c, 0xd9, 0x18, 0x6b, 0xfb, 0x33, 0x81, + 0xed, 0xe4, 0x88, 0xa7, 0xbd, 0xe6, 0xea, 0xc1, 0xc0, 0x38, 0x3d, 0x23, + 0x2b, 0x10, 0x38, 0xa4, 0xc6, 0x43, 0xe0, 0x41, 0x1f, 0x0f, 0x75, 0x5e, + 0x7c, 0x72, 0xc6, 0xb5, 0x32, 0xee, 0x6c, 0x5e, 0xf6, 0x55, 0xa7, 0x11, + 0xe0, 0x6e, 0x04, 0x5e, 0x5d, 0xb1, 0xf8, 0x20, 0x96, 0x68, 0x29, 0x87, + 0xcc, 0x02, 0x9b, 0xd2, 0xb7, 0x9e, 0x56, 0xae, 0x81, 0xbf, 0xb1, 0x3d, + 0xc9, 0x39, 0x83, 0x6d, 0xdd, 0x0e, 0x43, 0xd0, 0x28, 0x58, 0x02, 0x03, + 0x48, 0x40, 0xd2, 0xf1, 0xd8, 0x8e, 0x3d, 0xd4, 0xe3, 0xe1, 0xc1, 0x72, + 0xd8, 0xa8, 0x41, 0x2e, 0x8d, 0x37, 0xf9, 0x6f, 0x7d, 0x63, 0x25, 0x5b, + 0x73, 0x32, 0x52, 0xad, 0xf0, 0x71, 0xf0, 0x63, 0x82, 0xf6, 0xf3, 0x19, + 0x12, 0xd8, 0x11, 0x8b, 0x59, 0x5d, 0xaa, 0x3d, 0x67, 0x9c, 0xe7, 0xd8, + 0x62, 0xcf, 0x16, 0x5a, 0xa1, 0x6c, 0xdd, 0xff, 0xb4, 0xa8, 0x3d, 0x2a, + 0x33, 0x09, 0xd9, 0x33, 0xd8, 0x3b, 0x12, 0x04, 0x96, 0x98, 0xfc, 0x54, + 0xce, 0x27, 0xac, 0xc5, 0x59, 0xe6, 0x98, 0xfc, 0x8d, 0x5e, 0x5b, 0x7f, + 0xfb, 0x85, 0x43, 0x85, 0xa9, 0x5e, 0x81, 0x50, 0xb0, 0xbd, 0x1d, 0xa7, + 0x1d, 0x77, 0xea, 0xcb, 0xbe, 0x9c, 0x4a, 0x85, 0x41, 0xfb, 0x0a, 0xad, + 0xfe, 0x2f, 0x27, 0x2f, 0xb0, 0xac, 0xc8, 0x83, 0x13, 0x7b, 0x3d, 0x47, + 0x1c, 0x68, 0xaa, 0xae, 0x59, 0xee, 0x61, 0xbb, 0xc0, 0xb0, 0x31, 0x89, + 0x69, 0x84, 0x9a, 0x3e, 0x4e, 0x3f, 0x2e, 0xd5, 0x5a, 0x59, 0x20, 0x80, + 0xaa, 0x61, 0x64, 0x6c, 0x3d, 0x93, 0xe2, 0x0a, 0x8d, 0x02, 0xea, 0x2d, + 0xd5, 0x00, 0xb6, 0x61, 0xca, 0x0e, 0x03, 0x10, 0xaa, 0x65, 0xda, 0xc0, + 0x56, 0x96, 0xf5, 0xbd, 0x89, 0xff, 0xdf, 0x31, 0x57, 0xdf, 0x44, 0x53, + 0x90, 0x19, 0x06, 0x01, 0x11, 0x4c, 0x60, 0x41, 0x1d, 0x03, 0x2f, 0x31, + 0xbf, 0x7c, 0x3e, 0x99, 0x76, 0xb4, 0x57, 0x92, 0xde, 0x87, 0x85, 0xa3, + 0x6d, 0xd5, 0x12, 0x95, 0x03, 0x8c, 0x0c, 0x42, 0x08, 0x92, 0x0c, 0x1f, + 0x08, 0x41, 0xf8, 0xe2, 0x37, 0xaa, 0xff, 0xe5, 0x43, 0x8c, 0x97, 0x16, + 0xfd, 0x85, 0xb1, 0x62, 0xb5, 0x0a, 0x3a, 0x36, 0x02, 0xb8, 0x60, 0x89, + 0x70, 0x1c, 0x12, 0x13, 0x2a, 0x91, 0x50, 0xf3, 0xcd, 0x34, 0xde, 0x42, + 0xd9, 0x73, 0xb6, 0xdb, 0x3a, 0xba, 0x90, 0x60, 0x9c, 0x82, 0xda, 0x72, + 0x36, 0x18, 0x15, 0x88, 0x69, 0xc4, 0x94, 0xfb, 0xe6, 0x39, 0x83, 0xe5, + 0xe7, 0x36, 0x4e, 0xff, 0x3a, 0xbf, 0x6e, 0xe7, 0xca, 0x8e, 0x23, 0xe2, + 0xe5, 0x4a, 0xb9, 0x41, 0x4d, 0x99, 0x2c, 0x0e, 0xd8, 0x5d, 0x47, 0x4d, + 0xb9, 0x30, 0x6a, 0x0a, 0x46, 0xea, 0x66, 0xd9, 0x03, 0xdf, 0xd6, 0x2f, + 0xa4, 0x2d, 0x1e, 0x7b, 0x93, 0xdf, 0x9e, 0x42, 0xc2, 0x82, 0xc1, 0xc3, + 0x61, 0xb0, 0x31, 0x08, 0xff, 0xc0, 0xd5, 0x80, 0x35, 0x47, 0x42, 0x4f, + 0x99, 0x80, 0xe1, 0xf3, 0x00, 0x67, 0xdb, 0x6e, 0xa9, 0xbe, 0x9d, 0x96, + 0x6e, 0x29, 0xc4, 0x63, 0x72, 0xd0, 0xef, 0x01, 0x85, 0x65, 0xe0, 0x05, + 0xe1, 0x6b, 0x62, 0x90, 0x37, 0x8d, 0x0e, 0xbe, 0xa3, 0x0b, 0x7f, 0x9e, + 0xe7, 0xad, 0x35, 0x79, 0xca, 0x0c, 0x34, 0x1d, 0x7b, 0xec, 0x88, 0x93, + 0x27, 0xd6, 0x5f, 0x88, 0xa7, 0x91, 0x40, 0x71, 0x83, 0xa0, 0xf0, 0x3f, + 0xe2, 0xb3, 0xea, 0x0e, 0x49, 0x01, 0x8a, 0xa4, 0x91, 0xa4, 0xcd, 0xf3, + 0x6a, 0xd6, 0x4b, 0x7e, 0xce, 0x67, 0xb7, 0x73, 0x57, 0x05, 0x77, 0xc2, + 0xc0, 0x90, 0x5d, 0x81, 0xfa, 0x46, 0x07, 0xea, 0x24, 0x1c, 0xfa, 0x55, + 0x19, 0xaa, 0x56, 0xb2, 0x55, 0xea, 0x8f, 0x00, 0x93, 0xbf, 0xb1, 0x03, + 0xb0, 0xb5, 0xb1, 0xa8, 0x96, 0x23, 0xb2, 0x20, 0x36, 0x25, 0x45, 0x59, + 0x7b, 0xbb, 0xd6, 0x4b, 0x6c, 0x97, 0x0b, 0x6e, 0xcf, 0x59, 0x99, 0xe0, + 0x7c, 0xbf, 0xfe, 0xc6, 0xfe, 0x53, 0x36, 0xed, 0x63, 0xbe, 0x2b, 0xc5, + 0x02, 0x24, 0xec, 0x0e, 0xe5, 0x1b, 0x82, 0xb8, 0xc1, 0x8d, 0xf7, 0xbe, + 0x5e, 0xcc, 0xf8, 0x79, 0xc5, 0x7a, 0xa3, 0xcb, 0xdb, 0xfb, 0x6d, 0xa5, + 0xb3, 0x88, 0xd0, 0x69, 0x58, 0x74, 0x16, 0x8a, 0x63, 0x1d, 0xdf, 0xb4, + 0xcd, 0xbf, 0x51, 0x81, 0xfb, 0x1b, 0xad, 0xc2, 0xd9, 0xd5, 0x84, 0x4c, + 0x51, 0x88, 0xc1, 0x85, 0x65, 0xe6, 0x76, 0x38, 0xc2, 0x66, 0xde, 0xf8, + 0xb7, 0x7d, 0xad, 0x29, 0x92, 0xd5, 0xd1, 0xe5, 0x59, 0x1f, 0xfb, 0xa0, + 0xf9, 0x5f, 0xfd, 0x89, 0x12, 0x09, 0x50, 0xbf, 0x2f, 0x19, 0x6b, 0x97, + 0xf3, 0x0b, 0x57, 0xe8, 0x83, 0x22, 0xd2, 0x4c, 0x2b, 0x02, 0x78, 0x2c, + 0x14, 0x0f, 0x00, 0xe6, 0xb6, 0x5c, 0xd2, 0x86, 0x2f, 0xdb, 0xd5, 0xbc, + 0x57, 0xdb, 0xab, 0xce, 0xb7, 0x7e, 0x1c, 0x62, 0xe5, 0x42, 0xb9, 0x56, + 0x24, 0x30, 0x3c, 0x1d, 0xe0, 0x39, 0x2e, 0xda, 0xb0, 0x38, 0x14, 0xd3, + 0xb1, 0xad, 0x88, 0xe7, 0xe0, 0x7a, 0x39, 0x6d, 0x48, 0x75, 0x80, 0xf9, + 0x70, 0x03, 0xad, 0x92, 0x10, 0x10, 0x16, 0x36, 0xa8, 0x96, 0x21, 0x54, + 0x9a, 0xd6, 0x25, 0xb0, 0x3f, 0xdf, 0xcf, 0x75, 0x4f, 0x6e, 0xc9, 0xd8, + 0x8e, 0x61, 0x52, 0x01, 0xb8, 0x31, 0x17, 0x03, 0x40, 0xdc, 0xdd, 0xf3, + 0x25, 0x8c, 0xb0, 0x04, 0x3c, 0x1e, 0xe3, 0x17, 0xeb, 0xf7, 0xfe, 0xc1, + 0xba, 0x85, 0xb0, 0x3b, 0x06, 0x23, 0x18, 0x00, 0x6c, 0xdf, 0xa5, 0xf6, + 0xe3, 0x3e, 0x98, 0xce, 0xf8, 0x3c, 0xd9, 0xca, 0x9b, 0x22, 0x30, 0x36, + 0xc9, 0x5e, 0x62, 0x3b, 0xaa, 0x30, 0x18, 0xe8, 0xc9, 0xb2, 0xfb, 0x9f, + 0x57, 0x55, 0x02, 0xb3, 0xde, 0x51, 0xe6, 0x04, 0x0e, 0x6f, 0x7f, 0xe5, + 0x83, 0xc6, 0x73, 0x17, 0xcd, 0xca, 0x37, 0xd0, 0xf4, 0x04, 0xda, 0x58, + 0x68, 0x2c, 0xb4, 0xa9, 0xed, 0xb0, 0x84, 0x90, 0x7d, 0xa1, 0x05, 0xac, + 0xdc, 0xbf, 0x4d, 0xe5, 0xff, 0x7f, 0xb2, 0x77, 0x64, 0xcb, 0xce, 0x68, + 0x2d, 0xc2, 0xd3, 0x45, 0xec, 0x5e, 0x28, 0xcb, 0x68, 0xba, 0xf2, 0x13, + 0xd7, 0xd3, 0x81, 0xa6, 0xcb, 0x92, 0xe3, 0x54, 0xb5, 0x6d, 0x56, 0x5b, + 0xe2, 0xcd, 0xdd, 0x43, 0x3a, 0x0e, 0x2b, 0x0f, 0x11, 0x19, 0x0c, 0x00, + 0x1c, 0x07, 0x47, 0x82, 0x5a, 0xbd, 0x4d, 0xf1, 0xc9, 0x70, 0x78, 0xa6, + 0x6a, 0xdc, 0xdc, 0x88, 0xe4, 0x50, 0x09, 0x0b, 0x85, 0x93, 0xdc, 0x42, + 0x66, 0x61, 0x94, 0xc7, 0xa9, 0x12, 0x83, 0x16, 0xab, 0xb9, 0xec, 0x6f, + 0x8c, 0x36, 0xa2, 0xc1, 0x12, 0xd8, 0x8d, 0xe2, 0x42, 0xf2, 0xf6, 0xcb, + 0x9a, 0xf3, 0x09, 0x98, 0xd6, 0x4b, 0xdb, 0xe0, 0xe1, 0x86, 0xb9, 0xd9, + 0x3a, 0xbf, 0xff, 0x74, 0xa9, 0xac, 0x30, 0x2f, 0xa0, 0xdf, 0x1f, 0x24, + 0xe8, 0xf0, 0x0f, 0x26, 0x1c, 0xab, 0xdb, 0x14, 0x56, 0xc3, 0xc9, 0xfd, + 0xad, 0xf3, 0xfc, 0x2a, 0x52, 0xa7, 0x17, 0xd5, 0x20, 0xc4, 0x49, 0x97, + 0x76, 0x26, 0x0f, 0xdb, 0x53, 0x1b, 0x66, 0x52, 0xd5, 0xca, 0xc5, 0x07, + 0x5c, 0xa0, 0x97, 0x13, 0x16, 0xdc, 0xba, 0xcf, 0xb7, 0xfc, 0xdd, 0x51, + 0x04, 0x55, 0x25, 0x96, 0xc0, 0xf6, 0x74, 0x1c, 0x64, 0xd0, 0x30, 0xd9, + 0x5e, 0x7c, 0x08, 0xe4, 0x83, 0x0a, 0xbc, 0x07, 0x38, 0x31, 0x32, 0xae, + 0x88, 0x49, 0xcb, 0x35, 0x40, 0x7c, 0x3d, 0xe4, 0x2e, 0x8a, 0x40, 0xc8, + 0x29, 0xcb, 0x57, 0xec, 0xd5, 0x0a, 0x71, 0x9e, 0xc2, 0xb2, 0xd0, 0xf3, + 0x85, 0x80, 0x96, 0x17, 0x23, 0x7a, 0xc9, 0x73, 0x4d, 0xc2, 0xbd, 0x63, + 0x8a, 0x78, 0x6b, 0x88, 0xc2, 0x85, 0x1b, 0x10, 0xab, 0x63, 0xc0, 0x66, + 0xd3, 0x27, 0x61, 0x8a, 0x94, 0x78, 0x3d, 0x6c, 0xb9, 0x8f, 0xf2, 0xa5, + 0xcf, 0x75, 0x7d, 0x47, 0x3e, 0x0c, 0x13, 0x0e, 0xc0, 0x30, 0x21, 0x8e, + 0xf0, 0x78, 0xd8, 0x90, 0x5f, 0x76, 0x96, 0xec, 0xdf, 0x2b, 0x6d, 0x76, + 0xdb, 0x62, 0xaf, 0xca, 0x68, 0x80, 0x88, 0x20, 0xfd, 0x27, 0xc0, 0x30, + 0x7a, 0x0a, 0x7b, 0x63, 0x02, 0x00, 0x7b, 0xc9, 0xdd, 0x47, 0x37, 0x92, + 0x07, 0x2a, 0x40, 0x40, 0x63, 0x6c, 0x76, 0xde, 0xea, 0x49, 0x0b, 0x73, + 0x9f, 0x55, 0x89, 0x23, 0x19, 0x36, 0x46, 0x27, 0xb3, 0xd3, 0xbf, 0x11, + 0x74, 0x88, 0x96, 0x35, 0x64, 0x40, 0x90, 0xae, 0x4c, 0x80, 0xf8, 0x21, + 0xf0, 0x03, 0xd5, 0x09, 0x13, 0x92, 0x6a, 0xaf, 0xb7, 0xff, 0xad, 0x6e, + 0xd4, 0x73, 0xd0, 0x36, 0x51, 0xc2, 0xd0, 0xb4, 0x29, 0x35, 0x85, 0xa5, + 0x5a, 0x36, 0x47, 0xa1, 0x21, 0x30, 0x0e, 0x1e, 0x0f, 0x63, 0x29, 0x44, + 0xb9, 0xf5, 0x78, 0x97, 0xdf, 0x1c, 0x71, 0xbd, 0x9a, 0xdb, 0x32, 0x45, + 0x3f, 0xed, 0xd2, 0xcc, 0xcc, 0x52, 0x2c, 0x5d, 0x21, 0x7a, 0x9f, 0x24, + 0xc1, 0xb7, 0xd3, 0xb5, 0x3f, 0xbd, 0x46, 0xb7, 0x25, 0x96, 0x06, 0xb4, + 0x12, 0x5d, 0xb2, 0xb3, 0xb5, 0xb1, 0x69, 0x67, 0x96, 0x53, 0x27, 0x77, + 0xa0, 0x8d, 0xc2, 0x22, 0x6a, 0x32, 0x25, 0xcf, 0x4e, 0x4e, 0x0f, 0xcb, + 0x0d, 0xe4, 0xc9, 0x29, 0x60, 0x30, 0x9d, 0x54, 0x56, 0xc2, 0xa5, 0x32, + 0x49, 0xce, 0xf6, 0xce, 0xa2, 0xe8, 0x2d, 0x3e, 0xf8, 0x70, 0x3f, 0xcf, + 0x2f, 0x41, 0xc5, 0xfe, 0x57, 0x56, 0x40, 0x38, 0xbe, 0xa0, 0xfa, 0xdf, + 0xfe, 0x8e, 0x7d, 0xf0, 0x02, 0xec, 0xd2, 0xbf, 0x46, 0x58, 0x1d, 0x81, + 0x91, 0xc5, 0x6c, 0x7b, 0xe6, 0x09, 0x26, 0xb1, 0x3d, 0x7d, 0x65, 0x0d, + 0x4b, 0x31, 0x40, 0xac, 0xbb, 0x7f, 0xe0, 0xed, 0xa4, 0x96, 0x03, 0x15, + 0x32, 0x5d, 0x4a, 0xea, 0x2a, 0xaf, 0xd6, 0xe7, 0xc2, 0x98, 0x67, 0xd8, + 0x0d, 0xcd, 0x4a, 0xbc, 0x98, 0x3f, 0x65, 0x3b, 0x38, 0xa1, 0x6d, 0xf0, + 0x7e, 0x59, 0x7d, 0x43, 0x75, 0xbc, 0x05, 0x01, 0x28, 0xc8, 0x93, 0x41, + 0x97, 0x10, 0x93, 0xe5, 0x9f, 0x06, 0x5f, 0xec, 0x55, 0x08, 0xda, 0xf3, + 0x2d, 0x76, 0x5b, 0x04, 0x45, 0x07, 0xb5, 0x2f, 0xb4, 0x0c, 0x8b, 0x5a, + 0xe7, 0x0b, 0x31, 0x45, 0x81, 0x92, 0xe2, 0x61, 0x9b, 0x17, 0x66, 0xa7, + 0xdc, 0x47, 0x7e, 0x59, 0x72, 0x2d, 0x2e, 0xf6, 0x55, 0xe8, 0x72, 0x46, + 0x8c, 0x6f, 0x2d, 0x67, 0x7d, 0xf1, 0xcc, 0xdc, 0x50, 0xb1, 0x5e, 0x77, + 0xdc, 0x94, 0x18, 0x4e, 0x92, 0xa0, 0x61, 0xba, 0x71, 0x11, 0x4e, 0xc2, + 0xaa, 0x6d, 0x0b, 0xf3, 0x1f, 0x62, 0xff, 0x77, 0xbf, 0x5d, 0x7e, 0x8b, + 0x8d, 0x74, 0x16, 0xb7, 0xa8, 0x9f, 0xd7, 0xcf, 0xde, 0x5a, 0xa7, 0xaa, + 0x51, 0xf2, 0x72, 0xce, 0x9e, 0xbd, 0xdf, 0x7f, 0x23, 0x70, 0xa8, 0xae, + 0x4d, 0xf0, 0x8b, 0x9b, 0x50, 0x3f, 0x97, 0x95, 0x64, 0x51, 0x2a, 0x25, + 0x3d, 0x50, 0x6a, 0x48, 0x43, 0x73, 0x56, 0xec, 0x0d, 0x0a, 0x60, 0xaf, + 0xd2, 0xb6, 0x25, 0xcf, 0x96, 0x69, 0x5e, 0x45, 0xbb, 0x22, 0xfc, 0x22, + 0x94, 0xc3, 0x65, 0x17, 0x9d, 0xbd, 0x84, 0x8a, 0x79, 0x29, 0xfe, 0xb6, + 0x18, 0x81, 0x46, 0x0d, 0x5a, 0x04, 0x26, 0x20, 0xe5, 0xaa, 0xde, 0xa5, + 0x6d, 0x98, 0xd7, 0xa7, 0x20, 0x32, 0x2f, 0x45, 0xe8, 0x6c, 0xa7, 0x98, + 0x0c, 0x27, 0x0e, 0x00, 0xc1, 0x08, 0x4b, 0x56, 0x3f, 0x00, 0xf1, 0x27, + 0xea, 0xdb, 0xbb, 0xa9, 0xda, 0x03, 0x7b, 0x28, 0xdb, 0xb1, 0x5e, 0x45, + 0x83, 0x85, 0x05, 0xa1, 0x60, 0x30, 0x81, 0x82, 0x19, 0x78, 0x22, 0x84, + 0x36, 0x58, 0xff, 0x71, 0xb2, 0xe6, 0xea, 0xac, 0xca, 0xb4, 0x2c, 0x5a, + 0xdd, 0x80, 0xaf, 0xda, 0xa4, 0x4c, 0x4c, 0x46, 0x05, 0x18, 0x1c, 0x05, + 0x00, 0xf9, 0x52, 0xa1, 0xe3, 0x1f, 0x4e, 0x3f, 0x6e, 0xfb, 0x44, 0xb4, + 0xab, 0x7b, 0xdc, 0x02, 0xbe, 0xf5, 0xd2, 0xb6, 0xd4, 0x40, 0xeb, 0x0b, + 0x33, 0xc0, 0xc2, 0xbe, 0xde, 0xd9, 0x10, 0x18, 0x69, 0x48, 0x9b, 0x08, + 0x62, 0x48, 0x07, 0x97, 0x01, 0xc6, 0x23, 0x23, 0xff, 0xdc, 0xcb, 0xfc, + 0xf6, 0x49, 0x8a, 0x77, 0x76, 0xf6, 0xc2, 0xc8, 0x22, 0xe2, 0x89, 0x4b, + 0x41, 0xc6, 0x21, 0x30, 0x92, 0x98, 0x49, 0xc0, 0xfc, 0xb9, 0x96, 0x95, + 0xb5, 0xdb, 0x14, 0xfa, 0xf7, 0x9a, 0xb5, 0xe5, 0x0d, 0xd7, 0x70, 0x39, + 0x00, 0x3c, 0x43, 0x6c, 0x20, 0x89, 0x7f, 0x2f, 0x6e, 0xd9, 0xe5, 0x20, + 0x61, 0xa4, 0x73, 0xd8, 0x88, 0x11, 0xd6, 0x52, 0x2d, 0x09, 0xc0, 0xc0, + 0x18, 0x3d, 0x68, 0x0d, 0x25, 0x1d, 0x03, 0x21, 0x8c, 0xd5, 0x78, 0x81, + 0x4f, 0xac, 0x92, 0xac, 0x1b, 0x16, 0x03, 0x05, 0x77, 0x2f, 0x6b, 0xdf, + 0x0c, 0xa6, 0x16, 0x32, 0xf3, 0xbb, 0x51, 0x40, 0xa4, 0xc9, 0x72, 0xad, + 0xd0, 0x51, 0xe0, 0x96, 0xa7, 0x26, 0x03, 0x0e, 0x28, 0xfa, 0xe7, 0x17, + 0x52, 0x1f, 0xc6, 0x6f, 0xe0, 0x2d, 0x85, 0xc2, 0x38, 0x1f, 0x83, 0xa0, + 0x0d, 0x49, 0xa9, 0xcb, 0xc0, 0xd0, 0xf1, 0x81, 0xf7, 0xf5, 0xbf, 0x2f, + 0xba, 0xaf, 0x59, 0xfd, 0xe4, 0xf7, 0xb0, 0x6f, 0xb9, 0xbe, 0x1b, 0xe8, + 0x2b, 0x8b, 0x41, 0x8e, 0x8b, 0x13, 0x82, 0x95, 0x30, 0x8c, 0x91, 0x50, + 0x87, 0xaa, 0x77, 0xcd, 0xea, 0x65, 0x0a, 0x16, 0xda, 0x20, 0xce, 0xdb, + 0xc0, 0xdb, 0x3b, 0xaa, 0x01, 0x6c, 0x9a, 0x44, 0xa9, 0xa0, 0xc9, 0x53, + 0x14, 0xdf, 0xc1, 0x81, 0x34, 0x42, 0x9e, 0xe0, 0x32, 0x8b, 0x28, 0x8a, + 0x19, 0xcb, 0xd0, 0xc1, 0xe6, 0x9a, 0x1f, 0xf8, 0x49, 0x4c, 0x98, 0xbd, + 0x37, 0xe7, 0xd8, 0x67, 0x25, 0x86, 0xe2, 0xc8, 0xac, 0x0e, 0x44, 0x41, + 0x68, 0x61, 0x05, 0x08, 0x29, 0x4b, 0x84, 0xa6, 0x2f, 0xb7, 0xfd, 0xd8, + 0xa4, 0xa9, 0x15, 0x52, 0xba, 0xd2, 0x08, 0xa1, 0xc0, 0x5b, 0x7d, 0x9d, + 0x33, 0x53, 0x0f, 0x20, 0x1a, 0x59, 0x8d, 0x81, 0xc9, 0x6c, 0xac, 0x41, + 0xdd, 0x2d, 0x88, 0xb3, 0x3f, 0x7d, 0x79, 0xfb, 0x43, 0xd1, 0x16, 0x82, + 0x41, 0x4f, 0x88, 0xe5, 0xc1, 0xff, 0x8b, 0xaa, 0x76, 0xb5, 0x5e, 0xe0, + 0x74, 0x39, 0xf5, 0xfd, 0xd4, 0x2b, 0x66, 0x8a, 0x8f, 0x17, 0x01, 0xb0, + 0x0f, 0x4c, 0x0d, 0xd2, 0xf2, 0xa2, 0xe2, 0xda, 0x58, 0xaa, 0xf0, 0xae, + 0xf2, 0xae, 0x1b, 0x28, 0xe8, 0x24, 0x86, 0xf1, 0xd3, 0x40, 0xc0, 0x88, + 0xac, 0x3a, 0x49, 0xff, 0x27, 0x6c, 0x18, 0x6f, 0xbe, 0x07, 0x25, 0x10, + 0x7f, 0x41, 0x83, 0x90, 0xf7, 0x54, 0x28, 0xe8, 0x08, 0x2b, 0x5a, 0xe8, + 0x6e, 0xa0, 0x58, 0xad, 0x85, 0x4c, 0x2c, 0xeb, 0x7b, 0xc0, 0x64, 0x7c, + 0xa8, 0x79, 0xc9, 0x16, 0x38, 0x0c, 0xe5, 0x6a, 0x87, 0x40, 0xab, 0x10, + 0xf9, 0xef, 0x6b, 0x3e, 0x2f, 0x4f, 0xad, 0x29, 0xb4, 0x71, 0x9c, 0xfd, + 0xec, 0xf8, 0x38, 0xc0, 0x51, 0x45, 0xda, 0x8c, 0x3c, 0x18, 0xde, 0xca, + 0xec, 0x01, 0xe2, 0x47, 0xea, 0x7d, 0xdf, 0xa9, 0xb2, 0xb6, 0xcd, 0xd9, + 0xe5, 0xe8, 0x83, 0xf5, 0xa7, 0xc3, 0x40, 0x4a, 0xd5, 0x77, 0x9f, 0x58, + 0x2d, 0xf4, 0xc3, 0x67, 0x7c, 0xdb, 0x4a, 0xdb, 0x9d, 0xcf, 0x7b, 0x2c, + 0x03, 0x33, 0xd3, 0x96, 0xd0, 0x28, 0x58, 0xa7, 0x4a, 0xb0, 0x44, 0x52, + 0x5a, 0x58, 0x59, 0xa0, 0xc4, 0x50, 0x10, 0x07, 0x4a, 0x82, 0x00, 0x95, + 0x14, 0xfe, 0x29, 0x4f, 0xb8, 0xad, 0x46, 0x7e, 0x37, 0xe5, 0xfd, 0x27, + 0x3d, 0x60, 0xdf, 0x30, 0x39, 0x06, 0x21, 0x16, 0x81, 0xe6, 0x47, 0x80, + 0xdd, 0xd2, 0xe5, 0x79, 0x38, 0x38, 0xac, 0x51, 0xcf, 0x5b, 0x53, 0xf9, + 0x11, 0x79, 0x9d, 0x2c, 0x1c, 0x66, 0xf2, 0x83, 0x10, 0x07, 0xf0, 0x86, + 0x25, 0xab, 0xd6, 0x9b, 0x63, 0x14, 0xa6, 0x2e, 0x8d, 0xcf, 0x34, 0xa8, + 0x0a, 0xef, 0xb9, 0x65, 0x9d, 0xc2, 0xac, 0xc5, 0x83, 0xdc, 0x02, 0x26, 0x4b, 0xff, 0x36, 0x23, 0x04, 0x83, 0x7a, 0x46 }; -void mpeg4_get_video_info(VideoDecodeInfo *info) +void +mpeg4_get_video_info (VideoDecodeInfo * info) { - info->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; - info->width = MPEG4_CLIP_WIDTH; - info->height = MPEG4_CLIP_HEIGHT; - info->data = mpeg4_clip; - info->data_size = MPEG4_CLIP_DATA_SIZE; + info->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE; + info->width = MPEG4_CLIP_WIDTH; + info->height = MPEG4_CLIP_HEIGHT; + info->data = mpeg4_clip; + info->data_size = MPEG4_CLIP_DATA_SIZE; } diff --git a/tests/test-subpicture-data.c b/tests/test-subpicture-data.c index 02f21888dc..0bd213394f 100644 --- a/tests/test-subpicture-data.c +++ b/tests/test-subpicture-data.c @@ -1421,7 +1421,8 @@ static const guint32 text[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; -void subpicture_get_info(VideoSubpictureInfo *info) +void +subpicture_get_info (VideoSubpictureInfo * info) { info->width = SUBPICTURE_WIDTH; info->height = SUBPICTURE_HEIGHT; diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 97ca232992..b842572196 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -27,146 +27,147 @@ #include "output.h" #include "test-subpicture-data.h" -static inline void pause(void) +static inline void +pause (void) { - g_print("Press any key to continue...\n"); - getchar(); + g_print ("Press any key to continue...\n"); + getchar (); } static gchar *g_codec_str; static gdouble g_global_alpha = 1.0; static GOptionEntry g_options[] = { - { "codec", 'c', - 0, - G_OPTION_ARG_STRING, &g_codec_str, - "codec to test", NULL }, - { "global-alpha", 'g', - 0, - G_OPTION_ARG_DOUBLE, &g_global_alpha, - "global-alpha value", NULL }, - { NULL, } + {"codec", 'c', + 0, + G_OPTION_ARG_STRING, &g_codec_str, + "codec to test", NULL}, + {"global-alpha", 'g', + 0, + G_OPTION_ARG_DOUBLE, &g_global_alpha, + "global-alpha value", NULL}, + {NULL,} }; static void -upload_subpicture(GstBuffer *buffer, const VideoSubpictureInfo *subinfo) +upload_subpicture (GstBuffer * buffer, const VideoSubpictureInfo * subinfo) { - const guint32 * const src = subinfo->data; - guint i, len = subinfo->data_size / 4; - GstMapInfo map_info; - guint32 *dst; + const guint32 *const src = subinfo->data; + guint i, len = subinfo->data_size / 4; + GstMapInfo map_info; + guint32 *dst; - if (!gst_buffer_map(buffer, &map_info, GST_MAP_WRITE)) - return; - dst = (guint32 *)map_info.data; + if (!gst_buffer_map (buffer, &map_info, GST_MAP_WRITE)) + return; + dst = (guint32 *) map_info.data; - /* Convert from RGBA source to ARGB */ - for (i = 0; i < len; i++) { - const guint32 rgba = src[i]; - dst[i] = (rgba >> 8) | (rgba << 24); - } + /* Convert from RGBA source to ARGB */ + for (i = 0; i < len; i++) { + const guint32 rgba = src[i]; + dst[i] = (rgba >> 8) | (rgba << 24); + } - gst_buffer_unmap(buffer, &map_info); + gst_buffer_unmap (buffer, &map_info); } int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { - GstVaapiDisplay *display; - GstVaapiWindow *window; - GstVaapiDecoder *decoder; - GstVaapiSurfaceProxy *proxy; - GstVaapiSurface *surface; - GstBuffer *buffer; - VideoSubpictureInfo subinfo; - GstVaapiRectangle subrect; - GstVideoOverlayRectangle *overlay; - GstVideoOverlayComposition *compo; - guint flags = 0; + GstVaapiDisplay *display; + GstVaapiWindow *window; + GstVaapiDecoder *decoder; + GstVaapiSurfaceProxy *proxy; + GstVaapiSurface *surface; + GstBuffer *buffer; + VideoSubpictureInfo subinfo; + GstVaapiRectangle subrect; + GstVideoOverlayRectangle *overlay; + GstVideoOverlayComposition *compo; + guint flags = 0; - static const guint win_width = 640; - static const guint win_height = 480; + static const guint win_width = 640; + static const guint win_height = 480; - if (!video_output_init(&argc, argv, g_options)) - g_error("failed to initialize video output subsystem"); + if (!video_output_init (&argc, argv, g_options)) + g_error ("failed to initialize video output subsystem"); - if (g_global_alpha != 1.0) - flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA; + if (g_global_alpha != 1.0) + flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA; - g_print("Test subpicture\n"); + g_print ("Test subpicture\n"); - display = video_output_create_display(NULL); - if (!display) - g_error("could not create VA display"); + display = video_output_create_display (NULL); + if (!display) + g_error ("could not create VA display"); - window = video_output_create_window(display, win_width, win_height); - if (!window) - g_error("could not create window"); + window = video_output_create_window (display, win_width, win_height); + if (!window) + g_error ("could not create window"); - decoder = decoder_new(display, g_codec_str); - if (!decoder) - g_error("could not create decoder"); + decoder = decoder_new (display, g_codec_str); + if (!decoder) + g_error ("could not create decoder"); - if (!decoder_put_buffers(decoder)) - g_error("could not fill decoder with sample data"); + if (!decoder_put_buffers (decoder)) + g_error ("could not fill decoder with sample data"); - proxy = decoder_get_surface(decoder); - if (!proxy) - g_error("could not get decoded surface"); + proxy = decoder_get_surface (decoder); + if (!proxy) + g_error ("could not get decoded surface"); - surface = gst_vaapi_surface_proxy_get_surface(proxy); + surface = gst_vaapi_surface_proxy_get_surface (proxy); - subpicture_get_info(&subinfo); - buffer = gst_buffer_new_and_alloc(subinfo.data_size); - upload_subpicture(buffer, &subinfo); + subpicture_get_info (&subinfo); + buffer = gst_buffer_new_and_alloc (subinfo.data_size); + upload_subpicture (buffer, &subinfo); - /* We position the subpicture at the bottom center */ - subrect.x = (gst_vaapi_surface_get_width(surface) - subinfo.width) / 2; - subrect.y = gst_vaapi_surface_get_height(surface) - subinfo.height - 10; - subrect.height = subinfo.height; - subrect.width = subinfo.width; + /* We position the subpicture at the bottom center */ + subrect.x = (gst_vaapi_surface_get_width (surface) - subinfo.width) / 2; + subrect.y = gst_vaapi_surface_get_height (surface) - subinfo.height - 10; + subrect.height = subinfo.height; + subrect.width = subinfo.width; - { - GstVideoMeta * const vmeta = - gst_buffer_add_video_meta(buffer, GST_VIDEO_FRAME_FLAG_NONE, - GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB, - subinfo.width, subinfo.height); - if (!vmeta) - g_error("could not create video meta"); + { + GstVideoMeta *const vmeta = + gst_buffer_add_video_meta (buffer, GST_VIDEO_FRAME_FLAG_NONE, + GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB, + subinfo.width, subinfo.height); + if (!vmeta) + g_error ("could not create video meta"); - overlay = gst_video_overlay_rectangle_new_raw(buffer, - subrect.x, subrect.y, subrect.width, subrect.height, flags); - } - if (!overlay) - g_error("could not create video overlay"); - gst_buffer_unref(buffer); + overlay = gst_video_overlay_rectangle_new_raw (buffer, + subrect.x, subrect.y, subrect.width, subrect.height, flags); + } + if (!overlay) + g_error ("could not create video overlay"); + gst_buffer_unref (buffer); - if (flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA) - gst_video_overlay_rectangle_set_global_alpha(overlay, g_global_alpha); + if (flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA) + gst_video_overlay_rectangle_set_global_alpha (overlay, g_global_alpha); - compo = gst_video_overlay_composition_new(overlay); - if (!compo) - g_error("could not create video overlay composition"); - gst_video_overlay_rectangle_unref(overlay); + compo = gst_video_overlay_composition_new (overlay); + if (!compo) + g_error ("could not create video overlay composition"); + gst_video_overlay_rectangle_unref (overlay); - if (!gst_vaapi_surface_set_subpictures_from_composition(surface, compo, - FALSE)) - g_error("could not create subpictures from video overlay compoition"); + if (!gst_vaapi_surface_set_subpictures_from_composition (surface, compo, + FALSE)) + g_error ("could not create subpictures from video overlay compoition"); - gst_vaapi_window_show(window); + gst_vaapi_window_show (window); - if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, - GST_VAAPI_PICTURE_STRUCTURE_FRAME)) - g_error("could not render surface"); + if (!gst_vaapi_window_put_surface (window, surface, NULL, NULL, + GST_VAAPI_PICTURE_STRUCTURE_FRAME)) + g_error ("could not render surface"); - pause(); + pause (); - gst_video_overlay_composition_unref(compo); - gst_vaapi_surface_proxy_unref(proxy); - gst_vaapi_decoder_unref(decoder); - gst_vaapi_window_unref(window); - gst_vaapi_display_unref(display); - g_free(g_codec_str); - video_output_exit(); - return 0; + gst_video_overlay_composition_unref (compo); + gst_vaapi_surface_proxy_unref (proxy); + gst_vaapi_decoder_unref (decoder); + gst_vaapi_window_unref (window); + gst_vaapi_display_unref (display); + g_free (g_codec_str); + video_output_exit (); + return 0; } diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index 734774f567..b58c5cf859 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -29,78 +29,78 @@ #define MAX_SURFACES 4 int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { - GstVaapiDisplay *display; - GstVaapiSurface *surface; - GstVaapiID surface_id; - GstVaapiSurface *surfaces[MAX_SURFACES]; - GstVaapiVideoPool *pool; - gint i; + GstVaapiDisplay *display; + GstVaapiSurface *surface; + GstVaapiID surface_id; + GstVaapiSurface *surfaces[MAX_SURFACES]; + GstVaapiVideoPool *pool; + gint i; - static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - static const guint width = 320; - static const guint height = 240; + static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + static const guint width = 320; + static const guint height = 240; - if (!video_output_init(&argc, argv, NULL)) - g_error("failed to initialize video output subsystem"); + if (!video_output_init (&argc, argv, NULL)) + g_error ("failed to initialize video output subsystem"); - display = video_output_create_display(NULL); - if (!display) - g_error("could not create Gst/VA display"); + display = video_output_create_display (NULL); + if (!display) + g_error ("could not create Gst/VA display"); - surface = gst_vaapi_surface_new(display, chroma_type, width, height); + surface = gst_vaapi_surface_new (display, chroma_type, width, height); + if (!surface) + g_error ("could not create Gst/VA surface"); + + surface_id = gst_vaapi_surface_get_id (surface); + g_print ("created surface %" GST_VAAPI_ID_FORMAT "\n", + GST_VAAPI_ID_ARGS (surface_id)); + + gst_vaapi_object_unref (surface); + + pool = gst_vaapi_surface_pool_new (display, GST_VIDEO_FORMAT_ENCODED, + width, height); + if (!pool) + g_error ("could not create Gst/VA surface pool"); + + for (i = 0; i < MAX_SURFACES; i++) { + surface = gst_vaapi_video_pool_get_object (pool); if (!surface) - g_error("could not create Gst/VA surface"); + g_error ("could not allocate Gst/VA surface from pool"); + g_print ("created surface %" GST_VAAPI_ID_FORMAT " from pool\n", + GST_VAAPI_ID_ARGS (gst_vaapi_surface_get_id (surface))); + surfaces[i] = surface; + } - surface_id = gst_vaapi_surface_get_id(surface); - g_print("created surface %" GST_VAAPI_ID_FORMAT "\n", - GST_VAAPI_ID_ARGS(surface_id)); + /* Check the pool doesn't return the last free'd surface */ + surface = gst_vaapi_object_ref (surfaces[1]); - gst_vaapi_object_unref(surface); + for (i = 0; i < 2; i++) + gst_vaapi_video_pool_put_object (pool, surfaces[i]); - pool = gst_vaapi_surface_pool_new(display, GST_VIDEO_FORMAT_ENCODED, - width, height); - if (!pool) - g_error("could not create Gst/VA surface pool"); + for (i = 0; i < 2; i++) { + surfaces[i] = gst_vaapi_video_pool_get_object (pool); + if (!surfaces[i]) + g_error ("could not re-allocate Gst/VA surface%d from pool", i); + g_print ("created surface %" GST_VAAPI_ID_FORMAT " from pool (realloc)\n", + GST_VAAPI_ID_ARGS (gst_vaapi_surface_get_id (surfaces[i]))); + } - for (i = 0; i < MAX_SURFACES; i++) { - surface = gst_vaapi_video_pool_get_object(pool); - if (!surface) - g_error("could not allocate Gst/VA surface from pool"); - g_print("created surface %" GST_VAAPI_ID_FORMAT " from pool\n", - GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface))); - surfaces[i] = surface; - } + if (surface == surfaces[0]) + g_error ("Gst/VA pool doesn't queue free surfaces"); - /* Check the pool doesn't return the last free'd surface */ - surface = gst_vaapi_object_ref(surfaces[1]); + for (i = MAX_SURFACES - 1; i >= 0; i--) { + if (!surfaces[i]) + continue; + gst_vaapi_video_pool_put_object (pool, surfaces[i]); + surfaces[i] = NULL; + } - for (i = 0; i < 2; i++) - gst_vaapi_video_pool_put_object(pool, surfaces[i]); - - for (i = 0; i < 2; i++) { - surfaces[i] = gst_vaapi_video_pool_get_object(pool); - if (!surfaces[i]) - g_error("could not re-allocate Gst/VA surface%d from pool", i); - g_print("created surface %" GST_VAAPI_ID_FORMAT " from pool (realloc)\n", - GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surfaces[i]))); - } - - if (surface == surfaces[0]) - g_error("Gst/VA pool doesn't queue free surfaces"); - - for (i = MAX_SURFACES - 1; i >= 0; i--) { - if (!surfaces[i]) - continue; - gst_vaapi_video_pool_put_object(pool, surfaces[i]); - surfaces[i] = NULL; - } - - /* Unref in random order to check objects are correctly refcounted */ - gst_vaapi_display_unref(display); - gst_vaapi_video_pool_unref(pool); - gst_vaapi_object_unref(surface); - video_output_exit(); - return 0; + /* Unref in random order to check objects are correctly refcounted */ + gst_vaapi_display_unref (display); + gst_vaapi_video_pool_unref (pool); + gst_vaapi_object_unref (surface); + video_output_exit (); + return 0; } diff --git a/tests/test-textures.c b/tests/test-textures.c index 63b4c784ae..a2d2005f46 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -28,167 +28,152 @@ #include #include "image.h" -static inline void pause(void) +static inline void +pause (void) { - g_print("Press any key to continue...\n"); - getchar(); + g_print ("Press any key to continue...\n"); + getchar (); } -static inline guint gl_get_current_texture_2d(void) +static inline guint +gl_get_current_texture_2d (void) { - GLint texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture); - return (guint)texture; + GLint texture; + glGetIntegerv (GL_TEXTURE_BINDING_2D, &texture); + return (guint) texture; } int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { - GstVaapiDisplay *display; - GstVaapiWindow *window; - GstVaapiWindowGLX *glx_window; - GstVaapiSurface *surface; - GstVaapiImage *image; - GstVaapiTexture *textures[2]; - GstVaapiTexture *texture; - GLuint texture_id; - GstVaapiRectangle src_rect; - GstVaapiRectangle dst_rect; - guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + GstVaapiDisplay *display; + GstVaapiWindow *window; + GstVaapiWindowGLX *glx_window; + GstVaapiSurface *surface; + GstVaapiImage *image; + GstVaapiTexture *textures[2]; + GstVaapiTexture *texture; + GLuint texture_id; + GstVaapiRectangle src_rect; + GstVaapiRectangle dst_rect; + guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - static const guint width = 320; - static const guint height = 240; - static const guint win_width = 640; - static const guint win_height = 480; + static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + static const guint width = 320; + static const guint height = 240; + static const guint win_width = 640; + static const guint win_height = 480; - gst_init(&argc, &argv); + gst_init (&argc, &argv); - display = gst_vaapi_display_glx_new(NULL); - if (!display) - g_error("could not create VA display"); + display = gst_vaapi_display_glx_new (NULL); + if (!display) + g_error ("could not create VA display"); - surface = gst_vaapi_surface_new(display, chroma_type, width, height); - if (!surface) - g_error("could not create VA surface"); + surface = gst_vaapi_surface_new (display, chroma_type, width, height); + if (!surface) + g_error ("could not create VA surface"); - image = image_generate(display, GST_VIDEO_FORMAT_NV12, width, height); - if (!image) - g_error("could not create VA image"); - if (!image_upload(image, surface)) - g_error("could not upload VA image to surface"); + image = image_generate (display, GST_VIDEO_FORMAT_NV12, width, height); + if (!image) + g_error ("could not create VA image"); + if (!image_upload (image, surface)) + g_error ("could not upload VA image to surface"); - window = gst_vaapi_window_glx_new(display, win_width, win_height); - if (!window) - g_error("could not create window"); - glx_window = GST_VAAPI_WINDOW_GLX(window); + window = gst_vaapi_window_glx_new (display, win_width, win_height); + if (!window) + g_error ("could not create window"); + glx_window = GST_VAAPI_WINDOW_GLX (window); - gst_vaapi_window_show(window); + gst_vaapi_window_show (window); - if (!gst_vaapi_window_glx_make_current(glx_window)) - g_error("coult not bind GL context"); + if (!gst_vaapi_window_glx_make_current (glx_window)) + g_error ("coult not bind GL context"); - g_print("#\n"); - g_print("# Create texture with gst_vaapi_texture_glx_new()\n"); - g_print("#\n"); - { - texture = gst_vaapi_texture_glx_new( - display, - GL_TEXTURE_2D, - GL_RGBA, - width, - height - ); - if (!texture) - g_error("could not create VA texture"); + g_print ("#\n"); + g_print ("# Create texture with gst_vaapi_texture_glx_new()\n"); + g_print ("#\n"); + { + texture = gst_vaapi_texture_glx_new (display, + GL_TEXTURE_2D, GL_RGBA, width, height); + if (!texture) + g_error ("could not create VA texture"); - textures[0] = texture; - texture_id = gst_vaapi_texture_get_id(texture); + textures[0] = texture; + texture_id = gst_vaapi_texture_get_id (texture); - if (!gst_vaapi_texture_put_surface(texture, surface, NULL, flags)) - g_error("could not transfer VA surface to texture"); + if (!gst_vaapi_texture_put_surface (texture, surface, NULL, flags)) + g_error ("could not transfer VA surface to texture"); - if (!gst_vaapi_window_glx_put_texture(glx_window, texture, NULL, NULL)) - g_error("could not render texture into the window"); - } + if (!gst_vaapi_window_glx_put_texture (glx_window, texture, NULL, NULL)) + g_error ("could not render texture into the window"); + } - g_print("#\n"); - g_print("# Create texture with gst_vaapi_texture_glx_new_wrapped()\n"); - g_print("#\n"); - { - const GLenum target = GL_TEXTURE_2D; - const GLenum format = GL_BGRA; + g_print ("#\n"); + g_print ("# Create texture with gst_vaapi_texture_glx_new_wrapped()\n"); + g_print ("#\n"); + { + const GLenum target = GL_TEXTURE_2D; + const GLenum format = GL_BGRA; - glEnable(target); - glGenTextures(1, &texture_id); - glBindTexture(target, texture_id); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glTexImage2D( - target, - 0, - GL_RGBA8, - width, height, - 0, - format, - GL_UNSIGNED_BYTE, - NULL - ); - glDisable(target); + glEnable (target); + glGenTextures (1, &texture_id); + glBindTexture (target, texture_id); + glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glPixelStorei (GL_UNPACK_ALIGNMENT, 4); + glTexImage2D (target, + 0, GL_RGBA8, width, height, 0, format, GL_UNSIGNED_BYTE, NULL); + glDisable (target); - texture = gst_vaapi_texture_glx_new_wrapped( - display, - texture_id, - target, - format - ); - if (!texture) - g_error("could not create VA texture"); + texture = gst_vaapi_texture_glx_new_wrapped (display, + texture_id, target, format); + if (!texture) + g_error ("could not create VA texture"); - if (texture_id != gst_vaapi_texture_get_id(texture)) - g_error("invalid texture id"); + if (texture_id != gst_vaapi_texture_get_id (texture)) + g_error ("invalid texture id"); - if (gl_get_current_texture_2d() != texture_id) - g_error("gst_vaapi_texture_glx_new_wrapped() altered texture bindings"); + if (gl_get_current_texture_2d () != texture_id) + g_error ("gst_vaapi_texture_glx_new_wrapped() altered texture bindings"); - textures[1] = texture; + textures[1] = texture; - if (!gst_vaapi_texture_put_surface(texture, surface, NULL, flags)) - g_error("could not transfer VA surface to texture"); + if (!gst_vaapi_texture_put_surface (texture, surface, NULL, flags)) + g_error ("could not transfer VA surface to texture"); - if (gl_get_current_texture_2d() != texture_id) - g_error("gst_vaapi_texture_put_surface() altered texture bindings"); + if (gl_get_current_texture_2d () != texture_id) + g_error ("gst_vaapi_texture_put_surface() altered texture bindings"); - src_rect.x = 0; - src_rect.y = 0; - src_rect.width = width; - src_rect.height = height; + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = width; + src_rect.height = height; - dst_rect.x = win_width/2; - dst_rect.y = win_height/2; - dst_rect.width = win_width/2; - dst_rect.height = win_height/2; + dst_rect.x = win_width / 2; + dst_rect.y = win_height / 2; + dst_rect.width = win_width / 2; + dst_rect.height = win_height / 2; - if (!gst_vaapi_window_glx_put_texture(glx_window, texture, - &src_rect, &dst_rect)) - g_error("could not render texture into the window"); + if (!gst_vaapi_window_glx_put_texture (glx_window, texture, + &src_rect, &dst_rect)) + g_error ("could not render texture into the window"); - if (gl_get_current_texture_2d() != texture_id) - g_error("gst_vaapi_window_glx_put_texture() altered texture bindings"); - } + if (gl_get_current_texture_2d () != texture_id) + g_error ("gst_vaapi_window_glx_put_texture() altered texture bindings"); + } - gst_vaapi_window_glx_swap_buffers(glx_window); - pause(); + gst_vaapi_window_glx_swap_buffers (glx_window); + pause (); - gst_vaapi_texture_unref(textures[0]); - gst_vaapi_texture_unref(textures[1]); - glDeleteTextures(1, &texture_id); + gst_vaapi_texture_unref (textures[0]); + gst_vaapi_texture_unref (textures[1]); + glDeleteTextures (1, &texture_id); - gst_vaapi_window_unref(window); - gst_vaapi_display_unref(display); - gst_deinit(); - return 0; + gst_vaapi_window_unref (window); + gst_vaapi_display_unref (display); + gst_deinit (); + return 0; } diff --git a/tests/test-vc1.c b/tests/test-vc1.c index f03b31f460..4a8dc9e848 100644 --- a/tests/test-vc1.c +++ b/tests/test-vc1.c @@ -28,1752 +28,1753 @@ /* Data dump of a 320x240 VC-1 video clip (vc1.raw), it has a single frame */ static const guchar vc1_clip[VC1_CLIP_DATA_SIZE] = { - 0x00, 0x00, 0x01, 0x0f, 0xca, 0x00, 0x09, 0xf0, 0x77, 0x0a, 0x09, 0x20, - 0x1d, 0xff, 0x0a, 0x0b, 0x80, 0x84, 0x80, 0x00, 0x00, 0x01, 0x0e, 0x4c, - 0x10, 0x80, 0x00, 0x00, 0x01, 0x0d, 0xc1, 0xd8, 0xd4, 0x47, 0xd0, 0xaa, - 0xc4, 0x45, 0xaa, 0xb8, 0x01, 0xdf, 0x4c, 0xc1, 0x3a, 0xfa, 0x13, 0x67, - 0x6a, 0xed, 0x2c, 0x67, 0xbc, 0xef, 0xdc, 0x69, 0x99, 0xf8, 0x53, 0x97, - 0x01, 0xdc, 0xbe, 0xd8, 0x3b, 0xa2, 0x96, 0xe8, 0xa1, 0x94, 0x02, 0x57, - 0x82, 0x82, 0xd6, 0x14, 0xc7, 0x61, 0x5a, 0x00, 0x22, 0x81, 0x73, 0x33, - 0x20, 0x00, 0xa0, 0x09, 0xc0, 0x50, 0xfa, 0x06, 0xce, 0x35, 0x91, 0x8d, - 0x19, 0x0f, 0x07, 0x1e, 0x84, 0x5b, 0x3a, 0x29, 0x03, 0xad, 0x8f, 0x8a, - 0xd2, 0x22, 0xf0, 0xfc, 0x28, 0xd2, 0x95, 0x4a, 0xfe, 0x74, 0x4b, 0x23, - 0xe7, 0xd4, 0x12, 0x1f, 0x37, 0x01, 0x88, 0xf8, 0xa4, 0x09, 0x76, 0x51, - 0xae, 0xf4, 0x23, 0x6d, 0x29, 0x8c, 0x54, 0xaa, 0x2c, 0x68, 0x10, 0x7e, - 0x71, 0xbf, 0x10, 0xb4, 0x77, 0x97, 0x8b, 0xa1, 0x54, 0xd1, 0xda, 0xb5, - 0x5f, 0x61, 0xf0, 0x64, 0x64, 0x29, 0x25, 0x7d, 0x42, 0xe0, 0xff, 0x2a, - 0x83, 0x29, 0x61, 0xfc, 0xee, 0xe5, 0x11, 0x04, 0xc0, 0x43, 0xc0, 0xc4, - 0x0e, 0x18, 0x43, 0xb6, 0x08, 0x55, 0xa0, 0x22, 0xf4, 0x58, 0x01, 0xc6, - 0x43, 0x0d, 0xba, 0x04, 0x3e, 0x8e, 0x5f, 0xc1, 0x11, 0x56, 0xef, 0xd7, - 0x78, 0xe2, 0xd2, 0xdb, 0x84, 0x16, 0x76, 0xc6, 0x92, 0x15, 0xf6, 0xc2, - 0x76, 0x2f, 0xd2, 0xef, 0x46, 0x02, 0x60, 0x24, 0xda, 0x16, 0x48, 0x95, - 0xc4, 0x87, 0x81, 0xa7, 0xdd, 0xd7, 0x77, 0x56, 0xb7, 0xb5, 0x28, 0x9d, - 0x6b, 0x7b, 0xd6, 0x8b, 0x80, 0x42, 0x28, 0xb0, 0x28, 0x82, 0x50, 0x04, - 0x65, 0x1a, 0xc3, 0x79, 0x74, 0x6c, 0x3e, 0x9e, 0x69, 0x0e, 0xc1, 0xed, - 0x8d, 0xe9, 0xf0, 0xf4, 0xf8, 0xde, 0xc1, 0x62, 0x1d, 0x1f, 0x4a, 0x5d, - 0x02, 0x11, 0xfa, 0xd8, 0x10, 0xb8, 0xa0, 0xc5, 0xf5, 0x85, 0xd1, 0x19, - 0x14, 0x06, 0x21, 0x5b, 0xa5, 0x37, 0xcd, 0xf2, 0xbc, 0x3b, 0x7f, 0xe3, - 0x1c, 0x62, 0x51, 0x4b, 0x09, 0x2e, 0x48, 0x1f, 0x4e, 0x19, 0xe4, 0x90, - 0x22, 0x81, 0xf4, 0xf7, 0x16, 0x4f, 0xe5, 0x97, 0x12, 0x9b, 0x92, 0x6e, - 0xcc, 0x61, 0xd6, 0x4a, 0x59, 0x66, 0x7d, 0xc2, 0x1d, 0x33, 0x7e, 0x62, - 0x29, 0x81, 0x80, 0xb7, 0xa4, 0xcb, 0xc4, 0xc3, 0x9b, 0x1d, 0x2b, 0x00, - 0xc9, 0x78, 0x82, 0xef, 0xd7, 0xa5, 0xad, 0x08, 0x18, 0x7c, 0x97, 0x61, - 0x3e, 0xaf, 0x4e, 0x21, 0xd6, 0x5a, 0x35, 0xd6, 0xf9, 0xdf, 0x89, 0xe9, - 0x09, 0x99, 0x3e, 0x53, 0x81, 0x80, 0x21, 0xd9, 0x44, 0x7f, 0xb9, 0xe7, - 0x7d, 0x1d, 0xa6, 0xd4, 0xb6, 0x60, 0x71, 0xa3, 0x87, 0x13, 0x40, 0x7a, - 0x50, 0xac, 0x02, 0x87, 0xe3, 0x7a, 0xab, 0xce, 0x11, 0xed, 0x51, 0x97, - 0xc5, 0xf0, 0x33, 0xf5, 0x3b, 0x7e, 0x05, 0xda, 0x4d, 0x29, 0x23, 0xa7, - 0xca, 0x43, 0x0e, 0x72, 0xf0, 0x96, 0xe9, 0x95, 0x4a, 0x32, 0xb0, 0xc4, - 0xe5, 0x65, 0x73, 0xc3, 0x30, 0xea, 0xfb, 0x93, 0x04, 0x64, 0x48, 0x48, - 0x20, 0x1a, 0x8c, 0xde, 0xb0, 0x24, 0x7d, 0xd6, 0xe9, 0x5b, 0xb9, 0x0b, - 0x18, 0xb9, 0xc4, 0x4a, 0x81, 0xaa, 0xfb, 0x6b, 0x2f, 0xe6, 0x77, 0x00, - 0x17, 0xa8, 0x1f, 0x7f, 0x8b, 0xcd, 0xaf, 0xb5, 0xc1, 0x26, 0x99, 0x3f, - 0x74, 0xd9, 0x69, 0x4c, 0x4c, 0xe5, 0x8a, 0x51, 0x3b, 0x47, 0x18, 0x33, - 0x1a, 0xc5, 0xc3, 0xe1, 0xeb, 0xc7, 0x80, 0xa4, 0xb3, 0x5f, 0x22, 0x64, - 0xcc, 0x97, 0xcb, 0xdb, 0xe5, 0xc9, 0x09, 0x89, 0x65, 0xfd, 0x61, 0x76, - 0xc3, 0xf7, 0xfe, 0x7d, 0xe1, 0x70, 0x07, 0x9a, 0x17, 0x95, 0x08, 0x4d, - 0xec, 0xfb, 0x38, 0x61, 0x06, 0x1e, 0x96, 0x91, 0x19, 0x42, 0x88, 0xf1, - 0x45, 0x04, 0x69, 0x63, 0x1c, 0x99, 0xf8, 0x26, 0xf4, 0xfc, 0xf0, 0xeb, - 0x48, 0x06, 0x9d, 0xef, 0x46, 0x72, 0x41, 0xa9, 0xa5, 0xb8, 0x4a, 0xf0, - 0xd3, 0x82, 0x65, 0x88, 0x98, 0x40, 0x97, 0x4a, 0x95, 0x10, 0x52, 0xca, - 0x47, 0xec, 0x14, 0x75, 0x86, 0xd5, 0x7d, 0xf7, 0xda, 0xa5, 0x09, 0xc6, - 0x50, 0x02, 0x8f, 0xd7, 0x51, 0x42, 0x43, 0x60, 0x27, 0x67, 0xa0, 0xd6, - 0xd8, 0xcf, 0x58, 0xc5, 0x13, 0x27, 0xa2, 0x4e, 0x4f, 0xc3, 0xc2, 0x50, - 0xcb, 0x8d, 0x00, 0x53, 0x87, 0x5a, 0x6b, 0x4d, 0xb4, 0x07, 0x0b, 0x40, - 0xb3, 0xba, 0xc3, 0x14, 0xb8, 0x75, 0xda, 0x84, 0x50, 0x96, 0x12, 0xc6, - 0xd1, 0x00, 0xa5, 0xa3, 0x4c, 0x11, 0x45, 0x02, 0xc7, 0x2f, 0xe2, 0x8f, - 0xb7, 0xe9, 0xff, 0xe2, 0x48, 0x8b, 0x28, 0x1c, 0x38, 0x8c, 0x41, 0xc9, - 0xd0, 0xfa, 0x13, 0x4f, 0xfd, 0x6b, 0x72, 0xa5, 0x0e, 0xd7, 0x2f, 0x2b, - 0xee, 0x37, 0xe6, 0xb0, 0x41, 0x4d, 0x45, 0x83, 0x88, 0x6d, 0x14, 0x6d, - 0xa6, 0xb1, 0x59, 0x7d, 0x7e, 0xa7, 0x8d, 0x48, 0xc3, 0x4c, 0x80, 0x91, - 0xf0, 0x4d, 0xfc, 0xaf, 0xe6, 0xae, 0x9a, 0x24, 0xca, 0x73, 0xc4, 0x13, - 0xf8, 0x28, 0xd2, 0xbf, 0xdf, 0xc4, 0xd0, 0x4e, 0xf4, 0x3e, 0x2c, 0x60, - 0x6a, 0xd4, 0x6e, 0x44, 0x8a, 0xae, 0x09, 0x37, 0xb1, 0x98, 0xaf, 0x69, - 0xf0, 0xee, 0x6f, 0x0a, 0x55, 0x6d, 0x12, 0x7c, 0xf0, 0x08, 0x78, 0xd2, - 0x98, 0x7c, 0xdf, 0xd7, 0xa0, 0x0d, 0xf3, 0x52, 0x65, 0xf6, 0xb9, 0xfe, - 0xf3, 0x73, 0x4c, 0xe2, 0x3a, 0x27, 0x64, 0x00, 0x28, 0x54, 0x2d, 0x4a, - 0x59, 0x42, 0x43, 0xea, 0x26, 0xeb, 0x13, 0x2a, 0x5a, 0x9a, 0x35, 0xe9, - 0xe3, 0xe0, 0x3d, 0x84, 0xf0, 0x12, 0xbe, 0x84, 0x3f, 0x1c, 0xe6, 0x06, - 0xab, 0x30, 0x0d, 0xa3, 0xba, 0xe4, 0x24, 0xe0, 0x6f, 0x5c, 0xab, 0x43, - 0x9a, 0xf6, 0xf4, 0xd9, 0x74, 0x7e, 0x2c, 0x63, 0xf3, 0xd2, 0x17, 0x0b, - 0x57, 0xda, 0x1d, 0xd0, 0x47, 0x52, 0xc7, 0xc9, 0xb8, 0x14, 0x12, 0x23, - 0xc1, 0x23, 0x9b, 0x78, 0x51, 0x81, 0x7b, 0x66, 0x48, 0xbb, 0xc8, 0x7a, - 0x67, 0x84, 0x0a, 0xff, 0x82, 0xe9, 0x7e, 0xea, 0x5f, 0x5b, 0x94, 0xd6, - 0x24, 0x48, 0x3b, 0xa6, 0x25, 0x29, 0xd1, 0x92, 0x12, 0x9a, 0x5f, 0x84, - 0x3e, 0xb4, 0xe4, 0x3f, 0x15, 0xad, 0xe9, 0xec, 0xbc, 0x10, 0x7d, 0xc9, - 0xcd, 0xeb, 0x71, 0xd3, 0x79, 0x1a, 0xc2, 0xf5, 0x0d, 0x31, 0xac, 0x6a, - 0xac, 0xbc, 0x7f, 0x67, 0x43, 0x78, 0xc5, 0x23, 0x97, 0x56, 0x88, 0x3c, - 0xb0, 0x8e, 0x2c, 0x8a, 0x2b, 0x63, 0xfe, 0xb2, 0xaa, 0xb1, 0x71, 0x72, - 0x74, 0x41, 0xc3, 0x78, 0x0c, 0x5f, 0x92, 0x8d, 0x64, 0xe0, 0xf8, 0xde, - 0x09, 0x8f, 0xcd, 0x39, 0x45, 0x5a, 0x5d, 0x12, 0x6b, 0x26, 0xad, 0xfe, - 0xc0, 0x51, 0x1e, 0x00, 0xe9, 0x36, 0xf1, 0xb6, 0x74, 0x7b, 0x67, 0x6e, - 0xe2, 0xe4, 0xf4, 0x8e, 0x40, 0x87, 0xc6, 0x14, 0xcc, 0xa8, 0x25, 0x37, - 0x72, 0x0c, 0xc0, 0xf4, 0xff, 0xf4, 0x7d, 0xdc, 0xa8, 0xda, 0x68, 0xa5, - 0xbf, 0x04, 0xa3, 0x2c, 0x9f, 0xc7, 0x0a, 0x7c, 0x37, 0x86, 0xe7, 0x76, - 0x4e, 0x50, 0x79, 0xa5, 0xd1, 0x5f, 0x2e, 0x6f, 0x9a, 0x5c, 0x75, 0x73, - 0xd3, 0x7a, 0x10, 0x69, 0x45, 0xf1, 0x99, 0xca, 0x04, 0x24, 0x0a, 0x76, - 0xf5, 0xb9, 0xf7, 0xca, 0xf3, 0xfe, 0xde, 0x28, 0x70, 0x47, 0x3c, 0x35, - 0x17, 0x70, 0x21, 0x42, 0x32, 0x81, 0xfb, 0x3d, 0xc8, 0xf0, 0x35, 0xfe, - 0xe7, 0xee, 0x1b, 0x1e, 0xdd, 0xce, 0x19, 0xa2, 0x95, 0x95, 0x43, 0x2f, - 0xb2, 0x26, 0xcc, 0xbb, 0xb7, 0x8b, 0x8b, 0xff, 0x1c, 0xeb, 0x82, 0xa9, - 0x4f, 0x25, 0x58, 0xfa, 0x41, 0x22, 0x4a, 0xcb, 0x38, 0xc4, 0xff, 0x12, - 0x0d, 0xf7, 0x3b, 0xed, 0x0c, 0x7e, 0x29, 0xd3, 0x19, 0xe2, 0x2c, 0xff, - 0x8e, 0xbf, 0xe1, 0x1b, 0xc9, 0x6f, 0xac, 0x51, 0x97, 0x49, 0x68, 0x4d, - 0x20, 0x27, 0x3f, 0x11, 0xfe, 0x1e, 0x7f, 0xef, 0xda, 0x76, 0xba, 0xba, - 0xf2, 0xdb, 0x60, 0x36, 0x9a, 0xa3, 0x28, 0x89, 0xc8, 0x64, 0xb0, 0x90, - 0x79, 0xcb, 0x9d, 0x45, 0xcc, 0xdd, 0x6d, 0xf0, 0xd5, 0xb5, 0x8a, 0x64, - 0x51, 0x96, 0xcb, 0x12, 0x70, 0x0a, 0xca, 0x69, 0x34, 0x20, 0x43, 0x31, - 0x3c, 0xba, 0xb2, 0x80, 0xe1, 0xb2, 0x65, 0x79, 0x6f, 0x4e, 0x6e, 0x92, - 0x4b, 0xbf, 0x80, 0x2a, 0xb7, 0x97, 0x7f, 0xc9, 0xf5, 0xbc, 0xef, 0x1e, - 0x7f, 0xc9, 0xb6, 0x3d, 0x86, 0x4c, 0x89, 0x62, 0xac, 0x2b, 0xd0, 0x26, - 0x9d, 0xab, 0xeb, 0xfb, 0x5d, 0x4b, 0x6c, 0xe5, 0x58, 0x29, 0xb3, 0x4a, - 0x09, 0xed, 0x17, 0xf1, 0x00, 0xbb, 0x5c, 0x17, 0xc4, 0x56, 0x3b, 0xfc, - 0x13, 0x08, 0xc5, 0xcf, 0xc4, 0x14, 0x5f, 0xe2, 0xf8, 0xa5, 0xe2, 0xde, - 0x2f, 0x85, 0xde, 0xf7, 0xf7, 0x4d, 0xcd, 0x7b, 0xf2, 0xb6, 0x8b, 0x72, - 0x03, 0x6b, 0x2c, 0x7f, 0xde, 0x40, 0xf4, 0x76, 0x52, 0x2b, 0x61, 0x2d, - 0x72, 0xa2, 0x21, 0x0c, 0x1b, 0x44, 0x6c, 0x40, 0x04, 0xbc, 0x5e, 0xff, - 0xcb, 0xb6, 0x65, 0x99, 0xc6, 0xdb, 0xf7, 0x6f, 0xbc, 0x75, 0xd6, 0xcb, - 0x79, 0x6d, 0xd6, 0x94, 0xbd, 0xb7, 0x47, 0x89, 0xc6, 0xf6, 0xf0, 0xab, - 0x67, 0x60, 0x37, 0x32, 0x7d, 0x0f, 0x31, 0x08, 0xe2, 0x4e, 0x11, 0x0d, - 0x64, 0x1e, 0x66, 0xc6, 0xc6, 0xc5, 0x34, 0x56, 0xf8, 0xbf, 0x12, 0x83, - 0x7a, 0x75, 0xe0, 0x67, 0xae, 0x7b, 0x7e, 0xfb, 0xb6, 0x33, 0x38, 0xaa, - 0xea, 0x98, 0x9b, 0xfd, 0x36, 0x0d, 0x7e, 0x0f, 0xd4, 0xf9, 0x56, 0x6a, - 0xd5, 0x40, 0xb4, 0x38, 0xae, 0x6a, 0x7a, 0xc5, 0x40, 0x2c, 0x87, 0x72, - 0x80, 0x3e, 0x20, 0xf3, 0x48, 0xed, 0xbd, 0xb8, 0x13, 0xdf, 0xb7, 0xae, - 0x6a, 0xe6, 0x62, 0x6e, 0x73, 0x4c, 0xf0, 0x06, 0xba, 0x6c, 0xb2, 0xed, - 0xb6, 0x83, 0x32, 0x77, 0x63, 0xff, 0x84, 0x7e, 0xca, 0x91, 0xd7, 0x14, - 0xc7, 0xae, 0x12, 0x91, 0x49, 0xb6, 0x32, 0x92, 0x97, 0x5e, 0x39, 0x5a, - 0x71, 0x86, 0xdc, 0x92, 0xbb, 0x47, 0x8c, 0x3e, 0x24, 0xfc, 0x05, 0xf2, - 0x38, 0x7b, 0xdd, 0x4c, 0xec, 0x52, 0x8f, 0x80, 0x57, 0xd1, 0x52, 0x6b, - 0x0a, 0xb9, 0x81, 0xfd, 0x6b, 0xd2, 0x43, 0x58, 0x2c, 0x2a, 0xb8, 0x3d, - 0x66, 0xb0, 0x61, 0x9b, 0x3e, 0x7a, 0xc9, 0x38, 0x62, 0xc8, 0x6b, 0x4f, - 0xa0, 0xe3, 0xed, 0x13, 0x7b, 0xd6, 0x7c, 0xbb, 0x35, 0xaf, 0x81, 0xed, - 0x88, 0x91, 0x35, 0x2a, 0x5c, 0x5f, 0x47, 0xa7, 0x2f, 0x6f, 0xf5, 0x23, - 0x38, 0x20, 0x87, 0x5f, 0x65, 0x81, 0xfa, 0x44, 0x88, 0xd4, 0x96, 0x5e, - 0xc2, 0x84, 0xca, 0x39, 0x20, 0x28, 0x93, 0x94, 0x06, 0x4f, 0xc5, 0x41, - 0xff, 0x4e, 0x9d, 0xe6, 0xdb, 0x29, 0x50, 0xaf, 0x46, 0x49, 0x00, 0x24, - 0x04, 0xf2, 0xcd, 0x13, 0x84, 0x82, 0xa3, 0xc9, 0x21, 0x36, 0x26, 0x6f, - 0xad, 0xff, 0xb7, 0x6f, 0xf2, 0x6e, 0x15, 0x83, 0xa8, 0xb5, 0x2e, 0x89, - 0xfb, 0xca, 0xfe, 0xfa, 0x80, 0x2d, 0xc7, 0x43, 0xfe, 0xbe, 0xd5, 0x1b, - 0x8a, 0x4d, 0x08, 0xed, 0x55, 0x2c, 0x83, 0xc1, 0xe5, 0x7b, 0xc5, 0x1b, - 0x5d, 0xdd, 0xb7, 0x53, 0xf1, 0x3b, 0xd7, 0x7d, 0xed, 0xe6, 0x11, 0xbe, - 0x75, 0xb5, 0xb4, 0x22, 0x42, 0x53, 0x10, 0x81, 0x34, 0x7b, 0x81, 0x3c, - 0x94, 0x13, 0xc7, 0x2c, 0xed, 0xa1, 0xa3, 0x0a, 0x15, 0x7a, 0xb0, 0x26, - 0x69, 0xe0, 0x45, 0x19, 0xb1, 0x9c, 0x88, 0x9d, 0xe1, 0x61, 0x20, 0xee, - 0x3f, 0xe6, 0xa3, 0x8c, 0x61, 0x85, 0xa7, 0x28, 0xd2, 0x09, 0x7b, 0x69, - 0xb0, 0x95, 0x37, 0xd8, 0x96, 0x3c, 0xcc, 0x2c, 0x90, 0x83, 0x28, 0x8c, - 0x8b, 0x3b, 0xfe, 0xb7, 0xb5, 0x19, 0x15, 0x5e, 0xcf, 0x5f, 0xaf, 0x8c, - 0x76, 0x95, 0x02, 0x97, 0xe9, 0xac, 0x02, 0xb2, 0xee, 0x82, 0xe7, 0x16, - 0xca, 0x5b, 0x08, 0x22, 0xc6, 0x4e, 0xd2, 0xab, 0x10, 0x0f, 0x68, 0x5c, - 0xc2, 0x3d, 0x16, 0xf8, 0x74, 0x11, 0xd6, 0x4c, 0x65, 0xe1, 0x26, 0x9a, - 0x2d, 0xb0, 0x20, 0x66, 0xd2, 0xed, 0x60, 0xf4, 0xd1, 0xc2, 0x7d, 0x44, - 0xd7, 0xbd, 0x45, 0x36, 0x7b, 0xdc, 0xef, 0x87, 0xba, 0xbe, 0x16, 0x40, - 0x13, 0xa3, 0x3a, 0x6e, 0x12, 0xc0, 0xa3, 0xe2, 0x01, 0xfa, 0xde, 0xe5, - 0x75, 0xb9, 0x8a, 0x12, 0x19, 0x44, 0x8a, 0x12, 0xc9, 0x51, 0x84, 0xa5, - 0xcb, 0xc0, 0xec, 0xee, 0xd3, 0xaf, 0x34, 0xa4, 0x91, 0x34, 0x52, 0x01, - 0xeb, 0x00, 0x8e, 0x62, 0x71, 0x6f, 0x32, 0x80, 0x3e, 0xdc, 0x17, 0x3b, - 0x7d, 0x4b, 0x50, 0x4e, 0x81, 0x90, 0x98, 0xde, 0x4c, 0xc6, 0x90, 0x09, - 0x6e, 0xbb, 0x4e, 0x1f, 0x87, 0x0b, 0x2e, 0x1f, 0xed, 0x42, 0x0e, 0x2d, - 0x04, 0x24, 0xb0, 0x40, 0xc3, 0xde, 0x12, 0x24, 0x15, 0x2a, 0x68, 0x09, - 0xf8, 0xf8, 0x71, 0xf1, 0x85, 0x16, 0x12, 0xa4, 0x58, 0xc1, 0xa6, 0x19, - 0x1a, 0x68, 0x9d, 0xa1, 0x94, 0x32, 0x08, 0x11, 0x51, 0x14, 0xb1, 0xa4, - 0x24, 0x0c, 0xdd, 0x2c, 0x04, 0x20, 0x19, 0x72, 0x35, 0x60, 0xda, 0x79, - 0x84, 0x11, 0x05, 0xf0, 0xe6, 0x52, 0xf8, 0x9f, 0x3a, 0xd0, 0x9e, 0xe1, - 0xe4, 0x50, 0x99, 0x8c, 0xb4, 0xba, 0x33, 0xc7, 0xc0, 0x33, 0x00, 0x76, - 0x0e, 0x10, 0x19, 0x31, 0x23, 0x8d, 0x34, 0x96, 0xdf, 0xd8, 0x6b, 0x24, - 0x65, 0x3f, 0x4d, 0x1c, 0x95, 0x5a, 0x79, 0xc2, 0xe5, 0xb2, 0x36, 0xc5, - 0xa6, 0x8b, 0x28, 0x03, 0x95, 0xda, 0x51, 0xa3, 0x96, 0x00, 0xf9, 0xe0, - 0xbc, 0x7e, 0xc5, 0xab, 0x8a, 0x64, 0xa5, 0x7c, 0xf3, 0x65, 0x98, 0xc1, - 0x92, 0x4b, 0x9f, 0xa6, 0x87, 0x8a, 0x35, 0xa5, 0x35, 0x14, 0x93, 0x26, - 0x05, 0xfe, 0xec, 0x4b, 0xdc, 0xea, 0xd6, 0xb6, 0x54, 0x23, 0x2c, 0x24, - 0x72, 0xfe, 0x71, 0x90, 0x31, 0xfd, 0x00, 0x84, 0xc2, 0xc8, 0x63, 0x8a, - 0x88, 0xcb, 0x27, 0xf0, 0x7e, 0x05, 0x1e, 0xf3, 0xb4, 0xfa, 0x7e, 0xe1, - 0x77, 0x67, 0xe3, 0xa6, 0x28, 0x11, 0x48, 0xe3, 0xbd, 0x00, 0x25, 0x7b, - 0x30, 0xcb, 0xec, 0x27, 0xc1, 0x61, 0x28, 0x1c, 0x56, 0x66, 0x12, 0x10, - 0xba, 0x08, 0x03, 0x91, 0x43, 0xd3, 0x6d, 0x2a, 0xcd, 0x2a, 0x58, 0x64, - 0x68, 0x24, 0x4f, 0xc7, 0x47, 0xf1, 0x7c, 0x69, 0x9a, 0x14, 0x64, 0x5e, - 0x53, 0xbd, 0x74, 0x85, 0xa9, 0x29, 0xa6, 0x7e, 0xae, 0x39, 0x35, 0x40, - 0x8c, 0xe5, 0x59, 0x30, 0x5c, 0x7f, 0x46, 0xa1, 0x37, 0x29, 0x04, 0x07, - 0xc5, 0xf1, 0xcf, 0x30, 0x0f, 0x89, 0x87, 0x31, 0x4f, 0x33, 0xa2, 0x04, - 0xb2, 0x9b, 0x30, 0x55, 0x14, 0xb1, 0x82, 0xac, 0x3e, 0xb8, 0x1a, 0xb9, - 0xca, 0xa5, 0xe9, 0x4b, 0x28, 0x77, 0x3a, 0x63, 0xe8, 0xad, 0xbe, 0x98, - 0xd2, 0x2d, 0x32, 0xc6, 0x30, 0x82, 0x0e, 0xc1, 0x8f, 0xb9, 0x70, 0x13, - 0xca, 0x42, 0xd8, 0x07, 0x0f, 0x23, 0xd9, 0x5a, 0xed, 0x92, 0x9b, 0x38, - 0xc5, 0xa0, 0x65, 0xb1, 0x08, 0x90, 0xcb, 0x61, 0x2c, 0x05, 0x1f, 0xa6, - 0x2a, 0x55, 0x24, 0x2f, 0x40, 0xc2, 0x4f, 0x5c, 0xb3, 0xcc, 0xd5, 0xfb, - 0x57, 0xda, 0x92, 0x08, 0xed, 0x0e, 0x56, 0x4e, 0x55, 0x6d, 0xfc, 0xc3, - 0x66, 0x95, 0x9c, 0x81, 0x27, 0xe5, 0x6c, 0x9d, 0x42, 0x94, 0x38, 0x68, - 0x48, 0x22, 0x58, 0x48, 0x86, 0xfa, 0x83, 0x66, 0xb6, 0xbd, 0xca, 0x0d, - 0x0c, 0x72, 0x68, 0xd6, 0x07, 0xe4, 0xcc, 0x84, 0x76, 0x85, 0x0f, 0x9c, - 0x7a, 0x2d, 0x6a, 0xed, 0x3e, 0x34, 0xda, 0x2b, 0xf2, 0xf4, 0x67, 0xa6, - 0x00, 0xd1, 0x64, 0x5e, 0x45, 0x12, 0x82, 0x2d, 0x95, 0x2f, 0xac, 0x58, - 0xf9, 0xea, 0x65, 0x4b, 0x27, 0xdb, 0x3d, 0xdd, 0x8d, 0x8a, 0x5e, 0xda, - 0xb5, 0xd6, 0x05, 0x88, 0x64, 0x1c, 0x84, 0x7f, 0x69, 0x12, 0x11, 0x2f, - 0x80, 0x7d, 0x12, 0xbb, 0xaa, 0x50, 0x71, 0x9b, 0x4c, 0xba, 0xdf, 0xaa, - 0x5e, 0xf6, 0x34, 0x1f, 0xef, 0xa5, 0x4f, 0xfa, 0x95, 0x34, 0xef, 0x84, - 0xed, 0xd9, 0x2f, 0x1c, 0xcd, 0xc6, 0x5e, 0x90, 0xfb, 0x13, 0xf3, 0xf0, - 0xfa, 0x3f, 0x7f, 0x77, 0xca, 0x76, 0x12, 0x9a, 0x3c, 0x92, 0x86, 0xed, - 0xcb, 0xe0, 0x22, 0x84, 0x86, 0x5d, 0x02, 0xf2, 0xfa, 0x37, 0x83, 0x64, - 0xad, 0x1f, 0x0d, 0xdb, 0x95, 0x8f, 0x3d, 0x70, 0xbe, 0xff, 0xfb, 0x5d, - 0xfd, 0xbe, 0x1b, 0x92, 0xcc, 0xb6, 0x95, 0xef, 0x63, 0x8a, 0x72, 0xc8, - 0x4e, 0x88, 0xf9, 0xa3, 0xb9, 0x07, 0x9c, 0xb3, 0x3f, 0xad, 0xca, 0x84, - 0xb2, 0x06, 0x42, 0x28, 0xb7, 0xc4, 0xf1, 0x07, 0x9c, 0xcf, 0x8e, 0xe7, - 0xd9, 0xc9, 0xa8, 0xf8, 0x9e, 0x1b, 0x96, 0x48, 0xf6, 0xa9, 0x55, 0x5d, - 0x6d, 0xff, 0xff, 0xed, 0x49, 0xc8, 0x82, 0x8e, 0x33, 0x09, 0x78, 0x68, - 0x44, 0x2c, 0xd9, 0xbf, 0xd4, 0x22, 0x03, 0xad, 0x38, 0x01, 0x7b, 0xeb, - 0x1b, 0x8b, 0x6c, 0x94, 0xda, 0x81, 0x6e, 0xd8, 0x6a, 0x26, 0x02, 0x28, - 0xa3, 0x2f, 0xa8, 0x0f, 0xef, 0x0d, 0xbc, 0xb9, 0xa2, 0x57, 0xb2, 0x72, - 0x28, 0x81, 0x9b, 0x5d, 0x54, 0x86, 0x7b, 0xf9, 0xed, 0x13, 0xe1, 0x8c, - 0xa4, 0x32, 0x35, 0xe4, 0x8e, 0x01, 0xe1, 0xdd, 0x71, 0xc5, 0xfe, 0x50, - 0x53, 0xdf, 0xef, 0x6b, 0x69, 0x81, 0x35, 0x5a, 0x65, 0x16, 0x87, 0xce, - 0x42, 0x86, 0x32, 0xd4, 0x48, 0x97, 0x3f, 0x10, 0x39, 0xa3, 0xf6, 0x03, - 0xc1, 0xb2, 0xe7, 0xe3, 0xed, 0xae, 0x92, 0x06, 0xca, 0xd0, 0xd0, 0x96, - 0x51, 0xd2, 0x4b, 0x9f, 0xef, 0x5a, 0xdc, 0x66, 0x2b, 0x56, 0xa3, 0x5f, - 0xe3, 0x4b, 0x67, 0x39, 0x09, 0x6f, 0x27, 0x68, 0xd0, 0x75, 0x66, 0xf3, - 0x5c, 0x7c, 0x99, 0x97, 0xbe, 0x95, 0xb7, 0x22, 0xde, 0x54, 0x77, 0x8e, - 0x97, 0x05, 0x21, 0xa4, 0x00, 0x9a, 0x1d, 0xcc, 0xf5, 0x5e, 0xc6, 0xcf, - 0x48, 0x84, 0xab, 0x80, 0xe4, 0x3d, 0x25, 0xc0, 0x88, 0xc7, 0x62, 0xce, - 0x40, 0x32, 0x45, 0xc4, 0x89, 0x44, 0x64, 0xeb, 0x20, 0xe7, 0xba, 0x5a, - 0x97, 0xe7, 0xb1, 0x1a, 0xa6, 0xeb, 0xe2, 0x4f, 0x30, 0x03, 0x60, 0xc2, - 0x84, 0xcc, 0xf0, 0x0a, 0xa8, 0xb0, 0x97, 0x22, 0x48, 0x78, 0x40, 0x46, - 0x9f, 0xc4, 0x83, 0xfe, 0x62, 0x7b, 0xfe, 0xbb, 0xfb, 0x3d, 0x36, 0x2a, - 0xf5, 0xde, 0xb3, 0xbd, 0xf9, 0x4f, 0xcb, 0x1e, 0xbf, 0xcd, 0xe0, 0xef, - 0x3f, 0x34, 0x9b, 0xf3, 0x96, 0xd1, 0x30, 0x84, 0x69, 0x8d, 0x00, 0xf3, - 0x77, 0x1e, 0x06, 0x66, 0x09, 0x3d, 0xd2, 0xeb, 0x76, 0x2f, 0x96, 0xba, - 0x56, 0x73, 0x18, 0x6b, 0x5b, 0x89, 0xef, 0x1e, 0x9f, 0x4e, 0x5c, 0x62, - 0x73, 0xa5, 0x71, 0x7f, 0xa6, 0xb6, 0x27, 0x05, 0x89, 0xa6, 0x34, 0x6f, - 0xb8, 0x6a, 0x5c, 0xb3, 0x72, 0xe7, 0xc1, 0x2a, 0x9e, 0xc1, 0x3f, 0xbf, - 0x7f, 0x71, 0x7f, 0x6f, 0x3b, 0xfd, 0xf7, 0xbf, 0xb1, 0xfd, 0xaa, 0xdf, - 0x4b, 0x7f, 0x73, 0x6d, 0x7a, 0x2e, 0x2f, 0x95, 0xb6, 0xe6, 0xe5, 0xbc, - 0x18, 0x58, 0xcc, 0x4c, 0x3b, 0x49, 0x10, 0x88, 0x3e, 0x20, 0xe6, 0xfe, - 0x33, 0x5c, 0xc2, 0xc7, 0x6e, 0xbe, 0x7a, 0xbb, 0xaa, 0xd6, 0xd7, 0x13, - 0x81, 0xfb, 0xfd, 0xfe, 0x76, 0xfa, 0x26, 0xb9, 0x01, 0x87, 0x3d, 0x8f, - 0x5d, 0xe2, 0xa1, 0xc6, 0xa9, 0x2a, 0x26, 0xf7, 0x8f, 0x04, 0x23, 0x0c, - 0xd5, 0x49, 0x36, 0x72, 0x25, 0x74, 0x12, 0x66, 0xee, 0x7b, 0xe6, 0x2f, - 0xbf, 0x1f, 0xdf, 0xcc, 0xd2, 0x7d, 0xfd, 0xd5, 0x0b, 0x2d, 0xf7, 0xe3, - 0x37, 0x5b, 0xf7, 0xe3, 0xf7, 0xe5, 0x09, 0xfe, 0x7b, 0xca, 0xc7, 0x68, - 0xa7, 0xcb, 0x9d, 0xec, 0x38, 0xe4, 0x5e, 0xec, 0x02, 0x87, 0xd4, 0xc3, - 0xd9, 0x51, 0x5f, 0x3b, 0xef, 0xed, 0x78, 0x14, 0xe9, 0xde, 0xb7, 0xff, - 0x4f, 0x6d, 0x5d, 0x1c, 0x36, 0xed, 0xe5, 0x57, 0xe5, 0xd8, 0x39, 0x87, - 0x8b, 0x8e, 0xc7, 0x57, 0x97, 0xdd, 0x8a, 0x76, 0x40, 0xba, 0x23, 0xee, - 0x4d, 0x7c, 0x65, 0x72, 0xc8, 0x9d, 0x2f, 0xee, 0x36, 0xd4, 0xfb, 0xd6, - 0xff, 0x49, 0x7a, 0x7f, 0x93, 0xfa, 0x7b, 0x3f, 0x5a, 0x79, 0xf9, 0x85, - 0xd6, 0xeb, 0x7b, 0xf5, 0xd1, 0x64, 0x2e, 0x72, 0xf0, 0x98, 0x36, 0x03, - 0xed, 0xfe, 0xc0, 0x4e, 0x06, 0xec, 0x09, 0x8b, 0x83, 0x8d, 0x7f, 0x7b, - 0xa6, 0x75, 0xd7, 0x6e, 0xf3, 0xa8, 0xdb, 0xd2, 0xb6, 0x5b, 0xf8, 0xc5, - 0xe3, 0x86, 0xd1, 0x5a, 0xf9, 0xe7, 0x4e, 0x7a, 0x69, 0xb1, 0x65, 0xc3, - 0xc9, 0xb0, 0xfb, 0xbd, 0xea, 0xb7, 0x05, 0xd2, 0x73, 0x9a, 0x39, 0xdc, - 0xde, 0x2a, 0xef, 0xdf, 0x8c, 0xc3, 0xcd, 0xdf, 0x85, 0xf4, 0x89, 0xae, - 0xbc, 0xeb, 0xbf, 0xe7, 0xad, 0xe6, 0x9c, 0x6a, 0x60, 0xef, 0x5a, 0xff, - 0x4e, 0x95, 0xa6, 0x96, 0x2f, 0x3f, 0x97, 0x2c, 0x4d, 0x96, 0xd6, 0xe7, - 0xf4, 0x11, 0xe9, 0x5d, 0x5e, 0x28, 0x9c, 0x75, 0x55, 0xcc, 0xef, 0x65, - 0x6a, 0x2b, 0x29, 0xb7, 0xff, 0x43, 0x9d, 0xcb, 0x91, 0x60, 0x58, 0x50, - 0x79, 0xef, 0xb4, 0xd8, 0x7a, 0x1d, 0x94, 0x2a, 0xe4, 0x54, 0x74, 0x4c, - 0xe5, 0x8c, 0xeb, 0xfb, 0x13, 0xfd, 0x4a, 0xc3, 0xee, 0x3f, 0x71, 0x33, - 0xf9, 0xba, 0xa5, 0x17, 0xde, 0xcf, 0x45, 0x28, 0x75, 0xfe, 0xb8, 0x35, - 0xa5, 0x79, 0x9b, 0x54, 0x37, 0xc8, 0xa7, 0x8b, 0x0d, 0x56, 0x92, 0x3f, - 0xd8, 0xc8, 0x68, 0xf4, 0xe2, 0x1c, 0xbc, 0x4a, 0x5a, 0x9d, 0xea, 0x85, - 0x57, 0xa1, 0x45, 0x58, 0xb9, 0xc8, 0x23, 0x7a, 0xc5, 0xfe, 0x2f, 0xbd, - 0x9d, 0xe9, 0xbf, 0x19, 0x2a, 0x14, 0x0d, 0x78, 0xa4, 0x01, 0x03, 0x0e, - 0x97, 0x91, 0x0c, 0x5c, 0x6b, 0x9d, 0x29, 0x50, 0x5e, 0xfc, 0x18, 0x51, - 0x91, 0x9b, 0x03, 0x41, 0x1c, 0xb9, 0xe4, 0x42, 0x59, 0xcf, 0x3b, 0xd6, - 0xe9, 0xe3, 0x19, 0xc0, 0x82, 0x28, 0x60, 0x3f, 0x1e, 0x32, 0xe0, 0x05, - 0xca, 0x07, 0x5c, 0x8e, 0x37, 0xb0, 0xcb, 0x0d, 0xf1, 0x21, 0x91, 0x96, - 0x41, 0xb4, 0x67, 0x56, 0xab, 0x7d, 0x75, 0x02, 0x86, 0x83, 0xbf, 0x39, - 0x7b, 0x9d, 0x0c, 0x7c, 0xb0, 0x7d, 0x38, 0x4f, 0x9c, 0xf2, 0xe6, 0x52, - 0xdd, 0x2f, 0xc4, 0x3d, 0x75, 0x5e, 0xbb, 0x53, 0x7a, 0x4f, 0xa6, 0xf5, - 0x3a, 0xdb, 0xa1, 0xc0, 0x02, 0x62, 0xf2, 0xe6, 0x90, 0xca, 0x92, 0x3e, - 0x9c, 0x9f, 0x72, 0x0b, 0x7f, 0x63, 0xa7, 0x5f, 0x07, 0x2a, 0x62, 0xa9, - 0xe6, 0x22, 0x25, 0xb7, 0x96, 0xad, 0x51, 0x0b, 0xc6, 0x47, 0x9d, 0x76, - 0xbc, 0x1f, 0x83, 0x2c, 0x65, 0xd9, 0x15, 0xfb, 0x7c, 0x85, 0x6a, 0xd6, - 0xa6, 0xc8, 0x04, 0x5c, 0x25, 0xa1, 0x96, 0x91, 0xfa, 0x31, 0xaf, 0xd2, - 0x0d, 0xdd, 0x7f, 0x8a, 0x09, 0x4f, 0xd9, 0x38, 0x3f, 0xb6, 0x1e, 0x52, - 0xf3, 0x8a, 0x27, 0x25, 0xe2, 0x93, 0x08, 0x7c, 0x69, 0xa4, 0x39, 0xd6, - 0x59, 0x07, 0x0c, 0xd2, 0x91, 0x9c, 0xf3, 0x04, 0xf7, 0x7b, 0x99, 0x72, - 0x2c, 0x73, 0x7b, 0x6d, 0xe7, 0x7b, 0x1a, 0x8b, 0x71, 0x8e, 0x8c, 0xf2, - 0xea, 0x3a, 0x52, 0xee, 0x44, 0x91, 0xf8, 0x26, 0xfc, 0xc2, 0xde, 0x9b, - 0xd9, 0x6c, 0x3c, 0xc4, 0xaf, 0x75, 0x64, 0x3c, 0xa4, 0x27, 0xdc, 0xf8, - 0x5f, 0x91, 0x28, 0x87, 0xaa, 0xce, 0xea, 0x6e, 0x5c, 0xa2, 0x00, 0x04, - 0xcb, 0x4c, 0xe5, 0x99, 0xca, 0x00, 0x27, 0x34, 0x72, 0x5e, 0x0b, 0x4e, - 0x03, 0xbd, 0x7d, 0x10, 0x11, 0x90, 0xca, 0x8c, 0xbf, 0x04, 0xbe, 0xb2, - 0x5b, 0x65, 0xf1, 0x22, 0x83, 0xd1, 0x84, 0x3d, 0x16, 0x26, 0x30, 0xf1, - 0x03, 0xe6, 0x64, 0xa8, 0xc8, 0x20, 0x3c, 0x3b, 0x01, 0x72, 0xbc, 0xea, - 0xaa, 0x94, 0xf2, 0x80, 0x1d, 0x93, 0xc3, 0x3c, 0xbf, 0x4f, 0xce, 0x48, - 0x8f, 0xb5, 0x38, 0x83, 0x5c, 0x4d, 0x7f, 0xd6, 0x68, 0x70, 0x0c, 0x90, - 0x8c, 0x5d, 0x2b, 0xc2, 0x60, 0x51, 0xad, 0xfb, 0xfb, 0x22, 0x97, 0x02, - 0xe6, 0xda, 0x4c, 0x7c, 0x46, 0xfe, 0x36, 0xec, 0x8b, 0x9a, 0x09, 0x48, - 0x7d, 0x13, 0x2e, 0xd7, 0x1b, 0x3f, 0xcb, 0xe9, 0xa5, 0x90, 0xc4, 0x30, - 0x0c, 0x92, 0x23, 0x22, 0x89, 0x91, 0x62, 0x73, 0xb0, 0x8f, 0x55, 0xd2, - 0x9e, 0x1c, 0x3a, 0x22, 0x57, 0x87, 0xd9, 0x6e, 0x47, 0x93, 0xdd, 0xfd, - 0x53, 0xa0, 0x5e, 0x40, 0x92, 0x04, 0x54, 0x57, 0x3a, 0x69, 0x45, 0x7f, - 0xe7, 0x8d, 0x03, 0x8b, 0xff, 0xe2, 0x76, 0x13, 0xc1, 0x22, 0x2d, 0xf3, - 0xa9, 0x8b, 0xb9, 0x63, 0x33, 0x56, 0xa3, 0x9f, 0x02, 0xf5, 0x3d, 0x6c, - 0x89, 0xe3, 0xc9, 0x88, 0xc3, 0xa3, 0xf0, 0x5e, 0x05, 0xcd, 0x22, 0xeb, - 0xe1, 0x0c, 0x36, 0x2c, 0xb6, 0x7b, 0x40, 0x30, 0xf3, 0xab, 0x2f, 0xe0, - 0x4f, 0x03, 0x97, 0x2b, 0xd9, 0xfe, 0xfe, 0x23, 0xa7, 0x9f, 0x05, 0xdc, - 0x66, 0x82, 0xd2, 0x54, 0x6d, 0x87, 0xfa, 0x0c, 0x8e, 0x48, 0x25, 0xde, - 0xb0, 0x13, 0x77, 0x71, 0x55, 0x1e, 0x89, 0x63, 0x8d, 0xdb, 0x8a, 0x1c, - 0x31, 0x0d, 0xa2, 0xfa, 0xa0, 0x5c, 0x50, 0x34, 0x11, 0x22, 0x61, 0x1e, - 0xe0, 0x55, 0xfe, 0xd7, 0x5a, 0x5c, 0x91, 0x2b, 0xaf, 0x65, 0x91, 0x8c, - 0xe7, 0x1c, 0x34, 0x88, 0x22, 0x63, 0x2c, 0x56, 0x70, 0x4e, 0x15, 0x02, - 0x9b, 0x52, 0xff, 0x22, 0x14, 0xff, 0xb3, 0x05, 0x6e, 0xb7, 0xb6, 0x41, - 0x11, 0x21, 0x44, 0xe4, 0xf6, 0x90, 0xf0, 0x4d, 0x79, 0xf3, 0x34, 0x32, - 0xf2, 0x33, 0xb4, 0x94, 0x69, 0x49, 0xeb, 0xd3, 0x43, 0x7b, 0x07, 0x60, - 0xd1, 0xdc, 0x81, 0x43, 0x1a, 0x68, 0x1c, 0x9f, 0x64, 0xe3, 0x1c, 0x8d, - 0xaf, 0x40, 0x52, 0xd5, 0x28, 0x26, 0x69, 0x9c, 0x9a, 0x26, 0x80, 0x4e, - 0xc8, 0x12, 0x24, 0xeb, 0x56, 0x54, 0xe9, 0xb5, 0x2a, 0x0c, 0x44, 0xd2, - 0xd2, 0xe7, 0x56, 0xab, 0x97, 0x16, 0xac, 0x18, 0x41, 0x28, 0x4e, 0x11, - 0x46, 0x03, 0x2c, 0x79, 0x8c, 0x3f, 0xcf, 0x77, 0x96, 0x84, 0xc9, 0x03, - 0x26, 0xee, 0x7d, 0x3e, 0x15, 0xb6, 0x6b, 0x1d, 0x90, 0xdd, 0x87, 0x29, - 0x88, 0x06, 0x69, 0x19, 0x8c, 0x27, 0xef, 0x9d, 0x1a, 0x9f, 0xca, 0x12, - 0xff, 0x70, 0xee, 0x16, 0x10, 0x71, 0x95, 0x2a, 0x19, 0x79, 0x54, 0x3e, - 0x8b, 0xa7, 0x49, 0xc4, 0xe8, 0x4f, 0x2a, 0xac, 0xe0, 0x04, 0x66, 0x28, - 0xcf, 0x2a, 0x87, 0x64, 0x3e, 0x5d, 0x04, 0x3e, 0xc4, 0x89, 0x06, 0xc9, - 0x64, 0x98, 0xa0, 0xe7, 0x07, 0x6f, 0x05, 0xb4, 0xfb, 0x66, 0x9e, 0x33, - 0xb3, 0xbc, 0xe3, 0x10, 0x86, 0xa4, 0x10, 0xc9, 0xfd, 0x89, 0x97, 0x13, - 0x9e, 0x74, 0x49, 0x61, 0x29, 0xca, 0x9b, 0x98, 0x1a, 0x10, 0x84, 0x89, - 0xac, 0x02, 0xa3, 0xbf, 0xf2, 0x5f, 0xff, 0x8a, 0xfc, 0xf9, 0xab, 0xd6, - 0x90, 0xe5, 0xe0, 0x58, 0x2f, 0xd1, 0xde, 0x44, 0xc0, 0x5a, 0x67, 0x52, - 0x63, 0x28, 0x0a, 0x04, 0x63, 0xcf, 0xc1, 0x21, 0x38, 0xe9, 0x8b, 0xaf, - 0x2e, 0x4e, 0x40, 0x81, 0xa0, 0x9a, 0x1b, 0x69, 0x3f, 0x67, 0x07, 0x28, - 0x8c, 0x24, 0x24, 0x68, 0x63, 0x12, 0xee, 0xce, 0xdf, 0x8b, 0xeb, 0x4d, - 0x45, 0x07, 0xe7, 0xea, 0x49, 0xbb, 0xd1, 0x36, 0x6e, 0xdd, 0xd7, 0xe0, - 0xaf, 0x12, 0xf4, 0x08, 0x48, 0x9b, 0xd4, 0x26, 0x19, 0x6a, 0x5e, 0x7b, - 0xce, 0xd7, 0xde, 0xdd, 0x6a, 0x1f, 0xc1, 0x9b, 0xbd, 0x13, 0xb6, 0x1d, - 0x84, 0x15, 0x93, 0x3c, 0xf4, 0xf0, 0x06, 0xfa, 0xcd, 0xce, 0x89, 0x78, - 0x76, 0xe7, 0x23, 0x72, 0xe7, 0xf1, 0x3e, 0x27, 0x86, 0x54, 0x75, 0xec, - 0xef, 0x9e, 0x7b, 0xf2, 0x75, 0x57, 0x46, 0xc4, 0x2b, 0xf0, 0x55, 0x6c, - 0x95, 0x71, 0xc4, 0xf7, 0xd6, 0x32, 0xee, 0xd9, 0xa5, 0x8c, 0x6d, 0xce, - 0x40, 0x25, 0xc9, 0x01, 0x80, 0x7d, 0x75, 0xbf, 0x8a, 0xeb, 0xbc, 0x48, - 0xe7, 0xa7, 0x2e, 0x58, 0x06, 0x2c, 0xd5, 0xee, 0x20, 0x90, 0x22, 0xa8, - 0x4a, 0x41, 0x1e, 0xe7, 0x62, 0x9b, 0x13, 0x28, 0x02, 0x4d, 0xd6, 0xd0, - 0xb1, 0x80, 0x96, 0x39, 0xa3, 0x4c, 0xa4, 0x7b, 0x83, 0xf7, 0x78, 0x9f, - 0xbe, 0x0a, 0xf9, 0x98, 0xcb, 0x17, 0x7d, 0x46, 0xe4, 0x10, 0xbd, 0xa6, - 0x89, 0xca, 0x00, 0x98, 0xd0, 0x2f, 0xaa, 0x84, 0x09, 0xc2, 0xac, 0xc5, - 0xd6, 0xe9, 0x91, 0x1b, 0x5e, 0x49, 0x52, 0x73, 0x15, 0xf5, 0x6b, 0xf0, - 0xdb, 0xd4, 0x32, 0x8d, 0x34, 0xb8, 0x5c, 0x25, 0xe4, 0x21, 0x7a, 0x7c, - 0x44, 0x2e, 0x54, 0xe3, 0x5d, 0xf2, 0x59, 0xfd, 0x63, 0x6b, 0xb6, 0x2f, - 0x3b, 0xdb, 0xb3, 0x39, 0x94, 0xe5, 0x26, 0x26, 0x79, 0x5a, 0x0c, 0x26, - 0x12, 0xfc, 0x41, 0x57, 0x89, 0x63, 0x11, 0x0b, 0xc6, 0x46, 0x57, 0xa3, - 0xb2, 0xa5, 0x2a, 0x5d, 0xf6, 0xfd, 0x7c, 0x73, 0xe2, 0xaf, 0x6f, 0x5b, - 0xa4, 0xb3, 0x05, 0x1c, 0x7d, 0xc1, 0x89, 0xfa, 0xcd, 0x03, 0x29, 0xa0, - 0x25, 0x18, 0xcd, 0xe1, 0xf1, 0xee, 0x5a, 0x21, 0xbf, 0x4a, 0xb8, 0x4c, - 0x9c, 0x87, 0x21, 0x09, 0x19, 0xe4, 0xa5, 0xe2, 0x03, 0x50, 0x31, 0x34, - 0x7c, 0x49, 0xbf, 0xe6, 0x56, 0x6c, 0xb6, 0xdf, 0x4e, 0xa6, 0x34, 0xd9, - 0xd8, 0x90, 0x50, 0x26, 0x54, 0x11, 0x14, 0x08, 0x28, 0x1f, 0x05, 0x1b, - 0xa6, 0x5d, 0x39, 0x42, 0x77, 0xb6, 0xc7, 0xc4, 0xfa, 0xb1, 0x43, 0x0a, - 0x93, 0x86, 0xf9, 0xe0, 0xfe, 0xa9, 0x65, 0x99, 0xfe, 0xeb, 0x93, 0xe3, - 0x61, 0xb2, 0x2b, 0x6c, 0xde, 0xd6, 0xc6, 0x02, 0xc5, 0xc1, 0x91, 0x53, - 0x5e, 0xf4, 0xcb, 0xf9, 0x70, 0x03, 0xb0, 0xde, 0x85, 0x18, 0xc6, 0x4b, - 0xd0, 0xe2, 0x7a, 0x6a, 0x28, 0xc3, 0xec, 0x45, 0xc4, 0xf1, 0x91, 0x4a, - 0x44, 0x4c, 0x78, 0xe3, 0xa4, 0x47, 0xd8, 0x6a, 0x9a, 0xc8, 0x21, 0x67, - 0x10, 0x11, 0x35, 0x36, 0x42, 0xa2, 0xde, 0x4d, 0xb0, 0xc3, 0xb2, 0x5d, - 0x44, 0x27, 0x18, 0xbc, 0xd5, 0xbf, 0xd4, 0x9d, 0xe4, 0xb5, 0x50, 0x88, - 0x3a, 0xf8, 0x30, 0x8f, 0x64, 0xed, 0xbb, 0x28, 0x9e, 0x78, 0x9e, 0x41, - 0x6d, 0x98, 0x2f, 0x6c, 0x1c, 0xe9, 0xe0, 0x51, 0x93, 0x2a, 0xd2, 0xa7, - 0xdc, 0xcc, 0x91, 0x70, 0x40, 0xc9, 0x99, 0x82, 0x10, 0xec, 0xa9, 0xf9, - 0xde, 0x9d, 0x5b, 0xd6, 0x9d, 0xb7, 0xb5, 0xb3, 0xe8, 0x33, 0x31, 0x0e, - 0x49, 0x79, 0x25, 0x65, 0x51, 0x99, 0x28, 0x01, 0x3f, 0xad, 0x50, 0x9e, - 0x5f, 0x5c, 0x0c, 0x73, 0x42, 0xac, 0x53, 0xb7, 0x71, 0x87, 0x5d, 0x3b, - 0x53, 0x03, 0x30, 0x06, 0x7c, 0x66, 0xfa, 0x34, 0xfe, 0xa9, 0x41, 0xbf, - 0xba, 0x85, 0xf6, 0xa8, 0xe4, 0xbb, 0x95, 0xf2, 0xce, 0x59, 0x01, 0x32, - 0x50, 0x92, 0x13, 0xf8, 0xa9, 0x42, 0xad, 0x36, 0x27, 0x84, 0xd8, 0x5c, - 0xe8, 0x84, 0xa4, 0x0a, 0x43, 0xc4, 0x7d, 0xdb, 0x8a, 0x8e, 0xdb, 0x4f, - 0x34, 0xb8, 0x29, 0x1f, 0x4e, 0xa0, 0xc8, 0xa8, 0x88, 0xbf, 0xda, 0x86, - 0xcf, 0xc5, 0xac, 0xed, 0x0e, 0x37, 0x26, 0xa4, 0xba, 0x6e, 0x40, 0xc3, - 0x3a, 0x1f, 0x12, 0x44, 0xa4, 0xb0, 0x27, 0x28, 0x34, 0xe7, 0x7b, 0x2f, - 0x87, 0xe7, 0x86, 0xfe, 0xce, 0x04, 0x38, 0xd3, 0x18, 0x99, 0x30, 0x29, - 0xd6, 0x42, 0xce, 0xba, 0x73, 0xd8, 0x35, 0x6f, 0x43, 0x6a, 0x82, 0x5b, - 0x51, 0x12, 0x0e, 0xd4, 0x61, 0x48, 0xb9, 0x4a, 0xfb, 0x34, 0x95, 0x71, - 0x4c, 0xb8, 0x9a, 0xa7, 0x6e, 0xc6, 0x81, 0x38, 0xa4, 0x57, 0x83, 0xca, - 0x64, 0x19, 0xb4, 0x90, 0x91, 0x32, 0xac, 0x9b, 0x79, 0xce, 0x42, 0x01, - 0xf0, 0x66, 0x7f, 0x38, 0xa5, 0xad, 0x44, 0x43, 0x1f, 0xca, 0x0f, 0x59, - 0xbe, 0x8f, 0x9d, 0xff, 0x16, 0xc9, 0xb6, 0xb7, 0x37, 0xa4, 0x46, 0x54, - 0x62, 0xac, 0x03, 0x2a, 0xac, 0x07, 0x39, 0xf1, 0xc9, 0xcd, 0x9b, 0xd7, - 0x6b, 0x47, 0x13, 0x25, 0xb0, 0x68, 0x24, 0x1e, 0xb0, 0xb8, 0xec, 0x19, - 0xa7, 0x2e, 0xaf, 0x0e, 0xb2, 0x1b, 0xd1, 0x63, 0x56, 0x83, 0xce, 0x19, - 0xe9, 0xcb, 0x14, 0x0b, 0x19, 0x4f, 0xc3, 0x61, 0x55, 0x8d, 0xfe, 0x94, - 0x86, 0x4a, 0x0d, 0x78, 0xbb, 0x1b, 0x8a, 0x8d, 0x3d, 0xe4, 0xbe, 0x0e, - 0xf4, 0xa0, 0x97, 0x91, 0x02, 0xfe, 0x7d, 0xf4, 0xda, 0x44, 0x07, 0x79, - 0xc8, 0xa2, 0x4d, 0x24, 0x50, 0x39, 0x3f, 0x9c, 0x0f, 0x33, 0xba, 0x96, - 0x0b, 0xf9, 0x2b, 0xb7, 0x87, 0xc5, 0x74, 0x69, 0xba, 0xb6, 0xe2, 0x67, - 0x2d, 0xe0, 0xcc, 0x00, 0x0d, 0x5b, 0x64, 0x77, 0xb8, 0x4d, 0x1a, 0x23, - 0x2f, 0xd3, 0xf6, 0x47, 0x76, 0xff, 0x6d, 0x74, 0xde, 0x84, 0x36, 0xc3, - 0x7b, 0x62, 0x8c, 0x2f, 0xc4, 0x54, 0x15, 0x16, 0xc7, 0xd8, 0x10, 0xd7, - 0xa6, 0x0e, 0xd9, 0xa3, 0x1a, 0x41, 0x19, 0x76, 0x44, 0xa5, 0xda, 0x9e, - 0x6b, 0x0a, 0xaf, 0xea, 0x27, 0x29, 0x3f, 0xaf, 0x01, 0xb7, 0xb0, 0x31, - 0xff, 0x9e, 0x15, 0x21, 0x3d, 0xec, 0x3e, 0x24, 0x8a, 0x38, 0x63, 0x94, - 0x3c, 0x08, 0x39, 0xd9, 0x44, 0x99, 0x28, 0x64, 0x6b, 0x09, 0xcd, 0xe8, - 0xf8, 0x99, 0xb1, 0x33, 0x6d, 0xd6, 0xa4, 0xa5, 0xd2, 0x3c, 0x09, 0x39, - 0x38, 0x8b, 0x23, 0x14, 0x64, 0xb6, 0x01, 0xa2, 0x7e, 0x2c, 0xbe, 0xd5, - 0x24, 0xe5, 0xd8, 0x19, 0xce, 0xc8, 0x77, 0x8c, 0xec, 0x6c, 0x8a, 0x38, - 0x2d, 0x8b, 0xa8, 0x42, 0x2d, 0xb1, 0x34, 0x28, 0x9c, 0x85, 0x19, 0x78, - 0x40, 0x0a, 0xee, 0xff, 0xfa, 0xa3, 0xd9, 0xa2, 0x26, 0x55, 0xdb, 0x8f, - 0xa0, 0xc5, 0xd7, 0xa1, 0x07, 0x67, 0x87, 0x0f, 0x4e, 0x31, 0x09, 0x74, - 0x2a, 0xd2, 0xf3, 0xfb, 0xf3, 0x8c, 0x51, 0x65, 0x27, 0x74, 0x67, 0x2c, - 0x64, 0x7e, 0x6e, 0x32, 0xce, 0x12, 0x0b, 0x1b, 0xb6, 0xa2, 0xda, 0xb4, - 0xc2, 0xf4, 0xaa, 0xfe, 0x3a, 0x47, 0x52, 0x9c, 0x91, 0x43, 0x1f, 0xe7, - 0xee, 0x71, 0x8e, 0xa2, 0x3e, 0xbd, 0xf3, 0x2e, 0xbd, 0xbc, 0xae, 0x76, - 0x7f, 0x15, 0x3d, 0x41, 0xc1, 0xf3, 0xed, 0xc2, 0xdb, 0x3a, 0xcd, 0x2d, - 0xf4, 0xd4, 0x5e, 0x10, 0x02, 0x84, 0xd1, 0x23, 0x5d, 0xac, 0x86, 0x4c, - 0x7d, 0x17, 0xd3, 0xbc, 0x7f, 0xec, 0x42, 0xa9, 0x74, 0x01, 0x01, 0xa3, - 0x8e, 0x20, 0x8c, 0x26, 0x66, 0x4e, 0x03, 0xf5, 0x07, 0xac, 0x2b, 0xaf, - 0x5a, 0xd2, 0xbf, 0xef, 0x74, 0xf1, 0x5c, 0xb1, 0xa7, 0x48, 0x1a, 0x48, - 0x0c, 0x69, 0xc6, 0x32, 0xc0, 0x70, 0x80, 0x77, 0x9a, 0x4c, 0x6f, 0xd7, - 0x22, 0xd8, 0xcd, 0x42, 0x3f, 0xae, 0xf9, 0x01, 0x08, 0x06, 0x9c, 0xca, - 0xc8, 0x3d, 0x63, 0x2b, 0x54, 0x7e, 0x76, 0xc1, 0x2c, 0xe0, 0xf5, 0x50, - 0x54, 0x51, 0x1b, 0xcb, 0x77, 0x36, 0xed, 0x30, 0x2e, 0x63, 0xad, 0x34, - 0x38, 0x9a, 0xd6, 0x9b, 0x0c, 0xcd, 0x2c, 0x91, 0x7f, 0x19, 0xfc, 0x4d, - 0x58, 0xac, 0x47, 0xdd, 0x17, 0xf3, 0xb8, 0xa0, 0x10, 0x3f, 0x16, 0xad, - 0x9b, 0x06, 0xc9, 0x97, 0x7b, 0x3f, 0x40, 0xb0, 0x0d, 0x1d, 0x85, 0xcb, - 0x12, 0x79, 0x61, 0x8e, 0x31, 0x20, 0x51, 0x9e, 0x59, 0x97, 0x87, 0x6d, - 0xfa, 0x4a, 0x43, 0x70, 0x8f, 0x75, 0x9f, 0x31, 0x75, 0xd9, 0xa6, 0x84, - 0x9b, 0x40, 0xaf, 0x62, 0xa1, 0x7b, 0x4a, 0x6e, 0x72, 0xdc, 0xd0, 0xa0, - 0x04, 0x35, 0x94, 0xd5, 0xa7, 0x3e, 0xc6, 0xd3, 0x73, 0x7b, 0xfd, 0x5b, - 0x64, 0x1d, 0x94, 0x48, 0x69, 0x8a, 0x89, 0xd8, 0x50, 0x22, 0x30, 0x94, - 0xfb, 0x5f, 0xaa, 0x53, 0x0b, 0xb9, 0x53, 0xe4, 0xbe, 0x0a, 0x27, 0x97, - 0x77, 0x53, 0x0d, 0xc5, 0xde, 0x64, 0x7f, 0x73, 0x77, 0x23, 0x5a, 0x47, - 0xb0, 0xda, 0x7c, 0x3e, 0x00, 0xd4, 0x4f, 0x80, 0x3c, 0xd8, 0x7f, 0x4d, - 0x76, 0x56, 0x8f, 0x55, 0xdd, 0x6d, 0x63, 0xde, 0xeb, 0xa3, 0x8e, 0x44, - 0xcf, 0xcc, 0x9e, 0xe7, 0x42, 0x94, 0x7b, 0xb9, 0x1d, 0x7d, 0x15, 0xb3, - 0x0a, 0x9e, 0xe8, 0xd5, 0x8f, 0x2e, 0xe4, 0xa6, 0x79, 0x55, 0x82, 0xff, - 0xfe, 0x79, 0x3a, 0x3d, 0xa7, 0x02, 0x04, 0x8d, 0x65, 0x6e, 0xab, 0x9c, - 0x62, 0xd8, 0x6f, 0x7e, 0xab, 0x21, 0x70, 0x12, 0x88, 0x76, 0x68, 0x5b, - 0xe2, 0x4b, 0xc6, 0x69, 0x0d, 0x5f, 0xf8, 0x21, 0x92, 0xe5, 0x49, 0xef, - 0xe6, 0x79, 0x9d, 0xcf, 0x6d, 0x5a, 0x7d, 0xbf, 0x08, 0x61, 0x62, 0xbd, - 0x87, 0x75, 0x8e, 0x36, 0x1c, 0x0a, 0x13, 0x94, 0x9c, 0x03, 0x01, 0x2e, - 0x47, 0xd8, 0x93, 0x13, 0xab, 0xab, 0x8d, 0xfe, 0x4d, 0xb3, 0x4e, 0x0a, - 0x18, 0x67, 0x84, 0x38, 0x21, 0x11, 0xb0, 0x58, 0x7c, 0x78, 0x23, 0xaf, - 0xbc, 0x58, 0xf7, 0x3b, 0xeb, 0x69, 0x59, 0xc9, 0x1a, 0x03, 0xe6, 0x00, - 0x43, 0xc0, 0x15, 0x56, 0x9b, 0x19, 0xb3, 0xbc, 0xdb, 0xeb, 0xec, 0xca, - 0xb8, 0x6a, 0x18, 0x7c, 0x59, 0xba, 0xa4, 0xc6, 0x84, 0x91, 0x12, 0x4b, - 0x41, 0xf2, 0xbc, 0x5a, 0x52, 0x29, 0x99, 0x0c, 0x5e, 0xb0, 0x9f, 0x0c, - 0xd4, 0xc5, 0x6e, 0xed, 0xf9, 0xb0, 0xc1, 0xc1, 0x7d, 0xae, 0x67, 0x4c, - 0xc0, 0x55, 0xf4, 0xed, 0x03, 0xad, 0xc5, 0xb4, 0x83, 0xfe, 0xec, 0x16, - 0x70, 0x08, 0xdd, 0x5c, 0x45, 0xb4, 0xb7, 0x99, 0x9b, 0xec, 0xa0, 0x06, - 0x42, 0x44, 0xd0, 0x9f, 0xda, 0x05, 0xb7, 0xef, 0x7c, 0xd5, 0xa3, 0x0f, - 0x4c, 0x36, 0xf7, 0x92, 0x98, 0xc4, 0x64, 0x89, 0xa7, 0x2a, 0x39, 0x41, - 0xa1, 0x28, 0xcb, 0xc4, 0xc1, 0x77, 0xda, 0x49, 0xf7, 0xfa, 0xb3, 0x72, - 0x93, 0xa0, 0xad, 0x09, 0x9b, 0xd9, 0x82, 0x44, 0xf6, 0x84, 0x9c, 0xbf, - 0xad, 0x73, 0xde, 0x15, 0x76, 0xee, 0x9c, 0x4f, 0xce, 0x5f, 0x5d, 0xf4, - 0x90, 0x51, 0xfc, 0xaf, 0xfc, 0x59, 0x2a, 0x70, 0x92, 0x66, 0xeb, 0xd3, - 0x04, 0x29, 0xc8, 0xc2, 0x49, 0x40, 0x9a, 0xac, 0xff, 0x94, 0x31, 0x42, - 0x81, 0x83, 0x17, 0x6f, 0x87, 0xdc, 0x62, 0xe7, 0x74, 0x50, 0xc9, 0xc6, - 0x83, 0xbf, 0x7a, 0xe0, 0xae, 0x11, 0xbd, 0x86, 0x0f, 0x02, 0xdc, 0x2a, - 0x58, 0xee, 0x50, 0x04, 0xcf, 0x28, 0x7d, 0xa0, 0xdf, 0xd8, 0x2b, 0xec, - 0xe3, 0x79, 0xff, 0xd9, 0x2b, 0xc3, 0x23, 0x3a, 0x4a, 0x19, 0x26, 0x69, - 0x7c, 0x5a, 0xcb, 0xf5, 0x66, 0x11, 0xdd, 0x7e, 0x4f, 0x99, 0xc6, 0xf2, - 0x6f, 0xf6, 0xe5, 0x3f, 0x60, 0x46, 0xfe, 0x52, 0x26, 0xab, 0x3a, 0xcc, - 0x48, 0xbf, 0xdf, 0xcc, 0xaf, 0x67, 0xc5, 0x02, 0x99, 0x93, 0x43, 0x0b, - 0x11, 0x31, 0xda, 0x9c, 0xa6, 0x64, 0xb9, 0x4b, 0xed, 0x05, 0x56, 0xf8, - 0x75, 0xdf, 0xbc, 0x7d, 0xfd, 0xee, 0x69, 0x59, 0xfb, 0x68, 0x7e, 0xfd, - 0x94, 0xd3, 0x46, 0x1d, 0xa2, 0x61, 0x59, 0x8c, 0x7b, 0x05, 0x58, 0x07, - 0x8a, 0xfe, 0x37, 0x7b, 0xbc, 0x9c, 0x40, 0x04, 0x4d, 0x08, 0x31, 0xca, - 0x3c, 0xb9, 0x74, 0x67, 0x46, 0xbc, 0xc9, 0x79, 0x78, 0x4e, 0x60, 0xbf, - 0xf8, 0x92, 0x51, 0xa4, 0xda, 0x35, 0xfd, 0xe8, 0x89, 0x4b, 0xe0, 0xc8, - 0x9c, 0xb2, 0xbe, 0xb9, 0x3c, 0x26, 0x4b, 0x6a, 0x8a, 0xfa, 0xa8, 0x5c, - 0xd3, 0x0b, 0x9a, 0x86, 0xd9, 0x5a, 0xa1, 0x2b, 0x13, 0x2d, 0xf1, 0xe9, - 0xde, 0x99, 0x78, 0x0d, 0xc9, 0xae, 0x6d, 0x4e, 0x8e, 0x3c, 0x25, 0x2d, - 0x1f, 0xb1, 0x04, 0x69, 0x86, 0x4b, 0x23, 0xc3, 0x70, 0x8c, 0x5d, 0x08, - 0xc0, 0x3b, 0x8f, 0x88, 0x8f, 0x82, 0x42, 0x20, 0xef, 0xf8, 0xbb, 0x92, - 0x06, 0x8b, 0x19, 0x3e, 0xc6, 0x34, 0xa5, 0x95, 0x90, 0xf0, 0x16, 0xac, - 0xee, 0x4b, 0xed, 0x7c, 0xb6, 0x83, 0x2a, 0x67, 0x14, 0x8d, 0xec, 0x4c, - 0xe5, 0x6e, 0x96, 0x92, 0xa6, 0x05, 0x2a, 0xb1, 0x57, 0xb8, 0x7c, 0x31, - 0xc7, 0x56, 0xf4, 0xf3, 0xc9, 0x06, 0x3f, 0x51, 0x8e, 0x93, 0x45, 0xe6, - 0x22, 0xed, 0x44, 0x71, 0xff, 0x61, 0x38, 0x7f, 0xc4, 0x57, 0xff, 0x3c, - 0x04, 0x1a, 0xa1, 0xc8, 0x80, 0xb0, 0x97, 0x30, 0x2b, 0x17, 0xe5, 0x67, - 0xa2, 0x54, 0x38, 0xdc, 0x5e, 0x48, 0x27, 0xe8, 0x08, 0xd7, 0xfd, 0xef, - 0x99, 0x34, 0xb1, 0x40, 0x06, 0x14, 0x49, 0x43, 0x2b, 0x18, 0xbe, 0x5a, - 0x1d, 0xc1, 0x8e, 0xcf, 0x0a, 0xca, 0xf0, 0x13, 0x5b, 0x8b, 0x3f, 0xe8, - 0x3c, 0xa0, 0x84, 0x46, 0x09, 0x69, 0x14, 0x70, 0x1f, 0x06, 0x61, 0x3d, - 0xd3, 0x25, 0x24, 0x5f, 0x37, 0x0b, 0x36, 0xea, 0xbd, 0xce, 0xd9, 0xb5, - 0x0f, 0x21, 0x84, 0x25, 0xb4, 0x8b, 0x34, 0xe5, 0x41, 0xa7, 0x58, 0x47, - 0xcc, 0x97, 0x91, 0x1e, 0xcc, 0x63, 0x88, 0x8b, 0x84, 0xb9, 0xf7, 0x0c, - 0x59, 0xb4, 0x28, 0x8a, 0xa8, 0xcc, 0xa9, 0xc4, 0x9a, 0xb6, 0x2e, 0xca, - 0x0d, 0x8c, 0x52, 0x08, 0x9b, 0xd7, 0xee, 0x2a, 0x1b, 0x0e, 0xde, 0x81, - 0x38, 0x62, 0x97, 0x43, 0xe3, 0xd2, 0x20, 0x5a, 0x30, 0x92, 0xe9, 0x1f, - 0x14, 0x99, 0x69, 0x8c, 0xa1, 0x13, 0xc8, 0x48, 0x4e, 0xf5, 0x73, 0x3a, - 0xf4, 0xa1, 0xfb, 0xf4, 0x7c, 0xfb, 0x3f, 0x2d, 0xe6, 0x2d, 0x78, 0x10, - 0x03, 0x70, 0x7c, 0xc1, 0x90, 0x96, 0x4f, 0x09, 0x04, 0xfd, 0x03, 0x55, - 0xf7, 0x1a, 0x58, 0x5f, 0x6a, 0x26, 0x25, 0x80, 0xc6, 0x9f, 0xf7, 0x1b, - 0x45, 0x06, 0xdc, 0xcd, 0xf4, 0x65, 0x4b, 0xfb, 0xbe, 0xd7, 0x45, 0x19, - 0x1d, 0x41, 0x90, 0x82, 0x39, 0x14, 0x83, 0x35, 0x9c, 0xf3, 0xd7, 0x9f, - 0x9a, 0x70, 0x43, 0x03, 0x90, 0xde, 0x6d, 0x84, 0xb0, 0xe9, 0x55, 0x68, - 0xfb, 0xcd, 0xfb, 0x3c, 0x9b, 0x44, 0xb0, 0x22, 0x8b, 0x97, 0x79, 0x83, - 0xe9, 0xee, 0x5b, 0x59, 0xab, 0x8a, 0x69, 0x85, 0x37, 0x57, 0x11, 0x8f, - 0x97, 0x21, 0x80, 0xa1, 0x2c, 0x89, 0xc9, 0xed, 0x6c, 0xce, 0x4d, 0xb5, - 0xe2, 0xb7, 0xd2, 0xc4, 0xa2, 0x70, 0xe1, 0xb4, 0x45, 0x78, 0x2f, 0x0e, - 0x63, 0x06, 0x33, 0xc7, 0x9d, 0x1a, 0x52, 0x13, 0xdf, 0xda, 0xdb, 0xe8, - 0x57, 0x49, 0x1d, 0x81, 0xac, 0x71, 0x8c, 0x64, 0x90, 0x29, 0x19, 0xd1, - 0x33, 0xf9, 0xc0, 0xce, 0x13, 0xf2, 0x59, 0x16, 0xf0, 0xea, 0x6a, 0x75, - 0x78, 0x07, 0x75, 0xf0, 0xf9, 0x0a, 0x66, 0x52, 0x48, 0xd0, 0x4e, 0xd0, - 0x6b, 0x89, 0xd6, 0x9b, 0xef, 0x7e, 0xef, 0x23, 0x29, 0x0a, 0x4c, 0x28, - 0xe4, 0xc8, 0x1f, 0x15, 0x13, 0x3a, 0xca, 0x98, 0x20, 0x7f, 0xe2, 0x9d, - 0x2a, 0xe6, 0x1c, 0x77, 0xa5, 0x06, 0xe3, 0x19, 0xce, 0x7f, 0x38, 0xcf, - 0x5e, 0xd1, 0xef, 0xf8, 0x81, 0x20, 0xfa, 0x98, 0x45, 0x9f, 0x2b, 0x27, - 0xe0, 0x73, 0x8c, 0xe1, 0x01, 0x2c, 0x05, 0x0a, 0xa7, 0x19, 0xd9, 0xe5, - 0xf6, 0x06, 0xd4, 0x02, 0xdb, 0xee, 0x38, 0x41, 0x35, 0x02, 0x48, 0xa4, - 0x72, 0x0a, 0xa2, 0x6c, 0x6a, 0x8a, 0x18, 0x08, 0x4b, 0x26, 0x44, 0xa4, - 0x0a, 0x1e, 0x20, 0xcf, 0xfc, 0xa8, 0x72, 0x37, 0xe6, 0xe4, 0xea, 0xb4, - 0x4c, 0xe9, 0xe5, 0x6e, 0x1c, 0x57, 0x83, 0x2f, 0x44, 0x50, 0xc0, 0x3c, - 0x37, 0x07, 0x38, 0xbd, 0x6a, 0xc7, 0x88, 0x90, 0x0b, 0x7d, 0xe9, 0x20, - 0x2a, 0xbc, 0x73, 0xad, 0x07, 0x60, 0x52, 0x9a, 0x47, 0x2f, 0xe2, 0xc6, - 0x9a, 0xc0, 0x0d, 0x37, 0x12, 0x60, 0x99, 0x51, 0xfc, 0x5e, 0xdf, 0xc0, - 0x23, 0x7f, 0x47, 0xa2, 0x5c, 0xa6, 0x2f, 0xa5, 0x62, 0x13, 0xc6, 0x3b, - 0x61, 0xf1, 0x52, 0xe1, 0x90, 0x9b, 0xba, 0x4a, 0x67, 0x02, 0x3f, 0xfd, - 0x8d, 0xfe, 0xd7, 0xe1, 0xed, 0xd6, 0x26, 0x3a, 0xd9, 0x48, 0x3c, 0x00, - 0x11, 0x36, 0x33, 0x18, 0x6c, 0x9e, 0x57, 0x89, 0xe5, 0x44, 0xfe, 0xae, - 0x69, 0xd9, 0x4c, 0x22, 0x1f, 0x18, 0xe9, 0x07, 0xf8, 0xbf, 0x42, 0x8c, - 0x0b, 0xf1, 0xb5, 0x6c, 0x95, 0x2f, 0xcb, 0x0c, 0x85, 0x90, 0xc0, 0xfa, - 0x98, 0xcb, 0x32, 0xd8, 0xfb, 0x1a, 0x57, 0x49, 0xf5, 0xea, 0x9b, 0x27, - 0x3d, 0xf6, 0x11, 0xf5, 0xfc, 0xa9, 0x7f, 0xca, 0xe3, 0xf5, 0xb3, 0x50, - 0xd5, 0x78, 0xcf, 0x28, 0x99, 0x82, 0x11, 0x96, 0x46, 0x51, 0x00, 0x25, - 0x56, 0x4e, 0xf6, 0xa6, 0x59, 0xd3, 0x97, 0xdf, 0x0c, 0x1f, 0x4e, 0xa6, - 0x69, 0x50, 0x2f, 0xad, 0xe4, 0x84, 0x8b, 0x82, 0xc6, 0x45, 0x2f, 0xb8, - 0x07, 0x9a, 0x5c, 0x1e, 0xa8, 0xe7, 0x9a, 0xcc, 0xff, 0xf4, 0x89, 0x30, - 0xa7, 0x52, 0x9b, 0x99, 0x65, 0x28, 0xda, 0xef, 0x4f, 0x5a, 0x8c, 0x27, - 0x36, 0x4a, 0x06, 0x5d, 0xc0, 0x5c, 0x79, 0x96, 0xbf, 0x2d, 0xd6, 0xcb, - 0xa4, 0xcc, 0xc7, 0x15, 0xa0, 0x93, 0xb0, 0x2f, 0xa1, 0x19, 0x5f, 0x6e, - 0x66, 0x94, 0xe7, 0x37, 0x74, 0xf8, 0x22, 0x57, 0xed, 0xca, 0x0f, 0x0d, - 0x31, 0x54, 0xe2, 0x5b, 0xc6, 0xb1, 0x3d, 0x97, 0xb5, 0xdb, 0xaa, 0x5d, - 0x60, 0x0f, 0x08, 0x22, 0x1e, 0x2d, 0x80, 0x99, 0x92, 0x1a, 0x4d, 0x2d, - 0x90, 0x41, 0x38, 0x40, 0x0d, 0x07, 0xe0, 0xbc, 0x0c, 0x76, 0x58, 0x61, - 0xb2, 0xd1, 0x4b, 0x97, 0x68, 0x12, 0x3f, 0x6a, 0x4f, 0xc3, 0xf9, 0x1f, - 0xc8, 0x58, 0x39, 0x7b, 0xbc, 0x7f, 0x5a, 0xf9, 0xc4, 0x1a, 0x14, 0x88, - 0x27, 0x1d, 0xc6, 0xf6, 0x66, 0x95, 0x87, 0xcb, 0x99, 0xee, 0x50, 0x8d, - 0x56, 0xff, 0x90, 0x0b, 0xb4, 0x94, 0x77, 0xcb, 0x06, 0x63, 0x7a, 0x65, - 0xf1, 0xfc, 0x35, 0x59, 0x68, 0xee, 0x50, 0x25, 0xf2, 0x5c, 0xff, 0x28, - 0x9e, 0xd1, 0xd5, 0xea, 0x84, 0x14, 0x90, 0x28, 0xfc, 0x5f, 0xa0, 0x3e, - 0xc8, 0xee, 0x61, 0xeb, 0x05, 0x9c, 0x6e, 0x44, 0x58, 0x78, 0xfc, 0xfe, - 0x0c, 0xb5, 0x01, 0xf9, 0xab, 0xf3, 0xbf, 0xcd, 0x6f, 0x8e, 0x31, 0xdc, - 0x4a, 0xb4, 0x12, 0xe9, 0x8a, 0x15, 0x90, 0x62, 0x4d, 0xc1, 0xef, 0xbf, - 0x53, 0xeb, 0x8f, 0x90, 0x1d, 0x17, 0xbf, 0xc7, 0xa3, 0x0c, 0x35, 0x26, - 0x76, 0x9b, 0xa4, 0x56, 0xf0, 0xfc, 0x41, 0xe0, 0x96, 0x02, 0x75, 0x9b, - 0x0f, 0xfe, 0x1a, 0x9c, 0x10, 0x79, 0xa5, 0xfa, 0x2c, 0x5b, 0x6f, 0xfa, - 0xf3, 0x16, 0xea, 0xca, 0xed, 0xb5, 0xe9, 0xd3, 0x73, 0xf0, 0x41, 0x29, - 0x98, 0x4a, 0x00, 0x10, 0x03, 0xe8, 0x02, 0x6f, 0x15, 0xf8, 0x42, 0x65, - 0xb6, 0x8b, 0xf7, 0x12, 0x96, 0x55, 0xf6, 0x0e, 0x38, 0xaa, 0xc7, 0x6f, - 0x70, 0x7b, 0x40, 0x0f, 0xce, 0x02, 0xa7, 0xe3, 0xba, 0x8f, 0xff, 0xaa, - 0x76, 0x7e, 0x3c, 0xc9, 0x43, 0x98, 0x59, 0xa5, 0x4c, 0x68, 0x99, 0x03, - 0x01, 0x45, 0x11, 0x0d, 0x04, 0x60, 0xfa, 0x9d, 0xa9, 0xf7, 0xfd, 0x9e, - 0x3b, 0xac, 0xc6, 0xf9, 0xdd, 0xd2, 0x8c, 0x9b, 0x13, 0x58, 0x83, 0xcc, - 0x69, 0x6e, 0x63, 0x58, 0x79, 0x80, 0x10, 0xc6, 0x61, 0x21, 0xe0, 0x61, - 0x42, 0xac, 0x07, 0x95, 0xfd, 0xbd, 0xb7, 0xa8, 0x17, 0xed, 0x71, 0xc2, - 0x58, 0xf3, 0x36, 0x5e, 0x4e, 0x09, 0xe0, 0x3f, 0x6e, 0x1d, 0x28, 0x7c, - 0x4b, 0x9d, 0x1f, 0xd7, 0x84, 0x27, 0x29, 0xd3, 0x1f, 0xcf, 0x0a, 0xfc, - 0xdb, 0x3a, 0xde, 0xda, 0xd1, 0x3a, 0x50, 0x4a, 0x5a, 0x82, 0x80, 0x48, - 0xd1, 0x38, 0x49, 0x9d, 0x88, 0xb7, 0x39, 0x16, 0xa7, 0xb7, 0xbb, 0xdf, - 0x82, 0xfa, 0xa4, 0x08, 0xca, 0x13, 0x20, 0xe4, 0xcc, 0x69, 0x10, 0x89, - 0x85, 0xdc, 0xfe, 0xca, 0xd5, 0xbb, 0x1c, 0x75, 0x71, 0x94, 0x70, 0xce, - 0x46, 0x58, 0x33, 0x92, 0x5d, 0x61, 0x29, 0xe4, 0xa1, 0xaf, 0xed, 0x8e, - 0x35, 0x89, 0xa7, 0x45, 0x82, 0x33, 0x85, 0xa5, 0x36, 0x9f, 0x70, 0xbd, - 0xf4, 0x63, 0x5d, 0xc2, 0x3c, 0xd8, 0xea, 0x53, 0x7b, 0x6a, 0xf0, 0xa9, - 0x19, 0xbb, 0x9b, 0x1d, 0xf5, 0xaf, 0x4e, 0x71, 0xf4, 0xae, 0x44, 0x12, - 0x18, 0x71, 0x03, 0x4d, 0x9d, 0x04, 0x89, 0x47, 0xc4, 0x02, 0x69, 0xb9, - 0x6b, 0x79, 0x76, 0x29, 0x6f, 0xe6, 0x9b, 0x40, 0xe8, 0x4b, 0x94, 0x84, - 0xd1, 0x90, 0x3d, 0xaf, 0xcf, 0x3e, 0xdb, 0xe5, 0xec, 0x5e, 0x2d, 0x7f, - 0x1a, 0x92, 0x32, 0x10, 0xcc, 0xcb, 0xb5, 0xf0, 0x13, 0x15, 0xb4, 0x2e, - 0xec, 0x11, 0x65, 0x90, 0x42, 0x1b, 0xb5, 0x20, 0xa7, 0x7c, 0x92, 0xd1, - 0x33, 0x9d, 0xea, 0xa8, 0x46, 0xca, 0x2a, 0x60, 0x3d, 0xcf, 0x5d, 0x8f, - 0xa5, 0x25, 0x42, 0xe5, 0xff, 0x2a, 0x0b, 0x60, 0xcf, 0xfd, 0x8c, 0xb7, - 0xd9, 0x83, 0xa2, 0xc9, 0x6f, 0xc2, 0x5a, 0x30, 0xc2, 0xd8, 0x41, 0xd7, - 0x9a, 0xbe, 0x1b, 0xfe, 0x3c, 0xa3, 0x0f, 0x2d, 0x02, 0xe0, 0x4a, 0x66, - 0x92, 0x2d, 0xb4, 0x11, 0x48, 0xcb, 0xed, 0x04, 0xd9, 0xd1, 0x5b, 0xe3, - 0x7f, 0x9f, 0x99, 0x3b, 0x92, 0x95, 0x51, 0x64, 0x3a, 0x5d, 0x94, 0xce, - 0xfb, 0x73, 0xf1, 0xde, 0x2b, 0xf0, 0xcf, 0xb2, 0x00, 0x44, 0xe4, 0x92, - 0xbd, 0x3f, 0x5b, 0xa5, 0x1f, 0x97, 0xeb, 0x84, 0x52, 0x18, 0xd5, 0xad, - 0x79, 0x2d, 0x47, 0xfd, 0x24, 0xa3, 0x43, 0x2d, 0x0f, 0xa2, 0x9a, 0xd0, - 0xe5, 0x70, 0x23, 0x04, 0x82, 0x3d, 0x84, 0xab, 0x22, 0xf8, 0x82, 0x90, - 0x48, 0x56, 0x50, 0xb7, 0x9a, 0x41, 0x2d, 0xfc, 0x6f, 0x25, 0x0b, 0x86, - 0x01, 0x8b, 0x35, 0x18, 0xc4, 0xa4, 0x68, 0x78, 0x3a, 0x99, 0xd4, 0xa0, - 0xd3, 0xa3, 0x23, 0xf5, 0xde, 0x69, 0xba, 0x22, 0x60, 0x89, 0x56, 0x51, - 0x87, 0xe9, 0xea, 0x48, 0xbc, 0xdf, 0xe2, 0x9e, 0x7b, 0xfc, 0x88, 0x6b, - 0x6a, 0xe9, 0x65, 0xb8, 0x9c, 0xe9, 0x72, 0x28, 0xc9, 0xe9, 0x89, 0x11, - 0xf1, 0x2a, 0xd1, 0x4f, 0x7e, 0xf9, 0x5e, 0x07, 0x4f, 0xee, 0xdc, 0x82, - 0x4a, 0x53, 0x30, 0xf9, 0x96, 0x85, 0x1f, 0x99, 0xac, 0xd9, 0xfa, 0x44, - 0xa4, 0xe5, 0x4f, 0x16, 0xe7, 0x9c, 0x42, 0x11, 0x2d, 0x95, 0x2c, 0xbf, - 0x00, 0x17, 0x9e, 0x98, 0xc9, 0x9e, 0x77, 0x85, 0xe2, 0x0b, 0x29, 0xb7, - 0xa2, 0x4f, 0x04, 0xc9, 0x2d, 0xa3, 0x04, 0x8f, 0x82, 0x5e, 0x16, 0x58, - 0x33, 0x00, 0x21, 0x34, 0x72, 0xe4, 0x2a, 0xd9, 0x44, 0x7a, 0x63, 0xfc, - 0xf5, 0xa5, 0x80, 0x7f, 0x9e, 0xb6, 0xb9, 0xa5, 0xe3, 0xb4, 0x99, 0x1f, - 0x4d, 0x61, 0x1e, 0xcd, 0xa6, 0x37, 0x9f, 0x38, 0x8c, 0xfa, 0x28, 0xa5, - 0x81, 0x18, 0xe4, 0xbb, 0x29, 0xcf, 0x1c, 0x74, 0xd7, 0x69, 0xa7, 0xd9, - 0xed, 0x4c, 0x10, 0x93, 0xf3, 0x47, 0x81, 0xe7, 0x90, 0x32, 0x6d, 0xc4, - 0x74, 0x2a, 0xcd, 0x2f, 0x04, 0xd2, 0x00, 0xcc, 0x20, 0x7e, 0x71, 0xab, - 0x73, 0xf4, 0xda, 0xd9, 0xe2, 0xf7, 0x2c, 0xf4, 0x86, 0x42, 0x85, 0x13, - 0x47, 0x25, 0x2e, 0xe0, 0x65, 0x6f, 0x5a, 0x22, 0xbc, 0x1c, 0xf1, 0x8f, - 0x87, 0xff, 0xda, 0x99, 0x50, 0x54, 0xa4, 0x48, 0x47, 0x0f, 0xf6, 0x2d, - 0xdf, 0x99, 0xc9, 0xb4, 0xb4, 0x67, 0x8c, 0x06, 0x3e, 0x80, 0xf9, 0x9a, - 0x03, 0x25, 0x97, 0x84, 0x04, 0x93, 0x97, 0xa5, 0x52, 0xc4, 0x43, 0x0e, - 0x91, 0x45, 0x0c, 0x06, 0xf5, 0x15, 0x89, 0x47, 0x15, 0xba, 0xaa, 0x03, - 0x90, 0xf1, 0x43, 0x8a, 0x33, 0xc6, 0xc7, 0x19, 0x21, 0x47, 0x00, 0xac, - 0x89, 0xec, 0xa9, 0xb6, 0xb8, 0x34, 0x7b, 0xf2, 0x51, 0xd3, 0xf9, 0xf4, - 0x18, 0x19, 0x87, 0xd0, 0x07, 0x54, 0x70, 0xf9, 0x79, 0x74, 0x51, 0xee, - 0x41, 0x0d, 0xfa, 0xed, 0x8f, 0x0e, 0x2f, 0xf7, 0xd4, 0x8b, 0xc3, 0xb5, - 0x72, 0x26, 0x5c, 0xe5, 0xbe, 0x9c, 0x3e, 0x01, 0x04, 0xfc, 0x6d, 0x7b, - 0xc2, 0x4f, 0xfe, 0x2c, 0x5e, 0xea, 0xf1, 0x64, 0x31, 0xc5, 0x31, 0x31, - 0x42, 0x7d, 0x98, 0x80, 0x64, 0x42, 0x47, 0xc4, 0x45, 0xed, 0xfc, 0xf2, - 0x9f, 0x45, 0xad, 0xda, 0xaf, 0x51, 0x61, 0x97, 0x45, 0x68, 0x31, 0xc9, - 0xa1, 0x46, 0x5e, 0x03, 0xa9, 0xaa, 0x05, 0x14, 0x51, 0x61, 0xe9, 0xbd, - 0x58, 0x6c, 0x6d, 0x09, 0xd2, 0x48, 0x65, 0x7d, 0x79, 0xd9, 0xc9, 0x1e, - 0xca, 0xa5, 0xdc, 0xa7, 0x86, 0x77, 0xd6, 0x41, 0x45, 0x0f, 0x88, 0x7e, - 0xb1, 0xa5, 0xfa, 0xdd, 0xaa, 0x2d, 0xa8, 0x89, 0xa1, 0x32, 0x3b, 0x0b, - 0xe0, 0x0a, 0xf5, 0x72, 0x29, 0x9c, 0x03, 0xce, 0x00, 0x42, 0x46, 0x06, - 0x79, 0xbc, 0xd2, 0xfd, 0x23, 0x08, 0x00, 0x7c, 0xad, 0x65, 0xc5, 0x69, - 0x51, 0xa8, 0xcc, 0x68, 0x45, 0x7b, 0xc4, 0x72, 0xdc, 0xf0, 0x43, 0xd0, - 0xa3, 0x24, 0x94, 0x4f, 0xd3, 0x03, 0x53, 0xf9, 0x47, 0xf2, 0xcd, 0x79, - 0xa7, 0x4b, 0x7c, 0xbb, 0x69, 0x00, 0x51, 0xaf, 0x4e, 0x11, 0xf1, 0x3e, - 0x80, 0xaa, 0x8d, 0x57, 0x2f, 0xc9, 0x6a, 0xff, 0x3d, 0xbc, 0xdb, 0xad, - 0xea, 0x75, 0xfb, 0xdb, 0x70, 0x64, 0xd1, 0x1b, 0xed, 0x4a, 0x55, 0x01, - 0xe0, 0x6d, 0x99, 0x6f, 0x17, 0x56, 0x2d, 0x1e, 0x17, 0x47, 0x26, 0x1d, - 0x50, 0xcf, 0x00, 0xdc, 0xb2, 0x28, 0x2a, 0x9f, 0xd7, 0xf7, 0x2e, 0xb6, - 0xb9, 0xe3, 0x91, 0xca, 0x9e, 0x58, 0xdb, 0x64, 0x4a, 0x42, 0x31, 0xfa, - 0x8a, 0xba, 0x7c, 0xa5, 0x8a, 0x76, 0xce, 0xdc, 0x47, 0xe3, 0xf8, 0xeb, - 0x3a, 0xdc, 0x90, 0xb1, 0xc4, 0x28, 0x1c, 0xaa, 0x08, 0x51, 0xfb, 0x74, - 0x76, 0xbd, 0x83, 0x75, 0x3e, 0xef, 0x2d, 0xb3, 0x21, 0x60, 0x04, 0xa2, - 0xf8, 0x05, 0x14, 0x72, 0xa8, 0x61, 0x20, 0xe5, 0x26, 0x77, 0x71, 0x70, - 0x4f, 0x8a, 0xfa, 0x3b, 0x88, 0x7b, 0x59, 0x65, 0x10, 0xdd, 0xa2, 0x22, - 0x55, 0x58, 0x28, 0xfc, 0xb5, 0xe9, 0x91, 0x7a, 0xf2, 0x35, 0x08, 0x50, - 0x9a, 0x5f, 0xd2, 0xda, 0xb6, 0x5b, 0xda, 0xb9, 0x14, 0x83, 0xb2, 0x5f, - 0xee, 0x73, 0x0f, 0xa8, 0x6c, 0xb3, 0xe2, 0x4a, 0x47, 0xc1, 0x3d, 0xf5, - 0x44, 0x8d, 0x50, 0xfa, 0xa2, 0x3e, 0x85, 0xf0, 0x1f, 0x7d, 0x49, 0x47, - 0xc5, 0x43, 0x7f, 0x40, 0xa5, 0xe2, 0x09, 0x03, 0xae, 0x98, 0x4b, 0xd3, - 0x07, 0xb9, 0x1e, 0x05, 0x7c, 0xf1, 0xb1, 0xe7, 0x26, 0xd6, 0xc9, 0xc9, - 0x0f, 0x06, 0xd6, 0x9d, 0xfc, 0x2a, 0xdb, 0x7f, 0x43, 0x39, 0x61, 0x69, - 0x32, 0xe7, 0x98, 0xdb, 0xde, 0x51, 0xd7, 0x21, 0xd1, 0x2a, 0x84, 0x9d, - 0x16, 0x32, 0xa1, 0x4e, 0x70, 0x41, 0x23, 0x97, 0x2f, 0xa2, 0x4f, 0x4e, - 0xb4, 0x97, 0xae, 0x5e, 0x6f, 0x05, 0x03, 0x7a, 0x23, 0x40, 0x3c, 0x2d, - 0x42, 0xa5, 0x95, 0x6c, 0x40, 0xec, 0x65, 0x30, 0x72, 0x8e, 0x11, 0x0c, - 0x49, 0xa0, 0x9b, 0x28, 0xcf, 0x9f, 0xca, 0x67, 0x7b, 0xa0, 0x68, 0x16, - 0xf1, 0x31, 0xe3, 0x6f, 0xc2, 0xb6, 0xee, 0xf3, 0xd6, 0xb6, 0x68, 0x19, - 0x86, 0x97, 0xc5, 0x22, 0x57, 0xa8, 0x1b, 0xe4, 0x78, 0xd7, 0x1d, 0xf9, - 0xe8, 0xcf, 0x15, 0x9b, 0x73, 0x48, 0xc2, 0xd5, 0x50, 0xd1, 0x6d, 0x3d, - 0xf8, 0xfd, 0xdb, 0x57, 0x90, 0x60, 0xdf, 0x30, 0xdd, 0x85, 0x47, 0xc6, - 0xa3, 0x5e, 0x19, 0xef, 0x8c, 0xd9, 0x29, 0xe2, 0x46, 0x59, 0xb1, 0x72, - 0x9d, 0x59, 0xbf, 0x72, 0xae, 0x37, 0x1c, 0xc4, 0x87, 0xc5, 0x23, 0x15, - 0xc3, 0xc2, 0xcb, 0xe1, 0x1a, 0x52, 0x48, 0x21, 0xf7, 0x20, 0xd8, 0xb9, - 0xdf, 0xbd, 0xd5, 0x4e, 0x45, 0x50, 0x29, 0x16, 0xe4, 0xc8, 0x4d, 0xf1, - 0x8a, 0x34, 0x61, 0x0e, 0x50, 0xca, 0x22, 0x7e, 0x22, 0x31, 0xd9, 0xc5, - 0x67, 0xa6, 0x83, 0x1a, 0x5c, 0x91, 0x0c, 0xf2, 0xdf, 0x19, 0x9d, 0x00, - 0x95, 0x0f, 0x72, 0xba, 0xa2, 0xd9, 0xff, 0x1f, 0xc7, 0x45, 0xbc, 0xcc, - 0x49, 0x90, 0xc9, 0x78, 0xc1, 0x8e, 0x98, 0x51, 0x10, 0x34, 0xf6, 0xc9, - 0x64, 0xd5, 0x55, 0x14, 0xc5, 0xc5, 0x71, 0x2e, 0x51, 0x79, 0xbe, 0xaa, - 0xff, 0xa6, 0xb3, 0x8d, 0x62, 0x34, 0x49, 0x63, 0xa3, 0x51, 0xd0, 0x91, - 0x23, 0x29, 0x11, 0xe2, 0x85, 0xdc, 0xd2, 0x61, 0x57, 0x25, 0x76, 0x2b, - 0x42, 0x08, 0x69, 0xac, 0x57, 0xa4, 0x35, 0x34, 0x4b, 0xd5, 0x86, 0xf0, - 0x35, 0x9d, 0xb9, 0x17, 0x98, 0xbe, 0x69, 0x70, 0xd9, 0xcd, 0x0f, 0xe5, - 0xe5, 0xaf, 0x97, 0x1f, 0xa4, 0xc7, 0xd3, 0x8b, 0x22, 0x32, 0x78, 0x49, - 0x84, 0x64, 0xaa, 0xe7, 0xe9, 0x86, 0xd8, 0xb8, 0xad, 0xe9, 0xc5, 0x11, - 0xcb, 0xf3, 0xad, 0xb5, 0x14, 0xa5, 0xe2, 0xf1, 0x43, 0xb5, 0xdf, 0xd3, - 0x7e, 0xb7, 0x9e, 0x50, 0x68, 0xf6, 0xcb, 0x9e, 0x43, 0x4b, 0xf5, 0x19, - 0x0c, 0xa9, 0x1f, 0xd6, 0x14, 0x0e, 0xdc, 0xe0, 0x09, 0x64, 0xa5, 0xe6, - 0x02, 0x95, 0x71, 0x7c, 0xed, 0xb9, 0xb4, 0x87, 0x6c, 0x96, 0x50, 0xcc, - 0x13, 0xa1, 0x36, 0xee, 0xbf, 0x7e, 0xdc, 0x58, 0xf7, 0x7f, 0xd1, 0x04, - 0x13, 0x01, 0xa4, 0x6d, 0xb4, 0x9a, 0x1a, 0xd0, 0x9e, 0x4f, 0xe0, 0xe7, - 0xdc, 0x93, 0xb6, 0xfd, 0xd4, 0x54, 0xd8, 0xed, 0x0b, 0xeb, 0x38, 0x5b, - 0xfe, 0xde, 0xf9, 0x0e, 0x0f, 0xad, 0x17, 0x04, 0x84, 0x2c, 0x25, 0x0f, - 0x99, 0xd2, 0x10, 0xcb, 0x19, 0x1a, 0xcc, 0x59, 0x6f, 0xe8, 0x17, 0x6f, - 0xe5, 0x04, 0xb3, 0x40, 0x00, 0x02, 0x40, 0x77, 0x01, 0x1b, 0x6a, 0xb0, - 0x55, 0xf7, 0x29, 0x1c, 0x95, 0x64, 0x42, 0xdd, 0xbf, 0x21, 0x1d, 0xa9, - 0x43, 0x24, 0x8b, 0xfc, 0x52, 0xc0, 0xce, 0x58, 0x00, 0xf0, 0x1d, 0x19, - 0x7d, 0x2c, 0x52, 0xfe, 0x5f, 0x3d, 0x5e, 0x94, 0x05, 0x22, 0x72, 0x87, - 0x80, 0xb1, 0x4b, 0xb4, 0x94, 0xb2, 0x4d, 0x2f, 0x8e, 0x25, 0xbb, 0x22, - 0x6c, 0x35, 0x03, 0x4c, 0xcd, 0x16, 0x45, 0xf2, 0x64, 0x9f, 0x82, 0x08, - 0x78, 0x33, 0x8d, 0x1a, 0x20, 0x78, 0xbb, 0x99, 0xbf, 0xf8, 0x4e, 0x91, - 0x76, 0x5d, 0x26, 0x18, 0x5b, 0x0c, 0xf0, 0x42, 0x6a, 0xa0, 0x71, 0xfe, - 0xa7, 0xd2, 0x26, 0xd1, 0x69, 0x5e, 0x73, 0x42, 0x1d, 0xb0, 0x99, 0xd6, - 0x49, 0x03, 0xe2, 0x2e, 0x1d, 0xd1, 0x86, 0x6c, 0x95, 0xf5, 0x14, 0x13, - 0x56, 0xb5, 0x6e, 0x0a, 0xde, 0x8a, 0x28, 0x62, 0x37, 0x9d, 0x99, 0x29, - 0xd0, 0x86, 0x14, 0x26, 0x81, 0x6a, 0xa8, 0x07, 0xbb, 0x23, 0x58, 0x54, - 0xd7, 0x5a, 0x36, 0xef, 0xe7, 0xd8, 0x1b, 0x86, 0xba, 0x6e, 0x29, 0xe6, - 0x9c, 0x91, 0xb8, 0x19, 0xe7, 0xb3, 0x03, 0xba, 0x1a, 0x39, 0x64, 0x34, - 0x8f, 0x72, 0x0f, 0x2d, 0xff, 0x0d, 0x8a, 0xaf, 0x34, 0x4e, 0x31, 0xf6, - 0x64, 0xbb, 0x5c, 0x0c, 0x66, 0x87, 0xb4, 0xd0, 0x95, 0x37, 0x98, 0x14, - 0x48, 0x01, 0x10, 0x8d, 0x60, 0x1b, 0xd2, 0xc6, 0xe9, 0x02, 0xff, 0x3c, - 0x01, 0xcc, 0xa5, 0x95, 0xa3, 0x42, 0x4d, 0x59, 0x00, 0x33, 0x5d, 0x38, - 0xe7, 0x71, 0x79, 0xeb, 0xcc, 0x2b, 0xd3, 0x34, 0xb5, 0xd7, 0x61, 0xac, - 0x14, 0xb2, 0xec, 0x52, 0x1a, 0x0e, 0x97, 0x02, 0x49, 0xed, 0xfc, 0x06, - 0xbb, 0x7f, 0x6f, 0xfa, 0x23, 0xad, 0x6f, 0x96, 0x2e, 0xee, 0x03, 0x36, - 0x34, 0x08, 0x4f, 0x26, 0x4f, 0xcd, 0x3e, 0x28, 0x54, 0x97, 0xbd, 0xfb, - 0x31, 0x46, 0x1a, 0x6b, 0x9b, 0xcf, 0x2d, 0xca, 0x37, 0xab, 0x8f, 0xd6, - 0x30, 0xc5, 0x95, 0x6d, 0xfe, 0x6f, 0xc8, 0x1b, 0x70, 0x90, 0x25, 0xb1, - 0x92, 0x02, 0xb0, 0x9d, 0x81, 0x0e, 0x26, 0x51, 0x97, 0x60, 0xbe, 0x25, - 0x62, 0xae, 0x5c, 0xd6, 0xbd, 0xfc, 0xca, 0xad, 0x6a, 0x6a, 0xdb, 0x4b, - 0x19, 0x8a, 0x04, 0xce, 0x73, 0x73, 0x39, 0x22, 0x6b, 0x2f, 0x5f, 0x22, - 0x78, 0xd6, 0xd1, 0xcb, 0xa3, 0xf0, 0x48, 0x78, 0x80, 0xb9, 0x69, 0xe4, - 0x57, 0xdc, 0x0e, 0x47, 0x6a, 0x28, 0x94, 0x88, 0xca, 0xac, 0x83, 0x27, - 0xbb, 0x11, 0x74, 0x74, 0xc8, 0xce, 0x11, 0x01, 0xc0, 0x0e, 0x92, 0xaf, - 0x58, 0xf9, 0xd3, 0xae, 0xa5, 0xed, 0x81, 0x84, 0x69, 0xd5, 0xcb, 0xe3, - 0x65, 0xc9, 0x84, 0xbb, 0x5d, 0x89, 0xe3, 0x8f, 0x98, 0x04, 0xf7, 0x06, - 0x93, 0x9f, 0xd8, 0xb3, 0x61, 0xfe, 0xfa, 0xd2, 0x86, 0x39, 0x53, 0xed, - 0x58, 0x0b, 0x61, 0x88, 0x46, 0x8f, 0x8f, 0x1f, 0xdf, 0x1a, 0x7a, 0x77, - 0x06, 0x72, 0xc5, 0x6a, 0x88, 0x60, 0x2f, 0x4a, 0x60, 0xe4, 0xbe, 0xa0, - 0x59, 0x69, 0xb0, 0xc6, 0x49, 0x7a, 0x95, 0x03, 0x0e, 0xa9, 0x60, 0x22, - 0xa3, 0xd4, 0xc6, 0x54, 0x63, 0xdc, 0x1c, 0x5a, 0x8a, 0x25, 0x19, 0x4f, - 0xc4, 0x8d, 0xae, 0xba, 0x9b, 0x3e, 0xe1, 0xd2, 0x27, 0x1c, 0x68, 0x87, - 0x18, 0x06, 0x5f, 0x64, 0x25, 0xba, 0x67, 0x0e, 0xda, 0x9a, 0xb9, 0x97, - 0x9e, 0x52, 0x32, 0x44, 0x25, 0x9a, 0xa7, 0xa3, 0xae, 0xce, 0x19, 0x6d, - 0x33, 0x04, 0x63, 0x93, 0x14, 0x43, 0x8c, 0xaf, 0xa8, 0x4f, 0xa8, 0xe3, - 0x53, 0x6f, 0x77, 0x4b, 0xc6, 0xd9, 0x6c, 0x02, 0x8f, 0xd8, 0x17, 0x9d, - 0x52, 0x10, 0x2b, 0x4f, 0x92, 0x91, 0xd1, 0xa2, 0x94, 0x8f, 0xd5, 0xb9, - 0xd2, 0xf5, 0xd9, 0xec, 0x47, 0x4f, 0x27, 0x87, 0x21, 0x6d, 0x2c, 0x81, - 0x87, 0x07, 0xb5, 0x29, 0x26, 0x46, 0x7c, 0x47, 0x38, 0x97, 0x98, 0x13, - 0xa2, 0xaa, 0x47, 0x9d, 0x23, 0x3c, 0x9c, 0x2d, 0x80, 0x56, 0x10, 0xb9, - 0xbe, 0x78, 0xe8, 0x61, 0x17, 0x92, 0x8b, 0x88, 0x70, 0xf4, 0x31, 0xf0, - 0x0c, 0x07, 0xe7, 0xbd, 0x1c, 0x34, 0xe5, 0x8e, 0x8c, 0xe8, 0xd6, 0x4e, - 0x38, 0xef, 0x0b, 0x59, 0xf7, 0xc1, 0x5f, 0x0f, 0xa4, 0x21, 0x93, 0x90, - 0x27, 0x80, 0x21, 0x29, 0xe5, 0x7d, 0x12, 0xfd, 0x0e, 0x27, 0x0b, 0x42, - 0x8e, 0xcd, 0x12, 0x50, 0x96, 0x5b, 0x94, 0xa0, 0x3e, 0x29, 0xee, 0x1a, - 0x6f, 0xc5, 0x07, 0x9a, 0xef, 0xbc, 0x9e, 0x9e, 0x8b, 0x6f, 0x99, 0x96, - 0x78, 0x3b, 0x2c, 0xd2, 0xc5, 0x05, 0x91, 0x96, 0x5e, 0x39, 0x06, 0xb2, - 0x0f, 0x34, 0xa5, 0x98, 0x98, 0x67, 0xd9, 0x4e, 0x92, 0xb8, 0x46, 0xc0, - 0x7a, 0xf4, 0xf2, 0x90, 0x97, 0xcf, 0x33, 0x9e, 0x0b, 0xb7, 0xf3, 0xef, - 0xa5, 0xa5, 0xbf, 0x97, 0xf9, 0x04, 0x46, 0xea, 0x31, 0x21, 0x94, 0x61, - 0x19, 0x17, 0xd1, 0x9d, 0xe7, 0xfa, 0x3a, 0xaa, 0x52, 0x55, 0x46, 0x72, - 0x1b, 0x97, 0xd9, 0x6b, 0x5e, 0x3d, 0x15, 0x83, 0x55, 0x01, 0x95, 0x52, - 0x27, 0xd1, 0x0c, 0x41, 0x90, 0x67, 0x44, 0x7d, 0x4f, 0xd8, 0x7a, 0x3e, - 0x9f, 0xae, 0xc3, 0x00, 0x86, 0xc3, 0xc2, 0x06, 0xd8, 0x99, 0xb4, 0xfc, - 0x00, 0xbf, 0x8e, 0xa3, 0x0c, 0xf9, 0x14, 0x48, 0x2a, 0xb0, 0x5e, 0xf8, - 0xfe, 0x6b, 0x83, 0x13, 0xaa, 0x94, 0xd0, 0x62, 0x9b, 0xbb, 0xa7, 0x33, - 0x26, 0x18, 0xca, 0x60, 0x48, 0x0c, 0x5c, 0xe3, 0x13, 0x94, 0x24, 0xfe, - 0x00, 0xf3, 0x1f, 0xa2, 0x2f, 0xae, 0x49, 0x92, 0xe7, 0xf6, 0x49, 0x1e, - 0xf7, 0x57, 0x4c, 0xe5, 0x4c, 0x5f, 0x8c, 0xa3, 0xdc, 0x70, 0xbe, 0x5b, - 0x8c, 0x3c, 0xdb, 0xd3, 0x84, 0x02, 0x6e, 0xdc, 0xd5, 0x6a, 0xc9, 0xc2, - 0x5f, 0x95, 0x3a, 0x2d, 0x44, 0x87, 0x09, 0x52, 0x90, 0x41, 0x1f, 0xa8, - 0x93, 0x76, 0xae, 0x53, 0xd3, 0xef, 0x26, 0x15, 0x27, 0x38, 0x04, 0xc7, - 0xda, 0xed, 0xb1, 0x11, 0xe8, 0x2a, 0x67, 0x03, 0xd0, 0xfe, 0x5f, 0x85, - 0xfc, 0xa0, 0x6a, 0x73, 0x6e, 0xac, 0x15, 0x8d, 0xa2, 0xca, 0x5b, 0x32, - 0x52, 0xc1, 0x2e, 0xf4, 0xe6, 0x68, 0x99, 0xbd, 0xeb, 0x05, 0x4e, 0x8f, - 0xb7, 0x5c, 0xd1, 0x31, 0x5b, 0x17, 0x98, 0x81, 0xef, 0x69, 0x3d, 0x23, - 0x01, 0xc3, 0x34, 0xc7, 0x69, 0x39, 0x5e, 0xb3, 0x1e, 0x99, 0xa6, 0xbf, - 0x78, 0xee, 0x88, 0xe2, 0xdb, 0xd7, 0x4e, 0x17, 0xa0, 0x27, 0x0f, 0xe6, - 0x9f, 0x9f, 0x74, 0x0c, 0xa4, 0xd2, 0x47, 0xe3, 0xc1, 0xb5, 0xc9, 0x13, - 0xaa, 0x72, 0x22, 0xbb, 0x7d, 0xd6, 0xb8, 0x76, 0x6c, 0x5e, 0xd5, 0xf7, - 0x22, 0x69, 0x7c, 0x40, 0x4f, 0x64, 0xcd, 0x02, 0x43, 0x4a, 0x09, 0x1d, - 0x95, 0x90, 0x16, 0x3f, 0xaa, 0x4d, 0xdf, 0x5d, 0xea, 0x76, 0xb0, 0x52, - 0x92, 0xa1, 0xde, 0xd6, 0x2f, 0x66, 0x7d, 0x53, 0x65, 0xb4, 0xa6, 0x3e, - 0x0a, 0x85, 0x03, 0x56, 0x82, 0x6f, 0x17, 0xe6, 0xb6, 0xef, 0x0f, 0x4e, - 0x01, 0xc5, 0xba, 0x01, 0xdb, 0x23, 0x4c, 0x9f, 0x11, 0x59, 0x28, 0x71, - 0xc4, 0xf2, 0xeb, 0x00, 0xa9, 0x72, 0x7b, 0xd7, 0x02, 0x94, 0xd8, 0xaf, - 0xad, 0x16, 0x92, 0x51, 0xea, 0xe4, 0xb6, 0xf6, 0xe1, 0x80, 0xaf, 0x6b, - 0x0d, 0x2c, 0xbc, 0x6f, 0xb4, 0x0c, 0xa9, 0xd4, 0xf8, 0xb8, 0x19, 0xc5, - 0x69, 0x5d, 0x8f, 0xce, 0x4b, 0x98, 0x11, 0xae, 0x66, 0x19, 0x66, 0x6e, - 0xe5, 0x88, 0xc9, 0x23, 0xf5, 0xc6, 0x3d, 0x52, 0x4d, 0x5a, 0x6d, 0x5e, - 0xdc, 0x00, 0x21, 0x41, 0x53, 0xab, 0x97, 0x3d, 0xa3, 0xfb, 0xd9, 0xdf, - 0x90, 0x77, 0xeb, 0x4f, 0x8d, 0xec, 0xca, 0x17, 0xad, 0x65, 0xb9, 0x92, - 0x0c, 0x24, 0xd4, 0x80, 0x19, 0x78, 0x49, 0x7d, 0x9b, 0xcf, 0xdd, 0xaf, - 0xfd, 0xb8, 0xdd, 0x89, 0x4b, 0xe5, 0xb9, 0x99, 0x9b, 0x70, 0x24, 0xc5, - 0x86, 0x42, 0x92, 0x2c, 0x47, 0xd5, 0x1a, 0x50, 0x5d, 0x4d, 0xcf, 0xdc, - 0xb4, 0x19, 0x9a, 0xe2, 0x94, 0x5f, 0x1b, 0x19, 0x40, 0xd3, 0x5c, 0xe3, - 0x09, 0xe3, 0x7c, 0x15, 0x60, 0x49, 0xf7, 0xf9, 0xdb, 0x8e, 0x38, 0x69, - 0xfa, 0xa2, 0xe6, 0x18, 0x11, 0xc3, 0x57, 0xa0, 0xec, 0x1b, 0x43, 0x3a, - 0xb1, 0x5a, 0x6a, 0xcd, 0x5a, 0x2e, 0x59, 0x10, 0x8b, 0xc1, 0xfc, 0xbd, - 0x75, 0xc9, 0x5e, 0x5c, 0xe2, 0x28, 0xb8, 0x72, 0xbc, 0xb3, 0x8a, 0x5e, - 0x82, 0x32, 0x50, 0xa3, 0xe0, 0x77, 0xf6, 0xe0, 0x46, 0xbe, 0xda, 0x52, - 0xa5, 0x13, 0xa5, 0x99, 0xcd, 0xc3, 0x55, 0x31, 0x83, 0x10, 0x72, 0xa3, - 0x2d, 0x14, 0x49, 0xda, 0x57, 0x81, 0xd7, 0x7f, 0xbd, 0x29, 0x6d, 0xb8, - 0x21, 0xe4, 0x4b, 0x58, 0x99, 0x74, 0x84, 0xef, 0x77, 0xd6, 0x92, 0xe0, - 0x81, 0xe1, 0xc0, 0x3c, 0x10, 0x81, 0xf9, 0xa9, 0xaa, 0x63, 0x74, 0x98, - 0x91, 0xa8, 0x72, 0x16, 0xa6, 0xf3, 0xf9, 0x89, 0xe4, 0xe6, 0x48, 0xac, - 0x50, 0x65, 0x11, 0x4c, 0xef, 0xfe, 0xcf, 0x89, 0xd3, 0x9f, 0xc1, 0xfc, - 0xdc, 0xea, 0x75, 0x19, 0xc7, 0xd0, 0x12, 0xaf, 0x20, 0x64, 0x82, 0x08, - 0x8e, 0xc8, 0x0f, 0x15, 0x51, 0x7b, 0xe2, 0x6b, 0xb0, 0x1c, 0xcd, 0xad, - 0xd1, 0x77, 0x2d, 0xad, 0xa0, 0xec, 0x81, 0xa7, 0xa8, 0x28, 0xcd, 0xb1, - 0xcc, 0xa5, 0x43, 0xc4, 0x5b, 0xb8, 0x9c, 0x84, 0xa5, 0x2c, 0xac, 0xba, - 0xc0, 0x2a, 0x61, 0xc7, 0xf1, 0xb6, 0x57, 0x56, 0xe5, 0xca, 0x96, 0xbb, - 0xfb, 0x8e, 0x49, 0x3e, 0x50, 0x2f, 0x36, 0x73, 0x5b, 0x44, 0x5b, 0x36, - 0x9c, 0xa0, 0x90, 0xc6, 0x96, 0x4e, 0x73, 0x1f, 0x68, 0x47, 0x43, 0xd3, - 0x6b, 0x1f, 0x4d, 0x43, 0x1e, 0xbf, 0x1c, 0x28, 0xe9, 0xf5, 0x3d, 0xac, - 0x48, 0x4c, 0xd4, 0x6d, 0x32, 0x25, 0xf3, 0x71, 0x29, 0xe9, 0xf0, 0x08, - 0x2a, 0xd2, 0x75, 0xc1, 0xa6, 0x5f, 0x1f, 0xca, 0xbb, 0x76, 0x91, 0xdc, - 0xca, 0x13, 0x3b, 0x18, 0xd9, 0x66, 0x48, 0xb0, 0x29, 0x01, 0x39, 0xfd, - 0x35, 0x8b, 0xd7, 0xac, 0xeb, 0xe3, 0x92, 0x96, 0xef, 0xe1, 0x7e, 0xd7, - 0xd0, 0xe9, 0xd6, 0xcf, 0xd7, 0x28, 0x58, 0x0a, 0x20, 0xcc, 0xc1, 0x8a, - 0x45, 0x45, 0xe0, 0x71, 0xca, 0x66, 0x75, 0xb0, 0x97, 0x89, 0x13, 0x7b, - 0xa3, 0x27, 0x5d, 0xce, 0x36, 0x58, 0xf6, 0x0a, 0x66, 0xf5, 0x83, 0xc8, - 0xef, 0x6e, 0x6f, 0x98, 0x79, 0x52, 0xd7, 0xd4, 0xa3, 0x3f, 0xda, 0x70, - 0xe2, 0x41, 0x10, 0x55, 0x20, 0x71, 0xb0, 0xd8, 0xd9, 0x14, 0x19, 0xc6, - 0x76, 0x0d, 0x45, 0x78, 0xb5, 0x70, 0x88, 0x65, 0x5a, 0x6b, 0xeb, 0x2f, - 0x28, 0x38, 0xf9, 0xbc, 0x28, 0xbe, 0xca, 0x44, 0x86, 0x4e, 0xd4, 0x29, - 0xc6, 0x16, 0xca, 0x3e, 0xb7, 0x33, 0x58, 0x04, 0x33, 0x7c, 0xac, 0xb5, - 0x9f, 0xf9, 0xfd, 0x6d, 0xb9, 0xff, 0x5a, 0x35, 0xa6, 0xd8, 0xa5, 0x28, - 0x30, 0xf5, 0x16, 0x95, 0xa9, 0x14, 0x65, 0x97, 0x56, 0x01, 0x4d, 0xf8, - 0x71, 0xc9, 0x93, 0xad, 0xac, 0x97, 0x1d, 0xab, 0x70, 0x21, 0x2d, 0xf3, - 0x26, 0x16, 0x66, 0xcb, 0xa2, 0x67, 0x56, 0x09, 0xd9, 0x9d, 0x9c, 0xec, - 0x37, 0x4d, 0x71, 0xbd, 0xef, 0xaf, 0x22, 0x78, 0xd9, 0x4c, 0xdd, 0xab, - 0x9a, 0x12, 0x28, 0x7d, 0xb4, 0xd4, 0x9c, 0x01, 0xf2, 0x85, 0x2f, 0xbc, - 0x58, 0x77, 0x85, 0x32, 0xdf, 0x4e, 0x79, 0x41, 0x41, 0xda, 0x6e, 0x9f, - 0x60, 0x09, 0x82, 0xf4, 0x50, 0x15, 0x68, 0x0f, 0xfd, 0x0b, 0x5b, 0x09, - 0x33, 0x98, 0x9c, 0x92, 0x1d, 0xc1, 0x38, 0xbe, 0xdc, 0x17, 0xbe, 0x88, - 0xa8, 0xa6, 0x88, 0xa2, 0x0f, 0x81, 0xcd, 0xb6, 0xde, 0x42, 0xc7, 0x7d, - 0x53, 0xc6, 0xab, 0xd3, 0x94, 0x9d, 0x2e, 0x79, 0x2f, 0x0b, 0x76, 0x63, - 0x36, 0xa5, 0x85, 0x7f, 0x94, 0x07, 0x53, 0xe7, 0xa8, 0x6a, 0x0d, 0xb1, - 0xda, 0x1f, 0xad, 0xb6, 0x5b, 0x13, 0xe7, 0x21, 0xcc, 0xe7, 0x29, 0x09, - 0x48, 0x1a, 0x19, 0x7e, 0x22, 0x1b, 0x1b, 0xe5, 0xf2, 0x1a, 0x08, 0x25, - 0x30, 0xca, 0xf1, 0xd6, 0x97, 0x56, 0x3a, 0xa7, 0x3f, 0x0b, 0xce, 0xaf, - 0xfc, 0x50, 0x24, 0x34, 0xab, 0xf0, 0x9c, 0x91, 0x12, 0xc0, 0x4f, 0xd5, - 0xed, 0xa4, 0xf4, 0xe4, 0x36, 0x54, 0x49, 0xed, 0x36, 0x61, 0x6d, 0xa4, - 0x1e, 0x63, 0x24, 0x3c, 0x40, 0xb0, 0xb2, 0x44, 0xe3, 0x6d, 0xf2, 0xa6, - 0x96, 0x97, 0xe9, 0x97, 0xd4, 0x76, 0x80, 0x0c, 0x6d, 0xa8, 0xb1, 0x39, - 0x48, 0x48, 0x7c, 0x1b, 0x46, 0x9e, 0x94, 0x7a, 0xbf, 0xfd, 0xc6, 0xff, - 0x72, 0xf0, 0x4d, 0x4b, 0x22, 0x46, 0x32, 0x8e, 0x51, 0x23, 0xe7, 0xb2, - 0xe7, 0xa7, 0x05, 0x38, 0xb9, 0x25, 0xcc, 0xe2, 0xbf, 0x08, 0xff, 0x77, - 0xf9, 0xb6, 0x37, 0xcd, 0x29, 0x47, 0xc3, 0x10, 0xe4, 0xc9, 0xd5, 0xaa, - 0x41, 0xe8, 0x6c, 0x6d, 0x17, 0xa2, 0x8a, 0x08, 0xcc, 0xde, 0xa3, 0xcb, - 0xeb, 0x66, 0x86, 0x2c, 0x0b, 0xd3, 0xeb, 0xb3, 0x4b, 0x9e, 0x64, 0x70, - 0xf3, 0xa2, 0x8e, 0x30, 0x14, 0x32, 0x09, 0xea, 0xbd, 0x57, 0x4b, 0x6b, - 0x1e, 0xa3, 0x12, 0x01, 0xc2, 0x46, 0x65, 0x23, 0xe9, 0xac, 0x21, 0xb2, - 0xba, 0x60, 0xef, 0x6e, 0xa8, 0x32, 0x16, 0x1b, 0x69, 0x41, 0x23, 0x93, - 0xfb, 0x48, 0x7a, 0xb3, 0xe2, 0xab, 0x9b, 0x1a, 0x44, 0xce, 0x8a, 0x35, - 0xfc, 0x87, 0x3e, 0xe4, 0xa5, 0xec, 0xcf, 0x98, 0x04, 0x32, 0xc2, 0x32, - 0x4b, 0x48, 0x96, 0xed, 0x6a, 0xd1, 0xca, 0x3a, 0xf0, 0xb9, 0x32, 0x14, - 0xe3, 0x11, 0x23, 0x87, 0x09, 0x49, 0x59, 0x20, 0x6b, 0x3a, 0xb7, 0xc5, - 0xa7, 0xb3, 0x86, 0xd1, 0x87, 0x0d, 0xcf, 0x04, 0x92, 0x2a, 0x87, 0xa4, - 0x36, 0xc9, 0x03, 0x3f, 0x05, 0x2f, 0x39, 0xad, 0xfb, 0xbb, 0x25, 0x0c, - 0xbe, 0x23, 0xe4, 0x18, 0x1c, 0x24, 0x71, 0xd1, 0x6c, 0xba, 0x6a, 0xba, - 0xa6, 0xa7, 0x93, 0x08, 0x43, 0x92, 0x13, 0xfa, 0x02, 0xe0, 0x0e, 0xf6, - 0x26, 0x20, 0x11, 0x5c, 0x4f, 0x54, 0xc0, 0xb2, 0x0b, 0x5e, 0x79, 0x41, - 0xd9, 0x03, 0xd8, 0x4f, 0xb4, 0x60, 0xf7, 0x2c, 0xbd, 0xd8, 0xcd, 0xdd, - 0x19, 0xee, 0x46, 0x5f, 0x44, 0x2b, 0x57, 0x3f, 0xe3, 0x6b, 0x41, 0x4b, - 0x63, 0x19, 0x2b, 0x69, 0xb3, 0xe4, 0x14, 0xe0, 0xfc, 0x70, 0x6f, 0xc5, - 0x9e, 0xe2, 0x56, 0xfe, 0x62, 0xc7, 0x2b, 0x68, 0x43, 0x34, 0xb0, 0xf8, - 0x71, 0xd9, 0x0e, 0xbd, 0x20, 0x29, 0x83, 0xf1, 0xfe, 0xed, 0xec, 0xd5, - 0xeb, 0x12, 0xc9, 0x13, 0x9d, 0x1f, 0xb4, 0xce, 0x39, 0xd8, 0x15, 0xa9, - 0x6c, 0x24, 0x8d, 0x6f, 0xc5, 0x0a, 0x0c, 0xa2, 0x7e, 0x29, 0x67, 0xf1, - 0x3a, 0xf8, 0xd6, 0xd0, 0x3b, 0x28, 0x30, 0x94, 0x0c, 0x28, 0x77, 0x06, - 0x79, 0x3f, 0xfc, 0x67, 0xf2, 0x76, 0x8b, 0xb5, 0xc0, 0x4a, 0x1a, 0x79, - 0x9c, 0x04, 0xef, 0xc1, 0x61, 0x0e, 0xe9, 0xe0, 0xf3, 0x4a, 0x03, 0x00, - 0xf1, 0x4a, 0xa6, 0x66, 0x51, 0x53, 0x76, 0x35, 0x72, 0xc7, 0x59, 0x4b, - 0x34, 0x34, 0xc9, 0x1d, 0x91, 0x21, 0x1a, 0x5f, 0xb6, 0x81, 0x9e, 0x7a, - 0x62, 0x4a, 0xb8, 0x54, 0xb7, 0xdf, 0xe7, 0xd7, 0xb0, 0x5f, 0xa8, 0x1c, - 0x93, 0xae, 0x94, 0x3d, 0x82, 0x83, 0xe7, 0x9c, 0x50, 0x79, 0xa5, 0x03, - 0xf2, 0x3f, 0x19, 0xd7, 0x3f, 0x5f, 0x33, 0xf1, 0x5b, 0x65, 0x03, 0x4d, - 0x40, 0x88, 0x66, 0x67, 0x3f, 0x16, 0x8e, 0x7c, 0x4f, 0xd6, 0x15, 0xb3, - 0x1d, 0xed, 0x86, 0xc7, 0x2b, 0x82, 0x4e, 0x4e, 0xc1, 0x9b, 0x25, 0xc1, - 0xf5, 0x3f, 0x6e, 0xde, 0xbd, 0x23, 0x44, 0xa1, 0xb4, 0x84, 0xfb, 0x0a, - 0x95, 0x59, 0x57, 0x60, 0x73, 0x54, 0xcf, 0x4d, 0x2d, 0x5d, 0x8d, 0xc3, - 0xc8, 0x2a, 0x98, 0x7d, 0xb2, 0x59, 0x94, 0xe6, 0x90, 0x43, 0xed, 0xa2, - 0xc2, 0x13, 0x33, 0xf5, 0xee, 0x21, 0x72, 0x82, 0xaa, 0x33, 0xfc, 0x92, - 0x15, 0xc1, 0xf6, 0xef, 0x7d, 0xdf, 0x25, 0x8a, 0xbe, 0x36, 0xe8, 0x69, - 0x91, 0x42, 0x93, 0x4f, 0x1d, 0xc4, 0x92, 0xa5, 0xf3, 0xc1, 0x5d, 0x3d, - 0x1b, 0x36, 0xd7, 0xc4, 0x35, 0x7d, 0xe5, 0x02, 0x5b, 0xca, 0x8f, 0xcc, - 0x0c, 0x86, 0x7b, 0x20, 0xbc, 0xc2, 0xc1, 0x6f, 0x5a, 0x7c, 0xfe, 0x66, - 0x6d, 0xeb, 0x5e, 0xa5, 0xba, 0xbe, 0x26, 0xd3, 0xda, 0xe8, 0x51, 0x26, - 0x57, 0xac, 0xcf, 0x3f, 0x86, 0x1d, 0x38, 0x71, 0xa4, 0x35, 0x70, 0xe9, - 0x50, 0x02, 0x72, 0xc2, 0x22, 0x79, 0x78, 0xeb, 0x7d, 0xcf, 0xc7, 0x87, - 0xbc, 0x7e, 0xc7, 0x1c, 0x8d, 0x13, 0x44, 0xf3, 0xd0, 0x8a, 0x25, 0xf6, - 0xf7, 0x3c, 0xd9, 0x6f, 0xf2, 0x37, 0x9e, 0xad, 0x33, 0x43, 0x86, 0x40, - 0x4e, 0x90, 0x92, 0x33, 0x8c, 0x49, 0x90, 0x26, 0xf5, 0x25, 0x7d, 0xfe, - 0xf7, 0x16, 0x7e, 0x57, 0xef, 0xde, 0x6f, 0x2f, 0x93, 0xbe, 0x57, 0xda, - 0xae, 0x04, 0x35, 0x40, 0xcc, 0x4d, 0x72, 0x03, 0x2b, 0xb8, 0x1a, 0xfb, - 0xda, 0x1b, 0xb6, 0xff, 0x86, 0x6b, 0x76, 0xa6, 0xee, 0x71, 0xdd, 0xe8, - 0x10, 0xd8, 0x00, 0x94, 0x00, 0xa4, 0x6b, 0x00, 0x46, 0xd3, 0x8d, 0x16, - 0x64, 0x4c, 0x21, 0xd5, 0xc0, 0xca, 0x64, 0x44, 0xd2, 0xe6, 0xee, 0x4f, - 0xc4, 0xfa, 0x35, 0x45, 0x64, 0xc5, 0x51, 0xa8, 0x7c, 0x14, 0x77, 0xeb, - 0x97, 0x87, 0x0b, 0xae, 0x1d, 0x9c, 0x6e, 0x0d, 0xba, 0xb8, 0xa8, 0x8c, - 0xc8, 0x97, 0xd7, 0xb5, 0x43, 0xf3, 0x6b, 0x2d, 0x86, 0xdd, 0x01, 0xf6, - 0x07, 0xde, 0x7d, 0x7f, 0xb7, 0x3c, 0xe2, 0x30, 0x6b, 0x98, 0x99, 0xce, - 0xa6, 0xcb, 0x18, 0xa4, 0xa7, 0x3b, 0xc9, 0x62, 0xb9, 0x61, 0x3c, 0x87, - 0xe0, 0x7f, 0x85, 0x0f, 0xda, 0x1f, 0x83, 0x76, 0x6e, 0x9c, 0x53, 0x95, - 0x0c, 0x75, 0xe3, 0xc2, 0x90, 0x91, 0x96, 0x54, 0x87, 0x70, 0xcf, 0xb6, - 0x84, 0xe2, 0xbe, 0x31, 0xe5, 0x4a, 0x79, 0x00, 0x4a, 0x25, 0x06, 0x54, - 0x19, 0x39, 0x4d, 0x14, 0x28, 0xfd, 0x71, 0x91, 0xa2, 0x69, 0xee, 0x2b, - 0xa2, 0x88, 0x97, 0x37, 0x4f, 0x3e, 0xfa, 0xb7, 0x2a, 0x41, 0x55, 0x10, - 0xdf, 0xc4, 0x24, 0xfc, 0xde, 0xa9, 0x45, 0x74, 0xb5, 0xb9, 0xee, 0xef, - 0xd7, 0xb3, 0x8d, 0xc3, 0x41, 0x0c, 0xe8, 0x23, 0x5e, 0x41, 0x29, 0x83, - 0x23, 0x90, 0xc9, 0xf1, 0x54, 0x0e, 0xb8, 0xbf, 0x95, 0x5a, 0x28, 0x2c, - 0x5d, 0xd2, 0xd6, 0x50, 0x60, 0x5b, 0x1d, 0xbe, 0x64, 0x4d, 0x10, 0x28, - 0x92, 0x87, 0x88, 0x7d, 0x3f, 0x8d, 0xaf, 0xfc, 0x0f, 0x0c, 0x00, 0xa3, - 0x29, 0xd2, 0x10, 0x8b, 0xd9, 0x14, 0xb8, 0x3b, 0x81, 0x76, 0x64, 0xc2, - 0x97, 0xbe, 0x6f, 0x92, 0x61, 0x8b, 0xb7, 0x05, 0xbd, 0x3e, 0x6d, 0x54, - 0x50, 0x0c, 0x87, 0x95, 0x97, 0xf4, 0x49, 0x2d, 0x06, 0xac, 0xb8, 0xa9, - 0x31, 0xd3, 0x76, 0x92, 0x4a, 0xa3, 0xd9, 0x1f, 0xf4, 0x08, 0xd9, 0x29, - 0x49, 0xa9, 0xe3, 0x65, 0xee, 0x68, 0x60, 0x12, 0x97, 0xcc, 0xfc, 0xe1, - 0x5d, 0x26, 0xcc, 0xbe, 0xa8, 0x4e, 0xdd, 0x9a, 0x28, 0x21, 0xc3, 0x41, - 0x2f, 0x8a, 0x4e, 0x60, 0xb7, 0x03, 0x8c, 0x1f, 0x6f, 0x05, 0x5e, 0x99, - 0x73, 0x33, 0x43, 0xd2, 0xe7, 0x22, 0x75, 0xbc, 0x98, 0xe0, 0x34, 0x7e, - 0x2c, 0xb0, 0x0f, 0xa9, 0xee, 0xbc, 0x82, 0xa8, 0x1d, 0xa0, 0xd0, 0x95, - 0x5e, 0xa1, 0x33, 0x95, 0xf4, 0xdb, 0xe0, 0xf5, 0x3c, 0x1c, 0xa4, 0x5e, - 0x12, 0x08, 0x40, 0x7c, 0xc6, 0x12, 0x22, 0xb3, 0x6d, 0x81, 0xa2, 0x88, - 0xac, 0x97, 0x6f, 0x2a, 0xc9, 0xd6, 0xde, 0x6b, 0xb6, 0x02, 0x58, 0x18, - 0x40, 0xc7, 0x92, 0x06, 0x63, 0x26, 0x11, 0x98, 0xf1, 0x05, 0x50, 0x73, - 0x37, 0x4c, 0xcf, 0x8e, 0x77, 0xe6, 0x0f, 0x6e, 0x4f, 0x36, 0x5e, 0x7a, - 0x94, 0xd1, 0x13, 0xa5, 0xb1, 0x22, 0x0c, 0x20, 0xa1, 0x97, 0x8c, 0x7e, - 0xcb, 0xf9, 0xfa, 0x17, 0x4a, 0x4a, 0x40, 0x5e, 0xef, 0xe6, 0x48, 0x6c, - 0x3b, 0x18, 0xca, 0x2c, 0x67, 0x91, 0x09, 0x85, 0x6a, 0xcd, 0xdd, 0xdb, - 0xdb, 0x82, 0x07, 0xa7, 0x57, 0xa2, 0x42, 0x84, 0xf8, 0xe7, 0xd2, 0xbe, - 0x8b, 0x80, 0xe4, 0xda, 0x07, 0x4e, 0xcc, 0x11, 0xc9, 0xf6, 0x5f, 0x5e, - 0x22, 0xcd, 0xf3, 0x82, 0xa9, 0x6d, 0x7a, 0xc4, 0x26, 0x70, 0xec, 0x1d, - 0x6a, 0x79, 0x7f, 0x37, 0x28, 0x88, 0x1a, 0x53, 0x84, 0xf8, 0x00, 0xad, - 0x47, 0x7b, 0xfe, 0x19, 0xc9, 0xac, 0xab, 0x55, 0x76, 0xde, 0x4b, 0x6d, - 0x6f, 0x2e, 0x77, 0xca, 0xd7, 0x4e, 0x73, 0x18, 0xcd, 0xc3, 0x41, 0xac, - 0x39, 0x9a, 0x22, 0xac, 0xbf, 0xd2, 0xc0, 0xec, 0x4c, 0x54, 0xfb, 0xb9, - 0x76, 0x39, 0xd4, 0xcf, 0x63, 0xd6, 0xd6, 0x3c, 0xfe, 0x6f, 0xc0, 0x22, - 0xc0, 0x14, 0x36, 0xb8, 0x02, 0x19, 0x1e, 0x6a, 0x8b, 0xa3, 0x39, 0x78, - 0x1a, 0x82, 0x9e, 0x78, 0xf6, 0x58, 0xdb, 0x2e, 0x0a, 0x70, 0xc3, 0xa7, - 0x45, 0x41, 0x19, 0x8d, 0xca, 0x91, 0xed, 0x28, 0x12, 0x8c, 0xbb, 0x91, - 0xbd, 0xb3, 0xf0, 0x6a, 0xff, 0x79, 0x7f, 0xdf, 0xbc, 0x03, 0x6c, 0x4f, - 0x05, 0xe1, 0xaf, 0x39, 0x14, 0x37, 0x08, 0xbd, 0xd8, 0xa5, 0x3a, 0x0d, - 0xe2, 0x65, 0xdd, 0x9f, 0x80, 0x0c, 0xca, 0xd2, 0x19, 0x36, 0x1d, 0x84, - 0xfa, 0xa0, 0xa7, 0xb3, 0x26, 0x14, 0x4e, 0x53, 0xb5, 0x98, 0x15, 0x7b, - 0x53, 0x55, 0xc7, 0x55, 0x59, 0x65, 0xf7, 0xf9, 0xb5, 0x6b, 0x96, 0x59, - 0x7d, 0xb6, 0xf2, 0xab, 0x6f, 0x4e, 0x48, 0xa1, 0x30, 0x18, 0x01, 0x2a, - 0x3e, 0x20, 0x3a, 0xc6, 0x6d, 0x2a, 0x23, 0x0d, 0x17, 0x3d, 0x66, 0x30, - 0xe5, 0xe5, 0xac, 0x86, 0x84, 0x08, 0x01, 0x7a, 0xcc, 0xed, 0xf9, 0xfa, - 0x83, 0xcf, 0x09, 0x95, 0xdf, 0xf8, 0xed, 0x8c, 0x12, 0x7d, 0xf0, 0xcc, - 0x3e, 0x35, 0xfe, 0x10, 0x50, 0xed, 0x35, 0xcc, 0x8a, 0x13, 0x18, 0x67, - 0x22, 0x79, 0x04, 0xd8, 0x43, 0xd2, 0x38, 0xb3, 0xe8, 0x4c, 0x57, 0x6b, - 0xab, 0xfa, 0x95, 0x4e, 0x2c, 0x5e, 0x14, 0x0e, 0x7e, 0x06, 0xd6, 0x7d, - 0xcd, 0xe9, 0xb7, 0xbb, 0x8b, 0x76, 0x35, 0xe5, 0xf1, 0x87, 0x6c, 0x92, - 0x2c, 0x44, 0x8e, 0x59, 0xa3, 0x84, 0x27, 0x55, 0xaa, 0xe7, 0x8a, 0xda, - 0x3a, 0x08, 0xa3, 0x3c, 0x94, 0x69, 0x07, 0x98, 0xf9, 0x33, 0x0a, 0xe8, - 0xfe, 0xfd, 0x7e, 0x55, 0x0c, 0x5b, 0x81, 0xba, 0x56, 0xb4, 0x86, 0xd9, - 0xca, 0x80, 0xc8, 0x12, 0xe8, 0x83, 0x8d, 0x51, 0x04, 0xb9, 0xcf, 0xe8, - 0x0f, 0x34, 0x97, 0xe7, 0x3b, 0xab, 0xaf, 0x85, 0x7f, 0x6f, 0x38, 0x1e, - 0x7b, 0xd8, 0x54, 0x31, 0xa7, 0x82, 0x4f, 0x2c, 0xa0, 0xff, 0x18, 0x73, - 0x8f, 0xbc, 0x57, 0xfe, 0x8f, 0x7f, 0xe5, 0x34, 0xfa, 0x16, 0x59, 0xa5, - 0x36, 0x3c, 0x01, 0x22, 0x89, 0x33, 0x99, 0x73, 0x93, 0xf1, 0x6b, 0x99, - 0xe3, 0xaa, 0xab, 0xf0, 0x37, 0x21, 0x09, 0xb2, 0x5d, 0x5a, 0x61, 0x89, - 0xb9, 0x62, 0xaf, 0x90, 0x3f, 0x8a, 0x42, 0x9d, 0x6b, 0x41, 0x86, 0x00, - 0x51, 0x78, 0x28, 0x41, 0x37, 0x35, 0x84, 0x73, 0xc6, 0x1e, 0x42, 0x52, - 0x91, 0x4a, 0x93, 0xce, 0x78, 0x0a, 0x08, 0x51, 0xec, 0x92, 0x15, 0x48, - 0x58, 0xe4, 0x94, 0x48, 0xbb, 0x8b, 0xd7, 0xf6, 0x5b, 0xac, 0x69, 0x5f, - 0x9a, 0x9d, 0x6c, 0xd9, 0x8e, 0xef, 0xb0, 0x71, 0xf8, 0x1a, 0xc4, 0xa8, - 0x90, 0x93, 0xec, 0x1a, 0x66, 0xbd, 0x29, 0x0f, 0xa9, 0xce, 0xf1, 0x65, - 0xb2, 0xc7, 0xb4, 0x4a, 0x92, 0x3d, 0x94, 0xcb, 0xae, 0x15, 0xc8, 0x99, - 0x44, 0x6d, 0x82, 0x00, 0x89, 0x20, 0x96, 0x97, 0x38, 0xd0, 0x5b, 0x8e, - 0xfa, 0x6d, 0x6a, 0x40, 0xa0, 0x72, 0xb2, 0x92, 0x27, 0xb5, 0xbc, 0x34, - 0x50, 0xfa, 0x5f, 0x1a, 0xfa, 0xe5, 0xdd, 0x75, 0x76, 0xb7, 0x7c, 0x19, - 0xbb, 0xe2, 0x89, 0x31, 0xab, 0xc9, 0x59, 0x72, 0x19, 0x7f, 0x3e, 0x60, - 0x9c, 0x8d, 0x4d, 0xdf, 0x90, 0xea, 0xcb, 0x65, 0xca, 0x03, 0x96, 0x59, - 0x22, 0x32, 0x8c, 0xfc, 0x0c, 0x97, 0x1f, 0x39, 0x75, 0xff, 0xd1, 0x79, - 0x9b, 0xce, 0x89, 0xd2, 0xe5, 0x8d, 0x04, 0xf0, 0xe2, 0x59, 0x48, 0xd0, - 0xf9, 0xc3, 0xbe, 0xee, 0x58, 0x06, 0xb7, 0xe6, 0xd1, 0x80, 0x6b, 0x13, - 0xb4, 0x41, 0x11, 0x06, 0x51, 0x8c, 0x66, 0xf9, 0x7e, 0x34, 0x07, 0xc1, - 0x4f, 0xfe, 0x9b, 0x31, 0xdf, 0x1e, 0x62, 0x44, 0xe7, 0x26, 0xc6, 0xa2, - 0x28, 0x25, 0x22, 0x28, 0xf8, 0x8d, 0xad, 0x27, 0x0b, 0xc7, 0x78, 0x01, - 0x82, 0x8c, 0x15, 0xe7, 0x96, 0x55, 0x1c, 0x63, 0xf1, 0xcc, 0x5d, 0xba, - 0x89, 0xbf, 0x1a, 0xd9, 0x98, 0xaf, 0xa1, 0x87, 0x6c, 0x8c, 0x86, 0xf4, - 0x4f, 0xc7, 0xf3, 0x13, 0x7c, 0x94, 0x5d, 0x95, 0x46, 0xbf, 0xad, 0x0d, - 0x9d, 0x3c, 0xe8, 0x12, 0x88, 0x99, 0x92, 0x5a, 0x15, 0x62, 0x50, 0xdb, - 0x67, 0x7a, 0xf3, 0x53, 0x6d, 0x5a, 0xd2, 0x12, 0x2f, 0x2e, 0xd0, 0x50, - 0x22, 0x8c, 0x3f, 0x3b, 0x45, 0x54, 0x5c, 0x54, 0x35, 0xe7, 0xb3, 0x78, - 0xf5, 0x10, 0x53, 0x38, 0xd8, 0xa1, 0x5f, 0x28, 0xe4, 0xc1, 0xf0, 0x66, - 0x54, 0x56, 0xdb, 0xed, 0xff, 0xd3, 0x60, 0x08, 0x41, 0xb5, 0xa0, 0x41, - 0x8c, 0x51, 0x96, 0x60, 0x0e, 0x3a, 0x5a, 0xf0, 0x13, 0xbc, 0x49, 0xd5, - 0xf9, 0xd7, 0xcf, 0xcc, 0x04, 0x20, 0x97, 0x64, 0x1a, 0xe6, 0x36, 0x03, - 0xa1, 0x4b, 0xaf, 0x34, 0x1d, 0x06, 0x31, 0x80, 0x8c, 0x0a, 0x5c, 0xf0, - 0x93, 0x03, 0xde, 0xb3, 0xd9, 0xca, 0xda, 0x9e, 0xd8, 0x99, 0xce, 0x9b, - 0xef, 0x72, 0x29, 0x72, 0x79, 0xfc, 0x5f, 0x01, 0xd7, 0x36, 0x93, 0x03, - 0xda, 0xcf, 0xd3, 0x2f, 0xa0, 0xad, 0xb4, 0x3f, 0xc7, 0x30, 0x92, 0xf0, - 0x3b, 0x49, 0x5d, 0xa2, 0x5c, 0xd2, 0x39, 0x45, 0x2f, 0xe8, 0xad, 0xfc, - 0xa6, 0x3f, 0xed, 0x61, 0x3d, 0x0a, 0x24, 0x1c, 0x02, 0x78, 0x41, 0xda, - 0xff, 0x02, 0xaa, 0xcf, 0xb1, 0xf3, 0xa3, 0xae, 0x72, 0xff, 0xe2, 0x83, - 0xfa, 0x92, 0xf6, 0xe3, 0x45, 0x8a, 0xcb, 0x10, 0x74, 0x19, 0xdc, 0x97, - 0x8d, 0x02, 0x75, 0x17, 0x0b, 0x05, 0x2f, 0x59, 0x62, 0x48, 0x61, 0xca, - 0x18, 0x07, 0x65, 0x11, 0x8e, 0x63, 0xde, 0xd2, 0xaf, 0xb6, 0x66, 0xaf, - 0xd1, 0x1f, 0xaf, 0x63, 0xe4, 0xc3, 0x50, 0xf1, 0xd0, 0x04, 0xc6, 0x3b, - 0x66, 0xc9, 0xd6, 0x25, 0xe2, 0xe7, 0xfa, 0xdf, 0xca, 0x26, 0xde, 0x2f, - 0xdc, 0xf9, 0x33, 0x13, 0x72, 0xa8, 0x9e, 0x6c, 0x18, 0x09, 0xc1, 0x39, - 0x1a, 0x6e, 0x81, 0x80, 0x4f, 0x2c, 0xde, 0xb3, 0xae, 0xf2, 0xf6, 0xbe, - 0xa5, 0xed, 0x7d, 0x66, 0xac, 0xd0, 0x63, 0xba, 0x74, 0x9a, 0x4e, 0xe7, - 0x18, 0x71, 0x4d, 0xf0, 0xfb, 0x72, 0x49, 0x13, 0x72, 0x6b, 0x00, 0xf3, - 0x6e, 0xc8, 0x76, 0x3a, 0xf2, 0xba, 0x5b, 0xf8, 0xd8, 0x70, 0x8a, 0x1a, - 0x16, 0x7e, 0x43, 0x41, 0xde, 0x02, 0x50, 0x23, 0x70, 0xa5, 0x90, 0x2b, - 0x22, 0x97, 0xc1, 0xf2, 0xb9, 0xe9, 0xa9, 0x43, 0xb0, 0x43, 0xf9, 0x37, - 0x8c, 0x6a, 0x86, 0x49, 0x13, 0xca, 0x03, 0xc1, 0x32, 0x68, 0x1d, 0xd3, - 0x2e, 0x9b, 0x6f, 0x51, 0xb8, 0x46, 0x19, 0x51, 0x34, 0x64, 0xd0, 0x62, - 0x23, 0xf1, 0x7c, 0x46, 0x60, 0xdf, 0xca, 0xd6, 0x6a, 0xf3, 0x9e, 0x20, - 0x00, 0xd1, 0x94, 0xa8, 0x04, 0xb0, 0xf0, 0x41, 0xf3, 0xd6, 0xad, 0xb3, - 0x8a, 0x30, 0xb3, 0x4a, 0x53, 0x11, 0x8d, 0x1b, 0xd0, 0x0f, 0xc5, 0x97, - 0xd0, 0x20, 0x4f, 0x4b, 0x36, 0xe2, 0x06, 0x14, 0xd9, 0xa0, 0x18, 0x78, - 0x05, 0x02, 0x23, 0x09, 0xcf, 0xe3, 0xfa, 0x0a, 0x66, 0x71, 0xf6, 0xe0, - 0xf1, 0xc0, 0xc5, 0xa0, 0xa7, 0xff, 0xb5, 0xca, 0x89, 0x2d, 0x3c, 0x67, - 0x3f, 0x37, 0x80, 0xce, 0x59, 0x5f, 0x3f, 0xa8, 0x4b, 0xa6, 0xcd, 0x0a, - 0x65, 0x1a, 0x25, 0x13, 0x18, 0x5e, 0xb2, 0x7b, 0x9f, 0x35, 0xc6, 0xc6, - 0x45, 0x7b, 0x3b, 0x32, 0x8c, 0x04, 0xcc, 0x85, 0xe8, 0x68, 0xd2, 0x62, - 0xed, 0xe7, 0x57, 0x18, 0xad, 0xda, 0xe1, 0xd9, 0x89, 0x09, 0x1f, 0x06, - 0x79, 0x5e, 0x82, 0xcd, 0x80, 0x61, 0xb1, 0x0b, 0x8a, 0x24, 0x09, 0xc1, - 0xe9, 0x4a, 0xac, 0x8d, 0xe7, 0x55, 0xcc, 0x55, 0x07, 0x7d, 0xdb, 0xbd, - 0x8b, 0x29, 0x4e, 0x78, 0xfb, 0x46, 0x64, 0x94, 0xaf, 0xa1, 0x19, 0x6f, - 0xcd, 0xbe, 0x72, 0x60, 0xe3, 0x55, 0xe1, 0xa5, 0x61, 0x83, 0xbb, 0xce, - 0x8c, 0x62, 0xe3, 0x2e, 0x84, 0x1f, 0x3c, 0xdc, 0x03, 0xf4, 0x41, 0xab, - 0x68, 0x63, 0xe3, 0x94, 0x8e, 0x1c, 0xe4, 0x80, 0xc6, 0xfb, 0x10, 0xb9, - 0xaf, 0xee, 0xcd, 0xfe, 0xfa, 0x9c, 0x18, 0xd8, 0xbc, 0xd6, 0xe0, 0xa8, - 0xe1, 0xfe, 0x78, 0x82, 0x0e, 0xd7, 0x0e, 0x80, 0xc9, 0x1f, 0x11, 0x5e, - 0x57, 0x35, 0x41, 0xdb, 0x6c, 0x39, 0xdb, 0xda, 0xfc, 0xb3, 0x12, 0x26, - 0x05, 0x9a, 0x01, 0xd4, 0x86, 0x4e, 0x60, 0x6a, 0x69, 0x72, 0xf1, 0x15, - 0x9f, 0x63, 0xaf, 0x9b, 0xe7, 0x1c, 0xbc, 0x33, 0xde, 0x3b, 0x6a, 0x74, - 0x8a, 0x9e, 0x74, 0x5c, 0xa0, 0x64, 0xc3, 0x01, 0xf1, 0x04, 0xef, 0xaf, - 0x45, 0x52, 0x5b, 0xed, 0xb2, 0xf8, 0x80, 0xb9, 0xc6, 0x04, 0x40, 0x1e, - 0x0b, 0xd0, 0x0f, 0xcf, 0x73, 0x2a, 0x65, 0xd2, 0xee, 0xcc, 0xdb, 0xe6, - 0xe8, 0x84, 0xff, 0xda, 0xb1, 0x25, 0x3a, 0x14, 0x94, 0x67, 0x0e, 0x03, - 0xdc, 0x93, 0xfe, 0x50, 0x19, 0x60, 0x61, 0xa5, 0xf3, 0xd2, 0x2d, 0x8e, - 0x6b, 0xa2, 0xc5, 0x63, 0xa9, 0x99, 0x8e, 0xe7, 0x21, 0x5e, 0x08, 0x4c, - 0xe5, 0x22, 0x66, 0x88, 0xc0, 0x7c, 0x0e, 0x5d, 0x97, 0xb2, 0x15, 0x30, - 0xd5, 0xee, 0xd4, 0x25, 0x22, 0x82, 0x28, 0x64, 0xc9, 0x96, 0x12, 0x46, - 0x53, 0xcb, 0xa1, 0xb7, 0x38, 0xe2, 0x8e, 0x52, 0x5a, 0x03, 0x1e, 0xf4, - 0x4a, 0xb2, 0x8e, 0x77, 0xfa, 0x6b, 0xe6, 0x8c, 0x12, 0xc3, 0x4d, 0x12, - 0x87, 0xc1, 0x78, 0x29, 0xfa, 0x86, 0xd9, 0xe0, 0xbc, 0x10, 0x87, 0xc6, - 0x42, 0x13, 0x8d, 0x19, 0x0f, 0x02, 0x4f, 0x56, 0xac, 0xb3, 0xce, 0x6a, - 0x84, 0xb9, 0x39, 0x59, 0x26, 0x23, 0xe0, 0xcf, 0x72, 0x2e, 0xb9, 0xa2, - 0xda, 0x32, 0x18, 0x77, 0x12, 0xc9, 0xc1, 0x95, 0x80, 0x93, 0x93, 0xac, - 0x2d, 0xdf, 0x4c, 0xc2, 0x53, 0x0d, 0xa3, 0x2c, 0xac, 0x3e, 0xfe, 0x72, - 0xdb, 0xf6, 0x20, 0x80, 0x21, 0xbd, 0x98, 0x71, 0x5d, 0x21, 0xf3, 0x45, - 0x64, 0x71, 0x0b, 0xb0, 0x33, 0x40, 0xa3, 0x33, 0x57, 0xe5, 0x96, 0x87, - 0xc4, 0xec, 0x80, 0x90, 0x1d, 0xfb, 0x31, 0x73, 0x5d, 0x7f, 0x70, 0xb3, - 0x61, 0xa4, 0x8b, 0x3c, 0xc8, 0x44, 0x4d, 0x09, 0xb2, 0x32, 0x74, 0x3e, - 0xa0, 0xaf, 0xd7, 0x66, 0xe8, 0xd0, 0xb1, 0xc3, 0xa8, 0x81, 0xbc, 0x70, - 0xe8, 0x6e, 0x68, 0x89, 0x14, 0xaf, 0x8f, 0x4b, 0x60, 0xae, 0x6a, 0xcd, - 0xa8, 0xbc, 0xd7, 0xbd, 0x35, 0x15, 0xbc, 0xcb, 0x9c, 0x84, 0x27, 0x86, - 0x69, 0xe5, 0x09, 0x21, 0xf6, 0xa4, 0xd9, 0xaf, 0x33, 0x48, 0x84, 0x93, - 0x91, 0x24, 0x96, 0xe5, 0x4c, 0x78, 0xee, 0xec, 0x79, 0x5b, 0x0a, 0x3c, - 0xa8, 0x62, 0xe9, 0xa9, 0x68, 0x21, 0x2c, 0x6a, 0x48, 0x4a, 0x17, 0x19, - 0x60, 0x65, 0xa5, 0x0c, 0x97, 0xd4, 0xc9, 0xde, 0x56, 0xe9, 0xf0, 0xf7, - 0x56, 0x57, 0x6c, 0x8e, 0x3e, 0xf6, 0x52, 0xe1, 0x86, 0x42, 0x80, 0x01, - 0x80, 0xa1, 0x28, 0x64, 0x32, 0x8f, 0x80, 0xf3, 0x7d, 0xa2, 0x97, 0x84, - 0x82, 0xe7, 0x91, 0x41, 0x92, 0x08, 0xe6, 0x02, 0x69, 0x37, 0xfe, 0xcd, - 0xa2, 0x85, 0xfa, 0xb7, 0x64, 0xab, 0x78, 0x95, 0xb4, 0x85, 0x44, 0x28, - 0xa5, 0xe5, 0xb8, 0xc0, 0x11, 0xac, 0x21, 0x5a, 0xd3, 0x98, 0x5e, 0x8a, - 0x08, 0x60, 0x14, 0x0d, 0x53, 0xde, 0xce, 0x06, 0xd4, 0x37, 0xb1, 0x22, - 0xe2, 0x68, 0x34, 0xc7, 0xc5, 0xa3, 0xf5, 0x1b, 0xce, 0xed, 0x45, 0x24, - 0xd9, 0x4a, 0x08, 0xdd, 0x65, 0x07, 0x8b, 0xbf, 0x81, 0xda, 0x3b, 0x31, - 0xdc, 0xb1, 0x7b, 0x3d, 0x8a, 0xb4, 0x74, 0x6e, 0xc8, 0xd4, 0x46, 0xd9, - 0xb6, 0x97, 0x45, 0x3b, 0xa0, 0x24, 0x88, 0xc3, 0xc4, 0x1d, 0x58, 0xa5, - 0xa7, 0xf0, 0x7c, 0xae, 0xd6, 0x77, 0x47, 0x7c, 0xe2, 0xb0, 0x18, 0xef, - 0x2c, 0x35, 0x82, 0x8c, 0x89, 0x93, 0x76, 0x40, 0x52, 0xbc, 0xf1, 0xf9, - 0x7f, 0x77, 0x03, 0x74, 0xdc, 0x12, 0xfd, 0x74, 0x2e, 0x16, 0xe6, 0x19, - 0xd5, 0xe0, 0x8b, 0x06, 0x4b, 0x99, 0x1f, 0x68, 0x3c, 0xd1, 0xbe, 0xe8, - 0x9c, 0xf7, 0xb5, 0x9d, 0x17, 0x1f, 0xaf, 0x47, 0xc5, 0x38, 0x92, 0x2c, - 0x1b, 0x54, 0x6f, 0x2b, 0x1d, 0x09, 0xeb, 0x4d, 0x89, 0x8e, 0x32, 0xe7, - 0x59, 0x84, 0x91, 0xfd, 0x57, 0xd9, 0x79, 0x4f, 0x8a, 0xdb, 0xc3, 0x3a, - 0x09, 0xe0, 0x07, 0x36, 0xdd, 0x93, 0x94, 0x1e, 0x69, 0x6b, 0xe1, 0x31, - 0xae, 0x72, 0xed, 0x66, 0x80, 0x06, 0x1b, 0x4a, 0x45, 0xdc, 0xbc, 0xdc, - 0x93, 0x44, 0xce, 0xf4, 0x01, 0xdc, 0x08, 0x73, 0x02, 0x32, 0xa3, 0xf0, - 0x61, 0x9a, 0x50, 0x04, 0x3b, 0x28, 0xb3, 0x9a, 0xbf, 0xe7, 0x5c, 0x5a, - 0x99, 0x4b, 0xf7, 0xff, 0x3b, 0x76, 0x7b, 0x7a, 0xcc, 0xcd, 0x49, 0xdf, - 0x49, 0x48, 0xcc, 0x99, 0x34, 0x14, 0x07, 0xda, 0x06, 0xfb, 0x9d, 0x97, - 0xc4, 0xd9, 0x2e, 0x25, 0x34, 0x63, 0x0c, 0x97, 0xce, 0xfa, 0x3b, 0xcf, - 0x87, 0x18, 0xdd, 0xf7, 0x3f, 0x8b, 0xe1, 0x00, 0xcb, 0x61, 0x03, 0x2c, - 0x38, 0xbc, 0x31, 0xdc, 0x80, 0xc4, 0x3f, 0xd5, 0x8c, 0x64, 0xe1, 0x09, - 0x4e, 0x86, 0x59, 0xec, 0x85, 0x55, 0xf0, 0x3a, 0xa7, 0xae, 0xae, 0x02, - 0xd1, 0x9c, 0x00, 0xc9, 0x20, 0x3e, 0x3c, 0x3f, 0x6e, 0x2e, 0xd9, 0x64, - 0xb9, 0x0c, 0x82, 0x32, 0x81, 0xe7, 0x46, 0xf5, 0x72, 0xb5, 0x70, 0x5c, - 0x4c, 0xaf, 0xda, 0xfc, 0x29, 0x07, 0x12, 0x3b, 0x09, 0xde, 0xd3, 0x29, - 0x06, 0xa0, 0x66, 0x94, 0x72, 0xbe, 0xa0, 0x3f, 0xc3, 0xef, 0x4f, 0xf2, - 0x77, 0x21, 0x37, 0x58, 0xd9, 0x62, 0x25, 0x08, 0x41, 0xf4, 0x47, 0xc4, - 0xcb, 0xcb, 0xac, 0x63, 0x14, 0x12, 0xb6, 0xe8, 0xfa, 0xb7, 0x12, 0x6d, - 0x41, 0xd1, 0x1c, 0x8c, 0x3b, 0x3d, 0x10, 0x20, 0xcb, 0xcb, 0x9c, 0xab, - 0x1a, 0x27, 0xe1, 0x71, 0xce, 0x95, 0x67, 0x02, 0xe4, 0x8b, 0x90, 0xe2, - 0x13, 0xb3, 0xb3, 0x0d, 0x33, 0xb3, 0xb3, 0x96, 0x7e, 0xb3, 0xb6, 0x89, - 0x44, 0x94, 0x0a, 0x0c, 0xc0, 0xd6, 0xc3, 0xe9, 0x14, 0x19, 0x0a, 0xfb, - 0xd0, 0x9d, 0x0a, 0x39, 0x61, 0xbe, 0xbb, 0x5f, 0xa4, 0xd4, 0xf8, 0xc4, - 0x7c, 0x91, 0x18, 0xe8, 0x84, 0x46, 0x1f, 0x25, 0x29, 0x9c, 0xbb, 0xd4, - 0x41, 0x9e, 0xdb, 0x04, 0x3b, 0xef, 0x46, 0x72, 0xc6, 0xdb, 0x40, 0x25, - 0x92, 0x7c, 0x34, 0x68, 0x2b, 0x43, 0xbd, 0x4b, 0xfd, 0x8c, 0x51, 0xa2, - 0xcd, 0x91, 0x3e, 0x7b, 0xfe, 0x67, 0xb7, 0x93, 0x5b, 0x62, 0x43, 0x25, - 0x7f, 0xd2, 0x98, 0xd5, 0xfd, 0x63, 0x21, 0x2a, 0x18, 0x0d, 0x0a, 0x3d, - 0xc6, 0x78, 0xe5, 0xd2, 0x92, 0xb1, 0x2a, 0x11, 0xd0, 0x9b, 0xa0, 0x4a, - 0x54, 0x1a, 0x68, 0x04, 0xca, 0x18, 0x7a, 0xc0, 0x4b, 0xeb, 0x76, 0xc9, - 0x81, 0x8e, 0x32, 0xb4, 0x5b, 0x50, 0xa0, 0x94, 0xe6, 0x80, 0xc9, 0x19, - 0xf8, 0x26, 0x57, 0xef, 0xf7, 0x29, 0x71, 0x17, 0xfb, 0xeb, 0x85, 0xa8, - 0xa8, 0x41, 0x5b, 0x26, 0x48, 0x51, 0x83, 0x4c, 0x89, 0x1b, 0xa1, 0x8e, - 0x91, 0xf1, 0xe9, 0x8c, 0xff, 0xba, 0xee, 0xd7, 0x6b, 0x0f, 0xf5, 0x39, - 0x60, 0x69, 0xda, 0xbc, 0x76, 0xd8, 0x15, 0x79, 0x9a, 0x79, 0x59, 0x54, - 0xa5, 0x46, 0xb2, 0x65, 0x7e, 0x34, 0xd4, 0xc4, 0xf6, 0xc7, 0x98, 0x26, - 0x39, 0x9c, 0x30, 0x18, 0xc0, 0x04, 0xac, 0xba, 0xca, 0x5f, 0xcd, 0x7b, - 0x03, 0xd7, 0x0d, 0xa0, 0x71, 0xdd, 0x90, 0x86, 0x85, 0x5e, 0x44, 0xfc, - 0xe3, 0x41, 0xf7, 0xc2, 0xd6, 0x6b, 0xee, 0xa5, 0x6b, 0x2f, 0x72, 0x18, - 0xbb, 0xc8, 0x48, 0xa0, 0x26, 0x48, 0x9b, 0xca, 0xac, 0x6d, 0x73, 0x5a, - 0x5d, 0x3d, 0xef, 0x97, 0xdc, 0x83, 0x4d, 0x47, 0x40, 0xee, 0x60, 0x85, - 0x61, 0xf6, 0x23, 0x2c, 0x80, 0x7c, 0x45, 0x5b, 0x49, 0x91, 0x43, 0x0c, - 0x50, 0x6c, 0xa2, 0x19, 0x0c, 0x03, 0x1f, 0xe7, 0x85, 0x15, 0x7f, 0x75, - 0xb2, 0xf2, 0x64, 0x05, 0x1a, 0x28, 0xbc, 0xa9, 0x21, 0x97, 0x42, 0x86, - 0x5e, 0x10, 0x01, 0xb9, 0x3c, 0x91, 0xfb, 0x95, 0x32, 0xde, 0x1a, 0xdd, - 0x32, 0x09, 0x81, 0x94, 0x9d, 0xda, 0x12, 0xed, 0x5a, 0x53, 0x4a, 0xc8, - 0xa2, 0xeb, 0xa8, 0x41, 0xcd, 0xaf, 0xfc, 0xe3, 0xb5, 0x89, 0x53, 0x90, - 0x30, 0x22, 0x59, 0x0a, 0x00, 0xcb, 0x01, 0xf0, 0x49, 0xb3, 0x5b, 0x7f, - 0x61, 0xc3, 0xc8, 0xee, 0xd9, 0x6d, 0xc8, 0xe1, 0x01, 0xa6, 0xe7, 0x26, - 0x84, 0xe8, 0xc8, 0x9c, 0x20, 0x3e, 0x18, 0x2a, 0xb7, 0x15, 0xd6, 0x66, - 0xb1, 0x51, 0x09, 0x20, 0xc1, 0x1a, 0x8b, 0x2d, 0x01, 0xdc, 0xac, 0xf6, - 0x1f, 0x6a, 0x74, 0x58, 0x8f, 0x30, 0x61, 0x46, 0x0e, 0x04, 0x91, 0x73, - 0x29, 0x08, 0x51, 0x0f, 0x92, 0x6f, 0x03, 0xaa, 0x88, 0x1d, 0x95, 0x57, - 0x6e, 0xec, 0xc2, 0xf8, 0xae, 0x43, 0x50, 0x14, 0xa4, 0x18, 0x19, 0x50, - 0x19, 0x08, 0x7c, 0x78, 0xde, 0xe7, 0xb3, 0x5e, 0x5c, 0x17, 0xde, 0xc0, - 0x66, 0x90, 0xed, 0x65, 0xaa, 0x00, 0x4e, 0x85, 0x3c, 0x6c, 0x79, 0x20, - 0x0d, 0x0f, 0xaa, 0x95, 0xa8, 0x5e, 0xb7, 0x8f, 0xbf, 0x3c, 0x07, 0x12, - 0x11, 0x91, 0xbd, 0xa9, 0x1f, 0x31, 0xf3, 0xd7, 0x8a, 0x6c, 0xd2, 0xa9, - 0xbd, 0x7d, 0xd1, 0x63, 0x39, 0x63, 0x64, 0x85, 0xe1, 0x94, 0xba, 0xb1, - 0xb5, 0xc0, 0xf4, 0xe2, 0xf7, 0x7b, 0xab, 0xc3, 0x99, 0xee, 0x43, 0x23, - 0x18, 0x80, 0x18, 0x50, 0xc3, 0xc0, 0x8e, 0x42, 0xf9, 0xef, 0xe5, 0xad, - 0xe2, 0x6d, 0xd8, 0xb6, 0x2e, 0xde, 0x45, 0xa3, 0x21, 0x87, 0x97, 0x70, - 0x33, 0xcb, 0xfa, 0xe6, 0x45, 0x7b, 0x46, 0x89, 0xf9, 0xa1, 0x2b, 0x09, - 0x65, 0x28, 0x87, 0x9b, 0xb8, 0x79, 0x04, 0x69, 0x01, 0xda, 0xbd, 0x17, - 0x7c, 0x84, 0x94, 0x23, 0x4b, 0x0a, 0x57, 0xe3, 0xf3, 0xed, 0x5d, 0x27, - 0xcc, 0x12, 0xe4, 0x07, 0xd3, 0x01, 0x46, 0x49, 0x43, 0x26, 0xf4, 0x70, - 0x85, 0x6b, 0x65, 0x9f, 0xaa, 0xa4, 0x88, 0x66, 0x20, 0x88, 0x44, 0x03, - 0x4c, 0x32, 0xa0, 0xa2, 0x5c, 0x8f, 0xb4, 0x0d, 0x90, 0x1f, 0x39, 0x41, - 0xfb, 0x48, 0x5c, 0x04, 0x70, 0xd9, 0x47, 0xec, 0x43, 0xae, 0x77, 0x33, - 0x84, 0xda, 0x48, 0xa6, 0xbd, 0xed, 0x92, 0xca, 0x38, 0x60, 0x28, 0x80, - 0x18, 0xd1, 0xa1, 0xd9, 0x46, 0xc7, 0xae, 0x2e, 0xcf, 0xd6, 0x4f, 0xb3, - 0x3c, 0xb7, 0xd0, 0x01, 0x03, 0x31, 0x97, 0xda, 0xd5, 0xee, 0xd7, 0x26, - 0x06, 0x12, 0xa5, 0xe8, 0x2f, 0xdf, 0x80, 0x18, 0xe2, 0x59, 0x64, 0xe1, - 0x20, 0x10, 0xc8, 0x97, 0x92, 0x4b, 0xad, 0x54, 0x02, 0x12, 0xc3, 0xcd, - 0x8a, 0x33, 0xc7, 0xf4, 0xfd, 0x4d, 0xeb, 0x6d, 0x4c, 0xa3, 0x34, 0x00, - 0xf8, 0xa8, 0xc8, 0x21, 0x90, 0x43, 0x3f, 0xae, 0x7b, 0xaf, 0x37, 0x7a, - 0x72, 0xc3, 0x47, 0xce, 0xbb, 0xbf, 0xd0, 0x80, 0x6e, 0x00, 0xd6, 0x71, - 0x42, 0x92, 0x12, 0x9c, 0x62, 0x09, 0xc7, 0x3f, 0x62, 0x36, 0xd2, 0xfe, - 0xff, 0xba, 0xb5, 0x08, 0x27, 0x88, 0x26, 0x86, 0x3b, 0xd4, 0x34, 0x8c, - 0x08, 0xf8, 0x24, 0xb3, 0x46, 0x1b, 0x60, 0xf3, 0x86, 0x32, 0x90, 0x47, - 0xb6, 0x92, 0x1f, 0x8b, 0xb6, 0xa1, 0x7a, 0x4e, 0x67, 0x04, 0x86, 0x51, - 0xfa, 0x96, 0xb4, 0xba, 0xe3, 0xe3, 0x6a, 0x97, 0x0a, 0x02, 0x30, 0x0a, - 0xd5, 0x08, 0x35, 0x42, 0x67, 0x00, 0xac, 0xa0, 0xd6, 0x6a, 0xcc, 0x52, - 0xa3, 0xe5, 0xec, 0xb9, 0x9c, 0xcb, 0xce, 0x53, 0xca, 0x63, 0x97, 0x95, - 0x91, 0x16, 0x6c, 0x65, 0x16, 0xcb, 0x6c, 0x3c, 0xa0, 0xa3, 0x34, 0x42, - 0x29, 0x5e, 0x01, 0x5e, 0xf4, 0xd2, 0xe1, 0x32, 0x9e, 0x42, 0x12, 0x3f, - 0x72, 0x3a, 0x8d, 0xe8, 0xab, 0x8b, 0x0a, 0x86, 0x29, 0x99, 0x00, 0xe3, - 0x38, 0x9a, 0x34, 0x0c, 0xd0, 0xcb, 0x4a, 0x21, 0x11, 0xdc, 0x07, 0xad, - 0x53, 0xe5, 0xb2, 0x30, 0x69, 0x13, 0x92, 0xc9, 0x64, 0xb3, 0x00, 0x35, - 0x33, 0x4d, 0xc0, 0xca, 0x64, 0x3e, 0x08, 0x03, 0x3a, 0x38, 0xde, 0x0d, - 0xd2, 0x96, 0xb7, 0xb7, 0xab, 0xc4, 0x9a, 0x26, 0x74, 0x27, 0xe9, 0xf1, - 0x0a, 0xc3, 0x6f, 0x5a, 0x79, 0xd5, 0xf2, 0x92, 0xd5, 0x33, 0x30, 0x40, - 0x41, 0x06, 0x81, 0x8d, 0xe1, 0xde, 0x9c, 0x8a, 0xbd, 0xb4, 0xb5, 0xc5, - 0x82, 0x8b, 0xe3, 0xc3, 0xf3, 0x03, 0xd3, 0x84, 0xa2, 0xcc, 0x03, 0xed, - 0x67, 0xe6, 0x20, 0x32, 0x94, 0x92, 0x18, 0x0e, 0x44, 0x61, 0x52, 0xaf, - 0xb8, 0x51, 0x7c, 0xac, 0x20, 0x67, 0x2c, 0x3b, 0x90, 0xe1, 0x90, 0x99, - 0x43, 0x24, 0x3d, 0x3f, 0x68, 0xad, 0xda, 0x91, 0x3e, 0x30, 0xc5, 0x2f, - 0xf1, 0x50, 0x71, 0x45, 0xf0, 0x09, 0x4e, 0x34, 0xd2, 0x7d, 0x94, 0xb3, - 0xe9, 0xbd, 0x44, 0x0d, 0x34, 0x18, 0x4f, 0xc4, 0x5c, 0xc3, 0x04, 0x3c, - 0x9b, 0x08, 0xc5, 0x2d, 0x65, 0x23, 0x40, 0x64, 0xa5, 0xf4, 0x77, 0xfb, - 0xbf, 0xca, 0x23, 0x89, 0x8d, 0x03, 0x4b, 0x40, 0xf6, 0xb4, 0x49, 0x39, - 0x24, 0x7c, 0x4f, 0x79, 0xce, 0x13, 0x0b, 0x38, 0xc9, 0xbf, 0xc5, 0x94, - 0x64, 0x07, 0xd0, 0x2d, 0xed, 0xe0, 0x30, 0x14, 0x68, 0xfd, 0x3f, 0x08, - 0x42, 0x62, 0xa3, 0xd3, 0x1c, 0x88, 0x58, 0xe8, 0x8c, 0x9b, 0x22, 0x3c, - 0x41, 0xa6, 0xa5, 0x7d, 0x1d, 0xbf, 0xc0, 0xf9, 0xf9, 0xbe, 0x78, 0x67, - 0x0a, 0x2f, 0xbf, 0x39, 0xd4, 0xb2, 0x6f, 0x07, 0xcc, 0x09, 0xe5, 0x7d, - 0x54, 0xfc, 0xbb, 0x30, 0xc6, 0x22, 0x66, 0x84, 0xf2, 0xb4, 0x8c, 0xa1, - 0x74, 0xaf, 0x04, 0x8e, 0x73, 0x71, 0x1a, 0xf0, 0x67, 0xad, 0x8a, 0x18, - 0xd0, 0xf1, 0x63, 0x95, 0xf4, 0xc7, 0xc4, 0x7e, 0x75, 0xb6, 0x12, 0xd8, - 0xd4, 0xe7, 0x03, 0x11, 0xb2, 0x1e, 0x70, 0x8f, 0xb2, 0xbf, 0x18, 0x7b, - 0xf8, 0x98, 0x97, 0xe1, 0xe7, 0x08, 0x0c, 0x6f, 0x55, 0x19, 0x94, 0xfa, - 0xd5, 0x89, 0xb7, 0xdc, 0xf1, 0x2b, 0xc6, 0x4b, 0x32, 0x8c, 0x26, 0x26, - 0x96, 0x72, 0x4d, 0x55, 0x3d, 0xba, 0x6e, 0xbc, 0xb6, 0x98, 0xe1, 0x9c, - 0x6e, 0x18, 0x12, 0x84, 0xf1, 0x8d, 0x14, 0x0e, 0x5e, 0x01, 0xe2, 0x74, - 0xf7, 0x4a, 0x55, 0xff, 0xb7, 0x3c, 0xe7, 0xfe, 0xd2, 0x97, 0xce, 0xed, - 0xc6, 0xc6, 0xec, 0xfd, 0x89, 0xe9, 0x52, 0x26, 0x8b, 0x82, 0xfa, 0x44, - 0x8c, 0x21, 0xbc, 0xa5, 0x79, 0x76, 0x5b, 0xb7, 0x93, 0x70, 0x56, 0xe0, - 0x00, 0x48, 0x84, 0xee, 0x09, 0x17, 0x61, 0x46, 0x90, 0x44, 0x07, 0x32, - 0x9c, 0xc7, 0x71, 0x56, 0x64, 0x67, 0x46, 0x3e, 0xbf, 0x93, 0xdf, 0x4e, - 0xa6, 0x2c, 0x0a, 0x05, 0x0a, 0x6b, 0x15, 0x0f, 0xe9, 0x0d, 0xb6, 0xf0, - 0xce, 0x0a, 0x32, 0xa1, 0x59, 0x11, 0xe3, 0xa6, 0xac, 0xe1, 0xb4, 0xc4, - 0xbf, 0xcc, 0xac, 0x9d, 0xed, 0xe7, 0x34, 0x49, 0xf1, 0x26, 0xad, 0x58, - 0xdb, 0xf1, 0xb5, 0x00, 0xa1, 0x05, 0xed, 0xb2, 0xe0, 0xc2, 0x96, 0x82, - 0x05, 0xa4, 0x95, 0x59, 0x76, 0xbf, 0xe6, 0x96, 0xb8, 0xd0, 0x29, 0xe5, - 0xad, 0x2b, 0x7b, 0x73, 0xb3, 0x2d, 0x01, 0x20, 0x4d, 0x12, 0x72, 0xdc, - 0x92, 0x5d, 0x1c, 0x24, 0x2e, 0xb8, 0x33, 0x70, 0xe9, 0x41, 0x56, 0xaf, - 0x9f, 0xeb, 0x1a, 0xa5, 0xae, 0x1a, 0x74, 0x68, 0x04, 0x24, 0xc0, 0x01, - 0x38, 0x4e, 0xc8, 0xc9, 0x9f, 0x01, 0xc3, 0x39, 0xc3, 0xb5, 0x0c, 0xa3, - 0xe2, 0xaa, 0x6e, 0xf0, 0x69, 0x07, 0xda, 0x17, 0xbf, 0x6a, 0xcd, 0x92, - 0x26, 0x87, 0xd7, 0x87, 0xae, 0x0a, 0x3d, 0xf5, 0x87, 0xfc, 0x3b, 0x9c, - 0xb1, 0xf2, 0xe8, 0x90, 0x12, 0x92, 0x27, 0xb9, 0x40, 0xea, 0xc5, 0x63, - 0xab, 0xfe, 0xf3, 0xbe, 0x62, 0x07, 0xa2, 0x95, 0xf3, 0x47, 0x72, 0x1b, - 0xd9, 0xaf, 0xd2, 0x2c, 0x51, 0x28, 0x8c, 0x9f, 0xcc, 0xe4, 0xfb, 0x83, - 0x33, 0xdd, 0xba, 0xbe, 0xb4, 0xbb, 0x33, 0xf7, 0x4d, 0x8c, 0xe0, 0xb6, - 0x41, 0xc9, 0x13, 0xc3, 0x72, 0xad, 0xd1, 0xd1, 0xed, 0x58, 0x16, 0xf9, - 0xff, 0xde, 0xf5, 0x0b, 0xfb, 0x38, 0xbb, 0x1b, 0x8c, 0x1e, 0xdf, 0x9a, - 0x5f, 0xd5, 0x8d, 0xb9, 0x8c, 0x60, 0x1c, 0xbc, 0xc2, 0x58, 0x44, 0x23, - 0x94, 0x67, 0xf4, 0x1d, 0x27, 0x10, 0x46, 0xfb, 0x75, 0xa0, 0xc3, 0x22, - 0x6d, 0x45, 0xc1, 0x94, 0xa6, 0xc5, 0x08, 0x7e, 0x30, 0x56, 0x7d, 0xb6, - 0x59, 0xcd, 0x35, 0xfe, 0xcf, 0xfc, 0xf0, 0x1a, 0xe7, 0xb8, 0xf3, 0x04, - 0x0c, 0xa7, 0x05, 0x09, 0xe0, 0x15, 0x86, 0x4e, 0x56, 0xce, 0xff, 0x8b, - 0x6e, 0xed, 0x94, 0x26, 0x79, 0xa2, 0x12, 0xe4, 0x25, 0x38, 0x12, 0xce, - 0xe7, 0x92, 0xfa, 0x6a, 0xaa, 0xb6, 0xa8, 0x84, 0x71, 0xd9, 0x9b, 0x72, - 0xd9, 0x14, 0xb1, 0x66, 0x85, 0x09, 0x91, 0x29, 0xe5, 0xc9, 0x17, 0xa0, - 0x09, 0xfa, 0x20, 0xa5, 0xc3, 0x66, 0x2e, 0x3b, 0x53, 0x59, 0xd1, 0x0c, - 0x40, 0x5c, 0xd2, 0xf7, 0x95, 0x46, 0x53, 0x01, 0x10, 0x4e, 0x53, 0xfd, - 0x46, 0xb7, 0x82, 0x6b, 0xe8, 0xea, 0x52, 0xc6, 0x9b, 0xe5, 0xa5, 0x88, - 0x2a, 0xf0, 0x28, 0x23, 0x51, 0x99, 0x77, 0x00, 0x46, 0x77, 0x3c, 0x9a, - 0xfa, 0x51, 0x28, 0xad, 0x8d, 0x13, 0x0d, 0xe9, 0x41, 0x1a, 0x12, 0x43, - 0xee, 0x12, 0x28, 0xbb, 0x8e, 0xf6, 0x0e, 0x18, 0xc0, 0x57, 0x6f, 0x2d, - 0x28, 0x32, 0x33, 0xf2, 0xa4, 0x06, 0xf2, 0x7b, 0xa3, 0xf1, 0x6b, 0x06, - 0xcf, 0x23, 0x81, 0xe7, 0x90, 0xc5, 0xa8, 0xa9, 0x27, 0x64, 0x97, 0x44, - 0xba, 0x07, 0x1a, 0x52, 0xc9, 0xa2, 0x97, 0x56, 0x19, 0xca, 0x2a, 0x7e, - 0xd8, 0x92, 0x79, 0xbd, 0x7a, 0x0d, 0xf9, 0x61, 0x80, 0x9b, 0x83, 0x31, - 0xa6, 0xa6, 0xe8, 0x32, 0x38, 0x40, 0x99, 0x81, 0x75, 0xd5, 0xa5, 0xd8, - 0xbd, 0x0c, 0x71, 0xb8, 0x1c, 0xe5, 0x65, 0x99, 0x50, 0x09, 0x0c, 0xb3, - 0xe2, 0x7b, 0x5a, 0xbc, 0x1c, 0x0d, 0x21, 0xa9, 0xc8, 0x33, 0x01, 0x2c, - 0x64, 0x66, 0x6f, 0x49, 0xf4, 0xf8, 0xb7, 0x5a, 0x5f, 0xe8, 0x86, 0x10, - 0xcc, 0x01, 0x08, 0xc6, 0x9e, 0x8b, 0xc8, 0x91, 0x47, 0x72, 0x22, 0x55, - 0x83, 0xfb, 0xa5, 0xa7, 0x50, 0xd3, 0x4d, 0xcb, 0xd2, 0xa5, 0x96, 0x60, - 0x35, 0x1e, 0x52, 0x00, 0xa3, 0x39, 0x23, 0xf6, 0x4c, 0x6d, 0x4b, 0x14, - 0x96, 0xf9, 0xa9, 0x43, 0xd9, 0x80, 0x27, 0x6a, 0xf3, 0xa2, 0xcf, 0xc3, - 0x19, 0x19, 0x4f, 0x2a, 0x69, 0x72, 0x32, 0x95, 0x65, 0x3e, 0x9b, 0xfa, - 0x8e, 0x23, 0x36, 0x83, 0xb0, 0x71, 0xd4, 0x0d, 0x52, 0xaf, 0x99, 0x02, - 0xf9, 0x7b, 0x20, 0x8c, 0x82, 0x33, 0x8e, 0x5d, 0xb1, 0x34, 0x18, 0x1c, - 0x32, 0xad, 0x70, 0x4c, 0x88, 0x95, 0x1e, 0xc2, 0xf8, 0xda, 0x70, 0xe0, - 0xc8, 0x62, 0xfc, 0xdc, 0xc8, 0x96, 0x02, 0x83, 0x41, 0x56, 0xbf, 0xc5, - 0xfc, 0xba, 0xdc, 0x53, 0x94, 0x9c, 0x63, 0x38, 0x9c, 0x19, 0x29, 0x99, - 0xa4, 0x60, 0x12, 0xac, 0x53, 0x6b, 0xcc, 0xb1, 0xc3, 0xca, 0x50, 0x24, - 0x4f, 0x68, 0x12, 0x35, 0x53, 0x3b, 0xbe, 0xca, 0x08, 0x87, 0x79, 0x49, - 0x20, 0xd5, 0x60, 0xea, 0x68, 0xc4, 0x50, 0xcb, 0x29, 0x50, 0xf7, 0x02, - 0xfe, 0xba, 0x30, 0x35, 0x3e, 0x06, 0xf5, 0x86, 0x7c, 0x32, 0x22, 0x53, - 0x24, 0xa2, 0x82, 0x33, 0x19, 0x3e, 0xc8, 0x35, 0xbb, 0x30, 0xd2, 0x05, - 0x8b, 0x9f, 0xf0, 0x22, 0xdd, 0xa3, 0x22, 0x81, 0x48, 0x37, 0xda, 0x88, - 0x20, 0xae, 0x96, 0x5c, 0xa1, 0xbd, 0x18, 0x49, 0xe6, 0xe6, 0x6b, 0xdb, - 0xeb, 0x19, 0x06, 0x9c, 0xe8, 0x99, 0x11, 0x93, 0xc9, 0x7d, 0x42, 0xff, - 0xe3, 0xa3, 0x00, 0x82, 0x88, 0x1e, 0x94, 0x67, 0x47, 0xe2, 0xd6, 0x5a, - 0x64, 0xb2, 0x26, 0x40, 0xa1, 0xe9, 0xc2, 0x45, 0x33, 0x4a, 0x8a, 0x5f, - 0x61, 0x3c, 0x11, 0x2d, 0x23, 0xa6, 0x9c, 0xe4, 0x8a, 0x17, 0xa0, 0x4f, - 0xe2, 0xf8, 0xb8, 0xbc, 0xd1, 0x6a, 0x34, 0xa1, 0x94, 0x19, 0x32, 0x97, - 0x80, 0xd5, 0x67, 0x26, 0x01, 0xce, 0x95, 0x41, 0xcb, 0x42, 0x8e, 0x50, - 0x83, 0x0e, 0x70, 0x8d, 0xc0, 0x7a, 0xdc, 0x88, 0xa2, 0x48, 0x9c, 0xf2, - 0x52, 0xfb, 0x6c, 0x49, 0x62, 0xec, 0xcd, 0xe1, 0x39, 0x06, 0xfb, 0x09, - 0xf6, 0x8e, 0x84, 0x8e, 0xe9, 0x25, 0xb9, 0x39, 0x7e, 0x9c, 0xaf, 0x11, - 0x1b, 0x04, 0xf9, 0x7d, 0x9a, 0x1a, 0x4a, 0xab, 0x00, 0xdb, 0xba, 0x4a, - 0xe6, 0xd2, 0x6b, 0x9b, 0x85, 0xf2, 0xcc, 0x32, 0xab, 0xc7, 0x2d, 0x21, - 0x59, 0x3a, 0xb0, 0x27, 0xbf, 0xc5, 0xf2, 0x7b, 0x3f, 0x43, 0x6c, 0xab, - 0xbf, 0xd5, 0xe5, 0x2e, 0xcd, 0x4e, 0xbe, 0xe1, 0xc8, 0x3c, 0x96, 0x13, - 0xed, 0x14, 0xe8, 0xf8, 0x81, 0x7c, 0x49, 0x06, 0x5b, 0xd1, 0xca, 0x45, - 0x2f, 0x2a, 0x34, 0x2e, 0x03, 0xc5, 0x86, 0x64, 0x40, 0x8e, 0x1e, 0x80, - 0x0d, 0x42, 0x14, 0x80, 0x6f, 0xb4, 0xc9, 0xe4, 0xf6, 0xed, 0xda, 0xd4, - 0x45, 0x0d, 0x42, 0xc1, 0x76, 0xe2, 0xbb, 0xd1, 0x05, 0x66, 0x4a, 0xd4, - 0xd1, 0xca, 0x85, 0xc8, 0xcb, 0xfb, 0x84, 0xa5, 0xca, 0x98, 0x8f, 0xbf, - 0xcf, 0xc5, 0x71, 0x5f, 0xfe, 0xe6, 0x92, 0x56, 0x20, 0xa4, 0x34, 0x8a, - 0x35, 0x7a, 0xaa, 0xa2, 0xb5, 0x79, 0xe1, 0x24, 0xa9, 0xee, 0xc3, 0x2c, - 0x4d, 0x59, 0xa0, 0x41, 0xf5, 0x87, 0xa8, 0xa0, 0xeb, 0x02, 0xe9, 0xfd, - 0xdf, 0x77, 0xbb, 0x72, 0xc4, 0x17, 0x9e, 0xdb, 0xe1, 0x18, 0x70, 0xca, - 0x6a, 0x87, 0x24, 0x68, 0xb8, 0x80, 0x84, 0x94, 0xc1, 0xe7, 0xd5, 0x07, - 0xde, 0xd4, 0xdc, 0xce, 0x2a, 0xde, 0x74, 0xb8, 0xd9, 0xfd, 0x5a, 0x0f, - 0x91, 0x9a, 0x70, 0x8a, 0x34, 0x0a, 0xc9, 0x5f, 0x88, 0x28, 0xf9, 0x3a, - 0x79, 0xd6, 0xee, 0x4c, 0x82, 0xa4, 0x97, 0x24, 0x4a, 0x43, 0x2b, 0x25, - 0xf5, 0x55, 0xcb, 0x6f, 0x23, 0xb1, 0x2c, 0x9a, 0x43, 0xe6, 0x9e, 0xe1, - 0x70, 0x77, 0x07, 0x09, 0x14, 0x9c, 0x00, 0x5e, 0xb9, 0x22, 0x28, 0xd7, - 0xf9, 0x41, 0xe6, 0x13, 0xa6, 0x2b, 0x73, 0x5a, 0x4f, 0x6b, 0x98, 0x39, - 0xba, 0xf8, 0xa7, 0xfc, 0x07, 0x1d, 0xbf, 0x69, 0xcc, 0x00, 0xd1, 0x66, - 0xa6, 0x41, 0x00, 0x91, 0x41, 0x1e, 0xe0, 0x07, 0xcb, 0x16, 0xfe, 0xc6, - 0xe6, 0xd5, 0x54, 0xb4, 0x51, 0x4e, 0xf7, 0x2a, 0xb4, 0x86, 0xa0, 0x77, - 0xb8, 0x2b, 0xf2, 0x41, 0x2f, 0xb2, 0x03, 0xc0, 0x7a, 0x92, 0x7b, 0xcb, - 0xd5, 0x9a, 0x65, 0xd2, 0x37, 0x80, 0xbe, 0xdc, 0x4e, 0x0c, 0x3e, 0xaa, - 0x86, 0xef, 0x86, 0x01, 0xa8, 0x77, 0x36, 0xd7, 0xf2, 0xf5, 0xb9, 0xeb, - 0xd8, 0x6e, 0x5e, 0x12, 0x5d, 0xfc, 0xf7, 0x93, 0xb6, 0x91, 0xbc, 0x00, - 0x04, 0x67, 0x97, 0xf7, 0x37, 0xac, 0x3b, 0x81, 0xbe, 0xab, 0x3e, 0xfa, - 0x92, 0x67, 0xb1, 0x60, 0x4e, 0xf4, 0x64, 0x27, 0x08, 0x08, 0x32, 0x40, - 0x9a, 0x3e, 0x2c, 0x4c, 0x9a, 0x53, 0x45, 0xcc, 0xe1, 0xfa, 0x70, 0xda, - 0x8c, 0x00, 0x49, 0x6d, 0x0e, 0x4b, 0x22, 0xf6, 0x7f, 0xd1, 0x49, 0x37, - 0xa0, 0x28, 0x48, 0x5e, 0xa4, 0xc5, 0x76, 0xb8, 0x86, 0x1a, 0xa5, 0x34, - 0xe6, 0x0a, 0x25, 0x80, 0x48, 0x9f, 0x01, 0x25, 0xb3, 0xde, 0xf1, 0x0b, - 0xaf, 0x6b, 0x22, 0x1c, 0x60, 0x1c, 0xc9, 0xa3, 0x17, 0x96, 0x19, 0xb2, - 0x1b, 0xcb, 0xc2, 0x1d, 0xf6, 0x9f, 0xc2, 0x89, 0x99, 0xcd, 0x9b, 0x7f, - 0x67, 0x7e, 0x39, 0xdf, 0x37, 0x9b, 0xd3, 0xf3, 0x7f, 0xfe, 0xb8, 0x34, - 0xb0, 0xf0, 0x03, 0xbf, 0x33, 0x23, 0xa5, 0x01, 0x51, 0x28, 0x09, 0x90, - 0x89, 0x78, 0x4f, 0xd0, 0x1c, 0xf6, 0x61, 0xc6, 0xb4, 0xd4, 0x08, 0x9d, - 0x22, 0xcf, 0x08, 0xa4, 0x70, 0xc6, 0x79, 0x77, 0xa8, 0x15, 0xe9, 0x0d, - 0x74, 0x0a, 0xc6, 0x04, 0xb0, 0x6f, 0x39, 0x80, 0x43, 0xcc, 0xa8, 0xfc, - 0x5a, 0x32, 0xa0, 0x2a, 0xd6, 0x01, 0xb9, 0x41, 0xd1, 0xd8, 0x96, 0x5a, - 0x07, 0x25, 0xf4, 0x5c, 0x48, 0x1f, 0x0b, 0x38, 0x4c, 0x2e, 0x15, 0x23, - 0x32, 0xe2, 0xee, 0x7c, 0x7d, 0xf8, 0xa5, 0x89, 0xde, 0x89, 0x2f, 0xc7, - 0x4d, 0xba, 0x2f, 0xfe, 0x48, 0x95, 0x19, 0x4e, 0x06, 0x64, 0x4e, 0x54, - 0xfc, 0x0c, 0xf6, 0xc3, 0x5a, 0x17, 0xb0, 0x90, 0x9e, 0x52, 0x5c, 0xf2, - 0x51, 0xa4, 0x15, 0xc5, 0xf2, 0x98, 0xce, 0x50, 0xfc, 0xef, 0x86, 0x91, - 0x5b, 0x95, 0x23, 0x42, 0x48, 0xa3, 0x90, 0xea, 0xcb, 0x47, 0x98, 0xdf, - 0xf2, 0xcc, 0xfc, 0x5b, 0x0d, 0xdc, 0x8e, 0x78, 0x86, 0x58, 0xf2, 0xed, - 0xa0, 0x6a, 0xea, 0xe1, 0x51, 0xf1, 0x0c, 0xfb, 0x3a, 0x2c, 0x4e, 0x59, - 0xec, 0x82, 0x32, 0x65, 0x93, 0xc2, 0xd9, 0xa4, 0x32, 0x72, 0x41, 0x91, - 0x45, 0x23, 0x43, 0xc3, 0xab, 0x8a, 0xfb, 0xaf, 0x21, 0xc6, 0x42, 0x85, - 0x61, 0x24, 0xcb, 0x25, 0x09, 0xf4, 0xf6, 0x54, 0x1e, 0x45, 0xe1, 0x42, - 0x19, 0x49, 0x1c, 0x96, 0x11, 0x3c, 0x89, 0x2f, 0xf3, 0xa9, 0x48, 0x39, - 0x02, 0x14, 0x50, 0x26, 0x8f, 0x64, 0x33, 0x85, 0x4f, 0x35, 0x85, 0xe7, - 0xdd, 0x7f, 0x7d, 0xfb, 0xd9, 0xd4, 0x62, 0x06, 0x1a, 0x57, 0x10, 0xfe, - 0x12, 0xc6, 0x9e, 0x26, 0xb6, 0x5d, 0x41, 0xde, 0x66, 0x1e, 0xcf, 0x32, - 0x7b, 0x20, 0x4e, 0xec, 0xf1, 0x84, 0xb2, 0x28, 0x55, 0xd2, 0x4f, 0xcd, - 0x23, 0xff, 0xcb, 0xd4, 0x96, 0x6a, 0x16, 0xc9, 0x1a, 0xd8, 0x02, 0x59, - 0x7f, 0x06, 0x3e, 0x7d, 0xe1, 0x0f, 0x60, 0x79, 0xec, 0x1b, 0x41, 0x5f, - 0x99, 0xb9, 0x65, 0x5d, 0x82, 0xbe, 0x2f, 0x97, 0x8f, 0xd2, 0xef, 0x0e, - 0x32, 0xd7, 0xab, 0x65, 0xc5, 0xa1, 0x92, 0xf1, 0x74, 0x65, 0xf3, 0x00, - 0xb1, 0xab, 0x54, 0x7f, 0x26, 0x43, 0x2c, 0x4e, 0xba, 0x6d, 0x83, 0xb9, - 0x1a, 0x75, 0xec, 0x98, 0x6d, 0x1f, 0xa1, 0x37, 0xdb, 0xaa, 0x3e, 0xb4, - 0x1a, 0xef, 0xe9, 0x4a, 0x7a, 0x76, 0xe3, 0x66, 0x0c, 0x92, 0xf5, 0x06, - 0xcc, 0x39, 0x3d, 0x78, 0x84, 0x7a, 0x7e, 0xb0, 0x7d, 0xd5, 0xff, 0x20, - 0x07, 0x08, 0x68, 0x35, 0xbf, 0x04, 0xd8, 0xc6, 0x59, 0x67, 0xec, 0xa4, - 0x24, 0xfc, 0xce, 0x83, 0x4f, 0x44, 0x3e, 0xde, 0x86, 0xd4, 0x79, 0x9b, - 0xb0, 0xaf, 0x98, 0x4c, 0xf2, 0xa8, 0xe0, 0x1f, 0x47, 0x83, 0x85, 0x12, - 0xfb, 0x32, 0x01, 0x0a, 0x5a, 0xca, 0xc6, 0x92, 0x31, 0x8a, 0x45, 0x1a, - 0x3f, 0x57, 0x1f, 0xb8, 0x96, 0xe1, 0xfd, 0x20, 0xc8, 0x98, 0x54, 0x56, - 0x01, 0x27, 0x2a, 0x50, 0xcd, 0x0f, 0x9e, 0x36, 0xe2, 0x97, 0xae, 0x69, - 0x36, 0x86, 0x5e, 0x54, 0xcc, 0x68, 0x69, 0x73, 0x32, 0xdb, 0x56, 0xbf, - 0xfb, 0xa7, 0x66, 0x20, 0xd6, 0xcb, 0x06, 0x82, 0x07, 0x98, 0x46, 0x6f, - 0xb9, 0x61, 0xbe, 0x3d, 0x57, 0x3d, 0xed, 0x8f, 0x50, 0x2e, 0x56, 0x2f, - 0x37, 0x75, 0xed, 0x94, 0xc2, 0x72, 0x66, 0x91, 0x07, 0x95, 0xa5, 0x6d, - 0xf1, 0xb5, 0xaf, 0x8e, 0xd8, 0xcb, 0x20, 0x1a, 0x44, 0x09, 0xbc, 0xd0, - 0x13, 0x2c, 0x12, 0xb2, 0xa1, 0xf1, 0x3e, 0xda, 0x6b, 0x21, 0xad, 0x9d, - 0x53, 0x59, 0x33, 0x6e, 0x1a, 0x50, 0xb0, 0xc3, 0x19, 0x55, 0x31, 0x00, - 0x61, 0x7c, 0xa9, 0xe5, 0xf8, 0xb7, 0x7f, 0x2e, 0x8f, 0x9b, 0x6e, 0xd1, - 0x3a, 0x1c, 0x66, 0xd0, 0x65, 0xc3, 0x04, 0xe6, 0xe6, 0xf0, 0x98, 0x09, - 0x21, 0x95, 0xe2, 0x18, 0xa7, 0xb2, 0xbd, 0x90, 0x14, 0x05, 0x78, 0xcf, - 0x21, 0x65, 0xa1, 0x93, 0x47, 0x09, 0x15, 0xbe, 0x1f, 0x92, 0xf0, 0x15, - 0x32, 0x84, 0xd8, 0xe0, 0x22, 0x8c, 0xdc, 0xa3, 0x2f, 0x83, 0xf1, 0x43, - 0x14, 0x4c, 0x7e, 0xe1, 0xa0, 0x18, 0xef, 0x5f, 0xa2, 0x1b, 0xe6, 0x66, - 0x97, 0x2a, 0x3e, 0x2d, 0x7f, 0x80, 0x5a, 0x1b, 0xc7, 0x2e, 0x94, 0xdf, - 0x17, 0xe0, 0xfe, 0x8a, 0x77, 0x05, 0xc3, 0x3c, 0x33, 0x28, 0xc2, 0x90, - 0xc9, 0x66, 0x0a, 0x2a, 0x60, 0xa6, 0xec, 0x11, 0x9e, 0x54, 0xd2, 0x82, - 0x5f, 0xdc, 0x10, 0x88, 0x5b, 0x24, 0x6f, 0x4f, 0x69, 0x4a, 0xf5, 0xb8, - 0x5c, 0xac, 0xc6, 0xf7, 0x77, 0x35, 0x19, 0x81, 0x0a, 0x32, 0x0d, 0x92, - 0x11, 0xa3, 0xf1, 0xa2, 0xc8, 0x99, 0x4c, 0xb9, 0x43, 0x2d, 0x28, 0x4a, - 0xf5, 0x3e, 0x23, 0x36, 0x1d, 0xd1, 0xc3, 0x94, 0x87, 0xdc, 0x06, 0xfb, - 0x07, 0x78, 0x60, 0xed, 0x05, 0x2c, 0x9f, 0x65, 0x0f, 0xe5, 0x09, 0x53, - 0x9e, 0x84, 0x91, 0x66, 0x72, 0x4f, 0xc7, 0x1f, 0x05, 0xd6, 0x68, 0x7c, - 0x58, 0xd0, 0xcc, 0xd0, 0xec, 0xc2, 0x86, 0x98, 0x51, 0x7c, 0xa6, 0xa3, - 0x33, 0x56, 0xa1, 0x6f, 0xf1, 0xf8, 0x20, 0xcc, 0x48, 0xed, 0x46, 0xf2, - 0x69, 0x72, 0xf1, 0x72, 0x39, 0x69, 0x09, 0xde, 0x33, 0xf1, 0x54, 0x2b, - 0xcc, 0x4e, 0x3e, 0x52, 0x29, 0x11, 0xd8, 0x4f, 0x8f, 0x06, 0x60, 0xfd, - 0xdd, 0x5d, 0x34, 0xae, 0x37, 0xe6, 0x5c, 0x5e, 0x75, 0xc1, 0xd3, 0xbe, - 0x50, 0x24, 0xb6, 0xf7, 0x23, 0x87, 0xa5, 0xc3, 0x94, 0x12, 0xfc, 0x01, - 0xf7, 0xfb, 0xfb, 0x3b, 0xbe, 0x9e, 0xea, 0xce, 0x5e, 0x2e, 0xf5, 0xba, - 0x4f, 0x90, 0x5e, 0xa6, 0x8e, 0x4f, 0x4e, 0x84, 0x8d, 0x0f, 0x14, 0x61, - 0xf6, 0xe9, 0xd5, 0x5e, 0x6b, 0x35, 0x5b, 0xea, 0xba, 0xd0, 0x3b, 0xd4, - 0xb5, 0x33, 0x37, 0x63, 0xb7, 0x94, 0x98, 0x99, 0x4f, 0x2a, 0x7e, 0x3b, - 0x48, 0x1c, 0xeb, 0xb4, 0xa6, 0x9e, 0x76, 0x2b, 0xc2, 0x89, 0x3b, 0xf8, - 0x36, 0x55, 0xce, 0x57, 0x8d, 0xd0, 0x0b, 0xdd, 0x53, 0x34, 0xa0, 0x93, - 0x01, 0xb1, 0x80, 0x25, 0xa5, 0x51, 0xf1, 0x3d, 0x3e, 0xbc, 0xb3, 0x56, - 0x99, 0xb7, 0x12, 0xa1, 0x73, 0x23, 0x5f, 0x14, 0xf1, 0xb8, 0x83, 0x2e, - 0x73, 0x84, 0xf8, 0x82, 0xb4, 0x54, 0xcb, 0x4c, 0x6b, 0xdb, 0xf3, 0xf1, - 0x04, 0xad, 0x66, 0xb6, 0x7b, 0x9a, 0x25, 0x2c, 0x63, 0x80, 0xfb, 0x61, - 0x8c, 0x0d, 0x1e, 0xe0, 0x4e, 0xfe, 0x37, 0x63, 0x1e, 0x7a, 0x86, 0xfe, - 0xb7, 0x9d, 0x2b, 0x79, 0xd7, 0x9c, 0x0a, 0x0d, 0x35, 0x12, 0x40, 0x83, - 0x49, 0x55, 0x8c, 0x3d, 0x3a, 0xfb, 0x4a, 0x3e, 0xb6, 0xb6, 0xbb, 0xed, - 0x13, 0x6d, 0x2f, 0x9d, 0x95, 0x6e, 0xdc, 0xa9, 0x09, 0x9e, 0x7c, 0xfe, - 0x9c, 0xd5, 0xdd, 0x9d, 0xf3, 0x9e, 0xcf, 0xcb, 0xb9, 0x7e, 0xd7, 0x16, - 0xa2, 0x21, 0x08, 0x27, 0xa0, 0x8c, 0xb2, 0x20, 0x84, 0x6c, 0xee, 0xed, - 0xd3, 0x85, 0xee, 0x7c, 0x6d, 0xc1, 0x18, 0xf4, 0x55, 0x42, 0xa2, 0x29, - 0x55, 0x60, 0x27, 0xdb, 0xbd, 0x76, 0x26, 0x7a, 0x8f, 0x98, 0xcd, 0xa2, - 0xe9, 0xa9, 0x1e, 0xd0, 0x08, 0x4c, 0x26, 0xa8, 0x44, 0x61, 0x89, 0xab, - 0x01, 0xe1, 0xff, 0xb9, 0xbb, 0xc9, 0xc0, 0x14, 0xff, 0xfb, 0x38, 0xb7, - 0xcd, 0x04, 0xa1, 0xe5, 0x81, 0x38, 0xd8, 0x0a, 0x14, 0x6a, 0xd7, 0xe9, - 0x17, 0xb9, 0x25, 0xd0, 0xac, 0xff, 0x0b, 0xff, 0xb4, 0x60, 0xba, 0xbf, - 0x14, 0x9d, 0xee, 0x9b, 0xb3, 0x5c, 0x36, 0xe1, 0x1b, 0x07, 0x70, 0xec, - 0x25, 0x04, 0x03, 0x5e, 0x1d, 0x64, 0x4d, 0x3a, 0xb0, 0xdb, 0xab, 0x34, - 0xf4, 0xff, 0xbc, 0xb0, 0xda, 0x45, 0xa4, 0x96, 0x4f, 0xd8, 0x9b, 0x81, - 0x7f, 0xcd, 0x7e, 0xb6, 0xfb, 0x82, 0x4d, 0x88, 0x35, 0x25, 0x6c, 0x64, - 0x17, 0x97, 0x02, 0x29, 0x14, 0x92, 0x11, 0xf3, 0x2f, 0xf5, 0x69, 0x5c, - 0x40, 0x36, 0x9c, 0xf0, 0x29, 0xc3, 0x40, 0xb6, 0x58, 0x14, 0x27, 0x31, - 0x42, 0x0a, 0xcd, 0x12, 0x7b, 0x83, 0x82, 0x79, 0x2d, 0x7f, 0x1d, 0x07, - 0x43, 0x8e, 0x96, 0x8c, 0x98, 0xa0, 0xf3, 0xcf, 0x90, 0x4e, 0x1f, 0x77, - 0x4a, 0x95, 0xaf, 0x3e, 0x8d, 0x81, 0x9f, 0x79, 0x66, 0x73, 0x92, 0x43, - 0xb8, 0x07, 0x8b, 0xba, 0xc1, 0xaf, 0xbd, 0xee, 0x7f, 0x99, 0xbf, 0x1c, - 0xde, 0x07, 0xac, 0xb2, 0x24, 0x83, 0xb2, 0x38, 0x76, 0xca, 0xf0, 0xdc, - 0x5a, 0xf6, 0xf7, 0xfd, 0xdc, 0xb8, 0xc4, 0xf6, 0xc4, 0x50, 0xe3, 0x48, - 0x11, 0x4e, 0x64, 0xbd, 0xa7, 0x2e, 0x73, 0x94, 0xaa, 0xc3, 0xe2, 0x3d, - 0xec, 0x8f, 0xb7, 0xff, 0xe3, 0x30, 0xbe, 0x4e, 0x5d, 0x0d, 0xb1, 0xa1, - 0xe9, 0xfb, 0x29, 0x07, 0xd8, 0x37, 0xd1, 0xd7, 0xea, 0x2e, 0x3f, 0x5c, - 0x3a, 0xf0, 0xa9, 0x75, 0xd9, 0x5d, 0x54, 0xbf, 0x2f, 0x9e, 0x9d, 0x2b, - 0x73, 0x97, 0xe1, 0x88, 0x5c, 0xe2, 0xe2, 0xa2, 0xd8, 0xe4, 0xbc, 0xe4, - 0xa3, 0x0c, 0x30, 0x25, 0x77, 0x00, 0x88, 0xea, 0x97, 0x2b, 0xfe, 0xae, - 0xdd, 0xdd, 0x6a, 0x16, 0x26, 0x40, 0xa9, 0xc4, 0x03, 0x2d, 0x89, 0x82, - 0x06, 0x9a, 0x33, 0xbd, 0x3e, 0x20, 0x8e, 0xc5, 0x8b, 0x63, 0xda, 0xf5, - 0xed, 0xaf, 0x83, 0xfd, 0xd8, 0x65, 0x62, 0x0e, 0xd2, 0x72, 0xa3, 0x0a, - 0x1d, 0x90, 0xeb, 0x8e, 0xdd, 0xf7, 0x58, 0xdf, 0x8f, 0x65, 0xec, 0x3b, - 0x5c, 0x18, 0x8c, 0xb6, 0x22, 0x4a, 0x7d, 0x63, 0x90, 0xc0, 0x9c, 0x3c, - 0x9c, 0x65, 0x04, 0x7e, 0xc3, 0xe7, 0xa5, 0x12, 0x57, 0x96, 0x63, 0x31, - 0xeb, 0xe6, 0x29, 0x9e, 0xdc, 0xab, 0x30, 0x3b, 0x18, 0x58, 0x38, 0x28, - 0x20, 0x40, 0x3e, 0x01, 0x56, 0x41, 0xe2, 0xf2, 0x3f, 0x7b, 0xf3, 0x37, - 0x60, 0x53, 0x14, 0xd6, 0x75, 0xe8, 0xb1, 0xfe, 0xb7, 0x06, 0x1b, 0x7c, - 0x36, 0x36, 0xcc, 0x88, 0x94, 0xf5, 0x03, 0x89, 0x09, 0x42, 0x3e, 0x8b, - 0x8d, 0x58, 0xfd, 0x5c, 0xcd, 0x2f, 0xd9, 0x96, 0xcd, 0xd7, 0x3d, 0x9d, - 0x88, 0x13, 0x91, 0x16, 0x31, 0x38, 0xaf, 0x47, 0xb5, 0xbd, 0x88, 0x48, - 0xfd, 0x2f, 0x39, 0xa5, 0xe0, 0x59, 0x31, 0x52, 0x99, 0xbf, 0x23, 0x72, - 0x3b, 0xf5, 0xbb, 0xd7, 0xdd, 0xda, 0xa6, 0x26, 0x0d, 0x4c, 0x8d, 0x13, - 0x93, 0xda, 0x52, 0x43, 0x22, 0x02, 0xa1, 0x66, 0xb8, 0x71, 0x7c, 0xad, - 0x57, 0x9b, 0x65, 0x53, 0x2b, 0x32, 0xa7, 0x04, 0xd1, 0x0c, 0x8e, 0x34, - 0xf2, 0xcf, 0x88, 0x3c, 0xd2, 0xd1, 0x9f, 0x17, 0xfd, 0x4e, 0x2d, 0xb7, - 0x62, 0xac, 0x9d, 0xef, 0xb4, 0x96, 0x1b, 0x52, 0x94, 0x16, 0x69, 0xa6, - 0x65, 0xa4, 0xac, 0x04, 0x94, 0x4f, 0x89, 0xd3, 0x7d, 0xde, 0xe1, 0xba, - 0xd3, 0x2d, 0x8f, 0x05, 0x19, 0xa2, 0x89, 0x92, 0x3f, 0x10, 0xce, 0xb0, - 0xf9, 0x5e, 0xfb, 0x3c, 0xb6, 0x59, 0xe5, 0xab, 0xb0, 0x21, 0x7d, 0xb3, - 0x57, 0xf2, 0x82, 0xbf, 0x63, 0xce, 0x0c, 0x00, 0x16, 0x7e, 0xdb, 0x22, - 0x0c, 0xb1, 0xa4, 0x72, 0x49, 0x1f, 0xb4, 0x4f, 0x51, 0xb0, 0xe9, 0xba, - 0x69, 0xb7, 0x6a, 0xc8, 0xc4, 0x57, 0xfc, 0x94, 0xa1, 0xf4, 0x93, 0xd9, - 0x02, 0xe3, 0xde, 0xde, 0x7f, 0x6a, 0x19, 0x52, 0xa2, 0xd0, 0xc1, 0x87, - 0x40, 0xe3, 0x00, 0x52, 0xf6, 0x04, 0x85, 0x64, 0xc5, 0xd5, 0xa7, 0x98, - 0x36, 0xea, 0x7c, 0xce, 0x84, 0x32, 0x93, 0x1c, 0x95, 0x06, 0x38, 0x4b, - 0xe1, 0xa3, 0xf0, 0x22, 0x4f, 0x3e, 0xa4, 0x0c, 0x19, 0x2f, 0x70, 0x0b, - 0x50, 0x8a, 0x9a, 0x2d, 0x87, 0x5f, 0xc6, 0xa8, 0x6c, 0xa8, 0xd7, 0xa1, - 0x46, 0x02, 0xe8, 0x22, 0x4d, 0x01, 0x29, 0x19, 0x7c, 0xf2, 0xdf, 0xcd, - 0xdc, 0xbb, 0xce, 0x11, 0x93, 0x4a, 0xca, 0x95, 0x58, 0x24, 0x6d, 0x7f, - 0xf3, 0xd2, 0xdd, 0x16, 0xcb, 0x1f, 0x3c, 0xeb, 0xce, 0x8a, 0x24, 0x44, - 0xb4, 0xfb, 0x12, 0x46, 0x61, 0x12, 0x32, 0x91, 0xab, 0x27, 0x49, 0x3f, - 0x31, 0x13, 0xae, 0xba, 0x4f, 0x6f, 0x0a, 0x39, 0x7a, 0xc6, 0x9e, 0x43, - 0x1f, 0x34, 0x56, 0x00, 0xf1, 0xad, 0x68, 0x63, 0xa5, 0x51, 0x03, 0x09, - 0x38, 0xd9, 0x1e, 0xdf, 0xd8, 0x39, 0xd7, 0x07, 0x6c, 0x77, 0x51, 0xb8, - 0x6a, 0xf6, 0x82, 0x3b, 0x46, 0x58, 0xd5, 0x69, 0xd1, 0xf7, 0xf3, 0xef, - 0xb8, 0xf7, 0xb8, 0x7f, 0xc7, 0x7f, 0x8f, 0xeb, 0xb1, 0xe6, 0x3d, 0x1a, - 0xcb, 0x0a, 0xc7, 0x0d, 0x3a, 0xbe, 0xb3, 0x2d, 0x00, 0x52, 0x89, 0x85, - 0xf2, 0x08, 0x50, 0xad, 0xfc, 0x50, 0xa0, 0x25, 0x0f, 0x02, 0x78, 0x82, - 0x9f, 0xf2, 0x56, 0x86, 0x81, 0x9b, 0xb9, 0x9e, 0x49, 0x23, 0xe2, 0xd3, - 0x3b, 0x28, 0x9c, 0x32, 0x18, 0x07, 0xcf, 0x32, 0xbc, 0x2f, 0xe4, 0xa0, - 0xbc, 0x68, 0x08, 0x94, 0x01, 0xe1, 0x0f, 0x33, 0x43, 0x27, 0xf1, 0x68, - 0x8f, 0xb0, 0xcf, 0x3e, 0x27, 0x2d, 0xd4, 0xd3, 0x2f, 0x3e, 0x17, 0xa9, - 0x49, 0xa6, 0x08, 0x9a, 0x04, 0xd0, 0xc8, 0xa4, 0xb9, 0xd6, 0x98, 0xdd, - 0x37, 0xe2, 0x9c, 0xe7, 0x3c, 0x49, 0xc0, 0x58, 0xd4, 0x4e, 0x8e, 0x5f, - 0xc7, 0xf5, 0x7e, 0x6f, 0xcb, 0x3c, 0x28, 0x4b, 0x58, 0x78, 0x00, 0xa0, - 0x27, 0x94, 0x12, 0x87, 0x81, 0x67, 0x14, 0x10, 0x82, 0x89, 0xc9, 0xcc, - 0x4e, 0x85, 0xdd, 0x5a, 0xeb, 0x11, 0xc9, 0x08, 0x28, 0xa9, 0x86, 0x39, - 0x8c, 0x1b, 0x08, 0x16, 0xc7, 0xfb, 0xb4, 0xd3, 0x98, 0x9f, 0xd5, 0xe8, - 0x3e, 0x41, 0x30, 0x4b, 0x2c, 0x29, 0x02, 0x4f, 0x81, 0xbf, 0xd1, 0xeb, - 0x55, 0x7e, 0xc2, 0xcb, 0x84, 0xc1, 0x4f, 0x5c, 0xac, 0x59, 0x94, 0x94, - 0xb7, 0x86, 0x7f, 0x31, 0xf6, 0xb8, 0xd7, 0x0b, 0x22, 0x7c, 0x47, 0x6c, - 0xd0, 0xa8, 0xff, 0x6f, 0x82, 0x63, 0x17, 0x6c, 0xa8, 0x09, 0x48, 0x4b, - 0xc1, 0xab, 0x50, 0xda, 0xa3, 0xaf, 0xfa, 0xe4, 0x2f, 0x7c, 0x83, 0xa4, - 0x8e, 0xc0, 0xd5, 0xec, 0x70, 0xef, 0x24, 0x8e, 0xe1, 0x2f, 0x29, 0x64, - 0xef, 0x58, 0xc2, 0xea, 0xf1, 0xe1, 0xb3, 0xce, 0xa9, 0xd4, 0x62, 0x89, - 0x96, 0x42, 0x9c, 0xa6, 0x72, 0x21, 0x2c, 0xe0, 0xef, 0x9d, 0xbd, 0x6d, - 0x7f, 0xf8, 0xa7, 0x5e, 0x0f, 0xb2, 0xcb, 0x61, 0x24, 0x51, 0x80, 0x91, - 0x02, 0x54, 0x12, 0x33, 0xfa, 0x3b, 0x2a, 0x38, 0xb7, 0x97, 0xc0, 0x5b, - 0x42, 0x8d, 0xed, 0xf8, 0xc8, 0x93, 0x96, 0x0c, 0x14, 0x72, 0xa7, 0x3b, - 0xd6, 0xa3, 0xf7, 0xf9, 0xff, 0x79, 0xd9, 0x9b, 0x63, 0x83, 0xa4, 0x08, - 0x67, 0x13, 0x48, 0xa5, 0xe3, 0x9a, 0x13, 0xee, 0x21, 0xab, 0x97, 0x69, - 0xc3, 0xd0, 0xe8, 0x6b, 0x23, 0x44, 0x23, 0x7b, 0x47, 0x0e, 0x0a, 0x52, - 0x47, 0xed, 0x2e, 0xe2, 0x5c, 0x6e, 0x75, 0x68, 0xea, 0xf6, 0x02, 0x70, - 0xf4, 0x86, 0x32, 0xe7, 0x34, 0x32, 0x11, 0xc9, 0xca, 0x85, 0x64, 0x3d, - 0x2b, 0x5a, 0x80, 0x71, 0x0c, 0x09, 0x78, 0xa6, 0x11, 0xf1, 0x10, 0x4a, - 0xac, 0x11, 0x03, 0x32, 0x7c, 0xca, 0x80, 0xba, 0x99, 0x92, 0xb2, 0xdd, - 0x92, 0xfd, 0x33, 0xfb, 0x69, 0x6d, 0x45, 0x0b, 0x76, 0xb7, 0x03, 0x0c, - 0x84, 0xa6, 0x52, 0x89, 0x22, 0x85, 0xe9, 0xc2, 0x14, 0xe4, 0x4d, 0xa5, - 0x39, 0xe5, 0x05, 0x09, 0x81, 0x97, 0x0e, 0x52, 0x57, 0xc7, 0x3e, 0x8b, - 0xec, 0x3d, 0x3d, 0x41, 0xb9, 0x41, 0x23, 0xb2, 0x61, 0x91, 0x9c, 0x25, - 0x02, 0xe5, 0x1c, 0xa1, 0x3f, 0xb1, 0xab, 0x31, 0x45, 0xe8, 0x97, 0xdb, - 0x97, 0x9d, 0x19, 0x40, 0x86, 0x5a, 0x43, 0x09, 0x2b, 0xd1, 0x14, 0x3e, - 0x2e, 0x5f, 0xa6, 0xaa, 0x2c, 0x85, 0x10, 0x68, 0x20, 0x91, 0xf9, 0xc4, - 0xa7, 0x3f, 0x98, 0x37, 0xa7, 0xe7, 0x82, 0xff, 0x18, 0xb4, 0x38, 0x71, - 0x43, 0x00, 0x09, 0x59, 0x82, 0x4d, 0xad, 0xbf, 0x59, 0xe7, 0x71, 0x0b, - 0x09, 0x98, 0x34, 0xd8, 0xee, 0xe4, 0x19, 0x48, 0x37, 0x6a, 0x51, 0x95, - 0x60, 0x0a, 0xb4, 0x39, 0x05, 0xc3, 0x21, 0x94, 0x8a, 0x18, 0x0a, 0x11, - 0xa0, 0x04, 0x4c, 0xde, 0xad, 0xe3, 0x5c, 0xe3, 0x5e, 0x5b, 0xa3, 0xba, - 0x46, 0xbf, 0x63, 0xa1, 0x50, 0xf2, 0x0d, 0xe5, 0xd5, 0x4f, 0xc8, 0xf1, - 0x5c, 0xde, 0xa2, 0x83, 0xec, 0xcf, 0x3d, 0x5e, 0xfe, 0x56, 0xf3, 0xad, - 0xe5, 0x57, 0x92, 0xc9, 0xa5, 0x25, 0x4d, 0x97, 0x22, 0x11, 0x67, 0x62, - 0x4b, 0x46, 0x58, 0x97, 0xd0, 0x13, 0x6f, 0x7f, 0xa7, 0xe5, 0x62, 0xf3, - 0xc3, 0x00, 0x95, 0x48, 0x69, 0x25, 0x81, 0x7f, 0xc1, 0xee, 0xb0, 0x58, - 0x6d, 0x79, 0x9f, 0x53, 0x9e, 0xa8, 0xbb, 0x93, 0x90, 0xc2, 0x08, 0x0a, - 0x22, 0x53, 0xab, 0x53, 0x26, 0x7c, 0xbc, 0x26, 0x9f, 0xe2, 0xc8, 0x78, - 0x75, 0x3b, 0x08, 0x54, 0xf2, 0x86, 0x44, 0x63, 0x6c, 0x48, 0x9c, 0x67, - 0xee, 0x3e, 0x01, 0xf0, 0xb6, 0x6c, 0x8d, 0xf9, 0x22, 0xb8, 0xbe, 0xfe, - 0xb5, 0x7d, 0xda, 0x99, 0x7b, 0xa5, 0x3c, 0x60, 0x8d, 0x24, 0xb1, 0x40, - 0xf7, 0x26, 0x7e, 0x2b, 0x40, 0x4f, 0x67, 0x4d, 0x90, 0xe6, 0x43, 0x7c, - 0x53, 0x58, 0x2e, 0x09, 0x3d, 0x89, 0xff, 0xb7, 0x76, 0x5f, 0x8d, 0xf9, - 0x85, 0x92, 0xe1, 0xbb, 0x50, 0x3b, 0x5e, 0x50, 0x46, 0x7d, 0xa3, 0x1a, - 0x00, 0x7d, 0x85, 0xd1, 0xce, 0x62, 0x79, 0xf3, 0xaa, 0x93, 0x23, 0x39, - 0xb8, 0x2a, 0x09, 0x13, 0x94, 0x32, 0x7e, 0x2e, 0xbb, 0x7d, 0x05, 0x4d, - 0x25, 0x05, 0x53, 0xfd, 0x4d, 0xb8, 0x69, 0xe3, 0xb1, 0x6a, 0x8f, 0x44, - 0x20, 0x46, 0x4e, 0x7e, 0x07, 0x57, 0x7e, 0xe5, 0xad, 0xfb, 0xcf, 0x79, - 0xed, 0xd7, 0x09, 0x27, 0xaa, 0x0f, 0x5f, 0xd3, 0xd1, 0x0c, 0xc0, 0xc9, - 0x95, 0xa9, 0x63, 0x0e, 0xe0, 0x43, 0xa4, 0x77, 0x40, 0xfc, 0xda, 0xa7, - 0x7d, 0xb6, 0xd4, 0x35, 0xd9, 0x9e, 0x4f, 0x62, 0x45, 0x2b, 0x62, 0x84, - 0x86, 0xe7, 0x07, 0x70, 0xbb, 0xef, 0x7e, 0x0b, 0x7e, 0xe3, 0xa3, 0xc0, - 0x74, 0xc0, 0x1d, 0xf0, 0xe5, 0x18, 0x00, 0x08, 0x83, 0x40, 0xe5, 0xca, - 0x58, 0x4b, 0x7c, 0x36, 0x76, 0x29, 0x65, 0x05, 0x49, 0xf7, 0xdf, 0xe5, - 0x44, 0xe7, 0x71, 0x74, 0xe7, 0x83, 0x7b, 0x53, 0x0d, 0x3a, 0x78, 0xf2, - 0x40, 0x22, 0x11, 0x4b, 0x97, 0x88, 0xae, 0xec, 0xa7, 0x3f, 0x21, 0x5a, - 0x81, 0x9e, 0x9f, 0x4b, 0x7d, 0xb1, 0xa2, 0xa7, 0x08, 0x96, 0x70, 0x96, - 0xc6, 0xb1, 0x6a, 0x36, 0xe2, 0x15, 0x75, 0xb0, 0xca, 0x95, 0x7e, 0x45, - 0xc0, 0x45, 0xb2, 0xb4, 0x6b, 0xc3, 0x0c, 0x28, 0x25, 0x64, 0xfe, 0xa2, - 0x15, 0x03, 0x3f, 0xaa, 0xde, 0xf2, 0xb5, 0xed, 0xe4, 0x03, 0x38, 0x37, - 0xb2, 0x48, 0xa0, 0x8b, 0x60, 0x28, 0xcb, 0x2d, 0xa7, 0x84, 0x2e, 0x2d, - 0xe3, 0x0a, 0x37, 0x36, 0xca, 0x1a, 0xaa, 0x03, 0xb4, 0x2f, 0xe5, 0xad, - 0xf7, 0xc9, 0x0f, 0x8b, 0xab, 0x47, 0x66, 0xcb, 0x99, 0x83, 0x52, 0xc7, - 0xa0, 0x96, 0x2a, 0xc3, 0x17, 0xbf, 0xe0, 0x62, 0xde, 0xe2, 0x1d, 0x21, - 0x0b, 0x4f, 0x1d, 0x0c, 0x97, 0xda, 0x8b, 0xc2, 0x9e, 0xea, 0x1e, 0xd5, - 0x88, 0x1b, 0x4e, 0xec, 0xca, 0xd0, 0x08, 0x0d, 0x20, 0x65, 0x29, 0x48, - 0x7c, 0xc0, 0x9f, 0xce, 0x3a, 0xaf, 0xe2, 0x5b, 0xfd, 0xfc, 0xb7, 0x63, - 0xbd, 0x6c, 0x40, 0x10, 0xab, 0xda, 0x72, 0xce, 0x88, 0xca, 0x1f, 0x6d, - 0x49, 0x02, 0x76, 0x22, 0x5a, 0x27, 0xe2, 0x82, 0xa3, 0x9f, 0xdb, 0xdd, - 0xa6, 0xfc, 0x09, 0xd6, 0xce, 0xec, 0xde, 0xe9, 0x34, 0xe0, 0x76, 0xa3, - 0x33, 0x29, 0x83, 0x4d, 0xd0, 0x39, 0x04, 0x19, 0xdf, 0xb5, 0x4f, 0xd8, - 0x29, 0xe5, 0x21, 0xba, 0x63, 0x67, 0x73, 0x40, 0x13, 0xbc, 0x3d, 0x39, - 0x94, 0x21, 0x28, 0x43, 0x59, 0x13, 0xe2, 0x7b, 0xdc, 0xb8, 0x0e, 0x75, - 0xdd, 0x96, 0x7d, 0x63, 0x52, 0xd9, 0x9b, 0x8d, 0xb1, 0xa0, 0x8f, 0x81, - 0x7e, 0x5f, 0x67, 0xfe, 0xae, 0x20, 0x58, 0xb3, 0x54, 0xe1, 0x9c, 0x98, - 0x3b, 0xed, 0x13, 0x2c, 0x47, 0x91, 0x38, 0x05, 0x0c, 0x24, 0x20, 0x03, - 0xc7, 0x83, 0x2f, 0xde, 0x76, 0xd3, 0xa1, 0xfc, 0x83, 0x65, 0xc2, 0xae, - 0xc6, 0x7f, 0xda, 0x0d, 0x68, 0xa1, 0x03, 0xce, 0x54, 0x75, 0x97, 0xe1, - 0x46, 0x7c, 0xd7, 0x9b, 0x9e, 0x0f, 0xed, 0x17, 0xb1, 0xf9, 0x7a, 0x86, - 0xc5, 0x54, 0x8b, 0xd3, 0x92, 0xac, 0x91, 0x83, 0x1e, 0xa2, 0x81, 0xcc, - 0xe8, 0x94, 0x3e, 0xaf, 0x17, 0x33, 0x37, 0x2f, 0x2b, 0x1f, 0x88, 0x75, - 0x27, 0x84, 0xda, 0x89, 0x72, 0x10, 0x9a, 0x13, 0x03, 0x19, 0x9e, 0x69, - 0x1f, 0x03, 0x3a, 0xb4, 0x2b, 0xaf, 0x1c, 0xf4, 0x4e, 0xf4, 0x26, 0xc6, - 0x14, 0x02, 0xf4, 0x4c, 0x2d, 0x90, 0xe5, 0x8c, 0x95, 0x8f, 0xf5, 0xf9, - 0x1e, 0x38, 0x1f, 0xc7, 0x57, 0x45, 0xdd, 0xab, 0x14, 0x24, 0x1e, 0x16, - 0xf3, 0x1c, 0x7b, 0xeb, 0x60, 0x3e, 0xa9, 0x75, 0xe4, 0xbd, 0xe7, 0xa7, - 0x66, 0x72, 0x2e, 0xec, 0xa1, 0x6a, 0x9d, 0xc9, 0x3c, 0x79, 0xb4, 0x07, - 0x95, 0x48, 0x88, 0x21, 0xa1, 0xf5, 0x33, 0x26, 0x34, 0x54, 0xf3, 0xc5, - 0x44, 0x1a, 0x61, 0xea, 0x27, 0x82, 0x84, 0xe4, 0x7e, 0xa9, 0x06, 0x1e, - 0x49, 0xc7, 0x1a, 0x62, 0x8c, 0x84, 0x33, 0x79, 0xcd, 0xa5, 0xb3, 0xb9, - 0x4f, 0x1d, 0x1f, 0xab, 0x89, 0x3b, 0xbc, 0x08, 0x64, 0x78, 0x31, 0xd1, - 0x9d, 0x5e, 0x60, 0x8a, 0x08, 0xf7, 0x31, 0xe7, 0xb3, 0x88, 0x65, 0x73, - 0x01, 0x46, 0x02, 0x8c, 0xcc, 0xa4, 0x8a, 0x07, 0x2e, 0x59, 0x5f, 0x3c, - 0x16, 0xcc, 0xda, 0x51, 0x69, 0x04, 0x20, 0xd5, 0x14, 0x8c, 0x26, 0x34, - 0xbe, 0x39, 0x00, 0x8c, 0x60, 0xc6, 0x83, 0xd0, 0x93, 0x99, 0xf7, 0x29, - 0x81, 0x0c, 0x31, 0x21, 0x0f, 0x32, 0xc7, 0x00, 0x48, 0x25, 0x9f, 0xb3, - 0x84, 0x89, 0xe1, 0x3e, 0x90, 0xf8, 0x0d, 0x66, 0x4e, 0xed, 0xc5, 0x3e, - 0xd3, 0x14, 0xce, 0x55, 0x3e, 0xf6, 0x0d, 0xc5, 0x6d, 0xe3, 0xad, 0x68, - 0x8a, 0x07, 0x19, 0xf1, 0x8a, 0xca, 0x28, 0xf3, 0x6b, 0x54, 0x31, 0x97, - 0x8c, 0xf2, 0x90, 0xc2, 0x17, 0xef, 0x13, 0x63, 0x8d, 0xbd, 0x29, 0x8a, - 0x46, 0x48, 0x63, 0xe5, 0xa5, 0x65, 0xf8, 0x19, 0x92, 0xc5, 0x6d, 0x3a, - 0x95, 0xd9, 0xce, 0xdc, 0x03, 0x01, 0x9c, 0x28, 0x55, 0x32, 0x49, 0x24, - 0x0f, 0x39, 0x5d, 0x66, 0x55, 0xac, 0x5b, 0x4d, 0xc3, 0xa7, 0xe7, 0x70, - 0x9c, 0x57, 0x42, 0xbc, 0x95, 0xa6, 0xa2, 0xc0, 0xa2, 0x4f, 0x64, 0xef, - 0x38, 0x20, 0xce, 0x2a, 0x0b, 0xf1, 0x74, 0x7f, 0x6f, 0x94, 0xf7, 0xac, - 0xa0, 0xaf, 0xd3, 0x97, 0xbc, 0xb5, 0x8a, 0x81, 0x18, 0xd8, 0x74, 0x28, - 0x50, 0xf9, 0xfe, 0xdb, 0x69, 0x9a, 0xfc, 0xb5, 0x3a, 0xbc, 0xa2, 0x89, - 0x74, 0xb3, 0x92, 0xf0, 0x05, 0x5f, 0xde, 0xd1, 0x0b, 0xea, 0xc1, 0x23, - 0x31, 0x87, 0xed, 0x24, 0x67, 0x38, 0x00, 0x3f, 0x38, 0xde, 0xba, 0x70, - 0xbc, 0x57, 0x90, 0x30, 0xa0, 0x66, 0x32, 0x53, 0x43, 0xb2, 0x78, 0x50, - 0xf3, 0x28, 0x06, 0xf9, 0x94, 0xba, 0x7b, 0xbd, 0xf6, 0x7b, 0x6f, 0xfd, - 0xce, 0x5f, 0xae, 0xc3, 0x1c, 0x3f, 0x4b, 0x66, 0x25, 0xa2, 0x27, 0x49, - 0xe6, 0xed, 0x0a, 0x22, 0x84, 0xeb, 0x22, 0xf8, 0xf6, 0xb3, 0xf1, 0xdf, - 0x9b, 0xa7, 0x17, 0x07, 0x28, 0xd3, 0xc4, 0x93, 0x46, 0x41, 0x06, 0x19, - 0x39, 0x04, 0x7c, 0x41, 0x16, 0x66, 0xf0, 0x7b, 0x0a, 0x6e, 0x3b, 0xc7, - 0x3a, 0xc9, 0x3e, 0x3d, 0x5d, 0x2f, 0x4d, 0xdd, 0xea, 0x14, 0x0e, 0x50, - 0x22, 0x8e, 0x2e, 0x1f, 0x64, 0x4f, 0x0d, 0x58, 0x07, 0x37, 0x5d, 0x84, - 0x45, 0x69, 0xdc, 0x43, 0xa8, 0x18, 0xd3, 0x92, 0x32, 0x42, 0x68, 0x1a, - 0xb1, 0x4b, 0x16, 0x70, 0xab, 0x94, 0xa2, 0x89, 0xd6, 0xdc, 0xf7, 0x5f, - 0xe0, 0x0f, 0xf6, 0xd7, 0x3a, 0xe6, 0x1e, 0x46, 0xca, 0x30, 0xa9, 0xa1, - 0x90, 0x32, 0xa0, 0x5f, 0x88, 0x27, 0x41, 0x1f, 0xa8, 0x34, 0xd9, 0xe7, - 0x49, 0x27, 0x68, 0xba, 0x5b, 0x1d, 0x75, 0x13, 0xc9, 0x9c, 0x96, 0x4f, - 0xc1, 0x37, 0x39, 0xdf, 0xae, 0x4d, 0x6b, 0xe4, 0x84, 0x63, 0x11, 0xf1, - 0x50, 0x08, 0xf8, 0xc8, 0x50, 0xb1, 0xbe, 0xdf, 0x52, 0x69, 0x89, 0x8a, - 0x9d, 0xb9, 0x96, 0x30, 0x23, 0x22, 0x18, 0x43, 0x8a, 0xf4, 0xbb, 0x46, - 0xed, 0x72, 0x67, 0x08, 0x5c, 0x7a, 0x9f, 0xa8, 0x18, 0xf8, 0xc1, 0x21, - 0x34, 0x67, 0xe9, 0xfa, 0xad, 0xc8, 0x53, 0x18, 0x50, 0x12, 0xa1, 0x21, - 0x33, 0x92, 0xf0, 0x89, 0xf5, 0x65, 0xfc, 0xba, 0x8a, 0x18, 0xba, 0xba, - 0x66, 0x06, 0x3e, 0x64, 0x68, 0xb6, 0x83, 0xcf, 0x79, 0x75, 0xf9, 0x90, - 0x86, 0x4b, 0xc5, 0x5f, 0xff, 0x6c, 0xa3, 0xab, 0x8a, 0x43, 0x28, 0xf4, - 0x7d, 0x4e, 0x69, 0x13, 0x30, 0x32, 0xea, 0xf4, 0xea, 0xd8, 0xc7, 0xf4, - 0xcb, 0xff, 0x4b, 0xd3, 0x8a, 0x36, 0x0c, 0xf0, 0x1f, 0x01, 0x4c, 0xd7, - 0x41, 0x20, 0xc4, 0xde, 0xc7, 0xa5, 0x76, 0xf0, 0x65, 0xf3, 0x03, 0x10, - 0x8e, 0xda, 0x7f, 0xd9, 0x89, 0x47, 0xce, 0x11, 0x88, 0x45, 0x36, 0x9d, - 0x4c, 0x65, 0x5b, 0xea, 0xc5, 0xe5, 0x87, 0x75, 0x29, 0xd4, 0xff, 0x15, - 0x4f, 0x7a, 0x3c, 0x4d, 0x07, 0x62, 0x8e, 0xab, 0x73, 0x26, 0x50, 0x02, - 0xc6, 0x11, 0xf3, 0x34, 0x3b, 0x82, 0x52, 0xb1, 0xe1, 0x64, 0x9e, 0x9b, - 0xff, 0x10, 0x40, 0x08, 0x0e, 0x34, 0x01, 0x33, 0x82, 0x6f, 0x4b, 0x46, - 0x80, 0x42, 0xb2, 0xb1, 0x45, 0xdd, 0xed, 0x99, 0x39, 0x18, 0x28, 0xbc, - 0xa8, 0xe1, 0xf1, 0x90, 0x4b, 0xfa, 0xf2, 0x6a, 0x9c, 0xa2, 0x06, 0xdc, - 0xfe, 0x97, 0x20, 0x51, 0x24, 0xb8, 0x07, 0x1a, 0x1c, 0x7d, 0xa4, 0x7b, - 0x68, 0x93, 0x9e, 0x2e, 0x4c, 0x3b, 0xd9, 0xae, 0x77, 0x97, 0x40, 0xd2, - 0xd4, 0x92, 0x51, 0x39, 0x2a, 0x19, 0x10, 0x05, 0x91, 0xfc, 0x7f, 0x96, - 0x34, 0x80, 0x4b, 0x8c, 0x0c, 0x61, 0x46, 0x8f, 0xd1, 0xf7, 0x62, 0xad, - 0x6a, 0xfd, 0x78, 0xb9, 0x9d, 0x45, 0x8c, 0x95, 0x44, 0x21, 0xdc, 0x35, - 0xa9, 0x92, 0x31, 0xb5, 0x06, 0x1a, 0x79, 0x46, 0x16, 0x28, 0x51, 0x4b, - 0x48, 0x56, 0x68, 0x31, 0x45, 0x46, 0xcd, 0x05, 0x0a, 0x18, 0x7c, 0x9f, - 0x64, 0xec, 0xb6, 0x6a, 0xf4, 0xed, 0x0f, 0x86, 0xd0, 0x28, 0x24, 0x5e, - 0x86, 0x1c, 0xa5, 0x61, 0x03, 0x95, 0x39, 0x40, 0x17, 0xf9, 0x82, 0xd3, - 0xf8, 0xc5, 0x2a, 0x8c, 0xde, 0x73, 0xc3, 0x7a, 0x7b, 0x91, 0x61, 0x86, - 0x83, 0x09, 0xcf, 0xb0, 0x74, 0x3e, 0x7a, 0xc7, 0xe6, 0x76, 0x47, 0x2a, - 0xf4, 0x7c, 0xe7, 0x0c, 0xc2, 0x63, 0x64, 0xc6, 0x57, 0x80, 0x17, 0x08, - 0x14, 0x17, 0xe7, 0x21, 0xdb, 0x66, 0x54, 0x18, 0x88, 0x0b, 0x65, 0x42, - 0x97, 0x46, 0x7d, 0x91, 0x26, 0x5e, 0x59, 0x3c, 0x48, 0x06, 0xbc, 0x20, - 0x66, 0x89, 0x39, 0x64, 0xd6, 0x5a, 0x7a, 0x05, 0x10, 0x89, 0x44, 0x4a, - 0x73, 0x98, 0x3e, 0x9f, 0xb0, 0xc3, 0x3c, 0xea, 0x77, 0x95, 0xc6, 0xc5, - 0x5b, 0x08, 0x07, 0x2b, 0xaa, 0x63, 0x25, 0x4c, 0xf6, 0xa7, 0x08, 0xf9, - 0x42, 0x4c, 0xc7, 0xa9, 0xe9, 0x58, 0x0a, 0x9e, 0x4a, 0x0e, 0xf6, 0x2b, - 0xf5, 0x35, 0x20, 0x55, 0x65, 0x46, 0xda, 0x32, 0xdc, 0xb5, 0x29, 0x4a, - 0x79, 0x2a, 0x1e, 0x20, 0xa3, 0x3f, 0xfb, 0x5c, 0xf7, 0xce, 0x5f, 0x3b, - 0x96, 0xb9, 0x16, 0xf4, 0x6f, 0xe9, 0x5b, 0x63, 0x86, 0x85, 0xbe, 0x7f, - 0xe8, 0x3b, 0x30, 0xdb, 0xc0, 0xd4, 0xeb, 0xf8, 0xcd, 0x40, 0x4e, 0x72, - 0x1f, 0x37, 0x74, 0xb7, 0x28, 0x93, 0xe2, 0x0d, 0xdf, 0x5b, 0x9f, 0xa0, - 0x1b, 0x82, 0x13, 0x2d, 0x52, 0x3b, 0xdd, 0x17, 0x32, 0x93, 0x36, 0x82, - 0x5f, 0x68, 0x3c, 0x1d, 0xf3, 0x54, 0xcd, 0x2e, 0x24, 0x5f, 0xcb, 0x73, - 0x5e, 0xf1, 0x31, 0xf7, 0xb5, 0x3d, 0x6c, 0x43, 0x65, 0x2a, 0x8d, 0xf9, - 0x05, 0xb2, 0xa4, 0x67, 0x46, 0x50, 0x65, 0x8a, 0xb0, 0xcc, 0xbf, 0xea, - 0xa5, 0x46, 0xfd, 0x39, 0xb7, 0x75, 0xa8, 0x8f, 0xd3, 0x91, 0x5a, 0x79, - 0x98, 0x2b, 0x7b, 0xa3, 0x97, 0x49, 0xa1, 0x08, 0xb4, 0x62, 0x97, 0x58, - 0x13, 0x9b, 0xef, 0x5e, 0x7e, 0xfd, 0x23, 0xf7, 0x6f, 0xf2, 0xfc, 0x79, - 0x9f, 0x5a, 0x56, 0x33, 0x0d, 0x73, 0x67, 0x9a, 0x9b, 0xed, 0xc0, 0x30, - 0xe2, 0xa3, 0x5e, 0x12, 0x91, 0x3f, 0x68, 0x95, 0xbf, 0x77, 0xfd, 0xd4, - 0x4d, 0x8b, 0xd5, 0xf6, 0xb1, 0x4c, 0x95, 0xb7, 0x50, 0xba, 0xb5, 0xf1, - 0x06, 0x33, 0xd2, 0x9b, 0x32, 0x8b, 0xb9, 0x34, 0x4b, 0xe3, 0x4c, 0x91, - 0xdc, 0x27, 0xd7, 0xa9, 0x61, 0xe2, 0xfb, 0x41, 0xf7, 0xf6, 0xb9, 0x67, - 0x3d, 0x38, 0x5a, 0xc7, 0xf5, 0x62, 0xae, 0x9b, 0x86, 0x65, 0x29, 0xa8, - 0x90, 0x03, 0x3a, 0x27, 0x48, 0xe2, 0x63, 0x0c, 0xaf, 0xa8, 0x26, 0xfd, - 0x8f, 0xee, 0xb7, 0x22, 0xa9, 0x97, 0x6d, 0x8b, 0xe7, 0x56, 0x56, 0xec, - 0x50, 0x9d, 0x18, 0x20, 0x59, 0xc8, 0x4c, 0x9d, 0xe8, 0xfd, 0x86, 0x6e, - 0xb9, 0xfd, 0xa6, 0x95, 0x30, 0x02, 0xa9, 0x4b, 0xb0, 0x83, 0x51, 0x8f, - 0x6d, 0x00, 0x75, 0xd1, 0x37, 0x85, 0x47, 0xec, 0x75, 0xb3, 0xab, 0xb3, - 0xf4, 0xd3, 0x62, 0x2d, 0x95, 0x0f, 0xe6, 0xd6, 0xbb, 0x49, 0xc2, 0x08, - 0x77, 0x4b, 0x91, 0x18, 0xc2, 0xb3, 0x90, 0x99, 0x90, 0x81, 0x2b, 0xc9, - 0xba, 0x79, 0xe3, 0xca, 0x1b, 0x71, 0x5a, 0x6d, 0xbc, 0xd9, 0x98, 0x92, - 0xba, 0x7b, 0xe5, 0xeb, 0x9b, 0x29, 0xde, 0x6e, 0x85, 0x20, 0x10, 0x82, - 0xb0, 0x0a, 0x73, 0x3a, 0xd1, 0xf6, 0x58, 0x5a, 0xd7, 0xc6, 0xb6, 0x29, - 0x42, 0xca, 0x32, 0x3b, 0x04, 0xa2, 0xd4, 0x09, 0x93, 0xf6, 0xb9, 0x2a, - 0x12, 0xfb, 0x52, 0x22, 0xfc, 0xbe, 0x66, 0xb3, 0x71, 0xd1, 0xdc, 0xe6, - 0xf5, 0xd4, 0x09, 0xea, 0xd5, 0x57, 0x35, 0x1d, 0x00, 0x09, 0x44, 0xcc, - 0x94, 0x65, 0x4a, 0x52, 0xee, 0x44, 0xb5, 0x26, 0xe3, 0x8c, 0xef, 0x61, - 0x65, 0x73, 0x37, 0xed, 0x4b, 0x8c, 0xa4, 0x08, 0x32, 0x87, 0x21, 0xd1, - 0x26, 0xad, 0xbf, 0xb4, 0xf6, 0x4e, 0x57, 0x4e, 0x53, 0xa2, 0xed, 0x3c, - 0xdd, 0xda, 0x70, 0x93, 0xd3, 0x12, 0x9d, 0x69, 0x85, 0x02, 0x06, 0x3c, - 0x27, 0x27, 0x0b, 0xc9, 0x21, 0xe0, 0x7f, 0xf6, 0xb1, 0x38, 0xe9, 0xbd, - 0x22, 0x14, 0xd8, 0x83, 0x79, 0x36, 0x90, 0x08, 0x76, 0x50, 0xb0, 0xab, - 0xc6, 0xd6, 0x75, 0xe5, 0x32, 0x3f, 0xcf, 0xc7, 0x05, 0x7e, 0x98, 0x9b, - 0xe4, 0x1b, 0xda, 0x72, 0x06, 0xc2, 0x45, 0x5e, 0x9b, 0xf6, 0x6d, 0xcb, - 0xe7, 0x82, 0x8c, 0xc7, 0xff, 0x56, 0xdc, 0xb2, 0x2f, 0xee, 0x6d, 0xe0, - 0xd3, 0x5d, 0x87, 0xcc, 0x8a, 0xbc, 0xe3, 0xb5, 0xa3, 0xe9, 0xb2, 0x89, - 0x82, 0x60, 0xb7, 0x73, 0x74, 0xb0, 0xf0, 0x3b, 0x28, 0x20, 0xb0, 0x1e, - 0xe3, 0x3f, 0x8b, 0x7f, 0xf7, 0xf6, 0x43, 0x4d, 0x33, 0xb2, 0x02, 0x27, - 0x4d, 0x8d, 0x80, 0xfc, 0xd1, 0xe0, 0x24, 0xe7, 0x82, 0xdf, 0xe9, 0x1c, - 0x62, 0x34, 0xd2, 0x9b, 0xd1, 0x9a, 0x5f, 0x61, 0x6a, 0xd4, 0xd9, 0x8f, - 0x5c, 0x8e, 0xa3, 0x19, 0x6b, 0xd2, 0xda, 0x16, 0x54, 0xc4, 0xf8, 0xb1, - 0x95, 0x48, 0x3e, 0x26, 0x5c, 0x27, 0x1c, 0xf2, 0xd2, 0x0d, 0x36, 0x3f, - 0x69, 0x9e, 0x6d, 0x81, 0x86, 0x1f, 0x50, 0xcd, 0xa9, 0x76, 0x08, 0xe1, - 0xd3, 0xb0, 0xda, 0xfb, 0xd8, 0x5d, 0x93, 0xb1, 0x8e, 0x6d, 0x14, 0xed, - 0xdf, 0xf7, 0x57, 0xff, 0xff, 0x8c, 0x4d, 0x15, 0x36, 0x21, 0x87, 0x64, - 0xb0, 0x67, 0xe5, 0x89, 0x90, 0x9a, 0x26, 0x86, 0xa5, 0x2c, 0x20, 0xc3, - 0xcd, 0x4b, 0x7c, 0x6c, 0xc0, 0xfa, 0x40, 0xca, 0x08, 0x65, 0xa3, 0x40, - 0x31, 0x9a, 0x59, 0xfb, 0x46, 0xd7, 0xe7, 0xda, 0xa1, 0x46, 0x9b, 0x3c, - 0x05, 0x40, 0x11, 0x5e, 0x7e, 0xd5, 0x8e, 0x58, 0xaf, 0x43, 0x0c, 0x86, - 0x5f, 0x88, 0x37, 0x81, 0x4e, 0x7c, 0xea, 0xdf, 0x32, 0xde, 0x9d, 0x7f, - 0x43, 0x1c, 0x15, 0x96, 0x10, 0xe4, 0xe8, 0x50, 0xab, 0x6f, 0x37, 0x6a, - 0xf7, 0x6c, 0x68, 0x21, 0xda, 0x19, 0x5d, 0x2d, 0xc7, 0x9d, 0xcc, 0x88, - 0x18, 0x8c, 0xe3, 0x00, 0x68, 0x05, 0x1c, 0xa2, 0x6a, 0xc3, 0xaf, 0xbd, - 0xd1, 0xb3, 0xc5, 0xba, 0xa5, 0xb7, 0xc6, 0x91, 0xf3, 0x4f, 0x1c, 0xba, - 0x10, 0x23, 0x21, 0x2a, 0x4e, 0xd8, 0xf9, 0x72, 0xf1, 0x3a, 0x7b, 0xab, - 0x9c, 0x2d, 0xec, 0x6f, 0x2b, 0x15, 0xcb, 0x38, 0xa6, 0x60, 0x83, 0x5a, - 0x08, 0x9d, 0xed, 0x67, 0xb5, 0x27, 0x2b, 0xb9, 0x0b, 0xa0, 0x8f, 0xf6, - 0xfd, 0x68, 0x27, 0xe6, 0xbb, 0x6b, 0x53, 0x86, 0x30, 0x14, 0x1b, 0x89, - 0x51, 0x39, 0x5b, 0x38, 0x60, 0xce, 0x8d, 0x65, 0xc7, 0x81, 0xbd, 0x5e, - 0xd1, 0x08, 0xdd, 0x65, 0x15, 0x1d, 0xff, 0xfa, 0x86, 0x2d, 0x9c, 0x1d, - 0xf3, 0x01, 0xc3, 0xc3, 0x38, 0x6a, 0x9a, 0x65, 0x38, 0xc2, 0x82, 0x38, - 0xef, 0xe3, 0x70, 0xc2, 0xc9, 0xf3, 0xc3, 0x99, 0x75, 0x14, 0xa9, 0x85, - 0x21, 0x5a, 0xd2, 0xd0, 0xd0, 0x4a, 0x26, 0x31, 0xc7, 0x90, 0xee, 0x41, - 0x9a, 0x8f, 0xbf, 0x9d, 0xaf, 0x4b, 0x7b, 0x56, 0x23, 0x6e, 0xbf, 0x6b, - 0x87, 0x1a, 0x56, 0x91, 0xe5, 0xec, 0xf9, 0xbe, 0xe1, 0x51, 0xaf, 0x50, - 0xcb, 0xee, 0x4e, 0x33, 0xdf, 0xb3, 0xbe, 0x8e, 0xed, 0x7a, 0x47, 0x12, - 0x0e, 0x28, 0xa8, 0xe3, 0x41, 0xb0, 0xdb, 0x12, 0xaf, 0x10, 0x0e, 0x32, - 0x13, 0x99, 0xf9, 0xf0, 0xf5, 0x48, 0x61, 0xa2, 0xec, 0x3a, 0x8c, 0x5c, - 0xa8, 0xab, 0xef, 0x77, 0xea, 0xe2, 0x8a, 0xc8, 0xb3, 0x8d, 0xcf, 0x70, - 0xf0, 0x4d, 0x7e, 0x1c, 0xa2, 0x40, 0x6a, 0x28, 0x50, 0x3e, 0x29, 0x5f, - 0x76, 0x05, 0x99, 0x90, 0x18, 0xf8, 0x48, 0xa8, 0xb5, 0x77, 0xd9, 0xb8, - 0xd5, 0xba, 0x6a, 0x58, 0xdb, 0x83, 0x72, 0x62, 0xee, 0xfa, 0x70, 0x4b, - 0x97, 0x4b, 0x45, 0x00, 0x68, 0xc1, 0x23, 0xdc, 0x09, 0xd8, 0x3c, 0xca, - 0xb8, 0x73, 0xab, 0x6d, 0x6e, 0x27, 0x95, 0xcd, 0x42, 0x2f, 0x51, 0x2e, - 0x70, 0x65, 0x1a, 0x06, 0x67, 0x1b, 0x09, 0xf6, 0xf0, 0x02, 0x40, 0x59, - 0x3a, 0x77, 0x1b, 0x9d, 0x52, 0x3e, 0x46, 0xc7, 0x5a, 0x4e, 0xdc, 0xa6, - 0x6e, 0x3f, 0x6c, 0xdc, 0x82, 0x1b, 0x16, 0x66, 0x43, 0x23, 0x32, 0xab, - 0x27, 0x78, 0xb1, 0x5d, 0xad, 0x54, 0x48, 0x9a, 0x3e, 0x7b, 0x49, 0x60, - 0x6d, 0x2d, 0xd9, 0xbf, 0x29, 0xa1, 0xa7, 0xb7, 0x34, 0x09, 0x94, 0xa0, - 0x64, 0xbf, 0x04, 0xf7, 0x8f, 0x5b, 0x71, 0xfa, 0xa5, 0x9c, 0xdb, 0x43, - 0x1c, 0x0c, 0x66, 0x7b, 0x21, 0xd3, 0xe3, 0x69, 0x6e, 0xf8, 0x67, 0x04, - 0x3c, 0xb1, 0xa6, 0x7c, 0x57, 0xea, 0x83, 0x08, 0x45, 0x2e, 0x5d, 0x1a, - 0x8d, 0x02, 0xe4, 0xe5, 0xfc, 0x61, 0x50, 0x61, 0x13, 0x9b, 0x6e, 0x54, - 0x28, 0x0a, 0x09, 0xd7, 0x97, 0x2c, 0x72, 0x27, 0xb6, 0xa8, 0xe5, 0x43, - 0x27, 0x29, 0xcf, 0xc4, 0x05, 0x2b, 0x78, 0xed, 0x69, 0xe0, 0x20, 0x48, - 0x8c, 0x02, 0x5f, 0x40, 0x71, 0xfd, 0x39, 0xbe, 0x2f, 0xbb, 0xeb, 0xde, - 0xbd, 0xb4, 0x2f, 0x97, 0xa0, 0xcc, 0xdb, 0xed, 0x1c, 0x73, 0x5e, 0x70, - 0x32, 0xdf, 0x45, 0xcc, 0xf2, 0xbe, 0x80, 0xed, 0xf6, 0xce, 0x60, 0xeb, - 0x66, 0x4a, 0x4b, 0x17, 0x87, 0xf1, 0x8c, 0x46, 0x0b, 0x5a, 0x74, 0x13, - 0xcf, 0x51, 0x4c, 0xfa, 0x37, 0xb8, 0xe7, 0xf7, 0xf8, 0xbf, 0xb7, 0x0e, - 0xee, 0x74, 0xff, 0x3e, 0x35, 0x0c, 0x3e, 0x5b, 0x64, 0x82, 0x27, 0x63, - 0x27, 0x24, 0xa1, 0xf6, 0x0d, 0x99, 0xae, 0x3a, 0xe7, 0xe2, 0xf7, 0xdc, - 0x47, 0x45, 0x00, 0x93, 0x0d, 0x9b, 0x37, 0xba, 0xce, 0x1c, 0x80, 0x44, - 0x81, 0x4a, 0x28, 0x9a, 0xc1, 0xce, 0x2d, 0x49, 0xea, 0xe2, 0x73, 0xe7, - 0xb0, 0x4c, 0xe3, 0x0d, 0x4e, 0xf7, 0x9a, 0x5c, 0x1d, 0xa0, 0xa2, 0xf4, - 0x06, 0x12, 0x0f, 0x3d, 0x2d, 0x3f, 0xb7, 0xe5, 0xbf, 0xff, 0x60, 0x84, - 0x94, 0x7a, 0xef, 0xce, 0xd2, 0x15, 0x1a, 0x80, 0x75, 0x18, 0x28, 0xb0, - 0x9a, 0x08, 0x48, 0x43, 0x84, 0x6f, 0x83, 0xdb, 0xb0, 0xd0, 0x51, 0xf5, - 0x15, 0x19, 0xc2, 0xc2, 0x53, 0xf9, 0xbf, 0x93, 0x37, 0xfc, 0xcb, 0x3a, - 0x2f, 0x16, 0x6a, 0x54, 0x67, 0xa7, 0xa6, 0xe4, 0xd1, 0x25, 0xe0, 0x30, - 0x06, 0x13, 0x00, 0x0a, 0x2e, 0x11, 0xf1, 0x33, 0x9e, 0xb4, 0xe7, 0x1c, - 0xe3, 0x0c, 0x91, 0xfb, 0x52, 0x62, 0x46, 0xcd, 0xed, 0x77, 0x12, 0xff, - 0x15, 0x7b, 0xd7, 0x3b, 0x22, 0xcd, 0xd7, 0xf4, 0x0c, 0xe1, 0x85, 0x68, - 0x0a, 0x24, 0xd0, 0x07, 0x0e, 0xf5, 0x68, 0x5d, 0x55, 0xb5, 0xe3, 0x28, - 0x68, 0x23, 0x40, 0xec, 0x0d, 0x94, 0x8c, 0xa8, 0x09, 0x77, 0x16, 0xe5, - 0xab, 0xc5, 0xe8, 0x53, 0xe2, 0xc1, 0xce, 0x5c, 0xa9, 0x55, 0x10, 0xea, - 0x9b, 0x3e, 0x8a, 0x1d, 0xae, 0x60, 0x1d, 0x09, 0xc7, 0xf7, 0xf5, 0xca, - 0x92, 0x02, 0x5f, 0x35, 0x96, 0x74, 0x72, 0x85, 0x29, 0xf8, 0x04, 0x20, - 0x70, 0xf7, 0xb9, 0x34, 0x46, 0x3a, 0xb2, 0x92, 0x05, 0x1f, 0xa3, 0x05, - 0x5d, 0xb0, 0x10, 0x15, 0xbe, 0x01, 0x21, 0x03, 0x57, 0x46, 0xef, 0x43, - 0x80, 0x10, 0xc9, 0x78, 0xf2, 0x33, 0x39, 0xd3, 0xc0, 0x6a, 0x92, 0xd9, - 0x69, 0x22, 0xbf, 0xd9, 0xd1, 0xf4, 0xda, 0xb5, 0xe9, 0xe8, 0x65, 0x1a, - 0x60, 0x3b, 0x19, 0xbd, 0x44, 0xe8, 0x89, 0x77, 0x28, 0xb9, 0xbb, 0xcd, - 0x2d, 0xfb, 0x7b, 0xf0, 0x74, 0x32, 0xbf, 0x6f, 0x4c, 0x74, 0xf8, 0x0a, - 0x0f, 0x31, 0x24, 0x51, 0xfa, 0x01, 0x51, 0xe3, 0x8d, 0x4f, 0xfe, 0x08, - 0x8d, 0x02, 0xd8, 0x71, 0xa3, 0xfd, 0xc8, 0x19, 0x7b, 0xd1, 0x87, 0x6c, - 0x72, 0x73, 0x7f, 0x9e, 0x31, 0xb7, 0xbf, 0xc3, 0x6f, 0xcf, 0xd3, 0xd9, - 0x7a, 0x3a, 0x76, 0xc5, 0xe5, 0xb9, 0x7b, 0x20, 0x13, 0xa3, 0x2d, 0xa1, - 0x7a, 0xa2, 0x60, 0x49, 0xfd, 0xba, 0x2f, 0x2c, 0xb9, 0x48, 0x49, 0xfe, - 0x80, 0x8e, 0xc4, 0xd0, 0x96, 0x92, 0xf7, 0x0e, 0x4e, 0x6d, 0x8c, 0x32, - 0x1a, 0x3f, 0x14, 0xf8, 0x2d, 0x63, 0x44, 0x1d, 0x1d, 0xba, 0xc2, 0xcc, - 0xa6, 0x36, 0x8b, 0x48, 0xd5, 0xea, 0x8e, 0x87, 0xce, 0x0c, 0xfb, 0x46, - 0x0e, 0xb9, 0xa4, 0x68, 0x0c, 0x9f, 0xa6, 0xb3, 0xfd, 0x39, 0xad, 0x69, - 0x2e, 0x53, 0x48, 0x9c, 0x02, 0xac, 0x51, 0xd8, 0x19, 0x24, 0x82, 0x1e, - 0x24, 0x91, 0x52, 0x0f, 0xba, 0x53, 0x25, 0x07, 0x0e, 0x83, 0xe0, 0x09, - 0x72, 0xa2, 0x32, 0x2c, 0xee, 0x0e, 0x88, 0x5b, 0x42, 0x25, 0x3c, 0x69, - 0xb7, 0xc5, 0x9a, 0x07, 0xc0, 0x6b, 0x94, 0x28, 0x01, 0x39, 0x34, 0xd1, - 0xab, 0xf4, 0x32, 0x55, 0x82, 0x3c, 0x07, 0x2a, 0x11, 0x7a, 0x10, 0xc9, - 0x55, 0xaa, 0x84, 0x39, 0xd8, 0x3c, 0x4e, 0x09, 0x65, 0xe9, 0x03, 0x39, - 0xd0, 0xf1, 0x79, 0x70, 0x83, 0x07, 0x68, 0x72, 0x4f, 0x3f, 0x8e, 0x05, - 0xe1, 0x41, 0xe4, 0xf8, 0x1b, 0xc6, 0x13, 0xd4, 0x95, 0xed, 0xe5, 0x2f, - 0xab, 0x97, 0xaf, 0xa9, 0x6b, 0x59, 0x3c, 0x09, 0xe3, 0x3d, 0x26, 0xdb, - 0x04, 0x72, 0x19, 0x05, 0x28, 0x1f, 0x00, 0x67, 0x29, 0x2a, 0xe1, 0x7b, - 0xdb, 0x8b, 0xfb, 0x71, 0xde, 0x13, 0x5f, 0xe1, 0xb6, 0x91, 0x99, 0x90, - 0x99, 0x4a, 0xf8, 0xf0, 0x79, 0xe2, 0x2d, 0x76, 0x9b, 0x1e, 0x29, 0xed, - 0xf7, 0x8b, 0xa2, 0x1c, 0xf9, 0xec, 0xde, 0xf4, 0x35, 0x40, 0xca, 0x4c, - 0xf0, 0x30, 0x4a, 0xcb, 0x9f, 0x72, 0x0f, 0xfe, 0x06, 0xcd, 0x54, 0xb0, - 0x5d, 0x30, 0x59, 0xd6, 0x0d, 0x7e, 0x7e, 0x71, 0x45, 0xb6, 0xc3, 0xac, - 0x5b, 0x76, 0xa7, 0xc6, 0x67, 0x08, 0x2d, 0xd1, 0xa7, 0x32, 0x1a, 0x90, - 0x83, 0xc1, 0x55, 0x6a, 0xca, 0x9c, 0x8e, 0xb3, 0x7b, 0x8f, 0xc5, 0x05, - 0x4f, 0x91, 0xef, 0xee, 0xa5, 0x7d, 0xcd, 0xd6, 0xb0, 0xad, 0xc1, 0x94, - 0x98, 0x20, 0x04, 0x26, 0x54, 0xd6, 0x72, 0xb4, 0x28, 0xe4, 0xe4, 0xdf, - 0x43, 0x7e, 0xfd, 0x15, 0x17, 0x8d, 0xd9, 0xd4, 0x62, 0xa9, 0x62, 0x47, - 0x6d, 0x32, 0x26, 0x11, 0x41, 0x04, 0x6f, 0x50, 0x3c, 0xd2, 0x9a, 0xeb, - 0x76, 0x2e, 0x7e, 0xcf, 0xfe, 0xbc, 0xbd, 0xae, 0x5f, 0x23, 0x77, 0x86, - 0x9c, 0xf1, 0x99, 0xa7, 0x8c, 0xd9, 0x21, 0x58, 0x07, 0x9b, 0x3b, 0xfa, - 0xe4, 0xc1, 0x72, 0xd9, 0x01, 0xc5, 0xe5, 0xb8, 0xc0, 0xe8, 0xb9, 0x11, - 0x96, 0xcf, 0x39, 0x8c, 0x8a, 0x77, 0x3e, 0xd7, 0x8d, 0x27, 0xf1, 0x0b, - 0xfc, 0xa0, 0xa7, 0x7a, 0x61, 0x44, 0xcc, 0xfc, 0x15, 0xea, 0x0b, 0xf7, - 0x74, 0x9b, 0xa7, 0xda, 0x73, 0x9b, 0xec, 0x62, 0x43, 0x19, 0xbb, 0x16, - 0xba, 0x0d, 0x1e, 0xd6, 0xa1, 0x4c, 0xbd, 0x58, 0xac, 0xcf, 0x79, 0x9d, - 0xf2, 0xbd, 0xfa, 0x9c, 0xfd, 0x79, 0x81, 0x0c, 0x7d, 0xb8, 0xe9, 0xf9, - 0x99, 0x64, 0xee, 0xa9, 0xa4, 0xe9, 0xcc, 0x94, 0x09, 0x6c, 0x3d, 0x7e, - 0x59, 0x55, 0x80, 0x5e, 0xf1, 0xf5, 0xff, 0x5d, 0x74, 0xf2, 0xea, 0xe6, - 0xfa, 0xb1, 0x7a, 0x48, 0xeb, 0x72, 0x53, 0x18, 0x60, 0x14, 0xfb, 0x54, - 0x72, 0xab, 0x04, 0x13, 0xa7, 0x47, 0xfb, 0xbb, 0x21, 0x14, 0x3d, 0xd3, - 0x56, 0x53, 0x89, 0xa4, 0x6b, 0x02, 0x79, 0x83, 0x74, 0x85, 0x2e, 0x9c, - 0xbe, 0x03, 0xf4, 0x0b, 0xa2, 0xdc, 0xf2, 0xdb, 0x57, 0x2a, 0x25, 0x5b, - 0x63, 0x01, 0x67, 0x18, 0xc4, 0x1c, 0xa7, 0xfa, 0x99, 0xc2, 0x3d, 0x26, - 0xaf, 0x9b, 0x9f, 0x9f, 0x4c, 0x03, 0x73, 0xb9, 0xd7, 0x98, 0x22, 0x67, - 0x0e, 0x5c, 0x60, 0xc8, 0xf8, 0xc0, 0x54, 0x9b, 0xfb, 0x4c, 0xd9, 0x38, - 0xf8, 0xfc, 0x90, 0x78, 0x5b, 0xeb, 0xf0, 0xe9, 0x3f, 0xa5, 0x32, 0xc8, - 0x28, 0xc3, 0xf8, 0x6f, 0x63, 0x62, 0x59, 0x54, 0xf1, 0x81, 0xc9, 0xa1, - 0xf3, 0x97, 0xdf, 0x1f, 0xff, 0xfb, 0x75, 0xe3, 0xf2, 0xc3, 0x2d, 0x7c, - 0x6f, 0x41, 0xa1, 0xa0, 0x1d, 0xc8, 0x34, 0x44, 0xca, 0x15, 0x93, 0xde, - 0xda, 0xb9, 0x17, 0x93, 0x7f, 0x17, 0x5a, 0xfe, 0xe1, 0x3b, 0x94, 0x4c, - 0xd9, 0x54, 0x27, 0x08, 0x13, 0x9c, 0x04, 0x89, 0x65, 0x51, 0xee, 0x41, - 0xd7, 0x93, 0x1b, 0xef, 0x40, 0x6f, 0xac, 0xc5, 0x55, 0xe5, 0xad, 0x42, - 0xa2, 0x65, 0xf7, 0x7a, 0xc3, 0xae, 0x99, 0xc8, 0xd3, 0x44, 0x7d, 0x36, - 0x47, 0xaa, 0xe2, 0xd9, 0xe2, 0xa0, 0xcf, 0x34, 0xb7, 0xca, 0x0f, 0x2e, - 0x9f, 0xa5, 0x21, 0x07, 0xf6, 0x70, 0x32, 0x34, 0xf2, 0xcf, 0x19, 0x19, - 0xa2, 0x28, 0x4b, 0xea, 0x0f, 0x34, 0xbb, 0x4a, 0x27, 0x17, 0x35, 0xc7, - 0x27, 0x12, 0xda, 0xd7, 0x9d, 0xde, 0x30, 0x71, 0xda, 0x0c, 0x6a, 0xbe, - 0x72, 0x0c, 0x6b, 0x00, 0xa6, 0xb7, 0xc5, 0x3a, 0x43, 0xfb, 0x3b, 0xe4, - 0x20, 0x5a, 0x79, 0x10, 0xa9, 0x9e, 0xfc, 0x84, 0x48, 0xc6, 0x2b, 0xa0, - 0xa4, 0x5a, 0x90, 0x13, 0x9e, 0xf1, 0x5f, 0x0f, 0x97, 0x0e, 0x5e, 0x10, - 0xe2, 0x42, 0x1f, 0x22, 0x73, 0xe4, 0xe0, 0xa5, 0x2a, 0x0c, 0x7c, 0xae, - 0x95, 0x57, 0x95, 0xb1, 0x40, 0x76, 0xc7, 0x0d, 0xa2, 0xe0, 0x30, 0x62, - 0x77, 0x07, 0x07, 0x65, 0xd6, 0xef, 0x23, 0x8d, 0xac, 0x3c, 0xc9, 0x45, - 0xe5, 0x21, 0xe2, 0x1f, 0xee, 0x96, 0x60, 0xae, 0x6f, 0x51, 0x3f, 0x11, - 0x0c, 0xcd, 0x1a, 0x7b, 0x32, 0xa1, 0xda, 0xe3, 0x90, 0x05, 0x0a, 0xa9, - 0x27, 0xaf, 0xc8, 0x39, 0xbe, 0xe1, 0x7a, 0xf7, 0x94, 0x22, 0x1a, 0xd2, - 0xad, 0xc6, 0xa7, 0xb8, 0x77, 0x5b, 0x93, 0xe5, 0x4e, 0x50, 0x30, 0x8c, - 0x0e, 0x12, 0x0f, 0x34, 0xb6, 0x7b, 0xe0, 0xef, 0x3b, 0xbb, 0xb6, 0x92, - 0xe8, 0xfc, 0xd4, 0x1d, 0x67, 0x18, 0x8a, 0x50, 0x9a, 0x48, 0x81, 0x4f, - 0x2f, 0x54, 0x12, 0xbe, 0xdb, 0xd2, 0x67, 0xae, 0x1d, 0x2a, 0x5f, 0x8d, - 0x0f, 0x55, 0xbf, 0x40, 0x00, 0x00, 0x01, 0x0a + 0x00, 0x00, 0x01, 0x0f, 0xca, 0x00, 0x09, 0xf0, 0x77, 0x0a, 0x09, 0x20, + 0x1d, 0xff, 0x0a, 0x0b, 0x80, 0x84, 0x80, 0x00, 0x00, 0x01, 0x0e, 0x4c, + 0x10, 0x80, 0x00, 0x00, 0x01, 0x0d, 0xc1, 0xd8, 0xd4, 0x47, 0xd0, 0xaa, + 0xc4, 0x45, 0xaa, 0xb8, 0x01, 0xdf, 0x4c, 0xc1, 0x3a, 0xfa, 0x13, 0x67, + 0x6a, 0xed, 0x2c, 0x67, 0xbc, 0xef, 0xdc, 0x69, 0x99, 0xf8, 0x53, 0x97, + 0x01, 0xdc, 0xbe, 0xd8, 0x3b, 0xa2, 0x96, 0xe8, 0xa1, 0x94, 0x02, 0x57, + 0x82, 0x82, 0xd6, 0x14, 0xc7, 0x61, 0x5a, 0x00, 0x22, 0x81, 0x73, 0x33, + 0x20, 0x00, 0xa0, 0x09, 0xc0, 0x50, 0xfa, 0x06, 0xce, 0x35, 0x91, 0x8d, + 0x19, 0x0f, 0x07, 0x1e, 0x84, 0x5b, 0x3a, 0x29, 0x03, 0xad, 0x8f, 0x8a, + 0xd2, 0x22, 0xf0, 0xfc, 0x28, 0xd2, 0x95, 0x4a, 0xfe, 0x74, 0x4b, 0x23, + 0xe7, 0xd4, 0x12, 0x1f, 0x37, 0x01, 0x88, 0xf8, 0xa4, 0x09, 0x76, 0x51, + 0xae, 0xf4, 0x23, 0x6d, 0x29, 0x8c, 0x54, 0xaa, 0x2c, 0x68, 0x10, 0x7e, + 0x71, 0xbf, 0x10, 0xb4, 0x77, 0x97, 0x8b, 0xa1, 0x54, 0xd1, 0xda, 0xb5, + 0x5f, 0x61, 0xf0, 0x64, 0x64, 0x29, 0x25, 0x7d, 0x42, 0xe0, 0xff, 0x2a, + 0x83, 0x29, 0x61, 0xfc, 0xee, 0xe5, 0x11, 0x04, 0xc0, 0x43, 0xc0, 0xc4, + 0x0e, 0x18, 0x43, 0xb6, 0x08, 0x55, 0xa0, 0x22, 0xf4, 0x58, 0x01, 0xc6, + 0x43, 0x0d, 0xba, 0x04, 0x3e, 0x8e, 0x5f, 0xc1, 0x11, 0x56, 0xef, 0xd7, + 0x78, 0xe2, 0xd2, 0xdb, 0x84, 0x16, 0x76, 0xc6, 0x92, 0x15, 0xf6, 0xc2, + 0x76, 0x2f, 0xd2, 0xef, 0x46, 0x02, 0x60, 0x24, 0xda, 0x16, 0x48, 0x95, + 0xc4, 0x87, 0x81, 0xa7, 0xdd, 0xd7, 0x77, 0x56, 0xb7, 0xb5, 0x28, 0x9d, + 0x6b, 0x7b, 0xd6, 0x8b, 0x80, 0x42, 0x28, 0xb0, 0x28, 0x82, 0x50, 0x04, + 0x65, 0x1a, 0xc3, 0x79, 0x74, 0x6c, 0x3e, 0x9e, 0x69, 0x0e, 0xc1, 0xed, + 0x8d, 0xe9, 0xf0, 0xf4, 0xf8, 0xde, 0xc1, 0x62, 0x1d, 0x1f, 0x4a, 0x5d, + 0x02, 0x11, 0xfa, 0xd8, 0x10, 0xb8, 0xa0, 0xc5, 0xf5, 0x85, 0xd1, 0x19, + 0x14, 0x06, 0x21, 0x5b, 0xa5, 0x37, 0xcd, 0xf2, 0xbc, 0x3b, 0x7f, 0xe3, + 0x1c, 0x62, 0x51, 0x4b, 0x09, 0x2e, 0x48, 0x1f, 0x4e, 0x19, 0xe4, 0x90, + 0x22, 0x81, 0xf4, 0xf7, 0x16, 0x4f, 0xe5, 0x97, 0x12, 0x9b, 0x92, 0x6e, + 0xcc, 0x61, 0xd6, 0x4a, 0x59, 0x66, 0x7d, 0xc2, 0x1d, 0x33, 0x7e, 0x62, + 0x29, 0x81, 0x80, 0xb7, 0xa4, 0xcb, 0xc4, 0xc3, 0x9b, 0x1d, 0x2b, 0x00, + 0xc9, 0x78, 0x82, 0xef, 0xd7, 0xa5, 0xad, 0x08, 0x18, 0x7c, 0x97, 0x61, + 0x3e, 0xaf, 0x4e, 0x21, 0xd6, 0x5a, 0x35, 0xd6, 0xf9, 0xdf, 0x89, 0xe9, + 0x09, 0x99, 0x3e, 0x53, 0x81, 0x80, 0x21, 0xd9, 0x44, 0x7f, 0xb9, 0xe7, + 0x7d, 0x1d, 0xa6, 0xd4, 0xb6, 0x60, 0x71, 0xa3, 0x87, 0x13, 0x40, 0x7a, + 0x50, 0xac, 0x02, 0x87, 0xe3, 0x7a, 0xab, 0xce, 0x11, 0xed, 0x51, 0x97, + 0xc5, 0xf0, 0x33, 0xf5, 0x3b, 0x7e, 0x05, 0xda, 0x4d, 0x29, 0x23, 0xa7, + 0xca, 0x43, 0x0e, 0x72, 0xf0, 0x96, 0xe9, 0x95, 0x4a, 0x32, 0xb0, 0xc4, + 0xe5, 0x65, 0x73, 0xc3, 0x30, 0xea, 0xfb, 0x93, 0x04, 0x64, 0x48, 0x48, + 0x20, 0x1a, 0x8c, 0xde, 0xb0, 0x24, 0x7d, 0xd6, 0xe9, 0x5b, 0xb9, 0x0b, + 0x18, 0xb9, 0xc4, 0x4a, 0x81, 0xaa, 0xfb, 0x6b, 0x2f, 0xe6, 0x77, 0x00, + 0x17, 0xa8, 0x1f, 0x7f, 0x8b, 0xcd, 0xaf, 0xb5, 0xc1, 0x26, 0x99, 0x3f, + 0x74, 0xd9, 0x69, 0x4c, 0x4c, 0xe5, 0x8a, 0x51, 0x3b, 0x47, 0x18, 0x33, + 0x1a, 0xc5, 0xc3, 0xe1, 0xeb, 0xc7, 0x80, 0xa4, 0xb3, 0x5f, 0x22, 0x64, + 0xcc, 0x97, 0xcb, 0xdb, 0xe5, 0xc9, 0x09, 0x89, 0x65, 0xfd, 0x61, 0x76, + 0xc3, 0xf7, 0xfe, 0x7d, 0xe1, 0x70, 0x07, 0x9a, 0x17, 0x95, 0x08, 0x4d, + 0xec, 0xfb, 0x38, 0x61, 0x06, 0x1e, 0x96, 0x91, 0x19, 0x42, 0x88, 0xf1, + 0x45, 0x04, 0x69, 0x63, 0x1c, 0x99, 0xf8, 0x26, 0xf4, 0xfc, 0xf0, 0xeb, + 0x48, 0x06, 0x9d, 0xef, 0x46, 0x72, 0x41, 0xa9, 0xa5, 0xb8, 0x4a, 0xf0, + 0xd3, 0x82, 0x65, 0x88, 0x98, 0x40, 0x97, 0x4a, 0x95, 0x10, 0x52, 0xca, + 0x47, 0xec, 0x14, 0x75, 0x86, 0xd5, 0x7d, 0xf7, 0xda, 0xa5, 0x09, 0xc6, + 0x50, 0x02, 0x8f, 0xd7, 0x51, 0x42, 0x43, 0x60, 0x27, 0x67, 0xa0, 0xd6, + 0xd8, 0xcf, 0x58, 0xc5, 0x13, 0x27, 0xa2, 0x4e, 0x4f, 0xc3, 0xc2, 0x50, + 0xcb, 0x8d, 0x00, 0x53, 0x87, 0x5a, 0x6b, 0x4d, 0xb4, 0x07, 0x0b, 0x40, + 0xb3, 0xba, 0xc3, 0x14, 0xb8, 0x75, 0xda, 0x84, 0x50, 0x96, 0x12, 0xc6, + 0xd1, 0x00, 0xa5, 0xa3, 0x4c, 0x11, 0x45, 0x02, 0xc7, 0x2f, 0xe2, 0x8f, + 0xb7, 0xe9, 0xff, 0xe2, 0x48, 0x8b, 0x28, 0x1c, 0x38, 0x8c, 0x41, 0xc9, + 0xd0, 0xfa, 0x13, 0x4f, 0xfd, 0x6b, 0x72, 0xa5, 0x0e, 0xd7, 0x2f, 0x2b, + 0xee, 0x37, 0xe6, 0xb0, 0x41, 0x4d, 0x45, 0x83, 0x88, 0x6d, 0x14, 0x6d, + 0xa6, 0xb1, 0x59, 0x7d, 0x7e, 0xa7, 0x8d, 0x48, 0xc3, 0x4c, 0x80, 0x91, + 0xf0, 0x4d, 0xfc, 0xaf, 0xe6, 0xae, 0x9a, 0x24, 0xca, 0x73, 0xc4, 0x13, + 0xf8, 0x28, 0xd2, 0xbf, 0xdf, 0xc4, 0xd0, 0x4e, 0xf4, 0x3e, 0x2c, 0x60, + 0x6a, 0xd4, 0x6e, 0x44, 0x8a, 0xae, 0x09, 0x37, 0xb1, 0x98, 0xaf, 0x69, + 0xf0, 0xee, 0x6f, 0x0a, 0x55, 0x6d, 0x12, 0x7c, 0xf0, 0x08, 0x78, 0xd2, + 0x98, 0x7c, 0xdf, 0xd7, 0xa0, 0x0d, 0xf3, 0x52, 0x65, 0xf6, 0xb9, 0xfe, + 0xf3, 0x73, 0x4c, 0xe2, 0x3a, 0x27, 0x64, 0x00, 0x28, 0x54, 0x2d, 0x4a, + 0x59, 0x42, 0x43, 0xea, 0x26, 0xeb, 0x13, 0x2a, 0x5a, 0x9a, 0x35, 0xe9, + 0xe3, 0xe0, 0x3d, 0x84, 0xf0, 0x12, 0xbe, 0x84, 0x3f, 0x1c, 0xe6, 0x06, + 0xab, 0x30, 0x0d, 0xa3, 0xba, 0xe4, 0x24, 0xe0, 0x6f, 0x5c, 0xab, 0x43, + 0x9a, 0xf6, 0xf4, 0xd9, 0x74, 0x7e, 0x2c, 0x63, 0xf3, 0xd2, 0x17, 0x0b, + 0x57, 0xda, 0x1d, 0xd0, 0x47, 0x52, 0xc7, 0xc9, 0xb8, 0x14, 0x12, 0x23, + 0xc1, 0x23, 0x9b, 0x78, 0x51, 0x81, 0x7b, 0x66, 0x48, 0xbb, 0xc8, 0x7a, + 0x67, 0x84, 0x0a, 0xff, 0x82, 0xe9, 0x7e, 0xea, 0x5f, 0x5b, 0x94, 0xd6, + 0x24, 0x48, 0x3b, 0xa6, 0x25, 0x29, 0xd1, 0x92, 0x12, 0x9a, 0x5f, 0x84, + 0x3e, 0xb4, 0xe4, 0x3f, 0x15, 0xad, 0xe9, 0xec, 0xbc, 0x10, 0x7d, 0xc9, + 0xcd, 0xeb, 0x71, 0xd3, 0x79, 0x1a, 0xc2, 0xf5, 0x0d, 0x31, 0xac, 0x6a, + 0xac, 0xbc, 0x7f, 0x67, 0x43, 0x78, 0xc5, 0x23, 0x97, 0x56, 0x88, 0x3c, + 0xb0, 0x8e, 0x2c, 0x8a, 0x2b, 0x63, 0xfe, 0xb2, 0xaa, 0xb1, 0x71, 0x72, + 0x74, 0x41, 0xc3, 0x78, 0x0c, 0x5f, 0x92, 0x8d, 0x64, 0xe0, 0xf8, 0xde, + 0x09, 0x8f, 0xcd, 0x39, 0x45, 0x5a, 0x5d, 0x12, 0x6b, 0x26, 0xad, 0xfe, + 0xc0, 0x51, 0x1e, 0x00, 0xe9, 0x36, 0xf1, 0xb6, 0x74, 0x7b, 0x67, 0x6e, + 0xe2, 0xe4, 0xf4, 0x8e, 0x40, 0x87, 0xc6, 0x14, 0xcc, 0xa8, 0x25, 0x37, + 0x72, 0x0c, 0xc0, 0xf4, 0xff, 0xf4, 0x7d, 0xdc, 0xa8, 0xda, 0x68, 0xa5, + 0xbf, 0x04, 0xa3, 0x2c, 0x9f, 0xc7, 0x0a, 0x7c, 0x37, 0x86, 0xe7, 0x76, + 0x4e, 0x50, 0x79, 0xa5, 0xd1, 0x5f, 0x2e, 0x6f, 0x9a, 0x5c, 0x75, 0x73, + 0xd3, 0x7a, 0x10, 0x69, 0x45, 0xf1, 0x99, 0xca, 0x04, 0x24, 0x0a, 0x76, + 0xf5, 0xb9, 0xf7, 0xca, 0xf3, 0xfe, 0xde, 0x28, 0x70, 0x47, 0x3c, 0x35, + 0x17, 0x70, 0x21, 0x42, 0x32, 0x81, 0xfb, 0x3d, 0xc8, 0xf0, 0x35, 0xfe, + 0xe7, 0xee, 0x1b, 0x1e, 0xdd, 0xce, 0x19, 0xa2, 0x95, 0x95, 0x43, 0x2f, + 0xb2, 0x26, 0xcc, 0xbb, 0xb7, 0x8b, 0x8b, 0xff, 0x1c, 0xeb, 0x82, 0xa9, + 0x4f, 0x25, 0x58, 0xfa, 0x41, 0x22, 0x4a, 0xcb, 0x38, 0xc4, 0xff, 0x12, + 0x0d, 0xf7, 0x3b, 0xed, 0x0c, 0x7e, 0x29, 0xd3, 0x19, 0xe2, 0x2c, 0xff, + 0x8e, 0xbf, 0xe1, 0x1b, 0xc9, 0x6f, 0xac, 0x51, 0x97, 0x49, 0x68, 0x4d, + 0x20, 0x27, 0x3f, 0x11, 0xfe, 0x1e, 0x7f, 0xef, 0xda, 0x76, 0xba, 0xba, + 0xf2, 0xdb, 0x60, 0x36, 0x9a, 0xa3, 0x28, 0x89, 0xc8, 0x64, 0xb0, 0x90, + 0x79, 0xcb, 0x9d, 0x45, 0xcc, 0xdd, 0x6d, 0xf0, 0xd5, 0xb5, 0x8a, 0x64, + 0x51, 0x96, 0xcb, 0x12, 0x70, 0x0a, 0xca, 0x69, 0x34, 0x20, 0x43, 0x31, + 0x3c, 0xba, 0xb2, 0x80, 0xe1, 0xb2, 0x65, 0x79, 0x6f, 0x4e, 0x6e, 0x92, + 0x4b, 0xbf, 0x80, 0x2a, 0xb7, 0x97, 0x7f, 0xc9, 0xf5, 0xbc, 0xef, 0x1e, + 0x7f, 0xc9, 0xb6, 0x3d, 0x86, 0x4c, 0x89, 0x62, 0xac, 0x2b, 0xd0, 0x26, + 0x9d, 0xab, 0xeb, 0xfb, 0x5d, 0x4b, 0x6c, 0xe5, 0x58, 0x29, 0xb3, 0x4a, + 0x09, 0xed, 0x17, 0xf1, 0x00, 0xbb, 0x5c, 0x17, 0xc4, 0x56, 0x3b, 0xfc, + 0x13, 0x08, 0xc5, 0xcf, 0xc4, 0x14, 0x5f, 0xe2, 0xf8, 0xa5, 0xe2, 0xde, + 0x2f, 0x85, 0xde, 0xf7, 0xf7, 0x4d, 0xcd, 0x7b, 0xf2, 0xb6, 0x8b, 0x72, + 0x03, 0x6b, 0x2c, 0x7f, 0xde, 0x40, 0xf4, 0x76, 0x52, 0x2b, 0x61, 0x2d, + 0x72, 0xa2, 0x21, 0x0c, 0x1b, 0x44, 0x6c, 0x40, 0x04, 0xbc, 0x5e, 0xff, + 0xcb, 0xb6, 0x65, 0x99, 0xc6, 0xdb, 0xf7, 0x6f, 0xbc, 0x75, 0xd6, 0xcb, + 0x79, 0x6d, 0xd6, 0x94, 0xbd, 0xb7, 0x47, 0x89, 0xc6, 0xf6, 0xf0, 0xab, + 0x67, 0x60, 0x37, 0x32, 0x7d, 0x0f, 0x31, 0x08, 0xe2, 0x4e, 0x11, 0x0d, + 0x64, 0x1e, 0x66, 0xc6, 0xc6, 0xc5, 0x34, 0x56, 0xf8, 0xbf, 0x12, 0x83, + 0x7a, 0x75, 0xe0, 0x67, 0xae, 0x7b, 0x7e, 0xfb, 0xb6, 0x33, 0x38, 0xaa, + 0xea, 0x98, 0x9b, 0xfd, 0x36, 0x0d, 0x7e, 0x0f, 0xd4, 0xf9, 0x56, 0x6a, + 0xd5, 0x40, 0xb4, 0x38, 0xae, 0x6a, 0x7a, 0xc5, 0x40, 0x2c, 0x87, 0x72, + 0x80, 0x3e, 0x20, 0xf3, 0x48, 0xed, 0xbd, 0xb8, 0x13, 0xdf, 0xb7, 0xae, + 0x6a, 0xe6, 0x62, 0x6e, 0x73, 0x4c, 0xf0, 0x06, 0xba, 0x6c, 0xb2, 0xed, + 0xb6, 0x83, 0x32, 0x77, 0x63, 0xff, 0x84, 0x7e, 0xca, 0x91, 0xd7, 0x14, + 0xc7, 0xae, 0x12, 0x91, 0x49, 0xb6, 0x32, 0x92, 0x97, 0x5e, 0x39, 0x5a, + 0x71, 0x86, 0xdc, 0x92, 0xbb, 0x47, 0x8c, 0x3e, 0x24, 0xfc, 0x05, 0xf2, + 0x38, 0x7b, 0xdd, 0x4c, 0xec, 0x52, 0x8f, 0x80, 0x57, 0xd1, 0x52, 0x6b, + 0x0a, 0xb9, 0x81, 0xfd, 0x6b, 0xd2, 0x43, 0x58, 0x2c, 0x2a, 0xb8, 0x3d, + 0x66, 0xb0, 0x61, 0x9b, 0x3e, 0x7a, 0xc9, 0x38, 0x62, 0xc8, 0x6b, 0x4f, + 0xa0, 0xe3, 0xed, 0x13, 0x7b, 0xd6, 0x7c, 0xbb, 0x35, 0xaf, 0x81, 0xed, + 0x88, 0x91, 0x35, 0x2a, 0x5c, 0x5f, 0x47, 0xa7, 0x2f, 0x6f, 0xf5, 0x23, + 0x38, 0x20, 0x87, 0x5f, 0x65, 0x81, 0xfa, 0x44, 0x88, 0xd4, 0x96, 0x5e, + 0xc2, 0x84, 0xca, 0x39, 0x20, 0x28, 0x93, 0x94, 0x06, 0x4f, 0xc5, 0x41, + 0xff, 0x4e, 0x9d, 0xe6, 0xdb, 0x29, 0x50, 0xaf, 0x46, 0x49, 0x00, 0x24, + 0x04, 0xf2, 0xcd, 0x13, 0x84, 0x82, 0xa3, 0xc9, 0x21, 0x36, 0x26, 0x6f, + 0xad, 0xff, 0xb7, 0x6f, 0xf2, 0x6e, 0x15, 0x83, 0xa8, 0xb5, 0x2e, 0x89, + 0xfb, 0xca, 0xfe, 0xfa, 0x80, 0x2d, 0xc7, 0x43, 0xfe, 0xbe, 0xd5, 0x1b, + 0x8a, 0x4d, 0x08, 0xed, 0x55, 0x2c, 0x83, 0xc1, 0xe5, 0x7b, 0xc5, 0x1b, + 0x5d, 0xdd, 0xb7, 0x53, 0xf1, 0x3b, 0xd7, 0x7d, 0xed, 0xe6, 0x11, 0xbe, + 0x75, 0xb5, 0xb4, 0x22, 0x42, 0x53, 0x10, 0x81, 0x34, 0x7b, 0x81, 0x3c, + 0x94, 0x13, 0xc7, 0x2c, 0xed, 0xa1, 0xa3, 0x0a, 0x15, 0x7a, 0xb0, 0x26, + 0x69, 0xe0, 0x45, 0x19, 0xb1, 0x9c, 0x88, 0x9d, 0xe1, 0x61, 0x20, 0xee, + 0x3f, 0xe6, 0xa3, 0x8c, 0x61, 0x85, 0xa7, 0x28, 0xd2, 0x09, 0x7b, 0x69, + 0xb0, 0x95, 0x37, 0xd8, 0x96, 0x3c, 0xcc, 0x2c, 0x90, 0x83, 0x28, 0x8c, + 0x8b, 0x3b, 0xfe, 0xb7, 0xb5, 0x19, 0x15, 0x5e, 0xcf, 0x5f, 0xaf, 0x8c, + 0x76, 0x95, 0x02, 0x97, 0xe9, 0xac, 0x02, 0xb2, 0xee, 0x82, 0xe7, 0x16, + 0xca, 0x5b, 0x08, 0x22, 0xc6, 0x4e, 0xd2, 0xab, 0x10, 0x0f, 0x68, 0x5c, + 0xc2, 0x3d, 0x16, 0xf8, 0x74, 0x11, 0xd6, 0x4c, 0x65, 0xe1, 0x26, 0x9a, + 0x2d, 0xb0, 0x20, 0x66, 0xd2, 0xed, 0x60, 0xf4, 0xd1, 0xc2, 0x7d, 0x44, + 0xd7, 0xbd, 0x45, 0x36, 0x7b, 0xdc, 0xef, 0x87, 0xba, 0xbe, 0x16, 0x40, + 0x13, 0xa3, 0x3a, 0x6e, 0x12, 0xc0, 0xa3, 0xe2, 0x01, 0xfa, 0xde, 0xe5, + 0x75, 0xb9, 0x8a, 0x12, 0x19, 0x44, 0x8a, 0x12, 0xc9, 0x51, 0x84, 0xa5, + 0xcb, 0xc0, 0xec, 0xee, 0xd3, 0xaf, 0x34, 0xa4, 0x91, 0x34, 0x52, 0x01, + 0xeb, 0x00, 0x8e, 0x62, 0x71, 0x6f, 0x32, 0x80, 0x3e, 0xdc, 0x17, 0x3b, + 0x7d, 0x4b, 0x50, 0x4e, 0x81, 0x90, 0x98, 0xde, 0x4c, 0xc6, 0x90, 0x09, + 0x6e, 0xbb, 0x4e, 0x1f, 0x87, 0x0b, 0x2e, 0x1f, 0xed, 0x42, 0x0e, 0x2d, + 0x04, 0x24, 0xb0, 0x40, 0xc3, 0xde, 0x12, 0x24, 0x15, 0x2a, 0x68, 0x09, + 0xf8, 0xf8, 0x71, 0xf1, 0x85, 0x16, 0x12, 0xa4, 0x58, 0xc1, 0xa6, 0x19, + 0x1a, 0x68, 0x9d, 0xa1, 0x94, 0x32, 0x08, 0x11, 0x51, 0x14, 0xb1, 0xa4, + 0x24, 0x0c, 0xdd, 0x2c, 0x04, 0x20, 0x19, 0x72, 0x35, 0x60, 0xda, 0x79, + 0x84, 0x11, 0x05, 0xf0, 0xe6, 0x52, 0xf8, 0x9f, 0x3a, 0xd0, 0x9e, 0xe1, + 0xe4, 0x50, 0x99, 0x8c, 0xb4, 0xba, 0x33, 0xc7, 0xc0, 0x33, 0x00, 0x76, + 0x0e, 0x10, 0x19, 0x31, 0x23, 0x8d, 0x34, 0x96, 0xdf, 0xd8, 0x6b, 0x24, + 0x65, 0x3f, 0x4d, 0x1c, 0x95, 0x5a, 0x79, 0xc2, 0xe5, 0xb2, 0x36, 0xc5, + 0xa6, 0x8b, 0x28, 0x03, 0x95, 0xda, 0x51, 0xa3, 0x96, 0x00, 0xf9, 0xe0, + 0xbc, 0x7e, 0xc5, 0xab, 0x8a, 0x64, 0xa5, 0x7c, 0xf3, 0x65, 0x98, 0xc1, + 0x92, 0x4b, 0x9f, 0xa6, 0x87, 0x8a, 0x35, 0xa5, 0x35, 0x14, 0x93, 0x26, + 0x05, 0xfe, 0xec, 0x4b, 0xdc, 0xea, 0xd6, 0xb6, 0x54, 0x23, 0x2c, 0x24, + 0x72, 0xfe, 0x71, 0x90, 0x31, 0xfd, 0x00, 0x84, 0xc2, 0xc8, 0x63, 0x8a, + 0x88, 0xcb, 0x27, 0xf0, 0x7e, 0x05, 0x1e, 0xf3, 0xb4, 0xfa, 0x7e, 0xe1, + 0x77, 0x67, 0xe3, 0xa6, 0x28, 0x11, 0x48, 0xe3, 0xbd, 0x00, 0x25, 0x7b, + 0x30, 0xcb, 0xec, 0x27, 0xc1, 0x61, 0x28, 0x1c, 0x56, 0x66, 0x12, 0x10, + 0xba, 0x08, 0x03, 0x91, 0x43, 0xd3, 0x6d, 0x2a, 0xcd, 0x2a, 0x58, 0x64, + 0x68, 0x24, 0x4f, 0xc7, 0x47, 0xf1, 0x7c, 0x69, 0x9a, 0x14, 0x64, 0x5e, + 0x53, 0xbd, 0x74, 0x85, 0xa9, 0x29, 0xa6, 0x7e, 0xae, 0x39, 0x35, 0x40, + 0x8c, 0xe5, 0x59, 0x30, 0x5c, 0x7f, 0x46, 0xa1, 0x37, 0x29, 0x04, 0x07, + 0xc5, 0xf1, 0xcf, 0x30, 0x0f, 0x89, 0x87, 0x31, 0x4f, 0x33, 0xa2, 0x04, + 0xb2, 0x9b, 0x30, 0x55, 0x14, 0xb1, 0x82, 0xac, 0x3e, 0xb8, 0x1a, 0xb9, + 0xca, 0xa5, 0xe9, 0x4b, 0x28, 0x77, 0x3a, 0x63, 0xe8, 0xad, 0xbe, 0x98, + 0xd2, 0x2d, 0x32, 0xc6, 0x30, 0x82, 0x0e, 0xc1, 0x8f, 0xb9, 0x70, 0x13, + 0xca, 0x42, 0xd8, 0x07, 0x0f, 0x23, 0xd9, 0x5a, 0xed, 0x92, 0x9b, 0x38, + 0xc5, 0xa0, 0x65, 0xb1, 0x08, 0x90, 0xcb, 0x61, 0x2c, 0x05, 0x1f, 0xa6, + 0x2a, 0x55, 0x24, 0x2f, 0x40, 0xc2, 0x4f, 0x5c, 0xb3, 0xcc, 0xd5, 0xfb, + 0x57, 0xda, 0x92, 0x08, 0xed, 0x0e, 0x56, 0x4e, 0x55, 0x6d, 0xfc, 0xc3, + 0x66, 0x95, 0x9c, 0x81, 0x27, 0xe5, 0x6c, 0x9d, 0x42, 0x94, 0x38, 0x68, + 0x48, 0x22, 0x58, 0x48, 0x86, 0xfa, 0x83, 0x66, 0xb6, 0xbd, 0xca, 0x0d, + 0x0c, 0x72, 0x68, 0xd6, 0x07, 0xe4, 0xcc, 0x84, 0x76, 0x85, 0x0f, 0x9c, + 0x7a, 0x2d, 0x6a, 0xed, 0x3e, 0x34, 0xda, 0x2b, 0xf2, 0xf4, 0x67, 0xa6, + 0x00, 0xd1, 0x64, 0x5e, 0x45, 0x12, 0x82, 0x2d, 0x95, 0x2f, 0xac, 0x58, + 0xf9, 0xea, 0x65, 0x4b, 0x27, 0xdb, 0x3d, 0xdd, 0x8d, 0x8a, 0x5e, 0xda, + 0xb5, 0xd6, 0x05, 0x88, 0x64, 0x1c, 0x84, 0x7f, 0x69, 0x12, 0x11, 0x2f, + 0x80, 0x7d, 0x12, 0xbb, 0xaa, 0x50, 0x71, 0x9b, 0x4c, 0xba, 0xdf, 0xaa, + 0x5e, 0xf6, 0x34, 0x1f, 0xef, 0xa5, 0x4f, 0xfa, 0x95, 0x34, 0xef, 0x84, + 0xed, 0xd9, 0x2f, 0x1c, 0xcd, 0xc6, 0x5e, 0x90, 0xfb, 0x13, 0xf3, 0xf0, + 0xfa, 0x3f, 0x7f, 0x77, 0xca, 0x76, 0x12, 0x9a, 0x3c, 0x92, 0x86, 0xed, + 0xcb, 0xe0, 0x22, 0x84, 0x86, 0x5d, 0x02, 0xf2, 0xfa, 0x37, 0x83, 0x64, + 0xad, 0x1f, 0x0d, 0xdb, 0x95, 0x8f, 0x3d, 0x70, 0xbe, 0xff, 0xfb, 0x5d, + 0xfd, 0xbe, 0x1b, 0x92, 0xcc, 0xb6, 0x95, 0xef, 0x63, 0x8a, 0x72, 0xc8, + 0x4e, 0x88, 0xf9, 0xa3, 0xb9, 0x07, 0x9c, 0xb3, 0x3f, 0xad, 0xca, 0x84, + 0xb2, 0x06, 0x42, 0x28, 0xb7, 0xc4, 0xf1, 0x07, 0x9c, 0xcf, 0x8e, 0xe7, + 0xd9, 0xc9, 0xa8, 0xf8, 0x9e, 0x1b, 0x96, 0x48, 0xf6, 0xa9, 0x55, 0x5d, + 0x6d, 0xff, 0xff, 0xed, 0x49, 0xc8, 0x82, 0x8e, 0x33, 0x09, 0x78, 0x68, + 0x44, 0x2c, 0xd9, 0xbf, 0xd4, 0x22, 0x03, 0xad, 0x38, 0x01, 0x7b, 0xeb, + 0x1b, 0x8b, 0x6c, 0x94, 0xda, 0x81, 0x6e, 0xd8, 0x6a, 0x26, 0x02, 0x28, + 0xa3, 0x2f, 0xa8, 0x0f, 0xef, 0x0d, 0xbc, 0xb9, 0xa2, 0x57, 0xb2, 0x72, + 0x28, 0x81, 0x9b, 0x5d, 0x54, 0x86, 0x7b, 0xf9, 0xed, 0x13, 0xe1, 0x8c, + 0xa4, 0x32, 0x35, 0xe4, 0x8e, 0x01, 0xe1, 0xdd, 0x71, 0xc5, 0xfe, 0x50, + 0x53, 0xdf, 0xef, 0x6b, 0x69, 0x81, 0x35, 0x5a, 0x65, 0x16, 0x87, 0xce, + 0x42, 0x86, 0x32, 0xd4, 0x48, 0x97, 0x3f, 0x10, 0x39, 0xa3, 0xf6, 0x03, + 0xc1, 0xb2, 0xe7, 0xe3, 0xed, 0xae, 0x92, 0x06, 0xca, 0xd0, 0xd0, 0x96, + 0x51, 0xd2, 0x4b, 0x9f, 0xef, 0x5a, 0xdc, 0x66, 0x2b, 0x56, 0xa3, 0x5f, + 0xe3, 0x4b, 0x67, 0x39, 0x09, 0x6f, 0x27, 0x68, 0xd0, 0x75, 0x66, 0xf3, + 0x5c, 0x7c, 0x99, 0x97, 0xbe, 0x95, 0xb7, 0x22, 0xde, 0x54, 0x77, 0x8e, + 0x97, 0x05, 0x21, 0xa4, 0x00, 0x9a, 0x1d, 0xcc, 0xf5, 0x5e, 0xc6, 0xcf, + 0x48, 0x84, 0xab, 0x80, 0xe4, 0x3d, 0x25, 0xc0, 0x88, 0xc7, 0x62, 0xce, + 0x40, 0x32, 0x45, 0xc4, 0x89, 0x44, 0x64, 0xeb, 0x20, 0xe7, 0xba, 0x5a, + 0x97, 0xe7, 0xb1, 0x1a, 0xa6, 0xeb, 0xe2, 0x4f, 0x30, 0x03, 0x60, 0xc2, + 0x84, 0xcc, 0xf0, 0x0a, 0xa8, 0xb0, 0x97, 0x22, 0x48, 0x78, 0x40, 0x46, + 0x9f, 0xc4, 0x83, 0xfe, 0x62, 0x7b, 0xfe, 0xbb, 0xfb, 0x3d, 0x36, 0x2a, + 0xf5, 0xde, 0xb3, 0xbd, 0xf9, 0x4f, 0xcb, 0x1e, 0xbf, 0xcd, 0xe0, 0xef, + 0x3f, 0x34, 0x9b, 0xf3, 0x96, 0xd1, 0x30, 0x84, 0x69, 0x8d, 0x00, 0xf3, + 0x77, 0x1e, 0x06, 0x66, 0x09, 0x3d, 0xd2, 0xeb, 0x76, 0x2f, 0x96, 0xba, + 0x56, 0x73, 0x18, 0x6b, 0x5b, 0x89, 0xef, 0x1e, 0x9f, 0x4e, 0x5c, 0x62, + 0x73, 0xa5, 0x71, 0x7f, 0xa6, 0xb6, 0x27, 0x05, 0x89, 0xa6, 0x34, 0x6f, + 0xb8, 0x6a, 0x5c, 0xb3, 0x72, 0xe7, 0xc1, 0x2a, 0x9e, 0xc1, 0x3f, 0xbf, + 0x7f, 0x71, 0x7f, 0x6f, 0x3b, 0xfd, 0xf7, 0xbf, 0xb1, 0xfd, 0xaa, 0xdf, + 0x4b, 0x7f, 0x73, 0x6d, 0x7a, 0x2e, 0x2f, 0x95, 0xb6, 0xe6, 0xe5, 0xbc, + 0x18, 0x58, 0xcc, 0x4c, 0x3b, 0x49, 0x10, 0x88, 0x3e, 0x20, 0xe6, 0xfe, + 0x33, 0x5c, 0xc2, 0xc7, 0x6e, 0xbe, 0x7a, 0xbb, 0xaa, 0xd6, 0xd7, 0x13, + 0x81, 0xfb, 0xfd, 0xfe, 0x76, 0xfa, 0x26, 0xb9, 0x01, 0x87, 0x3d, 0x8f, + 0x5d, 0xe2, 0xa1, 0xc6, 0xa9, 0x2a, 0x26, 0xf7, 0x8f, 0x04, 0x23, 0x0c, + 0xd5, 0x49, 0x36, 0x72, 0x25, 0x74, 0x12, 0x66, 0xee, 0x7b, 0xe6, 0x2f, + 0xbf, 0x1f, 0xdf, 0xcc, 0xd2, 0x7d, 0xfd, 0xd5, 0x0b, 0x2d, 0xf7, 0xe3, + 0x37, 0x5b, 0xf7, 0xe3, 0xf7, 0xe5, 0x09, 0xfe, 0x7b, 0xca, 0xc7, 0x68, + 0xa7, 0xcb, 0x9d, 0xec, 0x38, 0xe4, 0x5e, 0xec, 0x02, 0x87, 0xd4, 0xc3, + 0xd9, 0x51, 0x5f, 0x3b, 0xef, 0xed, 0x78, 0x14, 0xe9, 0xde, 0xb7, 0xff, + 0x4f, 0x6d, 0x5d, 0x1c, 0x36, 0xed, 0xe5, 0x57, 0xe5, 0xd8, 0x39, 0x87, + 0x8b, 0x8e, 0xc7, 0x57, 0x97, 0xdd, 0x8a, 0x76, 0x40, 0xba, 0x23, 0xee, + 0x4d, 0x7c, 0x65, 0x72, 0xc8, 0x9d, 0x2f, 0xee, 0x36, 0xd4, 0xfb, 0xd6, + 0xff, 0x49, 0x7a, 0x7f, 0x93, 0xfa, 0x7b, 0x3f, 0x5a, 0x79, 0xf9, 0x85, + 0xd6, 0xeb, 0x7b, 0xf5, 0xd1, 0x64, 0x2e, 0x72, 0xf0, 0x98, 0x36, 0x03, + 0xed, 0xfe, 0xc0, 0x4e, 0x06, 0xec, 0x09, 0x8b, 0x83, 0x8d, 0x7f, 0x7b, + 0xa6, 0x75, 0xd7, 0x6e, 0xf3, 0xa8, 0xdb, 0xd2, 0xb6, 0x5b, 0xf8, 0xc5, + 0xe3, 0x86, 0xd1, 0x5a, 0xf9, 0xe7, 0x4e, 0x7a, 0x69, 0xb1, 0x65, 0xc3, + 0xc9, 0xb0, 0xfb, 0xbd, 0xea, 0xb7, 0x05, 0xd2, 0x73, 0x9a, 0x39, 0xdc, + 0xde, 0x2a, 0xef, 0xdf, 0x8c, 0xc3, 0xcd, 0xdf, 0x85, 0xf4, 0x89, 0xae, + 0xbc, 0xeb, 0xbf, 0xe7, 0xad, 0xe6, 0x9c, 0x6a, 0x60, 0xef, 0x5a, 0xff, + 0x4e, 0x95, 0xa6, 0x96, 0x2f, 0x3f, 0x97, 0x2c, 0x4d, 0x96, 0xd6, 0xe7, + 0xf4, 0x11, 0xe9, 0x5d, 0x5e, 0x28, 0x9c, 0x75, 0x55, 0xcc, 0xef, 0x65, + 0x6a, 0x2b, 0x29, 0xb7, 0xff, 0x43, 0x9d, 0xcb, 0x91, 0x60, 0x58, 0x50, + 0x79, 0xef, 0xb4, 0xd8, 0x7a, 0x1d, 0x94, 0x2a, 0xe4, 0x54, 0x74, 0x4c, + 0xe5, 0x8c, 0xeb, 0xfb, 0x13, 0xfd, 0x4a, 0xc3, 0xee, 0x3f, 0x71, 0x33, + 0xf9, 0xba, 0xa5, 0x17, 0xde, 0xcf, 0x45, 0x28, 0x75, 0xfe, 0xb8, 0x35, + 0xa5, 0x79, 0x9b, 0x54, 0x37, 0xc8, 0xa7, 0x8b, 0x0d, 0x56, 0x92, 0x3f, + 0xd8, 0xc8, 0x68, 0xf4, 0xe2, 0x1c, 0xbc, 0x4a, 0x5a, 0x9d, 0xea, 0x85, + 0x57, 0xa1, 0x45, 0x58, 0xb9, 0xc8, 0x23, 0x7a, 0xc5, 0xfe, 0x2f, 0xbd, + 0x9d, 0xe9, 0xbf, 0x19, 0x2a, 0x14, 0x0d, 0x78, 0xa4, 0x01, 0x03, 0x0e, + 0x97, 0x91, 0x0c, 0x5c, 0x6b, 0x9d, 0x29, 0x50, 0x5e, 0xfc, 0x18, 0x51, + 0x91, 0x9b, 0x03, 0x41, 0x1c, 0xb9, 0xe4, 0x42, 0x59, 0xcf, 0x3b, 0xd6, + 0xe9, 0xe3, 0x19, 0xc0, 0x82, 0x28, 0x60, 0x3f, 0x1e, 0x32, 0xe0, 0x05, + 0xca, 0x07, 0x5c, 0x8e, 0x37, 0xb0, 0xcb, 0x0d, 0xf1, 0x21, 0x91, 0x96, + 0x41, 0xb4, 0x67, 0x56, 0xab, 0x7d, 0x75, 0x02, 0x86, 0x83, 0xbf, 0x39, + 0x7b, 0x9d, 0x0c, 0x7c, 0xb0, 0x7d, 0x38, 0x4f, 0x9c, 0xf2, 0xe6, 0x52, + 0xdd, 0x2f, 0xc4, 0x3d, 0x75, 0x5e, 0xbb, 0x53, 0x7a, 0x4f, 0xa6, 0xf5, + 0x3a, 0xdb, 0xa1, 0xc0, 0x02, 0x62, 0xf2, 0xe6, 0x90, 0xca, 0x92, 0x3e, + 0x9c, 0x9f, 0x72, 0x0b, 0x7f, 0x63, 0xa7, 0x5f, 0x07, 0x2a, 0x62, 0xa9, + 0xe6, 0x22, 0x25, 0xb7, 0x96, 0xad, 0x51, 0x0b, 0xc6, 0x47, 0x9d, 0x76, + 0xbc, 0x1f, 0x83, 0x2c, 0x65, 0xd9, 0x15, 0xfb, 0x7c, 0x85, 0x6a, 0xd6, + 0xa6, 0xc8, 0x04, 0x5c, 0x25, 0xa1, 0x96, 0x91, 0xfa, 0x31, 0xaf, 0xd2, + 0x0d, 0xdd, 0x7f, 0x8a, 0x09, 0x4f, 0xd9, 0x38, 0x3f, 0xb6, 0x1e, 0x52, + 0xf3, 0x8a, 0x27, 0x25, 0xe2, 0x93, 0x08, 0x7c, 0x69, 0xa4, 0x39, 0xd6, + 0x59, 0x07, 0x0c, 0xd2, 0x91, 0x9c, 0xf3, 0x04, 0xf7, 0x7b, 0x99, 0x72, + 0x2c, 0x73, 0x7b, 0x6d, 0xe7, 0x7b, 0x1a, 0x8b, 0x71, 0x8e, 0x8c, 0xf2, + 0xea, 0x3a, 0x52, 0xee, 0x44, 0x91, 0xf8, 0x26, 0xfc, 0xc2, 0xde, 0x9b, + 0xd9, 0x6c, 0x3c, 0xc4, 0xaf, 0x75, 0x64, 0x3c, 0xa4, 0x27, 0xdc, 0xf8, + 0x5f, 0x91, 0x28, 0x87, 0xaa, 0xce, 0xea, 0x6e, 0x5c, 0xa2, 0x00, 0x04, + 0xcb, 0x4c, 0xe5, 0x99, 0xca, 0x00, 0x27, 0x34, 0x72, 0x5e, 0x0b, 0x4e, + 0x03, 0xbd, 0x7d, 0x10, 0x11, 0x90, 0xca, 0x8c, 0xbf, 0x04, 0xbe, 0xb2, + 0x5b, 0x65, 0xf1, 0x22, 0x83, 0xd1, 0x84, 0x3d, 0x16, 0x26, 0x30, 0xf1, + 0x03, 0xe6, 0x64, 0xa8, 0xc8, 0x20, 0x3c, 0x3b, 0x01, 0x72, 0xbc, 0xea, + 0xaa, 0x94, 0xf2, 0x80, 0x1d, 0x93, 0xc3, 0x3c, 0xbf, 0x4f, 0xce, 0x48, + 0x8f, 0xb5, 0x38, 0x83, 0x5c, 0x4d, 0x7f, 0xd6, 0x68, 0x70, 0x0c, 0x90, + 0x8c, 0x5d, 0x2b, 0xc2, 0x60, 0x51, 0xad, 0xfb, 0xfb, 0x22, 0x97, 0x02, + 0xe6, 0xda, 0x4c, 0x7c, 0x46, 0xfe, 0x36, 0xec, 0x8b, 0x9a, 0x09, 0x48, + 0x7d, 0x13, 0x2e, 0xd7, 0x1b, 0x3f, 0xcb, 0xe9, 0xa5, 0x90, 0xc4, 0x30, + 0x0c, 0x92, 0x23, 0x22, 0x89, 0x91, 0x62, 0x73, 0xb0, 0x8f, 0x55, 0xd2, + 0x9e, 0x1c, 0x3a, 0x22, 0x57, 0x87, 0xd9, 0x6e, 0x47, 0x93, 0xdd, 0xfd, + 0x53, 0xa0, 0x5e, 0x40, 0x92, 0x04, 0x54, 0x57, 0x3a, 0x69, 0x45, 0x7f, + 0xe7, 0x8d, 0x03, 0x8b, 0xff, 0xe2, 0x76, 0x13, 0xc1, 0x22, 0x2d, 0xf3, + 0xa9, 0x8b, 0xb9, 0x63, 0x33, 0x56, 0xa3, 0x9f, 0x02, 0xf5, 0x3d, 0x6c, + 0x89, 0xe3, 0xc9, 0x88, 0xc3, 0xa3, 0xf0, 0x5e, 0x05, 0xcd, 0x22, 0xeb, + 0xe1, 0x0c, 0x36, 0x2c, 0xb6, 0x7b, 0x40, 0x30, 0xf3, 0xab, 0x2f, 0xe0, + 0x4f, 0x03, 0x97, 0x2b, 0xd9, 0xfe, 0xfe, 0x23, 0xa7, 0x9f, 0x05, 0xdc, + 0x66, 0x82, 0xd2, 0x54, 0x6d, 0x87, 0xfa, 0x0c, 0x8e, 0x48, 0x25, 0xde, + 0xb0, 0x13, 0x77, 0x71, 0x55, 0x1e, 0x89, 0x63, 0x8d, 0xdb, 0x8a, 0x1c, + 0x31, 0x0d, 0xa2, 0xfa, 0xa0, 0x5c, 0x50, 0x34, 0x11, 0x22, 0x61, 0x1e, + 0xe0, 0x55, 0xfe, 0xd7, 0x5a, 0x5c, 0x91, 0x2b, 0xaf, 0x65, 0x91, 0x8c, + 0xe7, 0x1c, 0x34, 0x88, 0x22, 0x63, 0x2c, 0x56, 0x70, 0x4e, 0x15, 0x02, + 0x9b, 0x52, 0xff, 0x22, 0x14, 0xff, 0xb3, 0x05, 0x6e, 0xb7, 0xb6, 0x41, + 0x11, 0x21, 0x44, 0xe4, 0xf6, 0x90, 0xf0, 0x4d, 0x79, 0xf3, 0x34, 0x32, + 0xf2, 0x33, 0xb4, 0x94, 0x69, 0x49, 0xeb, 0xd3, 0x43, 0x7b, 0x07, 0x60, + 0xd1, 0xdc, 0x81, 0x43, 0x1a, 0x68, 0x1c, 0x9f, 0x64, 0xe3, 0x1c, 0x8d, + 0xaf, 0x40, 0x52, 0xd5, 0x28, 0x26, 0x69, 0x9c, 0x9a, 0x26, 0x80, 0x4e, + 0xc8, 0x12, 0x24, 0xeb, 0x56, 0x54, 0xe9, 0xb5, 0x2a, 0x0c, 0x44, 0xd2, + 0xd2, 0xe7, 0x56, 0xab, 0x97, 0x16, 0xac, 0x18, 0x41, 0x28, 0x4e, 0x11, + 0x46, 0x03, 0x2c, 0x79, 0x8c, 0x3f, 0xcf, 0x77, 0x96, 0x84, 0xc9, 0x03, + 0x26, 0xee, 0x7d, 0x3e, 0x15, 0xb6, 0x6b, 0x1d, 0x90, 0xdd, 0x87, 0x29, + 0x88, 0x06, 0x69, 0x19, 0x8c, 0x27, 0xef, 0x9d, 0x1a, 0x9f, 0xca, 0x12, + 0xff, 0x70, 0xee, 0x16, 0x10, 0x71, 0x95, 0x2a, 0x19, 0x79, 0x54, 0x3e, + 0x8b, 0xa7, 0x49, 0xc4, 0xe8, 0x4f, 0x2a, 0xac, 0xe0, 0x04, 0x66, 0x28, + 0xcf, 0x2a, 0x87, 0x64, 0x3e, 0x5d, 0x04, 0x3e, 0xc4, 0x89, 0x06, 0xc9, + 0x64, 0x98, 0xa0, 0xe7, 0x07, 0x6f, 0x05, 0xb4, 0xfb, 0x66, 0x9e, 0x33, + 0xb3, 0xbc, 0xe3, 0x10, 0x86, 0xa4, 0x10, 0xc9, 0xfd, 0x89, 0x97, 0x13, + 0x9e, 0x74, 0x49, 0x61, 0x29, 0xca, 0x9b, 0x98, 0x1a, 0x10, 0x84, 0x89, + 0xac, 0x02, 0xa3, 0xbf, 0xf2, 0x5f, 0xff, 0x8a, 0xfc, 0xf9, 0xab, 0xd6, + 0x90, 0xe5, 0xe0, 0x58, 0x2f, 0xd1, 0xde, 0x44, 0xc0, 0x5a, 0x67, 0x52, + 0x63, 0x28, 0x0a, 0x04, 0x63, 0xcf, 0xc1, 0x21, 0x38, 0xe9, 0x8b, 0xaf, + 0x2e, 0x4e, 0x40, 0x81, 0xa0, 0x9a, 0x1b, 0x69, 0x3f, 0x67, 0x07, 0x28, + 0x8c, 0x24, 0x24, 0x68, 0x63, 0x12, 0xee, 0xce, 0xdf, 0x8b, 0xeb, 0x4d, + 0x45, 0x07, 0xe7, 0xea, 0x49, 0xbb, 0xd1, 0x36, 0x6e, 0xdd, 0xd7, 0xe0, + 0xaf, 0x12, 0xf4, 0x08, 0x48, 0x9b, 0xd4, 0x26, 0x19, 0x6a, 0x5e, 0x7b, + 0xce, 0xd7, 0xde, 0xdd, 0x6a, 0x1f, 0xc1, 0x9b, 0xbd, 0x13, 0xb6, 0x1d, + 0x84, 0x15, 0x93, 0x3c, 0xf4, 0xf0, 0x06, 0xfa, 0xcd, 0xce, 0x89, 0x78, + 0x76, 0xe7, 0x23, 0x72, 0xe7, 0xf1, 0x3e, 0x27, 0x86, 0x54, 0x75, 0xec, + 0xef, 0x9e, 0x7b, 0xf2, 0x75, 0x57, 0x46, 0xc4, 0x2b, 0xf0, 0x55, 0x6c, + 0x95, 0x71, 0xc4, 0xf7, 0xd6, 0x32, 0xee, 0xd9, 0xa5, 0x8c, 0x6d, 0xce, + 0x40, 0x25, 0xc9, 0x01, 0x80, 0x7d, 0x75, 0xbf, 0x8a, 0xeb, 0xbc, 0x48, + 0xe7, 0xa7, 0x2e, 0x58, 0x06, 0x2c, 0xd5, 0xee, 0x20, 0x90, 0x22, 0xa8, + 0x4a, 0x41, 0x1e, 0xe7, 0x62, 0x9b, 0x13, 0x28, 0x02, 0x4d, 0xd6, 0xd0, + 0xb1, 0x80, 0x96, 0x39, 0xa3, 0x4c, 0xa4, 0x7b, 0x83, 0xf7, 0x78, 0x9f, + 0xbe, 0x0a, 0xf9, 0x98, 0xcb, 0x17, 0x7d, 0x46, 0xe4, 0x10, 0xbd, 0xa6, + 0x89, 0xca, 0x00, 0x98, 0xd0, 0x2f, 0xaa, 0x84, 0x09, 0xc2, 0xac, 0xc5, + 0xd6, 0xe9, 0x91, 0x1b, 0x5e, 0x49, 0x52, 0x73, 0x15, 0xf5, 0x6b, 0xf0, + 0xdb, 0xd4, 0x32, 0x8d, 0x34, 0xb8, 0x5c, 0x25, 0xe4, 0x21, 0x7a, 0x7c, + 0x44, 0x2e, 0x54, 0xe3, 0x5d, 0xf2, 0x59, 0xfd, 0x63, 0x6b, 0xb6, 0x2f, + 0x3b, 0xdb, 0xb3, 0x39, 0x94, 0xe5, 0x26, 0x26, 0x79, 0x5a, 0x0c, 0x26, + 0x12, 0xfc, 0x41, 0x57, 0x89, 0x63, 0x11, 0x0b, 0xc6, 0x46, 0x57, 0xa3, + 0xb2, 0xa5, 0x2a, 0x5d, 0xf6, 0xfd, 0x7c, 0x73, 0xe2, 0xaf, 0x6f, 0x5b, + 0xa4, 0xb3, 0x05, 0x1c, 0x7d, 0xc1, 0x89, 0xfa, 0xcd, 0x03, 0x29, 0xa0, + 0x25, 0x18, 0xcd, 0xe1, 0xf1, 0xee, 0x5a, 0x21, 0xbf, 0x4a, 0xb8, 0x4c, + 0x9c, 0x87, 0x21, 0x09, 0x19, 0xe4, 0xa5, 0xe2, 0x03, 0x50, 0x31, 0x34, + 0x7c, 0x49, 0xbf, 0xe6, 0x56, 0x6c, 0xb6, 0xdf, 0x4e, 0xa6, 0x34, 0xd9, + 0xd8, 0x90, 0x50, 0x26, 0x54, 0x11, 0x14, 0x08, 0x28, 0x1f, 0x05, 0x1b, + 0xa6, 0x5d, 0x39, 0x42, 0x77, 0xb6, 0xc7, 0xc4, 0xfa, 0xb1, 0x43, 0x0a, + 0x93, 0x86, 0xf9, 0xe0, 0xfe, 0xa9, 0x65, 0x99, 0xfe, 0xeb, 0x93, 0xe3, + 0x61, 0xb2, 0x2b, 0x6c, 0xde, 0xd6, 0xc6, 0x02, 0xc5, 0xc1, 0x91, 0x53, + 0x5e, 0xf4, 0xcb, 0xf9, 0x70, 0x03, 0xb0, 0xde, 0x85, 0x18, 0xc6, 0x4b, + 0xd0, 0xe2, 0x7a, 0x6a, 0x28, 0xc3, 0xec, 0x45, 0xc4, 0xf1, 0x91, 0x4a, + 0x44, 0x4c, 0x78, 0xe3, 0xa4, 0x47, 0xd8, 0x6a, 0x9a, 0xc8, 0x21, 0x67, + 0x10, 0x11, 0x35, 0x36, 0x42, 0xa2, 0xde, 0x4d, 0xb0, 0xc3, 0xb2, 0x5d, + 0x44, 0x27, 0x18, 0xbc, 0xd5, 0xbf, 0xd4, 0x9d, 0xe4, 0xb5, 0x50, 0x88, + 0x3a, 0xf8, 0x30, 0x8f, 0x64, 0xed, 0xbb, 0x28, 0x9e, 0x78, 0x9e, 0x41, + 0x6d, 0x98, 0x2f, 0x6c, 0x1c, 0xe9, 0xe0, 0x51, 0x93, 0x2a, 0xd2, 0xa7, + 0xdc, 0xcc, 0x91, 0x70, 0x40, 0xc9, 0x99, 0x82, 0x10, 0xec, 0xa9, 0xf9, + 0xde, 0x9d, 0x5b, 0xd6, 0x9d, 0xb7, 0xb5, 0xb3, 0xe8, 0x33, 0x31, 0x0e, + 0x49, 0x79, 0x25, 0x65, 0x51, 0x99, 0x28, 0x01, 0x3f, 0xad, 0x50, 0x9e, + 0x5f, 0x5c, 0x0c, 0x73, 0x42, 0xac, 0x53, 0xb7, 0x71, 0x87, 0x5d, 0x3b, + 0x53, 0x03, 0x30, 0x06, 0x7c, 0x66, 0xfa, 0x34, 0xfe, 0xa9, 0x41, 0xbf, + 0xba, 0x85, 0xf6, 0xa8, 0xe4, 0xbb, 0x95, 0xf2, 0xce, 0x59, 0x01, 0x32, + 0x50, 0x92, 0x13, 0xf8, 0xa9, 0x42, 0xad, 0x36, 0x27, 0x84, 0xd8, 0x5c, + 0xe8, 0x84, 0xa4, 0x0a, 0x43, 0xc4, 0x7d, 0xdb, 0x8a, 0x8e, 0xdb, 0x4f, + 0x34, 0xb8, 0x29, 0x1f, 0x4e, 0xa0, 0xc8, 0xa8, 0x88, 0xbf, 0xda, 0x86, + 0xcf, 0xc5, 0xac, 0xed, 0x0e, 0x37, 0x26, 0xa4, 0xba, 0x6e, 0x40, 0xc3, + 0x3a, 0x1f, 0x12, 0x44, 0xa4, 0xb0, 0x27, 0x28, 0x34, 0xe7, 0x7b, 0x2f, + 0x87, 0xe7, 0x86, 0xfe, 0xce, 0x04, 0x38, 0xd3, 0x18, 0x99, 0x30, 0x29, + 0xd6, 0x42, 0xce, 0xba, 0x73, 0xd8, 0x35, 0x6f, 0x43, 0x6a, 0x82, 0x5b, + 0x51, 0x12, 0x0e, 0xd4, 0x61, 0x48, 0xb9, 0x4a, 0xfb, 0x34, 0x95, 0x71, + 0x4c, 0xb8, 0x9a, 0xa7, 0x6e, 0xc6, 0x81, 0x38, 0xa4, 0x57, 0x83, 0xca, + 0x64, 0x19, 0xb4, 0x90, 0x91, 0x32, 0xac, 0x9b, 0x79, 0xce, 0x42, 0x01, + 0xf0, 0x66, 0x7f, 0x38, 0xa5, 0xad, 0x44, 0x43, 0x1f, 0xca, 0x0f, 0x59, + 0xbe, 0x8f, 0x9d, 0xff, 0x16, 0xc9, 0xb6, 0xb7, 0x37, 0xa4, 0x46, 0x54, + 0x62, 0xac, 0x03, 0x2a, 0xac, 0x07, 0x39, 0xf1, 0xc9, 0xcd, 0x9b, 0xd7, + 0x6b, 0x47, 0x13, 0x25, 0xb0, 0x68, 0x24, 0x1e, 0xb0, 0xb8, 0xec, 0x19, + 0xa7, 0x2e, 0xaf, 0x0e, 0xb2, 0x1b, 0xd1, 0x63, 0x56, 0x83, 0xce, 0x19, + 0xe9, 0xcb, 0x14, 0x0b, 0x19, 0x4f, 0xc3, 0x61, 0x55, 0x8d, 0xfe, 0x94, + 0x86, 0x4a, 0x0d, 0x78, 0xbb, 0x1b, 0x8a, 0x8d, 0x3d, 0xe4, 0xbe, 0x0e, + 0xf4, 0xa0, 0x97, 0x91, 0x02, 0xfe, 0x7d, 0xf4, 0xda, 0x44, 0x07, 0x79, + 0xc8, 0xa2, 0x4d, 0x24, 0x50, 0x39, 0x3f, 0x9c, 0x0f, 0x33, 0xba, 0x96, + 0x0b, 0xf9, 0x2b, 0xb7, 0x87, 0xc5, 0x74, 0x69, 0xba, 0xb6, 0xe2, 0x67, + 0x2d, 0xe0, 0xcc, 0x00, 0x0d, 0x5b, 0x64, 0x77, 0xb8, 0x4d, 0x1a, 0x23, + 0x2f, 0xd3, 0xf6, 0x47, 0x76, 0xff, 0x6d, 0x74, 0xde, 0x84, 0x36, 0xc3, + 0x7b, 0x62, 0x8c, 0x2f, 0xc4, 0x54, 0x15, 0x16, 0xc7, 0xd8, 0x10, 0xd7, + 0xa6, 0x0e, 0xd9, 0xa3, 0x1a, 0x41, 0x19, 0x76, 0x44, 0xa5, 0xda, 0x9e, + 0x6b, 0x0a, 0xaf, 0xea, 0x27, 0x29, 0x3f, 0xaf, 0x01, 0xb7, 0xb0, 0x31, + 0xff, 0x9e, 0x15, 0x21, 0x3d, 0xec, 0x3e, 0x24, 0x8a, 0x38, 0x63, 0x94, + 0x3c, 0x08, 0x39, 0xd9, 0x44, 0x99, 0x28, 0x64, 0x6b, 0x09, 0xcd, 0xe8, + 0xf8, 0x99, 0xb1, 0x33, 0x6d, 0xd6, 0xa4, 0xa5, 0xd2, 0x3c, 0x09, 0x39, + 0x38, 0x8b, 0x23, 0x14, 0x64, 0xb6, 0x01, 0xa2, 0x7e, 0x2c, 0xbe, 0xd5, + 0x24, 0xe5, 0xd8, 0x19, 0xce, 0xc8, 0x77, 0x8c, 0xec, 0x6c, 0x8a, 0x38, + 0x2d, 0x8b, 0xa8, 0x42, 0x2d, 0xb1, 0x34, 0x28, 0x9c, 0x85, 0x19, 0x78, + 0x40, 0x0a, 0xee, 0xff, 0xfa, 0xa3, 0xd9, 0xa2, 0x26, 0x55, 0xdb, 0x8f, + 0xa0, 0xc5, 0xd7, 0xa1, 0x07, 0x67, 0x87, 0x0f, 0x4e, 0x31, 0x09, 0x74, + 0x2a, 0xd2, 0xf3, 0xfb, 0xf3, 0x8c, 0x51, 0x65, 0x27, 0x74, 0x67, 0x2c, + 0x64, 0x7e, 0x6e, 0x32, 0xce, 0x12, 0x0b, 0x1b, 0xb6, 0xa2, 0xda, 0xb4, + 0xc2, 0xf4, 0xaa, 0xfe, 0x3a, 0x47, 0x52, 0x9c, 0x91, 0x43, 0x1f, 0xe7, + 0xee, 0x71, 0x8e, 0xa2, 0x3e, 0xbd, 0xf3, 0x2e, 0xbd, 0xbc, 0xae, 0x76, + 0x7f, 0x15, 0x3d, 0x41, 0xc1, 0xf3, 0xed, 0xc2, 0xdb, 0x3a, 0xcd, 0x2d, + 0xf4, 0xd4, 0x5e, 0x10, 0x02, 0x84, 0xd1, 0x23, 0x5d, 0xac, 0x86, 0x4c, + 0x7d, 0x17, 0xd3, 0xbc, 0x7f, 0xec, 0x42, 0xa9, 0x74, 0x01, 0x01, 0xa3, + 0x8e, 0x20, 0x8c, 0x26, 0x66, 0x4e, 0x03, 0xf5, 0x07, 0xac, 0x2b, 0xaf, + 0x5a, 0xd2, 0xbf, 0xef, 0x74, 0xf1, 0x5c, 0xb1, 0xa7, 0x48, 0x1a, 0x48, + 0x0c, 0x69, 0xc6, 0x32, 0xc0, 0x70, 0x80, 0x77, 0x9a, 0x4c, 0x6f, 0xd7, + 0x22, 0xd8, 0xcd, 0x42, 0x3f, 0xae, 0xf9, 0x01, 0x08, 0x06, 0x9c, 0xca, + 0xc8, 0x3d, 0x63, 0x2b, 0x54, 0x7e, 0x76, 0xc1, 0x2c, 0xe0, 0xf5, 0x50, + 0x54, 0x51, 0x1b, 0xcb, 0x77, 0x36, 0xed, 0x30, 0x2e, 0x63, 0xad, 0x34, + 0x38, 0x9a, 0xd6, 0x9b, 0x0c, 0xcd, 0x2c, 0x91, 0x7f, 0x19, 0xfc, 0x4d, + 0x58, 0xac, 0x47, 0xdd, 0x17, 0xf3, 0xb8, 0xa0, 0x10, 0x3f, 0x16, 0xad, + 0x9b, 0x06, 0xc9, 0x97, 0x7b, 0x3f, 0x40, 0xb0, 0x0d, 0x1d, 0x85, 0xcb, + 0x12, 0x79, 0x61, 0x8e, 0x31, 0x20, 0x51, 0x9e, 0x59, 0x97, 0x87, 0x6d, + 0xfa, 0x4a, 0x43, 0x70, 0x8f, 0x75, 0x9f, 0x31, 0x75, 0xd9, 0xa6, 0x84, + 0x9b, 0x40, 0xaf, 0x62, 0xa1, 0x7b, 0x4a, 0x6e, 0x72, 0xdc, 0xd0, 0xa0, + 0x04, 0x35, 0x94, 0xd5, 0xa7, 0x3e, 0xc6, 0xd3, 0x73, 0x7b, 0xfd, 0x5b, + 0x64, 0x1d, 0x94, 0x48, 0x69, 0x8a, 0x89, 0xd8, 0x50, 0x22, 0x30, 0x94, + 0xfb, 0x5f, 0xaa, 0x53, 0x0b, 0xb9, 0x53, 0xe4, 0xbe, 0x0a, 0x27, 0x97, + 0x77, 0x53, 0x0d, 0xc5, 0xde, 0x64, 0x7f, 0x73, 0x77, 0x23, 0x5a, 0x47, + 0xb0, 0xda, 0x7c, 0x3e, 0x00, 0xd4, 0x4f, 0x80, 0x3c, 0xd8, 0x7f, 0x4d, + 0x76, 0x56, 0x8f, 0x55, 0xdd, 0x6d, 0x63, 0xde, 0xeb, 0xa3, 0x8e, 0x44, + 0xcf, 0xcc, 0x9e, 0xe7, 0x42, 0x94, 0x7b, 0xb9, 0x1d, 0x7d, 0x15, 0xb3, + 0x0a, 0x9e, 0xe8, 0xd5, 0x8f, 0x2e, 0xe4, 0xa6, 0x79, 0x55, 0x82, 0xff, + 0xfe, 0x79, 0x3a, 0x3d, 0xa7, 0x02, 0x04, 0x8d, 0x65, 0x6e, 0xab, 0x9c, + 0x62, 0xd8, 0x6f, 0x7e, 0xab, 0x21, 0x70, 0x12, 0x88, 0x76, 0x68, 0x5b, + 0xe2, 0x4b, 0xc6, 0x69, 0x0d, 0x5f, 0xf8, 0x21, 0x92, 0xe5, 0x49, 0xef, + 0xe6, 0x79, 0x9d, 0xcf, 0x6d, 0x5a, 0x7d, 0xbf, 0x08, 0x61, 0x62, 0xbd, + 0x87, 0x75, 0x8e, 0x36, 0x1c, 0x0a, 0x13, 0x94, 0x9c, 0x03, 0x01, 0x2e, + 0x47, 0xd8, 0x93, 0x13, 0xab, 0xab, 0x8d, 0xfe, 0x4d, 0xb3, 0x4e, 0x0a, + 0x18, 0x67, 0x84, 0x38, 0x21, 0x11, 0xb0, 0x58, 0x7c, 0x78, 0x23, 0xaf, + 0xbc, 0x58, 0xf7, 0x3b, 0xeb, 0x69, 0x59, 0xc9, 0x1a, 0x03, 0xe6, 0x00, + 0x43, 0xc0, 0x15, 0x56, 0x9b, 0x19, 0xb3, 0xbc, 0xdb, 0xeb, 0xec, 0xca, + 0xb8, 0x6a, 0x18, 0x7c, 0x59, 0xba, 0xa4, 0xc6, 0x84, 0x91, 0x12, 0x4b, + 0x41, 0xf2, 0xbc, 0x5a, 0x52, 0x29, 0x99, 0x0c, 0x5e, 0xb0, 0x9f, 0x0c, + 0xd4, 0xc5, 0x6e, 0xed, 0xf9, 0xb0, 0xc1, 0xc1, 0x7d, 0xae, 0x67, 0x4c, + 0xc0, 0x55, 0xf4, 0xed, 0x03, 0xad, 0xc5, 0xb4, 0x83, 0xfe, 0xec, 0x16, + 0x70, 0x08, 0xdd, 0x5c, 0x45, 0xb4, 0xb7, 0x99, 0x9b, 0xec, 0xa0, 0x06, + 0x42, 0x44, 0xd0, 0x9f, 0xda, 0x05, 0xb7, 0xef, 0x7c, 0xd5, 0xa3, 0x0f, + 0x4c, 0x36, 0xf7, 0x92, 0x98, 0xc4, 0x64, 0x89, 0xa7, 0x2a, 0x39, 0x41, + 0xa1, 0x28, 0xcb, 0xc4, 0xc1, 0x77, 0xda, 0x49, 0xf7, 0xfa, 0xb3, 0x72, + 0x93, 0xa0, 0xad, 0x09, 0x9b, 0xd9, 0x82, 0x44, 0xf6, 0x84, 0x9c, 0xbf, + 0xad, 0x73, 0xde, 0x15, 0x76, 0xee, 0x9c, 0x4f, 0xce, 0x5f, 0x5d, 0xf4, + 0x90, 0x51, 0xfc, 0xaf, 0xfc, 0x59, 0x2a, 0x70, 0x92, 0x66, 0xeb, 0xd3, + 0x04, 0x29, 0xc8, 0xc2, 0x49, 0x40, 0x9a, 0xac, 0xff, 0x94, 0x31, 0x42, + 0x81, 0x83, 0x17, 0x6f, 0x87, 0xdc, 0x62, 0xe7, 0x74, 0x50, 0xc9, 0xc6, + 0x83, 0xbf, 0x7a, 0xe0, 0xae, 0x11, 0xbd, 0x86, 0x0f, 0x02, 0xdc, 0x2a, + 0x58, 0xee, 0x50, 0x04, 0xcf, 0x28, 0x7d, 0xa0, 0xdf, 0xd8, 0x2b, 0xec, + 0xe3, 0x79, 0xff, 0xd9, 0x2b, 0xc3, 0x23, 0x3a, 0x4a, 0x19, 0x26, 0x69, + 0x7c, 0x5a, 0xcb, 0xf5, 0x66, 0x11, 0xdd, 0x7e, 0x4f, 0x99, 0xc6, 0xf2, + 0x6f, 0xf6, 0xe5, 0x3f, 0x60, 0x46, 0xfe, 0x52, 0x26, 0xab, 0x3a, 0xcc, + 0x48, 0xbf, 0xdf, 0xcc, 0xaf, 0x67, 0xc5, 0x02, 0x99, 0x93, 0x43, 0x0b, + 0x11, 0x31, 0xda, 0x9c, 0xa6, 0x64, 0xb9, 0x4b, 0xed, 0x05, 0x56, 0xf8, + 0x75, 0xdf, 0xbc, 0x7d, 0xfd, 0xee, 0x69, 0x59, 0xfb, 0x68, 0x7e, 0xfd, + 0x94, 0xd3, 0x46, 0x1d, 0xa2, 0x61, 0x59, 0x8c, 0x7b, 0x05, 0x58, 0x07, + 0x8a, 0xfe, 0x37, 0x7b, 0xbc, 0x9c, 0x40, 0x04, 0x4d, 0x08, 0x31, 0xca, + 0x3c, 0xb9, 0x74, 0x67, 0x46, 0xbc, 0xc9, 0x79, 0x78, 0x4e, 0x60, 0xbf, + 0xf8, 0x92, 0x51, 0xa4, 0xda, 0x35, 0xfd, 0xe8, 0x89, 0x4b, 0xe0, 0xc8, + 0x9c, 0xb2, 0xbe, 0xb9, 0x3c, 0x26, 0x4b, 0x6a, 0x8a, 0xfa, 0xa8, 0x5c, + 0xd3, 0x0b, 0x9a, 0x86, 0xd9, 0x5a, 0xa1, 0x2b, 0x13, 0x2d, 0xf1, 0xe9, + 0xde, 0x99, 0x78, 0x0d, 0xc9, 0xae, 0x6d, 0x4e, 0x8e, 0x3c, 0x25, 0x2d, + 0x1f, 0xb1, 0x04, 0x69, 0x86, 0x4b, 0x23, 0xc3, 0x70, 0x8c, 0x5d, 0x08, + 0xc0, 0x3b, 0x8f, 0x88, 0x8f, 0x82, 0x42, 0x20, 0xef, 0xf8, 0xbb, 0x92, + 0x06, 0x8b, 0x19, 0x3e, 0xc6, 0x34, 0xa5, 0x95, 0x90, 0xf0, 0x16, 0xac, + 0xee, 0x4b, 0xed, 0x7c, 0xb6, 0x83, 0x2a, 0x67, 0x14, 0x8d, 0xec, 0x4c, + 0xe5, 0x6e, 0x96, 0x92, 0xa6, 0x05, 0x2a, 0xb1, 0x57, 0xb8, 0x7c, 0x31, + 0xc7, 0x56, 0xf4, 0xf3, 0xc9, 0x06, 0x3f, 0x51, 0x8e, 0x93, 0x45, 0xe6, + 0x22, 0xed, 0x44, 0x71, 0xff, 0x61, 0x38, 0x7f, 0xc4, 0x57, 0xff, 0x3c, + 0x04, 0x1a, 0xa1, 0xc8, 0x80, 0xb0, 0x97, 0x30, 0x2b, 0x17, 0xe5, 0x67, + 0xa2, 0x54, 0x38, 0xdc, 0x5e, 0x48, 0x27, 0xe8, 0x08, 0xd7, 0xfd, 0xef, + 0x99, 0x34, 0xb1, 0x40, 0x06, 0x14, 0x49, 0x43, 0x2b, 0x18, 0xbe, 0x5a, + 0x1d, 0xc1, 0x8e, 0xcf, 0x0a, 0xca, 0xf0, 0x13, 0x5b, 0x8b, 0x3f, 0xe8, + 0x3c, 0xa0, 0x84, 0x46, 0x09, 0x69, 0x14, 0x70, 0x1f, 0x06, 0x61, 0x3d, + 0xd3, 0x25, 0x24, 0x5f, 0x37, 0x0b, 0x36, 0xea, 0xbd, 0xce, 0xd9, 0xb5, + 0x0f, 0x21, 0x84, 0x25, 0xb4, 0x8b, 0x34, 0xe5, 0x41, 0xa7, 0x58, 0x47, + 0xcc, 0x97, 0x91, 0x1e, 0xcc, 0x63, 0x88, 0x8b, 0x84, 0xb9, 0xf7, 0x0c, + 0x59, 0xb4, 0x28, 0x8a, 0xa8, 0xcc, 0xa9, 0xc4, 0x9a, 0xb6, 0x2e, 0xca, + 0x0d, 0x8c, 0x52, 0x08, 0x9b, 0xd7, 0xee, 0x2a, 0x1b, 0x0e, 0xde, 0x81, + 0x38, 0x62, 0x97, 0x43, 0xe3, 0xd2, 0x20, 0x5a, 0x30, 0x92, 0xe9, 0x1f, + 0x14, 0x99, 0x69, 0x8c, 0xa1, 0x13, 0xc8, 0x48, 0x4e, 0xf5, 0x73, 0x3a, + 0xf4, 0xa1, 0xfb, 0xf4, 0x7c, 0xfb, 0x3f, 0x2d, 0xe6, 0x2d, 0x78, 0x10, + 0x03, 0x70, 0x7c, 0xc1, 0x90, 0x96, 0x4f, 0x09, 0x04, 0xfd, 0x03, 0x55, + 0xf7, 0x1a, 0x58, 0x5f, 0x6a, 0x26, 0x25, 0x80, 0xc6, 0x9f, 0xf7, 0x1b, + 0x45, 0x06, 0xdc, 0xcd, 0xf4, 0x65, 0x4b, 0xfb, 0xbe, 0xd7, 0x45, 0x19, + 0x1d, 0x41, 0x90, 0x82, 0x39, 0x14, 0x83, 0x35, 0x9c, 0xf3, 0xd7, 0x9f, + 0x9a, 0x70, 0x43, 0x03, 0x90, 0xde, 0x6d, 0x84, 0xb0, 0xe9, 0x55, 0x68, + 0xfb, 0xcd, 0xfb, 0x3c, 0x9b, 0x44, 0xb0, 0x22, 0x8b, 0x97, 0x79, 0x83, + 0xe9, 0xee, 0x5b, 0x59, 0xab, 0x8a, 0x69, 0x85, 0x37, 0x57, 0x11, 0x8f, + 0x97, 0x21, 0x80, 0xa1, 0x2c, 0x89, 0xc9, 0xed, 0x6c, 0xce, 0x4d, 0xb5, + 0xe2, 0xb7, 0xd2, 0xc4, 0xa2, 0x70, 0xe1, 0xb4, 0x45, 0x78, 0x2f, 0x0e, + 0x63, 0x06, 0x33, 0xc7, 0x9d, 0x1a, 0x52, 0x13, 0xdf, 0xda, 0xdb, 0xe8, + 0x57, 0x49, 0x1d, 0x81, 0xac, 0x71, 0x8c, 0x64, 0x90, 0x29, 0x19, 0xd1, + 0x33, 0xf9, 0xc0, 0xce, 0x13, 0xf2, 0x59, 0x16, 0xf0, 0xea, 0x6a, 0x75, + 0x78, 0x07, 0x75, 0xf0, 0xf9, 0x0a, 0x66, 0x52, 0x48, 0xd0, 0x4e, 0xd0, + 0x6b, 0x89, 0xd6, 0x9b, 0xef, 0x7e, 0xef, 0x23, 0x29, 0x0a, 0x4c, 0x28, + 0xe4, 0xc8, 0x1f, 0x15, 0x13, 0x3a, 0xca, 0x98, 0x20, 0x7f, 0xe2, 0x9d, + 0x2a, 0xe6, 0x1c, 0x77, 0xa5, 0x06, 0xe3, 0x19, 0xce, 0x7f, 0x38, 0xcf, + 0x5e, 0xd1, 0xef, 0xf8, 0x81, 0x20, 0xfa, 0x98, 0x45, 0x9f, 0x2b, 0x27, + 0xe0, 0x73, 0x8c, 0xe1, 0x01, 0x2c, 0x05, 0x0a, 0xa7, 0x19, 0xd9, 0xe5, + 0xf6, 0x06, 0xd4, 0x02, 0xdb, 0xee, 0x38, 0x41, 0x35, 0x02, 0x48, 0xa4, + 0x72, 0x0a, 0xa2, 0x6c, 0x6a, 0x8a, 0x18, 0x08, 0x4b, 0x26, 0x44, 0xa4, + 0x0a, 0x1e, 0x20, 0xcf, 0xfc, 0xa8, 0x72, 0x37, 0xe6, 0xe4, 0xea, 0xb4, + 0x4c, 0xe9, 0xe5, 0x6e, 0x1c, 0x57, 0x83, 0x2f, 0x44, 0x50, 0xc0, 0x3c, + 0x37, 0x07, 0x38, 0xbd, 0x6a, 0xc7, 0x88, 0x90, 0x0b, 0x7d, 0xe9, 0x20, + 0x2a, 0xbc, 0x73, 0xad, 0x07, 0x60, 0x52, 0x9a, 0x47, 0x2f, 0xe2, 0xc6, + 0x9a, 0xc0, 0x0d, 0x37, 0x12, 0x60, 0x99, 0x51, 0xfc, 0x5e, 0xdf, 0xc0, + 0x23, 0x7f, 0x47, 0xa2, 0x5c, 0xa6, 0x2f, 0xa5, 0x62, 0x13, 0xc6, 0x3b, + 0x61, 0xf1, 0x52, 0xe1, 0x90, 0x9b, 0xba, 0x4a, 0x67, 0x02, 0x3f, 0xfd, + 0x8d, 0xfe, 0xd7, 0xe1, 0xed, 0xd6, 0x26, 0x3a, 0xd9, 0x48, 0x3c, 0x00, + 0x11, 0x36, 0x33, 0x18, 0x6c, 0x9e, 0x57, 0x89, 0xe5, 0x44, 0xfe, 0xae, + 0x69, 0xd9, 0x4c, 0x22, 0x1f, 0x18, 0xe9, 0x07, 0xf8, 0xbf, 0x42, 0x8c, + 0x0b, 0xf1, 0xb5, 0x6c, 0x95, 0x2f, 0xcb, 0x0c, 0x85, 0x90, 0xc0, 0xfa, + 0x98, 0xcb, 0x32, 0xd8, 0xfb, 0x1a, 0x57, 0x49, 0xf5, 0xea, 0x9b, 0x27, + 0x3d, 0xf6, 0x11, 0xf5, 0xfc, 0xa9, 0x7f, 0xca, 0xe3, 0xf5, 0xb3, 0x50, + 0xd5, 0x78, 0xcf, 0x28, 0x99, 0x82, 0x11, 0x96, 0x46, 0x51, 0x00, 0x25, + 0x56, 0x4e, 0xf6, 0xa6, 0x59, 0xd3, 0x97, 0xdf, 0x0c, 0x1f, 0x4e, 0xa6, + 0x69, 0x50, 0x2f, 0xad, 0xe4, 0x84, 0x8b, 0x82, 0xc6, 0x45, 0x2f, 0xb8, + 0x07, 0x9a, 0x5c, 0x1e, 0xa8, 0xe7, 0x9a, 0xcc, 0xff, 0xf4, 0x89, 0x30, + 0xa7, 0x52, 0x9b, 0x99, 0x65, 0x28, 0xda, 0xef, 0x4f, 0x5a, 0x8c, 0x27, + 0x36, 0x4a, 0x06, 0x5d, 0xc0, 0x5c, 0x79, 0x96, 0xbf, 0x2d, 0xd6, 0xcb, + 0xa4, 0xcc, 0xc7, 0x15, 0xa0, 0x93, 0xb0, 0x2f, 0xa1, 0x19, 0x5f, 0x6e, + 0x66, 0x94, 0xe7, 0x37, 0x74, 0xf8, 0x22, 0x57, 0xed, 0xca, 0x0f, 0x0d, + 0x31, 0x54, 0xe2, 0x5b, 0xc6, 0xb1, 0x3d, 0x97, 0xb5, 0xdb, 0xaa, 0x5d, + 0x60, 0x0f, 0x08, 0x22, 0x1e, 0x2d, 0x80, 0x99, 0x92, 0x1a, 0x4d, 0x2d, + 0x90, 0x41, 0x38, 0x40, 0x0d, 0x07, 0xe0, 0xbc, 0x0c, 0x76, 0x58, 0x61, + 0xb2, 0xd1, 0x4b, 0x97, 0x68, 0x12, 0x3f, 0x6a, 0x4f, 0xc3, 0xf9, 0x1f, + 0xc8, 0x58, 0x39, 0x7b, 0xbc, 0x7f, 0x5a, 0xf9, 0xc4, 0x1a, 0x14, 0x88, + 0x27, 0x1d, 0xc6, 0xf6, 0x66, 0x95, 0x87, 0xcb, 0x99, 0xee, 0x50, 0x8d, + 0x56, 0xff, 0x90, 0x0b, 0xb4, 0x94, 0x77, 0xcb, 0x06, 0x63, 0x7a, 0x65, + 0xf1, 0xfc, 0x35, 0x59, 0x68, 0xee, 0x50, 0x25, 0xf2, 0x5c, 0xff, 0x28, + 0x9e, 0xd1, 0xd5, 0xea, 0x84, 0x14, 0x90, 0x28, 0xfc, 0x5f, 0xa0, 0x3e, + 0xc8, 0xee, 0x61, 0xeb, 0x05, 0x9c, 0x6e, 0x44, 0x58, 0x78, 0xfc, 0xfe, + 0x0c, 0xb5, 0x01, 0xf9, 0xab, 0xf3, 0xbf, 0xcd, 0x6f, 0x8e, 0x31, 0xdc, + 0x4a, 0xb4, 0x12, 0xe9, 0x8a, 0x15, 0x90, 0x62, 0x4d, 0xc1, 0xef, 0xbf, + 0x53, 0xeb, 0x8f, 0x90, 0x1d, 0x17, 0xbf, 0xc7, 0xa3, 0x0c, 0x35, 0x26, + 0x76, 0x9b, 0xa4, 0x56, 0xf0, 0xfc, 0x41, 0xe0, 0x96, 0x02, 0x75, 0x9b, + 0x0f, 0xfe, 0x1a, 0x9c, 0x10, 0x79, 0xa5, 0xfa, 0x2c, 0x5b, 0x6f, 0xfa, + 0xf3, 0x16, 0xea, 0xca, 0xed, 0xb5, 0xe9, 0xd3, 0x73, 0xf0, 0x41, 0x29, + 0x98, 0x4a, 0x00, 0x10, 0x03, 0xe8, 0x02, 0x6f, 0x15, 0xf8, 0x42, 0x65, + 0xb6, 0x8b, 0xf7, 0x12, 0x96, 0x55, 0xf6, 0x0e, 0x38, 0xaa, 0xc7, 0x6f, + 0x70, 0x7b, 0x40, 0x0f, 0xce, 0x02, 0xa7, 0xe3, 0xba, 0x8f, 0xff, 0xaa, + 0x76, 0x7e, 0x3c, 0xc9, 0x43, 0x98, 0x59, 0xa5, 0x4c, 0x68, 0x99, 0x03, + 0x01, 0x45, 0x11, 0x0d, 0x04, 0x60, 0xfa, 0x9d, 0xa9, 0xf7, 0xfd, 0x9e, + 0x3b, 0xac, 0xc6, 0xf9, 0xdd, 0xd2, 0x8c, 0x9b, 0x13, 0x58, 0x83, 0xcc, + 0x69, 0x6e, 0x63, 0x58, 0x79, 0x80, 0x10, 0xc6, 0x61, 0x21, 0xe0, 0x61, + 0x42, 0xac, 0x07, 0x95, 0xfd, 0xbd, 0xb7, 0xa8, 0x17, 0xed, 0x71, 0xc2, + 0x58, 0xf3, 0x36, 0x5e, 0x4e, 0x09, 0xe0, 0x3f, 0x6e, 0x1d, 0x28, 0x7c, + 0x4b, 0x9d, 0x1f, 0xd7, 0x84, 0x27, 0x29, 0xd3, 0x1f, 0xcf, 0x0a, 0xfc, + 0xdb, 0x3a, 0xde, 0xda, 0xd1, 0x3a, 0x50, 0x4a, 0x5a, 0x82, 0x80, 0x48, + 0xd1, 0x38, 0x49, 0x9d, 0x88, 0xb7, 0x39, 0x16, 0xa7, 0xb7, 0xbb, 0xdf, + 0x82, 0xfa, 0xa4, 0x08, 0xca, 0x13, 0x20, 0xe4, 0xcc, 0x69, 0x10, 0x89, + 0x85, 0xdc, 0xfe, 0xca, 0xd5, 0xbb, 0x1c, 0x75, 0x71, 0x94, 0x70, 0xce, + 0x46, 0x58, 0x33, 0x92, 0x5d, 0x61, 0x29, 0xe4, 0xa1, 0xaf, 0xed, 0x8e, + 0x35, 0x89, 0xa7, 0x45, 0x82, 0x33, 0x85, 0xa5, 0x36, 0x9f, 0x70, 0xbd, + 0xf4, 0x63, 0x5d, 0xc2, 0x3c, 0xd8, 0xea, 0x53, 0x7b, 0x6a, 0xf0, 0xa9, + 0x19, 0xbb, 0x9b, 0x1d, 0xf5, 0xaf, 0x4e, 0x71, 0xf4, 0xae, 0x44, 0x12, + 0x18, 0x71, 0x03, 0x4d, 0x9d, 0x04, 0x89, 0x47, 0xc4, 0x02, 0x69, 0xb9, + 0x6b, 0x79, 0x76, 0x29, 0x6f, 0xe6, 0x9b, 0x40, 0xe8, 0x4b, 0x94, 0x84, + 0xd1, 0x90, 0x3d, 0xaf, 0xcf, 0x3e, 0xdb, 0xe5, 0xec, 0x5e, 0x2d, 0x7f, + 0x1a, 0x92, 0x32, 0x10, 0xcc, 0xcb, 0xb5, 0xf0, 0x13, 0x15, 0xb4, 0x2e, + 0xec, 0x11, 0x65, 0x90, 0x42, 0x1b, 0xb5, 0x20, 0xa7, 0x7c, 0x92, 0xd1, + 0x33, 0x9d, 0xea, 0xa8, 0x46, 0xca, 0x2a, 0x60, 0x3d, 0xcf, 0x5d, 0x8f, + 0xa5, 0x25, 0x42, 0xe5, 0xff, 0x2a, 0x0b, 0x60, 0xcf, 0xfd, 0x8c, 0xb7, + 0xd9, 0x83, 0xa2, 0xc9, 0x6f, 0xc2, 0x5a, 0x30, 0xc2, 0xd8, 0x41, 0xd7, + 0x9a, 0xbe, 0x1b, 0xfe, 0x3c, 0xa3, 0x0f, 0x2d, 0x02, 0xe0, 0x4a, 0x66, + 0x92, 0x2d, 0xb4, 0x11, 0x48, 0xcb, 0xed, 0x04, 0xd9, 0xd1, 0x5b, 0xe3, + 0x7f, 0x9f, 0x99, 0x3b, 0x92, 0x95, 0x51, 0x64, 0x3a, 0x5d, 0x94, 0xce, + 0xfb, 0x73, 0xf1, 0xde, 0x2b, 0xf0, 0xcf, 0xb2, 0x00, 0x44, 0xe4, 0x92, + 0xbd, 0x3f, 0x5b, 0xa5, 0x1f, 0x97, 0xeb, 0x84, 0x52, 0x18, 0xd5, 0xad, + 0x79, 0x2d, 0x47, 0xfd, 0x24, 0xa3, 0x43, 0x2d, 0x0f, 0xa2, 0x9a, 0xd0, + 0xe5, 0x70, 0x23, 0x04, 0x82, 0x3d, 0x84, 0xab, 0x22, 0xf8, 0x82, 0x90, + 0x48, 0x56, 0x50, 0xb7, 0x9a, 0x41, 0x2d, 0xfc, 0x6f, 0x25, 0x0b, 0x86, + 0x01, 0x8b, 0x35, 0x18, 0xc4, 0xa4, 0x68, 0x78, 0x3a, 0x99, 0xd4, 0xa0, + 0xd3, 0xa3, 0x23, 0xf5, 0xde, 0x69, 0xba, 0x22, 0x60, 0x89, 0x56, 0x51, + 0x87, 0xe9, 0xea, 0x48, 0xbc, 0xdf, 0xe2, 0x9e, 0x7b, 0xfc, 0x88, 0x6b, + 0x6a, 0xe9, 0x65, 0xb8, 0x9c, 0xe9, 0x72, 0x28, 0xc9, 0xe9, 0x89, 0x11, + 0xf1, 0x2a, 0xd1, 0x4f, 0x7e, 0xf9, 0x5e, 0x07, 0x4f, 0xee, 0xdc, 0x82, + 0x4a, 0x53, 0x30, 0xf9, 0x96, 0x85, 0x1f, 0x99, 0xac, 0xd9, 0xfa, 0x44, + 0xa4, 0xe5, 0x4f, 0x16, 0xe7, 0x9c, 0x42, 0x11, 0x2d, 0x95, 0x2c, 0xbf, + 0x00, 0x17, 0x9e, 0x98, 0xc9, 0x9e, 0x77, 0x85, 0xe2, 0x0b, 0x29, 0xb7, + 0xa2, 0x4f, 0x04, 0xc9, 0x2d, 0xa3, 0x04, 0x8f, 0x82, 0x5e, 0x16, 0x58, + 0x33, 0x00, 0x21, 0x34, 0x72, 0xe4, 0x2a, 0xd9, 0x44, 0x7a, 0x63, 0xfc, + 0xf5, 0xa5, 0x80, 0x7f, 0x9e, 0xb6, 0xb9, 0xa5, 0xe3, 0xb4, 0x99, 0x1f, + 0x4d, 0x61, 0x1e, 0xcd, 0xa6, 0x37, 0x9f, 0x38, 0x8c, 0xfa, 0x28, 0xa5, + 0x81, 0x18, 0xe4, 0xbb, 0x29, 0xcf, 0x1c, 0x74, 0xd7, 0x69, 0xa7, 0xd9, + 0xed, 0x4c, 0x10, 0x93, 0xf3, 0x47, 0x81, 0xe7, 0x90, 0x32, 0x6d, 0xc4, + 0x74, 0x2a, 0xcd, 0x2f, 0x04, 0xd2, 0x00, 0xcc, 0x20, 0x7e, 0x71, 0xab, + 0x73, 0xf4, 0xda, 0xd9, 0xe2, 0xf7, 0x2c, 0xf4, 0x86, 0x42, 0x85, 0x13, + 0x47, 0x25, 0x2e, 0xe0, 0x65, 0x6f, 0x5a, 0x22, 0xbc, 0x1c, 0xf1, 0x8f, + 0x87, 0xff, 0xda, 0x99, 0x50, 0x54, 0xa4, 0x48, 0x47, 0x0f, 0xf6, 0x2d, + 0xdf, 0x99, 0xc9, 0xb4, 0xb4, 0x67, 0x8c, 0x06, 0x3e, 0x80, 0xf9, 0x9a, + 0x03, 0x25, 0x97, 0x84, 0x04, 0x93, 0x97, 0xa5, 0x52, 0xc4, 0x43, 0x0e, + 0x91, 0x45, 0x0c, 0x06, 0xf5, 0x15, 0x89, 0x47, 0x15, 0xba, 0xaa, 0x03, + 0x90, 0xf1, 0x43, 0x8a, 0x33, 0xc6, 0xc7, 0x19, 0x21, 0x47, 0x00, 0xac, + 0x89, 0xec, 0xa9, 0xb6, 0xb8, 0x34, 0x7b, 0xf2, 0x51, 0xd3, 0xf9, 0xf4, + 0x18, 0x19, 0x87, 0xd0, 0x07, 0x54, 0x70, 0xf9, 0x79, 0x74, 0x51, 0xee, + 0x41, 0x0d, 0xfa, 0xed, 0x8f, 0x0e, 0x2f, 0xf7, 0xd4, 0x8b, 0xc3, 0xb5, + 0x72, 0x26, 0x5c, 0xe5, 0xbe, 0x9c, 0x3e, 0x01, 0x04, 0xfc, 0x6d, 0x7b, + 0xc2, 0x4f, 0xfe, 0x2c, 0x5e, 0xea, 0xf1, 0x64, 0x31, 0xc5, 0x31, 0x31, + 0x42, 0x7d, 0x98, 0x80, 0x64, 0x42, 0x47, 0xc4, 0x45, 0xed, 0xfc, 0xf2, + 0x9f, 0x45, 0xad, 0xda, 0xaf, 0x51, 0x61, 0x97, 0x45, 0x68, 0x31, 0xc9, + 0xa1, 0x46, 0x5e, 0x03, 0xa9, 0xaa, 0x05, 0x14, 0x51, 0x61, 0xe9, 0xbd, + 0x58, 0x6c, 0x6d, 0x09, 0xd2, 0x48, 0x65, 0x7d, 0x79, 0xd9, 0xc9, 0x1e, + 0xca, 0xa5, 0xdc, 0xa7, 0x86, 0x77, 0xd6, 0x41, 0x45, 0x0f, 0x88, 0x7e, + 0xb1, 0xa5, 0xfa, 0xdd, 0xaa, 0x2d, 0xa8, 0x89, 0xa1, 0x32, 0x3b, 0x0b, + 0xe0, 0x0a, 0xf5, 0x72, 0x29, 0x9c, 0x03, 0xce, 0x00, 0x42, 0x46, 0x06, + 0x79, 0xbc, 0xd2, 0xfd, 0x23, 0x08, 0x00, 0x7c, 0xad, 0x65, 0xc5, 0x69, + 0x51, 0xa8, 0xcc, 0x68, 0x45, 0x7b, 0xc4, 0x72, 0xdc, 0xf0, 0x43, 0xd0, + 0xa3, 0x24, 0x94, 0x4f, 0xd3, 0x03, 0x53, 0xf9, 0x47, 0xf2, 0xcd, 0x79, + 0xa7, 0x4b, 0x7c, 0xbb, 0x69, 0x00, 0x51, 0xaf, 0x4e, 0x11, 0xf1, 0x3e, + 0x80, 0xaa, 0x8d, 0x57, 0x2f, 0xc9, 0x6a, 0xff, 0x3d, 0xbc, 0xdb, 0xad, + 0xea, 0x75, 0xfb, 0xdb, 0x70, 0x64, 0xd1, 0x1b, 0xed, 0x4a, 0x55, 0x01, + 0xe0, 0x6d, 0x99, 0x6f, 0x17, 0x56, 0x2d, 0x1e, 0x17, 0x47, 0x26, 0x1d, + 0x50, 0xcf, 0x00, 0xdc, 0xb2, 0x28, 0x2a, 0x9f, 0xd7, 0xf7, 0x2e, 0xb6, + 0xb9, 0xe3, 0x91, 0xca, 0x9e, 0x58, 0xdb, 0x64, 0x4a, 0x42, 0x31, 0xfa, + 0x8a, 0xba, 0x7c, 0xa5, 0x8a, 0x76, 0xce, 0xdc, 0x47, 0xe3, 0xf8, 0xeb, + 0x3a, 0xdc, 0x90, 0xb1, 0xc4, 0x28, 0x1c, 0xaa, 0x08, 0x51, 0xfb, 0x74, + 0x76, 0xbd, 0x83, 0x75, 0x3e, 0xef, 0x2d, 0xb3, 0x21, 0x60, 0x04, 0xa2, + 0xf8, 0x05, 0x14, 0x72, 0xa8, 0x61, 0x20, 0xe5, 0x26, 0x77, 0x71, 0x70, + 0x4f, 0x8a, 0xfa, 0x3b, 0x88, 0x7b, 0x59, 0x65, 0x10, 0xdd, 0xa2, 0x22, + 0x55, 0x58, 0x28, 0xfc, 0xb5, 0xe9, 0x91, 0x7a, 0xf2, 0x35, 0x08, 0x50, + 0x9a, 0x5f, 0xd2, 0xda, 0xb6, 0x5b, 0xda, 0xb9, 0x14, 0x83, 0xb2, 0x5f, + 0xee, 0x73, 0x0f, 0xa8, 0x6c, 0xb3, 0xe2, 0x4a, 0x47, 0xc1, 0x3d, 0xf5, + 0x44, 0x8d, 0x50, 0xfa, 0xa2, 0x3e, 0x85, 0xf0, 0x1f, 0x7d, 0x49, 0x47, + 0xc5, 0x43, 0x7f, 0x40, 0xa5, 0xe2, 0x09, 0x03, 0xae, 0x98, 0x4b, 0xd3, + 0x07, 0xb9, 0x1e, 0x05, 0x7c, 0xf1, 0xb1, 0xe7, 0x26, 0xd6, 0xc9, 0xc9, + 0x0f, 0x06, 0xd6, 0x9d, 0xfc, 0x2a, 0xdb, 0x7f, 0x43, 0x39, 0x61, 0x69, + 0x32, 0xe7, 0x98, 0xdb, 0xde, 0x51, 0xd7, 0x21, 0xd1, 0x2a, 0x84, 0x9d, + 0x16, 0x32, 0xa1, 0x4e, 0x70, 0x41, 0x23, 0x97, 0x2f, 0xa2, 0x4f, 0x4e, + 0xb4, 0x97, 0xae, 0x5e, 0x6f, 0x05, 0x03, 0x7a, 0x23, 0x40, 0x3c, 0x2d, + 0x42, 0xa5, 0x95, 0x6c, 0x40, 0xec, 0x65, 0x30, 0x72, 0x8e, 0x11, 0x0c, + 0x49, 0xa0, 0x9b, 0x28, 0xcf, 0x9f, 0xca, 0x67, 0x7b, 0xa0, 0x68, 0x16, + 0xf1, 0x31, 0xe3, 0x6f, 0xc2, 0xb6, 0xee, 0xf3, 0xd6, 0xb6, 0x68, 0x19, + 0x86, 0x97, 0xc5, 0x22, 0x57, 0xa8, 0x1b, 0xe4, 0x78, 0xd7, 0x1d, 0xf9, + 0xe8, 0xcf, 0x15, 0x9b, 0x73, 0x48, 0xc2, 0xd5, 0x50, 0xd1, 0x6d, 0x3d, + 0xf8, 0xfd, 0xdb, 0x57, 0x90, 0x60, 0xdf, 0x30, 0xdd, 0x85, 0x47, 0xc6, + 0xa3, 0x5e, 0x19, 0xef, 0x8c, 0xd9, 0x29, 0xe2, 0x46, 0x59, 0xb1, 0x72, + 0x9d, 0x59, 0xbf, 0x72, 0xae, 0x37, 0x1c, 0xc4, 0x87, 0xc5, 0x23, 0x15, + 0xc3, 0xc2, 0xcb, 0xe1, 0x1a, 0x52, 0x48, 0x21, 0xf7, 0x20, 0xd8, 0xb9, + 0xdf, 0xbd, 0xd5, 0x4e, 0x45, 0x50, 0x29, 0x16, 0xe4, 0xc8, 0x4d, 0xf1, + 0x8a, 0x34, 0x61, 0x0e, 0x50, 0xca, 0x22, 0x7e, 0x22, 0x31, 0xd9, 0xc5, + 0x67, 0xa6, 0x83, 0x1a, 0x5c, 0x91, 0x0c, 0xf2, 0xdf, 0x19, 0x9d, 0x00, + 0x95, 0x0f, 0x72, 0xba, 0xa2, 0xd9, 0xff, 0x1f, 0xc7, 0x45, 0xbc, 0xcc, + 0x49, 0x90, 0xc9, 0x78, 0xc1, 0x8e, 0x98, 0x51, 0x10, 0x34, 0xf6, 0xc9, + 0x64, 0xd5, 0x55, 0x14, 0xc5, 0xc5, 0x71, 0x2e, 0x51, 0x79, 0xbe, 0xaa, + 0xff, 0xa6, 0xb3, 0x8d, 0x62, 0x34, 0x49, 0x63, 0xa3, 0x51, 0xd0, 0x91, + 0x23, 0x29, 0x11, 0xe2, 0x85, 0xdc, 0xd2, 0x61, 0x57, 0x25, 0x76, 0x2b, + 0x42, 0x08, 0x69, 0xac, 0x57, 0xa4, 0x35, 0x34, 0x4b, 0xd5, 0x86, 0xf0, + 0x35, 0x9d, 0xb9, 0x17, 0x98, 0xbe, 0x69, 0x70, 0xd9, 0xcd, 0x0f, 0xe5, + 0xe5, 0xaf, 0x97, 0x1f, 0xa4, 0xc7, 0xd3, 0x8b, 0x22, 0x32, 0x78, 0x49, + 0x84, 0x64, 0xaa, 0xe7, 0xe9, 0x86, 0xd8, 0xb8, 0xad, 0xe9, 0xc5, 0x11, + 0xcb, 0xf3, 0xad, 0xb5, 0x14, 0xa5, 0xe2, 0xf1, 0x43, 0xb5, 0xdf, 0xd3, + 0x7e, 0xb7, 0x9e, 0x50, 0x68, 0xf6, 0xcb, 0x9e, 0x43, 0x4b, 0xf5, 0x19, + 0x0c, 0xa9, 0x1f, 0xd6, 0x14, 0x0e, 0xdc, 0xe0, 0x09, 0x64, 0xa5, 0xe6, + 0x02, 0x95, 0x71, 0x7c, 0xed, 0xb9, 0xb4, 0x87, 0x6c, 0x96, 0x50, 0xcc, + 0x13, 0xa1, 0x36, 0xee, 0xbf, 0x7e, 0xdc, 0x58, 0xf7, 0x7f, 0xd1, 0x04, + 0x13, 0x01, 0xa4, 0x6d, 0xb4, 0x9a, 0x1a, 0xd0, 0x9e, 0x4f, 0xe0, 0xe7, + 0xdc, 0x93, 0xb6, 0xfd, 0xd4, 0x54, 0xd8, 0xed, 0x0b, 0xeb, 0x38, 0x5b, + 0xfe, 0xde, 0xf9, 0x0e, 0x0f, 0xad, 0x17, 0x04, 0x84, 0x2c, 0x25, 0x0f, + 0x99, 0xd2, 0x10, 0xcb, 0x19, 0x1a, 0xcc, 0x59, 0x6f, 0xe8, 0x17, 0x6f, + 0xe5, 0x04, 0xb3, 0x40, 0x00, 0x02, 0x40, 0x77, 0x01, 0x1b, 0x6a, 0xb0, + 0x55, 0xf7, 0x29, 0x1c, 0x95, 0x64, 0x42, 0xdd, 0xbf, 0x21, 0x1d, 0xa9, + 0x43, 0x24, 0x8b, 0xfc, 0x52, 0xc0, 0xce, 0x58, 0x00, 0xf0, 0x1d, 0x19, + 0x7d, 0x2c, 0x52, 0xfe, 0x5f, 0x3d, 0x5e, 0x94, 0x05, 0x22, 0x72, 0x87, + 0x80, 0xb1, 0x4b, 0xb4, 0x94, 0xb2, 0x4d, 0x2f, 0x8e, 0x25, 0xbb, 0x22, + 0x6c, 0x35, 0x03, 0x4c, 0xcd, 0x16, 0x45, 0xf2, 0x64, 0x9f, 0x82, 0x08, + 0x78, 0x33, 0x8d, 0x1a, 0x20, 0x78, 0xbb, 0x99, 0xbf, 0xf8, 0x4e, 0x91, + 0x76, 0x5d, 0x26, 0x18, 0x5b, 0x0c, 0xf0, 0x42, 0x6a, 0xa0, 0x71, 0xfe, + 0xa7, 0xd2, 0x26, 0xd1, 0x69, 0x5e, 0x73, 0x42, 0x1d, 0xb0, 0x99, 0xd6, + 0x49, 0x03, 0xe2, 0x2e, 0x1d, 0xd1, 0x86, 0x6c, 0x95, 0xf5, 0x14, 0x13, + 0x56, 0xb5, 0x6e, 0x0a, 0xde, 0x8a, 0x28, 0x62, 0x37, 0x9d, 0x99, 0x29, + 0xd0, 0x86, 0x14, 0x26, 0x81, 0x6a, 0xa8, 0x07, 0xbb, 0x23, 0x58, 0x54, + 0xd7, 0x5a, 0x36, 0xef, 0xe7, 0xd8, 0x1b, 0x86, 0xba, 0x6e, 0x29, 0xe6, + 0x9c, 0x91, 0xb8, 0x19, 0xe7, 0xb3, 0x03, 0xba, 0x1a, 0x39, 0x64, 0x34, + 0x8f, 0x72, 0x0f, 0x2d, 0xff, 0x0d, 0x8a, 0xaf, 0x34, 0x4e, 0x31, 0xf6, + 0x64, 0xbb, 0x5c, 0x0c, 0x66, 0x87, 0xb4, 0xd0, 0x95, 0x37, 0x98, 0x14, + 0x48, 0x01, 0x10, 0x8d, 0x60, 0x1b, 0xd2, 0xc6, 0xe9, 0x02, 0xff, 0x3c, + 0x01, 0xcc, 0xa5, 0x95, 0xa3, 0x42, 0x4d, 0x59, 0x00, 0x33, 0x5d, 0x38, + 0xe7, 0x71, 0x79, 0xeb, 0xcc, 0x2b, 0xd3, 0x34, 0xb5, 0xd7, 0x61, 0xac, + 0x14, 0xb2, 0xec, 0x52, 0x1a, 0x0e, 0x97, 0x02, 0x49, 0xed, 0xfc, 0x06, + 0xbb, 0x7f, 0x6f, 0xfa, 0x23, 0xad, 0x6f, 0x96, 0x2e, 0xee, 0x03, 0x36, + 0x34, 0x08, 0x4f, 0x26, 0x4f, 0xcd, 0x3e, 0x28, 0x54, 0x97, 0xbd, 0xfb, + 0x31, 0x46, 0x1a, 0x6b, 0x9b, 0xcf, 0x2d, 0xca, 0x37, 0xab, 0x8f, 0xd6, + 0x30, 0xc5, 0x95, 0x6d, 0xfe, 0x6f, 0xc8, 0x1b, 0x70, 0x90, 0x25, 0xb1, + 0x92, 0x02, 0xb0, 0x9d, 0x81, 0x0e, 0x26, 0x51, 0x97, 0x60, 0xbe, 0x25, + 0x62, 0xae, 0x5c, 0xd6, 0xbd, 0xfc, 0xca, 0xad, 0x6a, 0x6a, 0xdb, 0x4b, + 0x19, 0x8a, 0x04, 0xce, 0x73, 0x73, 0x39, 0x22, 0x6b, 0x2f, 0x5f, 0x22, + 0x78, 0xd6, 0xd1, 0xcb, 0xa3, 0xf0, 0x48, 0x78, 0x80, 0xb9, 0x69, 0xe4, + 0x57, 0xdc, 0x0e, 0x47, 0x6a, 0x28, 0x94, 0x88, 0xca, 0xac, 0x83, 0x27, + 0xbb, 0x11, 0x74, 0x74, 0xc8, 0xce, 0x11, 0x01, 0xc0, 0x0e, 0x92, 0xaf, + 0x58, 0xf9, 0xd3, 0xae, 0xa5, 0xed, 0x81, 0x84, 0x69, 0xd5, 0xcb, 0xe3, + 0x65, 0xc9, 0x84, 0xbb, 0x5d, 0x89, 0xe3, 0x8f, 0x98, 0x04, 0xf7, 0x06, + 0x93, 0x9f, 0xd8, 0xb3, 0x61, 0xfe, 0xfa, 0xd2, 0x86, 0x39, 0x53, 0xed, + 0x58, 0x0b, 0x61, 0x88, 0x46, 0x8f, 0x8f, 0x1f, 0xdf, 0x1a, 0x7a, 0x77, + 0x06, 0x72, 0xc5, 0x6a, 0x88, 0x60, 0x2f, 0x4a, 0x60, 0xe4, 0xbe, 0xa0, + 0x59, 0x69, 0xb0, 0xc6, 0x49, 0x7a, 0x95, 0x03, 0x0e, 0xa9, 0x60, 0x22, + 0xa3, 0xd4, 0xc6, 0x54, 0x63, 0xdc, 0x1c, 0x5a, 0x8a, 0x25, 0x19, 0x4f, + 0xc4, 0x8d, 0xae, 0xba, 0x9b, 0x3e, 0xe1, 0xd2, 0x27, 0x1c, 0x68, 0x87, + 0x18, 0x06, 0x5f, 0x64, 0x25, 0xba, 0x67, 0x0e, 0xda, 0x9a, 0xb9, 0x97, + 0x9e, 0x52, 0x32, 0x44, 0x25, 0x9a, 0xa7, 0xa3, 0xae, 0xce, 0x19, 0x6d, + 0x33, 0x04, 0x63, 0x93, 0x14, 0x43, 0x8c, 0xaf, 0xa8, 0x4f, 0xa8, 0xe3, + 0x53, 0x6f, 0x77, 0x4b, 0xc6, 0xd9, 0x6c, 0x02, 0x8f, 0xd8, 0x17, 0x9d, + 0x52, 0x10, 0x2b, 0x4f, 0x92, 0x91, 0xd1, 0xa2, 0x94, 0x8f, 0xd5, 0xb9, + 0xd2, 0xf5, 0xd9, 0xec, 0x47, 0x4f, 0x27, 0x87, 0x21, 0x6d, 0x2c, 0x81, + 0x87, 0x07, 0xb5, 0x29, 0x26, 0x46, 0x7c, 0x47, 0x38, 0x97, 0x98, 0x13, + 0xa2, 0xaa, 0x47, 0x9d, 0x23, 0x3c, 0x9c, 0x2d, 0x80, 0x56, 0x10, 0xb9, + 0xbe, 0x78, 0xe8, 0x61, 0x17, 0x92, 0x8b, 0x88, 0x70, 0xf4, 0x31, 0xf0, + 0x0c, 0x07, 0xe7, 0xbd, 0x1c, 0x34, 0xe5, 0x8e, 0x8c, 0xe8, 0xd6, 0x4e, + 0x38, 0xef, 0x0b, 0x59, 0xf7, 0xc1, 0x5f, 0x0f, 0xa4, 0x21, 0x93, 0x90, + 0x27, 0x80, 0x21, 0x29, 0xe5, 0x7d, 0x12, 0xfd, 0x0e, 0x27, 0x0b, 0x42, + 0x8e, 0xcd, 0x12, 0x50, 0x96, 0x5b, 0x94, 0xa0, 0x3e, 0x29, 0xee, 0x1a, + 0x6f, 0xc5, 0x07, 0x9a, 0xef, 0xbc, 0x9e, 0x9e, 0x8b, 0x6f, 0x99, 0x96, + 0x78, 0x3b, 0x2c, 0xd2, 0xc5, 0x05, 0x91, 0x96, 0x5e, 0x39, 0x06, 0xb2, + 0x0f, 0x34, 0xa5, 0x98, 0x98, 0x67, 0xd9, 0x4e, 0x92, 0xb8, 0x46, 0xc0, + 0x7a, 0xf4, 0xf2, 0x90, 0x97, 0xcf, 0x33, 0x9e, 0x0b, 0xb7, 0xf3, 0xef, + 0xa5, 0xa5, 0xbf, 0x97, 0xf9, 0x04, 0x46, 0xea, 0x31, 0x21, 0x94, 0x61, + 0x19, 0x17, 0xd1, 0x9d, 0xe7, 0xfa, 0x3a, 0xaa, 0x52, 0x55, 0x46, 0x72, + 0x1b, 0x97, 0xd9, 0x6b, 0x5e, 0x3d, 0x15, 0x83, 0x55, 0x01, 0x95, 0x52, + 0x27, 0xd1, 0x0c, 0x41, 0x90, 0x67, 0x44, 0x7d, 0x4f, 0xd8, 0x7a, 0x3e, + 0x9f, 0xae, 0xc3, 0x00, 0x86, 0xc3, 0xc2, 0x06, 0xd8, 0x99, 0xb4, 0xfc, + 0x00, 0xbf, 0x8e, 0xa3, 0x0c, 0xf9, 0x14, 0x48, 0x2a, 0xb0, 0x5e, 0xf8, + 0xfe, 0x6b, 0x83, 0x13, 0xaa, 0x94, 0xd0, 0x62, 0x9b, 0xbb, 0xa7, 0x33, + 0x26, 0x18, 0xca, 0x60, 0x48, 0x0c, 0x5c, 0xe3, 0x13, 0x94, 0x24, 0xfe, + 0x00, 0xf3, 0x1f, 0xa2, 0x2f, 0xae, 0x49, 0x92, 0xe7, 0xf6, 0x49, 0x1e, + 0xf7, 0x57, 0x4c, 0xe5, 0x4c, 0x5f, 0x8c, 0xa3, 0xdc, 0x70, 0xbe, 0x5b, + 0x8c, 0x3c, 0xdb, 0xd3, 0x84, 0x02, 0x6e, 0xdc, 0xd5, 0x6a, 0xc9, 0xc2, + 0x5f, 0x95, 0x3a, 0x2d, 0x44, 0x87, 0x09, 0x52, 0x90, 0x41, 0x1f, 0xa8, + 0x93, 0x76, 0xae, 0x53, 0xd3, 0xef, 0x26, 0x15, 0x27, 0x38, 0x04, 0xc7, + 0xda, 0xed, 0xb1, 0x11, 0xe8, 0x2a, 0x67, 0x03, 0xd0, 0xfe, 0x5f, 0x85, + 0xfc, 0xa0, 0x6a, 0x73, 0x6e, 0xac, 0x15, 0x8d, 0xa2, 0xca, 0x5b, 0x32, + 0x52, 0xc1, 0x2e, 0xf4, 0xe6, 0x68, 0x99, 0xbd, 0xeb, 0x05, 0x4e, 0x8f, + 0xb7, 0x5c, 0xd1, 0x31, 0x5b, 0x17, 0x98, 0x81, 0xef, 0x69, 0x3d, 0x23, + 0x01, 0xc3, 0x34, 0xc7, 0x69, 0x39, 0x5e, 0xb3, 0x1e, 0x99, 0xa6, 0xbf, + 0x78, 0xee, 0x88, 0xe2, 0xdb, 0xd7, 0x4e, 0x17, 0xa0, 0x27, 0x0f, 0xe6, + 0x9f, 0x9f, 0x74, 0x0c, 0xa4, 0xd2, 0x47, 0xe3, 0xc1, 0xb5, 0xc9, 0x13, + 0xaa, 0x72, 0x22, 0xbb, 0x7d, 0xd6, 0xb8, 0x76, 0x6c, 0x5e, 0xd5, 0xf7, + 0x22, 0x69, 0x7c, 0x40, 0x4f, 0x64, 0xcd, 0x02, 0x43, 0x4a, 0x09, 0x1d, + 0x95, 0x90, 0x16, 0x3f, 0xaa, 0x4d, 0xdf, 0x5d, 0xea, 0x76, 0xb0, 0x52, + 0x92, 0xa1, 0xde, 0xd6, 0x2f, 0x66, 0x7d, 0x53, 0x65, 0xb4, 0xa6, 0x3e, + 0x0a, 0x85, 0x03, 0x56, 0x82, 0x6f, 0x17, 0xe6, 0xb6, 0xef, 0x0f, 0x4e, + 0x01, 0xc5, 0xba, 0x01, 0xdb, 0x23, 0x4c, 0x9f, 0x11, 0x59, 0x28, 0x71, + 0xc4, 0xf2, 0xeb, 0x00, 0xa9, 0x72, 0x7b, 0xd7, 0x02, 0x94, 0xd8, 0xaf, + 0xad, 0x16, 0x92, 0x51, 0xea, 0xe4, 0xb6, 0xf6, 0xe1, 0x80, 0xaf, 0x6b, + 0x0d, 0x2c, 0xbc, 0x6f, 0xb4, 0x0c, 0xa9, 0xd4, 0xf8, 0xb8, 0x19, 0xc5, + 0x69, 0x5d, 0x8f, 0xce, 0x4b, 0x98, 0x11, 0xae, 0x66, 0x19, 0x66, 0x6e, + 0xe5, 0x88, 0xc9, 0x23, 0xf5, 0xc6, 0x3d, 0x52, 0x4d, 0x5a, 0x6d, 0x5e, + 0xdc, 0x00, 0x21, 0x41, 0x53, 0xab, 0x97, 0x3d, 0xa3, 0xfb, 0xd9, 0xdf, + 0x90, 0x77, 0xeb, 0x4f, 0x8d, 0xec, 0xca, 0x17, 0xad, 0x65, 0xb9, 0x92, + 0x0c, 0x24, 0xd4, 0x80, 0x19, 0x78, 0x49, 0x7d, 0x9b, 0xcf, 0xdd, 0xaf, + 0xfd, 0xb8, 0xdd, 0x89, 0x4b, 0xe5, 0xb9, 0x99, 0x9b, 0x70, 0x24, 0xc5, + 0x86, 0x42, 0x92, 0x2c, 0x47, 0xd5, 0x1a, 0x50, 0x5d, 0x4d, 0xcf, 0xdc, + 0xb4, 0x19, 0x9a, 0xe2, 0x94, 0x5f, 0x1b, 0x19, 0x40, 0xd3, 0x5c, 0xe3, + 0x09, 0xe3, 0x7c, 0x15, 0x60, 0x49, 0xf7, 0xf9, 0xdb, 0x8e, 0x38, 0x69, + 0xfa, 0xa2, 0xe6, 0x18, 0x11, 0xc3, 0x57, 0xa0, 0xec, 0x1b, 0x43, 0x3a, + 0xb1, 0x5a, 0x6a, 0xcd, 0x5a, 0x2e, 0x59, 0x10, 0x8b, 0xc1, 0xfc, 0xbd, + 0x75, 0xc9, 0x5e, 0x5c, 0xe2, 0x28, 0xb8, 0x72, 0xbc, 0xb3, 0x8a, 0x5e, + 0x82, 0x32, 0x50, 0xa3, 0xe0, 0x77, 0xf6, 0xe0, 0x46, 0xbe, 0xda, 0x52, + 0xa5, 0x13, 0xa5, 0x99, 0xcd, 0xc3, 0x55, 0x31, 0x83, 0x10, 0x72, 0xa3, + 0x2d, 0x14, 0x49, 0xda, 0x57, 0x81, 0xd7, 0x7f, 0xbd, 0x29, 0x6d, 0xb8, + 0x21, 0xe4, 0x4b, 0x58, 0x99, 0x74, 0x84, 0xef, 0x77, 0xd6, 0x92, 0xe0, + 0x81, 0xe1, 0xc0, 0x3c, 0x10, 0x81, 0xf9, 0xa9, 0xaa, 0x63, 0x74, 0x98, + 0x91, 0xa8, 0x72, 0x16, 0xa6, 0xf3, 0xf9, 0x89, 0xe4, 0xe6, 0x48, 0xac, + 0x50, 0x65, 0x11, 0x4c, 0xef, 0xfe, 0xcf, 0x89, 0xd3, 0x9f, 0xc1, 0xfc, + 0xdc, 0xea, 0x75, 0x19, 0xc7, 0xd0, 0x12, 0xaf, 0x20, 0x64, 0x82, 0x08, + 0x8e, 0xc8, 0x0f, 0x15, 0x51, 0x7b, 0xe2, 0x6b, 0xb0, 0x1c, 0xcd, 0xad, + 0xd1, 0x77, 0x2d, 0xad, 0xa0, 0xec, 0x81, 0xa7, 0xa8, 0x28, 0xcd, 0xb1, + 0xcc, 0xa5, 0x43, 0xc4, 0x5b, 0xb8, 0x9c, 0x84, 0xa5, 0x2c, 0xac, 0xba, + 0xc0, 0x2a, 0x61, 0xc7, 0xf1, 0xb6, 0x57, 0x56, 0xe5, 0xca, 0x96, 0xbb, + 0xfb, 0x8e, 0x49, 0x3e, 0x50, 0x2f, 0x36, 0x73, 0x5b, 0x44, 0x5b, 0x36, + 0x9c, 0xa0, 0x90, 0xc6, 0x96, 0x4e, 0x73, 0x1f, 0x68, 0x47, 0x43, 0xd3, + 0x6b, 0x1f, 0x4d, 0x43, 0x1e, 0xbf, 0x1c, 0x28, 0xe9, 0xf5, 0x3d, 0xac, + 0x48, 0x4c, 0xd4, 0x6d, 0x32, 0x25, 0xf3, 0x71, 0x29, 0xe9, 0xf0, 0x08, + 0x2a, 0xd2, 0x75, 0xc1, 0xa6, 0x5f, 0x1f, 0xca, 0xbb, 0x76, 0x91, 0xdc, + 0xca, 0x13, 0x3b, 0x18, 0xd9, 0x66, 0x48, 0xb0, 0x29, 0x01, 0x39, 0xfd, + 0x35, 0x8b, 0xd7, 0xac, 0xeb, 0xe3, 0x92, 0x96, 0xef, 0xe1, 0x7e, 0xd7, + 0xd0, 0xe9, 0xd6, 0xcf, 0xd7, 0x28, 0x58, 0x0a, 0x20, 0xcc, 0xc1, 0x8a, + 0x45, 0x45, 0xe0, 0x71, 0xca, 0x66, 0x75, 0xb0, 0x97, 0x89, 0x13, 0x7b, + 0xa3, 0x27, 0x5d, 0xce, 0x36, 0x58, 0xf6, 0x0a, 0x66, 0xf5, 0x83, 0xc8, + 0xef, 0x6e, 0x6f, 0x98, 0x79, 0x52, 0xd7, 0xd4, 0xa3, 0x3f, 0xda, 0x70, + 0xe2, 0x41, 0x10, 0x55, 0x20, 0x71, 0xb0, 0xd8, 0xd9, 0x14, 0x19, 0xc6, + 0x76, 0x0d, 0x45, 0x78, 0xb5, 0x70, 0x88, 0x65, 0x5a, 0x6b, 0xeb, 0x2f, + 0x28, 0x38, 0xf9, 0xbc, 0x28, 0xbe, 0xca, 0x44, 0x86, 0x4e, 0xd4, 0x29, + 0xc6, 0x16, 0xca, 0x3e, 0xb7, 0x33, 0x58, 0x04, 0x33, 0x7c, 0xac, 0xb5, + 0x9f, 0xf9, 0xfd, 0x6d, 0xb9, 0xff, 0x5a, 0x35, 0xa6, 0xd8, 0xa5, 0x28, + 0x30, 0xf5, 0x16, 0x95, 0xa9, 0x14, 0x65, 0x97, 0x56, 0x01, 0x4d, 0xf8, + 0x71, 0xc9, 0x93, 0xad, 0xac, 0x97, 0x1d, 0xab, 0x70, 0x21, 0x2d, 0xf3, + 0x26, 0x16, 0x66, 0xcb, 0xa2, 0x67, 0x56, 0x09, 0xd9, 0x9d, 0x9c, 0xec, + 0x37, 0x4d, 0x71, 0xbd, 0xef, 0xaf, 0x22, 0x78, 0xd9, 0x4c, 0xdd, 0xab, + 0x9a, 0x12, 0x28, 0x7d, 0xb4, 0xd4, 0x9c, 0x01, 0xf2, 0x85, 0x2f, 0xbc, + 0x58, 0x77, 0x85, 0x32, 0xdf, 0x4e, 0x79, 0x41, 0x41, 0xda, 0x6e, 0x9f, + 0x60, 0x09, 0x82, 0xf4, 0x50, 0x15, 0x68, 0x0f, 0xfd, 0x0b, 0x5b, 0x09, + 0x33, 0x98, 0x9c, 0x92, 0x1d, 0xc1, 0x38, 0xbe, 0xdc, 0x17, 0xbe, 0x88, + 0xa8, 0xa6, 0x88, 0xa2, 0x0f, 0x81, 0xcd, 0xb6, 0xde, 0x42, 0xc7, 0x7d, + 0x53, 0xc6, 0xab, 0xd3, 0x94, 0x9d, 0x2e, 0x79, 0x2f, 0x0b, 0x76, 0x63, + 0x36, 0xa5, 0x85, 0x7f, 0x94, 0x07, 0x53, 0xe7, 0xa8, 0x6a, 0x0d, 0xb1, + 0xda, 0x1f, 0xad, 0xb6, 0x5b, 0x13, 0xe7, 0x21, 0xcc, 0xe7, 0x29, 0x09, + 0x48, 0x1a, 0x19, 0x7e, 0x22, 0x1b, 0x1b, 0xe5, 0xf2, 0x1a, 0x08, 0x25, + 0x30, 0xca, 0xf1, 0xd6, 0x97, 0x56, 0x3a, 0xa7, 0x3f, 0x0b, 0xce, 0xaf, + 0xfc, 0x50, 0x24, 0x34, 0xab, 0xf0, 0x9c, 0x91, 0x12, 0xc0, 0x4f, 0xd5, + 0xed, 0xa4, 0xf4, 0xe4, 0x36, 0x54, 0x49, 0xed, 0x36, 0x61, 0x6d, 0xa4, + 0x1e, 0x63, 0x24, 0x3c, 0x40, 0xb0, 0xb2, 0x44, 0xe3, 0x6d, 0xf2, 0xa6, + 0x96, 0x97, 0xe9, 0x97, 0xd4, 0x76, 0x80, 0x0c, 0x6d, 0xa8, 0xb1, 0x39, + 0x48, 0x48, 0x7c, 0x1b, 0x46, 0x9e, 0x94, 0x7a, 0xbf, 0xfd, 0xc6, 0xff, + 0x72, 0xf0, 0x4d, 0x4b, 0x22, 0x46, 0x32, 0x8e, 0x51, 0x23, 0xe7, 0xb2, + 0xe7, 0xa7, 0x05, 0x38, 0xb9, 0x25, 0xcc, 0xe2, 0xbf, 0x08, 0xff, 0x77, + 0xf9, 0xb6, 0x37, 0xcd, 0x29, 0x47, 0xc3, 0x10, 0xe4, 0xc9, 0xd5, 0xaa, + 0x41, 0xe8, 0x6c, 0x6d, 0x17, 0xa2, 0x8a, 0x08, 0xcc, 0xde, 0xa3, 0xcb, + 0xeb, 0x66, 0x86, 0x2c, 0x0b, 0xd3, 0xeb, 0xb3, 0x4b, 0x9e, 0x64, 0x70, + 0xf3, 0xa2, 0x8e, 0x30, 0x14, 0x32, 0x09, 0xea, 0xbd, 0x57, 0x4b, 0x6b, + 0x1e, 0xa3, 0x12, 0x01, 0xc2, 0x46, 0x65, 0x23, 0xe9, 0xac, 0x21, 0xb2, + 0xba, 0x60, 0xef, 0x6e, 0xa8, 0x32, 0x16, 0x1b, 0x69, 0x41, 0x23, 0x93, + 0xfb, 0x48, 0x7a, 0xb3, 0xe2, 0xab, 0x9b, 0x1a, 0x44, 0xce, 0x8a, 0x35, + 0xfc, 0x87, 0x3e, 0xe4, 0xa5, 0xec, 0xcf, 0x98, 0x04, 0x32, 0xc2, 0x32, + 0x4b, 0x48, 0x96, 0xed, 0x6a, 0xd1, 0xca, 0x3a, 0xf0, 0xb9, 0x32, 0x14, + 0xe3, 0x11, 0x23, 0x87, 0x09, 0x49, 0x59, 0x20, 0x6b, 0x3a, 0xb7, 0xc5, + 0xa7, 0xb3, 0x86, 0xd1, 0x87, 0x0d, 0xcf, 0x04, 0x92, 0x2a, 0x87, 0xa4, + 0x36, 0xc9, 0x03, 0x3f, 0x05, 0x2f, 0x39, 0xad, 0xfb, 0xbb, 0x25, 0x0c, + 0xbe, 0x23, 0xe4, 0x18, 0x1c, 0x24, 0x71, 0xd1, 0x6c, 0xba, 0x6a, 0xba, + 0xa6, 0xa7, 0x93, 0x08, 0x43, 0x92, 0x13, 0xfa, 0x02, 0xe0, 0x0e, 0xf6, + 0x26, 0x20, 0x11, 0x5c, 0x4f, 0x54, 0xc0, 0xb2, 0x0b, 0x5e, 0x79, 0x41, + 0xd9, 0x03, 0xd8, 0x4f, 0xb4, 0x60, 0xf7, 0x2c, 0xbd, 0xd8, 0xcd, 0xdd, + 0x19, 0xee, 0x46, 0x5f, 0x44, 0x2b, 0x57, 0x3f, 0xe3, 0x6b, 0x41, 0x4b, + 0x63, 0x19, 0x2b, 0x69, 0xb3, 0xe4, 0x14, 0xe0, 0xfc, 0x70, 0x6f, 0xc5, + 0x9e, 0xe2, 0x56, 0xfe, 0x62, 0xc7, 0x2b, 0x68, 0x43, 0x34, 0xb0, 0xf8, + 0x71, 0xd9, 0x0e, 0xbd, 0x20, 0x29, 0x83, 0xf1, 0xfe, 0xed, 0xec, 0xd5, + 0xeb, 0x12, 0xc9, 0x13, 0x9d, 0x1f, 0xb4, 0xce, 0x39, 0xd8, 0x15, 0xa9, + 0x6c, 0x24, 0x8d, 0x6f, 0xc5, 0x0a, 0x0c, 0xa2, 0x7e, 0x29, 0x67, 0xf1, + 0x3a, 0xf8, 0xd6, 0xd0, 0x3b, 0x28, 0x30, 0x94, 0x0c, 0x28, 0x77, 0x06, + 0x79, 0x3f, 0xfc, 0x67, 0xf2, 0x76, 0x8b, 0xb5, 0xc0, 0x4a, 0x1a, 0x79, + 0x9c, 0x04, 0xef, 0xc1, 0x61, 0x0e, 0xe9, 0xe0, 0xf3, 0x4a, 0x03, 0x00, + 0xf1, 0x4a, 0xa6, 0x66, 0x51, 0x53, 0x76, 0x35, 0x72, 0xc7, 0x59, 0x4b, + 0x34, 0x34, 0xc9, 0x1d, 0x91, 0x21, 0x1a, 0x5f, 0xb6, 0x81, 0x9e, 0x7a, + 0x62, 0x4a, 0xb8, 0x54, 0xb7, 0xdf, 0xe7, 0xd7, 0xb0, 0x5f, 0xa8, 0x1c, + 0x93, 0xae, 0x94, 0x3d, 0x82, 0x83, 0xe7, 0x9c, 0x50, 0x79, 0xa5, 0x03, + 0xf2, 0x3f, 0x19, 0xd7, 0x3f, 0x5f, 0x33, 0xf1, 0x5b, 0x65, 0x03, 0x4d, + 0x40, 0x88, 0x66, 0x67, 0x3f, 0x16, 0x8e, 0x7c, 0x4f, 0xd6, 0x15, 0xb3, + 0x1d, 0xed, 0x86, 0xc7, 0x2b, 0x82, 0x4e, 0x4e, 0xc1, 0x9b, 0x25, 0xc1, + 0xf5, 0x3f, 0x6e, 0xde, 0xbd, 0x23, 0x44, 0xa1, 0xb4, 0x84, 0xfb, 0x0a, + 0x95, 0x59, 0x57, 0x60, 0x73, 0x54, 0xcf, 0x4d, 0x2d, 0x5d, 0x8d, 0xc3, + 0xc8, 0x2a, 0x98, 0x7d, 0xb2, 0x59, 0x94, 0xe6, 0x90, 0x43, 0xed, 0xa2, + 0xc2, 0x13, 0x33, 0xf5, 0xee, 0x21, 0x72, 0x82, 0xaa, 0x33, 0xfc, 0x92, + 0x15, 0xc1, 0xf6, 0xef, 0x7d, 0xdf, 0x25, 0x8a, 0xbe, 0x36, 0xe8, 0x69, + 0x91, 0x42, 0x93, 0x4f, 0x1d, 0xc4, 0x92, 0xa5, 0xf3, 0xc1, 0x5d, 0x3d, + 0x1b, 0x36, 0xd7, 0xc4, 0x35, 0x7d, 0xe5, 0x02, 0x5b, 0xca, 0x8f, 0xcc, + 0x0c, 0x86, 0x7b, 0x20, 0xbc, 0xc2, 0xc1, 0x6f, 0x5a, 0x7c, 0xfe, 0x66, + 0x6d, 0xeb, 0x5e, 0xa5, 0xba, 0xbe, 0x26, 0xd3, 0xda, 0xe8, 0x51, 0x26, + 0x57, 0xac, 0xcf, 0x3f, 0x86, 0x1d, 0x38, 0x71, 0xa4, 0x35, 0x70, 0xe9, + 0x50, 0x02, 0x72, 0xc2, 0x22, 0x79, 0x78, 0xeb, 0x7d, 0xcf, 0xc7, 0x87, + 0xbc, 0x7e, 0xc7, 0x1c, 0x8d, 0x13, 0x44, 0xf3, 0xd0, 0x8a, 0x25, 0xf6, + 0xf7, 0x3c, 0xd9, 0x6f, 0xf2, 0x37, 0x9e, 0xad, 0x33, 0x43, 0x86, 0x40, + 0x4e, 0x90, 0x92, 0x33, 0x8c, 0x49, 0x90, 0x26, 0xf5, 0x25, 0x7d, 0xfe, + 0xf7, 0x16, 0x7e, 0x57, 0xef, 0xde, 0x6f, 0x2f, 0x93, 0xbe, 0x57, 0xda, + 0xae, 0x04, 0x35, 0x40, 0xcc, 0x4d, 0x72, 0x03, 0x2b, 0xb8, 0x1a, 0xfb, + 0xda, 0x1b, 0xb6, 0xff, 0x86, 0x6b, 0x76, 0xa6, 0xee, 0x71, 0xdd, 0xe8, + 0x10, 0xd8, 0x00, 0x94, 0x00, 0xa4, 0x6b, 0x00, 0x46, 0xd3, 0x8d, 0x16, + 0x64, 0x4c, 0x21, 0xd5, 0xc0, 0xca, 0x64, 0x44, 0xd2, 0xe6, 0xee, 0x4f, + 0xc4, 0xfa, 0x35, 0x45, 0x64, 0xc5, 0x51, 0xa8, 0x7c, 0x14, 0x77, 0xeb, + 0x97, 0x87, 0x0b, 0xae, 0x1d, 0x9c, 0x6e, 0x0d, 0xba, 0xb8, 0xa8, 0x8c, + 0xc8, 0x97, 0xd7, 0xb5, 0x43, 0xf3, 0x6b, 0x2d, 0x86, 0xdd, 0x01, 0xf6, + 0x07, 0xde, 0x7d, 0x7f, 0xb7, 0x3c, 0xe2, 0x30, 0x6b, 0x98, 0x99, 0xce, + 0xa6, 0xcb, 0x18, 0xa4, 0xa7, 0x3b, 0xc9, 0x62, 0xb9, 0x61, 0x3c, 0x87, + 0xe0, 0x7f, 0x85, 0x0f, 0xda, 0x1f, 0x83, 0x76, 0x6e, 0x9c, 0x53, 0x95, + 0x0c, 0x75, 0xe3, 0xc2, 0x90, 0x91, 0x96, 0x54, 0x87, 0x70, 0xcf, 0xb6, + 0x84, 0xe2, 0xbe, 0x31, 0xe5, 0x4a, 0x79, 0x00, 0x4a, 0x25, 0x06, 0x54, + 0x19, 0x39, 0x4d, 0x14, 0x28, 0xfd, 0x71, 0x91, 0xa2, 0x69, 0xee, 0x2b, + 0xa2, 0x88, 0x97, 0x37, 0x4f, 0x3e, 0xfa, 0xb7, 0x2a, 0x41, 0x55, 0x10, + 0xdf, 0xc4, 0x24, 0xfc, 0xde, 0xa9, 0x45, 0x74, 0xb5, 0xb9, 0xee, 0xef, + 0xd7, 0xb3, 0x8d, 0xc3, 0x41, 0x0c, 0xe8, 0x23, 0x5e, 0x41, 0x29, 0x83, + 0x23, 0x90, 0xc9, 0xf1, 0x54, 0x0e, 0xb8, 0xbf, 0x95, 0x5a, 0x28, 0x2c, + 0x5d, 0xd2, 0xd6, 0x50, 0x60, 0x5b, 0x1d, 0xbe, 0x64, 0x4d, 0x10, 0x28, + 0x92, 0x87, 0x88, 0x7d, 0x3f, 0x8d, 0xaf, 0xfc, 0x0f, 0x0c, 0x00, 0xa3, + 0x29, 0xd2, 0x10, 0x8b, 0xd9, 0x14, 0xb8, 0x3b, 0x81, 0x76, 0x64, 0xc2, + 0x97, 0xbe, 0x6f, 0x92, 0x61, 0x8b, 0xb7, 0x05, 0xbd, 0x3e, 0x6d, 0x54, + 0x50, 0x0c, 0x87, 0x95, 0x97, 0xf4, 0x49, 0x2d, 0x06, 0xac, 0xb8, 0xa9, + 0x31, 0xd3, 0x76, 0x92, 0x4a, 0xa3, 0xd9, 0x1f, 0xf4, 0x08, 0xd9, 0x29, + 0x49, 0xa9, 0xe3, 0x65, 0xee, 0x68, 0x60, 0x12, 0x97, 0xcc, 0xfc, 0xe1, + 0x5d, 0x26, 0xcc, 0xbe, 0xa8, 0x4e, 0xdd, 0x9a, 0x28, 0x21, 0xc3, 0x41, + 0x2f, 0x8a, 0x4e, 0x60, 0xb7, 0x03, 0x8c, 0x1f, 0x6f, 0x05, 0x5e, 0x99, + 0x73, 0x33, 0x43, 0xd2, 0xe7, 0x22, 0x75, 0xbc, 0x98, 0xe0, 0x34, 0x7e, + 0x2c, 0xb0, 0x0f, 0xa9, 0xee, 0xbc, 0x82, 0xa8, 0x1d, 0xa0, 0xd0, 0x95, + 0x5e, 0xa1, 0x33, 0x95, 0xf4, 0xdb, 0xe0, 0xf5, 0x3c, 0x1c, 0xa4, 0x5e, + 0x12, 0x08, 0x40, 0x7c, 0xc6, 0x12, 0x22, 0xb3, 0x6d, 0x81, 0xa2, 0x88, + 0xac, 0x97, 0x6f, 0x2a, 0xc9, 0xd6, 0xde, 0x6b, 0xb6, 0x02, 0x58, 0x18, + 0x40, 0xc7, 0x92, 0x06, 0x63, 0x26, 0x11, 0x98, 0xf1, 0x05, 0x50, 0x73, + 0x37, 0x4c, 0xcf, 0x8e, 0x77, 0xe6, 0x0f, 0x6e, 0x4f, 0x36, 0x5e, 0x7a, + 0x94, 0xd1, 0x13, 0xa5, 0xb1, 0x22, 0x0c, 0x20, 0xa1, 0x97, 0x8c, 0x7e, + 0xcb, 0xf9, 0xfa, 0x17, 0x4a, 0x4a, 0x40, 0x5e, 0xef, 0xe6, 0x48, 0x6c, + 0x3b, 0x18, 0xca, 0x2c, 0x67, 0x91, 0x09, 0x85, 0x6a, 0xcd, 0xdd, 0xdb, + 0xdb, 0x82, 0x07, 0xa7, 0x57, 0xa2, 0x42, 0x84, 0xf8, 0xe7, 0xd2, 0xbe, + 0x8b, 0x80, 0xe4, 0xda, 0x07, 0x4e, 0xcc, 0x11, 0xc9, 0xf6, 0x5f, 0x5e, + 0x22, 0xcd, 0xf3, 0x82, 0xa9, 0x6d, 0x7a, 0xc4, 0x26, 0x70, 0xec, 0x1d, + 0x6a, 0x79, 0x7f, 0x37, 0x28, 0x88, 0x1a, 0x53, 0x84, 0xf8, 0x00, 0xad, + 0x47, 0x7b, 0xfe, 0x19, 0xc9, 0xac, 0xab, 0x55, 0x76, 0xde, 0x4b, 0x6d, + 0x6f, 0x2e, 0x77, 0xca, 0xd7, 0x4e, 0x73, 0x18, 0xcd, 0xc3, 0x41, 0xac, + 0x39, 0x9a, 0x22, 0xac, 0xbf, 0xd2, 0xc0, 0xec, 0x4c, 0x54, 0xfb, 0xb9, + 0x76, 0x39, 0xd4, 0xcf, 0x63, 0xd6, 0xd6, 0x3c, 0xfe, 0x6f, 0xc0, 0x22, + 0xc0, 0x14, 0x36, 0xb8, 0x02, 0x19, 0x1e, 0x6a, 0x8b, 0xa3, 0x39, 0x78, + 0x1a, 0x82, 0x9e, 0x78, 0xf6, 0x58, 0xdb, 0x2e, 0x0a, 0x70, 0xc3, 0xa7, + 0x45, 0x41, 0x19, 0x8d, 0xca, 0x91, 0xed, 0x28, 0x12, 0x8c, 0xbb, 0x91, + 0xbd, 0xb3, 0xf0, 0x6a, 0xff, 0x79, 0x7f, 0xdf, 0xbc, 0x03, 0x6c, 0x4f, + 0x05, 0xe1, 0xaf, 0x39, 0x14, 0x37, 0x08, 0xbd, 0xd8, 0xa5, 0x3a, 0x0d, + 0xe2, 0x65, 0xdd, 0x9f, 0x80, 0x0c, 0xca, 0xd2, 0x19, 0x36, 0x1d, 0x84, + 0xfa, 0xa0, 0xa7, 0xb3, 0x26, 0x14, 0x4e, 0x53, 0xb5, 0x98, 0x15, 0x7b, + 0x53, 0x55, 0xc7, 0x55, 0x59, 0x65, 0xf7, 0xf9, 0xb5, 0x6b, 0x96, 0x59, + 0x7d, 0xb6, 0xf2, 0xab, 0x6f, 0x4e, 0x48, 0xa1, 0x30, 0x18, 0x01, 0x2a, + 0x3e, 0x20, 0x3a, 0xc6, 0x6d, 0x2a, 0x23, 0x0d, 0x17, 0x3d, 0x66, 0x30, + 0xe5, 0xe5, 0xac, 0x86, 0x84, 0x08, 0x01, 0x7a, 0xcc, 0xed, 0xf9, 0xfa, + 0x83, 0xcf, 0x09, 0x95, 0xdf, 0xf8, 0xed, 0x8c, 0x12, 0x7d, 0xf0, 0xcc, + 0x3e, 0x35, 0xfe, 0x10, 0x50, 0xed, 0x35, 0xcc, 0x8a, 0x13, 0x18, 0x67, + 0x22, 0x79, 0x04, 0xd8, 0x43, 0xd2, 0x38, 0xb3, 0xe8, 0x4c, 0x57, 0x6b, + 0xab, 0xfa, 0x95, 0x4e, 0x2c, 0x5e, 0x14, 0x0e, 0x7e, 0x06, 0xd6, 0x7d, + 0xcd, 0xe9, 0xb7, 0xbb, 0x8b, 0x76, 0x35, 0xe5, 0xf1, 0x87, 0x6c, 0x92, + 0x2c, 0x44, 0x8e, 0x59, 0xa3, 0x84, 0x27, 0x55, 0xaa, 0xe7, 0x8a, 0xda, + 0x3a, 0x08, 0xa3, 0x3c, 0x94, 0x69, 0x07, 0x98, 0xf9, 0x33, 0x0a, 0xe8, + 0xfe, 0xfd, 0x7e, 0x55, 0x0c, 0x5b, 0x81, 0xba, 0x56, 0xb4, 0x86, 0xd9, + 0xca, 0x80, 0xc8, 0x12, 0xe8, 0x83, 0x8d, 0x51, 0x04, 0xb9, 0xcf, 0xe8, + 0x0f, 0x34, 0x97, 0xe7, 0x3b, 0xab, 0xaf, 0x85, 0x7f, 0x6f, 0x38, 0x1e, + 0x7b, 0xd8, 0x54, 0x31, 0xa7, 0x82, 0x4f, 0x2c, 0xa0, 0xff, 0x18, 0x73, + 0x8f, 0xbc, 0x57, 0xfe, 0x8f, 0x7f, 0xe5, 0x34, 0xfa, 0x16, 0x59, 0xa5, + 0x36, 0x3c, 0x01, 0x22, 0x89, 0x33, 0x99, 0x73, 0x93, 0xf1, 0x6b, 0x99, + 0xe3, 0xaa, 0xab, 0xf0, 0x37, 0x21, 0x09, 0xb2, 0x5d, 0x5a, 0x61, 0x89, + 0xb9, 0x62, 0xaf, 0x90, 0x3f, 0x8a, 0x42, 0x9d, 0x6b, 0x41, 0x86, 0x00, + 0x51, 0x78, 0x28, 0x41, 0x37, 0x35, 0x84, 0x73, 0xc6, 0x1e, 0x42, 0x52, + 0x91, 0x4a, 0x93, 0xce, 0x78, 0x0a, 0x08, 0x51, 0xec, 0x92, 0x15, 0x48, + 0x58, 0xe4, 0x94, 0x48, 0xbb, 0x8b, 0xd7, 0xf6, 0x5b, 0xac, 0x69, 0x5f, + 0x9a, 0x9d, 0x6c, 0xd9, 0x8e, 0xef, 0xb0, 0x71, 0xf8, 0x1a, 0xc4, 0xa8, + 0x90, 0x93, 0xec, 0x1a, 0x66, 0xbd, 0x29, 0x0f, 0xa9, 0xce, 0xf1, 0x65, + 0xb2, 0xc7, 0xb4, 0x4a, 0x92, 0x3d, 0x94, 0xcb, 0xae, 0x15, 0xc8, 0x99, + 0x44, 0x6d, 0x82, 0x00, 0x89, 0x20, 0x96, 0x97, 0x38, 0xd0, 0x5b, 0x8e, + 0xfa, 0x6d, 0x6a, 0x40, 0xa0, 0x72, 0xb2, 0x92, 0x27, 0xb5, 0xbc, 0x34, + 0x50, 0xfa, 0x5f, 0x1a, 0xfa, 0xe5, 0xdd, 0x75, 0x76, 0xb7, 0x7c, 0x19, + 0xbb, 0xe2, 0x89, 0x31, 0xab, 0xc9, 0x59, 0x72, 0x19, 0x7f, 0x3e, 0x60, + 0x9c, 0x8d, 0x4d, 0xdf, 0x90, 0xea, 0xcb, 0x65, 0xca, 0x03, 0x96, 0x59, + 0x22, 0x32, 0x8c, 0xfc, 0x0c, 0x97, 0x1f, 0x39, 0x75, 0xff, 0xd1, 0x79, + 0x9b, 0xce, 0x89, 0xd2, 0xe5, 0x8d, 0x04, 0xf0, 0xe2, 0x59, 0x48, 0xd0, + 0xf9, 0xc3, 0xbe, 0xee, 0x58, 0x06, 0xb7, 0xe6, 0xd1, 0x80, 0x6b, 0x13, + 0xb4, 0x41, 0x11, 0x06, 0x51, 0x8c, 0x66, 0xf9, 0x7e, 0x34, 0x07, 0xc1, + 0x4f, 0xfe, 0x9b, 0x31, 0xdf, 0x1e, 0x62, 0x44, 0xe7, 0x26, 0xc6, 0xa2, + 0x28, 0x25, 0x22, 0x28, 0xf8, 0x8d, 0xad, 0x27, 0x0b, 0xc7, 0x78, 0x01, + 0x82, 0x8c, 0x15, 0xe7, 0x96, 0x55, 0x1c, 0x63, 0xf1, 0xcc, 0x5d, 0xba, + 0x89, 0xbf, 0x1a, 0xd9, 0x98, 0xaf, 0xa1, 0x87, 0x6c, 0x8c, 0x86, 0xf4, + 0x4f, 0xc7, 0xf3, 0x13, 0x7c, 0x94, 0x5d, 0x95, 0x46, 0xbf, 0xad, 0x0d, + 0x9d, 0x3c, 0xe8, 0x12, 0x88, 0x99, 0x92, 0x5a, 0x15, 0x62, 0x50, 0xdb, + 0x67, 0x7a, 0xf3, 0x53, 0x6d, 0x5a, 0xd2, 0x12, 0x2f, 0x2e, 0xd0, 0x50, + 0x22, 0x8c, 0x3f, 0x3b, 0x45, 0x54, 0x5c, 0x54, 0x35, 0xe7, 0xb3, 0x78, + 0xf5, 0x10, 0x53, 0x38, 0xd8, 0xa1, 0x5f, 0x28, 0xe4, 0xc1, 0xf0, 0x66, + 0x54, 0x56, 0xdb, 0xed, 0xff, 0xd3, 0x60, 0x08, 0x41, 0xb5, 0xa0, 0x41, + 0x8c, 0x51, 0x96, 0x60, 0x0e, 0x3a, 0x5a, 0xf0, 0x13, 0xbc, 0x49, 0xd5, + 0xf9, 0xd7, 0xcf, 0xcc, 0x04, 0x20, 0x97, 0x64, 0x1a, 0xe6, 0x36, 0x03, + 0xa1, 0x4b, 0xaf, 0x34, 0x1d, 0x06, 0x31, 0x80, 0x8c, 0x0a, 0x5c, 0xf0, + 0x93, 0x03, 0xde, 0xb3, 0xd9, 0xca, 0xda, 0x9e, 0xd8, 0x99, 0xce, 0x9b, + 0xef, 0x72, 0x29, 0x72, 0x79, 0xfc, 0x5f, 0x01, 0xd7, 0x36, 0x93, 0x03, + 0xda, 0xcf, 0xd3, 0x2f, 0xa0, 0xad, 0xb4, 0x3f, 0xc7, 0x30, 0x92, 0xf0, + 0x3b, 0x49, 0x5d, 0xa2, 0x5c, 0xd2, 0x39, 0x45, 0x2f, 0xe8, 0xad, 0xfc, + 0xa6, 0x3f, 0xed, 0x61, 0x3d, 0x0a, 0x24, 0x1c, 0x02, 0x78, 0x41, 0xda, + 0xff, 0x02, 0xaa, 0xcf, 0xb1, 0xf3, 0xa3, 0xae, 0x72, 0xff, 0xe2, 0x83, + 0xfa, 0x92, 0xf6, 0xe3, 0x45, 0x8a, 0xcb, 0x10, 0x74, 0x19, 0xdc, 0x97, + 0x8d, 0x02, 0x75, 0x17, 0x0b, 0x05, 0x2f, 0x59, 0x62, 0x48, 0x61, 0xca, + 0x18, 0x07, 0x65, 0x11, 0x8e, 0x63, 0xde, 0xd2, 0xaf, 0xb6, 0x66, 0xaf, + 0xd1, 0x1f, 0xaf, 0x63, 0xe4, 0xc3, 0x50, 0xf1, 0xd0, 0x04, 0xc6, 0x3b, + 0x66, 0xc9, 0xd6, 0x25, 0xe2, 0xe7, 0xfa, 0xdf, 0xca, 0x26, 0xde, 0x2f, + 0xdc, 0xf9, 0x33, 0x13, 0x72, 0xa8, 0x9e, 0x6c, 0x18, 0x09, 0xc1, 0x39, + 0x1a, 0x6e, 0x81, 0x80, 0x4f, 0x2c, 0xde, 0xb3, 0xae, 0xf2, 0xf6, 0xbe, + 0xa5, 0xed, 0x7d, 0x66, 0xac, 0xd0, 0x63, 0xba, 0x74, 0x9a, 0x4e, 0xe7, + 0x18, 0x71, 0x4d, 0xf0, 0xfb, 0x72, 0x49, 0x13, 0x72, 0x6b, 0x00, 0xf3, + 0x6e, 0xc8, 0x76, 0x3a, 0xf2, 0xba, 0x5b, 0xf8, 0xd8, 0x70, 0x8a, 0x1a, + 0x16, 0x7e, 0x43, 0x41, 0xde, 0x02, 0x50, 0x23, 0x70, 0xa5, 0x90, 0x2b, + 0x22, 0x97, 0xc1, 0xf2, 0xb9, 0xe9, 0xa9, 0x43, 0xb0, 0x43, 0xf9, 0x37, + 0x8c, 0x6a, 0x86, 0x49, 0x13, 0xca, 0x03, 0xc1, 0x32, 0x68, 0x1d, 0xd3, + 0x2e, 0x9b, 0x6f, 0x51, 0xb8, 0x46, 0x19, 0x51, 0x34, 0x64, 0xd0, 0x62, + 0x23, 0xf1, 0x7c, 0x46, 0x60, 0xdf, 0xca, 0xd6, 0x6a, 0xf3, 0x9e, 0x20, + 0x00, 0xd1, 0x94, 0xa8, 0x04, 0xb0, 0xf0, 0x41, 0xf3, 0xd6, 0xad, 0xb3, + 0x8a, 0x30, 0xb3, 0x4a, 0x53, 0x11, 0x8d, 0x1b, 0xd0, 0x0f, 0xc5, 0x97, + 0xd0, 0x20, 0x4f, 0x4b, 0x36, 0xe2, 0x06, 0x14, 0xd9, 0xa0, 0x18, 0x78, + 0x05, 0x02, 0x23, 0x09, 0xcf, 0xe3, 0xfa, 0x0a, 0x66, 0x71, 0xf6, 0xe0, + 0xf1, 0xc0, 0xc5, 0xa0, 0xa7, 0xff, 0xb5, 0xca, 0x89, 0x2d, 0x3c, 0x67, + 0x3f, 0x37, 0x80, 0xce, 0x59, 0x5f, 0x3f, 0xa8, 0x4b, 0xa6, 0xcd, 0x0a, + 0x65, 0x1a, 0x25, 0x13, 0x18, 0x5e, 0xb2, 0x7b, 0x9f, 0x35, 0xc6, 0xc6, + 0x45, 0x7b, 0x3b, 0x32, 0x8c, 0x04, 0xcc, 0x85, 0xe8, 0x68, 0xd2, 0x62, + 0xed, 0xe7, 0x57, 0x18, 0xad, 0xda, 0xe1, 0xd9, 0x89, 0x09, 0x1f, 0x06, + 0x79, 0x5e, 0x82, 0xcd, 0x80, 0x61, 0xb1, 0x0b, 0x8a, 0x24, 0x09, 0xc1, + 0xe9, 0x4a, 0xac, 0x8d, 0xe7, 0x55, 0xcc, 0x55, 0x07, 0x7d, 0xdb, 0xbd, + 0x8b, 0x29, 0x4e, 0x78, 0xfb, 0x46, 0x64, 0x94, 0xaf, 0xa1, 0x19, 0x6f, + 0xcd, 0xbe, 0x72, 0x60, 0xe3, 0x55, 0xe1, 0xa5, 0x61, 0x83, 0xbb, 0xce, + 0x8c, 0x62, 0xe3, 0x2e, 0x84, 0x1f, 0x3c, 0xdc, 0x03, 0xf4, 0x41, 0xab, + 0x68, 0x63, 0xe3, 0x94, 0x8e, 0x1c, 0xe4, 0x80, 0xc6, 0xfb, 0x10, 0xb9, + 0xaf, 0xee, 0xcd, 0xfe, 0xfa, 0x9c, 0x18, 0xd8, 0xbc, 0xd6, 0xe0, 0xa8, + 0xe1, 0xfe, 0x78, 0x82, 0x0e, 0xd7, 0x0e, 0x80, 0xc9, 0x1f, 0x11, 0x5e, + 0x57, 0x35, 0x41, 0xdb, 0x6c, 0x39, 0xdb, 0xda, 0xfc, 0xb3, 0x12, 0x26, + 0x05, 0x9a, 0x01, 0xd4, 0x86, 0x4e, 0x60, 0x6a, 0x69, 0x72, 0xf1, 0x15, + 0x9f, 0x63, 0xaf, 0x9b, 0xe7, 0x1c, 0xbc, 0x33, 0xde, 0x3b, 0x6a, 0x74, + 0x8a, 0x9e, 0x74, 0x5c, 0xa0, 0x64, 0xc3, 0x01, 0xf1, 0x04, 0xef, 0xaf, + 0x45, 0x52, 0x5b, 0xed, 0xb2, 0xf8, 0x80, 0xb9, 0xc6, 0x04, 0x40, 0x1e, + 0x0b, 0xd0, 0x0f, 0xcf, 0x73, 0x2a, 0x65, 0xd2, 0xee, 0xcc, 0xdb, 0xe6, + 0xe8, 0x84, 0xff, 0xda, 0xb1, 0x25, 0x3a, 0x14, 0x94, 0x67, 0x0e, 0x03, + 0xdc, 0x93, 0xfe, 0x50, 0x19, 0x60, 0x61, 0xa5, 0xf3, 0xd2, 0x2d, 0x8e, + 0x6b, 0xa2, 0xc5, 0x63, 0xa9, 0x99, 0x8e, 0xe7, 0x21, 0x5e, 0x08, 0x4c, + 0xe5, 0x22, 0x66, 0x88, 0xc0, 0x7c, 0x0e, 0x5d, 0x97, 0xb2, 0x15, 0x30, + 0xd5, 0xee, 0xd4, 0x25, 0x22, 0x82, 0x28, 0x64, 0xc9, 0x96, 0x12, 0x46, + 0x53, 0xcb, 0xa1, 0xb7, 0x38, 0xe2, 0x8e, 0x52, 0x5a, 0x03, 0x1e, 0xf4, + 0x4a, 0xb2, 0x8e, 0x77, 0xfa, 0x6b, 0xe6, 0x8c, 0x12, 0xc3, 0x4d, 0x12, + 0x87, 0xc1, 0x78, 0x29, 0xfa, 0x86, 0xd9, 0xe0, 0xbc, 0x10, 0x87, 0xc6, + 0x42, 0x13, 0x8d, 0x19, 0x0f, 0x02, 0x4f, 0x56, 0xac, 0xb3, 0xce, 0x6a, + 0x84, 0xb9, 0x39, 0x59, 0x26, 0x23, 0xe0, 0xcf, 0x72, 0x2e, 0xb9, 0xa2, + 0xda, 0x32, 0x18, 0x77, 0x12, 0xc9, 0xc1, 0x95, 0x80, 0x93, 0x93, 0xac, + 0x2d, 0xdf, 0x4c, 0xc2, 0x53, 0x0d, 0xa3, 0x2c, 0xac, 0x3e, 0xfe, 0x72, + 0xdb, 0xf6, 0x20, 0x80, 0x21, 0xbd, 0x98, 0x71, 0x5d, 0x21, 0xf3, 0x45, + 0x64, 0x71, 0x0b, 0xb0, 0x33, 0x40, 0xa3, 0x33, 0x57, 0xe5, 0x96, 0x87, + 0xc4, 0xec, 0x80, 0x90, 0x1d, 0xfb, 0x31, 0x73, 0x5d, 0x7f, 0x70, 0xb3, + 0x61, 0xa4, 0x8b, 0x3c, 0xc8, 0x44, 0x4d, 0x09, 0xb2, 0x32, 0x74, 0x3e, + 0xa0, 0xaf, 0xd7, 0x66, 0xe8, 0xd0, 0xb1, 0xc3, 0xa8, 0x81, 0xbc, 0x70, + 0xe8, 0x6e, 0x68, 0x89, 0x14, 0xaf, 0x8f, 0x4b, 0x60, 0xae, 0x6a, 0xcd, + 0xa8, 0xbc, 0xd7, 0xbd, 0x35, 0x15, 0xbc, 0xcb, 0x9c, 0x84, 0x27, 0x86, + 0x69, 0xe5, 0x09, 0x21, 0xf6, 0xa4, 0xd9, 0xaf, 0x33, 0x48, 0x84, 0x93, + 0x91, 0x24, 0x96, 0xe5, 0x4c, 0x78, 0xee, 0xec, 0x79, 0x5b, 0x0a, 0x3c, + 0xa8, 0x62, 0xe9, 0xa9, 0x68, 0x21, 0x2c, 0x6a, 0x48, 0x4a, 0x17, 0x19, + 0x60, 0x65, 0xa5, 0x0c, 0x97, 0xd4, 0xc9, 0xde, 0x56, 0xe9, 0xf0, 0xf7, + 0x56, 0x57, 0x6c, 0x8e, 0x3e, 0xf6, 0x52, 0xe1, 0x86, 0x42, 0x80, 0x01, + 0x80, 0xa1, 0x28, 0x64, 0x32, 0x8f, 0x80, 0xf3, 0x7d, 0xa2, 0x97, 0x84, + 0x82, 0xe7, 0x91, 0x41, 0x92, 0x08, 0xe6, 0x02, 0x69, 0x37, 0xfe, 0xcd, + 0xa2, 0x85, 0xfa, 0xb7, 0x64, 0xab, 0x78, 0x95, 0xb4, 0x85, 0x44, 0x28, + 0xa5, 0xe5, 0xb8, 0xc0, 0x11, 0xac, 0x21, 0x5a, 0xd3, 0x98, 0x5e, 0x8a, + 0x08, 0x60, 0x14, 0x0d, 0x53, 0xde, 0xce, 0x06, 0xd4, 0x37, 0xb1, 0x22, + 0xe2, 0x68, 0x34, 0xc7, 0xc5, 0xa3, 0xf5, 0x1b, 0xce, 0xed, 0x45, 0x24, + 0xd9, 0x4a, 0x08, 0xdd, 0x65, 0x07, 0x8b, 0xbf, 0x81, 0xda, 0x3b, 0x31, + 0xdc, 0xb1, 0x7b, 0x3d, 0x8a, 0xb4, 0x74, 0x6e, 0xc8, 0xd4, 0x46, 0xd9, + 0xb6, 0x97, 0x45, 0x3b, 0xa0, 0x24, 0x88, 0xc3, 0xc4, 0x1d, 0x58, 0xa5, + 0xa7, 0xf0, 0x7c, 0xae, 0xd6, 0x77, 0x47, 0x7c, 0xe2, 0xb0, 0x18, 0xef, + 0x2c, 0x35, 0x82, 0x8c, 0x89, 0x93, 0x76, 0x40, 0x52, 0xbc, 0xf1, 0xf9, + 0x7f, 0x77, 0x03, 0x74, 0xdc, 0x12, 0xfd, 0x74, 0x2e, 0x16, 0xe6, 0x19, + 0xd5, 0xe0, 0x8b, 0x06, 0x4b, 0x99, 0x1f, 0x68, 0x3c, 0xd1, 0xbe, 0xe8, + 0x9c, 0xf7, 0xb5, 0x9d, 0x17, 0x1f, 0xaf, 0x47, 0xc5, 0x38, 0x92, 0x2c, + 0x1b, 0x54, 0x6f, 0x2b, 0x1d, 0x09, 0xeb, 0x4d, 0x89, 0x8e, 0x32, 0xe7, + 0x59, 0x84, 0x91, 0xfd, 0x57, 0xd9, 0x79, 0x4f, 0x8a, 0xdb, 0xc3, 0x3a, + 0x09, 0xe0, 0x07, 0x36, 0xdd, 0x93, 0x94, 0x1e, 0x69, 0x6b, 0xe1, 0x31, + 0xae, 0x72, 0xed, 0x66, 0x80, 0x06, 0x1b, 0x4a, 0x45, 0xdc, 0xbc, 0xdc, + 0x93, 0x44, 0xce, 0xf4, 0x01, 0xdc, 0x08, 0x73, 0x02, 0x32, 0xa3, 0xf0, + 0x61, 0x9a, 0x50, 0x04, 0x3b, 0x28, 0xb3, 0x9a, 0xbf, 0xe7, 0x5c, 0x5a, + 0x99, 0x4b, 0xf7, 0xff, 0x3b, 0x76, 0x7b, 0x7a, 0xcc, 0xcd, 0x49, 0xdf, + 0x49, 0x48, 0xcc, 0x99, 0x34, 0x14, 0x07, 0xda, 0x06, 0xfb, 0x9d, 0x97, + 0xc4, 0xd9, 0x2e, 0x25, 0x34, 0x63, 0x0c, 0x97, 0xce, 0xfa, 0x3b, 0xcf, + 0x87, 0x18, 0xdd, 0xf7, 0x3f, 0x8b, 0xe1, 0x00, 0xcb, 0x61, 0x03, 0x2c, + 0x38, 0xbc, 0x31, 0xdc, 0x80, 0xc4, 0x3f, 0xd5, 0x8c, 0x64, 0xe1, 0x09, + 0x4e, 0x86, 0x59, 0xec, 0x85, 0x55, 0xf0, 0x3a, 0xa7, 0xae, 0xae, 0x02, + 0xd1, 0x9c, 0x00, 0xc9, 0x20, 0x3e, 0x3c, 0x3f, 0x6e, 0x2e, 0xd9, 0x64, + 0xb9, 0x0c, 0x82, 0x32, 0x81, 0xe7, 0x46, 0xf5, 0x72, 0xb5, 0x70, 0x5c, + 0x4c, 0xaf, 0xda, 0xfc, 0x29, 0x07, 0x12, 0x3b, 0x09, 0xde, 0xd3, 0x29, + 0x06, 0xa0, 0x66, 0x94, 0x72, 0xbe, 0xa0, 0x3f, 0xc3, 0xef, 0x4f, 0xf2, + 0x77, 0x21, 0x37, 0x58, 0xd9, 0x62, 0x25, 0x08, 0x41, 0xf4, 0x47, 0xc4, + 0xcb, 0xcb, 0xac, 0x63, 0x14, 0x12, 0xb6, 0xe8, 0xfa, 0xb7, 0x12, 0x6d, + 0x41, 0xd1, 0x1c, 0x8c, 0x3b, 0x3d, 0x10, 0x20, 0xcb, 0xcb, 0x9c, 0xab, + 0x1a, 0x27, 0xe1, 0x71, 0xce, 0x95, 0x67, 0x02, 0xe4, 0x8b, 0x90, 0xe2, + 0x13, 0xb3, 0xb3, 0x0d, 0x33, 0xb3, 0xb3, 0x96, 0x7e, 0xb3, 0xb6, 0x89, + 0x44, 0x94, 0x0a, 0x0c, 0xc0, 0xd6, 0xc3, 0xe9, 0x14, 0x19, 0x0a, 0xfb, + 0xd0, 0x9d, 0x0a, 0x39, 0x61, 0xbe, 0xbb, 0x5f, 0xa4, 0xd4, 0xf8, 0xc4, + 0x7c, 0x91, 0x18, 0xe8, 0x84, 0x46, 0x1f, 0x25, 0x29, 0x9c, 0xbb, 0xd4, + 0x41, 0x9e, 0xdb, 0x04, 0x3b, 0xef, 0x46, 0x72, 0xc6, 0xdb, 0x40, 0x25, + 0x92, 0x7c, 0x34, 0x68, 0x2b, 0x43, 0xbd, 0x4b, 0xfd, 0x8c, 0x51, 0xa2, + 0xcd, 0x91, 0x3e, 0x7b, 0xfe, 0x67, 0xb7, 0x93, 0x5b, 0x62, 0x43, 0x25, + 0x7f, 0xd2, 0x98, 0xd5, 0xfd, 0x63, 0x21, 0x2a, 0x18, 0x0d, 0x0a, 0x3d, + 0xc6, 0x78, 0xe5, 0xd2, 0x92, 0xb1, 0x2a, 0x11, 0xd0, 0x9b, 0xa0, 0x4a, + 0x54, 0x1a, 0x68, 0x04, 0xca, 0x18, 0x7a, 0xc0, 0x4b, 0xeb, 0x76, 0xc9, + 0x81, 0x8e, 0x32, 0xb4, 0x5b, 0x50, 0xa0, 0x94, 0xe6, 0x80, 0xc9, 0x19, + 0xf8, 0x26, 0x57, 0xef, 0xf7, 0x29, 0x71, 0x17, 0xfb, 0xeb, 0x85, 0xa8, + 0xa8, 0x41, 0x5b, 0x26, 0x48, 0x51, 0x83, 0x4c, 0x89, 0x1b, 0xa1, 0x8e, + 0x91, 0xf1, 0xe9, 0x8c, 0xff, 0xba, 0xee, 0xd7, 0x6b, 0x0f, 0xf5, 0x39, + 0x60, 0x69, 0xda, 0xbc, 0x76, 0xd8, 0x15, 0x79, 0x9a, 0x79, 0x59, 0x54, + 0xa5, 0x46, 0xb2, 0x65, 0x7e, 0x34, 0xd4, 0xc4, 0xf6, 0xc7, 0x98, 0x26, + 0x39, 0x9c, 0x30, 0x18, 0xc0, 0x04, 0xac, 0xba, 0xca, 0x5f, 0xcd, 0x7b, + 0x03, 0xd7, 0x0d, 0xa0, 0x71, 0xdd, 0x90, 0x86, 0x85, 0x5e, 0x44, 0xfc, + 0xe3, 0x41, 0xf7, 0xc2, 0xd6, 0x6b, 0xee, 0xa5, 0x6b, 0x2f, 0x72, 0x18, + 0xbb, 0xc8, 0x48, 0xa0, 0x26, 0x48, 0x9b, 0xca, 0xac, 0x6d, 0x73, 0x5a, + 0x5d, 0x3d, 0xef, 0x97, 0xdc, 0x83, 0x4d, 0x47, 0x40, 0xee, 0x60, 0x85, + 0x61, 0xf6, 0x23, 0x2c, 0x80, 0x7c, 0x45, 0x5b, 0x49, 0x91, 0x43, 0x0c, + 0x50, 0x6c, 0xa2, 0x19, 0x0c, 0x03, 0x1f, 0xe7, 0x85, 0x15, 0x7f, 0x75, + 0xb2, 0xf2, 0x64, 0x05, 0x1a, 0x28, 0xbc, 0xa9, 0x21, 0x97, 0x42, 0x86, + 0x5e, 0x10, 0x01, 0xb9, 0x3c, 0x91, 0xfb, 0x95, 0x32, 0xde, 0x1a, 0xdd, + 0x32, 0x09, 0x81, 0x94, 0x9d, 0xda, 0x12, 0xed, 0x5a, 0x53, 0x4a, 0xc8, + 0xa2, 0xeb, 0xa8, 0x41, 0xcd, 0xaf, 0xfc, 0xe3, 0xb5, 0x89, 0x53, 0x90, + 0x30, 0x22, 0x59, 0x0a, 0x00, 0xcb, 0x01, 0xf0, 0x49, 0xb3, 0x5b, 0x7f, + 0x61, 0xc3, 0xc8, 0xee, 0xd9, 0x6d, 0xc8, 0xe1, 0x01, 0xa6, 0xe7, 0x26, + 0x84, 0xe8, 0xc8, 0x9c, 0x20, 0x3e, 0x18, 0x2a, 0xb7, 0x15, 0xd6, 0x66, + 0xb1, 0x51, 0x09, 0x20, 0xc1, 0x1a, 0x8b, 0x2d, 0x01, 0xdc, 0xac, 0xf6, + 0x1f, 0x6a, 0x74, 0x58, 0x8f, 0x30, 0x61, 0x46, 0x0e, 0x04, 0x91, 0x73, + 0x29, 0x08, 0x51, 0x0f, 0x92, 0x6f, 0x03, 0xaa, 0x88, 0x1d, 0x95, 0x57, + 0x6e, 0xec, 0xc2, 0xf8, 0xae, 0x43, 0x50, 0x14, 0xa4, 0x18, 0x19, 0x50, + 0x19, 0x08, 0x7c, 0x78, 0xde, 0xe7, 0xb3, 0x5e, 0x5c, 0x17, 0xde, 0xc0, + 0x66, 0x90, 0xed, 0x65, 0xaa, 0x00, 0x4e, 0x85, 0x3c, 0x6c, 0x79, 0x20, + 0x0d, 0x0f, 0xaa, 0x95, 0xa8, 0x5e, 0xb7, 0x8f, 0xbf, 0x3c, 0x07, 0x12, + 0x11, 0x91, 0xbd, 0xa9, 0x1f, 0x31, 0xf3, 0xd7, 0x8a, 0x6c, 0xd2, 0xa9, + 0xbd, 0x7d, 0xd1, 0x63, 0x39, 0x63, 0x64, 0x85, 0xe1, 0x94, 0xba, 0xb1, + 0xb5, 0xc0, 0xf4, 0xe2, 0xf7, 0x7b, 0xab, 0xc3, 0x99, 0xee, 0x43, 0x23, + 0x18, 0x80, 0x18, 0x50, 0xc3, 0xc0, 0x8e, 0x42, 0xf9, 0xef, 0xe5, 0xad, + 0xe2, 0x6d, 0xd8, 0xb6, 0x2e, 0xde, 0x45, 0xa3, 0x21, 0x87, 0x97, 0x70, + 0x33, 0xcb, 0xfa, 0xe6, 0x45, 0x7b, 0x46, 0x89, 0xf9, 0xa1, 0x2b, 0x09, + 0x65, 0x28, 0x87, 0x9b, 0xb8, 0x79, 0x04, 0x69, 0x01, 0xda, 0xbd, 0x17, + 0x7c, 0x84, 0x94, 0x23, 0x4b, 0x0a, 0x57, 0xe3, 0xf3, 0xed, 0x5d, 0x27, + 0xcc, 0x12, 0xe4, 0x07, 0xd3, 0x01, 0x46, 0x49, 0x43, 0x26, 0xf4, 0x70, + 0x85, 0x6b, 0x65, 0x9f, 0xaa, 0xa4, 0x88, 0x66, 0x20, 0x88, 0x44, 0x03, + 0x4c, 0x32, 0xa0, 0xa2, 0x5c, 0x8f, 0xb4, 0x0d, 0x90, 0x1f, 0x39, 0x41, + 0xfb, 0x48, 0x5c, 0x04, 0x70, 0xd9, 0x47, 0xec, 0x43, 0xae, 0x77, 0x33, + 0x84, 0xda, 0x48, 0xa6, 0xbd, 0xed, 0x92, 0xca, 0x38, 0x60, 0x28, 0x80, + 0x18, 0xd1, 0xa1, 0xd9, 0x46, 0xc7, 0xae, 0x2e, 0xcf, 0xd6, 0x4f, 0xb3, + 0x3c, 0xb7, 0xd0, 0x01, 0x03, 0x31, 0x97, 0xda, 0xd5, 0xee, 0xd7, 0x26, + 0x06, 0x12, 0xa5, 0xe8, 0x2f, 0xdf, 0x80, 0x18, 0xe2, 0x59, 0x64, 0xe1, + 0x20, 0x10, 0xc8, 0x97, 0x92, 0x4b, 0xad, 0x54, 0x02, 0x12, 0xc3, 0xcd, + 0x8a, 0x33, 0xc7, 0xf4, 0xfd, 0x4d, 0xeb, 0x6d, 0x4c, 0xa3, 0x34, 0x00, + 0xf8, 0xa8, 0xc8, 0x21, 0x90, 0x43, 0x3f, 0xae, 0x7b, 0xaf, 0x37, 0x7a, + 0x72, 0xc3, 0x47, 0xce, 0xbb, 0xbf, 0xd0, 0x80, 0x6e, 0x00, 0xd6, 0x71, + 0x42, 0x92, 0x12, 0x9c, 0x62, 0x09, 0xc7, 0x3f, 0x62, 0x36, 0xd2, 0xfe, + 0xff, 0xba, 0xb5, 0x08, 0x27, 0x88, 0x26, 0x86, 0x3b, 0xd4, 0x34, 0x8c, + 0x08, 0xf8, 0x24, 0xb3, 0x46, 0x1b, 0x60, 0xf3, 0x86, 0x32, 0x90, 0x47, + 0xb6, 0x92, 0x1f, 0x8b, 0xb6, 0xa1, 0x7a, 0x4e, 0x67, 0x04, 0x86, 0x51, + 0xfa, 0x96, 0xb4, 0xba, 0xe3, 0xe3, 0x6a, 0x97, 0x0a, 0x02, 0x30, 0x0a, + 0xd5, 0x08, 0x35, 0x42, 0x67, 0x00, 0xac, 0xa0, 0xd6, 0x6a, 0xcc, 0x52, + 0xa3, 0xe5, 0xec, 0xb9, 0x9c, 0xcb, 0xce, 0x53, 0xca, 0x63, 0x97, 0x95, + 0x91, 0x16, 0x6c, 0x65, 0x16, 0xcb, 0x6c, 0x3c, 0xa0, 0xa3, 0x34, 0x42, + 0x29, 0x5e, 0x01, 0x5e, 0xf4, 0xd2, 0xe1, 0x32, 0x9e, 0x42, 0x12, 0x3f, + 0x72, 0x3a, 0x8d, 0xe8, 0xab, 0x8b, 0x0a, 0x86, 0x29, 0x99, 0x00, 0xe3, + 0x38, 0x9a, 0x34, 0x0c, 0xd0, 0xcb, 0x4a, 0x21, 0x11, 0xdc, 0x07, 0xad, + 0x53, 0xe5, 0xb2, 0x30, 0x69, 0x13, 0x92, 0xc9, 0x64, 0xb3, 0x00, 0x35, + 0x33, 0x4d, 0xc0, 0xca, 0x64, 0x3e, 0x08, 0x03, 0x3a, 0x38, 0xde, 0x0d, + 0xd2, 0x96, 0xb7, 0xb7, 0xab, 0xc4, 0x9a, 0x26, 0x74, 0x27, 0xe9, 0xf1, + 0x0a, 0xc3, 0x6f, 0x5a, 0x79, 0xd5, 0xf2, 0x92, 0xd5, 0x33, 0x30, 0x40, + 0x41, 0x06, 0x81, 0x8d, 0xe1, 0xde, 0x9c, 0x8a, 0xbd, 0xb4, 0xb5, 0xc5, + 0x82, 0x8b, 0xe3, 0xc3, 0xf3, 0x03, 0xd3, 0x84, 0xa2, 0xcc, 0x03, 0xed, + 0x67, 0xe6, 0x20, 0x32, 0x94, 0x92, 0x18, 0x0e, 0x44, 0x61, 0x52, 0xaf, + 0xb8, 0x51, 0x7c, 0xac, 0x20, 0x67, 0x2c, 0x3b, 0x90, 0xe1, 0x90, 0x99, + 0x43, 0x24, 0x3d, 0x3f, 0x68, 0xad, 0xda, 0x91, 0x3e, 0x30, 0xc5, 0x2f, + 0xf1, 0x50, 0x71, 0x45, 0xf0, 0x09, 0x4e, 0x34, 0xd2, 0x7d, 0x94, 0xb3, + 0xe9, 0xbd, 0x44, 0x0d, 0x34, 0x18, 0x4f, 0xc4, 0x5c, 0xc3, 0x04, 0x3c, + 0x9b, 0x08, 0xc5, 0x2d, 0x65, 0x23, 0x40, 0x64, 0xa5, 0xf4, 0x77, 0xfb, + 0xbf, 0xca, 0x23, 0x89, 0x8d, 0x03, 0x4b, 0x40, 0xf6, 0xb4, 0x49, 0x39, + 0x24, 0x7c, 0x4f, 0x79, 0xce, 0x13, 0x0b, 0x38, 0xc9, 0xbf, 0xc5, 0x94, + 0x64, 0x07, 0xd0, 0x2d, 0xed, 0xe0, 0x30, 0x14, 0x68, 0xfd, 0x3f, 0x08, + 0x42, 0x62, 0xa3, 0xd3, 0x1c, 0x88, 0x58, 0xe8, 0x8c, 0x9b, 0x22, 0x3c, + 0x41, 0xa6, 0xa5, 0x7d, 0x1d, 0xbf, 0xc0, 0xf9, 0xf9, 0xbe, 0x78, 0x67, + 0x0a, 0x2f, 0xbf, 0x39, 0xd4, 0xb2, 0x6f, 0x07, 0xcc, 0x09, 0xe5, 0x7d, + 0x54, 0xfc, 0xbb, 0x30, 0xc6, 0x22, 0x66, 0x84, 0xf2, 0xb4, 0x8c, 0xa1, + 0x74, 0xaf, 0x04, 0x8e, 0x73, 0x71, 0x1a, 0xf0, 0x67, 0xad, 0x8a, 0x18, + 0xd0, 0xf1, 0x63, 0x95, 0xf4, 0xc7, 0xc4, 0x7e, 0x75, 0xb6, 0x12, 0xd8, + 0xd4, 0xe7, 0x03, 0x11, 0xb2, 0x1e, 0x70, 0x8f, 0xb2, 0xbf, 0x18, 0x7b, + 0xf8, 0x98, 0x97, 0xe1, 0xe7, 0x08, 0x0c, 0x6f, 0x55, 0x19, 0x94, 0xfa, + 0xd5, 0x89, 0xb7, 0xdc, 0xf1, 0x2b, 0xc6, 0x4b, 0x32, 0x8c, 0x26, 0x26, + 0x96, 0x72, 0x4d, 0x55, 0x3d, 0xba, 0x6e, 0xbc, 0xb6, 0x98, 0xe1, 0x9c, + 0x6e, 0x18, 0x12, 0x84, 0xf1, 0x8d, 0x14, 0x0e, 0x5e, 0x01, 0xe2, 0x74, + 0xf7, 0x4a, 0x55, 0xff, 0xb7, 0x3c, 0xe7, 0xfe, 0xd2, 0x97, 0xce, 0xed, + 0xc6, 0xc6, 0xec, 0xfd, 0x89, 0xe9, 0x52, 0x26, 0x8b, 0x82, 0xfa, 0x44, + 0x8c, 0x21, 0xbc, 0xa5, 0x79, 0x76, 0x5b, 0xb7, 0x93, 0x70, 0x56, 0xe0, + 0x00, 0x48, 0x84, 0xee, 0x09, 0x17, 0x61, 0x46, 0x90, 0x44, 0x07, 0x32, + 0x9c, 0xc7, 0x71, 0x56, 0x64, 0x67, 0x46, 0x3e, 0xbf, 0x93, 0xdf, 0x4e, + 0xa6, 0x2c, 0x0a, 0x05, 0x0a, 0x6b, 0x15, 0x0f, 0xe9, 0x0d, 0xb6, 0xf0, + 0xce, 0x0a, 0x32, 0xa1, 0x59, 0x11, 0xe3, 0xa6, 0xac, 0xe1, 0xb4, 0xc4, + 0xbf, 0xcc, 0xac, 0x9d, 0xed, 0xe7, 0x34, 0x49, 0xf1, 0x26, 0xad, 0x58, + 0xdb, 0xf1, 0xb5, 0x00, 0xa1, 0x05, 0xed, 0xb2, 0xe0, 0xc2, 0x96, 0x82, + 0x05, 0xa4, 0x95, 0x59, 0x76, 0xbf, 0xe6, 0x96, 0xb8, 0xd0, 0x29, 0xe5, + 0xad, 0x2b, 0x7b, 0x73, 0xb3, 0x2d, 0x01, 0x20, 0x4d, 0x12, 0x72, 0xdc, + 0x92, 0x5d, 0x1c, 0x24, 0x2e, 0xb8, 0x33, 0x70, 0xe9, 0x41, 0x56, 0xaf, + 0x9f, 0xeb, 0x1a, 0xa5, 0xae, 0x1a, 0x74, 0x68, 0x04, 0x24, 0xc0, 0x01, + 0x38, 0x4e, 0xc8, 0xc9, 0x9f, 0x01, 0xc3, 0x39, 0xc3, 0xb5, 0x0c, 0xa3, + 0xe2, 0xaa, 0x6e, 0xf0, 0x69, 0x07, 0xda, 0x17, 0xbf, 0x6a, 0xcd, 0x92, + 0x26, 0x87, 0xd7, 0x87, 0xae, 0x0a, 0x3d, 0xf5, 0x87, 0xfc, 0x3b, 0x9c, + 0xb1, 0xf2, 0xe8, 0x90, 0x12, 0x92, 0x27, 0xb9, 0x40, 0xea, 0xc5, 0x63, + 0xab, 0xfe, 0xf3, 0xbe, 0x62, 0x07, 0xa2, 0x95, 0xf3, 0x47, 0x72, 0x1b, + 0xd9, 0xaf, 0xd2, 0x2c, 0x51, 0x28, 0x8c, 0x9f, 0xcc, 0xe4, 0xfb, 0x83, + 0x33, 0xdd, 0xba, 0xbe, 0xb4, 0xbb, 0x33, 0xf7, 0x4d, 0x8c, 0xe0, 0xb6, + 0x41, 0xc9, 0x13, 0xc3, 0x72, 0xad, 0xd1, 0xd1, 0xed, 0x58, 0x16, 0xf9, + 0xff, 0xde, 0xf5, 0x0b, 0xfb, 0x38, 0xbb, 0x1b, 0x8c, 0x1e, 0xdf, 0x9a, + 0x5f, 0xd5, 0x8d, 0xb9, 0x8c, 0x60, 0x1c, 0xbc, 0xc2, 0x58, 0x44, 0x23, + 0x94, 0x67, 0xf4, 0x1d, 0x27, 0x10, 0x46, 0xfb, 0x75, 0xa0, 0xc3, 0x22, + 0x6d, 0x45, 0xc1, 0x94, 0xa6, 0xc5, 0x08, 0x7e, 0x30, 0x56, 0x7d, 0xb6, + 0x59, 0xcd, 0x35, 0xfe, 0xcf, 0xfc, 0xf0, 0x1a, 0xe7, 0xb8, 0xf3, 0x04, + 0x0c, 0xa7, 0x05, 0x09, 0xe0, 0x15, 0x86, 0x4e, 0x56, 0xce, 0xff, 0x8b, + 0x6e, 0xed, 0x94, 0x26, 0x79, 0xa2, 0x12, 0xe4, 0x25, 0x38, 0x12, 0xce, + 0xe7, 0x92, 0xfa, 0x6a, 0xaa, 0xb6, 0xa8, 0x84, 0x71, 0xd9, 0x9b, 0x72, + 0xd9, 0x14, 0xb1, 0x66, 0x85, 0x09, 0x91, 0x29, 0xe5, 0xc9, 0x17, 0xa0, + 0x09, 0xfa, 0x20, 0xa5, 0xc3, 0x66, 0x2e, 0x3b, 0x53, 0x59, 0xd1, 0x0c, + 0x40, 0x5c, 0xd2, 0xf7, 0x95, 0x46, 0x53, 0x01, 0x10, 0x4e, 0x53, 0xfd, + 0x46, 0xb7, 0x82, 0x6b, 0xe8, 0xea, 0x52, 0xc6, 0x9b, 0xe5, 0xa5, 0x88, + 0x2a, 0xf0, 0x28, 0x23, 0x51, 0x99, 0x77, 0x00, 0x46, 0x77, 0x3c, 0x9a, + 0xfa, 0x51, 0x28, 0xad, 0x8d, 0x13, 0x0d, 0xe9, 0x41, 0x1a, 0x12, 0x43, + 0xee, 0x12, 0x28, 0xbb, 0x8e, 0xf6, 0x0e, 0x18, 0xc0, 0x57, 0x6f, 0x2d, + 0x28, 0x32, 0x33, 0xf2, 0xa4, 0x06, 0xf2, 0x7b, 0xa3, 0xf1, 0x6b, 0x06, + 0xcf, 0x23, 0x81, 0xe7, 0x90, 0xc5, 0xa8, 0xa9, 0x27, 0x64, 0x97, 0x44, + 0xba, 0x07, 0x1a, 0x52, 0xc9, 0xa2, 0x97, 0x56, 0x19, 0xca, 0x2a, 0x7e, + 0xd8, 0x92, 0x79, 0xbd, 0x7a, 0x0d, 0xf9, 0x61, 0x80, 0x9b, 0x83, 0x31, + 0xa6, 0xa6, 0xe8, 0x32, 0x38, 0x40, 0x99, 0x81, 0x75, 0xd5, 0xa5, 0xd8, + 0xbd, 0x0c, 0x71, 0xb8, 0x1c, 0xe5, 0x65, 0x99, 0x50, 0x09, 0x0c, 0xb3, + 0xe2, 0x7b, 0x5a, 0xbc, 0x1c, 0x0d, 0x21, 0xa9, 0xc8, 0x33, 0x01, 0x2c, + 0x64, 0x66, 0x6f, 0x49, 0xf4, 0xf8, 0xb7, 0x5a, 0x5f, 0xe8, 0x86, 0x10, + 0xcc, 0x01, 0x08, 0xc6, 0x9e, 0x8b, 0xc8, 0x91, 0x47, 0x72, 0x22, 0x55, + 0x83, 0xfb, 0xa5, 0xa7, 0x50, 0xd3, 0x4d, 0xcb, 0xd2, 0xa5, 0x96, 0x60, + 0x35, 0x1e, 0x52, 0x00, 0xa3, 0x39, 0x23, 0xf6, 0x4c, 0x6d, 0x4b, 0x14, + 0x96, 0xf9, 0xa9, 0x43, 0xd9, 0x80, 0x27, 0x6a, 0xf3, 0xa2, 0xcf, 0xc3, + 0x19, 0x19, 0x4f, 0x2a, 0x69, 0x72, 0x32, 0x95, 0x65, 0x3e, 0x9b, 0xfa, + 0x8e, 0x23, 0x36, 0x83, 0xb0, 0x71, 0xd4, 0x0d, 0x52, 0xaf, 0x99, 0x02, + 0xf9, 0x7b, 0x20, 0x8c, 0x82, 0x33, 0x8e, 0x5d, 0xb1, 0x34, 0x18, 0x1c, + 0x32, 0xad, 0x70, 0x4c, 0x88, 0x95, 0x1e, 0xc2, 0xf8, 0xda, 0x70, 0xe0, + 0xc8, 0x62, 0xfc, 0xdc, 0xc8, 0x96, 0x02, 0x83, 0x41, 0x56, 0xbf, 0xc5, + 0xfc, 0xba, 0xdc, 0x53, 0x94, 0x9c, 0x63, 0x38, 0x9c, 0x19, 0x29, 0x99, + 0xa4, 0x60, 0x12, 0xac, 0x53, 0x6b, 0xcc, 0xb1, 0xc3, 0xca, 0x50, 0x24, + 0x4f, 0x68, 0x12, 0x35, 0x53, 0x3b, 0xbe, 0xca, 0x08, 0x87, 0x79, 0x49, + 0x20, 0xd5, 0x60, 0xea, 0x68, 0xc4, 0x50, 0xcb, 0x29, 0x50, 0xf7, 0x02, + 0xfe, 0xba, 0x30, 0x35, 0x3e, 0x06, 0xf5, 0x86, 0x7c, 0x32, 0x22, 0x53, + 0x24, 0xa2, 0x82, 0x33, 0x19, 0x3e, 0xc8, 0x35, 0xbb, 0x30, 0xd2, 0x05, + 0x8b, 0x9f, 0xf0, 0x22, 0xdd, 0xa3, 0x22, 0x81, 0x48, 0x37, 0xda, 0x88, + 0x20, 0xae, 0x96, 0x5c, 0xa1, 0xbd, 0x18, 0x49, 0xe6, 0xe6, 0x6b, 0xdb, + 0xeb, 0x19, 0x06, 0x9c, 0xe8, 0x99, 0x11, 0x93, 0xc9, 0x7d, 0x42, 0xff, + 0xe3, 0xa3, 0x00, 0x82, 0x88, 0x1e, 0x94, 0x67, 0x47, 0xe2, 0xd6, 0x5a, + 0x64, 0xb2, 0x26, 0x40, 0xa1, 0xe9, 0xc2, 0x45, 0x33, 0x4a, 0x8a, 0x5f, + 0x61, 0x3c, 0x11, 0x2d, 0x23, 0xa6, 0x9c, 0xe4, 0x8a, 0x17, 0xa0, 0x4f, + 0xe2, 0xf8, 0xb8, 0xbc, 0xd1, 0x6a, 0x34, 0xa1, 0x94, 0x19, 0x32, 0x97, + 0x80, 0xd5, 0x67, 0x26, 0x01, 0xce, 0x95, 0x41, 0xcb, 0x42, 0x8e, 0x50, + 0x83, 0x0e, 0x70, 0x8d, 0xc0, 0x7a, 0xdc, 0x88, 0xa2, 0x48, 0x9c, 0xf2, + 0x52, 0xfb, 0x6c, 0x49, 0x62, 0xec, 0xcd, 0xe1, 0x39, 0x06, 0xfb, 0x09, + 0xf6, 0x8e, 0x84, 0x8e, 0xe9, 0x25, 0xb9, 0x39, 0x7e, 0x9c, 0xaf, 0x11, + 0x1b, 0x04, 0xf9, 0x7d, 0x9a, 0x1a, 0x4a, 0xab, 0x00, 0xdb, 0xba, 0x4a, + 0xe6, 0xd2, 0x6b, 0x9b, 0x85, 0xf2, 0xcc, 0x32, 0xab, 0xc7, 0x2d, 0x21, + 0x59, 0x3a, 0xb0, 0x27, 0xbf, 0xc5, 0xf2, 0x7b, 0x3f, 0x43, 0x6c, 0xab, + 0xbf, 0xd5, 0xe5, 0x2e, 0xcd, 0x4e, 0xbe, 0xe1, 0xc8, 0x3c, 0x96, 0x13, + 0xed, 0x14, 0xe8, 0xf8, 0x81, 0x7c, 0x49, 0x06, 0x5b, 0xd1, 0xca, 0x45, + 0x2f, 0x2a, 0x34, 0x2e, 0x03, 0xc5, 0x86, 0x64, 0x40, 0x8e, 0x1e, 0x80, + 0x0d, 0x42, 0x14, 0x80, 0x6f, 0xb4, 0xc9, 0xe4, 0xf6, 0xed, 0xda, 0xd4, + 0x45, 0x0d, 0x42, 0xc1, 0x76, 0xe2, 0xbb, 0xd1, 0x05, 0x66, 0x4a, 0xd4, + 0xd1, 0xca, 0x85, 0xc8, 0xcb, 0xfb, 0x84, 0xa5, 0xca, 0x98, 0x8f, 0xbf, + 0xcf, 0xc5, 0x71, 0x5f, 0xfe, 0xe6, 0x92, 0x56, 0x20, 0xa4, 0x34, 0x8a, + 0x35, 0x7a, 0xaa, 0xa2, 0xb5, 0x79, 0xe1, 0x24, 0xa9, 0xee, 0xc3, 0x2c, + 0x4d, 0x59, 0xa0, 0x41, 0xf5, 0x87, 0xa8, 0xa0, 0xeb, 0x02, 0xe9, 0xfd, + 0xdf, 0x77, 0xbb, 0x72, 0xc4, 0x17, 0x9e, 0xdb, 0xe1, 0x18, 0x70, 0xca, + 0x6a, 0x87, 0x24, 0x68, 0xb8, 0x80, 0x84, 0x94, 0xc1, 0xe7, 0xd5, 0x07, + 0xde, 0xd4, 0xdc, 0xce, 0x2a, 0xde, 0x74, 0xb8, 0xd9, 0xfd, 0x5a, 0x0f, + 0x91, 0x9a, 0x70, 0x8a, 0x34, 0x0a, 0xc9, 0x5f, 0x88, 0x28, 0xf9, 0x3a, + 0x79, 0xd6, 0xee, 0x4c, 0x82, 0xa4, 0x97, 0x24, 0x4a, 0x43, 0x2b, 0x25, + 0xf5, 0x55, 0xcb, 0x6f, 0x23, 0xb1, 0x2c, 0x9a, 0x43, 0xe6, 0x9e, 0xe1, + 0x70, 0x77, 0x07, 0x09, 0x14, 0x9c, 0x00, 0x5e, 0xb9, 0x22, 0x28, 0xd7, + 0xf9, 0x41, 0xe6, 0x13, 0xa6, 0x2b, 0x73, 0x5a, 0x4f, 0x6b, 0x98, 0x39, + 0xba, 0xf8, 0xa7, 0xfc, 0x07, 0x1d, 0xbf, 0x69, 0xcc, 0x00, 0xd1, 0x66, + 0xa6, 0x41, 0x00, 0x91, 0x41, 0x1e, 0xe0, 0x07, 0xcb, 0x16, 0xfe, 0xc6, + 0xe6, 0xd5, 0x54, 0xb4, 0x51, 0x4e, 0xf7, 0x2a, 0xb4, 0x86, 0xa0, 0x77, + 0xb8, 0x2b, 0xf2, 0x41, 0x2f, 0xb2, 0x03, 0xc0, 0x7a, 0x92, 0x7b, 0xcb, + 0xd5, 0x9a, 0x65, 0xd2, 0x37, 0x80, 0xbe, 0xdc, 0x4e, 0x0c, 0x3e, 0xaa, + 0x86, 0xef, 0x86, 0x01, 0xa8, 0x77, 0x36, 0xd7, 0xf2, 0xf5, 0xb9, 0xeb, + 0xd8, 0x6e, 0x5e, 0x12, 0x5d, 0xfc, 0xf7, 0x93, 0xb6, 0x91, 0xbc, 0x00, + 0x04, 0x67, 0x97, 0xf7, 0x37, 0xac, 0x3b, 0x81, 0xbe, 0xab, 0x3e, 0xfa, + 0x92, 0x67, 0xb1, 0x60, 0x4e, 0xf4, 0x64, 0x27, 0x08, 0x08, 0x32, 0x40, + 0x9a, 0x3e, 0x2c, 0x4c, 0x9a, 0x53, 0x45, 0xcc, 0xe1, 0xfa, 0x70, 0xda, + 0x8c, 0x00, 0x49, 0x6d, 0x0e, 0x4b, 0x22, 0xf6, 0x7f, 0xd1, 0x49, 0x37, + 0xa0, 0x28, 0x48, 0x5e, 0xa4, 0xc5, 0x76, 0xb8, 0x86, 0x1a, 0xa5, 0x34, + 0xe6, 0x0a, 0x25, 0x80, 0x48, 0x9f, 0x01, 0x25, 0xb3, 0xde, 0xf1, 0x0b, + 0xaf, 0x6b, 0x22, 0x1c, 0x60, 0x1c, 0xc9, 0xa3, 0x17, 0x96, 0x19, 0xb2, + 0x1b, 0xcb, 0xc2, 0x1d, 0xf6, 0x9f, 0xc2, 0x89, 0x99, 0xcd, 0x9b, 0x7f, + 0x67, 0x7e, 0x39, 0xdf, 0x37, 0x9b, 0xd3, 0xf3, 0x7f, 0xfe, 0xb8, 0x34, + 0xb0, 0xf0, 0x03, 0xbf, 0x33, 0x23, 0xa5, 0x01, 0x51, 0x28, 0x09, 0x90, + 0x89, 0x78, 0x4f, 0xd0, 0x1c, 0xf6, 0x61, 0xc6, 0xb4, 0xd4, 0x08, 0x9d, + 0x22, 0xcf, 0x08, 0xa4, 0x70, 0xc6, 0x79, 0x77, 0xa8, 0x15, 0xe9, 0x0d, + 0x74, 0x0a, 0xc6, 0x04, 0xb0, 0x6f, 0x39, 0x80, 0x43, 0xcc, 0xa8, 0xfc, + 0x5a, 0x32, 0xa0, 0x2a, 0xd6, 0x01, 0xb9, 0x41, 0xd1, 0xd8, 0x96, 0x5a, + 0x07, 0x25, 0xf4, 0x5c, 0x48, 0x1f, 0x0b, 0x38, 0x4c, 0x2e, 0x15, 0x23, + 0x32, 0xe2, 0xee, 0x7c, 0x7d, 0xf8, 0xa5, 0x89, 0xde, 0x89, 0x2f, 0xc7, + 0x4d, 0xba, 0x2f, 0xfe, 0x48, 0x95, 0x19, 0x4e, 0x06, 0x64, 0x4e, 0x54, + 0xfc, 0x0c, 0xf6, 0xc3, 0x5a, 0x17, 0xb0, 0x90, 0x9e, 0x52, 0x5c, 0xf2, + 0x51, 0xa4, 0x15, 0xc5, 0xf2, 0x98, 0xce, 0x50, 0xfc, 0xef, 0x86, 0x91, + 0x5b, 0x95, 0x23, 0x42, 0x48, 0xa3, 0x90, 0xea, 0xcb, 0x47, 0x98, 0xdf, + 0xf2, 0xcc, 0xfc, 0x5b, 0x0d, 0xdc, 0x8e, 0x78, 0x86, 0x58, 0xf2, 0xed, + 0xa0, 0x6a, 0xea, 0xe1, 0x51, 0xf1, 0x0c, 0xfb, 0x3a, 0x2c, 0x4e, 0x59, + 0xec, 0x82, 0x32, 0x65, 0x93, 0xc2, 0xd9, 0xa4, 0x32, 0x72, 0x41, 0x91, + 0x45, 0x23, 0x43, 0xc3, 0xab, 0x8a, 0xfb, 0xaf, 0x21, 0xc6, 0x42, 0x85, + 0x61, 0x24, 0xcb, 0x25, 0x09, 0xf4, 0xf6, 0x54, 0x1e, 0x45, 0xe1, 0x42, + 0x19, 0x49, 0x1c, 0x96, 0x11, 0x3c, 0x89, 0x2f, 0xf3, 0xa9, 0x48, 0x39, + 0x02, 0x14, 0x50, 0x26, 0x8f, 0x64, 0x33, 0x85, 0x4f, 0x35, 0x85, 0xe7, + 0xdd, 0x7f, 0x7d, 0xfb, 0xd9, 0xd4, 0x62, 0x06, 0x1a, 0x57, 0x10, 0xfe, + 0x12, 0xc6, 0x9e, 0x26, 0xb6, 0x5d, 0x41, 0xde, 0x66, 0x1e, 0xcf, 0x32, + 0x7b, 0x20, 0x4e, 0xec, 0xf1, 0x84, 0xb2, 0x28, 0x55, 0xd2, 0x4f, 0xcd, + 0x23, 0xff, 0xcb, 0xd4, 0x96, 0x6a, 0x16, 0xc9, 0x1a, 0xd8, 0x02, 0x59, + 0x7f, 0x06, 0x3e, 0x7d, 0xe1, 0x0f, 0x60, 0x79, 0xec, 0x1b, 0x41, 0x5f, + 0x99, 0xb9, 0x65, 0x5d, 0x82, 0xbe, 0x2f, 0x97, 0x8f, 0xd2, 0xef, 0x0e, + 0x32, 0xd7, 0xab, 0x65, 0xc5, 0xa1, 0x92, 0xf1, 0x74, 0x65, 0xf3, 0x00, + 0xb1, 0xab, 0x54, 0x7f, 0x26, 0x43, 0x2c, 0x4e, 0xba, 0x6d, 0x83, 0xb9, + 0x1a, 0x75, 0xec, 0x98, 0x6d, 0x1f, 0xa1, 0x37, 0xdb, 0xaa, 0x3e, 0xb4, + 0x1a, 0xef, 0xe9, 0x4a, 0x7a, 0x76, 0xe3, 0x66, 0x0c, 0x92, 0xf5, 0x06, + 0xcc, 0x39, 0x3d, 0x78, 0x84, 0x7a, 0x7e, 0xb0, 0x7d, 0xd5, 0xff, 0x20, + 0x07, 0x08, 0x68, 0x35, 0xbf, 0x04, 0xd8, 0xc6, 0x59, 0x67, 0xec, 0xa4, + 0x24, 0xfc, 0xce, 0x83, 0x4f, 0x44, 0x3e, 0xde, 0x86, 0xd4, 0x79, 0x9b, + 0xb0, 0xaf, 0x98, 0x4c, 0xf2, 0xa8, 0xe0, 0x1f, 0x47, 0x83, 0x85, 0x12, + 0xfb, 0x32, 0x01, 0x0a, 0x5a, 0xca, 0xc6, 0x92, 0x31, 0x8a, 0x45, 0x1a, + 0x3f, 0x57, 0x1f, 0xb8, 0x96, 0xe1, 0xfd, 0x20, 0xc8, 0x98, 0x54, 0x56, + 0x01, 0x27, 0x2a, 0x50, 0xcd, 0x0f, 0x9e, 0x36, 0xe2, 0x97, 0xae, 0x69, + 0x36, 0x86, 0x5e, 0x54, 0xcc, 0x68, 0x69, 0x73, 0x32, 0xdb, 0x56, 0xbf, + 0xfb, 0xa7, 0x66, 0x20, 0xd6, 0xcb, 0x06, 0x82, 0x07, 0x98, 0x46, 0x6f, + 0xb9, 0x61, 0xbe, 0x3d, 0x57, 0x3d, 0xed, 0x8f, 0x50, 0x2e, 0x56, 0x2f, + 0x37, 0x75, 0xed, 0x94, 0xc2, 0x72, 0x66, 0x91, 0x07, 0x95, 0xa5, 0x6d, + 0xf1, 0xb5, 0xaf, 0x8e, 0xd8, 0xcb, 0x20, 0x1a, 0x44, 0x09, 0xbc, 0xd0, + 0x13, 0x2c, 0x12, 0xb2, 0xa1, 0xf1, 0x3e, 0xda, 0x6b, 0x21, 0xad, 0x9d, + 0x53, 0x59, 0x33, 0x6e, 0x1a, 0x50, 0xb0, 0xc3, 0x19, 0x55, 0x31, 0x00, + 0x61, 0x7c, 0xa9, 0xe5, 0xf8, 0xb7, 0x7f, 0x2e, 0x8f, 0x9b, 0x6e, 0xd1, + 0x3a, 0x1c, 0x66, 0xd0, 0x65, 0xc3, 0x04, 0xe6, 0xe6, 0xf0, 0x98, 0x09, + 0x21, 0x95, 0xe2, 0x18, 0xa7, 0xb2, 0xbd, 0x90, 0x14, 0x05, 0x78, 0xcf, + 0x21, 0x65, 0xa1, 0x93, 0x47, 0x09, 0x15, 0xbe, 0x1f, 0x92, 0xf0, 0x15, + 0x32, 0x84, 0xd8, 0xe0, 0x22, 0x8c, 0xdc, 0xa3, 0x2f, 0x83, 0xf1, 0x43, + 0x14, 0x4c, 0x7e, 0xe1, 0xa0, 0x18, 0xef, 0x5f, 0xa2, 0x1b, 0xe6, 0x66, + 0x97, 0x2a, 0x3e, 0x2d, 0x7f, 0x80, 0x5a, 0x1b, 0xc7, 0x2e, 0x94, 0xdf, + 0x17, 0xe0, 0xfe, 0x8a, 0x77, 0x05, 0xc3, 0x3c, 0x33, 0x28, 0xc2, 0x90, + 0xc9, 0x66, 0x0a, 0x2a, 0x60, 0xa6, 0xec, 0x11, 0x9e, 0x54, 0xd2, 0x82, + 0x5f, 0xdc, 0x10, 0x88, 0x5b, 0x24, 0x6f, 0x4f, 0x69, 0x4a, 0xf5, 0xb8, + 0x5c, 0xac, 0xc6, 0xf7, 0x77, 0x35, 0x19, 0x81, 0x0a, 0x32, 0x0d, 0x92, + 0x11, 0xa3, 0xf1, 0xa2, 0xc8, 0x99, 0x4c, 0xb9, 0x43, 0x2d, 0x28, 0x4a, + 0xf5, 0x3e, 0x23, 0x36, 0x1d, 0xd1, 0xc3, 0x94, 0x87, 0xdc, 0x06, 0xfb, + 0x07, 0x78, 0x60, 0xed, 0x05, 0x2c, 0x9f, 0x65, 0x0f, 0xe5, 0x09, 0x53, + 0x9e, 0x84, 0x91, 0x66, 0x72, 0x4f, 0xc7, 0x1f, 0x05, 0xd6, 0x68, 0x7c, + 0x58, 0xd0, 0xcc, 0xd0, 0xec, 0xc2, 0x86, 0x98, 0x51, 0x7c, 0xa6, 0xa3, + 0x33, 0x56, 0xa1, 0x6f, 0xf1, 0xf8, 0x20, 0xcc, 0x48, 0xed, 0x46, 0xf2, + 0x69, 0x72, 0xf1, 0x72, 0x39, 0x69, 0x09, 0xde, 0x33, 0xf1, 0x54, 0x2b, + 0xcc, 0x4e, 0x3e, 0x52, 0x29, 0x11, 0xd8, 0x4f, 0x8f, 0x06, 0x60, 0xfd, + 0xdd, 0x5d, 0x34, 0xae, 0x37, 0xe6, 0x5c, 0x5e, 0x75, 0xc1, 0xd3, 0xbe, + 0x50, 0x24, 0xb6, 0xf7, 0x23, 0x87, 0xa5, 0xc3, 0x94, 0x12, 0xfc, 0x01, + 0xf7, 0xfb, 0xfb, 0x3b, 0xbe, 0x9e, 0xea, 0xce, 0x5e, 0x2e, 0xf5, 0xba, + 0x4f, 0x90, 0x5e, 0xa6, 0x8e, 0x4f, 0x4e, 0x84, 0x8d, 0x0f, 0x14, 0x61, + 0xf6, 0xe9, 0xd5, 0x5e, 0x6b, 0x35, 0x5b, 0xea, 0xba, 0xd0, 0x3b, 0xd4, + 0xb5, 0x33, 0x37, 0x63, 0xb7, 0x94, 0x98, 0x99, 0x4f, 0x2a, 0x7e, 0x3b, + 0x48, 0x1c, 0xeb, 0xb4, 0xa6, 0x9e, 0x76, 0x2b, 0xc2, 0x89, 0x3b, 0xf8, + 0x36, 0x55, 0xce, 0x57, 0x8d, 0xd0, 0x0b, 0xdd, 0x53, 0x34, 0xa0, 0x93, + 0x01, 0xb1, 0x80, 0x25, 0xa5, 0x51, 0xf1, 0x3d, 0x3e, 0xbc, 0xb3, 0x56, + 0x99, 0xb7, 0x12, 0xa1, 0x73, 0x23, 0x5f, 0x14, 0xf1, 0xb8, 0x83, 0x2e, + 0x73, 0x84, 0xf8, 0x82, 0xb4, 0x54, 0xcb, 0x4c, 0x6b, 0xdb, 0xf3, 0xf1, + 0x04, 0xad, 0x66, 0xb6, 0x7b, 0x9a, 0x25, 0x2c, 0x63, 0x80, 0xfb, 0x61, + 0x8c, 0x0d, 0x1e, 0xe0, 0x4e, 0xfe, 0x37, 0x63, 0x1e, 0x7a, 0x86, 0xfe, + 0xb7, 0x9d, 0x2b, 0x79, 0xd7, 0x9c, 0x0a, 0x0d, 0x35, 0x12, 0x40, 0x83, + 0x49, 0x55, 0x8c, 0x3d, 0x3a, 0xfb, 0x4a, 0x3e, 0xb6, 0xb6, 0xbb, 0xed, + 0x13, 0x6d, 0x2f, 0x9d, 0x95, 0x6e, 0xdc, 0xa9, 0x09, 0x9e, 0x7c, 0xfe, + 0x9c, 0xd5, 0xdd, 0x9d, 0xf3, 0x9e, 0xcf, 0xcb, 0xb9, 0x7e, 0xd7, 0x16, + 0xa2, 0x21, 0x08, 0x27, 0xa0, 0x8c, 0xb2, 0x20, 0x84, 0x6c, 0xee, 0xed, + 0xd3, 0x85, 0xee, 0x7c, 0x6d, 0xc1, 0x18, 0xf4, 0x55, 0x42, 0xa2, 0x29, + 0x55, 0x60, 0x27, 0xdb, 0xbd, 0x76, 0x26, 0x7a, 0x8f, 0x98, 0xcd, 0xa2, + 0xe9, 0xa9, 0x1e, 0xd0, 0x08, 0x4c, 0x26, 0xa8, 0x44, 0x61, 0x89, 0xab, + 0x01, 0xe1, 0xff, 0xb9, 0xbb, 0xc9, 0xc0, 0x14, 0xff, 0xfb, 0x38, 0xb7, + 0xcd, 0x04, 0xa1, 0xe5, 0x81, 0x38, 0xd8, 0x0a, 0x14, 0x6a, 0xd7, 0xe9, + 0x17, 0xb9, 0x25, 0xd0, 0xac, 0xff, 0x0b, 0xff, 0xb4, 0x60, 0xba, 0xbf, + 0x14, 0x9d, 0xee, 0x9b, 0xb3, 0x5c, 0x36, 0xe1, 0x1b, 0x07, 0x70, 0xec, + 0x25, 0x04, 0x03, 0x5e, 0x1d, 0x64, 0x4d, 0x3a, 0xb0, 0xdb, 0xab, 0x34, + 0xf4, 0xff, 0xbc, 0xb0, 0xda, 0x45, 0xa4, 0x96, 0x4f, 0xd8, 0x9b, 0x81, + 0x7f, 0xcd, 0x7e, 0xb6, 0xfb, 0x82, 0x4d, 0x88, 0x35, 0x25, 0x6c, 0x64, + 0x17, 0x97, 0x02, 0x29, 0x14, 0x92, 0x11, 0xf3, 0x2f, 0xf5, 0x69, 0x5c, + 0x40, 0x36, 0x9c, 0xf0, 0x29, 0xc3, 0x40, 0xb6, 0x58, 0x14, 0x27, 0x31, + 0x42, 0x0a, 0xcd, 0x12, 0x7b, 0x83, 0x82, 0x79, 0x2d, 0x7f, 0x1d, 0x07, + 0x43, 0x8e, 0x96, 0x8c, 0x98, 0xa0, 0xf3, 0xcf, 0x90, 0x4e, 0x1f, 0x77, + 0x4a, 0x95, 0xaf, 0x3e, 0x8d, 0x81, 0x9f, 0x79, 0x66, 0x73, 0x92, 0x43, + 0xb8, 0x07, 0x8b, 0xba, 0xc1, 0xaf, 0xbd, 0xee, 0x7f, 0x99, 0xbf, 0x1c, + 0xde, 0x07, 0xac, 0xb2, 0x24, 0x83, 0xb2, 0x38, 0x76, 0xca, 0xf0, 0xdc, + 0x5a, 0xf6, 0xf7, 0xfd, 0xdc, 0xb8, 0xc4, 0xf6, 0xc4, 0x50, 0xe3, 0x48, + 0x11, 0x4e, 0x64, 0xbd, 0xa7, 0x2e, 0x73, 0x94, 0xaa, 0xc3, 0xe2, 0x3d, + 0xec, 0x8f, 0xb7, 0xff, 0xe3, 0x30, 0xbe, 0x4e, 0x5d, 0x0d, 0xb1, 0xa1, + 0xe9, 0xfb, 0x29, 0x07, 0xd8, 0x37, 0xd1, 0xd7, 0xea, 0x2e, 0x3f, 0x5c, + 0x3a, 0xf0, 0xa9, 0x75, 0xd9, 0x5d, 0x54, 0xbf, 0x2f, 0x9e, 0x9d, 0x2b, + 0x73, 0x97, 0xe1, 0x88, 0x5c, 0xe2, 0xe2, 0xa2, 0xd8, 0xe4, 0xbc, 0xe4, + 0xa3, 0x0c, 0x30, 0x25, 0x77, 0x00, 0x88, 0xea, 0x97, 0x2b, 0xfe, 0xae, + 0xdd, 0xdd, 0x6a, 0x16, 0x26, 0x40, 0xa9, 0xc4, 0x03, 0x2d, 0x89, 0x82, + 0x06, 0x9a, 0x33, 0xbd, 0x3e, 0x20, 0x8e, 0xc5, 0x8b, 0x63, 0xda, 0xf5, + 0xed, 0xaf, 0x83, 0xfd, 0xd8, 0x65, 0x62, 0x0e, 0xd2, 0x72, 0xa3, 0x0a, + 0x1d, 0x90, 0xeb, 0x8e, 0xdd, 0xf7, 0x58, 0xdf, 0x8f, 0x65, 0xec, 0x3b, + 0x5c, 0x18, 0x8c, 0xb6, 0x22, 0x4a, 0x7d, 0x63, 0x90, 0xc0, 0x9c, 0x3c, + 0x9c, 0x65, 0x04, 0x7e, 0xc3, 0xe7, 0xa5, 0x12, 0x57, 0x96, 0x63, 0x31, + 0xeb, 0xe6, 0x29, 0x9e, 0xdc, 0xab, 0x30, 0x3b, 0x18, 0x58, 0x38, 0x28, + 0x20, 0x40, 0x3e, 0x01, 0x56, 0x41, 0xe2, 0xf2, 0x3f, 0x7b, 0xf3, 0x37, + 0x60, 0x53, 0x14, 0xd6, 0x75, 0xe8, 0xb1, 0xfe, 0xb7, 0x06, 0x1b, 0x7c, + 0x36, 0x36, 0xcc, 0x88, 0x94, 0xf5, 0x03, 0x89, 0x09, 0x42, 0x3e, 0x8b, + 0x8d, 0x58, 0xfd, 0x5c, 0xcd, 0x2f, 0xd9, 0x96, 0xcd, 0xd7, 0x3d, 0x9d, + 0x88, 0x13, 0x91, 0x16, 0x31, 0x38, 0xaf, 0x47, 0xb5, 0xbd, 0x88, 0x48, + 0xfd, 0x2f, 0x39, 0xa5, 0xe0, 0x59, 0x31, 0x52, 0x99, 0xbf, 0x23, 0x72, + 0x3b, 0xf5, 0xbb, 0xd7, 0xdd, 0xda, 0xa6, 0x26, 0x0d, 0x4c, 0x8d, 0x13, + 0x93, 0xda, 0x52, 0x43, 0x22, 0x02, 0xa1, 0x66, 0xb8, 0x71, 0x7c, 0xad, + 0x57, 0x9b, 0x65, 0x53, 0x2b, 0x32, 0xa7, 0x04, 0xd1, 0x0c, 0x8e, 0x34, + 0xf2, 0xcf, 0x88, 0x3c, 0xd2, 0xd1, 0x9f, 0x17, 0xfd, 0x4e, 0x2d, 0xb7, + 0x62, 0xac, 0x9d, 0xef, 0xb4, 0x96, 0x1b, 0x52, 0x94, 0x16, 0x69, 0xa6, + 0x65, 0xa4, 0xac, 0x04, 0x94, 0x4f, 0x89, 0xd3, 0x7d, 0xde, 0xe1, 0xba, + 0xd3, 0x2d, 0x8f, 0x05, 0x19, 0xa2, 0x89, 0x92, 0x3f, 0x10, 0xce, 0xb0, + 0xf9, 0x5e, 0xfb, 0x3c, 0xb6, 0x59, 0xe5, 0xab, 0xb0, 0x21, 0x7d, 0xb3, + 0x57, 0xf2, 0x82, 0xbf, 0x63, 0xce, 0x0c, 0x00, 0x16, 0x7e, 0xdb, 0x22, + 0x0c, 0xb1, 0xa4, 0x72, 0x49, 0x1f, 0xb4, 0x4f, 0x51, 0xb0, 0xe9, 0xba, + 0x69, 0xb7, 0x6a, 0xc8, 0xc4, 0x57, 0xfc, 0x94, 0xa1, 0xf4, 0x93, 0xd9, + 0x02, 0xe3, 0xde, 0xde, 0x7f, 0x6a, 0x19, 0x52, 0xa2, 0xd0, 0xc1, 0x87, + 0x40, 0xe3, 0x00, 0x52, 0xf6, 0x04, 0x85, 0x64, 0xc5, 0xd5, 0xa7, 0x98, + 0x36, 0xea, 0x7c, 0xce, 0x84, 0x32, 0x93, 0x1c, 0x95, 0x06, 0x38, 0x4b, + 0xe1, 0xa3, 0xf0, 0x22, 0x4f, 0x3e, 0xa4, 0x0c, 0x19, 0x2f, 0x70, 0x0b, + 0x50, 0x8a, 0x9a, 0x2d, 0x87, 0x5f, 0xc6, 0xa8, 0x6c, 0xa8, 0xd7, 0xa1, + 0x46, 0x02, 0xe8, 0x22, 0x4d, 0x01, 0x29, 0x19, 0x7c, 0xf2, 0xdf, 0xcd, + 0xdc, 0xbb, 0xce, 0x11, 0x93, 0x4a, 0xca, 0x95, 0x58, 0x24, 0x6d, 0x7f, + 0xf3, 0xd2, 0xdd, 0x16, 0xcb, 0x1f, 0x3c, 0xeb, 0xce, 0x8a, 0x24, 0x44, + 0xb4, 0xfb, 0x12, 0x46, 0x61, 0x12, 0x32, 0x91, 0xab, 0x27, 0x49, 0x3f, + 0x31, 0x13, 0xae, 0xba, 0x4f, 0x6f, 0x0a, 0x39, 0x7a, 0xc6, 0x9e, 0x43, + 0x1f, 0x34, 0x56, 0x00, 0xf1, 0xad, 0x68, 0x63, 0xa5, 0x51, 0x03, 0x09, + 0x38, 0xd9, 0x1e, 0xdf, 0xd8, 0x39, 0xd7, 0x07, 0x6c, 0x77, 0x51, 0xb8, + 0x6a, 0xf6, 0x82, 0x3b, 0x46, 0x58, 0xd5, 0x69, 0xd1, 0xf7, 0xf3, 0xef, + 0xb8, 0xf7, 0xb8, 0x7f, 0xc7, 0x7f, 0x8f, 0xeb, 0xb1, 0xe6, 0x3d, 0x1a, + 0xcb, 0x0a, 0xc7, 0x0d, 0x3a, 0xbe, 0xb3, 0x2d, 0x00, 0x52, 0x89, 0x85, + 0xf2, 0x08, 0x50, 0xad, 0xfc, 0x50, 0xa0, 0x25, 0x0f, 0x02, 0x78, 0x82, + 0x9f, 0xf2, 0x56, 0x86, 0x81, 0x9b, 0xb9, 0x9e, 0x49, 0x23, 0xe2, 0xd3, + 0x3b, 0x28, 0x9c, 0x32, 0x18, 0x07, 0xcf, 0x32, 0xbc, 0x2f, 0xe4, 0xa0, + 0xbc, 0x68, 0x08, 0x94, 0x01, 0xe1, 0x0f, 0x33, 0x43, 0x27, 0xf1, 0x68, + 0x8f, 0xb0, 0xcf, 0x3e, 0x27, 0x2d, 0xd4, 0xd3, 0x2f, 0x3e, 0x17, 0xa9, + 0x49, 0xa6, 0x08, 0x9a, 0x04, 0xd0, 0xc8, 0xa4, 0xb9, 0xd6, 0x98, 0xdd, + 0x37, 0xe2, 0x9c, 0xe7, 0x3c, 0x49, 0xc0, 0x58, 0xd4, 0x4e, 0x8e, 0x5f, + 0xc7, 0xf5, 0x7e, 0x6f, 0xcb, 0x3c, 0x28, 0x4b, 0x58, 0x78, 0x00, 0xa0, + 0x27, 0x94, 0x12, 0x87, 0x81, 0x67, 0x14, 0x10, 0x82, 0x89, 0xc9, 0xcc, + 0x4e, 0x85, 0xdd, 0x5a, 0xeb, 0x11, 0xc9, 0x08, 0x28, 0xa9, 0x86, 0x39, + 0x8c, 0x1b, 0x08, 0x16, 0xc7, 0xfb, 0xb4, 0xd3, 0x98, 0x9f, 0xd5, 0xe8, + 0x3e, 0x41, 0x30, 0x4b, 0x2c, 0x29, 0x02, 0x4f, 0x81, 0xbf, 0xd1, 0xeb, + 0x55, 0x7e, 0xc2, 0xcb, 0x84, 0xc1, 0x4f, 0x5c, 0xac, 0x59, 0x94, 0x94, + 0xb7, 0x86, 0x7f, 0x31, 0xf6, 0xb8, 0xd7, 0x0b, 0x22, 0x7c, 0x47, 0x6c, + 0xd0, 0xa8, 0xff, 0x6f, 0x82, 0x63, 0x17, 0x6c, 0xa8, 0x09, 0x48, 0x4b, + 0xc1, 0xab, 0x50, 0xda, 0xa3, 0xaf, 0xfa, 0xe4, 0x2f, 0x7c, 0x83, 0xa4, + 0x8e, 0xc0, 0xd5, 0xec, 0x70, 0xef, 0x24, 0x8e, 0xe1, 0x2f, 0x29, 0x64, + 0xef, 0x58, 0xc2, 0xea, 0xf1, 0xe1, 0xb3, 0xce, 0xa9, 0xd4, 0x62, 0x89, + 0x96, 0x42, 0x9c, 0xa6, 0x72, 0x21, 0x2c, 0xe0, 0xef, 0x9d, 0xbd, 0x6d, + 0x7f, 0xf8, 0xa7, 0x5e, 0x0f, 0xb2, 0xcb, 0x61, 0x24, 0x51, 0x80, 0x91, + 0x02, 0x54, 0x12, 0x33, 0xfa, 0x3b, 0x2a, 0x38, 0xb7, 0x97, 0xc0, 0x5b, + 0x42, 0x8d, 0xed, 0xf8, 0xc8, 0x93, 0x96, 0x0c, 0x14, 0x72, 0xa7, 0x3b, + 0xd6, 0xa3, 0xf7, 0xf9, 0xff, 0x79, 0xd9, 0x9b, 0x63, 0x83, 0xa4, 0x08, + 0x67, 0x13, 0x48, 0xa5, 0xe3, 0x9a, 0x13, 0xee, 0x21, 0xab, 0x97, 0x69, + 0xc3, 0xd0, 0xe8, 0x6b, 0x23, 0x44, 0x23, 0x7b, 0x47, 0x0e, 0x0a, 0x52, + 0x47, 0xed, 0x2e, 0xe2, 0x5c, 0x6e, 0x75, 0x68, 0xea, 0xf6, 0x02, 0x70, + 0xf4, 0x86, 0x32, 0xe7, 0x34, 0x32, 0x11, 0xc9, 0xca, 0x85, 0x64, 0x3d, + 0x2b, 0x5a, 0x80, 0x71, 0x0c, 0x09, 0x78, 0xa6, 0x11, 0xf1, 0x10, 0x4a, + 0xac, 0x11, 0x03, 0x32, 0x7c, 0xca, 0x80, 0xba, 0x99, 0x92, 0xb2, 0xdd, + 0x92, 0xfd, 0x33, 0xfb, 0x69, 0x6d, 0x45, 0x0b, 0x76, 0xb7, 0x03, 0x0c, + 0x84, 0xa6, 0x52, 0x89, 0x22, 0x85, 0xe9, 0xc2, 0x14, 0xe4, 0x4d, 0xa5, + 0x39, 0xe5, 0x05, 0x09, 0x81, 0x97, 0x0e, 0x52, 0x57, 0xc7, 0x3e, 0x8b, + 0xec, 0x3d, 0x3d, 0x41, 0xb9, 0x41, 0x23, 0xb2, 0x61, 0x91, 0x9c, 0x25, + 0x02, 0xe5, 0x1c, 0xa1, 0x3f, 0xb1, 0xab, 0x31, 0x45, 0xe8, 0x97, 0xdb, + 0x97, 0x9d, 0x19, 0x40, 0x86, 0x5a, 0x43, 0x09, 0x2b, 0xd1, 0x14, 0x3e, + 0x2e, 0x5f, 0xa6, 0xaa, 0x2c, 0x85, 0x10, 0x68, 0x20, 0x91, 0xf9, 0xc4, + 0xa7, 0x3f, 0x98, 0x37, 0xa7, 0xe7, 0x82, 0xff, 0x18, 0xb4, 0x38, 0x71, + 0x43, 0x00, 0x09, 0x59, 0x82, 0x4d, 0xad, 0xbf, 0x59, 0xe7, 0x71, 0x0b, + 0x09, 0x98, 0x34, 0xd8, 0xee, 0xe4, 0x19, 0x48, 0x37, 0x6a, 0x51, 0x95, + 0x60, 0x0a, 0xb4, 0x39, 0x05, 0xc3, 0x21, 0x94, 0x8a, 0x18, 0x0a, 0x11, + 0xa0, 0x04, 0x4c, 0xde, 0xad, 0xe3, 0x5c, 0xe3, 0x5e, 0x5b, 0xa3, 0xba, + 0x46, 0xbf, 0x63, 0xa1, 0x50, 0xf2, 0x0d, 0xe5, 0xd5, 0x4f, 0xc8, 0xf1, + 0x5c, 0xde, 0xa2, 0x83, 0xec, 0xcf, 0x3d, 0x5e, 0xfe, 0x56, 0xf3, 0xad, + 0xe5, 0x57, 0x92, 0xc9, 0xa5, 0x25, 0x4d, 0x97, 0x22, 0x11, 0x67, 0x62, + 0x4b, 0x46, 0x58, 0x97, 0xd0, 0x13, 0x6f, 0x7f, 0xa7, 0xe5, 0x62, 0xf3, + 0xc3, 0x00, 0x95, 0x48, 0x69, 0x25, 0x81, 0x7f, 0xc1, 0xee, 0xb0, 0x58, + 0x6d, 0x79, 0x9f, 0x53, 0x9e, 0xa8, 0xbb, 0x93, 0x90, 0xc2, 0x08, 0x0a, + 0x22, 0x53, 0xab, 0x53, 0x26, 0x7c, 0xbc, 0x26, 0x9f, 0xe2, 0xc8, 0x78, + 0x75, 0x3b, 0x08, 0x54, 0xf2, 0x86, 0x44, 0x63, 0x6c, 0x48, 0x9c, 0x67, + 0xee, 0x3e, 0x01, 0xf0, 0xb6, 0x6c, 0x8d, 0xf9, 0x22, 0xb8, 0xbe, 0xfe, + 0xb5, 0x7d, 0xda, 0x99, 0x7b, 0xa5, 0x3c, 0x60, 0x8d, 0x24, 0xb1, 0x40, + 0xf7, 0x26, 0x7e, 0x2b, 0x40, 0x4f, 0x67, 0x4d, 0x90, 0xe6, 0x43, 0x7c, + 0x53, 0x58, 0x2e, 0x09, 0x3d, 0x89, 0xff, 0xb7, 0x76, 0x5f, 0x8d, 0xf9, + 0x85, 0x92, 0xe1, 0xbb, 0x50, 0x3b, 0x5e, 0x50, 0x46, 0x7d, 0xa3, 0x1a, + 0x00, 0x7d, 0x85, 0xd1, 0xce, 0x62, 0x79, 0xf3, 0xaa, 0x93, 0x23, 0x39, + 0xb8, 0x2a, 0x09, 0x13, 0x94, 0x32, 0x7e, 0x2e, 0xbb, 0x7d, 0x05, 0x4d, + 0x25, 0x05, 0x53, 0xfd, 0x4d, 0xb8, 0x69, 0xe3, 0xb1, 0x6a, 0x8f, 0x44, + 0x20, 0x46, 0x4e, 0x7e, 0x07, 0x57, 0x7e, 0xe5, 0xad, 0xfb, 0xcf, 0x79, + 0xed, 0xd7, 0x09, 0x27, 0xaa, 0x0f, 0x5f, 0xd3, 0xd1, 0x0c, 0xc0, 0xc9, + 0x95, 0xa9, 0x63, 0x0e, 0xe0, 0x43, 0xa4, 0x77, 0x40, 0xfc, 0xda, 0xa7, + 0x7d, 0xb6, 0xd4, 0x35, 0xd9, 0x9e, 0x4f, 0x62, 0x45, 0x2b, 0x62, 0x84, + 0x86, 0xe7, 0x07, 0x70, 0xbb, 0xef, 0x7e, 0x0b, 0x7e, 0xe3, 0xa3, 0xc0, + 0x74, 0xc0, 0x1d, 0xf0, 0xe5, 0x18, 0x00, 0x08, 0x83, 0x40, 0xe5, 0xca, + 0x58, 0x4b, 0x7c, 0x36, 0x76, 0x29, 0x65, 0x05, 0x49, 0xf7, 0xdf, 0xe5, + 0x44, 0xe7, 0x71, 0x74, 0xe7, 0x83, 0x7b, 0x53, 0x0d, 0x3a, 0x78, 0xf2, + 0x40, 0x22, 0x11, 0x4b, 0x97, 0x88, 0xae, 0xec, 0xa7, 0x3f, 0x21, 0x5a, + 0x81, 0x9e, 0x9f, 0x4b, 0x7d, 0xb1, 0xa2, 0xa7, 0x08, 0x96, 0x70, 0x96, + 0xc6, 0xb1, 0x6a, 0x36, 0xe2, 0x15, 0x75, 0xb0, 0xca, 0x95, 0x7e, 0x45, + 0xc0, 0x45, 0xb2, 0xb4, 0x6b, 0xc3, 0x0c, 0x28, 0x25, 0x64, 0xfe, 0xa2, + 0x15, 0x03, 0x3f, 0xaa, 0xde, 0xf2, 0xb5, 0xed, 0xe4, 0x03, 0x38, 0x37, + 0xb2, 0x48, 0xa0, 0x8b, 0x60, 0x28, 0xcb, 0x2d, 0xa7, 0x84, 0x2e, 0x2d, + 0xe3, 0x0a, 0x37, 0x36, 0xca, 0x1a, 0xaa, 0x03, 0xb4, 0x2f, 0xe5, 0xad, + 0xf7, 0xc9, 0x0f, 0x8b, 0xab, 0x47, 0x66, 0xcb, 0x99, 0x83, 0x52, 0xc7, + 0xa0, 0x96, 0x2a, 0xc3, 0x17, 0xbf, 0xe0, 0x62, 0xde, 0xe2, 0x1d, 0x21, + 0x0b, 0x4f, 0x1d, 0x0c, 0x97, 0xda, 0x8b, 0xc2, 0x9e, 0xea, 0x1e, 0xd5, + 0x88, 0x1b, 0x4e, 0xec, 0xca, 0xd0, 0x08, 0x0d, 0x20, 0x65, 0x29, 0x48, + 0x7c, 0xc0, 0x9f, 0xce, 0x3a, 0xaf, 0xe2, 0x5b, 0xfd, 0xfc, 0xb7, 0x63, + 0xbd, 0x6c, 0x40, 0x10, 0xab, 0xda, 0x72, 0xce, 0x88, 0xca, 0x1f, 0x6d, + 0x49, 0x02, 0x76, 0x22, 0x5a, 0x27, 0xe2, 0x82, 0xa3, 0x9f, 0xdb, 0xdd, + 0xa6, 0xfc, 0x09, 0xd6, 0xce, 0xec, 0xde, 0xe9, 0x34, 0xe0, 0x76, 0xa3, + 0x33, 0x29, 0x83, 0x4d, 0xd0, 0x39, 0x04, 0x19, 0xdf, 0xb5, 0x4f, 0xd8, + 0x29, 0xe5, 0x21, 0xba, 0x63, 0x67, 0x73, 0x40, 0x13, 0xbc, 0x3d, 0x39, + 0x94, 0x21, 0x28, 0x43, 0x59, 0x13, 0xe2, 0x7b, 0xdc, 0xb8, 0x0e, 0x75, + 0xdd, 0x96, 0x7d, 0x63, 0x52, 0xd9, 0x9b, 0x8d, 0xb1, 0xa0, 0x8f, 0x81, + 0x7e, 0x5f, 0x67, 0xfe, 0xae, 0x20, 0x58, 0xb3, 0x54, 0xe1, 0x9c, 0x98, + 0x3b, 0xed, 0x13, 0x2c, 0x47, 0x91, 0x38, 0x05, 0x0c, 0x24, 0x20, 0x03, + 0xc7, 0x83, 0x2f, 0xde, 0x76, 0xd3, 0xa1, 0xfc, 0x83, 0x65, 0xc2, 0xae, + 0xc6, 0x7f, 0xda, 0x0d, 0x68, 0xa1, 0x03, 0xce, 0x54, 0x75, 0x97, 0xe1, + 0x46, 0x7c, 0xd7, 0x9b, 0x9e, 0x0f, 0xed, 0x17, 0xb1, 0xf9, 0x7a, 0x86, + 0xc5, 0x54, 0x8b, 0xd3, 0x92, 0xac, 0x91, 0x83, 0x1e, 0xa2, 0x81, 0xcc, + 0xe8, 0x94, 0x3e, 0xaf, 0x17, 0x33, 0x37, 0x2f, 0x2b, 0x1f, 0x88, 0x75, + 0x27, 0x84, 0xda, 0x89, 0x72, 0x10, 0x9a, 0x13, 0x03, 0x19, 0x9e, 0x69, + 0x1f, 0x03, 0x3a, 0xb4, 0x2b, 0xaf, 0x1c, 0xf4, 0x4e, 0xf4, 0x26, 0xc6, + 0x14, 0x02, 0xf4, 0x4c, 0x2d, 0x90, 0xe5, 0x8c, 0x95, 0x8f, 0xf5, 0xf9, + 0x1e, 0x38, 0x1f, 0xc7, 0x57, 0x45, 0xdd, 0xab, 0x14, 0x24, 0x1e, 0x16, + 0xf3, 0x1c, 0x7b, 0xeb, 0x60, 0x3e, 0xa9, 0x75, 0xe4, 0xbd, 0xe7, 0xa7, + 0x66, 0x72, 0x2e, 0xec, 0xa1, 0x6a, 0x9d, 0xc9, 0x3c, 0x79, 0xb4, 0x07, + 0x95, 0x48, 0x88, 0x21, 0xa1, 0xf5, 0x33, 0x26, 0x34, 0x54, 0xf3, 0xc5, + 0x44, 0x1a, 0x61, 0xea, 0x27, 0x82, 0x84, 0xe4, 0x7e, 0xa9, 0x06, 0x1e, + 0x49, 0xc7, 0x1a, 0x62, 0x8c, 0x84, 0x33, 0x79, 0xcd, 0xa5, 0xb3, 0xb9, + 0x4f, 0x1d, 0x1f, 0xab, 0x89, 0x3b, 0xbc, 0x08, 0x64, 0x78, 0x31, 0xd1, + 0x9d, 0x5e, 0x60, 0x8a, 0x08, 0xf7, 0x31, 0xe7, 0xb3, 0x88, 0x65, 0x73, + 0x01, 0x46, 0x02, 0x8c, 0xcc, 0xa4, 0x8a, 0x07, 0x2e, 0x59, 0x5f, 0x3c, + 0x16, 0xcc, 0xda, 0x51, 0x69, 0x04, 0x20, 0xd5, 0x14, 0x8c, 0x26, 0x34, + 0xbe, 0x39, 0x00, 0x8c, 0x60, 0xc6, 0x83, 0xd0, 0x93, 0x99, 0xf7, 0x29, + 0x81, 0x0c, 0x31, 0x21, 0x0f, 0x32, 0xc7, 0x00, 0x48, 0x25, 0x9f, 0xb3, + 0x84, 0x89, 0xe1, 0x3e, 0x90, 0xf8, 0x0d, 0x66, 0x4e, 0xed, 0xc5, 0x3e, + 0xd3, 0x14, 0xce, 0x55, 0x3e, 0xf6, 0x0d, 0xc5, 0x6d, 0xe3, 0xad, 0x68, + 0x8a, 0x07, 0x19, 0xf1, 0x8a, 0xca, 0x28, 0xf3, 0x6b, 0x54, 0x31, 0x97, + 0x8c, 0xf2, 0x90, 0xc2, 0x17, 0xef, 0x13, 0x63, 0x8d, 0xbd, 0x29, 0x8a, + 0x46, 0x48, 0x63, 0xe5, 0xa5, 0x65, 0xf8, 0x19, 0x92, 0xc5, 0x6d, 0x3a, + 0x95, 0xd9, 0xce, 0xdc, 0x03, 0x01, 0x9c, 0x28, 0x55, 0x32, 0x49, 0x24, + 0x0f, 0x39, 0x5d, 0x66, 0x55, 0xac, 0x5b, 0x4d, 0xc3, 0xa7, 0xe7, 0x70, + 0x9c, 0x57, 0x42, 0xbc, 0x95, 0xa6, 0xa2, 0xc0, 0xa2, 0x4f, 0x64, 0xef, + 0x38, 0x20, 0xce, 0x2a, 0x0b, 0xf1, 0x74, 0x7f, 0x6f, 0x94, 0xf7, 0xac, + 0xa0, 0xaf, 0xd3, 0x97, 0xbc, 0xb5, 0x8a, 0x81, 0x18, 0xd8, 0x74, 0x28, + 0x50, 0xf9, 0xfe, 0xdb, 0x69, 0x9a, 0xfc, 0xb5, 0x3a, 0xbc, 0xa2, 0x89, + 0x74, 0xb3, 0x92, 0xf0, 0x05, 0x5f, 0xde, 0xd1, 0x0b, 0xea, 0xc1, 0x23, + 0x31, 0x87, 0xed, 0x24, 0x67, 0x38, 0x00, 0x3f, 0x38, 0xde, 0xba, 0x70, + 0xbc, 0x57, 0x90, 0x30, 0xa0, 0x66, 0x32, 0x53, 0x43, 0xb2, 0x78, 0x50, + 0xf3, 0x28, 0x06, 0xf9, 0x94, 0xba, 0x7b, 0xbd, 0xf6, 0x7b, 0x6f, 0xfd, + 0xce, 0x5f, 0xae, 0xc3, 0x1c, 0x3f, 0x4b, 0x66, 0x25, 0xa2, 0x27, 0x49, + 0xe6, 0xed, 0x0a, 0x22, 0x84, 0xeb, 0x22, 0xf8, 0xf6, 0xb3, 0xf1, 0xdf, + 0x9b, 0xa7, 0x17, 0x07, 0x28, 0xd3, 0xc4, 0x93, 0x46, 0x41, 0x06, 0x19, + 0x39, 0x04, 0x7c, 0x41, 0x16, 0x66, 0xf0, 0x7b, 0x0a, 0x6e, 0x3b, 0xc7, + 0x3a, 0xc9, 0x3e, 0x3d, 0x5d, 0x2f, 0x4d, 0xdd, 0xea, 0x14, 0x0e, 0x50, + 0x22, 0x8e, 0x2e, 0x1f, 0x64, 0x4f, 0x0d, 0x58, 0x07, 0x37, 0x5d, 0x84, + 0x45, 0x69, 0xdc, 0x43, 0xa8, 0x18, 0xd3, 0x92, 0x32, 0x42, 0x68, 0x1a, + 0xb1, 0x4b, 0x16, 0x70, 0xab, 0x94, 0xa2, 0x89, 0xd6, 0xdc, 0xf7, 0x5f, + 0xe0, 0x0f, 0xf6, 0xd7, 0x3a, 0xe6, 0x1e, 0x46, 0xca, 0x30, 0xa9, 0xa1, + 0x90, 0x32, 0xa0, 0x5f, 0x88, 0x27, 0x41, 0x1f, 0xa8, 0x34, 0xd9, 0xe7, + 0x49, 0x27, 0x68, 0xba, 0x5b, 0x1d, 0x75, 0x13, 0xc9, 0x9c, 0x96, 0x4f, + 0xc1, 0x37, 0x39, 0xdf, 0xae, 0x4d, 0x6b, 0xe4, 0x84, 0x63, 0x11, 0xf1, + 0x50, 0x08, 0xf8, 0xc8, 0x50, 0xb1, 0xbe, 0xdf, 0x52, 0x69, 0x89, 0x8a, + 0x9d, 0xb9, 0x96, 0x30, 0x23, 0x22, 0x18, 0x43, 0x8a, 0xf4, 0xbb, 0x46, + 0xed, 0x72, 0x67, 0x08, 0x5c, 0x7a, 0x9f, 0xa8, 0x18, 0xf8, 0xc1, 0x21, + 0x34, 0x67, 0xe9, 0xfa, 0xad, 0xc8, 0x53, 0x18, 0x50, 0x12, 0xa1, 0x21, + 0x33, 0x92, 0xf0, 0x89, 0xf5, 0x65, 0xfc, 0xba, 0x8a, 0x18, 0xba, 0xba, + 0x66, 0x06, 0x3e, 0x64, 0x68, 0xb6, 0x83, 0xcf, 0x79, 0x75, 0xf9, 0x90, + 0x86, 0x4b, 0xc5, 0x5f, 0xff, 0x6c, 0xa3, 0xab, 0x8a, 0x43, 0x28, 0xf4, + 0x7d, 0x4e, 0x69, 0x13, 0x30, 0x32, 0xea, 0xf4, 0xea, 0xd8, 0xc7, 0xf4, + 0xcb, 0xff, 0x4b, 0xd3, 0x8a, 0x36, 0x0c, 0xf0, 0x1f, 0x01, 0x4c, 0xd7, + 0x41, 0x20, 0xc4, 0xde, 0xc7, 0xa5, 0x76, 0xf0, 0x65, 0xf3, 0x03, 0x10, + 0x8e, 0xda, 0x7f, 0xd9, 0x89, 0x47, 0xce, 0x11, 0x88, 0x45, 0x36, 0x9d, + 0x4c, 0x65, 0x5b, 0xea, 0xc5, 0xe5, 0x87, 0x75, 0x29, 0xd4, 0xff, 0x15, + 0x4f, 0x7a, 0x3c, 0x4d, 0x07, 0x62, 0x8e, 0xab, 0x73, 0x26, 0x50, 0x02, + 0xc6, 0x11, 0xf3, 0x34, 0x3b, 0x82, 0x52, 0xb1, 0xe1, 0x64, 0x9e, 0x9b, + 0xff, 0x10, 0x40, 0x08, 0x0e, 0x34, 0x01, 0x33, 0x82, 0x6f, 0x4b, 0x46, + 0x80, 0x42, 0xb2, 0xb1, 0x45, 0xdd, 0xed, 0x99, 0x39, 0x18, 0x28, 0xbc, + 0xa8, 0xe1, 0xf1, 0x90, 0x4b, 0xfa, 0xf2, 0x6a, 0x9c, 0xa2, 0x06, 0xdc, + 0xfe, 0x97, 0x20, 0x51, 0x24, 0xb8, 0x07, 0x1a, 0x1c, 0x7d, 0xa4, 0x7b, + 0x68, 0x93, 0x9e, 0x2e, 0x4c, 0x3b, 0xd9, 0xae, 0x77, 0x97, 0x40, 0xd2, + 0xd4, 0x92, 0x51, 0x39, 0x2a, 0x19, 0x10, 0x05, 0x91, 0xfc, 0x7f, 0x96, + 0x34, 0x80, 0x4b, 0x8c, 0x0c, 0x61, 0x46, 0x8f, 0xd1, 0xf7, 0x62, 0xad, + 0x6a, 0xfd, 0x78, 0xb9, 0x9d, 0x45, 0x8c, 0x95, 0x44, 0x21, 0xdc, 0x35, + 0xa9, 0x92, 0x31, 0xb5, 0x06, 0x1a, 0x79, 0x46, 0x16, 0x28, 0x51, 0x4b, + 0x48, 0x56, 0x68, 0x31, 0x45, 0x46, 0xcd, 0x05, 0x0a, 0x18, 0x7c, 0x9f, + 0x64, 0xec, 0xb6, 0x6a, 0xf4, 0xed, 0x0f, 0x86, 0xd0, 0x28, 0x24, 0x5e, + 0x86, 0x1c, 0xa5, 0x61, 0x03, 0x95, 0x39, 0x40, 0x17, 0xf9, 0x82, 0xd3, + 0xf8, 0xc5, 0x2a, 0x8c, 0xde, 0x73, 0xc3, 0x7a, 0x7b, 0x91, 0x61, 0x86, + 0x83, 0x09, 0xcf, 0xb0, 0x74, 0x3e, 0x7a, 0xc7, 0xe6, 0x76, 0x47, 0x2a, + 0xf4, 0x7c, 0xe7, 0x0c, 0xc2, 0x63, 0x64, 0xc6, 0x57, 0x80, 0x17, 0x08, + 0x14, 0x17, 0xe7, 0x21, 0xdb, 0x66, 0x54, 0x18, 0x88, 0x0b, 0x65, 0x42, + 0x97, 0x46, 0x7d, 0x91, 0x26, 0x5e, 0x59, 0x3c, 0x48, 0x06, 0xbc, 0x20, + 0x66, 0x89, 0x39, 0x64, 0xd6, 0x5a, 0x7a, 0x05, 0x10, 0x89, 0x44, 0x4a, + 0x73, 0x98, 0x3e, 0x9f, 0xb0, 0xc3, 0x3c, 0xea, 0x77, 0x95, 0xc6, 0xc5, + 0x5b, 0x08, 0x07, 0x2b, 0xaa, 0x63, 0x25, 0x4c, 0xf6, 0xa7, 0x08, 0xf9, + 0x42, 0x4c, 0xc7, 0xa9, 0xe9, 0x58, 0x0a, 0x9e, 0x4a, 0x0e, 0xf6, 0x2b, + 0xf5, 0x35, 0x20, 0x55, 0x65, 0x46, 0xda, 0x32, 0xdc, 0xb5, 0x29, 0x4a, + 0x79, 0x2a, 0x1e, 0x20, 0xa3, 0x3f, 0xfb, 0x5c, 0xf7, 0xce, 0x5f, 0x3b, + 0x96, 0xb9, 0x16, 0xf4, 0x6f, 0xe9, 0x5b, 0x63, 0x86, 0x85, 0xbe, 0x7f, + 0xe8, 0x3b, 0x30, 0xdb, 0xc0, 0xd4, 0xeb, 0xf8, 0xcd, 0x40, 0x4e, 0x72, + 0x1f, 0x37, 0x74, 0xb7, 0x28, 0x93, 0xe2, 0x0d, 0xdf, 0x5b, 0x9f, 0xa0, + 0x1b, 0x82, 0x13, 0x2d, 0x52, 0x3b, 0xdd, 0x17, 0x32, 0x93, 0x36, 0x82, + 0x5f, 0x68, 0x3c, 0x1d, 0xf3, 0x54, 0xcd, 0x2e, 0x24, 0x5f, 0xcb, 0x73, + 0x5e, 0xf1, 0x31, 0xf7, 0xb5, 0x3d, 0x6c, 0x43, 0x65, 0x2a, 0x8d, 0xf9, + 0x05, 0xb2, 0xa4, 0x67, 0x46, 0x50, 0x65, 0x8a, 0xb0, 0xcc, 0xbf, 0xea, + 0xa5, 0x46, 0xfd, 0x39, 0xb7, 0x75, 0xa8, 0x8f, 0xd3, 0x91, 0x5a, 0x79, + 0x98, 0x2b, 0x7b, 0xa3, 0x97, 0x49, 0xa1, 0x08, 0xb4, 0x62, 0x97, 0x58, + 0x13, 0x9b, 0xef, 0x5e, 0x7e, 0xfd, 0x23, 0xf7, 0x6f, 0xf2, 0xfc, 0x79, + 0x9f, 0x5a, 0x56, 0x33, 0x0d, 0x73, 0x67, 0x9a, 0x9b, 0xed, 0xc0, 0x30, + 0xe2, 0xa3, 0x5e, 0x12, 0x91, 0x3f, 0x68, 0x95, 0xbf, 0x77, 0xfd, 0xd4, + 0x4d, 0x8b, 0xd5, 0xf6, 0xb1, 0x4c, 0x95, 0xb7, 0x50, 0xba, 0xb5, 0xf1, + 0x06, 0x33, 0xd2, 0x9b, 0x32, 0x8b, 0xb9, 0x34, 0x4b, 0xe3, 0x4c, 0x91, + 0xdc, 0x27, 0xd7, 0xa9, 0x61, 0xe2, 0xfb, 0x41, 0xf7, 0xf6, 0xb9, 0x67, + 0x3d, 0x38, 0x5a, 0xc7, 0xf5, 0x62, 0xae, 0x9b, 0x86, 0x65, 0x29, 0xa8, + 0x90, 0x03, 0x3a, 0x27, 0x48, 0xe2, 0x63, 0x0c, 0xaf, 0xa8, 0x26, 0xfd, + 0x8f, 0xee, 0xb7, 0x22, 0xa9, 0x97, 0x6d, 0x8b, 0xe7, 0x56, 0x56, 0xec, + 0x50, 0x9d, 0x18, 0x20, 0x59, 0xc8, 0x4c, 0x9d, 0xe8, 0xfd, 0x86, 0x6e, + 0xb9, 0xfd, 0xa6, 0x95, 0x30, 0x02, 0xa9, 0x4b, 0xb0, 0x83, 0x51, 0x8f, + 0x6d, 0x00, 0x75, 0xd1, 0x37, 0x85, 0x47, 0xec, 0x75, 0xb3, 0xab, 0xb3, + 0xf4, 0xd3, 0x62, 0x2d, 0x95, 0x0f, 0xe6, 0xd6, 0xbb, 0x49, 0xc2, 0x08, + 0x77, 0x4b, 0x91, 0x18, 0xc2, 0xb3, 0x90, 0x99, 0x90, 0x81, 0x2b, 0xc9, + 0xba, 0x79, 0xe3, 0xca, 0x1b, 0x71, 0x5a, 0x6d, 0xbc, 0xd9, 0x98, 0x92, + 0xba, 0x7b, 0xe5, 0xeb, 0x9b, 0x29, 0xde, 0x6e, 0x85, 0x20, 0x10, 0x82, + 0xb0, 0x0a, 0x73, 0x3a, 0xd1, 0xf6, 0x58, 0x5a, 0xd7, 0xc6, 0xb6, 0x29, + 0x42, 0xca, 0x32, 0x3b, 0x04, 0xa2, 0xd4, 0x09, 0x93, 0xf6, 0xb9, 0x2a, + 0x12, 0xfb, 0x52, 0x22, 0xfc, 0xbe, 0x66, 0xb3, 0x71, 0xd1, 0xdc, 0xe6, + 0xf5, 0xd4, 0x09, 0xea, 0xd5, 0x57, 0x35, 0x1d, 0x00, 0x09, 0x44, 0xcc, + 0x94, 0x65, 0x4a, 0x52, 0xee, 0x44, 0xb5, 0x26, 0xe3, 0x8c, 0xef, 0x61, + 0x65, 0x73, 0x37, 0xed, 0x4b, 0x8c, 0xa4, 0x08, 0x32, 0x87, 0x21, 0xd1, + 0x26, 0xad, 0xbf, 0xb4, 0xf6, 0x4e, 0x57, 0x4e, 0x53, 0xa2, 0xed, 0x3c, + 0xdd, 0xda, 0x70, 0x93, 0xd3, 0x12, 0x9d, 0x69, 0x85, 0x02, 0x06, 0x3c, + 0x27, 0x27, 0x0b, 0xc9, 0x21, 0xe0, 0x7f, 0xf6, 0xb1, 0x38, 0xe9, 0xbd, + 0x22, 0x14, 0xd8, 0x83, 0x79, 0x36, 0x90, 0x08, 0x76, 0x50, 0xb0, 0xab, + 0xc6, 0xd6, 0x75, 0xe5, 0x32, 0x3f, 0xcf, 0xc7, 0x05, 0x7e, 0x98, 0x9b, + 0xe4, 0x1b, 0xda, 0x72, 0x06, 0xc2, 0x45, 0x5e, 0x9b, 0xf6, 0x6d, 0xcb, + 0xe7, 0x82, 0x8c, 0xc7, 0xff, 0x56, 0xdc, 0xb2, 0x2f, 0xee, 0x6d, 0xe0, + 0xd3, 0x5d, 0x87, 0xcc, 0x8a, 0xbc, 0xe3, 0xb5, 0xa3, 0xe9, 0xb2, 0x89, + 0x82, 0x60, 0xb7, 0x73, 0x74, 0xb0, 0xf0, 0x3b, 0x28, 0x20, 0xb0, 0x1e, + 0xe3, 0x3f, 0x8b, 0x7f, 0xf7, 0xf6, 0x43, 0x4d, 0x33, 0xb2, 0x02, 0x27, + 0x4d, 0x8d, 0x80, 0xfc, 0xd1, 0xe0, 0x24, 0xe7, 0x82, 0xdf, 0xe9, 0x1c, + 0x62, 0x34, 0xd2, 0x9b, 0xd1, 0x9a, 0x5f, 0x61, 0x6a, 0xd4, 0xd9, 0x8f, + 0x5c, 0x8e, 0xa3, 0x19, 0x6b, 0xd2, 0xda, 0x16, 0x54, 0xc4, 0xf8, 0xb1, + 0x95, 0x48, 0x3e, 0x26, 0x5c, 0x27, 0x1c, 0xf2, 0xd2, 0x0d, 0x36, 0x3f, + 0x69, 0x9e, 0x6d, 0x81, 0x86, 0x1f, 0x50, 0xcd, 0xa9, 0x76, 0x08, 0xe1, + 0xd3, 0xb0, 0xda, 0xfb, 0xd8, 0x5d, 0x93, 0xb1, 0x8e, 0x6d, 0x14, 0xed, + 0xdf, 0xf7, 0x57, 0xff, 0xff, 0x8c, 0x4d, 0x15, 0x36, 0x21, 0x87, 0x64, + 0xb0, 0x67, 0xe5, 0x89, 0x90, 0x9a, 0x26, 0x86, 0xa5, 0x2c, 0x20, 0xc3, + 0xcd, 0x4b, 0x7c, 0x6c, 0xc0, 0xfa, 0x40, 0xca, 0x08, 0x65, 0xa3, 0x40, + 0x31, 0x9a, 0x59, 0xfb, 0x46, 0xd7, 0xe7, 0xda, 0xa1, 0x46, 0x9b, 0x3c, + 0x05, 0x40, 0x11, 0x5e, 0x7e, 0xd5, 0x8e, 0x58, 0xaf, 0x43, 0x0c, 0x86, + 0x5f, 0x88, 0x37, 0x81, 0x4e, 0x7c, 0xea, 0xdf, 0x32, 0xde, 0x9d, 0x7f, + 0x43, 0x1c, 0x15, 0x96, 0x10, 0xe4, 0xe8, 0x50, 0xab, 0x6f, 0x37, 0x6a, + 0xf7, 0x6c, 0x68, 0x21, 0xda, 0x19, 0x5d, 0x2d, 0xc7, 0x9d, 0xcc, 0x88, + 0x18, 0x8c, 0xe3, 0x00, 0x68, 0x05, 0x1c, 0xa2, 0x6a, 0xc3, 0xaf, 0xbd, + 0xd1, 0xb3, 0xc5, 0xba, 0xa5, 0xb7, 0xc6, 0x91, 0xf3, 0x4f, 0x1c, 0xba, + 0x10, 0x23, 0x21, 0x2a, 0x4e, 0xd8, 0xf9, 0x72, 0xf1, 0x3a, 0x7b, 0xab, + 0x9c, 0x2d, 0xec, 0x6f, 0x2b, 0x15, 0xcb, 0x38, 0xa6, 0x60, 0x83, 0x5a, + 0x08, 0x9d, 0xed, 0x67, 0xb5, 0x27, 0x2b, 0xb9, 0x0b, 0xa0, 0x8f, 0xf6, + 0xfd, 0x68, 0x27, 0xe6, 0xbb, 0x6b, 0x53, 0x86, 0x30, 0x14, 0x1b, 0x89, + 0x51, 0x39, 0x5b, 0x38, 0x60, 0xce, 0x8d, 0x65, 0xc7, 0x81, 0xbd, 0x5e, + 0xd1, 0x08, 0xdd, 0x65, 0x15, 0x1d, 0xff, 0xfa, 0x86, 0x2d, 0x9c, 0x1d, + 0xf3, 0x01, 0xc3, 0xc3, 0x38, 0x6a, 0x9a, 0x65, 0x38, 0xc2, 0x82, 0x38, + 0xef, 0xe3, 0x70, 0xc2, 0xc9, 0xf3, 0xc3, 0x99, 0x75, 0x14, 0xa9, 0x85, + 0x21, 0x5a, 0xd2, 0xd0, 0xd0, 0x4a, 0x26, 0x31, 0xc7, 0x90, 0xee, 0x41, + 0x9a, 0x8f, 0xbf, 0x9d, 0xaf, 0x4b, 0x7b, 0x56, 0x23, 0x6e, 0xbf, 0x6b, + 0x87, 0x1a, 0x56, 0x91, 0xe5, 0xec, 0xf9, 0xbe, 0xe1, 0x51, 0xaf, 0x50, + 0xcb, 0xee, 0x4e, 0x33, 0xdf, 0xb3, 0xbe, 0x8e, 0xed, 0x7a, 0x47, 0x12, + 0x0e, 0x28, 0xa8, 0xe3, 0x41, 0xb0, 0xdb, 0x12, 0xaf, 0x10, 0x0e, 0x32, + 0x13, 0x99, 0xf9, 0xf0, 0xf5, 0x48, 0x61, 0xa2, 0xec, 0x3a, 0x8c, 0x5c, + 0xa8, 0xab, 0xef, 0x77, 0xea, 0xe2, 0x8a, 0xc8, 0xb3, 0x8d, 0xcf, 0x70, + 0xf0, 0x4d, 0x7e, 0x1c, 0xa2, 0x40, 0x6a, 0x28, 0x50, 0x3e, 0x29, 0x5f, + 0x76, 0x05, 0x99, 0x90, 0x18, 0xf8, 0x48, 0xa8, 0xb5, 0x77, 0xd9, 0xb8, + 0xd5, 0xba, 0x6a, 0x58, 0xdb, 0x83, 0x72, 0x62, 0xee, 0xfa, 0x70, 0x4b, + 0x97, 0x4b, 0x45, 0x00, 0x68, 0xc1, 0x23, 0xdc, 0x09, 0xd8, 0x3c, 0xca, + 0xb8, 0x73, 0xab, 0x6d, 0x6e, 0x27, 0x95, 0xcd, 0x42, 0x2f, 0x51, 0x2e, + 0x70, 0x65, 0x1a, 0x06, 0x67, 0x1b, 0x09, 0xf6, 0xf0, 0x02, 0x40, 0x59, + 0x3a, 0x77, 0x1b, 0x9d, 0x52, 0x3e, 0x46, 0xc7, 0x5a, 0x4e, 0xdc, 0xa6, + 0x6e, 0x3f, 0x6c, 0xdc, 0x82, 0x1b, 0x16, 0x66, 0x43, 0x23, 0x32, 0xab, + 0x27, 0x78, 0xb1, 0x5d, 0xad, 0x54, 0x48, 0x9a, 0x3e, 0x7b, 0x49, 0x60, + 0x6d, 0x2d, 0xd9, 0xbf, 0x29, 0xa1, 0xa7, 0xb7, 0x34, 0x09, 0x94, 0xa0, + 0x64, 0xbf, 0x04, 0xf7, 0x8f, 0x5b, 0x71, 0xfa, 0xa5, 0x9c, 0xdb, 0x43, + 0x1c, 0x0c, 0x66, 0x7b, 0x21, 0xd3, 0xe3, 0x69, 0x6e, 0xf8, 0x67, 0x04, + 0x3c, 0xb1, 0xa6, 0x7c, 0x57, 0xea, 0x83, 0x08, 0x45, 0x2e, 0x5d, 0x1a, + 0x8d, 0x02, 0xe4, 0xe5, 0xfc, 0x61, 0x50, 0x61, 0x13, 0x9b, 0x6e, 0x54, + 0x28, 0x0a, 0x09, 0xd7, 0x97, 0x2c, 0x72, 0x27, 0xb6, 0xa8, 0xe5, 0x43, + 0x27, 0x29, 0xcf, 0xc4, 0x05, 0x2b, 0x78, 0xed, 0x69, 0xe0, 0x20, 0x48, + 0x8c, 0x02, 0x5f, 0x40, 0x71, 0xfd, 0x39, 0xbe, 0x2f, 0xbb, 0xeb, 0xde, + 0xbd, 0xb4, 0x2f, 0x97, 0xa0, 0xcc, 0xdb, 0xed, 0x1c, 0x73, 0x5e, 0x70, + 0x32, 0xdf, 0x45, 0xcc, 0xf2, 0xbe, 0x80, 0xed, 0xf6, 0xce, 0x60, 0xeb, + 0x66, 0x4a, 0x4b, 0x17, 0x87, 0xf1, 0x8c, 0x46, 0x0b, 0x5a, 0x74, 0x13, + 0xcf, 0x51, 0x4c, 0xfa, 0x37, 0xb8, 0xe7, 0xf7, 0xf8, 0xbf, 0xb7, 0x0e, + 0xee, 0x74, 0xff, 0x3e, 0x35, 0x0c, 0x3e, 0x5b, 0x64, 0x82, 0x27, 0x63, + 0x27, 0x24, 0xa1, 0xf6, 0x0d, 0x99, 0xae, 0x3a, 0xe7, 0xe2, 0xf7, 0xdc, + 0x47, 0x45, 0x00, 0x93, 0x0d, 0x9b, 0x37, 0xba, 0xce, 0x1c, 0x80, 0x44, + 0x81, 0x4a, 0x28, 0x9a, 0xc1, 0xce, 0x2d, 0x49, 0xea, 0xe2, 0x73, 0xe7, + 0xb0, 0x4c, 0xe3, 0x0d, 0x4e, 0xf7, 0x9a, 0x5c, 0x1d, 0xa0, 0xa2, 0xf4, + 0x06, 0x12, 0x0f, 0x3d, 0x2d, 0x3f, 0xb7, 0xe5, 0xbf, 0xff, 0x60, 0x84, + 0x94, 0x7a, 0xef, 0xce, 0xd2, 0x15, 0x1a, 0x80, 0x75, 0x18, 0x28, 0xb0, + 0x9a, 0x08, 0x48, 0x43, 0x84, 0x6f, 0x83, 0xdb, 0xb0, 0xd0, 0x51, 0xf5, + 0x15, 0x19, 0xc2, 0xc2, 0x53, 0xf9, 0xbf, 0x93, 0x37, 0xfc, 0xcb, 0x3a, + 0x2f, 0x16, 0x6a, 0x54, 0x67, 0xa7, 0xa6, 0xe4, 0xd1, 0x25, 0xe0, 0x30, + 0x06, 0x13, 0x00, 0x0a, 0x2e, 0x11, 0xf1, 0x33, 0x9e, 0xb4, 0xe7, 0x1c, + 0xe3, 0x0c, 0x91, 0xfb, 0x52, 0x62, 0x46, 0xcd, 0xed, 0x77, 0x12, 0xff, + 0x15, 0x7b, 0xd7, 0x3b, 0x22, 0xcd, 0xd7, 0xf4, 0x0c, 0xe1, 0x85, 0x68, + 0x0a, 0x24, 0xd0, 0x07, 0x0e, 0xf5, 0x68, 0x5d, 0x55, 0xb5, 0xe3, 0x28, + 0x68, 0x23, 0x40, 0xec, 0x0d, 0x94, 0x8c, 0xa8, 0x09, 0x77, 0x16, 0xe5, + 0xab, 0xc5, 0xe8, 0x53, 0xe2, 0xc1, 0xce, 0x5c, 0xa9, 0x55, 0x10, 0xea, + 0x9b, 0x3e, 0x8a, 0x1d, 0xae, 0x60, 0x1d, 0x09, 0xc7, 0xf7, 0xf5, 0xca, + 0x92, 0x02, 0x5f, 0x35, 0x96, 0x74, 0x72, 0x85, 0x29, 0xf8, 0x04, 0x20, + 0x70, 0xf7, 0xb9, 0x34, 0x46, 0x3a, 0xb2, 0x92, 0x05, 0x1f, 0xa3, 0x05, + 0x5d, 0xb0, 0x10, 0x15, 0xbe, 0x01, 0x21, 0x03, 0x57, 0x46, 0xef, 0x43, + 0x80, 0x10, 0xc9, 0x78, 0xf2, 0x33, 0x39, 0xd3, 0xc0, 0x6a, 0x92, 0xd9, + 0x69, 0x22, 0xbf, 0xd9, 0xd1, 0xf4, 0xda, 0xb5, 0xe9, 0xe8, 0x65, 0x1a, + 0x60, 0x3b, 0x19, 0xbd, 0x44, 0xe8, 0x89, 0x77, 0x28, 0xb9, 0xbb, 0xcd, + 0x2d, 0xfb, 0x7b, 0xf0, 0x74, 0x32, 0xbf, 0x6f, 0x4c, 0x74, 0xf8, 0x0a, + 0x0f, 0x31, 0x24, 0x51, 0xfa, 0x01, 0x51, 0xe3, 0x8d, 0x4f, 0xfe, 0x08, + 0x8d, 0x02, 0xd8, 0x71, 0xa3, 0xfd, 0xc8, 0x19, 0x7b, 0xd1, 0x87, 0x6c, + 0x72, 0x73, 0x7f, 0x9e, 0x31, 0xb7, 0xbf, 0xc3, 0x6f, 0xcf, 0xd3, 0xd9, + 0x7a, 0x3a, 0x76, 0xc5, 0xe5, 0xb9, 0x7b, 0x20, 0x13, 0xa3, 0x2d, 0xa1, + 0x7a, 0xa2, 0x60, 0x49, 0xfd, 0xba, 0x2f, 0x2c, 0xb9, 0x48, 0x49, 0xfe, + 0x80, 0x8e, 0xc4, 0xd0, 0x96, 0x92, 0xf7, 0x0e, 0x4e, 0x6d, 0x8c, 0x32, + 0x1a, 0x3f, 0x14, 0xf8, 0x2d, 0x63, 0x44, 0x1d, 0x1d, 0xba, 0xc2, 0xcc, + 0xa6, 0x36, 0x8b, 0x48, 0xd5, 0xea, 0x8e, 0x87, 0xce, 0x0c, 0xfb, 0x46, + 0x0e, 0xb9, 0xa4, 0x68, 0x0c, 0x9f, 0xa6, 0xb3, 0xfd, 0x39, 0xad, 0x69, + 0x2e, 0x53, 0x48, 0x9c, 0x02, 0xac, 0x51, 0xd8, 0x19, 0x24, 0x82, 0x1e, + 0x24, 0x91, 0x52, 0x0f, 0xba, 0x53, 0x25, 0x07, 0x0e, 0x83, 0xe0, 0x09, + 0x72, 0xa2, 0x32, 0x2c, 0xee, 0x0e, 0x88, 0x5b, 0x42, 0x25, 0x3c, 0x69, + 0xb7, 0xc5, 0x9a, 0x07, 0xc0, 0x6b, 0x94, 0x28, 0x01, 0x39, 0x34, 0xd1, + 0xab, 0xf4, 0x32, 0x55, 0x82, 0x3c, 0x07, 0x2a, 0x11, 0x7a, 0x10, 0xc9, + 0x55, 0xaa, 0x84, 0x39, 0xd8, 0x3c, 0x4e, 0x09, 0x65, 0xe9, 0x03, 0x39, + 0xd0, 0xf1, 0x79, 0x70, 0x83, 0x07, 0x68, 0x72, 0x4f, 0x3f, 0x8e, 0x05, + 0xe1, 0x41, 0xe4, 0xf8, 0x1b, 0xc6, 0x13, 0xd4, 0x95, 0xed, 0xe5, 0x2f, + 0xab, 0x97, 0xaf, 0xa9, 0x6b, 0x59, 0x3c, 0x09, 0xe3, 0x3d, 0x26, 0xdb, + 0x04, 0x72, 0x19, 0x05, 0x28, 0x1f, 0x00, 0x67, 0x29, 0x2a, 0xe1, 0x7b, + 0xdb, 0x8b, 0xfb, 0x71, 0xde, 0x13, 0x5f, 0xe1, 0xb6, 0x91, 0x99, 0x90, + 0x99, 0x4a, 0xf8, 0xf0, 0x79, 0xe2, 0x2d, 0x76, 0x9b, 0x1e, 0x29, 0xed, + 0xf7, 0x8b, 0xa2, 0x1c, 0xf9, 0xec, 0xde, 0xf4, 0x35, 0x40, 0xca, 0x4c, + 0xf0, 0x30, 0x4a, 0xcb, 0x9f, 0x72, 0x0f, 0xfe, 0x06, 0xcd, 0x54, 0xb0, + 0x5d, 0x30, 0x59, 0xd6, 0x0d, 0x7e, 0x7e, 0x71, 0x45, 0xb6, 0xc3, 0xac, + 0x5b, 0x76, 0xa7, 0xc6, 0x67, 0x08, 0x2d, 0xd1, 0xa7, 0x32, 0x1a, 0x90, + 0x83, 0xc1, 0x55, 0x6a, 0xca, 0x9c, 0x8e, 0xb3, 0x7b, 0x8f, 0xc5, 0x05, + 0x4f, 0x91, 0xef, 0xee, 0xa5, 0x7d, 0xcd, 0xd6, 0xb0, 0xad, 0xc1, 0x94, + 0x98, 0x20, 0x04, 0x26, 0x54, 0xd6, 0x72, 0xb4, 0x28, 0xe4, 0xe4, 0xdf, + 0x43, 0x7e, 0xfd, 0x15, 0x17, 0x8d, 0xd9, 0xd4, 0x62, 0xa9, 0x62, 0x47, + 0x6d, 0x32, 0x26, 0x11, 0x41, 0x04, 0x6f, 0x50, 0x3c, 0xd2, 0x9a, 0xeb, + 0x76, 0x2e, 0x7e, 0xcf, 0xfe, 0xbc, 0xbd, 0xae, 0x5f, 0x23, 0x77, 0x86, + 0x9c, 0xf1, 0x99, 0xa7, 0x8c, 0xd9, 0x21, 0x58, 0x07, 0x9b, 0x3b, 0xfa, + 0xe4, 0xc1, 0x72, 0xd9, 0x01, 0xc5, 0xe5, 0xb8, 0xc0, 0xe8, 0xb9, 0x11, + 0x96, 0xcf, 0x39, 0x8c, 0x8a, 0x77, 0x3e, 0xd7, 0x8d, 0x27, 0xf1, 0x0b, + 0xfc, 0xa0, 0xa7, 0x7a, 0x61, 0x44, 0xcc, 0xfc, 0x15, 0xea, 0x0b, 0xf7, + 0x74, 0x9b, 0xa7, 0xda, 0x73, 0x9b, 0xec, 0x62, 0x43, 0x19, 0xbb, 0x16, + 0xba, 0x0d, 0x1e, 0xd6, 0xa1, 0x4c, 0xbd, 0x58, 0xac, 0xcf, 0x79, 0x9d, + 0xf2, 0xbd, 0xfa, 0x9c, 0xfd, 0x79, 0x81, 0x0c, 0x7d, 0xb8, 0xe9, 0xf9, + 0x99, 0x64, 0xee, 0xa9, 0xa4, 0xe9, 0xcc, 0x94, 0x09, 0x6c, 0x3d, 0x7e, + 0x59, 0x55, 0x80, 0x5e, 0xf1, 0xf5, 0xff, 0x5d, 0x74, 0xf2, 0xea, 0xe6, + 0xfa, 0xb1, 0x7a, 0x48, 0xeb, 0x72, 0x53, 0x18, 0x60, 0x14, 0xfb, 0x54, + 0x72, 0xab, 0x04, 0x13, 0xa7, 0x47, 0xfb, 0xbb, 0x21, 0x14, 0x3d, 0xd3, + 0x56, 0x53, 0x89, 0xa4, 0x6b, 0x02, 0x79, 0x83, 0x74, 0x85, 0x2e, 0x9c, + 0xbe, 0x03, 0xf4, 0x0b, 0xa2, 0xdc, 0xf2, 0xdb, 0x57, 0x2a, 0x25, 0x5b, + 0x63, 0x01, 0x67, 0x18, 0xc4, 0x1c, 0xa7, 0xfa, 0x99, 0xc2, 0x3d, 0x26, + 0xaf, 0x9b, 0x9f, 0x9f, 0x4c, 0x03, 0x73, 0xb9, 0xd7, 0x98, 0x22, 0x67, + 0x0e, 0x5c, 0x60, 0xc8, 0xf8, 0xc0, 0x54, 0x9b, 0xfb, 0x4c, 0xd9, 0x38, + 0xf8, 0xfc, 0x90, 0x78, 0x5b, 0xeb, 0xf0, 0xe9, 0x3f, 0xa5, 0x32, 0xc8, + 0x28, 0xc3, 0xf8, 0x6f, 0x63, 0x62, 0x59, 0x54, 0xf1, 0x81, 0xc9, 0xa1, + 0xf3, 0x97, 0xdf, 0x1f, 0xff, 0xfb, 0x75, 0xe3, 0xf2, 0xc3, 0x2d, 0x7c, + 0x6f, 0x41, 0xa1, 0xa0, 0x1d, 0xc8, 0x34, 0x44, 0xca, 0x15, 0x93, 0xde, + 0xda, 0xb9, 0x17, 0x93, 0x7f, 0x17, 0x5a, 0xfe, 0xe1, 0x3b, 0x94, 0x4c, + 0xd9, 0x54, 0x27, 0x08, 0x13, 0x9c, 0x04, 0x89, 0x65, 0x51, 0xee, 0x41, + 0xd7, 0x93, 0x1b, 0xef, 0x40, 0x6f, 0xac, 0xc5, 0x55, 0xe5, 0xad, 0x42, + 0xa2, 0x65, 0xf7, 0x7a, 0xc3, 0xae, 0x99, 0xc8, 0xd3, 0x44, 0x7d, 0x36, + 0x47, 0xaa, 0xe2, 0xd9, 0xe2, 0xa0, 0xcf, 0x34, 0xb7, 0xca, 0x0f, 0x2e, + 0x9f, 0xa5, 0x21, 0x07, 0xf6, 0x70, 0x32, 0x34, 0xf2, 0xcf, 0x19, 0x19, + 0xa2, 0x28, 0x4b, 0xea, 0x0f, 0x34, 0xbb, 0x4a, 0x27, 0x17, 0x35, 0xc7, + 0x27, 0x12, 0xda, 0xd7, 0x9d, 0xde, 0x30, 0x71, 0xda, 0x0c, 0x6a, 0xbe, + 0x72, 0x0c, 0x6b, 0x00, 0xa6, 0xb7, 0xc5, 0x3a, 0x43, 0xfb, 0x3b, 0xe4, + 0x20, 0x5a, 0x79, 0x10, 0xa9, 0x9e, 0xfc, 0x84, 0x48, 0xc6, 0x2b, 0xa0, + 0xa4, 0x5a, 0x90, 0x13, 0x9e, 0xf1, 0x5f, 0x0f, 0x97, 0x0e, 0x5e, 0x10, + 0xe2, 0x42, 0x1f, 0x22, 0x73, 0xe4, 0xe0, 0xa5, 0x2a, 0x0c, 0x7c, 0xae, + 0x95, 0x57, 0x95, 0xb1, 0x40, 0x76, 0xc7, 0x0d, 0xa2, 0xe0, 0x30, 0x62, + 0x77, 0x07, 0x07, 0x65, 0xd6, 0xef, 0x23, 0x8d, 0xac, 0x3c, 0xc9, 0x45, + 0xe5, 0x21, 0xe2, 0x1f, 0xee, 0x96, 0x60, 0xae, 0x6f, 0x51, 0x3f, 0x11, + 0x0c, 0xcd, 0x1a, 0x7b, 0x32, 0xa1, 0xda, 0xe3, 0x90, 0x05, 0x0a, 0xa9, + 0x27, 0xaf, 0xc8, 0x39, 0xbe, 0xe1, 0x7a, 0xf7, 0x94, 0x22, 0x1a, 0xd2, + 0xad, 0xc6, 0xa7, 0xb8, 0x77, 0x5b, 0x93, 0xe5, 0x4e, 0x50, 0x30, 0x8c, + 0x0e, 0x12, 0x0f, 0x34, 0xb6, 0x7b, 0xe0, 0xef, 0x3b, 0xbb, 0xb6, 0x92, + 0xe8, 0xfc, 0xd4, 0x1d, 0x67, 0x18, 0x8a, 0x50, 0x9a, 0x48, 0x81, 0x4f, + 0x2f, 0x54, 0x12, 0xbe, 0xdb, 0xd2, 0x67, 0xae, 0x1d, 0x2a, 0x5f, 0x8d, + 0x0f, 0x55, 0xbf, 0x40, 0x00, 0x00, 0x01, 0x0a }; -void vc1_get_video_info(VideoDecodeInfo *info) +void +vc1_get_video_info (VideoDecodeInfo * info) { - info->profile = GST_VAAPI_PROFILE_VC1_ADVANCED; - info->width = VC1_CLIP_WIDTH; - info->height = VC1_CLIP_HEIGHT; - info->data = vc1_clip; - info->data_size = VC1_CLIP_DATA_SIZE; + info->profile = GST_VAAPI_PROFILE_VC1_ADVANCED; + info->width = VC1_CLIP_WIDTH; + info->height = VC1_CLIP_HEIGHT; + info->data = vc1_clip; + info->data_size = VC1_CLIP_DATA_SIZE; } diff --git a/tests/test-windows.c b/tests/test-windows.c index e90f4c0e72..aaffb03bba 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -44,199 +44,195 @@ #include "image.h" static inline void -pause(void) +pause (void) { - g_print("Press any key to continue...\n"); - getchar(); + g_print ("Press any key to continue...\n"); + getchar (); } static GstVaapiSurface * -create_test_surface(GstVaapiDisplay *display, guint width, guint height) +create_test_surface (GstVaapiDisplay * display, guint width, guint height) { - GstVaapiImage *image = NULL; - GstVaapiSurface *surface; - guint i; + GstVaapiImage *image = NULL; + GstVaapiSurface *surface; + guint i; - static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - static const GstVideoFormat image_formats[] = { - GST_VIDEO_FORMAT_NV12, - GST_VIDEO_FORMAT_YV12, - GST_VIDEO_FORMAT_I420, - GST_VIDEO_FORMAT_AYUV, - GST_VIDEO_FORMAT_ARGB, - GST_VIDEO_FORMAT_BGRA, - GST_VIDEO_FORMAT_RGBA, - GST_VIDEO_FORMAT_ABGR, - GST_VIDEO_FORMAT_UNKNOWN - }; + static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + static const GstVideoFormat image_formats[] = { + GST_VIDEO_FORMAT_NV12, + GST_VIDEO_FORMAT_YV12, + GST_VIDEO_FORMAT_I420, + GST_VIDEO_FORMAT_AYUV, + GST_VIDEO_FORMAT_ARGB, + GST_VIDEO_FORMAT_BGRA, + GST_VIDEO_FORMAT_RGBA, + GST_VIDEO_FORMAT_ABGR, + GST_VIDEO_FORMAT_UNKNOWN + }; - surface = gst_vaapi_surface_new(display, chroma_type, width, height); - if (!surface) - g_error("could not create Gst/VA surface"); + surface = gst_vaapi_surface_new (display, chroma_type, width, height); + if (!surface) + g_error ("could not create Gst/VA surface"); - for (i = 0; image_formats[i] != GST_VIDEO_FORMAT_UNKNOWN; i++) { - const GstVideoFormat format = image_formats[i]; + for (i = 0; image_formats[i] != GST_VIDEO_FORMAT_UNKNOWN; i++) { + const GstVideoFormat format = image_formats[i]; - image = image_generate(display, format, width, height); - if (!image) - break; - if (image_upload(image, surface)) - break; - } + image = image_generate (display, format, width, height); if (!image) - g_error("could not create Gst/VA image"); + break; + if (image_upload (image, surface)) + break; + } + if (!image) + g_error ("could not create Gst/VA image"); - if (!gst_vaapi_surface_sync(surface)) - g_error("could not complete image upload"); + if (!gst_vaapi_surface_sync (surface)) + g_error ("could not complete image upload"); - gst_vaapi_object_unref(image); - return surface; + gst_vaapi_object_unref (image); + return surface; } int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { - GstVaapiDisplay *display; - GstVaapiWindow *window; - GstVaapiSurface *surface; - guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + GstVaapiDisplay *display; + GstVaapiWindow *window; + GstVaapiSurface *surface; + guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - static const guint width = 320; - static const guint height = 240; - static const guint win_width = 640; - static const guint win_height = 480; + static const guint width = 320; + static const guint height = 240; + static const guint win_width = 640; + static const guint win_height = 480; - gst_init(&argc, &argv); + gst_init (&argc, &argv); #if USE_DRM - display = gst_vaapi_display_drm_new(NULL); - if (!display) - g_error("could not create Gst/VA (DRM) display"); + display = gst_vaapi_display_drm_new (NULL); + if (!display) + g_error ("could not create Gst/VA (DRM) display"); - surface = create_test_surface(display, width, height); - if (!surface) - g_error("could not create Gst/VA surface"); + surface = create_test_surface (display, width, height); + if (!surface) + g_error ("could not create Gst/VA surface"); - g_print("#\n"); - g_print("# Create window with gst_vaapi_window_drm_new()\n"); - g_print("#\n"); - { - window = gst_vaapi_window_drm_new(display, win_width, win_height); - if (!window) - g_error("could not create dummy window"); + g_print ("#\n"); + g_print ("# Create window with gst_vaapi_window_drm_new()\n"); + g_print ("#\n"); + { + window = gst_vaapi_window_drm_new (display, win_width, win_height); + if (!window) + g_error ("could not create dummy window"); - gst_vaapi_window_show(window); + gst_vaapi_window_show (window); - if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) - g_error("could not render surface"); + if (!gst_vaapi_window_put_surface (window, surface, NULL, NULL, flags)) + g_error ("could not render surface"); - pause(); - gst_vaapi_window_unref(window); - } + pause (); + gst_vaapi_window_unref (window); + } - gst_vaapi_object_unref(surface); - gst_vaapi_display_unref(display); + gst_vaapi_object_unref (surface); + gst_vaapi_display_unref (display); #endif #if USE_X11 - display = gst_vaapi_display_x11_new(NULL); - if (!display) - g_error("could not create Gst/VA display"); + display = gst_vaapi_display_x11_new (NULL); + if (!display) + g_error ("could not create Gst/VA display"); - surface = create_test_surface(display, width, height); - if (!surface) - g_error("could not create Gst/VA surface"); + surface = create_test_surface (display, width, height); + if (!surface) + g_error ("could not create Gst/VA surface"); - g_print("#\n"); - g_print("# Create window with gst_vaapi_window_x11_new()\n"); - g_print("#\n"); - { - window = gst_vaapi_window_x11_new(display, win_width, win_height); - if (!window) - g_error("could not create window"); + g_print ("#\n"); + g_print ("# Create window with gst_vaapi_window_x11_new()\n"); + g_print ("#\n"); + { + window = gst_vaapi_window_x11_new (display, win_width, win_height); + if (!window) + g_error ("could not create window"); - gst_vaapi_window_show(window); + gst_vaapi_window_show (window); - if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) - g_error("could not render surface"); + if (!gst_vaapi_window_put_surface (window, surface, NULL, NULL, flags)) + g_error ("could not render surface"); - pause(); - gst_vaapi_window_unref(window); - } + pause (); + gst_vaapi_window_unref (window); + } - g_print("#\n"); - g_print("# Create window with gst_vaapi_window_x11_new_with_xid()\n"); - g_print("#\n"); - { - Display * const dpy = gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)); - Window rootwin, win; - int screen; - unsigned long white_pixel, black_pixel; + g_print ("#\n"); + g_print ("# Create window with gst_vaapi_window_x11_new_with_xid()\n"); + g_print ("#\n"); + { + Display *const dpy = + gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display)); + Window rootwin, win; + int screen; + unsigned long white_pixel, black_pixel; - screen = DefaultScreen(dpy); - rootwin = RootWindow(dpy, screen); - white_pixel = WhitePixel(dpy, screen); - black_pixel = BlackPixel(dpy, screen); + screen = DefaultScreen (dpy); + rootwin = RootWindow (dpy, screen); + white_pixel = WhitePixel (dpy, screen); + black_pixel = BlackPixel (dpy, screen); - win = XCreateSimpleWindow( - dpy, - rootwin, - 0, 0, win_width, win_height, - 0, black_pixel, - white_pixel - ); - if (!win) - g_error("could not create X window"); + win = XCreateSimpleWindow (dpy, + rootwin, 0, 0, win_width, win_height, 0, black_pixel, white_pixel); + if (!win) + g_error ("could not create X window"); - window = gst_vaapi_window_x11_new_with_xid(display, win); - if (!window) - g_error("could not create window"); + window = gst_vaapi_window_x11_new_with_xid (display, win); + if (!window) + g_error ("could not create window"); - gst_vaapi_window_show(window); + gst_vaapi_window_show (window); - if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) - g_error("could not render surface"); + if (!gst_vaapi_window_put_surface (window, surface, NULL, NULL, flags)) + g_error ("could not render surface"); - pause(); - gst_vaapi_window_unref(window); - XUnmapWindow(dpy, win); - XDestroyWindow(dpy, win); - } + pause (); + gst_vaapi_window_unref (window); + XUnmapWindow (dpy, win); + XDestroyWindow (dpy, win); + } - gst_vaapi_object_unref(surface); - gst_vaapi_display_unref(display); + gst_vaapi_object_unref (surface); + gst_vaapi_display_unref (display); #endif #if USE_WAYLAND - display = gst_vaapi_display_wayland_new(NULL); - if (!display) - g_error("could not create Gst/VA (Wayland) display"); + display = gst_vaapi_display_wayland_new (NULL); + if (!display) + g_error ("could not create Gst/VA (Wayland) display"); - surface = create_test_surface(display, width, height); - if (!surface) - g_error("could not create Gst/VA surface"); + surface = create_test_surface (display, width, height); + if (!surface) + g_error ("could not create Gst/VA surface"); - g_print("#\n"); - g_print("# Create window with gst_vaapi_window_wayland_new()\n"); - g_print("#\n"); - { - window = gst_vaapi_window_wayland_new(display, win_width, win_height); - if (!window) - g_error("could not create window"); + g_print ("#\n"); + g_print ("# Create window with gst_vaapi_window_wayland_new()\n"); + g_print ("#\n"); + { + window = gst_vaapi_window_wayland_new (display, win_width, win_height); + if (!window) + g_error ("could not create window"); - gst_vaapi_window_show(window); + gst_vaapi_window_show (window); - if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) - g_error("could not render surface"); + if (!gst_vaapi_window_put_surface (window, surface, NULL, NULL, flags)) + g_error ("could not render surface"); - pause(); - gst_vaapi_window_unref(window); - } + pause (); + gst_vaapi_window_unref (window); + } - gst_vaapi_object_unref(surface); - gst_vaapi_display_unref(display); + gst_vaapi_object_unref (surface); + gst_vaapi_display_unref (display); #endif - gst_deinit(); - return 0; + gst_deinit (); + return 0; } From 3fcfd40fb5817a6f0c3cb52aff7202baad1f5b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Apr 2016 12:53:06 +0200 Subject: [PATCH 2371/3781] tests: display: guard possible unused variables https://bugzilla.gnome.org/show_bug.cgi?id=765702 --- tests/test-display.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/test-display.c b/tests/test-display.c index 4a995b25f6..be9c24be21 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -268,8 +268,14 @@ dump_info (GstVaapiDisplay * display) int main (int argc, char *argv[]) { - GstVaapiDisplay *display, *display2; - guint width, height, par_n, par_d; + GstVaapiDisplay *display; +#if USE_X11 + GstVaapiDisplay *display2; +#endif +#if USE_X11 || USE_WAYLAND + guint width, height; + guint par_n, par_d; +#endif gst_init (&argc, &argv); From 4f30d28ff03569e9dd889e05bf0ffc2181dafaf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Apr 2016 13:11:48 +0200 Subject: [PATCH 2372/3781] plugin: fix macro processor check Instead of #ifdef it should be used #if becasuse USE_GST_GL_HELPERS is always defined in config.h, but it would be 0 or 1 depending on the configure output. https://bugzilla.gnome.org/show_bug.cgi?id=765702 --- gst/vaapi/gstvaapipluginbase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 0694bf74c7..2e538929e5 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -31,7 +31,7 @@ #include #include -#ifdef USE_GST_GL_HELPERS +#if USE_GST_GL_HELPERS # include #endif From 6a6ea750164b2c8acdd575393dc868258cbb8420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 6 May 2016 12:16:26 +0200 Subject: [PATCH 2373/3781] build: update git.mk --- git.mk | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/git.mk b/git.mk index 9d4bf2511e..643c2ca9ae 100644 --- a/git.mk +++ b/git.mk @@ -171,10 +171,24 @@ $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk $(DOC_MODULE)-decl.txt \ tmpl/$(DOC_MODULE)-unused.sgml \ "tmpl/*.bak" \ + $(REPORT_FILES) \ + $(DOC_MODULE).pdf \ xml html \ ; do echo "/$$x"; done; \ FLAVOR=$$(cd $(top_srcdir); $(AUTOCONF) --trace 'GTK_DOC_CHECK:$$2' ./configure.ac); \ case $$FLAVOR in *no-tmpl*) echo /tmpl;; esac; \ + if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-types"; then \ + echo "/$(DOC_MODULE).types"; \ + fi; \ + if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-sections"; then \ + echo "/$(DOC_MODULE)-sections.txt"; \ + fi; \ + if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ + for x in \ + $(SETUP_FILES) \ + $(DOC_MODULE).types \ + ; do echo "/$$x"; done; \ + fi; \ fi; \ if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \ for lc in $(DOC_LINGUAS); do \ @@ -229,6 +243,7 @@ $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk po/POTFILES \ po/Rules-quot \ po/stamp-it \ + po/stamp-po \ po/.intltool-merge-cache \ "po/*.gmo" \ "po/*.header" \ @@ -260,7 +275,7 @@ $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk if test "x$(am__dirstamp)" = x; then :; else \ echo "$(am__dirstamp)"; \ fi; \ - if test "x$(LTCOMPILE)" = x -a "x$(LTCXXCOMPILE)" = x -a "x$(GTKDOC_RUN)" = x; then :; else \ + if test "x$(findstring libtool,$(LTCOMPILE))" = x -a "x$(findstring libtool,$(LTCXXCOMPILE))" = x -a "x$(GTKDOC_RUN)" = x; then :; else \ for x in \ "*.lo" \ ".libs" "_libs" \ From 240fc0f726f8be5da29554332d0e50a78d4be238 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Mon, 28 Sep 2015 08:49:39 +0100 Subject: [PATCH 2374/3781] vaapibufferpool: do not create texture upload meta if dmabuf https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapivideobufferpool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 8e45bbc4c0..cc80df6532 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -199,7 +199,8 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, gst_buffer_pool_config_set_video_alignment (config, &align); } - priv->has_texture_upload_meta = gst_buffer_pool_config_has_option (config, + priv->has_texture_upload_meta = !priv->use_dmabuf_memory + && gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); return From ebf0d94534cce5203be4cddf53dbfafd66e0d758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Apr 2016 21:20:32 +0200 Subject: [PATCH 2375/3781] vaapipostproc: no GLTextureUpload in sinkpad As the vaapipostproc does not process frames with the VideoGLTextureUpload meta, the feature is removed from the sink pad template. https://bugzilla.gnome.org/show_bug.cgi?id=765931 --- gst/vaapi/gstvaapipostproc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 4757d8325c..87c3298bca 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -55,9 +55,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapipostproc); static const char gst_vaapipostproc_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES "; " -#if (USE_GLX || USE_EGL) - GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS "; " -#endif GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " GST_CAPS_INTERLACED_MODES; /* *INDENT-ON* */ From 54a2d9fb77eeadfc8669f7cdf179b739d6e7a7af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 25 Apr 2016 13:45:04 +0200 Subject: [PATCH 2376/3781] vaapipostproc: log the caps transformation https://bugzilla.gnome.org/show_bug.cgi?id=758548 --- gst/vaapi/gstvaapipostproc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 87c3298bca..8672f8a24e 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1146,12 +1146,19 @@ gst_vaapipostproc_transform_caps (GstBaseTransform * trans, { GstCaps *out_caps; + GST_DEBUG_OBJECT (trans, + "Transforming caps %" GST_PTR_FORMAT " in direction %s", caps, + (direction == GST_PAD_SINK) ? "sink" : "src"); + caps = gst_vaapipostproc_transform_caps_impl (trans, direction, caps); if (caps && filter) { out_caps = gst_caps_intersect_full (caps, filter, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (caps); - return out_caps; + caps = out_caps; } + + GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, caps); + return caps; } From 606d166b566529188b189a5c58bcaad124868a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 5 May 2016 12:07:59 +0200 Subject: [PATCH 2377/3781] vaapipostproc: set early properties restrictions When running transform_caps() vmethod, returning the srcpad caps, the caps are early restricted to the element properties set: width, height, format and force keep aspect. A new file was added gstvaapipostprocutil.{c,h} where the utilities functions are stored. https://bugzilla.gnome.org/show_bug.cgi?id=758548 --- gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapipostproc.c | 7 +- gst/vaapi/gstvaapipostprocutil.c | 126 +++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipostprocutil.h | 39 ++++++++++ 4 files changed, 169 insertions(+), 5 deletions(-) create mode 100644 gst/vaapi/gstvaapipostprocutil.c create mode 100644 gst/vaapi/gstvaapipostprocutil.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 21eef47a1b..3e54a41d18 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -46,6 +46,7 @@ libgstvaapi_source_c = \ gstvaapipluginbase.c \ gstvaapipluginutil.c \ gstvaapipostproc.c \ + gstvaapipostprocutil.c \ gstvaapisink.c \ gstvaapivideobuffer.c \ gstvaapivideocontext.c \ @@ -62,6 +63,7 @@ libgstvaapi_source_h = \ gstvaapipluginbase.h \ gstvaapipluginutil.h \ gstvaapipostproc.h \ + gstvaapipostprocutil.h \ gstvaapisink.h \ gstvaapivideobuffer.h \ gstvaapivideocontext.h \ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 8672f8a24e..6e24a872be 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -39,6 +39,7 @@ #include #include "gstvaapipostproc.h" +#include "gstvaapipostprocutil.h" #include "gstvaapipluginutil.h" #include "gstvaapivideobuffer.h" #include "gstvaapivideobufferpool.h" @@ -118,10 +119,6 @@ enum PROP_SKIN_TONE_ENHANCEMENT, }; -#define DEFAULT_FORMAT GST_VIDEO_FORMAT_ENCODED -#define DEFAULT_DEINTERLACE_MODE GST_VAAPI_DEINTERLACE_MODE_AUTO -#define DEFAULT_DEINTERLACE_METHOD GST_VAAPI_DEINTERLACE_METHOD_BOB - #define GST_VAAPI_TYPE_DEINTERLACE_MODE \ gst_vaapi_deinterlace_mode_get_type() @@ -1076,7 +1073,7 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, if (!gst_caps_is_fixed (caps)) { if (!ensure_allowed_srcpad_caps (postproc)) return NULL; - return gst_caps_ref (postproc->allowed_srcpad_caps); + return gst_vaapipostproc_transform_srccaps (postproc); } /* Generate the expected src pad caps, from the current fixated diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c new file mode 100644 index 0000000000..b2a64d9f3d --- /dev/null +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -0,0 +1,126 @@ +/* + * gstvaapipostprocutil.h - VA-API video post processing utilities + * + * Copyright (C) 2016 Intel Corporation + * Author: Gwenole Beauchesne + * Author: Victor Jaquez + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "gstvaapipostprocutil.h" +#include "gstvaapipluginutil.h" + +/* if format property is set */ +static void +_transform_format (GstVaapiPostproc * postproc, GstCapsFeatures * features, + GstStructure * structure) +{ + GValue value = G_VALUE_INIT; + + if (postproc->format == DEFAULT_FORMAT) + return; + + if (!gst_caps_features_is_equal (features, + GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY) + && !gst_caps_features_contains (features, + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE)) + return; + + if (!gst_vaapi_value_set_format (&value, postproc->format)) + return; + + gst_structure_set_value (structure, "format", &value); +} + +static void +_set_int (GValue * value, gint val) +{ + g_value_init (value, G_TYPE_INT); + g_value_set_int (value, val); +} + +static void +_set_int_range (GValue * value) +{ + g_value_init (value, GST_TYPE_INT_RANGE); + gst_value_set_int_range (value, 1, G_MAXINT); +} + +static void +_transform_frame_size (GstVaapiPostproc * postproc, GstStructure * structure) +{ + GValue width = G_VALUE_INIT; + GValue height = G_VALUE_INIT; + + if (postproc->width && postproc->height) { + _set_int (&width, postproc->width); + _set_int (&height, postproc->height); + } else if (postproc->width) { + _set_int (&width, postproc->width); + _set_int_range (&height); + } else if (postproc->height) { + _set_int_range (&width); + _set_int (&height, postproc->height); + } else { + _set_int_range (&width); + _set_int_range (&height); + } + + gst_structure_set_value (structure, "width", &width); + gst_structure_set_value (structure, "height", &height); +} + +/** + * gst_vaapipostproc_transform_srccaps: + * @postproc: a #GstVaapiPostproc instance + * + * Early apply transformation of the src pad caps according to the set + * properties. + * + * Returns: A new allocated #GstCaps + **/ +GstCaps * +gst_vaapipostproc_transform_srccaps (GstVaapiPostproc * postproc) +{ + GstCaps *out_caps; + GstStructure *structure; + GstCapsFeatures *features; + gint i, n; + + out_caps = gst_caps_new_empty (); + n = gst_caps_get_size (postproc->allowed_srcpad_caps); + + for (i = 0; i < n; i++) { + structure = gst_caps_get_structure (postproc->allowed_srcpad_caps, i); + features = gst_caps_get_features (postproc->allowed_srcpad_caps, i); + + /* make copy */ + structure = gst_structure_copy (structure); + + if (postproc->keep_aspect) + gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, + 1, NULL); + + _transform_format (postproc, features, structure); + _transform_frame_size (postproc, structure); + + gst_caps_append_structure_full (out_caps, structure, + gst_caps_features_copy (features)); + } + + return out_caps; +} diff --git a/gst/vaapi/gstvaapipostprocutil.h b/gst/vaapi/gstvaapipostprocutil.h new file mode 100644 index 0000000000..70f6d97cea --- /dev/null +++ b/gst/vaapi/gstvaapipostprocutil.h @@ -0,0 +1,39 @@ +/* + * gstvaapipostprocutil.h - VA-API video post processing utilities + * + * Copyright (C) 2016 Intel Corporation + * Author: Gwenole Beauchesne + * Author: Victor Jaquez + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef GST_VAAPIPOSTPROCUTIL_H +#define GST_VAAPIPOSTPROCUTIL_H + +#include "gstvaapipostproc.h" + +G_BEGIN_DECLS + +#define DEFAULT_FORMAT GST_VIDEO_FORMAT_ENCODED +#define DEFAULT_DEINTERLACE_MODE GST_VAAPI_DEINTERLACE_MODE_AUTO +#define DEFAULT_DEINTERLACE_METHOD GST_VAAPI_DEINTERLACE_METHOD_BOB + +GstCaps *gst_vaapipostproc_transform_srccaps (GstVaapiPostproc * postproc); + +G_END_DECLS + +#endif /* GST_VAAPIPOSTPROCUTIL_H */ From 8de7faafdcbbcb1211d427a0d7de330928191cc0 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Thu, 5 May 2016 13:46:11 +0200 Subject: [PATCH 2378/3781] vaapipostproc: add fixate_caps() vmethod Instead of fixating the srcpad caps in transform_caps() vmethod, this patch implements the fixate_caps() vmethod and moves code around. https://bugzilla.gnome.org/show_bug.cgi?id=758548 --- gst/vaapi/gstvaapipostproc.c | 92 ++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 31 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6e24a872be..60927de5d1 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1054,12 +1054,6 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, GstPadDirection direction, GstCaps * caps) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - GstVideoInfo vi; - GstVideoFormat out_format; - GstCaps *out_caps; - GstVaapiCapsFeature feature; - const gchar *feature_str; - guint width, height; /* Generate the sink pad caps, that could be fixated afterwards */ if (direction == GST_PAD_SRC) { @@ -1068,17 +1062,49 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, return gst_caps_ref (postproc->allowed_sinkpad_caps); } - /* Generate complete set of src pad caps if non-fixated sink pad - caps are provided */ - if (!gst_caps_is_fixed (caps)) { - if (!ensure_allowed_srcpad_caps (postproc)) - return NULL; - return gst_vaapipostproc_transform_srccaps (postproc); + /* Generate complete set of src pad caps */ + if (!ensure_allowed_srcpad_caps (postproc)) + return NULL; + return gst_vaapipostproc_transform_srccaps (postproc); +} + +static GstCaps * +gst_vaapipostproc_transform_caps (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps, GstCaps * filter) +{ + GstCaps *out_caps; + + GST_DEBUG_OBJECT (trans, + "Transforming caps %" GST_PTR_FORMAT " in direction %s", caps, + (direction == GST_PAD_SINK) ? "sink" : "src"); + + caps = gst_vaapipostproc_transform_caps_impl (trans, direction, caps); + if (caps && filter) { + out_caps = gst_caps_intersect_full (caps, filter, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (caps); + caps = out_caps; } - /* Generate the expected src pad caps, from the current fixated - sink pad caps */ - if (!gst_video_info_from_caps (&vi, caps)) + GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, caps); + + return caps; +} + +static GstCaps * +gst_vaapipostproc_fixate_srccaps (GstVaapiPostproc * postproc, + GstCaps * sinkcaps) +{ + GstVideoInfo vi; + GstVideoFormat out_format; + GstCaps *out_caps; + GstVaapiCapsFeature feature; + const gchar *feature_str; + guint width, height; + GstPad *srcpad; + + /* Generate the expected src pad caps, from the current fixated sink + pad caps */ + if (!gst_video_info_from_caps (&vi, sinkcaps)) return NULL; // Set double framerate in interlaced mode @@ -1107,14 +1133,13 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, if (postproc->format != DEFAULT_FORMAT) out_format = postproc->format; - feature = - gst_vaapi_find_preferred_caps_feature (GST_BASE_TRANSFORM_SRC_PAD (trans), + srcpad = GST_BASE_TRANSFORM_SRC_PAD (postproc); + feature = gst_vaapi_find_preferred_caps_feature (srcpad, postproc->allowed_srcpad_caps, (out_format == GST_VIDEO_FORMAT_UNKNOWN) ? &out_format : NULL); if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) - return gst_pad_peer_query_caps (GST_BASE_TRANSFORM_SRC_PAD (trans), - postproc->allowed_srcpad_caps); + return NULL; gst_video_info_change_format (&vi, out_format, width, height); out_caps = gst_video_info_to_caps (&vi); @@ -1138,25 +1163,29 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, } static GstCaps * -gst_vaapipostproc_transform_caps (GstBaseTransform * trans, - GstPadDirection direction, GstCaps * caps, GstCaps * filter) +gst_vaapipostproc_fixate_caps (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps, GstCaps * othercaps) { - GstCaps *out_caps; + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + GstCaps *outcaps; - GST_DEBUG_OBJECT (trans, - "Transforming caps %" GST_PTR_FORMAT " in direction %s", caps, + GST_DEBUG_OBJECT (trans, "trying to fixate othercaps %" GST_PTR_FORMAT + " based on caps %" GST_PTR_FORMAT " in direction %s", othercaps, caps, (direction == GST_PAD_SINK) ? "sink" : "src"); - caps = gst_vaapipostproc_transform_caps_impl (trans, direction, caps); - if (caps && filter) { - out_caps = gst_caps_intersect_full (caps, filter, GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (caps); - caps = out_caps; + if (direction == GST_PAD_SRC) { + /* @TODO: we can do better */ + othercaps = gst_caps_fixate (othercaps); + goto done; } - GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, caps); + if ((outcaps = gst_vaapipostproc_fixate_srccaps (postproc, caps))) + gst_caps_replace (&othercaps, outcaps); - return caps; +done: + GST_DEBUG_OBJECT (trans, "fixated othercaps to %" GST_PTR_FORMAT, othercaps); + + return othercaps; } static gboolean @@ -1517,6 +1546,7 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) object_class->get_property = gst_vaapipostproc_get_property; trans_class->start = gst_vaapipostproc_start; trans_class->stop = gst_vaapipostproc_stop; + trans_class->fixate_caps = gst_vaapipostproc_fixate_caps; trans_class->transform_caps = gst_vaapipostproc_transform_caps; trans_class->transform_size = gst_vaapipostproc_transform_size; trans_class->transform = gst_vaapipostproc_transform; From bde3b072da7f76a7b7f9c6d64336b299e5646c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 5 May 2016 15:16:02 +0200 Subject: [PATCH 2379/3781] vaapipostproc: use othercaps for preferred caps Instead of the allowed_srcpad_caps variable, this patch uses the othercaps from fixate_caps() vmethod to find the preferred caps feature and color format. https://bugzilla.gnome.org/show_bug.cgi?id=758548 --- gst/vaapi/gstvaapipostproc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 60927de5d1..bdb650df19 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1092,7 +1092,7 @@ gst_vaapipostproc_transform_caps (GstBaseTransform * trans, static GstCaps * gst_vaapipostproc_fixate_srccaps (GstVaapiPostproc * postproc, - GstCaps * sinkcaps) + GstCaps * sinkcaps, GstCaps * srccaps) { GstVideoInfo vi; GstVideoFormat out_format; @@ -1134,8 +1134,7 @@ gst_vaapipostproc_fixate_srccaps (GstVaapiPostproc * postproc, out_format = postproc->format; srcpad = GST_BASE_TRANSFORM_SRC_PAD (postproc); - feature = gst_vaapi_find_preferred_caps_feature (srcpad, - postproc->allowed_srcpad_caps, + feature = gst_vaapi_find_preferred_caps_feature (srcpad, srccaps, (out_format == GST_VIDEO_FORMAT_UNKNOWN) ? &out_format : NULL); if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) @@ -1179,7 +1178,7 @@ gst_vaapipostproc_fixate_caps (GstBaseTransform * trans, goto done; } - if ((outcaps = gst_vaapipostproc_fixate_srccaps (postproc, caps))) + if ((outcaps = gst_vaapipostproc_fixate_srccaps (postproc, caps, othercaps))) gst_caps_replace (&othercaps, outcaps); done: From d9b09b623ef04dbe5a171aa0bbfab12683fd93eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 5 May 2016 15:19:02 +0200 Subject: [PATCH 2380/3781] vaapipostproc: simplify code Change a convoluted snippet to find the preferred color format in the peer caps. https://bugzilla.gnome.org/show_bug.cgi?id=758548 --- gst/vaapi/gstvaapipostproc.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index bdb650df19..819b423fca 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1123,19 +1123,12 @@ gst_vaapipostproc_fixate_srccaps (GstVaapiPostproc * postproc, find_best_size (postproc, &vi, &width, &height); // Update format from user-specified parameters - /* XXX: this is a workaround until auto-plugging is fixed when - * format=ENCODED + memory:VASurface caps feature are provided. - * use the downstream negotiated video format as the output format - * if the user didn't explicitly ask for colorspace conversion. - * Use a filter caps which contain all raw video formats, (excluding - * GST_VIDEO_FORMAT_ENCODED) */ - out_format = GST_VIDEO_FORMAT_UNKNOWN; - if (postproc->format != DEFAULT_FORMAT) - out_format = postproc->format; - srcpad = GST_BASE_TRANSFORM_SRC_PAD (postproc); feature = gst_vaapi_find_preferred_caps_feature (srcpad, srccaps, - (out_format == GST_VIDEO_FORMAT_UNKNOWN) ? &out_format : NULL); + &out_format); + + if (postproc->format != DEFAULT_FORMAT) + out_format = postproc->format; if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) return NULL; From 1901e2231be53c23936d9a236c34c0812a0cfbdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 5 May 2016 15:32:36 +0200 Subject: [PATCH 2381/3781] vaapipostproc: move gst_vaapipostproc_fixate_srccaps() Move gst_vaapipostproc_fixate_srccaps() to gstvaapiposptprocutil. No functional changes. https://bugzilla.gnome.org/show_bug.cgi?id=758548 --- gst/vaapi/gstvaapipostproc.c | 112 ---------------------------- gst/vaapi/gstvaapipostprocutil.c | 123 +++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipostprocutil.h | 6 ++ 3 files changed, 129 insertions(+), 112 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 819b423fca..a29b2a626b 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -830,25 +830,6 @@ error_invalid_buffer: } } -static gboolean -is_deinterlace_enabled (GstVaapiPostproc * postproc, GstVideoInfo * vip) -{ - gboolean deinterlace; - - switch (postproc->deinterlace_mode) { - case GST_VAAPI_DEINTERLACE_MODE_AUTO: - deinterlace = GST_VIDEO_INFO_IS_INTERLACED (vip); - break; - case GST_VAAPI_DEINTERLACE_MODE_INTERLACED: - deinterlace = TRUE; - break; - default: - deinterlace = FALSE; - break; - } - return deinterlace; -} - static gboolean video_info_changed (GstVideoInfo * old_vip, GstVideoInfo * new_vip) { @@ -1020,35 +1001,6 @@ ensure_allowed_srcpad_caps (GstVaapiPostproc * postproc) return postproc->allowed_srcpad_caps != NULL; } -static void -find_best_size (GstVaapiPostproc * postproc, GstVideoInfo * vip, - guint * width_ptr, guint * height_ptr) -{ - guint width, height; - - width = GST_VIDEO_INFO_WIDTH (vip); - height = GST_VIDEO_INFO_HEIGHT (vip); - if (postproc->width && postproc->height) { - width = postproc->width; - height = postproc->height; - } else if (postproc->keep_aspect) { - const gdouble ratio = (gdouble) width / height; - if (postproc->width) { - width = postproc->width; - height = postproc->width / ratio; - } else if (postproc->height) { - height = postproc->height; - width = postproc->height * ratio; - } - } else if (postproc->width) - width = postproc->width; - else if (postproc->height) - height = postproc->height; - - *width_ptr = width; - *height_ptr = height; -} - static GstCaps * gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, GstPadDirection direction, GstCaps * caps) @@ -1090,70 +1042,6 @@ gst_vaapipostproc_transform_caps (GstBaseTransform * trans, return caps; } -static GstCaps * -gst_vaapipostproc_fixate_srccaps (GstVaapiPostproc * postproc, - GstCaps * sinkcaps, GstCaps * srccaps) -{ - GstVideoInfo vi; - GstVideoFormat out_format; - GstCaps *out_caps; - GstVaapiCapsFeature feature; - const gchar *feature_str; - guint width, height; - GstPad *srcpad; - - /* Generate the expected src pad caps, from the current fixated sink - pad caps */ - if (!gst_video_info_from_caps (&vi, sinkcaps)) - return NULL; - - // Set double framerate in interlaced mode - if (is_deinterlace_enabled (postproc, &vi)) { - gint fps_n = GST_VIDEO_INFO_FPS_N (&vi); - gint fps_d = GST_VIDEO_INFO_FPS_D (&vi); - if (!gst_util_fraction_multiply (fps_n, fps_d, 2, 1, &fps_n, &fps_d)) - return NULL; - GST_VIDEO_INFO_FPS_N (&vi) = fps_n; - GST_VIDEO_INFO_FPS_D (&vi) = fps_d; - } - // Signal the other pad that we only generate progressive frames - GST_VIDEO_INFO_INTERLACE_MODE (&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; - - // Update size from user-specified parameters - find_best_size (postproc, &vi, &width, &height); - - // Update format from user-specified parameters - srcpad = GST_BASE_TRANSFORM_SRC_PAD (postproc); - feature = gst_vaapi_find_preferred_caps_feature (srcpad, srccaps, - &out_format); - - if (postproc->format != DEFAULT_FORMAT) - out_format = postproc->format; - - if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) - return NULL; - - gst_video_info_change_format (&vi, out_format, width, height); - out_caps = gst_video_info_to_caps (&vi); - if (!out_caps) - return NULL; - - if (feature) { - feature_str = gst_vaapi_caps_feature_to_string (feature); - if (feature_str) - gst_caps_set_features (out_caps, 0, - gst_caps_features_new (feature_str, NULL)); - } - - /* we don't need to do format conversion if GL_TEXTURE_UPLOAD_META - * is negotiated */ - if (feature != GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META && - postproc->format != out_format) { - postproc->format = out_format; - } - return out_caps; -} - static GstCaps * gst_vaapipostproc_fixate_caps (GstBaseTransform * trans, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index b2a64d9f3d..935880035e 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -124,3 +124,126 @@ gst_vaapipostproc_transform_srccaps (GstVaapiPostproc * postproc) return out_caps; } + +gboolean +is_deinterlace_enabled (GstVaapiPostproc * postproc, GstVideoInfo * vip) +{ + gboolean deinterlace; + + switch (postproc->deinterlace_mode) { + case GST_VAAPI_DEINTERLACE_MODE_AUTO: + deinterlace = GST_VIDEO_INFO_IS_INTERLACED (vip); + break; + case GST_VAAPI_DEINTERLACE_MODE_INTERLACED: + deinterlace = TRUE; + break; + default: + deinterlace = FALSE; + break; + } + return deinterlace; +} + +static void +find_best_size (GstVaapiPostproc * postproc, GstVideoInfo * vip, + guint * width_ptr, guint * height_ptr) +{ + guint width, height; + + width = GST_VIDEO_INFO_WIDTH (vip); + height = GST_VIDEO_INFO_HEIGHT (vip); + if (postproc->width && postproc->height) { + width = postproc->width; + height = postproc->height; + } else if (postproc->keep_aspect) { + const gdouble ratio = (gdouble) width / height; + if (postproc->width) { + width = postproc->width; + height = postproc->width / ratio; + } else if (postproc->height) { + height = postproc->height; + width = postproc->height * ratio; + } + } else if (postproc->width) + width = postproc->width; + else if (postproc->height) + height = postproc->height; + + *width_ptr = width; + *height_ptr = height; +} + +/** + * gst_vaapipostproc_fixate_srccaps: + * @postproc: a #GstVaapiPostproc instance + * @sinkcaps: fixed #GstCaps from sink pad + * @srccaps: #GstCaps from src pad to fixate + * + * Given @srccaps and @sinkcaps returns a new allocated #GstCaps with + * the fixated caps for the src pad. + * + * Returns: A new allocated #GstCaps + **/ +GstCaps * +gst_vaapipostproc_fixate_srccaps (GstVaapiPostproc * postproc, + GstCaps * sinkcaps, GstCaps * srccaps) +{ + GstVideoInfo vi; + GstVideoFormat out_format; + GstCaps *out_caps; + GstVaapiCapsFeature feature; + const gchar *feature_str; + guint width, height; + GstPad *srcpad; + + /* Generate the expected src pad caps, from the current fixated sink + pad caps */ + if (!gst_video_info_from_caps (&vi, sinkcaps)) + return NULL; + + // Set double framerate in interlaced mode + if (is_deinterlace_enabled (postproc, &vi)) { + gint fps_n = GST_VIDEO_INFO_FPS_N (&vi); + gint fps_d = GST_VIDEO_INFO_FPS_D (&vi); + if (!gst_util_fraction_multiply (fps_n, fps_d, 2, 1, &fps_n, &fps_d)) + return NULL; + GST_VIDEO_INFO_FPS_N (&vi) = fps_n; + GST_VIDEO_INFO_FPS_D (&vi) = fps_d; + } + // Signal the other pad that we only generate progressive frames + GST_VIDEO_INFO_INTERLACE_MODE (&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; + + // Update size from user-specified parameters + find_best_size (postproc, &vi, &width, &height); + + // Update format from user-specified parameters + srcpad = GST_BASE_TRANSFORM_SRC_PAD (postproc); + feature = gst_vaapi_find_preferred_caps_feature (srcpad, srccaps, + &out_format); + + if (postproc->format != DEFAULT_FORMAT) + out_format = postproc->format; + + if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) + return NULL; + + gst_video_info_change_format (&vi, out_format, width, height); + out_caps = gst_video_info_to_caps (&vi); + if (!out_caps) + return NULL; + + if (feature) { + feature_str = gst_vaapi_caps_feature_to_string (feature); + if (feature_str) + gst_caps_set_features (out_caps, 0, + gst_caps_features_new (feature_str, NULL)); + } + + /* we don't need to do format conversion if GL_TEXTURE_UPLOAD_META + * is negotiated */ + if (feature != GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META && + postproc->format != out_format) { + postproc->format = out_format; + } + return out_caps; +} diff --git a/gst/vaapi/gstvaapipostprocutil.h b/gst/vaapi/gstvaapipostprocutil.h index 70f6d97cea..db5d303286 100644 --- a/gst/vaapi/gstvaapipostprocutil.h +++ b/gst/vaapi/gstvaapipostprocutil.h @@ -34,6 +34,12 @@ G_BEGIN_DECLS GstCaps *gst_vaapipostproc_transform_srccaps (GstVaapiPostproc * postproc); +GstCaps *gst_vaapipostproc_fixate_srccaps (GstVaapiPostproc * postproc, + GstCaps * sinkcaps, GstCaps * srccaps); + +gboolean is_deinterlace_enabled (GstVaapiPostproc * postproc, + GstVideoInfo * vip); + G_END_DECLS #endif /* GST_VAAPIPOSTPROCUTIL_H */ From 4d1b11ed03759ef702c675cbacdb5ea543daa305 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Fri, 6 May 2016 10:50:10 +0200 Subject: [PATCH 2382/3781] vaapipostproc: don't use GstVideoInfo for src caps Instead of using gst_video_info_to_caps () to generated the fixed src caps, this patch enables the first step for caps negotiation with a possible following caps filter. _get_preferred_caps() will traverse the possible src caps looking for the one wit the preferred feature and the preferred color format. Then the color format, the frame size and the frame rate are fixated. https://bugzilla.gnome.org/show_bug.cgi?id=758548 --- gst/vaapi/gstvaapipostprocutil.c | 182 ++++++++++++++++++++++--------- 1 file changed, 128 insertions(+), 54 deletions(-) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 935880035e..ff114a15cc 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -24,6 +24,8 @@ #include "gstvaapipostprocutil.h" #include "gstvaapipluginutil.h" +#define GST_CAT_DEFAULT (GST_VAAPI_PLUGIN_BASE (postproc)->debug_category) + /* if format property is set */ static void _transform_format (GstVaapiPostproc * postproc, GstCapsFeatures * features, @@ -173,6 +175,131 @@ find_best_size (GstVaapiPostproc * postproc, GstVideoInfo * vip, *height_ptr = height; } +static gboolean +_fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, + GstStructure * outs) +{ + guint width, height, par_n, par_d; + + par_n = GST_VIDEO_INFO_PAR_N (vinfo); + par_d = GST_VIDEO_INFO_PAR_D (vinfo); + find_best_size (postproc, vinfo, &width, &height); + gst_structure_set (outs, "width", G_TYPE_INT, width, "height", G_TYPE_INT, + height, "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL); + return TRUE; +} + +static gboolean +_fixate_frame_rate (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, + GstStructure * outs) +{ + gint fps_n, fps_d; + + fps_n = GST_VIDEO_INFO_FPS_N (vinfo); + fps_d = GST_VIDEO_INFO_FPS_D (vinfo); + if (is_deinterlace_enabled (postproc, vinfo)) { + if (!gst_util_fraction_multiply (fps_n, fps_d, 2, 1, &fps_n, &fps_d)) + goto overflow_error; + } + gst_structure_set (outs, "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); + return TRUE; + + /* ERRORS */ +overflow_error: + { + GST_ELEMENT_ERROR (postproc, CORE, NEGOTIATION, (NULL), + ("Error calculating the output framerate - integer overflow")); + return FALSE; + } +} + +static gboolean +_set_preferred_format (GstStructure * outs, GstVideoFormat format) +{ + GValue value = G_VALUE_INIT; + + if (format == GST_VIDEO_FORMAT_UNKNOWN || format == GST_VIDEO_FORMAT_ENCODED) + return FALSE; + + if (gst_vaapi_value_set_format (&value, format)) { + gst_structure_set_value (outs, "format", &value); + return TRUE; + } + return FALSE; +} + +static GstCaps * +_get_preferred_caps (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, + GstCaps * srccaps) +{ + GstPad *srcpad; + GstVideoFormat format; + GstVaapiCapsFeature f; + const gchar *feature; + GstStructure *structure; + GstCapsFeatures *features; + GstCaps *outcaps; + gint i, n; + + format = GST_VIDEO_FORMAT_UNKNOWN; + srcpad = GST_BASE_TRANSFORM_SRC_PAD (postproc); + f = gst_vaapi_find_preferred_caps_feature (srcpad, srccaps, &format); + if (f == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) + return NULL; + + feature = gst_vaapi_caps_feature_to_string (f); + if (!feature) + feature = GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY; + + n = gst_caps_get_size (srccaps); + for (i = 0; i < n; i++) { + structure = gst_caps_get_structure (srccaps, i); + features = gst_caps_get_features (srccaps, i); + + if (!gst_caps_features_is_any (features) + && gst_caps_features_contains (features, feature)) + break; + } + + if (i >= n) + goto invalid_caps; + + /* make copy */ + structure = gst_structure_copy (structure); + + if (!_set_preferred_format (structure, format)) + goto fixate_failed; + if (!_fixate_frame_size (postproc, vinfo, structure)) + goto fixate_failed; + if (!_fixate_frame_rate (postproc, vinfo, structure)) + goto fixate_failed; + + outcaps = gst_caps_new_empty (); + gst_caps_append_structure_full (outcaps, structure, + gst_caps_features_copy (features)); + + /* we don't need to do format conversion if GL_TEXTURE_UPLOAD_META + * is negotiated */ + if (f != GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META + && postproc->format != format) + postproc->format = format; + + return outcaps; + + /* ERRORS */ +fixate_failed: + { + GST_WARNING_OBJECT (postproc, "Could not fixate src caps"); + gst_structure_free (structure); + return NULL; + } +invalid_caps: + { + GST_WARNING_OBJECT (postproc, "No valid src caps found"); + return NULL; + } +} + /** * gst_vaapipostproc_fixate_srccaps: * @postproc: a #GstVaapiPostproc instance @@ -189,61 +316,8 @@ gst_vaapipostproc_fixate_srccaps (GstVaapiPostproc * postproc, GstCaps * sinkcaps, GstCaps * srccaps) { GstVideoInfo vi; - GstVideoFormat out_format; - GstCaps *out_caps; - GstVaapiCapsFeature feature; - const gchar *feature_str; - guint width, height; - GstPad *srcpad; - /* Generate the expected src pad caps, from the current fixated sink - pad caps */ if (!gst_video_info_from_caps (&vi, sinkcaps)) return NULL; - - // Set double framerate in interlaced mode - if (is_deinterlace_enabled (postproc, &vi)) { - gint fps_n = GST_VIDEO_INFO_FPS_N (&vi); - gint fps_d = GST_VIDEO_INFO_FPS_D (&vi); - if (!gst_util_fraction_multiply (fps_n, fps_d, 2, 1, &fps_n, &fps_d)) - return NULL; - GST_VIDEO_INFO_FPS_N (&vi) = fps_n; - GST_VIDEO_INFO_FPS_D (&vi) = fps_d; - } - // Signal the other pad that we only generate progressive frames - GST_VIDEO_INFO_INTERLACE_MODE (&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; - - // Update size from user-specified parameters - find_best_size (postproc, &vi, &width, &height); - - // Update format from user-specified parameters - srcpad = GST_BASE_TRANSFORM_SRC_PAD (postproc); - feature = gst_vaapi_find_preferred_caps_feature (srcpad, srccaps, - &out_format); - - if (postproc->format != DEFAULT_FORMAT) - out_format = postproc->format; - - if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) - return NULL; - - gst_video_info_change_format (&vi, out_format, width, height); - out_caps = gst_video_info_to_caps (&vi); - if (!out_caps) - return NULL; - - if (feature) { - feature_str = gst_vaapi_caps_feature_to_string (feature); - if (feature_str) - gst_caps_set_features (out_caps, 0, - gst_caps_features_new (feature_str, NULL)); - } - - /* we don't need to do format conversion if GL_TEXTURE_UPLOAD_META - * is negotiated */ - if (feature != GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META && - postproc->format != out_format) { - postproc->format = out_format; - } - return out_caps; + return _get_preferred_caps (postproc, &vi, srccaps); } From 7baacda91c1e2f66d4618669862b7b6f7dfc4f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 5 May 2016 18:23:10 +0200 Subject: [PATCH 2383/3781] vaapipostproc: negotiate frame size fixation Refactor _fixate_frame_size(). Now, instead of fixating the frame size only using the sink caps, also it use the next capsfilter. This code is a shameless copy of gst_video_scale_fixate_caps() from https://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/gst/videoscale/gstvideoscale.c?id=1.8.1#n634 https://bugzilla.gnome.org/show_bug.cgi?id=758548 --- gst/vaapi/gstvaapipostprocutil.c | 407 ++++++++++++++++++++++++++++--- 1 file changed, 371 insertions(+), 36 deletions(-) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index ff114a15cc..139f5fc903 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -1,6 +1,8 @@ /* * gstvaapipostprocutil.h - VA-API video post processing utilities * + * Copyright (C) <1999> Erik Walthinsen + * Copyright (C) 2005-2012 David Schleef * Copyright (C) 2016 Intel Corporation * Author: Gwenole Beauchesne * Author: Victor Jaquez @@ -146,47 +148,380 @@ is_deinterlace_enabled (GstVaapiPostproc * postproc, GstVideoInfo * vip) return deinterlace; } -static void -find_best_size (GstVaapiPostproc * postproc, GstVideoInfo * vip, - guint * width_ptr, guint * height_ptr) -{ - guint width, height; - - width = GST_VIDEO_INFO_WIDTH (vip); - height = GST_VIDEO_INFO_HEIGHT (vip); - if (postproc->width && postproc->height) { - width = postproc->width; - height = postproc->height; - } else if (postproc->keep_aspect) { - const gdouble ratio = (gdouble) width / height; - if (postproc->width) { - width = postproc->width; - height = postproc->width / ratio; - } else if (postproc->height) { - height = postproc->height; - width = postproc->height * ratio; - } - } else if (postproc->width) - width = postproc->width; - else if (postproc->height) - height = postproc->height; - - *width_ptr = width; - *height_ptr = height; -} - static gboolean _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, GstStructure * outs) { - guint width, height, par_n, par_d; + const GValue *to_par; + GValue tpar = G_VALUE_INIT; + gboolean ret; - par_n = GST_VIDEO_INFO_PAR_N (vinfo); - par_d = GST_VIDEO_INFO_PAR_D (vinfo); - find_best_size (postproc, vinfo, &width, &height); - gst_structure_set (outs, "width", G_TYPE_INT, width, "height", G_TYPE_INT, - height, "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL); - return TRUE; + ret = TRUE; + to_par = gst_structure_get_value (outs, "pixel-aspect-ratio"); + if (!to_par) { + g_value_init (&tpar, GST_TYPE_FRACTION); + gst_value_set_fraction (&tpar, 1, 1); + to_par = &tpar; + + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, + NULL); + } + + /* we have both PAR but they might not be fixated */ + { + gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d; + gint w = 0, h = 0; + gint from_dar_n, from_dar_d; + gint num, den; + + from_par_n = GST_VIDEO_INFO_PAR_N (vinfo); + from_par_d = GST_VIDEO_INFO_PAR_D (vinfo); + from_w = GST_VIDEO_INFO_WIDTH (vinfo); + from_h = GST_VIDEO_INFO_HEIGHT (vinfo); + + gst_structure_get_int (outs, "width", &w); + gst_structure_get_int (outs, "height", &h); + + /* if both width and height are already fixed, we can't do anything + * about it anymore */ + if (w && h) { + guint n, d; + + GST_DEBUG_OBJECT (postproc, + "dimensions already set to %dx%d, not fixating", w, h); + + if (!gst_value_is_fixed (to_par)) { + if (gst_video_calculate_display_ratio (&n, &d, from_w, from_h, + from_par_n, from_par_d, w, h)) { + GST_DEBUG_OBJECT (postproc, "fixating to_par to %dx%d", n, d); + if (gst_structure_has_field (outs, "pixel-aspect-ratio")) + gst_structure_fixate_field_nearest_fraction (outs, + "pixel-aspect-ratio", n, d); + else if (n != d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + n, d, NULL); + } + } + + goto done; + } + + /* Calculate input DAR */ + if (!gst_util_fraction_multiply (from_w, from_h, from_par_n, from_par_d, + &from_dar_n, &from_dar_d)) + goto overflow_error; + + GST_DEBUG_OBJECT (postproc, "Input DAR is %d/%d", from_dar_n, from_dar_d); + + /* If either width or height are fixed there's not much we + * can do either except choosing a height or width and PAR + * that matches the DAR as good as possible + */ + if (h) { + GstStructure *tmp; + gint set_w, set_par_n, set_par_d; + + GST_DEBUG_OBJECT (postproc, "height is fixed (%d)", h); + + /* If the PAR is fixed too, there's not much to do + * except choosing the width that is nearest to the + * width with the same DAR */ + if (gst_value_is_fixed (to_par)) { + to_par_n = gst_value_get_fraction_numerator (to_par); + to_par_d = gst_value_get_fraction_denominator (to_par); + + GST_DEBUG_OBJECT (postproc, "PAR is fixed %d/%d", to_par_n, to_par_d); + + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_d, + to_par_n, &num, &den)) + goto overflow_error; + + w = (guint) gst_util_uint64_scale_int (h, num, den); + gst_structure_fixate_field_nearest_int (outs, "width", w); + + goto done; + } + + /* The PAR is not fixed and it's quite likely that we can set + * an arbitrary PAR. */ + + /* Check if we can keep the input width */ + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "width", from_w); + gst_structure_get_int (tmp, "width", &set_w); + + /* Might have failed but try to keep the DAR nonetheless by + * adjusting the PAR */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, h, set_w, + &to_par_n, &to_par_d)) + goto overflow_error; + + if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) + gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); + gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio", + to_par_n, to_par_d); + gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n, + &set_par_d); + gst_structure_free (tmp); + + /* Check if the adjusted PAR is accepted */ + if (set_par_n == to_par_n && set_par_d == to_par_d) { + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "width", G_TYPE_INT, set_w, + "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d, + NULL); + goto done; + } + + /* Otherwise scale the width to the new PAR and check if the + * adjusted with is accepted. If all that fails we can't keep + * the DAR */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d, + set_par_n, &num, &den)) + goto overflow_error; + + w = (guint) gst_util_uint64_scale_int (h, num, den); + gst_structure_fixate_field_nearest_int (outs, "width", w); + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); + + goto done; + } else if (w) { + GstStructure *tmp; + gint set_h, set_par_n, set_par_d; + + GST_DEBUG_OBJECT (postproc, "width is fixed (%d)", w); + + /* If the PAR is fixed too, there's not much to do + * except choosing the height that is nearest to the + * height with the same DAR */ + if (gst_value_is_fixed (to_par)) { + to_par_n = gst_value_get_fraction_numerator (to_par); + to_par_d = gst_value_get_fraction_denominator (to_par); + + GST_DEBUG_OBJECT (postproc, "PAR is fixed %d/%d", to_par_n, to_par_d); + + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_d, + to_par_n, &num, &den)) + goto overflow_error; + + h = (guint) gst_util_uint64_scale_int (w, den, num); + gst_structure_fixate_field_nearest_int (outs, "height", h); + + goto done; + } + + /* The PAR is not fixed and it's quite likely that we can set + * an arbitrary PAR. */ + + /* Check if we can keep the input height */ + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "height", from_h); + gst_structure_get_int (tmp, "height", &set_h); + + /* Might have failed but try to keep the DAR nonetheless by + * adjusting the PAR */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, w, + &to_par_n, &to_par_d)) + goto overflow_error; + + if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) + gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); + gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio", + to_par_n, to_par_d); + gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n, + &set_par_d); + gst_structure_free (tmp); + + /* Check if the adjusted PAR is accepted */ + if (set_par_n == to_par_n && set_par_d == to_par_d) { + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "height", G_TYPE_INT, set_h, + "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d, + NULL); + goto done; + } + + /* Otherwise scale the height to the new PAR and check if the + * adjusted with is accepted. If all that fails we can't keep + * the DAR */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d, + set_par_n, &num, &den)) + goto overflow_error; + + h = (guint) gst_util_uint64_scale_int (w, den, num); + gst_structure_fixate_field_nearest_int (outs, "height", h); + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); + + goto done; + } else if (gst_value_is_fixed (to_par)) { + GstStructure *tmp; + gint set_h, set_w, f_h, f_w; + + to_par_n = gst_value_get_fraction_numerator (to_par); + to_par_d = gst_value_get_fraction_denominator (to_par); + + /* Calculate scale factor for the PAR change */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_n, + to_par_d, &num, &den)) + goto overflow_error; + + /* Try to keep the input height (because of interlacing) */ + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "height", from_h); + gst_structure_get_int (tmp, "height", &set_h); + + /* This might have failed but try to scale the width + * to keep the DAR nonetheless */ + w = (guint) gst_util_uint64_scale_int (set_h, num, den); + gst_structure_fixate_field_nearest_int (tmp, "width", w); + gst_structure_get_int (tmp, "width", &set_w); + gst_structure_free (tmp); + + /* We kept the DAR and the height is nearest to the original height */ + if (set_w == w) { + gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", + G_TYPE_INT, set_h, NULL); + goto done; + } + + f_h = set_h; + f_w = set_w; + + /* If the former failed, try to keep the input width at least */ + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "width", from_w); + gst_structure_get_int (tmp, "width", &set_w); + + /* This might have failed but try to scale the width + * to keep the DAR nonetheless */ + h = (guint) gst_util_uint64_scale_int (set_w, den, num); + gst_structure_fixate_field_nearest_int (tmp, "height", h); + gst_structure_get_int (tmp, "height", &set_h); + gst_structure_free (tmp); + + /* We kept the DAR and the width is nearest to the original width */ + if (set_h == h) { + gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", + G_TYPE_INT, set_h, NULL); + goto done; + } + + /* If all this failed, keep the height that was nearest to the orignal + * height and the nearest possible width. This changes the DAR but + * there's not much else to do here. + */ + gst_structure_set (outs, "width", G_TYPE_INT, f_w, "height", G_TYPE_INT, + f_h, NULL); + goto done; + } else { + GstStructure *tmp; + gint set_h, set_w, set_par_n, set_par_d, tmp2; + + /* width, height and PAR are not fixed but passthrough is not possible */ + + /* First try to keep the height and width as good as possible + * and scale PAR */ + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "height", from_h); + gst_structure_get_int (tmp, "height", &set_h); + gst_structure_fixate_field_nearest_int (tmp, "width", from_w); + gst_structure_get_int (tmp, "width", &set_w); + + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, set_w, + &to_par_n, &to_par_d)) + goto overflow_error; + + if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) + gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); + gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio", + to_par_n, to_par_d); + gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n, + &set_par_d); + gst_structure_free (tmp); + + if (set_par_n == to_par_n && set_par_d == to_par_d) { + gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", + G_TYPE_INT, set_h, NULL); + + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); + goto done; + } + + /* Otherwise try to scale width to keep the DAR with the set + * PAR and height */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d, + set_par_n, &num, &den)) + goto overflow_error; + + w = (guint) gst_util_uint64_scale_int (set_h, num, den); + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "width", w); + gst_structure_get_int (tmp, "width", &tmp2); + gst_structure_free (tmp); + + if (tmp2 == w) { + gst_structure_set (outs, "width", G_TYPE_INT, tmp2, "height", + G_TYPE_INT, set_h, NULL); + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); + goto done; + } + + /* ... or try the same with the height */ + h = (guint) gst_util_uint64_scale_int (set_w, den, num); + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "height", h); + gst_structure_get_int (tmp, "height", &tmp2); + gst_structure_free (tmp); + + if (tmp2 == h) { + gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", + G_TYPE_INT, tmp2, NULL); + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); + goto done; + } + + /* If all fails we can't keep the DAR and take the nearest values + * for everything from the first try */ + gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", + G_TYPE_INT, set_h, NULL); + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); + } + } + +done: + if (to_par == &tpar) + g_value_unset (&tpar); + + return ret; + + /* ERRORS */ +overflow_error: + { + ret = FALSE; + GST_ELEMENT_ERROR (postproc, CORE, NEGOTIATION, (NULL), + ("Error calculating the output scaled size - integer overflow")); + goto done; + } } static gboolean From 7e4e597c6dd165940c90b5b4602763f0ccb98969 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 11 May 2016 11:59:59 +0300 Subject: [PATCH 2384/3781] gstvaapiprofile : Add VAEntrypointEncSliceLP definitions This is for implementations that supports low_power/high_performance variant for slice level encode. https://bugzilla.gnome.org/show_bug.cgi?id=766050 --- gst-libs/gst/vaapi/gstvaapiprofile.c | 3 +++ gst-libs/gst/vaapi/gstvaapiprofile.h | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 89d8929e64..9c353c56af 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -154,6 +154,9 @@ static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = { #if VA_CHECK_VERSION(0,30,0) {GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, VAEntrypointEncSlice}, {GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, VAEntrypointEncPicture}, +#endif +#if VA_CHECK_VERSION(0,39,1) + {GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP, VAEntrypointEncSliceLP}, #endif {0,} }; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index c77777f0d2..745c229d26 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -188,6 +188,8 @@ typedef enum { * @GST_VAAPI_ENTRYPOINT_MOCO: Motion Compensation * @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: Encode Slice * @GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE: Encode Picture + * @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP: Encode Slice low power/ + * high performace varient * * The set of all entrypoints for #GstVaapiEntrypoint */ @@ -196,7 +198,8 @@ typedef enum { GST_VAAPI_ENTRYPOINT_IDCT, GST_VAAPI_ENTRYPOINT_MOCO, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, - GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE + GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, + GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP } GstVaapiEntrypoint; const gchar * From c1abf37d0b6126166df2195ed51971d49d0aab88 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 11 May 2016 12:03:08 +0300 Subject: [PATCH 2385/3781] gstvaapidisplay: Add VAEntrypointEncSliceLP support https://bugzilla.gnome.org/show_bug.cgi?id=766050 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 34f2faf425..a733423dbe 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -566,6 +566,7 @@ ensure_profiles (GstVaapiDisplay * display) break; case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: case GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE: + case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP: g_array_append_val (priv->encoders, config); break; } From 8c1cfbaa1e98e12c584613afbfdb1853c90cc064 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 11 May 2016 12:04:46 +0300 Subject: [PATCH 2386/3781] Add mapping for Macroblock level rate control (VA_RC_MB) --- gst-libs/gst/vaapi/gstvaapitypes.h | 2 ++ gst-libs/gst/vaapi/gstvaapiutils.c | 8 ++++++++ gst-libs/gst/vaapi/gstvaapivalue.c | 2 ++ 3 files changed, 12 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 9cc646f57e..33d7619821 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -146,6 +146,7 @@ typedef enum { * @GST_VAAPI_RATECONTROL_VBR: Variable bitrate * @GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: Variable bitrate with peak * rate higher than average bitrate + * @GST_VAAPI_RATECONTROL_MB: Macroblock based rate control * * The set of allowed rate control values for #GstVaapiRateControl. * Note: this is only valid for encoders. @@ -157,6 +158,7 @@ typedef enum { GST_VAAPI_RATECONTROL_VCM, GST_VAAPI_RATECONTROL_VBR, GST_VAAPI_RATECONTROL_VBR_CONSTRAINED, + GST_VAAPI_RATECONTROL_MB, } GstVaapiRateControl; /* Define a mask for GstVaapiRateControl */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index c1cca4633c..569e4b5d23 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -543,6 +543,10 @@ from_GstVaapiRateControl (guint value) #ifdef VA_RC_VBR_CONSTRAINED case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: return VA_RC_VBR_CONSTRAINED; +#endif +#ifdef VA_RC_MB + case GST_VAAPI_RATECONTROL_MB: + return VA_RC_MB; #endif } GST_ERROR ("unsupported GstVaapiRateControl value %u", value); @@ -568,6 +572,10 @@ to_GstVaapiRateControl (guint value) #ifdef VA_RC_VBR_CONSTRAINED case VA_RC_VBR_CONSTRAINED: return GST_VAAPI_RATECONTROL_VBR_CONSTRAINED; +#endif +#ifdef VA_RC_MB + case VA_RC_MB: + return GST_VAAPI_RATECONTROL_MB; #endif } GST_ERROR ("unsupported VA-API Rate Control value %u", value); diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index e6bacfbed0..5ca01ce2b4 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -143,6 +143,8 @@ gst_vaapi_rate_control_get_type (void) "Variable bitrate", "vbr"}, {GST_VAAPI_RATECONTROL_VBR_CONSTRAINED, "Variable bitrate - Constrained", "vbr_constrained"}, + {GST_VAAPI_RATECONTROL_MB, + "Macroblock based rate control", "mb"}, {0, NULL, NULL}, }; From 32ee78bc524e9a98785513d2f5befb436a112f8e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 11 May 2016 12:05:36 +0300 Subject: [PATCH 2387/3781] encoder: h264: Add support of low power/high performance encoding mode Added a new property "low-power-enc" for enabling low power encoding mode. Certain encoding tools may not be available with the VAEntrypointEncSliceLP. https://bugzilla.gnome.org/show_bug.cgi?id=766050 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 23 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 5 ++++- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index cf77864804..febc3b71a0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -604,10 +604,10 @@ set_context_info (GstVaapiEncoder * encoder) cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; cip->profile = encoder->profile; - cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; - if (cdata->codec != GST_VAAPI_CODEC_JPEG) - cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; - else + if (cdata->codec != GST_VAAPI_CODEC_JPEG) { + if (cip->entrypoint != GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) + cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + } else cip->entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; cip->chroma_type = gst_vaapi_video_format_get_chroma_type (format); cip->width = GST_VAAPI_ENCODER_WIDTH (encoder); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 289a311bb4..15ae67ddc5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -745,6 +745,7 @@ struct _GstVaapiEncoderH264 GstVaapiProfile profile; GstVaapiLevelH264 level; + GstVaapiEntrypoint entrypoint; guint8 profile_idc; guint8 max_profile_idc; guint8 hw_max_profile_idc; @@ -758,6 +759,7 @@ struct _GstVaapiEncoderH264 guint32 mb_height; gboolean use_cabac; gboolean use_dct8x8; + gboolean enable_lp; GstClockTime cts_offset; gboolean config_changed; @@ -1071,6 +1073,11 @@ ensure_hw_profile (GstVaapiEncoderH264 * encoder) GstVaapiProfile profile, profiles[4]; guint i, num_profiles = 0; + if (encoder->enable_lp) + entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; + + encoder->entrypoint = entrypoint; + profiles[num_profiles++] = encoder->profile; switch (encoder->profile) { case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE: @@ -2777,6 +2784,8 @@ set_context_info (GstVaapiEncoder * base_encoder) base_encoder->codedbuf_size += encoder->num_slices * (4 + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); + base_encoder->context_info.entrypoint = encoder->entrypoint; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } @@ -2938,6 +2947,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, } break; } + case GST_VAAPI_ENCODER_H264_PROP_LP_MODE: + encoder->enable_lp = g_value_get_boolean (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -3102,6 +3114,17 @@ gst_vaapi_encoder_h264_get_default_properties (void) "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:enable_lp: + * + * Enable low power/high performace encoding mode. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_LP_MODE, + g_param_spec_boolean ("low-power-enc", + "Enable Low Power Encode", + "Enable Low Power/High Performace encoding", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 4e64d3bc64..9f65f8bde4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -48,6 +48,8 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * in milliseconds (uint). * @GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: Number of views per frame. * @GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS: View IDs + * @GST_VAAPI_ENCODER_H264_PROP_LP_MODE: Enable Low Power/High Performace + * encoding. * * The set of H.264 encoder specific configurable properties. */ @@ -60,7 +62,8 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_DCT8X8 = -6, GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH = -7, GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS = -8, - GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS = -9 + GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS = -9, + GST_VAAPI_ENCODER_H264_PROP_LP_MODE = -10 } GstVaapiEncoderH264Prop; GstVaapiEncoder * From d446013ae4dd2286b4bbe020443baaf3816a65f3 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 11 May 2016 12:06:38 +0300 Subject: [PATCH 2388/3781] gstvaapiencoder:Use internal api to dervie configured VAEntrypoint https://bugzilla.gnome.org/show_bug.cgi?id=766050 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index febc3b71a0..f900eff3d4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -513,18 +513,14 @@ get_config_attribute (GstVaapiEncoder * encoder, VAConfigAttribType type, GstVaapiProfile profile; VAProfile va_profile; VAEntrypoint va_entrypoint; - const GstVaapiEncoderClassData *const cdata = - GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; profile = get_profile (encoder); if (!profile) return FALSE; va_profile = gst_vaapi_profile_get_va_profile (profile); - if (cdata->codec != GST_VAAPI_CODEC_JPEG) - va_entrypoint = VAEntrypointEncSlice; - else - va_entrypoint = VAEntrypointEncPicture; + va_entrypoint = + gst_vaapi_entrypoint_get_va_entrypoint (encoder->context_info.entrypoint); return gst_vaapi_get_config_attribute (encoder->display, va_profile, va_entrypoint, type, out_value_ptr); From 43af7c362c7fa3a19690406de09969ccc5769511 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 13 May 2016 11:44:57 +0300 Subject: [PATCH 2389/3781] encoder: h264 : Use "tune=low-power" for enabling lowpower encode Remove the duplicate property "low-power-enc" and use the tune property for enabling low power encoding mode. https://bugzilla.gnome.org/show_bug.cgi?id=766050 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 39 ++++++++++------------- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 3 -- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 15ae67ddc5..39937fbaee 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -74,7 +74,8 @@ /* Supported set of tuning options, within this implementation */ #define SUPPORTED_TUNE_OPTIONS \ (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \ - GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION)) + GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION) | \ + GST_VAAPI_ENCODER_TUNE_MASK (LOW_POWER)) /* Supported set of VA packed headers, within this implementation */ #define SUPPORTED_PACKED_HEADERS \ @@ -759,7 +760,6 @@ struct _GstVaapiEncoderH264 guint32 mb_height; gboolean use_cabac; gboolean use_dct8x8; - gboolean enable_lp; GstClockTime cts_offset; gboolean config_changed; @@ -1069,15 +1069,10 @@ static gboolean ensure_hw_profile (GstVaapiEncoderH264 * encoder) { GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); - GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + GstVaapiEntrypoint entrypoint = encoder->entrypoint; GstVaapiProfile profile, profiles[4]; guint i, num_profiles = 0; - if (encoder->enable_lp) - entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; - - encoder->entrypoint = entrypoint; - profiles[num_profiles++] = encoder->profile; switch (encoder->profile) { case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE: @@ -1251,6 +1246,14 @@ ensure_tuning (GstVaapiEncoderH264 * encoder) case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: success = ensure_tuning_high_compression (encoder); break; + case GST_VAAPI_ENCODER_TUNE_LOW_POWER: + /* Set low-power encode entry point. If hardware doesn't have + * support, it will fail in ensure_hw_profile() in later stage. + * So not duplicating the profile/entrypont query mechanism + * here as a part of optimization */ + encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; + success = TRUE; + break; default: success = TRUE; break; @@ -2398,7 +2401,8 @@ ensure_profile_and_level (GstVaapiEncoderH264 * encoder) const GstVaapiProfile profile = encoder->profile; const GstVaapiLevelH264 level = encoder->level; - ensure_tuning (encoder); + if (!ensure_tuning (encoder)) + GST_WARNING ("Failed to set some of the tuning option as expected! "); if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; @@ -2832,6 +2836,9 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder) GST_VAAPI_ENCODER_H264_CAST (base_encoder); guint32 i; + /* Default encoding entrypoint */ + encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + /* Multi-view coding information */ encoder->is_mvc = FALSE; encoder->num_views = 1; @@ -2947,9 +2954,6 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, } break; } - case GST_VAAPI_ENCODER_H264_PROP_LP_MODE: - encoder->enable_lp = g_value_get_boolean (value); - break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -3114,17 +3118,6 @@ gst_vaapi_encoder_h264_get_default_properties (void) "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiEncoderH264:enable_lp: - * - * Enable low power/high performace encoding mode. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_LP_MODE, - g_param_spec_boolean ("low-power-enc", - "Enable Low Power Encode", - "Enable Low Power/High Performace encoding", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 9f65f8bde4..14e35efd6e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -48,8 +48,6 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * in milliseconds (uint). * @GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: Number of views per frame. * @GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS: View IDs - * @GST_VAAPI_ENCODER_H264_PROP_LP_MODE: Enable Low Power/High Performace - * encoding. * * The set of H.264 encoder specific configurable properties. */ @@ -63,7 +61,6 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH = -7, GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS = -8, GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS = -9, - GST_VAAPI_ENCODER_H264_PROP_LP_MODE = -10 } GstVaapiEncoderH264Prop; GstVaapiEncoder * From c91de2398a89e9c7cfb31afb6f69c2b9d4b51752 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 13 May 2016 11:45:20 +0300 Subject: [PATCH 2390/3781] encoder : h264: Disable b-frame encode in low-power mode This is a workaround since vaapi-intel-driver doesn't have support for B-frame encode when utilizing low-power-enc hardware block. Fixme :We should query the VAConfigAttribEncMaxRefFrames instead of blindly disabling b-frame support and set b/p frame count, buffer pool size etc based on the query result. https://bugzilla.gnome.org/show_bug.cgi?id=766050 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 39937fbaee..eaafd55c79 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2451,6 +2451,20 @@ reset_properties (GstVaapiEncoderH264 * encoder) if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; + /* Workaround : vaapi-intel-driver doesn't have support for + * B-frame encode when utilizing low-power encode hardware block. + * So Disabling b-frame encoding in low-pwer encode. + * + * Fixme :We should query the VAConfigAttribEncMaxRefFrames + * instead of blindly disabling b-frame support and set b/p frame count, + * buffer pool size etc based on that.*/ + if ((encoder->num_bframes > 0) + && (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)) { + GST_WARNING + ("Disabling b-frame since the driver doesn't supporting it in low-power encode"); + encoder->num_bframes = 0; + } + if (encoder->num_bframes) encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) / GST_VAAPI_ENCODER_FPS_N (encoder); From 36e2346fc7755c253d94e2f781a8080b54bd7a29 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 18 May 2016 17:05:03 +0300 Subject: [PATCH 2391/3781] gstvaapipluginbase: Fix typo in doc --- gst/vaapi/gstvaapipluginbase.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 2863589fbf..b302557c83 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -806,7 +806,7 @@ config_failed: /** * gst_vaapi_plugin_base_get_input_buffer: * @plugin: a #GstVaapiPluginBase - * @incaps: the sink pad (input) buffer + * @inbuf: the sink pad (input) buffer * @outbuf_ptr: the pointer to location to the VA surface backed buffer * * Acquires the sink pad (input) buffer as a VA surface backed From 5341d9ae9fcc78c90562423b30a8fdf0b97351f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 10 May 2016 16:14:48 +0200 Subject: [PATCH 2392/3781] plugins: remove gst_vaapi_plugin_base_set_pool_config() This function helper make sense for GStreamer 1.2, but it is not helpful for greater version since the validation is already done in the API implementation. Thus, it is removed. --- gst/vaapi/gstvaapipluginbase.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index b302557c83..9a9d08b50f 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -623,17 +623,6 @@ error_pool_config: } } -static inline gboolean -gst_vaapi_plugin_base_set_pool_config (GstBufferPool * pool, - const gchar * option) -{ - GstStructure *config; - - config = gst_buffer_pool_get_config (pool); - gst_buffer_pool_config_add_option (config, option); - return gst_buffer_pool_set_config (pool, config); -} - /** * gst_vaapi_plugin_base_decide_allocation: * @plugin: a #GstVaapiPluginBase @@ -746,26 +735,28 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, goto config_failed; } + config = gst_buffer_pool_get_config (pool); + /* Check whether GstVideoMeta, or GstVideoAlignment, is needed (raw video) */ if (has_video_meta) { - if (!gst_vaapi_plugin_base_set_pool_config (pool, - GST_BUFFER_POOL_OPTION_VIDEO_META)) - goto config_failed; + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); } else if (has_video_alignment) { - if (!gst_vaapi_plugin_base_set_pool_config (pool, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) - goto config_failed; + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); } /* GstVideoGLTextureUploadMeta (OpenGL) */ #if (USE_GLX || USE_EGL) if (has_texture_upload_meta) { - if (!gst_vaapi_plugin_base_set_pool_config (pool, - GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META)) - goto config_failed; + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); } #endif + if (!gst_buffer_pool_set_config (pool, config)) + goto config_failed; + if (update_pool) gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); else From 1769da4957e1d8d4ffcacf3ae94ffca4e8011219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 6 May 2016 13:17:47 +0200 Subject: [PATCH 2393/3781] vaapivideobufferpool: relate errors to instance Use GST_ERROR_OBJECT instead of GST_ERROR, thus the logs will show the name of the vaapivideobufferpool instance that failed. --- gst/vaapi/gstvaapivideobufferpool.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index cc80df6532..32d80834e4 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -210,27 +210,28 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, /* ERRORS */ error_invalid_config: { - GST_ERROR ("invalid config"); + GST_ERROR_OBJECT (pool, "invalid config"); return FALSE; } error_no_caps: { - GST_ERROR ("no valid caps in config"); + GST_ERROR_OBJECT (pool, "no valid caps in config"); return FALSE; } error_create_allocator: { - GST_ERROR ("failed to create GstVaapiVideoAllocator object"); + GST_ERROR_OBJECT (pool, "failed to create GstVaapiVideoAllocator object"); return FALSE; } error_create_allocator_info: { - GST_ERROR ("failed to create GstVaapiVideoAllocator `video-info'"); + GST_ERROR_OBJECT (pool, + "failed to create GstVaapiVideoAllocator `video-info'"); return FALSE; } error_no_vaapi_video_meta_option: { - GST_ERROR ("no GstVaapiVideoMeta option"); + GST_ERROR_OBJECT (pool, "no GstVaapiVideoMeta option"); return FALSE; } } @@ -299,23 +300,23 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, /* ERRORS */ error_no_allocator: { - GST_ERROR ("no GstAllocator in buffer pool"); + GST_ERROR_OBJECT (pool, "no GstAllocator in buffer pool"); return GST_FLOW_ERROR; } error_create_meta: { - GST_ERROR ("failed to allocate vaapi video meta"); + GST_ERROR_OBJECT (pool, "failed to allocate vaapi video meta"); return GST_FLOW_ERROR; } error_create_buffer: { - GST_ERROR ("failed to create video buffer"); + GST_ERROR_OBJECT (pool, "failed to create video buffer"); gst_vaapi_video_meta_unref (meta); return GST_FLOW_ERROR; } error_create_memory: { - GST_ERROR ("failed to create video memory"); + GST_ERROR_OBJECT (pool, "failed to create video memory"); gst_buffer_unref (buffer); gst_vaapi_video_meta_unref (meta); return GST_FLOW_ERROR; From 3f61394cb03f440774ebbd94f1a023f79a30058e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 19 May 2016 16:34:50 +0200 Subject: [PATCH 2394/3781] vaapivideomemory: use allocator custom alloc flag Instead of a dummy alloc() vmethod, the allocator instance set the flag GST_ALLOCATOR_FLAG_CUSTOM_ALLOC, which is used by the framework to avoid call gst_allocator_alloc() on the allocator. --- gst/vaapi/gstvaapivideomemory.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index c7f8ee1b42..6ece32cfed 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -556,16 +556,6 @@ gst_vaapi_video_memory_is_span (GstVaapiVideoMemory * mem1, G_DEFINE_TYPE (GstVaapiVideoAllocator, gst_vaapi_video_allocator, GST_TYPE_ALLOCATOR); -static GstMemory * -gst_vaapi_video_allocator_alloc (GstAllocator * allocator, gsize size, - GstAllocationParams * params) -{ - g_warning ("use gst_vaapi_video_memory_new() to allocate from " - "GstVaapiVideoMemory allocator"); - - return NULL; -} - static void gst_vaapi_video_allocator_free (GstAllocator * allocator, GstMemory * mem) { @@ -594,7 +584,6 @@ gst_vaapi_video_allocator_class_init (GstVaapiVideoAllocatorClass * klass) "vaapivideomemory", 0, "VA-API video memory allocator"); object_class->finalize = gst_vaapi_video_allocator_finalize; - allocator_class->alloc = gst_vaapi_video_allocator_alloc; allocator_class->free = gst_vaapi_video_allocator_free; } @@ -614,6 +603,8 @@ gst_vaapi_video_allocator_init (GstVaapiVideoAllocator * allocator) gst_vaapi_video_memory_share; base_allocator->mem_is_span = (GstMemoryIsSpanFunction) gst_vaapi_video_memory_is_span; + + GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); } static gboolean From 35f6ce964d23bddd18e510135643042213f34b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 May 2016 19:15:11 +0200 Subject: [PATCH 2395/3781] vaapipluginbase: code-style: rename goto label The error labels have error_ prefix, but this one. --- gst/vaapi/gstvaapipluginbase.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 9a9d08b50f..45e9a3d321 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -732,7 +732,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); if (!gst_buffer_pool_set_config (pool, config)) - goto config_failed; + goto error_config_failed; } config = gst_buffer_pool_get_config (pool); @@ -755,7 +755,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, #endif if (!gst_buffer_pool_set_config (pool, config)) - goto config_failed; + goto error_config_failed; if (update_pool) gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); @@ -783,7 +783,7 @@ error_create_pool: GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); return FALSE; } -config_failed: +error_config_failed: { if (pool) gst_object_unref (pool); From d69917ecca8a8600246c9bcdd6652897f386fb1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 May 2016 19:33:39 +0200 Subject: [PATCH 2396/3781] remove spurious gst_video_info_init() gst_video_info_set_format() and gst_video_info_from_caps() call, internally, gst_video_info_init(), hence it is not required to call it before them. This patch removes these spurious calls. --- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 1 - gst/vaapi/gstvaapipluginbase.c | 2 -- gst/vaapi/gstvaapipostproc.c | 1 - tests/simple-encoder.c | 1 - 4 files changed, 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index 426019a35a..371f05dc09 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -114,7 +114,6 @@ fill_video_info (GstVideoInfo * vip, GstVideoFormat format, guint width, { guint i; - gst_video_info_init (vip); gst_video_info_set_format (vip, format, width, height); for (i = 0; i < GST_VIDEO_INFO_N_PLANES (vip); i++) { GST_VIDEO_INFO_PLANE_OFFSET (vip, i) = offset[i]; diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 45e9a3d321..8ef550cbb2 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -500,7 +500,6 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) if (!pool) goto error_create_pool; - gst_video_info_init (&vi); gst_video_info_from_caps (&vi, caps); if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) { GST_DEBUG ("assume video buffer pool format is NV12"); @@ -694,7 +693,6 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!gst_vaapi_plugin_base_ensure_display (plugin)) goto error_ensure_display; - gst_video_info_init (&vi); gst_video_info_from_caps (&vi, caps); if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index a29b2a626b..85270c6b04 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1140,7 +1140,6 @@ ensure_srcpad_buffer_pool (GstVaapiPostproc * postproc, GstCaps * caps) GstVideoInfo vi; GstVaapiVideoPool *pool; - gst_video_info_init (&vi); gst_video_info_from_caps (&vi, caps); gst_video_info_change_format (&vi, postproc->format, GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); diff --git a/tests/simple-encoder.c b/tests/simple-encoder.c index b827604f9a..58b0e8c214 100644 --- a/tests/simple-encoder.c +++ b/tests/simple-encoder.c @@ -157,7 +157,6 @@ new_codec_state (gint width, gint height, gint fps_n, gint fps_d) state = g_slice_new0 (GstVideoCodecState); state->ref_count = 1; - gst_video_info_init (&state->info); gst_video_info_set_format (&state->info, GST_VIDEO_FORMAT_ENCODED, width, height); From 4dd246406096c1cf1f5baf5696a2ff82aff4617d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 May 2016 21:01:02 +0200 Subject: [PATCH 2397/3781] plugins: use GstVideoInfo accessors Instead of access to GstVideInfo members directly, use their accessors macros. This patch makes more resistance to future changes in GStreamer core. --- gst/vaapi/gstvaapipluginbase.c | 6 +++--- gst/vaapi/gstvaapipluginutil.c | 15 +++++++-------- gst/vaapi/gstvaapisink.c | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 8ef550cbb2..00dc9c9021 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -506,7 +506,7 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); } - plugin->sinkpad_buffer_size = vi.size; + plugin->sinkpad_buffer_size = GST_VIDEO_INFO_SIZE (&vi); config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, @@ -701,7 +701,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); update_pool = TRUE; - size = MAX (size, vi.size); + size = MAX (size, GST_VIDEO_INFO_SIZE (&vi)); if (pool) { /* Check whether downstream element proposed a bufferpool but did not provide a correct propose_allocation() implementation */ @@ -710,7 +710,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, } } else { pool = NULL; - size = vi.size; + size = GST_VIDEO_INFO_SIZE (&vi); min = max = 0; } diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index f774916d5d..a4a9ad4863 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -659,14 +659,13 @@ gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, gst_video_info_set_format (vip, format, width, height); - vip->interlace_mode = vi.interlace_mode; - vip->flags = vi.flags; - vip->views = vi.views; - vip->par_n = vi.par_n; - vip->par_d = vi.par_d; - vip->fps_n = vi.fps_n; - vip->fps_d = vi.fps_d; - + GST_VIDEO_INFO_INTERLACE_MODE (vip) = GST_VIDEO_INFO_INTERLACE_MODE (&vi); + GST_VIDEO_FORMAT_INFO_FLAGS (vip) = GST_VIDEO_FORMAT_INFO_FLAGS (&vi); + GST_VIDEO_INFO_VIEWS (vip) = GST_VIDEO_INFO_VIEWS (&vi); + GST_VIDEO_INFO_PAR_N (vip) = GST_VIDEO_INFO_PAR_N (&vi); + GST_VIDEO_INFO_PAR_D (vip) = GST_VIDEO_INFO_PAR_D (&vi); + GST_VIDEO_INFO_FPS_N (vip) = GST_VIDEO_INFO_FPS_N (&vi); + GST_VIDEO_INFO_FPS_D (vip) = GST_VIDEO_INFO_FPS_D (&vi); GST_VIDEO_INFO_MULTIVIEW_MODE (vip) = GST_VIDEO_INFO_MULTIVIEW_MODE (&vi); GST_VIDEO_INFO_MULTIVIEW_FLAGS (vip) = GST_VIDEO_INFO_MULTIVIEW_FLAGS (&vi); } diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index c7b0ca0a01..ea825cba8b 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1308,7 +1308,7 @@ gst_vaapisink_set_caps (GstBaseSink * base_sink, GstCaps * caps) GST_DEBUG ("video pixel-aspect-ratio %d/%d", sink->video_par_n, sink->video_par_d); - update_colorimetry (sink, &vip->colorimetry); + update_colorimetry (sink, &GST_VIDEO_INFO_COLORIMETRY (vip)); gst_caps_replace (&sink->caps, caps); gst_vaapisink_ensure_colorbalance (sink); From 6d8b7056cc93002f646df1fc8a7857a21b819cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 23 May 2016 17:47:36 +0200 Subject: [PATCH 2398/3781] plugins: relate errors to instance Use GST_{ERROR,WARNING}_OBJECT instead of GST_{ERROR,WARNING}, thus the logs will show the name of the vaapipluginbase instance that failed. Also, the code-style is fixed, where some error labels need to be surrounded by braces. --- gst/vaapi/gstvaapipluginbase.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 00dc9c9021..9230e9b444 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -226,14 +226,23 @@ plugin_bind_dma_to_vaapi_buffer (GstVaapiPluginBase * plugin, /* ERRORS */ error_update_sinkpad_info: - GST_ERROR ("failed to update sink pad video info from video meta"); - return FALSE; + { + GST_ERROR_OBJECT (plugin, + "failed to update sink pad video info from video meta"); + return FALSE; + } error_create_surface: - GST_ERROR ("failed to create VA surface from dma_buf handle"); - return FALSE; + { + GST_ERROR_OBJECT (plugin, + "failed to create VA surface from dma_buf handle"); + return FALSE; + } error_create_proxy: - GST_ERROR ("failed to create VA surface proxy from wrapped VA surface"); - return FALSE; + { + GST_ERROR_OBJECT (plugin, + "failed to create VA surface proxy from wrapped VA surface"); + return FALSE; + } } void @@ -522,12 +531,12 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) /* ERRORS */ error_create_pool: { - GST_ERROR ("failed to create buffer pool"); + GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); return FALSE; } error_pool_config: { - GST_ERROR ("failed to reset buffer pool config"); + GST_ERROR_OBJECT (plugin, "failed to reset buffer pool config"); gst_object_unref (pool); return FALSE; } @@ -911,7 +920,7 @@ error_bind_dma_buffer: } error_copy_buffer: { - GST_WARNING ("failed to upload buffer to VA surface"); + GST_WARNING_OBJECT (plugin, "failed to upload buffer to VA surface"); gst_buffer_unref (outbuf); return GST_FLOW_NOT_SUPPORTED; } From 915932843413d371f841871a6f2323ea609b5a69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 23 May 2016 17:55:35 +0200 Subject: [PATCH 2399/3781] plugins: handle if gst_video_info_from_caps() fails Let's play safe and return error if, somehow, the received caps are wrong. --- gst/vaapi/gstvaapipluginbase.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 9230e9b444..2666c9a01b 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -509,7 +509,8 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) if (!pool) goto error_create_pool; - gst_video_info_from_caps (&vi, caps); + if (!gst_video_info_from_caps (&vi, caps)) + goto error_invalid_caps; if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) { GST_DEBUG ("assume video buffer pool format is NV12"); gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, @@ -529,6 +530,11 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) return TRUE; /* ERRORS */ +error_invalid_caps: + { + GST_ERROR_OBJECT (plugin, "invalid caps %" GST_PTR_FORMAT, caps); + return FALSE; + } error_create_pool: { GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); @@ -702,7 +708,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!gst_vaapi_plugin_base_ensure_display (plugin)) goto error_ensure_display; - gst_video_info_from_caps (&vi, caps); + if (!gst_video_info_from_caps (&vi, caps)) + goto error_invalid_caps; if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); @@ -779,6 +786,11 @@ error_no_caps: GST_ERROR_OBJECT (plugin, "no caps specified"); return FALSE; } +error_invalid_caps: + { + GST_ERROR_OBJECT (plugin, "invalid caps %" GST_PTR_FORMAT, caps); + return FALSE; + } error_ensure_display: { GST_ERROR_OBJECT (plugin, "failed to ensure display of type %d", From 9da69fa3a2cad2cfabd47a7c1c41a272ca53321e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 23 May 2016 18:04:47 +0200 Subject: [PATCH 2400/3781] vaapipostproc: handle if gst_video_info_from_caps() fails Return FALSE is the received caps cannot be transformed into a GstVideoInfo structure. --- gst/vaapi/gstvaapipostproc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 85270c6b04..9f2ff5bfb7 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1140,7 +1140,8 @@ ensure_srcpad_buffer_pool (GstVaapiPostproc * postproc, GstCaps * caps) GstVideoInfo vi; GstVaapiVideoPool *pool; - gst_video_info_from_caps (&vi, caps); + if (!gst_video_info_from_caps (&vi, caps)) + return FALSE; gst_video_info_change_format (&vi, postproc->format, GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); @@ -1184,7 +1185,8 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, * formats while doing advanced deinterlacing. The format of reference surfaces must * be same as the format used by the driver internally for motion adaptive * deinterlacing and motion compensated deinterlacing */ - gst_video_info_from_caps (&vinfo, caps); + if (!gst_video_info_from_caps (&vinfo, caps)) + return FALSE; if (deint_method_is_advanced (postproc->deinterlace_method) && !is_native_video_format (GST_VIDEO_INFO_FORMAT (&vinfo))) { GST_WARNING_OBJECT (postproc, From 4800f48980c4106cdb83a7025166b8436fe3f1ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 23 May 2016 18:47:46 +0200 Subject: [PATCH 2401/3781] plugins: fix potential memleak from commit 9159328 If gst_video_info_from_caps() fails it is required to unref the instantiated pool. --- gst/vaapi/gstvaapipluginbase.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 2666c9a01b..7d5dec3305 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -533,6 +533,7 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) error_invalid_caps: { GST_ERROR_OBJECT (plugin, "invalid caps %" GST_PTR_FORMAT, caps); + gst_object_unref (pool); return FALSE; } error_create_pool: From f0d385ea4ece91e6b9902c3ee1ce63fc1fd541b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 23 May 2016 23:13:55 +0200 Subject: [PATCH 2402/3781] plugins: remove unused variables This variables stopped to be used since commit 001a5c63, which removed the gstvaapiuploader. --- gst/vaapi/gstvaapipluginbase.c | 4 ---- gst/vaapi/gstvaapipluginbase.h | 2 -- 2 files changed, 6 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 7d5dec3305..e30e24d1d5 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -310,7 +310,6 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) gst_object_replace (&plugin->gl_context, NULL); gst_caps_replace (&plugin->sinkpad_caps, NULL); - plugin->sinkpad_caps_changed = FALSE; gst_video_info_init (&plugin->sinkpad_info); if (plugin->sinkpad_buffer_pool) { gst_object_unref (plugin->sinkpad_buffer_pool); @@ -319,7 +318,6 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) g_clear_object (&plugin->srcpad_buffer_pool); gst_caps_replace (&plugin->srcpad_caps, NULL); - plugin->srcpad_caps_changed = FALSE; gst_video_info_init (&plugin->srcpad_info); gst_caps_replace (&plugin->allowed_raw_caps, NULL); } @@ -568,7 +566,6 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, gst_caps_replace (&plugin->sinkpad_caps, incaps); if (!gst_video_info_from_caps (&plugin->sinkpad_info, incaps)) return FALSE; - plugin->sinkpad_caps_changed = TRUE; plugin->sinkpad_caps_is_raw = !gst_caps_has_vaapi_surface (incaps); } @@ -576,7 +573,6 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, gst_caps_replace (&plugin->srcpad_caps, outcaps); if (!gst_video_info_from_caps (&plugin->srcpad_info, outcaps)) return FALSE; - plugin->srcpad_caps_changed = TRUE; } if (!ensure_sinkpad_buffer_pool (plugin, plugin->sinkpad_caps)) diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 2e538929e5..885650543c 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -157,7 +157,6 @@ struct _GstVaapiPluginBase GstPad *sinkpad; GstCaps *sinkpad_caps; - gboolean sinkpad_caps_changed; gboolean sinkpad_caps_is_raw; GstVideoInfo sinkpad_info; GstBufferPool *sinkpad_buffer_pool; @@ -165,7 +164,6 @@ struct _GstVaapiPluginBase GstPad *srcpad; GstCaps *srcpad_caps; - gboolean srcpad_caps_changed; GstVideoInfo srcpad_info; GstBufferPool *srcpad_buffer_pool; From 1f5ba28bd0e0cfdacd747170c1b09c4e33973a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 23 May 2016 22:21:15 +0200 Subject: [PATCH 2403/3781] plugins: check for caps in query earlier Check for caps as soon gst_query_parse_allocation() returns. --- gst/vaapi/gstvaapidecode.c | 5 ++--- gst/vaapi/gstvaapipluginbase.c | 9 ++++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index c8274829b3..8bfc4eab98 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -732,12 +732,11 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) GstCaps *caps = NULL; gst_query_parse_allocation (query, &caps, NULL); - - decode->has_texture_upload_meta = FALSE; - if (!caps) goto error_no_caps; + decode->has_texture_upload_meta = FALSE; + #if (USE_GLX || USE_EGL) decode->has_texture_upload_meta = gst_query_find_allocation_meta (query, diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e30e24d1d5..000e326e52 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -597,10 +597,10 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, gboolean need_pool; gst_query_parse_allocation (query, &caps, &need_pool); + if (!caps) + goto error_no_caps; if (need_pool) { - if (!caps) - goto error_no_caps; if (!ensure_sinkpad_buffer_pool (plugin, caps)) return FALSE; gst_query_add_allocation_pool (query, plugin->sinkpad_buffer_pool, @@ -665,14 +665,13 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, g_return_val_if_fail (plugin->display != NULL, FALSE); gst_query_parse_allocation (query, &caps, NULL); + if (!caps) + goto error_no_caps; /* We don't need any GL context beyond this point if not requested so explicitly through GstVideoGLTextureUploadMeta */ gst_object_replace (&plugin->gl_context, NULL); - if (!caps) - goto error_no_caps; - has_video_meta = gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); From 21b184284bc4e9c6740457e74312c8eabdb28a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 23 May 2016 22:30:04 +0200 Subject: [PATCH 2404/3781] vaapivideobufferpool: split caps validation When validating the caps from bufferpool config, this patch distinguishes the error from no caps received (NULL) from the invalid caps (cannot be converted into GstVideoInfo structure). --- gst/vaapi/gstvaapivideobufferpool.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 32d80834e4..fa8ded20c0 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -145,8 +145,10 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) goto error_invalid_config; - if (!caps || !gst_video_info_from_caps (new_vip, caps)) + if (!caps) goto error_no_caps; + if (!gst_video_info_from_caps (new_vip, caps)) + goto error_invalid_caps; use_dmabuf_memory = gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_DMABUF_MEMORY); @@ -218,6 +220,11 @@ error_no_caps: GST_ERROR_OBJECT (pool, "no valid caps in config"); return FALSE; } +error_invalid_caps: + { + GST_ERROR_OBJECT (pool, "invalid caps %" GST_PTR_FORMAT, caps); + return FALSE; + } error_create_allocator: { GST_ERROR_OBJECT (pool, "failed to create GstVaapiVideoAllocator object"); From 9667f0e4728cbfad6113668011e7b210050adc95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 13 May 2016 13:14:23 +0200 Subject: [PATCH 2405/3781] plugins: destroy pool earlier if non-vaapi If the offered pool in decide_allocation() vmethod doesn't have the VAAPI_VIDEO_META option, it is destroyed immediatly and the pointer cleared, so it could be created later. --- gst/vaapi/gstvaapipluginbase.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 000e326e52..f7fc2eed9c 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -719,6 +719,14 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, not provide a correct propose_allocation() implementation */ has_video_alignment = gst_buffer_pool_has_option (pool, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + + /* GstVaapiVideoMeta is mandatory, and this implies VA surface memory */ + if (!gst_buffer_pool_has_option (pool, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) { + GST_INFO_OBJECT (plugin, "ignoring non-VAAPI pool: %" GST_PTR_FORMAT, + pool); + g_clear_object (&pool); + } } } else { pool = NULL; @@ -726,13 +734,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, min = max = 0; } - /* GstVaapiVideoMeta is mandatory, and this implies VA surface memory */ - if (!pool || !gst_buffer_pool_has_option (pool, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) { - GST_INFO_OBJECT (plugin, "%s. Making a new pool", pool == NULL ? "No pool" : - "Pool hasn't GstVaapiVideoMeta"); - if (pool) - gst_object_unref (pool); + if (!pool) { pool = gst_vaapi_video_buffer_pool_new (plugin->display); if (!pool) goto error_create_pool; From c9f600686531049c3f17ea0a4db745c8bd8d547c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 24 May 2016 13:39:25 +0200 Subject: [PATCH 2406/3781] plugins: avoid to get/set pool config twice This patch is a bit of optimization, since the bufferpool configuration is get when the pool is created. Hence, we only need to request it when the pool from the allocation query is reused. --- gst/vaapi/gstvaapipluginbase.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index f7fc2eed9c..90e935c785 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -734,6 +734,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, min = max = 0; } + config = NULL; if (!pool) { pool = gst_vaapi_video_buffer_pool_new (plugin->display); if (!pool) @@ -743,11 +744,10 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gst_buffer_pool_config_set_params (config, caps, size, min, max); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - if (!gst_buffer_pool_set_config (pool, config)) - goto error_config_failed; } - config = gst_buffer_pool_get_config (pool); + if (!config) + config = gst_buffer_pool_get_config (pool); /* Check whether GstVideoMeta, or GstVideoAlignment, is needed (raw video) */ if (has_video_meta) { From b27ddd8036b82567ae84f6e4ab225a1332b50b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 24 May 2016 16:22:24 +0200 Subject: [PATCH 2407/3781] plugins: no sinkpad bufferpool when decoder Right now, the decoders create a buffer pool for their sink pad which is not used at all, because the decoders have never proposed it to upstream. This patch avoids the buffer pool instantiating when the element inherits from the GstVideoDecoder class. --- gst/vaapi/gstvaapipluginbase.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 90e935c785..66ef97c6ba 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -489,6 +489,10 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) GstVideoInfo vi; gboolean need_pool; + /* video decoders don't use a buffer pool in the sink pad */ + if (GST_IS_VIDEO_DECODER (plugin)) + return TRUE; + if (!gst_vaapi_plugin_base_ensure_display (plugin)) return FALSE; From 2fc855b134949c685e19f163a4ed5a36c7bdbd6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 24 May 2016 16:29:33 +0200 Subject: [PATCH 2408/3781] plugins: deactivate buffer pool before unref This buffer pool may still be processing buffers when a caps renegotiation is done. This one-liner patch deactivates the pool to drain it before it de-allocation. --- gst/vaapi/gstvaapipluginbase.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 66ef97c6ba..d61c9a8453 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -503,6 +503,7 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) gst_structure_free (config); if (!need_pool) return TRUE; + gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, FALSE); g_clear_object (&plugin->sinkpad_buffer_pool); plugin->sinkpad_buffer_size = 0; } From 789afaccfbd9214c1070f39243db037c64763323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 23 May 2016 22:49:11 +0200 Subject: [PATCH 2409/3781] plugins: add gst_vaapi_buffer_pool_caps_is_equal() This is a helper function to improve the readability of ensure_sinkpad_buffer_pool(). It makes clearer when the buffer pool needs to be re-instantiated. --- gst/vaapi/gstvaapipluginbase.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index d61c9a8453..1d77456323 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -470,6 +470,23 @@ has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad) return is_dmabuf_capable; } +static gboolean +gst_vaapi_buffer_pool_caps_is_equal (GstBufferPool * pool, GstCaps * newcaps) +{ + GstStructure *config; + GstCaps *caps; + gboolean ret; + + caps = NULL; + ret = FALSE; + config = gst_buffer_pool_get_config (pool); + if (gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) + ret = gst_caps_is_equal (newcaps, caps); + gst_structure_free (config); + + return ret; +} + /** * ensure_sinkpad_buffer_pool: * @plugin: a #GstVaapiPluginBase @@ -484,10 +501,8 @@ static gboolean ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) { GstBufferPool *pool; - GstCaps *pool_caps; GstStructure *config; GstVideoInfo vi; - gboolean need_pool; /* video decoders don't use a buffer pool in the sink pad */ if (GST_IS_VIDEO_DECODER (plugin)) @@ -497,11 +512,7 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) return FALSE; if (plugin->sinkpad_buffer_pool) { - config = gst_buffer_pool_get_config (plugin->sinkpad_buffer_pool); - gst_buffer_pool_config_get_params (config, &pool_caps, NULL, NULL, NULL); - need_pool = !gst_caps_is_equal (caps, pool_caps); - gst_structure_free (config); - if (!need_pool) + if (gst_vaapi_buffer_pool_caps_is_equal (plugin->sinkpad_buffer_pool, caps)) return TRUE; gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, FALSE); g_clear_object (&plugin->sinkpad_buffer_pool); From 9f46a94d2af146ddcb314855112a049fd06d8b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 25 May 2016 10:36:33 +0200 Subject: [PATCH 2410/3781] vaapivideobufferpool: remove GL_TEXTURE_UPLOAD_META Since gstreamer-vaapi is coupled with gstreamer releases, there is no need to keep compatibility definition. This patch removes the definition of GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META since it is in gst-plugins-base version 1.2.2 --- gst/vaapi/gstvaapivideobufferpool.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index 1ff3f57b7a..07b28a7a45 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -54,21 +54,6 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; #define GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META \ "GstBufferPoolOptionVaapiVideoMeta" -/** - * - * GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META: - * - * An option that can be activated on bufferpool to request gl texture - * upload on buffers from the pool. - * - * When this option is enabled on the bufferpool, - * #GST_BUFFER_POOL_OPTION_VIDEO_META should also be enabled. - */ -#ifndef GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META -#define GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META \ - "GstBufferPoolOptionVideoGLTextureUploadMeta" -#endif - /** * GST_BUFFER_POOL_OPTION_DMABUF_MEMORY: * From 101e31df83363ba89221ca1b87287509c54ad19a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 25 May 2016 12:28:48 +0200 Subject: [PATCH 2411/3781] plugins: remove unused header Remove the include of gst/allocators/allocators.h since it is not used. --- gst/vaapi/gstvaapipluginbase.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 1d77456323..906891d3bd 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -30,7 +30,6 @@ #include "gstvaapivideocontext.h" #include "gstvaapivideometa.h" #include "gstvaapivideobufferpool.h" -#include /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) From 372a03a9e38acbf435eb80bf31d9a9844069e504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 May 2016 11:41:25 +0200 Subject: [PATCH 2412/3781] gstvaapisurface_drm: fix code-style --- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index 371f05dc09..f4364a3315 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -36,14 +36,13 @@ gst_vaapi_surface_get_drm_buf_handle (GstVaapiSurface * surface, guint type) if (!image) goto error_derive_image; - if (type == GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF) - proxy = - gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), - image->internal_image.buf, type, NULL, NULL); - else - proxy = - gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), - image->internal_image.buf, type, gst_vaapi_object_unref, image); + if (type == GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF) { + proxy = gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), + image->internal_image.buf, type, NULL, NULL); + } else { + proxy = gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), + image->internal_image.buf, type, gst_vaapi_object_unref, image); + } if (!proxy) goto error_alloc_export_buffer; From 765a53d4c27865aafa73ecbe17b654a938980413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 May 2016 11:42:32 +0200 Subject: [PATCH 2413/3781] gstvaapisurface_drm: fix internal documentation --- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index f4364a3315..121b708772 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -159,7 +159,7 @@ gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, } /** - * gst_vaapi_surface_new_with_dma_buf_handle: + * gst_vaapi_surface_new_with_gem_buf_handle: * @display: a #GstVaapiDisplay * @name: the DRM GEM buffer name * @size: the underlying DRM buffer size @@ -174,7 +174,7 @@ gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, * handle. * * Return value: the newly allocated #GstVaapiSurface object, or %NULL - * if creation from DRM PRIME fd failed, or is not supported + * if creation from GEM @name failed, or is not supported */ GstVaapiSurface * gst_vaapi_surface_new_with_gem_buf_handle (GstVaapiDisplay * display, From 266650054aa365141e4e7a26bcca9514671ce810 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 30 May 2016 11:22:35 +0300 Subject: [PATCH 2414/3781] build: Add check for VP9 encode API support in libva https://bugzilla.gnome.org/show_bug.cgi?id=766048 --- configure.ac | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/configure.ac b/configure.ac index 71356f6902..628ee471a8 100644 --- a/configure.ac +++ b/configure.ac @@ -725,6 +725,8 @@ fi USE_JPEG_ENCODER=0 USE_VP8_ENCODER=0 USE_H265_ENCODER=0 +USE_VP9_ENCODER=0 + if test $USE_ENCODERS -eq 1; then dnl Check for JPEG Encoding API (0.37.0+) AC_CHECK_HEADERS([va/va_enc_jpeg.h], [], [], @@ -828,6 +830,41 @@ VAQMatrixBufferHEVC q_matrix; LIBS="$saved_LIBS" ]) AS_IF([test "x$ac_cv_have_hevc_encoding_api" = "xyes"], [USE_H265_ENCODER=1]) + + dnl Check for VP9 Encoding API + AC_CHECK_HEADERS([va/va_enc_vp9.h], [], [], + [ +#include + ]) + AC_CACHE_CHECK([for VP9 encoding API], + [ac_cv_have_vp9_encoding_api], + [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ +#include +#ifdef HAVE_VA_VA_ENC_VP9_H +# include +#endif + ]], + [[ +VAEncSequenceParameterBufferVP9 seq_param; +VAEncPictureParameterBufferVP9 pic_param; +VAEncSegParamVP9 seg_param; +VAEncMiscParameterTypeVP9PerSegmantParam misc_param; + ]]) + ], + [ac_cv_have_vp9_encoding_api="yes"], + [ac_cv_have_vp9_encoding_api="no"]) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" + ]) + AS_IF([test "x$ac_cv_have_vp9_encoding_api" = "xyes"], [USE_VP9_ENCODER=1]) fi dnl VA/Wayland API @@ -928,6 +965,10 @@ AC_DEFINE_UNQUOTED([USE_H265_ENCODER], [$USE_H265_ENCODER], [Defined to 1 if H265 encoder is used]) AM_CONDITIONAL([USE_H265_ENCODER], [test $USE_H265_ENCODER -eq 1]) +AC_DEFINE_UNQUOTED([USE_VP9_ENCODER], [$USE_VP9_ENCODER], + [Defined to 1 if VP9 encoder is used]) +AM_CONDITIONAL([USE_VP9_ENCODER], [test $USE_VP9_ENCODER -eq 1]) + AC_DEFINE_UNQUOTED([USE_VA_VPP], [$USE_VA_VPP], [Defined to 1 if video post-processing is used]) AM_CONDITIONAL([USE_VA_VPP], [test $USE_VA_VPP -eq 1]) From 221fb9351a9563a221bf4981cc0223627c252658 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 30 May 2016 11:23:12 +0300 Subject: [PATCH 2415/3781] Add vp9 encoder support in libgstvaapi https://bugzilla.gnome.org/show_bug.cgi?id=766048 --- gst-libs/gst/vaapi/Makefile.am | 9 + gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 431 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 56 +++ 3 files changed, 496 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_vp9.c create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_vp9.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index eba5445bfa..56388a6a7e 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -232,6 +232,13 @@ libgstvaapi_source_c += $(libgstvaapi_h265enc_source_c) libgstvaapi_source_h += $(libgstvaapi_h265enc_source_h) endif +libgstvaapi_vp9enc_source_c = gstvaapiencoder_vp9.c +libgstvaapi_vp9enc_source_h = gstvaapiencoder_vp9.h +if USE_VP9_ENCODER +libgstvaapi_source_c += $(libgstvaapi_vp9enc_source_c) +libgstvaapi_source_h += $(libgstvaapi_vp9enc_source_h) +endif + libgstvaapi_drm_source_c = \ gstvaapidisplay_drm.c \ gstvaapiwindow_drm.c \ @@ -549,6 +556,8 @@ EXTRA_DIST += \ $(libgstvaapi_vp8enc_source_c) \ $(libgstvaapi_h265enc_source_h) \ $(libgstvaapi_h265enc_source_c) \ + $(libgstvaapi_vp9enc_source_h) \ + $(libgstvaapi_vp9enc_source_c) \ $(libgstvaapi_egl_source_c) \ $(libgstvaapi_egl_source_h) \ $(libgstvaapi_egl_source_priv_h) \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c new file mode 100644 index 0000000000..a625fcc1f1 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -0,0 +1,431 @@ +/* + * gstvaapiencoder_vp9.c - VP9 encoder + * + * Copyright (C) 2016 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 +#include +#include +#include +#include "gstvaapicompat.h" +#include "gstvaapiencoder_priv.h" +#include "gstvaapiencoder_vp9.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)) + +/* 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 + +/* ------------------------------------------------------------------------- */ +/* --- VP9 Encoder --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENCODER_VP9_CAST(encoder) \ + ((GstVaapiEncoderVP9 *)(encoder)) + +struct _GstVaapiEncoderVP9 +{ + GstVaapiEncoder parent_instance; + GstVaapiProfile profile; + guint frame_num; + /* reference list */ + GstVaapiSurfaceProxy *ref_list[GST_VP9_REF_FRAMES]; +}; + +/* Derives the profile that suits best to the configuration */ +static GstVaapiEncoderStatus +ensure_profile (GstVaapiEncoderVP9 * encoder) +{ + /* Always start from "simple" profile for maximum compatibility */ + encoder->profile = GST_VAAPI_PROFILE_VP9_0; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +/* Derives the profile supported by the underlying hardware */ +static gboolean +ensure_hw_profile (GstVaapiEncoderVP9 * 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 (0x%08x)", encoder->profile); + return FALSE; + } +} + +static GstVaapiEncoderStatus +set_context_info (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderVP9 *encoder = GST_VAAPI_ENCODER_VP9_CAST (base_encoder); + GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); + + /*Fixme: Maximum sizes for common headers (in bytes) */ + + 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. */ + base_encoder->codedbuf_size = GST_ROUND_UP_16 (vip->width) * + GST_ROUND_UP_16 (vip->height) * 3 / 2; + + 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)); + + /* Fixme: check the requirement of 64 byte alignment ? */ + seq_param->max_frame_width = 8192; + seq_param->max_frame_height = 8192; + + /* 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; + + 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; + +error: + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; +} + +static gboolean +fill_picture (GstVaapiEncoderVP9 * encoder, + GstVaapiEncPicture * picture, + GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) +{ + VAEncPictureParameterBufferVP9 *const pic_param = picture->param; + guint i; + + memset (pic_param, 0, sizeof (VAEncPictureParameterBufferVP9)); + + pic_param->reconstructed_frame = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); + pic_param->coded_buf = GST_VAAPI_OBJECT_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; + + pic_param->ref_flags.bits.ref_last_idx = 0; + pic_param->ref_flags.bits.ref_gf_idx = 1; + pic_param->ref_flags.bits.ref_arf_idx = 2; + + /* updating the ref_slot[0] with current frame */ + pic_param->refresh_frame_flags = 0x01; + } + + /* Fixme: Add tuning options for ac/dc qindex */ + /* Assiging some default values for now */ + pic_param->luma_ac_qindex = 60; + pic_param->luma_dc_qindex_delta = 1; + pic_param->chroma_ac_qindex_delta = 1; + pic_param->chroma_dc_qindex_delta = 1; + /* Fixme: Add properties to control sharness and loopfilter level */ + pic_param->filter_level = 0; + pic_param->sharpness_level = 0; + + 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++) { + if (encoder->ref_list[i]) + gst_vaapi_surface_proxy_unref (encoder->ref_list[i]); + encoder->ref_list[i] = gst_vaapi_surface_proxy_ref (ref); + } + gst_vaapi_surface_proxy_unref (ref); + return; + } + + gst_vaapi_surface_proxy_unref (encoder->ref_list[0]); + encoder->ref_list[0] = ref; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_vp9_encode (GstVaapiEncoder * base_encoder, + GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) +{ + GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9_CAST (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_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; +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) +{ + 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_CAST (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_CAST (base_encoder); + GstVaapiEncoderStatus status; + + status = ensure_profile (encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + + return set_context_info (base_encoder); +} + +static gboolean +gst_vaapi_encoder_vp9_init (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9_CAST (base_encoder); + + encoder->frame_num = 0; + memset (encoder->ref_list, 0, G_N_ELEMENTS (encoder->ref_list)); + return TRUE; +} + +static void +gst_vaapi_encoder_vp9_finalize (GstVaapiEncoder * base_encoder) +{ +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_vp9_set_property (GstVaapiEncoder * base_encoder, + gint prop_id, const GValue * value) +{ + switch (prop_id) { + default: + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (VP9); + +static inline const GstVaapiEncoderClass * +gst_vaapi_encoder_vp9_class (void) +{ + static const GstVaapiEncoderClass GstVaapiEncoderVP9Class = { + GST_VAAPI_ENCODER_CLASS_INIT (VP9, vp9), + .set_property = gst_vaapi_encoder_vp9_set_property, + }; + return &GstVaapiEncoderVP9Class; +} + +/** + * 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 gst_vaapi_encoder_new (gst_vaapi_encoder_vp9_class (), display); +} + +/** + * gst_vaapi_encoder_vp9_get_default_properties: + * + * Determines the set of common and vp9 specific encoder properties. + * The caller owns an extra reference to the resulting array of + * #GstVaapiEncoderPropInfo elements, so it shall be released with + * g_ptr_array_unref() after usage. + * + * Return value: the set of encoder properties for #GstVaapiEncoderVP9, + * or %NULL if an error occurred. + */ +GPtrArray * +gst_vaapi_encoder_vp9_get_default_properties (void) +{ + const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_vp9_class (); + GPtrArray *props; + + props = gst_vaapi_encoder_properties_get_default (klass); + if (!props) + return NULL; + + return props; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h new file mode 100644 index 0000000000..560cbe7ac3 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -0,0 +1,56 @@ +/* + * gstvaapiencoder_vp9.h VP9 encoder + * + * Copyright (C) 2016 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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 + +G_BEGIN_DECLS + +#define GST_VAAPI_ENCODER_VP9(encoder) \ + ((GstVaapiEncoderVP9 *) (encoder)) + +typedef struct _GstVaapiEncoderVP9 GstVaapiEncoderVP9; + +/** + * GstVaapiEncoderVP9Prop: + * @GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL: Loop Filter Level(uint). + * @GST_VAAPI_ENCODER_VP9_PROP_LOOP_SHARPNESS_LEVEL: Sharpness Level(uint). + * @GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX: Quantization table index for luma AC(uint). + * + * The set of VP9 encoder specific configurable properties. + */ +typedef enum { + GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL = -1, + GST_VAAPI_ENCODER_VP9_PROP_SHARPNESS_LEVEL = -2, + GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX = -3 +} GstVaapiEncoderVP9Prop; + +GstVaapiEncoder * +gst_vaapi_encoder_vp9_new (GstVaapiDisplay * display); + +GPtrArray * +gst_vaapi_encoder_vp9_get_default_properties (void); + +G_END_DECLS +#endif /*GST_VAAPI_ENCODER_VP9_H */ From 4464d81b6a300db3c6cc77d37557dc39d3d2195d Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 30 May 2016 11:24:14 +0300 Subject: [PATCH 2416/3781] Add vp9 encode element to "vaapi" plugin https://bugzilla.gnome.org/show_bug.cgi?id=766048 --- gst/vaapi/Makefile.am | 10 +- gst/vaapi/gstvaapi.c | 9 +- gst/vaapi/gstvaapiencode_vp9.c | 177 +++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode_vp9.h | 69 +++++++++++++ 4 files changed, 263 insertions(+), 2 deletions(-) create mode 100644 gst/vaapi/gstvaapiencode_vp9.c create mode 100644 gst/vaapi/gstvaapiencode_vp9.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 3e54a41d18..016b3d92b8 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -105,7 +105,6 @@ libgstvaapi_source_c += $(libgstvaapi_vp8enc_source_c) libgstvaapi_source_h += $(libgstvaapi_vp8enc_source_h) endif - libgstvaapi_h265enc_source_c = gstvaapiencode_h265.c libgstvaapi_h265enc_source_h = gstvaapiencode_h265.h if USE_H265_ENCODER @@ -113,6 +112,13 @@ libgstvaapi_source_c += $(libgstvaapi_h265enc_source_c) libgstvaapi_source_h += $(libgstvaapi_h265enc_source_h) endif +libgstvaapi_vp9enc_source_c = gstvaapiencode_vp9.c +libgstvaapi_vp9enc_source_h = gstvaapiencode_vp9.h +if USE_VP9_ENCODER +libgstvaapi_source_c += $(libgstvaapi_vp9enc_source_c) +libgstvaapi_source_h += $(libgstvaapi_vp9enc_source_h) +endif + libgstvaapi_la_SOURCES = $(libgstvaapi_source_c) noinst_HEADERS = $(libgstvaapi_source_h) @@ -150,6 +156,8 @@ EXTRA_DIST = \ $(libgstvaapi_vp8enc_source_h) \ $(libgstvaapi_h265enc_source_c) \ $(libgstvaapi_h265enc_source_h) \ + $(libgstvaapi_vp9enc_source_c) \ + $(libgstvaapi_vp9enc_source_h) \ $(libgstvaapi_egl_source_c) \ $(libgstvaapi_egl_source_h) \ $(libgstvaapi_1_2p_source_c) \ diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index aabddc3590..396c7d0142 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -46,6 +46,10 @@ #include "gstvaapiencode_h265.h" #endif +#if USE_VP9_ENCODER +#include "gstvaapiencode_vp9.h" +#endif + #define PLUGIN_NAME "vaapi" #define PLUGIN_DESC "VA-API based elements" #define PLUGIN_LICENSE "LGPL" @@ -73,11 +77,14 @@ plugin_init (GstPlugin * plugin) gst_element_register (plugin, "vaapivp8enc", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_VP8); #endif - #if USE_H265_ENCODER gst_element_register (plugin, "vaapih265enc", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_H265); #endif +#if USE_VP9_ENCODER + gst_element_register (plugin, "vaapivp9enc", + GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_VP9); +#endif gst_element_register (plugin, "vaapidecodebin", GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c new file mode 100644 index 0000000000..74767575a2 --- /dev/null +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -0,0 +1,177 @@ +/* + * gstvaapiencode_vp9.c - VA-API VP9 encoder + * + * Copyright (C) 2016 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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:element-vaapivp9enc + * @short_description: A VA-API based VP9 video encoder + * + * Encodes raw video streams into VP9 bitstreams. + * + * + * Example launch line + * |[ + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapivp9enc ! matroskamux ! filesink location=test.mkv + * ]| + * + */ + +#include "gstcompat.h" +#include +#include +#include "gstvaapiencode_vp9.h" +#include "gstvaapipluginutil.h" +#include "gstvaapivideomemory.h" + +#define GST_PLUGIN_NAME "vaapivp9enc" +#define GST_PLUGIN_DESC "A VA-API based VP9 video encoder" + +GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp9_encode_debug); +#define GST_CAT_DEFAULT gst_vaapi_vp9_encode_debug + +#define GST_CODEC_CAPS \ + "video/x-vp9" + +/* *INDENT-OFF* */ +static const char gst_vaapiencode_vp9_sink_caps_str[] = + GST_VAAPI_MAKE_SURFACE_CAPS ", " + GST_CAPS_INTERLACED_FALSE "; " + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static const char gst_vaapiencode_vp9_src_caps_str[] = + GST_CODEC_CAPS; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapiencode_vp9_sink_factory = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_vp9_sink_caps_str)); +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapiencode_vp9_src_factory = + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_vp9_src_caps_str)); +/* *INDENT-ON* */ + +/* vp9 encode */ +G_DEFINE_TYPE (GstVaapiEncodeVP9, gst_vaapiencode_vp9, GST_TYPE_VAAPIENCODE); + +static void +gst_vaapiencode_vp9_init (GstVaapiEncodeVP9 * encode) +{ + gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); +} + +static void +gst_vaapiencode_vp9_finalize (GObject * object) +{ + G_OBJECT_CLASS (gst_vaapiencode_vp9_parent_class)->finalize (object); +} + +static void +gst_vaapiencode_vp9_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + default: + if (!encode_class->set_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapiencode_vp9_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + default: + if (!encode_class->get_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstCaps * +gst_vaapiencode_vp9_get_caps (GstVaapiEncode * base_encode) +{ + GstCaps *caps; + + caps = gst_caps_from_string (GST_CODEC_CAPS); + + return caps; +} + +static GstVaapiEncoder * +gst_vaapiencode_vp9_alloc_encoder (GstVaapiEncode * base, + GstVaapiDisplay * display) +{ + return gst_vaapi_encoder_vp9_new (display); +} + +static void +gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_vaapi_vp9_encode_debug, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + object_class->finalize = gst_vaapiencode_vp9_finalize; + object_class->set_property = gst_vaapiencode_vp9_set_property; + object_class->get_property = gst_vaapiencode_vp9_get_property; + + encode_class->get_properties = gst_vaapi_encoder_vp9_get_default_properties; + encode_class->get_caps = gst_vaapiencode_vp9_get_caps; + encode_class->alloc_encoder = gst_vaapiencode_vp9_alloc_encoder; + + gst_element_class_set_static_metadata (element_class, + "VA-API VP9 encoder", + "Codec/Encoder/Video", + GST_PLUGIN_DESC, + "Sreerenj Balachandran "); + + /* sink pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_vp9_sink_factory)); + + /* src pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_vp9_src_factory)); + + gst_vaapiencode_class_init_properties (encode_class); +} diff --git a/gst/vaapi/gstvaapiencode_vp9.h b/gst/vaapi/gstvaapiencode_vp9.h new file mode 100644 index 0000000000..09c1fe2a67 --- /dev/null +++ b/gst/vaapi/gstvaapiencode_vp9.h @@ -0,0 +1,69 @@ +/* + * gstvaapiencode_vp9.h - VA-API VP9 encoder + * + * Copyright (C) 2016 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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_VAAPIENCODE_VP9_H +#define GST_VAAPIENCODE_VP9_H + +#include +#include "gstvaapiencode.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIENCODE_VP9 \ + (gst_vaapiencode_vp9_get_type ()) +#define GST_VAAPIENCODE_VP9_CAST(obj) \ + ((GstVaapiEncodeVP9 *)(obj)) +#define GST_VAAPIENCODE_VP9(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPIENCODE_VP9, \ + GstVaapiEncodeVP9)) +#define GST_VAAPIENCODE_VP9_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPIENCODE_VP9, \ + GstVaapiEncodeVP9Class)) +#define GST_VAAPIENCODE_VP9_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPIENCODE_VP9, \ + GstVaapiEncodeVP9Class)) +#define GST_IS_VAAPIENCODE_VP9(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_VP9)) +#define GST_IS_VAAPIENCODE_VP9_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_VP9)) + +typedef struct _GstVaapiEncodeVP9 GstVaapiEncodeVP9; +typedef struct _GstVaapiEncodeVP9Class GstVaapiEncodeVP9Class; + +struct _GstVaapiEncodeVP9 +{ + /*< private >*/ + GstVaapiEncode parent_instance; +}; + +struct _GstVaapiEncodeVP9Class +{ + /*< private >*/ + GstVaapiEncodeClass parent_class; +}; + +GType +gst_vaapiencode_vp9_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GST_VAAPIENCODE_VP9_H */ From 1606d4bd779701c9450a00bd6143441da43f8efe Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 30 May 2016 11:25:03 +0300 Subject: [PATCH 2417/3781] encoder: vp9: Add more propertis for tuning encode quality Added three tuning properties: 1: filter_level 2: sharpness_level 3: luma ac quant-table index https://bugzilla.gnome.org/show_bug.cgi?id=766048 --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 55 ++++++++++++++++++++---- gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 2 +- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index a625fcc1f1..be47aa5321 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -49,9 +49,9 @@ #define SUPPORTED_PACKED_HEADERS \ (VA_ENC_PACKED_HEADER_NONE) -#define DEFAULT_LOOP_FILTER_LEVEL 0 +#define DEFAULT_LOOP_FILTER_LEVEL 10 #define DEFAULT_SHARPNESS_LEVEL 0 -#define DEFAULT_YAC_QI 40 +#define DEFAULT_YAC_QINDEX 60 /* ------------------------------------------------------------------------- */ /* --- VP9 Encoder --- */ @@ -64,6 +64,9 @@ struct _GstVaapiEncoderVP9 { GstVaapiEncoder parent_instance; GstVaapiProfile profile; + guint loop_filter_level; + guint sharpness_level; + guint yac_qi; guint frame_num; /* reference list */ GstVaapiSurfaceProxy *ref_list[GST_VP9_REF_FRAMES]; @@ -227,15 +230,12 @@ fill_picture (GstVaapiEncoderVP9 * encoder, pic_param->refresh_frame_flags = 0x01; } - /* Fixme: Add tuning options for ac/dc qindex */ - /* Assiging some default values for now */ - pic_param->luma_ac_qindex = 60; + 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; - /* Fixme: Add properties to control sharness and loopfilter level */ - pic_param->filter_level = 0; - pic_param->sharpness_level = 0; + pic_param->filter_level = encoder->loop_filter_level; + pic_param->sharpness_level = encoder->sharpness_level; return TRUE; } @@ -360,6 +360,9 @@ gst_vaapi_encoder_vp9_init (GstVaapiEncoder * base_encoder) GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9_CAST (base_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; memset (encoder->ref_list, 0, G_N_ELEMENTS (encoder->ref_list)); return TRUE; } @@ -373,7 +376,18 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_vp9_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { + GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9_CAST (base_encoder); + switch (prop_id) { + case GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL: + encoder->loop_filter_level = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_VP9_PROP_SHARPNESS_LEVEL: + encoder->sharpness_level = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX: + encoder->yac_qi = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -427,5 +441,30 @@ gst_vaapi_encoder_vp9_get_default_properties (void) if (!props) return NULL; + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_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)); + + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_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)); + + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_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)); + + return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h index 560cbe7ac3..1f615591dc 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -36,7 +36,7 @@ typedef struct _GstVaapiEncoderVP9 GstVaapiEncoderVP9; * GstVaapiEncoderVP9Prop: * @GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL: Loop Filter Level(uint). * @GST_VAAPI_ENCODER_VP9_PROP_LOOP_SHARPNESS_LEVEL: Sharpness Level(uint). - * @GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX: Quantization table index for luma AC(uint). + * @GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX: Quantization table index for luma AC * * The set of VP9 encoder specific configurable properties. */ From 5dc63dbf5a0efa8d8e20839ebf1a64b6bd48d787 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 30 May 2016 11:25:52 +0300 Subject: [PATCH 2418/3781] encoder: vp9: Define Max frame width and height https://bugzilla.gnome.org/show_bug.cgi?id=766048 --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index be47aa5321..c06046bd26 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -53,6 +53,9 @@ #define DEFAULT_SHARPNESS_LEVEL 0 #define DEFAULT_YAC_QINDEX 60 +#define MAX_FRAME_WIDTH 4096 +#define MAX_FRAME_HEIGHT 4096 + /* ------------------------------------------------------------------------- */ /* --- VP9 Encoder --- */ /* ------------------------------------------------------------------------- */ @@ -142,9 +145,8 @@ fill_sequence (GstVaapiEncoderVP9 * encoder, GstVaapiEncSequence * sequence) memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferVP9)); - /* Fixme: check the requirement of 64 byte alignment ? */ - seq_param->max_frame_width = 8192; - seq_param->max_frame_height = 8192; + 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; From 76c2e5fdb5095e67067572725897faa7b833d76a Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 30 May 2016 11:30:40 +0300 Subject: [PATCH 2419/3781] encoder: vp9: Add simple algorithms for reference picture selection Added two modes(as properties) for reference picture selection: ref-mode-0: AltRef and GoldRef pointing to the recent keyframe and LastRef is pointing to the previous frame. ref-mode-1: Previous frame (n) as LastRef , n-1 th frame as GoldRef and n-2 th frame as AltRef https://bugzilla.gnome.org/show_bug.cgi?id=766048 --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 114 +++++++++++++++++++---- gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 4 +- 2 files changed, 101 insertions(+), 17 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index c06046bd26..6006f682db 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -56,6 +56,33 @@ #define MAX_FRAME_WIDTH 4096 #define MAX_FRAME_HEIGHT 4096 +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"} + }; + + gtype = g_enum_register_static ("GstVaapiEncoderVP9RefPicMode", values); + } + return gtype; +} + + /* ------------------------------------------------------------------------- */ /* --- VP9 Encoder --- */ /* ------------------------------------------------------------------------- */ @@ -70,9 +97,10 @@ struct _GstVaapiEncoderVP9 guint loop_filter_level; guint sharpness_level; guint yac_qi; + guint ref_pic_mode; guint frame_num; - /* reference list */ - GstVaapiSurfaceProxy *ref_list[GST_VP9_REF_FRAMES]; + GstVaapiSurfaceProxy *ref_list[GST_VP9_REF_FRAMES]; /* reference list */ + guint ref_list_idx; /* next free slot in ref_list */ }; /* Derives the profile that suits best to the configuration */ @@ -122,13 +150,14 @@ set_context_info (GstVaapiEncoder * base_encoder) { GstVaapiEncoderVP9 *encoder = GST_VAAPI_ENCODER_VP9_CAST (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) */ if (!ensure_hw_profile (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - base_encoder->num_ref_frames = 3; + 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) * @@ -183,13 +212,38 @@ error: return FALSE; } +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_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; + guint i, last_idx = 0, gf_idx = 0, arf_idx = 0; + guint8 refresh_frame_flags = 0; memset (pic_param, 0, sizeof (VAEncPictureParameterBufferVP9)); @@ -224,12 +278,13 @@ fill_picture (GstVaapiEncoderVP9 * encoder, * for prediction */ pic_param->ref_flags.bits.ref_frame_ctrl_l0 = 0x7; - pic_param->ref_flags.bits.ref_last_idx = 0; - pic_param->ref_flags.bits.ref_gf_idx = 1; - pic_param->ref_flags.bits.ref_arf_idx = 2; + get_ref_indices (encoder->ref_pic_mode, encoder->ref_list_idx, &last_idx, + &gf_idx, &arf_idx, &refresh_frame_flags); - /* updating the ref_slot[0] with current frame */ - pic_param->refresh_frame_flags = 0x01; + 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; } pic_param->luma_ac_qindex = encoder->yac_qi; @@ -262,17 +317,29 @@ update_ref_list (GstVaapiEncoderVP9 * encoder, GstVaapiEncPicture * picture, guint i; if (picture->type == GST_VAAPI_PICTURE_TYPE_I) { - for (i = 0; i < G_N_ELEMENTS (encoder->ref_list); i++) { - if (encoder->ref_list[i]) - gst_vaapi_surface_proxy_unref (encoder->ref_list[i]); - encoder->ref_list[i] = gst_vaapi_surface_proxy_ref (ref); - } + 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; } - gst_vaapi_surface_proxy_unref (encoder->ref_list[0]); - encoder->ref_list[0] = ref; + 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: + gst_vaapi_surface_proxy_replace (&encoder-> + ref_list[encoder->ref_list_idx], 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 @@ -365,7 +432,10 @@ gst_vaapi_encoder_vp9_init (GstVaapiEncoder * base_encoder) encoder->loop_filter_level = DEFAULT_LOOP_FILTER_LEVEL; encoder->sharpness_level = DEFAULT_SHARPNESS_LEVEL; encoder->yac_qi = DEFAULT_YAC_QINDEX; + memset (encoder->ref_list, 0, G_N_ELEMENTS (encoder->ref_list)); + encoder->ref_list_idx = 0; + return TRUE; } @@ -390,6 +460,9 @@ gst_vaapi_encoder_vp9_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX: encoder->yac_qi = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE: + encoder->ref_pic_mode = g_value_get_enum (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -467,6 +540,15 @@ gst_vaapi_encoder_vp9_get_default_properties (void) 0, 255, DEFAULT_YAC_QINDEX, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_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)); + return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h index 1f615591dc..2ddcbd40d6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -37,13 +37,15 @@ typedef struct _GstVaapiEncoderVP9 GstVaapiEncoderVP9; * @GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL: Loop Filter Level(uint). * @GST_VAAPI_ENCODER_VP9_PROP_LOOP_SHARPNESS_LEVEL: Sharpness Level(uint). * @GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX: Quantization table index for luma AC + * @GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE: Reference picute selection modes * * The set of VP9 encoder specific configurable properties. */ typedef enum { GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL = -1, GST_VAAPI_ENCODER_VP9_PROP_SHARPNESS_LEVEL = -2, - GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX = -3 + GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX = -3, + GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE = -4 } GstVaapiEncoderVP9Prop; GstVaapiEncoder * From 4791e9f2ea3537f2b9f7b36b1f79d87c3e73f08f Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Tue, 7 Jun 2016 14:19:50 -0700 Subject: [PATCH 2420/3781] vaapipostproc: add postproc_lock to protect data members Add a mutex to postproc to protect concurrent access to data members. Previously set_caps() could release the allowed_srcpad_caps while transform_caps was in the middle of using it. Signed-off-by: Scott D Phillips https://bugzilla.gnome.org/show_bug.cgi?id=766940 --- gst/vaapi/gstvaapipostproc.c | 34 ++++++++++++++++++++++++++-------- gst/vaapi/gstvaapipostproc.h | 1 + 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 9f2ff5bfb7..0d2b8720a0 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1024,13 +1024,16 @@ static GstCaps * gst_vaapipostproc_transform_caps (GstBaseTransform * trans, GstPadDirection direction, GstCaps * caps, GstCaps * filter) { + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); GstCaps *out_caps; GST_DEBUG_OBJECT (trans, "Transforming caps %" GST_PTR_FORMAT " in direction %s", caps, (direction == GST_PAD_SINK) ? "sink" : "src"); + g_mutex_lock (&postproc->postproc_lock); caps = gst_vaapipostproc_transform_caps_impl (trans, direction, caps); + g_mutex_unlock (&postproc->postproc_lock); if (caps && filter) { out_caps = gst_caps_intersect_full (caps, filter, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (caps); @@ -1059,8 +1062,10 @@ gst_vaapipostproc_fixate_caps (GstBaseTransform * trans, goto done; } + g_mutex_lock (&postproc->postproc_lock); if ((outcaps = gst_vaapipostproc_fixate_srccaps (postproc, caps, othercaps))) gst_caps_replace (&othercaps, outcaps); + g_mutex_unlock (&postproc->postproc_lock); done: GST_DEBUG_OBJECT (trans, "fixated othercaps to %" GST_PTR_FORMAT, othercaps); @@ -1178,36 +1183,43 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); gboolean caps_changed = FALSE; GstVideoInfo vinfo; + gboolean ret = FALSE; + g_mutex_lock (&postproc->postproc_lock); if (!gst_vaapipostproc_update_sink_caps (postproc, caps, &caps_changed)) - return FALSE; + goto done; /* HACK: This is a workaround to deal with the va-intel-driver for non-native * formats while doing advanced deinterlacing. The format of reference surfaces must * be same as the format used by the driver internally for motion adaptive * deinterlacing and motion compensated deinterlacing */ if (!gst_video_info_from_caps (&vinfo, caps)) - return FALSE; + goto done; if (deint_method_is_advanced (postproc->deinterlace_method) && !is_native_video_format (GST_VIDEO_INFO_FORMAT (&vinfo))) { GST_WARNING_OBJECT (postproc, "Advanced deinterlacing requires the native video formats used by the driver internally"); - return FALSE; + goto done; } if (!gst_vaapipostproc_update_src_caps (postproc, out_caps, &caps_changed)) - return FALSE; + goto done; if (caps_changed) { gst_vaapipostproc_destroy (postproc); if (!gst_vaapipostproc_create (postproc)) - return FALSE; + goto done; if (!gst_vaapi_plugin_base_set_caps (GST_VAAPI_PLUGIN_BASE (trans), caps, out_caps)) - return FALSE; + goto done; } if (!ensure_srcpad_buffer_pool (postproc, out_caps)) - return FALSE; - return TRUE; + goto done; + + ret = TRUE; + +done: + g_mutex_unlock (&postproc->postproc_lock); + return ret; } static gboolean @@ -1285,6 +1297,7 @@ gst_vaapipostproc_finalize (GObject * object) gst_vaapipostproc_destroy (postproc); + g_mutex_clear (&postproc->postproc_lock); gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (postproc)); G_OBJECT_CLASS (gst_vaapipostproc_parent_class)->finalize (object); } @@ -1295,6 +1308,7 @@ gst_vaapipostproc_set_property (GObject * object, { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (object); + g_mutex_lock (&postproc->postproc_lock); switch (prop_id) { case PROP_FORMAT: postproc->format = g_value_get_enum (value); @@ -1350,6 +1364,7 @@ gst_vaapipostproc_set_property (GObject * object, G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + g_mutex_unlock (&postproc->postproc_lock); } static void @@ -1358,6 +1373,7 @@ gst_vaapipostproc_get_property (GObject * object, { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (object); + g_mutex_lock (&postproc->postproc_lock); switch (prop_id) { case PROP_FORMAT: g_value_set_enum (value, postproc->format); @@ -1405,6 +1421,7 @@ gst_vaapipostproc_get_property (GObject * object, G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + g_mutex_unlock (&postproc->postproc_lock); } static void @@ -1675,6 +1692,7 @@ gst_vaapipostproc_init (GstVaapiPostproc * postproc) gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (postproc), GST_CAT_DEFAULT); + g_mutex_init (&postproc->postproc_lock); postproc->format = DEFAULT_FORMAT; postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE; postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index a42997560a..d829ab1c92 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -134,6 +134,7 @@ struct _GstVaapiPostproc /*< private >*/ GstVaapiPluginBase parent_instance; + GMutex postproc_lock; GstVaapiFilter *filter; GPtrArray *filter_ops; GstVaapiVideoPool *filter_pool; From 1e52269b893b1bd02d88fe70309d692afa823718 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 8 Jun 2016 10:17:46 +0900 Subject: [PATCH 2421/3781] vaapidecode: remove chroma-site and colorimetry from src caps https://bugzilla.gnome.org/show_bug.cgi?id=766596 --- gst/vaapi/gstvaapidecode.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 8bfc4eab98..9c674c2d8a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -302,6 +302,14 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) switch (feature) { case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE:{ + GstStructure *structure = gst_caps_get_structure (state->caps, 0); + + /* Remove chroma-site and colorimetry from src caps, + * which is unnecessary on downstream if using VASurface + */ + gst_structure_remove_fields (structure, "chroma-site", "colorimetry", + NULL); + feature_str = gst_vaapi_caps_feature_to_string (feature); features = gst_caps_features_new (feature_str, NULL); gst_caps_set_features (state->caps, 0, features); From 08ee0f9e783cbaa8ca84c1a17c666f7f29def12a Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 8 Jun 2016 10:14:16 +0900 Subject: [PATCH 2422/3781] vaapipostproc: Add colorimetry attributes to src caps https://bugzilla.gnome.org/show_bug.cgi?id=766596 --- gst/vaapi/gstvaapipostprocutil.c | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 139f5fc903..956bd84d4d 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -548,6 +548,43 @@ overflow_error: } } +static gboolean +_set_colorimetry (GstVaapiPostproc * postproc, GstVideoFormat format, + GstStructure * outs) +{ + GstVideoInfo vinfo; + GstVideoColorimetry colorimetry; + gchar *color; + gint width, height; + + if (!gst_structure_get_int (outs, "width", &width) + || !gst_structure_get_int (outs, "height", &height)) + return FALSE; + + gst_video_info_set_format (&vinfo, format, width, height); + + if (GST_VIDEO_INFO_CHROMA_SITE (&vinfo) != GST_VIDEO_CHROMA_SITE_UNKNOWN) { + gst_structure_set (outs, "chroma-site", G_TYPE_STRING, + gst_video_chroma_to_string (GST_VIDEO_INFO_CHROMA_SITE (&vinfo)), NULL); + } + + /* make sure we set the RGB matrix for RGB formats */ + colorimetry = GST_VIDEO_INFO_COLORIMETRY (&vinfo); + if (GST_VIDEO_FORMAT_INFO_IS_RGB (vinfo.finfo) && + colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_RGB) { + GST_WARNING ("invalid matrix %d for RGB format, using RGB", + colorimetry.matrix); + colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB; + } + + if ((color = gst_video_colorimetry_to_string (&colorimetry))) { + gst_structure_set (outs, "colorimetry", G_TYPE_STRING, color, NULL); + g_free (color); + } + + return TRUE; +} + static gboolean _set_preferred_format (GstStructure * outs, GstVideoFormat format) { @@ -609,6 +646,9 @@ _get_preferred_caps (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, if (!_fixate_frame_rate (postproc, vinfo, structure)) goto fixate_failed; + if (f == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) + _set_colorimetry (postproc, format, structure); + outcaps = gst_caps_new_empty (); gst_caps_append_structure_full (outcaps, structure, gst_caps_features_copy (features)); From 2562cd51beb9b105d2809988651b45a173f88072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 May 2016 14:15:53 +0200 Subject: [PATCH 2423/3781] pluginutil: add gst_video_info_changed() helper This function is shared among different elements, so let factorized it. https://bugzilla.gnome.org/show_bug.cgi?id=765435 --- gst/vaapi/gstvaapipluginutil.c | 22 ++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 4 ++++ gst/vaapi/gstvaapipostproc.c | 6 +----- gst/vaapi/gstvaapivideobufferpool.c | 7 ++----- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index a4a9ad4863..287612101e 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -670,6 +670,28 @@ gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, GST_VIDEO_INFO_MULTIVIEW_FLAGS (vip) = GST_VIDEO_INFO_MULTIVIEW_FLAGS (&vi); } +/** + * gst_video_info_changed: + * @old: old #GstVideoInfo + * @new: new #GstVideoInfo + * + * Compares @old and @new + * + * Returns: %TRUE if @old has different format/width/height than + * @new. Otherwise, %FALSE. + **/ +gboolean +gst_video_info_changed (GstVideoInfo * old, GstVideoInfo * new) +{ + if (GST_VIDEO_INFO_FORMAT (old) != GST_VIDEO_INFO_FORMAT (new)) + return TRUE; + if (GST_VIDEO_INFO_WIDTH (old) != GST_VIDEO_INFO_WIDTH (new)) + return TRUE; + if (GST_VIDEO_INFO_HEIGHT (old) != GST_VIDEO_INFO_HEIGHT (new)) + return TRUE; + return FALSE; +} + /** * gst_vaapi_create_test_display: * diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 1589638d76..8b5d0f0e5a 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -123,6 +123,10 @@ void gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, guint width, guint height); +G_GNUC_INTERNAL +gboolean +gst_video_info_changed (GstVideoInfo * old, GstVideoInfo * new); + G_GNUC_INTERNAL GstVaapiDisplay * gst_vaapi_create_test_display (void); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 0d2b8720a0..e5a8eedefd 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -833,15 +833,11 @@ error_invalid_buffer: static gboolean video_info_changed (GstVideoInfo * old_vip, GstVideoInfo * new_vip) { - if (GST_VIDEO_INFO_FORMAT (old_vip) != GST_VIDEO_INFO_FORMAT (new_vip)) + if (gst_video_info_changed (old_vip, new_vip)) return TRUE; if (GST_VIDEO_INFO_INTERLACE_MODE (old_vip) != GST_VIDEO_INFO_INTERLACE_MODE (new_vip)) return TRUE; - if (GST_VIDEO_INFO_WIDTH (old_vip) != GST_VIDEO_INFO_WIDTH (new_vip)) - return TRUE; - if (GST_VIDEO_INFO_HEIGHT (old_vip) != GST_VIDEO_INFO_HEIGHT (new_vip)) - return TRUE; return FALSE; } diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index fa8ded20c0..1e9409b536 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -24,6 +24,7 @@ #include "gstvaapivideobufferpool.h" #include "gstvaapivideobuffer.h" #include "gstvaapivideomemory.h" +#include "gstvaapipluginutil.h" #if (USE_GLX || USE_EGL) #include "gstvaapivideometa_texture.h" #endif @@ -157,11 +158,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, g_clear_object (&priv->allocator); } - changed_caps = !priv->allocator || - GST_VIDEO_INFO_FORMAT (cur_vip) != GST_VIDEO_INFO_FORMAT (new_vip) || - GST_VIDEO_INFO_WIDTH (cur_vip) != GST_VIDEO_INFO_WIDTH (new_vip) || - GST_VIDEO_INFO_HEIGHT (cur_vip) != GST_VIDEO_INFO_HEIGHT (new_vip); - + changed_caps = !priv->allocator || gst_video_info_changed (cur_vip, new_vip); if (changed_caps) { const GstVideoInfo *alloc_vip; guint flags = 0; From 3d9f8dd41fe53996c8b9ea6dc5ed2aab5e0a3db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 23 May 2016 15:38:07 +0200 Subject: [PATCH 2424/3781] pluginutil: add gst_video_info_force_nv12_if_encoded() This lines repeat a couple times in the code, so it would be better to put it a helper function. https://bugzilla.gnome.org/show_bug.cgi?id=765435 --- gst/vaapi/gstvaapipluginbase.c | 10 ++-------- gst/vaapi/gstvaapipluginutil.c | 16 ++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 4 ++++ gst/vaapi/gstvaapivideomemory.c | 9 +++------ 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 906891d3bd..32cfd120e1 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -524,11 +524,7 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) if (!gst_video_info_from_caps (&vi, caps)) goto error_invalid_caps; - if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) { - GST_DEBUG ("assume video buffer pool format is NV12"); - gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, - GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); - } + gst_video_info_force_nv12_if_encoded (&vi); plugin->sinkpad_buffer_size = GST_VIDEO_INFO_SIZE (&vi); config = gst_buffer_pool_get_config (pool); @@ -721,9 +717,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!gst_video_info_from_caps (&vi, caps)) goto error_invalid_caps; - if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) - gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, - GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); + gst_video_info_force_nv12_if_encoded (&vi); if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 287612101e..a88aeba902 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -692,6 +692,22 @@ gst_video_info_changed (GstVideoInfo * old, GstVideoInfo * new) return FALSE; } +/** + * gst_video_info_force_nv12_if_encoded: + * @vinfo: a #GstVideoInfo + * + * If the format of @vinfo is %GST_VIDEO_FORMAT_ENCODED it is changed + * to %GST_VIDEO_FORMAT_NV12. + **/ +void +gst_video_info_force_nv12_if_encoded (GstVideoInfo * vinfo) +{ + if (GST_VIDEO_INFO_FORMAT (vinfo) != GST_VIDEO_FORMAT_ENCODED) + return; + gst_video_info_set_format (vinfo, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); +} + /** * gst_vaapi_create_test_display: * diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 8b5d0f0e5a..84da876c8d 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -127,6 +127,10 @@ G_GNUC_INTERNAL gboolean gst_video_info_changed (GstVideoInfo * old, GstVideoInfo * new); +G_GNUC_INTERNAL +void +gst_video_info_force_nv12_if_encoded (GstVideoInfo * vinfo); + G_GNUC_INTERNAL GstVaapiDisplay * gst_vaapi_create_test_display (void); diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 6ece32cfed..5eb0cb94bc 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -26,6 +26,7 @@ #include #include #include "gstvaapivideomemory.h" +#include "gstvaapipluginutil.h" GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapivideomemory); #define GST_CAT_DEFAULT gst_debug_vaapivideomemory @@ -705,12 +706,8 @@ allocator_configure_image_info (GstVaapiDisplay * display, } vinfo = &allocator->video_info; - - if (GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) - gst_video_info_set_format (&allocator->image_info, GST_VIDEO_FORMAT_NV12, - GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); - else - allocator->image_info = *vinfo; + allocator->image_info = *vinfo; + gst_video_info_force_nv12_if_encoded (&allocator->image_info); image = new_image (display, &allocator->image_info); if (!image) From 2643ae980a79d7b11ef1643235d0b52db82bacd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 May 2016 14:39:23 +0200 Subject: [PATCH 2425/3781] vaapivideobufferpool: keep only current video info Instead of keeping old and new GstVideoInfo video structure, we only keep one, the current one, the negotiated. The old one is not needed at all. https://bugzilla.gnome.org/show_bug.cgi?id=765435 --- gst/vaapi/gstvaapivideobufferpool.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 1e9409b536..41eac91499 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -44,8 +44,7 @@ enum struct _GstVaapiVideoBufferPoolPrivate { - GstVideoInfo video_info[2]; - guint video_info_index; + GstVideoInfo video_info; GstAllocator *allocator; GstVideoInfo alloc_info; GstVaapiDisplay *display; @@ -138,8 +137,8 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, GstVaapiVideoBufferPoolPrivate *const priv = GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv; GstCaps *caps = NULL; - GstVideoInfo *const cur_vip = &priv->video_info[priv->video_info_index]; - GstVideoInfo *const new_vip = &priv->video_info[!priv->video_info_index]; + GstVideoInfo *const cur_vip = &priv->video_info; + GstVideoInfo new_vip; GstVideoAlignment align; GstAllocator *allocator; gboolean changed_caps, use_dmabuf_memory; @@ -148,7 +147,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, goto error_invalid_config; if (!caps) goto error_no_caps; - if (!gst_video_info_from_caps (new_vip, caps)) + if (!gst_video_info_from_caps (&new_vip, caps)) goto error_invalid_caps; use_dmabuf_memory = gst_buffer_pool_config_has_option (config, @@ -158,7 +157,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, g_clear_object (&priv->allocator); } - changed_caps = !priv->allocator || gst_video_info_changed (cur_vip, new_vip); + changed_caps = !priv->allocator || gst_video_info_changed (cur_vip, &new_vip); if (changed_caps) { const GstVideoInfo *alloc_vip; guint flags = 0; @@ -167,16 +166,16 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, /* XXX: also needs fixed strides/offsets */ flags |= GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE; allocator = - gst_vaapi_dmabuf_allocator_new (priv->display, new_vip, flags); + gst_vaapi_dmabuf_allocator_new (priv->display, &new_vip, flags); } else { - allocator = gst_vaapi_video_allocator_new (priv->display, new_vip, 0); + allocator = gst_vaapi_video_allocator_new (priv->display, &new_vip, 0); } if (!allocator) goto error_create_allocator; gst_object_replace ((GstObject **) & priv->allocator, GST_OBJECT_CAST (allocator)); gst_object_unref (allocator); - priv->video_info_index ^= 1; + priv->video_info = new_vip; alloc_vip = gst_allocator_get_vaapi_video_info (allocator, NULL); if (!alloc_vip) @@ -382,9 +381,7 @@ gst_vaapi_video_buffer_pool_init (GstVaapiVideoBufferPool * pool) pool->priv = priv; - gst_video_info_init (&priv->video_info[0]); - gst_video_info_init (&priv->video_info[1]); - gst_video_info_init (&priv->alloc_info); + gst_video_info_init (&priv->video_info); } GstBufferPool * From 50b2423a2bf0388e0158d1e56ba83e405982a20c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 May 2016 18:46:14 +0200 Subject: [PATCH 2426/3781] pluginbase negotiates allocator with bufferpool Originally vaapivideobufferpool instantiates its own allocator regardless the received configuration, and it relies in custom configuration options to choose which kind of allocator instantiate. This patch transfers the responsibility of the allocator instantiate to vaapipluginbase and pass it to the vaapivideobufferpool through its configuration. * gst/vaapi/gstvaapipluginbase.c + set_dmabuf_allocator(): inserts a dmabuf allocator in the bufferpool + ensure_sinkpad_buffer_pool(): set a normal vaapi video allocator in bufferpool configuration + gst_vaapi_plugin_base_propose_allocation(): call set_dmabuf_allocator() if needed. + gst_vaapi_plugin_base_decide_allocation(): set a normal vaapi video allocator in bufferpool configuration * gst/vaapi/gstvaapivideobufferpool.c + gst_vaapi_video_buffer_pool_set_config(): instead of instantiate the allocator, process the received one through its configuration. * gst/vaapi/gstvaapivideobufferpool.h: removed GST_BUFFER_POOL_OPTION_DMABUF_MEMORY since it is not used anymore. * gst/vaapi/gstvaapivideomemory.c + gst_vaapi_is_dmabuf_allocator(): new helper function to identify a dmabuf allocator with the vaapi qdata. https://bugzilla.gnome.org/show_bug.cgi?id=765435 --- gst/vaapi/gstvaapipluginbase.c | 60 +++++++++++++++++++--- gst/vaapi/gstvaapivideobufferpool.c | 78 ++++++++++++++--------------- gst/vaapi/gstvaapivideobufferpool.h | 11 ---- gst/vaapi/gstvaapivideomemory.c | 13 +++++ gst/vaapi/gstvaapivideomemory.h | 3 ++ 5 files changed, 108 insertions(+), 57 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 32cfd120e1..47e3fd7429 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -469,6 +469,28 @@ has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad) return is_dmabuf_capable; } +static gboolean +set_dmabuf_allocator (GstVaapiPluginBase * plugin, GstBufferPool * pool, + GstCaps * caps) +{ + GstStructure *config; + GstAllocator *allocator; + GstVideoInfo vi; + gboolean ret; + + if (!gst_video_info_from_caps (&vi, caps)) + return FALSE; + config = gst_buffer_pool_get_config (pool); + allocator = gst_vaapi_dmabuf_allocator_new (plugin->display, &vi, + GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); + if (!allocator) + return FALSE; + gst_buffer_pool_config_set_allocator (config, allocator, NULL); + ret = gst_buffer_pool_set_config (pool, config); + gst_object_unref (allocator); + return ret; +} + static gboolean gst_vaapi_buffer_pool_caps_is_equal (GstBufferPool * pool, GstCaps * newcaps) { @@ -502,6 +524,8 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) GstBufferPool *pool; GstStructure *config; GstVideoInfo vi; + GstAllocator *allocator; + gboolean configured; /* video decoders don't use a buffer pool in the sink pad */ if (GST_IS_VIDEO_DECODER (plugin)) @@ -527,13 +551,20 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) gst_video_info_force_nv12_if_encoded (&vi); plugin->sinkpad_buffer_size = GST_VIDEO_INFO_SIZE (&vi); + allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0); + if (!allocator) + goto error_create_allocator; + config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, plugin->sinkpad_buffer_size, 0, 0); + gst_buffer_pool_config_set_allocator (config, allocator, NULL); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); - if (!gst_buffer_pool_set_config (pool, config)) + configured = gst_buffer_pool_set_config (pool, config); + gst_object_unref (allocator); + if (!configured) goto error_pool_config; plugin->sinkpad_buffer_pool = pool; return TRUE; @@ -545,6 +576,12 @@ error_invalid_caps: gst_object_unref (pool); return FALSE; } +error_create_allocator: + { + GST_ERROR_OBJECT (plugin, "failed to create allocator"); + gst_object_unref (pool); + return FALSE; + } error_create_pool: { GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); @@ -618,12 +655,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, plugin->sinkpad_buffer_size, 0, 0); if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) { - GstStructure *const config = - gst_buffer_pool_get_config (plugin->sinkpad_buffer_pool); - - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_DMABUF_MEMORY); - if (!gst_buffer_pool_set_config (plugin->sinkpad_buffer_pool, config)) + if (!set_dmabuf_allocator (plugin, plugin->sinkpad_buffer_pool, caps)) goto error_pool_config; } } @@ -668,6 +700,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gboolean update_pool = FALSE; gboolean has_video_meta = FALSE; gboolean has_video_alignment = FALSE; + GstAllocator *allocator; #if (USE_GLX || USE_EGL) gboolean has_texture_upload_meta = FALSE; guint idx; @@ -749,10 +782,17 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!pool) goto error_create_pool; + allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0); + if (!allocator) + goto error_create_allocator; + config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, min, max); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); + gst_buffer_pool_config_set_allocator (config, allocator, NULL); + + gst_object_unref (allocator); } if (!config) @@ -809,6 +849,12 @@ error_create_pool: GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); return FALSE; } +error_create_allocator: + { + GST_ERROR_OBJECT (plugin, "failed to create allocator"); + gst_object_unref (pool); + return FALSE; + } error_config_failed: { if (pool) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 41eac91499..b424027557 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -136,13 +136,15 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, { GstVaapiVideoBufferPoolPrivate *const priv = GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv; - GstCaps *caps = NULL; - GstVideoInfo *const cur_vip = &priv->video_info; + GstCaps *caps; GstVideoInfo new_vip; + const GstVideoInfo *alloc_vip; GstVideoAlignment align; GstAllocator *allocator; - gboolean changed_caps, use_dmabuf_memory; + GST_DEBUG_OBJECT (pool, "config %" GST_PTR_FORMAT, config); + + caps = NULL; if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) goto error_invalid_config; if (!caps) @@ -150,43 +152,36 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, if (!gst_video_info_from_caps (&new_vip, caps)) goto error_invalid_caps; - use_dmabuf_memory = gst_buffer_pool_config_has_option (config, - GST_BUFFER_POOL_OPTION_DMABUF_MEMORY); - if (priv->use_dmabuf_memory != use_dmabuf_memory) { - priv->use_dmabuf_memory = use_dmabuf_memory; - g_clear_object (&priv->allocator); - } + allocator = NULL; + if (!gst_buffer_pool_config_get_allocator (config, &allocator, NULL)) + goto error_invalid_allocator; - changed_caps = !priv->allocator || gst_video_info_changed (cur_vip, &new_vip); - if (changed_caps) { - const GstVideoInfo *alloc_vip; - guint flags = 0; - - if (use_dmabuf_memory) { - /* XXX: also needs fixed strides/offsets */ - flags |= GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE; - allocator = - gst_vaapi_dmabuf_allocator_new (priv->display, &new_vip, flags); - } else { - allocator = gst_vaapi_video_allocator_new (priv->display, &new_vip, 0); - } - if (!allocator) - goto error_create_allocator; - gst_object_replace ((GstObject **) & priv->allocator, - GST_OBJECT_CAST (allocator)); - gst_object_unref (allocator); - priv->video_info = new_vip; - - alloc_vip = gst_allocator_get_vaapi_video_info (allocator, NULL); - if (!alloc_vip) - goto error_create_allocator_info; - priv->alloc_info = *alloc_vip; - } + if (gst_video_info_changed (&priv->video_info, &new_vip)) + gst_object_replace ((GstObject **) & priv->allocator, NULL); + priv->video_info = new_vip; if (!gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) goto error_no_vaapi_video_meta_option; + /* not our allocator, not our buffers */ + if (allocator) { + priv->use_dmabuf_memory = gst_vaapi_is_dmabuf_allocator (allocator); + if (priv->use_dmabuf_memory || + g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) == 0) { + if (priv->allocator) + gst_object_unref (priv->allocator); + if ((priv->allocator = allocator)) + gst_object_ref (allocator); + alloc_vip = gst_allocator_get_vaapi_video_info (priv->allocator, NULL); + if (!alloc_vip) + goto error_create_allocator_info; + priv->alloc_info = *alloc_vip; + } + } + if (!priv->allocator) + goto error_no_allocator; + priv->has_video_meta = gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); @@ -213,7 +208,7 @@ error_invalid_config: } error_no_caps: { - GST_ERROR_OBJECT (pool, "no valid caps in config"); + GST_ERROR_OBJECT (pool, "no caps in config"); return FALSE; } error_invalid_caps: @@ -221,9 +216,14 @@ error_invalid_caps: GST_ERROR_OBJECT (pool, "invalid caps %" GST_PTR_FORMAT, caps); return FALSE; } -error_create_allocator: +error_invalid_allocator: { - GST_ERROR_OBJECT (pool, "failed to create GstVaapiVideoAllocator object"); + GST_ERROR_OBJECT (pool, "no allocator in config"); + return FALSE; + } +error_no_vaapi_video_meta_option: + { + GST_ERROR_OBJECT (pool, "no GstVaapiVideoMeta option in config"); return FALSE; } error_create_allocator_info: @@ -232,9 +232,9 @@ error_create_allocator_info: "failed to create GstVaapiVideoAllocator `video-info'"); return FALSE; } -error_no_vaapi_video_meta_option: +error_no_allocator: { - GST_ERROR_OBJECT (pool, "no GstVaapiVideoMeta option"); + GST_ERROR_OBJECT (pool, "no allocator defined"); return FALSE; } } diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index 07b28a7a45..8f691caad7 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -54,17 +54,6 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; #define GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META \ "GstBufferPoolOptionVaapiVideoMeta" -/** - * GST_BUFFER_POOL_OPTION_DMABUF_MEMORY: - * - * An option that can be activated on bufferpool to request dmabuf - * handles on buffers from the pool. - */ -#ifndef GST_BUFFER_POOL_OPTION_DMABUF_MEMORY -#define GST_BUFFER_POOL_OPTION_DMABUF_MEMORY \ - "GstBufferPoolOptionDMABUFMemory" -#endif - /** * GstVaapiVideoBufferPoolAcquireFlags: * @GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC: option to diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 5eb0cb94bc..ea09177faf 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1035,3 +1035,16 @@ gst_allocator_set_vaapi_video_info (GstAllocator * allocator, return TRUE; } + +gboolean +gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator) +{ + GstStructure *st; + + g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), FALSE); + + if (g_strcmp0 (allocator->mem_type, GST_ALLOCATOR_DMABUF) != 0) + return FALSE; + st = g_object_get_qdata (G_OBJECT (allocator), GST_VAAPI_VIDEO_INFO_QUARK); + return (st != NULL); +} diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 43994c7a50..6254f324e3 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -214,6 +214,9 @@ gboolean gst_allocator_set_vaapi_video_info (GstAllocator * allocator, const GstVideoInfo * vip, guint flags); +gboolean +gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_MEMORY_H */ From d0c72182a41f34f747ee200af2fd09791a873fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 10 May 2016 15:57:06 +0200 Subject: [PATCH 2427/3781] plugins: add gst_vaapi_plugin_base_create_pool() This patch refactors the code in pluginbase in order to centralize the buffer pool instantiation. As the buffer pool config may have different options, these are gathered using a bitwise flag. https://bugzilla.gnome.org/show_bug.cgi?id=765435 --- gst/vaapi/gstvaapipluginbase.c | 180 +++++++++++++++++---------------- 1 file changed, 95 insertions(+), 85 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 47e3fd7429..c255e717d1 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -37,6 +37,13 @@ /* Environment variable for disable driver white-list */ #define GST_VAAPI_ALL_DRIVERS_ENV "GST_VAAPI_ALL_DRIVERS" +enum +{ + GST_VAAPI_OPTION_VIDEO_META = (1u << 0), + GST_VAAPI_OPTION_VIDEO_ALIGNMENT = (1u << 1), + GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD = (1u << 2), +}; + /* GstVideoContext interface */ static void plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) @@ -508,6 +515,70 @@ gst_vaapi_buffer_pool_caps_is_equal (GstBufferPool * pool, GstCaps * newcaps) return ret; } +/** + * gst_vaapi_plugin_base_create_pool: + * @plugin: a #GstVaapiPluginBase + * @caps: the initial #GstCaps for the resulting buffer pool + * @size: the size of each buffer, not including prefix and padding + * @options: #GstBufferPool options encoded as bit-wise flags + * @allocator: (allow-none): the #GstAllocator to use or %NULL + * + * Create an instance of #GstVaapiVideoBufferPool + * + * Returns: (transfer full): a new allocated #GstBufferPool + **/ +static GstBufferPool * +gst_vaapi_plugin_base_create_pool (GstVaapiPluginBase * plugin, GstCaps * caps, + gsize size, guint min_buffers, guint max_buffers, guint options, + GstAllocator * allocator) +{ + GstBufferPool *pool; + GstStructure *config; + + if (!(pool = gst_vaapi_video_buffer_pool_new (plugin->display))) + goto error_create_pool; + + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set_params (config, caps, size, min_buffers, + max_buffers); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); + if (options & GST_VAAPI_OPTION_VIDEO_META) { + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); + } + if (options & GST_VAAPI_OPTION_VIDEO_ALIGNMENT) { + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + } +#if (USE_GLX || USE_EGL) + if (options & GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD) { + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); + } +#endif + if (allocator) + gst_buffer_pool_config_set_allocator (config, allocator, NULL); + if (!gst_buffer_pool_set_config (pool, config)) + goto error_pool_config; + return pool; + + /* ERRORS */ +error_create_pool: + { + GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); + return NULL; + } +error_pool_config: + { + gst_object_unref (pool); + GST_ELEMENT_ERROR (plugin, RESOURCE, SETTINGS, + ("Failed to configure the buffer pool"), + ("Configuration is most likely invalid, please report this issue.")); + return NULL; + } +} + /** * ensure_sinkpad_buffer_pool: * @plugin: a #GstVaapiPluginBase @@ -522,10 +593,8 @@ static gboolean ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) { GstBufferPool *pool; - GstStructure *config; GstVideoInfo vi; GstAllocator *allocator; - gboolean configured; /* video decoders don't use a buffer pool in the sink pad */ if (GST_IS_VIDEO_DECODER (plugin)) @@ -542,55 +611,37 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) plugin->sinkpad_buffer_size = 0; } - pool = gst_vaapi_video_buffer_pool_new (plugin->display); - if (!pool) - goto error_create_pool; - if (!gst_video_info_from_caps (&vi, caps)) goto error_invalid_caps; gst_video_info_force_nv12_if_encoded (&vi); - plugin->sinkpad_buffer_size = GST_VIDEO_INFO_SIZE (&vi); allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0); if (!allocator) goto error_create_allocator; - config = gst_buffer_pool_get_config (pool); - gst_buffer_pool_config_set_params (config, caps, - plugin->sinkpad_buffer_size, 0, 0); - gst_buffer_pool_config_set_allocator (config, allocator, NULL); - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); - configured = gst_buffer_pool_set_config (pool, config); + pool = gst_vaapi_plugin_base_create_pool (plugin, caps, + GST_VIDEO_INFO_SIZE (&vi), 0, 0, GST_VAAPI_OPTION_VIDEO_META, allocator); gst_object_unref (allocator); - if (!configured) - goto error_pool_config; + if (!pool) + goto error_create_pool; plugin->sinkpad_buffer_pool = pool; + plugin->sinkpad_buffer_size = GST_VIDEO_INFO_SIZE (&vi); return TRUE; /* ERRORS */ error_invalid_caps: { GST_ERROR_OBJECT (plugin, "invalid caps %" GST_PTR_FORMAT, caps); - gst_object_unref (pool); return FALSE; } error_create_allocator: { GST_ERROR_OBJECT (plugin, "failed to create allocator"); - gst_object_unref (pool); return FALSE; } error_create_pool: { - GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); - return FALSE; - } -error_pool_config: - { - GST_ERROR_OBJECT (plugin, "failed to reset buffer pool config"); - gst_object_unref (pool); + /* error message already sent */ return FALSE; } } @@ -694,15 +745,12 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, { GstCaps *caps = NULL; GstBufferPool *pool; - GstStructure *config; GstVideoInfo vi; guint size, min, max; gboolean update_pool = FALSE; - gboolean has_video_meta = FALSE; - gboolean has_video_alignment = FALSE; + guint pool_options; GstAllocator *allocator; #if (USE_GLX || USE_EGL) - gboolean has_texture_upload_meta = FALSE; guint idx; #endif @@ -716,17 +764,19 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, so explicitly through GstVideoGLTextureUploadMeta */ gst_object_replace (&plugin->gl_context, NULL); - has_video_meta = gst_query_find_allocation_meta (query, - GST_VIDEO_META_API_TYPE, NULL); + pool_options = 0; + if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) + pool_options |= GST_VAAPI_OPTION_VIDEO_META; #if (USE_GLX || USE_EGL) - has_texture_upload_meta = gst_query_find_allocation_meta (query, - GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx) && + if (gst_query_find_allocation_meta (query, + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx) && gst_vaapi_caps_feature_contains (caps, - GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); + GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META)) + pool_options |= GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD; #if USE_GST_GL_HELPERS - if (has_texture_upload_meta) { + if (pool_options & GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD) { const GstStructure *params; GstObject *gl_context; @@ -759,8 +809,9 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (pool) { /* Check whether downstream element proposed a bufferpool but did not provide a correct propose_allocation() implementation */ - has_video_alignment = gst_buffer_pool_has_option (pool, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + if (gst_buffer_pool_has_option (pool, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) + pool_options |= GST_VAAPI_OPTION_VIDEO_ALIGNMENT; /* GstVaapiVideoMeta is mandatory, and this implies VA surface memory */ if (!gst_buffer_pool_has_option (pool, @@ -776,48 +827,17 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, min = max = 0; } - config = NULL; if (!pool) { - pool = gst_vaapi_video_buffer_pool_new (plugin->display); - if (!pool) - goto error_create_pool; - allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0); if (!allocator) goto error_create_allocator; - - config = gst_buffer_pool_get_config (pool); - gst_buffer_pool_config_set_params (config, caps, size, min, max); - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - gst_buffer_pool_config_set_allocator (config, allocator, NULL); - + pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, min, max, + pool_options, allocator); gst_object_unref (allocator); + if (!pool) + goto error_create_pool; } - if (!config) - config = gst_buffer_pool_get_config (pool); - - /* Check whether GstVideoMeta, or GstVideoAlignment, is needed (raw video) */ - if (has_video_meta) { - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_META); - } else if (has_video_alignment) { - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); - } - - /* GstVideoGLTextureUploadMeta (OpenGL) */ -#if (USE_GLX || USE_EGL) - if (has_texture_upload_meta) { - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); - } -#endif - - if (!gst_buffer_pool_set_config (pool, config)) - goto error_config_failed; - if (update_pool) gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); else @@ -844,24 +864,14 @@ error_ensure_display: plugin->display_type_req); return FALSE; } -error_create_pool: - { - GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); - return FALSE; - } error_create_allocator: { GST_ERROR_OBJECT (plugin, "failed to create allocator"); - gst_object_unref (pool); return FALSE; } -error_config_failed: +error_create_pool: { - if (pool) - gst_object_unref (pool); - GST_ELEMENT_ERROR (plugin, RESOURCE, SETTINGS, - ("Failed to configure the buffer pool"), - ("Configuration is most likely invalid, please report this issue.")); + /* error message already sent */ return FALSE; } } From 6c5b6232da85bfdfda5c5fe108ef02fb438e26a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 25 May 2016 10:58:01 +0200 Subject: [PATCH 2428/3781] vaapivideobufferpool: share options flag with pluginbase Originally, vaapivideobufferpool has a set of boolean variables for the buffer configuration options. This pach changes these boolean variables for a single bitwise, just as it is used in pluginbase. Hence, the internal enum was moved to vaapivideobufferpool header. https://bugzilla.gnome.org/show_bug.cgi?id=765435 --- gst/vaapi/gstvaapipluginbase.c | 26 ++++++++++---------------- gst/vaapi/gstvaapivideobufferpool.c | 25 ++++++++++++------------- gst/vaapi/gstvaapivideobufferpool.h | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index c255e717d1..1762b4e10d 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -37,13 +37,6 @@ /* Environment variable for disable driver white-list */ #define GST_VAAPI_ALL_DRIVERS_ENV "GST_VAAPI_ALL_DRIVERS" -enum -{ - GST_VAAPI_OPTION_VIDEO_META = (1u << 0), - GST_VAAPI_OPTION_VIDEO_ALIGNMENT = (1u << 1), - GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD = (1u << 2), -}; - /* GstVideoContext interface */ static void plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) @@ -520,7 +513,7 @@ gst_vaapi_buffer_pool_caps_is_equal (GstBufferPool * pool, GstCaps * newcaps) * @plugin: a #GstVaapiPluginBase * @caps: the initial #GstCaps for the resulting buffer pool * @size: the size of each buffer, not including prefix and padding - * @options: #GstBufferPool options encoded as bit-wise flags + * @options: a set of #GstVaapiVideoBufferPoolOption encoded as bit-wise * @allocator: (allow-none): the #GstAllocator to use or %NULL * * Create an instance of #GstVaapiVideoBufferPool @@ -543,16 +536,16 @@ gst_vaapi_plugin_base_create_pool (GstVaapiPluginBase * plugin, GstCaps * caps, max_buffers); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - if (options & GST_VAAPI_OPTION_VIDEO_META) { + if (options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META) { gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); } - if (options & GST_VAAPI_OPTION_VIDEO_ALIGNMENT) { + if (options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT) { gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); } #if (USE_GLX || USE_EGL) - if (options & GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD) { + if (options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD) { gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); } @@ -620,7 +613,8 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) goto error_create_allocator; pool = gst_vaapi_plugin_base_create_pool (plugin, caps, - GST_VIDEO_INFO_SIZE (&vi), 0, 0, GST_VAAPI_OPTION_VIDEO_META, allocator); + GST_VIDEO_INFO_SIZE (&vi), 0, 0, + GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, allocator); gst_object_unref (allocator); if (!pool) goto error_create_pool; @@ -766,17 +760,17 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, pool_options = 0; if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) - pool_options |= GST_VAAPI_OPTION_VIDEO_META; + pool_options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; #if (USE_GLX || USE_EGL) if (gst_query_find_allocation_meta (query, GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx) && gst_vaapi_caps_feature_contains (caps, GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META)) - pool_options |= GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD; + pool_options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD; #if USE_GST_GL_HELPERS - if (pool_options & GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD) { + if (pool_options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD) { const GstStructure *params; GstObject *gl_context; @@ -811,7 +805,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, not provide a correct propose_allocation() implementation */ if (gst_buffer_pool_has_option (pool, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) - pool_options |= GST_VAAPI_OPTION_VIDEO_ALIGNMENT; + pool_options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT; /* GstVaapiVideoMeta is mandatory, and this implies VA surface memory */ if (!gst_buffer_pool_has_option (pool, diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index b424027557..fe0da52a6a 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -48,9 +48,7 @@ struct _GstVaapiVideoBufferPoolPrivate GstAllocator *allocator; GstVideoInfo alloc_info; GstVaapiDisplay *display; - guint has_video_meta:1; - guint has_video_alignment:1; - guint has_texture_upload_meta:1; + guint options; guint use_dmabuf_memory:1; }; @@ -182,19 +180,20 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, if (!priv->allocator) goto error_no_allocator; - priv->has_video_meta = gst_buffer_pool_config_has_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_META); + priv->options = 0; + if (gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META)) + priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; - priv->has_video_alignment = gst_buffer_pool_config_has_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); - if (priv->has_video_alignment) { + if (gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) { fill_video_alignment (GST_VAAPI_VIDEO_BUFFER_POOL (pool), &align); gst_buffer_pool_config_set_video_alignment (config, &align); } - priv->has_texture_upload_meta = !priv->use_dmabuf_memory - && gst_buffer_pool_config_has_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); + if (!priv->use_dmabuf_memory && gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META)) + priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD; return GST_BUFFER_POOL_CLASS @@ -277,7 +276,7 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, gst_vaapi_video_meta_replace (&meta, NULL); gst_buffer_append_memory (buffer, mem); - if (priv->has_video_meta) { + if (priv->options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META) { GstVideoInfo *const vip = &priv->alloc_info; GstVideoMeta *vmeta; @@ -293,7 +292,7 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, } } #if (USE_GLX || USE_EGL) - if (priv->has_texture_upload_meta) + if (priv->options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD) gst_buffer_add_texture_upload_meta (buffer); #endif diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index 8f691caad7..418c687728 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -68,6 +68,21 @@ typedef enum { GST_BUFFER_POOL_ACQUIRE_FLAG_LAST << 0, } GstVaapiVideoBufferPoolAcquireFlags; +/** + * GstVaapiVideoBufferPoolOption: + * @GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META: + * @GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT: + * @GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD: + * + * Helper enum to handle the buffer pool options using bit operation. + **/ +typedef enum +{ + GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META = (1u << 0), + GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT = (1u << 1), + GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD = (1u << 2), +} GstVaapiVideoBufferPoolOption; + /** * GstVaapiVideoBufferPool: * From ad4c38b36ffdb481db7eb4ef51bc02f987ce2d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 25 May 2016 12:31:15 +0200 Subject: [PATCH 2429/3781] plugins: use an unique allocator per pad Instead of instantiating an allocator per vaapivideobufferpool, only one allocator is instantiated per element's pad and shared among future pools. If the pad's caps changes, the allocator is reset. https://bugzilla.gnome.org/show_bug.cgi?id=765435 --- gst/vaapi/gstvaapipluginbase.c | 46 +++++++++++++++++++++++++--------- gst/vaapi/gstvaapipluginbase.h | 2 ++ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 1762b4e10d..7b91355bd5 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -316,6 +316,9 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) } g_clear_object (&plugin->srcpad_buffer_pool); + g_clear_object (&plugin->sinkpad_allocator); + g_clear_object (&plugin->srcpad_allocator); + gst_caps_replace (&plugin->srcpad_caps, NULL); gst_video_info_init (&plugin->srcpad_info); gst_caps_replace (&plugin->allowed_raw_caps, NULL); @@ -487,7 +490,9 @@ set_dmabuf_allocator (GstVaapiPluginBase * plugin, GstBufferPool * pool, return FALSE; gst_buffer_pool_config_set_allocator (config, allocator, NULL); ret = gst_buffer_pool_set_config (pool, config); - gst_object_unref (allocator); + if (plugin->sinkpad_allocator) + gst_object_unref (plugin->sinkpad_allocator); + plugin->sinkpad_allocator = allocator; return ret; } @@ -508,6 +513,28 @@ gst_vaapi_buffer_pool_caps_is_equal (GstBufferPool * pool, GstCaps * newcaps) return ret; } +static gboolean +ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo) +{ + if (plugin->sinkpad_allocator) + return TRUE; + + plugin->sinkpad_allocator = + gst_vaapi_video_allocator_new (plugin->display, vinfo, 0); + return plugin->sinkpad_allocator != NULL; +} + +static gboolean +ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo) +{ + if (plugin->srcpad_allocator) + return TRUE; + + plugin->srcpad_allocator = + gst_vaapi_video_allocator_new (plugin->display, vinfo, 0); + return plugin->srcpad_allocator != NULL; +} + /** * gst_vaapi_plugin_base_create_pool: * @plugin: a #GstVaapiPluginBase @@ -587,7 +614,6 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) { GstBufferPool *pool; GstVideoInfo vi; - GstAllocator *allocator; /* video decoders don't use a buffer pool in the sink pad */ if (GST_IS_VIDEO_DECODER (plugin)) @@ -608,14 +634,11 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) goto error_invalid_caps; gst_video_info_force_nv12_if_encoded (&vi); - allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0); - if (!allocator) + if (!ensure_sinkpad_allocator (plugin, &vi)) goto error_create_allocator; - pool = gst_vaapi_plugin_base_create_pool (plugin, caps, GST_VIDEO_INFO_SIZE (&vi), 0, 0, - GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, allocator); - gst_object_unref (allocator); + GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, plugin->sinkpad_allocator); if (!pool) goto error_create_pool; plugin->sinkpad_buffer_pool = pool; @@ -656,6 +679,7 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, GstCaps * outcaps) { if (incaps && incaps != plugin->sinkpad_caps) { + g_clear_object (&plugin->sinkpad_allocator); gst_caps_replace (&plugin->sinkpad_caps, incaps); if (!gst_video_info_from_caps (&plugin->sinkpad_info, incaps)) return FALSE; @@ -663,6 +687,7 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, } if (outcaps && outcaps != plugin->srcpad_caps) { + g_clear_object (&plugin->srcpad_allocator); gst_caps_replace (&plugin->srcpad_caps, outcaps); if (!gst_video_info_from_caps (&plugin->srcpad_info, outcaps)) return FALSE; @@ -743,7 +768,6 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, guint size, min, max; gboolean update_pool = FALSE; guint pool_options; - GstAllocator *allocator; #if (USE_GLX || USE_EGL) guint idx; #endif @@ -822,12 +846,10 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, } if (!pool) { - allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0); - if (!allocator) + if (!ensure_srcpad_allocator (plugin, &vi)) goto error_create_allocator; pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, min, max, - pool_options, allocator); - gst_object_unref (allocator); + pool_options, plugin->srcpad_allocator); if (!pool) goto error_create_pool; } diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 885650543c..33aa695448 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -175,6 +175,8 @@ struct _GstVaapiPluginBase GstObject *gl_context; GstCaps *allowed_raw_caps; + GstAllocator *sinkpad_allocator; + GstAllocator *srcpad_allocator; }; struct _GstVaapiPluginBaseClass From 73d12288961b5c6c6e2ccac66ae015136376447b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 30 May 2016 23:55:43 +0200 Subject: [PATCH 2430/3781] libs: change gst_vaapi_surface_new_with_dma_buf_handle() Instead of passing the data already in GstVideoInfo, let's just pass the GstVideoInfo structure. https://bugzilla.gnome.org/show_bug.cgi?id=765435 --- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 12 +++++------- gst-libs/gst/vaapi/gstvaapisurface_drm.h | 5 ++--- gst/vaapi/gstvaapipluginbase.c | 6 ++---- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index 121b708772..b6357d306b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -139,21 +139,19 @@ fill_video_info (GstVideoInfo * vip, GstVideoFormat format, guint width, * if creation from DRM PRIME fd failed, or is not supported */ GstVaapiSurface * -gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, - gint fd, guint size, GstVideoFormat format, guint width, guint height, - gsize offset[GST_VIDEO_MAX_PLANES], gint stride[GST_VIDEO_MAX_PLANES]) +gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, gint fd, + GstVideoInfo * vi) { GstVaapiBufferProxy *proxy; GstVaapiSurface *surface; - GstVideoInfo vi; proxy = gst_vaapi_buffer_proxy_new ((gintptr) fd, - GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF, size, NULL, NULL); + GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF, GST_VIDEO_INFO_SIZE (vi), NULL, + NULL); if (!proxy) return NULL; - fill_video_info (&vi, format, width, height, offset, stride); - surface = gst_vaapi_surface_new_from_buffer_proxy (display, proxy, &vi); + surface = gst_vaapi_surface_new_from_buffer_proxy (display, proxy, vi); gst_vaapi_buffer_proxy_unref (proxy); return surface; } diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.h b/gst-libs/gst/vaapi/gstvaapisurface_drm.h index 5073f55641..1dd637d8e5 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.h @@ -35,9 +35,8 @@ GstVaapiBufferProxy * gst_vaapi_surface_get_gem_buf_handle (GstVaapiSurface * surface); GstVaapiSurface * -gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, - gint fd, guint size, GstVideoFormat format, guint width, guint height, - gsize offset[GST_VIDEO_MAX_PLANES], gint stride[GST_VIDEO_MAX_PLANES]); +gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, gint fd, + GstVideoInfo * vi); GstVaapiSurface * gst_vaapi_surface_new_with_gem_buf_handle (GstVaapiDisplay * display, diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 7b91355bd5..b623abd293 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -205,10 +205,8 @@ plugin_bind_dma_to_vaapi_buffer (GstVaapiPluginBase * plugin, meta = gst_buffer_get_vaapi_video_meta (outbuf); g_return_val_if_fail (meta != NULL, FALSE); - surface = gst_vaapi_surface_new_with_dma_buf_handle (plugin->display, fd, - GST_VIDEO_INFO_SIZE (vip), GST_VIDEO_INFO_FORMAT (vip), - GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip), - vip->offset, vip->stride); + surface = + gst_vaapi_surface_new_with_dma_buf_handle (plugin->display, fd, vip); if (!surface) goto error_create_surface; From 8292acfdd458419db836d1b8ca01151779447313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 31 May 2016 08:26:33 +0200 Subject: [PATCH 2431/3781] plugins: cache VASurfaces from dmabufs This patch avoids the creation of a VASurface each time a new input buffer is processed, caching them in the input buffer itself. https://bugzilla.gnome.org/show_bug.cgi?id=765435 --- gst/vaapi/gstvaapipluginbase.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index b623abd293..e631b74d44 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -145,6 +145,21 @@ default_display_changed (GstVaapiPluginBase * plugin) { } +static GstVaapiSurface * +_get_cached_surface (GstBuffer * buf) +{ + return gst_mini_object_get_qdata (GST_MINI_OBJECT (buf), + g_quark_from_static_string ("GstVaapiDMABufSurface")); +} + +static void +_set_cached_surface (GstBuffer * buf, GstVaapiSurface * surface) +{ + return gst_mini_object_set_qdata (GST_MINI_OBJECT (buf), + g_quark_from_static_string ("GstVaapiDMABufSurface"), surface, + (GDestroyNotify) gst_vaapi_object_unref); +} + static gboolean plugin_update_sinkpad_info_from_buffer (GstVaapiPluginBase * plugin, GstBuffer * buf) @@ -205,13 +220,18 @@ plugin_bind_dma_to_vaapi_buffer (GstVaapiPluginBase * plugin, meta = gst_buffer_get_vaapi_video_meta (outbuf); g_return_val_if_fail (meta != NULL, FALSE); - surface = - gst_vaapi_surface_new_with_dma_buf_handle (plugin->display, fd, vip); - if (!surface) - goto error_create_surface; + /* Check for a VASurface cached in the buffer */ + surface = _get_cached_surface (inbuf); + if (!surface) { + /* otherwise create one and cache it */ + surface = + gst_vaapi_surface_new_with_dma_buf_handle (plugin->display, fd, vip); + if (!surface) + goto error_create_surface; + _set_cached_surface (inbuf, surface); + } proxy = gst_vaapi_surface_proxy_new (surface); - gst_vaapi_object_unref (surface); if (!proxy) goto error_create_proxy; From 8d7a0ae16c175165d62ec6e8fb45cc43798129c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 31 May 2016 11:52:57 +0200 Subject: [PATCH 2432/3781] plugins: use GstParentBufferMeta Instead of using the VASurface proxy's notify, which is internal gstvaapi API, use the GStreamer's GstParentBufferMeta. https://bugzilla.gnome.org/show_bug.cgi?id=765435 --- gst/vaapi/gstvaapipluginbase.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e631b74d44..a952057794 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -234,11 +234,9 @@ plugin_bind_dma_to_vaapi_buffer (GstVaapiPluginBase * plugin, proxy = gst_vaapi_surface_proxy_new (surface); if (!proxy) goto error_create_proxy; - - gst_vaapi_surface_proxy_set_destroy_notify (proxy, - (GDestroyNotify) gst_buffer_unref, (gpointer) gst_buffer_ref (inbuf)); gst_vaapi_video_meta_set_surface_proxy (meta, proxy); gst_vaapi_surface_proxy_unref (proxy); + gst_buffer_add_parent_buffer_meta (outbuf, inbuf); return TRUE; /* ERRORS */ From 4c99077af414064e3443b2c17a33858e5b97dee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 8 Jun 2016 18:44:34 +0200 Subject: [PATCH 2433/3781] plugins: avoid possible memory leaks Get the pool config just before use it, to avoid a memory leak if the allocator cannot be instantiated. Similarly, return FALSE if the configuration cannot be set, avoid keep a not used allocator in the pool. --- gst/vaapi/gstvaapipluginbase.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index a952057794..143c7ef7e6 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -495,21 +495,23 @@ set_dmabuf_allocator (GstVaapiPluginBase * plugin, GstBufferPool * pool, GstStructure *config; GstAllocator *allocator; GstVideoInfo vi; - gboolean ret; if (!gst_video_info_from_caps (&vi, caps)) return FALSE; - config = gst_buffer_pool_get_config (pool); allocator = gst_vaapi_dmabuf_allocator_new (plugin->display, &vi, GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); if (!allocator) return FALSE; + + config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_allocator (config, allocator, NULL); - ret = gst_buffer_pool_set_config (pool, config); + if (!gst_buffer_pool_set_config (pool, config)) + return FALSE; + if (plugin->sinkpad_allocator) gst_object_unref (plugin->sinkpad_allocator); plugin->sinkpad_allocator = allocator; - return ret; + return TRUE; } static gboolean From f189af8dc535e94ba45dfcd21d324df919a7cb27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 2 Jun 2016 15:41:22 +0200 Subject: [PATCH 2434/3781] plugins: remove precondition for decide_allocation() There's no need to check for the display in the plugin object when decide_allocation() vmethod is called, because the display will created or re-created along the method execution. --- gst/vaapi/gstvaapipluginbase.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 143c7ef7e6..389d69a99e 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -790,8 +790,6 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, guint idx; #endif - g_return_val_if_fail (plugin->display != NULL, FALSE); - gst_query_parse_allocation (query, &caps, NULL); if (!caps) goto error_no_caps; From fec82052d54daf1338f30d655a12fe6a72ea0a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 8 Jun 2016 18:42:43 +0200 Subject: [PATCH 2435/3781] vaapivideomemory: internal attributes to methods Mark as internal the functions used by VA-API dmabuf allocator. --- gst/vaapi/gstvaapivideomemory.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 6254f324e3..c096a03b11 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -206,14 +206,17 @@ GstAllocator * gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, const GstVideoInfo * vip, guint flags); +G_GNUC_INTERNAL const GstVideoInfo * gst_allocator_get_vaapi_video_info (GstAllocator * allocator, guint * out_flags_ptr); +G_GNUC_INTERNAL gboolean gst_allocator_set_vaapi_video_info (GstAllocator * allocator, const GstVideoInfo * vip, guint flags); +G_GNUC_INTERNAL gboolean gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator); From 2e5367a23c34d93973fff71c5b66b31081068dab Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Mon, 13 Jun 2016 10:48:41 -0700 Subject: [PATCH 2436/3781] plugins: retry pool config if gst_buffer_pool_set_config returns FALSE, check the modified config and retry set_config if the config is still acceptable. Signed-off-by: Scott D Phillips https://bugzilla.gnome.org/show_bug.cgi?id=766184 --- gst/vaapi/gstvaapipluginbase.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 389d69a99e..b74dbf4c3d 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -597,8 +597,18 @@ gst_vaapi_plugin_base_create_pool (GstVaapiPluginBase * plugin, GstCaps * caps, #endif if (allocator) gst_buffer_pool_config_set_allocator (config, allocator, NULL); - if (!gst_buffer_pool_set_config (pool, config)) - goto error_pool_config; + if (!gst_buffer_pool_set_config (pool, config)) { + config = gst_buffer_pool_get_config (pool); + + if (!gst_buffer_pool_config_validate_params (config, caps, size, + min_buffers, max_buffers)) { + gst_structure_free (config); + goto error_pool_config; + } + + if (!gst_buffer_pool_set_config (pool, config)) + goto error_pool_config; + } return pool; /* ERRORS */ From b5bf2e83f76e6828829fa0376a7c0041708dc3b9 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Tue, 14 Jun 2016 09:45:22 -0700 Subject: [PATCH 2437/3781] vaapivideobufferpool: add video meta to config when needed In cases where we know the video meta must be present, add it to the pool configuration. Signed-off-by: Scott D Phillips https://bugzilla.gnome.org/show_bug.cgi?id=766184 --- gst/vaapi/gstvaapivideobufferpool.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index fe0da52a6a..a3b9223f24 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -139,6 +139,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, const GstVideoInfo *alloc_vip; GstVideoAlignment align; GstAllocator *allocator; + gboolean ret, updated = FALSE; GST_DEBUG_OBJECT (pool, "config %" GST_PTR_FORMAT, config); @@ -184,6 +185,21 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, if (gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META)) priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; + else { + gint i; + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&priv->video_info); i++) { + if (GST_VIDEO_INFO_PLANE_OFFSET (&priv->video_info, i) != + GST_VIDEO_INFO_PLANE_OFFSET (&priv->alloc_info, i) || + GST_VIDEO_INFO_PLANE_STRIDE (&priv->video_info, i) != + GST_VIDEO_INFO_PLANE_STRIDE (&priv->alloc_info, i)) { + priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); + updated = TRUE; + break; + } + } + } if (gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) { @@ -195,9 +211,10 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META)) priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD; - return + ret = GST_BUFFER_POOL_CLASS (gst_vaapi_video_buffer_pool_parent_class)->set_config (pool, config); + return !updated && ret; /* ERRORS */ error_invalid_config: From ad9fcb938639c4384b42155dfbea85393bf73137 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Tue, 17 May 2016 15:34:23 -0700 Subject: [PATCH 2438/3781] gstvaapicontext: control reset_on_resize with option Signed-off-by: Scott D Phillips https://bugzilla.gnome.org/show_bug.cgi?id=767474 --- gst-libs/gst/vaapi/gstvaapicontext.c | 20 +++++++++++++++++++- gst-libs/gst/vaapi/gstvaapicontext.h | 6 ++++++ gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 3 +++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 000c713739..63e4dd6ac5 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -323,6 +323,7 @@ gst_vaapi_context_init (GstVaapiContext * context, cip->chroma_type = DEFAULT_CHROMA_TYPE; context->va_config = VA_INVALID_ID; + context->reset_on_resize = TRUE; gst_vaapi_context_overlay_init (context); } @@ -425,7 +426,7 @@ gst_vaapi_context_reset (GstVaapiContext * context, 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 || grow_surfaces) + if ((reset_surfaces && context->reset_on_resize) || grow_surfaces) reset_config = TRUE; } @@ -499,3 +500,20 @@ gst_vaapi_context_get_surface_count (GstVaapiContext * context) 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; +} diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index d3010c106b..19afc0626a 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -108,6 +108,7 @@ struct _GstVaapiContext GstVaapiVideoPool *surfaces_pool; GPtrArray *overlays[2]; guint overlay_id; + gboolean reset_on_resize; }; /** @@ -143,6 +144,11 @@ 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_END_DECLS #endif /* GST_VAAPI_CONTEXT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index a93154a54e..74f92d87f9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -220,6 +220,9 @@ ensure_context (GstVaapiDecoderVp9 * decoder) 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; } From 57ee937b8cc4b7824e0a837fafb15e213197146c Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Wed, 15 Jun 2016 11:25:23 -0700 Subject: [PATCH 2439/3781] decoder: vp9: Update comment about context resets Clarify that vaapi context resets are never needed for vp9, but that ensure_context() needs called when the size increases so that new surfaces can be allocated. Signed-off-by: Scott D Phillips https://bugzilla.gnome.org/show_bug.cgi?id=767474 --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 74f92d87f9..0443488feb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -600,9 +600,10 @@ parse_frame_header (GstVaapiDecoderVp9 * decoder, const guchar * buf, return get_status (result); /* Unlike other decoders, vp9 decoder doesn't need to reset the - * whole context and surfaces for each resolution change. context - * reset only needed if resolution of any frame is greater than - * what actullay configured. There are streams where a bigger + * 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 */ From aee9166c7fcfe9d59e7638920701dbf01369a7e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 15 Jun 2016 20:19:27 +0200 Subject: [PATCH 2440/3781] vaapisink: return caps template if no display If vaapisink received a caps query before getting a VA display, it returned only the surfaces related caps. This behavior broke the autovideosink negotiation. This patch returns the pad's template caps if no VA display, otherwise the caps are crafted as before. https://bugzilla.gnome.org/show_bug.cgi?id=767699 --- gst/vaapi/gstvaapisink.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index ea825cba8b..472b8731d6 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1215,34 +1215,31 @@ static GstCaps * gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) { GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); - GstCaps *out_caps, *raw_caps; + GstCaps *out_caps, *raw_caps, *feature_caps; static const char surface_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ";" GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, "{ ENCODED, NV12, I420, YV12 }"); + GstCapsFeatures *const features = gst_caps_features_new + (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL); + + if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)) + return gst_static_pad_template_get_caps (&gst_vaapisink_sink_factory); out_caps = gst_caps_from_string (surface_caps_str); + raw_caps = + gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE (sink)); + if (!raw_caps) + return out_caps; - if (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)) { - raw_caps = - gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE - (sink)); - if (raw_caps) { - GstCaps *feature_caps; - GstCapsFeatures *const features = - gst_caps_features_new - (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL); + out_caps = gst_caps_make_writable (out_caps); + gst_caps_append (out_caps, gst_caps_copy (raw_caps)); - out_caps = gst_caps_make_writable (out_caps); + feature_caps = gst_caps_copy (raw_caps); + gst_caps_set_features (feature_caps, 0, features); + gst_caps_append (out_caps, feature_caps); - gst_caps_append (out_caps, gst_caps_copy (raw_caps)); - - feature_caps = gst_caps_copy (raw_caps); - gst_caps_set_features (feature_caps, 0, features); - gst_caps_append (out_caps, feature_caps); - } - } return out_caps; } From c3c7f08e5d38ecdb910ae891cb11fd3590afedcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Jun 2016 16:53:26 +0200 Subject: [PATCH 2441/3781] vaapidecodebin: add vp9 in sink pad template --- gst/vaapi/gstvaapidecodebin.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 93fa8b2217..d5b308ef60 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -98,6 +98,9 @@ static const char gst_vaapi_decode_bin_sink_caps_str[] = GST_CAPS_CODEC("video/x-wmv") #if USE_VP8_DECODER GST_CAPS_CODEC("video/x-vp8") +#endif +#if USE_VP9_DECODER + GST_CAPS_CODEC("video/x-vp9") #endif ; /* *INDENT-ON* */ From fc8fbddc5c54d4a4edbc5fe40bbd9bf66811bfa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Jun 2016 17:00:03 +0200 Subject: [PATCH 2442/3781] vaapi: remove an already included header gst/gst.h is already included in gstcompat.h --- gst/vaapi/gstvaapi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 396c7d0142..a4e57e0a7f 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -23,7 +23,6 @@ */ #include "gstcompat.h" -#include #include "gstvaapidecode.h" #include "gstvaapipostproc.h" #include "gstvaapisink.h" From 2fb05613a080d58ab80948dab04e19d4843eeec1 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Mon, 20 Jun 2016 19:53:26 +0900 Subject: [PATCH 2443/3781] vaapi: fix minor leaks https://bugzilla.gnome.org/show_bug.cgi?id=767868 --- gst/vaapi/gstvaapidecode.c | 2 ++ gst/vaapi/gstvaapipostproc.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9c674c2d8a..2cc8c47879 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -333,6 +333,8 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) allocation_caps); } gst_caps_replace (&state->allocation_caps, allocation_caps); + if (allocation_caps) + gst_caps_unref (allocation_caps); GST_INFO_OBJECT (decode, "new src caps = %" GST_PTR_FORMAT, state->caps); gst_caps_replace (&decode->srcpad_caps, state->caps); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index e5a8eedefd..df654bcd0f 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1046,7 +1046,7 @@ gst_vaapipostproc_fixate_caps (GstBaseTransform * trans, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - GstCaps *outcaps; + GstCaps *outcaps = NULL; GST_DEBUG_OBJECT (trans, "trying to fixate othercaps %" GST_PTR_FORMAT " based on caps %" GST_PTR_FORMAT " in direction %s", othercaps, caps, @@ -1065,6 +1065,8 @@ gst_vaapipostproc_fixate_caps (GstBaseTransform * trans, done: GST_DEBUG_OBJECT (trans, "fixated othercaps to %" GST_PTR_FORMAT, othercaps); + if (outcaps) + gst_caps_unref (outcaps); return othercaps; } From c5681cff6aecb02c05218d3fc747a4ed89b2760c Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 21 Jun 2016 11:48:54 -0400 Subject: [PATCH 2444/3781] Automatic update of common submodule From ac2f647 to f363b32 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index ac2f647695..f363b32056 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit ac2f647695e7bd4b433ea108ee1d0e23901797d4 +Subproject commit f363b3205658a38e84fa77f19dee218cd4445275 From 05cf583c97737ac531faef6db0588fcbdb949d68 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 22 Jun 2016 15:11:56 +0300 Subject: [PATCH 2445/3781] decoder: h265: fix to release all dpb pictures Without this, all dpb pictures are not released during flush, because we used the global dpb_count variable for checking the dpb fullness which get decremented in dpb_remove_index() routine during each loop iteration. https://bugzilla.gnome.org/show_bug.cgi?id=767934 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 0dac7dbfcd..ef703d02b3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -622,6 +622,15 @@ get_max_dec_frame_buffering (GstH265SPS * sps) (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] + 1)); } +static void +dpb_remove_all (GstVaapiDecoderH265 * decoder) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + + while (priv->dpb_count > 0) + gst_vaapi_frame_store_replace (&priv->dpb[--priv->dpb_count], NULL); +} + static void dpb_remove_index (GstVaapiDecoderH265 * decoder, gint index) { @@ -745,9 +754,7 @@ dpb_clear (GstVaapiDecoderH265 * decoder, gboolean hard_flush) guint i; if (hard_flush) { - for (i = 0; i < priv->dpb_count; i++) - dpb_remove_index (decoder, i); - priv->dpb_count = 0; + dpb_remove_all (decoder); } else { /* Remove unused pictures from DPB */ i = 0; From 55e244817dd1d62880a8248e6969a741614af872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 22 Jun 2016 12:15:29 +0200 Subject: [PATCH 2446/3781] vaapidecodebin: element warning if missing element Raise an element warning if a required element is not available, thus the pipeline will post a warning message and the application will be informed. --- gst/vaapi/gstvaapidecodebin.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index d5b308ef60..79731e6362 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -137,12 +137,13 @@ post_missing_element_message (GstVaapiDecodeBin * vaapidecbin, { GstMessage *msg; - GST_ERROR_OBJECT (vaapidecbin, "Failed to create %s element", - missing_factory); - msg = - gst_missing_element_message_new (GST_ELEMENT_CAST (vaapidecbin), + msg = gst_missing_element_message_new (GST_ELEMENT_CAST (vaapidecbin), missing_factory); gst_element_post_message (GST_ELEMENT_CAST (vaapidecbin), msg); + + GST_ELEMENT_WARNING (vaapidecbin, CORE, MISSING_PLUGIN, + ("Missing element '%s' - check your GStreamer installation.", + missing_factory), ("video decoding might fail")); } static gboolean From 4aec5bdd7207fc0e45813ef14c9c0ad5174a8f75 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Wed, 22 Jun 2016 14:28:44 -0700 Subject: [PATCH 2447/3781] encoder: h264: Use high profile by default Change defaults for max-bframes, cabac, and dct8x8 to be enabled by default. This will cause the default profile to be high instead of baseline. In most situations this is the right decision, and the profile can still be lowered in the case of caps restrictions. Signed-off-by: Scott D Phillips https://bugzilla.gnome.org/show_bug.cgi?id=757941 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index eaafd55c79..8c06d2f2aa 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3031,7 +3031,7 @@ gst_vaapi_encoder_h264_get_default_properties (void) GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES, g_param_spec_uint ("max-bframes", - "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, + "Max B-Frames", "Number of B-frames between I and P", 0, 10, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** @@ -3080,7 +3080,7 @@ gst_vaapi_encoder_h264_get_default_properties (void) g_param_spec_boolean ("cabac", "Enable CABAC", "Enable CABAC entropy coding mode", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiEncoderH264:dct8x8: @@ -3094,7 +3094,7 @@ gst_vaapi_encoder_h264_get_default_properties (void) g_param_spec_boolean ("dct8x8", "Enable 8x8 DCT", "Enable adaptive use of 8x8 transforms in I-frames", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiEncoderH264:cpb-length: From 60cd511fada1c19e4bd0111685cf8580e272d2cf Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Mon, 20 Jun 2016 13:22:36 -0700 Subject: [PATCH 2448/3781] remove unused glibcompat.h glibcompat.h is no longer doing anything. Remove it. Signed-off-by: Scott D Phillips https://bugzilla.gnome.org/show_bug.cgi?id=767886 --- gst-libs/gst/vaapi/Makefile.am | 1 - gst-libs/gst/vaapi/glibcompat.h | 38 --------------------------------- gst-libs/gst/vaapi/sysdeps.h | 2 -- 3 files changed, 41 deletions(-) delete mode 100644 gst-libs/gst/vaapi/glibcompat.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 56388a6a7e..fc97c9441d 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -116,7 +116,6 @@ libgstvaapi_source_h = \ $(NULL) libgstvaapi_source_priv_h = \ - glibcompat.h \ gstvaapibufferproxy_priv.h \ gstvaapicodec_objects.h \ gstvaapicompat.h \ diff --git a/gst-libs/gst/vaapi/glibcompat.h b/gst-libs/gst/vaapi/glibcompat.h deleted file mode 100644 index b02fbade68..0000000000 --- a/gst-libs/gst/vaapi/glibcompat.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * glibcompat.h - System-dependent definitions - * - * Copyright (C) 2012-2014 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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 GLIB_COMPAT_H -#define GLIB_COMPAT_H - -#include -#include - -#define G_COMPAT_DEFINE(new_api, new_args, old_api, old_args) \ -static inline void \ -new_api new_args \ -{ \ - old_api old_args; \ -} - -#undef G_COMPAT_DEFINE - -#endif /* GLIB_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/sysdeps.h b/gst-libs/gst/vaapi/sysdeps.h index f298f56bcc..5e6dafb66a 100644 --- a/gst-libs/gst/vaapi/sysdeps.h +++ b/gst-libs/gst/vaapi/sysdeps.h @@ -31,8 +31,6 @@ #include #include -#include "glibcompat.h" - #include #endif /* SYSDEPS_H */ From 80c439683091dfabc346af0b521e626a945a3d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 24 Jun 2016 12:05:24 +0200 Subject: [PATCH 2449/3781] vaapivideocontext: check if query context is NULL Under certain conditions the element might receive a positive context query but without a context instance. This situation will lead to a segmentation fault when traversing the context list in the pipeline. https://bugzilla.gnome.org/show_bug.cgi?id=767946 --- gst/vaapi/gstvaapivideocontext.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index c90ede7de1..cb5b68e1fb 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -141,6 +141,9 @@ _gst_context_get_from_query (GstElement * element, GstQuery * query, return FALSE; gst_query_parse_context (query, &ctxt); + if (!ctxt) + return FALSE; + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "found context (%" GST_PTR_FORMAT ") in %s query", ctxt, direction == GST_PAD_SRC ? "downstream" : "upstream"); From 1c05c53b022a4d4b89a1c462a66413599e389f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 28 Jun 2016 11:54:33 +0200 Subject: [PATCH 2450/3781] vaapi: nest encoders under USE_ENCODER macro Though USE_{JPEG,VP8,VP9,H265}_ENCODER macros definition depend on USE_ENCODER macro, it is clearer to nest them, showing explicitly the dependency relation. --- gst/vaapi/gstvaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index a4e57e0a7f..ce4c57e00a 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -67,7 +67,6 @@ plugin_init (GstPlugin * plugin) GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_H264); gst_element_register (plugin, "vaapimpeg2enc", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_MPEG2); -#endif #if USE_JPEG_ENCODER gst_element_register (plugin, "vaapijpegenc", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_JPEG); @@ -83,6 +82,7 @@ plugin_init (GstPlugin * plugin) #if USE_VP9_ENCODER gst_element_register (plugin, "vaapivp9enc", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_VP9); +#endif #endif gst_element_register (plugin, "vaapidecodebin", From 326011af5876faad31c0542ec12545ceeba83243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 28 Jun 2016 14:05:51 +0200 Subject: [PATCH 2451/3781] vaapi: nest includes under USE_ENCODER macro This is a missed changeset from commit 1c05c53, since also header includes should be nested. --- gst/vaapi/gstvaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index ce4c57e00a..bf56be2155 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -31,7 +31,6 @@ #if USE_ENCODERS #include "gstvaapiencode_h264.h" #include "gstvaapiencode_mpeg2.h" -#endif #if USE_JPEG_ENCODER #include "gstvaapiencode_jpeg.h" @@ -48,6 +47,7 @@ #if USE_VP9_ENCODER #include "gstvaapiencode_vp9.h" #endif +#endif #define PLUGIN_NAME "vaapi" #define PLUGIN_DESC "VA-API based elements" From 22647090be1e4a4a1a37551a13e429da4a780f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 28 Jun 2016 15:48:39 +0200 Subject: [PATCH 2452/3781] utils: report VP9 profiles Add VP9Profile0-3 name mapping. --- gst-libs/gst/vaapi/gstvaapiutils.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 569e4b5d23..5b8c7a2dc4 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -152,6 +152,14 @@ string_of_VAProfile (VAProfile profile) #if VA_CHECK_VERSION(0,35,0) MAP (VP8Version0_3); #endif +#if VA_CHECK_VERSION(0,37,0) + MAP (VP9Profile0); +#endif +#if VA_CHECK_VERSION(0,39,0) + MAP (VP9Profile1); + MAP (VP9Profile2); + MAP (VP9Profile3); +#endif #undef MAP default: break; From 6d73ca8da2bc0b33262307c0fd1d5e64dc819655 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Wed, 29 Jun 2016 16:42:18 +1000 Subject: [PATCH 2453/3781] vaapipostproc: don't require a vaapi display for all caps queries This delays the requirement of having a GstVaapiDisplay until later https://bugzilla.gnome.org/show_bug.cgi?id=768161 --- gst/vaapi/gstvaapipostproc.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index df654bcd0f..2a2f5219d2 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -920,16 +920,21 @@ ensure_allowed_sinkpad_caps (GstVaapiPostproc * postproc) } /* Append raw video caps */ - if (gst_vaapipostproc_ensure_display (postproc)) { + if (GST_VAAPI_PLUGIN_BASE (postproc)->display) { raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE (postproc)); - if (raw_caps) { - out_caps = gst_caps_make_writable (out_caps); - gst_caps_append (out_caps, gst_caps_copy (raw_caps)); - } else { - GST_WARNING_OBJECT (postproc, "failed to create YUV sink caps"); - } + } else { + raw_caps = + gst_caps_from_string (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_MODES); + } + + if (raw_caps) { + out_caps = gst_caps_make_writable (out_caps); + gst_caps_append (out_caps, gst_caps_copy (raw_caps)); + } else { + GST_WARNING_OBJECT (postproc, "failed to create YUV sink caps"); } postproc->allowed_sinkpad_caps = out_caps; From 649c00d3c73310077277624307a0a27768abd4e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Jun 2016 13:57:02 +0200 Subject: [PATCH 2454/3781] vaapipostproc: return caps template if no display This patch is a fix for my bad review of commit 6d73ca8d. The element should be able to return the available raw caps handled by the VA display, but that only should happen when there a VA display. If there's none, the element should use the caps template. https://bugzilla.gnome.org/show_bug.cgi?id=768161 --- gst/vaapi/gstvaapipostproc.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 2a2f5219d2..43e6582d82 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -911,31 +911,27 @@ ensure_allowed_sinkpad_caps (GstVaapiPostproc * postproc) if (postproc->allowed_sinkpad_caps) return TRUE; + if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc)) + return FALSE; + /* Create VA caps */ out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES); if (!out_caps) { - GST_ERROR_OBJECT (postproc, "failed to create VA sink caps"); + GST_WARNING_OBJECT (postproc, "failed to create VA sink caps"); return FALSE; } - /* Append raw video caps */ - if (GST_VAAPI_PLUGIN_BASE (postproc)->display) { - raw_caps = - gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE - (postproc)); - } else { - raw_caps = - gst_caps_from_string (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " - GST_CAPS_INTERLACED_MODES); + raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps + (GST_VAAPI_PLUGIN_BASE (postproc)); + if (!raw_caps) { + gst_caps_unref (out_caps); + GST_WARNING_OBJECT (postproc, "failed to create YUV sink caps"); + return FALSE; } - if (raw_caps) { - out_caps = gst_caps_make_writable (out_caps); - gst_caps_append (out_caps, gst_caps_copy (raw_caps)); - } else { - GST_WARNING_OBJECT (postproc, "failed to create YUV sink caps"); - } + out_caps = gst_caps_make_writable (out_caps); + gst_caps_append (out_caps, gst_caps_copy (raw_caps)); postproc->allowed_sinkpad_caps = out_caps; /* XXX: append VA/VPP filters */ @@ -1011,7 +1007,7 @@ gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, /* Generate the sink pad caps, that could be fixated afterwards */ if (direction == GST_PAD_SRC) { if (!ensure_allowed_sinkpad_caps (postproc)) - return NULL; + return gst_caps_from_string (gst_vaapipostproc_sink_caps_str); return gst_caps_ref (postproc->allowed_sinkpad_caps); } From e8fabf6a9923328def8f3d7f0c3105dc34b285d9 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 1 Jul 2016 16:00:46 +0900 Subject: [PATCH 2455/3781] vaapisink: add support for GST_TAG_IMAGE_ORIENTATION https://bugzilla.gnome.org/show_bug.cgi?id=765798 --- gst-libs/gst/vaapi/gstvaapitypes.h | 2 + gst-libs/gst/vaapi/gstvaapivalue.c | 2 + gst/vaapi/gstvaapisink.c | 69 +++++++++++++++++++++++++++++- gst/vaapi/gstvaapisink.h | 2 + 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 33d7619821..cf486a4153 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -128,12 +128,14 @@ typedef enum { * @GST_VAAPI_ROTATION_90: the VA display is rotated by 90°, clockwise. * @GST_VAAPI_ROTATION_180: the VA display is rotated by 180°, clockwise. * @GST_VAAPI_ROTATION_270: the VA display is rotated by 270°, clockwise. + * @GST_VAAPI_ROTATION_AUTOMATIC: the VA display is rotated by image-orientating tag. */ typedef enum { GST_VAAPI_ROTATION_0 = 0, GST_VAAPI_ROTATION_90 = 90, GST_VAAPI_ROTATION_180 = 180, GST_VAAPI_ROTATION_270 = 270, + GST_VAAPI_ROTATION_AUTOMATIC = 360, } GstVaapiRotation; /** diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 5ca01ce2b4..2185e7ea63 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -113,6 +113,8 @@ gst_vaapi_rotation_get_type (void) "Rotated by 180°, clockwise", "180"}, {GST_VAAPI_ROTATION_270, "Rotated by 270°, clockwise", "270"}, + {GST_VAAPI_ROTATION_AUTOMATIC, + "Rotated by image-orientating tag°", "Automatic"}, {0, NULL, NULL}, }; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 472b8731d6..68f21c0eaa 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1114,6 +1114,26 @@ gst_vaapisink_ensure_colorbalance (GstVaapiSink * sink) return cb_sync_values_to_display (sink, GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); } + +static void +gst_vaapisink_set_rotation (GstVaapiSink * sink, GstVaapiRotation rotation, + gboolean from_tag) +{ + GST_OBJECT_LOCK (sink); + + if (from_tag) + sink->rotation_tag = rotation; + else + sink->rotation_prop = rotation; + + if (sink->rotation_prop == GST_VAAPI_ROTATION_AUTOMATIC) + sink->rotation_req = sink->rotation_tag; + else + sink->rotation_req = sink->rotation_prop; + + GST_OBJECT_UNLOCK (sink); +} + static gboolean gst_vaapisink_ensure_rotation (GstVaapiSink * sink, gboolean recalc_display_rect) @@ -1533,7 +1553,7 @@ gst_vaapisink_set_property (GObject * object, sink->view_id = g_value_get_int (value); break; case PROP_ROTATION: - sink->rotation_req = g_value_get_enum (value); + gst_vaapisink_set_rotation (sink, g_value_get_enum (value), FALSE); break; case PROP_FORCE_ASPECT_RATIO: sink->keep_aspect = g_value_get_boolean (value); @@ -1616,6 +1636,51 @@ gst_vaapisink_unlock_stop (GstBaseSink * base_sink) return TRUE; } +static gboolean +gst_vaapisink_event (GstBaseSink * base_sink, GstEvent * event) +{ + gboolean res = TRUE; + GstTagList *taglist; + gchar *orientation; + + GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); + + GST_DEBUG_OBJECT (sink, "handling event %s", GST_EVENT_TYPE_NAME (event)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_TAG: + gst_event_parse_tag (event, &taglist); + + if (gst_tag_list_get_string (taglist, GST_TAG_IMAGE_ORIENTATION, + &orientation)) { + if (!g_strcmp0 ("rotate-0", orientation)) { + gst_vaapisink_set_rotation (sink, GST_VAAPI_ROTATION_0, TRUE); + } else if (!g_strcmp0 ("rotate-90", orientation)) { + gst_vaapisink_set_rotation (sink, GST_VAAPI_ROTATION_90, TRUE); + } else if (!g_strcmp0 ("rotate-180", orientation)) { + gst_vaapisink_set_rotation (sink, GST_VAAPI_ROTATION_180, TRUE); + } else if (!g_strcmp0 ("rotate-270", orientation)) { + gst_vaapisink_set_rotation (sink, GST_VAAPI_ROTATION_270, TRUE); + } + + /* Do not support for flip yet. + * It should be implemented in the near future. + * See https://bugs.freedesktop.org/show_bug.cgi?id=90654 + */ + g_free (orientation); + } + break; + default: + break; + } + + res = + GST_BASE_SINK_CLASS (gst_vaapisink_parent_class)->event (base_sink, + event); + + return res; +} + static void gst_vaapisink_set_bus (GstElement * element, GstBus * bus) { @@ -1659,6 +1724,7 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) basesink_class->propose_allocation = gst_vaapisink_propose_allocation; basesink_class->unlock = gst_vaapisink_unlock; basesink_class->unlock_stop = gst_vaapisink_unlock_stop; + basesink_class->event = gst_vaapisink_event; videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_vaapisink_show_frame); @@ -1829,6 +1895,7 @@ gst_vaapisink_init (GstVaapiSink * sink) sink->handle_events = TRUE; sink->rotation = DEFAULT_ROTATION; sink->rotation_req = DEFAULT_ROTATION; + sink->rotation_tag = DEFAULT_ROTATION; sink->keep_aspect = TRUE; sink->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS; gst_video_info_init (&sink->video_info); diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 3ba3dfcdc7..1fb6e832c2 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -94,6 +94,8 @@ struct _GstVaapiSink GstVaapiRectangle display_rect; GstVaapiRotation rotation; GstVaapiRotation rotation_req; + GstVaapiRotation rotation_tag; + GstVaapiRotation rotation_prop; guint color_standard; gint32 view_id; GThread *event_thread; From da4d916a8c0ee2fa5c3b7ac66470736629d25965 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 1 Jul 2016 16:01:54 +0900 Subject: [PATCH 2456/3781] tests: elements: Add testsuite for vaapisink https://bugzilla.gnome.org/show_bug.cgi?id=765798 --- configure.ac | 1 + tests/Makefile.am | 2 + tests/elements/Makefile.am | 68 +++++++++++++++++++ tests/elements/test-vaapisink.c | 115 ++++++++++++++++++++++++++++++++ 4 files changed, 186 insertions(+) create mode 100644 tests/elements/Makefile.am create mode 100644 tests/elements/test-vaapisink.c diff --git a/configure.ac b/configure.ac index 628ee471a8..7b1d632f87 100644 --- a/configure.ac +++ b/configure.ac @@ -1032,6 +1032,7 @@ AC_CONFIG_FILES([ gst/Makefile gst/vaapi/Makefile tests/Makefile + tests/elements/Makefile ]) AC_OUTPUT diff --git a/tests/Makefile.am b/tests/Makefile.am index 578b60538e..ca58797934 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -158,4 +158,6 @@ EXTRA_DIST = \ $(test_utils_source_h) \ $(NULL) +SUBDIRS = elements + -include $(top_srcdir)/git.mk diff --git a/tests/elements/Makefile.am b/tests/elements/Makefile.am new file mode 100644 index 0000000000..73e39ed49a --- /dev/null +++ b/tests/elements/Makefile.am @@ -0,0 +1,68 @@ +noinst_PROGRAMS = \ + test-vaapisink \ + $(NULL) + +TEST_CFLAGS = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + -I$(top_builddir)/gst-libs \ + $(LIBVA_CFLAGS) \ + $(GST_CFLAGS) \ + $(GST_VIDEO_CFLAGS) \ + $(NULL) + +GST_VAAPI_LIBS = $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la +TEST_LIBS = \ + $(LIBVA_LIBS) \ + $(GST_LIBS) \ + $(NULL) + +if USE_DRM +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm.la +TEST_CFLAGS += $(LIBVA_DRM_CFLAGS) +TEST_LIBS += $(LIBVA_DRM_LIBS) +endif + +if USE_X11 +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11.la +TEST_CFLAGS += $(X11_CFLAGS) +TEST_LIBS += \ + $(LIBVA_X11_LIBS) \ + $(X11_LIBS) \ + $(NULL) +endif + +if USE_GLX +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx.la +TEST_CFLAGS += $(X11_CFLAGS) $(GL_CFLAGS) +TEST_LIBS += \ + $(LIBVA_GLX_LIBS) \ + $(X11_LIBS) \ + $(GL_LIBS) \ + $(NULL) +endif + +if USE_EGL +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl.la +TEST_CFLAGS += $(EGL_CFLAGS) +TEST_LIBS += \ + $(LIBVA_EGL_LIBS) \ + $(EGL_LIBS) \ + $(NULL) +endif + +if USE_WAYLAND +GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland.la +TEST_CFLAGS += $(WAYLAND_CFLAGS) +TEST_LIBS += \ + $(LIBVA_WAYLAND_LIBS) \ + $(WAYLAND_LIBS) \ + $(NULL) +endif + +test_vaapisink_SOURCES = test-vaapisink.c +test_vaapisink_CFLAGS = $(TEST_CFLAGS) +test_vaapisink_LDFLAGS = $(GST_VAAPI_LIBS) +test_vaapisink_LDADD = $(TEST_LIBS) + +-include $(top_srcdir)/git.mk diff --git a/tests/elements/test-vaapisink.c b/tests/elements/test-vaapisink.c new file mode 100644 index 0000000000..7167aecfa1 --- /dev/null +++ b/tests/elements/test-vaapisink.c @@ -0,0 +1,115 @@ +#include +#include +#include + +#include + +typedef struct _CustomData +{ + GstElement *pipeline; + GstElement *video_sink; + GstElement *src_sink; + GMainLoop *loop; + GstPad *src_pad; + gboolean orient_automatic; +} AppData; + +static void +send_rotate_event (AppData * data) +{ + gboolean res = FALSE; + GstEvent *event; + + event = gst_event_new_tag (gst_tag_list_new (GST_TAG_IMAGE_ORIENTATION, + "rotate-90", NULL)); + + /* Send the event */ + res = gst_pad_push_event (data->src_pad, event); + g_print ("Sending event %p done: %d\n", event, res); +} + +/* Process keyboard input */ +static gboolean +handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data) +{ + gchar *str = NULL; + + if (g_io_channel_read_line (source, &str, NULL, NULL, + NULL) != G_IO_STATUS_NORMAL) { + return TRUE; + } + + switch (g_ascii_tolower (str[0])) { + case 'r': + send_rotate_event (data); + break; + case 's':{ + g_object_set (G_OBJECT (data->video_sink), "rotation", + GST_VAAPI_ROTATION_AUTOMATIC, NULL); + break; + } + case 'q': + g_main_loop_quit (data->loop); + break; + default: + break; + } + + g_free (str); + + return TRUE; +} + +int +main (int argc, char *argv[]) +{ + AppData data; + GstStateChangeReturn ret; + GIOChannel *io_stdin; + + /* Initialize GStreamer */ + gst_init (&argc, &argv); + + /* Initialize our data structure */ + memset (&data, 0, sizeof (data)); + + /* Print usage map */ + g_print ("USAGE: Choose one of the following options, then press enter:\n" + " 'r' to send image-orientation tag event\n \ + 's' to set orient-automatic\n \ + 'Q' to quit\n"); + + data.pipeline = + gst_parse_launch + ("videotestsrc name=src ! vaapisink name=vaapisink", NULL); + data.video_sink = gst_bin_get_by_name (GST_BIN (data.pipeline), "vaapisink"); + data.src_sink = gst_bin_get_by_name (GST_BIN (data.pipeline), "src"); + data.src_pad = gst_element_get_static_pad (data.src_sink, "src"); + + /* Add a keyboard watch so we get notified of keystrokes */ + io_stdin = g_io_channel_unix_new (fileno (stdin)); + g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc) handle_keyboard, &data); + + /* Start playing */ + ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + g_printerr ("Unable to set the pipeline to the playing state.\n"); + gst_object_unref (data.pipeline); + return -1; + } + + /* Create a GLib Main Loop and set it to run */ + data.loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (data.loop); + + /* Free resources */ + g_main_loop_unref (data.loop); + g_io_channel_unref (io_stdin); + gst_element_set_state (data.pipeline, GST_STATE_NULL); + + if (data.video_sink != NULL) + gst_object_unref (data.video_sink); + gst_object_unref (data.pipeline); + + return 0; +} From 2310273a697f9dfb11821d7315a27e754f398907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 5 Jul 2016 20:59:49 +0200 Subject: [PATCH 2457/3781] tests: elements: rotate orientation event --- tests/elements/test-vaapisink.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/elements/test-vaapisink.c b/tests/elements/test-vaapisink.c index 7167aecfa1..441a991e12 100644 --- a/tests/elements/test-vaapisink.c +++ b/tests/elements/test-vaapisink.c @@ -19,9 +19,13 @@ send_rotate_event (AppData * data) { gboolean res = FALSE; GstEvent *event; + static gint counter = 0; + const static gchar *tags[] = { "rotate-90", "rotate-180", "rotate-270", + "rotate-0" + }; event = gst_event_new_tag (gst_tag_list_new (GST_TAG_IMAGE_ORIENTATION, - "rotate-90", NULL)); + tags[counter++ % G_N_ELEMENTS (tags)], NULL)); /* Send the event */ res = gst_pad_push_event (data->src_pad, event); From 27c55d34eda1cda721704c1e09a8e07c35155bf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 6 Jul 2016 13:48:07 +0300 Subject: [PATCH 2458/3781] Release 1.9.1 --- ChangeLog | 1263 +++++++++++++++++++++++++++++++++++++++++- NEWS | 787 +------------------------- common | 2 +- configure.ac | 14 +- gstreamer-vaapi.doap | 9 + 5 files changed, 1278 insertions(+), 797 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0804da3801..eb543a0158 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,1266 @@ -=== release 1.8.0 === +=== release 1.9.1 === -2016-03-24 Sebastian Dröge +2016-07-06 Sebastian Dröge * configure.ac: - releasing 1.8.0 + releasing 1.9.1 + +2016-07-05 20:59:49 +0200 Víctor Manuel Jáquez Leal + + * tests/elements/test-vaapisink.c: + tests: elements: rotate orientation event + +2016-07-01 16:01:54 +0900 Hyunjun Ko + + * configure.ac: + * tests/Makefile.am: + * tests/elements/Makefile.am: + * tests/elements/test-vaapisink.c: + tests: elements: Add testsuite for vaapisink + https://bugzilla.gnome.org/show_bug.cgi?id=765798 + +2016-07-01 16:00:46 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + vaapisink: add support for GST_TAG_IMAGE_ORIENTATION + https://bugzilla.gnome.org/show_bug.cgi?id=765798 + +2016-06-29 13:57:02 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: return caps template if no display + This patch is a fix for my bad review of commit 6d73ca8d. The element should + be able to return the available raw caps handled by the VA display, but that + only should happen when there a VA display. If there's none, the element + should use the caps template. + https://bugzilla.gnome.org/show_bug.cgi?id=768161 + +2016-06-29 16:42:18 +1000 Matthew Waters + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: don't require a vaapi display for all caps queries + This delays the requirement of having a GstVaapiDisplay until later + https://bugzilla.gnome.org/show_bug.cgi?id=768161 + +2016-06-28 15:48:39 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils.c: + utils: report VP9 profiles + Add VP9Profile0-3 name mapping. + +2016-06-28 14:05:51 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + vaapi: nest includes under USE_ENCODER macro + This is a missed changeset from commit 1c05c53, since also header includes + should be nested. + +2016-06-28 11:54:33 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + vaapi: nest encoders under USE_ENCODER macro + Though USE_{JPEG,VP8,VP9,H265}_ENCODER macros definition depend on USE_ENCODER + macro, it is clearer to nest them, showing explicitly the dependency relation. + +2016-06-24 12:05:24 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + vaapivideocontext: check if query context is NULL + Under certain conditions the element might receive a positive context query + but without a context instance. This situation will lead to a segmentation + fault when traversing the context list in the pipeline. + https://bugzilla.gnome.org/show_bug.cgi?id=767946 + +2016-06-20 13:22:36 -0700 Scott D Phillips + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/glibcompat.h: + * gst-libs/gst/vaapi/sysdeps.h: + remove unused glibcompat.h + glibcompat.h is no longer doing anything. Remove it. + Signed-off-by: Scott D Phillips + https://bugzilla.gnome.org/show_bug.cgi?id=767886 + +2016-06-22 14:28:44 -0700 Scott D Phillips + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: Use high profile by default + Change defaults for max-bframes, cabac, and dct8x8 to be enabled + by default. This will cause the default profile to be high instead + of baseline. In most situations this is the right decision, and + the profile can still be lowered in the case of caps restrictions. + Signed-off-by: Scott D Phillips + https://bugzilla.gnome.org/show_bug.cgi?id=757941 + +2016-06-22 12:15:29 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: element warning if missing element + Raise an element warning if a required element is not available, thus the + pipeline will post a warning message and the application will be informed. + +2016-06-22 15:11:56 +0300 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: h265: fix to release all dpb pictures + Without this, all dpb pictures are not released during flush, + because we used the global dpb_count variable for checking the + dpb fullness which get decremented in dpb_remove_index() + routine during each loop iteration. + https://bugzilla.gnome.org/show_bug.cgi?id=767934 + +2016-06-21 11:48:54 -0400 Nicolas Dufresne + + * common: + Automatic update of common submodule + From ac2f647 to f363b32 + +2016-06-20 19:53:26 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipostproc.c: + vaapi: fix minor leaks + https://bugzilla.gnome.org/show_bug.cgi?id=767868 + +2016-06-17 17:00:03 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + vaapi: remove an already included header + gst/gst.h is already included in gstcompat.h + +2016-06-17 16:53:26 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: add vp9 in sink pad template + +2016-06-15 20:19:27 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: return caps template if no display + If vaapisink received a caps query before getting a VA display, it returned + only the surfaces related caps. This behavior broke the autovideosink + negotiation. + This patch returns the pad's template caps if no VA display, otherwise the + caps are crafted as before. + https://bugzilla.gnome.org/show_bug.cgi?id=767699 + +2016-06-15 11:25:23 -0700 Scott D Phillips + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Update comment about context resets + Clarify that vaapi context resets are never needed for vp9, but + that ensure_context() needs called when the size increases so that + new surfaces can be allocated. + Signed-off-by: Scott D Phillips + https://bugzilla.gnome.org/show_bug.cgi?id=767474 + +2016-05-17 15:34:23 -0700 Scott D Phillips + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + gstvaapicontext: control reset_on_resize with option + Signed-off-by: Scott D Phillips + https://bugzilla.gnome.org/show_bug.cgi?id=767474 + +2016-06-14 09:45:22 -0700 Scott D Phillips + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: add video meta to config when needed + In cases where we know the video meta must be present, add it to + the pool configuration. + Signed-off-by: Scott D Phillips + https://bugzilla.gnome.org/show_bug.cgi?id=766184 + +2016-06-13 10:48:41 -0700 Scott D Phillips + + * gst/vaapi/gstvaapipluginbase.c: + plugins: retry pool config + if gst_buffer_pool_set_config returns FALSE, check the modified + config and retry set_config if the config is still acceptable. + Signed-off-by: Scott D Phillips + https://bugzilla.gnome.org/show_bug.cgi?id=766184 + +2016-06-08 18:42:43 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: internal attributes to methods + Mark as internal the functions used by VA-API dmabuf allocator. + +2016-06-02 15:41:22 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: remove precondition for decide_allocation() + There's no need to check for the display in the plugin object when + decide_allocation() vmethod is called, because the display will created or + re-created along the method execution. + +2016-06-08 18:44:34 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: avoid possible memory leaks + Get the pool config just before use it, to avoid a memory leak if the + allocator cannot be instantiated. Similarly, return FALSE if the configuration + cannot be set, avoid keep a not used allocator in the pool. + +2016-05-31 11:52:57 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: use GstParentBufferMeta + Instead of using the VASurface proxy's notify, which is internal gstvaapi API, + use the GStreamer's GstParentBufferMeta. + https://bugzilla.gnome.org/show_bug.cgi?id=765435 + +2016-05-31 08:26:33 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: cache VASurfaces from dmabufs + This patch avoids the creation of a VASurface each time a new input buffer is + processed, caching them in the input buffer itself. + https://bugzilla.gnome.org/show_bug.cgi?id=765435 + +2016-05-30 23:55:43 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + * gst-libs/gst/vaapi/gstvaapisurface_drm.h: + * gst/vaapi/gstvaapipluginbase.c: + libs: change gst_vaapi_surface_new_with_dma_buf_handle() + Instead of passing the data already in GstVideoInfo, let's just pass the + GstVideoInfo structure. + https://bugzilla.gnome.org/show_bug.cgi?id=765435 + +2016-05-25 12:31:15 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: use an unique allocator per pad + Instead of instantiating an allocator per vaapivideobufferpool, only one + allocator is instantiated per element's pad and shared among future pools. + If the pad's caps changes, the allocator is reset. + https://bugzilla.gnome.org/show_bug.cgi?id=765435 + +2016-05-25 10:58:01 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideobufferpool.h: + vaapivideobufferpool: share options flag with pluginbase + Originally, vaapivideobufferpool has a set of boolean variables for the + buffer configuration options. + This pach changes these boolean variables for a single bitwise, just as + it is used in pluginbase. Hence, the internal enum was moved to + vaapivideobufferpool header. + https://bugzilla.gnome.org/show_bug.cgi?id=765435 + +2016-05-10 15:57:06 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: add gst_vaapi_plugin_base_create_pool() + This patch refactors the code in pluginbase in order to centralize the buffer + pool instantiation. As the buffer pool config may have different options, these + are gathered using a bitwise flag. + https://bugzilla.gnome.org/show_bug.cgi?id=765435 + +2016-05-20 18:46:14 +0200 Víctor Manuel Jáquez Leal + + pluginbase negotiates allocator with bufferpool + Originally vaapivideobufferpool instantiates its own allocator regardless the + received configuration, and it relies in custom configuration options to + choose which kind of allocator instantiate. + This patch transfers the responsibility of the allocator instantiate to + vaapipluginbase and pass it to the vaapivideobufferpool through its + configuration. + * gst/vaapi/gstvaapipluginbase.c + + set_dmabuf_allocator(): inserts a dmabuf allocator in the bufferpool + + ensure_sinkpad_buffer_pool(): set a normal vaapi video allocator in + bufferpool configuration + + gst_vaapi_plugin_base_propose_allocation(): call set_dmabuf_allocator() if + needed. + + gst_vaapi_plugin_base_decide_allocation(): set a normal vaapi video + allocator in bufferpool configuration + * gst/vaapi/gstvaapivideobufferpool.c + + gst_vaapi_video_buffer_pool_set_config(): instead of instantiate the + allocator, process the received one through its configuration. + * gst/vaapi/gstvaapivideobufferpool.h: removed + GST_BUFFER_POOL_OPTION_DMABUF_MEMORY since it is not used anymore. + * gst/vaapi/gstvaapivideomemory.c + + gst_vaapi_is_dmabuf_allocator(): new helper function to identify a dmabuf + allocator with the vaapi qdata. + https://bugzilla.gnome.org/show_bug.cgi?id=765435 + +2016-05-20 14:39:23 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: keep only current video info + Instead of keeping old and new GstVideoInfo video structure, we only keep one, + the current one, the negotiated. The old one is not needed at all. + https://bugzilla.gnome.org/show_bug.cgi?id=765435 + +2016-05-23 15:38:07 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapivideomemory.c: + pluginutil: add gst_video_info_force_nv12_if_encoded() + This lines repeat a couple times in the code, so it would be better to put it + a helper function. + https://bugzilla.gnome.org/show_bug.cgi?id=765435 + +2016-05-20 14:15:53 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapivideobufferpool.c: + pluginutil: add gst_video_info_changed() helper + This function is shared among different elements, so let factorized it. + https://bugzilla.gnome.org/show_bug.cgi?id=765435 + +2016-06-08 10:14:16 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: Add colorimetry attributes to src caps + https://bugzilla.gnome.org/show_bug.cgi?id=766596 + +2016-06-08 10:17:46 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: remove chroma-site and colorimetry from src caps + https://bugzilla.gnome.org/show_bug.cgi?id=766596 + +2016-06-07 14:19:50 -0700 Scott D Phillips + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: add postproc_lock to protect data members + Add a mutex to postproc to protect concurrent access to data members. + Previously set_caps() could release the allowed_srcpad_caps while + transform_caps was in the middle of using it. + Signed-off-by: Scott D Phillips + https://bugzilla.gnome.org/show_bug.cgi?id=766940 + +2016-05-30 11:30:40 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.h: + encoder: vp9: Add simple algorithms for reference picture selection + Added two modes(as properties) for reference picture selection: + ref-mode-0: AltRef and GoldRef pointing to the recent keyframe + and LastRef is pointing to the previous frame. + ref-mode-1: Previous frame (n) as LastRef , n-1 th frame as GoldRef + and n-2 th frame as AltRef + https://bugzilla.gnome.org/show_bug.cgi?id=766048 + +2016-05-30 11:25:52 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + encoder: vp9: Define Max frame width and height + https://bugzilla.gnome.org/show_bug.cgi?id=766048 + +2016-05-30 11:25:03 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.h: + encoder: vp9: Add more propertis for tuning encode quality + Added three tuning properties: + 1: filter_level + 2: sharpness_level + 3: luma ac quant-table index + https://bugzilla.gnome.org/show_bug.cgi?id=766048 + +2016-05-30 11:24:14 +0300 Sreerenj Balachandran + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapiencode_vp9.c: + * gst/vaapi/gstvaapiencode_vp9.h: + Add vp9 encode element to "vaapi" plugin + https://bugzilla.gnome.org/show_bug.cgi?id=766048 + +2016-05-30 11:23:12 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.h: + Add vp9 encoder support in libgstvaapi + https://bugzilla.gnome.org/show_bug.cgi?id=766048 + +2016-05-30 11:22:35 +0300 Sreerenj Balachandran + + * configure.ac: + build: Add check for VP9 encode API support in libva + https://bugzilla.gnome.org/show_bug.cgi?id=766048 + +2016-05-26 11:42:32 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + gstvaapisurface_drm: fix internal documentation + +2016-05-26 11:41:25 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + gstvaapisurface_drm: fix code-style + +2016-05-25 12:28:48 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: remove unused header + Remove the include of gst/allocators/allocators.h since it is not used. + +2016-05-25 10:36:33 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.h: + vaapivideobufferpool: remove GL_TEXTURE_UPLOAD_META + Since gstreamer-vaapi is coupled with gstreamer releases, there is no need to + keep compatibility definition. + This patch removes the definition of + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META since it is in + gst-plugins-base version 1.2.2 + +2016-05-23 22:49:11 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: add gst_vaapi_buffer_pool_caps_is_equal() + This is a helper function to improve the readability of + ensure_sinkpad_buffer_pool(). It makes clearer when the buffer pool needs to be + re-instantiated. + +2016-05-24 16:29:33 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: deactivate buffer pool before unref + This buffer pool may still be processing buffers when a caps renegotiation is + done. This one-liner patch deactivates the pool to drain it before it + de-allocation. + +2016-05-24 16:22:24 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: no sinkpad bufferpool when decoder + Right now, the decoders create a buffer pool for their sink pad which is not + used at all, because the decoders have never proposed it to upstream. + This patch avoids the buffer pool instantiating when the element inherits from + the GstVideoDecoder class. + +2016-05-24 13:39:25 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: avoid to get/set pool config twice + This patch is a bit of optimization, since the bufferpool configuration is get + when the pool is created. Hence, we only need to request it when the pool from + the allocation query is reused. + +2016-05-13 13:14:23 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: destroy pool earlier if non-vaapi + If the offered pool in decide_allocation() vmethod doesn't have the + VAAPI_VIDEO_META option, it is destroyed immediatly and the pointer cleared, + so it could be created later. + +2016-05-23 22:30:04 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: split caps validation + When validating the caps from bufferpool config, this patch distinguishes the + error from no caps received (NULL) from the invalid caps (cannot be converted + into GstVideoInfo structure). + +2016-05-23 22:21:15 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + plugins: check for caps in query earlier + Check for caps as soon gst_query_parse_allocation() returns. + +2016-05-23 23:13:55 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: remove unused variables + This variables stopped to be used since commit 001a5c63, which removed the + gstvaapiuploader. + +2016-05-23 18:47:46 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: fix potential memleak from commit 9159328 + If gst_video_info_from_caps() fails it is required to unref the instantiated + pool. + +2016-05-23 18:04:47 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: handle if gst_video_info_from_caps() fails + Return FALSE is the received caps cannot be transformed into a GstVideoInfo + structure. + +2016-05-23 17:55:35 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: handle if gst_video_info_from_caps() fails + Let's play safe and return error if, somehow, the received caps are wrong. + +2016-05-23 17:47:36 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: relate errors to instance + Use GST_{ERROR,WARNING}_OBJECT instead of GST_{ERROR,WARNING}, thus the logs + will show the name of the vaapipluginbase instance that failed. + Also, the code-style is fixed, where some error labels need to be surrounded + by braces. + +2016-05-20 21:01:02 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapisink.c: + plugins: use GstVideoInfo accessors + Instead of access to GstVideInfo members directly, use their accessors + macros. This patch makes more resistance to future changes in GStreamer core. + +2016-05-20 19:33:39 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipostproc.c: + * tests/simple-encoder.c: + remove spurious gst_video_info_init() + gst_video_info_set_format() and gst_video_info_from_caps() call, internally, + gst_video_info_init(), hence it is not required to call it before them. This + patch removes these spurious calls. + +2016-05-20 19:15:11 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + vaapipluginbase: code-style: rename goto label + The error labels have error_ prefix, but this one. + +2016-05-19 16:34:50 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: use allocator custom alloc flag + Instead of a dummy alloc() vmethod, the allocator instance set the flag + GST_ALLOCATOR_FLAG_CUSTOM_ALLOC, which is used by the framework to avoid call + gst_allocator_alloc() on the allocator. + +2016-05-06 13:17:47 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: relate errors to instance + Use GST_ERROR_OBJECT instead of GST_ERROR, thus the logs will show the name of + the vaapivideobufferpool instance that failed. + +2016-05-10 16:14:48 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: remove gst_vaapi_plugin_base_set_pool_config() + This function helper make sense for GStreamer 1.2, but it is not helpful for + greater version since the validation is already done in the API implementation. + Thus, it is removed. + +2016-05-18 17:05:03 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapipluginbase.c: + gstvaapipluginbase: Fix typo in doc + +2016-05-13 11:45:20 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder : h264: Disable b-frame encode in low-power mode + This is a workaround since vaapi-intel-driver doesn't have + support for B-frame encode when utilizing low-power-enc + hardware block. + Fixme :We should query the VAConfigAttribEncMaxRefFrames + instead of blindly disabling b-frame support and set b/p frame count, + buffer pool size etc based on the query result. + https://bugzilla.gnome.org/show_bug.cgi?id=766050 + +2016-05-13 11:44:57 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + encoder: h264 : Use "tune=low-power" for enabling lowpower encode + Remove the duplicate property "low-power-enc" and use the + tune property for enabling low power encoding mode. + https://bugzilla.gnome.org/show_bug.cgi?id=766050 + +2016-05-11 12:06:38 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + gstvaapiencoder:Use internal api to dervie configured VAEntrypoint + https://bugzilla.gnome.org/show_bug.cgi?id=766050 + +2016-05-11 12:05:36 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + encoder: h264: Add support of low power/high performance encoding mode + Added a new property "low-power-enc" for enabling low power + encoding mode. Certain encoding tools may not be available + with the VAEntrypointEncSliceLP. + https://bugzilla.gnome.org/show_bug.cgi?id=766050 + +2016-05-11 12:04:46 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapivalue.c: + Add mapping for Macroblock level rate control (VA_RC_MB) + +2016-05-11 12:03:08 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + gstvaapidisplay: Add VAEntrypointEncSliceLP support + https://bugzilla.gnome.org/show_bug.cgi?id=766050 + +2016-05-11 11:59:59 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + gstvaapiprofile : Add VAEntrypointEncSliceLP definitions + This is for implementations that supports low_power/high_performance + variant for slice level encode. + https://bugzilla.gnome.org/show_bug.cgi?id=766050 + +2016-05-05 18:23:10 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: negotiate frame size fixation + Refactor _fixate_frame_size(). Now, instead of fixating the frame size only + using the sink caps, also it use the next capsfilter. + This code is a shameless copy of gst_video_scale_fixate_caps() from + https://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/gst/videoscale/gstvideoscale.c?id=1.8.1#n634 + https://bugzilla.gnome.org/show_bug.cgi?id=758548 + +2016-05-06 10:50:10 +0200 Scott D Phillips + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: don't use GstVideoInfo for src caps + Instead of using gst_video_info_to_caps () to generated the fixed src caps, + this patch enables the first step for caps negotiation with a possible + following caps filter. + _get_preferred_caps() will traverse the possible src caps looking for the one + wit the preferred feature and the preferred color format. Then the color + format, the frame size and the frame rate are fixated. + https://bugzilla.gnome.org/show_bug.cgi?id=758548 + +2016-05-05 15:32:36 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostprocutil.c: + * gst/vaapi/gstvaapipostprocutil.h: + vaapipostproc: move gst_vaapipostproc_fixate_srccaps() + Move gst_vaapipostproc_fixate_srccaps() to gstvaapiposptprocutil. + No functional changes. + https://bugzilla.gnome.org/show_bug.cgi?id=758548 + +2016-05-05 15:19:02 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: simplify code + Change a convoluted snippet to find the preferred color format in the peer + caps. + https://bugzilla.gnome.org/show_bug.cgi?id=758548 + +2016-05-05 15:16:02 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: use othercaps for preferred caps + Instead of the allowed_srcpad_caps variable, this patch uses the othercaps + from fixate_caps() vmethod to find the preferred caps feature and color + format. + https://bugzilla.gnome.org/show_bug.cgi?id=758548 + +2016-05-05 13:46:11 +0200 Scott D Phillips + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: add fixate_caps() vmethod + Instead of fixating the srcpad caps in transform_caps() vmethod, this patch + implements the fixate_caps() vmethod and moves code around. + https://bugzilla.gnome.org/show_bug.cgi?id=758548 + +2016-05-05 12:07:59 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostprocutil.c: + * gst/vaapi/gstvaapipostprocutil.h: + vaapipostproc: set early properties restrictions + When running transform_caps() vmethod, returning the srcpad caps, the caps are + early restricted to the element properties set: width, height, format and + force keep aspect. + A new file was added gstvaapipostprocutil.{c,h} where the utilities functions + are stored. + https://bugzilla.gnome.org/show_bug.cgi?id=758548 + +2016-04-25 13:45:04 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: log the caps transformation + https://bugzilla.gnome.org/show_bug.cgi?id=758548 + +2016-04-27 21:20:32 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: no GLTextureUpload in sinkpad + As the vaapipostproc does not process frames with the VideoGLTextureUpload + meta, the feature is removed from the sink pad template. + https://bugzilla.gnome.org/show_bug.cgi?id=765931 + +2015-09-28 08:49:39 +0100 Julien Isorce + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapibufferpool: do not create texture upload meta if dmabuf + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-05-06 12:16:26 +0200 Víctor Manuel Jáquez Leal + + * git.mk: + build: update git.mk + +2016-04-29 13:11:48 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.h: + plugin: fix macro processor check + Instead of #ifdef it should be used #if becasuse USE_GST_GL_HELPERS is always + defined in config.h, but it would be 0 or 1 depending on the configure output. + https://bugzilla.gnome.org/show_bug.cgi?id=765702 + +2016-04-29 12:53:06 +0200 Víctor Manuel Jáquez Leal + + * tests/test-display.c: + tests: display: guard possible unused variables + https://bugzilla.gnome.org/show_bug.cgi?id=765702 + +2016-04-29 12:48:44 +0200 Víctor Manuel Jáquez Leal + + * tests/codec.c: + * tests/decoder.c: + * tests/image.c: + * tests/output.c: + * tests/simple-decoder.c: + * tests/test-decode.c: + * tests/test-display.c: + * tests/test-filter.c: + * tests/test-h264.c: + * tests/test-jpeg.c: + * tests/test-mpeg2.c: + * tests/test-mpeg4.c: + * tests/test-subpicture-data.c: + * tests/test-subpicture.c: + * tests/test-surfaces.c: + * tests/test-textures.c: + * tests/test-vc1.c: + * tests/test-windows.c: + tests: inforce gstreamer code-style + +2016-04-27 17:10:26 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + encoder: h265: Enable cu_qp_delta_enabled_flag for CBR + It seems driver requires enablement of cu_qp_delta_enabled_flag + for modifying QP values to controll the CBR mode bitrate. + https://bugzilla.gnome.org/show_bug.cgi?id=749852 + +2016-04-27 17:06:09 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + encoder: h265: Add CBR Encoding support + https://bugzilla.gnome.org/show_bug.cgi?id=749852 + +2015-11-27 05:09:10 +0000 Julien Isorce + + * gst-libs/gst/vaapi/gstvaapisurface.c: + gstvaapisurface: explicitely clear TILING flag if dmabuf + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2015-10-04 23:44:16 +0100 Julien Isorce + + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + gstvaapisurface_drm: release image when done + Otherwise intel-vaapi-driver will fail to process the exported surface because + it will find it is currently derived, so considered as busy. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2015-09-26 06:25:12 +0100 Julien Isorce + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: already have a surface proxy if dmabuf + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-03-11 08:58:51 +0000 Julien Isorce + + * gst/vaapi/gstvaapipostproc.c: + various gst-indent + +2016-04-21 15:14:47 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + vaapidecode: search driver in whitelist + If the backend driver vendor string is not in a white-list, and the + environment variable GST_VAAPI_ALL_DRIVERS is not set either, the decoder will + change it state from NULL to READY, hence the auto-plug mechanism will look + for another decoder. + This patch assumes the GstContext has already being shared along the pipeline + and the element has a valid GstVaapiDisplay instance. + https://bugzilla.gnome.org/show_bug.cgi?id=764673 + +2016-04-21 12:57:30 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + plugins: rework set_context() vmethod definition + In bug 757598 was added the set_context() vmethod chain up in + GstVaapiPluginBase. But it is buggy, since the parent_class address is + assigned to the last element which called gst_vaapi_plugin_base_class_init(). + No error has shown up since none of the element's base classes redefined + set_context() vmethod from GstElement, so always the correct function was + called. Still this code is wrong and this patch make it right. + Since set_context() is the same code, a macro is used to implement that code + in all the gst-vaapi elements. + https://bugzilla.gnome.org/show_bug.cgi?id=765368 + +2016-04-15 17:57:25 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: resize if negotiated and allocation caps are different + Since commit 859a2b2, in vaapidecode, allocation query can be different from + the negotiated caps. + When connecting the vaapidecoder to the vaapipostprocessor, the last one will + resize the frame to the negotiated, if and only if, some other parameter is + activated to avoid the passthrough. If it is not, the surface won't be mapped + into a image. If not, the image won't be resized and the output buffer would be + mapped. + This patch will break the passthrough if the allocation query is different + from the negotiation caps, forcing the resizing. + https://bugzilla.gnome.org/show_bug.cgi?id=765095 + +2016-04-05 13:09:37 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: improve code readability + No functional changes. + +2016-04-05 13:37:40 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: move GstCapsFeatures near to its use + Move the handling of the GstCapsFeatures just after it is used, in order to + avoid handling its memory. + +2016-04-05 13:07:14 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: caps negotiation checks + Check that GLUploadTexture is not negotatiated if gstreamer-vaapi is not + compiled with GL support. + +2016-03-10 16:43:16 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipostproc.c: + plugins: remove param in gst_vaapi_plugin_base_decide_allocation() + +2016-03-10 16:42:04 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: bail early if not caps in decide_allocation() + +2016-03-29 14:17:54 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + plugin: use allowed caps filter from element + Instead of using the srcpad template caps for filtering the peer caps, the + function gst_vaapi_find_preferred_caps_feature(), now receives a new parameter + for the element's allowed caps. + With this modification, the vaapipostproc element simplifies a bit its code. + https://bugzilla.gnome.org/show_bug.cgi?id=765223 + +2016-04-18 17:28:51 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + plugin: remove function parameter + The native format parameter in gst_vaapi_find_preferred_caps_feature() can be + saved if the out format is used for both: in and out. Thus the code is more + readable. + https://bugzilla.gnome.org/show_bug.cgi?id=765223 + +2016-04-18 17:17:58 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: warns if driver will do color conversions + If the downstream feature is system memory, the surface has to be mapped, + hence a warning message is logged saying that the driver has to do color + conversions. This might be troublesome because not all the color conversion + combinations are supported by the VA-API drivers, and there is not a reliable + way to know them before hand. + https://bugzilla.gnome.org/show_bug.cgi?id=765223 + +2016-03-29 13:28:27 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugin: honour negotiated format + Instead of setting the requested format by the caller, the function + gst_vaapi_find_preferred_caps_feature() now returns, in the output parameter, + the negotiated format. + A new helper function was added: gst_vaapi_find_preferred_format(), which, + given the format list from the negotiated caps, will choose the best one, if + possible, given the native format. + https://bugzilla.gnome.org/show_bug.cgi?id=765223 + +2016-03-28 19:26:02 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugin: simplify caps feature selection + This patch simplifies the function gst_vaapi_find_preferred_caps_feature(). + Instead of intersecting custom caps to find the preferred feature, the peer + caps are traversed in order to find the preferred feature, according to an + ordered feature priority list. + In the case of GLTextureUploadMeta, the colour format is computed using + GstVideoInfo of the selected fixed caps. + https://bugzilla.gnome.org/show_bug.cgi?id=765223 + +2016-03-31 16:39:08 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: use macros for GstVideoInfo + Instead of accessing directly to the members of the structure, use the macros. + +2016-04-14 17:02:23 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: refactor is_display_resolution_changed() + Make the comparisons more readable and simple. + https://bugzilla.gnome.org/show_bug.cgi?id=764316 + +2016-04-14 16:43:07 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: keep only display_{width,height} + Instead of keeping the structure GstVideoInfo when we are using its width and + height, we only keep these two guints. + https://bugzilla.gnome.org/show_bug.cgi?id=764316 + +2016-04-14 16:31:34 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: decoded_info is valid at src caps update + As decoded_info is assured to be valid when gst_vaapidecode_update_src_caps() + is called, then we don't need to verify or replace it with the sinkpad info + (reference state). + https://bugzilla.gnome.org/show_bug.cgi?id=764316 + +2016-04-14 16:22:25 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: always a valid format in decoded_info + Always set a valid format in decoded_info class variable. + https://bugzilla.gnome.org/show_bug.cgi?id=764316 + +2016-03-25 15:31:28 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: code style fixes + No functional changes. + https://bugzilla.gnome.org/show_bug.cgi?id=764316 + +2016-04-14 16:10:02 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: init {decoded,display}_info at open() + It is required to initialize {decoded,display}_info variables when the decoder + is open, not only at instance initialization. + https://bugzilla.gnome.org/show_bug.cgi?id=764316 + +2016-03-28 15:30:28 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: remove spurious class variables + active, do_pool_renego and do_outstate_renego class variables were used to + indicate when negotiate downstream once, but now that each time a new surface + resolution is pop out a renegotation verified, these variable are not required + anymore. + https://bugzilla.gnome.org/show_bug.cgi?id=764316 + +2016-04-14 15:46:32 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipostproc.c: + remove custom allocation query + When resolving bug 753914, a custom allocation query was added, overlapping + the responsibilities of GstVideoDecoder. + But with the merge of the patches from bug 764421 this overlapping was not + required anymore. This patch restores this situation setting the + allocation_caps in the GstVideoCodecState when needed. + https://bugzilla.gnome.org/show_bug.cgi?id=764316 + +2016-04-14 10:04:47 +0100 Julien Isorce + + * common: + Automatic update of common submodule + From 6f2d209 to ac2f647 + +2016-04-13 15:44:20 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapipostproc.c: + plugins: disable GL_TEXTURE_UPLOAD if no EGL/GLX + The plugins should not expose the feature meta:GstVideoGLTextureUploadMeta in + their caps templates if they were not compiled either with GLX or EGL support. + +2016-04-13 20:33:32 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: fix compilation when EGL/GLX is disabled + The compiler might complain of gst_vaapi_create_display_from_handle() being + unused if both EGL and GLX are disabled. This patch avoid that compilation + error. + +2016-04-13 14:09:00 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapicodedbufferpool.c: + libs: fix deleting a GstVaapiCodedBufferPool object + Call gst_vaapi_video_pool_finalize() in coded_buffer_pool_finalize(). + Otherwise it is not called when the pool is destroyed and all objects + referenced by the GstVaapiVideoPool are never released. + https://bugzilla.gnome.org/show_bug.cgi?id=764993 + +2016-04-07 18:03:42 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface.c: + surface: destroy derived image + If gst_vaapi_image_new_with_image() fails, the created derived image should be + destroyed, otherwise the surface cannot be processed because is being used. + https://bugzilla.gnome.org/show_bug.cgi?id=764607 + +2016-03-18 20:00:52 -0300 Thiago Santos + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: add stop function + Clear any status on the current stream: + stored frames, caps and decoder configuration + https://bugzilla.gnome.org/show_bug.cgi?id=763460 + +2016-04-01 14:00:28 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9: Align with the ABI changes in vp9 codecparser + The subsampling_x, subsampling_y, bit_depth, color_space and color_range + fileds are moved from GstVp9FrameHdr to the global GstVp9Parser structure. + These fields are only present in keyframe or intra-only frame, no need to + duplicate them for inter-frames. + https://bugzilla.gnome.org/show_bug.cgi?id=764082 + +2016-04-01 13:59:59 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + decoder: vp9 : Add 10bit decoding support (Profile2) + https://bugzilla.gnome.org/show_bug.cgi?id=764082 + +2016-04-01 13:57:45 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + gstvaapiporfile: Add more VP9 profile definitions + https://bugzilla.gnome.org/show_bug.cgi?id=764082 + +2016-02-03 20:34:49 +0100 Víctor Manuel Jáquez Leal + + * Makefile.am: + * configure.ac: + build: possibility to disable tests + The configuration option --disable-examples will disable the compilation of + the sample apps in tests/ directory. + +2016-03-29 14:25:55 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapisink.c: + unify caps template for VAAPI encoders and decoders + There is no difference in VAAPI surface caps between encoders and decoders. + Thus, the patch makes a simplification by removing encoders specific caps and + shares the same definition of VAAPI surfaces caps for all the elements. + +2016-03-10 17:42:55 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: move gst_vaapidecode_negotiate() code + With it we can remove a function declaration, making the code a bit + more readable. + https://bugzilla.gnome.org/show_bug.cgi?id=764316 + +2016-03-29 13:50:00 +0200 Víctor Manuel Jáquez Leal + + * docs/plugins/gstreamer-vaapi-plugins-docs.xml.in: + * docs/plugins/gstreamer-vaapi-plugins-sections.txt: + * gst/vaapi/gstvaapidecode.c: + docs: generate vaapijpegdec documentation + https://bugzilla.gnome.org/show_bug.cgi?id=764314 + +2016-03-30 14:37:21 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: h265: Fix offset calculation when there is more than one vps/sps/pps present in codec_data + The array_completeness, reserved bit and num_nal_units fields + in HEVCDecoderConfigurationRecord will be present for each VPS/SPS/PPS array list, + but not for each occurance of similar headers. + https://bugzilla.gnome.org/show_bug.cgi?id=764274 + +2016-03-29 15:34:38 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/video-format.c: + video-format: Keep the HW order preference while mapping to GstVideoFormats + +2016-03-29 15:02:46 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapivideomemory.c: + gst/vaapi: keep precedence for NV12 over I420 + Use NV12 as default "assumption" format all over. + NV12 is the default high priority format used my most of the + vaapi-drivers. + +2016-03-29 14:34:37 +0300 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Use video format derived from decoded surface as default src pad format + Use the surface format derived from first decoded surface + to negotiate the downstream video format capabilities. + https://bugzilla.gnome.org/show_bug.cgi?id=759181 + +2016-03-29 14:34:00 +0300 Scott D Phillips + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/video-format.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapisink.c: + Add P010 video format support + The P010 video format is the native format used by the vaapi intel driver + for HEVCMain10 decode . Add support for planes and images of this video format. + https://bugzilla.gnome.org/show_bug.cgi?id=759181 + +2016-03-27 09:11:00 +0000 Stephen + + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + libs: x11: allows 30-bit colour depth + The colour depth is clamped to 24 when it is not equal {15,16,24,32}. But this + fails with the NVIDIA binary driver as it doesn't advertise a TrueColor visual + with a depth of 24 (only 30 and 32). Allowing the depth to be 30, lets everything + work as expected. + https://bugzilla.gnome.org/show_bug.cgi?id=764256 + +2016-03-28 13:13:56 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideometa_texture.c: + gltextureupload: use an array for texture type + Instead of using a single value for the texture type, use an array with 4 + elements, just as the GstVideoGLTextureUploadMeta, avoiding a buffer + overflow. + https://bugzilla.gnome.org/show_bug.cgi?id=764231 + +2016-03-24 15:09:43 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + vaapidecode: Fix decide_allocation handling + Set the already configured pool in decide_allocation query + in cases where pool renegotiation is not required. + https://bugzilla.gnome.org/show_bug.cgi?id=753914 + +2016-03-24 15:09:15 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Derive and save the decoded surface format + After the decoding of first frame, try to extract the exact + decoded surface format using vaDeriveImage and keep this + as the format in decoded_info. + https://bugzilla.gnome.org/show_bug.cgi?id=753914 + +2016-03-24 15:08:50 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipostproc.c: + Make vaapidecode to advertise the cropped values in srcpad, but negotiate pool only if needed + -- Maintaing decoded surface resoluton and actual display resoultion separately + -- Before pushing every frames downstream, check for the requirement of pool negoation and + output_state negotiation: This is needed to avoid multiple issuses with cropping, + multi-resoluton video handling, more complex multi resolution decode scenarios for vp9decode, + possible wrong behaviour from upstream element to report uncropped values etc. Due to these reasons, + We can't just reliably use the resolution change notification from libgstvaapi for pool renegotiation too. + This is slight overhead, but safe enough. Optimization could be possible though. + https://bugzilla.gnome.org/show_bug.cgi?id=753914 + +2016-03-24 15:08:27 +0200 Sreerenj Balachandran + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Delay the output format setting until we have a decoded surface + This will help to consoidate the out caps negotiation to a single place, + which will make the code simpler, allows to get the exact decoded format + if needed and the selected chroma type too. + https://bugzilla.gnome.org/show_bug.cgi?id=753914 + +2016-03-24 13:36:24 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.h: + vaapidecode: GST_VAAPIDECODE macro is a cast + This patch is the continuation of commit 1e1d3b1d because the function + gst_vaapidecode_get_type() got undefined since then. + Now, the macro GST_VAAPIDECODE is a simple cast to the GstVaapiDecode + structure. The rest of the GObject handling macros were deleted too. + +2016-03-24 13:34:18 +0200 Sebastian Dröge + + * configure.ac: + Back to development + +=== release 1.8.0 === + +2016-03-24 13:11:05 +0200 Sebastian Dröge + + * ChangeLog: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + Release 1.8.0 === release 1.7.91 === diff --git a/NEWS b/NEWS index ee7f213e57..4c3baabdc2 100644 --- a/NEWS +++ b/NEWS @@ -1,786 +1 @@ -# GStreamer 1.8 Release Notes - -**GStreamer 1.8.0 was released on 24 March 2016.** - -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 new features, bug fixes and other -improvements. - -See [https://gstreamer.freedesktop.org/releases/1.8/][latest] for the latest -version of this document. - -*Last updated: Thursday 24 March 2016, 10:00 UTC [(log)][gitlog]* - -[latest]: https://gstreamer.freedesktop.org/releases/1.8/ -[gitlog]: https://cgit.freedesktop.org/gstreamer/www/log/src/htdocs/releases/1.8/release-notes-1.8.md - -## Highlights - -- **Hardware-accelerated zero-copy video decoding on Android** - -- **New video capture source for Android using the android.hardware.Camera API** - -- **Windows Media reverse playback** support (ASF/WMV/WMA) - -- **New tracing system** provides support for more sophisticated debugging tools - -- **New high-level GstPlayer playback convenience API** - -- **Initial support for the new [Vulkan][vulkan] API**, see - [Matthew Waters' blog post][vulkan-in-gstreamer] for more details - -- **Improved Opus audio codec support**: Support for more than two channels; MPEG-TS demuxer/muxer can now handle Opus; - [sample-accurate][opus-sample-accurate] encoding/decoding/transmuxing with - Ogg, Matroska, ISOBMFF (Quicktime/MP4), and MPEG-TS as container; - [new codec utility functions for Opus header and caps handling][opus-codec-utils] - in pbutils library. The Opus encoder/decoder elements were also moved to - gst-plugins-base (from -bad), and the opus RTP depayloader/payloader to -good. - - [opus-sample-accurate]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstaudiometa.html#GstAudioClippingMeta - [opus-codec-utils]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstpbutilscodecutils.html - -- **GStreamer VAAPI module now released and maintained as part of the GStreamer project** - - [vulkan]: https://www.khronos.org/vulkan - [vulkan-in-gstreamer]: http://ystreet00.blogspot.co.uk/2016/02/vulkan-in-gstreamer.html - -## Major new features and changes - -### Noteworthy new API, features and other changes - -- New GstVideoAffineTransformationMeta meta for adding a simple 4x4 affine - transformation matrix to video buffers - -- [g\_autoptr()](https://developer.gnome.org/glib/stable/glib-Miscellaneous-Macros.html#g-autoptr) - support for all types is exposed in GStreamer headers now, in combination - with a sufficiently-new GLib version (i.e. 2.44 or later). This is primarily - for the benefit of application developers who would like to make use of - this, the GStreamer codebase itself will not be using g_autoptr() for - the time being due to portability issues. - -- GstContexts are now automatically propagated to elements added to a bin - or pipeline, and elements now maintain a list of contexts set on them. - The list of contexts set on an element can now be queried using the new functions - [gst\_element\_get\_context()](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#gst-element-get-context) - and [gst\_element\_get\_contexts()](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#gst-element-get-contexts). GstContexts are used to share context-specific configuration objects - between elements and can also be used by applications to set context-specific - configuration objects on elements, e.g. for OpenGL or Hardware-accelerated - video decoding. - -- New [GST\_BUFFER\_DTS\_OR\_PTS()](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstBuffer.html#GST-BUFFER-DTS-OR-PTS:CAPS) - convenience macro that returns the decode timestamp if one is set and - otherwise returns the presentation timestamp - -- New GstPadEventFullFunc that returns a GstFlowReturn instead of a gboolean. - This new API is mostly for internal use and was added to fix a race condition - where occasionally internal flow error messages were posted on the bus when - sticky events were propagated at just the wrong moment whilst the pipeline - was shutting down. This happened primarily when the pipeline was shut down - immediately after starting it up. GStreamer would not know that the reason - the events could not be propagated was because the pipeline was shutting down - and not some other problem, and now the flow error allows GStreamer to know - the reason for the failure (and that there's no reason to post an error - message). This is particularly useful for queue-like elements which may need - to asynchronously propagate a previous flow return from downstream. - -- Pipeline dumps in form of "dot files" now also show pad properties that - differ from their default value, the same as it does for elements. This is - useful for elements with pad subclasses that provide additional properties, - e.g. videomixer or compositor. - -- Pad probes are now guaranteed to be called in the order they were added - (before they were called in reverse order, but no particular order was - documented or guaranteed) - -- Plugins can now have dependencies on device nodes (not just regular files) - and also have a prefix filter. This is useful for plugins that expose - features (elements) based on available devices, such as the video4linux - plugin does with video decoders on certain embedded systems. - -- gst\_segment\_to\_position() has been deprecated and been replaced by the - better-named gst\_segment\_position\_from\_running\_time(). At the same time - gst\_segment\_position\_from\_stream\_time() was added, as well as \_full() - variants of both to deal with negative stream time. - -- GstController: the interpolation control source gained a new monotonic cubic - interpolation mode that, unlike the existing cubic mode, will never overshoot - the min/max y values set. - -- GstNetAddressMeta: can now be read from buffers in language bindings as well, - via the new gst\_buffer\_get\_net\_address\_meta() function - -- ID3 tag PRIV frames are now extraced into a new GST\_TAG\_PRIVATE\_DATA tag - -- gst-launch-1.0 and gst\_parse\_launch() now warn in the most common case if - a dynamic pad link could not be resolved, instead of just silently - waiting to see if a suitable pad appears later, which is often perceived - by users as hanging -- they are now notified when this happens and can check - their pipeline. - -- GstRTSPConnection now also parses custom RTSP message headers and retains - them for the application instead of just ignoring them - -- rtspsrc handling of authentication over tunneled connections (e.g. RTSP over HTTP) - was fixed - -- gst\_video\_convert\_sample() now crops if there is a crop meta on the input buffer - -- The debugging system printf functions are now exposed for general use, which - supports special printf format specifiers such as GST\_PTR\_FORMAT and - GST\_SEGMENT\_FORMAT to print GStreamer-related objects. This is handy for - systems that want to prepare some debug log information to be output at a - later point in time. The GStreamer-OpenGL subsystem is making use of these - new functions, which are [gst\_info\_vasprintf()][gst_info_vasprintf], - [gst\_info\_strdup\_vprintf()][gst_info_strdup_vprintf] and - [gst\_info\_strdup\_printf()][gst_info_strdup_printf]. - -- videoparse: "strides", "offsets" and "framesize" properties have been added to - allow parsing raw data with strides and padding that do not match GStreamer - defaults. - -- GstPreset reads presets from the directories given in GST\_PRESET\_PATH now. - Presets are read from there after presets in the system path, but before - application and user paths. - -[gst_info_vasprintf]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-info-vasprintf -[gst_info_strdup_vprintf]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-info-strdup-vprintf -[gst_info_strdup_printf]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-info-strdup-printf - -### New Elements - -- [netsim](): a new (resurrected) element to simulate network jitter and - packet dropping / duplication. - -- New VP9 RTP payloader/depayloader elements: rtpvp9pay/rtpvp9depay - -- New [videoframe_audiolevel]() element, a video frame synchronized audio level element - -- New spandsp-based tone generator source - -- New NVIDIA NVENC-based H.264 encoder for GPU-accelerated video encoding on - suitable NVIDIA hardware - -- [rtspclientsink](), a new RTSP RECORD sink element, was added to gst-rtsp-server - -- [alsamidisrc](), a new ALSA MIDI sequencer source element - -### Noteworthy element features and additions - -- *identity*: new ["drop-buffer-flags"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-identity.html#GstIdentity--drop-buffer-flags) - property to drop buffers based on buffer flags. This can be used to drop all - non-keyframe buffers, for example. - -- *multiqueue*: various fixes and improvements, in particular special handling - for sparse streams such as substitle streams, to make sure we don't overread - them any more. For sparse streams it can be normal that there's no buffer for - a long period of time, so having no buffer queued is perfectly normal. Before - we would often unnecessarily try to fill the subtitle stream queue, which - could lead to much more data being queued in multiqueue than necessary. - -- *multiqueue*/*queue*: When dealing with time limits, these elements now use the - new ["GST_BUFFER_DTS_OR_PTS"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstBuffer.html#GST-BUFFER-DTS-OR-PTS:CAPS) - and ["gst_segment_to_running_time_full()"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstSegment.html#gst-segment-to-running-time-full) - API, resulting in more accurate levels, especially when dealing with non-raw - streams (where reordering happens, and we want to use the increasing DTS as - opposed to the non-continuously increasing PTS) and out-of-segment input/output. - Previously all encoded buffers before the segment start, which can happen when - doing ACCURATE seeks, were not taken into account in the queue level calculation. - -- *multiqueue*: New ["use-interleave"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-multiqueue.html#GstMultiQueue--use-interleave) - property which allows the size of the queues to be optimized based on the input - streams interleave. This should only be used with input streams which are properly - timestamped. It will be used in the future decodebin3 element. - -- *queue2*: new ["avg-in-rate"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-queue2.html#GstQueue2--avg-in-rate) - property that returns the average input rate in bytes per second - -- audiotestsrc now supports all audio formats and is no longer artificially - limited with regard to the number of channels or sample rate - -- gst-libav (ffmpeg codec wrapper): map and enable JPEG2000 decoder - -- multisocketsink can, on request, send a custom GstNetworkMessage event - upstream whenever data is received from a client on a socket. Similarly, - socketsrc will, on request, pick up GstNetworkMessage events from downstream - and send any data contained within them via the socket. This allows for - simple bidirectional communication. - -- matroska muxer and demuxer now support the ProRes video format - -- Improved VP8/VP9 decoding performance on multi-core systems by enabling - multi-threaded decoding in the libvpx-based decoders on such systems - -- appsink has a new ["wait-on-eos"](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-appsink.html#GstAppSink--wait-on-eos) - property, so in cases where it is uncertain if an appsink will have a consumer for - its buffers when it receives an EOS this can be set to FALSE to ensure that the - appsink will not hang. - -- rtph264pay and rtph265pay have a new "config-interval" mode -1 that will - re-send the setup data (SPS/PPS/VPS) before every keyframe to ensure - optimal coverage and the shortest possibly start-up time for a new client - -- mpegtsmux can now mux H.265/HEVC video as well - -- The MXF muxer was ported to 1.x and produces more standard conformant files now - that can be handled by more other software; The MXF demuxer got improved - support for seek tables (IndexTableSegments). - -### Plugin moves - -- The rtph265pay/depay RTP payloader/depayloader elements for H.265/HEVC video - from the rtph265 plugin in -bad have been moved into the existing rtp plugin - in gst-plugins-good. - -- The mpg123 plugin containing a libmpg123 based audio decoder element has - been moved from -bad to -ugly. - -- The Opus encoder/decoder elements have been moved to gst-plugins-base and - the RTP payloader to gst-plugins-good, both coming from gst-plugins-bad. - -### New tracing tools for developers - -A new tracing subsystem API has been added to GStreamer, which provides -external tracers with the possibility to strategically hook into GStreamer -internals and collect data that can be evaluated later. These tracers are a -new type of plugin features, and GStreamer core ships with a few example -tracers (latency, stats, rusage, log) to start with. Tracers can be loaded -and configured at start-up via an environment variable (GST\_TRACER\_PLUGINS). - -Background: While GStreamer provides plenty of data on what's going on in a -pipeline via its debug log, that data is not necessarily structured enough to -be generally useful, and the overhead to enable logging output for all data -required might be too high in many cases. The new tracing system allows tracers -to just obtain the data needed at the right spot with as little overhead as -possible, which will be particularly useful on embedded systems. - -Of course it has always been possible to do performance benchmarks and debug -memory leaks, memory consumption and invalid memory access using standard -operating system tools, but there are some things that are difficult to track -with the standard tools, and the new tracing system helps with that. Examples -are things such as latency handling, buffer flow, ownership transfer of -events and buffers from element to element, caps negotiation, etc. - -For some background on the new tracing system, watch Stefan Sauer's -GStreamer Conference talk ["A new tracing subsystem for GStreamer"][tracer-0] -and for a more specific example how it can be useful have a look at -Thiago Santos's lightning talk ["Analyzing caps negotiation using GstTracer"][tracer-1] -and his ["GstTracer experiments"][tracer-2] blog post. There was also a Google -Summer of Code project in 2015 that used tracing system for a graphical -GStreamer debugging tool ["gst-debugger"][tracer-3]. - -This is all still very much work in progress, but we hope this will provide the -foundation for a whole suite of new debugging tools for GStreamer pipelines. - -[tracer-0]: https://gstconf.ubicast.tv/videos/a-new-tracing-subsystem-for-gstreamer/ -[tracer-1]: https://gstconf.ubicast.tv/videos/analyzing-caps-negotiation-using-gsttracer/ -[tracer-2]: http://blog.thiagoss.com/2015/07/23/gsttracer-experiments/ -[tracer-3]: https://git.gnome.org/browse/gst-debugger - -### GstPlayer: a new high-level API for cross-platform multimedia playback - -GStreamer has had reasonably high-level API for multimedia playback -in the form of the playbin element for a long time. This allowed application -developers to just configure a URI to play, and playbin would take care of -everything else. This works well, but there is still way too much to do on -the application-side to implement a fully-featured playback application, and -too much general GStreamer pipeline API exposed, making it less accessible -to application developers. - -Enter GstPlayer. GstPlayer's aim is to provide an even higher-level abstraction -of a fully-featured playback API but specialised for its specific use case. It -also provides easy integration with and examples for Gtk+, Qt, Android, OS/X, -iOS and Windows. Watch Sebastian's [GstPlayer talk at the GStreamer Conference][gstplayer-talk] -for more information, or check out the [GstPlayer API reference][gstplayer-api] -and [GstPlayer examples][gstplayer-examples]. - -[gstplayer-api]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/player.html -[gstplayer-talk]: https://gstconf.ubicast.tv/videos/gstplayer-a-simple-cross-platform-api-for-all-your-media-playback-needs-part-1/ -[gstplayer-examples]: https://github.com/sdroege/gst-player/ - -### Adaptive streaming: DASH, HLS and MSS improvements - -- dashdemux now supports loading external xml nodes pointed from its MPD. - -- Content protection nodes parsing support for PlayReady WRM in mssdemux. - -- Reverse playback was improved to respect seek start and stop positions. - -- Adaptive demuxers (hlsdemux, dashdemux, mssdemux) now support the SNAP_AFTER - and SNAP_BEFORE seek flags which will jump to the nearest fragment boundary - when executing a seek, which means playback resumes more quickly after a seek. - -### Audio library improvements - -- audio conversion, quantization and channel up/downmixing functionality - has been moved from the audioconvert element into the audio library and - is now available as public API in form of [GstAudioConverter][audio-0], - [GstAudioQuantize][audio-1] and [GstAudioChannelMixer][audio-2]. - Audio resampling will follow in future releases. - -- [gst\_audio\_channel\_get\_fallback\_mask()][audio-3] can be used - to retrieve a default channel mask for a given number of channels as last - resort if the layout is unknown - -- A new [GstAudioClippingMeta][audio-4] meta was added for specifying clipping - on encoded audio buffers - -- A new GstAudioVisualizer base class for audio visualisation elements; - most of the existing visualisers have been ported over to the new base class. - This new base class lives in the pbutils library rather than the audio library, - since we'd have had to make libgstaudio depend on libgstvideo otherwise, - which was deemed undesirable. - -[audio-0]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-GstAudioConverter.html -[audio-1]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-GstAudioQuantize.html -[audio-2]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstaudiochannels.html#gst-audio-channel-mix-new -[audio-3]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstaudiochannels.html#gst-audio-channel-get-fallback-mask -[audio-4]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstaudiometa.html#GstAudioClippingMeta - -### GStreamer OpenGL support improvements - -#### Better OpenGL Shader support - -[GstGLShader][shader] has been revamped to allow more OpenGL shader types -by utilizing a new GstGLSLStage object. Each stage holds an OpenGL pipeline -stage such as a vertex, fragment or a geometry shader that are all compiled -separately into a program that is executed. - -The glshader element has also received a revamp as a result of the changes in -the library. It does not take file locations for the vertex and fragment -shaders anymore. Instead it takes the strings directly leaving the file -management to the application. - -A new [example][liveshader-example] was added utilizing the new shader -infrastructure showcasing live shader edits. - -[shader]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-gstglshader.html -[liveshader-example]: https://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/tests/examples/gtk/glliveshader.c - -#### OpenGL GLMemory rework - -[GstGLMemory] was extensively reworked to support the addition of multiple -texture targets required for zero-copy integration with the Android -MediaCodec elements. This work was also used to provide IOSurface based -GLMemory on OS X for zero-copy with OS X's VideoToolbox decoder (vtdec) and -AV Foundation video source (avfvideosrc). There are also patches in bugzilla -for GstGLMemoryEGL specifically aimed at improving the decoding performance on -the Raspberry Pi. - -[GstGLMemory]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-gstglmemory.html - -A texture-target field was added to video/x-raw(memory:GLMemory) caps to signal -the texture target contained in the GLMemory. Its values can be 2D, rectangle -or external-oes. glcolorconvert can convert between the different formats as -required and different elements will accept or produce different targets. e.g. -glimagesink can take and render external-oes textures directly as required for -effecient zero-copy on android. - -A generic GL allocation framework was also implemented to support the generic -allocation of OpenGL buffers and textures which is used extensively by -GstGLBufferPool. - -#### OpenGL DMABuf import uploader - -There is now a DMABuf uploader available for automatic selection that will -attempt to import the upstream provided DMABuf. The uploader will import into -2D textures with the necesarry format. YUV to RGB conversion is still provided -by glcolorconvert to avoid the laxer restrictions with external-oes textures. - -#### OpenGL queries - -Queries of various aspects of the OpenGL runtime such as timers, number of -samples or the current timestamp are not possible. The GstGLQuery object uses a -delayed debug system to delay the debug output to later to avoid expensive calls -to the glGet\* family of functions directly after finishing a query. It is -currently used to output the time taken to perform various operations of texture -uploads and downloads in GstGLMemory. - -#### New OpenGL elements - -glcolorbalance has been created mirroring the videobalance elements. -glcolorbalance provides the exact same interface as videobalance so can be used -as a GPU accelerated replacement. glcolorbalance has been added to glsinkbin so -usage with playsink/playbin will use it automatically instead of videobalance -where possible. - -glvideoflip, which is the OpenGL equiavalant of videoflip, implements the exact -same interface and functionality as videoflip. - -#### EGL implementation now selects OpenGL 3.x - -The EGL implementation can now select OpenGL 3.x contexts. - -#### OpenGL API removal - -The GstGLDownload library object was removed as it was not used by anything. -Everything is performed by GstGLMemory or in the gldownloadelement. - -The GstGLUploadMeta library object was removed as it was not being used and we -don't want to promote the use of GstVideoGLTextureUploadMeta. - -#### OpenGL: Other miscellaneous changes - -- The EGL implementation can now select OpenGL 3.x contexts. This brings - OpenGL 3.x to e.g. wayland and other EGL systems. - -- glstereomix/glstereosplit are now built and are usable on OpenGL ES systems - -- The UYVY/YUY2 to RGBA and RGBA to UYVY/YUY2 shaders were fixed removing the - sawtooth pattern and luma bleeding. - -- We now utilize the GL\_APPLE\_sync extension on iOS devices which improves - performance of OpenGL applications, especially with multiple OpenGL - contexts. - -- glcolorconvert now uses a bufferpool to avoid costly - glGenTextures/glDeleteTextures for every frame. - -- glvideomixer now has full glBlendFunc and glBlendEquation support per input. - -- gltransformation now support navigation events so your weird transformations - also work with DVD menus. - -- qmlglsink can now run on iOS, OS X and Android in addition to the already - supported Linux platform. - -- glimagesink now posts unhandled keyboard and mouse events (on backends that - support user input, current only X11) on the bus for the application. - -### Initial GStreamer Vulkan support - -Some new elements, vulkansink and vulkanupload have been implemented utilizing -the new Vulkan API. The implementation is currently limited to X11 platforms -(via xcb) and does not perform any scaling of the stream's contents to the size -of the available output. - -A lot of infrasctructure work has been undertaken to support using Vulkan in -GStreamer in the future. A number of GstMemory subclasses have been created for -integrating Vulkan's GPU memory handling along with VkBuffer's and VkImage's -that can be passed between elements. Some GStreamer refcounted wrappers for -global objects such as VkInstance, VkDevice, VkQueue, etc have also been -implemented along with GstContext integration for sharing these objects with the -application. - -### GStreamer VAAPI support for hardware-accelerated video decoding and encoding on Intel (and other) platforms - -#### GStreamer VAAPI is now part of upstream GStreamer - -The GStreamer-VAAPI module which provides support for hardware-accelerated -video decoding, encoding and post-processing on Intel graphics hardware -on Linux has moved from its previous home at the [Intel Open Source Technology Center][iostc] -to the upstream GStreamer repositories, where it will in future be maintained -as part of the upstream GStreamer project and released in lockstep with the -other GStreamer modules. The current maintainers will continue to spearhead -the development at the new location: - -[http://cgit.freedesktop.org/gstreamer/gstreamer-vaapi/][gst-vaapi-git] - -[gst-vaapi-git]: http://cgit.freedesktop.org/gstreamer/gstreamer-vaapi/ - -GStreamer-VAAPI relies heavily on certain GStreamer infrastructure API that -is still in flux such as the OpenGL integration API or the codec parser -libraries, and one of the goals of the move was to be able to leverage -new developments early and provide tighter integration with the latest -developments of those APIs and other graphics-related APIs provided by -GStreamer, which should hopefully improve performance even further and in -some cases might also provide better stability. - -Thanks to everyone involved in making this move happen! - -#### GStreamer VAAPI: Bug tracking - -Bugs had already been tracked on [GNOME bugzilla](bgo) but will be moved -from the gstreamer-vaapi product into a new gstreamer-vaapi component of -the GStreamer product in bugzilla. Please file new bugs against the new -component in the GStreamer product from now on. - -#### GStreamer VAAPI: Pending patches - -The code base has been re-indented to the GStreamer code style, which -affected some files more than others. This means that some of the patches -in bugzilla might not apply any longer, so if you have any unmerged patches -sitting in bugzilla please consider checking if they still apply cleany and -refresh them if not. Sorry for any inconvenience this may cause. - -#### GStreamer VAAPI: New versioning scheme and supported GStreamer versions - -The version numbering has been changed to match the GStreamer version -numbering to avoid confusion: there is a new gstreamer-vaapi 1.6.0 release -and a 1.6 branch that is roughly equivalent to the previous 0.7.0 version. -Future releases 1.7.x and 1.8.x will be made alongside GStreamer releases. - -While it was possible and supported by previous releases to build against -a whole range of different GStreamer versions (such as 1.2, 1.4, 1.6 or 1.7/1.8), -in the future there will only be one target branch, so that git master will -track GStreamer git master, 1.8.x will target GStreamer 1.8, and -1.6.x will target the 1.6 series. - -[iostc]: http://01.org -[bgo]: http://bugzilla.gnome.og - -#### GStreamer VAAPI: Miscellaneous changes - -All GStreamer-VAAPI functionality is now provided solely by its GStreamer -elements. There is no more public library exposing GstVaapi API, this API -was only ever meant for private use by the elements. Parts of it may be -resurrected again in future if needed, but for now it has all been made -private. - -GStreamer-VAAPI now unconditionally uses the codecparser library in -gst-plugins-bad instead of shipping its own internal copy. Similarly, -it no longer ships its own codec parsers but relies on the upstream -codec parser elements. - -The GStreamer-VAAPI encoder elements have been renamed from vaapiencode_foo -to vaapifooenc, so encoders are now called vaapih264enc, vaapih265enc, -vaapimpeg2enc, vaapijpegenc, and vaapivp8enc. With this change we now follow -the standard names in GStreamer, and the plugin documentation is generated -correctly. - -In the case of the decoders, only the jpeg decoder has been split from the -general decoding element vaapidecode: vaapijpegdec. This is the first step to -split per codec each decoding element. The vaapijpegdec has also been given -marginal rank for the time being. - -#### GStreamer VAAPI: New features in 1.8: 10-bit H.265/HEVC decoding support - -Support for decoding 10-bit H.265/HEVC has been added. For the time being -this only works in combination with vaapisink though, until support for the -P010 video format used internally is added to GStreamer and to the -vaGetImage()/vaPutimage() API in the vaapi-intel-driver. - -Several fixes for memory leaks, build errors, and in the internal -video parsing. - -Finally, vaapisink now posts the unhandled keyboard and mouse events to the -application. - -### GStreamer Video 4 Linux Support - -Colorimetry support has been enhanced even more. It will now properly select -default values when not specified by the driver. The range of color formats -supported by GStreamer has been greatly improved. Notably, support for -multi-planar I420 has been added along with all the new and non-ambiguous RGB -formats that got added in recent kernels. - -The device provider now exposes a variety of properties as found in the udev -database. - -The video decoder is now able to negotiate the downstream format. - -Elements that are dynamically created from /dev/video\* now track changes on -these devices to ensure the registry stay up to date. - -All this and various bug fixes that improve both stability and correctness. - -### GStreamer Editing Services - -Added APIs to handle asset proxying support. Proxy creation is not the -responsibility of GES itself, but GES provides all the needed features -for it to be cleanly handled at a higher level. - -Added support for changing playback rate. This means that now, whenever a -user adds a 'pitch' element (as it is the only known element to change playback -rate through properties), GES will handle everything internally. This change -introduced a new media-duration-factor property in NleObject which will -lead to tweaking of seek events so they have the proper playback range to be -requested upstream. - -Construction of NLE objects has been reworked making copy/pasting fully -functional and allowing users to set properties on effects right after -creating them. - -Rework of the title source to add more flexibility in text positioning, -and letting the user get feedback about rendered text positioning. - -Report nlecomposition structural issues (coming from user programing mistakes) -into ERROR messages on the bus. - -Add GI/pythyon testsuite in GES itself, making sure the API is working as expected -in python, and allowing writing tests faster. - -### GstValidate - -Added support to run tests inside gdb. - -Added a 'smart' reporting mode where we give as much information as possible about -critical errors. - -Uses GstTracer now instead of a LD\_PRELOAD library. - -## Miscellaneous - -- encodebin now works with "encoder-muxers" such as wavenc - -- gst-play-1.0 acquired a new keyboard shortcut: '0' seeks back to the start - -- gst-play-1.0 supports two new command line switches: -v for verbose output - and --flags to configure the playbin flags to use. - -## Build and Dependencies - -- The GLib dependency requirement was bumped to 2.40 - -- The -Bsymbolic configure check now works with clang as well - -- ffmpeg is now required as libav provider, incompatible changes were - introduced that make it no longer viable to support both FFmpeg and Libav - as libav providers. Most major distros have switched to FFmpeg or are in - the process of switching to it anyway, so we don't expect this to be a - problem, and there is still an internal copy of ffmpeg that can be used - as fallback if needed. - -- The internal ffmpeg snapshot is now FFMpeg 3.0, but it should be possible - to build against 2.8 as well for the time being. - -## Platform-specific improvements - -### Android - -- Zero-copy video decoding on Android using the hardware-accelerated decoders - has been implemented, and is fully integrated with the GStreamer OpenGL stack - -- ahcsrc, a new camera source element, has been merged and can be used to - capture video on android devices. It uses the android.hardware.Camera Java - API to capture from the system's cameras. - -- The OpenGL-based QML video sink can now also be used on Android - -- New tinyalsasink element, which is mainly useful for Android but can also - be used on other platforms. - -### OS/X and iOS - -- The system clock now uses mach\_absolute\_time() on OSX/iOS, which is - the preferred high-resolution monotonic clock to be used on Apple platforms - -- The OpenGL-based QML video sink can now also be used on OS X and iOS (with - some Qt build system massaging) - -- New IOSurface based memory implementation in avfvideosrc and vtdec on OS X - for zerocopy with OpenGL. The previously used OpenGL extension - GL_APPLE_ycbcr_422 is not compatible with GL 3.x core contexts. - -- New GstAppleCoreVideoMemory wrapping CVPixelBuffer's - -- avfvideosrc now supports renegotiation. - -### Windows - -- Various bugs with UDP and multicast were fixed on Windows, mostly related to - gst-rtsp-server. - -- A few bugs in directsoundsrc and directsoundsink were fixed that could cause - the element to lock up. Also the "mute" property on the sink was fixed, and - a new "device" property for device selection was added to the source. - -## Known Issues - -- Building GStreamer applications with the Android NDK r11 is currently not - supported due to incompatible changes in the NDK. This is expected to be - fixed for 1.8.1. - [Bugzilla #763999](https://bugzilla.gnome.org/show_bug.cgi?id=763999) - -- vp8enc crashes on 32 bit Windows, but was working fine in 1.6. 64 bit - Windows is unaffected. - [Bugzilla #763663](https://bugzilla.gnome.org/show_bug.cgi?id=763663) - -## Contributors - -Adam Miartus, Alban Bedel, Aleix Conchillo Flaqué, Aleksander Wabik, -Alessandro Decina, Alex Ashley, Alex Dizengof, Alex Henrie, Alistair Buxton, -Andreas Cadhalpun, Andreas Frisch, André Draszik, Anthony G. Basile, -Antoine Jacoutot, Anton Bondarenko, Antonio Ospite, Arjen Veenhuizen, -Arnaud Vrac, Arun Raghavan, Athanasios Oikonomou, Aurélien Zanelli, Ben Iofel, -Bob Holcomb, Branko Subasic, Carlos Rafael Giani, Chris Bass, Csaba Toth, -Daniel Kamil Kozar, Danilo Cesar Lemes de Paula, Dave Craig, David Fernandez, -David Schleef, David Svensson Fors, David Waring, David Wu, Duncan Palmer, -Edward Hervey, Egor Zaharov, Etienne Peron, Eunhae Choi, Evan Callaway, -Evan Nemerson, Fabian Orccon, Florent Thiéry, Florin Apostol, Frédéric Wang, -George Kiagiadakis, George Yunaev, Göran Jönsson, Graham Leggett, -Guillaume Desmottes, Guillaume Marquebielle, Haihua Hu, Havard Graff, -Heinrich Fink, Holger Kaelberer, HoonHee Lee, Hugues Fruchet, Hyunil Park, -Hyunjun Ko, Ilya Konstantinov, James Stevenson, Jan Alexander Steffens (heftig), -Jan Schmidt, Jason Litzinger, Jens Georg, Jimmy Ohn, Joan Pau Beltran, -Joe Gorse, John Chang, John Slade, Jose Antonio Santos Cadenas, Josep Torra, -Julian Bouzas, Julien Isorce, Julien Moutte, Justin Kim, Kazunori Kobayashi, -Koop Mast, Lim Siew Hoon, Linus Svensson, Lubosz Sarnecki, Luis de Bethencourt, -Lukasz Forynski, Manasa Athreya, Marcel Holtmann, Marcin Kolny, Marcus Prebble, -Mark Nauwelaerts, Maroš Ondrášek, Martin Kelly, Matej Knopp, Mathias Hasselmann, -Mathieu Duponchelle, Matt Crane, Matthew Marsh, Matthew Waters, Matthieu Bouron, -Mersad Jelacic, Michael Olbrich, Miguel París Díaz, Mikhail Fludkov, -Mischa Spiegelmock, Nicola Murino, Nicolas Dufresne, Nicolas Huet, -Nirbheek Chauhan, Ognyan Tonchev, Olivier Crête, Pablo Anton, Pankaj Darak, -Paolo Pettinato, Patricia Muscalu, Paul Arzelier, Pavel Bludov, Perry Hung, -Peter Korsgaard, Peter Seiderer, Petr Viktorin, Philippe Normand, -Philippe Renon, Philipp Zabel, Philip Van Hoof, Philip Withnall, Piotr Drąg, -plamot, Polochon\_street, Prashant Gotarne, Rajat Verma, Ramiro Polla, -Ravi Kiran K N, Reynaldo H. Verdejo Pinochet, Robert Swain, Romain Picard, -Roman Nowicki, Ross Burton, Ryan Hendrickson, Santiago Carot-Nemesio, -Scott D Phillips, Sebastian Dröge, Sebastian Rasmussen, Sergey Borovkov, -Seungha Yang, Sjors Gielen, Song Bing, Sreerenj Balachandran, Srimanta Panda, -Stavros Vagionitis, Stefan Sauer, Steven Hoving, Stian Selnes, Suhwang Kim, -Thiago Santos, Thibault Saunier, Thijs Vermeir, Thomas Bluemel, Thomas Roos, -Thomas Vander Stichele, Tim-Philipp Müller, Tim Sheridan, Ting-Wei Lan, -Tom Deseyn, Vanessa Chipirrás Navalón, Víctor Manuel Jáquez Leal, -Vincent Dehors, Vincent Penquerc'h, Vineeth T M, Vivia Nikolaidou, -Wang Xin-yu (王昕宇), William Manley, Wim Taymans, Wonchul Lee, Xavi Artigas, -Xavier Claessens, Youness Alaoui, - -... and many others who have contributed bug reports, translations, sent -suggestions or helped testing. - -## Bugs fixed in 1.8 - -More than [~700 bugs][bugs-fixed-in-1.8] have been fixed during -the development of 1.8. - -This list does not include issues that have been cherry-picked into the -stable 1.6 branch and fixed there as well, all fixes that ended up in the -1.6 branch are also included in 1.8. - -This list also does not include issues that have been fixed without a bug -report in bugzilla, so the actual number of fixes is much higher. - -[bugs-fixed-in-1.8]: https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&classification=Platform&limit=0&list_id=107311&order=bug_id&product=GStreamer&query_format=advanced&resolution=FIXED&target_milestone=1.6.1&target_milestone=1.6.2&target_milestone=1.6.3&target_milestone=1.7.0&target_milestone=1.7.1&target_milestone=1.7.2&target_milestone=1.7.3&target_milestone=1.7.4&target_milestone=1.7.90&target_milestone=1.7.91&target_milestone=1.7.92&target_milestone=1.7.x&target_milestone=1.8.0 - -## Stable 1.8 branch - -After the 1.8.0 release there will be several 1.8.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.8.x bug-fix releases will be made from the git 1.8 branch, which -is a stable branch. - -### 1.8.0 - -1.8.0 was released on 24 March 2016. - -### 1.8.1 - -The first 1.8 bug-fix release (1.8.1) is planned for April 2016. - -## Schedule for 1.10 - -Our next major feature release will be 1.10, and 1.9 will be the unstable -development version leading up to the stable 1.10 release. The development -of 1.9/1.10 will happen in the git master branch. - -The plan for the 1.10 development cycle is yet to be confirmed, but it is -expected that feature freeze will be around late July or early August, -followed by several 1.9 pre-releases and the new 1.10 stable release -in September. - -1.10 will be backwards-compatible to the stable 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 Sebastian Dröge, Nicolas Dufresne, Edward Hervey, Víctor -Manuel Jáquez Leal, Arun Raghavan, Thiago Santos, Thibault Saunier, Jan -Schmidt and Matthew Waters.* - -*License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)* +This is GStreamer 1.9.1 diff --git a/common b/common index f363b32056..ac2f647695 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit f363b3205658a38e84fa77f19dee218cd4445275 +Subproject commit ac2f647695e7bd4b433ea108ee1d0e23901797d4 diff --git a/configure.ac b/configure.ac index 7b1d632f87..3513ad1d4d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [9]) -m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [1]) +m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [900]) +m4_define([gst_vaapi_lt_current], [901]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [900]) +m4_define([gst_vaapi_lt_age], [901]) # glib version number m4_define([glib_version], [2.32]) # gstreamer version number -m4_define([gst_version], [1.9.0.1]) -m4_define([gst_plugins_base_version], [1.9.0.1]) -m4_define([gst_plugins_bad_version], [1.9.0.1]) +m4_define([gst_version], [1.9.1]) +m4_define([gst_plugins_base_version], [1.9.1]) +m4_define([gst_plugins_bad_version], [1.9.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 2b928a33c5..6f9155799c 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,15 @@ + + + 1.9.1 + master + 2016-06-06 + + + + 1.8.0 From 9bc53dd3caff6b1315dfee363f6ae6988db91c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 6 Jul 2016 13:51:21 +0300 Subject: [PATCH 2459/3781] Back to development --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 3513ad1d4d..9e1e525e54 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [9]) m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -24,9 +24,9 @@ m4_define([gst_vaapi_lt_age], [901]) m4_define([glib_version], [2.32]) # gstreamer version number -m4_define([gst_version], [1.9.1]) -m4_define([gst_plugins_base_version], [1.9.1]) -m4_define([gst_plugins_bad_version], [1.9.1]) +m4_define([gst_version], [1.9.1.1]) +m4_define([gst_plugins_base_version], [1.9.1.1]) +m4_define([gst_plugins_bad_version], [1.9.1.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) From f7ea48597e586877ac216869303ceddb72fafbf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 6 Jul 2016 14:41:21 +0300 Subject: [PATCH 2460/3781] configure: Require GLib >= 2.40 like everywhere else --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 9e1e525e54..c4efc9f960 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [901]) # glib version number -m4_define([glib_version], [2.32]) +m4_define([glib_version], [2.40]) # gstreamer version number m4_define([gst_version], [1.9.1.1]) From 6970dc127764129a6bcb06fcceb600e057346796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 6 Jul 2016 18:38:37 +0200 Subject: [PATCH 2461/3781] test: elements: remove spurious linkage Element tests only need to link against gstreamer libraries. --- tests/elements/Makefile.am | 52 ++------------------------------- tests/elements/test-vaapisink.c | 5 +--- 2 files changed, 3 insertions(+), 54 deletions(-) diff --git a/tests/elements/Makefile.am b/tests/elements/Makefile.am index 73e39ed49a..f940a5d0bf 100644 --- a/tests/elements/Makefile.am +++ b/tests/elements/Makefile.am @@ -4,65 +4,17 @@ noinst_PROGRAMS = \ TEST_CFLAGS = \ -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - -I$(top_builddir)/gst-libs \ - $(LIBVA_CFLAGS) \ $(GST_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ $(NULL) -GST_VAAPI_LIBS = $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la TEST_LIBS = \ - $(LIBVA_LIBS) \ - $(GST_LIBS) \ + $(GST_LIBS) \ + $(GST_VIDEO_CFLAGS) \ $(NULL) -if USE_DRM -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm.la -TEST_CFLAGS += $(LIBVA_DRM_CFLAGS) -TEST_LIBS += $(LIBVA_DRM_LIBS) -endif - -if USE_X11 -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11.la -TEST_CFLAGS += $(X11_CFLAGS) -TEST_LIBS += \ - $(LIBVA_X11_LIBS) \ - $(X11_LIBS) \ - $(NULL) -endif - -if USE_GLX -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx.la -TEST_CFLAGS += $(X11_CFLAGS) $(GL_CFLAGS) -TEST_LIBS += \ - $(LIBVA_GLX_LIBS) \ - $(X11_LIBS) \ - $(GL_LIBS) \ - $(NULL) -endif - -if USE_EGL -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl.la -TEST_CFLAGS += $(EGL_CFLAGS) -TEST_LIBS += \ - $(LIBVA_EGL_LIBS) \ - $(EGL_LIBS) \ - $(NULL) -endif - -if USE_WAYLAND -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland.la -TEST_CFLAGS += $(WAYLAND_CFLAGS) -TEST_LIBS += \ - $(LIBVA_WAYLAND_LIBS) \ - $(WAYLAND_LIBS) \ - $(NULL) -endif - test_vaapisink_SOURCES = test-vaapisink.c test_vaapisink_CFLAGS = $(TEST_CFLAGS) -test_vaapisink_LDFLAGS = $(GST_VAAPI_LIBS) test_vaapisink_LDADD = $(TEST_LIBS) -include $(top_srcdir)/git.mk diff --git a/tests/elements/test-vaapisink.c b/tests/elements/test-vaapisink.c index 441a991e12..5005755738 100644 --- a/tests/elements/test-vaapisink.c +++ b/tests/elements/test-vaapisink.c @@ -2,8 +2,6 @@ #include #include -#include - typedef struct _CustomData { GstElement *pipeline; @@ -48,8 +46,7 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data) send_rotate_event (data); break; case 's':{ - g_object_set (G_OBJECT (data->video_sink), "rotation", - GST_VAAPI_ROTATION_AUTOMATIC, NULL); + g_object_set (G_OBJECT (data->video_sink), "rotation", 360, NULL); break; } case 'q': From 03e85bbc0f0bd19b9c6ccd711d299a9c33afbe67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 10 Jul 2016 13:46:25 +0200 Subject: [PATCH 2462/3781] vaapidecode: call purge at flush() Calling flush() vmethod means "to flush all remaining data from the decoder without pushing it downstream". Nonetheless flush() is calling gst_vaapidecode_internal_flush(), which calls gst_video_decoder_have_frame() if there is still something in the input adapter, which may push buffers to downstream by calling handle_frame(). This patch changes this behavior by calling gst_vaapidecode_purge() rather than gst_vaapidecode_internal_flush(), which does what we want: flushes the VA decoder and releases all the rest of decoded frames. https://bugzilla.gnome.org/show_bug.cgi?id=768652 --- gst/vaapi/gstvaapidecode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 2cc8c47879..2d3a558ddf 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1001,9 +1001,13 @@ gst_vaapidecode_flush (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - if (decode->decoder && !gst_vaapidecode_internal_flush (vdec)) + if (!decode->decoder) return FALSE; + GST_LOG_OBJECT (vdec, "flushing"); + + gst_vaapidecode_purge (decode); + /* There could be issues if we avoid the reset_full() while doing * seeking: we have to reset the internal state */ return gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, TRUE); From b392b4f0642fa63cf89e28568460c81e1c02fbf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 10 Jul 2016 18:18:57 +0200 Subject: [PATCH 2463/3781] vaapidecode: flush output adapter at drain() Calling drain() vmethod means "decode any data it can at this point, but that more data may arrive after". Hence, vaapidecode should check if there is data in the output adapter and process them, without destroying the decoded picture buffer (dpb). Since this operation is done by gst_vaapidecode_internal_flush(), the operation was refactored into a new function gst_vaapidecode_flush_output_adapter(). https://bugzilla.gnome.org/show_bug.cgi?id=768652 --- gst/vaapi/gstvaapidecode.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 2d3a558ddf..a5ad73165b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -682,6 +682,17 @@ not_negotiated: } } +/* If there is something in GstVideoDecoder's output adapter, then + submit the frame for decoding */ +static inline void +gst_vaapidecode_flush_output_adapter (GstVaapiDecode * decode) +{ + if (decode->current_frame_size == 0) + return; + gst_video_decoder_have_frame (GST_VIDEO_DECODER (decode)); + decode->current_frame_size = 0; +} + static GstFlowReturn gst_vaapidecode_drain (GstVideoDecoder * vdec) { @@ -690,6 +701,9 @@ gst_vaapidecode_drain (GstVideoDecoder * vdec) if (!decode->decoder) return GST_FLOW_NOT_NEGOTIATED; + GST_LOG_OBJECT (decode, "drain"); + + gst_vaapidecode_flush_output_adapter (decode); return gst_vaapidecode_push_all_decoded_frames (decode); } @@ -702,13 +716,7 @@ gst_vaapidecode_internal_flush (GstVideoDecoder * vdec) if (!decode->decoder) return TRUE; - /* If there is something in GstVideoDecoder's output adapter, then - submit the frame for decoding */ - if (decode->current_frame_size) { - gst_video_decoder_have_frame (vdec); - decode->current_frame_size = 0; - } - + gst_vaapidecode_flush_output_adapter (decode); status = gst_vaapi_decoder_flush (decode->decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { GST_WARNING_OBJECT (decode, "failed to flush decoder (status %d)", status); From cb0ec6b60c647cd3c01fe8d8c50a2fb81acf73eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 10 Jul 2016 19:01:17 +0200 Subject: [PATCH 2464/3781] vaapidecode: remove gst_vaapidecode_internal_flush() As gst_vaapidecode_finish() is the only callee of gst_vaapidecode_internal_flush(), it is better to inline it. https://bugzilla.gnome.org/show_bug.cgi?id=768652 --- gst/vaapi/gstvaapidecode.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a5ad73165b..83dff65284 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -707,40 +707,29 @@ gst_vaapidecode_drain (GstVideoDecoder * vdec) return gst_vaapidecode_push_all_decoded_frames (decode); } -static gboolean -gst_vaapidecode_internal_flush (GstVideoDecoder * vdec) -{ - GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - GstVaapiDecoderStatus status; - - if (!decode->decoder) - return TRUE; - - gst_vaapidecode_flush_output_adapter (decode); - status = gst_vaapi_decoder_flush (decode->decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { - GST_WARNING_OBJECT (decode, "failed to flush decoder (status %d)", status); - return FALSE; - } - - return TRUE; -} - static GstFlowReturn gst_vaapidecode_finish (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - gboolean flushed; + GstVaapiDecoderStatus status; GstFlowReturn ret; if (!decode->decoder) return GST_FLOW_OK; - flushed = gst_vaapidecode_internal_flush (vdec); + gst_vaapidecode_flush_output_adapter (decode); + status = gst_vaapi_decoder_flush (decode->decoder); ret = gst_vaapidecode_push_all_decoded_frames (decode); - if (!flushed) - return GST_FLOW_ERROR; + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto error_decoder_flush; return ret; + + /* ERRORS: */ +error_decoder_flush: + { + GST_WARNING_OBJECT (decode, "failed to flush decoder (status %d)", status); + return GST_FLOW_ERROR; + } } static gboolean From c9a5801c35c55544287689cc60743e8a67bc19ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 10 Jul 2016 19:33:14 +0200 Subject: [PATCH 2465/3781] vaapidecode: unref output frame earlier The queue in GstVaapiDecode adds an extra reference to the frames. This patch unref that extra reference earlier making the code simpler to follow. https://bugzilla.gnome.org/show_bug.cgi?id=768652 --- gst/vaapi/gstvaapidecode.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 83dff65284..ec0c914c04 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -547,8 +547,6 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, ret = gst_video_decoder_finish_frame (vdec, out_frame); if (ret != GST_FLOW_OK) goto error_commit_buffer; - - gst_video_codec_frame_unref (out_frame); return GST_FLOW_OK; /* ERRORS */ @@ -562,7 +560,6 @@ error_create_buffer: ("video sink failed to create video buffer for proxy'ed " "surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id))); gst_video_decoder_drop_frame (vdec, out_frame); - gst_video_codec_frame_unref (out_frame); return GST_FLOW_ERROR; } error_get_meta: @@ -571,14 +568,12 @@ error_get_meta: ("Failed to get vaapi video meta attached to video buffer"), ("Failed to get vaapi video meta attached to video buffer")); gst_video_decoder_drop_frame (vdec, out_frame); - gst_video_codec_frame_unref (out_frame); return GST_FLOW_ERROR; } error_commit_buffer: { GST_INFO_OBJECT (decode, "downstream element rejected the frame (%s [%d])", gst_flow_get_name (ret), ret); - gst_video_codec_frame_unref (out_frame); return ret; } } @@ -596,6 +591,8 @@ gst_vaapidecode_push_all_decoded_frames (GstVaapiDecode * decode) switch (status) { case GST_VAAPI_DECODER_STATUS_SUCCESS: + /* GstVaapiDecode's queue adds an extra reference */ + gst_video_codec_frame_unref (out_frame); ret = gst_vaapidecode_push_decoded_frame (vdec, out_frame); if (ret != GST_FLOW_OK) return ret; From 19c0c8a97385ce119440c4aad2d689fc79297435 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 1 Jul 2016 14:42:20 +0900 Subject: [PATCH 2466/3781] vaapidecode: drop non-keyframe in reverse playback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid surface-exhausted situation during reverse playback, drop frames except for key frame. Also, to avoid the corruption of the parser state, flush() vmethod doesn't destroy the VA decoder when playing in reverse. https://bugzilla.gnome.org/show_bug.cgi?id=742922 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapidecode.c | 36 +++++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapidecode.h | 1 + 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ec0c914c04..8663fb89e4 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -544,6 +544,13 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, #endif } + if (decode->in_segment.rate < 0.0 + && !GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (out_frame)) { + GST_TRACE_OBJECT (decode, "drop frame in reverse playback"); + gst_video_decoder_release_frame (GST_VIDEO_DECODER (decode), out_frame); + return GST_FLOW_OK; + } + ret = gst_video_decoder_finish_frame (vdec, out_frame); if (ret != GST_FLOW_OK) goto error_commit_buffer; @@ -994,6 +1001,7 @@ static gboolean gst_vaapidecode_flush (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + gboolean reverse; if (!decode->decoder) return FALSE; @@ -1002,9 +1010,13 @@ gst_vaapidecode_flush (GstVideoDecoder * vdec) gst_vaapidecode_purge (decode); + /* in reverse playback we cannot destroy the decoder at flush, since + * it will lost the parsing state */ + reverse = decode->in_segment.rate < 0; + /* There could be issues if we avoid the reset_full() while doing * seeking: we have to reset the internal state */ - return gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, TRUE); + return gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, !reverse); } static gboolean @@ -1225,6 +1237,27 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) return ret; } +static gboolean +gst_vaapidecode_sink_event (GstVideoDecoder * vdec, GstEvent * event) +{ + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_SEGMENT: + { + /* Keep segment event to refer to rate so that + * vaapidecode can handle reverse playback + */ + gst_event_copy_segment (event, &decode->in_segment); + break; + } + default: + break; + } + + return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (vdec, event); +} + static void gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) { @@ -1259,6 +1292,7 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_src_query); vdec_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_query); vdec_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_getcaps); + vdec_class->sink_event = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_event); map = (GstVaapiDecoderMap *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass), GST_VAAPI_DECODE_PARAMS_QDATA); diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 9496e7da73..043294b120 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -54,6 +54,7 @@ struct _GstVaapiDecode { guint display_height; GstVideoCodecState *input_state; + GstSegment in_segment; }; struct _GstVaapiDecodeClass { From fcc08627e58c82e62e7310bb9caaf9a984b63e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 11 Jul 2016 08:43:04 +0200 Subject: [PATCH 2467/3781] decoder: vc1: flush dpb only if opened Flush the decode picture buffer, if and only if, the decoder is started. Otherwise the dpb structure might be NULL. https://bugzilla.gnome.org/show_bug.cgi?id=742922 --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 0a34d7ed26..76eb66063c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -1393,7 +1393,8 @@ gst_vaapi_decoder_vc1_flush (GstVaapiDecoder * base_decoder) GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder); GstVaapiDecoderVC1Private *const priv = &decoder->priv; - gst_vaapi_dpb_flush (priv->dpb); + if (priv->is_opened) + gst_vaapi_dpb_flush (priv->dpb); return GST_VAAPI_DECODER_STATUS_SUCCESS; } From d94001b82005e3d58b915d1fb9224db76bbe82f8 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 6 Jul 2016 11:17:23 +0900 Subject: [PATCH 2468/3781] vaapiencode: implement flush() vmethod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to handle correctly seek and other operations, vaapiencode should flush all the remaining data from the encoder without pushing it downstream. This patch implements the flush() vmethod, only after of pausing the source pad task, and restarting it again after the flush stop. https://bugzilla.gnome.org/show_bug.cgi?id=767176 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapiencode.c | 78 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 9d79fd10af..9646f98435 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -338,6 +338,7 @@ gst_vaapiencode_buffer_loop (GstVaapiEncode * encode) if (ret == GST_FLOW_OK || ret == GST_VAAPI_ENCODE_FLOW_TIMEOUT) return; + GST_LOG_OBJECT (encode, "pausing task, reason %s", gst_flow_get_name (ret)); gst_pad_pause_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); } @@ -370,6 +371,26 @@ gst_vaapiencode_destroy (GstVaapiEncode * encode) return TRUE; } +static void +gst_vaapiencode_purge (GstVaapiEncode * encode) +{ + GstVaapiCodedBufferProxy *codedbuf_proxy = NULL; + GstVaapiEncoderStatus status; + GstVideoCodecFrame *out_frame; + + do { + status = gst_vaapi_encoder_get_buffer_with_timeout (encode->encoder, + &codedbuf_proxy, 0); + if (status == GST_VAAPI_ENCODER_STATUS_SUCCESS) { + out_frame = gst_vaapi_coded_buffer_proxy_get_user_data (codedbuf_proxy); + if (out_frame) + gst_video_codec_frame_set_user_data (out_frame, NULL, NULL); + + gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); + } + } while (status == GST_VAAPI_ENCODER_STATUS_SUCCESS); +} + static gboolean ensure_encoder (GstVaapiEncode * encode) { @@ -380,6 +401,9 @@ ensure_encoder (GstVaapiEncode * encode) g_return_val_if_fail (klass->alloc_encoder, FALSE); + if (encode->encoder) + return FALSE; + encode->encoder = klass->alloc_encoder (encode, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); if (!encode->encoder) @@ -592,6 +616,58 @@ gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query) return TRUE; } +static gboolean +gst_vaapiencode_sink_event (GstVideoEncoder * venc, GstEvent * event) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); + GstPad *const srcpad = GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode); + gboolean ret; + + ret = GST_VIDEO_ENCODER_CLASS (gst_vaapiencode_parent_class)->sink_event + (venc, event); + if (!ret) + return FALSE; + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_START: + gst_pad_pause_task (srcpad); + break; + case GST_EVENT_FLUSH_STOP: + ret = gst_pad_start_task (srcpad, + (GstTaskFunction) gst_vaapiencode_buffer_loop, encode, NULL); + break; + default: + break; + } + + return ret; +} + +static gboolean +gst_vaapiencode_flush (GstVideoEncoder * venc) +{ + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); + GstVaapiEncoderStatus status; + + if (!encode->encoder) + return FALSE; + + GST_LOG_OBJECT (encode, "flushing"); + + status = gst_vaapi_encoder_flush (encode->encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return FALSE; + gst_vaapiencode_purge (encode); + + gst_vaapi_encoder_replace (&encode->encoder, NULL); + if (!ensure_encoder (encode)) + return FALSE; + if (!set_codec_state (encode, encode->input_state)) + return FALSE; + + return TRUE; +} + static void gst_vaapiencode_finalize (GObject * object) { @@ -643,6 +719,8 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) venc_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapiencode_get_caps); venc_class->propose_allocation = GST_DEBUG_FUNCPTR (gst_vaapiencode_propose_allocation); + venc_class->flush = GST_DEBUG_FUNCPTR (gst_vaapiencode_flush); + venc_class->sink_event = GST_DEBUG_FUNCPTR (gst_vaapiencode_sink_event); klass->get_property = gst_vaapiencode_default_get_property; klass->set_property = gst_vaapiencode_default_set_property; From cf1dd3790f233761477f8179ce6b7a6f1fcfbbe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 5 Jul 2016 18:23:22 +0200 Subject: [PATCH 2469/3781] vaapiencode: demote a log to trace level Removes noise when debugging. --- gst/vaapi/gstvaapiencode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 9646f98435..acaac3c02c 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -298,7 +298,7 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) gst_buffer_replace (&out_frame->output_buffer, out_buffer); gst_buffer_unref (out_buffer); - GST_DEBUG ("output:%" GST_TIME_FORMAT ", size:%zu", + GST_TRACE_OBJECT (encode, "output:%" GST_TIME_FORMAT ", size:%zu", GST_TIME_ARGS (out_frame->pts), gst_buffer_get_size (out_buffer)); return gst_video_encoder_finish_frame (venc, out_frame); From f8eb0c84d96c7de85cc88396a4e330cc47b44cc7 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Mon, 11 Jul 2016 21:15:57 +0200 Subject: [PATCH 2470/3781] Automatic update of common submodule From ac2f647 to f49c55e --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index ac2f647695..f49c55ecd3 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit ac2f647695e7bd4b433ea108ee1d0e23901797d4 +Subproject commit f49c55ecd35a7436194d28297f6d6f20eb6a66fa From 0d1d09727347b642a86e0d6b8502e3ea46f2b9fa Mon Sep 17 00:00:00 2001 From: Jagyum Koo Date: Wed, 13 Jul 2016 17:21:01 +0900 Subject: [PATCH 2471/3781] wayland: Error check before using cached wl_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A planar(or some other) buffer allocation may fail on the driver, then the wayland connection becomes invalid, not able to send request or receive any event. So we need to set up a new wayland connection if there's an error detected on the cached wl_display. https://bugzilla.gnome.org/show_bug.cgi?id=768761 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 8b8e8cb36e..bb7c5f3339 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -207,6 +207,7 @@ gst_vaapi_display_wayland_open_display (GstVaapiDisplay * display, GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); const GstVaapiDisplayInfo *info; + int dsp_error = 0; if (!set_display_name (display, name)) return FALSE; @@ -214,6 +215,11 @@ gst_vaapi_display_wayland_open_display (GstVaapiDisplay * display, info = gst_vaapi_display_cache_lookup_custom (cache, compare_display_name, priv->display_name, g_display_types); if (info) { + wl_display_roundtrip (info->native_display); + if ((dsp_error = wl_display_get_error (info->native_display))) + GST_ERROR ("wayland display error detected: %d", dsp_error); + } + if (info && !dsp_error) { priv->wl_display = info->native_display; priv->use_foreign_display = TRUE; } else { From 9f4796756dbe03a90c06a0f9247df2d95c4b0e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 12 Jul 2016 23:58:55 +0200 Subject: [PATCH 2472/3781] vaapisink: demote a debug message to trace Reduces noise when debugging. --- gst/vaapi/gstvaapisink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 68f21c0eaa..cd19bc5abd 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1409,7 +1409,7 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) gst_vaapisink_ensure_colorbalance (sink); gst_vaapisink_ensure_rotation (sink, TRUE); - GST_DEBUG ("render surface %" GST_VAAPI_ID_FORMAT, + GST_TRACE_OBJECT (sink, "render surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (gst_vaapi_surface_get_id (surface))); if (!surface_rect) From 6c6007ad94c402d33da9c5c73620e84064ea8fb2 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 15 Jul 2016 14:41:27 +0300 Subject: [PATCH 2473/3781] encoder: h264: Fix MVC encode while enabling dct8x8 Pack the transform_8x8_mode_flag and other necessary rbsp data in packed_pps header for MVC encode. https://bugzilla.gnome.org/show_bug.cgi?id=768647 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 8c06d2f2aa..0b2878d593 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -703,7 +703,9 @@ bs_write_pps (GstBitWriter * bs, WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1); /* more_rbsp_data */ - if (profile == GST_VAAPI_PROFILE_H264_HIGH) { + if (profile == GST_VAAPI_PROFILE_H264_HIGH + || profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH + || profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1); WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1); From b138e5e042329c759c3d39bf0f408b03fcd6f588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 15 Jul 2016 16:32:26 +0200 Subject: [PATCH 2474/3781] build: doc: do not redefine MAINTAINERCLEANFILES MAINTAINERCLEANFILES is defined in gtk-doc-plugins.mak, thus instead of overload it, the files should be added. --- docs/plugins/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index e0cb471375..86ab1b465e 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -82,7 +82,7 @@ include $(top_srcdir)/common/gtk-doc-plugins.mak SUBDIRS = # Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = \ +MAINTAINERCLEANFILES += \ gstreamer-vaapi-plugins.* \ *.stamp inspect \ gstreamer-vaapi-plugins-overrides.txt \ From d9ef88230f3aaf17a6e6556fa4a116c3a3423a1d Mon Sep 17 00:00:00 2001 From: Allen Zhang Date: Thu, 21 Jul 2016 11:24:31 +0300 Subject: [PATCH 2475/3781] decoder: h265: handle the SEI NAL units included in codec_data The prefix/suffix SEI nal units can appear in codec_data too which weren't handled before. Parse these SEI headers to fix the segfault. https://bugzilla.gnome.org/show_bug.cgi?id=768544 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index ef703d02b3..d44047c7a8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2696,6 +2696,16 @@ gst_vaapi_decoder_h265_decode_codec_data (GstVaapiDecoder * if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto cleanup; break; + case GST_H265_NAL_SUFFIX_SEI: + case GST_H265_NAL_PREFIX_SEI: + status = parse_sei (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + status = decode_sei (decoder, &unit); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto cleanup; + break; + } ofs = pi->nalu.offset + pi->nalu.size; gst_vaapi_parser_info_h265_replace (&pi, NULL); From cc6df605a1056082fb3bfea5992081b4cf2f57a7 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 22 Jul 2016 11:51:26 +0900 Subject: [PATCH 2476/3781] vaapipostproc: checking and updating filter parameter only when it's set This patch is to avoid checking filter value at every frame. https://bugzilla.gnome.org/show_bug.cgi?id=751876 --- gst-libs/gst/vaapi/gstvaapifilter.c | 81 +++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 23 +++++ gst/vaapi/gstvaapipostproc.c | 153 ++++++++++++++++++++-------- 3 files changed, 217 insertions(+), 40 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index e2f269c6ac..6eb7446006 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1877,3 +1877,84 @@ gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, gboolean enhance) return op_set_skintone (filter, find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE), enhance); } + +static inline gfloat +op_get_float_default_value (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data) +{ +#if USE_VA_VPP + GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (op_data->pspec); + return pspec->default_value; +#endif + return 0.0; +} + +gfloat +gst_vaapi_filter_get_denoising_level_default (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return op_get_float_default_value (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_DENOISE)); +} + +gfloat +gst_vaapi_filter_get_sharpening_level_default (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return op_get_float_default_value (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_SHARPEN)); +} + +gfloat +gst_vaapi_filter_get_hue_default (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return op_get_float_default_value (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_HUE)); +} + +gfloat +gst_vaapi_filter_get_saturation_default (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return op_get_float_default_value (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_SATURATION)); +} + +gfloat +gst_vaapi_filter_get_brightness_default (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return op_get_float_default_value (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_BRIGHTNESS)); +} + +gfloat +gst_vaapi_filter_get_contrast_default (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return op_get_float_default_value (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_CONTRAST)); +} + +GstVaapiScaleMethod +gst_vaapi_filter_get_scaling_default (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return DEFAULT_SCALING; +} + +gboolean +gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return FALSE; +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 6364803c06..667dd69856 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -246,4 +246,27 @@ gboolean gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, gboolean enhance); +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); + +gboolean +gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter); #endif /* GST_VAAPI_FILTER_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 43e6582d82..19aca684be 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -469,6 +469,113 @@ set_best_deint_method (GstVaapiPostproc * postproc, guint flags, return success; } +static gboolean +check_filter_update (GstVaapiPostproc * postproc) +{ + guint filter_flag = postproc->flags; + guint op_flag; + gint i; + + if (!postproc->has_vpp) + return FALSE; + + for (i = GST_VAAPI_FILTER_OP_DENOISE; i <= GST_VAAPI_FILTER_OP_SKINTONE; i++) { + op_flag = (filter_flag >> i) & 1; + if (op_flag) + return TRUE; + } + + return FALSE; +} + +static gboolean +update_filter (GstVaapiPostproc * postproc) +{ + /* Validate filters */ + if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) && + !gst_vaapi_filter_set_format (postproc->filter, postproc->format)) + return FALSE; + + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DENOISE) { + if (!gst_vaapi_filter_set_denoising_level (postproc->filter, + postproc->denoise_level)) + return FALSE; + + if (gst_vaapi_filter_get_denoising_level_default (postproc->filter) == + postproc->denoise_level) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_DENOISE); + } + + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SHARPEN) { + if (!gst_vaapi_filter_set_sharpening_level (postproc->filter, + postproc->sharpen_level)) + return FALSE; + + if (gst_vaapi_filter_get_sharpening_level_default (postproc->filter) == + postproc->sharpen_level) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_SHARPEN); + } + + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_HUE) { + if (!gst_vaapi_filter_set_hue (postproc->filter, postproc->hue)) + return FALSE; + + if (gst_vaapi_filter_get_hue_default (postproc->filter) == postproc->hue) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_HUE); + } + + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SATURATION) { + if (!gst_vaapi_filter_set_saturation (postproc->filter, + postproc->saturation)) + return FALSE; + + if (gst_vaapi_filter_get_saturation_default (postproc->filter) == + postproc->saturation) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_SATURATION); + } + + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS) { + if (!gst_vaapi_filter_set_brightness (postproc->filter, + postproc->brightness)) + return FALSE; + + if (gst_vaapi_filter_get_brightness_default (postproc->filter) == + postproc->brightness) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS); + } + + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_CONTRAST) { + if (!gst_vaapi_filter_set_contrast (postproc->filter, postproc->contrast)) + return FALSE; + + if (gst_vaapi_filter_get_contrast_default (postproc->filter) == + postproc->contrast) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_CONTRAST); + } + + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SCALE) { + if (!gst_vaapi_filter_set_scaling (postproc->filter, + postproc->scale_method)) + return FALSE; + + if (gst_vaapi_filter_get_scaling_default (postproc->filter) == + postproc->scale_method) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_SCALE); + } + + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SKINTONE) { + if (!gst_vaapi_filter_set_skintone (postproc->filter, + postproc->skintone_enhance)) + return FALSE; + + if (gst_vaapi_filter_get_skintone_default (postproc->filter) == + postproc->skintone_enhance) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_SKINTONE); + } + + return TRUE; +} + static GstFlowReturn gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer * outbuf) @@ -489,46 +596,6 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, GstVaapiRectangle *crop_rect = NULL; GstVaapiRectangle tmp_rect; - /* Validate filters */ - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) && - !gst_vaapi_filter_set_format (postproc->filter, postproc->format)) - return GST_FLOW_NOT_SUPPORTED; - - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_DENOISE) && - !gst_vaapi_filter_set_denoising_level (postproc->filter, - postproc->denoise_level)) - return GST_FLOW_NOT_SUPPORTED; - - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SHARPEN) && - !gst_vaapi_filter_set_sharpening_level (postproc->filter, - postproc->sharpen_level)) - return GST_FLOW_NOT_SUPPORTED; - - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_HUE) && - !gst_vaapi_filter_set_hue (postproc->filter, postproc->hue)) - return GST_FLOW_NOT_SUPPORTED; - - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SATURATION) && - !gst_vaapi_filter_set_saturation (postproc->filter, postproc->saturation)) - return GST_FLOW_NOT_SUPPORTED; - - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_BRIGHTNESS) && - !gst_vaapi_filter_set_brightness (postproc->filter, postproc->brightness)) - return GST_FLOW_NOT_SUPPORTED; - - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_CONTRAST) && - !gst_vaapi_filter_set_contrast (postproc->filter, postproc->contrast)) - return GST_FLOW_NOT_SUPPORTED; - - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SCALE) && - !gst_vaapi_filter_set_scaling (postproc->filter, postproc->scale_method)) - return GST_FLOW_NOT_SUPPORTED; - - if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SKINTONE) && - !gst_vaapi_filter_set_skintone (postproc->filter, - postproc->skintone_enhance)) - return GST_FLOW_NOT_SUPPORTED; - inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); if (!inbuf_meta) goto error_invalid_buffer; @@ -1214,6 +1281,9 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, if (!ensure_srcpad_buffer_pool (postproc, out_caps)) goto done; + if (check_filter_update (postproc)) + update_filter (postproc); + ret = TRUE; done: @@ -1364,6 +1434,9 @@ gst_vaapipostproc_set_property (GObject * object, break; } g_mutex_unlock (&postproc->postproc_lock); + + if (check_filter_update (postproc)) + update_filter (postproc); } static void From 73d4da2e790e638f458361d17c5a5f5b6dd87b88 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 22 Jul 2016 12:10:23 +0900 Subject: [PATCH 2477/3781] vaapipostproc: make it enable/disable pass-through mode In case that sink caps and src caps are same, and no filtering parameter set, pass-through mode is enabled. If new filtering parameter is set during playback, it makes it reconfiguring, so that pass-through mode is changed In addition, updating filter is performed during reconfiguration, if needed. https://bugzilla.gnome.org/show_bug.cgi?id=751876 --- gst/vaapi/gstvaapipostproc.c | 31 ++++++++++++++++++++++++++++--- gst/vaapi/gstvaapipostproc.h | 1 + 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 19aca684be..391fd276c0 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -576,6 +576,21 @@ update_filter (GstVaapiPostproc * postproc) return TRUE; } +static void +gst_vaapipostproc_set_passthrough (GstBaseTransform * trans) +{ + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + gboolean filter_updated = FALSE; + + if (check_filter_update (postproc) && update_filter (postproc)) { + /* check again if changed value is default */ + filter_updated = check_filter_update (postproc); + } + + gst_base_transform_set_passthrough (trans, postproc->same_caps + && !filter_updated); +} + static GstFlowReturn gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer * outbuf) @@ -1131,6 +1146,9 @@ gst_vaapipostproc_fixate_caps (GstBaseTransform * trans, gst_caps_replace (&othercaps, outcaps); g_mutex_unlock (&postproc->postproc_lock); + /* set passthrough according to caps changes or filter changes */ + gst_vaapipostproc_set_passthrough (trans); + done: GST_DEBUG_OBJECT (trans, "fixated othercaps to %" GST_PTR_FORMAT, othercaps); if (outcaps) @@ -1201,6 +1219,11 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + if (gst_base_transform_is_passthrough (trans)) { + *outbuf_ptr = inbuf; + return GST_FLOW_OK; + } + *outbuf_ptr = create_output_buffer (postproc); return *outbuf_ptr ? GST_FLOW_OK : GST_FLOW_ERROR; } @@ -1281,8 +1304,10 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, if (!ensure_srcpad_buffer_pool (postproc, out_caps)) goto done; - if (check_filter_update (postproc)) - update_filter (postproc); + postproc->same_caps = gst_caps_is_equal (caps, out_caps); + + /* set passthrough according to caps changes or filter changes */ + gst_vaapipostproc_set_passthrough (trans); ret = TRUE; @@ -1436,7 +1461,7 @@ gst_vaapipostproc_set_property (GObject * object, g_mutex_unlock (&postproc->postproc_lock); if (check_filter_update (postproc)) - update_filter (postproc); + gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM (postproc)); } static void diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index d829ab1c92..3c4232c236 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -176,6 +176,7 @@ struct _GstVaapiPostproc /* color balance's channel list */ GList *cb_channels; + gboolean same_caps; }; struct _GstVaapiPostprocClass From 6cbb607ec921d6b7848c07e98cab3031a61bde7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 Jul 2016 16:55:59 +0200 Subject: [PATCH 2478/3781] vaapipostproc: update filters at color balance This is a fix for a regression of previous commit, which updates the filters only when the property is set, because it is also required to update the filter when the color balance interface change its values. --- gst/vaapi/gstvaapipostproc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 391fd276c0..15c7275e50 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1911,6 +1911,8 @@ gst_vaapipostproc_colorbalance_set_value (GstColorBalance * balance, *var = new_val; postproc->flags |= flags; gst_color_balance_value_changed (balance, channel, value); + if (check_filter_update (postproc)) + gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM (postproc)); return; } From 3efc2f70b7e14a5c74ff9b547231e105387809c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 21 Jul 2016 17:38:17 +0200 Subject: [PATCH 2479/3781] encoder: h265: fix code-style --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 0a5a291d67..739feed46a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1988,7 +1988,7 @@ ensure_profile_tier_level (GstVaapiEncoderH265 * encoder) ensure_bitrate (encoder); if (!ensure_level (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; if (encoder->profile != profile || encoder->level != level || encoder->tier != tier) { From 7472826a3633d803d55def32dee58eb8d318e3ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 Jul 2016 17:43:28 +0200 Subject: [PATCH 2480/3781] Revert "gstvaapisurface_drm: release image when done" This reverts commit 1dbcc8a0e199f2da6a0ab8e949f13341916128a3 and commit 372a03a9e38acbf435eb80bf31d9a9844069e504. While the dmabuf handle is exported, the derive image must exist, otherwise the image's VA buffer is invalid, thus the dmabuf handle is never released, leading into a file descriptors leak. --- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index b6357d306b..73df5af0dd 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -36,19 +36,11 @@ gst_vaapi_surface_get_drm_buf_handle (GstVaapiSurface * surface, guint type) if (!image) goto error_derive_image; - if (type == GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF) { - proxy = gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), - image->internal_image.buf, type, NULL, NULL); - } else { - proxy = gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), - image->internal_image.buf, type, gst_vaapi_object_unref, image); - } + proxy = + gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), + image->internal_image.buf, type, gst_vaapi_object_unref, image); if (!proxy) goto error_alloc_export_buffer; - - if (type == GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF) - gst_vaapi_object_unref (image); - return proxy; /* ERRORS */ From 955cdb84e6d841dd745504fb2a53595c1402a435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 Jul 2016 18:28:28 +0200 Subject: [PATCH 2481/3781] plugins: remove undefined macros --- gst/vaapi/gstvaapipluginbase.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 33aa695448..4a1de465fa 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -81,16 +81,12 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_caps) #define GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO(plugin) \ (&GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_info) -#define GST_VAAPI_PLUGIN_BASE_SINK_PAD_QUERYFUNC(plugin) \ - (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_query) #define GST_VAAPI_PLUGIN_BASE_SRC_PAD(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad) #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_caps) #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO(plugin) \ (&GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_info) -#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_QUERYFYNC(plugin) \ - (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_query) #define GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->display) From 024d5401955d4d7b1348ba5f68180719640aa93c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 Jul 2016 16:02:27 +0200 Subject: [PATCH 2482/3781] vaapidecode: remove unneeded initializations GObject's memory is set to zero, so there is no need to initialize to zero or NULL it's class variables. --- gst/vaapi/gstvaapidecode.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 8663fb89e4..e6f6687520 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1335,10 +1335,6 @@ gst_vaapidecode_init (GstVaapiDecode * decode) gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (decode), GST_CAT_DEFAULT); - decode->decoder = NULL; - decode->decoder_caps = NULL; - decode->allowed_caps = NULL; - g_mutex_init (&decode->surface_ready_mutex); g_cond_init (&decode->surface_ready); From 1cba2f363385914e2c6cc445d19834c41f56a6e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 28 Jun 2016 11:33:18 +0200 Subject: [PATCH 2483/3781] vaapi: declare external dependencies There are two main external dependencies that define the feature set of this plugin: a) the kernel and b) the VA driver This patch tracks both dependencies, if any of them change, GStreamer will re-inspect the plugin. The kernel is tracked through the device files /dev/dri/card* The VA driver is tracked through the files VA_DRIVERS_PATH/*_drv_video.so, where VA_DRIVERS_PATH is the one defined in libva package configuration. Also, the environment variables LIBVA_DRIVERS_PATH and LIBVA_DRIVER_NAME are tracked since they modify the driver lookup. Additionally, the environment variable GST_VAAPI_ALL_DRIVERS is tracked too. https://bugzilla.gnome.org/show_bug.cgi?id=724352 --- configure.ac | 3 +++ gst/vaapi/gstvaapi.c | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/configure.ac b/configure.ac index c4efc9f960..994dec167f 100644 --- a/configure.ac +++ b/configure.ac @@ -488,6 +488,9 @@ dnl --------------------------------------------------------------------------- dnl Core API PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ]) VA_VERSION_STR=`$PKG_CONFIG --modversion libva` +VA_DRIVERS_PATH=`$PKG_CONFIG --variable=driverdir libva` +AC_DEFINE_UNQUOTED([VA_DRIVERS_PATH], ["$VA_DRIVERS_PATH"], + [VA drivers path]) dnl VA/DRM API if test $USE_DRM -eq 1; then diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index bf56be2155..2a53fea68d 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -53,9 +53,36 @@ #define PLUGIN_DESC "VA-API based elements" #define PLUGIN_LICENSE "LGPL" +static void +plugin_add_dependencies (GstPlugin * plugin) +{ + const gchar *envvars[] = { "GST_VAAPI_ALL_DRIVERS", "LIBVA_DRIVER_NAME", + NULL + }; + const gchar *kernel_paths[] = { "/dev/dri", NULL }; + const gchar *kernel_names[] = { "card", "render" }; + + /* features get updated upon changes in /dev/dri/card* */ + gst_plugin_add_dependency (plugin, NULL, kernel_paths, kernel_names, + GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_PREFIX); + + /* features get updated upon changes in VA environment variables */ + gst_plugin_add_dependency (plugin, envvars, NULL, NULL, + GST_PLUGIN_DEPENDENCY_FLAG_NONE); + + /* features get updated upon changes in default VA drivers + * directory */ + gst_plugin_add_dependency_simple (plugin, "LIBVA_DRIVERS_PATH", + VA_DRIVERS_PATH, "_drv_video.so", + GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_SUFFIX | + GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_DEFAULT_ONLY); +} + static gboolean plugin_init (GstPlugin * plugin) { + plugin_add_dependencies (plugin); + gst_vaapidecode_register (plugin); gst_element_register (plugin, "vaapipostproc", From e070d3ebede3415699e6e72a5c953f304b951279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 12 Jul 2016 19:56:02 +0200 Subject: [PATCH 2484/3781] vaapi: instantiate a VA display when registering This patch tries to instantiate a GstVaapiDisplay when registering the plugin features, if it fails, no gstreamer-vaapi element is registering. The purpose of this patch is to avoid a situation where the user has gstreamer-vaapi installed but their VA-API setup is not functional, which may lead to unexpected behavior. https://bugzilla.gnome.org/show_bug.cgi?id=724352 --- gst/vaapi/gstvaapi.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 2a53fea68d..f52f1f4c4a 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -81,8 +81,14 @@ plugin_add_dependencies (GstPlugin * plugin) static gboolean plugin_init (GstPlugin * plugin) { + GstVaapiDisplay *display; + plugin_add_dependencies (plugin); + display = gst_vaapi_create_test_display (); + if (!display) + goto error_no_display; + gst_vaapidecode_register (plugin); gst_element_register (plugin, "vaapipostproc", @@ -114,7 +120,19 @@ plugin_init (GstPlugin * plugin) gst_element_register (plugin, "vaapidecodebin", GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); + + gst_vaapi_display_unref (display); + return TRUE; + + /* ERRORS: */ +error_no_display: + { + GST_ERROR ("Cannot create a VA display"); + /* Avoid blacklisting: failure to create a display could be a + * transient condition */ + return TRUE; + } } GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, From a9e7eac10834b32ca3bdf4402f8b3ffdcedda6bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 28 Jun 2016 17:14:06 +0200 Subject: [PATCH 2485/3781] plugins: add gst_vaapi_driver_is_whitelisted() Move some of the logic in gst_vaapi_plugin_base_driver_is_whitelisted() to a new function gst_vaapi_driver_is_whitelisted(), in this way, it can be used when registering the plugin's feature set with the test VA display. https://bugzilla.gnome.org/show_bug.cgi?id=724352 --- gst/vaapi/gstvaapipluginbase.c | 30 +-------------------- gst/vaapi/gstvaapipluginutil.c | 48 ++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 4 +++ 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index b74dbf4c3d..b9c579932e 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -34,9 +34,6 @@ /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) -/* Environment variable for disable driver white-list */ -#define GST_VAAPI_ALL_DRIVERS_ENV "GST_VAAPI_ALL_DRIVERS" - /* GstVideoContext interface */ static void plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) @@ -89,32 +86,12 @@ gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, gboolean gst_vaapi_plugin_base_driver_is_whitelisted (GstVaapiPluginBase * plugin) { - const gchar *vendor; - guint i; GstVaapiDisplay *display; - static const gchar *whitelist[] = { - "Intel i965 driver", - "mesa gallium vaapi", - NULL - }; - - if (g_getenv (GST_VAAPI_ALL_DRIVERS_ENV)) - return TRUE; display = GST_VAAPI_PLUGIN_BASE_DISPLAY (plugin); if (!display) goto no_display; - vendor = gst_vaapi_display_get_vendor_string (display); - if (!vendor) - goto no_vendor; - for (i = 0; whitelist[i]; i++) { - if (g_ascii_strncasecmp (vendor, whitelist[i], strlen (whitelist[i])) == 0) - return TRUE; - } - - GST_ERROR ("Unsupported VA driver: %s. Export environment variable " - GST_VAAPI_ALL_DRIVERS_ENV " to bypass", vendor); - return FALSE; + return gst_vaapi_driver_is_whitelisted (display); /* ERRORS */ no_display: @@ -122,11 +99,6 @@ no_display: GST_WARNING_OBJECT (plugin, "no VA-API display available"); return FALSE; } -no_vendor: - { - GST_WARNING_OBJECT (plugin, "no VA-API driver vendor description"); - return FALSE; - } } void diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index a88aeba902..de32521d0f 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -42,6 +42,9 @@ #include "gstvaapipluginutil.h" #include "gstvaapipluginbase.h" +/* Environment variable for disable driver white-list */ +#define GST_VAAPI_ALL_DRIVERS_ENV "GST_VAAPI_ALL_DRIVERS" + typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFunc) (const gchar *); typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFromHandleFunc) (gpointer); @@ -722,3 +725,48 @@ gst_vaapi_create_test_display (void) { return gst_vaapi_create_display (GST_VAAPI_DISPLAY_TYPE_ANY, NULL); } + +/** + * gst_vaapi_driver_is_whitelisted: + * @display: a #GstVaapiDisplay + * + * Looks the VA-API driver vendors in an internal white-list. + * + * Returns: %TRUE if driver is in the white-list, otherwise %FALSE + **/ +gboolean +gst_vaapi_driver_is_whitelisted (GstVaapiDisplay * display) +{ + const gchar *vendor; + guint i; + static const gchar *whitelist[] = { + "Intel i965 driver", + "mesa gallium vaapi", + NULL + }; + + g_return_val_if_fail (display, FALSE); + + if (g_getenv (GST_VAAPI_ALL_DRIVERS_ENV)) + return TRUE; + + vendor = gst_vaapi_display_get_vendor_string (display); + if (!vendor) + goto no_vendor; + + for (i = 0; whitelist[i]; i++) { + if (g_ascii_strncasecmp (vendor, whitelist[i], strlen (whitelist[i])) == 0) + return TRUE; + } + + GST_ERROR ("Unsupported VA driver: %s. Export environment variable " + GST_VAAPI_ALL_DRIVERS_ENV " to bypass", vendor); + return FALSE; + + /* ERRORS */ +no_vendor: + { + GST_WARNING ("no VA-API driver vendor description"); + return FALSE; + } +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 84da876c8d..5d01ff6035 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -135,4 +135,8 @@ G_GNUC_INTERNAL GstVaapiDisplay * gst_vaapi_create_test_display (void); +G_GNUC_INTERNAL +gboolean +gst_vaapi_driver_is_whitelisted (GstVaapiDisplay * display); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ From 90b0ba7e2b981bed19532bfcda41081d57de73ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Jun 2016 12:36:26 +0200 Subject: [PATCH 2486/3781] vaapi: don't register if VA driver is unsupported Using the test VA display, the driver name is queried, and if it is not white-listed, the plugin rejects to register any element. https://bugzilla.gnome.org/show_bug.cgi?id=724352 --- gst/vaapi/gstvaapi.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index f52f1f4c4a..8ec40468a4 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -88,6 +88,8 @@ plugin_init (GstPlugin * plugin) display = gst_vaapi_create_test_display (); if (!display) goto error_no_display; + if (!gst_vaapi_driver_is_whitelisted (display)) + goto unsupported_driver; gst_vaapidecode_register (plugin); @@ -133,6 +135,11 @@ error_no_display: * transient condition */ return TRUE; } +unsupported_driver: + { + gst_vaapi_display_unref (display); + return TRUE; /* return TRUE to avoid get blacklisted */ + } } GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, From c60312c78f9b8e7e28b84968d7ee7f95aa199a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 12 Jul 2016 20:29:12 +0200 Subject: [PATCH 2487/3781] vaapi: register vaapipostproc only if supported Query the GstVaapiDisplay to know if the driver supports video postprocessing. If does, then register vaapipostproc and vaapidecodebin elements. This patch will simplify the design of vaapidecodebin. https://bugzilla.gnome.org/show_bug.cgi?id=724352 --- gst/vaapi/gstvaapi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 8ec40468a4..079c048530 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -93,8 +93,14 @@ plugin_init (GstPlugin * plugin) gst_vaapidecode_register (plugin); - gst_element_register (plugin, "vaapipostproc", - GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); + if (gst_vaapi_display_has_video_processing (display)) { + gst_element_register (plugin, "vaapipostproc", + GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); + + gst_element_register (plugin, "vaapidecodebin", + GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); + } + gst_element_register (plugin, "vaapisink", GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); #if USE_ENCODERS @@ -120,9 +126,6 @@ plugin_init (GstPlugin * plugin) #endif #endif - gst_element_register (plugin, "vaapidecodebin", - GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); - gst_vaapi_display_unref (display); return TRUE; From 4a9b20465234d73d0cf0239fef483abcd8b412d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 12 Jul 2016 20:38:07 +0200 Subject: [PATCH 2488/3781] vaapidecode: remove change_state() vmethod Since the driver checkup is done at registering, there is no need to do it when changing the element state from NULL to READY. This patch remove this vmethod from vaapidecode. --- gst/vaapi/gstvaapidecode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index e6f6687520..af2a97c10c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -160,7 +160,7 @@ static const GstVaapiDecoderMap vaapi_decode_map[] = { }; static GstElementClass *parent_class = NULL; -GST_VAAPI_PLUGIN_BASE_DEFINE_VMETHODS (parent_class); +GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT (parent_class); static gboolean gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps); @@ -1306,7 +1306,6 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) } element_class->set_context = gst_vaapi_base_set_context; - element_class->change_state = GST_DEBUG_FUNCPTR (gst_vaapi_base_change_state); gst_element_class_set_static_metadata (element_class, longname, "Codec/Decoder/Video", GST_PLUGIN_DESC, "Gwenole Beauchesne , " From dcb0de85328c6a4d13d88f33400c0f7dd187d97c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 12 Jul 2016 18:24:10 +0200 Subject: [PATCH 2489/3781] plugins: remove common change_state() vmethod Remove the common change_state() vmethod for all the plugins, since no one is using it. --- gst/vaapi/gstvaapipluginbase.h | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 4a1de465fa..53dd928d12 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -98,10 +98,6 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (gst_vaapi_display_replace(&GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin), \ (new_display))) -#define GST_VAAPI_PLUGIN_BASE_DEFINE_VMETHODS(parent_class) \ - GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT(parent_class) \ - GST_VAAPI_PLUGIN_BASE_DEFINE_CHANGE_STATE(parent_class) - #define GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT(parent_class) \ static void \ gst_vaapi_base_set_context (GstElement * element, GstContext * context) \ @@ -112,31 +108,6 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; GST_ELEMENT_CLASS (parent_class)->set_context (element, context); \ } -#define GST_VAAPI_PLUGIN_BASE_DEFINE_CHANGE_STATE(parent_class) \ - static GstStateChangeReturn \ - gst_vaapi_base_change_state (GstElement * element, \ - GstStateChange transition) \ - { \ - GstStateChangeReturn ret; \ - \ - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, \ - transition); \ - if (ret == GST_STATE_CHANGE_FAILURE) \ - return ret; \ - \ - switch (transition) { \ - case GST_STATE_CHANGE_NULL_TO_READY:{ \ - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); \ - if (!gst_vaapi_plugin_base_driver_is_whitelisted (plugin)) \ - ret = GST_STATE_CHANGE_FAILURE; \ - break; \ - } \ - default: \ - break; \ - } \ - return ret; \ - } - struct _GstVaapiPluginBase { /*< private >*/ From fabcb4dc06a4f9bf2dc6b5573943d99b6a2dde29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 28 Jun 2016 17:14:06 +0200 Subject: [PATCH 2490/3781] plugins: remove gst_vaapi_plugin_base_driver_is_whitelisted() Since nobody is calling gst_vaapi_plugin_base_driver_is_whitelisted(), it is deleted. --- gst/vaapi/gstvaapipluginbase.c | 26 -------------------------- gst/vaapi/gstvaapipluginbase.h | 4 ---- 2 files changed, 30 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index b9c579932e..b8092fa06c 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -75,32 +75,6 @@ gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, plugin_set_display (plugin, display); } -/** - * gst_vaapi_plugin_base_driver_is_whitelisted: - * @plugin: a #GstVaapiPluginBase instance - * - * Looks the VA-API driver vendors in an internal white-list. - * - * Returns: %TRUE if driver is in the white-list, otherwise %FALSE - **/ -gboolean -gst_vaapi_plugin_base_driver_is_whitelisted (GstVaapiPluginBase * plugin) -{ - GstVaapiDisplay *display; - - display = GST_VAAPI_PLUGIN_BASE_DISPLAY (plugin); - if (!display) - goto no_display; - return gst_vaapi_driver_is_whitelisted (display); - - /* ERRORS */ -no_display: - { - GST_WARNING_OBJECT (plugin, "no VA-API display available"); - return FALSE; - } -} - void gst_vaapi_plugin_base_init_interfaces (GType g_define_type_id) { diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 53dd928d12..9526d8ff10 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -226,10 +226,6 @@ GstFlowReturn gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, GstBuffer * inbuf, GstBuffer ** outbuf_ptr); -G_GNUC_INTERNAL -gboolean -gst_vaapi_plugin_base_driver_is_whitelisted (GstVaapiPluginBase * plugin); - G_GNUC_INTERNAL void gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, From 604986749ed3380fd176360f3e49ee1824cecc45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 2 Jun 2016 19:57:08 +0200 Subject: [PATCH 2491/3781] plugins: add gst_vaapi_plugin_base_find_gl_context() Using the GstContext mechanism, it is possible to find if the pipeline shares a GstGLContext, even if we are not to negotiating GLTextureUpload meta. This is interesting because we could negotiate system memory caps feature, but enable DMABuf if the GstGLContext is EGL with some extensions. https://bugzilla.gnome.org/show_bug.cgi?id=766206 --- gst/vaapi/gstvaapipluginbase.c | 26 +++++++++++++++++---- gst/vaapi/gstvaapivideocontext.c | 40 ++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapivideocontext.h | 5 ++++ 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index b8092fa06c..ad65297925 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -206,6 +206,17 @@ error_create_proxy: } } +static void +gst_vaapi_plugin_base_find_gl_context (GstVaapiPluginBase * plugin) +{ + GstObject *gl_context; + + if (!gst_vaapi_find_gl_local_context (GST_ELEMENT_CAST (plugin), &gl_context)) + return; + gst_vaapi_plugin_base_set_gl_context (plugin, gl_context); + gst_object_unref (gl_context); +} + void gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) { @@ -363,6 +374,10 @@ gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) return TRUE; gst_vaapi_display_replace (&plugin->display, NULL); + /* Query for a local GstGL context. If it's found, it will be used + * to create the VA display */ + gst_vaapi_plugin_base_find_gl_context (plugin); + if (!gst_vaapi_ensure_display (GST_ELEMENT (plugin), plugin->display_type_req)) return FALSE; @@ -750,10 +765,6 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!caps) goto error_no_caps; - /* We don't need any GL context beyond this point if not requested - so explicitly through GstVideoGLTextureUploadMeta */ - gst_object_replace (&plugin->gl_context, NULL); - pool_options = 0; if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) pool_options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; @@ -766,7 +777,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, pool_options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD; #if USE_GST_GL_HELPERS - if (pool_options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD) { + if (!plugin->gl_context && + (pool_options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD)) { const GstStructure *params; GstObject *gl_context; @@ -1007,6 +1019,9 @@ gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, GstGLContext *const gl_context = GST_GL_CONTEXT (object); GstVaapiDisplayType display_type; + if (plugin->gl_context == object) + return; + gst_object_replace (&plugin->gl_context, object); switch (gst_gl_context_get_gl_platform (gl_context)) { @@ -1024,6 +1039,7 @@ gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, display_type = plugin->display_type; break; } + GST_INFO_OBJECT (plugin, "GL context: %" GST_PTR_FORMAT, plugin->gl_context); gst_vaapi_plugin_base_set_display_type (plugin, display_type); #endif } diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index cb5b68e1fb..8bd4448f39 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -25,6 +25,9 @@ #include "gstcompat.h" #include "gstvaapivideocontext.h" +#if USE_GST_GL_HELPERS +# include +#endif GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); @@ -233,3 +236,40 @@ gst_vaapi_video_context_propagate (GstElement * element, msg = gst_message_new_have_context (GST_OBJECT_CAST (element), context); gst_element_post_message (GST_ELEMENT_CAST (element), msg); } + +gboolean +gst_vaapi_find_gl_local_context (GstElement * element, + GstObject ** gl_context_ptr) +{ +#if USE_GST_GL_HELPERS + GstQuery *query; + GstContext *context; + const GstStructure *s; + GstObject *gl_context; + + g_return_val_if_fail (gl_context_ptr, FALSE); + + gl_context = NULL; + query = gst_query_new_context ("gst.gl.local_context"); + if (_gst_context_run_query (element, query, GST_PAD_SRC)) { + gst_query_parse_context (query, &context); + if (context) { + s = gst_context_get_structure (context); + gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &gl_context, NULL); + } + } + if (!gl_context && _gst_context_run_query (element, query, GST_PAD_SINK)) { + gst_query_parse_context (query, &context); + if (context) { + s = gst_context_get_structure (context); + gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &gl_context, NULL); + } + } + gst_query_unref (query); + if (gl_context) { + *gl_context_ptr = gl_context; + return TRUE; + } +#endif + return FALSE; +} diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index 2d56183dfb..437486b239 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -56,4 +56,9 @@ void gst_vaapi_video_context_propagate (GstElement * element, GstVaapiDisplay * display); +G_GNUC_INTERNAL +gboolean +gst_vaapi_find_gl_local_context (GstElement * element, + GstObject ** gl_context_ptr); + #endif /* GST_VAAPI_VIDEO_CONTEXT_H */ From 0faff37e73ccb5f513b337ae0eae640fcf655295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 12 Jul 2016 17:49:50 +0200 Subject: [PATCH 2492/3781] pluginutil: set GLX display type The function gst_vaapi_create_display_from_gl_context() cretes a GstVaapiDisplay given a GstGLContext. But it didn't created a GLX VA display when the GL platform was GLX, but a plain X11 VA display. This patch fixes that, by querying the GL platform earlier. https://bugzilla.gnome.org/show_bug.cgi?id=766206 --- gst/vaapi/gstvaapipluginutil.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index de32521d0f..4422daa9a5 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -136,12 +136,19 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) GstGLDisplay *const gl_display = gst_gl_context_get_display (gl_context); gpointer native_display = GSIZE_TO_POINTER (gst_gl_display_get_handle (gl_display)); + GstGLPlatform platform = gst_gl_context_get_gl_platform (gl_context); GstVaapiDisplay *display, *out_display; GstVaapiDisplayType display_type; switch (gst_gl_display_get_handle_type (gl_display)) { #if USE_X11 case GST_GL_DISPLAY_TYPE_X11: +#if USE_GLX + if (platform == GST_GL_PLATFORM_GLX) { + display_type = GST_VAAPI_DISPLAY_TYPE_GLX; + break; + } +#endif display_type = GST_VAAPI_DISPLAY_TYPE_X11; break; #endif @@ -192,7 +199,7 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) if (!display) return NULL; - switch (gst_gl_context_get_gl_platform (gl_context)) { + switch (platform) { #if USE_EGL case GST_GL_PLATFORM_EGL:{ guint gles_version; From cc6c2d23ce1adf2235412b26f2f8637b3630f697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 12 Jul 2016 17:54:26 +0200 Subject: [PATCH 2493/3781] vaapidecode: delay the GstVaapiDisplay instantiating Delay the GstVaapiDisplay instantiating until when changing the state from READY to PAUSE. In this way the element has more chances to find an already created GstVaapiDisplay, or a GL context, in the pipeline. https://bugzilla.gnome.org/show_bug.cgi?id=766206 --- gst/vaapi/gstvaapidecode.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index af2a97c10c..5ed1c38fe4 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -950,8 +950,6 @@ static gboolean gst_vaapidecode_open (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - GstVaapiDisplay *const old_display = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode); - gboolean success; if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (decode))) return FALSE; @@ -960,17 +958,7 @@ gst_vaapidecode_open (GstVideoDecoder * vdec) decode->display_height = 0; gst_video_info_init (&decode->decoded_info); - /* Let GstVideoContext ask for a proper display to its neighbours */ - /* Note: steal old display that may be allocated from get_caps() - so that to retain a reference to it, thus avoiding extra - initialization steps if we turn out to simply re-use the - existing (cached) VA display */ - GST_VAAPI_PLUGIN_BASE_DISPLAY (decode) = NULL; - success = gst_vaapidecode_ensure_display (decode); - if (old_display) - gst_vaapi_display_unref (old_display); - - return success; + return TRUE; } static gboolean @@ -983,6 +971,27 @@ gst_vaapidecode_close (GstVideoDecoder * vdec) return TRUE; } +static gboolean +gst_vaapidecode_start (GstVideoDecoder * vdec) +{ + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstVaapiDisplay *const old_display = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode); + gboolean success; + + /* Let GstVideoContext ask for a proper display to its neighbours */ + /* Note: steal old display that may be allocated from get_caps() + so that to retain a reference to it, thus avoiding extra + initialization steps if we turn out to simply re-use the + existing (cached) VA display */ + GST_VAAPI_PLUGIN_BASE_DISPLAY (decode) = NULL; + success = + gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (decode)); + if (old_display) + gst_vaapi_display_unref (old_display); + + return success; +} + static gboolean gst_vaapidecode_stop (GstVideoDecoder * vdec) { @@ -1280,6 +1289,7 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->open = GST_DEBUG_FUNCPTR (gst_vaapidecode_open); vdec_class->close = GST_DEBUG_FUNCPTR (gst_vaapidecode_close); + vdec_class->start = GST_DEBUG_FUNCPTR (gst_vaapidecode_start); vdec_class->stop = GST_DEBUG_FUNCPTR (gst_vaapidecode_stop); vdec_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapidecode_set_format); vdec_class->flush = GST_DEBUG_FUNCPTR (gst_vaapidecode_flush); From ca0c3fd627e20eb261aaa79eff7a69ef028e467e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 12 Jul 2016 22:19:37 +0200 Subject: [PATCH 2494/3781] vaapidecodebin: simplify the code Since the elements dependant of the VA video processor are now only registered if it is available, vaapidecodebin code can be simplified a lot, removing all the code required to check if the VA video processor was available. https://bugzilla.gnome.org/show_bug.cgi?id=768899 --- gst/vaapi/gstvaapidecodebin.c | 214 +++------------------------------- 1 file changed, 16 insertions(+), 198 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 79731e6362..9e20727c01 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -146,110 +146,6 @@ post_missing_element_message (GstVaapiDecodeBin * vaapidecbin, missing_factory), ("video decoding might fail")); } -static gboolean -activate_vpp (GstVaapiDecodeBin * vaapidecbin) -{ - GstPad *queue_srcpad, *srcpad, *vpp_sinkpad, *vpp_srcpad; - gboolean res; - - if (vaapidecbin->postproc) - return TRUE; - - if (vaapidecbin->has_vpp != HAS_VPP_YES || vaapidecbin->disable_vpp) - return TRUE; - - GST_DEBUG_OBJECT (vaapidecbin, "Enabling VPP"); - - /* create the postproc */ - vaapidecbin->postproc = - gst_element_factory_make ("vaapipostproc", "vaapipostproc"); - if (!vaapidecbin->postproc) - goto error_element_missing; - - g_object_set (G_OBJECT (vaapidecbin->postproc), "deinterlace-method", - vaapidecbin->deinterlace_method, NULL); - - gst_bin_add (GST_BIN (vaapidecbin), vaapidecbin->postproc); - - if (!gst_element_sync_state_with_parent (vaapidecbin->postproc)) - goto error_sync_state; - - srcpad = gst_element_get_static_pad (GST_ELEMENT_CAST (vaapidecbin), "src"); - if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (srcpad), NULL)) - goto error_link_pad; - - queue_srcpad = gst_element_get_static_pad (vaapidecbin->queue, "src"); - vpp_sinkpad = gst_element_get_static_pad (vaapidecbin->postproc, "sink"); - res = (gst_pad_link (queue_srcpad, vpp_sinkpad) == GST_PAD_LINK_OK); - gst_object_unref (vpp_sinkpad); - gst_object_unref (queue_srcpad); - if (!res) - goto error_link_pad; - - vpp_srcpad = gst_element_get_static_pad (vaapidecbin->postproc, "src"); - res = gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (srcpad), vpp_srcpad); - gst_object_unref (vpp_srcpad); - if (!res) - goto error_link_pad; - - gst_object_unref (srcpad); - - return TRUE; - -error_element_missing: - { - post_missing_element_message (vaapidecbin, "vaapipostproc"); - return FALSE; - } -error_sync_state: - { - GST_ERROR_OBJECT (vaapidecbin, "Failed to sync VPP state"); - return FALSE; - } -error_link_pad: - { - gst_object_unref (srcpad); - GST_ERROR_OBJECT (vaapidecbin, "Failed to link the child elements"); - return FALSE; - } -} - -static gboolean -ensure_vpp (GstVaapiDecodeBin * vaapidecbin) -{ - GstVaapiDisplay *display; - - if (vaapidecbin->has_vpp != HAS_VPP_UNKNOWN) - return TRUE; - - display = GST_VAAPI_PLUGIN_BASE_DISPLAY (vaapidecbin->decoder); - if (display) { - GST_INFO_OBJECT (vaapidecbin, "Got display from vaapidecode"); - gst_vaapi_display_ref (display); - } else { - GST_INFO_OBJECT (vaapidecbin, "Creating a dummy display to test for vpp"); - display = gst_vaapi_create_test_display (); - } - if (!display) - return FALSE; - - vaapidecbin->has_vpp = gst_vaapi_display_has_video_processing (display) ? - HAS_VPP_YES : HAS_VPP_NO; - - gst_vaapi_display_unref (display); - - return TRUE; -} - -static gboolean -gst_vaapi_decode_bin_reconfigure (GstVaapiDecodeBin * vaapidecbin) -{ - if (!ensure_vpp (vaapidecbin)) - return FALSE; - - return activate_vpp (vaapidecbin); -} - static void gst_vaapi_decode_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -326,101 +222,18 @@ gst_vaapi_decode_bin_get_property (GObject * object, } } -static void -gst_vaapi_decode_bin_handle_message (GstBin * bin, GstMessage * message) -{ - GstVaapiDecodeBin *vaapidecbin = GST_VAAPI_DECODE_BIN (bin); - GstMessageType type; - GstContext *context = NULL; - const gchar *context_type; - GstVaapiDisplay *display = NULL; - - type = GST_MESSAGE_TYPE (message); - if (type != GST_MESSAGE_HAVE_CONTEXT) - goto bail; - gst_message_parse_have_context (message, &context); - if (!context) - goto bail; - context_type = gst_context_get_context_type (context); - if (g_strcmp0 (context_type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) != 0) - goto bail; - if (!gst_vaapi_video_context_get_display (context, &display)) - goto bail; - - vaapidecbin->has_vpp = gst_vaapi_display_has_video_processing (display) ? - HAS_VPP_YES : HAS_VPP_NO; - - /* the underlying VA driver implementation doesn't support video - * post-processing, hence we have to disable it */ - if (vaapidecbin->has_vpp != HAS_VPP_YES) { - GST_WARNING_OBJECT (vaapidecbin, "VA driver doesn't support VPP"); - if (!vaapidecbin->disable_vpp) { - vaapidecbin->disable_vpp = TRUE; - g_object_notify_by_pspec (G_OBJECT (vaapidecbin), - properties[PROP_DISABLE_VPP]); - } - } - -bail: - if (display) - gst_vaapi_display_unref (display); - - if (context) - gst_context_unref (context); - - GST_BIN_CLASS (gst_vaapi_decode_bin_parent_class)->handle_message (bin, - message); -} - -static GstStateChangeReturn -gst_vaapi_decode_bin_change_state (GstElement * element, - GstStateChange transition) -{ - GstVaapiDecodeBin *vaapidecbin = GST_VAAPI_DECODE_BIN (element); - GstStateChangeReturn ret; - - switch (transition) { - default: - break; - } - - ret = GST_ELEMENT_CLASS (gst_vaapi_decode_bin_parent_class)->change_state - (element, transition); - if (ret == GST_STATE_CHANGE_FAILURE) - return ret; - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - if (!gst_vaapi_decode_bin_reconfigure (vaapidecbin)) - return GST_STATE_CHANGE_FAILURE; - break; - default: - break; - } - - return ret; -} - static void gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) { GObjectClass *gobject_class; GstElementClass *element_class; - GstBinClass *bin_class; gobject_class = G_OBJECT_CLASS (klass); element_class = GST_ELEMENT_CLASS (klass); - bin_class = GST_BIN_CLASS (klass); gobject_class->set_property = gst_vaapi_decode_bin_set_property; gobject_class->get_property = gst_vaapi_decode_bin_get_property; - element_class->change_state = - GST_DEBUG_FUNCPTR (gst_vaapi_decode_bin_change_state); - - bin_class->handle_message = - GST_DEBUG_FUNCPTR (gst_vaapi_decode_bin_handle_message); - gst_element_class_set_static_metadata (element_class, "VA-API Decode Bin", "Codec/Decoder/Video", @@ -466,7 +279,6 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) { const gchar *missing_factory = NULL; GstPad *pad, *ghostpad; - GstPadTemplate *tmpl; /* create the decoder */ /* @FIXME: "vaapidecode" is going to be removed soon: (bug @@ -474,14 +286,13 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) * "vaapi{codec}dec". We will need a mechanism to automatically * select de correct decoder based on caps. */ - vaapidecbin->decoder = - gst_element_factory_make ("vaapidecode", "vaapidecode"); + vaapidecbin->decoder = gst_element_factory_make ("vaapidecode", NULL); if (!vaapidecbin->decoder) { missing_factory = "vaapidecode"; goto error_element_missing; } /* create the queue */ - vaapidecbin->queue = gst_element_factory_make ("queue", "queue"); + vaapidecbin->queue = gst_element_factory_make ("queue", NULL); if (!vaapidecbin->queue) { missing_factory = "queue"; goto error_element_missing; @@ -492,10 +303,18 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) "max-size-buffers", vaapidecbin->max_size_buffers, "max-size-time", vaapidecbin->max_size_time, NULL); - gst_bin_add_many (GST_BIN (vaapidecbin), vaapidecbin->decoder, - vaapidecbin->queue, NULL); + /* create the postproc */ + vaapidecbin->postproc = gst_element_factory_make ("vaapipostproc", NULL); + if (!vaapidecbin->postproc) { + missing_factory = "vaapipostproc"; + goto error_element_missing; + } - if (!gst_element_link_many (vaapidecbin->decoder, vaapidecbin->queue, NULL)) + gst_bin_add_many (GST_BIN (vaapidecbin), vaapidecbin->decoder, + vaapidecbin->queue, vaapidecbin->postproc, NULL); + + if (!gst_element_link_many (vaapidecbin->decoder, vaapidecbin->queue, + vaapidecbin->postproc, NULL)) goto error_link_pad; /* create ghost pad sink */ @@ -507,11 +326,10 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) goto error_adding_pad; /* create ghost pad src */ - pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->queue), "src"); - tmpl = gst_static_pad_template_get (&gst_vaapi_decode_bin_src_factory); - ghostpad = gst_ghost_pad_new_from_template ("src", pad, tmpl); + pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->postproc), "src"); + ghostpad = gst_ghost_pad_new_from_template ("src", pad, + GST_PAD_PAD_TEMPLATE (pad)); gst_object_unref (pad); - gst_object_unref (tmpl); if (!gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad)) goto error_adding_pad; From 55daedf514175949d0343123f15fe2d45b0fa4a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 7 Jun 2016 16:28:07 +0200 Subject: [PATCH 2495/3781] vaapidecode: split all the codecs Split the vaapidecode to all the supported codecs with the format vaapi{codec}dec. vaapidecode is stil registered as a GObject type, but not as a GStreamer feature, so it can be used internally by vaapidecodebin without changing its code too much. https://bugzilla.gnome.org/show_bug.cgi?id=734093 --- gst/vaapi/gstvaapidecode.c | 25 ++++++++++++++++++++++++- gst/vaapi/gstvaapidecodebin.c | 13 +++---------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 5ed1c38fe4..3d6ceae941 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -154,6 +154,25 @@ struct _GstVaapiDecoderMap static const GstVaapiDecoderMap vaapi_decode_map[] = { #if USE_JPEG_DECODER {GST_VAAPI_CODEC_JPEG, GST_RANK_MARGINAL, "jpeg", "image/jpeg"}, +#endif + {GST_VAAPI_CODEC_MPEG2, GST_RANK_PRIMARY, "mpeg2", + "video/mpeg, mpegversion=2, systemstream=(boolean)false"}, + {GST_VAAPI_CODEC_MPEG4, GST_RANK_PRIMARY, "mpeg4", + "video/mpeg, mpegversion=4"}, + {GST_VAAPI_CODEC_H263, GST_RANK_PRIMARY, "h263", "video/x-h263"}, + {GST_VAAPI_CODEC_H264, GST_RANK_PRIMARY, "h264", "video/x-h264"}, + {GST_VAAPI_CODEC_WMV3, GST_RANK_PRIMARY, "wmv3", + "video/x-wmv, wmvversion=3, format=WMV3"}, + {GST_VAAPI_CODEC_VC1, GST_RANK_PRIMARY, "vc1", + "video/x-wmv, wmvversion=3, format={WVC1,WMVA}"}, +#if USE_VP8_DECODER + {GST_VAAPI_CODEC_VP8, GST_RANK_PRIMARY, "vp8", "video/x-vp8"}, +#endif +#if USE_VP9_DECODER + {GST_VAAPI_CODEC_VP9, GST_RANK_PRIMARY, "vp9", "video/x-vp9"}, +#endif +#if USE_HEVC_DECODER + {GST_VAAPI_CODEC_H265, GST_RANK_PRIMARY, "h265", "video/x-h265"}, #endif {0 /* the rest */ , GST_RANK_PRIMARY + 1, NULL, gst_vaapidecode_sink_caps_str}, @@ -1393,7 +1412,11 @@ gst_vaapidecode_register (GstPlugin * plugin) (gpointer) & vaapi_decode_map[i]); } - ret |= gst_element_register (plugin, element_name, rank, type); + /* Register GstVaapiDecode as GObject type, but not in GStreamer, so + * vaapidecodebin can use it internally, but no exposed as a plugin + * feature */ + if (codec) + ret |= gst_element_register (plugin, element_name, rank, type); g_free (element_name); g_free (type_name); diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 9e20727c01..1b1aead9cb 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -281,16 +281,9 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) GstPad *pad, *ghostpad; /* create the decoder */ - /* @FIXME: "vaapidecode" is going to be removed soon: (bug - * #734093). Instead there are going to be a set of elements - * "vaapi{codec}dec". We will need a mechanism to automatically - * select de correct decoder based on caps. - */ - vaapidecbin->decoder = gst_element_factory_make ("vaapidecode", NULL); - if (!vaapidecbin->decoder) { - missing_factory = "vaapidecode"; - goto error_element_missing; - } + vaapidecbin->decoder = + g_object_new (g_type_from_name ("GstVaapiDecode"), NULL); + /* create the queue */ vaapidecbin->queue = gst_element_factory_make ("queue", NULL); if (!vaapidecbin->queue) { From eb621c970e560bb0e07a3086d36df7ab768299af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 28 Jun 2016 11:43:15 +0200 Subject: [PATCH 2496/3781] vaapi: register only the available encoders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to register only the available encoders, this patch queries the created test VA display, which uses the currently used back-end (X11, Wayland, DRM, …) on the used display device. https://bugzilla.gnome.org/show_bug.cgi?id=724352 --- gst/vaapi/gstvaapi.c | 119 +++++++++++++++++++++++++++------ gst/vaapi/gstvaapipluginutil.c | 23 +++++++ gst/vaapi/gstvaapipluginutil.h | 4 ++ 3 files changed, 126 insertions(+), 20 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 079c048530..6530cc178f 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -78,6 +78,104 @@ plugin_add_dependencies (GstPlugin * plugin) GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_DEFAULT_ONLY); } +static GArray * +profiles_get_codecs (GArray * profiles) +{ + guint i; + GArray *codecs; + GstVaapiProfile profile; + GstVaapiCodec codec; + + codecs = g_array_new (FALSE, FALSE, sizeof (GstVaapiCodec)); + if (!codecs) + return NULL; + + for (i = 0; i < profiles->len; i++) { + profile = g_array_index (profiles, GstVaapiProfile, i); + codec = gst_vaapi_profile_get_codec (profile); + if (gst_vaapi_codecs_has_codec (codecs, codec)) + continue; + g_array_append_val (codecs, codec); + } + + return codecs; +} + +#if USE_ENCODERS +static GArray * +display_get_encoder_codecs (GstVaapiDisplay * display) +{ + GArray *profiles, *codecs; + + profiles = gst_vaapi_display_get_encode_profiles (display); + if (!profiles) + return NULL; + + codecs = profiles_get_codecs (profiles); + g_array_unref (profiles); + return codecs; +} + +typedef struct _GstVaapiEncoderMap GstVaapiEncoderMap; +struct _GstVaapiEncoderMap +{ + GstVaapiCodec codec; + guint rank; + const gchar *name; + GType (*get_type) (void); +}; + +#define DEF_ENC(CODEC,codec) \ + {GST_VAAPI_CODEC_##CODEC, \ + GST_RANK_PRIMARY, \ + "vaapi" G_STRINGIFY (codec) "enc", \ + gst_vaapiencode_##codec##_get_type} + +static const GstVaapiEncoderMap vaapi_encode_map[] = { + DEF_ENC (H264, h264), + DEF_ENC (MPEG2, mpeg2), +#if USE_JPEG_ENCODER + DEF_ENC (JPEG, jpeg), +#endif +#if USE_VP8_ENCODER + DEF_ENC (VP8, vp8), +#endif +#if USE_VP9_ENCODER + DEF_ENC (VP9, vp9), +#endif +#if USE_H265_ENCODER + DEF_ENC (H265, h265), +#endif +}; + +#undef DEF_ENC + +static void +gst_vaapiencode_register (GstPlugin * plugin, GstVaapiDisplay * display) +{ + guint i, j; + GArray *codecs; + GstVaapiCodec codec; + + codecs = display_get_encoder_codecs (display); + if (!codecs) + return; + + for (i = 0; i < codecs->len; i++) { + codec = g_array_index (codecs, GstVaapiCodec, i); + for (j = 0; j < G_N_ELEMENTS (vaapi_encode_map); j++) { + if (vaapi_encode_map[j].codec == codec) { + gst_element_register (plugin, vaapi_encode_map[j].name, + vaapi_encode_map[j].rank, vaapi_encode_map[j].get_type ()); + break; + } + } + } + + g_array_unref (codecs); +} +#endif + static gboolean plugin_init (GstPlugin * plugin) { @@ -104,26 +202,7 @@ plugin_init (GstPlugin * plugin) gst_element_register (plugin, "vaapisink", GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); #if USE_ENCODERS - gst_element_register (plugin, "vaapih264enc", - GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_H264); - gst_element_register (plugin, "vaapimpeg2enc", - GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_MPEG2); -#if USE_JPEG_ENCODER - gst_element_register (plugin, "vaapijpegenc", - GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_JPEG); -#endif -#if USE_VP8_ENCODER - gst_element_register (plugin, "vaapivp8enc", - GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_VP8); -#endif -#if USE_H265_ENCODER - gst_element_register (plugin, "vaapih265enc", - GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_H265); -#endif -#if USE_VP9_ENCODER - gst_element_register (plugin, "vaapivp9enc", - GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_VP9); -#endif + gst_vaapiencode_register (plugin, display); #endif gst_vaapi_display_unref (display); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 4422daa9a5..38172ae7d3 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -777,3 +777,26 @@ no_vendor: return FALSE; } } + +/** + * gst_vaapi_codecs_has_codec: + * @codecs: a #GArray of #GstVaapiCodec + * @codec: a #GstVaapiCodec to find in @codec + * + * Returns: %TRUE if @codec is in @codecs + **/ +gboolean +gst_vaapi_codecs_has_codec (GArray * codecs, GstVaapiCodec codec) +{ + guint i; + GstVaapiCodec c; + + g_return_val_if_fail (codec, FALSE); + + for (i = 0; i < codecs->len; i++) { + c = g_array_index (codecs, GstVaapiCodec, i); + if (c == codec) + return TRUE; + } + return FALSE; +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 5d01ff6035..7b0710a058 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -139,4 +139,8 @@ G_GNUC_INTERNAL gboolean gst_vaapi_driver_is_whitelisted (GstVaapiDisplay * display); +G_GNUC_INTERNAL +gboolean +gst_vaapi_codecs_has_codec (GArray * codecs, GstVaapiCodec codec); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ From 5beccf5fa06bcab14da213d3f7187eb122fbb6e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 12 Jul 2016 23:47:41 +0200 Subject: [PATCH 2497/3781] vaapidecode: register only the available decoders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to register only the available decoders, this patch queries the created test VA display, which uses the currently used back-end (X11, Wayland, DRM, …) on the used display device. https://bugzilla.gnome.org/show_bug.cgi?id=724352 --- gst/vaapi/gstvaapi.c | 21 ++++++++++++++++++++- gst/vaapi/gstvaapidecode.c | 5 ++++- gst/vaapi/gstvaapidecode.h | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 6530cc178f..a17ede8e0a 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -101,6 +101,20 @@ profiles_get_codecs (GArray * profiles) return codecs; } +static GArray * +display_get_decoder_codecs (GstVaapiDisplay * display) +{ + GArray *profiles, *codecs; + + profiles = gst_vaapi_display_get_decode_profiles (display); + if (!profiles) + return NULL; + + codecs = profiles_get_codecs (profiles); + g_array_unref (profiles); + return codecs; +} + #if USE_ENCODERS static GArray * display_get_encoder_codecs (GstVaapiDisplay * display) @@ -180,6 +194,7 @@ static gboolean plugin_init (GstPlugin * plugin) { GstVaapiDisplay *display; + GArray *decoders; plugin_add_dependencies (plugin); @@ -189,7 +204,11 @@ plugin_init (GstPlugin * plugin) if (!gst_vaapi_driver_is_whitelisted (display)) goto unsupported_driver; - gst_vaapidecode_register (plugin); + decoders = display_get_decoder_codecs (display); + if (decoders) { + gst_vaapidecode_register (plugin, decoders); + g_array_unref (decoders); + } if (gst_vaapi_display_has_video_processing (display)) { gst_element_register (plugin, "vaapipostproc", diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3d6ceae941..ef3babbed8 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1370,7 +1370,7 @@ gst_vaapidecode_init (GstVaapiDecode * decode) } gboolean -gst_vaapidecode_register (GstPlugin * plugin) +gst_vaapidecode_register (GstPlugin * plugin, GArray * decoders) { gboolean ret = FALSE; guint i, codec, rank; @@ -1394,6 +1394,9 @@ gst_vaapidecode_register (GstPlugin * plugin) rank = vaapi_decode_map[i].rank; name = vaapi_decode_map[i].name; + if (codec && !gst_vaapi_codecs_has_codec (decoders, codec)) + continue; + if (codec) { type_name = g_strdup_printf ("GstVaapiDecode_%s", name); element_name = g_strdup_printf ("vaapi%sdec", name); diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 043294b120..c4fad51a96 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -62,7 +62,7 @@ struct _GstVaapiDecodeClass { GstVaapiPluginBaseClass parent_class; }; -gboolean gst_vaapidecode_register (GstPlugin * plugin); +gboolean gst_vaapidecode_register (GstPlugin * plugin, GArray * decoders); G_END_DECLS From 27429ce676e5759c77e8b55b30603161125c14d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 13 Jul 2016 18:34:57 +0200 Subject: [PATCH 2498/3781] libs: egl: remove dynamic library loading code Since the upstream of gstreamer-vaapi, the library is not a public shared object anymore. But the EGL support depended on this dynamic library, so the EGL support was broken. This patch removes the dynamic library loading code and instantiates the EGL display using either X11 or Wayland if available. https://bugzilla.gnome.org/show_bug.cgi?id=767203 --- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 272 ++--------------------- 1 file changed, 22 insertions(+), 250 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index 3d7ec20b16..feab6408fb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -29,230 +29,14 @@ #include "gstvaapiwindow_priv.h" #include "gstvaapitexture_egl.h" -GST_DEBUG_CATEGORY (gst_debug_vaapidisplay_egl); - -/* ------------------------------------------------------------------------- */ -/* --- Display backend loader --- */ -/* ------------------------------------------------------------------------- */ - -typedef struct _GstVaapiDisplayLoader GstVaapiDisplayLoader; -typedef struct _GstVaapiDisplayLoaderInfo GstVaapiDisplayLoaderInfo; - -typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFunc) (const gchar * name); -typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFromNativeFunc) (gpointer dpy); - -struct _GstVaapiDisplayLoader -{ - GstVaapiMiniObject parent_instance; - - GModule *module; - GPtrArray *module_names; - GstVaapiDisplayCreateFunc create_display; - GstVaapiDisplayCreateFromNativeFunc create_display_from_native; -}; - -struct _GstVaapiDisplayLoaderInfo -{ - const gchar *name; - GstVaapiDisplayType type; - const gchar *create_display; - const gchar *create_display_from_native; -}; - -static GMutex g_loader_lock; -static GstVaapiDisplayLoader *g_loader; - -/* *INDENT-OFF* */ -static const GstVaapiDisplayLoaderInfo g_loader_info[] = { -#if USE_WAYLAND - { "wayland", - GST_VAAPI_DISPLAY_TYPE_WAYLAND, - "gst_vaapi_display_wayland_new", - "gst_vaapi_display_wayland_new_with_display", - }, -#endif #if USE_X11 - { "x11", - GST_VAAPI_DISPLAY_TYPE_X11, - "gst_vaapi_display_x11_new", - "gst_vaapi_display_x11_new_with_display", - }, +#include "gstvaapidisplay_x11.h" +#endif +#if USE_WAYLAND +#include "gstvaapidisplay_wayland.h" #endif - {NULL,} -}; -/* *INDENT-ON* */ -static void -gst_vaapi_display_loader_finalize (GstVaapiDisplayLoader * loader) -{ - if (!loader) - return; - - if (loader->module) { - g_module_close (loader->module); - loader->module = NULL; - } - - if (loader->module_names) { - g_ptr_array_unref (loader->module_names); - loader->module_names = NULL; - } -} - -static inline const GstVaapiMiniObjectClass * -gst_vaapi_display_loader_class (void) -{ - static const GstVaapiMiniObjectClass g_class = { - .size = sizeof (GstVaapiDisplayLoader), - .finalize = (GDestroyNotify) gst_vaapi_display_loader_finalize, - }; - return &g_class; -} - -static inline GstVaapiDisplayLoader * -gst_vaapi_display_loader_new (void) -{ - return (GstVaapiDisplayLoader *) - gst_vaapi_mini_object_new0 (gst_vaapi_display_loader_class ()); -} - -static gboolean -gst_vaapi_display_loader_reset_module_names (GstVaapiDisplayLoader * loader, - const GstVaapiDisplayLoaderInfo * loader_info) -{ - gchar *module_name; - - if (loader->module_names) - g_ptr_array_unref (loader->module_names); - loader->module_names = g_ptr_array_new_full (3, (GDestroyNotify) g_free); - if (!loader->module_names) - return FALSE; - - module_name = - g_strdup_printf ("libgstvaapi-%s-%s.la", loader_info->name, - GST_API_VERSION_S); - if (module_name) - g_ptr_array_add (loader->module_names, module_name); - - module_name = - g_strdup_printf ("libgstvaapi-%s-%s.so", loader_info->name, - GST_API_VERSION_S); - if (module_name) - g_ptr_array_add (loader->module_names, module_name); - - module_name = - g_strdup_printf ("libgstvaapi-%s-%s.so.%s", loader_info->name, - GST_API_VERSION_S, GST_VAAPI_MAJOR_VERSION_S); - if (module_name) - g_ptr_array_add (loader->module_names, module_name); - - return loader->module_names->len > 0; -} - -static gboolean -gst_vaapi_display_loader_try_load_module (GstVaapiDisplayLoader * loader, - const GstVaapiDisplayLoaderInfo * loader_info) -{ - guint i; - - if (!gst_vaapi_display_loader_reset_module_names (loader, loader_info)) - return FALSE; - - if (loader->module) { - g_module_close (loader->module); - loader->module = NULL; - } - - for (i = 0; i < loader->module_names->len; i++) { - const gchar *const module_name = - g_ptr_array_index (loader->module_names, i); - - loader->module = g_module_open (module_name, - G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); - if (loader->module) - return TRUE; - } - return FALSE; -} - -static gboolean -gst_vaapi_display_loader_try_load (GstVaapiDisplayLoader * loader, - const GstVaapiDisplayLoaderInfo * loader_info) -{ - guint has_errors = 0; - - if (!gst_vaapi_display_loader_try_load_module (loader, loader_info)) - return FALSE; - GST_DEBUG ("loaded backend: %s", g_module_name (loader->module)); - - has_errors |= !g_module_symbol (loader->module, - loader_info->create_display, (gpointer *) & loader->create_display); - has_errors |= !g_module_symbol (loader->module, - loader_info->create_display_from_native, - (gpointer *) & loader->create_display_from_native); - - return has_errors == 0; -} - -static GstVaapiDisplay * -gst_vaapi_display_loader_try_load_any (GstVaapiDisplayLoader * loader) -{ - GstVaapiDisplay *display; - const GstVaapiDisplayLoaderInfo *loader_info; - - for (loader_info = g_loader_info; loader_info->name != NULL; loader_info++) { - if (!gst_vaapi_display_loader_try_load (loader, loader_info)) - continue; - - display = loader->create_display (NULL); - if (display) { - GST_INFO ("selected backend: %s", loader_info->name); - return display; - } - } - return NULL; -} - -#define gst_vaapi_display_loader_ref(loader) \ - ((GstVaapiDisplayLoader *) gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (loader))) -#define gst_vaapi_display_loader_unref(loader) \ - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (loader)) -#define gst_vaapi_display_loader_replace(old_loader_ptr, new_loader) \ - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **)(old_loader_ptr), \ - GST_VAAPI_MINI_OBJECT (new_loader)) - -static GstVaapiDisplayLoader * -gst_vaapi_display_loader_acquire_global (void) -{ - GstVaapiDisplayLoader *loader; - - g_mutex_lock (&g_loader_lock); - loader = g_loader ? gst_vaapi_display_loader_ref (g_loader) : - gst_vaapi_display_loader_new (); - g_loader = loader; - g_mutex_unlock (&g_loader_lock); - return loader; -} - -static void -gst_vaapi_display_loader_release_global (void) -{ - g_mutex_lock (&g_loader_lock); - gst_vaapi_display_loader_replace (&g_loader, NULL); - g_mutex_unlock (&g_loader_lock); -} - -static const GstVaapiDisplayLoaderInfo * -gst_vaapi_display_loader_map_lookup_type (GstVaapiDisplayType type) -{ - const GstVaapiDisplayLoaderInfo *loader_info; - - for (loader_info = g_loader_info; loader_info->name != NULL; loader_info++) { - if (loader_info->type == type) - return loader_info; - } - return NULL; -} +GST_DEBUG_CATEGORY (gst_debug_vaapidisplay_egl); /* ------------------------------------------------------------------------- */ /* --- EGL backend implementation --- */ @@ -310,29 +94,28 @@ static gboolean gst_vaapi_display_egl_bind_display (GstVaapiDisplayEGL * display, const InitParams * params) { - GstVaapiDisplay *native_display; - GstVaapiDisplayLoader *loader; - const GstVaapiDisplayLoaderInfo *loader_info; + GstVaapiDisplay *native_display = NULL; EglDisplay *egl_display; - loader = gst_vaapi_display_loader_acquire_global (); if (params->display) { - loader_info = - gst_vaapi_display_loader_map_lookup_type (params->display_type); - if (!loader_info) - goto error_unsupported_display_type; - - loader = gst_vaapi_display_loader_new (); - if (!loader || !gst_vaapi_display_loader_try_load (loader, loader_info)) - goto error_init_loader; - - native_display = loader->create_display_from_native (params->display); +#if USE_X11 + if (params->display_type == GST_VAAPI_DISPLAY_TYPE_X11) + native_display = gst_vaapi_display_x11_new_with_display (params->display); +#endif +#if USE_WAYLAND + if (params->display_type == GST_VAAPI_DISPLAY_TYPE_WAYLAND) + native_display = + gst_vaapi_display_wayland_new_with_display (params->display); +#endif } else { - gst_vaapi_display_loader_ref (loader); - native_display = gst_vaapi_display_loader_try_load_any (loader); +#if USE_X11 + native_display = gst_vaapi_display_x11_new (NULL); +#endif +#if USE_WAYLAND + if (!native_display) + native_display = gst_vaapi_display_wayland_new (NULL); +#endif } - gst_vaapi_display_loader_replace (&display->loader, loader); - gst_vaapi_display_loader_unref (loader); if (!native_display) return FALSE; @@ -347,23 +130,12 @@ gst_vaapi_display_egl_bind_display (GstVaapiDisplayEGL * display, egl_object_unref (egl_display); display->gles_version = params->gles_version; return TRUE; - - /* ERRORS */ -error_unsupported_display_type: - GST_ERROR ("unsupported display type (%d)", params->display_type); - return FALSE; -error_init_loader: - GST_ERROR ("failed to initialize display backend loader"); - gst_vaapi_display_loader_replace (&loader, NULL); - return FALSE; } static void gst_vaapi_display_egl_close_display (GstVaapiDisplayEGL * display) { gst_vaapi_display_replace (&display->display, NULL); - gst_vaapi_display_loader_replace (&display->loader, NULL); - gst_vaapi_display_loader_release_global (); } static void From 971472e9c492c541d0a17fed69b18c5d5a8b6bfc Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Wed, 27 Jul 2016 10:09:38 -0700 Subject: [PATCH 2499/3781] configure: Fix non-fatal PKG_CHECK_MODULES invocations Some invocations of PKG_CHECK_MODULES were intended to be non-fatal if the package is missing, but action-if-not-found was given as an empty string which still causes the default action to run, which halts execution. Signed-off-by: Scott D Phillips https://bugzilla.gnome.org/show_bug.cgi?id=769237 --- configure.ac | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 994dec167f..173f9df5a8 100644 --- a/configure.ac +++ b/configure.ac @@ -282,7 +282,7 @@ GstGLContext gl_context; CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) - ], []) + ], [:]) fi AS_IF([test "x$ac_cv_have_gst_gl_helpers" = "xno"], [HAVE_GSTGL=0]) AM_CONDITIONAL([USE_GST_GL_HELPERS], [test $HAVE_GSTGL -eq 1]) @@ -308,7 +308,7 @@ if test "x$enable_drm" = "xyes"; then CPPFLAGS="$CPPFLAGS $DRM_CFLAGS" AC_CHECK_HEADERS([drm_fourcc.h], [], [USE_DRM=0]) CPPFLAGS="$saved_CPPFLAGS" - ], []) + ], [:]) fi dnl Check for X11 @@ -321,7 +321,7 @@ if test "x$enable_x11" = "xyes"; then CPPFLAGS="$CPPFLAGS $X11_CFLAGS" AC_CHECK_HEADERS([X11/Xlib.h X11/Xutil.h X11/Xatom.h], [], [USE_X11=0]) CPPFLAGS="$saved_CPPFLAGS" - ], []) + ], [:]) fi HAVE_XKBLIB=0 @@ -340,7 +340,7 @@ if test $USE_X11 -eq 1; then CPPFLAGS="$CPPFLAGS $XRANDR_CFLAGS" AC_CHECK_HEADERS([X11/extensions/Xrandr.h], [], [HAVE_XRANDR=0]) CPPFLAGS="$saved_CPPFLAGS" - ], []) + ], [:]) dnl Check for XRender PKG_CHECK_MODULES([XRENDER], [xrender], @@ -350,7 +350,7 @@ if test $USE_X11 -eq 1; then CPPFLAGS="$CPPFLAGS $XRENDER_CFLAGS" AC_CHECK_HEADERS([X11/extensions/Xrender.h], [], [HAVE_XRENDER=0]) CPPFLAGS="$saved_CPPFLAGS" - ], []) + ], [:]) fi AC_DEFINE_UNQUOTED([HAVE_XKBLIB], [$HAVE_XKBLIB], @@ -465,7 +465,7 @@ if test "x$enable_egl" = "xyes" -a $GLES_VERSION_MASK -ne 0; then dnl Check for GMODULE PKG_CHECK_MODULES([GMODULE], [gmodule-2.0 >= $GLIB_REQ]) - ], []) + ], [:]) fi dnl Check for Wayland @@ -478,7 +478,7 @@ if test "x$enable_wayland" = "xyes"; then CPPFLAGS="$CPPFLAGS $WAYLAND_CFLAGS" AC_CHECK_HEADERS([wayland-client.h], [], [USE_WAYLAND=0]) CPPFLAGS="$saved_CPPFLAGS" - ], []) + ], [:]) fi dnl --------------------------------------------------------------------------- @@ -722,7 +722,7 @@ if test "x$enable_encoders" = "xyes"; then #include ]) CPPFLAGS="$saved_CPPFLAGS" - ], []) + ], [:]) fi USE_JPEG_ENCODER=0 From ad3ae71032d4bbb3940e3e604e3c9af92e01e2b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Jul 2016 19:49:59 +0200 Subject: [PATCH 2500/3781] configure: remove gmodule-2.0 EGL dependency Since commit 27429ce, EGL support doesn't depend on dynamic loading libraries, thus the dependency to gmodule-2.0 is not mandatory anymore. --- configure.ac | 3 --- 1 file changed, 3 deletions(-) diff --git a/configure.ac b/configure.ac index 173f9df5a8..991826d869 100644 --- a/configure.ac +++ b/configure.ac @@ -462,9 +462,6 @@ if test "x$enable_egl" = "xyes" -a $GLES_VERSION_MASK -ne 0; then AC_CHECK_LIB([EGL], [eglGetDisplay], [], [USE_EGL=0]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" - - dnl Check for GMODULE - PKG_CHECK_MODULES([GMODULE], [gmodule-2.0 >= $GLIB_REQ]) ], [:]) fi From d0ee0b4e7216e8694ab3a32830e7eab4071ceca9 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 29 Jul 2016 18:06:30 +0900 Subject: [PATCH 2501/3781] plugins: update buffer pool size with new allocator's image size Depends on media, video size is sometimes updated with new allocator. It leads to dismatch between bufferpool's set size and real allocated buffer size. In this case, it causes every buffer is freed during release in bufferpool, which should be reused. This affects performance. https://bugzilla.gnome.org/show_bug.cgi?id=769248 --- gst/vaapi/gstvaapipluginbase.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index ad65297925..c5b8b8558d 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -832,6 +832,10 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!pool) { if (!ensure_srcpad_allocator (plugin, &vi)) goto error_create_allocator; + + /* Update video size with allocator's image size */ + size = GST_VIDEO_INFO_SIZE (&GST_VAAPI_VIDEO_ALLOCATOR_CAST + (plugin->srcpad_allocator)->image_info); pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, min, max, pool_options, plugin->srcpad_allocator); if (!pool) From 892b6d3822f675fdb84be90c4c5bf086cc2af331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Jul 2016 15:13:29 +0200 Subject: [PATCH 2502/3781] gstvaapivideomemory: allocator's image size getter Add the method gst_allocator_get_vaapi_image_size() for the GstVaapiVideoAllocator, which gets the size of the allocated images with the current video info. This method replaces the direct call to the allocator's image info when the pool is configured. --- gst/vaapi/gstvaapipluginbase.c | 4 +--- gst/vaapi/gstvaapivideomemory.c | 26 ++++++++++++++++++++++++++ gst/vaapi/gstvaapivideomemory.h | 4 ++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index c5b8b8558d..54fc403229 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -832,10 +832,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!pool) { if (!ensure_srcpad_allocator (plugin, &vi)) goto error_create_allocator; - /* Update video size with allocator's image size */ - size = GST_VIDEO_INFO_SIZE (&GST_VAAPI_VIDEO_ALLOCATOR_CAST - (plugin->srcpad_allocator)->image_info); + gst_allocator_get_vaapi_image_size (plugin->srcpad_allocator, &size); pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, min, max, pool_options, plugin->srcpad_allocator); if (!pool) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index ea09177faf..3b2b4d8264 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1036,6 +1036,32 @@ gst_allocator_set_vaapi_video_info (GstAllocator * allocator, return TRUE; } +/** + * gst_allocator_get_vaapi_image_size: + * @allocator: a #GstAllocator instance. + * @size: (out) (optional): the VA image size created by @allocator. + * + * This function gets the size of the VA images instantiated by the + * @allocator. + * + * Returns: %TRUE if @allocator is VA valid + **/ +gboolean +gst_allocator_get_vaapi_image_size (GstAllocator * allocator, guint * size) +{ + GstVaapiVideoAllocator *alloc; + + g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), FALSE); + + if (g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME)) + return FALSE; + alloc = GST_VAAPI_VIDEO_ALLOCATOR_CAST (allocator); + if (alloc && size) + *size = GST_VIDEO_INFO_SIZE (&alloc->image_info); + + return TRUE; +} + gboolean gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator) { diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index c096a03b11..88a3814f40 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -216,6 +216,10 @@ gboolean gst_allocator_set_vaapi_video_info (GstAllocator * allocator, const GstVideoInfo * vip, guint flags); +G_GNUC_INTERNAL +gboolean +gst_allocator_get_vaapi_image_size (GstAllocator * allocator, guint * size); + G_GNUC_INTERNAL gboolean gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator); From 0541ef451080206782dab8b2949f7127c4b9d254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 Jul 2016 20:01:05 +0200 Subject: [PATCH 2503/3781] pluginutil: const params to gst_video_info_changed() Since they are not modified, we should mark them as const. --- gst/vaapi/gstvaapipluginutil.c | 2 +- gst/vaapi/gstvaapipluginutil.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 38172ae7d3..4e3d7a3947 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -691,7 +691,7 @@ gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, * @new. Otherwise, %FALSE. **/ gboolean -gst_video_info_changed (GstVideoInfo * old, GstVideoInfo * new) +gst_video_info_changed (const GstVideoInfo * old, const GstVideoInfo * new) { if (GST_VIDEO_INFO_FORMAT (old) != GST_VIDEO_INFO_FORMAT (new)) return TRUE; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 7b0710a058..34aea9cd1e 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -125,7 +125,7 @@ gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, G_GNUC_INTERNAL gboolean -gst_video_info_changed (GstVideoInfo * old, GstVideoInfo * new); +gst_video_info_changed (const GstVideoInfo * old, const GstVideoInfo * new); G_GNUC_INTERNAL void From 01b5ed3edbab7bfad8d1c6464051799bc07a85ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 Jul 2016 19:27:27 +0200 Subject: [PATCH 2504/3781] plugins: remove sink pad allocator if caps change If the negotiated sinkpad caps change, destroy the assignated allocator, because it is not valid anymore. --- gst/vaapi/gstvaapipluginbase.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 54fc403229..f41d39a450 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -616,6 +616,7 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) return TRUE; gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, FALSE); g_clear_object (&plugin->sinkpad_buffer_pool); + g_clear_object (&plugin->sinkpad_allocator); plugin->sinkpad_buffer_size = 0; } From 773eea0db06f3a10d2ad1e3470f671507b39755f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 Jul 2016 20:02:54 +0200 Subject: [PATCH 2505/3781] plugins: reset allocators if video info changed If the frame size or format, change, the allocators are reset, so a new ones can be created with the new video info. --- gst/vaapi/gstvaapipluginbase.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index f41d39a450..e80d203576 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -492,10 +492,26 @@ gst_vaapi_buffer_pool_caps_is_equal (GstBufferPool * pool, GstCaps * newcaps) return ret; } +static inline gboolean +reset_allocator (GstAllocator * allocator, GstVideoInfo * vinfo) +{ + const GstVideoInfo *orig_vi; + + if (!allocator) + return TRUE; + + orig_vi = gst_allocator_get_vaapi_video_info (allocator, NULL); + if (!gst_video_info_changed (orig_vi, vinfo)) + return FALSE; + + gst_object_unref (allocator); + return TRUE; +} + static gboolean ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo) { - if (plugin->sinkpad_allocator) + if (!reset_allocator (plugin->sinkpad_allocator, vinfo)) return TRUE; plugin->sinkpad_allocator = @@ -506,7 +522,7 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo) static gboolean ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo) { - if (plugin->srcpad_allocator) + if (!reset_allocator (plugin->srcpad_allocator, vinfo)) return TRUE; plugin->srcpad_allocator = From 020cb8badb10ecaa6003553289cab0fcde913cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 Jul 2016 19:24:08 +0200 Subject: [PATCH 2506/3781] plugins: check dmabuf-import for sink pad allocator Check earlier if upstream video source has activated the dmabuf-import io-mode (hack to disappear soon), thus we can avoid the re-assignation of a new allocator. --- gst/vaapi/gstvaapipluginbase.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e80d203576..7717ec5d0a 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -514,8 +514,14 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo) if (!reset_allocator (plugin->sinkpad_allocator, vinfo)) return TRUE; - plugin->sinkpad_allocator = - gst_vaapi_video_allocator_new (plugin->display, vinfo, 0); + if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) { + plugin->sinkpad_allocator = + gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo, + GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); + } else { + plugin->sinkpad_allocator = + gst_vaapi_video_allocator_new (plugin->display, vinfo, 0); + } return plugin->sinkpad_allocator != NULL; } From f182b8be2ba05965e6d31a4d380d6563b9b53a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 6 Aug 2016 12:54:17 +0100 Subject: [PATCH 2507/3781] encoders: demote to RANK_NONE since not fit for autoplugging yet Encoders claim to support a whole bunch of input formats but then just error out if the format is not actually supported, even if there's a converter in front. This means they're not fit for autoplugging in encodebin or camerabin yet and therefore should not have a rank. People can still use them in custom pipelines. https://bugzilla.gnome.org/show_bug.cgi?id=769266 --- gst/vaapi/gstvaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index a17ede8e0a..4c4a90d9ab 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -141,7 +141,7 @@ struct _GstVaapiEncoderMap #define DEF_ENC(CODEC,codec) \ {GST_VAAPI_CODEC_##CODEC, \ - GST_RANK_PRIMARY, \ + GST_RANK_NONE, \ "vaapi" G_STRINGIFY (codec) "enc", \ gst_vaapiencode_##codec##_get_type} From 4259d1aec7b046a992ad908804949d2167706280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 5 Jul 2016 20:07:15 +0200 Subject: [PATCH 2508/3781] vaapiencode: h264,h265: validate fps numerator Validate that fps numerator is non-zero so it can be used to calculate the duration of the B frame. Also it gst_util_uint64_scale() is used instead of normal arithmetic in order to aviod overflows, underflows and loss of precision. https://bugzilla.gnome.org/show_bug.cgi?id=768458 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 0b2878d593..9aa35e2968 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2467,11 +2467,11 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->num_bframes = 0; } - if (encoder->num_bframes) - encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) / - GST_VAAPI_ENCODER_FPS_N (encoder); + if (encoder->num_bframes > 0 && GST_VAAPI_ENCODER_FPS_N (encoder) > 0) + encoder->cts_offset = gst_util_uint64_scale (GST_SECOND, + GST_VAAPI_ENCODER_FPS_D (encoder), GST_VAAPI_ENCODER_FPS_N (encoder)); else - encoder->cts_offset = 0; + encoder->cts_offset = GST_CLOCK_TIME_NONE; /* init max_frame_num, max_poc */ encoder->log2_max_frame_num = diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 739feed46a..5d015baa78 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2030,11 +2030,11 @@ reset_properties (GstVaapiEncoderH265 * encoder) if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; - if (encoder->num_bframes) - encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) / - GST_VAAPI_ENCODER_FPS_N (encoder); + if (encoder->num_bframes > 0 && GST_VAAPI_ENCODER_FPS_N (encoder) > 0) + encoder->cts_offset = gst_util_uint64_scale (GST_SECOND, + GST_VAAPI_ENCODER_FPS_D (encoder), GST_VAAPI_ENCODER_FPS_N (encoder)); else - encoder->cts_offset = 0; + encoder->cts_offset = GST_CLOCK_TIME_NONE; /* init max_poc */ encoder->log2_max_pic_order_cnt = From 68b9ab78180c841ad17cb8076c179abdabce8796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 21 Jul 2016 17:38:40 +0200 Subject: [PATCH 2509/3781] encoder: h264,h265,mpeg2,vp8: use gst_util_uint64_scale() for bitrate Use gst_util_uint64_scale() to calculate bitrate instead of normal arithmetic to avoid overflows, underflows and loss of precision. https://bugzilla.gnome.org/show_bug.cgi?id=768458 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 +++--- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 6 +++--- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 9 +++++---- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 9 +++++---- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 9aa35e2968..b46315b071 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2382,10 +2382,10 @@ ensure_bitrate (GstVaapiEncoderH264 * encoder) if (!encoder->use_dct8x8) bits_per_mb += (bits_per_mb * 10) / 100; + guint64 factor = encoder->mb_width * encoder->mb_height * bits_per_mb; base_encoder->bitrate = - encoder->mb_width * encoder->mb_height * bits_per_mb * - GST_VAAPI_ENCODER_FPS_N (encoder) / - GST_VAAPI_ENCODER_FPS_D (encoder) / 1000; + gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder), + GST_VAAPI_ENCODER_FPS_D (encoder)) / 1000; GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate); } break; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 5d015baa78..b7fcc205a0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1947,10 +1947,10 @@ ensure_bitrate (GstVaapiEncoderH265 * encoder) /* Fixme: Provide better estimation */ /* Using a 1/6 compression ratio */ /* 12 bits per pixel fro yuv420 */ + guint64 factor = encoder->luma_width * encoder->luma_height * 12 / 6; base_encoder->bitrate = - (encoder->luma_width * encoder->luma_height * 12 / 6) * - GST_VAAPI_ENCODER_FPS_N (encoder) / - GST_VAAPI_ENCODER_FPS_D (encoder) / 1000; + gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder), + GST_VAAPI_ENCODER_FPS_D (encoder)) / 1000; GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate); } break; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 0620d9f9be..9333307864 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -186,10 +186,11 @@ ensure_bitrate (GstVaapiEncoderMpeg2 * encoder) switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { case GST_VAAPI_RATECONTROL_CBR: if (!base_encoder->bitrate) - base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * - GST_VAAPI_ENCODER_HEIGHT (encoder) * - GST_VAAPI_ENCODER_FPS_N (encoder) / - GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1000; + 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; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 65b449ed84..c23bd257b9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -125,10 +125,11 @@ ensure_bitrate (GstVaapiEncoderVP8 * encoder) switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { case GST_VAAPI_RATECONTROL_CBR: if (!base_encoder->bitrate) { - base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) * - GST_VAAPI_ENCODER_HEIGHT (encoder) * - GST_VAAPI_ENCODER_FPS_N (encoder) / - GST_VAAPI_ENCODER_FPS_D (encoder) / 4 * 1000; + 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; } default: base_encoder->bitrate = 0; From ad3b45ebc4fc771fd9d315ac53c8ab376276ed19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 10 Aug 2016 13:29:45 +0200 Subject: [PATCH 2510/3781] encoder: h264: fix C90 mixed declarations and code Commit 4259d1a introduced this compilation error. This patch fixes it. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index b46315b071..cc219b9cf6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2377,12 +2377,14 @@ ensure_bitrate (GstVaapiEncoderH264 * encoder) thus estimating +15% here ; and using adaptive 8x8 transforms in I-frames could bring up to +10% improvement. */ guint bits_per_mb = 48; + guint64 factor; + if (!encoder->use_cabac) bits_per_mb += (bits_per_mb * 15) / 100; if (!encoder->use_dct8x8) bits_per_mb += (bits_per_mb * 10) / 100; - guint64 factor = encoder->mb_width * encoder->mb_height * bits_per_mb; + factor = encoder->mb_width * encoder->mb_height * bits_per_mb; base_encoder->bitrate = gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder)) / 1000; From f31d9f37b615acd5d30cc9917ff57e5fba70d5d2 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Tue, 16 Aug 2016 11:58:38 +0300 Subject: [PATCH 2511/3781] decoder: vc1: Print error on interlaced content Interlaced video is as yet unsupported in the vc1 element. Print an error to make that more obvious. https://bugzilla.gnome.org/show_bug.cgi?id=769250 --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 76eb66063c..00ee16ae37 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -276,6 +276,11 @@ decode_sequence (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, priv->has_entrypoint = FALSE; + if (adv_hdr->interlace != 0) { + GST_ERROR ("interlaced sequence unsupported"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + /* Reset POC */ if (priv->last_non_b_picture) { if (priv->last_non_b_picture->poc == priv->next_poc) From 0df4b087151dc877c3287055225e0de681fd9676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 1 Sep 2016 12:34:38 +0300 Subject: [PATCH 2512/3781] Release 1.9.2 --- ChangeLog | 548 ++++++++++++++++++++++++++++++++++++++----- NEWS | 2 +- configure.ac | 14 +- gstreamer-vaapi.doap | 9 + 4 files changed, 511 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index eb543a0158..a5a8ac422c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,500 @@ -=== release 1.9.1 === +=== release 1.9.2 === -2016-07-06 Sebastian Dröge +2016-09-01 Sebastian Dröge * configure.ac: - releasing 1.9.1 + releasing 1.9.2 + +2016-08-16 11:58:38 +0300 Scott D Phillips + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: vc1: Print error on interlaced content + Interlaced video is as yet unsupported in the vc1 element. Print + an error to make that more obvious. + https://bugzilla.gnome.org/show_bug.cgi?id=769250 + +2016-08-10 13:29:45 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: fix C90 mixed declarations and code + Commit 4259d1a introduced this compilation error. This patch fixes it. + +2016-07-21 17:38:40 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + encoder: h264,h265,mpeg2,vp8: use gst_util_uint64_scale() for bitrate + Use gst_util_uint64_scale() to calculate bitrate instead of normal arithmetic + to avoid overflows, underflows and loss of precision. + https://bugzilla.gnome.org/show_bug.cgi?id=768458 + +2016-07-05 20:07:15 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + vaapiencode: h264,h265: validate fps numerator + Validate that fps numerator is non-zero so it can be used to calculate + the duration of the B frame. + Also it gst_util_uint64_scale() is used instead of normal arithmetic in + order to aviod overflows, underflows and loss of precision. + https://bugzilla.gnome.org/show_bug.cgi?id=768458 + +2016-08-06 12:54:17 +0100 Tim-Philipp Müller + + * gst/vaapi/gstvaapi.c: + encoders: demote to RANK_NONE since not fit for autoplugging yet + Encoders claim to support a whole bunch of input formats but then + just error out if the format is not actually supported, even if + there's a converter in front. This means they're not fit for + autoplugging in encodebin or camerabin yet and therefore should + not have a rank. People can still use them in custom pipelines. + https://bugzilla.gnome.org/show_bug.cgi?id=769266 + +2016-07-19 19:24:08 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: check dmabuf-import for sink pad allocator + Check earlier if upstream video source has activated the dmabuf-import + io-mode (hack to disappear soon), thus we can avoid the re-assignation of a + new allocator. + +2016-07-19 20:02:54 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: reset allocators if video info changed + If the frame size or format, change, the allocators are reset, so a new ones + can be created with the new video info. + +2016-07-19 19:27:27 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: remove sink pad allocator if caps change + If the negotiated sinkpad caps change, destroy the assignated allocator, + because it is not valid anymore. + +2016-07-19 20:01:05 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + pluginutil: const params to gst_video_info_changed() + Since they are not modified, we should mark them as const. + +2016-07-29 15:13:29 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + gstvaapivideomemory: allocator's image size getter + Add the method gst_allocator_get_vaapi_image_size() for the + GstVaapiVideoAllocator, which gets the size of the allocated images with the + current video info. + This method replaces the direct call to the allocator's image info when the + pool is configured. + +2016-07-29 18:06:30 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipluginbase.c: + plugins: update buffer pool size with new allocator's image size + Depends on media, video size is sometimes updated with new allocator. + It leads to dismatch between bufferpool's set size and real allocated buffer size. + In this case, it causes every buffer is freed during release in bufferpool, + which should be reused. This affects performance. + https://bugzilla.gnome.org/show_bug.cgi?id=769248 + +2016-07-27 19:49:59 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + configure: remove gmodule-2.0 EGL dependency + Since commit 27429ce, EGL support doesn't depend on dynamic loading libraries, + thus the dependency to gmodule-2.0 is not mandatory anymore. + +2016-07-27 10:09:38 -0700 Scott D Phillips + + * configure.ac: + configure: Fix non-fatal PKG_CHECK_MODULES invocations + Some invocations of PKG_CHECK_MODULES were intended to be non-fatal if + the package is missing, but action-if-not-found was given as an empty + string which still causes the default action to run, which halts + execution. + Signed-off-by: Scott D Phillips + https://bugzilla.gnome.org/show_bug.cgi?id=769237 + +2016-07-13 18:34:57 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + libs: egl: remove dynamic library loading code + Since the upstream of gstreamer-vaapi, the library is not a public shared + object anymore. But the EGL support depended on this dynamic library, so the + EGL support was broken. + This patch removes the dynamic library loading code and instantiates the + EGL display using either X11 or Wayland if available. + https://bugzilla.gnome.org/show_bug.cgi?id=767203 + +2016-07-12 23:47:41 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: register only the available decoders + In order to register only the available decoders, this patch queries the + created test VA display, which uses the currently used back-end (X11, Wayland, + DRM, …) on the used display device. + https://bugzilla.gnome.org/show_bug.cgi?id=724352 + +2016-06-28 11:43:15 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + vaapi: register only the available encoders + In order to register only the available encoders, this patch queries the + created test VA display, which uses the currently used back-end (X11, + Wayland, DRM, …) on the used display device. + https://bugzilla.gnome.org/show_bug.cgi?id=724352 + +2016-06-07 16:28:07 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + vaapidecode: split all the codecs + Split the vaapidecode to all the supported codecs with the format + vaapi{codec}dec. + vaapidecode is stil registered as a GObject type, but not as a + GStreamer feature, so it can be used internally by vaapidecodebin without + changing its code too much. + https://bugzilla.gnome.org/show_bug.cgi?id=734093 + +2016-07-12 22:19:37 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: simplify the code + Since the elements dependant of the VA video processor are now only registered + if it is available, vaapidecodebin code can be simplified a lot, removing all + the code required to check if the VA video processor was available. + https://bugzilla.gnome.org/show_bug.cgi?id=768899 + +2016-07-12 17:54:26 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: delay the GstVaapiDisplay instantiating + Delay the GstVaapiDisplay instantiating until when changing the state from + READY to PAUSE. In this way the element has more chances to find an already + created GstVaapiDisplay, or a GL context, in the pipeline. + https://bugzilla.gnome.org/show_bug.cgi?id=766206 + +2016-07-12 17:49:50 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + pluginutil: set GLX display type + The function gst_vaapi_create_display_from_gl_context() cretes a + GstVaapiDisplay given a GstGLContext. But it didn't created a GLX VA display + when the GL platform was GLX, but a plain X11 VA display. + This patch fixes that, by querying the GL platform earlier. + https://bugzilla.gnome.org/show_bug.cgi?id=766206 + +2016-06-02 19:57:08 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + plugins: add gst_vaapi_plugin_base_find_gl_context() + Using the GstContext mechanism, it is possible to find if the pipeline + shares a GstGLContext, even if we are not to negotiating GLTextureUpload + meta. This is interesting because we could negotiate system memory caps + feature, but enable DMABuf if the GstGLContext is EGL with some extensions. + https://bugzilla.gnome.org/show_bug.cgi?id=766206 + +2016-06-28 17:14:06 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: remove gst_vaapi_plugin_base_driver_is_whitelisted() + Since nobody is calling gst_vaapi_plugin_base_driver_is_whitelisted(), + it is deleted. + +2016-07-12 18:24:10 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.h: + plugins: remove common change_state() vmethod + Remove the common change_state() vmethod for all the plugins, since no one is + using it. + +2016-07-12 20:38:07 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: remove change_state() vmethod + Since the driver checkup is done at registering, there is no need to do it + when changing the element state from NULL to READY. This patch remove this + vmethod from vaapidecode. + +2016-07-12 20:29:12 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + vaapi: register vaapipostproc only if supported + Query the GstVaapiDisplay to know if the driver supports video + postprocessing. If does, then register vaapipostproc and vaapidecodebin + elements. + This patch will simplify the design of vaapidecodebin. + https://bugzilla.gnome.org/show_bug.cgi?id=724352 + +2016-06-29 12:36:26 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + vaapi: don't register if VA driver is unsupported + Using the test VA display, the driver name is queried, and if it is not + white-listed, the plugin rejects to register any element. + https://bugzilla.gnome.org/show_bug.cgi?id=724352 + +2016-06-28 17:14:06 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + plugins: add gst_vaapi_driver_is_whitelisted() + Move some of the logic in gst_vaapi_plugin_base_driver_is_whitelisted() to a + new function gst_vaapi_driver_is_whitelisted(), in this way, it can be used + when registering the plugin's feature set with the test VA display. + https://bugzilla.gnome.org/show_bug.cgi?id=724352 + +2016-07-12 19:56:02 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + vaapi: instantiate a VA display when registering + This patch tries to instantiate a GstVaapiDisplay when registering the plugin + features, if it fails, no gstreamer-vaapi element is registering. + The purpose of this patch is to avoid a situation where the user has + gstreamer-vaapi installed but their VA-API setup is not functional, which may + lead to unexpected behavior. + https://bugzilla.gnome.org/show_bug.cgi?id=724352 + +2016-06-28 11:33:18 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + * gst/vaapi/gstvaapi.c: + vaapi: declare external dependencies + There are two main external dependencies that define the feature set of this + plugin: a) the kernel and b) the VA driver + This patch tracks both dependencies, if any of them change, GStreamer will + re-inspect the plugin. + The kernel is tracked through the device files /dev/dri/card* + The VA driver is tracked through the files VA_DRIVERS_PATH/*_drv_video.so, + where VA_DRIVERS_PATH is the one defined in libva package configuration. Also, + the environment variables LIBVA_DRIVERS_PATH and LIBVA_DRIVER_NAME are tracked + since they modify the driver lookup. + Additionally, the environment variable GST_VAAPI_ALL_DRIVERS is tracked too. + https://bugzilla.gnome.org/show_bug.cgi?id=724352 + +2016-07-19 16:02:27 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: remove unneeded initializations + GObject's memory is set to zero, so there is no need to initialize to zero or + NULL it's class variables. + +2016-07-19 18:28:28 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.h: + plugins: remove undefined macros + +2016-07-19 17:43:28 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + Revert "gstvaapisurface_drm: release image when done" + This reverts commit 1dbcc8a0e199f2da6a0ab8e949f13341916128a3 and commit + 372a03a9e38acbf435eb80bf31d9a9844069e504. + While the dmabuf handle is exported, the derive image must exist, otherwise + the image's VA buffer is invalid, thus the dmabuf handle is never released, + leading into a file descriptors leak. + +2016-07-21 17:38:17 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + encoder: h265: fix code-style + +2016-07-22 16:55:59 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: update filters at color balance + This is a fix for a regression of previous commit, which updates the filters + only when the property is set, because it is also required to update the + filter when the color balance interface change its values. + +2016-07-22 12:10:23 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: make it enable/disable pass-through mode + In case that sink caps and src caps are same, and no filtering parameter set, + pass-through mode is enabled. + If new filtering parameter is set during playback, it makes it reconfiguring, + so that pass-through mode is changed + In addition, updating filter is performed during reconfiguration, if needed. + https://bugzilla.gnome.org/show_bug.cgi?id=751876 + +2016-07-22 11:51:26 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: checking and updating filter parameter only when it's set + This patch is to avoid checking filter value at every frame. + https://bugzilla.gnome.org/show_bug.cgi?id=751876 + +2016-07-21 11:24:31 +0300 Allen Zhang + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + decoder: h265: handle the SEI NAL units included in codec_data + The prefix/suffix SEI nal units can appear in codec_data too + which weren't handled before. Parse these SEI headers to + fix the segfault. + https://bugzilla.gnome.org/show_bug.cgi?id=768544 + +2016-07-15 16:32:26 +0200 Víctor Manuel Jáquez Leal + + * docs/plugins/Makefile.am: + build: doc: do not redefine MAINTAINERCLEANFILES + MAINTAINERCLEANFILES is defined in gtk-doc-plugins.mak, thus instead of + overload it, the files should be added. + +2016-07-15 14:41:27 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: Fix MVC encode while enabling dct8x8 + Pack the transform_8x8_mode_flag and other necessary rbsp data + in packed_pps header for MVC encode. + https://bugzilla.gnome.org/show_bug.cgi?id=768647 + +2016-07-12 23:58:55 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: demote a debug message to trace + Reduces noise when debugging. + +2016-07-13 17:21:01 +0900 Jagyum Koo + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + wayland: Error check before using cached wl_display + A planar(or some other) buffer allocation may fail on the driver, then + the wayland connection becomes invalid, not able to send request or + receive any event. So we need to set up a new wayland connection if + there's an error detected on the cached wl_display. + https://bugzilla.gnome.org/show_bug.cgi?id=768761 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-07-11 21:15:57 +0200 Stefan Sauer + + * common: + Automatic update of common submodule + From ac2f647 to f49c55e + +2016-07-05 18:23:22 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: demote a log to trace level + Removes noise when debugging. + +2016-07-06 11:17:23 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: implement flush() vmethod + In order to handle correctly seek and other operations, vaapiencode should + flush all the remaining data from the encoder without pushing it downstream. + This patch implements the flush() vmethod, only after of pausing the + source pad task, and restarting it again after the flush stop. + https://bugzilla.gnome.org/show_bug.cgi?id=767176 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-07-11 08:43:04 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: vc1: flush dpb only if opened + Flush the decode picture buffer, if and only if, the decoder is + started. Otherwise the dpb structure might be NULL. + https://bugzilla.gnome.org/show_bug.cgi?id=742922 + +2016-07-01 14:42:20 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: drop non-keyframe in reverse playback + To avoid surface-exhausted situation during reverse playback, + drop frames except for key frame. + Also, to avoid the corruption of the parser state, flush() vmethod + doesn't destroy the VA decoder when playing in reverse. + https://bugzilla.gnome.org/show_bug.cgi?id=742922 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-07-10 19:33:14 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: unref output frame earlier + The queue in GstVaapiDecode adds an extra reference to the frames. This patch + unref that extra reference earlier making the code simpler to follow. + https://bugzilla.gnome.org/show_bug.cgi?id=768652 + +2016-07-10 19:01:17 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: remove gst_vaapidecode_internal_flush() + As gst_vaapidecode_finish() is the only callee of + gst_vaapidecode_internal_flush(), it is better to inline it. + https://bugzilla.gnome.org/show_bug.cgi?id=768652 + +2016-07-10 18:18:57 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: flush output adapter at drain() + Calling drain() vmethod means "decode any data it can at this point, but that + more data may arrive after". Hence, vaapidecode should check if there is data + in the output adapter and process them, without destroying the decoded picture + buffer (dpb). + Since this operation is done by gst_vaapidecode_internal_flush(), the operation + was refactored into a new function gst_vaapidecode_flush_output_adapter(). + https://bugzilla.gnome.org/show_bug.cgi?id=768652 + +2016-07-10 13:46:25 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: call purge at flush() + Calling flush() vmethod means "to flush all remaining data from the decoder + without pushing it downstream". + Nonetheless flush() is calling gst_vaapidecode_internal_flush(), which calls + gst_video_decoder_have_frame() if there is still something in the input + adapter, which may push buffers to downstream by calling handle_frame(). + This patch changes this behavior by calling gst_vaapidecode_purge() rather + than gst_vaapidecode_internal_flush(), which does what we want: flushes the VA + decoder and releases all the rest of decoded frames. + https://bugzilla.gnome.org/show_bug.cgi?id=768652 + +2016-07-06 18:38:37 +0200 Víctor Manuel Jáquez Leal + + * tests/elements/Makefile.am: + * tests/elements/test-vaapisink.c: + test: elements: remove spurious linkage + Element tests only need to link against gstreamer libraries. + +2016-07-06 14:41:21 +0300 Sebastian Dröge + + * configure.ac: + configure: Require GLib >= 2.40 like everywhere else + +2016-07-06 13:51:21 +0300 Sebastian Dröge + + * configure.ac: + Back to development + +=== release 1.9.1 === + +2016-07-06 13:48:07 +0300 Sebastian Dröge + + * ChangeLog: + * NEWS: + * common: + * configure.ac: + * gstreamer-vaapi.doap: + Release 1.9.1 2016-07-05 20:59:49 +0200 Víctor Manuel Jáquez Leal @@ -1655,8 +2146,6 @@ * docs/plugins/gstreamer-vaapi-plugins.types: * docs/reference/Makefile.am: * docs/reference/plugins/Makefile.am: - * docs/reference/plugins/plugins-docs.xml.in: - * docs/reference/plugins/plugins-overrides.txt: * docs/reference/plugins/plugins-sections.txt: * docs/reference/plugins/plugins.types: * docs/version.entities.in: @@ -2328,9 +2817,7 @@ 2015-11-27 14:24:55 +0200 Sreerenj Balachandran - * patches/videoparsers/0005-h265parse-include-gstvaapiparse.h.patch: * patches/videoparsers/0005-videoparsers-h264-Disable-passthorugh-mode-enabling.patch: - * patches/videoparsers/0006-h265parse-fix-build-with-GStreamer-1.5.patch: * patches/videoparsers/0006-h265parse-include-gstvaapiparse.h.patch: * patches/videoparsers/0007-h265parse-fix-build-with-GStreamer-1.5.patch: * patches/videoparsers/series.frag: @@ -2984,7 +3471,6 @@ 2015-09-14 19:19:56 +0200 Víctor Manuel Jáquez Leal - * patches/videoparsers/0001-h265parse-include-gstvaapiparse.h.patch: * patches/videoparsers/0005-h265parse-include-gstvaapiparse.h.patch: * patches/videoparsers/series.frag: patches/videoparsers: h265parser: rename patch keeping number @@ -3003,7 +3489,6 @@ 2015-09-14 19:16:51 +0200 Víctor Manuel Jáquez Leal * patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStreamer-1.5.patch: - * patches/videoparsers/0004-h264parse-Disable-3D-video-support-for-GStremaer-1.5.patch: * patches/videoparsers/series.frag: patches/videoparsers: h264parser: fix description and refresh Fix a typo in the patch description and refresh it in order to avoid the @@ -4214,7 +4699,6 @@ 2015-05-26 10:21:59 +0300 Sreerenj Balachandran * patches/videoparsers/0003-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch: - * patches/videoparsers/0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch: * patches/videoparsers/series.frag: patches/videoparsers: Rebase the patch on top of gst-vaapi-branch commit 20ee952 Signed-off-by: Sreerenj Balachandran @@ -13547,8 +14031,6 @@ * gst-libs/gst/vaapi/Makefile.am: * gst-libs/gst/vaapi/gstvaapidecoder.c: - * gst-libs/gst/vaapi/gstvaapidecoder_frame.c: - * gst-libs/gst/vaapi/gstvaapidecoder_frame.h: * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: * gst-libs/gst/vaapi/gstvaapiparser_frame.c: * gst-libs/gst/vaapi/gstvaapiparser_frame.h: @@ -13981,8 +14463,6 @@ * docs/reference/libs/libs-sections.txt: * gst-libs/gst/vaapi/Makefile.am: - * gst-libs/gst/vaapi/gstvaapivideometa.c: - * gst-libs/gst/vaapi/gstvaapivideometa.h: * gst/vaapi/Makefile.am: * gst/vaapi/gstvaapidecode.c: * gst/vaapi/gstvaapidownload.c: @@ -14020,7 +14500,6 @@ * docs/reference/libs/libs-sections.txt: * docs/reference/libs/libs.core.types: * gst-libs/gst/vaapi/Makefile.am: - * gst-libs/gst/vaapi/gstvaapivideobuffer.c: * gst-libs/gst/vaapi/gstvaapivideobuffer.h: * gst/vaapi/Makefile.am: * gst/vaapi/gstvaapidownload.h: @@ -19248,8 +19727,6 @@ * docs/reference/plugins/plugins.types: * gst/vaapi/Makefile.am: * gst/vaapi/gstvaapi.c: - * gst/vaapi/gstvaapiconvert.c: - * gst/vaapi/gstvaapiconvert.h: * gst/vaapi/gstvaapiupload.c: * gst/vaapi/gstvaapiupload.h: Rename vaapiconvert element to vaapiupload. @@ -19551,7 +20028,6 @@ * configure.ac: * gst-libs/gst/vaapi/Makefile.am: * gst-libs/gst/vaapi/gstvaapiutils_gst.c: - * gst-libs/gst/vaapi/gstvaapiutils_gst.h: * gst/vaapi/Makefile.am: * gst/vaapi/gstvaapiconvert.c: * gst/vaapi/gstvaapidecode.c: @@ -19643,14 +20119,7 @@ * gst/vaapi/gstvaapisink.c: * gst/vaapi/gstvaapisink.h: * gst/vaapiconvert/Makefile.am: - * gst/vaapiconvert/gstvaapiconvert.c: - * gst/vaapiconvert/gstvaapiconvert.h: * gst/vaapidecode/Makefile.am: - * gst/vaapidecode/gstvaapidecode.c: - * gst/vaapidecode/gstvaapidecode.h: - * gst/vaapisink/Makefile.am: - * gst/vaapisink/gstvaapisink.c: - * gst/vaapisink/gstvaapisink.h: Group all plugins into the same bundle Signed-off-by: Gwenole Beauchesne @@ -21204,13 +21673,6 @@ * gst/vaapisink/Makefile.am: * gst/vaapisink/gstvaapisink.c: * gst/vaapisink/gstvaapisink.h: - * sys/Makefile.am: - * sys/vaapiconvert/Makefile.am: - * sys/vaapiconvert/gstvaapiconvert.c: - * sys/vaapiconvert/gstvaapiconvert.h: - * sys/vaapisink/Makefile.am: - * sys/vaapisink/gstvaapisink.c: - * sys/vaapisink/gstvaapisink.h: Rename to gst/ as sys/ was too vague. 2010-03-30 07:39:16 +0000 gb @@ -21287,7 +21749,6 @@ * docs/reference/libs/Makefile.am: * docs/reference/libs/libs.core.types: * docs/reference/libs/libs.glx.types: - * docs/reference/libs/libs.types: * docs/reference/libs/libs.x11.types: Fix doc build. @@ -21670,7 +22131,6 @@ * gst-libs/gst/vaapi/Makefile.am: * gst-libs/gst/vaapi/gstvaapiobject.c: * gst-libs/gst/vaapi/gstvaapiparamspecs.c: - * gst-libs/gst/vaapi/gstvaapitypes.c: * gst-libs/gst/vaapi/gstvaapitypes.h: * gst-libs/gst/vaapi/gstvaapivalue.c: Move GValue specific stuff to a dedicated file. @@ -21801,17 +22261,6 @@ * debian.upstream/libgstvaapi-x11.install.in: * debian.upstream/libgstvaapi.install.in: * debian.upstream/rules: - * debian/Makefile.am: - * debian/changelog.in: - * debian/compat: - * debian/control.in: - * debian/copyright: - * debian/gstreamer-vaapi-doc.install.in: - * debian/gstreamer-vaapi.install.in: - * debian/libgstvaapi-dev.install.in: - * debian/libgstvaapi-x11.install.in: - * debian/libgstvaapi.install.in: - * debian/rules: Generate upstream packages through make deb.upstream. 2010-03-23 17:40:03 +0000 gb @@ -22433,7 +22882,6 @@ * gst-libs/gst/vaapi/gstvaapivideopool.c: * gst-libs/gst/vaapi/gstvaapiwindow.c: * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: - * gst-libs/gst/vaapi/vaapi_debug.h: Rename vaapi_debug.h to gstvaapidebug.h. 2010-03-16 09:15:48 +0000 gb @@ -22447,8 +22895,6 @@ * gst-libs/gst/vaapi/gstvaapiutils.c: * gst-libs/gst/vaapi/gstvaapiutils.h: * gst-libs/gst/vaapi/vaapi_debug.h: - * gst-libs/gst/vaapi/vaapi_utils.c: - * gst-libs/gst/vaapi/vaapi_utils.h: Move vaapi_utils.* to gstvaapiutils.* 2010-03-16 09:13:16 +0000 gb @@ -22467,8 +22913,6 @@ 2010-03-16 09:03:10 +0000 gb * gst-libs/gst/vaapi/Makefile.am: - * gst-libs/gst/vaapi/gstvaapisinkbase.c: - * gst-libs/gst/vaapi/gstvaapisinkbase.h: * gst-libs/gst/vaapi/gstvaapivideosink.c: * gst-libs/gst/vaapi/gstvaapivideosink.h: * sys/vaapiconvert/gstvaapiconvert.c: @@ -22481,9 +22925,6 @@ * tests/Makefile.am: * tests/examples/Makefile.am: * tests/examples/generic/Makefile.am: - * tests/examples/generic/test-display.c: - * tests/examples/generic/test-surfaces.c: - * tests/examples/generic/test-windows.c: * tests/test-display.c: * tests/test-surfaces.c: * tests/test-windows.c: @@ -22782,7 +23223,6 @@ 2010-03-05 15:26:36 +0000 gb - * sys/vaapi/Makefile.am: * sys/vaapisink/Makefile.am: Rename to vaapisink. diff --git a/NEWS b/NEWS index 4c3baabdc2..027c01804e 100644 --- a/NEWS +++ b/NEWS @@ -1 +1 @@ -This is GStreamer 1.9.1 +This is GStreamer 1.9.2 diff --git a/configure.ac b/configure.ac index 991826d869..07d46f8a48 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [9]) -m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_nano_version], [1]) +m4_define([gst_vaapi_micro_version], [2]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [901]) +m4_define([gst_vaapi_lt_current], [902]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [901]) +m4_define([gst_vaapi_lt_age], [902]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.9.1.1]) -m4_define([gst_plugins_base_version], [1.9.1.1]) -m4_define([gst_plugins_bad_version], [1.9.1.1]) +m4_define([gst_version], [1.9.2]) +m4_define([gst_plugins_base_version], [1.9.2]) +m4_define([gst_plugins_bad_version], [1.9.2]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 6f9155799c..db2212c967 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,15 @@ + + + 1.9.2 + master + 2016-09-01 + + + + 1.9.1 From 58d5d6068171c7543016d427d93277d36c8af262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 1 Sep 2016 12:34:48 +0300 Subject: [PATCH 2513/3781] Back to development --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 07d46f8a48..d2eceebd93 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [9]) m4_define([gst_vaapi_micro_version], [2]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], From 2eb439416de641c56d09efa4a33671ab983eac12 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Fri, 26 Aug 2016 14:55:17 -0700 Subject: [PATCH 2514/3781] decoder: vc1: Fail only on actual interlaced frames In the earlier patch: f31d9f3 decoder: vc1: Print error on interlaced content Decoding would error out if the interlace flag was set in the sequence bdu. This isn't quite right because a video can have this flag set and yet not have any interlaced pictures. Here instead we error out when either parsing a field bdu or decoding a frame bdu which has fcm set to anything other than progressive. Signed-off-by: Scott D Phillips https://bugzilla.gnome.org/show_bug.cgi?id=769250 --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 00ee16ae37..7cfd4d284d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -276,11 +276,6 @@ decode_sequence (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, priv->has_entrypoint = FALSE; - if (adv_hdr->interlace != 0) { - GST_ERROR ("interlaced sequence unsupported"); - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - } - /* Reset POC */ if (priv->last_non_b_picture) { if (priv->last_non_b_picture->poc == priv->next_poc) @@ -962,6 +957,11 @@ decode_frame (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, GstVC1BDU * ebdu) return get_status (result); } + if (frame_hdr->pic.advanced.fcm != GST_VC1_FRAME_PROGRESSIVE) { + GST_ERROR ("interlaced video not supported"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + switch (frame_hdr->ptype) { case GST_VC1_PICTURE_TYPE_I: picture->type = GST_VAAPI_PICTURE_TYPE_I; @@ -1303,6 +1303,9 @@ gst_vaapi_decoder_vc1_parse (GstVaapiDecoder * base_decoder, case GST_VC1_SLICE: flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; break; + case GST_VC1_FIELD: + GST_ERROR ("interlaced video not supported"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags); return GST_VAAPI_DECODER_STATUS_SUCCESS; From 59821a21e935392c76c31b6fb081ccc5c85582af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 1 Sep 2016 12:39:15 +0200 Subject: [PATCH 2515/3781] vaapi: DISPLAY envvar as dependency In a multiple video cards system, a X11 environment may have different VA capabilities. This patch tracks the DISPLAY environment variable to invalidates the GStreamer features cache. Also tracks WAYLAND_DISPLAY. https://bugzilla.gnome.org/show_bug.cgi?id=770357 --- gst/vaapi/gstvaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 4c4a90d9ab..6996f7ae56 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -57,7 +57,7 @@ static void plugin_add_dependencies (GstPlugin * plugin) { const gchar *envvars[] = { "GST_VAAPI_ALL_DRIVERS", "LIBVA_DRIVER_NAME", - NULL + "DISPLAY", "WAYLAND_DISPLAY", NULL }; const gchar *kernel_paths[] = { "/dev/dri", NULL }; const gchar *kernel_names[] = { "card", "render" }; From 7ebef5809328534c74b9fbaabcd2363174545410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 6 Sep 2016 11:19:05 +0200 Subject: [PATCH 2516/3781] decoder: vc1: fails only on advanced profile In commit 2eb4394 the frame coding mode was verified for progressive regardless the profile. But the FCM is only valid in the advanced profile. This patch checks for the advanced profile before verifying FCM for progressive. https://bugzilla.gnome.org/show_bug.cgi?id=769250 --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 7cfd4d284d..b7929a3ae7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -957,7 +957,9 @@ decode_frame (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, GstVC1BDU * ebdu) return get_status (result); } - if (frame_hdr->pic.advanced.fcm != GST_VC1_FRAME_PROGRESSIVE) { + /* @FIXME: intel-driver cannot handle interlaced frames */ + if (priv->profile == GST_VAAPI_PROFILE_VC1_ADVANCED + && frame_hdr->pic.advanced.fcm != GST_VC1_FRAME_PROGRESSIVE) { GST_ERROR ("interlaced video not supported"); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } @@ -1304,6 +1306,7 @@ gst_vaapi_decoder_vc1_parse (GstVaapiDecoder * base_decoder, flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; break; case GST_VC1_FIELD: + /* @FIXME: intel-driver cannot handle interlaced frames */ GST_ERROR ("interlaced video not supported"); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } From 5ed967088f5f3256f4a0121c3b042ed05b967b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 6 Sep 2016 12:27:45 +0200 Subject: [PATCH 2517/3781] vaapidecode: merge vc1 and wmv3 elements This patch merges vaapivc1dec and vaapiwmv3dec into a single vaapivc1dec. Also, removed the WMVA format, since it is not supported by libva. https://bugzilla.gnome.org/show_bug.cgi?id=734093 --- gst/vaapi/gstvaapidecode.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ef3babbed8..ed24c95ed5 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -161,10 +161,8 @@ static const GstVaapiDecoderMap vaapi_decode_map[] = { "video/mpeg, mpegversion=4"}, {GST_VAAPI_CODEC_H263, GST_RANK_PRIMARY, "h263", "video/x-h263"}, {GST_VAAPI_CODEC_H264, GST_RANK_PRIMARY, "h264", "video/x-h264"}, - {GST_VAAPI_CODEC_WMV3, GST_RANK_PRIMARY, "wmv3", - "video/x-wmv, wmvversion=3, format=WMV3"}, {GST_VAAPI_CODEC_VC1, GST_RANK_PRIMARY, "vc1", - "video/x-wmv, wmvversion=3, format={WVC1,WMVA}"}, + "video/x-wmv, wmvversion=3, format={WMV3,WVC1}"}, #if USE_VP8_DECODER {GST_VAAPI_CODEC_VP8, GST_RANK_PRIMARY, "vp8", "video/x-vp8"}, #endif From c67edea4aba35f16d9e97c78a0b49ad1b590b112 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 7 Sep 2016 17:51:23 +0900 Subject: [PATCH 2518/3781] vaapivideomemory: load VA Image when mapping to write When calling gst_video_frame_map() with GST_MAP_WRITE flag, it doesn't call ensure_image_is_current(), which means it doesn't guarentee VAImage is valid in this case. https://bugzilla.gnome.org/show_bug.cgi?id=766978 --- gst/vaapi/gstvaapivideomemory.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 3b2b4d8264..813b41502b 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -208,8 +208,10 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, if (!ensure_image (mem)) goto error_ensure_image; - // Load VA image from surface - if ((flags & GST_MAP_READ) && !ensure_image_is_current (mem)) + /* Load VA image from surface only on read OR write, not both. + * Refer to bugs #704078 and #704083 */ + if (((flags & GST_MAP_READWRITE) != GST_MAP_READWRITE) + && !ensure_image_is_current (mem)) goto error_no_current_image; if (!gst_vaapi_image_map (mem->image)) From 574ff693a5eedf79f1e012654b6d08af486972fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 7 Sep 2016 17:34:08 +0200 Subject: [PATCH 2519/3781] libs: surface: ensure composite overlay is not bigger Ensure the composition overlay rectangle (subtitles) is not bigger than the surface where it is going to be composited and rendered. https://bugzilla.gnome.org/show_bug.cgi?id=766978 --- gst-libs/gst/vaapi/gstvaapisurface.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 07f8a29270..4ef616eec9 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -1016,6 +1016,10 @@ gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface, (gint *) & sub_rect.x, (gint *) & sub_rect.y, &sub_rect.width, &sub_rect.height); + /* ensure that the overlay is not bigger than the surface */ + sub_rect.y = MIN (sub_rect.y, surface->height); + sub_rect.width = MIN (sub_rect.width, surface->width); + if (!gst_vaapi_surface_associate_subpicture (surface, subpicture, NULL, &sub_rect)) { GST_WARNING ("could not render overlay rectangle %p", rect); From de233c137feefba9a993067d3b2b10a8d2fbbcd3 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 8 Sep 2016 16:16:09 +0900 Subject: [PATCH 2520/3781] plugins: set allocator's image size to sinkpad bufferpool Otherwise the buffer is always ditched by the bufferpool, losing performance. https://bugzilla.gnome.org/show_bug.cgi?id=771035 --- gst/vaapi/gstvaapipluginbase.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 7717ec5d0a..7849161bcb 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -625,6 +625,7 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) { GstBufferPool *pool; GstVideoInfo vi; + guint size; /* video decoders don't use a buffer pool in the sink pad */ if (GST_IS_VIDEO_DECODER (plugin)) @@ -648,13 +649,15 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) if (!ensure_sinkpad_allocator (plugin, &vi)) goto error_create_allocator; - pool = gst_vaapi_plugin_base_create_pool (plugin, caps, - GST_VIDEO_INFO_SIZE (&vi), 0, 0, + + size = GST_VIDEO_INFO_SIZE (&vi); + gst_allocator_get_vaapi_image_size (plugin->sinkpad_allocator, &size); + pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, 0, 0, GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, plugin->sinkpad_allocator); if (!pool) goto error_create_pool; plugin->sinkpad_buffer_pool = pool; - plugin->sinkpad_buffer_size = GST_VIDEO_INFO_SIZE (&vi); + plugin->sinkpad_buffer_size = size; return TRUE; /* ERRORS */ From 188f9992091b259c4f2447e235c9025c5aa71277 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sat, 10 Sep 2016 09:58:25 +1000 Subject: [PATCH 2521/3781] Automatic update of common submodule From f49c55e to b18d820 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index f49c55ecd3..b18d820635 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit f49c55ecd35a7436194d28297f6d6f20eb6a66fa +Subproject commit b18d820635185eb549530af1ce406937141b2dd9 From 7f4374f6866c7639006952f38f5692c6cce4a016 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sat, 10 Sep 2016 20:52:21 +1000 Subject: [PATCH 2522/3781] Automatic update of common submodule From b18d820 to f980fd9 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index b18d820635..f980fd91c1 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit b18d820635185eb549530af1ce406937141b2dd9 +Subproject commit f980fd91c1c1fd01333966041a4a535366e897bd From abffbfc71f0ab3ce66601f9d3374a5fe4507f8af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 9 Sep 2016 12:03:37 +0200 Subject: [PATCH 2523/3781] Revert "vaapivideomemory: load VA Image when mapping to write" This reverts commit c67edea4aba35f16d9e97c78a0b49ad1b590b112. --- gst/vaapi/gstvaapivideomemory.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 813b41502b..3b2b4d8264 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -208,10 +208,8 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, if (!ensure_image (mem)) goto error_ensure_image; - /* Load VA image from surface only on read OR write, not both. - * Refer to bugs #704078 and #704083 */ - if (((flags & GST_MAP_READWRITE) != GST_MAP_READWRITE) - && !ensure_image_is_current (mem)) + // Load VA image from surface + if ((flags & GST_MAP_READ) && !ensure_image_is_current (mem)) goto error_no_current_image; if (!gst_vaapi_image_map (mem->image)) From c18a6c97e156809426cec19aa0f21622ec1aa992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 14 Sep 2016 11:31:39 +0200 Subject: [PATCH 2524/3781] configure: Depend on gstreamer 1.9.2.1 --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index d2eceebd93..3aa225e409 100644 --- a/configure.ac +++ b/configure.ac @@ -24,9 +24,9 @@ m4_define([gst_vaapi_lt_age], [902]) m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.9.2]) -m4_define([gst_plugins_base_version], [1.9.2]) -m4_define([gst_plugins_bad_version], [1.9.2]) +m4_define([gst_version], [1.9.2.1]) +m4_define([gst_plugins_base_version], [1.9.2.1]) +m4_define([gst_plugins_bad_version], [1.9.2.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) From 99d404f1df588e7eb0fd3dced4cf19cec93a2120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 14 Sep 2016 16:29:01 +0200 Subject: [PATCH 2525/3781] vaapidecode: reset decoder hard when set_format() set_format() is called by upstream when the stream capabilites has changed. Before, if the new stream is compatible with the old one the VA decoder was not destroyed. Nonetheless, with this behavoir, the VA decoder ignores when the upstreamer parsers gets more details of the stream, such as the framerate. Hence, when the src caps are negotiates, the further sink caps updates are ignored. This patch forces the VA decoder destroying and recreation when set_format() is called. https://bugzilla.gnome.org/show_bug.cgi?id=770921 --- gst/vaapi/gstvaapidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ed24c95ed5..47c08197b6 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1057,7 +1057,7 @@ gst_vaapidecode_set_format (GstVideoDecoder * vdec, GstVideoCodecState * state) return FALSE; if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) return FALSE; - if (!gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, FALSE)) + if (!gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, TRUE)) return FALSE; return TRUE; From 9afa0ce47169cc91aa212dcf7db375a64244c0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 14 Sep 2016 18:42:09 +0200 Subject: [PATCH 2526/3781] vaapidecode: codec_data minimal size is 7 When the format of a H.264 stream is AVC3, the SPS and PPS are inside the stream, not in the codec_data, so the size of codec_data might be 7. This patch reduces the minimal size of the codec_data buffer from 8 to 7. https://bugzilla.gnome.org/show_bug.cgi?id=771441 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 3df0df958c..e8651a146d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4233,7 +4233,7 @@ gst_vaapi_decoder_h264_decode_codec_data (GstVaapiDecoder * base_decoder, unit.parsed_info = NULL; - if (buf_size < 8) + if (buf_size < 7) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; if (buf[0] != 1) { From 44a90c196ddce97519d99311983ac04631e43d58 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 21 Sep 2016 09:52:21 +0300 Subject: [PATCH 2527/3781] encoder: vp9: Fix refresh frame flag setting While doing the mode-1 referece picture selection, the circular buffer logic was not correctly setting the refresh frame flags as per VP9 spec. Make sure refresh_flag[0] get updated correclty after each cycle of GST_VP9_REF_FRAMES. https://bugzilla.gnome.org/show_bug.cgi?id=771507 --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 6006f682db..0069648ce6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -228,7 +228,7 @@ get_ref_indices (guint ref_pic_mode, guint ref_list_idx, guint * last_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); + *refresh_frame_flags = 1 << ((*last_idx + 1) % GST_VP9_REF_FRAMES); } GST_LOG From 0fae277d34cd2db89c9c7be45f41684f1040052f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 21 Sep 2016 09:55:53 +0300 Subject: [PATCH 2528/3781] encoder: vp8: Increase the allocation size for coded buffer We are not getting enough compression for some streams and encoded frame end up with more size than allocated. Assuming a compression ratio of 4, which should be good enough for holding the frames. https://bugzilla.gnome.org/show_bug.cgi?id=771528 --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index c23bd257b9..af54d9195c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -163,8 +163,9 @@ set_context_info (GstVaapiEncoder * base_encoder) 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) * 3 / 2; + GST_ROUND_UP_16 (vip->height) * 12 / 4; base_encoder->codedbuf_size += MAX_FRAME_TAG_SIZE + MAX_UPDATE_SEGMENTATION_SIZE + From f974c91d73b669e90cfaeed095c8e6f7dbee9103 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 22 Sep 2016 16:33:06 +0900 Subject: [PATCH 2529/3781] libs: vaapitexturemap: implement GstVaapiTextureMap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement GstVaapiTextureMap object, which caches VAAPI textures, so them can be reused. Internally it is a hash table. Note that it is GstObject based rather than GstVaapiObject, as part of the future converstion to GstObject of most of the code. https://bugzilla.gnome.org/show_bug.cgi?id=769293 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapitexturemap.c | 163 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapitexturemap.h | 58 +++++++++ 3 files changed, 223 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapitexturemap.c create mode 100644 gst-libs/gst/vaapi/gstvaapitexturemap.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index fc97c9441d..43a7772ab1 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -73,6 +73,7 @@ libgstvaapi_source_c = \ gstvaapisurfacepool.c \ gstvaapisurfaceproxy.c \ gstvaapitexture.c \ + gstvaapitexturemap.c \ gstvaapiutils.c \ gstvaapiutils_core.c \ gstvaapiutils_h264.c \ @@ -105,6 +106,7 @@ libgstvaapi_source_h = \ gstvaapisurfacepool.h \ gstvaapisurfaceproxy.h \ gstvaapitexture.h \ + gstvaapitexturemap.h \ gstvaapitypes.h \ gstvaapiutils_h264.h \ gstvaapiutils_h265.h \ diff --git a/gst-libs/gst/vaapi/gstvaapitexturemap.c b/gst-libs/gst/vaapi/gstvaapitexturemap.c new file mode 100644 index 0000000000..cb832dad78 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapitexturemap.c @@ -0,0 +1,163 @@ +/* + * gstvaapitexture.c - VA texture Hash map + * + * Copyright (C) 2016 Intel Corporation + * Copyright (C) 2016 Igalia S.L. + * + * 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:gstvaapitexturemap + * @short_description: VA/GLX/EGL texture hash map abstraction + */ + +#include "gstvaapitexturemap.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +/** + * GstVaapiTextureMap: + * + * Base class for API-dependent texture map. + */ +struct _GstVaapiTextureMap { + GstObject parent_instance; + + /*< private >*/ + GHashTable *texture_map; +}; + +/** + * GstVaapiTextureMapClass: + * + * Base class for API-dependent texture map. + */ +struct _GstVaapiTextureMapClass { + GstObjectClass parent_class; +}; + +#define MAX_NUM_TEXTURE 10 + +G_DEFINE_TYPE (GstVaapiTextureMap, gst_vaapi_texture_map, GST_TYPE_OBJECT); + +static void +gst_vaapi_texture_map_init (GstVaapiTextureMap * map) +{ + map->texture_map = + g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, + (GDestroyNotify) gst_vaapi_texture_unref); +} + +static void +gst_vaapi_texture_map_finalize (GObject * object) +{ + GstVaapiTextureMap *map = GST_VAAPI_TEXTURE_MAP (object); + + if (map->texture_map) { + g_hash_table_remove_all (map->texture_map); + g_hash_table_destroy (map->texture_map); + } + + G_OBJECT_CLASS (gst_vaapi_texture_map_parent_class)->finalize (object); +} + +static void +gst_vaapi_texture_map_class_init (GstVaapiTextureMapClass * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gst_vaapi_texture_map_finalize; +} + +/** + * gst_vaapi_texture_map_new: + * + * Creates a texture hash map. + * + * Return value: the newly created #GstVaapiTextureMap object + */ +GstVaapiTextureMap * +gst_vaapi_texture_map_new (void) +{ + GstVaapiTextureMap *map; + + map = g_object_new (GST_TYPE_VAAPI_TEXTURE_MAP, NULL); + return map; +} + +/** + * gst_vaapi_texture_map_add: + * @map: a #GstVaapiTextureMap instance + * @texture: a #GstVaapiTexture instance to add + * @id: the id of the GLTexture + * + * Adds @texture into the @map table. + * + * Returns: %TRUE if @texture was inserted correctly. + **/ +gboolean +gst_vaapi_texture_map_add (GstVaapiTextureMap * map, GstVaapiTexture * texture, + guint id) +{ + g_return_val_if_fail (map != NULL, FALSE); + g_return_val_if_fail (map->texture_map != NULL, FALSE); + g_return_val_if_fail (texture != NULL, FALSE); + + if (g_hash_table_size (map->texture_map) > MAX_NUM_TEXTURE) { + GST_WARNING ("Texture map is full"); + return FALSE; + } + + g_hash_table_insert (map->texture_map, GUINT_TO_POINTER (id), texture); + + return TRUE; +} + +/** + * gst_vaapi_texture_map_lookup: + * @map: a #GstVaapiTextureMap instance + * @id: the id of the GLTexture + * + * Search for the #GstVaapiTexture associated with the GLTexture @id + * in the @map. + * + * Returns: a pointer to #GstVaapiTexture if found; otherwise %NULL. + **/ +GstVaapiTexture * +gst_vaapi_texture_map_lookup (GstVaapiTextureMap * map, guint id) +{ + g_return_val_if_fail (map != NULL, NULL); + g_return_val_if_fail (map->texture_map != NULL, NULL); + + return g_hash_table_lookup (map->texture_map, GUINT_TO_POINTER (id)); +} + +/** + * gst_vaapi_texture_map_reset: + * @map: a #GstVaapiTextureMap instance + * + * Removes all the #GstVaapiTexture in the @map. + **/ +void +gst_vaapi_texture_map_reset (GstVaapiTextureMap * map) +{ + g_return_if_fail (map != NULL); + g_return_if_fail (map->texture_map != NULL); + + g_hash_table_remove_all (map->texture_map); +} diff --git a/gst-libs/gst/vaapi/gstvaapitexturemap.h b/gst-libs/gst/vaapi/gstvaapitexturemap.h new file mode 100644 index 0000000000..e74fedf8f5 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapitexturemap.h @@ -0,0 +1,58 @@ +/* + * gstvaapitexturemap.h - VA texture Hash map + * + * Copyright (C) 2016 Intel Corporation + * Copyright (C) 2016 Igalia S.L. + * + * 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_TEXTURE_MAP_H +#define GST_VAAPI_TEXTURE_MAP_H + +#include + +G_BEGIN_DECLS + +typedef struct _GstVaapiTextureMap GstVaapiTextureMap; +typedef struct _GstVaapiTextureMapClass GstVaapiTextureMapClass; + +#define GST_TYPE_VAAPI_TEXTURE_MAP \ + (gst_vaapi_texture_map_get_type ()) +#define GST_VAAPI_TEXTURE_MAP(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_TEXTURE_MAP, GstVaapiTextureMap)) + +GstVaapiTextureMap * +gst_vaapi_texture_map_new (void); + +gboolean +gst_vaapi_texture_map_add (GstVaapiTextureMap * map, + GstVaapiTexture * texture, + guint id); + +GstVaapiTexture * +gst_vaapi_texture_map_lookup (GstVaapiTextureMap * map, + guint id); + +void +gst_vaapi_texture_map_reset (GstVaapiTextureMap * map); + +GType +gst_vaapi_texture_map_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GST_VAAPI_TEXTURE_MAP_H */ From a80e10ac5c85107592da3ce327d7739415cc9cb7 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 22 Sep 2016 16:34:38 +0900 Subject: [PATCH 2530/3781] libs: display{egl,glx}: cache GstVaapiTextures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit instances when created and reuse This patch improves performance when glimagesink uploads a GL texture. It caches the GStVaapiTexture instances in GstVaapiDisplay{GLX,EGL}, using an instance of GstVaapiTextureMap, so our internal texture structure can be found by matching the GL texture id for each frame upload process, avoiding the internal texture structure creation and its following destruction. https://bugzilla.gnome.org/show_bug.cgi?id=769293 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapidisplay.c | 26 ++++++++++ gst-libs/gst/vaapi/gstvaapidisplay.h | 3 ++ gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 48 +++++++++++++++++-- gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h | 3 ++ gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 46 ++++++++++++++++-- gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 3 ++ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 4 ++ gst/vaapi/gstvaapivideometa_texture.c | 24 ++++++---- 8 files changed, 142 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index a733423dbe..32738a116e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -32,6 +32,7 @@ #include "gstvaapiutils.h" #include "gstvaapivalue.h" #include "gstvaapidisplay.h" +#include "gstvaapitexturemap.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiworkarounds.h" #include "gstvaapiversion.h" @@ -2149,3 +2150,28 @@ gst_vaapi_display_has_opengl (GstVaapiDisplay * display) return (klass->display_type == GST_VAAPI_DISPLAY_TYPE_GLX || klass->display_type == GST_VAAPI_DISPLAY_TYPE_EGL); } + +/** + * gst_vaapi_display_reset_texture_map: + * @display: a #GstVaapiDisplay + * + * Reset the internal #GstVaapiTextureMap if available. + * + * This function is thread safe. + */ +void +gst_vaapi_display_reset_texture_map (GstVaapiDisplay * display) +{ + GstVaapiDisplayClass *klass; + GstVaapiTextureMap *map; + + g_return_if_fail (display != NULL); + + if (!gst_vaapi_display_has_opengl (display)) + return; + klass = GST_VAAPI_DISPLAY_GET_CLASS (display); + if (!klass->get_texture_map) + return; + if ((map = klass->get_texture_map (display))) + gst_vaapi_texture_map_reset (map); +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index f4cc8653d9..600f276eca 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -257,6 +257,9 @@ 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); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index feab6408fb..f049de98ca 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -232,14 +232,49 @@ gst_vaapi_display_egl_create_window (GstVaapiDisplay * display, GstVaapiID id, 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) { - if (id != GST_VAAPI_ID_INVALID) - return gst_vaapi_texture_egl_new_wrapped (display, id, target, format, - width, height); - return gst_vaapi_texture_egl_new (display, target, format, width, 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 (GstVaapiDisplay * display) +{ + GstVaapiDisplayEGL *dpy = GST_VAAPI_DISPLAY_EGL (display); + + if (dpy->texture_map) + gst_object_unref (dpy->texture_map); + GST_VAAPI_DISPLAY_EGL_GET_CLASS (display)->parent_finalize (display); } static void @@ -254,6 +289,10 @@ gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass) gst_vaapi_display_class_init (dpy_class); + /* chain up destructor */ + klass->parent_finalize = object_class->finalize; + object_class->finalize = (GDestroyNotify) gst_vaapi_display_egl_finalize; + object_class->size = sizeof (GstVaapiDisplayEGL); dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_EGL; dpy_class->bind_display = (GstVaapiDisplayBindFunc) @@ -280,6 +319,7 @@ gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass) gst_vaapi_display_egl_create_window; dpy_class->create_texture = (GstVaapiDisplayCreateTextureFunc) gst_vaapi_display_egl_create_texture; + dpy_class->get_texture_map = gst_vaapi_display_egl_get_texture_map; } static inline const GstVaapiDisplayClass * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h index 3db5ad8980..96e2b43b85 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h @@ -24,6 +24,7 @@ #define GST_VAAPI_DISPLAY_EGL_PRIV_H #include +#include #include "gstvaapidisplay_egl.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiutils_egl.h" @@ -79,6 +80,7 @@ struct _GstVaapiDisplayEGL EglDisplay *egl_display; EglContext *egl_context; guint gles_version; + GstVaapiTextureMap *texture_map; }; /** @@ -90,6 +92,7 @@ struct _GstVaapiDisplayEGLClass { /*< private >*/ GstVaapiDisplayClass parent_class; + GDestroyNotify parent_finalize; }; G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 32aa714113..9b4a007cbc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -50,13 +50,48 @@ gst_vaapi_display_glx_create_window (GstVaapiDisplay * display, GstVaapiID 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) { - return id != GST_VAAPI_ID_INVALID ? - gst_vaapi_texture_glx_new_wrapped (display, id, target, format) : - gst_vaapi_texture_glx_new (display, target, format, width, 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 (GstVaapiDisplay * display) +{ + GstVaapiDisplayGLX *dpy = GST_VAAPI_DISPLAY_GLX (display); + + if (dpy->texture_map) + gst_object_unref (dpy->texture_map); + GST_VAAPI_DISPLAY_GLX_GET_CLASS (display)->parent_finalize (display); } static void @@ -68,10 +103,15 @@ gst_vaapi_display_glx_class_init (GstVaapiDisplayGLXClass * klass) gst_vaapi_display_x11_class_init (&klass->parent_class); + /* chain up destructor */ + klass->parent_finalize = object_class->finalize; + object_class->finalize = (GDestroyNotify) gst_vaapi_display_glx_finalize; + object_class->size = sizeof (GstVaapiDisplayGLX); 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; } static inline const GstVaapiDisplayClass * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index 63f7175ce7..4da88228a6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -25,6 +25,7 @@ #include #include +#include #include "gstvaapidisplay_x11_priv.h" G_BEGIN_DECLS @@ -53,6 +54,7 @@ struct _GstVaapiDisplayGLX { /*< private >*/ GstVaapiDisplayX11 parent_instance; + GstVaapiTextureMap *texture_map; }; /** @@ -64,6 +66,7 @@ struct _GstVaapiDisplayGLXClass { /*< private >*/ GstVaapiDisplayX11Class parent_class; + GDestroyNotify parent_finalize; }; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index fd50fe79e2..12b5184bfe 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -29,6 +29,7 @@ #include #include #include +#include #include "gstvaapiminiobject.h" G_BEGIN_DECLS @@ -73,6 +74,8 @@ typedef GstVaapiWindow *(*GstVaapiDisplayCreateWindowFunc) ( typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) ( GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height); +typedef GstVaapiTextureMap *(*GstVaapiDisplayGetTextureMapFunc) ( + GstVaapiDisplay * display); typedef guintptr (*GstVaapiDisplayGetVisualIdFunc) (GstVaapiDisplay * display, GstVaapiWindow * window); @@ -226,6 +229,7 @@ struct _GstVaapiDisplayClass GstVaapiDisplayGetColormapFunc get_colormap; GstVaapiDisplayCreateWindowFunc create_window; GstVaapiDisplayCreateTextureFunc create_texture; + GstVaapiDisplayGetTextureMapFunc get_texture_map; }; /* Initialization types */ diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 01e33852fd..fb1535a760 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -176,26 +176,34 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, gst_vaapi_video_meta_get_surface_proxy (vmeta); GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface); + GstVaapiTexture *texture = NULL; if (!gst_vaapi_display_has_opengl (dpy)) return FALSE; - if (!meta_texture->texture || + if (meta_texture->texture /* Check whether VA display changed */ - GST_VAAPI_OBJECT_DISPLAY (meta_texture->texture) != dpy || + && GST_VAAPI_OBJECT_DISPLAY (meta_texture->texture) == dpy /* Check whether texture id changed */ - gst_vaapi_texture_get_id (meta_texture->texture) != texture_id[0]) { + && (gst_vaapi_texture_get_id (meta_texture->texture) == texture_id[0])) { + texture = meta_texture->texture; + } + + if (!texture) { /* FIXME: should we assume target? */ - GstVaapiTexture *const texture = + texture = gst_vaapi_texture_new_wrapped (dpy, texture_id[0], GL_TEXTURE_2D, meta_texture->gl_format, meta_texture->width, meta_texture->height); - gst_vaapi_texture_replace (&meta_texture->texture, texture); - if (!texture) - return FALSE; - gst_vaapi_texture_unref (texture); } + if (meta_texture->texture != texture) { + gst_vaapi_texture_replace (&meta_texture->texture, texture); + } + + if (!texture) + return FALSE; + gst_vaapi_texture_set_orientation_flags (meta_texture->texture, get_texture_orientation_flags (meta->texture_orientation)); From 5a4540e6540e78be2ca4d491543c92b47dc91d06 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 22 Sep 2016 16:34:48 +0900 Subject: [PATCH 2531/3781] plugins: reset textures at negotiation/shutdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When caps reconfiguration is called, the new downstream frame size might be different. Thus, if the downstream caps change,the display's texture map is reset. In addition, during pipeline shutdown, textures in texture map have to be released, since each one have a reference to the GstVaapiDisplay object, which is a dangerous circular reference. https://bugzilla.gnome.org/show_bug.cgi?id=769293 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapipluginbase.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 7849161bcb..a1f3d3b0ea 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -206,6 +206,13 @@ error_create_proxy: } } +static void +plugin_reset_texture_map (GstVaapiPluginBase * plugin) +{ + if (plugin->display) + gst_vaapi_display_reset_texture_map (plugin->display); +} + static void gst_vaapi_plugin_base_find_gl_context (GstVaapiPluginBase * plugin) { @@ -278,6 +285,9 @@ gst_vaapi_plugin_base_open (GstVaapiPluginBase * plugin) void gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) { + /* Release vaapi textures first if exist, which refs display object */ + plugin_reset_texture_map (plugin); + gst_vaapi_display_replace (&plugin->display, NULL); gst_object_replace (&plugin->gl_context, NULL); @@ -704,6 +714,7 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, if (outcaps && outcaps != plugin->srcpad_caps) { g_clear_object (&plugin->srcpad_allocator); gst_caps_replace (&plugin->srcpad_caps, outcaps); + plugin_reset_texture_map (plugin); if (!gst_video_info_from_caps (&plugin->srcpad_info, outcaps)) return FALSE; } From 57313f3f7001de6177dfc05c5517c2d2d54af311 Mon Sep 17 00:00:00 2001 From: Vineeth TM Date: Fri, 4 Mar 2016 16:35:11 +0900 Subject: [PATCH 2532/3781] vaapi: use new gst_element_class_add_static_pad_template() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugzilla.gnome.org/show_bug.cgi?id=763083 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapidecode.c | 4 ++-- gst/vaapi/gstvaapidecodebin.c | 8 ++++---- gst/vaapi/gstvaapiencode_h264.c | 8 ++++---- gst/vaapi/gstvaapiencode_h265.c | 8 ++++---- gst/vaapi/gstvaapiencode_jpeg.c | 8 ++++---- gst/vaapi/gstvaapiencode_mpeg2.c | 8 ++++---- gst/vaapi/gstvaapiencode_vp8.c | 8 ++++---- gst/vaapi/gstvaapipostproc.c | 9 ++++----- gst/vaapi/gstvaapisink.c | 5 ++--- 9 files changed, 32 insertions(+), 34 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 47c08197b6..c014374306 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1350,8 +1350,8 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) gst_element_class_add_pad_template (element_class, pad_template); /* src pad */ - pad_template = gst_static_pad_template_get (&gst_vaapidecode_src_factory); - gst_element_class_add_pad_template (element_class, pad_template); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapidecode_src_factory); } static void diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 1b1aead9cb..0e3b713c26 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -264,11 +264,11 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) g_object_class_install_properties (gobject_class, PROP_LAST, properties); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapi_decode_bin_sink_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapi_decode_bin_sink_factory); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapi_decode_bin_src_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapi_decode_bin_src_factory); GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_decode_bin, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index ba7a1e5287..d07f4ffecc 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -405,12 +405,12 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) GST_PLUGIN_DESC, "Wind Yuan "); /* sink pad */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_h264_sink_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_h264_sink_factory); /* src pad */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_h264_src_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_h264_src_factory); gst_vaapiencode_class_init_properties (encode_class); } diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index f48adbf400..49115754fe 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -405,12 +405,12 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass) "Sreerenj Balachandran "); /* sink pad */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_h265_sink_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_h265_sink_factory); /* src pad */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_h265_src_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_h265_src_factory); gst_vaapiencode_class_init_properties (encode_class); } diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 58c057ae01..4e6bbcf668 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -166,12 +166,12 @@ gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass) "Sreerenj Balachandran "); /* sink pad */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_jpeg_sink_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_jpeg_sink_factory); /* src pad */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_jpeg_src_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_jpeg_src_factory); gst_vaapiencode_class_init_properties (encode_class); } diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index c060061fa0..4864c90fa7 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -169,12 +169,12 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) GST_PLUGIN_DESC, "Guangxin Xu "); /* sink pad */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_mpeg2_sink_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_mpeg2_sink_factory); /* src pad */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_mpeg2_src_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_mpeg2_src_factory); gst_vaapiencode_class_init_properties (encode_class); } diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index cc9beb36a9..54e63b4b21 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -166,12 +166,12 @@ gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass) "Sreerenj Balachandran "); /* sink pad */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_vp8_sink_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_vp8_sink_factory); /* src pad */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_vp8_src_factory)); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_vp8_src_factory); gst_vaapiencode_class_init_properties (encode_class); } diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 15c7275e50..41f36fd6ae 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1527,7 +1527,6 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstBaseTransformClass *const trans_class = GST_BASE_TRANSFORM_CLASS (klass); - GstPadTemplate *pad_template; GPtrArray *filter_ops; GstVaapiFilterOpInfo *filter_op; @@ -1560,12 +1559,12 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) GST_PLUGIN_DESC, "Gwenole Beauchesne "); /* sink pad */ - pad_template = gst_static_pad_template_get (&gst_vaapipostproc_sink_factory); - gst_element_class_add_pad_template (element_class, pad_template); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapipostproc_sink_factory); /* src pad */ - pad_template = gst_static_pad_template_get (&gst_vaapipostproc_src_factory); - gst_element_class_add_pad_template (element_class, pad_template); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapipostproc_src_factory); /** * GstVaapiPostproc:deinterlace-mode: diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index cd19bc5abd..1af1aa2956 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1703,7 +1703,6 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) GstVideoSinkClass *const videosink_class = GST_VIDEO_SINK_CLASS (klass); GstVaapiPluginBaseClass *const base_plugin_class = GST_VAAPI_PLUGIN_BASE_CLASS (klass); - GstPadTemplate *pad_template; GST_DEBUG_CATEGORY_INIT (gst_debug_vaapisink, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); @@ -1734,8 +1733,8 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) "VA-API sink", "Sink/Video", GST_PLUGIN_DESC, "Gwenole Beauchesne "); - pad_template = gst_static_pad_template_get (&gst_vaapisink_sink_factory); - gst_element_class_add_pad_template (element_class, pad_template); + gst_element_class_add_static_pad_template (element_class, + &gst_vaapisink_sink_factory); /** * GstVaapiSink:display: From 80036bd63cb7193004fc9807e363f69610840636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 30 Sep 2016 13:05:20 +0300 Subject: [PATCH 2533/3781] Release 1.9.90 --- ChangeLog | 216 ++++++++++++++++++++++++++++++++++++++++++- NEWS | 2 +- common | 2 +- configure.ac | 14 +-- gstreamer-vaapi.doap | 9 ++ 5 files changed, 231 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index a5a8ac422c..4ca899b898 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,219 @@ -=== release 1.9.2 === +=== release 1.9.90 === -2016-09-01 Sebastian Dröge +2016-09-30 Sebastian Dröge * configure.ac: - releasing 1.9.2 + releasing 1.9.90 + +2016-03-04 16:35:11 +0900 Vineeth TM + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + vaapi: use new gst_element_class_add_static_pad_template() + https://bugzilla.gnome.org/show_bug.cgi?id=763083 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-09-22 16:34:48 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipluginbase.c: + plugins: reset textures at negotiation/shutdown + When caps reconfiguration is called, the new downstream frame size might be + different. Thus, if the downstream caps change,the display's texture map is + reset. + In addition, during pipeline shutdown, textures in texture map have to be + released, since each one have a reference to the GstVaapiDisplay object, which + is a dangerous circular reference. + https://bugzilla.gnome.org/show_bug.cgi?id=769293 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-09-22 16:34:38 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst/vaapi/gstvaapivideometa_texture.c: + libs: display{egl,glx}: cache GstVaapiTextures + instances when created and reuse + This patch improves performance when glimagesink uploads a GL texture. + It caches the GStVaapiTexture instances in GstVaapiDisplay{GLX,EGL}, using an + instance of GstVaapiTextureMap, so our internal texture structure can be found + by matching the GL texture id for each frame upload process, avoiding the + internal texture structure creation and its following destruction. + https://bugzilla.gnome.org/show_bug.cgi?id=769293 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-09-22 16:33:06 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapitexturemap.c: + * gst-libs/gst/vaapi/gstvaapitexturemap.h: + libs: vaapitexturemap: implement GstVaapiTextureMap + Implement GstVaapiTextureMap object, which caches VAAPI textures, so them can be + reused. Internally it is a hash table. + Note that it is GstObject based rather than GstVaapiObject, as part of the future + converstion to GstObject of most of the code. + https://bugzilla.gnome.org/show_bug.cgi?id=769293 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-09-21 09:55:53 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + encoder: vp8: Increase the allocation size for coded buffer + We are not getting enough compression for some streams and + encoded frame end up with more size than allocated. + Assuming a compression ratio of 4, which should be good enough + for holding the frames. + https://bugzilla.gnome.org/show_bug.cgi?id=771528 + +2016-09-21 09:52:21 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + encoder: vp9: Fix refresh frame flag setting + While doing the mode-1 referece picture selection, + the circular buffer logic was not correctly setting the + refresh frame flags as per VP9 spec. + Make sure refresh_flag[0] get updated correclty after + each cycle of GST_VP9_REF_FRAMES. + https://bugzilla.gnome.org/show_bug.cgi?id=771507 + +2016-09-14 18:42:09 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + vaapidecode: codec_data minimal size is 7 + When the format of a H.264 stream is AVC3, the SPS and PPS are inside the + stream, not in the codec_data, so the size of codec_data might be 7. + This patch reduces the minimal size of the codec_data buffer from 8 to 7. + https://bugzilla.gnome.org/show_bug.cgi?id=771441 + +2016-09-14 16:29:01 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: reset decoder hard when set_format() + set_format() is called by upstream when the stream capabilites has changed. + Before, if the new stream is compatible with the old one the VA decoder was + not destroyed. Nonetheless, with this behavoir, the VA decoder ignores + when the upstreamer parsers gets more details of the stream, such as the + framerate. Hence, when the src caps are negotiates, the further sink caps + updates are ignored. + This patch forces the VA decoder destroying and recreation when set_format() + is called. + https://bugzilla.gnome.org/show_bug.cgi?id=770921 + +2016-09-14 11:31:39 +0200 Sebastian Dröge + + * configure.ac: + configure: Depend on gstreamer 1.9.2.1 + +2016-09-09 12:03:37 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + Revert "vaapivideomemory: load VA Image when mapping to write" + This reverts commit c67edea4aba35f16d9e97c78a0b49ad1b590b112. + +2016-09-10 20:52:21 +1000 Jan Schmidt + + * common: + Automatic update of common submodule + From b18d820 to f980fd9 + +2016-09-10 09:58:25 +1000 Jan Schmidt + + * common: + Automatic update of common submodule + From f49c55e to b18d820 + +2016-09-08 16:16:09 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipluginbase.c: + plugins: set allocator's image size to sinkpad bufferpool + Otherwise the buffer is always ditched by the bufferpool, losing performance. + https://bugzilla.gnome.org/show_bug.cgi?id=771035 + +2016-09-07 17:34:08 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface.c: + libs: surface: ensure composite overlay is not bigger + Ensure the composition overlay rectangle (subtitles) is not bigger than + the surface where it is going to be composited and rendered. + https://bugzilla.gnome.org/show_bug.cgi?id=766978 + +2016-09-07 17:51:23 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: load VA Image when mapping to write + When calling gst_video_frame_map() with GST_MAP_WRITE flag, it doesn't call + ensure_image_is_current(), which means it doesn't guarentee VAImage is valid + in this case. + https://bugzilla.gnome.org/show_bug.cgi?id=766978 + +2016-09-06 12:27:45 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: merge vc1 and wmv3 elements + This patch merges vaapivc1dec and vaapiwmv3dec into a single + vaapivc1dec. Also, removed the WMVA format, since it is not + supported by libva. + https://bugzilla.gnome.org/show_bug.cgi?id=734093 + +2016-09-06 11:19:05 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: vc1: fails only on advanced profile + In commit 2eb4394 the frame coding mode was verified for progressive + regardless the profile. But the FCM is only valid in the advanced + profile. This patch checks for the advanced profile before verifying FCM for + progressive. + https://bugzilla.gnome.org/show_bug.cgi?id=769250 + +2016-09-01 12:39:15 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + vaapi: DISPLAY envvar as dependency + In a multiple video cards system, a X11 environment may have different VA + capabilities. This patch tracks the DISPLAY environment variable to + invalidates the GStreamer features cache. Also tracks WAYLAND_DISPLAY. + https://bugzilla.gnome.org/show_bug.cgi?id=770357 + +2016-08-26 14:55:17 -0700 Scott D Phillips + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + decoder: vc1: Fail only on actual interlaced frames + In the earlier patch: + f31d9f3 decoder: vc1: Print error on interlaced content + Decoding would error out if the interlace flag was set in the + sequence bdu. This isn't quite right because a video can have this + flag set and yet not have any interlaced pictures. + Here instead we error out when either parsing a field bdu or + decoding a frame bdu which has fcm set to anything other than + progressive. + Signed-off-by: Scott D Phillips + https://bugzilla.gnome.org/show_bug.cgi?id=769250 + +2016-09-01 12:34:48 +0300 Sebastian Dröge + + * configure.ac: + Back to development + +=== release 1.9.2 === + +2016-09-01 12:34:38 +0300 Sebastian Dröge + + * ChangeLog: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + Release 1.9.2 2016-08-16 11:58:38 +0300 Scott D Phillips diff --git a/NEWS b/NEWS index 027c01804e..072b2dfb35 100644 --- a/NEWS +++ b/NEWS @@ -1 +1 @@ -This is GStreamer 1.9.2 +This is GStreamer 1.9.90 diff --git a/common b/common index f980fd91c1..f49c55ecd3 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit f980fd91c1c1fd01333966041a4a535366e897bd +Subproject commit f49c55ecd35a7436194d28297f6d6f20eb6a66fa diff --git a/configure.ac b/configure.ac index 3aa225e409..6a4a913dbe 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [9]) -m4_define([gst_vaapi_micro_version], [2]) -m4_define([gst_vaapi_nano_version], [1]) +m4_define([gst_vaapi_micro_version], [90]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [902]) +m4_define([gst_vaapi_lt_current], [990]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [902]) +m4_define([gst_vaapi_lt_age], [990]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.9.2.1]) -m4_define([gst_plugins_base_version], [1.9.2.1]) -m4_define([gst_plugins_bad_version], [1.9.2.1]) +m4_define([gst_version], [1.9.90]) +m4_define([gst_plugins_base_version], [1.9.90]) +m4_define([gst_plugins_bad_version], [1.9.90]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index db2212c967..5e85a510e7 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,15 @@ + + + 1.9.90 + master + 2016-09-30 + + + + 1.9.2 From 9414815383f3531f111aacb613e0e127dffbb97a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 27 Sep 2016 17:29:25 +0200 Subject: [PATCH 2534/3781] libs: display: egl: remove unused header include The header gmodule.h is not used since the library dynamic loading for EGL display was removed. https://bugzilla.gnome.org/show_bug.cgi?id=772599 --- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index f049de98ca..99783ea145 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -21,7 +21,6 @@ */ #include "sysdeps.h" -#include #include "gstvaapidisplay_egl.h" #include "gstvaapidisplay_egl_priv.h" #include "gstvaapiwindow.h" From 60ada3e76beb3e13b86ca8ee92cb8ac547d7919c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 18 Oct 2016 17:02:59 +0200 Subject: [PATCH 2535/3781] docs: update README --- README | 52 +++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/README b/README index 69c63ae015..9c2d9cfb53 100644 --- a/README +++ b/README @@ -20,16 +20,17 @@ Overview gstreamer-vaapi consists in a collection of VA-API based plugins for GStreamer and helper libraries. - * `vaapidecode' is used to decode JPEG, MPEG-2, MPEG-4:2, H.264 AVC, - H.264 MVC, VP8, VC-1, WMV3, HEVC videos to VA surfaces, depending - on the underlying hardware capabilities. This plugin is also able - to implicitly download the decoded surface to raw YUV buffers. + * `vaapidec' is used to decode JPEG, MPEG-2, MPEG-4:2, H.264 + AVC, H.264 MVC, VP8, VC-1, WMV3, HEVC videos to VA surfaces, + depending on the actual value of and the underlying + hardware capabilities. This plugin is also able to implicitly + download the decoded surface to raw YUV buffers. - * `vaapiencode_' is used to encode into MPEG-2, H.264 AVC, - H.264 MVC, JPEG, VP8, HEVC videos, depending on the actual value - of (mpeg2, h264, etc.). By default, raw format bitstreams - are generated, so the result may be piped to a muxer. - e.g. qtmux for MP4 containers. + * `vaapienc' is used to encode into MPEG-2, H.264 AVC, H.264 + MVC, JPEG, VP8, HEVC videos, depending on the actual value of + (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 @@ -45,18 +46,20 @@ Features -------- * VA-API support from 0.29 to 0.38 - * JPEG, MPEG-2, MPEG-4, H.264 AVC, H.264 MVC, VP8, VC-1, HEVC and VP9 ad-hoc decoders + * 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 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 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 + - Image enhancement filters: Sharpening, Noise Reductio, Color + Balance, Skin-Tone-Enhancement - Advanced deinterlacing: Motion-Adaptive, Motion-Compensated @@ -65,11 +68,10 @@ Requirements Software requirements - * GStreamer 1.4.x (up to including GStreamer 1.6): - libglib2.0-dev (>= 2.32) - libgstreamer1.0-dev (>= 1.4.0) - libgstreamer-plugins-base1.0-dev (>= 1.4.0) - libgstreamer-plugins-bad1.0-dev (>= 1.4.0) + * GStreamer 1.9.x: + libgstreamer1.0-dev (>= 1.9.x) + libgstreamer-plugins-base1.0-dev (>= 1.9.x) + libgstreamer-plugins-bad1.0-dev (>= 1.9.0) * Renderers: DRM: libva-dev (>= 1.1.0), libdrm-dev, libudev-dev @@ -79,13 +81,13 @@ Software requirements Hardware requirements - * AMD platforms with UVD2 (XvBA supported) * Intel Eaglelake (G45) - * Intel Ironlake, Sandybridge, Ivybridge, Haswell and Broadwell (HD Graphics) + * Intel Ironlake, Sandybridge, Ivybridge, Haswell, Broadwell, + Skylake, etc. (HD Graphics) * Intel BayTrail, Braswell * Intel Poulsbo (US15W) * Intel Medfield or Cedar Trail - * NVIDIA platforms with PureVideo (VDPAU supported) + * Hardware supported by Mesa VA gallium state-tracker Usage @@ -98,11 +100,11 @@ Usage * Play an H.264 video with an MP4 container in fullscreen mode $ gst-launch-1.0 -v filesrc location=/path/to/video.mp4 ! \ - qtdemux ! vaapidecode ! vaapisink fullscreen=true + qtdemux ! vaapidecodebin ! vaapisink fullscreen=true * Play a raw MPEG-2 interlaced stream $ gst-launch-1.0 -v filesrc location=/path/to/mpeg2.bits ! \ - mpegvideoparse ! vaapidecode ! vaapipostproc ! vaapisink + 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 ! \ @@ -112,7 +114,7 @@ Usage * 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 ! \ - vaapiencode_h264 rate-control=cbr tune=high-compression ! \ + vaapih264enc rate-control=cbr tune=high-compression ! \ qtmux ! filesink location=/path/to/encoded_video.mp4 @@ -126,7 +128,7 @@ Sources Git repository for work-in-progress changes is available at: - + Reporting Bugs From ef3ee8b7bbff58c59fae8e940739a2fca678e09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 8 Oct 2016 14:33:59 +0200 Subject: [PATCH 2536/3781] encoder: h264,h265: fix regression in offset count In commit dc35dafa a bug was introduced because I assumed that GST_CLOCK_TIME_NONE is zero when is -1. This patch fixes that mistake. https://bugzilla.gnome.org/show_bug.cgi?id=772259 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index cc219b9cf6..c5c1a2000c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2473,7 +2473,7 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->cts_offset = gst_util_uint64_scale (GST_SECOND, GST_VAAPI_ENCODER_FPS_D (encoder), GST_VAAPI_ENCODER_FPS_N (encoder)); else - encoder->cts_offset = GST_CLOCK_TIME_NONE; + encoder->cts_offset = 0; /* init max_frame_num, max_poc */ encoder->log2_max_frame_num = diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index b7fcc205a0..48629b6ad4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2034,7 +2034,7 @@ reset_properties (GstVaapiEncoderH265 * encoder) encoder->cts_offset = gst_util_uint64_scale (GST_SECOND, GST_VAAPI_ENCODER_FPS_D (encoder), GST_VAAPI_ENCODER_FPS_N (encoder)); else - encoder->cts_offset = GST_CLOCK_TIME_NONE; + encoder->cts_offset = 0; /* init max_poc */ encoder->log2_max_pic_order_cnt = From fb95a798183c2a962383ec60bc3c33fbd92c7f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 2 Sep 2016 16:42:45 +0200 Subject: [PATCH 2537/3781] build: clean up the dlopen usage --- configure.ac | 4 ++-- gst-libs/gst/vaapi/Makefile.am | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 6a4a913dbe..d76b585ca7 100644 --- a/configure.ac +++ b/configure.ac @@ -183,8 +183,8 @@ dnl *** checks for libraries *** dnl check for libm, for sin() etc. AC_CHECK_LIB([m], [tan]) -dnl Check to see if dlopen is in default libraries (like Solaris, which -dnl has it in libc), or if libdl is needed to get it. +dnl Check to see if dlopen/dlsym is in default libraries (like +dnl Solaris, which has it in libc), or if libdl is needed to get it. AC_CHECK_FUNC([dlopen], [], [ AC_CHECK_LIB([dl], [dlopen], [DLOPEN_LIBS="-ldl"])]) AC_SUBST([DLOPEN_LIBS]) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 43a7772ab1..f606bbb5c4 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -471,7 +471,6 @@ libgstvaapi_egl_la_LIBADD = \ $(GST_BASE_LIBS) \ $(GST_VIDEO_LIBS) \ $(EGL_LIBS) \ - $(DLOPEN_LIBS) \ $(NULL) libgstvaapi_egl_la_LDFLAGS = \ From 84f7a3ec516155314c07ad6c7d45954d2cfd33da Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:39:54 +0100 Subject: [PATCH 2538/3781] vaapivideomemory: add explanation about the call 'dup (dmabuf_fd)' In short GstFdMemory is configured to call close when using GstDmabufMemory. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapivideomemory.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 3b2b4d8264..7545149923 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -825,6 +825,9 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta) gst_vaapi_video_meta_set_surface_proxy (meta, proxy); gst_vaapi_surface_proxy_unref (proxy); + /* Need dup because GstDmabufMemory creates the GstFdMemory with flag + * GST_FD_MEMORY_FLAG_NONE. So when being freed it calls close on the fd + * because GST_FD_MEMORY_FLAG_DONT_CLOSE is not set. */ dmabuf_fd = gst_vaapi_buffer_proxy_get_handle (dmabuf_proxy); if (dmabuf_fd < 0 || (dmabuf_fd = dup (dmabuf_fd)) < 0) goto error_create_dmabuf_handle; From abc2480b10e9be723b89acb6b0b5235ef05e9f6f Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 7 Oct 2016 18:46:22 +0900 Subject: [PATCH 2539/3781] libs: minor correction for logical consistency GstVaapiDecode is a descendant of GstVaapiMiniObject, so, thought we should use its methods, even though it doesn't change functionality. GstVaapiPixmap, GstVaapiTexture and GstVaapiWindow are descendant of GstVaapiObject, hence its methods shall be used. https://bugzilla.gnome.org/show_bug.cgi?id=772554 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 3 ++- gst-libs/gst/vaapi/gstvaapipixmap_priv.h | 8 ++++---- gst-libs/gst/vaapi/gstvaapitexture_priv.h | 8 ++++---- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 8 ++++---- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 7de5276c0f..498cbc170c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -576,7 +576,8 @@ void gst_vaapi_decoder_replace (GstVaapiDecoder ** old_decoder_ptr, GstVaapiDecoder * new_decoder) { - gst_vaapi_object_replace (old_decoder_ptr, new_decoder); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_decoder_ptr, + GST_VAAPI_MINI_OBJECT (new_decoder)); } /** diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_priv.h b/gst-libs/gst/vaapi/gstvaapipixmap_priv.h index 9219bf6596..9dd6bc5133 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_priv.h +++ b/gst-libs/gst/vaapi/gstvaapipixmap_priv.h @@ -111,14 +111,14 @@ gst_vaapi_pixmap_new_from_native(const GstVaapiPixmapClass *pixmap_class, /* Inline reference counting for core libgstvaapi library */ #ifdef IN_LIBGSTVAAPI_CORE #define gst_vaapi_pixmap_ref_internal(pixmap) \ - ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pixmap))) + ((gpointer)gst_vaapi_object_ref(GST_VAAPI_OBJECT(pixmap))) #define gst_vaapi_pixmap_unref_internal(pixmap) \ - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pixmap)) + gst_vaapi_object_unref(GST_VAAPI_OBJECT(pixmap)) #define gst_vaapi_pixmap_replace_internal(old_pixmap_ptr, new_pixmap) \ - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pixmap_ptr), \ - GST_VAAPI_MINI_OBJECT(new_pixmap)) + gst_vaapi_object_replace((GstVaapiObject **)(old_pixmap_ptr), \ + GST_VAAPI_OBJECT(new_pixmap)) #undef gst_vaapi_pixmap_ref #define gst_vaapi_pixmap_ref(pixmap) \ diff --git a/gst-libs/gst/vaapi/gstvaapitexture_priv.h b/gst-libs/gst/vaapi/gstvaapitexture_priv.h index 782ae78309..86befe67cd 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_priv.h +++ b/gst-libs/gst/vaapi/gstvaapitexture_priv.h @@ -138,14 +138,14 @@ gst_vaapi_texture_new_internal (const GstVaapiTextureClass * klass, /* Inline reference counting for core libgstvaapi library */ #ifdef IN_LIBGSTVAAPI_CORE #define gst_vaapi_texture_ref_internal(texture) \ - ((gpointer)gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (texture))) + ((gpointer)gst_vaapi_object_ref (GST_VAAPI_OBJECT (texture))) #define gst_vaapi_texture_unref_internal(texture) \ - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (texture)) + gst_vaapi_object_unref (GST_VAAPI_OBJECT (texture)) #define gst_vaapi_texture_replace_internal(old_texture_ptr, new_texture) \ - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **)(old_texture_ptr), \ - GST_VAAPI_MINI_OBJECT (new_texture)) + gst_vaapi_object_replace ((GstVaapiObject **)(old_texture_ptr), \ + GST_VAAPI_OBJECT (new_texture)) #undef gst_vaapi_texture_ref #define gst_vaapi_texture_ref(texture) \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index 3d0a59639e..ea0e19a175 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -123,14 +123,14 @@ gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, /* Inline reference counting for core libgstvaapi library */ #ifdef IN_LIBGSTVAAPI_CORE #define gst_vaapi_window_ref_internal(window) \ - ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(window))) + ((gpointer)gst_vaapi_object_ref(GST_VAAPI_OBJECT(window))) #define gst_vaapi_window_unref_internal(window) \ - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(window)) + gst_vaapi_object_unref(GST_VAAPI_OBJECT(window)) #define gst_vaapi_window_replace_internal(old_window_ptr, new_window) \ - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_window_ptr), \ - GST_VAAPI_MINI_OBJECT(new_window)) + gst_vaapi_object_replace((GstVaapiObject **)(old_window_ptr), \ + GST_VAAPI_OBJECT(new_window)) #undef gst_vaapi_window_ref #define gst_vaapi_window_ref(window) \ From 4f4e0a8f36cbcd04054facb3e4cb2f698bb13c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Jul 2016 15:17:33 +0200 Subject: [PATCH 2540/3781] plugins: simplify code Merge two lines of variable declarations. https://bugzilla.gnome.org/show_bug.cgi?id=773497 --- gst/vaapi/gstvaapipluginbase.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index a1f3d3b0ea..aa3d814f82 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -791,9 +791,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GstCaps *caps = NULL; GstBufferPool *pool; GstVideoInfo vi; - guint size, min, max; + guint size, min, max, pool_options; gboolean update_pool = FALSE; - guint pool_options; #if (USE_GLX || USE_EGL) guint idx; #endif From 43dd4b7452137d996fb335deefd64f04d7d2092d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 2 Aug 2016 11:32:19 +0200 Subject: [PATCH 2541/3781] vaapiencode: h264, h265: rename codec name So encoder and decoders have the same codec name. https://bugzilla.gnome.org/show_bug.cgi?id=773497 --- gst/vaapi/gstvaapiencode_h264.c | 4 ++-- gst/vaapi/gstvaapiencode_h265.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index d07f4ffecc..44a857d805 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -44,7 +44,7 @@ #include "gstvaapivideomemory.h" #define GST_PLUGIN_NAME "vaapih264enc" -#define GST_PLUGIN_DESC "A VA-API based H.264 video encoder" +#define GST_PLUGIN_DESC "A VA-API based H264 video encoder" GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); #define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug @@ -400,7 +400,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) encode_class->alloc_buffer = gst_vaapiencode_h264_alloc_buffer; gst_element_class_set_static_metadata (element_class, - "VA-API H.264 encoder", + "VA-API H264 encoder", "Codec/Encoder/Video", GST_PLUGIN_DESC, "Wind Yuan "); diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 49115754fe..58219bd5bf 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -43,7 +43,7 @@ #include "gstvaapivideomemory.h" #define GST_PLUGIN_NAME "vaapih265enc" -#define GST_PLUGIN_DESC "A VA-API based H.265 video encoder" +#define GST_PLUGIN_DESC "A VA-API based H265 video encoder" GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h265_encode_debug); #define GST_CAT_DEFAULT gst_vaapi_h265_encode_debug @@ -399,7 +399,7 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass) encode_class->alloc_buffer = gst_vaapiencode_h265_alloc_buffer; gst_element_class_set_static_metadata (element_class, - "VA-API H.265 encoder", + "VA-API H265 encoder", "Codec/Encoder/Video", GST_PLUGIN_DESC, "Sreerenj Balachandran "); From 039e8c0d5626fd13acb85f049151245b9726abb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 25 Oct 2016 19:22:03 +0200 Subject: [PATCH 2542/3781] vaapidecode: rename element description So encoders and decoders have similar descriptions. https://bugzilla.gnome.org/show_bug.cgi?id=773497 --- gst/vaapi/gstvaapidecode.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index c014374306..3b9c949b41 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1292,7 +1292,7 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) GstVideoDecoderClass *const vdec_class = GST_VIDEO_DECODER_CLASS (klass); GstPadTemplate *pad_template; GstVaapiDecoderMap *map; - gchar *name, *longname; + gchar *name, *longname, *description; GstCaps *caps; GST_DEBUG_CATEGORY_INIT (gst_debug_vaapidecode, @@ -1327,20 +1327,23 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) if (map->codec) { name = g_ascii_strup (map->name, -1); longname = g_strdup_printf ("VA-API %s decoder", name); + description = g_strdup_printf ("A VA-API based %s video decoder", name); g_free (name); } else { longname = g_strdup ("VA-API decoder"); + description = g_strdup (GST_PLUGIN_DESC); } element_class->set_context = gst_vaapi_base_set_context; gst_element_class_set_static_metadata (element_class, longname, - "Codec/Decoder/Video", GST_PLUGIN_DESC, + "Codec/Decoder/Video", description, "Gwenole Beauchesne , " "Halley Zhao , " "Sreerenj Balachandran , " "Wind Yuan "); g_free (longname); + g_free (description); /* sink pad */ caps = gst_caps_from_string (map->caps_str); From 289a8e5b87647179f4bbc849824b8bac5a0343cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Oct 2016 11:19:50 +0200 Subject: [PATCH 2543/3781] vaapivideomemory: rename input parameter In order to clarify the use of flag as input parameter, it is renamed to surface_alloc_flag, since it is used when creating a VA surface with certain properties. https://bugzilla.gnome.org/show_bug.cgi?id=773497 --- gst/vaapi/gstvaapivideomemory.c | 4 ++-- gst/vaapi/gstvaapivideomemory.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 7545149923..b28187e757 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -725,7 +725,7 @@ bail: GstAllocator * gst_vaapi_video_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint flags) + const GstVideoInfo * vip, guint surface_alloc_flags) { GstVaapiVideoAllocator *allocator; @@ -740,7 +740,7 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display, allocator_configure_surface_info (display, allocator); allocator->surface_pool = gst_vaapi_surface_pool_new_full (display, - &allocator->surface_info, flags); + &allocator->surface_info, surface_alloc_flags); if (!allocator->surface_pool) goto error_create_surface_pool; diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 88a3814f40..3f1957e475 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -186,7 +186,7 @@ gst_vaapi_video_allocator_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstAllocator * gst_vaapi_video_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint flags); + const GstVideoInfo * vip, guint surface_alloc_flags); /* ------------------------------------------------------------------------ */ /* --- GstVaapiDmaBufMemory --- */ From 34e85792389f9d47d5d33a42a4ce092dd92724bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Oct 2016 17:01:57 +0200 Subject: [PATCH 2544/3781] vaapivideomemory: comment style https://bugzilla.gnome.org/show_bug.cgi?id=773497 --- gst/vaapi/gstvaapivideomemory.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index b28187e757..2fa1ad8a80 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -352,7 +352,8 @@ gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem) mem->image = NULL; } - /* Don't synchronize to surface, this shall have happened during unmaps */ + /* Don't synchronize to surface, this shall have happened during + * unmaps */ GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); } From 0f938be7a458314356884b56748db8ef22d78d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Oct 2016 18:12:04 +0200 Subject: [PATCH 2545/3781] plugins: fix code style for errors https://bugzilla.gnome.org/show_bug.cgi?id=773497 --- gst/vaapi/gstvaapiencode_h264.c | 6 ++- gst/vaapi/gstvaapiencode_h265.c | 6 ++- gst/vaapi/gstvaapisink.c | 21 +++++--- gst/vaapi/gstvaapivideomemory.c | 72 ++++++++++++++++++--------- gst/vaapi/gstvaapivideometa.c | 7 ++- gst/vaapi/gstvaapivideometa_texture.c | 14 ++++-- 6 files changed, 84 insertions(+), 42 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 44a857d805..1f37fc466f 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -341,8 +341,10 @@ _h264_convert_byte_stream_to_avc (GstBuffer * buf) return TRUE; error: - gst_buffer_unmap (buf, &info); - return FALSE; + { + gst_buffer_unmap (buf, &info); + return FALSE; + } } static GstFlowReturn diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 58219bd5bf..dbb60e66a9 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -340,8 +340,10 @@ _h265_convert_byte_stream_to_hvc (GstBuffer * buf) return TRUE; error: - gst_buffer_unmap (buf, &info); - return FALSE; + { + gst_buffer_unmap (buf, &info); + return FALSE; + } } static GstFlowReturn diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 1af1aa2956..cb593d2e3d 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1449,17 +1449,22 @@ done: gst_buffer_unref (buffer); return ret; + /* ERRORS */ error: - GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, - ("Internal error: could not render surface"), (NULL)); - ret = GST_FLOW_ERROR; - goto done; + { + GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, + ("Internal error: could not render surface"), (NULL)); + ret = GST_FLOW_ERROR; + goto done; + } no_surface: - /* No surface or surface proxy. That's very bad! */ - GST_WARNING_OBJECT (sink, "could not get surface"); - ret = GST_FLOW_ERROR; - goto done; + { + /* No surface or surface proxy. That's very bad! */ + GST_WARNING_OBJECT (sink, "could not get surface"); + ret = GST_FLOW_ERROR; + goto done; + } } static GstFlowReturn diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 2fa1ad8a80..0006e49012 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -436,29 +436,45 @@ gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize, /* ERRORS */ error_unsupported_map: - GST_ERROR ("unsupported map flags (0x%x)", flags); - return NULL; + { + GST_ERROR ("unsupported map flags (0x%x)", flags); + return NULL; + } error_unsupported_map_type: - GST_ERROR ("unsupported map type (%d)", mem->map_type); - return NULL; + { + GST_ERROR ("unsupported map type (%d)", mem->map_type); + return NULL; + } error_no_surface_proxy: - GST_ERROR ("failed to extract GstVaapiSurfaceProxy from video meta"); - return NULL; + { + GST_ERROR ("failed to extract GstVaapiSurfaceProxy from video meta"); + return NULL; + } error_no_surface: - GST_ERROR ("failed to extract VA surface from video buffer"); - return NULL; + { + GST_ERROR ("failed to extract VA surface from video buffer"); + return NULL; + } error_no_current_surface: - GST_ERROR ("failed to make surface current"); - return NULL; + { + GST_ERROR ("failed to make surface current"); + return NULL; + } error_no_image: - GST_ERROR ("failed to extract VA image from video buffer"); - return NULL; + { + GST_ERROR ("failed to extract VA image from video buffer"); + return NULL; + } error_no_current_image: - GST_ERROR ("failed to make image current"); - return NULL; + { + GST_ERROR ("failed to make image current"); + return NULL; + } error_map_image: - GST_ERROR ("failed to map VA image"); - return NULL; + { + GST_ERROR ("failed to map VA image"); + return NULL; + } } static void @@ -482,8 +498,10 @@ gst_vaapi_video_memory_unmap (GstVaapiVideoMemory * mem) /* ERRORS */ error_incompatible_map: - GST_ERROR ("incompatible map type (%d)", mem->map_type); - return; + { + GST_ERROR ("incompatible map type (%d)", mem->map_type); + return; + } } static GstVaapiVideoMemory * @@ -518,14 +536,20 @@ gst_vaapi_video_memory_copy (GstVaapiVideoMemory * mem, /* ERRORS */ error_no_current_surface: - GST_ERROR ("failed to make surface current"); - return NULL; + { + GST_ERROR ("failed to make surface current"); + return NULL; + } error_unsupported: - GST_ERROR ("failed to copy partial memory (unsupported operation)"); - return NULL; + { + GST_ERROR ("failed to copy partial memory (unsupported operation)"); + return NULL; + } error_allocate_memory: - GST_ERROR ("failed to allocate GstVaapiVideoMemory copy"); - return NULL; + { + GST_ERROR ("failed to allocate GstVaapiVideoMemory copy"); + return NULL; + } } static GstVaapiVideoMemory * diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index caafcbeae0..e73386adf2 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -307,9 +307,12 @@ gst_vaapi_video_meta_new_from_pool (GstVaapiVideoPool * pool) set_display (meta, gst_vaapi_video_pool_get_display (pool)); return meta; + /* ERRORS */ error: - gst_vaapi_video_meta_unref (meta); - return NULL; + { + gst_vaapi_video_meta_unref (meta); + return NULL; + } } /** diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index fb1535a760..b89f9ee80a 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -143,9 +143,12 @@ meta_texture_new (void) goto error; return meta; + /* ERRORS */ error: - meta_texture_free (meta); - return NULL; + { + meta_texture_free (meta); + return NULL; + } } static GstVaapiVideoMetaTexture * @@ -237,9 +240,12 @@ gst_buffer_add_texture_upload_meta (GstBuffer * buffer) goto error; return TRUE; + /* ERRORS */ error: - meta_texture_free (meta_texture); - return FALSE; + { + meta_texture_free (meta_texture); + return FALSE; + } } gboolean From c258343243f8be1f3e8f518c4372549256d13c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 Jul 2016 17:00:23 +0200 Subject: [PATCH 2546/3781] vaapidecode: rename member to allowed_sinkpad_caps vaapidecode has a member named allowed_caps, but this name is not enough explicit. This patch renames allowed_caps to allowed_sinkpad_caps. No functional changes were included. https://bugzilla.gnome.org/show_bug.cgi?id=773497 --- gst/vaapi/gstvaapidecode.c | 21 +++++++++++---------- gst/vaapi/gstvaapidecode.h | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3b9c949b41..6f84427127 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -954,7 +954,7 @@ gst_vaapidecode_finalize (GObject * object) { GstVaapiDecode *const decode = GST_VAAPIDECODE (object); - gst_caps_replace (&decode->allowed_caps, NULL); + gst_caps_replace (&decode->allowed_sinkpad_caps, NULL); g_cond_clear (&decode->surface_ready); g_mutex_clear (&decode->surface_ready_mutex); @@ -1120,9 +1120,9 @@ gst_vaapidecode_parse (GstVideoDecoder * vdec, } static gboolean -gst_vaapidecode_ensure_allowed_caps (GstVaapiDecode * decode) +gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) { - GstCaps *caps, *allowed_caps; + GstCaps *caps, *allowed_sinkpad_caps; GArray *profiles; guint i; @@ -1132,8 +1132,8 @@ gst_vaapidecode_ensure_allowed_caps (GstVaapiDecode * decode) if (!profiles) goto error_no_profiles; - allowed_caps = gst_caps_new_empty (); - if (!allowed_caps) + allowed_sinkpad_caps = gst_caps_new_empty (); + if (!allowed_sinkpad_caps) goto error_no_memory; for (i = 0; i < profiles->len; i++) { @@ -1157,9 +1157,9 @@ gst_vaapidecode_ensure_allowed_caps (GstVaapiDecode * decode) gst_structure_set (structure, "profile", G_TYPE_STRING, profile_name, NULL); - allowed_caps = gst_caps_merge (allowed_caps, caps); + allowed_sinkpad_caps = gst_caps_merge (allowed_sinkpad_caps, caps); } - decode->allowed_caps = gst_caps_simplify (allowed_caps); + decode->allowed_sinkpad_caps = gst_caps_simplify (allowed_sinkpad_caps); g_array_unref (profiles); return TRUE; @@ -1184,7 +1184,7 @@ gst_vaapidecode_sink_getcaps (GstVideoDecoder * vdec, GstCaps * filter) GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstCaps *result; - if (decode->allowed_caps) + if (decode->allowed_sinkpad_caps) goto bail; /* if we haven't a display yet, return our pad's template caps */ @@ -1193,11 +1193,12 @@ gst_vaapidecode_sink_getcaps (GstVideoDecoder * vdec, GstCaps * filter) /* if the allowed caps calculation fails, return an empty caps, so * the auto-plug can try other decoder */ - if (!gst_vaapidecode_ensure_allowed_caps (decode)) + if (!gst_vaapidecode_ensure_allowed_sinkpad_caps (decode)) return gst_caps_new_empty (); bail: - result = gst_video_decoder_proxy_getcaps (vdec, decode->allowed_caps, filter); + result = gst_video_decoder_proxy_getcaps (vdec, decode->allowed_sinkpad_caps, + filter); GST_DEBUG_OBJECT (decode, "Returning sink caps %" GST_PTR_FORMAT, result); diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index c4fad51a96..41d85640e6 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -46,7 +46,7 @@ struct _GstVaapiDecode { GMutex surface_ready_mutex; GCond surface_ready; GstCaps *decoder_caps; - GstCaps *allowed_caps; + GstCaps *allowed_sinkpad_caps; guint current_frame_size; guint has_texture_upload_meta : 1; From bb0abb1a18c91e8fced1f36215ce9e102e7d6895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 25 Oct 2016 14:32:44 +0200 Subject: [PATCH 2547/3781] vaapipostproc: use GST_*_OBJECT when possible Since we can have several vaapipostproc operating in a pipeline, it is useful to know which one is generating the logging message. https://bugzilla.gnome.org/show_bug.cgi?id=773497 --- gst/vaapi/gstvaapipostproc.c | 37 +++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 41f36fd6ae..ddc8489ec9 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -344,7 +344,8 @@ should_deinterlace_buffer (GstVaapiPostproc * postproc, GstBuffer * buf) return TRUE; break; default: - GST_ERROR ("unhandled \"interlace-mode\", disabling deinterlacing"); + GST_ERROR_OBJECT (postproc, + "unhandled \"interlace-mode\", disabling deinterlacing"); break; } return FALSE; @@ -373,12 +374,12 @@ create_output_buffer (GstVaapiPostproc * postproc) /* ERRORS */ error_activate_pool: { - GST_ERROR ("failed to activate output video buffer pool"); + GST_ERROR_OBJECT (postproc, "failed to activate output video buffer pool"); return NULL; } error_create_buffer: { - GST_ERROR ("failed to create output video buffer"); + GST_ERROR_OBJECT (postproc, "failed to create output video buffer"); return NULL; } } @@ -772,42 +773,43 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, /* ERRORS */ error_invalid_buffer: { - GST_ERROR ("failed to validate source buffer"); + GST_ERROR_OBJECT (postproc, "failed to validate source buffer"); return GST_FLOW_ERROR; } error_create_buffer: { - GST_ERROR ("failed to create output buffer"); + GST_ERROR_OBJECT (postproc, "failed to create output buffer"); return GST_FLOW_ERROR; } error_create_meta: { - GST_ERROR ("failed to create new output buffer meta"); + GST_ERROR_OBJECT (postproc, "failed to create new output buffer meta"); gst_buffer_replace (&fieldbuf, NULL); return GST_FLOW_ERROR; } error_create_proxy: { - GST_ERROR ("failed to create surface proxy from pool"); + GST_ERROR_OBJECT (postproc, "failed to create surface proxy from pool"); gst_buffer_replace (&fieldbuf, NULL); return GST_FLOW_ERROR; } error_op_deinterlace: { - GST_ERROR ("failed to apply deinterlacing filter"); + GST_ERROR_OBJECT (postproc, "failed to apply deinterlacing filter"); gst_buffer_replace (&fieldbuf, NULL); return GST_FLOW_NOT_SUPPORTED; } error_process_vpp: { - GST_ERROR ("failed to apply VPP filters (error %d)", status); + GST_ERROR_OBJECT (postproc, "failed to apply VPP filters (error %d)", + status); gst_buffer_replace (&fieldbuf, NULL); return GST_FLOW_ERROR; } error_push_buffer: { if (ret != GST_FLOW_FLUSHING) - GST_ERROR ("failed to push output buffer to video sink"); + GST_ERROR_OBJECT (postproc, "failed to push output buffer to video sink"); return GST_FLOW_ERROR; } } @@ -873,18 +875,18 @@ gst_vaapipostproc_process (GstBaseTransform * trans, GstBuffer * inbuf, /* ERRORS */ error_invalid_buffer: { - GST_ERROR ("failed to validate source buffer"); + GST_ERROR_OBJECT (postproc, "failed to validate source buffer"); return GST_FLOW_ERROR; } error_create_buffer: { - GST_ERROR ("failed to create output buffer"); + GST_ERROR_OBJECT (postproc, "failed to create output buffer"); return GST_FLOW_EOS; } error_push_buffer: { if (ret != GST_FLOW_FLUSHING) - GST_ERROR ("failed to push output buffer to video sink"); + GST_ERROR_OBJECT (postproc, "failed to push output buffer to video sink"); return GST_FLOW_EOS; } } @@ -893,6 +895,7 @@ static GstFlowReturn gst_vaapipostproc_passthrough (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer * outbuf) { + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); GstVaapiVideoMeta *meta; /* No video processing needed, simply copy buffer metadata */ @@ -900,14 +903,14 @@ gst_vaapipostproc_passthrough (GstBaseTransform * trans, GstBuffer * inbuf, if (!meta) goto error_invalid_buffer; - append_output_buffer_metadata (GST_VAAPIPOSTPROC (trans), outbuf, inbuf, + append_output_buffer_metadata (postproc, outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS); return GST_FLOW_OK; /* ERRORS */ error_invalid_buffer: { - GST_ERROR ("failed to validate source buffer"); + GST_ERROR_OBJECT (postproc, "failed to validate source buffer"); return GST_FLOW_ERROR; } } @@ -1071,7 +1074,7 @@ ensure_allowed_srcpad_caps (GstVaapiPostproc * postproc) /* Create initial caps from pad template */ out_caps = gst_caps_from_string (gst_vaapipostproc_src_caps_str); if (!out_caps) { - GST_ERROR ("failed to create VA src caps"); + GST_ERROR_OBJECT (postproc, "failed to create VA src caps"); return FALSE; } @@ -1194,7 +1197,7 @@ gst_vaapipostproc_transform (GstBaseTransform * trans, GstBuffer * inbuf, ret = gst_vaapipostproc_process_vpp (trans, buf, outbuf); if (ret != GST_FLOW_NOT_SUPPORTED) goto done; - GST_WARNING ("unsupported VPP filters. Disabling"); + GST_WARNING_OBJECT (postproc, "unsupported VPP filters. Disabling"); } /* Only append picture structure meta data (top/bottom field) */ From 0b46da2a8f70d17c2991f67e960e836ae8c74142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 27 Oct 2016 11:06:06 +0200 Subject: [PATCH 2548/3781] docs: add missing long descriptions --- gst/vaapi/gstvaapipluginutil.c | 2 ++ gst/vaapi/gstvaapivideobuffer.c | 3 +++ gst/vaapi/gstvaapivideometa.c | 2 ++ 3 files changed, 7 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 4e3d7a3947..88223ba39a 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -783,6 +783,8 @@ no_vendor: * @codecs: a #GArray of #GstVaapiCodec * @codec: a #GstVaapiCodec to find in @codec * + * Search in the available @codecs for the specific @codec. + * * Returns: %TRUE if @codec is in @codecs **/ gboolean diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 68dbff3d15..9d047e73ff 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -25,6 +25,9 @@ /** * SECTION:gstvaapivideobuffer * @short_description: VA video buffer for GStreamer + * + * This functions creates and decorates a #GstBuffer that is going to + * be used by VA base gstreamer elements. */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index e73386adf2..ca5333bcca 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -25,6 +25,8 @@ /** * SECTION:gstvaapivideometa * @short_description: VA video meta for GStreamer + * + * Describes a #GstMeta for VA-base video buffers. */ #include "gstcompat.h" From 74a9f76d32e1777ee6de3a0a49a5978ef389869b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 27 Oct 2016 12:31:49 +0200 Subject: [PATCH 2549/3781] docs: replace vaapidecode with each codec In the spirit of the codec split, this patch removes the documentation of vaapidecode and adds a page per each possible decoder. Nonetheless, only those available in the compilation system are going to be instrospected, because the rest are not registered. --- .../gstreamer-vaapi-plugins-docs.xml.in | 10 +- .../gstreamer-vaapi-plugins-sections.txt | 85 +++++- gst/vaapi/Makefile.am | 1 + gst/vaapi/gstvaapidecode.c | 50 ---- gst/vaapi/gstvaapidecodebin.c | 6 +- gst/vaapi/gstvaapidecodedoc.c | 254 ++++++++++++++++++ 6 files changed, 346 insertions(+), 60 deletions(-) create mode 100644 gst/vaapi/gstvaapidecodedoc.c diff --git a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in index c9cb5fc1f4..5eec5ca8aa 100644 --- a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in +++ b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in @@ -11,8 +11,15 @@ gstreamer-vaapi Elements - + + + + + + + + @@ -21,6 +28,7 @@ + diff --git a/docs/plugins/gstreamer-vaapi-plugins-sections.txt b/docs/plugins/gstreamer-vaapi-plugins-sections.txt index e3bc8e4031..2833db3d5a 100644 --- a/docs/plugins/gstreamer-vaapi-plugins-sections.txt +++ b/docs/plugins/gstreamer-vaapi-plugins-sections.txt @@ -1,10 +1,4 @@
-element-vaapidecode -vaapidecode - -GstVaapiDecode -GstVaapiDecodeClass -
element-vaapijpegdec @@ -14,6 +8,70 @@ GstVaapiDecode_jpeg GstVaapiDecode_jpegClass
+
+element-vaapimpeg2dec +vaapimpeg2dec + +GstVaapiDecode_mpeg2 +GstVaapiDecode_mpeg2Class +
+ +
+element-vaapimpeg4dec +vaapimpeg4dec + +GstVaapiDecode_mpeg4 +GstVaapiDecode_mpeg4Class +
+ +
+element-vaapih263dec +vaapih263dec + +GstVaapiDecode_h263 +GstVaapiDecode_h263Class +
+ +
+element-vaapih264dec +vaapih264dec + +GstVaapiDecode_h264 +GstVaapiDecode_h264Class +
+ +
+element-vaapih265dec +vaapih265dec + +GstVaapiDecode_h265 +GstVaapiDecode_h265Class +
+ +
+element-vaapivc1dec +vaapivc1dec + +GstVaapiDecode_vc1 +GstVaapiDecode_vc1Class +
+ +
+element-vaapivp8dec +vaapivp8dec + +GstVaapiDecode_vp8 +GstVaapiDecode_vp8Class +
+ +
+element-vaapivp9dec +vaapivp9dec + +GstVaapiDecode_vp9 +GstVaapiDecode_vp9Class +
+
element-vaapidecodebin vaapidecodebin @@ -134,3 +192,18 @@ GstVaapiEncodeVP8 GstVaapiEncodeVP8Class gst_vaapiencode_vp8_get_type
+ +
+element-vaapivp9enc +vaapivp9enc + +GST_IS_VAAPIENCODE_VP9 +GST_IS_VAAPIENCODE_VP9_CLASS +GST_TYPE_VAAPIENCODE_VP9 +GST_VAAPIENCODE_VP9 +GST_VAAPIENCODE_VP9_CLASS +GST_VAAPIENCODE_VP9_GET_CLASS +GstVaapiEncodeVP9 +GstVaapiEncodeVP9Class +gst_vaapiencode_vp9_get_type +
diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 016b3d92b8..90212480b9 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -43,6 +43,7 @@ endif libgstvaapi_source_c = \ gstvaapi.c \ gstvaapidecode.c \ + gstvaapidecodedoc.c \ gstvaapipluginbase.c \ gstvaapipluginutil.c \ gstvaapipostproc.c \ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6f84427127..51001ef0f0 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -20,56 +20,6 @@ * 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:element-vaapidecode - * @short_description: A VA-API based video decoder - * - * vaapidecode decodes from raw bitstreams to surfaces suitable for - * the vaapisink or vaapipostproc elements using the installed VA-API - * back-end. - * - * In the case of OpenGL based elements, the buffers have the - * #GstVideoGLTextureUploadMeta meta, which efficiently copies the - * content of the VA-API surface into a GL texture. - * - * Also it can deliver normal video buffers that can be rendered or - * processed by other elements, but the performance would be rather - * bad. - * - * - * Example launch line - * |[ - * gst-launch-1.0 filesrc location=~/big_buck_bunny.mov ! qtdemux ! h264parse ! vaapidecode ! vaapisink - * ]| - * - */ - -/** - * SECTION:element-vaapijpegdec - * @short_description: A VA-API based JPEG image decoder - * - * vaapijpegdec decodes a JPEG image to surfaces suitable for the - * vaapisink or vaapipostproc elements using the installed VA-API - * back-end. - * - * In the case of OpenGL based elements, the buffers have the - * #GstVideoGLTextureUploadMeta meta, which efficiently copies the - * content of the VA-API surface into a GL texture. - * - * Also it can deliver normal video buffers that can be rendered or - * processed by other elements, but the performance would be rather - * bad. - * - * - * Example launch line - * |[ - * gst-launch-1.0 filesrc location=~/image.jpeg ! jpegparse ! vaapijpegdec ! imagefreeze ! vaapisink - * ]| - * */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 0e3b713c26..92856146a4 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -26,9 +26,9 @@ * @short_description: A VA-API based video decoder with a * post-processor * - * vaapidecodebin is similar #GstVaapiDecode, but it is composed by - * the vaapidecode, a #GstQueue, and the #GstVaapiPostproc, if it is - * available and functional in the setup. + * vaapidecodebin is similar vaapi{CODEC}dec, but it is composed by + * the unregistered vaapidecode, a #GstQueue, and the + * #GstVaapiPostproc, if it is available and functional in the setup. * * It offers the functionality of #GstVaapiDecode and the many options * of #GstVaapiPostproc. diff --git a/gst/vaapi/gstvaapidecodedoc.c b/gst/vaapi/gstvaapidecodedoc.c new file mode 100644 index 0000000000..aafe9fa66d --- /dev/null +++ b/gst/vaapi/gstvaapidecodedoc.c @@ -0,0 +1,254 @@ +/* + * gstvaapidecodedoc.c - VA-API video decoders documentation + * + * Copyright (C) 2016 Intel Corporation + * Author: Victor Jaquez + * + * 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:element-vaapijpegdec + * @short_description: A VA-API based JPEG image decoder + * + * vaapijpegdec decodes a JPEG image to surfaces suitable for the + * vaapisink or vaapipostproc elements using the installed VA-API + * back-end. + * + * In the case of OpenGL based elements, the buffers have the + * #GstVideoGLTextureUploadMeta meta, which efficiently copies the + * content of the VA-API surface into a GL texture. + * + * Also it can deliver normal video buffers that can be rendered or + * processed by other elements, but the performance would be rather + * bad. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=~/image.jpeg ! jpegparse ! vaapijpegdec ! imagefreeze ! vaapisink + * ]| + * + */ + +/** + * SECTION:element-vaapimpeg2dec + * @short_description: A VA-API based MPEG2 video decoder + * + * vaapimpeg2dec decodes from MPEG2 bitstreams to surfaces suitable + * for the vaapisink or vaapipostproc elements using the installed + * VA-API + * back-end. + * + * In the case of OpenGL based elements, the buffers have the + * #GstVideoGLTextureUploadMeta meta, which efficiently copies the + * content of the VA-API surface into a GL texture. + * + * Also it can deliver normal video buffers that can be rendered or + * processed by other elements, but the performance would be rather + * bad. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=~/sample.mpg ! mpegpsdemux ! vaapimpeg2dec ! vaapisink + * ]| + * + */ + +/** + * SECTION:element-vaapimpeg4dec + * @short_description: A VA-API based MPEG4 video decoder + * + * vaapimpeg4dec decodes from MPEG4 bitstreams to surfaces suitable + * for the vaapisink or vaapipostproc elements using the installed + * VA-API + * back-end. + * + * In the case of OpenGL based elements, the buffers have the + * #GstVideoGLTextureUploadMeta meta, which efficiently copies the + * content of the VA-API surface into a GL texture. + * + * Also it can deliver normal video buffers that can be rendered or + * processed by other elements, but the performance would be rather + * bad. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=~/sample.mpeg4 ! mpeg4videoparse ! vaapimpeg4dec ! vaapisink + * ]| + * + */ + +/** + * SECTION:element-vaapih263dec + * @short_description: A VA-API based H263 video decoder + * + * vaapih263dec decodes from H263 bitstreams to surfaces suitable + * for the vaapisink or vaapipostproc elements using the installed + * VA-API + * back-end. + * + * In the case of OpenGL based elements, the buffers have the + * #GstVideoGLTextureUploadMeta meta, which efficiently copies the + * content of the VA-API surface into a GL texture. + * + * Also it can deliver normal video buffers that can be rendered or + * processed by other elements, but the performance would be rather + * bad. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=~/sample.h263 ! h263parse ! vaapih263dec ! vaapisink + * ]| + * + */ + +/** + * SECTION:element-vaapih264dec + * @short_description: A VA-API based H264 video decoder + * + * vaapih264dec decodes from H264 bitstreams to surfaces suitable + * for the vaapisink or vaapipostproc elements using the installed + * VA-API + * back-end. + * + * In the case of OpenGL based elements, the buffers have the + * #GstVideoGLTextureUploadMeta meta, which efficiently copies the + * content of the VA-API surface into a GL texture. + * + * Also it can deliver normal video buffers that can be rendered or + * processed by other elements, but the performance would be rather + * bad. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=~/big_buck_bunny.mov ! qtdemux ! h264parse ! vaapih264dec ! vaapisink + * ]| + * + */ + +/** + * SECTION:element-vaapih265dec + * @short_description: A VA-API based H265 video decoder + * + * vaapih265dec decodes from H265 bitstreams to surfaces suitable + * for the vaapisink or vaapipostproc elements using the installed + * VA-API + * back-end. + * + * In the case of OpenGL based elements, the buffers have the + * #GstVideoGLTextureUploadMeta meta, which efficiently copies the + * content of the VA-API surface into a GL texture. + * + * Also it can deliver normal video buffers that can be rendered or + * processed by other elements, but the performance would be rather + * bad. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=./sample.bin ! h265parse ! vaapih265dec ! vaapisink + * ]| + * + */ + +/** + * SECTION:element-vaapivc1dec + * @short_description: A VA-API based VC1 video decoder + * + * vaapivc1dec decodes from VC1 bitstreams to surfaces suitable + * for the vaapisink or vaapipostproc elements using the installed + * VA-API + * back-end. + * + * In the case of OpenGL based elements, the buffers have the + * #GstVideoGLTextureUploadMeta meta, which efficiently copies the + * content of the VA-API surface into a GL texture. + * + * Also it can deliver normal video buffers that can be rendered or + * processed by other elements, but the performance would be rather + * bad. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=~/elephants_dream.wmv ! asfdemux ! vaapivc1dec ! vaapisink + * ]| + * + */ + +/** + * SECTION:element-vaapivp8dec + * @short_description: A VA-API based VP8 video decoder + * + * vaapivp8dec decodes from VP8 bitstreams to surfaces suitable + * for the vaapisink or vaapipostproc elements using the installed + * VA-API + * back-end. + * + * In the case of OpenGL based elements, the buffers have the + * #GstVideoGLTextureUploadMeta meta, which efficiently copies the + * content of the VA-API surface into a GL texture. + * + * Also it can deliver normal video buffers that can be rendered or + * processed by other elements, but the performance would be rather + * bad. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=./sample.webm ! matroskademux ! vaapivp8dec ! vaapisink + * ]| + * + */ + +/** + * SECTION:element-vaapivp9dec + * @short_description: A VA-API based VP9 video decoder + * + * vaapivp9dec decodes from VP9 bitstreams to surfaces suitable + * for the vaapisink or vaapipostproc elements using the installed + * VA-API + * back-end. + * + * In the case of OpenGL based elements, the buffers have the + * #GstVideoGLTextureUploadMeta meta, which efficiently copies the + * content of the VA-API surface into a GL texture. + * + * Also it can deliver normal video buffers that can be rendered or + * processed by other elements, but the performance would be rather + * bad. + * + * + * Example launch line + * |[ + * gst-launch-1.0 filesrc location=./sample.vp9.webm ! ivfparse ! vaapivp9dec ! vaapisink + * ]| + * + */ From 2e1f69898b7842c62471dec854dd4accce37e425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 27 Oct 2016 12:53:54 +0200 Subject: [PATCH 2550/3781] docs: document environment variables https://bugzilla.gnome.org/show_bug.cgi?id=773544 --- docs/plugins/Makefile.am | 2 +- .../gstreamer-vaapi-plugins-docs.xml.in | 5 ++ docs/plugins/running.xml | 68 +++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 docs/plugins/running.xml diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 86ab1b465e..7701535c7b 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -61,7 +61,7 @@ EXAMPLE_CFILES = HTML_IMAGES = # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). -content_files = +content_files = running.xml # Other files to distribute. extra_files = diff --git a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in index 5eec5ca8aa..37351d96ce 100644 --- a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in +++ b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in @@ -9,6 +9,11 @@ GStreamer VA-API Plugins @GST_API_VERSION@ Plugins Reference Manual + + gstremaer-vaapi Overview + + + gstreamer-vaapi Elements diff --git a/docs/plugins/running.xml b/docs/plugins/running.xml new file mode 100644 index 0000000000..f7d98cb021 --- /dev/null +++ b/docs/plugins/running.xml @@ -0,0 +1,68 @@ + + +%version-entities; + +]> + + +Running GStreamer VAAPI Applications + + + +Running GStreamer VAAPI Applications + +How to run GStreamer application with VAAPI elements. + + + + +Running GStreamer VAAPI Applications + + +Environment variables + + +GStreamer-VAAPI inspects a few of environment variables to define it usage. + + + + <envar>GST_VAAPI_ALL_DRIVERS</envar> + + +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. + + + + + + <envar>LIBVA_DRIVER_NAME</envar> + + +This environment variable can be set with the drivers name to load. For +example, intel's driver is i915, meanwhile mesa is +gallium. + + + + + + <envar>LIBVA_DRIVERS_PATH</envar> + + +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. + + + + + + + + + From 0db3e149892c3d15fc1b7cd0234338141ca96644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 27 Oct 2016 16:27:45 +0200 Subject: [PATCH 2551/3781] vaapidecodebin: remove unused variables Since vaapipostproc is only registered if the driver supports it, all the support for dynamic loading were removed. Though some leftovers remained. https://bugzilla.gnome.org/show_bug.cgi?id=773589 --- gst/vaapi/gstvaapidecodebin.c | 8 -------- gst/vaapi/gstvaapidecodebin.h | 1 - 2 files changed, 9 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 92856146a4..a60d556c0b 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -73,13 +73,6 @@ enum PROP_LAST }; -enum -{ - HAS_VPP_UNKNOWN, - HAS_VPP_NO, - HAS_VPP_YES -}; - static GParamSpec *properties[PROP_LAST]; /* Default templates */ @@ -350,7 +343,6 @@ error_adding_pad: static void gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) { - vaapidecbin->has_vpp = HAS_VPP_UNKNOWN; vaapidecbin->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; gst_vaapi_decode_bin_configure (vaapidecbin); diff --git a/gst/vaapi/gstvaapidecodebin.h b/gst/vaapi/gstvaapidecodebin.h index 81804b99d5..787d302be1 100644 --- a/gst/vaapi/gstvaapidecodebin.h +++ b/gst/vaapi/gstvaapidecodebin.h @@ -53,7 +53,6 @@ typedef struct _GstVaapiDecodeBin { guint64 max_size_time; GstVaapiDeinterlaceMethod deinterlace_method; gboolean disable_vpp; - guint has_vpp; } GstVaapiDecodeBin; From 4100e8d5c2a1d4770fc591e3d99d57d66152d82c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 27 Oct 2016 16:32:23 +0200 Subject: [PATCH 2552/3781] vaapidecodebin: name the internal queue https://bugzilla.gnome.org/show_bug.cgi?id=773589 --- gst/vaapi/gstvaapidecodebin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index a60d556c0b..026ebf024f 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -278,7 +278,7 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) g_object_new (g_type_from_name ("GstVaapiDecode"), NULL); /* create the queue */ - vaapidecbin->queue = gst_element_factory_make ("queue", NULL); + vaapidecbin->queue = gst_element_factory_make ("queue", "vaapi-queue"); if (!vaapidecbin->queue) { missing_factory = "queue"; goto error_element_missing; From af0c2fab0dec98699c43437c91a1fb44c3a691f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 27 Oct 2016 17:13:48 +0200 Subject: [PATCH 2553/3781] vaapidecodebin: resurrect disable-vpp property https://bugzilla.gnome.org/show_bug.cgi?id=773589 --- gst/vaapi/gstvaapidecodebin.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 026ebf024f..dfafc8e676 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -168,19 +168,9 @@ gst_vaapi_decode_bin_set_property (GObject * object, vaapidecbin->deinterlace_method, NULL); break; case PROP_DISABLE_VPP: - { - gboolean disable_vpp; - - disable_vpp = g_value_get_boolean (value); - if (!disable_vpp && !vaapidecbin->has_vpp) - GST_WARNING_OBJECT (vaapidecbin, - "Cannot enable VPP since the VA driver does not support it"); - else - vaapidecbin->disable_vpp = disable_vpp; - /* @TODO: Add run-time disabling support */ + vaapidecbin->disable_vpp = g_value_get_boolean (value); break; - } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -277,6 +267,12 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) vaapidecbin->decoder = g_object_new (g_type_from_name ("GstVaapiDecode"), NULL); + if (vaapidecbin->disable_vpp) { + gst_bin_add (GST_BIN (vaapidecbin), vaapidecbin->decoder); + pad = gst_element_get_static_pad (vaapidecbin->decoder, "src"); + goto bail; + } + /* create the queue */ vaapidecbin->queue = gst_element_factory_make ("queue", "vaapi-queue"); if (!vaapidecbin->queue) { @@ -303,17 +299,19 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) vaapidecbin->postproc, NULL)) goto error_link_pad; - /* create ghost pad sink */ - pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->decoder), "sink"); - ghostpad = gst_ghost_pad_new_from_template ("sink", pad, + /* create ghost pad src */ + pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->postproc), "src"); + +bail: + ghostpad = gst_ghost_pad_new_from_template ("src", pad, GST_PAD_PAD_TEMPLATE (pad)); gst_object_unref (pad); if (!gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad)) goto error_adding_pad; - /* create ghost pad src */ - pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->postproc), "src"); - ghostpad = gst_ghost_pad_new_from_template ("src", pad, + /* create ghost pad sink */ + pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->decoder), "sink"); + ghostpad = gst_ghost_pad_new_from_template ("sink", pad, GST_PAD_PAD_TEMPLATE (pad)); gst_object_unref (pad); if (!gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad)) From eb4c8d7302bbb1b6116210c2ea3d54491fc2d2d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 1 Nov 2016 18:19:32 +0200 Subject: [PATCH 2554/3781] Release 1.10.0 --- ChangeLog | 183 ++++++- NEWS | 1115 +++++++++++++++++++++++++++++++++++++++++- configure.ac | 14 +- gstreamer-vaapi.doap | 9 + 4 files changed, 1310 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4ca899b898..77ac03f954 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,186 @@ -=== release 1.9.90 === +=== release 1.10.0 === -2016-09-30 Sebastian Dröge +2016-11-01 Sebastian Dröge * configure.ac: - releasing 1.9.90 + releasing 1.10.0 + +2016-10-27 17:13:48 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: resurrect disable-vpp property + https://bugzilla.gnome.org/show_bug.cgi?id=773589 + +2016-10-27 16:32:23 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: name the internal queue + https://bugzilla.gnome.org/show_bug.cgi?id=773589 + +2016-10-27 16:27:45 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapidecodebin.h: + vaapidecodebin: remove unused variables + Since vaapipostproc is only registered if the driver supports it, all the + support for dynamic loading were removed. Though some leftovers remained. + https://bugzilla.gnome.org/show_bug.cgi?id=773589 + +2016-10-27 12:53:54 +0200 Víctor Manuel Jáquez Leal + + * docs/plugins/Makefile.am: + * docs/plugins/gstreamer-vaapi-plugins-docs.xml.in: + * docs/plugins/running.xml: + docs: document environment variables + https://bugzilla.gnome.org/show_bug.cgi?id=773544 + +2016-10-27 12:31:49 +0200 Víctor Manuel Jáquez Leal + + * docs/plugins/gstreamer-vaapi-plugins-docs.xml.in: + * docs/plugins/gstreamer-vaapi-plugins-sections.txt: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapidecodedoc.c: + docs: replace vaapidecode with each codec + In the spirit of the codec split, this patch removes the documentation of + vaapidecode and adds a page per each possible decoder. + Nonetheless, only those available in the compilation system are going to be + instrospected, because the rest are not registered. + +2016-10-27 11:06:06 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideometa.c: + docs: add missing long descriptions + +2016-10-25 14:32:44 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: use GST_*_OBJECT when possible + Since we can have several vaapipostproc operating in a pipeline, it is useful + to know which one is generating the logging message. + https://bugzilla.gnome.org/show_bug.cgi?id=773497 + +2016-07-19 17:00:23 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: rename member to allowed_sinkpad_caps + vaapidecode has a member named allowed_caps, but this name is not enough + explicit. This patch renames allowed_caps to allowed_sinkpad_caps. + No functional changes were included. + https://bugzilla.gnome.org/show_bug.cgi?id=773497 + +2016-10-20 18:12:04 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa_texture.c: + plugins: fix code style for errors + https://bugzilla.gnome.org/show_bug.cgi?id=773497 + +2016-10-20 17:01:57 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: comment style + https://bugzilla.gnome.org/show_bug.cgi?id=773497 + +2016-10-20 11:19:50 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: rename input parameter + In order to clarify the use of flag as input parameter, it is renamed to + surface_alloc_flag, since it is used when creating a VA surface with certain + properties. + https://bugzilla.gnome.org/show_bug.cgi?id=773497 + +2016-10-25 19:22:03 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: rename element description + So encoders and decoders have similar descriptions. + https://bugzilla.gnome.org/show_bug.cgi?id=773497 + +2016-08-02 11:32:19 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + vaapiencode: h264, h265: rename codec name + So encoder and decoders have the same codec name. + https://bugzilla.gnome.org/show_bug.cgi?id=773497 + +2016-07-29 15:17:33 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: simplify code + Merge two lines of variable declarations. + https://bugzilla.gnome.org/show_bug.cgi?id=773497 + +2016-10-07 18:46:22 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapipixmap_priv.h: + * gst-libs/gst/vaapi/gstvaapitexture_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + libs: minor correction for logical consistency + GstVaapiDecode is a descendant of GstVaapiMiniObject, so, thought we should + use its methods, even though it doesn't change functionality. + GstVaapiPixmap, GstVaapiTexture and GstVaapiWindow are descendant of + GstVaapiObject, hence its methods shall be used. + https://bugzilla.gnome.org/show_bug.cgi?id=772554 + +2016-10-19 15:39:54 +0100 Julien Isorce + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: add explanation about the call 'dup (dmabuf_fd)' + In short GstFdMemory is configured to call close when using + GstDmabufMemory. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-09-02 16:42:45 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + build: clean up the dlopen usage + +2016-10-08 14:33:59 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + encoder: h264,h265: fix regression in offset count + In commit dc35dafa a bug was introduced because I assumed that + GST_CLOCK_TIME_NONE is zero when is -1. This patch fixes that mistake. + https://bugzilla.gnome.org/show_bug.cgi?id=772259 + +2016-10-18 17:02:59 +0200 Víctor Manuel Jáquez Leal + + * README: + docs: update README + +2016-09-27 17:29:25 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + libs: display: egl: remove unused header include + The header gmodule.h is not used since the library dynamic loading for EGL + display was removed. + https://bugzilla.gnome.org/show_bug.cgi?id=772599 + +=== release 1.9.90 === + +2016-09-30 13:05:20 +0300 Sebastian Dröge + + * ChangeLog: + * NEWS: + * common: + * configure.ac: + * gstreamer-vaapi.doap: + Release 1.9.90 2016-03-04 16:35:11 +0900 Vineeth TM diff --git a/NEWS b/NEWS index 072b2dfb35..547de7f3f9 100644 --- a/NEWS +++ b/NEWS @@ -1 +1,1114 @@ -This is GStreamer 1.9.90 +# GStreamer 1.10 Release Notes + +**GStreamer 1.10.0 was released on 1st November 2016.** + +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 new features, bug fixes and other +improvements. + +See [https://gstreamer.freedesktop.org/releases/1.10/][latest] for the latest +version of this document. + +*Last updated: Tuesday 1 Nov 2016, 15:00 UTC [(log)][gitlog]* + +[latest]: https://gstreamer.freedesktop.org/releases/1.10/ +[gitlog]: https://cgit.freedesktop.org/gstreamer/www/log/src/htdocs/releases/1.10/release-notes-1.10.md + +## 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 new features, bug fixes and other +improvements. + +## Highlights + +- Several convenience APIs have been added to make developers' lives easier +- A new `GstStream` API provides applications a more meaningful view of the + structure of streams, simplifying the process of dealing with media in + complex container formats +- Experimental `decodebin3` and `playbin3` elements which bring a number of + improvements which were hard to implement within `decodebin` and `playbin` +- A new `parsebin` element to automatically unpack and parse a stream, stopping + just short of decoding +- Experimental new `meson`-based build system, bringing faster build and much + better Windows support (including for building with Visual Studio) +- A new `gst-docs` module has been created, and we are in the process of moving + our documentation to a markdown-based format for easier maintenance and + updates +- A new `gst-examples` module has been create, which contains example + GStreamer applications and is expected to grow with many more examples in + the future +- Various OpenGL and OpenGL|ES-related fixes and improvements for greater + efficiency on desktop and mobile platforms, and Vulkan support on Wayland was + also added +- Extensive improvements to the VAAPI plugins for improved robustness and + efficiency +- Lots of fixes and improvements across the board, spanning RTP/RTSP, V4L2, + Bluetooth, audio conversion, echo cancellation, and more! + +## Major new features and changes + +### Noteworthy new API, features and other changes + +#### Core API additions + +##### Receive property change notifications via bus messages + +New API was added to receive element property change notifications via +bus messages. So far, applications had to connect a callback to an element's +`notify::property-name` signal via the GObject API, which was inconvenient for +at least two reasons: one had to implement a signal callback function, and that +callback function would usually be called from one of the streaming threads, so +one had to marshal (send) any information gathered or pending requests to the +main application thread which was tedious and error-prone. + +Enter [`gst_element_add_property_notify_watch()`][notify-watch] and +[`gst_element_add_property_deep_notify_watch()`][deep-notify-watch] which will +watch for changes of a property on the specified element, either only for this +element or recursively for a whole bin or pipeline. Whenever such a +property change happens, a `GST_MESSAGE_PROPERTY_NOTIFY` message will be posted +on the pipeline bus with details of the element, the property and the new +property value, all of which can be retrieved later from the message in the +application via [`gst_message_parse_property_notify()`][parse-notify]. Unlike +the GstBus watch functions, this API does not rely on a running GLib main loop. + +The above can be used to be notified asynchronously of caps changes in the +pipeline, or volume changes on an audio sink element, for example. + +[notify-watch]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#gst-element-add-property-notify-watch +[deep-notify-watch]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#gst-element-add-property-deep-notify-watch +[parse-notify]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html#gst-message-parse-property-notify + +##### GstBin "deep" element-added and element-removed signals + +GstBin has gained `"deep-element-added"` and `"deep-element-removed"` signals +which makes it easier for applications and higher-level plugins to track when +elements are added or removed from a complex pipeline with multiple sub-bins. + +`playbin` makes use of this to implement the new `"element-setup"` signal which +can be used to configure elements as they are added to `playbin`, just like the +existing `"source-setup"` signal which can be used to configure the source +element created. + +##### Error messages can contain additional structured details + +It is often useful to provide additional, structured information in error, +warning or info messages for applications (or higher-level elements) to make +intelligent decisions based on them. To allow this, error, warning and info +messages now have API for adding arbitrary additional information to them +using a `GstStructure`: +[`GST_ELEMENT_ERROR_WITH_DETAILS`][element-error-with-details] and +corresponding API for the other message types. + +This is now used e.g. by the new [`GST_ELEMENT_FLOW_ERROR`][element-flow-error] +API to include the actual flow error in the error message, and the +[souphttpsrc element][souphttpsrc-detailed-errors] to provide the HTTP +status code, and the URL (if any) to which a redirection has happened. + +[element-error-with-details]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#GST-ELEMENT-ERROR-WITH-DETAILS:CAPS +[element-flow-error]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#GST-ELEMENT-FLOW-ERROR:CAPS +[souphttpsrc-detailed-errors]: https://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/ext/soup/gstsouphttpsrc.c?id=60d30db912a1aedd743e66b9dcd2e21d71fbb24f#n1318 + +##### Redirect messages have official API now + +Sometimes, elements need to redirect the current stream URL and tell the +application to proceed with this new URL, possibly using a different +protocol too (thus changing the pipeline configuration). Until now, this was +informally implemented using `ELEMENT` messages on the bus. + +Now this has been formalized in the form of a new `GST_MESSAGE_REDIRECT` message. +A new redirect message can be created using [`gst_message_new_redirect()`][new-redirect]. +If needed, multiple redirect locations can be specified by calling +[`gst_message_add_redirect_entry()`][add-redirect] to add further redirect +entries, all with metadata, so the application can decide which is +most suitable (e.g. depending on the bitrate tags). + +[new-redirect]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html#gst-message-new-redirect +[add-redirect]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html#gst-message-add-redirect-entry + +##### New pad linking convenience functions that automatically create ghost pads + +New pad linking convenience functions were added: +[`gst_pad_link_maybe_ghosting()`][pad-maybe-ghost] and +[`gst_pad_link_maybe_ghosting_full()`][pad-maybe-ghost-full] which were +previously internal to GStreamer have now been exposed for general use. + +The existing pad link functions will refuse to link pads or elements at +different levels in the pipeline hierarchy, requiring the developer to +create ghost pads where necessary. These new utility functions will +automatically create ghostpads as needed when linking pads at different +levels of the hierarchy (e.g. from an element inside a bin to one that's at +the same level in the hierarchy as the bin, or in another bin). + +[pad-maybe-ghost]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPad.html#gst-pad-link-maybe-ghosting +[pad-maybe-ghost-full]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPad.html#gst-pad-link-maybe-ghosting-full + +##### Miscellaneous + +Pad probes: IDLE and BLOCK probes now work slightly differently in pull mode, +so that push and pull mode have opposite scenarios for idle and blocking probes. +In push mode, it will block with some data type and IDLE won't have any data. +In pull mode, it will block _before_ getting a buffer and will be IDLE once some +data has been obtained. ([commit][commit-pad-probes], [bug][bug-pad-probes]) + +[commit-pad-probes]: https://cgit.freedesktop.org/gstreamer/gstreamer/commit/gst/gstpad.c?id=368ee8a336d0c868d81fdace54b24431a8b48cbf +[bug-pad-probes]: https://bugzilla.gnome.org/show_bug.cgi?id=761211 + +[`gst_parse_launch_full()`][parse-launch-full] can now be made to return a +`GstBin` instead of a top-level pipeline by passing the new +`GST_PARSE_FLAG_PLACE_IN_BIN` flag. + +[parse-launch-full]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstParse.html#gst-parse-launch-full + +The default GStreamer debug log handler can now be removed before +calling `gst_init()`, so that it will never get installed and won't be active +during initialization. + +A new [`STREAM_GROUP_DONE` event][stream-group-done-event] was added. In some +ways it works similar to the `EOS` event in that it can be used to unblock +downstream elements which may be waiting for further data, such as for example +`input-selector`. Unlike `EOS`, further data flow may happen after the +`STREAM_GROUP_DONE` event though (and without the need to flush the pipeline). +This is used to unblock input-selector when switching between streams in +adaptive streaming scenarios (e.g. HLS). + +[stream-group-done-event]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstEvent.html#gst-event-new-stream-group-done + +The `gst-launch-1.0` command line tool will now print unescaped caps in verbose +mode (enabled by the -v switch). + +[`gst_element_call_async()`][call-async] has been added as convenience API for +plugin developers. It is useful for one-shot operations that need to be done +from a thread other than the current streaming thread. It is backed by a +thread-pool that is shared by all elements. + +[call-async]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#gst-element-call-async + +Various race conditions have been fixed around the `GstPoll` API used by e.g. +`GstBus` and `GstBufferPool`. Some of these manifested themselves primarily +on Windows. + +`GstAdapter` can now keep track of discontinuities signalled via the `DISCONT` +buffer flag, and has gained [new API][new-adapter-api] to track PTS, DTS and +offset at the last discont. This is useful for plugins implementing advanced +trick mode scenarios. + +[new-adapter-api]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstAdapter.html#gst-adapter-pts-at-discont + +`GstTestClock` gained a new [`"clock-type"` property][clock-type-prop]. + +[clock-type-prop]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstTestClock.html#GstTestClock--clock-type + +#### GstStream API for stream announcement and stream selection + +New stream listing and stream selection API: new API has been added to +provide high-level abstractions for streams ([`GstStream`][stream-api]) +and collections of streams ([`GstStreamCollections`][stream-collection-api]). + +##### Stream listing + +A [`GstStream`][stream-api] contains all the information pertinent to a stream, +such as stream id, caps, tags, flags and stream type(s); it can represent a +single elementary stream (e.g. audio, video, subtitles, etc.) or a container +stream. This will depend on the context. In a decodebin3/playbin3 one +it will typically be elementary streams that can be selected and unselected. + +A [`GstStreamCollection`][stream-collection-api] represents a group of streams +and is used to announce or publish all available streams. A GstStreamCollection +is immutable - once created it won't change. If the available streams change, +e.g. because a new stream appeared or some streams disappeared, a new stream +collection will be published. This new stream collection may contain streams +from the previous collection if those streams persist, or completely new ones. +Stream collections do not yet list all theoretically available streams, +e.g. other available DVD angles or alternative resolutions/bitrate of the same +stream in case of adaptive streaming. + +New events and messages have been added to notify or update other elements and +the application about which streams are currently available and/or selected. +This way, we can easily and seamlessly let the application know whenever the +available streams change, as happens frequently with digital television streams +for example. The new system is also more flexible. For example, it is now also +possible for the application to select multiple streams of the same type +(e.g. in a transcoding/transmuxing scenario). + +A [`STREAM_COLLECTION` message][stream-collection-msg] is posted on the bus +to inform the parent bin (e.g. `playbin3`, `decodebin3`) and/or the application +about what streams are available, so you no longer have to hunt for this +information at different places. The available information includes number of +streams of each type, caps, tags etc. Bins and/or the application can intercept +the message synchronously to select and deselect streams before any data is +produced - for the case where elements such as the demuxers support the new +stream API, not necessarily in the parsebin compatibility fallback case. + +Similarly, there is also a [`STREAM_COLLECTION` event][stream-collection-event] +to inform downstream elements of the available streams. This event can be used +by elements to aggregate streams from multiple inputs into one single collection. + +The `STREAM_START` event was extended so that it can also contain a GstStream +object with all information about the current stream, see +[`gst_event_set_stream()`][event-set-stream] and +[`gst_event_parse_stream()`][event-parse-stream]. +[`gst_pad_get_stream()`][pad-get-stream] is a new utility function that can be +used to look up the GstStream from the `STREAM_START` sticky event on a pad. + +[stream-api]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstStream.html +[stream-collection-api]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstStreamCollection.html +[stream-collection-msg]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html#gst-message-new-stream-collection +[stream-collection-event]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstEvent.html#gst-event-new-stream-collection +[event-set-stream]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstEvent.html#gst-event-set-stream +[event-parse-stream]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstEvent.html#gst-event-parse-stream +[pad-get-stream]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPad.html#gst-pad-get-stream + +##### Stream selection + +Once the available streams have been published, streams can be selected via +their stream ID using the new `SELECT_STREAMS` event, which can be created +with [`gst_event_new_select_streams()`][event-select-streams]. The new API +supports selecting multiple streams per stream type. In the future, we may also +implement explicit deselection of streams that will never be used, so +elements can skip these and never expose them or output data for them in the +first place. + +The application is then notified of the currently selected streams via the +new `STREAMS_SELECTED` message on the pipeline bus, containing both the current +stream collection as well as the selected streams. This might be posted in +response to the application sending a `SELECT_STREAMS` event or when +`decodebin3` or `playbin3` decide on the streams to be initially selected without +application input. + +[event-select-streams]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstEvent.html#gst-event-new-select-streams + +##### Further reading + +See further below for some notes on the new elements supporting this new +stream API, namely: `decodebin3`, `playbin3` and `parsebin`. + +More information about the new API and the new elements can also be found here: + +- GStreamer [stream selection design docs][streams-design] +- Edward Hervey's talk ["The new streams API: Design and usage"][streams-talk] ([slides][streams-slides]) +- Edward Hervey's talk ["Decodebin3: Dealing with modern playback use cases"][db3-talk] ([slides][db3-slides]) + +[streams-design]: https://cgit.freedesktop.org/gstreamer/gstreamer/tree/docs/design/part-stream-selection.txt +[streams-talk]: https://gstconf.ubicast.tv/videos/the-new-gststream-api-design-and-usage/ +[streams-slides]: https://gstreamer.freedesktop.org/data/events/gstreamer-conference/2016/Edward%20Hervey%20-%20The%20New%20Streams%20API%20Design%20and%20Usage.pdf +[db3-talk]: https://gstconf.ubicast.tv/videos/decodebin3-or-dealing-with-modern-playback-use-cases/ +[db3-slides]: https://gstreamer.freedesktop.org/data/events/gstreamer-conference/2015/Edward%20Hervey%20-%20decodebin3.pdf + +#### Audio conversion and resampling API + +The audio conversion library received a completely new and rewritten audio +resampler, complementing the audio conversion routines moved into the audio +library in the [previous release][release-notes-1.8]. Integrating the resampler +with the other audio conversion library allows us to implement generic +conversion much more efficiently, as format conversion and resampling can now +be done in the same processing loop instead of having to do it in separate +steps (our element implementations do not make use of this yet though). + +The new audio resampler library is a combination of some of the best features +of other samplers such as ffmpeg, speex and SRC. It natively supports S16, S32, +F32 and F64 formats and uses optimized x86 and neon assembly for most of its +processing. It also has support for dynamically changing sample rates by incrementally +updating the filter tables using linear or cubic interpolation. According to +some benchmarks, it's one of the fastest and most accurate resamplers around. + +The `audioresample` plugin has been ported to the new audio library functions +to make use of the new resampler. + +[release-notes-1.8]: https://gstreamer.freedesktop.org/releases/1.8/ + +#### Support for SMPTE timecodes + +Support for SMPTE timecodes was added to the GStreamer video library. This +comes with an abstraction for timecodes, [`GstVideoTimeCode`][video-timecode] +and a [`GstMeta`][video-timecode-meta] that can be placed on video buffers for +carrying the timecode information for each frame. Additionally there is +various API for making handling of timecodes easy and to do various +calculations with them. + +A new plugin called [`timecode`][timecode-plugin] was added, that contains an +element called `timecodestamper` for putting the timecode meta on video frames +based on counting the frames and another element called `timecodewait` that +drops all video (and audio) until a specific timecode is reached. + +Additionally support was added to the Decklink plugin for including the +timecode information when sending video out or capturing it via SDI, the +`qtmux` element is able to write timecode information into the MOV container, +and the `timeoverlay` element can overlay timecodes on top of the video. + +More information can be found in the [talk about timecodes][timecode-talk] at +the GStreamer Conference 2016. + +[video-timecode]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode +[video-timecode-meta]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideometa.html#gst-buffer-add-video-time-code-meta +[timecode-plugin]: https://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/gst/timecode +[timecode-talk]: https://gstconf.ubicast.tv/videos/smpte-timecodes-in-gstreamer/ + +#### GStreamer OpenMAX IL plugin + +The last gst-omx release, 1.2.0, was in July 2014. It was about time to get +a new one out with all the improvements that have happened in the meantime. +From now on, we will try to release gst-omx together with all other modules. + +This release features a lot of bugfixes, improved support for the Raspberry Pi +and in general improved support for zerocopy rendering via EGL and a few minor +new features. + +At this point, gst-omx is known to work best on the Raspberry Pi platform but +it is also known to work on various other platforms. Unfortunately, we are +not including configurations for any other platforms, so if you happen to use +gst-omx: please send us patches with your configuration and code changes! + +### New Elements + +#### decodebin3, playbin3, parsebin (experimental) + +This release features new decoding and playback elements as experimental +technology previews: `decodebin3` and `playbin3` will soon supersede the +existing `decodebin` and `playbin` elements. We skipped the number 2 because +it was already used back in the 0.10 days, which might cause confusion. +Experimental technology preview means that everything should work fine already, +but we can't guarantee there won't be minor behavioural changes in the +next cycle. In any case, please test and report any problems back. + +Before we go into detail about what these new elements improve, let's look at +the new [`parsebin`][parsebin] element. It works similarly to `decodebin` and +`decodebin3`, only that it stops one step short and does not plug any actual +decoder elements. It will only plug parsers, tag readers, demuxers and +depayloaders. Also note that parsebin does not contain any queueing element. + +[`decodebin3`'s][decodebin3] internal architecture is slightly different from +the existing `decodebin` element and fixes many long-standing issues with our +decoding engine. For one, data is now fed into the internal `multiqueue` element +*after* it has been parsed and timestamped, which means that the `multiqueue` +element now has more knowledge and is able to calculate the interleaving of the +various streams, thus minimizing memory requirements and doing away with magic +values for buffering limits that were conceived when videos were 240p or 360p. +Anyone who has tried to play back 4k video streams with decodebin2 +will have noticed the limitations of that approach. The improved timestamp +tracking also enables `multiqueue` to keep streams of the same type (audio, +video) aligned better, making sure switching between streams of the same type +is very fast. + +Another major improvement in `decodebin3` is that it will no longer decode +streams that are not being used. With the old `decodebin` and `playbin`, when +there were 8 audio streams we would always decode all 8 streams even +if 7 were not actually used. This caused a lot of CPU overhead, which was +particularly problematic on embedded devices. When switching between streams +`decodebin3` will try hard to re-use existing decoders. This is useful when +switching between multiple streams of the same type if they are encoded in the +same format. + +Re-using decoders is also useful when the available streams change on the fly, +as might happen with radio streams (chained Oggs), digital television +broadcasts, when adaptive streaming streams change bitrate, or when switching +gaplessly to the next title. In order to guarantee a seamless transition, the +old `decodebin2` would plug a second decoder for the new stream while finishing +up the old stream. With `decodebin3`, this is no longer needed - at least not +when the new and old format are the same. This will be particularly useful +on embedded systems where it is often not possible to run multiple decoders +at the same time, or when tearing down and setting up decoders is fairly +expensive. + +`decodebin3` also allows for multiple input streams, not just a single one. +This will be useful, in the future, for gapless playback, or for feeding +multiple external subtitle streams to decodebin/playbin. + +`playbin3` uses `decodebin3` internally, and will supercede `playbin`. +It was decided that it would be too risky to make the old `playbin` use the +new `decodebin3` in a backwards-compatible way. The new architecture +makes it awkward, if not impossible, to maintain perfect backwards compatibility +in some aspects, hence `playbin3` was born, and developers can migrate to the +new element and new API at their own pace. + +All of these new elements make use of the new `GstStream` API for listing and +selecting streams, as described above. `parsebin` provides backwards +compatibility for demuxers and parsers which do not advertise their streams +using the new API yet (which is most). + +The new elements are not entirely feature-complete yet: `playbin3` does not +support so-called decodersinks yet where the data is not decoded inside +GStreamer but passed directly for decoding to the sink. `decodebin3` is missing +the various `autoplug-*` signals to influence which decoders get autoplugged +in which order. We're looking to add back this functionality, but it will probably +be in a different way, with a single unified signal and using GstStream perhaps. + +For more information on these new elements, check out Edward Hervey's talk +[*decodebin3 - dealing with modern playback use cases*][db3-talk] + +[parsebin]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-parsebin.html +[decodebin3]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-decodebin3.html +[db3-talk]: https://gstconf.ubicast.tv/videos/decodebin3-or-dealing-with-modern-playback-use-cases/ + +#### LV2 ported from 0.10 and switched from slv2 to lilv2 + +The LV2 wrapper plugin has been ported to 1.0 and moved from using the +deprecated slv2 library to its replacement liblv2. We support sources and +filter elements. lv2 is short for *Linux Audio Developer's Simple Plugin API +(LADSPA) version 2* and is an open standard for audio plugins which includes +support for audio synthesis (generation), digital signal processing of digital +audio, and MIDI. The new lv2 plugin supersedes the existing LADSPA plugin. + +#### WebRTC DSP Plugin for echo-cancellation, gain control and noise suppression + +A set of new elements ([webrtcdsp][webrtcdsp], [webrtcechoprobe][webrtcechoprobe]) +based on the WebRTC DSP software stack can now be used to improve your audio +voice communication pipelines. They support echo cancellation, gain control, +noise suppression and more. For more details you may read +[Nicolas' blog post][webrtc-blog-post]. + +[webrtcdsp]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-webrtcdsp.html +[webrtcechoprobe]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-webrtcechoprobe.html +[webrtc-blog-post]: https://ndufresne.ca/2016/06/gstreamer-echo-canceller/ + +#### Fraunhofer FDK AAC encoder and decoder + +New encoder and decoder elements wrapping the Fraunhofer FDK AAC library have +been added (`fdkaacdec`, `fdkaacdec`). The Fraunhofer FDK AAC encoder is +generally considered to be a very high-quality AAC encoder, but unfortunately +it comes under a non-free license with the option to obtain a paid, commercial +license. + +### Noteworthy element features and additions + +#### Major RTP and RTSP improvements + +- The RTSP server and source element, as well as the RTP jitterbuffer now support + remote clock synchronization according to [RFC7273][https://tools.ietf.org/html/rfc7273]. +- Support for application and profile specific RTCP packets was added. +- The H265/HEVC payloader/depayloader is again in sync with the final RFC. +- Seeking stability of the RTSP source and server was improved a lot and + runs stably now, even when doing scrub-seeking. +- The RTSP server received various major bugfixes, including for regressions that + caused the IP/port address pool to not be considered, or NAT hole punching + to not work anymore. [Bugzilla #766612][https://bugzilla.gnome.org/show_bug.cgi?id=766612] +- Various other bugfixes that improve the stability of RTP and RTSP, including + many new unit / integration tests. + +#### Improvements to splitmuxsrc and splitmuxsink + +- The splitmux element received reliability and error handling improvements, + removing at least one deadlock case. `splitmuxsrc` now stops cleanly at the end + of the segment when handling seeks with a stop time. We fixed a bug with large + amounts of downstream buffering causing incorrect out-of-sequence playback. + +- `splitmuxsrc` now has a `"format-location"` signal to directly specify the list + of files to play from. + +- `splitmuxsink` can now optionally send force-keyunit events to upstream + elements to allow splitting files more accurately instead of having to wait + for upstream to provide a new keyframe by itself. + +#### OpenGL/GLES improvements + +##### iOS and macOS (OS/X) + +- We now create OpenGL|ES 3.x contexts on iOS by default with a fallback to + OpenGL|ES 2.x if that fails. +- Various zerocopy decoding fixes and enhancements with the + encoding/decoding/capturing elements. +- libdispatch is now used on all Apple platforms instead of GMainLoop, removing + the expensive poll()/pthread_*() overhead. + +##### New API + +- `GstGLFramebuffer` - for wrapping OpenGL frame buffer objects. It provides + facilities for attaching `GstGLMemory` objects to the necessary attachment + points, binding and unbinding and running a user-supplied function with the + framebuffer bound. +- `GstGLRenderbuffer` (a `GstGLBaseMemory` subclass) - for wrapping OpenGL + render buffer objects that are typically used for depth/stencil buffers or + for color buffers where we don't care about the output. +- `GstGLMemoryEGL` (a `GstGLMemory` subclass) - for combining `EGLImage`s with a GL + texture that replaces `GstEGLImageMemory` bringing the improvements made to the + other `GstGLMemory` implementations. This fixes a performance regression in + zerocopy decoding on the Raspberry Pi when used with an updated gst-omx. + +##### Miscellaneous improvements + +- `gltestsrc` is now usable on devices/platforms with OpenGL 3.x and OpenGL|ES + and has completed or gained support for new patterns in line with the + existing ones in `videotestsrc`. +- `gldeinterlace` is now available on devices/platforms with OpenGL|ES + implementations. +- The dispmanx backend (used on the Raspberry Pi) now supports the + `gst_video_overlay_set_window_handle()` and + `gst_video_overlay_set_render_rectangle()` functions. +- The `gltransformation` element now correctly transforms mouse coordinates (in + window space) to stream coordinates for both perspective and orthographic + projections. +- The `gltransformation` element now detects if the + `GstVideoAffineTransformationMeta` is supported downstream and will efficiently + pass its transformation downstream. This is a performance improvement as it + results in less processing being required. +- The wayland implementation now uses the multi-threaded safe event-loop API + allowing correct usage in applications that call wayland functions from + multiple threads. +- Support for native 90 degree rotations and horizontal/vertical flips + in `glimagesink`. + +#### Vulkan + +- The Vulkan elements now work under Wayland and have received numerous + bugfixes. + +#### QML elements + +- `qmlglsink` video sink now works on more platforms, notably, Windows, Wayland, + and Qt's eglfs (for embedded devices with an OpenGL implementation) including + the Raspberry Pi. +- New element `qmlglsrc` to record a QML scene into a GStreamer pipeline. + +#### KMS video sink + +- New element `kmssink` to render video using Direct Rendering Manager + (DRM) and Kernel Mode Setting (KMS) subsystems in the Linux + kernel. It is oriented to be used mostly in embedded systems. + +#### Wayland video sink + +- `waylandsink` now supports the wl_viewporter extension allowing + video scaling and cropping to be delegated to the Wayland + compositor. This extension is also been made optional, so that it can + also work on current compositors that don't support it. It also now has + support for the video meta, allowing zero-copy operations in more + cases. + +#### DVB improvements + +- `dvbsrc` now has better delivery-system autodetection and several + new parameter sanity-checks to improve its resilience to configuration + omissions and errors. Superfluous polling continues to be trimmed down, + and the debugging output has been made more consistent and precise. + Additionally, the channel-configuration parser now supports the new dvbv5 + format, enabling `dvbbasebin` to automatically playback content transmitted + on delivery systems that previously required manual description, like ISDB-T. + +#### DASH, HLS and adaptivedemux + +- HLS now has support for Alternate Rendition audio and video tracks. Full + support for Alternate Rendition subtitle tracks will be in an upcoming release. +- DASH received support for keyframe-only trick modes if the + `GST_SEEK_FLAG_TRICKMODE_KEY_UNITS` flag is given when seeking. It will + only download keyframes then, which should help with high-speed playback. + Changes to skip over multiple frames based on bandwidth and other metrics + will be added in the near future. +- Lots of reliability fixes around seek handling and bitrate switching. + +#### Bluetooth improvements + +- The `avdtpsrc` element now supports metadata such as track title, artist + name, and more, which devices can send via AVRCP. These are published as + tags on the pipeline. +- The `a2dpsink` element received some love and was cleaned up so that it + actually works after the initial GStreamer 1.0 port. + +#### GStreamer VAAPI + +- All the decoders have been split, one plugin feature per codec. So + far, the available ones, depending on the driver, are: + `vaapimpeg2dec`, `vaapih264dec`, `vaapih265dec`, `vaapivc1dec`, `vaapivp8dec`, + `vaapivp9dec` and `vaapijpegdec` (which already was split). +- Improvements when mapping VA surfaces into memory. It now differentiates + between negotiation caps and allocations caps, since the allocation + memory for surfaces may be bigger than one that is going to be + mapped. +- `vaapih265enc` now supports constant bitrate mode (CBR). +- Since several VA drivers are unmaintained, we decide to keep a whitelist + with the va drivers we actually test, which is mostly the i915 and to a lesser + degree gallium from the mesa project. Exporting the environment variable + `GST_VAAPI_ALL_DRIVERS` disables the whitelist. +- Plugin features are registered at run-time, according to their support by + the loaded VA driver. So only the decoders and encoder supported by the + system are registered. Since the driver can change, some dependencies are + tracked to invalidate the GStreamer registry and reload the plugin. +- `dmabuf` importation from upstream has been improved, gaining performance. +- `vaapipostproc` now can negotiate buffer transformations via caps. +- Decoders now can do I-frame only reverse playback. This decodes I-frames + only because the surface pool is smaller than the required by the GOP to show all the + frames. +- The upload of frames onto native GL textures has been optimized too, keeping + a cache of the internal structures for the offered textures by the sink. + +#### V4L2 changes + +- More pixels formats are now supported +- Decoder is now using `G_SELECTION` instead of the deprecated `G_CROP` +- Decoder now uses the `STOP` command to handle EOS +- Transform element can now scale the pixel aspect ratio +- Colorimetry support has been improved even more +- We now support the `OUTPUT_OVERLAY` type of video node in v4l2sink + +#### Miscellaneous + +- `multiqueue`'s input pads gained a new `"group-id"` property which + can be used to group input streams. Typically one will assign + different id numbers to audio, video and subtitle streams for + example. This way `multiqueue` can make sure streams of the same + type advance in lockstep if some of the streams are unlinked and the + `"sync-by-running-time"` property is set. This is used in + decodebin3/playbin3 to implement almost-instantaneous stream + switching. The grouping is required because different downstream + paths (audio, video, etc.) may have different buffering/latency + etc. so might be consuming data from multiqueue with a slightly + different phase, and if we track different stream groups separately + we minimize stream switching delays and buffering inside the + `multiqueue`. +- `alsasrc` now supports ALSA drivers without a position for each + channel, this is common in some professional or industrial hardware. +- `libvpx` based decoders (`vp8dec` and `vp9dec`) now create multiple threads on + computers with multiple CPUs automatically. +- `rfbsrc` - used for capturing from a VNC server - has seen a lot of + debugging. It now supports the latest version of the RFB + protocol and uses GIO everywhere. +- `tsdemux` can now read ATSC E-AC-3 streams. +- New `GstVideoDirection` video orientation interface for rotating, flipping + and mirroring video in 90° steps. It is implemented by the `videoflip` and + `glvideoflip` elements currently. +- It is now possible to give `appsrc` a duration in time, and there is now a + non-blocking try-pull API for `appsink` that returns NULL if nothing is + available right now. +- `x264enc` has support now for chroma-site and colorimetry settings +- A new JPEG2000 parser element was added, and the JPEG2000 caps were cleaned + up and gained more information needed in combination with RTP and various + container formats. +- Reverse playback support for `videorate` and `deinterlace` was implemented +- Various improvements everywhere for reverse playback and `KEY_UNITS` trick mode +- New cleaned up `rawaudioparse` and `rawvideoparse` elements that replace the + old `audioparse` and `videoparse` elements. There are compatibility element + factories registered with the old names to allow existing code to continue + to work. +- The Decklink plugin gained support for 10 bit video SMPTE timecodes, and + generally got many bugfixes for various issues. +- New API in `GstPlayer` for setting the multiview mode for stereoscopic + video, setting an HTTP/RTSP user agent and a time offset between audio and + video. In addition to that, there were various bugfixes and the new + gst-examples module contains Android, iOS, GTK+ and Qt example applications. +- `GstBin` has new API for suppressing various `GstElement` or `GstObject` + flags that would otherwise be affected by added/removed child elements. This + new API allows `GstBin` subclasses to handle for themselves if they + should be considered a sink or source element, for example. +- The `subparse` element can handle WebVTT streams now. +- A new `sdpsrc` element was added that can read an SDP from a file, or get it + as a string as property and then sets up an RTP pipeline accordingly. + +### Plugin moves + +No plugins were moved this cycle. We'll make up for it next cycle, promise! + +### Rewritten memory leak tracer + +GStreamer has had basic functionality to trace allocation and freeing of +both mini-objects (buffers, events, caps, etc.) and objects in the form of the +internal `GstAllocTrace` tracing system. This API was never exposed in the +1.x API series though. When requested, this would dump a list of objects and +mini-objects at exit time which had still not been freed at that point, +enabled with an environment variable. This subsystem has now been removed +in favour of a new implementation based on the recently-added tracing framework. + +Tracing hooks have been added to trace the creation and destruction of +GstObjects and mini-objects, and a new tracer plugin has been written using +those new hooks to track which objects are still live and which are not. If +GStreamer has been compiled against the libunwind library, the new leaks tracer +will remember where objects were allocated from as well. By default the leaks +tracer will simply output a warning if leaks have been detected on `gst_deinit()`. + +If the `GST_LEAKS_TRACER_SIG` environment variable is set, the leaks tracer +will also handle the following UNIX signals: + + - `SIGUSR1`: log alive objects + - `SIGUSR2`: create a checkpoint and print a list of objects created and + destroyed since the previous checkpoint. + +Unfortunately this will not work on Windows due to no signals, however. + +If the `GST_LEAKS_TRACER_STACK_TRACE` environment variable is set, the leaks +tracer will also log the creation stack trace of leaked objects. This may +significantly increase memory consumption however. + +New `MAY_BE_LEAKED` flags have been added to GstObject and GstMiniObject, so +that objects and mini-objects that are likely to stay around forever can be +flagged and blacklisted from the leak output. + +To give the new leak tracer a spin, simply call any GStreamer application such +as `gst-launch-1.0` or `gst-play-1.0` like this: + + GST_TRACERS=leaks gst-launch-1.0 videotestsrc num-buffers=10 ! fakesink + +If there are any leaks, a warning will be raised at the end. + +It is also possible to trace only certain types of objects or mini-objects: + + GST_TRACERS="leaks(GstEvent,GstMessage)" gst-launch-1.0 videotestsrc num-buffers=10 ! fakesink + +This dedicated leaks tracer is much much faster than valgrind since all code is +executed natively instead of being instrumented. This makes it very suitable +for use on slow machines or embedded devices. It is however limited to certain +types of leaks and won't catch memory leaks when the allocation has been made +via plain old `malloc()` or `g_malloc()` or other means. It will also not trace +non-GstObject GObjects. + +The goal is to enable leak tracing on GStreamer's Continuous-Integration and +testing system, both for the regular unit tests (make check) and media tests +(gst-validate), so that accidental leaks in common code paths can be detected +and fixed quickly. + +For more information about the new tracer, check out Guillaume Desmottes's +["Tracking Memory Leaks"][leaks-talk] talk or his [blog post][leaks-blog] about +the topic. + +[leaks-talk]: https://gstconf.ubicast.tv/videos/tracking-memory-leaks/ +[leaks-blog]: https://blog.desmottes.be/?post/2016/06/20/GStreamer-leaks-tracer + +### GES and NLE changes + +- Clip priorities are now handled by the layers, and the GESTimelineElement + priority property is now deprecated and unused +- Enhanced (de)interlacing support to always use the `deinterlace` element + and expose needed properties to users +- Allow reusing clips children after removing the clip from a layer +- We are now testing many more rendering formats in the gst-validate + test suite, and failures have been fixed. +- Also many bugs have been fixed in this cycle! + +### GStreamer validate changes + +This cycle has been focused on making GstValidate more than just a validating +tool, but also a tool to help developers debug their GStreamer issues. When +reporting issues, we try to gather as much information as possible and expose +it to end users in a useful way. For an example of such enhancements, check out +Thibault Saunier's [blog post](improving-debugging-gstreamer-validate) about +the new Not Negotiated Error reporting mechanism. + +Playbin3 support has been added so we can run validate tests with `playbin3` +instead of playbin. + +We are now able to properly communicate between `gst-validate-launcher` and +launched subprocesses with actual IPC between them. That has enabled the test +launcher to handle failing tests specifying the exact expected issue(s). + +[improving-debugging-gstreamer-validate]: https://blogs.s-osg.org/improving-debugging-gstreamer-validate/ + +### gst-libav changes + +gst-libav uses the recently released ffmpeg 3.2 now, which brings a lot of +improvements and bugfixes from the ffmpeg team in addition to various new +codec mappings on the GStreamer side and quite a few bugfixes to the GStreamer +integration to make it more robust. + +## Build and Dependencies + +### Experimental support for Meson as build system + +#### Overview + +We have have added support for building GStreamer using the +[Meson build system][meson]. This is currently experimental, but should work +fine at least on Linux using the gcc or clang toolchains and on Windows using +the MingW or MSVC toolchains. + +Autotools remains the primary build system for the time being, but we hope to +someday replace it and will steadily work towards that goal. + +More information about the background and implications of all this and where +we're hoping to go in future with this can be found in [Tim's mail][meson-mail] +to the gstreamer-devel mailing list. + +For more information on Meson check out [these videos][meson-videos] and also +the [Meson talk][meson-gstconf] at the GStreamer Conference. + +Immediate benefits for Linux users are faster builds and rebuilds. At the time +of writing the Meson build of GStreamer is used by default in GNOME's jhbuild +system. + +The Meson build currently still lacks many of the fine-grained configuration +options to enable/disable specific plugins. These will be added back in due +course. + +Note: The meson build files are not distributed in the source tarballs, you will +need to get GStreamer from git if you want try it out. + +[meson]: http://mesonbuild.com/ +[meson-mail]: https://lists.freedesktop.org/archives/gstreamer-devel/2016-September/060231.html +[meson-videos]: http://mesonbuild.com/videos.html +[meson-gstconf]: https://gstconf.ubicast.tv/videos/gstreamer-development-on-windows-ans-faster-builds-everywhere-with-meson/ + +#### Windows Visual Studio toolchain support + +Windows users might appreciate being able to build GStreamer using the MSVC +toolchain, which is not possible using autotools. This means that it will be +possible to debug GStreamer and applications in Visual Studio, for example. +We require VS2015 or newer for this at the moment. + +There are two ways to build GStreamer using the MSVC toolchain: + +1. Using the MSVC command-line tools (`cl.exe` etc.) via Meson's "ninja" backend. +2. Letting Meson's "vs2015" backend generate Visual Studio project files that + can be opened in Visual Studio and compiled from there. + +This is currently only for adventurous souls though. All the bits are in place, +but support for all of this has not been merged into GStreamer's cerbero build +tool yet at the time of writing. This will hopefully happen in the next cycle, +but for now this means that those wishing to compile GStreamer with MSVC will +have to get their hands dirty. + +There are also no binary SDK builds using the MSVC toolchain yet. + +For more information on GStreamer builds using Meson and the Windows toolchain +check out Nirbheek Chauhan's blog post ["Building and developing GStreamer using Visual Studio"][msvc-blog]. + +[msvc-blog]: http://blog.nirbheek.in/2016/07/building-and-developing-gstreamer-using.html + +### Dependencies + +#### gstreamer + +libunwind was added as an optional dependency. It is used only for debugging +and tracing purposes. + +The `opencv` plugin in gst-plugins-bad can now be built against OpenCV +version 3.1, previously only 2.3-2.5 were supported. + +#### gst-plugins-ugly + +- `mpeg2dec` now requires at least libmpeg2 0.5.1 (from 2008). + +#### gst-plugins-bad + +- `gltransformation` now requires at least graphene 1.4.0. + +- `lv2` now plugin requires at least lilv 0.16 instead of slv2. + +### Packaging notes + +Packagers please note that the `gst/gstconfig.h` public header file in the +GStreamer core library moved back from being an architecture dependent include +to being architecture independent, and thus it is no longer installed into +`$(libdir)/gstreamer-1.0/include/gst` but into the normal include directory +where it lives happily ever after with all the other public header files. The +reason for this is that we now check whether the target supports unaligned +memory access based on predefined compiler macros at compile time instead of +checking it at configure time. + +## Platform-specific improvements + +### Android + +#### New universal binaries for all supported ABIs + +We now provide a "universal" tarball to allow building apps against all the +architectures currently supported (x86, x86-64, armeabi, armeabi-v7a, +armeabi-v8a). This is needed for building with recent versions of the Android +NDK which defaults to building against all supported ABIs. Use [the Android +player example][android-player-example-build] as a reference for the required +changes. + +[android-player-example-build]: https://cgit.freedesktop.org/gstreamer/gst-examples/commit/playback/player/android?id=a5cdde9119f038a1eb365aca20faa9741a38e788 + +#### Miscellaneous + +- New `ahssrc` element that allows reading the hardware sensors, e.g. compass + or accelerometer. + +### macOS (OS/X) and iOS + +- Support for querying available devices on OS/X via the GstDeviceProvider + API was added. +- It is now possible to create OpenGL|ES 3.x contexts on iOS and use them in + combination with the VideoToolbox based decoder element. +- many OpenGL/GLES improvements, see OpenGL section above + +### Windows + +- gstconfig.h: Always use dllexport/import on Windows with MSVC +- Miscellaneous fixes to make libs and plugins compile with the MVSC toolchain +- MSVC toolchain support (see Meson section above for more details) + +## New Modules for Documentation, Examples, Meson Build + +Three new git modules have been added recently: + +### gst-docs + +This is a new module where we will maintain documentation in the markdown +format. + +It contains the former gstreamer.com SDK tutorials which have kindly been made +available by Fluendo under a Creative Commons license. The tutorials have been +reviewed and updated for GStreamer 1.x and will be available as part of the +[official GStreamer documentation][doc] going forward. The old gstreamer.com +site will then be shut down with redirects pointing to the updated tutorials. + +Some of the existing docbook XML-formatted documentation from the GStreamer +core module such as the *Application Development Manual* and the *Plugin +Writer's Guide* have been converted to markdown as well and will be maintained +in the gst-docs module in future. They will be removed from the GStreamer core +module in the next cycle. + +This is just the beginning. Our goal is to provide a more cohesive documentation +experience for our users going forward, and easier to create and maintain +documentation for developers. There is a lot more work to do, get in touch if +you want to help out. + +If you encounter any problems or spot any omissions or outdated content in the +new documentation, please [file a bug in bugzilla][doc-bug] to let us know. + +We will probably release gst-docs as a separate tarball for distributions to +package in the next cycle. + +[doc]: http://gstreamer.freedesktop.org/documentation/ +[doc-bug]: https://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer&component=documentation + +### gst-examples + +A new [module][examples-git] has been added for examples. It does not contain +much yet, currently it only contains a small [http-launch][http-launch] utility +that serves a pipeline over http as well as various [GstPlayer playback frontends][puis] +for Android, iOS, Gtk+ and Qt. + +More examples will be added over time. The examples in this repository should +be more useful and more substantial than most of the examples we ship as part +of our other modules, and also written in a way that makes them good example +code. If you have ideas for examples, let us know. + +No decision has been made yet if this module will be released and/or packaged. +It probably makes sense to do so though. + +[examples-git]: https://cgit.freedesktop.org/gstreamer/gst-examples/tree/ +[http-launch]: https://cgit.freedesktop.org/gstreamer/gst-examples/tree/network/http-launch/ +[puis]: https://cgit.freedesktop.org/gstreamer/gst-examples/tree/playback/player + +### gst-build + +[gst-build][gst-build-git] is a new meta module to build GStreamer using the +new Meson build system. This module is not required to build GStreamer with +Meson, it is merely for convenience and aims to provide a development setup +similar to the existing `gst-uninstalled` setup. + +gst-build makes use of Meson's [subproject feature][meson-subprojects] and sets +up the various GStreamer modules as subprojects, so they can all be updated and +built in parallel. + +This module is still very new and highly experimental. It should work at least +on Linux and Windows (OS/X needs some build fixes). Let us know of any issues +you encounter by popping into the `#gstreamer` IRC channel or by +[filing a bug][gst-build-bug]. + +This module will probably not be released or packaged (does not really make sense). + +[gst-build-git]: https://cgit.freedesktop.org/gstreamer/gst-build/tree/ +[gst-build-bug]: https://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer&component=gst-build +[meson-subprojects]: https://github.com/mesonbuild/meson/wiki/Subprojects + +## Contributors + +Aaron Boxer, Aleix Conchillo Flaqué, Alessandro Decina, Alexandru Băluț, Alex +Ashley, Alex-P. Natsios, Alistair Buxton, Allen Zhang, Andreas Naumann, Andrew +Eikum, Andy Devar, Anthony G. Basile, Arjen Veenhuizen, Arnaud Vrac, Artem +Martynovich, Arun Raghavan, Aurélien Zanelli, Barun Kumar Singh, Bernhard +Miller, Brad Lackey, Branko Subasic, Carlos Garcia Campos, Carlos Rafael +Giani, Christoffer Stengren, Daiki Ueno, Damian Ziobro, Danilo Cesar Lemes de +Paula, David Buchmann, Dimitrios Katsaros, Duncan Palmer, Edward Hervey, +Emmanuel Poitier, Enrico Jorns, Enrique Ocaña González, Fabrice Bellet, +Florian Zwoch, Florin Apostol, Francisco Velazquez, Frédéric Bertolus, Fredrik +Fornwall, Gaurav Gupta, George Kiagiadakis, Georg Lippitsch, Göran Jönsson, +Graham Leggett, Gregoire Gentil, Guillaume Desmottes, Gwang Yoon Hwang, Haakon +Sporsheim, Haihua Hu, Havard Graff, Heinrich Fink, Hoonhee Lee, Hyunjun Ko, +Iain Lane, Ian, Ian Jamison, Jagyum Koo, Jake Foytik, Jakub Adam, Jan +Alexander Steffens (heftig), Jan Schmidt, Javier Martinez Canillas, Jerome +Laheurte, Jesper Larsen, Jie Jiang, Jihae Yi, Jimmy Ohn, Jinwoo Ahn, Joakim +Johansson, Joan Pau Beltran, Jonas Holmberg, Jonathan Matthew, Jonathan Roy, +Josep Torra, Julien Isorce, Jun Ji, Jürgen Slowack, Justin Kim, Kazunori +Kobayashi, Kieran Bingham, Kipp Cannon, Koop Mast, Kouhei Sutou, Kseniia, Kyle +Schwarz, Kyungyong Kim, Linus Svensson, Luis de Bethencourt, Marcin Kolny, +Marcin Lewandowski, Marianna Smidth Buschle, Mario Sanchez Prada, Mark +Combellack, Mark Nauwelaerts, Martin Kelly, Matej Knopp, Mathieu Duponchelle, +Mats Lindestam, Matthew Gruenke, Matthew Waters, Michael Olbrich, Michal Lazo, +Miguel París Díaz, Mikhail Fludkov, Minjae Kim, Mohan R, Munez, Nicola Murino, +Nicolas Dufresne, Nicolas Huet, Nikita Bobkov, Nirbheek Chauhan, Olivier +Crête, Paolo Pettinato, Patricia Muscalu, Paulo Neves, Peng Liu, Peter +Seiderer, Philippe Normand, Philippe Renon, Philipp Zabel, Pierre Lamot, Piotr +Drąg, Prashant Gotarne, Raffaele Rossi, Ray Strode, Reynaldo H. Verdejo +Pinochet, Santiago Carot-Nemesio, Scott D Phillips, Sebastian Dröge, Sebastian +Rasmussen, Sergei Saveliev, Sergey Borovkov, Sergey Mamonov, Sergio Torres +Soldado, Seungha Yang, sezero, Song Bing, Sreerenj Balachandran, Stefan Sauer, +Stephen, Steven Hoving, Stian Selnes, Thiago Santos, Thibault Saunier, Thijs +Vermeir, Thomas Bluemel, Thomas Jones, Thomas Klausner, Thomas Scheuermann, +Tim-Philipp Müller, Ting-Wei Lan, Tom Schoonjans, Ursula Maplehurst, Vanessa +Chipirras Navalon, Víctor Manuel Jáquez Leal, Vincent Penquerc'h, Vineeth TM, +Vivia Nikolaidou, Vootele Vesterblom, Wang Xin-yu (王昕宇), William Manley, +Wim Taymans, Wonchul Lee, Xabier Rodriguez Calvar, Xavier Claessens, xlazom00, +Yann Jouanin, Zaheer Abbas Merali + +... and many others who have contributed bug reports, translations, sent +suggestions or helped testing. + +## Bugs fixed in 1.10 + +More than [750 bugs][bugs-fixed-in-1.10] have been fixed during +the development of 1.10. + +This list does not include issues that have been cherry-picked into the +stable 1.8 branch and fixed there as well, all fixes that ended up in the +1.8 branch are also included in 1.10. + +This list also does not include issues that have been fixed without a bug +report in bugzilla, so the actual number of fixes is much higher. + +[bugs-fixed-in-1.10]: https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&classification=Platform&limit=0&list_id=164074&order=bug_id&product=GStreamer&query_format=advanced&resolution=FIXED&target_milestone=1.8.1&target_milestone=1.8.2&target_milestone=1.8.3&target_milestone=1.8.4&target_milestone=1.9.1&target_milestone=1.9.2&target_milestone=1.9.90&target_milestone=1.10.0 + +## Stable 1.10 branch + +After the 1.10.0 release there will be several 1.10.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.10.x bug-fix releases will be made from the git 1.10 branch, +which is a stable branch. + +### 1.10.0 + +1.10.0 was released on 1st November 2016. + +## Known Issues + +- iOS builds with iOS 6 SDK and old C++ STL. You need to select iOS 6 instead + of 7 or 8 in your projects settings to be able to link applications. + [Bug #766366](https://bugzilla.gnome.org/show_bug.cgi?id=766366) +- Code signing for Apple platforms has some problems currently, requiring + manual work to get your application signed. [Bug #771860](https://bugzilla.gnome.org/show_bug.cgi?id=771860) +- Building applications with Android NDK r13 on Windows does not work. Other + platforms and earlier/later versions of the NDK are not affected. + [Bug #772842](https://bugzilla.gnome.org/show_bug.cgi?id=772842) +- The new leaks tracer may deadlock the application (or exhibit other undefined + behaviour) when `SIGUSR` handling is enabled via the `GST_LEAKS_TRACER_SIG` + environment variable. [Bug #770373](https://bugzilla.gnome.org/show_bug.cgi?id=770373) +- vp8enc crashes on 32 bit Windows, but was working fine in 1.6. 64 bit Windows is unaffected. + [Bug #763663](https://bugzilla.gnome.org/show_bug.cgi?id=763663) + +## Schedule for 1.12 + +Our next major feature release will be 1.12, and 1.11 will be the unstable +development version leading up to the stable 1.12 release. The development +of 1.11/1.12 will happen in the git master branch. + +The plan for the 1.12 development cycle is yet to be confirmed, but it is +expected that feature freeze will be around early/mid-January, +followed by several 1.11 pre-releases and the new 1.12 stable release +in March. + +1.12 will be backwards-compatible to the stable 1.10, 1.8, 1.6, 1.4, 1.2 and +1.0 release series. + +- - - + +*These release notes have been prepared by Olivier Crête, Sebastian Dröge, +Nicolas Dufresne, Edward Hervey, Víctor Manuel Jáquez Leal, Tim-Philipp +Müller, Reynaldo H. Verdejo Pinochet, Arun Raghavan, Thibault Saunier, +Jan Schmidt, Wim Taymans, Matthew Waters* + +*License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)* + diff --git a/configure.ac b/configure.ac index d76b585ca7..010cdc96b9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [9]) -m4_define([gst_vaapi_micro_version], [90]) +m4_define([gst_vaapi_minor_version], [10]) +m4_define([gst_vaapi_micro_version], [0]) m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [990]) +m4_define([gst_vaapi_lt_current], [1000]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [990]) +m4_define([gst_vaapi_lt_age], [1000]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.9.90]) -m4_define([gst_plugins_base_version], [1.9.90]) -m4_define([gst_plugins_bad_version], [1.9.90]) +m4_define([gst_version], [1.10.0]) +m4_define([gst_plugins_base_version], [1.10.0]) +m4_define([gst_plugins_bad_version], [1.10.0]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 5e85a510e7..2592dd0601 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,15 @@ + + + 1.10.0 + master + 2016-11-01 + + + + 1.9.90 From 67d4c09341650129cc88ebba4bbc5f16a003fbb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 1 Nov 2016 18:54:54 +0200 Subject: [PATCH 2555/3781] Back to development --- configure.ac | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 010cdc96b9..b8124a6da8 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [10]) +m4_define([gst_vaapi_minor_version], [11]) m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1000]) +m4_define([gst_vaapi_lt_current], [1100]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1000]) +m4_define([gst_vaapi_lt_age], [1100]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.10.0]) -m4_define([gst_plugins_base_version], [1.10.0]) -m4_define([gst_plugins_bad_version], [1.10.0]) +m4_define([gst_version], [1.11.0.1]) +m4_define([gst_plugins_base_version], [1.11.0.1]) +m4_define([gst_plugins_bad_version], [1.11.0.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) From 185da3d1a48ea0ac17f2494242e383c340b2d1c7 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 13 Oct 2016 12:53:17 +0900 Subject: [PATCH 2556/3781] libs: display: GstVaapiDisplay as GstObject descendant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch is to change the inheritance of GstVaapiDisplay to GstObject, instead of GstVaapiMiniObject. In this way we can use all the available infrastructure for GObject/GstObject such as GstTracer, GIR, etc. In addition, a new debug category for GstVaapiDisplay is created to make it easier to trace debug messages. It is named "vaapidisplay" and it transverse all the VA display backends (DRM, GLX, EGL, Wayland, ...) This patch is a step forward to expose GstVaapiDisplay for users in a future library. https://bugzilla.gnome.org/show_bug.cgi?id=768266 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapidebug.h | 5 + gst-libs/gst/vaapi/gstvaapidisplay.c | 72 +++++------ gst-libs/gst/vaapi/gstvaapidisplay.h | 12 +- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 37 ++---- gst-libs/gst/vaapi/gstvaapidisplay_drm.h | 6 +- gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h | 10 +- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 117 ++++++++---------- gst-libs/gst/vaapi/gstvaapidisplay_egl.h | 6 +- gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h | 13 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 44 +++---- gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 6 +- gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 8 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 97 +++++---------- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 42 +++---- gst-libs/gst/vaapi/gstvaapidisplay_wayland.h | 6 +- .../gst/vaapi/gstvaapidisplay_wayland_priv.h | 10 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 45 ++++--- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 6 +- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 15 ++- gst-libs/gst/vaapi/gstvaapitexture_egl.c | 3 + gst-libs/gst/vaapi/gstvaapiutils_egl.c | 3 + gst-libs/gst/vaapi/gstvaapiutils_egl.h | 3 - gst/vaapi/gstvaapivideocontext.c | 15 +-- 23 files changed, 259 insertions(+), 322 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidebug.h b/gst-libs/gst/vaapi/gstvaapidebug.h index e386755503..88ea3123ca 100644 --- a/gst-libs/gst/vaapi/gstvaapidebug.h +++ b/gst-libs/gst/vaapi/gstvaapidebug.h @@ -30,4 +30,9 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 32738a116e..d10d5657fb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -37,11 +37,21 @@ #include "gstvaapiworkarounds.h" #include "gstvaapiversion.h" -#define DEBUG 1 -#include "gstvaapidebug.h" - +/* Debug category for all vaapi libs */ GST_DEBUG_CATEGORY (gst_debug_vaapi); +/* Debug category for VaapiDisplay */ +GST_DEBUG_CATEGORY (gst_debug_vaapi_display); +#define GST_CAT_DEFAULT gst_debug_vaapi_display + +#define _do_init \ + G_ADD_PRIVATE (GstVaapiDisplay); \ + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_display, \ + "vaapidisplay", 0, "VA-API Display"); + +G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplay, gst_vaapi_display, GST_TYPE_OBJECT, + _do_init); + /* Ensure those symbols are actually defined in the resulting libraries */ #undef gst_vaapi_display_ref #undef gst_vaapi_display_unref @@ -117,7 +127,8 @@ libgstvaapi_init_once (void) GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi, "vaapi", 0, "VA-API helper"); /* Dump gstreamer-vaapi version for debugging purposes */ - GST_INFO ("gstreamer-vaapi version %s", GST_VAAPI_VERSION_ID); + GST_CAT_INFO (gst_debug_vaapi, "gstreamer-vaapi version %s", + GST_VAAPI_VERSION_ID); gst_vaapi_display_properties_init (); @@ -947,6 +958,7 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, return FALSE; } + GST_INFO_OBJECT (display, "new display addr=%p", display); g_free (priv->display_name); priv->display_name = g_strdup (info.display_name); return TRUE; @@ -995,42 +1007,39 @@ gst_vaapi_display_unlock_default (GstVaapiDisplay * display) static void gst_vaapi_display_init (GstVaapiDisplay * display) { - GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - const GstVaapiDisplayClass *const dpy_class = - GST_VAAPI_DISPLAY_GET_CLASS (display); + GstVaapiDisplayPrivate *const priv = + gst_vaapi_display_get_instance_private (display); + display->priv = priv; priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; priv->par_n = 1; priv->par_d = 1; g_rec_mutex_init (&priv->mutex); - - if (dpy_class->init) - dpy_class->init (display); } static void -gst_vaapi_display_finalize (GstVaapiDisplay * display) +gst_vaapi_display_finalize (GObject * object) { + GstVaapiDisplay *const display = GST_VAAPI_DISPLAY (object); GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); gst_vaapi_display_destroy (display); g_rec_mutex_clear (&priv->mutex); + + G_OBJECT_CLASS (gst_vaapi_display_parent_class)->finalize (object); } void gst_vaapi_display_class_init (GstVaapiDisplayClass * klass) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); - GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); libgstvaapi_init_once (); - object_class->size = sizeof (GstVaapiDisplay); - object_class->finalize = (GDestroyNotify) gst_vaapi_display_finalize; - dpy_class->lock = gst_vaapi_display_lock_default; - dpy_class->unlock = gst_vaapi_display_unlock_default; + object_class->finalize = gst_vaapi_display_finalize; + klass->lock = gst_vaapi_display_lock_default; + klass->unlock = gst_vaapi_display_unlock_default; } static void @@ -1102,31 +1111,12 @@ gst_vaapi_display_properties_init (void) "The display contrast value", 0.0, 2.0, 1.0, G_PARAM_READWRITE); } -static inline const GstVaapiDisplayClass * -gst_vaapi_display_class (void) -{ - static GstVaapiDisplayClass g_class; - static gsize g_class_init = FALSE; - - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_display_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return &g_class; -} - GstVaapiDisplay * -gst_vaapi_display_new (const GstVaapiDisplayClass * klass, +gst_vaapi_display_new (GstVaapiDisplay * display, GstVaapiDisplayInitType init_type, gpointer init_value) { - GstVaapiDisplay *display; + g_return_val_if_fail (display != NULL, NULL); - display = (GstVaapiDisplay *) - gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS (klass)); - if (!display) - return NULL; - - gst_vaapi_display_init (display); if (!gst_vaapi_display_create (display, init_type, init_value)) goto error; return display; @@ -1158,7 +1148,7 @@ gst_vaapi_display_new_with_display (VADisplay va_display) if (info) return gst_vaapi_display_ref_internal (info->display); - return gst_vaapi_display_new (gst_vaapi_display_class (), + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY, NULL), GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, va_display); } @@ -2124,7 +2114,7 @@ gst_vaapi_display_get_vendor_string (GstVaapiDisplay * display) if (!ensure_vendor_string (display)) return NULL; - return display->priv.vendor_string; + return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->vendor_string; } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 600f276eca..8eba5fb058 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -33,8 +33,11 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_DISPLAY (gst_vaapi_display_get_type ()) #define GST_VAAPI_DISPLAY(obj) \ - ((GstVaapiDisplay *)(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: @@ -109,6 +112,9 @@ typedef enum 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); @@ -260,6 +266,10 @@ gst_vaapi_display_has_opengl (GstVaapiDisplay * display); void gst_vaapi_display_reset_texture_map (GstVaapiDisplay * display); +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDisplay, gst_vaapi_display_unref) +#endif + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 56da23507d..44e4cbd87f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -38,9 +38,15 @@ #include "gstvaapidisplay_drm_priv.h" #include "gstvaapiwindow_drm.h" -#define DEBUG 1 +#define DEBUG_VAAPI_DISPLAY 1 #include "gstvaapidebug.h" +#define _do_init \ + G_ADD_PRIVATE (GstVaapiDisplayDRM); + +G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplayDRM, gst_vaapi_display_drm, + GST_TYPE_VAAPI_DISPLAY, _do_init); + static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_DRM; typedef enum @@ -322,26 +328,21 @@ gst_vaapi_display_drm_create_window (GstVaapiDisplay * display, GstVaapiID id, } static void -gst_vaapi_display_drm_init (GstVaapiDisplay * display) +gst_vaapi_display_drm_init (GstVaapiDisplayDRM * display) { GstVaapiDisplayDRMPrivate *const priv = - GST_VAAPI_DISPLAY_DRM_PRIVATE (display); + 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) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); - gst_vaapi_display_class_init (&klass->parent_class); - - object_class->size = sizeof (GstVaapiDisplayDRM); dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_DRM; - dpy_class->init = gst_vaapi_display_drm_init; 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; @@ -349,19 +350,6 @@ gst_vaapi_display_drm_class_init (GstVaapiDisplayDRMClass * klass) dpy_class->create_window = gst_vaapi_display_drm_create_window; } -static inline const GstVaapiDisplayClass * -gst_vaapi_display_drm_class (void) -{ - static GstVaapiDisplayDRMClass g_class; - static gsize g_class_init = FALSE; - - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_display_drm_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DISPLAY_CLASS (&g_class); -} - /** * gst_vaapi_display_drm_new: * @device_path: the DRM device path @@ -394,7 +382,8 @@ gst_vaapi_display_drm_new (const gchar * device_path) for (i = 0; i < num_types; i++) { g_drm_device_type = types[i]; - display = gst_vaapi_display_new (gst_vaapi_display_drm_class (), + display = + gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_DRM, NULL), GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) device_path); if (display || device_path) break; @@ -419,7 +408,7 @@ gst_vaapi_display_drm_new_with_device (gint device) { g_return_val_if_fail (device >= 0, NULL); - return gst_vaapi_display_new (gst_vaapi_display_drm_class (), + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_DRM, NULL), GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, GINT_TO_POINTER (device)); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h index 88c7ca2a9b..2af4d9f53e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h @@ -27,8 +27,9 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_DISPLAY_DRM (gst_vaapi_display_drm_get_type ()) #define GST_VAAPI_DISPLAY_DRM(obj) \ - ((GstVaapiDisplayDRM *)(obj)) + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DISPLAY_DRM, GstVaapiDisplayDRM)) typedef struct _GstVaapiDisplayDRM GstVaapiDisplayDRM; @@ -45,6 +46,9 @@ const gchar * gst_vaapi_display_drm_get_device_path (GstVaapiDisplayDRM * display); +GType +gst_vaapi_display_drm_get_type (void) G_GNUC_CONST; + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_DRM_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h index 0fa295a683..ef3d2559bd 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h @@ -29,14 +29,16 @@ G_BEGIN_DECLS #define GST_VAAPI_IS_DISPLAY_DRM(display) \ - ((display) != NULL && \ - GST_VAAPI_DISPLAY_VADISPLAY_TYPE(display) == GST_VAAPI_DISPLAY_TYPE_DRM) + (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) + (GST_VAAPI_DISPLAY_DRM_CAST(display)->priv) typedef struct _GstVaapiDisplayDRMPrivate GstVaapiDisplayDRMPrivate; typedef struct _GstVaapiDisplayDRMClass GstVaapiDisplayDRMClass; @@ -69,7 +71,7 @@ struct _GstVaapiDisplayDRM /*< private >*/ GstVaapiDisplay parent_instance; - GstVaapiDisplayDRMPrivate priv; + GstVaapiDisplayDRMPrivate *priv; }; /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index 99783ea145..0c1dd9c9cb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -35,7 +35,11 @@ #include "gstvaapidisplay_wayland.h" #endif -GST_DEBUG_CATEGORY (gst_debug_vaapidisplay_egl); +#define DEBUG_VAAPI_DISPLAY 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE (GstVaapiDisplayEGL, gst_vaapi_display_egl, + GST_TYPE_VAAPI_DISPLAY); /* ------------------------------------------------------------------------- */ /* --- EGL backend implementation --- */ @@ -90,11 +94,13 @@ ensure_context_is_wrapped (GstVaapiDisplayEGL * display, EGLContext gl_context) } static gboolean -gst_vaapi_display_egl_bind_display (GstVaapiDisplayEGL * display, - const InitParams * params) +gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_display, + gpointer native_params) { GstVaapiDisplay *native_display = NULL; + GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display); EglDisplay *egl_display; + const InitParams *params = (InitParams *) native_params; if (params->display) { #if USE_X11 @@ -132,14 +138,16 @@ gst_vaapi_display_egl_bind_display (GstVaapiDisplayEGL * display, } static void -gst_vaapi_display_egl_close_display (GstVaapiDisplayEGL * display) +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 (GstVaapiDisplayEGL * display) +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); @@ -148,8 +156,9 @@ gst_vaapi_display_egl_lock (GstVaapiDisplayEGL * display) } static void -gst_vaapi_display_egl_unlock (GstVaapiDisplayEGL * display) +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); @@ -158,8 +167,9 @@ gst_vaapi_display_egl_unlock (GstVaapiDisplayEGL * display) } static void -gst_vaapi_display_egl_sync (GstVaapiDisplayEGL * display) +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); @@ -170,8 +180,9 @@ gst_vaapi_display_egl_sync (GstVaapiDisplayEGL * display) } static void -gst_vaapi_display_egl_flush (GstVaapiDisplayEGL * display) +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); @@ -180,9 +191,10 @@ gst_vaapi_display_egl_flush (GstVaapiDisplayEGL * display) } static gboolean -gst_vaapi_display_egl_get_display_info (GstVaapiDisplayEGL * display, +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); @@ -192,9 +204,10 @@ gst_vaapi_display_egl_get_display_info (GstVaapiDisplayEGL * display, } static void -gst_vaapi_display_egl_get_size (GstVaapiDisplayEGL * display, +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); @@ -203,9 +216,10 @@ gst_vaapi_display_egl_get_size (GstVaapiDisplayEGL * display, } static void -gst_vaapi_display_egl_get_size_mm (GstVaapiDisplayEGL * display, +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); @@ -214,9 +228,10 @@ gst_vaapi_display_egl_get_size_mm (GstVaapiDisplayEGL * display, } static guintptr -gst_vaapi_display_egl_get_visual_id (GstVaapiDisplayEGL * display, +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; @@ -267,73 +282,43 @@ gst_vaapi_display_egl_get_texture_map (GstVaapiDisplay * display) } static void -gst_vaapi_display_egl_finalize (GstVaapiDisplay * display) +gst_vaapi_display_egl_finalize (GObject * object) { - GstVaapiDisplayEGL *dpy = GST_VAAPI_DISPLAY_EGL (display); + GstVaapiDisplayEGL *dpy = GST_VAAPI_DISPLAY_EGL (object); if (dpy->texture_map) gst_object_unref (dpy->texture_map); - GST_VAAPI_DISPLAY_EGL_GET_CLASS (display)->parent_finalize (display); + 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) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); - GST_DEBUG_CATEGORY_INIT (gst_debug_vaapidisplay_egl, "vaapidisplay_egl", 0, - "VA/EGL backend"); - - gst_vaapi_display_class_init (dpy_class); - - /* chain up destructor */ - klass->parent_finalize = object_class->finalize; - object_class->finalize = (GDestroyNotify) gst_vaapi_display_egl_finalize; - - object_class->size = sizeof (GstVaapiDisplayEGL); + object_class->finalize = gst_vaapi_display_egl_finalize; dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_EGL; - dpy_class->bind_display = (GstVaapiDisplayBindFunc) - gst_vaapi_display_egl_bind_display; - dpy_class->close_display = (GstVaapiDisplayCloseFunc) - gst_vaapi_display_egl_close_display; - dpy_class->lock = (GstVaapiDisplayLockFunc) - gst_vaapi_display_egl_lock; - dpy_class->unlock = (GstVaapiDisplayUnlockFunc) - gst_vaapi_display_egl_unlock; - dpy_class->sync = (GstVaapiDisplaySyncFunc) - gst_vaapi_display_egl_sync; - dpy_class->flush = (GstVaapiDisplayFlushFunc) - gst_vaapi_display_egl_flush; - dpy_class->get_display = (GstVaapiDisplayGetInfoFunc) - gst_vaapi_display_egl_get_display_info; - dpy_class->get_size = (GstVaapiDisplayGetSizeFunc) - gst_vaapi_display_egl_get_size; - dpy_class->get_size_mm = (GstVaapiDisplayGetSizeMFunc) - gst_vaapi_display_egl_get_size_mm; - dpy_class->get_visual_id = (GstVaapiDisplayGetVisualIdFunc) - gst_vaapi_display_egl_get_visual_id; - dpy_class->create_window = (GstVaapiDisplayCreateWindowFunc) - gst_vaapi_display_egl_create_window; - dpy_class->create_texture = (GstVaapiDisplayCreateTextureFunc) - gst_vaapi_display_egl_create_texture; + 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; } -static inline const GstVaapiDisplayClass * -gst_vaapi_display_egl_class (void) -{ - static GstVaapiDisplayEGLClass g_class; - static gsize g_class_init = FALSE; - - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_display_egl_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DISPLAY_CLASS (&g_class); -} - /** * gst_vaapi_display_egl_new: * @display: a #GstVaapiDisplay, or %NULL to pick any one @@ -360,7 +345,7 @@ gst_vaapi_display_egl_new (GstVaapiDisplay * display, guint gles_version) params.display_type = GST_VAAPI_DISPLAY_TYPE_ANY; } params.gles_version = gles_version; - return gst_vaapi_display_new (gst_vaapi_display_egl_class (), + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_EGL, NULL), GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, ¶ms); } @@ -391,7 +376,7 @@ gst_vaapi_display_egl_new_with_native_display (gpointer native_display, params.display = native_display; params.display_type = display_type; params.gles_version = gles_version; - return gst_vaapi_display_new (gst_vaapi_display_egl_class (), + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_EGL, NULL), GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, ¶ms); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.h b/gst-libs/gst/vaapi/gstvaapidisplay_egl.h index 2f79e88fdf..22a80deb86 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.h @@ -30,8 +30,9 @@ 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) \ - ((GstVaapiDisplayEGL *)(obj)) + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DISPLAY_EGL, GstVaapiDisplayEGL)) GstVaapiDisplay * gst_vaapi_display_egl_new (GstVaapiDisplay * display, guint gles_version); @@ -50,6 +51,9 @@ gboolean gst_vaapi_display_egl_set_gl_context (GstVaapiDisplayEGL * display, EGLContext gl_context); +GType +gst_vaapi_display_egl_get_type (void) G_GNUC_CONST; + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_EGL_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h index 96e2b43b85..e99c54bdc1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h @@ -32,14 +32,16 @@ G_BEGIN_DECLS #define GST_VAAPI_IS_DISPLAY_EGL(display) \ - ((display) != NULL && \ - GST_VAAPI_DISPLAY_GET_CLASS_TYPE (display) == GST_VAAPI_DISPLAY_TYPE_EGL) + (G_TYPE_CHECK_INSTANCE_TYPE ((display), GST_TYPE_VAAPI_DISPLAY_EGL)) #define GST_VAAPI_DISPLAY_EGL_CLASS(klass) \ - ((GstVaapiDisplayEGLClass *)(klass)) + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_DISPLAY_EGL, GstVaapiDisplayEGLClass)) #define GST_VAAPI_DISPLAY_EGL_GET_CLASS(obj) \ - GST_VAAPI_DISPLAY_EGL_CLASS (GST_VAAPI_DISPLAY_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: @@ -50,7 +52,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DISPLAY_EGL_DISPLAY #define GST_VAAPI_DISPLAY_EGL_DISPLAY(display) \ - (GST_VAAPI_DISPLAY_EGL (display)->egl_display) + (GST_VAAPI_DISPLAY_EGL_CAST (display)->egl_display) /** * GST_VAAPI_DISPLAY_EGL_CONTEXT: @@ -92,7 +94,6 @@ struct _GstVaapiDisplayEGLClass { /*< private >*/ GstVaapiDisplayClass parent_class; - GDestroyNotify parent_finalize; }; G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 9b4a007cbc..94686c631d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -38,9 +38,12 @@ #include "gstvaapiwindow_glx.h" #include "gstvaapitexture_glx.h" -#define DEBUG 1 +#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) @@ -85,48 +88,33 @@ gst_vaapi_display_glx_get_texture_map (GstVaapiDisplay * display) } static void -gst_vaapi_display_glx_finalize (GstVaapiDisplay * display) +gst_vaapi_display_glx_finalize (GObject * object) { - GstVaapiDisplayGLX *dpy = GST_VAAPI_DISPLAY_GLX (display); + GstVaapiDisplayGLX *dpy = GST_VAAPI_DISPLAY_GLX (object); if (dpy->texture_map) gst_object_unref (dpy->texture_map); - GST_VAAPI_DISPLAY_GLX_GET_CLASS (display)->parent_finalize (display); + 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) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); - gst_vaapi_display_x11_class_init (&klass->parent_class); - - /* chain up destructor */ - klass->parent_finalize = object_class->finalize; - object_class->finalize = (GDestroyNotify) gst_vaapi_display_glx_finalize; - - object_class->size = sizeof (GstVaapiDisplayGLX); + 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; } -static inline const GstVaapiDisplayClass * -gst_vaapi_display_glx_class (void) -{ - static GstVaapiDisplayGLXClass g_class; - static gsize g_class_init = FALSE; - - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_display_glx_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DISPLAY_CLASS (&g_class); -} - /** * gst_vaapi_display_glx_new: * @display_name: the X11 display name @@ -140,7 +128,7 @@ gst_vaapi_display_glx_class (void) GstVaapiDisplay * gst_vaapi_display_glx_new (const gchar * display_name) { - return gst_vaapi_display_new (gst_vaapi_display_glx_class (), + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_GLX, NULL), GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) display_name); } @@ -160,6 +148,6 @@ gst_vaapi_display_glx_new_with_display (Display * x11_display) { g_return_val_if_fail (x11_display != NULL, NULL); - return gst_vaapi_display_new (gst_vaapi_display_glx_class (), + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_GLX, NULL), GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index 485c413cd0..d19a046b81 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -29,8 +29,9 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_DISPLAY_GLX (gst_vaapi_display_glx_get_type ()) #define GST_VAAPI_DISPLAY_GLX(obj) \ - ((GstVaapiDisplayGLX *)(obj)) + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DISPLAY_GLX, GstVaapiDisplayGLX)) typedef struct _GstVaapiDisplayGLX GstVaapiDisplayGLX; @@ -40,6 +41,9 @@ 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_END_DECLS #endif /* GST_VAAPI_DISPLAY_GLX_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index 4da88228a6..a715175c04 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -31,17 +31,16 @@ G_BEGIN_DECLS #define GST_VAAPI_IS_DISPLAY_GLX(display) \ - ((display) != NULL && \ - GST_VAAPI_DISPLAY_GET_CLASS_TYPE (display) == GST_VAAPI_DISPLAY_TYPE_GLX) + (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) \ - ((GstVaapiDisplayGLXClass *)(klass)) + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_DISPLAY_GLX, GstVaapiDisplayGLXClass)) #define GST_VAAPI_DISPLAY_GLX_GET_CLASS(obj) \ - GST_VAAPI_DISPLAY_GLX_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_DISPLAY_GLX, GstVaapiDisplayGLXClass)) typedef struct _GstVaapiDisplayGLXClass GstVaapiDisplayGLXClass; @@ -66,7 +65,6 @@ struct _GstVaapiDisplayGLXClass { /*< private >*/ GstVaapiDisplayX11Class parent_class; - GDestroyNotify parent_finalize; }; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 12b5184bfe..d914e954d8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -35,53 +35,24 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_CAST(display) \ - ((GstVaapiDisplay *) (display)) + ((GstVaapiDisplay *)(display)) #define GST_VAAPI_DISPLAY_GET_PRIVATE(display) \ - (&GST_VAAPI_DISPLAY_CAST (display)->priv) + (GST_VAAPI_DISPLAY_CAST (display)->priv) #define GST_VAAPI_DISPLAY_CLASS(klass) \ - ((GstVaapiDisplayClass *) (klass)) + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_DISPLAY, GstVaapiDisplayClass)) #define GST_VAAPI_IS_DISPLAY_CLASS(klass) \ - ((klass) != NULL) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_DISPLAY)) #define GST_VAAPI_DISPLAY_GET_CLASS(obj) \ - GST_VAAPI_DISPLAY_CLASS (GST_VAAPI_MINI_OBJECT_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; -typedef void (*GstVaapiDisplayInitFunc) (GstVaapiDisplay * display); -typedef gboolean (*GstVaapiDisplayBindFunc) (GstVaapiDisplay * display, - gpointer native_dpy); -typedef gboolean (*GstVaapiDisplayOpenFunc) (GstVaapiDisplay * display, - const gchar * name); -typedef void (*GstVaapiDisplayCloseFunc) (GstVaapiDisplay * display); -typedef void (*GstVaapiDisplayLockFunc) (GstVaapiDisplay * display); -typedef void (*GstVaapiDisplayUnlockFunc) (GstVaapiDisplay * display); -typedef void (*GstVaapiDisplaySyncFunc) (GstVaapiDisplay * display); -typedef void (*GstVaapiDisplayFlushFunc) (GstVaapiDisplay * display); -typedef gboolean (*GstVaapiDisplayGetInfoFunc) (GstVaapiDisplay * display, - GstVaapiDisplayInfo * info); -typedef void (*GstVaapiDisplayGetSizeFunc) (GstVaapiDisplay * display, - guint * pwidth, guint * pheight); -typedef void (*GstVaapiDisplayGetSizeMFunc) (GstVaapiDisplay * display, - guint * pwidth, guint * pheight); -typedef GstVaapiWindow *(*GstVaapiDisplayCreateWindowFunc) ( - GstVaapiDisplay * display, GstVaapiID id, guint width, guint height); -typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) ( - GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, - guint width, guint height); -typedef GstVaapiTextureMap *(*GstVaapiDisplayGetTextureMapFunc) ( - GstVaapiDisplay * display); - -typedef guintptr (*GstVaapiDisplayGetVisualIdFunc) (GstVaapiDisplay * display, - GstVaapiWindow * window); -typedef guintptr (*GstVaapiDisplayGetColormapFunc) (GstVaapiDisplay * display, - GstVaapiWindow * window); - /** * GST_VAAPI_DISPLAY_GET_CLASS_TYPE: * @display: a #GstVaapiDisplay @@ -182,9 +153,9 @@ struct _GstVaapiDisplayPrivate struct _GstVaapiDisplay { /*< private >*/ - GstVaapiMiniObject parent_instance; + GstObject parent_instance; - GstVaapiDisplayPrivate priv; + GstVaapiDisplayPrivate *priv; }; /** @@ -202,34 +173,36 @@ struct _GstVaapiDisplay * @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 >*/ - GstVaapiMiniObjectClass parent_class; + GstObjectClass parent_class; /*< protected >*/ guint display_type; /*< public >*/ - GstVaapiDisplayInitFunc init; - GstVaapiDisplayBindFunc bind_display; - GstVaapiDisplayOpenFunc open_display; - GstVaapiDisplayCloseFunc close_display; - GstVaapiDisplayLockFunc lock; - GstVaapiDisplayUnlockFunc unlock; - GstVaapiDisplaySyncFunc sync; - GstVaapiDisplayFlushFunc flush; - GstVaapiDisplayGetInfoFunc get_display; - GstVaapiDisplayGetSizeFunc get_size; - GstVaapiDisplayGetSizeMFunc get_size_mm; - GstVaapiDisplayGetVisualIdFunc get_visual_id; - GstVaapiDisplayGetColormapFunc get_colormap; - GstVaapiDisplayCreateWindowFunc create_window; - GstVaapiDisplayCreateTextureFunc create_texture; - GstVaapiDisplayGetTextureMapFunc get_texture_map; + 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 */ @@ -240,36 +213,32 @@ enum _GstVaapiDisplayInitType GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY }; -void -gst_vaapi_display_class_init (GstVaapiDisplayClass * klass); - GstVaapiDisplay * -gst_vaapi_display_new (const GstVaapiDisplayClass * klass, +gst_vaapi_display_new (GstVaapiDisplay * display, GstVaapiDisplayInitType init_type, gpointer init_value); /* Inline reference counting for core libgstvaapi library */ #ifdef IN_LIBGSTVAAPI_CORE #define gst_vaapi_display_ref_internal(display) \ - ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(display))) + ((gpointer) gst_object_ref (GST_OBJECT (display))) #define gst_vaapi_display_unref_internal(display) \ - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(display)) + gst_object_unref (GST_OBJECT (display)) #define gst_vaapi_display_replace_internal(old_display_ptr, new_display) \ - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_display_ptr), \ - GST_VAAPI_MINI_OBJECT(new_display)) + gst_object_replace ((GstObject **)(old_display_ptr), GST_OBJECT (new_display)) #undef gst_vaapi_display_ref #define gst_vaapi_display_ref(display) \ - gst_vaapi_display_ref_internal((display)) + gst_vaapi_display_ref_internal ((display)) #undef gst_vaapi_display_unref #define gst_vaapi_display_unref(display) \ - gst_vaapi_display_unref_internal((display)) + gst_vaapi_display_unref_internal ((display)) #undef gst_vaapi_display_replace #define gst_vaapi_display_replace(old_display_ptr, new_display) \ - gst_vaapi_display_replace_internal((old_display_ptr), (new_display)) + gst_vaapi_display_replace_internal ((old_display_ptr), (new_display)) #endif G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index bb7c5f3339..08a61c4f14 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -33,9 +33,15 @@ #include "gstvaapidisplay_wayland_priv.h" #include "gstvaapiwindow_wayland.h" -#define DEBUG 1 +#define DEBUG_VAAPI_DISPLAY 1 #include "gstvaapidebug.h" +#define _do_init \ + G_ADD_PRIVATE (GstVaapiDisplayWayland); + +G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplayWayland, gst_vaapi_display_wayland, + GST_TYPE_VAAPI_DISPLAY, _do_init); + static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_WAYLAND; static inline const gchar * @@ -342,26 +348,22 @@ gst_vaapi_display_wayland_create_window (GstVaapiDisplay * display, } static void -gst_vaapi_display_wayland_init (GstVaapiDisplay * display) +gst_vaapi_display_wayland_init (GstVaapiDisplayWayland * display) { GstVaapiDisplayWaylandPrivate *const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); + gst_vaapi_display_wayland_get_instance_private (display); + display->priv = priv; priv->event_fd = -1; } static void gst_vaapi_display_wayland_class_init (GstVaapiDisplayWaylandClass * klass) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); - gst_vaapi_display_class_init (&klass->parent_class); - - object_class->size = sizeof (GstVaapiDisplayWayland); dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; - dpy_class->init = gst_vaapi_display_wayland_init; + 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; @@ -371,19 +373,6 @@ gst_vaapi_display_wayland_class_init (GstVaapiDisplayWaylandClass * klass) dpy_class->create_window = gst_vaapi_display_wayland_create_window; } -static inline const GstVaapiDisplayClass * -gst_vaapi_display_wayland_class (void) -{ - static GstVaapiDisplayWaylandClass g_class; - static gsize g_class_init = FALSE; - - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_display_wayland_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DISPLAY_CLASS (&g_class); -} - /** * gst_vaapi_display_wayland_new: * @display_name: the Wayland display name @@ -397,8 +386,9 @@ gst_vaapi_display_wayland_class (void) GstVaapiDisplay * gst_vaapi_display_wayland_new (const gchar * display_name) { - return gst_vaapi_display_new (gst_vaapi_display_wayland_class (), - GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) display_name); + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_WAYLAND, + NULL), GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, + (gpointer) display_name); } /** @@ -417,8 +407,8 @@ gst_vaapi_display_wayland_new_with_display (struct wl_display * wl_display) { g_return_val_if_fail (wl_display, NULL); - return gst_vaapi_display_new (gst_vaapi_display_wayland_class (), - GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, wl_display); + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_WAYLAND, + NULL), GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, wl_display); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h index 6a3fa90e29..fd6fa11d44 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h @@ -29,8 +29,9 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_DISPLAY_WAYLAND (gst_vaapi_display_wayland_get_type ()) #define GST_VAAPI_DISPLAY_WAYLAND(obj) \ - ((GstVaapiDisplayWayland *)(obj)) + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DISPLAY_WAYLAND, GstVaapiDisplayWayland)) typedef struct _GstVaapiDisplayWayland GstVaapiDisplayWayland; @@ -43,6 +44,9 @@ gst_vaapi_display_wayland_new_with_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_END_DECLS #endif /* GST_VAAPI_DISPLAY_WAYLAND_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index 0232d2477a..bf6e81c639 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -30,14 +30,16 @@ G_BEGIN_DECLS #define GST_VAAPI_IS_DISPLAY_WAYLAND(display) \ - ((display) != NULL && \ - GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display) == GST_VAAPI_DISPLAY_TYPE_WAYLAND) + (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) + (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; @@ -79,7 +81,7 @@ struct _GstVaapiDisplayWayland /*< private >*/ GstVaapiDisplay parent_instance; - GstVaapiDisplayWaylandPrivate priv; + GstVaapiDisplayWaylandPrivate *priv; }; /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 658b597577..08bfb1a361 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -43,9 +43,15 @@ # include #endif -#define DEBUG 1 +#define DEBUG_VAAPI_DISPLAY 1 #include "gstvaapidebug.h" +#define _do_init \ + G_ADD_PRIVATE (GstVaapiDisplayX11); + +G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplayX11, gst_vaapi_display_x11, + GST_TYPE_VAAPI_DISPLAY, _do_init); + static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_X11; static gboolean @@ -114,7 +120,7 @@ get_default_display_name (void) static const gchar * get_display_name (GstVaapiDisplayX11 * display) { - GstVaapiDisplayX11Private *const priv = &display->priv; + GstVaapiDisplayX11Private *const priv = display->priv; const gchar *display_name = priv->display_name; if (!display_name || *display_name == '\0') @@ -126,7 +132,7 @@ get_display_name (GstVaapiDisplayX11 * display) static gboolean set_display_name (GstVaapiDisplayX11 * display, const gchar * display_name) { - GstVaapiDisplayX11Private *const priv = &display->priv; + GstVaapiDisplayX11Private *const priv = display->priv; g_free (priv->display_name); @@ -143,7 +149,7 @@ set_display_name (GstVaapiDisplayX11 * display, const gchar * display_name) static void set_synchronous (GstVaapiDisplayX11 * display, gboolean synchronous) { - GstVaapiDisplayX11Private *const priv = &display->priv; + GstVaapiDisplayX11Private *const priv = display->priv; if (priv->synchronous != synchronous) { priv->synchronous = synchronous; @@ -159,8 +165,7 @@ set_synchronous (GstVaapiDisplayX11 * display, gboolean synchronous) static void check_extensions (GstVaapiDisplayX11 * display) { - GstVaapiDisplayX11Private *const priv = - GST_VAAPI_DISPLAY_X11_PRIVATE (display); + GstVaapiDisplayX11Private *const priv = display->priv; int evt_base, err_base; #ifdef HAVE_XRANDR @@ -178,7 +183,7 @@ 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; + GstVaapiDisplayX11Private *const priv = display->priv; priv->x11_display = native_display; priv->x11_screen = DefaultScreen (native_display); @@ -196,7 +201,8 @@ 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; + GstVaapiDisplayX11Private *const priv = display->priv; + GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); const GstVaapiDisplayInfo *info; @@ -381,13 +387,8 @@ gst_vaapi_display_x11_create_window (GstVaapiDisplay * display, GstVaapiID id, void gst_vaapi_display_x11_class_init (GstVaapiDisplayX11Class * klass) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass); - gst_vaapi_display_class_init (&klass->parent_class); - - object_class->size = sizeof (GstVaapiDisplayX11); 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; @@ -400,17 +401,13 @@ gst_vaapi_display_x11_class_init (GstVaapiDisplayX11Class * klass) dpy_class->create_window = gst_vaapi_display_x11_create_window; } -static inline const GstVaapiDisplayClass * -gst_vaapi_display_x11_class (void) +static void +gst_vaapi_display_x11_init (GstVaapiDisplayX11 * display) { - static GstVaapiDisplayX11Class g_class; - static gsize g_class_init = FALSE; + GstVaapiDisplayX11Private *const priv = + gst_vaapi_display_x11_get_instance_private (display); - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_display_x11_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DISPLAY_CLASS (&g_class); + display->priv = priv; } /** @@ -426,7 +423,7 @@ gst_vaapi_display_x11_class (void) GstVaapiDisplay * gst_vaapi_display_x11_new (const gchar * display_name) { - return gst_vaapi_display_new (gst_vaapi_display_x11_class (), + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_X11, NULL), GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) display_name); } @@ -446,7 +443,7 @@ gst_vaapi_display_x11_new_with_display (Display * x11_display) { g_return_val_if_fail (x11_display, NULL); - return gst_vaapi_display_new (gst_vaapi_display_x11_class (), + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_X11, NULL), GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 5eca2c2c61..703545920b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -30,8 +30,9 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_DISPLAY_X11 (gst_vaapi_display_x11_get_type ()) #define GST_VAAPI_DISPLAY_X11(obj) \ - ((GstVaapiDisplayX11 *)(obj)) + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_DISPLAY_X11, GstVaapiDisplayX11)) typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11; @@ -51,6 +52,9 @@ void gst_vaapi_display_x11_set_synchronous (GstVaapiDisplayX11 * display, gboolean synchronous); +GType +gst_vaapi_display_x11_get_type (void) G_GNUC_CONST; + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_X11_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index 3225328d3b..9a26e8a40f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -32,14 +32,16 @@ G_BEGIN_DECLS #define GST_VAAPI_IS_DISPLAY_X11(display) \ - ((display) != NULL && \ - GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display) == GST_VAAPI_DISPLAY_TYPE_X11) + (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) + (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; @@ -97,13 +99,13 @@ struct _GstVaapiDisplayX11 /*< private >*/ GstVaapiDisplay parent_instance; - GstVaapiDisplayX11Private priv; + GstVaapiDisplayX11Private *priv; }; /** * GstVaapiDisplayX11Class: * - * VA/X11 display wrapper clas. + * VA/X11 display wrapper class. */ struct _GstVaapiDisplayX11Class { @@ -111,9 +113,6 @@ struct _GstVaapiDisplayX11Class GstVaapiDisplayClass parent_class; }; -void -gst_vaapi_display_x11_class_init (GstVaapiDisplayX11Class * klass); - G_GNUC_INTERNAL GstVideoFormat gst_vaapi_display_x11_get_pixmap_format (GstVaapiDisplayX11 * display, diff --git a/gst-libs/gst/vaapi/gstvaapitexture_egl.c b/gst-libs/gst/vaapi/gstvaapitexture_egl.c index 1df21e3a3b..260ffaa24f 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_egl.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_egl.c @@ -37,6 +37,9 @@ #include "gstvaapisurface_egl.h" #include "gstvaapifilter.h" +#define DEBUG 1 +#include "gstvaapidebug.h" + #define GST_VAAPI_TEXTURE_EGL(texture) \ ((GstVaapiTextureEGL *) (texture)) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c index dc5dfcb392..173e9dc035 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -23,6 +23,9 @@ #include "sysdeps.h" #include "gstvaapiutils_egl.h" +#define DEBUG 1 +#include "gstvaapidebug.h" + typedef struct egl_message_s EglMessage; struct egl_message_s { diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.h b/gst-libs/gst/vaapi/gstvaapiutils_egl.h index 1c5cdc3083..fa0820286b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.h @@ -29,9 +29,6 @@ #include "egl_compat.h" #include "gstvaapiminiobject.h" -GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapidisplay_egl); -#define GST_CAT_DEFAULT gst_debug_vaapidisplay_egl - typedef union egl_handle_s EglHandle; typedef struct egl_object_s EglObject; typedef struct egl_object_class_s EglObjectClass; diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 8bd4448f39..b706486f4c 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -31,17 +31,6 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); -#define GST_VAAPI_TYPE_DISPLAY \ - gst_vaapi_display_get_type () - -/* *INDENT-OFF* */ -static GType gst_vaapi_display_get_type (void) G_GNUC_CONST; -/* *INDENT-ON* */ - -G_DEFINE_BOXED_TYPE (GstVaapiDisplay, gst_vaapi_display, - (GBoxedCopyFunc) gst_vaapi_display_ref, - (GBoxedFreeFunc) gst_vaapi_display_unref); - static void _init_context_debug (void) { @@ -65,7 +54,7 @@ gst_vaapi_video_context_set_display (GstContext * context, structure = gst_context_writable_structure (context); gst_structure_set (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, - GST_VAAPI_TYPE_DISPLAY, display, NULL); + GST_TYPE_VAAPI_DISPLAY, display, NULL); } GstContext * @@ -91,7 +80,7 @@ gst_vaapi_video_context_get_display (GstContext * context, structure = gst_context_get_structure (context); return gst_structure_get (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, - GST_VAAPI_TYPE_DISPLAY, display_ptr, NULL); + GST_TYPE_VAAPI_DISPLAY, display_ptr, NULL); } static gboolean From 313860dea483458557fb83a543940660cd55cd0f Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 2 Nov 2016 18:37:00 +0900 Subject: [PATCH 2557/3781] libs: window: egl: pass native va display When creating a GstVaapiWindowEGL, it also creates native window by its own native display. It should pass the native display, either X11 or Wayland. https://bugzilla.gnome.org/show_bug.cgi?id=768266 --- gst-libs/gst/vaapi/gstvaapiwindow_egl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c index e511e5eba6..8cabd03e4d 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c @@ -228,7 +228,8 @@ gst_vaapi_window_egl_create (GstVaapiWindowEGL * window, g_return_val_if_fail (native_dpy_class != NULL, FALSE); - window->window = native_dpy_class->create_window (GST_VAAPI_DISPLAY (display), + window->window = + native_dpy_class->create_window (GST_VAAPI_DISPLAY (display->display), GST_VAAPI_ID_INVALID, *width, *height); if (!window->window) return FALSE; From 242e8018183c085835778b64f0b75fd33b3fcf19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 2 Nov 2016 15:38:52 +0100 Subject: [PATCH 2558/3781] plugins: log the GstVaapiDisplay name Now that GstVaapiDisplay is descendant of GstObject, it has a human-friendly name. Log it instead of the memory address. --- gst/vaapi/gstvaapipluginbase.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index aa3d814f82..4eb9f6f3d4 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -46,7 +46,7 @@ plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) display_name, plugin->display_name); gst_vaapi_display_replace (&plugin->display, NULL); } else { - GST_INFO_OBJECT (plugin, "set display %p", display); + GST_INFO_OBJECT (plugin, "set display %" GST_PTR_FORMAT, display); gst_vaapi_display_replace (&plugin->display, display); plugin->display_type = gst_vaapi_display_get_display_type (display); gst_vaapi_plugin_base_set_display_name (plugin, display_name); From be65508753df1908becb99aa8d591c1b7c719273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 2 Nov 2016 20:01:09 +0100 Subject: [PATCH 2559/3781] libs: display: egl: avoid recreate native display Instead of passing the native descriptor of the display, just pass the received GstVaapiDisplay and reuse it. --- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index 0c1dd9c9cb..7d3d27ee34 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -103,15 +103,7 @@ gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_display, const InitParams *params = (InitParams *) native_params; if (params->display) { -#if USE_X11 - if (params->display_type == GST_VAAPI_DISPLAY_TYPE_X11) - native_display = gst_vaapi_display_x11_new_with_display (params->display); -#endif -#if USE_WAYLAND - if (params->display_type == GST_VAAPI_DISPLAY_TYPE_WAYLAND) - native_display = - gst_vaapi_display_wayland_new_with_display (params->display); -#endif + native_display = params->display; } else { #if USE_X11 native_display = gst_vaapi_display_x11_new (NULL); @@ -125,7 +117,6 @@ gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_display, return FALSE; gst_vaapi_display_replace (&display->display, native_display); - gst_vaapi_display_unref (native_display); egl_display = egl_display_new (GST_VAAPI_DISPLAY_NATIVE (display->display)); if (!egl_display) @@ -338,7 +329,7 @@ gst_vaapi_display_egl_new (GstVaapiDisplay * display, guint gles_version) InitParams params; if (display) { - params.display = GST_VAAPI_DISPLAY_NATIVE (display); + params.display = display; params.display_type = GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display); } else { params.display = NULL; From 5ff513ec271e9b4f070f6f4f93d3d823a27b6828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 3 Nov 2016 08:31:16 +0100 Subject: [PATCH 2560/3781] libs: vaapitexturemap: trivial code-style fix --- gst-libs/gst/vaapi/gstvaapitexturemap.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexturemap.c b/gst-libs/gst/vaapi/gstvaapitexturemap.c index cb832dad78..0a17bac9fb 100644 --- a/gst-libs/gst/vaapi/gstvaapitexturemap.c +++ b/gst-libs/gst/vaapi/gstvaapitexturemap.c @@ -35,10 +35,11 @@ * * Base class for API-dependent texture map. */ -struct _GstVaapiTextureMap { +struct _GstVaapiTextureMap +{ GstObject parent_instance; - /*< private >*/ + /*< private > */ GHashTable *texture_map; }; @@ -47,7 +48,8 @@ struct _GstVaapiTextureMap { * * Base class for API-dependent texture map. */ -struct _GstVaapiTextureMapClass { +struct _GstVaapiTextureMapClass +{ GstObjectClass parent_class; }; From 40163885656f2ee55f9c5869bc841523e03deb14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Oct 2016 12:22:06 +0200 Subject: [PATCH 2561/3781] vaapivideomemory: category init when object define Move the Gstreamer debug category initialize to the GObject definition. --- gst/vaapi/gstvaapivideomemory.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 0006e49012..d2f5a8c738 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -579,8 +579,10 @@ gst_vaapi_video_memory_is_span (GstVaapiVideoMemory * mem1, #define GST_VAAPI_IS_VIDEO_ALLOCATOR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_ALLOCATOR)) -G_DEFINE_TYPE (GstVaapiVideoAllocator, - gst_vaapi_video_allocator, GST_TYPE_ALLOCATOR); +G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoAllocator, + gst_vaapi_video_allocator, GST_TYPE_ALLOCATOR, + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapivideomemory, "vaapivideomemory", 0, + "VA-API video memory allocator")); static void gst_vaapi_video_allocator_free (GstAllocator * allocator, GstMemory * mem) @@ -606,9 +608,6 @@ gst_vaapi_video_allocator_class_init (GstVaapiVideoAllocatorClass * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstAllocatorClass *const allocator_class = GST_ALLOCATOR_CLASS (klass); - GST_DEBUG_CATEGORY_INIT (gst_debug_vaapivideomemory, - "vaapivideomemory", 0, "VA-API video memory allocator"); - object_class->finalize = gst_vaapi_video_allocator_finalize; allocator_class->free = gst_vaapi_video_allocator_free; } From dcbd4112755fb5d9f0953cc5437356a532fd32b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Oct 2016 12:52:18 +0200 Subject: [PATCH 2562/3781] vaapivideomemory: store surface alloc flags in qdata For sake of consistency, we should add the requested surface allocation flags to the object's qdata structure. --- gst/vaapi/gstvaapivideomemory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index d2f5a8c738..0f63a3c05a 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -775,7 +775,7 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display, goto error_create_image_pool; gst_allocator_set_vaapi_video_info (GST_ALLOCATOR_CAST (allocator), - &allocator->image_info, 0); + &allocator->image_info, surface_alloc_flags); return GST_ALLOCATOR_CAST (allocator); /* ERRORS */ From 7e90ae4c2e0962376d2c256e6c226e98915cab0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Oct 2016 16:31:21 +0200 Subject: [PATCH 2563/3781] vaapivideomemory: error log is derive image fails Instead of a silently failure of the derive image, this patch log an error message according to the failure. --- gst/vaapi/gstvaapivideomemory.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 0f63a3c05a..b0d6fd13b5 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -692,12 +692,12 @@ allocator_configure_surface_info (GstVaapiDisplay * display, surface = new_surface (display, vinfo); if (!surface) - goto bail; + goto error_no_surface; image = gst_vaapi_surface_derive_image (surface); if (!image) - goto bail; + goto error_no_derive_image; if (!gst_vaapi_image_map (image)) - goto bail; + goto error_cannot_map; updated = gst_video_info_update_from_image (&allocator->surface_info, image); @@ -711,10 +711,28 @@ allocator_configure_surface_info (GstVaapiDisplay * display, gst_vaapi_image_unmap (image); bail: - if (surface) - gst_vaapi_object_unref (surface); if (image) gst_vaapi_object_unref (image); + if (surface) + gst_vaapi_object_unref (surface); + return; + +error_no_surface: + { + GST_ERROR_OBJECT (allocator, "Cannot create a VA Surface"); + return; + } +error_no_derive_image: + { + GST_ERROR_OBJECT (allocator, + "Cannot create a derived image from surface %p", surface); + goto bail; + } +error_cannot_map: + { + GST_ERROR_OBJECT (allocator, "Cannot map VA derived image %p", image); + goto bail; + } } static inline void From 1bc5f00dfea3c968d0086db21e7bd26c0b8d0344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Oct 2016 18:09:59 +0200 Subject: [PATCH 2564/3781] vaapivideomemory: log in perf category when copy Log in performance category when the derive image handling fails, falling back to memory copy. --- gst/vaapi/gstvaapivideomemory.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index b0d6fd13b5..468c6f612b 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -28,6 +28,7 @@ #include "gstvaapivideomemory.h" #include "gstvaapipluginutil.h" +GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE); GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapivideomemory); #define GST_CAT_DEFAULT gst_debug_vaapivideomemory @@ -45,6 +46,27 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapivideomemory); static void gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem); +static void +_init_performance_debug (void) +{ +#ifndef GST_DISABLE_GST_DEBUG + static volatile gsize _init = 0; + + if (g_once_init_enter (&_init)) { + GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE"); + g_once_init_leave (&_init, 1); + } +#endif +} + +static inline void +reset_image_usage (gboolean * flag) +{ + _init_performance_debug (); + GST_CAT_INFO (CAT_PERFORMANCE, "derive image failed, fallbacking to copy"); + *flag = FALSE; +} + static guchar * get_image_data (GstVaapiImage * image) { @@ -74,12 +96,11 @@ ensure_image (GstVaapiVideoMemory * mem) if (!mem->image && mem->use_direct_rendering) { mem->image = gst_vaapi_surface_derive_image (mem->surface); if (!mem->image) { - GST_WARNING ("failed to derive image, fallbacking to copy"); - mem->use_direct_rendering = FALSE; + reset_image_usage (&mem->use_direct_rendering); } else if (gst_vaapi_surface_get_format (mem->surface) != GST_VIDEO_INFO_FORMAT (mem->image_info)) { gst_vaapi_object_replace (&mem->image, NULL); - mem->use_direct_rendering = FALSE; + reset_image_usage (&mem->use_direct_rendering); } } From e98829878262e9cd328b7d7ad78e1adf78d03782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Oct 2016 16:49:22 +0200 Subject: [PATCH 2565/3781] vaapivideomemory: set direct rendering at run-time The way to experiment with the direct rendering is through and internal compiler pre-processor flag. The current change set enables a way to specified at run-time, as a flag passed to the allocator at instanciation time. --- gst/vaapi/gstvaapipluginbase.c | 6 ++- gst/vaapi/gstvaapivideomemory.c | 71 ++++++++++++++++++++------------- gst/vaapi/gstvaapivideomemory.h | 21 ++++++++-- 3 files changed, 65 insertions(+), 33 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 4eb9f6f3d4..d7665bac40 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -530,7 +530,8 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo) GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); } else { plugin->sinkpad_allocator = - gst_vaapi_video_allocator_new (plugin->display, vinfo, 0); + gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, + GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS); } return plugin->sinkpad_allocator != NULL; } @@ -542,7 +543,8 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo) return TRUE; plugin->srcpad_allocator = - gst_vaapi_video_allocator_new (plugin->display, vinfo, 0); + gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, + GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS); return plugin->srcpad_allocator != NULL; } diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 468c6f612b..5df6399b6b 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -37,9 +37,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapivideomemory); gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)) #endif -/* Defined if native VA surface formats are preferred over direct rendering */ -#define USE_NATIVE_FORMATS 1 - /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoMemory --- */ /* ------------------------------------------------------------------------ */ @@ -60,11 +57,23 @@ _init_performance_debug (void) } static inline void -reset_image_usage (gboolean * flag) +reset_image_usage (GstVaapiImageUsageFlags * flag) { _init_performance_debug (); GST_CAT_INFO (CAT_PERFORMANCE, "derive image failed, fallbacking to copy"); - *flag = FALSE; + *flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; +} + +static inline gboolean +use_native_formats (GstVaapiImageUsageFlags flag) +{ + return flag == GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; +} + +static inline gboolean +use_direct_rendering (GstVaapiImageUsageFlags flag) +{ + return flag == GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; } static guchar * @@ -93,14 +102,14 @@ new_image (GstVaapiDisplay * display, const GstVideoInfo * vip) static gboolean ensure_image (GstVaapiVideoMemory * mem) { - if (!mem->image && mem->use_direct_rendering) { + if (!mem->image && !use_native_formats (mem->usage_flag)) { mem->image = gst_vaapi_surface_derive_image (mem->surface); if (!mem->image) { - reset_image_usage (&mem->use_direct_rendering); + reset_image_usage (&mem->usage_flag); } else if (gst_vaapi_surface_get_format (mem->surface) != GST_VIDEO_INFO_FORMAT (mem->image_info)) { gst_vaapi_object_replace (&mem->image, NULL); - reset_image_usage (&mem->use_direct_rendering); + reset_image_usage (&mem->usage_flag); } } @@ -119,7 +128,7 @@ ensure_image (GstVaapiVideoMemory * mem) static gboolean ensure_image_is_current (GstVaapiVideoMemory * mem) { - if (mem->use_direct_rendering) + if (!use_native_formats (mem->usage_flag)) return TRUE; if (!GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET (mem, @@ -134,13 +143,14 @@ ensure_image_is_current (GstVaapiVideoMemory * mem) } static GstVaapiSurface * -new_surface (GstVaapiDisplay * display, const GstVideoInfo * vip) +new_surface (GstVaapiDisplay * display, const GstVideoInfo * vip, + GstVaapiImageUsageFlags usage_flag) { GstVaapiSurface *surface; GstVaapiChromaType chroma_type; /* Try with explicit format first */ - if (!USE_NATIVE_FORMATS && + if (!use_native_formats (usage_flag) && GST_VIDEO_INFO_FORMAT (vip) != GST_VIDEO_FORMAT_ENCODED) { surface = gst_vaapi_surface_new_with_format (display, GST_VIDEO_INFO_FORMAT (vip), GST_VIDEO_INFO_WIDTH (vip), @@ -190,7 +200,7 @@ ensure_surface (GstVaapiVideoMemory * mem) static gboolean ensure_surface_is_current (GstVaapiVideoMemory * mem) { - if (mem->use_direct_rendering) + if (!use_native_formats (mem->usage_flag)) return TRUE; if (!GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET (mem, @@ -342,7 +352,7 @@ gst_vaapi_video_memory_new (GstAllocator * base_allocator, mem->meta = meta ? gst_vaapi_video_meta_ref (meta) : NULL; mem->map_type = 0; mem->map_count = 0; - mem->use_direct_rendering = allocator->has_direct_rendering; + mem->usage_flag = allocator->usage_flag; GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); @@ -366,7 +376,7 @@ gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem) GstVaapiVideoAllocator *const allocator = GST_VAAPI_VIDEO_ALLOCATOR_CAST (GST_MEMORY_CAST (mem)->allocator); - if (mem->use_direct_rendering) + if (!use_native_formats (mem->usage_flag)) gst_vaapi_object_replace (&mem->image, NULL); else if (mem->image) { gst_vaapi_video_pool_put_object (allocator->image_pool, mem->image); @@ -692,26 +702,27 @@ gst_video_info_update_from_image (GstVideoInfo * vip, GstVaapiImage * image) static inline void allocator_configure_surface_info (GstVaapiDisplay * display, - GstVaapiVideoAllocator * allocator) + GstVaapiVideoAllocator * allocator, GstVaapiImageUsageFlags req_usage_flag) { const GstVideoInfo *vinfo; GstVaapiSurface *surface = NULL; GstVaapiImage *image = NULL; - gboolean updated; + gboolean updated, has_direct_rendering; GstVideoFormat fmt; vinfo = &allocator->video_info; + allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; fmt = gst_vaapi_video_format_get_best_native (GST_VIDEO_INFO_FORMAT (vinfo)); gst_video_info_set_format (&allocator->surface_info, fmt, GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); /* nothing to configure */ - if (USE_NATIVE_FORMATS || - GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) + if (use_native_formats (req_usage_flag) + || GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) return; - surface = new_surface (display, vinfo); + surface = new_surface (display, vinfo, req_usage_flag); if (!surface) goto error_no_surface; image = gst_vaapi_surface_derive_image (surface); @@ -722,15 +733,18 @@ allocator_configure_surface_info (GstVaapiDisplay * display, updated = gst_video_info_update_from_image (&allocator->surface_info, image); - allocator->has_direct_rendering = !USE_NATIVE_FORMATS && updated && - (GST_VAAPI_IMAGE_FORMAT (image) == GST_VIDEO_INFO_FORMAT (vinfo)); - - GST_INFO ("has direct-rendering for %s surfaces: %s", - GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info), - allocator->has_direct_rendering ? "yes" : "no"); + has_direct_rendering = updated && use_direct_rendering (req_usage_flag) + && (GST_VAAPI_IMAGE_FORMAT (image) == GST_VIDEO_INFO_FORMAT (vinfo)); gst_vaapi_image_unmap (image); + GST_INFO_OBJECT (allocator, "has %sdirect-rendering for %s surfaces", + has_direct_rendering ? "" : "no ", + GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info)); + + if (has_direct_rendering) + allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; + bail: if (image) gst_vaapi_object_unref (image); @@ -763,7 +777,7 @@ allocator_configure_image_info (GstVaapiDisplay * display, GstVaapiImage *image = NULL; const GstVideoInfo *vinfo; - if (allocator->has_direct_rendering) { + if (!use_native_formats (allocator->usage_flag)) { allocator->image_info = allocator->surface_info; return; } @@ -788,7 +802,8 @@ bail: GstAllocator * gst_vaapi_video_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint surface_alloc_flags) + const GstVideoInfo * vip, guint surface_alloc_flags, + GstVaapiImageUsageFlags req_usage_flag) { GstVaapiVideoAllocator *allocator; @@ -801,7 +816,7 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display, allocator->video_info = *vip; - allocator_configure_surface_info (display, allocator); + allocator_configure_surface_info (display, allocator, req_usage_flag); allocator->surface_pool = gst_vaapi_surface_pool_new_full (display, &allocator->surface_info, surface_alloc_flags); if (!allocator->surface_pool) diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 3f1957e475..f2446e4bf1 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -90,6 +90,20 @@ typedef enum GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT = GST_MEMORY_FLAG_LAST << 1, } GstVaapiVideoMemoryFlags; +/** + * GstVaapiImageUsageFlags: + * @GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS: will use vaCreateImage + + * va{Put,Get}Image when writing or reading onto the system memory. + * @GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER: will try to use + * vaDeriveImage with reading data onto the system memory. + * + * Set the usage of GstVaapiImage in GstVaapiVideoMemory. + **/ +typedef enum { + GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS, + GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER, +} GstVaapiImageUsageFlags; + /** * GstVaapiVideoMemory: * @@ -109,7 +123,7 @@ struct _GstVaapiVideoMemory GstVaapiVideoMeta *meta; guint map_type; gint map_count; - gboolean use_direct_rendering; + GstVaapiImageUsageFlags usage_flag; }; G_GNUC_INTERNAL @@ -166,7 +180,7 @@ struct _GstVaapiVideoAllocator GstVaapiVideoPool *surface_pool; GstVideoInfo image_info; GstVaapiVideoPool *image_pool; - gboolean has_direct_rendering; + GstVaapiImageUsageFlags usage_flag; }; /** @@ -186,7 +200,8 @@ gst_vaapi_video_allocator_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstAllocator * gst_vaapi_video_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint surface_alloc_flags); + const GstVideoInfo * vip, guint surface_alloc_flags, + GstVaapiImageUsageFlags req_usage_flag); /* ------------------------------------------------------------------------ */ /* --- GstVaapiDmaBufMemory --- */ From 7c692265d80b614d07dea38a590c16e6272586ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Oct 2016 17:02:49 +0200 Subject: [PATCH 2566/3781] vaapivideomemory: add direct upload flag Adds the direct-upload flag in the GstVaapiVideoAllocator and GstVaapiVideoMemory. It still doesn't apply any functional change. --- gst/vaapi/gstvaapivideomemory.c | 17 +++++++++++++++-- gst/vaapi/gstvaapivideomemory.h | 3 +++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 5df6399b6b..d26830b93a 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -76,6 +76,12 @@ use_direct_rendering (GstVaapiImageUsageFlags flag) return flag == GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; } +static inline gboolean +use_direct_uploading (GstVaapiImageUsageFlags flag) +{ + return flag == GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD; +} + static guchar * get_image_data (GstVaapiImage * image) { @@ -707,7 +713,7 @@ allocator_configure_surface_info (GstVaapiDisplay * display, const GstVideoInfo *vinfo; GstVaapiSurface *surface = NULL; GstVaapiImage *image = NULL; - gboolean updated, has_direct_rendering; + gboolean updated, has_direct_uploading, has_direct_rendering; GstVideoFormat fmt; vinfo = &allocator->video_info; @@ -735,15 +741,22 @@ allocator_configure_surface_info (GstVaapiDisplay * display, has_direct_rendering = updated && use_direct_rendering (req_usage_flag) && (GST_VAAPI_IMAGE_FORMAT (image) == GST_VIDEO_INFO_FORMAT (vinfo)); + has_direct_uploading = updated && use_direct_uploading (req_usage_flag) + && (GST_VAAPI_IMAGE_FORMAT (image) == GST_VIDEO_INFO_FORMAT (vinfo)); gst_vaapi_image_unmap (image); GST_INFO_OBJECT (allocator, "has %sdirect-rendering for %s surfaces", has_direct_rendering ? "" : "no ", GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info)); + GST_INFO_OBJECT (allocator, "has %sdirect-uploading for %s surfaces", + has_direct_uploading ? "" : "no ", + GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info)); - if (has_direct_rendering) + if (has_direct_rendering && !has_direct_uploading) allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; + else if (!has_direct_rendering && has_direct_uploading) + allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD; bail: if (image) diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index f2446e4bf1..c7a866ee7b 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -94,6 +94,8 @@ typedef enum * GstVaapiImageUsageFlags: * @GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS: will use vaCreateImage + * va{Put,Get}Image when writing or reading onto the system memory. + * @GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD: will try to use + * vaDeriveImage when writing data from the system memory. * @GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER: will try to use * vaDeriveImage with reading data onto the system memory. * @@ -101,6 +103,7 @@ typedef enum **/ typedef enum { GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS, + GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD, GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER, } GstVaapiImageUsageFlags; From ce8b14858fc14a3da68b2f87efba4790fe55ebcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 21 Oct 2016 11:57:55 +0200 Subject: [PATCH 2567/3781] vaapivideomemory: enhance logs for direct modes Print, conditionally, only the enabled direct mode. --- gst/vaapi/gstvaapivideomemory.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index d26830b93a..453f1b4a24 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -746,17 +746,15 @@ allocator_configure_surface_info (GstVaapiDisplay * display, gst_vaapi_image_unmap (image); - GST_INFO_OBJECT (allocator, "has %sdirect-rendering for %s surfaces", - has_direct_rendering ? "" : "no ", - GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info)); - GST_INFO_OBJECT (allocator, "has %sdirect-uploading for %s surfaces", - has_direct_uploading ? "" : "no ", - GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info)); - - if (has_direct_rendering && !has_direct_uploading) + if (has_direct_rendering && !has_direct_uploading) { allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; - else if (!has_direct_rendering && has_direct_uploading) + GST_INFO_OBJECT (allocator, "has direct-rendering for %s surfaces", + GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info)); + } else if (!has_direct_rendering && has_direct_uploading) { allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD; + GST_INFO_OBJECT (allocator, "has direct-uploading for %s surfaces", + GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info)); + } bail: if (image) From 2761e472af4817e4787ef06bc815bd2885be4d73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Oct 2016 19:31:58 +0200 Subject: [PATCH 2568/3781] vaapivideomemory: destroy derived image at unmap If the allocator was configured to use direct upload or rendering, the generated derived image created at mapping needs to be destroyed after unmapping, because, in order to process the surface, it should not be marked as "busy" by the driver. --- gst/vaapi/gstvaapivideomemory.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 453f1b4a24..69745ebb6d 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -325,6 +325,11 @@ gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane, GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); } + + if (!use_native_formats (mem->usage_flag)) { + gst_vaapi_video_meta_set_image (mem->meta, NULL); + gst_vaapi_video_memory_reset_image (mem); + } } } return TRUE; From e0d73d613e3eae919c8ddcad9eb80081d8f6836a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 24 Oct 2016 19:25:27 +0200 Subject: [PATCH 2569/3781] plugins: receive caps in ensure_sinkpad_allocator() Instead of receiving the GstVideoInfo structure as parameter, get the original GstCaps from ensure_sinkpad_buffer_pool(), in this way we could decide better which allocator instantiate. --- gst/vaapi/gstvaapipluginbase.c | 56 +++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index d7665bac40..dcf9d4c4ae 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -519,21 +519,43 @@ reset_allocator (GstAllocator * allocator, GstVideoInfo * vinfo) } static gboolean -ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo) +ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, + guint * size) { - if (!reset_allocator (plugin->sinkpad_allocator, vinfo)) + GstVideoInfo vinfo; + + if (!gst_video_info_from_caps (&vinfo, caps)) + goto error_invalid_caps; + gst_video_info_force_nv12_if_encoded (&vinfo); + *size = GST_VIDEO_INFO_SIZE (&vinfo); + + if (!reset_allocator (plugin->sinkpad_allocator, &vinfo)) return TRUE; if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) { plugin->sinkpad_allocator = - gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo, + gst_vaapi_dmabuf_allocator_new (plugin->display, &vinfo, GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); } else { plugin->sinkpad_allocator = - gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, + gst_vaapi_video_allocator_new (plugin->display, &vinfo, 0, GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS); } - return plugin->sinkpad_allocator != NULL; + if (!plugin->sinkpad_allocator) + goto error_create_allocator; + return TRUE; + + /* ERRORS */ +error_invalid_caps: + { + GST_ERROR_OBJECT (plugin, "invalid caps %" GST_PTR_FORMAT, caps); + return FALSE; + } +error_create_allocator: + { + GST_ERROR_OBJECT (plugin, "failed to create sink pad's allocator"); + return FALSE; + } } static gboolean @@ -636,7 +658,6 @@ static gboolean ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) { GstBufferPool *pool; - GstVideoInfo vi; guint size; /* video decoders don't use a buffer pool in the sink pad */ @@ -655,35 +676,20 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) plugin->sinkpad_buffer_size = 0; } - if (!gst_video_info_from_caps (&vi, caps)) - goto error_invalid_caps; - gst_video_info_force_nv12_if_encoded (&vi); + if (!ensure_sinkpad_allocator (plugin, caps, &size)) + goto error; - if (!ensure_sinkpad_allocator (plugin, &vi)) - goto error_create_allocator; - - size = GST_VIDEO_INFO_SIZE (&vi); gst_allocator_get_vaapi_image_size (plugin->sinkpad_allocator, &size); pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, 0, 0, GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, plugin->sinkpad_allocator); if (!pool) - goto error_create_pool; + goto error; plugin->sinkpad_buffer_pool = pool; plugin->sinkpad_buffer_size = size; return TRUE; /* ERRORS */ -error_invalid_caps: - { - GST_ERROR_OBJECT (plugin, "invalid caps %" GST_PTR_FORMAT, caps); - return FALSE; - } -error_create_allocator: - { - GST_ERROR_OBJECT (plugin, "failed to create allocator"); - return FALSE; - } -error_create_pool: +error: { /* error message already sent */ return FALSE; From 1605a2646a2c59cf5c45a653538e634c00314ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 21 Oct 2016 11:21:04 +0200 Subject: [PATCH 2570/3781] pluginutil: add gst_caps_is_video_raw() --- gst/vaapi/gstvaapipluginutil.c | 15 +++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 88223ba39a..2dcfbdbe50 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -661,6 +661,21 @@ gst_caps_has_vaapi_surface (GstCaps * caps) return _gst_caps_has_feature (caps, GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE); } +gboolean +gst_caps_is_video_raw (GstCaps * caps) +{ + GstStructure *structure; + + g_return_val_if_fail (caps != NULL, FALSE); + + if (!gst_caps_is_fixed (caps)) + return FALSE; + if (!_gst_caps_has_feature (caps, GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY)) + return FALSE; + structure = gst_caps_get_structure (caps, 0); + return gst_structure_has_name (structure, "video/x-raw"); +} + void gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, guint width, guint height) diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 34aea9cd1e..eb5633bf93 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -118,6 +118,10 @@ G_GNUC_INTERNAL gboolean gst_caps_has_vaapi_surface (GstCaps * caps); +G_GNUC_INTERNAL +gboolean +gst_caps_is_video_raw (GstCaps * caps); + G_GNUC_INTERNAL void gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format, From 02f16e82e948231a665824c30c065128ac9a1b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Oct 2016 19:37:01 +0200 Subject: [PATCH 2571/3781] plugins: enable direct upload if raw video Enable the direct upload with linear surfaces if the negotiated sink caps are video/x-raw without features. --- gst/vaapi/gstvaapipluginbase.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index dcf9d4c4ae..42226806a7 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -523,6 +523,8 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, guint * size) { GstVideoInfo vinfo; + GstVaapiImageUsageFlags usage_flag = + GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; if (!gst_video_info_from_caps (&vinfo, caps)) goto error_invalid_caps; @@ -536,11 +538,18 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, plugin->sinkpad_allocator = gst_vaapi_dmabuf_allocator_new (plugin->display, &vinfo, GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); - } else { - plugin->sinkpad_allocator = - gst_vaapi_video_allocator_new (plugin->display, &vinfo, 0, - GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS); + goto bail; } + + /* enable direct upload if upstream requests raw video */ + if (gst_caps_is_video_raw (caps)) { + usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD; + GST_INFO_OBJECT (plugin, "enabling direct upload in sink allocator"); + } + plugin->sinkpad_allocator = + gst_vaapi_video_allocator_new (plugin->display, &vinfo, 0, usage_flag); + +bail: if (!plugin->sinkpad_allocator) goto error_create_allocator; return TRUE; From faebca3383b49275b64b6b11b0e0884741ad8858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 24 Oct 2016 20:09:59 +0200 Subject: [PATCH 2572/3781] plugins: move src allocator error to instantiator Just as we did in ensure_sinkpad_allocator(), let's move the error message into the ensure_srcpad_allocator() from the caller, gst_vaapi_plugin_base_decide_allocation() --- gst/vaapi/gstvaapipluginbase.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 42226806a7..70ebb3bfcf 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -576,7 +576,16 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo) plugin->srcpad_allocator = gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS); - return plugin->srcpad_allocator != NULL; + if (!plugin->srcpad_allocator) + goto error_create_allocator; + return TRUE; + + /* ERRORS */ +error_create_allocator: + { + GST_ERROR_OBJECT (plugin, "failed to create src pad's allocator"); + return FALSE; + } } /** @@ -884,13 +893,13 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!pool) { if (!ensure_srcpad_allocator (plugin, &vi)) - goto error_create_allocator; + goto error; /* Update video size with allocator's image size */ gst_allocator_get_vaapi_image_size (plugin->srcpad_allocator, &size); pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, min, max, pool_options, plugin->srcpad_allocator); if (!pool) - goto error_create_pool; + goto error; } if (update_pool) @@ -919,12 +928,7 @@ error_ensure_display: plugin->display_type_req); return FALSE; } -error_create_allocator: - { - GST_ERROR_OBJECT (plugin, "failed to create allocator"); - return FALSE; - } -error_create_pool: +error: { /* error message already sent */ return FALSE; From 202110bded181192c1b571d51968d2b15cbe7478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 21 Oct 2016 11:48:54 +0200 Subject: [PATCH 2573/3781] plugins: direct render when raw video Enable the direct rendering with linear surfaces if the negotiated src caps are video/x-raw without features. Pass also the caps, since they are needed to know the requested caps features. --- gst/vaapi/gstvaapipluginbase.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 70ebb3bfcf..00a7c204cd 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -568,14 +568,23 @@ error_create_allocator: } static gboolean -ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo) +ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, + GstCaps * caps) { + GstVaapiImageUsageFlags usage_flag = + GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; + if (!reset_allocator (plugin->srcpad_allocator, vinfo)) return TRUE; + /* enable direct rendering if downstream requests raw video */ + if (caps && gst_caps_is_video_raw (caps)) { + usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; + GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); + } + plugin->srcpad_allocator = - gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, - GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS); + gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag); if (!plugin->srcpad_allocator) goto error_create_allocator; return TRUE; @@ -892,7 +901,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, } if (!pool) { - if (!ensure_srcpad_allocator (plugin, &vi)) + if (!ensure_srcpad_allocator (plugin, &vi, caps)) goto error; /* Update video size with allocator's image size */ gst_allocator_get_vaapi_image_size (plugin->srcpad_allocator, &size); From 3578716a4ffaa01d0cbd85f34caf10749c0f15ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 3 Nov 2016 09:31:17 +0100 Subject: [PATCH 2574/3781] plugins: update GstGL deprecated symbol GST_GL_TYPE_CONTEXT was deprecated. Now it is GST_TYPE_GL_CONTEXT. --- gst/vaapi/gstvaapipluginbase.c | 2 +- gst/vaapi/gstvaapivideocontext.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 00a7c204cd..a08815dbe2 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -855,7 +855,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gst_query_parse_nth_allocation_meta (query, idx, ¶ms); if (params) { - if (gst_structure_get (params, "gst.gl.GstGLContext", GST_GL_TYPE_CONTEXT, + if (gst_structure_get (params, "gst.gl.GstGLContext", GST_TYPE_GL_CONTEXT, &gl_context, NULL) && gl_context) { gst_vaapi_plugin_base_set_gl_context (plugin, gl_context); gst_object_unref (gl_context); diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index b706486f4c..c16cc873a5 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -244,14 +244,14 @@ gst_vaapi_find_gl_local_context (GstElement * element, gst_query_parse_context (query, &context); if (context) { s = gst_context_get_structure (context); - gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &gl_context, NULL); + gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &gl_context, NULL); } } if (!gl_context && _gst_context_run_query (element, query, GST_PAD_SINK)) { gst_query_parse_context (query, &context); if (context) { s = gst_context_get_structure (context); - gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &gl_context, NULL); + gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &gl_context, NULL); } } gst_query_unref (query); From b1f6da98de4a858350323889320fa6baa785516e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 19 Oct 2016 19:04:20 +0200 Subject: [PATCH 2575/3781] libs: fix code style for errors --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 24 ++-- gst-libs/gst/vaapi/gstvaapicodedbuffer.c | 7 +- gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c | 7 +- gst-libs/gst/vaapi/gstvaapicontext.c | 7 +- gst-libs/gst/vaapi/gstvaapicontext_overlay.c | 14 ++- gst-libs/gst/vaapi/gstvaapidecoder.c | 7 +- gst-libs/gst/vaapi/gstvaapidecoder_dpb.c | 7 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 103 ++++++++++++------ gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 15 ++- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 13 ++- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 15 ++- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 9 +- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 9 +- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 9 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 7 +- gst-libs/gst/vaapi/gstvaapidisplaycache.c | 7 +- gst-libs/gst/vaapi/gstvaapiencoder.c | 8 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 12 +- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 12 +- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 13 ++- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 24 ++-- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 24 ++-- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 19 +++- gst-libs/gst/vaapi/gstvaapifilter.c | 62 +++++++---- gst-libs/gst/vaapi/gstvaapiimage.c | 14 ++- gst-libs/gst/vaapi/gstvaapiimagepool.c | 7 +- gst-libs/gst/vaapi/gstvaapiparser_frame.c | 7 +- gst-libs/gst/vaapi/gstvaapipixmap.c | 14 ++- gst-libs/gst/vaapi/gstvaapisubpicture.c | 7 +- gst-libs/gst/vaapi/gstvaapisurface.c | 21 +++- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 7 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 14 ++- gst-libs/gst/vaapi/gstvaapitexture.c | 7 +- gst-libs/gst/vaapi/gstvaapiutils.c | 7 +- gst-libs/gst/vaapi/gstvaapiutils_egl.c | 49 ++++++--- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 29 +++-- gst-libs/gst/vaapi/gstvaapiwindow.c | 7 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 14 ++- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 37 ++++--- 39 files changed, 463 insertions(+), 212 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index 358a34e944..a9b3485806 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -177,9 +177,11 @@ gst_vaapi_buffer_proxy_new (guintptr handle, guint type, gsize size, /* ERRORS */ error_unsupported_mem_type: - GST_ERROR ("unsupported buffer type (%d)", proxy->type); - gst_vaapi_buffer_proxy_unref_internal (proxy); - return NULL; + { + GST_ERROR ("unsupported buffer type (%d)", proxy->type); + gst_vaapi_buffer_proxy_unref_internal (proxy); + return NULL; + } #else return NULL; #endif @@ -214,13 +216,17 @@ gst_vaapi_buffer_proxy_new_from_object (GstVaapiObject * object, /* ERRORS */ error_unsupported_mem_type: - GST_ERROR ("unsupported buffer type (%d)", proxy->type); - gst_vaapi_buffer_proxy_unref_internal (proxy); - return NULL; + { + GST_ERROR ("unsupported buffer type (%d)", proxy->type); + gst_vaapi_buffer_proxy_unref_internal (proxy); + return NULL; + } error_acquire_handle: - GST_ERROR ("failed to acquire the underlying VA buffer handle"); - gst_vaapi_buffer_proxy_unref_internal (proxy); - return NULL; + { + GST_ERROR ("failed to acquire the underlying VA buffer handle"); + gst_vaapi_buffer_proxy_unref_internal (proxy); + return NULL; + } #else return NULL; #endif diff --git a/gst-libs/gst/vaapi/gstvaapicodedbuffer.c b/gst-libs/gst/vaapi/gstvaapicodedbuffer.c index 5ae15cf783..3680d2d4c8 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbuffer.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbuffer.c @@ -128,9 +128,12 @@ gst_vaapi_coded_buffer_new (GstVaapiContext * context, guint buf_size) goto error; return buf; + /* ERRORS */ error: - gst_vaapi_object_unref (buf); - return NULL; + { + gst_vaapi_object_unref (buf); + return NULL; + } } /* diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c index bcf471abf2..d5c42828f3 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c @@ -100,9 +100,12 @@ gst_vaapi_coded_buffer_proxy_new_from_pool (GstVaapiCodedBufferPool * pool) gst_vaapi_object_ref (proxy->buffer); return proxy; + /* ERRORS */ error: - gst_vaapi_coded_buffer_proxy_unref (proxy); - return NULL; + { + gst_vaapi_coded_buffer_proxy_unref (proxy); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 63e4dd6ac5..4017c7bb1d 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -368,9 +368,12 @@ gst_vaapi_context_new (GstVaapiDisplay * display, goto error; return context; + /* ERRORS */ error: - gst_vaapi_object_unref (context); - return NULL; + { + gst_vaapi_object_unref (context); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapicontext_overlay.c b/gst-libs/gst/vaapi/gstvaapicontext_overlay.c index 0d670b03db..9059e3b8a9 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext_overlay.c +++ b/gst-libs/gst/vaapi/gstvaapicontext_overlay.c @@ -120,9 +120,12 @@ overlay_rectangle_new (GstVideoOverlayRectangle * rect, render_rect->height = height; return overlay; + /* ERRORS */ error: - overlay_rectangle_unref (overlay); - return NULL; + { + overlay_rectangle_unref (overlay); + return NULL; + } } static void @@ -438,7 +441,10 @@ gst_vaapi_context_apply_composition (GstVaapiContext * context, return FALSE; return TRUE; + /* ERRORS */ error: - gst_vaapi_context_overlay_reset (context); - return FALSE; + { + gst_vaapi_context_overlay_reset (context); + return FALSE; + } } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 498cbc170c..123b5a3353 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -531,9 +531,12 @@ gst_vaapi_decoder_new (const GstVaapiDecoderClass * klass, goto error; return decoder; + /* ERRORS */ error: - gst_vaapi_decoder_unref (decoder); - return NULL; + { + gst_vaapi_decoder_unref (decoder); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c index b9531fa8e2..7825c9dc61 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_dpb.c @@ -94,9 +94,12 @@ dpb_new (guint max_pictures) goto error; return dpb; + /* ERRORS */ error: - gst_vaapi_dpb_unref (dpb); - return NULL; + { + gst_vaapi_dpb_unref (dpb); + return NULL; + } } static gint diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index e8651a146d..4c6dc03675 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1144,12 +1144,14 @@ mvc_reset (GstVaapiDecoderH264 * decoder) /* ERRORS */ error_allocate: - g_free (priv->prev_ref_frames); - priv->prev_ref_frames = NULL; - g_free (priv->prev_frames); - priv->prev_frames = NULL; - priv->prev_frames_alloc = 0; - return FALSE; + { + g_free (priv->prev_ref_frames); + priv->prev_ref_frames = NULL; + g_free (priv->prev_frames); + priv->prev_frames = NULL; + priv->prev_frames_alloc = 0; + return FALSE; + } } static GstVaapiDecoderStatus @@ -1627,15 +1629,20 @@ decode_current_picture (GstVaapiDecoderH264 * decoder) 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; + { + /* 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; + } drop_frame: - priv->decoder_state = 0; - priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME; - return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; + { + priv->decoder_state = 0; + priv->pic_structure = GST_H264_SEI_PIC_STRUCT_FRAME; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; + } } static GstVaapiDecoderStatus @@ -2990,8 +2997,10 @@ fill_picture_first_field_gap (GstVaapiDecoderH264 * decoder, /* ERRORS */ error_allocate_field: - GST_ERROR ("failed to allocate missing field for current frame store"); - return NULL; + { + GST_ERROR ("failed to allocate missing field for current frame store"); + return NULL; + } } static gboolean @@ -3033,11 +3042,15 @@ cleanup: /* ERRORS */ error_exec_ref_pic_marking: - GST_ERROR ("failed to execute reference picture marking process"); - goto cleanup; + { + GST_ERROR ("failed to execute reference picture marking process"); + goto cleanup; + } error_dpb_add: - GST_ERROR ("failed to store lost picture into the DPB"); - goto cleanup; + { + GST_ERROR ("failed to store lost picture into the DPB"); + goto cleanup; + } } static GstVaapiPictureH264 * @@ -3096,17 +3109,25 @@ fill_picture_other_field_gap (GstVaapiDecoderH264 * decoder, /* ERRORS */ error_find_field: - GST_ERROR ("failed to find field with POC nearest to %d", f0->base.poc); - return NULL; + { + GST_ERROR ("failed to find field with POC nearest to %d", f0->base.poc); + return NULL; + } error_allocate_field: - GST_ERROR ("failed to allocate missing field for previous frame store"); - return NULL; + { + GST_ERROR ("failed to allocate missing field for previous frame store"); + return NULL; + } error_exec_ref_pic_marking: - GST_ERROR ("failed to execute reference picture marking process"); - return NULL; + { + GST_ERROR ("failed to execute reference picture marking process"); + return NULL; + } error_append_field: - GST_ERROR ("failed to add missing field into previous frame store"); - return NULL; + { + GST_ERROR ("failed to add missing field into previous frame store"); + return NULL; + } } static gboolean @@ -3206,14 +3227,20 @@ cleanup: /* ERRORS */ error_allocate_picture: - GST_ERROR ("failed to allocate lost picture"); - goto cleanup; + { + GST_ERROR ("failed to allocate lost picture"); + goto cleanup; + } error_exec_ref_pic_marking: - GST_ERROR ("failed to execute reference picture marking process"); - goto cleanup; + { + GST_ERROR ("failed to execute reference picture marking process"); + goto cleanup; + } error_dpb_add: - GST_ERROR ("failed to store lost picture into the DPB"); - goto cleanup; + { + GST_ERROR ("failed to store lost picture into the DPB"); + goto cleanup; + } } static gboolean @@ -4307,8 +4334,10 @@ gst_vaapi_decoder_h264_decode_codec_data (GstVaapiDecoder * base_decoder, status = GST_VAAPI_DECODER_STATUS_SUCCESS; cleanup: - gst_vaapi_parser_info_h264_replace (&pi, NULL); - return status; + { + gst_vaapi_parser_info_h264_replace (&pi, NULL); + return status; + } } static GstVaapiDecoderStatus @@ -4547,8 +4576,10 @@ gst_vaapi_decoder_h264_parse (GstVaapiDecoder * base_decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; exit: - gst_vaapi_parser_info_h264_unref (pi); - return status; + { + gst_vaapi_parser_info_h264_unref (pi); + return status; + } } static GstVaapiDecoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index d44047c7a8..6147e0c89b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1309,13 +1309,18 @@ decode_current_picture (GstVaapiDecoderH265 * decoder) 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; + { + gst_vaapi_picture_replace (&priv->current_picture, NULL); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } drop_frame: - priv->decoder_state = 0; - priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; - return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; + { + priv->decoder_state = 0; + priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; + } } static GstVaapiDecoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index d199bb2f9e..bef1eb71f2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -235,13 +235,18 @@ decode_current_picture (GstVaapiDecoderJpeg * decoder) 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; + { + 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; + { + priv->decoder_state = 0; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; + } } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 46d1e8e1e4..cb05b6e7b8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -559,14 +559,19 @@ decode_current_picture (GstVaapiDecoderMpeg2 * decoder) } 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; + { + /* 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; + } drop_frame: - priv->state &= GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS; - return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; + { + priv->state &= GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS; + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; + } } static GstVaapiDecoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index b7929a3ae7..256f017c46 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -248,10 +248,13 @@ decode_current_picture (GstVaapiDecoderVC1 * decoder) } 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; + { + /* 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 diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index 8bfb5c1592..cac5036a18 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -514,10 +514,13 @@ decode_current_picture (GstVaapiDecoderVp8 * decoder) 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; + { + /* 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 diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 0443488feb..1376834810 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -531,10 +531,13 @@ ret: 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; + { + /* 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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index d10d5657fb..01b7d3aeb7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1121,9 +1121,12 @@ gst_vaapi_display_new (GstVaapiDisplay * display, goto error; return display; + /* ERRORS */ error: - gst_vaapi_display_unref_internal (display); - return NULL; + { + gst_vaapi_display_unref_internal (display); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c index f5c6069a77..9c4680c5e0 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ b/gst-libs/gst/vaapi/gstvaapidisplaycache.c @@ -82,9 +82,12 @@ cache_entry_new (const GstVaapiDisplayInfo * di) } return entry; + /* ERRORS */ error: - cache_entry_free (entry); - return NULL; + { + cache_entry_free (entry); + return NULL; + } } static inline gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index f900eff3d4..b8cd4f1341 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -579,6 +579,7 @@ is_chroma_type_supported (GstVaapiEncoder * encoder) return TRUE; + /* ERRORS */ unsupported: { GST_ERROR ("We only support YUV 4:2:0 and YUV 4:2:2 for encoding. " @@ -1132,9 +1133,12 @@ gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass, goto error; return encoder; + /* ERRORS */ error: - gst_vaapi_encoder_unref (encoder); - return NULL; + { + gst_vaapi_encoder_unref (encoder); + return NULL; + } } /** Returns a GType for the #GstVaapiEncoderTune set */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index c5c1a2000c..49a7988bf8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2526,11 +2526,15 @@ gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base_encoder, goto error; return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ error: - if (reconstruct) - gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), - reconstruct); - return ret; + { + if (reconstruct) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); + return ret; + } } static GstVaapiEncoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 48629b6ad4..a838d97f37 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2091,11 +2091,15 @@ gst_vaapi_encoder_h265_encode (GstVaapiEncoder * base_encoder, goto error; return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ error: - if (reconstruct) - gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), - reconstruct); - return ret; + { + if (reconstruct) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); + return ret; + } } static GstVaapiEncoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index f669d8383c..b335d9782e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -651,6 +651,7 @@ ensure_packed_headers (GstVaapiEncoderJpeg * encoder, return TRUE; + /* ERRORS */ error_create_packed_hdr: { GST_ERROR ("failed to create packed raw data header buffer"); @@ -688,11 +689,15 @@ gst_vaapi_encoder_jpeg_encode (GstVaapiEncoder * base_encoder, reconstruct); return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ error: - if (reconstruct) - gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), - reconstruct); - return ret; + { + if (reconstruct) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); + return ret; + } } static GstVaapiEncoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 9333307864..ccb495d712 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -426,9 +426,12 @@ ensure_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) gst_vaapi_codec_object_replace (&sequence, NULL); return TRUE; + /* ERRORS */ error: - gst_vaapi_codec_object_replace (&sequence, NULL); - return FALSE; + { + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; + } } static gboolean @@ -570,11 +573,15 @@ gst_vaapi_encoder_mpeg2_encode (GstVaapiEncoder * base_encoder, reconstruct); return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ error: - if (reconstruct) - gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), - reconstruct); - return ret; + { + if (reconstruct) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); + return ret; + } } static GstVaapiEncoderStatus @@ -715,8 +722,11 @@ gst_vaapi_encoder_mpeg2_reconfigure (GstVaapiEncoder * base_encoder) goto error; return set_context_info (base_encoder); + /* ERRORS */ error: - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + { + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index af54d9195c..a002347169 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -247,9 +247,12 @@ ensure_sequence (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) gst_vaapi_codec_object_replace (&sequence, NULL); return TRUE; + /* ERRORS */ error: - gst_vaapi_codec_object_replace (&sequence, NULL); - return FALSE; + { + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; + } } static gboolean @@ -384,11 +387,15 @@ gst_vaapi_encoder_vp8_encode (GstVaapiEncoder * base_encoder, } return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ error: - if (reconstruct) - gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), - reconstruct); - return ret; + { + if (reconstruct) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); + return ret; + } } static GstVaapiEncoderStatus @@ -446,8 +453,11 @@ gst_vaapi_encoder_vp8_reconfigure (GstVaapiEncoder * base_encoder) return set_context_info (base_encoder); + /* ERRORS */ error: - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + { + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 0069648ce6..7b53775828 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -207,9 +207,12 @@ ensure_sequence (GstVaapiEncoderVP9 * encoder, GstVaapiEncPicture * picture) gst_vaapi_codec_object_replace (&sequence, NULL); return TRUE; + /* ERRORS */ error: - gst_vaapi_codec_object_replace (&sequence, NULL); - return FALSE; + { + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; + } } static void @@ -364,11 +367,15 @@ gst_vaapi_encoder_vp9_encode (GstVaapiEncoder * base_encoder, 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; + { + if (reconstruct) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); + return ret; + } } static GstVaapiEncoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 6eb7446006..1405a0ec47 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -191,9 +191,12 @@ vpp_get_filters_unlocked (GstVaapiFilter * filter, guint * num_filters_ptr) *num_filters_ptr = num_filters; return filters; + /* ERRORS */ error: - g_free (filters); - return NULL; + { + g_free (filters); + return NULL; + } } static VAProcFilterType * @@ -238,9 +241,12 @@ vpp_get_filter_caps_unlocked (GstVaapiFilter * filter, VAProcFilterType type, *num_caps_ptr = num_caps; return caps; + /* ERRORS */ error: - g_free (caps); - return NULL; + { + g_free (caps); + return NULL; + } } static gpointer @@ -495,9 +501,12 @@ op_data_new (GstVaapiFilterOp op, GParamSpec * pspec) } return op_data; + /* ERRORS */ error: - op_data_free (op_data); - return NULL; + { + op_data_free (op_data); + return NULL; + } } static inline gpointer @@ -608,9 +617,12 @@ get_operations_default (void) } return ops; + /* ERRORS */ error: - g_ptr_array_unref (ops); - return NULL; + { + g_ptr_array_unref (ops); + return NULL; + } } /* Get the ordered list of operations, based on VA/VPP queries */ @@ -675,12 +687,15 @@ get_operations_ordered (GstVaapiFilter * filter, GPtrArray * default_ops) g_ptr_array_unref (default_ops); return ops; + /* ERRORS */ error: - g_free (filter_caps); - g_free (filters); - g_ptr_array_unref (ops); - g_ptr_array_unref (default_ops); - return NULL; + { + g_free (filter_caps); + g_free (filters); + g_ptr_array_unref (ops); + g_ptr_array_unref (default_ops); + return NULL; + } } #endif @@ -1027,8 +1042,11 @@ ensure_formats (GstVaapiFilter * filter) g_free (surface_attribs); return TRUE; + /* ERRORS */ error: - g_free (surface_attribs); + { + g_free (surface_attribs); + } #endif return FALSE; } @@ -1175,9 +1193,12 @@ gst_vaapi_filter_new (GstVaapiDisplay * display) goto error; return filter; + /* ERRORS */ error: - gst_vaapi_filter_unref (filter); - return NULL; + { + gst_vaapi_filter_unref (filter); + return NULL; + } #else GST_WARNING ("video processing is not supported, " "please consider an upgrade to VA-API >= 0.34"); @@ -1528,10 +1549,13 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, vaapi_destroy_buffer (filter->va_display, &pipeline_param_buf_id); return GST_VAAPI_FILTER_STATUS_SUCCESS; + /* ERRORS */ error: - deint_refs_clear_all (filter); - vaapi_destroy_buffer (filter->va_display, &pipeline_param_buf_id); - return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED; + { + deint_refs_clear_all (filter); + vaapi_destroy_buffer (filter->va_display, &pipeline_param_buf_id); + return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED; + } #endif return GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_OPERATION; } diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index b1f530112d..4fb535fcab 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -258,9 +258,12 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiImage, goto error; return image; + /* ERRORS */ error: - gst_vaapi_object_unref (image); - return NULL; + { + gst_vaapi_object_unref (image); + return NULL; + } } /** @@ -297,9 +300,12 @@ gst_vaapi_image_new_with_image (GstVaapiDisplay * display, VAImage * va_image) goto error; return image; + /* ERRORS */ error: - gst_vaapi_object_unref (image); - return NULL; + { + gst_vaapi_object_unref (image); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c index 3a8dc76a49..f64a367945 100644 --- a/gst-libs/gst/vaapi/gstvaapiimagepool.c +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -111,7 +111,10 @@ gst_vaapi_image_pool_new (GstVaapiDisplay * display, const GstVideoInfo * vip) goto error; return pool; + /* ERRORS */ error: - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pool)); - return NULL; + { + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pool)); + return NULL; + } } diff --git a/gst-libs/gst/vaapi/gstvaapiparser_frame.c b/gst-libs/gst/vaapi/gstvaapiparser_frame.c index 1f75e814bb..4eda63f934 100644 --- a/gst-libs/gst/vaapi/gstvaapiparser_frame.c +++ b/gst-libs/gst/vaapi/gstvaapiparser_frame.c @@ -98,9 +98,12 @@ gst_vaapi_parser_frame_new (guint width, guint height) frame->output_offset = 0; return frame; + /* ERRORS */ error: - gst_vaapi_parser_frame_unref (frame); - return NULL; + { + gst_vaapi_parser_frame_unref (frame); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapipixmap.c b/gst-libs/gst/vaapi/gstvaapipixmap.c index aba117c53e..33acb2ea00 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap.c +++ b/gst-libs/gst/vaapi/gstvaapipixmap.c @@ -70,9 +70,12 @@ gst_vaapi_pixmap_new (const GstVaapiPixmapClass * pixmap_class, goto error; return pixmap; + /* ERRORS */ error: - gst_vaapi_pixmap_unref_internal (pixmap); - return NULL; + { + gst_vaapi_pixmap_unref_internal (pixmap); + return NULL; + } } GstVaapiPixmap * @@ -91,9 +94,12 @@ gst_vaapi_pixmap_new_from_native (const GstVaapiPixmapClass * pixmap_class, goto error; return pixmap; + /* ERRORS */ error: - gst_vaapi_pixmap_unref_internal (pixmap); - return NULL; + { + gst_vaapi_pixmap_unref_internal (pixmap); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 021de15d47..f39f90a4b0 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -156,9 +156,12 @@ GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture) goto error; return subpicture; + /* ERRORS */ error: - gst_vaapi_object_unref (subpicture); - return NULL; + { + gst_vaapi_object_unref (subpicture); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 4ef616eec9..64add345ba 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -344,9 +344,12 @@ gst_vaapi_surface_new (GstVaapiDisplay * display, goto error; return surface; + /* ERRORS */ error: - gst_vaapi_object_unref (surface); - return NULL; + { + gst_vaapi_object_unref (surface); + return NULL; + } } /** @@ -380,9 +383,12 @@ gst_vaapi_surface_new_full (GstVaapiDisplay * display, goto error; return surface; + /* ERRORS */ error: - gst_vaapi_object_unref (surface); - return NULL; + { + gst_vaapi_object_unref (surface); + return NULL; + } } /** @@ -443,9 +449,12 @@ gst_vaapi_surface_new_from_buffer_proxy (GstVaapiDisplay * display, goto error; return surface; + /* ERRORS */ error: - gst_vaapi_object_unref (surface); - return NULL; + { + gst_vaapi_object_unref (surface); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index cb1b2b7d05..661ae18cca 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -161,9 +161,12 @@ gst_vaapi_surface_pool_new_full (GstVaapiDisplay * display, goto error; return pool; + /* ERRORS */ error: - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pool)); - return NULL; + { + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pool)); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 96865c7dfa..2b6e1d522d 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -102,9 +102,12 @@ gst_vaapi_surface_proxy_new (GstVaapiSurface * surface) gst_vaapi_surface_proxy_init_properties (proxy); return proxy; + /* ERRORS */ error: - gst_vaapi_surface_proxy_unref (proxy); - return NULL; + { + gst_vaapi_surface_proxy_unref (proxy); + return NULL; + } } /** @@ -140,9 +143,12 @@ gst_vaapi_surface_proxy_new_from_pool (GstVaapiSurfacePool * pool) gst_vaapi_surface_proxy_init_properties (proxy); return proxy; + /* ERRORS */ error: - gst_vaapi_surface_proxy_unref (proxy); - return NULL; + { + gst_vaapi_surface_proxy_unref (proxy); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 0ff118c884..139822f765 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -82,9 +82,12 @@ gst_vaapi_texture_new_internal (const GstVaapiTextureClass * klass, goto error; return texture; + /* ERRORS */ error: - gst_vaapi_object_unref (texture); - return NULL; + { + gst_vaapi_object_unref (texture); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 5b8c7a2dc4..fbe17a3009 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -106,9 +106,12 @@ vaapi_create_buffer (VADisplay dpy, VAContextID ctx, int type, guint size, *buf_id_ptr = buf_id; return TRUE; + /* ERRORS */ error: - vaapi_destroy_buffer (dpy, &buf_id); - return FALSE; + { + vaapi_destroy_buffer (dpy, &buf_id); + return FALSE; + } } /* Destroy VA buffer */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c index 173e9dc035..0f0390993a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -472,9 +472,12 @@ egl_vtable_new (EglDisplay * display, guint gles_version) goto error; return vtable; + /* ERRORS */ error: - egl_object_replace (&vtable, NULL); - return NULL; + { + egl_object_replace (&vtable, NULL); + return NULL; + } } static EglVTable * @@ -596,9 +599,12 @@ done: g_cond_broadcast (&display->gl_thread_ready); return NULL; + /* ERRORS */ error: - display->base.is_valid = FALSE; - goto done; + { + display->base.is_valid = FALSE; + goto done; + } } static gboolean @@ -651,9 +657,12 @@ egl_display_new_full (gpointer handle, gboolean is_wrapped) goto error; return display; + /* ERRORS */ error: - egl_object_unref (display); - return NULL; + { + egl_object_unref (display); + return NULL; + } } EglDisplay * @@ -766,9 +775,12 @@ egl_config_new_with_attribs (EglDisplay * display, const EGLint * attribs) goto error; return config; + /* ERRORS */ error: - egl_object_replace (&config, NULL); - return NULL; + { + egl_object_replace (&config, NULL); + return NULL; + } } static EglConfig * @@ -1030,9 +1042,12 @@ do_egl_context_new (CreateContextArgs * args) args->context = ctx; return; + /* ERRORS */ error: - egl_object_replace (&ctx, NULL); - args->context = NULL; + { + egl_object_replace (&ctx, NULL); + args->context = NULL; + } } EglContext * @@ -1256,9 +1271,12 @@ egl_program_new (EglContext * ctx, const gchar * frag_shader_text, goto error; return program; + /* ERRORS */ error: - egl_object_replace (&program, NULL); - return NULL; + { + egl_object_replace (&program, NULL); + return NULL; + } } /* ------------------------------------------------------------------------- */ @@ -1319,9 +1337,12 @@ egl_window_new (EglContext * ctx, gpointer native_window) goto error; return window; + /* ERRORS */ error: - egl_object_replace (&window, NULL); - return NULL; + { + egl_object_replace (&window, NULL); + return NULL; + } } /* ------------------------------------------------------------------------- */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 39b3bf9af8..cd9244f06a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -357,16 +357,21 @@ gl_create_context (Display * dpy, int screen, GLContextState * parent) cs->visual = glXGetVisualFromFBConfig (cs->display, fbconfigs[n]); cs->context = glXCreateNewContext (cs->display, fbconfigs[n], GLX_RGBA_TYPE, parent ? parent->context : NULL, True); - if (cs->context) - goto end; + if (!cs->context) + goto error; -error: - gl_destroy_context (cs); - cs = NULL; end: if (fbconfigs) XFree (fbconfigs); return cs; + + /* ERRORS */ +error: + { + gl_destroy_context (cs); + cs = NULL; + goto end; + } } /** @@ -890,9 +895,12 @@ gl_create_pixmap_object (Display * dpy, guint width, guint height) gl_unbind_texture (&pixo->old_texture); return pixo; + /* ERRORS */ error: - gl_destroy_pixmap_object (pixo); - return NULL; + { + gl_destroy_pixmap_object (pixo); + return NULL; + } } /** @@ -1042,9 +1050,12 @@ gl_create_framebuffer_object (GLenum target, goto error; return fbo; + /* ERRORS */ error: - gl_destroy_framebuffer_object (fbo); - return NULL; + { + gl_destroy_framebuffer_object (fbo); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 715ef62721..2bb02e1f32 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -99,9 +99,12 @@ gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, goto error; return window; + /* ERRORS */ error: - gst_vaapi_window_unref_internal (window); - return NULL; + { + gst_vaapi_window_unref_internal (window); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 32d3b7a0be..27dbb04771 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -357,9 +357,12 @@ gst_vaapi_window_glx_new (GstVaapiDisplay * display, guint width, guint height) goto error; return window; + /* ERRORS */ error: - gst_vaapi_window_unref (window); - return NULL; + { + gst_vaapi_window_unref (window); + return NULL; + } } /** @@ -394,9 +397,12 @@ gst_vaapi_window_glx_new_with_xid (GstVaapiDisplay * display, Window xid) goto error; return window; + /* ERRORS */ error: - gst_vaapi_window_unref (window); - return NULL; + { + gst_vaapi_window_unref (window); + return NULL; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 0b4dd2fa39..85a1c437a9 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -198,10 +198,13 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) } return TRUE; + /* ERRORS */ error: - priv->sync_failed = TRUE; - GST_ERROR ("Error on dispatching events: %s", g_strerror (errno)); - return FALSE; + { + priv->sync_failed = TRUE; + GST_ERROR ("Error on dispatching events: %s", g_strerror (errno)); + return FALSE; + } } static void @@ -433,19 +436,25 @@ vpp_convert (GstVaapiWindow * window, /* ERRORS */ error_create_filter: - GST_WARNING ("failed to create VPP filter. Disabling"); - priv->use_vpp = FALSE; - return NULL; + { + GST_WARNING ("failed to create VPP filter. Disabling"); + priv->use_vpp = FALSE; + return NULL; + } error_unsupported_format: - GST_ERROR ("unsupported render target format %s", - gst_vaapi_video_format_to_string (priv->surface_format)); - priv->use_vpp = FALSE; - return NULL; + { + GST_ERROR ("unsupported render target format %s", + gst_vaapi_video_format_to_string (priv->surface_format)); + priv->use_vpp = FALSE; + return NULL; + } error_process_filter: - GST_ERROR ("failed to process surface %" GST_VAAPI_ID_FORMAT " (error %d)", - GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (surface)), status); - gst_vaapi_video_pool_put_object (priv->surface_pool, vpp_surface); - return NULL; + { + GST_ERROR ("failed to process surface %" GST_VAAPI_ID_FORMAT " (error %d)", + GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (surface)), status); + gst_vaapi_video_pool_put_object (priv->surface_pool, vpp_surface); + return NULL; + } } static gboolean From 1e7d89e7fee54a111bd4fcdab7f45372ae16f9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 3 Nov 2016 12:54:23 +0100 Subject: [PATCH 2576/3781] plugins: fix code style for errors --- gst/vaapi/gstvaapiencode_h264.c | 1 + gst/vaapi/gstvaapiencode_h265.c | 1 + 2 files changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 1f37fc466f..4389d7d8c5 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -340,6 +340,7 @@ _h264_convert_byte_stream_to_avc (GstBuffer * buf) gst_buffer_unmap (buf, &info); return TRUE; + /* ERRORS */ error: { gst_buffer_unmap (buf, &info); diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index dbb60e66a9..a577657f9a 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -339,6 +339,7 @@ _h265_convert_byte_stream_to_hvc (GstBuffer * buf) gst_buffer_unmap (buf, &info); return TRUE; + /* ERRORS */ error: { gst_buffer_unmap (buf, &info); From 9d5875df67f27a8e2cc55e38fe87aea3928e6a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 27 Oct 2016 11:25:55 +0200 Subject: [PATCH 2577/3781] plugins: ensure display when getting raw caps When running gst-discoverer-1.0, in certain media, vaapipostroc is stopped meanwhile it is transforming caps. The problem is that stop() calls gst_vaapi_plugin_base_close(), which nullifies the element's va display, but the va display is used in tranform_caps() when it is extracting the possible format conversions. This display disappearing generates warning messages. This patch holds a local reference of va display at ensure_allowed_raw_caps() hence it doesn't go away meanwhile it is used, even if the gst_vaapi_plugin_base_close() is called in other thread. https://bugzilla.gnome.org/show_bug.cgi?id=773593 --- gst/vaapi/gstvaapipluginbase.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index a08815dbe2..d6ec91ddcc 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1117,6 +1117,7 @@ ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) { GArray *formats, *out_formats; GstVaapiSurface *surface; + GstVaapiDisplay *display; guint i; GstCaps *out_caps; gboolean ret = FALSE; @@ -1127,7 +1128,8 @@ ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) out_formats = formats = NULL; surface = NULL; - formats = gst_vaapi_display_get_image_formats (plugin->display); + display = gst_vaapi_display_ref (plugin->display); + formats = gst_vaapi_display_get_image_formats (display); if (!formats) goto bail; @@ -1137,8 +1139,7 @@ ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) goto bail; surface = - gst_vaapi_surface_new (plugin->display, GST_VAAPI_CHROMA_TYPE_YUV420, 64, - 64); + gst_vaapi_surface_new (display, GST_VAAPI_CHROMA_TYPE_YUV420, 64, 64); if (!surface) goto bail; @@ -1148,7 +1149,7 @@ ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) if (format == GST_VIDEO_FORMAT_UNKNOWN) continue; - image = gst_vaapi_image_new (plugin->display, format, 64, 64); + image = gst_vaapi_image_new (display, format, 64, 64); if (!image) continue; if (gst_vaapi_surface_put_image (surface, image)) @@ -1171,6 +1172,7 @@ bail: g_array_unref (out_formats); if (surface) gst_vaapi_object_unref (surface); + gst_vaapi_display_unref (display); return ret; } From e9ba11a733da7b31d29e3f55d7bb78a307f06e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 Jul 2016 18:56:15 +0200 Subject: [PATCH 2578/3781] plugins: remove set_sinkpad_dmabuf_allocator() Since when the sink pad allocator is created, it is decided if the required one is vaapi allocator or dmabuf allocator, there is no need to force its set again. --- gst/vaapi/gstvaapipluginbase.c | 36 ---------------------------------- 1 file changed, 36 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index d6ec91ddcc..6c7ab04a6a 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -459,32 +459,6 @@ has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad) return is_dmabuf_capable; } -static gboolean -set_dmabuf_allocator (GstVaapiPluginBase * plugin, GstBufferPool * pool, - GstCaps * caps) -{ - GstStructure *config; - GstAllocator *allocator; - GstVideoInfo vi; - - if (!gst_video_info_from_caps (&vi, caps)) - return FALSE; - allocator = gst_vaapi_dmabuf_allocator_new (plugin->display, &vi, - GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); - if (!allocator) - return FALSE; - - config = gst_buffer_pool_get_config (pool); - gst_buffer_pool_config_set_allocator (config, allocator, NULL); - if (!gst_buffer_pool_set_config (pool, config)) - return FALSE; - - if (plugin->sinkpad_allocator) - gst_object_unref (plugin->sinkpad_allocator); - plugin->sinkpad_allocator = allocator; - return TRUE; -} - static gboolean gst_vaapi_buffer_pool_caps_is_equal (GstBufferPool * pool, GstCaps * newcaps) { @@ -784,11 +758,6 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, return FALSE; gst_query_add_allocation_pool (query, plugin->sinkpad_buffer_pool, plugin->sinkpad_buffer_size, 0, 0); - - if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) { - if (!set_dmabuf_allocator (plugin, plugin->sinkpad_buffer_pool, caps)) - goto error_pool_config; - } } gst_query_add_allocation_meta (query, GST_VAAPI_VIDEO_META_API_TYPE, NULL); @@ -801,11 +770,6 @@ error_no_caps: GST_INFO_OBJECT (plugin, "no caps specified"); return FALSE; } -error_pool_config: - { - GST_ERROR_OBJECT (plugin, "failed to reset buffer pool config"); - return FALSE; - } } /** From d1581ba5570ba5d57c09aa833f728b4f0a23a1da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 18 Feb 2016 19:20:10 +0100 Subject: [PATCH 2579/3781] libs: move get_surface_formats to utils_core The query of all the supported formats for a VA config were only used by the postprocessor (vaapifilter). But, in order to enable the vaapidecoder to negotiate a suitable raw format with downstream, we need to query these formats against the decoder's config. This patch is the first step: moves the code in filter's ensure_image() to a generic gst_vaapi_get_surface_formats() in vaapiutils_core, so it can be shared later by the decoder. https://bugzilla.gnome.org/show_bug.cgi?id=752958 --- gst-libs/gst/vaapi/gstvaapifilter.c | 58 ++----------------- gst-libs/gst/vaapi/gstvaapiutils_core.c | 76 +++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_core.h | 5 ++ 3 files changed, 85 insertions(+), 54 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 1405a0ec47..da6f733ea7 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -27,6 +27,7 @@ #include "gstvaapiminiobject.h" #include "gstvaapidisplay_priv.h" #include "gstvaapisurface_priv.h" +#include "gstvaapiutils_core.h" #if USE_VA_VPP # include @@ -992,63 +993,12 @@ deint_refs_clear_all (GstVaapiFilter * filter) static gboolean ensure_formats (GstVaapiFilter * filter) { -#if VA_CHECK_VERSION(0,34,0) - VASurfaceAttrib *surface_attribs = NULL; - guint i, num_surface_attribs = 0; - VAStatus va_status; - if (G_LIKELY (filter->formats)) return TRUE; - GST_VAAPI_DISPLAY_LOCK (filter->display); - va_status = vaQuerySurfaceAttributes (filter->va_display, filter->va_config, - NULL, &num_surface_attribs); - GST_VAAPI_DISPLAY_UNLOCK (filter->display); - if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()")) - return FALSE; - - surface_attribs = g_malloc (num_surface_attribs * sizeof (*surface_attribs)); - if (!surface_attribs) - return FALSE; - - GST_VAAPI_DISPLAY_LOCK (filter->display); - va_status = vaQuerySurfaceAttributes (filter->va_display, filter->va_config, - surface_attribs, &num_surface_attribs); - GST_VAAPI_DISPLAY_UNLOCK (filter->display); - if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()")) - return FALSE; - - filter->formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), - num_surface_attribs); - if (!filter->formats) - goto error; - - for (i = 0; i < num_surface_attribs; i++) { - const VASurfaceAttrib *const surface_attrib = &surface_attribs[i]; - GstVideoFormat format; - - if (surface_attrib->type != VASurfaceAttribPixelFormat) - continue; - if (!(surface_attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) - continue; - - format = - gst_vaapi_video_format_from_va_fourcc (surface_attrib->value.value.i); - if (format == GST_VIDEO_FORMAT_UNKNOWN) - continue; - g_array_append_val (filter->formats, format); - } - - g_free (surface_attribs); - return TRUE; - - /* ERRORS */ -error: - { - g_free (surface_attribs); - } -#endif - return FALSE; + filter->formats = gst_vaapi_get_surface_formats (filter->display, + filter->va_config); + return (filter->formats != NULL); } static inline gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.c b/gst-libs/gst/vaapi/gstvaapiutils_core.c index fe0832654f..42ebaff13a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_core.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.c @@ -24,6 +24,7 @@ #include "sysdeps.h" #include "gstvaapicompat.h" +#include "gstvaapiimage.h" #include "gstvaapiutils.h" #include "gstvaapiutils_core.h" #include "gstvaapidisplay_priv.h" @@ -75,3 +76,78 @@ gst_vaapi_get_config_attribute (GstVaapiDisplay * display, VAProfile profile, *out_value_ptr = attrib.value; return TRUE; } + +/** + * gst_vaapi_get_surface_formats: + * @display: a #GstVaapiDisplay + * @config: a #VAConfigID + * + * Gets surface formats for the supplied config. + * + * This function will query for all the supported formats for the + * supplied VA @config. + * + * Return value: (transfer full): a #GArray of #GstVideoFormats or %NULL + */ +GArray * +gst_vaapi_get_surface_formats (GstVaapiDisplay * display, VAConfigID config) +{ +#if VA_CHECK_VERSION(0,34,0) + VASurfaceAttrib *surface_attribs = NULL; + guint i, num_surface_attribs = 0; + VAStatus va_status; + GArray *formats; + + if (config == VA_INVALID_ID) + return NULL; + + GST_VAAPI_DISPLAY_LOCK (display); + va_status = vaQuerySurfaceAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display), + config, NULL, &num_surface_attribs); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()")) + return NULL; + + surface_attribs = g_malloc (num_surface_attribs * sizeof (*surface_attribs)); + if (!surface_attribs) + return NULL; + + GST_VAAPI_DISPLAY_LOCK (display); + va_status = vaQuerySurfaceAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display), + config, surface_attribs, &num_surface_attribs); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()")) + return NULL; + + formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), + num_surface_attribs); + if (!formats) + goto error; + + for (i = 0; i < num_surface_attribs; i++) { + const VASurfaceAttrib *const attrib = &surface_attribs[i]; + GstVideoFormat fmt; + + if (attrib->type != VASurfaceAttribPixelFormat) + continue; + if (!(attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) + continue; + + fmt = gst_vaapi_video_format_from_va_fourcc (attrib->value.value.i); + if (fmt == GST_VIDEO_FORMAT_UNKNOWN) + continue; + g_array_append_val (formats, fmt); + } + + g_free (surface_attribs); + return formats; + + /* ERRORS */ +error: + { + g_free (surface_attribs); + } +#endif + return NULL; + +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.h b/gst-libs/gst/vaapi/gstvaapiutils_core.h index 7f9dcf9b59..4fdaad5eb0 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_core.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.h @@ -35,6 +35,11 @@ gboolean gst_vaapi_get_config_attribute (GstVaapiDisplay * display, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttribType type, guint * out_value_ptr); +/* Gets the available GstVideoFormats of a surface in a VAConfig */ +G_GNUC_INTERNAL +GArray * +gst_vaapi_get_surface_formats (GstVaapiDisplay * display, VAConfigID config); + G_END_DECLS #endif /* GST_VAAPI_UTILS_CORE_H */ From 71264ede6f3eb82c8dd3cb6ac566afefa502fd7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 18 Feb 2016 19:32:58 +0100 Subject: [PATCH 2580/3781] libs: context: ensure context formats This patch ensures to get the formats, as filter does, available in the decoder / encoder context. The context fills up the array as soon it is created, otherwise the pipeline could get stalled (perhaps this is a bug in my HSW backend). https://bugzilla.gnome.org/show_bug.cgi?id=752958 --- gst-libs/gst/vaapi/gstvaapicontext.c | 41 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapicontext.h | 5 ++++ 2 files changed, 46 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 4017c7bb1d..bf7a915e91 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -50,6 +50,18 @@ /* Number of scratch surfaces beyond those used as reference */ #define SCRATCH_SURFACES_COUNT (4) +static gboolean +ensure_formats (GstVaapiContext * context) +{ + if (G_LIKELY (context->formats)) + return TRUE; + + context->formats = + gst_vaapi_get_surface_formats (GST_VAAPI_OBJECT_DISPLAY (context), + context->va_config); + return (context->formats != NULL); +} + static void unref_surface_cb (GstVaapiSurface * surface) { @@ -106,6 +118,11 @@ context_destroy (GstVaapiContext * context) GST_WARNING ("failed to destroy config 0x%08x", context->va_config); context->va_config = VA_INVALID_ID; } + + if (context->formats) { + g_array_unref (context->formats); + context->formats = NULL; + } } static gboolean @@ -325,6 +342,8 @@ gst_vaapi_context_init (GstVaapiContext * context, context->va_config = VA_INVALID_ID; context->reset_on_resize = TRUE; gst_vaapi_context_overlay_init (context); + + context->formats = NULL; } static void @@ -520,3 +539,25 @@ gst_vaapi_context_reset_on_resize (GstVaapiContext * context, 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_formats (context)) + return NULL; + return g_array_ref (context->formats); +} diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 19afc0626a..030419e131 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -109,6 +109,7 @@ struct _GstVaapiContext GPtrArray *overlays[2]; guint overlay_id; gboolean reset_on_resize; + GArray *formats; }; /** @@ -149,6 +150,10 @@ 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_END_DECLS #endif /* GST_VAAPI_CONTEXT_H */ From b09f592a4c62becccc549d15d02e99c0a6a44320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 25 Feb 2016 18:57:30 +0100 Subject: [PATCH 2581/3781] libs: decoder: add _get_surface_formats() This function exposes the available formats of the surfaces in the the current context to the plugins. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 18 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 123b5a3353..9a8cda2a84 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -1067,3 +1067,21 @@ gst_vaapi_decoder_decode_codec_data (GstVaapiDecoder * decoder) gst_buffer_unmap (codec_data, &map_info); return status; } + +/** + * gst_vaapi_decoder_get_surface_formats: + * @decoder: a #GstVaapiDecoder + * + * Retrieves an array of #GstVideoFormat which the output surfaces of + * the @decoder can handle. + * + * Return value: (transfer full): a #GArray of #GstVideoFormat or + * %NULL + */ +GArray * +gst_vaapi_decoder_get_surface_formats (GstVaapiDecoder * decoder) +{ + if (decoder && decoder->context) + return gst_vaapi_context_get_surface_formats (decoder->context); + return NULL; +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 77587d471d..4b75f2d2da 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -102,6 +102,9 @@ gst_vaapi_decoder_set_codec_state_changed_func (GstVaapiDecoder * decoder, GstCaps * gst_vaapi_decoder_get_caps (GstVaapiDecoder * decoder); +GArray * +gst_vaapi_decoder_get_surface_formats (GstVaapiDecoder * decoder); + gboolean gst_vaapi_decoder_put_buffer (GstVaapiDecoder * decoder, GstBuffer * buf); From 6d11a0098e3171f65a332f204a31f741cbfcff4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 19 Jul 2016 16:40:10 +0200 Subject: [PATCH 2582/3781] vaapidecode: generate source pad caps Just as vaapipostproc, VA decoder's context can be queried to get the possible raw formats, so, the src caps can negotiate the exact caps that the context supports. --- gst/vaapi/gstvaapidecode.c | 56 +++++++++++++++++++++++++++++++++++--- gst/vaapi/gstvaapidecode.h | 1 + 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 51001ef0f0..a1f9b2fe54 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -200,12 +200,59 @@ gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps) return TRUE; } +static gboolean +gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) +{ + GstCaps *out_caps, *raw_caps; + + if (decode->allowed_srcpad_caps) + return TRUE; + + if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)) + return FALSE; + + /* Create VA caps */ + out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS ";" + GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS); + if (!out_caps) { + GST_WARNING_OBJECT (decode, "failed to create VA/GL source caps"); + return FALSE; + } + + raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps + (GST_VAAPI_PLUGIN_BASE (decode)); + if (!raw_caps) { + gst_caps_unref (out_caps); + GST_WARNING_OBJECT (decode, "failed to create raw sink caps"); + return FALSE; + } + + out_caps = gst_caps_make_writable (out_caps); + gst_caps_append (out_caps, gst_caps_copy (raw_caps)); + decode->allowed_srcpad_caps = out_caps; + + GST_INFO_OBJECT (decode, "allowed srcpad caps: %" GST_PTR_FORMAT, + decode->allowed_srcpad_caps); + + return TRUE; +} + +static GstCaps * +gst_vaapidecode_get_allowed_srcpad_caps (GstVaapiDecode * decode) +{ + GstPad *const srcpad = GST_VIDEO_DECODER_SRC_PAD (decode); + + if (gst_vaapidecode_ensure_allowed_srcpad_caps (decode)) + return gst_caps_ref (decode->allowed_srcpad_caps); + return gst_pad_get_pad_template_caps (srcpad); +} + static gboolean gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) { GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); GstPad *const srcpad = GST_VIDEO_DECODER_SRC_PAD (vdec); - GstCaps *templ; + GstCaps *allowed; GstVideoCodecState *state, *ref_state; GstVaapiCapsFeature feature; GstCapsFeatures *features; @@ -223,9 +270,9 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) ref_state = decode->input_state; format = GST_VIDEO_INFO_FORMAT (&decode->decoded_info); - templ = gst_pad_get_pad_template_caps (srcpad); - feature = gst_vaapi_find_preferred_caps_feature (srcpad, templ, &format); - gst_caps_unref (templ); + allowed = gst_vaapidecode_get_allowed_srcpad_caps (decode); + feature = gst_vaapi_find_preferred_caps_feature (srcpad, allowed, &format); + gst_caps_unref (allowed); if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED) return FALSE; @@ -934,6 +981,7 @@ gst_vaapidecode_close (GstVideoDecoder * vdec) GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); gst_vaapidecode_destroy (decode); + gst_caps_replace (&decode->allowed_srcpad_caps, NULL); gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (decode)); return TRUE; } diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 41d85640e6..cb2a2f1d81 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -47,6 +47,7 @@ struct _GstVaapiDecode { GCond surface_ready; GstCaps *decoder_caps; GstCaps *allowed_sinkpad_caps; + GstCaps *allowed_srcpad_caps; guint current_frame_size; guint has_texture_upload_meta : 1; From 1f190e49c4d63e87fbd621323df8db397e26659b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 3 Nov 2016 17:30:46 +0100 Subject: [PATCH 2583/3781] plugins: set negotiation caps in src allocator When the allocator is created, it stores the allocation caps. But sometimes the "allocation caps" may be different from the "negotiation caps". In this case, the allocator should store the negotiation caps since they are the ones used for frame mapping with GstVideoMeta. When vaapispostproc is used, this is not a problem since the element is assume to resize. But when using a vaapi decoder only, with a software renderer, it fails in this case. https://bugzilla.gnome.org/show_bug.cgi?id=773323 --- gst/vaapi/gstvaapipluginbase.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 6c7ab04a6a..f3ca17b1ac 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -545,10 +545,27 @@ static gboolean ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, GstCaps * caps) { + gboolean different_caps; + GstVideoInfo vi; GstVaapiImageUsageFlags usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; - if (!reset_allocator (plugin->srcpad_allocator, vinfo)) + /* the received caps are the "allocation caps" which may be + * different from the "negotiation caps". In this case, we should + * indicate the allocator to store the negotiation caps since they + * are the one should be used for frame mapping with GstVideoMeta */ + different_caps = GST_IS_VIDEO_DECODER (plugin) && plugin->srcpad_caps && + !gst_caps_is_strictly_equal (plugin->srcpad_caps, caps); + + if (different_caps) { + vi = plugin->srcpad_info; + /* let's keep the size of the allocation info */ + GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (vinfo); + } else { + vi = *vinfo; + } + + if (!reset_allocator (plugin->srcpad_allocator, &vi)) return TRUE; /* enable direct rendering if downstream requests raw video */ @@ -561,6 +578,10 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag); if (!plugin->srcpad_allocator) goto error_create_allocator; + + if (different_caps) + gst_allocator_set_vaapi_video_info (plugin->srcpad_allocator, &vi, 0); + return TRUE; /* ERRORS */ From ae8e5d44f7619863287528b71df115dfce18d2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 4 Nov 2016 12:55:23 +0100 Subject: [PATCH 2584/3781] vaapivideomemory: increment map counter only if succeeded Previously the frame map counter increased independently if the map succeeded or not. This leaded to critical messages and crashes if the frame was unable to be mapped, but the counter increased. This patch increases the map counter only if the map operation occurred. https://bugzilla.gnome.org/show_bug.cgi?id=773939 --- gst/vaapi/gstvaapivideomemory.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 69745ebb6d..aed272a402 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -239,7 +239,7 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, goto error_incompatible_map; /* Map for writing */ - if (++mem->map_count == 1) { + if (mem->map_count == 0) { if (!ensure_surface (mem)) goto error_ensure_surface; if (!ensure_image (mem)) @@ -258,6 +258,7 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); } + mem->map_count++; *data = gst_vaapi_image_get_plane (mem->image, plane); *stride = gst_vaapi_image_get_pitch (mem->image, plane); From d7231f66ccd7b460c3465c4fdff6694813397114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 4 Nov 2016 16:26:18 +0100 Subject: [PATCH 2585/3781] vaapidecode: guard GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS In commit 6d11a00 were introduced a regression when gstreamer-vaapi is compiled with out EGL/GLX support: it shall not support GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS. This patch guards the inclusion of GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS in the allowed src caps for vaapedecode if EGL/GLX. --- gst/vaapi/gstvaapidecode.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a1f9b2fe54..94e5eca28b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -212,8 +212,11 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) return FALSE; /* Create VA caps */ - out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS ";" - GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS); + out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS +#if (USE_GLX || USE_EGL) + ";" GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS +#endif + ); if (!out_caps) { GST_WARNING_OBJECT (decode, "failed to create VA/GL source caps"); return FALSE; From cbce9b8e49a04fc75454128e1dbcc4639026424d Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 8 Nov 2016 10:05:32 +0900 Subject: [PATCH 2586/3781] postproc: honor gst_pad_push() return value Returning GST_FLOW_ERROR always when gst_pad_push fails might lead to deadlock during seek. This patch returns the same error of gst_pad_push() and log out the return value. https://bugzilla.gnome.org/show_bug.cgi?id=774030 --- gst/vaapi/gstvaapipostproc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index ddc8489ec9..38ac95a9fb 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -808,9 +808,9 @@ error_process_vpp: } error_push_buffer: { - if (ret != GST_FLOW_FLUSHING) - GST_ERROR_OBJECT (postproc, "failed to push output buffer to video sink"); - return GST_FLOW_ERROR; + GST_DEBUG_OBJECT (postproc, "gst_pad_push failed : %s", + gst_flow_get_name (ret)); + return ret; } } @@ -885,9 +885,9 @@ error_create_buffer: } error_push_buffer: { - if (ret != GST_FLOW_FLUSHING) - GST_ERROR_OBJECT (postproc, "failed to push output buffer to video sink"); - return GST_FLOW_EOS; + GST_DEBUG_OBJECT (postproc, "gst_pad_push failed : %s", + gst_flow_get_name (ret)); + return ret; } } From 0d3e1d9072ab950c6154149feb17e17077cd8245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Nov 2016 09:35:00 +0100 Subject: [PATCH 2587/3781] vaapipostproc: enhance debug message "gst_pad_push" is not a good description of the event. --- gst/vaapi/gstvaapipostproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 38ac95a9fb..556cb51509 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -808,7 +808,7 @@ error_process_vpp: } error_push_buffer: { - GST_DEBUG_OBJECT (postproc, "gst_pad_push failed : %s", + GST_DEBUG_OBJECT (postproc, "failed to push output buffer: %s", gst_flow_get_name (ret)); return ret; } @@ -885,7 +885,7 @@ error_create_buffer: } error_push_buffer: { - GST_DEBUG_OBJECT (postproc, "gst_pad_push failed : %s", + GST_DEBUG_OBJECT (postproc, "failed to push output buffer: %s", gst_flow_get_name (ret)); return ret; } From d2e801e87a8d7d542b49a218334ebdf6f3f69d59 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 11 Nov 2016 11:40:09 +0900 Subject: [PATCH 2588/3781] vaapisink: finish event thread at stop() The thread that handles window's events should be finished during pipeline's shutdown, otherwise it will remain alive during pipeline re-activation, leading to unexpected problems. This patch fixes failures of intensive_state_change scenario of gst-validate https://bugzilla.gnome.org/show_bug.cgi?id=774241 --- gst/vaapi/gstvaapisink.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index cb593d2e3d..aada7d07d8 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1224,6 +1224,7 @@ gst_vaapisink_stop (GstBaseSink * base_sink) { GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); + gst_vaapisink_set_event_handling (sink, FALSE); gst_buffer_replace (&sink->video_buffer, NULL); gst_vaapi_window_replace (&sink->window, NULL); @@ -1520,8 +1521,6 @@ gst_vaapisink_query (GstBaseSink * base_sink, GstQuery * query) static void gst_vaapisink_destroy (GstVaapiSink * sink) { - gst_vaapisink_set_event_handling (sink, FALSE); - cb_channels_finalize (sink); gst_buffer_replace (&sink->video_buffer, NULL); gst_caps_replace (&sink->caps, NULL); From 02cd120bc879e5ee7fc6ff791ae693ea99bf8060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 27 Oct 2016 18:22:18 +0200 Subject: [PATCH 2589/3781] vaapidecode: unref allowed_sinkpad_caps at close() The variable member allowed_sinkpad_caps is constructed querying the current VA display. Bearing that in mind, the variable shall be freed when the VA display changes or is removed. This patch moves the freeing of allowed_sinkpad_caps to close(), when the VA display is freed. --- gst/vaapi/gstvaapidecode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 94e5eca28b..74e9ce6257 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -954,8 +954,6 @@ gst_vaapidecode_finalize (GObject * object) { GstVaapiDecode *const decode = GST_VAAPIDECODE (object); - gst_caps_replace (&decode->allowed_sinkpad_caps, NULL); - g_cond_clear (&decode->surface_ready); g_mutex_clear (&decode->surface_ready_mutex); @@ -985,6 +983,7 @@ gst_vaapidecode_close (GstVideoDecoder * vdec) gst_vaapidecode_destroy (decode); gst_caps_replace (&decode->allowed_srcpad_caps, NULL); + gst_caps_replace (&decode->allowed_sinkpad_caps, NULL); gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (decode)); return TRUE; } From eda03230d9e06e9d358236a10df610d9fd7f45bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Nov 2016 13:54:23 +0100 Subject: [PATCH 2590/3781] vaapivideomemory: refactor vaapi memory mapping There were duplicated code in gst_video_meta_map_vaapi_memory() and gst_vaapi_video_memory_map() when doing the READ and WRITE mapping. This patch refactors both methods adding the common function map_vaapi_memory(). Additionally, only when flag has the READ bit it calls ensure_images_is_current(), which was done in gst_video_meta_map_vaapi_memory() but no in gst_vaapi_video_memory_map(). https://bugzilla.gnome.org/show_bug.cgi?id=772151 --- gst/vaapi/gstvaapivideomemory.c | 123 +++++++++++++++----------------- 1 file changed, 56 insertions(+), 67 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index aed272a402..9a5cfb49d1 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -222,6 +222,58 @@ ensure_surface_is_current (GstVaapiVideoMemory * mem) return TRUE; } +static inline gboolean +map_vaapi_memory (GstVaapiVideoMemory * mem, GstMapFlags flags) +{ + if (!ensure_surface (mem)) + goto error_no_surface; + if (!ensure_image (mem)) + goto error_no_image; + + /* Load VA image from surface only for read flag since it returns + * raw pixels */ + if ((flags & GST_MAP_READ) && !ensure_image_is_current (mem)) + goto error_no_current_image; + + if (!gst_vaapi_image_map (mem->image)) + goto error_map_image; + + /* Mark surface as dirty and expect updates from image */ + if (flags & GST_MAP_WRITE) + GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); + + return TRUE; + +error_no_surface: + { + const GstVideoInfo *const vip = mem->surface_info; + GST_ERROR ("failed to extract VA surface of size %ux%u and format %s", + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip), + GST_VIDEO_INFO_FORMAT_STRING (vip)); + return FALSE; + } +error_no_image: + { + const GstVideoInfo *const vip = mem->image_info; + GST_ERROR ("failed to extract VA image of size %ux%u and format %s", + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip), + GST_VIDEO_INFO_FORMAT_STRING (vip)); + return FALSE; + } +error_no_current_image: + { + GST_ERROR ("failed to make image current"); + return FALSE; + } +error_map_image: + { + GST_ERROR ("failed to map image %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (gst_vaapi_image_get_id (mem->image))); + return FALSE; + } +} + gboolean gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags) @@ -240,23 +292,9 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, /* Map for writing */ if (mem->map_count == 0) { - if (!ensure_surface (mem)) - goto error_ensure_surface; - if (!ensure_image (mem)) - goto error_ensure_image; - - // Load VA image from surface - if ((flags & GST_MAP_READ) && !ensure_image_is_current (mem)) - goto error_no_current_image; - - if (!gst_vaapi_image_map (mem->image)) - goto error_map_image; + if (!map_vaapi_memory (mem, flags)) + return FALSE; mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR; - - // Mark surface as dirty and expect updates from image - if (flags & GST_MAP_WRITE) - GST_VAAPI_VIDEO_MEMORY_FLAG_UNSET (mem, - GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); } mem->map_count++; @@ -271,33 +309,6 @@ error_incompatible_map: GST_ERROR ("incompatible map type (%d)", mem->map_type); return FALSE; } -error_ensure_surface: - { - const GstVideoInfo *const vip = mem->surface_info; - GST_ERROR ("failed to create %s surface of size %ux%u", - GST_VIDEO_INFO_FORMAT_STRING (vip), - GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); - return FALSE; - } -error_ensure_image: - { - const GstVideoInfo *const vip = mem->image_info; - GST_ERROR ("failed to create %s image of size %ux%u", - GST_VIDEO_INFO_FORMAT_STRING (vip), - GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); - return FALSE; - } -error_map_image: - { - GST_ERROR ("failed to map image %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS (gst_vaapi_image_get_id (mem->image))); - return FALSE; - } -error_no_current_image: - { - GST_ERROR ("failed to make image current"); - return FALSE; - } } gboolean @@ -444,15 +455,8 @@ gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize, mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE; break; case GST_MAP_READ: - // Only read flag set: return raw pixels - if (!ensure_surface (mem)) - goto error_no_surface; - if (!ensure_image (mem)) - goto error_no_image; - if (!ensure_image_is_current (mem)) - goto error_no_current_image; - if (!gst_vaapi_image_map (mem->image)) - goto error_map_image; + if (!map_vaapi_memory (mem, flags)) + return NULL; mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR; break; default: @@ -493,11 +497,6 @@ error_no_surface_proxy: GST_ERROR ("failed to extract GstVaapiSurfaceProxy from video meta"); return NULL; } -error_no_surface: - { - GST_ERROR ("failed to extract VA surface from video buffer"); - return NULL; - } error_no_current_surface: { GST_ERROR ("failed to make surface current"); @@ -508,16 +507,6 @@ error_no_image: GST_ERROR ("failed to extract VA image from video buffer"); return NULL; } -error_no_current_image: - { - GST_ERROR ("failed to make image current"); - return NULL; - } -error_map_image: - { - GST_ERROR ("failed to map VA image"); - return NULL; - } } static void From 4ae9428072d756c7fc7570c49532e6413a3e88e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Nov 2016 17:37:06 +0100 Subject: [PATCH 2591/3781] vaapivideomemory: refactor vaapi memory unmapping There were duplicated code in gst_video_meta_unmap_vaapi_memory() and gst_vaapi_video_memory_unmap() when unmapping. This patch refactors both methods adding the common function unmap_vaapi_memory(). This also ensures, if direct rendering is enabled, it is correctly reset. Additionally, only when mapping flag has the WRITE bit, it set the image as current, which was done in gst_video_meta_map_vaapi_memory() but no in gst_vaapi_video_memory_map(). In order to make this, the mapping flags were required, so instead of overloading mem_unmap() virtual function, mem_unmap_full() is overloaded. https://bugzilla.gnome.org/show_bug.cgi?id=774213 --- gst/vaapi/gstvaapivideomemory.c | 39 +++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 9a5cfb49d1..ee2b1d74ac 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -274,6 +274,22 @@ error_map_image: } } +static inline void +unmap_vaapi_memory (GstVaapiVideoMemory * mem, GstMapFlags flags) +{ + gst_vaapi_image_unmap (mem->image); + + if (flags & GST_MAP_WRITE) { + GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, + GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); + } + + if (!use_native_formats (mem->usage_flag)) { + gst_vaapi_video_meta_set_image (mem->meta, NULL); + gst_vaapi_video_memory_reset_image (mem); + } +} + gboolean gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags) @@ -330,19 +346,8 @@ gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane, mem->map_type = 0; /* Unmap VA image used for read/writes */ - if (info->flags & GST_MAP_READWRITE) { - gst_vaapi_image_unmap (mem->image); - - if (info->flags & GST_MAP_WRITE) { - GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, - GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT); - } - - if (!use_native_formats (mem->usage_flag)) { - gst_vaapi_video_meta_set_image (mem->meta, NULL); - gst_vaapi_video_memory_reset_image (mem); - } - } + if (info->flags & GST_MAP_READWRITE) + unmap_vaapi_memory (mem, info->flags); } return TRUE; } @@ -510,7 +515,7 @@ error_no_image: } static void -gst_vaapi_video_memory_unmap (GstVaapiVideoMemory * mem) +gst_vaapi_video_memory_unmap_full (GstVaapiVideoMemory * mem, GstMapInfo * info) { if (mem->map_count == 1) { switch (mem->map_type) { @@ -518,7 +523,7 @@ gst_vaapi_video_memory_unmap (GstVaapiVideoMemory * mem) gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); break; case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR: - gst_vaapi_image_unmap (mem->image); + unmap_vaapi_memory (mem, info->flags); break; default: goto error_incompatible_map; @@ -652,8 +657,8 @@ gst_vaapi_video_allocator_init (GstVaapiVideoAllocator * allocator) base_allocator->mem_type = GST_VAAPI_VIDEO_MEMORY_NAME; base_allocator->mem_map = (GstMemoryMapFunction) gst_vaapi_video_memory_map; - base_allocator->mem_unmap = (GstMemoryUnmapFunction) - gst_vaapi_video_memory_unmap; + base_allocator->mem_unmap_full = (GstMemoryUnmapFullFunction) + gst_vaapi_video_memory_unmap_full; base_allocator->mem_copy = (GstMemoryCopyFunction) gst_vaapi_video_memory_copy; base_allocator->mem_share = (GstMemoryShareFunction) From 3fa9af225f1478d251365482a4d8f19f5dd303d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Nov 2016 18:39:06 +0100 Subject: [PATCH 2592/3781] vaapivideomemory: lock map and unmap operations In order to avoid race condition when two threads call map/unmap the same VA surface, this patch mutex these operations. https://bugzilla.gnome.org/show_bug.cgi?id=774213 --- gst/vaapi/gstvaapivideomemory.c | 40 ++++++++++++++++++++++++--------- gst/vaapi/gstvaapivideomemory.h | 1 + 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index ee2b1d74ac..03b7ec7540 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -294,6 +294,7 @@ gboolean gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags) { + gboolean ret = FALSE; GstAllocator *allocator; GstVaapiVideoMemory *const mem = GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0)); @@ -303,13 +304,14 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (allocator), FALSE); g_return_val_if_fail (mem->meta, FALSE); + g_mutex_lock (&mem->lock); if (mem->map_type && mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR) goto error_incompatible_map; /* Map for writing */ if (mem->map_count == 0) { if (!map_vaapi_memory (mem, flags)) - return FALSE; + goto out; mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR; } mem->map_count++; @@ -317,13 +319,17 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, *data = gst_vaapi_image_get_plane (mem->image, plane); *stride = gst_vaapi_image_get_pitch (mem->image, plane); info->flags = flags; - return TRUE; + ret = TRUE; + +out: + g_mutex_unlock (&mem->lock); + return ret; /* ERRORS */ error_incompatible_map: { GST_ERROR ("incompatible map type (%d)", mem->map_type); - return FALSE; + goto out; } } @@ -342,6 +348,7 @@ gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane, g_return_val_if_fail (mem->surface, FALSE); g_return_val_if_fail (mem->image, FALSE); + g_mutex_lock (&mem->lock); if (--mem->map_count == 0) { mem->map_type = 0; @@ -349,6 +356,7 @@ gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane, if (info->flags & GST_MAP_READWRITE) unmap_vaapi_memory (mem, info->flags); } + g_mutex_unlock (&mem->lock); return TRUE; } @@ -381,6 +389,7 @@ gst_vaapi_video_memory_new (GstAllocator * base_allocator, mem->map_type = 0; mem->map_count = 0; mem->usage_flag = allocator->usage_flag; + g_mutex_init (&mem->lock); GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); @@ -395,6 +404,7 @@ gst_vaapi_video_memory_free (GstVaapiVideoMemory * mem) gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); gst_vaapi_video_meta_replace (&mem->meta, NULL); gst_object_unref (GST_MEMORY_CAST (mem)->allocator); + g_mutex_clear (&mem->lock); g_slice_free (GstVaapiVideoMemory, mem); } @@ -442,11 +452,12 @@ static gpointer gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize, guint flags) { - gpointer data; + gpointer data = NULL; g_return_val_if_fail (mem, NULL); g_return_val_if_fail (mem->meta, NULL); + g_mutex_lock (&mem->lock); if (mem->map_count == 0) { switch (flags & GST_MAP_READWRITE) { case 0: @@ -461,7 +472,7 @@ gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize, break; case GST_MAP_READ: if (!map_vaapi_memory (mem, flags)) - return NULL; + goto out; mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR; break; default: @@ -484,39 +495,43 @@ gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize, goto error_unsupported_map_type; } mem->map_count++; + +out: + g_mutex_unlock (&mem->lock); return data; /* ERRORS */ error_unsupported_map: { GST_ERROR ("unsupported map flags (0x%x)", flags); - return NULL; + goto out; } error_unsupported_map_type: { GST_ERROR ("unsupported map type (%d)", mem->map_type); - return NULL; + goto out; } error_no_surface_proxy: { GST_ERROR ("failed to extract GstVaapiSurfaceProxy from video meta"); - return NULL; + goto out; } error_no_current_surface: { GST_ERROR ("failed to make surface current"); - return NULL; + goto out; } error_no_image: { GST_ERROR ("failed to extract VA image from video buffer"); - return NULL; + goto out; } } static void gst_vaapi_video_memory_unmap_full (GstVaapiVideoMemory * mem, GstMapInfo * info) { + g_mutex_lock (&mem->lock); if (mem->map_count == 1) { switch (mem->map_type) { case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: @@ -531,13 +546,16 @@ gst_vaapi_video_memory_unmap_full (GstVaapiVideoMemory * mem, GstMapInfo * info) mem->map_type = 0; } mem->map_count--; + +out: + g_mutex_unlock (&mem->lock); return; /* ERRORS */ error_incompatible_map: { GST_ERROR ("incompatible map type (%d)", mem->map_type); - return; + goto out; } } diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index c7a866ee7b..ef895a6806 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -127,6 +127,7 @@ struct _GstVaapiVideoMemory guint map_type; gint map_count; GstVaapiImageUsageFlags usage_flag; + GMutex lock; }; G_GNUC_INTERNAL From a02c86b39518fd5a9c955f829a86fddff9a0767e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Nov 2016 18:54:47 +0100 Subject: [PATCH 2593/3781] vaapivideomemory: fail if frame map can't get plane If map() vmethod in GstVideMeta cannot get the plane data, return false, thus the caller will not try to read invalid memory. https://bugzilla.gnome.org/show_bug.cgi?id=774213 --- gst/vaapi/gstvaapivideomemory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 03b7ec7540..143ee40d36 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -319,7 +319,7 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, *data = gst_vaapi_image_get_plane (mem->image, plane); *stride = gst_vaapi_image_get_pitch (mem->image, plane); info->flags = flags; - ret = TRUE; + ret = (*data != NULL); out: g_mutex_unlock (&mem->lock); From 82cb89e1ed756adf2d38fc02869e3547d2d95989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Nov 2016 18:58:20 +0100 Subject: [PATCH 2594/3781] vaapivideomemory: remove unimplemented methods Remove unimplemented method for allocator mem_share() and mem_is_span(). --- gst/vaapi/gstvaapivideomemory.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 143ee40d36..8aaee070d7 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -607,22 +607,6 @@ error_allocate_memory: } } -static GstVaapiVideoMemory * -gst_vaapi_video_memory_share (GstVaapiVideoMemory * mem, - gssize offset, gssize size) -{ - GST_FIXME ("unimplemented GstVaapiVideoAllocator::mem_share() hook"); - return NULL; -} - -static gboolean -gst_vaapi_video_memory_is_span (GstVaapiVideoMemory * mem1, - GstVaapiVideoMemory * mem2, gsize * offset_ptr) -{ - GST_FIXME ("unimplemented GstVaapiVideoAllocator::mem_is_span() hook"); - return FALSE; -} - /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoAllocator --- */ /* ------------------------------------------------------------------------ */ @@ -679,10 +663,6 @@ gst_vaapi_video_allocator_init (GstVaapiVideoAllocator * allocator) gst_vaapi_video_memory_unmap_full; base_allocator->mem_copy = (GstMemoryCopyFunction) gst_vaapi_video_memory_copy; - base_allocator->mem_share = (GstMemoryShareFunction) - gst_vaapi_video_memory_share; - base_allocator->mem_is_span = (GstMemoryIsSpanFunction) - gst_vaapi_video_memory_is_span; GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); } From 582d4d47f9058f29bc7d2cf469603c12f1d3db58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Nov 2016 19:29:12 +0100 Subject: [PATCH 2595/3781] vaapivideomemory: avoid virtual methods casting Use the expected virtual method signatures for readability. --- gst/vaapi/gstvaapivideomemory.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 8aaee070d7..3ce6f1f5c0 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -449,10 +449,10 @@ gst_vaapi_video_memory_sync (GstVaapiVideoMemory * mem) } static gpointer -gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize, - guint flags) +gst_vaapi_video_memory_map (GstMemory * base_mem, gsize maxsize, guint flags) { gpointer data = NULL; + GstVaapiVideoMemory *const mem = GST_VAAPI_VIDEO_MEMORY_CAST (base_mem); g_return_val_if_fail (mem, NULL); g_return_val_if_fail (mem->meta, NULL); @@ -529,8 +529,10 @@ error_no_image: } static void -gst_vaapi_video_memory_unmap_full (GstVaapiVideoMemory * mem, GstMapInfo * info) +gst_vaapi_video_memory_unmap_full (GstMemory * base_mem, GstMapInfo * info) { + GstVaapiVideoMemory *const mem = GST_VAAPI_VIDEO_MEMORY_CAST (base_mem); + g_mutex_lock (&mem->lock); if (mem->map_count == 1) { switch (mem->map_type) { @@ -559,10 +561,10 @@ error_incompatible_map: } } -static GstVaapiVideoMemory * -gst_vaapi_video_memory_copy (GstVaapiVideoMemory * mem, - gssize offset, gssize size) +static GstMemory * +gst_vaapi_video_memory_copy (GstMemory * base_mem, gssize offset, gssize size) { + GstVaapiVideoMemory *const mem = GST_VAAPI_VIDEO_MEMORY_CAST (base_mem); GstVaapiVideoMeta *meta; GstMemory *out_mem; gsize maxsize; @@ -587,7 +589,7 @@ gst_vaapi_video_memory_copy (GstVaapiVideoMemory * mem, gst_vaapi_video_meta_unref (meta); if (!out_mem) goto error_allocate_memory; - return GST_VAAPI_VIDEO_MEMORY_CAST (out_mem); + return out_mem; /* ERRORS */ error_no_current_surface: @@ -657,12 +659,9 @@ gst_vaapi_video_allocator_init (GstVaapiVideoAllocator * allocator) GstAllocator *const base_allocator = GST_ALLOCATOR_CAST (allocator); base_allocator->mem_type = GST_VAAPI_VIDEO_MEMORY_NAME; - base_allocator->mem_map = (GstMemoryMapFunction) - gst_vaapi_video_memory_map; - base_allocator->mem_unmap_full = (GstMemoryUnmapFullFunction) - gst_vaapi_video_memory_unmap_full; - base_allocator->mem_copy = (GstMemoryCopyFunction) - gst_vaapi_video_memory_copy; + base_allocator->mem_map = gst_vaapi_video_memory_map; + base_allocator->mem_unmap_full = gst_vaapi_video_memory_unmap_full; + base_allocator->mem_copy = gst_vaapi_video_memory_copy; GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); } From 85b3af62b412101691bc1e24a123d94dabf79090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Nov 2016 19:49:22 +0100 Subject: [PATCH 2596/3781] vaapivideomemory: unroll gst_vaapi_video_allocator_free() Instead of having a gst_vaapi_video_memory_free() that is only going to be called by gst_vaapi_video_allocator_free(), let's just remove the first and merged into the second. --- gst/vaapi/gstvaapivideomemory.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 3ce6f1f5c0..99a2b57190 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -396,18 +396,6 @@ gst_vaapi_video_memory_new (GstAllocator * base_allocator, return GST_MEMORY_CAST (mem); } -static void -gst_vaapi_video_memory_free (GstVaapiVideoMemory * mem) -{ - mem->surface = NULL; - gst_vaapi_video_memory_reset_image (mem); - gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); - gst_vaapi_video_meta_replace (&mem->meta, NULL); - gst_object_unref (GST_MEMORY_CAST (mem)->allocator); - g_mutex_clear (&mem->lock); - g_slice_free (GstVaapiVideoMemory, mem); -} - void gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem) { @@ -626,9 +614,17 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoAllocator, "VA-API video memory allocator")); static void -gst_vaapi_video_allocator_free (GstAllocator * allocator, GstMemory * mem) +gst_vaapi_video_allocator_free (GstAllocator * allocator, GstMemory * base_mem) { - gst_vaapi_video_memory_free (GST_VAAPI_VIDEO_MEMORY_CAST (mem)); + GstVaapiVideoMemory *const mem = GST_VAAPI_VIDEO_MEMORY_CAST (base_mem); + + mem->surface = NULL; + gst_vaapi_video_memory_reset_image (mem); + gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); + gst_vaapi_video_meta_replace (&mem->meta, NULL); + gst_object_unref (GST_MEMORY_CAST (mem)->allocator); + g_mutex_clear (&mem->lock); + g_slice_free (GstVaapiVideoMemory, mem); } static void From f6566a2c98269c8d31e7cafc62111a523a85a047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Nov 2016 13:25:30 +0100 Subject: [PATCH 2597/3781] vaapivideomemory: code style fixes A cosmetic commit for enhance readability of the casts and method preconditions. --- gst/vaapi/gstvaapivideomemory.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 99a2b57190..91b33cec09 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -298,11 +298,12 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane, GstAllocator *allocator; GstVaapiVideoMemory *const mem = GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0)); + g_return_val_if_fail (mem, FALSE); + g_return_val_if_fail (mem->meta, FALSE); allocator = GST_MEMORY_CAST (mem)->allocator; g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (allocator), FALSE); - g_return_val_if_fail (mem->meta, FALSE); g_mutex_lock (&mem->lock); if (mem->map_type && mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR) @@ -340,14 +341,15 @@ gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane, GstAllocator *allocator; GstVaapiVideoMemory *const mem = GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0)); - g_return_val_if_fail (mem, FALSE); - allocator = GST_MEMORY_CAST (mem)->allocator; - g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (allocator), FALSE); + g_return_val_if_fail (mem, FALSE); g_return_val_if_fail (mem->meta, FALSE); g_return_val_if_fail (mem->surface, FALSE); g_return_val_if_fail (mem->image, FALSE); + allocator = GST_MEMORY_CAST (mem)->allocator; + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (allocator), FALSE); + g_mutex_lock (&mem->lock); if (--mem->map_count == 0) { mem->map_type = 0; From e2657882712ae0e18583688f7623c125a517bc61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Nov 2016 13:26:31 +0100 Subject: [PATCH 2598/3781] vaapivideomemory: check for memory allocator When calling gst_vaapi_video_memory_copy() the allocator of the memory to copy should be allocated by the vaapi allocator. This patch does this verification. --- gst/vaapi/gstvaapivideomemory.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 91b33cec09..78985594ee 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -556,15 +556,19 @@ gst_vaapi_video_memory_copy (GstMemory * base_mem, gssize offset, gssize size) { GstVaapiVideoMemory *const mem = GST_VAAPI_VIDEO_MEMORY_CAST (base_mem); GstVaapiVideoMeta *meta; + GstAllocator *allocator; GstMemory *out_mem; gsize maxsize; g_return_val_if_fail (mem, NULL); g_return_val_if_fail (mem->meta, NULL); + allocator = base_mem->allocator; + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (allocator), FALSE); + /* XXX: this implements a soft-copy, i.e. underlying VA surfaces are not copied */ - (void) gst_memory_get_sizes (GST_MEMORY_CAST (mem), NULL, &maxsize); + (void) gst_memory_get_sizes (base_mem, NULL, &maxsize); if (offset != 0 || (size != -1 && (gsize) size != maxsize)) goto error_unsupported; @@ -575,7 +579,7 @@ gst_vaapi_video_memory_copy (GstMemory * base_mem, gssize offset, gssize size) if (!meta) goto error_allocate_memory; - out_mem = gst_vaapi_video_memory_new (GST_MEMORY_CAST (mem)->allocator, meta); + out_mem = gst_vaapi_video_memory_new (allocator, meta); gst_vaapi_video_meta_unref (meta); if (!out_mem) goto error_allocate_memory; From aca43dab4773e7bdf92f2d70066a53541432522f Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:15:01 +0100 Subject: [PATCH 2599/3781] vaapivideobufferpool: set correct buffer size We should set the correct buffer size when we are configuring the pool, otherwise the buffer will be discarded when it returns to the pool. Indeed when the ref-count of a buffer reaches zero, its pool will queue it back (and ref it) if, and only if, the buffer size matches the configured buffer size on the pool. This issue can be debugged with GST_DEBUG=*PERF*:6, see gstbufferpool.c https://bugzilla.gnome.org/show_bug.cgi?id=774782 --- gst/vaapi/gstvaapivideobufferpool.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index a3b9223f24..a97fa558d1 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -140,11 +140,13 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, GstVideoAlignment align; GstAllocator *allocator; gboolean ret, updated = FALSE; + guint size, min_buffers, max_buffers; GST_DEBUG_OBJECT (pool, "config %" GST_PTR_FORMAT, config); caps = NULL; - if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) + if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, + &max_buffers)) goto error_invalid_config; if (!caps) goto error_no_caps; @@ -177,6 +179,10 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, goto error_create_allocator_info; priv->alloc_info = *alloc_vip; } + if (GST_VIDEO_INFO_SIZE (&priv->alloc_info) != size) { + gst_buffer_pool_config_set_params (config, caps, + GST_VIDEO_INFO_SIZE (&priv->alloc_info), min_buffers, max_buffers); + } } if (!priv->allocator) goto error_no_allocator; From acefc7e384bd0112a4406f1062cbe9c95b9feed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Nov 2016 11:25:21 +0100 Subject: [PATCH 2600/3781] plugins: add allocator to allocation query This patch adds the created allocator to the allocation query either in decide_allocation() and propose_allocation() vmehtods. With it, there's no need to set the modified allocator's size in the pool configuration. https://bugzilla.gnome.org/show_bug.cgi?id=774782 --- gst/vaapi/gstvaapipluginbase.c | 15 +++++++++++---- gst/vaapi/gstvaapivideomemory.c | 26 -------------------------- gst/vaapi/gstvaapivideomemory.h | 4 ---- 3 files changed, 11 insertions(+), 34 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index f3ca17b1ac..e3502756db 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -701,7 +701,6 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) if (!ensure_sinkpad_allocator (plugin, caps, &size)) goto error; - gst_allocator_get_vaapi_image_size (plugin->sinkpad_allocator, &size); pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, 0, 0, GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, plugin->sinkpad_allocator); if (!pool) @@ -779,6 +778,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, return FALSE; gst_query_add_allocation_pool (query, plugin->sinkpad_buffer_pool, plugin->sinkpad_buffer_size, 0, 0); + gst_query_add_allocation_param (query, plugin->sinkpad_allocator, NULL); } gst_query_add_allocation_meta (query, GST_VAAPI_VIDEO_META_API_TYPE, NULL); @@ -812,7 +812,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GstBufferPool *pool; GstVideoInfo vi; guint size, min, max, pool_options; - gboolean update_pool = FALSE; + gboolean update_pool = FALSE, update_allocator = FALSE; #if (USE_GLX || USE_EGL) guint idx; #endif @@ -860,6 +860,9 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, goto error_invalid_caps; gst_video_info_force_nv12_if_encoded (&vi); + if (gst_query_get_n_allocation_params (query) > 0) + update_allocator = TRUE; + if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); update_pool = TRUE; @@ -888,8 +891,6 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!pool) { if (!ensure_srcpad_allocator (plugin, &vi, caps)) goto error; - /* Update video size with allocator's image size */ - gst_allocator_get_vaapi_image_size (plugin->srcpad_allocator, &size); pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, min, max, pool_options, plugin->srcpad_allocator); if (!pool) @@ -901,6 +902,12 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, else gst_query_add_allocation_pool (query, pool, size, min, max); + if (update_allocator) + gst_query_set_nth_allocation_param (query, 0, plugin->srcpad_allocator, + NULL); + else + gst_query_add_allocation_param (query, plugin->srcpad_allocator, NULL); + g_clear_object (&plugin->srcpad_buffer_pool); plugin->srcpad_buffer_pool = pool; return TRUE; diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 78985594ee..be6bc5bf5e 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1127,32 +1127,6 @@ gst_allocator_set_vaapi_video_info (GstAllocator * allocator, return TRUE; } -/** - * gst_allocator_get_vaapi_image_size: - * @allocator: a #GstAllocator instance. - * @size: (out) (optional): the VA image size created by @allocator. - * - * This function gets the size of the VA images instantiated by the - * @allocator. - * - * Returns: %TRUE if @allocator is VA valid - **/ -gboolean -gst_allocator_get_vaapi_image_size (GstAllocator * allocator, guint * size) -{ - GstVaapiVideoAllocator *alloc; - - g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), FALSE); - - if (g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME)) - return FALSE; - alloc = GST_VAAPI_VIDEO_ALLOCATOR_CAST (allocator); - if (alloc && size) - *size = GST_VIDEO_INFO_SIZE (&alloc->image_info); - - return TRUE; -} - gboolean gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator) { diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index ef895a6806..8f4746b7b2 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -235,10 +235,6 @@ gboolean gst_allocator_set_vaapi_video_info (GstAllocator * allocator, const GstVideoInfo * vip, guint flags); -G_GNUC_INTERNAL -gboolean -gst_allocator_get_vaapi_image_size (GstAllocator * allocator, guint * size); - G_GNUC_INTERNAL gboolean gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator); From ac18e0479f48a457ba9019f235d732be8ec938c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Nov 2016 12:29:26 +0100 Subject: [PATCH 2601/3781] plugins: use early return without goto https://bugzilla.gnome.org/show_bug.cgi?id=774782 --- gst/vaapi/gstvaapipluginbase.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e3502756db..147e5f283c 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -699,22 +699,16 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) } if (!ensure_sinkpad_allocator (plugin, caps, &size)) - goto error; + return FALSE; pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, 0, 0, GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, plugin->sinkpad_allocator); if (!pool) - goto error; + return FALSE; + plugin->sinkpad_buffer_pool = pool; plugin->sinkpad_buffer_size = size; return TRUE; - - /* ERRORS */ -error: - { - /* error message already sent */ - return FALSE; - } } /** From 432731e6363e01bbde7f490103f9b883a180ec67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Nov 2016 12:36:27 +0100 Subject: [PATCH 2602/3781] vaapivideomemory: add missing documentation https://bugzilla.gnome.org/show_bug.cgi?id=774782 --- gst/vaapi/gstvaapivideomemory.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index be6bc5bf5e..03402b9b0b 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1084,6 +1084,16 @@ flags_quark_get (void) return g_quark; } +/** + * gst_allocator_get_vaapi_video_info: + * @allocator: a #GstAllocator + * @out_flags_ptr: (out): the stored flags + * + * Will get the @allocator qdata to fetch the flags and the + * #GstVideoInfo stored in it. + * + * Returns: the stored #GstVideoInfo + **/ const GstVideoInfo * gst_allocator_get_vaapi_video_info (GstAllocator * allocator, guint * out_flags_ptr) @@ -1111,6 +1121,17 @@ gst_allocator_get_vaapi_video_info (GstAllocator * allocator, return g_value_get_boxed (value); } +/** + * gst_allocator_set_vaapi_video_info: + * @allocator: a #GstAllocator + * @vip: the #GstVideoInfo to store + * @flags: the flags to store + * + * Stores as GObject's qdata the @vip and the @flags in the + * allocator. This will "decorate" the allocator as a GstVaapi one. + * + * Returns: always %TRUE + **/ gboolean gst_allocator_set_vaapi_video_info (GstAllocator * allocator, const GstVideoInfo * vip, guint flags) @@ -1127,6 +1148,16 @@ gst_allocator_set_vaapi_video_info (GstAllocator * allocator, return TRUE; } +/** + * gst_vaapi_is_dmabuf_allocator: + * @allocator: an #GstAllocator + * + * Checks if the allocator is DMABuf allocator with the GstVaapi + * decorator. + * + * Returns: %TRUE if @allocator is a DMABuf allocator type with + * GstVaapi decorator. + **/ gboolean gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator) { From d799bb304156b305245ce9c6e3abc618c5097266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Nov 2016 12:51:25 +0100 Subject: [PATCH 2603/3781] plugins: update the src pad allocator video info Update the size, stride and offset of the source pad allocator video info, so the pool could set the correct GstVideoMeta https://bugzilla.gnome.org/show_bug.cgi?id=774782 --- gst/vaapi/gstvaapipluginbase.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 147e5f283c..036533b027 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -559,8 +559,6 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, if (different_caps) { vi = plugin->srcpad_info; - /* let's keep the size of the allocation info */ - GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (vinfo); } else { vi = *vinfo; } @@ -579,8 +577,23 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, if (!plugin->srcpad_allocator) goto error_create_allocator; - if (different_caps) - gst_allocator_set_vaapi_video_info (plugin->srcpad_allocator, &vi, 0); + if (different_caps) { + guint i, flags = 0; + const GstVideoInfo *alloc_vi = + gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, &flags); + /* update the planes and the size with the allocator image info, + * but not the resolution */ + if (alloc_vi) { + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (alloc_vi); i++) { + GST_VIDEO_INFO_PLANE_OFFSET (&vi, i) = + GST_VIDEO_INFO_PLANE_OFFSET (alloc_vi, i); + GST_VIDEO_INFO_PLANE_STRIDE (&vi, i) = + GST_VIDEO_INFO_PLANE_STRIDE (alloc_vi, i); + } + GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (alloc_vi); + gst_allocator_set_vaapi_video_info (plugin->srcpad_allocator, &vi, flags); + } + } return TRUE; From 22463b96f34b0ffe0a5544976b40371ea9bdee13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Nov 2016 16:35:34 +0100 Subject: [PATCH 2604/3781] vaapivideomemory: remove GST_VAAPI_TYPE_VIDEO_INFO Remove redundant GST_VAAPI_TYPE_VIDEO_INFO, since it is a duplicate of GST_TYPE_VIDEO_INFO created before gstreamer 1.6, where the boxed type was created. https://bugzilla.gnome.org/show_bug.cgi?id=774782 --- gst/vaapi/gstvaapivideomemory.c | 41 ++------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 03402b9b0b..854638ae86 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1009,42 +1009,6 @@ gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, /* --- GstVaapiVideoInfo = { GstVideoInfo, flags } --- */ /* ------------------------------------------------------------------------ */ -static GstVideoInfo * -gst_vaapi_video_info_copy (const GstVideoInfo * vip) -{ - GstVideoInfo *out_vip; - - out_vip = g_slice_new (GstVideoInfo); - if (!out_vip) - return NULL; - - gst_video_info_init (out_vip); - *out_vip = *vip; - return out_vip; -} - -static void -gst_vaapi_video_info_free (GstVideoInfo * vip) -{ - g_slice_free (GstVideoInfo, vip); -} - -#define GST_VAAPI_TYPE_VIDEO_INFO gst_vaapi_video_info_get_type () -static GType -gst_vaapi_video_info_get_type (void) -{ - static gsize g_type; - - if (g_once_init_enter (&g_type)) { - GType type; - type = g_boxed_type_register_static ("GstVaapiVideoInfo", - (GBoxedCopyFunc) gst_vaapi_video_info_copy, - (GBoxedFreeFunc) gst_vaapi_video_info_free); - g_once_init_leave (&g_type, type); - } - return (GType) g_type; -} - #define GST_VAAPI_VIDEO_INFO_QUARK gst_vaapi_video_info_quark_get () static GQuark gst_vaapi_video_info_quark_get (void) @@ -1140,9 +1104,8 @@ gst_allocator_set_vaapi_video_info (GstAllocator * allocator, g_return_val_if_fail (vip != NULL, FALSE); g_object_set_qdata_full (G_OBJECT (allocator), GST_VAAPI_VIDEO_INFO_QUARK, - gst_structure_new_id (GST_VAAPI_VIDEO_INFO_QUARK, - INFO_QUARK, GST_VAAPI_TYPE_VIDEO_INFO, vip, - FLAGS_QUARK, G_TYPE_UINT, flags, NULL), + gst_structure_new_id (GST_VAAPI_VIDEO_INFO_QUARK, INFO_QUARK, + GST_TYPE_VIDEO_INFO, vip, FLAGS_QUARK, G_TYPE_UINT, flags, NULL), (GDestroyNotify) gst_structure_free); return TRUE; From f09d9ff2ab93fbbab3a3f89d43bd72a59e49ef38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Nov 2016 18:42:02 +0100 Subject: [PATCH 2605/3781] vaapidecode: negotiate after destroying allocator This is related with bug 758907 when no vaapipostproc is used (no vaapidecodebin). In order to negotiate downstream we need to destroy the source pad allocator, otherwise the same allocated buffers are used, failing the mapping. --- gst/vaapi/gstvaapidecode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 74e9ce6257..0279ceff2f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -469,10 +469,10 @@ gst_vaapidecode_negotiate (GstVaapiDecode * decode) return FALSE; if (!gst_vaapidecode_update_src_caps (decode)) return FALSE; - if (!gst_video_decoder_negotiate (vdec)) - return FALSE; if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) return FALSE; + if (!gst_video_decoder_negotiate (vdec)) + return FALSE; return TRUE; } From ec364858b1ef8ea229a947361794db0f2cb4d6dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Nov 2016 18:27:00 +0100 Subject: [PATCH 2606/3781] plugins: first validate the out caps When calling _set_caps() first validate the out caps before doing anything else. --- gst/vaapi/gstvaapipluginbase.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 036533b027..a8508a58c0 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -740,19 +740,19 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, GstCaps * outcaps) { if (incaps && incaps != plugin->sinkpad_caps) { - g_clear_object (&plugin->sinkpad_allocator); - gst_caps_replace (&plugin->sinkpad_caps, incaps); if (!gst_video_info_from_caps (&plugin->sinkpad_info, incaps)) return FALSE; + g_clear_object (&plugin->sinkpad_allocator); + gst_caps_replace (&plugin->sinkpad_caps, incaps); plugin->sinkpad_caps_is_raw = !gst_caps_has_vaapi_surface (incaps); } if (outcaps && outcaps != plugin->srcpad_caps) { + if (!gst_video_info_from_caps (&plugin->srcpad_info, outcaps)) + return FALSE; g_clear_object (&plugin->srcpad_allocator); gst_caps_replace (&plugin->srcpad_caps, outcaps); plugin_reset_texture_map (plugin); - if (!gst_video_info_from_caps (&plugin->srcpad_info, outcaps)) - return FALSE; } if (!ensure_sinkpad_buffer_pool (plugin, plugin->sinkpad_caps)) From 89531263746c1455b71d25d1dc170918320117fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Nov 2016 19:17:07 +0100 Subject: [PATCH 2607/3781] plugins: don't destroy sink pad allocator Don't destroy sink pad allocator at _set_caps() because it will be done at ensure_sinkpad_buffer_pool() if it is required. --- gst/vaapi/gstvaapipluginbase.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index a8508a58c0..be75c17a02 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -742,7 +742,6 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, if (incaps && incaps != plugin->sinkpad_caps) { if (!gst_video_info_from_caps (&plugin->sinkpad_info, incaps)) return FALSE; - g_clear_object (&plugin->sinkpad_allocator); gst_caps_replace (&plugin->sinkpad_caps, incaps); plugin->sinkpad_caps_is_raw = !gst_caps_has_vaapi_surface (incaps); } From 3fccc8327887133cd85077f58eae49cd6b622108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Nov 2016 18:28:18 +0100 Subject: [PATCH 2608/3781] plugins: destroy source pad allocator and pool First, deactivate source pad pool when the out caps change, and if so, destroy texture map, the source pad allocator and pool only if the new caps are different from the ones already set. --- gst/vaapi/gstvaapipluginbase.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index be75c17a02..2aa3b867f2 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -749,9 +749,15 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, if (outcaps && outcaps != plugin->srcpad_caps) { if (!gst_video_info_from_caps (&plugin->srcpad_info, outcaps)) return FALSE; - g_clear_object (&plugin->srcpad_allocator); + if (plugin->srcpad_buffer_pool + && !gst_vaapi_buffer_pool_caps_is_equal (plugin->srcpad_buffer_pool, + outcaps)) { + gst_buffer_pool_set_active (plugin->srcpad_buffer_pool, FALSE); + g_clear_object (&plugin->srcpad_buffer_pool); + g_clear_object (&plugin->srcpad_allocator); + plugin_reset_texture_map (plugin); + } gst_caps_replace (&plugin->srcpad_caps, outcaps); - plugin_reset_texture_map (plugin); } if (!ensure_sinkpad_buffer_pool (plugin, plugin->sinkpad_caps)) From 267422dde51e1c332b77d8b0a89255305485aec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 19 Mar 2015 21:20:26 +0100 Subject: [PATCH 2609/3781] remove the video converter from vaapi buffer meta Since all the video converter were deprecated in gstreamer-1.2, we don't need to handle them anymore in the vaapi's buffer meta. This patch removes its usage and the buffer meta's API for that. https://bugzilla.gnome.org/show_bug.cgi?id=745728 --- gst/vaapi/gstvaapivideobuffer.c | 26 ++------------------------ gst/vaapi/gstvaapivideometa.c | 32 -------------------------------- gst/vaapi/gstvaapivideometa.h | 9 --------- 3 files changed, 2 insertions(+), 65 deletions(-) diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 9d047e73ff..af79338b6e 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -33,25 +33,6 @@ #include "gstcompat.h" #include "gstvaapivideobuffer.h" -static inline GstBuffer * -gst_surface_buffer_new (void) -{ - return gst_buffer_new (); -} - -static GFunc -get_surface_converter (GstVaapiDisplay * display) -{ - GFunc func; - - switch (gst_vaapi_display_get_class_type (display)) { - default: - func = NULL; - break; - } - return func; -} - static GstBuffer * new_vbuffer (GstVaapiVideoMeta * meta) { @@ -59,10 +40,7 @@ new_vbuffer (GstVaapiVideoMeta * meta) g_return_val_if_fail (meta != NULL, NULL); - gst_vaapi_video_meta_set_surface_converter (meta, - get_surface_converter (gst_vaapi_video_meta_get_display (meta))); - - buffer = gst_surface_buffer_new (); + buffer = gst_buffer_new (); if (buffer) gst_buffer_set_vaapi_video_meta (buffer, meta); gst_vaapi_video_meta_unref (meta); @@ -80,7 +58,7 @@ gst_vaapi_video_buffer_new (GstVaapiVideoMeta * meta) GstBuffer * gst_vaapi_video_buffer_new_empty (void) { - return gst_surface_buffer_new (); + return gst_buffer_new (); } GstBuffer * diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index ca5333bcca..a8ddf0501f 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -588,38 +588,6 @@ gst_vaapi_video_meta_set_surface_proxy (GstVaapiVideoMeta * meta, } } -/** - * gst_vaapi_video_meta_get_surface_converter: - * @meta: a #GstVaapiVideoMeta - * - * Retrieves the surface converter bound to the @meta. - * - * Return value: the surface converter associated with the video @meta - */ -GFunc -gst_vaapi_video_meta_get_surface_converter (GstVaapiVideoMeta * meta) -{ - g_return_val_if_fail (GST_VAAPI_IS_VIDEO_META (meta), NULL); - - return meta->converter; -} - -/** - * gst_vaapi_video_meta_set_surface_converter: - * @meta: a #GstVaapiVideoMeta - * @func: a pointer to the surface converter function - * - * Sets the @meta surface converter function to @func. - */ -void -gst_vaapi_video_meta_set_surface_converter (GstVaapiVideoMeta * meta, - GFunc func) -{ - g_return_if_fail (GST_VAAPI_IS_VIDEO_META (meta)); - - meta->converter = func; -} - /** * gst_vaapi_video_meta_get_render_flags: * @meta: a #GstVaapiVideoMeta diff --git a/gst/vaapi/gstvaapivideometa.h b/gst/vaapi/gstvaapivideometa.h index 62f4322ebd..c88abfd454 100644 --- a/gst/vaapi/gstvaapivideometa.h +++ b/gst/vaapi/gstvaapivideometa.h @@ -106,15 +106,6 @@ void gst_vaapi_video_meta_set_surface_proxy (GstVaapiVideoMeta * meta, GstVaapiSurfaceProxy * proxy); -G_GNUC_INTERNAL -GFunc -gst_vaapi_video_meta_get_surface_converter (GstVaapiVideoMeta * meta); - -G_GNUC_INTERNAL -void -gst_vaapi_video_meta_set_surface_converter (GstVaapiVideoMeta * meta, - GFunc func); - G_GNUC_INTERNAL guint gst_vaapi_video_meta_get_render_flags (GstVaapiVideoMeta * meta); From 8555eaf07967a660ba4e3695d22c88ef4561eef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 4 Nov 2016 18:04:36 +0100 Subject: [PATCH 2610/3781] vaapidecode: don't add video crop meta Since the differentiation of negotiation caps and allocation caps, there is no need to add a video crop meta with the negotiation caps. Hence, removing it. https://bugzilla.gnome.org/show_bug.cgi?id=773948 --- gst/vaapi/gstvaapidecode.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 0279ceff2f..db490615de 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -544,17 +544,6 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_VIDEO_BUFFER_FLAG_FIRST_IN_BUNDLE); } - - if (crop_rect) { - GstVideoCropMeta *const crop_meta = - gst_buffer_add_video_crop_meta (out_frame->output_buffer); - if (crop_meta) { - crop_meta->x = crop_rect->x; - crop_meta->y = crop_rect->y; - crop_meta->width = crop_rect->width; - crop_meta->height = crop_rect->height; - } - } #if (USE_GLX || USE_EGL) if (decode->has_texture_upload_meta) gst_buffer_ensure_texture_upload_meta (out_frame->output_buffer); From a567955c6ded7a0dbb99708247668e471642d1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 28 Oct 2015 12:57:14 +0100 Subject: [PATCH 2611/3781] vaapisink: create display at open() Instead of creating the VA display before setting the bus to the element, it is created when the element is opened. Basically, this commit is a revert of 5e5d62cac79754ba60057fc2516135aad8d7de35 That was done when the GStreamer's context sharing was not mature enough as now. There is no reason to keep this hack. --- gst/vaapi/gstvaapisink.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index aada7d07d8..58e194a7e8 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1214,9 +1214,7 @@ gst_vaapisink_display_changed (GstVaapiPluginBase * plugin) static gboolean gst_vaapisink_start (GstBaseSink * base_sink) { - GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); - - return gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (sink)); + return gst_vaapisink_ensure_display (GST_VAAPISINK_CAST (base_sink)); } static gboolean @@ -1685,19 +1683,6 @@ gst_vaapisink_event (GstBaseSink * base_sink, GstEvent * event) return res; } -static void -gst_vaapisink_set_bus (GstElement * element, GstBus * bus) -{ - /* Make sure to allocate a VA display in the sink element first, - so that upstream elements could query a display that was - allocated here, and that exactly matches what the user - requested through the "display" property */ - if (!GST_ELEMENT_BUS (element) && bus) - gst_vaapisink_ensure_display (GST_VAAPISINK_CAST (element)); - - GST_ELEMENT_CLASS (gst_vaapisink_parent_class)->set_bus (element, bus); -} - static void gst_vaapisink_class_init (GstVaapiSinkClass * klass) { @@ -1732,7 +1717,6 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass) videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_vaapisink_show_frame); element_class->set_context = gst_vaapi_base_set_context; - element_class->set_bus = gst_vaapisink_set_bus; gst_element_class_set_static_metadata (element_class, "VA-API sink", "Sink/Video", GST_PLUGIN_DESC, "Gwenole Beauchesne "); From 184e6890ca0e3673ed74132e5b45730e66eca1d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 28 Oct 2015 12:55:18 +0100 Subject: [PATCH 2612/3781] vaapivideocontext: log a message if no bus Raise a warning if there is no bus when the element tries to post a message. --- gst/vaapi/gstvaapivideocontext.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index c16cc873a5..4d59f2fc7d 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -171,7 +171,8 @@ _gst_context_query (GstElement * element, const gchar * context_type) GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "posting `need-context' message"); msg = gst_message_new_need_context (GST_OBJECT_CAST (element), context_type); - gst_element_post_message (element, msg); + if (!gst_element_post_message (element, msg)) + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "No bus attached"); /* * Whomever responds to the need-context message performs a @@ -223,7 +224,8 @@ gst_vaapi_video_context_propagate (GstElement * element, "posting `have-context' (%p) message with display (%p)", context, display); msg = gst_message_new_have_context (GST_OBJECT_CAST (element), context); - gst_element_post_message (GST_ELEMENT_CAST (element), msg); + if (!gst_element_post_message (element, msg)) + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "No bus attached"); } gboolean From 8effd68975d04a24ed50802fb3a81d56a0047b99 Mon Sep 17 00:00:00 2001 From: Dominique Leuenberger Date: Thu, 24 Nov 2016 21:17:54 +0100 Subject: [PATCH 2613/3781] build: add LIBVA_WAYLAND_CFLAGS to libgstvaapiegl In case libva-wayland has its headers not installed in default locations (like /usr/include), the build fails to include "wayland-client.h": CC libgstvaapi_egl_la-gstvaapiutils_egl.lo In file included from gstvaapidisplay_wayland.h:27:0, from gstvaapidisplay_egl.c:35: /usr/include/va/va_wayland.h:31:28: fatal error: wayland-client.h: No such file or directory #include As we already passed VA_CLAGS, /usr/include/va/va_wayland.h could be found, but it is our fault not to instruct the system that we ALSO care for va_wayland. We correctly query for libva-wayland.pc in configure and use this in other places as well. It is thus only correct and consequent, to do it also at this spot. https://bugzilla.gnome.org/show_bug.cgi?id=773946 --- gst-libs/gst/vaapi/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f606bbb5c4..dd3aed59c3 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -461,6 +461,7 @@ libgstvaapi_egl_la_CFLAGS = \ $(GST_BASE_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ $(LIBVA_CFLAGS) \ + $(LIBVA_WAYLAND_CFLAGS) \ $(EGL_CFLAGS) \ $(NULL) From 7f1b632c566def8c3d4d380480ae8d4378abe256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 26 Nov 2016 11:27:26 +0000 Subject: [PATCH 2614/3781] common: use https protocol for common submodule https://bugzilla.gnome.org/show_bug.cgi?id=775110 --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index a6b1edac4c..3ff9d95ea0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "common"] path = common - url = git://anongit.freedesktop.org/gstreamer/common + url = https://anongit.freedesktop.org/git/gstreamer/common.git From 3285121181295c544480fc6ba756845b16285d30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Nov 2016 18:25:18 +0100 Subject: [PATCH 2615/3781] vaapidecode: implement negotiate() vmethod Instead of decorating the negotiate() method, let us override it, so the stream is locked while called. https://bugzilla.gnome.org/show_bug.cgi?id=775040 --- gst/vaapi/gstvaapidecode.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index db490615de..6d9e21527a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -458,20 +458,18 @@ set_display_res: } static gboolean -gst_vaapidecode_negotiate (GstVaapiDecode * decode) +gst_vaapidecode_negotiate (GstVideoDecoder * vdec) { - GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); + GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); - GST_DEBUG_OBJECT (decode, "Input codec state changed, doing renegotiation"); - if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) return FALSE; if (!gst_vaapidecode_update_src_caps (decode)) return FALSE; if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) return FALSE; - if (!gst_video_decoder_negotiate (vdec)) + if (!GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (vdec)) return FALSE; return TRUE; @@ -509,8 +507,8 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, if (gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec)) || alloc_renegotiate || caps_renegotiate) { - - if (!gst_vaapidecode_negotiate (decode)) + GST_INFO_OBJECT (decode, "input codec state changed: renegotiating"); + if (!gst_video_decoder_negotiate (vdec)) return GST_FLOW_ERROR; } @@ -1310,6 +1308,7 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_query); vdec_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_getcaps); vdec_class->sink_event = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_event); + vdec_class->negotiate = GST_DEBUG_FUNCPTR (gst_vaapidecode_negotiate); map = (GstVaapiDecoderMap *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass), GST_VAAPI_DECODE_PARAMS_QDATA); From 4609f7fd5e35fef9699578e2e7c104a143a2f896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Nov 2016 19:29:22 +0100 Subject: [PATCH 2616/3781] vaapidecodebin: bring back dynamic configuration In commit ca0c3fd6 we remove the dynamic configuration if the bin because we assumed that the bin will be always static as it is registered. Nonetheless we were wrong, because it is possible to request, with a property, to avoid the use of the post-processor. Since we want to add a way to disable the post-processor through environment variables, this remove feature is required again. If the environment variable GST_VAAPI_DISABLE_VPP is defined the postprocessor inside of the vaapidecodebin is disabled, then vaapidecodebin is an alias of the old vaapidecode. https://bugzilla.gnome.org/show_bug.cgi?id=775041 --- gst/vaapi/gstvaapidecodebin.c | 172 +++++++++++++++++++++++----------- 1 file changed, 118 insertions(+), 54 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index dfafc8e676..e7db8fc58e 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -124,6 +124,8 @@ GST_STATIC_PAD_TEMPLATE ("src", G_DEFINE_TYPE (GstVaapiDecodeBin, gst_vaapi_decode_bin, GST_TYPE_BIN); +static gboolean gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * self); + static void post_missing_element_message (GstVaapiDecodeBin * vaapidecbin, const gchar * missing_factory) @@ -205,6 +207,35 @@ gst_vaapi_decode_bin_get_property (GObject * object, } } +static GstStateChangeReturn +gst_vaapi_decode_bin_change_state (GstElement * element, + GstStateChange transition) +{ + GstVaapiDecodeBin *vaapidecbin = GST_VAAPI_DECODE_BIN (element); + GstStateChangeReturn ret; + + switch (transition) { + default: + break; + } + + ret = GST_ELEMENT_CLASS (gst_vaapi_decode_bin_parent_class)->change_state + (element, transition); + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + if (!gst_vaapi_decode_bin_configure (vaapidecbin)) + return GST_STATE_CHANGE_FAILURE; + break; + default: + break; + } + + return ret; +} + static void gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) { @@ -217,6 +248,7 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) gobject_class->set_property = gst_vaapi_decode_bin_set_property; gobject_class->get_property = gst_vaapi_decode_bin_get_property; + element_class->change_state = gst_vaapi_decode_bin_change_state; gst_element_class_set_static_metadata (element_class, "VA-API Decode Bin", "Codec/Decoder/Video", @@ -260,80 +292,72 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) static gboolean gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) { - const gchar *missing_factory = NULL; - GstPad *pad, *ghostpad; - - /* create the decoder */ - vaapidecbin->decoder = - g_object_new (g_type_from_name ("GstVaapiDecode"), NULL); - - if (vaapidecbin->disable_vpp) { - gst_bin_add (GST_BIN (vaapidecbin), vaapidecbin->decoder); - pad = gst_element_get_static_pad (vaapidecbin->decoder, "src"); - goto bail; - } - - /* create the queue */ - vaapidecbin->queue = gst_element_factory_make ("queue", "vaapi-queue"); - if (!vaapidecbin->queue) { - missing_factory = "queue"; - goto error_element_missing; - } + GstPad *queue_srcpad, *bin_srcpad, *vpp_sinkpad, *vpp_srcpad; + gboolean res; g_object_set (G_OBJECT (vaapidecbin->queue), "max-size-bytes", vaapidecbin->max_size_bytes, "max-size-buffers", vaapidecbin->max_size_buffers, "max-size-time", vaapidecbin->max_size_time, NULL); + if (vaapidecbin->disable_vpp) + return TRUE; + + GST_INFO_OBJECT (vaapidecbin, "enabling VPP"); + /* create the postproc */ vaapidecbin->postproc = gst_element_factory_make ("vaapipostproc", NULL); - if (!vaapidecbin->postproc) { - missing_factory = "vaapipostproc"; - goto error_element_missing; - } + if (!vaapidecbin->postproc) + goto error_vpp_missing; + g_object_set (G_OBJECT (vaapidecbin->postproc), "deinterlace-method", + vaapidecbin->deinterlace_method, NULL); - gst_bin_add_many (GST_BIN (vaapidecbin), vaapidecbin->decoder, - vaapidecbin->queue, vaapidecbin->postproc, NULL); + gst_bin_add (GST_BIN (vaapidecbin), vaapidecbin->postproc); + if (!gst_element_sync_state_with_parent (vaapidecbin->postproc)) + goto error_sync_state; - if (!gst_element_link_many (vaapidecbin->decoder, vaapidecbin->queue, - vaapidecbin->postproc, NULL)) + /* break source ghost pad target */ + bin_srcpad = + gst_element_get_static_pad (GST_ELEMENT_CAST (vaapidecbin), "src"); + if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (bin_srcpad), NULL)) goto error_link_pad; - /* create ghost pad src */ - pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->postproc), "src"); + /* link decoder and queue */ + queue_srcpad = gst_element_get_static_pad (vaapidecbin->queue, "src"); + vpp_sinkpad = gst_element_get_static_pad (vaapidecbin->postproc, "sink"); + res = (gst_pad_link (queue_srcpad, vpp_sinkpad) == GST_PAD_LINK_OK); + gst_object_unref (vpp_sinkpad); + gst_object_unref (queue_srcpad); + if (!res) + goto error_link_pad; -bail: - ghostpad = gst_ghost_pad_new_from_template ("src", pad, - GST_PAD_PAD_TEMPLATE (pad)); - gst_object_unref (pad); - if (!gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad)) - goto error_adding_pad; + /* set vpp source pad as source ghost pad target */ + vpp_srcpad = gst_element_get_static_pad (vaapidecbin->postproc, "src"); + res = gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (bin_srcpad), vpp_srcpad); + gst_object_unref (vpp_srcpad); + if (!res) + goto error_link_pad; - /* create ghost pad sink */ - pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->decoder), "sink"); - ghostpad = gst_ghost_pad_new_from_template ("sink", pad, - GST_PAD_PAD_TEMPLATE (pad)); - gst_object_unref (pad); - if (!gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad)) - goto error_adding_pad; + gst_object_unref (bin_srcpad); return TRUE; -error_element_missing: +error_vpp_missing: { - post_missing_element_message (vaapidecbin, missing_factory); + post_missing_element_message (vaapidecbin, "vaapipostproc"); + return FALSE; + } +error_sync_state: + { + GST_ELEMENT_ERROR (vaapidecbin, CORE, STATE_CHANGE, + ("Failed to sync state of vaapipostproc"), (NULL)); return FALSE; } error_link_pad: { - GST_ELEMENT_ERROR (vaapidecbin, CORE, PAD, (NULL), - ("Failed to configure the vaapidecodebin.")); - return FALSE; - } -error_adding_pad: - { - GST_ELEMENT_ERROR (vaapidecbin, CORE, PAD, (NULL), - ("Failed to adding pads.")); + gst_object_unref (bin_srcpad); + GST_ELEMENT_ERROR (vaapidecbin, CORE, PAD, + ("Failed to configure the vaapidecodebin."), (NULL)); return FALSE; } } @@ -341,7 +365,47 @@ error_adding_pad: static void gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) { - vaapidecbin->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; + GstPad *pad, *ghostpad; - gst_vaapi_decode_bin_configure (vaapidecbin); + vaapidecbin->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; + vaapidecbin->disable_vpp = (g_getenv ("GST_VAAPI_DISABLE_VPP") != NULL); + + /* create the decoder */ + vaapidecbin->decoder = + g_object_new (g_type_from_name ("GstVaapiDecode"), NULL); + g_assert (vaapidecbin->decoder); + + /* create the queue */ + vaapidecbin->queue = gst_element_factory_make ("queue", "vaapi-queue"); + if (!vaapidecbin->queue) { + g_clear_object (&vaapidecbin->decoder); + post_missing_element_message (vaapidecbin, "queue"); + return; + } + + gst_bin_add_many (GST_BIN (vaapidecbin), vaapidecbin->decoder, + vaapidecbin->queue, NULL); + + if (!gst_element_link (vaapidecbin->decoder, vaapidecbin->queue)) { + g_clear_object (&vaapidecbin->decoder); + g_clear_object (&vaapidecbin->queue); + g_critical ("failed to link decoder and queue"); + return; + } + + /* create ghost pad sink */ + pad = gst_element_get_static_pad (vaapidecbin->decoder, "sink"); + ghostpad = gst_ghost_pad_new_from_template ("sink", pad, + GST_PAD_PAD_TEMPLATE (pad)); + gst_object_unref (pad); + if (!gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad)) + g_critical ("failed to add decoder sink pad to bin"); + + /* create ghost pad src */ + pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->queue), "src"); + ghostpad = gst_ghost_pad_new_from_template ("src", pad, + GST_PAD_PAD_TEMPLATE (pad)); + gst_object_unref (pad); + if (!gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad)) + g_critical ("failed to add queue source pad to bin"); } From 6e6fbd1cbfdaffec6f58b3c9aca58a2216fc4c30 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 29 Nov 2016 14:59:02 +0900 Subject: [PATCH 2617/3781] vaapiencode: call ensure_encoder() at start() Currently, specific encoder is created during set_format(). This might lead to race condition when creating profiles with multiple encoders. This patch moves ensure_encoder() call to start() vmethod to ensure avoiding the race condition. https://bugzilla.gnome.org/show_bug.cgi?id=773546 --- gst/vaapi/gstvaapiencode.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index acaac3c02c..a68384a8df 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -438,6 +438,12 @@ gst_vaapiencode_open (GstVideoEncoder * venc) return success; } +static gboolean +gst_vaapiencode_start (GstVideoEncoder * venc) +{ + return ensure_encoder (GST_VAAPIENCODE_CAST (venc)); +} + static gboolean gst_vaapiencode_close (GstVideoEncoder * venc) { @@ -473,8 +479,6 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) g_return_val_if_fail (state->caps != NULL, FALSE); - if (!ensure_encoder (encode)) - return FALSE; if (!set_codec_state (encode, state)) return FALSE; @@ -713,6 +717,7 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) venc_class->open = GST_DEBUG_FUNCPTR (gst_vaapiencode_open); venc_class->close = GST_DEBUG_FUNCPTR (gst_vaapiencode_close); + venc_class->start = GST_DEBUG_FUNCPTR (gst_vaapiencode_start); venc_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_format); venc_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapiencode_handle_frame); venc_class->finish = GST_DEBUG_FUNCPTR (gst_vaapiencode_finish); From 5df21e9d54475fb4454aba072fdeb983919b78c9 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Sat, 3 Dec 2016 08:20:56 +0100 Subject: [PATCH 2618/3781] Automatic update of common submodule From f49c55e to 39ac2f5 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index f49c55ecd3..39ac2f563e 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit f49c55ecd35a7436194d28297f6d6f20eb6a66fa +Subproject commit 39ac2f563e12d22100e320c95aaab8d8e5812ca9 From 55aa83c5bf7b4408db2b23c0a88c6e1f4e408896 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 29 Nov 2016 15:14:32 +0900 Subject: [PATCH 2619/3781] vaapiencode: release internal encoder at stop() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the internal encoder is created at start(), let's release it at stop() vmethod, to be consistent. gst_vaapiencode_destroy() is called since it also resets the input and output states, which is something that the base class does internally after calling stop() vmethod. https://bugzilla.gnome.org/show_bug.cgi?id=769266 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapiencode.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index a68384a8df..8d76b3c362 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -444,13 +444,16 @@ gst_vaapiencode_start (GstVideoEncoder * venc) return ensure_encoder (GST_VAAPIENCODE_CAST (venc)); } +static gboolean +gst_vaapiencode_stop (GstVideoEncoder * venc) +{ + return gst_vaapiencode_destroy (GST_VAAPIENCODE_CAST (venc)); +} + static gboolean gst_vaapiencode_close (GstVideoEncoder * venc) { - GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); - - gst_vaapiencode_destroy (encode); - gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (encode)); + gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (venc)); return TRUE; } @@ -718,6 +721,7 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) venc_class->open = GST_DEBUG_FUNCPTR (gst_vaapiencode_open); venc_class->close = GST_DEBUG_FUNCPTR (gst_vaapiencode_close); venc_class->start = GST_DEBUG_FUNCPTR (gst_vaapiencode_start); + venc_class->stop = GST_DEBUG_FUNCPTR (gst_vaapiencode_stop); venc_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapiencode_set_format); venc_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapiencode_handle_frame); venc_class->finish = GST_DEBUG_FUNCPTR (gst_vaapiencode_finish); From bb4dc645f005f019ba1e8d466b38358cb9e4cf8b Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:30:09 +0100 Subject: [PATCH 2620/3781] vaapivideomemory: errors in gst_vaapi_dmabuf_allocator_new() Add a helper function to initialize the gst_debug_vaapivideomemory, to use it either by the GstVaapiVideoAllocatorClass or GstVaapiDmabufAllocator (which is a decorator of GstDmaBufAllocator). Later, log possible errors when calling gst_vaapi_dmabuf_allocator_new () https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapivideomemory.c | 80 ++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 854638ae86..2e8d517834 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -56,6 +56,20 @@ _init_performance_debug (void) #endif } +static void +_init_vaapi_video_memory_debug (void) +{ +#ifndef GST_DISABLE_GST_DEBUG + static volatile gsize _init = 0; + + if (g_once_init_enter (&_init)) { + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapivideomemory, "vaapivideomemory", 0, + "VA-API video memory allocator"); + g_once_init_leave (&_init, 1); + } +#endif +} + static inline void reset_image_usage (GstVaapiImageUsageFlags * flag) { @@ -614,10 +628,8 @@ error_allocate_memory: #define GST_VAAPI_IS_VIDEO_ALLOCATOR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_ALLOCATOR)) -G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoAllocator, - gst_vaapi_video_allocator, GST_TYPE_ALLOCATOR, - GST_DEBUG_CATEGORY_INIT (gst_debug_vaapivideomemory, "vaapivideomemory", 0, - "VA-API video memory allocator")); +G_DEFINE_TYPE (GstVaapiVideoAllocator, gst_vaapi_video_allocator, + GST_TYPE_ALLOCATOR); static void gst_vaapi_video_allocator_free (GstAllocator * allocator, GstMemory * base_mem) @@ -651,6 +663,8 @@ gst_vaapi_video_allocator_class_init (GstVaapiVideoAllocatorClass * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstAllocatorClass *const allocator_class = GST_ALLOCATOR_CLASS (klass); + _init_vaapi_video_memory_debug (); + object_class->finalize = gst_vaapi_video_allocator_finalize; allocator_class->free = gst_vaapi_video_allocator_free; } @@ -980,29 +994,55 @@ gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, g_return_val_if_fail (display != NULL, NULL); g_return_val_if_fail (vip != NULL, NULL); - do { - surface = gst_vaapi_surface_new_full (display, vip, flags); - if (!surface) - break; + _init_vaapi_video_memory_debug (); - image = gst_vaapi_surface_derive_image (surface); - if (!image || !gst_vaapi_image_map (image)) - break; + surface = gst_vaapi_surface_new_full (display, vip, flags); + if (!surface) + goto error_no_surface; - gst_video_info_set_format (&alloc_info, GST_VIDEO_INFO_FORMAT (vip), - GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); - gst_video_info_update_from_image (&alloc_info, image); - gst_vaapi_image_unmap (image); + image = gst_vaapi_surface_derive_image (surface); + if (!image) + goto error_no_image; + if (!gst_vaapi_image_map (image)) + goto error_map_failed; - allocator = gst_dmabuf_allocator_new (); - if (!allocator) - break; - gst_allocator_set_vaapi_video_info (allocator, &alloc_info, flags); - } while (0); + gst_video_info_set_format (&alloc_info, GST_VIDEO_INFO_FORMAT (vip), + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); + gst_video_info_update_from_image (&alloc_info, image); + gst_vaapi_image_unmap (image); + allocator = gst_dmabuf_allocator_new (); + if (!allocator) + goto error_no_allocator; + gst_allocator_set_vaapi_video_info (allocator, &alloc_info, flags); + +bail: gst_vaapi_object_replace (&image, NULL); gst_vaapi_object_replace (&surface, NULL); return allocator; + + /* ERRORS */ +error_no_surface: + { + GST_ERROR ("failed to create a new surface"); + goto bail; + } +error_no_image: + { + GST_ERROR ("failed derive surface to image for format: %s", + GST_VIDEO_INFO_FORMAT_STRING (vip)); + goto bail; + } +error_map_failed: + { + GST_ERROR ("failed to map image"); + goto bail; + } +error_no_allocator: + { + GST_ERROR ("failed to create a new dmabuf allocator"); + goto bail; + } } /* ------------------------------------------------------------------------ */ From 952b20a8933ed0a9e4bea07b231c4b51a731e832 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:27:03 +0100 Subject: [PATCH 2621/3781] vaapivideomemory: add real GstVaapiDmaBufAllocator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of defining GstVaapiDmaBufAllocator as a hackish decorator of GstDmaBufAllocator, now, since the expose of the GstDmaBufAllocator's GType, GstVaapiDmaBufAllocator is a full feature GstAllocator inherited from GstDmaBufAllocator. https://bugzilla.gnome.org/show_bug.cgi?id=755072 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapivideomemory.c | 39 ++++++++++++++++++++++++--------- gst/vaapi/gstvaapivideomemory.h | 39 +++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 2e8d517834..b3695adab2 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -889,7 +889,8 @@ gst_vaapi_buffer_proxy_quark_get (void) } GstMemory * -gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta) +gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, + GstVaapiVideoMeta * meta) { GstMemory *mem; GstVaapiDisplay *display; @@ -899,11 +900,13 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta) gint dmabuf_fd; const GstVideoInfo *vip; guint flags; + GstVaapiDmaBufAllocator *const allocator = + GST_VAAPI_DMABUF_ALLOCATOR_CAST (base_allocator); g_return_val_if_fail (allocator != NULL, NULL); g_return_val_if_fail (meta != NULL, NULL); - vip = gst_allocator_get_vaapi_video_info (allocator, &flags); + vip = gst_allocator_get_vaapi_video_info (base_allocator, &flags); if (!vip) return NULL; @@ -934,7 +937,7 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta) if (dmabuf_fd < 0 || (dmabuf_fd = dup (dmabuf_fd)) < 0) goto error_create_dmabuf_handle; - mem = gst_dmabuf_allocator_alloc (allocator, dmabuf_fd, + mem = gst_dmabuf_allocator_alloc (base_allocator, dmabuf_fd, gst_vaapi_buffer_proxy_get_size (dmabuf_proxy)); if (!mem) goto error_create_dmabuf_memory; @@ -982,11 +985,28 @@ error_create_dmabuf_memory: /* --- GstVaapiDmaBufAllocator --- */ /* ------------------------------------------------------------------------ */ +G_DEFINE_TYPE (GstVaapiDmaBufAllocator, + gst_vaapi_dmabuf_allocator, GST_TYPE_DMABUF_ALLOCATOR); + +static void +gst_vaapi_dmabuf_allocator_class_init (GstVaapiDmaBufAllocatorClass * klass) +{ + _init_vaapi_video_memory_debug (); +} + +static void +gst_vaapi_dmabuf_allocator_init (GstVaapiDmaBufAllocator * allocator) +{ + GstAllocator *const base_allocator = GST_ALLOCATOR_CAST (allocator); + + base_allocator->mem_type = GST_VAAPI_DMABUF_ALLOCATOR_NAME; +} + GstAllocator * gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, const GstVideoInfo * vip, guint flags) { - GstAllocator *allocator = NULL; + GstVaapiDmaBufAllocator *allocator = NULL; GstVaapiSurface *surface = NULL; GstVaapiImage *image = NULL; GstVideoInfo alloc_info; @@ -994,8 +1014,6 @@ gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, g_return_val_if_fail (display != NULL, NULL); g_return_val_if_fail (vip != NULL, NULL); - _init_vaapi_video_memory_debug (); - surface = gst_vaapi_surface_new_full (display, vip, flags); if (!surface) goto error_no_surface; @@ -1011,15 +1029,16 @@ gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, gst_video_info_update_from_image (&alloc_info, image); gst_vaapi_image_unmap (image); - allocator = gst_dmabuf_allocator_new (); + allocator = g_object_new (GST_VAAPI_TYPE_DMABUF_ALLOCATOR, NULL); if (!allocator) goto error_no_allocator; - gst_allocator_set_vaapi_video_info (allocator, &alloc_info, flags); + gst_allocator_set_vaapi_video_info (GST_ALLOCATOR_CAST (allocator), + &alloc_info, flags); bail: gst_vaapi_object_replace (&image, NULL); gst_vaapi_object_replace (&surface, NULL); - return allocator; + return GST_ALLOCATOR_CAST (allocator); /* ERRORS */ error_no_surface: @@ -1168,7 +1187,7 @@ gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator) g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), FALSE); - if (g_strcmp0 (allocator->mem_type, GST_ALLOCATOR_DMABUF) != 0) + if (g_strcmp0 (allocator->mem_type, GST_VAAPI_DMABUF_ALLOCATOR_NAME) != 0) return FALSE; st = g_object_get_qdata (G_OBJECT (allocator), GST_VAAPI_VIDEO_INFO_QUARK); return (st != NULL); diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 8f4746b7b2..4641f193f4 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -35,6 +35,8 @@ G_BEGIN_DECLS typedef struct _GstVaapiVideoMemory GstVaapiVideoMemory; typedef struct _GstVaapiVideoAllocator GstVaapiVideoAllocator; typedef struct _GstVaapiVideoAllocatorClass GstVaapiVideoAllocatorClass; +typedef struct _GstVaapiDmaBufAllocator GstVaapiDmaBufAllocator; +typedef struct _GstVaapiDmaBufAllocatorClass GstVaapiDmaBufAllocatorClass; /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoMemory --- */ @@ -220,6 +222,43 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, /* --- GstVaapiDmaBufAllocator --- */ /* ------------------------------------------------------------------------ */ +#define GST_VAAPI_DMABUF_ALLOCATOR_CAST(allocator) \ + ((GstVaapiDmaBufAllocator *) (allocator)) + +#define GST_VAAPI_TYPE_DMABUF_ALLOCATOR \ + (gst_vaapi_dmabuf_allocator_get_type ()) +#define GST_VAAPI_DMABUF_ALLOCATOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_DMABUF_ALLOCATOR, \ + GstVaapiDmaBufAllocator)) +#define GST_VAAPI_IS_DMABUF_ALLOCATOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_DMABUF_ALLOCATOR)) + +#define GST_VAAPI_DMABUF_ALLOCATOR_NAME "GstVaapiDmaBufAllocator" + +/** + * GstVaapiDmaBufAllocator: + * + * A VA dmabuf memory allocator object. + */ +struct _GstVaapiDmaBufAllocator +{ + GstDmaBufAllocator parent_instance; +}; + +/** + * GstVaapiDmaBufoAllocatorClass: + * + * A VA dmabuf memory allocator class. + */ +struct _GstVaapiDmaBufAllocatorClass +{ + GstDmaBufAllocatorClass parent_class; +}; + +G_GNUC_INTERNAL +GType +gst_vaapi_dmabuf_allocator_get_type (void) G_GNUC_CONST; + G_GNUC_INTERNAL GstAllocator * gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, From 4dffc12d6b11d3c1a8b7d26afc5a1aeb6600035d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 11 Nov 2016 19:45:45 +0100 Subject: [PATCH 2622/3781] vaapivideomemory: rename video for allocation_info Since video_info stores the GstVideoInfo of the allocation caps, it is clear if we rename it as allocation_info, to distinguish it later from negotiation_info. --- gst/vaapi/gstvaapivideomemory.c | 6 +++--- gst/vaapi/gstvaapivideomemory.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index b3695adab2..613441fac8 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -729,7 +729,7 @@ allocator_configure_surface_info (GstVaapiDisplay * display, gboolean updated, has_direct_uploading, has_direct_rendering; GstVideoFormat fmt; - vinfo = &allocator->video_info; + vinfo = &allocator->allocation_info; allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; fmt = gst_vaapi_video_format_get_best_native (GST_VIDEO_INFO_FORMAT (vinfo)); @@ -806,7 +806,7 @@ allocator_configure_image_info (GstVaapiDisplay * display, return; } - vinfo = &allocator->video_info; + vinfo = &allocator->allocation_info; allocator->image_info = *vinfo; gst_video_info_force_nv12_if_encoded (&allocator->image_info); @@ -838,7 +838,7 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display, if (!allocator) return NULL; - allocator->video_info = *vip; + allocator->allocation_info = *vip; allocator_configure_surface_info (display, allocator, req_usage_flag); allocator->surface_pool = gst_vaapi_surface_pool_new_full (display, diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 4641f193f4..761ad1ce58 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -181,7 +181,7 @@ struct _GstVaapiVideoAllocator GstAllocator parent_instance; /*< private >*/ - GstVideoInfo video_info; + GstVideoInfo allocation_info; GstVideoInfo surface_info; GstVaapiVideoPool *surface_pool; GstVideoInfo image_info; From f88ce54b65e7f03fdfde13376d8a9988b30d5c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 14 Nov 2016 17:33:41 +0100 Subject: [PATCH 2623/3781] vaapivideomemory: remove unused macros These macros are not used. Let us remove them. --- gst/vaapi/gstvaapivideomemory.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 613441fac8..00955cd812 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -621,13 +621,6 @@ error_allocate_memory: /* --- GstVaapiVideoAllocator --- */ /* ------------------------------------------------------------------------ */ -#define GST_VAAPI_VIDEO_ALLOCATOR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_ALLOCATOR, \ - GstVaapiVideoAllocatorClass)) - -#define GST_VAAPI_IS_VIDEO_ALLOCATOR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_ALLOCATOR)) - G_DEFINE_TYPE (GstVaapiVideoAllocator, gst_vaapi_video_allocator, GST_TYPE_ALLOCATOR); From b9b8c26c4012a7c8df1effc19cd55c52d36cba76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 14 Nov 2016 17:40:37 +0100 Subject: [PATCH 2624/3781] vaapivideomemory: log error if not VA image Log an error message if the test image for surface downloading cannot be allocated or mapped. --- gst/vaapi/gstvaapivideomemory.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 00955cd812..9fa69fc59d 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -805,9 +805,9 @@ allocator_configure_image_info (GstVaapiDisplay * display, image = new_image (display, &allocator->image_info); if (!image) - goto bail; + goto error; if (!gst_vaapi_image_map (image)) - goto bail; + goto error; gst_video_info_update_from_image (&allocator->image_info, image); gst_vaapi_image_unmap (image); @@ -815,6 +815,14 @@ allocator_configure_image_info (GstVaapiDisplay * display, bail: if (image) gst_vaapi_object_unref (image); + return; + + /* ERRORS */ +error: + { + GST_ERROR_OBJECT (allocator, "Cannot create or map a VA image"); + goto bail; + } } GstAllocator * From ad8da84062d87fb93a03c6682ab792c94034be54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 14 Nov 2016 17:45:55 +0100 Subject: [PATCH 2625/3781] vaapivideomemory: refactor code for readability Added the inlined function allocator_configure_pools() moving out code from gst_vaapi_video_allocator_new() to make clear that it is a post-initalization of the object. --- gst/vaapi/gstvaapivideomemory.c | 47 +++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 9fa69fc59d..b8b2c8eea7 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -825,20 +825,11 @@ error: } } -GstAllocator * -gst_vaapi_video_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint surface_alloc_flags, - GstVaapiImageUsageFlags req_usage_flag) +static inline gboolean +allocator_params_init (GstVaapiVideoAllocator * allocator, + GstVaapiDisplay * display, const GstVideoInfo * vip, + guint surface_alloc_flags, GstVaapiImageUsageFlags req_usage_flag) { - GstVaapiVideoAllocator *allocator; - - g_return_val_if_fail (display != NULL, NULL); - g_return_val_if_fail (vip != NULL, NULL); - - allocator = g_object_new (GST_VAAPI_TYPE_VIDEO_ALLOCATOR, NULL); - if (!allocator) - return NULL; - allocator->allocation_info = *vip; allocator_configure_surface_info (display, allocator, req_usage_flag); @@ -855,21 +846,43 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display, gst_allocator_set_vaapi_video_info (GST_ALLOCATOR_CAST (allocator), &allocator->image_info, surface_alloc_flags); - return GST_ALLOCATOR_CAST (allocator); + + return TRUE; /* ERRORS */ error_create_surface_pool: { GST_ERROR ("failed to allocate VA surface pool"); - gst_object_unref (allocator); - return NULL; + return FALSE; } error_create_image_pool: { GST_ERROR ("failed to allocate VA image pool"); - gst_object_unref (allocator); + return FALSE; + } +} + +GstAllocator * +gst_vaapi_video_allocator_new (GstVaapiDisplay * display, + const GstVideoInfo * vip, guint surface_alloc_flags, + GstVaapiImageUsageFlags req_usage_flag) +{ + GstVaapiVideoAllocator *allocator; + + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (vip != NULL, NULL); + + allocator = g_object_new (GST_VAAPI_TYPE_VIDEO_ALLOCATOR, NULL); + if (!allocator) + return NULL; + + if (!allocator_params_init (allocator, display, vip, surface_alloc_flags, + req_usage_flag)) { + g_object_unref (allocator); return NULL; } + + return GST_ALLOCATOR_CAST (allocator); } /* ------------------------------------------------------------------------ */ From 7aeefb09904baf807e342b30093c38f3976e593f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 6 Dec 2016 17:33:42 +0100 Subject: [PATCH 2626/3781] libs: drm: find render node in hybrid system Originally the drm backend only tried to open the first render node found. But in hybrid system this first render node might not support VA-API (propietary Nvidia driver, for example). This patch tries all the available nodes until a finding one with a VA-API supported driver. https://bugzilla.gnome.org/show_bug.cgi?id=774811 Original-patch-by: Stirling Westrup and Reza Razavi --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 44e4cbd87f..1150f75376 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -58,6 +58,22 @@ typedef enum static DRMDeviceType g_drm_device_type; static GMutex g_drm_device_type_lock; +static gboolean +supports_vaapi (int fd) +{ + gboolean ret; + VADisplay va_dpy; + int major, minor; + + va_dpy = vaGetDisplayDRM (fd); + if (!va_dpy) + return FALSE; + + ret = (vaInitialize (va_dpy, &major, &minor) == VA_STATUS_SUCCESS); + 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) @@ -109,10 +125,12 @@ get_default_device_path (GstVaapiDisplay * display) continue; } - priv->device_path_default = g_strdup (devpath); + if (supports_vaapi (fd)) + priv->device_path_default = g_strdup (devpath); close (fd); udev_device_unref (device); - break; + if (priv->device_path_default) + break; } end: From 059cc59a29c5df1cba55bee8d8c4a25002e9f973 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 2 Dec 2016 09:28:07 +0900 Subject: [PATCH 2627/3781] libs: context: split context_create() Split the funcion context_create() into context_create() and config_create(). Decoupling VAConfig and VAContext during context creation, we could query the VAConfig for the supported surface's formats without creating a VAContext. https://bugzilla.gnome.org/show_bug.cgi?id=769266 --- gst-libs/gst/vaapi/gstvaapicontext.c | 54 ++++++++++++++++++---------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index bf7a915e91..e6410dc1e6 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -181,13 +181,12 @@ context_create (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); - VAConfigAttrib attribs[3], *attrib = attribs; VAContextID context_id; VASurfaceID surface_id; VAStatus status; GArray *surfaces = NULL; gboolean success = FALSE; - guint i, value, va_chroma_format; + guint i; if (!context->surfaces && !context_create_surfaces (context)) goto cleanup; @@ -207,6 +206,33 @@ context_create (GstVaapiContext * context) } g_assert (surfaces->len == context->surfaces->len); + GST_VAAPI_DISPLAY_LOCK (display); + status = vaCreateContext (GST_VAAPI_DISPLAY_VADISPLAY (display), + context->va_config, cip->width, cip->height, VA_PROGRESSIVE, + (VASurfaceID *) surfaces->data, surfaces->len, &context_id); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaCreateContext()")) + goto cleanup; + + GST_DEBUG ("context 0x%08x", context_id); + GST_VAAPI_OBJECT_ID (context) = context_id; + success = TRUE; + +cleanup: + if (surfaces) + g_array_free (surfaces, TRUE); + return success; +} + +static gboolean +config_create (GstVaapiContext * context) +{ + const GstVaapiContextInfo *const cip = &context->info; + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); + VAConfigAttrib attribs[3], *attrib = attribs; + VAStatus status; + guint value, va_chroma_format; + /* Reset profile and entrypoint */ if (!cip->profile || !cip->entrypoint) goto cleanup; @@ -289,22 +315,10 @@ context_create (GstVaapiContext * context) if (!vaapi_check_status (status, "vaCreateConfig()")) goto cleanup; - GST_VAAPI_DISPLAY_LOCK (display); - status = vaCreateContext (GST_VAAPI_DISPLAY_VADISPLAY (display), - context->va_config, cip->width, cip->height, VA_PROGRESSIVE, - (VASurfaceID *) surfaces->data, surfaces->len, &context_id); - GST_VAAPI_DISPLAY_UNLOCK (display); - if (!vaapi_check_status (status, "vaCreateContext()")) - goto cleanup; - - GST_DEBUG ("context 0x%08x", context_id); - GST_VAAPI_OBJECT_ID (context) = context_id; - success = TRUE; - + return TRUE; cleanup: - if (surfaces) - g_array_free (surfaces, TRUE); - return success; + GST_WARNING ("Failed to create vaConfig"); + return FALSE; } /** Updates config for encoding. Returns %TRUE if config changed */ @@ -383,6 +397,10 @@ gst_vaapi_context_new (GstVaapiDisplay * display, return NULL; gst_vaapi_context_init (context, cip); + + if (!config_create (context)) + goto error; + if (!context_create (context)) goto error; return context; @@ -461,7 +479,7 @@ gst_vaapi_context_reset (GstVaapiContext * context, return FALSE; else if (grow_surfaces && !context_ensure_surfaces (context)) return FALSE; - if (reset_config && !context_create (context)) + if (reset_config && !(config_create (context) && context_create (context))) return FALSE; return TRUE; } From 41d27b5e2ec3fab6cebbe92569dd6e29428f1033 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 2 Dec 2016 09:30:52 +0900 Subject: [PATCH 2628/3781] libs: context: skip VAContext if no frame size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If GstVaapiContextInfo has just initial information, without frame's width and height, skip the creation of the VAContext, just keep the VAConfig. https://bugzilla.gnome.org/show_bug.cgi?id=769266 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapicontext.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index e6410dc1e6..9a3e0abd45 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -389,8 +389,6 @@ gst_vaapi_context_new (GstVaapiDisplay * display, g_return_val_if_fail (cip->profile, NULL); g_return_val_if_fail (cip->entrypoint, NULL); - g_return_val_if_fail (cip->width > 0, NULL); - g_return_val_if_fail (cip->height > 0, NULL); context = gst_vaapi_object_new (gst_vaapi_context_class (), display); if (!context) @@ -401,8 +399,18 @@ gst_vaapi_context_new (GstVaapiDisplay * display, 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: return context; /* ERRORS */ From 72e26ed30b475553019e0b2952057cfd4b56e27a Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 7 Dec 2016 11:10:42 +0100 Subject: [PATCH 2629/3781] libs: encoder: split set_context_info() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split set_context_info() adding init_context_info() which only initialises the GstVaapiContextInfo structure inside GstVaapiEncoder required for VAConfig. https://bugzilla.gnome.org/show_bug.cgi?id=769266 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiencoder.c | 32 +++++++++++++++++++--------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index b8cd4f1341..eac90a81bf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -588,6 +588,26 @@ unsupported: } } +static void +init_context_info (GstVaapiEncoder * encoder) +{ + GstVaapiContextInfo *const cip = &encoder->context_info; + const GstVaapiEncoderClassData *const cdata = + GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; + + cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; + cip->profile = encoder->profile; + if (cdata->codec == GST_VAAPI_CODEC_JPEG) { + cip->entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; + } else { + if (cip->entrypoint != GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) + cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + } + cip->width = 0; + cip->height = 0; + cip->ref_frames = encoder->num_ref_frames; +} + /* Updates video context */ static gboolean set_context_info (GstVaapiEncoder * encoder) @@ -596,20 +616,12 @@ set_context_info (GstVaapiEncoder * encoder) GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); - const GstVaapiEncoderClassData *const cdata = - GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; - cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; - cip->profile = encoder->profile; - if (cdata->codec != GST_VAAPI_CODEC_JPEG) { - if (cip->entrypoint != GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) - cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; - } else - cip->entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; + init_context_info (encoder); + cip->chroma_type = gst_vaapi_video_format_get_chroma_type (format); cip->width = GST_VAAPI_ENCODER_WIDTH (encoder); cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); - cip->ref_frames = encoder->num_ref_frames; if (!is_chroma_type_supported (encoder)) goto error_unsupported_format; From 4e2049d108666d0670b3fb621aa230d7952dbdf1 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 7 Dec 2016 11:26:37 +0100 Subject: [PATCH 2630/3781] libs: encoder: add gst_vaapi_encoder_get_surface_formats() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This method will return the valid surface formats in the current config. If the are no VAConfig it is created with the information available. https://bugzilla.gnome.org/show_bug.cgi?id=769266 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiencoder.c | 29 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 2 ++ 2 files changed, 31 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index eac90a81bf..a55f782bfd 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1153,6 +1153,35 @@ error: } } +static gboolean +gst_vaapi_encoder_ensure_context_config (GstVaapiEncoder * encoder) +{ + GstVaapiContextInfo *const cip = &encoder->context_info; + + if (encoder->context) + return TRUE; + + init_context_info (encoder); + encoder->context = gst_vaapi_context_new (encoder->display, cip); + return (encoder->context != NULL); +} + +/** + * gst_vaapi_encoder_get_surface_formats: + * @encoder: a #GstVaapiEncoder instances + * + * Fetches the valid surface formats for the current VAConfig + * + * Returns: a #GArray of valid formats for the current VAConfig + **/ +GArray * +gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder) +{ + if (!gst_vaapi_encoder_ensure_context_config (encoder)) + return NULL; + return gst_vaapi_context_get_surface_formats (encoder->context); +} + /** Returns a GType for the #GstVaapiEncoderTune set */ GType gst_vaapi_encoder_tune_get_type (void) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index a90e26dc67..3160036d69 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -173,6 +173,8 @@ gst_vaapi_encoder_get_buffer_with_timeout (GstVaapiEncoder * encoder, GstVaapiEncoderStatus gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); +GArray * +gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder); G_END_DECLS #endif /* GST_VAAPI_ENCODER_H */ From 9bda7a6d5d13a788daa13fde7c96dfdbbaafdb1d Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 1 Dec 2016 18:57:10 +0900 Subject: [PATCH 2631/3781] vaapiencode: get surface formats in get_caps() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Query for the supported surface formats in config at get_caps() vmethod. https://bugzilla.gnome.org/show_bug.cgi?id=769266 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapiencode.c | 64 ++++++++++++++++++++++++++++++++++++-- gst/vaapi/gstvaapiencode.h | 1 + 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 8d76b3c362..4a7c64fa54 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -342,16 +342,72 @@ gst_vaapiencode_buffer_loop (GstVaapiEncode * encode) gst_pad_pause_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); } +static gboolean +ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) +{ + GstCaps *out_caps, *raw_caps = NULL; + GArray *formats = NULL; + gboolean ret = FALSE; + + if (encode->allowed_sinkpad_caps) + return TRUE; + if (!encode->encoder) + return TRUE; + + out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS); + if (!out_caps) + goto failed_create_va_caps; + + formats = gst_vaapi_encoder_get_surface_formats (encode->encoder); + if (!formats) + goto failed_get_formats; + + raw_caps = gst_vaapi_video_format_new_template_caps_from_list (formats); + if (!raw_caps) + goto failed_create_raw_caps; + + out_caps = gst_caps_make_writable (out_caps); + gst_caps_append (out_caps, gst_caps_copy (raw_caps)); + gst_caps_replace (&encode->allowed_sinkpad_caps, out_caps); + ret = TRUE; + +bail: + if (out_caps) + gst_caps_unref (out_caps); + if (raw_caps) + gst_caps_unref (raw_caps); + if (formats) + g_array_unref (formats); + return ret; + +failed_create_va_caps: + { + GST_WARNING_OBJECT (encode, "failed to create VA/GL sink caps"); + return FALSE; + } +failed_get_formats: + { + GST_WARNING_OBJECT (encode, "failed to get allowed surface formats"); + goto bail; + } +failed_create_raw_caps: + { + GST_WARNING_OBJECT (encode, "failed to create raw sink caps"); + goto bail; + } +} + static GstCaps * gst_vaapiencode_get_caps (GstVideoEncoder * venc, GstCaps * filter) { - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (venc); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); GstCaps *result; - result = gst_video_encoder_proxy_getcaps (venc, plugin->sinkpad_caps, filter); + ensure_allowed_sinkpad_caps (encode); + result = gst_video_encoder_proxy_getcaps (venc, encode->allowed_sinkpad_caps, + filter); GST_DEBUG_OBJECT (venc, "Returning sink caps %" GST_PTR_FORMAT, result); - return result; } @@ -367,6 +423,8 @@ gst_vaapiencode_destroy (GstVaapiEncode * encode) gst_video_codec_state_unref (encode->output_state); encode->output_state = NULL; } + + gst_caps_replace (&encode->allowed_sinkpad_caps, NULL); gst_vaapi_encoder_replace (&encode->encoder, NULL); return TRUE; } diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 03c6a104c5..77a8a40bb6 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -59,6 +59,7 @@ struct _GstVaapiEncode gboolean need_codec_data; GstVideoCodecState *output_state; GPtrArray *prop_values; + GstCaps *allowed_sinkpad_caps; }; struct _GstVaapiEncodeClass From 2d9547273e0d5ea883cce7855fe1c5b104a99a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 7 Dec 2016 16:52:35 +0100 Subject: [PATCH 2632/3781] Revert "encoders: demote to RANK_NONE since not fit for autoplugging yet" This reverts commit f182b8be2ba05965e6d31a4d380d6563b9b53a77. --- gst/vaapi/gstvaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 6996f7ae56..f060f8e6af 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -141,7 +141,7 @@ struct _GstVaapiEncoderMap #define DEF_ENC(CODEC,codec) \ {GST_VAAPI_CODEC_##CODEC, \ - GST_RANK_NONE, \ + GST_RANK_PRIMARY, \ "vaapi" G_STRINGIFY (codec) "enc", \ gst_vaapiencode_##codec##_get_type} From ba49dc9dd77e858946fd2ad277117abcc8e36ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 9 Dec 2016 17:42:42 +0100 Subject: [PATCH 2633/3781] Revert "vaapidecode: implement negotiate() vmethod" This reverts commit 3285121181295c544480fc6ba756845b16285d30. videodecode's negotiate() vmethod is also called when events arrive, but this would mean that the proper configuration of sink pad might not be complete, thus we should not update the src pad. Let's keep the old non-vmethod negotitate(). --- gst/vaapi/gstvaapidecode.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6d9e21527a..db490615de 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -458,18 +458,20 @@ set_display_res: } static gboolean -gst_vaapidecode_negotiate (GstVideoDecoder * vdec) +gst_vaapidecode_negotiate (GstVaapiDecode * decode) { - GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); + GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); + GST_DEBUG_OBJECT (decode, "Input codec state changed, doing renegotiation"); + if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) return FALSE; if (!gst_vaapidecode_update_src_caps (decode)) return FALSE; if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) return FALSE; - if (!GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (vdec)) + if (!gst_video_decoder_negotiate (vdec)) return FALSE; return TRUE; @@ -507,8 +509,8 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, if (gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec)) || alloc_renegotiate || caps_renegotiate) { - GST_INFO_OBJECT (decode, "input codec state changed: renegotiating"); - if (!gst_video_decoder_negotiate (vdec)) + + if (!gst_vaapidecode_negotiate (decode)) return GST_FLOW_ERROR; } @@ -1308,7 +1310,6 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_query); vdec_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_getcaps); vdec_class->sink_event = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_event); - vdec_class->negotiate = GST_DEBUG_FUNCPTR (gst_vaapidecode_negotiate); map = (GstVaapiDecoderMap *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass), GST_VAAPI_DECODE_PARAMS_QDATA); From daed911caf4bbeee35273e78ebe029a03cf645b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 9 Dec 2016 17:56:02 +0100 Subject: [PATCH 2634/3781] vaapidecode: lock stream when setting caps --- gst/vaapi/gstvaapidecode.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index db490615de..6b490176b2 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -463,14 +463,17 @@ gst_vaapidecode_negotiate (GstVaapiDecode * decode) GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode); GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); - GST_DEBUG_OBJECT (decode, "Input codec state changed, doing renegotiation"); + GST_DEBUG_OBJECT (decode, "input codec state changed: renegotiating"); + GST_VIDEO_DECODER_STREAM_LOCK (vdec); if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) return FALSE; if (!gst_vaapidecode_update_src_caps (decode)) return FALSE; if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) return FALSE; + GST_VIDEO_DECODER_STREAM_UNLOCK (vdec); + if (!gst_video_decoder_negotiate (vdec)) return FALSE; From 7b2f774036a6c568f688a3e61b5b76eb58814819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 9 Dec 2016 15:51:32 +0100 Subject: [PATCH 2635/3781] vaapivideomemory: no log object at initialization When an instance of GstVaapiVideoAllocator fails at initializing, the log message should not include the allocator's object, because it is going to be unrefed. --- gst/vaapi/gstvaapivideomemory.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index b8b2c8eea7..de7017d83f 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -771,18 +771,17 @@ bail: error_no_surface: { - GST_ERROR_OBJECT (allocator, "Cannot create a VA Surface"); + GST_ERROR ("Cannot create a VA Surface"); return; } error_no_derive_image: { - GST_ERROR_OBJECT (allocator, - "Cannot create a derived image from surface %p", surface); + GST_ERROR ("Cannot create a derived image from surface %p", surface); goto bail; } error_cannot_map: { - GST_ERROR_OBJECT (allocator, "Cannot map VA derived image %p", image); + GST_ERROR ("Cannot map VA derived image %p", image); goto bail; } } @@ -805,9 +804,9 @@ allocator_configure_image_info (GstVaapiDisplay * display, image = new_image (display, &allocator->image_info); if (!image) - goto error; + goto error_no_image; if (!gst_vaapi_image_map (image)) - goto error; + goto error_cannot_map; gst_video_info_update_from_image (&allocator->image_info, image); gst_vaapi_image_unmap (image); @@ -818,9 +817,14 @@ bail: return; /* ERRORS */ -error: +error_no_image: { - GST_ERROR_OBJECT (allocator, "Cannot create or map a VA image"); + GST_ERROR ("Cannot create VA image"); + return; + } +error_cannot_map: + { + GST_ERROR ("Failed to map VA image %p", image); goto bail; } } From 0f819fa190ef3f052d5e663b6e76d921b1ef2caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 9 Dec 2016 16:14:14 +0100 Subject: [PATCH 2636/3781] vaapivideomemory: add gst_video_info_update_from_surface() With this function is possible to refactor and remove duplicated code between dmabuf configuration and direct rendering/uploading configuration. --- gst/vaapi/gstvaapivideomemory.c | 136 ++++++++++++++++---------------- 1 file changed, 70 insertions(+), 66 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index de7017d83f..7196e29144 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -712,14 +712,46 @@ gst_video_info_update_from_image (GstVideoInfo * vip, GstVaapiImage * image) return TRUE; } +static gboolean +gst_video_info_update_from_surface (GstVideoInfo * vip, + GstVaapiSurface * surface) +{ + GstVaapiImage *image; + gboolean ret; + + ret = FALSE; + image = gst_vaapi_surface_derive_image (surface); + if (!image) + goto error_no_derive_image; + if (!gst_vaapi_image_map (image)) + goto error_cannot_map; + ret = gst_video_info_update_from_image (vip, image); + gst_vaapi_image_unmap (image); + +bail: + gst_vaapi_object_unref (image); + return ret; + + /* ERRORS */ +error_no_derive_image: + { + GST_ERROR ("Cannot create a VA derived image from surface %p", surface); + return FALSE; + } +error_cannot_map: + { + GST_ERROR ("Cannot map VA derived image %p", image); + goto bail; + } +} + static inline void allocator_configure_surface_info (GstVaapiDisplay * display, GstVaapiVideoAllocator * allocator, GstVaapiImageUsageFlags req_usage_flag) { const GstVideoInfo *vinfo; + GstVideoInfo *sinfo; GstVaapiSurface *surface = NULL; - GstVaapiImage *image = NULL; - gboolean updated, has_direct_uploading, has_direct_rendering; GstVideoFormat fmt; vinfo = &allocator->allocation_info; @@ -737,34 +769,28 @@ allocator_configure_surface_info (GstVaapiDisplay * display, surface = new_surface (display, vinfo, req_usage_flag); if (!surface) goto error_no_surface; - image = gst_vaapi_surface_derive_image (surface); - if (!image) - goto error_no_derive_image; - if (!gst_vaapi_image_map (image)) - goto error_cannot_map; - updated = gst_video_info_update_from_image (&allocator->surface_info, image); + sinfo = &allocator->surface_info; + if (!gst_video_info_update_from_surface (sinfo, surface)) + goto bail; - has_direct_rendering = updated && use_direct_rendering (req_usage_flag) - && (GST_VAAPI_IMAGE_FORMAT (image) == GST_VIDEO_INFO_FORMAT (vinfo)); - has_direct_uploading = updated && use_direct_uploading (req_usage_flag) - && (GST_VAAPI_IMAGE_FORMAT (image) == GST_VIDEO_INFO_FORMAT (vinfo)); + /* if not the same format, don't use derived images */ + if (GST_VIDEO_INFO_FORMAT (sinfo) != GST_VIDEO_INFO_FORMAT (vinfo)) + goto bail; - gst_vaapi_image_unmap (image); - - if (has_direct_rendering && !has_direct_uploading) { + if (use_direct_rendering (req_usage_flag) + && !use_direct_uploading (req_usage_flag)) { allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; GST_INFO_OBJECT (allocator, "has direct-rendering for %s surfaces", - GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info)); - } else if (!has_direct_rendering && has_direct_uploading) { + GST_VIDEO_INFO_FORMAT_STRING (sinfo)); + } else if (!use_direct_rendering (req_usage_flag) + && use_direct_uploading (req_usage_flag)) { allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD; GST_INFO_OBJECT (allocator, "has direct-uploading for %s surfaces", - GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info)); + GST_VIDEO_INFO_FORMAT_STRING (sinfo)); } bail: - if (image) - gst_vaapi_object_unref (image); if (surface) gst_vaapi_object_unref (surface); return; @@ -774,16 +800,6 @@ error_no_surface: GST_ERROR ("Cannot create a VA Surface"); return; } -error_no_derive_image: - { - GST_ERROR ("Cannot create a derived image from surface %p", surface); - goto bail; - } -error_cannot_map: - { - GST_ERROR ("Cannot map VA derived image %p", image); - goto bail; - } } static inline void @@ -1026,59 +1042,47 @@ gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, { GstVaapiDmaBufAllocator *allocator = NULL; GstVaapiSurface *surface = NULL; - GstVaapiImage *image = NULL; GstVideoInfo alloc_info; + GstAllocator *base_allocator; g_return_val_if_fail (display != NULL, NULL); g_return_val_if_fail (vip != NULL, NULL); - surface = gst_vaapi_surface_new_full (display, vip, flags); - if (!surface) - goto error_no_surface; - - image = gst_vaapi_surface_derive_image (surface); - if (!image) - goto error_no_image; - if (!gst_vaapi_image_map (image)) - goto error_map_failed; - - gst_video_info_set_format (&alloc_info, GST_VIDEO_INFO_FORMAT (vip), - GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); - gst_video_info_update_from_image (&alloc_info, image); - gst_vaapi_image_unmap (image); - allocator = g_object_new (GST_VAAPI_TYPE_DMABUF_ALLOCATOR, NULL); if (!allocator) goto error_no_allocator; - gst_allocator_set_vaapi_video_info (GST_ALLOCATOR_CAST (allocator), - &alloc_info, flags); -bail: - gst_vaapi_object_replace (&image, NULL); + base_allocator = GST_ALLOCATOR_CAST (allocator); + + gst_video_info_set_format (&alloc_info, GST_VIDEO_INFO_FORMAT (vip), + GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); + surface = gst_vaapi_surface_new_full (display, vip, flags); + if (!surface) + goto error_no_surface; + if (!gst_video_info_update_from_surface (&alloc_info, surface)) + goto fail; gst_vaapi_object_replace (&surface, NULL); - return GST_ALLOCATOR_CAST (allocator); + + gst_allocator_set_vaapi_video_info (base_allocator, &alloc_info, flags); + + return base_allocator; /* ERRORS */ -error_no_surface: +fail: { - GST_ERROR ("failed to create a new surface"); - goto bail; - } -error_no_image: - { - GST_ERROR ("failed derive surface to image for format: %s", - GST_VIDEO_INFO_FORMAT_STRING (vip)); - goto bail; - } -error_map_failed: - { - GST_ERROR ("failed to map image"); - goto bail; + gst_vaapi_object_replace (&surface, NULL); + gst_object_replace ((GstObject **) & base_allocator, NULL); + return NULL; } error_no_allocator: { GST_ERROR ("failed to create a new dmabuf allocator"); - goto bail; + return NULL; + } +error_no_surface: + { + GST_ERROR ("failed to create a new surface"); + goto fail; } } From dde4db3b3e9c383936eb3e33041c3ebe9de13dcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 9 Dec 2016 14:51:52 +0100 Subject: [PATCH 2637/3781] libs: surface: fix error handling code style --- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index 73df5af0dd..8c0f8f93b2 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -45,12 +45,16 @@ gst_vaapi_surface_get_drm_buf_handle (GstVaapiSurface * surface, guint type) /* ERRORS */ error_derive_image: - GST_ERROR ("failed to extract image handle from surface"); - return NULL; + { + GST_ERROR ("failed to extract image handle from surface"); + return NULL; + } error_alloc_export_buffer: - GST_ERROR ("failed to allocate export buffer proxy"); - gst_vaapi_object_unref (image); - return NULL; + { + GST_ERROR ("failed to allocate export buffer proxy"); + gst_vaapi_object_unref (image); + return NULL; + } } /** From 5e09f57deaceaf0ce8ae9a3211571c88457f53f6 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 21 Dec 2016 17:50:41 +0900 Subject: [PATCH 2638/3781] vaapisink: ensures raw caps at start() Calls gst_vaapi_plugin_base_get_allowed_raw_caps() at start() to avoid race conditions at get_caps(), especially with multiple src elements. https://bugzilla.gnome.org/show_bug.cgi?id=776303 --- gst/vaapi/gstvaapisink.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 58e194a7e8..7c8caff647 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1214,7 +1214,18 @@ gst_vaapisink_display_changed (GstVaapiPluginBase * plugin) static gboolean gst_vaapisink_start (GstBaseSink * base_sink) { - return gst_vaapisink_ensure_display (GST_VAAPISINK_CAST (base_sink)); + GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (base_sink); + + if (!gst_vaapisink_ensure_display (sink)) + return FALSE; + + /* Ensures possible raw caps earlier to avoid race conditions at + * get_caps() */ + if (!gst_vaapi_plugin_base_get_allowed_raw_caps (plugin)) + return FALSE; + + return TRUE; } static gboolean From a66c2d44bfca52292d912bb44ff7cb1fb44f9512 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 21 Dec 2016 17:38:07 +0900 Subject: [PATCH 2639/3781] vaapivideomemory: fail surface/image configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To detect and handle errors during allocator_configure_surface_info() and allocator_conigure_image_info(). https://bugzilla.gnome.org/show_bug.cgi?id=776084 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapivideomemory.c | 34 +++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 7196e29144..2ad0127e34 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -745,7 +745,7 @@ error_cannot_map: } } -static inline void +static inline gboolean allocator_configure_surface_info (GstVaapiDisplay * display, GstVaapiVideoAllocator * allocator, GstVaapiImageUsageFlags req_usage_flag) { @@ -758,13 +758,16 @@ allocator_configure_surface_info (GstVaapiDisplay * display, allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; fmt = gst_vaapi_video_format_get_best_native (GST_VIDEO_INFO_FORMAT (vinfo)); + if (fmt == GST_VIDEO_FORMAT_UNKNOWN) + goto error_invalid_format; + gst_video_info_set_format (&allocator->surface_info, fmt, GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); /* nothing to configure */ if (use_native_formats (req_usage_flag) || GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) - return; + return TRUE; surface = new_surface (display, vinfo, req_usage_flag); if (!surface) @@ -793,25 +796,33 @@ allocator_configure_surface_info (GstVaapiDisplay * display, bail: if (surface) gst_vaapi_object_unref (surface); - return; + return TRUE; + /* ERRORS */ +error_invalid_format: + { + GST_ERROR ("Cannot handle format %s", + gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (vinfo))); + return FALSE; + } error_no_surface: { GST_ERROR ("Cannot create a VA Surface"); - return; + return FALSE; } } -static inline void +static inline gboolean allocator_configure_image_info (GstVaapiDisplay * display, GstVaapiVideoAllocator * allocator) { GstVaapiImage *image = NULL; const GstVideoInfo *vinfo; + gboolean ret = FALSE; if (!use_native_formats (allocator->usage_flag)) { allocator->image_info = allocator->surface_info; - return; + return TRUE; } vinfo = &allocator->allocation_info; @@ -826,17 +837,18 @@ allocator_configure_image_info (GstVaapiDisplay * display, gst_video_info_update_from_image (&allocator->image_info, image); gst_vaapi_image_unmap (image); + ret = TRUE; bail: if (image) gst_vaapi_object_unref (image); - return; + return ret; /* ERRORS */ error_no_image: { GST_ERROR ("Cannot create VA image"); - return; + return ret; } error_cannot_map: { @@ -852,13 +864,15 @@ allocator_params_init (GstVaapiVideoAllocator * allocator, { allocator->allocation_info = *vip; - allocator_configure_surface_info (display, allocator, req_usage_flag); + if (!allocator_configure_surface_info (display, allocator, req_usage_flag)) + return FALSE; allocator->surface_pool = gst_vaapi_surface_pool_new_full (display, &allocator->surface_info, surface_alloc_flags); if (!allocator->surface_pool) goto error_create_surface_pool; - allocator_configure_image_info (display, allocator); + if (!allocator_configure_image_info (display, allocator)) + return FALSE; allocator->image_pool = gst_vaapi_image_pool_new (display, &allocator->image_info); if (!allocator->image_pool) From a36b9b27e5b9971701ea39f54256af2c51ee35fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 14 Dec 2016 15:51:01 +0100 Subject: [PATCH 2640/3781] vaapidecodebin: capsfilter to optimize negotiation Add a capsfilter forcing the caps "video/x-raw(memory:VASurface), format=(string)NV12" between the queue and the vaapipostproc so no renegotiation is required. https://bugzilla.gnome.org/show_bug.cgi?id=776175 --- gst/vaapi/gstvaapidecodebin.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index e7db8fc58e..9fc2bd4a2f 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -292,7 +292,9 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) static gboolean gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) { - GstPad *queue_srcpad, *bin_srcpad, *vpp_sinkpad, *vpp_srcpad; + GstElement *capsfilter; + GstCaps *caps; + GstPad *queue_srcpad, *bin_srcpad, *capsfilter_sinkpad, *vpp_srcpad; gboolean res; g_object_set (G_OBJECT (vaapidecbin->queue), @@ -305,6 +307,15 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) GST_INFO_OBJECT (vaapidecbin, "enabling VPP"); + /* capsfilter to avoid negotiation with vaapidecode */ + caps = gst_caps_from_string + ("video/x-raw(memory:VASurface), format=(string)NV12"); + if (!caps) + goto error_cannot_set_caps; + capsfilter = gst_element_factory_make ("capsfilter", NULL); + g_object_set (capsfilter, "caps", caps, NULL); + gst_caps_unref (caps); + /* create the postproc */ vaapidecbin->postproc = gst_element_factory_make ("vaapipostproc", NULL); if (!vaapidecbin->postproc) @@ -312,7 +323,14 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) g_object_set (G_OBJECT (vaapidecbin->postproc), "deinterlace-method", vaapidecbin->deinterlace_method, NULL); - gst_bin_add (GST_BIN (vaapidecbin), vaapidecbin->postproc); + gst_bin_add_many (GST_BIN (vaapidecbin), capsfilter, vaapidecbin->postproc, + NULL); + + if (!gst_element_link (capsfilter, vaapidecbin->postproc)) + goto error_sync_state; + + if (!gst_element_sync_state_with_parent (capsfilter)) + goto error_sync_state; if (!gst_element_sync_state_with_parent (vaapidecbin->postproc)) goto error_sync_state; @@ -324,9 +342,9 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) /* link decoder and queue */ queue_srcpad = gst_element_get_static_pad (vaapidecbin->queue, "src"); - vpp_sinkpad = gst_element_get_static_pad (vaapidecbin->postproc, "sink"); - res = (gst_pad_link (queue_srcpad, vpp_sinkpad) == GST_PAD_LINK_OK); - gst_object_unref (vpp_sinkpad); + capsfilter_sinkpad = gst_element_get_static_pad (capsfilter, "sink"); + res = (gst_pad_link (queue_srcpad, capsfilter_sinkpad) == GST_PAD_LINK_OK); + gst_object_unref (capsfilter_sinkpad); gst_object_unref (queue_srcpad); if (!res) goto error_link_pad; @@ -342,6 +360,13 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) return TRUE; + /* ERRORS */ +error_cannot_set_caps: + { + GST_ELEMENT_ERROR (vaapidecbin, CORE, PAD, + ("Failed to configure caps for VA Surfaces."), (NULL)); + return FALSE; + } error_vpp_missing: { post_missing_element_message (vaapidecbin, "vaapipostproc"); From b23640fb2715c215c739a624a9201420d47004d4 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 4 Jan 2017 19:23:06 +0900 Subject: [PATCH 2641/3781] vaapipostproc: notify if src pad caps changed If src pad caps have changed, it needs to notify it downstream. In addition, do not set passthrough if they have changed. Otherwise, transform sometimes starts processing before caps change. The passthrough value will be set in fixate later in this case. https://bugzilla.gnome.org/show_bug.cgi?id=775204 --- gst/vaapi/gstvaapipostproc.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 556cb51509..e2afea8c8d 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1273,12 +1273,13 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, GstCaps * out_caps) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - gboolean caps_changed = FALSE; + gboolean sink_caps_changed = FALSE; + gboolean src_caps_changed = FALSE; GstVideoInfo vinfo; gboolean ret = FALSE; g_mutex_lock (&postproc->postproc_lock); - if (!gst_vaapipostproc_update_sink_caps (postproc, caps, &caps_changed)) + if (!gst_vaapipostproc_update_sink_caps (postproc, caps, &sink_caps_changed)) goto done; /* HACK: This is a workaround to deal with the va-intel-driver for non-native * formats while doing advanced deinterlacing. The format of reference surfaces must @@ -1292,10 +1293,11 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, "Advanced deinterlacing requires the native video formats used by the driver internally"); goto done; } - if (!gst_vaapipostproc_update_src_caps (postproc, out_caps, &caps_changed)) + if (!gst_vaapipostproc_update_src_caps (postproc, out_caps, + &src_caps_changed)) goto done; - if (caps_changed) { + if (sink_caps_changed || src_caps_changed) { gst_vaapipostproc_destroy (postproc); if (!gst_vaapipostproc_create (postproc)) goto done; @@ -1309,13 +1311,20 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, postproc->same_caps = gst_caps_is_equal (caps, out_caps); - /* set passthrough according to caps changes or filter changes */ - gst_vaapipostproc_set_passthrough (trans); + if (!src_caps_changed) { + /* set passthrough according to caps changes or filter changes */ + gst_vaapipostproc_set_passthrough (trans); + } ret = TRUE; done: g_mutex_unlock (&postproc->postproc_lock); + + /* Updates the srcpad caps and send the caps downstream */ + if (ret && src_caps_changed) + gst_base_transform_update_src_caps (trans, out_caps); + return ret; } From 7ced30dbac4dbf578b4a7e32a8120c3dab4ad8e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 9 Jan 2017 12:51:11 +0100 Subject: [PATCH 2642/3781] vaapivideomemory: unroll gst_vaapi_surface_new_with_format() gst_vaapi_surface_new_with_format() is a wrapper for gst_vaapi_surface_new_full (). In this case, the former is simpler than the first. This patch changes that. --- gst/vaapi/gstvaapivideomemory.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 2ad0127e34..fa14ba7c4a 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -172,9 +172,7 @@ new_surface (GstVaapiDisplay * display, const GstVideoInfo * vip, /* Try with explicit format first */ if (!use_native_formats (usage_flag) && GST_VIDEO_INFO_FORMAT (vip) != GST_VIDEO_FORMAT_ENCODED) { - surface = gst_vaapi_surface_new_with_format (display, - GST_VIDEO_INFO_FORMAT (vip), GST_VIDEO_INFO_WIDTH (vip), - GST_VIDEO_INFO_HEIGHT (vip)); + surface = gst_vaapi_surface_new_full (display, vip, 0); if (surface) return surface; } From d3d489a855f56e5a39b6f8265e1c8e7b1bfa49e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 9 Jan 2017 16:08:17 +0100 Subject: [PATCH 2643/3781] vaapivideomemory: use GST_VIDEO_INFO_FORMAT_STRING() Use the existing local macro GST_VIDEO_INFO_FORMAT_STRING() to get the video format string. --- gst/vaapi/gstvaapivideomemory.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index fa14ba7c4a..4695570987 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -799,8 +799,7 @@ bail: /* ERRORS */ error_invalid_format: { - GST_ERROR ("Cannot handle format %s", - gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (vinfo))); + GST_ERROR ("Cannot handle format %s", GST_VIDEO_INFO_FORMAT_STRING (vinfo)); return FALSE; } error_no_surface: @@ -997,8 +996,8 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, error_create_surface: { GST_ERROR ("failed to create VA surface (format:%s size:%ux%u)", - gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)), - GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); + GST_VIDEO_INFO_FORMAT_STRING (vip), GST_VIDEO_INFO_WIDTH (vip), + GST_VIDEO_INFO_HEIGHT (vip)); return NULL; } error_create_surface_proxy: From 2534dab8d83d7c9baf69fcd2c62e41fd3f963498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 9 Jan 2017 16:18:32 +0100 Subject: [PATCH 2644/3781] vaapivideomemory: rename vip to alloc_info parameter In order to auto-document the code, this patch renames the 'vip' parameter in the functions related to gst_vaapi_video_allocator_new () to 'alloc_info', since it declares the allocation video info from the vaapi buffer pool. --- gst/vaapi/gstvaapivideomemory.c | 12 ++++++------ gst/vaapi/gstvaapivideomemory.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 4695570987..447b99f359 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -856,10 +856,10 @@ error_cannot_map: static inline gboolean allocator_params_init (GstVaapiVideoAllocator * allocator, - GstVaapiDisplay * display, const GstVideoInfo * vip, + GstVaapiDisplay * display, const GstVideoInfo * alloc_info, guint surface_alloc_flags, GstVaapiImageUsageFlags req_usage_flag) { - allocator->allocation_info = *vip; + allocator->allocation_info = *alloc_info; if (!allocator_configure_surface_info (display, allocator, req_usage_flag)) return FALSE; @@ -895,20 +895,20 @@ error_create_image_pool: GstAllocator * gst_vaapi_video_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint surface_alloc_flags, + const GstVideoInfo * alloc_info, guint surface_alloc_flags, GstVaapiImageUsageFlags req_usage_flag) { GstVaapiVideoAllocator *allocator; g_return_val_if_fail (display != NULL, NULL); - g_return_val_if_fail (vip != NULL, NULL); + g_return_val_if_fail (alloc_info != NULL, NULL); allocator = g_object_new (GST_VAAPI_TYPE_VIDEO_ALLOCATOR, NULL); if (!allocator) return NULL; - if (!allocator_params_init (allocator, display, vip, surface_alloc_flags, - req_usage_flag)) { + if (!allocator_params_init (allocator, display, alloc_info, + surface_alloc_flags, req_usage_flag)) { g_object_unref (allocator); return NULL; } diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 761ad1ce58..8c6c7f5883 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -206,7 +206,7 @@ gst_vaapi_video_allocator_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstAllocator * gst_vaapi_video_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint surface_alloc_flags, + const GstVideoInfo * alloc_info, guint surface_alloc_flags, GstVaapiImageUsageFlags req_usage_flag); /* ------------------------------------------------------------------------ */ From eb1d3965364563528c162643c0b6c9a551f6fe8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 9 Jan 2017 16:23:56 +0100 Subject: [PATCH 2645/3781] vaapivideomemory: rename dmabuf allocator parameters Rename the parameters 'vip' and 'flags' to 'alloc_info' and 'surface_alloc_flags' respectively. The purpose of this change is to auto-document those parameters. Also, aligned to this patch, the local 'alloc_info' variable was renamed as 'surface_info', because it stores the possible surface's video info, not the allocate one. --- gst/vaapi/gstvaapivideomemory.c | 35 +++++++++++++++++++-------------- gst/vaapi/gstvaapivideomemory.h | 2 +- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 447b99f359..3bab3cb62a 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -943,23 +943,25 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, GstVaapiSurfaceProxy *proxy; GstVaapiBufferProxy *dmabuf_proxy; gint dmabuf_fd; - const GstVideoInfo *vip; - guint flags; + const GstVideoInfo *surface_info; + guint surface_alloc_flags; GstVaapiDmaBufAllocator *const allocator = GST_VAAPI_DMABUF_ALLOCATOR_CAST (base_allocator); g_return_val_if_fail (allocator != NULL, NULL); g_return_val_if_fail (meta != NULL, NULL); - vip = gst_allocator_get_vaapi_video_info (base_allocator, &flags); - if (!vip) + surface_info = gst_allocator_get_vaapi_video_info (base_allocator, + &surface_alloc_flags); + if (!surface_info) return NULL; display = gst_vaapi_video_meta_get_display (meta); if (!meta) return NULL; - surface = gst_vaapi_surface_new_full (display, vip, flags); + surface = gst_vaapi_surface_new_full (display, surface_info, + surface_alloc_flags); if (!surface) goto error_create_surface; @@ -996,8 +998,9 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, error_create_surface: { GST_ERROR ("failed to create VA surface (format:%s size:%ux%u)", - GST_VIDEO_INFO_FORMAT_STRING (vip), GST_VIDEO_INFO_WIDTH (vip), - GST_VIDEO_INFO_HEIGHT (vip)); + GST_VIDEO_INFO_FORMAT_STRING (surface_info), + GST_VIDEO_INFO_WIDTH (surface_info), + GST_VIDEO_INFO_HEIGHT (surface_info)); return NULL; } error_create_surface_proxy: @@ -1049,15 +1052,15 @@ gst_vaapi_dmabuf_allocator_init (GstVaapiDmaBufAllocator * allocator) GstAllocator * gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint flags) + const GstVideoInfo * alloc_info, guint surface_alloc_flags) { GstVaapiDmaBufAllocator *allocator = NULL; GstVaapiSurface *surface = NULL; - GstVideoInfo alloc_info; + GstVideoInfo surface_info; GstAllocator *base_allocator; g_return_val_if_fail (display != NULL, NULL); - g_return_val_if_fail (vip != NULL, NULL); + g_return_val_if_fail (alloc_info != NULL, NULL); allocator = g_object_new (GST_VAAPI_TYPE_DMABUF_ALLOCATOR, NULL); if (!allocator) @@ -1065,16 +1068,18 @@ gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, base_allocator = GST_ALLOCATOR_CAST (allocator); - gst_video_info_set_format (&alloc_info, GST_VIDEO_INFO_FORMAT (vip), - GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); - surface = gst_vaapi_surface_new_full (display, vip, flags); + gst_video_info_set_format (&surface_info, GST_VIDEO_INFO_FORMAT (alloc_info), + GST_VIDEO_INFO_WIDTH (alloc_info), GST_VIDEO_INFO_HEIGHT (alloc_info)); + surface = gst_vaapi_surface_new_full (display, alloc_info, + surface_alloc_flags); if (!surface) goto error_no_surface; - if (!gst_video_info_update_from_surface (&alloc_info, surface)) + if (!gst_video_info_update_from_surface (&surface_info, surface)) goto fail; gst_vaapi_object_replace (&surface, NULL); - gst_allocator_set_vaapi_video_info (base_allocator, &alloc_info, flags); + gst_allocator_set_vaapi_video_info (base_allocator, &surface_info, + surface_alloc_flags); return base_allocator; diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 8c6c7f5883..c95ff3221a 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -262,7 +262,7 @@ gst_vaapi_dmabuf_allocator_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstAllocator * gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint flags); + const GstVideoInfo * alloc_info, guint surface_alloc_flags); G_GNUC_INTERNAL const GstVideoInfo * From a1f7b5573dd98d5132286941d3985b71704b685b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 9 Jan 2017 19:25:24 +0100 Subject: [PATCH 2646/3781] vaapivideomemory: check for display This patch fixes the check of display, rather than check for the meta, which it is known it exists. --- gst/vaapi/gstvaapivideomemory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 3bab3cb62a..9945b4b547 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -957,7 +957,7 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, return NULL; display = gst_vaapi_video_meta_get_display (meta); - if (!meta) + if (!display) return NULL; surface = gst_vaapi_surface_new_full (display, surface_info, From 58e7b575bbcaac8a9b1d442087ccf0dcb34313d5 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 10 Jan 2017 13:49:27 +0900 Subject: [PATCH 2647/3781] libs: decoder: h264: don't update cloned attributes If the frame is a cloned picture, its PTS comes from its parent picture. In addition, the base decoder doesn't set a valid PTS to the frame corresponding to the cloned picture. https://bugzilla.gnome.org/show_bug.cgi?id=774254 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 4c6dc03675..7b5b2a348c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -3258,10 +3258,17 @@ init_picture (GstVaapiDecoderH264 * decoder, picture->frame_num = priv->frame_num; picture->frame_num_wrap = priv->frame_num; picture->output_flag = TRUE; /* XXX: conformant to Annex A only */ - base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts; - base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE; - base_picture->view_id = pi->view_id; - base_picture->voc = pi->voc; + + /* If it's a cloned picture, it has some assignments from parent + * picture already. In addition, base decoder doesn't set valid pts + * to the frame corresponding to cloned picture. + */ + if (G_LIKELY (!base_picture->parent_picture)) { + base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts; + base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE; + base_picture->view_id = pi->view_id; + base_picture->voc = pi->voc; + } /* Initialize extensions */ switch (pi->nalu.extension_type) { From bca2b1680bf07a1f7c593eb3aa1b04a354c47e6f Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 10 Jan 2017 15:15:31 +0900 Subject: [PATCH 2648/3781] plugins: provide at least two buffers in sink pool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds two buffers as the default value of minimum buffer. This would be used when creating and proposing vaapi bufferpool for sink pad, hence the upstream element will keep, at least, these two buffers. https://bugzilla.gnome.org/show_bug.cgi?id=775203 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapipluginbase.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 2aa3b867f2..7e7a4438e4 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -34,6 +34,8 @@ /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) +#define BUFFER_POOL_SINK_MIN_BUFFERS 2 + /* GstVideoContext interface */ static void plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) @@ -714,7 +716,9 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) if (!ensure_sinkpad_allocator (plugin, caps, &size)) return FALSE; - pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, 0, 0, + pool = + gst_vaapi_plugin_base_create_pool (plugin, caps, size, + BUFFER_POOL_SINK_MIN_BUFFERS, 0, GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, plugin->sinkpad_allocator); if (!pool) return FALSE; @@ -789,7 +793,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, if (!ensure_sinkpad_buffer_pool (plugin, caps)) return FALSE; gst_query_add_allocation_pool (query, plugin->sinkpad_buffer_pool, - plugin->sinkpad_buffer_size, 0, 0); + plugin->sinkpad_buffer_size, BUFFER_POOL_SINK_MIN_BUFFERS, 0); gst_query_add_allocation_param (query, plugin->sinkpad_allocator, NULL); } From 1e0b3c2f74788d562b024733d0d467ca0666a39f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 11 Jan 2017 16:04:24 +0100 Subject: [PATCH 2649/3781] libs: display: redirect logging at initialize Redirect libva's logs to GStreamer logging mechanism. This is particularly useful when VA is initialized, because it always logs out the drivers details. In order to achieve this a new helper function was added as a wrapper for the vaInitialize() function. https://bugzilla.gnome.org/show_bug.cgi?id=777115 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 6 +---- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 3 +-- gst-libs/gst/vaapi/gstvaapiutils.c | 33 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 5 ++++ 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 01b7d3aeb7..0597003d8e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -900,8 +900,6 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); const GstVaapiDisplayClass *const klass = GST_VAAPI_DISPLAY_GET_CLASS (display); - gint major_version, minor_version; - VAStatus status; GstVaapiDisplayInfo info; const GstVaapiDisplayInfo *cached_info = NULL; @@ -947,10 +945,8 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, } if (!priv->parent) { - status = vaInitialize (priv->display, &major_version, &minor_version); - if (!vaapi_check_status (status, "vaInitialize()")) + if (!vaapi_initialize (priv->display)) return FALSE; - GST_DEBUG ("VA-API version %d.%d", major_version, minor_version); } if (!cached_info) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 1150f75376..f4360366b9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -63,13 +63,12 @@ supports_vaapi (int fd) { gboolean ret; VADisplay va_dpy; - int major, minor; va_dpy = vaGetDisplayDRM (fd); if (!va_dpy) return FALSE; - ret = (vaInitialize (va_dpy, &major, &minor) == VA_STATUS_SUCCESS); + ret = vaapi_initialize (va_dpy); vaTerminate (va_dpy); return ret; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index fbe17a3009..1070630280 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -45,6 +45,39 @@ #define STRCASEP(p, x) STRCASE(CONCAT(p, x)) #define STRCASE(x) case x: return STRINGIFY(x) +#if VA_CHECK_VERSION (0,39,4) +static void +gst_vaapi_log (const char *message) +{ + gchar *msg; + + msg = g_strdup (message); + if (!msg) + return; + g_strchomp (msg); + GST_INFO ("%s", msg); + g_free (msg); +} +#endif + +gboolean +vaapi_initialize (VADisplay dpy) +{ + gint major_version, minor_version; + VAStatus status; + +#if VA_CHECK_VERSION (0,39,4) + vaSetInfoCallback (gst_vaapi_log); +#endif + + status = vaInitialize (dpy, &major_version, &minor_version); + if (!vaapi_check_status (status, "vaInitialize()")) + return FALSE; + + GST_INFO ("VA-API version %d.%d", major_version, minor_version); + return TRUE; +} + /* Check VA status for success or print out an error */ gboolean vaapi_check_status (VAStatus status, const gchar * msg) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 979a9ed785..b4ee99e619 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -30,6 +30,11 @@ #include #include +/** calls vaInitialize() redirecting the logging mechanism */ +G_GNUC_INTERNAL +gboolean +vaapi_initialize (VADisplay dpy); + /** Check VA status for success or print out an error */ G_GNUC_INTERNAL gboolean From 08dea01bf49c8159ce2fec8290bcc1c018105075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 12 Jan 2017 13:45:29 +0200 Subject: [PATCH 2650/3781] vaapiutils: Fix compilation with latest and previous libva releases vaSetInfoCallback() was defined after 0.39.4 / 1.7.3, so check for 0.39.5 instead. --- gst-libs/gst/vaapi/gstvaapiutils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 1070630280..9e93b37abb 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -45,7 +45,7 @@ #define STRCASEP(p, x) STRCASE(CONCAT(p, x)) #define STRCASE(x) case x: return STRINGIFY(x) -#if VA_CHECK_VERSION (0,39,4) +#if VA_CHECK_VERSION (0,39,5) static void gst_vaapi_log (const char *message) { @@ -66,7 +66,7 @@ vaapi_initialize (VADisplay dpy) gint major_version, minor_version; VAStatus status; -#if VA_CHECK_VERSION (0,39,4) +#if VA_CHECK_VERSION (0,39,5) vaSetInfoCallback (gst_vaapi_log); #endif From da7500de3fb8ec4ae0f07ad57b8150d76b807aea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 12 Jan 2017 12:49:55 +0100 Subject: [PATCH 2651/3781] vaapi: bump ifdef to API 0.40.0 for log redirect vaSetInfoCallback() is not released yet. It is going to appear in VA-API 0.40.0 --- gst-libs/gst/vaapi/gstvaapiutils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 9e93b37abb..df17044c52 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -45,7 +45,7 @@ #define STRCASEP(p, x) STRCASE(CONCAT(p, x)) #define STRCASE(x) case x: return STRINGIFY(x) -#if VA_CHECK_VERSION (0,39,5) +#if VA_CHECK_VERSION (0,40,0) static void gst_vaapi_log (const char *message) { @@ -66,7 +66,7 @@ vaapi_initialize (VADisplay dpy) gint major_version, minor_version; VAStatus status; -#if VA_CHECK_VERSION (0,39,5) +#if VA_CHECK_VERSION (0,40,0) vaSetInfoCallback (gst_vaapi_log); #endif From 0fbcc0597011c48e9445fa4f26f1f7663b60214d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 12 Jan 2017 16:27:12 +0200 Subject: [PATCH 2652/3781] Release 1.11.1 --- ChangeLog | 942 ++++++++++++++++++++++++++++++++++- NEWS | 1115 +----------------------------------------- configure.ac | 14 +- gstreamer-vaapi.doap | 10 + 4 files changed, 957 insertions(+), 1124 deletions(-) diff --git a/ChangeLog b/ChangeLog index 77ac03f954..cbf0e5d2d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,945 @@ -=== release 1.10.0 === +=== release 1.11.1 === -2016-11-01 Sebastian Dröge +2017-01-12 Sebastian Dröge * configure.ac: - releasing 1.10.0 + releasing 1.11.1 + +2017-01-12 12:49:55 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils.c: + vaapi: bump ifdef to API 0.40.0 for log redirect + vaSetInfoCallback() is not released yet. It is going to appear in + VA-API 0.40.0 + +2017-01-12 13:45:29 +0200 Sebastian Dröge + + * gst-libs/gst/vaapi/gstvaapiutils.c: + vaapiutils: Fix compilation with latest and previous libva releases + vaSetInfoCallback() was defined after 0.39.4 / 1.7.3, so check for + 0.39.5 instead. + +2017-01-11 16:04:24 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + libs: display: redirect logging at initialize + Redirect libva's logs to GStreamer logging mechanism. This is + particularly useful when VA is initialized, because it always logs + out the drivers details. + In order to achieve this a new helper function was added as a wrapper + for the vaInitialize() function. + https://bugzilla.gnome.org/show_bug.cgi?id=777115 + +2017-01-10 15:15:31 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipluginbase.c: + plugins: provide at least two buffers in sink pool + Adds two buffers as the default value of minimum buffer. + This would be used when creating and proposing vaapi bufferpool for + sink pad, hence the upstream element will keep, at least, these two + buffers. + https://bugzilla.gnome.org/show_bug.cgi?id=775203 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-01-10 13:49:27 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: don't update cloned attributes + If the frame is a cloned picture, its PTS comes from its parent + picture. In addition, the base decoder doesn't set a valid PTS to + the frame corresponding to the cloned picture. + https://bugzilla.gnome.org/show_bug.cgi?id=774254 + +2017-01-09 19:25:24 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: check for display + This patch fixes the check of display, rather than check for the + meta, which it is known it exists. + +2017-01-09 16:23:56 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: rename dmabuf allocator parameters + Rename the parameters 'vip' and 'flags' to 'alloc_info' and + 'surface_alloc_flags' respectively. The purpose of this change is + to auto-document those parameters. + Also, aligned to this patch, the local 'alloc_info' variable was + renamed as 'surface_info', because it stores the possible surface's + video info, not the allocate one. + +2017-01-09 16:18:32 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: rename vip to alloc_info parameter + In order to auto-document the code, this patch renames the 'vip' + parameter in the functions related to gst_vaapi_video_allocator_new () + to 'alloc_info', since it declares the allocation video info from + the vaapi buffer pool. + +2017-01-09 16:08:17 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: use GST_VIDEO_INFO_FORMAT_STRING() + Use the existing local macro GST_VIDEO_INFO_FORMAT_STRING() to get + the video format string. + +2017-01-09 12:51:11 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: unroll gst_vaapi_surface_new_with_format() + gst_vaapi_surface_new_with_format() is a wrapper for + gst_vaapi_surface_new_full (). In this case, the former is simpler + than the first. This patch changes that. + +2017-01-04 19:23:06 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: notify if src pad caps changed + If src pad caps have changed, it needs to notify it downstream. In + addition, do not set passthrough if they have changed. + Otherwise, transform sometimes starts processing before caps change. + The passthrough value will be set in fixate later in this case. + https://bugzilla.gnome.org/show_bug.cgi?id=775204 + +2016-12-14 15:51:01 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: capsfilter to optimize negotiation + Add a capsfilter forcing the caps + "video/x-raw(memory:VASurface), format=(string)NV12" between the + queue and the vaapipostproc so no renegotiation is required. + https://bugzilla.gnome.org/show_bug.cgi?id=776175 + +2016-12-21 17:38:07 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: fail surface/image configuration + To detect and handle errors during allocator_configure_surface_info() + and allocator_conigure_image_info(). + https://bugzilla.gnome.org/show_bug.cgi?id=776084 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-12-21 17:50:41 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapisink.c: + vaapisink: ensures raw caps at start() + Calls gst_vaapi_plugin_base_get_allowed_raw_caps() at start() to avoid + race conditions at get_caps(), especially with multiple src elements. + https://bugzilla.gnome.org/show_bug.cgi?id=776303 + +2016-12-09 14:51:52 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + libs: surface: fix error handling code style + +2016-12-09 16:14:14 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: add gst_video_info_update_from_surface() + With this function is possible to refactor and remove duplicated code + between dmabuf configuration and direct rendering/uploading + configuration. + +2016-12-09 15:51:32 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: no log object at initialization + When an instance of GstVaapiVideoAllocator fails at initializing, the + log message should not include the allocator's object, because it is + going to be unrefed. + +2016-12-09 17:56:02 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: lock stream when setting caps + +2016-12-09 17:42:42 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + Revert "vaapidecode: implement negotiate() vmethod" + This reverts commit 3285121181295c544480fc6ba756845b16285d30. + videodecode's negotiate() vmethod is also called when events arrive, + but this would mean that the proper configuration of sink pad might + not be complete, thus we should not update the src pad. + Let's keep the old non-vmethod negotitate(). + +2016-12-07 16:52:35 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + Revert "encoders: demote to RANK_NONE since not fit for autoplugging yet" + This reverts commit f182b8be2ba05965e6d31a4d380d6563b9b53a77. + +2016-12-01 18:57:10 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + vaapiencode: get surface formats in get_caps() + Query for the supported surface formats in config at get_caps() vmethod. + https://bugzilla.gnome.org/show_bug.cgi?id=769266 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-12-07 11:26:37 +0100 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + libs: encoder: add gst_vaapi_encoder_get_surface_formats() + This method will return the valid surface formats in the current + config. If the are no VAConfig it is created with the information + available. + https://bugzilla.gnome.org/show_bug.cgi?id=769266 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-12-07 11:10:42 +0100 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: split set_context_info() + Split set_context_info() adding init_context_info() which only + initialises the GstVaapiContextInfo structure inside GstVaapiEncoder + required for VAConfig. + https://bugzilla.gnome.org/show_bug.cgi?id=769266 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-12-02 09:30:52 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapicontext.c: + libs: context: skip VAContext if no frame size + If GstVaapiContextInfo has just initial information, without frame's + width and height, skip the creation of the VAContext, just keep the + VAConfig. + https://bugzilla.gnome.org/show_bug.cgi?id=769266 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-12-02 09:28:07 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapicontext.c: + libs: context: split context_create() + Split the funcion context_create() into context_create() and + config_create(). + Decoupling VAConfig and VAContext during context creation, we could + query the VAConfig for the supported surface's formats without creating + a VAContext. + https://bugzilla.gnome.org/show_bug.cgi?id=769266 + +2016-12-06 17:33:42 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + libs: drm: find render node in hybrid system + Originally the drm backend only tried to open the first render node + found. But in hybrid system this first render node might not support + VA-API (propietary Nvidia driver, for example). + This patch tries all the available nodes until a finding one with a + VA-API supported driver. + https://bugzilla.gnome.org/show_bug.cgi?id=774811 + Original-patch-by: Stirling Westrup and + Reza Razavi + +2016-11-14 17:45:55 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: refactor code for readability + Added the inlined function allocator_configure_pools() moving out code + from gst_vaapi_video_allocator_new() to make clear that it is a + post-initalization of the object. + +2016-11-14 17:40:37 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: log error if not VA image + Log an error message if the test image for surface downloading + cannot be allocated or mapped. + +2016-11-14 17:33:41 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: remove unused macros + These macros are not used. Let us remove them. + +2016-11-11 19:45:45 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: rename video for allocation_info + Since video_info stores the GstVideoInfo of the allocation caps, + it is clear if we rename it as allocation_info, to distinguish it + later from negotiation_info. + +2016-10-19 15:27:03 +0100 Julien Isorce + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: add real GstVaapiDmaBufAllocator + Instead of defining GstVaapiDmaBufAllocator as a hackish decorator of + GstDmaBufAllocator, now, since the expose of the GstDmaBufAllocator's + GType, GstVaapiDmaBufAllocator is a full feature GstAllocator inherited + from GstDmaBufAllocator. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-10-19 15:30:09 +0100 Julien Isorce + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: errors in gst_vaapi_dmabuf_allocator_new() + Add a helper function to initialize the gst_debug_vaapivideomemory, + to use it either by the GstVaapiVideoAllocatorClass or + GstVaapiDmabufAllocator (which is a decorator of GstDmaBufAllocator). + Later, log possible errors when calling gst_vaapi_dmabuf_allocator_new () + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-11-29 15:14:32 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: release internal encoder at stop() + As the internal encoder is created at start(), let's release it at + stop() vmethod, to be consistent. + gst_vaapiencode_destroy() is called since it also resets the input and + output states, which is something that the base class does internally + after calling stop() vmethod. + https://bugzilla.gnome.org/show_bug.cgi?id=769266 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-12-03 08:20:56 +0100 Edward Hervey + + * common: + Automatic update of common submodule + From f49c55e to 39ac2f5 + +2016-11-29 14:59:02 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: call ensure_encoder() at start() + Currently, specific encoder is created during set_format(). This might + lead to race condition when creating profiles with multiple encoders. + This patch moves ensure_encoder() call to start() vmethod to ensure + avoiding the race condition. + https://bugzilla.gnome.org/show_bug.cgi?id=773546 + +2016-11-21 19:29:22 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: bring back dynamic configuration + In commit ca0c3fd6 we remove the dynamic configuration if the bin + because we assumed that the bin will be always static as it is + registered. + Nonetheless we were wrong, because it is possible to request, with a + property, to avoid the use of the post-processor. + Since we want to add a way to disable the post-processor through + environment variables, this remove feature is required again. + If the environment variable GST_VAAPI_DISABLE_VPP is defined the + postprocessor inside of the vaapidecodebin is disabled, then + vaapidecodebin is an alias of the old vaapidecode. + https://bugzilla.gnome.org/show_bug.cgi?id=775041 + +2016-11-21 18:25:18 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: implement negotiate() vmethod + Instead of decorating the negotiate() method, let us override it, + so the stream is locked while called. + https://bugzilla.gnome.org/show_bug.cgi?id=775040 + +2016-11-26 11:27:26 +0000 Tim-Philipp Müller + + * .gitmodules: + common: use https protocol for common submodule + https://bugzilla.gnome.org/show_bug.cgi?id=775110 + +2016-11-24 21:17:54 +0100 Dominique Leuenberger + + * gst-libs/gst/vaapi/Makefile.am: + build: add LIBVA_WAYLAND_CFLAGS to libgstvaapiegl + In case libva-wayland has its headers not installed in default + locations (like /usr/include), the build fails to include "wayland-client.h": + CC libgstvaapi_egl_la-gstvaapiutils_egl.lo + In file included from gstvaapidisplay_wayland.h:27:0, + from gstvaapidisplay_egl.c:35: + /usr/include/va/va_wayland.h:31:28: fatal error: wayland-client.h: No such file or directory + #include + As we already passed VA_CLAGS, /usr/include/va/va_wayland.h could be found, but it is + our fault not to instruct the system that we ALSO care for va_wayland. We correctly query + for libva-wayland.pc in configure and use this in other places as well. It is thus only + correct and consequent, to do it also at this spot. + https://bugzilla.gnome.org/show_bug.cgi?id=773946 + +2015-10-28 12:55:18 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + vaapivideocontext: log a message if no bus + Raise a warning if there is no bus when the element tries to post a + message. + +2015-10-28 12:57:14 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: create display at open() + Instead of creating the VA display before setting the bus to the + element, it is created when the element is opened. + Basically, this commit is a revert of + 5e5d62cac79754ba60057fc2516135aad8d7de35 + That was done when the GStreamer's context sharing was not mature + enough as now. There is no reason to keep this hack. + +2016-11-04 18:04:36 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: don't add video crop meta + Since the differentiation of negotiation caps and allocation caps, + there is no need to add a video crop meta with the negotiation caps. + Hence, removing it. + https://bugzilla.gnome.org/show_bug.cgi?id=773948 + +2015-03-19 21:20:26 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobuffer.c: + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa.h: + remove the video converter from vaapi buffer meta + Since all the video converter were deprecated in gstreamer-1.2, we don't need + to handle them anymore in the vaapi's buffer meta. + This patch removes its usage and the buffer meta's API for that. + https://bugzilla.gnome.org/show_bug.cgi?id=745728 + +2016-11-21 18:28:18 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: destroy source pad allocator and pool + First, deactivate source pad pool when the out caps change, and if so, + destroy texture map, the source pad allocator and pool only if the + new caps are different from the ones already set. + +2016-11-21 19:17:07 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: don't destroy sink pad allocator + Don't destroy sink pad allocator at _set_caps() because it will be done at + ensure_sinkpad_buffer_pool() if it is required. + +2016-11-21 18:27:00 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: first validate the out caps + When calling _set_caps() first validate the out caps before doing + anything else. + +2016-11-21 18:42:02 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: negotiate after destroying allocator + This is related with bug 758907 when no vaapipostproc is used (no + vaapidecodebin). In order to negotiate downstream we need to destroy + the source pad allocator, otherwise the same allocated buffers are + used, failing the mapping. + +2016-11-21 16:35:34 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: remove GST_VAAPI_TYPE_VIDEO_INFO + Remove redundant GST_VAAPI_TYPE_VIDEO_INFO, since it is a duplicate of + GST_TYPE_VIDEO_INFO created before gstreamer 1.6, where the boxed type + was created. + https://bugzilla.gnome.org/show_bug.cgi?id=774782 + +2016-11-21 12:51:25 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: update the src pad allocator video info + Update the size, stride and offset of the source pad allocator video + info, so the pool could set the correct GstVideoMeta + https://bugzilla.gnome.org/show_bug.cgi?id=774782 + +2016-11-21 12:36:27 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: add missing documentation + https://bugzilla.gnome.org/show_bug.cgi?id=774782 + +2016-11-21 12:29:26 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: use early return without goto + https://bugzilla.gnome.org/show_bug.cgi?id=774782 + +2016-11-21 11:25:21 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: add allocator to allocation query + This patch adds the created allocator to the allocation query either + in decide_allocation() and propose_allocation() vmehtods. + With it, there's no need to set the modified allocator's size in the + pool configuration. + https://bugzilla.gnome.org/show_bug.cgi?id=774782 + +2016-10-19 15:15:01 +0100 Julien Isorce + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: set correct buffer size + We should set the correct buffer size when we are configuring the pool, + otherwise the buffer will be discarded when it returns to the pool. + Indeed when the ref-count of a buffer reaches zero, its pool will queue + it back (and ref it) if, and only if, the buffer size matches the + configured buffer size on the pool. + This issue can be debugged with GST_DEBUG=*PERF*:6, see gstbufferpool.c + https://bugzilla.gnome.org/show_bug.cgi?id=774782 + +2016-11-10 13:26:31 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: check for memory allocator + When calling gst_vaapi_video_memory_copy() the allocator of the memory + to copy should be allocated by the vaapi allocator. + This patch does this verification. + +2016-11-10 13:25:30 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: code style fixes + A cosmetic commit for enhance readability of the casts and method + preconditions. + +2016-11-09 19:49:22 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: unroll gst_vaapi_video_allocator_free() + Instead of having a gst_vaapi_video_memory_free() that is only going to + be called by gst_vaapi_video_allocator_free(), let's just remove the first + and merged into the second. + +2016-11-09 19:29:12 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: avoid virtual methods casting + Use the expected virtual method signatures for readability. + +2016-11-09 18:58:20 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: remove unimplemented methods + Remove unimplemented method for allocator mem_share() and mem_is_span(). + +2016-11-09 18:54:47 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: fail if frame map can't get plane + If map() vmethod in GstVideMeta cannot get the plane data, return false, + thus the caller will not try to read invalid memory. + https://bugzilla.gnome.org/show_bug.cgi?id=774213 + +2016-11-09 18:39:06 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: lock map and unmap operations + In order to avoid race condition when two threads call map/unmap the same + VA surface, this patch mutex these operations. + https://bugzilla.gnome.org/show_bug.cgi?id=774213 + +2016-11-09 17:37:06 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: refactor vaapi memory unmapping + There were duplicated code in gst_video_meta_unmap_vaapi_memory() and + gst_vaapi_video_memory_unmap() when unmapping. + This patch refactors both methods adding the common function + unmap_vaapi_memory(). This also ensures, if direct rendering is enabled, it + is correctly reset. + Additionally, only when mapping flag has the WRITE bit, it set the image as + current, which was done in gst_video_meta_map_vaapi_memory() but no in + gst_vaapi_video_memory_map(). + In order to make this, the mapping flags were required, so instead of + overloading mem_unmap() virtual function, mem_unmap_full() is overloaded. + https://bugzilla.gnome.org/show_bug.cgi?id=774213 + +2016-11-09 13:54:23 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: refactor vaapi memory mapping + There were duplicated code in gst_video_meta_map_vaapi_memory() and + gst_vaapi_video_memory_map() when doing the READ and WRITE mapping. + This patch refactors both methods adding the common function + map_vaapi_memory(). + Additionally, only when flag has the READ bit it calls + ensure_images_is_current(), which was done in + gst_video_meta_map_vaapi_memory() but no in + gst_vaapi_video_memory_map(). + https://bugzilla.gnome.org/show_bug.cgi?id=772151 + +2016-10-27 18:22:18 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: unref allowed_sinkpad_caps at close() + The variable member allowed_sinkpad_caps is constructed querying the + current VA display. Bearing that in mind, the variable shall be freed + when the VA display changes or is removed. + This patch moves the freeing of allowed_sinkpad_caps to close(), when + the VA display is freed. + +2016-11-11 11:40:09 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapisink.c: + vaapisink: finish event thread at stop() + The thread that handles window's events should be finished during + pipeline's shutdown, otherwise it will remain alive during pipeline + re-activation, leading to unexpected problems. + This patch fixes failures of intensive_state_change scenario of + gst-validate + https://bugzilla.gnome.org/show_bug.cgi?id=774241 + +2016-11-08 09:35:00 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: enhance debug message + "gst_pad_push" is not a good description of the event. + +2016-11-08 10:05:32 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipostproc.c: + postproc: honor gst_pad_push() return value + Returning GST_FLOW_ERROR always when gst_pad_push fails might lead to + deadlock during seek. + This patch returns the same error of gst_pad_push() and log out the + return value. + https://bugzilla.gnome.org/show_bug.cgi?id=774030 + +2016-11-04 16:26:18 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: guard GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS + In commit 6d11a00 were introduced a regression when gstreamer-vaapi is + compiled with out EGL/GLX support: it shall not support + GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS. + This patch guards the inclusion of GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS in the + allowed src caps for vaapedecode if EGL/GLX. + +2016-11-04 12:55:23 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: increment map counter only if succeeded + Previously the frame map counter increased independently if the map succeeded + or not. This leaded to critical messages and crashes if the frame was unable + to be mapped, but the counter increased. + This patch increases the map counter only if the map operation occurred. + https://bugzilla.gnome.org/show_bug.cgi?id=773939 + +2016-11-03 17:30:46 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: set negotiation caps in src allocator + When the allocator is created, it stores the allocation caps. But sometimes + the "allocation caps" may be different from the "negotiation caps". + In this case, the allocator should store the negotiation caps since they + are the ones used for frame mapping with GstVideoMeta. + When vaapispostproc is used, this is not a problem since the element is assume + to resize. But when using a vaapi decoder only, with a software renderer, it + fails in this case. + https://bugzilla.gnome.org/show_bug.cgi?id=773323 + +2016-07-19 16:40:10 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: generate source pad caps + Just as vaapipostproc, VA decoder's context can be queried to get the possible + raw formats, so, the src caps can negotiate the exact caps that the context + supports. + +2016-02-25 18:57:30 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + libs: decoder: add _get_surface_formats() + This function exposes the available formats of the surfaces in the the current + context to the plugins. + +2016-02-18 19:32:58 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + libs: context: ensure context formats + This patch ensures to get the formats, as filter does, available in the + decoder / encoder context. + The context fills up the array as soon it is created, otherwise the pipeline + could get stalled (perhaps this is a bug in my HSW backend). + https://bugzilla.gnome.org/show_bug.cgi?id=752958 + +2016-02-18 19:20:10 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapiutils_core.c: + * gst-libs/gst/vaapi/gstvaapiutils_core.h: + libs: move get_surface_formats to utils_core + The query of all the supported formats for a VA config were only used by the + postprocessor (vaapifilter). But, in order to enable the vaapidecoder to + negotiate a suitable raw format with downstream, we need to query these + formats against the decoder's config. + This patch is the first step: moves the code in filter's ensure_image() to a + generic gst_vaapi_get_surface_formats() in vaapiutils_core, so it can be + shared later by the decoder. + https://bugzilla.gnome.org/show_bug.cgi?id=752958 + +2016-07-19 18:56:15 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: remove set_sinkpad_dmabuf_allocator() + Since when the sink pad allocator is created, it is decided if the required + one is vaapi allocator or dmabuf allocator, there is no need to force its set + again. + +2016-10-27 11:25:55 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: ensure display when getting raw caps + When running gst-discoverer-1.0, in certain media, vaapipostroc is stopped + meanwhile it is transforming caps. The problem is that stop() calls + gst_vaapi_plugin_base_close(), which nullifies the element's va display, but + the va display is used in tranform_caps() when it is extracting the possible + format conversions. This display disappearing generates warning messages. + This patch holds a local reference of va display at ensure_allowed_raw_caps() + hence it doesn't go away meanwhile it is used, even if the + gst_vaapi_plugin_base_close() is called in other thread. + https://bugzilla.gnome.org/show_bug.cgi?id=773593 + +2016-11-03 12:54:23 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + plugins: fix code style for errors + +2016-10-19 19:04:20 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapicodedbuffer.c: + * gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext_overlay.c: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_dpb.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimagepool.c: + * gst-libs/gst/vaapi/gstvaapiparser_frame.c: + * gst-libs/gst/vaapi/gstvaapipixmap.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: fix code style for errors + +2016-11-03 09:31:17 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideocontext.c: + plugins: update GstGL deprecated symbol + GST_GL_TYPE_CONTEXT was deprecated. Now it is GST_TYPE_GL_CONTEXT. + +2016-10-21 11:48:54 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: direct render when raw video + Enable the direct rendering with linear surfaces if the negotiated src caps + are video/x-raw without features. + Pass also the caps, since they are needed to know the requested caps features. + +2016-10-24 20:09:59 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: move src allocator error to instantiator + Just as we did in ensure_sinkpad_allocator(), let's move the error message + into the ensure_srcpad_allocator() from the caller, + gst_vaapi_plugin_base_decide_allocation() + +2016-10-20 19:37:01 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: enable direct upload if raw video + Enable the direct upload with linear surfaces if the negotiated sink caps are + video/x-raw without features. + +2016-10-21 11:21:04 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + pluginutil: add gst_caps_is_video_raw() + +2016-10-24 19:25:27 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: receive caps in ensure_sinkpad_allocator() + Instead of receiving the GstVideoInfo structure as parameter, get the original + GstCaps from ensure_sinkpad_buffer_pool(), in this way we could decide better + which allocator instantiate. + +2016-10-20 19:31:58 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: destroy derived image at unmap + If the allocator was configured to use direct upload or rendering, the + generated derived image created at mapping needs to be destroyed after + unmapping, because, in order to process the surface, it should not be marked + as "busy" by the driver. + +2016-10-21 11:57:55 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: enhance logs for direct modes + Print, conditionally, only the enabled direct mode. + +2016-10-20 17:02:49 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: add direct upload flag + Adds the direct-upload flag in the GstVaapiVideoAllocator and + GstVaapiVideoMemory. + It still doesn't apply any functional change. + +2016-10-20 16:49:22 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: set direct rendering at run-time + The way to experiment with the direct rendering is through and internal + compiler pre-processor flag. + The current change set enables a way to specified at run-time, as a flag + passed to the allocator at instanciation time. + +2016-10-20 18:09:59 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: log in perf category when copy + Log in performance category when the derive image handling fails, falling back + to memory copy. + +2016-10-20 16:31:21 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: error log is derive image fails + Instead of a silently failure of the derive image, this patch log an error + message according to the failure. + +2016-10-20 12:52:18 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: store surface alloc flags in qdata + For sake of consistency, we should add the requested surface allocation flags + to the object's qdata structure. + +2016-10-20 12:22:06 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: category init when object define + Move the Gstreamer debug category initialize to the GObject definition. + +2016-11-03 08:31:16 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapitexturemap.c: + libs: vaapitexturemap: trivial code-style fix + +2016-11-02 20:01:09 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + libs: display: egl: avoid recreate native display + Instead of passing the native descriptor of the display, just pass the received + GstVaapiDisplay and reuse it. + +2016-11-02 15:38:52 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: log the GstVaapiDisplay name + Now that GstVaapiDisplay is descendant of GstObject, it has a human-friendly + name. Log it instead of the memory address. + +2016-11-02 18:37:00 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiwindow_egl.c: + libs: window: egl: pass native va display + When creating a GstVaapiWindowEGL, it also creates native window by its own + native display. It should pass the native display, either X11 or Wayland. + https://bugzilla.gnome.org/show_bug.cgi?id=768266 + +2016-10-13 12:53:17 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidebug.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.h: + * gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapitexture_egl.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.h: + * gst/vaapi/gstvaapivideocontext.c: + libs: display: GstVaapiDisplay as GstObject descendant + This patch is to change the inheritance of GstVaapiDisplay to GstObject, + instead of GstVaapiMiniObject. In this way we can use all the available + infrastructure for GObject/GstObject such as GstTracer, GIR, etc. + In addition, a new debug category for GstVaapiDisplay is created to make it + easier to trace debug messages. It is named "vaapidisplay" and it transverse + all the VA display backends (DRM, GLX, EGL, Wayland, ...) + This patch is a step forward to expose GstVaapiDisplay for users in a future + library. + https://bugzilla.gnome.org/show_bug.cgi?id=768266 + Signed-off-by: Víctor Manuel Jáquez Leal + +=== release 1.11.0 === + +2016-11-01 18:54:54 +0200 Sebastian Dröge + + * configure.ac: + Back to development + +=== release 1.10.0 === + +2016-11-01 18:19:32 +0200 Sebastian Dröge + + * ChangeLog: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + Release 1.10.0 2016-10-27 17:13:48 +0200 Víctor Manuel Jáquez Leal diff --git a/NEWS b/NEWS index 547de7f3f9..a940f7bb0f 100644 --- a/NEWS +++ b/NEWS @@ -1,1114 +1 @@ -# GStreamer 1.10 Release Notes - -**GStreamer 1.10.0 was released on 1st November 2016.** - -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 new features, bug fixes and other -improvements. - -See [https://gstreamer.freedesktop.org/releases/1.10/][latest] for the latest -version of this document. - -*Last updated: Tuesday 1 Nov 2016, 15:00 UTC [(log)][gitlog]* - -[latest]: https://gstreamer.freedesktop.org/releases/1.10/ -[gitlog]: https://cgit.freedesktop.org/gstreamer/www/log/src/htdocs/releases/1.10/release-notes-1.10.md - -## 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 new features, bug fixes and other -improvements. - -## Highlights - -- Several convenience APIs have been added to make developers' lives easier -- A new `GstStream` API provides applications a more meaningful view of the - structure of streams, simplifying the process of dealing with media in - complex container formats -- Experimental `decodebin3` and `playbin3` elements which bring a number of - improvements which were hard to implement within `decodebin` and `playbin` -- A new `parsebin` element to automatically unpack and parse a stream, stopping - just short of decoding -- Experimental new `meson`-based build system, bringing faster build and much - better Windows support (including for building with Visual Studio) -- A new `gst-docs` module has been created, and we are in the process of moving - our documentation to a markdown-based format for easier maintenance and - updates -- A new `gst-examples` module has been create, which contains example - GStreamer applications and is expected to grow with many more examples in - the future -- Various OpenGL and OpenGL|ES-related fixes and improvements for greater - efficiency on desktop and mobile platforms, and Vulkan support on Wayland was - also added -- Extensive improvements to the VAAPI plugins for improved robustness and - efficiency -- Lots of fixes and improvements across the board, spanning RTP/RTSP, V4L2, - Bluetooth, audio conversion, echo cancellation, and more! - -## Major new features and changes - -### Noteworthy new API, features and other changes - -#### Core API additions - -##### Receive property change notifications via bus messages - -New API was added to receive element property change notifications via -bus messages. So far, applications had to connect a callback to an element's -`notify::property-name` signal via the GObject API, which was inconvenient for -at least two reasons: one had to implement a signal callback function, and that -callback function would usually be called from one of the streaming threads, so -one had to marshal (send) any information gathered or pending requests to the -main application thread which was tedious and error-prone. - -Enter [`gst_element_add_property_notify_watch()`][notify-watch] and -[`gst_element_add_property_deep_notify_watch()`][deep-notify-watch] which will -watch for changes of a property on the specified element, either only for this -element or recursively for a whole bin or pipeline. Whenever such a -property change happens, a `GST_MESSAGE_PROPERTY_NOTIFY` message will be posted -on the pipeline bus with details of the element, the property and the new -property value, all of which can be retrieved later from the message in the -application via [`gst_message_parse_property_notify()`][parse-notify]. Unlike -the GstBus watch functions, this API does not rely on a running GLib main loop. - -The above can be used to be notified asynchronously of caps changes in the -pipeline, or volume changes on an audio sink element, for example. - -[notify-watch]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#gst-element-add-property-notify-watch -[deep-notify-watch]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#gst-element-add-property-deep-notify-watch -[parse-notify]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html#gst-message-parse-property-notify - -##### GstBin "deep" element-added and element-removed signals - -GstBin has gained `"deep-element-added"` and `"deep-element-removed"` signals -which makes it easier for applications and higher-level plugins to track when -elements are added or removed from a complex pipeline with multiple sub-bins. - -`playbin` makes use of this to implement the new `"element-setup"` signal which -can be used to configure elements as they are added to `playbin`, just like the -existing `"source-setup"` signal which can be used to configure the source -element created. - -##### Error messages can contain additional structured details - -It is often useful to provide additional, structured information in error, -warning or info messages for applications (or higher-level elements) to make -intelligent decisions based on them. To allow this, error, warning and info -messages now have API for adding arbitrary additional information to them -using a `GstStructure`: -[`GST_ELEMENT_ERROR_WITH_DETAILS`][element-error-with-details] and -corresponding API for the other message types. - -This is now used e.g. by the new [`GST_ELEMENT_FLOW_ERROR`][element-flow-error] -API to include the actual flow error in the error message, and the -[souphttpsrc element][souphttpsrc-detailed-errors] to provide the HTTP -status code, and the URL (if any) to which a redirection has happened. - -[element-error-with-details]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#GST-ELEMENT-ERROR-WITH-DETAILS:CAPS -[element-flow-error]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#GST-ELEMENT-FLOW-ERROR:CAPS -[souphttpsrc-detailed-errors]: https://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/ext/soup/gstsouphttpsrc.c?id=60d30db912a1aedd743e66b9dcd2e21d71fbb24f#n1318 - -##### Redirect messages have official API now - -Sometimes, elements need to redirect the current stream URL and tell the -application to proceed with this new URL, possibly using a different -protocol too (thus changing the pipeline configuration). Until now, this was -informally implemented using `ELEMENT` messages on the bus. - -Now this has been formalized in the form of a new `GST_MESSAGE_REDIRECT` message. -A new redirect message can be created using [`gst_message_new_redirect()`][new-redirect]. -If needed, multiple redirect locations can be specified by calling -[`gst_message_add_redirect_entry()`][add-redirect] to add further redirect -entries, all with metadata, so the application can decide which is -most suitable (e.g. depending on the bitrate tags). - -[new-redirect]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html#gst-message-new-redirect -[add-redirect]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html#gst-message-add-redirect-entry - -##### New pad linking convenience functions that automatically create ghost pads - -New pad linking convenience functions were added: -[`gst_pad_link_maybe_ghosting()`][pad-maybe-ghost] and -[`gst_pad_link_maybe_ghosting_full()`][pad-maybe-ghost-full] which were -previously internal to GStreamer have now been exposed for general use. - -The existing pad link functions will refuse to link pads or elements at -different levels in the pipeline hierarchy, requiring the developer to -create ghost pads where necessary. These new utility functions will -automatically create ghostpads as needed when linking pads at different -levels of the hierarchy (e.g. from an element inside a bin to one that's at -the same level in the hierarchy as the bin, or in another bin). - -[pad-maybe-ghost]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPad.html#gst-pad-link-maybe-ghosting -[pad-maybe-ghost-full]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPad.html#gst-pad-link-maybe-ghosting-full - -##### Miscellaneous - -Pad probes: IDLE and BLOCK probes now work slightly differently in pull mode, -so that push and pull mode have opposite scenarios for idle and blocking probes. -In push mode, it will block with some data type and IDLE won't have any data. -In pull mode, it will block _before_ getting a buffer and will be IDLE once some -data has been obtained. ([commit][commit-pad-probes], [bug][bug-pad-probes]) - -[commit-pad-probes]: https://cgit.freedesktop.org/gstreamer/gstreamer/commit/gst/gstpad.c?id=368ee8a336d0c868d81fdace54b24431a8b48cbf -[bug-pad-probes]: https://bugzilla.gnome.org/show_bug.cgi?id=761211 - -[`gst_parse_launch_full()`][parse-launch-full] can now be made to return a -`GstBin` instead of a top-level pipeline by passing the new -`GST_PARSE_FLAG_PLACE_IN_BIN` flag. - -[parse-launch-full]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstParse.html#gst-parse-launch-full - -The default GStreamer debug log handler can now be removed before -calling `gst_init()`, so that it will never get installed and won't be active -during initialization. - -A new [`STREAM_GROUP_DONE` event][stream-group-done-event] was added. In some -ways it works similar to the `EOS` event in that it can be used to unblock -downstream elements which may be waiting for further data, such as for example -`input-selector`. Unlike `EOS`, further data flow may happen after the -`STREAM_GROUP_DONE` event though (and without the need to flush the pipeline). -This is used to unblock input-selector when switching between streams in -adaptive streaming scenarios (e.g. HLS). - -[stream-group-done-event]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstEvent.html#gst-event-new-stream-group-done - -The `gst-launch-1.0` command line tool will now print unescaped caps in verbose -mode (enabled by the -v switch). - -[`gst_element_call_async()`][call-async] has been added as convenience API for -plugin developers. It is useful for one-shot operations that need to be done -from a thread other than the current streaming thread. It is backed by a -thread-pool that is shared by all elements. - -[call-async]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#gst-element-call-async - -Various race conditions have been fixed around the `GstPoll` API used by e.g. -`GstBus` and `GstBufferPool`. Some of these manifested themselves primarily -on Windows. - -`GstAdapter` can now keep track of discontinuities signalled via the `DISCONT` -buffer flag, and has gained [new API][new-adapter-api] to track PTS, DTS and -offset at the last discont. This is useful for plugins implementing advanced -trick mode scenarios. - -[new-adapter-api]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstAdapter.html#gst-adapter-pts-at-discont - -`GstTestClock` gained a new [`"clock-type"` property][clock-type-prop]. - -[clock-type-prop]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstTestClock.html#GstTestClock--clock-type - -#### GstStream API for stream announcement and stream selection - -New stream listing and stream selection API: new API has been added to -provide high-level abstractions for streams ([`GstStream`][stream-api]) -and collections of streams ([`GstStreamCollections`][stream-collection-api]). - -##### Stream listing - -A [`GstStream`][stream-api] contains all the information pertinent to a stream, -such as stream id, caps, tags, flags and stream type(s); it can represent a -single elementary stream (e.g. audio, video, subtitles, etc.) or a container -stream. This will depend on the context. In a decodebin3/playbin3 one -it will typically be elementary streams that can be selected and unselected. - -A [`GstStreamCollection`][stream-collection-api] represents a group of streams -and is used to announce or publish all available streams. A GstStreamCollection -is immutable - once created it won't change. If the available streams change, -e.g. because a new stream appeared or some streams disappeared, a new stream -collection will be published. This new stream collection may contain streams -from the previous collection if those streams persist, or completely new ones. -Stream collections do not yet list all theoretically available streams, -e.g. other available DVD angles or alternative resolutions/bitrate of the same -stream in case of adaptive streaming. - -New events and messages have been added to notify or update other elements and -the application about which streams are currently available and/or selected. -This way, we can easily and seamlessly let the application know whenever the -available streams change, as happens frequently with digital television streams -for example. The new system is also more flexible. For example, it is now also -possible for the application to select multiple streams of the same type -(e.g. in a transcoding/transmuxing scenario). - -A [`STREAM_COLLECTION` message][stream-collection-msg] is posted on the bus -to inform the parent bin (e.g. `playbin3`, `decodebin3`) and/or the application -about what streams are available, so you no longer have to hunt for this -information at different places. The available information includes number of -streams of each type, caps, tags etc. Bins and/or the application can intercept -the message synchronously to select and deselect streams before any data is -produced - for the case where elements such as the demuxers support the new -stream API, not necessarily in the parsebin compatibility fallback case. - -Similarly, there is also a [`STREAM_COLLECTION` event][stream-collection-event] -to inform downstream elements of the available streams. This event can be used -by elements to aggregate streams from multiple inputs into one single collection. - -The `STREAM_START` event was extended so that it can also contain a GstStream -object with all information about the current stream, see -[`gst_event_set_stream()`][event-set-stream] and -[`gst_event_parse_stream()`][event-parse-stream]. -[`gst_pad_get_stream()`][pad-get-stream] is a new utility function that can be -used to look up the GstStream from the `STREAM_START` sticky event on a pad. - -[stream-api]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstStream.html -[stream-collection-api]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstStreamCollection.html -[stream-collection-msg]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html#gst-message-new-stream-collection -[stream-collection-event]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstEvent.html#gst-event-new-stream-collection -[event-set-stream]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstEvent.html#gst-event-set-stream -[event-parse-stream]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstEvent.html#gst-event-parse-stream -[pad-get-stream]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPad.html#gst-pad-get-stream - -##### Stream selection - -Once the available streams have been published, streams can be selected via -their stream ID using the new `SELECT_STREAMS` event, which can be created -with [`gst_event_new_select_streams()`][event-select-streams]. The new API -supports selecting multiple streams per stream type. In the future, we may also -implement explicit deselection of streams that will never be used, so -elements can skip these and never expose them or output data for them in the -first place. - -The application is then notified of the currently selected streams via the -new `STREAMS_SELECTED` message on the pipeline bus, containing both the current -stream collection as well as the selected streams. This might be posted in -response to the application sending a `SELECT_STREAMS` event or when -`decodebin3` or `playbin3` decide on the streams to be initially selected without -application input. - -[event-select-streams]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstEvent.html#gst-event-new-select-streams - -##### Further reading - -See further below for some notes on the new elements supporting this new -stream API, namely: `decodebin3`, `playbin3` and `parsebin`. - -More information about the new API and the new elements can also be found here: - -- GStreamer [stream selection design docs][streams-design] -- Edward Hervey's talk ["The new streams API: Design and usage"][streams-talk] ([slides][streams-slides]) -- Edward Hervey's talk ["Decodebin3: Dealing with modern playback use cases"][db3-talk] ([slides][db3-slides]) - -[streams-design]: https://cgit.freedesktop.org/gstreamer/gstreamer/tree/docs/design/part-stream-selection.txt -[streams-talk]: https://gstconf.ubicast.tv/videos/the-new-gststream-api-design-and-usage/ -[streams-slides]: https://gstreamer.freedesktop.org/data/events/gstreamer-conference/2016/Edward%20Hervey%20-%20The%20New%20Streams%20API%20Design%20and%20Usage.pdf -[db3-talk]: https://gstconf.ubicast.tv/videos/decodebin3-or-dealing-with-modern-playback-use-cases/ -[db3-slides]: https://gstreamer.freedesktop.org/data/events/gstreamer-conference/2015/Edward%20Hervey%20-%20decodebin3.pdf - -#### Audio conversion and resampling API - -The audio conversion library received a completely new and rewritten audio -resampler, complementing the audio conversion routines moved into the audio -library in the [previous release][release-notes-1.8]. Integrating the resampler -with the other audio conversion library allows us to implement generic -conversion much more efficiently, as format conversion and resampling can now -be done in the same processing loop instead of having to do it in separate -steps (our element implementations do not make use of this yet though). - -The new audio resampler library is a combination of some of the best features -of other samplers such as ffmpeg, speex and SRC. It natively supports S16, S32, -F32 and F64 formats and uses optimized x86 and neon assembly for most of its -processing. It also has support for dynamically changing sample rates by incrementally -updating the filter tables using linear or cubic interpolation. According to -some benchmarks, it's one of the fastest and most accurate resamplers around. - -The `audioresample` plugin has been ported to the new audio library functions -to make use of the new resampler. - -[release-notes-1.8]: https://gstreamer.freedesktop.org/releases/1.8/ - -#### Support for SMPTE timecodes - -Support for SMPTE timecodes was added to the GStreamer video library. This -comes with an abstraction for timecodes, [`GstVideoTimeCode`][video-timecode] -and a [`GstMeta`][video-timecode-meta] that can be placed on video buffers for -carrying the timecode information for each frame. Additionally there is -various API for making handling of timecodes easy and to do various -calculations with them. - -A new plugin called [`timecode`][timecode-plugin] was added, that contains an -element called `timecodestamper` for putting the timecode meta on video frames -based on counting the frames and another element called `timecodewait` that -drops all video (and audio) until a specific timecode is reached. - -Additionally support was added to the Decklink plugin for including the -timecode information when sending video out or capturing it via SDI, the -`qtmux` element is able to write timecode information into the MOV container, -and the `timeoverlay` element can overlay timecodes on top of the video. - -More information can be found in the [talk about timecodes][timecode-talk] at -the GStreamer Conference 2016. - -[video-timecode]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode -[video-timecode-meta]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideometa.html#gst-buffer-add-video-time-code-meta -[timecode-plugin]: https://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/gst/timecode -[timecode-talk]: https://gstconf.ubicast.tv/videos/smpte-timecodes-in-gstreamer/ - -#### GStreamer OpenMAX IL plugin - -The last gst-omx release, 1.2.0, was in July 2014. It was about time to get -a new one out with all the improvements that have happened in the meantime. -From now on, we will try to release gst-omx together with all other modules. - -This release features a lot of bugfixes, improved support for the Raspberry Pi -and in general improved support for zerocopy rendering via EGL and a few minor -new features. - -At this point, gst-omx is known to work best on the Raspberry Pi platform but -it is also known to work on various other platforms. Unfortunately, we are -not including configurations for any other platforms, so if you happen to use -gst-omx: please send us patches with your configuration and code changes! - -### New Elements - -#### decodebin3, playbin3, parsebin (experimental) - -This release features new decoding and playback elements as experimental -technology previews: `decodebin3` and `playbin3` will soon supersede the -existing `decodebin` and `playbin` elements. We skipped the number 2 because -it was already used back in the 0.10 days, which might cause confusion. -Experimental technology preview means that everything should work fine already, -but we can't guarantee there won't be minor behavioural changes in the -next cycle. In any case, please test and report any problems back. - -Before we go into detail about what these new elements improve, let's look at -the new [`parsebin`][parsebin] element. It works similarly to `decodebin` and -`decodebin3`, only that it stops one step short and does not plug any actual -decoder elements. It will only plug parsers, tag readers, demuxers and -depayloaders. Also note that parsebin does not contain any queueing element. - -[`decodebin3`'s][decodebin3] internal architecture is slightly different from -the existing `decodebin` element and fixes many long-standing issues with our -decoding engine. For one, data is now fed into the internal `multiqueue` element -*after* it has been parsed and timestamped, which means that the `multiqueue` -element now has more knowledge and is able to calculate the interleaving of the -various streams, thus minimizing memory requirements and doing away with magic -values for buffering limits that were conceived when videos were 240p or 360p. -Anyone who has tried to play back 4k video streams with decodebin2 -will have noticed the limitations of that approach. The improved timestamp -tracking also enables `multiqueue` to keep streams of the same type (audio, -video) aligned better, making sure switching between streams of the same type -is very fast. - -Another major improvement in `decodebin3` is that it will no longer decode -streams that are not being used. With the old `decodebin` and `playbin`, when -there were 8 audio streams we would always decode all 8 streams even -if 7 were not actually used. This caused a lot of CPU overhead, which was -particularly problematic on embedded devices. When switching between streams -`decodebin3` will try hard to re-use existing decoders. This is useful when -switching between multiple streams of the same type if they are encoded in the -same format. - -Re-using decoders is also useful when the available streams change on the fly, -as might happen with radio streams (chained Oggs), digital television -broadcasts, when adaptive streaming streams change bitrate, or when switching -gaplessly to the next title. In order to guarantee a seamless transition, the -old `decodebin2` would plug a second decoder for the new stream while finishing -up the old stream. With `decodebin3`, this is no longer needed - at least not -when the new and old format are the same. This will be particularly useful -on embedded systems where it is often not possible to run multiple decoders -at the same time, or when tearing down and setting up decoders is fairly -expensive. - -`decodebin3` also allows for multiple input streams, not just a single one. -This will be useful, in the future, for gapless playback, or for feeding -multiple external subtitle streams to decodebin/playbin. - -`playbin3` uses `decodebin3` internally, and will supercede `playbin`. -It was decided that it would be too risky to make the old `playbin` use the -new `decodebin3` in a backwards-compatible way. The new architecture -makes it awkward, if not impossible, to maintain perfect backwards compatibility -in some aspects, hence `playbin3` was born, and developers can migrate to the -new element and new API at their own pace. - -All of these new elements make use of the new `GstStream` API for listing and -selecting streams, as described above. `parsebin` provides backwards -compatibility for demuxers and parsers which do not advertise their streams -using the new API yet (which is most). - -The new elements are not entirely feature-complete yet: `playbin3` does not -support so-called decodersinks yet where the data is not decoded inside -GStreamer but passed directly for decoding to the sink. `decodebin3` is missing -the various `autoplug-*` signals to influence which decoders get autoplugged -in which order. We're looking to add back this functionality, but it will probably -be in a different way, with a single unified signal and using GstStream perhaps. - -For more information on these new elements, check out Edward Hervey's talk -[*decodebin3 - dealing with modern playback use cases*][db3-talk] - -[parsebin]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-parsebin.html -[decodebin3]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-decodebin3.html -[db3-talk]: https://gstconf.ubicast.tv/videos/decodebin3-or-dealing-with-modern-playback-use-cases/ - -#### LV2 ported from 0.10 and switched from slv2 to lilv2 - -The LV2 wrapper plugin has been ported to 1.0 and moved from using the -deprecated slv2 library to its replacement liblv2. We support sources and -filter elements. lv2 is short for *Linux Audio Developer's Simple Plugin API -(LADSPA) version 2* and is an open standard for audio plugins which includes -support for audio synthesis (generation), digital signal processing of digital -audio, and MIDI. The new lv2 plugin supersedes the existing LADSPA plugin. - -#### WebRTC DSP Plugin for echo-cancellation, gain control and noise suppression - -A set of new elements ([webrtcdsp][webrtcdsp], [webrtcechoprobe][webrtcechoprobe]) -based on the WebRTC DSP software stack can now be used to improve your audio -voice communication pipelines. They support echo cancellation, gain control, -noise suppression and more. For more details you may read -[Nicolas' blog post][webrtc-blog-post]. - -[webrtcdsp]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-webrtcdsp.html -[webrtcechoprobe]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-webrtcechoprobe.html -[webrtc-blog-post]: https://ndufresne.ca/2016/06/gstreamer-echo-canceller/ - -#### Fraunhofer FDK AAC encoder and decoder - -New encoder and decoder elements wrapping the Fraunhofer FDK AAC library have -been added (`fdkaacdec`, `fdkaacdec`). The Fraunhofer FDK AAC encoder is -generally considered to be a very high-quality AAC encoder, but unfortunately -it comes under a non-free license with the option to obtain a paid, commercial -license. - -### Noteworthy element features and additions - -#### Major RTP and RTSP improvements - -- The RTSP server and source element, as well as the RTP jitterbuffer now support - remote clock synchronization according to [RFC7273][https://tools.ietf.org/html/rfc7273]. -- Support for application and profile specific RTCP packets was added. -- The H265/HEVC payloader/depayloader is again in sync with the final RFC. -- Seeking stability of the RTSP source and server was improved a lot and - runs stably now, even when doing scrub-seeking. -- The RTSP server received various major bugfixes, including for regressions that - caused the IP/port address pool to not be considered, or NAT hole punching - to not work anymore. [Bugzilla #766612][https://bugzilla.gnome.org/show_bug.cgi?id=766612] -- Various other bugfixes that improve the stability of RTP and RTSP, including - many new unit / integration tests. - -#### Improvements to splitmuxsrc and splitmuxsink - -- The splitmux element received reliability and error handling improvements, - removing at least one deadlock case. `splitmuxsrc` now stops cleanly at the end - of the segment when handling seeks with a stop time. We fixed a bug with large - amounts of downstream buffering causing incorrect out-of-sequence playback. - -- `splitmuxsrc` now has a `"format-location"` signal to directly specify the list - of files to play from. - -- `splitmuxsink` can now optionally send force-keyunit events to upstream - elements to allow splitting files more accurately instead of having to wait - for upstream to provide a new keyframe by itself. - -#### OpenGL/GLES improvements - -##### iOS and macOS (OS/X) - -- We now create OpenGL|ES 3.x contexts on iOS by default with a fallback to - OpenGL|ES 2.x if that fails. -- Various zerocopy decoding fixes and enhancements with the - encoding/decoding/capturing elements. -- libdispatch is now used on all Apple platforms instead of GMainLoop, removing - the expensive poll()/pthread_*() overhead. - -##### New API - -- `GstGLFramebuffer` - for wrapping OpenGL frame buffer objects. It provides - facilities for attaching `GstGLMemory` objects to the necessary attachment - points, binding and unbinding and running a user-supplied function with the - framebuffer bound. -- `GstGLRenderbuffer` (a `GstGLBaseMemory` subclass) - for wrapping OpenGL - render buffer objects that are typically used for depth/stencil buffers or - for color buffers where we don't care about the output. -- `GstGLMemoryEGL` (a `GstGLMemory` subclass) - for combining `EGLImage`s with a GL - texture that replaces `GstEGLImageMemory` bringing the improvements made to the - other `GstGLMemory` implementations. This fixes a performance regression in - zerocopy decoding on the Raspberry Pi when used with an updated gst-omx. - -##### Miscellaneous improvements - -- `gltestsrc` is now usable on devices/platforms with OpenGL 3.x and OpenGL|ES - and has completed or gained support for new patterns in line with the - existing ones in `videotestsrc`. -- `gldeinterlace` is now available on devices/platforms with OpenGL|ES - implementations. -- The dispmanx backend (used on the Raspberry Pi) now supports the - `gst_video_overlay_set_window_handle()` and - `gst_video_overlay_set_render_rectangle()` functions. -- The `gltransformation` element now correctly transforms mouse coordinates (in - window space) to stream coordinates for both perspective and orthographic - projections. -- The `gltransformation` element now detects if the - `GstVideoAffineTransformationMeta` is supported downstream and will efficiently - pass its transformation downstream. This is a performance improvement as it - results in less processing being required. -- The wayland implementation now uses the multi-threaded safe event-loop API - allowing correct usage in applications that call wayland functions from - multiple threads. -- Support for native 90 degree rotations and horizontal/vertical flips - in `glimagesink`. - -#### Vulkan - -- The Vulkan elements now work under Wayland and have received numerous - bugfixes. - -#### QML elements - -- `qmlglsink` video sink now works on more platforms, notably, Windows, Wayland, - and Qt's eglfs (for embedded devices with an OpenGL implementation) including - the Raspberry Pi. -- New element `qmlglsrc` to record a QML scene into a GStreamer pipeline. - -#### KMS video sink - -- New element `kmssink` to render video using Direct Rendering Manager - (DRM) and Kernel Mode Setting (KMS) subsystems in the Linux - kernel. It is oriented to be used mostly in embedded systems. - -#### Wayland video sink - -- `waylandsink` now supports the wl_viewporter extension allowing - video scaling and cropping to be delegated to the Wayland - compositor. This extension is also been made optional, so that it can - also work on current compositors that don't support it. It also now has - support for the video meta, allowing zero-copy operations in more - cases. - -#### DVB improvements - -- `dvbsrc` now has better delivery-system autodetection and several - new parameter sanity-checks to improve its resilience to configuration - omissions and errors. Superfluous polling continues to be trimmed down, - and the debugging output has been made more consistent and precise. - Additionally, the channel-configuration parser now supports the new dvbv5 - format, enabling `dvbbasebin` to automatically playback content transmitted - on delivery systems that previously required manual description, like ISDB-T. - -#### DASH, HLS and adaptivedemux - -- HLS now has support for Alternate Rendition audio and video tracks. Full - support for Alternate Rendition subtitle tracks will be in an upcoming release. -- DASH received support for keyframe-only trick modes if the - `GST_SEEK_FLAG_TRICKMODE_KEY_UNITS` flag is given when seeking. It will - only download keyframes then, which should help with high-speed playback. - Changes to skip over multiple frames based on bandwidth and other metrics - will be added in the near future. -- Lots of reliability fixes around seek handling and bitrate switching. - -#### Bluetooth improvements - -- The `avdtpsrc` element now supports metadata such as track title, artist - name, and more, which devices can send via AVRCP. These are published as - tags on the pipeline. -- The `a2dpsink` element received some love and was cleaned up so that it - actually works after the initial GStreamer 1.0 port. - -#### GStreamer VAAPI - -- All the decoders have been split, one plugin feature per codec. So - far, the available ones, depending on the driver, are: - `vaapimpeg2dec`, `vaapih264dec`, `vaapih265dec`, `vaapivc1dec`, `vaapivp8dec`, - `vaapivp9dec` and `vaapijpegdec` (which already was split). -- Improvements when mapping VA surfaces into memory. It now differentiates - between negotiation caps and allocations caps, since the allocation - memory for surfaces may be bigger than one that is going to be - mapped. -- `vaapih265enc` now supports constant bitrate mode (CBR). -- Since several VA drivers are unmaintained, we decide to keep a whitelist - with the va drivers we actually test, which is mostly the i915 and to a lesser - degree gallium from the mesa project. Exporting the environment variable - `GST_VAAPI_ALL_DRIVERS` disables the whitelist. -- Plugin features are registered at run-time, according to their support by - the loaded VA driver. So only the decoders and encoder supported by the - system are registered. Since the driver can change, some dependencies are - tracked to invalidate the GStreamer registry and reload the plugin. -- `dmabuf` importation from upstream has been improved, gaining performance. -- `vaapipostproc` now can negotiate buffer transformations via caps. -- Decoders now can do I-frame only reverse playback. This decodes I-frames - only because the surface pool is smaller than the required by the GOP to show all the - frames. -- The upload of frames onto native GL textures has been optimized too, keeping - a cache of the internal structures for the offered textures by the sink. - -#### V4L2 changes - -- More pixels formats are now supported -- Decoder is now using `G_SELECTION` instead of the deprecated `G_CROP` -- Decoder now uses the `STOP` command to handle EOS -- Transform element can now scale the pixel aspect ratio -- Colorimetry support has been improved even more -- We now support the `OUTPUT_OVERLAY` type of video node in v4l2sink - -#### Miscellaneous - -- `multiqueue`'s input pads gained a new `"group-id"` property which - can be used to group input streams. Typically one will assign - different id numbers to audio, video and subtitle streams for - example. This way `multiqueue` can make sure streams of the same - type advance in lockstep if some of the streams are unlinked and the - `"sync-by-running-time"` property is set. This is used in - decodebin3/playbin3 to implement almost-instantaneous stream - switching. The grouping is required because different downstream - paths (audio, video, etc.) may have different buffering/latency - etc. so might be consuming data from multiqueue with a slightly - different phase, and if we track different stream groups separately - we minimize stream switching delays and buffering inside the - `multiqueue`. -- `alsasrc` now supports ALSA drivers without a position for each - channel, this is common in some professional or industrial hardware. -- `libvpx` based decoders (`vp8dec` and `vp9dec`) now create multiple threads on - computers with multiple CPUs automatically. -- `rfbsrc` - used for capturing from a VNC server - has seen a lot of - debugging. It now supports the latest version of the RFB - protocol and uses GIO everywhere. -- `tsdemux` can now read ATSC E-AC-3 streams. -- New `GstVideoDirection` video orientation interface for rotating, flipping - and mirroring video in 90° steps. It is implemented by the `videoflip` and - `glvideoflip` elements currently. -- It is now possible to give `appsrc` a duration in time, and there is now a - non-blocking try-pull API for `appsink` that returns NULL if nothing is - available right now. -- `x264enc` has support now for chroma-site and colorimetry settings -- A new JPEG2000 parser element was added, and the JPEG2000 caps were cleaned - up and gained more information needed in combination with RTP and various - container formats. -- Reverse playback support for `videorate` and `deinterlace` was implemented -- Various improvements everywhere for reverse playback and `KEY_UNITS` trick mode -- New cleaned up `rawaudioparse` and `rawvideoparse` elements that replace the - old `audioparse` and `videoparse` elements. There are compatibility element - factories registered with the old names to allow existing code to continue - to work. -- The Decklink plugin gained support for 10 bit video SMPTE timecodes, and - generally got many bugfixes for various issues. -- New API in `GstPlayer` for setting the multiview mode for stereoscopic - video, setting an HTTP/RTSP user agent and a time offset between audio and - video. In addition to that, there were various bugfixes and the new - gst-examples module contains Android, iOS, GTK+ and Qt example applications. -- `GstBin` has new API for suppressing various `GstElement` or `GstObject` - flags that would otherwise be affected by added/removed child elements. This - new API allows `GstBin` subclasses to handle for themselves if they - should be considered a sink or source element, for example. -- The `subparse` element can handle WebVTT streams now. -- A new `sdpsrc` element was added that can read an SDP from a file, or get it - as a string as property and then sets up an RTP pipeline accordingly. - -### Plugin moves - -No plugins were moved this cycle. We'll make up for it next cycle, promise! - -### Rewritten memory leak tracer - -GStreamer has had basic functionality to trace allocation and freeing of -both mini-objects (buffers, events, caps, etc.) and objects in the form of the -internal `GstAllocTrace` tracing system. This API was never exposed in the -1.x API series though. When requested, this would dump a list of objects and -mini-objects at exit time which had still not been freed at that point, -enabled with an environment variable. This subsystem has now been removed -in favour of a new implementation based on the recently-added tracing framework. - -Tracing hooks have been added to trace the creation and destruction of -GstObjects and mini-objects, and a new tracer plugin has been written using -those new hooks to track which objects are still live and which are not. If -GStreamer has been compiled against the libunwind library, the new leaks tracer -will remember where objects were allocated from as well. By default the leaks -tracer will simply output a warning if leaks have been detected on `gst_deinit()`. - -If the `GST_LEAKS_TRACER_SIG` environment variable is set, the leaks tracer -will also handle the following UNIX signals: - - - `SIGUSR1`: log alive objects - - `SIGUSR2`: create a checkpoint and print a list of objects created and - destroyed since the previous checkpoint. - -Unfortunately this will not work on Windows due to no signals, however. - -If the `GST_LEAKS_TRACER_STACK_TRACE` environment variable is set, the leaks -tracer will also log the creation stack trace of leaked objects. This may -significantly increase memory consumption however. - -New `MAY_BE_LEAKED` flags have been added to GstObject and GstMiniObject, so -that objects and mini-objects that are likely to stay around forever can be -flagged and blacklisted from the leak output. - -To give the new leak tracer a spin, simply call any GStreamer application such -as `gst-launch-1.0` or `gst-play-1.0` like this: - - GST_TRACERS=leaks gst-launch-1.0 videotestsrc num-buffers=10 ! fakesink - -If there are any leaks, a warning will be raised at the end. - -It is also possible to trace only certain types of objects or mini-objects: - - GST_TRACERS="leaks(GstEvent,GstMessage)" gst-launch-1.0 videotestsrc num-buffers=10 ! fakesink - -This dedicated leaks tracer is much much faster than valgrind since all code is -executed natively instead of being instrumented. This makes it very suitable -for use on slow machines or embedded devices. It is however limited to certain -types of leaks and won't catch memory leaks when the allocation has been made -via plain old `malloc()` or `g_malloc()` or other means. It will also not trace -non-GstObject GObjects. - -The goal is to enable leak tracing on GStreamer's Continuous-Integration and -testing system, both for the regular unit tests (make check) and media tests -(gst-validate), so that accidental leaks in common code paths can be detected -and fixed quickly. - -For more information about the new tracer, check out Guillaume Desmottes's -["Tracking Memory Leaks"][leaks-talk] talk or his [blog post][leaks-blog] about -the topic. - -[leaks-talk]: https://gstconf.ubicast.tv/videos/tracking-memory-leaks/ -[leaks-blog]: https://blog.desmottes.be/?post/2016/06/20/GStreamer-leaks-tracer - -### GES and NLE changes - -- Clip priorities are now handled by the layers, and the GESTimelineElement - priority property is now deprecated and unused -- Enhanced (de)interlacing support to always use the `deinterlace` element - and expose needed properties to users -- Allow reusing clips children after removing the clip from a layer -- We are now testing many more rendering formats in the gst-validate - test suite, and failures have been fixed. -- Also many bugs have been fixed in this cycle! - -### GStreamer validate changes - -This cycle has been focused on making GstValidate more than just a validating -tool, but also a tool to help developers debug their GStreamer issues. When -reporting issues, we try to gather as much information as possible and expose -it to end users in a useful way. For an example of such enhancements, check out -Thibault Saunier's [blog post](improving-debugging-gstreamer-validate) about -the new Not Negotiated Error reporting mechanism. - -Playbin3 support has been added so we can run validate tests with `playbin3` -instead of playbin. - -We are now able to properly communicate between `gst-validate-launcher` and -launched subprocesses with actual IPC between them. That has enabled the test -launcher to handle failing tests specifying the exact expected issue(s). - -[improving-debugging-gstreamer-validate]: https://blogs.s-osg.org/improving-debugging-gstreamer-validate/ - -### gst-libav changes - -gst-libav uses the recently released ffmpeg 3.2 now, which brings a lot of -improvements and bugfixes from the ffmpeg team in addition to various new -codec mappings on the GStreamer side and quite a few bugfixes to the GStreamer -integration to make it more robust. - -## Build and Dependencies - -### Experimental support for Meson as build system - -#### Overview - -We have have added support for building GStreamer using the -[Meson build system][meson]. This is currently experimental, but should work -fine at least on Linux using the gcc or clang toolchains and on Windows using -the MingW or MSVC toolchains. - -Autotools remains the primary build system for the time being, but we hope to -someday replace it and will steadily work towards that goal. - -More information about the background and implications of all this and where -we're hoping to go in future with this can be found in [Tim's mail][meson-mail] -to the gstreamer-devel mailing list. - -For more information on Meson check out [these videos][meson-videos] and also -the [Meson talk][meson-gstconf] at the GStreamer Conference. - -Immediate benefits for Linux users are faster builds and rebuilds. At the time -of writing the Meson build of GStreamer is used by default in GNOME's jhbuild -system. - -The Meson build currently still lacks many of the fine-grained configuration -options to enable/disable specific plugins. These will be added back in due -course. - -Note: The meson build files are not distributed in the source tarballs, you will -need to get GStreamer from git if you want try it out. - -[meson]: http://mesonbuild.com/ -[meson-mail]: https://lists.freedesktop.org/archives/gstreamer-devel/2016-September/060231.html -[meson-videos]: http://mesonbuild.com/videos.html -[meson-gstconf]: https://gstconf.ubicast.tv/videos/gstreamer-development-on-windows-ans-faster-builds-everywhere-with-meson/ - -#### Windows Visual Studio toolchain support - -Windows users might appreciate being able to build GStreamer using the MSVC -toolchain, which is not possible using autotools. This means that it will be -possible to debug GStreamer and applications in Visual Studio, for example. -We require VS2015 or newer for this at the moment. - -There are two ways to build GStreamer using the MSVC toolchain: - -1. Using the MSVC command-line tools (`cl.exe` etc.) via Meson's "ninja" backend. -2. Letting Meson's "vs2015" backend generate Visual Studio project files that - can be opened in Visual Studio and compiled from there. - -This is currently only for adventurous souls though. All the bits are in place, -but support for all of this has not been merged into GStreamer's cerbero build -tool yet at the time of writing. This will hopefully happen in the next cycle, -but for now this means that those wishing to compile GStreamer with MSVC will -have to get their hands dirty. - -There are also no binary SDK builds using the MSVC toolchain yet. - -For more information on GStreamer builds using Meson and the Windows toolchain -check out Nirbheek Chauhan's blog post ["Building and developing GStreamer using Visual Studio"][msvc-blog]. - -[msvc-blog]: http://blog.nirbheek.in/2016/07/building-and-developing-gstreamer-using.html - -### Dependencies - -#### gstreamer - -libunwind was added as an optional dependency. It is used only for debugging -and tracing purposes. - -The `opencv` plugin in gst-plugins-bad can now be built against OpenCV -version 3.1, previously only 2.3-2.5 were supported. - -#### gst-plugins-ugly - -- `mpeg2dec` now requires at least libmpeg2 0.5.1 (from 2008). - -#### gst-plugins-bad - -- `gltransformation` now requires at least graphene 1.4.0. - -- `lv2` now plugin requires at least lilv 0.16 instead of slv2. - -### Packaging notes - -Packagers please note that the `gst/gstconfig.h` public header file in the -GStreamer core library moved back from being an architecture dependent include -to being architecture independent, and thus it is no longer installed into -`$(libdir)/gstreamer-1.0/include/gst` but into the normal include directory -where it lives happily ever after with all the other public header files. The -reason for this is that we now check whether the target supports unaligned -memory access based on predefined compiler macros at compile time instead of -checking it at configure time. - -## Platform-specific improvements - -### Android - -#### New universal binaries for all supported ABIs - -We now provide a "universal" tarball to allow building apps against all the -architectures currently supported (x86, x86-64, armeabi, armeabi-v7a, -armeabi-v8a). This is needed for building with recent versions of the Android -NDK which defaults to building against all supported ABIs. Use [the Android -player example][android-player-example-build] as a reference for the required -changes. - -[android-player-example-build]: https://cgit.freedesktop.org/gstreamer/gst-examples/commit/playback/player/android?id=a5cdde9119f038a1eb365aca20faa9741a38e788 - -#### Miscellaneous - -- New `ahssrc` element that allows reading the hardware sensors, e.g. compass - or accelerometer. - -### macOS (OS/X) and iOS - -- Support for querying available devices on OS/X via the GstDeviceProvider - API was added. -- It is now possible to create OpenGL|ES 3.x contexts on iOS and use them in - combination with the VideoToolbox based decoder element. -- many OpenGL/GLES improvements, see OpenGL section above - -### Windows - -- gstconfig.h: Always use dllexport/import on Windows with MSVC -- Miscellaneous fixes to make libs and plugins compile with the MVSC toolchain -- MSVC toolchain support (see Meson section above for more details) - -## New Modules for Documentation, Examples, Meson Build - -Three new git modules have been added recently: - -### gst-docs - -This is a new module where we will maintain documentation in the markdown -format. - -It contains the former gstreamer.com SDK tutorials which have kindly been made -available by Fluendo under a Creative Commons license. The tutorials have been -reviewed and updated for GStreamer 1.x and will be available as part of the -[official GStreamer documentation][doc] going forward. The old gstreamer.com -site will then be shut down with redirects pointing to the updated tutorials. - -Some of the existing docbook XML-formatted documentation from the GStreamer -core module such as the *Application Development Manual* and the *Plugin -Writer's Guide* have been converted to markdown as well and will be maintained -in the gst-docs module in future. They will be removed from the GStreamer core -module in the next cycle. - -This is just the beginning. Our goal is to provide a more cohesive documentation -experience for our users going forward, and easier to create and maintain -documentation for developers. There is a lot more work to do, get in touch if -you want to help out. - -If you encounter any problems or spot any omissions or outdated content in the -new documentation, please [file a bug in bugzilla][doc-bug] to let us know. - -We will probably release gst-docs as a separate tarball for distributions to -package in the next cycle. - -[doc]: http://gstreamer.freedesktop.org/documentation/ -[doc-bug]: https://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer&component=documentation - -### gst-examples - -A new [module][examples-git] has been added for examples. It does not contain -much yet, currently it only contains a small [http-launch][http-launch] utility -that serves a pipeline over http as well as various [GstPlayer playback frontends][puis] -for Android, iOS, Gtk+ and Qt. - -More examples will be added over time. The examples in this repository should -be more useful and more substantial than most of the examples we ship as part -of our other modules, and also written in a way that makes them good example -code. If you have ideas for examples, let us know. - -No decision has been made yet if this module will be released and/or packaged. -It probably makes sense to do so though. - -[examples-git]: https://cgit.freedesktop.org/gstreamer/gst-examples/tree/ -[http-launch]: https://cgit.freedesktop.org/gstreamer/gst-examples/tree/network/http-launch/ -[puis]: https://cgit.freedesktop.org/gstreamer/gst-examples/tree/playback/player - -### gst-build - -[gst-build][gst-build-git] is a new meta module to build GStreamer using the -new Meson build system. This module is not required to build GStreamer with -Meson, it is merely for convenience and aims to provide a development setup -similar to the existing `gst-uninstalled` setup. - -gst-build makes use of Meson's [subproject feature][meson-subprojects] and sets -up the various GStreamer modules as subprojects, so they can all be updated and -built in parallel. - -This module is still very new and highly experimental. It should work at least -on Linux and Windows (OS/X needs some build fixes). Let us know of any issues -you encounter by popping into the `#gstreamer` IRC channel or by -[filing a bug][gst-build-bug]. - -This module will probably not be released or packaged (does not really make sense). - -[gst-build-git]: https://cgit.freedesktop.org/gstreamer/gst-build/tree/ -[gst-build-bug]: https://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer&component=gst-build -[meson-subprojects]: https://github.com/mesonbuild/meson/wiki/Subprojects - -## Contributors - -Aaron Boxer, Aleix Conchillo Flaqué, Alessandro Decina, Alexandru Băluț, Alex -Ashley, Alex-P. Natsios, Alistair Buxton, Allen Zhang, Andreas Naumann, Andrew -Eikum, Andy Devar, Anthony G. Basile, Arjen Veenhuizen, Arnaud Vrac, Artem -Martynovich, Arun Raghavan, Aurélien Zanelli, Barun Kumar Singh, Bernhard -Miller, Brad Lackey, Branko Subasic, Carlos Garcia Campos, Carlos Rafael -Giani, Christoffer Stengren, Daiki Ueno, Damian Ziobro, Danilo Cesar Lemes de -Paula, David Buchmann, Dimitrios Katsaros, Duncan Palmer, Edward Hervey, -Emmanuel Poitier, Enrico Jorns, Enrique Ocaña González, Fabrice Bellet, -Florian Zwoch, Florin Apostol, Francisco Velazquez, Frédéric Bertolus, Fredrik -Fornwall, Gaurav Gupta, George Kiagiadakis, Georg Lippitsch, Göran Jönsson, -Graham Leggett, Gregoire Gentil, Guillaume Desmottes, Gwang Yoon Hwang, Haakon -Sporsheim, Haihua Hu, Havard Graff, Heinrich Fink, Hoonhee Lee, Hyunjun Ko, -Iain Lane, Ian, Ian Jamison, Jagyum Koo, Jake Foytik, Jakub Adam, Jan -Alexander Steffens (heftig), Jan Schmidt, Javier Martinez Canillas, Jerome -Laheurte, Jesper Larsen, Jie Jiang, Jihae Yi, Jimmy Ohn, Jinwoo Ahn, Joakim -Johansson, Joan Pau Beltran, Jonas Holmberg, Jonathan Matthew, Jonathan Roy, -Josep Torra, Julien Isorce, Jun Ji, Jürgen Slowack, Justin Kim, Kazunori -Kobayashi, Kieran Bingham, Kipp Cannon, Koop Mast, Kouhei Sutou, Kseniia, Kyle -Schwarz, Kyungyong Kim, Linus Svensson, Luis de Bethencourt, Marcin Kolny, -Marcin Lewandowski, Marianna Smidth Buschle, Mario Sanchez Prada, Mark -Combellack, Mark Nauwelaerts, Martin Kelly, Matej Knopp, Mathieu Duponchelle, -Mats Lindestam, Matthew Gruenke, Matthew Waters, Michael Olbrich, Michal Lazo, -Miguel París Díaz, Mikhail Fludkov, Minjae Kim, Mohan R, Munez, Nicola Murino, -Nicolas Dufresne, Nicolas Huet, Nikita Bobkov, Nirbheek Chauhan, Olivier -Crête, Paolo Pettinato, Patricia Muscalu, Paulo Neves, Peng Liu, Peter -Seiderer, Philippe Normand, Philippe Renon, Philipp Zabel, Pierre Lamot, Piotr -Drąg, Prashant Gotarne, Raffaele Rossi, Ray Strode, Reynaldo H. Verdejo -Pinochet, Santiago Carot-Nemesio, Scott D Phillips, Sebastian Dröge, Sebastian -Rasmussen, Sergei Saveliev, Sergey Borovkov, Sergey Mamonov, Sergio Torres -Soldado, Seungha Yang, sezero, Song Bing, Sreerenj Balachandran, Stefan Sauer, -Stephen, Steven Hoving, Stian Selnes, Thiago Santos, Thibault Saunier, Thijs -Vermeir, Thomas Bluemel, Thomas Jones, Thomas Klausner, Thomas Scheuermann, -Tim-Philipp Müller, Ting-Wei Lan, Tom Schoonjans, Ursula Maplehurst, Vanessa -Chipirras Navalon, Víctor Manuel Jáquez Leal, Vincent Penquerc'h, Vineeth TM, -Vivia Nikolaidou, Vootele Vesterblom, Wang Xin-yu (王昕宇), William Manley, -Wim Taymans, Wonchul Lee, Xabier Rodriguez Calvar, Xavier Claessens, xlazom00, -Yann Jouanin, Zaheer Abbas Merali - -... and many others who have contributed bug reports, translations, sent -suggestions or helped testing. - -## Bugs fixed in 1.10 - -More than [750 bugs][bugs-fixed-in-1.10] have been fixed during -the development of 1.10. - -This list does not include issues that have been cherry-picked into the -stable 1.8 branch and fixed there as well, all fixes that ended up in the -1.8 branch are also included in 1.10. - -This list also does not include issues that have been fixed without a bug -report in bugzilla, so the actual number of fixes is much higher. - -[bugs-fixed-in-1.10]: https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&classification=Platform&limit=0&list_id=164074&order=bug_id&product=GStreamer&query_format=advanced&resolution=FIXED&target_milestone=1.8.1&target_milestone=1.8.2&target_milestone=1.8.3&target_milestone=1.8.4&target_milestone=1.9.1&target_milestone=1.9.2&target_milestone=1.9.90&target_milestone=1.10.0 - -## Stable 1.10 branch - -After the 1.10.0 release there will be several 1.10.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.10.x bug-fix releases will be made from the git 1.10 branch, -which is a stable branch. - -### 1.10.0 - -1.10.0 was released on 1st November 2016. - -## Known Issues - -- iOS builds with iOS 6 SDK and old C++ STL. You need to select iOS 6 instead - of 7 or 8 in your projects settings to be able to link applications. - [Bug #766366](https://bugzilla.gnome.org/show_bug.cgi?id=766366) -- Code signing for Apple platforms has some problems currently, requiring - manual work to get your application signed. [Bug #771860](https://bugzilla.gnome.org/show_bug.cgi?id=771860) -- Building applications with Android NDK r13 on Windows does not work. Other - platforms and earlier/later versions of the NDK are not affected. - [Bug #772842](https://bugzilla.gnome.org/show_bug.cgi?id=772842) -- The new leaks tracer may deadlock the application (or exhibit other undefined - behaviour) when `SIGUSR` handling is enabled via the `GST_LEAKS_TRACER_SIG` - environment variable. [Bug #770373](https://bugzilla.gnome.org/show_bug.cgi?id=770373) -- vp8enc crashes on 32 bit Windows, but was working fine in 1.6. 64 bit Windows is unaffected. - [Bug #763663](https://bugzilla.gnome.org/show_bug.cgi?id=763663) - -## Schedule for 1.12 - -Our next major feature release will be 1.12, and 1.11 will be the unstable -development version leading up to the stable 1.12 release. The development -of 1.11/1.12 will happen in the git master branch. - -The plan for the 1.12 development cycle is yet to be confirmed, but it is -expected that feature freeze will be around early/mid-January, -followed by several 1.11 pre-releases and the new 1.12 stable release -in March. - -1.12 will be backwards-compatible to the stable 1.10, 1.8, 1.6, 1.4, 1.2 and -1.0 release series. - -- - - - -*These release notes have been prepared by Olivier Crête, Sebastian Dröge, -Nicolas Dufresne, Edward Hervey, Víctor Manuel Jáquez Leal, Tim-Philipp -Müller, Reynaldo H. Verdejo Pinochet, Arun Raghavan, Thibault Saunier, -Jan Schmidt, Wim Taymans, Matthew Waters* - -*License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)* - +This is GStreamer 1.11.1. diff --git a/configure.ac b/configure.ac index b8124a6da8..ce1424a9ce 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [11]) -m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [1]) +m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1100]) +m4_define([gst_vaapi_lt_current], [1101]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1100]) +m4_define([gst_vaapi_lt_age], [1101]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.11.0.1]) -m4_define([gst_plugins_base_version], [1.11.0.1]) -m4_define([gst_plugins_bad_version], [1.11.0.1]) +m4_define([gst_version], [1.11.1]) +m4_define([gst_plugins_base_version], [1.11.1]) +m4_define([gst_plugins_bad_version], [1.11.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 2592dd0601..d51583bc0b 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.11.1 + master + + 2017-01-12 + + + + 1.10.0 From 4807a85e82e09e314ba14df4353f13004f9b1381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 12 Jan 2017 16:33:13 +0200 Subject: [PATCH 2653/3781] Back to development --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index ce1424a9ce..b6d269c9a5 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [11]) m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -24,9 +24,9 @@ m4_define([gst_vaapi_lt_age], [1101]) m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.11.1]) -m4_define([gst_plugins_base_version], [1.11.1]) -m4_define([gst_plugins_bad_version], [1.11.1]) +m4_define([gst_version], [1.11.1.1]) +m4_define([gst_plugins_base_version], [1.11.1.1]) +m4_define([gst_plugins_bad_version], [1.11.1.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) From 86548296280a4e3f640799faefed2cee073e33ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 13 Jan 2017 21:26:15 +0100 Subject: [PATCH 2654/3781] vaapidecode: update internal decoder sink caps When a new sink caps arrive the internal decoder state is updated and, if it is, request a downstream renegotiation. Previously, when new caps arrived the whole decoder where destroyed and recreated. Now, if the caps are compatible or has the same codec, the internal decoder is kept, but a downstream renegotiation is requested. https://bugzilla.gnome.org/show_bug.cgi?id=776979 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 49 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder.h | 3 ++ gst/vaapi/gstvaapidecode.c | 22 +++++-------- gst/vaapi/gstvaapidecode.h | 3 +- 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 9a8cda2a84..6af1372fdd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -418,6 +418,8 @@ set_caps (GstVaapiDecoder * decoder, const GstCaps * caps) if (!gst_video_info_from_caps (&codec_state->info, caps)) return FALSE; + if (codec_state->caps) + gst_caps_unref (codec_state->caps); codec_state->caps = gst_caps_copy (caps); v_codec_data = gst_structure_get_value (structure, "codec_data"); @@ -1085,3 +1087,50 @@ gst_vaapi_decoder_get_surface_formats (GstVaapiDecoder * decoder) return gst_vaapi_context_get_surface_formats (decoder->context); return NULL; } + +/** + * gst_vaapi_decoder_update_caps: + * @decoder: a #GstVaapiDecoder + * @caps: a #GstCaps + * + * If @caps is compatible with the current caps, or they have the same + * codec, the caps are updated internally. + * + * This method will not call codec_state_changed() callback, since + * this function is intended to run sync and during the set_format() + * vmethod. + * + * Returns: %TRUE if the caps were updated internally. + **/ +gboolean +gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps) +{ + GstCaps *decoder_caps; + GstVaapiProfile profile; + GstVaapiCodec codec; + + g_return_val_if_fail (decoder != NULL, FALSE); + g_return_val_if_fail (caps != NULL, FALSE); + + decoder_caps = get_caps (decoder); + if (!decoder_caps) + return FALSE; + + if (gst_caps_is_always_compatible (caps, decoder_caps)) { + set_caps (decoder, caps); + return TRUE; + } + + profile = gst_vaapi_profile_from_caps (caps); + if (profile == GST_VAAPI_PROFILE_UNKNOWN) + return FALSE; + codec = gst_vaapi_profile_get_codec (profile); + if (codec == 0) + return FALSE; + if (codec == decoder->codec) { + set_caps (decoder, caps); + return TRUE; + } + + return FALSE; +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 4b75f2d2da..a8ca5aa9ec 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -135,6 +135,9 @@ gst_vaapi_decoder_flush (GstVaapiDecoder * decoder); GstVaapiDecoderStatus gst_vaapi_decoder_check_status (GstVaapiDecoder * decoder); +gboolean +gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps); + G_END_DECLS #endif /* GST_VAAPI_DECODER_H */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6b490176b2..b7570025e4 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -134,7 +134,8 @@ static gboolean gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, static gboolean gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode, const GstVideoCodecState * new_state); -/* get invoked only if actural VASurface size (not the cropped values) changed */ +/* invoked if actual VASurface size (not the cropped values) + * changed */ static void gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder, const GstVideoCodecState * codec_state, gpointer user_data) @@ -511,8 +512,9 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, caps_renegotiate = is_display_resolution_changed (decode, crop_rect); if (gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec)) - || alloc_renegotiate || caps_renegotiate) { + || alloc_renegotiate || caps_renegotiate || decode->do_renego) { + g_atomic_int_set (&decode->do_renego, FALSE); if (!gst_vaapidecode_negotiate (decode)) return GST_FLOW_ERROR; } @@ -878,7 +880,6 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) gst_vaapi_decoder_set_codec_state_changed_func (decode->decoder, gst_vaapi_decoder_state_changed, decode); - decode->decoder_caps = gst_caps_ref (caps); return TRUE; } @@ -915,7 +916,6 @@ gst_vaapidecode_destroy (GstVaapiDecode * decode) gst_vaapidecode_purge (decode); gst_vaapi_decoder_replace (&decode->decoder, NULL); - gst_caps_replace (&decode->decoder_caps, NULL); gst_vaapidecode_release (gst_object_ref (decode)); } @@ -924,17 +924,14 @@ static gboolean gst_vaapidecode_reset_full (GstVaapiDecode * decode, GstCaps * caps, gboolean hard) { - GstVaapiCodec codec; - /* Reset tracked frame size */ decode->current_frame_size = 0; - if (!hard && decode->decoder && decode->decoder_caps) { - if (gst_caps_is_always_compatible (caps, decode->decoder_caps)) - return TRUE; - codec = gst_vaapi_codec_from_caps (caps); - if (codec == gst_vaapi_decoder_get_codec (decode->decoder)) + if (!hard && decode->decoder) { + if (gst_vaapi_decoder_update_caps (decode->decoder, caps)) { + g_atomic_int_set (&decode->do_renego, TRUE); return TRUE; + } } gst_vaapidecode_destroy (decode); @@ -1009,7 +1006,6 @@ gst_vaapidecode_stop (GstVideoDecoder * vdec) gst_vaapidecode_purge (decode); gst_vaapi_decode_input_state_replace (decode, NULL); gst_vaapi_decoder_replace (&decode->decoder, NULL); - gst_caps_replace (&decode->decoder_caps, NULL); gst_caps_replace (&decode->sinkpad_caps, NULL); gst_caps_replace (&decode->srcpad_caps, NULL); return TRUE; @@ -1049,7 +1045,7 @@ gst_vaapidecode_set_format (GstVideoDecoder * vdec, GstVideoCodecState * state) return FALSE; if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) return FALSE; - if (!gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, TRUE)) + if (!gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, FALSE)) return FALSE; return TRUE; diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index cb2a2f1d81..8c841901dd 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -45,7 +45,6 @@ struct _GstVaapiDecode { GstVaapiDecoder *decoder; GMutex surface_ready_mutex; GCond surface_ready; - GstCaps *decoder_caps; GstCaps *allowed_sinkpad_caps; GstCaps *allowed_srcpad_caps; guint current_frame_size; @@ -56,6 +55,8 @@ struct _GstVaapiDecode { GstVideoCodecState *input_state; GstSegment in_segment; + + gboolean do_renego; }; struct _GstVaapiDecodeClass { From 7fd41c42639d0603015bf467d9fb8b1eef15c078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 18 Jan 2017 17:20:21 +0100 Subject: [PATCH 2655/3781] plugins: avoid log flood when activating pool Every time a new buffer is allocated, the pool is activated. This doesn't impact in performance since gst_buffer_pool_set_active() checks the current state of the pool. Nonetheless it logs out a message if the state is the same, and it floods the logging subsystem if it is enabled. To avoid this log flooding first the pool state is checked before changing it. --- gst/vaapi/gstvaapipluginbase.c | 3 ++- gst/vaapi/gstvaapipostproc.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 7e7a4438e4..d37300e680 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -989,7 +989,8 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, if (!plugin->sinkpad_buffer_pool) goto error_no_pool; - if (!gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, TRUE)) + if (!gst_buffer_pool_is_active (plugin->sinkpad_buffer_pool) && + !gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, TRUE)) goto error_active_pool; outbuf = NULL; diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index e2afea8c8d..d59496af05 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -362,7 +362,8 @@ create_output_buffer (GstVaapiPostproc * postproc) g_return_val_if_fail (pool != NULL, NULL); - if (!gst_buffer_pool_set_active (pool, TRUE)) + if (!gst_buffer_pool_is_active (pool) && + !gst_buffer_pool_set_active (pool, TRUE)) goto error_activate_pool; outbuf = NULL; From f5360282bc5428445b3c3a4661bce2ba4a42af0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 12 Jan 2017 19:54:41 +0100 Subject: [PATCH 2656/3781] vaapisink: don't use member variable outside lock Thus a race condition segfault is avoided. Original-patch-by: Matt Staples https://bugzilla.gnome.org/show_bug.cgi?id=777146 --- gst/vaapi/gstvaapisink.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 7c8caff647..319d9695b2 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -574,10 +574,8 @@ gst_vaapisink_video_overlay_expose (GstVideoOverlay * overlay) { GstVaapiSink *const sink = GST_VAAPISINK (overlay); - if (sink->video_buffer) { - gst_vaapisink_reconfigure_window (sink); - gst_vaapisink_show_frame (GST_VIDEO_SINK_CAST (sink), sink->video_buffer); - } + gst_vaapisink_reconfigure_window (sink); + gst_vaapisink_show_frame (GST_VIDEO_SINK_CAST (sink), NULL); } static void @@ -1372,12 +1370,20 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) GstVaapiSurfaceProxy *proxy; GstVaapiSurface *surface; GstBuffer *buffer; + GstBuffer *old_buf; guint flags; GstVaapiRectangle *surface_rect = NULL; GstVaapiRectangle tmp_rect; GstFlowReturn ret; gint32 view_id; + if (!src_buffer) { + if (sink->video_buffer) + src_buffer = sink->video_buffer; + else + return GST_FLOW_OK; + } + GstVideoCropMeta *const crop_meta = gst_buffer_get_video_crop_meta (src_buffer); if (crop_meta) { @@ -1448,9 +1454,13 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) g_signal_emit (sink, gst_vaapisink_signals[HANDOFF_SIGNAL], 0, buffer); /* Retain VA surface until the next one is displayed */ - /* Need to release the lock for the duration, otherwise a deadlock is possible */ + old_buf = sink->video_buffer; + sink->video_buffer = gst_buffer_ref (buffer); + /* Need to release the lock while releasing old buffer, otherwise a + * deadlock is possible */ gst_vaapi_display_unlock (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); - gst_buffer_replace (&sink->video_buffer, buffer); + if (old_buf) + gst_buffer_unref (old_buf); gst_vaapi_display_lock (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); ret = GST_FLOW_OK; From 42df9ba98cc2ab0ff4d82887b96300c8682abf9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 Jan 2017 16:10:32 +0100 Subject: [PATCH 2657/3781] vaapisink: fix gcc compiler warning warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] --- gst/vaapi/gstvaapisink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 319d9695b2..7c747a1536 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1376,6 +1376,7 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) GstVaapiRectangle tmp_rect; GstFlowReturn ret; gint32 view_id; + GstVideoCropMeta *crop_meta; if (!src_buffer) { if (sink->video_buffer) @@ -1384,8 +1385,7 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) return GST_FLOW_OK; } - GstVideoCropMeta *const crop_meta = - gst_buffer_get_video_crop_meta (src_buffer); + crop_meta = gst_buffer_get_video_crop_meta (src_buffer); if (crop_meta) { surface_rect = &tmp_rect; surface_rect->x = crop_meta->x; From d8abbd7652874571d24b3a7151b351330614c1db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 Jan 2017 19:00:24 +0100 Subject: [PATCH 2658/3781] vaapipostproc: set interlace mode if the vaapipostproc is configured to not do deinterlacing, the interlace-mode in the src caps should be the same as the input caps. https://bugzilla.gnome.org/show_bug.cgi?id=777395 --- gst/vaapi/gstvaapipostproc.c | 2 +- gst/vaapi/gstvaapipostprocutil.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index d59496af05..569119873d 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -68,7 +68,7 @@ static const char gst_vaapipostproc_src_caps_str[] = GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS "; " #endif GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " - GST_CAPS_INTERLACED_FALSE; + GST_CAPS_INTERLACED_MODES; /* *INDENT-ON* */ /* *INDENT-OFF* */ diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 956bd84d4d..d1bdd88920 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -585,6 +585,28 @@ _set_colorimetry (GstVaapiPostproc * postproc, GstVideoFormat format, return TRUE; } +static gboolean +_set_interlace_mode (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, + GstStructure * outs) +{ + const gchar *interlace_mode = NULL; + + if (is_deinterlace_enabled (postproc, vinfo)) { + interlace_mode = "progressive"; + } else { + interlace_mode = + gst_video_interlace_mode_to_string (GST_VIDEO_INFO_INTERLACE_MODE + (vinfo)); + } + + if (!interlace_mode) + return FALSE; + + gst_structure_set (outs, "interlace-mode", G_TYPE_STRING, interlace_mode, + NULL); + return TRUE; +} + static gboolean _set_preferred_format (GstStructure * outs, GstVideoFormat format) { @@ -649,6 +671,9 @@ _get_preferred_caps (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, if (f == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) _set_colorimetry (postproc, format, structure); + if (!_set_interlace_mode (postproc, vinfo, structure)) + goto interlace_mode_failed; + outcaps = gst_caps_new_empty (); gst_caps_append_structure_full (outcaps, structure, gst_caps_features_copy (features)); @@ -673,6 +698,11 @@ invalid_caps: GST_WARNING_OBJECT (postproc, "No valid src caps found"); return NULL; } +interlace_mode_failed: + { + GST_WARNING_OBJECT (postproc, "Invalid sink caps interlace mode"); + return NULL; + } } /** From 26fa4df958ea9480ffb76f78b7492ab387bb2861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 Jan 2017 19:57:52 +0100 Subject: [PATCH 2659/3781] vaapipostproc: use sink caps par if not requested Use the sink caps pixel-aspect-ratio to fixate the src caps, if it is not already set. https://bugzilla.gnome.org/show_bug.cgi?id=777395 --- gst/vaapi/gstvaapipostprocutil.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index d1bdd88920..1780df3f1f 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -160,11 +160,11 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, to_par = gst_structure_get_value (outs, "pixel-aspect-ratio"); if (!to_par) { g_value_init (&tpar, GST_TYPE_FRACTION); - gst_value_set_fraction (&tpar, 1, 1); + gst_value_set_fraction (&tpar, GST_VIDEO_INFO_PAR_N (vinfo), + GST_VIDEO_INFO_PAR_D (vinfo)); to_par = &tpar; - gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, - NULL); + gst_structure_set_value (outs, "pixel-aspect-ratio", &tpar); } /* we have both PAR but they might not be fixated */ From 43d4f0bfb5995faea0d49164e31b2a632ac6408e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 2 Aug 2016 15:48:25 +0200 Subject: [PATCH 2660/3781] vaapivideocontext: context type can be rejected Instead of calling g_return_val_if_fail() to check the context type, we should use a normal conditional, since it is possible that other context types can arrive and try to be assigned. Otherwise a critical log message is printed. This happens when we use playbin3 with vaapipostproc as video-filter. https://bugzilla.gnome.org/show_bug.cgi?id=777409 --- gst/vaapi/gstvaapivideocontext.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 4d59f2fc7d..5e9f9b7072 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -73,10 +73,13 @@ gst_vaapi_video_context_get_display (GstContext * context, GstVaapiDisplay ** display_ptr) { const GstStructure *structure; + const gchar *type; g_return_val_if_fail (GST_IS_CONTEXT (context), FALSE); - g_return_val_if_fail (g_strcmp0 (gst_context_get_context_type (context), - GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) == 0, FALSE); + + type = gst_context_get_context_type (context); + if (g_strcmp0 (type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME)) + return FALSE; structure = gst_context_get_structure (context); return gst_structure_get (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, From 0968ce468de9e927593be0c2f8686017844eacf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Jan 2017 12:02:56 +0100 Subject: [PATCH 2661/3781] plugins: create a GL context on certain conditions If a GstVaapiDisplay is not found in the GStreamer context sharing, then VAAPI elements look for a local GstGLContext in gst context sharing mechanism ('gst.gl.local.context'). If this GstGLContext not found either then, only the VAAPI decoders and the VAAPI post-processor, will try to instantiate a new GstGLContext. If a valid GstGLContext is received, then a new GstVaapiDisplay will be instantiated with the platform, API and windowing specified by the instantiated GstGLContext. Original-Patch-By: Matt Fischer https://bugzilla.gnome.org/show_bug.cgi?id=777409 --- gst/vaapi/gstvaapipluginbase.c | 76 +++++++++++++++++++++++++++------- gst/vaapi/gstvaapipluginbase.h | 6 +++ gst/vaapi/gstvaapipluginutil.c | 28 +++++++++++++ 3 files changed, 95 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index d37300e680..d951aa4e65 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -30,6 +30,9 @@ #include "gstvaapivideocontext.h" #include "gstvaapivideometa.h" #include "gstvaapivideobufferpool.h" +#if USE_GST_GL_HELPERS +# include +#endif /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) @@ -75,6 +78,12 @@ gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, if (gst_vaapi_video_context_get_display (context, &display)) plugin_set_display (plugin, display); + +#if USE_GST_GL_HELPERS + gst_gl_handle_set_context (GST_ELEMENT_CAST (plugin), context, + (GstGLDisplay **) & plugin->gl_display, + (GstGLContext **) & plugin->gl_other_context); +#endif } void @@ -215,17 +224,6 @@ plugin_reset_texture_map (GstVaapiPluginBase * plugin) gst_vaapi_display_reset_texture_map (plugin->display); } -static void -gst_vaapi_plugin_base_find_gl_context (GstVaapiPluginBase * plugin) -{ - GstObject *gl_context; - - if (!gst_vaapi_find_gl_local_context (GST_ELEMENT_CAST (plugin), &gl_context)) - return; - gst_vaapi_plugin_base_set_gl_context (plugin, gl_context); - gst_object_unref (gl_context); -} - void gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) { @@ -292,6 +290,8 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) gst_vaapi_display_replace (&plugin->display, NULL); gst_object_replace (&plugin->gl_context, NULL); + gst_object_replace (&plugin->gl_display, NULL); + gst_object_replace (&plugin->gl_other_context, NULL); gst_caps_replace (&plugin->sinkpad_caps, NULL); gst_video_info_init (&plugin->sinkpad_info); @@ -386,10 +386,6 @@ gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) return TRUE; gst_vaapi_display_replace (&plugin->display, NULL); - /* Query for a local GstGL context. If it's found, it will be used - * to create the VA display */ - gst_vaapi_plugin_base_find_gl_context (plugin); - if (!gst_vaapi_ensure_display (GST_ELEMENT (plugin), plugin->display_type_req)) return FALSE; @@ -1121,6 +1117,56 @@ gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, #endif } +/** + * gst_vaapi_plugin_base_create_gl_context: + * @plugin: a #GstVaapiPluginBase + * + * It queries downstream and upstream for a #GstGLDisplay and a other + * #GstGLContext. If not found, a new #GstGLDisplay and #GstGLContext + * are created, if it is possible. + * + * Returns: (transfer full) a new created #GstGLContext or %NULL + **/ +GstObject * +gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin) +{ +#if USE_GST_GL_HELPERS + GstGLContext *gl_other_context, *gl_context = NULL; + GstGLDisplay *gl_display; + + gst_gl_ensure_element_data (plugin, (GstGLDisplay **) & plugin->gl_display, + (GstGLContext **) & plugin->gl_other_context); + + gl_display = (GstGLDisplay *) plugin->gl_display; + if (!gl_display || + gst_gl_display_get_handle_type (gl_display) == GST_GL_DISPLAY_TYPE_ANY) { + gst_object_replace (&plugin->gl_display, NULL); + gst_object_replace (&plugin->gl_other_context, NULL); + return NULL; + } + gl_other_context = (GstGLContext *) plugin->gl_other_context; + + GST_INFO_OBJECT (plugin, "creating a new GstGL context"); + + GST_OBJECT_LOCK (gl_display); + do { + if (gl_context) + gst_object_unref (gl_context); + gl_context = gst_gl_display_get_gl_context_for_thread (gl_display, NULL); + if (!gl_context) { + if (!gst_gl_display_create_context (gl_display, gl_other_context, + &gl_context, NULL)) + break; + } + } while (!gst_gl_display_add_context (gl_display, gl_context)); + GST_OBJECT_UNLOCK (gl_display); + + return GST_OBJECT_CAST (gl_context); +#else + return NULL; +#endif +} + static gboolean ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) { diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 9526d8ff10..e1db5e72f4 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -140,6 +140,8 @@ struct _GstVaapiPluginBase gchar *display_name; GstObject *gl_context; + GstObject *gl_display; + GstObject *gl_other_context; GstCaps *allowed_raw_caps; GstAllocator *sinkpad_allocator; @@ -236,6 +238,10 @@ void gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, GstObject * object); +G_GNUC_INTERNAL +GstObject * +gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin); + G_GNUC_INTERNAL GstCaps * gst_vaapi_plugin_base_get_allowed_raw_caps (GstVaapiPluginBase * plugin); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 2dcfbdbe50..ec7c36de8b 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -241,6 +241,29 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) return NULL; } +static void +gst_vaapi_find_gl_context (GstElement * element) +{ + GstObject *gl_context; + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); + + /* if the element is vaapisink or any vaapi encoder it doesn't need + * to know a GstGLContext in order to create an appropriate + * GstVaapiDisplay. Let's them to choose their own + * GstVaapiDisplay */ + if (GST_IS_VIDEO_SINK (element) || GST_IS_VIDEO_ENCODER (element)) + return; + + gl_context = NULL; + if (!gst_vaapi_find_gl_local_context (element, &gl_context)) + gl_context = gst_vaapi_plugin_base_create_gl_context (plugin); + + if (gl_context) { + gst_vaapi_plugin_base_set_gl_context (plugin, gl_context); + gst_object_unref (gl_context); + } +} + gboolean gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type) { @@ -255,6 +278,11 @@ gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type) return TRUE; } + /* Query for a local GstGL context. If it's found, it will be used + * to create the VA display */ + if (!plugin->gl_context) + gst_vaapi_find_gl_context (element); + /* If no neighboor, or application not interested, use system default */ if (plugin->gl_context) display = gst_vaapi_create_display_from_gl_context (plugin->gl_context); From c9bd45f05debec8a3fa79a42da72bd8e8bed23e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 27 Jan 2017 12:10:54 +0100 Subject: [PATCH 2662/3781] plugins: handle GL params through context query If the element instantiated the GL display and context, they should handle them too through the context query. https://bugzilla.gnome.org/show_bug.cgi?id=777409 --- gst/vaapi/gstvaapidecode.c | 10 ++++------ gst/vaapi/gstvaapiencode.c | 8 ++++---- gst/vaapi/gstvaapipluginutil.c | 19 +++++++++++++++---- gst/vaapi/gstvaapipluginutil.h | 2 +- gst/vaapi/gstvaapipostproc.c | 6 +++--- gst/vaapi/gstvaapisink.c | 5 ++--- 6 files changed, 29 insertions(+), 21 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b7570025e4..0e606d765d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1197,12 +1197,11 @@ static gboolean gst_vaapidecode_sink_query (GstVideoDecoder * vdec, GstQuery * query) { gboolean ret = TRUE; - GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (decode); + GstElement *const element = GST_ELEMENT (vdec); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CONTEXT:{ - ret = gst_vaapi_handle_context_query (query, plugin->display); + ret = gst_vaapi_handle_context_query (element, query); break; } default:{ @@ -1218,8 +1217,7 @@ static gboolean gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) { gboolean ret = TRUE; - GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (decode); + GstElement *const element = GST_ELEMENT (vdec); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CAPS:{ @@ -1240,7 +1238,7 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) break; } case GST_QUERY_CONTEXT:{ - ret = gst_vaapi_handle_context_query (query, plugin->display); + ret = gst_vaapi_handle_context_query (element, query); break; } default:{ diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 4a7c64fa54..61f0fbe4b6 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -63,11 +63,11 @@ static gboolean gst_vaapiencode_sink_query (GstVideoEncoder * encoder, GstQuery * query) { gboolean ret = TRUE; - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (encoder); + GstElement *const element = GST_ELEMENT (encoder); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CONTEXT: - ret = gst_vaapi_handle_context_query (query, plugin->display); + ret = gst_vaapi_handle_context_query (element, query); break; default: ret = GST_VIDEO_ENCODER_CLASS (gst_vaapiencode_parent_class)->sink_query @@ -82,11 +82,11 @@ static gboolean gst_vaapiencode_src_query (GstVideoEncoder * encoder, GstQuery * query) { gboolean ret = TRUE; - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (encoder); + GstElement *const element = GST_ELEMENT (encoder); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CONTEXT: - ret = gst_vaapi_handle_context_query (query, plugin->display); + ret = gst_vaapi_handle_context_query (element, query); break; default: ret = GST_VIDEO_ENCODER_CLASS (gst_vaapiencode_parent_class)->src_query diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ec7c36de8b..2ac5a1a9d5 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -297,14 +297,25 @@ gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type) } gboolean -gst_vaapi_handle_context_query (GstQuery * query, GstVaapiDisplay * display) +gst_vaapi_handle_context_query (GstElement * element, GstQuery * query) { + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); const gchar *type = NULL; GstContext *context, *old_context; g_return_val_if_fail (query != NULL, FALSE); - if (!display) +#if USE_GST_GL_HELPERS + if (plugin->gl_display && plugin->gl_context && plugin->gl_other_context) { + if (gst_gl_handle_context_query (element, query, + (GstGLDisplay *) plugin->gl_display, + (GstGLContext *) plugin->gl_context, + (GstGLContext *) plugin->gl_other_context)) + return TRUE; + } +#endif + + if (!plugin->display) return FALSE; if (!gst_query_parse_context_type (query, &type)) @@ -316,9 +327,9 @@ gst_vaapi_handle_context_query (GstQuery * query, GstVaapiDisplay * display) gst_query_parse_context (query, &old_context); if (old_context) { context = gst_context_copy (old_context); - gst_vaapi_video_context_set_display (context, display); + gst_vaapi_video_context_set_display (context, plugin->display); } else { - context = gst_vaapi_video_context_new_with_display (display, FALSE); + context = gst_vaapi_video_context_new_with_display (plugin->display, FALSE); } gst_query_set_context (query, context); diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index eb5633bf93..61a833558a 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -35,7 +35,7 @@ gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type); G_GNUC_INTERNAL gboolean -gst_vaapi_handle_context_query (GstQuery * query, GstVaapiDisplay * display); +gst_vaapi_handle_context_query (GstElement * element, GstQuery * query); G_GNUC_INTERNAL gboolean diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 569119873d..60b6960d45 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1334,11 +1334,11 @@ gst_vaapipostproc_query (GstBaseTransform * trans, GstPadDirection direction, GstQuery * query) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + GstElement *const element = GST_ELEMENT (trans); if (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT) { - if (gst_vaapi_handle_context_query (query, - GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc))) { - GST_DEBUG_OBJECT (postproc, "sharing display %p", + if (gst_vaapi_handle_context_query (element, query)) { + GST_DEBUG_OBJECT (postproc, "sharing display %" GST_PTR_FORMAT, GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc)); return TRUE; } diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 7c747a1536..cca71d9f3a 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1520,13 +1520,12 @@ gst_vaapisink_propose_allocation (GstBaseSink * base_sink, GstQuery * query) static gboolean gst_vaapisink_query (GstBaseSink * base_sink, GstQuery * query) { - GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink); - GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (sink); + GstElement *const element = GST_ELEMENT (base_sink); gboolean ret = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CONTEXT: - ret = gst_vaapi_handle_context_query (query, plugin->display); + ret = gst_vaapi_handle_context_query (element, query); break; default: ret = GST_BASE_SINK_CLASS (gst_vaapisink_parent_class)->query (base_sink, From a01c0bc3523f1bd9336200616aa9c8f1d48a558b Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 1 Feb 2017 14:32:45 +0900 Subject: [PATCH 2663/3781] vaapipostproc: set GST_VAAPI_POSTPROC_FLAG_SIZE according to src caps A value of width/height property should be set to out caps, if negotiation had been going properly. So we can use srcpad_info when making decision of scaling. https://bugzilla.gnome.org/show_bug.cgi?id=778010 --- gst/vaapi/gstvaapipostproc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 60b6960d45..dab15bea37 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -982,10 +982,12 @@ gst_vaapipostproc_update_src_caps (GstVaapiPostproc * postproc, GstCaps * caps, postproc->format != DEFAULT_FORMAT) postproc->flags |= GST_VAAPI_POSTPROC_FLAG_FORMAT; - if ((postproc->width || postproc->height) && - postproc->width != GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info) && - postproc->height != GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info)) + if (GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) != + GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info) + && GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) != + GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info)) postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SIZE; + return TRUE; } From 65c16145a59f603b340540eb97fc21aa9ba61ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Nov 2015 18:21:08 +0100 Subject: [PATCH 2664/3781] Revert "vaapidisplay: mark X11 display as compatible with EGL" This reverts commit 200b1baabc066f8a4102f82f539655d588200ec9. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 0597003d8e..e47058d791 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -217,10 +217,6 @@ gst_vaapi_display_type_is_compatible (GstVaapiDisplayType type1, if (type2 == GST_VAAPI_DISPLAY_TYPE_X11) return TRUE; break; - case GST_VAAPI_DISPLAY_TYPE_X11: - if (type2 == GST_VAAPI_DISPLAY_TYPE_EGL) - return TRUE; - break; default: break; } From a5650e8dc3e0424eb391a96a0fc7c871c27c61f3 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 15 Dec 2016 15:59:30 +0900 Subject: [PATCH 2665/3781] libs: utils: return NULL if failed to get surface formats Thus, when generating the allowed caps, the element will throw a warning and it will use its caps template. This behavior might be a bug in the VA driver. https://bugzilla.gnome.org/show_bug.cgi?id=775490 --- gst-libs/gst/vaapi/gstvaapiutils_core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.c b/gst-libs/gst/vaapi/gstvaapiutils_core.c index 42ebaff13a..e1e76b810b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_core.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.c @@ -139,6 +139,11 @@ gst_vaapi_get_surface_formats (GstVaapiDisplay * display, VAConfigID config) g_array_append_val (formats, fmt); } + if (formats->len == 0) { + g_array_unref (formats); + formats = NULL; + } + g_free (surface_attribs); return formats; @@ -149,5 +154,4 @@ error: } #endif return NULL; - } From fbed3c3366da9a544069d2d472949d5f31b63e5d Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:27:03 +0100 Subject: [PATCH 2666/3781] vaapivideomemory: add direction to dmabuf allocator Add GstPadDirection param to gst_vaapi_dmabuf_allocator_new(), thus we later could do different thing when the allocated memory is for upstream or dowstream, as required by VA-API. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapipluginbase.c | 2 +- gst/vaapi/gstvaapivideomemory.c | 6 +++++- gst/vaapi/gstvaapivideomemory.h | 6 +++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index d951aa4e65..f2929db818 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -509,7 +509,7 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) { plugin->sinkpad_allocator = gst_vaapi_dmabuf_allocator_new (plugin->display, &vinfo, - GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); + GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE, GST_PAD_SINK); goto bail; } diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 9945b4b547..ed1fdf757e 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1048,11 +1048,13 @@ gst_vaapi_dmabuf_allocator_init (GstVaapiDmaBufAllocator * allocator) GstAllocator *const base_allocator = GST_ALLOCATOR_CAST (allocator); base_allocator->mem_type = GST_VAAPI_DMABUF_ALLOCATOR_NAME; + allocator->direction = GST_PAD_SINK; } GstAllocator * gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * alloc_info, guint surface_alloc_flags) + const GstVideoInfo * alloc_info, guint surface_alloc_flags, + GstPadDirection direction) { GstVaapiDmaBufAllocator *allocator = NULL; GstVaapiSurface *surface = NULL; @@ -1081,6 +1083,8 @@ gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, gst_allocator_set_vaapi_video_info (base_allocator, &surface_info, surface_alloc_flags); + allocator->direction = direction; + return base_allocator; /* ERRORS */ diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index c95ff3221a..342ca65802 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -243,6 +243,9 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, struct _GstVaapiDmaBufAllocator { GstDmaBufAllocator parent_instance; + + /*< private >*/ + GstPadDirection direction; }; /** @@ -262,7 +265,8 @@ gst_vaapi_dmabuf_allocator_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstAllocator * gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, - const GstVideoInfo * alloc_info, guint surface_alloc_flags); + const GstVideoInfo * alloc_info, guint surface_alloc_flags, + GstPadDirection direction); G_GNUC_INTERNAL const GstVideoInfo * From 69a2406a20335ce045c4c67a9ff98e2c96d143c9 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:01:04 +0100 Subject: [PATCH 2667/3781] libs: bufferproxy: add gst_vaapi_buffer_proxy_release_data() Adds an API to request the user's data release in the buffer proxy. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 19 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapibufferproxy.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index a9b3485806..75cbe9296d 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -336,3 +336,22 @@ gst_vaapi_buffer_proxy_get_size (GstVaapiBufferProxy * proxy) return 0; #endif } + +/** + * 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; + } +} diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.h b/gst-libs/gst/vaapi/gstvaapibufferproxy.h index a70d33f419..7d611cf3f8 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.h @@ -92,6 +92,9 @@ 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 */ From 33af1fc5786a179a22ecb9c43021ddd24c382263 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:37:04 +0100 Subject: [PATCH 2668/3781] vaapivideomemory: release proxy's data if downstream The surface created for downstream is going to be filled by VAAPI elements. So, the driver needs write access on that surface. This patch releases the derived image held by the proxy, thus the surface is unmarked as busy. This is how it has to be done as discussed on libva mailing list. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapivideomemory.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index ed1fdf757e..ebb0065fc6 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -992,6 +992,14 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem), GST_VAAPI_BUFFER_PROXY_QUARK, dmabuf_proxy, (GDestroyNotify) gst_vaapi_buffer_proxy_unref); + + /* When a VA surface is going to be filled by a VAAPI element + * (decoder or VPP), it has _not_ be marked as busy in the driver. + * Releasing the surface's derived image, held by the buffer proxy, + * the surface will be unmarked as busy. */ + if (allocator->direction == GST_PAD_SRC) + gst_vaapi_buffer_proxy_release_data (dmabuf_proxy); + return mem; /* ERRORS */ From 37b774393413aec9c444bc45f08be2bf385e3be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 2 Jun 2016 22:13:51 +0200 Subject: [PATCH 2669/3781] plugins: check if negotiate dmabuf with downstream In order to enable, in the future, dmabuf-based buffers, the vaapi base plugin needs to check if downstream can import dmabuf buffers. This patch checks if downstream can handle dmabuf, by introspecting the shared GL context. If the GL context is EGL/GLES2 and have the extension EGL_EXT_image_dma_buf_import, then dmabuf can be negotiated. Original-patch-by: Julien Isorce --- gst/vaapi/gstvaapipluginbase.c | 8 +++++++- gst/vaapi/gstvaapipluginbase.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index f2929db818..8c23110984 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1103,8 +1103,14 @@ gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, display_type = GST_VAAPI_DISPLAY_TYPE_GLX; break; #endif -#if USE_EGL case GST_GL_PLATFORM_EGL: +#if VA_CHECK_VERSION (0,36,0) && USE_GST_GL_HELPERS + plugin->srcpad_can_dmabuf = + (!(gst_gl_context_get_gl_api (gl_context) & GST_GL_API_GLES1) + && gst_gl_context_check_feature (gl_context, + "EGL_EXT_image_dma_buf_import")); +#endif +#if USE_EGL display_type = GST_VAAPI_DISPLAY_TYPE_EGL; break; #endif diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index e1db5e72f4..bfeeb1078e 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -87,6 +87,8 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_caps) #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO(plugin) \ (&GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_info) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_can_dmabuf) #define GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->display) @@ -146,6 +148,7 @@ struct _GstVaapiPluginBase GstCaps *allowed_raw_caps; GstAllocator *sinkpad_allocator; GstAllocator *srcpad_allocator; + gboolean srcpad_can_dmabuf; }; struct _GstVaapiPluginBaseClass From aa20508bcfd1109b1fd522b0fba0f5f7f48a1d73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 16 Dec 2016 14:12:30 +0100 Subject: [PATCH 2670/3781] plugins: enable DMAbuf allocator to downstream If the negotiated caps are raw caps and downstream supports the EGL_EXT_image_dma_buf_import extension, then the created allocator is the DMAbuf, configured to downstream. At this moment, the only element which can push dmabuf-based buffers to downstream, is vaapipostproc. --- gst/vaapi/gstvaapipluginbase.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 8c23110984..e863a680b2 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -564,14 +564,27 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, if (!reset_allocator (plugin->srcpad_allocator, &vi)) return TRUE; + plugin->srcpad_allocator = NULL; + /* enable direct rendering if downstream requests raw video */ if (caps && gst_caps_is_video_raw (caps)) { - usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; - GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); + if (plugin->srcpad_can_dmabuf) { + if (GST_IS_BASE_TRANSFORM (plugin)) { + plugin->srcpad_allocator = + gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo, 0, + GST_PAD_SRC); + } + } else { + usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; + GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); + } + } + + if (!plugin->srcpad_allocator) { + plugin->srcpad_allocator = + gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag); } - plugin->srcpad_allocator = - gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag); if (!plugin->srcpad_allocator) goto error_create_allocator; From bc97987ffb5a5d5699fcb53a9413f9e8b4e525f2 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:33:41 +0100 Subject: [PATCH 2671/3781] vaapipostproc: don't GLTextureUpload if dmabuf Do not add the meta:GstVideoGLTextureUploadMeta feature if the render element can handle dmabuf-based buffers, avoiding its negotiation. Similar as "vaapidecode: do not add meta:GstVideoGLTextureUploadMeta feature if can dmabuf" https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapipostproc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index dab15bea37..cb48ed3668 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1032,6 +1032,7 @@ expand_allowed_srcpad_caps (GstVaapiPostproc * postproc, GstCaps * caps) { GValue value = G_VALUE_INIT, v_format = G_VALUE_INIT; guint i, num_structures; + gint gl_upload_meta_idx = -1; if (postproc->filter == NULL) goto cleanup; @@ -1052,8 +1053,10 @@ expand_allowed_srcpad_caps (GstVaapiPostproc * postproc, GstCaps * caps) GstStructure *structure; if (gst_caps_features_contains (features, - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META)) + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META)) { + gl_upload_meta_idx = i; continue; + } structure = gst_caps_get_structure (caps, i); if (!structure) @@ -1062,6 +1065,11 @@ expand_allowed_srcpad_caps (GstVaapiPostproc * postproc, GstCaps * caps) } g_value_unset (&value); + if (GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (postproc) + && gl_upload_meta_idx > -1) { + gst_caps_remove_structure (caps, gl_upload_meta_idx); + } + cleanup: return caps; } From 7fc1b70ff65bc5a78181e1faa23b4e5e510f8c3b Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:07:31 +0100 Subject: [PATCH 2672/3781] libs: bufferproxy: gst_vaapi_buffer_proxy_{set,peek}_mem() This patch adds a GstMemory as a variable member of the buffer proxy, because we will need to associate the buffer proxy with the memory which exposes it. Later, we will know which memory, in the video buffer pool, is attached to the processed surface. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 40 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapibufferproxy.h | 6 +++ gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h | 1 + 3 files changed, 47 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index 75cbe9296d..44c6126135 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -128,6 +128,11 @@ gst_vaapi_buffer_proxy_finalize (GstVaapiBufferProxy * proxy) { gst_vaapi_buffer_proxy_release_handle (proxy); + if (proxy->mem) { + gst_memory_unref (proxy->mem); + proxy->mem = NULL; + } + /* Notify the user function that the object is now destroyed */ if (proxy->destroy_func) proxy->destroy_func (proxy->destroy_data); @@ -171,6 +176,7 @@ gst_vaapi_buffer_proxy_new (guintptr handle, guint type, gsize size, proxy->va_info.type = VAImageBufferType; proxy->va_info.mem_type = from_GstVaapiBufferMemoryType (proxy->type); proxy->va_info.mem_size = size; + proxy->mem = NULL; if (!proxy->va_info.mem_type) goto error_unsupported_mem_type; return proxy; @@ -206,6 +212,7 @@ gst_vaapi_buffer_proxy_new_from_object (GstVaapiObject * object, proxy->destroy_data = data; proxy->type = type; proxy->va_buf = buf_id; + proxy->mem = NULL; memset (&proxy->va_info, 0, sizeof (proxy->va_info)); proxy->va_info.mem_type = from_GstVaapiBufferMemoryType (proxy->type); if (!proxy->va_info.mem_type) @@ -355,3 +362,36 @@ gst_vaapi_buffer_proxy_release_data (GstVaapiBufferProxy * proxy) proxy->destroy_data = NULL; } } + +/** + * gst_vaapi_buffer_proxy_set_mem: + * @proxy: a #GstVaapiBufferProxy + * @mem: a #GstMemory + * + * Relates @mem with @proxy, hence we later will know which memory + * correspond to processed surface. + * + * This is useful when a dmabuf-based memory is instantiated and + * associated with a surface. + **/ +void +gst_vaapi_buffer_proxy_set_mem (GstVaapiBufferProxy * proxy, GstMemory * mem) +{ + gst_mini_object_replace ((GstMiniObject **) & proxy->mem, + GST_MINI_OBJECT (mem)); +} + +/** + * gst_vaapi_buffer_proxy_peek_mem: + * @proxy: a #GstVaapiBufferProxy + * + * This is useful when a dmabuf-based memory is instantiated and + * associated with a surface. + * + * Returns: (transfer none): the assigned #GstMemory to the @proxy. + **/ +GstMemory * +gst_vaapi_buffer_proxy_peek_mem (GstVaapiBufferProxy * proxy) +{ + return proxy->mem; +} diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.h b/gst-libs/gst/vaapi/gstvaapibufferproxy.h index 7d611cf3f8..872af2f7c6 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.h @@ -95,6 +95,12 @@ gst_vaapi_buffer_proxy_get_size (GstVaapiBufferProxy * proxy); void gst_vaapi_buffer_proxy_release_data (GstVaapiBufferProxy * proxy); +void +gst_vaapi_buffer_proxy_set_mem (GstVaapiBufferProxy * proxy, GstMemory * mem); + +GstMemory * +gst_vaapi_buffer_proxy_peek_mem (GstVaapiBufferProxy * proxy); + G_END_DECLS #endif /* GST_VAAPI_BUFFER_PROXY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h index 833e22ce22..2cbbbf9cf8 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h @@ -71,6 +71,7 @@ struct _GstVaapiBufferProxy { #if VA_CHECK_VERSION (0,36,0) VABufferInfo va_info; #endif + GstMemory *mem; }; G_GNUC_INTERNAL From 4f037a036bf138607df201e73ff3ff0f8fa449b4 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:09:34 +0100 Subject: [PATCH 2673/3781] libs: surface: add gst_vaapi_surface_{set,peek}_buffer_proxy() These functions are useful when a dmabuf-based memory is instantiated in order to relate the generated buffer @proxy with the processed @surface. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst-libs/gst/vaapi/gstvaapisurface.c | 33 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 7 ++++++ 2 files changed, 40 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 64add345ba..4c4bbeeb66 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -1039,3 +1039,36 @@ gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface, } return TRUE; } + +/** + * gst_vaapi_surface_set_buffer_proxy: + * @surface: a #GstVaapiSurface + * @proxy: an external #GstVaapiBufferProxy + * + * Replaces the external buffer proxy in @surface with @proxy. + * + * This is useful when a dmabuf-based memory is instantiated in order + * to relate the generated buffer @proxy with the processed @surface. + **/ +void +gst_vaapi_surface_set_buffer_proxy (GstVaapiSurface * surface, + GstVaapiBufferProxy * proxy) +{ + gst_vaapi_buffer_proxy_replace (&surface->extbuf_proxy, proxy); +} + +/** + * gst_vaapi_surface_peek_buffer_proxy: + * @surface: a #GstVaapiSurface + * + * This is useful when a dmabuf-based memory is instantiated in order + * to relate the generated buffer @proxy with the processed @surface. + * + * Returns: (transfer none): the associated external + * #GstVaapiBufferProxy + **/ +GstVaapiBufferProxy * +gst_vaapi_surface_peek_buffer_proxy (GstVaapiSurface * surface) +{ + return surface->extbuf_proxy; +} diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index b176a2cdfe..eaed6f8e60 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -233,6 +233,13 @@ gboolean gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface, GstVideoOverlayComposition * composition, gboolean propagate_context); +void +gst_vaapi_surface_set_buffer_proxy (GstVaapiSurface * surface, + GstVaapiBufferProxy * proxy); + +GstVaapiBufferProxy * +gst_vaapi_surface_peek_buffer_proxy (GstVaapiSurface * surface); + G_END_DECLS #endif /* GST_VAAPI_SURFACE_H */ From 9132510ce090f1a6e7279f19c230fdea8aae0b4c Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:55:27 +0100 Subject: [PATCH 2674/3781] vaapivideobufferpool: add GstVaapiVideoBufferPoolAcquireParams Useful to let the pool know the current surface proxy when calling gst_buffer_pool_alloc_buffer() / gst_buffer_pool_acquire_buffer() https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapivideobufferpool.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index 418c687728..6a2169f1e7 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -25,6 +25,7 @@ #include #include +#include G_BEGIN_DECLS @@ -41,6 +42,7 @@ G_BEGIN_DECLS #define GST_VAAPI_IS_VIDEO_BUFFER_POOL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_BUFFER_POOL)) +typedef struct _GstVaapiVideoBufferPoolAcquireParams GstVaapiVideoBufferPoolAcquireParams; typedef struct _GstVaapiVideoBufferPool GstVaapiVideoBufferPool; typedef struct _GstVaapiVideoBufferPoolClass GstVaapiVideoBufferPoolClass; typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; @@ -83,6 +85,24 @@ typedef enum GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD = (1u << 2), } GstVaapiVideoBufferPoolOption; +/** + * GstVaapiVideoBufferPoolAcquireParams: + * @proxy: the #GstVaapiSurfaceProxy associated to the dmabuf-base + * memory + * + * Parameters passed to the gst_buffer_pool_acquire_buffer() function + * on a #GstVaapiVideoBufferPool, to control the allocation of the + * buffer. + * + * This is an extension of #GstBufferPoolAcquireParams + */ +struct _GstVaapiVideoBufferPoolAcquireParams +{ + GstBufferPoolAcquireParams parent_instance; + + GstVaapiSurfaceProxy *proxy; +}; + /** * GstVaapiVideoBufferPool: * From 6a0375d96eae0378d19f5c450a278516e5d16305 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 16:05:04 +0100 Subject: [PATCH 2675/3781] vaapivideomemory: export surface if it is provided gst_vaapi_dmabuf_memory_new() always exports a surface. Previously, it had to create that surface. Now it can also export an already provided surface. It is useful to export decoder's surfaces (from VA context). https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapivideobufferpool.c | 5 +++ gst/vaapi/gstvaapivideomemory.c | 56 +++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index a97fa558d1..275ccc4f63 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -267,6 +267,8 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, { GstVaapiVideoBufferPoolPrivate *const priv = GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv; + GstVaapiVideoBufferPoolAcquireParams *const priv_params = + (GstVaapiVideoBufferPoolAcquireParams *) params; GstVaapiVideoMeta *meta; GstMemory *mem; GstBuffer *buffer; @@ -290,6 +292,9 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, if (!buffer) goto error_create_buffer; + if (priv_params && priv_params->proxy) + gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy); + if (priv->use_dmabuf_memory) mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta); else diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index ebb0065fc6..c37985b03e 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -945,6 +945,7 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, gint dmabuf_fd; const GstVideoInfo *surface_info; guint surface_alloc_flags; + gboolean needs_surface; GstVaapiDmaBufAllocator *const allocator = GST_VAAPI_DMABUF_ALLOCATOR_CAST (base_allocator); @@ -960,22 +961,36 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, if (!display) return NULL; - surface = gst_vaapi_surface_new_full (display, surface_info, - surface_alloc_flags); - if (!surface) - goto error_create_surface; + proxy = gst_vaapi_video_meta_get_surface_proxy (meta); + needs_surface = (proxy == NULL); - proxy = gst_vaapi_surface_proxy_new (surface); - if (!proxy) - goto error_create_surface_proxy; + if (needs_surface) { + /* When exporting output VPP surfaces, or when exporting input + * surfaces to be filled/imported by an upstream element, such as + * v4l2src, we have to instantiate a VA surface to store it. */ + surface = gst_vaapi_surface_new_full (display, surface_info, + surface_alloc_flags); + if (!surface) + goto error_create_surface; + proxy = gst_vaapi_surface_proxy_new (surface); + if (!proxy) + goto error_create_surface_proxy; + } else { + /* When exporting existing surfaces that come from decoder's + * context. */ + surface = GST_VAAPI_SURFACE_PROXY_SURFACE (proxy); + } dmabuf_proxy = gst_vaapi_surface_get_dma_buf_handle (surface); - gst_vaapi_object_unref (surface); if (!dmabuf_proxy) goto error_create_dmabuf_proxy; - gst_vaapi_video_meta_set_surface_proxy (meta, proxy); - gst_vaapi_surface_proxy_unref (proxy); + if (needs_surface) { + /* The proxy has incremented the surface ref count. */ + gst_vaapi_object_unref (surface); + gst_vaapi_video_meta_set_surface_proxy (meta, proxy); + gst_vaapi_surface_proxy_unref (proxy); + } /* Need dup because GstDmabufMemory creates the GstFdMemory with flag * GST_FD_MEMORY_FLAG_NONE. So when being freed it calls close on the fd @@ -989,9 +1004,19 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, if (!mem) goto error_create_dmabuf_memory; - gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem), - GST_VAAPI_BUFFER_PROXY_QUARK, dmabuf_proxy, - (GDestroyNotify) gst_vaapi_buffer_proxy_unref); + if (needs_surface) { + /* Just set the GstVaapiBufferProxy (dmabuf_proxy) as qdata and + * forget about it. */ + gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem), + GST_VAAPI_BUFFER_PROXY_QUARK, dmabuf_proxy, + (GDestroyNotify) gst_vaapi_buffer_proxy_unref); + } else { + /* When not allocating the surface from this pool, so when + * exporting from the decoder's VA context, we need to know which + * GstMemory belongs to a provided surface. */ + gst_vaapi_buffer_proxy_set_mem (dmabuf_proxy, mem); + gst_vaapi_surface_set_buffer_proxy (surface, dmabuf_proxy); + } /* When a VA surface is going to be filled by a VAAPI element * (decoder or VPP), it has _not_ be marked as busy in the driver. @@ -1020,7 +1045,10 @@ error_create_surface_proxy: error_create_dmabuf_proxy: { GST_ERROR ("failed to export VA surface to DMABUF"); - gst_vaapi_surface_proxy_unref (proxy); + if (surface) + gst_vaapi_object_unref (surface); + if (proxy) + gst_vaapi_surface_proxy_unref (proxy); return NULL; } error_create_dmabuf_handle: From 9ed73e76afba6b88ca50b0b8c94cfecf6995f35e Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 16:07:07 +0100 Subject: [PATCH 2676/3781] vaapivideobufferpool: override acquire_buffer() Overriding the vmethod acquire_buffer() it is possible to attach the right GstMemory to the current acquired buffer. As a matter of fact, this acquired buffer may contain any instantiated GstFdmemory, since this buffer have been popped out from the buffer pool, which is a FIFO queue. So there is no garantee that this buffer matches with the current processed surface. Evenmore, the VA driver might not use a FIFO queue. Therefore, it is no way to guess on the ordering. In short, acquire_buffer on the VA driver and on the buffer pool return none matching data, we have to manually attach the right GstFdMemory to the acquired GstBuffer. The right GstMemory is the one associated with the current surface. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapivideobufferpool.c | 70 +++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 275ccc4f63..6aec965399 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -353,6 +353,75 @@ error_create_memory: } } +static GstFlowReturn +gst_vaapi_video_buffer_pool_acquire_buffer (GstBufferPool * pool, + GstBuffer ** out_buffer_ptr, GstBufferPoolAcquireParams * params) +{ + GstVaapiVideoBufferPoolPrivate *const priv = + GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv; + GstVaapiVideoBufferPoolAcquireParams *const priv_params = + (GstVaapiVideoBufferPoolAcquireParams *) params; + GstFlowReturn ret; + GstBuffer *buffer; + GstMemory *mem; + GstVaapiVideoMeta *meta; + GstVaapiSurface *surface; + GstVaapiBufferProxy *dmabuf_proxy; + + ret = + GST_BUFFER_POOL_CLASS + (gst_vaapi_video_buffer_pool_parent_class)->acquire_buffer (pool, &buffer, + params); + + if (!priv->use_dmabuf_memory || !params || !priv_params->proxy + || ret != GST_FLOW_OK) { + *out_buffer_ptr = buffer; + return ret; + } + + /* The point of the following dance is to attach the right GstMemory to the + * current acquired buffer. Indeed this buffer can contain any of the + * GstFdmemory since this buffer have been popped out from the buffer pool's + * FIFO. So there is no garantee that this matches the current surface. The + * va decoder driver might not even use a FIFO. So there is no way to guess + * on the ordering. In short acquire_current_buffer on the va driver and on + * the buffer pool return none matching data. So we have to manually attach + * the right GstFdMemory to the acquired GstBuffer. The right GstMemory is + * the one associated with the current surface. */ + g_assert (gst_buffer_n_memory (buffer) == 1); + + /* Find the cached memory associated with the given surface. */ + surface = GST_VAAPI_SURFACE_PROXY_SURFACE (priv_params->proxy); + dmabuf_proxy = gst_vaapi_surface_peek_buffer_proxy (surface); + if (dmabuf_proxy) { + mem = gst_vaapi_buffer_proxy_peek_mem (dmabuf_proxy); + if (mem == gst_buffer_peek_memory (buffer, 0)) + mem = NULL; + else + mem = gst_memory_ref (mem); + } else { + /* The given surface has not been exported yet. */ + meta = gst_buffer_get_vaapi_video_meta (buffer); + if (gst_vaapi_video_meta_get_surface_proxy (meta)) + gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy); + + mem = + gst_vaapi_dmabuf_memory_new (priv->allocator, + gst_buffer_get_vaapi_video_meta (buffer)); + } + + /* Attach the GstFdMemory to the output buffer. */ + if (mem) { + GST_DEBUG_OBJECT (pool, "assigning memory %p to acquired buffer %p", mem, + buffer); + gst_buffer_replace_memory (buffer, 0, mem); + gst_buffer_unset_flags (buffer, GST_BUFFER_FLAG_TAG_MEMORY); + } + + *out_buffer_ptr = buffer; + return GST_FLOW_OK; +} + static void gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool, GstBuffer * buffer) @@ -384,6 +453,7 @@ gst_vaapi_video_buffer_pool_class_init (GstVaapiVideoBufferPoolClass * klass) pool_class->get_options = gst_vaapi_video_buffer_pool_get_options; pool_class->set_config = gst_vaapi_video_buffer_pool_set_config; pool_class->alloc_buffer = gst_vaapi_video_buffer_pool_alloc_buffer; + pool_class->acquire_buffer = gst_vaapi_video_buffer_pool_acquire_buffer; pool_class->reset_buffer = gst_vaapi_video_buffer_pool_reset_buffer; /** From 50242eaaf7a14abfa4f62308a808b9d7e7950b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Feb 2017 17:06:29 +0100 Subject: [PATCH 2677/3781] plugins: decoder can negotiate dmabuf downstream --- gst/vaapi/gstvaapipluginbase.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e863a680b2..85a5e0f005 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -569,7 +569,7 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, /* enable direct rendering if downstream requests raw video */ if (caps && gst_caps_is_video_raw (caps)) { if (plugin->srcpad_can_dmabuf) { - if (GST_IS_BASE_TRANSFORM (plugin)) { + if (GST_IS_VIDEO_DECODER (plugin) || GST_IS_BASE_TRANSFORM (plugin)) { plugin->srcpad_allocator = gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo, 0, GST_PAD_SRC); From 25e8309567167321b1a596235f1114bc4a9da960 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 16:21:21 +0100 Subject: [PATCH 2678/3781] vaapidecode: make pool to export decoder's surface Use new -base API gst_video_decoder_allocate_output_frame_full() to pass the current proxy/surface to the pool. The pool will will export thins given surface instead of exporting a brand new surface that will never be filled in with meaningfull data. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapidecode.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 0e606d765d..1d84a8fd74 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -481,6 +481,16 @@ gst_vaapidecode_negotiate (GstVaapiDecode * decode) return TRUE; } +static gboolean +is_src_allocator_dmabuf (GstVaapiDecode * decode) +{ + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (decode); + + if (!GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (plugin)) + return FALSE; + return gst_vaapi_is_dmabuf_allocator (plugin->srcpad_allocator); +} + static GstFlowReturn gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, GstVideoCodecFrame * out_frame) @@ -491,6 +501,8 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, GstFlowReturn ret; const GstVaapiRectangle *crop_rect; GstVaapiVideoMeta *meta; + GstBufferPoolAcquireParams *params = NULL; + GstVaapiVideoBufferPoolAcquireParams vaapi_params = { {0,}, }; guint flags, out_flags = 0; gboolean alloc_renegotiate, caps_renegotiate; @@ -522,14 +534,26 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, gst_vaapi_surface_proxy_set_destroy_notify (proxy, (GDestroyNotify) gst_vaapidecode_release, gst_object_ref (decode)); - ret = gst_video_decoder_allocate_output_frame (vdec, out_frame); + if (is_src_allocator_dmabuf (decode)) { + vaapi_params.proxy = gst_vaapi_surface_proxy_ref (proxy); + params = (GstBufferPoolAcquireParams *) & vaapi_params; + } + + ret = gst_video_decoder_allocate_output_frame_with_params (vdec, out_frame, + params); + if (params) + gst_vaapi_surface_proxy_unref (vaapi_params.proxy); if (ret != GST_FLOW_OK) goto error_create_buffer; - meta = gst_buffer_get_vaapi_video_meta (out_frame->output_buffer); - if (!meta) - goto error_get_meta; - gst_vaapi_video_meta_set_surface_proxy (meta, proxy); + /* if not dmabuf is negotiated set the vaapi video meta in the + * proxy */ + if (!params) { + meta = gst_buffer_get_vaapi_video_meta (out_frame->output_buffer); + if (!meta) + goto error_get_meta; + gst_vaapi_video_meta_set_surface_proxy (meta, proxy); + } flags = gst_vaapi_surface_proxy_get_flags (proxy); if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_CORRUPTED) From b0016e336bba268e4eb9968ff7847932711e07db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 16 Oct 2016 01:04:09 +0100 Subject: [PATCH 2679/3781] vaapidecode: don't GLTextureUpload if dmabuf Do not add the meta:GstVideoGLTextureUploadMeta feature if the render element can handle dmabuf-based buffers, avoiding its negotiation. --- gst/vaapi/gstvaapidecode.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1d84a8fd74..80993d5c66 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -213,15 +213,18 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) return FALSE; /* Create VA caps */ - out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS -#if (USE_GLX || USE_EGL) - ";" GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS -#endif - ); + out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS); if (!out_caps) { GST_WARNING_OBJECT (decode, "failed to create VA/GL source caps"); return FALSE; } +#if (USE_GLX || USE_EGL) + if (!GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (decode)) { + out_caps = gst_caps_make_writable (out_caps); + gst_caps_append (out_caps, + gst_caps_from_string (GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS)); + } +#endif raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE (decode)); From d89a3bd258a3f27d5e36ae8156999a6398abbe29 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 7 Feb 2017 16:17:39 +0900 Subject: [PATCH 2680/3781] libs: decoder: h264: reduce frame number of gaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce frame num gaps so that we don't have to create unnecessary dummy pictures, just throw them away. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=777506 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 7b5b2a348c..fbff9bc79c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -3137,6 +3137,7 @@ fill_picture_gaps (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, GstVaapiDecoderH264Private *const priv = &decoder->priv; GstH264SPS *const sps = get_sps (decoder); const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); + gint32 prev_frame_num; GstVaapiFrameStore *prev_frame; GstVaapiPicture *base_picture; GstVaapiPictureH264 *lost_picture, *prev_picture; @@ -3164,8 +3165,20 @@ fill_picture_gaps (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, lost_slice_hdr.dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag = 0; /* XXX: this process is incorrect for MVC */ - /* XXX: optimize to reduce the number of dummy pictures created */ - priv->frame_num = priv->prev_ref_frame_num; + /* Reduce frame num gaps so we don't have to create unnecessary + * dummy pictures */ + prev_frame_num = priv->prev_ref_frame_num; + if (prev_frame_num > slice_hdr->frame_num) + prev_frame_num -= MaxFrameNum; + + if ((slice_hdr->frame_num - prev_frame_num) - 1 > sps->num_ref_frames) { + prev_frame_num = (slice_hdr->frame_num - sps->num_ref_frames) - 1; + + if (prev_frame_num < 0) + prev_frame_num += MaxFrameNum; + } + priv->frame_num = prev_frame_num; + for (;;) { priv->prev_ref_frame_num = priv->frame_num; priv->frame_num = (priv->prev_ref_frame_num + 1) % MaxFrameNum; From 2d463f79f21aa3cbc5eb4d9ab860f74154d6781f Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 8 Feb 2017 14:17:05 +0900 Subject: [PATCH 2681/3781] libs: utils: add HEVC profiles representation https://bugzilla.gnome.org/show_bug.cgi?id=778318 --- gst-libs/gst/vaapi/gstvaapiutils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index df17044c52..d583ab454a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -181,6 +181,10 @@ string_of_VAProfile (VAProfile profile) #if VA_CHECK_VERSION(0,35,2) MAP (H264MultiviewHigh); MAP (H264StereoHigh); +#endif +#if VA_CHECK_VERSION(0,37,1) + MAP (HEVCMain); + MAP (HEVCMain10); #endif MAP (VC1Simple); MAP (VC1Main); From a8e482f93f7d78144dbd5aaf919dcfe8d7efb64c Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:47:41 +0100 Subject: [PATCH 2682/3781] plugins: use linear storage if not the same device When dmabuf is negotiated downstream and decoding and rendering are not done on the same device, the layout has to be linear in order for the memory to be shared accross devices, since each device has its own way to do tiling. Right now this code is rather just a to-do comment, since we are not fetching the device ids. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapipluginbase.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 85a5e0f005..7509efa24c 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -539,6 +539,26 @@ error_create_allocator: } } +static inline guint +get_dmabuf_surface_allocation_flags () +{ + /* @FIXME: fetch the real devices ids */ + /* Pair vendor/device identifies an unique physical device. */ + guint va_vendor_id = 0x00; + guint va_device_id = 0x00; + guint gl_vendor_id = 0x00; + guint gl_device_id = 0x00; + + /* Requires linear memory only if fd export is done on a different + * device than the device where the fd is imported. */ + gboolean same_physical_device = va_vendor_id == gl_vendor_id + && va_device_id == gl_device_id; + + if (same_physical_device) + return 0; + return GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE; +} + static gboolean ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, GstCaps * caps) @@ -565,14 +585,12 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, return TRUE; plugin->srcpad_allocator = NULL; - - /* enable direct rendering if downstream requests raw video */ if (caps && gst_caps_is_video_raw (caps)) { if (plugin->srcpad_can_dmabuf) { if (GST_IS_VIDEO_DECODER (plugin) || GST_IS_BASE_TRANSFORM (plugin)) { plugin->srcpad_allocator = - gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo, 0, - GST_PAD_SRC); + gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo, + get_dmabuf_surface_allocation_flags (), GST_PAD_SRC); } } else { usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; From 3cc4eb7b8138089b8cb64e3ca754784d9c194b59 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Wed, 8 Feb 2017 10:17:40 -0800 Subject: [PATCH 2683/3781] make: remove gstvaapiversion.h generation https://bugzilla.gnome.org/show_bug.cgi?id=778250 --- configure.ac | 4 --- gst-libs/gst/vaapi/Makefile.am | 40 +------------------------ gst-libs/gst/vaapi/gstvaapidisplay.c | 5 ---- gst-libs/gst/vaapi/gstvaapiversion.h.in | 33 -------------------- 4 files changed, 1 insertion(+), 81 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapiversion.h.in diff --git a/configure.ac b/configure.ac index b6d269c9a5..cde58fbebf 100644 --- a/configure.ac +++ b/configure.ac @@ -171,10 +171,6 @@ AC_PROG_CC_STDC dnl check if the compiler supports '-c' and '-o' options AM_PROG_CC_C_O -dnl check for git command for version generation in libgstvaapi -AC_PATH_PROG([GIT], [git]) -AM_CONDITIONAL([HAVE_GIT], [test -n "$GIT"]) - dnl check for documentation tools GTK_DOC_CHECK([$GTKDOC_REQ]) AG_GST_PLUGIN_DOCS([$GTKDOC_REQ]) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index dd3aed59c3..56a225513e 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -143,7 +143,6 @@ libgstvaapi_source_priv_h = \ gstvaapiutils_h264_priv.h \ gstvaapiutils_h265_priv.h \ gstvaapiutils_mpeg2_priv.h \ - gstvaapiversion.h \ gstvaapivideopool_priv.h \ gstvaapiwindow_priv.h \ gstvaapiworkarounds.h \ @@ -507,38 +506,7 @@ libgstvaapi_wayland_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) -VERSION_FILE = .VERSION -OLD_VERSION_FILE = $(VERSION_FILE).old -NEW_VERSION_FILE = $(VERSION_FILE).new -PKG_VERSION_FILE = $(VERSION_FILE).pkg - -gstvaapiversion.h: gen-version - $(AM_V_GEN) \ - OV=`[ -f $(OLD_VERSION_FILE) ] && cat $(OLD_VERSION_FILE) || :`; \ - NV=`cat $(NEW_VERSION_FILE)`; \ - if [ "$$OV" != "$$NV" -o ! -f gstvaapiversion.h ]; then \ - cp -f $(NEW_VERSION_FILE) $(OLD_VERSION_FILE); \ - $(SED) -e "s|\@GST_VAAPI_VERSION_ID\@|$${NV}|" \ - $(srcdir)/gstvaapiversion.h.in > gstvaapiversion.h; \ - fi - -gen-version: - @echo $(VERSION) > $(NEW_VERSION_FILE) -if HAVE_GIT - @[ -d $(top_srcdir)/.git ] && \ - (cd $(top_srcdir) && $(GIT) describe --tags) > $(NEW_VERSION_FILE) || : -endif - @[ -f $(srcdir)/$(PKG_VERSION_FILE) ] && \ - cp -f $(srcdir)/$(PKG_VERSION_FILE) $(NEW_VERSION_FILE) || : - -$(PKG_VERSION_FILE): $(NEW_VERSION_FILE) - @cp -f $< $@ - -BUILT_SOURCES = gstvaapiversion.h -EXTRA_DIST = gstvaapiversion.h.in $(PKG_VERSION_FILE) -DISTCLEANFILES = $(BUILT_SOURCES) - -EXTRA_DIST += \ +EXTRA_DIST = \ $(libgstvaapi_enc_source_c) \ $(libgstvaapi_enc_source_h) \ $(libgstvaapi_enc_source_priv_h) \ @@ -564,10 +532,4 @@ EXTRA_DIST += \ $(libgstvaapi_egl_source_priv_h) \ $(NULL) -CLEANFILES = \ - $(OLD_VERSION_FILE) \ - $(NEW_VERSION_FILE) \ - $(PKG_VERSION_FILE) \ - $(NULL) - -include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index e47058d791..61bc8d76f6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -35,7 +35,6 @@ #include "gstvaapitexturemap.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiworkarounds.h" -#include "gstvaapiversion.h" /* Debug category for all vaapi libs */ GST_DEBUG_CATEGORY (gst_debug_vaapi); @@ -126,10 +125,6 @@ libgstvaapi_init_once (void) GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi, "vaapi", 0, "VA-API helper"); - /* Dump gstreamer-vaapi version for debugging purposes */ - GST_CAT_INFO (gst_debug_vaapi, "gstreamer-vaapi version %s", - GST_VAAPI_VERSION_ID); - gst_vaapi_display_properties_init (); g_once_init_leave (&g_once, TRUE); diff --git a/gst-libs/gst/vaapi/gstvaapiversion.h.in b/gst-libs/gst/vaapi/gstvaapiversion.h.in deleted file mode 100644 index e4896a4fe2..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiversion.h.in +++ /dev/null @@ -1,33 +0,0 @@ -/* - * gstvaapiversion.h - Versioning - * - * Copyright (C) 2013 Intel Corporation - * - * 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_VERSION_H -#define GST_VAAPI_VERSION_H - -/** - * GST_VAAPI_VERSION_ID: - * - * The full version identifier of gstreamer-vaapi, in string form - * (suitable for string concatenation). - */ -#define GST_VAAPI_VERSION_ID "@GST_VAAPI_VERSION_ID@" - -#endif /* GST_VAAPI_VERSION_H */ From 412dd13e86e834a846a26983470876ba36eace1c Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Mon, 6 Feb 2017 15:46:20 -0800 Subject: [PATCH 2684/3781] vaapi: add meson build https://bugzilla.gnome.org/show_bug.cgi?id=778250 --- gst-libs/gst/base/meson.build | 22 ++++ gst-libs/gst/meson.build | 2 + gst-libs/gst/vaapi/meson.build | 229 +++++++++++++++++++++++++++++++++ gst-libs/meson.build | 1 + gst/meson.build | 1 + gst/vaapi/meson.build | 51 ++++++++ meson.build | 129 +++++++++++++++++++ meson_options.txt | 6 + 8 files changed, 441 insertions(+) create mode 100644 gst-libs/gst/base/meson.build create mode 100644 gst-libs/gst/meson.build create mode 100644 gst-libs/gst/vaapi/meson.build create mode 100644 gst-libs/meson.build create mode 100644 gst/meson.build create mode 100644 gst/vaapi/meson.build create mode 100644 meson.build create mode 100644 meson_options.txt diff --git a/gst-libs/gst/base/meson.build b/gst-libs/gst/base/meson.build new file mode 100644 index 0000000000..a64f9a3ccc --- /dev/null +++ b/gst-libs/gst/base/meson.build @@ -0,0 +1,22 @@ +gstvaapi_baseutils_sources = [ + 'gstbitwriter.c', +] + +gstvaapi_baseutils_headers = [ + 'gstbitwriter.h', +] + +gstvaapi_baseutils_deps = [gstbase_dep] + +gstvaapi_baseutils = static_library('gstvaapi-baseutils-@0@'.format(api_version), + gstvaapi_baseutils_sources, + c_args : gstreamer_vaapi_args, + include_directories: [configinc, libsinc], + version : libversion, + soversion : soversion, + dependencies : gstvaapi_baseutils_deps, +) + +gstvaapi_baseutils_dep = declare_dependency(link_with: gstvaapi_baseutils, + include_directories : [libsinc], + dependencies : gstvaapi_baseutils_deps) diff --git a/gst-libs/gst/meson.build b/gst-libs/gst/meson.build new file mode 100644 index 0000000000..f47f7b1df7 --- /dev/null +++ b/gst-libs/gst/meson.build @@ -0,0 +1,2 @@ +subdir('base') +subdir('vaapi') diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build new file mode 100644 index 0000000000..7f9ff0275c --- /dev/null +++ b/gst-libs/gst/vaapi/meson.build @@ -0,0 +1,229 @@ +gstlibvaapi_sources = [ + 'gstvaapibufferproxy.c', + 'gstvaapicodec_objects.c', + 'gstvaapicontext.c', + 'gstvaapicontext_overlay.c', + 'gstvaapidecoder.c', + 'gstvaapidecoder_dpb.c', + 'gstvaapidecoder_h264.c', + 'gstvaapidecoder_mpeg2.c', + 'gstvaapidecoder_mpeg4.c', + 'gstvaapidecoder_objects.c', + 'gstvaapidecoder_unit.c', + 'gstvaapidecoder_vc1.c', + 'gstvaapidisplay.c', + 'gstvaapidisplaycache.c', + 'gstvaapifilter.c', + 'gstvaapiimage.c', + 'gstvaapiimagepool.c', + 'gstvaapiminiobject.c', + 'gstvaapiobject.c', + 'gstvaapiparser_frame.c', + 'gstvaapipixmap.c', + 'gstvaapiprofile.c', + 'gstvaapisubpicture.c', + 'gstvaapisurface.c', + 'gstvaapisurface_drm.c', + 'gstvaapisurfacepool.c', + 'gstvaapisurfaceproxy.c', + 'gstvaapitexture.c', + 'gstvaapitexturemap.c', + 'gstvaapiutils.c', + 'gstvaapiutils_core.c', + 'gstvaapiutils_h264.c', + 'gstvaapiutils_h265.c', + 'gstvaapiutils_mpeg2.c', + 'gstvaapivalue.c', + 'gstvaapivideopool.c', + 'gstvaapiwindow.c', + 'video-format.c', +] + +gstlibvaapi_headers = [ + 'gstvaapibufferproxy.h', + 'gstvaapidecoder.h', + 'gstvaapidecoder_h264.h', + 'gstvaapidecoder_h265.h', + 'gstvaapidecoder_mpeg2.h', + 'gstvaapidecoder_mpeg4.h', + 'gstvaapidecoder_vc1.h', + 'gstvaapidisplay.h', + 'gstvaapifilter.h', + 'gstvaapiimage.h', + 'gstvaapiimagepool.h', + 'gstvaapiobject.h', + 'gstvaapipixmap.h', + 'gstvaapiprofile.h', + 'gstvaapisubpicture.h', + 'gstvaapisurface.h', + 'gstvaapisurface_drm.h', + 'gstvaapisurfacepool.h', + 'gstvaapisurfaceproxy.h', + 'gstvaapitexture.h', + 'gstvaapitexturemap.h', + 'gstvaapitypes.h', + 'gstvaapiutils_h264.h', + 'gstvaapiutils_h265.h', + 'gstvaapiutils_mpeg2.h', + 'gstvaapivalue.h', + 'gstvaapivideopool.h', + 'gstvaapiwindow.h', + 'video-format.h', +] + +if USE_JPEG_DECODER + gstlibvaapi_sources += 'gstvaapidecoder_jpeg.c' + gstlibvaapi_headers += 'gstvaapidecoder_jpeg.h' +endif + +if USE_VP8_DECODER + gstlibvaapi_sources += 'gstvaapidecoder_vp8.c' + gstlibvaapi_headers += 'gstvaapidecoder_vp8.h' +endif + +if USE_H265_DECODER + gstlibvaapi_sources += 'gstvaapidecoder_h265.c' + gstlibvaapi_headers += 'gstvaapidecoder_h265.h' +endif + +if USE_VP9_DECODER + gstlibvaapi_sources += 'gstvaapidecoder_vp9.c' + gstlibvaapi_headers += 'gstvaapidecoder_vp9.h' +endif + +if USE_ENCODERS + gstlibvaapi_sources += [ + 'gstvaapicodedbuffer.c', + 'gstvaapicodedbufferpool.c', + 'gstvaapicodedbufferproxy.c', + 'gstvaapiencoder.c', + 'gstvaapiencoder_h264.c', + 'gstvaapiencoder_mpeg2.c', + 'gstvaapiencoder_objects.c', + ] + gstlibvaapi_headers += [ + 'gstvaapicodedbuffer.h', + 'gstvaapicodedbufferpool.h', + 'gstvaapicodedbufferproxy.h', + 'gstvaapiencoder.h', + 'gstvaapiencoder_h264.h', + 'gstvaapiencoder_mpeg2.h', + ] +endif + +if USE_JPEG_ENCODER + gstlibvaapi_sources += 'gstvaapiencoder_jpeg.c' + gstlibvaapi_headers += 'gstvaapiencoder_jpeg.h' +endif + +if USE_VP8_ENCODER + gstlibvaapi_sources += 'gstvaapiencoder_vp8.c' + gstlibvaapi_headers += 'gstvaapiencoder_vp8.h' +endif + +if USE_H265_ENCODER + gstlibvaapi_sources += 'gstvaapiencoder_h265.c' + gstlibvaapi_headers += 'gstvaapiencoder_h265.h' +endif + +if USE_VP9_ENCODER + gstlibvaapi_sources += 'gstvaapiencoder_vp9.c' + gstlibvaapi_headers += 'gstvaapiencoder_vp9.h' +endif + +if USE_DRM + gstlibvaapi_sources += [ + 'gstvaapidisplay_drm.c', + 'gstvaapiwindow_drm.c', + ] + gstlibvaapi_headers += [ + 'gstvaapidisplay_drm.h', + 'gstvaapiwindow_drm.h', + ] +endif + +if USE_X11 + gstlibvaapi_sources += [ + 'gstvaapidisplay_x11.c', + 'gstvaapipixmap_x11.c', + 'gstvaapiutils_x11.c', + 'gstvaapiwindow_x11.c', + ] + gstlibvaapi_headers += [ + 'gstvaapidisplay_x11.h', + 'gstvaapipixmap_x11.h', + 'gstvaapiwindow_x11.h', + ] +endif + +if USE_GLX + gstlibvaapi_sources += [ + 'gstvaapidisplay_glx.c', + 'gstvaapitexture_glx.c', + 'gstvaapiutils_glx.c', + 'gstvaapiwindow_glx.c', + ] + gstlibvaapi_headers += [ + 'gstvaapidisplay_glx.h', + 'gstvaapitexture.h', + 'gstvaapitexture_glx.h', + 'gstvaapiwindow_glx.h', + ] +endif + +if USE_EGL + gstlibvaapi_sources += [ + 'gstvaapidisplay_egl.c', + 'gstvaapisurface_egl.c', + 'gstvaapitexture_egl.c', + 'gstvaapiutils_egl.c', + 'gstvaapiwindow_egl.c', + ] + gstlibvaapi_headers += [ + 'gstvaapidisplay_egl.h', + 'gstvaapisurface_egl.h', + 'gstvaapitexture_egl.h', + 'gstvaapiwindow_egl.h', + ] +endif + +if USE_WAYLAND + gstlibvaapi_sources += [ + 'gstvaapidisplay_wayland.c', + 'gstvaapiwindow_wayland.c', + ] + gstlibvaapi_headers += [ + 'gstvaapidisplay_wayland.h', + 'gstvaapiwindow_wayland.h', + ] +endif + +gstlibvaapi_deps = [gstbase_dep, gstvideo_dep, gstcodecparsers_dep, libva_dep, gstvaapi_baseutils_dep] +if USE_DRM + gstlibvaapi_deps += [libva_drm_dep, libdrm_dep, libudev_dep] +endif +if USE_EGL + gstlibvaapi_deps += [egl_dep, gmodule_dep] +endif +if USE_GLX + gstlibvaapi_deps += [libva_x11_dep, x11_dep, gl_dep, libdl_dep] +endif +if USE_WAYLAND + gstlibvaapi_deps += [libva_wayland_dep, wayland_client_dep] +endif +if USE_X11 + gstlibvaapi_deps += [libva_x11_dep, x11_dep, xrandr_dep, xrender_dep] +endif + +gstlibvaapi = static_library('gstlibvaapi-@0@'.format(api_version), + gstlibvaapi_sources, + c_args : gstreamer_vaapi_args + ['-DIN_LIBGSTVAAPI', '-DIN_LIBGSTVAAPI_CORE', '-DGST_USE_UNSTABLE_API', '-DGST_VAAPI_VERSION_ID="@0@"'.format(gst_version)], + include_directories: [configinc, libsinc], + version : libversion, + soversion : soversion, + dependencies : gstlibvaapi_deps, +) + +gstlibvaapi_dep = declare_dependency(link_with: gstlibvaapi, + include_directories : [libsinc], + dependencies : gstlibvaapi_deps) diff --git a/gst-libs/meson.build b/gst-libs/meson.build new file mode 100644 index 0000000000..668dcbaaff --- /dev/null +++ b/gst-libs/meson.build @@ -0,0 +1 @@ +subdir('gst') diff --git a/gst/meson.build b/gst/meson.build new file mode 100644 index 0000000000..a8719a14c0 --- /dev/null +++ b/gst/meson.build @@ -0,0 +1 @@ +subdir('vaapi') diff --git a/gst/vaapi/meson.build b/gst/vaapi/meson.build new file mode 100644 index 0000000000..744b91c14f --- /dev/null +++ b/gst/vaapi/meson.build @@ -0,0 +1,51 @@ +vaapi_sources = [ + 'gstvaapi.c', + 'gstvaapidecode.c', + 'gstvaapidecodedoc.c', + 'gstvaapipluginbase.c', + 'gstvaapipluginutil.c', + 'gstvaapipostproc.c', + 'gstvaapipostprocutil.c', + 'gstvaapisink.c', + 'gstvaapivideobuffer.c', + 'gstvaapivideocontext.c', + 'gstvaapivideometa.c', + 'gstvaapidecodebin.c', + 'gstvaapivideobufferpool.c', + 'gstvaapivideomemory.c', + 'gstvaapivideometa_texture.c', +] + +if USE_ENCODERS + vaapi_sources += [ + 'gstvaapiencode.c', + 'gstvaapiencode_h264.c', + 'gstvaapiencode_mpeg2.c', + ] +endif + +if USE_JPEG_ENCODER + vaapi_sources += 'gstvaapiencode_jpeg.c' +endif + +if USE_VP8_ENCODER + vaapi_sources += 'gstvaapiencode_vp8.c' +endif + +if USE_H265_ENCODER + vaapi_sources += 'gstvaapiencode_h265.c' +endif + +if USE_VP9_ENCODER + vaapi_sources += 'gstvaapiencode_vp9.c' +endif + +gstvaapi = library('gstvaapi', + vaapi_sources, + c_args : gstreamer_vaapi_args + ['-DGST_USE_UNSTABLE_API'], + include_directories : [configinc, libsinc], + dependencies : [gstbase_dep, gstvideo_dep, gstallocators_dep, gstpbutils_dep, + libva_dep, gstlibvaapi_dep, gstgl_dep, libm], + install : true, + install_dir : plugins_install_dir, +) diff --git a/meson.build b/meson.build new file mode 100644 index 0000000000..7559934d13 --- /dev/null +++ b/meson.build @@ -0,0 +1,129 @@ +project('gstreamer-vaapi', 'c', + version : '1.11.1.1', + meson_version : '>= 0.36.0', + default_options : [ 'warning_level=1', + 'buildtype=debugoptimized' ]) + +gst_version = meson.project_version() +version_arr = gst_version.split('.') +gst_version_major = version_arr[0] +gst_version_minor = version_arr[1] +gst_version_micro = version_arr[2] +if version_arr.length() == 4 + gst_version_nano = version_arr[3] +else + gst_version_nano = 0 +endif + +glib_req = '>= 2.40.0' +gst_req = '>= @0@.@1@.0'.format(gst_version_major, gst_version_minor) + +# Mandatory GST deps +cc = meson.get_compiler('c') + +libm = cc.find_library('m', required : false) +gst_dep = dependency('gstreamer-1.0', version : gst_req, + fallback : ['gstreamer', 'gst_dep']) +gstbase_dep = dependency('gstreamer-base-1.0', version : gst_req, + fallback : ['gstreamer', 'gst_base_dep']) +gstpbutils_dep = dependency('gstreamer-pbutils-1.0', version : gst_req, + fallback : ['gst-plugins-base', 'pbutils_dep']) +gstallocators_dep = dependency('gstreamer-allocators-1.0', version : gst_req, + fallback : ['gst-plugins-base', 'allocators_dep']) +gstvideo_dep = dependency('gstreamer-video-1.0', version : gst_req, + fallback : ['gst-plugins-base', 'video_dep']) +gstcodecparsers_dep = dependency('gstreamer-codecparsers-1.0', version : gst_req, + fallback : ['gst-plugins-bad', 'gstcodecparsers_dep'], required: false) +gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, + fallback : ['gst-plugins-bad', 'gstgl_dep'], required: false) +gmodule_dep = dependency('gmodule-2.0', required: false) +libva_dep = dependency('libva', version: '>= 0.30.4') + +libva_drm_dep = dependency('libva-drm', version: '>= 0.33.0', required: false) +libva_wayland_dep = dependency('libva-wayland', version: '>= 0.33.0', required: false) +libva_x11_dep = dependency('libva-x11', version: '>= 0.31.0', required: false) +libdrm_dep = dependency('libdrm', required: false) +libudev_dep = dependency('libudev', required: false) +egl_dep = dependency('egl', required: false) +gl_dep = dependency('gl', required: false) +glesv2_dep = dependency('glesv2', required: false) +glesv3_dep = dependency('glesv3', required: false) +libdl_dep = cc.find_library('dl', rqeuired: false) +wayland_client_dep = dependency('wayland-client', required: false) +x11_dep = dependency('x11', required: false) +xrandr_dep = dependency('xrandr', required: false) +xrender_dep = dependency('xrender', required: false) + +GLES_VERSION_MASK = 0 +GLES_VERSION_MASK += gl_dep.found() ? 1 : 0 +GLES_VERSION_MASK += glesv2_dep.found() ? 4 : 0 +GLES_VERSION_MASK += glesv3_dep.found() ? 8 : 0 + +USE_ENCODERS = libva_dep.version().version_compare('>= 0.34.0') and get_option('with_encoders') != 'no' +USE_H265_DECODER = cc.has_header('va/va_dec_hevc.h', dependencies: libva_dep, prefix: '#include ') +USE_H265_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_hevc.h', dependencies: libva_dep, prefix: '#include ') +USE_JPEG_DECODER = cc.has_header('va/va_dec_jpeg.h', dependencies: libva_dep, prefix: '#include ') +USE_JPEG_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_jpeg.h', dependencies: libva_dep, prefix: '#include ') +USE_VP8_DECODER = cc.has_header('va/va_dec_vp8.h', dependencies: libva_dep, prefix: '#include ') +USE_VP8_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp8.h', dependencies: libva_dep, prefix: '#include ') +USE_VP9_DECODER = cc.has_header('va/va_dec_vp9.h', dependencies: libva_dep, prefix: '#include ') +USE_VP9_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp9.h', dependencies: libva_dep, prefix: '#include ') + +USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() and get_option('with_drm') != 'no' +USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no' +USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl_dep.found() and get_option('with_glx') != 'no' +USE_WAYLAND = libva_wayland_dep.found() and wayland_client_dep.found() and get_option('with_wayland') != 'no' +USE_X11 = libva_x11_dep.found() and x11_dep.found() and get_option('with_x11') != 'no' + +cdata = configuration_data() +cdata.set('GST_API_VERSION_S', '"@0@.@1@"'.format(gst_version_major, gst_version_minor)) +cdata.set('PACKAGE', '"gstreamer-vaapi"') +cdata.set('VERSION', '"@0@"'.format(gst_version)) +cdata.set('PACKAGE_VERSION', '"@0@"'.format(gst_version)) +cdata.set('PACKAGE_NAME', '"GStreamer VA-API Plug-ins"') +cdata.set('PACKAGE_STRING', '"GStreamer VA-API Plug-ins @0@"'.format(gst_version)) +cdata.set('PACKAGE_BUGREPORT', '"http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer"') +cdata.set10('USE_DRM', USE_DRM) +cdata.set10('USE_EGL', USE_EGL) +cdata.set10('USE_ENCODERS', USE_ENCODERS) +cdata.set10('USE_GLX', USE_GLX) +cdata.set10('USE_H265_DECODER', USE_H265_DECODER) +cdata.set10('USE_H265_ENCODER', USE_H265_ENCODER) +cdata.set10('USE_JPEG_DECODER', USE_JPEG_DECODER) +cdata.set10('USE_JPEG_ENCODER', USE_JPEG_ENCODER) +cdata.set10('USE_VP8_DECODER', USE_VP8_DECODER) +cdata.set10('USE_VP8_ENCODER', USE_VP8_ENCODER) +cdata.set10('USE_VP9_DECODER', USE_VP9_DECODER) +cdata.set10('USE_VP9_ENCODER', USE_VP9_ENCODER) +cdata.set10('USE_WAYLAND', USE_WAYLAND) +cdata.set10('USE_X11', USE_X11) +cdata.set10('HAVE_XKBLIB', cc.has_header('X11/XKBlib.h', dependencies: x11_dep)) +cdata.set10('HAVE_XRANDR', xrandr_dep.found()) +cdata.set10('HAVE_XRENDER', xrender_dep.found()) +cdata.set10('USE_VA_VPP', true) +cdata.set10('USE_GST_GL_HELPERS', gstgl_dep.found()) +cdata.set('GLES_VERSION_MASK', GLES_VERSION_MASK) +runcmd = run_command('pkg-config', '--variable=driverdir', 'libva') +if runcmd.returncode() == 0 + cdata.set('VA_DRIVERS_PATH', '"@0@"'.format(runcmd.stdout().strip())) +endif + +api_version = '1.0' +soversion = 0 +# maintaining compatibility with the previous libtool versioning +# current = minor * 100 + micro +libversion = '@0@.@1@.0'.format(soversion, gst_version_minor.to_int() * 100 + gst_version_micro.to_int()) + +plugins_install_dir = '@0@/gstreamer-1.0'.format(get_option('libdir')) + +configure_file(configuration: cdata, output: 'config.h') +gstreamer_vaapi_args = ['-DHAVE_CONFIG_H'] +configinc = include_directories('.') +libsinc = include_directories('gst-libs') + +subdir('gst-libs') +subdir('gst') +#subdir('tests') + +python3 = find_program('python3') +run_command(python3, '-c', 'import shutil; shutil.copy("hooks/pre-commit.hook", ".git/hooks/pre-commit")') diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000000..018f8bc33d --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,6 @@ +option('with_encoders', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') +option('with_drm', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') +option('with_x11', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') +option('with_glx', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') +option('with_wayland', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') +option('with_egl', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') From 025d5ce33e98d35ba5419dd7f4cf811a2f0e5cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 9 Feb 2017 12:49:44 +0100 Subject: [PATCH 2685/3781] plugins: fix build when gcc In commit a8e482f9 we added a function without parameters, but gcc doesn't like that. --- gst/vaapi/gstvaapipluginbase.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 7509efa24c..a60498df4f 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -540,7 +540,7 @@ error_create_allocator: } static inline guint -get_dmabuf_surface_allocation_flags () +get_dmabuf_surface_allocation_flags (void) { /* @FIXME: fetch the real devices ids */ /* Pair vendor/device identifies an unique physical device. */ From ffc5b43da735f8c5a00e7f152e09e6a8e840f151 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 9 Feb 2017 12:39:19 +0900 Subject: [PATCH 2686/3781] libs: encoder: vp8: fix bitrate calculation Base encoder's unit of bitrate is in Kbps. We should honor it so we use the value of bitrate in VA, in which is expressed in bps. https://bugzilla.gnome.org/show_bug.cgi?id=749950 --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index a002347169..00e9baec2c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -129,8 +129,9 @@ ensure_bitrate (GstVaapiEncoderVP8 * encoder) 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; + GST_VAAPI_ENCODER_FPS_D (encoder)) / (4 * 1000); } + break; default: base_encoder->bitrate = 0; break; @@ -219,7 +220,7 @@ fill_sequence (GstVaapiEncoderVP8 * encoder, GstVaapiEncSequence * sequence) seq_param->frame_height = GST_VAAPI_ENCODER_HEIGHT (encoder); if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) & GST_VAAPI_RATECONTROL_CBR) - seq_param->bits_per_second = base_encoder->bitrate; + seq_param->bits_per_second = base_encoder->bitrate * 1000; seq_param->intra_period = base_encoder->keyframe_period; From b6a3e88059d1405f1e0eb311a2436c85cb26bf05 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 10 Feb 2017 09:51:38 +0900 Subject: [PATCH 2687/3781] libs: encoder: vp8: add CBR encoding mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch enables the Constant BitRate encoding mode in VP8 encoder. Basically it adds the configuration parameters required by libva to CBR enconding. Original-Patch-By: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=749950 --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 68 +++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 00e9baec2c..56a19438a3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -39,7 +39,8 @@ /* Supported set of VA rate controls, within this implementation */ #define SUPPORTED_RATECONTROLS \ - (GST_VAAPI_RATECONTROL_MASK (CQP)) + (GST_VAAPI_RATECONTROL_MASK (CQP) | \ + GST_VAAPI_RATECONTROL_MASK (CBR)) /* Supported set of tuning options, within this implementation */ #define SUPPORTED_TUNE_OPTIONS \ @@ -256,6 +257,65 @@ error: } } +static gboolean +ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + GstVaapiEncMiscParam *misc; + + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CBR) + return TRUE; + + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (FrameRate, encoder); + if (!misc) + return FALSE; + { + VAEncMiscParameterFrameRate *param = misc->data; + param->framerate = + GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder); + } + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); + if (!misc) + return FALSE; + { + VAEncMiscParameterHRD *hrd = misc->data; + if (base_encoder->bitrate > 0) { + hrd->buffer_size = base_encoder->bitrate * 1000 * 2; + hrd->initial_buffer_fullness = base_encoder->bitrate * 1000; + } else { + hrd->buffer_size = 0; + hrd->initial_buffer_fullness = 0; + } + } + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + /* RateControl params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); + if (!misc) + return FALSE; + { + VAEncMiscParameterRateControl *rate_control; + rate_control = misc->data; + rate_control->bits_per_second = base_encoder->bitrate * 1000; + rate_control->target_percentage = 70; + /* CPB (Coded picture buffer) length in milliseconds, which could + * be provided as a property */ + rate_control->window_size = 500; + rate_control->initial_qp = encoder->yac_qi; + rate_control->min_qp = 1; + } + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + return TRUE; +} + static gboolean fill_picture (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture, @@ -303,6 +363,10 @@ fill_picture (GstVaapiEncoderVP8 * encoder, pic_param->sharpness_level = encoder->sharpness_level; + /* Used for CBR */ + pic_param->clamp_qindex_low = 0; + pic_param->clamp_qindex_high = 127; + return TRUE; } @@ -375,6 +439,8 @@ gst_vaapi_encoder_vp8_encode (GstVaapiEncoder * base_encoder, 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)) From 91a8688fa115c67a0d60cdb06eb0a5e0db315343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 15 Feb 2017 00:26:21 +0000 Subject: [PATCH 2688/3781] meson: dist meson build files Ship meson build files in tarballs, so people who use tarballs in their builds can start playing with meson already. --- Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index a6a4a42338..a915de0fdf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,6 +20,8 @@ MAINTAINERCLEANFILES = \ EXTRA_DIST = \ configure.ac autogen.sh \ - gstreamer-vaapi.doap + gstreamer-vaapi.doap \ + $(shell find "$(top_srcdir)" -type f -name meson.build ! -path "$(top_srcdir)/$(PACKAGE_TARNAME)-*" ) \ + meson_options.txt -include $(top_srcdir)/git.mk From 015e2617082a3a0e4788420094a20b4919d765ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 15 Feb 2017 19:14:59 +0000 Subject: [PATCH 2689/3781] meson: gstreamer-codecparsers is a required dep Just like in configure.ac. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 7559934d13..59f5d0749f 100644 --- a/meson.build +++ b/meson.build @@ -33,7 +33,7 @@ gstallocators_dep = dependency('gstreamer-allocators-1.0', version : gst_req, gstvideo_dep = dependency('gstreamer-video-1.0', version : gst_req, fallback : ['gst-plugins-base', 'video_dep']) gstcodecparsers_dep = dependency('gstreamer-codecparsers-1.0', version : gst_req, - fallback : ['gst-plugins-bad', 'gstcodecparsers_dep'], required: false) + fallback : ['gst-plugins-bad', 'gstcodecparsers_dep']) gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, fallback : ['gst-plugins-bad', 'gstgl_dep'], required: false) gmodule_dep = dependency('gmodule-2.0', required: false) From 884e0bece269b5199006690f8f30221aa4d56be3 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Mon, 13 Feb 2017 16:39:41 -0800 Subject: [PATCH 2690/3781] build: rename USE_HEVC_DECODER to USE_H265_DECODER Rename to be consistent with H.264 and also H.265 encoder. The meson build assumed this was already consistently named, and so previously was not able to actually build the H.265 decoder. https://bugzilla.gnome.org/show_bug.cgi?id=778576 --- configure.ac | 14 +++++++------- gst-libs/gst/vaapi/Makefile.am | 2 +- gst/vaapi/gstvaapidecode.c | 6 +++--- gst/vaapi/gstvaapidecodebin.c | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index cde58fbebf..ba223f8622 100644 --- a/configure.ac +++ b/configure.ac @@ -638,9 +638,9 @@ AC_CHECK_HEADERS([va/va_dec_hevc.h], [], [], CPPFLAGS="$saved_CPPFLAGS" dnl Check for HEVC decoding API (0.38+) -USE_HEVC_DECODER=0 +USE_H265_DECODER=0 AC_CACHE_CHECK([for HEVC decoding API], - [ac_cv_have_hevc_decoding_api], + [ac_cv_have_h265_decoding_api], [ saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" @@ -663,12 +663,12 @@ slice_param.slice_data_offset = 0; slice_param.slice_data_flag = 0; ]]) ], - [ac_cv_have_hevc_decoding_api="yes"], - [ac_cv_have_hevc_decoding_api="no"]) + [ac_cv_have_h265_decoding_api="yes"], + [ac_cv_have_h265_decoding_api="no"]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) -AS_IF([test "x$ac_cv_have_hevc_decoding_api" = "xyes"], [USE_HEVC_DECODER=1]) +AS_IF([test "x$ac_cv_have_h265_decoding_api" = "xyes"], [USE_H265_DECODER=1]) dnl Check for vpp (video post-processing) support USE_VA_VPP=0 @@ -981,9 +981,9 @@ AC_DEFINE_UNQUOTED([USE_VP9_DECODER], [$USE_VP9_DECODER], [Defined to 1 if VP9 decoder is used]) AM_CONDITIONAL([USE_VP9_DECODER], [test $USE_VP9_DECODER -eq 1]) -AC_DEFINE_UNQUOTED([USE_HEVC_DECODER], [$USE_HEVC_DECODER], +AC_DEFINE_UNQUOTED([USE_H265_DECODER], [$USE_H265_DECODER], [Defined to 1 if HEVC decoder is used]) -AM_CONDITIONAL([USE_HEVC_DECODER], [test $USE_HEVC_DECODER -eq 1]) +AM_CONDITIONAL([USE_H265_DECODER], [test $USE_H265_DECODER -eq 1]) AC_DEFINE_UNQUOTED([USE_DRM], [$USE_DRM], [Defined to 1 if DRM is enabled]) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 56a225513e..1159928da4 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -166,7 +166,7 @@ endif libgstvaapi_hevcdec_source_c = gstvaapidecoder_h265.c libgstvaapi_hevcdec_source_h = gstvaapidecoder_h265.h -if USE_HEVC_DECODER +if USE_H265_DECODER libgstvaapi_source_c += $(libgstvaapi_hevcdec_source_c) libgstvaapi_source_h += $(libgstvaapi_hevcdec_source_h) endif diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 80993d5c66..b279b83c9e 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -65,7 +65,7 @@ static const char gst_vaapidecode_sink_caps_str[] = GST_CAPS_CODEC("video/x-xvid") GST_CAPS_CODEC("video/x-h263") GST_CAPS_CODEC("video/x-h264") -#if USE_HEVC_DECODER +#if USE_H265_DECODER GST_CAPS_CODEC("video/x-h265") #endif GST_CAPS_CODEC("video/x-wmv") @@ -119,7 +119,7 @@ static const GstVaapiDecoderMap vaapi_decode_map[] = { #if USE_VP9_DECODER {GST_VAAPI_CODEC_VP9, GST_RANK_PRIMARY, "vp9", "video/x-vp9"}, #endif -#if USE_HEVC_DECODER +#if USE_H265_DECODER {GST_VAAPI_CODEC_H265, GST_RANK_PRIMARY, "h265", "video/x-h265"}, #endif {0 /* the rest */ , GST_RANK_PRIMARY + 1, NULL, @@ -855,7 +855,7 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) } } break; -#if USE_HEVC_DECODER +#if USE_H265_DECODER case GST_VAAPI_CODEC_H265: decode->decoder = gst_vaapi_decoder_h265_new (dpy, caps); diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 9fc2bd4a2f..295c12bd97 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -85,7 +85,7 @@ static const char gst_vaapi_decode_bin_sink_caps_str[] = GST_CAPS_CODEC("video/x-xvid") GST_CAPS_CODEC("video/x-h263") GST_CAPS_CODEC("video/x-h264") -#if USE_HEVC_DECODER +#if USE_H265_DECODER GST_CAPS_CODEC("video/x-h265") #endif GST_CAPS_CODEC("video/x-wmv") From d6738f3f93ce19b6cd9d072b9a3e31264d9a9d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 16 Feb 2017 18:11:50 +0100 Subject: [PATCH 2691/3781] libs: decoder: h264,h265 avoid uninitialized variable Configuring GCC to verify possible usage of uninitialized variables, shows that found_index might be used without previous assignation. This patch assigns a initial value to found_index, also avoid a branching when returning the result value. https://bugzilla.gnome.org/show_bug.cgi?id=778782 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 12 ++++++------ gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index fbff9bc79c..d4bd6dda18 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -769,7 +769,7 @@ dpb_find_nearest_prev_poc (GstVaapiDecoderH264 * decoder, { GstVaapiDecoderH264Private *const priv = &decoder->priv; GstVaapiPictureH264 *found_picture = NULL; - guint i, j, found_index; + guint i, j, found_index = -1; g_return_val_if_fail (picture != NULL, -1); @@ -793,7 +793,7 @@ dpb_find_nearest_prev_poc (GstVaapiDecoderH264 * decoder, if (found_picture_ptr) *found_picture_ptr = found_picture; - return found_picture ? found_index : -1; + return found_index; } /* Finds the picture with the lowest POC that needs to be output */ @@ -803,7 +803,7 @@ dpb_find_lowest_poc (GstVaapiDecoderH264 * decoder, { GstVaapiDecoderH264Private *const priv = &decoder->priv; GstVaapiPictureH264 *found_picture = NULL; - guint i, j, found_index; + guint i, j, found_index = -1; for (i = 0; i < priv->dpb_count; i++) { GstVaapiFrameStore *const fs = priv->dpb[i]; @@ -824,7 +824,7 @@ dpb_find_lowest_poc (GstVaapiDecoderH264 * decoder, if (found_picture_ptr) *found_picture_ptr = found_picture; - return found_picture ? found_index : -1; + return found_index; } /* Finds the picture with the lowest VOC that needs to be output */ @@ -834,7 +834,7 @@ dpb_find_lowest_voc (GstVaapiDecoderH264 * decoder, { GstVaapiDecoderH264Private *const priv = &decoder->priv; GstVaapiPictureH264 *found_picture = NULL; - guint i, j, found_index; + guint i, j, found_index = -1; for (i = 0; i < priv->dpb_count; i++) { GstVaapiFrameStore *const fs = priv->dpb[i]; @@ -851,7 +851,7 @@ dpb_find_lowest_voc (GstVaapiDecoderH264 * decoder, if (found_picture_ptr) *found_picture_ptr = found_picture; - return found_picture ? found_index : -1; + return found_index; } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 6147e0c89b..2675f79af8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -711,7 +711,7 @@ dpb_find_lowest_poc (GstVaapiDecoderH265 * decoder, { GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiPictureH265 *found_picture = NULL; - guint i, found_index; + guint i, found_index = -1; for (i = 0; i < priv->dpb_count; i++) { GstVaapiPictureH265 *const picture = priv->dpb[i]->buffer; @@ -723,7 +723,7 @@ dpb_find_lowest_poc (GstVaapiDecoderH265 * decoder, if (found_picture_ptr) *found_picture_ptr = found_picture; - return found_picture ? found_index : -1; + return found_index; } static gboolean From 7b3a51f145902aa13a38d37f6f3a88a9dbde83c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Feb 2017 01:19:00 +0100 Subject: [PATCH 2692/3781] libs: encoder: h265: bail if nal unit type fails Bail out if the NAL unit type is not recognized. https://bugzilla.gnome.org/show_bug.cgi?id=778782 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index a838d97f37..b657e0dee6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1625,7 +1625,8 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, pic_param->num_ref_idx_l1_default_active_minus1 = (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0); - get_nal_unit_type (picture, &nal_unit_type); + if (!get_nal_unit_type (picture, &nal_unit_type)) + return FALSE; pic_param->nal_unit_type = nal_unit_type; /* set picture fields */ From a0a2f7bfe8cba66ac5e40924a0fbe03f6341b75e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Feb 2017 01:27:52 +0100 Subject: [PATCH 2693/3781] libs: encoder: caps can change at any time The encoder should be able to change its caps even it is already processing a stream. This is suppose to happen after a flush so the codedbuf_queue should be empty. https://bugzilla.gnome.org/show_bug.cgi?id=775490 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index a55f782bfd..74f4118e41 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -735,9 +735,6 @@ gst_vaapi_encoder_set_codec_state (GstVaapiEncoder * encoder, g_return_val_if_fail (state != NULL, GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER); - if (encoder->num_codedbuf_queued > 0) - goto error_operation_failed; - if (!gst_video_info_is_equal (&state->info, &encoder->video_info)) { status = check_video_info (encoder, &state->info); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) @@ -745,13 +742,6 @@ gst_vaapi_encoder_set_codec_state (GstVaapiEncoder * encoder, encoder->video_info = state->info; } return gst_vaapi_encoder_reconfigure_internal (encoder); - - /* ERRORS */ -error_operation_failed: - { - GST_ERROR ("could not change codec state after encoding started"); - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; - } } /** From 590597091763c057e42c735745c38011281c4616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 16 Feb 2017 18:37:59 +0100 Subject: [PATCH 2694/3781] vaapiencode: merge tags for downstream's info Add encoder and codec name and the bitrate into the output for informational purposes. Some muxers or application use it as media metadata. https://bugzilla.gnome.org/show_bug.cgi?id=778781 --- gst/vaapi/gstvaapiencode.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 61f0fbe4b6..dd609014d1 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -537,6 +537,7 @@ static gboolean gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); + gboolean ret; g_return_val_if_fail (state->caps != NULL, FALSE); @@ -552,8 +553,39 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) encode->input_state = gst_video_codec_state_ref (state); encode->input_state_changed = TRUE; - return gst_pad_start_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode), + ret = gst_pad_start_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode), (GstTaskFunction) gst_vaapiencode_buffer_loop, encode, NULL); + + if (!ret) + return FALSE; + + /* Store some tags */ + { + GstTagList *tags = gst_tag_list_new_empty (); + const gchar *encoder, *codec; + guint bitrate = 0; + + g_object_get (encode, "bitrate", &bitrate, NULL); + gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_NOMINAL_BITRATE, + bitrate, NULL); + + if ((encoder = + gst_element_class_get_metadata (GST_ELEMENT_GET_CLASS (encode), + GST_ELEMENT_METADATA_LONGNAME))) + gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_ENCODER, encoder, + NULL); + + if ((codec = + gst_vaapi_codec_get_name (gst_vaapi_profile_get_codec + (gst_vaapi_profile_from_caps (state->caps))))) + gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_CODEC, codec, + NULL); + + gst_video_encoder_merge_tags (venc, tags, GST_TAG_MERGE_REPLACE); + gst_tag_list_unref (tags); + } + + return TRUE; } static GstFlowReturn From c40f6af547f9a3f48501245c5a642bac3b9d8df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 24 Feb 2017 15:10:21 +0200 Subject: [PATCH 2695/3781] Release 1.11.2 --- ChangeLog | 423 ++++++++++++++++++++++++++++++++++++++++++- NEWS | 2 +- configure.ac | 14 +- gstreamer-vaapi.doap | 10 + 4 files changed, 438 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index cbf0e5d2d4..c38d6c4dbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,426 @@ -=== release 1.11.1 === +=== release 1.11.2 === -2017-01-12 Sebastian Dröge +2017-02-24 Sebastian Dröge * configure.ac: - releasing 1.11.1 + releasing 1.11.2 + +2017-02-16 18:37:59 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: merge tags for downstream's info + Add encoder and codec name and the bitrate into the output for + informational purposes. Some muxers or application use it as + media metadata. + https://bugzilla.gnome.org/show_bug.cgi?id=778781 + +2017-02-17 01:27:52 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: caps can change at any time + The encoder should be able to change its caps even it is already + processing a stream. + This is suppose to happen after a flush so the codedbuf_queue should + be empty. + https://bugzilla.gnome.org/show_bug.cgi?id=775490 + +2017-02-17 01:19:00 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: bail if nal unit type fails + Bail out if the NAL unit type is not recognized. + https://bugzilla.gnome.org/show_bug.cgi?id=778782 + +2017-02-16 18:11:50 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h264,h265 avoid uninitialized variable + Configuring GCC to verify possible usage of uninitialized variables, + shows that found_index might be used without previous assignation. + This patch assigns a initial value to found_index, also avoid a + branching when returning the result value. + https://bugzilla.gnome.org/show_bug.cgi?id=778782 + +2017-02-13 16:39:41 -0800 Scott D Phillips + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + build: rename USE_HEVC_DECODER to USE_H265_DECODER + Rename to be consistent with H.264 and also H.265 encoder. The + meson build assumed this was already consistently named, and so + previously was not able to actually build the H.265 decoder. + https://bugzilla.gnome.org/show_bug.cgi?id=778576 + +2017-02-15 19:14:59 +0000 Tim-Philipp Müller + + * meson.build: + meson: gstreamer-codecparsers is a required dep + Just like in configure.ac. + +2017-02-15 00:26:21 +0000 Tim-Philipp Müller + + * Makefile.am: + meson: dist meson build files + Ship meson build files in tarballs, so people who use tarballs + in their builds can start playing with meson already. + +2017-02-10 09:51:38 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: encoder: vp8: add CBR encoding mode + This patch enables the Constant BitRate encoding mode in VP8 encoder. + Basically it adds the configuration parameters required by libva to + CBR enconding. + Original-Patch-By: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=749950 + +2017-02-09 12:39:19 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: encoder: vp8: fix bitrate calculation + Base encoder's unit of bitrate is in Kbps. We should honor it so + we use the value of bitrate in VA, in which is expressed in bps. + https://bugzilla.gnome.org/show_bug.cgi?id=749950 + +2017-02-09 12:49:44 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: fix build when gcc + In commit a8e482f9 we added a function without parameters, but gcc + doesn't like that. + +2017-02-06 15:46:20 -0800 Scott D Phillips + + * gst-libs/gst/base/meson.build: + * gst-libs/gst/meson.build: + * gst-libs/gst/vaapi/meson.build: + * gst-libs/meson.build: + * gst/meson.build: + * gst/vaapi/meson.build: + * meson.build: + * meson_options.txt: + vaapi: add meson build + https://bugzilla.gnome.org/show_bug.cgi?id=778250 + +2017-02-08 10:17:40 -0800 Scott D Phillips + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiversion.h.in: + make: remove gstvaapiversion.h generation + https://bugzilla.gnome.org/show_bug.cgi?id=778250 + +2016-10-19 15:47:41 +0100 Julien Isorce + + * gst/vaapi/gstvaapipluginbase.c: + plugins: use linear storage if not the same device + When dmabuf is negotiated downstream and decoding and rendering are + not done on the same device, the layout has to be linear in order for + the memory to be shared accross devices, since each device has its + own way to do tiling. + Right now this code is rather just a to-do comment, since we are not + fetching the device ids. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2017-02-08 14:17:05 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: add HEVC profiles representation + https://bugzilla.gnome.org/show_bug.cgi?id=778318 + +2017-02-07 16:17:39 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: reduce frame number of gaps + Reduce frame num gaps so that we don't have to create unnecessary + dummy pictures, just throw them away. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=777506 + +2016-10-16 01:04:09 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: don't GLTextureUpload if dmabuf + Do not add the meta:GstVideoGLTextureUploadMeta feature if the render + element can handle dmabuf-based buffers, avoiding its negotiation. + +2016-10-19 16:21:21 +0100 Julien Isorce + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: make pool to export decoder's surface + Use new -base API gst_video_decoder_allocate_output_frame_full() to + pass the current proxy/surface to the pool. + The pool will will export thins given surface instead of exporting a + brand new surface that will never be filled in with meaningfull data. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2017-02-03 17:06:29 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: decoder can negotiate dmabuf downstream + +2016-10-19 16:07:07 +0100 Julien Isorce + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: override acquire_buffer() + Overriding the vmethod acquire_buffer() it is possible to attach the + right GstMemory to the current acquired buffer. + As a matter of fact, this acquired buffer may contain any instantiated + GstFdmemory, since this buffer have been popped out from the buffer + pool, which is a FIFO queue. So there is no garantee that this buffer + matches with the current processed surface. Evenmore, the VA driver + might not use a FIFO queue. Therefore, it is no way to guess on the + ordering. + In short, acquire_buffer on the VA driver and on the buffer pool return + none matching data, we have to manually attach the right GstFdMemory to + the acquired GstBuffer. The right GstMemory is the one associated with + the current surface. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-10-19 16:05:04 +0100 Julien Isorce + + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: export surface if it is provided + gst_vaapi_dmabuf_memory_new() always exports a surface. Previously, it + had to create that surface. Now it can also export an already provided + surface. It is useful to export decoder's surfaces (from VA context). + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-10-19 15:55:27 +0100 Julien Isorce + + * gst/vaapi/gstvaapivideobufferpool.h: + vaapivideobufferpool: add GstVaapiVideoBufferPoolAcquireParams + Useful to let the pool know the current surface proxy when calling + gst_buffer_pool_alloc_buffer() / gst_buffer_pool_acquire_buffer() + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-10-19 15:09:34 +0100 Julien Isorce + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + libs: surface: add gst_vaapi_surface_{set,peek}_buffer_proxy() + These functions are useful when a dmabuf-based memory is instantiated in + order to relate the generated buffer @proxy with the processed @surface. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-10-19 15:07:31 +0100 Julien Isorce + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy.h: + * gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h: + libs: bufferproxy: gst_vaapi_buffer_proxy_{set,peek}_mem() + This patch adds a GstMemory as a variable member of the buffer proxy, + because we will need to associate the buffer proxy with the memory + which exposes it. Later, we will know which memory, in the video buffer + pool, is attached to the processed surface. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-10-19 15:33:41 +0100 Julien Isorce + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: don't GLTextureUpload if dmabuf + Do not add the meta:GstVideoGLTextureUploadMeta feature if the render + element can handle dmabuf-based buffers, avoiding its negotiation. + Similar as "vaapidecode: do not add meta:GstVideoGLTextureUploadMeta + feature if can dmabuf" + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-12-16 14:12:30 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: enable DMAbuf allocator to downstream + If the negotiated caps are raw caps and downstream supports the + EGL_EXT_image_dma_buf_import extension, then the created allocator + is the DMAbuf, configured to downstream. + At this moment, the only element which can push dmabuf-based buffers + to downstream, is vaapipostproc. + +2016-06-02 22:13:51 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: check if negotiate dmabuf with downstream + In order to enable, in the future, dmabuf-based buffers, the vaapi base + plugin needs to check if downstream can import dmabuf buffers. + This patch checks if downstream can handle dmabuf, by introspecting the + shared GL context. If the GL context is EGL/GLES2 and have the extension + EGL_EXT_image_dma_buf_import, then dmabuf can be negotiated. + Original-patch-by: Julien Isorce + +2016-10-19 15:37:04 +0100 Julien Isorce + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: release proxy's data if downstream + The surface created for downstream is going to be filled by VAAPI + elements. So, the driver needs write access on that surface. + This patch releases the derived image held by the proxy, thus the + surface is unmarked as busy. + This is how it has to be done as discussed on libva mailing list. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-10-19 15:01:04 +0100 Julien Isorce + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy.h: + libs: bufferproxy: add gst_vaapi_buffer_proxy_release_data() + Adds an API to request the user's data release in the buffer proxy. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-10-19 15:27:03 +0100 Julien Isorce + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: add direction to dmabuf allocator + Add GstPadDirection param to gst_vaapi_dmabuf_allocator_new(), thus + we later could do different thing when the allocated memory is for + upstream or dowstream, as required by VA-API. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-12-15 15:59:30 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiutils_core.c: + libs: utils: return NULL if failed to get surface formats + Thus, when generating the allowed caps, the element will throw a + warning and it will use its caps template. + This behavior might be a bug in the VA driver. + https://bugzilla.gnome.org/show_bug.cgi?id=775490 + +2015-11-26 18:21:08 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + Revert "vaapidisplay: mark X11 display as compatible with EGL" + This reverts commit 200b1baabc066f8a4102f82f539655d588200ec9. + +2017-02-01 14:32:45 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: set GST_VAAPI_POSTPROC_FLAG_SIZE according to src caps + A value of width/height property should be set to out caps, + if negotiation had been going properly. + So we can use srcpad_info when making decision of scaling. + https://bugzilla.gnome.org/show_bug.cgi?id=778010 + +2017-01-27 12:10:54 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + plugins: handle GL params through context query + If the element instantiated the GL display and context, they should + handle them too through the context query. + https://bugzilla.gnome.org/show_bug.cgi?id=777409 + +2017-01-26 12:02:56 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipluginutil.c: + plugins: create a GL context on certain conditions + If a GstVaapiDisplay is not found in the GStreamer context sharing, + then VAAPI elements look for a local GstGLContext in gst context + sharing mechanism ('gst.gl.local.context'). + If this GstGLContext not found either then, only the VAAPI decoders + and the VAAPI post-processor, will try to instantiate a new + GstGLContext. + If a valid GstGLContext is received, then a new GstVaapiDisplay will + be instantiated with the platform, API and windowing specified by the + instantiated GstGLContext. + Original-Patch-By: Matt Fischer + https://bugzilla.gnome.org/show_bug.cgi?id=777409 + +2016-08-02 15:48:25 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + vaapivideocontext: context type can be rejected + Instead of calling g_return_val_if_fail() to check the context type, we + should use a normal conditional, since it is possible that other context types + can arrive and try to be assigned. Otherwise a critical log message is + printed. + This happens when we use playbin3 with vaapipostproc as video-filter. + https://bugzilla.gnome.org/show_bug.cgi?id=777409 + +2017-01-20 19:57:52 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: use sink caps par if not requested + Use the sink caps pixel-aspect-ratio to fixate the src caps, if it + is not already set. + https://bugzilla.gnome.org/show_bug.cgi?id=777395 + +2017-01-20 19:00:24 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: set interlace mode + if the vaapipostproc is configured to not do deinterlacing, the + interlace-mode in the src caps should be the same as the input caps. + https://bugzilla.gnome.org/show_bug.cgi?id=777395 + +2017-01-20 16:10:32 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix gcc compiler warning + warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] + +2017-01-12 19:54:41 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: don't use member variable outside lock + Thus a race condition segfault is avoided. + Original-patch-by: Matt Staples + https://bugzilla.gnome.org/show_bug.cgi?id=777146 + +2017-01-18 17:20:21 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipostproc.c: + plugins: avoid log flood when activating pool + Every time a new buffer is allocated, the pool is activated. This + doesn't impact in performance since gst_buffer_pool_set_active() + checks the current state of the pool. Nonetheless it logs out a + message if the state is the same, and it floods the logging subsystem + if it is enabled. + To avoid this log flooding first the pool state is checked before + changing it. + +2017-01-13 21:26:15 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + vaapidecode: update internal decoder sink caps + When a new sink caps arrive the internal decoder state is updated + and, if it is, request a downstream renegotiation. + Previously, when new caps arrived the whole decoder where destroyed + and recreated. Now, if the caps are compatible or has the same codec, + the internal decoder is kept, but a downstream renegotiation is + requested. + https://bugzilla.gnome.org/show_bug.cgi?id=776979 + +2017-01-12 16:33:13 +0200 Sebastian Dröge + + * configure.ac: + Back to development + +=== release 1.11.1 === + +2017-01-12 16:27:12 +0200 Sebastian Dröge + + * ChangeLog: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + Release 1.11.1 2017-01-12 12:49:55 +0100 Víctor Manuel Jáquez Leal diff --git a/NEWS b/NEWS index a940f7bb0f..ba794a2734 100644 --- a/NEWS +++ b/NEWS @@ -1 +1 @@ -This is GStreamer 1.11.1. +This is GStreamer 1.11.2. diff --git a/configure.ac b/configure.ac index ba223f8622..21652743fc 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [11]) -m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_nano_version], [1]) +m4_define([gst_vaapi_micro_version], [2]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1101]) +m4_define([gst_vaapi_lt_current], [1102]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1101]) +m4_define([gst_vaapi_lt_age], [1102]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.11.1.1]) -m4_define([gst_plugins_base_version], [1.11.1.1]) -m4_define([gst_plugins_bad_version], [1.11.1.1]) +m4_define([gst_version], [1.11.2]) +m4_define([gst_plugins_base_version], [1.11.2]) +m4_define([gst_plugins_bad_version], [1.11.2]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index d51583bc0b..7b9167c8dd 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.11.2 + master + + 2017-02-24 + + + + 1.11.1 From 20af04baa05983e59d6035393ea6f936a2004c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 24 Feb 2017 15:38:22 +0200 Subject: [PATCH 2696/3781] Back to development --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 21652743fc..f55c3d0661 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [11]) m4_define([gst_vaapi_micro_version], [2]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -24,9 +24,9 @@ m4_define([gst_vaapi_lt_age], [1102]) m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.11.2]) -m4_define([gst_plugins_base_version], [1.11.2]) -m4_define([gst_plugins_bad_version], [1.11.2]) +m4_define([gst_version], [1.11.2.1]) +m4_define([gst_plugins_base_version], [1.11.2.1]) +m4_define([gst_plugins_bad_version], [1.11.2.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) From 98b41956e1942c4368dc8a971eeb8cde80482014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 24 Feb 2017 16:00:23 +0200 Subject: [PATCH 2697/3781] meson: Update version --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 59f5d0749f..1c1cbb2aff 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.11.1.1', + version : '1.11.2.1', meson_version : '>= 0.36.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 04a844ced08930e6f758b946f9396f573144992b Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 23 Feb 2017 15:13:59 +0900 Subject: [PATCH 2698/3781] libs: encoder: set rate control info only when query succeed Currently, it set rate control information even when query fails. In addition, it doesn't update any more since the flag got_rate_control_mask is set to TRUE. https://bugzilla.gnome.org/show_bug.cgi?id=779120 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 74f4118e41..6f8ef2837d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -855,11 +855,12 @@ get_rate_control_mask (GstVaapiEncoder * encoder) continue; rate_control_mask |= 1 << to_GstVaapiRateControl (1 << i); } - } - GST_INFO ("supported rate controls: 0x%08x", rate_control_mask); + GST_INFO ("supported rate controls: 0x%08x", rate_control_mask); + + encoder->got_rate_control_mask = TRUE; + encoder->rate_control_mask = cdata->rate_control_mask & rate_control_mask; + } - encoder->got_rate_control_mask = TRUE; - encoder->rate_control_mask = cdata->rate_control_mask & rate_control_mask; return encoder->rate_control_mask; } From 6468bf2ddf0463f5ec24a945ac4fad182fecac6f Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 23 Feb 2017 15:16:06 +0900 Subject: [PATCH 2699/3781] libs: encoder: ensure profile when context initialization We can't be sure that encoder's profile is assgined already or not at context initialization. https://bugzilla.gnome.org/show_bug.cgi?id=779120 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 6f8ef2837d..2989ff805b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -596,7 +596,7 @@ init_context_info (GstVaapiEncoder * encoder) GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; - cip->profile = encoder->profile; + cip->profile = get_profile (encoder); if (cdata->codec == GST_VAAPI_CODEC_JPEG) { cip->entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; } else { From c4ef77993184e528f884c5806399b287daa72cef Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 1 Mar 2017 14:48:46 +0900 Subject: [PATCH 2700/3781] libs: window: wayland: handle more VAStatus to use vpp Since the commit landed https://github.com/01org/intel-vaapi-driver/pull/55, we should consider more returned VAStatus to use vpp. https://bugzilla.gnome.org/show_bug.cgi?id=779400 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 85a1c437a9..b299d762d5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -495,7 +495,9 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, GST_VAAPI_OBJECT_ID (surface), va_flags & (VA_TOP_FIELD | VA_BOTTOM_FIELD), &buffer); GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); - if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED) + if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED || + status == VA_STATUS_ERROR_UNIMPLEMENTED || + status == VA_STATUS_ERROR_INVALID_IMAGE_FORMAT) need_vpp = TRUE; else if (!vaapi_check_status (status, "vaGetSurfaceBufferWl()")) return FALSE; From e0891d93cef50263c204c20251d5dd4058725138 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 22 Feb 2017 15:02:01 -0800 Subject: [PATCH 2701/3781] configure: Add missing compiler flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AC_CHECK_HEADERS macro was failing to locate some headers, in particular the va_enc_* headers due to missing compiler flags. https://bugzilla.gnome.org/show_bug.cgi?id=779101 Signed-off-by: Víctor Manuel Jáquez Leal --- configure.ac | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index f55c3d0661..10c5835779 100644 --- a/configure.ac +++ b/configure.ac @@ -326,7 +326,10 @@ HAVE_XRENDER=0 if test $USE_X11 -eq 1; then dnl Check for XKB library HAVE_XKBLIB=1 + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $X11_CFLAGS" AC_CHECK_HEADERS([X11/XKBlib.h], [], [HAVE_XKBLIB=0]) + CPPFLAGS="$saved_CPPFLAGS" dnl Check for XRandR PKG_CHECK_MODULES([XRANDR], [xrandr], @@ -454,6 +457,8 @@ if test "x$enable_egl" = "xyes" -a $GLES_VERSION_MASK -ne 0; then saved_CPPFLAGS="$CPPFLAGS" saved_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $EGL_CFLAGS" + LIBS="$LIBS $EGL_LIBS" AC_CHECK_HEADERS([EGL/egl.h], [], [USE_EGL=0]) AC_CHECK_LIB([EGL], [eglGetDisplay], [], [USE_EGL=0]) CPPFLAGS="$saved_CPPFLAGS" @@ -490,7 +495,7 @@ if test $USE_DRM -eq 1; then PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= $VAAPI_DRM_REQ], [ saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$LIBVA_DRM_CFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_DRM_CFLAGS" AC_CHECK_HEADERS([va/va_drm.h], [], [USE_DRM=0]) CPPFLAGS="$saved_CPPFLAGS" ], [USE_DRM=0]) @@ -708,7 +713,7 @@ if test "x$enable_encoders" = "xyes"; then [ USE_ENCODERS=1 saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$LIBVA_CFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" AC_CHECK_HEADERS([va/va_enc_mpeg2.h va/va_enc_h264.h], [], [USE_ENCODERS=0], [ @@ -724,6 +729,9 @@ USE_H265_ENCODER=0 USE_VP9_ENCODER=0 if test $USE_ENCODERS -eq 1; then + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + dnl Check for JPEG Encoding API (0.37.0+) AC_CHECK_HEADERS([va/va_enc_jpeg.h], [], [], [ @@ -732,8 +740,6 @@ if test $USE_ENCODERS -eq 1; then AC_CACHE_CHECK([for JPEG encoding API], [ac_cv_have_jpeg_encoding_api], [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $LIBVA_LIBS" AC_COMPILE_IFELSE( @@ -753,7 +759,6 @@ VAQMatrixBufferJPEG q_matrix; ], [ac_cv_have_jpeg_encoding_api="yes"], [ac_cv_have_jpeg_encoding_api="no"]) - CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) AS_IF([test "x$ac_cv_have_jpeg_encoding_api" = "xyes"], [USE_JPEG_ENCODER=1]) @@ -766,8 +771,6 @@ VAQMatrixBufferJPEG q_matrix; AC_CACHE_CHECK([for VP8 encoding API], [ac_cv_have_vp8_encoding_api], [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $LIBVA_LIBS" AC_COMPILE_IFELSE( @@ -787,7 +790,6 @@ VAQMatrixBufferVP8 q_matrix; ], [ac_cv_have_vp8_encoding_api="yes"], [ac_cv_have_vp8_encoding_api="no"]) - CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) AS_IF([test "x$ac_cv_have_vp8_encoding_api" = "xyes"], [USE_VP8_ENCODER=1]) @@ -800,8 +802,6 @@ VAQMatrixBufferVP8 q_matrix; AC_CACHE_CHECK([for HEVC encoding API], [ac_cv_have_hevc_encoding_api], [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $LIBVA_LIBS" AC_COMPILE_IFELSE( @@ -822,7 +822,6 @@ VAQMatrixBufferHEVC q_matrix; ], [ac_cv_have_hevc_encoding_api="yes"], [ac_cv_have_hevc_encoding_api="no"]) - CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) AS_IF([test "x$ac_cv_have_hevc_encoding_api" = "xyes"], [USE_H265_ENCODER=1]) @@ -835,8 +834,6 @@ VAQMatrixBufferHEVC q_matrix; AC_CACHE_CHECK([for VP9 encoding API], [ac_cv_have_vp9_encoding_api], [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" saved_LIBS="$LIBS" LIBS="$LIBS $LIBVA_LIBS" AC_COMPILE_IFELSE( @@ -857,10 +854,11 @@ VAEncMiscParameterTypeVP9PerSegmantParam misc_param; ], [ac_cv_have_vp9_encoding_api="yes"], [ac_cv_have_vp9_encoding_api="no"]) - CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" ]) AS_IF([test "x$ac_cv_have_vp9_encoding_api" = "xyes"], [USE_VP9_ENCODER=1]) + + CPPFLAGS="$saved_CPPFLAGS" fi dnl VA/Wayland API From bce6e1416b322cff6c159f10b4db72bb3d96b5a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 25 Oct 2016 17:48:47 +0200 Subject: [PATCH 2702/3781] vaapidecode: texture upload if driver supports GL When the allowed source pad caps are generated, the GLTextureUpload caps are only inserted if the driver support OpenGL. https://bugzilla.gnome.org/show_bug.cgi?id=772838 --- gst/vaapi/gstvaapidecode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b279b83c9e..407e25b36a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -219,7 +219,8 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) return FALSE; } #if (USE_GLX || USE_EGL) - if (!GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (decode)) { + if (!GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (decode) && + gst_vaapi_display_has_opengl (GST_VAAPI_PLUGIN_BASE_DISPLAY (decode))) { out_caps = gst_caps_make_writable (out_caps); gst_caps_append (out_caps, gst_caps_from_string (GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS)); From 8d86b3f40aee44379edf2fbd4dc493f255b3eaef Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 19 Oct 2016 15:33:41 +0100 Subject: [PATCH 2703/3781] vaapipostproc: texture upload if driver supports GL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes GstVideoGLTextureUploadMeta caps feature if the driver doesn't support opengl. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=772838 --- gst/vaapi/gstvaapipostproc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index cb48ed3668..f4ddbb5116 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1065,7 +1065,9 @@ expand_allowed_srcpad_caps (GstVaapiPostproc * postproc, GstCaps * caps) } g_value_unset (&value); - if (GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (postproc) + if ((GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (postproc) + || !gst_vaapi_display_has_opengl (GST_VAAPI_PLUGIN_BASE_DISPLAY + (postproc))) && gl_upload_meta_idx > -1) { gst_caps_remove_structure (caps, gl_upload_meta_idx); } From 3723d2051a782e994517fb6eaac8ede9e82ecf78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 Mar 2017 19:55:00 +0100 Subject: [PATCH 2704/3781] plugins: retry to create the VA display Particularly in GNOME Wayland, the negotiated or created GL context defines a GLX environment, but VAAPI fails to create a GLX VA display because there is no a DRI2 connection. This patch retries to create the VA display if VA cannot create one with the GL context parameters. Now using the old list of display types. This should also work in the case of systems with two GPU, when the non-VAAPI has the graphics environment, and the VAAPI-enabled one shall work headless. https://bugzilla.gnome.org/show_bug.cgi?id=772838 --- gst/vaapi/gstvaapipluginutil.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 2ac5a1a9d5..9a12472baa 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -268,7 +268,7 @@ gboolean gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type) { GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); - GstVaapiDisplay *display; + GstVaapiDisplay *display = NULL; g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); @@ -284,9 +284,15 @@ gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type) gst_vaapi_find_gl_context (element); /* If no neighboor, or application not interested, use system default */ - if (plugin->gl_context) + if (plugin->gl_context) { display = gst_vaapi_create_display_from_gl_context (plugin->gl_context); - else + /* Cannot instantiate VA display based on GL context. Reset the + * requested display type to ANY to try again */ + if (!display) + gst_vaapi_plugin_base_set_display_type (plugin, + GST_VAAPI_DISPLAY_TYPE_ANY); + } + if (!display) display = gst_vaapi_create_display (type, plugin->display_name); if (!display) return FALSE; From bcd0887140bea7d123e93eb005acc58fec730873 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Sun, 12 Mar 2017 21:39:53 +0100 Subject: [PATCH 2705/3781] README: fix "Reporting bugs" section The "Reporting bugs" section gives https://bugzilla.gnome.org/enter_bug.cgi?product=gstreamer-vaapi as the link to report a bug, but this link says "Sorry, entering a bug into the product gstreamer-vaapi has been disabled.". This commit fixes the URL to point to the proper location, and also removes the following paragraph that is no longer correct. Signed-off-by: Thomas Petazzoni https://bugzilla.gnome.org/show_bug.cgi?id=779954 --- README | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README b/README index 9c2d9cfb53..0bdaa07836 100644 --- a/README +++ b/README @@ -135,7 +135,4 @@ Reporting Bugs -------------- Bugs can be reported in the GNOME Bugzilla system at: - - - From the main page, new bugs can be reported through New -> Other -> - gstreamer-vaapi product. + From 7b64cec70fd2e3ffc74d2236f5ac5e8235f13f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 14 Mar 2017 16:07:08 +0100 Subject: [PATCH 2706/3781] README: fix "Sources" section Update the URL where the release source tarballs can be downloaded. --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 0bdaa07836..6a4fed1633 100644 --- a/README +++ b/README @@ -125,7 +125,7 @@ Sources framework are really easy to get. Stable source code releases can be found at: - + Git repository for work-in-progress changes is available at: From 159e3c3f08ef1c19da4ede8a437337dd8cf7f0b7 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Sun, 12 Mar 2017 18:59:42 +0100 Subject: [PATCH 2707/3781] O_CLOEXEC needs _GNU_SOURCE defined From man open(2): The O_CLOEXEC, O_DIRECTORY, and O_NOFOLLOW flags are not specified in POSIX.1-2001, but are specified in POSIX.1-2008. Since glibc 2.12, one can obtain their definitions by defining either _POSIX_C_SOURCE with a value greater than or equal to 200809L or _XOPEN_SOURCE with a value greater than or equal to 700. In glibc 2.11 and earlier, one obtains the definitions by defining _GNU_SOURCE. And indeed, with the uClibc C library, O_CLOEXEC is not exposed if _GNU_SOURCE is not defined. Therefore, this commit fixes the build of gstreamer-vaapi with the uClibc C library. Signed-off-by: Thomas Petazzoni https://bugzilla.gnome.org/show_bug.cgi?id=779953 --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 1 + tests/test-display.c | 1 + 2 files changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index f4360366b9..00ff039546 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -25,6 +25,7 @@ * @short_description: VA/DRM display abstraction */ +#define _GNU_SOURCE #include "sysdeps.h" #include #include diff --git a/tests/test-display.c b/tests/test-display.c index be9c24be21..9abe7546d9 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ +#define _GNU_SOURCE #include "gst/vaapi/sysdeps.h" #include #if USE_DRM From 7f38b3b9f2f513de9cd6729713b15fbd68177dcf Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Mon, 13 Mar 2017 16:20:59 +0900 Subject: [PATCH 2708/3781] libs: encoder: h265: fix reserved length of bits Fix reserved length of bits for bit_depth_luma_minus8 and bit_depth_chroma_minus8 https://bugzilla.gnome.org/show_bug.cgi?id=778749 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index b657e0dee6..6a2b283769 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2171,9 +2171,9 @@ gst_vaapi_encoder_h265_get_codec_data (GstVaapiEncoder * base_encoder, WRITE_UINT32 (&bs, 0x00, 2); /* parallelismType */ WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */ WRITE_UINT32 (&bs, 0x01, 2); /* chroma_format_idc */ - WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */ + WRITE_UINT32 (&bs, 0x1f, 5); /* 11111 */ WRITE_UINT32 (&bs, 0x01, 3); /* bit_depth_luma_minus8 */ - WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */ + WRITE_UINT32 (&bs, 0x1f, 5); /* 11111 */ WRITE_UINT32 (&bs, 0x01, 3); /* bit_depth_chroma_minus8 */ WRITE_UINT32 (&bs, 0x00, 16); /* avgFramerate */ WRITE_UINT32 (&bs, 0x00, 2); /* constatnFramerate */ From e65d916f0d78b388376301c4bffe19b452b12c8d Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Mon, 13 Mar 2017 17:29:59 +0900 Subject: [PATCH 2709/3781] docs: h264/h265: put parser to the example pipeline https://bugzilla.gnome.org/show_bug.cgi?id=778749 --- gst/vaapi/gstvaapiencode_h264.c | 2 +- gst/vaapi/gstvaapiencode_h265.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 4389d7d8c5..35306ebda3 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -30,7 +30,7 @@ * * Example launch line * |[ - * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapih264enc ! mp4mux ! filesink location=test.mp4 + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapih264enc ! h264parse ! mp4mux ! filesink location=test.mp4 * ]| * */ diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index a577657f9a..3915b2f11a 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -29,7 +29,7 @@ * * Example launch line * |[ - * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapih265enc ! matroskamux ! filesink location=test.mkv + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapih265enc ! h265parse ! matroskamux ! filesink location=test.mkv * ]| * */ From 257cfb61fee1cecd0fe9a8164a309f371f644200 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 17 Mar 2017 16:32:36 +0900 Subject: [PATCH 2710/3781] libs: encoder: h264/5: fix wrong return value https://bugzilla.gnome.org/show_bug.cgi?id=778750 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 49a7988bf8..450d43598b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2633,7 +2633,7 @@ bs_error: gst_buffer_unmap (encoder->sps_data, &sps_info); gst_buffer_unmap (encoder->pps_data, &pps_info); gst_bit_writer_clear (&bs, TRUE); - return FALSE; + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } error_map_sps_buffer: { diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 6a2b283769..39fca6c6b6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2231,7 +2231,7 @@ bs_error: gst_buffer_unmap (encoder->sps_data, &sps_info); gst_buffer_unmap (encoder->pps_data, &pps_info); gst_bit_writer_clear (&bs, TRUE); - return FALSE; + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } error_map_vps_buffer: { From 49b370ed600c713f0c309bf6091994393af2a6bd Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 17 Mar 2017 16:49:41 +0900 Subject: [PATCH 2711/3781] libs: utils: h26x: create vaapiutils_h26x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since there is duplicated code in h264/265 encoder, we could refactor it to avoid duplicated code. https://bugzilla.gnome.org/show_bug.cgi?id=778750 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 76 +----------------- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 76 +----------------- gst-libs/gst/vaapi/gstvaapiutils_h26x.c | 58 ++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h | 82 ++++++++++++++++++++ gst-libs/gst/vaapi/meson.build | 1 + 6 files changed, 145 insertions(+), 150 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_h26x.c create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 1159928da4..50bdef8e58 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -78,6 +78,7 @@ libgstvaapi_source_c = \ gstvaapiutils_core.c \ gstvaapiutils_h264.c \ gstvaapiutils_h265.c \ + gstvaapiutils_h26x.c \ gstvaapiutils_mpeg2.c \ gstvaapivalue.c \ gstvaapivideopool.c \ @@ -142,6 +143,7 @@ libgstvaapi_source_priv_h = \ gstvaapiutils_core.h \ gstvaapiutils_h264_priv.h \ gstvaapiutils_h265_priv.h \ + gstvaapiutils_h26x_priv.h \ gstvaapiutils_mpeg2_priv.h \ gstvaapivideopool_priv.h \ gstvaapiwindow_priv.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 450d43598b..801a721f7c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -36,6 +36,7 @@ #include "gstvaapiencoder_h264.h" #include "gstvaapiutils_h264.h" #include "gstvaapiutils_h264_priv.h" +#include "gstvaapiutils_h26x_priv.h" #include "gstvaapicodedbufferproxy_priv.h" #include "gstvaapisurface.h" @@ -49,21 +50,6 @@ /* Define the maximum value for view-id */ #define MAX_VIEW_ID 1023 -/* Define the maximum IDR period */ -#define MAX_IDR_PERIOD 512 - -/* Default CPB length (in milliseconds) */ -#define DEFAULT_CPB_LENGTH 1500 - -/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */ -#define SX_CPB_SIZE 4 - -/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ -#define SX_BITRATE 6 - -/* 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) | \ @@ -200,66 +186,6 @@ h264_get_cpb_nal_factor (GstVaapiProfile profile) return f; } -/* ------------------------------------------------------------------------- */ -/* --- H.264 Bitstream Writer --- */ -/* ------------------------------------------------------------------------- */ - -#define WRITE_UINT32(bs, val, nbits) do { \ - if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \ - GST_WARNING ("failed to write uint32, nbits: %d", nbits); \ - goto bs_error; \ - } \ - } while (0) - -#define WRITE_UE(bs, val) do { \ - if (!bs_write_ue (bs, val)) { \ - GST_WARNING ("failed to write ue(v)"); \ - goto bs_error; \ - } \ - } while (0) - -#define WRITE_SE(bs, val) do { \ - if (!bs_write_se (bs, val)) { \ - GST_WARNING ("failed to write se(v)"); \ - goto bs_error; \ - } \ - } while (0) - -/* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */ -static gboolean -bs_write_ue (GstBitWriter * bs, guint32 value) -{ - guint32 size_in_bits = 0; - guint32 tmp_value = ++value; - - while (tmp_value) { - ++size_in_bits; - tmp_value >>= 1; - } - if (size_in_bits > 1 - && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1)) - return FALSE; - if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits)) - return FALSE; - return TRUE; -} - -/* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */ -static gboolean -bs_write_se (GstBitWriter * bs, gint32 value) -{ - guint32 new_val; - - if (value <= 0) - new_val = -(value << 1); - else - new_val = (value << 1) - 1; - - if (!bs_write_ue (bs, new_val)) - return FALSE; - return TRUE; -} - /* Write the NAL unit header */ static gboolean bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc, diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 39fca6c6b6..e156fdbb49 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -36,27 +36,13 @@ #include "gstvaapiencoder_h265.h" #include "gstvaapiutils_h265.h" #include "gstvaapiutils_h265_priv.h" +#include "gstvaapiutils_h26x_priv.h" #include "gstvaapicodedbufferproxy_priv.h" #include "gstvaapisurface.h" #define DEBUG 1 #include "gstvaapidebug.h" -/* Define the maximum IDR period */ -#define MAX_IDR_PERIOD 512 - -/* Default CPB length (in milliseconds) */ -#define DEFAULT_CPB_LENGTH 1500 - -/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ -#define SX_BITRATE 6 - -/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */ -#define SX_CPB_SIZE 4 - -/* 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)) | \ @@ -205,66 +191,6 @@ h265_get_log2_max_pic_order_cnt (guint num) return ret; } -/* ------------------------------------------------------------------------- */ -/* --- H.265 Bitstream Writer --- */ -/* ------------------------------------------------------------------------- */ - -#define WRITE_UINT32(bs, val, nbits) do { \ - if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \ - GST_WARNING ("failed to write uint32, nbits: %d", nbits); \ - goto bs_error; \ - } \ - } while (0) - -#define WRITE_UE(bs, val) do { \ - if (!bs_write_ue (bs, val)) { \ - GST_WARNING ("failed to write ue(v)"); \ - goto bs_error; \ - } \ - } while (0) - -#define WRITE_SE(bs, val) do { \ - if (!bs_write_se (bs, val)) { \ - GST_WARNING ("failed to write se(v)"); \ - goto bs_error; \ - } \ - } while (0) - -/* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */ -static gboolean -bs_write_ue (GstBitWriter * bs, guint32 value) -{ - guint32 size_in_bits = 0; - guint32 tmp_value = ++value; - - while (tmp_value) { - ++size_in_bits; - tmp_value >>= 1; - } - if (size_in_bits > 1 - && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1)) - return FALSE; - if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits)) - return FALSE; - return TRUE; -} - -/* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */ -static gboolean -bs_write_se (GstBitWriter * bs, gint32 value) -{ - guint32 new_val; - - if (value <= 0) - new_val = -(value << 1); - else - new_val = (value << 1) - 1; - - if (!bs_write_ue (bs, new_val)) - return FALSE; - return TRUE; -} - /* Write the NAL unit header */ static gboolean bs_write_nal_header (GstBitWriter * bs, guint32 nal_unit_type) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h26x.c b/gst-libs/gst/vaapi/gstvaapiutils_h26x.c new file mode 100644 index 0000000000..717be39339 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_h26x.c @@ -0,0 +1,58 @@ +/* + * gstvaapiutils_h26x.c - H.26x related utilities + * + * Copyright (C) 2011-2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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 "gstvaapiutils_h26x_priv.h" + +/* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */ +gboolean +bs_write_ue (GstBitWriter * bs, guint32 value) +{ + guint32 size_in_bits = 0; + guint32 tmp_value = ++value; + + while (tmp_value) { + ++size_in_bits; + tmp_value >>= 1; + } + if (size_in_bits > 1 + && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1)) + return FALSE; + if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits)) + return FALSE; + return TRUE; +} + +/* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */ +gboolean +bs_write_se (GstBitWriter * bs, gint32 value) +{ + guint32 new_val; + + if (value <= 0) + new_val = -(value << 1); + else + new_val = (value << 1) - 1; + + if (!bs_write_ue (bs, new_val)) + return FALSE; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h new file mode 100644 index 0000000000..a1ede90520 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h @@ -0,0 +1,82 @@ +/* + * gstvaapiutils_h26x_priv.h - H.26x related utilities + * + * Copyright (C) 2011-2014 Intel Corporation + * Author: Gwenole Beauchesne + * + * 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_UTILS_H26X_PRIV_H +#define GST_VAAPI_UTILS_H26X_PRIV_H + +#include + +G_BEGIN_DECLS + +/* Define the maximum IDR period */ +#define MAX_IDR_PERIOD 512 + +/* Default CPB length (in milliseconds) */ +#define DEFAULT_CPB_LENGTH 1500 + +/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */ +#define SX_CPB_SIZE 4 + +/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ +#define SX_BITRATE 6 + +/* Define default rate control mode ("constant-qp") */ +#define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP + +/* ------------------------------------------------------------------------- */ +/* --- H.264/265 Bitstream Writer --- */ +/* ------------------------------------------------------------------------- */ + +#define WRITE_UINT32(bs, val, nbits) \ + G_STMT_START { \ + if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \ + GST_WARNING ("failed to write uint32, nbits: %d", nbits); \ + goto bs_error; \ + } \ + } G_STMT_END + +#define WRITE_UE(bs, val) \ + G_STMT_START { \ + if (!bs_write_ue (bs, val)) { \ + GST_WARNING ("failed to write ue(v)"); \ + goto bs_error; \ + } \ + } G_STMT_END + +#define WRITE_SE(bs, val) \ + G_STMT_START { \ + if (!bs_write_se (bs, val)) { \ + GST_WARNING ("failed to write se(v)"); \ + goto bs_error; \ + } \ + } G_STMT_END + + +gboolean +bs_write_ue (GstBitWriter * bs, guint32 value); + +gboolean +bs_write_se (GstBitWriter * bs, gint32 value); + +G_END_DECLS + +#endif /* GST_VAAPI_UTILS_H26X_PRIV_H */ diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 7f9ff0275c..55bb5c76e8 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -32,6 +32,7 @@ gstlibvaapi_sources = [ 'gstvaapiutils_core.c', 'gstvaapiutils_h264.c', 'gstvaapiutils_h265.c', + 'gstvaapiutils_h26x.c', 'gstvaapiutils_mpeg2.c', 'gstvaapivalue.c', 'gstvaapivideopool.c', From 9ed6ac1f763589dd3f77fdccfe6b3487c3a836ba Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 17 Mar 2017 17:14:01 +0900 Subject: [PATCH 2712/3781] libs: h26x: adds gst_vaapi_utils_h26x_write_nal_unit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements gst_vaapi_utils_h26x_write_nal_unit(), which writes NAL unit length and data to a bitwriter. Note that this helper function applies EPB (Emulation Prevention Bytes), since otherwise produced codec_data might be broken when decoder/parser considering EPB, starts parsing. See sections 7.3 and 7.4 of the H264 and H264 specifications, which describes the emulation_prevention_three_byte. https://bugzilla.gnome.org/show_bug.cgi?id=778750 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 18 +++- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 24 ++++-- gst-libs/gst/vaapi/gstvaapiutils_h26x.c | 89 ++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h | 6 ++ 4 files changed, 127 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 801a721f7c..bd5e791216 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2532,13 +2532,15 @@ gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder, /* Write SPS */ WRITE_UINT32 (&bs, 1, 5); /* SPS count = 1 */ g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - WRITE_UINT32 (&bs, sps_info.size, 16); - gst_bit_writer_put_bytes (&bs, sps_info.data, sps_info.size); + /* Write Nal unit length and data of SPS */ + if (!gst_vaapi_utils_h26x_write_nal_unit (&bs, sps_info.data, sps_info.size)) + goto nal_to_byte_stream_error; /* Write PPS */ WRITE_UINT32 (&bs, 1, 8); /* PPS count = 1 */ - WRITE_UINT32 (&bs, pps_info.size, 16); - gst_bit_writer_put_bytes (&bs, pps_info.data, pps_info.size); + /* Write Nal unit length and data of PPS */ + if (!gst_vaapi_utils_h26x_write_nal_unit (&bs, pps_info.data, pps_info.size)) + goto nal_to_byte_stream_error; gst_buffer_unmap (encoder->pps_data, &pps_info); gst_buffer_unmap (encoder->sps_data, &sps_info); @@ -2561,6 +2563,14 @@ bs_error: gst_bit_writer_clear (&bs, TRUE); return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } +nal_to_byte_stream_error: + { + GST_ERROR ("failed to write nal unit"); + gst_buffer_unmap (encoder->sps_data, &sps_info); + gst_buffer_unmap (encoder->pps_data, &pps_info); + gst_bit_writer_clear (&bs, TRUE); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } error_map_sps_buffer: { GST_ERROR ("failed to map SPS packed header"); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index e156fdbb49..8d30287ec0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2116,8 +2116,9 @@ gst_vaapi_encoder_h265_get_codec_data (GstVaapiEncoder * base_encoder, WRITE_UINT32 (&bs, GST_H265_NAL_VPS, 6); /* Nal_unit_type */ WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, VPS count = 1 */ g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - WRITE_UINT32 (&bs, vps_info.size, 16); /* VPS nalUnitLength */ - gst_bit_writer_put_bytes (&bs, vps_info.data, vps_info.size); + /* Write Nal unit length and data of VPS */ + if (!gst_vaapi_utils_h26x_write_nal_unit (&bs, vps_info.data, vps_info.size)) + goto nal_to_byte_stream_error; /* Write SPS */ WRITE_UINT32 (&bs, 0x00, 1); /* array_completeness */ @@ -2125,16 +2126,18 @@ gst_vaapi_encoder_h265_get_codec_data (GstVaapiEncoder * base_encoder, WRITE_UINT32 (&bs, GST_H265_NAL_SPS, 6); /* Nal_unit_type */ WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, SPS count = 1 */ g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - WRITE_UINT32 (&bs, sps_info.size, 16); /* SPS nalUnitLength */ - gst_bit_writer_put_bytes (&bs, sps_info.data, sps_info.size); + /* Write Nal unit length and data of SPS */ + if (!gst_vaapi_utils_h26x_write_nal_unit (&bs, sps_info.data, sps_info.size)) + goto nal_to_byte_stream_error; /* Write PPS */ WRITE_UINT32 (&bs, 0x00, 1); /* array_completeness */ WRITE_UINT32 (&bs, 0x00, 1); /* reserved zero */ WRITE_UINT32 (&bs, GST_H265_NAL_PPS, 6); /* Nal_unit_type */ WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, PPS count = 1 */ - WRITE_UINT32 (&bs, pps_info.size, 16); /* PPS nalUnitLength */ - gst_bit_writer_put_bytes (&bs, pps_info.data, pps_info.size); + /* Write Nal unit length and data of PPS */ + if (!gst_vaapi_utils_h26x_write_nal_unit (&bs, pps_info.data, pps_info.size)) + goto nal_to_byte_stream_error; gst_buffer_unmap (encoder->pps_data, &pps_info); gst_buffer_unmap (encoder->sps_data, &sps_info); @@ -2159,6 +2162,15 @@ bs_error: gst_bit_writer_clear (&bs, TRUE); return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } +nal_to_byte_stream_error: + { + GST_ERROR ("failed to write nal unit"); + gst_buffer_unmap (encoder->vps_data, &vps_info); + gst_buffer_unmap (encoder->sps_data, &sps_info); + gst_buffer_unmap (encoder->pps_data, &pps_info); + gst_bit_writer_clear (&bs, TRUE); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } error_map_vps_buffer: { GST_ERROR ("failed to map VPS packed header"); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h26x.c b/gst-libs/gst/vaapi/gstvaapiutils_h26x.c index 717be39339..4a679aaa74 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h26x.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h26x.c @@ -3,6 +3,9 @@ * * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne + * Copyright (C) 2017 Intel Corporation + * Author: Hyunjun Ko + * Author: Mark Thompson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -56,3 +59,89 @@ bs_write_se (GstBitWriter * bs, gint32 value) return FALSE; return TRUE; } + +/* Copy from src to dst, applying emulation prevention bytes. + * + * This is copied from libavcodec written by Mark Thompson + * from + * http://git.videolan.org/?p=ffmpeg.git;a=commit;h=2c62fcdf5d617791a653d7957d449f75569eede0 + */ +static gboolean +gst_vaapi_utils_h26x_nal_unit_to_byte_stream (guint8 * dst, guint * dst_len, + guint8 * src, guint src_len) +{ + guint dp = 0, sp; + guint zero_run = 0; + + for (sp = 0; sp < src_len; sp++) { + if (dp >= *dst_len) + goto fail; + if (zero_run < 2) { + if (src[sp] == 0) + ++zero_run; + else + zero_run = 0; + } else { + if ((src[sp] & ~3) == 0) { + /* emulation_prevention_byte: 0x03 */ + dst[dp++] = 3; + if (dp >= *dst_len) + goto fail; + } + zero_run = src[sp] == 0; + } + dst[dp++] = src[sp]; + } + + *dst_len = dp; + return TRUE; + +fail: + *dst_len = 0; + return FALSE; +} + +/** + * gst_vaapi_utils_h26x_write_nal_unit: + * @bs: a #GstBitWriter instance + * @nal: the NAL (Network Abstraction Layer) unit to write + * @nal_size: the size, in bytes, of @nal + * + * Writes in the @bs the @nal rewritten with the "emulation prevention + * bytes" if required. + * + * Returns: TRUE if the NAL unit could be coded applying the + * "emulation prevention bytes"; otherwise FALSE. + **/ +gboolean +gst_vaapi_utils_h26x_write_nal_unit (GstBitWriter * bs, guint8 * nal, + guint nal_size) +{ + guint8 *byte_stream = NULL; + guint byte_stream_len; + + byte_stream_len = nal_size + 10; + byte_stream = g_malloc (byte_stream_len); + + if (!byte_stream) + return FALSE; + + if (!gst_vaapi_utils_h26x_nal_unit_to_byte_stream (byte_stream, + &byte_stream_len, nal, nal_size)) { + g_free (byte_stream); + return FALSE; + } + + WRITE_UINT32 (bs, byte_stream_len, 16); + gst_bit_writer_put_bytes (bs, byte_stream, byte_stream_len); + g_free (byte_stream); + + return TRUE; + +bs_error: + { + GST_ERROR ("failed to write codec-data"); + g_free (byte_stream); + return FALSE; + } +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h index a1ede90520..4122904d21 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h @@ -3,6 +3,8 @@ * * Copyright (C) 2011-2014 Intel Corporation * Author: Gwenole Beauchesne + * Copyright (C) 2017 Intel Corporation + * Author: Hyunjun Ko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -77,6 +79,10 @@ bs_write_ue (GstBitWriter * bs, guint32 value); gboolean bs_write_se (GstBitWriter * bs, gint32 value); +/* Write nal unit, applying emulation prevention bytes */ +gboolean +gst_vaapi_utils_h26x_write_nal_unit (GstBitWriter * bs, guint8 * nal, guint nal_size); + G_END_DECLS #endif /* GST_VAAPI_UTILS_H26X_PRIV_H */ From 152217064f1192bb836620ad7eaadbc031624f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 20 Mar 2017 16:45:01 +0100 Subject: [PATCH 2713/3781] plugins: when debug disabled, default category is NULL As in gstreamer-vaapi a common base class is used, the specific default category is passed to the base-plugin initializator, thus the log messages are categorized with the used plugin. Nonetheless, when the gst-debug is disabled in compilation time, it is needed to pass NULL to the base-plugin initializator. This patch does that. https://bugzilla.gnome.org/show_bug.cgi?id=780302 --- gst/vaapi/gstvaapidecode.c | 4 ++++ gst/vaapi/gstvaapiencode.c | 4 ++++ gst/vaapi/gstvaapipostproc.c | 4 ++++ gst/vaapi/gstvaapisink.c | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 407e25b36a..c2bb42af71 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -49,7 +49,11 @@ #define GST_VAAPI_DECODE_FLOW_PARSE_DATA GST_FLOW_CUSTOM_SUCCESS_2 GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapidecode); +#ifndef GST_DISABLE_GST_DEBUG #define GST_CAT_DEFAULT gst_debug_vaapidecode +#else +#define GST_CAT_DEFAULT NULL +#endif #define GST_VAAPI_DECODE_PARAMS_QDATA \ g_quark_from_static_string("vaapidec-params") diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index dd609014d1..b0f0a324b1 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -38,7 +38,11 @@ #define GST_VAAPI_ENCODE_FLOW_CONVERT_ERROR GST_FLOW_CUSTOM_ERROR_1 GST_DEBUG_CATEGORY_STATIC (gst_vaapiencode_debug); +#ifndef GST_DISABLE_GST_DEBUG #define GST_CAT_DEFAULT gst_vaapiencode_debug +#else +#define GST_CAT_DEFAULT NULL +#endif G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstVaapiEncode, gst_vaapiencode, GST_TYPE_VIDEO_ENCODER, diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index f4ddbb5116..d45f7ee9d7 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -49,7 +49,11 @@ #define GST_PLUGIN_DESC "A VA-API video postprocessing filter" GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapipostproc); +#ifndef GST_DISABLE_GST_DEBUG #define GST_CAT_DEFAULT gst_debug_vaapipostproc +#else +#define GST_CAT_DEFAULT NULL +#endif /* Default templates */ /* *INDENT-OFF* */ diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index cca71d9f3a..9cc5154cda 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -59,7 +59,11 @@ #define GST_PLUGIN_DESC "A VA-API based videosink" GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapisink); +#ifndef GST_DISABLE_GST_DEBUG #define GST_CAT_DEFAULT gst_debug_vaapisink +#else +#define GST_CAT_DEFAULT NULL +#endif /* Default template */ /* *INDENT-OFF* */ From 7f8b3254509b005b6c2351b53dda56fd5ad31e68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 21 Mar 2017 16:13:56 +0100 Subject: [PATCH 2714/3781] libs: encoder: h265: remove unused macro definition Since the h265 encoder doesn't use GValueArray, there is no need to disable the Glib deprecation warnings, thus removing the macro definition. --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 8d30287ec0..0b6047c5d4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -20,11 +20,6 @@ * Boston, MA 02110-1301 USA */ -/* GValueArray has deprecated without providing an alternative in glib >= 2.32 - * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 - */ -#define GLIB_DISABLE_DEPRECATION_WARNINGS - #include "sysdeps.h" #include #include From dbbe340906008c5088d2c048c589e84bde829b62 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 28 Mar 2017 10:53:20 -0700 Subject: [PATCH 2715/3781] encoder: h264: Fix B frame encoding artifacts The current implementation is updating the POC values only in Slice parameter Buffer.But we are not filling the picture order count and reference flags in VAPictureH264 while populating VA Picture/Slice structures.The latest intel-vaapi-driver is directly accessing the above fields from VAPicutreH264 provided as RefPicLists, which resulted some wrong maths and prediction errors in driver. https://bugzilla.gnome.org/show_bug.cgi?id=780620 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index bd5e791216..21d5d19843 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1894,6 +1894,10 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, pic_param->ReferenceFrames[i].picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); + pic_param->ReferenceFrames[i].TopFieldOrderCnt = ref_pic->poc; + pic_param->ReferenceFrames[i].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + pic_param->ReferenceFrames[i].frame_idx = ref_pic->frame_num; ++i; } g_assert (i <= 16 && i <= ref_pool->max_ref_frames); @@ -2002,6 +2006,11 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, for (; i_ref < reflist_0_count; ++i_ref) { slice_param->RefPicList0[i_ref].picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); + slice_param->RefPicList0[i_ref].TopFieldOrderCnt = + reflist_0[i_ref]->poc; + slice_param->RefPicList0[i_ref].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + slice_param->RefPicList0[i_ref].frame_idx = reflist_0[i_ref]->frame_num; } g_assert (i_ref == 1); } @@ -2014,6 +2023,11 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, for (; i_ref < reflist_1_count; ++i_ref) { slice_param->RefPicList1[i_ref].picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); + slice_param->RefPicList1[i_ref].TopFieldOrderCnt = + reflist_1[i_ref]->poc; + slice_param->RefPicList1[i_ref].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + slice_param->RefPicList1[i_ref].flags |= reflist_1[i_ref]->frame_num; } g_assert (i_ref == 1); } From 834557d5b614f920f8fd5fa20fb4f86c001e9a35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Mar 2017 13:22:47 +0200 Subject: [PATCH 2716/3781] libs: encoder: h265: fix code style Trivial patch to remove a double ';' as end of instruction. --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 0b6047c5d4..7170bcff39 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -924,7 +924,7 @@ ensure_profile_limits (GstVaapiEncoderH265 * encoder) ("Needs to lower coding tools to meet target decoder constraints"); GST_WARNING ("Only supporting Main profile, reset profile to Main"); - encoder->profile = GST_VAAPI_PROFILE_H265_MAIN;; + encoder->profile = GST_VAAPI_PROFILE_H265_MAIN; encoder->profile_idc = gst_vaapi_utils_h265_get_profile_idc (encoder->profile); From be990f5ed44b1b47df33936f94d7e01a18e103aa Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 31 Mar 2017 14:12:43 -0700 Subject: [PATCH 2717/3781] encoder: h264: Fix Backward ReferencePicture flag setting This is a regression introduced by e829b62 which override the reference flags and caused issues with latest intel-vaapi-driver. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 21d5d19843..16e5b43861 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2027,7 +2027,8 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, reflist_1[i_ref]->poc; slice_param->RefPicList1[i_ref].flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE; - slice_param->RefPicList1[i_ref].flags |= reflist_1[i_ref]->frame_num; + slice_param->RefPicList1[i_ref].frame_idx |= + reflist_1[i_ref]->frame_num; } g_assert (i_ref == 1); } From 123672a9bd3d5807affaaf2cecd3e56acd521d53 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Wed, 5 Apr 2017 11:15:41 -0700 Subject: [PATCH 2718/3781] libs: encoder: vp9: Fix initialization of ref_list gcc 7.0.1 gives a memset-elt-size warning in gst_vaapi_encoder_vp9_init: 'memset' used with length equal to number of elements without multiplication by element size [-Werror=memset-elt-size] https://bugzilla.gnome.org/show_bug.cgi?id=780947 --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 7b53775828..b9af78551c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -440,7 +440,8 @@ gst_vaapi_encoder_vp9_init (GstVaapiEncoder * base_encoder) encoder->sharpness_level = DEFAULT_SHARPNESS_LEVEL; encoder->yac_qi = DEFAULT_YAC_QINDEX; - memset (encoder->ref_list, 0, G_N_ELEMENTS (encoder->ref_list)); + memset (encoder->ref_list, 0, + G_N_ELEMENTS (encoder->ref_list) * sizeof (encoder->ref_list[0])); encoder->ref_list_idx = 0; return TRUE; From 914a4712d9fc34966b22256f993899d5b581a3a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 31 Mar 2017 11:21:21 +0200 Subject: [PATCH 2719/3781] vaapiencode: enhance logs of negotiated caps https://bugzilla.gnome.org/show_bug.cgi?id=771291 --- gst/vaapi/gstvaapiencode.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index b0f0a324b1..cc460a4c83 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -373,6 +373,9 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) out_caps = gst_caps_make_writable (out_caps); gst_caps_append (out_caps, gst_caps_copy (raw_caps)); gst_caps_replace (&encode->allowed_sinkpad_caps, out_caps); + GST_INFO_OBJECT (encode, "Allowed sink caps %" GST_PTR_FORMAT, + encode->allowed_sinkpad_caps); + ret = TRUE; bail: @@ -411,7 +414,7 @@ gst_vaapiencode_get_caps (GstVideoEncoder * venc, GstCaps * filter) result = gst_video_encoder_proxy_getcaps (venc, encode->allowed_sinkpad_caps, filter); - GST_DEBUG_OBJECT (venc, "Returning sink caps %" GST_PTR_FORMAT, result); + GST_DEBUG_OBJECT (venc, "Negotiated sink caps %" GST_PTR_FORMAT, result); return result; } From db7268117d804a54f8be60c1046b9969ac112950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 4 Apr 2017 14:21:43 +0200 Subject: [PATCH 2720/3781] libs: encoder: initialize chroma_type Instead of initialize the chroma_type with a undefined value, which will be converted to GST_VAAPI_CHROMA_TYPE_YUV420 by GstVaapiContext, this patch queries the VA config, given the received GstVaapiContextInfo's parameters, and gets the first response. In order to get the GstVaapiChromaType value, also it was needed to add a new utility function: to_GstVaapiChromaType(), which, given a VA_RT_FORMAT_* will return the associated GstVaapiChromaType. https://bugzilla.gnome.org/show_bug.cgi?id=771291 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 16 +++++++++ gst-libs/gst/vaapi/gstvaapiutils.c | 50 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 4 +++ 3 files changed, 70 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 2989ff805b..a1ec79136c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -588,6 +588,21 @@ unsupported: } } +static guint +get_default_chroma_type (GstVaapiEncoder * encoder, + const GstVaapiContextInfo * cip) +{ + guint value; + + if (!gst_vaapi_get_config_attribute (encoder->display, + gst_vaapi_profile_get_va_profile (cip->profile), + gst_vaapi_entrypoint_get_va_entrypoint (cip->entrypoint), + VAConfigAttribRTFormat, &value)) + return 0; + + return to_GstVaapiChromaType (value); +} + static void init_context_info (GstVaapiEncoder * encoder) { @@ -603,6 +618,7 @@ init_context_info (GstVaapiEncoder * encoder) if (cip->entrypoint != GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; } + cip->chroma_type = get_default_chroma_type (encoder, cip); cip->width = 0; cip->height = 0; cip->ref_frames = encoder->num_ref_frames; diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index d583ab454a..0ed1efe101 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -315,6 +315,56 @@ string_of_VARateControl (guint rate_control) return ""; } +/** + * to_GstVaapiChromaType: + * @va_rt_format: the value of VAConfigAttribRTFormat + * + * Converts the VA_RT_FORMAT_* to #GstVaapiChromaType + * + * Returns: the #GstVaapiChromaType associated to @va_rt_format or + * zero. + **/ +guint +to_GstVaapiChromaType (guint va_rt_format) +{ + guint chroma_type; + + switch (va_rt_format) { + case VA_RT_FORMAT_YUV420: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + break; + case VA_RT_FORMAT_YUV422: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; + break; + case VA_RT_FORMAT_YUV444: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; + break; +#if VA_CHECK_VERSION(0,34,0) + case VA_RT_FORMAT_YUV411: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV411; + break; + case VA_RT_FORMAT_YUV400: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400; + break; + case VA_RT_FORMAT_RGB32: + chroma_type = GST_VAAPI_CHROMA_TYPE_RGB32; + break; + case VA_RT_FORMAT_RGB16: + chroma_type = GST_VAAPI_CHROMA_TYPE_RGB16; + break; +#endif +#if VA_CHECK_VERSION(0,38,1) + case VA_RT_FORMAT_YUV420_10BPP: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; + break; +#endif + default: + chroma_type = 0; + break; + } + return chroma_type; +} + /** * from_GstVaapiChromaType: * @chroma_type: the #GstVaapiChromaType diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index b4ee99e619..41b5762b82 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -85,6 +85,10 @@ G_GNUC_INTERNAL const gchar * string_of_VARateControl (guint rate_control); +G_GNUC_INTERNAL +guint +to_GstVaapiChromaType (guint va_rt_format); + G_GNUC_INTERNAL guint from_GstVaapiChromaType (guint chroma_type); From 31d326c9ee12e6c8da7b765c9968ac52ac29239f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 4 Apr 2017 14:39:59 +0200 Subject: [PATCH 2721/3781] libs: encoder: refactor init_context_info() In order to generate vaapi contexts iterative, the function init_context_info() is refactored to pass, as parameters the GstVaapiContextInfo and the GstVaapiProfile. https://bugzilla.gnome.org/show_bug.cgi?id=771291 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index a1ec79136c..f4836e3990 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -604,14 +604,14 @@ get_default_chroma_type (GstVaapiEncoder * encoder, } static void -init_context_info (GstVaapiEncoder * encoder) +init_context_info (GstVaapiEncoder * encoder, GstVaapiContextInfo * cip, + GstVaapiProfile profile) { - GstVaapiContextInfo *const cip = &encoder->context_info; const GstVaapiEncoderClassData *const cdata = GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; - cip->profile = get_profile (encoder); + cip->profile = profile; if (cdata->codec == GST_VAAPI_CODEC_JPEG) { cip->entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; } else { @@ -633,7 +633,7 @@ set_context_info (GstVaapiEncoder * encoder) const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); - init_context_info (encoder); + init_context_info (encoder, cip, get_profile (encoder)); cip->chroma_type = gst_vaapi_video_format_get_chroma_type (format); cip->width = GST_VAAPI_ENCODER_WIDTH (encoder); @@ -1168,7 +1168,7 @@ gst_vaapi_encoder_ensure_context_config (GstVaapiEncoder * encoder) if (encoder->context) return TRUE; - init_context_info (encoder); + init_context_info (encoder, cip, get_profile (encoder)); encoder->context = gst_vaapi_context_new (encoder->display, cip); return (encoder->context != NULL); } From 9aa63e4595105ac035663a22360d75c52b74b4b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Apr 2017 12:28:51 +0200 Subject: [PATCH 2722/3781] libs: encoder: dummy context for get_surface_formats() Instead of creating (if it doesn't exist, yet) the encoder's context the method gst_vaapi_encoder_get_surface_formats() now it creates dummy contexts, unless the encoder has it already created. The purpose of this is to avoid setting a encoder's context with a wrong profile. https://bugzilla.gnome.org/show_bug.cgi?id=771291 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index f4836e3990..3ecd2c453f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1160,17 +1160,18 @@ error: } } -static gboolean -gst_vaapi_encoder_ensure_context_config (GstVaapiEncoder * encoder) +static GstVaapiContext * +create_test_context_config (GstVaapiEncoder * encoder) { - GstVaapiContextInfo *const cip = &encoder->context_info; + GstVaapiContextInfo cip = { 0, }; + GstVaapiContext *ctxt; if (encoder->context) - return TRUE; + return gst_vaapi_object_ref (encoder->context); - init_context_info (encoder, cip, get_profile (encoder)); - encoder->context = gst_vaapi_context_new (encoder->display, cip); - return (encoder->context != NULL); + init_context_info (encoder, &cip, get_profile (encoder)); + ctxt = gst_vaapi_context_new (encoder->display, &cip); + return ctxt; } /** @@ -1184,9 +1185,15 @@ gst_vaapi_encoder_ensure_context_config (GstVaapiEncoder * encoder) GArray * gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder) { - if (!gst_vaapi_encoder_ensure_context_config (encoder)) + GstVaapiContext *ctxt; + GArray *formats; + + ctxt = create_test_context_config (encoder); + if (!ctxt) return NULL; - return gst_vaapi_context_get_surface_formats (encoder->context); + formats = gst_vaapi_context_get_surface_formats (ctxt); + gst_vaapi_object_unref (ctxt); + return formats; } /** Returns a GType for the #GstVaapiEncoderTune set */ From 7153b4597d24af67508b0f20c20f34c8a56b1675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Apr 2017 12:49:24 +0200 Subject: [PATCH 2723/3781] libs: encoder: pass profile to get_surface_formats() In order to get the supported surface formats within a specific profile this patch adds the GstVaapiProfile as property to gst_vaapi_encoder_get_surface_formats(). Currently the extracted formats are only those related with the default profile of the element's codec. https://bugzilla.gnome.org/show_bug.cgi?id=771291 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 13 +++++++++---- gst-libs/gst/vaapi/gstvaapiencoder.h | 3 ++- gst/vaapi/gstvaapiencode.c | 3 ++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 3ecd2c453f..cfbdfc84fb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1161,7 +1161,7 @@ error: } static GstVaapiContext * -create_test_context_config (GstVaapiEncoder * encoder) +create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile) { GstVaapiContextInfo cip = { 0, }; GstVaapiContext *ctxt; @@ -1169,7 +1169,11 @@ create_test_context_config (GstVaapiEncoder * encoder) if (encoder->context) return gst_vaapi_object_ref (encoder->context); - init_context_info (encoder, &cip, get_profile (encoder)); + /* if there is no profile, let's figure out one */ + if (profile == GST_VAAPI_PROFILE_UNKNOWN) + profile = get_profile (encoder); + + init_context_info (encoder, &cip, profile); ctxt = gst_vaapi_context_new (encoder->display, &cip); return ctxt; } @@ -1183,12 +1187,13 @@ create_test_context_config (GstVaapiEncoder * encoder) * Returns: a #GArray of valid formats for the current VAConfig **/ GArray * -gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder) +gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, + GstVaapiProfile profile) { GstVaapiContext *ctxt; GArray *formats; - ctxt = create_test_context_config (encoder); + ctxt = create_test_context_config (encoder, profile); if (!ctxt) return NULL; formats = gst_vaapi_context_get_surface_formats (ctxt); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 3160036d69..1c7cd4737b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -174,7 +174,8 @@ GstVaapiEncoderStatus gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); GArray * -gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder); +gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, + GstVaapiProfile profile); G_END_DECLS #endif /* GST_VAAPI_ENCODER_H */ diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index cc460a4c83..ff7154de07 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -362,7 +362,8 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) if (!out_caps) goto failed_create_va_caps; - formats = gst_vaapi_encoder_get_surface_formats (encode->encoder); + formats = gst_vaapi_encoder_get_surface_formats (encode->encoder, + GST_VAAPI_PROFILE_UNKNOWN); if (!formats) goto failed_get_formats; From 5ccadd6e9cc76c30060878949eb4c4e2edfef45f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Apr 2017 16:28:12 +0200 Subject: [PATCH 2724/3781] vaapiencode: add get_profile() vmethod This new virtual method, get_profile(), if implemented by specific encoders, will return the VA profile potentially determined by the source caps. Also it is implemented by h264 and h265 encoders, which are the main users of this vmethod. https://bugzilla.gnome.org/show_bug.cgi?id=771291 --- gst/vaapi/gstvaapiencode.c | 15 +++++++++++++-- gst/vaapi/gstvaapiencode.h | 1 + gst/vaapi/gstvaapiencode_h264.c | 20 ++++++++++++++++++++ gst/vaapi/gstvaapiencode_h265.c | 20 ++++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index ff7154de07..12d634de3a 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -349,9 +349,11 @@ gst_vaapiencode_buffer_loop (GstVaapiEncode * encode) static gboolean ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) { + GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode); GstCaps *out_caps, *raw_caps = NULL; GArray *formats = NULL; gboolean ret = FALSE; + GstVaapiProfile profile = GST_VAAPI_PROFILE_UNKNOWN; if (encode->allowed_sinkpad_caps) return TRUE; @@ -362,8 +364,17 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) if (!out_caps) goto failed_create_va_caps; - formats = gst_vaapi_encoder_get_surface_formats (encode->encoder, - GST_VAAPI_PROFILE_UNKNOWN); + if (klass->get_profile) { + GstCaps *allowed = + gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); + if (allowed) { + if (!gst_caps_is_empty (allowed) && !gst_caps_is_any (allowed)) + profile = klass->get_profile (allowed); + gst_caps_unref (allowed); + } + } + + formats = gst_vaapi_encoder_get_surface_formats (encode->encoder, profile); if (!formats) goto failed_get_formats; diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 77a8a40bb6..72121f79eb 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -80,6 +80,7 @@ struct _GstVaapiEncodeClass GstFlowReturn (*alloc_buffer) (GstVaapiEncode * encode, GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr); + GstVaapiProfile (*get_profile) (GstCaps * caps); }; GType diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 35306ebda3..074274524b 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -129,6 +129,25 @@ gst_vaapiencode_h264_get_property (GObject * object, } } +static GstVaapiProfile +gst_vaapiencode_h264_get_profile (GstCaps * caps) +{ + guint i; + + for (i = 0; i < gst_caps_get_size (caps); i++) { + GstStructure *const structure = gst_caps_get_structure (caps, i); + const GValue *const value = gst_structure_get_value (structure, "profile"); + + if (value && G_VALUE_HOLDS_STRING (value)) { + const gchar *str = g_value_get_string (value); + if (str) + return gst_vaapi_utils_h264_get_profile_from_string (str); + } + } + + return GST_VAAPI_PROFILE_UNKNOWN; +} + typedef struct { GstVaapiProfile best_profile; @@ -397,6 +416,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) object_class->get_property = gst_vaapiencode_h264_get_property; encode_class->get_properties = gst_vaapi_encoder_h264_get_default_properties; + encode_class->get_profile = gst_vaapiencode_h264_get_profile; encode_class->set_config = gst_vaapiencode_h264_set_config; encode_class->get_caps = gst_vaapiencode_h264_get_caps; encode_class->alloc_encoder = gst_vaapiencode_h264_alloc_encoder; diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 3915b2f11a..c8490fb133 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -128,6 +128,25 @@ gst_vaapiencode_h265_get_property (GObject * object, } } +static GstVaapiProfile +gst_vaapiencode_h265_get_profile (GstCaps * caps) +{ + guint i; + + for (i = 0; i < gst_caps_get_size (caps); i++) { + GstStructure *const structure = gst_caps_get_structure (caps, i); + const GValue *const value = gst_structure_get_value (structure, "profile"); + + if (value && G_VALUE_HOLDS_STRING (value)) { + const gchar *str = g_value_get_string (value); + if (str) + return gst_vaapi_utils_h265_get_profile_from_string (str); + } + } + + return GST_VAAPI_PROFILE_UNKNOWN; +} + typedef struct { GstVaapiProfile best_profile; @@ -396,6 +415,7 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass) object_class->get_property = gst_vaapiencode_h265_get_property; encode_class->get_properties = gst_vaapi_encoder_h265_get_default_properties; + encode_class->get_profile = gst_vaapiencode_h265_get_profile; encode_class->set_config = gst_vaapiencode_h265_set_config; encode_class->get_caps = gst_vaapiencode_h265_get_caps; encode_class->alloc_encoder = gst_vaapiencode_h265_alloc_encoder; From e534ff56097d0ec7ccba1c3cb760163933cc98e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Apr 2017 17:21:21 +0200 Subject: [PATCH 2725/3781] libs: encode: merge all possible surface formats When the function gst_vaapi_encoder_get_surface_formats() was added it was under the assumption that any VA profile of the specific codec supported the same format colors. But it is not, for example the profiles that support 10bit formats. In other words, different VA profiles of a same codec may support different color formats in their upload surfaces. In order to expose all the possible color formats, if no profile is specified via source caps, or if the encoder doesn't have yet a context, all the possible VA profiles for the specific codec are iterated and their color formats are merged. https://bugzilla.gnome.org/show_bug.cgi?id=771291 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 76 +++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index cfbdfc84fb..327e2155f0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1178,6 +1178,50 @@ create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile) return ctxt; } +static GArray * +get_profile_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile) +{ + GstVaapiContext *ctxt; + GArray *formats; + + ctxt = create_test_context_config (encoder, profile); + if (!ctxt) + return NULL; + formats = gst_vaapi_context_get_surface_formats (ctxt); + gst_vaapi_object_unref (ctxt); + return formats; +} + +static gboolean +merge_profile_surface_formats (GstVaapiEncoder * encoder, + GstVaapiProfile profile, GArray * formats) +{ + GArray *surface_fmts; + guint i, j; + GstVideoFormat fmt, sfmt; + + if (profile == GST_VAAPI_PROFILE_UNKNOWN) + return FALSE; + + surface_fmts = get_profile_surface_formats (encoder, profile); + if (!surface_fmts) + return FALSE; + + for (i = 0; i < surface_fmts->len; i++) { + sfmt = g_array_index (surface_fmts, GstVideoFormat, i); + for (j = 0; j < formats->len; j++) { + fmt = g_array_index (formats, GstVideoFormat, j); + if (fmt == sfmt) + break; + } + if (j >= formats->len) + g_array_append_val (formats, sfmt); + } + + g_array_unref (surface_fmts); + return TRUE; +} + /** * gst_vaapi_encoder_get_surface_formats: * @encoder: a #GstVaapiEncoder instances @@ -1190,14 +1234,34 @@ GArray * gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile) { - GstVaapiContext *ctxt; - GArray *formats; + const GstVaapiEncoderClassData *const cdata = + GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; + GArray *profiles, *formats; + guint i; - ctxt = create_test_context_config (encoder, profile); - if (!ctxt) + if (profile || encoder->context) + return get_profile_surface_formats (encoder, profile); + + /* no specific context neither specific profile, let's iterate among + * the codec's profiles */ + profiles = gst_vaapi_display_get_encode_profiles (encoder->display); + if (!profiles) return NULL; - formats = gst_vaapi_context_get_surface_formats (ctxt); - gst_vaapi_object_unref (ctxt); + + formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat)); + for (i = 0; i < profiles->len; i++) { + profile = g_array_index (profiles, GstVaapiProfile, i); + if (gst_vaapi_profile_get_codec (profile) == cdata->codec) { + if (!merge_profile_surface_formats (encoder, profile, formats)) { + g_array_unref (formats); + formats = NULL; + break; + } + } + } + + g_array_unref (profiles); + return formats; } From 48e21d6ba88496d0ffb9fa578778c949393225f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Mar 2017 19:16:50 +0200 Subject: [PATCH 2726/3781] libs: encoder: h265: ensures profile given format Set the VA profile as GST_VAAPI_PROFILE_H265_MAIN10 if the configured color format is P010_10LE. Otherwise, keep GST_VAAPI_PROFILE_H265_MAIN https://bugzilla.gnome.org/show_bug.cgi?id=771291 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 7170bcff39..8993e14d03 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -936,11 +936,16 @@ static gboolean ensure_profile (GstVaapiEncoderH265 * encoder) { GstVaapiProfile profile; + const GstVideoFormat format = + GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); /* Always start from "Main" profile for maximum compatibility */ profile = GST_VAAPI_PROFILE_H265_MAIN; + if (format == GST_VIDEO_FORMAT_P010_10LE) + profile = GST_VAAPI_PROFILE_H265_MAIN10; + encoder->profile = profile; encoder->profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile); return TRUE; From d744aeb5fa41d35f82a4fdbe5b4397335be40f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Mar 2017 19:20:26 +0200 Subject: [PATCH 2727/3781] libs: encoder: admit YUV420_10BPP as valid chroma Accepts as supported the GST_VAAPI_CHROMA_TYPE_YUV420_10BPP chroma type. https://bugzilla.gnome.org/show_bug.cgi?id=771291 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 327e2155f0..0a87c1b32f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -568,7 +568,8 @@ is_chroma_type_supported (GstVaapiEncoder * encoder) return TRUE; if (cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420 && - cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV422) + cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV422 && + cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420_10BPP) goto unsupported; if (!get_config_attribute (encoder, VAConfigAttribRTFormat, &format)) From 3532dca16aacef23e5ea20611b4331621c566332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 3 Apr 2017 15:34:51 +0200 Subject: [PATCH 2728/3781] libs: encoder: h265: chroma and luma with format If the profile is main-10 the bit_depth_luma_minus8, in the sequence parameter buffer, shall be the color format bit depth minus 8, 10-8 which is 2. Also for bit_depth_chroma_minus8. This patch gets the negotiated sink caps format and queries its luma's depth and uses that value to fill the mentioned parameters. https://bugzilla.gnome.org/show_bug.cgi?id=771291 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 8993e14d03..f49121ce2b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1436,6 +1436,13 @@ static gboolean fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) { VAEncSequenceParameterBufferHEVC *const seq_param = sequence->param; + const GstVideoFormat format = + GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); + guint bits_depth_luma_minus8 = + GST_VIDEO_FORMAT_INFO_DEPTH (gst_video_format_get_info (format), 0); + if (bits_depth_luma_minus8 < 8) + return FALSE; + bits_depth_luma_minus8 -= 8; memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferHEVC)); @@ -1457,8 +1464,8 @@ fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) seq_param->seq_fields.value = 0; seq_param->seq_fields.bits.chroma_format_idc = 1; seq_param->seq_fields.bits.separate_colour_plane_flag = 0; - seq_param->seq_fields.bits.bit_depth_luma_minus8 = 0; - seq_param->seq_fields.bits.bit_depth_chroma_minus8 = 0; + seq_param->seq_fields.bits.bit_depth_luma_minus8 = bits_depth_luma_minus8; + seq_param->seq_fields.bits.bit_depth_chroma_minus8 = bits_depth_luma_minus8; seq_param->seq_fields.bits.scaling_list_enabled_flag = FALSE; seq_param->seq_fields.bits.strong_intra_smoothing_enabled_flag = TRUE; seq_param->seq_fields.bits.amp_enabled_flag = TRUE; From b2815a376bb4ca424642e8129b35fe6673f77f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 3 Apr 2017 14:52:41 +0200 Subject: [PATCH 2729/3781] vaapiencode: h265: add main-10 in caps template This patch adds h265's main-10 profile in encoder src caps template. https://bugzilla.gnome.org/show_bug.cgi?id=771291 --- gst/vaapi/gstvaapiencode_h265.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index c8490fb133..8c8d2e214f 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -64,7 +64,7 @@ static const char gst_vaapiencode_h265_sink_caps_str[] = /* *INDENT-OFF* */ static const char gst_vaapiencode_h265_src_caps_str[] = GST_CODEC_CAPS ", " - "profile = (string) { main }"; + "profile = (string) { main, main-10 }"; /* *INDENT-ON* */ /* *INDENT-OFF* */ From d2213994f37ad5e63a5ccb607b843513054ba177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 7 Apr 2017 16:36:21 +0300 Subject: [PATCH 2730/3781] Release 1.11.90 --- ChangeLog | 360 ++++++++++++++++++++++++++++++++++++++++++- NEWS | 2 +- configure.ac | 14 +- gstreamer-vaapi.doap | 10 ++ meson.build | 2 +- 5 files changed, 376 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index c38d6c4dbc..571bc83cb6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,363 @@ -=== release 1.11.2 === +=== release 1.11.90 === -2017-02-24 Sebastian Dröge +2017-04-07 Sebastian Dröge * configure.ac: - releasing 1.11.2 + releasing 1.11.90 + +2017-04-03 14:52:41 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h265.c: + vaapiencode: h265: add main-10 in caps template + This patch adds h265's main-10 profile in encoder src caps template. + https://bugzilla.gnome.org/show_bug.cgi?id=771291 + +2017-04-03 15:34:51 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: chroma and luma with format + If the profile is main-10 the bit_depth_luma_minus8, in the sequence + parameter buffer, shall be the color format bit depth minus 8, 10-8 + which is 2. Also for bit_depth_chroma_minus8. + This patch gets the negotiated sink caps format and queries its + luma's depth and uses that value to fill the mentioned parameters. + https://bugzilla.gnome.org/show_bug.cgi?id=771291 + +2017-03-29 19:20:26 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: admit YUV420_10BPP as valid chroma + Accepts as supported the GST_VAAPI_CHROMA_TYPE_YUV420_10BPP chroma + type. + https://bugzilla.gnome.org/show_bug.cgi?id=771291 + +2017-03-29 19:16:50 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: ensures profile given format + Set the VA profile as GST_VAAPI_PROFILE_H265_MAIN10 if the + configured color format is P010_10LE. + Otherwise, keep GST_VAAPI_PROFILE_H265_MAIN + https://bugzilla.gnome.org/show_bug.cgi?id=771291 + +2017-04-06 17:21:21 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encode: merge all possible surface formats + When the function gst_vaapi_encoder_get_surface_formats() was added + it was under the assumption that any VA profile of the specific codec + supported the same format colors. But it is not, for example the + profiles that support 10bit formats. + In other words, different VA profiles of a same codec may support + different color formats in their upload surfaces. + In order to expose all the possible color formats, if no profile is + specified via source caps, or if the encoder doesn't have yet a + context, all the possible VA profiles for the specific codec are + iterated and their color formats are merged. + https://bugzilla.gnome.org/show_bug.cgi?id=771291 + +2017-04-06 16:28:12 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + vaapiencode: add get_profile() vmethod + This new virtual method, get_profile(), if implemented by specific + encoders, will return the VA profile potentially determined by the + source caps. + Also it is implemented by h264 and h265 encoders, which are the main + users of this vmethod. + https://bugzilla.gnome.org/show_bug.cgi?id=771291 + +2017-04-06 12:49:24 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst/vaapi/gstvaapiencode.c: + libs: encoder: pass profile to get_surface_formats() + In order to get the supported surface formats within a specific + profile this patch adds the GstVaapiProfile as property to + gst_vaapi_encoder_get_surface_formats(). + Currently the extracted formats are only those related with the + default profile of the element's codec. + https://bugzilla.gnome.org/show_bug.cgi?id=771291 + +2017-04-06 12:28:51 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: dummy context for get_surface_formats() + Instead of creating (if it doesn't exist, yet) the encoder's context + the method gst_vaapi_encoder_get_surface_formats() now it creates + dummy contexts, unless the encoder has it already created. + The purpose of this is to avoid setting a encoder's context with a + wrong profile. + https://bugzilla.gnome.org/show_bug.cgi?id=771291 + +2017-04-04 14:39:59 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: refactor init_context_info() + In order to generate vaapi contexts iterative, the function + init_context_info() is refactored to pass, as parameters the + GstVaapiContextInfo and the GstVaapiProfile. + https://bugzilla.gnome.org/show_bug.cgi?id=771291 + +2017-04-04 14:21:43 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + libs: encoder: initialize chroma_type + Instead of initialize the chroma_type with a undefined value, which + will be converted to GST_VAAPI_CHROMA_TYPE_YUV420 by GstVaapiContext, + this patch queries the VA config, given the received + GstVaapiContextInfo's parameters, and gets the first response. + In order to get the GstVaapiChromaType value, also it was needed to + add a new utility function: to_GstVaapiChromaType(), which, given a + VA_RT_FORMAT_* will return the associated GstVaapiChromaType. + https://bugzilla.gnome.org/show_bug.cgi?id=771291 + +2017-03-31 11:21:21 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: enhance logs of negotiated caps + https://bugzilla.gnome.org/show_bug.cgi?id=771291 + +2017-04-05 11:15:41 -0700 Scott D Phillips + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: vp9: Fix initialization of ref_list + gcc 7.0.1 gives a memset-elt-size warning in gst_vaapi_encoder_vp9_init: + 'memset' used with length equal to number of elements without + multiplication by element size [-Werror=memset-elt-size] + https://bugzilla.gnome.org/show_bug.cgi?id=780947 + +2017-03-31 14:12:43 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: Fix Backward ReferencePicture flag setting + This is a regression introduced by e829b62 which + override the reference flags and caused issues with + latest intel-vaapi-driver. + +2017-03-29 13:22:47 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: fix code style + Trivial patch to remove a double ';' as end of instruction. + +2017-03-28 10:53:20 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + encoder: h264: Fix B frame encoding artifacts + The current implementation is updating the POC values only + in Slice parameter Buffer.But we are not filling the + picture order count and reference flags in VAPictureH264 + while populating VA Picture/Slice structures.The latest + intel-vaapi-driver is directly accessing the above fields + from VAPicutreH264 provided as RefPicLists, which resulted + some wrong maths and prediction errors in driver. + https://bugzilla.gnome.org/show_bug.cgi?id=780620 + +2017-03-21 16:13:56 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: remove unused macro definition + Since the h265 encoder doesn't use GValueArray, there is no need to + disable the Glib deprecation warnings, thus removing the macro + definition. + +2017-03-20 16:45:01 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + plugins: when debug disabled, default category is NULL + As in gstreamer-vaapi a common base class is used, the specific + default category is passed to the base-plugin initializator, thus + the log messages are categorized with the used plugin. + Nonetheless, when the gst-debug is disabled in compilation time, + it is needed to pass NULL to the base-plugin initializator. This + patch does that. + https://bugzilla.gnome.org/show_bug.cgi?id=780302 + +2017-03-17 17:14:01 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h26x.c: + * gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h: + libs: h26x: adds gst_vaapi_utils_h26x_write_nal_unit() + Implements gst_vaapi_utils_h26x_write_nal_unit(), which writes NAL + unit length and data to a bitwriter. + Note that this helper function applies EPB (Emulation Prevention + Bytes), since otherwise produced codec_data might be broken when + decoder/parser considering EPB, starts parsing. + See sections 7.3 and 7.4 of the H264 and H264 specifications, which + describes the emulation_prevention_three_byte. + https://bugzilla.gnome.org/show_bug.cgi?id=778750 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-03-17 16:49:41 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h26x.c: + * gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h: + * gst-libs/gst/vaapi/meson.build: + libs: utils: h26x: create vaapiutils_h26x + Since there is duplicated code in h264/265 encoder, we could + refactor it to avoid duplicated code. + https://bugzilla.gnome.org/show_bug.cgi?id=778750 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-03-17 16:32:36 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h264/5: fix wrong return value + https://bugzilla.gnome.org/show_bug.cgi?id=778750 + +2017-03-13 17:29:59 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + docs: h264/h265: put parser to the example pipeline + https://bugzilla.gnome.org/show_bug.cgi?id=778749 + +2017-03-13 16:20:59 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: fix reserved length of bits + Fix reserved length of bits for bit_depth_luma_minus8 and bit_depth_chroma_minus8 + https://bugzilla.gnome.org/show_bug.cgi?id=778749 + +2017-03-12 18:59:42 +0100 Thomas Petazzoni + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * tests/test-display.c: + O_CLOEXEC needs _GNU_SOURCE defined + From man open(2): + The O_CLOEXEC, O_DIRECTORY, and O_NOFOLLOW flags are not specified + in POSIX.1-2001, but are specified in POSIX.1-2008. Since glibc + 2.12, one can obtain their definitions by defining either + _POSIX_C_SOURCE with a value greater than or equal to 200809L or + _XOPEN_SOURCE with a value greater than or equal to 700. In glibc + 2.11 and earlier, one obtains the definitions by defining + _GNU_SOURCE. + And indeed, with the uClibc C library, O_CLOEXEC is not exposed if + _GNU_SOURCE is not defined. Therefore, this commit fixes the build of + gstreamer-vaapi with the uClibc C library. + Signed-off-by: Thomas Petazzoni + https://bugzilla.gnome.org/show_bug.cgi?id=779953 + +2017-03-14 16:07:08 +0100 Víctor Manuel Jáquez Leal + + * README: + README: fix "Sources" section + Update the URL where the release source tarballs can be downloaded. + +2017-03-12 21:39:53 +0100 Thomas Petazzoni + + * README: + README: fix "Reporting bugs" section + The "Reporting bugs" section gives + https://bugzilla.gnome.org/enter_bug.cgi?product=gstreamer-vaapi as the + link to report a bug, but this link says "Sorry, entering a bug into the + product gstreamer-vaapi has been disabled.". + This commit fixes the URL to point to the proper location, and also + removes the following paragraph that is no longer correct. + Signed-off-by: Thomas Petazzoni + https://bugzilla.gnome.org/show_bug.cgi?id=779954 + +2017-03-03 19:55:00 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: retry to create the VA display + Particularly in GNOME Wayland, the negotiated or created GL context + defines a GLX environment, but VAAPI fails to create a GLX VA + display because there is no a DRI2 connection. + This patch retries to create the VA display if VA cannot create one + with the GL context parameters. Now using the old list of display + types. + This should also work in the case of systems with two GPU, when the + non-VAAPI has the graphics environment, and the VAAPI-enabled one + shall work headless. + https://bugzilla.gnome.org/show_bug.cgi?id=772838 + +2016-10-19 15:33:41 +0100 Julien Isorce + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: texture upload if driver supports GL + Removes GstVideoGLTextureUploadMeta caps feature if the driver + doesn't support opengl. + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=772838 + +2016-10-25 17:48:47 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: texture upload if driver supports GL + When the allowed source pad caps are generated, the GLTextureUpload caps are + only inserted if the driver support OpenGL. + https://bugzilla.gnome.org/show_bug.cgi?id=772838 + +2017-02-22 15:02:01 -0800 Sreerenj Balachandran + + * configure.ac: + configure: Add missing compiler flags + The AC_CHECK_HEADERS macro was failing to locate some headers, in + particular the va_enc_* headers due to missing compiler flags. + https://bugzilla.gnome.org/show_bug.cgi?id=779101 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-03-01 14:48:46 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: window: wayland: handle more VAStatus to use vpp + Since the commit landed https://github.com/01org/intel-vaapi-driver/pull/55, + we should consider more returned VAStatus to use vpp. + https://bugzilla.gnome.org/show_bug.cgi?id=779400 + +2017-02-23 15:16:06 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: ensure profile when context initialization + We can't be sure that encoder's profile is assgined already or not + at context initialization. + https://bugzilla.gnome.org/show_bug.cgi?id=779120 + +2017-02-23 15:13:59 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: set rate control info only when query succeed + Currently, it set rate control information even when query fails. + In addition, it doesn't update any more since the flag + got_rate_control_mask is set to TRUE. + https://bugzilla.gnome.org/show_bug.cgi?id=779120 + +2017-02-24 16:00:23 +0200 Sebastian Dröge + + * meson.build: + meson: Update version + +2017-02-24 15:38:22 +0200 Sebastian Dröge + + * configure.ac: + Back to development + +=== release 1.11.2 === + +2017-02-24 15:10:21 +0200 Sebastian Dröge + + * ChangeLog: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + Release 1.11.2 2017-02-16 18:37:59 +0100 Víctor Manuel Jáquez Leal diff --git a/NEWS b/NEWS index ba794a2734..8e8dc3f622 100644 --- a/NEWS +++ b/NEWS @@ -1 +1 @@ -This is GStreamer 1.11.2. +This is GStreamer 1.11.90. diff --git a/configure.ac b/configure.ac index 10c5835779..7f2edd0a8b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [11]) -m4_define([gst_vaapi_micro_version], [2]) -m4_define([gst_vaapi_nano_version], [1]) +m4_define([gst_vaapi_micro_version], [90]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1102]) +m4_define([gst_vaapi_lt_current], [1190]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1102]) +m4_define([gst_vaapi_lt_age], [1190]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.11.2.1]) -m4_define([gst_plugins_base_version], [1.11.2.1]) -m4_define([gst_plugins_bad_version], [1.11.2.1]) +m4_define([gst_version], [1.11.90]) +m4_define([gst_plugins_base_version], [1.11.90]) +m4_define([gst_plugins_bad_version], [1.11.90]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 7b9167c8dd..ab9267f4fa 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.11.90 + master + + 2017-04-07 + + + + 1.11.2 diff --git a/meson.build b/meson.build index 1c1cbb2aff..0bbd5911e0 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.11.2.1', + version : '1.11.90', meson_version : '>= 0.36.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From d68edb04a17ba9dd6964ec84ba7997dd4b84c6e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 10 Apr 2017 23:51:06 +0100 Subject: [PATCH 2731/3781] Automatic update of common submodule From 39ac2f5 to 60aeef6 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 39ac2f563e..60aeef6837 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 39ac2f563e12d22100e320c95aaab8d8e5812ca9 +Subproject commit 60aeef6837610c672cebf247ec748538faab7bf1 From 0343649667d58dfb24d002e9cc924fd356a1dd9f Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Wed, 5 Apr 2017 11:19:15 -0700 Subject: [PATCH 2732/3781] plugins: Fix usage of GST_GL_HAVE_WINDOW_* defines When these definitions are false, they are undef in the preprocessor, not a defined value of 0. When they are unset the compile fails with: 'GST_GL_HAVE_WINDOW_WAYLAND' undeclared (first use in this function) https://bugzilla.gnome.org/show_bug.cgi?id=780948 --- gst/vaapi/gstvaapipluginutil.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 9a12472baa..78a46239a6 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -177,12 +177,12 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; #endif } else { -#if USE_X11 - if (!display_type && GST_GL_HAVE_WINDOW_X11) +#if USE_X11 && GST_GL_HAVE_WINDOW_X11 + if (!display_type) display_type = GST_VAAPI_DISPLAY_TYPE_X11; #endif -#if USE_WAYLAND - if (!display_type && GST_GL_HAVE_WINDOW_WAYLAND) +#if USE_WAYLAND && GST_GL_HAVE_WINDOW_WAYLAND + if (!display_type) display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; #endif } From 4752f68a376afc59c27d9e3e94483d3387372098 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Mon, 3 Apr 2017 16:45:36 +0900 Subject: [PATCH 2733/3781] libs: window: x11/wayland: chaining up to GstVaapiWindow Currently, GstVaapiWindowX11/Wayland are not descendants of GstVaapiWindow. This patch chains them up to GstVaapiWindow to handle common members in GstVaapiWindow. https://bugzilla.gnome.org/show_bug.cgi?id=759533 --- gst-libs/gst/vaapi/gstvaapiwindow.c | 17 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 3 +++ gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 13 +++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 6 ++++++ gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 1 + 5 files changed, 40 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 2bb02e1f32..62cdeaf0ce 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -74,6 +74,23 @@ gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height) return TRUE; } +static void +gst_vaapi_window_finalize (GstVaapiWindow * window) +{ +} + +void +gst_vaapi_window_class_init (GstVaapiWindowClass * klass) +{ + GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); + + object_class->finalize = (GstVaapiObjectFinalizeFunc) + gst_vaapi_window_finalize; +} + +GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindow, + gst_vaapi_window, gst_vaapi_window_class_init (&g_class)); + GstVaapiWindow * gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, GstVaapiDisplay * display, GstVaapiID id, guint width, guint height) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index ea0e19a175..71b67559f2 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -120,6 +120,9 @@ GstVaapiWindow * gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, GstVaapiDisplay * display, GstVaapiID handle, guint width, guint height); +void +gst_vaapi_window_class_init (GstVaapiWindowClass * klass); + /* Inline reference counting for core libgstvaapi library */ #ifdef IN_LIBGSTVAAPI_CORE #define gst_vaapi_window_ref_internal(window) \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index b299d762d5..9a2e664aef 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -46,6 +46,12 @@ #define GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(obj) \ (&GST_VAAPI_WINDOW_WAYLAND_CAST(obj)->priv) +#define GST_VAAPI_WINDOW_WAYLAND_CLASS(klass) \ + ((GstVaapiWindowWaylandClass *)(klass)) + +#define GST_VAAPI_WINDOW_WAYLAND_GET_CLASS(obj) \ + GST_VAAPI_WINDOW_WAYLAND_CLASS (GST_VAAPI_WINDOW_GET_CLASS (obj)) + typedef struct _GstVaapiWindowWaylandPrivate GstVaapiWindowWaylandPrivate; typedef struct _GstVaapiWindowWaylandClass GstVaapiWindowWaylandClass; typedef struct _FrameState FrameState; @@ -135,6 +141,7 @@ struct _GstVaapiWindowWaylandClass { /*< private > */ GstVaapiWindowClass parent_class; + GstVaapiObjectFinalizeFunc parent_finalize; }; static gboolean @@ -339,6 +346,9 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) gst_vaapi_video_pool_replace (&priv->surface_pool, NULL); gst_poll_free (priv->poll); + + GST_VAAPI_WINDOW_WAYLAND_GET_CLASS (window)->parent_finalize (GST_VAAPI_OBJECT + (window)); } static gboolean @@ -593,6 +603,9 @@ gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass) GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); + gst_vaapi_window_class_init (&klass->parent_class); + + klass->parent_finalize = object_class->finalize; object_class->finalize = (GstVaapiObjectFinalizeFunc) gst_vaapi_window_wayland_destroy; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 10ff1d42fa..c34ecdee7c 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -297,6 +297,9 @@ gst_vaapi_window_x11_destroy (GstVaapiWindow * window) } GST_VAAPI_OBJECT_ID (window) = None; } + + GST_VAAPI_WINDOW_X11_GET_CLASS (window)->parent_finalize (GST_VAAPI_OBJECT + (window)); } static gboolean @@ -536,6 +539,9 @@ gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass) GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); + gst_vaapi_window_class_init (&klass->parent_class); + + klass->parent_finalize = object_class->finalize; object_class->finalize = (GstVaapiObjectFinalizeFunc) gst_vaapi_window_x11_destroy; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index f57916c996..3abbc8129e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -79,6 +79,7 @@ struct _GstVaapiWindowX11Class { /*< private >*/ GstVaapiWindowClass parent_class; + GstVaapiObjectFinalizeFunc parent_finalize; }; void From ccfbca733dd3511bcbfda349b81587c6b2793fa4 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Mon, 10 Apr 2017 11:41:29 +0900 Subject: [PATCH 2734/3781] libs: window: add gst_vaapi_window_vpp_convert_internal() If a backend doesn't support specific format, we can use vpp for conversion and make it playing. This api is originated from GstVaapiWindowWayland and moved to GstVaapiWindow, so that GstVaapiWindowX11 could use it. https://bugzilla.gnome.org/show_bug.cgi?id=759533 --- gst-libs/gst/vaapi/gstvaapiwindow.c | 104 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 13 +++ 2 files changed, 117 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 62cdeaf0ce..f63a4b98ba 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -57,6 +57,60 @@ gst_vaapi_window_ensure_size (GstVaapiWindow * window) window->height == window->display_height); } +static gboolean +ensure_filter (GstVaapiWindow * window) +{ + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); + + /* Ensure VPP pipeline is built */ + if (window->filter) + return TRUE; + + window->filter = gst_vaapi_filter_new (display); + if (!window->filter) + goto error_create_filter; + if (!gst_vaapi_filter_set_format (window->filter, window->surface_format)) + goto error_unsupported_format; + + return TRUE; + +error_create_filter: + { + GST_WARNING ("failed to create VPP filter. Disabling"); + window->has_vpp = FALSE; + return FALSE; + } +error_unsupported_format: + { + GST_ERROR ("unsupported render target format %s", + gst_vaapi_video_format_to_string (window->surface_format)); + window->has_vpp = FALSE; + return FALSE; + } +} + +static gboolean +ensure_filter_surface_pool (GstVaapiWindow * window) +{ + GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); + + if (window->surface_pool) + goto ensure_filter; + + /* Ensure VA surface pool is created */ + /* XXX: optimize the surface format to use. e.g. YUY2 */ + window->surface_pool = gst_vaapi_surface_pool_new (display, + window->surface_format, window->width, window->height); + if (!window->surface_pool) { + GST_WARNING ("failed to create surface pool for conversion"); + return FALSE; + } + gst_vaapi_filter_replace (&window->filter, NULL); + +ensure_filter: + return ensure_filter (window); +} + static gboolean gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height) { @@ -77,6 +131,8 @@ gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height) static void gst_vaapi_window_finalize (GstVaapiWindow * window) { + gst_vaapi_video_pool_replace (&window->surface_pool, NULL); + gst_vaapi_filter_replace (&window->filter, NULL); } void @@ -112,6 +168,10 @@ gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, window->use_foreign_window = id != GST_VAAPI_ID_INVALID; GST_VAAPI_OBJECT_ID (window) = window->use_foreign_window ? id : 0; + window->surface_format = GST_VIDEO_FORMAT_ENCODED; + window->has_vpp = + GST_VAAPI_DISPLAY_HAS_VPP (GST_VAAPI_OBJECT_DISPLAY (window)); + if (!gst_vaapi_window_create (window, width, height)) goto error; return window; @@ -124,6 +184,48 @@ error: } } +GstVaapiSurface * +gst_vaapi_window_vpp_convert_internal (GstVaapiWindow * window, + GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags) +{ + GstVaapiSurface *vpp_surface = NULL; + GstVaapiFilterStatus status; + + if (!window->has_vpp) + return NULL; + + if (!ensure_filter_surface_pool (window)) + return NULL; + + if (src_rect) + if (!gst_vaapi_filter_set_cropping_rectangle (window->filter, src_rect)) + return NULL; + if (dst_rect) + if (!gst_vaapi_filter_set_target_rectangle (window->filter, dst_rect)) + return NULL; + + /* Post-process the decoded source surface */ + vpp_surface = gst_vaapi_video_pool_get_object (window->surface_pool); + if (!vpp_surface) + return NULL; + + status = + gst_vaapi_filter_process (window->filter, surface, vpp_surface, flags); + if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) + goto error_process_filter; + return vpp_surface; + + /* ERRORS */ +error_process_filter: + { + GST_ERROR ("failed to process surface %" GST_VAAPI_ID_FORMAT " (error %d)", + GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (surface)), status); + gst_vaapi_video_pool_put_object (window->surface_pool, vpp_surface); + return NULL; + } +} + /** * gst_vaapi_window_new: * @display: a #GstVaapiDisplay @@ -389,6 +491,8 @@ gst_vaapi_window_set_size (GstVaapiWindow * window, guint width, guint height) if (!GST_VAAPI_WINDOW_GET_CLASS (window)->resize (window, width, height)) return; + gst_vaapi_video_pool_replace (&window->surface_pool, NULL); + window->width = width; window->height = height; } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index 71b67559f2..c2c106337e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -26,6 +26,8 @@ #define GST_VAAPI_WINDOW_PRIV_H #include "gstvaapiobject_priv.h" +#include "gstvaapifilter.h" +#include "gstvaapisurfacepool.h" G_BEGIN_DECLS @@ -75,6 +77,12 @@ struct _GstVaapiWindow guint use_foreign_window:1; guint is_fullscreen:1; guint check_geometry:1; + + /* for conversion */ + GstVideoFormat surface_format; + GstVaapiVideoPool *surface_pool; + GstVaapiFilter *filter; + gboolean has_vpp; }; /** @@ -120,6 +128,11 @@ GstVaapiWindow * gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, GstVaapiDisplay * display, GstVaapiID handle, guint width, guint height); +GstVaapiSurface * +gst_vaapi_window_vpp_convert_internal (GstVaapiWindow * window, + GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags); + void gst_vaapi_window_class_init (GstVaapiWindowClass * klass); From c5b3577e8827277e75bc1a3bdb6eb66f388e2480 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Mon, 10 Apr 2017 17:23:26 +0900 Subject: [PATCH 2735/3781] libs: window: x11/wayland: use new api for conversion Since gst_vaapi_window_vpp_convert_internal is created, GstVaapiWindowX11/Wayland can use it for conversion. Note that once it chooses to use vpp, it's going to use vpp until the session is finished. https://bugzilla.gnome.org/show_bug.cgi?id=759533 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 105 +++---------------- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 72 +++++++++++-- gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 1 + 3 files changed, 77 insertions(+), 101 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 9a2e664aef..df644aab0d 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -107,16 +107,13 @@ struct _GstVaapiWindowWaylandPrivate struct wl_region *opaque_region; struct wl_event_queue *event_queue; FrameState *last_frame; - GstVideoFormat surface_format; - GstVaapiVideoPool *surface_pool; - GstVaapiFilter *filter; GstPoll *poll; GstPollFD pollfd; guint is_shown:1; guint fullscreen_on_show:1; - guint use_vpp:1; guint sync_failed:1; volatile guint num_frames_pending; + gboolean need_vpp; }; /** @@ -306,8 +303,6 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window, if (priv->fullscreen_on_show) gst_vaapi_window_wayland_set_fullscreen (window, TRUE); - priv->surface_format = GST_VIDEO_FORMAT_ENCODED; - priv->use_vpp = GST_VAAPI_DISPLAY_HAS_VPP (GST_VAAPI_OBJECT_DISPLAY (window)); priv->is_shown = TRUE; return TRUE; @@ -342,9 +337,6 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) priv->event_queue = NULL; } - gst_vaapi_filter_replace (&priv->filter, NULL); - gst_vaapi_video_pool_replace (&priv->surface_pool, NULL); - gst_poll_free (priv->poll); GST_VAAPI_WINDOW_WAYLAND_GET_CLASS (window)->parent_finalize (GST_VAAPI_OBJECT @@ -362,7 +354,6 @@ gst_vaapi_window_wayland_resize (GstVaapiWindow * window, GST_DEBUG ("resize window, new size %ux%u", width, height); - gst_vaapi_video_pool_replace (&priv->surface_pool, NULL); if (priv->opaque_region) wl_region_destroy (priv->opaque_region); GST_VAAPI_OBJECT_LOCK_DISPLAY (window); @@ -399,74 +390,6 @@ static const struct wl_buffer_listener frame_buffer_listener = { frame_release_callback }; -static GstVaapiSurface * -vpp_convert (GstVaapiWindow * window, - GstVaapiSurface * surface, - const GstVaapiRectangle * src_rect, - const GstVaapiRectangle * dst_rect, guint flags) -{ - GstVaapiWindowWaylandPrivate *const priv = - GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); - GstVaapiSurface *vpp_surface = NULL; - GstVaapiFilterStatus status; - - /* Ensure VA surface pool is created */ - /* XXX: optimize the surface format to use. e.g. YUY2 */ - if (!priv->surface_pool) { - priv->surface_pool = gst_vaapi_surface_pool_new (display, - priv->surface_format, window->width, window->height); - if (!priv->surface_pool) - return NULL; - gst_vaapi_filter_replace (&priv->filter, NULL); - } - - /* Ensure VPP pipeline is built */ - if (!priv->filter) { - priv->filter = gst_vaapi_filter_new (display); - if (!priv->filter) - goto error_create_filter; - if (!gst_vaapi_filter_set_format (priv->filter, priv->surface_format)) - goto error_unsupported_format; - } - if (!gst_vaapi_filter_set_cropping_rectangle (priv->filter, src_rect)) - return NULL; - if (!gst_vaapi_filter_set_target_rectangle (priv->filter, dst_rect)) - return NULL; - - /* Post-process the decoded source surface */ - vpp_surface = gst_vaapi_video_pool_get_object (priv->surface_pool); - if (!vpp_surface) - return NULL; - - status = gst_vaapi_filter_process (priv->filter, surface, vpp_surface, flags); - if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) - goto error_process_filter; - return vpp_surface; - - /* ERRORS */ -error_create_filter: - { - GST_WARNING ("failed to create VPP filter. Disabling"); - priv->use_vpp = FALSE; - return NULL; - } -error_unsupported_format: - { - GST_ERROR ("unsupported render target format %s", - gst_vaapi_video_format_to_string (priv->surface_format)); - priv->use_vpp = FALSE; - return NULL; - } -error_process_filter: - { - GST_ERROR ("failed to process surface %" GST_VAAPI_ID_FORMAT " (error %d)", - GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (surface)), status); - gst_vaapi_video_pool_put_object (priv->surface_pool, vpp_surface); - return NULL; - } -} - static gboolean gst_vaapi_window_wayland_render (GstVaapiWindow * window, GstVaapiSurface * surface, @@ -482,23 +405,22 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, FrameState *frame; guint width, height, va_flags; VAStatus status; - gboolean need_vpp = FALSE; /* Check that we don't need to crop source VA surface */ gst_vaapi_surface_get_size (surface, &width, &height); if (src_rect->x != 0 || src_rect->y != 0) - need_vpp = TRUE; + priv->need_vpp = TRUE; if (src_rect->width != width || src_rect->height != height) - need_vpp = TRUE; + priv->need_vpp = TRUE; /* Check that we don't render to a subregion of this window */ if (dst_rect->x != 0 || dst_rect->y != 0) - need_vpp = TRUE; + priv->need_vpp = TRUE; if (dst_rect->width != window->width || dst_rect->height != window->height) - need_vpp = TRUE; + priv->need_vpp = TRUE; /* Try to construct a Wayland buffer from VA surface as is (without VPP) */ - if (!need_vpp) { + if (!priv->need_vpp) { GST_VAAPI_OBJECT_LOCK_DISPLAY (window); va_flags = from_GstVaapiSurfaceRenderFlags (flags); status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), @@ -508,18 +430,19 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED || status == VA_STATUS_ERROR_UNIMPLEMENTED || status == VA_STATUS_ERROR_INVALID_IMAGE_FORMAT) - need_vpp = TRUE; + priv->need_vpp = TRUE; else if (!vaapi_check_status (status, "vaGetSurfaceBufferWl()")) return FALSE; } /* Try to construct a Wayland buffer with VPP */ - if (need_vpp) { - if (priv->use_vpp) { + if (priv->need_vpp) { + if (window->has_vpp) { GstVaapiSurface *const vpp_surface = - vpp_convert (window, surface, src_rect, dst_rect, flags); + gst_vaapi_window_vpp_convert_internal (window, surface, src_rect, + dst_rect, flags); if (G_UNLIKELY (!vpp_surface)) - need_vpp = FALSE; + priv->need_vpp = FALSE; else { surface = vpp_surface; width = window->width; @@ -547,9 +470,9 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, g_atomic_pointer_set (&priv->last_frame, frame); g_atomic_int_inc (&priv->num_frames_pending); - if (need_vpp && priv->use_vpp) { + if (priv->need_vpp && window->has_vpp) { frame->surface = surface; - frame->surface_pool = gst_vaapi_video_pool_ref (priv->surface_pool); + frame->surface_pool = gst_vaapi_video_pool_ref (window->surface_pool); } /* XXX: attach to the specified target rectangle */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index c34ecdee7c..909672ba6e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -399,19 +399,14 @@ gst_vaapi_window_x11_resize (GstVaapiWindow * window, guint width, guint height) return !has_errors; } -static gboolean -gst_vaapi_window_x11_render (GstVaapiWindow * window, - GstVaapiSurface * surface, +static VAStatus +gst_vaapi_window_x11_put_surface (GstVaapiWindow * window, + VASurfaceID surface_id, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect, guint flags) { - VASurfaceID surface_id; VAStatus status; - surface_id = GST_VAAPI_OBJECT_ID (surface); - if (surface_id == VA_INVALID_ID) - return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (window), surface_id, @@ -425,11 +420,68 @@ gst_vaapi_window_x11_render (GstVaapiWindow * window, dst_rect->width, dst_rect->height, NULL, 0, from_GstVaapiSurfaceRenderFlags (flags) ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); - if (!vaapi_check_status (status, "vaPutSurface()")) + + return status; +} + +static gboolean +gst_vaapi_window_x11_render (GstVaapiWindow * window, + GstVaapiSurface * surface, + const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect, guint flags) +{ + VASurfaceID surface_id; + VAStatus status; + GstVaapiWindowX11Private *const priv = + GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); + gboolean ret = FALSE; + + surface_id = GST_VAAPI_OBJECT_ID (surface); + if (surface_id == VA_INVALID_ID) return FALSE; - return TRUE; + if (window->has_vpp && priv->need_vpp) + goto conversion; + + status = + gst_vaapi_window_x11_put_surface (window, surface_id, src_rect, dst_rect, + flags); + + if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED || + status == VA_STATUS_ERROR_UNIMPLEMENTED || + status == VA_STATUS_ERROR_INVALID_IMAGE_FORMAT) { + priv->need_vpp = TRUE; + } else { + ret = vaapi_check_status (status, "vaPutSurface()"); + } + +conversion: + if (priv->need_vpp && window->has_vpp) { + GstVaapiSurface *const vpp_surface = + gst_vaapi_window_vpp_convert_internal (window, surface, NULL, NULL, + flags); + if (G_LIKELY (vpp_surface)) { + surface_id = GST_VAAPI_OBJECT_ID (vpp_surface); + status = + gst_vaapi_window_x11_put_surface (window, surface_id, src_rect, + dst_rect, flags); + + ret = vaapi_check_status (status, "vaPutSurface()"); + + if (!gst_vaapi_surface_sync (vpp_surface)) { + GST_WARNING ("failed to render surface"); + ret = FALSE; + } + + gst_vaapi_video_pool_put_object (window->surface_pool, vpp_surface); + } else { + priv->need_vpp = FALSE; + } + } + + return ret; } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index 3abbc8129e..bde150cd52 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -55,6 +55,7 @@ struct _GstVaapiWindowX11Private guint is_mapped:1; guint fullscreen_on_map:1; guint has_xrender:1; + gboolean need_vpp; }; /** From 8e8280efbf01e997564831c14cd1bc30a50d313f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 11 Apr 2017 18:22:00 +0200 Subject: [PATCH 2736/3781] libs: window: remove surface_format member Since we always convert to NV12, there is no need to keep a variable for that. Let us hard code it. https://bugzilla.gnome.org/show_bug.cgi?id=759533 --- gst-libs/gst/vaapi/gstvaapiwindow.c | 7 +++---- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index f63a4b98ba..001802cfb4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -69,7 +69,7 @@ ensure_filter (GstVaapiWindow * window) window->filter = gst_vaapi_filter_new (display); if (!window->filter) goto error_create_filter; - if (!gst_vaapi_filter_set_format (window->filter, window->surface_format)) + if (!gst_vaapi_filter_set_format (window->filter, GST_VIDEO_FORMAT_NV12)) goto error_unsupported_format; return TRUE; @@ -83,7 +83,7 @@ error_create_filter: error_unsupported_format: { GST_ERROR ("unsupported render target format %s", - gst_vaapi_video_format_to_string (window->surface_format)); + gst_vaapi_video_format_to_string (GST_VIDEO_FORMAT_NV12)); window->has_vpp = FALSE; return FALSE; } @@ -100,7 +100,7 @@ ensure_filter_surface_pool (GstVaapiWindow * window) /* Ensure VA surface pool is created */ /* XXX: optimize the surface format to use. e.g. YUY2 */ window->surface_pool = gst_vaapi_surface_pool_new (display, - window->surface_format, window->width, window->height); + GST_VIDEO_FORMAT_NV12, window->width, window->height); if (!window->surface_pool) { GST_WARNING ("failed to create surface pool for conversion"); return FALSE; @@ -168,7 +168,6 @@ gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, window->use_foreign_window = id != GST_VAAPI_ID_INVALID; GST_VAAPI_OBJECT_ID (window) = window->use_foreign_window ? id : 0; - window->surface_format = GST_VIDEO_FORMAT_ENCODED; window->has_vpp = GST_VAAPI_DISPLAY_HAS_VPP (GST_VAAPI_OBJECT_DISPLAY (window)); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index c2c106337e..cd0df1a467 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -78,8 +78,7 @@ struct _GstVaapiWindow guint is_fullscreen:1; guint check_geometry:1; - /* for conversion */ - GstVideoFormat surface_format; + /* for conversion */ GstVaapiVideoPool *surface_pool; GstVaapiFilter *filter; gboolean has_vpp; From bd2e304ea44ef9e6a09ad771fedcb200c22d8a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 11 Apr 2017 18:50:35 +0200 Subject: [PATCH 2737/3781] libs: window: don't add an unused function The macro GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE only defines a function that is never used, thus when compiling we might see this warning (clang): gstvaapiwindow.c:147:1: warning: unused function 'gst_vaapi_window_class' [-Wunused-function] GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindow, ^ https://bugzilla.gnome.org/show_bug.cgi?id=759533 --- gst-libs/gst/vaapi/gstvaapiwindow.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 001802cfb4..f3d6ab02fb 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -144,9 +144,6 @@ gst_vaapi_window_class_init (GstVaapiWindowClass * klass) gst_vaapi_window_finalize; } -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindow, - gst_vaapi_window, gst_vaapi_window_class_init (&g_class)); - GstVaapiWindow * gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, GstVaapiDisplay * display, GstVaapiID id, guint width, guint height) From a7a9b33ad9a8aa4366f33b2284638142ac5a9298 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Wed, 5 Apr 2017 17:24:20 +1000 Subject: [PATCH 2738/3781] Implement decoder reset on flush, rather than recreating Clear decoders out on a flush but keep the same instance, rather than completely recreating them. That avoids unecessarily freeing and recreating surface pools and contexts, which can be quite expensive https://bugzilla.gnome.org/show_bug.cgi?id=781142 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 88 +++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapidecoder.h | 3 + gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 3 +- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 5 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 2 + gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 1 + gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 15 +++- gst/vaapi/gstvaapidecode.c | 23 +++--- 8 files changed, 112 insertions(+), 28 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 6af1372fdd..ce9c065b01 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -40,6 +40,26 @@ static void drop_frame (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame); +static void +parser_state_reset (GstVaapiParserState * ps) +{ + + if (ps->input_adapter) + gst_adapter_clear (ps->input_adapter); + if (ps->output_adapter) + gst_adapter_clear (ps->output_adapter); + ps->current_adapter = NULL; + + if (ps->next_unit_pending) { + gst_vaapi_decoder_unit_clear (&ps->next_unit); + ps->next_unit_pending = FALSE; + } + + ps->current_frame_number = 0; + ps->input_offset1 = ps->input_offset2 = 0; + ps->at_eos = FALSE; +} + static void parser_state_finalize (GstVaapiParserState * ps) { @@ -266,16 +286,6 @@ do_decode (GstVaapiDecoder * decoder, GstVideoCodecFrame * base_frame) return status; } -static inline GstVaapiDecoderStatus -do_flush (GstVaapiDecoder * decoder) -{ - GstVaapiDecoderClass *const klass = GST_VAAPI_DECODER_GET_CLASS (decoder); - - if (klass->flush) - return klass->flush (decoder); - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - static GstVaapiDecoderStatus decode_step (GstVaapiDecoder * decoder) { @@ -1029,13 +1039,69 @@ gst_vaapi_decoder_decode (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame) return do_decode (decoder, frame); } +/* This function really marks the end of input, + * so that the decoder will drain out any pending + * frames on calls to gst_vaapi_decoder_get_frame_with_timeout() */ GstVaapiDecoderStatus gst_vaapi_decoder_flush (GstVaapiDecoder * decoder) { + GstVaapiDecoderClass *klass; + g_return_val_if_fail (decoder != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - return do_flush (decoder); + klass = GST_VAAPI_DECODER_GET_CLASS (decoder); + + if (klass->flush) + return klass->flush (decoder); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +/* Reset the decoder instance to a clean state, + * clearing any pending decode state, without + * reallocating the entire decoder */ +GstVaapiDecoderStatus +gst_vaapi_decoder_reset (GstVaapiDecoder * decoder) +{ + GstVaapiDecoderClass *klass; + GstVaapiDecoderStatus ret = GST_VAAPI_DECODER_STATUS_SUCCESS; + + g_return_val_if_fail (decoder != NULL, + GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); + + klass = GST_VAAPI_DECODER_GET_CLASS (decoder); + + GST_DEBUG ("Resetting decoder"); + + if (klass->reset) { + ret = klass->reset (decoder); + } else { + if (klass->destroy) + klass->destroy (decoder); + if (klass->create) + if (!klass->create (decoder)) + ret = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (ret != GST_VAAPI_DECODER_STATUS_SUCCESS) + return ret; + + /* Clear any buffers and frame in the queues */ + { + GstVideoCodecFrame *frame; + GstBuffer *buffer; + + while ((frame = g_async_queue_try_pop (decoder->frames)) != NULL) + gst_video_codec_frame_unref (frame); + + while ((buffer = g_async_queue_try_pop (decoder->buffers)) != NULL) + gst_buffer_unref (buffer); + } + + parser_state_reset (&decoder->parser_state); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; } GstVaapiDecoderStatus diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index a8ca5aa9ec..8b442b9f41 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -132,6 +132,9 @@ gst_vaapi_decoder_decode (GstVaapiDecoder * decoder, GstVaapiDecoderStatus gst_vaapi_decoder_flush (GstVaapiDecoder * decoder); +GstVaapiDecoderStatus +gst_vaapi_decoder_reset (GstVaapiDecoder * decoder); + GstVaapiDecoderStatus gst_vaapi_decoder_check_status (GstVaapiDecoder * decoder); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index d4bd6dda18..f87ac308f3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1221,10 +1221,11 @@ gst_vaapi_decoder_h264_destroy (GstVaapiDecoder * base_decoder) guint i; gst_vaapi_decoder_h264_close (decoder); + priv->is_opened = FALSE; g_free (priv->dpb); priv->dpb = NULL; - priv->dpb_size = 0; + priv->dpb_size_max = priv->dpb_size = 0; g_free (priv->prev_ref_frames); priv->prev_ref_frames = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 2675f79af8..15be632bc5 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -957,6 +957,8 @@ gst_vaapi_decoder_h265_close (GstVaapiDecoderH265 * decoder) gst_h265_parser_free (priv->parser); priv->parser = NULL; } + + priv->is_opened = FALSE; } static gboolean @@ -982,7 +984,8 @@ gst_vaapi_decoder_h265_destroy (GstVaapiDecoder * base_decoder) gst_vaapi_decoder_h265_close (decoder); g_free (priv->dpb); priv->dpb = NULL; - priv->dpb_size = 0; + priv->dpb_count = priv->dpb_size_max = priv->dpb_size = 0; + for (i = 0; i < G_N_ELEMENTS (priv->pps); i++) gst_vaapi_parser_info_h265_replace (&priv->pps[i], NULL); gst_vaapi_parser_info_h265_replace (&priv->active_pps, NULL); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index cb05b6e7b8..8d45910277 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -317,6 +317,8 @@ gst_vaapi_decoder_mpeg2_close (GstVaapiDecoderMpeg2 * decoder) priv->state = 0; gst_vaapi_dpb_replace (&priv->dpb, NULL); + + priv->is_opened = FALSE; } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 3473315f56..c80db0f9fe 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -225,6 +225,7 @@ struct _GstVaapiDecoderClass 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); }; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 256f017c46..7fc0244b41 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -67,7 +67,6 @@ struct _GstVaapiDecoderVC1Private guint8 rndctrl; guint rbdu_buffer_size; guint is_opened:1; - guint is_first_field:1; guint has_codec_data:1; guint has_entrypoint:1; guint size_changed:1; @@ -134,6 +133,7 @@ gst_vaapi_decoder_vc1_close (GstVaapiDecoderVC1 * decoder) gst_vc1_bitplanes_free (priv->bitplanes); priv->bitplanes = NULL; } + priv->is_opened = FALSE; } static gboolean @@ -150,6 +150,11 @@ gst_vaapi_decoder_vc1_open (GstVaapiDecoderVC1 * decoder) priv->bitplanes = gst_vc1_bitplanes_new (); if (!priv->bitplanes) return FALSE; + + memset (&priv->seq_hdr, 0, sizeof (GstVC1SeqHdr)); + memset (&priv->entrypoint_hdr, 0, sizeof (GstVC1EntryPointHdr)); + memset (&priv->frame_hdr, 0, sizeof (GstVC1FrameHdr)); + return TRUE; } @@ -174,8 +179,13 @@ gst_vaapi_decoder_vc1_create (GstVaapiDecoder * base_decoder) GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder); GstVaapiDecoderVC1Private *const priv = &decoder->priv; + priv->has_codec_data = priv->has_entrypoint = + priv->size_changed = priv->profile_changed = + priv->closed_entry = priv->broken_link = FALSE; + priv->profile = (GstVaapiProfile) 0; priv->rndctrl = 0; + priv->width = priv->height = 0; return TRUE; } @@ -1357,6 +1367,9 @@ gst_vaapi_decoder_vc1_start_frame (GstVaapiDecoder * base_decoder, GST_ERROR ("failed to reset context"); return status; } + status = ensure_decoder (decoder); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; picture = GST_VAAPI_PICTURE_NEW (VC1, decoder); if (!picture) { diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index c2bb42af71..33adcef1c0 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -953,20 +953,21 @@ gst_vaapidecode_destroy (GstVaapiDecode * decode) } static gboolean -gst_vaapidecode_reset_full (GstVaapiDecode * decode, GstCaps * caps, - gboolean hard) +gst_vaapidecode_reset (GstVaapiDecode * decode, GstCaps * caps, + gboolean force_reset) { /* Reset tracked frame size */ decode->current_frame_size = 0; - if (!hard && decode->decoder) { + if (decode->decoder) { if (gst_vaapi_decoder_update_caps (decode->decoder, caps)) { g_atomic_int_set (&decode->do_renego, TRUE); - return TRUE; + if (!force_reset) + return TRUE; } + return gst_vaapi_decoder_reset (decode->decoder); } - gst_vaapidecode_destroy (decode); return gst_vaapidecode_create (decode, caps); } @@ -1047,8 +1048,6 @@ static gboolean gst_vaapidecode_flush (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - gboolean reverse; - if (!decode->decoder) return FALSE; @@ -1056,13 +1055,9 @@ gst_vaapidecode_flush (GstVideoDecoder * vdec) gst_vaapidecode_purge (decode); - /* in reverse playback we cannot destroy the decoder at flush, since - * it will lost the parsing state */ - reverse = decode->in_segment.rate < 0; - - /* There could be issues if we avoid the reset_full() while doing + /* There could be issues if we avoid the reset() while doing * seeking: we have to reset the internal state */ - return gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, !reverse); + return gst_vaapidecode_reset (decode, decode->sinkpad_caps, TRUE); } static gboolean @@ -1077,7 +1072,7 @@ gst_vaapidecode_set_format (GstVideoDecoder * vdec, GstVideoCodecState * state) return FALSE; if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) return FALSE; - if (!gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, FALSE)) + if (!gst_vaapidecode_reset (decode, decode->sinkpad_caps, FALSE)) return FALSE; return TRUE; From bae56fe0c2ca8212e5c3c8e5312e8b95d22c7b41 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sat, 8 Apr 2017 01:21:23 +1000 Subject: [PATCH 2739/3781] h264 decoder: Implement reset() for faster flush Implement a custom reset() function for faster flushes that just clear the reference pictures but don't reallocate the DPB or clear out SPS/PPS https://bugzilla.gnome.org/show_bug.cgi?id=781142 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index f87ac308f3..b97c5506e3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1258,6 +1258,37 @@ gst_vaapi_decoder_h264_create (GstVaapiDecoder * base_decoder) return TRUE; } +/* Limited reset can just needs to get the decoder + * ready to process fresh data after a flush. + * Preserves the existing DPB allocation and any SPS/PPS */ +static GstVaapiDecoderStatus +gst_vaapi_decoder_h264_reset (GstVaapiDecoder * base_decoder) +{ + GstVaapiDecoderH264 *const decoder = + GST_VAAPI_DECODER_H264_CAST (base_decoder); + GstVaapiDecoderH264Private *const priv = &decoder->priv; + + gst_vaapi_decoder_h264_close (decoder); + priv->is_opened = FALSE; + + priv->dpb_size = 0; + + g_free (priv->prev_ref_frames); + priv->prev_ref_frames = NULL; + g_free (priv->prev_frames); + priv->prev_frames = NULL; + priv->prev_frames_alloc = 0; + + priv->profile = GST_VAAPI_PROFILE_UNKNOWN; + priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD; + priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + priv->progressive_sequence = TRUE; + priv->top_field_first = FALSE; + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + /* Activates the supplied PPS */ static GstH264PPS * ensure_pps (GstVaapiDecoderH264 * decoder, GstH264PPS * pps) @@ -4658,6 +4689,7 @@ gst_vaapi_decoder_h264_class_init (GstVaapiDecoderH264Class * klass) decoder_class->create = gst_vaapi_decoder_h264_create; decoder_class->destroy = gst_vaapi_decoder_h264_destroy; + decoder_class->reset = gst_vaapi_decoder_h264_reset; decoder_class->parse = gst_vaapi_decoder_h264_parse; decoder_class->decode = gst_vaapi_decoder_h264_decode; decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame; From ebca86dcc7fc9b54632f6e0a398caa7516f40659 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sat, 8 Apr 2017 02:05:21 +1000 Subject: [PATCH 2740/3781] vaapidecode: Don't renegotiate on every flush If caps don't actually change, don't update the decoder and don't set the do_renego flag forcing downstream renegotiation https://bugzilla.gnome.org/show_bug.cgi?id=781142 --- gst/vaapi/gstvaapidecode.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 33adcef1c0..1b312598f4 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -960,10 +960,12 @@ gst_vaapidecode_reset (GstVaapiDecode * decode, GstCaps * caps, decode->current_frame_size = 0; if (decode->decoder) { - if (gst_vaapi_decoder_update_caps (decode->decoder, caps)) { - g_atomic_int_set (&decode->do_renego, TRUE); - if (!force_reset) - return TRUE; + if (!gst_caps_is_equal (caps, gst_vaapi_decoder_get_caps (decode->decoder))) { + if (gst_vaapi_decoder_update_caps (decode->decoder, caps)) { + g_atomic_int_set (&decode->do_renego, TRUE); + if (!force_reset) + return TRUE; + } } return gst_vaapi_decoder_reset (decode->decoder); } From 24af97a7d106c1ba7cd1fe607e427f728ab9cf9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 8 Dec 2016 18:51:54 +0100 Subject: [PATCH 2741/3781] plugins: enable direct rendering with envvar Direct rendering (use vaDeriveImage rather than vaPutImage) has better performance in some Intel platforms (Haswell, for example) but in others (Skylake) is the opposite. In order to have some control, the patch enables the direct rendering through the environment variable GST_VAAPI_ENABLE_DIRECT_RENDERING. Also it seems to generating some problems with gallium/radeon backend. See bug #779642. https://bugzilla.gnome.org/show_bug.cgi?id=775848 --- gst/vaapi/gstvaapipluginbase.c | 5 ++++- gst/vaapi/gstvaapipluginbase.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index a60498df4f..8c2b84aa50 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -247,6 +247,9 @@ gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin, if (!(GST_OBJECT_FLAGS (plugin) & GST_ELEMENT_FLAG_SINK)) plugin->srcpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "src"); gst_video_info_init (&plugin->srcpad_info); + + plugin->enable_direct_rendering = + (g_getenv ("GST_VAAPI_ENABLE_DIRECT_RENDERING") != NULL); } void @@ -592,7 +595,7 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo, get_dmabuf_surface_allocation_flags (), GST_PAD_SRC); } - } else { + } else if (plugin->enable_direct_rendering) { usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); } diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index bfeeb1078e..3346ed40ae 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -149,6 +149,8 @@ struct _GstVaapiPluginBase GstAllocator *sinkpad_allocator; GstAllocator *srcpad_allocator; gboolean srcpad_can_dmabuf; + + gboolean enable_direct_rendering; }; struct _GstVaapiPluginBaseClass From 5c3318227b8b33071fa649662e21b337804e020c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Apr 2017 18:44:41 +0200 Subject: [PATCH 2742/3781] vaapipostproc: fixes for memory leaks The use of gst_vaapi_value_set_format() and gst_structure_*_value() requires to clear the used GValue to avoid a memory leak. --- gst/vaapi/gstvaapipostprocutil.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 1780df3f1f..84035ea55b 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -48,6 +48,7 @@ _transform_format (GstVaapiPostproc * postproc, GstCapsFeatures * features, return; gst_structure_set_value (structure, "format", &value); + g_value_unset (&value); } static void @@ -615,11 +616,11 @@ _set_preferred_format (GstStructure * outs, GstVideoFormat format) if (format == GST_VIDEO_FORMAT_UNKNOWN || format == GST_VIDEO_FORMAT_ENCODED) return FALSE; - if (gst_vaapi_value_set_format (&value, format)) { - gst_structure_set_value (outs, "format", &value); - return TRUE; - } - return FALSE; + if (!gst_vaapi_value_set_format (&value, format)) + return FALSE; + gst_structure_set_value (outs, "format", &value); + g_value_unset (&value); + return TRUE; } static GstCaps * From 26486c436a6d7f6bd0a2bbb26ac3ef9ab06f08ef Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 21 Apr 2017 18:05:48 +0900 Subject: [PATCH 2743/3781] vaapidecodebin: skips configuration once it's done Skips configuration of creation of vpp/capsfilter and link them once it's done. Otherwise, it always fails when it's trying to re-start playback. https://bugzilla.gnome.org/show_bug.cgi?id=781573 --- gst/vaapi/gstvaapidecodebin.c | 3 ++- gst/vaapi/gstvaapidecodebin.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 295c12bd97..2522b0af1c 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -302,7 +302,7 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) "max-size-buffers", vaapidecbin->max_size_buffers, "max-size-time", vaapidecbin->max_size_time, NULL); - if (vaapidecbin->disable_vpp) + if (vaapidecbin->disable_vpp || vaapidecbin->configured) return TRUE; GST_INFO_OBJECT (vaapidecbin, "enabling VPP"); @@ -357,6 +357,7 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) goto error_link_pad; gst_object_unref (bin_srcpad); + vaapidecbin->configured = TRUE; return TRUE; diff --git a/gst/vaapi/gstvaapidecodebin.h b/gst/vaapi/gstvaapidecodebin.h index 787d302be1..085a941bad 100644 --- a/gst/vaapi/gstvaapidecodebin.h +++ b/gst/vaapi/gstvaapidecodebin.h @@ -54,6 +54,7 @@ typedef struct _GstVaapiDecodeBin { GstVaapiDeinterlaceMethod deinterlace_method; gboolean disable_vpp; + gboolean configured; } GstVaapiDecodeBin; typedef struct _GstVaapiDecodeBinClass { From 9c3a4edf05ea325934c688622c8b1a1597620d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 Apr 2017 20:30:52 +0200 Subject: [PATCH 2744/3781] libs: window: wayland: cancel read at poll message Always call wl_display_cancel_read() when an errno is set, but different to EAGAIN or EINTR. https://bugzilla.gnome.org/show_bug.cgi?id=780442 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index df644aab0d..dda423baf4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -188,11 +188,11 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) int saved_errno = errno; if (saved_errno == EAGAIN || saved_errno == EINTR) goto again; - if (saved_errno == EBUSY) { /* closing */ - wl_display_cancel_read (wl_display); + wl_display_cancel_read (wl_display); + if (saved_errno == EBUSY) /* flushing */ return FALSE; - } - goto error; + else + goto error; } if (wl_display_read_events (wl_display) < 0) From 896a836f1dcd52c08d6ebcd5045d47036dce5854 Mon Sep 17 00:00:00 2001 From: Jagyum Koo Date: Sun, 30 Oct 2016 10:43:49 +0900 Subject: [PATCH 2745/3781] libs: window: wayland: rt event queue at destroy() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The proxy object of wl_buffer for the last frame remains in the wl_map. Even though we call wl_buffer_destroy() in frame_release_callback(), the proxy object remains without being removed, since proxy object is deleted when wayland server sees the delete request and sends 'delete_id' event. We need to call roundtrip before destroying event_queue so that the proxy object is removed. Otherwise, it would be mess up as receiving 'delete_id' event from previous play, when playing in the next va/wayland window with the same wl_display connection. https://bugzilla.gnome.org/show_bug.cgi?id=773689 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index dda423baf4..e4797b7c21 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -313,10 +313,15 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + struct wl_display *const wl_display = + GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); /* Wait for the last frame to complete redraw */ gst_vaapi_window_wayland_sync (window); + if (priv->event_queue) + wl_display_roundtrip_queue (wl_display, priv->event_queue); + if (priv->last_frame) { frame_state_free (priv->last_frame); priv->last_frame = NULL; From ca314a25ccf81c9740d147c6b20de4c24b354301 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 19 Apr 2017 10:37:19 +0900 Subject: [PATCH 2746/3781] libs: window: wayland: null buffer at destroy() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix leakage of the last wl buffer. VAAPI wayland sink needs to send a null buffer while destruction, it assures that all the wl buffers are released. Otherwise, the last buffer's callback might be not called, which leads to leak of GstVaapiDisplay. This was inspired by gstwaylandsink. https://bugzilla.gnome.org/show_bug.cgi?id=774029 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index e4797b7c21..ace2cffb04 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -319,6 +319,15 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) /* Wait for the last frame to complete redraw */ gst_vaapi_window_wayland_sync (window); + /* Make sure that the last wl buffer's callback could be called */ + GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + if (priv->surface) { + wl_surface_attach (priv->surface, NULL, 0, 0); + wl_surface_commit (priv->surface); + wl_display_flush (wl_display); + } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + if (priv->event_queue) wl_display_roundtrip_queue (wl_display, priv->event_queue); From 3b314ba93e61bad3d8decbe45bcb12717b595a55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 21 Apr 2017 14:07:44 +0200 Subject: [PATCH 2747/3781] libs: window: wayland: don't sync at destroy() Don't call gst_vaapi_window_wayland_sync() when destroying the wayland window instance, since it might lead to a lock at gst_poll_wait() when more than one instances of vaapisink are rendering in the same pipeline, this is because they share the same window. Since now all the frames are freed we don't need to freed the private last_frame, since its address is invalid now. https://bugzilla.gnome.org/show_bug.cgi?id=780442 Signed-off-by: Hyunjun Ko --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index ace2cffb04..1cdf6d22c0 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -316,9 +316,6 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) struct wl_display *const wl_display = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - /* Wait for the last frame to complete redraw */ - gst_vaapi_window_wayland_sync (window); - /* Make sure that the last wl buffer's callback could be called */ GST_VAAPI_OBJECT_LOCK_DISPLAY (window); if (priv->surface) { @@ -328,14 +325,11 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) } GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + gst_poll_set_flushing (priv->poll, TRUE); + if (priv->event_queue) wl_display_roundtrip_queue (wl_display, priv->event_queue); - if (priv->last_frame) { - frame_state_free (priv->last_frame); - priv->last_frame = NULL; - } - if (priv->shell_surface) { wl_shell_surface_destroy (priv->shell_surface); priv->shell_surface = NULL; From 824974e657445401d9d7b56c556c0a1a9f4c22c7 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 21 Apr 2017 15:30:09 +0200 Subject: [PATCH 2748/3781] libs: window: wayland: mark frames as done MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the frame listener callbacks 'done', the number of pending frames are decreased. Nonetheless, there might be occasions where the buffer listener callbacks 'release', without calling previously frame's 'done'. This leads to problem with gst_vaapi_window_wayland_sync() operation. This patch marks as done those frames which were callbacked, but if the buffer callbacks 'release' and associated frame is not marked as 'done' it is so, thus the number of pending frames keeps correct. https://bugzilla.gnome.org/show_bug.cgi?id=780442 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 22 ++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 1cdf6d22c0..80f0f5e633 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -62,6 +62,7 @@ struct _FrameState GstVaapiSurface *surface; GstVaapiVideoPool *surface_pool; struct wl_callback *callback; + gboolean done; }; static FrameState * @@ -77,6 +78,7 @@ frame_state_new (GstVaapiWindow * window) frame->surface = NULL; frame->surface_pool = NULL; frame->callback = NULL; + frame->done = FALSE; return frame; } @@ -372,15 +374,21 @@ gst_vaapi_window_wayland_resize (GstVaapiWindow * window, return TRUE; } -static void -frame_done_callback (void *data, struct wl_callback *callback, uint32_t time) +static inline gboolean +frame_done (FrameState * frame) { - FrameState *const frame = data; GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); + g_atomic_int_set (&frame->done, TRUE); g_atomic_pointer_compare_and_exchange (&priv->last_frame, frame, NULL); - g_atomic_int_dec_and_test (&priv->num_frames_pending); + return g_atomic_int_dec_and_test (&priv->num_frames_pending); +} + +static void +frame_done_callback (void *data, struct wl_callback *callback, uint32_t time) +{ + frame_done (data); } static const struct wl_callback_listener frame_callback_listener = { @@ -390,8 +398,12 @@ static const struct wl_callback_listener frame_callback_listener = { static void frame_release_callback (void *data, struct wl_buffer *wl_buffer) { + FrameState *const frame = data; + + if (!frame->done) + frame_done (frame); wl_buffer_destroy (wl_buffer); - frame_state_free (data); + frame_state_free (frame); } static const struct wl_buffer_listener frame_buffer_listener = { From 307148dfc801d2c2c3eada4e041bdb81f24783b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 24 Apr 2017 20:30:30 +0100 Subject: [PATCH 2749/3781] Automatic update of common submodule From 60aeef6 to 48a5d85 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 60aeef6837..48a5d85ebf 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 60aeef6837610c672cebf247ec748538faab7bf1 +Subproject commit 48a5d85ebf4a0bad1c997c83100f710fe2154fbf From 2d7c7630c9e64294bace52e87122d37bbef4e2d8 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 25 Apr 2017 16:23:08 +0900 Subject: [PATCH 2750/3781] libs: windows: wayland: fix leak if failure of sync Sometimes gst_vaapi_window_wayland_sync returns FALSE when poll returns EBUSY during destruction. In this case, if GstVaapiWindow is using vpp, leak of vpp surface happens. This surface is not attached to anything at this moment, so we should release it manually. https://bugzilla.gnome.org/show_bug.cgi?id=781695 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 80f0f5e633..45934aa720 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -480,6 +480,9 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, /* Wait for the previous frame to complete redraw */ if (!gst_vaapi_window_wayland_sync (window)) { + /* Release vpp surface if exists */ + if (priv->need_vpp && window->has_vpp) + gst_vaapi_video_pool_put_object (window->surface_pool, surface); wl_buffer_destroy (buffer); return !priv->sync_failed; } From 10fc9a97b5556407571ae6834f3553317a88cf7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 25 Apr 2017 12:58:44 +0200 Subject: [PATCH 2751/3781] test: elements: fix compilation flags This issue was spotten on bug #766704 Original-patch-by: Hyunjun Ko --- tests/elements/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/elements/Makefile.am b/tests/elements/Makefile.am index f940a5d0bf..93b30c8ecf 100644 --- a/tests/elements/Makefile.am +++ b/tests/elements/Makefile.am @@ -10,7 +10,7 @@ TEST_CFLAGS = \ TEST_LIBS = \ $(GST_LIBS) \ - $(GST_VIDEO_CFLAGS) \ + $(GST_VIDEO_LIBS) \ $(NULL) test_vaapisink_SOURCES = test-vaapisink.c From 158b44fc1ed7d8fb48bd1db9a36b8ddb30f38c5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 21 Apr 2017 19:07:18 +0200 Subject: [PATCH 2752/3781] vaapivideobufferpool: create or reconfig allocator Sometimes a video decoder could set different buffer pool configurations, because their frame size changes. In this case we did not reconfigure the allocator. This patch enables this use case, creating a new allocator inside the VAAPI buffer pool if the caps changed, if it is not dmabuf-based. If so, it is just reconfigured, since it doesn't have a surface pool. https://bugzilla.gnome.org/show_bug.cgi?id=781577 --- gst/vaapi/gstvaapivideobufferpool.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 6aec965399..1834bd7593 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -161,6 +161,27 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, gst_object_replace ((GstObject **) & priv->allocator, NULL); priv->video_info = new_vip; + { + guint surface_alloc_flags; + gboolean vinfo_changed = FALSE; + + if (allocator) { + const GstVideoInfo *alloc_vinfo = + gst_allocator_get_vaapi_video_info (allocator, &surface_alloc_flags); + vinfo_changed = gst_video_info_changed (alloc_vinfo, &new_vip); + } + + if (vinfo_changed && allocator && priv->use_dmabuf_memory) { + gst_allocator_set_vaapi_video_info (allocator, &new_vip, + surface_alloc_flags); + } else if (!priv->use_dmabuf_memory && (vinfo_changed || !allocator)) { + /* let's destroy the other allocator and create a new one */ + allocator = gst_vaapi_video_allocator_new (priv->display, &new_vip, + surface_alloc_flags, 0); + gst_buffer_pool_config_set_allocator (config, allocator, NULL); + } + } + if (!gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) goto error_no_vaapi_video_meta_option; From cce5ce4a9dd74f83224e437af9344db6b8daefdb Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 27 Apr 2017 14:42:55 +0900 Subject: [PATCH 2753/3781] vaapivideobufferpool: fix leak of created allocator Since it's created by itself, it should be unref-counted after gst_buffer_pool_config_set_allocator call. Afterwards, this allocator will be ref-counted again when assigning to priv->allocator. https://bugzilla.gnome.org/show_bug.cgi?id=781577 --- gst/vaapi/gstvaapivideobufferpool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 1834bd7593..2782403a13 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -179,6 +179,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, allocator = gst_vaapi_video_allocator_new (priv->display, &new_vip, surface_alloc_flags, 0); gst_buffer_pool_config_set_allocator (config, allocator, NULL); + gst_object_unref (allocator); } } From 4820d2d09db1af3f23258caf029696884a65fbe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 26 Apr 2017 15:48:01 +0200 Subject: [PATCH 2754/3781] plugins: handle pixel-aspect-ratio with value 0/1 When downstream negotiates a pixel-aspect-ratio of 0/1, the calculations for resizing and formatting in vaapipostproc and vaapisink, respectively, failed, and thus the pipeline. This patch handles this situation by converting p-a-r of 0/1 to 1/1. This is how other sinks, such as glimagesink, work. https://bugzilla.gnome.org/show_bug.cgi?id=781759 --- gst/vaapi/gstvaapipostprocutil.c | 2 ++ gst/vaapi/gstvaapisink.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 84035ea55b..0fa474eb55 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -176,6 +176,8 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, gint num, den; from_par_n = GST_VIDEO_INFO_PAR_N (vinfo); + if (from_par_n == 0) + from_par_n = 1; from_par_d = GST_VIDEO_INFO_PAR_D (vinfo); from_w = GST_VIDEO_INFO_WIDTH (vinfo); from_h = GST_VIDEO_INFO_HEIGHT (vinfo); diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 9cc5154cda..013a4690a5 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1334,6 +1334,8 @@ gst_vaapisink_set_caps (GstBaseSink * base_sink, GstCaps * caps) sink->video_height = GST_VIDEO_INFO_HEIGHT (vip); sink->video_par_n = GST_VIDEO_INFO_PAR_N (vip); sink->video_par_d = GST_VIDEO_INFO_PAR_D (vip); + if (sink->video_par_n == 0) + sink->video_par_n = 1; GST_DEBUG ("video pixel-aspect-ratio %d/%d", sink->video_par_n, sink->video_par_d); From c0be7b1890ea8da915a81ae82bc9f504aee7cc26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 27 Apr 2017 12:43:54 +0200 Subject: [PATCH 2755/3781] plugins: reject pixel-aspect-ratio with value 0/1 Do not negotiate a pixel-aspect-ratio of 0/1. https://bugzilla.gnome.org/show_bug.cgi?id=781759 --- gst/vaapi/gstvaapipluginutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 78a46239a6..f3bac7dea6 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -426,7 +426,7 @@ set_video_template_caps (GstCaps * caps) "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, - "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 1, 1, G_MAXINT, 1, NULL); } GstCaps * From c7d46646091e4ff901cc0f8db365a406a496c3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 27 Apr 2017 13:08:56 +0200 Subject: [PATCH 2756/3781] Revert "plugins: reject pixel-aspect-ratio with value 0/1" This reverts commit c0be7b1890ea8da915a81ae82bc9f504aee7cc26. --- gst/vaapi/gstvaapipluginutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index f3bac7dea6..78a46239a6 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -426,7 +426,7 @@ set_video_template_caps (GstCaps * caps) "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, - "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 1, 1, G_MAXINT, 1, NULL); + "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); } GstCaps * From 5647e3392b447b7115819f0c7552d62c46df2077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 27 Apr 2017 17:49:52 +0300 Subject: [PATCH 2757/3781] Release 1.11.91 --- ChangeLog | 290 ++++++++++++++++++++++++++++++++++++++++++- NEWS | 2 +- configure.ac | 12 +- gstreamer-vaapi.doap | 10 ++ meson.build | 2 +- 5 files changed, 305 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 571bc83cb6..211b41ce41 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,293 @@ -=== release 1.11.90 === +=== release 1.11.91 === -2017-04-07 Sebastian Dröge +2017-04-27 Sebastian Dröge * configure.ac: - releasing 1.11.90 + releasing 1.11.91 + +2017-04-27 13:08:56 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + Revert "plugins: reject pixel-aspect-ratio with value 0/1" + This reverts commit c0be7b1890ea8da915a81ae82bc9f504aee7cc26. + +2017-04-27 12:43:54 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: reject pixel-aspect-ratio with value 0/1 + Do not negotiate a pixel-aspect-ratio of 0/1. + https://bugzilla.gnome.org/show_bug.cgi?id=781759 + +2017-04-26 15:48:01 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostprocutil.c: + * gst/vaapi/gstvaapisink.c: + plugins: handle pixel-aspect-ratio with value 0/1 + When downstream negotiates a pixel-aspect-ratio of 0/1, the + calculations for resizing and formatting in vaapipostproc and + vaapisink, respectively, failed, and thus the pipeline. + This patch handles this situation by converting p-a-r of 0/1 to + 1/1. This is how other sinks, such as glimagesink, work. + https://bugzilla.gnome.org/show_bug.cgi?id=781759 + +2017-04-27 14:42:55 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: fix leak of created allocator + Since it's created by itself, it should be unref-counted + after gst_buffer_pool_config_set_allocator call. Afterwards, + this allocator will be ref-counted again when assigning to priv->allocator. + https://bugzilla.gnome.org/show_bug.cgi?id=781577 + +2017-04-21 19:07:18 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: create or reconfig allocator + Sometimes a video decoder could set different buffer pool + configurations, because their frame size changes. In this case we + did not reconfigure the allocator. + This patch enables this use case, creating a new allocator inside + the VAAPI buffer pool if the caps changed, if it is not dmabuf-based. + If so, it is just reconfigured, since it doesn't have a surface pool. + https://bugzilla.gnome.org/show_bug.cgi?id=781577 + +2017-04-25 12:58:44 +0200 Víctor Manuel Jáquez Leal + + * tests/elements/Makefile.am: + test: elements: fix compilation flags + This issue was spotten on bug #766704 + Original-patch-by: Hyunjun Ko + +2017-04-25 16:23:08 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: windows: wayland: fix leak if failure of sync + Sometimes gst_vaapi_window_wayland_sync returns FALSE when poll returns EBUSY + during destruction. + In this case, if GstVaapiWindow is using vpp, leak of vpp surface happens. + This surface is not attached to anything at this moment, so we should release + it manually. + https://bugzilla.gnome.org/show_bug.cgi?id=781695 + +2017-04-24 20:30:30 +0100 Tim-Philipp Müller + + * common: + Automatic update of common submodule + From 60aeef6 to 48a5d85 + +2017-04-21 15:30:09 +0200 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: window: wayland: mark frames as done + When the frame listener callbacks 'done', the number of pending + frames are decreased. Nonetheless, there might be occasions where + the buffer listener callbacks 'release', without calling previously + frame's 'done'. This leads to problem with + gst_vaapi_window_wayland_sync() operation. + This patch marks as done those frames which were callbacked, but if + the buffer callbacks 'release' and associated frame is not marked + as 'done' it is so, thus the number of pending frames keeps correct. + https://bugzilla.gnome.org/show_bug.cgi?id=780442 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-04-21 14:07:44 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: window: wayland: don't sync at destroy() + Don't call gst_vaapi_window_wayland_sync() when destroying the + wayland window instance, since it might lead to a lock at + gst_poll_wait() when more than one instances of vaapisink are + rendering in the same pipeline, this is because they share the + same window. + Since now all the frames are freed we don't need to freed the + private last_frame, since its address is invalid now. + https://bugzilla.gnome.org/show_bug.cgi?id=780442 + Signed-off-by: Hyunjun Ko + +2017-04-19 10:37:19 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: window: wayland: null buffer at destroy() + Fix leakage of the last wl buffer. + VAAPI wayland sink needs to send a null buffer while destruction, + it assures that all the wl buffers are released. Otherwise, the last + buffer's callback might be not called, which leads to leak of + GstVaapiDisplay. + This was inspired by gstwaylandsink. + https://bugzilla.gnome.org/show_bug.cgi?id=774029 + Signed-off-by: Víctor Manuel Jáquez Leal + +2016-10-30 10:43:49 +0900 Jagyum Koo + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: window: wayland: rt event queue at destroy() + The proxy object of wl_buffer for the last frame remains in the + wl_map. Even though we call wl_buffer_destroy() in + frame_release_callback(), the proxy object remains without being + removed, since proxy object is deleted when wayland server sees the + delete request and sends 'delete_id' event. + We need to call roundtrip before destroying event_queue so that the + proxy object is removed. Otherwise, it would be mess up as receiving + 'delete_id' event from previous play, when playing in the next + va/wayland window with the same wl_display connection. + https://bugzilla.gnome.org/show_bug.cgi?id=773689 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-04-20 20:30:52 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: window: wayland: cancel read at poll message + Always call wl_display_cancel_read() when an errno is set, but + different to EAGAIN or EINTR. + https://bugzilla.gnome.org/show_bug.cgi?id=780442 + +2017-04-21 18:05:48 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapidecodebin.h: + vaapidecodebin: skips configuration once it's done + Skips configuration of creation of vpp/capsfilter and link them once it's done. + Otherwise, it always fails when it's trying to re-start playback. + https://bugzilla.gnome.org/show_bug.cgi?id=781573 + +2017-04-20 18:44:41 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: fixes for memory leaks + The use of gst_vaapi_value_set_format() and gst_structure_*_value() + requires to clear the used GValue to avoid a memory leak. + +2016-12-08 18:51:54 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: enable direct rendering with envvar + Direct rendering (use vaDeriveImage rather than vaPutImage) has better + performance in some Intel platforms (Haswell, for example) but in others + (Skylake) is the opposite. + In order to have some control, the patch enables the direct rendering + through the environment variable GST_VAAPI_ENABLE_DIRECT_RENDERING. + Also it seems to generating some problems with gallium/radeon backend. + See bug #779642. + https://bugzilla.gnome.org/show_bug.cgi?id=775848 + +2017-04-08 02:05:21 +1000 Jan Schmidt + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Don't renegotiate on every flush + If caps don't actually change, don't update the + decoder and don't set the do_renego flag forcing + downstream renegotiation + https://bugzilla.gnome.org/show_bug.cgi?id=781142 + +2017-04-08 01:21:23 +1000 Jan Schmidt + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264 decoder: Implement reset() for faster flush + Implement a custom reset() function for faster flushes + that just clear the reference pictures but don't reallocate + the DPB or clear out SPS/PPS + https://bugzilla.gnome.org/show_bug.cgi?id=781142 + +2017-04-05 17:24:20 +1000 Jan Schmidt + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst/vaapi/gstvaapidecode.c: + Implement decoder reset on flush, rather than recreating + Clear decoders out on a flush but keep the same instance, + rather than completely recreating them. That avoids + unecessarily freeing and recreating surface pools + and contexts, which can be quite expensive + https://bugzilla.gnome.org/show_bug.cgi?id=781142 + +2017-04-11 18:50:35 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + libs: window: don't add an unused function + The macro GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE only defines + a function that is never used, thus when compiling we might see + this warning (clang): + gstvaapiwindow.c:147:1: warning: unused function 'gst_vaapi_window_class' [-Wunused-function] + GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindow, + ^ + https://bugzilla.gnome.org/show_bug.cgi?id=759533 + +2017-04-11 18:22:00 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + libs: window: remove surface_format member + Since we always convert to NV12, there is no need to keep a + variable for that. Let us hard code it. + https://bugzilla.gnome.org/show_bug.cgi?id=759533 + +2017-04-10 17:23:26 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + libs: window: x11/wayland: use new api for conversion + Since gst_vaapi_window_vpp_convert_internal is created, + GstVaapiWindowX11/Wayland can use it for conversion. + Note that once it chooses to use vpp, it's going to use vpp + until the session is finished. + https://bugzilla.gnome.org/show_bug.cgi?id=759533 + +2017-04-10 11:41:29 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + libs: window: add gst_vaapi_window_vpp_convert_internal() + If a backend doesn't support specific format, we can use vpp for conversion + and make it playing. + This api is originated from GstVaapiWindowWayland and moved to GstVaapiWindow, + so that GstVaapiWindowX11 could use it. + https://bugzilla.gnome.org/show_bug.cgi?id=759533 + +2017-04-03 16:45:36 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + libs: window: x11/wayland: chaining up to GstVaapiWindow + Currently, GstVaapiWindowX11/Wayland are not descendants of GstVaapiWindow. + This patch chains them up to GstVaapiWindow to handle common members in GstVaapiWindow. + https://bugzilla.gnome.org/show_bug.cgi?id=759533 + +2017-04-05 11:19:15 -0700 Scott D Phillips + + * gst/vaapi/gstvaapipluginutil.c: + plugins: Fix usage of GST_GL_HAVE_WINDOW_* defines + When these definitions are false, they are undef in the + preprocessor, not a defined value of 0. When they are unset the + compile fails with: + 'GST_GL_HAVE_WINDOW_WAYLAND' undeclared (first use in this function) + https://bugzilla.gnome.org/show_bug.cgi?id=780948 + +2017-04-10 23:51:06 +0100 Tim-Philipp Müller + + * common: + Automatic update of common submodule + From 39ac2f5 to 60aeef6 + +=== release 1.11.90 === + +2017-04-07 16:36:21 +0300 Sebastian Dröge + + * ChangeLog: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.11.90 2017-04-03 14:52:41 +0200 Víctor Manuel Jáquez Leal diff --git a/NEWS b/NEWS index 8e8dc3f622..bf58e3069e 100644 --- a/NEWS +++ b/NEWS @@ -1 +1 @@ -This is GStreamer 1.11.90. +This is GStreamer 1.11.91. diff --git a/configure.ac b/configure.ac index 7f2edd0a8b..7362061530 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [11]) -m4_define([gst_vaapi_micro_version], [90]) +m4_define([gst_vaapi_micro_version], [91]) m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1190]) +m4_define([gst_vaapi_lt_current], [1191]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1190]) +m4_define([gst_vaapi_lt_age], [1191]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.11.90]) -m4_define([gst_plugins_base_version], [1.11.90]) -m4_define([gst_plugins_bad_version], [1.11.90]) +m4_define([gst_version], [1.11.91]) +m4_define([gst_plugins_base_version], [1.11.91]) +m4_define([gst_plugins_bad_version], [1.11.91]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index ab9267f4fa..bfbfab3172 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.11.91 + master + + 2017-04-27 + + + + 1.11.90 diff --git a/meson.build b/meson.build index 0bbd5911e0..dd1ca68091 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.11.90', + version : '1.11.91', meson_version : '>= 0.36.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 8cbe03599a4f27c2001380e2ec150c4f4267a9cf Mon Sep 17 00:00:00 2001 From: Victor Toso Date: Tue, 2 May 2017 14:08:54 +0200 Subject: [PATCH 2758/3781] vaapidecodebin: fix element's classification This bin should have similar classification as decodebin which is "Generic/Bin/Decoder" otherwise it will appear wrongly as video decoder. Signed-off-by: Victor Toso https://bugzilla.gnome.org/show_bug.cgi?id=782063 --- gst/vaapi/gstvaapidecodebin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 2522b0af1c..7f756e8e6d 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -251,7 +251,7 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) element_class->change_state = gst_vaapi_decode_bin_change_state; gst_element_class_set_static_metadata (element_class, "VA-API Decode Bin", - "Codec/Decoder/Video", + "Generic/Bin/Decoder", GST_PLUGIN_DESC, "Sreerenj Balachandran , " "Victor Jaquez "); From 33888bf534400d3ea3ad7f4c9041ed835076fcc0 Mon Sep 17 00:00:00 2001 From: Scott D Phillips Date: Thu, 27 Apr 2017 22:55:27 -0700 Subject: [PATCH 2759/3781] build: Require libva < 0.99.0 libva >= 0.99.0 is not currently supported by gstreamer-vaapi, so fail to configure instead of failing late in the build. This libva is bundled in msdk[1] and it is ahead in time with respect the official and open source libva[2]. GStreamer-VAAPI only supports the latter for now. 1. https://software.intel.com/en-us/media-sdk/download 2. https://github.com/01org/libva/ https://bugzilla.gnome.org/show_bug.cgi?id=781866 --- configure.ac | 2 +- meson.build | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 7362061530..312815910b 100644 --- a/configure.ac +++ b/configure.ac @@ -484,7 +484,7 @@ dnl -- VA-API -- dnl --------------------------------------------------------------------------- dnl Core API -PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ]) +PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ libva < 0.99.0]) VA_VERSION_STR=`$PKG_CONFIG --modversion libva` VA_DRIVERS_PATH=`$PKG_CONFIG --variable=driverdir libva` AC_DEFINE_UNQUOTED([VA_DRIVERS_PATH], ["$VA_DRIVERS_PATH"], diff --git a/meson.build b/meson.build index dd1ca68091..70f0bbeb91 100644 --- a/meson.build +++ b/meson.build @@ -37,7 +37,7 @@ gstcodecparsers_dep = dependency('gstreamer-codecparsers-1.0', version : gst_req gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, fallback : ['gst-plugins-bad', 'gstgl_dep'], required: false) gmodule_dep = dependency('gmodule-2.0', required: false) -libva_dep = dependency('libva', version: '>= 0.30.4') +libva_dep = dependency('libva', version: ['>= 0.30.4', '< 0.99.0']) libva_drm_dep = dependency('libva-drm', version: '>= 0.33.0', required: false) libva_wayland_dep = dependency('libva-wayland', version: '>= 0.33.0', required: false) From c45d448a15682f47716cc08ebdaf231e400b9ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 4 May 2017 11:49:33 +0200 Subject: [PATCH 2760/3781] Revert "vaapidecodebin: fix element's classification" This reverts commit 8cbe03599a4f27c2001380e2ec150c4f4267a9cf. --- gst/vaapi/gstvaapidecodebin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 7f756e8e6d..2522b0af1c 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -251,7 +251,7 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) element_class->change_state = gst_vaapi_decode_bin_change_state; gst_element_class_set_static_metadata (element_class, "VA-API Decode Bin", - "Generic/Bin/Decoder", + "Codec/Decoder/Video", GST_PLUGIN_DESC, "Sreerenj Balachandran , " "Victor Jaquez "); From 14ed473dbde118aefd5cb55d134243f2a56e654b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 4 May 2017 15:46:03 +0300 Subject: [PATCH 2761/3781] Release 1.12.0 --- ChangeLog | 47 ++- NEWS | 735 ++++++++++++++++++++++++++++++++++++++++++- configure.ac | 14 +- gstreamer-vaapi.doap | 10 + meson.build | 2 +- 5 files changed, 796 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 211b41ce41..aafc3bad7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,50 @@ -=== release 1.11.91 === +=== release 1.12.0 === -2017-04-27 Sebastian Dröge +2017-05-04 Sebastian Dröge * configure.ac: - releasing 1.11.91 + releasing 1.12.0 + +2017-05-04 11:49:33 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + Revert "vaapidecodebin: fix element's classification" + This reverts commit 8cbe03599a4f27c2001380e2ec150c4f4267a9cf. + +2017-04-27 22:55:27 -0700 Scott D Phillips + + * configure.ac: + * meson.build: + build: Require libva < 0.99.0 + libva >= 0.99.0 is not currently supported by gstreamer-vaapi, so + fail to configure instead of failing late in the build. + This libva is bundled in msdk[1] and it is ahead in time with + respect the official and open source libva[2]. GStreamer-VAAPI + only supports the latter for now. + 1. https://software.intel.com/en-us/media-sdk/download + 2. https://github.com/01org/libva/ + https://bugzilla.gnome.org/show_bug.cgi?id=781866 + +2017-05-02 14:08:54 +0200 Victor Toso + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: fix element's classification + This bin should have similar classification as decodebin which is + "Generic/Bin/Decoder" otherwise it will appear wrongly as video + decoder. + Signed-off-by: Victor Toso + https://bugzilla.gnome.org/show_bug.cgi?id=782063 + +=== release 1.11.91 === + +2017-04-27 17:49:52 +0300 Sebastian Dröge + + * ChangeLog: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.11.91 2017-04-27 13:08:56 +0200 Víctor Manuel Jáquez Leal diff --git a/NEWS b/NEWS index bf58e3069e..74fb1eaeb8 100644 --- a/NEWS +++ b/NEWS @@ -1 +1,734 @@ -This is GStreamer 1.11.91. +# GStreamer 1.12 Release Notes + +GStreamer 1.12.0 was originally released on 4th May 2017. + +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 new features, bug fixes and other +improvements. + +See [https://gstreamer.freedesktop.org/releases/1.12/][latest] for the latest +version of this document. + +*Last updated: Thursday 4 May 2017, 11:00 UTC [(log)][gitlog]* + +[latest]: https://gstreamer.freedesktop.org/releases/1.12/ +[gitlog]: https://cgit.freedesktop.org/gstreamer/www/log/src/htdocs/releases/1.12/release-notes-1.12.md + +## 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 new features, bug fixes and other +improvements. + +## Highlights + +- new `msdk` plugin for Intel's Media SDK for hardware-accelerated video + encoding and decoding on Intel graphics hardware on Windows or Linux. + +- `x264enc` can now use multiple x264 library versions compiled for different + bit depths at runtime, to transparently provide support for multiple bit + depths. + +- `videoscale` and `videoconvert` now support multi-threaded scaling and + conversion, which is particularly useful with higher resolution video. + +- `h264parse` will now automatically insert AU delimiters if needed when + outputting byte-stream format, which improves standard compliance and + is needed in particular for HLS playback on iOS/macOS. + +- `rtpbin` has acquired bundle support for incoming streams + +## Major new features and changes + +### Noteworthy new API + +- The video library gained support for a number of new video formats: + + - `GBR_12LE`, `GBR_12BE`, `GBRA_12LE`, `GBRA_12BE` (planar 4:4:4 RGB/RGBA, 12 bits per channel) + - `GBRA_10LE`, `GBRA_10BE` (planar 4:4:4:4 RGBA, 10 bits per channel) + - `GBRA` (planar 4:4:4:4 ARGB, 8 bits per channel) + - `I420_12BE`, `I420_12LE` (planar 4:2:0 YUV, 12 bits per channel) + - `I422_12BE`,`I422_12LE` (planar 4:2:2 YUV, 12 bits per channel) + - `Y444_12BE`, `Y444_12LE` (planar 4:4:4 YUV, 12 bits per channel) + - `VYUY` (another packed 4:2:2 YUV format) + +- The high-level `GstPlayer` API was extended with functions for taking video + snapshots and enabling accurate seeking. It can optionally also use the + still-experimental `playbin3` element now. + +### New Elements + +- msdk: new plugin for Intel's Media SDK for hardware-accelerated video encoding + and decoding on Intel graphics hardware on Windows or Linux. This includes + an H.264 encoder/decoder (`msdkh264dec`, `msdkh264enc`), + an H.265 encoder/decoder (`msdkh265dec`, `msdkh265enc`), + an MJPEG encoder/encoder (`msdkmjpegdec`, `msdkmjpegenc`), + an MPEG-2 video encoder (`msdkmpeg2enc`) and a VP8 encoder (`msdkvp8enc`). + +- `iqa` is a new Image Quality Assessment plugin based on [DSSIM][dssim], + similar to the old (unported) videomeasure element. + +- The `faceoverlay` element, which allows you to overlay SVG graphics over + a detected face in a video stream, has been ported from 0.10. + +- our `ffmpeg` wrapper plugin now exposes/maps the ffmpeg Opus audio decoder + (`avdec_opus`) as well as the GoPro CineForm HD / CFHD decoder (`avdec_cfhd`), + and also a parser/writer for the IVF format (`avdemux_ivf` and `avmux_ivf`). + +- `audiobuffersplit` is a new element that splits raw audio buffers into + equal-sized buffers + +- `audiomixmatrix` is a new element that mixes N:M audio channels according to + a configured mix matrix. + +- The `timecodewait` element got renamed to `avwait` and can operate in + different modes now. + +- The `opencv` video processing plugin has gained a new `dewarp` element that + dewarps fisheye images. + +- `ttml` is a new plugin for parsing and rendering subtitles in Timed Text + Markup Language (TTML) format. For the time being these elements will not + be autoplugged during media playback however, unless the `GST_TTML_AUTOPLUG=1` + environment variable is set. Only the EBU-TT-D profile is supported at this + point. + +[dssim]: https://github.com/pornel/dssim + +### New element features and additions + +- `x264enc` can now use multiple x264 library versions compiled for different + bit depths at runtime, to transparently provide support for multiple bit + depths. A new configure parameter `--with-x264-libraries` has been added to + specify additional paths to look for additional x264 libraries to load. + Background is that the libx264 library is always compile for one specific + bit depth and the `x264enc` element would simply support the depth supported + by the underlying library. Now we can support multiple depths. + +- `x264enc` also picks up the interlacing mode automatically from the input + caps now and passed interlacing/TFF information correctly to the library. + +- `videoscale` and `videoconvert` now support multi-threaded scaling and + conversion, which is particularly useful with higher resolution video. + This has to be enabled explicitly via the `"n-threads"` property. + +- `videorate`'s new `"rate"` property lets you set a speed factor + on the output stream + +- `splitmuxsink`'s buffer collection and scheduling was rewritten to make + processing and splitting deterministic; before it was possible for a buffer + to end up in a different file chunk in different runs. `splitmuxsink` also + gained a new `"format-location-full"` signal that works just like the existing + `"format-location"` signal only that it is also passed the primary stream's + first buffer as argument, so that it is possible to construct the file name + based on metadata such as the buffer timestamp or any GstMeta attached to + the buffer. The new `"max-size-timecode"` property allows for timecode-based + splitting. `splitmuxsink` will now also automatically start a new file if the + input caps change in an incompatible way. + +- `fakesink` has a new `"drop-out-of-segment"` property to not drop + out-of-segment buffers, which is useful for debugging purposes. + +- `identity` gained a `"ts-offset"` property. + +- both `fakesink` and `identity` now also print what kind of metas are attached + to buffers when printing buffer details via the `"last-message"` property + used by `gst-launch-1.0 -v`. + +- multiqueue: made `"min-interleave-time"` a configurable property. + +- video nerds will be thrilled to know that `videotestsrc`'s snow is now + deterministic. `videotestsrc` also gained some new properties to make the + ball pattern based on system time, and invert colours each second + (`"animation-mode"`, `"motion"`, and `"flip"` properties). + +- `oggdemux` reverse playback should work again now. You're welcome. + +- `playbin3` and `urisourcebin` now have buffering enabled by default, and + buffering message aggregation was fixed. + +- `tcpclientsrc` now has a `"timeout"` property + +- `appsink` has gained support for buffer lists. For backwards compatibility + reasons users need to enable this explicitly with `gst_app_sink_set_buffer_list_support()`, + however. Once activated, a pulled `GstSample` can contain either a buffer + list or a single buffer. + +- `splitmuxsrc` reverse playback was fixed and handling of sparse streams, such + as subtitle tracks or metadata tracks, was improved. + +- `matroskamux` has acquired support for muxing G722 audio; it also marks all + buffers as keyframes now when streaming only audio, so that `tcpserversink` + will behave properly with audio-only streams. + +- `qtmux` gained support for ProRes 4444 XQ, HEVC/H.265 and CineForm (GoPro) formats, + and generally writes more video stream-related metadata into the track headers. + It is also allows configuration of the maximum interleave size in bytes and + time now. For fragmented mp4 we always write the `tfdt` atom now as required + by the DASH spec. + +- `qtdemux` supports FLAC, xvid, mp2, S16L and CineForm (GoPro) tracks now, and + generally tries harder to extract more video-related information from track + headers, such as colorimetry or interlacing details. It also received a + couple of fixes for the scenario where upstream operates in TIME format and + feeds chunks to qtdemux (e.g. DASH or MSE). + +- `audioecho` has two new properties to apply a delay only to certain channels + to create a surround effect, rather than an echo on all channels. This is + useful when upmixing from stereo, for example. The `"surround-delay"` property + enables this, and the `"surround-mask"` property controls which channels + are considered surround sound channels in this case. + +- `webrtcdsp` gained various new properties for gain control and also exposes + voice activity detection now, in which case it will post `"voice-activity"` + messages on the bus whenever the voice detection status changes. + +- The `decklink` capture elements for Blackmagic Decklink cards have seen a + number of improvements: + + - `decklinkvideosrc` will post a warning message on "no signal" and an info + message when the signal lock has been (re)acquired. There is also a new + read-only `"signal"` property that can be used to query the signal lock + status. The `GAP` flag will be set on buffers that are captured without + a signal lock. The new `drop-no-signal-frames` will make `decklinkvideosrc` + drop all buffers that have been captured without an input signal. The + `"skip-first-time"` property will make the source drop the first few + buffers, which is handy since some devices will at first output buffers + with the wrong resolution before they manage to figure out the right input + format and decide on the actual output caps. + + - `decklinkaudiosrc` supports more than just 2 audio channels now. + + - The capture sources no longer use the "hardware" timestamps which turn + out to be useless and instead just use the pipeline clock directly. + +- `srtpdec` now also has a readonly `"stats"` property, just like `srtpenc`. + +- `rtpbin` gained RTP bundle support, as used by e.g. WebRTC. The first + rtpsession will have a `rtpssrcdemux` element inside splitting the streams + based on their SSRC and potentially dispatch to a different rtpsession. + Because retransmission SSRCs need to be merged with the corresponding media + stream the `::on-bundled-ssrc` signal is emitted on `rtpbin` so that the + application can find out to which session the SSRC belongs. + +- `rtprtxqueue` gained two new properties exposing retransmission + statistics (`"requests"` and `"fulfilled-requests"`) + +- `kmssink` will now use the preferred mode for the monitor and render to the + base plane if nothing else has set a mode yet. This can also be done forcibly + in any case via the new `"force-modesetting"` property. Furthermore, `kmssink` + now allows only the supported connector resolutions as input caps in order to + avoid scaling or positioning of the input stream, as `kmssink` can't know + whether scaling or positioning would be more appropriate for the use case at + hand. + +- `waylandsink` can now take DMAbuf buffers as input in the presence + of a compatible Wayland compositor. This enables zero-copy transfer + from a decoder or source that outputs DMAbuf. + +- `udpsrc` can be bound to more than one interface when joining a + multicast group, this is done by giving a comma separate list of + interfaces such as multicast-iface="eth0,eth1". + +### Plugin moves + +- `dataurisrc` moved from gst-plugins-bad to core + +- The `rawparse` plugin containing the `rawaudioparse` and `rawvideoparse` + elements moved from gst-plugins-bad to gst-plugins-base. These elements + supersede the old `videoparse` and `audioparse` elements. They work the + same, with just some minor API changes. The old legacy elements still + exist in gst-plugins-bad, but may be removed at some point in the future. + +- `timecodestamper` is an element that attaches time codes to video buffers + in form of `GstVideoTimeCodeMeta`s. It had a `"clock-source"` property + which has now been removed because it was fairly useless in practice. It + gained some new properties however: the `"first-timecode"` property can + be used to set the inital timecode; alternatively `"first-timecode-to-now"` + can be set, and then the current system time at the time the first buffer + arrives is used as base time for the time codes. + + +### Plugin removals + +- The `mad` mp1/mp2/mp3 decoder plugin was removed from gst-plugins-ugly, + as libmad is GPL licensed, has been unmaintained for a very long time, and + there are better alternatives available. Use the `mpg123audiodec` element + from the `mpg123` plugin in gst-plugins-ugly instead, or `avdec_mp3` from + the `gst-libav` module which wraps the ffmpeg library. We expect that we + will be able to move mp3 decoding to gst-plugins-good in the next cycle + seeing that most patents around mp3 have expired recently or are about to + expire. + +- The `mimic` plugin was removed from gst-plugins-bad. It contained a decoder + and encoder for a video codec used by MSN messenger many many years ago (in + a galaxy far far away). The underlying library is unmaintained and no one + really needs to use this codec any more. Recorded videos can still be played + back with the MIMIC decoder in gst-libav. + +## Miscellaneous API additions + +- Request pad name templates passed to `gst_element_request_pad()` may now + contain multiple specifiers, such as e.g. `src_%u_%u`. + +- [`gst_buffer_iterate_meta_filtered()`][buffer-iterate-meta-filtered] is a + variant of `gst_buffer_iterate_meta()` that only returns metas of the + requested type and skips all other metas. + +- [`gst_pad_task_get_state()`][pad-task-get-state] gets the current state of + a task in a thread-safe way. + +- [`gst_uri_get_media_fragment_table()`][uri-get-fragment-table] provides the + media fragments of an URI as a table of key=value pairs. + +- [`gst_print()`][print], [`gst_println()`][println], [`gst_printerr()`][printerr], + and [`gst_printerrln()`][printerrln] can be used to print to stdout or stderr. + These functions are similar to `g_print()` and `g_printerr()` but they also + support all the additional format specifiers provided by the GStreamer + logging system, such as e.g. `GST_PTR_FORMAT`. + +- a `GstParamSpecArray` has been added, for elements who want to have array + type properties, such as the `audiomixmatrix` element for example. There are + also two new functions to set and get properties of this type from bindings: + - gst_util_set_object_array() + - gst_util_get_object_array() + +- various helper functions have been added to make it easier to set or get + GstStructure fields containing caps-style array or list fields from language + bindings (which usually support GValueArray but don't know about the GStreamer + specific fundamental types): + - [`gst_structure_get_array()`][get-array] + - [`gst_structure_set_array()`][set-array] + - [`gst_structure_get_list()`][get-list] + - [`gst_structure_set_list()`][set-list] + +- a new ['dynamic type' registry factory type][dynamic-type] was added to + register dynamically loadable GType types. This is useful for automatically + loading enum/flags types that are used in caps, such as for example the + `GstVideoMultiviewFlagsSet` type used in multiview video caps. + +- there is a new [`GstProxyControlBinding`][proxy-control-binding] for use + with GstController. This allows proxying the control interface from one + property on one GstObject to another property (of the same type) in another + GstObject. So e.g. in parent-child relationship, one may need to call + `gst_object_sync_values()` on the child and have a binding (set elsewhere) + on the parent update the value. This is used in `glvideomixer` and `glsinkbin` + for example, where `sync_values()` on the child pad or element will call + `sync_values()` on the exposed bin pad or element. + + Note that this doesn't solve GObject property forwarding, that must + be taken care of by the implementation manually or using GBinding. + +- `gst_base_parse_drain()` has been made public for subclasses to use. + +- `gst_base_sink_set_drop_out_of_segment()' can be used by subclasses to + prevent GstBaseSink from dropping buffers that fall outside of the segment. + +- [`gst_calculate_linear_regression()`][calc-lin-regression] is a new utility + function to calculate a linear regression. + +- [`gst_debug_get_stack_trace`][get-stack-trace] is an easy way to retrieve a + stack trace, which can be useful in tracer plugins. + +- allocators: the dmabuf allocator is now sub-classable, and there is a new + `GST_CAPS_FEATURE_MEMORY_DMABUF` define. + +- video decoder subclasses can use the newly-added function + `gst_video_decoder_allocate_output_frame_with_params()` to + pass a `GstBufferPoolAcquireParams` to the buffer pool for + each buffer allocation. + +- the video time code API has gained a dedicated [`GstVideoTimeCodeInterval`][timecode-interval] + type plus related API, including functions to add intervals to timecodes. + +- There is a new `libgstbadallocators-1.0` library in gst-plugins-bad, which + may go away again in future releases once the `GstPhysMemoryAllocator` + interface API has been validated by more users and was moved to + `libgstallocators-1.0` from gst-plugins-base. + +[timecode-interval]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideo.html#gst-video-time-code-interval-new +[buffer-iterate-meta-filtered]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstBuffer.html#gst-buffer-iterate-meta-filtered +[pad-task-get-state]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPad.html#gst-pad-task-get-state +[uri-get-fragment-table]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstUri.html#gst-uri-get-media-fragment-table +[print]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-print +[println]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-println +[printerr]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-printerr +[printerrln]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-printerrln +[get-array]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstStructure.html#gst-structure-get-array +[set-array]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstStructure.html#gst-structure-set-array +[get-list]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstStructure.html#gst-structure-get-list +[set-list]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstStructure.html#gst-structure-set-list +[dynamic-type]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstDynamicTypeFactory.html +[proxy-control-binding]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/gstreamer-libs-GstProxyControlBinding.html +[calc-lin-regression]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstUtils.html#gst-calculate-linear-regression +[get-stack-trace]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstUtils.html#gst-debug-get-stack-trace + +### GstPlayer + +New API has been added to: + + - get the number of audio/video/subtitle streams: + - `gst_player_media_info_get_number_of_streams()` + - `gst_player_media_info_get_number_of_video_streams()` + - `gst_player_media_info_get_number_of_audio_streams()` + - `gst_player_media_info_get_number_of_subtitle_streams()` + + - enable accurate seeking: `gst_player_config_set_seek_accurate()` + and `gst_player_config_get_seek_accurate()` + + - get a snapshot image of the video in RGBx, BGRx, JPEG, PNG or + native format: [`gst_player_get_video_snapshot()`][snapshot] + + - selecting use of a specific video sink element + ([`gst_player_video_overlay_video_renderer_new_with_sink()`][renderer-with-vsink]) + + - If the environment variable `GST_PLAYER_USE_PLAYBIN3` is set, GstPlayer will + use the still-experimental `playbin3` element and the `GstStreams` API for + playback. + +[snapshot]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-gstplayer.html#gst-player-get-video-snapshot +[renderer-with-vsink]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-gstplayer-videooverlayvideorenderer.html#gst-player-video-overlay-video-renderer-new-with-sink + +## Miscellaneous changes + +- video caps for interlaced video may contain an optional `"field-order"` field + now in the case of `interlaced-mode=interleaved` to signal that the field + order is always the same throughout the stream. This is useful to signal to + muxers such as mp4mux. The new field is parsed from/to `GstVideoInfo` of course. + +- video decoder and video encoder base classes try harder to proxy + interlacing, colorimetry and chroma-site related fields in caps properly. + +- The buffer stored in the `PROTECTION` events is now left unchanged. This is a + change of behaviour since 1.8, especially for the mssdemux element which used to + decode the base64 parsed data wrapped in the protection events emitted by the + demuxer. + +- `PROTECTION` events can now be injected into the pipeline from the application; + source elements deriving from GstBaseSrc will forward those downstream now. + +- The DASH demuxer is now correctly parsing the MSPR-2.0 ContentProtection nodes + and emits Protection events accordingly. Applications relying on those events + might need to decode the base64 data stored in the event buffer before using it. + +- The registry can now also be disabled by setting the environment variable + `GST_REGISTRY_DISABLE=yes`, with similar effect as the `GST_DISABLE_REGISTRY` + compile time switch. + +- Seeking performance with gstreamer-vaapi based decoders was improved. It would + recreate the decoder and surfaces on every seek which can be quite slow. + +- more robust handling of input caps changes in videoaggregator-based elements + such as `compositor`. + +- Lots of adaptive streaming-related fixes across the board (DASH, MSS, HLS). Also: + + - `mssdemux`, the Microsoft Smooth Streaming demuxer, has seen various + fixes for live streams, duration reporting and seeking. + + - The DASH manifest parser now extracts MS PlayReady ContentProtection objects + from manifests and sends them downstream as `PROTECTION` events. It also + supports multiple Period elements in external xml now. + +- gst-libav was updated to ffmpeg 3.3 but should still work with any 3.x + version. + +- GstEncodingProfile has been generally enhanced so it can, for + example, be used to get possible profiles for a given file + extension. It is now possible to define profiles based on element + factory names or using a path to a `.gep` file containing a + serialized profile. + +- `audioconvert` can now do endianness conversion in-place. All other + conversions still require a copy, but e.g. sign conversion and a few others + could also be implemented in-place now. + +- The new, experimental `playbin3` and `urisourcebin` elements got many + bugfixes and improvements and should generally be closer to a full + replacement of the old elements. + +- `interleave` now supports > 64 channels. + +### OpenGL integration + +- As usual the GStreamer OpenGL integration library has seen numerous + fixes and performance improvements all over the place, and is hopefully + ready now to become API stable and be moved to gst-plugins-base during the + 1.14 release cycle. + +- The GStreamer OpenGL integration layer has also gained support for the + Vivante EGL FB windowing system, which improves performance on platforms + such as Freescale iMX.6 for those who are stuck with the proprietary driver. + The `qmlglsink` element also supports this now if Qt is used with eglfs or + wayland backend, and it works in conjunction with [gstreamer-imx][gstreamer-imx] + of course. + +- various `qmlglsrc` improvements + +[gstreamer-imx]: https://github.com/Freescale/gstreamer-imx + +## Tracing framework and debugging improvements + +- New tracing hooks have been added to track GstMiniObject and GstObject + ref/unref operations. + +- The memory leaks tracer can optionally use this to retrieve stack traces if + enabled with e.g. `GST_TRACERS=leaks(filters="GstEvent,GstMessage",stack-traces-flags=full)` + +- The `GST_DEBUG_FILE` environment variable, which can be used to write the + debug log output to a file instead of printing it to stderr, can now contain + a name pattern, which is useful for automated testing and continuous + integration systems. The following format specifiers are supported: + + - `%p`: will be replaced with the PID + - `%r`: will be replaced with a random number, which is useful for instance + when running two processes with the same PID but in different containers. + +## Tools + +- `gst-inspect-1.0` can now list elements by type with the new `--types` + command-line option, e.g. `gst-inspect-1.0 --types=Audio/Encoder` will + show a list of audio encoders. + +- `gst-launch-1.0` and `gst_parse_launch()` have gained a new operator (`:`) + that allows linking all pads between two elements. This is useful in cases + where the exact number of pads or type of pads is not known beforehand, such + as in the `uridecodebin : encodebin` scenario, for example. In this case, + multiple links will be created if the encodebin has multiple profiles + compatible with the output of uridecodebin. + +- `gst-device-monitor-1.0` now shows a `gst-launch-1.0` snippet for each + device that shows how to make use of it in a `gst-launch-1.0` pipeline string. + +## GStreamer RTSP server + +- The RTSP server now also supports Digest authentication in addition to Basic + authentication. + +- The `GstRTSPClient` class has gained a `pre-*-request` signal and virtual + method for each client request type, emitted in the beginning of each rtsp + request. These signals or virtual methods let the application validate the + requests, configure the media/stream in a certain way and also generate error + status codes in case of an error or a bad request. + +## GStreamer VAAPI + +- GstVaapiDisplay now inherits from GstObject, thus the VA display logging + messages are better and tracing the context sharing is more readable. + +- When uploading raw images into a VA surfaces now VADeriveImages are tried + fist, improving the upload performance, if it is possible. + +- The decoders and the post-processor now can push dmabuf-based buffers to + downstream under certain conditions. For example: + + `GST_GL_PLATFORM=egl gst-play-1.0 video-sample.mkv --videosink=glimagesink` + +- Refactored the wrapping of VA surface into gstreamer memory, adding lock + when mapping and unmapping, and many other fixes. + +- Now `vaapidecodebin` loads `vaapipostproc` dynamically. It is possible to + avoid it usage with the environment variable `GST_VAAPI_DISABLE_VPP=1`. + +- Regarding encoders: they have primary rank again, since they can discover, + in run-time, the color formats they can use for upstream raw buffers and + caps renegotiation is now possible. Also the encoders push encoding info + downstream via tags. + +- About specific encoders: added constant bit-rate encoding mode for VP8 and + H265 encoder handles P010_10LE color format. + +- Regarding decoders, flush operation has been improved, now the internal VA + encoder is not recreated at each flush. Also there are several improvements + in the handling of H264 and H265 streams. + +- VAAPI plugins try to create their on GstGL context (when available) if they + cannot find it in the pipeline, to figure out what type of VA Display they + should create. + +- Regarding `vaapisink` for X11, if the backend reports that it is unable to + render correctly the current color format, an internal VA post-processor, is + instantiated (if available) and converts the color format. + +## GStreamer Editing Services and NLE + +- Enhanced auto transition behaviour + +- Fix some races in `nlecomposition` + +- Allow building with msvc + +- Added a UNIX manpage for `ges-launch` + +- API changes: + - Added ges_deinit (allowing the leak tracer to work properly) + - Added ges_layer_get_clips_in_interval + - Finally hide internal symbols that should never have been exposed + +## GStreamer validate + +- Port `gst-validate-launcher` to python 3 + +- `gst-validate-launcher` now checks if blacklisted bugs have been fixed on + bugzilla and errors out if it is the case + +- Allow building with msvc + +- Add ability for the launcher to run GStreamer unit tests + +- Added a way to activate the leaks tracer on our tests and fix leaks + +- Make the http server multithreaded + +- New testsuite for running various test scenarios on the DASH-IF test vectors + +## Build and Dependencies + +- Meson build files are now disted in tarballs, for jhbuild and so distro + packagers can start using it. Note that the Meson-based build system is not + 100% feature-equivalent with the autotools-based one yet. + +- Some plugin filenames have been changed to match the plugin names: for example + the file name of the `encoding` plugin in gst-plugins-base containing the + `encodebin` element was `libgstencodebin.so` and has been changed to + `libgstencodebin.so`. This affects only a handful of plugins across modules. + + **Developers who install GStreamer from source and just do `make install`** + **after updating the source code, without doing `make uninstall` first, will** + **have to manually remove the old installed plugin files from the installation** + **prefix, or they will get 'Cannot register existing type' critical warnings.** + +- Most of the docbook-based documentation (FAQ, Application Development Manual, + Plugin Writer's Guide, design documents) has been converted to markdown and + moved into a new gst-docs module. The gtk-doc library API references and + the plugins documentation are still built as part of the source modules though. + +- GStreamer core now optionally uses libunwind and libdw to generate backtraces. + This is useful for tracer plugins used during debugging and development. + +- There is a new `libgstbadallocators-1.0` library in gst-plugins-bad (which + may go away again in future releases once the `GstPhysMemoryAllocator` + interface API has been validated by more users). + +- `gst-omx` and `gstreamer-vaapi` modules can now also be built using the + Meson build system. + +- The `qtkitvideosrc` element for macOS was removed. The API is deprecated + since 10.9 and it wasn't shipped in the binaries since a few releases. + +## Platform-specific improvements + +### Android + +- androidmedia: add support for VP9 video decoding/encoding and Opus audio + decoding (where supported) + +### OS/X and iOS + +- `avfvideosrc`, which represents an iPhone camera or, on a Mac, a screencapture + session, so far allowed you to select an input device by device index only. + New API adds the ability to select the position (front or back facing) and + device-type (wide angle, telephoto, etc.). Furthermore, you can now also + specify the orientation (portrait, landscape, etc.) of the videostream. + +### Windows + +- `dx9screencapsrc` can now optionally also capture the cursor. + +## Contributors + +Aleix Conchillo Flaque, Alejandro G. Castro, Aleksandr Slobodeniuk, Alexandru +Băluț, Alex Ashley, Andre McCurdy, Andrew, Anton Eliasson, Antonio Ospite, +Arnaud Vrac, Arun Raghavan, Aurélien Zanelli, Axel Menzel, Benjamin Otte, +Branko Subasic, Brendan Shanks, Carl Karsten, Carlos Rafael Giani, ChangBok +Chae, Chris Bass, Christian Schaller, christophecvr, Claudio Saavedra, +Corentin Noël, Dag Gullberg, Daniel Garbanzo, Daniel Shahaf, David Evans, +David Schleef, David Warman, Dominique Leuenberger, Dongil Park, Douglas +Bagnall, Edgard Lima, Edward Hervey, Emeric Grange, Enrico Jorns, Enrique +Ocaña González, Evan Nemerson, Fabian Orccon, Fabien Dessenne, Fabrice Bellet, +Florent Thiéry, Florian Zwoch, Francisco Velazquez, Frédéric Dalleau, Garima +Gaur, Gaurav Gupta, George Kiagiadakis, Georg Lippitsch, Göran Jönsson, Graham +Leggett, Guillaume Desmottes, Gurkirpal Singh, Haihua Hu, Hanno Boeck, Havard +Graff, Heekyoung Seo, hoonhee.lee, Hyunjun Ko, Imre Eörs, Iñaki García +Etxebarria, Jagadish, Jagyum Koo, Jan Alexander Steffens (heftig), Jan +Schmidt, Jean-Christophe Trotin, Jochen Henneberg, Jonas Holmberg, Joris +Valette, Josep Torra, Juan Pablo Ugarte, Julien Isorce, Jürgen Sachs, Koop +Mast, Kseniia Vasilchuk, Lars Wendler, leigh123linux@googlemail.com, Luis de +Bethencourt, Lyon Wang, Marcin Kolny, Marinus Schraal, Mark Nauwelaerts, +Mathieu Duponchelle, Matthew Waters, Matt Staples, Michael Dutka, Michael +Olbrich, Michael Smith, Michael Tretter, Miguel París Díaz, namanyadav12, Neha +Arora, Nick Kallen, Nicola Murino, Nicolas Dechesne, Nicolas Dufresne, Nicolas +Huet, Nirbheek Chauhan, Ole André Vadla Ravnås, Olivier Crête, Patricia +Muscalu, Peter Korsgaard, Peter Seiderer, Petr Kulhavy, Philippe Normand, +Philippe Renon, Philipp Zabel, Rahul Bedarkar, Reynaldo H. Verdejo Pinochet, +Ricardo Ribalda Delgado, Rico Tzschichholz, Руслан Ижбулатов, Samuel Maroy, +Santiago Carot-Nemesio, Scott D Phillips, Sean DuBois, Sebastian Dröge, Sergey +Borovkov, Seungha Yang, shakin chou, Song Bing, Søren Juul, Sreerenj +Balachandran, Stefan Kost, Stefan Sauer, Stepan Salenikovich, Stian Selnes, +Stuart Weaver, suhas2go, Thiago Santos, Thibault Saunier, Thomas Bluemel, +Thomas Petazzoni, Tim-Philipp Müller, Ting-Wei Lan, Tobias Mueller, Todor +Tomov, Tomasz Zajac, Ulf Olsson, Ursula Maplehurst, Víctor Manuel Jáquez Leal, +Victor Toso, Vincent Penquerc'h, Vineeth TM, Vinod Kesti, Vitor Massaru Iha, +Vivia Nikolaidou, WeiChungChang, William Manley, Wim Taymans, Wojciech +Przybyl, Wonchul Lee, Xavier Claessens, Yasushi SHOJI + +... and many others who have contributed bug reports, translations, sent +suggestions or helped testing. + +## Bugs fixed in 1.12 + +More than [635 bugs][bugs-fixed-in-1.12] have been fixed during +the development of 1.12. + +This list does not include issues that have been cherry-picked into the +stable 1.10 branch and fixed there as well, all fixes that ended up in the +1.10 branch are also included in 1.12. + +This list also does not include issues that have been fixed without a bug +report in bugzilla, so the actual number of fixes is much higher. + +[bugs-fixed-in-1.12]: https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&classification=Platform&limit=0&list_id=213265&order=bug_id&product=GStreamer&query_format=advanced&resolution=FIXED&target_milestone=1.10.1&target_milestone=1.10.2&target_milestone=1.10.3&target_milestone=1.10.4&target_milestone=1.11.1&target_milestone=1.11.2&target_milestone=1.11.3&target_milestone=1.11.4&target_milestone=1.11.90&target_milestone=1.11.91&target_milestone=1.12.0 + +## Stable 1.12 branch + +After the 1.12.0 release there will be several 1.12.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.12.x bug-fix releases will be made from the git 1.12 branch, which +is a stable branch. + +### 1.12.0 + +1.12.0 was released on 4th May 2017. + +## Known Issues + +- The `webrtcdsp` element is currently not shipped as part of the Windows + binary packages due to a [build system issue][bug-770264]. + +[bug-770264]: https://bugzilla.gnome.org/show_bug.cgi?id=770264 + +## Schedule for 1.14 + +Our next major feature release will be 1.14, and 1.11 will be the unstable +development version leading up to the stable 1.12 release. The development +of 1.13/1.14 will happen in the git master branch. + +The plan for the 1.14 development cycle is yet to be confirmed, but it is +expected that feature freeze will be around September 2017 +followed by several 1.13 pre-releases and the new 1.14 stable release +in October. + +1.14 will be backwards-compatible to the stable 1.12, 1.10, 1.8, 1.6, 1.4, +1.2 and 1.0 release series. + +- - - + +*These release notes have been prepared by Sebastian Dröge, Tim-Philipp Müller +and Víctor Manuel Jáquez Leal.* + +*License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)* diff --git a/configure.ac b/configure.ac index 312815910b..90473cb0b9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [11]) -m4_define([gst_vaapi_micro_version], [91]) +m4_define([gst_vaapi_minor_version], [12]) +m4_define([gst_vaapi_micro_version], [0]) m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1191]) +m4_define([gst_vaapi_lt_current], [1200]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1191]) +m4_define([gst_vaapi_lt_age], [1200]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.11.91]) -m4_define([gst_plugins_base_version], [1.11.91]) -m4_define([gst_plugins_bad_version], [1.11.91]) +m4_define([gst_version], [1.12.0]) +m4_define([gst_plugins_base_version], [1.12.0]) +m4_define([gst_plugins_bad_version], [1.12.0]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index bfbfab3172..e30da6dee7 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.12.0 + master + + 2017-05-04 + + + + 1.11.91 diff --git a/meson.build b/meson.build index 70f0bbeb91..f42c632558 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.11.91', + version : '1.12.0', meson_version : '>= 0.36.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 10eb6efb30c0fde968ba0bacdd032219a2c485be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 4 May 2017 18:59:31 +0300 Subject: [PATCH 2762/3781] Back to development --- configure.ac | 14 +++++++------- meson.build | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 90473cb0b9..340b4649d0 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [12]) +m4_define([gst_vaapi_minor_version], [13]) m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1200]) +m4_define([gst_vaapi_lt_current], [1300]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1200]) +m4_define([gst_vaapi_lt_age], [1300]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.12.0]) -m4_define([gst_plugins_base_version], [1.12.0]) -m4_define([gst_plugins_bad_version], [1.12.0]) +m4_define([gst_version], [1.13.0.1]) +m4_define([gst_plugins_base_version], [1.13.0.1]) +m4_define([gst_plugins_bad_version], [1.13.0.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/meson.build b/meson.build index f42c632558..13a72717cf 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.12.0', + version : '1.13.0.1', meson_version : '>= 0.36.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 4f343f82e3e9051b3d5759290c1a9aa418d8559d Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 19 Apr 2017 13:04:44 -0700 Subject: [PATCH 2763/3781] encoders: add quality level tuning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds the handling of VAEncMiscParameterTypeQualityLevel, in gstreamer-vaapi encoders: The encoding quality could be set through this structure, if the implementation supports multiple quality levels. The quality level set through this structure is persistent over the entire coded sequence, or until a new structure is being sent. The quality level range can be queried through the VAConfigAttribEncQualityRange attribute. A lower value means higher quality, and a value of 1 represents the highest quality. The quality level setting is used as a trade-off between quality and speed/power consumption, with higher quality corresponds to lower speed and higher power consumption. The quality level is set by the element's parameter "quality-level" with a hard-coded range of 1 to 8. Later, when the encoder is configured in run time, just before start processing, the quality level is scaled to the codec range. If VAConfigAttribEncQualityRange is not available in the used VA backend, then the quality level is set to zero, which means "disabled". All the available codecs now process this parameter if it is available. https://bugzilla.gnome.org/show_bug.cgi?id=778733 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiencoder.c | 87 +++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiencoder.h | 5 ++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 5 ++ gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 3 + gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 3 + gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 6 ++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 17 ++++ gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 2 + gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 12 +++ 9 files changed, 139 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 0a87c1b32f..6727cbb959 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -169,9 +169,44 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) cdata->encoder_tune_get_type (), cdata->default_encoder_tune, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoder:quality-level: + * + * The Encoding quality level. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_PROP_QUALITY_LEVEL, + g_param_spec_uint ("quality-level", + "Quality Level", + "Encoding Quality Level ", 1, 8, + 4, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } +gboolean +gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncMiscParam *misc; + VAEncMiscParameterBufferQualityLevel *quality_level; + + /* quality level param is not supported */ + if (GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder) == 0) + return TRUE; + + misc = GST_VAAPI_ENC_QUALITY_LEVEL_MISC_PARAM_NEW (encoder); + if (!misc) + return FALSE; + quality_level = misc->data; + memset (quality_level, 0, sizeof (VAEncMiscParameterBufferQualityLevel)); + quality_level->quality_level = encoder->quality_level; + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + return TRUE; +} + /** * gst_vaapi_encoder_ref: * @encoder: a #GstVaapiEncoder @@ -686,7 +721,7 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); GstVaapiEncoderStatus status; GstVaapiVideoPool *pool; - guint codedbuf_size; + guint codedbuf_size, quality_level_max = 0; /* Generate a keyframe every second */ if (!encoder->keyframe_period) @@ -699,6 +734,16 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) if (!gst_vaapi_encoder_ensure_context (encoder)) goto error_reset_context; + if (get_config_attribute (encoder, VAConfigAttribEncQualityRange, + &quality_level_max) && quality_level_max > 0) { + encoder->quality_level = + gst_util_uint64_scale_int_ceil (encoder->quality_level, + quality_level_max, 8); + } else { + encoder->quality_level = 0; + } + GST_INFO ("Quality level is fixed to %d", encoder->quality_level); + codedbuf_size = encoder->codedbuf_pool ? gst_vaapi_coded_buffer_pool_get_buffer_size (GST_VAAPI_CODED_BUFFER_POOL (encoder)) : 0; @@ -810,6 +855,10 @@ set_property (GstVaapiEncoder * encoder, gint prop_id, const GValue * value) case GST_VAAPI_ENCODER_PROP_TUNE: status = gst_vaapi_encoder_set_tuning (encoder, g_value_get_enum (value)); break; + case GST_VAAPI_ENCODER_PROP_QUALITY_LEVEL: + status = gst_vaapi_encoder_set_quality_level (encoder, + g_value_get_uint (value)); + break; } return status; @@ -1035,6 +1084,42 @@ error_operation_failed: } } +/** + * gst_vaapi_encoder_set_quality_level: + * @encoder: a #GstVaapiEncoder + * @quality_level: the encoder quality level + * + * Notifies the @encoder to use the supplied @quality_level value. + * + * Note: currently, the quality_level can only be specified before + * the last call to gst_vaapi_encoder_set_codec_state(), which shall + * occur before the first frame is encoded. Afterwards, any change to + * this parameter causes gst_vaapi_encoder_set_quality_level() to + * return @GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED. + * + * Return value: a #GstVaapiEncoderStatus + */ +GstVaapiEncoderStatus +gst_vaapi_encoder_set_quality_level (GstVaapiEncoder * encoder, + guint quality_level) +{ + g_return_val_if_fail (encoder != NULL, 0); + + if (encoder->quality_level != quality_level + && encoder->num_codedbuf_queued > 0) + goto error_operation_failed; + + encoder->quality_level = quality_level; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +error_operation_failed: + { + GST_ERROR ("could not change quality level after encoding started"); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } +} + /* Initialize default values for configurable properties */ static gboolean gst_vaapi_encoder_init_properties (GstVaapiEncoder * encoder) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 1c7cd4737b..7d1ebe4eca 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -108,6 +108,7 @@ typedef enum { GST_VAAPI_ENCODER_PROP_BITRATE, GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, GST_VAAPI_ENCODER_PROP_TUNE, + GST_VAAPI_ENCODER_PROP_QUALITY_LEVEL } GstVaapiEncoderProp; /** @@ -166,6 +167,10 @@ 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_get_buffer_with_timeout (GstVaapiEncoder * encoder, GstVaapiCodedBufferProxy ** out_codedbuf_proxy_ptr, guint64 timeout); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 16e5b43861..dc96b646bf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2157,6 +2157,7 @@ error_create_packed_seq_hdr: static gboolean ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncMiscParam *misc = NULL; VAEncMiscParameterRateControl *rate_control; @@ -2204,6 +2205,10 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) } } + + if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) + return FALSE; + return TRUE; error_create_packed_sei_hdr: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index f49121ce2b..ba05563268 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1765,6 +1765,7 @@ error_create_packed_seq_hdr: static gboolean ensure_misc_params (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncMiscParam *misc = NULL; /* HRD params for rate control */ @@ -1778,6 +1779,8 @@ ensure_misc_params (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) gst_vaapi_codec_object_replace (&misc, NULL); } + if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) + return FALSE; return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index ccb495d712..251b9a5ce0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -496,6 +496,9 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, rate_control->basic_unit_size = 0; gst_vaapi_codec_object_replace (&misc, NULL); } + + if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) + return FALSE; return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index 6e8945cd9f..90c31e004f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -319,6 +319,12 @@ gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture); G_PASTE (VAEncMiscParameterType, type), \ sizeof (G_PASTE (VAEncMiscParameter, type))) +/* GstVaapiEncFeiMiscParam */ +#define GST_VAAPI_ENC_QUALITY_LEVEL_MISC_PARAM_NEW(encoder) \ + gst_vaapi_enc_misc_param_new (GST_VAAPI_ENCODER_CAST (encoder), \ + VAEncMiscParameterTypeQualityLevel, \ + sizeof (VAEncMiscParameterBufferQualityLevel)) + /* GstVaapiEncPicture */ #define GST_VAAPI_ENC_PICTURE_NEW(codec, encoder, frame) \ gst_vaapi_enc_picture_new (GST_VAAPI_ENCODER_CAST (encoder), \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 5cf748a7e2..a80ba76fb2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -164,6 +164,17 @@ G_BEGIN_DECLS #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)->quality_level) + /* Generate a mask for the supplied tuning option (internal) */ #define GST_VAAPI_ENCODER_TUNE_MASK(TUNE) \ (1U << G_PASTE (GST_VAAPI_ENCODER_TUNE_, TUNE)) @@ -216,6 +227,7 @@ struct _GstVaapiEncoder guint32 rate_control_mask; guint bitrate; /* kbps */ guint keyframe_period; + guint quality_level; GMutex mutex; GCond surface_free; @@ -340,6 +352,11 @@ gst_vaapi_encoder_release_surface (GstVaapiEncoder * encoder, gst_vaapi_surface_proxy_unref (proxy); } +G_GNUC_INTERNAL +gboolean +gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder, + GstVaapiEncPicture * picture); + G_END_DECLS #endif /* GST_VAAPI_ENCODER_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 56a19438a3..9ced12bb23 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -313,6 +313,8 @@ ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); + if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) + return FALSE; return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index b9af78551c..437ce16e24 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -215,6 +215,16 @@ error: } } +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; + 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) @@ -359,6 +369,8 @@ gst_vaapi_encoder_vp9_encode (GstVaapiEncoder * base_encoder, 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)) From 4269adf791526a68a6e885750b8e6a4c5e3fefb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 11 May 2017 12:23:28 +0200 Subject: [PATCH 2764/3781] libs: encoder: guard quality level configuration The quality level appeared in VA-API 0.36. So let's guard its usage. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 6727cbb959..90978d19bf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -188,6 +188,7 @@ gboolean gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder, GstVaapiEncPicture * picture) { +#if VA_CHECK_VERSION(0,36,0) GstVaapiEncMiscParam *misc; VAEncMiscParameterBufferQualityLevel *quality_level; @@ -203,7 +204,7 @@ gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder, quality_level->quality_level = encoder->quality_level; gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); - +#endif return TRUE; } @@ -734,6 +735,7 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) if (!gst_vaapi_encoder_ensure_context (encoder)) goto error_reset_context; +#if VA_CHECK_VERSION(0,36,0) if (get_config_attribute (encoder, VAConfigAttribEncQualityRange, &quality_level_max) && quality_level_max > 0) { encoder->quality_level = @@ -743,6 +745,7 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) encoder->quality_level = 0; } GST_INFO ("Quality level is fixed to %d", encoder->quality_level); +#endif codedbuf_size = encoder->codedbuf_pool ? gst_vaapi_coded_buffer_pool_get_buffer_size (GST_VAAPI_CODED_BUFFER_POOL From 3ec7996d75155999cabc2d5d7b513012062dfa64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 12 May 2017 11:11:48 +0200 Subject: [PATCH 2765/3781] libs: encoder: fix a comment --- gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index 90c31e004f..8ca594679a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -319,7 +319,7 @@ gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture); G_PASTE (VAEncMiscParameterType, type), \ sizeof (G_PASTE (VAEncMiscParameter, type))) -/* GstVaapiEncFeiMiscParam */ +/* GstVaapiEncQualityLevelMiscParam */ #define GST_VAAPI_ENC_QUALITY_LEVEL_MISC_PARAM_NEW(encoder) \ gst_vaapi_enc_misc_param_new (GST_VAAPI_ENCODER_CAST (encoder), \ VAEncMiscParameterTypeQualityLevel, \ From b41d72b7c50b8e69f44525d34e704af447678e27 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 23 Feb 2017 17:57:07 +0900 Subject: [PATCH 2766/3781] libs: encoder/context: query region of interest support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Queries if the driver supports "Region of Interest" (ROI) during the config creation. This attribute conveys whether the driver supports region-of-interest (ROI) encoding, based on user provided ROI rectangles. The attribute value is partitioned into fields as defined in the VAConfigAttribValEncROI union. If ROI encoding is supported, the ROI information is passed to the driver using VAEncMiscParameterTypeROI. https://bugzilla.gnome.org/show_bug.cgi?id=768248 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapicontext.c | 30 +++++++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapicontext.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder.c | 29 +++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 9a3e0abd45..52d81e207f 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -229,7 +229,7 @@ config_create (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); - VAConfigAttrib attribs[3], *attrib = attribs; + VAConfigAttrib attribs[4], *attrib = attribs; VAStatus status; guint value, va_chroma_format; @@ -299,6 +299,26 @@ config_create (GstVaapiContext * context) attrib->value = value; attrib++; } +#endif +#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 || + roi_config->bits.roi_rc_qp_delat_support == 0) { + GST_ERROR ("ROI unsupported - number of regions supported: %d" + " ROI delta QP: %d", roi_config->bits.num_roi_regions, + roi_config->bits.roi_rc_qp_delat_support); + goto cleanup; + } + attrib->value = value; + attrib++; + } #endif break; } @@ -340,6 +360,14 @@ context_update_config_encoder (GstVaapiContext * context, 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; } diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 030419e131..0f91eb37f4 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -67,6 +67,8 @@ struct _GstVaapiConfigInfoEncoder { GstVaapiRateControl rc_mode; guint packed_headers; + gboolean roi_capability; + guint roi_num_supported; }; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 90978d19bf..ef90c87118 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -592,6 +592,32 @@ get_packed_headers (GstVaapiEncoder * encoder) return encoder->packed_headers; } +static gboolean +get_roi_capability (GstVaapiEncoder * encoder, guint * num_roi_supported) +{ +#if VA_CHECK_VERSION(0,39,1) + VAConfigAttribValEncROI *roi_config; + guint value; + + if (!get_config_attribute (encoder, VAConfigAttribEncROI, &value)) + return FALSE; + + roi_config = (VAConfigAttribValEncROI *) & value; + + if (roi_config->bits.num_roi_regions == 0 || + roi_config->bits.roi_rc_qp_delat_support == 0) + return FALSE; + + GST_INFO ("Support for ROI - number of regions supported: %d", + roi_config->bits.num_roi_regions); + + *num_roi_supported = roi_config->bits.num_roi_regions; + return TRUE; +#else + return FALSE; +#endif +} + static inline gboolean is_chroma_type_supported (GstVaapiEncoder * encoder) { @@ -682,6 +708,9 @@ set_context_info (GstVaapiEncoder * encoder) memset (config, 0, sizeof (*config)); config->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); config->packed_headers = get_packed_headers (encoder); + config->roi_capability = + get_roi_capability (encoder, &config->roi_num_supported); + return TRUE; /* ERRORS */ From 7a6f690340dcb3b82c59efa777d4453227851de8 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 28 Mar 2017 17:41:37 +0900 Subject: [PATCH 2767/3781] libs: encoder: add api gst_vaapi_encoder_add/del_roi Implements and exposes new api gst_vaapi_encoder_add/del_roi to set ROI regions. https://bugzilla.gnome.org/show_bug.cgi?id=768248 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 108 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 12 +++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 3 + 3 files changed, 123 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index ef90c87118..c4a2e08b79 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1235,6 +1235,9 @@ gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) klass->finalize (encoder); + if (encoder->roi_regions) + g_list_free_full (encoder->roi_regions, g_free); + gst_vaapi_object_replace (&encoder->context, NULL); gst_vaapi_display_replace (&encoder->display, NULL); encoder->va_display = NULL; @@ -1383,6 +1386,111 @@ gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, return formats; } +/** + * gst_vaapi_encoder_add_roi: + * @encoder: a #GstVaapiEncoder + * @roi: (transfer none): a #GstVaapiROI + * + * Adds a roi region provided by user. + * + * This can be called on running a pipeline, + * Since vaapi encoder set roi regions at every frame encoding. + * Note that if it exceeds number of supported roi in driver, + * this will return FALSE. + * + * Return value: a #gboolean + */ +gboolean +gst_vaapi_encoder_add_roi (GstVaapiEncoder * encoder, GstVaapiROI * roi) +{ + GstVaapiContextInfo *const cip = &encoder->context_info; + const GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; + GstVaapiROI *region = NULL; + GList *walk; + + g_return_val_if_fail (roi != NULL, FALSE); + + if (!config->roi_capability) + return FALSE; + + if (encoder->roi_regions && + g_list_length (encoder->roi_regions) > config->roi_num_supported) + return FALSE; + + walk = encoder->roi_regions; + while (walk) { + GstVaapiROI *region_ptr = (GstVaapiROI *) walk->data; + if (region_ptr->rect.x == roi->rect.x && + region_ptr->rect.y == roi->rect.y && + region_ptr->rect.width == roi->rect.width && + region_ptr->rect.height == roi->rect.height) { + /* Duplicated region */ + goto end; + } + walk = walk->next; + } + + region = g_malloc0 (sizeof (GstVaapiROI)); + if (G_UNLIKELY (!region)) + return FALSE; + + region->rect.x = roi->rect.x; + region->rect.y = roi->rect.y; + region->rect.width = roi->rect.width; + region->rect.height = roi->rect.height; + + encoder->roi_regions = g_list_append (encoder->roi_regions, region); + +end: + return TRUE; +} + +/** + * gst_vaapi_encoder_del_roi: + * @encoder: a #GstVaapiEncoder + * @roi: (transfer none): a #GstVaapiROI + * + * Deletes a roi region provided by user. + * + * This can be called on running a pipeline, + * Since vaapi encoder set roi regions at every frame encoding. + * + * Return value: a #gboolean + */ +gboolean +gst_vaapi_encoder_del_roi (GstVaapiEncoder * encoder, GstVaapiROI * roi) +{ + GstVaapiContextInfo *const cip = &encoder->context_info; + const GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; + GList *walk; + gboolean ret = FALSE; + + g_return_val_if_fail (roi != NULL, FALSE); + + if (!config->roi_capability) + return FALSE; + + if (encoder->roi_regions && g_list_length (encoder->roi_regions) == 0) + return FALSE; + + walk = encoder->roi_regions; + while (walk) { + GstVaapiROI *region = (GstVaapiROI *) walk->data; + if (region->rect.x == roi->rect.x && + region->rect.y == roi->rect.y && + region->rect.width == roi->rect.width && + region->rect.height == roi->rect.height) { + encoder->roi_regions = g_list_remove (encoder->roi_regions, region); + g_free (region); + ret = TRUE; + break; + } + walk = walk->next; + } + + return ret; +} + /** Returns a GType for the #GstVaapiEncoderTune set */ GType gst_vaapi_encoder_tune_get_type (void) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 7d1ebe4eca..e3627ac2cc 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -123,6 +123,11 @@ typedef struct { GParamSpec *const pspec; } GstVaapiEncoderPropInfo; +typedef struct _GstVaapiROI { + gint roi_value; + GstVaapiRectangle rect; +} GstVaapiROI; + GType gst_vaapi_encoder_tune_get_type (void) G_GNUC_CONST; @@ -181,6 +186,13 @@ gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); GArray * gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile); + +gboolean +gst_vaapi_encoder_add_roi (GstVaapiEncoder * encoder, GstVaapiROI * roi); + +gboolean +gst_vaapi_encoder_del_roi (GstVaapiEncoder * encoder, GstVaapiROI * roi); + G_END_DECLS #endif /* GST_VAAPI_ENCODER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index a80ba76fb2..d01ed73648 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -239,6 +239,9 @@ struct _GstVaapiEncoder guint got_packed_headers:1; guint got_rate_control_mask:1; + + /* Region of Interest */ + GList *roi_regions; }; struct _GstVaapiEncoderClassData From f3302a0a7935da2f120c9ec2785648c8a763dd5a Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 23 Feb 2017 18:52:48 +0900 Subject: [PATCH 2768/3781] libs: encoder: h264: set ROI params during encoding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set ROI params during encoding each frame, which are set via gst_vaapi_encoder_add_roi () https://bugzilla.gnome.org/show_bug.cgi?id=768248 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 44 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index dc96b646bf..b53127778f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2160,6 +2160,7 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncMiscParam *misc = NULL; VAEncMiscParameterRateControl *rate_control; + guint num_roi; /* HRD params */ misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); @@ -2203,9 +2204,50 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) GST_VAAPI_H264_SEI_PIC_TIMING)) goto error_create_packed_sei_hdr; } - } + /* region-of-interest params */ + num_roi = base_encoder->roi_regions ? + g_list_length (base_encoder->roi_regions) : 0; +#if VA_CHECK_VERSION(0,39,1) + if (num_roi > 0) { + /* ROI(Region of Interest) params */ + VAEncMiscParameterBufferROI *roi_param; + VAEncROI *region_roi; + gpointer ptr; + GList *tmp; + + misc = + gst_vaapi_enc_misc_param_new (base_encoder, VAEncMiscParameterTypeROI, + sizeof (VAEncMiscParameterBufferROI) + num_roi * sizeof (VAEncROI)); + + roi_param = misc->data; + roi_param->roi_flags.bits.roi_value_is_qp_delta = 1; + roi_param->max_delta_qp = 10; + roi_param->min_delta_qp = 10; + + ptr = (guchar *) misc->param + sizeof (VAEncMiscParameterBuffer) + + sizeof (VAEncMiscParameterBufferROI); + region_roi = ptr; + + for (tmp = base_encoder->roi_regions; tmp; tmp = tmp->next) { + GstVaapiROI *item = tmp->data; + region_roi->roi_value = item->roi_value; + region_roi->roi_rectangle.x = item->rect.x; + region_roi->roi_rectangle.y = item->rect.y; + region_roi->roi_rectangle.width = item->rect.width; + region_roi->roi_rectangle.height = item->rect.height; + region_roi++; + } + + roi_param->roi = ptr; + roi_param->num_roi = num_roi; + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + } +#endif + if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) return FALSE; From c21345c4787bb6342adddea1190f53fe62abff04 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 23 Feb 2017 18:53:18 +0900 Subject: [PATCH 2769/3781] tests: simple-encoder: add an option to set ROI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $ simple-encoder -r inputfile.y4m And you'll got an output file in H264 with two regions of interest. https://bugzilla.gnome.org/show_bug.cgi?id=768248 Signed-off-by: Víctor Manuel Jáquez Leal --- tests/simple-encoder.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/simple-encoder.c b/tests/simple-encoder.c index 58b0e8c214..a404e9a259 100644 --- a/tests/simple-encoder.c +++ b/tests/simple-encoder.c @@ -32,6 +32,7 @@ static guint g_bitrate = 0; static gchar *g_codec_str; static gchar *g_output_file_name; static char **g_input_files = NULL; +static gboolean g_roi_enable = FALSE; #define SURFACE_NUM 16 @@ -42,6 +43,8 @@ static GOptionEntry g_options[] = { "desired bitrate expressed in kbps", NULL}, {"output", 'o', 0, G_OPTION_ARG_FILENAME, &g_output_file_name, "output file name", NULL}, + {"roi", 'r', 0, G_OPTION_ARG_NONE, &g_roi_enable, + "enable region of interest", NULL}, {G_OPTION_REMAINING, ' ', 0, G_OPTION_ARG_FILENAME_ARRAY, &g_input_files, "input file name", NULL}, {NULL} @@ -58,6 +61,7 @@ typedef struct FILE *output_file; guint input_stopped:1; guint encode_failed:1; + GstVaapiROI roi_region[2]; } App; static inline gchar * @@ -180,6 +184,35 @@ set_format (GstVaapiEncoder * encoder, gint width, gint height, gint fps_n, return (status == GST_VAAPI_ENCODER_STATUS_SUCCESS); } +static void +add_roi (App * app) +{ + guint i; + gint width, height; + + width = app->parser->width; + height = app->parser->height; + + for (i = 0; i < 2; i++) { + app->roi_region[i].roi_value = 4; + app->roi_region[i].rect.x = i * width / 2; + app->roi_region[i].rect.y = i * height / 2; + app->roi_region[i].rect.width = width / 4; + app->roi_region[i].rect.height = height / 4; + + gst_vaapi_encoder_add_roi (app->encoder, &app->roi_region[i]); + } +} + +static void +del_roi (App * app) +{ + guint i; + + for (i = 0; i < 2; i++) + gst_vaapi_encoder_del_roi (app->encoder, &app->roi_region[i]); +} + static GstBuffer * allocate_buffer (GstVaapiCodedBuffer * vbuf) { @@ -293,6 +326,9 @@ app_free (App * app) { g_return_if_fail (app); + if (g_roi_enable) + del_roi (app); + if (app->parser) y4m_reader_close (app->parser); @@ -348,6 +384,9 @@ app_new (const gchar * input_fn, const gchar * output_fn) goto error; } + if (g_roi_enable) + add_roi (app); + return app; error: From 8f1b88dac0e64a211325cdcb2cda693b80229bd1 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 30 Mar 2017 17:54:20 +0900 Subject: [PATCH 2770/3781] vaapiencode: handle custom event GstVaapiEncoderRegionOfInterest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handles new custom event GstVaapiEncoderRegionOfInterest to enable/disable a ROI region. Writes a way to use new event to document. https://bugzilla.gnome.org/show_bug.cgi?id=768248 Signed-off-by: Víctor Manuel Jáquez Leal --- gst/vaapi/gstvaapiencode.c | 39 +++++++++++++++++ gst/vaapi/gstvaapiencode_h264.c | 74 +++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 12d634de3a..fc8cf6e02a 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -739,6 +739,45 @@ gst_vaapiencode_sink_event (GstVideoEncoder * venc, GstEvent * event) GstPad *const srcpad = GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode); gboolean ret; + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CUSTOM_DOWNSTREAM:{ + const GstStructure *s = gst_event_get_structure (event); + if (gst_structure_has_name (s, "GstVaapiEncoderRegionOfInterest")) { + GstVaapiROI roi; + + if (!encode->encoder) + return TRUE; + + if (!gst_structure_get_uint (s, "roi-x", &roi.rect.x) || + !gst_structure_get_uint (s, "roi-y", &roi.rect.y) || + !gst_structure_get_uint (s, "roi-width", &roi.rect.width) || + !gst_structure_get_uint (s, "roi-height", &roi.rect.height) || + !gst_structure_get_int (s, "roi-value", &roi.roi_value)) { + return TRUE; + } + + if (roi.roi_value == 0) { + ret = gst_vaapi_encoder_del_roi (encode->encoder, &roi); + if (ret) { + GST_INFO_OBJECT (venc, "ROI: region with %d/%d/%d/%d is removed", + roi.rect.x, roi.rect.y, roi.rect.width, roi.rect.height); + } + } else { + ret = gst_vaapi_encoder_add_roi (encode->encoder, &roi); + if (ret) { + GST_INFO_OBJECT (venc, "ROI: region with %d/%d/%d/%d is added", + roi.rect.x, roi.rect.y, roi.rect.width, roi.rect.height); + } + } + gst_event_unref (event); + return ret; + } + break; + } + default: + break; + } + ret = GST_VIDEO_ENCODER_CLASS (gst_vaapiencode_parent_class)->sink_event (venc, event); if (!ret) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 074274524b..3f7db3e589 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -33,6 +33,80 @@ * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapih264enc ! h264parse ! mp4mux ! filesink location=test.mp4 * ]| * + * + * + * Region of Interest + * Since libva supports Region Of Interest for avc encoding depending on H/W, + * GStreamer VA-API supports it by #GstEvent. + * To enable ROI, an application must send an event of type GST_EVENT_CUSTOM_DOWNSTREAM, + * having a structure of name "GstVaapiEncoderRegionOfInterest" with fields set + * according to the following table: + * + * + * + * + * + * + * + * + * Name + * GType + * Description + * + * + * + * + * roi-value + * G_TYPE_INT + * specifies ROI delta QP or ROI priority. + * ROI delta QP is the value that will be added on top of the frame level QP. + * ROI priority specifies the priority of a region, it can be positive (more important) + * or negative (less important) values and is compared with non-ROI region (taken as value 0), + * + * + * + * + * roi-x + * G_TYPE_UINT + * X + * + * + * roi-y + * G_TYPE_UINT + * Y + * + * + * roi-width + * G_TYPE_UINT + * width + * + * + * roi-height + * G_TYPE_UINT + * height + * + * + * + * + * + * For example, the following code informs the encoder to enable ROI + * with a region for ROI. + * Note that if an application wants to disable the region, + * just send an event with roi-value=0 and same coordination. + * + * + * GstEvent *event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, + * gst_structure_new ("GstVaapiEncoderRegionOfInterest", + * "roi-x", G_TYPE_UINT, 1820, + * "roi-y", G_TYPE_UINT, 980, + * "roi-width", G_TYPE_UINT, 100, + * "roi-height", G_TYPE_UINT, 100, + * "roi-value", G_TYPE_INT, 4, NULL)); + * + * gst_element_send_event (pipeline, event); + * + * + * */ #include "gstcompat.h" From eb17b711b62a019caf842622685f19213eae084a Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 30 Mar 2017 17:57:42 +0900 Subject: [PATCH 2771/3781] tests: elements: add an example for ROI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This implements a pipleint to recognize difference between ROI and non-ROI. See comments in this code in detail. https://bugzilla.gnome.org/show_bug.cgi?id=768248 Signed-off-by: Víctor Manuel Jáquez Leal --- tests/elements/Makefile.am | 5 + tests/elements/test-roi.c | 187 +++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 tests/elements/test-roi.c diff --git a/tests/elements/Makefile.am b/tests/elements/Makefile.am index 93b30c8ecf..822f8e725d 100644 --- a/tests/elements/Makefile.am +++ b/tests/elements/Makefile.am @@ -1,5 +1,6 @@ noinst_PROGRAMS = \ test-vaapisink \ + test-roi \ $(NULL) TEST_CFLAGS = \ @@ -17,4 +18,8 @@ test_vaapisink_SOURCES = test-vaapisink.c test_vaapisink_CFLAGS = $(TEST_CFLAGS) test_vaapisink_LDADD = $(TEST_LIBS) +test_roi_SOURCES = test-roi.c +test_roi_CFLAGS = $(TEST_CFLAGS) +test_roi_LDADD = $(TEST_LIBS) + -include $(top_srcdir)/git.mk diff --git a/tests/elements/test-roi.c b/tests/elements/test-roi.c new file mode 100644 index 0000000000..2818a10e5f --- /dev/null +++ b/tests/elements/test-roi.c @@ -0,0 +1,187 @@ +/* + * test-roi.c - Testsuite for Region of Interest + * + * Copyright (C) 2017 Intel Corporation + * + * 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 +#include +#include + +typedef struct _CustomData +{ + GstElement *pipeline; + GstPad *src_pad; + GMainLoop *loop; +} AppData; + +static void +send_roi_event (AppData * data) +{ + gboolean res = FALSE; + GstEvent *event; + gint value[2] = { 4, 0 }; + static gint counter = 0; + + event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, + gst_structure_new ("GstVaapiEncoderRegionOfInterest", + "roi-x", G_TYPE_UINT, 0, + "roi-y", G_TYPE_UINT, 0, + "roi-width", G_TYPE_UINT, 320, + "roi-height", G_TYPE_UINT, 240, + "roi-value", G_TYPE_INT, value[counter++ % 2], NULL)); + + /* Send the event */ + res = gst_pad_push_event (data->src_pad, event); + g_print ("Sending event %p done: %d\n", event, res); +} + +static void +send_eos_event (AppData * data) +{ + GstBus *bus; + GstMessage *msg; + + bus = gst_element_get_bus (data->pipeline); + gst_element_send_event (data->pipeline, gst_event_new_eos ()); + msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS); + + gst_message_unref (msg); + gst_object_unref (bus); +} + +/* Process keyboard input */ +static gboolean +handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data) +{ + gchar *str = NULL; + + if (g_io_channel_read_line (source, &str, NULL, NULL, + NULL) != G_IO_STATUS_NORMAL) { + return TRUE; + } + + switch (g_ascii_tolower (str[0])) { + case 'r': + send_roi_event (data); + break; + case 'q': + send_eos_event (data); + g_main_loop_quit (data->loop); + break; + default: + break; + } + + g_free (str); + + return TRUE; +} + +/* + * This is an example pipeline to recognize difference between ROI and non-ROI. + * 1. Produce snow pattern with 320p + * 2. Encode and decode the raw data with 2 pipelines at same time. + * 2.1. Inject a GstCustomEvent to the 2nd pipeline to enable ROI. + * 3. Mix both streams in videomixer. + * 5. Output the result in one window. + * + * Note that the higher definition of original raw data, the easier we + * recognize. So you can replace videotestsrc with your + * high-definition camera or other src elements. + */ + +/* +.----------. .---. .--------. .---. .---. .---. .--------. .----------. .-----. +| videosrc |->|tee|->Q->|txtovrly|->|enc|->|dec|->|vpp|->|videobox|->|videomixer|->|vsink| +'----------' '---' '--------' '---' '---' '---' '--------' '----------' '-----' + ^ ^ + | | + | .--------. .---. .---. .---. .--------. | + '--->Q->|txtovrly|->|enc|->|dec|->|vpp|->|videobox|->' + ^ '--------' '---' '---' '---' '--------' + | + '-- Injection of GstCustomEvent "GstVaapiEncoderRegionOfInterest" +*/ + +int +main (int argc, char *argv[]) +{ + AppData data; + GstStateChangeReturn ret; + GstElement *q; + GIOChannel *io_stdin; + GError *err = NULL; + + /* Initialize GStreamer */ + gst_init (&argc, &argv); + + /* Print usage map */ + g_print ("USAGE: Choose one of the following options, then press enter:\n" + " 'r' to send ROI event \n" " 'q' to quit\n"); + +#define ENCDEC "vaapih264enc rate-control=cbr bitrate=2000 ! vaapih264dec ! vaapipostproc width=640 " +#define TEXT "textoverlay font-desc=\"Arial Bold 48\" text=" + + data.pipeline = + gst_parse_launch + ("videomixer name=mix ! vaapipostproc ! vaapisink sync=false " + "videotestsrc pattern=snow ! video/x-raw, width=320, framerate=5/1 " + "! tee name=t " + "t. ! queue ! " TEXT "\"non-ROI\" ! " ENCDEC + "! videobox left=-640 ! mix. " + "t. ! queue name=roi ! " TEXT "\"ROI\" ! " ENCDEC + "! videobox ! mix.", &err); + + if (err) { + g_printerr ("failed to parse pipeline: %s\n", err->message); + g_error_free (err); + return -1; + } + + q = gst_bin_get_by_name (GST_BIN (data.pipeline), "roi"); + data.src_pad = gst_element_get_static_pad (q, "src"); + gst_object_unref (q); + + /* Add a keyboard watch so we get notified of keystrokes */ + io_stdin = g_io_channel_unix_new (fileno (stdin)); + g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc) handle_keyboard, &data); + + /* Start playing */ + ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + g_printerr ("Unable to set the pipeline to the playing state.\n"); + gst_object_unref (data.pipeline); + return -1; + } + + /* Create a GLib Main Loop and set it to run */ + data.loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (data.loop); + + /* Free resources */ + g_main_loop_unref (data.loop); + g_io_channel_unref (io_stdin); + gst_element_set_state (data.pipeline, GST_STATE_NULL); + + if (data.src_pad) + gst_object_unref (data.src_pad); + gst_object_unref (data.pipeline); + + return 0; +} From b3c374e22f21613295a16745428487707b680cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 28 Apr 2017 15:20:01 +0200 Subject: [PATCH 2772/3781] plugins: remove par from caps negotiation https://bugzilla.gnome.org/show_bug.cgi?id=781759 --- gst/vaapi/gstvaapipluginutil.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 78a46239a6..b11901f824 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -425,8 +425,7 @@ set_video_template_caps (GstCaps * caps) gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, - "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, - "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); } GstCaps * From f09f21def72e2e241a59ba59e1ce68721edbb699 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 12 May 2017 13:06:24 +0900 Subject: [PATCH 2773/3781] libs: window: x11: fix src rect info when using vpp Since we started using VPP in VaapiWindowX11, we need to care about the case that src rect and window's size are different. So, once VPP has converted to other format, we should honor the size of the VPP's surface as source rect. Otherwise, it is cropped according the previous size of the source rect. https://bugzilla.gnome.org/show_bug.cgi?id=782542 --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 909672ba6e..44b15c265e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -37,6 +37,7 @@ #include "gstvaapipixmap_priv.h" #include "gstvaapidisplay_x11.h" #include "gstvaapidisplay_x11_priv.h" +#include "gstvaapisurface_priv.h" #include "gstvaapiutils.h" #include "gstvaapiutils_x11.h" @@ -463,9 +464,15 @@ conversion: gst_vaapi_window_vpp_convert_internal (window, surface, NULL, NULL, flags); if (G_LIKELY (vpp_surface)) { + GstVaapiRectangle vpp_src_rect; + surface_id = GST_VAAPI_OBJECT_ID (vpp_surface); + vpp_src_rect.x = vpp_src_rect.y = 0; + vpp_src_rect.width = GST_VAAPI_SURFACE_WIDTH (vpp_surface); + vpp_src_rect.height = GST_VAAPI_SURFACE_HEIGHT (vpp_surface); + status = - gst_vaapi_window_x11_put_surface (window, surface_id, src_rect, + gst_vaapi_window_x11_put_surface (window, surface_id, &vpp_src_rect, dst_rect, flags); ret = vaapi_check_status (status, "vaPutSurface()"); From 5ab5113f6f401584f8ab053f098c2fb7340699d3 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 12 May 2017 13:08:30 +0900 Subject: [PATCH 2774/3781] vaapisink: keep handle_events flag except that if user want to set When state of vaapisink is changed from PLAYING to NULL, the handle_events flag is set to FALSE, and never recovered, and then event thread is never going to run. So we should allow to set the flag only when users try it. https://bugzilla.gnome.org/show_bug.cgi?id=782543 --- gst/vaapi/gstvaapisink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 013a4690a5..d01c72775c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -588,6 +588,7 @@ gst_vaapisink_video_overlay_set_event_handling (GstVideoOverlay * overlay, { GstVaapiSink *const sink = GST_VAAPISINK (overlay); + sink->handle_events = handle_events; gst_vaapisink_set_event_handling (sink, handle_events); } @@ -934,7 +935,6 @@ gst_vaapisink_set_event_handling (GstVaapiSink * sink, gboolean handle_events) return; GST_OBJECT_LOCK (sink); - sink->handle_events = handle_events; if (handle_events && !sink->event_thread) { /* Setup our event listening thread */ GST_DEBUG ("starting xevent thread"); From b02a25cd7f1b474d15391ec772b32591bcfdd5b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 12 May 2017 18:17:55 +0200 Subject: [PATCH 2775/3781] tests: elements: clean up vaapisink test - Use gst_element_send_event() instead of gst_pad_push_event() - don't zero App structure - check for pipeline parsing error - only get vaapisink for property set --- tests/elements/test-vaapisink.c | 37 +++++++++++++++------------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/tests/elements/test-vaapisink.c b/tests/elements/test-vaapisink.c index 5005755738..c09988eb6d 100644 --- a/tests/elements/test-vaapisink.c +++ b/tests/elements/test-vaapisink.c @@ -6,9 +6,7 @@ typedef struct _CustomData { GstElement *pipeline; GstElement *video_sink; - GstElement *src_sink; GMainLoop *loop; - GstPad *src_pad; gboolean orient_automatic; } AppData; @@ -26,7 +24,7 @@ send_rotate_event (AppData * data) tags[counter++ % G_N_ELEMENTS (tags)], NULL)); /* Send the event */ - res = gst_pad_push_event (data->src_pad, event); + res = gst_element_send_event (data->pipeline, event); g_print ("Sending event %p done: %d\n", event, res); } @@ -67,25 +65,24 @@ main (int argc, char *argv[]) AppData data; GstStateChangeReturn ret; GIOChannel *io_stdin; + GError *err = NULL; /* Initialize GStreamer */ gst_init (&argc, &argv); - /* Initialize our data structure */ - memset (&data, 0, sizeof (data)); - /* Print usage map */ g_print ("USAGE: Choose one of the following options, then press enter:\n" - " 'r' to send image-orientation tag event\n \ - 's' to set orient-automatic\n \ - 'Q' to quit\n"); + " 'r' to send image-orientation tag event\n" + " 's' to set orient-automatic\n" " 'Q' to quit\n"); - data.pipeline = - gst_parse_launch - ("videotestsrc name=src ! vaapisink name=vaapisink", NULL); - data.video_sink = gst_bin_get_by_name (GST_BIN (data.pipeline), "vaapisink"); - data.src_sink = gst_bin_get_by_name (GST_BIN (data.pipeline), "src"); - data.src_pad = gst_element_get_static_pad (data.src_sink, "src"); + data.pipeline = gst_parse_launch ("videotestsrc ! vaapisink name=sink", &err); + if (err) { + g_printerr ("failed to create pipeline: %s\n", err->message); + g_error_free (err); + return -1; + } + + data.video_sink = gst_bin_get_by_name (GST_BIN (data.pipeline), "sink"); /* Add a keyboard watch so we get notified of keystrokes */ io_stdin = g_io_channel_unix_new (fileno (stdin)); @@ -95,21 +92,21 @@ main (int argc, char *argv[]) ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { g_printerr ("Unable to set the pipeline to the playing state.\n"); - gst_object_unref (data.pipeline); - return -1; + goto bail; } /* Create a GLib Main Loop and set it to run */ data.loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (data.loop); + gst_element_set_state (data.pipeline, GST_STATE_NULL); + +bail: /* Free resources */ g_main_loop_unref (data.loop); g_io_channel_unref (io_stdin); - gst_element_set_state (data.pipeline, GST_STATE_NULL); - if (data.video_sink != NULL) - gst_object_unref (data.video_sink); + gst_object_unref (data.video_sink); gst_object_unref (data.pipeline); return 0; From f133c3d67e45f31fd04eececec104c94fac77d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 12 May 2017 18:46:50 +0200 Subject: [PATCH 2776/3781] tests: elements: vaapisink: handle nav events The test app can now handle navigation events to rotate the display. --- tests/elements/test-vaapisink.c | 64 +++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/tests/elements/test-vaapisink.c b/tests/elements/test-vaapisink.c index c09988eb6d..5bb5c4e10b 100644 --- a/tests/elements/test-vaapisink.c +++ b/tests/elements/test-vaapisink.c @@ -1,6 +1,7 @@ #include #include #include +#include typedef struct _CustomData { @@ -28,18 +29,10 @@ send_rotate_event (AppData * data) g_print ("Sending event %p done: %d\n", event, res); } -/* Process keyboard input */ -static gboolean -handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data) +static void +keyboard_cb (const gchar * key, AppData * data) { - gchar *str = NULL; - - if (g_io_channel_read_line (source, &str, NULL, NULL, - NULL) != G_IO_STATUS_NORMAL) { - return TRUE; - } - - switch (g_ascii_tolower (str[0])) { + switch (g_ascii_tolower (key[0])) { case 'r': send_rotate_event (data); break; @@ -53,7 +46,53 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data) default: break; } +} +static gboolean +bus_msg (GstBus * bus, GstMessage * msg, gpointer user_data) +{ + AppData *data = user_data; + + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_ELEMENT: + { + GstNavigationMessageType mtype = gst_navigation_message_get_type (msg); + if (mtype == GST_NAVIGATION_MESSAGE_EVENT) { + GstEvent *ev = NULL; + + if (gst_navigation_message_parse_event (msg, &ev)) { + GstNavigationEventType type = gst_navigation_event_get_type (ev); + if (type == GST_NAVIGATION_EVENT_KEY_PRESS) { + const gchar *key; + + if (gst_navigation_event_parse_key_event (ev, &key)) + keyboard_cb (key, data); + } + } + if (ev) + gst_event_unref (ev); + } + break; + } + default: + break; + } + + return TRUE; +} + +/* Process keyboard input */ +static gboolean +handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data) +{ + gchar *str = NULL; + + if (g_io_channel_read_line (source, &str, NULL, NULL, + NULL) != G_IO_STATUS_NORMAL) { + return TRUE; + } + + keyboard_cb (str, data); g_free (str); return TRUE; @@ -66,6 +105,7 @@ main (int argc, char *argv[]) GstStateChangeReturn ret; GIOChannel *io_stdin; GError *err = NULL; + guint srcid; /* Initialize GStreamer */ gst_init (&argc, &argv); @@ -83,6 +123,7 @@ main (int argc, char *argv[]) } data.video_sink = gst_bin_get_by_name (GST_BIN (data.pipeline), "sink"); + srcid = gst_bus_add_watch (GST_ELEMENT_BUS (data.pipeline), bus_msg, &data); /* Add a keyboard watch so we get notified of keystrokes */ io_stdin = g_io_channel_unix_new (fileno (stdin)); @@ -103,6 +144,7 @@ main (int argc, char *argv[]) bail: /* Free resources */ + g_source_remove (srcid); g_main_loop_unref (data.loop); g_io_channel_unref (io_stdin); From 3c31e8292adcdb2a1654631990dbc46af7a7f061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 May 2017 18:35:40 +0200 Subject: [PATCH 2777/3781] libs: context: add missing documentation Document the region-of-interest configuration variables. --- gst-libs/gst/vaapi/gstvaapicontext.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 0f91eb37f4..a94259ec46 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -60,6 +60,8 @@ typedef enum { * 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. */ From 58f6e780170ffe264e58ab8575764580af3bfae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 May 2017 18:36:21 +0200 Subject: [PATCH 2778/3781] libs: utils: mark functions as internals The functions in this header are internal to the library. --- gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h index 4122904d21..3d3e5014ec 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h @@ -72,14 +72,16 @@ G_BEGIN_DECLS } \ } G_STMT_END - +G_GNUC_INTERNAL gboolean bs_write_ue (GstBitWriter * bs, guint32 value); +G_GNUC_INTERNAL gboolean bs_write_se (GstBitWriter * bs, gint32 value); /* Write nal unit, applying emulation prevention bytes */ +G_GNUC_INTERNAL gboolean gst_vaapi_utils_h26x_write_nal_unit (GstBitWriter * bs, guint8 * nal, guint nal_size); From ed3360bf3b2e48c1574af04b36be859bc4d322e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 May 2017 18:38:29 +0200 Subject: [PATCH 2779/3781] libs: encoder: check for maximum number of slices Right now, H264 and HEVC can set as a property the number of slices to process. But each driver can set a maximum number of slices, depending on the supported profile & entry point. This patch verifies the current num_slices to process against the maximum permitted by the driver and the media size. https://bugzilla.gnome.org/show_bug.cgi?id=780955 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 49 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 5 +-- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 6 +-- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 6 +++ 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index c4a2e08b79..e2559f0074 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1386,6 +1386,55 @@ gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, return formats; } +/** + * gst_vaapi_encoder_ensure_num_slices: + * @encoder: a #GstVaapiEncoder + * @profile: a #GstVaapiProfile + * @entrypoint: a #GstVaapiEntrypoint + * @media_max_slices: the number of the slices permitted by the stream + * @num_slices: (out): the possible number of slices to process + * + * This function will clamp the @num_slices provided by the user, + * according the limit of the number of slices permitted by the stream + * and by the hardware. + * + * We need to pass the @profile and the @entrypoint, because at the + * moment the encoder base class, still doesn't have them assigned, + * and this function is meant to be called by the derived classes + * while they are configured. + * + * Returns: %TRUE if the number of slices is different than zero. + **/ +gboolean +gst_vaapi_encoder_ensure_num_slices (GstVaapiEncoder * encoder, + GstVaapiProfile profile, GstVaapiEntrypoint entrypoint, + guint media_max_slices, guint * num_slices) +{ + VAProfile va_profile; + VAEntrypoint va_entrypoint; + guint max_slices, num; + + va_profile = gst_vaapi_profile_get_va_profile (profile); + va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint (entrypoint); + + if (!gst_vaapi_get_config_attribute (encoder->display, va_profile, + va_entrypoint, VAConfigAttribEncMaxSlices, &max_slices)) { + *num_slices = 1; + return TRUE; + } + + num = *num_slices; + if (num > max_slices) + num = max_slices; + if (num > media_max_slices) + num = media_max_slices; + + if (num == 0) + return FALSE; + *num_slices = num; + return TRUE; +} + /** * gst_vaapi_encoder_add_roi: * @encoder: a #GstVaapiEncoder diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index b53127778f..94923962b9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2436,9 +2436,8 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->min_qp = encoder->init_qp; mb_size = encoder->mb_width * encoder->mb_height; - if (encoder->num_slices > (mb_size + 1) / 2) - encoder->num_slices = (mb_size + 1) / 2; - g_assert (encoder->num_slices); + g_assert (gst_vaapi_encoder_ensure_num_slices (base_encoder, encoder->profile, + encoder->entrypoint, (mb_size + 1) / 2, &encoder->num_slices)); if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index ba05563268..dd02d54b7f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1960,9 +1960,9 @@ reset_properties (GstVaapiEncoderH265 * encoder) encoder->min_qp = encoder->init_qp; ctu_size = encoder->ctu_width * encoder->ctu_height; - if (encoder->num_slices > (ctu_size + 1) / 2) - encoder->num_slices = (ctu_size + 1) / 2; - g_assert (encoder->num_slices); + g_assert (gst_vaapi_encoder_ensure_num_slices (base_encoder, encoder->profile, + GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, (ctu_size + 1) / 2, + &encoder->num_slices)); if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index d01ed73648..bb9b319fd7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -360,6 +360,12 @@ gboolean gst_vaapi_encoder_ensure_param_quality_level (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_END_DECLS #endif /* GST_VAAPI_ENCODER_PRIV_H */ From e66aaf166c3f02f3b7744d4a414903a7f6cb6dda Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Mon, 22 May 2017 17:20:45 +0200 Subject: [PATCH 2780/3781] libs: encoder: vp8: set quality level regardless of rate control mode https://bugzilla.gnome.org/show_bug.cgi?id=782957 --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 9ced12bb23..58ee55527b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -263,6 +263,9 @@ ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncMiscParam *misc; + if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) + return FALSE; + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CBR) return TRUE; @@ -313,8 +316,6 @@ ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); - if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) - return FALSE; return TRUE; } From 0e31137dec544a75d1079099f9a36a34f44eb17a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 26 May 2017 11:10:34 +0200 Subject: [PATCH 2781/3781] libs: standardize the FIXME comment This is a trivial patch that makes homogeneous the FIXME tag in comments. For more info about these comment style: http://wiki.c2.com/?FixmeComment --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 16 ++++++------- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 26 +++++++++++++--------- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 2 +- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 15be632bc5..9759dd97c2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -615,7 +615,7 @@ get_max_dec_frame_buffering (GstH265SPS * sps) max_dec_frame_buffering = 16; } - /* Fixme: Add limit check based on Annex A */ + /* FIXME: Add limit check based on Annex A */ /* Assuming HighestTid as sps_max_sub_layers_minus1 */ return MAX (1, @@ -1134,7 +1134,7 @@ ensure_context (GstVaapiDecoderH265 * decoder, GstH265SPS * sps) priv->pic_height_in_luma_samples = sps->pic_height_in_luma_samples; } - priv->progressive_sequence = 1; /*Fixme */ + priv->progressive_sequence = 1; /* FIXME */ gst_vaapi_decoder_set_interlaced (base_decoder, !priv->progressive_sequence); gst_vaapi_decoder_set_pixel_aspect_ratio (base_decoder, sps->vui_params.par_n, sps->vui_params.par_d); @@ -1297,7 +1297,7 @@ decode_current_picture (GstVaapiDecoderH265 * decoder) } priv->decoder_state = 0; - /*Fixme: Use SEI header values */ + /* FIXME: Use SEI header values */ priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; if (!picture) @@ -1465,8 +1465,8 @@ decode_sps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) sps->max_latency_increase_plus1[sps->max_sub_layers_minus1] - 1; /* Calculate WpOffsetHalfRangeC: (7-34) - * Fixme: We don't have parser API for sps_range_extension, so assuming - * high_precision_offsets_enabled_flag as zero */ + * FIXME: We don't have parser API for sps_range_extension, so + * assuming high_precision_offsets_enabled_flag as zero */ bitdepthC = sps->bit_depth_chroma_minus8 + 8; priv->WpOffsetHalfRangeC = 1 << (high_precision_offsets_enabled_flag ? (bitdepthC - 1) : 7); @@ -1698,7 +1698,7 @@ init_picture (GstVaapiDecoderH265 * decoder, pi->nalu.type <= GST_H265_NAL_SLICE_CRA_NUT) picture->RapPicFlag = TRUE; - /*Fixme: Use SEI header values */ + /* FIXME: Use SEI header values */ base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; picture->structure = base_picture->structure; @@ -1917,7 +1917,7 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) pic_param->pps_tc_offset_div2 = pps->tc_offset_div2; COPY_FIELD (pps, num_extra_slice_header_bits); - /*Fixme: Set correct value as mentioned in va_dec_hevc.h */ + /* FIXME: Set correct value as mentioned in va_dec_hevc.h */ pic_param->st_rps_bits = 0; return TRUE; } @@ -2306,7 +2306,7 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice_hdr)) || (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice_hdr))) { - /* Fixme: This should be done in parser apis */ + /* FIXME: This should be done in parser apis */ memset (slice_param->delta_luma_weight_l0, 0, sizeof (slice_param->delta_luma_weight_l0)); memset (slice_param->luma_offset_l0, 0, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 76360c7599..314498f710 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -573,7 +573,7 @@ decode_picture (GstVaapiDecoderMpeg4 * decoder, const guint8 * buf, * | | * nearest I/P/S in the past with vop_coded ==1 | * nearest I/P/S in the future with any vop_coded - * fixme, it said that B frame shouldn't use backward reference frame + * FIXME: it said that B frame shouldn't use backward reference frame * when backward reference frame coded is 0 */ if (priv->is_svh) { diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index dd02d54b7f..dcf71d182b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -671,7 +671,7 @@ bs_write_slice (GstBitWriter * bs, /* first_slice_segment_in_pic_flag */ WRITE_UINT32 (bs, encoder->first_slice_segment_in_pic_flag, 1); - /* Fixme: For all IRAP pics */ + /* FIXME: For all IRAP pics */ /* no_output_of_prior_pics_flag */ if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1); @@ -957,7 +957,8 @@ ensure_tier (GstVaapiEncoderH265 * encoder) { encoder->tier = GST_VAAPI_TIER_H265_MAIN; - /*Fixme: Derive proper tier based on upstream caps or limits, coding tools etc */ + /* FIXME: Derive proper tier based on upstream caps or limits, coding + * tools etc */ return TRUE; } @@ -976,8 +977,8 @@ ensure_level (GstVaapiEncoderH265 * encoder) const GstVaapiH265LevelLimits *const limits = &limits_table[i]; if (PicSizeInSamplesY <= limits->MaxLumaPs) break; - /* Fixme: Add more constraint checking:tier (extracted from caps), cpb size, - * bitrate, num_tile_columns and num_tile_rows */ + /* FIXME: Add more constraint checking:tier (extracted from caps), + * cpb size, bitrate, num_tile_columns and num_tile_rows */ } if (i == num_limits) goto error_unsupported_level; @@ -1448,7 +1449,9 @@ fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) seq_param->general_profile_idc = encoder->profile_idc; seq_param->general_level_idc = encoder->level_idc; - seq_param->general_tier_flag = 0; /* Fixme: use the tier flag extracted from upstream caps or calcuted one */ + seq_param->general_tier_flag = 0; /* FIXME: use the tier flag + * extracted from upstream + * caps or calcuted one */ seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq_param->intra_idr_period = encoder->idr_period; @@ -1881,9 +1884,9 @@ ensure_bitrate (GstVaapiEncoderH265 * encoder) switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { case GST_VAAPI_RATECONTROL_CBR: if (!base_encoder->bitrate) { - /* Fixme: Provide better estimation */ + /* FIXME: Provide better estimation */ /* Using a 1/6 compression ratio */ - /* 12 bits per pixel fro yuv420 */ + /* 12 bits per pixel for YUV420 */ guint64 factor = encoder->luma_width * encoder->luma_height * 12 / 6; base_encoder->bitrate = gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder), @@ -1951,7 +1954,7 @@ reset_properties (GstVaapiEncoderH265 * encoder) if (encoder->idr_period > MAX_IDR_PERIOD) encoder->idr_period = MAX_IDR_PERIOD; - /*Fixme: provide user control for idr_period ?? */ + /* FIXME: provide user control for idr_period ?? */ encoder->idr_period = base_encoder->keyframe_period * 2; if (encoder->min_qp > encoder->init_qp || @@ -2318,8 +2321,9 @@ set_context_info (GstVaapiEncoder * base_encoder) GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); const guint DEFAULT_SURFACES_COUNT = 3; - /* Fixme: Using only a rough approximation for bitstream headers.. - * Fixme: Not taken into account: ScalingList, RefPicListModification, PredWeightTable */ + /* FIXME: Using only a rough approximation for bitstream headers. + * Not taken into account: ScalingList, RefPicListModification, + * PredWeightTable */ /* Maximum sizes for common headers (in bits) */ enum { @@ -2579,7 +2583,7 @@ gst_vaapi_encoder_h265_get_default_properties (void) "Minimum QP", "Minimum quantizer value", 1, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /* Fixme: there seems to be issues with multi-slice encoding */ + /* FIXME: there seems to be issues with multi-slice encoding */ /** * GstVaapiEncoderH265:num-slices: * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 437ce16e24..8bb9f2307c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -152,7 +152,7 @@ set_context_info (GstVaapiEncoder * 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) */ + /* FIXME: Maximum sizes for common headers (in bytes) */ if (!ensure_hw_profile (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; From 37b81a7b69037d8da09b5bcf941ac6433d4539bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 5 Jun 2017 18:19:05 +0200 Subject: [PATCH 2782/3781] libs: encoder: use VA quality level structure Instead of using a proxy to story the buffer quality level, the encoder now uses the native VA structure, which is copied to the dynamically allocated VAEncMiscParameterBuffer. This approach is computationally less expensive. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 21 ++++++++++----------- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 6 ++++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index e2559f0074..7df617677f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -190,7 +190,6 @@ gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder, { #if VA_CHECK_VERSION(0,36,0) GstVaapiEncMiscParam *misc; - VAEncMiscParameterBufferQualityLevel *quality_level; /* quality level param is not supported */ if (GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder) == 0) @@ -199,9 +198,8 @@ gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder, misc = GST_VAAPI_ENC_QUALITY_LEVEL_MISC_PARAM_NEW (encoder); if (!misc) return FALSE; - quality_level = misc->data; - memset (quality_level, 0, sizeof (VAEncMiscParameterBufferQualityLevel)); - quality_level->quality_level = encoder->quality_level; + memcpy (misc->data, &encoder->va_quality_level, + sizeof (encoder->va_quality_level)); gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); #endif @@ -767,13 +765,14 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) #if VA_CHECK_VERSION(0,36,0) if (get_config_attribute (encoder, VAConfigAttribEncQualityRange, &quality_level_max) && quality_level_max > 0) { - encoder->quality_level = - gst_util_uint64_scale_int_ceil (encoder->quality_level, - quality_level_max, 8); + GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder) = + gst_util_uint64_scale_int_ceil (GST_VAAPI_ENCODER_QUALITY_LEVEL + (encoder), quality_level_max, 8); } else { - encoder->quality_level = 0; + GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder) = 0; } - GST_INFO ("Quality level is fixed to %d", encoder->quality_level); + GST_INFO ("Quality level is fixed to %d", + GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder)); #endif codedbuf_size = encoder->codedbuf_pool ? @@ -1137,11 +1136,11 @@ gst_vaapi_encoder_set_quality_level (GstVaapiEncoder * encoder, { g_return_val_if_fail (encoder != NULL, 0); - if (encoder->quality_level != quality_level + if (GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder) != quality_level && encoder->num_codedbuf_queued > 0) goto error_operation_failed; - encoder->quality_level = quality_level; + GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder) = quality_level; return GST_VAAPI_ENCODER_STATUS_SUCCESS; /* ERRORS */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index bb9b319fd7..8de816f222 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -173,7 +173,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_ENCODER_QUALITY_LEVEL #define GST_VAAPI_ENCODER_QUALITY_LEVEL(encoder) \ - (GST_VAAPI_ENCODER_CAST (encoder)->quality_level) + (GST_VAAPI_ENCODER_CAST (encoder)->va_quality_level.quality_level) /* Generate a mask for the supplied tuning option (internal) */ #define GST_VAAPI_ENCODER_TUNE_MASK(TUNE) \ @@ -227,7 +227,9 @@ struct _GstVaapiEncoder guint32 rate_control_mask; guint bitrate; /* kbps */ guint keyframe_period; - guint quality_level; + + /* parameters */ + VAEncMiscParameterBufferQualityLevel va_quality_level; GMutex mutex; GCond surface_free; From 5c05a8b436b3dbbee3dd8375bb024706bf4aae5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 2 Jun 2017 16:28:30 +0200 Subject: [PATCH 2783/3781] libs: encoder: h264, h265, mpeg2: remove assert Remove spurious asserts for misc parameters. If they cannot be allocated, FALSE is already returned. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 -- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 1 - gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 2 -- 3 files changed, 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 94923962b9..fbe5d45ba4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2164,7 +2164,6 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) /* HRD params */ misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - g_assert (misc); if (!misc) return FALSE; fill_hrd_params (encoder, misc->data); @@ -2175,7 +2174,6 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR || GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) { misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); - g_assert (misc); if (!misc) return FALSE; rate_control = misc->data; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index dcf71d182b..a2459e7afd 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1774,7 +1774,6 @@ ensure_misc_params (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) /* HRD params for rate control */ if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) { misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - g_assert (misc); if (!misc) return FALSE; fill_hrd_params (encoder, misc->data); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 251b9a5ce0..02700920f4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -462,7 +462,6 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, /* add hrd */ misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - g_assert (misc); if (!misc) return FALSE; gst_vaapi_enc_picture_add_misc_param (picture, misc); @@ -479,7 +478,6 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, /* add ratecontrol */ if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) { misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); - g_assert (misc); if (!misc) return FALSE; gst_vaapi_enc_picture_add_misc_param (picture, misc); From b538a86d4e3b36de92f60801554c29aa88993324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 2 Jun 2017 17:21:25 +0200 Subject: [PATCH 2784/3781] libs: encoder: h264,vp8,mpeg2: refactor control rate Instead of filling the control rate param in ensure_misc_params(), this patch refactor it out, as a first step to merge the same code for all the encoders. https://bugzilla.gnome.org/show_bug.cgi?id=783449 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 53 +++++++++++++------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 55 +++++++++++++-------- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 57 ++++++++++++++-------- 3 files changed, 108 insertions(+), 57 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index fbe5d45ba4..0f046bb6d7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2153,13 +2153,44 @@ error_create_packed_seq_hdr: } } +static gboolean +ensure_control_rate_params (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncMiscParam *misc; + + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) + return TRUE; + + /* RateControl params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); + if (!misc) + return FALSE; + + { + VAEncMiscParameterRateControl rate_control = { + .bits_per_second = encoder->bitrate_bits, + .target_percentage = 70, + .window_size = encoder->cpb_length, + .initial_qp = encoder->init_qp, + .min_qp = encoder->min_qp, + }; + + memcpy (misc->data, &rate_control, sizeof (rate_control)); + } + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + return TRUE; +} + /* Generates additional control parameters */ static gboolean ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - GstVaapiEncMiscParam *misc = NULL; - VAEncMiscParameterRateControl *rate_control; + GstVaapiEncMiscParam *misc; guint num_roi; /* HRD params */ @@ -2170,23 +2201,11 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); - /* RateControl params */ + if (!ensure_control_rate_params (encoder, picture)) + return FALSE; + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR || GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) { - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); - if (!misc) - return FALSE; - rate_control = misc->data; - memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); - rate_control->bits_per_second = encoder->bitrate_bits; - rate_control->target_percentage = 70; - rate_control->window_size = encoder->cpb_length; - rate_control->initial_qp = encoder->init_qp; - rate_control->min_qp = encoder->min_qp; - rate_control->basic_unit_size = 0; - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - if (!encoder->view_idx) { if ((GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) && (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 02700920f4..dd878d8820 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -451,6 +451,38 @@ ensure_picture (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture, return TRUE; } +static gboolean +ensure_control_rate_params (GstVaapiEncoderMpeg2 * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + GstVaapiEncMiscParam *misc; + + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) + return TRUE; + + /* RateControl params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); + if (!misc) + return FALSE; + + { + VAEncMiscParameterRateControl rate_control = { + .bits_per_second = base_encoder->bitrate * 1000, + .target_percentage = 70, + .window_size = 500, + .initial_qp = encoder->cqp, + }; + + memcpy (misc->data, &rate_control, sizeof (rate_control)); + } + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + return TRUE; +} + static gboolean set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) @@ -458,7 +490,6 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncMiscParam *misc = NULL; VAEncMiscParameterHRD *hrd; - VAEncMiscParameterRateControl *rate_control; /* add hrd */ misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); @@ -475,26 +506,8 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, } gst_vaapi_codec_object_replace (&misc, NULL); - /* add ratecontrol */ - if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) { - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); - if (!misc) - return FALSE; - gst_vaapi_enc_picture_add_misc_param (picture, misc); - rate_control = misc->data; - memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); - if (base_encoder->bitrate) - rate_control->bits_per_second = base_encoder->bitrate * 1000; - else - rate_control->bits_per_second = 0; - rate_control->target_percentage = 70; - rate_control->window_size = 500; - rate_control->initial_qp = encoder->cqp; - rate_control->min_qp = 0; - rate_control->basic_unit_size = 0; - gst_vaapi_codec_object_replace (&misc, NULL); - } - + if (!ensure_control_rate_params (encoder, picture)) + return FALSE; if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) return FALSE; return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 58ee55527b..4a94af03e2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -257,6 +257,41 @@ error: } } +static gboolean +ensure_control_rate_params (GstVaapiEncoderVP8 * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + GstVaapiEncMiscParam *misc; + + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) + return TRUE; + + /* RateControl params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); + if (!misc) + return FALSE; + + { + VAEncMiscParameterRateControl rate_control = { + .bits_per_second = base_encoder->bitrate * 1000, + .target_percentage = 70, + /* CPB (Coded picture buffer) length in milliseconds, which + * could be provided as a property */ + .window_size = 500, + .initial_qp = encoder->yac_qi, + .min_qp = 1, + }; + + memcpy (misc->data, &rate_control, sizeof (rate_control)); + } + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + return TRUE; +} + static gboolean ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) { @@ -266,6 +301,9 @@ ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) return FALSE; + if (!ensure_control_rate_params (encoder, picture)) + return FALSE; + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CBR) return TRUE; @@ -297,25 +335,6 @@ ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); - /* RateControl params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); - if (!misc) - return FALSE; - { - VAEncMiscParameterRateControl *rate_control; - rate_control = misc->data; - rate_control->bits_per_second = base_encoder->bitrate * 1000; - rate_control->target_percentage = 70; - /* CPB (Coded picture buffer) length in milliseconds, which could - * be provided as a property */ - rate_control->window_size = 500; - rate_control->initial_qp = encoder->yac_qi; - rate_control->min_qp = 1; - } - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - return TRUE; } From fc5106bd3123a234d1cf71f936e73cbfcd025f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 2 Jun 2017 19:33:36 +0200 Subject: [PATCH 2785/3781] libs: encoder: h264,h265,mpeg2,vp8: refactor HDR Move the Hypothetical Reference Decoder (HRD) parameter, from ensure_misc_params() to ensure_control_rate_params(), since it only shall be defined when the control rate is either VBR or CBR. https://bugzilla.gnome.org/show_bug.cgi?id=783449 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 20 +++++++----- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 38 +++++++++++++++------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 33 +++++++++---------- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 34 +++++++++---------- 4 files changed, 72 insertions(+), 53 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 0f046bb6d7..085f0f9cfc 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2182,6 +2182,18 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder, gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); + /* HRD params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); + if (!misc) + return FALSE; + + { + fill_hrd_params (encoder, misc->data); + } + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + return TRUE; } @@ -2193,14 +2205,6 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) GstVaapiEncMiscParam *misc; guint num_roi; - /* HRD params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - if (!misc) - return FALSE; - fill_hrd_params (encoder, misc->data); - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - if (!ensure_control_rate_params (encoder, picture)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index a2459e7afd..2aee116a08 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1765,22 +1765,38 @@ error_create_packed_seq_hdr: } } +static gboolean +ensure_control_rate_params (GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncMiscParam *misc; + + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) + return TRUE; + + /* HRD params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); + if (!misc) + return FALSE; + + { + fill_hrd_params (encoder, misc->data); + } + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + return TRUE; +} + + static gboolean ensure_misc_params (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - GstVaapiEncMiscParam *misc = NULL; - - /* HRD params for rate control */ - if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) { - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - if (!misc) - return FALSE; - fill_hrd_params (encoder, misc->data); - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - } + if (!ensure_control_rate_params (encoder, picture)) + return FALSE; if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) return FALSE; return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index dd878d8820..e33956d3d6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -480,6 +480,22 @@ ensure_control_rate_params (GstVaapiEncoderMpeg2 * encoder, gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); + /* HRD params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); + if (!misc) + return FALSE; + { + VAEncMiscParameterHRD hrd = { + .buffer_size = base_encoder->bitrate * 1000 * 8, + .initial_buffer_fullness = base_encoder->bitrate * 1000 * 4, + }; + + memcpy (misc->data, &hrd, sizeof (hrd)); + } + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + return TRUE; } @@ -488,23 +504,6 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - GstVaapiEncMiscParam *misc = NULL; - VAEncMiscParameterHRD *hrd; - - /* add hrd */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - if (!misc) - return FALSE; - gst_vaapi_enc_picture_add_misc_param (picture, misc); - hrd = misc->data; - if (base_encoder->bitrate > 0) { - hrd->initial_buffer_fullness = base_encoder->bitrate * 1000 * 4; - hrd->buffer_size = base_encoder->bitrate * 1000 * 8; - } else { - hrd->initial_buffer_fullness = 0; - hrd->buffer_size = 0; - } - gst_vaapi_codec_object_replace (&misc, NULL); if (!ensure_control_rate_params (encoder, picture)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 4a94af03e2..cb6cbe3f9a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -289,6 +289,23 @@ ensure_control_rate_params (GstVaapiEncoderVP8 * encoder, gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); + /* HRD params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); + if (!misc) + return FALSE; + + { + VAEncMiscParameterHRD hrd = { + .buffer_size = base_encoder->bitrate * 1000 * 2, + .initial_buffer_fullness = base_encoder->bitrate * 1000, + }; + + memcpy (misc->data, &hrd, sizeof (hrd)); + } + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + return TRUE; } @@ -318,23 +335,6 @@ ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - if (!misc) - return FALSE; - { - VAEncMiscParameterHRD *hrd = misc->data; - if (base_encoder->bitrate > 0) { - hrd->buffer_size = base_encoder->bitrate * 1000 * 2; - hrd->initial_buffer_fullness = base_encoder->bitrate * 1000; - } else { - hrd->buffer_size = 0; - hrd->initial_buffer_fullness = 0; - } - } - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - return TRUE; } From baac8dc8a398c1d88a1c0e6d885fed2052a78c04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 2 Jun 2017 19:46:52 +0200 Subject: [PATCH 2786/3781] libs: encoder: vp8: refactor FrameRate parameter Move frame-rate parameter from ensure_misc_params() to ensure_contro_rate_param() since it only has meaning when the control rate is either VBR or CBR. https://bugzilla.gnome.org/show_bug.cgi?id=783449 --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 29 ++++++++++++------------ 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index cb6cbe3f9a..eeb2b6b7b8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -306,6 +306,20 @@ ensure_control_rate_params (GstVaapiEncoderVP8 * encoder, gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); + /* FrameRate params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (FrameRate, encoder); + if (!misc) + return FALSE; + { + VAEncMiscParameterFrameRate fr = { + .framerate = + GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder), + }; + memcpy (misc->data, &fr, sizeof (fr)); + } + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + return TRUE; } @@ -313,7 +327,6 @@ static gboolean ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - GstVaapiEncMiscParam *misc; if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) return FALSE; @@ -321,20 +334,6 @@ ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) if (!ensure_control_rate_params (encoder, picture)) return FALSE; - if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CBR) - return TRUE; - - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (FrameRate, encoder); - if (!misc) - return FALSE; - { - VAEncMiscParameterFrameRate *param = misc->data; - param->framerate = - GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder); - } - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - return TRUE; } From daff4e9fbd7637832ba1c0d1aebca3f4b0e254e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 5 Jun 2017 16:34:12 +0200 Subject: [PATCH 2787/3781] libs: encoder: vp8: fix frame rate calculation According to the VA documentation: The framerate is specified as a number of frames per second, as a fraction. The denominator of the fraction is given in the top half (the high two bytes) of the framerate field, and the numerator is given in the bottom half (the low two bytes). For example, if framerate is set to (100 << 16 | 750), this is 750 / 100, hence 7.5fps. If the denominator is zero (the high two bytes are both zero) then it takes the value one instead, so the framerate is just the integer in the low 2 bytes. This patch fixes the the framerate calculation in vp8 encoder according to this. https://bugzilla.gnome.org/show_bug.cgi?id=783449 --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index eeb2b6b7b8..5c895dbdb2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -312,8 +312,8 @@ ensure_control_rate_params (GstVaapiEncoderVP8 * encoder, return FALSE; { VAEncMiscParameterFrameRate fr = { - .framerate = - GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder), + .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | + GST_VAAPI_ENCODER_FPS_N (encoder), }; memcpy (misc->data, &fr, sizeof (fr)); } From acf106e1a718cc273f5684c3e76c4e9da17324eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 5 Jun 2017 17:31:10 +0200 Subject: [PATCH 2788/3781] libs: encoder: vp8,h264,h265,mpeg2: refactor misc parameters This is patch pretends to decouple the assignation of the values in the parameter structures and the VA buffer's parameters setting. It may lead to some issues since HRD, framerate or controlrate may not be handled by the specific encoder, but they are set in the VA buffer's parameters. I leave as it because this patch is just a transitional patch. https://bugzilla.gnome.org/show_bug.cgi?id=783449 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 42 +++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 42 ++++--------- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 16 +---- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 46 ++++----------- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 43 ++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 69 +++++++--------------- 6 files changed, 133 insertions(+), 125 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 7df617677f..563e91c360 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -206,6 +206,48 @@ gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder, return TRUE; } +gboolean +gst_vaapi_encoder_ensure_param_control_rate (GstVaapiEncoder * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncMiscParam *misc; + + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) + return TRUE; + + /* RateControl params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); + if (!misc) + return FALSE; + memcpy (misc->data, &GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder), + sizeof (VAEncMiscParameterRateControl)); + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + /* HRD params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); + if (!misc) + return FALSE; + memcpy (misc->data, &GST_VAAPI_ENCODER_VA_HRD (encoder), + sizeof (VAEncMiscParameterHRD)); + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + /* FrameRate params */ + if (GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder).framerate == 0) + return TRUE; + + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (FrameRate, encoder); + if (!misc) + return FALSE; + memcpy (misc->data, &GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder), + sizeof (VAEncMiscParameterFrameRate)); + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + return TRUE; +} + /** * gst_vaapi_encoder_ref: * @encoder: a #GstVaapiEncoder diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 085f0f9cfc..14bb076207 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2157,44 +2157,26 @@ static gboolean ensure_control_rate_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { - GstVaapiEncMiscParam *misc; + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; + /* *INDENT-OFF* */ /* RateControl params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); - if (!misc) - return FALSE; - - { - VAEncMiscParameterRateControl rate_control = { - .bits_per_second = encoder->bitrate_bits, - .target_percentage = 70, - .window_size = encoder->cpb_length, - .initial_qp = encoder->init_qp, - .min_qp = encoder->min_qp, - }; - - memcpy (misc->data, &rate_control, sizeof (rate_control)); - } - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { + .bits_per_second = encoder->bitrate_bits, + .target_percentage = 70, + .window_size = encoder->cpb_length, + .initial_qp = encoder->init_qp, + .min_qp = encoder->min_qp, + }; /* HRD params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - if (!misc) - return FALSE; + fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); + /* *INDENT-ON* */ - { - fill_hrd_params (encoder, misc->data); - } - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - - return TRUE; + return gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture); } /* Generates additional control parameters */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 2aee116a08..9513f5c874 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1769,27 +1769,17 @@ static gboolean ensure_control_rate_params (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) { - GstVaapiEncMiscParam *misc; + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; /* HRD params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - if (!misc) - return FALSE; + fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); - { - fill_hrd_params (encoder, misc->data); - } - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - - return TRUE; + return gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture); } - static gboolean ensure_misc_params (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) { diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index e33956d3d6..e80443a7fd 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -456,47 +456,27 @@ ensure_control_rate_params (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - GstVaapiEncMiscParam *misc; if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; + /* *INDENT-OFF* */ /* RateControl params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); - if (!misc) - return FALSE; - - { - VAEncMiscParameterRateControl rate_control = { - .bits_per_second = base_encoder->bitrate * 1000, - .target_percentage = 70, - .window_size = 500, - .initial_qp = encoder->cqp, - }; - - memcpy (misc->data, &rate_control, sizeof (rate_control)); - } - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { + .bits_per_second = base_encoder->bitrate * 1000, + .target_percentage = 70, + .window_size = 500, + .initial_qp = encoder->cqp, + }; /* HRD params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - if (!misc) - return FALSE; - { - VAEncMiscParameterHRD hrd = { - .buffer_size = base_encoder->bitrate * 1000 * 8, - .initial_buffer_fullness = base_encoder->bitrate * 1000 * 4, - }; + GST_VAAPI_ENCODER_VA_HRD (encoder) = (VAEncMiscParameterHRD) { + .buffer_size = base_encoder->bitrate * 1000 * 8, + .initial_buffer_fullness = base_encoder->bitrate * 1000 * 4, + }; + /* *INDENT-ON* */ - memcpy (misc->data, &hrd, sizeof (hrd)); - } - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - - return TRUE; + return gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture); } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 8de816f222..598aabf263 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -175,6 +175,39 @@ G_BEGIN_DECLS #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)) @@ -244,6 +277,11 @@ struct _GstVaapiEncoder /* Region of Interest */ GList *roi_regions; + + /* miscellaneous buffer parameters */ + VAEncMiscParameterRateControl va_ratecontrol; + VAEncMiscParameterFrameRate va_framerate; + VAEncMiscParameterHRD va_hrd; }; struct _GstVaapiEncoderClassData @@ -362,6 +400,11 @@ 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_num_slices (GstVaapiEncoder * encoder, diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 5c895dbdb2..11f6449212 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -262,65 +262,36 @@ ensure_control_rate_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - GstVaapiEncMiscParam *misc; if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; + /* *INDENT-OFF* */ /* RateControl params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); - if (!misc) - return FALSE; - - { - VAEncMiscParameterRateControl rate_control = { - .bits_per_second = base_encoder->bitrate * 1000, - .target_percentage = 70, - /* CPB (Coded picture buffer) length in milliseconds, which - * could be provided as a property */ - .window_size = 500, - .initial_qp = encoder->yac_qi, - .min_qp = 1, - }; - - memcpy (misc->data, &rate_control, sizeof (rate_control)); - } - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { + .bits_per_second = base_encoder->bitrate * 1000, + .target_percentage = 70, + /* CPB (Coded picture buffer) length in milliseconds, which + * could be provided as a property */ + .window_size = 500, + .initial_qp = encoder->yac_qi, + .min_qp = 1, + }; /* HRD params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - if (!misc) - return FALSE; - - { - VAEncMiscParameterHRD hrd = { - .buffer_size = base_encoder->bitrate * 1000 * 2, - .initial_buffer_fullness = base_encoder->bitrate * 1000, - }; - - memcpy (misc->data, &hrd, sizeof (hrd)); - } - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); + GST_VAAPI_ENCODER_VA_HRD (encoder) = (VAEncMiscParameterHRD) { + .buffer_size = base_encoder->bitrate * 1000 * 2, + .initial_buffer_fullness = base_encoder->bitrate * 1000, + }; /* FrameRate params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (FrameRate, encoder); - if (!misc) - return FALSE; - { - VAEncMiscParameterFrameRate fr = { - .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | - GST_VAAPI_ENCODER_FPS_N (encoder), - }; - memcpy (misc->data, &fr, sizeof (fr)); - } - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); + GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder) = (VAEncMiscParameterFrameRate) { + .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | + GST_VAAPI_ENCODER_FPS_N (encoder), + }; + /* *INDENT-ON* */ - return TRUE; + return gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture); } static gboolean From 846c276e26a071c4f1fccb7b0949d4de30a27fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 5 Jun 2017 20:30:07 +0200 Subject: [PATCH 2789/3781] libs: encoder: vp8,h264,h265,mpeg2: set misc param once Instead of recalculating the miscellaneous buffer parameters for every buffer, it is only done once, when the encoder is configured. And for every buffer, the same structures are just copied. https://bugzilla.gnome.org/show_bug.cgi?id=783449 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 10 ++++------ gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 10 ++++------ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 8 ++++---- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 14bb076207..6ffbd96623 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2154,11 +2154,8 @@ error_create_packed_seq_hdr: } static gboolean -ensure_control_rate_params (GstVaapiEncoderH264 * encoder, - GstVaapiEncPicture * picture) +ensure_control_rate_params (GstVaapiEncoderH264 * encoder) { - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; @@ -2176,7 +2173,7 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder, fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); /* *INDENT-ON* */ - return gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture); + return TRUE; } /* Generates additional control parameters */ @@ -2187,7 +2184,7 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) GstVaapiEncMiscParam *misc; guint num_roi; - if (!ensure_control_rate_params (encoder, picture)) + if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture)) return FALSE; if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR || @@ -2848,6 +2845,7 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) return status; reset_properties (encoder); + ensure_control_rate_params (encoder); return set_context_info (base_encoder); } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 9513f5c874..e8bc289d99 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1766,18 +1766,15 @@ error_create_packed_seq_hdr: } static gboolean -ensure_control_rate_params (GstVaapiEncoderH265 * encoder, - GstVaapiEncPicture * picture) +ensure_control_rate_params (GstVaapiEncoderH265 * encoder) { - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); - return gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture); + return TRUE; } static gboolean @@ -1785,7 +1782,7 @@ ensure_misc_params (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - if (!ensure_control_rate_params (encoder, picture)) + if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture)) return FALSE; if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) return FALSE; @@ -2413,6 +2410,7 @@ gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) return status; reset_properties (encoder); + ensure_control_rate_params (encoder); return set_context_info (base_encoder); } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index e80443a7fd..2c284ee4b5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -452,8 +452,7 @@ ensure_picture (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture, } static gboolean -ensure_control_rate_params (GstVaapiEncoderMpeg2 * encoder, - GstVaapiEncPicture * picture) +ensure_control_rate_params (GstVaapiEncoderMpeg2 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); @@ -476,7 +475,7 @@ ensure_control_rate_params (GstVaapiEncoderMpeg2 * encoder, }; /* *INDENT-ON* */ - return gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture); + return TRUE; } static gboolean @@ -485,7 +484,7 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - if (!ensure_control_rate_params (encoder, picture)) + if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture)) return FALSE; if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) return FALSE; @@ -713,6 +712,7 @@ gst_vaapi_encoder_mpeg2_reconfigure (GstVaapiEncoder * base_encoder) if (!ensure_bitrate (encoder)) goto error; + ensure_control_rate_params (encoder); return set_context_info (base_encoder); /* ERRORS */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 11f6449212..3aa46e7a31 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -258,8 +258,7 @@ error: } static gboolean -ensure_control_rate_params (GstVaapiEncoderVP8 * encoder, - GstVaapiEncPicture * picture) +ensure_control_rate_params (GstVaapiEncoderVP8 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); @@ -291,7 +290,7 @@ ensure_control_rate_params (GstVaapiEncoderVP8 * encoder, }; /* *INDENT-ON* */ - return gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture); + return TRUE; } static gboolean @@ -302,7 +301,7 @@ ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) return FALSE; - if (!ensure_control_rate_params (encoder, picture)) + if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture)) return FALSE; return TRUE; @@ -510,6 +509,7 @@ gst_vaapi_encoder_vp8_reconfigure (GstVaapiEncoder * base_encoder) if (!ensure_bitrate (encoder)) goto error; + ensure_control_rate_params (encoder); return set_context_info (base_encoder); /* ERRORS */ From d733714ef85db8c66cb8e36d2438cff9b899358a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 5 Jun 2017 20:33:27 +0200 Subject: [PATCH 2790/3781] libs: encoder: h264,h265,mpeg2: add framerate parameter https://bugzilla.gnome.org/show_bug.cgi?id=783449 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 ++++++ gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 8 ++++++++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 6ffbd96623..e75a2ca958 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2171,6 +2171,12 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder) /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); + + /* FrameRate params */ + GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder) = (VAEncMiscParameterFrameRate) { + .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | + GST_VAAPI_ENCODER_FPS_N (encoder), + }; /* *INDENT-ON* */ return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index e8bc289d99..33975ab2e1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1771,9 +1771,17 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; + /* *INDENT-OFF* */ /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); + /* FrameRate params */ + GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder) = (VAEncMiscParameterFrameRate) { + .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | + GST_VAAPI_ENCODER_FPS_N (encoder), + }; + /* *INDENT-ON* */ + return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 2c284ee4b5..798c00f079 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -473,6 +473,12 @@ ensure_control_rate_params (GstVaapiEncoderMpeg2 * encoder) .buffer_size = base_encoder->bitrate * 1000 * 8, .initial_buffer_fullness = base_encoder->bitrate * 1000 * 4, }; + + /* FrameRate params */ + GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder) = (VAEncMiscParameterFrameRate) { + .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | + GST_VAAPI_ENCODER_FPS_N (encoder), + }; /* *INDENT-ON* */ return TRUE; From 81886682cd462f4ad1d490299f487f7aa521ca1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 5 Jun 2017 20:44:22 +0200 Subject: [PATCH 2791/3781] libs: encoder: h265: add rate control parameter https://bugzilla.gnome.org/show_bug.cgi?id=783449 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 33975ab2e1..d8a521b4f0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1772,6 +1772,17 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) return TRUE; /* *INDENT-OFF* */ + /* RateControl params */ + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { + .bits_per_second = encoder->bitrate_bits, + .target_percentage = 70, + /* CPB (Coded picture buffer) length in milliseconds, which could + * be provided as a property */ + .window_size = encoder->cpb_length, + .initial_qp = encoder->init_qp, + .min_qp = encoder->min_qp, + }; + /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); From cbd912b89b1aa268ebbd94e84d20140e53ec1fd2 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 2 Jun 2017 13:50:05 +0900 Subject: [PATCH 2792/3781] libs: encoder: Describes more detail about the bitrate property https://bugzilla.gnome.org/show_bug.cgi?id=778732 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 563e91c360..792f356d55 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -136,6 +136,17 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) * GstVaapiEncoder:bitrate: * * The desired bitrate, expressed in kbps. + * This is available when rate-control is CBR or VBR. + * + * CBR: This applies equally to minimum, maximum and target bitrate in the driver. + * VBR: This applies to maximum bitrate in the driver. + * Minimum bitrate will be calculated like the following in the driver. + * if (target percentage < 50) minimum bitrate = 0 + * else minimum bitrate = maximum bitrate * (2 * target percentage -100) / 100 + * Target bitrate will be calculated like the following in the driver. + * target bitrate = maximum bitrate * target percentage / 100 + * + * Note that target percentage is set as 70 currently in GStreamer VA-API. */ GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_PROP_BITRATE, From f68d0452be7fe914519bcac7431a0848a27dab0b Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 1 Jun 2017 12:11:12 +0900 Subject: [PATCH 2793/3781] libs: encoder: h265: Adds VBR Encoding support Enables Variable BitRate mode, which does set FrameRate and RateControl parameters. https://bugzilla.gnome.org/show_bug.cgi?id=778732 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index d8a521b4f0..0c0569674c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -40,8 +40,9 @@ /* 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 (CQP) | \ + GST_VAAPI_RATECONTROL_MASK (CBR) | \ + GST_VAAPI_RATECONTROL_MASK (VBR)) /* Supported set of tuning options, within this implementation */ #define SUPPORTED_TUNE_OPTIONS \ @@ -1576,8 +1577,9 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, pic_param->pic_fields.bits.transform_skip_enabled_flag = TRUE; /* it seems driver requires enablement of cu_qp_delta_enabled_flag * to modifiy QP values in CBR mode encoding */ - if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) - pic_param->pic_fields.bits.cu_qp_delta_enabled_flag = TRUE; + pic_param->pic_fields.bits.cu_qp_delta_enabled_flag = + GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CQP; + pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag = TRUE; if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) @@ -1904,6 +1906,7 @@ ensure_bitrate (GstVaapiEncoderH265 * encoder) 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 */ From 5d345b08fd7a707b19140d58adad2c63e49d8afe Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 1 Jun 2017 12:12:26 +0900 Subject: [PATCH 2794/3781] libs: encoder: vp8: Adds VBR Encoding support https://bugzilla.gnome.org/show_bug.cgi?id=778732 --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 3aa46e7a31..3b52dc2dc4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -40,7 +40,8 @@ /* 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 (CBR) | \ + GST_VAAPI_RATECONTROL_MASK (VBR)) /* Supported set of tuning options, within this implementation */ #define SUPPORTED_TUNE_OPTIONS \ @@ -125,6 +126,7 @@ ensure_bitrate (GstVaapiEncoderVP8 * 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) * @@ -220,7 +222,8 @@ fill_sequence (GstVaapiEncoderVP8 * encoder, GstVaapiEncSequence * sequence) 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) + 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; From 4bf8ef724b9313529a7c4c70eb6595dfcdf5811e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Tue, 9 Aug 2016 15:53:47 +0300 Subject: [PATCH 2795/3781] libs: encoder: vp9: Adds CBR and VBR Encoding support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugzilla.gnome.org/show_bug.cgi?id=766832 Signed-off-by: Hyunjun Ko Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 100 ++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 4 +- 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 8bb9f2307c..f4d93113bd 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -39,7 +39,9 @@ /* Supported set of VA rate controls, within this implementation */ #define SUPPORTED_RATECONTROLS \ - (GST_VAAPI_RATECONTROL_MASK (CQP)) + (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 \ @@ -56,6 +58,9 @@ #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, @@ -101,8 +106,47 @@ struct _GstVaapiEncoderVP9 guint frame_num; GstVaapiSurfaceProxy *ref_list[GST_VP9_REF_FRAMES]; /* reference list */ guint ref_list_idx; /* next free slot in ref_list */ + + /* 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; + } +} + /* Derives the profile that suits best to the configuration */ static GstVaapiEncoderStatus ensure_profile (GstVaapiEncoderVP9 * encoder) @@ -110,6 +154,9 @@ ensure_profile (GstVaapiEncoderVP9 * encoder) /* Always start from "simple" profile for maximum compatibility */ encoder->profile = GST_VAAPI_PROFILE_VP9_0; + /* Ensure bitrate if not set already */ + ensure_bitrate (encoder); + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } @@ -182,6 +229,7 @@ fill_sequence (GstVaapiEncoderVP9 * encoder, GstVaapiEncSequence * sequence) /* 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; } @@ -215,6 +263,36 @@ error: } } +static gboolean +ensure_control_rate_params (GstVaapiEncoderVP9 * encoder) +{ + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) + return TRUE; + + /* *INDENT-OFF* */ + /* RateControl params */ + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { + .bits_per_second = encoder->bitrate_bits, + .target_percentage = 70, + .window_size = encoder->cpb_length, + }; + + /* HRD params */ + GST_VAAPI_ENCODER_VA_HRD (encoder) = (VAEncMiscParameterHRD) { + .buffer_size = encoder->bitrate_bits * 2, + .initial_buffer_fullness = encoder->bitrate_bits, + }; + + /* FrameRate params */ + GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder) = (VAEncMiscParameterFrameRate) { + .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | + GST_VAAPI_ENCODER_FPS_N (encoder), + }; + /* *INDENT-ON* */ + + return TRUE; +} + static gboolean ensure_misc_params (GstVaapiEncoderVP9 * encoder, GstVaapiEncPicture * picture) { @@ -222,6 +300,8 @@ ensure_misc_params (GstVaapiEncoderVP9 * encoder, GstVaapiEncPicture * picture) 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; } @@ -439,6 +519,7 @@ gst_vaapi_encoder_vp9_reconfigure (GstVaapiEncoder * base_encoder) if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; + ensure_control_rate_params (encoder); return set_context_info (base_encoder); } @@ -451,6 +532,7 @@ gst_vaapi_encoder_vp9_init (GstVaapiEncoder * base_encoder) 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; memset (encoder->ref_list, 0, G_N_ELEMENTS (encoder->ref_list) * sizeof (encoder->ref_list[0])); @@ -483,6 +565,9 @@ gst_vaapi_encoder_vp9_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE: encoder->ref_pic_mode = g_value_get_enum (value); break; + case GST_VAAPI_ENCODER_VP9_PROP_CPB_LENGTH: + encoder->cpb_length = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -569,6 +654,19 @@ gst_vaapi_encoder_vp9_get_default_properties (void) GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderVP9:cpb-length: + * + * The size of the Coded Picture Buffer , which means + * the window size in milliseconds. + * + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_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)); return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h index 2ddcbd40d6..7967a98002 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -38,6 +38,7 @@ typedef struct _GstVaapiEncoderVP9 GstVaapiEncoderVP9; * @GST_VAAPI_ENCODER_VP9_PROP_LOOP_SHARPNESS_LEVEL: Sharpness Level(uint). * @GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX: Quantization table index for luma AC * @GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE: Reference picute selection modes + * @GST_VAAPI_ENCODER_VP9_PROP_CPB_LENGTH:Length of CPB buffer in milliseconds * * The set of VP9 encoder specific configurable properties. */ @@ -45,7 +46,8 @@ typedef enum { GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL = -1, GST_VAAPI_ENCODER_VP9_PROP_SHARPNESS_LEVEL = -2, GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX = -3, - GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE = -4 + GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE = -4, + GST_VAAPI_ENCODER_VP9_PROP_CPB_LENGTH = -5 } GstVaapiEncoderVP9Prop; GstVaapiEncoder * From 035efded759e181ec8591fc360758530bb757446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 7 Jun 2017 11:10:49 +0200 Subject: [PATCH 2796/3781] libs: encoder: h264,h265,mpeg2,vp8,vp9: refactor framerate param Since the framerate VA parameter is calculated equally among all the encoders, it is better to handle it in the base encoder class. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 4 ++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 ------ gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 6 ------ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 6 ------ gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 6 ------ gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 6 ------ 6 files changed, 4 insertions(+), 30 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 792f356d55..ea20df089e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -808,6 +808,10 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) if (!encoder->keyframe_period) encoder->keyframe_period = (vip->fps_n + vip->fps_d - 1) / vip->fps_d; + /* Default frame rate parameter */ + GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder).framerate = + (guint) GST_VIDEO_INFO_FPS_D (vip) << 16 | GST_VIDEO_INFO_FPS_N (vip); + status = klass->reconfigure (encoder); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index e75a2ca958..6ffbd96623 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2171,12 +2171,6 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder) /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); - - /* FrameRate params */ - GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder) = (VAEncMiscParameterFrameRate) { - .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | - GST_VAAPI_ENCODER_FPS_N (encoder), - }; /* *INDENT-ON* */ return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 0c0569674c..69393c04e4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1787,12 +1787,6 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); - - /* FrameRate params */ - GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder) = (VAEncMiscParameterFrameRate) { - .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | - GST_VAAPI_ENCODER_FPS_N (encoder), - }; /* *INDENT-ON* */ return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 798c00f079..2c284ee4b5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -473,12 +473,6 @@ ensure_control_rate_params (GstVaapiEncoderMpeg2 * encoder) .buffer_size = base_encoder->bitrate * 1000 * 8, .initial_buffer_fullness = base_encoder->bitrate * 1000 * 4, }; - - /* FrameRate params */ - GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder) = (VAEncMiscParameterFrameRate) { - .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | - GST_VAAPI_ENCODER_FPS_N (encoder), - }; /* *INDENT-ON* */ return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 3b52dc2dc4..f823974db9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -285,12 +285,6 @@ ensure_control_rate_params (GstVaapiEncoderVP8 * encoder) .buffer_size = base_encoder->bitrate * 1000 * 2, .initial_buffer_fullness = base_encoder->bitrate * 1000, }; - - /* FrameRate params */ - GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder) = (VAEncMiscParameterFrameRate) { - .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | - GST_VAAPI_ENCODER_FPS_N (encoder), - }; /* *INDENT-ON* */ return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index f4d93113bd..fbc8d665db 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -282,12 +282,6 @@ ensure_control_rate_params (GstVaapiEncoderVP9 * encoder) .buffer_size = encoder->bitrate_bits * 2, .initial_buffer_fullness = encoder->bitrate_bits, }; - - /* FrameRate params */ - GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder) = (VAEncMiscParameterFrameRate) { - .framerate = (guint) GST_VAAPI_ENCODER_FPS_D (encoder) << 16 | - GST_VAAPI_ENCODER_FPS_N (encoder), - }; /* *INDENT-ON* */ return TRUE; From 4b5ecca29c81d0219d83d3271c1aa5e25c3673d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 7 Jun 2017 12:25:24 +0200 Subject: [PATCH 2797/3781] libs: encoder: h264,h265,mpeg2,vp8,vp9: refactor ratecontrol param Centralize the common configuration for the Rate Control parameter, thus can be overloaded per each specific encoder. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 9 +++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 14 +++++--------- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 18 +++++++----------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 9 ++------- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 13 +++---------- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 10 ++++------ 6 files changed, 30 insertions(+), 43 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index ea20df089e..d266f60b1c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -812,6 +812,15 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder).framerate = (guint) GST_VIDEO_INFO_FPS_D (vip) << 16 | GST_VIDEO_INFO_FPS_N (vip); + /* *INDENT-OFF* */ + /* Default values for rate control parameter */ + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { + .bits_per_second = encoder->bitrate * 1000, + .target_percentage = 70, + .window_size = 500, + }; + /* *INDENT-ON* */ + status = klass->reconfigure (encoder); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 6ffbd96623..fb3dab920a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2159,19 +2159,15 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder) if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; - /* *INDENT-OFF* */ /* RateControl params */ - GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { - .bits_per_second = encoder->bitrate_bits, - .target_percentage = 70, - .window_size = encoder->cpb_length, - .initial_qp = encoder->init_qp, - .min_qp = encoder->min_qp, - }; + 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; + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); - /* *INDENT-ON* */ return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 69393c04e4..b8cd97cbfa 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1773,21 +1773,17 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; - /* *INDENT-OFF* */ /* RateControl params */ - GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { - .bits_per_second = encoder->bitrate_bits, - .target_percentage = 70, - /* CPB (Coded picture buffer) length in milliseconds, which could - * be provided as a property */ - .window_size = encoder->cpb_length, - .initial_qp = encoder->init_qp, - .min_qp = encoder->min_qp, - }; + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).bits_per_second = + encoder->bitrate_bits; + /* CPB (Coded picture buffer) length in milliseconds, which could be + * provided as a property */ + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length; + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); - /* *INDENT-ON* */ return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 2c284ee4b5..ab074071d2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -459,15 +459,10 @@ ensure_control_rate_params (GstVaapiEncoderMpeg2 * encoder) if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; - /* *INDENT-OFF* */ /* RateControl params */ - GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { - .bits_per_second = base_encoder->bitrate * 1000, - .target_percentage = 70, - .window_size = 500, - .initial_qp = encoder->cqp, - }; + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->cqp; + /* *INDENT-OFF* */ /* HRD params */ GST_VAAPI_ENCODER_VA_HRD (encoder) = (VAEncMiscParameterHRD) { .buffer_size = base_encoder->bitrate * 1000 * 8, diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index f823974db9..9357527766 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -268,18 +268,11 @@ ensure_control_rate_params (GstVaapiEncoderVP8 * encoder) if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; - /* *INDENT-OFF* */ /* RateControl params */ - GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { - .bits_per_second = base_encoder->bitrate * 1000, - .target_percentage = 70, - /* CPB (Coded picture buffer) length in milliseconds, which - * could be provided as a property */ - .window_size = 500, - .initial_qp = encoder->yac_qi, - .min_qp = 1, - }; + 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, diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index fbc8d665db..35b4f7e6cf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -269,14 +269,12 @@ ensure_control_rate_params (GstVaapiEncoderVP9 * encoder) if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; - /* *INDENT-OFF* */ /* RateControl params */ - GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { - .bits_per_second = encoder->bitrate_bits, - .target_percentage = 70, - .window_size = encoder->cpb_length, - }; + 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, From f8afb1eea475d2d77b5b660609a0f02da401636f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 7 Jun 2017 12:32:53 +0200 Subject: [PATCH 2798/3781] libs: encoder: bitrate target percentage calculation If the rate control is set to Constant Bit Rate (CBR) the target percentage is 100%, otherwise is 70% --- gst-libs/gst/vaapi/gstvaapiencoder.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index d266f60b1c..b416c85098 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -802,7 +802,7 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); GstVaapiEncoderStatus status; GstVaapiVideoPool *pool; - guint codedbuf_size, quality_level_max = 0; + guint codedbuf_size, target_percentage, quality_level_max = 0; /* Generate a keyframe every second */ if (!encoder->keyframe_period) @@ -812,11 +812,15 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder).framerate = (guint) GST_VIDEO_INFO_FPS_D (vip) << 16 | GST_VIDEO_INFO_FPS_N (vip); + target_percentage = + (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) ? + 100 : 70; + /* *INDENT-OFF* */ /* Default values for rate control parameter */ GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder) = (VAEncMiscParameterRateControl) { .bits_per_second = encoder->bitrate * 1000, - .target_percentage = 70, + .target_percentage = target_percentage, .window_size = 500, }; /* *INDENT-ON* */ From 94b41c8d3873aeea34d9a3a9214120509847940c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 8 Jun 2017 12:51:50 +0200 Subject: [PATCH 2799/3781] libs: encoder: set framerate if bigger than 0/1 Just set the framerate parameter if the framerate numerator and denominator are bigger than zero. Otherwise, in Intel Gen6 driver, a warning is raised disabling the bitrate control. Original-patch-by: Hyunjun Ko https://bugzilla.gnome.org/show_bug.cgi?id=783532 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index b416c85098..fb2d5dd8b7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -803,14 +803,18 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) GstVaapiEncoderStatus status; GstVaapiVideoPool *pool; guint codedbuf_size, target_percentage, quality_level_max = 0; + guint fps_d, fps_n; + + fps_d = GST_VIDEO_INFO_FPS_D (vip); + fps_n = GST_VIDEO_INFO_FPS_N (vip); /* Generate a keyframe every second */ if (!encoder->keyframe_period) - encoder->keyframe_period = (vip->fps_n + vip->fps_d - 1) / vip->fps_d; + encoder->keyframe_period = (fps_n + fps_d - 1) / fps_d; /* Default frame rate parameter */ - GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder).framerate = - (guint) GST_VIDEO_INFO_FPS_D (vip) << 16 | GST_VIDEO_INFO_FPS_N (vip); + if (fps_d > 0 && fps_n > 0) + GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder).framerate = fps_d << 16 | fps_n; target_percentage = (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) ? From dce7a6f46ba3a33e182d9d10d1d23b3d7bc1db9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 8 Jun 2017 15:49:05 +0200 Subject: [PATCH 2800/3781] vaapivideobufferpool: rename video info structures Renamed private GstVideoInfo structure video_info to allocation_vinfo and alloc_info to negotiated_vinfo. The purpose of these renaming is to clarify the origin and purpose of these private variables: video_info (now allocation_vinfo) comes from the bufferpool configuration. It describes the physical video resolution to be allocated by the allocator, which may be different from the negotiated one. alloc_info (now vmeta_vinfo) comes from the negotiated caps in the pipeline. It represents how the frame is going to be mapped using the video meta. In Intel's VA-API backend, the allocation_vinfo resolution is bigger than the negotiated_info. https://bugzilla.gnome.org/show_bug.cgi?id=783599 --- gst/vaapi/gstvaapivideobufferpool.c | 31 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 2782403a13..5339585cd3 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -44,9 +44,9 @@ enum struct _GstVaapiVideoBufferPoolPrivate { - GstVideoInfo video_info; + GstVideoInfo allocation_vinfo; GstAllocator *allocator; - GstVideoInfo alloc_info; + GstVideoInfo vmeta_vinfo; GstVaapiDisplay *display; guint options; guint use_dmabuf_memory:1; @@ -105,7 +105,7 @@ gst_vaapi_video_buffer_pool_get_property (GObject * object, guint prop_id, static void fill_video_alignment (GstVaapiVideoBufferPool * pool, GstVideoAlignment * align) { - GstVideoInfo *const vip = &pool->priv->alloc_info; + GstVideoInfo *const vip = &pool->priv->vmeta_vinfo; guint i; gst_video_alignment_reset (align); @@ -157,9 +157,9 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, if (!gst_buffer_pool_config_get_allocator (config, &allocator, NULL)) goto error_invalid_allocator; - if (gst_video_info_changed (&priv->video_info, &new_vip)) + if (gst_video_info_changed (&priv->allocation_vinfo, &new_vip)) gst_object_replace ((GstObject **) & priv->allocator, NULL); - priv->video_info = new_vip; + priv->allocation_vinfo = new_vip; { guint surface_alloc_flags; @@ -199,11 +199,12 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, alloc_vip = gst_allocator_get_vaapi_video_info (priv->allocator, NULL); if (!alloc_vip) goto error_create_allocator_info; - priv->alloc_info = *alloc_vip; + priv->vmeta_vinfo = *alloc_vip; } - if (GST_VIDEO_INFO_SIZE (&priv->alloc_info) != size) { + if (GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo) != size) { gst_buffer_pool_config_set_params (config, caps, - GST_VIDEO_INFO_SIZE (&priv->alloc_info), min_buffers, max_buffers); + GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo), min_buffers, + max_buffers); } } if (!priv->allocator) @@ -215,11 +216,11 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; else { gint i; - for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&priv->video_info); i++) { - if (GST_VIDEO_INFO_PLANE_OFFSET (&priv->video_info, i) != - GST_VIDEO_INFO_PLANE_OFFSET (&priv->alloc_info, i) || - GST_VIDEO_INFO_PLANE_STRIDE (&priv->video_info, i) != - GST_VIDEO_INFO_PLANE_STRIDE (&priv->alloc_info, i)) { + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&priv->allocation_vinfo); i++) { + if (GST_VIDEO_INFO_PLANE_OFFSET (&priv->allocation_vinfo, i) != + GST_VIDEO_INFO_PLANE_OFFSET (&priv->vmeta_vinfo, i) || + GST_VIDEO_INFO_PLANE_STRIDE (&priv->allocation_vinfo, i) != + GST_VIDEO_INFO_PLANE_STRIDE (&priv->vmeta_vinfo, i)) { priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); @@ -327,7 +328,7 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, gst_buffer_append_memory (buffer, mem); if (priv->options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META) { - GstVideoInfo *const vip = &priv->alloc_info; + GstVideoInfo *const vip = &priv->vmeta_vinfo; GstVideoMeta *vmeta; vmeta = gst_buffer_add_video_meta_full (buffer, 0, @@ -500,7 +501,7 @@ gst_vaapi_video_buffer_pool_init (GstVaapiVideoBufferPool * pool) pool->priv = priv; - gst_video_info_init (&priv->video_info); + gst_video_info_init (&priv->allocation_vinfo); } GstBufferPool * From 45faeb25e88b21e40b3b8b3f288779a115471b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 8 Jun 2017 16:05:49 +0200 Subject: [PATCH 2801/3781] vaapivideobufferpool: rename local variables Renamed local video info structure names in set_config() vitual method. The purpose of their renaming is to clarify the origin of those structures, whether come from passed caps parameter (new_allocation_vinfo) or from the configured allocator (allocator_vinfo). https://bugzilla.gnome.org/show_bug.cgi?id=783599 --- gst/vaapi/gstvaapivideobufferpool.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 5339585cd3..f0b6ec4c06 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -135,8 +135,8 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, GstVaapiVideoBufferPoolPrivate *const priv = GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv; GstCaps *caps; - GstVideoInfo new_vip; - const GstVideoInfo *alloc_vip; + GstVideoInfo new_allocation_vinfo; + const GstVideoInfo *allocator_vinfo; GstVideoAlignment align; GstAllocator *allocator; gboolean ret, updated = FALSE; @@ -150,34 +150,35 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, goto error_invalid_config; if (!caps) goto error_no_caps; - if (!gst_video_info_from_caps (&new_vip, caps)) + if (!gst_video_info_from_caps (&new_allocation_vinfo, caps)) goto error_invalid_caps; allocator = NULL; if (!gst_buffer_pool_config_get_allocator (config, &allocator, NULL)) goto error_invalid_allocator; - if (gst_video_info_changed (&priv->allocation_vinfo, &new_vip)) + if (gst_video_info_changed (&priv->allocation_vinfo, &new_allocation_vinfo)) gst_object_replace ((GstObject **) & priv->allocator, NULL); - priv->allocation_vinfo = new_vip; + priv->allocation_vinfo = new_allocation_vinfo; { guint surface_alloc_flags; gboolean vinfo_changed = FALSE; if (allocator) { - const GstVideoInfo *alloc_vinfo = + allocator_vinfo = gst_allocator_get_vaapi_video_info (allocator, &surface_alloc_flags); - vinfo_changed = gst_video_info_changed (alloc_vinfo, &new_vip); + vinfo_changed = + gst_video_info_changed (allocator_vinfo, &new_allocation_vinfo); } if (vinfo_changed && allocator && priv->use_dmabuf_memory) { - gst_allocator_set_vaapi_video_info (allocator, &new_vip, + gst_allocator_set_vaapi_video_info (allocator, &new_allocation_vinfo, surface_alloc_flags); } else if (!priv->use_dmabuf_memory && (vinfo_changed || !allocator)) { /* let's destroy the other allocator and create a new one */ - allocator = gst_vaapi_video_allocator_new (priv->display, &new_vip, - surface_alloc_flags, 0); + allocator = gst_vaapi_video_allocator_new (priv->display, + &new_allocation_vinfo, surface_alloc_flags, 0); gst_buffer_pool_config_set_allocator (config, allocator, NULL); gst_object_unref (allocator); } @@ -196,10 +197,11 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, gst_object_unref (priv->allocator); if ((priv->allocator = allocator)) gst_object_ref (allocator); - alloc_vip = gst_allocator_get_vaapi_video_info (priv->allocator, NULL); - if (!alloc_vip) + allocator_vinfo = + gst_allocator_get_vaapi_video_info (priv->allocator, NULL); + if (!allocator_vinfo) goto error_create_allocator_info; - priv->vmeta_vinfo = *alloc_vip; + priv->vmeta_vinfo = *allocator_vinfo; } if (GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo) != size) { gst_buffer_pool_config_set_params (config, caps, From 36cf510ce8b197bdf2f33af630e7a9e04e103d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 8 Jun 2017 19:32:35 +0200 Subject: [PATCH 2802/3781] vaapivideomemory: rename qdata quarks and ids Also the parameter names were renamed to reflect their origin and purpose. https://bugzilla.gnome.org/show_bug.cgi?id=783599 --- gst/vaapi/gstvaapivideomemory.c | 42 +++++++++++++++++++-------------- gst/vaapi/gstvaapivideomemory.h | 2 +- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index c37985b03e..17c7a0dad9 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1159,27 +1159,27 @@ gst_vaapi_video_info_quark_get (void) return g_quark; } -#define INFO_QUARK info_quark_get () +#define ALLOCATION_VINFO_QUARK allocation_vinfo_quark_get () static GQuark -info_quark_get (void) +allocation_vinfo_quark_get (void) { static gsize g_quark; if (g_once_init_enter (&g_quark)) { - gsize quark = (gsize) g_quark_from_static_string ("info"); + gsize quark = (gsize) g_quark_from_static_string ("allocation-vinfo"); g_once_init_leave (&g_quark, quark); } return g_quark; } -#define FLAGS_QUARK flags_quark_get () +#define SURFACE_ALLOC_FLAGS_QUARK surface_alloc_flags_quark_get () static GQuark -flags_quark_get (void) +surface_alloc_flags_quark_get (void) { static gsize g_quark; if (g_once_init_enter (&g_quark)) { - gsize quark = (gsize) g_quark_from_static_string ("flags"); + gsize quark = (gsize) g_quark_from_static_string ("surface-alloc-flags"); g_once_init_leave (&g_quark, quark); } return g_quark; @@ -1188,10 +1188,14 @@ flags_quark_get (void) /** * gst_allocator_get_vaapi_video_info: * @allocator: a #GstAllocator - * @out_flags_ptr: (out): the stored flags + * @out_flags_ptr: (out): the stored surface allocation flags * * Will get the @allocator qdata to fetch the flags and the - * #GstVideoInfo stored in it. + * allocation's #GstVideoInfo stored in it. + * + * The allocation video info, is the image video info in the case of + * the #GstVaapiVideoAllocator; and the allocation video info in the + * case of #GstVaapiDmaBufAllocator. * * Returns: the stored #GstVideoInfo **/ @@ -1210,13 +1214,13 @@ gst_allocator_get_vaapi_video_info (GstAllocator * allocator, return NULL; if (out_flags_ptr) { - value = gst_structure_id_get_value (structure, FLAGS_QUARK); + value = gst_structure_id_get_value (structure, SURFACE_ALLOC_FLAGS_QUARK); if (!value) return NULL; *out_flags_ptr = g_value_get_uint (value); } - value = gst_structure_id_get_value (structure, INFO_QUARK); + value = gst_structure_id_get_value (structure, ALLOCATION_VINFO_QUARK); if (!value) return NULL; return g_value_get_boxed (value); @@ -1225,24 +1229,26 @@ gst_allocator_get_vaapi_video_info (GstAllocator * allocator, /** * gst_allocator_set_vaapi_video_info: * @allocator: a #GstAllocator - * @vip: the #GstVideoInfo to store - * @flags: the flags to store + * @alloc_info: the allocation #GstVideoInfo to store + * @surface_alloc_flags: the flags to store * - * Stores as GObject's qdata the @vip and the @flags in the - * allocator. This will "decorate" the allocator as a GstVaapi one. + * Stores as GObject's qdata the @alloc_info and the + * @surface_alloc_flags in the allocator. This will "decorate" the + * allocator as a GstVaapi one. * * Returns: always %TRUE **/ gboolean gst_allocator_set_vaapi_video_info (GstAllocator * allocator, - const GstVideoInfo * vip, guint flags) + const GstVideoInfo * alloc_info, guint surface_alloc_flags) { g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), FALSE); - g_return_val_if_fail (vip != NULL, FALSE); + g_return_val_if_fail (alloc_info != NULL, FALSE); g_object_set_qdata_full (G_OBJECT (allocator), GST_VAAPI_VIDEO_INFO_QUARK, - gst_structure_new_id (GST_VAAPI_VIDEO_INFO_QUARK, INFO_QUARK, - GST_TYPE_VIDEO_INFO, vip, FLAGS_QUARK, G_TYPE_UINT, flags, NULL), + gst_structure_new_id (GST_VAAPI_VIDEO_INFO_QUARK, + ALLOCATION_VINFO_QUARK, GST_TYPE_VIDEO_INFO, alloc_info, + SURFACE_ALLOC_FLAGS_QUARK, G_TYPE_UINT, surface_alloc_flags, NULL), (GDestroyNotify) gst_structure_free); return TRUE; diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 342ca65802..47c72eb67e 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -276,7 +276,7 @@ gst_allocator_get_vaapi_video_info (GstAllocator * allocator, G_GNUC_INTERNAL gboolean gst_allocator_set_vaapi_video_info (GstAllocator * allocator, - const GstVideoInfo * vip, guint flags); + const GstVideoInfo * alloc_info, guint surface_alloc_flags); G_GNUC_INTERNAL gboolean From 7a20692364b67809e2a77769fe591557f445c170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 9 Jun 2017 13:05:36 +0200 Subject: [PATCH 2803/3781] plugins: distinguish allocation and negotiation caps The vaapi video decoders might have different allocation caps from the negotiation caps, thus the GstVideoMeta shall use the negotiation caps, not the allocation caps. This was done before reusing gst_allocator_get_vaapi_video_info(), storing there the negotiation caps if they differ from the allocation ones, but this strategy felt short when the allocator had to be reset in the vaapi buffer pool, since we need both. This patch adds gst_allocator_set_vaapi_negotiated_video_info() and gst_allocator_get_vaapi_negotiated_video_info() to store the negotiated video info in the allocator, and distinguish it from the allocation video info. https://bugzilla.gnome.org/show_bug.cgi?id=783599 --- gst/vaapi/gstvaapipluginbase.c | 55 ++++++++++++++--------------- gst/vaapi/gstvaapivideobufferpool.c | 23 ++++++------ gst/vaapi/gstvaapivideomemory.c | 51 ++++++++++++++++++++++++++ gst/vaapi/gstvaapivideomemory.h | 9 +++++ 4 files changed, 98 insertions(+), 40 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 8c2b84aa50..e7270b8cdd 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -567,24 +567,10 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, GstCaps * caps) { gboolean different_caps; - GstVideoInfo vi; GstVaapiImageUsageFlags usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; - /* the received caps are the "allocation caps" which may be - * different from the "negotiation caps". In this case, we should - * indicate the allocator to store the negotiation caps since they - * are the one should be used for frame mapping with GstVideoMeta */ - different_caps = GST_IS_VIDEO_DECODER (plugin) && plugin->srcpad_caps && - !gst_caps_is_strictly_equal (plugin->srcpad_caps, caps); - - if (different_caps) { - vi = plugin->srcpad_info; - } else { - vi = *vinfo; - } - - if (!reset_allocator (plugin->srcpad_allocator, &vi)) + if (!reset_allocator (plugin->srcpad_allocator, vinfo)) return TRUE; plugin->srcpad_allocator = NULL; @@ -609,22 +595,33 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, if (!plugin->srcpad_allocator) goto error_create_allocator; + /* the received caps are the "allocation caps" which may be + * different from the "negotiation caps". In this case, we should + * indicate the allocator to store the negotiation caps since they + * are the one should be used for frame mapping with GstVideoMeta */ + different_caps = GST_IS_VIDEO_DECODER (plugin) && plugin->srcpad_caps && + !gst_caps_is_strictly_equal (plugin->srcpad_caps, caps); + if (different_caps) { - guint i, flags = 0; - const GstVideoInfo *alloc_vi = - gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, &flags); - /* update the planes and the size with the allocator image info, - * but not the resolution */ - if (alloc_vi) { - for (i = 0; i < GST_VIDEO_INFO_N_PLANES (alloc_vi); i++) { - GST_VIDEO_INFO_PLANE_OFFSET (&vi, i) = - GST_VIDEO_INFO_PLANE_OFFSET (alloc_vi, i); - GST_VIDEO_INFO_PLANE_STRIDE (&vi, i) = - GST_VIDEO_INFO_PLANE_STRIDE (alloc_vi, i); - } - GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (alloc_vi); - gst_allocator_set_vaapi_video_info (plugin->srcpad_allocator, &vi, flags); + guint i; + GstVideoInfo vi = plugin->srcpad_info; + const GstVideoInfo *image_info = + gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, NULL); + + g_assert (image_info); /* both allocators should set its video + * info */ + + /* update the planes and the size with the allocator image/surface + * info, but not the resolution */ + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (image_info); i++) { + GST_VIDEO_INFO_PLANE_OFFSET (&vi, i) = + GST_VIDEO_INFO_PLANE_OFFSET (image_info, i); + GST_VIDEO_INFO_PLANE_STRIDE (&vi, i) = + GST_VIDEO_INFO_PLANE_STRIDE (image_info, i); } + GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (image_info); + gst_allocator_set_vaapi_negotiated_video_info (plugin->srcpad_allocator, + &vi); } return TRUE; diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index f0b6ec4c06..c1c4fba1a6 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -137,6 +137,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, GstCaps *caps; GstVideoInfo new_allocation_vinfo; const GstVideoInfo *allocator_vinfo; + const GstVideoInfo *negotiated_vinfo; GstVideoAlignment align; GstAllocator *allocator; gboolean ret, updated = FALSE; @@ -176,9 +177,16 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, gst_allocator_set_vaapi_video_info (allocator, &new_allocation_vinfo, surface_alloc_flags); } else if (!priv->use_dmabuf_memory && (vinfo_changed || !allocator)) { + negotiated_vinfo = + gst_allocator_get_vaapi_negotiated_video_info (allocator); + /* let's destroy the other allocator and create a new one */ allocator = gst_vaapi_video_allocator_new (priv->display, &new_allocation_vinfo, surface_alloc_flags, 0); + if (negotiated_vinfo) { + gst_allocator_set_vaapi_negotiated_video_info (allocator, + negotiated_vinfo); + } gst_buffer_pool_config_set_allocator (config, allocator, NULL); gst_object_unref (allocator); } @@ -197,11 +205,10 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, gst_object_unref (priv->allocator); if ((priv->allocator = allocator)) gst_object_ref (allocator); - allocator_vinfo = - gst_allocator_get_vaapi_video_info (priv->allocator, NULL); - if (!allocator_vinfo) - goto error_create_allocator_info; - priv->vmeta_vinfo = *allocator_vinfo; + negotiated_vinfo = + gst_allocator_get_vaapi_negotiated_video_info (priv->allocator); + priv->vmeta_vinfo = (negotiated_vinfo) ? + *negotiated_vinfo : priv->allocation_vinfo; } if (GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo) != size) { gst_buffer_pool_config_set_params (config, caps, @@ -273,12 +280,6 @@ error_no_vaapi_video_meta_option: GST_ERROR_OBJECT (pool, "no GstVaapiVideoMeta option in config"); return FALSE; } -error_create_allocator_info: - { - GST_ERROR_OBJECT (pool, - "failed to create GstVaapiVideoAllocator `video-info'"); - return FALSE; - } error_no_allocator: { GST_ERROR_OBJECT (pool, "no allocator defined"); diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 17c7a0dad9..6b26d02ac3 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1185,6 +1185,19 @@ surface_alloc_flags_quark_get (void) return g_quark; } +#define NEGOTIATED_VINFO_QUARK negotiated_vinfo_quark_get () +static GQuark +negotiated_vinfo_quark_get (void) +{ + static gsize g_quark; + + if (g_once_init_enter (&g_quark)) { + gsize quark = (gsize) g_quark_from_static_string ("negotiated-vinfo"); + g_once_init_leave (&g_quark, quark); + } + return g_quark; +} + /** * gst_allocator_get_vaapi_video_info: * @allocator: a #GstAllocator @@ -1254,6 +1267,44 @@ gst_allocator_set_vaapi_video_info (GstAllocator * allocator, return TRUE; } +/** + * gst_allocator_set_vaapi_negotiated_video_info: + * @allocator: a #GstAllocator + * @negotiated_vinfo: the negotiated #GstVideoInfo to store + * + * Stores as GObject's qdata the @negotiated_vinfo in the allocator + * instance. + * + * The @negotiated_vinfo is different of the @alloc_info from + * gst_allocator_set_vaapi_video_info(), and might not be set. + **/ +void +gst_allocator_set_vaapi_negotiated_video_info (GstAllocator * allocator, + const GstVideoInfo * negotiated_vinfo) +{ + g_return_if_fail (allocator && GST_IS_ALLOCATOR (allocator)); + g_return_if_fail (negotiated_vinfo); + + g_object_set_qdata_full (G_OBJECT (allocator), NEGOTIATED_VINFO_QUARK, + gst_video_info_copy (negotiated_vinfo), + (GDestroyNotify) gst_video_info_free); +} + +/** + * gst_allocator_get_vaapi_negotiated_video_info: + * @allocator: a #GstAllocator + * + * Returns: the stored negotiation #GstVideoInfo, if it was stored + * previously. Otherwise, %NULL + **/ +GstVideoInfo * +gst_allocator_get_vaapi_negotiated_video_info (GstAllocator * allocator) +{ + g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), NULL); + + return g_object_get_qdata (G_OBJECT (allocator), NEGOTIATED_VINFO_QUARK); +} + /** * gst_vaapi_is_dmabuf_allocator: * @allocator: an #GstAllocator diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 47c72eb67e..dcc998d456 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -278,6 +278,15 @@ gboolean gst_allocator_set_vaapi_video_info (GstAllocator * allocator, const GstVideoInfo * alloc_info, guint surface_alloc_flags); +G_GNUC_INTERNAL +void +gst_allocator_set_vaapi_negotiated_video_info (GstAllocator * allocator, + const GstVideoInfo * negotiated_vinfo); + +G_GNUC_INTERNAL +GstVideoInfo * +gst_allocator_get_vaapi_negotiated_video_info (GstAllocator * allocator); + G_GNUC_INTERNAL gboolean gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator); From 60158c3d6bcf24c89ffa61b2678e91cf17dac359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 9 Jun 2017 15:02:08 +0200 Subject: [PATCH 2804/3781] vaapivideobufferpool: refactor set_config() Refactor the set_config() virtual method considering a cleaner approach to allocator instanciation, if it it not set or if it is not valid for the pool. https://bugzilla.gnome.org/show_bug.cgi?id=783599 --- gst/vaapi/gstvaapivideobufferpool.c | 110 +++++++++++++++++----------- 1 file changed, 66 insertions(+), 44 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index c1c4fba1a6..a2eae83650 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -142,6 +142,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, GstAllocator *allocator; gboolean ret, updated = FALSE; guint size, min_buffers, max_buffers; + guint surface_alloc_flags; GST_DEBUG_OBJECT (pool, "config %" GST_PTR_FORMAT, config); @@ -158,62 +159,83 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, if (!gst_buffer_pool_config_get_allocator (config, &allocator, NULL)) goto error_invalid_allocator; - if (gst_video_info_changed (&priv->allocation_vinfo, &new_allocation_vinfo)) + /* it is a valid allocator? */ + if (allocator + && (g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) != 0 + && g_strcmp0 (allocator->mem_type, + GST_VAAPI_DMABUF_ALLOCATOR_NAME) != 0)) + allocator = NULL; + + /* get the allocator properties */ + if (allocator) { + priv->use_dmabuf_memory = gst_vaapi_is_dmabuf_allocator (allocator); + negotiated_vinfo = + gst_allocator_get_vaapi_negotiated_video_info (allocator); + allocator_vinfo = + gst_allocator_get_vaapi_video_info (allocator, &surface_alloc_flags); + } else { + priv->use_dmabuf_memory = FALSE; + negotiated_vinfo = NULL; + allocator_vinfo = NULL; + surface_alloc_flags = 0; + } + + /* reset or update the allocator if video resolution changed */ + if (gst_video_info_changed (&priv->allocation_vinfo, &new_allocation_vinfo) + || gst_video_info_changed (allocator_vinfo, &new_allocation_vinfo)) { gst_object_replace ((GstObject **) & priv->allocator, NULL); - priv->allocation_vinfo = new_allocation_vinfo; - { - guint surface_alloc_flags; - gboolean vinfo_changed = FALSE; - - if (allocator) { - allocator_vinfo = - gst_allocator_get_vaapi_video_info (allocator, &surface_alloc_flags); - vinfo_changed = - gst_video_info_changed (allocator_vinfo, &new_allocation_vinfo); - } - - if (vinfo_changed && allocator && priv->use_dmabuf_memory) { + if (allocator && priv->use_dmabuf_memory) { gst_allocator_set_vaapi_video_info (allocator, &new_allocation_vinfo, surface_alloc_flags); - } else if (!priv->use_dmabuf_memory && (vinfo_changed || !allocator)) { - negotiated_vinfo = - gst_allocator_get_vaapi_negotiated_video_info (allocator); - - /* let's destroy the other allocator and create a new one */ - allocator = gst_vaapi_video_allocator_new (priv->display, - &new_allocation_vinfo, surface_alloc_flags, 0); - if (negotiated_vinfo) { - gst_allocator_set_vaapi_negotiated_video_info (allocator, - negotiated_vinfo); - } - gst_buffer_pool_config_set_allocator (config, allocator, NULL); - gst_object_unref (allocator); + } else { + allocator = NULL; } } + priv->allocation_vinfo = new_allocation_vinfo; if (!gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) goto error_no_vaapi_video_meta_option; - /* not our allocator, not our buffers */ - if (allocator) { - priv->use_dmabuf_memory = gst_vaapi_is_dmabuf_allocator (allocator); - if (priv->use_dmabuf_memory || - g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) == 0) { - if (priv->allocator) - gst_object_unref (priv->allocator); - if ((priv->allocator = allocator)) - gst_object_ref (allocator); - negotiated_vinfo = - gst_allocator_get_vaapi_negotiated_video_info (priv->allocator); - priv->vmeta_vinfo = (negotiated_vinfo) ? - *negotiated_vinfo : priv->allocation_vinfo; + /* create a new allocator if needed */ + if (!allocator) { + if (priv->use_dmabuf_memory) { + allocator = gst_vaapi_dmabuf_allocator_new (priv->display, + &new_allocation_vinfo, /* FIXME: */ 0, GST_PAD_SRC); + } else { + allocator = gst_vaapi_video_allocator_new (priv->display, + &new_allocation_vinfo, surface_alloc_flags, 0); } + + if (!allocator) + goto error_no_allocator; + + if (negotiated_vinfo) { + gst_allocator_set_vaapi_negotiated_video_info (allocator, + negotiated_vinfo); + } + + GST_INFO_OBJECT (pool, "created new allocator %" GST_PTR_FORMAT, allocator); + gst_buffer_pool_config_set_allocator (config, allocator, NULL); + gst_object_unref (allocator); + } + + /* use the allocator and set the video info for the vmeta */ + if (allocator) { + if (priv->allocator) + gst_object_unref (priv->allocator); + if ((priv->allocator = allocator)) + gst_object_ref (allocator); + + negotiated_vinfo = + gst_allocator_get_vaapi_negotiated_video_info (priv->allocator); + priv->vmeta_vinfo = (negotiated_vinfo) ? + *negotiated_vinfo : priv->allocation_vinfo; + if (GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo) != size) { gst_buffer_pool_config_set_params (config, caps, - GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo), min_buffers, - max_buffers); + GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo), min_buffers, max_buffers); } } if (!priv->allocator) @@ -221,9 +243,9 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, priv->options = 0; if (gst_buffer_pool_config_has_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_META)) + GST_BUFFER_POOL_OPTION_VIDEO_META)) { priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; - else { + } else { gint i; for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&priv->allocation_vinfo); i++) { if (GST_VIDEO_INFO_PLANE_OFFSET (&priv->allocation_vinfo, i) != From bd0209228bfb47c25631cc25459ac226ecc174f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 9 Jun 2017 17:00:40 +0200 Subject: [PATCH 2805/3781] vaapivideobufferpool: remove allocation_vinfo private attribute There is no need to keep this attribute internally since it is already managed by the allocator. https://bugzilla.gnome.org/show_bug.cgi?id=783599 --- gst/vaapi/gstvaapivideobufferpool.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index a2eae83650..7a1fc93f4f 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -44,7 +44,6 @@ enum struct _GstVaapiVideoBufferPoolPrivate { - GstVideoInfo allocation_vinfo; GstAllocator *allocator; GstVideoInfo vmeta_vinfo; GstVaapiDisplay *display; @@ -181,8 +180,8 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, } /* reset or update the allocator if video resolution changed */ - if (gst_video_info_changed (&priv->allocation_vinfo, &new_allocation_vinfo) - || gst_video_info_changed (allocator_vinfo, &new_allocation_vinfo)) { + if (allocator_vinfo + && gst_video_info_changed (allocator_vinfo, &new_allocation_vinfo)) { gst_object_replace ((GstObject **) & priv->allocator, NULL); if (allocator && priv->use_dmabuf_memory) { @@ -192,7 +191,6 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, allocator = NULL; } } - priv->allocation_vinfo = new_allocation_vinfo; if (!gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) @@ -231,7 +229,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, negotiated_vinfo = gst_allocator_get_vaapi_negotiated_video_info (priv->allocator); priv->vmeta_vinfo = (negotiated_vinfo) ? - *negotiated_vinfo : priv->allocation_vinfo; + *negotiated_vinfo : new_allocation_vinfo; if (GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo) != size) { gst_buffer_pool_config_set_params (config, caps, @@ -247,10 +245,10 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; } else { gint i; - for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&priv->allocation_vinfo); i++) { - if (GST_VIDEO_INFO_PLANE_OFFSET (&priv->allocation_vinfo, i) != + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&new_allocation_vinfo); i++) { + if (GST_VIDEO_INFO_PLANE_OFFSET (&new_allocation_vinfo, i) != GST_VIDEO_INFO_PLANE_OFFSET (&priv->vmeta_vinfo, i) || - GST_VIDEO_INFO_PLANE_STRIDE (&priv->allocation_vinfo, i) != + GST_VIDEO_INFO_PLANE_STRIDE (&new_allocation_vinfo, i) != GST_VIDEO_INFO_PLANE_STRIDE (&priv->vmeta_vinfo, i)) { priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; gst_buffer_pool_config_add_option (config, @@ -525,8 +523,6 @@ gst_vaapi_video_buffer_pool_init (GstVaapiVideoBufferPool * pool) GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE (pool); pool->priv = priv; - - gst_video_info_init (&priv->allocation_vinfo); } GstBufferPool * From 3dce250236c06e6a078ff04a840be2482c6f6d43 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 31 May 2017 12:36:17 +0900 Subject: [PATCH 2806/3781] libs: encoder: h264: changes raw number of profile to macro name of its Changes raw number of profile to macro name of its to improve readability. https://bugzilla.gnome.org/show_bug.cgi?id=757941 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index fb3dab920a..969f2fdd01 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1050,13 +1050,13 @@ ensure_profile_limits (GstVaapiEncoderH264 * encoder) profile = GST_VAAPI_PROFILE_UNKNOWN; /* Try Main profile coding tools */ - if (encoder->max_profile_idc < 100) { + if (encoder->max_profile_idc < GST_H264_PROFILE_HIGH) { encoder->use_dct8x8 = FALSE; profile = GST_VAAPI_PROFILE_H264_MAIN; } /* Try Constrained Baseline profile coding tools */ - if (encoder->max_profile_idc < 77) { + if (encoder->max_profile_idc < GST_H264_PROFILE_MAIN) { encoder->num_bframes = 0; encoder->use_cabac = FALSE; profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; @@ -1151,14 +1151,15 @@ ensure_tuning_high_compression (GstVaapiEncoderH264 * encoder) profile_idc = encoder->max_profile_idc; /* Tuning options to enable Main profile */ - if (profile_idc >= 77 && profile_idc != 88) { + if (profile_idc >= GST_H264_PROFILE_MAIN + && profile_idc != GST_H264_PROFILE_EXTENDED) { encoder->use_cabac = TRUE; if (!encoder->num_bframes) encoder->num_bframes = 1; } /* Tuning options to enable High profile */ - if (profile_idc >= 100) { + if (profile_idc >= GST_H264_PROFILE_HIGH) { encoder->use_dct8x8 = TRUE; } return TRUE; From eee8a781735bfa1a69f35631bf907aaa7b5deec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Apr 2017 19:35:27 +0200 Subject: [PATCH 2807/3781] libs: encoder: log out the name of the profile Instead of printing a number, it is more readable to log out, in case of error, the name of the failing profile. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 3 ++- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 3 ++- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 3 ++- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 3 ++- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 3 ++- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 969f2fdd01..b76ccb63c1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1030,7 +1030,8 @@ ensure_hw_profile (GstVaapiEncoderH264 * encoder) /* ERRORS */ error_unsupported_profile: { - GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile); + GST_ERROR ("unsupported HW profile %s", + gst_vaapi_profile_get_name (encoder->profile)); return FALSE; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index b8cd97cbfa..7bcb54f3f6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -907,7 +907,8 @@ ensure_hw_profile (GstVaapiEncoderH265 * encoder) /* ERRORS */ error_unsupported_profile: { - GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile); + GST_ERROR ("unsupported HW profile %s", + gst_vaapi_profile_get_name (encoder->profile)); return FALSE; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index b335d9782e..73bee563ee 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -168,7 +168,8 @@ ensure_hw_profile (GstVaapiEncoderJpeg * encoder) /* ERRORS */ error_unsupported_profile: { - GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile); + GST_ERROR ("unsupported HW profile %s", + gst_vaapi_profile_get_name (encoder->profile)); return FALSE; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index ab074071d2..04fbd0dccb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -103,7 +103,8 @@ ensure_hw_profile (GstVaapiEncoderMpeg2 * encoder) /* ERRORS */ error_unsupported_profile: { - GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile); + GST_ERROR ("unsupported HW profile %s", + gst_vaapi_profile_get_name (encoder->profile)); return FALSE; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 9357527766..a448df8e3f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -113,7 +113,8 @@ ensure_hw_profile (GstVaapiEncoderVP8 * encoder) /* ERRORS */ error_unsupported_profile: { - GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile); + GST_ERROR ("unsupported HW profile %s", + gst_vaapi_profile_get_name (encoder->profile)); return FALSE; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 35b4f7e6cf..80de4b039d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -187,7 +187,8 @@ ensure_hw_profile (GstVaapiEncoderVP9 * encoder) /* ERRORS */ error_unsupported_profile: { - GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile); + GST_ERROR ("unsupported HW profile %s", + gst_vaapi_profile_get_name (encoder->profile)); return FALSE; } } From 595f8b7d4baf118eb6b7bf0efbcf02ce0fead225 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 9 Jun 2017 14:02:20 -0700 Subject: [PATCH 2808/3781] libs: encoder: Fix the quality level clamping Change the hard-coded range of quality-level from {1-8} to {1-7}, since it is the range Intel Open source driver supports. Also perform the range clamping only if the user provided quality-level is greater than the max-range suppored by the driver, because there could be non-intel drivers giving lower value than the hard-coded max value 7. https://bugzilla.gnome.org/show_bug.cgi?id=783567 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index fb2d5dd8b7..4aeccc5b7e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -188,9 +188,10 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_PROP_QUALITY_LEVEL, g_param_spec_uint ("quality-level", - "Quality Level", - "Encoding Quality Level ", 1, 8, - 4, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Quality Level", "Encoding Quality Level " + "(lower value means higher-quality/slow-encode, " + " higher value means lower-quality/fast-encode)", + 1, 7, 4, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); return props; } @@ -840,8 +841,7 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) if (get_config_attribute (encoder, VAConfigAttribEncQualityRange, &quality_level_max) && quality_level_max > 0) { GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder) = - gst_util_uint64_scale_int_ceil (GST_VAAPI_ENCODER_QUALITY_LEVEL - (encoder), quality_level_max, 8); + CLAMP (GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder), 1, quality_level_max); } else { GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder) = 0; } From 3ed2023c2ce2df591bf149e9a2e680fd7be5fa5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 15 Jun 2017 13:24:56 +0200 Subject: [PATCH 2809/3781] libs: encoder: fix compilation with old versions of libva There are some symbols that are not used when compiling with old version of libva and those generates a compilation error. Original-patch-by: Matt Staples --- gst-libs/gst/vaapi/gstvaapiencoder.c | 5 ++++- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 4aeccc5b7e..bdb8d9ef49 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -803,8 +803,11 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); GstVaapiEncoderStatus status; GstVaapiVideoPool *pool; - guint codedbuf_size, target_percentage, quality_level_max = 0; + guint codedbuf_size, target_percentage; guint fps_d, fps_n; +#if VA_CHECK_VERSION(0,36,0) + guint quality_level_max = 0; +#endif fps_d = GST_VIDEO_INFO_FPS_D (vip); fps_n = GST_VIDEO_INFO_FPS_N (vip); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index b76ccb63c1..42a05db3a5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2179,8 +2179,10 @@ static gboolean ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); +#if VA_CHECK_VERSION(0,39,1) GstVaapiEncMiscParam *misc; guint num_roi; +#endif if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture)) return FALSE; @@ -2203,11 +2205,10 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) goto error_create_packed_sei_hdr; } } - +#if VA_CHECK_VERSION(0,39,1) /* region-of-interest params */ num_roi = base_encoder->roi_regions ? g_list_length (base_encoder->roi_regions) : 0; -#if VA_CHECK_VERSION(0,39,1) if (num_roi > 0) { /* ROI(Region of Interest) params */ VAEncMiscParameterBufferROI *roi_param; From 9397cd7d4d487141346dbe28e1c21897960862b0 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 14 Jun 2017 21:40:33 +0900 Subject: [PATCH 2810/3781] libs: decoder: h264: initialize active_sps/pps in reset Since commits in https://bugzilla.gnome.org/show_bug.cgi?id=781142 landed, they introduced regression in seek. Formerly, once seek is done, decoder drops P-frames until I-frame arrives. But since the commits landed, it doesn't drop P-frame and does try to decode it continuously because active_sps is still alive. See ensure_sps function. But there are prev_frames and prev_ref_frames reset already, then it causes assertion. So it's necessary to reset active_sps/pps also in reset method. https://bugzilla.gnome.org/show_bug.cgi?id=783726 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index b97c5506e3..678e952f4c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1278,6 +1278,8 @@ gst_vaapi_decoder_h264_reset (GstVaapiDecoder * base_decoder) g_free (priv->prev_frames); priv->prev_frames = NULL; priv->prev_frames_alloc = 0; + gst_vaapi_parser_info_h264_replace (&priv->active_pps, NULL); + gst_vaapi_parser_info_h264_replace (&priv->active_sps, NULL); priv->profile = GST_VAAPI_PROFILE_UNKNOWN; priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD; From 05a41009f21678eb4c416fa450668bd50894df02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 23 Jun 2017 14:38:10 +0200 Subject: [PATCH 2811/3781] plugins: update buffer size with the one reported by allocator There is a regression in 7a206923, since the buffer pool ditches all the buffers generated by them because the pool config size is different of the buffer's size. Test pipeline: gst-launch-1.0 filesrc location=big_buck_bunny_1080p_h264.mov \ ! qtdemux ! vaapih264dec ! vaapipostproc ! xvimagesink \ --gst-debug=GST_PERFORMANCE:5 The allocator may update the buffer size according to the VA surface properties. In order to do this, the video info is modified when the allocator is created, which reports through the allocation info the updated size, and set it to the pool config. --- gst/vaapi/gstvaapipluginbase.c | 32 +++++++++++++++++++++-------- gst/vaapi/gstvaapivideobufferpool.c | 6 ++++-- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e7270b8cdd..d2b7dbc5b7 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -498,16 +498,15 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, guint * size) { GstVideoInfo vinfo; + const GstVideoInfo *image_info; GstVaapiImageUsageFlags usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; if (!gst_video_info_from_caps (&vinfo, caps)) goto error_invalid_caps; - gst_video_info_force_nv12_if_encoded (&vinfo); - *size = GST_VIDEO_INFO_SIZE (&vinfo); if (!reset_allocator (plugin->sinkpad_allocator, &vinfo)) - return TRUE; + goto bail; if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) { plugin->sinkpad_allocator = @@ -527,6 +526,14 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, bail: if (!plugin->sinkpad_allocator) goto error_create_allocator; + + image_info = + gst_allocator_get_vaapi_video_info (plugin->sinkpad_allocator, NULL); + g_assert (image_info); /* allocator ought set its image info */ + + /* update the size with the one generated by the allocator */ + *size = GST_VIDEO_INFO_SIZE (image_info); + return TRUE; /* ERRORS */ @@ -567,11 +574,12 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, GstCaps * caps) { gboolean different_caps; + const GstVideoInfo *image_info; GstVaapiImageUsageFlags usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; if (!reset_allocator (plugin->srcpad_allocator, vinfo)) - return TRUE; + goto valid_allocator; plugin->srcpad_allocator = NULL; if (caps && gst_caps_is_video_raw (caps)) { @@ -595,6 +603,15 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, if (!plugin->srcpad_allocator) goto error_create_allocator; +valid_allocator: + image_info = + gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, NULL); + g_assert (image_info); /* both allocators ought set its image + * info */ + + /* update the size with the one generated by the allocator */ + GST_VIDEO_INFO_SIZE (vinfo) = GST_VIDEO_INFO_SIZE (image_info); + /* the received caps are the "allocation caps" which may be * different from the "negotiation caps". In this case, we should * indicate the allocator to store the negotiation caps since they @@ -605,11 +622,6 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, if (different_caps) { guint i; GstVideoInfo vi = plugin->srcpad_info; - const GstVideoInfo *image_info = - gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, NULL); - - g_assert (image_info); /* both allocators should set its video - * info */ /* update the planes and the size with the allocator image/surface * info, but not the resolution */ @@ -934,6 +946,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (!pool) { if (!ensure_srcpad_allocator (plugin, &vi, caps)) goto error; + size = GST_VIDEO_INFO_SIZE (&vi); /* size might be updated by + * allocator */ pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, min, max, pool_options, plugin->srcpad_allocator); if (!pool) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 7a1fc93f4f..b14bd68108 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -231,9 +231,11 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, priv->vmeta_vinfo = (negotiated_vinfo) ? *negotiated_vinfo : new_allocation_vinfo; - if (GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo) != size) { + /* last resource to set the correct buffer size */ + allocator_vinfo = gst_allocator_get_vaapi_video_info (allocator, NULL); + if (GST_VIDEO_INFO_SIZE (allocator_vinfo) != size) { gst_buffer_pool_config_set_params (config, caps, - GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo), min_buffers, max_buffers); + GST_VIDEO_INFO_SIZE (allocator_vinfo), min_buffers, max_buffers); } } if (!priv->allocator) From 7d7f722a18912e7e8fc8a15be1f49b41ccc73669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 23 Jun 2017 17:33:03 +0200 Subject: [PATCH 2812/3781] vaapivideobufferpool: fix regression with video metas There is another regression with 7a206923 when setting the video info for the video meta, it should be the one from the image's allocator rather from the allocation caps. Test pipeline: gst-launch-1.0 filesrc location=bug766184.flv ! decodebin \ ! tee ! videoconvert ! videoscale \ ! video/x-raw, width=1920, height=1080 ! xvimagesink --- gst/vaapi/gstvaapivideobufferpool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index b14bd68108..dcdc29e9f9 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -228,11 +228,11 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, negotiated_vinfo = gst_allocator_get_vaapi_negotiated_video_info (priv->allocator); + allocator_vinfo = gst_allocator_get_vaapi_video_info (allocator, NULL); priv->vmeta_vinfo = (negotiated_vinfo) ? - *negotiated_vinfo : new_allocation_vinfo; + *negotiated_vinfo : *allocator_vinfo; /* last resource to set the correct buffer size */ - allocator_vinfo = gst_allocator_get_vaapi_video_info (allocator, NULL); if (GST_VIDEO_INFO_SIZE (allocator_vinfo) != size) { gst_buffer_pool_config_set_params (config, caps, GST_VIDEO_INFO_SIZE (allocator_vinfo), min_buffers, max_buffers); From 5312923d1c0ad7d63b12bb2f5e60a57ae43dde1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 8 Jun 2016 19:11:15 +0200 Subject: [PATCH 2813/3781] vaapivideomemory: add gst_vaapi_dmabuf_can_map() This new method checks the specified allocator can create GstMemory that can be mapped. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapivideomemory.c | 47 +++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapivideomemory.h | 4 +++ 2 files changed, 51 insertions(+) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 6b26d02ac3..3d00e8dd1f 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1327,3 +1327,50 @@ gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator) st = g_object_get_qdata (G_OBJECT (allocator), GST_VAAPI_VIDEO_INFO_QUARK); return (st != NULL); } + +/** + * gst_vaapi_dmabuf_can_map: + * @display: a #GstVaapiDisplay + * @allocator: a #GstAllocator + * + * It will create a dmabuf-based buffer using @allocator, and it will + * try to map it using gst_memory_map(). + * + * Returns: %TRUE if the internal dummy buffer can be + * mapped. Otherwise %FALSE. + **/ +gboolean +gst_vaapi_dmabuf_can_map (GstVaapiDisplay * display, GstAllocator * allocator) +{ + GstVaapiVideoMeta *meta; + GstMemory *mem; + GstMapInfo info; + gboolean ret; + + g_return_val_if_fail (display != NULL, FALSE); + + ret = FALSE; + mem = NULL; + meta = NULL; + if (!gst_vaapi_is_dmabuf_allocator (allocator)) + return FALSE; + meta = gst_vaapi_video_meta_new (display); + if (!meta) + return FALSE; + mem = gst_vaapi_dmabuf_memory_new (allocator, meta); + if (!mem) + goto bail; + + if (!gst_memory_map (mem, &info, GST_MAP_READWRITE) || info.size == 0) + goto bail; + + gst_memory_unmap (mem, &info); + ret = TRUE; + +bail: + if (mem) + gst_memory_unref (mem); + if (meta) + gst_vaapi_video_meta_unref (meta); + return ret; +} diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index dcc998d456..db31b69613 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -291,6 +291,10 @@ G_GNUC_INTERNAL gboolean gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator); +G_GNUC_INTERNAL +gboolean +gst_vaapi_dmabuf_can_map (GstVaapiDisplay * display, GstAllocator * allocator); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_MEMORY_H */ From f578515988ecf6c0ebaf920a94ea43b3fcf5c2a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 1 Jun 2017 19:13:52 +0200 Subject: [PATCH 2814/3781] vaapipluginbase: dmabuf memory map trial for raw caps Only push dmabuf-based buffers with raw caps if gst_memory_map() succeeds. Otherwise, use the the vaapi surfaces allocator. https://bugzilla.gnome.org/show_bug.cgi?id=755072 https://bugzilla.gnome.org/show_bug.cgi?id=774649 Original-patch-by: Julien Isorce --- gst/vaapi/gstvaapipluginbase.c | 36 +++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index d2b7dbc5b7..4ef936ad76 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -569,6 +569,31 @@ get_dmabuf_surface_allocation_flags (void) return GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE; } +static inline GstAllocator * +create_dmabuf_srcpad_allocator (GstVaapiPluginBase * plugin, + GstVideoInfo * vinfo, gboolean check_for_map) +{ + GstAllocator *allocator; + + if (!GST_IS_VIDEO_DECODER (plugin) && !GST_IS_BASE_TRANSFORM (plugin)) + return NULL; + + allocator = gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo, + get_dmabuf_surface_allocation_flags (), GST_PAD_SRC); + if (!allocator || !check_for_map) + return allocator; + + /* the dmabuf allocator *must* be capable to map a buffer with raw + * caps and the there's no evidence of downstream dmabuf + * importation */ + if (!gst_vaapi_dmabuf_can_map (plugin->display, allocator)) { + GST_INFO_OBJECT (plugin, "dmabuf allocator generates unmappable buffers"); + gst_object_replace ((GstObject **) & allocator, NULL); + } + + return allocator; +} + static gboolean ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, GstCaps * caps) @@ -583,16 +608,13 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, plugin->srcpad_allocator = NULL; if (caps && gst_caps_is_video_raw (caps)) { - if (plugin->srcpad_can_dmabuf) { - if (GST_IS_VIDEO_DECODER (plugin) || GST_IS_BASE_TRANSFORM (plugin)) { - plugin->srcpad_allocator = - gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo, - get_dmabuf_surface_allocation_flags (), GST_PAD_SRC); - } - } else if (plugin->enable_direct_rendering) { + GstAllocator *allocator = create_dmabuf_srcpad_allocator (plugin, vinfo, + !plugin->srcpad_can_dmabuf); + if (!allocator && plugin->enable_direct_rendering) { usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); } + plugin->srcpad_allocator = allocator; } if (!plugin->srcpad_allocator) { From 953afe9d17ab6686c93258bf1b469dff3150495e Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Tue, 22 Nov 2016 23:26:05 +0000 Subject: [PATCH 2815/3781] vaapipluginutil: add support for DMABuf caps feature https://bugzilla.gnome.org/show_bug.cgi?id=755072 Signed-off-by: Julien Isorce Signed-off-by: Victor Jaquez vaapipluginutil: add support for DMABuf caps feature --- gst/vaapi/gstvaapipluginutil.c | 4 ++++ gst/vaapi/gstvaapipluginutil.h | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index b11901f824..e9ff8b6e93 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -540,6 +540,7 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstCaps * allowed_caps, guint i, j, num_structures; GstCaps *out_caps, *caps = NULL; static const guint feature_list[] = { GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE, + GST_VAAPI_CAPS_FEATURE_DMABUF, GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META, GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY, }; @@ -627,6 +628,9 @@ gst_vaapi_caps_feature_to_string (GstVaapiCapsFeature feature) case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: str = GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META; break; + case GST_VAAPI_CAPS_FEATURE_DMABUF: + str = GST_CAPS_FEATURE_MEMORY_DMABUF; + break; case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE: str = GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE; break; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 61a833558a..19053df0ce 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -66,6 +66,7 @@ typedef enum GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED, GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY, GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META, + GST_VAAPI_CAPS_FEATURE_DMABUF, GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE, } GstVaapiCapsFeature; @@ -110,6 +111,10 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps, GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") +#define GST_VAAPI_MAKE_DMABUF_CAPS \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ + GST_CAPS_FEATURE_MEMORY_DMABUF, "{ NV12, I420, YV12 }") + G_GNUC_INTERNAL gboolean gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip); From b6863e64b550af8b472eeb35520071ab7cc0d6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 23 Jun 2017 12:12:12 +0200 Subject: [PATCH 2816/3781] vaapipluginbase: force dmabuf allocator if DMABuf caps feature Instantiate all dmabuf allocator for src pad buffer pool if the src caps ask for memory:DMABuf feature. https://bugzilla.gnome.org/show_bug.cgi?id=755072 --- gst/vaapi/gstvaapipluginbase.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 4ef936ad76..6a81f37182 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -615,6 +615,12 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); } plugin->srcpad_allocator = allocator; + } else if (caps && gst_vaapi_caps_feature_contains (caps, + GST_VAAPI_CAPS_FEATURE_DMABUF)) { + plugin->srcpad_allocator = + create_dmabuf_srcpad_allocator (plugin, vinfo, FALSE); + if (!plugin->srcpad_allocator) + goto error_create_allocator; } if (!plugin->srcpad_allocator) { From 332cfe562605c3c37c32a535697b039f194311cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 1 Jun 2017 19:42:20 +0200 Subject: [PATCH 2817/3781] vaapidecode: add support for DMABuf caps feature https://bugzilla.gnome.org/show_bug.cgi?id=755072 Original-patch-by: Julien Isorce --- gst/vaapi/gstvaapidecode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1b312598f4..ea1edf8eec 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -86,7 +86,8 @@ static const char gst_vaapidecode_src_caps_str[] = #if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" #endif - GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, P010_10LE }"); + GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, P010_10LE }") ";" + GST_VAAPI_MAKE_DMABUF_CAPS; static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_STATIC_PAD_TEMPLATE( @@ -230,6 +231,8 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) gst_caps_from_string (GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS)); } #endif + out_caps = gst_caps_make_writable (out_caps); + gst_caps_append (out_caps, gst_caps_from_string (GST_VAAPI_MAKE_DMABUF_CAPS)); raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE (decode)); @@ -327,6 +330,7 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) switch (feature) { case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: + case GST_VAAPI_CAPS_FEATURE_DMABUF: case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE:{ GstStructure *structure = gst_caps_get_structure (state->caps, 0); From e7dd25ffc1601446bc3a85e07032c745e2a35f47 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Tue, 22 Nov 2016 15:52:47 +0000 Subject: [PATCH 2818/3781] vaapipostproc: add support for DMABuf caps feature https://bugzilla.gnome.org/show_bug.cgi?id=755072 Signed-off-by: Julien Isorce --- gst/vaapi/gstvaapipostproc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index d45f7ee9d7..f9a37e15b9 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -72,7 +72,8 @@ static const char gst_vaapipostproc_src_caps_str[] = GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS "; " #endif GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " - GST_CAPS_INTERLACED_MODES; + GST_CAPS_INTERLACED_MODES "; " + GST_VAAPI_MAKE_DMABUF_CAPS; /* *INDENT-ON* */ /* *INDENT-OFF* */ From e7bba345ded42edfc03ccb546836d9c42d9fd7a6 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 29 Jun 2017 12:49:24 +0900 Subject: [PATCH 2819/3781] vaapipostproc: set multivew-mode flags to src caps vaapipostproc didn't negotiate the proper multiview caps losing downstream information. This patch enables the playing of MVC encoded stream by setting the proper multiview mode/flags and views to src caps, according to sink caps. https://bugzilla.gnome.org/show_bug.cgi?id=784320 --- gst/vaapi/gstvaapipostprocutil.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 0fa474eb55..4bfc169cfa 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -551,6 +551,30 @@ overflow_error: } } +static gboolean +_set_multiview_mode (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, + GstStructure * outs) +{ + const gchar *caps_str; + + caps_str = + gst_video_multiview_mode_to_caps_string (GST_VIDEO_INFO_MULTIVIEW_MODE + (vinfo)); + if (!caps_str) + return TRUE; + + gst_structure_set (outs, "multiview-mode", G_TYPE_STRING, caps_str, + "multiview-flags", GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, + GST_VIDEO_INFO_MULTIVIEW_FLAGS (vinfo), GST_FLAG_SET_MASK_EXACT, NULL); + + if (GST_VIDEO_INFO_VIEWS (vinfo) > 1) { + gst_structure_set (outs, "views", G_TYPE_INT, GST_VIDEO_INFO_VIEWS (vinfo), + NULL); + } + + return TRUE; +} + static gboolean _set_colorimetry (GstVaapiPostproc * postproc, GstVideoFormat format, GstStructure * outs) @@ -670,6 +694,7 @@ _get_preferred_caps (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, goto fixate_failed; if (!_fixate_frame_rate (postproc, vinfo, structure)) goto fixate_failed; + _set_multiview_mode (postproc, vinfo, structure); if (f == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) _set_colorimetry (postproc, format, structure); From b713af42a19c30f97d5f0f367a9d88b0b3962247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 21 Jun 2017 19:30:55 +0200 Subject: [PATCH 2820/3781] vaapiencode: h264: check for avc in set_config() The check for avc stream format was done in the vaapi encoder's vmethod get_caps(), but that is wrong since it has to be check when encoder set_format(). https://bugzilla.gnome.org/show_bug.cgi?id=757941 --- gst/vaapi/gstvaapiencode_h264.c | 41 +++++++++++++++------------------ 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 3f7db3e589..33cb0ed1bf 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -281,17 +281,33 @@ find_best_profile (GstCaps * caps) static gboolean gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) { + GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base_encode); GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encode->encoder); GstCaps *allowed_caps; GstVaapiProfile profile; + const char *stream_format = NULL; + GstStructure *structure; + guint i, num_structures; - /* Check for the largest profile that is supported */ allowed_caps = gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (base_encode)); if (!allowed_caps) return TRUE; + /* Check whether "stream-format" is avcC mode */ + num_structures = gst_caps_get_size (allowed_caps); + for (i = 0; !stream_format && i < num_structures; i++) { + structure = gst_caps_get_structure (allowed_caps, i); + if (!gst_structure_has_field_typed (structure, "stream-format", + G_TYPE_STRING)) + continue; + stream_format = gst_structure_get_string (structure, "stream-format"); + } + encode->is_avc = stream_format && strcmp (stream_format, "avc") == 0; + base_encode->need_codec_data = encode->is_avc; + + /* Check for the largest profile that is supported */ profile = find_best_profile (allowed_caps); gst_caps_unref (allowed_caps); if (profile) { @@ -307,34 +323,13 @@ static GstCaps * gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) { GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base_encode); - GstCaps *caps, *allowed_caps; + GstCaps *caps; caps = gst_caps_from_string (GST_CODEC_CAPS); - /* Check whether "stream-format" is avcC mode */ - allowed_caps = - gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); - if (allowed_caps) { - const char *stream_format = NULL; - GstStructure *structure; - guint i, num_structures; - - num_structures = gst_caps_get_size (allowed_caps); - for (i = 0; !stream_format && i < num_structures; i++) { - structure = gst_caps_get_structure (allowed_caps, i); - if (!gst_structure_has_field_typed (structure, "stream-format", - G_TYPE_STRING)) - continue; - stream_format = gst_structure_get_string (structure, "stream-format"); - } - encode->is_avc = stream_format && strcmp (stream_format, "avc") == 0; - gst_caps_unref (allowed_caps); - } gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, encode->is_avc ? "avc" : "byte-stream", NULL); - base_encode->need_codec_data = encode->is_avc; - /* XXX: update profile and level information */ return caps; } From 322fe9893622b61f005167422c8867a3c55921b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 21 Jun 2017 21:49:27 +0200 Subject: [PATCH 2821/3781] vaapiencode: h264: improve set_config() vmethod First check if downstream requests ANY caps. If so, byte-stream is used and the profile will be choose by the encoder. If dowstream requests EMPTY caps, the negotiation will fail. Lately, byte-stream and profile are looked in the allowed caps. https://bugzilla.gnome.org/show_bug.cgi?id=757941 --- gst/vaapi/gstvaapiencode_h264.c | 74 +++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 33cb0ed1bf..63b82fb3e2 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -284,39 +284,59 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base_encode); GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encode->encoder); - GstCaps *allowed_caps; - GstVaapiProfile profile; - const char *stream_format = NULL; - GstStructure *structure; - guint i, num_structures; + GstCaps *template_caps, *allowed_caps; + gboolean ret = TRUE; + template_caps = + gst_static_pad_template_get_caps (&gst_vaapiencode_h264_src_factory); allowed_caps = - gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (base_encode)); - if (!allowed_caps) - return TRUE; + gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); - /* Check whether "stream-format" is avcC mode */ - num_structures = gst_caps_get_size (allowed_caps); - for (i = 0; !stream_format && i < num_structures; i++) { - structure = gst_caps_get_structure (allowed_caps, i); - if (!gst_structure_has_field_typed (structure, "stream-format", - G_TYPE_STRING)) - continue; - stream_format = gst_structure_get_string (structure, "stream-format"); + if (allowed_caps == template_caps) { + GST_INFO_OBJECT (encode, "downstream has ANY caps, outputting byte-stream"); + encode->is_avc = FALSE; + gst_caps_unref (allowed_caps); + } else if (!allowed_caps) { + GST_INFO_OBJECT (encode, + "downstream has NULL caps, outputting byte-stream"); + encode->is_avc = FALSE; + } else if (gst_caps_is_empty (allowed_caps)) { + GST_INFO_OBJECT (encode, "downstream has EMPTY caps"); + gst_caps_unref (template_caps); + gst_caps_unref (allowed_caps); + return FALSE; + } else { + const char *stream_format = NULL; + GstStructure *structure; + guint i, num_structures; + GstVaapiProfile profile; + + /* Check whether "stream-format" is avcC mode */ + num_structures = gst_caps_get_size (allowed_caps); + for (i = 0; !stream_format && i < num_structures; i++) { + structure = gst_caps_get_structure (allowed_caps, i); + if (!gst_structure_has_field_typed (structure, "stream-format", + G_TYPE_STRING)) + continue; + stream_format = gst_structure_get_string (structure, "stream-format"); + } + encode->is_avc = stream_format && strcmp (stream_format, "avc") == 0; + + /* Check for the largest profile that is supported */ + profile = find_best_profile (allowed_caps); + if (profile != GST_VAAPI_PROFILE_UNKNOWN) { + GST_INFO ("using %s profile as target decoder constraints", + gst_vaapi_utils_h264_get_profile_string (profile)); + ret = gst_vaapi_encoder_h264_set_max_profile (encoder, profile); + } + + gst_caps_unref (allowed_caps); } - encode->is_avc = stream_format && strcmp (stream_format, "avc") == 0; + gst_caps_unref (template_caps); + base_encode->need_codec_data = encode->is_avc; - /* Check for the largest profile that is supported */ - profile = find_best_profile (allowed_caps); - gst_caps_unref (allowed_caps); - if (profile) { - GST_INFO ("using %s profile as target decoder constraints", - gst_vaapi_utils_h264_get_profile_string (profile)); - if (!gst_vaapi_encoder_h264_set_max_profile (encoder, profile)) - return FALSE; - } - return TRUE; + return ret; } static GstCaps * From 39b36f7d14731ddb309af4a918fdf1b9fc3a5378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 22 Jun 2017 09:56:49 +0200 Subject: [PATCH 2822/3781] vaapiencode: h264: verify if requested profile is supported Check if the requested profile in source caps, is supported by the VA driver. If it is not, an info log message is send saying that another (compatible?) profile will be used. https://bugzilla.gnome.org/show_bug.cgi?id=757941 --- gst/vaapi/gstvaapiencode_h264.c | 60 +++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode_h264.h | 1 + 2 files changed, 61 insertions(+) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 63b82fb3e2..1b7572c356 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -170,6 +170,9 @@ gst_vaapiencode_h264_init (GstVaapiEncodeH264 * encode) static void gst_vaapiencode_h264_finalize (GObject * object) { + GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (object); + + gst_caps_replace (&encode->available_caps, NULL); G_OBJECT_CLASS (gst_vaapiencode_h264_parent_class)->finalize (object); } @@ -278,6 +281,51 @@ find_best_profile (GstCaps * caps) return data.best_profile; } +static GstCaps * +get_available_caps (GstVaapiEncodeH264 * encode) +{ + GstCaps *out_caps; + GArray *profiles; + GstVaapiProfile profile; + const gchar *profile_str; + GValue profile_v = G_VALUE_INIT; + GValue profile_list = G_VALUE_INIT; + guint i; + + if (encode->available_caps) + return encode->available_caps; + + g_value_init (&profile_list, GST_TYPE_LIST); + g_value_init (&profile_v, G_TYPE_STRING); + + profiles = + gst_vaapi_display_get_encode_profiles + (GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); + if (!profiles) + return NULL; + + for (i = 0; i < profiles->len; i++) { + profile = g_array_index (profiles, GstVaapiProfile, i); + if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264) + continue; + profile_str = gst_vaapi_profile_get_name (profile); + if (!profile_str) + continue; + g_value_set_string (&profile_v, profile_str); + gst_value_list_append_value (&profile_list, &profile_v); + } + g_array_unref (profiles); + + out_caps = gst_caps_from_string (GST_CODEC_CAPS); + gst_caps_set_value (out_caps, "profile", &profile_list); + g_value_unset (&profile_list); + g_value_unset (&profile_v); + + encode->available_caps = out_caps; + + return encode->available_caps; +} + static gboolean gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) { @@ -310,6 +358,18 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) GstStructure *structure; guint i, num_structures; GstVaapiProfile profile; + GstCaps *available_caps; + + available_caps = get_available_caps (encode); + if (!available_caps) { + gst_caps_unref (template_caps); + gst_caps_unref (allowed_caps); + return FALSE; + } + if (!gst_caps_can_intersect (allowed_caps, available_caps)) { + GST_INFO_OBJECT (encode, "downstream requested an unsupported profile, " + "but encoder will output a compatible one"); + } /* Check whether "stream-format" is avcC mode */ num_structures = gst_caps_get_size (allowed_caps); diff --git a/gst/vaapi/gstvaapiencode_h264.h b/gst/vaapi/gstvaapiencode_h264.h index cab73d77ec..46a0e8161a 100644 --- a/gst/vaapi/gstvaapiencode_h264.h +++ b/gst/vaapi/gstvaapiencode_h264.h @@ -56,6 +56,7 @@ struct _GstVaapiEncodeH264 GstVaapiEncode parent_instance; guint is_avc:1; /* [FALSE]=byte-stream (default); [TRUE]=avcC */ + GstCaps *available_caps; }; struct _GstVaapiEncodeH264Class From d018f64cbdbb2037ff6aaf4b08856e52ffdfe7e0 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 27 Jun 2017 13:14:31 +0900 Subject: [PATCH 2823/3781] vaapiencode: h264: set profile to src caps So far vaapi encoder does not set profile to src caps. This patch makes it setting profile to src caps, which is determined by itself. In addition, if encoder chose different profile, which is not negotiated with downstream, we should set compatible profile to make negotiation working. https://bugzilla.gnome.org/show_bug.cgi?id=757941 --- gst/vaapi/gstvaapiencode_h264.c | 58 ++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 1b7572c356..d2ff38d097 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -399,10 +399,61 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) return ret; } +static void +set_compatible_profile (GstVaapiEncodeH264 * encode, GstCaps * caps, + GstVaapiProfile profile) +{ + GstCaps *allowed_caps, *tmp_caps; + gboolean ret = FALSE; + + allowed_caps = + gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); + if (!allowed_caps || gst_caps_is_empty (allowed_caps)) { + if (allowed_caps) + gst_caps_unref (allowed_caps); + return; + } + + tmp_caps = gst_caps_from_string (GST_CODEC_CAPS); + + /* If profile doesn't exist in the allowed caps, let's find + * compatible profile in the caps. + * + * If there is one, we can set it as a compatible profile and make + * the negotiation. We consider baseline compatible with + * constrained-baseline, which is a strict subset of baseline + * profile. + */ +retry: + gst_caps_set_simple (tmp_caps, "profile", G_TYPE_STRING, + gst_vaapi_utils_h264_get_profile_string (profile), NULL); + + if (!gst_caps_can_intersect (allowed_caps, tmp_caps)) { + if (profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE) { + profile = GST_VAAPI_PROFILE_H264_BASELINE; + goto retry; + } + } else { + gst_caps_set_simple (caps, "profile", G_TYPE_STRING, + gst_vaapi_utils_h264_get_profile_string (profile), NULL); + ret = TRUE; + } + + if (!ret) + GST_LOG ("There is no compatible profile in the requested caps."); + + gst_caps_unref (tmp_caps); + gst_caps_unref (allowed_caps); + return; +} + static GstCaps * gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) { GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base_encode); + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264 (base_encode->encoder); + GstVaapiProfile profile; GstCaps *caps; caps = gst_caps_from_string (GST_CODEC_CAPS); @@ -410,7 +461,12 @@ gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, encode->is_avc ? "avc" : "byte-stream", NULL); - /* XXX: update profile and level information */ + /* Update profile determined by encoder */ + gst_vaapi_encoder_h264_get_profile_and_level (encoder, &profile, NULL); + if (profile != GST_VAAPI_PROFILE_UNKNOWN) + set_compatible_profile (encode, caps, profile); + + /* XXX: update level information */ return caps; } From ca84fd211a94ebd0bbca8adae6f083689a9d9511 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 27 Jun 2017 16:03:37 +0900 Subject: [PATCH 2824/3781] libs: encoder: h264: set profile via capsfilter Until now, the encoder ignored the profile in src caps and chose one according with the given parameters. But the encoder must honor the profile specifed in src caps. This patch do that, and if the encoder needs to choose the profile, it will do it by following these rules: 1\ If given parameters are not compatible with given profile, the encoder will bail out with an error. 2\ The encoder will choose the higher profile indicated in the src caps. https://bugzilla.gnome.org/show_bug.cgi?id=757941 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 34 +++++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 42a05db3a5..d1265c17d1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1043,24 +1043,34 @@ ensure_profile_limits (GstVaapiEncoderH264 * encoder) GstVaapiProfile profile; if (!encoder->max_profile_idc - || encoder->profile_idc <= encoder->max_profile_idc) + || encoder->profile_idc == encoder->max_profile_idc) return TRUE; - GST_WARNING ("lowering coding tools to meet target decoder constraints"); + /* Give an error if the given parameters are invalid for requested + * profile rather than lowering profile. + */ + if (encoder->profile_idc > encoder->max_profile_idc) { + GST_WARNING ("Invalid parameter for maximum profile"); + return FALSE; + } profile = GST_VAAPI_PROFILE_UNKNOWN; - /* Try Main profile coding tools */ - if (encoder->max_profile_idc < GST_H264_PROFILE_HIGH) { - encoder->use_dct8x8 = FALSE; - profile = GST_VAAPI_PROFILE_H264_MAIN; - } + if (encoder->profile_idc < encoder->max_profile_idc) { + /* Let profile be higher to fit in the maximum profile + * without changing parameters */ + if (encoder->max_profile_idc > GST_H264_PROFILE_BASELINE) + profile = GST_VAAPI_PROFILE_H264_MAIN; - /* Try Constrained Baseline profile coding tools */ - if (encoder->max_profile_idc < GST_H264_PROFILE_MAIN) { - encoder->num_bframes = 0; - encoder->use_cabac = FALSE; - profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + if (encoder->max_profile_idc > GST_H264_PROFILE_MAIN) + profile = GST_VAAPI_PROFILE_H264_HIGH; + + if (encoder->max_profile_idc > GST_H264_PROFILE_HIGH) { + if (encoder->num_views > 2) + profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH; + else if (encoder->num_views == 2) + profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH; + } } if (profile) { From 5b38e7fbe2165276af3aabe126e9747cf850a599 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 27 Jun 2017 14:30:54 +0900 Subject: [PATCH 2825/3781] Revert "encoder: h264: Use high profile by default" This reverts commit 4aec5bdd7207fc0e45813ef14c9c0ad5174a8f75. https://bugzilla.gnome.org/show_bug.cgi?id=757941 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index d1265c17d1..b93bafeacd 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3046,7 +3046,7 @@ gst_vaapi_encoder_h264_get_default_properties (void) GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES, g_param_spec_uint ("max-bframes", - "Max B-Frames", "Number of B-frames between I and P", 0, 10, 1, + "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** @@ -3095,7 +3095,7 @@ gst_vaapi_encoder_h264_get_default_properties (void) g_param_spec_boolean ("cabac", "Enable CABAC", "Enable CABAC entropy coding mode", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiEncoderH264:dct8x8: @@ -3109,7 +3109,7 @@ gst_vaapi_encoder_h264_get_default_properties (void) g_param_spec_boolean ("dct8x8", "Enable 8x8 DCT", "Enable adaptive use of 8x8 transforms in I-frames", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiEncoderH264:cpb-length: From 9b73b31c7a0bd99792e59438f962c5100358e311 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 29 Jun 2017 12:50:26 +0900 Subject: [PATCH 2826/3781] libs: encoder: h264: initialize all elements of view_ids Currently when num_views is changed by multiview-mode on sink caps, it produces wrong MVC encoded stream since the array view_ids is not set properly according to changed num_views. So this patch initializes all of the array sequentially to handle this case. Side effect is not going to happen by this patch since this array is being handled by num_views. https://bugzilla.gnome.org/show_bug.cgi?id=784321 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index b93bafeacd..fda0c31e72 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2971,7 +2971,7 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, GValueArray *view_ids = g_value_get_boxed (value); if (view_ids == NULL) { - for (i = 0; i < encoder->num_views; i++) + for (i = 0; i < MAX_NUM_VIEWS; i++) encoder->view_ids[i] = i; } else { g_assert (view_ids->n_values <= encoder->num_views); From 02a6e9a2735a88e212716f3c5e414db0dcf5b597 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 5 Apr 2017 14:48:46 -0700 Subject: [PATCH 2827/3781] libs: encoder: h264: insert AU delimiter Insert an AUD as the first NAL of each encoded frame. Some applications require Access Unit Delimiter for decoding the stream. The AU delimeter insertion is done only when the aud parameter is TRUE (by default is disabled). The reason of this it is because this header is only available from Intel Gen9 and the VA intel driver should be 1.8 or superior. Otherwise, the output will be corrupted. https://bugzilla.gnome.org/show_bug.cgi?id=776712 Signed-off-by: Victor Jaquez --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 75 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 1 + 2 files changed, 76 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index fda0c31e72..c5e33fd1a9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -715,6 +715,8 @@ struct _GstVaapiEncoderH264 guint16 view_ids[MAX_NUM_VIEWS]; GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS]; GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS]; + + gboolean use_aud; }; /* Write a SEI buffering period payload */ @@ -1293,6 +1295,52 @@ fill_hrd_params (GstVaapiEncoderH264 * encoder, VAEncMiscParameterHRD * hrd) } } +static gboolean +add_packed_au_delimiter (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncPackedHeader *packed_aud; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; + guint32 data_bit_size; + guint8 *data; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_NONE, + GST_H264_NAL_AU_DELIMITER); + WRITE_UINT32 (&bs, picture->type - 1, 3); + if (!bs_write_trailing_bits (&bs)) + goto bs_error; + + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_header_param_buffer.type = VAEncPackedHeaderRawData; + packed_header_param_buffer.bit_length = data_bit_size; + packed_header_param_buffer.has_emulation_bytes = 0; + + packed_aud = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_header_param_buffer, sizeof (packed_header_param_buffer), + data, (data_bit_size + 7) / 8); + g_assert (packed_aud); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_aud); + gst_vaapi_codec_object_replace (&packed_aud, NULL); + + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write AU Delimiter NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + /* Adds the supplied sequence header (SPS) to the list of packed headers to pass down as-is to the encoder */ static gboolean @@ -2120,6 +2168,13 @@ ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncSequence *sequence = NULL; + /* Insert an AU delimiter */ + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_RAW_DATA) && encoder->use_aud) { + if (!add_packed_au_delimiter (encoder, picture)) + goto error_create_packed_au_delimiter; + } + /* submit an SPS header before every new I-frame, if codec config changed */ if (!encoder->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I) return TRUE; @@ -2157,6 +2212,11 @@ error_create_seq_param: gst_vaapi_codec_object_replace (&sequence, NULL); return FALSE; } +error_create_packed_au_delimiter: + { + GST_ERROR ("failed to create AU delimiter"); + gst_vaapi_codec_object_replace (&sequence, NULL); + } error_create_packed_seq_hdr: { GST_ERROR ("failed to create packed sequence header buffer"); @@ -2983,6 +3043,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, } break; } + case GST_VAAPI_ENCODER_H264_PROP_AUD: + encoder->use_aud = g_value_get_boolean (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -3134,6 +3197,7 @@ gst_vaapi_encoder_h264_get_default_properties (void) "Number of Views", "Number of Views for MVC encoding", 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiEncoderH264:view-ids: * @@ -3148,6 +3212,17 @@ gst_vaapi_encoder_h264_get_default_properties (void) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:aud: + * + * Use AU (Access Unit) delimeter. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_AUD, + g_param_spec_boolean ("aud", "AU delimiter", + "Use AU (Access Unit) delimeter", FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 14e35efd6e..5019b6cf4e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -61,6 +61,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH = -7, GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS = -8, GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS = -9, + GST_VAAPI_ENCODER_H264_PROP_AUD = -10, } GstVaapiEncoderH264Prop; GstVaapiEncoder * From 465d5868d96ec7c839bfdb4a3e17f33a8bae1206 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 9 Jun 2017 14:47:16 +0900 Subject: [PATCH 2828/3781] libs: encoder: h264: set the frame as IDR if forced key unit GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME() is a flag usually used to manage the `frame-lost` event in the case of streaming, such as RTP. In case of this event, it is needed to start new GOP rather than just produce an I-frame. https://bugzilla.gnome.org/show_bug.cgi?id=776712 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index c5e33fd1a9..3ae4430ac7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2790,12 +2790,14 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame, encoder); ++reorder_pool->cur_frame_num; - set_key_frame (picture, encoder, is_idr); + set_key_frame (picture, encoder, + is_idr | GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame)); g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); picture = p_pic; reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; } else { /* no b frames in queue */ - set_key_frame (picture, encoder, is_idr); + set_key_frame (picture, encoder, + is_idr | GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame)); g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list)); if (encoder->num_bframes) reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; From 6ebf7b10ae5895fb2ce67249c5d3d3f9bbaf9460 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 9 Jun 2017 14:47:40 +0900 Subject: [PATCH 2829/3781] libs: encoder: h264: submit sps in case of IDR picture If the picture is IDR, also submit a SPS header. This means when frame number reaches to keyframe-period or an force key unit event arrives, we insert SPS/PPS again. https://bugzilla.gnome.org/show_bug.cgi?id=776712 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 3ae4430ac7..601a4be28d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2175,8 +2175,11 @@ ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) goto error_create_packed_au_delimiter; } - /* submit an SPS header before every new I-frame, if codec config changed */ - if (!encoder->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I) + /* submit an SPS header before every new I-frame, if codec config changed + * or if the picture is IDR. + */ + if ((!encoder->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I) + && !GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) return TRUE; sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder); From da5024ca8097c9eafb4e0a027c80ae5b597f9fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 7 Jul 2017 12:01:59 +0100 Subject: [PATCH 2830/3781] meson: find python3 via python3 module https://bugzilla.gnome.org/show_bug.cgi?id=783198 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 13a72717cf..b958c6cd9c 100644 --- a/meson.build +++ b/meson.build @@ -125,5 +125,5 @@ subdir('gst-libs') subdir('gst') #subdir('tests') -python3 = find_program('python3') +python3 = import('python3').find_python() run_command(python3, '-c', 'import shutil; shutil.copy("hooks/pre-commit.hook", ".git/hooks/pre-commit")') From 207486aa1ff4a5686791ac2300c13e5b489f5d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 14 Jun 2017 17:07:30 +0200 Subject: [PATCH 2831/3781] vaapidecode: properties callback in decoders map https://bugzilla.gnome.org/show_bug.cgi?id=783588 --- gst/vaapi/gstvaapidecode.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index ea1edf8eec..73242fb7ef 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -104,31 +104,33 @@ struct _GstVaapiDecoderMap guint rank; const gchar *name; const gchar *caps_str; + + void (*install_properties) (GObjectClass * klass); }; static const GstVaapiDecoderMap vaapi_decode_map[] = { #if USE_JPEG_DECODER - {GST_VAAPI_CODEC_JPEG, GST_RANK_MARGINAL, "jpeg", "image/jpeg"}, + {GST_VAAPI_CODEC_JPEG, GST_RANK_MARGINAL, "jpeg", "image/jpeg", NULL}, #endif {GST_VAAPI_CODEC_MPEG2, GST_RANK_PRIMARY, "mpeg2", - "video/mpeg, mpegversion=2, systemstream=(boolean)false"}, + "video/mpeg, mpegversion=2, systemstream=(boolean)false", NULL}, {GST_VAAPI_CODEC_MPEG4, GST_RANK_PRIMARY, "mpeg4", - "video/mpeg, mpegversion=4"}, - {GST_VAAPI_CODEC_H263, GST_RANK_PRIMARY, "h263", "video/x-h263"}, - {GST_VAAPI_CODEC_H264, GST_RANK_PRIMARY, "h264", "video/x-h264"}, + "video/mpeg, mpegversion=4", NULL}, + {GST_VAAPI_CODEC_H263, GST_RANK_PRIMARY, "h263", "video/x-h263", NULL}, + {GST_VAAPI_CODEC_H264, GST_RANK_PRIMARY, "h264", "video/x-h264", NULL}, {GST_VAAPI_CODEC_VC1, GST_RANK_PRIMARY, "vc1", - "video/x-wmv, wmvversion=3, format={WMV3,WVC1}"}, + "video/x-wmv, wmvversion=3, format={WMV3,WVC1}", NULL}, #if USE_VP8_DECODER - {GST_VAAPI_CODEC_VP8, GST_RANK_PRIMARY, "vp8", "video/x-vp8"}, + {GST_VAAPI_CODEC_VP8, GST_RANK_PRIMARY, "vp8", "video/x-vp8", NULL}, #endif #if USE_VP9_DECODER - {GST_VAAPI_CODEC_VP9, GST_RANK_PRIMARY, "vp9", "video/x-vp9"}, + {GST_VAAPI_CODEC_VP9, GST_RANK_PRIMARY, "vp9", "video/x-vp9", NULL}, #endif #if USE_H265_DECODER - {GST_VAAPI_CODEC_H265, GST_RANK_PRIMARY, "h265", "video/x-h265"}, + {GST_VAAPI_CODEC_H265, GST_RANK_PRIMARY, "h265", "video/x-h265", NULL}, #endif {0 /* the rest */ , GST_RANK_PRIMARY + 1, NULL, - gst_vaapidecode_sink_caps_str}, + gst_vaapidecode_sink_caps_str, NULL}, }; static GstElementClass *parent_class = NULL; @@ -1365,6 +1367,9 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) g_free (longname); g_free (description); + if (map->install_properties) + map->install_properties (object_class); + /* sink pad */ caps = gst_caps_from_string (map->caps_str); pad_template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, From 484033d0390c8f0b4c84a54f5ac8e8eb3654ae42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 14 Jun 2017 18:23:34 +0200 Subject: [PATCH 2832/3781] vaapidecode_props: add skeleton for h264 decoder properties https://bugzilla.gnome.org/show_bug.cgi?id=783588 --- gst/vaapi/Makefile.am | 2 ++ gst/vaapi/gstvaapidecode.c | 4 ++- gst/vaapi/gstvaapidecode_props.c | 43 ++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapidecode_props.h | 36 ++++++++++++++++++++++++++ gst/vaapi/meson.build | 1 + 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 gst/vaapi/gstvaapidecode_props.c create mode 100644 gst/vaapi/gstvaapidecode_props.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 90212480b9..1f29516eab 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -56,6 +56,7 @@ libgstvaapi_source_c = \ gstvaapivideobufferpool.c \ gstvaapivideomemory.c \ gstvaapivideometa_texture.c \ + gstvaapidecode_props.c \ $(NULL) libgstvaapi_source_h = \ @@ -73,6 +74,7 @@ libgstvaapi_source_h = \ gstvaapivideobufferpool.h \ gstvaapivideomemory.h \ gstvaapivideometa_texture.h \ + gstvaapidecode_props.h \ $(NULL) libgstvaapi_enc_source_c = \ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 73242fb7ef..946e084a47 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -26,6 +26,7 @@ #include #include "gstvaapidecode.h" +#include "gstvaapidecode_props.h" #include "gstvaapipluginutil.h" #include "gstvaapivideobuffer.h" #if (USE_GLX || USE_EGL) @@ -117,7 +118,8 @@ static const GstVaapiDecoderMap vaapi_decode_map[] = { {GST_VAAPI_CODEC_MPEG4, GST_RANK_PRIMARY, "mpeg4", "video/mpeg, mpegversion=4", NULL}, {GST_VAAPI_CODEC_H263, GST_RANK_PRIMARY, "h263", "video/x-h263", NULL}, - {GST_VAAPI_CODEC_H264, GST_RANK_PRIMARY, "h264", "video/x-h264", NULL}, + {GST_VAAPI_CODEC_H264, GST_RANK_PRIMARY, "h264", "video/x-h264", + gst_vaapi_decode_h264_install_properties}, {GST_VAAPI_CODEC_VC1, GST_RANK_PRIMARY, "vc1", "video/x-wmv, wmvversion=3, format={WMV3,WVC1}", NULL}, #if USE_VP8_DECODER diff --git a/gst/vaapi/gstvaapidecode_props.c b/gst/vaapi/gstvaapidecode_props.c new file mode 100644 index 0000000000..895a55e638 --- /dev/null +++ b/gst/vaapi/gstvaapidecode_props.c @@ -0,0 +1,43 @@ +/* + * gstvaapidecode_props.c - VA-API decoders specific properties + * + * Copyright (C) 2017 Intel Corporation + * Author: Gwenole Beauchesne + * Author: Victor Jaquez + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "gstvaapidecode_props.h" + +static void +gst_vaapi_decode_h264_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ +} + +static void +gst_vaapi_decode_h264_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ +} + +void +gst_vaapi_decode_h264_install_properties (GObjectClass * klass) +{ + klass->get_property = gst_vaapi_decode_h264_get_property; + klass->set_property = gst_vaapi_decode_h264_set_property; +} diff --git a/gst/vaapi/gstvaapidecode_props.h b/gst/vaapi/gstvaapidecode_props.h new file mode 100644 index 0000000000..3865c7791d --- /dev/null +++ b/gst/vaapi/gstvaapidecode_props.h @@ -0,0 +1,36 @@ +/* + * gstvaapidecode_props.h - VA-API decoders specific properties + * + * Copyright (C) 2017 Intel Corporation + * Author: Gwenole Beauchesne + * Author: Victor Jaquez + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef GST_VAAPI_DECODE_PROPS_H +#define GST_VAAPI_DECODE_PROPS_H + +#include "gstcompat.h" + +G_BEGIN_DECLS + +void +gst_vaapi_decode_h264_install_properties (GObjectClass * klass); + +G_END_DECLS + +#endif /* GST_VAAPI_DECODE_PROPS_H */ diff --git a/gst/vaapi/meson.build b/gst/vaapi/meson.build index 744b91c14f..ac2e0146ea 100644 --- a/gst/vaapi/meson.build +++ b/gst/vaapi/meson.build @@ -14,6 +14,7 @@ vaapi_sources = [ 'gstvaapivideobufferpool.c', 'gstvaapivideomemory.c', 'gstvaapivideometa_texture.c', + 'gstvaapidecode_props.c', ] if USE_ENCODERS From f39b7e97cec9ca3006b26f0b88b161628529c29a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 14 Jun 2017 18:31:18 +0200 Subject: [PATCH 2833/3781] vaapidecode_props: h264: add low latency property Adding support for private data. https://bugzilla.gnome.org/show_bug.cgi?id=783588 --- gst/vaapi/gstvaapidecode_props.c | 49 ++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapidecode_props.h | 10 +++++++ 2 files changed, 59 insertions(+) diff --git a/gst/vaapi/gstvaapidecode_props.c b/gst/vaapi/gstvaapidecode_props.c index 895a55e638..b93f06c4bf 100644 --- a/gst/vaapi/gstvaapidecode_props.c +++ b/gst/vaapi/gstvaapidecode_props.c @@ -23,21 +23,70 @@ #include "gstvaapidecode_props.h" +enum +{ + GST_VAAPI_DECODER_H264_PROP_FORCE_LOW_LATENCY = 1, +}; + +static gint h264_private_offset; + static void gst_vaapi_decode_h264_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { + GstVaapiDecodeH264Private *priv; + + priv = gst_vaapi_decode_h264_get_instance_private (object); + + switch (prop_id) { + case GST_VAAPI_DECODER_H264_PROP_FORCE_LOW_LATENCY: + g_value_set_boolean (value, priv->is_low_latency); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void gst_vaapi_decode_h264_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { + GstVaapiDecodeH264Private *priv; + + priv = gst_vaapi_decode_h264_get_instance_private (object); + + switch (prop_id) { + case GST_VAAPI_DECODER_H264_PROP_FORCE_LOW_LATENCY: + priv->is_low_latency = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } void gst_vaapi_decode_h264_install_properties (GObjectClass * klass) { + h264_private_offset = sizeof (GstVaapiDecodeH264Private); + g_type_class_adjust_private_offset (klass, &h264_private_offset); + klass->get_property = gst_vaapi_decode_h264_get_property; klass->set_property = gst_vaapi_decode_h264_set_property; + + g_object_class_install_property (klass, + GST_VAAPI_DECODER_H264_PROP_FORCE_LOW_LATENCY, + g_param_spec_boolean ("low-latency", "Force low latency mode", + "When enabled, frames will be pushed as soon as they are available. " + "It might violate the H.264 spec.", FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT)); +} + +GstVaapiDecodeH264Private * +gst_vaapi_decode_h264_get_instance_private (gpointer self) +{ + if (h264_private_offset == 0) + return NULL; + return (G_STRUCT_MEMBER_P (self, h264_private_offset)); } diff --git a/gst/vaapi/gstvaapidecode_props.h b/gst/vaapi/gstvaapidecode_props.h index 3865c7791d..877754f7ad 100644 --- a/gst/vaapi/gstvaapidecode_props.h +++ b/gst/vaapi/gstvaapidecode_props.h @@ -28,9 +28,19 @@ G_BEGIN_DECLS +typedef struct _GstVaapiDecodeH264Private GstVaapiDecodeH264Private; + +struct _GstVaapiDecodeH264Private +{ + gboolean is_low_latency; +}; + void gst_vaapi_decode_h264_install_properties (GObjectClass * klass); +GstVaapiDecodeH264Private * +gst_vaapi_decode_h264_get_instance_private (gpointer self); + G_END_DECLS #endif /* GST_VAAPI_DECODE_PROPS_H */ From 28d1d048a603082b5acf50c0d59ecfd039b46a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 14 Jun 2017 18:30:53 +0200 Subject: [PATCH 2834/3781] libs: decoder: h264: add getter/setter for low latency mode https://bugzilla.gnome.org/show_bug.cgi?id=783588 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 38 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 7 +++++ 2 files changed, 45 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 678e952f4c..18df327da9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -528,6 +528,8 @@ struct _GstVaapiDecoderH264Private guint has_context:1; guint progressive_sequence:1; guint top_field_first:1; + + gboolean force_low_latency; }; /** @@ -4732,6 +4734,42 @@ gst_vaapi_decoder_h264_set_alignment (GstVaapiDecoderH264 * decoder, decoder->priv.stream_alignment = alignment; } +/** + * gst_vaapi_decoder_h264_set_low_latency: + * @decoder: a #GstVaapiDecoderH264 + * @force_low_latency: %TRUE if force low latency + * + * if @force_low_latency is %TRUE the decoded frames are pushed soon + * as possible, instead of to wait until decoded picture buffer (DPB) + * release them. + * + * This violate the H.264 specification but it is useful for some live + * sources. + **/ +void +gst_vaapi_decoder_h264_set_low_latency (GstVaapiDecoderH264 * decoder, + gboolean force_low_latency) +{ + g_return_if_fail (decoder != NULL); + + decoder->priv.force_low_latency = force_low_latency; +} + +/** + * gst_vaapi_decoder_h264_get_low_latency: + * @decoder: a #GstVaapiDecoderH264 + * + * Returns: %TRUE if the low latency mode is enabled; otherwise + * %FALSE. + **/ +gboolean +gst_vaapi_decoder_h264_get_low_latency (GstVaapiDecoderH264 * decoder) +{ + g_return_val_if_fail (decoder != NULL, FALSE); + + return decoder->priv.force_low_latency; +} + /** * gst_vaapi_decoder_h264_new: * @display: a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h index f9949dd126..9ca65cfc99 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -55,6 +55,13 @@ 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); + G_END_DECLS #endif /* GST_VAAPI_DECODER_H264_H */ From 551ae940a780788752e41346eed9f5071c569bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Jul 2017 20:00:15 +0200 Subject: [PATCH 2835/3781] vaapidecode: set h264 low latency to decoder https://bugzilla.gnome.org/show_bug.cgi?id=783588 --- gst/vaapi/gstvaapidecode.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 946e084a47..0cc66f68f1 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -852,6 +852,8 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) /* Set the stream buffer alignment for better optimizations */ if (decode->decoder && caps) { + GstVaapiDecodeH264Private *priv = + gst_vaapi_decode_h264_get_instance_private (decode); GstStructure *const structure = gst_caps_get_structure (caps, 0); const gchar *str = NULL; @@ -866,6 +868,11 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) gst_vaapi_decoder_h264_set_alignment (GST_VAAPI_DECODER_H264 (decode->decoder), alignment); } + + if (priv) { + gst_vaapi_decoder_h264_set_low_latency (GST_VAAPI_DECODER_H264 + (decode->decoder), priv->is_low_latency); + } } break; #if USE_H265_DECODER From 11f461fb106326a771666dde9ee842a8ce43a0a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 10 Jul 2017 19:27:57 +0200 Subject: [PATCH 2836/3781] vaapidecode_props: h264: set low-latency in decoder Set the low-latency property if the H264 decoder is already instantiated, thus you could change the behavior in run-time. https://bugzilla.gnome.org/show_bug.cgi?id=783588 --- gst/vaapi/gstvaapidecode_props.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst/vaapi/gstvaapidecode_props.c b/gst/vaapi/gstvaapidecode_props.c index b93f06c4bf..0ca37aae8e 100644 --- a/gst/vaapi/gstvaapidecode_props.c +++ b/gst/vaapi/gstvaapidecode_props.c @@ -22,6 +22,9 @@ */ #include "gstvaapidecode_props.h" +#include "gstvaapidecode.h" + +#include enum { @@ -53,12 +56,16 @@ gst_vaapi_decode_h264_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstVaapiDecodeH264Private *priv; + GstVaapiDecoderH264 *decoder; priv = gst_vaapi_decode_h264_get_instance_private (object); switch (prop_id) { case GST_VAAPI_DECODER_H264_PROP_FORCE_LOW_LATENCY: priv->is_low_latency = g_value_get_boolean (value); + decoder = GST_VAAPI_DECODER_H264 (GST_VAAPIDECODE (object)->decoder); + if (decoder) + gst_vaapi_decoder_h264_set_low_latency (decoder, priv->is_low_latency); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); From 66d26da39f42ed1670705cfb80d8f93105655a00 Mon Sep 17 00:00:00 2001 From: Matt Staples Date: Fri, 26 May 2017 15:19:00 +0000 Subject: [PATCH 2837/3781] libs: decoder: h264: push frames as soon as possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Push frames downstream as soon as possible instead of waiting until they are ejected from the DPB. This patch makes the decoder not comply with the H.264 specification, but it is required for some video cameras. https://bugzilla.gnome.org/show_bug.cgi?id=762509 Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 73 +++++++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 18df327da9..e971f75012 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -800,17 +800,31 @@ dpb_find_nearest_prev_poc (GstVaapiDecoderH264 * decoder, /* Finds the picture with the lowest POC that needs to be output */ static gint -dpb_find_lowest_poc (GstVaapiDecoderH264 * decoder, - GstVaapiPictureH264 * picture, GstVaapiPictureH264 ** found_picture_ptr) +dpb_find_lowest_poc_for_output (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstVaapiPictureH264 ** found_picture_ptr, + gboolean * can_be_output) { GstVaapiDecoderH264Private *const priv = &decoder->priv; GstVaapiPictureH264 *found_picture = NULL; - guint i, j, found_index = -1; + guint i, j, found_index = -1, found_poc = -1; + gboolean is_first = TRUE; + gint last_output_poc = -1; for (i = 0; i < priv->dpb_count; i++) { GstVaapiFrameStore *const fs = priv->dpb[i]; - if (!fs->output_needed) + if (!fs->output_needed) { + /* find the maximum poc of any previously output frames that are + * still held in the DPB. */ + if (can_be_output != NULL) { + for (j = 0; j < fs->num_buffers; j++) { + if (is_first || fs->buffers[j]->base.poc > last_output_poc) { + is_first = FALSE; + last_output_poc = fs->buffers[j]->base.poc; + } + } + } continue; + } if (picture && picture->base.view_id != fs->view_id) continue; for (j = 0; j < fs->num_buffers; j++) { @@ -820,7 +834,27 @@ dpb_find_lowest_poc (GstVaapiDecoderH264 * decoder, if (!found_picture || found_picture->base.poc > pic->base.poc || (found_picture->base.poc == pic->base.poc && found_picture->base.voc > pic->base.voc)) - found_picture = pic, found_index = i; + found_picture = pic, found_index = i, found_poc = pic->base.poc; + } + } + + if (can_be_output != NULL) { + /* found_picture can be output if it's the first frame in the DPB, + * or if there's no gap between it and the most recently output + * frame. */ + *can_be_output = FALSE; + if (found_picture && + gst_vaapi_frame_store_is_complete (priv->dpb[found_index])) { + if (is_first) { + *can_be_output = TRUE; + } else if (((int) (found_poc)) > ((int) (last_output_poc))) { + *can_be_output = (found_poc - last_output_poc) <= 2; + } else { + /* A frame with a higher poc has already been sent. No choice + * now but to drop this frame */ + GST_WARNING ("dropping out-of-sequence frame"); + priv->dpb[found_index]->output_needed = FALSE; + } } } @@ -829,6 +863,16 @@ dpb_find_lowest_poc (GstVaapiDecoderH264 * decoder, return found_index; } +/* Finds the picture with the lowest POC that needs to be output */ +static gint +dpb_find_lowest_poc (GstVaapiDecoderH264 * decoder, + GstVaapiPictureH264 * picture, GstVaapiPictureH264 ** found_picture_ptr) +{ + return dpb_find_lowest_poc_for_output (decoder, picture, found_picture_ptr, + NULL); +} + + /* Finds the picture with the lowest VOC that needs to be output */ static gint dpb_find_lowest_voc (GstVaapiDecoderH264 * decoder, @@ -908,6 +952,22 @@ dpb_bump (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) return success; } +static void +dpb_output_ready_frames (GstVaapiDecoderH264 * decoder) +{ + GstVaapiDecoderH264Private *const priv = &decoder->priv; + gboolean can_output = FALSE; + gint found_index; + + while (TRUE) { + found_index = dpb_find_lowest_poc_for_output (decoder, + priv->current_picture, NULL, &can_output); + if (found_index < 0 || !can_output) + break; + dpb_output (decoder, priv->dpb[found_index]); + } +} + static void dpb_clear (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) { @@ -1662,6 +1722,9 @@ decode_current_picture (GstVaapiDecoderH264 * decoder) goto error; if (!dpb_add (decoder, picture)) goto error; + + if (priv->force_low_latency) + dpb_output_ready_frames (decoder); gst_vaapi_picture_replace (&priv->current_picture, NULL); return GST_VAAPI_DECODER_STATUS_SUCCESS; From e9fd571214f7823ae45d93325fc3bb4a811bb55e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 13 Jul 2017 16:43:34 +0200 Subject: [PATCH 2838/3781] vaapiencode: h264: add plugin documentation Comment how the profile is set and other parameters. --- gst/vaapi/gstvaapiencode_h264.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index d2ff38d097..949038c15a 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -27,6 +27,31 @@ * * Encodes raw video streams into H.264 bitstreams. * + * The #GstVaapiEncodeH264:rate-control property controls the type of + * encoding. In case of Constant Bitrate Encoding (CBR), the + * #GstVaapiEncodeH264:bitrate will determine the quality of the + * encoding. Alternatively, one may choose to perform Constant + * Quantizer or Variable Bitrate Encoding (VBR), in which case the + * #GstVaapiEncodeH264:bitrate is the maximum bitrate. + * + * The H264 profile that is eventually used depends on a few settings. + * If #GstVaapiEncodeH264:dct8x8 is enabled, then High profile is + * used. Otherwise, if #GstVaapiEncodeH264:cabac entropy coding is + * enabled or #GstVaapiEncodeH264:max-bframes are allowed, then Main + * Profile is in effect, and otherwise Baseline profile applies. The + * high profile is imposed by default, which is fine for most software + * players and settings, but in some cases (e.g. hardware platforms) a + * more restricted profile/level may be necessary. The recommended way + * to set a profile is to set it in the downstream caps. + * + * You can also set parameters to adjust the latency of encoding: + * #GstVaapiEncodeH264:quality-level is a number between 1-7, in the + * case of the Intel VAAPI driver, where a lower value will produce a + * higher quality output but with more latency; meanwhile a hihg + * number will produce a lower quality output with less latency. Also + * you can set #GstVaapiEncodeH264:tune, if your backend supports it, + * for low-power mode or high compression. + * * * Example launch line * |[ From a9c13a093496ef68ec9342370cc42cd5fbc612bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 17 Jul 2017 18:53:57 +0200 Subject: [PATCH 2839/3781] libs: encoder: vp9: array terminated in zeros There is a crash when setting ref-pic-mode since the #GEnumValue array is not terminated with a structured with all memvers being zero. https://bugzilla.gnome.org/show_bug.cgi?id=785032 --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 80de4b039d..64ef1f314c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -79,7 +79,8 @@ gst_vaapi_encoder_vp9_ref_pic_mode_type (void) "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"} + "mode-1"}, + {0, NULL, NULL}, }; gtype = g_enum_register_static ("GstVaapiEncoderVP9RefPicMode", values); From 8a04f390c8b71d22714411056bf1dd7f236525f2 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 12 Jul 2017 18:25:15 +0900 Subject: [PATCH 2840/3781] postproc: reconfigure when width or height changes https://bugzilla.gnome.org/show_bug.cgi?id=754885 --- gst/vaapi/gstvaapipostproc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index f9a37e15b9..241a4efd81 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1431,6 +1431,7 @@ gst_vaapipostproc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (object); + gboolean do_reconf = FALSE; g_mutex_lock (&postproc->postproc_lock); switch (prop_id) { @@ -1438,11 +1439,19 @@ gst_vaapipostproc_set_property (GObject * object, postproc->format = g_value_get_enum (value); break; case PROP_WIDTH: + { + guint prev_width = postproc->width; postproc->width = g_value_get_uint (value); + do_reconf = (prev_width != postproc->width); break; + } case PROP_HEIGHT: + { + guint prev_height = postproc->height; postproc->height = g_value_get_uint (value); + do_reconf = (prev_height != postproc->height); break; + } case PROP_FORCE_ASPECT_RATIO: postproc->keep_aspect = g_value_get_boolean (value); break; @@ -1490,7 +1499,7 @@ gst_vaapipostproc_set_property (GObject * object, } g_mutex_unlock (&postproc->postproc_lock); - if (check_filter_update (postproc)) + if (do_reconf || check_filter_update (postproc)) gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM (postproc)); } From dd78e038591dd09f65798154cd6ac4a76fc71a6f Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 13 Jul 2017 10:56:18 +0900 Subject: [PATCH 2841/3781] tests: elements: add test for vaapipostproc https://bugzilla.gnome.org/show_bug.cgi?id=754885 --- tests/elements/Makefile.am | 5 + tests/elements/test-vaapipostproc.c | 157 ++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 tests/elements/test-vaapipostproc.c diff --git a/tests/elements/Makefile.am b/tests/elements/Makefile.am index 822f8e725d..86c49f5f95 100644 --- a/tests/elements/Makefile.am +++ b/tests/elements/Makefile.am @@ -1,5 +1,6 @@ noinst_PROGRAMS = \ test-vaapisink \ + test-vaapipostproc \ test-roi \ $(NULL) @@ -18,6 +19,10 @@ test_vaapisink_SOURCES = test-vaapisink.c test_vaapisink_CFLAGS = $(TEST_CFLAGS) test_vaapisink_LDADD = $(TEST_LIBS) +test_vaapipostproc_SOURCES = test-vaapipostproc.c +test_vaapipostproc_CFLAGS = $(TEST_CFLAGS) +test_vaapipostproc_LDADD = $(TEST_LIBS) + test_roi_SOURCES = test-roi.c test_roi_CFLAGS = $(TEST_CFLAGS) test_roi_LDADD = $(TEST_LIBS) diff --git a/tests/elements/test-vaapipostproc.c b/tests/elements/test-vaapipostproc.c new file mode 100644 index 0000000000..87d1353912 --- /dev/null +++ b/tests/elements/test-vaapipostproc.c @@ -0,0 +1,157 @@ +/* + * test-vaapipostproc.c - Testsuite for VAAPI Postprocessor + * + * Copyright (C) 2017 Intel Corporation + * + * 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 +#include +#include + +typedef struct _CustomData +{ + GstElement *pipeline; + GstElement *postproc; + GMainLoop *loop; +} AppData; + +static gboolean +_check_passthrough_mode (gpointer user_data) +{ + gboolean ret; + AppData *data = (AppData *) user_data; + + ret = gst_base_transform_is_passthrough (GST_BASE_TRANSFORM (data->postproc)); + + if (ret) + gst_println ("Now this pipeline is on passthrough mode"); + else + gst_println ("Now this pipeline is NOT on passthrough mode"); + + return FALSE; +} + +static void +set_contrast (AppData * data) +{ + static gfloat value = 1.0; + + value = value == 1.0 ? 0.5 : 1.0; + g_object_set (data->postproc, "contrast", value, NULL); + gst_println ("contrast value is changed to %f", value); + + g_timeout_add (300, _check_passthrough_mode, data); +} + +static void +change_size (AppData * data) +{ + static gint i = 0; + if (i == 0) { + g_object_set (data->postproc, "width", 1280, "height", 720, NULL); + gst_println ("frame size is changed to 1280x720"); + i++; + } else { + g_object_set (data->postproc, "width", 0, "height", 0, NULL); + gst_println ("frame size is changed to default"); + i = 0; + } + + g_timeout_add (300, _check_passthrough_mode, data); +} + +/* Process keyboard input */ +static gboolean +handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data) +{ + gchar *str = NULL; + + if (g_io_channel_read_line (source, &str, NULL, NULL, + NULL) != G_IO_STATUS_NORMAL) { + return TRUE; + } + + switch (g_ascii_tolower (str[0])) { + case 's':{ + set_contrast (data); + break; + } + case 'c':{ + change_size (data); + break; + } + case 'q': + g_main_loop_quit (data->loop); + break; + default: + break; + } + + g_free (str); + + return TRUE; +} + +int +main (int argc, char *argv[]) +{ + AppData data = { 0, }; + GstStateChangeReturn ret; + GIOChannel *io_stdin; + + /* Initialize GStreamer */ + gst_init (&argc, &argv); + + /* Print usage map */ + gst_println ("USAGE: Choose one of the following options, then press enter:\n" + " 's' to set contrast\n" " 'c' to change size\n" " 'q' to quit\n"); + + data.pipeline = + gst_parse_launch + ("videotestsrc name=src ! vaapih264enc ! vaapih264dec ! vaapipostproc name=postproc ! vaapisink", + NULL); + data.postproc = gst_bin_get_by_name (GST_BIN (data.pipeline), "postproc"); + + /* Add a keyboard watch so we get notified of keystrokes */ + io_stdin = g_io_channel_unix_new (fileno (stdin)); + g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc) handle_keyboard, &data); + + /* Start playing */ + ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + g_printerr ("Unable to set the pipeline to the playing state.\n"); + gst_object_unref (data.pipeline); + return -1; + } + + g_timeout_add (300, _check_passthrough_mode, &data); + + /* Create a GLib Main Loop and set it to run */ + data.loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (data.loop); + + /* Free resources */ + g_main_loop_unref (data.loop); + g_io_channel_unref (io_stdin); + gst_element_set_state (data.pipeline, GST_STATE_NULL); + + gst_object_unref (data.postproc); + gst_object_unref (data.pipeline); + + return 0; +} From ec3e10f6664789a6161fe1d82aec396e02e71248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 26 Jun 2017 21:18:25 +0200 Subject: [PATCH 2842/3781] libs: display: remove cache Remove a bunch of code that handles the VADisplay cache, since the context sharing should be doing this correctly. https://bugzilla.gnome.org/show_bug.cgi?id=747946 --- gst-libs/gst/vaapi/Makefile.am | 2 - gst-libs/gst/vaapi/gstvaapidisplay.c | 72 +--- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 31 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 13 - gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 70 +--- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 84 +--- gst-libs/gst/vaapi/gstvaapidisplaycache.c | 415 ------------------- gst-libs/gst/vaapi/gstvaapidisplaycache.h | 87 ---- 8 files changed, 16 insertions(+), 758 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapidisplaycache.c delete mode 100644 gst-libs/gst/vaapi/gstvaapidisplaycache.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 50bdef8e58..5bf3c105b3 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -58,7 +58,6 @@ libgstvaapi_source_c = \ gstvaapidecoder_unit.c \ gstvaapidecoder_vc1.c \ gstvaapidisplay.c \ - gstvaapidisplaycache.c \ gstvaapifilter.c \ gstvaapiimage.c \ gstvaapiimagepool.c \ @@ -130,7 +129,6 @@ libgstvaapi_source_priv_h = \ gstvaapidecoder_priv.h \ gstvaapidecoder_unit.h \ gstvaapidisplay_priv.h \ - gstvaapidisplaycache.h \ gstvaapiimage_priv.h \ gstvaapiminiobject.h \ gstvaapiobject_priv.h \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 61bc8d76f6..3c74826928 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -95,9 +95,6 @@ enum N_PROPERTIES }; -static GstVaapiDisplayCache *g_display_cache; -static GMutex g_display_cache_lock; - static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; static void gst_vaapi_display_properties_init (void); @@ -130,29 +127,6 @@ libgstvaapi_init_once (void) g_once_init_leave (&g_once, TRUE); } -static GstVaapiDisplayCache * -get_display_cache (void) -{ - GstVaapiDisplayCache *cache = NULL; - - g_mutex_lock (&g_display_cache_lock); - if (!g_display_cache) - g_display_cache = gst_vaapi_display_cache_new (); - if (g_display_cache) - cache = gst_vaapi_display_cache_ref (g_display_cache); - g_mutex_unlock (&g_display_cache_lock); - return cache; -} - -static void -free_display_cache (void) -{ - g_mutex_lock (&g_display_cache_lock); - if (g_display_cache && gst_vaapi_display_cache_is_empty (g_display_cache)) - gst_vaapi_display_cache_replace (&g_display_cache, NULL); - g_mutex_unlock (&g_display_cache_lock); -} - /* GstVaapiDisplayType enumerations */ GType gst_vaapi_display_type_get_type (void) @@ -874,14 +848,6 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) priv->vendor_string = NULL; gst_vaapi_display_replace_internal (&priv->parent, NULL); - - if (priv->cache) { - gst_vaapi_display_cache_lock (priv->cache); - gst_vaapi_display_cache_remove (priv->cache, display); - gst_vaapi_display_cache_unlock (priv->cache); - } - gst_vaapi_display_cache_replace (&priv->cache, NULL); - free_display_cache (); } static gboolean @@ -892,7 +858,6 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, const GstVaapiDisplayClass *const klass = GST_VAAPI_DISPLAY_GET_CLASS (display); GstVaapiDisplayInfo info; - const GstVaapiDisplayInfo *cached_info = NULL; memset (&info, 0, sizeof (info)); info.display = display; @@ -928,23 +893,11 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, if (!priv->display) return FALSE; - cached_info = gst_vaapi_display_cache_lookup_by_va_display (priv->cache, - info.va_display); - if (cached_info) { - gst_vaapi_display_replace_internal (&priv->parent, cached_info->display); - priv->display_type = cached_info->display_type; - } - if (!priv->parent) { if (!vaapi_initialize (priv->display)) return FALSE; } - if (!cached_info) { - if (!gst_vaapi_display_cache_add (priv->cache, &info)) - return FALSE; - } - GST_INFO_OBJECT (display, "new display addr=%p", display); g_free (priv->display_name); priv->display_name = g_strdup (info.display_name); @@ -955,20 +908,7 @@ static gboolean gst_vaapi_display_create (GstVaapiDisplay * display, GstVaapiDisplayInitType init_type, gpointer init_value) { - GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - GstVaapiDisplayCache *cache; - gboolean success; - - cache = get_display_cache (); - if (!cache) - return FALSE; - gst_vaapi_display_cache_replace (&priv->cache, cache); - gst_vaapi_display_cache_unref (cache); - - gst_vaapi_display_cache_lock (cache); - success = gst_vaapi_display_create_unlocked (display, init_type, init_value); - gst_vaapi_display_cache_unlock (cache); - return success; + return gst_vaapi_display_create_unlocked (display, init_type, init_value); } static void @@ -1128,16 +1068,6 @@ error: GstVaapiDisplay * gst_vaapi_display_new_with_display (VADisplay va_display) { - GstVaapiDisplayCache *const cache = get_display_cache (); - const GstVaapiDisplayInfo *info; - - g_return_val_if_fail (va_display != NULL, NULL); - g_return_val_if_fail (cache != NULL, NULL); - - info = gst_vaapi_display_cache_lookup_by_va_display (cache, va_display); - if (info) - return gst_vaapi_display_ref_internal (info->display); - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY, NULL), GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, va_display); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 00ff039546..a129cce758 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -48,8 +48,6 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplayDRM, gst_vaapi_display_drm, GST_TYPE_VAAPI_DISPLAY, _do_init); -static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_DRM; - typedef enum { DRM_DEVICE_LEGACY = 1, @@ -265,23 +263,15 @@ gst_vaapi_display_drm_open_display (GstVaapiDisplay * display, { GstVaapiDisplayDRMPrivate *const priv = GST_VAAPI_DISPLAY_DRM_PRIVATE (display); - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); - const GstVaapiDisplayInfo *info; if (!set_device_path (display, name)) return FALSE; - info = gst_vaapi_display_cache_lookup_by_name (cache, priv->device_path, - g_display_types); - if (info) { - priv->drm_device = GPOINTER_TO_INT (info->native_display); - priv->use_foreign_display = TRUE; - } else { - priv->drm_device = open (get_device_path (display), O_RDWR | O_CLOEXEC); - if (priv->drm_device < 0) - return FALSE; - priv->use_foreign_display = 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; } @@ -314,18 +304,7 @@ gst_vaapi_display_drm_get_display_info (GstVaapiDisplay * display, { GstVaapiDisplayDRMPrivate *const priv = GST_VAAPI_DISPLAY_DRM_PRIVATE (display); - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); - const GstVaapiDisplayInfo *cached_info; - /* Return any cached info even if child has its own VA display */ - cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache, - GINT_TO_POINTER (priv->drm_device), g_display_types); - if (cached_info) { - *info = *cached_info; - return TRUE; - } - - /* Otherwise, create VA display if there is none already */ info->native_display = GINT_TO_POINTER (priv->drm_device); info->display_name = priv->device_path; if (!info->va_display) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index d914e954d8..c4ef59fed7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -26,7 +26,6 @@ #define GST_VAAPI_DISPLAY_PRIV_H #include -#include #include #include #include @@ -108,21 +107,9 @@ typedef enum _GstVaapiDisplayInitType GstVaapiDisplayInitType; #define GST_VAAPI_DISPLAY_HAS_VPP(display) \ gst_vaapi_display_has_video_processing (GST_VAAPI_DISPLAY_CAST (display)) -/** - * GST_VAAPI_DISPLAY_CACHE: - * @display: a @GstVaapiDisplay - * - * Returns the #GstVaapiDisplayCache attached to the supplied @display object. - * This is an internal macro that does not do any run-time type check. - */ -#undef GST_VAAPI_DISPLAY_CACHE -#define GST_VAAPI_DISPLAY_CACHE(display) \ - (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->cache) - struct _GstVaapiDisplayPrivate { GstVaapiDisplay *parent; - GstVaapiDisplayCache *cache; GRecMutex mutex; GstVaapiDisplayType display_type; gchar *display_name; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 08a61c4f14..951e0307be 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -42,8 +42,6 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplayWayland, gst_vaapi_display_wayland, GST_TYPE_VAAPI_DISPLAY, _do_init); -static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_WAYLAND; - static inline const gchar * get_default_display_name (void) { @@ -54,39 +52,6 @@ get_default_display_name (void) return g_display_name; } -static inline guint -get_display_name_length (const gchar * display_name) -{ - const gchar *str; - - str = strchr (display_name, '-'); - if (str) - return str - display_name; - return strlen (display_name); -} - -static gint -compare_display_name (gconstpointer a, gconstpointer b) -{ - const GstVaapiDisplayInfo *const info = a; - const gchar *cached_name = info->display_name; - const gchar *tested_name = b; - guint cached_name_length, tested_name_length; - - g_return_val_if_fail (cached_name, FALSE); - g_return_val_if_fail (tested_name, FALSE); - - cached_name_length = get_display_name_length (cached_name); - tested_name_length = get_display_name_length (tested_name); - - /* XXX: handle screen number and default WAYLAND_DISPLAY name */ - if (cached_name_length != tested_name_length) - return FALSE; - if (strncmp (cached_name, tested_name, cached_name_length) != 0) - return FALSE; - return TRUE; -} - /* Mangle display name with our prefix */ static gboolean set_display_name (GstVaapiDisplay * display, const gchar * display_name) @@ -211,29 +176,15 @@ gst_vaapi_display_wayland_open_display (GstVaapiDisplay * display, { GstVaapiDisplayWaylandPrivate *const priv = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); - const GstVaapiDisplayInfo *info; - int dsp_error = 0; if (!set_display_name (display, name)) return FALSE; - info = gst_vaapi_display_cache_lookup_custom (cache, compare_display_name, - priv->display_name, g_display_types); - if (info) { - wl_display_roundtrip (info->native_display); - if ((dsp_error = wl_display_get_error (info->native_display))) - GST_ERROR ("wayland display error detected: %d", dsp_error); - } - if (info && !dsp_error) { - priv->wl_display = info->native_display; - priv->use_foreign_display = TRUE; - } else { - priv->wl_display = wl_display_connect (name); - if (!priv->wl_display) - return FALSE; - priv->use_foreign_display = 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); } @@ -281,18 +232,7 @@ gst_vaapi_display_wayland_get_display_info (GstVaapiDisplay * display, { GstVaapiDisplayWaylandPrivate *const priv = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); - const GstVaapiDisplayInfo *cached_info; - /* Return any cached info even if child has its own VA display */ - cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache, - priv->wl_display, g_display_types); - if (cached_info) { - *info = *cached_info; - return TRUE; - } - - /* Otherwise, create VA display if there is none already */ info->native_display = priv->wl_display; info->display_name = priv->display_name; if (!info->va_display) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 08bfb1a361..ca7fa5c584 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -52,60 +52,6 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplayX11, gst_vaapi_display_x11, GST_TYPE_VAAPI_DISPLAY, _do_init); -static const guint g_display_types = 1U << GST_VAAPI_DISPLAY_TYPE_X11; - -static gboolean -parse_display_name (const gchar * name, guint * len_ptr, guint * id_ptr, - guint * screen_ptr) -{ - gulong len, id = 0, screen = 0; - gchar *end; - - end = strchr (name, ':'); - len = end ? end - name : strlen (name); - - if (end) { - id = strtoul (&end[1], &end, 10); - if (*end == '.') - screen = strtoul (&end[1], &end, 10); - if (*end != '\0') - return FALSE; - } - - if (len_ptr) - *len_ptr = len; - if (id_ptr) - *id_ptr = id; - if (screen_ptr) - *screen_ptr = screen; - return TRUE; -} - -static gint -compare_display_name (gconstpointer a, gconstpointer b) -{ - const GstVaapiDisplayInfo *const info = a; - const gchar *const cached_name = info->display_name; - const gchar *const tested_name = b; - guint cached_name_length, cached_id; - guint tested_name_length, tested_id; - - g_return_val_if_fail (cached_name, FALSE); - g_return_val_if_fail (tested_name, FALSE); - - if (!parse_display_name (cached_name, &cached_name_length, &cached_id, NULL)) - return FALSE; - if (!parse_display_name (tested_name, &tested_name_length, &tested_id, NULL)) - return FALSE; - if (cached_name_length != tested_name_length) - return FALSE; - if (strncmp (cached_name, tested_name, cached_name_length) != 0) - return FALSE; - if (cached_id != tested_id) - return FALSE; - return TRUE; -} - static inline const gchar * get_default_display_name (void) { @@ -203,23 +149,14 @@ gst_vaapi_display_x11_open_display (GstVaapiDisplay * base_display, GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11_CAST (base_display); GstVaapiDisplayX11Private *const priv = display->priv; - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); - const GstVaapiDisplayInfo *info; - if (!set_display_name (display, name)) return FALSE; - info = gst_vaapi_display_cache_lookup_custom (cache, compare_display_name, - priv->display_name, g_display_types); - if (info) { - priv->x11_display = info->native_display; - priv->use_foreign_display = TRUE; - } else { - priv->x11_display = XOpenDisplay (get_display_name (display)); - if (!priv->x11_display) - return FALSE; - priv->use_foreign_display = 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); @@ -281,18 +218,7 @@ gst_vaapi_display_x11_get_display_info (GstVaapiDisplay * display, { GstVaapiDisplayX11Private *const priv = GST_VAAPI_DISPLAY_X11_PRIVATE (display); - GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_CACHE (display); - const GstVaapiDisplayInfo *cached_info; - /* Return any cached info even if child has its own VA display */ - cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache, - priv->x11_display, g_display_types); - if (cached_info) { - *info = *cached_info; - return TRUE; - } - - /* Otherwise, create VA display if there is none already */ info->native_display = priv->x11_display; info->display_name = priv->display_name; if (!info->va_display) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c deleted file mode 100644 index 9c4680c5e0..0000000000 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * gstvaapidisplaycache.c - VA display cache - * - * Copyright (C) 2012-2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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 -#include -#include "gstvaapidisplaycache.h" - -#define DEBUG 1 -#include "gstvaapidebug.h" - -typedef struct _CacheEntry CacheEntry; -struct _CacheEntry -{ - GstVaapiDisplayInfo info; -}; - -struct _GstVaapiDisplayCache -{ - GstVaapiMiniObject parent_instance; - GRecMutex mutex; - GList *list; -}; - -static void -cache_entry_free (CacheEntry * entry) -{ - GstVaapiDisplayInfo *info; - - if (!entry) - return; - - info = &entry->info; - - if (info->display_name) { - g_free (info->display_name); - info->display_name = NULL; - } - g_slice_free (CacheEntry, entry); -} - -static CacheEntry * -cache_entry_new (const GstVaapiDisplayInfo * di) -{ - GstVaapiDisplayInfo *info; - CacheEntry *entry; - - entry = g_slice_new (CacheEntry); - if (!entry) - return NULL; - - info = &entry->info; - info->display = di->display; - info->va_display = di->va_display; - info->native_display = di->native_display; - info->display_type = di->display_type; - info->display_name = NULL; - - if (di->display_name) { - info->display_name = g_strdup (di->display_name); - if (!info->display_name) - goto error; - } - return entry; - - /* ERRORS */ -error: - { - cache_entry_free (entry); - return NULL; - } -} - -static inline gboolean -is_compatible_display_type (const GstVaapiDisplayType display_type, - guint display_types) -{ - if (display_type == GST_VAAPI_DISPLAY_TYPE_ANY) - return TRUE; - if (display_types == GST_VAAPI_DISPLAY_TYPE_ANY) - return TRUE; - return ((1U << display_type) & display_types) != 0; -} - -static GList * -cache_lookup_1 (GstVaapiDisplayCache * cache, GCompareFunc func, - gconstpointer data, guint display_types) -{ - GList *l; - - for (l = cache->list; l != NULL; l = l->next) { - GstVaapiDisplayInfo *const info = &((CacheEntry *) l->data)->info; - if (!is_compatible_display_type (info->display_type, display_types)) - continue; - if (func (info, data)) - break; - } - return l; -} - -static inline const GstVaapiDisplayInfo * -cache_lookup (GstVaapiDisplayCache * cache, GCompareFunc func, - gconstpointer data, guint display_types) -{ - GList *const m = cache_lookup_1 (cache, func, data, display_types); - - return m ? &((CacheEntry *) m->data)->info : NULL; -} - -static gint -compare_display (gconstpointer a, gconstpointer display) -{ - const GstVaapiDisplayInfo *const info = a; - - return info->display == display; -} - -static gint -compare_va_display (gconstpointer a, gconstpointer va_display) -{ - const GstVaapiDisplayInfo *const info = a; - - return info->va_display == va_display; -} - -static gint -compare_native_display (gconstpointer a, gconstpointer native_display) -{ - const GstVaapiDisplayInfo *const info = a; - - return info->native_display == native_display; -} - -static gint -compare_display_name (gconstpointer a, gconstpointer b) -{ - const GstVaapiDisplayInfo *const info = a; - const gchar *const display_name = b; - - if (info->display_name == NULL && display_name == NULL) - return TRUE; - if (!info->display_name || !display_name) - return FALSE; - return strcmp (info->display_name, display_name) == 0; -} - -static void -gst_vaapi_display_cache_finalize (GstVaapiDisplayCache * cache) -{ - GList *l; - - if (cache->list) { - for (l = cache->list; l != NULL; l = l->next) - cache_entry_free (l->data); - g_list_free (cache->list); - cache->list = NULL; - } - g_rec_mutex_clear (&cache->mutex); -} - -static const GstVaapiMiniObjectClass * -gst_vaapi_display_cache_class (void) -{ - static const GstVaapiMiniObjectClass GstVaapiDisplayCacheClass = { - .size = sizeof (GstVaapiDisplayCache), - .finalize = (GDestroyNotify) gst_vaapi_display_cache_finalize - }; - return &GstVaapiDisplayCacheClass; -} - -/** - * gst_vaapi_display_cache_new: - * - * Creates a new VA display cache. - * - * Return value: the newly created #GstVaapiDisplayCache object - */ -GstVaapiDisplayCache * -gst_vaapi_display_cache_new (void) -{ - GstVaapiDisplayCache *cache; - - cache = (GstVaapiDisplayCache *) - gst_vaapi_mini_object_new (gst_vaapi_display_cache_class ()); - if (!cache) - return NULL; - - g_rec_mutex_init (&cache->mutex); - cache->list = NULL; - return cache; -} - -/** - * gst_vaapi_display_cache_lock: - * @cache: the #GstVaapiDisplayCache - * - * Locks the display cache @cache. - */ -void -gst_vaapi_display_cache_lock (GstVaapiDisplayCache * cache) -{ - g_return_if_fail (cache != NULL); - - g_rec_mutex_lock (&cache->mutex); -} - -/** - * gst_vaapi_display_cache_unlock: - * @cache: the #GstVaapiDisplayCache - * - * Unlocks the display cache @cache. - */ -void -gst_vaapi_display_cache_unlock (GstVaapiDisplayCache * cache) -{ - g_return_if_fail (cache != NULL); - - g_rec_mutex_unlock (&cache->mutex); -} - -/** - * gst_vaapi_display_cache_is_empty: - * @cache: the #GstVaapiDisplayCache - * - * Checks whether the display cache @cache is empty. - * - * Return value: %TRUE if the display @cache is empty, %FALSE otherwise. - */ -gboolean -gst_vaapi_display_cache_is_empty (GstVaapiDisplayCache * cache) -{ - g_return_val_if_fail (cache != NULL, 0); - - return cache->list == NULL; -} - -/** - * gst_vaapi_display_cache_add: - * @cache: the #GstVaapiDisplayCache - * @info: the display cache info to add - * - * Adds a new entry with data from @info. The display @info data is - * copied into the newly created cache entry. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_display_cache_add (GstVaapiDisplayCache * cache, - GstVaapiDisplayInfo * info) -{ - CacheEntry *entry; - - g_return_val_if_fail (cache != NULL, FALSE); - g_return_val_if_fail (info != NULL, FALSE); - - entry = cache_entry_new (info); - if (!entry) - return FALSE; - - cache->list = g_list_prepend (cache->list, entry); - return TRUE; -} - -/** - * gst_vaapi_display_cache_remove: - * @cache: the #GstVaapiDisplayCache - * @display: the display to remove from cache - * - * Removes any cache entry that matches the specified #GstVaapiDisplay. - */ -void -gst_vaapi_display_cache_remove (GstVaapiDisplayCache * cache, - GstVaapiDisplay * display) -{ - GList *m; - - m = cache_lookup_1 (cache, compare_display, display, - GST_VAAPI_DISPLAY_TYPE_ANY); - if (!m) - return; - - cache_entry_free (m->data); - cache->list = g_list_delete_link (cache->list, m); -} - -/** - * gst_vaapi_display_cache_lookup: - * @cache: the #GstVaapiDisplayCache - * @display: the display to find - * - * Looks up the display cache for the specified #GstVaapiDisplay. - * - * Return value: a #GstVaapiDisplayInfo matching @display, or %NULL if - * none was found - */ -const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup (GstVaapiDisplayCache * cache, - GstVaapiDisplay * display) -{ - g_return_val_if_fail (cache != NULL, NULL); - g_return_val_if_fail (display != NULL, NULL); - - return cache_lookup (cache, compare_display, display, - GST_VAAPI_DISPLAY_TYPE_ANY); -} - -/** - * gst_vaapi_display_cache_lookup_custom: - * @cache: the #GstVaapiDisplayCache - * @func: an comparison function - * @data: user data passed to the function - * - * Looks up an element in the display @cache using the supplied - * function @func to find the desired element. It iterates over all - * elements in cache, calling the given function which should return - * %TRUE when the desired element is found. - * - * The comparison function takes two gconstpointer arguments, a - * #GstVaapiDisplayInfo as the first argument, and that is used to - * compare against the given user @data argument as the second - * argument. - * - * Return value: a #GstVaapiDisplayInfo causing @func to succeed - * (i.e. returning %TRUE), or %NULL if none was found - */ -const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_custom (GstVaapiDisplayCache * cache, - GCompareFunc func, gconstpointer data, guint display_types) -{ - g_return_val_if_fail (cache != NULL, NULL); - g_return_val_if_fail (func != NULL, NULL); - - return cache_lookup (cache, func, data, display_types); -} - -/** - * gst_vaapi_display_cache_lookup_by_va_display: - * @cache: the #GstVaapiDisplayCache - * @va_display: the VA display to find - * - * Looks up the display cache for the specified VA display. - * - * Return value: a #GstVaapiDisplayInfo matching @va_display, or %NULL - * if none was found - */ -const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_va_display (GstVaapiDisplayCache * cache, - VADisplay va_display) -{ - g_return_val_if_fail (cache != NULL, NULL); - g_return_val_if_fail (va_display != NULL, NULL); - - return cache_lookup (cache, compare_va_display, va_display, - GST_VAAPI_DISPLAY_TYPE_ANY); -} - -/** - * gst_vaapi_display_cache_lookup_by_native_display: - * @cache: the #GstVaapiDisplayCache - * @native_display: the native display to find - * - * Looks up the display cache for the specified native display. - * - * Return value: a #GstVaapiDisplayInfo matching @native_display, or - * %NULL if none was found - */ -const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_native_display (GstVaapiDisplayCache * cache, - gpointer native_display, guint display_types) -{ - g_return_val_if_fail (cache != NULL, NULL); - g_return_val_if_fail (native_display != NULL, NULL); - - return cache_lookup (cache, compare_native_display, native_display, - display_types); -} - -/** - * gst_vaapi_display_cache_lookup_by_name: - * @cache: the #GstVaapiDisplayCache - * @display_name: the display name to match - * - * Looks up the display cache for the specified display name. - * - * Return value: a #GstVaapiDisplayInfo matching @display_name, or - * %NULL if none was found - */ -const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_name (GstVaapiDisplayCache * cache, - const gchar * display_name, guint display_types) -{ - g_return_val_if_fail (cache != NULL, NULL); - - return cache_lookup (cache, compare_display_name, display_name, - display_types); -} diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h deleted file mode 100644 index 9d0abb7762..0000000000 --- a/gst-libs/gst/vaapi/gstvaapidisplaycache.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * gstvaapidisplaycache.h - VA display cache - * - * Copyright (C) 2012-2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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 GSTVAAPIDISPLAYCACHE_H -#define GSTVAAPIDISPLAYCACHE_H - -#include "libgstvaapi_priv_check.h" -#include -#include "gstvaapiminiobject.h" - -typedef struct _GstVaapiDisplayCache GstVaapiDisplayCache; - -G_GNUC_INTERNAL -GstVaapiDisplayCache * -gst_vaapi_display_cache_new (void); - -#define gst_vaapi_display_cache_ref(cache) \ - ((GstVaapiDisplayCache *) gst_vaapi_mini_object_ref ( \ - GST_VAAPI_MINI_OBJECT (cache))) -#define gst_vaapi_display_cache_unref(cache) \ - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (cache)) -#define gst_vaapi_display_cache_replace(old_cache_ptr, new_cache) \ - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_cache_ptr), \ - GST_VAAPI_MINI_OBJECT (new_cache)) - -G_GNUC_INTERNAL -void -gst_vaapi_display_cache_lock (GstVaapiDisplayCache * cache); - -G_GNUC_INTERNAL -void -gst_vaapi_display_cache_unlock (GstVaapiDisplayCache * cache); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_display_cache_is_empty (GstVaapiDisplayCache * cache); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_display_cache_add (GstVaapiDisplayCache * cache, - GstVaapiDisplayInfo * info); - -G_GNUC_INTERNAL -void -gst_vaapi_display_cache_remove (GstVaapiDisplayCache * cache, - GstVaapiDisplay * display); - -const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup (GstVaapiDisplayCache - * cache, GstVaapiDisplay * display); - -const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_custom (GstVaapiDisplayCache * cache, - GCompareFunc func, gconstpointer data, guint display_types); - -const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_va_display (GstVaapiDisplayCache * cache, - VADisplay va_display); - -const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_native_display (GstVaapiDisplayCache * - cache, gpointer native_display, guint display_types); - -const GstVaapiDisplayInfo * -gst_vaapi_display_cache_lookup_by_name (GstVaapiDisplayCache * cache, - const gchar * display_name, guint display_types); - -#endif /* GSTVAAPIDISPLAYCACHE_H */ From 356212214b76722417325625529a91509d1fa94f Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 5 Jul 2017 14:32:35 +0900 Subject: [PATCH 2843/3781] libs: display: pass display info when foreign display When creating a GstVaapiDisplay using a foreign VADisplay, and render with that display, it also requires native display of the backend. https://bugzilla.gnome.org/show_bug.cgi?id=766704 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 40 +++++++++++++++++++--------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 3c74826928..73da04eb78 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -852,29 +852,38 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) static gboolean gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, - GstVaapiDisplayInitType init_type, gpointer init_value) + GstVaapiDisplayInitType init_type, gpointer data) { GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); const GstVaapiDisplayClass *const klass = GST_VAAPI_DISPLAY_GET_CLASS (display); - GstVaapiDisplayInfo info; - - memset (&info, 0, sizeof (info)); - info.display = display; - info.display_type = priv->display_type; + GstVaapiDisplayInfo info = { + .display = display, + .display_type = priv->display_type, + }; switch (init_type) { - case GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY: - info.va_display = init_value; - priv->display = init_value; + case GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY:{ + GstVaapiDisplayInfo *p_info = data; + + info.va_display = p_info->va_display; + info.display_type = p_info->display_type; + priv->display = p_info->va_display; priv->use_foreign_display = TRUE; - break; + + if (!klass->bind_display) + break; + + data = p_info->native_display; + goto bind_display; + } case GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME: - if (klass->open_display && !klass->open_display (display, init_value)) + if (klass->open_display && !klass->open_display (display, data)) return FALSE; goto create_display; case GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY: - if (klass->bind_display && !klass->bind_display (display, init_value)) + bind_display: + if (klass->bind_display && !klass->bind_display (display, data)) return FALSE; // fall-through create_display: @@ -1068,8 +1077,13 @@ error: GstVaapiDisplay * gst_vaapi_display_new_with_display (VADisplay va_display) { + GstVaapiDisplayInfo info = { + .va_display = va_display, + .display_type = GST_VAAPI_DISPLAY_TYPE_ANY, + }; + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY, NULL), - GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, va_display); + GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, &info); } /** From d78e094fd4bc112b40872de07b078455989292cc Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 5 Jul 2017 14:33:38 +0900 Subject: [PATCH 2844/3781] libs: display: x11: add gst_vaapi_display_x11_new_with_va_display() Implements new API function so that users could create GstVaapiDisplay with their own VADisplay within a native display as backend. https://bugzilla.gnome.org/show_bug.cgi?id=766704 --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 16 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index ca7fa5c584..ee36009536 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -373,6 +373,22 @@ gst_vaapi_display_x11_new_with_display (Display * x11_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) +{ + GstVaapiDisplayInfo info = { + .va_display = va_display, + .native_display = x11_display, + .display_type = GST_VAAPI_DISPLAY_TYPE_X11, + }; + + g_return_val_if_fail (x11_display, NULL); + + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_X11, NULL), + GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, &info); +} + /** * gst_vaapi_display_x11_get_display: * @display: a #GstVaapiDisplayX11 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 703545920b..1458ea7ad1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -42,6 +42,9 @@ 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); From b8265db2600e123ca921d710ff73b7cd3b330ede Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 5 Jul 2017 15:31:55 +0900 Subject: [PATCH 2845/3781] videocontext: support "gst.vaapi.app.Display" context Through "gst.vaapi.app.Display" context, users can set their own VADisplay and native display of their backend. Attributes: - display : pointer of VADisplay - x11-display : pointer of X11 display (Display *), if they're using. This patch creates GstVaapidisplayX11 if information provided through "gst.vaapi.app.Display" https://bugzilla.gnome.org/show_bug.cgi?id=766704 --- gst/vaapi/gstvaapivideocontext.c | 42 +++++++++++++++++++++++++++----- gst/vaapi/gstvaapivideocontext.h | 1 + 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 5e9f9b7072..214840bcd5 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -28,6 +28,9 @@ #if USE_GST_GL_HELPERS # include #endif +#if USE_X11 +#include +#endif GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); @@ -78,12 +81,31 @@ gst_vaapi_video_context_get_display (GstContext * context, g_return_val_if_fail (GST_IS_CONTEXT (context), FALSE); type = gst_context_get_context_type (context); - if (g_strcmp0 (type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME)) - return FALSE; - structure = gst_context_get_structure (context); - return gst_structure_get (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, - GST_TYPE_VAAPI_DISPLAY, display_ptr, NULL); + if (!g_strcmp0 (type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME)) { + structure = gst_context_get_structure (context); + return gst_structure_get (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, + GST_TYPE_VAAPI_DISPLAY, display_ptr, NULL); + } else if (!g_strcmp0 (type, GST_VAAPI_DISPLAY_APP_CONTEXT_TYPE_NAME)) { + VADisplay va_display = NULL; + structure = gst_context_get_structure (context); + + if (gst_structure_get (structure, "va-display", G_TYPE_POINTER, &va_display, + NULL)) { +#if USE_X11 + Display *x11_display = NULL; + if (gst_structure_get (structure, "x11-display", G_TYPE_POINTER, + &x11_display, NULL)) { + *display_ptr = + gst_vaapi_display_x11_new_with_va_display (va_display, x11_display); + return TRUE; + } +#endif + GST_WARNING ("Not support if only VADisplay provided"); + } + } + + return FALSE; } static gboolean @@ -204,8 +226,16 @@ gst_vaapi_video_context_prepare (GstElement * element, _gst_context_query (element, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); - if (*display_ptr) + if (*display_ptr) { GST_LOG_OBJECT (element, "found a display (%p)", *display_ptr); + return TRUE; + } + + _gst_context_query (element, GST_VAAPI_DISPLAY_APP_CONTEXT_TYPE_NAME); + + if (*display_ptr) + GST_LOG_OBJECT (element, "got a display with va display from app (%p)", + *display_ptr); return *display_ptr != NULL; } diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index 437486b239..0aaeb7e80b 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -30,6 +30,7 @@ #include #define GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME "gst.vaapi.Display" +#define GST_VAAPI_DISPLAY_APP_CONTEXT_TYPE_NAME "gst.vaapi.app.Display" G_GNUC_INTERNAL void From 736478d2a76caee872acd7980f593fe0c9b0b599 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 5 Jul 2017 15:32:43 +0900 Subject: [PATCH 2846/3781] vaapisink: fail if surface display is different Replacing GstVaapiDisplay during rendering might be hiding problems at some cases, even though it's safe currently since we use cache of GstVaapidisplay. Play safe by failing if this happens. https://bugzilla.gnome.org/show_bug.cgi?id=766704 --- gst/vaapi/gstvaapisink.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index d01c72775c..96ca674866 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1408,8 +1408,9 @@ gst_vaapisink_show_frame_unlocked (GstVaapiSink * sink, GstBuffer * src_buffer) return ret; meta = gst_buffer_get_vaapi_video_meta (buffer); - GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE (sink, - gst_vaapi_video_meta_get_display (meta)); + if (gst_vaapi_video_meta_get_display (meta) != + GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)) + goto different_display; proxy = gst_vaapi_video_meta_get_surface_proxy (meta); if (!proxy) @@ -1491,6 +1492,13 @@ no_surface: ret = GST_FLOW_ERROR; goto done; } + +different_display: + { + GST_WARNING_OBJECT (sink, "incoming surface has different VAAPI Display"); + ret = GST_FLOW_ERROR; + goto done; + } } static GstFlowReturn From 85856c29a70d6de4aea5b708e04e9eb418190623 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 5 Jul 2017 15:59:43 +0900 Subject: [PATCH 2847/3781] tests: elements: add testsuite of vaapi context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=766704 --- configure.ac | 21 ++ tests/elements/Makefile.am | 20 ++ tests/elements/test-vaapicontext.c | 314 +++++++++++++++++++++++++++++ 3 files changed, 355 insertions(+) create mode 100644 tests/elements/test-vaapicontext.c diff --git a/configure.ac b/configure.ac index 340b4649d0..2e8c703ca0 100644 --- a/configure.ac +++ b/configure.ac @@ -155,6 +155,11 @@ AC_ARG_WITH([glapi], [build with the specified OpenGL APIs @<:@default=default_glapi@:>@]), [GLAPI="$with_glapi"], [GLAPI=default_glapi]) +AC_ARG_WITH([gtk], + [AS_HELP_STRING([--with-gtk], + [compile GTK3 based test apps @<:@default=check@:>@])], + [], [with_gtk="check"]) + dnl *** checks for platform *** dnl * hardware/architecture * @@ -479,6 +484,22 @@ if test "x$enable_wayland" = "xyes"; then ], [:]) fi +dnl Check for GTK for tests +USE_GTK=0 +AS_IF([test "x$BUILD_EXAMPLES" = "xyes" -a $USE_X11 -eq 1], + [AS_CASE([$with_gtk], + [yes], [PKG_CHECK_MODULES([GTK3], [gtk+-3.0], [USE_GTK=1])], + [no], [], + [PKG_CHECK_MODULES([GTK3], [gtk+-3.0], [USE_GTK=1])])]) +AS_IF([test $USE_GTK -eq 1], + [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GTK3_CFLAGS" + AC_CHECK_HEADERS([gtk/gtk.h], [], [USE_GTK=0]) + CPPFLAGS="$saved_CPPFLAGS" + ]) +AM_CONDITIONAL([USE_GTK], [test $USE_GTK -eq 1]) + dnl --------------------------------------------------------------------------- dnl -- VA-API -- dnl --------------------------------------------------------------------------- diff --git a/tests/elements/Makefile.am b/tests/elements/Makefile.am index 86c49f5f95..742d923a67 100644 --- a/tests/elements/Makefile.am +++ b/tests/elements/Makefile.am @@ -27,4 +27,24 @@ test_roi_SOURCES = test-roi.c test_roi_CFLAGS = $(TEST_CFLAGS) test_roi_LDADD = $(TEST_LIBS) +if USE_GTK +noinst_PROGRAMS += test-vaapicontext + +test_vaapicontext_SOURCES = test-vaapicontext.c +test_vaapicontext_CFLAGS = \ + $(TEST_CFLAGS) \ + $(GTK3_CFLAGS) \ + $(X11_CFLAGS) \ + $(LIBVA_CFLAGS) \ + $(LIBVA_X11_CFLAGS) \ + $(NULL) +test_vaapicontext_LDADD = \ + $(TEST_LIBS) \ + $(GTK3_LIBS) \ + $(X11_LIBS) \ + $(LIBVA_LIBS) \ + $(LIBVA_X11_LIBS) \ + $(NULL) +endif + -include $(top_srcdir)/git.mk diff --git a/tests/elements/test-vaapicontext.c b/tests/elements/test-vaapicontext.c new file mode 100644 index 0000000000..ac974cc4c0 --- /dev/null +++ b/tests/elements/test-vaapicontext.c @@ -0,0 +1,314 @@ +/* + * test-vaapicontext.c - Testsuite for VAAPI app context + * + * Copyright (C) 2017 Intel Corporation + * + * 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 +#include + +#include +#include + +#include +#include +#ifdef GDK_WINDOWING_X11 +#include +#else +#error "X11 is not supported in GTK+" +#endif + +static gboolean g_multisink; +static gchar *g_filepath; + +static GOptionEntry g_options[] = { + {"multi", 'm', 0, G_OPTION_ARG_NONE, &g_multisink, "test multiple vaapisink", + NULL}, + {"file", 'f', 0, G_OPTION_ARG_STRING, &g_filepath, + "file path to play (only mp4/h264)", NULL}, + {NULL,} +}; + +typedef struct _CustomData +{ + GtkWidget *main_window; + VADisplay va_display; + GstElement *pipeline; + guintptr videoarea_handle[2]; +} AppData; + +static void +delete_event_cb (GtkWidget * widget, GdkEvent * event, gpointer data) +{ + AppData *app = data; + + gst_element_set_state (app->pipeline, GST_STATE_NULL); + gtk_main_quit (); +} + +static void +button_rotate_cb (GtkWidget * widget, GstElement * elem) +{ + static gint counter = 0; + const static gint tags[] = { 90, 180, 270, 0 }; + + g_object_set (elem, "rotation", tags[counter++ % G_N_ELEMENTS (tags)], NULL); +} + +static Display * +get_x11_window_display (AppData * app) +{ +#if defined(GDK_WINDOWING_X11) + GdkDisplay *gdk_display; + Display *x11_display; + + gdk_display = gtk_widget_get_display (app->main_window); + x11_display = gdk_x11_display_get_xdisplay (gdk_display); + return x11_display; +#endif + g_error ("Running in a non-X11 environment"); +} + +static VADisplay +ensure_va_display (AppData * app) +{ + if (app->va_display) + return app->va_display; + app->va_display = vaGetDisplay (get_x11_window_display (app)); + /* There's no need to call vaInitialize() since element does it + * internally */ + return app->va_display; +} + +static GstContext * +create_vaapi_app_display_context (AppData * app, gboolean new_va_display) +{ + GstContext *context; + GstStructure *s; + VADisplay va_display; + Display *x11_display; + + x11_display = get_x11_window_display (app); + + if (new_va_display) + va_display = vaGetDisplay (x11_display); + else + va_display = ensure_va_display (app); + + context = gst_context_new ("gst.vaapi.app.Display", TRUE); + s = gst_context_writable_structure (context); + gst_structure_set (s, "va-display", G_TYPE_POINTER, va_display, NULL); + gst_structure_set (s, "x11-display", G_TYPE_POINTER, x11_display, NULL); + + return context; +} + +static GstBusSyncReply +bus_sync_handler (GstBus * bus, GstMessage * msg, gpointer data) +{ + AppData *app = data; + + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_NEED_CONTEXT:{ + const gchar *context_type; + gboolean new_va_disp; + GstContext *context; + + gst_message_parse_context_type (msg, &context_type); + gst_println ("Got need context %s from %s", context_type, + GST_MESSAGE_SRC_NAME (msg)); + + if (g_strcmp0 (context_type, "gst.vaapi.app.Display") != 0) + break; + + /* create a new VA display *only* for the second video sink */ + new_va_disp = (g_strcmp0 (GST_MESSAGE_SRC_NAME (msg), "sink2") == 0); + + context = create_vaapi_app_display_context (app, new_va_disp); + gst_element_set_context (GST_ELEMENT (GST_MESSAGE_SRC (msg)), context); + gst_context_unref (context); + break; + } + case GST_MESSAGE_ELEMENT:{ + if (!gst_is_video_overlay_prepare_window_handle_message (msg)) + break; + + if (g_strcmp0 (GST_MESSAGE_SRC_NAME (msg), "sink2") == 0) + gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY + (GST_MESSAGE_SRC (msg)), app->videoarea_handle[1]); + else + gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY + (GST_MESSAGE_SRC (msg)), app->videoarea_handle[0]); + break; + } + case GST_MESSAGE_EOS: + gtk_main_quit (); + break; + default: + break; + } + + return GST_BUS_PASS; +} + +static void +realize_cb (GtkWidget * widget, gpointer data) +{ + AppData *app = data; + GdkWindow *window; + static guint counter = 0; + +#if defined(GDK_WINDOWING_X11) + window = gtk_widget_get_window (widget); + + if (!gdk_window_ensure_native (window)) + g_error ("Couldn't create native window needed for GstXOverlay!"); + + app->videoarea_handle[counter++ % 2] = GDK_WINDOW_XID (window); +#endif +} + +static GtkWidget * +create_video_box (AppData * app) +{ + GtkWidget *video_area; + + video_area = gtk_drawing_area_new (); + gtk_widget_set_size_request (video_area, 640, 480); + g_signal_connect (video_area, "realize", G_CALLBACK (realize_cb), app); + return video_area; +} + +static GtkWidget * +create_rotate_button (AppData * app, const gchar * name) +{ + GtkWidget *rotate; + GstElement *sink; + + sink = gst_bin_get_by_name (GST_BIN (app->pipeline), name); + g_assert (sink); + + rotate = gtk_button_new_with_label ("Rotate"); + g_signal_connect (rotate, "clicked", G_CALLBACK (button_rotate_cb), sink); + gst_object_unref (sink); + + return rotate; +} + +static void +build_ui (AppData * app) +{ + GtkWidget *mainwin, *vbox, *pane, *bbox; + + mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (mainwin), "VAAPI display context test"); + gtk_window_set_resizable (GTK_WINDOW (mainwin), FALSE); + g_signal_connect (mainwin, "delete-event", G_CALLBACK (delete_event_cb), app); + app->main_window = mainwin; + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add (GTK_CONTAINER (mainwin), vbox); + + pane = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); + gtk_box_pack_start (GTK_BOX (vbox), pane, TRUE, TRUE, 0); + + /* first video box */ + gtk_paned_pack1 (GTK_PANED (pane), create_video_box (app), TRUE, TRUE); + + /* rotate buttons */ + bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); + gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD); + gtk_box_pack_end (GTK_BOX (vbox), bbox, TRUE, TRUE, 0); + + gtk_box_pack_start (GTK_BOX (bbox), create_rotate_button (app, "sink1"), TRUE, + TRUE, 0); + + if (g_multisink) { + /* second video box */ + gtk_paned_pack2 (GTK_PANED (pane), create_video_box (app), TRUE, TRUE); + + gtk_box_pack_start (GTK_BOX (bbox), create_rotate_button (app, "sink2"), + TRUE, TRUE, 0); + } + + gtk_widget_show_all (mainwin); +} + +int +main (gint argc, gchar ** argv) +{ + AppData app = { 0, }; + GstBus *bus; + GOptionContext *ctx; + GError *error = NULL; + + XInitThreads (); + + ctx = g_option_context_new ("- test options"); + if (!ctx) + return -1; + + g_option_context_add_group (ctx, gtk_get_option_group (TRUE)); + g_option_context_add_group (ctx, gst_init_get_option_group ()); + g_option_context_add_main_entries (ctx, g_options, NULL); + if (!g_option_context_parse (ctx, &argc, &argv, NULL)) + return -1; + g_option_context_free (ctx); + + if (g_multisink) { + app.pipeline = gst_parse_launch ("videotestsrc ! tee name=t ! queue ! " + "vaapisink name=sink1 t. ! queue ! vaapisink name=sink2", &error); + } else if (!g_filepath) { + app.pipeline = gst_parse_launch ("videotestsrc ! vaapih264enc ! " + "vaapidecodebin ! vaapisink name=sink1", &error); + } else { + app.pipeline = gst_parse_launch ("filesrc name=src ! qtdemux ! h264parse ! " + "vaapidecodebin ! vaapisink name=sink1", &error); + } + + if (error) { + gst_printerrln ("failed to parse pipeline: %s", error->message); + g_error_free (error); + return -1; + } + + if (!g_multisink && g_filepath) { + GstElement *src; + + src = gst_bin_get_by_name (GST_BIN (app.pipeline), "src"); + g_assert (src); + g_object_set (src, "location", g_filepath, NULL); + gst_object_unref (src); + } + + build_ui (&app); + + bus = gst_element_get_bus (app.pipeline); + gst_bus_set_sync_handler (bus, bus_sync_handler, (gpointer) & app, NULL); + gst_object_unref (bus); + + gst_element_set_state (app.pipeline, GST_STATE_PLAYING); + gst_println ("Now playing…"); + + gtk_main (); + + gst_object_unref (app.pipeline); + /* there is no need to call vaTerminate() because it is done by the + * vaapi elements */ + return 0; +} From a77209ad540456bc7f267d8b8495fdff3349cca6 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Wed, 26 Jul 2017 09:53:10 -0700 Subject: [PATCH 2848/3781] configure: do not break configure if gtk+-3.0 devel missing Fix PKG_CHECK_MODULES rule for with_gtk=check condition to set USE_GTK=0 if gtk+-3.0 is not available. Since commit 85856c29a70d6de4aea5b708e04e9eb418190623 Author: Hyunjun Ko Date: Wed Jul 5 15:59:43 2017 +0900 tests: elements: add testsuite of vaapi context ...configure fails if gtk+-3.0 development files are missing. The "with_gtk" option defaults to "check" in configure.ac which implies that if it is not explicitly requested then configure will only enable it if it's available on the system. However, the PKG_CHECK_MODULES rule that get's activated on "check" condition did not provide default when gtk+-3.0 devel packages are not found on the system. Thus, it resulted in configure failure. Signed-off-by: U. Artie Eoff https://bugzilla.gnome.org/show_bug.cgi?id=785452 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 2e8c703ca0..73b6473ed1 100644 --- a/configure.ac +++ b/configure.ac @@ -490,7 +490,7 @@ AS_IF([test "x$BUILD_EXAMPLES" = "xyes" -a $USE_X11 -eq 1], [AS_CASE([$with_gtk], [yes], [PKG_CHECK_MODULES([GTK3], [gtk+-3.0], [USE_GTK=1])], [no], [], - [PKG_CHECK_MODULES([GTK3], [gtk+-3.0], [USE_GTK=1])])]) + [PKG_CHECK_MODULES([GTK3], [gtk+-3.0], [USE_GTK=1], [USE_GTK=0])])]) AS_IF([test $USE_GTK -eq 1], [ saved_CPPFLAGS="$CPPFLAGS" From 8a7354380c62ce65fd20e2a491fff60582407844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 26 Jul 2017 20:30:37 +0200 Subject: [PATCH 2849/3781] build: meson: remove gstvaapidisplaycache.c This is a missing bit of commit ec3e10f6 --- gst-libs/gst/vaapi/meson.build | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 55bb5c76e8..3519f0060f 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -12,7 +12,6 @@ gstlibvaapi_sources = [ 'gstvaapidecoder_unit.c', 'gstvaapidecoder_vc1.c', 'gstvaapidisplay.c', - 'gstvaapidisplaycache.c', 'gstvaapifilter.c', 'gstvaapiimage.c', 'gstvaapiimagepool.c', From d8de1853555d473e863b76b99231c234f8d13c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 11 Jul 2017 16:55:26 +0200 Subject: [PATCH 2850/3781] build: blacklist only libva 0.99.0 Intel's MSDK uses libva 0.99.0, meanwhile open source libva bumped its API version to 1.0.0. Thus we have to blacklist only the MSDK's libva (0.99.0) https://bugzilla.gnome.org/show_bug.cgi?id=784398 --- configure.ac | 2 +- meson.build | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 73b6473ed1..230f352273 100644 --- a/configure.ac +++ b/configure.ac @@ -505,7 +505,7 @@ dnl -- VA-API -- dnl --------------------------------------------------------------------------- dnl Core API -PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ libva < 0.99.0]) +PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ libva != 0.99.0]) VA_VERSION_STR=`$PKG_CONFIG --modversion libva` VA_DRIVERS_PATH=`$PKG_CONFIG --variable=driverdir libva` AC_DEFINE_UNQUOTED([VA_DRIVERS_PATH], ["$VA_DRIVERS_PATH"], diff --git a/meson.build b/meson.build index b958c6cd9c..10d2af0ce7 100644 --- a/meson.build +++ b/meson.build @@ -15,6 +15,7 @@ else gst_version_nano = 0 endif +libva_req = ['>= 0.30.4', '!= 0.99.0'] glib_req = '>= 2.40.0' gst_req = '>= @0@.@1@.0'.format(gst_version_major, gst_version_minor) @@ -37,7 +38,7 @@ gstcodecparsers_dep = dependency('gstreamer-codecparsers-1.0', version : gst_req gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, fallback : ['gst-plugins-bad', 'gstgl_dep'], required: false) gmodule_dep = dependency('gmodule-2.0', required: false) -libva_dep = dependency('libva', version: ['>= 0.30.4', '< 0.99.0']) +libva_dep = dependency('libva', version: libva_req) libva_drm_dep = dependency('libva-drm', version: '>= 0.33.0', required: false) libva_wayland_dep = dependency('libva-wayland', version: '>= 0.33.0', required: false) From 8f2eb70803099d4b533ecc10fc259041d8714210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 26 Jul 2017 20:03:35 +0200 Subject: [PATCH 2851/3781] build: check for libva-2.0 Check for libva-2.0 since libva's developers decided to increase the library's version number. https://bugzilla.gnome.org/show_bug.cgi?id=784398 --- configure.ac | 25 +++++++++++++++++++------ meson.build | 27 +++++++++++++++++++++++---- meson_options.txt | 1 + 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 230f352273..ce1e02348d 100644 --- a/configure.ac +++ b/configure.ac @@ -120,6 +120,11 @@ AG_GST_SET_PACKAGE_RELEASE_DATETIME_WITH_NANO([$PACKAGE_VERSION_NANO], ["${srcdir}/gstreamer-vaapi.doap"], [$PACKAGE_VERSION_MAJOR.$PACKAGE_VERSION_MINOR.$PACKAGE_VERSION_MICRO]) +AC_ARG_WITH([libva], + [AS_HELP_STRING([--with-libva[[=VERSION]]], + [which version of libva use (1 or 2) @<:@default=check@:>@])], + [], [with_libva="check"]) + AC_ARG_ENABLE([encoders], AS_HELP_STRING([--enable-encoders], [enable video encoders @<:@default=yes@:>@]), @@ -505,15 +510,23 @@ dnl -- VA-API -- dnl --------------------------------------------------------------------------- dnl Core API -PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ libva != 0.99.0]) -VA_VERSION_STR=`$PKG_CONFIG --modversion libva` -VA_DRIVERS_PATH=`$PKG_CONFIG --variable=driverdir libva` +LIBVA_VERSION= +AS_CASE([$with_libva], + [2], [PKG_CHECK_MODULES([LIBVA], [libva-2.0 >= 1.0.0], + [LIBVA_VERSION="-2.0"])], + [1], [PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ libva != 0.99.0])], + [PKG_CHECK_MODULES([LIBVA], [libva-2.0 >= 1.0.0], + [LIBVA_VERSION="-2.0"], + [PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ libva != 0.99.0])])]) + +VA_VERSION_STR=`$PKG_CONFIG --modversion libva$LIBVA_VERSION` +VA_DRIVERS_PATH=`$PKG_CONFIG --variable=driverdir libva$LIBVA_VERSION` AC_DEFINE_UNQUOTED([VA_DRIVERS_PATH], ["$VA_DRIVERS_PATH"], [VA drivers path]) dnl VA/DRM API if test $USE_DRM -eq 1; then - PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= $VAAPI_DRM_REQ], + PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm$LIBVA_VERSION >= $VAAPI_DRM_REQ], [ saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_DRM_CFLAGS" @@ -524,7 +537,7 @@ fi dnl VA/X11 API if test $USE_X11 -eq 1; then - PKG_CHECK_MODULES(LIBVA_X11, [libva-x11 >= $VAAPI_X11_REQ], + PKG_CHECK_MODULES(LIBVA_X11, [libva-x11$LIBVA_VERSION >= $VAAPI_X11_REQ], [], [USE_X11=0]) fi @@ -884,7 +897,7 @@ fi dnl VA/Wayland API if test $USE_WAYLAND -eq 1; then - PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= $VAAPI_WLD_REQ], + PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland$LIBVA_VERSION >= $VAAPI_WLD_REQ], [], [USE_WAYLAND=0]) fi diff --git a/meson.build b/meson.build index 10d2af0ce7..8e39584a17 100644 --- a/meson.build +++ b/meson.build @@ -38,11 +38,30 @@ gstcodecparsers_dep = dependency('gstreamer-codecparsers-1.0', version : gst_req gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, fallback : ['gst-plugins-bad', 'gstgl_dep'], required: false) gmodule_dep = dependency('gmodule-2.0', required: false) -libva_dep = dependency('libva', version: libva_req) -libva_drm_dep = dependency('libva-drm', version: '>= 0.33.0', required: false) -libva_wayland_dep = dependency('libva-wayland', version: '>= 0.33.0', required: false) -libva_x11_dep = dependency('libva-x11', version: '>= 0.31.0', required: false) +libva_version = '' +if get_option('with_libva') == 'auto' + libva_dep = dependency('libva-2.0', required : false) + if not libva_dep.found() + libva_dep = dependency('libva', version: libva_req) + else + libva_version = '-2.0' + endif +else + if get_option('with_libva') == '2' + libva_dep = dependency('libva-2.0') + libva_version = '-2.0' + else + libva_dep = dependency('libva', version: libva_req) + endif +endif + +libva_drm_dep = dependency('libva-drm' + libva_version, version: '>= 0.33.0', + required: false) +libva_wayland_dep = dependency('libva-wayland' + libva_version, + version: '>= 0.33.0', required: false) +libva_x11_dep = dependency('libva-x11' + libva_version, version: '>= 0.31.0', + required: false) libdrm_dep = dependency('libdrm', required: false) libudev_dep = dependency('libudev', required: false) egl_dep = dependency('egl', required: false) diff --git a/meson_options.txt b/meson_options.txt index 018f8bc33d..b411067cbe 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,3 +1,4 @@ +option('with_libva', type : 'combo', choices : ['1', '2', 'auto'], value : 'auto') option('with_encoders', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') option('with_drm', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') option('with_x11', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') From e0e0a47476ed050209dde61b214a2961ef7fd612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 11 Jul 2017 17:27:32 +0200 Subject: [PATCH 2852/3781] libs: decoder: h264: libva 1.0 deprecated baseline libva 1.0 deprecated H.264 baseline profile and FMO support (commit b4f332b3). https://bugzilla.gnome.org/show_bug.cgi?id=784398 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index e971f75012..9c96180734 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -3849,9 +3849,12 @@ fill_picture (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) COPY_FIELD (sps, bit_depth_luma_minus8); COPY_FIELD (sps, bit_depth_chroma_minus8); COPY_FIELD (sps, num_ref_frames); +#if !VA_CHECK_VERSION(1,0,0) + /* Deprecate H.264 baseline profile and FMO support */ COPY_FIELD (pps, num_slice_groups_minus1); COPY_FIELD (pps, slice_group_map_type); COPY_FIELD (pps, slice_group_change_rate_minus1); +#endif COPY_FIELD (pps, pic_init_qp_minus26); COPY_FIELD (pps, pic_init_qs_minus26); COPY_FIELD (pps, chroma_qp_index_offset); From 777bba473e3ed1c7b8b7f7f0322892851c70dfd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 11 Jul 2017 17:29:13 +0200 Subject: [PATCH 2853/3781] libs: utils: libva 1.0 changed the logging The logging mechanism in libva has changed it's functions signatures. This patch updates that for libva versions >= 1.0 https://bugzilla.gnome.org/show_bug.cgi?id=784398 --- gst-libs/gst/vaapi/gstvaapiutils.c | 39 +++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 0ed1efe101..c24bed7b6b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -46,15 +46,43 @@ #define STRCASE(x) case x: return STRINGIFY(x) #if VA_CHECK_VERSION (0,40,0) -static void -gst_vaapi_log (const char *message) +static gchar * +strip_msg (const char *message) { gchar *msg; msg = g_strdup (message); + if (!msg) + return NULL; + return g_strstrip (msg); +} + +#if VA_CHECK_VERSION (1,0,0) +static void +gst_vaapi_err (void *data, const char *message) +{ + gchar *msg; + + msg = strip_msg (message); + if (!msg) + return; + GST_ERROR ("%s", msg); + g_free (msg); +} +#endif + +static void +gst_vaapi_log ( +#if VA_CHECK_VERSION (1,0,0) + void *data, +#endif + const char *message) +{ + gchar *msg; + + msg = strip_msg (message); if (!msg) return; - g_strchomp (msg); GST_INFO ("%s", msg); g_free (msg); } @@ -66,7 +94,10 @@ vaapi_initialize (VADisplay dpy) gint major_version, minor_version; VAStatus status; -#if VA_CHECK_VERSION (0,40,0) +#if VA_CHECK_VERSION (1,0,0) + vaSetErrorCallback (dpy, gst_vaapi_err, NULL); + vaSetInfoCallback (dpy, gst_vaapi_log, NULL); +#elif VA_CHECK_VERSION (0,40,0) vaSetInfoCallback (gst_vaapi_log); #endif From f775bbfe0765883fe656700f909faa14a3bf35f3 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 5 Jul 2017 17:13:44 -0700 Subject: [PATCH 2854/3781] libs: utils_h264: Extend LevelLimit table with MinCR field Add MinCR(Minimum Compression Ratio) field to GstVaapiH264LevelLimits based on Annex A.3 https://bugzilla.gnome.org/show_bug.cgi?id=784590 --- gst-libs/gst/vaapi/gstvaapiutils_h264.c | 36 ++++++++++---------- gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h | 2 ++ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index f8d95feeac..180e22fad5 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -76,24 +76,24 @@ static const struct map gst_vaapi_h264_level_map[] = { /* Table A-1 - Level limits */ /* *INDENT-OFF* */ static const GstVaapiH264LevelLimits gst_vaapi_h264_level_limits[] = { - /* level idc MaxMBPS MaxFS MaxDpbMbs MaxBR MaxCPB */ - { GST_VAAPI_LEVEL_H264_L1, 10, 1485, 99, 396, 64, 175 }, - { GST_VAAPI_LEVEL_H264_L1b, 11, 1485, 99, 396, 128, 350 }, - { GST_VAAPI_LEVEL_H264_L1_1, 11, 3000, 396, 900, 192, 500 }, - { GST_VAAPI_LEVEL_H264_L1_2, 12, 6000, 396, 2376, 384, 1000 }, - { GST_VAAPI_LEVEL_H264_L1_3, 13, 11880, 396, 2376, 768, 2000 }, - { GST_VAAPI_LEVEL_H264_L2, 20, 11880, 396, 2376, 2000, 2000 }, - { GST_VAAPI_LEVEL_H264_L2_1, 21, 19800, 792, 4752, 4000, 4000 }, - { GST_VAAPI_LEVEL_H264_L2_2, 22, 20250, 1620, 8100, 4000, 4000 }, - { GST_VAAPI_LEVEL_H264_L3, 30, 40500, 1620, 8100, 10000, 10000 }, - { GST_VAAPI_LEVEL_H264_L3_1, 31, 108000, 3600, 18000, 14000, 14000 }, - { GST_VAAPI_LEVEL_H264_L3_2, 32, 216000, 5120, 20480, 20000, 20000 }, - { GST_VAAPI_LEVEL_H264_L4, 40, 245760, 8192, 32768, 20000, 25000 }, - { GST_VAAPI_LEVEL_H264_L4_1, 41, 245760, 8192, 32768, 50000, 62500 }, - { GST_VAAPI_LEVEL_H264_L4_2, 42, 522240, 8704, 34816, 50000, 62500 }, - { GST_VAAPI_LEVEL_H264_L5, 50, 589824, 22080, 110400, 135000, 135000 }, - { GST_VAAPI_LEVEL_H264_L5_1, 51, 983040, 36864, 184320, 240000, 240000 }, - { GST_VAAPI_LEVEL_H264_L5_2, 52, 2073600, 36864, 184320, 240000, 240000 }, + /* level idc MaxMBPS MaxFS MaxDpbMbs MaxBR MaxCPB MinCr */ + { GST_VAAPI_LEVEL_H264_L1, 10, 1485, 99, 396, 64, 175, 2 }, + { GST_VAAPI_LEVEL_H264_L1b, 11, 1485, 99, 396, 128, 350, 2 }, + { GST_VAAPI_LEVEL_H264_L1_1, 11, 3000, 396, 900, 192, 500, 2 }, + { GST_VAAPI_LEVEL_H264_L1_2, 12, 6000, 396, 2376, 384, 1000, 2 }, + { GST_VAAPI_LEVEL_H264_L1_3, 13, 11880, 396, 2376, 768, 2000, 2 }, + { GST_VAAPI_LEVEL_H264_L2, 20, 11880, 396, 2376, 2000, 2000, 2 }, + { GST_VAAPI_LEVEL_H264_L2_1, 21, 19800, 792, 4752, 4000, 4000, 2 }, + { GST_VAAPI_LEVEL_H264_L2_2, 22, 20250, 1620, 8100, 4000, 4000, 2 }, + { GST_VAAPI_LEVEL_H264_L3, 30, 40500, 1620, 8100, 10000, 10000, 2 }, + { GST_VAAPI_LEVEL_H264_L3_1, 31, 108000, 3600, 18000, 14000, 14000, 4 }, + { GST_VAAPI_LEVEL_H264_L3_2, 32, 216000, 5120, 20480, 20000, 20000, 4 }, + { GST_VAAPI_LEVEL_H264_L4, 40, 245760, 8192, 32768, 20000, 25000, 4 }, + { GST_VAAPI_LEVEL_H264_L4_1, 41, 245760, 8192, 32768, 50000, 62500, 2 }, + { GST_VAAPI_LEVEL_H264_L4_2, 42, 522240, 8704, 34816, 50000, 62500, 2 }, + { GST_VAAPI_LEVEL_H264_L5, 50, 589824, 22080, 110400, 135000, 135000, 2 }, + { GST_VAAPI_LEVEL_H264_L5_1, 51, 983040, 36864, 184320, 240000, 240000, 2 }, + { GST_VAAPI_LEVEL_H264_L5_2, 52, 2073600, 36864, 184320, 240000, 240000, 2 }, { 0, } }; /* *INDENT-ON* */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h index 0ca552a807..8fe0d41c44 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h @@ -37,6 +37,7 @@ G_BEGIN_DECLS * @MaxDpbMbs: the maxium decoded picture buffer size (MBs) * @MaxBR: the maximum video bit rate (kbps) * @MaxCPB: the maximum CPB size (kbits) + * @MinCR: the minimum Compression Ratio * * The data structure that describes the limits of an H.264 level. */ @@ -48,6 +49,7 @@ typedef struct { guint32 MaxDpbMbs; guint32 MaxBR; guint32 MaxCPB; + guint32 MinCR; } GstVaapiH264LevelLimits; /* Returns GstVaapiProfile from H.264 profile_idc value */ From aa3543929b163ea959937bca8262ffb991e701a4 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 19 Jul 2017 12:02:40 -0700 Subject: [PATCH 2855/3781] libs: encoder: h264: Add uncompliant mode reducing coded buffer size Added a new property "compliance-mode", which default is the normal strict compliant mode. The second mode, "restrict-buf-alloc", is to limit the coded buffer allocation size to improve performance in some specific Intel platforms (there is asignificant performance improvement in parallel encodings). Under this new mode, we use the MinCR field in A.3.1 for pre-calculating the coded-buffer size. https://bugzilla.gnome.org/show_bug.cgi?id=784590 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 69 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 + 2 files changed, 71 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 601a4be28d..a382412456 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -76,6 +76,37 @@ #define GST_H264_NAL_REF_IDC_MEDIUM 2 #define GST_H264_NAL_REF_IDC_HIGH 3 +typedef enum +{ + GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT = 0, + GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_RESTRICT_CODED_BUFFER_ALLOC = 1, +} GstVaapiEnoderH264ComplianceMode; + +static GType +gst_vaapi_encoder_h264_compliance_mode_type (void) +{ + static GType gtype = 0; + + if (gtype == 0) { + static const GEnumValue values[] = { + {GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT, + "Strict compliance to the H264 Specification ", + "strict"}, + /* The main intention is to reduce the CodedBuffer Size allocation. + * This will help to get better performance in some of the Intel + * platforms which has LLC restirictions */ + {GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_RESTRICT_CODED_BUFFER_ALLOC, + "Restict the allocation size of coded-buffer", + "restrict-buf-alloc"}, + {0, NULL, NULL}, + }; + + gtype = + g_enum_register_static ("GstVaapiEncoderH264ComplianceMode", values); + } + return gtype; +} + /* only for internal usage, values won't be equal to actual payload type */ typedef enum { @@ -717,6 +748,10 @@ struct _GstVaapiEncoderH264 GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS]; gboolean use_aud; + + /* Complance mode */ + GstVaapiEnoderH264ComplianceMode compliance_mode; + guint min_cr; // Minimum Compression Ratio (A.3.1) }; /* Write a SEI buffering period payload */ @@ -1140,6 +1175,7 @@ ensure_level (GstVaapiEncoderH264 * encoder) encoder->level = limits_table[i].level; encoder->level_idc = limits_table[i].level_idc; + encoder->min_cr = limits_table[i].MinCR; return TRUE; /* ERRORS */ @@ -2880,6 +2916,17 @@ set_context_info (GstVaapiEncoder * base_encoder) /* Account for slice header */ base_encoder->codedbuf_size += encoder->num_slices * (4 + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); + /* Some of the Intel Platforms(eg: APL) doesn't have LLC so + * the driver call cflush to ensure data consistency which is an + * expensive operation but we can still reduce the impact by + * limitting the pre-calculated coded_buffer size. This is not + * strictly following the h264 specification, but should be safe + * enough with intel-vaapi-driver. Our test cases showing significat + * performance improvement on APL platfrom with small coded-buffer size */ + if (encoder->compliance_mode == + GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_RESTRICT_CODED_BUFFER_ALLOC) + base_encoder->codedbuf_size /= encoder->min_cr; + base_encoder->context_info.entrypoint = encoder->entrypoint; @@ -2959,6 +3006,9 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder) ref_pool->max_reflist1_count = 1; } + encoder->compliance_mode = GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT; + encoder->min_cr = 1; + return TRUE; } @@ -3051,6 +3101,10 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_AUD: encoder->use_aud = g_value_get_boolean (value); break; + case GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE: + encoder->compliance_mode = g_value_get_enum (value); + break; + default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -3228,6 +3282,21 @@ gst_vaapi_encoder_h264_get_default_properties (void) "Use AU (Access Unit) delimeter", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:Compliance Mode: + * + * Encode Tuning(Tweaking) with different compliance modes . + * + * + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE, + g_param_spec_enum ("compliance-mode", + "Spec Compliance Mode", + "Tune Encode quality/performance by relaxing specification compliance restrictions", + gst_vaapi_encoder_h264_compliance_mode_type (), + GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT, G_PARAM_READWRITE)); + return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 5019b6cf4e..dec2ea974a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -48,6 +48,7 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * in milliseconds (uint). * @GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: Number of views per frame. * @GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS: View IDs + * @GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE: Relax Compliance restrictions * * The set of H.264 encoder specific configurable properties. */ @@ -62,6 +63,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS = -8, GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS = -9, GST_VAAPI_ENCODER_H264_PROP_AUD = -10, + GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE = -11, } GstVaapiEncoderH264Prop; GstVaapiEncoder * From c18130890418a9fb0665de0c873150dd8cee9379 Mon Sep 17 00:00:00 2001 From: Tomas Rataj Date: Thu, 27 Jul 2017 10:54:00 +0000 Subject: [PATCH 2856/3781] libs: display: when appending formats change pointers to indexes Thus, it fixes an invalid read when YV12 or I420 are not supported by the driver. https://bugzilla.gnome.org/show_bug.cgi?id=785085 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 73da04eb78..bf23ccb6e4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -209,13 +209,13 @@ append_formats (GArray * formats, const VAImageFormat * va_formats, guint * flags, guint n) { GstVideoFormat format; - const GstVaapiFormatInfo *YV12_fip = NULL; - const GstVaapiFormatInfo *I420_fip = NULL; + int YV12_idx = -1; + int I420_idx = -1; + const GstVaapiFormatInfo *fip; guint i; for (i = 0; i < n; i++) { const VAImageFormat *const va_format = &va_formats[i]; - const GstVaapiFormatInfo **fipp; format = gst_vaapi_video_format_from_va_format (va_format); if (format == GST_VIDEO_FORMAT_UNKNOWN) { @@ -227,25 +227,25 @@ append_formats (GArray * formats, const VAImageFormat * va_formats, switch (format) { case GST_VIDEO_FORMAT_YV12: - fipp = &YV12_fip; + YV12_idx = formats->len - 1; break; case GST_VIDEO_FORMAT_I420: - fipp = &I420_fip; + I420_idx = formats->len - 1; break; default: - fipp = NULL; break; } - if (fipp) - *fipp = &g_array_index (formats, GstVaapiFormatInfo, formats->len - 1); } /* Append I420 (resp. YV12) format if YV12 (resp. I420) is not supported by the underlying driver */ - if (YV12_fip && !I420_fip) - append_format (formats, GST_VIDEO_FORMAT_I420, YV12_fip->flags); - else if (I420_fip && !YV12_fip) - append_format (formats, GST_VIDEO_FORMAT_YV12, I420_fip->flags); + if ((YV12_idx != -1) && (I420_idx == -1)) { + fip = &g_array_index (formats, GstVaapiFormatInfo, YV12_idx); + append_format (formats, GST_VIDEO_FORMAT_I420, fip->flags); + } else if ((I420_idx != -1) && (YV12_idx == -1)) { + fip = &g_array_index (formats, GstVaapiFormatInfo, I420_idx); + append_format (formats, GST_VIDEO_FORMAT_YV12, fip->flags); + } } /* Sort image formats. Prefer YUV formats first */ From ce03fa8ed0aec7acc787e831d11286d958edf6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 1 Aug 2017 17:23:48 +0200 Subject: [PATCH 2857/3781] vaapipostproc: fix memory leaks --- gst/vaapi/gstvaapipostprocutil.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 4bfc169cfa..9c344b122f 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -256,8 +256,10 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, /* Might have failed but try to keep the DAR nonetheless by * adjusting the PAR */ if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, h, set_w, - &to_par_n, &to_par_d)) + &to_par_n, &to_par_d)) { + gst_structure_free (tmp); goto overflow_error; + } if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); @@ -328,8 +330,10 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, /* Might have failed but try to keep the DAR nonetheless by * adjusting the PAR */ if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, w, - &to_par_n, &to_par_d)) + &to_par_n, &to_par_d)) { + gst_structure_free (tmp); goto overflow_error; + } if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); @@ -439,8 +443,10 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, gst_structure_get_int (tmp, "width", &set_w); if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, set_w, - &to_par_n, &to_par_d)) + &to_par_n, &to_par_d)) { + gst_structure_free (tmp); goto overflow_error; + } if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); From 19444ce1840d76e555d283a3f12d87b1b25ca529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 1 Aug 2017 17:29:40 +0200 Subject: [PATCH 2858/3781] vaapisink: fix memory leak --- gst/vaapi/gstvaapisink.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 96ca674866..9336e540f4 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1253,8 +1253,7 @@ gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, "{ ENCODED, NV12, I420, YV12 }"); - GstCapsFeatures *const features = gst_caps_features_new - (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL); + GstCapsFeatures *features; if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)) return gst_static_pad_template_get_caps (&gst_vaapisink_sink_factory); @@ -1269,6 +1268,8 @@ gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) gst_caps_append (out_caps, gst_caps_copy (raw_caps)); feature_caps = gst_caps_copy (raw_caps); + features = gst_caps_features_new + (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL); gst_caps_set_features (feature_caps, 0, features); gst_caps_append (out_caps, feature_caps); From de0f8936f82ef6cdede02299def8a50993fe92c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 1 Aug 2017 17:39:04 +0200 Subject: [PATCH 2859/3781] vaapivideobufferpool: don't shift by negative since it's undefined The function g_bit_nth_lsf() may return -1 if the request bit position is not avaible. Thus, this patch check if the return value is not -1 in order to continue. --- gst/vaapi/gstvaapivideobufferpool.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index dcdc29e9f9..f4b1a42f68 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -106,11 +106,14 @@ fill_video_alignment (GstVaapiVideoBufferPool * pool, GstVideoAlignment * align) { GstVideoInfo *const vip = &pool->priv->vmeta_vinfo; guint i; + gint nth_bit; gst_video_alignment_reset (align); - for (i = 0; i < GST_VIDEO_INFO_N_PLANES (vip); i++) - align->stride_align[i] = - (1U << g_bit_nth_lsf (GST_VIDEO_INFO_PLANE_STRIDE (vip, i), 0)) - 1; + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (vip); i++) { + nth_bit = g_bit_nth_lsf (GST_VIDEO_INFO_PLANE_STRIDE (vip, i), 0); + if (nth_bit >= 0) + align->stride_align[i] = (1U << nth_bit) - 1; + } } static const gchar ** From 02e48ad8dc3f31971786addb795d54851ff2360c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 1 Aug 2017 17:59:38 +0200 Subject: [PATCH 2860/3781] plugins: avoid dead code detection By using #elif macro, the static code analysis would stop to detect these lines as dead code. Also it is inforced the mutually exclusive environments. --- gst/vaapi/gstvaapipluginutil.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index e9ff8b6e93..c38334fc25 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -180,8 +180,7 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) #if USE_X11 && GST_GL_HAVE_WINDOW_X11 if (!display_type) display_type = GST_VAAPI_DISPLAY_TYPE_X11; -#endif -#if USE_WAYLAND && GST_GL_HAVE_WINDOW_WAYLAND +#elif USE_WAYLAND && GST_GL_HAVE_WINDOW_WAYLAND if (!display_type) display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; #endif From 5f64d6df6cf3e62265e3ed29ef9c41cbe6f1b5fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 1 Aug 2017 18:10:50 +0200 Subject: [PATCH 2861/3781] plugins: check gst_gl_ensure_element_data() return value Refactor gst_vaapi_plugin_base_create_gl_context() in order to check the return value of gst_gl_ensure_element_data(). The result is a code bit cleaner. --- gst/vaapi/gstvaapipluginbase.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 6a81f37182..76d136109e 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1213,16 +1213,14 @@ gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin) GstGLContext *gl_other_context, *gl_context = NULL; GstGLDisplay *gl_display; - gst_gl_ensure_element_data (plugin, (GstGLDisplay **) & plugin->gl_display, - (GstGLContext **) & plugin->gl_other_context); + if (!gst_gl_ensure_element_data (plugin, + (GstGLDisplay **) & plugin->gl_display, + (GstGLContext **) & plugin->gl_other_context)) + goto no_valid_gl_display; gl_display = (GstGLDisplay *) plugin->gl_display; - if (!gl_display || - gst_gl_display_get_handle_type (gl_display) == GST_GL_DISPLAY_TYPE_ANY) { - gst_object_replace (&plugin->gl_display, NULL); - gst_object_replace (&plugin->gl_other_context, NULL); - return NULL; - } + if (gst_gl_display_get_handle_type (gl_display) == GST_GL_DISPLAY_TYPE_ANY) + goto no_valid_gl_display; gl_other_context = (GstGLContext *) plugin->gl_other_context; GST_INFO_OBJECT (plugin, "creating a new GstGL context"); @@ -1241,6 +1239,14 @@ gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin) GST_OBJECT_UNLOCK (gl_display); return GST_OBJECT_CAST (gl_context); + + /* ERRORS */ +no_valid_gl_display: + { + gst_object_replace (&plugin->gl_display, NULL); + gst_object_replace (&plugin->gl_other_context, NULL); + return NULL; + } #else return NULL; #endif From 7d6a80e13d41e1863f9e4f188adba80187fd57ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 1 Aug 2017 18:38:40 +0200 Subject: [PATCH 2862/3781] vaapiencode: h265: compare an unsigned int if not zero An unsigned value can never be negative, so this test (greater than zero) will always evaluate the same way. Thus change it to just if it's not zero. --- gst/vaapi/gstvaapiencode_h265.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 8c8d2e214f..3a71d0676c 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -281,7 +281,7 @@ _h265_byte_stream_next_nal (guint8 * buffer, guint32 len, guint32 * nal_size) guint32 flag = 0xFFFFFFFF; guint32 nal_start_len = 0; - g_assert (len >= 0 && buffer && nal_size); + g_assert (len != 0U && buffer && nal_size); if (len < 3) { *nal_size = len; nal_start = (len ? buffer : NULL); From ec76a9a7e3eb1da58190799c15854897daa2898e Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 28 Jul 2017 15:27:20 +0900 Subject: [PATCH 2863/3781] libs: encoder: implements gst_vaapi_encoder_ensure_max_num_ref_frames This function will query VAConfigAttribEncMaxRefFrames to get the maximum number of reference frames supported in the driver. This will be used for h264/h265 encoding. https://bugzilla.gnome.org/show_bug.cgi?id=783803 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 43 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 10 ++++++ 2 files changed, 53 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index bdb8d9ef49..d761bfa242 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1511,6 +1511,49 @@ gst_vaapi_encoder_ensure_num_slices (GstVaapiEncoder * encoder, return TRUE; } +/** + * gst_vaapi_encoder_ensure_max_num_ref_frames: + * @encoder: a #GstVaapiEncoder + * @profile: a #GstVaapiProfile + * @entrypoint: a #GstVaapiEntrypoint + * + * This function will query VAConfigAttribEncMaxRefFrames to get the + * maximum number of reference frames in the driver, + * for both the reference picture list 0 (bottom 16 bits) and + * the reference picture list 1 (top 16 bits). + * + * We need to pass the @profile and the @entrypoint, because at the + * moment the encoder base class, still doesn't have them assigned, + * and this function is meant to be called by the derived classes + * while they are configured. + * + * Returns: %TRUE if the number of reference frames is different than zero. + **/ +gboolean +gst_vaapi_encoder_ensure_max_num_ref_frames (GstVaapiEncoder * encoder, + GstVaapiProfile profile, GstVaapiEntrypoint entrypoint) +{ + VAProfile va_profile; + VAEntrypoint va_entrypoint; + guint max_ref_frames; + + va_profile = gst_vaapi_profile_get_va_profile (profile); + va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint (entrypoint); + + if (!gst_vaapi_get_config_attribute (encoder->display, va_profile, + va_entrypoint, VAConfigAttribEncMaxRefFrames, &max_ref_frames)) { + /* Set the default the number of reference frames */ + encoder->max_num_ref_frames_0 = 1; + encoder->max_num_ref_frames_1 = 0; + return TRUE; + } + + encoder->max_num_ref_frames_0 = max_ref_frames & 0xffff; + encoder->max_num_ref_frames_1 = (max_ref_frames >> 16) & 0xffff; + + return TRUE; +} + /** * gst_vaapi_encoder_add_roi: * @encoder: a #GstVaapiEncoder diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 598aabf263..d73689e409 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -261,6 +261,11 @@ struct _GstVaapiEncoder guint bitrate; /* kbps */ 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; @@ -411,6 +416,11 @@ 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_END_DECLS #endif /* GST_VAAPI_ENCODER_PRIV_H */ From cd6a9736bd289157bb1dbf4358f1439365ce289d Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 2 Aug 2017 14:53:34 +0900 Subject: [PATCH 2864/3781] libs: encoder: h264: add refs property Users can provide the number of reference frame by this property. The value of the property will be considered as the number of reference picture list0 and will add 1 reference frame more to the reference picture list1 internally if b-frame encoding. If the value provided is bigger than the number of refrence frames supported in the driver, it will be lowered. https://bugzilla.gnome.org/show_bug.cgi?id=783803 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 16 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index a382412456..34018286bf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -730,6 +730,7 @@ struct _GstVaapiEncoderH264 guint32 idr_num; guint8 pic_order_cnt_type; guint8 delta_pic_order_always_zero_flag; + guint num_ref_frames; GstBuffer *sps_data; GstBuffer *subset_sps_data; @@ -3104,6 +3105,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE: encoder->compliance_mode = g_value_get_enum (value); break; + case GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES: + encoder->num_ref_frames = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; @@ -3171,6 +3175,18 @@ gst_vaapi_encoder_h264_get_default_properties (void) "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:refs: + * + * The number of reference frames. + * If B frame is encoded, it will add 1 reference frame more. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES, + g_param_spec_uint ("refs", "Number of Reference Frames", + "Number of reference frames", 1, 8, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiEncoderH264:init-qp: * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index dec2ea974a..181cadec18 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -49,6 +49,7 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * @GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: Number of views per frame. * @GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS: View IDs * @GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE: Relax Compliance restrictions + * @GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES: Maximum number of reference frames. * * The set of H.264 encoder specific configurable properties. */ @@ -64,6 +65,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS = -9, GST_VAAPI_ENCODER_H264_PROP_AUD = -10, GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE = -11, + GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES = -12, } GstVaapiEncoderH264Prop; GstVaapiEncoder * From cdaf15b24d966093f2ca51fbfa1b1757cd3bcb0f Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 2 Aug 2017 14:54:53 +0900 Subject: [PATCH 2865/3781] libs: encoder: h264: add multi reference support Using num_ref_frames provided and the result of the Query VAConfigAttribEncMaxRefFrames, it determines the size of reference list and perform encoding with multi reference frames as the following: 1\ The num_ref_frames is being considered as the number of reference picture list0 2\ Encoder adds 1 reference frame more to the reference picture list1 internally if b-frame encoding. 3\ If num_ref_frames is bigger than the number of refrence frames supported in the driver, it will be lowered. https://bugzilla.gnome.org/show_bug.cgi?id=783803 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 36 +++++++++++------------ 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 34018286bf..61ad175a86 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2086,7 +2086,7 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, /* only works for B frames */ slice_param->direct_spatial_mv_pred_flag = FALSE; /* default equal to picture parameters */ - slice_param->num_ref_idx_active_override_flag = FALSE; + slice_param->num_ref_idx_active_override_flag = TRUE; if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; else @@ -2095,8 +2095,6 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; else slice_param->num_ref_idx_l1_active_minus1 = 0; - g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0); - g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0); i_ref = 0; if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { @@ -2109,10 +2107,10 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, VA_PICTURE_H264_SHORT_TERM_REFERENCE; slice_param->RefPicList0[i_ref].frame_idx = reflist_0[i_ref]->frame_num; } - g_assert (i_ref == 1); } for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) { slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->RefPicList0[i_ref].flags = VA_PICTURE_H264_INVALID; } i_ref = 0; @@ -2127,10 +2125,10 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, slice_param->RefPicList1[i_ref].frame_idx |= reflist_1[i_ref]->frame_num; } - g_assert (i_ref == 1); } for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) { slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->RefPicList0[i_ref].flags = VA_PICTURE_H264_INVALID; } /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */ @@ -2551,20 +2549,20 @@ reset_properties (GstVaapiEncoderH264 * encoder) if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; - /* Workaround : vaapi-intel-driver doesn't have support for - * B-frame encode when utilizing low-power encode hardware block. - * So Disabling b-frame encoding in low-pwer encode. - * - * Fixme :We should query the VAConfigAttribEncMaxRefFrames - * instead of blindly disabling b-frame support and set b/p frame count, - * buffer pool size etc based on that.*/ - if ((encoder->num_bframes > 0) - && (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)) { - GST_WARNING - ("Disabling b-frame since the driver doesn't supporting it in low-power encode"); + gst_vaapi_encoder_ensure_max_num_ref_frames (base_encoder, encoder->profile, + encoder->entrypoint); + + if (base_encoder->max_num_ref_frames_1 < 1 && encoder->num_bframes > 0) { + GST_WARNING ("Disabling b-frame since the driver doesn't support it"); encoder->num_bframes = 0; } + if (encoder->num_ref_frames > base_encoder->max_num_ref_frames_0) { + GST_INFO ("Lowering the number of reference frames to %d", + base_encoder->max_num_ref_frames_0); + encoder->num_ref_frames = base_encoder->max_num_ref_frames_0; + } + if (encoder->num_bframes > 0 && GST_VAAPI_ENCODER_FPS_N (encoder) > 0) encoder->cts_offset = gst_util_uint64_scale (GST_SECOND, GST_VAAPI_ENCODER_FPS_D (encoder), GST_VAAPI_ENCODER_FPS_N (encoder)); @@ -2585,7 +2583,7 @@ reset_properties (GstVaapiEncoderH264 * encoder) GstVaapiH264ViewReorderPool *const reorder_pool = &encoder->reorder_pools[i]; - ref_pool->max_reflist0_count = 1; + ref_pool->max_reflist0_count = encoder->num_ref_frames; ref_pool->max_reflist1_count = encoder->num_bframes > 0; ref_pool->max_ref_frames = ref_pool->max_reflist0_count + ref_pool->max_reflist1_count; @@ -2895,8 +2893,8 @@ set_context_info (GstVaapiEncoder * base_encoder) if (!ensure_hw_profile (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - base_encoder->num_ref_frames = - ((encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT) + base_encoder->num_ref_frames = (encoder->num_ref_frames + + (encoder->num_bframes > 0 ? 1 : 0) + DEFAULT_SURFACES_COUNT) * encoder->num_views; /* Only YUV 4:2:0 formats are supported for now. This means that we From a1fc1e9822a9ac03e3740b7a239fa65523a5e1ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 1 Aug 2017 11:11:55 +0200 Subject: [PATCH 2866/3781] libs: encoder: h264: missing property enum documentation --- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 181cadec18..89eab76c33 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -48,6 +48,7 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * in milliseconds (uint). * @GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: Number of views per frame. * @GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS: View IDs + * @GST_VAAPI_ENCODER_H264_PROP_AUD: Insert AUD as first NAL per frame. * @GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE: Relax Compliance restrictions * @GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES: Maximum number of reference frames. * From bd040adb9c93efd2f30154a6e11a2ac46c6b9462 Mon Sep 17 00:00:00 2001 From: orestisf Date: Tue, 25 Jul 2017 22:01:37 +0300 Subject: [PATCH 2867/3781] vaapidecode_props: h264: add base-only property https://bugzilla.gnome.org/show_bug.cgi?id=732265 --- gst/vaapi/gstvaapidecode_props.c | 12 ++++++++++++ gst/vaapi/gstvaapidecode_props.h | 1 + 2 files changed, 13 insertions(+) diff --git a/gst/vaapi/gstvaapidecode_props.c b/gst/vaapi/gstvaapidecode_props.c index 0ca37aae8e..3bc634adaa 100644 --- a/gst/vaapi/gstvaapidecode_props.c +++ b/gst/vaapi/gstvaapidecode_props.c @@ -29,6 +29,7 @@ enum { GST_VAAPI_DECODER_H264_PROP_FORCE_LOW_LATENCY = 1, + GST_VAAPI_DECODER_H264_PROP_BASE_ONLY }; static gint h264_private_offset; @@ -45,6 +46,9 @@ gst_vaapi_decode_h264_get_property (GObject * object, guint prop_id, case GST_VAAPI_DECODER_H264_PROP_FORCE_LOW_LATENCY: g_value_set_boolean (value, priv->is_low_latency); break; + case GST_VAAPI_DECODER_H264_PROP_BASE_ONLY: + g_value_set_boolean (value, priv->base_only); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -67,6 +71,9 @@ gst_vaapi_decode_h264_set_property (GObject * object, guint prop_id, if (decoder) gst_vaapi_decoder_h264_set_low_latency (decoder, priv->is_low_latency); break; + case GST_VAAPI_DECODER_H264_PROP_BASE_ONLY: + priv->base_only = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -88,6 +95,11 @@ gst_vaapi_decode_h264_install_properties (GObjectClass * klass) "When enabled, frames will be pushed as soon as they are available. " "It might violate the H.264 spec.", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (klass, GST_VAAPI_DECODER_H264_PROP_BASE_ONLY, + g_param_spec_boolean ("base-only", "Decode base view only", + "Drop any NAL unit not defined in Annex.A", FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } GstVaapiDecodeH264Private * diff --git a/gst/vaapi/gstvaapidecode_props.h b/gst/vaapi/gstvaapidecode_props.h index 877754f7ad..b1f2fec600 100644 --- a/gst/vaapi/gstvaapidecode_props.h +++ b/gst/vaapi/gstvaapidecode_props.h @@ -33,6 +33,7 @@ typedef struct _GstVaapiDecodeH264Private GstVaapiDecodeH264Private; struct _GstVaapiDecodeH264Private { gboolean is_low_latency; + gboolean base_only; }; void From 1dd03ac2fdf97cd2d9d018a5bd6bc1808f623f7e Mon Sep 17 00:00:00 2001 From: orestisf Date: Tue, 25 Jul 2017 22:03:34 +0300 Subject: [PATCH 2868/3781] libs: decoder: h264: add setter for base-only mode https://bugzilla.gnome.org/show_bug.cgi?id=732265 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 19 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 9c96180734..c5c5fddcda 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -530,6 +530,7 @@ struct _GstVaapiDecoderH264Private guint top_field_first:1; gboolean force_low_latency; + gboolean base_only; }; /** @@ -4800,6 +4801,24 @@ gst_vaapi_decoder_h264_set_alignment (GstVaapiDecoderH264 * decoder, decoder->priv.stream_alignment = alignment; } +/** + * gst_vaapi_decoder_h264_set_base_only: + * @decoder: a #GstVaapiDecoderH264 + * @base_only: %TRUE to force decoding the base view only + * + * if @base_only is %TRUE only the base view of MVC encoded streams + * is decoded. + * + **/ +void +gst_vaapi_decoder_h264_set_base_only (GstVaapiDecoderH264 * decoder, + gboolean base_only) +{ + g_return_if_fail (decoder != NULL); + + decoder->priv.base_only = base_only; +} + /** * gst_vaapi_decoder_h264_set_low_latency: * @decoder: a #GstVaapiDecoderH264 diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h index 9ca65cfc99..d170638134 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -62,6 +62,10 @@ 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_END_DECLS #endif /* GST_VAAPI_DECODER_H264_H */ From 66703a7835e4177c93d46728eda63226e8be4d19 Mon Sep 17 00:00:00 2001 From: orestisf Date: Tue, 25 Jul 2017 22:06:56 +0300 Subject: [PATCH 2869/3781] vaapidecode: set h264 base-only to decoder Set the base-only value when property is set and the internal decoder is already instantiated or when the internal decoder is created. https://bugzilla.gnome.org/show_bug.cgi?id=732265 --- gst/vaapi/gstvaapidecode.c | 2 ++ gst/vaapi/gstvaapidecode_props.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 0cc66f68f1..a0fd4b4733 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -872,6 +872,8 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) if (priv) { gst_vaapi_decoder_h264_set_low_latency (GST_VAAPI_DECODER_H264 (decode->decoder), priv->is_low_latency); + gst_vaapi_decoder_h264_set_base_only (GST_VAAPI_DECODER_H264 + (decode->decoder), priv->base_only); } } break; diff --git a/gst/vaapi/gstvaapidecode_props.c b/gst/vaapi/gstvaapidecode_props.c index 3bc634adaa..e9287b4259 100644 --- a/gst/vaapi/gstvaapidecode_props.c +++ b/gst/vaapi/gstvaapidecode_props.c @@ -73,6 +73,9 @@ gst_vaapi_decode_h264_set_property (GObject * object, guint prop_id, break; case GST_VAAPI_DECODER_H264_PROP_BASE_ONLY: priv->base_only = g_value_get_boolean (value); + decoder = GST_VAAPI_DECODER_H264 (GST_VAAPIDECODE (object)->decoder); + if (decoder) + gst_vaapi_decoder_h264_set_base_only (decoder, priv->base_only); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); From ac9ddc5e8daa9e48a48dd56fdaef869f1f8cc65c Mon Sep 17 00:00:00 2001 From: orestisf Date: Tue, 25 Jul 2017 22:54:30 +0300 Subject: [PATCH 2870/3781] libs: decoder: h264: decode MVC base view only If processed SPS has mvc profile and the configuration is set to base-only, the frame is drop. https://bugzilla.gnome.org/show_bug.cgi?id=732265 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index c5c5fddcda..c7885e4ba1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4050,10 +4050,9 @@ decode_picture (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) g_return_val_if_fail (sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); /* Only decode base stream for MVC */ - switch (sps->profile_idc) { - case GST_H264_PROFILE_MULTIVIEW_HIGH: - case GST_H264_PROFILE_STEREO_HIGH: - break; + if (priv->base_only && is_mvc_profile (sps->profile_idc)) { + GST_DEBUG ("multiview sequence but base-only is set: dropping frame"); + return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; } status = ensure_context (decoder, sps); From d4b6459bb2242c446d29eff7b86ea8f3a8ec1c72 Mon Sep 17 00:00:00 2001 From: orestisf Date: Tue, 25 Jul 2017 22:25:10 +0300 Subject: [PATCH 2871/3781] vaapidecode: force add h264 MVC profiles in caps When vaapih264dec's base-only profile is set to TRUE, fake MVC profile support in caps. https://bugzilla.gnome.org/show_bug.cgi?id=732265 --- gst/vaapi/gstvaapidecode.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a0fd4b4733..e1ac44f463 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1153,12 +1153,30 @@ gst_vaapidecode_parse (GstVideoDecoder * vdec, return ret; } +static gboolean +is_mvc_profile (GstVaapiProfile profile) +{ + return profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH + || profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH; +} + +static GstCaps * +add_h264_profile_in_caps (GstCaps * caps, const gchar * profile_name) +{ + GstCaps *caps_new = + gst_caps_new_simple ("video/x-h264", "profile", profile_name, NULL); + return gst_caps_merge (caps_new, caps); +} + static gboolean gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) { GstCaps *caps, *allowed_sinkpad_caps; GArray *profiles; guint i; + gboolean base_only; + gboolean have_high = FALSE; + gboolean have_mvc = FALSE; profiles = gst_vaapi_display_get_decode_profiles (GST_VAAPI_PLUGIN_BASE_DISPLAY @@ -1170,6 +1188,10 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) if (!allowed_sinkpad_caps) goto error_no_memory; + if (g_object_class_find_property (G_OBJECT_GET_CLASS (decode), "base-only")) { + g_object_get (decode, "base-only", &base_only, NULL); + } + for (i = 0; i < profiles->len; i++) { const GstVaapiProfile profile = g_array_index (profiles, GstVaapiProfile, i); @@ -1192,6 +1214,17 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) profile_name, NULL); allowed_sinkpad_caps = gst_caps_merge (allowed_sinkpad_caps, caps); + have_mvc |= is_mvc_profile (profile); + have_high |= profile == GST_VAAPI_PROFILE_H264_HIGH; + } + + if (base_only && !have_mvc && have_high) { + GST_DEBUG ("base_only: Force adding MVC profiles in caps"); + + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, "multiview-high"); + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, "stereo-high"); } decode->allowed_sinkpad_caps = gst_caps_simplify (allowed_sinkpad_caps); From 3bb96eff14a3320f58392fe7129f946840939735 Mon Sep 17 00:00:00 2001 From: orestisf Date: Thu, 3 Aug 2017 23:17:44 +0300 Subject: [PATCH 2872/3781] vaapidecode: fix gst_caps_new_simple call https://bugzilla.gnome.org/show_bug.cgi?id=732265 --- gst/vaapi/gstvaapidecode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index e1ac44f463..488ab53938 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1164,7 +1164,8 @@ static GstCaps * add_h264_profile_in_caps (GstCaps * caps, const gchar * profile_name) { GstCaps *caps_new = - gst_caps_new_simple ("video/x-h264", "profile", profile_name, NULL); + gst_caps_new_simple ("video/x-h264", "profile", G_TYPE_STRING, + profile_name, NULL); return gst_caps_merge (caps_new, caps); } From 9eddf6c00458f9d611a4a3f5b343ec294538ae6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 13:46:56 +0200 Subject: [PATCH 2873/3781] libs: decoder: h264: remove unrequired NULL check Coverity scan bug: Dereference after null check: Either the check against null is unnecessary, or there may be a null pointer dereference. In the original commit for fill_picture_gaps() (commit 5abd2b90) the prev_picture could be NULL, that's why the code did a null check. But, since commit 52adebe7, the previous reference frames are tracked, thus there is no need to check null anymore. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index c7885e4ba1..5f982a0c4d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -3252,7 +3252,7 @@ fill_picture_gaps (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, return TRUE; prev_frame = priv->prev_ref_frames[picture->base.voc]; - g_assert (prev_frame != NULL); + g_assert (prev_frame != NULL && prev_frame->buffers[0] != NULL); prev_picture = gst_vaapi_picture_ref (prev_frame->buffers[0]); gst_vaapi_picture_ref (picture); @@ -3286,10 +3286,7 @@ fill_picture_gaps (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, break; /* Create new picture */ - if (prev_picture) - lost_picture = gst_vaapi_picture_h264_new_clone (prev_picture); - else - lost_picture = gst_vaapi_picture_h264_new (decoder); + lost_picture = gst_vaapi_picture_h264_new_clone (prev_picture); if (!lost_picture) goto error_allocate_picture; From d879664a0ad55a65f8604be3a44375bc1117633b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 15:38:16 +0200 Subject: [PATCH 2874/3781] libs: decoder: h265: untaint loop control variable Coverity scan bug: Scalars (for example, integers) are not properly bounds-checked (sanitized) before being used as array or pointer indexes, loop boundaries, or function arguments are considered as tainted. In this case, num_nals were not checked before used as loop control. --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 9759dd97c2..3da14e6b7d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2664,7 +2664,17 @@ gst_vaapi_decoder_h265_decode_codec_data (GstVaapiDecoder * num_nal_arrays = buf[22]; ofs = 23; for (i = 0; i < num_nal_arrays; i++) { - num_nals = GST_READ_UINT16_BE (buf + ofs + 1); + const guchar *data; + + if (ofs + 1 > buf_size) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + data = buf + ofs + 1; + if (!data) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + num_nals = GST_READ_UINT16_BE (data); + /* the max number of nals is GST_H265_MAX_PPS_COUNT (64) */ + if (num_nals > 64) + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; ofs += 3; for (j = 0; j < num_nals; j++) { From 067968ae74f321ae9927d43af8b9deab923d17ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 15:49:27 +0200 Subject: [PATCH 2875/3781] libs: decoder: h265: check for null Coverity scan bug: Dereference after null check: Either the check against null is unnecessary, or there may be a null pointer dereference. While looking for hte lowest poc, according to rest of the code, the picture in the dbp (decoded picture buffer) might be NULL, thus we could check for a NULL picture before assigned as found. Also, split a comma operator because it is considered as a bad practice because it possible side effects. --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 3da14e6b7d..a1c856d353 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -717,8 +717,10 @@ dpb_find_lowest_poc (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 *const picture = priv->dpb[i]->buffer; if (picture && !picture->output_needed) continue; - if (!found_picture || found_picture->poc > picture->poc) - found_picture = picture, found_index = i; + if (picture && (!found_picture || found_picture->poc > picture->poc)) { + found_picture = picture; + found_index = i; + } } if (found_picture_ptr) From 4e27245f2893c1d2fef95dca2400ebfc16a3d93c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 16:12:13 +0200 Subject: [PATCH 2876/3781] libs: decoder: mpeg4: fail if return value is not OK Coverity scan bug: An assigned value that is never used may represent unnecessary computation, an incorrect algorithm, or possibly the need for cleanup or refactoring. In the return value of decode_slice() or gst_mpeg4_parse_video_packet_header() are not success, thus fail decode_packet() function. --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 314498f710..bda09b4df0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -900,6 +900,8 @@ decode_packet (GstVaapiDecoderMpeg4 * decoder, GstMpeg4Packet packet) if (first_slice) { status = decode_slice (decoder, _data, video_packet.size, FALSE); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; first_slice = FALSE; } else { _data += video_packet.offset; @@ -909,9 +911,13 @@ decode_packet (GstVaapiDecoderMpeg4 * decoder, GstMpeg4Packet packet) gst_mpeg4_parse_video_packet_header (&priv->packet_hdr, &priv->vol_hdr, &priv->vop_hdr, &priv->sprite_trajectory, _data, _data_size); + if (ret != GST_MPEG4_PARSER_OK) + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; status = decode_slice (decoder, _data + priv->packet_hdr.size / 8, video_packet.size - priv->packet_hdr.size / 8, TRUE); + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + return status; } _data += video_packet.size; From bd7716a739e0a23bbac3e7f04f40c1383d893505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 16:33:44 +0200 Subject: [PATCH 2877/3781] libs: encoder: h265: fix possible integer overflow Coverity scan bug: Unintentional integer overflow. The expression's value may not be what the programmer intended, because the expression is evaluated using a narrow (i.e. few bits) integer type. Cast operator to guint64 before computation to avoid narrowing. merge with 3c5a6add --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 61ad175a86..1a14f6c3de 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2479,7 +2479,7 @@ ensure_bitrate (GstVaapiEncoderH264 * encoder) if (!encoder->use_dct8x8) bits_per_mb += (bits_per_mb * 10) / 100; - factor = encoder->mb_width * encoder->mb_height * bits_per_mb; + factor = (guint64) encoder->mb_width * encoder->mb_height * bits_per_mb; base_encoder->bitrate = gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder)) / 1000; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 7bcb54f3f6..b2bf494d23 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1902,7 +1902,9 @@ ensure_bitrate (GstVaapiEncoderH265 * encoder) /* FIXME: Provide better estimation */ /* Using a 1/6 compression ratio */ /* 12 bits per pixel for YUV420 */ - guint64 factor = encoder->luma_width * encoder->luma_height * 12 / 6; + guint64 factor; + + factor = (guint64) encoder->luma_width * encoder->luma_height * 12 / 6; base_encoder->bitrate = gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder)) / 1000; From f197749343676f31b47c0b6dba4e426609c5e74d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 16:50:39 +0200 Subject: [PATCH 2878/3781] libs: encoder: h264: fix copy & paste error Coverity scan bug: The copied code will not have its intended effect. This is a bug from commit cdaf15b2, where the intention is to initialize RefPicList1 while setting RefPicList0. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 1a14f6c3de..dab3c1494a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2128,7 +2128,7 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, } for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) { slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE; - slice_param->RefPicList0[i_ref].flags = VA_PICTURE_H264_INVALID; + slice_param->RefPicList1[i_ref].flags = VA_PICTURE_H264_INVALID; } /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */ From d65ce31f142080efe00773dc49a6144f8b59bfed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 17:06:17 +0200 Subject: [PATCH 2879/3781] libs: encoder: h265: remove spurious assignation Coverity scan bug: An assigned value that is never used may represent unnecessary computation, an incorrect algorithm, or possibly the need for cleanup or refactoring. ip_period is assigned first to be rewritter inmediatly after. The first assignation is spurious. --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index b2bf494d23..673145c728 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1457,7 +1457,6 @@ fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq_param->intra_idr_period = encoder->idr_period; - seq_param->ip_period = 1 + encoder->num_bframes; seq_param->ip_period = seq_param->intra_period > 1 ? (1 + encoder->num_bframes) : 0; seq_param->bits_per_second = encoder->bitrate_bits; From d99d5704a4a2c3ef9102123e0b8eca80732f8a7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 17:12:06 +0200 Subject: [PATCH 2880/3781] libs: vaapi: object: remove unrequired NULL check Coverity scan bug: Dereference after null check: Either the check against null is unnecessary, or there may be a null pointer dereference. Variable klass has been validated as non-NULL several time before in gst_vaapi_object_new() function, so there is no need to check it again. --- gst-libs/gst/vaapi/gstvaapiobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 15af267953..8609ef7791 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -98,7 +98,7 @@ gst_vaapi_object_new (const GstVaapiObjectClass * klass, if (sub_size > 0) memset (((guchar *) object) + sizeof (*object), 0, sub_size); - if (klass && klass->init) + if (klass->init) klass->init (object); return object; } From fbffda4e2f75ef31080f3a8480246018a006300f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 17:21:52 +0200 Subject: [PATCH 2881/3781] libs: utils: glx: check return value Coverity scan bug: If the function returns an error value, the error value may be mistaken for a normal value. Function sscanf returns the number of assignations done. Validate this return value with the number of expected variables to match. --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index cd9244f06a..714dffbdc8 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -1163,7 +1163,7 @@ GstVaapiGLApi gl_get_current_api (guint * major, guint * minor) { const gchar *version; - gint maj, min, n; + gint maj, min, n, sret; GstVaapiGLApi ret = (1 << 31); while (ret != GST_VAAPI_GL_API_NONE) { @@ -1181,7 +1181,9 @@ gl_get_current_api (guint * major, guint * minor) if (n < 13) goto next; - sscanf (&version[10], "%d.%d", &maj, &min); + sret = sscanf (&version[10], "%d.%d", &maj, &min); + if (sret != 2) + goto next; if (maj <= 0 || min < 0) goto next; @@ -1196,7 +1198,9 @@ gl_get_current_api (guint * major, guint * minor) goto next; } else { - sscanf (version, "%d.%d", &maj, &min); + sret = sscanf (version, "%d.%d", &maj, &min); + if (sret != 2) + goto next; if (maj <= 0 || min < 0) goto next; From 775f912247b246539a8f8bcc66dbbba4f1add167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 17:29:54 +0200 Subject: [PATCH 2882/3781] libs: windows: wayland: fail if cannot remove last frame Converity scan bug: If the function returns an error value, the error value may be mistaken for a normal value. If g_atomic_pointer_compare_and_exchange() fails because the frame is not the last one, the function fails. Thus, logging an info message. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 45934aa720..3d77e45668 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -381,14 +381,16 @@ frame_done (FrameState * frame) GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); g_atomic_int_set (&frame->done, TRUE); - g_atomic_pointer_compare_and_exchange (&priv->last_frame, frame, NULL); - return g_atomic_int_dec_and_test (&priv->num_frames_pending); + if (g_atomic_pointer_compare_and_exchange (&priv->last_frame, frame, NULL)) + return g_atomic_int_dec_and_test (&priv->num_frames_pending); + return FALSE; } static void frame_done_callback (void *data, struct wl_callback *callback, uint32_t time) { - frame_done (data); + if (!frame_done (data)) + GST_INFO ("cannot remove last frame because it didn't match or empty"); } static const struct wl_callback_listener frame_callback_listener = { @@ -401,7 +403,8 @@ frame_release_callback (void *data, struct wl_buffer *wl_buffer) FrameState *const frame = data; if (!frame->done) - frame_done (frame); + if (!frame_done (frame)) + GST_INFO ("cannot remove last frame because it didn't match or empty"); wl_buffer_destroy (wl_buffer); frame_state_free (frame); } From 0b3ca626328605b670eb752b44a1ffdfb587bd8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 17:34:12 +0200 Subject: [PATCH 2883/3781] vaapidecode: initialize variable Coverity scan bug: The variable will contain an arbitrary value left from earlier computations. Variable base_only is fetched from base-only property, and it may be not assigned. It needs to be initialized. --- gst/vaapi/gstvaapidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 488ab53938..d5747d327c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1175,7 +1175,7 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) GstCaps *caps, *allowed_sinkpad_caps; GArray *profiles; guint i; - gboolean base_only; + gboolean base_only = FALSE; gboolean have_high = FALSE; gboolean have_mvc = FALSE; From 9578fd1f7b49b8d6c0dbdd02673814eaf8099aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 17:38:51 +0200 Subject: [PATCH 2884/3781] vaapiencode: h264: remove spurious code Coverity scan bug: An unsigned value can never be negative, so this test will always evaluate the same way. As len is guint32, there is no need to check it if it is equal or bigger than zero. --- gst/vaapi/gstvaapiencode_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 949038c15a..f963de943f 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -512,7 +512,7 @@ _h264_byte_stream_next_nal (guint8 * buffer, guint32 len, guint32 * nal_size) guint32 flag = 0xFFFFFFFF; guint32 nal_start_len = 0; - g_assert (len >= 0 && buffer && nal_size); + g_assert (buffer && nal_size); if (len < 3) { *nal_size = len; nal_start = (len ? buffer : NULL); From e42ec3ad3c5dfcc9ae6826b6b215b8d6efd856ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 8 Aug 2017 18:52:37 +0200 Subject: [PATCH 2885/3781] libs: context: use attribs index instead pointers Coverity scan bug: Out-of-bounds write. This could cause an immediate crash or incorrect computations. Coverity basically found that it is possible to assign more than 4 attribs in the array. In my opinion this was produced because code pattern used pointer arithmetic, which is not readable nor maintainable. This patch refactors config_create() to use an array index rather than pointer arithmetic. Also a run-time check for index size was added. --- gst-libs/gst/vaapi/gstvaapicontext.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 52d81e207f..2aadd736f4 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -229,9 +229,9 @@ config_create (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); - VAConfigAttrib attribs[4], *attrib = attribs; + VAConfigAttrib attribs[6], *attrib; VAStatus status; - guint value, va_chroma_format; + guint value, va_chroma_format, attrib_index; /* Reset profile and entrypoint */ if (!cip->profile || !cip->entrypoint) @@ -240,6 +240,10 @@ config_create (GstVaapiContext * context) 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) @@ -253,7 +257,8 @@ config_create (GstVaapiContext * context) goto cleanup; } attrib->value = va_chroma_format; - attrib++; + attrib = &attribs[attrib_index++]; + g_assert (attrib_index < G_N_ELEMENTS (attribs)); switch (cip->usage) { #if USE_ENCODERS @@ -275,7 +280,8 @@ config_create (GstVaapiContext * context) goto cleanup; } attrib->value = va_rate_control; - attrib++; + attrib = &attribs[attrib_index++]; + g_assert (attrib_index < G_N_ELEMENTS (attribs)); } /* Packed headers */ if (config->packed_headers) { @@ -289,7 +295,8 @@ config_create (GstVaapiContext * context) goto cleanup; } attrib->value = config->packed_headers; - attrib++; + attrib = &attribs[attrib_index++]; + g_assert (attrib_index < G_N_ELEMENTS (attribs)); } #if VA_CHECK_VERSION(0,37,0) if (cip->profile == GST_VAAPI_PROFILE_JPEG_BASELINE) { @@ -297,18 +304,18 @@ config_create (GstVaapiContext * context) if (!context_get_attribute (context, attrib->type, &value)) goto cleanup; attrib->value = value; - attrib++; + attrib = &attribs[attrib_index++]; + g_assert (attrib_index < G_N_ELEMENTS (attribs)); } #endif #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 || roi_config->bits.roi_rc_qp_delat_support == 0) { GST_ERROR ("ROI unsupported - number of regions supported: %d" @@ -317,7 +324,8 @@ config_create (GstVaapiContext * context) goto cleanup; } attrib->value = value; - attrib++; + attrib = &attribs[attrib_index++]; + g_assert (attrib_index < G_N_ELEMENTS (attribs)); } #endif break; @@ -329,7 +337,7 @@ config_create (GstVaapiContext * context) GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateConfig (GST_VAAPI_DISPLAY_VADISPLAY (display), - context->va_profile, context->va_entrypoint, attribs, attrib - attribs, + context->va_profile, context->va_entrypoint, attribs, attrib_index, &context->va_config); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateConfig()")) From 241b95dad26ff6559f8e2a8e66c20273ef68b475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 9 Aug 2017 19:06:59 +0200 Subject: [PATCH 2886/3781] libs: decoder: h265: remove spurious code Coverity scan: Logically dead code: The indicated dead code may have performed some action; that action will never occur. By using pointer arithmetic is impossible to get NULL. --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index a1c856d353..9d2fa6ee17 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2666,14 +2666,9 @@ gst_vaapi_decoder_h265_decode_codec_data (GstVaapiDecoder * num_nal_arrays = buf[22]; ofs = 23; for (i = 0; i < num_nal_arrays; i++) { - const guchar *data; - if (ofs + 1 > buf_size) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - data = buf + ofs + 1; - if (!data) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; - num_nals = GST_READ_UINT16_BE (data); + num_nals = GST_READ_UINT16_BE (buf + ofs + 1); /* the max number of nals is GST_H265_MAX_PPS_COUNT (64) */ if (num_nals > 64) return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; From 93c7c9c3f426aa1be278c5cf8e6d5dd54f12b964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 11 Aug 2017 20:22:41 +0100 Subject: [PATCH 2887/3781] meson: don't export symbols by default Only plugin entry points should be exported. --- meson.build | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 8e39584a17..ac5cf99cf7 100644 --- a/meson.build +++ b/meson.build @@ -19,9 +19,14 @@ libva_req = ['>= 0.30.4', '!= 0.99.0'] glib_req = '>= 2.40.0' gst_req = '>= @0@.@1@.0'.format(gst_version_major, gst_version_minor) -# Mandatory GST deps cc = meson.get_compiler('c') +# Symbol visibility +if cc.has_argument('-fvisibility=hidden') + add_project_arguments('-fvisibility=hidden', language: 'c') +endif + +# Mandatory GST deps libm = cc.find_library('m', required : false) gst_dep = dependency('gstreamer-1.0', version : gst_req, fallback : ['gstreamer', 'gst_dep']) From 1789c6090fa9781fd9887db18b475a32e476bf46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Aug 2017 13:09:27 +0200 Subject: [PATCH 2888/3781] build: check for va_vpp.h Thus, in config.h the macro HAVE_VA_VA_VPP_H is defined. This will allow us to handle the inclusion of the header better. https://bugzilla.gnome.org/show_bug.cgi?id=786119 --- configure.ac | 13 ++++++++++++- meson.build | 4 +++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index ce1e02348d..efa7bdc1ba 100644 --- a/configure.ac +++ b/configure.ac @@ -709,6 +709,15 @@ slice_param.slice_data_flag = 0; ]) AS_IF([test "x$ac_cv_have_h265_decoding_api" = "xyes"], [USE_H265_DECODER=1]) +dnl Check for va_vpp.h header +saved_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" +AC_CHECK_HEADERS([va/va_vpp.h], [], [], + [ +#include + ]) +CPPFLAGS="$saved_CPPFLAGS" + dnl Check for vpp (video post-processing) support USE_VA_VPP=0 AC_CACHE_CHECK([for video post-postprocessing API], @@ -723,7 +732,9 @@ AC_CACHE_CHECK([for video post-postprocessing API], AC_LANG_PROGRAM( [[ #include -#include +#ifdef HAVE_VA_VA_VPP_H +# include +#endif ]], [[ VADisplay va_dpy; diff --git a/meson.build b/meson.build index ac5cf99cf7..6f335b372c 100644 --- a/meson.build +++ b/meson.build @@ -94,6 +94,8 @@ USE_VP8_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp8.h', dependencies USE_VP9_DECODER = cc.has_header('va/va_dec_vp9.h', dependencies: libva_dep, prefix: '#include ') USE_VP9_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp9.h', dependencies: libva_dep, prefix: '#include ') +USE_VPP = cc.has_header('va/va_vpp.h', dependencies: libva_dep, prefix: '#include ') + USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() and get_option('with_drm') != 'no' USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no' USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl_dep.found() and get_option('with_glx') != 'no' @@ -125,7 +127,7 @@ cdata.set10('USE_X11', USE_X11) cdata.set10('HAVE_XKBLIB', cc.has_header('X11/XKBlib.h', dependencies: x11_dep)) cdata.set10('HAVE_XRANDR', xrandr_dep.found()) cdata.set10('HAVE_XRENDER', xrender_dep.found()) -cdata.set10('USE_VA_VPP', true) +cdata.set10('USE_VA_VPP', USE_VPP) cdata.set10('USE_GST_GL_HELPERS', gstgl_dep.found()) cdata.set('GLES_VERSION_MASK', GLES_VERSION_MASK) runcmd = run_command('pkg-config', '--variable=driverdir', 'libva') From 9891f1a9e2ed7ff6c3b0f46b64f898bd2657ab4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Aug 2017 13:11:04 +0200 Subject: [PATCH 2889/3781] build: consolidate the VA sub API includes Include all VA sub APIs headers in a single point (gstvaapicompat.h), since they are all already included in va.h after VA-API 0.38. https://bugzilla.gnome.org/show_bug.cgi?id=786119 --- gst-libs/gst/vaapi/gstvaapicodec_objects.h | 3 -- gst-libs/gst/vaapi/gstvaapicompat.h | 33 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 4 --- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 3 -- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 3 -- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 1 - gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 1 - gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 1 - gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 1 - gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 1 - gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 1 - gst-libs/gst/vaapi/gstvaapifilter.c | 5 +--- gst-libs/gst/vaapi/gstvaapiutils.c | 4 --- meson.build | 31 ++++++++++++++++++++ 14 files changed, 65 insertions(+), 27 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index 163ebf773f..2d081bde44 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -27,9 +27,6 @@ #include #include -#if USE_VP8_DECODER -#include -#endif G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 781e30d610..1e5a302503 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -46,8 +46,41 @@ #include #endif +/* VA-API < 0.37 doesn't include sub core APIs in va.h */ +#if !VA_CHECK_VERSION(0,37,0) #ifdef HAVE_VA_VA_DEC_HEVC_H # include #endif +#ifdef HAVE_VA_VA_DEC_JPEG_H +# include +#endif +#ifdef HAVE_VA_VA_DEC_VP8_H +# include +#endif +#ifdef HAVE_VA_VA_DEC_VP9_H +# include +#endif +#ifdef HAVE_VA_VA_ENC_HEVC_H +# include +#endif +#ifdef HAVE_VA_VA_ENC_H264_H +# include +#endif +#ifdef HAVE_VA_VA_ENC_JPEG_H +# include +#endif +#ifdef HAVE_VA_VA_ENC_MPEG2_H +# include +#endif +#ifdef HAVE_VA_VA_ENC_VP8_H +# include +#endif +#ifdef HAVE_VA_VA_ENC_VP9_H +# include +#endif +#ifdef HAVE_VA_VA_VPP_H +# include +#endif +#endif #endif /* GST_VAAPI_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index bef1eb71f2..51d9aeb1a9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -36,10 +36,6 @@ #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" -#ifdef HAVE_VA_VA_DEC_JPEG_H -# include -#endif - #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index cac5036a18..1503458001 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -35,9 +35,6 @@ #include "gstvaapiobject_priv.h" #include "gstvaapicompat.h" -#ifdef HAVE_VA_VA_DEC_VP8_H -#include -#endif #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 1376834810..c2cc928473 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -34,9 +34,6 @@ #include "gstvaapiobject_priv.h" #include "gstvaapicompat.h" -#ifdef HAVE_VA_VA_DEC_VP9_H -#include -#endif #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index dab3c1494a..04560aacf1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -28,7 +28,6 @@ #include "sysdeps.h" #include -#include #include #include #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 673145c728..5309c22f06 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -23,7 +23,6 @@ #include "sysdeps.h" #include #include -#include #include #include #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 73bee563ee..399696c69a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -22,7 +22,6 @@ #include "sysdeps.h" #include -#include #include #include #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 04fbd0dccb..1f8b516e81 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -24,7 +24,6 @@ #include "sysdeps.h" #include #include -#include #include #include "gstvaapicompat.h" #include "gstvaapiencoder_mpeg2.h" diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index a448df8e3f..088ca1d360 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -22,7 +22,6 @@ #include "sysdeps.h" #include -#include #include #include #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 64ef1f314c..af433cd899 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -22,7 +22,6 @@ #include "sysdeps.h" #include -#include #include #include #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index da6f733ea7..388fff3ded 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -21,6 +21,7 @@ */ #include "sysdeps.h" +#include "gstvaapicompat.h" #include "gstvaapifilter.h" #include "gstvaapiutils.h" #include "gstvaapivalue.h" @@ -29,10 +30,6 @@ #include "gstvaapisurface_priv.h" #include "gstvaapiutils_core.h" -#if USE_VA_VPP -# include -#endif - #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index c24bed7b6b..616a63839e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -31,10 +31,6 @@ #include #include -#if USE_VA_VPP -# include -#endif - #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/meson.build b/meson.build index 6f335b372c..310e61d7d3 100644 --- a/meson.build +++ b/meson.build @@ -135,6 +135,37 @@ if runcmd.returncode() == 0 cdata.set('VA_DRIVERS_PATH', '"@0@"'.format(runcmd.stdout().strip())) endif +if libva_dep.version().version_compare('< 0.38.0') + check_headers = [ + [USE_H265_DECODER, 'HAVE_VA_VA_DEC_HEVC_H'], + [USE_H265_ENCODER, 'HAVE_VA_VA_ENC_HEVC_H'], + [USE_JPEG_DECODER, 'HAVE_VA_VA_DEC_JPEG_H'], + [USE_JPEG_ENCODER, 'HAVE_VA_VA_ENC_JPEG_H'], + [USE_VP8_DECODER, 'HAVE_VA_VA_DEC_VP8_H'], + [USE_VP8_ENCODER, 'HAVE_VA_VA_ENC_VP8_H'], + [USE_VP9_DECODER, 'HAVE_VA_VA_DEC_VP9_H'], + [USE_VP9_ENCODER, 'HAVE_VA_VA_DEC_VP9_H'], + [USE_VPP, 'HAVE_VA_VA_VPP_H'], + ] + foreach h : check_headers + if h.get(0) + cdata.set(h.get(1), 1) + endif + endforeach + + if USE_ENCODERS + check_headers = [ + ['HAVE_VA_VA_ENC_MPEG2_H', 'va/va_enc_mpeg2.h'], + ['HAVE_VA_VA_ENC_H264_H', 'va/va_enc_h264.h'], + ] + foreach h : check_headers + if cc.has_header(h.get(1), dependencies: libva_dep, prefix: '#include ') + cdata.set(h.get(0), 1) + endif + endforeach + endif +endif + api_version = '1.0' soversion = 0 # maintaining compatibility with the previous libtool versioning From aaca75fefb63f45d984f95ce96c53b28063eaaf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Aug 2017 13:24:06 +0200 Subject: [PATCH 2890/3781] libs: encoder: remove va.h include Since it is already managed by gstvaapicompat.h https://bugzilla.gnome.org/show_bug.cgi?id=786119 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 1 - gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 1 - gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 1 - gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 4 +--- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 1 - gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 1 - 6 files changed, 1 insertion(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 04560aacf1..88ee3674b1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -27,7 +27,6 @@ #define GLIB_DISABLE_DEPRECATION_WARNINGS #include "sysdeps.h" -#include #include #include #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 5309c22f06..d2567d7f21 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -22,7 +22,6 @@ #include "sysdeps.h" #include -#include #include #include #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 399696c69a..e02c40d1a3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -21,7 +21,6 @@ */ #include "sysdeps.h" -#include #include #include #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 1f8b516e81..db4751bf12 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -21,16 +21,14 @@ * Boston, MA 02110-1301 USA */ -#include "sysdeps.h" #include -#include +#include "sysdeps.h" #include #include "gstvaapicompat.h" #include "gstvaapiencoder_mpeg2.h" #include "gstvaapiencoder_mpeg2_priv.h" #include "gstvaapiutils_mpeg2_priv.h" #include "gstvaapicodedbufferproxy_priv.h" - #include "gstvaapicontext.h" #include "gstvaapisurface.h" #include "gstvaapidisplay_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 088ca1d360..02021475cc 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -21,7 +21,6 @@ */ #include "sysdeps.h" -#include #include #include #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index af433cd899..bafb3cc7b5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -21,7 +21,6 @@ */ #include "sysdeps.h" -#include #include #include #include "gstvaapicompat.h" From 3f9ad1ffd8de671f4a6ed1c4358b5ee0e43f6a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Aug 2017 13:26:12 +0200 Subject: [PATCH 2891/3781] libs: utils: remove va.h include in header And include gstvaapicompat.h in the C files, since the VA-API is not exposed in the headers. https://bugzilla.gnome.org/show_bug.cgi?id=786119 --- gst-libs/gst/vaapi/gstvaapiutils_h264.c | 1 + gst-libs/gst/vaapi/gstvaapiutils_h264.h | 1 - gst-libs/gst/vaapi/gstvaapiutils_h265.c | 1 + gst-libs/gst/vaapi/gstvaapiutils_h265.h | 1 - gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c | 1 + gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h | 1 - 6 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index 180e22fad5..19bfae95be 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -22,6 +22,7 @@ #include "sysdeps.h" #include +#include "gstvaapicompat.h" #include "gstvaapiutils_h264_priv.h" struct map diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.h b/gst-libs/gst/vaapi/gstvaapiutils_h264.h index 16db4ea7fe..8dea3efffb 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.h @@ -23,7 +23,6 @@ #ifndef GST_VAAPI_UTILS_H264_H #define GST_VAAPI_UTILS_H264_H -#include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index aa1515ceee..24199b9102 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -22,6 +22,7 @@ #include "sysdeps.h" #include +#include "gstvaapicompat.h" #include "gstvaapiutils_h265_priv.h" struct map diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.h b/gst-libs/gst/vaapi/gstvaapiutils_h265.h index 71011b99cd..373764e990 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.h @@ -23,7 +23,6 @@ #ifndef GST_VAAPI_UTILS_H265_H #define GST_VAAPI_UTILS_H265_H -#include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c index de170e8e41..20f7e1292f 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c @@ -22,6 +22,7 @@ #include "sysdeps.h" #include +#include "gstvaapicompat.h" #include "gstvaapiutils_mpeg2_priv.h" struct map diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h index 4820a4703e..d846f86a1f 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h @@ -23,7 +23,6 @@ #ifndef GST_VAAPI_UTILS_MPEG2_H #define GST_VAAPI_UTILS_MPEG2_H -#include #include #include From 3b8b2ff36c9f081a993f7906eae1d8408d881ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Aug 2017 13:27:11 +0200 Subject: [PATCH 2892/3781] libs: utils: move gstvaapisurface.h to private headers Since the utils don't expose API defined in gstvaapisource.h, it is moved to their private headers where they are used. https://bugzilla.gnome.org/show_bug.cgi?id=786119 --- gst-libs/gst/vaapi/gstvaapiutils_h264.h | 1 - gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_h265.h | 1 - gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h | 1 - gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h | 1 + 6 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.h b/gst-libs/gst/vaapi/gstvaapiutils_h264.h index 8dea3efffb..057705033d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.h @@ -24,7 +24,6 @@ #define GST_VAAPI_UTILS_H264_H #include -#include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h index 8fe0d41c44..6a0c61d03c 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h @@ -25,6 +25,7 @@ #include "gstvaapiutils_h264.h" #include "libgstvaapi_priv_check.h" +#include "gstvaapisurface.h" G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.h b/gst-libs/gst/vaapi/gstvaapiutils_h265.h index 373764e990..930da0b61b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.h @@ -24,7 +24,6 @@ #define GST_VAAPI_UTILS_H265_H #include -#include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h index 5e9f53211d..7b5173ed4d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h @@ -25,6 +25,7 @@ #include "gstvaapiutils_h265.h" #include "libgstvaapi_priv_check.h" +#include "gstvaapisurface.h" G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h index d846f86a1f..64e38d1cb2 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h @@ -24,7 +24,6 @@ #define GST_VAAPI_UTILS_MPEG2_H #include -#include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h index e6507faa4b..231a6b4fcd 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h @@ -25,6 +25,7 @@ #include "gstvaapiutils_mpeg2.h" #include "libgstvaapi_priv_check.h" +#include "gstvaapisurface.h" G_BEGIN_DECLS From a07ff9641cf86b7ae6b80d1b26089d1612bc6a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 10 Aug 2017 13:34:21 +0200 Subject: [PATCH 2893/3781] libs: remove unused header Since libgstvaapi is not distributed, there is no need to check for private header inclusion. Thus removing it. https://bugzilla.gnome.org/show_bug.cgi?id=786119 --- gst-libs/gst/vaapi/Makefile.am | 7 ------ gst-libs/gst/vaapi/gstvaapidecoder_unit.h | 2 -- gst-libs/gst/vaapi/gstvaapiminiobject.h | 1 - gst-libs/gst/vaapi/gstvaapiutils.h | 1 - gst-libs/gst/vaapi/gstvaapiutils_glx.h | 1 - gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h | 1 - gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h | 1 - gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h | 1 - gst-libs/gst/vaapi/gstvaapiutils_x11.h | 1 - gst-libs/gst/vaapi/libgstvaapi_priv_check.h | 25 ------------------- gst-libs/gst/vaapi/meson.build | 2 +- 11 files changed, 1 insertion(+), 42 deletions(-) delete mode 100644 gst-libs/gst/vaapi/libgstvaapi_priv_check.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 5bf3c105b3..f7da153ce3 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -21,7 +21,6 @@ noinst_LTLIBRARIES += libgstvaapi-wayland.la endif libgstvaapi_cflags = \ - -DIN_LIBGSTVAAPI \ -DIN_LIBGSTVAAPI_CORE \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ @@ -146,7 +145,6 @@ libgstvaapi_source_priv_h = \ gstvaapivideopool_priv.h \ gstvaapiwindow_priv.h \ gstvaapiworkarounds.h \ - libgstvaapi_priv_check.h \ sysdeps.h \ $(NULL) @@ -358,7 +356,6 @@ libgstvaapi_drm_la_SOURCES = \ $(NULL) libgstvaapi_drm_la_CFLAGS = \ - -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ @@ -388,7 +385,6 @@ libgstvaapi_x11_la_SOURCES = \ $(NULL) libgstvaapi_x11_la_CFLAGS = \ - -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ @@ -420,7 +416,6 @@ libgstvaapi_glx_la_SOURCES = \ $(NULL) libgstvaapi_glx_la_CFLAGS = \ - -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ @@ -452,7 +447,6 @@ libgstvaapi_egl_la_SOURCES = \ $(NULL) libgstvaapi_egl_la_CFLAGS = \ - -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ @@ -484,7 +478,6 @@ libgstvaapi_wayland_la_SOURCES = \ $(NULL) libgstvaapi_wayland_la_CFLAGS = \ - -DIN_LIBGSTVAAPI \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ $(GLIB_CFLAGS) \ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h index 32fa9bb458..7ee77a05cf 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_unit.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_unit.h @@ -23,8 +23,6 @@ #ifndef GST_VAAPI_DECODER_UNIT_H #define GST_VAAPI_DECODER_UNIT_H -#include "libgstvaapi_priv_check.h" - G_BEGIN_DECLS typedef struct _GstVaapiDecoderUnit GstVaapiDecoderUnit; diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.h b/gst-libs/gst/vaapi/gstvaapiminiobject.h index 562c5fc472..3f30189121 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.h @@ -24,7 +24,6 @@ #define GST_VAAPI_MINI_OBJECT_H #include -#include "libgstvaapi_priv_check.h" G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 41b5762b82..82efc31550 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -26,7 +26,6 @@ #define GST_VAAPI_UTILS_H #include "config.h" -#include "libgstvaapi_priv_check.h" #include #include diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 3fafe5ec99..f5c632cc4c 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -26,7 +26,6 @@ #define GST_VAAPI_UTILS_GLX_H #include "config.h" -#include "libgstvaapi_priv_check.h" #include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h index 6a0c61d03c..eb582f5ee7 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h @@ -24,7 +24,6 @@ #define GST_VAAPI_UTILS_H264_PRIV_H #include "gstvaapiutils_h264.h" -#include "libgstvaapi_priv_check.h" #include "gstvaapisurface.h" G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h index 7b5173ed4d..9e1b83c9d6 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h @@ -24,7 +24,6 @@ #define GST_VAAPI_UTILS_H265_PRIV_H #include "gstvaapiutils_h265.h" -#include "libgstvaapi_priv_check.h" #include "gstvaapisurface.h" G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h index 231a6b4fcd..3ac65c5d3b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h @@ -24,7 +24,6 @@ #define GST_VAAPI_UTILS_MPEG2_PRIV_H #include "gstvaapiutils_mpeg2.h" -#include "libgstvaapi_priv_check.h" #include "gstvaapisurface.h" G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index 500a47fc39..b205585b29 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -26,7 +26,6 @@ #define GST_VAAPI_UTILS_X11_H #include "config.h" -#include "libgstvaapi_priv_check.h" #include #include diff --git a/gst-libs/gst/vaapi/libgstvaapi_priv_check.h b/gst-libs/gst/vaapi/libgstvaapi_priv_check.h deleted file mode 100644 index e7cf0e1f08..0000000000 --- a/gst-libs/gst/vaapi/libgstvaapi_priv_check.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * libgstvaapi_priv_check.h - Check file is included from within libgstvaapi - * - * Copyright (C) 2014 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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 IN_LIBGSTVAAPI -# error "This file is only meant to be included from within libgstvaapi" -#endif diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 3519f0060f..debdfe9743 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -217,7 +217,7 @@ endif gstlibvaapi = static_library('gstlibvaapi-@0@'.format(api_version), gstlibvaapi_sources, - c_args : gstreamer_vaapi_args + ['-DIN_LIBGSTVAAPI', '-DIN_LIBGSTVAAPI_CORE', '-DGST_USE_UNSTABLE_API', '-DGST_VAAPI_VERSION_ID="@0@"'.format(gst_version)], + c_args : gstreamer_vaapi_args + ['-DIN_LIBGSTVAAPI_CORE', '-DGST_USE_UNSTABLE_API', '-DGST_VAAPI_VERSION_ID="@0@"'.format(gst_version)], include_directories: [configinc, libsinc], version : libversion, soversion : soversion, From ee159b58eeb004765b7476cb5ccbb07c09842394 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 15 Aug 2017 17:36:51 +0900 Subject: [PATCH 2894/3781] vaapidecode: fix mismatch of the return type https://bugzilla.gnome.org/show_bug.cgi?id=786307 --- gst/vaapi/gstvaapidecode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d5747d327c..71c026ae90 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -984,7 +984,8 @@ gst_vaapidecode_reset (GstVaapiDecode * decode, GstCaps * caps, return TRUE; } } - return gst_vaapi_decoder_reset (decode->decoder); + return (gst_vaapi_decoder_reset (decode->decoder) == + GST_VAAPI_DECODER_STATUS_SUCCESS); } return gst_vaapidecode_create (decode, caps); From 75fd0d4ff0658b9a590c5c13db8dbbe5d82de3ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 17 Aug 2017 11:03:35 +0200 Subject: [PATCH 2895/3781] libs: encoder: h264: remove spurious assignation Coverity scan bug: An assigned value that is never used may represent unnecessary computation, an incorrect algorithm, or possibly the need for cleanup or refactoring. ip_period is assigned first to be rewritter inmediatly after. The first assignation is spurious. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 88ee3674b1..178e68fbeb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1877,7 +1877,6 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) seq_param->level_idc = encoder->level_idc; seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); - seq_param->ip_period = 1 + encoder->num_bframes; seq_param->ip_period = seq_param->intra_period > 1 ? (1 + encoder->num_bframes) : 0; seq_param->bits_per_second = encoder->bitrate_bits; From c86e61e6a63dc272ccd39dfb74a158ba52486956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 17 Aug 2017 12:26:12 +0100 Subject: [PATCH 2896/3781] Automatic update of common submodule From 48a5d85 to 3f4aa96 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 48a5d85ebf..3f4aa969cb 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 48a5d85ebf4a0bad1c997c83100f710fe2154fbf +Subproject commit 3f4aa969cbe39584a649d98d4cf321d78bd73092 From ffffb99473331b9e5d87e880e6f60b2aa6d0894e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 18 Aug 2017 18:00:24 +0200 Subject: [PATCH 2897/3781] libs: encoder: h264: fix enum namespace --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 178e68fbeb..ab8985297f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -78,7 +78,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT = 0, GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_RESTRICT_CODED_BUFFER_ALLOC = 1, -} GstVaapiEnoderH264ComplianceMode; +} GstVaapiEncoderH264ComplianceMode; static GType gst_vaapi_encoder_h264_compliance_mode_type (void) @@ -749,7 +749,7 @@ struct _GstVaapiEncoderH264 gboolean use_aud; /* Complance mode */ - GstVaapiEnoderH264ComplianceMode compliance_mode; + GstVaapiEncoderH264ComplianceMode compliance_mode; guint min_cr; // Minimum Compression Ratio (A.3.1) }; From 466c0548dc7de371935ad358cfc5bb0d25d78c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 22 Aug 2017 11:37:28 +0200 Subject: [PATCH 2898/3781] plugins: include main gstgl header Instead including particular gstgl header files in a header file that doesn't export a gstgl symbol, the main gstgl header file is included in gstvaapipluginutil.c where the symbols are used. https://bugzilla.gnome.org/show_bug.cgi?id=786597 --- gst/vaapi/gstvaapipluginbase.h | 4 ---- gst/vaapi/gstvaapipluginutil.c | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 3346ed40ae..276e130ae3 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -31,10 +31,6 @@ #include #include -#if USE_GST_GL_HELPERS -# include -#endif - G_BEGIN_DECLS typedef struct _GstVaapiPluginBase GstVaapiPluginBase; diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index c38334fc25..d5114b5d99 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -39,6 +39,9 @@ #if USE_WAYLAND # include #endif +#if USE_GST_GL_HELPERS +# include +#endif #include "gstvaapipluginutil.h" #include "gstvaapipluginbase.h" From e8148cea0de71d19e4a9e62bc84ec5ab6cb8bc6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 17 Aug 2017 12:44:40 +0200 Subject: [PATCH 2899/3781] libs: macro to get a renamed value in VA-API 1.0 In VA-API 1.0 the union bits in VAEncMiscParameterBufferROI has renamed one member from roi_value_is_qp_delat to roi_value_is_qp_delta, which is the correct name. In order to keep back compatibility a macro has added to access this union member. https://bugzilla.gnome.org/show_bug.cgi?id=784398 --- gst-libs/gst/vaapi/gstvaapicompat.h | 6 ++++++ gst-libs/gst/vaapi/gstvaapicontext.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 1e5a302503..493cadc36d 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -37,6 +37,12 @@ #define vaAssociateSubpicture vaAssociateSubpicture2 #endif +#if VA_CHECK_VERSION(1,0,0) +#define VA_ROI_RC_QP_DELTA_SUPPORT(x) x->bits.roi_rc_qp_delta_support +#else +#define VA_ROI_RC_QP_DELTA_SUPPORT(x) x->bits.roi_rc_qp_delat_support +#endif + /* Compatibility glue with VA-API 0.34 */ #if VA_CHECK_VERSION(0,34,0) # include diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 2aadd736f4..2312878167 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -317,10 +317,10 @@ config_create (GstVaapiContext * context) goto cleanup; roi_config = (VAConfigAttribValEncROI *) & value; if (roi_config->bits.num_roi_regions != config->roi_num_supported || - roi_config->bits.roi_rc_qp_delat_support == 0) { + VA_ROI_RC_QP_DELTA_SUPPORT (roi_config) == 0) { GST_ERROR ("ROI unsupported - number of regions supported: %d" " ROI delta QP: %d", roi_config->bits.num_roi_regions, - roi_config->bits.roi_rc_qp_delat_support); + VA_ROI_RC_QP_DELTA_SUPPORT (roi_config)); goto cleanup; } attrib->value = value; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index d761bfa242..0a91b2e5c2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -657,7 +657,7 @@ get_roi_capability (GstVaapiEncoder * encoder, guint * num_roi_supported) roi_config = (VAConfigAttribValEncROI *) & value; if (roi_config->bits.num_roi_regions == 0 || - roi_config->bits.roi_rc_qp_delat_support == 0) + VA_ROI_RC_QP_DELTA_SUPPORT (roi_config) == 0) return FALSE; GST_INFO ("Support for ROI - number of regions supported: %d", From 3c345e3a43bbf7a5000d7d29dcfa7fa8601361f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 17 Aug 2017 12:54:47 +0200 Subject: [PATCH 2900/3781] Revert "build: check for libva-2.0" This reverts commit 8f2eb70803099d4b533ecc10fc259041d8714210. https://bugzilla.gnome.org/show_bug.cgi?id=784398 --- configure.ac | 25 ++++++------------------- meson.build | 27 ++++----------------------- meson_options.txt | 1 - 3 files changed, 10 insertions(+), 43 deletions(-) diff --git a/configure.ac b/configure.ac index efa7bdc1ba..145e3b83b8 100644 --- a/configure.ac +++ b/configure.ac @@ -120,11 +120,6 @@ AG_GST_SET_PACKAGE_RELEASE_DATETIME_WITH_NANO([$PACKAGE_VERSION_NANO], ["${srcdir}/gstreamer-vaapi.doap"], [$PACKAGE_VERSION_MAJOR.$PACKAGE_VERSION_MINOR.$PACKAGE_VERSION_MICRO]) -AC_ARG_WITH([libva], - [AS_HELP_STRING([--with-libva[[=VERSION]]], - [which version of libva use (1 or 2) @<:@default=check@:>@])], - [], [with_libva="check"]) - AC_ARG_ENABLE([encoders], AS_HELP_STRING([--enable-encoders], [enable video encoders @<:@default=yes@:>@]), @@ -510,23 +505,15 @@ dnl -- VA-API -- dnl --------------------------------------------------------------------------- dnl Core API -LIBVA_VERSION= -AS_CASE([$with_libva], - [2], [PKG_CHECK_MODULES([LIBVA], [libva-2.0 >= 1.0.0], - [LIBVA_VERSION="-2.0"])], - [1], [PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ libva != 0.99.0])], - [PKG_CHECK_MODULES([LIBVA], [libva-2.0 >= 1.0.0], - [LIBVA_VERSION="-2.0"], - [PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ libva != 0.99.0])])]) - -VA_VERSION_STR=`$PKG_CONFIG --modversion libva$LIBVA_VERSION` -VA_DRIVERS_PATH=`$PKG_CONFIG --variable=driverdir libva$LIBVA_VERSION` +PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ libva != 0.99.0]) +VA_VERSION_STR=`$PKG_CONFIG --modversion libva` +VA_DRIVERS_PATH=`$PKG_CONFIG --variable=driverdir libva` AC_DEFINE_UNQUOTED([VA_DRIVERS_PATH], ["$VA_DRIVERS_PATH"], [VA drivers path]) dnl VA/DRM API if test $USE_DRM -eq 1; then - PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm$LIBVA_VERSION >= $VAAPI_DRM_REQ], + PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= $VAAPI_DRM_REQ], [ saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_DRM_CFLAGS" @@ -537,7 +524,7 @@ fi dnl VA/X11 API if test $USE_X11 -eq 1; then - PKG_CHECK_MODULES(LIBVA_X11, [libva-x11$LIBVA_VERSION >= $VAAPI_X11_REQ], + PKG_CHECK_MODULES(LIBVA_X11, [libva-x11 >= $VAAPI_X11_REQ], [], [USE_X11=0]) fi @@ -908,7 +895,7 @@ fi dnl VA/Wayland API if test $USE_WAYLAND -eq 1; then - PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland$LIBVA_VERSION >= $VAAPI_WLD_REQ], + PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= $VAAPI_WLD_REQ], [], [USE_WAYLAND=0]) fi diff --git a/meson.build b/meson.build index 310e61d7d3..a6acda2c88 100644 --- a/meson.build +++ b/meson.build @@ -43,30 +43,11 @@ gstcodecparsers_dep = dependency('gstreamer-codecparsers-1.0', version : gst_req gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, fallback : ['gst-plugins-bad', 'gstgl_dep'], required: false) gmodule_dep = dependency('gmodule-2.0', required: false) +libva_dep = dependency('libva', version: libva_req) -libva_version = '' -if get_option('with_libva') == 'auto' - libva_dep = dependency('libva-2.0', required : false) - if not libva_dep.found() - libva_dep = dependency('libva', version: libva_req) - else - libva_version = '-2.0' - endif -else - if get_option('with_libva') == '2' - libva_dep = dependency('libva-2.0') - libva_version = '-2.0' - else - libva_dep = dependency('libva', version: libva_req) - endif -endif - -libva_drm_dep = dependency('libva-drm' + libva_version, version: '>= 0.33.0', - required: false) -libva_wayland_dep = dependency('libva-wayland' + libva_version, - version: '>= 0.33.0', required: false) -libva_x11_dep = dependency('libva-x11' + libva_version, version: '>= 0.31.0', - required: false) +libva_drm_dep = dependency('libva-drm', version: '>= 0.33.0', required: false) +libva_wayland_dep = dependency('libva-wayland', version: '>= 0.33.0', required: false) +libva_x11_dep = dependency('libva-x11', version: '>= 0.31.0', required: false) libdrm_dep = dependency('libdrm', required: false) libudev_dep = dependency('libudev', required: false) egl_dep = dependency('egl', required: false) diff --git a/meson_options.txt b/meson_options.txt index b411067cbe..018f8bc33d 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,4 +1,3 @@ -option('with_libva', type : 'combo', choices : ['1', '2', 'auto'], value : 'auto') option('with_encoders', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') option('with_drm', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') option('with_x11', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') From 585628d2a218263613418c55ba51dab2d3c4d9f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 25 Aug 2017 16:07:34 +0200 Subject: [PATCH 2901/3781] libs: guard deprecated symbols In VA-API 1.0 the H.264 baseline profile is deprecated. This patch guards the H.264 baseline usage. Consider this commit as a continuation of commit e0e0a474 https://bugzilla.gnome.org/show_bug.cgi?id=784398 --- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 ++ gst-libs/gst/vaapi/gstvaapiutils.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 9c353c56af..6e8fd0a6a4 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -94,8 +94,10 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { {GST_VAAPI_PROFILE_H263_BASELINE, VAProfileH263Baseline, "video/x-h263, variant=itu, h263version=h263", "baseline"}, #endif +#if !VA_CHECK_VERSION(1,0,0) {GST_VAAPI_PROFILE_H264_BASELINE, VAProfileH264Baseline, "video/x-h264", "baseline"}, +#endif #if VA_CHECK_VERSION(0,31,1) {GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE, VAProfileH264ConstrainedBaseline, diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 616a63839e..5d7ae62e61 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -202,7 +202,9 @@ string_of_VAProfile (VAProfile profile) MAP (H263Baseline); MAP (H264ConstrainedBaseline); #endif +#if !VA_CHECK_VERSION(1,0,0) MAP (H264Baseline); +#endif MAP (H264Main); MAP (H264High); #if VA_CHECK_VERSION(0,35,2) From b942f9e17f8c9aa82d817749970544dd6d303d74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 25 Aug 2017 16:22:59 +0200 Subject: [PATCH 2902/3781] libs: encoder: h264: handle deprecated enum In VA-API 1.0 the enum VAEncPackedHeaderH264_SEI is deprecated, and instead VAEncPackedHeaderRawData should be used. This patch creates a compatibility symbol, VA_ENC_PACKED_HEADER_H264_SEI, to expose the used enum according the VA-API version. https://bugzilla.gnome.org/show_bug.cgi?id=784398 --- gst-libs/gst/vaapi/gstvaapicompat.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index 493cadc36d..b87df0ebb8 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -39,8 +39,10 @@ #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 /* Compatibility glue with VA-API 0.34 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index ab8985297f..ddf5ded862 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1601,7 +1601,7 @@ add_packed_sei_header (GstVaapiEncoderH264 * encoder, data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); data = GST_BIT_WRITER_DATA (&bs); - packed_sei_param.type = VAEncPackedHeaderH264_SEI; + packed_sei_param.type = VA_ENC_PACKED_HEADER_H264_SEI; packed_sei_param.bit_length = data_bit_size; packed_sei_param.has_emulation_bytes = 0; From d9c88f478571523909c712cbc9cebea671f53b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 24 Aug 2017 20:26:11 +0200 Subject: [PATCH 2903/3781] libs: decoder: h264: improve code-style https://bugzilla.gnome.org/show_bug.cgi?id=786173 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 5f982a0c4d..d236065772 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1581,8 +1581,8 @@ ensure_context (GstVaapiDecoderH264 * decoder, GstH264SPS * sps) } mb_width = sps->pic_width_in_mbs_minus1 + 1; - mb_height = (sps->pic_height_in_map_units_minus1 + 1) << - !sps->frame_mbs_only_flag; + mb_height = + (sps->pic_height_in_map_units_minus1 + 1) << !sps->frame_mbs_only_flag; if (priv->mb_width != mb_width || priv->mb_height != mb_height) { GST_DEBUG ("size changed"); reset_context = TRUE; From fd7d38f7d26b11e592638092b4073b5c1764f255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 28 Aug 2017 18:32:32 +0200 Subject: [PATCH 2904/3781] libs: encoders: remove unused cast macros They are only used inside the code, where another macro is defined. Thus these exported macros have no use. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 3 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 3 --- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h | 3 --- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 3 --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.h | 3 --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 3 --- 6 files changed, 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 89eab76c33..0ba54ed429 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -29,9 +29,6 @@ G_BEGIN_DECLS -#define GST_VAAPI_ENCODER_H264(encoder) \ - ((GstVaapiEncoderH264 *) (encoder)) - typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index ec8483e5b7..3554ef15c3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -28,9 +28,6 @@ G_BEGIN_DECLS -#define GST_VAAPI_ENCODER_H265(encoder) \ - ((GstVaapiEncoderH265 *) (encoder)) - typedef struct _GstVaapiEncoderH265 GstVaapiEncoderH265; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h index a18c7e2796..108d03036e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h @@ -27,9 +27,6 @@ G_BEGIN_DECLS -#define GST_VAAPI_ENCODER_JPEG(encoder) \ - ((GstVaapiEncoderJpeg *) (encoder)) - typedef struct _GstVaapiEncoderJpeg GstVaapiEncoderJpeg; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h index 923ad1d85a..c81cc6c75f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -28,9 +28,6 @@ G_BEGIN_DECLS -#define GST_VAAPI_ENCODER_MPEG2(encoder) \ - ((GstVaapiEncoderMpeg2 *) (encoder)) - typedef struct _GstVaapiEncoderMpeg2 GstVaapiEncoderMpeg2; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h index a48bf460c4..c362ebaab1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h @@ -27,9 +27,6 @@ G_BEGIN_DECLS -#define GST_VAAPI_ENCODER_VP8(encoder) \ - ((GstVaapiEncoderVP8 *) (encoder)) - typedef struct _GstVaapiEncoderVP8 GstVaapiEncoderVP8; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h index 7967a98002..3723ddb4b0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -27,9 +27,6 @@ G_BEGIN_DECLS -#define GST_VAAPI_ENCODER_VP9(encoder) \ - ((GstVaapiEncoderVP9 *) (encoder)) - typedef struct _GstVaapiEncoderVP9 GstVaapiEncoderVP9; /** From 9c2246740b033d760daeeb75b3a459184c89058f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 28 Aug 2017 19:09:07 +0200 Subject: [PATCH 2905/3781] Revert "libs: encoders: remove unused cast macros" This reverts commit fd7d38f7d26b11e592638092b4073b5c1764f255. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_vp8.h | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 3 +++ 6 files changed, 18 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 0ba54ed429..89eab76c33 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -29,6 +29,9 @@ G_BEGIN_DECLS +#define GST_VAAPI_ENCODER_H264(encoder) \ + ((GstVaapiEncoderH264 *) (encoder)) + typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index 3554ef15c3..ec8483e5b7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -28,6 +28,9 @@ G_BEGIN_DECLS +#define GST_VAAPI_ENCODER_H265(encoder) \ + ((GstVaapiEncoderH265 *) (encoder)) + typedef struct _GstVaapiEncoderH265 GstVaapiEncoderH265; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h index 108d03036e..a18c7e2796 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h @@ -27,6 +27,9 @@ G_BEGIN_DECLS +#define GST_VAAPI_ENCODER_JPEG(encoder) \ + ((GstVaapiEncoderJpeg *) (encoder)) + typedef struct _GstVaapiEncoderJpeg GstVaapiEncoderJpeg; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h index c81cc6c75f..923ad1d85a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -28,6 +28,9 @@ G_BEGIN_DECLS +#define GST_VAAPI_ENCODER_MPEG2(encoder) \ + ((GstVaapiEncoderMpeg2 *) (encoder)) + typedef struct _GstVaapiEncoderMpeg2 GstVaapiEncoderMpeg2; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h index c362ebaab1..a48bf460c4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h @@ -27,6 +27,9 @@ G_BEGIN_DECLS +#define GST_VAAPI_ENCODER_VP8(encoder) \ + ((GstVaapiEncoderVP8 *) (encoder)) + typedef struct _GstVaapiEncoderVP8 GstVaapiEncoderVP8; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h index 3723ddb4b0..7967a98002 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -27,6 +27,9 @@ G_BEGIN_DECLS +#define GST_VAAPI_ENCODER_VP9(encoder) \ + ((GstVaapiEncoderVP9 *) (encoder)) + typedef struct _GstVaapiEncoderVP9 GstVaapiEncoderVP9; /** From 3bfb29e4c2eeda7010d72cf2bba7fcffc5c86957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 28 Aug 2017 19:20:42 +0200 Subject: [PATCH 2906/3781] libs: encoder: remove unused cast macro Remove internal macro to cast structure that are already declared in the header. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 30 +++++++---------------- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 30 +++++++---------------- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 20 +++++---------- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 17 ++++++------- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 15 +++++------- 5 files changed, 37 insertions(+), 75 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index ddf5ded862..396eb41f57 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -694,9 +694,6 @@ bs_error: /* --- H.264 Encoder --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_ENCODER_H264_CAST(encoder) \ - ((GstVaapiEncoderH264 *)(encoder)) - struct _GstVaapiEncoderH264 { GstVaapiEncoder parent_instance; @@ -2593,8 +2590,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base_encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) { - GstVaapiEncoderH264 *const encoder = - GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; @@ -2631,8 +2627,7 @@ error: static GstVaapiEncoderStatus gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH264 *const encoder = - GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); GstVaapiH264ViewReorderPool *reorder_pool; GstVaapiEncPicture *pic; guint i; @@ -2659,8 +2654,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder, GstBuffer ** out_buffer_ptr) { - GstVaapiEncoderH264 *const encoder = - GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); const guint32 configuration_version = 0x01; const guint32 nal_length_size = 4; guint8 profile_idc, profile_comp, level_idc; @@ -2759,8 +2753,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) { - GstVaapiEncoderH264 *const encoder = - GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); GstVaapiH264ViewReorderPool *reorder_pool = NULL; GstVaapiEncPicture *picture; gboolean is_idr = FALSE; @@ -2872,8 +2865,7 @@ end: static GstVaapiEncoderStatus set_context_info (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH264 *const encoder = - GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); const guint DEFAULT_SURFACES_COUNT = 3; @@ -2932,8 +2924,7 @@ set_context_info (GstVaapiEncoder * base_encoder) static GstVaapiEncoderStatus gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH264 *const encoder = - GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); GstVaapiEncoderStatus status; guint mb_width, mb_height; @@ -2969,8 +2960,7 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) static gboolean gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH264 *const encoder = - GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); guint32 i; /* Default encoding entrypoint */ @@ -3012,8 +3002,7 @@ static void gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder) { /*free private buffers */ - GstVaapiEncoderH264 *const encoder = - GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); GstVaapiEncPicture *pic; GstVaapiEncoderH264Ref *ref; guint32 i; @@ -3049,8 +3038,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { - GstVaapiEncoderH264 *const encoder = - GST_VAAPI_ENCODER_H264_CAST (base_encoder); + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); switch (prop_id) { case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index d2567d7f21..d5123ec8b3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -85,9 +85,6 @@ typedef struct _GstVaapiH265ReorderPool /* --- H.265 Encoder --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_ENCODER_H265_CAST(encoder) \ - ((GstVaapiEncoderH265 *)(encoder)) - struct _GstVaapiEncoderH265 { GstVaapiEncoder parent_instance; @@ -2021,8 +2018,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_h265_encode (GstVaapiEncoder * base_encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) { - GstVaapiEncoderH265 *const encoder = - GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; @@ -2059,8 +2055,7 @@ error: static GstVaapiEncoderStatus gst_vaapi_encoder_h265_flush (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH265 *const encoder = - GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); GstVaapiH265ReorderPool *reorder_pool; GstVaapiEncPicture *pic; @@ -2083,8 +2078,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_h265_get_codec_data (GstVaapiEncoder * base_encoder, GstBuffer ** out_buffer_ptr) { - GstVaapiEncoderH265 *const encoder = - GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); const guint32 configuration_version = 0x01; const guint32 nal_length_size = 4; GstMapInfo vps_info, sps_info, pps_info; @@ -2230,8 +2224,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_h265_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) { - GstVaapiEncoderH265 *const encoder = - GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); GstVaapiH265ReorderPool *reorder_pool = NULL; GstVaapiEncPicture *picture; gboolean is_idr = FALSE; @@ -2330,8 +2323,7 @@ end: static GstVaapiEncoderStatus set_context_info (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH265 *const encoder = - GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); const guint DEFAULT_SURFACES_COUNT = 3; @@ -2383,8 +2375,7 @@ set_context_info (GstVaapiEncoder * base_encoder) static GstVaapiEncoderStatus gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH265 *const encoder = - GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); GstVaapiEncoderStatus status; guint luma_width, luma_height; @@ -2429,8 +2420,7 @@ gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) static gboolean gst_vaapi_encoder_h265_init (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderH265 *const encoder = - GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); GstVaapiH265ReorderPool *reorder_pool; GstVaapiH265RefPool *ref_pool; @@ -2458,8 +2448,7 @@ static void gst_vaapi_encoder_h265_finalize (GstVaapiEncoder * base_encoder) { /*free private buffers */ - GstVaapiEncoderH265 *const encoder = - GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); GstVaapiEncPicture *pic; GstVaapiEncoderH265Ref *ref; GstVaapiH265RefPool *ref_pool; @@ -2491,8 +2480,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { - GstVaapiEncoderH265 *const encoder = - GST_VAAPI_ENCODER_H265_CAST (base_encoder); + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); switch (prop_id) { case GST_VAAPI_ENCODER_H265_PROP_MAX_BFRAMES: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index e02c40d1a3..5153ad9554 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -56,9 +56,6 @@ /* --- JPEG Encoder --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_ENCODER_JPEG_CAST(encoder) \ - ((GstVaapiEncoderJpeg *)(encoder)) - struct _GstVaapiEncoderJpeg { GstVaapiEncoder parent_instance; @@ -175,7 +172,7 @@ error_unsupported_profile: static GstVaapiEncoderStatus set_context_info (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderJpeg *encoder = GST_VAAPI_ENCODER_JPEG_CAST (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) */ @@ -662,8 +659,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_jpeg_encode (GstVaapiEncoder * base_encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) { - GstVaapiEncoderJpeg *const encoder = - GST_VAAPI_ENCODER_JPEG_CAST (base_encoder); + GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (base_encoder); GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; @@ -709,8 +705,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_jpeg_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) { - GstVaapiEncoderJpeg *const encoder = - GST_VAAPI_ENCODER_JPEG_CAST (base_encoder); + GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (base_encoder); GstVaapiEncPicture *picture = NULL; GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS; @@ -731,8 +726,7 @@ gst_vaapi_encoder_jpeg_reordering (GstVaapiEncoder * base_encoder, static GstVaapiEncoderStatus gst_vaapi_encoder_jpeg_reconfigure (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderJpeg *const encoder = - GST_VAAPI_ENCODER_JPEG_CAST (base_encoder); + GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (base_encoder); GstVaapiEncoderStatus status; status = ensure_profile (encoder); @@ -748,8 +742,7 @@ gst_vaapi_encoder_jpeg_reconfigure (GstVaapiEncoder * base_encoder) static gboolean gst_vaapi_encoder_jpeg_init (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderJpeg *const encoder = - GST_VAAPI_ENCODER_JPEG_CAST (base_encoder); + GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (base_encoder); encoder->has_quant_tables = FALSE; memset (&encoder->quant_tables, 0, sizeof (encoder->quant_tables)); @@ -770,8 +763,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_jpeg_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { - GstVaapiEncoderJpeg *const encoder = - GST_VAAPI_ENCODER_JPEG_CAST (base_encoder); + GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (base_encoder); switch (prop_id) { case GST_VAAPI_ENCODER_JPEG_PROP_QUALITY: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 02021475cc..7ee0a2ef4d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -57,9 +57,6 @@ /* --- VP8 Encoder --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_ENCODER_VP8_CAST(encoder) \ - ((GstVaapiEncoderVP8 *)(encoder)) - struct _GstVaapiEncoderVP8 { GstVaapiEncoder parent_instance; @@ -145,7 +142,7 @@ ensure_bitrate (GstVaapiEncoderVP8 * encoder) static GstVaapiEncoderStatus set_context_info (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderVP8 *encoder = GST_VAAPI_ENCODER_VP8_CAST (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) */ @@ -409,7 +406,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_vp8_encode (GstVaapiEncoder * base_encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) { - GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8_CAST (base_encoder); + GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder); GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; @@ -455,7 +452,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_vp8_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) { - GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8_CAST (base_encoder); + GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder); GstVaapiEncPicture *picture = NULL; GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS; @@ -488,7 +485,7 @@ gst_vaapi_encoder_vp8_reordering (GstVaapiEncoder * base_encoder, static GstVaapiEncoderStatus gst_vaapi_encoder_vp8_reconfigure (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8_CAST (base_encoder); + GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder); GstVaapiEncoderStatus status; status = ensure_profile (encoder); @@ -511,7 +508,7 @@ error: static gboolean gst_vaapi_encoder_vp8_init (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8_CAST (base_encoder); + GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder); encoder->frame_num = 0; encoder->last_ref = NULL; @@ -524,7 +521,7 @@ gst_vaapi_encoder_vp8_init (GstVaapiEncoder * base_encoder) static void gst_vaapi_encoder_vp8_finalize (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8_CAST (base_encoder); + GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder); clear_references (encoder); } @@ -532,7 +529,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_vp8_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { - GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8_CAST (base_encoder); + GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder); switch (prop_id) { case GST_VAAPI_ENCODER_VP8_PROP_LOOP_FILTER_LEVEL: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index bafb3cc7b5..94c9a5a6ed 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -91,9 +91,6 @@ gst_vaapi_encoder_vp9_ref_pic_mode_type (void) /* --- VP9 Encoder --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_ENCODER_VP9_CAST(encoder) \ - ((GstVaapiEncoderVP9 *)(encoder)) - struct _GstVaapiEncoderVP9 { GstVaapiEncoder parent_instance; @@ -195,7 +192,7 @@ error_unsupported_profile: static GstVaapiEncoderStatus set_context_info (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderVP9 *encoder = GST_VAAPI_ENCODER_VP9_CAST (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; @@ -431,7 +428,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_vp9_encode (GstVaapiEncoder * base_encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) { - GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9_CAST (base_encoder); + GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (base_encoder); GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; @@ -472,7 +469,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_vp9_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) { - GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9_CAST (base_encoder); + GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (base_encoder); GstVaapiEncPicture *picture = NULL; GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS; @@ -504,7 +501,7 @@ gst_vaapi_encoder_vp9_reordering (GstVaapiEncoder * base_encoder, static GstVaapiEncoderStatus gst_vaapi_encoder_vp9_reconfigure (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9_CAST (base_encoder); + GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (base_encoder); GstVaapiEncoderStatus status; status = ensure_profile (encoder); @@ -518,7 +515,7 @@ gst_vaapi_encoder_vp9_reconfigure (GstVaapiEncoder * base_encoder) static gboolean gst_vaapi_encoder_vp9_init (GstVaapiEncoder * base_encoder) { - GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9_CAST (base_encoder); + GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (base_encoder); encoder->frame_num = 0; encoder->loop_filter_level = DEFAULT_LOOP_FILTER_LEVEL; @@ -542,7 +539,7 @@ static GstVaapiEncoderStatus gst_vaapi_encoder_vp9_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { - GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9_CAST (base_encoder); + GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (base_encoder); switch (prop_id) { case GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL: From a016aa181b8239e11ab1795c2630c407a7d64811 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Mon, 28 Aug 2017 17:28:04 -0700 Subject: [PATCH 2907/3781] libs: decoder: h264: check nalu validity in parser info finalize https://bugzilla.gnome.org/show_bug.cgi?id=732266 Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index d236065772..c2d9dd7e39 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -100,6 +100,9 @@ struct _GstVaapiParserInfoH264 static void gst_vaapi_parser_info_h264_finalize (GstVaapiParserInfoH264 * pi) { + if (!pi->nalu.valid) + return; + switch (pi->nalu.type) { case GST_H264_NAL_SPS: case GST_H264_NAL_SUBSET_SPS: From 09557528983edc36414e8d62b836fc012027db7a Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Mon, 28 Aug 2017 17:32:57 -0700 Subject: [PATCH 2908/3781] libs: decoder: h264: decode SVC base layer only Drops non-base NALs when the base-only property is set to TRUE. This modifies the behavior for MVC streams with base-only too: All the non-base units are dropped before they are decoded instead of dropping the non-base frames. The relevant part from the H264 spec is: > Decoders that conform to one or more of the profiles specified in Annex A rather than the profiles specified in Annexes G or H shall ignore (remove from the bitstream and discard) the contents of all NAL units with nal_unit_type equal to 14, 15, or 20. To eliminate side effects from the offending units: - PPS's with a broken seq_parameter_set_id (referring to dropped subset SPS's) are ignored. - The NAL parsing is skipped and their flags are set to GST_VAAPI_DECODER_UNIT_FLAG_SKIP. - Prefix units are not stored in prev_pi. Otherwise, parse_slice() would use them even if they are flagged to be skipped. Subset SPS's and slice extension units are not stored there either. https://bugzilla.gnome.org/show_bug.cgi?id=732266 Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 26 +++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index c2d9dd7e39..ac45427645 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1805,8 +1805,6 @@ parse_pps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) GST_DEBUG ("parse PPS"); - priv->parser_state &= GST_H264_VIDEO_STATE_GOT_SPS; - /* Variables that don't have inferred values per the H.264 standard but that should get a default value anyway */ pps->slice_group_map_type = 0; @@ -1814,6 +1812,15 @@ parse_pps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) pps->slice_group_id = NULL; result = gst_h264_parser_parse_pps (priv->parser, &pi->nalu, pps); + + /* PPS's sps id might be an ignored subset sps in SVC streams */ + if (priv->base_only && result == GST_H264_PARSER_BROKEN_LINK) { + pi->nalu.valid = FALSE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; + } + + priv->parser_state &= GST_H264_VIDEO_STATE_GOT_SPS; + if (result != GST_H264_PARSER_OK) return get_status (result); @@ -4049,12 +4056,6 @@ decode_picture (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) g_return_val_if_fail (pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); g_return_val_if_fail (sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); - /* Only decode base stream for MVC */ - if (priv->base_only && is_mvc_profile (sps->profile_idc)) { - GST_DEBUG ("multiview sequence but base-only is set: dropping frame"); - return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME; - } - status = ensure_context (decoder, sps); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; @@ -4593,6 +4594,13 @@ gst_vaapi_decoder_h264_parse (GstVaapiDecoder * base_decoder, if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto exit; + if (priv->base_only && (pi->nalu.type == GST_H264_NAL_PREFIX_UNIT + || pi->nalu.type == GST_H264_NAL_SUBSET_SPS + || pi->nalu.type == GST_H264_NAL_SLICE_EXT)) { + GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, GST_VAAPI_DECODER_UNIT_FLAG_SKIP); + pi->nalu.valid = FALSE; + return GST_VAAPI_DECODER_STATUS_SUCCESS; + } switch (pi->nalu.type) { case GST_H264_NAL_SPS: status = parse_sps (decoder, unit); @@ -4805,7 +4813,7 @@ gst_vaapi_decoder_h264_set_alignment (GstVaapiDecoderH264 * decoder, * @decoder: a #GstVaapiDecoderH264 * @base_only: %TRUE to force decoding the base view only * - * if @base_only is %TRUE only the base view of MVC encoded streams + * if @base_only is %TRUE only the base view of MVC or SVC encoded streams * is decoded. * **/ From 1ae42facc170c48d889fab2e6c9a8430f2c79899 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Mon, 28 Aug 2017 17:34:50 -0700 Subject: [PATCH 2909/3781] vaapidecode: force add h264 SVC profiles in caps When vaapih264dec's base-only profile is set to TRUE, fake SVC profile support in caps. https://bugzilla.gnome.org/show_bug.cgi?id=732266 Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapidecode.c | 42 ++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 71c026ae90..4c33b06b05 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1161,6 +1161,14 @@ is_mvc_profile (GstVaapiProfile profile) || profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH; } +static gboolean +is_svc_profile (GstVaapiProfile profile) +{ + return profile == GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE + || profile == GST_VAAPI_PROFILE_H264_SCALABLE_HIGH; +} + + static GstCaps * add_h264_profile_in_caps (GstCaps * caps, const gchar * profile_name) { @@ -1179,6 +1187,7 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) gboolean base_only = FALSE; gboolean have_high = FALSE; gboolean have_mvc = FALSE; + gboolean have_svc = FALSE; profiles = gst_vaapi_display_get_decode_profiles (GST_VAAPI_PLUGIN_BASE_DISPLAY @@ -1217,16 +1226,37 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) allowed_sinkpad_caps = gst_caps_merge (allowed_sinkpad_caps, caps); have_mvc |= is_mvc_profile (profile); + have_svc |= is_svc_profile (profile); have_high |= profile == GST_VAAPI_PROFILE_H264_HIGH; } - if (base_only && !have_mvc && have_high) { - GST_DEBUG ("base_only: Force adding MVC profiles in caps"); + if (base_only && (!have_mvc || !have_svc) && have_high) { + if (!have_mvc) { + GST_DEBUG ("base_only: force adding MVC profiles in caps"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "multiview-high"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "stereo-high"); + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, "multiview-high"); + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, "stereo-high"); + } + + if (!have_svc) { + GST_DEBUG ("base_only: force adding SVC profiles in caps"); + + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, + "scalable-constrained-baseline"); + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, "scalable-baseline"); + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, + "scalable-high-intra"); + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, + "scalable-constrained-high"); + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, "scalable-high"); + } } decode->allowed_sinkpad_caps = gst_caps_simplify (allowed_sinkpad_caps); From 1d287ef86558db0cd6f6a220f1d456cb3753514f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 12:58:29 -0700 Subject: [PATCH 2910/3781] FEI: Add support for FEI conditional build FEI(Flexible Encoding Infrastructure) is an extension to VA API. Define USE_H264_FEI_ENCODER based on fei header file and required structures availability. https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 --- configure.ac | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/configure.ac b/configure.ac index 145e3b83b8..2ca4c85b8d 100644 --- a/configure.ac +++ b/configure.ac @@ -759,6 +759,7 @@ USE_JPEG_ENCODER=0 USE_VP8_ENCODER=0 USE_H265_ENCODER=0 USE_VP9_ENCODER=0 +USE_H264_FEI_ENCODER=0 if test $USE_ENCODERS -eq 1; then saved_CPPFLAGS="$CPPFLAGS" @@ -890,6 +891,41 @@ VAEncMiscParameterTypeVP9PerSegmantParam misc_param; ]) AS_IF([test "x$ac_cv_have_vp9_encoding_api" = "xyes"], [USE_VP9_ENCODER=1]) + dnl Check for H264 FEI Encoding API + AC_CHECK_HEADERS([va/va_fei_h264.h], [], [], + [ +#include + ]) + AC_CACHE_CHECK([for H264_FEI encoding API], + [ac_cv_have_h264_fei_encoding_api], + [ + saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" + saved_LIBS="$LIBS" + LIBS="$LIBS $LIBVA_LIBS" + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ +#include +#ifdef HAVE_VA_VA_FEI_H264_H +# include +#endif + ]], + [[ +VAEncMiscParameterFEIFrameControlH264 framectl; +VAEncFEIMBControlH264 mbcntrl; +VAEncFEIMVPredictorH264 mvpred; +VAEncFEIMBCodeH264 mbcode; +VAEncFEIDistortionH264 dist; + ]]) + ], + [ac_cv_have_h264_fei_encoding_api="yes"], + [ac_cv_have_h264_fei_encoding_api="no"]) + CPPFLAGS="$saved_CPPFLAGS" + LIBS="$saved_LIBS" + ]) + AS_IF([test "x$ac_cv_have_h264_fei_encoding_api" = "xyes"], [USE_H264_FEI_ENCODER=1]) CPPFLAGS="$saved_CPPFLAGS" fi @@ -995,6 +1031,10 @@ AC_DEFINE_UNQUOTED([USE_VP9_ENCODER], [$USE_VP9_ENCODER], [Defined to 1 if VP9 encoder is used]) AM_CONDITIONAL([USE_VP9_ENCODER], [test $USE_VP9_ENCODER -eq 1]) +AC_DEFINE_UNQUOTED([USE_H264_FEI_ENCODER], [$USE_H264_FEI_ENCODER], + [Defined to 1 if H264_FEI encoder is used]) +AM_CONDITIONAL([USE_H264_FEI_ENCODER], [test $USE_H264_FEI_ENCODER -eq 1]) + AC_DEFINE_UNQUOTED([USE_VA_VPP], [$USE_VA_VPP], [Defined to 1 if video post-processing is used]) AM_CONDITIONAL([USE_VA_VPP], [test $USE_VA_VPP -eq 1]) From 6bbe79925c007287af98a6d4e135b765ed6dfb44 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 13:02:24 -0700 Subject: [PATCH 2911/3781] FEI: libs: Add FEI Entrypoint mapping Define the new mapping GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI for VAEntrypointFEI. https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + gst-libs/gst/vaapi/gstvaapiprofile.c | 3 +++ gst-libs/gst/vaapi/gstvaapiprofile.h | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index bf23ccb6e4..6575e4e733 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -544,6 +544,7 @@ ensure_profiles (GstVaapiDisplay * display) case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: case GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE: case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP: + case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI: g_array_append_val (priv->encoders, config); break; } diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 6e8fd0a6a4..7148a83844 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -159,6 +159,9 @@ static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = { #endif #if VA_CHECK_VERSION(0,39,1) {GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP, VAEntrypointEncSliceLP}, +#endif +#if USE_H264_FEI_ENCODER + {GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI, VAEntrypointFEI}, #endif {0,} }; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 745c229d26..1a6fbb81ba 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -190,6 +190,7 @@ typedef enum { * @GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE: Encode Picture * @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP: Encode Slice low power/ * high performace varient + * @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI: FEI Encode * * The set of all entrypoints for #GstVaapiEntrypoint */ @@ -199,7 +200,8 @@ typedef enum { GST_VAAPI_ENTRYPOINT_MOCO, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, - GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP + GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP, + GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI } GstVaapiEntrypoint; const gchar * From 7d77cdd9f7b4897193674e74a75a91edf16a5ff4 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 13:45:40 -0700 Subject: [PATCH 2912/3781] FEI: libs: Add FEI functional mode configuration FEI Entrypoint can work in either one of the 3 different modes: VA_FEI_FUNCTION_ENC, VA_FEI_FUNCTION_PAK or VA_FEI_FUNCTION_ENC_PAK. Add infrastructure in gstvaapicontext and gstvaapiencoder for this functioal mode configuration. https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 --- gst-libs/gst/vaapi/gstvaapicontext.c | 10 +++++++++- gst-libs/gst/vaapi/gstvaapicontext.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder.c | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 2312878167..758d3b4969 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -229,7 +229,7 @@ config_create (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); - VAConfigAttrib attribs[6], *attrib; + VAConfigAttrib attribs[7], *attrib; VAStatus status; guint value, va_chroma_format, attrib_index; @@ -327,6 +327,14 @@ config_create (GstVaapiContext * context) attrib = &attribs[attrib_index++]; g_assert (attrib_index < G_N_ELEMENTS (attribs)); } +#endif +#if USE_H264_FEI_ENCODER + if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI) { + attrib->type = (VAConfigAttribType) VAConfigAttribFEIFunctionType; + attrib = &attribs[attrib_index++]; + g_assert (attrib_index < G_N_ELEMENTS (attribs)); + /* FIXME: Query the read-only supported MV predictors */ + } #endif break; } diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index a94259ec46..a80dbd9f10 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -62,6 +62,7 @@ typedef enum { * @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. + * @fei_function: The functional mode for FEI Entrypoint (VA_FEI_FUNCTION_*). * * Extra configuration for encoding. */ @@ -71,6 +72,7 @@ struct _GstVaapiConfigInfoEncoder guint packed_headers; gboolean roi_capability; guint roi_num_supported; + guint fei_function; }; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 0a91b2e5c2..c908e7e4fc 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -747,6 +747,7 @@ set_context_info (GstVaapiEncoder * encoder) GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); + guint fei_function = config->fei_function; init_context_info (encoder, cip, get_profile (encoder)); @@ -762,6 +763,7 @@ set_context_info (GstVaapiEncoder * encoder) config->packed_headers = get_packed_headers (encoder); config->roi_capability = get_roi_capability (encoder, &config->roi_num_supported); + config->fei_function = fei_function; return TRUE; From ac1de3d39a13db59cd5c8b9fe98f0aa29a17ba72 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 14:05:03 -0700 Subject: [PATCH 2913/3781] FEI: libs: make sure the default context creation works as expected. Current code always guess the entrypoint during init phase in case if there is no entrypoint already configured in GstVaapiContextInfo. Make sure FEI Entrypoint is not messing up with this logic. https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index c908e7e4fc..12b090a7b8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -730,7 +730,8 @@ init_context_info (GstVaapiEncoder * encoder, GstVaapiContextInfo * cip, if (cdata->codec == GST_VAAPI_CODEC_JPEG) { cip->entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; } else { - if (cip->entrypoint != GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) + if (cip->entrypoint != GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP && + cip->entrypoint != GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI) cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; } cip->chroma_type = get_default_chroma_type (encoder, cip); From 94483de40f4c5232e0928730e9e27604e0bc54b3 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 14:10:16 -0700 Subject: [PATCH 2914/3781] FEI: libs: Add virtual method for secondary context creation. Add a new vitrual method ensure_secondary_context to the base encoder which is only required for the FEI entrypoint, that too only when user configures the ENC+PAK mode. ENC+PAK mode is not something supported directly by libva or driver, but this can be enabled from the middleware. Original Author of this idea: Leilei Shang Signed-off-by: Leilei Shang Signed-off-by: xiaominc Signed-off-by: Sreerenj Balachandran https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 12 ++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 3 +++ 2 files changed, 15 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 12b090a7b8..8fb60b79df 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -843,6 +843,13 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) if (!gst_vaapi_encoder_ensure_context (encoder)) goto error_reset_context; + /* Currently only FEI entrypoint needed this. + * FEI ENC+PAK requires two contexts where the first one is for ENC + * and the second one is for PAK */ + if (klass->ensure_secondary_context + && !klass->ensure_secondary_context (encoder)) + goto error_reset_secondary_context; + #if VA_CHECK_VERSION(0,36,0) if (get_config_attribute (encoder, VAConfigAttribEncQualityRange, &quality_level_max) && quality_level_max > 0) { @@ -879,6 +886,11 @@ error_reset_context: GST_ERROR ("failed to update VA context"); return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } +error_reset_secondary_context: + { + GST_ERROR ("failed to create/update secondary VA context"); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index d73689e409..ead9f5eec3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -357,6 +357,9 @@ struct _GstVaapiEncoderClass /* get_codec_data can be NULL */ GstVaapiEncoderStatus (*get_codec_data) (GstVaapiEncoder * encoder, GstBuffer ** codec_data); + + /* To create a secondary context for a single base encoder */ + gboolean (*ensure_secondary_context) (GstVaapiEncoder * encoder); }; #define GST_VAAPI_ENCODER_CLASS_HOOK(codec, func) \ From 0b91ebeb2c3e17f81bed8053cb6ddf84af45b6cf Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 14:22:12 -0700 Subject: [PATCH 2915/3781] FEI: libs: add H264 fei specific utility functions Added enum/flag type definitions for a number of FEI input and output parameters. Original author of the patch: Wang, Yi https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 Signed-off-by: Wang, Yi Signed-off-by: Sreerenj Balachandran --- gst-libs/gst/vaapi/Makefile.am | 13 ++ gst-libs/gst/vaapi/gstvaapifeiutils_h264.c | 222 +++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifeiutils_h264.h | 215 ++++++++++++++++++++ 3 files changed, 450 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapifeiutils_h264.c create mode 100644 gst-libs/gst/vaapi/gstvaapifeiutils_h264.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f7da153ce3..803857c417 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -237,6 +237,17 @@ libgstvaapi_source_c += $(libgstvaapi_vp9enc_source_c) libgstvaapi_source_h += $(libgstvaapi_vp9enc_source_h) endif +libgstvaapi_h264feienc_source_c = \ + gstvaapifeiutils_h264.c \ + $(NULL) +libgstvaapi_h264feienc_source_h = \ + gstvaapifeiutils_h264.h \ + $(NULL) +if USE_H264_FEI_ENCODER +libgstvaapi_source_c += $(libgstvaapi_h264feienc_source_c) +libgstvaapi_source_h += $(libgstvaapi_h264feienc_source_h) +endif + libgstvaapi_drm_source_c = \ gstvaapidisplay_drm.c \ gstvaapiwindow_drm.c \ @@ -523,6 +534,8 @@ EXTRA_DIST = \ $(libgstvaapi_egl_source_c) \ $(libgstvaapi_egl_source_h) \ $(libgstvaapi_egl_source_priv_h) \ + $(libgstvaapi_h264feienc_source_h) \ + $(libgstvaapi_h264feienc_source_c) \ $(NULL) -include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/vaapi/gstvaapifeiutils_h264.c b/gst-libs/gst/vaapi/gstvaapifeiutils_h264.c new file mode 100644 index 0000000000..38411a7268 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapifeiutils_h264.c @@ -0,0 +1,222 @@ +/* + * gstvaapifeiutils_h264_fei.c - Fei related utilities for H264 + * + * Copyright (C) 2016-2018 Intel Corporation + * Author: Wang, Yi + * Author: Sreerenj Balachandran + * + * 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 + +#include "gstvaapifeiutils_h264.h" + +/* FeiFixme: This is common fei modes for all codecs, + * move to a generic header file */ +/* --- GstVaapiFeiMode --- */ +GType +gst_vaapi_fei_mode_get_type (void) +{ + static volatile gsize g_type = 0; + + static const GFlagsValue encoding_mode_values[] = { + {GST_VAAPI_FEI_MODE_ENC, + "ENC Mode", "ENC"}, + {GST_VAAPI_FEI_MODE_PAK, + "PAK Mode", "PAK"}, + {GST_VAAPI_FEI_MODE_ENC_PAK, + "ENC_PAK Mode", "ENC_PAK"}, + {0, NULL, NULL}, + }; + + if (g_once_init_enter (&g_type)) { + GType type = + g_flags_register_static ("GstVaapiFeiMode", encoding_mode_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} + +/* --- GstVaapiFeiH264SearchPath --- */ +GType +gst_vaapi_fei_h264_search_path_get_type (void) +{ + static volatile gsize g_type = 0; + + static const GEnumValue search_path_values[] = { + {GST_VAAPI_FEI_H264_FULL_SEARCH_PATH, + "full search path", "full"}, + {GST_VAAPI_FEI_H264_DIAMOND_SEARCH_PATH, + "diamond search path", "diamond"}, + {0, NULL, NULL}, + }; + + if (g_once_init_enter (&g_type)) { + GType type = g_enum_register_static ("GstVaapiFeiH264SearchPath", + search_path_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} + +/* --- GstVaapiFeiH264SearchWindow --- */ +GType +gst_vaapi_fei_h264_search_window_get_type (void) +{ + static volatile gsize g_type = 0; + + static const GEnumValue search_window_values[] = { + {GST_VAAPI_FEI_H264_SEARCH_WINDOW_NONE, + "not use predefined search window", "none"}, + {GST_VAAPI_FEI_H264_SEARCH_WINDOW_TINY, + "4 SUs 24x24 window diamond search", "tiny"}, + {GST_VAAPI_FEI_H264_SEARCH_WINDOW_SMALL, + "9 SUs 28x28 window diamond search", "small"}, + {GST_VAAPI_FEI_H264_SEARCH_WINDOW_DIAMOND, + "16 SUs 48x40 window diamond search", "diamond"}, + {GST_VAAPI_FEI_H264_SEARCH_WINDOW_LARGE_DIAMOND, + "32 SUs 48x40 window diamond search", "large diamond"}, + {GST_VAAPI_FEI_H264_SEARCH_WINDOW_EXHAUSTIVE, + "48 SUs 48x40 window full search", "exhaustive"}, + {GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_DIAMOND, + "16 SUs 64x32 window diamond search", "horizon diamond"}, + {GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_LARGE_DIAMOND, + "32 SUs 64x32 window diamond search", "horizon large diamond"}, + {GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_EXHAUSTIVE, + "48 SUs 64x32 window full search", "horizon exhaustive"}, + {0, NULL, NULL}, + }; + + if (g_once_init_enter (&g_type)) { + GType type = g_enum_register_static ("GstVaapiFeiH264SearchWindow", + search_window_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} + +/* --- GstVaapiFeiH264SubPelMode --- */ +GType +gst_vaapi_fei_h264_sub_pel_mode_get_type (void) +{ + static volatile gsize g_type = 0; + + static const GEnumValue sub_pel_mode_values[] = { + {GST_VAAPI_FEI_H264_INTEGER_ME, + "integer mode searching", "integer"}, + {GST_VAAPI_FEI_H264_HALF_ME, + "half-pel mode searching", "half"}, + {GST_VAAPI_FEI_H264_QUARTER_ME, + "quarter-pel mode searching", "quarter"}, + {0, NULL, NULL}, + }; + + if (g_once_init_enter (&g_type)) { + GType type = g_enum_register_static ("GstVaapiFeiH264SubPelMode", + sub_pel_mode_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} + +/* --- GstVaapiFeiH264SadMode --- */ +GType +gst_vaapi_fei_h264_sad_mode_get_type (void) +{ + static volatile gsize g_type = 0; + + static const GEnumValue sad_mode_values[] = { + {GST_VAAPI_FEI_H264_SAD_NONE_TRANS, + "none transform adjusted", "none"}, + {GST_VAAPI_FEI_H264_SAD_HAAR_TRANS, + "Haar transform adjusted", "haar"}, + {0, NULL, NULL}, + }; + + if (g_once_init_enter (&g_type)) { + GType type = + g_enum_register_static ("GstVaapiFeiH264SadMode", sad_mode_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} + +/* --- GstVaapiFeiH264IntraPartMask --- */ +GType +gst_vaapi_fei_h264_intra_part_mask_get_type (void) +{ + static volatile gsize g_type = 0; + + static const GFlagsValue intra_part_mask_values[] = { + {GST_VAAPI_FEI_H264_DISABLE_INTRA_NONE, + "enable all intra mode", "enable all"}, + {GST_VAAPI_FEI_H264_DISABLE_INTRA_16x16, + "luma_intra_16x16 disabled", "intra16x16 disabled"}, + {GST_VAAPI_FEI_H264_DISABLE_INTRA_8x8, + "luma_intra_8x8 disabled", "intra8x8 disabled"}, + {GST_VAAPI_FEI_H264_DISABLE_INTRA_4x4, + "luma_intra_4x4 disabled", "intra4x4 disabled"}, + {0, NULL, NULL}, + }; + + if (g_once_init_enter (&g_type)) { + GType type = g_flags_register_static ("GstVaapiFeiH264IntraPartMask", + intra_part_mask_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} + +/* --- GstVaapiFeiH264SubMbPartMask --- */ +GType +gst_vaapi_fei_h264_sub_mb_part_mask_get_type (void) +{ + static volatile gsize g_type = 0; + + static const GFlagsValue sub_mb_part_mask_values[] = { + {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_NONE, + "enable all subpartitions", "enable all"}, + {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_16x16, + "16x16 sub-macroblock disabled", "16x16 submb part disabled"}, + {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x16x8, + "2x(16x8) sub-macroblock within 16x16 disabled", + "16x8 submb part disabled"}, + {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x16, + "2x(8x16) sub-macroblock within 16x16 disabled", + "8x16 submb part disabled"}, + {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_1x8x8, + "1x(8x8) sub-partition for 4x(8x8) within 16x16 disabled", + "8x8 submb part disabled"}, + {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x4, + "2x(8x4) sub-partition for 4x(8x8) within 16x16 disabled", + "8x4 submb part disabled"}, + {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x4x8, + "2x(4x8) sub-partition for 4x(8x8) within 16x16 disabled", + "4x8 submb part disabled"}, + {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_4x4x4, + "4x(4x4) sub-partition for 4x(8x8) within 16x16 disabled", + "4x4 submb part disabled"}, + {0, NULL, NULL}, + }; + + if (g_once_init_enter (&g_type)) { + GType type = g_flags_register_static ("GstVaapiFeiH264SubMbPartMask", + sub_mb_part_mask_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} diff --git a/gst-libs/gst/vaapi/gstvaapifeiutils_h264.h b/gst-libs/gst/vaapi/gstvaapifeiutils_h264.h new file mode 100644 index 0000000000..a0eeb699c9 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapifeiutils_h264.h @@ -0,0 +1,215 @@ +/* + * gstvaapifeiutils_h264.h - FEI related utilities for H264 + * + * Copyright (C) 2016-2018 Intel Corporation + * Author: Wang, Yi + * Author: Sreerenj Balachandran + * + * 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_FEI_UTILS_H264_H +#define GST_VAAPI_FEI_UTILS_H264_H + +#include + +G_BEGIN_DECLS + +typedef struct _GstVaapiFeiInfoToPakH264 GstVaapiFeiInfoToPakH264; + +/* Structure useful for FEI ENC+PAK mode */ +struct _GstVaapiFeiInfoToPakH264 +{ + VAEncSequenceParameterBufferH264 h264_enc_sps; + VAEncPictureParameterBufferH264 h264_enc_pps; + GArray *h264_slice_headers; + guint h264_slice_num; +}; + +/******************* Common FEI enum definition for all codecs ***********/ +/* FeiFixme: This should be a common fei mode for all codecs, + * move to a common header file */ +#define GST_VAAPI_FEI_MODE_DEFAULT GST_VAAPI_FEI_MODE_ENC_PAK +typedef enum +{ + GST_VAAPI_FEI_MODE_ENC = (1 << 0), + GST_VAAPI_FEI_MODE_PAK = (1 << 1), + GST_VAAPI_FEI_MODE_ENC_PAK = (1 << 2) +} GstVaapiFeiMode; +/** +* GST_VAAPI_TYPE_FEI_MODE: +* +* A type that represents the fei encoding mode. +* +* Return value: the #GType of GstVaapiFeiMode +*/ +#define GST_VAAPI_TYPE_FEI_MODE (gst_vaapi_fei_mode_get_type()) + + +/******************* H264 Specific FEI enum definitions ***********/ + +typedef enum +{ + GST_VAAPI_FEI_H264_FULL_SEARCH_PATH = 0, + GST_VAAPI_FEI_H264_DIAMOND_SEARCH_PATH, +} GstVaapiFeiH264SearchPath; + +typedef enum +{ + GST_VAAPI_FEI_H264_SEARCH_WINDOW_NONE = 0, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_TINY, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_SMALL, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_DIAMOND, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_LARGE_DIAMOND, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_EXHAUSTIVE, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_DIAMOND, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_LARGE_DIAMOND, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_EXHAUSTIVE, +} GstVaapiFeiH264SearchWindow; + +typedef enum +{ + GST_VAAPI_FEI_H264_INTEGER_ME = 0, + GST_VAAPI_FEI_H264_HALF_ME = 1, + GST_VAAPI_FEI_H264_QUARTER_ME = 3, +} GstVaapiFeiH264SubPelMode; + +typedef enum +{ + GST_VAAPI_FEI_H264_SAD_NONE_TRANS = 0, + GST_VAAPI_FEI_H264_SAD_HAAR_TRANS = 2, +} GstVaapiFeiH264SadMode; + +typedef enum +{ + GST_VAAPI_FEI_H264_DISABLE_INTRA_NONE = 0, + GST_VAAPI_FEI_H264_DISABLE_INTRA_16x16 = (1 << 0), + GST_VAAPI_FEI_H264_DISABLE_INTRA_8x8 = (1 << 1), + GST_VAAPI_FEI_H264_DISABLE_INTRA_4x4 = (1 << 2), +} GstVaapiFeiH264IntraPartMask; + +typedef enum +{ + GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_NONE = 0, + GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_16x16 = (1 << 1), + GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x16x8 = (1 << 2), + GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x16 = (1 << 3), + GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_1x8x8 = (1 << 4), + GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x4 = (1 << 5), + GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x4x8 = (1 << 6), + GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_4x4x4 = (1 << 7), +} GstVaapiFeiH264SubMbPartMask; + +#define GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT \ + GST_VAAPI_FEI_H264_FULL_SEARCH_PATH +#define GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT \ + GST_VAAPI_FEI_H264_SEARCH_WINDOW_NONE +#define GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT \ + GST_VAAPI_FEI_H264_INTEGER_ME +#define GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT \ + GST_VAAPI_FEI_H264_SAD_NONE_TRANS +#define GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT \ + GST_VAAPI_FEI_H264_DISABLE_INTRA_NONE +#define GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT \ + GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_NONE +#define GST_VAAPI_FEI_H264_SEARCH_PATH_LENGTH_DEFAULT 32 +#define GST_VAAPI_FEI_H264_REF_WIDTH_DEFAULT 32 +#define GST_VAAPI_FEI_H264_REF_HEIGHT_DEFAULT 32 + +/** +* GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH: +* +* A type that represents the fei control param: search path. +* +* Return value: the #GType of GstVaapiFeiSearchPath +*/ +#define GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH gst_vaapi_fei_h264_search_path_get_type() + +/** +* GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW: +* +* A type that represents the fei control param: search window. +* +* Return value: the #GType of GstVaapiFeiSearchWindow +*/ +#define GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW gst_vaapi_fei_h264_search_window_get_type() + +/** +* GST_VAAPI_TYPE_FEI_H264_SAD_MODE: +* +* A type that represents the fei control param: sad mode. +* +* Return value: the #GType of GstVaapiFeiSadMode +*/ +#define GST_VAAPI_TYPE_FEI_H264_SAD_MODE gst_vaapi_fei_h264_sad_mode_get_type() + +/** +* GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK: +* +* A type that represents the fei control param: intra part mask. +* +* Return value: the #GType of GstVaapiFeiIntaPartMask +*/ +#define GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK gst_vaapi_fei_h264_intra_part_mask_get_type() + +/** +* GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE: +* +* A type that represents the fei control param: sub pel mode. +* +* Return value: the #GType of GstVaapiFeiSubPelMode +*/ +#define GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE gst_vaapi_fei_h264_sub_pel_mode_get_type() + +/** +* GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK: +* +* A type that represents the fei control param: sub maroclock partition mask. +* +* Return value: the #GType of GstVaapiFeiH264SubMbPartMask +*/ +#define GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK gst_vaapi_fei_h264_sub_mb_part_mask_get_type() + +GType +gst_vaapi_fei_mode_get_type (void) + G_GNUC_CONST; + +GType +gst_vaapi_fei_h264_search_path_get_type (void) + G_GNUC_CONST; + +GType +gst_vaapi_fei_h264_search_window_get_type (void) + G_GNUC_CONST; + +GType +gst_vaapi_fei_h264_sad_mode_get_type (void) + G_GNUC_CONST; + +GType +gst_vaapi_fei_h264_sub_pel_mode_get_type (void) + G_GNUC_CONST; + +GType +gst_vaapi_fei_h264_intra_part_mask_get_type (void) + G_GNUC_CONST; + +GType +gst_vaapi_fei_h264_sub_mb_part_mask_get_type (void) + G_GNUC_CONST; + +G_END_DECLS +#endif /* GST_VAAPI_UTILS_FEI_H264_H */ From d0d9f5e274950f32e494c046819a8da73d3d3fae Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 15:35:10 -0700 Subject: [PATCH 2916/3781] FEI: Add codec objects for fei usecase There are 6 new va buffer types, each defined as a specific codec object. Borrowed the code from gstvaapicodecobject , but made a clear separation to avoid any possible mess-up. Because unlike the other gstvaaicodecobjects, feicodecobjects can be shared between elements and also can be accessed from different thread. Unlike the other fei codecs object, VAEncMiscParameterTypeFEIFrameControl object is not shared between elements.So we utilize the already existing gst_vaapi_enc_misc_param_new(), but still keeping the code in gstvaapfei_objects_priv.h in order to have a better code readability. Fixme: -- Probably we need _locked_map() and _unlocked_map() -- Context can be associated with PreEnc(not just Enoder) once we have the proper support inplace, but for now we don't have PreEnc support, so should be safe enough to use GstVaapiEncoder. https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 --- gst-libs/gst/vaapi/Makefile.am | 7 + gst-libs/gst/vaapi/gstvaapifei_objects.c | 386 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifei_objects.h | 112 +++++ gst-libs/gst/vaapi/gstvaapifei_objects_priv.h | 236 +++++++++++ 4 files changed, 741 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapifei_objects.c create mode 100644 gst-libs/gst/vaapi/gstvaapifei_objects.h create mode 100644 gst-libs/gst/vaapi/gstvaapifei_objects_priv.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 803857c417..353eae9207 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -239,13 +239,19 @@ endif libgstvaapi_h264feienc_source_c = \ gstvaapifeiutils_h264.c \ + gstvaapifei_objects.c \ $(NULL) libgstvaapi_h264feienc_source_h = \ gstvaapifeiutils_h264.h \ + gstvaapifei_objects.h \ $(NULL) +libgstvaapi_h264feienc_source_priv_h = \ + gstvaapifei_objects_priv.h \ + $(NULL) if USE_H264_FEI_ENCODER libgstvaapi_source_c += $(libgstvaapi_h264feienc_source_c) libgstvaapi_source_h += $(libgstvaapi_h264feienc_source_h) +libgstvaapi_source_priv_h += $(libgstvaapi_h264feienc_source_priv_h) endif libgstvaapi_drm_source_c = \ @@ -536,6 +542,7 @@ EXTRA_DIST = \ $(libgstvaapi_egl_source_priv_h) \ $(libgstvaapi_h264feienc_source_h) \ $(libgstvaapi_h264feienc_source_c) \ + $(libgstvaapi_h264feienc_source_priv_h) \ $(NULL) -include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/vaapi/gstvaapifei_objects.c b/gst-libs/gst/vaapi/gstvaapifei_objects.c new file mode 100644 index 0000000000..fe71dcfb44 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapifei_objects.c @@ -0,0 +1,386 @@ +/* + * gstvaapifei_objects.c - VA FEI objects abstraction + * + * Copyright (C) 2017-2018 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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_priv.h" +#include "gstvaapicompat.h" +#include "gstvaapiutils.h" +#include "gstvaapifei_objects.h" +#include "gstvaapifei_objects_priv.h" +#define DEBUG 1 +#include "gstvaapidebug.h" + +/* ------------------------------------------------------------------------- */ +/* --- Base Codec Object --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_FEI_CODEC_OBJECT_GET_CLASS(object) \ + gst_vaapi_fei_codec_object_get_class(object) + +const GstVaapiFeiCodecObjectClass * +gst_vaapi_fei_codec_object_get_class (GstVaapiFeiCodecObject * object) +{ + return (const GstVaapiFeiCodecObjectClass *) + GST_VAAPI_MINI_OBJECT_GET_CLASS (object); +} + +static gboolean +gst_vaapi_fei_codec_object_create (GstVaapiFeiCodecObject * object, + const GstVaapiFeiCodecObjectConstructorArgs * args) +{ + const GstVaapiFeiCodecObjectClass *klass; + + g_return_val_if_fail (args->param_size > 0, FALSE); + + if (GST_VAAPI_MINI_OBJECT_FLAG_IS_SET (object, + GST_VAAPI_FEI_CODEC_OBJECT_FLAG_CONSTRUCTED)) + return TRUE; + + klass = GST_VAAPI_FEI_CODEC_OBJECT_GET_CLASS (object); + if (!klass->create || !klass->create (object, args)) + return FALSE; + + GST_VAAPI_MINI_OBJECT_FLAG_SET (object, + GST_VAAPI_FEI_CODEC_OBJECT_FLAG_CONSTRUCTED); + return TRUE; +} + +GstVaapiFeiCodecObject * +gst_vaapi_fei_codec_object_new (const GstVaapiFeiCodecObjectClass * + object_class, GstVaapiFeiCodecBase * codec, gconstpointer param, + guint param_size, gconstpointer data, guint data_size, guint flags) +{ + GstVaapiFeiCodecObject *obj; + GstVaapiFeiCodecObjectConstructorArgs args; + + obj = (GstVaapiFeiCodecObject *) + gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS (object_class)); + if (!obj) + return NULL; + + obj = GST_VAAPI_FEI_CODEC_OBJECT (obj); + obj->codec = codec; + + args.param = param; + args.param_size = param_size; + args.data = data; + args.data_size = data_size; + args.flags = flags; + + if (gst_vaapi_fei_codec_object_create (obj, &args)) + return obj; + + gst_vaapi_fei_codec_object_unref (obj); + return NULL; +} + +GstVaapiFeiCodecObject * +gst_vaapi_fei_codec_object_ref (GstVaapiFeiCodecObject * object) +{ + return ((GstVaapiFeiCodecObject *) + gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (object))); +} + +void +gst_vaapi_fei_codec_object_unref (GstVaapiFeiCodecObject * object) +{ + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (object)); +} + +void +gst_vaapi_fei_codec_object_replace (GstVaapiFeiCodecObject ** old_object_ptr, + GstVaapiFeiCodecObject * new_object) +{ + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_object_ptr), + GST_VAAPI_MINI_OBJECT (new_object)); +} + +/* FeiFixme: map_unlocked and map_lock could be needed */ +gboolean +gst_vaapi_fei_codec_object_map (GstVaapiFeiCodecObject * object, + gpointer * data, guint * size) +{ + g_return_val_if_fail (object != NULL, FALSE); + + /*FeiFixme: explicit map if not yet mapped */ + *data = object->param; + *size = object->param_size; + + return TRUE; +} + +void +gst_vaapi_fei_codec_object_unmap (GstVaapiFeiCodecObject * object) +{ + g_return_if_fail (object != NULL); + vaapi_unmap_buffer (GST_VAAPI_ENCODER_CAST (object->codec)->va_display, + object->param_id, &object->param); +} + +#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 + +/* ------------------------------------------------------------------------- */ +/* --- FEI Mb Code buffer --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMbCode, + gst_vaapi_enc_fei_mb_code); + +void +gst_vaapi_enc_fei_mb_code_destroy (GstVaapiEncFeiMbCode * fei_mb_code) +{ + GstVaapiFeiCodecObject *object = &fei_mb_code->parent_instance; + vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mb_code), &object->param_id); + object->param = NULL; +} + +gboolean +gst_vaapi_enc_fei_mb_code_create (GstVaapiEncFeiMbCode * + fei_mb_code, const GstVaapiFeiCodecObjectConstructorArgs * args) +{ + GstVaapiFeiCodecObject *object = &fei_mb_code->parent_instance; + object->param_id = VA_INVALID_ID; + return vaapi_create_buffer (GET_VA_DISPLAY (fei_mb_code), + GET_VA_CONTEXT (fei_mb_code), + (VABufferType) VAEncFEIMBCodeBufferType, args->param_size, + args->param, &object->param_id, &object->param); +} + +GstVaapiEncFeiMbCode * +gst_vaapi_enc_fei_mb_code_new (GstVaapiEncoder * encoder, + gconstpointer param, guint param_size) +{ + GstVaapiFeiCodecObject *object; + + object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMbCodeClass, + GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); + if (!object) + return NULL; + object->param_size = param_size; + return GST_VAAPI_ENC_FEI_MB_CODE_CAST (object); +} + +/* ------------------------------------------------------------------------- */ +/* --- FEI MV buffer --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMv, gst_vaapi_enc_fei_mv); + +void +gst_vaapi_enc_fei_mv_destroy (GstVaapiEncFeiMv * fei_mv) +{ + GstVaapiFeiCodecObject *object = &fei_mv->parent_instance; + vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mv), &object->param_id); + object->param = NULL; +} + +gboolean +gst_vaapi_enc_fei_mv_create (GstVaapiEncFeiMv * + fei_mv, const GstVaapiFeiCodecObjectConstructorArgs * args) +{ + GstVaapiFeiCodecObject *object = &fei_mv->parent_instance; + object->param_id = VA_INVALID_ID; + return vaapi_create_buffer (GET_VA_DISPLAY (fei_mv), + GET_VA_CONTEXT (fei_mv), + (VABufferType) VAEncFEIMVBufferType, args->param_size, + args->param, &object->param_id, &object->param); +} + +GstVaapiEncFeiMv * +gst_vaapi_enc_fei_mv_new (GstVaapiEncoder * encoder, + gconstpointer param, guint param_size) +{ + GstVaapiFeiCodecObject *object; + + object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMvClass, + GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); + if (!object) + return NULL; + object->param_size = param_size; + return GST_VAAPI_ENC_FEI_NEW_MV_CAST (object); +} + +/* ------------------------------------------------------------------------- */ +/* --- FEI Mv predictor buffer --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMvPredictor, + gst_vaapi_enc_fei_mv_predictor); + +void +gst_vaapi_enc_fei_mv_predictor_destroy (GstVaapiEncFeiMvPredictor * + fei_mv_predictor) +{ + GstVaapiFeiCodecObject *object = &fei_mv_predictor->parent_instance; + vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mv_predictor), &object->param_id); + object->param = NULL; +} + +gboolean +gst_vaapi_enc_fei_mv_predictor_create (GstVaapiEncFeiMvPredictor * + fei_mv_predictor, const GstVaapiFeiCodecObjectConstructorArgs * args) +{ + GstVaapiFeiCodecObject *object = &fei_mv_predictor->parent_instance; + object->param_id = VA_INVALID_ID; + return vaapi_create_buffer (GET_VA_DISPLAY (fei_mv_predictor), + GET_VA_CONTEXT (fei_mv_predictor), + (VABufferType) VAEncFEIMVPredictorBufferType, args->param_size, + args->param, &object->param_id, &object->param); +} + +GstVaapiEncFeiMvPredictor * +gst_vaapi_enc_fei_mv_predictor_new (GstVaapiEncoder * encoder, + gconstpointer param, guint param_size) +{ + GstVaapiFeiCodecObject *object; + + object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMvPredictorClass, + GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); + if (!object) + return NULL; + object->param_size = param_size; + return GST_VAAPI_ENC_FEI_NEW_MV_PREDICTOR_CAST (object); +} + +/* ------------------------------------------------------------------------- */ +/* --- FEI Mb Control buffer --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMbControl, + gst_vaapi_enc_fei_mb_control); + +void +gst_vaapi_enc_fei_mb_control_destroy (GstVaapiEncFeiMbControl * fei_mb_control) +{ + GstVaapiFeiCodecObject *object = &fei_mb_control->parent_instance; + vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mb_control), &object->param_id); + object->param = NULL; +} + +gboolean +gst_vaapi_enc_fei_mb_control_create (GstVaapiEncFeiMbControl * + fei_mb_control, const GstVaapiFeiCodecObjectConstructorArgs * args) +{ + GstVaapiFeiCodecObject *object = &fei_mb_control->parent_instance; + object->param_id = VA_INVALID_ID; + return vaapi_create_buffer (GET_VA_DISPLAY (fei_mb_control), + GET_VA_CONTEXT (fei_mb_control), + (VABufferType) VAEncFEIMBControlBufferType, args->param_size, + args->param, &object->param_id, &object->param); +} + +GstVaapiEncFeiMbControl * +gst_vaapi_enc_fei_mb_control_new (GstVaapiEncoder * encoder, + gconstpointer param, guint param_size) +{ + GstVaapiFeiCodecObject *object; + + object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMbControlClass, + GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); + if (!object) + return NULL; + object->param_size = param_size; + return GST_VAAPI_ENC_FEI_NEW_MB_CONTROL_CAST (object); +} + +/* ------------------------------------------------------------------------- */ +/* --- FEI qp buffer --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiQp, gst_vaapi_enc_fei_qp); + +void +gst_vaapi_enc_fei_qp_destroy (GstVaapiEncFeiQp * fei_qp) +{ + GstVaapiFeiCodecObject *object = &fei_qp->parent_instance; + vaapi_destroy_buffer (GET_VA_DISPLAY (fei_qp), &object->param_id); + object->param = NULL; +} + +gboolean +gst_vaapi_enc_fei_qp_create (GstVaapiEncFeiQp * fei_qp, + const GstVaapiFeiCodecObjectConstructorArgs * args) +{ + GstVaapiFeiCodecObject *object = &fei_qp->parent_instance; + object->param_id = VA_INVALID_ID; + return vaapi_create_buffer (GET_VA_DISPLAY (fei_qp), + GET_VA_CONTEXT (fei_qp), + (VABufferType) VAEncQPBufferType, args->param_size, + args->param, &object->param_id, &object->param); +} + +GstVaapiEncFeiQp * +gst_vaapi_enc_fei_qp_new (GstVaapiEncoder * encoder, + gconstpointer param, guint param_size) +{ + GstVaapiFeiCodecObject *object; + + object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiQpClass, + GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); + if (!object) + return NULL; + object->param_size = param_size; + return GST_VAAPI_ENC_FEI_NEW_QP_CAST (object); +} + +/* ------------------------------------------------------------------------- */ +/* --- FEI Distortion buffer --- */ +/* ------------------------------------------------------------------------- */ + +GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiDistortion, + gst_vaapi_enc_fei_distortion); + +void +gst_vaapi_enc_fei_distortion_destroy (GstVaapiEncFeiDistortion * fei_dist) +{ + GstVaapiFeiCodecObject *object = &fei_dist->parent_instance; + vaapi_destroy_buffer (GET_VA_DISPLAY (fei_dist), &object->param_id); + object->param = NULL; +} + +gboolean +gst_vaapi_enc_fei_distortion_create (GstVaapiEncFeiDistortion * fei_dist, + const GstVaapiFeiCodecObjectConstructorArgs * args) +{ + GstVaapiFeiCodecObject *object = &fei_dist->parent_instance; + object->param_id = VA_INVALID_ID; + return vaapi_create_buffer (GET_VA_DISPLAY (fei_dist), + GET_VA_CONTEXT (fei_dist), + (VABufferType) VAEncFEIDistortionBufferType, args->param_size, + args->param, &object->param_id, &object->param); +} + +GstVaapiEncFeiDistortion * +gst_vaapi_enc_fei_distortion_new (GstVaapiEncoder * encoder, + gconstpointer param, guint param_size) +{ + GstVaapiFeiCodecObject *object; + + object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiDistortionClass, + GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); + if (!object) + return NULL; + object->param_size = param_size; + return GST_VAAPI_ENC_FEI_NEW_DISTORTION_CAST (object); +} diff --git a/gst-libs/gst/vaapi/gstvaapifei_objects.h b/gst-libs/gst/vaapi/gstvaapifei_objects.h new file mode 100644 index 0000000000..03aef3da63 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapifei_objects.h @@ -0,0 +1,112 @@ +/* + * gstvaapifei_objects.h - VA FEI objects abstraction + * + * Copyright (C) 2017-2018 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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_FEI_OBJECTS_H +#define GST_VAAPI_FEI_OBJECTS_H + +G_BEGIN_DECLS + +#define GST_VAAPI_FEI_CODEC_OBJECT(obj) \ + ((GstVaapiFeiCodecObject *) (obj)) + +typedef struct _GstVaapiFeiCodecObject GstVaapiFeiCodecObject; + +typedef struct _GstVaapiEncFeiMbCode GstVaapiEncFeiMbCode; +typedef struct _GstVaapiEncFeiMv GstVaapiEncFeiMv; +typedef struct _GstVaapiEncFeiMvPredictor GstVaapiEncFeiMvPredictor; +typedef struct _GstVaapiEncFeiMbControl GstVaapiEncFeiMbControl; +typedef struct _GstVaapiEncFeiQp GstVaapiEncFeiQp; +typedef struct _GstVaapiEncFeiDistortion GstVaapiEncFeiDistortion; + +struct _GstVaapiEncoder; + +/* ----------------- Base Codec Object ---------------------------- */ +/* ------------------------------------------------------------------------- */ + +GstVaapiFeiCodecObject * +gst_vaapi_fei_codec_object_ref (GstVaapiFeiCodecObject *object); + +void +gst_vaapi_fei_codec_object_unref (GstVaapiFeiCodecObject *object); + +void +gst_vaapi_fei_codec_object_replace (GstVaapiFeiCodecObject **old_object_ptr, + GstVaapiFeiCodecObject *new_object); + +gboolean +gst_vaapi_fei_codec_object_map (GstVaapiFeiCodecObject *object, + gpointer *data, guint *size); + +void +gst_vaapi_fei_codec_object_unmap (GstVaapiFeiCodecObject *object); + +/* ------------------------------------------------------------------------- */ +/* --- MB Code buffer --- */ +/* ------------------------------------------------------------------------- */ + +GstVaapiEncFeiMbCode * +gst_vaapi_enc_fei_mb_code_new (struct _GstVaapiEncoder * encoder, gconstpointer param, + guint param_size); + +/* ------------------------------------------------------------------------- */ +/* --- MV Buffer --- */ +/* ------------------------------------------------------------------------- */ + +GstVaapiEncFeiMv * +gst_vaapi_enc_fei_mv_new (struct _GstVaapiEncoder * encoder, gconstpointer param, + guint param_size); + +/* ------------------------------------------------------------------------- */ +/* --- MV Predictor Buffer --- */ +/* ------------------------------------------------------------------------- */ + +GstVaapiEncFeiMvPredictor * +gst_vaapi_enc_fei_mv_predictor_new (struct _GstVaapiEncoder * encoder, gconstpointer param, + guint param_size); + +/* ------------------------------------------------------------------------- */ +/* --- MB Control Buffer --- */ +/* ------------------------------------------------------------------------- */ + +GstVaapiEncFeiMbControl * +gst_vaapi_enc_fei_mb_control_new (struct _GstVaapiEncoder * encoder, gconstpointer param, + guint param_size); + +/* ------------------------------------------------------------------------- */ +/* --- QP Buffer --- */ +/* ------------------------------------------------------------------------- */ + +GstVaapiEncFeiQp * +gst_vaapi_enc_fei_qp_new (struct _GstVaapiEncoder * encoder, gconstpointer param, + guint param_size); + +/* ------------------------------------------------------------------------- */ +/* --- Distortion Buffer --- */ +/* ------------------------------------------------------------------------- */ + +GstVaapiEncFeiDistortion * +gst_vaapi_enc_fei_distortion_new (struct _GstVaapiEncoder * encoder, gconstpointer param, + guint param_size); + +G_END_DECLS + +#endif /* GST_VAAPI_FEI_OBJECTS_H */ diff --git a/gst-libs/gst/vaapi/gstvaapifei_objects_priv.h b/gst-libs/gst/vaapi/gstvaapifei_objects_priv.h new file mode 100644 index 0000000000..87978775fa --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapifei_objects_priv.h @@ -0,0 +1,236 @@ +/* + * gstvaapifei_objects_priv.h - VA FEI objects abstraction (priv definitions) + * + * Copyright (C) 2017-2018 Intel Corporation + * Author: Sreerenj Balachandran + * + * 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_FEI_OBJECTS_PRIV_H +#define GST_VAAPI_FEI_OBJECTS_PRIV_H + +#include +#include +#include +#include +G_BEGIN_DECLS + +typedef gpointer GstVaapiFeiCodecBase; +typedef struct _GstVaapiFeiCodecObjectClass GstVaapiFeiCodecObjectClass; + +#define GST_VAAPI_FEI_CODEC_BASE(obj) \ + ((GstVaapiFeiCodecBase *) (obj)) + +enum +{ + GST_VAAPI_FEI_CODEC_OBJECT_FLAG_CONSTRUCTED = (1 << 0), + GST_VAAPI_FEI_CODEC_OBJECT_FLAG_LAST = (1 << 1) +}; + +typedef struct +{ + gconstpointer param; + guint param_size; + gconstpointer data; + guint data_size; + guint flags; +} GstVaapiFeiCodecObjectConstructorArgs; + +typedef gboolean +(*GstVaapiFeiCodecObjectCreateFunc)(GstVaapiFeiCodecObject * object, + const GstVaapiFeiCodecObjectConstructorArgs * args); + +typedef GDestroyNotify GstVaapiFeiCodecObjectDestroyFunc; + +/** + * GstVaapiFeiCodecObject: + * + * A #GstVaapiMiniObject holding the base codec object data + */ +struct _GstVaapiFeiCodecObject +{ + /*< private >*/ + GstVaapiMiniObject parent_instance; + GstVaapiFeiCodecBase *codec; + VABufferID param_id; + gpointer param; + guint param_size; +}; + +/** + * GstVaapiFeiCodecObjectClass: + * + * The #GstVaapiFeiCodecObject base class. + */ +struct _GstVaapiFeiCodecObjectClass +{ + /*< private >*/ + GstVaapiMiniObjectClass parent_class; + + GstVaapiFeiCodecObjectCreateFunc create; +}; + +G_GNUC_INTERNAL +const GstVaapiFeiCodecObjectClass * +gst_vaapi_fei_codec_object_get_class (GstVaapiFeiCodecObject * object) G_GNUC_CONST; + +G_GNUC_INTERNAL +GstVaapiFeiCodecObject * +gst_vaapi_fei_codec_object_new (const GstVaapiFeiCodecObjectClass * object_class, + GstVaapiFeiCodecBase * codec, gconstpointer param, guint param_size, + gconstpointer data, guint data_size, guint flags); + + +/* ------------------------------------------------------------------------- */ +/* --- MB Code Buffer --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENC_FEI_MB_CODE_CAST(obj) \ + ((GstVaapiEncFeiMbCode *) (obj)) +/** + * GstVaapiEncFeiMbCode: + * + * A #GstVaapiFeiCodecObject holding a mb code buffer. + */ +struct _GstVaapiEncFeiMbCode +{ + /*< private >*/ + GstVaapiFeiCodecObject parent_instance; +}; + +/* ------------------------------------------------------------------------- */ +/* --- MV Buffer --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENC_FEI_NEW_MV_CAST(obj) \ + ((GstVaapiEncFeiMv *) (obj)) +/** + * GstVaapiEncFeiMv: + * + * A #GstVaapiFeiCodecObject holding a mv buffer. + */ +struct _GstVaapiEncFeiMv +{ + /*< private >*/ + GstVaapiFeiCodecObject parent_instance; +}; + +/* ------------------------------------------------------------------------- */ +/* --- MV Predictor Buffer --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENC_FEI_NEW_MV_PREDICTOR_CAST(obj) \ + ((GstVaapiEncFeiMvPredictor *) (obj)) +/** + * GstVaapiEncFeiMvPredictor: + * + * A #GstVaapiFeiCodecObject holding a mv predictor buffer. + */ +struct _GstVaapiEncFeiMvPredictor +{ + /*< private >*/ + GstVaapiFeiCodecObject parent_instance; +}; + + +/* ------------------------------------------------------------------------- */ +/* --- MB Control Buffer --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENC_FEI_NEW_MB_CONTROL_CAST(obj) \ + ((GstVaapiEncFeiMbControl *) (obj)) +/** + * GstVaapiEncFeiMbControl: + * + * A #GstVaapiFeiCodecObject holding a mb control buffer. + */ +struct _GstVaapiEncFeiMbControl +{ + /*< private >*/ + GstVaapiFeiCodecObject parent_instance; +}; + + +/* ------------------------------------------------------------------------- */ +/* --- QP Buffer --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENC_FEI_NEW_QP_CAST(obj) \ + ((GstVaapiEncFeiQp *) (obj)) +/** + * GstVaapiEncFeiQp: + * + * A #GstVaapiFeiCodecObject holding a qp buffer. + */ +struct _GstVaapiEncFeiQp +{ + /*< private >*/ + GstVaapiFeiCodecObject parent_instance; +}; + + +/* ------------------------------------------------------------------------- */ +/* --- Distortion Buffer --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENC_FEI_NEW_DISTORTION_CAST(obj) \ + ((GstVaapiEncFeiDistortion *) (obj)) +/** + * GstVaapiEncFeiDistortion: + * + * A #GstVaapiFeiCodecObject holding a distortion buffer. + */ +struct _GstVaapiEncFeiDistortion +{ + /*< private >*/ + GstVaapiFeiCodecObject parent_instance; +}; + + +/* ------------------------------------------------------------------------- */ +/* --- Helpers to create fei objects --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_FEI_CODEC_DEFINE_TYPE(type, prefix) \ +G_GNUC_INTERNAL \ +void \ +G_PASTE (prefix, _destroy) (type *); \ + \ +G_GNUC_INTERNAL \ +gboolean \ +G_PASTE (prefix, _create) (type *, \ + const GstVaapiFeiCodecObjectConstructorArgs * args); \ + \ +static const GstVaapiFeiCodecObjectClass G_PASTE (type, Class) = { \ + .parent_class = { \ + .size = sizeof (type), \ + .finalize = (GstVaapiFeiCodecObjectDestroyFunc) \ + G_PASTE (prefix, _destroy) \ + }, \ + .create = (GstVaapiFeiCodecObjectCreateFunc) \ + G_PASTE (prefix, _create), \ +} + +/* GstVaapiEncFeiMiscParam */ +#define GST_VAAPI_ENC_FEI_MISC_PARAM_NEW(codec, encoder) \ + gst_vaapi_enc_misc_param_new (GST_VAAPI_ENCODER_CAST (encoder), \ + VAEncMiscParameterTypeFEIFrameControl, \ + sizeof (G_PASTE (VAEncMiscParameterFEIFrameControl, codec))) + +G_END_DECLS + +#endif /* GST_VAAPI_FEI_OBJECTS_H */ From d5542fa8c0c33ff54968f4b46632920a52fd91cb Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 15:49:21 -0700 Subject: [PATCH 2917/3781] FEI: libs: Add fei codec objects to surface proxy Add fei codec objects to surface proxy since handling the fei buffers(codec objects here) external to gstvaapisurfaceproxy will make the code complicated. Especially considering the behavior of encoder where the input frame order from upstream and output frame order to the downstream are not sequential. Other contributors: Zhong, Xiaoxia xiaominc Leilei Li, Jing B https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 --- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 271 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 44 +++ .../gst/vaapi/gstvaapisurfaceproxy_priv.h | 9 + 3 files changed, 324 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 2b6e1d522d..fc72e35873 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -50,6 +50,27 @@ gst_vaapi_surface_proxy_finalize (GstVaapiSurfaceProxy * proxy) /* Notify the user function that the object is now destroyed */ if (proxy->destroy_func) proxy->destroy_func (proxy->destroy_data); + +#if USE_H264_FEI_ENCODER + if (proxy->mvpred) + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mvpred, NULL); + if (proxy->mbcntrl) + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mbcntrl, NULL); + if (proxy->qp) + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->qp, NULL); + if (proxy->mbcode) + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mbcode, NULL); + if (proxy->mv) + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mv, NULL); + if (proxy->dist) + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->dist, NULL); +#endif } static inline const GstVaapiMiniObjectClass * @@ -69,6 +90,14 @@ gst_vaapi_surface_proxy_init_properties (GstVaapiSurfaceProxy * proxy) proxy->timestamp = GST_CLOCK_TIME_NONE; proxy->duration = GST_CLOCK_TIME_NONE; proxy->has_crop_rect = FALSE; +#if USE_H264_FEI_ENCODER + proxy->mvpred = NULL; + proxy->mbcntrl = NULL; + proxy->qp = NULL; + proxy->mbcode = NULL; + proxy->mv = NULL; + proxy->dist = NULL; +#endif } /** @@ -189,6 +218,52 @@ gst_vaapi_surface_proxy_copy (GstVaapiSurfaceProxy * proxy) copy->has_crop_rect = proxy->has_crop_rect; if (copy->has_crop_rect) copy->crop_rect = proxy->crop_rect; + +#if USE_H264_FEI_ENCODER + + if (proxy->mv) + copy->mv = (GstVaapiEncFeiMv *) + gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT (proxy->mv)); + else + copy->mv = NULL; + + if (proxy->mbcode) + copy->mbcode = (GstVaapiEncFeiMbCode *) + gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT + (proxy->mbcode)); + else + copy->mbcode = NULL; + + if (proxy->mvpred) + copy->mvpred = (GstVaapiEncFeiMvPredictor *) + gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT + (proxy->mvpred)); + else + copy->mvpred = NULL; + + if (proxy->qp) + copy->qp = (GstVaapiEncFeiQp *) + gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT (proxy->qp)); + else + copy->qp = NULL; + + if (proxy->mbcntrl) + copy->mbcntrl = (GstVaapiEncFeiMbControl *) + gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT + (proxy->mbcntrl)); + else + copy->mbcntrl = NULL; + + if (proxy->dist) + copy->dist = (GstVaapiEncFeiDistortion *) + gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT + (proxy->dist)); + else + copy->dist = NULL; + + +#endif + return copy; } @@ -402,3 +477,199 @@ gst_vaapi_surface_proxy_set_crop_rect (GstVaapiSurfaceProxy * proxy, if (proxy->has_crop_rect) proxy->crop_rect = *crop_rect; } + +#if USE_H264_FEI_ENCODER + +/** + * gst_vaapi_surface_proxy_get_fei_mb_code: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the #GstVaapiEncFeiMbCode stored in the @proxy + * + * Return value: the #GstVaapiEncFeiMbcode, or %NULL if none was + * associated with the surface proxy + */ +GstVaapiEncFeiMbCode * +gst_vaapi_surface_proxy_get_fei_mb_code (GstVaapiSurfaceProxy * proxy) +{ + g_return_val_if_fail (proxy != NULL, NULL); + return proxy->mbcode; +} + +/** + * gst_vaapi_surface_proxy_get_fei_mv: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the #GstVaapiEncFeiMv stored in the @proxy + * + * Return value: the #GstVaapiEncFeiMv, or %NULL if none was + * associated with the surface proxy + */ +GstVaapiEncFeiMv * +gst_vaapi_surface_proxy_get_fei_mv (GstVaapiSurfaceProxy * proxy) +{ + g_return_val_if_fail (proxy != NULL, NULL); + return proxy->mv; +} + +/** + * gst_vaapi_surface_proxy_get_fei_distortion: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the #GstVaapiEncFeiDistortion stored in the @proxy + * + * Return value: the #GstVaapiEncFeiDistortion, or %NULL if none was + * associated with the surface proxy + */ +GstVaapiEncFeiDistortion * +gst_vaapi_surface_proxy_get_fei_distortion (GstVaapiSurfaceProxy * proxy) +{ + g_return_val_if_fail (proxy != NULL, NULL); + return proxy->dist; +} + +/** + * gst_vaapi_surface_proxy_get_fei_qp: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the #GstVaapiEncFeiQp stored in the @proxy + * + * Return value: the #GstVaapiEncFeiQp, or %NULL if none was + * associated with the surface proxy + */ +GstVaapiEncFeiQp * +gst_vaapi_surface_proxy_get_fei_qp (GstVaapiSurfaceProxy * proxy) +{ + g_return_val_if_fail (proxy != NULL, NULL); + return proxy->qp; +} + +/** + * gst_vaapi_surface_proxy_get_fei_mv_predictor: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the #GstVaapiEncFeiMvPredictor stored in the @proxy + * + * Return value: the #GstVaapiEncFeiMvPredictor, or %NULL if none was + * associated with the surface proxy + */ +GstVaapiEncFeiMvPredictor * +gst_vaapi_surface_proxy_get_fei_mv_predictor (GstVaapiSurfaceProxy * proxy) +{ + g_return_val_if_fail (proxy != NULL, NULL); + return proxy->mvpred; +} + +/** + * gst_vaapi_surface_proxy_get_fei_mb_control: + * @proxy: a #GstVaapiSurfaceProxy + * + * Returns the #GstVaapiEncFeiMbControl stored in the @proxy + * + * Return value: the #GstVaapiEncFeiMbControl, or %NULL if none was + * associated with the surface proxy + */ +GstVaapiEncFeiMbControl * +gst_vaapi_surface_proxy_get_fei_mb_control (GstVaapiSurfaceProxy * proxy) +{ + g_return_val_if_fail (proxy != NULL, NULL); + return proxy->mbcntrl; +} + +/** + * gst_vaapi_surface_proxy_set_fei_mb_code: + * @proxy: #GstVaapiSurfaceProxy + * @mbcode: the #GstVaapiEncFeiMbCode to be stored in @proxy + * + * Associates the @mbcode with the @proxy + */ +void +gst_vaapi_surface_proxy_set_fei_mb_code (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiMbCode * mbcode) +{ + g_return_if_fail (proxy != NULL); + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mbcode, (GstVaapiFeiCodecObject *) mbcode); +} + +/** + * gst_vaapi_surface_proxy_set_fei_mv: + * @proxy: #GstVaapiSurfaceProxy + * @mv: the #GstVaapiEncFeiMv to be stored in @proxy + * + * Associates the @mv with the @proxy + */ +void +gst_vaapi_surface_proxy_set_fei_mv (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiMv * mv) +{ + g_return_if_fail (proxy != NULL); + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mv, (GstVaapiFeiCodecObject *) mv); +} + +/** + * gst_vaapi_surface_proxy_set_fei_distortion: + * @proxy: #GstVaapiSurfaceProxy + * @dist: the #GstVaapiEncFeiDistortion to be stored in @proxy + * + * Associates the @dist with the @proxy + */ +void +gst_vaapi_surface_proxy_set_fei_distortion (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiDistortion * dist) +{ + g_return_if_fail (proxy != NULL); + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->dist, (GstVaapiFeiCodecObject *) dist); +} + +/** + * gst_vaapi_surface_proxy_set_fei_qp: + * @proxy: #GstVaapiSurfaceProxy + * @qp: the #GstVaapiEncFeiQp to be stored in @proxy + * + * Associates the @qp with the @proxy + */ +void +gst_vaapi_surface_proxy_set_fei_qp (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiQp * qp) +{ + g_return_if_fail (proxy != NULL); + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->qp, (GstVaapiFeiCodecObject *) qp); +} + +/** + * gst_vaapi_surface_proxy_set_fei_mv_predictor: + * @proxy: #GstVaapiSurfaceProxy + * @mvpred: the #GstVaapiEncFeiMvPredictor to be stored in @proxy + * + * Associates the @mvpred with the @proxy + */ +void +gst_vaapi_surface_proxy_set_fei_mv_predictor (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiMvPredictor * mvpred) +{ + g_return_if_fail (proxy != NULL); + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mvpred, (GstVaapiFeiCodecObject *) mvpred); +} + +/** + * gst_vaapi_surface_proxy_set_fei_mb_control: + * @proxy: #GstVaapiSurfaceProxy + * @mbcntrl: the #GstVaapiEncFeiMbControl to be stored in @proxy + * + * Associates the @mbcntrl with the @proxy + */ +void +gst_vaapi_surface_proxy_set_fei_mb_control (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiMbControl * mbcntrl) +{ + g_return_if_fail (proxy != NULL); + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mbcntrl, (GstVaapiFeiCodecObject *) mbcntrl); +} + +#endif diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 1dc218c45d..5f6c16e584 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -28,6 +28,10 @@ #include #include +#if USE_H264_FEI_ENCODER +#include +#endif + G_BEGIN_DECLS /** @@ -152,6 +156,46 @@ void gst_vaapi_surface_proxy_set_crop_rect (GstVaapiSurfaceProxy * proxy, const GstVaapiRectangle * crop_rect); +#if USE_H264_FEI_ENCODER + +GstVaapiEncFeiMbCode * +gst_vaapi_surface_proxy_get_fei_mb_code (GstVaapiSurfaceProxy * proxy); + +GstVaapiEncFeiMv * +gst_vaapi_surface_proxy_get_fei_mv (GstVaapiSurfaceProxy * proxy); + +GstVaapiEncFeiDistortion * +gst_vaapi_surface_proxy_get_fei_distortion (GstVaapiSurfaceProxy * proxy); + +GstVaapiEncFeiQp * +gst_vaapi_surface_proxy_get_fei_qp (GstVaapiSurfaceProxy * proxy); + +GstVaapiEncFeiMvPredictor * +gst_vaapi_surface_proxy_get_fei_mv_predictor (GstVaapiSurfaceProxy * proxy); + +GstVaapiEncFeiMbControl * +gst_vaapi_surface_proxy_get_fei_mb_control (GstVaapiSurfaceProxy * proxy); + +void +gst_vaapi_surface_proxy_set_fei_mb_code (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiMbCode *mbcode); +void +gst_vaapi_surface_proxy_set_fei_mv (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiMv *mv); +void +gst_vaapi_surface_proxy_set_fei_distortion (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiDistortion *dist); +void +gst_vaapi_surface_proxy_set_fei_qp (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiQp *mbcode); +void +gst_vaapi_surface_proxy_set_fei_mv_predictor (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiMvPredictor *mvpred); +void +gst_vaapi_surface_proxy_set_fei_mb_control (GstVaapiSurfaceProxy * proxy, + GstVaapiEncFeiMbControl *mbcntrl); +#endif + G_END_DECLS #endif /* GST_VAAPI_SURFACE_PROXY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index d3bc7abc02..1540c7cb46 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -48,6 +48,15 @@ struct _GstVaapiSurfaceProxy gpointer destroy_data; GstVaapiRectangle crop_rect; guint has_crop_rect:1; + +#if USE_H264_FEI_ENCODER + GstVaapiEncFeiMvPredictor *mvpred; + GstVaapiEncFeiMbControl *mbcntrl; + GstVaapiEncFeiQp *qp; + GstVaapiEncFeiMbCode *mbcode; + GstVaapiEncFeiMv *mv; + GstVaapiEncFeiDistortion *dist; +#endif }; #define GST_VAAPI_SURFACE_PROXY_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS From 132eacde7981eb43219c9492205c35bb4fbb776c Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 16:05:13 -0700 Subject: [PATCH 2918/3781] FEI: libs: Add fei codec objects in codedbufferproxy MbCode, MV and Distortion buffers (fei codec objects) can be treated as output of different fei modes based user request. For eg: MbCode and MV are the output of ENC only. MbCode, MV and Dist can be dumped as output in ENC_PAK mode for analysis purpose. So treating them as a part of CodedBufferProxy too. Here we avoided Qp, MbControl and MvPredictor codec objects since there is no practical use case of treating them as "output buffers". Other contributors: Zhong, Xiaoxia xiaominc Leilei Li, Jing B https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 --- gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c | 119 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h | 27 ++++ .../gst/vaapi/gstvaapicodedbufferproxy_priv.h | 10 ++ 3 files changed, 156 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c index d5c42828f3..7e56f17ee2 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c @@ -54,6 +54,19 @@ coded_buffer_proxy_finalize (GstVaapiCodedBufferProxy * proxy) /* Notify the user function that the object is now destroyed */ if (proxy->destroy_func) proxy->destroy_func (proxy->destroy_data); + +#if USE_H264_FEI_ENCODER + if (proxy->mbcode) + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mbcode, NULL); + if (proxy->mv) + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mv, NULL); + if (proxy->dist) + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->dist, NULL); +#endif + } static inline const GstVaapiMiniObjectClass * @@ -95,6 +108,11 @@ gst_vaapi_coded_buffer_proxy_new_from_pool (GstVaapiCodedBufferPool * pool) proxy->user_data_destroy = NULL; proxy->pool = gst_vaapi_video_pool_ref (pool); proxy->buffer = gst_vaapi_video_pool_get_object (proxy->pool); +#if USE_H264_FEI_ENCODER + proxy->mv = NULL; + proxy->mbcode = NULL; + proxy->dist = NULL; +#endif if (!proxy->buffer) goto error; gst_vaapi_object_ref (proxy->buffer); @@ -254,3 +272,104 @@ gst_vaapi_coded_buffer_proxy_set_user_data (GstVaapiCodedBufferProxy * proxy, coded_buffer_proxy_set_user_data (proxy, user_data, destroy_func); } + +#if USE_H264_FEI_ENCODER + +/** + * gst_vaapi_coded_buffer_proxy_get_fei_mb_code: + * @proxy: a #GstVaapiCodedBufferProxy + * + * Returns the #GstVaapiEncFeiMbCode stored in the @proxy + * + * Return value: the #GstVaapiEncFeiMbcode, or %NULL if none was + * associated with the surface proxy + */ +GstVaapiEncFeiMbCode * +gst_vaapi_coded_buffer_proxy_get_fei_mbcode (GstVaapiCodedBufferProxy * proxy) +{ + g_return_val_if_fail (proxy != NULL, 0); + return proxy->mbcode; +} + +/** + * gst_vaapi_coded_buffer_proxy_get_fei_mv: + * @proxy: a #GstVaapiCodedBufferProxy + * + * Returns the #GstVaapiEncFeiMv stored in the @proxy + * + * Return value: the #GstVaapiEncFeiMv, or %NULL if none was + * associated with the surface proxy + */ +GstVaapiEncFeiMv * +gst_vaapi_coded_buffer_proxy_get_fei_mv (GstVaapiCodedBufferProxy * proxy) +{ + g_return_val_if_fail (proxy != NULL, 0); + return proxy->mv; +} + +/** + * gst_vaapi_coded_buffer_proxy_get_fei_distortion: + * @proxy: a #GstVaapiCodedBufferProxy + * + * Returns the #GstVaapiEncFeiDistortion stored in the @proxy + * + * Return value: the #GstVaapiEncFeiDistortion, or %NULL if none was + * associated with the surface proxy + */ +GstVaapiEncFeiDistortion * +gst_vaapi_coded_buffer_proxy_get_fei_distortion (GstVaapiCodedBufferProxy * + proxy) +{ + g_return_val_if_fail (proxy != NULL, 0); + return proxy->dist; +} + +/** + * gst_vaapi_coded_buffer_proxy_set_fei_mb_code: + * @proxy: #GstVaapiCodedBufferProxy + * @mbcode: the #GstVaapiEncFeiMbCode to be stored in @proxy + * + * Associates the @mbcode with the @proxy + */ +void +gst_vaapi_coded_buffer_proxy_set_fei_mb_code (GstVaapiCodedBufferProxy * proxy, + GstVaapiEncFeiMbCode * mbcode) +{ + g_return_if_fail (proxy != NULL); + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mbcode, (GstVaapiFeiCodecObject *) mbcode); +} + +/** + * gst_vaapi_coded_buffer_proxy_set_fei_mv: + * @proxy: #GstVaapiCodedBufferProxy + * @mv: the #GstVaapiEncFeiMv to be stored in @proxy + * + * Associates the @mv with the @proxy + */ +void +gst_vaapi_coded_buffer_proxy_set_fei_mv (GstVaapiCodedBufferProxy * proxy, + GstVaapiEncFeiMv * mv) +{ + g_return_if_fail (proxy != NULL); + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->mv, (GstVaapiFeiCodecObject *) mv); +} + +/** + * gst_vaapi_coded_buffer_proxy_set_fei_distortion: + * @proxy: #GstVaapiSurfaceProxy + * @dist: the #GstVaapiEncFeiDistortion to be stored in @proxy + * + * Associates the @dist with the @proxy + */ +void +gst_vaapi_coded_buffer_proxy_set_fei_distortion (GstVaapiCodedBufferProxy * + proxy, GstVaapiEncFeiDistortion * dist) +{ + g_return_if_fail (proxy != NULL); + gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & + proxy->dist, (GstVaapiFeiCodecObject *) dist); +} + +#endif diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h index 4968c63075..4514db92ff 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h @@ -26,6 +26,10 @@ #include #include +#if USE_H264_FEI_ENCODER +#include +#endif + G_BEGIN_DECLS /** @@ -77,6 +81,29 @@ void gst_vaapi_coded_buffer_proxy_set_user_data (GstVaapiCodedBufferProxy * proxy, gpointer user_data, GDestroyNotify destroy_func); +#if USE_H264_FEI_ENCODER + +GstVaapiEncFeiMbCode * +gst_vaapi_coded_buffer_proxy_get_fei_mbcode (GstVaapiCodedBufferProxy * proxy); + +GstVaapiEncFeiMv * +gst_vaapi_coded_buffer_proxy_get_fei_mv (GstVaapiCodedBufferProxy * proxy); + +GstVaapiEncFeiDistortion * +gst_vaapi_coded_buffer_proxy_get_fei_distortion (GstVaapiCodedBufferProxy * proxy); + +void +gst_vaapi_coded_buffer_proxy_set_fei_mb_code (GstVaapiCodedBufferProxy * proxy, + GstVaapiEncFeiMbCode *mbcode); +void +gst_vaapi_coded_buffer_proxy_set_fei_mv (GstVaapiCodedBufferProxy * proxy, + GstVaapiEncFeiMv *mv); +void +gst_vaapi_coded_buffer_proxy_set_fei_distortion (GstVaapiCodedBufferProxy * proxy, + GstVaapiEncFeiDistortion *dist); + +#endif + G_END_DECLS #endif /* GST_VAAPI_CODED_BUFFER_PROXY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h index 6feb8f9c82..bc91a9ccb5 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h @@ -26,6 +26,10 @@ #include "gstvaapicodedbuffer_priv.h" #include "gstvaapiminiobject.h" +#if USE_H264_FEI_ENCODER +#include +#endif + G_BEGIN_DECLS #define GST_VAAPI_CODED_BUFFER_PROXY(proxy) \ @@ -42,6 +46,12 @@ struct _GstVaapiCodedBufferProxy gpointer destroy_data; GDestroyNotify user_data_destroy; gpointer user_data; + +#if USE_H264_FEI_ENCODER + GstVaapiEncFeiMbCode *mbcode; + GstVaapiEncFeiMv *mv; + GstVaapiEncFeiDistortion *dist; +#endif }; /** From de2e4cd9bcec1197fc9a2341caf94db53e1546f1 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 17:54:27 -0700 Subject: [PATCH 2919/3781] FEI: libs: Add fei codec objects to GstVaapiEncPicture All the codec objects(vaapi buffers) supposed to be submited in vaRenderPicutre are associated with a GstVaapiEncPicture for each frame, follow the same design for FEI too. https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 --- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 9 +++++++++ gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index 02149d239e..ef72b5906c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -351,6 +351,15 @@ gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture) gst_vaapi_codec_object_replace (&picture->sequence, NULL); +#if USE_H264_FEI_ENCODER + gst_vaapi_codec_object_replace (&picture->mvpred, NULL); + gst_vaapi_codec_object_replace (&picture->mbcntrl, NULL); + gst_vaapi_codec_object_replace (&picture->qp, NULL); + gst_vaapi_codec_object_replace (&picture->mbcode, NULL); + gst_vaapi_codec_object_replace (&picture->mv, NULL); + gst_vaapi_codec_object_replace (&picture->dist, NULL); +#endif + gst_vaapi_surface_proxy_replace (&picture->proxy, NULL); picture->surface_id = VA_INVALID_ID; picture->surface = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index 8ca594679a..a4179ff06d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -27,6 +27,10 @@ #include #include +#if USE_H264_FEI_ENCODER +#include +#endif + G_BEGIN_DECLS typedef struct _GstVaapiEncPicture GstVaapiEncPicture; @@ -261,6 +265,14 @@ struct _GstVaapiEncPicture GstClockTime pts; guint frame_num; guint poc; +#if USE_H264_FEI_ENCODER + GstVaapiEncFeiMbControl *mbcntrl; + GstVaapiEncFeiMvPredictor *mvpred; + GstVaapiEncFeiQp *qp; + GstVaapiEncFeiMbCode *mbcode; + GstVaapiEncFeiMv *mv; + GstVaapiEncFeiDistortion *dist; +#endif }; G_GNUC_INTERNAL From 7e0d5b934bd72be87a741a5bf98bbb6dc6906a99 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 18:19:06 -0700 Subject: [PATCH 2920/3781] FEI: libs: Add FEI encoder Adding FEI encoder to core lib. The code is splitted into three session: 1: gstvaapiencoder_h264_fei.{h,c} This is the replica of gstvaapiencoder_h264.{c,h} but with FEI. All the modes ENC, PAK and ENC_PAK are running based the code in these files. 2: gstvaapifeienc_h264.{h,c} Abstract implementation intended for ENC (only VME) operation. 3: gstvaapifeipak_h264.{h,c} Abstrct implementation intended for PAK (only the PAK module) Right now ENC_PAK, ENC and PAK are running based on code in gstvaapiencoder_h264_fei.{h,c}. The abstract implementations in gstvaapifeienc_h264.{h,c} and gstvaapifeipak_h264.{h,c} are needed if user request for ENC+PAK mode operation. ENC+PAK: Here we need to invoke two sequence of vaBeginPicture/vaRenderPicutre/vaEndPicture for each frame, first for the ENC only and the second for PAK only. Each mode associated with separate context ,but same pool of surfaces are shared between the modes. This is more useful once we have custom BRC algorithms. Other Contributors: Wang, Yi Leilei Zhong, Xiaoxia xiaominc Li, Jing B https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 --- gst-libs/gst/vaapi/Makefile.am | 10 +- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 4317 +++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h | 112 + gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 2264 +++++++++ gst-libs/gst/vaapi/gstvaapifeienc_h264.h | 121 + gst-libs/gst/vaapi/gstvaapifeipak_h264.c | 1892 ++++++++ gst-libs/gst/vaapi/gstvaapifeipak_h264.h | 94 + 7 files changed, 8808 insertions(+), 2 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c create mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h create mode 100644 gst-libs/gst/vaapi/gstvaapifeienc_h264.c create mode 100644 gst-libs/gst/vaapi/gstvaapifeienc_h264.h create mode 100644 gst-libs/gst/vaapi/gstvaapifeipak_h264.c create mode 100644 gst-libs/gst/vaapi/gstvaapifeipak_h264.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 353eae9207..b29adf95c4 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -240,14 +240,20 @@ endif libgstvaapi_h264feienc_source_c = \ gstvaapifeiutils_h264.c \ gstvaapifei_objects.c \ + gstvaapifeienc_h264.c \ + gstvaapifeipak_h264.c \ + gstvaapiencoder_h264_fei.c \ $(NULL) libgstvaapi_h264feienc_source_h = \ gstvaapifeiutils_h264.h \ gstvaapifei_objects.h \ + gstvaapifeienc_h264.h \ + gstvaapifeipak_h264.h \ + gstvaapiencoder_h264_fei.h \ $(NULL) libgstvaapi_h264feienc_source_priv_h = \ - gstvaapifei_objects_priv.h \ - $(NULL) + gstvaapifei_objects_priv.h \ + $(NULL) if USE_H264_FEI_ENCODER libgstvaapi_source_c += $(libgstvaapi_h264feienc_source_c) libgstvaapi_source_h += $(libgstvaapi_h264feienc_source_h) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c new file mode 100644 index 0000000000..a2ce197f34 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -0,0 +1,4317 @@ +/* + * gstvaapiencoder_h264_fei.c - H.264 FEI encoder + * + * Copyright (C) 2016-2017 Intel Corporation + * Author: Yi A Wang + * Author: Sreerenj Balachandran + * + * 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 + */ + +/* GValueArray has deprecated without providing an alternative in glib >= 2.32 + * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 + */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#include "sysdeps.h" +#include +#include +#include +#include +#include "gstvaapicompat.h" +#include "gstvaapiencoder_priv.h" +#include "gstvaapiutils_h264_priv.h" +#include "gstvaapicodedbufferproxy_priv.h" +#include "gstvaapisurfaceproxy_priv.h" +#include "gstvaapisurface.h" +#include "gstvaapifeiutils_h264.h" +#include "gstvaapiencoder_h264_fei.h" +#include "gstvaapifeienc_h264.h" +#include "gstvaapifeipak_h264.h" +#include "gstvaapiutils.h" +#include "gstvaapiutils_core.h" +#include "gstvaapifei_objects_priv.h" +#define DEBUG 1 +#include "gstvaapidebug.h" + +GPtrArray *gst_vaapi_encoder_h264_fei_get_default_properties (void); +static gboolean +gst_vaapi_encoder_h264_fei_ensure_secondary_context (GstVaapiEncoder * + base_encoder); + +/* Define the maximum number of views supported */ +#define MAX_NUM_VIEWS 10 + +/* Define the maximum value for view-id */ +#define MAX_VIEW_ID 1023 + +/* Define the maximum IDR period */ +#define MAX_IDR_PERIOD 512 + +/* Default CPB length (in milliseconds) */ +#define DEFAULT_CPB_LENGTH 1500 + +/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */ +#define SX_CPB_SIZE 4 + +/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ +#define SX_BITRATE 6 + +/* 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) | \ + GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) + +/* Supported set of tuning options, within this implementation */ +#define SUPPORTED_TUNE_OPTIONS \ + (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \ + GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION) | \ + GST_VAAPI_ENCODER_TUNE_MASK (LOW_POWER)) + +/* Supported set of VA packed headers, within this implementation */ +#define SUPPORTED_PACKED_HEADERS \ + (VA_ENC_PACKED_HEADER_SEQUENCE | \ + VA_ENC_PACKED_HEADER_PICTURE | \ + VA_ENC_PACKED_HEADER_SLICE | \ + VA_ENC_PACKED_HEADER_RAW_DATA | \ + VA_ENC_PACKED_HEADER_MISC) + +#define GST_H264_NAL_REF_IDC_NONE 0 +#define GST_H264_NAL_REF_IDC_LOW 1 +#define GST_H264_NAL_REF_IDC_MEDIUM 2 +#define GST_H264_NAL_REF_IDC_HIGH 3 + +/* only for internal usage, values won't be equal to actual payload type */ +typedef enum +{ + GST_VAAPI_H264_SEI_UNKNOWN = 0, + GST_VAAPI_H264_SEI_BUF_PERIOD = (1 << 0), + GST_VAAPI_H264_SEI_PIC_TIMING = (1 << 1) +} GstVaapiH264SeiPayloadType; + +typedef struct +{ + GstVaapiSurfaceProxy *pic; + guint poc; + guint frame_num; +} GstVaapiEncoderH264FeiRef; + +typedef enum +{ + GST_VAAPI_ENC_H264_REORD_NONE = 0, + GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1, + GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2 +} GstVaapiEncH264ReorderState; + +typedef struct _GstVaapiH264ViewRefPool +{ + GQueue ref_list; + guint max_ref_frames; + guint max_reflist0_count; + guint max_reflist1_count; +} GstVaapiH264ViewRefPool; + +typedef struct _GstVaapiH264ViewReorderPool +{ + GQueue reorder_frame_list; + guint reorder_state; + guint frame_index; + guint frame_count; /* monotonically increasing with in every idr period */ + guint cur_frame_num; + guint cur_present_index; +} GstVaapiH264ViewReorderPool; + +static inline gboolean +_poc_greater_than (guint poc1, guint poc2, guint max_poc) +{ + return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2); +} + +/* Get slice_type value for H.264 specification */ +static guint8 +h264_get_slice_type (GstVaapiPictureType type) +{ + switch (type) { + case GST_VAAPI_PICTURE_TYPE_I: + return GST_H264_I_SLICE; + case GST_VAAPI_PICTURE_TYPE_P: + return GST_H264_P_SLICE; + case GST_VAAPI_PICTURE_TYPE_B: + return GST_H264_B_SLICE; + default: + break; + } + return -1; +} + +/* Get log2_max_frame_num value for H.264 specification */ +static guint +h264_get_log2_max_frame_num (guint num) +{ + guint ret = 0; + + while (num) { + ++ret; + num >>= 1; + } + if (ret <= 4) + ret = 4; + else if (ret > 10) + ret = 10; + /* must be greater than 4 */ + return ret; +} + +/* Determines the cpbBrNalFactor based on the supplied profile */ +static guint +h264_get_cpb_nal_factor (GstVaapiProfile profile) +{ + guint f; + + /* Table A-2 */ + switch (profile) { + case GST_VAAPI_PROFILE_H264_HIGH: + f = 1500; + break; + case GST_VAAPI_PROFILE_H264_HIGH10: + f = 3600; + break; + case GST_VAAPI_PROFILE_H264_HIGH_422: + case GST_VAAPI_PROFILE_H264_HIGH_444: + f = 4800; + break; + case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH: + case GST_VAAPI_PROFILE_H264_STEREO_HIGH: + f = 1500; /* H.10.2.1 (r) */ + break; + default: + f = 1200; + break; + } + return f; +} + +/* ------------------------------------------------------------------------- */ +/* --- H.264 Bitstream Writer --- */ +/* ------------------------------------------------------------------------- */ + +#define WRITE_UINT32(bs, val, nbits) do { \ + if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \ + GST_WARNING ("failed to write uint32, nbits: %d", nbits); \ + goto bs_error; \ + } \ + } while (0) + +#define WRITE_UE(bs, val) do { \ + if (!bs_write_ue (bs, val)) { \ + GST_WARNING ("failed to write ue(v)"); \ + goto bs_error; \ + } \ + } while (0) + +#define WRITE_SE(bs, val) do { \ + if (!bs_write_se (bs, val)) { \ + GST_WARNING ("failed to write se(v)"); \ + goto bs_error; \ + } \ + } while (0) + +/* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */ +static gboolean +bs_write_ue (GstBitWriter * bs, guint32 value) +{ + guint32 size_in_bits = 0; + guint32 tmp_value = ++value; + + while (tmp_value) { + ++size_in_bits; + tmp_value >>= 1; + } + if (size_in_bits > 1 + && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1)) + return FALSE; + if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits)) + return FALSE; + return TRUE; +} + +/* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */ +static gboolean +bs_write_se (GstBitWriter * bs, gint32 value) +{ + guint32 new_val; + + if (value <= 0) + new_val = -(value << 1); + else + new_val = (value << 1) - 1; + + if (!bs_write_ue (bs, new_val)) + return FALSE; + return TRUE; +} + +/* Write the NAL unit header */ +static gboolean +bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc, + guint32 nal_unit_type) +{ + WRITE_UINT32 (bs, 0, 1); + WRITE_UINT32 (bs, nal_ref_idc, 2); + WRITE_UINT32 (bs, nal_unit_type, 5); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write NAL unit header"); + return FALSE; + } +} + +/* Write the MVC NAL unit header extension */ +static gboolean +bs_write_nal_header_mvc_extension (GstBitWriter * bs, + GstVaapiEncPicture * picture, guint32 view_id) +{ + guint32 svc_extension_flag = 0; + guint32 non_idr_flag = 1; + guint32 priority_id = 0; + guint32 temporal_id = 0; + guint32 anchor_pic_flag = 0; + guint32 inter_view_flag = 0; + + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + non_idr_flag = 0; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_I) + anchor_pic_flag = 1; + /* svc_extension_flag == 0 for mvc stream */ + WRITE_UINT32 (bs, svc_extension_flag, 1); + + WRITE_UINT32 (bs, non_idr_flag, 1); + WRITE_UINT32 (bs, priority_id, 6); + WRITE_UINT32 (bs, view_id, 10); + WRITE_UINT32 (bs, temporal_id, 3); + WRITE_UINT32 (bs, anchor_pic_flag, 1); + WRITE_UINT32 (bs, inter_view_flag, 1); + WRITE_UINT32 (bs, 1, 1); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write NAL unit header"); + return FALSE; + } +} + +/* Write the NAL unit trailing bits */ +static gboolean +bs_write_trailing_bits (GstBitWriter * bs) +{ + if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1)) + goto bs_error; + gst_bit_writer_align_bytes_unchecked (bs, 0); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write NAL unit trailing bits"); + return FALSE; + } +} + +/* Write an SPS NAL unit */ +static gboolean +bs_write_sps_data (GstBitWriter * bs, + const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, + const VAEncMiscParameterHRD * hrd_params) +{ + guint8 profile_idc; + guint32 constraint_set0_flag, constraint_set1_flag; + guint32 constraint_set2_flag, constraint_set3_flag; + guint32 gaps_in_frame_num_value_allowed_flag = 0; // ?? + gboolean nal_hrd_parameters_present_flag; + + guint32 b_qpprime_y_zero_transform_bypass = 0; + guint32 residual_color_transform_flag = 0; + guint32 pic_height_in_map_units = + (seq_param->seq_fields.bits.frame_mbs_only_flag ? + seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2); + guint32 mb_adaptive_frame_field = + !seq_param->seq_fields.bits.frame_mbs_only_flag; + guint32 i = 0; + + profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + constraint_set0_flag = /* A.2.1 (baseline profile constraints) */ + profile == GST_VAAPI_PROFILE_H264_BASELINE || + profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + constraint_set1_flag = /* A.2.2 (main profile constraints) */ + profile == GST_VAAPI_PROFILE_H264_MAIN || + profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + constraint_set2_flag = 0; + constraint_set3_flag = 0; + + /* profile_idc */ + WRITE_UINT32 (bs, profile_idc, 8); + /* constraint_set0_flag */ + WRITE_UINT32 (bs, constraint_set0_flag, 1); + /* constraint_set1_flag */ + WRITE_UINT32 (bs, constraint_set1_flag, 1); + /* constraint_set2_flag */ + WRITE_UINT32 (bs, constraint_set2_flag, 1); + /* constraint_set3_flag */ + WRITE_UINT32 (bs, constraint_set3_flag, 1); + /* reserved_zero_4bits */ + WRITE_UINT32 (bs, 0, 4); + /* level_idc */ + WRITE_UINT32 (bs, seq_param->level_idc, 8); + /* seq_parameter_set_id */ + WRITE_UE (bs, seq_param->seq_parameter_set_id); + + if (profile == GST_VAAPI_PROFILE_H264_HIGH || + profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH || + profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { + /* for high profile */ + /* chroma_format_idc = 1, 4:2:0 */ + WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc); + if (3 == seq_param->seq_fields.bits.chroma_format_idc) { + WRITE_UINT32 (bs, residual_color_transform_flag, 1); + } + /* bit_depth_luma_minus8 */ + WRITE_UE (bs, seq_param->bit_depth_luma_minus8); + /* bit_depth_chroma_minus8 */ + WRITE_UE (bs, seq_param->bit_depth_chroma_minus8); + /* b_qpprime_y_zero_transform_bypass */ + WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1); + + /* seq_scaling_matrix_present_flag */ + g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0); + WRITE_UINT32 (bs, + seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1); + +#if 0 + if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) { + for (i = 0; + i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); + i++) { + gst_bit_writer_put_bits_uint8 (bs, + seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1); + if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) { + g_assert (0); + /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */ + } + } + } +#endif + } + + /* log2_max_frame_num_minus4 */ + WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4); + /* pic_order_cnt_type */ + WRITE_UE (bs, seq_param->seq_fields.bits.pic_order_cnt_type); + + if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) { + /* log2_max_pic_order_cnt_lsb_minus4 */ + WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4); + } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { + g_assert (0 && "only POC type 0 is supported"); + WRITE_UINT32 (bs, + seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1); + WRITE_SE (bs, seq_param->offset_for_non_ref_pic); + WRITE_SE (bs, seq_param->offset_for_top_to_bottom_field); + WRITE_UE (bs, seq_param->num_ref_frames_in_pic_order_cnt_cycle); + for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) { + WRITE_SE (bs, seq_param->offset_for_ref_frame[i]); + } + } + + /* num_ref_frames */ + WRITE_UE (bs, seq_param->max_num_ref_frames); + /* gaps_in_frame_num_value_allowed_flag */ + WRITE_UINT32 (bs, gaps_in_frame_num_value_allowed_flag, 1); + + /* pic_width_in_mbs_minus1 */ + WRITE_UE (bs, seq_param->picture_width_in_mbs - 1); + /* pic_height_in_map_units_minus1 */ + WRITE_UE (bs, pic_height_in_map_units - 1); + /* frame_mbs_only_flag */ + WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1); + + if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs + g_assert (0 && "only progressive frames encoding is supported"); + WRITE_UINT32 (bs, mb_adaptive_frame_field, 1); + } + + /* direct_8x8_inference_flag */ + WRITE_UINT32 (bs, 0, 1); + /* frame_cropping_flag */ + WRITE_UINT32 (bs, seq_param->frame_cropping_flag, 1); + + if (seq_param->frame_cropping_flag) { + /* frame_crop_left_offset */ + WRITE_UE (bs, seq_param->frame_crop_left_offset); + /* frame_crop_right_offset */ + WRITE_UE (bs, seq_param->frame_crop_right_offset); + /* frame_crop_top_offset */ + WRITE_UE (bs, seq_param->frame_crop_top_offset); + /* frame_crop_bottom_offset */ + WRITE_UE (bs, seq_param->frame_crop_bottom_offset); + } + + /* vui_parameters_present_flag */ + WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1); + if (seq_param->vui_parameters_present_flag) { + /* aspect_ratio_info_present_flag */ + WRITE_UINT32 (bs, + seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1); + if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { + WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8); + if (seq_param->aspect_ratio_idc == 0xFF) { + WRITE_UINT32 (bs, seq_param->sar_width, 16); + WRITE_UINT32 (bs, seq_param->sar_height, 16); + } + } + + /* overscan_info_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* video_signal_type_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* chroma_loc_info_present_flag */ + WRITE_UINT32 (bs, 0, 1); + + /* timing_info_present_flag */ + WRITE_UINT32 (bs, seq_param->vui_fields.bits.timing_info_present_flag, 1); + if (seq_param->vui_fields.bits.timing_info_present_flag) { + WRITE_UINT32 (bs, seq_param->num_units_in_tick, 32); + WRITE_UINT32 (bs, seq_param->time_scale, 32); + WRITE_UINT32 (bs, 1, 1); /* fixed_frame_rate_flag */ + } + + /* nal_hrd_parameters_present_flag */ + nal_hrd_parameters_present_flag = seq_param->bits_per_second > 0; + WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1); + if (nal_hrd_parameters_present_flag) { + /* hrd_parameters */ + /* cpb_cnt_minus1 */ + WRITE_UE (bs, 0); + WRITE_UINT32 (bs, SX_BITRATE - 6, 4); /* bit_rate_scale */ + WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4); /* cpb_size_scale */ + + for (i = 0; i < 1; ++i) { + /* bit_rate_value_minus1[0] */ + WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1); + /* cpb_size_value_minus1[0] */ + WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1); + /* cbr_flag[0] */ + WRITE_UINT32 (bs, 1, 1); + } + /* initial_cpb_removal_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + /* cpb_removal_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + /* dpb_output_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + /* time_offset_length */ + WRITE_UINT32 (bs, 23, 5); + } + + /* vcl_hrd_parameters_present_flag */ + WRITE_UINT32 (bs, 0, 1); + + if (nal_hrd_parameters_present_flag + || 0 /*vcl_hrd_parameters_present_flag */ ) { + /* low_delay_hrd_flag */ + WRITE_UINT32 (bs, 0, 1); + } + /* pic_struct_present_flag */ + WRITE_UINT32 (bs, 1, 1); + /* bs_restriction_flag */ + WRITE_UINT32 (bs, 0, 1); + } + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SPS NAL unit"); + return FALSE; + } +} + +static gboolean +bs_write_sps (GstBitWriter * bs, + const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, + const VAEncMiscParameterHRD * hrd_params) +{ + if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) + return FALSE; + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + + return FALSE; +} + +static gboolean +bs_write_subset_sps (GstBitWriter * bs, + const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, + guint num_views, guint16 * view_ids, + const VAEncMiscParameterHRD * hrd_params) +{ + guint32 i, j, k; + + if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) + return FALSE; + + if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH || + profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH) { + guint32 num_views_minus1, num_level_values_signalled_minus1; + + num_views_minus1 = num_views - 1; + g_assert (num_views_minus1 < 1024); + + /* bit equal to one */ + WRITE_UINT32 (bs, 1, 1); + + WRITE_UE (bs, num_views_minus1); + + for (i = 0; i <= num_views_minus1; i++) + WRITE_UE (bs, view_ids[i]); + + for (i = 1; i <= num_views_minus1; i++) { + guint32 num_anchor_refs_l0 = 0; + guint32 num_anchor_refs_l1 = 0; + + WRITE_UE (bs, num_anchor_refs_l0); + for (j = 0; j < num_anchor_refs_l0; j++) + WRITE_UE (bs, 0); + + WRITE_UE (bs, num_anchor_refs_l1); + for (j = 0; j < num_anchor_refs_l1; j++) + WRITE_UE (bs, 0); + } + + for (i = 1; i <= num_views_minus1; i++) { + guint32 num_non_anchor_refs_l0 = 0; + guint32 num_non_anchor_refs_l1 = 0; + + WRITE_UE (bs, num_non_anchor_refs_l0); + for (j = 0; j < num_non_anchor_refs_l0; j++) + WRITE_UE (bs, 0); + + WRITE_UE (bs, num_non_anchor_refs_l1); + for (j = 0; j < num_non_anchor_refs_l1; j++) + WRITE_UE (bs, 0); + } + + /* num level values signalled minus1 */ + num_level_values_signalled_minus1 = 0; + g_assert (num_level_values_signalled_minus1 < 64); + WRITE_UE (bs, num_level_values_signalled_minus1); + + for (i = 0; i <= num_level_values_signalled_minus1; i++) { + guint16 num_applicable_ops_minus1 = 0; + g_assert (num_applicable_ops_minus1 < 1024); + + WRITE_UINT32 (bs, seq_param->level_idc, 8); + WRITE_UE (bs, num_applicable_ops_minus1); + + for (j = 0; j <= num_applicable_ops_minus1; j++) { + guint8 temporal_id = 0; + guint16 num_target_views_minus1 = 1; + + WRITE_UINT32 (bs, temporal_id, 3); + WRITE_UE (bs, num_target_views_minus1); + + for (k = 0; k <= num_target_views_minus1; k++) + WRITE_UE (bs, k); + + WRITE_UE (bs, num_views_minus1); + } + } + + /* mvc_vui_parameters_present_flag */ + WRITE_UINT32 (bs, 0, 1); + } + + /* additional_extension2_flag */ + WRITE_UINT32 (bs, 0, 1); + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write subset SPS NAL unit"); + return FALSE; + } + return FALSE; +} + +/* Write a PPS NAL unit */ +static gboolean +bs_write_pps (GstBitWriter * bs, + const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile) +{ + guint32 num_slice_groups_minus1 = 0; + guint32 pic_init_qs_minus26 = 0; + guint32 redundant_pic_cnt_present_flag = 0; + + /* pic_parameter_set_id */ + WRITE_UE (bs, pic_param->pic_parameter_set_id); + /* seq_parameter_set_id */ + WRITE_UE (bs, pic_param->seq_parameter_set_id); + /* entropy_coding_mode_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1); + /* pic_order_present_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_order_present_flag, 1); + /* slice_groups-1 */ + WRITE_UE (bs, num_slice_groups_minus1); + + if (num_slice_groups_minus1 > 0) { + /*FIXME*/ g_assert (0 && "unsupported arbitrary slice ordering (ASO)"); + } + WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1); + WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1); + WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1); + WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2); + /* pic_init_qp_minus26 */ + WRITE_SE (bs, pic_param->pic_init_qp - 26); + /* pic_init_qs_minus26 */ + WRITE_SE (bs, pic_init_qs_minus26); + /* chroma_qp_index_offset */ + WRITE_SE (bs, pic_param->chroma_qp_index_offset); + + WRITE_UINT32 (bs, + pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1); + WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1); + WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1); + + /* more_rbsp_data */ + if (profile == GST_VAAPI_PROFILE_H264_HIGH + || profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH + || profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { + WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1); + WRITE_UINT32 (bs, + pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1); + if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) { + g_assert (0 && "unsupported scaling lists"); + /* FIXME */ + /* + for (i = 0; i < + (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag)); + i++) { + gst_bit_writer_put_bits_uint8(bs, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1); + } + */ + } + WRITE_SE (bs, pic_param->second_chroma_qp_index_offset); + } + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write PPS NAL unit"); + return FALSE; + } +} + +/* ------------------------------------------------------------------------- */ +/* --- H.264 Encoder --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_ENCODER_H264_FEI_CAST(encoder) \ + ((GstVaapiEncoderH264Fei *)(encoder)) + +struct _GstVaapiEncoderH264Fei +{ + GstVaapiEncoder parent_instance; + GstVaapiFeiEncH264 *feienc; + GstVaapiFEIPakH264 *feipak; + + GstVaapiProfile profile; + GstVaapiLevelH264 level; + GstVaapiEntrypoint entrypoint; + VAConfigID va_config; + guint8 profile_idc; + VABufferID coded_buf; + guint8 max_profile_idc; + guint8 hw_max_profile_idc; + guint8 level_idc; + guint32 idr_period; + guint32 init_qp; + guint32 min_qp; + guint32 num_slices; + guint32 num_bframes; + guint32 mb_width; + guint32 mb_height; + gboolean use_cabac; + gboolean use_dct8x8; + GstClockTime cts_offset; + gboolean config_changed; + + /* frame, poc */ + guint32 max_frame_num; + guint32 log2_max_frame_num; + guint32 max_pic_order_cnt; + guint32 log2_max_pic_order_cnt; + guint32 idr_num; + guint8 pic_order_cnt_type; + guint8 delta_pic_order_always_zero_flag; + + GstBuffer *sps_data; + GstBuffer *subset_sps_data; + GstBuffer *pps_data; + + guint bitrate_bits; // bitrate (bits) + guint cpb_length; // length of CPB buffer (ms) + guint cpb_length_bits; // length of CPB buffer (bits) + guint num_ref_frames; + + /* MVC */ + gboolean is_mvc; + guint32 view_idx; /* View Order Index (VOIdx) */ + guint32 num_views; + guint16 view_ids[MAX_NUM_VIEWS]; + GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS]; + GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS]; + gpointer ref_pool_ptr; + /*Fei frame level control */ + gboolean is_fei_disabled; + gboolean is_stats_out_enabled; + guint search_window; + guint len_sp; + guint search_path; + guint ref_width; + guint ref_height; + guint submb_part_mask; + guint subpel_mode; + guint intra_part_mask; + guint intra_sad; + guint inter_sad; + guint num_mv_predictors_l0; + guint num_mv_predictors_l1; + guint adaptive_search; + guint multi_predL0; + guint multi_predL1; + guint fei_mode; + +}; + +/* Write a SEI buffering period payload */ +static gboolean +bs_write_sei_buf_period (GstBitWriter * bs, + GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture) +{ + guint initial_cpb_removal_delay = 0; + guint initial_cpb_removal_delay_offset = 0; + guint8 initial_cpb_removal_delay_length = 24; + + /* sequence_parameter_set_id */ + WRITE_UE (bs, encoder->view_idx); + /* NalHrdBpPresentFlag == TRUE */ + /* cpb_cnt_minus1 == 0 */ + + /* decoding should start when the CPB fullness reaches half of cpb size + * initial_cpb_remvoal_delay = (((cpb_length / 2) * 90000) / 1000) */ + initial_cpb_removal_delay = encoder->cpb_length * 45; + + /* initial_cpb_remvoal_dealy */ + WRITE_UINT32 (bs, initial_cpb_removal_delay, + initial_cpb_removal_delay_length); + + /* initial_cpb_removal_delay_offset */ + WRITE_UINT32 (bs, initial_cpb_removal_delay_offset, + initial_cpb_removal_delay_length); + + /* VclHrdBpPresentFlag == FALSE */ + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Buffering Period SEI message"); + return FALSE; + } +} + +/* Write a SEI picture timing payload */ +static gboolean +bs_write_sei_pic_timing (GstBitWriter * bs, + GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiH264ViewReorderPool *reorder_pool = NULL; + guint cpb_removal_delay; + guint dpb_output_delay; + guint8 cpb_removal_delay_length = 24; + guint8 dpb_output_delay_length = 24; + guint pic_struct = 0; + guint clock_timestamp_flag = 0; + + reorder_pool = &encoder->reorder_pools[encoder->view_idx]; + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + reorder_pool->frame_count = 0; + else + reorder_pool->frame_count++; + + /* clock-tick = no_units_in_tick/time_scale (C-1) + * time_scale = FPS_N * 2 (E.2.1) + * num_units_in_tick = FPS_D (E.2.1) + * frame_duration = clock-tick * 2 + * so removal time for one frame is 2 clock-ticks. + * but adding a tolerance of one frame duration, + * which is 2 more clock-ticks */ + cpb_removal_delay = (reorder_pool->frame_count * 2 + 2); + + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) + dpb_output_delay = 0; + else + dpb_output_delay = picture->poc - reorder_pool->frame_count * 2; + + /* CpbDpbDelaysPresentFlag == 1 */ + WRITE_UINT32 (bs, cpb_removal_delay, cpb_removal_delay_length); + WRITE_UINT32 (bs, dpb_output_delay, dpb_output_delay_length); + + /* pic_struct_present_flag == 1 */ + /* pic_struct */ + WRITE_UINT32 (bs, pic_struct, 4); + /* clock_timestamp_flag */ + WRITE_UINT32 (bs, clock_timestamp_flag, 1); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Picture Timing SEI message"); + return FALSE; + } +} + +/* Write a Slice NAL unit */ +static gboolean +bs_write_slice (GstBitWriter * bs, + const VAEncSliceParameterBufferH264 * slice_param, + GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture) +{ + const VAEncPictureParameterBufferH264 *const pic_param = picture->param; + guint32 field_pic_flag = 0; + guint32 ref_pic_list_modification_flag_l0 = 0; + guint32 ref_pic_list_modification_flag_l1 = 0; + guint32 no_output_of_prior_pics_flag = 0; + guint32 long_term_reference_flag = 0; + guint32 adaptive_ref_pic_marking_mode_flag = 0; + + /* first_mb_in_slice */ + WRITE_UE (bs, slice_param->macroblock_address); + /* slice_type */ + WRITE_UE (bs, slice_param->slice_type); + /* pic_parameter_set_id */ + WRITE_UE (bs, slice_param->pic_parameter_set_id); + /* frame_num */ + WRITE_UINT32 (bs, picture->frame_num, encoder->log2_max_frame_num); + + /* XXX: only frames (i.e. non-interlaced) are supported for now */ + /* frame_mbs_only_flag == 0 */ + + /* idr_pic_id */ + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + WRITE_UE (bs, slice_param->idr_pic_id); + + /* XXX: only POC type 0 is supported */ + if (!encoder->pic_order_cnt_type) { + WRITE_UINT32 (bs, slice_param->pic_order_cnt_lsb, + encoder->log2_max_pic_order_cnt); + /* bottom_field_pic_order_in_frame_present_flag is FALSE */ + if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag) + WRITE_SE (bs, slice_param->delta_pic_order_cnt_bottom); + } else if (encoder->pic_order_cnt_type == 1 && + !encoder->delta_pic_order_always_zero_flag) { + WRITE_SE (bs, slice_param->delta_pic_order_cnt[0]); + if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag) + WRITE_SE (bs, slice_param->delta_pic_order_cnt[1]); + } + /* redundant_pic_cnt_present_flag is FALSE, no redundant coded pictures */ + + /* only works for B-frames */ + if (slice_param->slice_type == GST_H264_B_SLICE) + WRITE_UINT32 (bs, slice_param->direct_spatial_mv_pred_flag, 1); + + /* not supporting SP slices */ + if (slice_param->slice_type == 0 || slice_param->slice_type == 1) { + WRITE_UINT32 (bs, slice_param->num_ref_idx_active_override_flag, 1); + if (slice_param->num_ref_idx_active_override_flag) { + WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1); + if (slice_param->slice_type == 1) + WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1); + } + } + /* XXX: not supporting custom reference picture list modifications */ + if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4)) + WRITE_UINT32 (bs, ref_pic_list_modification_flag_l0, 1); + if (slice_param->slice_type == 1) + WRITE_UINT32 (bs, ref_pic_list_modification_flag_l1, 1); + + /* we have: weighted_pred_flag == FALSE and */ + /* : weighted_bipred_idc == FALSE */ + if ((pic_param->pic_fields.bits.weighted_pred_flag && + (slice_param->slice_type == 0)) || + ((pic_param->pic_fields.bits.weighted_bipred_idc == 1) && + (slice_param->slice_type == 1))) { + /* XXXX: add pred_weight_table() */ + } + + /* dec_ref_pic_marking() */ + if (slice_param->slice_type == 0 || slice_param->slice_type == 2) { + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { + /* no_output_of_prior_pics_flag = 0 */ + WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1); + /* long_term_reference_flag = 0 */ + WRITE_UINT32 (bs, long_term_reference_flag, 1); + } else { + /* only sliding_window reference picture marking mode is supported */ + /* adpative_ref_pic_marking_mode_flag = 0 */ + WRITE_UINT32 (bs, adaptive_ref_pic_marking_mode_flag, 1); + } + } + + /* cabac_init_idc */ + if (pic_param->pic_fields.bits.entropy_coding_mode_flag && + slice_param->slice_type != 2) + WRITE_UE (bs, slice_param->cabac_init_idc); + /*slice_qp_delta */ + WRITE_SE (bs, slice_param->slice_qp_delta); + + /* XXX: only supporting I, P and B type slices */ + /* no sp_for_switch_flag and no slice_qs_delta */ + + if (pic_param->pic_fields.bits.deblocking_filter_control_present_flag) { + /* disable_deblocking_filter_idc */ + WRITE_UE (bs, slice_param->disable_deblocking_filter_idc); + if (slice_param->disable_deblocking_filter_idc != 1) { + WRITE_SE (bs, slice_param->slice_alpha_c0_offset_div2); + WRITE_SE (bs, slice_param->slice_beta_offset_div2); + } + } + + /* XXX: unsupported arbitrary slice ordering (ASO) */ + /* num_slic_groups_minus1 should be zero */ + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Slice NAL unit"); + return FALSE; + } +} + +static inline void +_check_sps_pps_status (GstVaapiEncoderH264Fei * encoder, + const guint8 * nal, guint32 size) +{ + guint8 nal_type; + G_GNUC_UNUSED gsize ret; /* FIXME */ + gboolean has_subset_sps; + + g_assert (size); + + has_subset_sps = !encoder->is_mvc || (encoder->subset_sps_data != NULL); + if (encoder->sps_data && encoder->pps_data && has_subset_sps) + return; + + nal_type = nal[0] & 0x1F; + switch (nal_type) { + case GST_H264_NAL_SPS: + encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (encoder->sps_data, 0, nal, size); + g_assert (ret == size); + break; + case GST_H264_NAL_SUBSET_SPS: + encoder->subset_sps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (encoder->subset_sps_data, 0, nal, size); + g_assert (ret == size); + break; + case GST_H264_NAL_PPS: + encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (encoder->pps_data, 0, nal, size); + g_assert (ret == size); + break; + default: + break; + } +} + +/* Determines the largest supported profile by the underlying hardware */ +static gboolean +ensure_hw_profile_limits (GstVaapiEncoderH264Fei * encoder) +{ + GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); + GArray *profiles; + guint i, profile_idc, max_profile_idc; + + if (encoder->hw_max_profile_idc) + return TRUE; + + profiles = gst_vaapi_display_get_encode_profiles (display); + if (!profiles) + return FALSE; + + max_profile_idc = 0; + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index (profiles, GstVaapiProfile, i); + profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + if (!profile_idc) + continue; + if (max_profile_idc < profile_idc) + max_profile_idc = profile_idc; + } + g_array_unref (profiles); + + encoder->hw_max_profile_idc = max_profile_idc; + return TRUE; +} + +/* Derives the profile supported by the underlying hardware */ +static gboolean +ensure_hw_profile (GstVaapiEncoderH264Fei * encoder) +{ + GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); + GstVaapiEntrypoint entrypoint = encoder->entrypoint; + GstVaapiProfile profile, profiles[4]; + guint i, num_profiles = 0; + + profiles[num_profiles++] = encoder->profile; + switch (encoder->profile) { + case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE: + profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE; + profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN; + // fall-through + case GST_VAAPI_PROFILE_H264_MAIN: + profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; + break; + default: + break; + } + + 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 (0x%08x)", encoder->profile); + return FALSE; + } +} + +/* Check target decoder constraints */ +static gboolean +ensure_profile_limits (GstVaapiEncoderH264Fei * encoder) +{ + GstVaapiProfile profile; + + if (!encoder->max_profile_idc + || encoder->profile_idc <= encoder->max_profile_idc) + return TRUE; + + GST_WARNING ("lowering coding tools to meet target decoder constraints"); + + profile = GST_VAAPI_PROFILE_UNKNOWN; + + /* Try Main profile coding tools */ + if (encoder->max_profile_idc < 100) { + encoder->use_dct8x8 = FALSE; + profile = GST_VAAPI_PROFILE_H264_MAIN; + } + + /* Try Constrained Baseline profile coding tools */ + if (encoder->max_profile_idc < 77) { + encoder->num_bframes = 0; + encoder->use_cabac = FALSE; + profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + } + + if (profile) { + encoder->profile = profile; + encoder->profile_idc = encoder->max_profile_idc; + } + return TRUE; +} + +/* Derives the minimum profile from the active coding tools */ +static gboolean +ensure_profile (GstVaapiEncoderH264Fei * encoder) +{ + GstVaapiProfile profile; + + /* Always start from "constrained-baseline" profile for maximum + compatibility */ + profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + + /* Main profile coding tools */ + if (encoder->num_bframes > 0 || encoder->use_cabac) + profile = GST_VAAPI_PROFILE_H264_MAIN; + + /* High profile coding tools */ + if (encoder->use_dct8x8) + profile = GST_VAAPI_PROFILE_H264_HIGH; + + /* MVC profiles coding tools */ + if (encoder->num_views == 2) + profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH; + else if (encoder->num_views > 2) + profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH; + + encoder->profile = profile; + encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + return TRUE; +} + +/* Derives the level from the currently set limits */ +static gboolean +ensure_level (GstVaapiEncoderH264Fei * encoder) +{ + const guint cpb_factor = h264_get_cpb_nal_factor (encoder->profile); + const GstVaapiH264LevelLimits *limits_table; + guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS; + + PicSizeMbs = encoder->mb_width * encoder->mb_height; + MaxDpbMbs = PicSizeMbs * ((encoder->num_bframes) ? 2 : 1); + MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs, + GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder)); + + limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits); + for (i = 0; i < num_limits; i++) { + const GstVaapiH264LevelLimits *const limits = &limits_table[i]; + if (PicSizeMbs <= limits->MaxFS && + MaxDpbMbs <= limits->MaxDpbMbs && + MaxMBPS <= limits->MaxMBPS && (!encoder->bitrate_bits + || encoder->bitrate_bits <= (limits->MaxBR * cpb_factor)) && + (!encoder->cpb_length_bits || + encoder->cpb_length_bits <= (limits->MaxCPB * cpb_factor))) + break; + } + if (i == num_limits) + goto error_unsupported_level; + + encoder->level = limits_table[i].level; + encoder->level_idc = limits_table[i].level_idc; + return TRUE; + + /* ERRORS */ +error_unsupported_level: + { + GST_ERROR ("failed to find a suitable level matching codec config"); + return FALSE; + } +} + +/* Enable "high-compression" tuning options */ +static gboolean +ensure_tuning_high_compression (GstVaapiEncoderH264Fei * encoder) +{ + guint8 profile_idc; + + if (!ensure_hw_profile_limits (encoder)) + return FALSE; + + profile_idc = encoder->hw_max_profile_idc; + if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc) + profile_idc = encoder->max_profile_idc; + + /* Tuning options to enable Main profile */ + if (profile_idc >= 77 && profile_idc != 88) { + encoder->use_cabac = TRUE; + if (!encoder->num_bframes) + encoder->num_bframes = 1; + } + + /* Tuning options to enable High profile */ + if (profile_idc >= 100) { + encoder->use_dct8x8 = TRUE; + } + return TRUE; +} + +/* Ensure tuning options */ +static gboolean +ensure_tuning (GstVaapiEncoderH264Fei * encoder) +{ + gboolean success; + + switch (GST_VAAPI_ENCODER_TUNE (encoder)) { + case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: + success = ensure_tuning_high_compression (encoder); + break; + case GST_VAAPI_ENCODER_TUNE_LOW_POWER: + /* Set low-power encode entry point. If hardware doesn't have + * support, it will fail in ensure_hw_profile() in later stage. + * So not duplicating the profile/entrypont query mechanism + * here as a part of optimization */ + encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; + success = TRUE; + break; + default: + success = TRUE; + break; + } + return success; +} + +/* Handle new GOP starts */ +static void +reset_gop_start (GstVaapiEncoderH264Fei * encoder) +{ + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[encoder->view_idx]; + + reorder_pool->frame_index = 1; + reorder_pool->cur_frame_num = 0; + reorder_pool->cur_present_index = 0; + ++encoder->idr_num; +} + +/* Marks the supplied picture as a B-frame */ +static void +set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder) +{ + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[encoder->view_idx]; + + g_assert (pic && encoder); + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_B; + pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); +} + +/* Marks the supplied picture as a P-frame */ +static void +set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder) +{ + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[encoder->view_idx]; + + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_P; + pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); +} + +/* Marks the supplied picture as an I-frame */ +static void +set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder) +{ + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[encoder->view_idx]; + + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_I; + pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); + + g_assert (pic->frame); + GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); +} + +/* Marks the supplied picture as an IDR frame */ +static void +set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder) +{ + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_I; + pic->frame_num = 0; + pic->poc = 0; + GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR); + + g_assert (pic->frame); + GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); +} + +/* Marks the supplied picture a a key-frame */ +static void +set_key_frame (GstVaapiEncPicture * picture, + GstVaapiEncoderH264Fei * encoder, gboolean is_idr) +{ + if (is_idr) { + reset_gop_start (encoder); + set_idr_frame (picture, encoder); + } else + set_i_frame (picture, encoder); +} + +/* Fills in VA HRD parameters */ +static void +fill_hrd_params (GstVaapiEncoderH264Fei * encoder, VAEncMiscParameterHRD * hrd) +{ + if (encoder->bitrate_bits > 0) { + hrd->buffer_size = encoder->cpb_length_bits; + hrd->initial_buffer_fullness = hrd->buffer_size / 2; + } else { + hrd->buffer_size = 0; + hrd->initial_buffer_fullness = 0; + } +} + +/* Adds the supplied sequence header (SPS) to the list of packed + headers to pass down as-is to the encoder */ +static gboolean +add_packed_sequence_header (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) +{ + GstVaapiEncPackedHeader *packed_seq; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 }; + const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; + GstVaapiProfile profile = encoder->profile; + + VAEncMiscParameterHRD hrd_params; + guint32 data_bit_size; + guint8 *data; + + fill_hrd_params (encoder, &hrd_params); + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS); + + /* Set High profile for encoding the MVC base view. Otherwise, some + traditional decoder cannot recognize MVC profile streams with + only the base view in there */ + if (profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH || + profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) + profile = GST_VAAPI_PROFILE_H264_HIGH; + + bs_write_sps (&bs, seq_param, profile, &hrd_params); + + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_seq_param.type = VAEncPackedHeaderSequence; + packed_seq_param.bit_length = data_bit_size; + packed_seq_param.has_emulation_bytes = 0; + + packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_seq_param, sizeof (packed_seq_param), + data, (data_bit_size + 7) / 8); + g_assert (packed_seq); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_seq, NULL); + + /* store sps data */ + _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +static gboolean +add_packed_sequence_header_mvc (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) +{ + GstVaapiEncPackedHeader *packed_seq; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; + const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; + VAEncMiscParameterHRD hrd_params; + guint32 data_bit_size; + guint8 *data; + + fill_hrd_params (encoder, &hrd_params); + + /* non-base layer, pack one subset sps */ + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS); + + bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views, + encoder->view_ids, &hrd_params); + + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_header_param_buffer.type = VAEncPackedHeaderSequence; + packed_header_param_buffer.bit_length = data_bit_size; + packed_header_param_buffer.has_emulation_bytes = 0; + + packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_header_param_buffer, sizeof (packed_header_param_buffer), + data, (data_bit_size + 7) / 8); + g_assert (packed_seq); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL); + + /* store subset sps data */ + _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +/* Adds the supplied picture header (PPS) to the list of packed + headers to pass down as-is to the encoder */ +static gboolean +add_packed_picture_header (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncPackedHeader *packed_pic; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 }; + const VAEncPictureParameterBufferH264 *const pic_param = picture->param; + guint32 data_bit_size; + guint8 *data; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS); + bs_write_pps (&bs, pic_param, encoder->profile); + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_pic_param.type = VAEncPackedHeaderPicture; + packed_pic_param.bit_length = data_bit_size; + packed_pic_param.has_emulation_bytes = 0; + + packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_pic_param, sizeof (packed_pic_param), + data, (data_bit_size + 7) / 8); + g_assert (packed_pic); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_pic); + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_pic, NULL); + + /* store pps data */ + _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write PPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +static gboolean +add_packed_sei_header (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture, GstVaapiH264SeiPayloadType payloadtype) +{ + GstVaapiEncPackedHeader *packed_sei; + GstBitWriter bs, bs_buf_period, bs_pic_timing; + VAEncPackedHeaderParameterBuffer packed_sei_param = { 0 }; + guint32 data_bit_size; + guint8 buf_period_payload_size = 0, pic_timing_payload_size = 0; + guint8 *data, *buf_period_payload = NULL, *pic_timing_payload = NULL; + gboolean need_buf_period, need_pic_timing; + + gst_bit_writer_init (&bs_buf_period, 128 * 8); + gst_bit_writer_init (&bs_pic_timing, 128 * 8); + gst_bit_writer_init (&bs, 128 * 8); + + need_buf_period = GST_VAAPI_H264_SEI_BUF_PERIOD & payloadtype; + need_pic_timing = GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype; + + if (need_buf_period) { + /* Write a Buffering Period SEI message */ + bs_write_sei_buf_period (&bs_buf_period, encoder, picture); + /* Write byte alignment bits */ + if (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period) % 8 != 0) + bs_write_trailing_bits (&bs_buf_period); + buf_period_payload_size = (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period)) / 8; + buf_period_payload = GST_BIT_WRITER_DATA (&bs_buf_period); + } + + if (need_pic_timing) { + /* Write a Picture Timing SEI message */ + if (GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype) + bs_write_sei_pic_timing (&bs_pic_timing, encoder, picture); + /* Write byte alignment bits */ + if (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing) % 8 != 0) + bs_write_trailing_bits (&bs_pic_timing); + pic_timing_payload_size = (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing)) / 8; + pic_timing_payload = GST_BIT_WRITER_DATA (&bs_pic_timing); + } + + /* Write the SEI message */ + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_NONE, GST_H264_NAL_SEI); + + if (need_buf_period) { + WRITE_UINT32 (&bs, GST_H264_SEI_BUF_PERIOD, 8); + WRITE_UINT32 (&bs, buf_period_payload_size, 8); + /* Add buffering period sei message */ + gst_bit_writer_put_bytes (&bs, buf_period_payload, buf_period_payload_size); + } + + if (need_pic_timing) { + WRITE_UINT32 (&bs, GST_H264_SEI_PIC_TIMING, 8); + WRITE_UINT32 (&bs, pic_timing_payload_size, 8); + /* Add picture timing sei message */ + gst_bit_writer_put_bytes (&bs, pic_timing_payload, pic_timing_payload_size); + } + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (&bs); + + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_sei_param.type = VAEncPackedHeaderH264_SEI; + packed_sei_param.bit_length = data_bit_size; + packed_sei_param.has_emulation_bytes = 0; + + packed_sei = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_sei_param, sizeof (packed_sei_param), + data, (data_bit_size + 7) / 8); + g_assert (packed_sei); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_sei); + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_sei, NULL); + + gst_bit_writer_clear (&bs_buf_period, TRUE); + gst_bit_writer_clear (&bs_pic_timing, TRUE); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SEI NAL unit"); + gst_bit_writer_clear (&bs_buf_period, TRUE); + gst_bit_writer_clear (&bs_pic_timing, TRUE); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +static gboolean +get_nal_hdr_attributes (GstVaapiEncPicture * picture, + guint8 * nal_ref_idc, guint8 * nal_unit_type) +{ + switch (picture->type) { + case GST_VAAPI_PICTURE_TYPE_I: + *nal_ref_idc = GST_H264_NAL_REF_IDC_HIGH; + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + *nal_unit_type = GST_H264_NAL_SLICE_IDR; + else + *nal_unit_type = GST_H264_NAL_SLICE; + break; + case GST_VAAPI_PICTURE_TYPE_P: + *nal_ref_idc = GST_H264_NAL_REF_IDC_MEDIUM; + *nal_unit_type = GST_H264_NAL_SLICE; + break; + case GST_VAAPI_PICTURE_TYPE_B: + *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE; + *nal_unit_type = GST_H264_NAL_SLICE; + break; + default: + return FALSE; + } + return TRUE; +} + +/* Adds the supplied prefix nal header to the list of packed + headers to pass down as-is to the encoder */ +static gboolean +add_packed_prefix_nal_header (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture, GstVaapiEncSlice * slice) +{ + GstVaapiEncPackedHeader *packed_prefix_nal; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_prefix_nal_param = { 0 }; + guint32 data_bit_size; + guint8 *data; + guint8 nal_ref_idc, nal_unit_type; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + + if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) + goto bs_error; + nal_unit_type = GST_H264_NAL_PREFIX_UNIT; + + bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); + bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_idx); + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_prefix_nal_param.type = VAEncPackedHeaderRawData; + packed_prefix_nal_param.bit_length = data_bit_size; + packed_prefix_nal_param.has_emulation_bytes = 0; + + packed_prefix_nal = + gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_prefix_nal_param, sizeof (packed_prefix_nal_param), data, + (data_bit_size + 7) / 8); + g_assert (packed_prefix_nal); + + gst_vaapi_enc_slice_add_packed_header (slice, packed_prefix_nal); + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_prefix_nal, + NULL); + + gst_bit_writer_clear (&bs, TRUE); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Prefix NAL unit header"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +/* Adds the supplied slice header to the list of packed + headers to pass down as-is to the encoder */ +static gboolean +add_packed_slice_header (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture, GstVaapiEncSlice * slice) +{ + GstVaapiEncPackedHeader *packed_slice; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 }; + const VAEncSliceParameterBufferH264 *const slice_param = slice->param; + guint32 data_bit_size; + guint8 *data; + guint8 nal_ref_idc, nal_unit_type; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + + if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) + goto bs_error; + /* pack nal_unit_header_mvc_extension() for the non base view */ + if (encoder->is_mvc && encoder->view_idx) { + bs_write_nal_header (&bs, nal_ref_idc, GST_H264_NAL_SLICE_EXT); + bs_write_nal_header_mvc_extension (&bs, picture, + encoder->view_ids[encoder->view_idx]); + } else + bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); + + bs_write_slice (&bs, slice_param, encoder, picture); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_slice_param.type = VAEncPackedHeaderSlice; + packed_slice_param.bit_length = data_bit_size; + packed_slice_param.has_emulation_bytes = 0; + + packed_slice = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), + &packed_slice_param, sizeof (packed_slice_param), + data, (data_bit_size + 7) / 8); + g_assert (packed_slice); + + gst_vaapi_enc_slice_add_packed_header (slice, packed_slice); + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_slice, + NULL); + + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Slice NAL unit header"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +/* Reference picture management */ +static void +reference_pic_free (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncoderH264FeiRef * ref) +{ + if (!ref) + return; + if (ref->pic) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic); + g_slice_free (GstVaapiEncoderH264FeiRef, ref); +} + +static inline GstVaapiEncoderH264FeiRef * +reference_pic_create (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) +{ + GstVaapiEncoderH264FeiRef *const ref = + g_slice_new0 (GstVaapiEncoderH264FeiRef); + + ref->pic = surface; + ref->frame_num = picture->frame_num; + ref->poc = picture->poc; + return ref; +} + +static gboolean +reference_list_update (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) +{ + GstVaapiEncoderH264FeiRef *ref; + GstVaapiH264ViewRefPool *const ref_pool = + &encoder->ref_pools[encoder->view_idx]; + + if (GST_VAAPI_PICTURE_TYPE_B == picture->type) { + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface); + return TRUE; + } + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { + while (!g_queue_is_empty (&ref_pool->ref_list)) + reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list)); + } else if (g_queue_get_length (&ref_pool->ref_list) >= + ref_pool->max_ref_frames) { + reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list)); + } + ref = reference_pic_create (encoder, picture, surface); + g_queue_push_tail (&ref_pool->ref_list, ref); + g_assert (g_queue_get_length (&ref_pool->ref_list) <= + ref_pool->max_ref_frames); + return TRUE; +} + +static gboolean +reference_list_init (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture, + GstVaapiEncoderH264FeiRef ** reflist_0, + guint * reflist_0_count, + GstVaapiEncoderH264FeiRef ** reflist_1, guint * reflist_1_count) +{ + GstVaapiEncoderH264FeiRef *tmp; + GstVaapiH264ViewRefPool *const ref_pool = + &encoder->ref_pools[encoder->view_idx]; + GList *iter, *list_0_start = NULL, *list_1_start = NULL; + guint count; + + *reflist_0_count = 0; + *reflist_1_count = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_I) + return TRUE; + + iter = g_queue_peek_tail_link (&ref_pool->ref_list); + for (; iter; iter = g_list_previous (iter)) { + tmp = (GstVaapiEncoderH264FeiRef *) iter->data; + g_assert (tmp && tmp->poc != picture->poc); + if (_poc_greater_than (picture->poc, tmp->poc, encoder->max_pic_order_cnt)) { + list_0_start = iter; + list_1_start = g_list_next (iter); + break; + } + } + + /* order reflist_0 */ + g_assert (list_0_start); + iter = list_0_start; + count = 0; + for (; iter; iter = g_list_previous (iter)) { + reflist_0[count] = (GstVaapiEncoderH264FeiRef *) iter->data; + ++count; + } + *reflist_0_count = count; + + if (picture->type != GST_VAAPI_PICTURE_TYPE_B) + return TRUE; + + /* order reflist_1 */ + count = 0; + iter = list_1_start; + for (; iter; iter = g_list_next (iter)) { + reflist_1[count] = (GstVaapiEncoderH264FeiRef *) iter->data; + ++count; + } + *reflist_1_count = count; + return TRUE; +} + +/* Fills in VA sequence parameter buffer */ +static gboolean +fill_sequence (GstVaapiEncoderH264Fei * encoder, GstVaapiEncSequence * sequence) +{ + VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; + GstVaapiH264ViewRefPool *const ref_pool = + &encoder->ref_pools[encoder->view_idx]; + + memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264)); + seq_param->seq_parameter_set_id = encoder->view_idx; + seq_param->level_idc = encoder->level_idc; + seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); + seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); + seq_param->ip_period = 1 + encoder->num_bframes; + seq_param->ip_period = seq_param->intra_period > 1 ? + (1 + encoder->num_bframes) : 0; + seq_param->bits_per_second = encoder->bitrate_bits; + + seq_param->max_num_ref_frames = ref_pool->max_ref_frames; + seq_param->picture_width_in_mbs = encoder->mb_width; + seq_param->picture_height_in_mbs = encoder->mb_height; + + /*sequence field values */ + seq_param->seq_fields.value = 0; + seq_param->seq_fields.bits.chroma_format_idc = 1; + seq_param->seq_fields.bits.frame_mbs_only_flag = 1; + seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE; + seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE; + /* direct_8x8_inference_flag default false */ + seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE; + g_assert (encoder->log2_max_frame_num >= 4); + seq_param->seq_fields.bits.log2_max_frame_num_minus4 = + encoder->log2_max_frame_num - 4; + /* picture order count */ + encoder->pic_order_cnt_type = seq_param->seq_fields.bits.pic_order_cnt_type = + 0; + g_assert (encoder->log2_max_pic_order_cnt >= 4); + seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = + encoder->log2_max_pic_order_cnt - 4; + + seq_param->bit_depth_luma_minus8 = 0; + seq_param->bit_depth_chroma_minus8 = 0; + + /* not used if pic_order_cnt_type == 0 */ + if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { + encoder->delta_pic_order_always_zero_flag = + seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE; + seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0; + seq_param->offset_for_non_ref_pic = 0; + seq_param->offset_for_top_to_bottom_field = 0; + memset (seq_param->offset_for_ref_frame, 0, + sizeof (seq_param->offset_for_ref_frame)); + } + + /* frame_cropping_flag */ + if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) || + (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) { + static const guint SubWidthC[] = { 1, 2, 2, 1 }; + static const guint SubHeightC[] = { 1, 2, 1, 1 }; + const guint CropUnitX = + SubWidthC[seq_param->seq_fields.bits.chroma_format_idc]; + const guint CropUnitY = + SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] * + (2 - seq_param->seq_fields.bits.frame_mbs_only_flag); + + seq_param->frame_cropping_flag = 1; + seq_param->frame_crop_left_offset = 0; + seq_param->frame_crop_right_offset = + (16 * encoder->mb_width - + GST_VAAPI_ENCODER_WIDTH (encoder)) / CropUnitX; + seq_param->frame_crop_top_offset = 0; + seq_param->frame_crop_bottom_offset = + (16 * encoder->mb_height - + GST_VAAPI_ENCODER_HEIGHT (encoder)) / CropUnitY; + } + + /* VUI parameters are always set, at least for timing_info (framerate) */ + seq_param->vui_parameters_present_flag = TRUE; + if (seq_param->vui_parameters_present_flag) { + seq_param->vui_fields.bits.aspect_ratio_info_present_flag = TRUE; + if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { + const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); + seq_param->aspect_ratio_idc = 0xff; + seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip); + seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip); + } + seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE; + /* if vui_parameters_present_flag is TRUE and sps data belongs to + * subset sps, timing_info_preset_flag should be zero (H.7.4.2.1.1) */ + seq_param->vui_fields.bits.timing_info_present_flag = !encoder->view_idx; + if (seq_param->vui_fields.bits.timing_info_present_flag) { + seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder); + seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2; + } + } + return TRUE; +} + +/* Fills in VA picture parameter buffer */ +static gboolean +fill_picture (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture, + GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) +{ + VAEncPictureParameterBufferH264 *const pic_param = picture->param; + GstVaapiH264ViewRefPool *const ref_pool = + &encoder->ref_pools[encoder->view_idx]; + GstVaapiEncoderH264FeiRef *ref_pic; + GList *reflist; + guint i; + + memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264)); + + /* reference list, */ + pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); + pic_param->CurrPic.TopFieldOrderCnt = picture->poc; + i = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (reflist = g_queue_peek_head_link (&ref_pool->ref_list); + reflist; reflist = g_list_next (reflist)) { + ref_pic = reflist->data; + g_assert (ref_pic && ref_pic->pic && + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID); + + pic_param->ReferenceFrames[i].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); + pic_param->ReferenceFrames[i].TopFieldOrderCnt = ref_pic->poc; + pic_param->ReferenceFrames[i].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + pic_param->ReferenceFrames[i].frame_idx = ref_pic->frame_num; + + ++i; + } + g_assert (i <= 16 && i <= ref_pool->max_ref_frames); + } + for (; i < 16; ++i) { + pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID; + } + pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + + pic_param->pic_parameter_set_id = encoder->view_idx; + pic_param->seq_parameter_set_id = encoder->view_idx ? 1 : 0; + pic_param->last_picture = 0; /* means last encoding picture */ + pic_param->frame_num = picture->frame_num; + pic_param->pic_init_qp = encoder->init_qp; + pic_param->num_ref_idx_l0_active_minus1 = + (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0); + pic_param->num_ref_idx_l1_active_minus1 = + (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0); + pic_param->chroma_qp_index_offset = 0; + pic_param->second_chroma_qp_index_offset = 0; + + /* set picture fields */ + pic_param->pic_fields.value = 0; + pic_param->pic_fields.bits.idr_pic_flag = + GST_VAAPI_ENC_PICTURE_IS_IDR (picture); + pic_param->pic_fields.bits.reference_pic_flag = + (picture->type != GST_VAAPI_PICTURE_TYPE_B); + pic_param->pic_fields.bits.entropy_coding_mode_flag = encoder->use_cabac; + pic_param->pic_fields.bits.weighted_pred_flag = FALSE; + pic_param->pic_fields.bits.weighted_bipred_idc = 0; + pic_param->pic_fields.bits.constrained_intra_pred_flag = 0; + pic_param->pic_fields.bits.transform_8x8_mode_flag = encoder->use_dct8x8; + /* enable debloking */ + pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; + pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE; + /* bottom_field_pic_order_in_frame_present_flag */ + pic_param->pic_fields.bits.pic_order_present_flag = FALSE; + pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE; + + return TRUE; +} + +/* Adds slice headers to picture */ +static gboolean +add_slice_headers (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture, GstVaapiEncoderH264FeiRef ** reflist_0, + guint reflist_0_count, GstVaapiEncoderH264FeiRef ** reflist_1, + guint reflist_1_count) +{ + VAEncSliceParameterBufferH264 *slice_param; + GstVaapiEncSlice *slice; + guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs; + guint mb_size; + guint last_mb_index; + guint i_slice, i_ref; + + g_assert (picture); + + mb_size = encoder->mb_width * encoder->mb_height; + + g_assert (encoder->num_slices && encoder->num_slices < mb_size); + slice_of_mbs = mb_size / encoder->num_slices; + slice_mod_mbs = mb_size % encoder->num_slices; + last_mb_index = 0; + for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) { + cur_slice_mbs = slice_of_mbs; + if (slice_mod_mbs) { + ++cur_slice_mbs; + --slice_mod_mbs; + } + slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder); + g_assert (slice && slice->param_id != VA_INVALID_ID); + slice_param = slice->param; + + memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264)); + slice_param->macroblock_address = last_mb_index; + slice_param->num_macroblocks = cur_slice_mbs; + slice_param->macroblock_info = VA_INVALID_ID; + slice_param->slice_type = h264_get_slice_type (picture->type); + g_assert ((gint8) slice_param->slice_type != -1); + slice_param->pic_parameter_set_id = encoder->view_idx; + slice_param->idr_pic_id = encoder->idr_num; + slice_param->pic_order_cnt_lsb = picture->poc; + + /* not used if pic_order_cnt_type = 0 */ + slice_param->delta_pic_order_cnt_bottom = 0; + memset (slice_param->delta_pic_order_cnt, 0, + sizeof (slice_param->delta_pic_order_cnt)); + + /* only works for B frames */ + if (slice_param->slice_type == GST_H264_B_SLICE) + slice_param->direct_spatial_mv_pred_flag = TRUE; + /* default equal to picture parameters */ + slice_param->num_ref_idx_active_override_flag = FALSE; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) + slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; + else + slice_param->num_ref_idx_l0_active_minus1 = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0) + slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; + else + slice_param->num_ref_idx_l1_active_minus1 = 0; + g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0); + g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0); + + i_ref = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (; i_ref < reflist_0_count; ++i_ref) { + slice_param->RefPicList0[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); + slice_param->RefPicList0[i_ref].TopFieldOrderCnt = + reflist_0[i_ref]->poc; + slice_param->RefPicList0[i_ref].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + slice_param->RefPicList0[i_ref].frame_idx = reflist_0[i_ref]->frame_num; + } + g_assert (i_ref == 1); + } + for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) { + slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE; + } + + i_ref = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + for (; i_ref < reflist_1_count; ++i_ref) { + slice_param->RefPicList1[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); + slice_param->RefPicList1[i_ref].TopFieldOrderCnt = + reflist_1[i_ref]->poc; + slice_param->RefPicList1[i_ref].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + slice_param->RefPicList1[i_ref].frame_idx = reflist_1[i_ref]->frame_num; + } + g_assert (i_ref == 1); + } + for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) { + slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE; + } + + /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */ + slice_param->luma_log2_weight_denom = 0; + slice_param->chroma_log2_weight_denom = 0; + slice_param->luma_weight_l0_flag = FALSE; + memset (slice_param->luma_weight_l0, 0, + sizeof (slice_param->luma_weight_l0)); + memset (slice_param->luma_offset_l0, 0, + sizeof (slice_param->luma_offset_l0)); + slice_param->chroma_weight_l0_flag = FALSE; + memset (slice_param->chroma_weight_l0, 0, + sizeof (slice_param->chroma_weight_l0)); + memset (slice_param->chroma_offset_l0, 0, + sizeof (slice_param->chroma_offset_l0)); + slice_param->luma_weight_l1_flag = FALSE; + memset (slice_param->luma_weight_l1, 0, + sizeof (slice_param->luma_weight_l1)); + memset (slice_param->luma_offset_l1, 0, + sizeof (slice_param->luma_offset_l1)); + slice_param->chroma_weight_l1_flag = FALSE; + memset (slice_param->chroma_weight_l1, 0, + sizeof (slice_param->chroma_weight_l1)); + memset (slice_param->chroma_offset_l1, 0, + sizeof (slice_param->chroma_offset_l1)); + + slice_param->cabac_init_idc = 0; + slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp; + if (slice_param->slice_qp_delta > 4) + slice_param->slice_qp_delta = 4; + slice_param->disable_deblocking_filter_idc = 0; + slice_param->slice_alpha_c0_offset_div2 = 2; + slice_param->slice_beta_offset_div2 = 2; + + /* set calculation for next slice */ + last_mb_index += cur_slice_mbs; + + /* add packed Prefix NAL unit before each Coded slice NAL in base view */ + if (encoder->is_mvc && !encoder->view_idx && + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_RAW_DATA) + && !add_packed_prefix_nal_header (encoder, picture, slice)) + goto error_create_packed_prefix_nal_hdr; + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_SLICE) + && !add_packed_slice_header (encoder, picture, slice)) + goto error_create_packed_slice_hdr; + + gst_vaapi_enc_picture_add_slice (picture, slice); + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & slice, NULL); + } + g_assert (last_mb_index == mb_size); + return TRUE; + +error_create_packed_slice_hdr: + { + GST_ERROR ("failed to create packed slice header buffer"); + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & slice, NULL); + return FALSE; + } +error_create_packed_prefix_nal_hdr: + { + GST_ERROR ("failed to create packed prefix nal header buffer"); + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & slice, NULL); + return FALSE; + } +} + +/* Generates and submits SPS header accordingly into the bitstream */ +static gboolean +ensure_sequence (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncSequence *sequence = NULL; + + /* submit an SPS header before every new I-frame, if codec config changed */ + if (!encoder->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I) + return TRUE; + + sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder); + if (!sequence || !fill_sequence (encoder, sequence)) + goto error_create_seq_param; + + /* add subset sps for non-base view and sps for base view */ + if (encoder->is_mvc && encoder->view_idx) { + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_SEQUENCE) + && !add_packed_sequence_header_mvc (encoder, picture, sequence)) + goto error_create_packed_seq_hdr; + } else { + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_SEQUENCE) + && !add_packed_sequence_header (encoder, picture, sequence)) + goto error_create_packed_seq_hdr; + } + + if (sequence) { + gst_vaapi_enc_picture_set_sequence (picture, sequence); + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & sequence, NULL); + } + + if (!encoder->is_mvc || encoder->view_idx > 0) + encoder->config_changed = FALSE; + return TRUE; + + /* ERRORS */ +error_create_seq_param: + { + GST_ERROR ("failed to create sequence parameter buffer (SPS)"); + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & sequence, NULL); + return FALSE; + } +error_create_packed_seq_hdr: + { + GST_ERROR ("failed to create packed sequence header buffer"); + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & sequence, NULL); + return FALSE; + } +} + +/* Generates additional fei control parameters */ +static gboolean +ensure_fei_misc_params (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy) +{ + GstVaapiEncMiscParam *misc = NULL; + GstVaapiSurfaceProxy *surface_proxy = NULL; + + VAEncMiscParameterFEIFrameControlH264 *misc_fei_pic_control_param; + guint mbcode_size = 0; + guint mv_size = 0; + guint dist_size = 0; + gboolean enable_out = FALSE; + + /* fei pic control params */ + misc = GST_VAAPI_ENC_FEI_MISC_PARAM_NEW (H264, encoder); + g_assert (misc); + if (!misc) + return FALSE; + misc_fei_pic_control_param = misc->data; + surface_proxy = picture->proxy; + + enable_out = ((encoder->is_stats_out_enabled && + (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK)) || + (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC)) ? TRUE : FALSE; + + misc_fei_pic_control_param->function = encoder->fei_mode; + misc_fei_pic_control_param->search_path = encoder->search_path; + misc_fei_pic_control_param->num_mv_predictors_l0 = + encoder->num_mv_predictors_l0; + misc_fei_pic_control_param->num_mv_predictors_l1 = + encoder->num_mv_predictors_l1; + misc_fei_pic_control_param->len_sp = encoder->len_sp; + misc_fei_pic_control_param->sub_mb_part_mask = encoder->submb_part_mask; + if (!encoder->use_dct8x8) + misc_fei_pic_control_param->intra_part_mask = encoder->intra_part_mask | 2; + misc_fei_pic_control_param->multi_pred_l0 = encoder->multi_predL0; + misc_fei_pic_control_param->multi_pred_l1 = encoder->multi_predL1; + misc_fei_pic_control_param->sub_pel_mode = encoder->subpel_mode; + misc_fei_pic_control_param->inter_sad = encoder->inter_sad; + misc_fei_pic_control_param->intra_sad = encoder->intra_sad; + misc_fei_pic_control_param->distortion_type = 0; + misc_fei_pic_control_param->repartition_check_enable = 0; + misc_fei_pic_control_param->adaptive_search = encoder->adaptive_search; + misc_fei_pic_control_param->mb_size_ctrl = 0; + misc_fei_pic_control_param->ref_width = encoder->ref_width; + misc_fei_pic_control_param->ref_height = encoder->ref_height; + misc_fei_pic_control_param->search_window = encoder->search_window; + + if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK) || + (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC)) { + + /***** ENC_PAK/ENC input: mv_predictor *****/ + if (surface_proxy->mvpred) { + misc_fei_pic_control_param->mv_predictor = + GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mvpred)->param_id; + misc_fei_pic_control_param->mv_predictor_enable = TRUE; + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & + picture->mvpred, surface_proxy->mvpred); + } else { + misc_fei_pic_control_param->mv_predictor = VA_INVALID_ID; + misc_fei_pic_control_param->mv_predictor_enable = FALSE; + picture->mvpred = NULL; + } + + /***** ENC_PAK/ENC input: qp ******/ + if (surface_proxy->qp) { + misc_fei_pic_control_param->qp = + GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->qp)->param_id; + misc_fei_pic_control_param->mb_qp = TRUE; + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & + picture->qp, surface_proxy->qp); + } else { + misc_fei_pic_control_param->qp = VA_INVALID_ID; + misc_fei_pic_control_param->mb_qp = FALSE; + picture->qp = NULL; + } + + /***** ENC_PAK/ENC input: mb_control ******/ + if (surface_proxy->mbcntrl) { + misc_fei_pic_control_param->mb_ctrl = + GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mbcntrl)->param_id; + misc_fei_pic_control_param->mb_input = TRUE; + gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & + picture->mbcntrl, surface_proxy->mbcntrl); + } else { + misc_fei_pic_control_param->mb_ctrl = VA_INVALID_ID; + misc_fei_pic_control_param->mb_input = FALSE; + picture->mbcntrl = NULL; + } + } + + if (enable_out) { + + mbcode_size = sizeof (VAEncFEIMBCodeH264) * + encoder->mb_width * encoder->mb_height; + mv_size = sizeof (VAMotionVector) * 16 * + encoder->mb_width * encoder->mb_height; + dist_size = sizeof (VAEncFEIDistortionH264) * + encoder->mb_width * encoder->mb_height; + + /***** ENC_PAK/ENC output: macroblock code buffer *****/ + codedbuf_proxy->mbcode = + gst_vaapi_enc_fei_mb_code_new (GST_VAAPI_ENCODER_CAST (encoder), + NULL, mbcode_size); + misc_fei_pic_control_param->mb_code_data = + GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mbcode)->param_id; + picture->mbcode = gst_vaapi_codec_object_ref (codedbuf_proxy->mbcode); + + /***** ENC_PAK/ENC output: motion vector buffer *****/ + codedbuf_proxy->mv = + gst_vaapi_enc_fei_mv_new (GST_VAAPI_ENCODER_CAST (encoder), NULL, + mv_size); + misc_fei_pic_control_param->mv_data = + GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mv)->param_id; + picture->mv = gst_vaapi_codec_object_ref (codedbuf_proxy->mv); + + /***** ENC_PAK/ENC output: distortion buffer *****/ + codedbuf_proxy->dist = + gst_vaapi_enc_fei_distortion_new (GST_VAAPI_ENCODER_CAST (encoder), + NULL, dist_size); + misc_fei_pic_control_param->distortion = + GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->dist)->param_id; + picture->dist = gst_vaapi_codec_object_ref (codedbuf_proxy->dist); + + } else if (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK) { + + g_assert (surface_proxy->mbcode != NULL); + g_assert (surface_proxy->mv != NULL); + + /***** PAK input: macroblock code buffer *****/ + misc_fei_pic_control_param->mb_code_data = + GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mbcode)->param_id; + picture->mbcode = gst_vaapi_codec_object_ref (surface_proxy->mbcode); + + /***** PAK input: motion vector buffer *****/ + misc_fei_pic_control_param->mv_data = + GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mv)->param_id; + picture->mv = gst_vaapi_codec_object_ref (surface_proxy->mv); + } else { + + codedbuf_proxy->mbcode = picture->mbcode = NULL; + codedbuf_proxy->mv = picture->mv = NULL; + codedbuf_proxy->dist = picture->dist = NULL; + misc_fei_pic_control_param->mb_code_data = VA_INVALID_ID; + misc_fei_pic_control_param->mv_data = VA_INVALID_ID; + misc_fei_pic_control_param->distortion = VA_INVALID_ID; + } + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + return TRUE; +} + +/* Generates additional control parameters */ +static gboolean +ensure_misc_params (GstVaapiEncoderH264Fei * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncMiscParam *misc = NULL; + VAEncMiscParameterRateControl *rate_control; + + /* HRD params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); + g_assert (misc); + if (!misc) + return FALSE; + fill_hrd_params (encoder, misc->data); + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + /* RateControl params */ + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR || + GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) { + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); + g_assert (misc); + if (!misc) + return FALSE; + rate_control = misc->data; + memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); + rate_control->bits_per_second = encoder->bitrate_bits; + rate_control->target_percentage = 70; + rate_control->window_size = encoder->cpb_length; + rate_control->initial_qp = encoder->init_qp; + rate_control->min_qp = encoder->min_qp; + rate_control->basic_unit_size = 0; + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + if (!encoder->view_idx) { + if ((GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) && + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_MISC) && + !add_packed_sei_header (encoder, picture, + GST_VAAPI_H264_SEI_BUF_PERIOD | GST_VAAPI_H264_SEI_PIC_TIMING)) + goto error_create_packed_sei_hdr; + + else if (!GST_VAAPI_ENC_PICTURE_IS_IDR (picture) && + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_MISC) && + !add_packed_sei_header (encoder, picture, + GST_VAAPI_H264_SEI_PIC_TIMING)) + goto error_create_packed_sei_hdr; + } + + } + return TRUE; + +error_create_packed_sei_hdr: + { + GST_ERROR ("failed to create packed SEI header"); + return FALSE; + } +} + +/* Generates and submits PPS header accordingly into the bitstream */ +static gboolean +ensure_picture (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture, + GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) +{ + GstVaapiCodedBuffer *const codedbuf = + GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); + gboolean res = FALSE; + + res = fill_picture (encoder, picture, codedbuf, surface); + + if (!res) + return FALSE; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_I && + (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_PICTURE) + && !add_packed_picture_header (encoder, picture)) { + GST_ERROR ("set picture packed header failed"); + return FALSE; + } + return TRUE; +} + +/* Generates slice headers */ +static gboolean +ensure_slices (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncoderH264FeiRef *reflist_0[16]; + GstVaapiEncoderH264FeiRef *reflist_1[16]; + GstVaapiH264ViewRefPool *const ref_pool = + &encoder->ref_pools[encoder->view_idx]; + guint reflist_0_count = 0, reflist_1_count = 0; + + g_assert (picture); + + if (picture->type != GST_VAAPI_PICTURE_TYPE_I && + !reference_list_init (encoder, picture, + reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) { + GST_ERROR ("reference list reorder failed"); + return FALSE; + } + + g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames); + if (reflist_0_count > ref_pool->max_reflist0_count) + reflist_0_count = ref_pool->max_reflist0_count; + if (reflist_1_count > ref_pool->max_reflist1_count) + reflist_1_count = ref_pool->max_reflist1_count; + + if (!add_slice_headers (encoder, picture, + reflist_0, reflist_0_count, reflist_1, reflist_1_count)) + return FALSE; + + return TRUE; +} + +/* Normalizes bitrate (and CPB size) for HRD conformance */ +static void +ensure_bitrate_hrd (GstVaapiEncoderH264Fei * encoder) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + guint bitrate, cpb_size; + + if (!base_encoder->bitrate) { + encoder->bitrate_bits = 0; + return; + } + + /* Round down bitrate. This is a hard limit mandated by the user */ + g_assert (SX_BITRATE >= 6); + bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1); + if (bitrate != encoder->bitrate_bits) { + GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate); + encoder->bitrate_bits = bitrate; + encoder->config_changed = TRUE; + } + + /* Round up CPB size. This is an HRD compliance detail */ + g_assert (SX_CPB_SIZE >= 4); + cpb_size = gst_util_uint64_scale (bitrate, encoder->cpb_length, 1000) & + ~((1U << SX_CPB_SIZE) - 1); + if (cpb_size != encoder->cpb_length_bits) { + GST_DEBUG ("HRD CPB size: %u bits", cpb_size); + encoder->cpb_length_bits = cpb_size; + encoder->config_changed = TRUE; + } +} + +/* Estimates a good enough bitrate if none was supplied */ +static void +ensure_bitrate (GstVaapiEncoderH264Fei * encoder) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + + /* Default compression: 48 bits per macroblock in "high-compression" mode */ + switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { + case GST_VAAPI_RATECONTROL_CBR: + case GST_VAAPI_RATECONTROL_VBR: + case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: + if (!base_encoder->bitrate) { + /* According to the literature and testing, CABAC entropy coding + mode could provide for +10% to +18% improvement in general, + thus estimating +15% here ; and using adaptive 8x8 transforms + in I-frames could bring up to +10% improvement. */ + guint bits_per_mb = 48; + guint64 factor; + + if (!encoder->use_cabac) + bits_per_mb += (bits_per_mb * 15) / 100; + if (!encoder->use_dct8x8) + bits_per_mb += (bits_per_mb * 10) / 100; + + factor = encoder->mb_width * encoder->mb_height * bits_per_mb; + base_encoder->bitrate = + gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder), + GST_VAAPI_ENCODER_FPS_D (encoder)) / 1000; + GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate); + } + break; + default: + base_encoder->bitrate = 0; + break; + } + ensure_bitrate_hrd (encoder); +} + +/* Constructs profile and level information based on user-defined limits */ +static GstVaapiEncoderStatus +ensure_profile_and_level (GstVaapiEncoderH264Fei * encoder) +{ + const GstVaapiProfile profile = encoder->profile; + const GstVaapiLevelH264 level = encoder->level; + + if (!ensure_tuning (encoder)) + GST_WARNING ("Failed to set some of the tuning option as expected! "); + + if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + /* Check HW constraints */ + if (!ensure_hw_profile_limits (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + if (encoder->profile_idc > encoder->hw_max_profile_idc) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + /* Ensure bitrate if not set already and derive the right level to use */ + ensure_bitrate (encoder); + if (!ensure_level (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + + if (encoder->profile != profile || encoder->level != level) { + GST_DEBUG ("selected %s profile at level %s", + gst_vaapi_utils_h264_get_profile_string (encoder->profile), + gst_vaapi_utils_h264_get_level_string (encoder->level)); + encoder->config_changed = TRUE; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static void +reset_properties (GstVaapiEncoderH264Fei * encoder) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + guint mb_size, i; + + if (encoder->idr_period < base_encoder->keyframe_period) + encoder->idr_period = base_encoder->keyframe_period; + if (encoder->idr_period > MAX_IDR_PERIOD) + encoder->idr_period = MAX_IDR_PERIOD; + + if (encoder->min_qp > encoder->init_qp || + (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP && + encoder->min_qp < encoder->init_qp)) + encoder->min_qp = encoder->init_qp; + + mb_size = encoder->mb_width * encoder->mb_height; + if (encoder->num_slices > (mb_size + 1) / 2) + encoder->num_slices = (mb_size + 1) / 2; + g_assert (encoder->num_slices); + + if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) + encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; + + /* Workaround : vaapi-intel-driver doesn't have support for + * B-frame encode when utilizing low-power encode hardware block. + * So Disabling b-frame encoding in low-pwer encode. + * + * Fixme :We should query the VAConfigAttribEncMaxRefFrames + * instead of blindly disabling b-frame support and set b/p frame count, + * buffer pool size etc based on that.*/ + if ((encoder->num_bframes > 0) + && (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)) { + GST_WARNING + ("Disabling b-frame since the driver doesn't supporting it in low-power encode"); + encoder->num_bframes = 0; + } + + if (encoder->num_bframes > 0 && GST_VAAPI_ENCODER_FPS_N (encoder) > 0) + encoder->cts_offset = gst_util_uint64_scale (GST_SECOND, + GST_VAAPI_ENCODER_FPS_D (encoder), GST_VAAPI_ENCODER_FPS_N (encoder)); + else + encoder->cts_offset = 0; + + /* init max_frame_num, max_poc */ + encoder->log2_max_frame_num = + h264_get_log2_max_frame_num (encoder->idr_period); + g_assert (encoder->log2_max_frame_num >= 4); + encoder->max_frame_num = (1 << encoder->log2_max_frame_num); + encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1; + encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); + encoder->idr_num = 0; + + for (i = 0; i < encoder->num_views; i++) { + GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[i]; + + ref_pool->max_reflist0_count = 1; + ref_pool->max_reflist1_count = encoder->num_bframes > 0; + ref_pool->max_ref_frames = ref_pool->max_reflist0_count + + ref_pool->max_reflist1_count; + + reorder_pool->frame_index = 0; + } +} + +static gboolean +copy_picture_attrib (GstVaapiEncPicture * dst, GstVaapiEncPicture * src) +{ + if (!dst || !src) + return FALSE; + + dst->proxy = src->proxy; + dst->surface = src->surface; + dst->type = src->type; + dst->surface_id = src->surface_id; + dst->frame_num = src->frame_num; + dst->poc = src->poc; + + return TRUE; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_fei_encode (GstVaapiEncoder * base_encoder, + GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); + GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + GstVaapiSurfaceProxy *reconstruct = NULL; + GstVaapiEncPicture *picture2 = NULL; + GstVaapiFeiInfoToPakH264 info_to_pak; + + reconstruct = gst_vaapi_encoder_create_surface (base_encoder); + + g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct)); + + if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK) + || (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC) + || (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK)) { + + if (!ensure_sequence (encoder, picture)) + goto error; + if (!ensure_misc_params (encoder, picture)) + goto error; + if (!encoder->is_fei_disabled + && !ensure_fei_misc_params (encoder, picture, codedbuf)) + goto error; + if (!ensure_picture (encoder, picture, codedbuf, reconstruct)) + goto error; + if (!ensure_slices (encoder, picture)) + goto error; + if (!gst_vaapi_enc_picture_encode (picture)) + goto error; + + if (!reference_list_update (encoder, picture, reconstruct)) + goto error; + + } else if (encoder->fei_mode == + (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) { + /* + * ref pool is managed by pak. + * enc will copy from it. + */ + if (picture->type != GST_VAAPI_PICTURE_TYPE_I + && !gst_vaapi_feipak_h264_get_ref_pool (encoder->feipak, + &encoder->ref_pool_ptr)) { + GST_ERROR ("failed to get pak ref pool"); + status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + goto error; + } + + if (picture->type != GST_VAAPI_PICTURE_TYPE_I + && !gst_vaapi_feienc_h264_set_ref_pool (encoder->feienc, + encoder->ref_pool_ptr)) { + GST_ERROR ("failed to set enc ref pool"); + status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + goto error; + } + + status = + gst_vaapi_feienc_h264_encode (enc_base_encoder, picture, reconstruct, + codedbuf, &info_to_pak); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + GST_ERROR ("failed to process enc class encode"); + goto error; + } + + /* duplicate a picture for pak */ + picture2 = GST_VAAPI_ENC_PICTURE_NEW (H264, base_encoder, picture->frame); + if (!picture2) { + GST_WARNING ("create H264 picture failed, frame timestamp:%" + GST_TIME_FORMAT, GST_TIME_ARGS (picture->frame->pts)); + status = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + goto error; + } + if (!copy_picture_attrib (picture2, picture)) { + status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + goto error; + } + /* need set picture IDR info for PAK */ + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + GST_VAAPI_ENC_PICTURE_FLAG_SET (picture2, GST_VAAPI_ENC_PICTURE_FLAG_IDR); + + status = + gst_vaapi_feipak_h264_encode (encoder->feipak, picture2, codedbuf, + reconstruct, &info_to_pak); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + GST_ERROR ("failed to process pak class encode"); + goto error; + } + + /* Free the slice array */ + if (info_to_pak.h264_slice_headers) + g_array_free (info_to_pak.h264_slice_headers, TRUE); + + gst_vaapi_enc_picture_unref (picture2); + + } + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +error: + { + if (reconstruct) + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); + if (picture2) + gst_vaapi_enc_picture_unref (picture2); + return status; + } +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_fei_flush (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); + GstVaapiH264ViewReorderPool *reorder_pool; + GstVaapiEncPicture *pic; + GstVaapiEncoderStatus status; + guint i; + + if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK) + || (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK)) { + for (i = 0; i < encoder->num_views; i++) { + reorder_pool = &encoder->reorder_pools[i]; + reorder_pool->frame_index = 0; + reorder_pool->cur_frame_num = 0; + reorder_pool->cur_present_index = 0; + + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&reorder_pool->reorder_frame_list); + } + } else if (encoder->fei_mode == + (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) { + + status = gst_vaapi_feienc_h264_flush (enc_base_encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + GST_ERROR ("failed to process enc class flush"); + return status; + } + + status = gst_vaapi_feipak_h264_flush (encoder->feipak); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + GST_ERROR ("failed to process pak class flush"); + return status; + } + } else { + g_assert (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC); + } + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +/* Generate "codec-data" buffer */ +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_fei_get_codec_data (GstVaapiEncoder * base_encoder, + GstBuffer ** out_buffer_ptr) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + const guint32 configuration_version = 0x01; + const guint32 nal_length_size = 4; + guint8 profile_idc, profile_comp, level_idc; + GstMapInfo sps_info, pps_info; + GstBitWriter bs; + GstBuffer *buffer; + + if (!encoder->sps_data || !encoder->pps_data) + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER; + if (gst_buffer_get_size (encoder->sps_data) < 4) + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER; + + if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ)) + goto error_map_sps_buffer; + + if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ)) + goto error_map_pps_buffer; + + /* skip sps_data[0], which is the nal_unit_type */ + profile_idc = sps_info.data[1]; + profile_comp = sps_info.data[2]; + level_idc = sps_info.data[3]; + + /* Header */ + gst_bit_writer_init (&bs, (sps_info.size + pps_info.size + 64) * 8); + WRITE_UINT32 (&bs, configuration_version, 8); + WRITE_UINT32 (&bs, profile_idc, 8); + WRITE_UINT32 (&bs, profile_comp, 8); + WRITE_UINT32 (&bs, level_idc, 8); + WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */ + WRITE_UINT32 (&bs, nal_length_size - 1, 2); + WRITE_UINT32 (&bs, 0x07, 3); /* 111 */ + + /* Write SPS */ + WRITE_UINT32 (&bs, 1, 5); /* SPS count = 1 */ + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + WRITE_UINT32 (&bs, sps_info.size, 16); + gst_bit_writer_put_bytes (&bs, sps_info.data, sps_info.size); + + /* Write PPS */ + WRITE_UINT32 (&bs, 1, 8); /* PPS count = 1 */ + WRITE_UINT32 (&bs, pps_info.size, 16); + gst_bit_writer_put_bytes (&bs, pps_info.data, pps_info.size); + + gst_buffer_unmap (encoder->pps_data, &pps_info); + gst_buffer_unmap (encoder->sps_data, &sps_info); + + buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&bs), + GST_BIT_WRITER_BIT_SIZE (&bs) / 8); + if (!buffer) + goto error_alloc_buffer; + *out_buffer_ptr = buffer; + + gst_bit_writer_clear (&bs, FALSE); + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +bs_error: + { + GST_ERROR ("failed to write codec-data"); + gst_buffer_unmap (encoder->sps_data, &sps_info); + gst_buffer_unmap (encoder->pps_data, &pps_info); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +error_map_sps_buffer: + { + GST_ERROR ("failed to map SPS packed header"); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_map_pps_buffer: + { + GST_ERROR ("failed to map PPS packed header"); + gst_buffer_unmap (encoder->sps_data, &sps_info); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_alloc_buffer: + { + GST_ERROR ("failed to allocate codec-data buffer"); + gst_bit_writer_clear (&bs, TRUE); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_fei_reordering (GstVaapiEncoder * base_encoder, + GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + GstVaapiH264ViewReorderPool *reorder_pool = NULL; + GstVaapiEncPicture *picture; + gboolean is_idr = FALSE; + + *output = NULL; + + if ((encoder->fei_mode != GST_VAAPI_FEI_MODE_ENC_PAK) + && (encoder->fei_mode != GST_VAAPI_FEI_MODE_PAK)) { + GstVaapiEncoder *enc_base_encoder = + GST_VAAPI_ENCODER_CAST (encoder->feienc); + GstVaapiEncoderStatus status; + + status = gst_vaapi_feienc_h264_reordering (enc_base_encoder, frame, output); + if ((status != GST_VAAPI_ENCODER_STATUS_SUCCESS) && + (status != GST_VAAPI_ENCODER_STATUS_NO_SURFACE)) + GST_ERROR ("failed to process enc reordering"); + + return status; + } + + /* encoding views alternatively for MVC */ + if (encoder->is_mvc) { + /* FIXME: Use first-in-bundle flag on buffers to reset view idx? */ + if (frame) + encoder->view_idx = frame->system_frame_number % encoder->num_views; + else + encoder->view_idx = (encoder->view_idx + 1) % encoder->num_views; + } + reorder_pool = &encoder->reorder_pools[encoder->view_idx]; + + if (!frame) { + if (reorder_pool->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES) + return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; + + /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES + dump B frames from queue, sometime, there may also have P frame or I frame */ + g_assert (encoder->num_bframes > 0); + g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list), + GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN); + picture = g_queue_pop_head (&reorder_pool->reorder_frame_list); + g_assert (picture); + if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; + } + goto end; + } + + /* new frame coming */ + picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame); + if (!picture) { + GST_WARNING ("create H264 picture failed, frame timestamp:%" + GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } + ++reorder_pool->cur_present_index; + picture->poc = ((reorder_pool->cur_present_index * 2) % + encoder->max_pic_order_cnt); + + is_idr = (reorder_pool->frame_index == 0 || + reorder_pool->frame_index >= encoder->idr_period); + + /* check key frames */ + if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) || + (reorder_pool->frame_index % + GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == 0) { + ++reorder_pool->cur_frame_num; + ++reorder_pool->frame_index; + + /* b frame enabled, check queue of reorder_frame_list */ + if (encoder->num_bframes + && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + GstVaapiEncPicture *p_pic; + + p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list); + set_p_frame (p_pic, encoder); + g_queue_foreach (&reorder_pool->reorder_frame_list, + (GFunc) set_b_frame, encoder); + ++reorder_pool->cur_frame_num; + set_key_frame (picture, encoder, is_idr); + g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); + picture = p_pic; + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; + } else { /* no b frames in queue */ + set_key_frame (picture, encoder, is_idr); + g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list)); + if (encoder->num_bframes) + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; + } + goto end; + } + + /* new p/b frames coming */ + ++reorder_pool->frame_index; + if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES && + g_queue_get_length (&reorder_pool->reorder_frame_list) < + encoder->num_bframes) { + g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); + return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; + } + + ++reorder_pool->cur_frame_num; + set_p_frame (picture, encoder); + + if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) { + g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame, + encoder); + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; + g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list)); + } + +end: + g_assert (picture); + frame = picture->frame; + if (GST_CLOCK_TIME_IS_VALID (frame->pts)) + frame->pts += encoder->cts_offset; + *output = picture; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static GstVaapiEncoderStatus +set_context_info (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); + const guint DEFAULT_SURFACES_COUNT = 3; + + /* Maximum sizes for common headers (in bits) */ + enum + { + MAX_SPS_HDR_SIZE = 16473, + MAX_VUI_PARAMS_SIZE = 210, + MAX_HRD_PARAMS_SIZE = 4103, + MAX_PPS_HDR_SIZE = 101, + MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402, + }; + + if (!ensure_hw_profile (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + base_encoder->num_ref_frames = + ((encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT) + * encoder->num_views; + + /* Only YUV 4:2:0 formats are supported for now. This means that we + have a limit of 3200 bits per macroblock. */ + /* XXX: check profile and compute RawMbBits */ + base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) * + GST_ROUND_UP_16 (vip->height) / 256) * 400; + + /* Account for SPS header */ + /* XXX: exclude scaling lists, MVC/SVC extensions */ + base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE + + MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8; + + /* Account for PPS header */ + /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */ + base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8; + + /* Account for slice header */ + base_encoder->codedbuf_size += encoder->num_slices * (4 + + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); + + base_encoder->context_info.entrypoint = encoder->entrypoint; + + /* Fixme: Add a method to get VA_FEI_FUNCTION_* from GstVaapiFeiMode */ + base_encoder->context_info.config.encoder.fei_function = encoder->fei_mode; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static gboolean +copy_encoder_common_property (GstVaapiEncoder * dst, GstVaapiEncoder * src) +{ + if (!dst || !src) + return FALSE; + + dst->tune = src->tune; + dst->rate_control = src->rate_control; + dst->rate_control_mask = src->rate_control_mask; + dst->bitrate = src->bitrate; + dst->keyframe_period = src->keyframe_period; + + return TRUE; +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_fei_reconfigure (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); + GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); + GstVideoInfo *vip_enc = GST_VAAPI_ENCODER_VIDEO_INFO (encoder->feienc); + GstVaapiEncoderStatus status; + guint mb_width, mb_height; + const guint DEFAULT_SURFACES_COUNT = 3; + + if (encoder->fei_mode != (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) { + /* ENC_PAK, ENC and PAK modes doesn't need to care about ENC and PAK + * abstrct objects */ + mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; + mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; + if (mb_width != encoder->mb_width || mb_height != encoder->mb_height) { + GST_DEBUG ("resolution: %dx%d", GST_VAAPI_ENCODER_WIDTH (encoder), + GST_VAAPI_ENCODER_HEIGHT (encoder)); + encoder->mb_width = mb_width; + encoder->mb_height = mb_height; + encoder->config_changed = TRUE; + } + + /* Take number of MVC views from input caps if provided */ + if (GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == + GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME + || GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == + GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME) + encoder->num_views = GST_VIDEO_INFO_VIEWS (vip); + + encoder->is_mvc = encoder->num_views > 1; + + status = ensure_profile_and_level (encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + + reset_properties (encoder); + status = set_context_info (base_encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + + } else { + /* ENC+PAK mode requires two separate objects + for ENC and PAK */ + + /* Maximum sizes for common headers (in bits) */ + enum + { + MAX_SPS_HDR_SIZE = 16473, + MAX_VUI_PARAMS_SIZE = 210, + MAX_HRD_PARAMS_SIZE = 4103, + MAX_PPS_HDR_SIZE = 101, + MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402, + }; + + /* copy encoder-fei common property to feienc */ + if (!copy_encoder_common_property (enc_base_encoder, base_encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + + /* copy video info to feienc */ + *vip_enc = *vip; + + status = gst_vaapi_feienc_h264_reconfigure (enc_base_encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + GST_ERROR ("failed to process enc reconfigure"); + return status; + } + + if (!gst_vaapi_feienc_h264_get_profile_and_idc (encoder->feienc, + &encoder->profile, &encoder->profile_idc)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + + base_encoder->profile = enc_base_encoder->profile; + + mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; + mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; + if (mb_width != encoder->mb_width || mb_height != encoder->mb_height) { + GST_DEBUG ("resolution: %dx%d", GST_VAAPI_ENCODER_WIDTH (encoder), + GST_VAAPI_ENCODER_HEIGHT (encoder)); + encoder->mb_width = mb_width; + encoder->mb_height = mb_height; + encoder->config_changed = TRUE; + } + + status = + gst_vaapi_feipak_h264_reconfigure (encoder->feipak, + base_encoder->va_context, encoder->profile, encoder->profile_idc, + encoder->mb_width, encoder->mb_height, encoder->num_views, + encoder->num_slices, encoder->num_ref_frames); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + GST_ERROR ("failed to process pak reconfigure"); + return status; + } + + base_encoder->num_ref_frames = + (encoder->num_ref_frames + DEFAULT_SURFACES_COUNT) * encoder->num_views; + + /* Only YUV 4:2:0 formats are supported for now. This means that we + have a limit of 3200 bits per macroblock. */ + /* XXX: check profile and compute RawMbBits */ + base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) * + GST_ROUND_UP_16 (vip->height) / 256) * 400; + + /* Account for SPS header */ + /* XXX: exclude scaling lists, MVC/SVC extensions */ + base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE + + MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8; + + /* Account for PPS header */ + /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */ + base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8; + + /* Account for slice header */ + base_encoder->codedbuf_size += encoder->num_slices * (4 + + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); + + base_encoder->context_info.entrypoint = encoder->entrypoint; + + /* ENC+PAK mode use the base encoder context for PAK + * ENC handled separately */ + if (encoder->fei_mode == (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) + base_encoder->context_info.config.encoder.fei_function = + GST_VAAPI_FEI_MODE_PAK; + } + + return status; +} + +static gboolean +gst_vaapi_encoder_h264_fei_init (GstVaapiEncoder * base_encoder) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + guint32 i; + + /* Default encoding entrypoint */ + encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + encoder->is_fei_disabled = FALSE; + encoder->is_stats_out_enabled = FALSE; + encoder->fei_mode = GST_VAAPI_FEI_MODE_ENC_PAK; + encoder->search_path = GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT; + encoder->len_sp = GST_VAAPI_FEI_H264_SEARCH_PATH_LENGTH_DEFAULT; + encoder->ref_width = GST_VAAPI_FEI_H264_REF_WIDTH_DEFAULT; + encoder->ref_height = GST_VAAPI_FEI_H264_REF_HEIGHT_DEFAULT; + encoder->intra_part_mask = GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT; + encoder->submb_part_mask = GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT; + /* default num ref frames */ + encoder->num_ref_frames = 1; + /* Multi-view coding information */ + encoder->is_mvc = FALSE; + encoder->num_views = 1; + encoder->view_idx = 0; + memset (encoder->view_ids, 0, sizeof (encoder->view_ids)); + + /* re-ordering list initialize */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[i]; + g_queue_init (&reorder_pool->reorder_frame_list); + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE; + reorder_pool->frame_index = 0; + reorder_pool->cur_frame_num = 0; + reorder_pool->cur_present_index = 0; + } + + /* reference list info initialize */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; + g_queue_init (&ref_pool->ref_list); + ref_pool->max_ref_frames = 0; + ref_pool->max_reflist0_count = 1; + ref_pool->max_reflist1_count = 1; + } + + return TRUE; +} + +static void +gst_vaapi_encoder_h264_fei_finalize (GstVaapiEncoder * base_encoder) +{ + /*free private buffers */ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); + GstVaapiMiniObject *object = GST_VAAPI_MINI_OBJECT (encoder->feipak); + GstVaapiEncPicture *pic; + GstVaapiEncoderH264FeiRef *ref; + guint32 i; + + if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK) + || (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK)) { + + gst_buffer_replace (&encoder->sps_data, NULL); + gst_buffer_replace (&encoder->subset_sps_data, NULL); + gst_buffer_replace (&encoder->pps_data, NULL); + + /* reference list info de-init */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; + while (!g_queue_is_empty (&ref_pool->ref_list)) { + ref = (GstVaapiEncoderH264FeiRef *) + g_queue_pop_head (&ref_pool->ref_list); + reference_pic_free (encoder, ref); + } + g_queue_clear (&ref_pool->ref_list); + } + + /* re-ordering list initialize */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264ViewReorderPool *const reorder_pool = + &encoder->reorder_pools[i]; + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&reorder_pool->reorder_frame_list); + } + + } else { + if (encoder->coded_buf != VA_INVALID_ID) { + GST_VAAPI_DISPLAY_LOCK (base_encoder->display); + vaapi_destroy_buffer (base_encoder->va_display, &encoder->coded_buf); + GST_VAAPI_DISPLAY_UNLOCK (base_encoder->display); + encoder->coded_buf = VA_INVALID_ID; + } + + if (enc_base_encoder->va_context != VA_INVALID_ID) { + GST_VAAPI_DISPLAY_LOCK (base_encoder->display); + vaDestroyContext (base_encoder->va_display, enc_base_encoder->va_context); + GST_VAAPI_DISPLAY_UNLOCK (base_encoder->display); + enc_base_encoder->va_context = VA_INVALID_ID; + } + + if (encoder->va_config != VA_INVALID_ID) { + GST_VAAPI_DISPLAY_LOCK (base_encoder->display); + vaDestroyConfig (base_encoder->va_display, encoder->va_config); + GST_VAAPI_DISPLAY_UNLOCK (base_encoder->display); + encoder->va_config = VA_INVALID_ID; + } + + gst_vaapi_encoder_replace (&enc_base_encoder, NULL); + gst_vaapi_mini_object_replace (&object, NULL); + + encoder->ref_pool_ptr = NULL; + encoder->feienc = NULL; + } +} + +static GstVaapiEncoderStatus +gst_vaapi_encoder_h264_fei_set_property (GstVaapiEncoder * base_encoder, + gint prop_id, const GValue * value) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); + GstVaapiEncoderStatus status; + + switch (prop_id) { + case GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_BFRAMES: + encoder->num_bframes = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_FEI_PROP_INIT_QP: + encoder->init_qp = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_FEI_PROP_MIN_QP: + encoder->min_qp = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_SLICES: + encoder->num_slices = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_FEI_PROP_CABAC: + encoder->use_cabac = g_value_get_boolean (value); + break; + case GST_VAAPI_ENCODER_H264_FEI_PROP_DCT8X8: + encoder->use_dct8x8 = g_value_get_boolean (value); + break; + case GST_VAAPI_ENCODER_H264_FEI_PROP_CPB_LENGTH: + encoder->cpb_length = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS: + encoder->num_views = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS:{ + guint i; + GValueArray *view_ids = g_value_get_boxed (value); + + if (view_ids == NULL) { + for (i = 0; i < encoder->num_views; i++) + encoder->view_ids[i] = i; + } else { + g_assert (view_ids->n_values <= encoder->num_views); + + for (i = 0; i < encoder->num_views; i++) { + GValue *val = g_value_array_get_nth (view_ids, i); + encoder->view_ids[i] = g_value_get_uint (val); + } + } + break; + } + case GST_VAAPI_ENCODER_H264_PROP_FEI_DISABLE: + encoder->is_fei_disabled = g_value_get_boolean (value); + if (!encoder->is_fei_disabled) + encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI; + break; + case GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L0: + encoder->num_mv_predictors_l0 = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L1: + encoder->num_mv_predictors_l1 = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_SEARCH_WINDOW: + encoder->search_window = g_value_get_enum (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_LEN_SP: + encoder->len_sp = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_SEARCH_PATH: + encoder->search_path = g_value_get_enum (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_REF_WIDTH: + encoder->ref_width = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_REF_HEIGHT: + encoder->ref_height = g_value_get_uint (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_SUBMB_MASK: + encoder->submb_part_mask = g_value_get_flags (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_SUBPEL_MODE: + encoder->subpel_mode = g_value_get_enum (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_INTRA_PART_MASK: + encoder->intra_part_mask = g_value_get_flags (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_INTRA_SAD: + encoder->intra_sad = g_value_get_enum (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_INTER_SAD: + encoder->inter_sad = g_value_get_enum (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_ADAPT_SEARCH: + encoder->adaptive_search = g_value_get_boolean (value) ? 1 : 0; + break; + case GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L0: + encoder->multi_predL0 = g_value_get_boolean (value) ? 1 : 0; + break; + case GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L1: + encoder->multi_predL1 = g_value_get_boolean (value) ? 1 : 0; + break; + case GST_VAAPI_ENCODER_H264_PROP_ENABLE_STATS_OUT: + encoder->is_stats_out_enabled = g_value_get_boolean (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_FEI_MODE: + encoder->fei_mode = g_value_get_flags (value); + if (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC) { + g_warning ("============= ENC only mode selected ============ \n" + "We internally run the PAK stage because, the ENC operation requires the reconstructed output of PAK mode. Right now we have no infrastructure to provide reconstructed surfaces to ENC with out running the PAK \n"); + /*Fixme: Support ENC only mode with out running PAK */ + encoder->fei_mode = GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK; + } else if (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK) { + g_warning ("============ PAK only mode selected ============ \n" + "This mode can work as expected, only if there is a custom user specific upstream element which provides mb_code and mv_vectors. If you are running the pipeline only for verification, We recommand to use the fei-mod ENC+PAK which will run the ENC operation and generate what ever input needed for PAK \n"); + } + + break; + + default: + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } + + if ((prop_id != GST_VAAPI_ENCODER_H264_PROP_FEI_MODE) && + (prop_id != GST_VAAPI_ENCODER_H264_PROP_FEI_DISABLE) && + (prop_id != GST_VAAPI_ENCODER_H264_PROP_ENABLE_STATS_OUT)) { + + if (enc_base_encoder) { + status = + gst_vaapi_feienc_h264_set_property (enc_base_encoder, prop_id, value); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + GST_ERROR ("failed to set enc property"); + return status; + } + } + + if ((prop_id == GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_BFRAMES) || + (prop_id == GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS) || + (prop_id == GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS)) { + if (encoder->feipak) { + status = + gst_vaapi_feipak_h264_set_property (encoder->feipak, prop_id, + value); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + GST_ERROR ("failed to set pak property"); + return status; + } + } + } + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + + +static inline gboolean +context_get_attribute (GstVaapiContext * context, VAConfigAttribType type, + guint * out_value_ptr) +{ + return gst_vaapi_get_config_attribute (GST_VAAPI_OBJECT_DISPLAY (context), + context->va_profile, context->va_entrypoint, type, out_value_ptr); +} + +static gboolean +create_context_for_enc (GstVaapiEncoder * fei_encoder, + GstVaapiEncoder * enc_encoder) +{ + GstVaapiEncoderH264Fei *const feiencoder = + GST_VAAPI_ENCODER_H264_FEI (fei_encoder); + GstVaapiContext *context = fei_encoder->context; + const GstVaapiContextInfo *const cip = &context->info; + GstVaapiDisplay *const display = fei_encoder->display; + const GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; + guint va_rate_control; + VAConfigAttrib attribs[5], *attrib = attribs; + VASurfaceID surface_id; + VAStatus status; + GArray *surfaces = NULL; + gboolean success = FALSE; + guint i, value, va_chroma_format; + + if (!context->surfaces) + 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_OBJECT_ID (surface); + g_array_append_val (surfaces, surface_id); + } + g_assert (surfaces->len == context->surfaces->len); + if (!cip->profile || !cip->entrypoint) + goto cleanup; + + /* 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++; + + /* 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++; + } + + /* Packed headers */ + if (config->packed_headers) { + attrib->type = VAConfigAttribEncPackedHeaders; + attrib->value = VA_ENC_PACKED_HEADER_NONE; + attrib++; + } + + if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI) { + attrib->type = (VAConfigAttribType) VAConfigAttribFEIFunctionType; + attrib->value = VA_FEI_FUNCTION_ENC; + attrib++; + attrib->type = (VAConfigAttribType) VAConfigAttribFEIMVPredictors; + attrib->value = 1; + attrib++; + } + + GST_VAAPI_DISPLAY_LOCK (display); + status = vaCreateConfig (GST_VAAPI_DISPLAY_VADISPLAY (display), + context->va_profile, context->va_entrypoint, attribs, attrib - attribs, + &feiencoder->va_config); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaCreateConfig()")) + goto cleanup; + + GST_VAAPI_DISPLAY_LOCK (display); + status = vaCreateContext (GST_VAAPI_DISPLAY_VADISPLAY (display), + feiencoder->va_config, GST_ROUND_UP_16 (cip->width), + GST_ROUND_UP_16 (cip->height), VA_PROGRESSIVE, + (VASurfaceID *) surfaces->data, surfaces->len, &enc_encoder->va_context); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaCreateContext()")) + goto cleanup; + + success = TRUE; + +cleanup: + if (surfaces) + g_array_free (surfaces, TRUE); + return success; +} + +/** + * gst_vaapi_encoder_h264_get_fei_properties: + * + * Determines the set of common and H.264 Fei specific encoder properties. + * The caller owns an extra reference to the resulting array of + * #GstVaapiEncoderPropInfo elements, so it shall be released with + * g_ptr_array_unref() after usage. + * + * Return value: the set of encoder properties for #GstVaapiEncoderH264, + * or %NULL if an error occurred. + */ +static GPtrArray * +gst_vaapi_encoder_h264_get_fei_properties (GPtrArray * props) +{ + /** + * GstVaapiEncoderH264: disable-fei: + * + * Disable FEI mode Encode: disabling fei will results + * the encoder to use VAEntrypointEncSlice, which means + * vaapi-intel-driver will be using a different media kerenl. + * And most of the properties associated with this element + * will be non functional. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_FEI_DISABLE, + g_param_spec_boolean ("disable-fei", + "Disable FEI Mode Encode", + "Disable Flexible Encoding Infrasturcture", FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + + /** + * GstVaapiEncoderH264: stats-out: + * + * Enable outputting fei buffers MV, MBCode and Distortion. + * If enabled, encoder will allocate memory for these buffers + * and submit to the driver even for ENC_PAK mode so that + * the output data can be extraced for analysis after the + * complettion of each frame ncode + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_ENABLE_STATS_OUT, + g_param_spec_boolean ("stats-out", + "stats out", + "Enable stats out for fei", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:num_mv_predictors_l0: + * Indicate how many mv predictors should be used for l0 frames. + * Only valid if MVPredictor input has been enabled. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L0, + g_param_spec_uint ("num-mvpredict-l0", + "Num mv predict l0", + "Indicate how many predictors should be used for l0," + "only valid if MVPredictor input enabled", + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:num_mv_predictors_l1: + * Indicate how many mv predictors should be used for l1 frames. + * Only valid if MVPredictor input has been enabled. + * + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L1, + g_param_spec_uint ("num-mvpredict-l1", + "Num mv predict l1", + "Indicate how many predictors should be used for l1," + "only valid if MVPredictor input enabled", + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:search-window: + * Use predefined Search Window + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_SEARCH_WINDOW, + g_param_spec_enum ("search-window", + "search window", + "Specify one of the predefined search path", + GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:len-sp: + * Defines the maximum number of Search Units per reference. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_LEN_SP, + g_param_spec_uint ("len-sp", + "length of search path", + "This value defines number of search units in search path", + 1, 63, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:search-path: + * SearchPath defines the motion search method. + * Zero means full search, 1 indicate diamond search. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_SEARCH_PATH, + g_param_spec_enum ("search-path", + "search path", + "Specify search path", + GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, + GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:ref-width: + * Specifies the search region width in pixels. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_REF_WIDTH, + g_param_spec_uint ("ref-width", + "ref width", + "Width of search region in pixel, must be multiple of 4", + 4, 64, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:ref-height: + * Specifies the search region height in pixels. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_REF_HEIGHT, + g_param_spec_uint ("ref-height", + "ref height", + "Height of search region in pixel, must be multiple of 4", + 4, 32, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:submb-mask: + * Defines the bit-mask for disabling sub-partition + * + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_SUBMB_MASK, + g_param_spec_flags ("submbpart-mask", + "submb part mask", + "defines the bit-mask for disabling sub mb partition", + GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, + GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:subpel-mode: + * defines the half/quarter pel modes + * 00: integer mode searching + * 01: half-pel mode searching + * 11: quarter-pel mode searching + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_SUBPEL_MODE, + g_param_spec_enum ("subpel-mode", + "subpel mode", + "Sub pixel precision for motion estimation", + GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, + GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:intrapart-mask: + * Specifies which Luma Intra partition is enabled/disabled + * for intra mode decision + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_INTRA_PART_MASK, + g_param_spec_flags ("intrapart-mask", + "intra part mask", + "Specifies which Luma Intra partition is enabled/disabled for" + "intra mode decision", + GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, + GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:intra-sad: + * Specifies distortion measure adjustments used for + * the motion search SAD comparison. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_INTRA_SAD, + g_param_spec_enum ("intra-sad", + "intra sad", + "Specifies distortion measure adjustments used" + "in the motion search SAD comparison for intra MB", + GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:inter-sad: + * Specifies distortion measure adjustments used + * in the motion search SAD comparison for inter MB + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_INTER_SAD, + g_param_spec_enum ("inter-sad", + "inter sad", + "Specifies distortion measure adjustments used" + "in the motion search SAD comparison for inter MB", + GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:adaptive-search: + * Defines whether adaptive searching is enabled for IME + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_ADAPT_SEARCH, + g_param_spec_boolean ("adaptive-search", + "adaptive-search", + "Enable adaptive search", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:multi-predL0: + * When set to 1, neighbor MV will be used as predictor for list L0, + * otherwise no neighbor MV will be used as predictor + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L0, + g_param_spec_boolean ("multi-predL0", + "multi predL0", + "Enable multi prediction for ref L0 list, when set neighbor MV will be used" + "as predictor, no neighbor MV will be used otherwise", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:multi-predL1: + * When set to 1, neighbor MV will be used as predictor + * when set to 0, no neighbor MV will be used as predictor. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L1, + g_param_spec_boolean ("multi-predL1", + "multi predL1", + "Enable multi prediction for ref L1 list, when set neighbor MV will be used" + "as predictor, no neighbor MV will be used otherwise", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264Fei: fei-mode: + * + * Cose ENC, PAK, ENC_PAK, or ENC+PAK + * ENC: Only the Motion Estimation, no transformation or entropy coding + * PAK: transformation, quantization and entropy coding + * ENC_PAK: default mode, enc an pak are invoked by driver, middleware has + control over ENC input only + * ENC+PAK: enc and pak invoked separately, middleware has control over the ENC input, + ENC output, and PAK input + * Encoding mode which can be used for FEI + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_FEI_MODE, + g_param_spec_flags ("fei-mode", + "FEI Encoding Mode", + "Functional mode of FEI Encoding", + GST_VAAPI_TYPE_FEI_MODE, GST_VAAPI_FEI_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + return props; + +} + +static const GstVaapiEncoderClassData fei_encoder_class_data = { + .codec = GST_VAAPI_CODEC_H264, + .packed_headers = SUPPORTED_PACKED_HEADERS, + .rate_control_get_type = gst_vaapi_rate_control_get_type, + .default_rate_control = DEFAULT_RATECONTROL, + .rate_control_mask = SUPPORTED_RATECONTROLS, + .encoder_tune_get_type = gst_vaapi_encoder_tune_get_type, + .default_encoder_tune = GST_VAAPI_ENCODER_TUNE_NONE, + .encoder_tune_mask = SUPPORTED_TUNE_OPTIONS, +}; + +static inline const GstVaapiEncoderClass * +gst_vaapi_encoder_h264_fei_class (void) +{ + static const GstVaapiEncoderClass GstVaapiEncoderH264FeiClass = { + .parent_class = { + .size = sizeof (GstVaapiEncoderH264Fei), + .finalize = (GDestroyNotify) gst_vaapi_encoder_finalize, + } + , + .class_data = &fei_encoder_class_data, + .init = gst_vaapi_encoder_h264_fei_init, + .finalize = gst_vaapi_encoder_h264_fei_finalize, + .reconfigure = gst_vaapi_encoder_h264_fei_reconfigure, + .get_default_properties = gst_vaapi_encoder_h264_fei_get_default_properties, + .reordering = gst_vaapi_encoder_h264_fei_reordering, + .encode = gst_vaapi_encoder_h264_fei_encode, + .flush = gst_vaapi_encoder_h264_fei_flush, + .set_property = gst_vaapi_encoder_h264_fei_set_property, + .get_codec_data = gst_vaapi_encoder_h264_fei_get_codec_data, + .ensure_secondary_context = + gst_vaapi_encoder_h264_fei_ensure_secondary_context, + }; + return &GstVaapiEncoderH264FeiClass; +} + +/** + * gst_vaapi_encoder_h264_fei_get_default_properties: + * + * Determines the set of common and H.264 specific encoder properties. + * The caller owns an extra reference to the resulting array of + * #GstVaapiEncoderPropInfo elements, so it shall be released with + * g_ptr_array_unref() after usage. + * + * Return value: the set of encoder properties for #GstVaapiEncoderH264Fei, + * or %NULL if an error occurred. + */ +GPtrArray * +gst_vaapi_encoder_h264_fei_get_default_properties (void) +{ + const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h264_fei_class (); + GPtrArray *props; + + props = gst_vaapi_encoder_properties_get_default (klass); + if (!props) + return NULL; + + /** + * GstVaapiEncoderH264Fei:max-bframes: + * + * The number of B-frames between I and P. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_BFRAMES, + g_param_spec_uint ("max-bframes", + "Max B-Frames", "Number of B-frames between I and P", 0, 10, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264Fei:init-qp: + * + * The initial quantizer value. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_FEI_PROP_INIT_QP, + g_param_spec_uint ("init-qp", + "Initial QP", "Initial quantizer value", 1, 51, 26, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264Fei:min-qp: + * + * The minimum quantizer value. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_FEI_PROP_MIN_QP, + g_param_spec_uint ("min-qp", + "Minimum QP", "Minimum quantizer value", 1, 51, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264Fei:num-slices: + * + * The number of slices per frame. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_SLICES, + g_param_spec_uint ("num-slices", + "Number of Slices", + "Number of slices per frame", + 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264Fei:cabac: + * + * Enable CABAC entropy coding mode for improved compression ratio, + * at the expense that the minimum target profile is Main. Default + * is CAVLC entropy coding mode. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_FEI_PROP_CABAC, + g_param_spec_boolean ("cabac", + "Enable CABAC", + "Enable CABAC entropy coding mode", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264Fei:dct8x8: + * + * Enable adaptive use of 8x8 transforms in I-frames. This improves + * the compression ratio by the minimum target profile is High. + * Default is to use 4x4 DCT only. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_FEI_PROP_DCT8X8, + g_param_spec_boolean ("dct8x8", + "Enable 8x8 DCT", + "Enable adaptive use of 8x8 transforms in I-frames", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264Fei:cpb-length: + * + * The size of the CPB buffer in milliseconds. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_FEI_PROP_CPB_LENGTH, + g_param_spec_uint ("cpb-length", + "CPB Length", "Length of the CPB buffer in milliseconds", + 1, 10000, DEFAULT_CPB_LENGTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264Fei:num-views: + * + * The number of views for MVC encoding . + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS, + g_param_spec_uint ("num-views", + "Number of Views", + "Number of Views for MVC encoding", + 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264Fei:view-ids: + * + * The view ids for MVC encoding . + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS, + g_param_spec_value_array ("view-ids", + "View IDs", "Set of View Ids used for MVC encoding", + g_param_spec_uint ("view-id-value", "View id value", + "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + props = gst_vaapi_encoder_h264_get_fei_properties (props); + + return props; +} + +/** + * gst_vaapi_encoder_h264_fei_set_max_profile: + * @encoder: a #GstVaapiEncoderH264Fei + * @profile: an H.264 #GstVaapiProfile + * + * Notifies the @encoder to use coding tools from the supplied + * @profile at most. + * + * This means that if the minimal profile derived to + * support the specified coding tools is greater than this @profile, + * then an error is returned when the @encoder is configured. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_encoder_h264_fei_set_max_profile (GstVaapiEncoderH264Fei * + encoder, GstVaapiProfile profile) +{ + guint8 profile_idc; + + g_return_val_if_fail (encoder != NULL, FALSE); + g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE); + + if (encoder->fei_mode == (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) { + if (!gst_vaapi_feienc_h264_set_max_profile (encoder->feienc, profile)) + return FALSE; + return TRUE; + } + + if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264) + return FALSE; + + profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + if (!profile_idc) + return FALSE; + + encoder->max_profile_idc = profile_idc; + return TRUE; +} + +/** + * gst_vaapi_encoder_h264_fei_get_profile_and_level: + * @encoder: a #GstVaapiEncoderH264Fei + * @out_profile_ptr: return location for the #GstVaapiProfile + * @out_level_ptr: return location for the #GstVaapiLevelH264 + * + * Queries the H.264 @encoder for the active profile and level. That + * information is only constructed and valid after the encoder is + * configured, i.e. after the gst_vaapi_encoder_set_codec_state() + * function is called. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_encoder_h264_fei_get_profile_and_level (GstVaapiEncoderH264Fei * + encoder, GstVaapiProfile * out_profile_ptr, + GstVaapiLevelH264 * out_level_ptr) +{ + g_return_val_if_fail (encoder != NULL, FALSE); + + if (!encoder->profile || !encoder->level) + return FALSE; + + if (out_profile_ptr) + *out_profile_ptr = encoder->profile; + if (out_level_ptr) + *out_level_ptr = encoder->level; + return TRUE; +} + +/** + * gst_vaapi_encoder_h264_is_fei_stats_out_enabled + * @encoder: a #GstVaapiEncoderH264 + * + * check if fei output statis is needed + * + * Return value: %TRUE if output statistic is needed + */ +gboolean +gst_vaapi_encoder_h264_is_fei_stats_out_enabled (GstVaapiEncoderH264Fei * + encoder) +{ + return !encoder->is_fei_disabled && encoder->is_stats_out_enabled; +} + +/** + * gst_vaapi_encoder_h264_fei_get_function_mode + * @encoder: a #GstVaapiEncoderH264Fei + * + * return the configured FEI Encoding mode + * + * Return value: a #GstVaapiFeiMode + */ +GstVaapiFeiMode +gst_vaapi_encoder_h264_fei_get_function_mode (GstVaapiEncoderH264Fei * encoder) +{ + return encoder->fei_mode; +} + +/** + * gst_vaapi_encoder_h264_fei_set_function_mode + * @encoder: a #GstVaapiEncoderH264Fei + * + * set the configured FEI Encoding mode + * + */ +void +gst_vaapi_encoder_h264_fei_set_function_mode (GstVaapiEncoderH264Fei * encoder, + guint fei_mode) +{ + encoder->fei_mode = fei_mode; +} + +static gboolean +gst_vaapi_encoder_h264_fei_ensure_secondary_context (GstVaapiEncoder * + base_encoder) +{ + GstVaapiEncoderH264Fei *const feiencoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + GstVaapiEncoder *enc_base_encoder = + GST_VAAPI_ENCODER_CAST (feiencoder->feienc); + gboolean success; + + if (feiencoder->fei_mode != (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) + return TRUE; + + /* Create separate context for ENC */ + if (!create_context_for_enc (base_encoder, enc_base_encoder)) { + GST_ERROR ("create vacontext for enc failed.\n"); + return FALSE; + } + + /* + * create coded-buf for ENC. + * PAK coded-buf is created by parent encoder. + */ + success = + vaapi_create_buffer (enc_base_encoder->va_display, + enc_base_encoder->va_context, VAEncCodedBufferType, + base_encoder->codedbuf_size, NULL, &feiencoder->coded_buf, NULL); + if (!success) { + g_error ("failed to create coded buf for feienc.\n"); + return FALSE; + } + + return TRUE; +} + +/** + * gst_vaapi_encoder_h264_fei_new: + * @display: a #GstVaapiDisplay + * + * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the + * only supported output stream format is "byte-stream" format. + * + * Return value: the newly allocated #GstVaapiEncoder object + */ +GstVaapiEncoder * +gst_vaapi_encoder_h264_fei_new (GstVaapiDisplay * display) +{ + GstVaapiEncoder *base_encoder; + GstVaapiEncoderH264Fei *feiencoder; + GstVaapiFeiEncH264 *feienc; + GstVaapiFEIPakH264 *feipak; + + /* create FEIEncoderObject: Default mode of operation in ENC_PAK */ + base_encoder = + gst_vaapi_encoder_new (gst_vaapi_encoder_h264_fei_class (), display); + if (!base_encoder) + return NULL; + feiencoder = GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + + /* create an enc object */ + feienc = GST_VAAPI_FEI_H264_ENC (gst_vaapi_feienc_h264_new (display)); + if (!feienc) + return NULL; + + /* create a pak object */ + feipak = + gst_vaapi_feipak_h264_new (base_encoder, display, + base_encoder->va_context); + if (!feipak) + return NULL; + + feiencoder->feienc = feienc; + feiencoder->feipak = feipak; + + return base_encoder; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h new file mode 100644 index 0000000000..3622ed29bc --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h @@ -0,0 +1,112 @@ +/* + * gstvaapiencoder_h264_fei.h - H.264 FEI encoder + * + * Copyright (C) 2016-2017 Intel Corporation + * Author: Yi A Wang + * Author: Sreerenj Balachandran + * + * 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_FEI_H +#define GST_VAAPI_ENCODER_H264_FEI_H + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_VAAPI_ENCODER_H264_FEI(encoder) \ + ((GstVaapiEncoderH264Fei *) (encoder)) + +typedef struct _GstVaapiEncoderH264Fei GstVaapiEncoderH264Fei; + +/** + * GstVaapiEncoderH264FeiProp: + * @GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_BFRAMES: Number of B-frames between I + * and P (uint). + * @GST_VAAPI_ENCODER_H264_FEI_PROP_INIT_QP: Initial quantizer value (uint). + * @GST_VAAPI_ENCODER_H264_FEI_PROP_MIN_QP: Minimal quantizer value (uint). + * @GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_SLICES: Number of slices per frame (uint). + * @GST_VAAPI_ENCODER_H264_FEI_PROP_CABAC: Enable CABAC entropy coding mode (bool). + * @GST_VAAPI_ENCODER_H264_FEI_PROP_DCT8X8: Enable adaptive use of 8x8 + * transforms in I-frames (bool). + * @GST_VAAPI_ENCODER_H264_FEI_PROP_CPB_LENGTH: Length of the CPB buffer + * in milliseconds (uint). + * @GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS: Number of views per frame. + * @GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS: View IDs + * + * The set of H.264 encoder specific configurable properties. + */ +typedef enum { + GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_BFRAMES = -1, + GST_VAAPI_ENCODER_H264_FEI_PROP_INIT_QP = -2, + GST_VAAPI_ENCODER_H264_FEI_PROP_MIN_QP = -3, + GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_SLICES = -4, + GST_VAAPI_ENCODER_H264_FEI_PROP_CABAC = -5, + GST_VAAPI_ENCODER_H264_FEI_PROP_DCT8X8 = -6, + GST_VAAPI_ENCODER_H264_FEI_PROP_CPB_LENGTH = -7, + GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS = -8, + GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS = -9, + GST_VAAPI_ENCODER_H264_PROP_FEI_DISABLE= -11, + GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L0 = -12, + GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L1 = -13, + GST_VAAPI_ENCODER_H264_PROP_SEARCH_WINDOW = -14, + GST_VAAPI_ENCODER_H264_PROP_LEN_SP = -15, + GST_VAAPI_ENCODER_H264_PROP_SEARCH_PATH = -16, + GST_VAAPI_ENCODER_H264_PROP_REF_WIDTH = -17, + GST_VAAPI_ENCODER_H264_PROP_REF_HEIGHT = -18, + GST_VAAPI_ENCODER_H264_PROP_SUBMB_MASK = -19, + GST_VAAPI_ENCODER_H264_PROP_SUBPEL_MODE = -20, + GST_VAAPI_ENCODER_H264_PROP_INTRA_PART_MASK = -21, + GST_VAAPI_ENCODER_H264_PROP_INTRA_SAD = -22, + GST_VAAPI_ENCODER_H264_PROP_INTER_SAD = -23, + GST_VAAPI_ENCODER_H264_PROP_ADAPT_SEARCH = -24, + GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L0 = -25, + GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L1 = -26, + GST_VAAPI_ENCODER_H264_PROP_ENABLE_STATS_OUT = -27, + GST_VAAPI_ENCODER_H264_PROP_FEI_MODE = -28 + +} GstVaapiEncoderH264FeiProp; + +GstVaapiEncoder * +gst_vaapi_encoder_h264_fei_new (GstVaapiDisplay * display); + +GPtrArray * +gst_vaapi_encoder_h264_fei_get_default_properties (void); + +gboolean +gst_vaapi_encoder_h264_fei_set_max_profile (GstVaapiEncoderH264Fei * encoder, + GstVaapiProfile profile); + +gboolean +gst_vaapi_encoder_h264_fei_get_profile_and_level (GstVaapiEncoderH264Fei * encoder, + GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr); + +gboolean +gst_vaapi_encoder_h264_is_fei_stats_out_enabled (GstVaapiEncoderH264Fei * encoder); + +GstVaapiFeiMode +gst_vaapi_encoder_h264_fei_get_function_mode (GstVaapiEncoderH264Fei *encoder); + +void +gst_vaapi_encoder_h264_fei_set_function_mode (GstVaapiEncoderH264Fei * encoder, + guint fei_mode); + +G_END_DECLS + +#endif /*GST_VAAPI_ENCODER_H264_FEI_H */ diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c new file mode 100644 index 0000000000..4438a7fc81 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -0,0 +1,2264 @@ +/* + * gstvaapifeienc_h264.c - H264 FEI ENC + * + * Copyright (C) 2016-2018 Intel Corporation + * Author: Leilei Shang + * Author: Sreerenj Balachandran + * + * 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 + */ + +/* GValueArray has deprecated without providing an alternative in glib >= 2.32 + * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 + */ + +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#include "sysdeps.h" +#include +#include +#include +#include "gstvaapicompat.h" +#include "gstvaapiencoder_priv.h" +#include "gstvaapifeienc_h264.h" +#include "gstvaapiutils_h264_priv.h" +#include "gstvaapicodedbufferproxy_priv.h" +#include "gstvaapisurfaceproxy_priv.h" +#include "gstvaapisurface.h" +#include "gstvaapiutils.h" +#include +#define DEBUG 1 +#include "gstvaapidebug.h" + +/* Define the maximum number of views supported */ +#define MAX_NUM_VIEWS 10 + +/* Define the maximum value for view-id */ +#define MAX_VIEW_ID 1023 + +/* Define the maximum IDR period */ +#define MAX_IDR_PERIOD 512 + +/* Default CPB length (in milliseconds) */ +#define DEFAULT_CPB_LENGTH 1500 + +/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */ +#define SX_CPB_SIZE 4 + +/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ +#define SX_BITRATE 6 + +/* 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) | \ + GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) + +/* Supported set of tuning options, within this implementation */ +#define SUPPORTED_TUNE_OPTIONS \ + (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \ + GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION) | \ + 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 + +typedef struct +{ + GstVaapiSurfaceProxy *pic; + guint poc; + guint frame_num; +} GstVaapiFeiEncH264Ref; + +typedef enum +{ + GST_VAAPI_ENC_H264_REORD_NONE = 0, + GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1, + GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2 +} GstVaapiEncH264ReorderState; + +typedef struct _GstVaapiH264ViewRefPool +{ + GQueue ref_list; + guint max_ref_frames; + guint max_reflist0_count; + guint max_reflist1_count; +} GstVaapiH264ViewRefPool; + +typedef struct _GstVaapiH264ViewReorderPool +{ + GQueue reorder_frame_list; + guint reorder_state; + guint frame_index; + guint frame_count; /* monotonically increasing with in every idr period */ + guint cur_frame_num; + guint cur_present_index; +} GstVaapiH264ViewReorderPool; + +static inline gboolean +_poc_greater_than (guint poc1, guint poc2, guint max_poc) +{ + return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2); +} + +/* Get slice_type value for H.264 specification */ +static guint8 +h264_get_slice_type (GstVaapiPictureType type) +{ + switch (type) { + case GST_VAAPI_PICTURE_TYPE_I: + return GST_H264_I_SLICE; + case GST_VAAPI_PICTURE_TYPE_P: + return GST_H264_P_SLICE; + case GST_VAAPI_PICTURE_TYPE_B: + return GST_H264_B_SLICE; + default: + break; + } + return -1; +} + +/* Get log2_max_frame_num value for H.264 specification */ +static guint +h264_get_log2_max_frame_num (guint num) +{ + guint ret = 0; + + while (num) { + ++ret; + num >>= 1; + } + if (ret <= 4) + ret = 4; + else if (ret > 10) + ret = 10; + /* must be greater than 4 */ + return ret; +} + +/* Determines the cpbBrNalFactor based on the supplied profile */ +static guint +h264_get_cpb_nal_factor (GstVaapiProfile profile) +{ + guint f; + + /* Table A-2 */ + switch (profile) { + case GST_VAAPI_PROFILE_H264_HIGH: + f = 1500; + break; + case GST_VAAPI_PROFILE_H264_HIGH10: + f = 3600; + break; + case GST_VAAPI_PROFILE_H264_HIGH_422: + case GST_VAAPI_PROFILE_H264_HIGH_444: + f = 4800; + break; + case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH: + case GST_VAAPI_PROFILE_H264_STEREO_HIGH: + f = 1500; /* H.10.2.1 (r) */ + break; + default: + f = 1200; + break; + } + return f; +} + +/* ------------------------------------------------------------------------- */ +/* --- FEI Enc --- */ +/* ------------------------------------------------------------------------- */ + +#define GST_VAAPI_FEI_H264_ENC_CAST(feienc) \ + ((GstVaapiFeiEncH264 *)(feienc)) + +struct _GstVaapiFeiEncH264 +{ + GstVaapiEncoder parent_instance; + + GstVaapiProfile profile; + GstVaapiLevelH264 level; + GstVaapiEntrypoint entrypoint; + guint8 profile_idc; + guint8 max_profile_idc; + guint8 hw_max_profile_idc; + guint8 level_idc; + guint32 idr_period; + guint32 init_qp; + guint32 min_qp; + guint32 num_slices; + guint32 num_bframes; + guint32 mb_width; + guint32 mb_height; + gboolean use_cabac; + gboolean use_dct8x8; + GstClockTime cts_offset; + gboolean config_changed; + + /* frame, poc */ + guint32 max_frame_num; + guint32 log2_max_frame_num; + guint32 max_pic_order_cnt; + guint32 log2_max_pic_order_cnt; + guint32 idr_num; + guint8 pic_order_cnt_type; + guint8 delta_pic_order_always_zero_flag; + + GstBuffer *sps_data; + GstBuffer *subset_sps_data; + GstBuffer *pps_data; + + guint bitrate_bits; // bitrate (bits) + guint cpb_length; // length of CPB buffer (ms) + guint cpb_length_bits; // length of CPB buffer (bits) + guint32 num_ref_frames; // set reference frame num + + /* MVC */ + gboolean is_mvc; + guint32 view_idx; /* View Order Index (VOIdx) */ + guint32 num_views; + guint16 view_ids[MAX_NUM_VIEWS]; + GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS]; + GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS]; + + /*Fei frame level control */ + guint search_window; + guint len_sp; + guint search_path; + guint ref_width; + guint ref_height; + guint submb_part_mask; + guint subpel_mode; + guint intra_part_mask; + guint intra_sad; + guint inter_sad; + guint num_mv_predictors_l0; + guint num_mv_predictors_l1; + guint adaptive_search; + guint multi_predL0; + guint multi_predL1; +}; + +/* Determines the largest supported profile by the underlying hardware */ +static gboolean +ensure_hw_profile_limits (GstVaapiFeiEncH264 * feienc) +{ + GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (feienc); + GArray *profiles; + guint i, profile_idc, max_profile_idc; + + if (feienc->hw_max_profile_idc) + return TRUE; + + profiles = gst_vaapi_display_get_encode_profiles (display); + if (!profiles) + return FALSE; + + max_profile_idc = 0; + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index (profiles, GstVaapiProfile, i); + profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + if (!profile_idc) + continue; + if (max_profile_idc < profile_idc) + max_profile_idc = profile_idc; + } + g_array_unref (profiles); + + feienc->hw_max_profile_idc = max_profile_idc; + return TRUE; +} + +/* Derives the profile supported by the underlying hardware */ +static gboolean +ensure_hw_profile (GstVaapiFeiEncH264 * feienc) +{ + GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (feienc); + GstVaapiEntrypoint entrypoint = feienc->entrypoint; + GstVaapiProfile profile, profiles[4]; + guint i, num_profiles = 0; + + profiles[num_profiles++] = feienc->profile; + switch (feienc->profile) { + case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE: + profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE; + profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN; + // fall-through + case GST_VAAPI_PROFILE_H264_MAIN: + profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; + break; + default: + break; + } + + 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 (feienc)->profile = profile; + return TRUE; + + /* ERRORS */ +error_unsupported_profile: + { + GST_ERROR ("unsupported HW profile (0x%08x)", feienc->profile); + return FALSE; + } +} + +/* Check target decoder constraints */ +static gboolean +ensure_profile_limits (GstVaapiFeiEncH264 * feienc) +{ + GstVaapiProfile profile; + + if (!feienc->max_profile_idc + || feienc->profile_idc <= feienc->max_profile_idc) + return TRUE; + + GST_WARNING ("lowering coding tools to meet target decoder constraints"); + + profile = GST_VAAPI_PROFILE_UNKNOWN; + + /* Try Main profile coding tools */ + if (feienc->max_profile_idc < 100) { + feienc->use_dct8x8 = FALSE; + profile = GST_VAAPI_PROFILE_H264_MAIN; + } + + /* Try Constrained Baseline profile coding tools */ + if (feienc->max_profile_idc < 77) { + feienc->num_bframes = 0; + feienc->use_cabac = FALSE; + profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + } + + if (profile) { + feienc->profile = profile; + feienc->profile_idc = feienc->max_profile_idc; + } + return TRUE; +} + +/* Derives the minimum profile from the active coding tools */ +static gboolean +ensure_profile (GstVaapiFeiEncH264 * feienc) +{ + GstVaapiProfile profile; + + /* Always start from "constrained-baseline" profile for maximum + compatibility */ + profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + + /* Main profile coding tools */ + if (feienc->num_bframes > 0 || feienc->use_cabac) + profile = GST_VAAPI_PROFILE_H264_MAIN; + + /* High profile coding tools */ + if (feienc->use_dct8x8) + profile = GST_VAAPI_PROFILE_H264_HIGH; + + /* MVC profiles coding tools */ + if (feienc->num_views == 2) + profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH; + else if (feienc->num_views > 2) + profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH; + + feienc->profile = profile; + feienc->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + return TRUE; +} + +/* Derives the level from the currently set limits */ +static gboolean +ensure_level (GstVaapiFeiEncH264 * feienc) +{ + const guint cpb_factor = h264_get_cpb_nal_factor (feienc->profile); + const GstVaapiH264LevelLimits *limits_table; + guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS; + + PicSizeMbs = feienc->mb_width * feienc->mb_height; + MaxDpbMbs = PicSizeMbs * ((feienc->num_bframes) ? 2 : 1); + MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs, + GST_VAAPI_ENCODER_FPS_N (feienc), GST_VAAPI_ENCODER_FPS_D (feienc)); + + limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits); + for (i = 0; i < num_limits; i++) { + const GstVaapiH264LevelLimits *const limits = &limits_table[i]; + if (PicSizeMbs <= limits->MaxFS && + MaxDpbMbs <= limits->MaxDpbMbs && + MaxMBPS <= limits->MaxMBPS && (!feienc->bitrate_bits + || feienc->bitrate_bits <= (limits->MaxBR * cpb_factor)) && + (!feienc->cpb_length_bits || + feienc->cpb_length_bits <= (limits->MaxCPB * cpb_factor))) + break; + } + if (i == num_limits) + goto error_unsupported_level; + + feienc->level = limits_table[i].level; + feienc->level_idc = limits_table[i].level_idc; + return TRUE; + + /* ERRORS */ +error_unsupported_level: + { + GST_ERROR ("failed to find a suitable level matching codec config"); + return FALSE; + } +} + +/* Enable "high-compression" tuning options */ +static gboolean +ensure_tuning_high_compression (GstVaapiFeiEncH264 * feienc) +{ + guint8 profile_idc; + + if (!ensure_hw_profile_limits (feienc)) + return FALSE; + + profile_idc = feienc->hw_max_profile_idc; + if (feienc->max_profile_idc && feienc->max_profile_idc < profile_idc) + profile_idc = feienc->max_profile_idc; + + /* Tuning options to enable Main profile */ + if (profile_idc >= 77 && profile_idc != 88) { + feienc->use_cabac = TRUE; + if (!feienc->num_bframes) + feienc->num_bframes = 1; + } + + /* Tuning options to enable High profile */ + if (profile_idc >= 100) { + feienc->use_dct8x8 = TRUE; + } + return TRUE; +} + +/* Ensure tuning options */ +static gboolean +ensure_tuning (GstVaapiFeiEncH264 * feienc) +{ + gboolean success; + + switch (GST_VAAPI_ENCODER_TUNE (feienc)) { + case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: + success = ensure_tuning_high_compression (feienc); + break; + case GST_VAAPI_ENCODER_TUNE_LOW_POWER: + /* Set low-power encode entry point. If hardware doesn't have + * support, it will fail in ensure_hw_profile() in later stage. + * So not duplicating the profile/entrypont query mechanism + * here as a part of optimization */ + feienc->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; + success = TRUE; + break; + default: + success = TRUE; + break; + } + return success; +} + +/* Handle new GOP starts */ +static void +reset_gop_start (GstVaapiFeiEncH264 * feienc) +{ + GstVaapiH264ViewReorderPool *const reorder_pool = + &feienc->reorder_pools[feienc->view_idx]; + + reorder_pool->frame_index = 1; + reorder_pool->cur_frame_num = 0; + reorder_pool->cur_present_index = 0; + ++feienc->idr_num; +} + +/* Marks the supplied picture as a B-frame */ +static void +set_b_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc) +{ + GstVaapiH264ViewReorderPool *const reorder_pool = + &feienc->reorder_pools[feienc->view_idx]; + + g_assert (pic && feienc); + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_B; + pic->frame_num = (reorder_pool->cur_frame_num % feienc->max_frame_num); +} + +/* Marks the supplied picture as a P-frame */ +static void +set_p_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc) +{ + GstVaapiH264ViewReorderPool *const reorder_pool = + &feienc->reorder_pools[feienc->view_idx]; + + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_P; + pic->frame_num = (reorder_pool->cur_frame_num % feienc->max_frame_num); +} + +/* Marks the supplied picture as an I-frame */ +static void +set_i_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc) +{ + GstVaapiH264ViewReorderPool *const reorder_pool = + &feienc->reorder_pools[feienc->view_idx]; + + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_I; + pic->frame_num = (reorder_pool->cur_frame_num % feienc->max_frame_num); + + g_assert (pic->frame); + GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); +} + +/* Marks the supplied picture as an IDR frame */ +static void +set_idr_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc) +{ + g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); + pic->type = GST_VAAPI_PICTURE_TYPE_I; + pic->frame_num = 0; + pic->poc = 0; + GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR); + + g_assert (pic->frame); + GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); +} + +/* Marks the supplied picture a a key-frame */ +static void +set_key_frame (GstVaapiEncPicture * picture, + GstVaapiFeiEncH264 * feienc, gboolean is_idr) +{ + if (is_idr) { + reset_gop_start (feienc); + set_idr_frame (picture, feienc); + } else + set_i_frame (picture, feienc); +} + +/* Fills in VA HRD parameters */ +static void +fill_hrd_params (GstVaapiFeiEncH264 * feienc, VAEncMiscParameterHRD * hrd) +{ + if (feienc->bitrate_bits > 0) { + hrd->buffer_size = feienc->cpb_length_bits; + hrd->initial_buffer_fullness = hrd->buffer_size / 2; + } else { + hrd->buffer_size = 0; + hrd->initial_buffer_fullness = 0; + } +} + +/* Reference list */ +static gboolean +reference_list_init (GstVaapiFeiEncH264 * feienc, + GstVaapiEncPicture * picture, + GstVaapiFeiEncH264Ref ** reflist_0, + guint * reflist_0_count, + GstVaapiFeiEncH264Ref ** reflist_1, guint * reflist_1_count) +{ + GstVaapiFeiEncH264Ref *tmp; + GstVaapiH264ViewRefPool *const ref_pool = + &feienc->ref_pools[feienc->view_idx]; + GList *iter, *list_0_start = NULL, *list_1_start = NULL; + guint count; + + *reflist_0_count = 0; + *reflist_1_count = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_I) + return TRUE; + + iter = g_queue_peek_tail_link (&ref_pool->ref_list); + for (; iter; iter = g_list_previous (iter)) { + tmp = (GstVaapiFeiEncH264Ref *) iter->data; + g_assert (tmp && tmp->poc != picture->poc); + if (_poc_greater_than (picture->poc, tmp->poc, feienc->max_pic_order_cnt)) { + list_0_start = iter; + list_1_start = g_list_next (iter); + break; + } + } + + /* order reflist_0 */ + g_assert (list_0_start); + iter = list_0_start; + count = 0; + for (; iter; iter = g_list_previous (iter)) { + reflist_0[count] = (GstVaapiFeiEncH264Ref *) iter->data; + ++count; + } + *reflist_0_count = count; + + if (picture->type != GST_VAAPI_PICTURE_TYPE_B) + return TRUE; + + /* order reflist_1 */ + count = 0; + iter = list_1_start; + for (; iter; iter = g_list_next (iter)) { + reflist_1[count] = (GstVaapiFeiEncH264Ref *) iter->data; + ++count; + } + *reflist_1_count = count; + return TRUE; +} + +/* Fills in VA sequence parameter buffer */ +static gboolean +fill_sequence (GstVaapiFeiEncH264 * feienc, GstVaapiEncSequence * sequence) +{ + VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; + GstVaapiH264ViewRefPool *const ref_pool = + &feienc->ref_pools[feienc->view_idx]; + + memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264)); + seq_param->seq_parameter_set_id = feienc->view_idx; + seq_param->level_idc = feienc->level_idc; + seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (feienc); + seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (feienc); + seq_param->ip_period = 1 + feienc->num_bframes; + seq_param->ip_period = seq_param->intra_period > 1 ? + (1 + feienc->num_bframes) : 0; + seq_param->bits_per_second = feienc->bitrate_bits; + + seq_param->max_num_ref_frames = ref_pool->max_ref_frames; + seq_param->picture_width_in_mbs = feienc->mb_width; + seq_param->picture_height_in_mbs = feienc->mb_height; + + /*sequence field values */ + seq_param->seq_fields.value = 0; + seq_param->seq_fields.bits.chroma_format_idc = 1; + seq_param->seq_fields.bits.frame_mbs_only_flag = 1; + seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE; + seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE; + /* direct_8x8_inference_flag default false */ + seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE; + g_assert (feienc->log2_max_frame_num >= 4); + seq_param->seq_fields.bits.log2_max_frame_num_minus4 = + feienc->log2_max_frame_num - 4; + /* picture order count */ + feienc->pic_order_cnt_type = seq_param->seq_fields.bits.pic_order_cnt_type = + 0; + g_assert (feienc->log2_max_pic_order_cnt >= 4); + seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = + feienc->log2_max_pic_order_cnt - 4; + + seq_param->bit_depth_luma_minus8 = 0; + seq_param->bit_depth_chroma_minus8 = 0; + + /* not used if pic_order_cnt_type == 0 */ + if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { + feienc->delta_pic_order_always_zero_flag = + seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE; + seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0; + seq_param->offset_for_non_ref_pic = 0; + seq_param->offset_for_top_to_bottom_field = 0; + memset (seq_param->offset_for_ref_frame, 0, + sizeof (seq_param->offset_for_ref_frame)); + } + + /* frame_cropping_flag */ + if ((GST_VAAPI_ENCODER_WIDTH (feienc) & 15) || + (GST_VAAPI_ENCODER_HEIGHT (feienc) & 15)) { + static const guint SubWidthC[] = { 1, 2, 2, 1 }; + static const guint SubHeightC[] = { 1, 2, 1, 1 }; + const guint CropUnitX = + SubWidthC[seq_param->seq_fields.bits.chroma_format_idc]; + const guint CropUnitY = + SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] * + (2 - seq_param->seq_fields.bits.frame_mbs_only_flag); + + seq_param->frame_cropping_flag = 1; + seq_param->frame_crop_left_offset = 0; + seq_param->frame_crop_right_offset = + (16 * feienc->mb_width - GST_VAAPI_ENCODER_WIDTH (feienc)) / CropUnitX; + seq_param->frame_crop_top_offset = 0; + seq_param->frame_crop_bottom_offset = + (16 * feienc->mb_height - + GST_VAAPI_ENCODER_HEIGHT (feienc)) / CropUnitY; + } + + /* VUI parameters are always set, at least for timing_info (framerate) */ + seq_param->vui_parameters_present_flag = TRUE; + if (seq_param->vui_parameters_present_flag) { + seq_param->vui_fields.bits.aspect_ratio_info_present_flag = TRUE; + if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { + const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (feienc); + seq_param->aspect_ratio_idc = 0xff; + seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip); + seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip); + } + seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE; + /* if vui_parameters_present_flag is TRUE and sps data belongs to + * subset sps, timing_info_preset_flag should be zero (H.7.4.2.1.1) */ + seq_param->vui_fields.bits.timing_info_present_flag = !feienc->view_idx; + if (seq_param->vui_fields.bits.timing_info_present_flag) { + seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (feienc); + seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (feienc) * 2; + } + } + + return TRUE; +} + +/* Fills in VA picture parameter buffer */ +static gboolean +fill_picture (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, + GstVaapiSurfaceProxy * surface, GstVaapiCodedBuffer * const codedbuf) +{ + VAEncPictureParameterBufferH264 *const pic_param = picture->param; + GstVaapiH264ViewRefPool *const ref_pool = + &feienc->ref_pools[feienc->view_idx]; + GstVaapiFeiEncH264Ref *ref_pic; + GList *reflist; + guint i; + + memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264)); + + /* reference list, */ + pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); + pic_param->CurrPic.TopFieldOrderCnt = picture->poc; + pic_param->CurrPic.frame_idx = picture->frame_num; + i = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (reflist = g_queue_peek_head_link (&ref_pool->ref_list); + reflist; reflist = g_list_next (reflist)) { + ref_pic = reflist->data; + g_assert (ref_pic && ref_pic->pic && + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID); + + pic_param->ReferenceFrames[i].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); + pic_param->ReferenceFrames[i].TopFieldOrderCnt = ref_pic->poc; + pic_param->ReferenceFrames[i].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + pic_param->ReferenceFrames[i].frame_idx = ref_pic->frame_num; + ++i; + } + g_assert (i <= 16 && i <= ref_pool->max_ref_frames); + } + for (; i < 16; ++i) { + pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID; + pic_param->ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID; + } + + pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + + pic_param->pic_parameter_set_id = feienc->view_idx; + pic_param->seq_parameter_set_id = feienc->view_idx ? 1 : 0; + pic_param->last_picture = 0; /* means last encoding picture */ + pic_param->frame_num = picture->frame_num; + pic_param->pic_init_qp = feienc->init_qp; + pic_param->num_ref_idx_l0_active_minus1 = + (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0); + pic_param->num_ref_idx_l1_active_minus1 = + (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0); + pic_param->chroma_qp_index_offset = 0; + pic_param->second_chroma_qp_index_offset = 0; + + /* set picture fields */ + pic_param->pic_fields.value = 0; + pic_param->pic_fields.bits.idr_pic_flag = + GST_VAAPI_ENC_PICTURE_IS_IDR (picture); + pic_param->pic_fields.bits.reference_pic_flag = + (picture->type != GST_VAAPI_PICTURE_TYPE_B); + pic_param->pic_fields.bits.entropy_coding_mode_flag = feienc->use_cabac; + pic_param->pic_fields.bits.weighted_pred_flag = FALSE; + pic_param->pic_fields.bits.weighted_bipred_idc = 0; + pic_param->pic_fields.bits.constrained_intra_pred_flag = 0; + pic_param->pic_fields.bits.transform_8x8_mode_flag = feienc->use_dct8x8; + /* enable debloking */ + pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; + pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE; + /* bottom_field_pic_order_in_frame_present_flag */ + pic_param->pic_fields.bits.pic_order_present_flag = FALSE; + pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE; + + return TRUE; +} + +/* Adds slice headers to picture */ +static gboolean +add_slice_headers (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, + GstVaapiFeiEncH264Ref ** reflist_0, guint reflist_0_count, + GstVaapiFeiEncH264Ref ** reflist_1, guint reflist_1_count, + GstVaapiFeiInfoToPakH264 * info_to_pak) +{ + VAEncSliceParameterBufferH264 *slice_param; + GstVaapiEncSlice *slice; + GArray *h264_slice_params; + guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs; + guint mb_size; + guint last_mb_index; + guint i_slice, i_ref; + + g_assert (picture); + + mb_size = feienc->mb_width * feienc->mb_height; + + g_assert (feienc->num_slices && feienc->num_slices < mb_size); + slice_of_mbs = mb_size / feienc->num_slices; + slice_mod_mbs = mb_size % feienc->num_slices; + last_mb_index = 0; + h264_slice_params = + g_array_new (FALSE, TRUE, sizeof (VAEncSliceParameterBufferH264)); + for (i_slice = 0; i_slice < feienc->num_slices; ++i_slice) { + cur_slice_mbs = slice_of_mbs; + if (slice_mod_mbs) { + ++cur_slice_mbs; + --slice_mod_mbs; + } + slice = GST_VAAPI_ENC_SLICE_NEW (H264, feienc); + g_assert (slice && slice->param_id != VA_INVALID_ID); + slice_param = slice->param; + + memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264)); + slice_param->macroblock_address = last_mb_index; + slice_param->num_macroblocks = cur_slice_mbs; + slice_param->macroblock_info = VA_INVALID_ID; + slice_param->slice_type = h264_get_slice_type (picture->type); + g_assert ((gint8) slice_param->slice_type != -1); + slice_param->pic_parameter_set_id = feienc->view_idx; + slice_param->idr_pic_id = feienc->idr_num; + slice_param->pic_order_cnt_lsb = picture->poc; + + /* not used if pic_order_cnt_type = 0 */ + slice_param->delta_pic_order_cnt_bottom = 0; + memset (slice_param->delta_pic_order_cnt, 0, + sizeof (slice_param->delta_pic_order_cnt)); + + /* only works for B frames */ + if (slice_param->slice_type == GST_H264_B_SLICE) + slice_param->direct_spatial_mv_pred_flag = TRUE; + /* default equal to picture parameters */ + slice_param->num_ref_idx_active_override_flag = TRUE; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) + slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; + else + slice_param->num_ref_idx_l0_active_minus1 = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0) + slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; + else + slice_param->num_ref_idx_l1_active_minus1 = 0; + g_assert (slice_param->num_ref_idx_l0_active_minus1 >= 0); + g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0); + + i_ref = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (; i_ref < reflist_0_count; ++i_ref) { + slice_param->RefPicList0[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); + slice_param->RefPicList0[i_ref].TopFieldOrderCnt = + reflist_0[i_ref]->poc; + slice_param->RefPicList0[i_ref].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + slice_param->RefPicList0[i_ref].frame_idx = reflist_0[i_ref]->frame_num; + } + g_assert (i_ref >= 1); + } + for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) { + slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->RefPicList0[i_ref].flags = VA_PICTURE_H264_INVALID; + } + + i_ref = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + for (; i_ref < reflist_1_count; ++i_ref) { + slice_param->RefPicList1[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); + slice_param->RefPicList1[i_ref].TopFieldOrderCnt = + reflist_1[i_ref]->poc; + slice_param->RefPicList1[i_ref].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + slice_param->RefPicList1[i_ref].frame_idx = reflist_1[i_ref]->frame_num; + } + g_assert (i_ref == 1); + } + for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) { + slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->RefPicList1[i_ref].flags = VA_PICTURE_H264_INVALID; + } + + /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */ + slice_param->luma_log2_weight_denom = 0; + slice_param->chroma_log2_weight_denom = 0; + slice_param->luma_weight_l0_flag = FALSE; + memset (slice_param->luma_weight_l0, 0, + sizeof (slice_param->luma_weight_l0)); + memset (slice_param->luma_offset_l0, 0, + sizeof (slice_param->luma_offset_l0)); + slice_param->chroma_weight_l0_flag = FALSE; + memset (slice_param->chroma_weight_l0, 0, + sizeof (slice_param->chroma_weight_l0)); + memset (slice_param->chroma_offset_l0, 0, + sizeof (slice_param->chroma_offset_l0)); + slice_param->luma_weight_l1_flag = FALSE; + memset (slice_param->luma_weight_l1, 0, + sizeof (slice_param->luma_weight_l1)); + memset (slice_param->luma_offset_l1, 0, + sizeof (slice_param->luma_offset_l1)); + slice_param->chroma_weight_l1_flag = FALSE; + memset (slice_param->chroma_weight_l1, 0, + sizeof (slice_param->chroma_weight_l1)); + memset (slice_param->chroma_offset_l1, 0, + sizeof (slice_param->chroma_offset_l1)); + + slice_param->cabac_init_idc = 0; + slice_param->slice_qp_delta = feienc->init_qp - feienc->min_qp; + if (slice_param->slice_qp_delta > 4) + slice_param->slice_qp_delta = 4; + slice_param->disable_deblocking_filter_idc = 0; + slice_param->slice_alpha_c0_offset_div2 = 2; + slice_param->slice_beta_offset_div2 = 2; + + /* set calculation for next slice */ + last_mb_index += cur_slice_mbs; + + g_array_append_val (h264_slice_params, *slice_param); + + gst_vaapi_enc_picture_add_slice (picture, slice); + gst_vaapi_codec_object_replace (&slice, NULL); + } + g_assert (last_mb_index == mb_size); + + info_to_pak->h264_slice_headers = h264_slice_params; + + return TRUE; + +} + +/* Generates and submits SPS header accordingly into the bitstream */ +static gboolean +ensure_sequence (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, + GstVaapiFeiInfoToPakH264 * info_to_pak) +{ + GstVaapiEncSequence *sequence = NULL; + VAEncSequenceParameterBufferH264 *seq_param; + + sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, feienc); + if (!sequence || !fill_sequence (feienc, sequence)) + goto error_create_seq_param; + + seq_param = sequence->param; + info_to_pak->h264_enc_sps = *seq_param; + + if (sequence) { + gst_vaapi_enc_picture_set_sequence (picture, sequence); + gst_vaapi_codec_object_replace (&sequence, NULL); + } + + if (!feienc->is_mvc || feienc->view_idx > 0) + feienc->config_changed = FALSE; + return TRUE; + + /* ERRORS */ +error_create_seq_param: + { + GST_ERROR ("failed to create sequence parameter buffer (SPS)"); + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; + } +} + +/* Generates additional fei control parameters */ +static gboolean +ensure_fei_misc_params (GstVaapiFeiEncH264 * feienc, + GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy) +{ + GstVaapiEncMiscParam *misc = NULL; + GstVaapiSurfaceProxy *surface_proxy = picture->proxy; + VAEncMiscParameterFEIFrameControlH264 *misc_fei_pic_control_param; + guint mbcode_size = 0; + guint mv_size = 0; + guint dist_size = 0; + + /*fei pic control params */ + misc = GST_VAAPI_ENC_FEI_MISC_PARAM_NEW (H264, feienc); + g_assert (misc); + if (!misc) + return FALSE; + misc_fei_pic_control_param = misc->data; + surface_proxy = picture->proxy; + + misc_fei_pic_control_param->function = VA_FEI_FUNCTION_ENC; + misc_fei_pic_control_param->search_path = feienc->search_path; + misc_fei_pic_control_param->num_mv_predictors_l0 = + feienc->num_mv_predictors_l0; + misc_fei_pic_control_param->num_mv_predictors_l1 = + feienc->num_mv_predictors_l1; + misc_fei_pic_control_param->len_sp = feienc->len_sp; + misc_fei_pic_control_param->sub_mb_part_mask = feienc->submb_part_mask; + if (!feienc->use_dct8x8) + misc_fei_pic_control_param->intra_part_mask = feienc->intra_part_mask | 2; + misc_fei_pic_control_param->multi_pred_l0 = feienc->multi_predL0; + misc_fei_pic_control_param->multi_pred_l1 = feienc->multi_predL1; + misc_fei_pic_control_param->sub_pel_mode = feienc->subpel_mode; + misc_fei_pic_control_param->inter_sad = feienc->inter_sad; + misc_fei_pic_control_param->intra_sad = feienc->intra_sad; + misc_fei_pic_control_param->distortion_type = 0; + misc_fei_pic_control_param->repartition_check_enable = 0; + misc_fei_pic_control_param->adaptive_search = feienc->adaptive_search; + misc_fei_pic_control_param->mb_size_ctrl = 0; + misc_fei_pic_control_param->ref_width = feienc->ref_width; + misc_fei_pic_control_param->ref_height = feienc->ref_height; + misc_fei_pic_control_param->search_window = feienc->search_window; + + /***** ENC input: mv_predictor *****/ + if (surface_proxy->mvpred) { + misc_fei_pic_control_param->mv_predictor = + GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mvpred)->param_id; + misc_fei_pic_control_param->mv_predictor_enable = TRUE; + gst_vaapi_codec_object_replace (&picture->mvpred, surface_proxy->mvpred); + } else { + misc_fei_pic_control_param->mv_predictor = VA_INVALID_ID; + misc_fei_pic_control_param->mv_predictor_enable = FALSE; + picture->mvpred = NULL; + } + + /***** ENC input: qp ******/ + if (surface_proxy->qp) { + misc_fei_pic_control_param->qp = + GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->qp)->param_id; + misc_fei_pic_control_param->mb_qp = TRUE; + gst_vaapi_codec_object_replace (&picture->qp, surface_proxy->qp); + } else { + misc_fei_pic_control_param->qp = VA_INVALID_ID; + misc_fei_pic_control_param->mb_qp = FALSE; + picture->qp = NULL; + } + /***** ENC input: mb_control ******/ + if (surface_proxy->mbcntrl) { + misc_fei_pic_control_param->mb_ctrl = + GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mbcntrl)->param_id; + misc_fei_pic_control_param->mb_input = TRUE; + gst_vaapi_codec_object_replace (&picture->mbcntrl, surface_proxy->mbcntrl); + } else { + misc_fei_pic_control_param->mb_ctrl = VA_INVALID_ID; + misc_fei_pic_control_param->mb_input = FALSE; + picture->mbcntrl = NULL; + } + + mbcode_size = sizeof (VAEncFEIMBCodeH264) * + feienc->mb_width * feienc->mb_height; + mv_size = sizeof (VAMotionVector) * 16 * feienc->mb_width * feienc->mb_height; + dist_size = sizeof (VAEncFEIDistortionH264) * + feienc->mb_width * feienc->mb_height; + /***** ENC_PAK/ENC output: macroblock code buffer *****/ + codedbuf_proxy->mbcode = + gst_vaapi_enc_fei_mb_code_new (GST_VAAPI_ENCODER_CAST (feienc), + NULL, mbcode_size); + misc_fei_pic_control_param->mb_code_data = + GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mbcode)->param_id; + picture->mbcode = gst_vaapi_codec_object_ref (codedbuf_proxy->mbcode); + + /***** ENC_PAK/ENC output: motion vector buffer *****/ + codedbuf_proxy->mv = + gst_vaapi_enc_fei_mv_new (GST_VAAPI_ENCODER_CAST (feienc), NULL, mv_size); + misc_fei_pic_control_param->mv_data = + GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mv)->param_id; + picture->mv = gst_vaapi_codec_object_ref (codedbuf_proxy->mv); + + /* Fixme: a copy needed in coded_buf proxy */ + /***** ENC_PAK/ENC output: distortion buffer *****/ + picture->dist = + gst_vaapi_enc_fei_distortion_new (GST_VAAPI_ENCODER_CAST (feienc), + NULL, dist_size); + misc_fei_pic_control_param->distortion = + GST_VAAPI_FEI_CODEC_OBJECT (picture->dist)->param_id; + codedbuf_proxy->dist = gst_vaapi_codec_object_ref (picture->dist); + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + return TRUE; +} + +/* Generates additional control parameters */ +static gboolean +ensure_misc_params (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture) +{ + GstVaapiEncMiscParam *misc = NULL; + VAEncMiscParameterRateControl *rate_control; + + /* HRD params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, feienc); + g_assert (misc); + if (!misc) + return FALSE; + fill_hrd_params (feienc, misc->data); + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + /* RateControl params */ + if (GST_VAAPI_ENCODER_RATE_CONTROL (feienc) == GST_VAAPI_RATECONTROL_CBR || + GST_VAAPI_ENCODER_RATE_CONTROL (feienc) == GST_VAAPI_RATECONTROL_VBR) { + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, feienc); + g_assert (misc); + if (!misc) + return FALSE; + rate_control = misc->data; + memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); + rate_control->bits_per_second = feienc->bitrate_bits; + rate_control->target_percentage = 70; + rate_control->window_size = feienc->cpb_length; + rate_control->initial_qp = feienc->init_qp; + rate_control->min_qp = feienc->min_qp; + rate_control->basic_unit_size = 0; + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + } + return TRUE; + +} + +/* Generates and submits PPS header accordingly into the bitstream */ +static gboolean +ensure_picture (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, + GstVaapiSurfaceProxy * surface, GstVaapiCodedBufferProxy * codedbuf_proxy, + GstVaapiFeiInfoToPakH264 * info_to_pak) +{ + gboolean res = FALSE; + GstVaapiCodedBuffer *const codedbuf = + GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); + VAEncPictureParameterBufferH264 *const pic_param = picture->param; + + res = fill_picture (feienc, picture, surface, codedbuf); + + if (!res) + return FALSE; + + info_to_pak->h264_enc_pps = *pic_param; + + return TRUE; +} + +/* Generates slice headers */ +static gboolean +ensure_slices (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, + GstVaapiFeiInfoToPakH264 * info_to_pak) +{ + GstVaapiFeiEncH264Ref *reflist_0[16]; + GstVaapiFeiEncH264Ref *reflist_1[16]; + GstVaapiH264ViewRefPool *const ref_pool = + &feienc->ref_pools[feienc->view_idx]; + guint reflist_0_count = 0, reflist_1_count = 0; + + g_assert (picture); + + if (picture->type != GST_VAAPI_PICTURE_TYPE_I && + !reference_list_init (feienc, picture, + reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) { + GST_ERROR ("reference list reorder failed"); + return FALSE; + } + + g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames); + if (reflist_0_count > ref_pool->max_reflist0_count) + reflist_0_count = ref_pool->max_reflist0_count; + if (reflist_1_count > ref_pool->max_reflist1_count) + reflist_1_count = ref_pool->max_reflist1_count; + + if (!add_slice_headers (feienc, picture, + reflist_0, reflist_0_count, reflist_1, reflist_1_count, info_to_pak)) + return FALSE; + + return TRUE; +} + +/* Normalizes bitrate (and CPB size) for HRD conformance */ +static void +ensure_bitrate_hrd (GstVaapiFeiEncH264 * feienc) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (feienc); + guint bitrate, cpb_size; + + if (!base_encoder->bitrate) { + feienc->bitrate_bits = 0; + return; + } + + /* Round down bitrate. This is a hard limit mandated by the user */ + g_assert (SX_BITRATE >= 6); + bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1); + if (bitrate != feienc->bitrate_bits) { + GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate); + feienc->bitrate_bits = bitrate; + feienc->config_changed = TRUE; + } + + /* Round up CPB size. This is an HRD compliance detail */ + g_assert (SX_CPB_SIZE >= 4); + cpb_size = gst_util_uint64_scale (bitrate, feienc->cpb_length, 1000) & + ~((1U << SX_CPB_SIZE) - 1); + if (cpb_size != feienc->cpb_length_bits) { + GST_DEBUG ("HRD CPB size: %u bits", cpb_size); + feienc->cpb_length_bits = cpb_size; + feienc->config_changed = TRUE; + } +} + +/* Estimates a good enough bitrate if none was supplied */ +static void +ensure_bitrate (GstVaapiFeiEncH264 * feienc) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (feienc); + + /* Default compression: 48 bits per macroblock in "high-compression" mode */ + switch (GST_VAAPI_ENCODER_RATE_CONTROL (feienc)) { + case GST_VAAPI_RATECONTROL_CBR: + case GST_VAAPI_RATECONTROL_VBR: + case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: + if (!base_encoder->bitrate) { + /* According to the literature and testing, CABAC entropy coding + mode could provide for +10% to +18% improvement in general, + thus estimating +15% here ; and using adaptive 8x8 transforms + in I-frames could bring up to +10% improvement. */ + guint bits_per_mb = 48; + if (!feienc->use_cabac) + bits_per_mb += (bits_per_mb * 15) / 100; + if (!feienc->use_dct8x8) + bits_per_mb += (bits_per_mb * 10) / 100; + + base_encoder->bitrate = + feienc->mb_width * feienc->mb_height * bits_per_mb * + GST_VAAPI_ENCODER_FPS_N (feienc) / + GST_VAAPI_ENCODER_FPS_D (feienc) / 1000; + GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate); + } + break; + default: + base_encoder->bitrate = 0; + break; + } + ensure_bitrate_hrd (feienc); +} + +/* Constructs profile and level information based on user-defined limits */ +static GstVaapiEncoderStatus +ensure_profile_and_level (GstVaapiFeiEncH264 * feienc) +{ + const GstVaapiProfile profile = feienc->profile; + const GstVaapiLevelH264 level = feienc->level; + + if (!ensure_tuning (feienc)) + GST_WARNING ("Failed to set some of the tuning option as expected! "); + + if (!ensure_profile (feienc) || !ensure_profile_limits (feienc)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + /* Check HW constraints */ + if (!ensure_hw_profile_limits (feienc)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + if (feienc->profile_idc > feienc->hw_max_profile_idc) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + /* Ensure bitrate if not set already and derive the right level to use */ + ensure_bitrate (feienc); + if (!ensure_level (feienc)) + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + + if (feienc->profile != profile || feienc->level != level) { + GST_DEBUG ("selected %s profile at level %s", + gst_vaapi_utils_h264_get_profile_string (feienc->profile), + gst_vaapi_utils_h264_get_level_string (feienc->level)); + feienc->config_changed = TRUE; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static void +reset_properties (GstVaapiFeiEncH264 * feienc) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (feienc); + guint mb_size, i; + guint max_reflist0_count; + + if (feienc->idr_period < base_encoder->keyframe_period) + feienc->idr_period = base_encoder->keyframe_period; + if (feienc->idr_period > MAX_IDR_PERIOD) + feienc->idr_period = MAX_IDR_PERIOD; + + if (feienc->min_qp > feienc->init_qp || + (GST_VAAPI_ENCODER_RATE_CONTROL (feienc) == GST_VAAPI_RATECONTROL_CQP && + feienc->min_qp < feienc->init_qp)) + feienc->min_qp = feienc->init_qp; + + mb_size = feienc->mb_width * feienc->mb_height; + if (feienc->num_slices > (mb_size + 1) / 2) + feienc->num_slices = (mb_size + 1) / 2; + g_assert (feienc->num_slices); + + if (feienc->num_bframes > (base_encoder->keyframe_period + 1) / 2) + feienc->num_bframes = (base_encoder->keyframe_period + 1) / 2; + + /* Workaround : vaapi-intel-driver doesn't have support for + * B-frame encode when utilizing low-power encode hardware block. + * So Disabling b-frame encoding in low-pwer encode. + * + * Fixme :We should query the VAConfigAttribEncMaxRefFrames + * instead of blindly disabling b-frame support and set b/p frame count, + * buffer pool size etc based on that.*/ + if ((feienc->num_bframes > 0) + && (feienc->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)) { + GST_WARNING + ("Disabling b-frame since the driver doesn't supporting it in low-power encode"); + feienc->num_bframes = 0; + } + + if (feienc->num_bframes > 0 && GST_VAAPI_ENCODER_FPS_N (feienc) > 0) + feienc->cts_offset = gst_util_uint64_scale (GST_SECOND, + GST_VAAPI_ENCODER_FPS_D (feienc), GST_VAAPI_ENCODER_FPS_N (feienc)); + else + feienc->cts_offset = 0; + + /* init max_frame_num, max_poc */ + feienc->log2_max_frame_num = h264_get_log2_max_frame_num (feienc->idr_period); + g_assert (feienc->log2_max_frame_num >= 4); + feienc->max_frame_num = (1 << feienc->log2_max_frame_num); + feienc->log2_max_pic_order_cnt = feienc->log2_max_frame_num + 1; + feienc->max_pic_order_cnt = (1 << feienc->log2_max_pic_order_cnt); + feienc->idr_num = 0; + + if (feienc->num_bframes > 0) { + if (feienc->num_ref_frames == 1) { + GST_INFO ("num ref frames is modified as 2 as b frame is set"); + feienc->num_ref_frames = 2; + } + max_reflist0_count = feienc->num_ref_frames - 1; + } else { + max_reflist0_count = feienc->num_ref_frames; + } + max_reflist0_count = max_reflist0_count > 5 ? 5 : max_reflist0_count; + + for (i = 0; i < feienc->num_views; i++) { + GstVaapiH264ViewRefPool *const ref_pool = &feienc->ref_pools[i]; + GstVaapiH264ViewReorderPool *const reorder_pool = &feienc->reorder_pools[i]; + + ref_pool->max_reflist0_count = max_reflist0_count; + ref_pool->max_reflist1_count = feienc->num_bframes > 0; + ref_pool->max_ref_frames = ref_pool->max_reflist0_count + + ref_pool->max_reflist1_count; + + reorder_pool->frame_index = 0; + } + +} + +/* only for vaapi encoder framework checking */ +static GstVaapiEncoderStatus +gst_vaapi_feienc_h264_fake_encode (GstVaapiEncoder * base_encoder, + GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) +{ + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +GstVaapiEncoderStatus +gst_vaapi_feienc_h264_encode (GstVaapiEncoder * base_encoder, + GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * reconstruct, + GstVaapiCodedBufferProxy * codedbuf_proxy, + GstVaapiFeiInfoToPakH264 * info_to_pak) +{ + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + + if (!reconstruct || !codedbuf_proxy) + return ret; + + if (!ensure_sequence (feienc, picture, info_to_pak)) + goto error; + if (!ensure_misc_params (feienc, picture)) + goto error; + if (!ensure_fei_misc_params (feienc, picture, codedbuf_proxy)) + goto error; + if (!ensure_picture (feienc, picture, reconstruct, codedbuf_proxy, + info_to_pak)) + goto error; + if (!ensure_slices (feienc, picture, info_to_pak)) + goto error; + if (!gst_vaapi_enc_picture_encode (picture)) + goto error; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + +error: + g_slice_free (GstVaapiFeiInfoToPakH264, info_to_pak); + return ret; +} + +GstVaapiEncoderStatus +gst_vaapi_feienc_h264_flush (GstVaapiEncoder * base_encoder) +{ + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVaapiH264ViewReorderPool *reorder_pool; + GstVaapiEncPicture *pic; + guint i; + + for (i = 0; i < feienc->num_views; i++) { + reorder_pool = &feienc->reorder_pools[i]; + reorder_pool->frame_index = 0; + reorder_pool->cur_frame_num = 0; + reorder_pool->cur_present_index = 0; + + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&reorder_pool->reorder_frame_list); + } + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +/* Generate "codec-data" buffer */ +static GstVaapiEncoderStatus +gst_vaapi_feienc_h264_get_codec_data (GstVaapiEncoder * base_encoder, + GstBuffer ** out_buffer_ptr) +{ + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +GstVaapiEncoderStatus +gst_vaapi_feienc_h264_reordering (GstVaapiEncoder * base_encoder, + GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) +{ + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVaapiH264ViewReorderPool *reorder_pool = NULL; + GstVaapiEncPicture *picture; + gboolean is_idr = FALSE; + + *output = NULL; + + /* encoding views alternatively for MVC */ + if (feienc->is_mvc) { + /* FIXME: Use first-in-bundle flag on buffers to reset view idx? */ + if (frame) + feienc->view_idx = frame->system_frame_number % feienc->num_views; + else + feienc->view_idx = (feienc->view_idx + 1) % feienc->num_views; + } + reorder_pool = &feienc->reorder_pools[feienc->view_idx]; + + if (!frame) { + if (reorder_pool->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES) + return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; + + /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES + dump B frames from queue, sometime, there may also have P frame or I frame */ + g_assert (feienc->num_bframes > 0); + g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list), + GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN); + picture = g_queue_pop_head (&reorder_pool->reorder_frame_list); + g_assert (picture); + if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; + } + goto end; + } + + /* new frame coming */ + picture = GST_VAAPI_ENC_PICTURE_NEW (H264, feienc, frame); + if (!picture) { + GST_WARNING ("create H264 picture failed, frame timestamp:%" + GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } + ++reorder_pool->cur_present_index; + picture->poc = ((reorder_pool->cur_present_index * 2) % + feienc->max_pic_order_cnt); + + is_idr = (reorder_pool->frame_index == 0 || + reorder_pool->frame_index >= feienc->idr_period); + + /* check key frames */ + if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) || + (reorder_pool->frame_index % + GST_VAAPI_ENCODER_KEYFRAME_PERIOD (feienc)) == 0) { + ++reorder_pool->cur_frame_num; + ++reorder_pool->frame_index; + + /* b frame enabled, check queue of reorder_frame_list */ + if (feienc->num_bframes + && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + GstVaapiEncPicture *p_pic; + + p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list); + set_p_frame (p_pic, feienc); + g_queue_foreach (&reorder_pool->reorder_frame_list, + (GFunc) set_b_frame, feienc); + ++reorder_pool->cur_frame_num; + set_key_frame (picture, feienc, is_idr); + g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); + picture = p_pic; + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; + } else { /* no b frames in queue */ + set_key_frame (picture, feienc, is_idr); + g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list)); + if (feienc->num_bframes) + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; + } + goto end; + } + + /* new p/b frames coming */ + ++reorder_pool->frame_index; + if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES && + g_queue_get_length (&reorder_pool->reorder_frame_list) < + feienc->num_bframes) { + g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); + return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; + } + + ++reorder_pool->cur_frame_num; + set_p_frame (picture, feienc); + + if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) { + g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame, + feienc); + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; + g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list)); + } + +end: + g_assert (picture); + frame = picture->frame; + if (GST_CLOCK_TIME_IS_VALID (frame->pts)) + frame->pts += feienc->cts_offset; + *output = picture; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static GstVaapiEncoderStatus +set_context_info (GstVaapiEncoder * base_encoder) +{ + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (feienc); + const guint DEFAULT_SURFACES_COUNT = 3; + + /* Maximum sizes for common headers (in bits) */ + enum + { + MAX_SPS_HDR_SIZE = 16473, + MAX_VUI_PARAMS_SIZE = 210, + MAX_HRD_PARAMS_SIZE = 4103, + MAX_PPS_HDR_SIZE = 101, + MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402, + }; + + if (!ensure_hw_profile (feienc)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + base_encoder->num_ref_frames = + (feienc->num_ref_frames + DEFAULT_SURFACES_COUNT) * feienc->num_views; + + /* Only YUV 4:2:0 formats are supported for now. This means that we + have a limit of 3200 bits per macroblock. */ + /* XXX: check profile and compute RawMbBits */ + base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) * + GST_ROUND_UP_16 (vip->height) / 256) * 400; + + /* Account for SPS header */ + /* XXX: exclude scaling lists, MVC/SVC extensions */ + base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE + + MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8; + + /* Account for PPS header */ + /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */ + base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8; + + /* Account for slice header */ + base_encoder->codedbuf_size += feienc->num_slices * (4 + + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); + + base_encoder->context_info.entrypoint = feienc->entrypoint; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +GstVaapiEncoderStatus +gst_vaapi_feienc_h264_reconfigure (GstVaapiEncoder * base_encoder) +{ + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (feienc); + GstVaapiEncoderStatus status; + guint mb_width, mb_height; + + mb_width = (GST_VAAPI_ENCODER_WIDTH (feienc) + 15) / 16; + mb_height = (GST_VAAPI_ENCODER_HEIGHT (feienc) + 15) / 16; + if (mb_width != feienc->mb_width || mb_height != feienc->mb_height) { + GST_DEBUG ("resolution: %dx%d", GST_VAAPI_ENCODER_WIDTH (feienc), + GST_VAAPI_ENCODER_HEIGHT (feienc)); + feienc->mb_width = mb_width; + feienc->mb_height = mb_height; + feienc->config_changed = TRUE; + } + + /* Take number of MVC views from input caps if provided */ + if (GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == + GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME + || GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == + GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME) + feienc->num_views = GST_VIDEO_INFO_VIEWS (vip); + + feienc->is_mvc = feienc->num_views > 1; + + status = ensure_profile_and_level (feienc); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + + reset_properties (feienc); + status = set_context_info (base_encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static gboolean +gst_vaapi_feienc_h264_init (GstVaapiEncoder * base_encoder) +{ + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + guint32 i; + + /* Default encoding entrypoint */ + feienc->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + feienc->search_path = GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT; + feienc->len_sp = GST_VAAPI_FEI_H264_SEARCH_PATH_LENGTH_DEFAULT; + feienc->ref_width = GST_VAAPI_FEI_H264_REF_WIDTH_DEFAULT; + feienc->ref_height = GST_VAAPI_FEI_H264_REF_HEIGHT_DEFAULT; + feienc->intra_part_mask = GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT; + feienc->submb_part_mask = GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT; + + /* Multi-view coding information */ + feienc->is_mvc = FALSE; + feienc->num_views = 1; + feienc->view_idx = 0; + + /* default num ref frames */ + feienc->num_ref_frames = 1; + memset (feienc->view_ids, 0, sizeof (feienc->view_ids)); + + feienc->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI; + + /* re-ordering list initialize */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264ViewReorderPool *const reorder_pool = &feienc->reorder_pools[i]; + g_queue_init (&reorder_pool->reorder_frame_list); + reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE; + reorder_pool->frame_index = 0; + reorder_pool->cur_frame_num = 0; + reorder_pool->cur_present_index = 0; + } + + return TRUE; +} + +static void +gst_vaapi_feienc_h264_finalize (GstVaapiEncoder * base_encoder) +{ + /*free private buffers */ + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVaapiEncPicture *pic; + guint32 i; + + gst_buffer_replace (&feienc->sps_data, NULL); + gst_buffer_replace (&feienc->subset_sps_data, NULL); + gst_buffer_replace (&feienc->pps_data, NULL); + + /* re-ordering list initialize */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264ViewReorderPool *const reorder_pool = &feienc->reorder_pools[i]; + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&reorder_pool->reorder_frame_list); + } +} + +GstVaapiEncoderStatus +gst_vaapi_feienc_h264_set_property (GstVaapiEncoder * base_encoder, + gint prop_id, const GValue * value) +{ + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + + switch (prop_id) { + case GST_VAAPI_FEI_H264_ENC_PROP_MAX_BFRAMES: + feienc->num_bframes = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_INIT_QP: + feienc->init_qp = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_MIN_QP: + feienc->min_qp = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_NUM_SLICES: + feienc->num_slices = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_CABAC: + feienc->use_cabac = g_value_get_boolean (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_DCT8X8: + feienc->use_dct8x8 = g_value_get_boolean (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_CPB_LENGTH: + feienc->cpb_length = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_NUM_VIEWS: + feienc->num_views = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_VIEW_IDS:{ + guint i; + GValueArray *view_ids = g_value_get_boxed (value); + + if (view_ids == NULL) { + for (i = 0; i < feienc->num_views; i++) + feienc->view_ids[i] = i; + } else { + g_assert (view_ids->n_values <= feienc->num_views); + + for (i = 0; i < feienc->num_views; i++) { + GValue *val = g_value_array_get_nth (view_ids, i); + feienc->view_ids[i] = g_value_get_uint (val); + } + } + break; + } + case GST_VAAPI_FEI_H264_ENC_PROP_NUM_REF: + feienc->num_ref_frames = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0: + feienc->num_mv_predictors_l0 = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1: + feienc->num_mv_predictors_l1 = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_WINDOW: + feienc->search_window = g_value_get_enum (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_LEN_SP: + feienc->len_sp = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_PATH: + feienc->search_path = g_value_get_enum (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_REF_WIDTH: + feienc->ref_width = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_REF_HEIGHT: + feienc->ref_height = g_value_get_uint (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_SUBMB_MASK: + feienc->submb_part_mask = g_value_get_flags (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_SUBPEL_MODE: + feienc->subpel_mode = g_value_get_enum (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_INTRA_PART_MASK: + feienc->intra_part_mask = g_value_get_flags (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_INTRA_SAD: + feienc->intra_sad = g_value_get_enum (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_INTER_SAD: + feienc->inter_sad = g_value_get_enum (value); + break; + case GST_VAAPI_FEI_H264_ENC_PROP_ADAPT_SEARCH: + feienc->adaptive_search = g_value_get_boolean (value) ? 1 : 0; + break; + case GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L0: + feienc->multi_predL0 = g_value_get_boolean (value) ? 1 : 0; + break; + case GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L1: + feienc->multi_predL1 = g_value_get_boolean (value) ? 1 : 0; + break; + default: + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static const GstVaapiEncoderClassData fei_enc_class_data = { + .codec = GST_VAAPI_CODEC_H264, + .packed_headers = SUPPORTED_PACKED_HEADERS, + .rate_control_get_type = gst_vaapi_rate_control_get_type, + .default_rate_control = DEFAULT_RATECONTROL, + .rate_control_mask = SUPPORTED_RATECONTROLS, + .encoder_tune_get_type = gst_vaapi_encoder_tune_get_type, + .default_encoder_tune = GST_VAAPI_ENCODER_TUNE_NONE, + .encoder_tune_mask = SUPPORTED_TUNE_OPTIONS, +}; + +static inline const GstVaapiEncoderClass * +gst_vaapi_feienc_h264_class (void) +{ + static const GstVaapiEncoderClass GstVaapiFeiEncH264Class = { + .parent_class = { + .size = sizeof (GstVaapiFeiEncH264), + .finalize = (GDestroyNotify) gst_vaapi_encoder_finalize, + } + , + .class_data = &fei_enc_class_data, + .init = gst_vaapi_feienc_h264_init, + .finalize = gst_vaapi_feienc_h264_finalize, + .reconfigure = gst_vaapi_feienc_h264_reconfigure, + .get_default_properties = gst_vaapi_feienc_h264_get_default_properties, + .reordering = gst_vaapi_feienc_h264_reordering, + .encode = gst_vaapi_feienc_h264_fake_encode, + .flush = gst_vaapi_feienc_h264_flush, + .set_property = gst_vaapi_feienc_h264_set_property, + .get_codec_data = gst_vaapi_feienc_h264_get_codec_data, + }; + return &GstVaapiFeiEncH264Class; +} + +/** + * gst_vaapi_feienc_h264_new: + * @display: a #GstVaapiDisplay + * + * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the + * only supported output stream format is "byte-stream" format. + * + * Return value: the newly allocated #GstVaapiEncoder object + */ +GstVaapiEncoder * +gst_vaapi_feienc_h264_new (GstVaapiDisplay * display) +{ + return gst_vaapi_encoder_new (gst_vaapi_feienc_h264_class (), display); +} + +/** + * gst_vaapi_feienc_h264_get_fei_properties: + * + * Determines the set of common and H.264 Fei specific feienc properties. + * The caller owns an extra reference to the resulting array of + * #GstVaapiEncoderPropInfo elements, so it shall be released with + * g_ptr_array_unref() after usage. + * + * Return value: the set of feienc properties for #GstVaapiFeiEncH264, + * or %NULL if an error occurred. + */ +static GPtrArray * +gst_vaapi_feienc_h264_get_fei_properties (GPtrArray * props) +{ + /** + * GstVaapiFeiEncH264:num_mv_predictors_l0: + * + * The number of mv predict + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0, + g_param_spec_uint ("num-mvpredict-l0", + "Num mv predict l0", + "Indicate how many predictors should be used for l0", + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiFeiEncH264:num_mv_predictors_l1: + * + * The number of mv predict + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1, + g_param_spec_uint ("num-mvpredict-l1", + "Num mv predict l1", + "Indicate how many predictors should be used for l1", + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiFeiEncH264:search-window: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_WINDOW, + g_param_spec_enum ("search-window", + "search window", + "Specify one of the predefined search path", + GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiFeiEncH264:len-sp: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_LEN_SP, + g_param_spec_uint ("len-sp", + "len sp", + "This value defines number of search units in search path", + 1, 63, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:search-path: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_PATH, + g_param_spec_enum ("search-path", + "search path", + "Specify search path", + GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, + GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:ref-width: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_REF_WIDTH, + g_param_spec_uint ("ref-width", + "ref width", + "Width of search region in pixel, must be multiple of 4", + 4, 64, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:ref-height: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_REF_HEIGHT, + g_param_spec_uint ("ref-height", + "ref height", + "Height of search region in pixel, must be multiple of 4", + 4, 32, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiFeiEncH264:submb-mask: + * Defines the bit-mask for disabling sub-partition + * + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_SUBMB_MASK, + g_param_spec_flags ("submbpart-mask", + "submb part mask", + "defines the bit-mask for disabling sub mb partition", + GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, + GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:subpel-mode: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_SUBPEL_MODE, + g_param_spec_enum ("subpel-mode", + "subpel mode", + "Sub pixel precision for motion estimation", + GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, + GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiFeiEncH264:intrapart-mask: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_INTRA_PART_MASK, + g_param_spec_flags ("intrapart-mask", + "intra part mask", + "What block and sub-block partitions are disabled for intra MBs", + GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, + GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiFeiEncH264:intra-sad: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_INTRA_SAD, + g_param_spec_enum ("intra-sad", + "intra sad", + "Specifies distortion measure adjustments used in the motion search SAD comparison for intra MB", + GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:inter-sad: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_INTER_SAD, + g_param_spec_enum ("inter-sad", + "inter sad", + "Specifies distortion measure adjustments used in the motion search SAD comparison for inter MB", + GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:adaptive-search: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_ADAPT_SEARCH, + g_param_spec_boolean ("adaptive-search", + "adaptive-search", + "Enable adaptive search", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:multi-predL0: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L0, + g_param_spec_boolean ("multi-predL0", + "multi predL0", + "Enable multi prediction for ref L0 list", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:multi-predL0: + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L1, + g_param_spec_boolean ("multi-predL1", + "multi predL1", + "Enable multi prediction for ref L1 list", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + return props; + +} + +/** + * gst_vaapi_feienc_h264_get_default_properties: + * + * Determines the set of common and H.264 specific feienc properties. + * The caller owns an extra reference to the resulting array of + * #GstVaapiEncoderPropInfo elements, so it shall be released with + * g_ptr_array_unref() after usage. + * + * Return value: the set of feienc properties for #GstVaapiFeiEncH264, + * or %NULL if an error occurred. + */ +GPtrArray * +gst_vaapi_feienc_h264_get_default_properties (void) +{ + const GstVaapiEncoderClass *const klass = gst_vaapi_feienc_h264_class (); + GPtrArray *props; + + props = gst_vaapi_encoder_properties_get_default (klass); + + if (!props) + return NULL; + + /** + * GstVaapiFeiEncH264:max-bframes: + * + * The number of B-frames between I and P. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_MAX_BFRAMES, + g_param_spec_uint ("max-bframes", + "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:init-qp: + * + * The initial quantizer value. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_INIT_QP, + g_param_spec_uint ("init-qp", + "Initial QP", "Initial quantizer value", 1, 51, 26, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:min-qp: + * + * The minimum quantizer value. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_MIN_QP, + g_param_spec_uint ("min-qp", + "Minimum QP", "Minimum quantizer value", 1, 51, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:num-slices: + * + * The number of slices per frame. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_NUM_SLICES, + g_param_spec_uint ("num-slices", + "Number of Slices", + "Number of slices per frame", + 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:cabac: + * + * Enable CABAC entropy coding mode for improved compression ratio, + * at the expense that the minimum target profile is Main. Default + * is CAVLC entropy coding mode. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_CABAC, + g_param_spec_boolean ("cabac", + "Enable CABAC", + "Enable CABAC entropy coding mode", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:dct8x8: + * + * Enable adaptive use of 8x8 transforms in I-frames. This improves + * the compression ratio by the minimum target profile is High. + * Default is to use 4x4 DCT only. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_DCT8X8, + g_param_spec_boolean ("dct8x8", + "Enable 8x8 DCT", + "Enable adaptive use of 8x8 transforms in I-frames", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:cpb-length: + * + * The size of the CPB buffer in milliseconds. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_CPB_LENGTH, + g_param_spec_uint ("cpb-length", + "CPB Length", "Length of the CPB buffer in milliseconds", + 1, 10000, DEFAULT_CPB_LENGTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiFeiEncH264:num-views: + * + * The number of views for MVC encoding . + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_NUM_VIEWS, + g_param_spec_uint ("num-views", + "Number of Views", + "Number of Views for MVC encoding", + 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiFeiEncH264:view-ids: + * + * The view ids for MVC encoding . + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_VIEW_IDS, + g_param_spec_value_array ("view-ids", + "View IDs", "Set of View Ids used for MVC encoding", + g_param_spec_uint ("view-id-value", "View id value", + "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiFeiEncH264:num-ref: + * + * The number of reference frames. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_FEI_H264_ENC_PROP_NUM_REF, + g_param_spec_uint ("num-ref", + "Num Ref", + "reference frame number", + 1, 6, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + props = gst_vaapi_feienc_h264_get_fei_properties (props); + + return props; +} + +/** + * gst_vaapi_feienc_h264_set_max_profile: + * @feienc: a #GstVaapiFeiEncH264 + * @profile: an H.264 #GstVaapiProfile + * + * Notifies the @feienc to use coding tools from the supplied + * @profile at most. + * + * This means that if the minimal profile derived to + * support the specified coding tools is greater than this @profile, + * then an error is returned when the @feienc is configured. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_feienc_h264_set_max_profile (GstVaapiFeiEncH264 * feienc, + GstVaapiProfile profile) +{ + guint8 profile_idc; + + g_return_val_if_fail (feienc != NULL, FALSE); + g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE); + + if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264) + return FALSE; + + profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + if (!profile_idc) + return FALSE; + + feienc->max_profile_idc = profile_idc; + return TRUE; +} + +gboolean +gst_vaapi_feienc_h264_set_ref_pool (GstVaapiFeiEncH264 * feienc, + gpointer ref_pool_ptr) +{ + g_return_val_if_fail (feienc != NULL, FALSE); + + if (!ref_pool_ptr) + return FALSE; + + memcpy (&feienc->ref_pools[0], ref_pool_ptr, + sizeof (GstVaapiH264ViewRefPool) * MAX_NUM_VIEWS); + + return TRUE; +} + +/** + * gst_vaapi_feienc_h264_get_profile_and_level + * @feienc: a #GstVaapiFeiEncH264 + * @out_profile_ptr: return location for the #GstVaapiProfile + * @out_profile_idc_ptr: return location for the #GstVaapiLevelH264 + * + * Queries the H.264 @feienc for the active profile and level. That + * information is only constructed and valid after the feienc is + * configured, i.e. after the gst_vaapi_feienc_set_codec_state() + * function is called. + * + * Return value: %TRUE on success + */ +gboolean +gst_vaapi_feienc_h264_get_profile_and_idc (GstVaapiFeiEncH264 * feienc, + GstVaapiProfile * out_profile_ptr, guint8 * out_profile_idc_ptr) +{ + g_return_val_if_fail (feienc != NULL, FALSE); + + if (!feienc->profile || !feienc->profile_idc) + return FALSE; + + if (out_profile_ptr) + *out_profile_ptr = feienc->profile; + if (out_profile_idc_ptr) + *out_profile_idc_ptr = feienc->profile_idc; + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.h b/gst-libs/gst/vaapi/gstvaapifeienc_h264.h new file mode 100644 index 0000000000..03766e0df1 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.h @@ -0,0 +1,121 @@ +/* + * gstvaapifeienc_h264.h - FEI Enc abstract + * + * Copyright (C) 2016-2018 Intel Corporation + * Author: Leilei Shang + * Author: Sreerenj Balachandran + * + * 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_FEI_H264_ENC_H +#define GST_VAAPI_FEI_H264_ENC_H + +#include +#include +#include +#include +G_BEGIN_DECLS +#define GST_VAAPI_FEI_H264_ENC(feienc) \ + ((GstVaapiFeiEncH264 *) (feienc)) +typedef struct _GstVaapiFeiEncH264 GstVaapiFeiEncH264; + +/** + * GstVaapiFeiEncH264Prop: + * @GST_VAAPI_FEI_H264_ENC_PROP_MAX_BFRAMES: Number of B-frames between I + * and P (uint). + * @GST_VAAPI_FEI_H264_ENC_PROP_INIT_QP: Initial quantizer value (uint). + * @GST_VAAPI_FEI_H264_ENC_PROP_MIN_QP: Minimal quantizer value (uint). + * @GST_VAAPI_FEI_H264_ENC_PROP_NUM_SLICES: Number of slices per frame (uint). + * @GST_VAAPI_FEI_H264_ENC_PROP_CABAC: Enable CABAC entropy coding mode (bool). + * @GST_VAAPI_FEI_H264_ENC_PROP_DCT8X8: Enable adaptive use of 8x8 + * transforms in I-frames (bool). + * @GST_VAAPI_FEI_H264_ENC_PROP_CPB_LENGTH: Length of the CPB buffer + * in milliseconds (uint). + * @GST_VAAPI_FEI_H264_ENC_PROP_NUM_VIEWS: Number of views per frame. + * @GST_VAAPI_FEI_H264_ENC_PROP_VIEW_IDS: View IDs + * + * The set of FEI Enc specific configurable properties. + */ +typedef enum +{ + GST_VAAPI_FEI_H264_ENC_PROP_MAX_BFRAMES = -1, + GST_VAAPI_FEI_H264_ENC_PROP_INIT_QP = -2, + GST_VAAPI_FEI_H264_ENC_PROP_MIN_QP = -3, + GST_VAAPI_FEI_H264_ENC_PROP_NUM_SLICES = -4, + GST_VAAPI_FEI_H264_ENC_PROP_CABAC = -5, + GST_VAAPI_FEI_H264_ENC_PROP_DCT8X8 = -6, + GST_VAAPI_FEI_H264_ENC_PROP_CPB_LENGTH = -7, + GST_VAAPI_FEI_H264_ENC_PROP_NUM_VIEWS = -8, + GST_VAAPI_FEI_H264_ENC_PROP_VIEW_IDS = -9, + GST_VAAPI_FEI_H264_ENC_PROP_NUM_REF = -10, + GST_VAAPI_FEI_H264_ENC_PROP_FEI_ENABLE = -11, + GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0 = -12, + GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1 = -13, + GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_WINDOW = -14, + GST_VAAPI_FEI_H264_ENC_PROP_LEN_SP = -15, + GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_PATH = -16, + GST_VAAPI_FEI_H264_ENC_PROP_REF_WIDTH = -17, + GST_VAAPI_FEI_H264_ENC_PROP_REF_HEIGHT = -18, + GST_VAAPI_FEI_H264_ENC_PROP_SUBMB_MASK = -19, + GST_VAAPI_FEI_H264_ENC_PROP_SUBPEL_MODE = -20, + GST_VAAPI_FEI_H264_ENC_PROP_INTRA_PART_MASK = -21, + GST_VAAPI_FEI_H264_ENC_PROP_INTRA_SAD = -22, + GST_VAAPI_FEI_H264_ENC_PROP_INTER_SAD = -23, + GST_VAAPI_FEI_H264_ENC_PROP_ADAPT_SEARCH = -24, + GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L0 = -25, + GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L1 = -26, + GST_VAAPI_FEI_H264_ENC_PROP_ENABLE_STATS_OUT = -27, +} GstVaapiFeiEncH264Prop; + +GstVaapiEncoder * +gst_vaapi_feienc_h264_new (GstVaapiDisplay * display); + +GPtrArray * +gst_vaapi_feienc_h264_get_default_properties (void); + +gboolean +gst_vaapi_feienc_h264_set_max_profile (GstVaapiFeiEncH264 * feienc, + GstVaapiProfile profile); + +gboolean +gst_vaapi_feienc_h264_set_ref_pool (GstVaapiFeiEncH264 * feienc, gpointer ref_pool_ptr); + +GstVaapiEncoderStatus +gst_vaapi_feienc_h264_encode (GstVaapiEncoder * base_encoder, + GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * reconstruct, + GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiFeiInfoToPakH264 *info_to_pak); + +GstVaapiEncoderStatus +gst_vaapi_feienc_h264_flush (GstVaapiEncoder * base_encoder); + +GstVaapiEncoderStatus +gst_vaapi_feienc_h264_reordering (GstVaapiEncoder * base_encoder, + GstVideoCodecFrame * frame, GstVaapiEncPicture ** output); + +GstVaapiEncoderStatus +gst_vaapi_feienc_h264_reconfigure (GstVaapiEncoder * base_encoder); + +GstVaapiEncoderStatus +gst_vaapi_feienc_h264_set_property (GstVaapiEncoder * base_encoder, + gint prop_id, const GValue * value); + +gboolean +gst_vaapi_feienc_h264_get_profile_and_idc (GstVaapiFeiEncH264 * feienc, + GstVaapiProfile * out_profile_ptr, guint8 * out_profile_idc_ptr); + +G_END_DECLS +#endif /*GST_VAAPI_FEI_H264_ENC_H */ diff --git a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c new file mode 100644 index 0000000000..7a49f0a9a4 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c @@ -0,0 +1,1892 @@ +/* + * gstvaapifeipak_h264.c - H.264 FEI PAK + * + * Copyright (C) 2012-2016 Intel Corporation + * Author: Chen, Xiaomin + * Author: Sreerenj Balachandran + * + * 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 + */ + +/* GValueArray has deprecated without providing an alternative in glib >= 2.32 + * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 + */ + +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#include "sysdeps.h" +#include +#include +#include +#include "gstvaapicompat.h" +#include "gstvaapiencoder_priv.h" +#include "gstvaapifeipak_h264.h" +#include "gstvaapiutils_h264_priv.h" +#include "gstvaapicodedbufferproxy_priv.h" +#include "gstvaapisurface.h" +#define DEBUG 1 +#include "gstvaapidebug.h" + +/* Define the maximum number of views supported */ +#define MAX_NUM_VIEWS 10 + +/* Define the maximum value for view-id */ +#define MAX_VIEW_ID 1023 + +/* Define the maximum IDR period */ +#define MAX_IDR_PERIOD 512 + +/* Default CPB length (in milliseconds) */ +#define DEFAULT_CPB_LENGTH 1500 + +/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */ +#define SX_CPB_SIZE 4 + +/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ +#define SX_BITRATE 6 + +/* 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) | \ + GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) + +/* Supported set of tuning options, within this implementation */ +#define SUPPORTED_TUNE_OPTIONS \ + (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \ + GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION) | \ + GST_VAAPI_ENCODER_TUNE_MASK (LOW_POWER)) + +/* Supported set of VA packed headers, within this implementation */ +#define SUPPORTED_PACKED_HEADERS \ + (VA_ENC_PACKED_HEADER_SEQUENCE | \ + VA_ENC_PACKED_HEADER_PICTURE | \ + VA_ENC_PACKED_HEADER_SLICE | \ + VA_ENC_PACKED_HEADER_RAW_DATA) + +#define GST_H264_NAL_REF_IDC_NONE 0 +#define GST_H264_NAL_REF_IDC_LOW 1 +#define GST_H264_NAL_REF_IDC_MEDIUM 2 +#define GST_H264_NAL_REF_IDC_HIGH 3 + +typedef struct +{ + GstVaapiSurfaceProxy *pic; + guint poc; + guint frame_num; +} GstVaapiFEIPakH264Ref; + +typedef enum +{ + GST_VAAPI_FEIPAK_H264_REORD_NONE = 0, + GST_VAAPI_FEIPAK_H264_REORD_DUMP_FRAMES = 1, + GST_VAAPI_FEIPAK_H264_REORD_WAIT_FRAMES = 2 +} GstVaapiFEIPakH264ReorderState; + +typedef struct _GstVaapiH264FEIPakViewRefPool +{ + GQueue ref_list; + guint max_ref_frames; + guint max_reflist0_count; + guint max_reflist1_count; +} GstVaapiH264FEIPakViewRefPool; + +typedef struct _GstVaapiH264FEIPakViewReorderPool +{ + GQueue reorder_frame_list; + guint reorder_state; + guint frame_index; + guint frame_count; /* monotonically increasing with in every idr period */ + guint cur_frame_num; + guint cur_present_index; +} GstVaapiH264FEIPakViewReorderPool; + +/* ------------------------------------------------------------------------- */ +/* --- H.264 FEI PAK --- */ +/* ------------------------------------------------------------------------- */ + +struct _GstVaapiFEIPakH264 +{ + GstVaapiMiniObject parent_instance; + + GstVaapiEncoder *encoder; + + VAEncSequenceParameterBufferH264 h264_sps; + VAEncPictureParameterBufferH264 h264_pps; + GArray *h264_slice_params; + + GstVaapiProfile profile; + GstVaapiEntrypoint entrypoint; + GstVaapiDisplay *display; + VAContextID va_context; + guint8 profile_idc; + guint8 hw_max_profile_idc; + guint32 num_slices; + guint slice_type; + gboolean is_idr; + guint32 num_bframes; + guint32 mb_width; + guint32 mb_height; + gboolean props_reconfigured; + gboolean config_changed; + + guint32 max_pic_order_cnt; + guint32 log2_max_pic_order_cnt; + + GstBuffer *sps_data; + GstBuffer *subset_sps_data; + GstBuffer *pps_data; + guint32 num_ref_frames; // set reference frame num + + /* MVC */ + gboolean is_mvc; + guint32 view_idx; /* View Order Index (VOIdx) */ + guint32 num_views; + guint16 view_ids[MAX_NUM_VIEWS]; + GstVaapiH264FEIPakViewRefPool ref_pools[MAX_NUM_VIEWS]; +}; + +static inline gboolean +_poc_greater_than (guint poc1, guint poc2, guint max_poc) +{ + return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2); +} + +/* ------------------------------------------------------------------------- */ +/* --- H.264 Bitstream Writer --- */ +/* ------------------------------------------------------------------------- */ + +#define WRITE_UINT32(bs, val, nbits) do { \ + if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \ + GST_WARNING ("failed to write uint32, nbits: %d", nbits); \ + goto bs_error; \ + } \ + } while (0) + +#define WRITE_UE(bs, val) do { \ + if (!bs_write_ue (bs, val)) { \ + GST_WARNING ("failed to write ue(v)"); \ + goto bs_error; \ + } \ + } while (0) + +#define WRITE_SE(bs, val) do { \ + if (!bs_write_se (bs, val)) { \ + GST_WARNING ("failed to write se(v)"); \ + goto bs_error; \ + } \ + } while (0) + +/* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */ +static gboolean +bs_write_ue (GstBitWriter * bs, guint32 value) +{ + guint32 size_in_bits = 0; + guint32 tmp_value = ++value; + + while (tmp_value) { + ++size_in_bits; + tmp_value >>= 1; + } + if (size_in_bits > 1 + && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1)) + return FALSE; + if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits)) + return FALSE; + return TRUE; +} + +/* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */ +static gboolean +bs_write_se (GstBitWriter * bs, gint32 value) +{ + guint32 new_val; + + if (value <= 0) + new_val = -(value << 1); + else + new_val = (value << 1) - 1; + + if (!bs_write_ue (bs, new_val)) + return FALSE; + return TRUE; +} + +/* Write the NAL unit header */ +static gboolean +bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc, + guint32 nal_unit_type) +{ + WRITE_UINT32 (bs, 0, 1); + WRITE_UINT32 (bs, nal_ref_idc, 2); + WRITE_UINT32 (bs, nal_unit_type, 5); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write NAL unit header"); + return FALSE; + } +} + +/* Write the MVC NAL unit header extension */ +static gboolean +bs_write_nal_header_mvc_extension (GstBitWriter * bs, + GstVaapiEncPicture * picture, guint32 view_id) +{ + guint32 svc_extension_flag = 0; + guint32 non_idr_flag = 1; + guint32 priority_id = 0; + guint32 temporal_id = 0; + guint32 anchor_pic_flag = 0; + guint32 inter_view_flag = 0; + + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + non_idr_flag = 0; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_I) + anchor_pic_flag = 1; + /* svc_extension_flag == 0 for mvc stream */ + WRITE_UINT32 (bs, svc_extension_flag, 1); + + WRITE_UINT32 (bs, non_idr_flag, 1); + WRITE_UINT32 (bs, priority_id, 6); + WRITE_UINT32 (bs, view_id, 10); + WRITE_UINT32 (bs, temporal_id, 3); + WRITE_UINT32 (bs, anchor_pic_flag, 1); + WRITE_UINT32 (bs, inter_view_flag, 1); + WRITE_UINT32 (bs, 1, 1); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write NAL unit header"); + return FALSE; + } +} + +/* Write the NAL unit trailing bits */ +static gboolean +bs_write_trailing_bits (GstBitWriter * bs) +{ + if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1)) + goto bs_error; + gst_bit_writer_align_bytes_unchecked (bs, 0); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write NAL unit trailing bits"); + return FALSE; + } +} + +/* Write an SPS NAL unit */ +static gboolean +bs_write_sps_data (GstBitWriter * bs, + const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, + const VAEncMiscParameterHRD * hrd_params) +{ + guint8 profile_idc; + guint32 constraint_set0_flag, constraint_set1_flag; + guint32 constraint_set2_flag, constraint_set3_flag; + guint32 gaps_in_frame_num_value_allowed_flag = 0; // ?? + gboolean nal_hrd_parameters_present_flag; + + guint32 b_qpprime_y_zero_transform_bypass = 0; + guint32 residual_color_transform_flag = 0; + guint32 pic_height_in_map_units = + (seq_param->seq_fields.bits.frame_mbs_only_flag ? + seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2); + guint32 mb_adaptive_frame_field = + !seq_param->seq_fields.bits.frame_mbs_only_flag; + guint32 i = 0; + + profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + constraint_set0_flag = /* A.2.1 (baseline profile constraints) */ + profile == GST_VAAPI_PROFILE_H264_BASELINE || + profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + constraint_set1_flag = /* A.2.2 (main profile constraints) */ + profile == GST_VAAPI_PROFILE_H264_MAIN || + profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + constraint_set2_flag = 0; + constraint_set3_flag = 0; + + /* profile_idc */ + WRITE_UINT32 (bs, profile_idc, 8); + /* constraint_set0_flag */ + WRITE_UINT32 (bs, constraint_set0_flag, 1); + /* constraint_set1_flag */ + WRITE_UINT32 (bs, constraint_set1_flag, 1); + /* constraint_set2_flag */ + WRITE_UINT32 (bs, constraint_set2_flag, 1); + /* constraint_set3_flag */ + WRITE_UINT32 (bs, constraint_set3_flag, 1); + /* reserved_zero_4bits */ + WRITE_UINT32 (bs, 0, 4); + /* level_idc */ + WRITE_UINT32 (bs, seq_param->level_idc, 8); + /* seq_parameter_set_id */ + WRITE_UE (bs, seq_param->seq_parameter_set_id); + + if (profile == GST_VAAPI_PROFILE_H264_HIGH || + profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH || + profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { + /* for high profile */ + /* chroma_format_idc = 1, 4:2:0 */ + WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc); + if (3 == seq_param->seq_fields.bits.chroma_format_idc) { + WRITE_UINT32 (bs, residual_color_transform_flag, 1); + } + /* bit_depth_luma_minus8 */ + WRITE_UE (bs, seq_param->bit_depth_luma_minus8); + /* bit_depth_chroma_minus8 */ + WRITE_UE (bs, seq_param->bit_depth_chroma_minus8); + /* b_qpprime_y_zero_transform_bypass */ + WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1); + + /* seq_scaling_matrix_present_flag */ + g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0); + WRITE_UINT32 (bs, + seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1); + +#if 0 + if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) { + for (i = 0; + i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); + i++) { + gst_bit_writer_put_bits_uint8 (bs, + seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1); + if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) { + g_assert (0); + /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */ + } + } + } +#endif + } + + /* log2_max_frame_num_minus4 */ + WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4); + /* pic_order_cnt_type */ + WRITE_UE (bs, seq_param->seq_fields.bits.pic_order_cnt_type); + + if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) { + /* log2_max_pic_order_cnt_lsb_minus4 */ + WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4); + } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { + g_assert (0 && "only POC type 0 is supported"); + WRITE_UINT32 (bs, + seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1); + WRITE_SE (bs, seq_param->offset_for_non_ref_pic); + WRITE_SE (bs, seq_param->offset_for_top_to_bottom_field); + WRITE_UE (bs, seq_param->num_ref_frames_in_pic_order_cnt_cycle); + for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) { + WRITE_SE (bs, seq_param->offset_for_ref_frame[i]); + } + } + + /* num_ref_frames */ + WRITE_UE (bs, seq_param->max_num_ref_frames); + /* gaps_in_frame_num_value_allowed_flag */ + WRITE_UINT32 (bs, gaps_in_frame_num_value_allowed_flag, 1); + + /* pic_width_in_mbs_minus1 */ + WRITE_UE (bs, seq_param->picture_width_in_mbs - 1); + /* pic_height_in_map_units_minus1 */ + WRITE_UE (bs, pic_height_in_map_units - 1); + /* frame_mbs_only_flag */ + WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1); + + if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs + g_assert (0 && "only progressive frames encoding is supported"); + WRITE_UINT32 (bs, mb_adaptive_frame_field, 1); + } + + /* direct_8x8_inference_flag */ + WRITE_UINT32 (bs, 0, 1); + /* frame_cropping_flag */ + WRITE_UINT32 (bs, seq_param->frame_cropping_flag, 1); + + if (seq_param->frame_cropping_flag) { + /* frame_crop_left_offset */ + WRITE_UE (bs, seq_param->frame_crop_left_offset); + /* frame_crop_right_offset */ + WRITE_UE (bs, seq_param->frame_crop_right_offset); + /* frame_crop_top_offset */ + WRITE_UE (bs, seq_param->frame_crop_top_offset); + /* frame_crop_bottom_offset */ + WRITE_UE (bs, seq_param->frame_crop_bottom_offset); + } + + /* vui_parameters_present_flag */ + WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1); + if (seq_param->vui_parameters_present_flag) { + /* aspect_ratio_info_present_flag */ + WRITE_UINT32 (bs, + seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1); + if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { + WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8); + if (seq_param->aspect_ratio_idc == 0xFF) { + WRITE_UINT32 (bs, seq_param->sar_width, 16); + WRITE_UINT32 (bs, seq_param->sar_height, 16); + } + } + + /* overscan_info_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* video_signal_type_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* chroma_loc_info_present_flag */ + WRITE_UINT32 (bs, 0, 1); + + /* timing_info_present_flag */ + WRITE_UINT32 (bs, seq_param->vui_fields.bits.timing_info_present_flag, 1); + if (seq_param->vui_fields.bits.timing_info_present_flag) { + WRITE_UINT32 (bs, seq_param->num_units_in_tick, 32); + WRITE_UINT32 (bs, seq_param->time_scale, 32); + WRITE_UINT32 (bs, 1, 1); /* fixed_frame_rate_flag */ + } + + /* nal_hrd_parameters_present_flag */ + nal_hrd_parameters_present_flag = seq_param->bits_per_second > 0; + WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1); + if (nal_hrd_parameters_present_flag) { + /* hrd_parameters */ + /* cpb_cnt_minus1 */ + WRITE_UE (bs, 0); + WRITE_UINT32 (bs, SX_BITRATE - 6, 4); /* bit_rate_scale */ + WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4); /* cpb_size_scale */ + + for (i = 0; i < 1; ++i) { + /* bit_rate_value_minus1[0] */ + WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1); + /* cpb_size_value_minus1[0] */ + WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1); + /* cbr_flag[0] */ + WRITE_UINT32 (bs, 1, 1); + } + /* initial_cpb_removal_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + /* cpb_removal_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + /* dpb_output_delay_length_minus1 */ + WRITE_UINT32 (bs, 23, 5); + /* time_offset_length */ + WRITE_UINT32 (bs, 23, 5); + } + + /* vcl_hrd_parameters_present_flag */ + WRITE_UINT32 (bs, 0, 1); + + if (nal_hrd_parameters_present_flag + || 0 /*vcl_hrd_parameters_present_flag */ ) { + /* low_delay_hrd_flag */ + WRITE_UINT32 (bs, 0, 1); + } + /* pic_struct_present_flag */ + WRITE_UINT32 (bs, 1, 1); + /* bs_restriction_flag */ + WRITE_UINT32 (bs, 0, 1); + } + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SPS NAL unit"); + return FALSE; + } +} + +static gboolean +bs_write_sps (GstVaapiFEIPakH264 * feipak, GstBitWriter * bs, + const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, + const VAEncMiscParameterHRD * hrd_params) +{ + if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) + return FALSE; + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + + return FALSE; +} + +static gboolean +bs_write_subset_sps (GstVaapiFEIPakH264 * feipak, GstBitWriter * bs, + const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, + guint num_views, guint16 * view_ids, + const VAEncMiscParameterHRD * hrd_params) +{ + guint32 i, j, k; + + if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) + return FALSE; + + if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH || + profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH) { + guint32 num_views_minus1, num_level_values_signalled_minus1; + + num_views_minus1 = num_views - 1; + g_assert (num_views_minus1 < 1024); + + /* bit equal to one */ + WRITE_UINT32 (bs, 1, 1); + + WRITE_UE (bs, num_views_minus1); + + for (i = 0; i <= num_views_minus1; i++) + WRITE_UE (bs, view_ids[i]); + + for (i = 1; i <= num_views_minus1; i++) { + guint32 num_anchor_refs_l0 = 0; + guint32 num_anchor_refs_l1 = 0; + + WRITE_UE (bs, num_anchor_refs_l0); + for (j = 0; j < num_anchor_refs_l0; j++) + WRITE_UE (bs, 0); + + WRITE_UE (bs, num_anchor_refs_l1); + for (j = 0; j < num_anchor_refs_l1; j++) + WRITE_UE (bs, 0); + } + + for (i = 1; i <= num_views_minus1; i++) { + guint32 num_non_anchor_refs_l0 = 0; + guint32 num_non_anchor_refs_l1 = 0; + + WRITE_UE (bs, num_non_anchor_refs_l0); + for (j = 0; j < num_non_anchor_refs_l0; j++) + WRITE_UE (bs, 0); + + WRITE_UE (bs, num_non_anchor_refs_l1); + for (j = 0; j < num_non_anchor_refs_l1; j++) + WRITE_UE (bs, 0); + } + + /* num level values signalled minus1 */ + num_level_values_signalled_minus1 = 0; + g_assert (num_level_values_signalled_minus1 < 64); + WRITE_UE (bs, num_level_values_signalled_minus1); + + for (i = 0; i <= num_level_values_signalled_minus1; i++) { + guint16 num_applicable_ops_minus1 = 0; + g_assert (num_applicable_ops_minus1 < 1024); + + WRITE_UINT32 (bs, seq_param->level_idc, 8); + WRITE_UE (bs, num_applicable_ops_minus1); + + for (j = 0; j <= num_applicable_ops_minus1; j++) { + guint8 temporal_id = 0; + guint16 num_target_views_minus1 = 1; + + WRITE_UINT32 (bs, temporal_id, 3); + WRITE_UE (bs, num_target_views_minus1); + + for (k = 0; k <= num_target_views_minus1; k++) + WRITE_UE (bs, k); + + WRITE_UE (bs, num_views_minus1); + } + } + + /* mvc_vui_parameters_present_flag */ + WRITE_UINT32 (bs, 0, 1); + } + + /* additional_extension2_flag */ + WRITE_UINT32 (bs, 0, 1); + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write subset SPS NAL unit"); + return FALSE; + } + return FALSE; +} + +/* Write a PPS NAL unit */ +static gboolean +bs_write_pps (GstBitWriter * bs, + const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile) +{ + guint32 num_slice_groups_minus1 = 0; + guint32 pic_init_qs_minus26 = 0; + guint32 redundant_pic_cnt_present_flag = 0; + + /* pic_parameter_set_id */ + WRITE_UE (bs, pic_param->pic_parameter_set_id); + /* seq_parameter_set_id */ + WRITE_UE (bs, pic_param->seq_parameter_set_id); + /* entropy_coding_mode_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1); + /* pic_order_present_flag */ + WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_order_present_flag, 1); + /* slice_groups-1 */ + WRITE_UE (bs, num_slice_groups_minus1); + + if (num_slice_groups_minus1 > 0) { + /*FIXME*/ g_assert (0 && "unsupported arbitrary slice ordering (ASO)"); + } + WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1); + WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1); + WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1); + WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2); + /* pic_init_qp_minus26 */ + WRITE_SE (bs, pic_param->pic_init_qp - 26); + /* pic_init_qs_minus26 */ + WRITE_SE (bs, pic_init_qs_minus26); + /* chroma_qp_index_offset */ + WRITE_SE (bs, pic_param->chroma_qp_index_offset); + + WRITE_UINT32 (bs, + pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1); + WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1); + WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1); + + /* more_rbsp_data */ + if (profile == GST_VAAPI_PROFILE_H264_HIGH) { + WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1); + WRITE_UINT32 (bs, + pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1); + if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) { + g_assert (0 && "unsupported scaling lists"); + /* FIXME */ + /* + for (i = 0; i < + (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag)); + i++) { + gst_bit_writer_put_bits_uint8(bs, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1); + } + */ + } + WRITE_SE (bs, pic_param->second_chroma_qp_index_offset); + } + + /* rbsp_trailing_bits */ + bs_write_trailing_bits (bs); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write PPS NAL unit"); + return FALSE; + } +} + +/* Write a Slice NAL unit */ +static gboolean +bs_write_slice (GstBitWriter * bs, + const VAEncSliceParameterBufferH264 * slice_param, + GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture) +{ + const VAEncPictureParameterBufferH264 *const pic_param = picture->param; + guint32 field_pic_flag = 0; + guint32 ref_pic_list_modification_flag_l0 = 0; + guint32 ref_pic_list_modification_flag_l1 = 0; + guint32 no_output_of_prior_pics_flag = 0; + guint32 long_term_reference_flag = 0; + guint32 adaptive_ref_pic_marking_mode_flag = 0; + + /* first_mb_in_slice */ + WRITE_UE (bs, slice_param->macroblock_address); + /* slice_type */ + WRITE_UE (bs, slice_param->slice_type); + /* pic_parameter_set_id */ + WRITE_UE (bs, slice_param->pic_parameter_set_id); + /* frame_num */ + WRITE_UINT32 (bs, picture->frame_num, + feipak->h264_sps.seq_fields.bits.log2_max_frame_num_minus4 + 4); + + /* XXX: only frames (i.e. non-interlaced) are supported for now */ + /* frame_mbs_only_flag == 0 */ + + /* idr_pic_id */ + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + WRITE_UE (bs, slice_param->idr_pic_id); + + /* XXX: only POC type 0 is supported */ + if (!feipak->h264_sps.seq_fields.bits.pic_order_cnt_type) { + WRITE_UINT32 (bs, slice_param->pic_order_cnt_lsb, + feipak->h264_sps.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4); + /* bottom_field_pic_order_in_frame_present_flag is FALSE */ + if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag) + WRITE_SE (bs, slice_param->delta_pic_order_cnt_bottom); + } else if (feipak->h264_sps.seq_fields.bits.pic_order_cnt_type == 1 && + !feipak->h264_sps.seq_fields.bits.delta_pic_order_always_zero_flag) { + WRITE_SE (bs, slice_param->delta_pic_order_cnt[0]); + if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag) + WRITE_SE (bs, slice_param->delta_pic_order_cnt[1]); + } + /* redundant_pic_cnt_present_flag is FALSE, no redundant coded pictures */ + + /* only works for B-frames */ + if (slice_param->slice_type == GST_H264_B_SLICE) + WRITE_UINT32 (bs, slice_param->direct_spatial_mv_pred_flag, 1); + + /* not supporting SP slices */ + if (slice_param->slice_type == 0 || slice_param->slice_type == 1) { + WRITE_UINT32 (bs, slice_param->num_ref_idx_active_override_flag, 1); + if (slice_param->num_ref_idx_active_override_flag) { + WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1); + if (slice_param->slice_type == 1) + WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1); + } + } + /* XXX: not supporting custom reference picture list modifications */ + if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4)) + WRITE_UINT32 (bs, ref_pic_list_modification_flag_l0, 1); + if (slice_param->slice_type == 1) + WRITE_UINT32 (bs, ref_pic_list_modification_flag_l1, 1); + + /* we have: weighted_pred_flag == FALSE and */ + /* : weighted_bipred_idc == FALSE */ + if ((pic_param->pic_fields.bits.weighted_pred_flag && + (slice_param->slice_type == 0)) || + ((pic_param->pic_fields.bits.weighted_bipred_idc == 1) && + (slice_param->slice_type == 1))) { + /* XXXX: add pred_weight_table() */ + } + + /* dec_ref_pic_marking() */ + if (slice_param->slice_type == 0 || slice_param->slice_type == 2) { + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { + /* no_output_of_prior_pics_flag = 0 */ + WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1); + /* long_term_reference_flag = 0 */ + WRITE_UINT32 (bs, long_term_reference_flag, 1); + } else { + /* only sliding_window reference picture marking mode is supported */ + /* adpative_ref_pic_marking_mode_flag = 0 */ + WRITE_UINT32 (bs, adaptive_ref_pic_marking_mode_flag, 1); + } + } + + /* cabac_init_idc */ + if (pic_param->pic_fields.bits.entropy_coding_mode_flag && + slice_param->slice_type != 2) + WRITE_UE (bs, slice_param->cabac_init_idc); + /*slice_qp_delta */ + WRITE_SE (bs, slice_param->slice_qp_delta); + + /* XXX: only supporting I, P and B type slices */ + /* no sp_for_switch_flag and no slice_qs_delta */ + + if (pic_param->pic_fields.bits.deblocking_filter_control_present_flag) { + /* disable_deblocking_filter_idc */ + WRITE_UE (bs, slice_param->disable_deblocking_filter_idc); + if (slice_param->disable_deblocking_filter_idc != 1) { + WRITE_SE (bs, slice_param->slice_alpha_c0_offset_div2); + WRITE_SE (bs, slice_param->slice_beta_offset_div2); + } + } + + /* XXX: unsupported arbitrary slice ordering (ASO) */ + /* num_slic_groups_minus1 should be zero */ + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Slice NAL unit"); + return FALSE; + } +} + +static inline void +_check_sps_pps_status (GstVaapiFEIPakH264 * feipak, + const guint8 * nal, guint32 size) +{ + guint8 nal_type; + G_GNUC_UNUSED gsize ret; /* FIXME */ + gboolean has_subset_sps; + + g_assert (size); + + has_subset_sps = !feipak->is_mvc || (feipak->subset_sps_data != NULL); + if (feipak->sps_data && feipak->pps_data && has_subset_sps) + return; + + nal_type = nal[0] & 0x1F; + switch (nal_type) { + case GST_H264_NAL_SPS: + feipak->sps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (feipak->sps_data, 0, nal, size); + g_assert (ret == size); + break; + case GST_H264_NAL_SUBSET_SPS: + feipak->subset_sps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (feipak->subset_sps_data, 0, nal, size); + g_assert (ret == size); + break; + case GST_H264_NAL_PPS: + feipak->pps_data = gst_buffer_new_allocate (NULL, size, NULL); + ret = gst_buffer_fill (feipak->pps_data, 0, nal, size); + g_assert (ret == size); + break; + default: + break; + } +} + +/* Determines the largest supported profile by the underlying hardware */ +static gboolean +ensure_hw_profile_limits (GstVaapiFEIPakH264 * feipak) +{ + GstVaapiDisplay *const display = feipak->display; + GArray *profiles; + guint i, profile_idc, max_profile_idc; + + if (feipak->hw_max_profile_idc) + return TRUE; + + profiles = gst_vaapi_display_get_encode_profiles (display); + if (!profiles) + return FALSE; + + max_profile_idc = 0; + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index (profiles, GstVaapiProfile, i); + profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); + if (!profile_idc) + continue; + if (max_profile_idc < profile_idc) + max_profile_idc = profile_idc; + } + g_array_unref (profiles); + + feipak->hw_max_profile_idc = max_profile_idc; + return TRUE; +} + +/* Fills in VA HRD parameters */ +static void +fill_hrd_params (GstVaapiFEIPakH264 * feipak, VAEncMiscParameterHRD * hrd) +{ + hrd->buffer_size = 0; + hrd->initial_buffer_fullness = 0; +} + +/* Adds the supplied sequence header (SPS) to the list of packed + headers to pass down as-is to the feipak */ +static gboolean +add_packed_sequence_header (GstVaapiFEIPakH264 * feipak, + GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) +{ + GstVaapiEncPackedHeader *packed_seq; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 }; + const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; + GstVaapiProfile profile = feipak->profile; + + VAEncMiscParameterHRD hrd_params; + guint32 data_bit_size; + guint8 *data; + + fill_hrd_params (feipak, &hrd_params); + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS); + /* Set High profile for encoding the MVC base view. Otherwise, some + traditional decoder cannot recognize MVC profile streams with + only the base view in there */ + if (profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH || + profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) + profile = GST_VAAPI_PROFILE_H264_HIGH; + + bs_write_sps (feipak, &bs, seq_param, profile, &hrd_params); + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_seq_param.type = VAEncPackedHeaderSequence; + packed_seq_param.bit_length = data_bit_size; + packed_seq_param.has_emulation_bytes = 0; + + packed_seq = + gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder), + &packed_seq_param, sizeof (packed_seq_param), data, + (data_bit_size + 7) / 8); + g_assert (packed_seq); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); + gst_vaapi_codec_object_replace (&packed_seq, NULL); + + /* store sps data */ + _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +static gboolean +add_packed_sequence_header_mvc (GstVaapiFEIPakH264 * feipak, + GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) +{ + GstVaapiEncPackedHeader *packed_seq; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; + const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; + VAEncMiscParameterHRD hrd_params; + guint32 data_bit_size; + guint8 *data; + + fill_hrd_params (feipak, &hrd_params); + + /* non-base layer, pack one subset sps */ + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS); + + bs_write_subset_sps (feipak, &bs, seq_param, feipak->profile, + feipak->num_views, feipak->view_ids, &hrd_params); + + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_header_param_buffer.type = VAEncPackedHeaderSequence; + packed_header_param_buffer.bit_length = data_bit_size; + packed_header_param_buffer.has_emulation_bytes = 0; + + packed_seq = + gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder), + &packed_header_param_buffer, sizeof (packed_header_param_buffer), data, + (data_bit_size + 7) / 8); + g_assert (packed_seq); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL); + + /* store subset sps data */ + _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write SPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +/* Adds the supplied picture header (PPS) to the list of packed + headers to pass down as-is to the feipak */ +static gboolean +add_packed_picture_header (GstVaapiFEIPakH264 * feipak, + GstVaapiEncPicture * picture) +{ + GstVaapiEncPackedHeader *packed_pic; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 }; + const VAEncPictureParameterBufferH264 *const pic_param = picture->param; + guint32 data_bit_size; + guint8 *data; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS); + bs_write_pps (&bs, pic_param, feipak->profile); + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_pic_param.type = VAEncPackedHeaderPicture; + packed_pic_param.bit_length = data_bit_size; + packed_pic_param.has_emulation_bytes = 0; + + packed_pic = + gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder), + &packed_pic_param, sizeof (packed_pic_param), data, + (data_bit_size + 7) / 8); + g_assert (packed_pic); + + gst_vaapi_enc_picture_add_packed_header (picture, packed_pic); + gst_vaapi_codec_object_replace (&packed_pic, NULL); + + /* store pps data */ + _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4); + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write PPS NAL unit"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +static gboolean +get_nal_hdr_attributes (GstVaapiEncPicture * picture, + guint8 * nal_ref_idc, guint8 * nal_unit_type) +{ + switch (picture->type) { + case GST_VAAPI_PICTURE_TYPE_I: + *nal_ref_idc = GST_H264_NAL_REF_IDC_HIGH; + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) + *nal_unit_type = GST_H264_NAL_SLICE_IDR; + else + *nal_unit_type = GST_H264_NAL_SLICE; + break; + case GST_VAAPI_PICTURE_TYPE_P: + *nal_ref_idc = GST_H264_NAL_REF_IDC_MEDIUM; + *nal_unit_type = GST_H264_NAL_SLICE; + break; + case GST_VAAPI_PICTURE_TYPE_B: + *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE; + *nal_unit_type = GST_H264_NAL_SLICE; + break; + default: + return FALSE; + } + return TRUE; +} + +/* Adds the supplied prefix nal header to the list of packed + headers to pass down as-is to the feipak */ +static gboolean +add_packed_prefix_nal_header (GstVaapiFEIPakH264 * feipak, + GstVaapiEncPicture * picture, GstVaapiEncSlice * slice) +{ + GstVaapiEncPackedHeader *packed_prefix_nal; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_prefix_nal_param = { 0 }; + guint32 data_bit_size; + guint8 *data; + guint8 nal_ref_idc, nal_unit_type; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + + if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) + goto bs_error; + nal_unit_type = GST_H264_NAL_PREFIX_UNIT; + + bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); + bs_write_nal_header_mvc_extension (&bs, picture, feipak->view_idx); + g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_prefix_nal_param.type = VAEncPackedHeaderRawData; + packed_prefix_nal_param.bit_length = data_bit_size; + packed_prefix_nal_param.has_emulation_bytes = 0; + + packed_prefix_nal = + gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder), + &packed_prefix_nal_param, sizeof (packed_prefix_nal_param), data, + (data_bit_size + 7) / 8); + g_assert (packed_prefix_nal); + + gst_vaapi_enc_slice_add_packed_header (slice, packed_prefix_nal); + gst_vaapi_codec_object_replace (&packed_prefix_nal, NULL); + + gst_bit_writer_clear (&bs, TRUE); + + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Prefix NAL unit header"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +/* Adds the supplied slice header to the list of packed + headers to pass down as-is to the feipak */ +static gboolean +add_packed_slice_header (GstVaapiFEIPakH264 * feipak, + GstVaapiEncPicture * picture, GstVaapiEncSlice * slice) +{ + GstVaapiEncPackedHeader *packed_slice; + GstBitWriter bs; + VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 }; + const VAEncSliceParameterBufferH264 *const slice_param = slice->param; + guint32 data_bit_size; + guint8 *data; + guint8 nal_ref_idc, nal_unit_type; + + gst_bit_writer_init (&bs, 128 * 8); + WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ + + if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) + goto bs_error; + /* pack nal_unit_header_mvc_extension() for the non base view */ + if (feipak->is_mvc && feipak->view_idx) { + bs_write_nal_header (&bs, nal_ref_idc, GST_H264_NAL_SLICE_EXT); + bs_write_nal_header_mvc_extension (&bs, picture, + feipak->view_ids[feipak->view_idx]); + } else + bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); + + bs_write_slice (&bs, slice_param, feipak, picture); + data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); + data = GST_BIT_WRITER_DATA (&bs); + + packed_slice_param.type = VAEncPackedHeaderSlice; + packed_slice_param.bit_length = data_bit_size; + packed_slice_param.has_emulation_bytes = 0; + + packed_slice = + gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder), + &packed_slice_param, sizeof (packed_slice_param), data, + (data_bit_size + 7) / 8); + g_assert (packed_slice); + + gst_vaapi_enc_slice_add_packed_header (slice, packed_slice); + gst_vaapi_codec_object_replace (&packed_slice, NULL); + + gst_bit_writer_clear (&bs, TRUE); + return TRUE; + + /* ERRORS */ +bs_error: + { + GST_WARNING ("failed to write Slice NAL unit header"); + gst_bit_writer_clear (&bs, TRUE); + return FALSE; + } +} + +/* Reference picture management */ +static void +reference_pic_free (GstVaapiFEIPakH264 * feipak, GstVaapiFEIPakH264Ref * ref) +{ + if (!ref) + return; + if (ref->pic) + gst_vaapi_surface_proxy_unref (ref->pic); + g_slice_free (GstVaapiFEIPakH264Ref, ref); +} + +static inline GstVaapiFEIPakH264Ref * +reference_pic_create (GstVaapiFEIPakH264 * feipak, + GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) +{ + GstVaapiFEIPakH264Ref *const ref = g_slice_new0 (GstVaapiFEIPakH264Ref); + + ref->pic = surface; + ref->frame_num = picture->frame_num; + ref->poc = picture->poc; + return ref; +} + +static gboolean +reference_list_update (GstVaapiFEIPakH264 * feipak, + GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) +{ + GstVaapiFEIPakH264Ref *ref; + GstVaapiH264FEIPakViewRefPool *const ref_pool = + &feipak->ref_pools[feipak->view_idx]; + + if (GST_VAAPI_PICTURE_TYPE_B == picture->type) { + gst_vaapi_surface_proxy_unref (surface); + return TRUE; + } + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { + while (!g_queue_is_empty (&ref_pool->ref_list)) + reference_pic_free (feipak, g_queue_pop_head (&ref_pool->ref_list)); + } else if (g_queue_get_length (&ref_pool->ref_list) >= + ref_pool->max_ref_frames) { + reference_pic_free (feipak, g_queue_pop_head (&ref_pool->ref_list)); + } + ref = reference_pic_create (feipak, picture, surface); + g_queue_push_tail (&ref_pool->ref_list, ref); + g_assert (g_queue_get_length (&ref_pool->ref_list) <= + ref_pool->max_ref_frames); + return TRUE; +} + +static gboolean +reference_list_init (GstVaapiFEIPakH264 * feipak, + GstVaapiEncPicture * picture, + GstVaapiFEIPakH264Ref ** reflist_0, + guint * reflist_0_count, + GstVaapiFEIPakH264Ref ** reflist_1, guint * reflist_1_count) +{ + GstVaapiFEIPakH264Ref *tmp; + GstVaapiH264FEIPakViewRefPool *const ref_pool = + &feipak->ref_pools[feipak->view_idx]; + GList *iter, *list_0_start = NULL, *list_1_start = NULL; + guint count; + + *reflist_0_count = 0; + *reflist_1_count = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_I) + return TRUE; + + iter = g_queue_peek_tail_link (&ref_pool->ref_list); + for (; iter; iter = g_list_previous (iter)) { + tmp = (GstVaapiFEIPakH264Ref *) iter->data; + g_assert (tmp && tmp->poc != picture->poc); + if (_poc_greater_than (picture->poc, tmp->poc, + 1 << (feipak->h264_sps.seq_fields.bits. + log2_max_pic_order_cnt_lsb_minus4 + 4))) { + list_0_start = iter; + list_1_start = g_list_next (iter); + break; + } + } + + /* order reflist_0 */ + g_assert (list_0_start); + iter = list_0_start; + count = 0; + for (; iter; iter = g_list_previous (iter)) { + reflist_0[count] = (GstVaapiFEIPakH264Ref *) iter->data; + ++count; + } + *reflist_0_count = count; + + if (picture->type != GST_VAAPI_PICTURE_TYPE_B) + return TRUE; + + /* order reflist_1 */ + count = 0; + iter = list_1_start; + for (; iter; iter = g_list_next (iter)) { + reflist_1[count] = (GstVaapiFEIPakH264Ref *) iter->data; + ++count; + } + *reflist_1_count = count; + return TRUE; +} + +/* Fills in VA sequence parameter buffer */ +static gboolean +fill_sequence (GstVaapiFEIPakH264 * feipak, GstVaapiEncSequence * sequence) +{ + VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; + + memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264)); + *seq_param = feipak->h264_sps; + return TRUE; +} + +/* Fills in VA picture parameter buffer */ +static gboolean +fill_picture (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture, + GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) +{ + VAEncPictureParameterBufferH264 *const pic_param = picture->param; + GstVaapiH264FEIPakViewRefPool *const ref_pool = + &feipak->ref_pools[feipak->view_idx]; + GstVaapiFEIPakH264Ref *ref_pic; + GList *reflist; + guint i; + + memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264)); + *pic_param = feipak->h264_pps; + feipak->is_idr = feipak->h264_pps.pic_fields.bits.idr_pic_flag; + /* reference list, */ + pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); + pic_param->CurrPic.TopFieldOrderCnt = picture->poc; + pic_param->CurrPic.frame_idx = picture->frame_num; + i = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (reflist = g_queue_peek_head_link (&ref_pool->ref_list); + reflist; reflist = g_list_next (reflist)) { + ref_pic = reflist->data; + g_assert (ref_pic && ref_pic->pic && + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID); + + pic_param->ReferenceFrames[i].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); + pic_param->ReferenceFrames[i].TopFieldOrderCnt = ref_pic->poc; + pic_param->ReferenceFrames[i].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + pic_param->ReferenceFrames[i].frame_idx = ref_pic->frame_num; + ++i; + } + g_assert (i <= 16 && i <= ref_pool->max_ref_frames); + } + for (; i < 16; ++i) { + pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID; + pic_param->ReferenceFrames[i].frame_idx = VA_PICTURE_H264_INVALID; + } + pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + + return TRUE; +} + +/* Adds slice headers to picture */ +static gboolean +add_slice_headers (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture, + GstVaapiFEIPakH264Ref ** reflist_0, guint reflist_0_count, + GstVaapiFEIPakH264Ref ** reflist_1, guint reflist_1_count) +{ + VAEncSliceParameterBufferH264 *slice_param; + GstVaapiEncSlice *slice; + guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs; + guint mb_size; + guint last_mb_index; + guint i_slice, i_ref; + GArray *h264_slice_params = feipak->h264_slice_params; + + g_assert (picture); + + mb_size = feipak->mb_width * feipak->mb_height; + + g_assert (feipak->num_slices && feipak->num_slices < mb_size); + slice_of_mbs = mb_size / feipak->num_slices; + slice_mod_mbs = mb_size % feipak->num_slices; + last_mb_index = 0; + for (i_slice = 0; i_slice < feipak->num_slices; ++i_slice) { + cur_slice_mbs = slice_of_mbs; + if (slice_mod_mbs) { + ++cur_slice_mbs; + --slice_mod_mbs; + } + slice = GST_VAAPI_ENC_SLICE_NEW (H264, feipak->encoder); + g_assert (slice && slice->param_id != VA_INVALID_ID); + slice_param = slice->param; + + memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264)); + *slice_param = + g_array_index (h264_slice_params, VAEncSliceParameterBufferH264, + i_slice); + g_assert ((gint8) slice_param->slice_type != -1); + g_assert (slice_param->num_ref_idx_l0_active_minus1 >= 0); + g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0); + + i_ref = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (; i_ref < reflist_0_count; ++i_ref) { + slice_param->RefPicList0[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); + slice_param->RefPicList0[i_ref].TopFieldOrderCnt = + reflist_0[i_ref]->poc; + slice_param->RefPicList0[i_ref].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + slice_param->RefPicList0[i_ref].frame_idx = reflist_0[i_ref]->frame_num; + } + g_assert (i_ref >= 1); + } + for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) { + slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->RefPicList0[i_ref].frame_idx = VA_PICTURE_H264_INVALID; + } + + i_ref = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + for (; i_ref < reflist_1_count; ++i_ref) { + slice_param->RefPicList1[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); + slice_param->RefPicList1[i_ref].TopFieldOrderCnt = + reflist_1[i_ref]->poc; + slice_param->RefPicList1[i_ref].flags |= + VA_PICTURE_H264_SHORT_TERM_REFERENCE; + slice_param->RefPicList1[i_ref].frame_idx = reflist_1[i_ref]->frame_num; + } + g_assert (i_ref == 1); + } + for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) { + slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->RefPicList1[i_ref].frame_idx = VA_PICTURE_H264_INVALID; + } + + /* set calculation for next slice */ + last_mb_index += cur_slice_mbs; + + /* add packed Prefix NAL unit before each Coded slice NAL in base view */ + if (feipak->is_mvc && !feipak->view_idx + && !add_packed_prefix_nal_header (feipak, picture, slice)) + goto error_create_packed_prefix_nal_hdr; + if (!add_packed_slice_header (feipak, picture, slice)) + goto error_create_packed_slice_hdr; + + gst_vaapi_enc_picture_add_slice (picture, slice); + gst_vaapi_codec_object_replace (&slice, NULL); + } + g_assert (last_mb_index == mb_size); + return TRUE; + +error_create_packed_slice_hdr: + { + GST_ERROR ("failed to create packed slice header buffer"); + gst_vaapi_codec_object_replace (&slice, NULL); + return FALSE; + } +error_create_packed_prefix_nal_hdr: + { + GST_ERROR ("failed to create packed prefix nal header buffer"); + gst_vaapi_codec_object_replace (&slice, NULL); + return FALSE; + } +} + +/* Generates and submits SPS header accordingly into the bitstream */ +static gboolean +ensure_sequence (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture) +{ + GstVaapiEncSequence *sequence = NULL; + + if (!feipak->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I) + return TRUE; + + sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, feipak->encoder); + if (!sequence || !fill_sequence (feipak, sequence)) + goto error_create_seq_param; + + /* add subset sps for non-base view and sps for base view */ + if (feipak->is_mvc && feipak->view_idx) { + if (!add_packed_sequence_header_mvc (feipak, picture, sequence)) + goto error_create_packed_seq_hdr; + } else { + if (!add_packed_sequence_header (feipak, picture, sequence)) + goto error_create_packed_seq_hdr; + } + + if (sequence) { + gst_vaapi_enc_picture_set_sequence (picture, sequence); + gst_vaapi_codec_object_replace (&sequence, NULL); + } + + if (!feipak->is_mvc || feipak->view_idx > 0) + feipak->config_changed = FALSE; + return TRUE; + + /* ERRORS */ +error_create_seq_param: + { + GST_ERROR ("failed to create sequence parameter buffer (SPS)"); + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; + } +error_create_packed_seq_hdr: + { + GST_ERROR ("failed to create packed sequence header buffer"); + gst_vaapi_codec_object_replace (&sequence, NULL); + return FALSE; + } +} + +/* Generates additional fei control parameters */ +static gboolean +ensure_fei_misc_params (GstVaapiFEIPakH264 * feipak, + GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy) +{ + GstVaapiEncMiscParam *misc = NULL; + VAEncMiscParameterFEIFrameControlH264 *misc_fei_pic_control_param; + + /*fei pic control params */ + misc = GST_VAAPI_ENC_FEI_MISC_PARAM_NEW (H264, feipak->encoder); + g_assert (misc); + if (!misc) + return FALSE; + + misc_fei_pic_control_param = misc->data; + misc_fei_pic_control_param->function = VA_FEI_FUNCTION_PAK; + misc_fei_pic_control_param->mv_predictor = VA_INVALID_ID; + misc_fei_pic_control_param->qp = VA_INVALID_ID; + misc_fei_pic_control_param->mb_ctrl = VA_INVALID_ID; + + g_assert (codedbuf_proxy->mbcode != NULL); + g_assert (codedbuf_proxy->mv != NULL); + + misc_fei_pic_control_param->mb_code_data = + GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mbcode)->param_id; + misc_fei_pic_control_param->mv_data = + GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mv)->param_id; + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + return TRUE; +} + +/* Generates additional control parameters */ +static gboolean +ensure_misc_params (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture) +{ + GstVaapiEncMiscParam *misc = NULL; + + /* HRD params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, feipak->encoder); + g_assert (misc); + if (!misc) + return FALSE; + fill_hrd_params (feipak, misc->data); + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + + return TRUE; +} + +/* Generates and submits PPS header accordingly into the bitstream */ +static gboolean +ensure_picture (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture, + GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) +{ + GstVaapiCodedBuffer *const codedbuf = + GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); + gboolean res = FALSE; + res = fill_picture (feipak, picture, codedbuf, surface); + + if (!res) + return FALSE; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_I + && !add_packed_picture_header (feipak, picture)) { + GST_ERROR ("set picture packed header failed"); + return FALSE; + } + return TRUE; +} + +/* Generates slice headers */ +static gboolean +ensure_slices (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture) +{ + GstVaapiFEIPakH264Ref *reflist_0[16]; + GstVaapiFEIPakH264Ref *reflist_1[16]; + GstVaapiH264FEIPakViewRefPool *const ref_pool = + &feipak->ref_pools[feipak->view_idx]; + guint reflist_0_count = 0, reflist_1_count = 0; + + g_assert (picture); + + if (picture->type != GST_VAAPI_PICTURE_TYPE_I && + !reference_list_init (feipak, picture, + reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) { + GST_ERROR ("reference list reorder failed"); + return FALSE; + } + + g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames); + if (reflist_0_count > ref_pool->max_reflist0_count) + reflist_0_count = ref_pool->max_reflist0_count; + if (reflist_1_count > ref_pool->max_reflist1_count) + reflist_1_count = ref_pool->max_reflist1_count; + + if (!add_slice_headers (feipak, picture, + reflist_0, reflist_0_count, reflist_1, reflist_1_count)) + return FALSE; + + return TRUE; +} + +/* Constructs profile and level information based on user-defined limits */ +static GstVaapiEncoderStatus +ensure_profile_and_level (GstVaapiFEIPakH264 * feipak) +{ + const GstVaapiProfile profile = feipak->profile; + + /* Check HW constraints */ + if (!ensure_hw_profile_limits (feipak)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + if (feipak->profile_idc > feipak->hw_max_profile_idc) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + if (feipak->profile != profile) { + feipak->config_changed = TRUE; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static void +reset_properties (GstVaapiFEIPakH264 * feipak) +{ + guint i; + guint max_reflist0_count; + if (feipak->num_bframes > 0) { + if (feipak->num_ref_frames == 1) { + GST_INFO ("num ref frames is modified as 2 as b frame is set"); + feipak->num_ref_frames = 2; + } + max_reflist0_count = feipak->num_ref_frames - 1; + } else { + max_reflist0_count = feipak->num_ref_frames; + } + max_reflist0_count = max_reflist0_count > 5 ? 5 : max_reflist0_count; + + for (i = 0; i < feipak->num_views; i++) { + GstVaapiH264FEIPakViewRefPool *const ref_pool = &feipak->ref_pools[i]; + + ref_pool->max_reflist0_count = max_reflist0_count; + ref_pool->max_reflist1_count = feipak->num_bframes > 0; + ref_pool->max_ref_frames = ref_pool->max_reflist0_count + + ref_pool->max_reflist1_count; + + } +} + +GstVaapiEncoderStatus +gst_vaapi_feipak_h264_encode (GstVaapiFEIPakH264 * feipak, + GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf, + GstVaapiSurfaceProxy * surface, GstVaapiFeiInfoToPakH264 * info_to_pak) +{ + GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + GstVaapiSurfaceProxy *reconstruct = surface; + GstVaapiSurfaceProxy *proxy = picture->proxy; + VAEncSliceParameterBufferH264 slice_header; + + g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct)); + g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (proxy)); + + g_assert (info_to_pak != NULL); + + feipak->h264_sps = info_to_pak->h264_enc_sps; + feipak->h264_pps = info_to_pak->h264_enc_pps; + feipak->h264_slice_params = info_to_pak->h264_slice_headers; + + feipak->mb_width = feipak->h264_sps.picture_width_in_mbs; + feipak->mb_height = feipak->h264_sps.picture_height_in_mbs; + + slice_header = + g_array_index (feipak->h264_slice_params, VAEncSliceParameterBufferH264, + 0); + feipak->slice_type = slice_header.slice_type; + + if (!ensure_sequence (feipak, picture)) + goto error; + if (!ensure_misc_params (feipak, picture)) + goto error; + if (!ensure_fei_misc_params (feipak, picture, codedbuf)) + goto error; + if (!ensure_picture (feipak, picture, codedbuf, reconstruct)) + goto error; + if (!ensure_slices (feipak, picture)) + goto error; + if (!gst_vaapi_enc_picture_encode (picture)) + goto error; + + if (!reference_list_update (feipak, picture, reconstruct)) + goto error; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +error: + return ret; +} + +GstVaapiEncoderStatus +gst_vaapi_feipak_h264_flush (GstVaapiFEIPakH264 * feipak) +{ + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +GstVaapiEncoderStatus +gst_vaapi_feipak_h264_reconfigure (GstVaapiFEIPakH264 * feipak, + VAContextID va_context, GstVaapiProfile profile, + guint8 profile_idc, guint mb_width, guint mb_height, + guint32 num_views, guint slices_num, guint32 num_ref_frames) +{ + GstVaapiEncoderStatus status; + + if (mb_width != feipak->mb_width || mb_height != feipak->mb_height) { + feipak->mb_width = mb_width; + feipak->mb_height = mb_height; + feipak->config_changed = TRUE; + } + + feipak->va_context = va_context; + + /* Take number of MVC views from input caps if provided */ + feipak->num_views = num_views; + + feipak->is_mvc = feipak->num_views > 1; + + feipak->profile_idc = profile_idc; + feipak->profile = profile; + feipak->num_slices = slices_num; + feipak->num_ref_frames = num_ref_frames; + + status = ensure_profile_and_level (feipak); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + + reset_properties (feipak); + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static gboolean +gst_vaapi_feipak_h264_init (GstVaapiFEIPakH264 * feipak, + GstVaapiEncoder * encoder, GstVaapiDisplay * display, + VAContextID va_context) +{ + guint32 i; + + feipak->encoder = encoder; + /* Default encoding entrypoint */ + feipak->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI; + + feipak->h264_slice_params = NULL; + + /* Multi-view coding information */ + feipak->is_mvc = FALSE; + feipak->num_views = 1; + feipak->view_idx = 0; + feipak->display = display; + feipak->va_context = va_context; + + feipak->num_bframes = 0; + feipak->is_idr = FALSE; + /* default num ref frames */ + feipak->num_ref_frames = 1; + memset (feipak->view_ids, 0, sizeof (feipak->view_ids)); + + feipak->props_reconfigured = FALSE; + + /* reference list info initialize */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264FEIPakViewRefPool *const ref_pool = &feipak->ref_pools[i]; + g_queue_init (&ref_pool->ref_list); + ref_pool->max_ref_frames = 0; + ref_pool->max_reflist0_count = 1; + ref_pool->max_reflist1_count = 1; + } + + return TRUE; +} + +static void +gst_vaapi_feipak_h264_finalize (GstVaapiFEIPakH264 * feipak) +{ + GstVaapiFEIPakH264Ref *ref; + guint32 i; + + gst_buffer_replace (&feipak->sps_data, NULL); + gst_buffer_replace (&feipak->subset_sps_data, NULL); + gst_buffer_replace (&feipak->pps_data, NULL); + + /* reference list info de-init */ + for (i = 0; i < MAX_NUM_VIEWS; i++) { + GstVaapiH264FEIPakViewRefPool *const ref_pool = &feipak->ref_pools[i]; + while (!g_queue_is_empty (&ref_pool->ref_list)) { + ref = (GstVaapiFEIPakH264Ref *) g_queue_pop_head (&ref_pool->ref_list); + reference_pic_free (feipak, ref); + } + g_queue_clear (&ref_pool->ref_list); + } + +} + +GstVaapiEncoderStatus +gst_vaapi_feipak_h264_set_property (GstVaapiFEIPakH264 * feipak, + gint prop_id, const GValue * value) +{ + + switch (prop_id) { + case GST_VAAPI_FEIPAK_H264_PROP_MAX_BFRAMES: + feipak->num_bframes = g_value_get_uint (value); + break; + case GST_VAAPI_FEIPAK_H264_PROP_NUM_VIEWS: + feipak->num_views = g_value_get_uint (value); + break; + case GST_VAAPI_FEIPAK_H264_PROP_VIEW_IDS:{ + guint i; + GValueArray *view_ids = g_value_get_boxed (value); + + if (view_ids == NULL) { + for (i = 0; i < feipak->num_views; i++) + feipak->view_ids[i] = i; + } else { + g_assert (view_ids->n_values <= feipak->num_views); + + for (i = 0; i < feipak->num_views; i++) { + GValue *val = g_value_array_get_nth (view_ids, i); + feipak->view_ids[i] = g_value_get_uint (val); + } + } + break; + } + default: + return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; + } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static inline const GstVaapiMiniObjectClass * +gst_vaapi_feipak_h264_class (void) +{ + static const GstVaapiMiniObjectClass GstVaapiFEIPakH264Class = { + .size = sizeof (GstVaapiFEIPakH264), + .finalize = (GDestroyNotify) gst_vaapi_feipak_h264_finalize + }; + return &GstVaapiFEIPakH264Class; +} + +/** + * gst_vaapi_feipak_h264_new: + * @display: a #GstVaapiDisplay + * + * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the + * only supported output stream format is "byte-stream" format. + * + * Return value: the newly allocated #GstVaapiEncoder object + */ +GstVaapiFEIPakH264 * +gst_vaapi_feipak_h264_new (GstVaapiEncoder * encoder, GstVaapiDisplay * display, + VAContextID va_context) +{ + GstVaapiFEIPakH264 *feipak; + + feipak = (GstVaapiFEIPakH264 *) + gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS + (gst_vaapi_feipak_h264_class ())); + if (!feipak) + return NULL; + + if (!gst_vaapi_feipak_h264_init (feipak, encoder, display, va_context)) + goto error; + return feipak; + +error: + gst_vaapi_object_unref (feipak); + return NULL; +} + +gboolean +gst_vaapi_feipak_h264_get_ref_pool (GstVaapiFEIPakH264 * feipak, + gpointer * ref_pool_ptr) +{ + g_return_val_if_fail (feipak != NULL, FALSE); + if (!(&feipak->ref_pools[0])) + return FALSE; + + if (ref_pool_ptr) + *ref_pool_ptr = (gpointer) (&feipak->ref_pools[0]); + + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapifeipak_h264.h b/gst-libs/gst/vaapi/gstvaapifeipak_h264.h new file mode 100644 index 0000000000..f257becc1c --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapifeipak_h264.h @@ -0,0 +1,94 @@ +/* + * gstvaapifeipak_h264.h - H.264 FEI PAK + * + * Copyright (C) 2016-2018 Intel Corporation + * Author: Chen Xiaomin + * Author: Sreerenj Balachandran + * + * 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_FEIPAK_H264_H +#define GST_VAAPI_FEIPAK_H264_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _GstVaapiFEIPakH264 GstVaapiFEIPakH264; + +/** + * GstVaapiEncoderH264Prop: + * @GST_VAAPI_FEIPAK_H264_PROP_MAX_BFRAMES: Number of B-frames between I + * and P (uint). + * @GST_VAAPI_FEIPAK_H264_PROP_INIT_QP: Initial quantizer value (uint). + * @GST_VAAPI_FEIPAK_H264_PROP_MIN_QP: Minimal quantizer value (uint). + * @GST_VAAPI_FEIPAK_H264_PROP_NUM_SLICES: Number of slices per frame (uint). + * @GST_VAAPI_FEIPAK_H264_PROP_CABAC: Enable CABAC entropy coding mode (bool). + * @GST_VAAPI_FEIPAK_H264_PROP_DCT8X8: Enable adaptive use of 8x8 + * transforms in I-frames (bool). + * @GST_VAAPI_FEIPAK_H264_PROP_CPB_LENGTH: Length of the CPB buffer + * in milliseconds (uint). + * @GST_VAAPI_FEIPAK_H264_PROP_NUM_VIEWS: Number of views per frame. + * @GST_VAAPI_FEIPAK_H264_PROP_VIEW_IDS: View IDs + * + * The set of H.264 feipak specific configurable properties. + */ +typedef enum +{ + GST_VAAPI_FEIPAK_H264_PROP_MAX_BFRAMES = -1, + GST_VAAPI_FEIPAK_H264_PROP_INIT_QP = -2, + GST_VAAPI_FEIPAK_H264_PROP_MIN_QP = -3, + GST_VAAPI_FEIPAK_H264_PROP_NUM_SLICES = -4, + GST_VAAPI_FEIPAK_H264_PROP_CABAC = -5, + GST_VAAPI_FEIPAK_H264_PROP_DCT8X8 = -6, + GST_VAAPI_FEIPAK_H264_PROP_CPB_LENGTH = -7, + GST_VAAPI_FEIPAK_H264_PROP_NUM_VIEWS = -8, + GST_VAAPI_FEIPAK_H264_PROP_VIEW_IDS = -9, + GST_VAAPI_FEIPAK_H264_PROP_NUM_REF = -10, +} GstVaapiFEIPakH264Prop; + +GstVaapiEncoderStatus +gst_vaapi_feipak_h264_reconfigure (GstVaapiFEIPakH264 * feipak, + VAContextID va_context, GstVaapiProfile profile, guint8 profile_idc, + guint mb_width, guint mb_height, guint32 num_views, guint slices_num, + guint32 num_ref_frames); + +GstVaapiEncoderStatus +gst_vaapi_feipak_h264_encode (GstVaapiFEIPakH264 * feipak, + GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf, + GstVaapiSurfaceProxy * surface, GstVaapiFeiInfoToPakH264 *info_to_pak); + +GstVaapiEncoderStatus +gst_vaapi_feipak_h264_flush (GstVaapiFEIPakH264 * feipak); + +GstVaapiFEIPakH264 *gst_vaapi_feipak_h264_new (GstVaapiEncoder * encoder, + GstVaapiDisplay * display, VAContextID va_context); + +GstVaapiEncoderStatus +gst_vaapi_feipak_h264_set_property (GstVaapiFEIPakH264 * feipak, + gint prop_id, const GValue * value); + +gboolean +gst_vaapi_feipak_h264_get_ref_pool (GstVaapiFEIPakH264 * feipak, + gpointer * ref_pool_ptr); + +G_END_DECLS + +#endif /*GST_VAAPI_FEIPAK_H264_H */ From 0fdef0e349e738dc8988f16d9c8f76f6597c621a Mon Sep 17 00:00:00 2001 From: Yi A Wang Date: Wed, 9 Aug 2017 18:26:57 -0700 Subject: [PATCH 2921/3781] FEI: plugin: Add fei specific video meta GstVaapiFeiVideoMeta holds the below fei codec objects: GstVaapiEncFeiMbCode GstVaapiEncFeiMv GstVaapiEncFeiMvPredictor GstVaapiEncFeiMbControl GstVaapiEncFeiQp GstVaapiEncFeiDistortion https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 Signed-off-by: Sreerenj Balachandran --- gst/vaapi/Makefile.am | 14 +++ gst/vaapi/gstvaapifeivideometa.c | 210 +++++++++++++++++++++++++++++++ gst/vaapi/gstvaapifeivideometa.h | 80 ++++++++++++ 3 files changed, 304 insertions(+) create mode 100644 gst/vaapi/gstvaapifeivideometa.c create mode 100644 gst/vaapi/gstvaapifeivideometa.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 1f29516eab..cfdc2f423a 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -122,6 +122,18 @@ libgstvaapi_source_c += $(libgstvaapi_vp9enc_source_c) libgstvaapi_source_h += $(libgstvaapi_vp9enc_source_h) endif +libgstvaapi_h264feienc_source_c = \ + gstvaapifeivideometa.c \ + $(NULL) +libgstvaapi_h264feienc_source_h = \ + gstvaapifeivideometa.h \ + $(NULL) + +if USE_H264_FEI_ENCODER +libgstvaapi_source_c += $(libgstvaapi_h264feienc_source_c) +libgstvaapi_source_h += $(libgstvaapi_h264feienc_source_h) +endif + libgstvaapi_la_SOURCES = $(libgstvaapi_source_c) noinst_HEADERS = $(libgstvaapi_source_h) @@ -161,6 +173,8 @@ EXTRA_DIST = \ $(libgstvaapi_h265enc_source_h) \ $(libgstvaapi_vp9enc_source_c) \ $(libgstvaapi_vp9enc_source_h) \ + $(libgstvaapi_h264feienc_source_c) \ + $(libgstvaapi_h264feienc_source_h) \ $(libgstvaapi_egl_source_c) \ $(libgstvaapi_egl_source_h) \ $(libgstvaapi_1_2p_source_c) \ diff --git a/gst/vaapi/gstvaapifeivideometa.c b/gst/vaapi/gstvaapifeivideometa.c new file mode 100644 index 0000000000..eafb7d0cd1 --- /dev/null +++ b/gst/vaapi/gstvaapifeivideometa.c @@ -0,0 +1,210 @@ +/* + * gstvaapifeivideometa.c - Gst VA FEI video meta + * + * Copyright (C) 2016-2017 Intel Corporation + * Author: Yi A Wang + * Author: Sreerenj Balachandran * + * + * 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:gstvaapifeivideometa + * @short_description: VA FEI video meta for GStreamer + */ +#include "gstcompat.h" +#include "gstvaapifeivideometa.h" + +static void +gst_vaapi_fei_video_meta_finalize (GstVaapiFeiVideoMeta * meta) +{ + if (meta->mbcode) + gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT + (meta->mbcode)); + if (meta->mv) + gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT (meta->mv)); + if (meta->mvpred) + gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT + (meta->mvpred)); + if (meta->mbcntrl) + gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT + (meta->mbcntrl)); + if (meta->qp) + gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT (meta->qp)); + if (meta->dist) + gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT (meta->dist)); +} + +static void +gst_vaapi_fei_video_meta_init (GstVaapiFeiVideoMeta * meta) +{ +} + +static inline GstVaapiFeiVideoMeta * +_gst_vaapi_fei_video_meta_create (void) +{ + return g_slice_new0 (GstVaapiFeiVideoMeta); +} + +static inline void +_gst_vaapi_fei_video_meta_destroy (GstVaapiFeiVideoMeta * meta) +{ + g_slice_free1 (sizeof (*meta), meta); +} + +GstVaapiFeiVideoMeta * +gst_vaapi_fei_video_meta_new (void) +{ + GstVaapiFeiVideoMeta *meta; + + meta = _gst_vaapi_fei_video_meta_create (); + if (!meta) + return NULL; + gst_vaapi_fei_video_meta_init (meta); + return meta; +} + +static inline void +_gst_vaapi_fei_video_meta_free (GstVaapiFeiVideoMeta * meta) +{ + g_atomic_int_inc (&meta->ref_count); + + gst_vaapi_fei_video_meta_finalize (meta); + + if (G_LIKELY (g_atomic_int_dec_and_test (&meta->ref_count))) + _gst_vaapi_fei_video_meta_destroy (meta); +} + +/** + * gst_vaapi_fei_video_meta_ref: + * @meta: a #GstVaapiFeiVideoMeta + * + * Atomically increases the reference count of the given @meta by one. + * + * Returns: The same @meta argument + */ +GstVaapiFeiVideoMeta * +gst_vaapi_fei_video_meta_ref (GstVaapiFeiVideoMeta * meta) +{ + g_return_val_if_fail (meta != NULL, NULL); + + g_atomic_int_inc (&meta->ref_count); + return meta; +} + +/** + * gst_vaapi_fei_video_meta_unref: + * @meta: a #GstVaapiFeiVideoMeta + * + * Atomically decreases the reference count of the @meta by one. If + * the reference count reaches zero, the object will be free'd. + */ +void +gst_vaapi_fei_video_meta_unref (GstVaapiFeiVideoMeta * meta) +{ + g_return_if_fail (meta != NULL); + g_return_if_fail (meta->ref_count > 0); + if (g_atomic_int_dec_and_test (&meta->ref_count)) + _gst_vaapi_fei_video_meta_free (meta); +} + + +GType +gst_vaapi_fei_video_meta_api_get_type (void) +{ + static gsize g_type; + static const gchar *tags[] = { "memory", NULL }; + + if (g_once_init_enter (&g_type)) { + GType type = gst_meta_api_type_register ("GstVaapiFeiVideoMetaAPI", tags); + g_once_init_leave (&g_type, type); + } + return g_type; +} + + +#define GST_VAAPI_FEI_VIDEO_META_HOLDER(meta) \ + ((GstVaapiFeiVideoMetaHolder *) (meta)) + +static gboolean +gst_vaapi_fei_video_meta_holder_init (GstVaapiFeiVideoMetaHolder * meta, + gpointer params, GstBuffer * buffer) +{ + meta->meta = NULL; + return TRUE; +} + +static void +gst_vaapi_fei_video_meta_holder_free (GstVaapiFeiVideoMetaHolder * meta, + GstBuffer * buffer) +{ + if (meta->meta) + gst_vaapi_fei_video_meta_unref (meta->meta); +} + + +#define GST_VAAPI_FEI_VIDEO_META_INFO gst_vaapi_fei_video_meta_info_get () +static const GstMetaInfo * +gst_vaapi_fei_video_meta_info_get (void) +{ + static gsize g_meta_info; + + if (g_once_init_enter (&g_meta_info)) { + gsize meta_info = + GPOINTER_TO_SIZE (gst_meta_register (GST_VAAPI_FEI_VIDEO_META_API_TYPE, + "GstVaapiFeiVideoMeta", sizeof (GstVaapiFeiVideoMetaHolder), + (GstMetaInitFunction) gst_vaapi_fei_video_meta_holder_init, + (GstMetaFreeFunction) gst_vaapi_fei_video_meta_holder_free, + NULL)); + g_once_init_leave (&g_meta_info, meta_info); + } + return GSIZE_TO_POINTER (g_meta_info); +} + +GstVaapiFeiVideoMeta * +gst_buffer_get_vaapi_fei_video_meta (GstBuffer * buffer) +{ + GstVaapiFeiVideoMeta *meta; + GstMeta *m; + + g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); + + m = gst_buffer_get_meta (buffer, GST_VAAPI_FEI_VIDEO_META_API_TYPE); + if (!m) + return NULL; + + meta = GST_VAAPI_FEI_VIDEO_META_HOLDER (m)->meta; + if (meta) + meta->buffer = buffer; + return meta; +} + +void +gst_buffer_set_vaapi_fei_video_meta (GstBuffer * buffer, + GstVaapiFeiVideoMeta * meta) +{ + GstMeta *m = NULL; + + g_return_if_fail (GST_IS_BUFFER (buffer)); + g_return_if_fail (GST_VAAPI_IS_FEI_VIDEO_META (meta)); + + m = gst_buffer_add_meta (buffer, GST_VAAPI_FEI_VIDEO_META_INFO, NULL); + + if (m) + GST_VAAPI_FEI_VIDEO_META_HOLDER (m)->meta = + gst_vaapi_fei_video_meta_ref (meta); + return; +} diff --git a/gst/vaapi/gstvaapifeivideometa.h b/gst/vaapi/gstvaapifeivideometa.h new file mode 100644 index 0000000000..09d5f68ea6 --- /dev/null +++ b/gst/vaapi/gstvaapifeivideometa.h @@ -0,0 +1,80 @@ +/* + * gstvaapifeivideometa.h - Gstreamer/VA video meta + * + * Copyright (C) 2016-2017 Intel Corporation + * Author: Yi A Wang + * Author: Sreerenj Balachandran + * + * 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_FEI_VIDEO_META_H +#define GST_VAAPI_FEI_VIDEO_META_H + +#include +#include +G_BEGIN_DECLS + +typedef struct _GstVaapiFeiVideoMeta GstVaapiFeiVideoMeta; +typedef struct _GstVaapiFeiVideoMetaHolder GstVaapiFeiVideoMetaHolder; + +#define GST_VAAPI_FEI_VIDEO_META(obj) \ + ((GstVaapiFeiVideoMeta *) (obj)) +#define GST_VAAPI_IS_FEI_VIDEO_META(obj) \ + (GST_VAAPI_FEI_VIDEO_META (obj) != NULL) + +struct _GstVaapiFeiVideoMetaHolder +{ + GstMeta base; + GstVaapiFeiVideoMeta *meta; +}; + +struct _GstVaapiFeiVideoMeta { + GstVaapiEncFeiMbCode *mbcode; + GstVaapiEncFeiMv *mv; + GstVaapiEncFeiMvPredictor *mvpred; + GstVaapiEncFeiMbControl *mbcntrl; + GstVaapiEncFeiQp *qp; + GstVaapiEncFeiDistortion *dist; + + GstBuffer *buffer; + gint ref_count; +}; + +#define GST_VAAPI_FEI_VIDEO_META_API_TYPE \ + gst_vaapi_fei_video_meta_api_get_type () + +GType +gst_vaapi_fei_video_meta_api_get_type (void) G_GNUC_CONST; + +GstVaapiFeiVideoMeta * +gst_vaapi_fei_video_meta_new (void); + +GstVaapiFeiVideoMeta * +gst_vaapi_fei_video_meta_ref (GstVaapiFeiVideoMeta * meta); + +void +gst_vaapi_fei_video_meta_unref (GstVaapiFeiVideoMeta * meta); + +GstVaapiFeiVideoMeta * +gst_buffer_get_vaapi_fei_video_meta (GstBuffer * buffer); + +void +gst_buffer_set_vaapi_fei_video_meta (GstBuffer * buffer, GstVaapiFeiVideoMeta * meta); + +G_END_DECLS + +#endif /* GST_VAAPI_FEI_VIDEO_META_H */ From a46ad6b5bef3304c9ab5b0280c506536eea78e7f Mon Sep 17 00:00:00 2001 From: Yi A Wang Date: Wed, 9 Aug 2017 18:32:13 -0700 Subject: [PATCH 2922/3781] FEI: plugin: Add virtual methods to base encode Two new virtual methods are added to gstvaapiencode. load_control_data(): load the FEI input buffers set by the upstream elements save_stats_to_meta(): save the FEI output buffers to Meta for downnstream elements https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 Signed-off-by: Sreerenj Balachandran --- gst/vaapi/gstvaapiencode.c | 22 ++++++++++++++++++++++ gst/vaapi/gstvaapiencode.h | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index fc8cf6e02a..b3988394a9 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -271,6 +271,9 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) GstVaapiEncoderStatus status; GstBuffer *out_buffer; GstFlowReturn ret; +#if USE_H264_FEI_ENCODER + GstVaapiFeiVideoMeta *feimeta = NULL; +#endif status = gst_vaapi_encoder_get_buffer_with_timeout (encode->encoder, &codedbuf_proxy, timeout); @@ -295,6 +298,15 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) out_buffer = NULL; ret = klass->alloc_buffer (encode, GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy), &out_buffer); + +#if USE_H264_FEI_ENCODER + if (klass->save_stats_to_meta) { + feimeta = klass->save_stats_to_meta (encode, codedbuf_proxy); + if (feimeta != NULL) + gst_buffer_set_vaapi_fei_video_meta (out_buffer, feimeta); + } +#endif + gst_vaapi_coded_buffer_proxy_replace (&codedbuf_proxy, NULL); if (ret != GST_FLOW_OK) goto error_allocate_buffer; @@ -617,6 +629,10 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GstVaapiSurfaceProxy *proxy; GstFlowReturn ret; GstBuffer *buf; +#if USE_H264_FEI_ENCODER + GstVaapiFeiVideoMeta *feimeta = NULL; + GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (venc); +#endif buf = NULL; ret = gst_vaapi_plugin_base_get_input_buffer (GST_VAAPI_PLUGIN_BASE (encode), @@ -635,6 +651,12 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, if (!proxy) goto error_buffer_no_surface_proxy; +#if USE_H264_FEI_ENCODER + feimeta = gst_buffer_get_vaapi_fei_video_meta (buf); + if (feimeta && klass->load_control_data) + klass->load_control_data (encode, feimeta, proxy); +#endif + gst_video_codec_frame_set_user_data (frame, gst_vaapi_surface_proxy_ref (proxy), (GDestroyNotify) gst_vaapi_surface_proxy_unref); diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 72121f79eb..b63828526c 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -27,6 +27,12 @@ #include "gstvaapipluginbase.h" #include +#if USE_H264_FEI_ENCODER +#include +#include +#include "gstvaapifeivideometa.h" +#endif + G_BEGIN_DECLS #define GST_TYPE_VAAPIENCODE \ @@ -81,6 +87,18 @@ struct _GstVaapiEncodeClass GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr); GstVaapiProfile (*get_profile) (GstCaps * caps); + +#if USE_H264_FEI_ENCODER + + gboolean (*load_control_data) (GstVaapiEncode *encoder, + GstVaapiFeiVideoMeta *feimeta, + GstVaapiSurfaceProxy *proxy); + + GstVaapiFeiVideoMeta* (*save_stats_to_meta) (GstVaapiEncode *base_encode, + GstVaapiCodedBufferProxy *proxy); + +#endif + }; GType From 5750bd7850256dcb812dcac7ff23eed910c62e84 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 18:36:13 -0700 Subject: [PATCH 2923/3781] FEI: plugin: Add vaapih264feienc element A new FEI based encoder element for h264 is added: vaapih264feienc FEI is a an extension to VA-API which is providing low level advanced control over different stages of encoding. Extending vaapih264enc with fei support is possible, but it will make the code too much complicated and will be difficult to debug. So adding the new encoder element, but keeping the rank as 0 , vaapih264enc will stay as the primary encoder for normal use cases. The vaaih264feienc is mainly useful for customers who want to play with MotionVectors and Macroblock Predictions. Also user can do one stage of encoding(eg: only the Motion Vector Calculation) in software and offload trasformation/entroy-coding etc to Hardware (which is what PAK module is doing) using FEI element. vaapih264feienc can work in different modes using fei-mode properoty eg: gst-launch-1.0 videotestsrc ! vaapih264feienc fei-mode=ENC+PAK ! filesink location=sample.264 Important Note: ENC only mode won't produce any encoded data which is expected. But ENC alwys requires the output of PAK in order to do the inter-prediction over reconstructed frames. Similary PAK mode alway requires MV and MBCode as input, so unless there is an upstream element providing those buffers, PAK only won't work as expected. In a nutshell, ENC_PAK and the ENC+PAK modes are the only options we can verify with vaapih264feienc. But ideally, EN+PAK mode verification is enough to make sure that ENC and PAK are working as expected since ENC+PAK mode always invoke ENC and PAK separately in vaapih264feienc. People contributed: Wang, Yi Leilei Zhong, Xiaoxia xiaominc Li, Jing B https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 Signed-off-by: Sreerenj Balachandran --- gst/vaapi/Makefile.am | 14 +- gst/vaapi/gstvaapi.c | 13 + gst/vaapi/gstvaapiencode_h264_fei.c | 540 ++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode_h264_fei.h | 72 ++++ 4 files changed, 633 insertions(+), 6 deletions(-) create mode 100644 gst/vaapi/gstvaapiencode_h264_fei.c create mode 100644 gst/vaapi/gstvaapiencode_h264_fei.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index cfdc2f423a..610acd147f 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -122,12 +122,14 @@ libgstvaapi_source_c += $(libgstvaapi_vp9enc_source_c) libgstvaapi_source_h += $(libgstvaapi_vp9enc_source_h) endif -libgstvaapi_h264feienc_source_c = \ - gstvaapifeivideometa.c \ - $(NULL) -libgstvaapi_h264feienc_source_h = \ - gstvaapifeivideometa.h \ - $(NULL) +libgstvaapi_h264feienc_source_c = \ + gstvaapifeivideometa.c \ + gstvaapiencode_h264_fei.c \ + $(NULL) +libgstvaapi_h264feienc_source_h = \ + gstvaapifeivideometa.h \ + gstvaapiencode_h264_fei.h \ + $(NULL) if USE_H264_FEI_ENCODER libgstvaapi_source_c += $(libgstvaapi_h264feienc_source_c) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index f060f8e6af..f8414a91bd 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -47,6 +47,11 @@ #if USE_VP9_ENCODER #include "gstvaapiencode_vp9.h" #endif + +#if USE_H264_FEI_ENCODER +#include "gstvaapiencode_h264_fei.h" +#endif + #endif #define PLUGIN_NAME "vaapi" @@ -186,6 +191,14 @@ gst_vaapiencode_register (GstPlugin * plugin, GstVaapiDisplay * display) } } +#if USE_H264_FEI_ENCODER + if (gst_vaapi_display_has_encoder (display, + GST_VAAPI_PROFILE_H264_MAIN, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI)) { + gst_element_register (plugin, "vaapih264feienc", + GST_RANK_SECONDARY, GST_TYPE_VAAPIENCODE_H264_FEI); + } +#endif + g_array_unref (codecs); } #endif diff --git a/gst/vaapi/gstvaapiencode_h264_fei.c b/gst/vaapi/gstvaapiencode_h264_fei.c new file mode 100644 index 0000000000..d44f0633ad --- /dev/null +++ b/gst/vaapi/gstvaapiencode_h264_fei.c @@ -0,0 +1,540 @@ +/* + * gstvaapiencode_h264_fei.c - VA-API H.264 FEI ncoder + * + * Copyright (C) 2016-2019 Intel Corporation + * Author: Sreerenj Balachandran + * Author: Yi A Wang + * + * 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:element-vaapih264feienc + * @short_description: A VA-API FEI based H.264 video encoder + * + * Encodes raw video streams into H.264 bitstreams. + * + * + * Example launch line + * |[ + * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! vaapih264feienc fei-mode=ENC_PAK ! filesink location=test.264 + * ]| + * + */ + +#include "gstcompat.h" +#include +#include +#include +#include +#include +#include "gstvaapiencode_h264_fei.h" +#include "gstvaapipluginutil.h" +#include "gstvaapivideomemory.h" +#include "gstvaapifeivideometa.h" +#include + +#define GST_VAAPI_ENCODE_FLOW_MEM_ERROR GST_FLOW_CUSTOM_ERROR +#define GST_PLUGIN_NAME "vaapih264feienc" +#define GST_PLUGIN_DESC "A VA-API FEI based advanced H264 video encoder" + +GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_fei_encode_debug); +#define GST_CAT_DEFAULT gst_vaapi_h264_fei_encode_debug + +#define GST_CODEC_CAPS \ + "video/x-h264, " \ + "stream-format = (string) { avc, byte-stream }, " \ + "alignment = (string) au" + +/* *INDENT-OFF* */ +static const char gst_vaapiencode_h264_fei_sink_caps_str[] = + GST_VAAPI_MAKE_SURFACE_CAPS ", " + GST_CAPS_INTERLACED_FALSE "; " + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static const char gst_vaapiencode_h264_fei_src_caps_str[] = + GST_CODEC_CAPS ", " + "profile = (string) { constrained-baseline, baseline, main, high, multiview-high, stereo-high }"; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapiencode_h264_fei_sink_factory = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_h264_fei_sink_caps_str)); +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapiencode_h264_fei_src_factory = + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_h264_fei_src_caps_str)); +/* *INDENT-ON* */ + +/* h264 encode */ +G_DEFINE_TYPE (GstVaapiEncodeH264Fei, gst_vaapiencode_h264_fei, + GST_TYPE_VAAPIENCODE); + +static void +gst_vaapiencode_h264_fei_init (GstVaapiEncodeH264Fei * encode) +{ + gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); +} + +static void +gst_vaapiencode_h264_fei_finalize (GObject * object) +{ + G_OBJECT_CLASS (gst_vaapiencode_h264_fei_parent_class)->finalize (object); +} + +static void +gst_vaapiencode_h264_fei_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + default: + if (!encode_class->set_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapiencode_h264_fei_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); + + switch (prop_id) { + default: + if (!encode_class->get_property (base_encode, prop_id, value)) + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +typedef struct +{ + GstVaapiProfile best_profile; + guint best_score; +} FindBestProfileData; + +static void +find_best_profile_value (FindBestProfileData * data, const GValue * value) +{ + const gchar *str; + GstVaapiProfile profile; + guint score; + + if (!value || !G_VALUE_HOLDS_STRING (value)) + return; + + str = g_value_get_string (value); + if (!str) + return; + profile = gst_vaapi_utils_h264_get_profile_from_string (str); + if (!profile) + return; + score = gst_vaapi_utils_h264_get_profile_score (profile); + if (score < data->best_score) + return; + data->best_profile = profile; + data->best_score = score; +} + +static GstVaapiProfile +find_best_profile (GstCaps * caps) +{ + FindBestProfileData data; + guint i, j, num_structures, num_values; + + data.best_profile = GST_VAAPI_PROFILE_UNKNOWN; + data.best_score = 0; + + num_structures = gst_caps_get_size (caps); + for (i = 0; i < num_structures; i++) { + GstStructure *const structure = gst_caps_get_structure (caps, i); + const GValue *const value = gst_structure_get_value (structure, "profile"); + + if (!value) + continue; + if (G_VALUE_HOLDS_STRING (value)) + find_best_profile_value (&data, value); + else if (GST_VALUE_HOLDS_LIST (value)) { + num_values = gst_value_list_get_size (value); + for (j = 0; j < num_values; j++) + find_best_profile_value (&data, gst_value_list_get_value (value, j)); + } + } + return data.best_profile; +} + +static gboolean +gst_vaapiencode_h264_fei_set_config (GstVaapiEncode * base_encode) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI (base_encode->encoder); + GstCaps *allowed_caps; + GstVaapiProfile profile; + + /* Check for the largest profile that is supported */ + allowed_caps = + gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (base_encode)); + if (!allowed_caps) + return TRUE; + + profile = find_best_profile (allowed_caps); + gst_caps_unref (allowed_caps); + if (profile) { + GST_INFO ("using %s profile as target decoder constraints", + gst_vaapi_utils_h264_get_profile_string (profile)); + if (!gst_vaapi_encoder_h264_fei_set_max_profile (encoder, profile)) + return FALSE; + } + return TRUE; +} + +static GstCaps * +gst_vaapiencode_h264_fei_get_caps (GstVaapiEncode * base_encode) +{ + GstVaapiEncodeH264Fei *const encode = + GST_VAAPIENCODE_H264_FEI_CAST (base_encode); + GstCaps *caps, *allowed_caps; + + caps = gst_caps_from_string (GST_CODEC_CAPS); + + /* Check whether "stream-format" is avcC mode */ + allowed_caps = + gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); + if (allowed_caps) { + const char *stream_format = NULL; + GstStructure *structure; + guint i, num_structures; + + num_structures = gst_caps_get_size (allowed_caps); + for (i = 0; !stream_format && i < num_structures; i++) { + structure = gst_caps_get_structure (allowed_caps, i); + if (!gst_structure_has_field_typed (structure, "stream-format", + G_TYPE_STRING)) + continue; + stream_format = gst_structure_get_string (structure, "stream-format"); + } + encode->is_avc = stream_format && strcmp (stream_format, "avc") == 0; + gst_caps_unref (allowed_caps); + } + gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, + encode->is_avc ? "avc" : "byte-stream", NULL); + + base_encode->need_codec_data = encode->is_avc; + + /* XXX: update profile and level information */ + return caps; +} + +static GstVaapiEncoder * +gst_vaapiencode_h264_fei_alloc_encoder (GstVaapiEncode * base, + GstVaapiDisplay * display) +{ + return gst_vaapi_encoder_h264_fei_new (display); +} + +/* h264 NAL byte stream operations */ +static guint8 * +_h264_byte_stream_next_nal (guint8 * buffer, guint32 len, guint32 * nal_size) +{ + const guint8 *cur = buffer; + const guint8 *const end = buffer + len; + guint8 *nal_start = NULL; + guint32 flag = 0xFFFFFFFF; + guint32 nal_start_len = 0; + + g_assert (len >= 0 && buffer && nal_size); + if (len < 3) { + *nal_size = len; + nal_start = (len ? buffer : NULL); + return nal_start; + } + + /*locate head postion */ + if (!buffer[0] && !buffer[1]) { + if (buffer[2] == 1) { /* 0x000001 */ + nal_start_len = 3; + } else if (!buffer[2] && len >= 4 && buffer[3] == 1) { /* 0x00000001 */ + nal_start_len = 4; + } + } + nal_start = buffer + nal_start_len; + cur = nal_start; + + /*find next nal start position */ + while (cur < end) { + flag = ((flag << 8) | ((*cur++) & 0xFF)); + if ((flag & 0x00FFFFFF) == 0x00000001) { + if (flag == 0x00000001) + *nal_size = cur - 4 - nal_start; + else + *nal_size = cur - 3 - nal_start; + break; + } + } + if (cur >= end) { + *nal_size = end - nal_start; + if (nal_start >= end) { + nal_start = NULL; + } + } + return nal_start; +} + +static inline void +_start_code_to_size (guint8 nal_start_code[4], guint32 nal_size) +{ + nal_start_code[0] = ((nal_size >> 24) & 0xFF); + nal_start_code[1] = ((nal_size >> 16) & 0xFF); + nal_start_code[2] = ((nal_size >> 8) & 0xFF); + nal_start_code[3] = (nal_size & 0xFF); +} + +static gboolean +_h264_convert_byte_stream_to_avc (GstBuffer * buf) +{ + GstMapInfo info; + guint32 nal_size; + guint8 *nal_start_code, *nal_body; + guint8 *frame_end; + + g_assert (buf); + + if (!gst_buffer_map (buf, &info, GST_MAP_READ | GST_MAP_WRITE)) + return FALSE; + + nal_start_code = info.data; + frame_end = info.data + info.size; + nal_size = 0; + + while ((frame_end > nal_start_code) && + (nal_body = _h264_byte_stream_next_nal (nal_start_code, + frame_end - nal_start_code, &nal_size)) != NULL) { + if (!nal_size) + goto error; + + g_assert (nal_body - nal_start_code == 4); + _start_code_to_size (nal_start_code, nal_size); + nal_start_code = nal_body + nal_size; + } + gst_buffer_unmap (buf, &info); + return TRUE; + + /* ERRORS */ +error: + { + gst_buffer_unmap (buf, &info); + return FALSE; + } +} + +static GstFlowReturn +alloc_buffer (GstVaapiEncode * encode, + GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI (encode->encoder); + GstBuffer *buf; + gint32 buf_size; + GstVaapiFeiMode fei_mode; + + g_return_val_if_fail (coded_buf != NULL, GST_FLOW_ERROR); + g_return_val_if_fail (outbuf_ptr != NULL, GST_FLOW_ERROR); + + fei_mode = gst_vaapi_encoder_h264_fei_get_function_mode (encoder); + + if (fei_mode == GST_VAAPI_FEI_MODE_ENC) + buf_size = 4; /* just avoid zero size buffer allocation */ + else + buf_size = gst_vaapi_coded_buffer_get_size (coded_buf); + + if (buf_size <= 0) + goto error_invalid_buffer; + + buf = + gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER_CAST (encode), + buf_size); + if (!buf) + goto error_create_buffer; + + /* There is no encoded output content in ENC only mode */ + if (fei_mode != GST_VAAPI_FEI_MODE_ENC) { + if (!gst_vaapi_coded_buffer_copy_into (buf, coded_buf)) + goto error_copy_buffer; + } + + *outbuf_ptr = buf; + return GST_FLOW_OK; + + /* ERRORS */ +error_invalid_buffer: + { + GST_ERROR ("invalid GstVaapiCodedBuffer size (%d bytes)", buf_size); + return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; + } +error_create_buffer: + { + GST_ERROR ("failed to create output buffer of size %d", buf_size); + return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; + } +error_copy_buffer: + { + GST_ERROR ("failed to copy GstVaapiCodedBuffer data"); + gst_buffer_unref (buf); + return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; + } +} + +static GstFlowReturn +gst_vaapiencode_h264_fei_alloc_buffer (GstVaapiEncode * base_encode, + GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buffer_ptr) +{ + GstVaapiEncodeH264Fei *const encode = + GST_VAAPIENCODE_H264_FEI_CAST (base_encode); + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI (base_encode->encoder); + GstFlowReturn ret; + + g_return_val_if_fail (encoder != NULL, GST_FLOW_ERROR); + + ret = alloc_buffer (base_encode, coded_buf, out_buffer_ptr); + if (ret != GST_FLOW_OK) + return ret; + + if (!encode->is_avc) + return GST_FLOW_OK; + + /* Convert to avcC format */ + if (!_h264_convert_byte_stream_to_avc (*out_buffer_ptr)) + goto error_convert_buffer; + return GST_FLOW_OK; + + /* ERRORS */ +error_convert_buffer: + { + GST_ERROR ("failed to convert from bytestream format to avcC format"); + gst_buffer_replace (out_buffer_ptr, NULL); + return GST_FLOW_ERROR; + } +} + +static gboolean +gst_vaapiencode_h264_load_control_data (GstVaapiEncode * base_encode, + GstVaapiFeiVideoMeta * feimeta, GstVaapiSurfaceProxy * proxy) +{ + if (feimeta != NULL) { + gst_vaapi_surface_proxy_set_fei_mb_code (proxy, feimeta->mbcode); + gst_vaapi_surface_proxy_set_fei_mv (proxy, feimeta->mv); + gst_vaapi_surface_proxy_set_fei_mv_predictor (proxy, feimeta->mvpred); + gst_vaapi_surface_proxy_set_fei_mb_control (proxy, feimeta->mbcntrl); + gst_vaapi_surface_proxy_set_fei_qp (proxy, feimeta->qp); + gst_vaapi_surface_proxy_set_fei_distortion (proxy, feimeta->dist); + } + return TRUE; + +} + +static GstVaapiFeiVideoMeta * +gst_vaapiencode_h264_save_stats_to_meta (GstVaapiEncode * base_encode, + GstVaapiCodedBufferProxy * proxy) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI (base_encode->encoder); + GstVaapiFeiVideoMeta *feimeta = NULL; + GstVaapiEncFeiMbCode *mbcode = NULL; + GstVaapiEncFeiMv *mv = NULL; + GstVaapiEncFeiDistortion *dist = NULL; + + if (!gst_vaapi_encoder_h264_is_fei_stats_out_enabled (encoder)) + return NULL; + + feimeta = gst_vaapi_fei_video_meta_new (); + if (feimeta == NULL) + return NULL; + + mbcode = gst_vaapi_coded_buffer_proxy_get_fei_mbcode (proxy); + if (mbcode) + feimeta->mbcode = (GstVaapiEncFeiMbCode *) + gst_vaapi_fei_codec_object_ref ((GstVaapiFeiCodecObject *) mbcode); + + mv = gst_vaapi_coded_buffer_proxy_get_fei_mv (proxy); + if (mv) + feimeta->mv = (GstVaapiEncFeiMv *) + gst_vaapi_fei_codec_object_ref ((GstVaapiFeiCodecObject *) mv); + + dist = gst_vaapi_coded_buffer_proxy_get_fei_distortion (proxy); + if (dist) + feimeta->dist = (GstVaapiEncFeiDistortion *) + gst_vaapi_fei_codec_object_ref ((GstVaapiFeiCodecObject *) dist); + + return feimeta; +} + +static void +gst_vaapiencode_h264_fei_class_init (GstVaapiEncodeH264FeiClass * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_fei_encode_debug, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + object_class->finalize = gst_vaapiencode_h264_fei_finalize; + object_class->set_property = gst_vaapiencode_h264_fei_set_property; + object_class->get_property = gst_vaapiencode_h264_fei_get_property; + + encode_class->get_properties = + gst_vaapi_encoder_h264_fei_get_default_properties; + encode_class->set_config = gst_vaapiencode_h264_fei_set_config; + encode_class->get_caps = gst_vaapiencode_h264_fei_get_caps; + encode_class->alloc_encoder = gst_vaapiencode_h264_fei_alloc_encoder; + encode_class->alloc_buffer = gst_vaapiencode_h264_fei_alloc_buffer; + + encode_class->load_control_data = gst_vaapiencode_h264_load_control_data; + encode_class->save_stats_to_meta = gst_vaapiencode_h264_save_stats_to_meta; + + gst_element_class_set_static_metadata (element_class, + "VA-API H264 FEI Advanced encoder (Experimental)", + "Codec/Encoder/Video", + GST_PLUGIN_DESC, + "Sreerenj Balachandran ," + "Yi A Wang "); + + /* sink pad */ + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_h264_fei_sink_factory); + + /* src pad */ + gst_element_class_add_static_pad_template (element_class, + &gst_vaapiencode_h264_fei_src_factory); + + gst_vaapiencode_class_init_properties (encode_class); +} diff --git a/gst/vaapi/gstvaapiencode_h264_fei.h b/gst/vaapi/gstvaapiencode_h264_fei.h new file mode 100644 index 0000000000..195010786a --- /dev/null +++ b/gst/vaapi/gstvaapiencode_h264_fei.h @@ -0,0 +1,72 @@ +/* + * gstvaapiencode_h264i_fei.h - VA-API H.264 FEI encoder + * + * Copyright (C) 2016-2017 Intel Corporation + * Author: Sreerenj Balachandran + * Author: Yi A Wang + * + * 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_VAAPIENCODE_H264_FEI_FEI_H +#define GST_VAAPIENCODE_H264_FEI_FEI_H + +#include +#include "gstvaapiencode.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIENCODE_H264_FEI \ + (gst_vaapiencode_h264_fei_get_type ()) +#define GST_VAAPIENCODE_H264_FEI_CAST(obj) \ + ((GstVaapiEncodeH264Fei *)(obj)) +#define GST_VAAPIENCODE_H264_FEI(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPIENCODE_H264_FEI, \ + GstVaapiEncodeH264Fei)) +#define GST_VAAPIENCODE_H264_FEI_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPIENCODE_H264_FEI, \ + GstVaapiEncodeH264FeiClass)) +#define GST_VAAPIENCODE_H264_FEI_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPIENCODE_H264_FEI, \ + GstVaapiEncodeH264FeiClass)) +#define GST_IS_VAAPIENCODE_H264_FEI(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_H264_FEI)) +#define GST_IS_VAAPIENCODE_H264_FEI_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_H264_FEI)) + +typedef struct _GstVaapiEncodeH264Fei GstVaapiEncodeH264Fei; +typedef struct _GstVaapiEncodeH264FeiClass GstVaapiEncodeH264FeiClass; + +struct _GstVaapiEncodeH264Fei +{ + /*< private >*/ + GstVaapiEncode parent_instance; + + guint is_avc:1; /* [FALSE]=byte-stream (default); [TRUE]=avcC */ +}; + +struct _GstVaapiEncodeH264FeiClass +{ + /*< private >*/ + GstVaapiEncodeClass parent_class; +}; + +GType +gst_vaapiencode_h264_fei_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GST_VAAPIENCODE_H264_FEI_FEI_H */ From 9f98a02a0563f6d93c15553124ce3b8c4f4d3ad4 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 9 Aug 2017 18:46:09 -0700 Subject: [PATCH 2924/3781] FEI: Add test applications to showcase fei use case test-fei-enc-out: A simple fei encoding application to output mv, mbcode and distortion eg: ./test-fei-enc-out -i sample_320x240.nv12 -w 320 -h 240 -o out.264 -v mv.out -d out.dist -m out.mbcode -e 1 test-fei-enc-in: A simple fei encoding application for testing input fei buffers eg: ./test-fei-enc-in -c h264 -o out.264 -e 4 -q 1 sample_i420.y4m Fixme: Running test-fei-enc-in in PAK mode with mv and mbcode input buffers from saved files is still not working People contributed: Wang, Yi Leilei Zhong, Xiaoxia xiaominc Li, Jing B https://bugzilla.gnome.org/show_bug.cgi?id=785712 https://bugzilla.gnome.org/show_bug.cgi?id=784667 --- tests/Makefile.am | 19 ++ tests/test-fei-enc-in.c | 679 +++++++++++++++++++++++++++++++++++++++ tests/test-fei-enc-out.c | 300 +++++++++++++++++ 3 files changed, 998 insertions(+) create mode 100644 tests/test-fei-enc-in.c create mode 100644 tests/test-fei-enc-out.c diff --git a/tests/Makefile.am b/tests/Makefile.am index ca58797934..892e3966fc 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -14,6 +14,13 @@ noinst_PROGRAMS += \ $(NULL) endif +if USE_H264_FEI_ENCODER +noinst_PROGRAMS += \ + test-fei-enc-out \ + test-fei-enc-in \ + $(NULL) +endif + if USE_GLX noinst_PROGRAMS += \ test-textures \ @@ -136,6 +143,18 @@ test_textures_CFLAGS = $(TEST_CFLAGS) test_textures_LDFLAGS = $(GST_VAAPI_LIBS) test_textures_LDADD = libutils.la $(TEST_LIBS) +test_fei_enc_out_SOURCES = test-fei-enc-out.c ../gst/vaapi/gstvaapifeivideometa.h +test_fei_enc_out_CFLAGS = $(TEST_CFLAGS) +test_fei_enc_out_LDFLAGS = $(GST_VAAPI_LIBS) +test_fei_enc_out_LDADD = libutils.la $(TEST_LIBS) + +test_fei_enc_in_sources_c = test-fei-enc-in.c ../gst/vaapi/gstvaapifeivideometa.h y4mreader.c +test_fei_enc_in_sources_h = y4mreader.h +test_fei_enc_in_SOURCES = $(test_fei_enc_in_sources_c) +test_fei_enc_in_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) +test_fei_enc_in_LDFLAGS = $(GST_VAAPI_LIBS) +test_fei_enc_in_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) + simple_decoder_source_c = simple-decoder.c simple_decoder_source_h = simple_decoder_SOURCES = $(simple_decoder_source_c) diff --git a/tests/test-fei-enc-in.c b/tests/test-fei-enc-in.c new file mode 100644 index 0000000000..2f7d698e4a --- /dev/null +++ b/tests/test-fei-enc-in.c @@ -0,0 +1,679 @@ +/* + * test-fei-enc-in.c - Test FEI input buffer submission + * + * Copyright (C) 2016 Intel Corporation + * + * Author: Sreerenj Balachandran + * + * 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 + */ +/* sample pipeline: ./test-fei-enc-input -c h264 -o out.264 -e 4 -q 1 sample_i420.y4m */ + +#include +#include +#include +#include +#include +#include +#include "gst/vaapi/sysdeps.h" +#include +#include +#include +#include +#include +#include "output.h" +#include "y4mreader.h" +#include + +static guint g_bitrate = 0; +static gchar *g_codec_str; +static gchar *g_output_file_name; +static char **g_input_files = NULL; +static gchar *input_mv_name = NULL; +static gchar *input_mbmode_name = NULL; +static guint input_mv_size; +static guint input_mbmode_size; +static guint input_qp; +static guint enable_mbcntrl; +static guint enable_mvpred; +static guint fei_mode; + +#define SURFACE_NUM 16 + +#define ENC 1 +#define PAK 2 +#define ENC_PLUS_PAK 3 +#define ENC_PAK 4 + +static GOptionEntry g_options[] = { + {"codec", 'c', 0, G_OPTION_ARG_STRING, &g_codec_str, + "codec to use for video encoding (h264)", NULL}, + {"bitrate", 'b', 0, G_OPTION_ARG_INT, &g_bitrate, + "desired bitrate expressed in kbps", NULL}, + {"output", 'o', 0, G_OPTION_ARG_FILENAME, &g_output_file_name, + "output file name", NULL}, + {"imv", 'v', 0, G_OPTION_ARG_STRING, &input_mv_name, + "pak mv input file", NULL}, + {"imbmode ", 'm', 0, G_OPTION_ARG_STRING, &input_mbmode_name, + "pak mbmode input file", NULL}, + {"imvsize", 's', 0, G_OPTION_ARG_INT, &input_mv_size, + "input stream width", NULL}, + {"imbmodesize", 'd', 0, G_OPTION_ARG_INT, &input_mbmode_size, + "input stream height", NULL}, + {"iqp", 'q', 0, G_OPTION_ARG_INT, &input_qp, + "input qp val (it will get replicated for each macrobock)", NULL}, + {"imbcntrl", 'l', 0, G_OPTION_ARG_INT, &enable_mbcntrl, + "enable macroblock control for each macrobock", NULL}, + {"imbpred", 'p', 0, G_OPTION_ARG_INT, &enable_mvpred, + "enable mv predictor for each macroblock", NULL}, + {"fei-mode", 'e', 0, G_OPTION_ARG_INT, &fei_mode, + "1:ENC 2:PAK 3:ENC+PAK 4:ENC_PAK", NULL}, + + {G_OPTION_REMAINING, ' ', 0, G_OPTION_ARG_FILENAME_ARRAY, &g_input_files, + "input file name", NULL}, + {NULL} +}; + +typedef struct +{ + GstVaapiDisplay *display; + GstVaapiEncoder *encoder; + guint read_frames; + guint encoded_frames; + guint saved_frames; + Y4MReader *parser; + FILE *output_file; + int mv_fd; + int mbmode_fd; + guint input_mv_size; + guint input_mbmode_size; + guint input_stopped:1; + guint encode_failed:1; +} App; + +static inline gchar * +generate_output_filename (const gchar * ext) +{ + gchar *fn; + int i = 0; + + while (1) { + fn = g_strdup_printf ("temp%02d.%s", i, ext); + if (g_file_test (fn, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { + i++; + g_free (fn); + } else { + break; + } + } + + return fn; +} + +static gboolean +parse_options (int *argc, char *argv[]) +{ + GOptionContext *ctx; + gboolean success; + GError *error = NULL; + + ctx = g_option_context_new (" - encoder test options"); + if (!ctx) + return FALSE; + + g_option_context_add_group (ctx, gst_init_get_option_group ()); + g_option_context_add_main_entries (ctx, g_options, NULL); + g_option_context_set_help_enabled (ctx, TRUE); + success = g_option_context_parse (ctx, argc, &argv, &error); + if (!success) { + g_printerr ("Option parsing failed: %s\n", error->message); + g_error_free (error); + goto bail; + } + + if (!g_codec_str) + g_codec_str = g_strdup ("h264"); + if (!g_output_file_name) + g_output_file_name = generate_output_filename (g_codec_str); + +bail: + g_option_context_free (ctx); + return success; +} + +static void +print_yuv_info (App * app) +{ + g_print ("\n"); + g_print ("Encode : %s\n", g_codec_str); + g_print ("Resolution : %dx%d\n", app->parser->width, app->parser->height); + g_print ("Source YUV : %s\n", g_input_files ? g_input_files[0] : "stdin"); + g_print ("Frame Rate : %0.1f fps\n", + 1.0 * app->parser->fps_n / app->parser->fps_d); + g_print ("Coded file : %s\n", g_output_file_name); + g_print ("\n"); +} + +static void +print_num_frame (App * app) +{ + g_print ("\n"); + g_print ("read frames : %d\n", app->read_frames); + g_print ("encoded frames : %d\n", app->encoded_frames); + g_print ("saved frames : %d\n", app->saved_frames); + g_print ("\n"); +} + +static GstVaapiEncoder * +encoder_new (GstVaapiDisplay * display) +{ + GstVaapiEncoder *encoder = NULL; + + if (!g_strcmp0 (g_codec_str, "h264")) { + encoder = gst_vaapi_encoder_h264_fei_new (display); + gst_vaapi_encoder_h264_fei_set_function_mode (GST_VAAPI_ENCODER_H264_FEI + (encoder), fei_mode); + gst_vaapi_encoder_h264_fei_set_max_profile (GST_VAAPI_ENCODER_H264_FEI + (encoder), GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE); + } else + return NULL; + + return encoder; +} + +static inline GstVideoCodecState * +new_codec_state (gint width, gint height, gint fps_n, gint fps_d) +{ + GstVideoCodecState *state; + + state = g_slice_new0 (GstVideoCodecState); + state->ref_count = 1; + gst_video_info_set_format (&state->info, GST_VIDEO_FORMAT_ENCODED, width, + height); + + state->info.fps_n = fps_n; + state->info.fps_d = fps_d; + + return state; +} + +static gboolean +set_format (GstVaapiEncoder * encoder, gint width, gint height, gint fps_n, + gint fps_d) +{ + GstVideoCodecState *in_state; + GstVaapiEncoderStatus status; + + in_state = new_codec_state (width, height, fps_n, fps_d); + status = gst_vaapi_encoder_set_codec_state (encoder, in_state); + g_slice_free (GstVideoCodecState, in_state); + + return (status == GST_VAAPI_ENCODER_STATUS_SUCCESS); +} + +static GstBuffer * +allocate_buffer (GstVaapiCodedBuffer * vbuf) +{ + GstBuffer *buf; + gssize size; + + size = gst_vaapi_coded_buffer_get_size (vbuf); + + if (size <= 0) { + g_warning ("Invalid VA buffer size (%zd)", size); + return NULL; + } + + buf = gst_buffer_new_and_alloc (size); + if (!buf) { + g_warning ("Failed to create output buffer of size %zd", size); + return NULL; + } + + if (!gst_vaapi_coded_buffer_copy_into (buf, vbuf)) { + g_warning ("Failed to copy VA buffer data"); + gst_buffer_unref (buf); + return NULL; + } + + return buf; +} + +static GstVaapiEncoderStatus +get_encoder_buffer (GstVaapiEncoder * encoder, GstBuffer ** buffer) +{ + GstVaapiCodedBufferProxy *proxy = NULL; + GstVaapiEncoderStatus status; + + status = gst_vaapi_encoder_get_buffer_with_timeout (encoder, &proxy, 50000); + if (status < GST_VAAPI_ENCODER_STATUS_SUCCESS) { + g_warning ("Failed to get a buffer from encoder: %d", status); + return status; + } else if (status > GST_VAAPI_ENCODER_STATUS_SUCCESS) { + return status; + } + + *buffer = allocate_buffer (GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (proxy)); + gst_vaapi_coded_buffer_proxy_unref (proxy); + + return status; +} + +static gboolean +outputs_to_file (GstBuffer * buffer, FILE * file) +{ + GstMapInfo info; + size_t written; + gboolean ret = FALSE; + + gst_buffer_map (buffer, &info, GST_MAP_READ); + + if (info.size <= 0 || !info.data) + return FALSE; + + written = fwrite (info.data, 1, info.size, file); + if (written < info.size) { + g_warning ("write file error."); + goto bail; + } + + ret = TRUE; + +bail: + gst_buffer_unmap (buffer, &info); + return ret; +} + +static gpointer +get_buffer_thread (gpointer data) +{ + App *app = data; + + GstVaapiEncoderStatus ret; + GstBuffer *obuf; + + while (1) { + obuf = NULL; + ret = get_encoder_buffer (app->encoder, &obuf); + if (app->input_stopped && ret > GST_VAAPI_ENCODER_STATUS_SUCCESS) { + break; /* finished */ + } else if (ret > GST_VAAPI_ENCODER_STATUS_SUCCESS) { /* another chance */ + continue; + } + if (ret < GST_VAAPI_ENCODER_STATUS_SUCCESS) { /* fatal error */ + app->encode_failed = TRUE; + break; + } + + app->encoded_frames++; + g_debug ("encoded frame %d, buffer = %p", app->encoded_frames, obuf); + + if (app->output_file && outputs_to_file (obuf, app->output_file)) + app->saved_frames++; + + gst_buffer_unref (obuf); + } + if (obuf) + gst_buffer_replace (&obuf, NULL); + + return NULL; +} + +static void +app_free (App * app) +{ + g_return_if_fail (app); + + if (app->parser) + y4m_reader_close (app->parser); + + if (app->encoder) { + gst_vaapi_encoder_flush (app->encoder); + gst_vaapi_encoder_unref (app->encoder); + } + + if (app->display) + gst_vaapi_display_unref (app->display); + + if (app->output_file) + fclose (app->output_file); + + g_slice_free (App, app); +} + +static App * +app_new (const gchar * input_fn, const gchar * output_fn) +{ + App *app = g_slice_new0 (App); + if (!app) + return NULL; + app->parser = y4m_reader_open (input_fn); + if (!app->parser) { + g_warning ("Could not parse input stream."); + goto error; + } + + app->output_file = fopen (output_fn, "w"); + if (app->output_file == NULL) { + g_warning ("Could not open file \"%s\" for writing: %s.", output_fn, + g_strerror (errno)); + goto error; + } + + /* if PAK only */ + if (fei_mode == 2) { + if (!input_mv_name || !input_mbmode_name) { + g_warning ("pak only mode need an mv and mbmode files as input"); + assert (0); + } + + if (input_mv_name) + app->mv_fd = open (input_mv_name, O_RDONLY, 0); + if (input_mbmode_name) + app->mbmode_fd = open (input_mbmode_name, O_RDONLY, 0); + + assert (app->mv_fd >= 0); + assert (app->mbmode_fd >= 0); + } + + app->display = video_output_create_display (NULL); + if (!app->display) { + g_warning ("Could not create VA display."); + goto error; + } + + app->encoder = encoder_new (app->display); + if (!app->encoder) { + g_warning ("Could not create encoder."); + goto error; + } + + if (!set_format (app->encoder, app->parser->width, app->parser->height, + app->parser->fps_n, app->parser->fps_d)) { + g_warning ("Could not set format."); + goto error; + } + + return app; + +error: + app_free (app); + return NULL; +} + +static gboolean +upload_frame (GstVaapiEncoder * encoder, GstVaapiSurfaceProxy * proxy) +{ + GstVideoCodecFrame *frame; + GstVaapiEncoderStatus ret; + + frame = g_slice_new0 (GstVideoCodecFrame); + gst_video_codec_frame_set_user_data (frame, + gst_vaapi_surface_proxy_ref (proxy), + (GDestroyNotify) gst_vaapi_surface_proxy_unref); + + ret = gst_vaapi_encoder_put_frame (encoder, frame); + return (ret == GST_VAAPI_ENCODER_STATUS_SUCCESS); +} + +static gboolean +load_frame (App * app, GstVaapiImage * image) +{ + gboolean ret = FALSE; + + if (!gst_vaapi_image_map (image)) + return FALSE; + + ret = y4m_reader_load_image (app->parser, image); + + if (!gst_vaapi_image_unmap (image)) + return FALSE; + + return ret; +} + +static int +app_run (App * app) +{ + GstVaapiImage *image; + GstVaapiVideoPool *pool; + GThread *buffer_thread; + gsize id; + gint i; + + int ret = EXIT_FAILURE; + image = gst_vaapi_image_new (app->display, GST_VIDEO_FORMAT_I420, + app->parser->width, app->parser->height); + + { + GstVideoInfo vi; + gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_ENCODED, + app->parser->width, app->parser->height); + pool = gst_vaapi_surface_pool_new_full (app->display, &vi, 0); + } + buffer_thread = g_thread_new ("get buffer thread", get_buffer_thread, app); + + while (1) { + GstVaapiSurfaceProxy *proxy; + GstVaapiSurface *surface; + gpointer data = NULL; + guint size = 0; + gint rt = 0; + guint mb_width, mb_height, mb_size; + + if (!load_frame (app, image)) + break; + + if (!gst_vaapi_image_unmap (image)) + break; + + proxy = + gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL (pool)); + if (!proxy) { + g_warning ("Could not get surface proxy from pool."); + break; + } + surface = gst_vaapi_surface_proxy_get_surface (proxy); + if (!surface) { + g_warning ("Could not get surface from proxy."); + break; + } + + if (!gst_vaapi_surface_put_image (surface, image)) { + g_warning ("Could not update surface"); + break; + } + + mb_width = (app->parser->width + 15) >> 4; + mb_height = (app->parser->height + 15) >> 4; + mb_size = mb_width * mb_height; + + /* PAK Only */ + if (fei_mode == PAK) { + GstVaapiEncFeiMbCode *mbcode; + GstVaapiEncFeiMv *mv; + guint mv_size, mbmode_size; + + mv_size = mb_width * mb_height * 128; + mbmode_size = mb_width * mb_height * 64; + + if (input_mv_size) + assert (input_mv_size == mv_size); + + if (input_mbmode_size) + assert (input_mbmode_size == mbmode_size); + + /* Upload mbmode data */ + mbcode = gst_vaapi_enc_fei_mb_code_new (app->encoder, NULL, mbmode_size); + rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT (mbcode), + &data, &size); + assert (rt == 1); + rt = read (app->mbmode_fd, data, mbmode_size); + assert (rt >= 0); + + /* Upload mv data */ + mv = gst_vaapi_enc_fei_mv_new (app->encoder, NULL, mv_size); + rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT (mv), + &data, &size); + assert (rt == 1); + rt = read (app->mv_fd, data, mv_size); + assert (rt >= 0); + + /* assign mv and mbmode buffers to input surface proxy */ + gst_vaapi_surface_proxy_set_fei_mb_code (proxy, mbcode); + gst_vaapi_surface_proxy_set_fei_mv (proxy, mv); + + } else { + /* ENC, ENC+PAK and ENC_PAK */ + + if (input_qp) { + GstVaapiEncFeiQp *qp = NULL; + VAEncQPBufferH264 *pqp = NULL; + guint qp_size = 0; + + qp_size = mb_width * mb_height * sizeof (VAEncQPBufferH264); + + qp = gst_vaapi_enc_fei_qp_new (app->encoder, NULL, qp_size); + rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT (qp), + &data, &size); + assert (rt == 1); + + pqp = (VAEncQPBufferH264 *) data; + for (i = 0; i < mb_size; i++) { + pqp->qp = input_qp; + pqp++; + } + gst_vaapi_surface_proxy_set_fei_qp (proxy, qp); + } + + if (enable_mbcntrl) { + GstVaapiEncFeiMbControl *mbcntrl = NULL; + VAEncFEIMBControlH264 *pmbcntrl = NULL; + guint mbcntrl_size = 0; + + mbcntrl_size = mb_width * mb_height * sizeof (VAEncFEIMBControlH264); + mbcntrl = + gst_vaapi_enc_fei_mb_control_new (app->encoder, NULL, mbcntrl_size); + rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT + (mbcntrl), &data, &size); + assert (rt == 1); + + pmbcntrl = (VAEncFEIMBControlH264 *) data; + for (i = 0; i < mb_size; i++) { + pmbcntrl->force_to_intra = 1; + pmbcntrl->force_to_skip = 0; + pmbcntrl->force_to_nonskip = 0; + pmbcntrl->enable_direct_bias_adjustment = 0; + pmbcntrl->enable_motion_bias_adjustment = 0; + pmbcntrl->ext_mv_cost_scaling_factor = 0; + pmbcntrl->target_size_in_word = 0xff; + pmbcntrl->max_size_in_word = 0xff; + pmbcntrl++; + } + gst_vaapi_surface_proxy_set_fei_mb_control (proxy, mbcntrl); + } + + if (enable_mvpred) { + GstVaapiEncFeiMvPredictor *mvpred = NULL; + VAEncFEIMVPredictorH264 *pmvpred = NULL; + guint mvpred_size = 0, j; + + mvpred_size = mb_width * mb_height * sizeof (VAEncFEIMVPredictorH264); + mvpred = + gst_vaapi_enc_fei_mv_predictor_new (app->encoder, NULL, + mvpred_size); + rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT + (mvpred), &data, &size); + assert (rt == 1); + + pmvpred = (VAEncFEIMVPredictorH264 *) data; + for (i = 0; i < mb_size; i++) { + for (j = 0; i < 4; i++) { + pmvpred->ref_idx[j].ref_idx_l0 = 0; + pmvpred->ref_idx[j].ref_idx_l1 = 0; + + pmvpred->mv[j].mv0[0] = 0x8000; + pmvpred->mv[j].mv0[1] = 0x8000; + pmvpred->mv[j].mv1[0] = 0x8000; + pmvpred->mv[j].mv1[1] = 0x8000; + } + pmvpred++; + } + gst_vaapi_surface_proxy_set_fei_mv_predictor (proxy, mvpred); + } + } + + if (!upload_frame (app->encoder, proxy)) { + g_warning ("put frame failed"); + break; + } + + app->read_frames++; + id = gst_vaapi_surface_get_id (surface); + g_debug ("input frame %d, surface id = %" G_GSIZE_FORMAT, app->read_frames, + id); + + gst_vaapi_surface_proxy_unref (proxy); + } + + app->input_stopped = TRUE; + + g_thread_join (buffer_thread); + + if (!app->encode_failed && feof (app->parser->fp)) + ret = EXIT_SUCCESS; + + gst_vaapi_video_pool_replace (&pool, NULL); + gst_vaapi_object_unref (image); + return ret; +} + +int +main (int argc, char *argv[]) +{ + App *app; + int ret = EXIT_FAILURE; + gchar *input_fn; + + if (!parse_options (&argc, argv)) + return EXIT_FAILURE; + + /* @TODO: iterate all the input files */ + input_fn = g_input_files ? g_input_files[0] : NULL; + if (input_fn && !g_file_test (input_fn, + G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { + g_warning ("input file \"%s\" doesn't exist", input_fn); + goto bail; + } + + app = app_new (input_fn, g_output_file_name); + if (!app) + goto bail; + print_yuv_info (app); + ret = app_run (app); + print_num_frame (app); + + app_free (app); + +bail: + g_free (g_codec_str); + g_free (g_output_file_name); + g_strfreev (g_input_files); + + gst_deinit (); + + return ret; +} diff --git a/tests/test-fei-enc-out.c b/tests/test-fei-enc-out.c new file mode 100644 index 0000000000..3232643452 --- /dev/null +++ b/tests/test-fei-enc-out.c @@ -0,0 +1,300 @@ +/* + * test-fei-enc-out.c - FEI Encoder Test application to dump output buffers + * + * Copyright (C) 2017 Intel Corporation + * + * 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 + */ + +/* ./test-fei-enc -i sample_320x240.nv12 -f nv12 -w 320 -h 240 -o out.264 -v mv.out -d dist.out -m mbcode.out -e 1 */ + +#include +#include +#include +#include +#include "../gst/vaapi/gstvaapifeivideometa.h" +#include + +int +main (int argc, char *argv[]) +{ + GstElement *pipeline, *filesrc, *videoparse, *enc, *capsfilter, *appsink; + GError *err = NULL; + GstStateChangeReturn ret; + GstSample *sample; + GstVideoFormat raw_format = GST_VIDEO_FORMAT_NV12; + GOptionContext *ctx; + FILE *file = NULL; + FILE *mv_file = NULL; + FILE *dist_file = NULL; + FILE *mbcode_file = NULL; + FILE *fei_stat_file = NULL; + gchar *input_file_name = NULL; + gchar *output_file_name = NULL; + gchar *output_mv_name = NULL; + gchar *output_distortion_name = NULL; + gchar *output_mbcode_name = NULL; + gchar *input_format; + guint input_width; + guint input_height; + guint enc_frame_num = 0; + guint block_size = 0; + guint fei_mode = 1; + guint fei_mode_flag = 0x00000004; + gboolean link_ok = FALSE; + guint mv_buffer_size = 0; + guint mbcode_buffer_size = 0; + guint dist_buffer_size = 0; + gpointer mapped_data = NULL; + guint mapped_data_size = 0; + const gchar *caps_string = "video/x-h264, profile=constrained-baseline"; + GstCaps *filter_caps = NULL; + + GOptionEntry options[] = { + {"input file", 'i', 0, G_OPTION_ARG_STRING, &input_file_name, + "file to encode", NULL}, + {"output file", 'o', 0, G_OPTION_ARG_STRING, &output_file_name, + "encpak output file", NULL}, + {"output mv file", 'v', 0, G_OPTION_ARG_STRING, &output_mv_name, + "encpak mv output file", NULL}, + {"output distortion file", 'd', 0, G_OPTION_ARG_STRING, + &output_distortion_name, + "encpak distortion output file", NULL}, + {"output mbcode file", 'm', 0, G_OPTION_ARG_STRING, &output_mbcode_name, + "encpak mbcode output file", NULL}, + {"format", 'f', 0, G_OPTION_ARG_STRING, &input_format, + "input raw format: nv12 or i420", NULL}, + {"width", 'w', 0, G_OPTION_ARG_INT, &input_width, + "input stream width", NULL}, + {"height", 'h', 0, G_OPTION_ARG_INT, &input_height, + "input stream height", NULL}, + {"frame-num", 'n', 0, G_OPTION_ARG_INT, &enc_frame_num, + "numumber of buffers to be encoded", NULL}, + {"blocksize", 's', 0, G_OPTION_ARG_INT, &block_size, + "single buffer size of input stream", NULL}, + {"fei-mode", 'e', 0, G_OPTION_ARG_INT, &fei_mode, + "1: ENC_PAK 2: ENC+PAK", NULL}, + {NULL} + }; + + ctx = + g_option_context_new + ("encpak with element filesrc, videoparse, vaapih264feienc, appsink"); + g_option_context_add_main_entries (ctx, options, NULL); + g_option_context_add_group (ctx, gst_init_get_option_group ()); + + if (!g_option_context_parse (ctx, &argc, &argv, &err)) { + g_print ("Error intializing: %s\n", err->message); + g_option_context_free (ctx); + g_clear_error (&err); + return -1; + } + + if (input_file_name == NULL || output_file_name == NULL) { + g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL)); + g_option_context_free (ctx); + return -1; + } + + if (!g_strcmp0 (input_format, "nv12")) + raw_format = GST_VIDEO_FORMAT_NV12; + else if (!g_strcmp0 (input_format, "i420")) + raw_format = GST_VIDEO_FORMAT_I420; + else + return -1; + + if (!input_width || !input_height) { + g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL)); + g_option_context_free (ctx); + return -1; + } + + switch (fei_mode) { + case 1: + fei_mode_flag = 0x00000004; + break; + case 2: + fei_mode_flag = 0x00000001 | 0x00000002; + break; + default: + printf ("Unknown fei mode \n"); + g_assert (0); + break; + } + + g_option_context_free (ctx); + + gst_init (&argc, &argv); + + /* create pipeline */ + pipeline = gst_pipeline_new ("pipeline"); + filesrc = gst_element_factory_make ("filesrc", "source"); + videoparse = gst_element_factory_make ("videoparse", "videoparse"); + enc = gst_element_factory_make ("vaapih264feienc", "encpak"); + capsfilter = gst_element_factory_make ("capsfilter", "enccaps"); + appsink = gst_element_factory_make ("appsink", "sink"); + + /* element prop setup */ + g_object_set (G_OBJECT (filesrc), "location", input_file_name, NULL); + g_object_set (G_OBJECT (videoparse), "format", raw_format, + "width", input_width, "height", input_height, NULL); + + if (enc_frame_num != 0) + g_object_set (G_OBJECT (filesrc), "num-buffers", enc_frame_num, NULL); + if (block_size != 0) + g_object_set (G_OBJECT (filesrc), "blocksize", block_size, NULL); + + g_object_set (G_OBJECT (enc), "fei-mode", fei_mode_flag, NULL); + g_object_set (G_OBJECT (enc), "search-window", 5, NULL); + g_object_set (G_OBJECT (enc), "max-bframes", 0, NULL); + + filter_caps = gst_caps_from_string (caps_string); + if (filter_caps) + g_object_set (G_OBJECT (capsfilter), "caps", filter_caps, NULL); + gst_caps_unref (filter_caps); + + gst_bin_add_many (GST_BIN (pipeline), filesrc, videoparse, enc, capsfilter, + appsink, NULL); + + link_ok = + gst_element_link_many (filesrc, videoparse, enc, capsfilter, appsink, + NULL); + if (!link_ok) { + g_print ("filesrc, enc and appsink link fail"); + return -1; + } + + file = fopen (output_file_name, "wb"); + + if (output_mv_name != NULL) + mv_file = fopen (output_mv_name, "wb"); + + if (output_mbcode_name != NULL) + mbcode_file = fopen (output_mbcode_name, "wb"); + + if (output_distortion_name != NULL) + dist_file = fopen (output_distortion_name, "wb"); + + ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + g_printerr ("Unable to set the pipeline to the playing state.\n"); + gst_object_unref (pipeline); + return -1; + } + + /* pull sample from pipeline */ + while (1) { + g_signal_emit_by_name (appsink, "pull-sample", &sample, NULL); + if (sample) { + GstBuffer *buffer = NULL; + GstMapInfo map, info; + GstMemory *mem; + GstVaapiFeiVideoMeta *meta = NULL; + GstMeta *m = NULL; + const GstMetaInfo *meta_info; + GType api; + + g_debug ("appsink received sample.\n"); + buffer = gst_sample_get_buffer (sample); + if (gst_buffer_map (buffer, &map, GST_MAP_READ)) { + mem = gst_buffer_peek_memory (buffer, 0); + if (gst_memory_map (mem, &info, GST_MAP_READ)) + fwrite (info.data, 1, info.size, file); + + gst_memory_unmap (mem, &info); + gst_buffer_unmap (buffer, &map); + } + + meta_info = gst_meta_get_info ("GstVaapiFeiVideoMeta"); + api = meta_info->api; + m = gst_buffer_get_meta (buffer, api); + if (m != NULL) + meta = ((GstVaapiFeiVideoMetaHolder *) (m))->meta; + + if (meta != NULL) { + + if (mv_file != NULL) { + mapped_data = NULL; + mapped_data_size = 0; + if (gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT + (meta->mv), &mapped_data, &mapped_data_size)) { + fwrite (mapped_data, 1, mapped_data_size, mv_file); + gst_vaapi_fei_codec_object_unmap (GST_VAAPI_FEI_CODEC_OBJECT + (meta->mv)); + mv_buffer_size = mapped_data_size; + } + } + + if (mbcode_file != NULL) { + mapped_data = NULL; + mapped_data_size = 0; + if (gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT + (meta->mbcode), &mapped_data, &mapped_data_size)) { + fwrite (mapped_data, 1, mapped_data_size, mbcode_file); + gst_vaapi_fei_codec_object_unmap (GST_VAAPI_FEI_CODEC_OBJECT + (meta->mbcode)); + mbcode_buffer_size = mapped_data_size; + } + } + + if (dist_file != NULL) { + mapped_data = NULL; + mapped_data_size = 0; + if (gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT + (meta->dist), &mapped_data, &mapped_data_size)) { + fwrite (mapped_data, 1, mapped_data_size, dist_file); + gst_vaapi_fei_codec_object_unmap (GST_VAAPI_FEI_CODEC_OBJECT + (meta->dist)); + dist_buffer_size = mapped_data_size; + } + } + } + + gst_sample_unref (sample); + } else { + g_print ("appsink finished receive sample.\n"); + break; + } + } + + /* Fixme: Currently assuming the input video has only one resoultion + * which may not be true */ + /* create a status file for dumping size of each fei output buffer */ + if (output_mv_name || output_mbcode_name || output_distortion_name) { + fei_stat_file = fopen ("fei_stat.out", "wb"); + fprintf (fei_stat_file, "Frame_MotionVectorData_Buffer_Size => %d \n", + mv_buffer_size); + fprintf (fei_stat_file, "Frame_MacroblcokCode_Buffer_Size => %d \n", + mbcode_buffer_size); + fprintf (fei_stat_file, "Frame_Distortion_Buffer_Size => %d \n", + dist_buffer_size); + } + + /* free */ + fclose (file); + if (mv_file != NULL) + fclose (mv_file); + if (mbcode_file != NULL) + fclose (mbcode_file); + if (dist_file != NULL) + fclose (dist_file); + if (fei_stat_file) + fclose (fei_stat_file); + + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (pipeline); + return 0; +} From 782184e7813ff4cd402bec0e556ce1f4d1187220 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 1 Sep 2017 13:48:01 -0700 Subject: [PATCH 2925/3781] vaapisink: Fix rendering in drm display Make sure vaapisink create a va surface backed buffer pool and all required attributes get assigned correctly for drm display type. This is needed to make the below pipeline working: gst-launch-1.0 filesrc location= raw_video.mov ! videoparse format=uyvy width=320 height=240 framerate=30/1 ! vaapisink display=drm https://bugzilla.gnome.org/show_bug.cgi?id=786954 --- gst/vaapi/gstvaapisink.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 9336e540f4..27f0a6e037 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1325,9 +1325,6 @@ gst_vaapisink_set_caps (GstBaseSink * base_sink, GstCaps * caps) return FALSE; display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); - if (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE (sink) == GST_VAAPI_DISPLAY_TYPE_DRM) - return TRUE; - if (!gst_vaapi_plugin_base_set_caps (plugin, caps, NULL)) return FALSE; @@ -1346,6 +1343,9 @@ gst_vaapisink_set_caps (GstBaseSink * base_sink, GstCaps * caps) gst_vaapisink_ensure_colorbalance (sink); gst_vaapisink_ensure_rotation (sink, FALSE); + if (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE (sink) == GST_VAAPI_DISPLAY_TYPE_DRM) + return TRUE; + gst_vaapisink_ensure_window_size (sink, &win_width, &win_height); if (sink->window) { if (!sink->foreign_window || sink->fullscreen) From 6e3bfbc014d90c2e22f3aaf7feda1dc569b7e375 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 5 Sep 2017 10:58:57 -0700 Subject: [PATCH 2926/3781] libs: encoder: h264_fei: VA-API 1.0 compat Use VA_ENC_PACKED_HEADER_H264_SEI compat macro for VA-API 1.0 compatibility. https://bugzilla.gnome.org/show_bug.cgi?id=787322 Signed-off-by: U. Artie Eoff --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index a2ce197f34..68ef213ad1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -1615,7 +1615,7 @@ add_packed_sei_header (GstVaapiEncoderH264Fei * encoder, data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); data = GST_BIT_WRITER_DATA (&bs); - packed_sei_param.type = VAEncPackedHeaderH264_SEI; + packed_sei_param.type = VA_ENC_PACKED_HEADER_H264_SEI; packed_sei_param.bit_length = data_bit_size; packed_sei_param.has_emulation_bytes = 0; From 2039eb882ea51b5e4fafb8f3cc0f89b64a4f5a19 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 6 Sep 2017 14:03:25 -0400 Subject: [PATCH 2927/3781] Request minimum buffer even if need_pool is FALSE When tee is used, it will not request a pool, but still it wants to know how many buffers are required. https://bugzilla.gnome.org/show_bug.cgi?id=730758 --- gst/vaapi/gstvaapipluginbase.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 76d136109e..318e567b68 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -850,20 +850,25 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, GstQuery * query) { GstCaps *caps = NULL; + GstBufferPool *pool = NULL; gboolean need_pool; gst_query_parse_allocation (query, &caps, &need_pool); if (!caps) goto error_no_caps; + /* FIXME re-using buffer pool breaks renegotiation */ + if (!ensure_sinkpad_buffer_pool (plugin, caps)) + return FALSE; + if (need_pool) { - if (!ensure_sinkpad_buffer_pool (plugin, caps)) - return FALSE; - gst_query_add_allocation_pool (query, plugin->sinkpad_buffer_pool, - plugin->sinkpad_buffer_size, BUFFER_POOL_SINK_MIN_BUFFERS, 0); + pool = plugin->sinkpad_buffer_pool; gst_query_add_allocation_param (query, plugin->sinkpad_allocator, NULL); } + gst_query_add_allocation_pool (query, pool, plugin->sinkpad_buffer_size, + BUFFER_POOL_SINK_MIN_BUFFERS, 0); + gst_query_add_allocation_meta (query, GST_VAAPI_VIDEO_META_API_TYPE, NULL); gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); return TRUE; From f7886008e38a97f9b7bc17d0ff202f9328d81521 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 13 Sep 2017 11:06:20 +0900 Subject: [PATCH 2928/3781] libs: encoder: h265: keep idr_period equal to keyframe period Remove FIXME code, which makes previous assignation spurious. This also means to make idr_period equal to keyframe period, which is same as h264 encoder. https://bugzilla.gnome.org/show_bug.cgi?id=783804 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index d5123ec8b3..84389e267b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1965,9 +1965,6 @@ reset_properties (GstVaapiEncoderH265 * encoder) if (encoder->idr_period > MAX_IDR_PERIOD) encoder->idr_period = MAX_IDR_PERIOD; - /* FIXME: provide user control for idr_period ?? */ - encoder->idr_period = base_encoder->keyframe_period * 2; - if (encoder->min_qp > encoder->init_qp || (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP && encoder->min_qp < encoder->init_qp)) From f14563759aa89e6521b2911bcf30ec8ade40e3dd Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 13 Sep 2017 11:17:26 +0900 Subject: [PATCH 2929/3781] libs: encoder: h264/5: determine num_ref_idx_active_override_flag according to reference list Follows the specification as below: 7.4.7.1 in Rec. ITU-T H.265 v4 (12/2016) num_ref_idx_active_override_flag equal to 1 specifies that the syntax element num_ref_idx_l0_active_minus1 is present for P and B slices and that the syntax element num_ref_idx_l1_active_minus1 is present for B slices. num_ref_idx_active_override_flag equal to 0 specifies that the syntax elements num_ref_idx_l0_active_minus1 and num_ref_idx_l1_active_minus1 are not present. https://bugzilla.gnome.org/show_bug.cgi?id=783804 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 3 ++- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 396eb41f57..5512a50a17 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2080,7 +2080,8 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, /* only works for B frames */ slice_param->direct_spatial_mv_pred_flag = FALSE; /* default equal to picture parameters */ - slice_param->num_ref_idx_active_override_flag = TRUE; + slice_param->num_ref_idx_active_override_flag = reflist_0_count + || reflist_1_count; if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; else diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 84389e267b..6c40517088 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -661,8 +661,9 @@ bs_write_slice (GstBitWriter * bs, guint8 no_output_of_prior_pics_flag = 0; guint8 dependent_slice_segment_flag = 0; guint8 short_term_ref_pic_set_sps_flag = 0; - guint8 num_ref_idx_active_override_flag = 0; guint8 slice_deblocking_filter_disabled_flag = 0; + guint8 num_ref_idx_active_override_flag = + slice_param->slice_fields.bits.num_ref_idx_active_override_flag; /* first_slice_segment_in_pic_flag */ WRITE_UINT32 (bs, encoder->first_slice_segment_in_pic_flag, 1); @@ -752,6 +753,12 @@ bs_write_slice (GstBitWriter * bs, slice_param->slice_type == GST_H265_B_SLICE) { /* num_ref_idx_active_override_flag */ WRITE_UINT32 (bs, num_ref_idx_active_override_flag, 1); + if (num_ref_idx_active_override_flag) { + WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1); + if (slice_param->slice_type == GST_H265_B_SLICE) + WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1); + } + /* mvd_l1_zero_flag */ if (slice_param->slice_type == GST_H265_B_SLICE) WRITE_UINT32 (bs, slice_param->slice_fields.bits.mvd_l1_zero_flag, 1); @@ -1640,6 +1647,8 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, slice_param->slice_type = h265_get_slice_type (picture->type); slice_param->slice_pic_parameter_set_id = 0; + slice_param->slice_fields.bits.num_ref_idx_active_override_flag = + reflist_0_count || reflist_1_count; if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; else @@ -1682,8 +1691,6 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, slice_param->max_num_merge_cand = 5; /* MaxNumMergeCand */ slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp; - slice_param->slice_fields.value = 0; - slice_param->slice_fields.bits. slice_loop_filter_across_slices_enabled_flag = TRUE; From 3dbf44037307916afd0193e705a9300bf0b9d7e5 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 13 Sep 2017 11:37:33 +0900 Subject: [PATCH 2930/3781] libs: encoder: h265: add refs property Users can provide the number of reference frame by this property, which is exaclty same as h264. The value of the property will be considered as the number of reference picture list0 and will add 1 reference frame more to the reference picture list1 internally if b-frame encoding. If the value provided is bigger than the number of refrence frames supported in the driver, it will be lowered. The maximum value is aligned to the value of the driver supported now. https://bugzilla.gnome.org/show_bug.cgi?id=783804 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 16 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 6c40517088..5bf7cc497a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -118,6 +118,7 @@ struct _GstVaapiEncoderH265 guint32 max_pic_order_cnt; guint32 log2_max_pic_order_cnt; guint32 idr_num; + guint num_ref_frames; GstBuffer *vps_data; GstBuffer *sps_data; @@ -2502,6 +2503,9 @@ gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH: encoder->cpb_length = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES: + encoder->num_ref_frames = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -2568,6 +2572,18 @@ gst_vaapi_encoder_h265_get_default_properties (void) "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH265:refs: + * + * The number of reference frames. + * If B frame is encoded, it will add 1 reference frame more. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES, + g_param_spec_uint ("refs", + "Number of Reference Frames", "Number of reference frames", 1, 3, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiEncoderH265:init-qp: * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index ec8483e5b7..dbac0f9a7f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -40,6 +40,7 @@ typedef struct _GstVaapiEncoderH265 GstVaapiEncoderH265; * @GST_VAAPI_ENCODER_H265_PROP_INIT_QP: Initial quantizer value (uint). * @GST_VAAPI_ENCODER_H265_PROP_MIN_QP: Minimal quantizer value (uint). * @GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES: Number of slices per frame (uint). + * @GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES: Maximum number of reference frames. * @GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH: Length of the CPB buffer * in milliseconds (uint). * @@ -50,6 +51,7 @@ typedef enum { GST_VAAPI_ENCODER_H265_PROP_INIT_QP = -2, GST_VAAPI_ENCODER_H265_PROP_MIN_QP = -3, GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES = -4, + GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES = -5, GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH = -7 } GstVaapiEncoderH265Prop; From aa6aa996d672996227f8b529b21b7396063d63c4 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 13 Sep 2017 11:39:09 +0900 Subject: [PATCH 2931/3781] libs: encoder: h265: add multi reference support This is doing the same as h264 encoder as the following: Using num_ref_frames provided and the result of the Query VAConfigAttribEncMaxRefFrames, it determines the size of reference list and perform encoding with multi reference frames as the following: 1\ The num_ref_frames is being considered as the number of reference picture list0 2\ Encoder adds 1 reference frame more to the reference picture list1 internally if b-frame encoding. 3\ If num_ref_frames is bigger than the number of refrence frames supported in the driver, it will be lowered. Also this patch includes: - Set num_negative_pics and num_positive_pics according to the number of refs. - Set delta_poc according to the number of refs. - Increase max_dec_pic_buffering according to the number of refs - Change max_num_reorder_pics according to num of bframes https://bugzilla.gnome.org/show_bug.cgi?id=783804 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 79 +++++++++++++++++------ 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 5bf7cc497a..99c86ecff4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -699,10 +699,29 @@ bs_write_slice (GstBitWriter * bs, guint num_positive_pics = 0, num_negative_pics = 0; guint delta_poc_s0_minus1 = 0, delta_poc_s1_minus1 = 0; guint used_by_curr_pic_s0_flag = 0, used_by_curr_pic_s1_flag = 0; + guint reflist_0_count = 0, reflist_1_count = 0; + gint i; + + /* Get count of ref_pic_list */ + if (picture->type == GST_VAAPI_PICTURE_TYPE_P + || picture->type == GST_VAAPI_PICTURE_TYPE_B) { + for (i = 0; i < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i) { + if (slice_param->ref_pic_list0[i].picture_id == VA_INVALID_SURFACE) + break; + } + reflist_0_count = i; + + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + for (i = 0; i < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i) { + if (slice_param->ref_pic_list1[i].picture_id == + VA_INVALID_SURFACE) + break; + } + reflist_1_count = i; + } + } if (picture->type == GST_VAAPI_PICTURE_TYPE_P) { - num_negative_pics = 1; - num_positive_pics = 0; delta_poc_s0_minus1 = picture->poc - slice_param->ref_pic_list0[0].pic_order_cnt - 1; used_by_curr_pic_s0_flag = 1; @@ -710,8 +729,6 @@ bs_write_slice (GstBitWriter * bs, used_by_curr_pic_s1_flag = 0; } if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { - num_negative_pics = 1; - num_positive_pics = 1; delta_poc_s0_minus1 = picture->poc - slice_param->ref_pic_list0[0].pic_order_cnt - 1; used_by_curr_pic_s0_flag = 1; @@ -720,19 +737,35 @@ bs_write_slice (GstBitWriter * bs, used_by_curr_pic_s1_flag = 1; } + num_negative_pics = reflist_0_count; + num_positive_pics = reflist_1_count; + /* num_negative_pics */ WRITE_UE (bs, num_negative_pics); /* num_positive_pics */ WRITE_UE (bs, num_positive_pics); - if (num_negative_pics) { + + for (i = 0; i < num_negative_pics; i++) { /* delta_poc_s0_minus1 */ - WRITE_UE (bs, delta_poc_s0_minus1); + if (i == 0) { + WRITE_UE (bs, delta_poc_s0_minus1); + } else { + WRITE_UE (bs, + slice_param->ref_pic_list0[i - 1].pic_order_cnt - + slice_param->ref_pic_list0[i].pic_order_cnt - 1); + } /* used_by_curr_pic_s0_flag */ WRITE_UINT32 (bs, used_by_curr_pic_s0_flag, 1); } - if (num_positive_pics) { + for (i = 0; i < num_positive_pics; i++) { /* delta_poc_s1_minus1 */ - WRITE_UE (bs, delta_poc_s1_minus1); + if (i == 0) { + WRITE_UE (bs, delta_poc_s1_minus1); + } else { + WRITE_UE (bs, + slice_param->ref_pic_list1[i - 1].pic_order_cnt - + slice_param->ref_pic_list1[i].pic_order_cnt - 1); + } /* used_by_curr_pic_s1_flag */ WRITE_UINT32 (bs, used_by_curr_pic_s1_flag, 1); } @@ -1545,6 +1578,7 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, pic_param->reference_frames[i].picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); + pic_param->reference_frames[i].pic_order_cnt = ref_pic->poc; ++i; } g_assert (i <= 15 && i <= ref_pool->max_ref_frames); @@ -1658,8 +1692,6 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; else slice_param->num_ref_idx_l1_active_minus1 = 0; - g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0); - g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0); i_ref = 0; if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { @@ -1668,7 +1700,6 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); slice_param->ref_pic_list0[i_ref].pic_order_cnt = reflist_0[i_ref]->poc; } - g_assert (i_ref == 1); } for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i_ref) { slice_param->ref_pic_list0[i_ref].picture_id = VA_INVALID_SURFACE; @@ -1682,7 +1713,6 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_1[i_ref]->poc; } - g_assert (i_ref == 1); } for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i_ref) { slice_param->ref_pic_list1[i_ref].picture_id = VA_INVALID_SURFACE; @@ -1983,6 +2013,20 @@ reset_properties (GstVaapiEncoderH265 * encoder) GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, (ctu_size + 1) / 2, &encoder->num_slices)); + gst_vaapi_encoder_ensure_max_num_ref_frames (base_encoder, encoder->profile, + GST_VAAPI_ENTRYPOINT_SLICE_ENCODE); + + if (base_encoder->max_num_ref_frames_1 < 1 && encoder->num_bframes > 0) { + GST_WARNING ("Disabling b-frame since the driver doesn't support it"); + encoder->num_bframes = 0; + } + + if (encoder->num_ref_frames > base_encoder->max_num_ref_frames_0) { + GST_INFO ("Lowering the number of reference frames to %d", + base_encoder->max_num_ref_frames_0); + encoder->num_ref_frames = base_encoder->max_num_ref_frames_0; + } + if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; @@ -2001,16 +2045,15 @@ reset_properties (GstVaapiEncoderH265 * encoder) /* Only Supporting a maximum of two reference frames */ if (encoder->num_bframes) { - encoder->max_dec_pic_buffering = 3; + encoder->max_dec_pic_buffering = encoder->num_ref_frames + 2; encoder->max_num_reorder_pics = 1; } else { - encoder->max_dec_pic_buffering = - (GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder) == 1) ? 1 : 2; + encoder->max_dec_pic_buffering = encoder->num_ref_frames + 1; encoder->max_num_reorder_pics = 0; } ref_pool = &encoder->ref_pool; - ref_pool->max_reflist0_count = 1; + ref_pool->max_reflist0_count = encoder->num_ref_frames; ref_pool->max_reflist1_count = encoder->num_bframes > 0; ref_pool->max_ref_frames = ref_pool->max_reflist0_count + ref_pool->max_reflist1_count; @@ -2367,8 +2410,8 @@ set_context_info (GstVaapiEncoder * base_encoder) if (!ensure_hw_profile (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - base_encoder->num_ref_frames = - ((encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT); + base_encoder->num_ref_frames = (encoder->num_ref_frames + + (encoder->num_bframes > 0 ? 1 : 0) + DEFAULT_SURFACES_COUNT); /* Only YUV 4:2:0 formats are supported for now. */ base_encoder->codedbuf_size += GST_ROUND_UP_32 (vip->width) * From 6816d7c151111087a539309fdf27fd92931ffcaf Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 13 Sep 2017 12:02:53 +0900 Subject: [PATCH 2932/3781] libs: encoder: h264: Add mbbrc property This property supports Macroblock level Bitrate Control as the following: 0: auto 1: on 2: off https://bugzilla.gnome.org/show_bug.cgi?id=785917 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 19 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 5512a50a17..61fd9d2325 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -734,6 +734,7 @@ struct _GstVaapiEncoderH264 guint bitrate_bits; // bitrate (bits) guint cpb_length; // length of CPB buffer (ms) guint cpb_length_bits; // length of CPB buffer (bits) + guint mbbrc; // macroblock bitrate control /* MVC */ gboolean is_mvc; @@ -2270,6 +2271,8 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).rc_flags.bits.mb_rate_control = + encoder->mbbrc; /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); @@ -3092,6 +3095,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES: encoder->num_ref_frames = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_H264_PROP_MBBRC: + encoder->mbbrc = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; @@ -3233,6 +3239,19 @@ gst_vaapi_encoder_h264_get_default_properties (void) "Enable adaptive use of 8x8 transforms in I-frames", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:mbbrc: + * + * Macroblock level bitrate control. + * This is not compatible with Constant QP rate control. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_MBBRC, + g_param_spec_uint ("mbbrc", + "Macroblock level Bitrate Control", + "Macroblock level Bitrate Control (0: auto, 1: on, 2: off)", 0, 2, + 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiEncoderH264:cpb-length: * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 89eab76c33..b56416a27f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -51,6 +51,7 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * @GST_VAAPI_ENCODER_H264_PROP_AUD: Insert AUD as first NAL per frame. * @GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE: Relax Compliance restrictions * @GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES: Maximum number of reference frames. + * @GST_VAAPI_ENCODER_H264_PROP_MBBRC: Macroblock level Bitrate Control. * * The set of H.264 encoder specific configurable properties. */ @@ -67,6 +68,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_AUD = -10, GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE = -11, GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES = -12, + GST_VAAPI_ENCODER_H264_PROP_MBBRC = -13, } GstVaapiEncoderH264Prop; GstVaapiEncoder * From e7c099b957194f0982dd53374ecd628228da5330 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 13 Sep 2017 12:09:45 +0900 Subject: [PATCH 2933/3781] libs: encoder: h265: Add mbbrc property This property supports Macroblock level Bitrate Control as the following (same as h264 encoder): 0: auto 1: on 2: off https://bugzilla.gnome.org/show_bug.cgi?id=785917 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 19 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 4 +++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 99c86ecff4..d18df6db90 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -127,6 +127,7 @@ struct _GstVaapiEncoderH265 guint bitrate_bits; // bitrate (bits) guint cpb_length; // length of CPB buffer (ms) guint cpb_length_bits; // length of CPB buffer (bits) + guint mbbrc; // macroblock bitrate control /* Crop rectangle */ guint conformance_window_flag:1; @@ -1814,6 +1815,8 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).rc_flags.bits.mb_rate_control = + encoder->mbbrc; /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); @@ -2549,6 +2552,9 @@ gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES: encoder->num_ref_frames = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_H265_PROP_MBBRC: + encoder->mbbrc = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -2674,6 +2680,19 @@ gst_vaapi_encoder_h265_get_default_properties (void) 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH265:mbbrc: + * + * Macroblock level bitrate control. + * This is not compatible with Constant QP rate control. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H265_PROP_MBBRC, + g_param_spec_uint ("mbbrc", + "Macroblock level Bitrate Control", + "Macroblock level Bitrate Control (0: auto, 1: on, 2: off)", 0, 2, + 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index dbac0f9a7f..f09081ee50 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -42,6 +42,7 @@ typedef struct _GstVaapiEncoderH265 GstVaapiEncoderH265; * @GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES: Number of slices per frame (uint). * @GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES: Maximum number of reference frames. * @GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH: Length of the CPB buffer + * @GST_VAAPI_ENCODER_H265_PROP_MBBRC: Macroblock level Bitrate Control. * in milliseconds (uint). * * The set of H.265 encoder specific configurable properties. @@ -52,7 +53,8 @@ typedef enum { GST_VAAPI_ENCODER_H265_PROP_MIN_QP = -3, GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES = -4, GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES = -5, - GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH = -7 + GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH = -7, + GST_VAAPI_ENCODER_H265_PROP_MBBRC = -8, } GstVaapiEncoderH265Prop; GstVaapiEncoder * From 5796750604c0a93a4050c31d0d79a830b3c3ed7c Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 13 Sep 2017 12:15:57 +0900 Subject: [PATCH 2934/3781] libs: encoder: h264/h265: keep min_qp as is unless it's over init_qp Creates new variable for QP for I frame and keep it at configuration and use this for pic_init_qp and slice_qp_delta setting. Since changing min qp doesn't make sense, keep min qp as is. https://bugzilla.gnome.org/show_bug.cgi?id=785923 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 11 ++++++----- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 10 +++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 61fd9d2325..635c9110ec 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -708,6 +708,7 @@ struct _GstVaapiEncoderH264 guint32 idr_period; guint32 init_qp; guint32 min_qp; + guint32 qp_i; guint32 num_slices; guint32 num_bframes; guint32 mb_width; @@ -2003,7 +2004,7 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, pic_param->seq_parameter_set_id = encoder->view_idx ? 1 : 0; pic_param->last_picture = 0; /* means last encoding picture */ pic_param->frame_num = picture->frame_num; - pic_param->pic_init_qp = encoder->init_qp; + pic_param->pic_init_qp = encoder->qp_i; pic_param->num_ref_idx_l0_active_minus1 = (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0); pic_param->num_ref_idx_l1_active_minus1 = @@ -2152,9 +2153,10 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, sizeof (slice_param->chroma_offset_l1)); slice_param->cabac_init_idc = 0; - slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp; + slice_param->slice_qp_delta = encoder->qp_i - encoder->init_qp; if (slice_param->slice_qp_delta > 4) slice_param->slice_qp_delta = 4; + slice_param->disable_deblocking_filter_idc = 0; slice_param->slice_alpha_c0_offset_div2 = 2; slice_param->slice_beta_offset_div2 = 2; @@ -2535,10 +2537,9 @@ reset_properties (GstVaapiEncoderH264 * encoder) if (encoder->idr_period > MAX_IDR_PERIOD) encoder->idr_period = MAX_IDR_PERIOD; - if (encoder->min_qp > encoder->init_qp || - (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP && - encoder->min_qp < encoder->init_qp)) + if (encoder->min_qp > encoder->init_qp) encoder->min_qp = encoder->init_qp; + encoder->qp_i = encoder->init_qp; mb_size = encoder->mb_width * encoder->mb_height; g_assert (gst_vaapi_encoder_ensure_num_slices (base_encoder, encoder->profile, diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index d18df6db90..82426d1a1c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -99,6 +99,7 @@ struct _GstVaapiEncoderH265 guint32 idr_period; guint32 init_qp; guint32 min_qp; + guint32 qp_i; guint32 num_slices; guint32 num_bframes; guint32 ctu_width; /* CTU == Coding Tree Unit */ @@ -1594,7 +1595,7 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, pic_param->collocated_ref_pic_index = 0xFF; pic_param->last_picture = 0; - pic_param->pic_init_qp = encoder->init_qp; + pic_param->pic_init_qp = encoder->qp_i; pic_param->num_ref_idx_l0_default_active_minus1 = (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0); pic_param->num_ref_idx_l1_default_active_minus1 = @@ -1721,7 +1722,7 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, } slice_param->max_num_merge_cand = 5; /* MaxNumMergeCand */ - slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp; + slice_param->slice_qp_delta = encoder->qp_i - encoder->init_qp; slice_param->slice_fields.bits. slice_loop_filter_across_slices_enabled_flag = TRUE; @@ -2006,10 +2007,9 @@ reset_properties (GstVaapiEncoderH265 * encoder) if (encoder->idr_period > MAX_IDR_PERIOD) encoder->idr_period = MAX_IDR_PERIOD; - if (encoder->min_qp > encoder->init_qp || - (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP && - encoder->min_qp < encoder->init_qp)) + if (encoder->min_qp > encoder->init_qp) encoder->min_qp = encoder->init_qp; + encoder->qp_i = encoder->init_qp; ctu_size = encoder->ctu_width * encoder->ctu_height; g_assert (gst_vaapi_encoder_ensure_num_slices (base_encoder, encoder->profile, From 64a38a16f15b3fbc7051c489b06f3816fdfa7709 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 13 Sep 2017 12:22:07 +0900 Subject: [PATCH 2935/3781] libs: encoder: h264: support I/P/B QP setting seperatedly Creates 2 properties, qp-ip and qp-ib for setting different QP for P/B frames and set slice_qp_delta for each frame according to the value provided. In addition, remove the limitation of (<= 4) when setting slice_qp_delta. https://bugzilla.gnome.org/show_bug.cgi?id=785923 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 52 +++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 4 ++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 635c9110ec..05edb12faf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -709,6 +709,8 @@ struct _GstVaapiEncoderH264 guint32 init_qp; guint32 min_qp; guint32 qp_i; + guint32 qp_ip; + guint32 qp_ib; guint32 num_slices; guint32 num_bframes; guint32 mb_width; @@ -2154,9 +2156,21 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, slice_param->cabac_init_idc = 0; slice_param->slice_qp_delta = encoder->qp_i - encoder->init_qp; - if (slice_param->slice_qp_delta > 4) - slice_param->slice_qp_delta = 4; - + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) { + if (picture->type == GST_VAAPI_PICTURE_TYPE_P) { + slice_param->slice_qp_delta += encoder->qp_ip; + } else if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + slice_param->slice_qp_delta += encoder->qp_ib; + } + if ((gint) encoder->init_qp + slice_param->slice_qp_delta < + (gint) encoder->min_qp) { + slice_param->slice_qp_delta = encoder->min_qp - encoder->init_qp; + } + /* TODO: max_qp might be provided as a property in the future */ + if ((gint) encoder->init_qp + slice_param->slice_qp_delta > 51) { + slice_param->slice_qp_delta = 51 - encoder->init_qp; + } + } slice_param->disable_deblocking_filter_idc = 0; slice_param->slice_alpha_c0_offset_div2 = 2; slice_param->slice_beta_offset_div2 = 2; @@ -3055,6 +3069,12 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_MIN_QP: encoder->min_qp = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_H264_PROP_QP_IP: + encoder->qp_ip = g_value_get_int (value); + break; + case GST_VAAPI_ENCODER_H264_PROP_QP_IB: + encoder->qp_ib = g_value_get_int (value); + break; case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES: encoder->num_slices = g_value_get_uint (value); break; @@ -3200,6 +3220,32 @@ gst_vaapi_encoder_h264_get_default_properties (void) "Minimum QP", "Minimum quantizer value", 1, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:qp-ip: + * + * The difference of QP between I and P Frame. + * This is available only on CQP mode. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_QP_IP, + g_param_spec_int ("qp-ip", + "Difference of QP between I and P frame", + "Difference of QP between I and P frame (available only on CQP)", + -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH264:qp-ib: + * + * The difference of QP between I and B Frame. + * This is available only on CQP mode. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_QP_IB, + g_param_spec_int ("qp-ib", + "Difference of QP between I and B frame", + "Difference of QP between I and B frame (available only on CQP)", + -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiEncoderH264:num-slices: * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index b56416a27f..42cb08f1c6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -52,6 +52,8 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * @GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE: Relax Compliance restrictions * @GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES: Maximum number of reference frames. * @GST_VAAPI_ENCODER_H264_PROP_MBBRC: Macroblock level Bitrate Control. + * @GST_VAAPI_ENCODER_H264_PROP_QP_IP: Difference of QP between I and P frame. + * @GST_VAAPI_ENCODER_H264_PROP_QP_IB: Difference of QP between I and B frame. * * The set of H.264 encoder specific configurable properties. */ @@ -69,6 +71,8 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE = -11, GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES = -12, GST_VAAPI_ENCODER_H264_PROP_MBBRC = -13, + GST_VAAPI_ENCODER_H264_PROP_QP_IP = -14, + GST_VAAPI_ENCODER_H264_PROP_QP_IB = -15, } GstVaapiEncoderH264Prop; GstVaapiEncoder * From 5333155e27ca8e985dcfaddb6c561c4404d41f5c Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 13 Sep 2017 12:23:42 +0900 Subject: [PATCH 2936/3781] libs: encoder: h265: support I/P/B QP setting seperatedly Creates 2 properties, qp-ip and qp-ib for setting different QP for P/B frames and set slice_qp_delta for each frame according to the value provided. https://bugzilla.gnome.org/show_bug.cgi?id=785923 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 49 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 4 ++ 2 files changed, 53 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 82426d1a1c..603ab6c94e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -100,6 +100,8 @@ struct _GstVaapiEncoderH265 guint32 init_qp; guint32 min_qp; guint32 qp_i; + guint32 qp_ip; + guint32 qp_ib; guint32 num_slices; guint32 num_bframes; guint32 ctu_width; /* CTU == Coding Tree Unit */ @@ -1723,6 +1725,21 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, slice_param->max_num_merge_cand = 5; /* MaxNumMergeCand */ slice_param->slice_qp_delta = encoder->qp_i - encoder->init_qp; + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) { + if (picture->type == GST_VAAPI_PICTURE_TYPE_P) { + slice_param->slice_qp_delta += encoder->qp_ip; + } else if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + slice_param->slice_qp_delta += encoder->qp_ib; + } + if ((gint) encoder->init_qp + slice_param->slice_qp_delta < + (gint) encoder->min_qp) { + slice_param->slice_qp_delta = encoder->min_qp - encoder->init_qp; + } + /* TODO: max_qp could be provided as a property in the future */ + if ((gint) encoder->init_qp + slice_param->slice_qp_delta > 51) { + slice_param->slice_qp_delta = 51 - encoder->init_qp; + } + } slice_param->slice_fields.bits. slice_loop_filter_across_slices_enabled_flag = TRUE; @@ -2543,6 +2560,12 @@ gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H265_PROP_MIN_QP: encoder->min_qp = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_H265_PROP_QP_IP: + encoder->qp_ip = g_value_get_int (value); + break; + case GST_VAAPI_ENCODER_H265_PROP_QP_IB: + encoder->qp_ib = g_value_get_int (value); + break; case GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES: encoder->num_slices = g_value_get_uint (value); break; @@ -2655,6 +2678,32 @@ gst_vaapi_encoder_h265_get_default_properties (void) "Minimum QP", "Minimum quantizer value", 1, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH265:qp-ip: + * + * The difference of QP between I and P Frame. + * This is available only on CQP mode. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H265_PROP_QP_IP, + g_param_spec_int ("qp-ip", + "Difference of QP between I and P frame", + "Difference of QP between I and P frame (available only on CQP)", + -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoderH265:qp-ib: + * + * The difference of QP between I and B Frame. + * This is available only on CQP mode. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H265_PROP_QP_IB, + g_param_spec_int ("qp-ib", + "Difference of QP between I and B frame", + "Difference of QP between I and B frame (available only on CQP)", + -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /* FIXME: there seems to be issues with multi-slice encoding */ /** * GstVaapiEncoderH265:num-slices: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index f09081ee50..3496742a30 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -43,6 +43,8 @@ typedef struct _GstVaapiEncoderH265 GstVaapiEncoderH265; * @GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES: Maximum number of reference frames. * @GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH: Length of the CPB buffer * @GST_VAAPI_ENCODER_H265_PROP_MBBRC: Macroblock level Bitrate Control. + * @GST_VAAPI_ENCODER_H265_PROP_QP_IP: Difference of QP between I and P frame. + * @GST_VAAPI_ENCODER_H265_PROP_QP_IB: Difference of QP between I and B frame. * in milliseconds (uint). * * The set of H.265 encoder specific configurable properties. @@ -55,6 +57,8 @@ typedef enum { GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES = -5, GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH = -7, GST_VAAPI_ENCODER_H265_PROP_MBBRC = -8, + GST_VAAPI_ENCODER_H265_PROP_QP_IP = -9, + GST_VAAPI_ENCODER_H265_PROP_QP_IB = -10, } GstVaapiEncoderH265Prop; GstVaapiEncoder * From 9875c0d84e5c95695d0566ca44bbbc8b42f5a146 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 13 Sep 2017 15:44:32 +0900 Subject: [PATCH 2937/3781] libs: context: fix wrong counter of the array of attributes The counter value passed to vaCreateConfig is always +1. This is a regression caused by commit e42ec3ad. The present patch fixes wrong counting of the array of attributes. https://bugzilla.gnome.org/show_bug.cgi?id=787613 --- gst-libs/gst/vaapi/gstvaapicontext.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 758d3b4969..204e463308 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -241,7 +241,7 @@ config_create (GstVaapiContext * context) gst_vaapi_entrypoint_get_va_entrypoint (cip->entrypoint); attrib_index = 0; - attrib = &attribs[attrib_index++]; + attrib = &attribs[attrib_index]; g_assert (attrib_index < G_N_ELEMENTS (attribs)); /* Validate VA surface format */ @@ -257,7 +257,7 @@ config_create (GstVaapiContext * context) goto cleanup; } attrib->value = va_chroma_format; - attrib = &attribs[attrib_index++]; + attrib = &attribs[++attrib_index]; g_assert (attrib_index < G_N_ELEMENTS (attribs)); switch (cip->usage) { @@ -280,7 +280,7 @@ config_create (GstVaapiContext * context) goto cleanup; } attrib->value = va_rate_control; - attrib = &attribs[attrib_index++]; + attrib = &attribs[++attrib_index]; g_assert (attrib_index < G_N_ELEMENTS (attribs)); } /* Packed headers */ @@ -295,7 +295,7 @@ config_create (GstVaapiContext * context) goto cleanup; } attrib->value = config->packed_headers; - attrib = &attribs[attrib_index++]; + attrib = &attribs[++attrib_index]; g_assert (attrib_index < G_N_ELEMENTS (attribs)); } #if VA_CHECK_VERSION(0,37,0) @@ -304,7 +304,7 @@ config_create (GstVaapiContext * context) if (!context_get_attribute (context, attrib->type, &value)) goto cleanup; attrib->value = value; - attrib = &attribs[attrib_index++]; + attrib = &attribs[++attrib_index]; g_assert (attrib_index < G_N_ELEMENTS (attribs)); } #endif @@ -324,14 +324,14 @@ config_create (GstVaapiContext * context) goto cleanup; } attrib->value = value; - attrib = &attribs[attrib_index++]; + attrib = &attribs[++attrib_index]; g_assert (attrib_index < G_N_ELEMENTS (attribs)); } #endif #if USE_H264_FEI_ENCODER if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI) { attrib->type = (VAConfigAttribType) VAConfigAttribFEIFunctionType; - attrib = &attribs[attrib_index++]; + attrib = &attribs[++attrib_index]; g_assert (attrib_index < G_N_ELEMENTS (attribs)); /* FIXME: Query the read-only supported MV predictors */ } From 2eb2b26ad8d8c3fe9233c9242ae37ebdcec89a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 24 Aug 2017 21:51:22 +0200 Subject: [PATCH 2938/3781] libs: decoder: at update_caps() decode codec_data When updating the caps in decoder, if the caps has codec_data (avC format), it has to be parsed to update the state of the decoder. https://bugzilla.gnome.org/show_bug.cgi?id=786173 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index ce9c065b01..9e716db2c9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -1182,10 +1182,8 @@ gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps) if (!decoder_caps) return FALSE; - if (gst_caps_is_always_compatible (caps, decoder_caps)) { - set_caps (decoder, caps); - return TRUE; - } + if (gst_caps_is_always_compatible (caps, decoder_caps)) + return set_caps (decoder, caps); profile = gst_vaapi_profile_from_caps (caps); if (profile == GST_VAAPI_PROFILE_UNKNOWN) @@ -1194,8 +1192,11 @@ gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps) if (codec == 0) return FALSE; if (codec == decoder->codec) { - set_caps (decoder, caps); - return TRUE; + if (set_caps (decoder, caps)) { + return + gst_vaapi_decoder_decode_codec_data (decoder) == + GST_VAAPI_DECODER_STATUS_SUCCESS; + } } return FALSE; From 148f867c120fbde2ed5a92a8f89ef30a805eb61c Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 15 Sep 2017 15:14:47 +0900 Subject: [PATCH 2939/3781] vaapiencode/libs: encoder: fix leaks of properties https://bugzilla.gnome.org/show_bug.cgi?id=786321 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 ++ gst/vaapi/gstvaapiencode.c | 1 + 2 files changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 8fb60b79df..a05de4288b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1263,6 +1263,8 @@ gst_vaapi_encoder_init_properties (GstVaapiEncoder * encoder) NULL) != GST_VAAPI_ENCODER_STATUS_SUCCESS) return FALSE; } + + g_ptr_array_unref (props); return TRUE; } diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index b3988394a9..27a807afec 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -939,6 +939,7 @@ gst_vaapiencode_init_properties (GstVaapiEncode * encode) return FALSE; g_ptr_array_add (encode->prop_values, prop_value); } + g_ptr_array_unref (props); return TRUE; } From 29cf49d56a39ab5021b1dd4e2651b334febbf1a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 15 Sep 2017 18:31:49 +0200 Subject: [PATCH 2940/3781] libs: encoder: don't unref properties This patch fixes a regression introduced in commit 148f867c, since the props variable is set to object's member variable encoder->properties. And it is set in the instance initialization, thus it will not be leaked. https://bugzilla.gnome.org/show_bug.cgi?id=787733 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index a05de4288b..f0e694c974 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1264,7 +1264,6 @@ gst_vaapi_encoder_init_properties (GstVaapiEncoder * encoder) return FALSE; } - g_ptr_array_unref (props); return TRUE; } From b7c7335238d1131d71ac67453ad4cabbd9e8174f Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Mon, 18 Sep 2017 13:55:49 +1000 Subject: [PATCH 2941/3781] Fix a typo in the prop string for compliance-mode --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 05edb12faf..949f268665 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -94,7 +94,7 @@ gst_vaapi_encoder_h264_compliance_mode_type (void) * This will help to get better performance in some of the Intel * platforms which has LLC restirictions */ {GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_RESTRICT_CODED_BUFFER_ALLOC, - "Restict the allocation size of coded-buffer", + "Restrict the allocation size of coded-buffer", "restrict-buf-alloc"}, {0, NULL, NULL}, }; From e308b452d663d5856cdd74ebaf913fcf0463b1c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 18 Sep 2017 19:11:45 +0200 Subject: [PATCH 2942/3781] libs: encoder: change mbbrc from uint to enum Instead of handling the macroblock bitrate control as a integer, this patch changes it as a enum, which is more self documented in the GStreamer elements. https://bugzilla.gnome.org/show_bug.cgi?id=787855 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 22 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 20 ++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 13 +++++++------ gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 13 +++++++------ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 3 +++ 5 files changed, 59 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index f0e694c974..8befeeed70 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1702,3 +1702,25 @@ gst_vaapi_encoder_tune_get_type (void) } return g_type; } + +/** Returns a GType for the #GstVaapiEncoderMbbrc set */ +GType +gst_vaapi_encoder_mbbrc_get_type (void) +{ + static volatile gsize g_type = 0; + + if (g_once_init_enter (&g_type)) { + static const GEnumValue encoder_mbbrc_values[] = { + {GST_VAAPI_ENCODER_MBBRC_AUTO, "Auto", "auto"}, + {GST_VAAPI_ENCODER_MBBRC_ON, "On", "on"}, + {GST_VAAPI_ENCODER_MBBRC_OFF, "Off", "off"}, + {0, NULL, NULL}, + }; + + GType type = + g_enum_register_static (g_intern_static_string ("GstVaapiEncoderMbbrc"), + encoder_mbbrc_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index e3627ac2cc..d186905733 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -93,6 +93,23 @@ typedef enum { 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; + /** * GstVaapiEncoderProp: * @GST_VAAPI_ENCODER_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). @@ -131,6 +148,9 @@ typedef struct _GstVaapiROI { GType gst_vaapi_encoder_tune_get_type (void) G_GNUC_CONST; +GType +gst_vaapi_encoder_mbbrc_get_type (void) G_GNUC_CONST; + GstVaapiEncoder * gst_vaapi_encoder_ref (GstVaapiEncoder * encoder); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 949f268665..cd9adf808d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -737,7 +737,7 @@ struct _GstVaapiEncoderH264 guint bitrate_bits; // bitrate (bits) guint cpb_length; // length of CPB buffer (ms) guint cpb_length_bits; // length of CPB buffer (bits) - guint mbbrc; // macroblock bitrate control + GstVaapiEncoderMbbrc mbbrc; // macroblock bitrate control /* MVC */ gboolean is_mvc; @@ -2288,7 +2288,7 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).rc_flags.bits.mb_rate_control = - encoder->mbbrc; + (guint) encoder->mbbrc; /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); @@ -3117,7 +3117,7 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, encoder->num_ref_frames = g_value_get_uint (value); break; case GST_VAAPI_ENCODER_H264_PROP_MBBRC: - encoder->mbbrc = g_value_get_uint (value); + encoder->mbbrc = g_value_get_enum (value); break; default: @@ -3294,10 +3294,11 @@ gst_vaapi_encoder_h264_get_default_properties (void) */ GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H264_PROP_MBBRC, - g_param_spec_uint ("mbbrc", + g_param_spec_enum ("mbbrc", "Macroblock level Bitrate Control", - "Macroblock level Bitrate Control (0: auto, 1: on, 2: off)", 0, 2, - 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Macroblock level Bitrate Control", + GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiEncoderH264:cpb-length: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 603ab6c94e..5e4c84081b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -130,7 +130,7 @@ struct _GstVaapiEncoderH265 guint bitrate_bits; // bitrate (bits) guint cpb_length; // length of CPB buffer (ms) guint cpb_length_bits; // length of CPB buffer (bits) - guint mbbrc; // macroblock bitrate control + GstVaapiEncoderMbbrc mbbrc; // macroblock bitrate control /* Crop rectangle */ guint conformance_window_flag:1; @@ -1834,7 +1834,7 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).rc_flags.bits.mb_rate_control = - encoder->mbbrc; + (guint) encoder->mbbrc; /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); @@ -2576,7 +2576,7 @@ gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, encoder->num_ref_frames = g_value_get_uint (value); break; case GST_VAAPI_ENCODER_H265_PROP_MBBRC: - encoder->mbbrc = g_value_get_uint (value); + encoder->mbbrc = g_value_get_enum (value); break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; @@ -2737,10 +2737,11 @@ gst_vaapi_encoder_h265_get_default_properties (void) */ GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H265_PROP_MBBRC, - g_param_spec_uint ("mbbrc", + g_param_spec_enum ("mbbrc", "Macroblock level Bitrate Control", - "Macroblock level Bitrate Control (0: auto, 1: on, 2: off)", 0, 2, - 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Macroblock level Bitrate Control", + GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index ead9f5eec3..d71a49e1aa 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -215,6 +215,9 @@ G_BEGIN_DECLS #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; From b107520587bb52c0817f93f9de2245791c45159e Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Mon, 18 Sep 2017 14:29:55 +0900 Subject: [PATCH 2943/3781] libs: decoder: h264/h265: decode codec data only if opened Fixes regression introduced by commit 2eb2b26a. There is a use case when the decoder set the src caps and immediatly tries to process the media codec_data, this happens before decoder is even opened, thus priv->parser is not instantiated yet. https://bugzilla.gnome.org/show_bug.cgi?id=787818 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 3 +++ gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index ac45427645..a0698659d8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4381,6 +4381,9 @@ gst_vaapi_decoder_h264_decode_codec_data (GstVaapiDecoder * base_decoder, GstH264ParserResult result; guint i, ofs, num_sps, num_pps; + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + unit.parsed_info = NULL; if (buf_size < 7) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 9d2fa6ee17..e9353cf40b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2653,6 +2653,9 @@ gst_vaapi_decoder_h265_decode_codec_data (GstVaapiDecoder * guint num_nal_arrays, num_nals; guint i, j, ofs; + if (!priv->is_opened) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + unit.parsed_info = NULL; if (buf_size < 23) return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; From 684babb0d0f76f1eadeaf7fea4c8ee028a3594c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 Sep 2017 17:50:15 +0200 Subject: [PATCH 2944/3781] tests: test-display: remove display cache tests Since commit ec3e10f6, display cache was removed. This patch removes this leftovers in the display test. --- tests/test-display.c | 84 -------------------------------------------- 1 file changed, 84 deletions(-) diff --git a/tests/test-display.c b/tests/test-display.c index 9abe7546d9..154ca4048c 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -51,9 +51,6 @@ # include #endif -/* Set to 1 to check display cache works (shared VA display) */ -#define CHECK_DISPLAY_CACHE 1 - static void print_value (const GValue * value, const gchar * name) { @@ -270,9 +267,6 @@ int main (int argc, char *argv[]) { GstVaapiDisplay *display; -#if USE_X11 - GstVaapiDisplay *display2; -#endif #if USE_X11 || USE_WAYLAND guint width, height; guint par_n, par_d; @@ -349,46 +343,6 @@ main (int argc, char *argv[]) display = gst_vaapi_display_x11_new (NULL); if (!display) g_error ("could not create Gst/VA display"); - - if (CHECK_DISPLAY_CACHE) { - display2 = gst_vaapi_display_x11_new (NULL); - - /* Check for the same X11 display */ - g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 - (display)) == - gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2))); - - /* Check for the same VA display */ - g_assert (gst_vaapi_display_get_display (display) == - gst_vaapi_display_get_display (display2)); - - gst_vaapi_display_unref (display2); - -#if USE_GLX - display2 = gst_vaapi_display_glx_new (NULL); - - /* Check for the different X11 display */ - /* XXX: it is also desired to cache underlying X11 displays */ - g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 - (display)) != - gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2))); - - /* Check for different VA display */ - g_assert (gst_vaapi_display_get_display (display) != - gst_vaapi_display_get_display (display2)); - - gst_vaapi_display_unref (display2); -#endif - } - - gst_vaapi_display_get_size (display, &width, &height); - g_print ("Display size: %ux%u\n", width, height); - - gst_vaapi_display_get_pixel_aspect_ratio (display, &par_n, &par_d); - g_print ("Pixel aspect ratio: %u/%u\n", par_n, par_d); - - dump_info (display); - gst_vaapi_display_unref (display); } g_print ("\n"); @@ -406,16 +360,6 @@ main (int argc, char *argv[]) if (!display) g_error ("could not create Gst/VA display"); - if (CHECK_DISPLAY_CACHE) { - display2 = gst_vaapi_display_x11_new_with_display (x11_display); - - /* Check for the same VA display */ - g_assert (gst_vaapi_display_get_display (display) == - gst_vaapi_display_get_display (display2)); - - gst_vaapi_display_unref (display2); - } - dump_info (display); gst_vaapi_display_unref (display); XCloseDisplay (x11_display); @@ -458,34 +402,6 @@ main (int argc, char *argv[]) if (!display) g_error ("could not create Gst/VA display"); - if (CHECK_DISPLAY_CACHE) { - display2 = gst_vaapi_display_glx_new (NULL); - - /* Check for the same X11 display */ - g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 - (display)) == - gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2))); - - /* Check for the same VA display */ - g_assert (gst_vaapi_display_get_display (display) == - gst_vaapi_display_get_display (display2)); - - gst_vaapi_display_unref (display2); - - display2 = gst_vaapi_display_x11_new (NULL); - - /* Check for the same X11 display */ - g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 - (display)) == - gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2))); - - /* Check for the same VA display */ - g_assert (gst_vaapi_display_get_display (display) == - gst_vaapi_display_get_display (display2)); - - gst_vaapi_display_unref (display2); - } - gst_vaapi_display_get_size (display, &width, &height); g_print ("Display size: %ux%u\n", width, height); From 9116ffb7b759669271595ee298666c1e34b10ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 Sep 2017 15:12:05 +0200 Subject: [PATCH 2945/3781] libs: display: remove libgstvaapi_init_once() It is not required since it can be unrolled in gst_vaapi_display_class_init() https://bugzilla.gnome.org/show_bug.cgi?id=788058 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 29 ++++++++-------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 6575e4e733..2881cd9353 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -43,10 +43,11 @@ GST_DEBUG_CATEGORY (gst_debug_vaapi); GST_DEBUG_CATEGORY (gst_debug_vaapi_display); #define GST_CAT_DEFAULT gst_debug_vaapi_display -#define _do_init \ - G_ADD_PRIVATE (GstVaapiDisplay); \ - GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_display, \ - "vaapidisplay", 0, "VA-API Display"); +#define _do_init \ + G_ADD_PRIVATE (GstVaapiDisplay); \ + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_display, \ + "vaapidisplay", 0, "VA-API Display"); \ + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi, "vaapi", 0, "VA-API helper"); G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplay, gst_vaapi_display, GST_TYPE_OBJECT, _do_init); @@ -112,21 +113,6 @@ get_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat * v); static gboolean set_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat v); -static void -libgstvaapi_init_once (void) -{ - static gsize g_once = FALSE; - - if (!g_once_init_enter (&g_once)) - return; - - GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi, "vaapi", 0, "VA-API helper"); - - gst_vaapi_display_properties_init (); - - g_once_init_leave (&g_once, TRUE); -} - /* GstVaapiDisplayType enumerations */ GType gst_vaapi_display_type_get_type (void) @@ -972,11 +958,12 @@ gst_vaapi_display_class_init (GstVaapiDisplayClass * klass) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); - libgstvaapi_init_once (); - object_class->finalize = gst_vaapi_display_finalize; + klass->lock = gst_vaapi_display_lock_default; klass->unlock = gst_vaapi_display_unlock_default; + + gst_vaapi_display_properties_init (); } static void From 9dcaa0d09f39f46c45d2e66e31b3116d49b9c762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 Sep 2017 15:16:34 +0200 Subject: [PATCH 2946/3781] libs: display: remove gst_vaapi_display_properties_init() Remove gst_vaapi_display_properties_init() since it can be unrolled in gst_vaapi_display_class_init() https://bugzilla.gnome.org/show_bug.cgi?id=788058 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 2881cd9353..4cf64e3016 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -84,9 +84,7 @@ struct _GstVaapiFormatInfo enum { - PROP_0, - - PROP_RENDER_MODE, + PROP_RENDER_MODE = 1, PROP_ROTATION, PROP_HUE, PROP_SATURATION, @@ -98,8 +96,6 @@ enum static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; -static void gst_vaapi_display_properties_init (void); - static gboolean get_attribute (GstVaapiDisplay * display, VADisplayAttribType type, gint * value); @@ -963,12 +959,6 @@ gst_vaapi_display_class_init (GstVaapiDisplayClass * klass) klass->lock = gst_vaapi_display_lock_default; klass->unlock = gst_vaapi_display_unlock_default; - gst_vaapi_display_properties_init (); -} - -static void -gst_vaapi_display_properties_init (void) -{ /** * GstVaapiDisplay:render-mode: * From 0eeef929112ababb6125119f21fabf1ab72f3e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 Sep 2017 16:29:02 +0200 Subject: [PATCH 2947/3781] libs: display: install properties in class Install the properties in the class as a normal GObject. Implement set_property() and get_property() vmethods. https://bugzilla.gnome.org/show_bug.cgi?id=788058 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 4cf64e3016..eb0e69b009 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -937,6 +937,38 @@ gst_vaapi_display_init (GstVaapiDisplay * display) g_rec_mutex_init (&priv->mutex); } +static void +_gst_vaapi_display_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiDisplay *display = GST_VAAPI_DISPLAY (object); + const GstVaapiProperty *prop; + + prop = find_property_by_pspec (display, pspec); + if (!prop) { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + return; + } + + gst_vaapi_display_set_property (display, prop->name, value); +} + +static void +_gst_vaapi_display_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiDisplay *display = GST_VAAPI_DISPLAY (object); + const GstVaapiProperty *prop; + + prop = find_property_by_pspec (display, pspec); + if (!prop) { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + return; + } + + gst_vaapi_display_get_property (display, prop->name, value); +} + static void gst_vaapi_display_finalize (GObject * object) { @@ -955,6 +987,8 @@ gst_vaapi_display_class_init (GstVaapiDisplayClass * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); object_class->finalize = gst_vaapi_display_finalize; + object_class->set_property = _gst_vaapi_display_set_property; + object_class->get_property = _gst_vaapi_display_get_property; klass->lock = gst_vaapi_display_lock_default; klass->unlock = gst_vaapi_display_unlock_default; @@ -1023,6 +1057,8 @@ gst_vaapi_display_class_init (GstVaapiDisplayClass * klass) g_param_spec_float (GST_VAAPI_DISPLAY_PROP_CONTRAST, "contrast", "The display contrast value", 0.0, 2.0, 1.0, G_PARAM_READWRITE); + + g_object_class_install_properties (object_class, N_PROPERTIES, g_properties); } GstVaapiDisplay * From 6b35e00a287bccc2ebc036028e0e6a1b360a5063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 Sep 2017 17:04:17 +0200 Subject: [PATCH 2948/3781] libs: display: optimize properties setters and getters Shuffled some code to avoid to find the properties descriptor in the array twice, adding the internal functions _set_property() and _get_property(). https://bugzilla.gnome.org/show_bug.cgi?id=788058 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 150 +++++++++++++++------------ 1 file changed, 85 insertions(+), 65 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index eb0e69b009..de31e01715 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -937,6 +937,43 @@ gst_vaapi_display_init (GstVaapiDisplay * display) g_rec_mutex_init (&priv->mutex); } +static gboolean +_set_property (GstVaapiDisplay * display, const GstVaapiProperty * prop, + const GValue * value) +{ + switch (prop->attribute.type) { + case VADisplayAttribRenderMode:{ + GstVaapiRenderMode mode; + if (!G_VALUE_HOLDS (value, GST_VAAPI_TYPE_RENDER_MODE)) + return FALSE; + mode = g_value_get_enum (value); + return gst_vaapi_display_set_render_mode (display, mode); + } + case VADisplayAttribRotation:{ + GstVaapiRotation rotation; + if (!G_VALUE_HOLDS (value, GST_VAAPI_TYPE_ROTATION)) + return FALSE; + rotation = g_value_get_enum (value); + return gst_vaapi_display_set_rotation (display, rotation); + } + case VADisplayAttribHue: + case VADisplayAttribSaturation: + case VADisplayAttribBrightness: + case VADisplayAttribContrast:{ + gfloat v; + if (!G_VALUE_HOLDS (value, G_TYPE_FLOAT)) + return FALSE; + v = g_value_get_float (value); + return set_color_balance (display, find_property_id (prop->name), v); + } + default: + break; + } + + GST_WARNING ("unsupported property '%s'", prop->name); + return FALSE; +} + static void _gst_vaapi_display_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) @@ -944,13 +981,54 @@ _gst_vaapi_display_set_property (GObject * object, guint property_id, GstVaapiDisplay *display = GST_VAAPI_DISPLAY (object); const GstVaapiProperty *prop; + if (!ensure_properties (display)) + return; + prop = find_property_by_pspec (display, pspec); if (!prop) { G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); return; } - gst_vaapi_display_set_property (display, prop->name, value); + _set_property (display, prop, value); +} + +static gboolean +_get_property (GstVaapiDisplay * display, const GstVaapiProperty * prop, + GValue * value) +{ + switch (prop->attribute.type) { + case VADisplayAttribRenderMode:{ + GstVaapiRenderMode mode; + if (!gst_vaapi_display_get_render_mode (display, &mode)) + return FALSE; + g_value_init (value, GST_VAAPI_TYPE_RENDER_MODE); + g_value_set_enum (value, mode); + break; + } + case VADisplayAttribRotation:{ + GstVaapiRotation rotation; + rotation = gst_vaapi_display_get_rotation (display); + g_value_init (value, GST_VAAPI_TYPE_ROTATION); + g_value_set_enum (value, rotation); + break; + } + case VADisplayAttribHue: + case VADisplayAttribSaturation: + case VADisplayAttribBrightness: + case VADisplayAttribContrast:{ + gfloat val; + if (!get_color_balance (display, find_property_id (prop->name), &val)) + return FALSE; + g_value_init (value, G_TYPE_FLOAT); + g_value_set_float (value, val); + break; + } + default: + GST_WARNING ("unsupported property '%s'", prop->name); + return FALSE; + } + return TRUE; } static void @@ -960,13 +1038,16 @@ _gst_vaapi_display_get_property (GObject * object, guint property_id, GstVaapiDisplay *display = GST_VAAPI_DISPLAY (object); const GstVaapiProperty *prop; + if (!ensure_properties (display)) + return; + prop = find_property_by_pspec (display, pspec); if (!prop) { G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); return; } - gst_vaapi_display_get_property (display, prop->name, value); + _get_property (display, prop, value); } static void @@ -1648,38 +1729,7 @@ gst_vaapi_display_get_property (GstVaapiDisplay * display, const gchar * name, if (!prop) return FALSE; - switch (prop->attribute.type) { - case VADisplayAttribRenderMode:{ - GstVaapiRenderMode mode; - if (!gst_vaapi_display_get_render_mode (display, &mode)) - return FALSE; - g_value_init (out_value, GST_VAAPI_TYPE_RENDER_MODE); - g_value_set_enum (out_value, mode); - break; - } - case VADisplayAttribRotation:{ - GstVaapiRotation rotation; - rotation = gst_vaapi_display_get_rotation (display); - g_value_init (out_value, GST_VAAPI_TYPE_ROTATION); - g_value_set_enum (out_value, rotation); - break; - } - case VADisplayAttribHue: - case VADisplayAttribSaturation: - case VADisplayAttribBrightness: - case VADisplayAttribContrast:{ - gfloat value; - if (!get_color_balance (display, find_property_id (name), &value)) - return FALSE; - g_value_init (out_value, G_TYPE_FLOAT); - g_value_set_float (out_value, value); - break; - } - default: - GST_WARNING ("unsupported property '%s'", name); - return FALSE; - } - return TRUE; + return _get_property (display, prop, out_value); } gboolean @@ -1700,37 +1750,7 @@ gst_vaapi_display_set_property (GstVaapiDisplay * display, const gchar * name, if (!prop) return FALSE; - switch (prop->attribute.type) { - case VADisplayAttribRenderMode:{ - GstVaapiRenderMode mode; - if (!G_VALUE_HOLDS (value, GST_VAAPI_TYPE_RENDER_MODE)) - return FALSE; - mode = g_value_get_enum (value); - return gst_vaapi_display_set_render_mode (display, mode); - } - case VADisplayAttribRotation:{ - GstVaapiRotation rotation; - if (!G_VALUE_HOLDS (value, GST_VAAPI_TYPE_ROTATION)) - return FALSE; - rotation = g_value_get_enum (value); - return gst_vaapi_display_set_rotation (display, rotation); - } - case VADisplayAttribHue: - case VADisplayAttribSaturation: - case VADisplayAttribBrightness: - case VADisplayAttribContrast:{ - gfloat v; - if (!G_VALUE_HOLDS (value, G_TYPE_FLOAT)) - return FALSE; - v = g_value_get_float (value); - return set_color_balance (display, find_property_id (name), v); - } - default: - break; - } - - GST_WARNING ("unsupported property '%s'", name); - return FALSE; + return _set_property (display, prop, value); } static gboolean From b23ccc69b035dc4d79b7411570debfe538928745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 Sep 2017 18:59:49 +0200 Subject: [PATCH 2949/3781] libs: display: initialize value if they are not yet This is a difference between the GObject API and the GstVaapi one: the GValue passed to get a property value, in GObject has to be initialized with g_value_init(), but in GstVaapi is has not. In order to overcome this mismatch, this patch call g_value_init() internally only in the passed one is not already initialized. https://bugzilla.gnome.org/show_bug.cgi?id=788058 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index de31e01715..1d34434abc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1002,14 +1002,16 @@ _get_property (GstVaapiDisplay * display, const GstVaapiProperty * prop, GstVaapiRenderMode mode; if (!gst_vaapi_display_get_render_mode (display, &mode)) return FALSE; - g_value_init (value, GST_VAAPI_TYPE_RENDER_MODE); + if (!G_IS_VALUE (value)) + g_value_init (value, GST_VAAPI_TYPE_RENDER_MODE); g_value_set_enum (value, mode); break; } case VADisplayAttribRotation:{ GstVaapiRotation rotation; rotation = gst_vaapi_display_get_rotation (display); - g_value_init (value, GST_VAAPI_TYPE_ROTATION); + if (!G_IS_VALUE (value)) + g_value_init (value, GST_VAAPI_TYPE_ROTATION); g_value_set_enum (value, rotation); break; } @@ -1020,7 +1022,8 @@ _get_property (GstVaapiDisplay * display, const GstVaapiProperty * prop, gfloat val; if (!get_color_balance (display, find_property_id (prop->name), &val)) return FALSE; - g_value_init (value, G_TYPE_FLOAT); + if (!G_IS_VALUE (value)) + g_value_init (value, G_TYPE_FLOAT); g_value_set_float (value, val); break; } From b063511c0512f7cb09a6c94c9b3b0df4dab8d581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 Sep 2017 19:25:20 +0200 Subject: [PATCH 2950/3781] vaapisink: use GObject setter and getter Instead of using gst_vaapi_display_set_property() or gst_vaapi_display_get_property(), this patch set replace it usage with g_object_set() or g_object_get(). Also the internal helper cb_set_value() is removed since it is not used anymore. https://bugzilla.gnome.org/show_bug.cgi?id=788058 --- gst/vaapi/gstvaapisink.c | 44 +++++++++++++--------------------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 27f0a6e037..a4bea49425 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -652,14 +652,14 @@ cb_get_gvalue (GstVaapiSink * sink, guint id) } static gboolean -cb_set_gvalue (GstVaapiSink * sink, guint id, const GValue * value) +cb_set_value (GstVaapiSink * sink, guint id, gfloat value) { GValue *const v_value = cb_get_gvalue (sink, id); if (!v_value) return FALSE; - g_value_set_float (v_value, g_value_get_float (value)); + g_value_set_float (v_value, value); sink->cb_changed |= (1U << id); return TRUE; } @@ -672,57 +672,40 @@ cb_get_value (GstVaapiSink * sink, guint id) return v_value ? g_value_get_float (v_value) : 0.0; } -static gboolean -cb_set_value (GstVaapiSink * sink, guint id, gfloat value) -{ - GValue v_value = G_VALUE_INIT; - gboolean success; - - g_value_init (&v_value, G_TYPE_FLOAT); - g_value_set_float (&v_value, value); - success = cb_set_gvalue (sink, id, &v_value); - g_value_unset (&v_value); - return success; -} - static gboolean cb_sync_values_from_display (GstVaapiSink * sink, GstVaapiDisplay * display) { - GValue v_value = G_VALUE_INIT; - guint i, failures = 0; + guint i; + gfloat value; for (i = 0; i < G_N_ELEMENTS (sink->cb_values); i++) { const guint cb_id = CB_HUE + i; if (!gst_vaapi_display_has_property (display, cb_map[i].prop_name)) continue; - if (G_IS_VALUE (&v_value)) - g_value_unset (&v_value); - if (gst_vaapi_display_get_property (display, cb_map[i].prop_name, &v_value)) - cb_set_gvalue (sink, cb_id, &v_value); - else - failures++; + value = 0.0; + g_object_get (display, cb_map[i].prop_name, &value, NULL); + cb_set_value (sink, cb_id, value); } sink->cb_changed = 0; - return failures == 0; + return TRUE; } static gboolean cb_sync_values_to_display (GstVaapiSink * sink, GstVaapiDisplay * display) { - guint i, failures = 0; + guint i; for (i = 0; i < G_N_ELEMENTS (sink->cb_values); i++) { const guint cb_id = CB_HUE + i; if (!(sink->cb_changed & (1U << cb_id))) continue; - if (!gst_vaapi_display_set_property (display, cb_map[i].prop_name, - cb_get_gvalue (sink, cb_id))) - failures++; + g_object_set_property (G_OBJECT (display), cb_map[i].prop_name, + cb_get_gvalue (sink, cb_id)); } sink->cb_changed = 0; - return failures == 0; + return TRUE; } #define CB_CHANNEL_FACTOR (1000.0) @@ -1602,7 +1585,8 @@ gst_vaapisink_set_property (GObject * object, case PROP_SATURATION: case PROP_BRIGHTNESS: case PROP_CONTRAST: - cb_set_gvalue (sink, (prop_id - PROP_HUE) + CB_HUE, value); + cb_set_value (sink, (prop_id - PROP_HUE) + CB_HUE, + g_value_get_float (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); From 7d74176395b17e2a5d694c8b17b0cb23469605e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 22 Sep 2017 19:35:04 +0200 Subject: [PATCH 2951/3781] tests: display: use GObject getter Instead of using the gst_vaapi_display_get_property(), this patch replaces it with g_object_get_property() to dump the available VA display properties. https://bugzilla.gnome.org/show_bug.cgi?id=788058 --- tests/test-display.c | 86 +++++++------------------------------------- 1 file changed, 12 insertions(+), 74 deletions(-) diff --git a/tests/test-display.c b/tests/test-display.c index 154ca4048c..d81e903046 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -140,91 +140,29 @@ print_formats (GArray * formats, const gchar * name) } } -typedef struct _GstVaapiDisplayProperty GstVaapiDisplayProperty; -struct _GstVaapiDisplayProperty -{ - const gchar *name; - GValue value; -}; - -static void -gst_vaapi_display_property_free (GstVaapiDisplayProperty * prop) -{ - if (!prop) - return; - g_value_unset (&prop->value); - g_slice_free (GstVaapiDisplayProperty, prop); -} - -static GstVaapiDisplayProperty * -gst_vaapi_display_property_new (const gchar * name) -{ - GstVaapiDisplayProperty *prop; - - prop = g_slice_new0 (GstVaapiDisplayProperty); - if (!prop) - return NULL; - prop->name = name; - return prop; -} - -static void -free_property_cb (gpointer data, gpointer user_data) -{ - gst_vaapi_display_property_free (data); -} - static void dump_properties (GstVaapiDisplay * display) { - GstVaapiDisplayProperty *prop; - GPtrArray *properties; - guint i; + GParamSpec **properties; + guint i, n_properties; - static const gchar *g_properties[] = { - GST_VAAPI_DISPLAY_PROP_RENDER_MODE, - GST_VAAPI_DISPLAY_PROP_ROTATION, - GST_VAAPI_DISPLAY_PROP_HUE, - GST_VAAPI_DISPLAY_PROP_SATURATION, - GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, - GST_VAAPI_DISPLAY_PROP_CONTRAST, - NULL - }; + properties = + g_object_class_list_properties (G_OBJECT_GET_CLASS (display), + &n_properties); - properties = g_ptr_array_new (); - if (!properties) - return; - - for (i = 0; g_properties[i] != NULL; i++) { - const gchar *const name = g_properties[i]; + for (i = 0; i < n_properties; i++) { + const gchar *const name = g_param_spec_get_nick (properties[i]); + GValue value = G_VALUE_INIT; if (!gst_vaapi_display_has_property (display, name)) continue; - prop = gst_vaapi_display_property_new (name); - if (!prop) { - GST_ERROR ("failed to allocate GstVaapiDisplayProperty"); - goto end; - } - - if (!gst_vaapi_display_get_property (display, name, &prop->value)) { - GST_ERROR ("failed to get property '%s'", name); - goto end; - } - g_ptr_array_add (properties, prop); + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (properties[i])); + g_object_get_property (G_OBJECT (display), name, &value); + print_value (&value, name); } - g_print ("%u properties\n", properties->len); - for (i = 0; i < properties->len; i++) { - prop = g_ptr_array_index (properties, i); - print_value (&prop->value, prop->name); - } - -end: - if (properties) { - g_ptr_array_foreach (properties, free_property_cb, NULL); - g_ptr_array_free (properties, TRUE); - } + g_free (properties); } static void From a4daa2a04af923117bece0587db48e6ab35cb4d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 25 Sep 2017 15:50:19 +0200 Subject: [PATCH 2952/3781] vaapidecode: drain pending frames before set format Drain pending frames, if any, in the internal decoder before setting the new negotiated format. https://bugzilla.gnome.org/show_bug.cgi?id=786173 --- gst/vaapi/gstvaapidecode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4c33b06b05..1ecc537020 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1088,6 +1088,8 @@ gst_vaapidecode_set_format (GstVideoDecoder * vdec, GstVideoCodecState * state) if (!gst_vaapi_decode_input_state_replace (decode, state)) return TRUE; + if (gst_vaapidecode_drain (vdec) == GST_FLOW_ERROR) + return FALSE; if (!gst_vaapidecode_update_sink_caps (decode, state->caps)) return FALSE; if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) From 9f4a5762d5bc82a65b2bf414ed002462e231c899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 25 Sep 2017 17:04:12 +0200 Subject: [PATCH 2953/3781] vaapiencode: flush pending frames before set format Flush pending frames, if any, in the internal encorder, before setting the new negotiated format. https://bugzilla.gnome.org/show_bug.cgi?id=786173 --- gst/vaapi/gstvaapiencode.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 27a807afec..0aaa4d1008 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -564,6 +564,22 @@ set_codec_state (GstVaapiEncode * encode, GstVideoCodecState * state) return TRUE; } +static gboolean +gst_vaapiencode_drain (GstVaapiEncode * encode) +{ + GstVaapiEncoderStatus status; + + if (!encode->encoder) + return TRUE; + + status = gst_vaapi_encoder_flush (encode->encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return FALSE; + gst_vaapiencode_purge (encode); + + return TRUE; +} + static gboolean gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) { @@ -579,6 +595,9 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) state->caps, NULL)) return FALSE; + if (!gst_vaapiencode_drain (encode)) + return FALSE; + if (encode->input_state) gst_video_codec_state_unref (encode->input_state); encode->input_state = gst_video_codec_state_ref (state); @@ -824,17 +843,14 @@ static gboolean gst_vaapiencode_flush (GstVideoEncoder * venc) { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); - GstVaapiEncoderStatus status; if (!encode->encoder) return FALSE; GST_LOG_OBJECT (encode, "flushing"); - status = gst_vaapi_encoder_flush (encode->encoder); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + if (!gst_vaapiencode_drain (encode)) return FALSE; - gst_vaapiencode_purge (encode); gst_vaapi_encoder_replace (&encode->encoder, NULL); if (!ensure_encoder (encode)) From 8fee85ecaa8acf7e907439356063074e6d507d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Sep 2017 11:27:40 +0200 Subject: [PATCH 2954/3781] plugins: memory:DMABuf only handles planar formats When glimagesink negotiates the caps feature memory:DMABuf the exported dmabufs buffers with NV12 format are not well rendered, thus setting only planar. https://bugzilla.gnome.org/show_bug.cgi?id=788229 --- gst/vaapi/gstvaapipluginutil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 19053df0ce..68450ce7d0 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -113,7 +113,7 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps, #define GST_VAAPI_MAKE_DMABUF_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_DMABUF, "{ NV12, I420, YV12 }") + GST_CAPS_FEATURE_MEMORY_DMABUF, "{ I420, YV12, RGBA }") G_GNUC_INTERNAL gboolean From f6fc1774b94f2d2e444ca38faa7102fcd1dc6334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Sep 2017 13:32:34 +0200 Subject: [PATCH 2955/3781] vaapipostproc: use scoped variable for return value Instead of reusing a parameter variable for the return value of gst_vaapipostproc_fixate_caps(), this patch uses the function scoped pointer. Thus, the code is cleaner. https://bugzilla.gnome.org/show_bug.cgi?id=785706 --- gst/vaapi/gstvaapipostproc.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 241a4efd81..b984f33c1f 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1158,24 +1158,22 @@ gst_vaapipostproc_fixate_caps (GstBaseTransform * trans, if (direction == GST_PAD_SRC) { /* @TODO: we can do better */ - othercaps = gst_caps_fixate (othercaps); + outcaps = gst_caps_fixate (othercaps); goto done; } g_mutex_lock (&postproc->postproc_lock); - if ((outcaps = gst_vaapipostproc_fixate_srccaps (postproc, caps, othercaps))) - gst_caps_replace (&othercaps, outcaps); + outcaps = gst_vaapipostproc_fixate_srccaps (postproc, caps, othercaps); g_mutex_unlock (&postproc->postproc_lock); /* set passthrough according to caps changes or filter changes */ gst_vaapipostproc_set_passthrough (trans); done: - GST_DEBUG_OBJECT (trans, "fixated othercaps to %" GST_PTR_FORMAT, othercaps); - if (outcaps) - gst_caps_unref (outcaps); + GST_DEBUG_OBJECT (trans, "fixated othercaps to %" GST_PTR_FORMAT, outcaps); + gst_caps_unref (othercaps); - return othercaps; + return outcaps; } static gboolean From d3732a7cf8bc2b219b8e3e26869dd530e334d15b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Sep 2017 18:32:03 +0200 Subject: [PATCH 2956/3781] vaapipostproc: removed unused parameter Removed caps parameter from gst_vaapipostproc_transform_caps_impl() helper function since the it is not used. https://bugzilla.gnome.org/show_bug.cgi?id=785706 --- gst/vaapi/gstvaapipostproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index b984f33c1f..7da1547e76 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1103,7 +1103,7 @@ ensure_allowed_srcpad_caps (GstVaapiPostproc * postproc) static GstCaps * gst_vaapipostproc_transform_caps_impl (GstBaseTransform * trans, - GstPadDirection direction, GstCaps * caps) + GstPadDirection direction) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); @@ -1132,7 +1132,7 @@ gst_vaapipostproc_transform_caps (GstBaseTransform * trans, (direction == GST_PAD_SINK) ? "sink" : "src"); g_mutex_lock (&postproc->postproc_lock); - caps = gst_vaapipostproc_transform_caps_impl (trans, direction, caps); + caps = gst_vaapipostproc_transform_caps_impl (trans, direction); g_mutex_unlock (&postproc->postproc_lock); if (caps && filter) { out_caps = gst_caps_intersect_full (caps, filter, GST_CAPS_INTERSECT_FIRST); From bedaa13d7c208c9da44bf5cfe1b0f3e82dacc162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Sep 2017 18:35:20 +0200 Subject: [PATCH 2957/3781] vaapipostproc: use scoped variable for return value Instead of reusing a parameter variable for the return value of gst_vaapipostproc_transform_caps(), this patch uses the function scoped pointer. Thus, the code is cleaner. https://bugzilla.gnome.org/show_bug.cgi?id=785706 --- gst/vaapi/gstvaapipostproc.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 7da1547e76..427193c5f4 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1132,17 +1132,21 @@ gst_vaapipostproc_transform_caps (GstBaseTransform * trans, (direction == GST_PAD_SINK) ? "sink" : "src"); g_mutex_lock (&postproc->postproc_lock); - caps = gst_vaapipostproc_transform_caps_impl (trans, direction); + out_caps = gst_vaapipostproc_transform_caps_impl (trans, direction); g_mutex_unlock (&postproc->postproc_lock); - if (caps && filter) { - out_caps = gst_caps_intersect_full (caps, filter, GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (caps); - caps = out_caps; + + if (out_caps && filter) { + GstCaps *intersection; + + intersection = gst_caps_intersect_full (out_caps, filter, + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (out_caps); + out_caps = intersection; } - GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, caps); + GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, out_caps); - return caps; + return out_caps; } static GstCaps * From 76e9ad8646e4a2d56d6719b6f54d66d12e9e024c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 3 Oct 2017 10:51:06 +0200 Subject: [PATCH 2958/3781] vaapipostproc: Allow running without VPP support We returned FALSE from ::start() if VPP support is not available, but it is only really needed for complex filters and during transform we check for that. For simple deinterlacing it is not needed. --- gst/vaapi/gstvaapipostproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 427193c5f4..e828741415 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -306,8 +306,8 @@ gst_vaapipostproc_start (GstBaseTransform * trans) ds_reset (&postproc->deinterlace_state); if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (postproc))) return FALSE; - if (!gst_vaapipostproc_ensure_filter (postproc)) - return FALSE; + gst_vaapipostproc_ensure_filter (postproc); + return TRUE; } From 8a0e22a5bb163cdc33244dcf7b98a35583bfb7e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 3 Oct 2017 13:06:33 +0200 Subject: [PATCH 2959/3781] vaapi: Also register vaapipostproc without VPP support It can still do simple deinterlacing then. --- gst/vaapi/gstvaapi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index f8414a91bd..d7a3519c1e 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -223,10 +223,10 @@ plugin_init (GstPlugin * plugin) g_array_unref (decoders); } - if (gst_vaapi_display_has_video_processing (display)) { - gst_element_register (plugin, "vaapipostproc", - GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); + gst_element_register (plugin, "vaapipostproc", + GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); + if (gst_vaapi_display_has_video_processing (display)) { gst_element_register (plugin, "vaapidecodebin", GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); } From dcf135e2a5ddbb2322a3cfb7b6ffd2921c408b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Sep 2017 16:12:23 +0200 Subject: [PATCH 2960/3781] libs: display: remove parent member Parent was a crumb left from display cache. https://bugzilla.gnome.org/show_bug.cgi?id=782212 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 15 +++------------ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 1 - 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 1d34434abc..d8c2c58b5e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -813,8 +813,7 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) } if (priv->display) { - if (!priv->parent) - vaTerminate (priv->display); + vaTerminate (priv->display); priv->display = NULL; } @@ -829,8 +828,6 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) g_free (priv->vendor_string); priv->vendor_string = NULL; - - gst_vaapi_display_replace_internal (&priv->parent, NULL); } static gboolean @@ -885,10 +882,8 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, if (!priv->display) return FALSE; - if (!priv->parent) { - if (!vaapi_initialize (priv->display)) - return FALSE; - } + if (!vaapi_initialize (priv->display)) + return FALSE; GST_INFO_OBJECT (display, "new display addr=%p", display); g_free (priv->display_name); @@ -908,8 +903,6 @@ gst_vaapi_display_lock_default (GstVaapiDisplay * display) { GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - if (priv->parent) - priv = GST_VAAPI_DISPLAY_GET_PRIVATE (priv->parent); g_rec_mutex_lock (&priv->mutex); } @@ -918,8 +911,6 @@ gst_vaapi_display_unlock_default (GstVaapiDisplay * display) { GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - if (priv->parent) - priv = GST_VAAPI_DISPLAY_GET_PRIVATE (priv->parent); g_rec_mutex_unlock (&priv->mutex); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index c4ef59fed7..4d8e01ea72 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -109,7 +109,6 @@ typedef enum _GstVaapiDisplayInitType GstVaapiDisplayInitType; struct _GstVaapiDisplayPrivate { - GstVaapiDisplay *parent; GRecMutex mutex; GstVaapiDisplayType display_type; gchar *display_name; From 4e9de44ba24e1da27278b2d43a4887403dd0e17d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Sep 2017 17:35:01 +0200 Subject: [PATCH 2961/3781] libs: display: remove display_type member It is not used any more since GstVaapiDisplay was ported as a GstObject-based. This information is part of the class information. https://bugzilla.gnome.org/show_bug.cgi?id=782212 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 8 ++------ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 3 +-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index d8c2c58b5e..ba5e550138 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -839,7 +839,7 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, GST_VAAPI_DISPLAY_GET_CLASS (display); GstVaapiDisplayInfo info = { .display = display, - .display_type = priv->display_type, + .display_type = klass->display_type, }; switch (init_type) { @@ -870,7 +870,6 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, if (!klass->get_display || !klass->get_display (display, &info)) return FALSE; priv->display = info.va_display; - priv->display_type = info.display_type; priv->native_display = info.native_display; if (klass->get_size) klass->get_size (display, &priv->width, &priv->height); @@ -921,7 +920,6 @@ gst_vaapi_display_init (GstVaapiDisplay * display) gst_vaapi_display_get_instance_private (display); display->priv = priv; - priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; priv->par_n = 1; priv->par_d = 1; @@ -1824,9 +1822,7 @@ get_render_mode_VADisplayAttribDirectSurface (GstVaapiDisplay * display, static gboolean get_render_mode_default (GstVaapiDisplay * display, GstVaapiRenderMode * pmode) { - GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - - switch (priv->display_type) { + switch (GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display)) { #if USE_WAYLAND case GST_VAAPI_DISPLAY_TYPE_WAYLAND: /* wl_buffer mapped from VA surface through vaGetSurfaceBufferWl() */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 4d8e01ea72..20b2bce8f8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -94,7 +94,7 @@ typedef enum _GstVaapiDisplayInitType GstVaapiDisplayInitType; */ #undef GST_VAAPI_DISPLAY_VADISPLAY_TYPE #define GST_VAAPI_DISPLAY_VADISPLAY_TYPE(display) \ - (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display_type) + (GST_VAAPI_DISPLAY_GET_CLASS (display)->display_type) /** * GST_VAAPI_DISPLAY_HAS_VPP: @@ -110,7 +110,6 @@ typedef enum _GstVaapiDisplayInitType GstVaapiDisplayInitType; struct _GstVaapiDisplayPrivate { GRecMutex mutex; - GstVaapiDisplayType display_type; gchar *display_name; VADisplay display; gpointer native_display; From 494ac4e3a86cfc1ef8a0a2c455701fa6b1ca9992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Sep 2017 17:45:00 +0200 Subject: [PATCH 2962/3781] libs: display: remove display_type from display info Since it's no required to pass the display type in the display info, the structure member is removed. https://bugzilla.gnome.org/show_bug.cgi?id=782212 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 3 --- gst-libs/gst/vaapi/gstvaapidisplay.h | 1 - gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 1 - gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 1 - gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 2 -- 5 files changed, 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index ba5e550138..30abf91846 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -839,7 +839,6 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, GST_VAAPI_DISPLAY_GET_CLASS (display); GstVaapiDisplayInfo info = { .display = display, - .display_type = klass->display_type, }; switch (init_type) { @@ -847,7 +846,6 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, GstVaapiDisplayInfo *p_info = data; info.va_display = p_info->va_display; - info.display_type = p_info->display_type; priv->display = p_info->va_display; priv->use_foreign_display = TRUE; @@ -1166,7 +1164,6 @@ gst_vaapi_display_new_with_display (VADisplay va_display) { GstVaapiDisplayInfo info = { .va_display = va_display, - .display_type = GST_VAAPI_DISPLAY_TYPE_ANY, }; return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY, NULL), diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 8eba5fb058..01a2859892 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -127,7 +127,6 @@ gst_vaapi_display_type_is_compatible (GstVaapiDisplayType type1, struct _GstVaapiDisplayInfo { GstVaapiDisplay *display; - GstVaapiDisplayType display_type; gchar *display_name; VADisplay va_display; gpointer native_display; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index a129cce758..95becdb873 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -311,7 +311,6 @@ gst_vaapi_display_drm_get_display_info (GstVaapiDisplay * display, info->va_display = vaGetDisplayDRM (priv->drm_device); if (!info->va_display) return FALSE; - info->display_type = GST_VAAPI_DISPLAY_TYPE_DRM; } return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 951e0307be..13d40a2e6d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -239,7 +239,6 @@ gst_vaapi_display_wayland_get_display_info (GstVaapiDisplay * display, info->va_display = vaGetDisplayWl (priv->wl_display); if (!info->va_display) return FALSE; - info->display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; } return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index ee36009536..7131fe8635 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -225,7 +225,6 @@ gst_vaapi_display_x11_get_display_info (GstVaapiDisplay * display, info->va_display = vaGetDisplay (priv->x11_display); if (!info->va_display) return FALSE; - info->display_type = GST_VAAPI_DISPLAY_TYPE_X11; } return TRUE; } @@ -380,7 +379,6 @@ gst_vaapi_display_x11_new_with_va_display (VADisplay va_display, GstVaapiDisplayInfo info = { .va_display = va_display, .native_display = x11_display, - .display_type = GST_VAAPI_DISPLAY_TYPE_X11, }; g_return_val_if_fail (x11_display, NULL); From 66e4593c33a55933d9736fc9989e3cdb0a8a628b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 28 Sep 2017 18:58:17 +0200 Subject: [PATCH 2963/3781] libs: display: egl: avoid two vaDisplay instantiates GstVaapiDisplayEGL is a wrapper of another GstVaapiDisplay, either X11 or Wayland. Nonetheless it created another vaDisplay for it, instead of using the wrapped one. This patch enables the reuse of the wrapped vaDisplay avoiding instantiating two. https://bugzilla.gnome.org/show_bug.cgi?id=782212 --- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index 7d3d27ee34..fd5814eb78 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -189,6 +189,8 @@ gst_vaapi_display_egl_get_display_info (GstVaapiDisplay * 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; @@ -279,6 +281,11 @@ gst_vaapi_display_egl_finalize (GObject * 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; + G_OBJECT_CLASS (gst_vaapi_display_egl_parent_class)->finalize (object); } From 63a76c9dd0da2ec28a64e21fbf018c13f5b713a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Sep 2017 15:07:47 +0200 Subject: [PATCH 2964/3781] libs: display: delay getting screen resolution Instead of extracting the screen resolution at GstVaapiDisplay creation, this patch delay it until the screen size is requested for first time. https://bugzilla.gnome.org/show_bug.cgi?id=782212 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 32 +++++++++++++++++++---- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 1 + 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 30abf91846..0e80f9ca8e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -782,6 +782,25 @@ gst_vaapi_display_calculate_pixel_aspect_ratio (GstVaapiDisplay * display) priv->par_d = par[index][windex ^ 1]; } +static void +gst_vaapi_display_ensure_screen_resolution (GstVaapiDisplay * display) +{ + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + const GstVaapiDisplayClass *const klass = + GST_VAAPI_DISPLAY_GET_CLASS (display); + + if (priv->got_scrres) + return; + + if (klass->get_size) + klass->get_size (display, &priv->width, &priv->height); + if (klass->get_size_mm) + klass->get_size_mm (display, &priv->width_mm, &priv->height_mm); + + gst_vaapi_display_calculate_pixel_aspect_ratio (display); + priv->got_scrres = TRUE; +} + static void gst_vaapi_display_destroy (GstVaapiDisplay * display) { @@ -869,11 +888,6 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, return FALSE; priv->display = info.va_display; priv->native_display = info.native_display; - if (klass->get_size) - klass->get_size (display, &priv->width, &priv->height); - if (klass->get_size_mm) - klass->get_size_mm (display, &priv->width_mm, &priv->height_mm); - gst_vaapi_display_calculate_pixel_aspect_ratio (display); break; } if (!priv->display) @@ -1379,6 +1393,8 @@ gst_vaapi_display_get_width (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, 0); + gst_vaapi_display_ensure_screen_resolution (display); + return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->width; } @@ -1395,6 +1411,8 @@ gst_vaapi_display_get_height (GstVaapiDisplay * display) { g_return_val_if_fail (display != NULL, 0); + gst_vaapi_display_ensure_screen_resolution (display); + return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->height; } @@ -1412,6 +1430,8 @@ gst_vaapi_display_get_size (GstVaapiDisplay * display, guint * pwidth, { g_return_if_fail (GST_VAAPI_DISPLAY (display)); + gst_vaapi_display_ensure_screen_resolution (display); + if (pwidth) *pwidth = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->width; @@ -1433,6 +1453,8 @@ gst_vaapi_display_get_pixel_aspect_ratio (GstVaapiDisplay * display, { g_return_if_fail (display != NULL); + gst_vaapi_display_ensure_screen_resolution (display); + if (par_n) *par_n = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->par_n; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 20b2bce8f8..7f96208f0c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -128,6 +128,7 @@ struct _GstVaapiDisplayPrivate guint use_foreign_display:1; guint has_vpp:1; guint has_profiles:1; + guint got_scrres:1; }; /** From 68aca503ce6f1fbff4066df7c00cf3d6aef16e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Sep 2017 20:05:22 +0200 Subject: [PATCH 2965/3781] plugins: try to create test display in order When creating the test display for querying capabilites, it try in certain order: DRM, Wayland and finally X11. GLX nor EGL are tried since they are either composited with X11 or Wayland. The reason for this is to reduce the posibility of failure that could blacklist the plugin. https://bugzilla.gnome.org/show_bug.cgi?id=782212 --- gst/vaapi/gstvaapipluginutil.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index d5114b5d99..9ec96a70f3 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -790,12 +790,32 @@ gst_video_info_force_nv12_if_encoded (GstVideoInfo * vinfo) * supported features. * * Returns: a new #GstVaapiDisplay instances. Free with - * gst_vaapi_display_unref () after use. + * gst_vaapi_display_unref () after use. Or %NULL if no VA display is + * available. **/ GstVaapiDisplay * gst_vaapi_create_test_display (void) { - return gst_vaapi_create_display (GST_VAAPI_DISPLAY_TYPE_ANY, NULL); + guint i; + GstVaapiDisplay *display = NULL; + const GstVaapiDisplayType test_display_map[] = { +#if USE_DRM + GST_VAAPI_DISPLAY_TYPE_DRM, +#endif +#if USE_WAYLAND + GST_VAAPI_DISPLAY_TYPE_WAYLAND, +#endif +#if USE_X11 + GST_VAAPI_DISPLAY_TYPE_X11, +#endif + }; + + for (i = 0; G_N_ELEMENTS (test_display_map); i++) { + display = gst_vaapi_create_display (test_display_map[i], NULL); + if (display) + break; + } + return display; } /** From c7d712a93247d07c32591d2006cb8f1185a0b1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 2 Oct 2017 18:53:21 +0200 Subject: [PATCH 2966/3781] libs: utils: log warn if display fail gstreamer-vaapi initializes the display by trial-and-error, thus logging an error message if the display initialisation fails the user may be weary of the error message in the screen, if using VA-API 1.0 This commit set the VA error log handler to GStreamer warning level while calling vaInitialize() and set it to error after that. https://bugzilla.gnome.org/show_bug.cgi?id=783169 --- gst-libs/gst/vaapi/gstvaapiutils.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 5d7ae62e61..493cc098e8 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -65,6 +65,18 @@ gst_vaapi_err (void *data, const char *message) GST_ERROR ("%s", msg); g_free (msg); } + +static void +gst_vaapi_warning (void *data, const char *message) +{ + gchar *msg; + + msg = strip_msg (message); + if (!msg) + return; + GST_WARNING ("%s", msg); + g_free (msg); +} #endif static void @@ -91,13 +103,18 @@ vaapi_initialize (VADisplay dpy) VAStatus status; #if VA_CHECK_VERSION (1,0,0) - vaSetErrorCallback (dpy, gst_vaapi_err, NULL); + vaSetErrorCallback (dpy, gst_vaapi_warning, NULL); vaSetInfoCallback (dpy, gst_vaapi_log, NULL); #elif VA_CHECK_VERSION (0,40,0) vaSetInfoCallback (gst_vaapi_log); #endif status = vaInitialize (dpy, &major_version, &minor_version); + +#if VA_CHECK_VERSION (1,0,0) + vaSetErrorCallback (dpy, gst_vaapi_err, NULL); +#endif + if (!vaapi_check_status (status, "vaInitialize()")) return FALSE; From a6e191e09c7ce407c9e2280ba244ae9faa4637c9 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 16 Oct 2017 11:57:16 +0200 Subject: [PATCH 2967/3781] Avoid infinite loop when vaapi_create_display fails Which might be the case when using, for example, xvfb. --- gst/vaapi/gstvaapipluginutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 9ec96a70f3..ed2f32494e 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -810,7 +810,7 @@ gst_vaapi_create_test_display (void) #endif }; - for (i = 0; G_N_ELEMENTS (test_display_map); i++) { + for (i = 0; i < G_N_ELEMENTS (test_display_map); i++) { display = gst_vaapi_create_display (test_display_map[i], NULL); if (display) break; From a8f230959565cf1172792117a54abfd3ae2166c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 10 Oct 2017 11:35:24 +0300 Subject: [PATCH 2968/3781] vaapidecodebin: Register element if no VPP support is available too VPP support is only needed for advanced deinterlacing, which is not enabled by default either. Error out if it is selected but VPP is not supported, and otherwise just work without VPP support. https://bugzilla.gnome.org/show_bug.cgi?id=788758 --- gst/vaapi/gstvaapi.c | 11 +++++++---- gst/vaapi/gstvaapi.h | 30 ++++++++++++++++++++++++++++++ gst/vaapi/gstvaapidecodebin.c | 13 +++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 gst/vaapi/gstvaapi.h diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index d7a3519c1e..7939f9aaf5 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -54,6 +54,8 @@ #endif +gboolean _gst_vaapi_has_video_processing = FALSE; + #define PLUGIN_NAME "vaapi" #define PLUGIN_DESC "VA-API based elements" #define PLUGIN_LICENSE "LGPL" @@ -217,6 +219,9 @@ plugin_init (GstPlugin * plugin) if (!gst_vaapi_driver_is_whitelisted (display)) goto unsupported_driver; + _gst_vaapi_has_video_processing = + gst_vaapi_display_has_video_processing (display); + decoders = display_get_decoder_codecs (display); if (decoders) { gst_vaapidecode_register (plugin, decoders); @@ -226,10 +231,8 @@ plugin_init (GstPlugin * plugin) gst_element_register (plugin, "vaapipostproc", GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); - if (gst_vaapi_display_has_video_processing (display)) { - gst_element_register (plugin, "vaapidecodebin", - GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); - } + gst_element_register (plugin, "vaapidecodebin", + GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); gst_element_register (plugin, "vaapisink", GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); diff --git a/gst/vaapi/gstvaapi.h b/gst/vaapi/gstvaapi.h new file mode 100644 index 0000000000..f5859508f1 --- /dev/null +++ b/gst/vaapi/gstvaapi.h @@ -0,0 +1,30 @@ +/* + * gstvaapi.h - VA-API element registration + * + * Copyright (C) 2011-2013 Intel Corporation + * Author: Gwenole Beauchesne + * Copyright (C) 2011 Collabora Ltd. + * Author: Nicolas Dufresne + * + * 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_H__ +#define __GST_VAAPI_H__ + +G_GNUC_INTERNAL extern gboolean _gst_vaapi_has_video_processing; + +#endif /* __GST_VAAPI_H__ */ diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 2522b0af1c..34a6338d3f 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -50,6 +50,7 @@ #include "gstvaapidecodebin.h" #include "gstvaapivideocontext.h" #include "gstvaapipluginbase.h" +#include "gstvaapi.h" #define GST_PLUGIN_NAME "vaapidecodebin" #define GST_PLUGIN_DESC "A VA-API based bin with a decoder and a postprocessor" @@ -296,6 +297,7 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) GstCaps *caps; GstPad *queue_srcpad, *bin_srcpad, *capsfilter_sinkpad, *vpp_srcpad; gboolean res; + gboolean has_vpp; g_object_set (G_OBJECT (vaapidecbin->queue), "max-size-bytes", vaapidecbin->max_size_bytes, @@ -305,6 +307,17 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) if (vaapidecbin->disable_vpp || vaapidecbin->configured) return TRUE; + has_vpp = _gst_vaapi_has_video_processing; + + if (!has_vpp && (vaapidecbin->deinterlace_method == + GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE + || vaapidecbin->deinterlace_method == + GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED)) { + GST_ERROR_OBJECT (vaapidecbin, + "Don't have VPP support but advanced deinterlacing selected"); + return FALSE; + } + GST_INFO_OBJECT (vaapidecbin, "enabling VPP"); /* capsfilter to avoid negotiation with vaapidecode */ From acfabb356166b3a2be3bf5427951c19c615a9fe2 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 15 Sep 2017 15:38:18 +0900 Subject: [PATCH 2969/3781] libs: encoder: allow to set bitrate on runtime In case of streaming, controlling bitrate dynamically for encoder might be important to manage quality of the streaming. This patch is to support such a scenario. https://bugzilla.gnome.org/show_bug.cgi?id=786321 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 8befeeed70..46d40cf7ef 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1122,18 +1122,14 @@ gst_vaapi_encoder_set_bitrate (GstVaapiEncoder * encoder, guint bitrate) { g_return_val_if_fail (encoder != NULL, 0); - if (encoder->bitrate != bitrate && encoder->num_codedbuf_queued > 0) - goto error_operation_failed; + if (encoder->bitrate != bitrate && encoder->num_codedbuf_queued > 0) { + GST_INFO ("Bitrate is changed to %d on runtime", bitrate); + encoder->bitrate = bitrate; + return gst_vaapi_encoder_reconfigure_internal (encoder); + } encoder->bitrate = bitrate; return GST_VAAPI_ENCODER_STATUS_SUCCESS; - - /* ERRORS */ -error_operation_failed: - { - GST_ERROR ("could not change bitrate value after encoding started"); - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; - } } /** From 8ef3bc3cc2edbf20ea45767da81a5cf48e04c92c Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 20 Oct 2017 12:37:15 +0200 Subject: [PATCH 2970/3781] vaapiencode: allow to set property on runtime Tis patch, allows some properties that we want to be set on runtime. (eg. bitrate) Note that all properties are under control by num_codedbuf_queued. https://bugzilla.gnome.org/show_bug.cgi?id=786321 --- gst/vaapi/gstvaapiencode.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 0aaa4d1008..5bc67c55f2 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -175,11 +175,18 @@ gst_vaapiencode_default_set_property (GstVaapiEncode * encode, guint prop_id, const GValue * value) { PropValue *const prop_value = prop_value_lookup (encode, prop_id); + GstVaapiEncoder *encoder = encode->encoder; if (prop_value) { g_value_copy (value, &prop_value->value); + + if (encoder) + return (gst_vaapi_encoder_set_property (encoder, prop_id, + value) == GST_VAAPI_ENCODER_STATUS_SUCCESS); + return TRUE; } + return FALSE; } From 998e79ced6929c8ed5d7933c346977543348bca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 4 Oct 2017 08:30:51 +0200 Subject: [PATCH 2971/3781] plugins: add gst_vaapi_plugin_base_set_srcpad_can_dmabuf() This patch refactors the code by adding the function vaapi_plugin_base_set_srcpad_can_dmabuf(), it determines if the passed GstGLContext can handle dmabuf-based buffers. The function is exposed publicly since it is intended to be used later at GstVaapiDisplay instantiation. https://bugzilla.gnome.org/show_bug.cgi?id=788503 --- gst/vaapi/gstvaapipluginbase.c | 31 +++++++++++++++++++++++++------ gst/vaapi/gstvaapipluginbase.h | 5 +++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 318e567b68..120879a310 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1182,12 +1182,7 @@ gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, break; #endif case GST_GL_PLATFORM_EGL: -#if VA_CHECK_VERSION (0,36,0) && USE_GST_GL_HELPERS - plugin->srcpad_can_dmabuf = - (!(gst_gl_context_get_gl_api (gl_context) & GST_GL_API_GLES1) - && gst_gl_context_check_feature (gl_context, - "EGL_EXT_image_dma_buf_import")); -#endif + gst_vaapi_plugin_base_set_srcpad_can_dmabuf (plugin, object); #if USE_EGL display_type = GST_VAAPI_DISPLAY_TYPE_EGL; break; @@ -1337,3 +1332,27 @@ gst_vaapi_plugin_base_get_allowed_raw_caps (GstVaapiPluginBase * plugin) return NULL; return plugin->allowed_raw_caps; } + +/** + * gst_vaapi_plugin_base_set_srcpad_can_dmabuf: + * @plugin: a #GstVaapiPluginBase + * @object: the GL context from gst-gl + * + * This function will determine if @object supports dmabuf + * importing. + * + * Please note that the context @object should come from downstream. + **/ +void +gst_vaapi_plugin_base_set_srcpad_can_dmabuf (GstVaapiPluginBase * plugin, + GstObject * object) +{ +#if VA_CHECK_VERSION (0,36,0) && USE_EGL && USE_GST_GL_HELPERS + GstGLContext *const gl_context = GST_GL_CONTEXT (object); + + plugin->srcpad_can_dmabuf = + (!(gst_gl_context_get_gl_api (gl_context) & GST_GL_API_GLES1) + && gst_gl_context_check_feature (gl_context, + "EGL_EXT_image_dma_buf_import")); +#endif +} diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 276e130ae3..f08548260f 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -247,6 +247,11 @@ G_GNUC_INTERNAL GstCaps * gst_vaapi_plugin_base_get_allowed_raw_caps (GstVaapiPluginBase * plugin); +G_GNUC_INTERNAL +void +gst_vaapi_plugin_base_set_srcpad_can_dmabuf (GstVaapiPluginBase * plugin, + GstObject * object); + G_END_DECLS #endif /* GST_VAAPI_PLUGIN_BASE_H */ From 6b2b1294f8453e0acd37a510fd0326b7d80f7c78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 4 Oct 2017 11:50:25 +0200 Subject: [PATCH 2972/3781] vaapivideocontext: return the direction of gl context In function gst_vaapi_find_gl_context() add a direction parameter to return back the direction where the GstGL context was found. This is going to be useful when checking if downstream can import dmabuf-based buffers. https://bugzilla.gnome.org/show_bug.cgi?id=788503 --- gst/vaapi/gstvaapipluginutil.c | 3 ++- gst/vaapi/gstvaapivideocontext.c | 7 ++++++- gst/vaapi/gstvaapivideocontext.h | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ed2f32494e..1fbd611313 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -248,6 +248,7 @@ gst_vaapi_find_gl_context (GstElement * element) { GstObject *gl_context; GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); + GstPadDirection direction = GST_PAD_UNKNOWN; /* if the element is vaapisink or any vaapi encoder it doesn't need * to know a GstGLContext in order to create an appropriate @@ -257,7 +258,7 @@ gst_vaapi_find_gl_context (GstElement * element) return; gl_context = NULL; - if (!gst_vaapi_find_gl_local_context (element, &gl_context)) + if (!gst_vaapi_find_gl_local_context (element, &gl_context, &direction)) gl_context = gst_vaapi_plugin_base_create_gl_context (plugin); if (gl_context) { diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 214840bcd5..3f6a45d757 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -263,16 +263,18 @@ gst_vaapi_video_context_propagate (GstElement * element, gboolean gst_vaapi_find_gl_local_context (GstElement * element, - GstObject ** gl_context_ptr) + GstObject ** gl_context_ptr, GstPadDirection * direction_ptr) { #if USE_GST_GL_HELPERS GstQuery *query; GstContext *context; const GstStructure *s; GstObject *gl_context; + GstPadDirection direction; g_return_val_if_fail (gl_context_ptr, FALSE); + direction = GST_PAD_UNKNOWN; gl_context = NULL; query = gst_query_new_context ("gst.gl.local_context"); if (_gst_context_run_query (element, query, GST_PAD_SRC)) { @@ -280,6 +282,7 @@ gst_vaapi_find_gl_local_context (GstElement * element, if (context) { s = gst_context_get_structure (context); gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &gl_context, NULL); + direction = GST_PAD_SRC; } } if (!gl_context && _gst_context_run_query (element, query, GST_PAD_SINK)) { @@ -287,11 +290,13 @@ gst_vaapi_find_gl_local_context (GstElement * element, if (context) { s = gst_context_get_structure (context); gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &gl_context, NULL); + direction = GST_PAD_SINK; } } gst_query_unref (query); if (gl_context) { *gl_context_ptr = gl_context; + *direction_ptr = direction; return TRUE; } #endif diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index 0aaeb7e80b..3d87754a5e 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -60,6 +60,6 @@ gst_vaapi_video_context_propagate (GstElement * element, G_GNUC_INTERNAL gboolean gst_vaapi_find_gl_local_context (GstElement * element, - GstObject ** gl_context_ptr); + GstObject ** gl_context_ptr, GstPadDirection * direction); #endif /* GST_VAAPI_VIDEO_CONTEXT_H */ From 1135e8bd31d16b868a5400b9b40d7220bf8b443f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 4 Oct 2017 11:52:32 +0200 Subject: [PATCH 2973/3781] vaapivideocontext: add inline documentation Document function gst_vaapi_find_gl_local_context(). https://bugzilla.gnome.org/show_bug.cgi?id=788503 --- gst/vaapi/gstvaapivideocontext.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 3f6a45d757..e41e7dfc6b 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -261,6 +261,18 @@ gst_vaapi_video_context_propagate (GstElement * element, GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "No bus attached"); } +/** + * gst_vaapi_find_gl_local_context: + * @element: the #GstElement where the search begins + * @gl_context_ptr: the pointer where the GstGL context is going to be + * stored + * @direction_ptr: the pointer of the #GstPadDirection where the GstGL + * context was found + * + * Query the pipeline, downstream and upstream for a GstGL context + * + * Returns: %TRUE if found; otherwise %FALSE + **/ gboolean gst_vaapi_find_gl_local_context (GstElement * element, GstObject ** gl_context_ptr, GstPadDirection * direction_ptr) From 0a36a707ba1161cb5adfe7f364ca95d3a1ad61a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 4 Oct 2017 11:54:31 +0200 Subject: [PATCH 2974/3781] plugins: only dmabuf on srcpad if downstream Set if source pad can handle dmabuf only if the GstGL context comes from downstream. It is possible to know that at two moments: 1\ In the case of GstGLTextureUpload caps feature is negotiated and downstream pool reports back gst.gl.GstGLContext. 2\ When GstGLContext is found as GstContext from dowstream. https://bugzilla.gnome.org/show_bug.cgi?id=788503 --- gst/vaapi/gstvaapipluginbase.c | 2 +- gst/vaapi/gstvaapipluginutil.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 120879a310..36f8af983c 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -931,6 +931,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, if (gst_structure_get (params, "gst.gl.GstGLContext", GST_TYPE_GL_CONTEXT, &gl_context, NULL) && gl_context) { gst_vaapi_plugin_base_set_gl_context (plugin, gl_context); + gst_vaapi_plugin_base_set_srcpad_can_dmabuf (plugin, gl_context); gst_object_unref (gl_context); } } @@ -1182,7 +1183,6 @@ gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin, break; #endif case GST_GL_PLATFORM_EGL: - gst_vaapi_plugin_base_set_srcpad_can_dmabuf (plugin, object); #if USE_EGL display_type = GST_VAAPI_DISPLAY_TYPE_EGL; break; diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 1fbd611313..9e7330590e 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -263,6 +263,8 @@ gst_vaapi_find_gl_context (GstElement * element) if (gl_context) { gst_vaapi_plugin_base_set_gl_context (plugin, gl_context); + if (direction == GST_PAD_SRC) + gst_vaapi_plugin_base_set_srcpad_can_dmabuf (plugin, gl_context); gst_object_unref (gl_context); } } From 72362e10632fe46adafa92290b2480511eaecb29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 31 Oct 2017 13:10:50 +0100 Subject: [PATCH 2975/3781] plugins: direct rendering on memory:VASurface As buffers negotiated with memory:VASurface caps feature can also be mapped, they can also be configured to use VA derived images, in other words "direct rendering". Also, because of the changes in dmabuf allocator as default allocator, the code for configuring the direct rendering was not clear. This patch cleans up the code and enables direct rendering when the environment variable GST_VAAPI_ENABLE_DIRECT_RENDERING is defined, even then the memory:VASurface cap feature is negotiated. https://bugzilla.gnome.org/show_bug.cgi?id=786054 --- gst/vaapi/gstvaapipluginbase.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 36f8af983c..6194c3057b 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -600,8 +600,6 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, { gboolean different_caps; const GstVideoInfo *image_info; - GstVaapiImageUsageFlags usage_flag = - GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; if (!reset_allocator (plugin->srcpad_allocator, vinfo)) goto valid_allocator; @@ -610,10 +608,6 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, if (caps && gst_caps_is_video_raw (caps)) { GstAllocator *allocator = create_dmabuf_srcpad_allocator (plugin, vinfo, !plugin->srcpad_can_dmabuf); - if (!allocator && plugin->enable_direct_rendering) { - usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; - GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); - } plugin->srcpad_allocator = allocator; } else if (caps && gst_vaapi_caps_feature_contains (caps, GST_VAAPI_CAPS_FEATURE_DMABUF)) { @@ -624,6 +618,14 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, } if (!plugin->srcpad_allocator) { + GstVaapiImageUsageFlags usage_flag = + GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; + + if (plugin->enable_direct_rendering) { + usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; + GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); + } + plugin->srcpad_allocator = gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag); } From ea503ed08538f654049748630e7e3855d842c9f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 4 Oct 2017 13:51:23 +0200 Subject: [PATCH 2976/3781] libs: surface: egl: error message if no extension Instead of silently fail to export the image if there is not available the EGL_MESA_drm_image, log an error message. Also a code refactoring was done. https://bugzilla.gnome.org/show_bug.cgi?id=773453 --- gst-libs/gst/vaapi/gstvaapisurface_egl.c | 32 +++++++++++++++--------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_egl.c b/gst-libs/gst/vaapi/gstvaapisurface_egl.c index 8c13851655..8bc42e536e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_egl.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_egl.c @@ -55,22 +55,30 @@ do_create_surface_with_egl_image_unlocked (GstVaapiDisplayEGL * display, memset (offset, 0, sizeof (offset)); memset (stride, 0, sizeof (stride)); - if (vtable->has_EGL_MESA_drm_image) { - /* EGL_MESA_drm_image extension */ - if (!vtable->eglExportDRMImageMESA (ctx->display->base.handle.p, image, - &name, NULL, &stride[0])) - goto error_export_image_gem_buf; + if (!vtable->has_EGL_MESA_drm_image) + goto error_mission_extension; - size = height * stride[0]; - return gst_vaapi_surface_new_with_gem_buf_handle (base_display, name, size, - format, width, height, offset, stride); - } - return NULL; + /* EGL_MESA_drm_image extension */ + if (!vtable->eglExportDRMImageMESA (ctx->display->base.handle.p, image, + &name, NULL, &stride[0])) + goto error_export_image_gem_buf; + + size = height * stride[0]; + return gst_vaapi_surface_new_with_gem_buf_handle (base_display, name, size, + format, width, height, offset, stride); /* ERRORS */ error_export_image_gem_buf: - GST_ERROR ("failed to export EGL image to GEM buffer"); - return NULL; + { + GST_ERROR ("failed to export EGL image to GEM buffer"); + return NULL; + } + +error_mission_extension: + { + GST_ERROR ("missing EGL_MESA_drm_image extension"); + return NULL; + } } static void From 0840c08cf10d4a101859a625acf2351f28672553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 5 Oct 2017 19:25:08 +0200 Subject: [PATCH 2977/3781] libs: texture: egl: code style https://bugzilla.gnome.org/show_bug.cgi?id=773453 --- gst-libs/gst/vaapi/gstvaapitexture_egl.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture_egl.c b/gst-libs/gst/vaapi/gstvaapitexture_egl.c index 260ffaa24f..1a5897dda7 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_egl.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_egl.c @@ -120,14 +120,20 @@ create_objects (GstVaapiTextureEGL * texture, GLuint texture_id) /* ERRORS */ error_create_image: - GST_ERROR ("failed to create EGL image from 2D texture %u", texture_id); - return FALSE; + { + GST_ERROR ("failed to create EGL image from 2D texture %u", texture_id); + return FALSE; + } error_create_surface: - GST_ERROR ("failed to create VA surface from 2D texture %u", texture_id); - return FALSE; + { + GST_ERROR ("failed to create VA surface from 2D texture %u", texture_id); + return FALSE; + } error_create_filter: - GST_ERROR ("failed to create VPP filter for color conversion"); - return FALSE; + { + GST_ERROR ("failed to create VPP filter for color conversion"); + return FALSE; + } } static gboolean From ac31160dfca62398ce8a9399ed182573e7362b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 10 Oct 2017 14:01:59 +0200 Subject: [PATCH 2978/3781] libs: display: egl: free leaked memory The EGL VAAPI display forgot to release the egl display, context and proxied VAAPI display. https://bugzilla.gnome.org/show_bug.cgi?id=773453 --- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index fd5814eb78..883257aa59 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -286,6 +286,11 @@ gst_vaapi_display_egl_finalize (GObject * object) * 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); } From 4866e4c452d28794c216a1730f923dfa9eac8616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 10 Oct 2017 19:57:45 +0200 Subject: [PATCH 2979/3781] plugins: fix memory leak when GL context is created When the GL display and context are created inside an VAAPI element the created GL context is leaked. https://bugzilla.gnome.org/show_bug.cgi?id=773453 --- gst/vaapi/gstvaapipluginbase.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 6194c3057b..1f81ac102a 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1240,6 +1240,8 @@ gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin) } while (!gst_gl_display_add_context (gl_display, gl_context)); GST_OBJECT_UNLOCK (gl_display); + gst_object_replace (&plugin->gl_context, (GstObject *) gl_context); + return GST_OBJECT_CAST (gl_context); /* ERRORS */ From fc1c41551534dcb2ccd228fe006d37a358faceda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 10 Oct 2017 17:14:15 +0200 Subject: [PATCH 2980/3781] plugins: set GL objects if context is handled Only set the GL display and GL other context if they are extracted correctly from the gstreamer's context. https://bugzilla.gnome.org/show_bug.cgi?id=773453 --- gst/vaapi/gstvaapipluginbase.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 1f81ac102a..8318fa3790 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -80,9 +80,16 @@ gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, plugin_set_display (plugin, display); #if USE_GST_GL_HELPERS - gst_gl_handle_set_context (GST_ELEMENT_CAST (plugin), context, - (GstGLDisplay **) & plugin->gl_display, - (GstGLContext **) & plugin->gl_other_context); + { + GstGLDisplay *gl_display = NULL; + GstGLContext *gl_other_context = NULL; + GstElement *el = GST_ELEMENT_CAST (plugin); + + if (gst_gl_handle_set_context (el, context, &gl_display, &gl_other_context)) { + plugin->gl_display = (GstObject *) gl_display; + plugin->gl_other_context = (GstObject *) gl_other_context; + } + } #endif } From 3d56306c37e29b2b5094d846cb00d255e54895ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 10 Oct 2017 19:13:35 +0200 Subject: [PATCH 2981/3781] plugins: set GL objects if ensured Only set the GL display and GL other context if they are ensured. https://bugzilla.gnome.org/show_bug.cgi?id=773453 --- gst/vaapi/gstvaapipluginbase.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 8318fa3790..dbdf505c8a 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1219,18 +1219,14 @@ GstObject * gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin) { #if USE_GST_GL_HELPERS - GstGLContext *gl_other_context, *gl_context = NULL; - GstGLDisplay *gl_display; + GstGLContext *gl_other_context = NULL, *gl_context = NULL; + GstGLDisplay *gl_display = NULL; - if (!gst_gl_ensure_element_data (plugin, - (GstGLDisplay **) & plugin->gl_display, - (GstGLContext **) & plugin->gl_other_context)) + if (!gst_gl_ensure_element_data (plugin, &gl_display, &gl_other_context)) goto no_valid_gl_display; - gl_display = (GstGLDisplay *) plugin->gl_display; if (gst_gl_display_get_handle_type (gl_display) == GST_GL_DISPLAY_TYPE_ANY) goto no_valid_gl_display; - gl_other_context = (GstGLContext *) plugin->gl_other_context; GST_INFO_OBJECT (plugin, "creating a new GstGL context"); @@ -1247,6 +1243,8 @@ gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin) } while (!gst_gl_display_add_context (gl_display, gl_context)); GST_OBJECT_UNLOCK (gl_display); + plugin->gl_display = (GstObject *) gl_display; + plugin->gl_other_context = (GstObject *) gl_context; gst_object_replace (&plugin->gl_context, (GstObject *) gl_context); return GST_OBJECT_CAST (gl_context); @@ -1254,8 +1252,8 @@ gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin) /* ERRORS */ no_valid_gl_display: { - gst_object_replace (&plugin->gl_display, NULL); - gst_object_replace (&plugin->gl_other_context, NULL); + gst_object_replace ((GstObject **) & gl_display, NULL); + gst_object_replace ((GstObject **) & gl_other_context, NULL); return NULL; } #else From 80925377632db90673d436efc0cb83dbfb6d00e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 10 Oct 2017 19:53:04 +0200 Subject: [PATCH 2982/3781] plugins: centralize assignation of GL objects Add plugin_set_gst_gl() where the GstGL objects are assigned. https://bugzilla.gnome.org/show_bug.cgi?id=773453 --- gst/vaapi/gstvaapipluginbase.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index dbdf505c8a..e835f69eee 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -59,6 +59,21 @@ plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) gst_vaapi_display_unref (display); } +#if USE_GST_GL_HELPERS +static void +plugin_set_gst_gl (GstVaapiPluginBase * plugin, GstGLDisplay * gl_display, + GstGLContext * gl_context, GstGLContext * gl_other_context) +{ + gst_object_replace (&plugin->gl_display, NULL); + plugin->gl_display = (GstObject *) gl_display; + + gst_object_replace (&plugin->gl_context, (GstObject *) gl_context); + + gst_object_replace (&plugin->gl_other_context, NULL); + plugin->gl_other_context = (GstObject *) gl_other_context; +} +#endif + /** * gst_vaapi_plugin_base_set_context: * @plugin: a #GstVaapiPluginBase instance @@ -85,10 +100,8 @@ gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, GstGLContext *gl_other_context = NULL; GstElement *el = GST_ELEMENT_CAST (plugin); - if (gst_gl_handle_set_context (el, context, &gl_display, &gl_other_context)) { - plugin->gl_display = (GstObject *) gl_display; - plugin->gl_other_context = (GstObject *) gl_other_context; - } + if (gst_gl_handle_set_context (el, context, &gl_display, &gl_other_context)) + plugin_set_gst_gl (plugin, gl_display, NULL, gl_other_context); } #endif } @@ -1243,9 +1256,7 @@ gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin) } while (!gst_gl_display_add_context (gl_display, gl_context)); GST_OBJECT_UNLOCK (gl_display); - plugin->gl_display = (GstObject *) gl_display; - plugin->gl_other_context = (GstObject *) gl_context; - gst_object_replace (&plugin->gl_context, (GstObject *) gl_context); + plugin_set_gst_gl (plugin, gl_display, gl_context, gl_other_context); return GST_OBJECT_CAST (gl_context); From 98a136ae2a3b2f12fd37164534680ff27494ca0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 9 Oct 2017 16:02:11 +0200 Subject: [PATCH 2983/3781] libs: texture: egl: update EGL display and context It is required to use the context of the calling thread when wrapping a foreign texture. According the documentation of GstVideoGLTextureUploadMeta: "The caller of gst_video_gl_texture_upload_meta_upload() must have OpenGL set up and call this from a thread where it is valid to upload something to an OpenGL texture." This patch updates the EGL display and context in GstVaapiDisplay instance to the one used by te renderer that uploads the texture. Original-patch-by: Daniel van Vugt https://bugzilla.gnome.org/show_bug.cgi?id=773453 --- gst-libs/gst/vaapi/gstvaapitexture_egl.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture_egl.c b/gst-libs/gst/vaapi/gstvaapitexture_egl.c index 1a5897dda7..c50bb85dbe 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_egl.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_egl.c @@ -252,9 +252,28 @@ static gboolean gst_vaapi_texture_egl_create (GstVaapiTextureEGL * texture) { CreateTextureArgs args = { texture }; + GstVaapiDisplayEGL *display = + GST_VAAPI_DISPLAY_EGL (GST_VAAPI_OBJECT_DISPLAY (texture)); + + if (GST_VAAPI_TEXTURE (texture)->is_wrapped) { + if (G_UNLIKELY (display->egl_display->base.handle.p != + eglGetCurrentDisplay ())) { + EglDisplay *current_egl_display = + egl_display_new_wrapped (eglGetCurrentDisplay ()); + if (!current_egl_display) + return FALSE; + + egl_object_replace (&display->egl_display, current_egl_display); + egl_object_unref (current_egl_display); + + if (!gst_vaapi_display_egl_set_gl_context (display, + eglGetCurrentContext ())) + return FALSE; + } + } egl_object_replace (&texture->egl_context, - GST_VAAPI_DISPLAY_EGL_CONTEXT (GST_VAAPI_OBJECT_DISPLAY (texture))); + GST_VAAPI_DISPLAY_EGL_CONTEXT (display)); return egl_context_run (texture->egl_context, (EglContextRunFunc) do_create_texture, &args) && args.success; From 429e8002047e341136f834d44dc2a21b4af41dba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 10 Oct 2017 13:38:21 +0200 Subject: [PATCH 2984/3781] libs: display: egl: add gst_vaapi_display_egl_set_current_display() Adds a new function that changes the internal EGL display to the current one (eglGetCurrentDisplay()) and sets the current context too (eglGetCurrentContext()). This new function is called by gst_vaapi_texture_egl_create() updating the GstVaapiDisplayEGL with the current EGL display. https://bugzilla.gnome.org/show_bug.cgi?id=773453 --- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 23 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay_egl.h | 3 +++ gst-libs/gst/vaapi/gstvaapitexture_egl.c | 16 ++-------------- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index 883257aa59..c4fdbc240a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -414,3 +414,26 @@ gst_vaapi_display_egl_set_gl_context (GstVaapiDisplayEGL * display, 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; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.h b/gst-libs/gst/vaapi/gstvaapidisplay_egl.h index 22a80deb86..ccabf0f83a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.h @@ -51,6 +51,9 @@ 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; diff --git a/gst-libs/gst/vaapi/gstvaapitexture_egl.c b/gst-libs/gst/vaapi/gstvaapitexture_egl.c index c50bb85dbe..efeced4af4 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_egl.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_egl.c @@ -256,20 +256,8 @@ gst_vaapi_texture_egl_create (GstVaapiTextureEGL * texture) GST_VAAPI_DISPLAY_EGL (GST_VAAPI_OBJECT_DISPLAY (texture)); if (GST_VAAPI_TEXTURE (texture)->is_wrapped) { - if (G_UNLIKELY (display->egl_display->base.handle.p != - eglGetCurrentDisplay ())) { - EglDisplay *current_egl_display = - egl_display_new_wrapped (eglGetCurrentDisplay ()); - if (!current_egl_display) - return FALSE; - - egl_object_replace (&display->egl_display, current_egl_display); - egl_object_unref (current_egl_display); - - if (!gst_vaapi_display_egl_set_gl_context (display, - eglGetCurrentContext ())) - return FALSE; - } + if (!gst_vaapi_display_egl_set_current_display (display)) + return FALSE; } egl_object_replace (&texture->egl_context, From e1f9959eb51085d241f5e57fc235422126023375 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Thu, 2 Nov 2017 13:21:34 +0100 Subject: [PATCH 2985/3781] libs: surface: egl: add comment Add a warning comment when using old intel-vaapi-drivers (>1.8.4), where the creation of surfaces from GEM fd may fail. https://bugzilla.gnome.org/show_bug.cgi?id=773453 --- gst-libs/gst/vaapi/gstvaapisurface_egl.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_egl.c b/gst-libs/gst/vaapi/gstvaapisurface_egl.c index 8bc42e536e..8ebd80186f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_egl.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_egl.c @@ -64,6 +64,16 @@ do_create_surface_with_egl_image_unlocked (GstVaapiDisplayEGL * display, goto error_export_image_gem_buf; size = height * stride[0]; + /* + * XXX: The below surface creation may fail on Intel due to: + * https://github.com/01org/intel-vaapi-driver/issues/222 + * A permanent fix for that problem will be released in intel-vaapi-driver + * version 1.8.4 and later, and also in 1.8.3-1ubuntu1. + * However if you don't have that fix then a simple workaround is to + * uncomment this line of code: + * size = GST_ROUND_UP_32 (height) * stride[0]; + */ + return gst_vaapi_surface_new_with_gem_buf_handle (base_display, name, size, format, width, height, offset, stride); From 89717a447fcc46e64000e9099706aec83fe02769 Mon Sep 17 00:00:00 2001 From: XuGuangxin Date: Wed, 27 Jul 2016 16:41:01 +0300 Subject: [PATCH 2986/3781] libs: encoder: objects: Add a reference flag We can have p-frame as non-ref and also b-frame as ref which are not supported yet. Reference flag is the first machinery needed for more advanced reference picture selection modes. Signed-off-by: Sreerenj Balachandran https://bugzilla.gnome.org/show_bug.cgi?id=788918 --- gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index a4179ff06d..f537ae5b14 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -223,8 +223,9 @@ gst_vaapi_enc_huffman_table_new (GstVaapiEncoder * encoder, guint8 * data, typedef enum { - GST_VAAPI_ENC_PICTURE_FLAG_IDR = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 0), - GST_VAAPI_ENC_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 1), + 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 @@ -235,6 +236,9 @@ typedef enum #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: * From e49859fde03dc8afdf339f6894f15e3a32f902bc Mon Sep 17 00:00:00 2001 From: XuGuangxin Date: Thu, 28 Jul 2016 14:17:53 +0300 Subject: [PATCH 2987/3781] libs: encoder: h264: Add property "temporal-levels" Adds new property "temporal-levels" to select the number of temporal levels to be included in the encoded stream. Signed-off-by: Sreerenj Balachandran https://bugzilla.gnome.org/show_bug.cgi?id=788918 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 22 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index cd9adf808d..3d0afdd01a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -48,6 +48,10 @@ /* Define the maximum value for view-id */ #define MAX_VIEW_ID 1023 +/* Define default temporal levels */ +#define MIN_TEMPORAL_LEVELS 1 +#define MAX_TEMPORAL_LEVELS 4 + /* Supported set of VA rate controls, within this implementation */ #define SUPPORTED_RATECONTROLS \ (GST_VAAPI_RATECONTROL_MASK (CQP) | \ @@ -717,6 +721,7 @@ struct _GstVaapiEncoderH264 guint32 mb_height; gboolean use_cabac; gboolean use_dct8x8; + guint temporal_levels; GstClockTime cts_offset; gboolean config_changed; @@ -2989,6 +2994,7 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder) encoder->is_mvc = FALSE; encoder->num_views = 1; encoder->view_idx = 0; + encoder->temporal_levels = MIN_TEMPORAL_LEVELS; memset (encoder->view_ids, 0, sizeof (encoder->view_ids)); /* re-ordering list initialize */ @@ -3119,6 +3125,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_MBBRC: encoder->mbbrc = g_value_get_enum (value); break; + case GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS: + encoder->temporal_levels = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; @@ -3300,6 +3309,19 @@ gst_vaapi_encoder_h264_get_default_properties (void) GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:temporal-levels: + * + * Number of temporal levels in the encoded stream. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS, + g_param_spec_uint ("temporal-levels", + "temporal levels", + "Number of temporal levels in the encoded stream ", + MIN_TEMPORAL_LEVELS, MAX_TEMPORAL_LEVELS, MIN_TEMPORAL_LEVELS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiEncoderH264:cpb-length: * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 42cb08f1c6..7b38e76327 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -54,6 +54,7 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * @GST_VAAPI_ENCODER_H264_PROP_MBBRC: Macroblock level Bitrate Control. * @GST_VAAPI_ENCODER_H264_PROP_QP_IP: Difference of QP between I and P frame. * @GST_VAAPI_ENCODER_H264_PROP_QP_IB: Difference of QP between I and B frame. + * @GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS: Number of temporal levels * * The set of H.264 encoder specific configurable properties. */ @@ -73,6 +74,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_MBBRC = -13, GST_VAAPI_ENCODER_H264_PROP_QP_IP = -14, GST_VAAPI_ENCODER_H264_PROP_QP_IB = -15, + GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS = -16, } GstVaapiEncoderH264Prop; GstVaapiEncoder * From dc583452d8d3e295a816da1efb35e0d0cbe7f9e2 Mon Sep 17 00:00:00 2001 From: XuGuangxin Date: Thu, 28 Jul 2016 15:12:05 +0300 Subject: [PATCH 2988/3781] libs: encoder: h264: Add machinery for implementing hierarchical-prediction Adds some basic building blocks to ease the implementation of hierarchical prediction modes. -- add an utility method to find temporal level of each frame -- define max_ref_frame count based on temporal level count -- add temporal_level_div[] for finding temporal level each frame to be encoded. -- find ip_period based on temporal level count Signed-off-by: Sreerenj Balachandran https://bugzilla.gnome.org/show_bug.cgi?id=788918 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 50 ++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 1 + 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 3d0afdd01a..d6e1638694 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -710,6 +710,7 @@ struct _GstVaapiEncoderH264 guint8 hw_max_profile_idc; guint8 level_idc; guint32 idr_period; + guint32 ip_period; guint32 init_qp; guint32 min_qp; guint32 qp_i; @@ -721,7 +722,8 @@ struct _GstVaapiEncoderH264 guint32 mb_height; gboolean use_cabac; gboolean use_dct8x8; - guint temporal_levels; + guint temporal_levels; /* Number of temporal levels */ + guint temporal_level_div[MAX_TEMPORAL_LEVELS]; /* to find the temporal id */ GstClockTime cts_offset; gboolean config_changed; @@ -2596,15 +2598,37 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); encoder->idr_num = 0; + /* this ip_period calculation is for supporting hierarchical-p + * and hierarchical-b encode */ + encoder->ip_period = 1 << (encoder->temporal_levels - 1); + for (i = 0; i < encoder->num_views; i++) { GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; GstVaapiH264ViewReorderPool *const reorder_pool = &encoder->reorder_pools[i]; - ref_pool->max_reflist0_count = encoder->num_ref_frames; - ref_pool->max_reflist1_count = encoder->num_bframes > 0; - ref_pool->max_ref_frames = ref_pool->max_reflist0_count - + ref_pool->max_reflist1_count; + if (encoder->temporal_levels == 1) { + ref_pool->max_reflist0_count = encoder->num_ref_frames; + ref_pool->max_reflist1_count = encoder->num_bframes > 0; + ref_pool->max_ref_frames = ref_pool->max_reflist0_count + + ref_pool->max_reflist1_count; + } else { + guint d; + + ref_pool->max_ref_frames = + encoder->temporal_levels * encoder->temporal_levels / 2; + ref_pool->max_reflist0_count = 1; + ref_pool->max_reflist1_count = encoder->num_bframes > 0; + encoder->num_ref_frames = ref_pool->max_ref_frames; + + d = encoder->ip_period; + /* temporal_level_div[] is helpful to find out the temporal level + * where each frame should belongs */ + for (i = 0; i < encoder->temporal_levels; i++) { + encoder->temporal_level_div[i] = d; + d >>= 1; + } + } reorder_pool->frame_index = 0; } @@ -2773,6 +2797,19 @@ error_alloc_buffer: } } +static guint32 +get_temporal_id (GstVaapiEncoderH264 * encoder, guint32 display_order) +{ + int l; + for (l = 0; l < encoder->temporal_levels; l++) { + if ((display_order % encoder->temporal_level_div[l]) == 0) + return l; + } + + GST_WARNING ("Couldn't find valid temporal id"); + return 0; +} + static GstVaapiEncoderStatus gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) @@ -2822,6 +2859,9 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, picture->poc = ((reorder_pool->cur_present_index * 2) % encoder->max_pic_order_cnt); + picture->temporal_id = (encoder->temporal_levels == 1) ? 1 : + get_temporal_id (encoder, reorder_pool->frame_index); + is_idr = (reorder_pool->frame_index == 0 || reorder_pool->frame_index >= encoder->idr_period); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index f537ae5b14..521cb12ad0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -269,6 +269,7 @@ struct _GstVaapiEncPicture GstClockTime pts; guint frame_num; guint poc; + guint temporal_id; #if USE_H264_FEI_ENCODER GstVaapiEncFeiMbControl *mbcntrl; GstVaapiEncFeiMvPredictor *mvpred; From ff91d62415311279cb093395f1fa6b3369df1375 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 28 Jul 2016 15:53:48 +0300 Subject: [PATCH 2989/3781] libs: encoder: h264: Add new property "prediction-type" Adds new property "prediction-type" to select different reference picture selection modes like hierarchical-p, hierarchical-b etc. Signed-off-by: Sreerenj Balachandran https://bugzilla.gnome.org/show_bug.cgi?id=788918 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 50 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 + 2 files changed, 52 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index d6e1638694..4af46e9f7f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -109,6 +109,38 @@ gst_vaapi_encoder_h264_compliance_mode_type (void) return gtype; } +typedef enum +{ + GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT, + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P, + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B +} GstVaapiEnoderH264PredictionType; + +static GType +gst_vaapi_encoder_h264_prediction_type (void) +{ + static GType gtype = 0; + + if (gtype == 0) { + static const GEnumValue values[] = { + {GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT, + "Default encode, prev/next frame as ref ", + "default"}, + {GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P, + "Hierarchical P frame encode", + "hierarchical-p"}, + {GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B, + "Hierarchical B frame encode", + "hierarchical-b"}, + {0, NULL, NULL}, + }; + + gtype = + g_enum_register_static ("GstVaapiEncoderH264PredictionType", values); + } + return gtype; +} + /* only for internal usage, values won't be equal to actual payload type */ typedef enum { @@ -724,6 +756,7 @@ struct _GstVaapiEncoderH264 gboolean use_dct8x8; guint temporal_levels; /* Number of temporal levels */ guint temporal_level_div[MAX_TEMPORAL_LEVELS]; /* to find the temporal id */ + guint prediction_type; GstClockTime cts_offset; gboolean config_changed; @@ -3168,6 +3201,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS: encoder->temporal_levels = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE: + encoder->prediction_type = g_value_get_enum (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; @@ -3362,6 +3398,20 @@ gst_vaapi_encoder_h264_get_default_properties (void) MIN_TEMPORAL_LEVELS, MAX_TEMPORAL_LEVELS, MIN_TEMPORAL_LEVELS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:prediction-type: + * + * Select the referece picture selection modes + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE, + g_param_spec_enum ("prediction-type", + "RefPic Selection", + "Reference Picture Selection Modes", + gst_vaapi_encoder_h264_prediction_type (), + GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiEncoderH264:cpb-length: * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 7b38e76327..eb262783a7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -55,6 +55,7 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * @GST_VAAPI_ENCODER_H264_PROP_QP_IP: Difference of QP between I and P frame. * @GST_VAAPI_ENCODER_H264_PROP_QP_IB: Difference of QP between I and B frame. * @GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS: Number of temporal levels + * @GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE: Reference picture selection modes * * The set of H.264 encoder specific configurable properties. */ @@ -75,6 +76,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_QP_IP = -14, GST_VAAPI_ENCODER_H264_PROP_QP_IB = -15, GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS = -16, + GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE = -17, } GstVaapiEncoderH264Prop; GstVaapiEncoder * From 904931d7f36fde5411f4cedd93ff7343559a6951 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 28 Jul 2016 16:51:28 +0300 Subject: [PATCH 2990/3781] libs: encoder: h264: Fix frame_num generation The frame_num generation was not correctly implemented. According to h264 spec, frame_num should get incremented for each frame if previous frame is a referece frame. For eg: IPBPB sequece should have the frame numbers 0,1,2,2,3 Signed-off-by: Sreerenj Balachandran https://bugzilla.gnome.org/show_bug.cgi?id=788918 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 48 ++++++++++++++--------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 4af46e9f7f..a748d62a6b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -179,6 +179,7 @@ typedef struct _GstVaapiH264ViewReorderPool guint frame_count; /* monotonically increasing with in every idr period */ guint cur_frame_num; guint cur_present_index; + gboolean prev_frame_is_ref; /* previous frame is ref or not */ } GstVaapiH264ViewReorderPool; static inline gboolean @@ -1287,7 +1288,6 @@ reset_gop_start (GstVaapiEncoderH264 * encoder) &encoder->reorder_pools[encoder->view_idx]; reorder_pool->frame_index = 1; - reorder_pool->cur_frame_num = 0; reorder_pool->cur_present_index = 0; ++encoder->idr_num; } @@ -1296,37 +1296,27 @@ reset_gop_start (GstVaapiEncoderH264 * encoder) static void set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { - GstVaapiH264ViewReorderPool *const reorder_pool = - &encoder->reorder_pools[encoder->view_idx]; - g_assert (pic && encoder); g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_B; - pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); } /* Marks the supplied picture as a P-frame */ static void set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { - GstVaapiH264ViewReorderPool *const reorder_pool = - &encoder->reorder_pools[encoder->view_idx]; - g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_P; - pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); + GST_VAAPI_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_REFERENCE); } /* Marks the supplied picture as an I-frame */ static void set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { - GstVaapiH264ViewReorderPool *const reorder_pool = - &encoder->reorder_pools[encoder->view_idx]; - g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_I; - pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); + GST_VAAPI_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_REFERENCE); g_assert (pic->frame); GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); @@ -1338,9 +1328,9 @@ set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_I; - pic->frame_num = 0; pic->poc = 0; - GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR); + GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, + GST_VAAPI_ENC_PICTURE_FLAG_IDR | GST_VAAPI_ENC_PICTURE_FLAG_REFERENCE); g_assert (pic->frame); GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); @@ -2718,6 +2708,7 @@ gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder) reorder_pool->frame_index = 0; reorder_pool->cur_frame_num = 0; reorder_pool->cur_present_index = 0; + reorder_pool->prev_frame_is_ref = FALSE; while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { pic = (GstVaapiEncPicture *) @@ -2843,6 +2834,26 @@ get_temporal_id (GstVaapiEncoderH264 * encoder, guint32 display_order) return 0; } +static void +set_frame_num (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiH264ViewReorderPool *reorder_pool = NULL; + + reorder_pool = &encoder->reorder_pools[encoder->view_idx]; + + picture->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); + + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { + picture->frame_num = 0; + reorder_pool->cur_frame_num = 0; + } + + reorder_pool->prev_frame_is_ref = GST_VAAPI_ENC_PICTURE_IS_REFRENCE (picture); + + if (reorder_pool->prev_frame_is_ref) + ++reorder_pool->cur_frame_num; +} + static GstVaapiEncoderStatus gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) @@ -2902,7 +2913,6 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) || (reorder_pool->frame_index % GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == 0) { - ++reorder_pool->cur_frame_num; ++reorder_pool->frame_index; /* b frame enabled, check queue of reorder_frame_list */ @@ -2914,7 +2924,6 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, set_p_frame (p_pic, encoder); g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame, encoder); - ++reorder_pool->cur_frame_num; set_key_frame (picture, encoder, is_idr | GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame)); g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); @@ -2939,7 +2948,6 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; } - ++reorder_pool->cur_frame_num; set_p_frame (picture, encoder); if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) { @@ -2954,6 +2962,10 @@ end: frame = picture->frame; if (GST_CLOCK_TIME_IS_VALID (frame->pts)) frame->pts += encoder->cts_offset; + + /* set frame_num based on previous frame reference type */ + set_frame_num (encoder, picture); + *output = picture; return GST_VAAPI_ENCODER_STATUS_SUCCESS; From 53c83691f3bbd285f1aecd84ad0f0eef3bbf1d6e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 28 Jul 2016 18:33:23 +0300 Subject: [PATCH 2991/3781] libs: encoder: h264: Add Hierarchical-P encode Frames are encoded as different layers. A frame in a particular layer will use pictures in lower or same layer as references. Which means decoder can drop the frames in upper layer but still decode lower layer frames. eg: with 3 temporal layers T3: P1 P3 P5 P7 T2: P2 P6 T1: P0 P4 P8 T1, T2, T3: Temporal Layers P1...pn: P-Frames: P0->P1 , P0->P2, P2->P3, P0->P4......repeat Signed-off-by: Sreerenj Balachandran https://bugzilla.gnome.org/show_bug.cgi?id=788918 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 155 ++++++++++++++++++++-- 1 file changed, 143 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index a748d62a6b..e9015d3e8f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -154,6 +154,7 @@ typedef struct GstVaapiSurfaceProxy *pic; guint poc; guint frame_num; + guint temporal_id; } GstVaapiEncoderH264Ref; typedef enum @@ -758,6 +759,7 @@ struct _GstVaapiEncoderH264 guint temporal_levels; /* Number of temporal levels */ guint temporal_level_div[MAX_TEMPORAL_LEVELS]; /* to find the temporal id */ guint prediction_type; + guint abs_diff_pic_num_list0; GstClockTime cts_offset; gboolean config_changed; @@ -943,9 +945,25 @@ bs_write_slice (GstBitWriter * bs, WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1); } } - /* XXX: not supporting custom reference picture list modifications */ - if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4)) + + if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4)) { + if ((encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P) + && (encoder->abs_diff_pic_num_list0 > 1)) + ref_pic_list_modification_flag_l0 = 1; + WRITE_UINT32 (bs, ref_pic_list_modification_flag_l0, 1); + + if (ref_pic_list_modification_flag_l0) { + /*modification_of_pic_num_idc */ + WRITE_UE (bs, 0); + /* abs_diff_pic_num_minus1 */ + WRITE_UE (bs, encoder->abs_diff_pic_num_list0 - 1); + /*modification_of_pic_num_idc */ + WRITE_UE (bs, 3); + } + } + if (slice_param->slice_type == 1) WRITE_UINT32 (bs, ref_pic_list_modification_flag_l1, 1); @@ -959,7 +977,7 @@ bs_write_slice (GstBitWriter * bs, } /* dec_ref_pic_marking() */ - if (slice_param->slice_type == 0 || slice_param->slice_type == 2) { + if (GST_VAAPI_ENC_PICTURE_IS_REFRENCE (picture)) { if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { /* no_output_of_prior_pics_flag = 0 */ WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1); @@ -1280,6 +1298,13 @@ ensure_tuning (GstVaapiEncoderH264 * encoder) return success; } +static gboolean +is_temporal_id_max (GstVaapiEncoderH264 * encoder, guint32 temporal_id) +{ + g_assert (temporal_id < encoder->temporal_levels); + return temporal_id == encoder->temporal_levels - 1; +} + /* Handle new GOP starts */ static void reset_gop_start (GstVaapiEncoderH264 * encoder) @@ -1307,7 +1332,16 @@ set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) { g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_P; - GST_VAAPI_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_REFERENCE); + + if (encoder->temporal_levels == 1) { + /* Default prediction mode */ + GST_VAAPI_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_REFERENCE); + } else { + /* temporal_encode: all frames in highest level are not reference frames + * for hierarhical-p and hierarchical-b prediction mode */ + if (!is_temporal_id_max (encoder, pic->temporal_id)) + GST_VAAPI_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_REFERENCE); + } } /* Marks the supplied picture as an I-frame */ @@ -1673,7 +1707,11 @@ get_nal_hdr_attributes (GstVaapiEncPicture * picture, *nal_unit_type = GST_H264_NAL_SLICE; break; case GST_VAAPI_PICTURE_TYPE_P: - *nal_ref_idc = GST_H264_NAL_REF_IDC_MEDIUM; + if (!GST_VAAPI_ENC_PICTURE_IS_REFRENCE (picture)) + *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE; + else + *nal_ref_idc = GST_H264_NAL_REF_IDC_MEDIUM; + *nal_unit_type = GST_H264_NAL_SLICE; break; case GST_VAAPI_PICTURE_TYPE_B: @@ -1813,6 +1851,7 @@ reference_pic_create (GstVaapiEncoderH264 * encoder, ref->pic = surface; ref->frame_num = picture->frame_num; ref->poc = picture->poc; + ref->temporal_id = picture->temporal_id; return ref; } @@ -1842,6 +1881,57 @@ reference_list_update (GstVaapiEncoderH264 * encoder, return TRUE; } +static void +reflist0_init_hierarchical (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, GQueue * ref_list, + GstVaapiEncoderH264Ref ** reflist_0, guint * reflist_0_count) +{ + GstVaapiEncoderH264Ref *tmp = NULL; + GList *iter; + guint count = 0, i; + + iter = g_queue_peek_tail_link (ref_list); + for (; iter; iter = g_list_previous (iter)) { + tmp = (GstVaapiEncoderH264Ref *) iter->data; + + g_assert (tmp && tmp->poc != picture->poc); + + if (_poc_greater_than (picture->poc, tmp->poc, encoder->max_pic_order_cnt) + && ((picture->temporal_id && (tmp->temporal_id < picture->temporal_id)) + || (!picture->temporal_id + && (tmp->temporal_id == picture->temporal_id)))) { + reflist_0[count++] = tmp; + } + } + + g_assert (count != 0); + + /* Only need one ref frame */ + tmp = reflist_0[0]; + for (i = 1; i < count; i++) { + if (tmp->poc < reflist_0[i]->poc) + tmp = reflist_0[i]; + } + reflist_0[0] = tmp; + *reflist_0_count = 1; + encoder->abs_diff_pic_num_list0 = picture->frame_num - tmp->frame_num; +} + +static gboolean +reference_list_init_hierarchical (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, + GQueue * ref_list, + GstVaapiEncoderH264Ref ** reflist_0, + guint * reflist_0_count, + GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count) +{ + /* reflist_0 ordering is same for hierarchical-P and hierarchical-B */ + reflist0_init_hierarchical (encoder, picture, ref_list, reflist_0, + reflist_0_count); + + return TRUE; +} + static gboolean reference_list_init (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, @@ -1860,6 +1950,14 @@ reference_list_init (GstVaapiEncoderH264 * encoder, if (picture->type == GST_VAAPI_PICTURE_TYPE_I) return TRUE; + /* reference picture handling for hierarchial encode */ + if (encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P) { + return reference_list_init_hierarchical (encoder, picture, + &ref_pool->ref_list, reflist_0, reflist_0_count, reflist_1, + reflist_1_count); + } + iter = g_queue_peek_tail_link (&ref_pool->ref_list); for (; iter; iter = g_list_previous (iter)) { tmp = (GstVaapiEncoderH264Ref *) iter->data; @@ -1908,8 +2006,7 @@ fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence) seq_param->level_idc = encoder->level_idc; seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); - seq_param->ip_period = seq_param->intra_period > 1 ? - (1 + encoder->num_bframes) : 0; + seq_param->ip_period = encoder->ip_period; seq_param->bits_per_second = encoder->bitrate_bits; seq_param->max_num_ref_frames = ref_pool->max_ref_frames; @@ -2049,7 +2146,7 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, pic_param->pic_fields.bits.idr_pic_flag = GST_VAAPI_ENC_PICTURE_IS_IDR (picture); pic_param->pic_fields.bits.reference_pic_flag = - (picture->type != GST_VAAPI_PICTURE_TYPE_B); + GST_VAAPI_ENC_PICTURE_IS_REFRENCE (picture); pic_param->pic_fields.bits.entropy_coding_mode_flag = encoder->use_cabac; pic_param->pic_fields.bits.weighted_pred_flag = FALSE; pic_param->pic_fields.bits.weighted_bipred_idc = 0; @@ -2621,16 +2718,49 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); encoder->idr_num = 0; - /* this ip_period calculation is for supporting hierarchical-p - * and hierarchical-b encode */ - encoder->ip_period = 1 << (encoder->temporal_levels - 1); + /* if temporal scalability enabled then use hierarchical-p + * as default prediction */ + if (encoder->temporal_levels > 1 + && encoder->prediction_type == GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT) + encoder->prediction_type = GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P; + + if (encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P) { + + /* Hierarchical prediction should have a temporal level count + * greater than one and we use 4 temporal levels as default */ + if (encoder->temporal_levels <= 1) + encoder->temporal_levels = 4; + + /* this ip_period calculation is for supporting hierarchical-p + * and hierarchical-b encode */ + encoder->ip_period = 1 << (encoder->temporal_levels - 1); + + /* align the idr_period to ip_peroid to simplify encode process */ + encoder->idr_period = + GST_ROUND_UP_N (encoder->idr_period, encoder->ip_period); + + GST_VAAPI_ENCODER_KEYFRAME_PERIOD (base_encoder) = encoder->idr_period; + + /* Disable mvc-encode in hierarchical mode */ + if (encoder->num_views > 1) { + encoder->num_views = 1; + encoder->is_mvc = FALSE; + } + + /* no b-frames in Hierarchical-P */ + encoder->num_bframes = 0; + } else { + encoder->ip_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder) > 1 ? + (1 + encoder->num_bframes) : 0; + } for (i = 0; i < encoder->num_views; i++) { GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; GstVaapiH264ViewReorderPool *const reorder_pool = &encoder->reorder_pools[i]; - if (encoder->temporal_levels == 1) { + if (encoder->prediction_type == GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT) { ref_pool->max_reflist0_count = encoder->num_ref_frames; ref_pool->max_reflist1_count = encoder->num_bframes > 0; ref_pool->max_ref_frames = ref_pool->max_reflist0_count @@ -3080,6 +3210,7 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder) encoder->num_views = 1; encoder->view_idx = 0; encoder->temporal_levels = MIN_TEMPORAL_LEVELS; + encoder->abs_diff_pic_num_list0 = 1; memset (encoder->view_ids, 0, sizeof (encoder->view_ids)); /* re-ordering list initialize */ From 6a3f30aab10456423f40234323209e5915001c51 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Fri, 29 Jul 2016 14:58:49 +0300 Subject: [PATCH 2992/3781] libs: encoder: h264: Add Hierarchical-B encode Frames are encoded as different layers. Frame in a particular layer will use pictures in lower or same layer as references. Which means decoder can drop the frames in upper layer but still decode lower layer frames. B-frames, except the one in top most layer, are reference frames. All the base layer frames are I or P. eg: with 3 temporal layers T3: B1 B3 B5 B7 T2: B2 B6 T1: I0 P4 P8 T1, T2, T3: Temporal Layers P1...Pn: P-Frames: B1...Bn: B-frames: T1: I0->P4 , P4->P8 etc.. T2: I0--> B2 <-- P4 T3: I0--> B1 <-- B2, B2 --> B3 <-- P4 Signed-off-by: Sreerenj Balachandran https://bugzilla.gnome.org/show_bug.cgi?id=788918 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 172 ++++++++++++++++++++-- 1 file changed, 157 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index e9015d3e8f..a8eef8e9d1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -760,6 +760,7 @@ struct _GstVaapiEncoderH264 guint temporal_level_div[MAX_TEMPORAL_LEVELS]; /* to find the temporal id */ guint prediction_type; guint abs_diff_pic_num_list0; + guint abs_diff_pic_num_list1; GstClockTime cts_offset; gboolean config_changed; @@ -947,8 +948,7 @@ bs_write_slice (GstBitWriter * bs, } if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4)) { - if ((encoder->prediction_type == - GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P) + if ((encoder->prediction_type != GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT) && (encoder->abs_diff_pic_num_list0 > 1)) ref_pic_list_modification_flag_l0 = 1; @@ -964,9 +964,25 @@ bs_write_slice (GstBitWriter * bs, } } - if (slice_param->slice_type == 1) + /* B-frame */ + if (slice_param->slice_type == 1) { + if ((encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B) + && (encoder->abs_diff_pic_num_list1 > 1)) + ref_pic_list_modification_flag_l1 = 1; + WRITE_UINT32 (bs, ref_pic_list_modification_flag_l1, 1); + if (ref_pic_list_modification_flag_l1) { + /*modification_of_pic_num_idc */ + WRITE_UE (bs, 0); + /* abs_diff_pic_num_minus1 */ + WRITE_UE (bs, encoder->abs_diff_pic_num_list1 - 1); + /*modification_of_pic_num_idc */ + WRITE_UE (bs, 3); + } + } + /* we have: weighted_pred_flag == FALSE and */ /* : weighted_bipred_idc == FALSE */ if ((pic_param->pic_fields.bits.weighted_pred_flag && @@ -1324,6 +1340,17 @@ set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder) g_assert (pic && encoder); g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); pic->type = GST_VAAPI_PICTURE_TYPE_B; + + if (encoder->temporal_levels > 1) { + /* while doing temporal encoding, b frames are allowded + * only in hierarchical-b mode */ + g_assert (encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B); + /* temporal_encode: set b-frame as reference frames in + * hierarchical-b encode unless they belongs to highest level */ + if (!is_temporal_id_max (encoder, pic->temporal_id)) + GST_VAAPI_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_REFERENCE); + } } /* Marks the supplied picture as a P-frame */ @@ -1715,7 +1742,11 @@ get_nal_hdr_attributes (GstVaapiEncPicture * picture, *nal_unit_type = GST_H264_NAL_SLICE; break; case GST_VAAPI_PICTURE_TYPE_B: - *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE; + if (!GST_VAAPI_ENC_PICTURE_IS_REFRENCE (picture)) + *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE; + else + *nal_ref_idc = GST_H264_NAL_REF_IDC_LOW; + *nal_unit_type = GST_H264_NAL_SLICE; break; default: @@ -1863,7 +1894,8 @@ reference_list_update (GstVaapiEncoderH264 * encoder, GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[encoder->view_idx]; - if (GST_VAAPI_PICTURE_TYPE_B == picture->type) { + if (encoder->prediction_type == GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT + && GST_VAAPI_PICTURE_TYPE_B == picture->type) { gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface); return TRUE; } @@ -1881,6 +1913,7 @@ reference_list_update (GstVaapiEncoderH264 * encoder, return TRUE; } +/* update reflist0 for hierarchical-p and hierarchical-b encode */ static void reflist0_init_hierarchical (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GQueue * ref_list, @@ -1917,6 +1950,44 @@ reflist0_init_hierarchical (GstVaapiEncoderH264 * encoder, encoder->abs_diff_pic_num_list0 = picture->frame_num - tmp->frame_num; } +/* update reflist1 for hierarchical-b encode */ +static void +reflist1_init_hierarchical_b (GstVaapiEncoderH264 * encoder, + GstVaapiEncPicture * picture, GQueue * ref_list, + GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count) +{ + GstVaapiEncoderH264Ref *tmp = NULL; + GList *iter; + guint count = 0, i; + + /* base layer should have only P frames */ + g_assert (picture->temporal_id != 0); + + iter = g_queue_peek_tail_link (ref_list); + for (; iter; iter = g_list_previous (iter)) { + tmp = (GstVaapiEncoderH264Ref *) iter->data; + + g_assert (tmp && tmp->poc != picture->poc); + + if (_poc_greater_than (tmp->poc, picture->poc, encoder->max_pic_order_cnt) + && (tmp->temporal_id < picture->temporal_id)) { + reflist_1[count++] = tmp; + } + } + + g_assert (count != 0); + + /* Only need one ref frame */ + tmp = reflist_1[0]; + for (i = 1; i < count; i++) { + if (tmp->poc > reflist_1[i]->poc) + tmp = reflist_1[i]; + } + reflist_1[0] = tmp; + *reflist_1_count = 1; + encoder->abs_diff_pic_num_list1 = picture->frame_num - tmp->frame_num; +} + static gboolean reference_list_init_hierarchical (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, @@ -1929,6 +2000,19 @@ reference_list_init_hierarchical (GstVaapiEncoderH264 * encoder, reflist0_init_hierarchical (encoder, picture, ref_list, reflist_0, reflist_0_count); + if (picture->type != GST_VAAPI_PICTURE_TYPE_B) + return TRUE; + + g_assert (encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B); + + reflist1_init_hierarchical_b (encoder, picture, ref_list, + reflist_1, reflist_1_count); + + /* FIXME: Combine and optimize reflist_0_init and reflist_1_init. + * Keeping separate blocks for now to make it more + * readable and easy to debug */ + return TRUE; } @@ -1951,8 +2035,7 @@ reference_list_init (GstVaapiEncoderH264 * encoder, return TRUE; /* reference picture handling for hierarchial encode */ - if (encoder->prediction_type == - GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P) { + if (encoder->prediction_type != GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT) { return reference_list_init_hierarchical (encoder, picture, &ref_pool->ref_list, reflist_0, reflist_0_count, reflist_1, reflist_1_count); @@ -2695,6 +2778,10 @@ reset_properties (GstVaapiEncoderH264 * encoder) if (base_encoder->max_num_ref_frames_1 < 1 && encoder->num_bframes > 0) { GST_WARNING ("Disabling b-frame since the driver doesn't support it"); encoder->num_bframes = 0; + + if (encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B) + encoder->prediction_type = GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT; } if (encoder->num_ref_frames > base_encoder->max_num_ref_frames_0) { @@ -2718,14 +2805,20 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); encoder->idr_num = 0; - /* if temporal scalability enabled then use hierarchical-p - * as default prediction */ + /* If temporal scalability enabled then use hierarchical-p/b + * according to num_bframes as default prediction */ if (encoder->temporal_levels > 1 - && encoder->prediction_type == GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT) - encoder->prediction_type = GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P; + && encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT) { + if (encoder->num_bframes > 0) + encoder->prediction_type = + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B; + else + encoder->prediction_type = + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P; + } - if (encoder->prediction_type == - GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P) { + if (encoder->prediction_type != GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT) { /* Hierarchical prediction should have a temporal level count * greater than one and we use 4 temporal levels as default */ @@ -2749,7 +2842,14 @@ reset_properties (GstVaapiEncoderH264 * encoder) } /* no b-frames in Hierarchical-P */ - encoder->num_bframes = 0; + if (encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P) + encoder->num_bframes = 0; + + /* reset number of b-frames in Hierarchical-B */ + if (encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B) + encoder->num_bframes = (1 << (encoder->temporal_levels - 1)) - 1; } else { encoder->ip_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder) > 1 ? (1 + encoder->num_bframes) : 0; @@ -2768,8 +2868,12 @@ reset_properties (GstVaapiEncoderH264 * encoder) } else { guint d; + /* This shouldn't be executed on MVC encoding */ + g_assert (i < 1); + ref_pool->max_ref_frames = - encoder->temporal_levels * encoder->temporal_levels / 2; + encoder->temporal_levels * (encoder->temporal_levels) / 2 + + (encoder->num_bframes > 0); ref_pool->max_reflist0_count = 1; ref_pool->max_reflist1_count = encoder->num_bframes > 0; encoder->num_ref_frames = ref_pool->max_ref_frames; @@ -2964,6 +3068,23 @@ get_temporal_id (GstVaapiEncoderH264 * encoder, guint32 display_order) return 0; } +/* reorder_list sorting for hierarchical-b encode */ +static gint +sort_hierarchical_b (gconstpointer a, gconstpointer b, gpointer user_data) +{ + GstVaapiEncPicture *pic1 = (GstVaapiEncPicture *) a; + GstVaapiEncPicture *pic2 = (GstVaapiEncPicture *) b; + + if (pic1->type != GST_VAAPI_PICTURE_TYPE_B) + return 1; + if (pic2->type != GST_VAAPI_PICTURE_TYPE_B) + return -1; + if (pic1->temporal_id == pic2->temporal_id) + return pic1->poc - pic2->poc; + else + return pic1->temporal_id - pic2->temporal_id; +} + static void set_frame_num (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { @@ -3014,6 +3135,14 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, g_assert (encoder->num_bframes > 0); g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list), GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN); + + /* sort the queued list of frames for hierarchical-b based on + * temporal level where each frame belongs */ + if (encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B) + g_queue_sort (&reorder_pool->reorder_frame_list, sort_hierarchical_b, + NULL); + picture = g_queue_pop_head (&reorder_pool->reorder_frame_list); g_assert (picture); if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) { @@ -3052,6 +3181,18 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list); set_p_frame (p_pic, encoder); + + /* for hierarchical-b, if idr-period reached , make sure the + * most recent queued frame get encoded as a reference + * p-frame in base-layer */ + if (encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B) { + p_pic->temporal_id = 0; + GST_VAAPI_PICTURE_FLAG_SET (p_pic, + GST_VAAPI_ENC_PICTURE_FLAG_REFERENCE); + } + /* Fix : make sure the detached head is non-ref, currently it is ref */ + g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame, encoder); set_key_frame (picture, encoder, @@ -3211,6 +3352,7 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder) encoder->view_idx = 0; encoder->temporal_levels = MIN_TEMPORAL_LEVELS; encoder->abs_diff_pic_num_list0 = 1; + encoder->abs_diff_pic_num_list1 = 1; memset (encoder->view_ids, 0, sizeof (encoder->view_ids)); /* re-ordering list initialize */ From a7472ec4e85bb99cc473cb81979a221a96b547e2 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Mon, 27 Nov 2017 20:17:55 +1100 Subject: [PATCH 2993/3781] Automatic update of common submodule From 3f4aa96 to e8c7a71 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 3f4aa969cb..e8c7a71bf3 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 3f4aa969cbe39584a649d98d4cf321d78bd73092 +Subproject commit e8c7a71bf3e2ee48f682011bd63d64a8c78ea3b6 From bfc7f667081c62598a885d7419d500fcf4f38ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 27 Nov 2017 12:18:56 +0100 Subject: [PATCH 2994/3781] libs: encoder: h264,h265: guard rate control's macroblock macroblock parameter appear on VA-API 1.0.0. It should be guarded. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index a8eef8e9d1..0c4b8712f0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2497,8 +2497,11 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; + +#if VA_CHECK_VERSION(1,0,0) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).rc_flags.bits.mb_rate_control = (guint) encoder->mbbrc; +#endif /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 5e4c84081b..557901fe03 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1833,8 +1833,11 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; + +#if VA_CHECK_VERSION(1,0,0) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).rc_flags.bits.mb_rate_control = (guint) encoder->mbbrc; +#endif /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); From 20b95f0fec72ce61ce61e511df4e656475686a55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 27 Nov 2017 13:04:24 +0100 Subject: [PATCH 2995/3781] libs: window: wayland: remove unused header include Remove wayland-client.h include since there is no exposed symbols from it. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.h | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h index 304ecf053f..ed8f756de7 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h @@ -24,7 +24,6 @@ #ifndef GST_VAAPI_WINDOW_WAYLAND_H #define GST_VAAPI_WINDOW_WAYLAND_H -#include #include #include From 0438a3e62660e64ed390b6bb83bfb560b91664aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 30 Nov 2017 14:24:43 +0100 Subject: [PATCH 2996/3781] vaapivideocontext: possible memleak when no bus attached https://bugzilla.gnome.org/show_bug.cgi?id=790999 --- gst/vaapi/gstvaapivideocontext.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index e41e7dfc6b..03aa272fc4 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -196,8 +196,10 @@ _gst_context_query (GstElement * element, const gchar * context_type) GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "posting `need-context' message"); msg = gst_message_new_need_context (GST_OBJECT_CAST (element), context_type); - if (!gst_element_post_message (element, msg)) + if (!gst_element_post_message (element, msg)) { GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "No bus attached"); + gst_message_unref (msg); + } /* * Whomever responds to the need-context message performs a From 466c8399909fc3999ce8b9276a89d405ccdafafd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 1 Dec 2017 20:21:54 +0100 Subject: [PATCH 2997/3781] vaapivideocontext: log the name of GstVaapiDisplay https://bugzilla.gnome.org/show_bug.cgi?id=790999 --- gst/vaapi/gstvaapivideocontext.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 03aa272fc4..10961e7b26 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -222,22 +222,25 @@ gst_vaapi_video_context_prepare (GstElement * element, * type. */ if (*display_ptr) { - GST_LOG_OBJECT (element, "already have a display (%p)", *display_ptr); + GST_LOG_OBJECT (element, "already have a display %" GST_PTR_FORMAT, + *display_ptr); return TRUE; } _gst_context_query (element, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); if (*display_ptr) { - GST_LOG_OBJECT (element, "found a display (%p)", *display_ptr); + GST_LOG_OBJECT (element, "found a display %" GST_PTR_FORMAT, *display_ptr); return TRUE; } _gst_context_query (element, GST_VAAPI_DISPLAY_APP_CONTEXT_TYPE_NAME); - if (*display_ptr) - GST_LOG_OBJECT (element, "got a display with va display from app (%p)", + if (*display_ptr) { + GST_LOG_OBJECT (element, + "got a display with va display from app %" GST_PTR_FORMAT, *display_ptr); + } return *display_ptr != NULL; } @@ -256,7 +259,7 @@ gst_vaapi_video_context_propagate (GstElement * element, _init_context_debug (); GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, - "posting `have-context' (%p) message with display (%p)", + "posting `have-context' (%p) message with display %" GST_PTR_FORMAT, context, display); msg = gst_message_new_have_context (GST_OBJECT_CAST (element), context); if (!gst_element_post_message (element, msg)) From 8f5933cd80e91e8220403561672ed2e374be4053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Nov 2017 11:02:03 +0100 Subject: [PATCH 2998/3781] vaapivideocontext: only vaapisink process app context gst.vaapi.app.Display context is made for applications that will provide the VA display and the native display to used by the pipeline, when are using vaapisink as overlay. There are no use case for encoders, decoders, neither for the postprocessor. In the case of the vaapisink, it shall query for gst.vaapi.Display upstream first, and then, if there is no reply, gst.vaapi.app.Display context will be posted in the bus for the application. If the application replies, a GstVaapiDisplay object is instantiated given the context info, otherwise a GstVaapiDisplay is created with the normal algorithm to guess the graphics platform. Either way, the instantiated GstVaapiDisplay is propagated among the pipeline and the have-message bus message. Also only vaapisink will process the gst.vaapi.app.Display, if and only if, it doesn't have a display already set. This is caused because if vaapisink is in a bin (playsink, for example) the need-context is posted twice, leading to an error state. https://bugzilla.gnome.org/show_bug.cgi?id=790999 --- gst/vaapi/gstvaapipluginbase.c | 7 +++- gst/vaapi/gstvaapivideocontext.c | 69 +++++++++++++++++++++++++------- gst/vaapi/gstvaapivideocontext.h | 2 +- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e835f69eee..afb9a34a65 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -91,9 +91,12 @@ gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, { GstVaapiDisplay *display = NULL; - if (gst_vaapi_video_context_get_display (context, &display)) + /* gst.vaapi.app.Display is only attended _if_ the element is + * vaapisink and it doesn't have a display set yet */ + if (gst_vaapi_video_context_get_display (context, + GST_IS_VIDEO_SINK (plugin) && !plugin->display, &display)) { plugin_set_display (plugin, display); - + } #if USE_GST_GL_HELPERS { GstGLDisplay *gl_display = NULL; diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 10961e7b26..a556a895f1 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -72,11 +72,12 @@ gst_vaapi_video_context_new_with_display (GstVaapiDisplay * display, } gboolean -gst_vaapi_video_context_get_display (GstContext * context, +gst_vaapi_video_context_get_display (GstContext * context, gboolean app_context, GstVaapiDisplay ** display_ptr) { const GstStructure *structure; const gchar *type; + GstVaapiDisplay *display = NULL; g_return_val_if_fail (GST_IS_CONTEXT (context), FALSE); @@ -86,7 +87,9 @@ gst_vaapi_video_context_get_display (GstContext * context, structure = gst_context_get_structure (context); return gst_structure_get (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, GST_TYPE_VAAPI_DISPLAY, display_ptr, NULL); - } else if (!g_strcmp0 (type, GST_VAAPI_DISPLAY_APP_CONTEXT_TYPE_NAME)) { + } + + if (app_context && !g_strcmp0 (type, GST_VAAPI_DISPLAY_APP_CONTEXT_TYPE_NAME)) { VADisplay va_display = NULL; structure = gst_context_get_structure (context); @@ -96,12 +99,22 @@ gst_vaapi_video_context_get_display (GstContext * context, Display *x11_display = NULL; if (gst_structure_get (structure, "x11-display", G_TYPE_POINTER, &x11_display, NULL)) { - *display_ptr = + display = gst_vaapi_display_x11_new_with_va_display (va_display, x11_display); - return TRUE; } #endif - GST_WARNING ("Not support if only VADisplay provided"); + + _init_context_debug (); + + if (!display) { + GST_CAT_WARNING (GST_CAT_CONTEXT, + "Cannot create GstVaapiDisplay if only VADisplay is provided"); + return FALSE; + } + GST_CAT_INFO (GST_CAT_CONTEXT, + "new display with context %" GST_PTR_FORMAT, display); + *display_ptr = display; + return TRUE; } } @@ -211,6 +224,33 @@ found: gst_query_unref (query); } +static gboolean +_gst_vaapi_sink_find_context (GstElement * element) +{ + GstQuery *query; + GstMessage *msg; + gboolean found; + + /* 1. Query upstream for an already created GstVaapiDisplay */ + query = gst_query_new_context (GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); + found = _gst_context_get_from_query (element, query, GST_PAD_SINK); + gst_query_unref (query); + if (found) + return TRUE; + + /* 2. Post a GST_MESSAGE_NEED_CONTEXT message on the bus with a + * gst.vaapi.app.Display context from the application */ + msg = gst_message_new_need_context (GST_OBJECT_CAST (element), + GST_VAAPI_DISPLAY_APP_CONTEXT_TYPE_NAME); + if (!gst_element_post_message (element, msg)) { + _init_context_debug (); + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "No bus attached"); + gst_message_unref (msg); + } + + return FALSE; +} + gboolean gst_vaapi_video_context_prepare (GstElement * element, GstVaapiDisplay ** display_ptr) @@ -227,22 +267,21 @@ gst_vaapi_video_context_prepare (GstElement * element, return TRUE; } - _gst_context_query (element, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); + if (GST_IS_VIDEO_SINK (element)) { + if (!_gst_vaapi_sink_find_context (element) && *display_ptr) { + /* Propagate if display was created from application */ + gst_vaapi_video_context_propagate (element, *display_ptr); + } + } else { + _gst_context_query (element, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME); + } if (*display_ptr) { GST_LOG_OBJECT (element, "found a display %" GST_PTR_FORMAT, *display_ptr); return TRUE; } - _gst_context_query (element, GST_VAAPI_DISPLAY_APP_CONTEXT_TYPE_NAME); - - if (*display_ptr) { - GST_LOG_OBJECT (element, - "got a display with va display from app %" GST_PTR_FORMAT, - *display_ptr); - } - - return *display_ptr != NULL; + return FALSE; } /* 5) Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT message diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index 3d87754a5e..cdac0f9b9c 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -44,7 +44,7 @@ gst_vaapi_video_context_new_with_display (GstVaapiDisplay * display, G_GNUC_INTERNAL gboolean -gst_vaapi_video_context_get_display (GstContext * context, +gst_vaapi_video_context_get_display (GstContext * context, gboolean app_context, GstVaapiDisplay ** display_ptr); G_GNUC_INTERNAL From 4d29f4c8c499507568ba41b73a385d2a2435da80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Nov 2017 18:29:45 +0100 Subject: [PATCH 2999/3781] test: vaapicontext: app context is not persistent --- tests/elements/test-vaapicontext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/elements/test-vaapicontext.c b/tests/elements/test-vaapicontext.c index ac974cc4c0..4b37a2cbdb 100644 --- a/tests/elements/test-vaapicontext.c +++ b/tests/elements/test-vaapicontext.c @@ -110,7 +110,7 @@ create_vaapi_app_display_context (AppData * app, gboolean new_va_display) else va_display = ensure_va_display (app); - context = gst_context_new ("gst.vaapi.app.Display", TRUE); + context = gst_context_new ("gst.vaapi.app.Display", FALSE); s = gst_context_writable_structure (context); gst_structure_set (s, "va-display", G_TYPE_POINTER, va_display, NULL); gst_structure_set (s, "x11-display", G_TYPE_POINTER, x11_display, NULL); From af0bf7212bcf7d1064e15b7cbcb1bd901f093622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 1 Dec 2017 23:03:32 +0100 Subject: [PATCH 3000/3781] test: vaapicontext: process have-context bus message --- tests/elements/test-vaapicontext.c | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/elements/test-vaapicontext.c b/tests/elements/test-vaapicontext.c index 4b37a2cbdb..0085ca968b 100644 --- a/tests/elements/test-vaapicontext.c +++ b/tests/elements/test-vaapicontext.c @@ -50,6 +50,7 @@ typedef struct _CustomData VADisplay va_display; GstElement *pipeline; guintptr videoarea_handle[2]; + GstObject *gstvaapidisplay; } AppData; static void @@ -133,6 +134,18 @@ bus_sync_handler (GstBus * bus, GstMessage * msg, gpointer data) gst_println ("Got need context %s from %s", context_type, GST_MESSAGE_SRC_NAME (msg)); + if (g_strcmp0 (context_type, "gst.vaapi.Display") == 0) { + if (app->gstvaapidisplay) { + GstStructure *s; + + context = gst_context_new ("gst.vaapi.Display", FALSE); + s = gst_context_writable_structure (context); + gst_structure_set (s, "gst.vaapi.Display", + GST_TYPE_OBJECT, app->gstvaapidisplay, NULL); + } + break; + } + if (g_strcmp0 (context_type, "gst.vaapi.app.Display") != 0) break; @@ -156,6 +169,32 @@ bus_sync_handler (GstBus * bus, GstMessage * msg, gpointer data) (GST_MESSAGE_SRC (msg)), app->videoarea_handle[0]); break; } + case GST_MESSAGE_HAVE_CONTEXT:{ + const gchar *context_type; + const GstStructure *s; + GstContext *context = NULL; + const GValue *value; + + gst_message_parse_have_context (msg, &context); + if (!context) + break; + + context_type = gst_context_get_context_type (context); + gst_println ("Got have context %s from %s", context_type, + GST_MESSAGE_SRC_NAME (msg)); + + if (g_strcmp0 (context_type, "gst.vaapi.Display") != 0) + break; + s = gst_context_get_structure (context); + if (!s) + break; + value = gst_structure_get_value (s, "gst.vaapi.Display"); + if (!value) + break; + app->gstvaapidisplay = g_value_dup_object (value); + gst_println ("found display %s", GST_OBJECT_NAME (app->gstvaapidisplay)); + break; + } case GST_MESSAGE_EOS: gtk_main_quit (); break; @@ -308,6 +347,7 @@ main (gint argc, gchar ** argv) gtk_main (); gst_object_unref (app.pipeline); + gst_object_unref (app.gstvaapidisplay); /* there is no need to call vaTerminate() because it is done by the * vaapi elements */ return 0; From f9a57ccece4552a609b4660d2d3152611f52e0de Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 6 Dec 2017 16:11:25 -0500 Subject: [PATCH 3001/3781] Revert "vaapivideocontext: possible memleak when no bus attached" This reverts commit 0438a3e62660e64ed390b6bb83bfb560b91664aa. --- gst/vaapi/gstvaapivideocontext.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index a556a895f1..0646165d88 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -209,10 +209,8 @@ _gst_context_query (GstElement * element, const gchar * context_type) GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "posting `need-context' message"); msg = gst_message_new_need_context (GST_OBJECT_CAST (element), context_type); - if (!gst_element_post_message (element, msg)) { + if (!gst_element_post_message (element, msg)) GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "No bus attached"); - gst_message_unref (msg); - } /* * Whomever responds to the need-context message performs a From b0d41c5db8c29b3df2a5b23d3da55141d701b992 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 6 Dec 2017 16:11:46 -0500 Subject: [PATCH 3002/3781] videoconvert: gst_element_post_message() is transfer full on msg For this reson we need not to unref the message, even if it failed. --- gst/vaapi/gstvaapivideocontext.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 0646165d88..4c5a1d3c1f 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -243,7 +243,6 @@ _gst_vaapi_sink_find_context (GstElement * element) if (!gst_element_post_message (element, msg)) { _init_context_debug (); GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "No bus attached"); - gst_message_unref (msg); } return FALSE; From 54f1989bef31e40df480645db584900df8fc82c5 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Thu, 14 Dec 2017 14:53:27 +1100 Subject: [PATCH 3003/3781] Automatic update of common submodule From e8c7a71 to 3fa2c9e --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index e8c7a71bf3..3fa2c9e372 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit e8c7a71bf3e2ee48f682011bd63d64a8c78ea3b6 +Subproject commit 3fa2c9e372bceec30be91e67fb02b6cb05bed493 From ce3593c0f6999b6ceb77c16360e61973e2a59945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 19 Dec 2017 16:01:10 +0000 Subject: [PATCH 3004/3781] meson: fix fallback for gstreamer-gl-1.0, it's now in -base --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index a6acda2c88..b54dd8994e 100644 --- a/meson.build +++ b/meson.build @@ -41,7 +41,7 @@ gstvideo_dep = dependency('gstreamer-video-1.0', version : gst_req, gstcodecparsers_dep = dependency('gstreamer-codecparsers-1.0', version : gst_req, fallback : ['gst-plugins-bad', 'gstcodecparsers_dep']) gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, - fallback : ['gst-plugins-bad', 'gstgl_dep'], required: false) + fallback : ['gst-plugins-base', 'gstgl_dep'], required: false) gmodule_dep = dependency('gmodule-2.0', required: false) libva_dep = dependency('libva', version: libva_req) From 2b9712ca2da02e80115dd85b96e3392f9274ad83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 10 Jan 2018 16:48:07 +0100 Subject: [PATCH 3005/3781] tests: y4mreader: fix incompatible cast Passed pointer in parse_int() are unsigned int (32 bits, unsigned) but they are dereferenced as a wider long (64 bits, signed). This may lead to memory corruption. --- tests/y4mreader.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/y4mreader.c b/tests/y4mreader.c index aeb1d80834..7dc711b6d8 100644 --- a/tests/y4mreader.c +++ b/tests/y4mreader.c @@ -27,7 +27,7 @@ * http://wiki.multimedia.cx/index.php?title=YUV4MPEG2 */ static inline gboolean -parse_int (const gchar * str, glong * out_value_ptr) +parse_int (const gchar * str, guint * out_value_ptr) { gint saved_errno; glong value; @@ -44,7 +44,10 @@ parse_int (const gchar * str, glong * out_value_ptr) value = strtol (str, NULL, 0); ret = (errno == 0); errno = saved_errno; - *out_value_ptr = value; + if (value > 0 && value <= G_MAXUINT) + *out_value_ptr = value; + else + ret = FALSE; return ret; } @@ -83,11 +86,11 @@ parse_header (Y4MReader * file) if ((header[j] != 0x20) && (header[j - 1] == 0x20)) { switch (header[j]) { case 'W': - if (!parse_int ((gchar *) & header[j], (glong *) & file->width)) + if (!parse_int ((gchar *) & header[j], &file->width)) return FALSE; break; case 'H': - if (!parse_int ((gchar *) & header[j], (glong *) & file->height)) + if (!parse_int ((gchar *) & header[j], &file->height)) return FALSE; break; case 'C': @@ -108,11 +111,11 @@ parse_header (Y4MReader * file) { guint num, den; - if (!parse_int ((gchar *) & header[j], (glong *) & num)) + if (!parse_int ((gchar *) & header[j], &num)) return FALSE; while ((header[j] != ':') && (j < i)) j++; - if (!parse_int ((gchar *) & header[j], (glong *) & den)) + if (!parse_int ((gchar *) & header[j], &den)) return FALSE; if (num <= 0 || den <= 0) { From 3ee955a2f282121a73be6b4b7c959e5d7c1d507e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 10 Jan 2018 16:59:56 +0100 Subject: [PATCH 3006/3781] tests: y4mreader: use int for fgetc Assigning the return value of fgetc to char truncates its value. It will not be possible to distinguish between EOF and a valid character. --- tests/y4mreader.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/y4mreader.c b/tests/y4mreader.c index 7dc711b6d8..caded8ad7a 100644 --- a/tests/y4mreader.c +++ b/tests/y4mreader.c @@ -55,9 +55,8 @@ parse_int (const gchar * str, guint * out_value_ptr) static gboolean parse_header (Y4MReader * file) { - gint i, j; + gint i, j, b; guint8 header[BUFSIZ]; - gint8 b; size_t s; gchar *str; @@ -185,9 +184,8 @@ y4m_reader_close (Y4MReader * file) static gboolean skip_frame_header (Y4MReader * file) { - gint i; + gint i, b; guint8 header[BUFSIZ]; - gint8 b; size_t s; memset (header, 0, BUFSIZ); From 66794c9bc9b2a834764d0e139e594badb305875b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 10 Jan 2018 17:06:53 +0100 Subject: [PATCH 3007/3781] tests: y4mreader: fix string state checkup str cannot be null in that moment, but it may be the end of string. --- tests/y4mreader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/y4mreader.c b/tests/y4mreader.c index caded8ad7a..5fa7dcb190 100644 --- a/tests/y4mreader.c +++ b/tests/y4mreader.c @@ -36,7 +36,7 @@ parse_int (const gchar * str, guint * out_value_ptr) if (!str) return FALSE; str += 1; - if (!str) + if (*str == '\0') return FALSE; saved_errno = errno; From 089b8982e9816def693890a96882f370ea287f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 10 Jan 2018 17:10:28 +0100 Subject: [PATCH 3008/3781] tests: test-filter: fix dereference before null check Null-checking op_info suggests that it may be null, but it has already been dereferenced on all paths leading to the check. There may be a null pointer dereference, or else the comparison against null is unnecessary. --- tests/test-filter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test-filter.c b/tests/test-filter.c index f83068273a..6fdc8b6e95 100644 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -152,13 +152,14 @@ error_cleanup: static void dump_operation (GstVaapiFilterOpInfo * op_info) { - GParamSpec *const pspec = op_info->pspec; + GParamSpec *pspec; GValue value = G_VALUE_INIT; gchar *value_str; if (!op_info) return; + pspec = op_info->pspec; g_print (" %s: ", g_param_spec_get_name (pspec)); g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_param_value_set_default (pspec, &value); From aed4088967eec97de81a1c914f87fdbae09a19e8 Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Fri, 8 Dec 2017 14:46:02 +0100 Subject: [PATCH 3009/3781] vaapipostproc: lock ensure_filter with postproc_lock gst_vaapipostproc_ensure_filter might free the allowed_srcpad_caps and allowed_sinkpad_caps. This can race with copying these caps in gst_vaapipostproc_transform_caps and lead to segfaults. The gst_vaapipostproc_transform_caps function already locks postproc_lock before copying the caps. Make sure that calls to gst_vaapipostproc_ensure_filter also acquire this lock. https://bugzilla.gnome.org/show_bug.cgi?id=791404 --- gst/vaapi/gstvaapipostproc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index e828741415..e0f6aebb25 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -306,7 +306,9 @@ gst_vaapipostproc_start (GstBaseTransform * trans) ds_reset (&postproc->deinterlace_state); if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (postproc))) return FALSE; + g_mutex_lock (&postproc->postproc_lock); gst_vaapipostproc_ensure_filter (postproc); + g_mutex_unlock (&postproc->postproc_lock); return TRUE; } @@ -1881,8 +1883,12 @@ cb_channels_init (GstVaapiPostproc * postproc) if (postproc->cb_channels) return; - if (!gst_vaapipostproc_ensure_filter (postproc)) + g_mutex_lock (&postproc->postproc_lock); + if (!gst_vaapipostproc_ensure_filter (postproc)) { + g_mutex_unlock (&postproc->postproc_lock); return; + } + g_mutex_unlock (&postproc->postproc_lock); filter_ops = postproc->filter_ops ? g_ptr_array_ref (postproc->filter_ops) : gst_vaapi_filter_get_operations (postproc->filter); From 7e05160aaada42e2ede1f639c46adeb6dbd60563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 1 Dec 2017 15:04:35 +0100 Subject: [PATCH 3010/3781] libs: egl: utils: use eglGetPlatformDisplay() eglGetDisplay() is currently broken in Mesa for Wayland. Also using eglGetDisplay() is rather fragile, and it is recommended to use eglGetPlatformDisplay() when possible. In order to do that, this patch uses the helper in GstGL. If gstreamer-vaapi is not compiled with GstGL support, eglGetDisplay() will be used. https://bugzilla.gnome.org/show_bug.cgi?id=790493 --- gst-libs/gst/vaapi/Makefile.am | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 15 ++++++++- gst-libs/gst/vaapi/gstvaapiutils_egl.c | 41 +++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapiutils_egl.h | 9 +++++- 4 files changed, 60 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index b29adf95c4..491208f92c 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -476,6 +476,7 @@ libgstvaapi_egl_la_CFLAGS = \ $(GMODULE_CFLAGS) \ $(GST_BASE_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ + $(GST_GL_CFLAGS) \ $(LIBVA_CFLAGS) \ $(LIBVA_WAYLAND_CFLAGS) \ $(EGL_CFLAGS) \ @@ -487,6 +488,7 @@ libgstvaapi_egl_la_LIBADD = \ $(GST_LIBS) \ $(GST_BASE_LIBS) \ $(GST_VIDEO_LIBS) \ + $(GST_GL_LIBS) \ $(EGL_LIBS) \ $(NULL) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index c4fdbc240a..884d0090a4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -100,6 +100,7 @@ gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_display, GstVaapiDisplay *native_display = NULL; GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display); EglDisplay *egl_display; + guint gl_platform = EGL_PLATFORM_UNKNOWN; const InitParams *params = (InitParams *) native_params; if (params->display) { @@ -118,7 +119,19 @@ gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_display, gst_vaapi_display_replace (&display->display, native_display); - egl_display = egl_display_new (GST_VAAPI_DISPLAY_NATIVE (display->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; + } + + egl_display = egl_display_new (GST_VAAPI_DISPLAY_NATIVE (display->display), + gl_platform); if (!egl_display) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c index 0f0390993a..db570ad943 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -22,6 +22,9 @@ #include "sysdeps.h" #include "gstvaapiutils_egl.h" +#if USE_GST_GL_HELPERS +# include +#endif #define DEBUG 1 #include "gstvaapidebug.h" @@ -534,6 +537,31 @@ egl_display_run (EglDisplay * display, EglContextRunFunc func, gpointer args) return TRUE; } +static gpointer +egl_get_display_from_native (guintptr native_display, guint gl_platform) +{ +#if USE_GST_GL_HELPERS + EGLDisplay ret; + GstGLDisplayType display_type = GST_GL_DISPLAY_TYPE_ANY; + + switch (gl_platform) { + case EGL_PLATFORM_X11: + display_type = GST_GL_DISPLAY_TYPE_X11; + break; + case EGL_PLATFORM_WAYLAND: + display_type = GST_GL_DISPLAY_TYPE_WAYLAND; + break; + default: + break; + } + + ret = gst_gl_display_egl_get_from_native (display_type, native_display); + if (ret != EGL_NO_DISPLAY) + return ret; +#endif + return eglGetDisplay ((EGLNativeDisplayType) native_display); +} + static gpointer egl_display_thread (gpointer data) { @@ -543,7 +571,9 @@ egl_display_thread (gpointer data) gchar **gl_apis, **gl_api; if (!display->base.is_wrapped) { - gl_display = display->base.handle.p = eglGetDisplay (gl_display); + gl_display = display->base.handle.p = + egl_get_display_from_native (display->base.handle.u, + display->gl_platform); if (!gl_display) goto error; if (!eglInitialize (gl_display, &major_version, &minor_version)) @@ -643,7 +673,7 @@ egl_display_finalize (EglDisplay * display) } static EglDisplay * -egl_display_new_full (gpointer handle, gboolean is_wrapped) +egl_display_new_full (gpointer handle, gboolean is_wrapped, guint platform) { EglDisplay *display; @@ -653,6 +683,7 @@ egl_display_new_full (gpointer handle, gboolean is_wrapped) display->base.handle.p = handle; display->base.is_wrapped = is_wrapped; + display->gl_platform = platform; if (!egl_display_init (display)) goto error; return display; @@ -666,11 +697,11 @@ error: } EglDisplay * -egl_display_new (gpointer native_display) +egl_display_new (gpointer native_display, guint platform) { g_return_val_if_fail (native_display != NULL, NULL); - return egl_display_new_full (native_display, FALSE); + return egl_display_new_full (native_display, FALSE, platform); } EglDisplay * @@ -678,7 +709,7 @@ egl_display_new_wrapped (EGLDisplay gl_display) { g_return_val_if_fail (gl_display != EGL_NO_DISPLAY, NULL); - return egl_display_new_full (gl_display, TRUE); + return egl_display_new_full (gl_display, TRUE, EGL_PLATFORM_UNKNOWN); } /* ------------------------------------------------------------------------- */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.h b/gst-libs/gst/vaapi/gstvaapiutils_egl.h index fa0820286b..2dcdf6836b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.h @@ -51,6 +51,12 @@ typedef struct egl_window_s EglWindow; #define GL_PROTO_END() ; #include "egl_vtable.h" +enum { + EGL_PLATFORM_UNKNOWN, + EGL_PLATFORM_X11, + EGL_PLATFORM_WAYLAND, +}; + union egl_handle_s { gpointer p; @@ -109,6 +115,7 @@ struct egl_display_s gchar *gl_version_string; gchar *gl_apis_string; guint gl_apis; /* EGL_*_BIT mask */ + guint gl_platform; GMutex mutex; GThread *gl_thread; @@ -187,7 +194,7 @@ struct egl_window_s G_GNUC_INTERNAL EglDisplay * -egl_display_new (gpointer native_display); +egl_display_new (gpointer native_display, guint gl_platform); G_GNUC_INTERNAL EglDisplay * From 8688e81d426b42aaa14ab18cd1c2dda087b9d478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 11 Jan 2018 11:48:02 +0100 Subject: [PATCH 3011/3781] plugins: remove dmabuf-import hack Remove the hack to check if an upstream element has enabled the property io-mode enabled as dmabuf-import. https://bugzilla.gnome.org/show_bug.cgi?id=792034 --- gst/vaapi/gstvaapipluginbase.c | 69 ---------------------------------- 1 file changed, 69 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index afb9a34a65..625a49b759 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -421,68 +421,6 @@ gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) return TRUE; } -/* Checks whether the supplied pad peer element supports DMABUF sharing */ -/* XXX: this is a workaround to the absence of any proposer way to - specify DMABUF memory capsfeatures or bufferpool option to downstream */ -static gboolean -has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad) -{ - GstPad *other_pad = NULL; - GstElement *element = NULL; - gchar *element_name = NULL; - gboolean is_dmabuf_capable = FALSE; - gint v; - - gst_object_ref (pad); - - for (;;) { - other_pad = gst_pad_get_peer (pad); - gst_object_unref (pad); - if (!other_pad) - break; - - element = gst_pad_get_parent_element (other_pad); - gst_object_unref (other_pad); - if (!element) - break; - - if (GST_IS_PUSH_SRC (element)) { - element_name = gst_element_get_name (element); - if (!element_name) - break; - - if ((sscanf (element_name, "v4l2src%d", &v) != 1) - && (sscanf (element_name, "camerasrc%d", &v) != 1)) - break; - - v = 0; - g_object_get (element, "io-mode", &v, NULL); - if (strncmp (element_name, "camerasrc", 9) == 0) - is_dmabuf_capable = v == 3; - else - is_dmabuf_capable = v == 5; /* "dmabuf-import" enum value */ - break; - } else if (GST_IS_BASE_TRANSFORM (element)) { - element_name = gst_element_get_name (element); - if (!element_name || sscanf (element_name, "capsfilter%d", &v) != 1) - break; - - pad = gst_element_get_static_pad (element, "sink"); - if (!pad) - break; - } else - break; - - g_free (element_name); - element_name = NULL; - g_clear_object (&element); - } - - g_free (element_name); - g_clear_object (&element); - return is_dmabuf_capable; -} - static gboolean gst_vaapi_buffer_pool_caps_is_equal (GstBufferPool * pool, GstCaps * newcaps) { @@ -531,13 +469,6 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, if (!reset_allocator (plugin->sinkpad_allocator, &vinfo)) goto bail; - if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) { - plugin->sinkpad_allocator = - gst_vaapi_dmabuf_allocator_new (plugin->display, &vinfo, - GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE, GST_PAD_SINK); - goto bail; - } - /* enable direct upload if upstream requests raw video */ if (gst_caps_is_video_raw (caps)) { usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD; From 7418d4e954cafc1b70fef3e9c1bb275502faaea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 17 Jan 2018 12:41:54 +0100 Subject: [PATCH 3012/3781] libs: utils: egl: add missing guards for GstGL --- gst-libs/gst/vaapi/gstvaapiutils_egl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c index db570ad943..17a6cd8911 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -22,7 +22,7 @@ #include "sysdeps.h" #include "gstvaapiutils_egl.h" -#if USE_GST_GL_HELPERS +#if USE_GST_GL_HELPERS && GST_GL_HAVE_PLATFORM_EGL # include #endif @@ -540,7 +540,7 @@ egl_display_run (EglDisplay * display, EglContextRunFunc func, gpointer args) static gpointer egl_get_display_from_native (guintptr native_display, guint gl_platform) { -#if USE_GST_GL_HELPERS +#if USE_GST_GL_HELPERS && GST_GL_HAVE_PLATFORM_EGL EGLDisplay ret; GstGLDisplayType display_type = GST_GL_DISPLAY_TYPE_ANY; From d26dc920214d3d3d0f615329cb9d09ca73ecf20a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 17 Jan 2018 12:42:12 +0100 Subject: [PATCH 3013/3781] build: meson: add missing GstGL dependency --- gst-libs/gst/vaapi/meson.build | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index debdfe9743..4053748a69 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -198,7 +198,12 @@ if USE_WAYLAND ] endif -gstlibvaapi_deps = [gstbase_dep, gstvideo_dep, gstcodecparsers_dep, libva_dep, gstvaapi_baseutils_dep] +gstlibvaapi_deps = [ gstbase_dep, + gstvideo_dep, + gstgl_dep, + gstcodecparsers_dep, + libva_dep, + gstvaapi_baseutils_dep ] if USE_DRM gstlibvaapi_deps += [libva_drm_dep, libdrm_dep, libudev_dep] endif From 9933dcb218ee8335a0042cbdce343228c5ee13b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 17 Jan 2018 17:26:24 +0100 Subject: [PATCH 3014/3781] plugins: use g_clear_object() to unref sinkpad_buffer_pool https://bugzilla.gnome.org/show_bug.cgi?id=792620 --- gst/vaapi/gstvaapipluginbase.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 625a49b759..189546bfb2 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -321,10 +321,8 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) gst_caps_replace (&plugin->sinkpad_caps, NULL); gst_video_info_init (&plugin->sinkpad_info); - if (plugin->sinkpad_buffer_pool) { - gst_object_unref (plugin->sinkpad_buffer_pool); - plugin->sinkpad_buffer_pool = NULL; - } + + g_clear_object (&plugin->sinkpad_buffer_pool); g_clear_object (&plugin->srcpad_buffer_pool); g_clear_object (&plugin->sinkpad_allocator); From 6efce291f681e4984eff1fbe6cf9ac5a5e167970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 17 Jan 2018 17:30:50 +0100 Subject: [PATCH 3015/3781] plugins: re-using buffer pool breaks renegotiation at propose_allocation() we should not reuse the proposed buffer, because it could break renegotiation. https://bugzilla.gnome.org/show_bug.cgi?id=792620 --- gst/vaapi/gstvaapipluginbase.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 189546bfb2..ee6f915ce5 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -806,22 +806,30 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, GstCaps *caps = NULL; GstBufferPool *pool = NULL; gboolean need_pool; + guint size = 0; gst_query_parse_allocation (query, &caps, &need_pool); if (!caps) goto error_no_caps; - /* FIXME re-using buffer pool breaks renegotiation */ - if (!ensure_sinkpad_buffer_pool (plugin, caps)) + if (!ensure_sinkpad_allocator (plugin, caps, &size)) return FALSE; if (need_pool) { - pool = plugin->sinkpad_buffer_pool; + pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, + BUFFER_POOL_SINK_MIN_BUFFERS, 0, + GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, + plugin->sinkpad_allocator); + if (!pool) + return FALSE; + gst_query_add_allocation_param (query, plugin->sinkpad_allocator, NULL); } - gst_query_add_allocation_pool (query, pool, plugin->sinkpad_buffer_size, + gst_query_add_allocation_pool (query, pool, size, BUFFER_POOL_SINK_MIN_BUFFERS, 0); + if (pool) + gst_object_unref (pool); gst_query_add_allocation_meta (query, GST_VAAPI_VIDEO_META_API_TYPE, NULL); gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); From f3650381c356885b6150fd9b0c8a97363b880c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 18 Jan 2018 13:10:59 +0100 Subject: [PATCH 3016/3781] vaapisink: check for display's color-balance properties Check for display's color-balance properties, available by the VA-API driver, before setting them. Also logs an info message of those unavailable properties. https://bugzilla.gnome.org/show_bug.cgi?id=792638 --- gst/vaapi/gstvaapisink.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index a4bea49425..8bd8303098 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -680,8 +680,10 @@ cb_sync_values_from_display (GstVaapiSink * sink, GstVaapiDisplay * display) for (i = 0; i < G_N_ELEMENTS (sink->cb_values); i++) { const guint cb_id = CB_HUE + i; - if (!gst_vaapi_display_has_property (display, cb_map[i].prop_name)) + if (!gst_vaapi_display_has_property (display, cb_map[i].prop_name)) { + GST_INFO_OBJECT (sink, "backend does not handle %s", cb_map[i].prop_name); continue; + } value = 0.0; g_object_get (display, cb_map[i].prop_name, &value, NULL); @@ -700,6 +702,10 @@ cb_sync_values_to_display (GstVaapiSink * sink, GstVaapiDisplay * display) const guint cb_id = CB_HUE + i; if (!(sink->cb_changed & (1U << cb_id))) continue; + if (!gst_vaapi_display_has_property (display, cb_map[i].prop_name)) { + GST_INFO_OBJECT (sink, "backend does not handle %s", cb_map[i].prop_name); + continue; + } g_object_set_property (G_OBJECT (display), cb_map[i].prop_name, cb_get_gvalue (sink, cb_id)); From ea9c52ea8f75ecf43ecbc38ecacd876364aea835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 18 Jan 2018 18:51:57 +0100 Subject: [PATCH 3017/3781] vaapipostproc: if no p-a-r in out caps define a range Instead of copying the pixel-aspect-ratio from the sink caps, define an open range for the src caps pixel-aspect-ratio. Later it will be defined. https://bugzilla.gnome.org/show_bug.cgi?id=790149 --- gst/vaapi/gstvaapipostprocutil.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 9c344b122f..c71a20be64 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -160,12 +160,9 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, ret = TRUE; to_par = gst_structure_get_value (outs, "pixel-aspect-ratio"); if (!to_par) { - g_value_init (&tpar, GST_TYPE_FRACTION); - gst_value_set_fraction (&tpar, GST_VIDEO_INFO_PAR_N (vinfo), - GST_VIDEO_INFO_PAR_D (vinfo)); + g_value_init (&tpar, GST_TYPE_FRACTION_RANGE); + gst_value_set_fraction_range_full (&tpar, 1, G_MAXINT, G_MAXINT, 1); to_par = &tpar; - - gst_structure_set_value (outs, "pixel-aspect-ratio", &tpar); } /* we have both PAR but they might not be fixated */ From da77fd5e2ef0d376b408a4bab7b2be6bc1d32a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 18 Jan 2018 18:53:29 +0100 Subject: [PATCH 3018/3781] vaapipostproc: remove spurious code This assignation is dead code, since gst_video_info_from_caps() set to 1 by default. https://bugzilla.gnome.org/show_bug.cgi?id=790149 --- gst/vaapi/gstvaapipostprocutil.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index c71a20be64..1cdc5c4970 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -173,8 +173,6 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, gint num, den; from_par_n = GST_VIDEO_INFO_PAR_N (vinfo); - if (from_par_n == 0) - from_par_n = 1; from_par_d = GST_VIDEO_INFO_PAR_D (vinfo); from_w = GST_VIDEO_INFO_WIDTH (vinfo); from_h = GST_VIDEO_INFO_HEIGHT (vinfo); From d897de9738d1587c51f9d465f4e5d5b627213a30 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Tue, 30 Jan 2018 12:56:49 +0000 Subject: [PATCH 3019/3781] vaapi: add NULL-sentinel to kernel_names The array needs to be NULL-terminated according to the gst_plugin_add_dependency() documentation. --- gst/vaapi/gstvaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 7939f9aaf5..0edec43c07 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -67,7 +67,7 @@ plugin_add_dependencies (GstPlugin * plugin) "DISPLAY", "WAYLAND_DISPLAY", NULL }; const gchar *kernel_paths[] = { "/dev/dri", NULL }; - const gchar *kernel_names[] = { "card", "render" }; + const gchar *kernel_names[] = { "card", "render", NULL }; /* features get updated upon changes in /dev/dri/card* */ gst_plugin_add_dependency (plugin, NULL, kernel_paths, kernel_names, From abd65bfff82796f3734693eb9bf0068a12446e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 30 Jan 2018 20:38:37 +0000 Subject: [PATCH 3020/3781] meson: use -fno-strict-aliasing where supported https://bugzilla.gnome.org/show_bug.cgi?id=769183 --- meson.build | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/meson.build b/meson.build index b54dd8994e..e1700eca8e 100644 --- a/meson.build +++ b/meson.build @@ -26,6 +26,11 @@ if cc.has_argument('-fvisibility=hidden') add_project_arguments('-fvisibility=hidden', language: 'c') endif +# Disable strict aliasing +if cc.has_argument('-fno-strict-aliasing') + add_project_arguments('-fno-strict-aliasing', language: 'c') +endif + # Mandatory GST deps libm = cc.find_library('m', required : false) gst_dep = dependency('gstreamer-1.0', version : gst_req, From 58043ff62c5116dc7af191c230404e70ebb6d9ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 5 Feb 2018 08:51:56 +0100 Subject: [PATCH 3021/3781] autotools: use -fno-strict-aliasing where supported https://bugzilla.gnome.org/show_bug.cgi?id=769183 --- configure.ac | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 2ca4c85b8d..8f1d072f53 100644 --- a/configure.ac +++ b/configure.ac @@ -969,6 +969,10 @@ else fi AC_SUBST([DEPRECATED_CFLAGS]) +dnl disable strict aliasing +AS_COMPILER_FLAG([-fno-strict-aliasing], [EXTRA_CFLAGS="-fno-strict-aliasing"]) +AC_SUBST(EXTRA_CFLAGS) + dnl every flag in GST_OPTION_CFLAGS and GST_OPTION_CXXFLAGS can be overridden dnl at make time with e.g. make ERROR_CFLAGS="" GST_OPTION_CFLAGS="\$(WARNING_CFLAGS) \$(ERROR_CFLAGS) \$(DEBUG_CFLAGS) \$(PROFILE_CFLAGS) \$(DEPRECATED_CFLAGS)" @@ -979,7 +983,7 @@ dnl prefer internal headers to already installed ones dnl also add builddir include for enumtypes and marshal dnl add GST_OPTION_CFLAGS, but overridable GST_CFLAGS="$GST_CFLAGS -DGST_USE_UNSTABLE_API" -GST_CFLAGS="$GST_CFLAGS $GLIB_EXTRA_CFLAGS \$(GST_OPTION_CFLAGS)" +GST_CFLAGS="$GST_CFLAGS $EXTRA_CFLAGS $GLIB_EXTRA_CFLAGS \$(GST_OPTION_CFLAGS)" AC_SUBST([GST_CFLAGS]) dnl LDFLAGS really should only contain flags, not libs - they get added before From 76dbc3e971a7a3416544df0ada1ff9d219c1c30e Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Fri, 2 Feb 2018 08:54:00 +0000 Subject: [PATCH 3022/3781] vaapisink: don't mask button events for foreign windows Don't subscribe to button press events when using a foreing window, because the user created window would trap those events, preveting the show of frames. https://bugzilla.gnome.org/show_bug.cgi?id=791615 --- gst/vaapi/gstvaapisink.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 8bd8303098..c57b1261c9 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -448,9 +448,11 @@ gst_vaapisink_x11_pre_start_event_thread (GstVaapiSink * sink) { GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11 (GST_VAAPI_PLUGIN_BASE_DISPLAY (sink)); - static const int x11_event_mask = (KeyPressMask | KeyReleaseMask | - ButtonPressMask | ButtonReleaseMask | PointerMotionMask | - ExposureMask | StructureNotifyMask); + int x11_event_mask = (KeyPressMask | KeyReleaseMask | + PointerMotionMask | ExposureMask | StructureNotifyMask); + + if (!sink->foreign_window) + x11_event_mask |= ButtonPressMask | ButtonReleaseMask; if (sink->window) { gst_vaapi_display_lock (GST_VAAPI_DISPLAY (display)); From 8855a926bedc3ea710eb5f30bc445a7200cf3c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 7 Feb 2018 09:06:46 +0100 Subject: [PATCH 3023/3781] vaapivideomemory: remove unused macro GST_VAAPI_VIDEO_ALLOCATOR_NAME was added in commit 5b11b8332 but it was never used, since the native VA-API allocator name has been GST_VAAPI_VIDEO_MEMORY_NAME. This patch removes GST_VAAPI_VIDEO_ALLOCATOR_NAME macro. https://bugzilla.gnome.org/show_bug.cgi?id=789476 --- gst/vaapi/gstvaapivideomemory.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index db31b69613..be18bbfe1c 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -169,8 +169,6 @@ gst_vaapi_video_memory_sync (GstVaapiVideoMemory * mem); #define GST_VAAPI_IS_VIDEO_ALLOCATOR(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_ALLOCATOR)) -#define GST_VAAPI_VIDEO_ALLOCATOR_NAME "GstVaapiVideoAllocator" - /** * GstVaapiVideoAllocator: * From 448105578bd6b31d8c3992f137389a56132bd551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 7 Feb 2018 09:13:26 +0100 Subject: [PATCH 3024/3781] plugins: handle vaapi allocator in allocation query In propose_allocation() if the numer of allocation params is zero, the system's allocator is added first, and lastly the native VA-API allocator. In decide_allocation(), the allocations params in query are travered, looking for a native VA-API allocator. If it is found, it is reused as src pad allocator. Otherwise, a new allocator is instantiated and appended in the query. https://bugzilla.gnome.org/show_bug.cgi?id=789476 --- gst/vaapi/gstvaapipluginbase.c | 61 +++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index ee6f915ce5..7bc7178dad 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -806,7 +806,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, GstCaps *caps = NULL; GstBufferPool *pool = NULL; gboolean need_pool; - guint size = 0; + guint size = 0, n_allocators; gst_query_parse_allocation (query, &caps, &need_pool); if (!caps) @@ -822,10 +822,23 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, plugin->sinkpad_allocator); if (!pool) return FALSE; - - gst_query_add_allocation_param (query, plugin->sinkpad_allocator, NULL); } + /* Set sinkpad allocator as the last allocation param. + * + * If there's none, set system's allocator first and VAAPI allocator + * second + */ + n_allocators = gst_query_get_n_allocation_params (query); + if (n_allocators == 0) { + GstAllocator *allocator; + + allocator = gst_allocator_find (GST_ALLOCATOR_SYSMEM); + gst_query_add_allocation_param (query, allocator, NULL); + gst_object_unref (allocator); + } + gst_query_add_allocation_param (query, plugin->sinkpad_allocator, NULL); + gst_query_add_allocation_pool (query, pool, size, BUFFER_POOL_SINK_MIN_BUFFERS, 0); if (pool) @@ -861,8 +874,9 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GstCaps *caps = NULL; GstBufferPool *pool; GstVideoInfo vi; - guint size, min, max, pool_options; - gboolean update_pool = FALSE, update_allocator = FALSE; + guint i, size, min, max, pool_options, num_allocators; + gint index_allocator; + gboolean update_pool = FALSE; #if (USE_GLX || USE_EGL) guint idx; #endif @@ -911,8 +925,25 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, goto error_invalid_caps; gst_video_info_force_nv12_if_encoded (&vi); - if (gst_query_get_n_allocation_params (query) > 0) - update_allocator = TRUE; + index_allocator = -1; + num_allocators = gst_query_get_n_allocation_params (query); + for (i = 0; i < num_allocators; i++) { + GstAllocator *allocator = NULL; + + gst_query_parse_nth_allocation_param (query, i, &allocator, NULL); + if (!allocator) + continue; + if (g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) == 0) { + GST_DEBUG_OBJECT (plugin, "found vaapi allocator in query %" + GST_PTR_FORMAT, allocator); + index_allocator = i; + if (plugin->srcpad_allocator) + gst_object_unref (plugin->srcpad_allocator); + plugin->srcpad_allocator = allocator; + break; + } + gst_object_unref (allocator); + } if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); @@ -955,11 +986,17 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, else gst_query_add_allocation_pool (query, pool, size, min, max); - if (update_allocator) - gst_query_set_nth_allocation_param (query, 0, plugin->srcpad_allocator, - NULL); - else - gst_query_add_allocation_param (query, plugin->srcpad_allocator, NULL); + /* allocator might be updated by ensure_srcpad_allocator() */ + if (plugin->srcpad_allocator) { + if (index_allocator > 0) { + gst_query_set_nth_allocation_param (query, index_allocator, + plugin->srcpad_allocator, NULL); + } else { + GST_DEBUG_OBJECT (plugin, "adding allocator in query %" GST_PTR_FORMAT, + plugin->srcpad_allocator); + gst_query_add_allocation_param (query, plugin->srcpad_allocator, NULL); + } + } g_clear_object (&plugin->srcpad_buffer_pool); plugin->srcpad_buffer_pool = pool; From 7e28f455507fd2c418393142f46a6ab83a98c6ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 8 Feb 2018 19:22:17 +0000 Subject: [PATCH 3025/3781] meson: make version numbers ints and fix int/string comparison WARNING: Trying to compare values of different types (str, int). The result of this is undefined and will become a hard error in a future Meson release. --- meson.build | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/meson.build b/meson.build index e1700eca8e..e22b075705 100644 --- a/meson.build +++ b/meson.build @@ -6,11 +6,11 @@ project('gstreamer-vaapi', 'c', gst_version = meson.project_version() version_arr = gst_version.split('.') -gst_version_major = version_arr[0] -gst_version_minor = version_arr[1] -gst_version_micro = version_arr[2] -if version_arr.length() == 4 - gst_version_nano = version_arr[3] +gst_version_major = version_arr[0].to_int() +gst_version_minor = version_arr[1].to_int() +gst_version_micro = version_arr[2].to_int() + if version_arr.length() == 4 + gst_version_nano = version_arr[3].to_int() else gst_version_nano = 0 endif @@ -156,7 +156,7 @@ api_version = '1.0' soversion = 0 # maintaining compatibility with the previous libtool versioning # current = minor * 100 + micro -libversion = '@0@.@1@.0'.format(soversion, gst_version_minor.to_int() * 100 + gst_version_micro.to_int()) +libversion = '@0@.@1@.0'.format(soversion, gst_version_minor * 100 + gst_version_micro) plugins_install_dir = '@0@/gstreamer-1.0'.format(get_option('libdir')) From 19fe5c4d07e48dce1a64085f96653cad4498db2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 12 Feb 2018 19:00:36 +0100 Subject: [PATCH 3026/3781] plugins: update mesa's vendor string in whitelist Mesa has updated its VA-API Gallium driver vendor string: https://cgit.freedesktop.org/mesa/mesa/commit/?id=5db29d62ce1fefa3f2ee6e4a4688576fde4bde4a This patch tries to cover both, the old and the new one. https://bugzilla.gnome.org/show_bug.cgi?id=793386 --- gst/vaapi/gstvaapipluginutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 9e7330590e..0ff46bc01b 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -836,7 +836,7 @@ gst_vaapi_driver_is_whitelisted (GstVaapiDisplay * display) guint i; static const gchar *whitelist[] = { "Intel i965 driver", - "mesa gallium vaapi", + "mesa gallium", NULL }; From c653cb55f9a97d1bf6d3fc1d0ae30dcd958174a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 12 Feb 2018 17:53:58 +0100 Subject: [PATCH 3027/3781] vaapi: register vaapisink as marginal on wayland vaapsink, when used with the Intel VA-API driver, tries to display surfaces with format NV12, which are handled correctly by Weston. Nonetheless, COGL cannot display YUV surfaces, making fail pipelines on mutter. This shall be solved either by COGL or by making the driver to paint RGB surfaces. In the meanwhile, let's just demote vaapisink as marginal when the Wayland environment is detected, no matter if it is Weston. https://bugzilla.gnome.org/show_bug.cgi?id=775698 --- gst/vaapi/gstvaapi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 0edec43c07..9a82454406 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -210,6 +210,7 @@ plugin_init (GstPlugin * plugin) { GstVaapiDisplay *display; GArray *decoders; + guint rank; plugin_add_dependencies (plugin); @@ -234,8 +235,11 @@ plugin_init (GstPlugin * plugin) gst_element_register (plugin, "vaapidecodebin", GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); - gst_element_register (plugin, "vaapisink", - GST_RANK_PRIMARY, GST_TYPE_VAAPISINK); + rank = GST_RANK_PRIMARY; + if (g_getenv ("WAYLAND_DISPLAY")) + rank = GST_RANK_MARGINAL; + gst_element_register (plugin, "vaapisink", rank, GST_TYPE_VAAPISINK); + #if USE_ENCODERS gst_vaapiencode_register (plugin, display); #endif From a0b0728b6b19d5a783cdc578acfd61150dd23fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 15 Feb 2018 18:15:33 +0000 Subject: [PATCH 3028/3781] vaapi: dist new header --- gst/vaapi/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 610acd147f..b299ac98a2 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -61,6 +61,7 @@ libgstvaapi_source_c = \ libgstvaapi_source_h = \ gstcompat.h \ + gstvaapi.h \ gstvaapidecode.h \ gstvaapipluginbase.h \ gstvaapipluginutil.h \ From a8f5e135bfac0c9eb5d5e48bfe2073aa11a57d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 15 Feb 2018 17:39:16 +0000 Subject: [PATCH 3029/3781] Release 1.13.1 --- Makefile.am | 1 + NEWS | 676 ++++--------------------------------------- configure.ac | 14 +- gstreamer-vaapi.doap | 50 ++++ meson.build | 2 +- 5 files changed, 117 insertions(+), 626 deletions(-) diff --git a/Makefile.am b/Makefile.am index a915de0fdf..609c7e3990 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,4 +24,5 @@ EXTRA_DIST = \ $(shell find "$(top_srcdir)" -type f -name meson.build ! -path "$(top_srcdir)/$(PACKAGE_TARNAME)-*" ) \ meson_options.txt +-include $(top_srcdir)/common/release.mak -include $(top_srcdir)/git.mk diff --git a/NEWS b/NEWS index 74fb1eaeb8..385e4b6315 100644 --- a/NEWS +++ b/NEWS @@ -1,20 +1,18 @@ -# GStreamer 1.12 Release Notes +# GStreamer 1.14 Release Notes -GStreamer 1.12.0 was originally released on 4th May 2017. +GStreamer 1.14.0 has not been released yet. It is scheduled for release +in late February / early March 2018. -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! +There are unstable pre-releases available for testing and development purposes. +The latest pre-release is version 1.13.1 and was released on 15 February 2018. -As always, this release is again packed with new features, bug fixes and other -improvements. - -See [https://gstreamer.freedesktop.org/releases/1.12/][latest] for the latest +See [https://gstreamer.freedesktop.org/releases/1.14/][latest] for the latest version of this document. -*Last updated: Thursday 4 May 2017, 11:00 UTC [(log)][gitlog]* +*Last updated: Thursday 15 February 2018, 16:30 UTC [(log)][gitlog]* -[latest]: https://gstreamer.freedesktop.org/releases/1.12/ -[gitlog]: https://cgit.freedesktop.org/gstreamer/www/log/src/htdocs/releases/1.12/release-notes-1.12.md +[latest]: https://gstreamer.freedesktop.org/releases/1.14/ +[gitlog]: https://cgit.freedesktop.org/gstreamer/www/log/src/htdocs/releases/1.14/release-notes-1.14.md ## Introduction @@ -26,684 +24,127 @@ improvements. ## Highlights -- new `msdk` plugin for Intel's Media SDK for hardware-accelerated video - encoding and decoding on Intel graphics hardware on Windows or Linux. - -- `x264enc` can now use multiple x264 library versions compiled for different - bit depths at runtime, to transparently provide support for multiple bit - depths. - -- `videoscale` and `videoconvert` now support multi-threaded scaling and - conversion, which is particularly useful with higher resolution video. - -- `h264parse` will now automatically insert AU delimiters if needed when - outputting byte-stream format, which improves standard compliance and - is needed in particular for HLS playback on iOS/macOS. - -- `rtpbin` has acquired bundle support for incoming streams +- this section will be completed shortly ## Major new features and changes ### Noteworthy new API -- The video library gained support for a number of new video formats: - - - `GBR_12LE`, `GBR_12BE`, `GBRA_12LE`, `GBRA_12BE` (planar 4:4:4 RGB/RGBA, 12 bits per channel) - - `GBRA_10LE`, `GBRA_10BE` (planar 4:4:4:4 RGBA, 10 bits per channel) - - `GBRA` (planar 4:4:4:4 ARGB, 8 bits per channel) - - `I420_12BE`, `I420_12LE` (planar 4:2:0 YUV, 12 bits per channel) - - `I422_12BE`,`I422_12LE` (planar 4:2:2 YUV, 12 bits per channel) - - `Y444_12BE`, `Y444_12LE` (planar 4:4:4 YUV, 12 bits per channel) - - `VYUY` (another packed 4:2:2 YUV format) - -- The high-level `GstPlayer` API was extended with functions for taking video - snapshots and enabling accurate seeking. It can optionally also use the - still-experimental `playbin3` element now. +- this section will be filled in shortly ### New Elements -- msdk: new plugin for Intel's Media SDK for hardware-accelerated video encoding - and decoding on Intel graphics hardware on Windows or Linux. This includes - an H.264 encoder/decoder (`msdkh264dec`, `msdkh264enc`), - an H.265 encoder/decoder (`msdkh265dec`, `msdkh265enc`), - an MJPEG encoder/encoder (`msdkmjpegdec`, `msdkmjpegenc`), - an MPEG-2 video encoder (`msdkmpeg2enc`) and a VP8 encoder (`msdkvp8enc`). - -- `iqa` is a new Image Quality Assessment plugin based on [DSSIM][dssim], - similar to the old (unported) videomeasure element. - -- The `faceoverlay` element, which allows you to overlay SVG graphics over - a detected face in a video stream, has been ported from 0.10. - -- our `ffmpeg` wrapper plugin now exposes/maps the ffmpeg Opus audio decoder - (`avdec_opus`) as well as the GoPro CineForm HD / CFHD decoder (`avdec_cfhd`), - and also a parser/writer for the IVF format (`avdemux_ivf` and `avmux_ivf`). - -- `audiobuffersplit` is a new element that splits raw audio buffers into - equal-sized buffers - -- `audiomixmatrix` is a new element that mixes N:M audio channels according to - a configured mix matrix. - -- The `timecodewait` element got renamed to `avwait` and can operate in - different modes now. - -- The `opencv` video processing plugin has gained a new `dewarp` element that - dewarps fisheye images. - -- `ttml` is a new plugin for parsing and rendering subtitles in Timed Text - Markup Language (TTML) format. For the time being these elements will not - be autoplugged during media playback however, unless the `GST_TTML_AUTOPLUG=1` - environment variable is set. Only the EBU-TT-D profile is supported at this - point. - -[dssim]: https://github.com/pornel/dssim +- this section will be filled in shortly ### New element features and additions -- `x264enc` can now use multiple x264 library versions compiled for different - bit depths at runtime, to transparently provide support for multiple bit - depths. A new configure parameter `--with-x264-libraries` has been added to - specify additional paths to look for additional x264 libraries to load. - Background is that the libx264 library is always compile for one specific - bit depth and the `x264enc` element would simply support the depth supported - by the underlying library. Now we can support multiple depths. +- this section will be filled in shortly -- `x264enc` also picks up the interlacing mode automatically from the input - caps now and passed interlacing/TFF information correctly to the library. - -- `videoscale` and `videoconvert` now support multi-threaded scaling and - conversion, which is particularly useful with higher resolution video. - This has to be enabled explicitly via the `"n-threads"` property. - -- `videorate`'s new `"rate"` property lets you set a speed factor - on the output stream - -- `splitmuxsink`'s buffer collection and scheduling was rewritten to make - processing and splitting deterministic; before it was possible for a buffer - to end up in a different file chunk in different runs. `splitmuxsink` also - gained a new `"format-location-full"` signal that works just like the existing - `"format-location"` signal only that it is also passed the primary stream's - first buffer as argument, so that it is possible to construct the file name - based on metadata such as the buffer timestamp or any GstMeta attached to - the buffer. The new `"max-size-timecode"` property allows for timecode-based - splitting. `splitmuxsink` will now also automatically start a new file if the - input caps change in an incompatible way. - -- `fakesink` has a new `"drop-out-of-segment"` property to not drop - out-of-segment buffers, which is useful for debugging purposes. - -- `identity` gained a `"ts-offset"` property. - -- both `fakesink` and `identity` now also print what kind of metas are attached - to buffers when printing buffer details via the `"last-message"` property - used by `gst-launch-1.0 -v`. - -- multiqueue: made `"min-interleave-time"` a configurable property. - -- video nerds will be thrilled to know that `videotestsrc`'s snow is now - deterministic. `videotestsrc` also gained some new properties to make the - ball pattern based on system time, and invert colours each second - (`"animation-mode"`, `"motion"`, and `"flip"` properties). - -- `oggdemux` reverse playback should work again now. You're welcome. - -- `playbin3` and `urisourcebin` now have buffering enabled by default, and - buffering message aggregation was fixed. - -- `tcpclientsrc` now has a `"timeout"` property - -- `appsink` has gained support for buffer lists. For backwards compatibility - reasons users need to enable this explicitly with `gst_app_sink_set_buffer_list_support()`, - however. Once activated, a pulled `GstSample` can contain either a buffer - list or a single buffer. - -- `splitmuxsrc` reverse playback was fixed and handling of sparse streams, such - as subtitle tracks or metadata tracks, was improved. - -- `matroskamux` has acquired support for muxing G722 audio; it also marks all - buffers as keyframes now when streaming only audio, so that `tcpserversink` - will behave properly with audio-only streams. - -- `qtmux` gained support for ProRes 4444 XQ, HEVC/H.265 and CineForm (GoPro) formats, - and generally writes more video stream-related metadata into the track headers. - It is also allows configuration of the maximum interleave size in bytes and - time now. For fragmented mp4 we always write the `tfdt` atom now as required - by the DASH spec. - -- `qtdemux` supports FLAC, xvid, mp2, S16L and CineForm (GoPro) tracks now, and - generally tries harder to extract more video-related information from track - headers, such as colorimetry or interlacing details. It also received a - couple of fixes for the scenario where upstream operates in TIME format and - feeds chunks to qtdemux (e.g. DASH or MSE). - -- `audioecho` has two new properties to apply a delay only to certain channels - to create a surround effect, rather than an echo on all channels. This is - useful when upmixing from stereo, for example. The `"surround-delay"` property - enables this, and the `"surround-mask"` property controls which channels - are considered surround sound channels in this case. - -- `webrtcdsp` gained various new properties for gain control and also exposes - voice activity detection now, in which case it will post `"voice-activity"` - messages on the bus whenever the voice detection status changes. - -- The `decklink` capture elements for Blackmagic Decklink cards have seen a - number of improvements: - - - `decklinkvideosrc` will post a warning message on "no signal" and an info - message when the signal lock has been (re)acquired. There is also a new - read-only `"signal"` property that can be used to query the signal lock - status. The `GAP` flag will be set on buffers that are captured without - a signal lock. The new `drop-no-signal-frames` will make `decklinkvideosrc` - drop all buffers that have been captured without an input signal. The - `"skip-first-time"` property will make the source drop the first few - buffers, which is handy since some devices will at first output buffers - with the wrong resolution before they manage to figure out the right input - format and decide on the actual output caps. - - - `decklinkaudiosrc` supports more than just 2 audio channels now. - - - The capture sources no longer use the "hardware" timestamps which turn - out to be useless and instead just use the pipeline clock directly. - -- `srtpdec` now also has a readonly `"stats"` property, just like `srtpenc`. - -- `rtpbin` gained RTP bundle support, as used by e.g. WebRTC. The first - rtpsession will have a `rtpssrcdemux` element inside splitting the streams - based on their SSRC and potentially dispatch to a different rtpsession. - Because retransmission SSRCs need to be merged with the corresponding media - stream the `::on-bundled-ssrc` signal is emitted on `rtpbin` so that the - application can find out to which session the SSRC belongs. - -- `rtprtxqueue` gained two new properties exposing retransmission - statistics (`"requests"` and `"fulfilled-requests"`) - -- `kmssink` will now use the preferred mode for the monitor and render to the - base plane if nothing else has set a mode yet. This can also be done forcibly - in any case via the new `"force-modesetting"` property. Furthermore, `kmssink` - now allows only the supported connector resolutions as input caps in order to - avoid scaling or positioning of the input stream, as `kmssink` can't know - whether scaling or positioning would be more appropriate for the use case at - hand. - -- `waylandsink` can now take DMAbuf buffers as input in the presence - of a compatible Wayland compositor. This enables zero-copy transfer - from a decoder or source that outputs DMAbuf. - -- `udpsrc` can be bound to more than one interface when joining a - multicast group, this is done by giving a comma separate list of - interfaces such as multicast-iface="eth0,eth1". - -### Plugin moves - -- `dataurisrc` moved from gst-plugins-bad to core - -- The `rawparse` plugin containing the `rawaudioparse` and `rawvideoparse` - elements moved from gst-plugins-bad to gst-plugins-base. These elements - supersede the old `videoparse` and `audioparse` elements. They work the - same, with just some minor API changes. The old legacy elements still - exist in gst-plugins-bad, but may be removed at some point in the future. - -- `timecodestamper` is an element that attaches time codes to video buffers - in form of `GstVideoTimeCodeMeta`s. It had a `"clock-source"` property - which has now been removed because it was fairly useless in practice. It - gained some new properties however: the `"first-timecode"` property can - be used to set the inital timecode; alternatively `"first-timecode-to-now"` - can be set, and then the current system time at the time the first buffer - arrives is used as base time for the time codes. +### Plugin and library moves +- this section will be filled in shortly ### Plugin removals -- The `mad` mp1/mp2/mp3 decoder plugin was removed from gst-plugins-ugly, - as libmad is GPL licensed, has been unmaintained for a very long time, and - there are better alternatives available. Use the `mpg123audiodec` element - from the `mpg123` plugin in gst-plugins-ugly instead, or `avdec_mp3` from - the `gst-libav` module which wraps the ffmpeg library. We expect that we - will be able to move mp3 decoding to gst-plugins-good in the next cycle - seeing that most patents around mp3 have expired recently or are about to - expire. +- this section will be filled in shortly -- The `mimic` plugin was removed from gst-plugins-bad. It contained a decoder - and encoder for a video codec used by MSN messenger many many years ago (in - a galaxy far far away). The underlying library is unmaintained and no one - really needs to use this codec any more. Recorded videos can still be played - back with the MIMIC decoder in gst-libav. ## Miscellaneous API additions -- Request pad name templates passed to `gst_element_request_pad()` may now - contain multiple specifiers, such as e.g. `src_%u_%u`. - -- [`gst_buffer_iterate_meta_filtered()`][buffer-iterate-meta-filtered] is a - variant of `gst_buffer_iterate_meta()` that only returns metas of the - requested type and skips all other metas. - -- [`gst_pad_task_get_state()`][pad-task-get-state] gets the current state of - a task in a thread-safe way. - -- [`gst_uri_get_media_fragment_table()`][uri-get-fragment-table] provides the - media fragments of an URI as a table of key=value pairs. - -- [`gst_print()`][print], [`gst_println()`][println], [`gst_printerr()`][printerr], - and [`gst_printerrln()`][printerrln] can be used to print to stdout or stderr. - These functions are similar to `g_print()` and `g_printerr()` but they also - support all the additional format specifiers provided by the GStreamer - logging system, such as e.g. `GST_PTR_FORMAT`. - -- a `GstParamSpecArray` has been added, for elements who want to have array - type properties, such as the `audiomixmatrix` element for example. There are - also two new functions to set and get properties of this type from bindings: - - gst_util_set_object_array() - - gst_util_get_object_array() - -- various helper functions have been added to make it easier to set or get - GstStructure fields containing caps-style array or list fields from language - bindings (which usually support GValueArray but don't know about the GStreamer - specific fundamental types): - - [`gst_structure_get_array()`][get-array] - - [`gst_structure_set_array()`][set-array] - - [`gst_structure_get_list()`][get-list] - - [`gst_structure_set_list()`][set-list] - -- a new ['dynamic type' registry factory type][dynamic-type] was added to - register dynamically loadable GType types. This is useful for automatically - loading enum/flags types that are used in caps, such as for example the - `GstVideoMultiviewFlagsSet` type used in multiview video caps. - -- there is a new [`GstProxyControlBinding`][proxy-control-binding] for use - with GstController. This allows proxying the control interface from one - property on one GstObject to another property (of the same type) in another - GstObject. So e.g. in parent-child relationship, one may need to call - `gst_object_sync_values()` on the child and have a binding (set elsewhere) - on the parent update the value. This is used in `glvideomixer` and `glsinkbin` - for example, where `sync_values()` on the child pad or element will call - `sync_values()` on the exposed bin pad or element. - - Note that this doesn't solve GObject property forwarding, that must - be taken care of by the implementation manually or using GBinding. - -- `gst_base_parse_drain()` has been made public for subclasses to use. - -- `gst_base_sink_set_drop_out_of_segment()' can be used by subclasses to - prevent GstBaseSink from dropping buffers that fall outside of the segment. - -- [`gst_calculate_linear_regression()`][calc-lin-regression] is a new utility - function to calculate a linear regression. - -- [`gst_debug_get_stack_trace`][get-stack-trace] is an easy way to retrieve a - stack trace, which can be useful in tracer plugins. - -- allocators: the dmabuf allocator is now sub-classable, and there is a new - `GST_CAPS_FEATURE_MEMORY_DMABUF` define. - -- video decoder subclasses can use the newly-added function - `gst_video_decoder_allocate_output_frame_with_params()` to - pass a `GstBufferPoolAcquireParams` to the buffer pool for - each buffer allocation. - -- the video time code API has gained a dedicated [`GstVideoTimeCodeInterval`][timecode-interval] - type plus related API, including functions to add intervals to timecodes. - -- There is a new `libgstbadallocators-1.0` library in gst-plugins-bad, which - may go away again in future releases once the `GstPhysMemoryAllocator` - interface API has been validated by more users and was moved to - `libgstallocators-1.0` from gst-plugins-base. - -[timecode-interval]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideo.html#gst-video-time-code-interval-new -[buffer-iterate-meta-filtered]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstBuffer.html#gst-buffer-iterate-meta-filtered -[pad-task-get-state]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPad.html#gst-pad-task-get-state -[uri-get-fragment-table]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstUri.html#gst-uri-get-media-fragment-table -[print]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-print -[println]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-println -[printerr]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-printerr -[printerrln]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstInfo.html#gst-printerrln -[get-array]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstStructure.html#gst-structure-get-array -[set-array]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstStructure.html#gst-structure-set-array -[get-list]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstStructure.html#gst-structure-get-list -[set-list]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstStructure.html#gst-structure-set-list -[dynamic-type]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstDynamicTypeFactory.html -[proxy-control-binding]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/gstreamer-libs-GstProxyControlBinding.html -[calc-lin-regression]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstUtils.html#gst-calculate-linear-regression -[get-stack-trace]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstUtils.html#gst-debug-get-stack-trace +- this section will be filled in shortly ### GstPlayer -New API has been added to: - - - get the number of audio/video/subtitle streams: - - `gst_player_media_info_get_number_of_streams()` - - `gst_player_media_info_get_number_of_video_streams()` - - `gst_player_media_info_get_number_of_audio_streams()` - - `gst_player_media_info_get_number_of_subtitle_streams()` - - - enable accurate seeking: `gst_player_config_set_seek_accurate()` - and `gst_player_config_get_seek_accurate()` - - - get a snapshot image of the video in RGBx, BGRx, JPEG, PNG or - native format: [`gst_player_get_video_snapshot()`][snapshot] - - - selecting use of a specific video sink element - ([`gst_player_video_overlay_video_renderer_new_with_sink()`][renderer-with-vsink]) - - - If the environment variable `GST_PLAYER_USE_PLAYBIN3` is set, GstPlayer will - use the still-experimental `playbin3` element and the `GstStreams` API for - playback. - -[snapshot]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-gstplayer.html#gst-player-get-video-snapshot -[renderer-with-vsink]: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-gstplayer-videooverlayvideorenderer.html#gst-player-video-overlay-video-renderer-new-with-sink +- this section will be filled in shortly ## Miscellaneous changes -- video caps for interlaced video may contain an optional `"field-order"` field - now in the case of `interlaced-mode=interleaved` to signal that the field - order is always the same throughout the stream. This is useful to signal to - muxers such as mp4mux. The new field is parsed from/to `GstVideoInfo` of course. - -- video decoder and video encoder base classes try harder to proxy - interlacing, colorimetry and chroma-site related fields in caps properly. - -- The buffer stored in the `PROTECTION` events is now left unchanged. This is a - change of behaviour since 1.8, especially for the mssdemux element which used to - decode the base64 parsed data wrapped in the protection events emitted by the - demuxer. - -- `PROTECTION` events can now be injected into the pipeline from the application; - source elements deriving from GstBaseSrc will forward those downstream now. - -- The DASH demuxer is now correctly parsing the MSPR-2.0 ContentProtection nodes - and emits Protection events accordingly. Applications relying on those events - might need to decode the base64 data stored in the event buffer before using it. - -- The registry can now also be disabled by setting the environment variable - `GST_REGISTRY_DISABLE=yes`, with similar effect as the `GST_DISABLE_REGISTRY` - compile time switch. - -- Seeking performance with gstreamer-vaapi based decoders was improved. It would - recreate the decoder and surfaces on every seek which can be quite slow. - -- more robust handling of input caps changes in videoaggregator-based elements - such as `compositor`. - -- Lots of adaptive streaming-related fixes across the board (DASH, MSS, HLS). Also: - - - `mssdemux`, the Microsoft Smooth Streaming demuxer, has seen various - fixes for live streams, duration reporting and seeking. - - - The DASH manifest parser now extracts MS PlayReady ContentProtection objects - from manifests and sends them downstream as `PROTECTION` events. It also - supports multiple Period elements in external xml now. - -- gst-libav was updated to ffmpeg 3.3 but should still work with any 3.x - version. - -- GstEncodingProfile has been generally enhanced so it can, for - example, be used to get possible profiles for a given file - extension. It is now possible to define profiles based on element - factory names or using a path to a `.gep` file containing a - serialized profile. - -- `audioconvert` can now do endianness conversion in-place. All other - conversions still require a copy, but e.g. sign conversion and a few others - could also be implemented in-place now. - -- The new, experimental `playbin3` and `urisourcebin` elements got many - bugfixes and improvements and should generally be closer to a full - replacement of the old elements. - -- `interleave` now supports > 64 channels. +- this section will be filled in shortly ### OpenGL integration -- As usual the GStreamer OpenGL integration library has seen numerous - fixes and performance improvements all over the place, and is hopefully - ready now to become API stable and be moved to gst-plugins-base during the - 1.14 release cycle. - -- The GStreamer OpenGL integration layer has also gained support for the - Vivante EGL FB windowing system, which improves performance on platforms - such as Freescale iMX.6 for those who are stuck with the proprietary driver. - The `qmlglsink` element also supports this now if Qt is used with eglfs or - wayland backend, and it works in conjunction with [gstreamer-imx][gstreamer-imx] - of course. - -- various `qmlglsrc` improvements - -[gstreamer-imx]: https://github.com/Freescale/gstreamer-imx +- this section will be filled in shortly ## Tracing framework and debugging improvements -- New tracing hooks have been added to track GstMiniObject and GstObject - ref/unref operations. - -- The memory leaks tracer can optionally use this to retrieve stack traces if - enabled with e.g. `GST_TRACERS=leaks(filters="GstEvent,GstMessage",stack-traces-flags=full)` - -- The `GST_DEBUG_FILE` environment variable, which can be used to write the - debug log output to a file instead of printing it to stderr, can now contain - a name pattern, which is useful for automated testing and continuous - integration systems. The following format specifiers are supported: - - - `%p`: will be replaced with the PID - - `%r`: will be replaced with a random number, which is useful for instance - when running two processes with the same PID but in different containers. +- this section will be filled in shortly ## Tools -- `gst-inspect-1.0` can now list elements by type with the new `--types` - command-line option, e.g. `gst-inspect-1.0 --types=Audio/Encoder` will - show a list of audio encoders. - -- `gst-launch-1.0` and `gst_parse_launch()` have gained a new operator (`:`) - that allows linking all pads between two elements. This is useful in cases - where the exact number of pads or type of pads is not known beforehand, such - as in the `uridecodebin : encodebin` scenario, for example. In this case, - multiple links will be created if the encodebin has multiple profiles - compatible with the output of uridecodebin. - -- `gst-device-monitor-1.0` now shows a `gst-launch-1.0` snippet for each - device that shows how to make use of it in a `gst-launch-1.0` pipeline string. +- this section will be filled in shortly ## GStreamer RTSP server -- The RTSP server now also supports Digest authentication in addition to Basic - authentication. - -- The `GstRTSPClient` class has gained a `pre-*-request` signal and virtual - method for each client request type, emitted in the beginning of each rtsp - request. These signals or virtual methods let the application validate the - requests, configure the media/stream in a certain way and also generate error - status codes in case of an error or a bad request. +- this section will be filled in shortly ## GStreamer VAAPI -- GstVaapiDisplay now inherits from GstObject, thus the VA display logging - messages are better and tracing the context sharing is more readable. - -- When uploading raw images into a VA surfaces now VADeriveImages are tried - fist, improving the upload performance, if it is possible. - -- The decoders and the post-processor now can push dmabuf-based buffers to - downstream under certain conditions. For example: - - `GST_GL_PLATFORM=egl gst-play-1.0 video-sample.mkv --videosink=glimagesink` - -- Refactored the wrapping of VA surface into gstreamer memory, adding lock - when mapping and unmapping, and many other fixes. - -- Now `vaapidecodebin` loads `vaapipostproc` dynamically. It is possible to - avoid it usage with the environment variable `GST_VAAPI_DISABLE_VPP=1`. - -- Regarding encoders: they have primary rank again, since they can discover, - in run-time, the color formats they can use for upstream raw buffers and - caps renegotiation is now possible. Also the encoders push encoding info - downstream via tags. - -- About specific encoders: added constant bit-rate encoding mode for VP8 and - H265 encoder handles P010_10LE color format. - -- Regarding decoders, flush operation has been improved, now the internal VA - encoder is not recreated at each flush. Also there are several improvements - in the handling of H264 and H265 streams. - -- VAAPI plugins try to create their on GstGL context (when available) if they - cannot find it in the pipeline, to figure out what type of VA Display they - should create. - -- Regarding `vaapisink` for X11, if the backend reports that it is unable to - render correctly the current color format, an internal VA post-processor, is - instantiated (if available) and converts the color format. +- this section will be filled in shortly ## GStreamer Editing Services and NLE -- Enhanced auto transition behaviour - -- Fix some races in `nlecomposition` - -- Allow building with msvc - -- Added a UNIX manpage for `ges-launch` - -- API changes: - - Added ges_deinit (allowing the leak tracer to work properly) - - Added ges_layer_get_clips_in_interval - - Finally hide internal symbols that should never have been exposed +- this section will be filled in shortly ## GStreamer validate -- Port `gst-validate-launcher` to python 3 +- this section will be filled in shortly -- `gst-validate-launcher` now checks if blacklisted bugs have been fixed on - bugzilla and errors out if it is the case +## GStreamer Python Bindings -- Allow building with msvc - -- Add ability for the launcher to run GStreamer unit tests - -- Added a way to activate the leaks tracer on our tests and fix leaks - -- Make the http server multithreaded - -- New testsuite for running various test scenarios on the DASH-IF test vectors +- this section will be filled in shortly ## Build and Dependencies -- Meson build files are now disted in tarballs, for jhbuild and so distro - packagers can start using it. Note that the Meson-based build system is not - 100% feature-equivalent with the autotools-based one yet. - -- Some plugin filenames have been changed to match the plugin names: for example - the file name of the `encoding` plugin in gst-plugins-base containing the - `encodebin` element was `libgstencodebin.so` and has been changed to - `libgstencodebin.so`. This affects only a handful of plugins across modules. - - **Developers who install GStreamer from source and just do `make install`** - **after updating the source code, without doing `make uninstall` first, will** - **have to manually remove the old installed plugin files from the installation** - **prefix, or they will get 'Cannot register existing type' critical warnings.** - -- Most of the docbook-based documentation (FAQ, Application Development Manual, - Plugin Writer's Guide, design documents) has been converted to markdown and - moved into a new gst-docs module. The gtk-doc library API references and - the plugins documentation are still built as part of the source modules though. - -- GStreamer core now optionally uses libunwind and libdw to generate backtraces. - This is useful for tracer plugins used during debugging and development. - -- There is a new `libgstbadallocators-1.0` library in gst-plugins-bad (which - may go away again in future releases once the `GstPhysMemoryAllocator` - interface API has been validated by more users). - -- `gst-omx` and `gstreamer-vaapi` modules can now also be built using the - Meson build system. - -- The `qtkitvideosrc` element for macOS was removed. The API is deprecated - since 10.9 and it wasn't shipped in the binaries since a few releases. +- this section will be filled in shortly ## Platform-specific improvements ### Android -- androidmedia: add support for VP9 video decoding/encoding and Opus audio - decoding (where supported) +- this section will be filled in shortly -### OS/X and iOS +### macOS and iOS -- `avfvideosrc`, which represents an iPhone camera or, on a Mac, a screencapture - session, so far allowed you to select an input device by device index only. - New API adds the ability to select the position (front or back facing) and - device-type (wide angle, telephoto, etc.). Furthermore, you can now also - specify the orientation (portrait, landscape, etc.) of the videostream. +- this section will be filled in shortly ### Windows -- `dx9screencapsrc` can now optionally also capture the cursor. +- this section will be filled in shortly ## Contributors -Aleix Conchillo Flaque, Alejandro G. Castro, Aleksandr Slobodeniuk, Alexandru -Băluț, Alex Ashley, Andre McCurdy, Andrew, Anton Eliasson, Antonio Ospite, -Arnaud Vrac, Arun Raghavan, Aurélien Zanelli, Axel Menzel, Benjamin Otte, -Branko Subasic, Brendan Shanks, Carl Karsten, Carlos Rafael Giani, ChangBok -Chae, Chris Bass, Christian Schaller, christophecvr, Claudio Saavedra, -Corentin Noël, Dag Gullberg, Daniel Garbanzo, Daniel Shahaf, David Evans, -David Schleef, David Warman, Dominique Leuenberger, Dongil Park, Douglas -Bagnall, Edgard Lima, Edward Hervey, Emeric Grange, Enrico Jorns, Enrique -Ocaña González, Evan Nemerson, Fabian Orccon, Fabien Dessenne, Fabrice Bellet, -Florent Thiéry, Florian Zwoch, Francisco Velazquez, Frédéric Dalleau, Garima -Gaur, Gaurav Gupta, George Kiagiadakis, Georg Lippitsch, Göran Jönsson, Graham -Leggett, Guillaume Desmottes, Gurkirpal Singh, Haihua Hu, Hanno Boeck, Havard -Graff, Heekyoung Seo, hoonhee.lee, Hyunjun Ko, Imre Eörs, Iñaki García -Etxebarria, Jagadish, Jagyum Koo, Jan Alexander Steffens (heftig), Jan -Schmidt, Jean-Christophe Trotin, Jochen Henneberg, Jonas Holmberg, Joris -Valette, Josep Torra, Juan Pablo Ugarte, Julien Isorce, Jürgen Sachs, Koop -Mast, Kseniia Vasilchuk, Lars Wendler, leigh123linux@googlemail.com, Luis de -Bethencourt, Lyon Wang, Marcin Kolny, Marinus Schraal, Mark Nauwelaerts, -Mathieu Duponchelle, Matthew Waters, Matt Staples, Michael Dutka, Michael -Olbrich, Michael Smith, Michael Tretter, Miguel París Díaz, namanyadav12, Neha -Arora, Nick Kallen, Nicola Murino, Nicolas Dechesne, Nicolas Dufresne, Nicolas -Huet, Nirbheek Chauhan, Ole André Vadla Ravnås, Olivier Crête, Patricia -Muscalu, Peter Korsgaard, Peter Seiderer, Petr Kulhavy, Philippe Normand, -Philippe Renon, Philipp Zabel, Rahul Bedarkar, Reynaldo H. Verdejo Pinochet, -Ricardo Ribalda Delgado, Rico Tzschichholz, Руслан Ижбулатов, Samuel Maroy, -Santiago Carot-Nemesio, Scott D Phillips, Sean DuBois, Sebastian Dröge, Sergey -Borovkov, Seungha Yang, shakin chou, Song Bing, Søren Juul, Sreerenj -Balachandran, Stefan Kost, Stefan Sauer, Stepan Salenikovich, Stian Selnes, -Stuart Weaver, suhas2go, Thiago Santos, Thibault Saunier, Thomas Bluemel, -Thomas Petazzoni, Tim-Philipp Müller, Ting-Wei Lan, Tobias Mueller, Todor -Tomov, Tomasz Zajac, Ulf Olsson, Ursula Maplehurst, Víctor Manuel Jáquez Leal, -Victor Toso, Vincent Penquerc'h, Vineeth TM, Vinod Kesti, Vitor Massaru Iha, -Vivia Nikolaidou, WeiChungChang, William Manley, Wim Taymans, Wojciech -Przybyl, Wonchul Lee, Xavier Claessens, Yasushi SHOJI +- this section will be filled in shortly ... and many others who have contributed bug reports, translations, sent suggestions or helped testing. -## Bugs fixed in 1.12 +## Bugs fixed in 1.14 -More than [635 bugs][bugs-fixed-in-1.12] have been fixed during -the development of 1.12. +- this section will be filled in shortly + +More than [704 bugs][bugs-fixed-in-1.14] have been fixed during +the development of 1.14. This list does not include issues that have been cherry-picked into the -stable 1.10 branch and fixed there as well, all fixes that ended up in the -1.10 branch are also included in 1.12. +stable 1.12 branch and fixed there as well, all fixes that ended up in the +1.12 branch are also included in 1.14. This list also does not include issues that have been fixed without a bug report in bugzilla, so the actual number of fixes is much higher. -[bugs-fixed-in-1.12]: https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&classification=Platform&limit=0&list_id=213265&order=bug_id&product=GStreamer&query_format=advanced&resolution=FIXED&target_milestone=1.10.1&target_milestone=1.10.2&target_milestone=1.10.3&target_milestone=1.10.4&target_milestone=1.11.1&target_milestone=1.11.2&target_milestone=1.11.3&target_milestone=1.11.4&target_milestone=1.11.90&target_milestone=1.11.91&target_milestone=1.12.0 +[bugs-fixed-in-1.14]: https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&classification=Platform&limit=0&list_id=213265&order=bug_id&product=GStreamer&query_format=advanced&resolution=FIXED&target_milestone=1.12.1&target_milestone=1.12.2&target_milestone=1.12.3&target_milestone=1.12.4&target_milestone=1.13.1&target_milestone=1.13.2&target_milestone=1.13.3&target_milestone=1.13.4&target_milestone=1.13.90&target_milestone=1.13.91&target_milestone=1.14.0 -## Stable 1.12 branch +## Stable 1.14 branch -After the 1.12.0 release there will be several 1.12.x bug-fix releases which +After the 1.14.0 release there will be several 1.14.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.12.x bug-fix releases will be made from the git 1.12 branch, which -is a stable branch. +usually. The 1.14.x bug-fix releases will be made from the git 1.14 branch, +which is a stable branch. -### 1.12.0 +### 1.14.0 -1.12.0 was released on 4th May 2017. +1.14.0 is scheduled to be released in late February / early March 2018. ## Known Issues @@ -712,23 +153,22 @@ is a stable branch. [bug-770264]: https://bugzilla.gnome.org/show_bug.cgi?id=770264 -## Schedule for 1.14 +## Schedule for 1.16 -Our next major feature release will be 1.14, and 1.11 will be the unstable -development version leading up to the stable 1.12 release. The development -of 1.13/1.14 will happen in the git master branch. +Our next major feature release will be 1.16, and 1.15 will be the unstable +development version leading up to the stable 1.16 release. The development +of 1.15/1.16 will happen in the git master branch. -The plan for the 1.14 development cycle is yet to be confirmed, but it is -expected that feature freeze will be around September 2017 -followed by several 1.13 pre-releases and the new 1.14 stable release -in October. +The plan for the 1.16 development cycle is yet to be confirmed, but it is +expected that feature freeze will be around August 2017 +followed by several 1.15 pre-releases and the new 1.16 stable release +in September. -1.14 will be backwards-compatible to the stable 1.12, 1.10, 1.8, 1.6, 1.4, +1.16 will be backwards-compatible to the stable 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 Sebastian Dröge, Tim-Philipp Müller -and Víctor Manuel Jáquez Leal.* +*These release notes have been prepared by Tim-Philipp Müller.* *License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)* diff --git a/configure.ac b/configure.ac index 8f1d072f53..6182429e4a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [13]) -m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [1]) +m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1300]) +m4_define([gst_vaapi_lt_current], [1301]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1300]) +m4_define([gst_vaapi_lt_age], [1301]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.13.0.1]) -m4_define([gst_plugins_base_version], [1.13.0.1]) -m4_define([gst_plugins_bad_version], [1.13.0.1]) +m4_define([gst_version], [1.13.1]) +m4_define([gst_plugins_base_version], [1.13.1]) +m4_define([gst_plugins_bad_version], [1.13.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index e30da6dee7..c61018b94c 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,56 @@ + + + 1.13.1 + master + + 2018-02-15 + + + + + + + 1.12.4 + 1.12 + + 2017-12-07 + + + + + + + 1.12.3 + 1.12 + + 2017-09-18 + + + + + + + 1.12.2 + 1.12 + + 2017-07-14 + + + + + + + 1.12.1 + 1.12 + + 2017-06-20 + + + + 1.12.0 diff --git a/meson.build b/meson.build index e22b075705..5da9b167d5 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.13.0.1', + version : '1.13.1', meson_version : '>= 0.36.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From a9b61f22f946058ddf4dbe9f9ebf399a682b44c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 15 Feb 2018 19:44:35 +0000 Subject: [PATCH 3030/3781] Back to development --- configure.ac | 6 +++--- meson.build | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 6182429e4a..99023adb27 100644 --- a/configure.ac +++ b/configure.ac @@ -24,9 +24,9 @@ m4_define([gst_vaapi_lt_age], [1301]) m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.13.1]) -m4_define([gst_plugins_base_version], [1.13.1]) -m4_define([gst_plugins_bad_version], [1.13.1]) +m4_define([gst_version], [1.13.1.1]) +m4_define([gst_plugins_base_version], [1.13.1.1]) +m4_define([gst_plugins_bad_version], [1.13.1.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/meson.build b/meson.build index 5da9b167d5..c08bf889ec 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.13.1', + version : '1.13.1.1', meson_version : '>= 0.36.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 83886ced66dd0ae5a962efb2c14fc0a910b60f56 Mon Sep 17 00:00:00 2001 From: Matteo Valdina Date: Thu, 15 Feb 2018 14:55:42 -0600 Subject: [PATCH 3031/3781] libs: encoder: h264,h265: extend max periodic keyframe. Increased max values of periodic key frame for h26x codecs. This allow more fine tunning of encoder that in certian scenario want higher periodic key frame. For example: it doesn't want a key frame each 10 seconds but each 120 seconds. https://bugzilla.gnome.org/show_bug.cgi?id=786320 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 -- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 5 ----- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 2 -- gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 5 ----- gst-libs/gst/vaapi/gstvaapifeipak_h264.c | 3 --- gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h | 3 --- 7 files changed, 1 insertion(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 46d40cf7ef..f0d68997f1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -164,7 +164,7 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, g_param_spec_uint ("keyframe-period", "Keyframe Period", - "Maximal distance between two keyframes (0: auto-calculate)", 1, 300, + "Maximal distance between two keyframes (0: auto-calculate)", 1, G_MAXUINT32, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 0c4b8712f0..2355d912f3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2761,8 +2761,6 @@ reset_properties (GstVaapiEncoderH264 * encoder) if (encoder->idr_period < base_encoder->keyframe_period) encoder->idr_period = base_encoder->keyframe_period; - if (encoder->idr_period > MAX_IDR_PERIOD) - encoder->idr_period = MAX_IDR_PERIOD; if (encoder->min_qp > encoder->init_qp) encoder->min_qp = encoder->init_qp; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index 68ef213ad1..a99f780887 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -58,9 +58,6 @@ gst_vaapi_encoder_h264_fei_ensure_secondary_context (GstVaapiEncoder * /* Define the maximum value for view-id */ #define MAX_VIEW_ID 1023 -/* Define the maximum IDR period */ -#define MAX_IDR_PERIOD 512 - /* Default CPB length (in milliseconds) */ #define DEFAULT_CPB_LENGTH 1500 @@ -2650,8 +2647,6 @@ reset_properties (GstVaapiEncoderH264Fei * encoder) if (encoder->idr_period < base_encoder->keyframe_period) encoder->idr_period = base_encoder->keyframe_period; - if (encoder->idr_period > MAX_IDR_PERIOD) - encoder->idr_period = MAX_IDR_PERIOD; if (encoder->min_qp > encoder->init_qp || (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP && diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 557901fe03..479294e926 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2024,8 +2024,6 @@ reset_properties (GstVaapiEncoderH265 * encoder) if (encoder->idr_period < base_encoder->keyframe_period) encoder->idr_period = base_encoder->keyframe_period; - if (encoder->idr_period > MAX_IDR_PERIOD) - encoder->idr_period = MAX_IDR_PERIOD; if (encoder->min_qp > encoder->init_qp) encoder->min_qp = encoder->init_qp; diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index 4438a7fc81..c551e62556 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -49,9 +49,6 @@ /* Define the maximum value for view-id */ #define MAX_VIEW_ID 1023 -/* Define the maximum IDR period */ -#define MAX_IDR_PERIOD 512 - /* Default CPB length (in milliseconds) */ #define DEFAULT_CPB_LENGTH 1500 @@ -1303,8 +1300,6 @@ reset_properties (GstVaapiFeiEncH264 * feienc) if (feienc->idr_period < base_encoder->keyframe_period) feienc->idr_period = base_encoder->keyframe_period; - if (feienc->idr_period > MAX_IDR_PERIOD) - feienc->idr_period = MAX_IDR_PERIOD; if (feienc->min_qp > feienc->init_qp || (GST_VAAPI_ENCODER_RATE_CONTROL (feienc) == GST_VAAPI_RATECONTROL_CQP && diff --git a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c index 7a49f0a9a4..2eddaa64f5 100644 --- a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c @@ -46,9 +46,6 @@ /* Define the maximum value for view-id */ #define MAX_VIEW_ID 1023 -/* Define the maximum IDR period */ -#define MAX_IDR_PERIOD 512 - /* Default CPB length (in milliseconds) */ #define DEFAULT_CPB_LENGTH 1500 diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h index 3d3e5014ec..23749ea07c 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h @@ -29,9 +29,6 @@ G_BEGIN_DECLS -/* Define the maximum IDR period */ -#define MAX_IDR_PERIOD 512 - /* Default CPB length (in milliseconds) */ #define DEFAULT_CPB_LENGTH 1500 From 1ca2c78c7acc0255feb876233f5c79ef1a634c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 20 Feb 2018 02:14:37 +0100 Subject: [PATCH 3032/3781] vaapibufferpool: remove wrong gcc annotation --- gst/vaapi/gstvaapivideobufferpool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index 6a2169f1e7..9498531649 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -132,7 +132,7 @@ gst_vaapi_video_buffer_pool_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL GstBufferPool * -gst_vaapi_video_buffer_pool_new (GstVaapiDisplay * display) G_GNUC_CONST; +gst_vaapi_video_buffer_pool_new (GstVaapiDisplay * display); G_END_DECLS From 516d6bb3e2ceb8d1f308fbffbc2e697370b97ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 20 Feb 2018 09:15:05 -0600 Subject: [PATCH 3033/3781] vaapipostproc: set discont flag at vpp deinterlacing When deinterlacing with VPP the discont flag was not forwarded to the new created buffer. This patch sets the discont flag if input buffer has it. --- gst/vaapi/gstvaapipostproc.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index e0f6aebb25..29c8406b4d 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -615,7 +615,7 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer *fieldbuf; GstVaapiDeinterlaceMethod deint_method; guint flags, deint_flags; - gboolean tff, deint, deint_refs, deint_changed; + gboolean tff, deint, deint_refs, deint_changed, discont; const GstVideoCropMeta *crop_meta; GstVaapiRectangle *crop_rect = NULL; GstVaapiRectangle tmp_rect; @@ -639,6 +639,7 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, timestamp = GST_BUFFER_TIMESTAMP (inbuf); tff = GST_BUFFER_FLAG_IS_SET (inbuf, GST_VIDEO_BUFFER_FLAG_TFF); + discont = GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_DISCONT); deint = should_deinterlace_buffer (postproc, inbuf); /* Drop references if deinterlacing conditions changed */ @@ -721,6 +722,11 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, GST_BUFFER_TIMESTAMP (fieldbuf) = timestamp; GST_BUFFER_DURATION (fieldbuf) = postproc->field_duration; + if (discont) { + GST_BUFFER_FLAG_SET (fieldbuf, GST_BUFFER_FLAG_DISCONT); + discont = FALSE; + } + ret = gst_pad_push (trans->srcpad, fieldbuf); if (ret != GST_FLOW_OK) goto error_push_buffer; @@ -771,6 +777,10 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, else { GST_BUFFER_TIMESTAMP (outbuf) = timestamp + postproc->field_duration; GST_BUFFER_DURATION (outbuf) = postproc->field_duration; + if (discont) { + GST_BUFFER_FLAG_SET (fieldbuf, GST_BUFFER_FLAG_DISCONT); + discont = FALSE; + } } if (deint && deint_refs) From ad705cc5a3d45e70d2b1cb71698ebafe3c91cdc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 15 Feb 2018 19:22:08 +0100 Subject: [PATCH 3034/3781] vaapibufferpool: don't change config when forcing video meta VA-API based buffer might need a video meta because of different strides. But when donwstream doesn't support video meta we need to force the usage of video meta. Before we changed the buffer pool configuration, but actually this is a hack and we cannot rely on that for downstream. This patch add a check fo raw video caps and allocator is VA-API, then the option is enabled without changing the pool configuration. In this case the element is responsible to copy the frame to a simple buffer with the expected strides. https://bugzilla.gnome.org/show_bug.cgi?id=785054 --- gst/vaapi/gstvaapivideobufferpool.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index f4b1a42f68..812893ba16 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -142,7 +142,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, const GstVideoInfo *negotiated_vinfo; GstVideoAlignment align; GstAllocator *allocator; - gboolean ret, updated = FALSE; + gboolean ret; guint size, min_buffers, max_buffers; guint surface_alloc_flags; @@ -248,17 +248,16 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, if (gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META)) { priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; - } else { + } else if (gst_caps_is_video_raw (caps) && !priv->use_dmabuf_memory) { gint i; + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&new_allocation_vinfo); i++) { if (GST_VIDEO_INFO_PLANE_OFFSET (&new_allocation_vinfo, i) != GST_VIDEO_INFO_PLANE_OFFSET (&priv->vmeta_vinfo, i) || GST_VIDEO_INFO_PLANE_STRIDE (&new_allocation_vinfo, i) != GST_VIDEO_INFO_PLANE_STRIDE (&priv->vmeta_vinfo, i)) { priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_META); - updated = TRUE; + GST_INFO_OBJECT (pool, "adding unrequested video meta"); break; } } @@ -277,7 +276,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, ret = GST_BUFFER_POOL_CLASS (gst_vaapi_video_buffer_pool_parent_class)->set_config (pool, config); - return !updated && ret; + return ret; /* ERRORS */ error_invalid_config: From bcc480b70e18eb5c1768aad5a8c28c2bfb9526a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 20 Feb 2018 02:25:13 +0100 Subject: [PATCH 3035/3781] vaapibufferpool: add gst_vaapi_video_buffer_pool_copy_buffer() This function will inform the element if it shall copy the generated buffer by the pool to a system allocated buffer before pushing it to downstream. https://bugzilla.gnome.org/show_bug.cgi?id=785054 --- gst/vaapi/gstvaapivideobufferpool.c | 24 ++++++++++++++++++++++++ gst/vaapi/gstvaapivideobufferpool.h | 4 ++++ 2 files changed, 28 insertions(+) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 812893ba16..51539e278c 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -49,6 +49,7 @@ struct _GstVaapiVideoBufferPoolPrivate GstVaapiDisplay *display; guint options; guint use_dmabuf_memory:1; + guint forced_video_meta:1; }; #define GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(obj) \ @@ -257,6 +258,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, GST_VIDEO_INFO_PLANE_STRIDE (&new_allocation_vinfo, i) != GST_VIDEO_INFO_PLANE_STRIDE (&priv->vmeta_vinfo, i)) { priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; + priv->forced_video_meta = TRUE; GST_INFO_OBJECT (pool, "adding unrequested video meta"); break; } @@ -535,3 +537,25 @@ gst_vaapi_video_buffer_pool_new (GstVaapiDisplay * display) return g_object_new (GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, "display", display, NULL); } + +/** + * gst_vaapi_video_buffer_pool_copy_buffer: + * @pool: a #GstVaapiVideoBufferPool + * + * Returns if the @pool force set of #GstVideoMeta. If so, the element + * should copy the generated buffer by the pool to a system allocated + * buffer. Otherwise, downstream could not display correctly the + * frame. + * + * Returns: %TRUE if #GstVideoMeta is forced. + **/ +gboolean +gst_vaapi_video_buffer_pool_copy_buffer (GstBufferPool * pool) +{ + GstVaapiVideoBufferPoolPrivate *priv; + + g_return_val_if_fail (GST_VAAPI_IS_VIDEO_BUFFER_POOL (pool), FALSE); + + priv = GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE (pool); + return priv->forced_video_meta; +} diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index 9498531649..98be6f848a 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -134,6 +134,10 @@ G_GNUC_INTERNAL GstBufferPool * gst_vaapi_video_buffer_pool_new (GstVaapiDisplay * display); +G_GNUC_INTERNAL +gboolean +gst_vaapi_video_buffer_pool_copy_buffer (GstBufferPool * pool); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_BUFFER_POOL_H */ From f0fd2aeb0469fa15bd2932aedf3e682004107890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 15 Feb 2018 19:28:33 +0100 Subject: [PATCH 3036/3781] plugins: store the first downstream allocator if available The allocator will be required if we need to allocate a buffer to store the frame with the expected strides. https://bugzilla.gnome.org/show_bug.cgi?id=785054 --- gst/vaapi/gstvaapipluginbase.c | 17 ++++++++++++++++- gst/vaapi/gstvaapipluginbase.h | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 7bc7178dad..0183579cf1 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -327,6 +327,7 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) g_clear_object (&plugin->sinkpad_allocator); g_clear_object (&plugin->srcpad_allocator); + g_clear_object (&plugin->other_srcpad_allocator); gst_caps_replace (&plugin->srcpad_caps, NULL); gst_video_info_init (&plugin->srcpad_info); @@ -929,10 +930,24 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, num_allocators = gst_query_get_n_allocation_params (query); for (i = 0; i < num_allocators; i++) { GstAllocator *allocator = NULL; + GstAllocationParams params; - gst_query_parse_nth_allocation_param (query, i, &allocator, NULL); + gst_query_parse_nth_allocation_param (query, i, &allocator, ¶ms); if (!allocator) continue; + + /* Let's keep the the first allocator if it is not VA-API. It + * might be used if it is required to copy the output frame to a + * new buffer */ + if (i == 0 + && g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) != 0) { + if (plugin->other_srcpad_allocator) + gst_object_unref (plugin->other_srcpad_allocator); + plugin->other_srcpad_allocator = allocator; + plugin->other_allocator_params = params; + continue; + } + if (g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) == 0) { GST_DEBUG_OBJECT (plugin, "found vaapi allocator in query %" GST_PTR_FORMAT, allocator); diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index f08548260f..81b5f4eddb 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -147,6 +147,8 @@ struct _GstVaapiPluginBase gboolean srcpad_can_dmabuf; gboolean enable_direct_rendering; + GstAllocator *other_srcpad_allocator; + GstAllocationParams other_allocator_params; }; struct _GstVaapiPluginBaseClass From 5842e9cf879c8efb03a3e61d833be6627c8ad737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 15 Feb 2018 19:29:51 +0100 Subject: [PATCH 3037/3781] plugins: add COPY_OUTPUT_FRAME flag This patch add the member copy_output_frame and set it TRUE when when downstream didn't request GstVideoMeta API, the caps are raw and the internal allocator is the VA-API one. https://bugzilla.gnome.org/show_bug.cgi?id=785054 --- gst/vaapi/gstvaapipluginbase.c | 6 ++++++ gst/vaapi/gstvaapipluginbase.h | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 0183579cf1..568c42e7a1 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1015,6 +1015,12 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, g_clear_object (&plugin->srcpad_buffer_pool); plugin->srcpad_buffer_pool = pool; + + /* if downstream doesn't support GstVideoMeta, and the negotiated + * caps are raw video, and the used allocator is the VA-API one, we + * should copy the VA-API frame into a dumb buffer */ + plugin->copy_output_frame = gst_vaapi_video_buffer_pool_copy_buffer (pool); + return TRUE; /* ERRORS */ diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 81b5f4eddb..b58fdbea86 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -85,6 +85,8 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (&GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_info) #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_can_dmabuf) +#define GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->copy_output_frame) #define GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->display) @@ -147,8 +149,10 @@ struct _GstVaapiPluginBase gboolean srcpad_can_dmabuf; gboolean enable_direct_rendering; + GstAllocator *other_srcpad_allocator; GstAllocationParams other_allocator_params; + gboolean copy_output_frame; }; struct _GstVaapiPluginBaseClass From 2c36610748ce2840690601f4ce09fa929f64aa8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 15 Feb 2018 19:32:19 +0100 Subject: [PATCH 3038/3781] plugins: add gst_vaapi_copy_va_buffer() This helper function aims to copy buffers with VA memory to dumb buffers, when GstVideoMeta is not available dowstream. https://bugzilla.gnome.org/show_bug.cgi?id=785054 --- gst/vaapi/gstvaapipluginbase.c | 66 ++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginbase.h | 6 ++++ 2 files changed, 72 insertions(+) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 568c42e7a1..b5dd1df5a2 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -34,6 +34,7 @@ # include #endif +GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE); /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) @@ -1374,3 +1375,68 @@ gst_vaapi_plugin_base_set_srcpad_can_dmabuf (GstVaapiPluginBase * plugin, "EGL_EXT_image_dma_buf_import")); #endif } + +static void +_init_performance_debug (void) +{ +#ifndef GST_DISABLE_GST_DEBUG + static volatile gsize _init = 0; + + if (g_once_init_enter (&_init)) { + GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE"); + g_once_init_leave (&_init, 1); + } +#endif +} + +/** + * gst_vaapi_plugin_copy_va_buffer: + * @plugin: a #GstVaapiPluginBase + * @inbuf: a #GstBuffer with VA memory type + * @outbuf: a #GstBuffer with system allocated memory + * + * Copy @inbuf to @outbuf. This if required when downstream doesn't + * support GstVideoMeta, and since VA memory may have custom strides a + * frame copy is required. + * + * Returns: %FALSE if the copy failed, otherwise %TRUE. Also returns + * %TRUE if it is not required to do the copy + **/ +gboolean +gst_vaapi_plugin_copy_va_buffer (GstVaapiPluginBase * plugin, + GstBuffer * inbuf, GstBuffer * outbuf) +{ + GstVideoMeta *vmeta; + GstVideoFrame src_frame, dst_frame; + gboolean success; + + if (!plugin->copy_output_frame) + return TRUE; + + /* inbuf shall have video meta */ + vmeta = gst_buffer_get_video_meta (inbuf); + if (!vmeta) + return FALSE; + + _init_performance_debug (); + GST_CAT_INFO (CAT_PERFORMANCE, "copying VA buffer to system memory buffer"); + + if (!gst_video_frame_map (&src_frame, &plugin->srcpad_info, inbuf, + GST_MAP_READ)) + return FALSE; + if (!gst_video_frame_map (&dst_frame, &plugin->srcpad_info, outbuf, + GST_MAP_WRITE)) { + gst_video_frame_unmap (&src_frame); + return FALSE; + } + success = gst_video_frame_copy (&dst_frame, &src_frame); + gst_video_frame_unmap (&dst_frame); + gst_video_frame_unmap (&src_frame); + + if (success) { + gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS + | GST_BUFFER_COPY_FLAGS, 0, -1); + } + + return success; +} diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index b58fdbea86..c0d07496aa 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -258,6 +258,12 @@ void gst_vaapi_plugin_base_set_srcpad_can_dmabuf (GstVaapiPluginBase * plugin, GstObject * object); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_copy_va_buffer (GstVaapiPluginBase * plugin, + GstBuffer * inbuf, GstBuffer * outbuf); + + G_END_DECLS #endif /* GST_VAAPI_PLUGIN_BASE_H */ From 188434f25112436621661c9f209441bc32aa3907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 15 Feb 2018 19:32:37 +0100 Subject: [PATCH 3039/3781] vaapipostproc: handle system allocated buffers when required When downstream can't handle GstVideoMeta it is required to send system allocated buffers. The system allocated buffers are produced in prepare_output_buffer() vmethod if downstream can't handl GstVideoMeta. At transform() vmethod if the buffer is a system allocated buffer, a VA buffer is instanciated and replaces the out buffer. Later the VA buffer is copied to the system allocate buffer and it replaces the output buffer. https://bugzilla.gnome.org/show_bug.cgi?id=785054 --- gst/vaapi/gstvaapipostproc.c | 87 +++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 29c8406b4d..8ad3f2866e 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -392,6 +392,16 @@ error_create_buffer: } } +static inline GstBuffer * +create_output_dump_buffer (GstVaapiPostproc * postproc) +{ + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (postproc); + + return gst_buffer_new_allocate (plugin->other_srcpad_allocator, + GST_VIDEO_INFO_SIZE (&plugin->srcpad_info), + &plugin->other_allocator_params); +} + static gboolean append_output_buffer_metadata (GstVaapiPostproc * postproc, GstBuffer * outbuf, GstBuffer * inbuf, guint flags) @@ -600,6 +610,31 @@ gst_vaapipostproc_set_passthrough (GstBaseTransform * trans) && !filter_updated); } +static gboolean +replace_to_dumb_buffer_if_required (GstVaapiPostproc * postproc, + GstBuffer ** fieldbuf) +{ + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (postproc); + GstBuffer *newbuf; + + if (!GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME (postproc)) + return TRUE; + + newbuf = create_output_dump_buffer (postproc); + if (!newbuf) + return FALSE; + + if (!gst_vaapi_plugin_copy_va_buffer (plugin, *fieldbuf, newbuf)) { + gst_buffer_unref (newbuf); + return FALSE; + } + + gst_buffer_replace (fieldbuf, newbuf); + gst_buffer_unref (newbuf); + + return TRUE; +} + static GstFlowReturn gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer * outbuf) @@ -727,6 +762,9 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, discont = FALSE; } + if (!replace_to_dumb_buffer_if_required (postproc, &fieldbuf)) + goto error_copy_buffer; + ret = gst_pad_push (trans->srcpad, fieldbuf); if (ret != GST_FLOW_OK) goto error_push_buffer; @@ -824,6 +862,12 @@ error_process_vpp: gst_buffer_replace (&fieldbuf, NULL); return GST_FLOW_ERROR; } +error_copy_buffer: + { + GST_ERROR_OBJECT (postproc, "failed to copy field buffer to dumb buffer"); + gst_buffer_replace (&fieldbuf, NULL); + return GST_FLOW_ERROR; + } error_push_buffer: { GST_DEBUG_OBJECT (postproc, "failed to push output buffer: %s", @@ -871,6 +915,10 @@ gst_vaapipostproc_process (GstBaseTransform * trans, GstBuffer * inbuf, GST_BUFFER_TIMESTAMP (fieldbuf) = timestamp; GST_BUFFER_DURATION (fieldbuf) = postproc->field_duration; + + if (!replace_to_dumb_buffer_if_required (postproc, &fieldbuf)) + goto error_copy_buffer; + ret = gst_pad_push (trans->srcpad, fieldbuf); if (ret != GST_FLOW_OK) goto error_push_buffer; @@ -901,6 +949,12 @@ error_create_buffer: GST_ERROR_OBJECT (postproc, "failed to create output buffer"); return GST_FLOW_EOS; } +error_copy_buffer: + { + GST_ERROR_OBJECT (postproc, "failed to copy field buffer to dumb buffer"); + gst_buffer_replace (&fieldbuf, NULL); + return GST_FLOW_ERROR; + } error_push_buffer: { GST_DEBUG_OBJECT (postproc, "failed to push output buffer: %s", @@ -1211,15 +1265,24 @@ gst_vaapipostproc_transform (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer * outbuf) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - GstBuffer *buf; + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (postproc); + GstBuffer *buf, *sys_buf = NULL; GstFlowReturn ret; - ret = - gst_vaapi_plugin_base_get_input_buffer (GST_VAAPI_PLUGIN_BASE (postproc), - inbuf, &buf); + ret = gst_vaapi_plugin_base_get_input_buffer (plugin, inbuf, &buf); if (ret != GST_FLOW_OK) return GST_FLOW_ERROR; + if (GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME (trans)) { + GstBuffer *va_buf = create_output_buffer (postproc); + if (!va_buf) { + ret = GST_FLOW_ERROR; + goto done; + } + sys_buf = outbuf; + outbuf = va_buf; + } + ret = GST_FLOW_NOT_SUPPORTED; if (postproc->flags) { /* Use VA/VPP extensions to process this frame */ @@ -1245,6 +1308,15 @@ gst_vaapipostproc_transform (GstBaseTransform * trans, GstBuffer * inbuf, done: gst_buffer_unref (buf); + + if (sys_buf) { + if (!gst_vaapi_plugin_copy_va_buffer (plugin, outbuf, sys_buf)) + return GST_FLOW_ERROR; + + gst_buffer_unref (outbuf); + outbuf = sys_buf; + } + return ret; } @@ -1259,7 +1331,12 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, return GST_FLOW_OK; } - *outbuf_ptr = create_output_buffer (postproc); + if (GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME (trans)) { + *outbuf_ptr = create_output_dump_buffer (postproc); + } else { + *outbuf_ptr = create_output_buffer (postproc); + } + return *outbuf_ptr ? GST_FLOW_OK : GST_FLOW_ERROR; } From 9827ab0f3faf5fd3c27bbba225b192f35e03e105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 17 Feb 2018 18:32:11 +0100 Subject: [PATCH 3040/3781] vaapidecode: generate system allocated buffers Generate system allocated output buffers when downstream doesn't support GstVideoMeta. The VA buffer content is copied to the new output buffer, and it replaces the VA buffer. https://bugzilla.gnome.org/show_bug.cgi?id=785054 --- gst/vaapi/gstvaapidecode.c | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1ecc537020..d11b80325e 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -593,9 +593,32 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, if (decode->has_texture_upload_meta) gst_buffer_ensure_texture_upload_meta (out_frame->output_buffer); #endif + + /* Generate a system allocated output buffer if downstream doesn't + * support GstVideoMeta */ + if (GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME (vdec)) { + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec); + GstBuffer *sys_buf, *va_buf; + + va_buf = out_frame->output_buffer; + sys_buf = gst_buffer_new_allocate (plugin->other_srcpad_allocator, + GST_VIDEO_INFO_SIZE (&plugin->srcpad_info), + &plugin->other_allocator_params); + if (!sys_buf) + goto error_no_sys_buffer; + + if (!gst_vaapi_plugin_copy_va_buffer (plugin, va_buf, sys_buf)) { + gst_buffer_unref (sys_buf); + goto error_cannot_copy; + } + + gst_buffer_replace (&out_frame->output_buffer, sys_buf); + gst_buffer_unref (sys_buf); + } } if (decode->in_segment.rate < 0.0 + && !GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME (vdec) && !GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (out_frame)) { GST_TRACE_OBJECT (decode, "drop frame in reverse playback"); gst_video_decoder_release_frame (GST_VIDEO_DECODER (decode), out_frame); @@ -628,6 +651,22 @@ error_get_meta: gst_video_decoder_drop_frame (vdec, out_frame); return GST_FLOW_ERROR; } +error_no_sys_buffer: + { + GST_ELEMENT_ERROR (vdec, STREAM, FAILED, + ("Failed to create system allocated buffer"), + ("Failed to create system allocated buffer")); + gst_video_decoder_drop_frame (vdec, out_frame); + return GST_FLOW_ERROR; + } +error_cannot_copy: + { + GST_ELEMENT_ERROR (vdec, STREAM, FAILED, + ("Failed to copy system allocated buffer"), + ("Failed to copy system allocated buffer")); + gst_video_decoder_drop_frame (vdec, out_frame); + return GST_FLOW_ERROR; + } error_commit_buffer: { GST_INFO_OBJECT (decode, "downstream element rejected the frame (%s [%d])", From d18d6a8bd0d76b2874473fd4c6f9b3ddd4235ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 22 Feb 2018 08:24:12 -0600 Subject: [PATCH 3041/3781] libs: encoder: code-style fix --- gst-libs/gst/vaapi/gstvaapiencoder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index f0d68997f1..8e28096845 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -164,8 +164,8 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, g_param_spec_uint ("keyframe-period", "Keyframe Period", - "Maximal distance between two keyframes (0: auto-calculate)", 1, G_MAXUINT32, - 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Maximal distance between two keyframes (0: auto-calculate)", 1, + G_MAXUINT32, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiEncoder:tune: From 02c7c1bc17fa9f818a3bd50fd95ec425d62ab0aa Mon Sep 17 00:00:00 2001 From: Matteo Valdina Date: Sun, 25 Feb 2018 20:46:56 -0600 Subject: [PATCH 3042/3781] libs: encoder: add zero as valid value for periodic keyframe. Enabled zero as valid value for keyframe-period property. https://bugzilla.gnome.org/show_bug.cgi?id=793829 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 8e28096845..1f8e0a1a01 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -164,7 +164,7 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, g_param_spec_uint ("keyframe-period", "Keyframe Period", - "Maximal distance between two keyframes (0: auto-calculate)", 1, + "Maximal distance between two keyframes (0: auto-calculate)", 0, G_MAXUINT32, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** From 863b7fa6e08af76a703773c3bb69b10cbacb9810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 27 Feb 2018 06:10:09 -0600 Subject: [PATCH 3043/3781] libs: surface: cast to uintptr_t pointer According to Debian package auto-building, uintptr_t is not an unsigned long in i386 arch, raising an "incompatible pointer type" error. This patch adds a casting for compiler's satisfaction in i386. --- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 4c4bbeeb66..528dd8c656 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -268,7 +268,7 @@ gst_vaapi_surface_create_from_buffer_proxy (GstVaapiSurface * surface, extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vip, i); extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vip, i); } - extbuf.buffers = &extbuf_handle; + extbuf.buffers = (uintptr_t *) & extbuf_handle; extbuf.num_buffers = 1; extbuf.flags = 0; extbuf.private_data = NULL; From ba28c6cff2c7e6675d227c2bcbdd8c4a05f9824f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 23 Feb 2018 09:25:51 -0600 Subject: [PATCH 3044/3781] plugins: copy input buffer metas When importing buffers to a VA-base buffer, it is required to copy the metas in the original buffer, otherwise information will be lost, such as GstVideoRegionOfInterestMeta. https://bugzilla.gnome.org/show_bug.cgi?id=768248 --- gst/vaapi/gstvaapipluginbase.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index b5dd1df5a2..08f1e0da15 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1115,8 +1115,9 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, goto error_copy_buffer; done: - gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_FLAGS | - GST_BUFFER_COPY_TIMESTAMPS, 0, -1); + if (!gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_FLAGS | + GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_META, 0, -1)) + return GST_FLOW_ERROR; *outbuf_ptr = outbuf; return GST_FLOW_OK; From 25c2a0d35396a6b58847a83a8617ef87a3f6a899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 21 Feb 2018 10:56:47 -0600 Subject: [PATCH 3045/3781] Revert "vaapiencode: handle custom event GstVaapiEncoderRegionOfInterest" This reverts commit 8f1b88dac0e64a211325cdcb2cda693b80229bd1. https://bugzilla.gnome.org/show_bug.cgi?id=768248 --- gst/vaapi/gstvaapiencode.c | 39 ----------------- gst/vaapi/gstvaapiencode_h264.c | 74 --------------------------------- 2 files changed, 113 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 5bc67c55f2..159cd85947 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -787,45 +787,6 @@ gst_vaapiencode_sink_event (GstVideoEncoder * venc, GstEvent * event) GstPad *const srcpad = GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode); gboolean ret; - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_CUSTOM_DOWNSTREAM:{ - const GstStructure *s = gst_event_get_structure (event); - if (gst_structure_has_name (s, "GstVaapiEncoderRegionOfInterest")) { - GstVaapiROI roi; - - if (!encode->encoder) - return TRUE; - - if (!gst_structure_get_uint (s, "roi-x", &roi.rect.x) || - !gst_structure_get_uint (s, "roi-y", &roi.rect.y) || - !gst_structure_get_uint (s, "roi-width", &roi.rect.width) || - !gst_structure_get_uint (s, "roi-height", &roi.rect.height) || - !gst_structure_get_int (s, "roi-value", &roi.roi_value)) { - return TRUE; - } - - if (roi.roi_value == 0) { - ret = gst_vaapi_encoder_del_roi (encode->encoder, &roi); - if (ret) { - GST_INFO_OBJECT (venc, "ROI: region with %d/%d/%d/%d is removed", - roi.rect.x, roi.rect.y, roi.rect.width, roi.rect.height); - } - } else { - ret = gst_vaapi_encoder_add_roi (encode->encoder, &roi); - if (ret) { - GST_INFO_OBJECT (venc, "ROI: region with %d/%d/%d/%d is added", - roi.rect.x, roi.rect.y, roi.rect.width, roi.rect.height); - } - } - gst_event_unref (event); - return ret; - } - break; - } - default: - break; - } - ret = GST_VIDEO_ENCODER_CLASS (gst_vaapiencode_parent_class)->sink_event (venc, event); if (!ret) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index f963de943f..96e6ef5818 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -58,80 +58,6 @@ * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapih264enc ! h264parse ! mp4mux ! filesink location=test.mp4 * ]| * - * - * - * Region of Interest - * Since libva supports Region Of Interest for avc encoding depending on H/W, - * GStreamer VA-API supports it by #GstEvent. - * To enable ROI, an application must send an event of type GST_EVENT_CUSTOM_DOWNSTREAM, - * having a structure of name "GstVaapiEncoderRegionOfInterest" with fields set - * according to the following table: - * - * - * - * - * - * - * - * - * Name - * GType - * Description - * - * - * - * - * roi-value - * G_TYPE_INT - * specifies ROI delta QP or ROI priority. - * ROI delta QP is the value that will be added on top of the frame level QP. - * ROI priority specifies the priority of a region, it can be positive (more important) - * or negative (less important) values and is compared with non-ROI region (taken as value 0), - * - * - * - * - * roi-x - * G_TYPE_UINT - * X - * - * - * roi-y - * G_TYPE_UINT - * Y - * - * - * roi-width - * G_TYPE_UINT - * width - * - * - * roi-height - * G_TYPE_UINT - * height - * - * - * - * - * - * For example, the following code informs the encoder to enable ROI - * with a region for ROI. - * Note that if an application wants to disable the region, - * just send an event with roi-value=0 and same coordination. - * - * - * GstEvent *event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, - * gst_structure_new ("GstVaapiEncoderRegionOfInterest", - * "roi-x", G_TYPE_UINT, 1820, - * "roi-y", G_TYPE_UINT, 980, - * "roi-width", G_TYPE_UINT, 100, - * "roi-height", G_TYPE_UINT, 100, - * "roi-value", G_TYPE_INT, 4, NULL)); - * - * gst_element_send_event (pipeline, event); - * - * - * */ #include "gstcompat.h" From 35226dba88a47a0fe235a28123438e9177eeada1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 22 Feb 2018 14:29:19 -0600 Subject: [PATCH 3046/3781] Revert "tests: simple-encoder: add an option to set ROI" This reverts commit c21345c4787bb6342adddea1190f53fe62abff04. https://bugzilla.gnome.org/show_bug.cgi?id=768248 --- tests/simple-encoder.c | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/tests/simple-encoder.c b/tests/simple-encoder.c index a404e9a259..58b0e8c214 100644 --- a/tests/simple-encoder.c +++ b/tests/simple-encoder.c @@ -32,7 +32,6 @@ static guint g_bitrate = 0; static gchar *g_codec_str; static gchar *g_output_file_name; static char **g_input_files = NULL; -static gboolean g_roi_enable = FALSE; #define SURFACE_NUM 16 @@ -43,8 +42,6 @@ static GOptionEntry g_options[] = { "desired bitrate expressed in kbps", NULL}, {"output", 'o', 0, G_OPTION_ARG_FILENAME, &g_output_file_name, "output file name", NULL}, - {"roi", 'r', 0, G_OPTION_ARG_NONE, &g_roi_enable, - "enable region of interest", NULL}, {G_OPTION_REMAINING, ' ', 0, G_OPTION_ARG_FILENAME_ARRAY, &g_input_files, "input file name", NULL}, {NULL} @@ -61,7 +58,6 @@ typedef struct FILE *output_file; guint input_stopped:1; guint encode_failed:1; - GstVaapiROI roi_region[2]; } App; static inline gchar * @@ -184,35 +180,6 @@ set_format (GstVaapiEncoder * encoder, gint width, gint height, gint fps_n, return (status == GST_VAAPI_ENCODER_STATUS_SUCCESS); } -static void -add_roi (App * app) -{ - guint i; - gint width, height; - - width = app->parser->width; - height = app->parser->height; - - for (i = 0; i < 2; i++) { - app->roi_region[i].roi_value = 4; - app->roi_region[i].rect.x = i * width / 2; - app->roi_region[i].rect.y = i * height / 2; - app->roi_region[i].rect.width = width / 4; - app->roi_region[i].rect.height = height / 4; - - gst_vaapi_encoder_add_roi (app->encoder, &app->roi_region[i]); - } -} - -static void -del_roi (App * app) -{ - guint i; - - for (i = 0; i < 2; i++) - gst_vaapi_encoder_del_roi (app->encoder, &app->roi_region[i]); -} - static GstBuffer * allocate_buffer (GstVaapiCodedBuffer * vbuf) { @@ -326,9 +293,6 @@ app_free (App * app) { g_return_if_fail (app); - if (g_roi_enable) - del_roi (app); - if (app->parser) y4m_reader_close (app->parser); @@ -384,9 +348,6 @@ app_new (const gchar * input_fn, const gchar * output_fn) goto error; } - if (g_roi_enable) - add_roi (app); - return app; error: From d3110713b8c0c7ec3bd81e0422db5a56fff32042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 22 Feb 2018 08:22:35 -0600 Subject: [PATCH 3047/3781] Revert "libs: encoder: add api gst_vaapi_encoder_add/del_roi" This reverts commit 7a6f690340dcb3b82c59efa777d4453227851de8. https://bugzilla.gnome.org/show_bug.cgi?id=768248 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 108 ---------------------- gst-libs/gst/vaapi/gstvaapiencoder.h | 12 --- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 3 - 3 files changed, 123 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 1f8e0a1a01..71a7c1a02f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1323,9 +1323,6 @@ gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) klass->finalize (encoder); - if (encoder->roi_regions) - g_list_free_full (encoder->roi_regions, g_free); - gst_vaapi_object_replace (&encoder->context, NULL); gst_vaapi_display_replace (&encoder->display, NULL); encoder->va_display = NULL; @@ -1566,111 +1563,6 @@ gst_vaapi_encoder_ensure_max_num_ref_frames (GstVaapiEncoder * encoder, return TRUE; } -/** - * gst_vaapi_encoder_add_roi: - * @encoder: a #GstVaapiEncoder - * @roi: (transfer none): a #GstVaapiROI - * - * Adds a roi region provided by user. - * - * This can be called on running a pipeline, - * Since vaapi encoder set roi regions at every frame encoding. - * Note that if it exceeds number of supported roi in driver, - * this will return FALSE. - * - * Return value: a #gboolean - */ -gboolean -gst_vaapi_encoder_add_roi (GstVaapiEncoder * encoder, GstVaapiROI * roi) -{ - GstVaapiContextInfo *const cip = &encoder->context_info; - const GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; - GstVaapiROI *region = NULL; - GList *walk; - - g_return_val_if_fail (roi != NULL, FALSE); - - if (!config->roi_capability) - return FALSE; - - if (encoder->roi_regions && - g_list_length (encoder->roi_regions) > config->roi_num_supported) - return FALSE; - - walk = encoder->roi_regions; - while (walk) { - GstVaapiROI *region_ptr = (GstVaapiROI *) walk->data; - if (region_ptr->rect.x == roi->rect.x && - region_ptr->rect.y == roi->rect.y && - region_ptr->rect.width == roi->rect.width && - region_ptr->rect.height == roi->rect.height) { - /* Duplicated region */ - goto end; - } - walk = walk->next; - } - - region = g_malloc0 (sizeof (GstVaapiROI)); - if (G_UNLIKELY (!region)) - return FALSE; - - region->rect.x = roi->rect.x; - region->rect.y = roi->rect.y; - region->rect.width = roi->rect.width; - region->rect.height = roi->rect.height; - - encoder->roi_regions = g_list_append (encoder->roi_regions, region); - -end: - return TRUE; -} - -/** - * gst_vaapi_encoder_del_roi: - * @encoder: a #GstVaapiEncoder - * @roi: (transfer none): a #GstVaapiROI - * - * Deletes a roi region provided by user. - * - * This can be called on running a pipeline, - * Since vaapi encoder set roi regions at every frame encoding. - * - * Return value: a #gboolean - */ -gboolean -gst_vaapi_encoder_del_roi (GstVaapiEncoder * encoder, GstVaapiROI * roi) -{ - GstVaapiContextInfo *const cip = &encoder->context_info; - const GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; - GList *walk; - gboolean ret = FALSE; - - g_return_val_if_fail (roi != NULL, FALSE); - - if (!config->roi_capability) - return FALSE; - - if (encoder->roi_regions && g_list_length (encoder->roi_regions) == 0) - return FALSE; - - walk = encoder->roi_regions; - while (walk) { - GstVaapiROI *region = (GstVaapiROI *) walk->data; - if (region->rect.x == roi->rect.x && - region->rect.y == roi->rect.y && - region->rect.width == roi->rect.width && - region->rect.height == roi->rect.height) { - encoder->roi_regions = g_list_remove (encoder->roi_regions, region); - g_free (region); - ret = TRUE; - break; - } - walk = walk->next; - } - - return ret; -} - /** Returns a GType for the #GstVaapiEncoderTune set */ GType gst_vaapi_encoder_tune_get_type (void) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index d186905733..c610e8e1e4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -140,11 +140,6 @@ typedef struct { GParamSpec *const pspec; } GstVaapiEncoderPropInfo; -typedef struct _GstVaapiROI { - gint roi_value; - GstVaapiRectangle rect; -} GstVaapiROI; - GType gst_vaapi_encoder_tune_get_type (void) G_GNUC_CONST; @@ -206,13 +201,6 @@ gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); GArray * gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile); - -gboolean -gst_vaapi_encoder_add_roi (GstVaapiEncoder * encoder, GstVaapiROI * roi); - -gboolean -gst_vaapi_encoder_del_roi (GstVaapiEncoder * encoder, GstVaapiROI * roi); - G_END_DECLS #endif /* GST_VAAPI_ENCODER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index d71a49e1aa..2dccabce26 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -283,9 +283,6 @@ struct _GstVaapiEncoder guint got_packed_headers:1; guint got_rate_control_mask:1; - /* Region of Interest */ - GList *roi_regions; - /* miscellaneous buffer parameters */ VAEncMiscParameterRateControl va_ratecontrol; VAEncMiscParameterFrameRate va_framerate; From c49a17ed153c662b30bb5d4e61654bfee8ce7df9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 22 Feb 2018 14:20:42 -0600 Subject: [PATCH 3048/3781] libs: encoder: reimplement ROI using meta Check input buffers for ROI metas and pass them to VA. Also added a new "default-roi-delta-qp" property in order to tell the encoder what delta QP should be applied to ROI by default. Enabled it for H264 and H265 encoders. https://bugzilla.gnome.org/show_bug.cgi?id=768248 --- gst-libs/gst/vaapi/gstvaapicontext.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder.c | 119 +++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiencoder.h | 3 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 46 +-------- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 2 + gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 7 ++ 6 files changed, 131 insertions(+), 48 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 204e463308..afbf8b4b20 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -318,7 +318,7 @@ config_create (GstVaapiContext * context) roi_config = (VAConfigAttribValEncROI *) & value; if (roi_config->bits.num_roi_regions != config->roi_num_supported || VA_ROI_RC_QP_DELTA_SUPPORT (roi_config) == 0) { - GST_ERROR ("ROI unsupported - number of regions supported: %d" + GST_ERROR ("Mismatched ROI support: number of regions supported: %d" " ROI delta QP: %d", roi_config->bits.num_roi_regions, VA_ROI_RC_QP_DELTA_SUPPORT (roi_config)); goto cleanup; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 71a7c1a02f..caddb75478 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -193,6 +193,19 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) " higher value means lower-quality/fast-encode)", 1, 7, 4, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVapiEncoder:roi-default-delta-qp + * + * Default delta-qp to apply to each Region of Interest + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_PROP_DEFAULT_ROI_VALUE, + g_param_spec_int ("default-roi-delta-qp", "Default ROI delta QP", + "The default delta-qp to apply to each Region of Interest" + "(lower value means higher-quality, " + "higher value means lower-quality)", + -10, 10, -10, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } @@ -260,6 +273,99 @@ gst_vaapi_encoder_ensure_param_control_rate (GstVaapiEncoder * encoder, return TRUE; } +gboolean +gst_vaapi_encoder_ensure_param_roi_regions (GstVaapiEncoder * encoder, + GstVaapiEncPicture * picture) +{ +#if VA_CHECK_VERSION(0,39,1) + GstVaapiContextInfo *const cip = &encoder->context_info; + const GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; + VAEncMiscParameterBufferROI *roi_param; + GstVaapiEncMiscParam *misc; + VAEncROI *region_roi; + GstBuffer *input; + guint num_roi, i; + gpointer state = NULL; + + if (!config->roi_capability) + return TRUE; + + if (!picture->frame) + return FALSE; + + input = picture->frame->input_buffer; + if (!input) + return FALSE; + + num_roi = + gst_buffer_get_n_meta (input, GST_VIDEO_REGION_OF_INTEREST_META_API_TYPE); + if (num_roi == 0) + return TRUE; + num_roi = CLAMP (num_roi, 1, config->roi_num_supported); + + misc = + gst_vaapi_enc_misc_param_new (encoder, VAEncMiscParameterTypeROI, + sizeof (VAEncMiscParameterBufferROI) + num_roi * sizeof (VAEncROI)); + if (!misc) + return FALSE; + + region_roi = + (VAEncROI *) ((guint8 *) misc->param + sizeof (VAEncMiscParameterBuffer) + + sizeof (VAEncMiscParameterBufferROI)); + + roi_param = misc->data; + roi_param->num_roi = num_roi; + roi_param->roi = region_roi; + + /* roi_value in VAEncROI should be used as ROI delta QP */ + roi_param->roi_flags.bits.roi_value_is_qp_delta = 1; + roi_param->max_delta_qp = 10; + roi_param->min_delta_qp = -10; + + for (i = 0; i < num_roi; i++) { + GstVideoRegionOfInterestMeta *roi; + GstStructure *s; + + roi = (GstVideoRegionOfInterestMeta *) + gst_buffer_iterate_meta_filtered (input, &state, + GST_VIDEO_REGION_OF_INTEREST_META_API_TYPE); + + /* ignore roi if overflow */ + if ((roi->x > G_MAXINT16) || (roi->y > G_MAXINT16) + || (roi->w > G_MAXUINT16) || (roi->h > G_MAXUINT16)) + continue; + + GST_LOG ("Input buffer ROI: type=%s id=%d (%d, %d) %dx%d", + g_quark_to_string (roi->roi_type), roi->id, roi->x, roi->y, roi->w, + roi->h); + + region_roi[i].roi_rectangle.x = roi->x; + region_roi[i].roi_rectangle.y = roi->y; + region_roi[i].roi_rectangle.width = roi->w; + region_roi[i].roi_rectangle.height = roi->h; + + s = gst_video_region_of_interest_meta_get_param (roi, "roi/vaapi"); + if (s) { + int value = 0; + + if (!gst_structure_get_int (s, "delta-qp", &value)) + continue; + value = CLAMP (value, roi_param->min_delta_qp, roi_param->max_delta_qp); + region_roi[i].roi_value = value; + } else { + region_roi[i].roi_value = encoder->default_roi_value; + + GST_LOG ("No ROI value specified upstream, use default (%d)", + encoder->default_roi_value); + } + } + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); +#endif + return TRUE; +} + /** * gst_vaapi_encoder_ref: * @encoder: a #GstVaapiEncoder @@ -656,8 +762,13 @@ get_roi_capability (GstVaapiEncoder * encoder, guint * num_roi_supported) roi_config = (VAConfigAttribValEncROI *) & value; - if (roi_config->bits.num_roi_regions == 0 || - VA_ROI_RC_QP_DELTA_SUPPORT (roi_config) == 0) + if (roi_config->bits.num_roi_regions == 0) + return FALSE; + + /* Only support QP delta, and it only makes sense when rate control + * is not CQP */ + if ((GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CQP) + && (VA_ROI_RC_QP_DELTA_SUPPORT (roi_config) == 0)) return FALSE; GST_INFO ("Support for ROI - number of regions supported: %d", @@ -982,6 +1093,10 @@ set_property (GstVaapiEncoder * encoder, gint prop_id, const GValue * value) status = gst_vaapi_encoder_set_quality_level (encoder, g_value_get_uint (value)); break; + case GST_VAAPI_ENCODER_PROP_DEFAULT_ROI_VALUE: + encoder->default_roi_value = g_value_get_int (value); + status = GST_VAAPI_ENCODER_STATUS_SUCCESS; + break; } return status; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index c610e8e1e4..974a70a9b2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -125,7 +125,8 @@ typedef enum { GST_VAAPI_ENCODER_PROP_BITRATE, GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, GST_VAAPI_ENCODER_PROP_TUNE, - GST_VAAPI_ENCODER_PROP_QUALITY_LEVEL + GST_VAAPI_ENCODER_PROP_QUALITY_LEVEL, + GST_VAAPI_ENCODER_PROP_DEFAULT_ROI_VALUE } GstVaapiEncoderProp; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 2355d912f3..a4e65b0067 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2514,10 +2514,6 @@ static gboolean ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); -#if VA_CHECK_VERSION(0,39,1) - GstVaapiEncMiscParam *misc; - guint num_roi; -#endif if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture)) return FALSE; @@ -2540,47 +2536,9 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) goto error_create_packed_sei_hdr; } } -#if VA_CHECK_VERSION(0,39,1) - /* region-of-interest params */ - num_roi = base_encoder->roi_regions ? - g_list_length (base_encoder->roi_regions) : 0; - if (num_roi > 0) { - /* ROI(Region of Interest) params */ - VAEncMiscParameterBufferROI *roi_param; - VAEncROI *region_roi; - gpointer ptr; - GList *tmp; - misc = - gst_vaapi_enc_misc_param_new (base_encoder, VAEncMiscParameterTypeROI, - sizeof (VAEncMiscParameterBufferROI) + num_roi * sizeof (VAEncROI)); - - roi_param = misc->data; - roi_param->roi_flags.bits.roi_value_is_qp_delta = 1; - roi_param->max_delta_qp = 10; - roi_param->min_delta_qp = 10; - - ptr = (guchar *) misc->param + sizeof (VAEncMiscParameterBuffer) + - sizeof (VAEncMiscParameterBufferROI); - region_roi = ptr; - - for (tmp = base_encoder->roi_regions; tmp; tmp = tmp->next) { - GstVaapiROI *item = tmp->data; - region_roi->roi_value = item->roi_value; - region_roi->roi_rectangle.x = item->rect.x; - region_roi->roi_rectangle.y = item->rect.y; - region_roi->roi_rectangle.width = item->rect.width; - region_roi->roi_rectangle.height = item->rect.height; - region_roi++; - } - - roi_param->roi = ptr; - roi_param->num_roi = num_roi; - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - } -#endif + if (!gst_vaapi_encoder_ensure_param_roi_regions (base_encoder, picture)) + return FALSE; if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 479294e926..87f3a6bc59 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1852,6 +1852,8 @@ ensure_misc_params (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture) if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture)) return FALSE; + if (!gst_vaapi_encoder_ensure_param_roi_regions (base_encoder, picture)) + return FALSE; if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) return FALSE; return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 2dccabce26..d3253a23cc 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -287,6 +287,8 @@ struct _GstVaapiEncoder VAEncMiscParameterRateControl va_ratecontrol; VAEncMiscParameterFrameRate va_framerate; VAEncMiscParameterHRD va_hrd; + + gint8 default_roi_value; }; struct _GstVaapiEncoderClassData @@ -413,6 +415,11 @@ 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_num_slices (GstVaapiEncoder * encoder, From e82fafc482a6c9136179f2c363cd7189f8d23e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 23 Feb 2018 10:48:36 -0600 Subject: [PATCH 3049/3781] tests: element: rewrite ROI test Rewrote the ROI test to use GstVideoRegionOfInterest meta rather than injecting GstEvents. These meta are added as a pad probe in the queue src pad. Also * Use of navigation messages to control de test * Use signal watch for processing messages * Change to H265 rather than H264 since current intel-vaapi-driver only supports ROI on kabylake. TODO: add a parameter to change the encoder/decoder to test. https://bugzilla.gnome.org/show_bug.cgi?id=768248 --- tests/elements/test-roi.c | 206 ++++++++++++++++++++++++++------------ 1 file changed, 140 insertions(+), 66 deletions(-) diff --git a/tests/elements/test-roi.c b/tests/elements/test-roi.c index 2818a10e5f..2ce614efa5 100644 --- a/tests/elements/test-roi.c +++ b/tests/elements/test-roi.c @@ -20,55 +20,129 @@ */ #include -#include #include +#include +#include typedef struct _CustomData { GstElement *pipeline; - GstPad *src_pad; GMainLoop *loop; + gboolean roi_enabled; } AppData; -static void -send_roi_event (AppData * data) -{ - gboolean res = FALSE; - GstEvent *event; - gint value[2] = { 4, 0 }; - static gint counter = 0; - - event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, - gst_structure_new ("GstVaapiEncoderRegionOfInterest", - "roi-x", G_TYPE_UINT, 0, - "roi-y", G_TYPE_UINT, 0, - "roi-width", G_TYPE_UINT, 320, - "roi-height", G_TYPE_UINT, 240, - "roi-value", G_TYPE_INT, value[counter++ % 2], NULL)); - - /* Send the event */ - res = gst_pad_push_event (data->src_pad, event); - g_print ("Sending event %p done: %d\n", event, res); -} - static void send_eos_event (AppData * data) { - GstBus *bus; - GstMessage *msg; - - bus = gst_element_get_bus (data->pipeline); gst_element_send_event (data->pipeline, gst_event_new_eos ()); - msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS); +} - gst_message_unref (msg); - gst_object_unref (bus); +static void +dispatch_keystroke (AppData * app, const gchar * str) +{ + switch (g_ascii_tolower (str[0])) { + case 'r': + app->roi_enabled = !app->roi_enabled; + gst_println ("ROI %s", app->roi_enabled ? "enabled" : "disabled"); + break; + case 'q': + send_eos_event (app); + break; + default: + break; + } + + return; +} + +static void +cb_msg (GstBus * bus, GstMessage * msg, gpointer data) +{ + AppData *app = data; + GstNavigationMessageType mtype = gst_navigation_message_get_type (msg); + GstEvent *ev = NULL; + GstNavigationEventType type; + const gchar *key; + + if (mtype != GST_NAVIGATION_MESSAGE_EVENT) + return; + if (!gst_navigation_message_parse_event (msg, &ev)) + goto bail; + + type = gst_navigation_event_get_type (ev); + if (type != GST_NAVIGATION_EVENT_KEY_PRESS) + goto bail; + if (!gst_navigation_event_parse_key_event (ev, &key)) + goto bail; + + dispatch_keystroke (app, key); + +bail: + if (ev) + gst_event_unref (ev); +} + +static void +cb_msg_eos (GstBus * bus, GstMessage * msg, gpointer data) +{ + AppData *app = data; + g_main_loop_quit (app->loop); +} + + +static void +cb_msg_error (GstBus * bus, GstMessage * msg, gpointer data) +{ + AppData *app = data; + gchar *debug = NULL; + GError *err = NULL; + + gst_message_parse_error (msg, &err, &debug); + + g_print ("Error: %s\n", err->message); + g_error_free (err); + + if (debug) { + g_print ("Debug details: %s\n", debug); + g_free (debug); + } + + g_main_loop_quit (app->loop); +} + +static GstPadProbeReturn +cb_add_roi (GstPad * pad, GstPadProbeInfo * info, gpointer data) +{ + AppData *app = data; + GstVideoRegionOfInterestMeta *rmeta; + GstBuffer *buf = GST_PAD_PROBE_INFO_BUFFER (info); + GstStructure *s; + + if (!app->roi_enabled) + return GST_PAD_PROBE_OK; + + buf = gst_buffer_make_writable (buf); + if (!buf) + return GST_PAD_PROBE_OK; + + rmeta = + gst_buffer_add_video_region_of_interest_meta (buf, "test", 0, 0, 320, + 240); + if (!rmeta) + return GST_PAD_PROBE_OK; + + s = gst_structure_new ("roi/vaapi", "delta-qp", G_TYPE_INT, -10, NULL); + gst_video_region_of_interest_meta_add_param (rmeta, s); + + GST_PAD_PROBE_INFO_DATA (info) = buf; + return GST_PAD_PROBE_OK; } /* Process keyboard input */ static gboolean -handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data) +handle_keyboard (GIOChannel * source, GIOCondition cond, gpointer data) { + AppData *app = data; gchar *str = NULL; if (g_io_channel_read_line (source, &str, NULL, NULL, @@ -76,20 +150,9 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data) return TRUE; } - switch (g_ascii_tolower (str[0])) { - case 'r': - send_roi_event (data); - break; - case 'q': - send_eos_event (data); - g_main_loop_quit (data->loop); - break; - default: - break; - } + dispatch_keystroke (app, str); g_free (str); - return TRUE; } @@ -97,7 +160,7 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data) * This is an example pipeline to recognize difference between ROI and non-ROI. * 1. Produce snow pattern with 320p * 2. Encode and decode the raw data with 2 pipelines at same time. - * 2.1. Inject a GstCustomEvent to the 2nd pipeline to enable ROI. + * 2.1. Insert GstVideoRegionOfInterestMeta to the 2nd pipeline buffers to enable ROI. * 3. Mix both streams in videomixer. * 5. Output the result in one window. * @@ -116,37 +179,41 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data) '--->Q->|txtovrly|->|enc|->|dec|->|vpp|->|videobox|->' ^ '--------' '---' '---' '---' '--------' | - '-- Injection of GstCustomEvent "GstVaapiEncoderRegionOfInterest" + '-- Insert GstVideoRegionOfInterestMeta width roit/vaapi params on buffers */ int main (int argc, char *argv[]) { - AppData data; + AppData data = { 0, }; GstStateChangeReturn ret; - GstElement *q; - GIOChannel *io_stdin; + GstElement *el; + GstPad *pad; GError *err = NULL; + GIOChannel *io_stdin; + GstBus *bus; + + data.roi_enabled = TRUE; /* Initialize GStreamer */ gst_init (&argc, &argv); /* Print usage map */ - g_print ("USAGE: Choose one of the following options, then press enter:\n" - " 'r' to send ROI event \n" " 'q' to quit\n"); + g_print ("USAGE: 'r' to enable/disable ROI && 'q' to quit\n"); -#define ENCDEC "vaapih264enc rate-control=cbr bitrate=2000 ! vaapih264dec ! vaapipostproc width=640 " -#define TEXT "textoverlay font-desc=\"Arial Bold 48\" text=" +#define SRC "videotestsrc pattern=snow ! " \ + "video/x-raw, format=NV12, width=320, framerate=5/1" +#define ENCDEC "vaapih265enc rate-control=cbr bitrate=2000 ! vaapih265dec ! " \ + "vaapipostproc ! video/x-raw, width=640" +#define TEXT "textoverlay font-desc=\"Arial Bold 48\" " data.pipeline = gst_parse_launch ("videomixer name=mix ! vaapipostproc ! vaapisink sync=false " - "videotestsrc pattern=snow ! video/x-raw, width=320, framerate=5/1 " - "! tee name=t " - "t. ! queue ! " TEXT "\"non-ROI\" ! " ENCDEC - "! videobox left=-640 ! mix. " - "t. ! queue name=roi ! " TEXT "\"ROI\" ! " ENCDEC - "! videobox ! mix.", &err); + SRC " ! tee name=t ! queue ! " TEXT " text=\"non-ROI\" ! " ENCDEC + " ! videobox left=-640 ! mix. " + " t. ! queue name=roi ! " TEXT " text=\"ROI\" ! " ENCDEC + " ! videobox ! mix.", &err); if (err) { g_printerr ("failed to parse pipeline: %s\n", err->message); @@ -154,13 +221,23 @@ main (int argc, char *argv[]) return -1; } - q = gst_bin_get_by_name (GST_BIN (data.pipeline), "roi"); - data.src_pad = gst_element_get_static_pad (q, "src"); - gst_object_unref (q); + bus = gst_pipeline_get_bus (GST_PIPELINE (data.pipeline)); + gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH); + gst_bus_enable_sync_message_emission (bus); + g_signal_connect (bus, "message::error", G_CALLBACK (cb_msg_error), &data); + g_signal_connect (bus, "message::eos", G_CALLBACK (cb_msg_eos), &data); + g_signal_connect (bus, "message::element", G_CALLBACK (cb_msg), &data); + gst_object_unref (bus); + + el = gst_bin_get_by_name (GST_BIN (data.pipeline), "roi"); + pad = gst_element_get_static_pad (el, "src"); + gst_object_unref (el); + gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, cb_add_roi, &data, NULL); + gst_object_unref (pad); /* Add a keyboard watch so we get notified of keystrokes */ io_stdin = g_io_channel_unix_new (fileno (stdin)); - g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc) handle_keyboard, &data); + g_io_add_watch (io_stdin, G_IO_IN, handle_keyboard, &data); /* Start playing */ ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING); @@ -176,12 +253,9 @@ main (int argc, char *argv[]) /* Free resources */ g_main_loop_unref (data.loop); - g_io_channel_unref (io_stdin); gst_element_set_state (data.pipeline, GST_STATE_NULL); - - if (data.src_pad) - gst_object_unref (data.src_pad); gst_object_unref (data.pipeline); + g_io_channel_unref (io_stdin); return 0; } From fde55003ca58ab6114bb903969674da8fe5f3f74 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 27 Feb 2018 16:20:15 -0500 Subject: [PATCH 3050/3781] postproc: Copy meta data from input to output This will ensure that meta data without memory tags will be copied. This was noticed when testing ROI. https://bugzilla.gnome.org/show_bug.cgi?id=768248 --- gst/vaapi/gstvaapipostproc.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 8ad3f2866e..d5a0557cd5 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1260,6 +1260,13 @@ gst_vaapipostproc_transform_size (GstBaseTransform * trans, return TRUE; } +static gboolean +gst_vaapipostproc_transform_meta (GstBaseTransform * trans, GstBuffer * outbuf, + GstMeta * meta, GstBuffer * inbuf) +{ + return TRUE; +} + static GstFlowReturn gst_vaapipostproc_transform (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer * outbuf) @@ -1325,6 +1332,7 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer ** outbuf_ptr) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + GstBaseTransformClass *bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); if (gst_base_transform_is_passthrough (trans)) { *outbuf_ptr = inbuf; @@ -1337,7 +1345,18 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, *outbuf_ptr = create_output_buffer (postproc); } - return *outbuf_ptr ? GST_FLOW_OK : GST_FLOW_ERROR; + if (!*outbuf_ptr) + return GST_FLOW_ERROR; + + if (inbuf != *outbuf_ptr && bclass->copy_metadata) { + if (!bclass->copy_metadata (trans, inbuf, *outbuf_ptr)) { + /* something failed, post a warning */ + GST_ELEMENT_WARNING (trans, STREAM, NOT_IMPLEMENTED, + ("could not copy metadata"), (NULL)); + } + } + + return GST_FLOW_OK; } static gboolean @@ -1673,6 +1692,7 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) trans_class->fixate_caps = gst_vaapipostproc_fixate_caps; trans_class->transform_caps = gst_vaapipostproc_transform_caps; trans_class->transform_size = gst_vaapipostproc_transform_size; + trans_class->transform_meta = gst_vaapipostproc_transform_meta; trans_class->transform = gst_vaapipostproc_transform; trans_class->set_caps = gst_vaapipostproc_set_caps; trans_class->query = gst_vaapipostproc_query; From 940afd290088ffe830a70db26def9aecc04b421b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 1 Mar 2018 07:33:27 -0600 Subject: [PATCH 3051/3781] vaapipostproc: change how the metadata is copied Instead of copying the metada in prepare_output_buffer() vmethod, it is done in append_output_buffer_metadata() thus deinterlaced buffers could also have the proper metas. GstVideoCropMeta now it is copied internally and it is decided via transform_meta() vmethod. A new internal method, copy_metadata() was added to handle VPP transformation where non-GstVideoVaapiMeta metas were lost. --- gst/vaapi/gstvaapipostproc.c | 45 +++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index d5a0557cd5..2b888214c9 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -402,6 +402,24 @@ create_output_dump_buffer (GstVaapiPostproc * postproc) &plugin->other_allocator_params); } +static void +copy_metadata (GstVaapiPostproc * postproc, GstBuffer * outbuf, + GstBuffer * inbuf) +{ + GstBaseTransformClass *bclass = GST_BASE_TRANSFORM_GET_CLASS (postproc); + GstBaseTransform *trans = GST_BASE_TRANSFORM (postproc); + + if (inbuf == outbuf) + return; + if (!bclass->copy_metadata) + return; + if (!bclass->copy_metadata (trans, inbuf, outbuf)) { + /* something failed, post a warning */ + GST_ELEMENT_WARNING (trans, STREAM, NOT_IMPLEMENTED, + ("could not copy metadata"), (NULL)); + } +} + static gboolean append_output_buffer_metadata (GstVaapiPostproc * postproc, GstBuffer * outbuf, GstBuffer * inbuf, guint flags) @@ -411,16 +429,7 @@ append_output_buffer_metadata (GstVaapiPostproc * postproc, GstBuffer * outbuf, gst_buffer_copy_into (outbuf, inbuf, flags | GST_BUFFER_COPY_FLAGS, 0, -1); - /* GstVideoCropMeta */ - if (!postproc->use_vpp) { - GstVideoCropMeta *const crop_meta = gst_buffer_get_video_crop_meta (inbuf); - if (crop_meta) { - GstVideoCropMeta *const out_crop_meta = - gst_buffer_add_video_crop_meta (outbuf); - if (out_crop_meta) - *out_crop_meta = *crop_meta; - } - } + copy_metadata (postproc, outbuf, inbuf); /* GstVaapiVideoMeta */ inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); @@ -755,6 +764,7 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) goto error_process_vpp; + copy_metadata (postproc, fieldbuf, inbuf); GST_BUFFER_TIMESTAMP (fieldbuf) = timestamp; GST_BUFFER_DURATION (fieldbuf) = postproc->field_duration; if (discont) { @@ -820,6 +830,7 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, discont = FALSE; } } + copy_metadata (postproc, outbuf, inbuf); if (deint && deint_refs) ds_add_buffer (ds, inbuf); @@ -1264,6 +1275,11 @@ static gboolean gst_vaapipostproc_transform_meta (GstBaseTransform * trans, GstBuffer * outbuf, GstMeta * meta, GstBuffer * inbuf) { + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + + /* dont' GstVideoCropMeta if use_vpp */ + if (meta->info->api == GST_VIDEO_CROP_META_API_TYPE && postproc->use_vpp) + return FALSE; return TRUE; } @@ -1332,7 +1348,6 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer ** outbuf_ptr) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - GstBaseTransformClass *bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); if (gst_base_transform_is_passthrough (trans)) { *outbuf_ptr = inbuf; @@ -1348,14 +1363,6 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, if (!*outbuf_ptr) return GST_FLOW_ERROR; - if (inbuf != *outbuf_ptr && bclass->copy_metadata) { - if (!bclass->copy_metadata (trans, inbuf, *outbuf_ptr)) { - /* something failed, post a warning */ - GST_ELEMENT_WARNING (trans, STREAM, NOT_IMPLEMENTED, - ("could not copy metadata"), (NULL)); - } - } - return GST_FLOW_OK; } From f6f981e371ba8b189174a0d8a18aac9c8ea6bfab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 3 Mar 2018 22:59:30 +0000 Subject: [PATCH 3052/3781] Release 1.13.90 --- ChangeLog | 3073 +++++++++++++++++++++++++++++++++++++++++- NEWS | 281 ++-- configure.ac | 14 +- gstreamer-vaapi.doap | 10 + meson.build | 2 +- 5 files changed, 3259 insertions(+), 121 deletions(-) diff --git a/ChangeLog b/ChangeLog index aafc3bad7c..da8e5d21aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,3024 @@ -=== release 1.12.0 === +=== release 1.13.90 === -2017-05-04 Sebastian Dröge +2018-03-03 22:59:30 +0000 Tim-Philipp Müller + + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.13.90 + +2018-03-01 07:33:27 -0600 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: change how the metadata is copied + Instead of copying the metada in prepare_output_buffer() vmethod, + it is done in append_output_buffer_metadata() thus deinterlaced + buffers could also have the proper metas. + GstVideoCropMeta now it is copied internally and it is decided via + transform_meta() vmethod. + A new internal method, copy_metadata() was added to handle VPP + transformation where non-GstVideoVaapiMeta metas were lost. + +2018-02-27 16:20:15 -0500 Nicolas Dufresne + + * gst/vaapi/gstvaapipostproc.c: + postproc: Copy meta data from input to output + This will ensure that meta data without memory tags will be copied. This + was noticed when testing ROI. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + +2018-02-23 10:48:36 -0600 Víctor Manuel Jáquez Leal + + * tests/elements/test-roi.c: + tests: element: rewrite ROI test + Rewrote the ROI test to use GstVideoRegionOfInterest meta rather + than injecting GstEvents. These meta are added as a pad probe in + the queue src pad. + Also + * Use of navigation messages to control de test + * Use signal watch for processing messages + * Change to H265 rather than H264 since current intel-vaapi-driver + only supports ROI on kabylake. + TODO: add a parameter to change the encoder/decoder to test. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + +2018-02-22 14:20:42 -0600 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: reimplement ROI using meta + Check input buffers for ROI metas and pass them to VA. Also added a + new "default-roi-delta-qp" property in order to tell the encoder what + delta QP should be applied to ROI by default. + Enabled it for H264 and H265 encoders. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + +2018-02-22 08:22:35 -0600 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + Revert "libs: encoder: add api gst_vaapi_encoder_add/del_roi" + This reverts commit 7a6f690340dcb3b82c59efa777d4453227851de8. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + +2018-02-22 14:29:19 -0600 Víctor Manuel Jáquez Leal + + * tests/simple-encoder.c: + Revert "tests: simple-encoder: add an option to set ROI" + This reverts commit c21345c4787bb6342adddea1190f53fe62abff04. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + +2018-02-21 10:56:47 -0600 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode_h264.c: + Revert "vaapiencode: handle custom event GstVaapiEncoderRegionOfInterest" + This reverts commit 8f1b88dac0e64a211325cdcb2cda693b80229bd1. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + +2018-02-23 09:25:51 -0600 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: copy input buffer metas + When importing buffers to a VA-base buffer, it is required to copy + the metas in the original buffer, otherwise information will be + lost, such as GstVideoRegionOfInterestMeta. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + +2018-02-27 06:10:09 -0600 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface.c: + libs: surface: cast to uintptr_t pointer + According to Debian package auto-building, uintptr_t is not an + unsigned long in i386 arch, raising an "incompatible pointer type" + error. + This patch adds a casting for compiler's satisfaction in i386. + +2018-02-25 20:46:56 -0600 Matteo Valdina + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: add zero as valid value for periodic keyframe. + Enabled zero as valid value for keyframe-period property. + https://bugzilla.gnome.org/show_bug.cgi?id=793829 + +2018-02-22 08:24:12 -0600 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: code-style fix + +2018-02-17 18:32:11 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: generate system allocated buffers + Generate system allocated output buffers when downstream doesn't + support GstVideoMeta. + The VA buffer content is copied to the new output buffer, and it + replaces the VA buffer. + https://bugzilla.gnome.org/show_bug.cgi?id=785054 + +2018-02-15 19:32:37 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: handle system allocated buffers when required + When downstream can't handle GstVideoMeta it is required to send + system allocated buffers. + The system allocated buffers are produced in prepare_output_buffer() + vmethod if downstream can't handl GstVideoMeta. + At transform() vmethod if the buffer is a system allocated buffer, + a VA buffer is instanciated and replaces the out buffer. Later + the VA buffer is copied to the system allocate buffer and it + replaces the output buffer. + https://bugzilla.gnome.org/show_bug.cgi?id=785054 + +2018-02-15 19:32:19 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: add gst_vaapi_copy_va_buffer() + This helper function aims to copy buffers with VA memory to dumb + buffers, when GstVideoMeta is not available dowstream. + https://bugzilla.gnome.org/show_bug.cgi?id=785054 + +2018-02-15 19:29:51 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: add COPY_OUTPUT_FRAME flag + This patch add the member copy_output_frame and set it TRUE when + when downstream didn't request GstVideoMeta API, the caps are raw + and the internal allocator is the VA-API one. + https://bugzilla.gnome.org/show_bug.cgi?id=785054 + +2018-02-15 19:28:33 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: store the first downstream allocator if available + The allocator will be required if we need to allocate a buffer + to store the frame with the expected strides. + https://bugzilla.gnome.org/show_bug.cgi?id=785054 + +2018-02-20 02:25:13 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideobufferpool.h: + vaapibufferpool: add gst_vaapi_video_buffer_pool_copy_buffer() + This function will inform the element if it shall copy the generated + buffer by the pool to a system allocated buffer before pushing it + to downstream. + https://bugzilla.gnome.org/show_bug.cgi?id=785054 + +2018-02-15 19:22:08 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapibufferpool: don't change config when forcing video meta + VA-API based buffer might need a video meta because of different + strides. But when donwstream doesn't support video meta we need to + force the usage of video meta. + Before we changed the buffer pool configuration, but actually this + is a hack and we cannot rely on that for downstream. + This patch add a check fo raw video caps and allocator is VA-API, + then the option is enabled without changing the pool configuration. + In this case the element is responsible to copy the frame to a + simple buffer with the expected strides. + https://bugzilla.gnome.org/show_bug.cgi?id=785054 + +2018-02-20 09:15:05 -0600 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: set discont flag at vpp deinterlacing + When deinterlacing with VPP the discont flag was not forwarded to + the new created buffer. This patch sets the discont flag if input + buffer has it. + +2018-02-20 02:14:37 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.h: + vaapibufferpool: remove wrong gcc annotation + +2018-02-15 14:55:42 -0600 Matteo Valdina + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + * gst-libs/gst/vaapi/gstvaapifeipak_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h: + libs: encoder: h264,h265: extend max periodic keyframe. + Increased max values of periodic key frame for h26x codecs. + This allow more fine tunning of encoder that in certian scenario + want higher periodic key frame. + For example: it doesn't want a key frame each 10 seconds but + each 120 seconds. + https://bugzilla.gnome.org/show_bug.cgi?id=786320 + +2018-02-15 19:44:35 +0000 Tim-Philipp Müller * configure.ac: - releasing 1.12.0 + * meson.build: + Back to development + +=== release 1.13.1 === + +2018-02-15 17:39:16 +0000 Tim-Philipp Müller + + * Makefile.am: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.13.1 + +2018-02-15 18:15:33 +0000 Tim-Philipp Müller + + * gst/vaapi/Makefile.am: + vaapi: dist new header + +2018-02-12 17:53:58 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + vaapi: register vaapisink as marginal on wayland + vaapsink, when used with the Intel VA-API driver, tries to display + surfaces with format NV12, which are handled correctly by + Weston. Nonetheless, COGL cannot display YUV surfaces, making fail + pipelines on mutter. + This shall be solved either by COGL or by making the driver to paint + RGB surfaces. In the meanwhile, let's just demote vaapisink as + marginal when the Wayland environment is detected, no matter if it is + Weston. + https://bugzilla.gnome.org/show_bug.cgi?id=775698 + +2018-02-12 19:00:36 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: update mesa's vendor string in whitelist + Mesa has updated its VA-API Gallium driver vendor string: + https://cgit.freedesktop.org/mesa/mesa/commit/?id=5db29d62ce1fefa3f2ee6e4a4688576fde4bde4a + This patch tries to cover both, the old and the new one. + https://bugzilla.gnome.org/show_bug.cgi?id=793386 + +2018-02-08 19:22:17 +0000 Tim-Philipp Müller + + * meson.build: + meson: make version numbers ints and fix int/string comparison + WARNING: Trying to compare values of different types (str, int). + The result of this is undefined and will become a hard error + in a future Meson release. + +2018-02-07 09:13:26 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: handle vaapi allocator in allocation query + In propose_allocation() if the numer of allocation params is zero, the + system's allocator is added first, and lastly the native VA-API + allocator. + In decide_allocation(), the allocations params in query are travered, + looking for a native VA-API allocator. If it is found, it is reused as + src pad allocator. Otherwise, a new allocator is instantiated and + appended in the query. + https://bugzilla.gnome.org/show_bug.cgi?id=789476 + +2018-02-07 09:06:46 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: remove unused macro + GST_VAAPI_VIDEO_ALLOCATOR_NAME was added in commit 5b11b8332 but it + was never used, since the native VA-API allocator name has been + GST_VAAPI_VIDEO_MEMORY_NAME. + This patch removes GST_VAAPI_VIDEO_ALLOCATOR_NAME macro. + https://bugzilla.gnome.org/show_bug.cgi?id=789476 + +2018-02-02 08:54:00 +0000 VaL Doroshchuk + + * gst/vaapi/gstvaapisink.c: + vaapisink: don't mask button events for foreign windows + Don't subscribe to button press events when using a foreing window, + because the user created window would trap those events, preveting the + show of frames. + https://bugzilla.gnome.org/show_bug.cgi?id=791615 + +2018-02-05 08:51:56 +0100 Tim-Philipp Müller + + * configure.ac: + autotools: use -fno-strict-aliasing where supported + https://bugzilla.gnome.org/show_bug.cgi?id=769183 + +2018-01-30 20:38:37 +0000 Tim-Philipp Müller + + * meson.build: + meson: use -fno-strict-aliasing where supported + https://bugzilla.gnome.org/show_bug.cgi?id=769183 + +2018-01-30 12:56:49 +0000 Philippe Normand + + * gst/vaapi/gstvaapi.c: + vaapi: add NULL-sentinel to kernel_names + The array needs to be NULL-terminated according to the + gst_plugin_add_dependency() documentation. + +2018-01-18 18:53:29 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: remove spurious code + This assignation is dead code, since gst_video_info_from_caps() set + to 1 by default. + https://bugzilla.gnome.org/show_bug.cgi?id=790149 + +2018-01-18 18:51:57 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: if no p-a-r in out caps define a range + Instead of copying the pixel-aspect-ratio from the sink caps, define + an open range for the src caps pixel-aspect-ratio. Later it will be + defined. + https://bugzilla.gnome.org/show_bug.cgi?id=790149 + +2018-01-18 13:10:59 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: check for display's color-balance properties + Check for display's color-balance properties, available by the VA-API + driver, before setting them. + Also logs an info message of those unavailable properties. + https://bugzilla.gnome.org/show_bug.cgi?id=792638 + +2018-01-17 17:30:50 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: re-using buffer pool breaks renegotiation + at propose_allocation() we should not reuse the proposed buffer, + because it could break renegotiation. + https://bugzilla.gnome.org/show_bug.cgi?id=792620 + +2018-01-17 17:26:24 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: use g_clear_object() to unref sinkpad_buffer_pool + https://bugzilla.gnome.org/show_bug.cgi?id=792620 + +2018-01-17 12:42:12 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/meson.build: + build: meson: add missing GstGL dependency + +2018-01-17 12:41:54 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + libs: utils: egl: add missing guards for GstGL + +2018-01-11 11:48:02 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: remove dmabuf-import hack + Remove the hack to check if an upstream element has enabled the + property io-mode enabled as dmabuf-import. + https://bugzilla.gnome.org/show_bug.cgi?id=792034 + +2017-12-01 15:04:35 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.h: + libs: egl: utils: use eglGetPlatformDisplay() + eglGetDisplay() is currently broken in Mesa for Wayland. Also using + eglGetDisplay() is rather fragile, and it is recommended to use + eglGetPlatformDisplay() when possible. + In order to do that, this patch uses the helper in GstGL. If + gstreamer-vaapi is not compiled with GstGL support, eglGetDisplay() + will be used. + https://bugzilla.gnome.org/show_bug.cgi?id=790493 + +2017-12-08 14:46:02 +0100 Michael Tretter + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: lock ensure_filter with postproc_lock + gst_vaapipostproc_ensure_filter might free the allowed_srcpad_caps + and allowed_sinkpad_caps. This can race with copying these caps in + gst_vaapipostproc_transform_caps and lead to segfaults. + The gst_vaapipostproc_transform_caps function already locks + postproc_lock before copying the caps. Make sure that calls to + gst_vaapipostproc_ensure_filter also acquire this lock. + https://bugzilla.gnome.org/show_bug.cgi?id=791404 + +2018-01-10 17:10:28 +0100 Víctor Manuel Jáquez Leal + + * tests/test-filter.c: + tests: test-filter: fix dereference before null check + Null-checking op_info suggests that it may be null, but it has already + been dereferenced on all paths leading to the check. + There may be a null pointer dereference, or else the comparison + against null is unnecessary. + +2018-01-10 17:06:53 +0100 Víctor Manuel Jáquez Leal + + * tests/y4mreader.c: + tests: y4mreader: fix string state checkup + str cannot be null in that moment, but it may be the end of string. + +2018-01-10 16:59:56 +0100 Víctor Manuel Jáquez Leal + + * tests/y4mreader.c: + tests: y4mreader: use int for fgetc + Assigning the return value of fgetc to char truncates its value. + It will not be possible to distinguish between EOF and a valid + character. + +2018-01-10 16:48:07 +0100 Víctor Manuel Jáquez Leal + + * tests/y4mreader.c: + tests: y4mreader: fix incompatible cast + Passed pointer in parse_int() are unsigned int (32 bits, unsigned) but + they are dereferenced as a wider long (64 bits, signed). This may lead + to memory corruption. + +2017-12-19 16:01:10 +0000 Tim-Philipp Müller + + * meson.build: + meson: fix fallback for gstreamer-gl-1.0, it's now in -base + +2017-12-14 14:53:27 +1100 Matthew Waters + + * common: + Automatic update of common submodule + From e8c7a71 to 3fa2c9e + +2017-12-06 16:11:46 -0500 Nicolas Dufresne + + * gst/vaapi/gstvaapivideocontext.c: + videoconvert: gst_element_post_message() is transfer full on msg + For this reson we need not to unref the message, even if it failed. + +2017-12-06 16:11:25 -0500 Nicolas Dufresne + + * gst/vaapi/gstvaapivideocontext.c: + Revert "vaapivideocontext: possible memleak when no bus attached" + This reverts commit 0438a3e62660e64ed390b6bb83bfb560b91664aa. + +2017-12-01 23:03:32 +0100 Víctor Manuel Jáquez Leal + + * tests/elements/test-vaapicontext.c: + test: vaapicontext: process have-context bus message + +2017-11-29 18:29:45 +0100 Víctor Manuel Jáquez Leal + + * tests/elements/test-vaapicontext.c: + test: vaapicontext: app context is not persistent + +2017-11-29 11:02:03 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + vaapivideocontext: only vaapisink process app context + gst.vaapi.app.Display context is made for applications that will + provide the VA display and the native display to used by the + pipeline, when are using vaapisink as overlay. There are no use + case for encoders, decoders, neither for the postprocessor. + In the case of the vaapisink, it shall query for gst.vaapi.Display + upstream first, and then, if there is no reply, + gst.vaapi.app.Display context will be posted in the bus for the + application. If the application replies, a GstVaapiDisplay object + is instantiated given the context info, otherwise a + GstVaapiDisplay is created with the normal algorithm to guess the + graphics platform. Either way, the instantiated GstVaapiDisplay + is propagated among the pipeline and the have-message bus message. + Also only vaapisink will process the gst.vaapi.app.Display, if + and only if, it doesn't have a display already set. This is + caused because if vaapisink is in a bin (playsink, for example) + the need-context is posted twice, leading to an error state. + https://bugzilla.gnome.org/show_bug.cgi?id=790999 + +2017-12-01 20:21:54 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + vaapivideocontext: log the name of GstVaapiDisplay + https://bugzilla.gnome.org/show_bug.cgi?id=790999 + +2017-11-30 14:24:43 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + vaapivideocontext: possible memleak when no bus attached + https://bugzilla.gnome.org/show_bug.cgi?id=790999 + +2017-11-27 13:04:24 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.h: + libs: window: wayland: remove unused header include + Remove wayland-client.h include since there is no exposed symbols from + it. + +2017-11-27 12:18:56 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h264,h265: guard rate control's macroblock + macroblock parameter appear on VA-API 1.0.0. It should be guarded. + +2017-11-27 20:17:55 +1100 Matthew Waters + + * common: + Automatic update of common submodule + From 3f4aa96 to e8c7a71 + +2016-07-29 14:58:49 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: Add Hierarchical-B encode + Frames are encoded as different layers. Frame in a particular + layer will use pictures in lower or same layer as references. + Which means decoder can drop the frames in upper layer but still + decode lower layer frames. + B-frames, except the one in top most layer, are reference frames. + All the base layer frames are I or P. + eg: with 3 temporal layers + T3: B1 B3 B5 B7 + T2: B2 B6 + T1: I0 P4 P8 + T1, T2, T3: Temporal Layers + P1...Pn: P-Frames: + B1...Bn: B-frames: + T1: I0->P4 , P4->P8 etc.. + T2: I0--> B2 <-- P4 + T3: I0--> B1 <-- B2, B2 --> B3 <-- P4 + Signed-off-by: Sreerenj Balachandran + https://bugzilla.gnome.org/show_bug.cgi?id=788918 + +2016-07-28 18:33:23 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: Add Hierarchical-P encode + Frames are encoded as different layers. A frame in a particular + layer will use pictures in lower or same layer as references. + Which means decoder can drop the frames in upper layer but still + decode lower layer frames. + eg: with 3 temporal layers + T3: P1 P3 P5 P7 + T2: P2 P6 + T1: P0 P4 P8 + T1, T2, T3: Temporal Layers + P1...pn: P-Frames: + P0->P1 , P0->P2, P2->P3, P0->P4......repeat + Signed-off-by: Sreerenj Balachandran + https://bugzilla.gnome.org/show_bug.cgi?id=788918 + +2016-07-28 16:51:28 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: Fix frame_num generation + The frame_num generation was not correctly implemented. + According to h264 spec, frame_num should get incremented + for each frame if previous frame is a referece frame. + For eg: IPBPB sequece should have the frame numbers 0,1,2,2,3 + Signed-off-by: Sreerenj Balachandran + https://bugzilla.gnome.org/show_bug.cgi?id=788918 + +2016-07-28 15:53:48 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + libs: encoder: h264: Add new property "prediction-type" + Adds new property "prediction-type" to select different reference + picture selection modes like hierarchical-p, hierarchical-b etc. + Signed-off-by: Sreerenj Balachandran + https://bugzilla.gnome.org/show_bug.cgi?id=788918 + +2016-07-28 15:12:05 +0300 XuGuangxin + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + libs: encoder: h264: Add machinery for implementing hierarchical-prediction + Adds some basic building blocks to ease the implementation + of hierarchical prediction modes. + -- add an utility method to find temporal level of each frame + -- define max_ref_frame count based on temporal level count + -- add temporal_level_div[] for finding temporal level each frame + to be encoded. + -- find ip_period based on temporal level count + Signed-off-by: Sreerenj Balachandran + https://bugzilla.gnome.org/show_bug.cgi?id=788918 + +2016-07-28 14:17:53 +0300 XuGuangxin + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + libs: encoder: h264: Add property "temporal-levels" + Adds new property "temporal-levels" to select the number of + temporal levels to be included in the encoded stream. + Signed-off-by: Sreerenj Balachandran + https://bugzilla.gnome.org/show_bug.cgi?id=788918 + +2016-07-27 16:41:01 +0300 XuGuangxin + + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + libs: encoder: objects: Add a reference flag + We can have p-frame as non-ref and also b-frame as ref + which are not supported yet. Reference flag + is the first machinery needed for more advanced + reference picture selection modes. + Signed-off-by: Sreerenj Balachandran + https://bugzilla.gnome.org/show_bug.cgi?id=788918 + +2017-11-02 13:21:34 +0100 Daniel van Vugt + + * gst-libs/gst/vaapi/gstvaapisurface_egl.c: + libs: surface: egl: add comment + Add a warning comment when using old intel-vaapi-drivers (>1.8.4), + where the creation of surfaces from GEM fd may fail. + https://bugzilla.gnome.org/show_bug.cgi?id=773453 + +2017-10-10 13:38:21 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.h: + * gst-libs/gst/vaapi/gstvaapitexture_egl.c: + libs: display: egl: add gst_vaapi_display_egl_set_current_display() + Adds a new function that changes the internal EGL display to the + current one (eglGetCurrentDisplay()) and sets the current context + too (eglGetCurrentContext()). + This new function is called by gst_vaapi_texture_egl_create() updating + the GstVaapiDisplayEGL with the current EGL display. + https://bugzilla.gnome.org/show_bug.cgi?id=773453 + +2017-10-09 16:02:11 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapitexture_egl.c: + libs: texture: egl: update EGL display and context + It is required to use the context of the calling thread when wrapping + a foreign texture. According the documentation of + GstVideoGLTextureUploadMeta: + "The caller of gst_video_gl_texture_upload_meta_upload() must + have OpenGL set up and call this from a thread where it is valid + to upload something to an OpenGL texture." + This patch updates the EGL display and context in GstVaapiDisplay + instance to the one used by te renderer that uploads the texture. + Original-patch-by: Daniel van Vugt + https://bugzilla.gnome.org/show_bug.cgi?id=773453 + +2017-10-10 19:53:04 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: centralize assignation of GL objects + Add plugin_set_gst_gl() where the GstGL objects are assigned. + https://bugzilla.gnome.org/show_bug.cgi?id=773453 + +2017-10-10 19:13:35 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: set GL objects if ensured + Only set the GL display and GL other context if they are ensured. + https://bugzilla.gnome.org/show_bug.cgi?id=773453 + +2017-10-10 17:14:15 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: set GL objects if context is handled + Only set the GL display and GL other context if they are extracted + correctly from the gstreamer's context. + https://bugzilla.gnome.org/show_bug.cgi?id=773453 + +2017-10-10 19:57:45 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: fix memory leak when GL context is created + When the GL display and context are created inside an VAAPI element + the created GL context is leaked. + https://bugzilla.gnome.org/show_bug.cgi?id=773453 + +2017-10-10 14:01:59 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + libs: display: egl: free leaked memory + The EGL VAAPI display forgot to release the egl display, context and + proxied VAAPI display. + https://bugzilla.gnome.org/show_bug.cgi?id=773453 + +2017-10-05 19:25:08 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapitexture_egl.c: + libs: texture: egl: code style + https://bugzilla.gnome.org/show_bug.cgi?id=773453 + +2017-10-04 13:51:23 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface_egl.c: + libs: surface: egl: error message if no extension + Instead of silently fail to export the image if there is not available + the EGL_MESA_drm_image, log an error message. Also a code refactoring + was done. + https://bugzilla.gnome.org/show_bug.cgi?id=773453 + +2017-10-31 13:10:50 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: direct rendering on memory:VASurface + As buffers negotiated with memory:VASurface caps feature can also be + mapped, they can also be configured to use VA derived images, in other + words "direct rendering". + Also, because of the changes in dmabuf allocator as default allocator, + the code for configuring the direct rendering was not clear. + This patch cleans up the code and enables direct rendering when the + environment variable GST_VAAPI_ENABLE_DIRECT_RENDERING is defined, + even then the memory:VASurface cap feature is negotiated. + https://bugzilla.gnome.org/show_bug.cgi?id=786054 + +2017-10-04 11:54:31 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + plugins: only dmabuf on srcpad if downstream + Set if source pad can handle dmabuf only if the GstGL context comes + from downstream. + It is possible to know that at two moments: + 1\ In the case of GstGLTextureUpload caps feature is negotiated and + downstream pool reports back gst.gl.GstGLContext. + 2\ When GstGLContext is found as GstContext from dowstream. + https://bugzilla.gnome.org/show_bug.cgi?id=788503 + +2017-10-04 11:52:32 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideocontext.c: + vaapivideocontext: add inline documentation + Document function gst_vaapi_find_gl_local_context(). + https://bugzilla.gnome.org/show_bug.cgi?id=788503 + +2017-10-04 11:50:25 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + vaapivideocontext: return the direction of gl context + In function gst_vaapi_find_gl_context() add a direction parameter to + return back the direction where the GstGL context was found. + This is going to be useful when checking if downstream can import + dmabuf-based buffers. + https://bugzilla.gnome.org/show_bug.cgi?id=788503 + +2017-10-04 08:30:51 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: add gst_vaapi_plugin_base_set_srcpad_can_dmabuf() + This patch refactors the code by adding the function + vaapi_plugin_base_set_srcpad_can_dmabuf(), it determines if the passed + GstGLContext can handle dmabuf-based buffers. + The function is exposed publicly since it is intended to be used later + at GstVaapiDisplay instantiation. + https://bugzilla.gnome.org/show_bug.cgi?id=788503 + +2017-10-20 12:37:15 +0200 Hyunjun Ko + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: allow to set property on runtime + Tis patch, allows some properties that we want to be set on + runtime. (eg. bitrate) + Note that all properties are under control by num_codedbuf_queued. + https://bugzilla.gnome.org/show_bug.cgi?id=786321 + +2017-09-15 15:38:18 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: allow to set bitrate on runtime + In case of streaming, controlling bitrate dynamically for encoder might be + important to manage quality of the streaming. + This patch is to support such a scenario. + https://bugzilla.gnome.org/show_bug.cgi?id=786321 + +2017-10-10 11:35:24 +0300 Sebastian Dröge + + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapi.h: + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: Register element if no VPP support is available too + VPP support is only needed for advanced deinterlacing, which is not + enabled by default either. Error out if it is selected but VPP is not + supported, and otherwise just work without VPP support. + https://bugzilla.gnome.org/show_bug.cgi?id=788758 + +2017-10-16 11:57:16 +0200 Thibault Saunier + + * gst/vaapi/gstvaapipluginutil.c: + Avoid infinite loop when vaapi_create_display fails + Which might be the case when using, for example, xvfb. + +2017-10-02 18:53:21 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: log warn if display fail + gstreamer-vaapi initializes the display by trial-and-error, thus + logging an error message if the display initialisation fails the user + may be weary of the error message in the screen, if using VA-API 1.0 + This commit set the VA error log handler to GStreamer warning level + while calling vaInitialize() and set it to error after that. + https://bugzilla.gnome.org/show_bug.cgi?id=783169 + +2017-09-29 20:05:22 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: try to create test display in order + When creating the test display for querying capabilites, it try in + certain order: DRM, Wayland and finally X11. GLX nor EGL are tried + since they are either composited with X11 or Wayland. + The reason for this is to reduce the posibility of failure that could + blacklist the plugin. + https://bugzilla.gnome.org/show_bug.cgi?id=782212 + +2017-09-29 15:07:47 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + libs: display: delay getting screen resolution + Instead of extracting the screen resolution at GstVaapiDisplay + creation, this patch delay it until the screen size is requested for + first time. + https://bugzilla.gnome.org/show_bug.cgi?id=782212 + +2017-09-28 18:58:17 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + libs: display: egl: avoid two vaDisplay instantiates + GstVaapiDisplayEGL is a wrapper of another GstVaapiDisplay, either X11 + or Wayland. Nonetheless it created another vaDisplay for it, instead + of using the wrapped one. + This patch enables the reuse of the wrapped vaDisplay avoiding + instantiating two. + https://bugzilla.gnome.org/show_bug.cgi?id=782212 + +2017-09-28 17:45:00 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + libs: display: remove display_type from display info + Since it's no required to pass the display type in the display info, + the structure member is removed. + https://bugzilla.gnome.org/show_bug.cgi?id=782212 + +2017-09-28 17:35:01 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + libs: display: remove display_type member + It is not used any more since GstVaapiDisplay was ported as a + GstObject-based. This information is part of the class information. + https://bugzilla.gnome.org/show_bug.cgi?id=782212 + +2017-09-28 16:12:23 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + libs: display: remove parent member + Parent was a crumb left from display cache. + https://bugzilla.gnome.org/show_bug.cgi?id=782212 + +2017-10-03 13:06:33 +0200 Sebastian Dröge + + * gst/vaapi/gstvaapi.c: + vaapi: Also register vaapipostproc without VPP support + It can still do simple deinterlacing then. + +2017-10-03 10:51:06 +0200 Sebastian Dröge + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: Allow running without VPP support + We returned FALSE from ::start() if VPP support is not available, but it + is only really needed for complex filters and during transform we check + for that. For simple deinterlacing it is not needed. + +2017-09-27 18:35:20 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: use scoped variable for return value + Instead of reusing a parameter variable for the return value of + gst_vaapipostproc_transform_caps(), this patch uses the function + scoped pointer. Thus, the code is cleaner. + https://bugzilla.gnome.org/show_bug.cgi?id=785706 + +2017-09-27 18:32:03 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: removed unused parameter + Removed caps parameter from gst_vaapipostproc_transform_caps_impl() + helper function since the it is not used. + https://bugzilla.gnome.org/show_bug.cgi?id=785706 + +2017-09-27 13:32:34 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: use scoped variable for return value + Instead of reusing a parameter variable for the return value of + gst_vaapipostproc_fixate_caps(), this patch uses the function scoped + pointer. Thus, the code is cleaner. + https://bugzilla.gnome.org/show_bug.cgi?id=785706 + +2017-09-27 11:27:40 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.h: + plugins: memory:DMABuf only handles planar formats + When glimagesink negotiates the caps feature memory:DMABuf the + exported dmabufs buffers with NV12 format are not well rendered, thus + setting only planar. + https://bugzilla.gnome.org/show_bug.cgi?id=788229 + +2017-09-25 17:04:12 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: flush pending frames before set format + Flush pending frames, if any, in the internal encorder, before setting + the new negotiated format. + https://bugzilla.gnome.org/show_bug.cgi?id=786173 + +2017-09-25 15:50:19 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: drain pending frames before set format + Drain pending frames, if any, in the internal decoder before setting + the new negotiated format. + https://bugzilla.gnome.org/show_bug.cgi?id=786173 + +2017-09-22 19:35:04 +0200 Víctor Manuel Jáquez Leal + + * tests/test-display.c: + tests: display: use GObject getter + Instead of using the gst_vaapi_display_get_property(), this patch + replaces it with g_object_get_property() to dump the available VA + display properties. + https://bugzilla.gnome.org/show_bug.cgi?id=788058 + +2017-09-22 19:25:20 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: use GObject setter and getter + Instead of using gst_vaapi_display_set_property() or + gst_vaapi_display_get_property(), this patch set replace it usage + with g_object_set() or g_object_get(). + Also the internal helper cb_set_value() is removed since it is not + used anymore. + https://bugzilla.gnome.org/show_bug.cgi?id=788058 + +2017-09-22 18:59:49 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: initialize value if they are not yet + This is a difference between the GObject API and the GstVaapi one: the + GValue passed to get a property value, in GObject has to be + initialized with g_value_init(), but in GstVaapi is has not. + In order to overcome this mismatch, this patch call g_value_init() + internally only in the passed one is not already initialized. + https://bugzilla.gnome.org/show_bug.cgi?id=788058 + +2017-09-22 17:04:17 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: optimize properties setters and getters + Shuffled some code to avoid to find the properties descriptor in the + array twice, adding the internal functions _set_property() and + _get_property(). + https://bugzilla.gnome.org/show_bug.cgi?id=788058 + +2017-09-22 16:29:02 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: install properties in class + Install the properties in the class as a normal GObject. Implement + set_property() and get_property() vmethods. + https://bugzilla.gnome.org/show_bug.cgi?id=788058 + +2017-09-22 15:16:34 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: remove gst_vaapi_display_properties_init() + Remove gst_vaapi_display_properties_init() since it can be unrolled in + gst_vaapi_display_class_init() + https://bugzilla.gnome.org/show_bug.cgi?id=788058 + +2017-09-22 15:12:05 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: remove libgstvaapi_init_once() + It is not required since it can be unrolled in + gst_vaapi_display_class_init() + https://bugzilla.gnome.org/show_bug.cgi?id=788058 + +2017-09-22 17:50:15 +0200 Víctor Manuel Jáquez Leal + + * tests/test-display.c: + tests: test-display: remove display cache tests + Since commit ec3e10f6, display cache was removed. This patch removes + this leftovers in the display test. + +2017-09-18 14:29:55 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h264/h265: decode codec data only if opened + Fixes regression introduced by commit 2eb2b26a. + There is a use case when the decoder set the src caps and immediatly + tries to process the media codec_data, this happens before decoder is + even opened, thus priv->parser is not instantiated yet. + https://bugzilla.gnome.org/show_bug.cgi?id=787818 + +2017-09-18 19:11:45 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: change mbbrc from uint to enum + Instead of handling the macroblock bitrate control as a integer, this + patch changes it as a enum, which is more self documented in the + GStreamer elements. + https://bugzilla.gnome.org/show_bug.cgi?id=787855 + +2017-09-18 13:55:49 +1000 Jan Schmidt + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + Fix a typo in the prop string for compliance-mode + +2017-09-15 18:31:49 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: don't unref properties + This patch fixes a regression introduced in commit 148f867c, since the + props variable is set to object's member variable + encoder->properties. And it is set in the instance initialization, + thus it will not be leaked. + https://bugzilla.gnome.org/show_bug.cgi?id=787733 + +2017-09-15 15:14:47 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst/vaapi/gstvaapiencode.c: + vaapiencode/libs: encoder: fix leaks of properties + https://bugzilla.gnome.org/show_bug.cgi?id=786321 + +2017-08-24 21:51:22 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + libs: decoder: at update_caps() decode codec_data + When updating the caps in decoder, if the caps has codec_data (avC + format), it has to be parsed to update the state of the decoder. + https://bugzilla.gnome.org/show_bug.cgi?id=786173 + +2017-09-13 15:44:32 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapicontext.c: + libs: context: fix wrong counter of the array of attributes + The counter value passed to vaCreateConfig is always +1. + This is a regression caused by commit e42ec3ad. + The present patch fixes wrong counting of the array of attributes. + https://bugzilla.gnome.org/show_bug.cgi?id=787613 + +2017-09-13 12:23:42 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + libs: encoder: h265: support I/P/B QP setting seperatedly + Creates 2 properties, qp-ip and qp-ib for setting different QP for P/B + frames + and set slice_qp_delta for each frame according to the value provided. + https://bugzilla.gnome.org/show_bug.cgi?id=785923 + +2017-09-13 12:22:07 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + libs: encoder: h264: support I/P/B QP setting seperatedly + Creates 2 properties, qp-ip and qp-ib for setting different QP for P/B + frames + and set slice_qp_delta for each frame according to the value provided. + In addition, remove the limitation of (<= 4) when setting + slice_qp_delta. + https://bugzilla.gnome.org/show_bug.cgi?id=785923 + +2017-09-13 12:15:57 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h264/h265: keep min_qp as is unless it's over init_qp + Creates new variable for QP for I frame and keep it at configuration and + use this for pic_init_qp and slice_qp_delta setting. + Since changing min qp doesn't make sense, keep min qp as is. + https://bugzilla.gnome.org/show_bug.cgi?id=785923 + +2017-09-13 12:09:45 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + libs: encoder: h265: Add mbbrc property + This property supports Macroblock level Bitrate Control as the + following (same as h264 encoder): + 0: auto + 1: on + 2: off + https://bugzilla.gnome.org/show_bug.cgi?id=785917 + +2017-09-13 12:02:53 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + libs: encoder: h264: Add mbbrc property + This property supports Macroblock level Bitrate Control as the + following: + 0: auto + 1: on + 2: off + https://bugzilla.gnome.org/show_bug.cgi?id=785917 + +2017-09-13 11:39:09 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: add multi reference support + This is doing the same as h264 encoder as the following: + Using num_ref_frames provided and the result of the Query + VAConfigAttribEncMaxRefFrames, it determines the size of reference list + and perform encoding with multi reference frames as the following: + 1\ The num_ref_frames is being considered as the number of + reference picture list0 + 2\ Encoder adds 1 reference frame more to the reference picture list1 + internally if b-frame encoding. + 3\ If num_ref_frames is bigger than the number of refrence frames + supported in the driver, it will be lowered. + Also this patch includes: + - Set num_negative_pics and num_positive_pics according to the number of + refs. + - Set delta_poc according to the number of refs. + - Increase max_dec_pic_buffering according to the number of refs + - Change max_num_reorder_pics according to num of bframes + https://bugzilla.gnome.org/show_bug.cgi?id=783804 + +2017-09-13 11:37:33 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + libs: encoder: h265: add refs property + Users can provide the number of reference frame by this property, + which is exaclty same as h264. + The value of the property will be considered as the number of + reference picture list0 and will add 1 reference frame more to the + reference picture list1 internally if b-frame encoding. + If the value provided is bigger than the number of refrence frames + supported in the driver, it will be lowered. + The maximum value is aligned to the value of the driver supported now. + https://bugzilla.gnome.org/show_bug.cgi?id=783804 + +2017-09-13 11:17:26 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h264/5: determine num_ref_idx_active_override_flag according to reference list + Follows the specification as below: + 7.4.7.1 in Rec. ITU-T H.265 v4 (12/2016) + num_ref_idx_active_override_flag equal to 1 specifies that the syntax + element num_ref_idx_l0_active_minus1 is present for P and B slices and + that the syntax element num_ref_idx_l1_active_minus1 is present for B + slices. + num_ref_idx_active_override_flag equal to 0 specifies that the syntax + elements num_ref_idx_l0_active_minus1 and num_ref_idx_l1_active_minus1 + are not present. + https://bugzilla.gnome.org/show_bug.cgi?id=783804 + +2017-09-13 11:06:20 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: keep idr_period equal to keyframe period + Remove FIXME code, which makes previous assignation spurious. + This also means to make idr_period equal to keyframe period, + which is same as h264 encoder. + https://bugzilla.gnome.org/show_bug.cgi?id=783804 + +2017-09-06 14:03:25 -0400 Nicolas Dufresne + + * gst/vaapi/gstvaapipluginbase.c: + Request minimum buffer even if need_pool is FALSE + When tee is used, it will not request a pool, but still it wants to + know how many buffers are required. + https://bugzilla.gnome.org/show_bug.cgi?id=730758 + +2017-09-05 10:58:57 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + libs: encoder: h264_fei: VA-API 1.0 compat + Use VA_ENC_PACKED_HEADER_H264_SEI compat macro for VA-API 1.0 + compatibility. + https://bugzilla.gnome.org/show_bug.cgi?id=787322 + Signed-off-by: U. Artie Eoff + +2017-09-01 13:48:01 -0700 Sreerenj Balachandran + + * gst/vaapi/gstvaapisink.c: + vaapisink: Fix rendering in drm display + Make sure vaapisink create a va surface backed buffer pool and all + required attributes get assigned correctly for drm display type. + This is needed to make the below pipeline working: + gst-launch-1.0 filesrc location= raw_video.mov ! videoparse format=uyvy + width=320 height=240 framerate=30/1 ! vaapisink display=drm + https://bugzilla.gnome.org/show_bug.cgi?id=786954 + +2017-08-09 18:46:09 -0700 Sreerenj Balachandran + + * tests/Makefile.am: + * tests/test-fei-enc-in.c: + * tests/test-fei-enc-out.c: + FEI: Add test applications to showcase fei use case + test-fei-enc-out: A simple fei encoding application to output mv, mbcode and distortion + eg: + ./test-fei-enc-out -i sample_320x240.nv12 -w 320 -h 240 -o out.264 -v mv.out -d out.dist -m out.mbcode -e 1 + test-fei-enc-in: A simple fei encoding application for testing input fei buffers + eg: + ./test-fei-enc-in -c h264 -o out.264 -e 4 -q 1 sample_i420.y4m + Fixme: Running test-fei-enc-in in PAK mode with mv and mbcode input buffers + from saved files is still not working + People contributed: + Wang, Yi + Leilei + Zhong, Xiaoxia + xiaominc + Li, Jing B + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + +2017-08-09 18:36:13 -0700 Sreerenj Balachandran + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapiencode_h264_fei.c: + * gst/vaapi/gstvaapiencode_h264_fei.h: + FEI: plugin: Add vaapih264feienc element + A new FEI based encoder element for h264 is added: vaapih264feienc + FEI is a an extension to VA-API which is providing low level + advanced control over different stages of encoding. + Extending vaapih264enc with fei support is possible, but it will + make the code too much complicated and will be difficult + to debug. So adding the new encoder element, but keeping + the rank as 0 , vaapih264enc will stay as the primary + encoder for normal use cases. + The vaaih264feienc is mainly useful for customers who want to play + with MotionVectors and Macroblock Predictions. Also user can + do one stage of encoding(eg: only the Motion Vector Calculation) + in software and offload trasformation/entroy-coding etc to + Hardware (which is what PAK module is doing) using FEI element. + vaapih264feienc can work in different modes using fei-mode properoty + eg: gst-launch-1.0 videotestsrc ! vaapih264feienc fei-mode=ENC+PAK ! filesink location=sample.264 + Important Note: ENC only mode won't produce any encoded data which is expected. + But ENC alwys requires the output of PAK in order to do the inter-prediction + over reconstructed frames. + Similary PAK mode alway requires MV and MBCode as input, so unless there is an + upstream element providing those buffers, PAK only won't work as expected. + In a nutshell, ENC_PAK and the ENC+PAK modes are the only options we can verify + with vaapih264feienc. But ideally, EN+PAK mode verification is enough to make sure + that ENC and PAK are working as expected since ENC+PAK mode always invoke ENC and PAK + separately in vaapih264feienc. + People contributed: + Wang, Yi + Leilei + Zhong, Xiaoxia + xiaominc + Li, Jing B + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + Signed-off-by: Sreerenj Balachandran + +2017-08-09 18:32:13 -0700 Yi A Wang + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + FEI: plugin: Add virtual methods to base encode + Two new virtual methods are added to gstvaapiencode. + load_control_data(): load the FEI input buffers set by the upstream elements + save_stats_to_meta(): save the FEI output buffers to Meta for downnstream elements + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + Signed-off-by: Sreerenj Balachandran + +2017-08-09 18:26:57 -0700 Yi A Wang + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapifeivideometa.c: + * gst/vaapi/gstvaapifeivideometa.h: + FEI: plugin: Add fei specific video meta + GstVaapiFeiVideoMeta holds the below fei codec objects: + GstVaapiEncFeiMbCode + GstVaapiEncFeiMv + GstVaapiEncFeiMvPredictor + GstVaapiEncFeiMbControl + GstVaapiEncFeiQp + GstVaapiEncFeiDistortion + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + Signed-off-by: Sreerenj Balachandran + +2017-08-09 18:19:06 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.h: + * gst-libs/gst/vaapi/gstvaapifeipak_h264.c: + * gst-libs/gst/vaapi/gstvaapifeipak_h264.h: + FEI: libs: Add FEI encoder + Adding FEI encoder to core lib. + The code is splitted into three session: + 1: gstvaapiencoder_h264_fei.{h,c} + This is the replica of gstvaapiencoder_h264.{c,h} but with FEI. + All the modes ENC, PAK and ENC_PAK are running based + the code in these files. + 2: gstvaapifeienc_h264.{h,c} + Abstract implementation intended for ENC (only VME) operation. + 3: gstvaapifeipak_h264.{h,c} + Abstrct implementation intended for PAK (only the PAK module) + Right now ENC_PAK, ENC and PAK are running based on code + in gstvaapiencoder_h264_fei.{h,c}. The abstract implementations + in gstvaapifeienc_h264.{h,c} and gstvaapifeipak_h264.{h,c} are + needed if user request for ENC+PAK mode operation. + ENC+PAK: Here we need to invoke two sequence of + vaBeginPicture/vaRenderPicutre/vaEndPicture for each frame, + first for the ENC only and the second for PAK only. + Each mode associated with separate context ,but same pool of surfaces are + shared between the modes. + This is more useful once we have custom BRC algorithms. + Other Contributors: + Wang, Yi + Leilei + Zhong, Xiaoxia + xiaominc + Li, Jing B + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + +2017-08-09 17:54:27 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + FEI: libs: Add fei codec objects to GstVaapiEncPicture + All the codec objects(vaapi buffers) supposed to be + submited in vaRenderPicutre are associated with a GstVaapiEncPicture + for each frame, follow the same design for FEI too. + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + +2017-08-09 16:05:13 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c: + * gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h: + * gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h: + FEI: libs: Add fei codec objects in codedbufferproxy + MbCode, MV and Distortion buffers (fei codec objects) + can be treated as output of different fei modes based user request. + For eg: MbCode and MV are the output of ENC only. MbCode, MV and Dist + can be dumped as output in ENC_PAK mode for analysis purpose. + So treating them as a part of CodedBufferProxy too. + Here we avoided Qp, MbControl and MvPredictor codec objects since + there is no practical use case of treating them as "output buffers". + Other contributors: + Zhong, Xiaoxia + xiaominc + Leilei + Li, Jing B + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + +2017-08-09 15:49:21 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + FEI: libs: Add fei codec objects to surface proxy + Add fei codec objects to surface proxy since handling the + fei buffers(codec objects here) external to gstvaapisurfaceproxy + will make the code complicated. Especially considering the behavior + of encoder where the input frame order from upstream and output + frame order to the downstream are not sequential. + Other contributors: + Zhong, Xiaoxia + xiaominc + Leilei + Li, Jing B + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + +2017-08-09 15:35:10 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapifei_objects.c: + * gst-libs/gst/vaapi/gstvaapifei_objects.h: + * gst-libs/gst/vaapi/gstvaapifei_objects_priv.h: + FEI: Add codec objects for fei usecase + There are 6 new va buffer types, each defined as a specific codec object. + Borrowed the code from gstvaapicodecobject , but made a clear separation + to avoid any possible mess-up. Because unlike the other gstvaaicodecobjects, + feicodecobjects can be shared between elements and also can be accessed + from different thread. + Unlike the other fei codecs object, VAEncMiscParameterTypeFEIFrameControl + object is not shared between elements.So we utilize the already + existing gst_vaapi_enc_misc_param_new(), but still keeping the code + in gstvaapfei_objects_priv.h in order to have a better + code readability. + Fixme: + -- Probably we need _locked_map() and _unlocked_map() + -- Context can be associated with PreEnc(not just Enoder) + once we have the proper support inplace, but for now we don't have + PreEnc support, so should be safe enough to use GstVaapiEncoder. + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + +2017-08-09 14:22:12 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapifeiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapifeiutils_h264.h: + FEI: libs: add H264 fei specific utility functions + Added enum/flag type definitions for a number of FEI + input and output parameters. + Original author of the patch: Wang, Yi + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + Signed-off-by: Wang, Yi + Signed-off-by: Sreerenj Balachandran + +2017-08-09 14:10:16 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + FEI: libs: Add virtual method for secondary context creation. + Add a new vitrual method ensure_secondary_context to the + base encoder which is only required for the FEI entrypoint, that too + only when user configures the ENC+PAK mode. ENC+PAK mode is not something + supported directly by libva or driver, but this can be enabled + from the middleware. + Original Author of this idea: Leilei Shang + Signed-off-by: Leilei Shang + Signed-off-by: xiaominc + Signed-off-by: Sreerenj Balachandran + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + +2017-08-09 14:05:03 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + FEI: libs: make sure the default context creation works as expected. + Current code always guess the entrypoint during init phase in case + if there is no entrypoint already configured in GstVaapiContextInfo. + Make sure FEI Entrypoint is not messing up with this logic. + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + +2017-08-09 13:45:40 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + FEI: libs: Add FEI functional mode configuration + FEI Entrypoint can work in either one of the 3 different modes: + VA_FEI_FUNCTION_ENC, VA_FEI_FUNCTION_PAK or VA_FEI_FUNCTION_ENC_PAK. + Add infrastructure in gstvaapicontext and gstvaapiencoder for this + functioal mode configuration. + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + +2017-08-09 13:02:24 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + FEI: libs: Add FEI Entrypoint mapping + Define the new mapping GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI + for VAEntrypointFEI. + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + +2017-08-09 12:58:29 -0700 Sreerenj Balachandran + + * configure.ac: + FEI: Add support for FEI conditional build + FEI(Flexible Encoding Infrastructure) is an extension + to VA API. Define USE_H264_FEI_ENCODER based on + fei header file and required structures availability. + https://bugzilla.gnome.org/show_bug.cgi?id=785712 + https://bugzilla.gnome.org/show_bug.cgi?id=784667 + +2017-08-28 17:34:50 -0700 Orestis Floros + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: force add h264 SVC profiles in caps + When vaapih264dec's base-only profile is set to TRUE, fake SVC profile + support in caps. + https://bugzilla.gnome.org/show_bug.cgi?id=732266 + Signed-off-by: Sreerenj Balachandran + +2017-08-28 17:32:57 -0700 Orestis Floros + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: decode SVC base layer only + Drops non-base NALs when the base-only property is set to TRUE. + This modifies the behavior for MVC streams with base-only too: All the + non-base units are dropped before they are decoded instead of dropping + the non-base frames. + The relevant part from the H264 spec is: + > Decoders that conform to one or more of the profiles specified in + Annex A rather than the profiles specified in Annexes G or H shall + ignore (remove from the bitstream and discard) the contents of all NAL + units with nal_unit_type equal to 14, 15, or 20. + To eliminate side effects from the offending units: + - PPS's with a broken seq_parameter_set_id (referring to dropped subset + SPS's) are ignored. + - The NAL parsing is skipped and their flags are set to + GST_VAAPI_DECODER_UNIT_FLAG_SKIP. + - Prefix units are not stored in prev_pi. Otherwise, parse_slice() would + use them even if they are flagged to be skipped. Subset SPS's and slice + extension units are not stored there either. + https://bugzilla.gnome.org/show_bug.cgi?id=732266 + Signed-off-by: Sreerenj Balachandran + +2017-08-28 17:28:04 -0700 Orestis Floros + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: check nalu validity in parser info finalize + https://bugzilla.gnome.org/show_bug.cgi?id=732266 + Signed-off-by: Sreerenj Balachandran + +2017-08-28 19:20:42 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: remove unused cast macro + Remove internal macro to cast structure that are already declared + in the header. + +2017-08-28 19:09:07 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.h: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.h: + Revert "libs: encoders: remove unused cast macros" + This reverts commit fd7d38f7d26b11e592638092b4073b5c1764f255. + +2017-08-28 18:32:32 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.h: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.h: + libs: encoders: remove unused cast macros + They are only used inside the code, where another macro is defined. + Thus these exported macros have no use. + +2017-08-24 20:26:11 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: improve code-style + https://bugzilla.gnome.org/show_bug.cgi?id=786173 + +2017-08-25 16:22:59 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: handle deprecated enum + In VA-API 1.0 the enum VAEncPackedHeaderH264_SEI is deprecated, and + instead VAEncPackedHeaderRawData should be used. + This patch creates a compatibility symbol, + VA_ENC_PACKED_HEADER_H264_SEI, to expose the used enum according the + VA-API version. + https://bugzilla.gnome.org/show_bug.cgi?id=784398 + +2017-08-25 16:07:34 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: guard deprecated symbols + In VA-API 1.0 the H.264 baseline profile is deprecated. This patch + guards the H.264 baseline usage. Consider this commit as a + continuation of commit e0e0a474 + https://bugzilla.gnome.org/show_bug.cgi?id=784398 + +2017-08-17 12:54:47 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + * meson.build: + * meson_options.txt: + Revert "build: check for libva-2.0" + This reverts commit 8f2eb70803099d4b533ecc10fc259041d8714210. + https://bugzilla.gnome.org/show_bug.cgi?id=784398 + +2017-08-17 12:44:40 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: macro to get a renamed value in VA-API 1.0 + In VA-API 1.0 the union bits in VAEncMiscParameterBufferROI has + renamed one member from roi_value_is_qp_delat to + roi_value_is_qp_delta, which is the correct name. + In order to keep back compatibility a macro has added to access this + union member. + https://bugzilla.gnome.org/show_bug.cgi?id=784398 + +2017-08-22 11:37:28 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipluginutil.c: + plugins: include main gstgl header + Instead including particular gstgl header files in a header file + that doesn't export a gstgl symbol, the main gstgl header file is + included in gstvaapipluginutil.c where the symbols are used. + https://bugzilla.gnome.org/show_bug.cgi?id=786597 + +2017-08-18 18:00:24 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: fix enum namespace + +2017-08-17 12:26:12 +0100 Tim-Philipp Müller + + * common: + Automatic update of common submodule + From 48a5d85 to 3f4aa96 + +2017-08-17 11:03:35 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: remove spurious assignation + Coverity scan bug: + An assigned value that is never used may represent unnecessary + computation, an incorrect algorithm, or possibly the need for cleanup + or refactoring. + ip_period is assigned first to be rewritter inmediatly after. The + first assignation is spurious. + +2017-08-15 17:36:51 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix mismatch of the return type + https://bugzilla.gnome.org/show_bug.cgi?id=786307 + +2017-08-10 13:34:21 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidecoder_unit.h: + * gst-libs/gst/vaapi/gstvaapiminiobject.h: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst-libs/gst/vaapi/gstvaapiutils_glx.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_x11.h: + * gst-libs/gst/vaapi/libgstvaapi_priv_check.h: + * gst-libs/gst/vaapi/meson.build: + libs: remove unused header + Since libgstvaapi is not distributed, there is no need to check for + private header inclusion. Thus removing it. + https://bugzilla.gnome.org/show_bug.cgi?id=786119 + +2017-08-10 13:27:11 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils_h264.h: + * gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_h265.h: + * gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2_priv.h: + libs: utils: move gstvaapisurface.h to private headers + Since the utils don't expose API defined in gstvaapisource.h, it is + moved to their private headers where they are used. + https://bugzilla.gnome.org/show_bug.cgi?id=786119 + +2017-08-10 13:26:12 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.h: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.h: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h: + libs: utils: remove va.h include in header + And include gstvaapicompat.h in the C files, since the VA-API is not + exposed in the headers. + https://bugzilla.gnome.org/show_bug.cgi?id=786119 + +2017-08-10 13:24:06 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: remove va.h include + Since it is already managed by gstvaapicompat.h + https://bugzilla.gnome.org/show_bug.cgi?id=786119 + +2017-08-10 13:11:04 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * meson.build: + build: consolidate the VA sub API includes + Include all VA sub APIs headers in a single point (gstvaapicompat.h), + since they are all already included in va.h after VA-API 0.38. + https://bugzilla.gnome.org/show_bug.cgi?id=786119 + +2017-08-10 13:09:27 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + * meson.build: + build: check for va_vpp.h + Thus, in config.h the macro HAVE_VA_VA_VPP_H is defined. This will + allow us to handle the inclusion of the header better. + https://bugzilla.gnome.org/show_bug.cgi?id=786119 + +2017-08-11 20:22:41 +0100 Tim-Philipp Müller + + * meson.build: + meson: don't export symbols by default + Only plugin entry points should be exported. + +2017-08-09 19:06:59 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h265: remove spurious code + Coverity scan: + Logically dead code: The indicated dead code may have performed some + action; that action will never occur. + By using pointer arithmetic is impossible to get NULL. + +2017-08-08 18:52:37 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + libs: context: use attribs index instead pointers + Coverity scan bug: + Out-of-bounds write. This could cause an immediate crash or incorrect + computations. + Coverity basically found that it is possible to assign more than 4 + attribs in the array. + In my opinion this was produced because code pattern used pointer + arithmetic, which is not readable nor maintainable. + This patch refactors config_create() to use an array index rather than + pointer arithmetic. Also a run-time check for index size was added. + +2017-08-08 17:38:51 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: h264: remove spurious code + Coverity scan bug: + An unsigned value can never be negative, so this test will always + evaluate the same way. + As len is guint32, there is no need to check it if it is equal or + bigger than zero. + +2017-08-08 17:34:12 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: initialize variable + Coverity scan bug: + The variable will contain an arbitrary value left from earlier + computations. + Variable base_only is fetched from base-only property, and it may be + not assigned. It needs to be initialized. + +2017-08-08 17:29:54 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: windows: wayland: fail if cannot remove last frame + Converity scan bug: + If the function returns an error value, the error value may be + mistaken for a normal value. + If g_atomic_pointer_compare_and_exchange() fails because the frame is + not the last one, the function fails. Thus, logging an info message. + +2017-08-08 17:21:52 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + libs: utils: glx: check return value + Coverity scan bug: + If the function returns an error value, the error value may be + mistaken for a normal value. + Function sscanf returns the number of assignations done. Validate this + return value with the number of expected variables to match. + +2017-08-08 17:12:06 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiobject.c: + libs: vaapi: object: remove unrequired NULL check + Coverity scan bug: + Dereference after null check: Either the check against null is + unnecessary, or there may be a null pointer dereference. + Variable klass has been validated as non-NULL several time before in + gst_vaapi_object_new() function, so there is no need to check it + again. + +2017-08-08 17:06:17 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: remove spurious assignation + Coverity scan bug: + An assigned value that is never used may represent unnecessary + computation, an incorrect algorithm, or possibly the need for cleanup + or refactoring. + ip_period is assigned first to be rewritter inmediatly after. The + first assignation is spurious. + +2017-08-08 16:50:39 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: fix copy & paste error + Coverity scan bug: + The copied code will not have its intended effect. + This is a bug from commit cdaf15b2, where the intention is to + initialize RefPicList1 while setting RefPicList0. + +2017-08-08 16:33:44 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: fix possible integer overflow + Coverity scan bug: + Unintentional integer overflow. The expression's value may not be what + the programmer intended, because the expression is evaluated using a + narrow (i.e. few bits) integer type. + Cast operator to guint64 before computation to avoid narrowing. + merge with 3c5a6add + +2017-08-08 16:12:13 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + libs: decoder: mpeg4: fail if return value is not OK + Coverity scan bug: + An assigned value that is never used may represent unnecessary + computation, an incorrect algorithm, or possibly the need for cleanup + or refactoring. + In the return value of decode_slice() or + gst_mpeg4_parse_video_packet_header() are not success, thus fail + decode_packet() function. + +2017-08-08 15:49:27 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h265: check for null + Coverity scan bug: + Dereference after null check: Either the check against null is + unnecessary, or there may be a null pointer dereference. + While looking for hte lowest poc, according to rest of the code, the + picture in the dbp (decoded picture buffer) might be NULL, thus we + could check for a NULL picture before assigned as found. + Also, split a comma operator because it is considered as a bad + practice because it possible side effects. + +2017-08-08 15:38:16 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h265: untaint loop control variable + Coverity scan bug: + Scalars (for example, integers) are not properly + bounds-checked (sanitized) before being used as array or pointer + indexes, loop boundaries, or function arguments are considered as + tainted. + In this case, num_nals were not checked before used as loop control. + +2017-08-08 13:46:56 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: remove unrequired NULL check + Coverity scan bug: + Dereference after null check: Either the check against null is + unnecessary, or there may be a null pointer dereference. + In the original commit for fill_picture_gaps() (commit 5abd2b90) the + prev_picture could be NULL, that's why the code did a null check. But, + since commit 52adebe7, the previous reference frames are tracked, thus + there is no need to check null anymore. + +2017-08-03 23:17:44 +0300 orestisf + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: fix gst_caps_new_simple call + https://bugzilla.gnome.org/show_bug.cgi?id=732265 + +2017-07-25 22:25:10 +0300 orestisf + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: force add h264 MVC profiles in caps + When vaapih264dec's base-only profile is set to TRUE, fake MVC profile + support in caps. + https://bugzilla.gnome.org/show_bug.cgi?id=732265 + +2017-07-25 22:54:30 +0300 orestisf + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: decode MVC base view only + If processed SPS has mvc profile and the configuration is set to + base-only, the frame is drop. + https://bugzilla.gnome.org/show_bug.cgi?id=732265 + +2017-07-25 22:06:56 +0300 orestisf + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode_props.c: + vaapidecode: set h264 base-only to decoder + Set the base-only value when property is set and the internal + decoder is already instantiated or when the internal decoder + is created. + https://bugzilla.gnome.org/show_bug.cgi?id=732265 + +2017-07-25 22:03:34 +0300 orestisf + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + libs: decoder: h264: add setter for base-only mode + https://bugzilla.gnome.org/show_bug.cgi?id=732265 + +2017-07-25 22:01:37 +0300 orestisf + + * gst/vaapi/gstvaapidecode_props.c: + * gst/vaapi/gstvaapidecode_props.h: + vaapidecode_props: h264: add base-only property + https://bugzilla.gnome.org/show_bug.cgi?id=732265 + +2017-08-01 11:11:55 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + libs: encoder: h264: missing property enum documentation + +2017-08-02 14:54:53 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: add multi reference support + Using num_ref_frames provided and the result of the Query + VAConfigAttribEncMaxRefFrames, it determines the size of reference list + and perform encoding with multi reference frames as the following: + 1\ The num_ref_frames is being considered as the number of + reference picture list0 + 2\ Encoder adds 1 reference frame more to the reference picture list1 + internally if b-frame encoding. + 3\ If num_ref_frames is bigger than the number of refrence frames + supported in the driver, it will be lowered. + https://bugzilla.gnome.org/show_bug.cgi?id=783803 + +2017-08-02 14:53:34 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + libs: encoder: h264: add refs property + Users can provide the number of reference frame by this property. + The value of the property will be considered as the number of + reference picture list0 and will add 1 reference frame more to the + reference picture list1 internally if b-frame encoding. + If the value provided is bigger than the number of refrence frames + supported in the driver, it will be lowered. + https://bugzilla.gnome.org/show_bug.cgi?id=783803 + +2017-07-28 15:27:20 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: implements gst_vaapi_encoder_ensure_max_num_ref_frames + This function will query VAConfigAttribEncMaxRefFrames to get the + maximum number of reference frames supported in the driver. + This will be used for h264/h265 encoding. + https://bugzilla.gnome.org/show_bug.cgi?id=783803 + +2017-08-01 18:38:40 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h265.c: + vaapiencode: h265: compare an unsigned int if not zero + An unsigned value can never be negative, so this test (greater than + zero) will always evaluate the same way. Thus change it to just if + it's not zero. + +2017-08-01 18:10:50 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: check gst_gl_ensure_element_data() return value + Refactor gst_vaapi_plugin_base_create_gl_context() in order to check + the return value of gst_gl_ensure_element_data(). The result is a code + bit cleaner. + +2017-08-01 17:59:38 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: avoid dead code detection + By using #elif macro, the static code analysis would stop to detect + these lines as dead code. Also it is inforced the mutually exclusive + environments. + +2017-08-01 17:39:04 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: don't shift by negative since it's undefined + The function g_bit_nth_lsf() may return -1 if the request bit position + is not avaible. Thus, this patch check if the return value is not -1 + in order to continue. + +2017-08-01 17:29:40 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapisink.c: + vaapisink: fix memory leak + +2017-08-01 17:23:48 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: fix memory leaks + +2017-07-27 10:54:00 +0000 Tomas Rataj + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: when appending formats change pointers to indexes + Thus, it fixes an invalid read when YV12 or I420 are not supported by + the driver. + https://bugzilla.gnome.org/show_bug.cgi?id=785085 + +2017-07-19 12:02:40 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + libs: encoder: h264: Add uncompliant mode reducing coded buffer size + Added a new property "compliance-mode", which default is the normal + strict compliant mode. + The second mode, "restrict-buf-alloc", is to limit the coded buffer + allocation size to improve performance in some specific Intel + platforms (there is asignificant performance improvement in parallel + encodings). Under this new mode, we use the MinCR field in A.3.1 for + pre-calculating the coded-buffer size. + https://bugzilla.gnome.org/show_bug.cgi?id=784590 + +2017-07-05 17:13:44 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h: + libs: utils_h264: Extend LevelLimit table with MinCR field + Add MinCR(Minimum Compression Ratio) field to GstVaapiH264LevelLimits + based on Annex A.3 + https://bugzilla.gnome.org/show_bug.cgi?id=784590 + +2017-07-11 17:29:13 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: libva 1.0 changed the logging + The logging mechanism in libva has changed it's functions + signatures. This patch updates that for libva versions >= 1.0 + https://bugzilla.gnome.org/show_bug.cgi?id=784398 + +2017-07-11 17:27:32 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: libva 1.0 deprecated baseline + libva 1.0 deprecated H.264 baseline profile and FMO support + (commit b4f332b3). + https://bugzilla.gnome.org/show_bug.cgi?id=784398 + +2017-07-26 20:03:35 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + * meson.build: + * meson_options.txt: + build: check for libva-2.0 + Check for libva-2.0 since libva's developers decided to increase the + library's version number. + https://bugzilla.gnome.org/show_bug.cgi?id=784398 + +2017-07-11 16:55:26 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + * meson.build: + build: blacklist only libva 0.99.0 + Intel's MSDK uses libva 0.99.0, meanwhile open source libva bumped + its API version to 1.0.0. Thus we have to blacklist only the MSDK's + libva (0.99.0) + https://bugzilla.gnome.org/show_bug.cgi?id=784398 + +2017-07-26 20:30:37 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/meson.build: + build: meson: remove gstvaapidisplaycache.c + This is a missing bit of commit ec3e10f6 + +2017-07-26 09:53:10 -0700 U. Artie Eoff + + * configure.ac: + configure: do not break configure if gtk+-3.0 devel missing + Fix PKG_CHECK_MODULES rule for with_gtk=check condition to + set USE_GTK=0 if gtk+-3.0 is not available. + Since commit 85856c29a70d6de4aea5b708e04e9eb418190623 + Author: Hyunjun Ko + Date: Wed Jul 5 15:59:43 2017 +0900 + tests: elements: add testsuite of vaapi context + ...configure fails if gtk+-3.0 development files are missing. + The "with_gtk" option defaults to "check" in configure.ac + which implies that if it is not explicitly requested then + configure will only enable it if it's available on the system. + However, the PKG_CHECK_MODULES rule that get's activated on + "check" condition did not provide default when gtk+-3.0 devel + packages are not found on the system. Thus, it resulted in + configure failure. + Signed-off-by: U. Artie Eoff + https://bugzilla.gnome.org/show_bug.cgi?id=785452 + +2017-07-05 15:59:43 +0900 Hyunjun Ko + + * configure.ac: + * tests/elements/Makefile.am: + * tests/elements/test-vaapicontext.c: + tests: elements: add testsuite of vaapi context + Signed-off-by: Víctor Manuel Jáquez Leal + https://bugzilla.gnome.org/show_bug.cgi?id=766704 + +2017-07-05 15:32:43 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapisink.c: + vaapisink: fail if surface display is different + Replacing GstVaapiDisplay during rendering might be hiding problems + at some cases, even though it's safe currently since we use cache + of GstVaapidisplay. + Play safe by failing if this happens. + https://bugzilla.gnome.org/show_bug.cgi?id=766704 + +2017-07-05 15:31:55 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + videocontext: support "gst.vaapi.app.Display" context + Through "gst.vaapi.app.Display" context, users can set their own VADisplay + and native display of their backend. + Attributes: + - display : pointer of VADisplay + - x11-display : pointer of X11 display (Display *), if they're using. + This patch creates GstVaapidisplayX11 if information provided through + "gst.vaapi.app.Display" + https://bugzilla.gnome.org/show_bug.cgi?id=766704 + +2017-07-05 14:33:38 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + libs: display: x11: add gst_vaapi_display_x11_new_with_va_display() + Implements new API function so that users could create GstVaapiDisplay + with their own VADisplay within a native display as backend. + https://bugzilla.gnome.org/show_bug.cgi?id=766704 + +2017-07-05 14:32:35 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: pass display info when foreign display + When creating a GstVaapiDisplay using a foreign VADisplay, and render + with that display, it also requires native display of the backend. + https://bugzilla.gnome.org/show_bug.cgi?id=766704 + +2017-06-26 21:18:25 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.c: + * gst-libs/gst/vaapi/gstvaapidisplaycache.h: + libs: display: remove cache + Remove a bunch of code that handles the VADisplay cache, since the + context sharing should be doing this correctly. + https://bugzilla.gnome.org/show_bug.cgi?id=747946 + +2017-07-13 10:56:18 +0900 Hyunjun Ko + + * tests/elements/Makefile.am: + * tests/elements/test-vaapipostproc.c: + tests: elements: add test for vaapipostproc + https://bugzilla.gnome.org/show_bug.cgi?id=754885 + +2017-07-12 18:25:15 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipostproc.c: + postproc: reconfigure when width or height changes + https://bugzilla.gnome.org/show_bug.cgi?id=754885 + +2017-07-17 18:53:57 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: vp9: array terminated in zeros + There is a crash when setting ref-pic-mode since the #GEnumValue + array is not terminated with a structured with all memvers being + zero. + https://bugzilla.gnome.org/show_bug.cgi?id=785032 + +2017-07-13 16:43:34 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: h264: add plugin documentation + Comment how the profile is set and other parameters. + +2017-05-26 15:19:00 +0000 Matt Staples + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: push frames as soon as possible + Push frames downstream as soon as possible instead of waiting until + they are ejected from the DPB. + This patch makes the decoder not comply with the H.264 specification, + but it is required for some video cameras. + https://bugzilla.gnome.org/show_bug.cgi?id=762509 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-07-10 19:27:57 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode_props.c: + vaapidecode_props: h264: set low-latency in decoder + Set the low-latency property if the H264 decoder is already + instantiated, thus you could change the behavior in run-time. + https://bugzilla.gnome.org/show_bug.cgi?id=783588 + +2017-07-06 20:00:15 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: set h264 low latency to decoder + https://bugzilla.gnome.org/show_bug.cgi?id=783588 + +2017-06-14 18:30:53 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + libs: decoder: h264: add getter/setter for low latency mode + https://bugzilla.gnome.org/show_bug.cgi?id=783588 + +2017-06-14 18:31:18 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode_props.c: + * gst/vaapi/gstvaapidecode_props.h: + vaapidecode_props: h264: add low latency property + Adding support for private data. + https://bugzilla.gnome.org/show_bug.cgi?id=783588 + +2017-06-14 18:23:34 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode_props.c: + * gst/vaapi/gstvaapidecode_props.h: + * gst/vaapi/meson.build: + vaapidecode_props: add skeleton for h264 decoder properties + https://bugzilla.gnome.org/show_bug.cgi?id=783588 + +2017-06-14 17:07:30 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: properties callback in decoders map + https://bugzilla.gnome.org/show_bug.cgi?id=783588 + +2017-07-07 12:01:59 +0100 Tim-Philipp Müller + + * meson.build: + meson: find python3 via python3 module + https://bugzilla.gnome.org/show_bug.cgi?id=783198 + +2017-06-09 14:47:40 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: submit sps in case of IDR picture + If the picture is IDR, also submit a SPS header. + This means when frame number reaches to keyframe-period or an force + key unit event arrives, we insert SPS/PPS again. + https://bugzilla.gnome.org/show_bug.cgi?id=776712 + +2017-06-09 14:47:16 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: set the frame as IDR if forced key unit + GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME() is a flag usually used to manage + the `frame-lost` event in the case of streaming, such as RTP. + In case of this event, it is needed to start new GOP rather than just + produce an I-frame. + https://bugzilla.gnome.org/show_bug.cgi?id=776712 + +2017-04-05 14:48:46 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + libs: encoder: h264: insert AU delimiter + Insert an AUD as the first NAL of each encoded frame. + Some applications require Access Unit Delimiter for decoding the + stream. + The AU delimeter insertion is done only when the aud parameter is + TRUE (by default is disabled). The reason of this it is because this + header is only available from Intel Gen9 and the VA intel driver + should be 1.8 or superior. Otherwise, the output will be corrupted. + https://bugzilla.gnome.org/show_bug.cgi?id=776712 + Signed-off-by: Victor Jaquez + +2017-06-29 12:50:26 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: initialize all elements of view_ids + Currently when num_views is changed by multiview-mode on sink caps, it produces + wrong MVC encoded stream since the array view_ids is not set properly according + to changed num_views. + So this patch initializes all of the array sequentially to handle this case. + Side effect is not going to happen by this patch since this array is being + handled by num_views. + https://bugzilla.gnome.org/show_bug.cgi?id=784321 + +2017-06-27 14:30:54 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + Revert "encoder: h264: Use high profile by default" + This reverts commit 4aec5bdd7207fc0e45813ef14c9c0ad5174a8f75. + https://bugzilla.gnome.org/show_bug.cgi?id=757941 + +2017-06-27 16:03:37 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: set profile via capsfilter + Until now, the encoder ignored the profile in src caps and chose one + according with the given parameters. But the encoder must honor the + profile specifed in src caps. + This patch do that, and if the encoder needs to choose the profile, + it will do it by following these rules: + 1\ If given parameters are not compatible with given profile, the + encoder will bail out with an error. + 2\ The encoder will choose the higher profile indicated in the + src caps. + https://bugzilla.gnome.org/show_bug.cgi?id=757941 + +2017-06-27 13:14:31 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: h264: set profile to src caps + So far vaapi encoder does not set profile to src caps. This patch makes it + setting profile to src caps, which is determined by itself. + In addition, if encoder chose different profile, which is not negotiated with + downstream, we should set compatible profile to make negotiation working. + https://bugzilla.gnome.org/show_bug.cgi?id=757941 + +2017-06-22 09:56:49 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264.h: + vaapiencode: h264: verify if requested profile is supported + Check if the requested profile in source caps, is supported by the + VA driver. If it is not, an info log message is send saying that + another (compatible?) profile will be used. + https://bugzilla.gnome.org/show_bug.cgi?id=757941 + +2017-06-21 21:49:27 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: h264: improve set_config() vmethod + First check if downstream requests ANY caps. If so, byte-stream is + used and the profile will be choose by the encoder. If dowstream + requests EMPTY caps, the negotiation will fail. + Lately, byte-stream and profile are looked in the allowed caps. + https://bugzilla.gnome.org/show_bug.cgi?id=757941 + +2017-06-21 19:30:55 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: h264: check for avc in set_config() + The check for avc stream format was done in the vaapi encoder's + vmethod get_caps(), but that is wrong since it has to be check + when encoder set_format(). + https://bugzilla.gnome.org/show_bug.cgi?id=757941 + +2017-06-29 12:49:24 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: set multivew-mode flags to src caps + vaapipostproc didn't negotiate the proper multiview caps losing + downstream information. + This patch enables the playing of MVC encoded stream by setting + the proper multiview mode/flags and views to src caps, according + to sink caps. + https://bugzilla.gnome.org/show_bug.cgi?id=784320 + +2016-11-22 15:52:47 +0000 Julien Isorce + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: add support for DMABuf caps feature + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + Signed-off-by: Julien Isorce + +2017-06-01 19:42:20 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: add support for DMABuf caps feature + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + Original-patch-by: Julien Isorce + +2017-06-23 12:12:12 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + vaapipluginbase: force dmabuf allocator if DMABuf caps feature + Instantiate all dmabuf allocator for src pad buffer pool if the + src caps ask for memory:DMABuf feature. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2016-11-22 23:26:05 +0000 Julien Isorce + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + vaapipluginutil: add support for DMABuf caps feature + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + Signed-off-by: Julien Isorce + Signed-off-by: Victor Jaquez + vaapipluginutil: add support for DMABuf caps feature + +2017-06-01 19:13:52 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + vaapipluginbase: dmabuf memory map trial for raw caps + Only push dmabuf-based buffers with raw caps if gst_memory_map() + succeeds. Otherwise, use the the vaapi surfaces allocator. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + https://bugzilla.gnome.org/show_bug.cgi?id=774649 + Original-patch-by: Julien Isorce + +2016-06-08 19:11:15 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: add gst_vaapi_dmabuf_can_map() + This new method checks the specified allocator can create GstMemory that can + be mapped. + https://bugzilla.gnome.org/show_bug.cgi?id=755072 + +2017-06-23 17:33:03 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: fix regression with video metas + There is another regression with 7a206923 when setting the video + info for the video meta, it should be the one from the image's + allocator rather from the allocation caps. + Test pipeline: + gst-launch-1.0 filesrc location=bug766184.flv ! decodebin \ + ! tee ! videoconvert ! videoscale \ + ! video/x-raw, width=1920, height=1080 ! xvimagesink + +2017-06-23 14:38:10 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideobufferpool.c: + plugins: update buffer size with the one reported by allocator + There is a regression in 7a206923, since the buffer pool ditches all + the buffers generated by them because the pool config size is + different of the buffer's size. + Test pipeline: + gst-launch-1.0 filesrc location=big_buck_bunny_1080p_h264.mov \ + ! qtdemux ! vaapih264dec ! vaapipostproc ! xvimagesink \ + --gst-debug=GST_PERFORMANCE:5 + The allocator may update the buffer size according to the VA surface + properties. In order to do this, the video info is modified when the + allocator is created, which reports through the allocation info the + updated size, and set it to the pool config. + +2017-06-14 21:40:33 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: initialize active_sps/pps in reset + Since commits in https://bugzilla.gnome.org/show_bug.cgi?id=781142 landed, + they introduced regression in seek. + Formerly, once seek is done, decoder drops P-frames until I-frame arrives. + But since the commits landed, it doesn't drop P-frame and does try to + decode it continuously because active_sps is still alive. See ensure_sps function. + But there are prev_frames and prev_ref_frames reset already, then it + causes assertion. + So it's necessary to reset active_sps/pps also in reset method. + https://bugzilla.gnome.org/show_bug.cgi?id=783726 + +2017-06-15 13:24:56 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: fix compilation with old versions of libva + There are some symbols that are not used when compiling with old + version of libva and those generates a compilation error. + Original-patch-by: Matt Staples + +2017-06-09 14:02:20 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: Fix the quality level clamping + Change the hard-coded range of quality-level from {1-8} to {1-7}, + since it is the range Intel Open source driver supports. + Also perform the range clamping only if the user provided + quality-level is greater than the max-range suppored by the driver, + because there could be non-intel drivers giving lower value than + the hard-coded max value 7. + https://bugzilla.gnome.org/show_bug.cgi?id=783567 + +2017-04-06 19:35:27 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: log out the name of the profile + Instead of printing a number, it is more readable to log out, in + case of error, the name of the failing profile. + +2017-05-31 12:36:17 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: changes raw number of profile to macro name of its + Changes raw number of profile to macro name of its to improve readability. + https://bugzilla.gnome.org/show_bug.cgi?id=757941 + +2017-06-09 17:00:40 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: remove allocation_vinfo private attribute + There is no need to keep this attribute internally since it is + already managed by the allocator. + https://bugzilla.gnome.org/show_bug.cgi?id=783599 + +2017-06-09 15:02:08 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: refactor set_config() + Refactor the set_config() virtual method considering a cleaner + approach to allocator instanciation, if it it not set or if it is + not valid for the pool. + https://bugzilla.gnome.org/show_bug.cgi?id=783599 + +2017-06-09 13:05:36 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: distinguish allocation and negotiation caps + The vaapi video decoders might have different allocation caps from + the negotiation caps, thus the GstVideoMeta shall use the negotiation + caps, not the allocation caps. + This was done before reusing gst_allocator_get_vaapi_video_info(), + storing there the negotiation caps if they differ from the allocation + ones, but this strategy felt short when the allocator had to be reset + in the vaapi buffer pool, since we need both. + This patch adds gst_allocator_set_vaapi_negotiated_video_info() and + gst_allocator_get_vaapi_negotiated_video_info() to store the + negotiated video info in the allocator, and distinguish it from + the allocation video info. + https://bugzilla.gnome.org/show_bug.cgi?id=783599 + +2017-06-08 19:32:35 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + vaapivideomemory: rename qdata quarks and ids + Also the parameter names were renamed to reflect their origin + and purpose. + https://bugzilla.gnome.org/show_bug.cgi?id=783599 + +2017-06-08 16:05:49 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: rename local variables + Renamed local video info structure names in set_config() vitual + method. The purpose of their renaming is to clarify the origin + of those structures, whether come from passed caps parameter + (new_allocation_vinfo) or from the configured allocator + (allocator_vinfo). + https://bugzilla.gnome.org/show_bug.cgi?id=783599 + +2017-06-08 15:49:05 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: rename video info structures + Renamed private GstVideoInfo structure video_info to allocation_vinfo + and alloc_info to negotiated_vinfo. + The purpose of these renaming is to clarify the origin and purpose of + these private variables: + video_info (now allocation_vinfo) comes from the bufferpool + configuration. It describes the physical video resolution to be + allocated by the allocator, which may be different from the + negotiated one. + alloc_info (now vmeta_vinfo) comes from the negotiated caps in + the pipeline. It represents how the frame is going to be mapped + using the video meta. + In Intel's VA-API backend, the allocation_vinfo resolution is + bigger than the negotiated_info. + https://bugzilla.gnome.org/show_bug.cgi?id=783599 + +2017-06-08 12:51:50 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: set framerate if bigger than 0/1 + Just set the framerate parameter if the framerate numerator and + denominator are bigger than zero. + Otherwise, in Intel Gen6 driver, a warning is raised disabling the + bitrate control. + Original-patch-by: Hyunjun Ko + https://bugzilla.gnome.org/show_bug.cgi?id=783532 + +2017-06-07 12:32:53 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: bitrate target percentage calculation + If the rate control is set to Constant Bit Rate (CBR) the target + percentage is 100%, otherwise is 70% + +2017-06-07 12:25:24 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: h264,h265,mpeg2,vp8,vp9: refactor ratecontrol param + Centralize the common configuration for the Rate Control parameter, + thus can be overloaded per each specific encoder. + +2017-06-07 11:10:49 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: h264,h265,mpeg2,vp8,vp9: refactor framerate param + Since the framerate VA parameter is calculated equally among all the + encoders, it is better to handle it in the base encoder class. + +2016-08-09 15:53:47 +0300 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.h: + libs: encoder: vp9: Adds CBR and VBR Encoding support + https://bugzilla.gnome.org/show_bug.cgi?id=766832 + Signed-off-by: Hyunjun Ko + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-06-01 12:12:26 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: encoder: vp8: Adds VBR Encoding support + https://bugzilla.gnome.org/show_bug.cgi?id=778732 + +2017-06-01 12:11:12 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: Adds VBR Encoding support + Enables Variable BitRate mode, which does set FrameRate and RateControl + parameters. + https://bugzilla.gnome.org/show_bug.cgi?id=778732 + +2017-06-02 13:50:05 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: Describes more detail about the bitrate property + https://bugzilla.gnome.org/show_bug.cgi?id=778732 + +2017-06-05 20:44:22 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: add rate control parameter + https://bugzilla.gnome.org/show_bug.cgi?id=783449 + +2017-06-05 20:33:27 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + libs: encoder: h264,h265,mpeg2: add framerate parameter + https://bugzilla.gnome.org/show_bug.cgi?id=783449 + +2017-06-05 20:30:07 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: encoder: vp8,h264,h265,mpeg2: set misc param once + Instead of recalculating the miscellaneous buffer parameters for + every buffer, it is only done once, when the encoder is configured. + And for every buffer, the same structures are just copied. + https://bugzilla.gnome.org/show_bug.cgi?id=783449 + +2017-06-05 17:31:10 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: encoder: vp8,h264,h265,mpeg2: refactor misc parameters + This is patch pretends to decouple the assignation of the values + in the parameter structures and the VA buffer's parameters setting. + It may lead to some issues since HRD, framerate or controlrate may + not be handled by the specific encoder, but they are set in + the VA buffer's parameters. + I leave as it because this patch is just a transitional patch. + https://bugzilla.gnome.org/show_bug.cgi?id=783449 + +2017-06-05 16:34:12 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: encoder: vp8: fix frame rate calculation + According to the VA documentation: + The framerate is specified as a number of frames per second, + as a fraction. The denominator of the fraction is given in + the top half (the high two bytes) of the framerate field, and + the numerator is given in the bottom half (the low two bytes). + For example, if framerate is set to (100 << 16 | 750), this is + 750 / 100, hence 7.5fps. + If the denominator is zero (the high two bytes are both zero) + then it takes the value one instead, so the framerate is just + the integer in the low 2 bytes. + This patch fixes the the framerate calculation in vp8 encoder + according to this. + https://bugzilla.gnome.org/show_bug.cgi?id=783449 + +2017-06-02 19:46:52 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: encoder: vp8: refactor FrameRate parameter + Move frame-rate parameter from ensure_misc_params() to + ensure_contro_rate_param() since it only has meaning when the + control rate is either VBR or CBR. + https://bugzilla.gnome.org/show_bug.cgi?id=783449 + +2017-06-02 19:33:36 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: encoder: h264,h265,mpeg2,vp8: refactor HDR + Move the Hypothetical Reference Decoder (HRD) parameter, from + ensure_misc_params() to ensure_control_rate_params(), since it + only shall be defined when the control rate is either VBR or CBR. + https://bugzilla.gnome.org/show_bug.cgi?id=783449 + +2017-06-02 17:21:25 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: encoder: h264,vp8,mpeg2: refactor control rate + Instead of filling the control rate param in ensure_misc_params(), + this patch refactor it out, as a first step to merge the same code + for all the encoders. + https://bugzilla.gnome.org/show_bug.cgi?id=783449 + +2017-06-02 16:28:30 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + libs: encoder: h264, h265, mpeg2: remove assert + Remove spurious asserts for misc parameters. If they cannot be + allocated, FALSE is already returned. + +2017-06-05 18:19:05 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: use VA quality level structure + Instead of using a proxy to story the buffer quality level, the + encoder now uses the native VA structure, which is copied to the + dynamically allocated VAEncMiscParameterBuffer. + This approach is computationally less expensive. + +2017-05-26 11:10:34 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: standardize the FIXME comment + This is a trivial patch that makes homogeneous the FIXME tag in + comments. + For more info about these comment style: + http://wiki.c2.com/?FixmeComment + +2017-05-22 17:20:45 +0200 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: encoder: vp8: set quality level regardless of rate control mode + https://bugzilla.gnome.org/show_bug.cgi?id=782957 + +2017-05-15 18:38:29 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: check for maximum number of slices + Right now, H264 and HEVC can set as a property the number of slices to + process. But each driver can set a maximum number of slices, depending + on the supported profile & entry point. + This patch verifies the current num_slices to process against the maximum + permitted by the driver and the media size. + https://bugzilla.gnome.org/show_bug.cgi?id=780955 + +2017-05-15 18:36:21 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h: + libs: utils: mark functions as internals + The functions in this header are internal to the library. + +2017-05-15 18:35:40 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.h: + libs: context: add missing documentation + Document the region-of-interest configuration variables. + +2017-05-12 18:46:50 +0200 Víctor Manuel Jáquez Leal + + * tests/elements/test-vaapisink.c: + tests: elements: vaapisink: handle nav events + The test app can now handle navigation events to rotate the + display. + +2017-05-12 18:17:55 +0200 Víctor Manuel Jáquez Leal + + * tests/elements/test-vaapisink.c: + tests: elements: clean up vaapisink test + - Use gst_element_send_event() instead of gst_pad_push_event() + - don't zero App structure + - check for pipeline parsing error + - only get vaapisink for property set + +2017-05-12 13:08:30 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapisink.c: + vaapisink: keep handle_events flag except that if user want to set + When state of vaapisink is changed from PLAYING to NULL, the handle_events + flag is set to FALSE, and never recovered, and then event thread is never + going to run. + So we should allow to set the flag only when users try it. + https://bugzilla.gnome.org/show_bug.cgi?id=782543 + +2017-05-12 13:06:24 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + libs: window: x11: fix src rect info when using vpp + Since we started using VPP in VaapiWindowX11, we need to care about + the case that src rect and window's size are different. + So, once VPP has converted to other format, we should honor the + size of the VPP's surface as source rect. Otherwise, it is cropped + according the previous size of the source rect. + https://bugzilla.gnome.org/show_bug.cgi?id=782542 + +2017-04-28 15:20:01 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: remove par from caps negotiation + https://bugzilla.gnome.org/show_bug.cgi?id=781759 + +2017-03-30 17:57:42 +0900 Hyunjun Ko + + * tests/elements/Makefile.am: + * tests/elements/test-roi.c: + tests: elements: add an example for ROI + This implements a pipleint to recognize difference between ROI and non-ROI. + See comments in this code in detail. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-03-30 17:54:20 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: handle custom event GstVaapiEncoderRegionOfInterest + Handles new custom event GstVaapiEncoderRegionOfInterest + to enable/disable a ROI region. + Writes a way to use new event to document. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-02-23 18:53:18 +0900 Hyunjun Ko + + * tests/simple-encoder.c: + tests: simple-encoder: add an option to set ROI + $ simple-encoder -r inputfile.y4m + And you'll got an output file in H264 with two regions of interest. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-02-23 18:52:48 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: set ROI params during encoding + Set ROI params during encoding each frame, which are set via + gst_vaapi_encoder_add_roi () + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-03-28 17:41:37 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: add api gst_vaapi_encoder_add/del_roi + Implements and exposes new api gst_vaapi_encoder_add/del_roi to set ROI regions. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + +2017-02-23 17:57:07 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder/context: query region of interest support + Queries if the driver supports "Region of Interest" (ROI) during the config + creation. + This attribute conveys whether the driver supports region-of-interest (ROI) + encoding, based on user provided ROI rectangles. The attribute value is + partitioned into fields as defined in the VAConfigAttribValEncROI union. + If ROI encoding is supported, the ROI information is passed to the driver + using VAEncMiscParameterTypeROI. + https://bugzilla.gnome.org/show_bug.cgi?id=768248 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-05-12 11:11:48 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + libs: encoder: fix a comment + +2017-05-11 12:23:28 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: guard quality level configuration + The quality level appeared in VA-API 0.36. So let's guard its + usage. + +2017-04-19 13:04:44 -0700 Sreerenj Balachandran + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + encoders: add quality level tuning + This patch adds the handling of VAEncMiscParameterTypeQualityLevel, + in gstreamer-vaapi encoders: + The encoding quality could be set through this structure, if the + implementation supports multiple quality levels. The quality level set + through this structure is persistent over the entire coded sequence, or + until a new structure is being sent. The quality level range can be queried + through the VAConfigAttribEncQualityRange attribute. A lower value means + higher quality, and a value of 1 represents the highest quality. The quality + level setting is used as a trade-off between quality and speed/power + consumption, with higher quality corresponds to lower speed and higher power + consumption. + The quality level is set by the element's parameter "quality-level" with a + hard-coded range of 1 to 8. + Later, when the encoder is configured in run time, just before start + processing, the quality level is scaled to the codec range. If + VAConfigAttribEncQualityRange is not available in the used VA backend, then + the quality level is set to zero, which means "disabled". + All the available codecs now process this parameter if it is available. + https://bugzilla.gnome.org/show_bug.cgi?id=778733 + Signed-off-by: Víctor Manuel Jáquez Leal + +2017-05-04 18:59:31 +0300 Sebastian Dröge + + * configure.ac: + * meson.build: + Back to development + +=== release 1.12.0 === + +2017-05-04 15:46:03 +0300 Sebastian Dröge + + * ChangeLog: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.12.0 2017-05-04 11:49:33 +0200 Víctor Manuel Jáquez Leal @@ -10033,6 +13048,8 @@ * configure.ac: Bump version for development. +=== release 0.5.9 === + 2014-07-29 10:31:58 +0200 Gwenole Beauchesne * AUTHORS: @@ -11711,6 +14728,8 @@ * configure.ac: Bump version for development. +=== release 0.5.8 === + 2014-01-24 10:55:39 +0100 Gwenole Beauchesne * debian.upstream/control.in: @@ -13723,6 +16742,8 @@ * configure.ac: Bump version for development. +=== release 0.5.7 === + 2013-11-22 11:28:09 +0100 Gwenole Beauchesne * gst/vaapi/Makefile.am: @@ -14722,6 +17743,8 @@ * configure.ac: Bump version for development. +=== release 0.5.6 === + 2013-08-31 15:47:33 +0200 Gwenole Beauchesne * NEWS: @@ -15268,6 +18291,8 @@ * configure.ac: Bump version for development. +=== release 0.5.5 === + 2013-07-15 17:49:31 +0200 Gwenole Beauchesne * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: @@ -15805,6 +18830,8 @@ * configure.ac: Bump version for development. +=== release 0.5.4 === + 2013-06-14 11:47:50 +0200 Gwenole Beauchesne * NEWS: @@ -16351,6 +19378,8 @@ * configure.ac: Bump version for development. +=== release 0.5.3 === + 2013-04-18 19:09:45 +0200 Gwenole Beauchesne * NEWS: @@ -16848,6 +19877,8 @@ * configure.ac: Bump version for development. +=== release 0.5.2 === + 2013-03-28 10:18:51 +0100 Gwenole Beauchesne * NEWS: @@ -17333,6 +20364,8 @@ * configure.ac: Bump version for development. +=== release 0.5.1 === + 2013-01-30 09:37:38 +0100 Gwenole Beauchesne * NEWS: @@ -17797,6 +20830,8 @@ * configure.ac: Bump version for development. +=== release 0.5.0 === + 2013-01-15 09:21:08 +0100 Gwenole Beauchesne * NEWS: @@ -20832,6 +23867,8 @@ * configure.ac: Bump version for development. +=== release 0.3.6 === + 2012-04-02 10:07:33 +0200 Gwenole Beauchesne * configure.ac: @@ -21145,6 +24182,8 @@ bitstream. i.e. the direct slice() information. VA drivers will be fixed accordingly. +=== release 0.3.5 === + 2012-03-02 15:03:57 +0100 Gwenole Beauchesne * gst/vaapi/gstvaapidecode.c: @@ -21318,6 +24357,8 @@ * configure.ac: Bump version for development. +=== release 0.3.4 === + 2012-02-01 23:34:09 +0100 Gwenole Beauchesne * NEWS: @@ -21595,6 +24636,8 @@ * configure.ac: Bump version for development. +=== release 0.3.3 === + 2012-01-16 11:05:31 +0100 Gwenole Beauchesne * NEWS: @@ -22028,6 +25071,8 @@ * configure.ac: Bump version for development. +=== release 0.3.2 === + 2012-01-06 11:20:48 +0100 Gwenole Beauchesne * NEWS: @@ -22155,6 +25200,8 @@ * configure.ac: Bump version for development. +=== release 0.3.1 === + 2012-01-03 13:42:12 +0100 Gwenole Beauchesne * NEWS: @@ -22335,6 +25382,8 @@ * gst-libs/gst/video/gstbasevideoutils.h: Drop unused copy of GstBaseVideoDecoder. +=== release 0.3.0 === + 2011-12-09 11:46:45 +0100 Gwenole Beauchesne * NEWS: @@ -22765,6 +25814,8 @@ * tests/Makefile.am: Fix build with libva headers not in a standard include dir. +=== release 0.2.6 === + 2011-06-14 15:59:08 +0200 Gwenole Beauchesne * configure.ac: @@ -22979,6 +26030,8 @@ * gst-libs/gst/vaapi/gstvaapicompat.h: Fix build with older VA-API 0.29-sds. +=== release 0.2.4 === + 2010-05-18 11:22:54 +0000 gb * gst/vaapisink/gstvaapisink.c: @@ -23012,6 +26065,8 @@ * configure.ac: Bump version for development. +=== release 0.2.3 === + 2010-05-16 21:44:17 +0000 gb * NEWS: @@ -23088,6 +26143,8 @@ * configure.ac: Bump version for development. +=== release 0.2.2 === + 2010-05-13 21:52:22 +0000 gb * NEWS: @@ -23156,6 +26213,8 @@ * gst/vaapisink/gstvaapisink.c: Use XGetGeometry() to retrieve the window size. +=== release 0.2.1 === + 2010-05-12 19:40:30 +0000 gb * gst/vaapisink/gstvaapisink.c: @@ -23306,6 +26365,8 @@ * configure.ac: Bump version for development. +=== release 0.2.0 === + 2010-05-05 12:29:28 +0000 gb * NEWS: @@ -24018,6 +27079,8 @@ * configure.ac: Bump version for development. +=== release 0.1.2 === + 2010-03-30 13:29:34 +0000 gb * configure.ac: @@ -24687,6 +27750,8 @@ * configure.ac: Bump version for development. +=== release 0.1.1 === + 2010-03-23 17:29:47 +0000 gb * gst-libs/gst/vaapi/gstvaapiutils_x11.c: @@ -25216,6 +28281,8 @@ * configure.ac: Bump version for development. +=== release 0.1.0 === + 2010-03-16 14:07:53 +0000 gb * configure.ac: diff --git a/NEWS b/NEWS index 385e4b6315..c85b362017 100644 --- a/NEWS +++ b/NEWS @@ -1,174 +1,235 @@ -# GStreamer 1.14 Release Notes + + +GSTREAMER 1.14 RELEASE NOTES + GStreamer 1.14.0 has not been released yet. It is scheduled for release -in late February / early March 2018. +in early March 2018. -There are unstable pre-releases available for testing and development purposes. -The latest pre-release is version 1.13.1 and was released on 15 February 2018. +There are unstable pre-releases available for testing and development +purposes. The latest pre-release is version 1.13.90 (rc1) and was +released on 03 March 2018. -See [https://gstreamer.freedesktop.org/releases/1.14/][latest] for the latest +See https://gstreamer.freedesktop.org/releases/1.14/ for the latest version of this document. -*Last updated: Thursday 15 February 2018, 16:30 UTC [(log)][gitlog]* - -[latest]: https://gstreamer.freedesktop.org/releases/1.14/ -[gitlog]: https://cgit.freedesktop.org/gstreamer/www/log/src/htdocs/releases/1.14/release-notes-1.14.md - -## 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 new features, bug fixes and other -improvements. - -## Highlights - -- this section will be completed shortly - -## Major new features and changes - -### Noteworthy new API - -- this section will be filled in shortly - -### New Elements - -- this section will be filled in shortly - -### New element features and additions - -- this section will be filled in shortly - -### Plugin and library moves - -- this section will be filled in shortly - -### Plugin removals - -- this section will be filled in shortly +_Last updated: Saturday 03 March 2018, 16:30 UTC (log)_ -## Miscellaneous API additions +Introduction -- this section will be filled in shortly +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! -### GstPlayer +As always, this release is again packed with new features, bug fixes and +other improvements. -- this section will be filled in shortly -## Miscellaneous changes +Highlights -- this section will be filled in shortly +- this section will be completed shortly -### OpenGL integration -- this section will be filled in shortly +Major new features and changes -## Tracing framework and debugging improvements +Noteworthy new API -- this section will be filled in shortly +- this section will be filled in shortly -## Tools +New Elements -- this section will be filled in shortly +- this section will be filled in shortly -## GStreamer RTSP server +New element features and additions -- this section will be filled in shortly +- this section will be filled in shortly -## GStreamer VAAPI +Plugin and library moves -- this section will be filled in shortly +- this section will be filled in shortly -## GStreamer Editing Services and NLE +Plugin removals -- this section will be filled in shortly +- this section will be filled in shortly -## GStreamer validate -- this section will be filled in shortly +Miscellaneous API additions -## GStreamer Python Bindings +- this section will be filled in shortly -- this section will be filled in shortly +GstPlayer -## Build and Dependencies +- this section will be filled in shortly -- this section will be filled in shortly -## Platform-specific improvements +Miscellaneous changes -### Android +- this section will be filled in shortly -- this section will be filled in shortly +OpenGL integration -### macOS and iOS +- this section will be filled in shortly -- this section will be filled in shortly -### Windows +Tracing framework and debugging improvements -- this section will be filled in shortly +- this section will be filled in shortly -## Contributors -- this section will be filled in shortly +Tools + +- this section will be filled in shortly + + +GStreamer RTSP server + +- this section will be filled in shortly + + +GStreamer VAAPI + +- this section will be filled in shortly + + +GStreamer Editing Services and NLE + +- this section will be filled in shortly + + +GStreamer validate + +- this section will be filled in shortly + + +GStreamer Python Bindings + +- this section will be filled in shortly + + +Build and Dependencies + +- this section will be filled in shortly + + +Platform-specific improvements + +Android + +- this section will be filled in shortly + +macOS and iOS + +- this section will be filled in shortly + +Windows + +- this section will be filled in shortly + + +Contributors + +Aaron Boxer, Adrián Pardini, Adrien SCH, Akinobu Mita, Alban Bedel, +Alessandro Decina, Alex Ashley, Alicia Boya García, Alistair Buxton, +Alvaro Margulis, Anders Jonsson, Andreas Frisch, Andrejs Vasiljevs, +Andrew Bott, Antoine Jacoutot, Antonio Ospite, Antoni Silvestre, Anton +Obzhirov, Anuj Jaiswal, Arjen Veenhuizen, Arnaud Bonatti, Arun Raghavan, +Ashish Kumar, Aurélien Zanelli, Ayaka, Branislav Katreniak, Branko +Subasic, Brion Vibber, Carlos Rafael Giani, Cassandra Rommel, Chris +Bass, Chris Paulson-Ellis, Christoph Reiter, Claudio Saavedra, Clemens +Lang, Cyril Lashkevich, Daniel van Vugt, Dave Craig, Dave Johnstone, +David Evans, David Schleef, Deepak Srivastava, Dimitrios Katsaros, +Dmitry Zhadinets, Dongil Park, Dustin Spicuzza, Eduard Sinelnikov, +Edward Hervey, Enrico Jorns, Eunhae Choi, Ezequiel Garcia, fengalin, +Filippo Argiolas, Florent Thiéry, Florian Zwoch, Francisco Velazquez, +François Laignel, fvanzile, George Kiagiadakis, Georg Lippitsch, Graham +Leggett, Guillaume Desmottes, Gurkirpal Singh, Gwang Yoon Hwang, Gwenole +Beauchesne, Haakon Sporsheim, Haihua Hu, Håvard Graff, Heekyoung Seo, +Heinrich Fink, Holger Kaelberer, Hoonhee Lee, Hosang Lee, Hyunjun Ko, +Ian Jamison, James Stevenson, Jan Alexander Steffens (heftig), Jan +Schmidt, Jason Lin, Jens Georg, Jeremy Hiatt, Jérôme Laheurte, Jimmy +Ohn, Jochen Henneberg, John Ludwig, John Nikolaides, Jonathan Karlsson, +Josep Torra, Juan Navarro, Juan Pablo Ugarte, Julien Isorce, Jun Xie, +Jussi Kukkonen, Justin Kim, Lasse Laursen, Lubosz Sarnecki, Luc +Deschenaux, Luis de Bethencourt, Marcin Lewandowski, Mario Alfredo +Carrillo Arevalo, Mark Nauwelaerts, Martin Kelly, Matej Knopp, Mathieu +Duponchelle, Matteo Valdina, Matt Fischer, Matthew Waters, Matthieu +Bouron, Matthieu Crapet, Matt Staples, Michael Catanzaro, Michael +Olbrich, Michael Shigorin, Michael Tretter, Michał Dębski, Michał Górny, +Michele Dionisio, Miguel París, Mikhail Fludkov, Munez, Nael Ouedraogo, +Neos3452, Nicholas Panayis, Nick Kallen, Nicola Murino, Nicolas +Dechesne, Nicolas Dufresne, Nirbheek Chauhan, Ognyan Tonchev, Ole André +Vadla Ravnås, Oleksij Rempel, Olivier Crête, Omar Akkila, Orestis +Floros, Patricia Muscalu, Patrick Radizi, Paul Kim, Per-Erik Brodin, +Peter Seiderer, Philip Craig, Philippe Normand, Philippe Renon, Philipp +Zabel, Pierre Pouzol, Piotr Drąg, Ponnam Srinivas, Pratheesh Gangadhar, +Raimo Järvi, Ramprakash Jelari, Ravi Kiran K N, Reynaldo H. Verdejo +Pinochet, Rico Tzschichholz, Robert Rosengren, Roland Peffer, Руслан +Ижбулатов, Sam Hurst, Sam Thursfield, Sangkyu Park, Sanjay NM, Satya +Prakash Gupta, Scott D Phillips, Sean DuBois, Sebastian Cote, Sebastian +Dröge, Sebastian Rasmussen, Sejun Park, Sergey Borovkov, Seungha Yang, +Shakin Chou, Shinya Saito, Simon Himmelbauer, Sky Juan, Song Bing, +Sreerenj Balachandran, Stefan Kost, Stefan Popa, Stefan Sauer, Stian +Selnes, Thiago Santos, Thibault Saunier, Thijs Vermeir, Tim Allen, +Tim-Philipp Müller, Ting-Wei Lan, Tomas Rataj, Tom Bailey, Tonu Jaansoo, +U. Artie Eoff, Umang Jain, Ursula Maplehurst, VaL Doroshchuk, Vasilis +Liaskovitis, Víctor Manuel Jáquez Leal, vijay, Vincent Penquerc'h, +Vineeth T M, Vivia Nikolaidou, Wang Xin-yu (王昕宇), Wei Feng, Wim +Taymans, Wonchul Lee, Xabier Rodriguez Calvar, Xavier Claessens, +XuGuangxin, Yasushi SHOJI, Yi A Wang, Youness Alaoui, ... and many others who have contributed bug reports, translations, sent suggestions or helped testing. -## Bugs fixed in 1.14 -- this section will be filled in shortly +Bugs fixed in 1.14 -More than [704 bugs][bugs-fixed-in-1.14] have been fixed during -the development of 1.14. +- this section will be filled in shortly + +More than 704 bugs have been fixed during the development of 1.14. This list does not include issues that have been cherry-picked into the -stable 1.12 branch and fixed there as well, all fixes that ended up in the -1.12 branch are also included in 1.14. +stable 1.12 branch and fixed there as well, all fixes that ended up in +the 1.12 branch are also included in 1.14. -This list also does not include issues that have been fixed without a bug -report in bugzilla, so the actual number of fixes is much higher. +This list also does not include issues that have been fixed without a +bug report in bugzilla, so the actual number of fixes is much higher. -[bugs-fixed-in-1.14]: https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&classification=Platform&limit=0&list_id=213265&order=bug_id&product=GStreamer&query_format=advanced&resolution=FIXED&target_milestone=1.12.1&target_milestone=1.12.2&target_milestone=1.12.3&target_milestone=1.12.4&target_milestone=1.13.1&target_milestone=1.13.2&target_milestone=1.13.3&target_milestone=1.13.4&target_milestone=1.13.90&target_milestone=1.13.91&target_milestone=1.14.0 -## Stable 1.14 branch +Stable 1.14 branch -After the 1.14.0 release there will be several 1.14.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.14.x bug-fix releases will be made from the git 1.14 branch, -which is a stable branch. +After the 1.14.0 release there will be several 1.14.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.14.x bug-fix releases will be made from +the git 1.14 branch, which is a stable branch. -### 1.14.0 +1.14.0 -1.14.0 is scheduled to be released in late February / early March 2018. +1.14.0 is scheduled to be released in early March 2018. -## Known Issues -- The `webrtcdsp` element is currently not shipped as part of the Windows - binary packages due to a [build system issue][bug-770264]. +Known Issues -[bug-770264]: https://bugzilla.gnome.org/show_bug.cgi?id=770264 +- The webrtcdsp element is currently not shipped as part of the + Windows binary packages due to a build system issue. -## Schedule for 1.16 -Our next major feature release will be 1.16, and 1.15 will be the unstable -development version leading up to the stable 1.16 release. The development -of 1.15/1.16 will happen in the git master branch. +Schedule for 1.16 -The plan for the 1.16 development cycle is yet to be confirmed, but it is -expected that feature freeze will be around August 2017 -followed by several 1.15 pre-releases and the new 1.16 stable release -in September. +Our next major feature release will be 1.16, and 1.15 will be the +unstable development version leading up to the stable 1.16 release. The +development of 1.15/1.16 will happen in the git master branch. -1.16 will be backwards-compatible to the stable 1.14, 1.12, 1.10, 1.8, 1.6, 1.4, -1.2 and 1.0 release series. +The plan for the 1.16 development cycle is yet to be confirmed, but it +is expected that feature freeze will be around August 2017 followed by +several 1.15 pre-releases and the new 1.16 stable release in September. -- - - +1.16 will be backwards-compatible to the stable 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.* +------------------------------------------------------------------------ -*License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)* +_These release notes have been prepared by Tim-Philipp Müller._ + +_License: CC BY-SA 4.0_ diff --git a/configure.ac b/configure.ac index 99023adb27..5200331763 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [13]) -m4_define([gst_vaapi_micro_version], [1]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_micro_version], [90]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1301]) +m4_define([gst_vaapi_lt_current], [1390]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1301]) +m4_define([gst_vaapi_lt_age], [1390]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.13.1.1]) -m4_define([gst_plugins_base_version], [1.13.1.1]) -m4_define([gst_plugins_bad_version], [1.13.1.1]) +m4_define([gst_version], [1.13.90]) +m4_define([gst_plugins_base_version], [1.13.90]) +m4_define([gst_plugins_bad_version], [1.13.90]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index c61018b94c..4ff896a927 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.13.90 + master + + 2018-03-03 + + + + 1.13.1 diff --git a/meson.build b/meson.build index c08bf889ec..a575f26a9d 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.13.1.1', + version : '1.13.90', meson_version : '>= 0.36.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 01d55f5667e0b7bf71c9997dd332c5304899c3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 13 Mar 2018 19:32:05 +0000 Subject: [PATCH 3053/3781] Release 1.13.91 --- ChangeLog | 11 + NEWS | 924 +++++++++++++++++++++++++++++++++++++++++-- configure.ac | 12 +- gstreamer-vaapi.doap | 10 + meson.build | 2 +- 5 files changed, 917 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index da8e5d21aa..b18880de5f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,18 @@ +=== release 1.13.91 === + +2018-03-13 19:32:05 +0000 Tim-Philipp Müller + + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.13.91 + === release 1.13.90 === 2018-03-03 22:59:30 +0000 Tim-Philipp Müller + * ChangeLog: * NEWS: * configure.ac: * gstreamer-vaapi.doap: diff --git a/NEWS b/NEWS index c85b362017..407ab98387 100644 --- a/NEWS +++ b/NEWS @@ -7,13 +7,13 @@ GStreamer 1.14.0 has not been released yet. It is scheduled for release in early March 2018. There are unstable pre-releases available for testing and development -purposes. The latest pre-release is version 1.13.90 (rc1) and was -released on 03 March 2018. +purposes. The latest pre-release is version 1.13.91 (rc2) and was +released on 12 March 2018. See https://gstreamer.freedesktop.org/releases/1.14/ for the latest version of this document. -_Last updated: Saturday 03 March 2018, 16:30 UTC (log)_ +_Last updated: Monday 12 March 2018, 18:00 UTC (log)_ Introduction @@ -28,103 +28,957 @@ other improvements. Highlights -- this section will be completed shortly +- WebRTC support: real-time audio/video streaming to and from web + browsers + +- Experimental support for the next-gen royalty-free AV1 video codec + +- Video4Linux: encoding support, stable element names and faster + device probing + +- Support for the Secure Reliable Transport (SRT) video streaming + protocol + +- RTP Forward Error Correction (FEC) support (ULPFEC) + +- RTSP 2.0 support in rtspsrc and gst-rtsp-server + +- ONVIF audio backchannel support in gst-rtsp-server and rtspsrc + +- playbin3 gapless playback and pre-buffering support + +- tee, our stream splitter/duplication element, now does allocation + query aggregation which is important for efficient data handling and + zero-copy + +- QuickTime muxer has a new prefill recording mode that allows file + import in Adobe Premiere and FinalCut Pro while the file is still + being written. + +- rtpjitterbuffer fast-start mode and timestamp offset adjustment + smoothing + +- souphttpsrc connection sharing, which allows for connection reuse, + cookie sharing, etc. + +- nvdec: new plugin for hardware-accelerated video decoding using the + NVIDIA NVDEC API + +- Adaptive DASH trick play support + +- ipcpipeline: new plugin that allows splitting a pipeline across + multiple processes + +- Major gobject-introspection annotation improvements for large parts + of the library API Major new features and changes -Noteworthy new API +WebRTC support -- this section will be filled in shortly +There is now basic support for WebRTC in GStreamer in form of a new +webrtcbin element and a webrtc support library. This allows you to build +applications that set up connections with and stream to and from other +WebRTC peers, whilst leveraging all of the usual GStreamer features such +as hardware-accelerated encoding and decoding, OpenGL integration, +zero-copy and embedded platform support. And it's easy to build and +integrate into your application too! + +WebRTC enables real-time communication of audio, video and data with web +browsers and native apps, and it is supported or about to be support by +recent versions of all major browsers and operating systems. + +GStreamer's new WebRTC implementation uses libnice for Interactive +Connectivity Establishment (ICE) to figure out the best way to +communicate with other peers, punch holes into firewalls, and traverse +NATs. + +The implementation is not complete, but all the basics are there, and +the code sticks fairly close to the PeerConnection API. Where +functionality is missing it should be fairly obvious where it needs to +go. + +For more details, background and example code, check out Nirbheek's blog +post _GStreamer has grown a WebRTC implementation_, as well as Matthew's +_GStreamer WebRTC_ talk from last year's GStreamer Conference in Prague. New Elements -- this section will be filled in shortly +- webrtcbin handles the transport aspects of webrtc connections (see + WebRTC section above for more details) -New element features and additions +- New srtsink and srtsrc elements for the Secure Reliable Transport + (SRT) video streaming protocol, which aims to be easy to use whilst + striking a new balance between reliability and latency for low + latency video streaming use cases. More details about SRT and the + implementation in GStreamer in Olivier's blog post _SRT in + GStreamer_. -- this section will be filled in shortly +- av1enc and av1dec elements providing experimental support for the + next-generation royalty free video AV1 codec, alongside Matroska + support for it. + +- hlssink2 is a rewrite of the existing hlssink element, but unlike + its predecessor hlssink2 takes elementary streams as input and + handles the muxing to MPEG-TS internally. It also leverages + splitmuxsink internally to do the splitting. This allows more + control over the chunk splitting and sizing process and relies less + on the co-operation of an upstream muxer. Different to the old + hlssink it also works with pre-encoded streams and does not require + close interaction with an upstream encoder element. + +- audiolatency is a new element for measuring audio latency end-to-end + and is useful to measure roundtrip latency including both the + GStreamer-internal latency as well as latency added by external + components or circuits. + +- 'fakevideosink is basically a null sink for video data and very + similar to fakesink, only that it will answer allocation queries and + will advertise support for various video-specific things such + GstVideoMeta, GstVideoCropMeta and GstVideoOverlayCompositionMeta + like a normal video sink would. This is useful for throughput + testing and testing the zero-copy path when creating a new pipeline. + +- ipcpipeline: new plugin that allows the splitting of a pipeline into + multiple processes. Usually a GStreamer pipeline runs in a single + process and parallelism is achieved by distributing workloads using + multiple threads. This means that all elements in the pipeline have + access to all the other elements' memory space however, including + that of any libraries used. For security reasons one might therefore + want to put sensitive parts of a pipeline such as DRM and decryption + handling into a separate process to isolate it from the rest of the + pipeline. This can now be achieved with the new ipcpipeline plugin. + Check out George's blog post _ipcpipeline: Splitting a GStreamer + pipeline into multiple processes_ or his lightning talk from last + year's GStreamer Conference in Prague for all the gory details. + +  +- proxysink and proxysrc are new elements to pass data from one + pipeline to another within the same process, very similar to the + existing inter elements, but not limited to raw audio and video + data. These new proxy elements are very special in how they work + under the hood, which makes them extremely powerful, but also + dangerous if not used with care. The reason for this is that it's + not just data that's passed from sink to src, but these elements + basically establish a two-way wormhole that passes through queries + and events in both directions, which means caps negotiation and + allocation query driven zero-copy can work through this wormhole. + There are scheduling considerations as well: proxysink forwards + everything into the proxysrc pipeline directly from the proxysink + streaming thread. There is a queue element inside proxysrc to + decouple the source thread from the sink thread, but that queue is + not unlimited, so it is entirely possible that the proxysink + pipeline thread gets stuck in the proxysrc pipeline, e.g. when that + pipeline is paused or stops consuming data for some other reason. + This means that one should always shut down down the proxysrc + pipeline before shutting down the proxysink pipeline, for example. + Or at least take care when shutting down pipelines. Usually this is + not a problem though, especially not in live pipelines. For more + information see Nirbheek's blog post _Decoupling GStreamer + Pipelines_, and also check out out the new ipcpipeline plugin for + sending data from one process to another process (see above). + +- lcms is a new LCMS-based ICC color profile correction element + +- openmptdec is a new OpenMPT-based decoder for module music formats, + such as S3M, MOD, XM, IT. It is built on top of a new + GstNonstreamAudioDecoder base class which aims to unify handling of + files which do not operate a streaming model. The wildmidi plugin + has also been revived and is also implemented on top of this new + base class. + +- The curl plugin has gained a new curlhttpsrc element, which is + useful for testing HTTP protocol version 2.0 amongst other things. + +Noteworthy new API + +- GstPromise provides future/promise-like functionality. This is used + in the GStreamer WebRTC implementation. + +  +- GstReferenceTimestampMeta is a new meta that allows you to attach + additional reference timestamps to a buffer. These timestamps don't + have to relate to the pipeline clock in any way. Examples of this + could be an NTP timestamp when the media was captured, a frame + counter on the capture side or the (local) UNIX timestamp when the + media was captured. The decklink elements make use of this. + +  +- GstVideoRegionOfInterestMeta: it's now possible to attach generic + free-form element-specific parameters to a region of interest meta, + for example to tell a downstream encoder to use certain codec + parameters for a certain region. + +  +- gst_bus_get_pollfd can be used to obtain a file descriptor for the + bus that can be poll()-ed on for new messages. This is useful for + integration with non-GLib event loops. + +  +- gst_get_main_executable_path() can be used by wrapper plugins that + need to find things in the directory where the application + executable is located. In the same vein, + GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_RELATIVE_TO_EXE can be used to + signal that plugin dependency paths are relative to the main + executable. + +- pad templates can be told about the GType of the pad subclass of the + pad via newly-added GstPadTemplate API API or the + gst_element_class_add_static_pad_template_with_gtype() convenience + function. gst-inspect-1.0 will use this information to print pad + properties. + +  +- new convenience functions to iterate over element pads without using + the GstIterator API: gst_element_foreach_pad(), + gst_element_foreach_src_pad(), and gst_element_foreach_sink_pad(). + +  +- GstBaseSrc and appsrc have gained support for buffer lists: + GstBaseSrc subclasses can use gst_base_src_submit_buffer_list(), and + applications can use gst_app_src_push_buffer_list() to push a buffer + list into appsrc. + +  +- The GstHarness unit test harness has a couple of new convenience + functions to retrieve all pending data in the harness in form of a + single chunk of memory. + +  +- GstAudioStreamAlign is a new helper object for audio elements that + handles discontinuity detection and sample alignment. It will align + samples after the previous buffer's samples, but keep track of the + divergence between buffer timestamps and sample position (jitter). + If it exceeds a configurable threshold the alignment will be reset. + This simply factors out code that was duplicated in a number of + elements into a common helper API. + +  +- The GstVideoEncoder base class implements Quality of Service (QoS) + now. This is disabled by default and must be opted in by setting the + "qos" property, which will make the base class gather statistics + about the real-time performance of the pipeline from downstream + elements (usually sinks that sync the pipeline clock). Subclasses + can then make use of this by checking whether input frames are late + already using gst_video_encoder_get_max_encode_time() If late, they + can just drop them and skip encoding in the hope that the pipeline + will catch up. + +  +- The GstVideoOverlay interface gained a few helper functions for + installing and handling a "render-rectangle" property on elements + that implement this interface, so that this functionality can also + be used from the command line for testing and debugging purposes. + The property wasn't added to the interface itself as that would + require all implementors to provide it which would not be + backwards-compatible. + +  +- A new base class, GstNonstreamAudioDecoder for non-stream audio + decoders was added to gst-plugins-bad. This base-class is meant to + be used for audio decoders that require the whole stream to be + loaded first before decoding can start. Examples of this are module + formats (MOD/S3M/XM/IT/etc), C64 SID tunes, video console music + files (GYM/VGM/etc), MIDI files and others. The new openmptdec + element is based on this. + +  +- Full list of API new in 1.14: +- GStreamer core API new in 1.14 +- GStreamer base library API new in 1.14 +- gst-plugins-base libraries API new in 1.14 +- gst-plugins-bad: no list, mostly GstWebRTC library and new + non-stream audio decoder base class. + +New RTP features and improvements + +- rtpulpfecenc and rtpulpfecdec are new elements that implement + Generic Forward Error Correction (FEC) using Uneven Level Protection + (ULP) as described in RFC 5109. This can be used to protect against + certain types of (non-bursty) packet loss, and important packets + such as those containing codec configuration data or key frames can + be protected with higher redundancy. Equally, packets that are not + particularly important can be given low priority or not be protected + at all. If packets are lost, the receiver can then hopefully restore + the lost packet(s) from the surrounding packets which were received. + This is an alternative to, or rather complementary to, dealing with + packet loss using _retransmission (rtx)_. GStreamer has had + retransmission support for a long time, but Forward Error Correction + allows for different trade-offs: The advantage of Forward Error + Correction is that it doesn't add latency, whereas retransmission + requires at least one more roundtrip to request and hopefully + receive lost packets; Forward Error Correction increases the + required bandwidth however, even in situations where there is no + packet loss at all, so one will typically want to fine-tune the + overhead and mechanisms used based on the characteristics of the + link at the time. + +- New _Redundant Audio Data (RED)_ encoders and decoders for RTP as + per RFC 2198 are also provided (rtpredenc and rtpreddec), mostly for + chrome webrtc compatibility, as chrome will wrap ULPFEC-protected + streams in RED packets, and such streams need to be wrapped and + unwrapped in order to use ULPFEC with chrome. + +  +- a few new buffer flags for FEC support: + GST_BUFFER_FLAG_NON_DROPPABLE can be used to mark important buffers, + e.g. to flag RTP packets carrying keyframes or codec setup data for + RTP Forward Error Correction purposes, or to prevent still video + frames from being dropped by elements due to QoS. There already is a + GST_BUFFER_FLAG_DROPPABLE. GST_RTP_BUFFER_FLAG_REDUNDANT is used to + signal internally that a packet represents a redundant RTP packet + and used in rtpstorage to hold back the packet and use it only for + recovery from packet loss. Further work is still needed in + payloaders to make use of these. + +- rtpbin now has an option for increasing timestamp offsets gradually: + Instant large changes to the internal ts_offset may cause timestamps + to move backwards and also cause visible glitches in media playback. + The new "max-ts-offset-adjustment" and "max-ts-offset" properties + let the application control the rate to apply changes to ts_offset. + There have also been some EOS/BYE handling improvements in rtpbin. + +- rtpjitterbuffer has a new fast start mode: in many scenarios the + jitter buffer will have to wait for the full configured latency + before it can start outputting packets. The reason for that is that + it often can't know what the sequence number of the first expected + RTP packet is, so it can't know whether a packet earlier than the + earliest packet received will still arrive in future. This behaviour + can now be bypassed by setting the "faststart-min-packets" property + to the number of consecutive packets needed to start, and the jitter + buffer will start output packets as soon as it has N consecutive + packets queued internally. This is particularly useful to get a + first video frame decoded and rendered as quickly as possible. + +- rtpL8pay and rtpL8depay provide RTP payloading and depayloading for + 8-bit raw audio + +New element features + +- playbin3 has gained support or gapless playback via the + "about-to-finish" signal where users can set the uri for the next + item to play. For non-live streams this will be emitted as soon as + the first uri has finished downloading, so with sufficiently large + buffers it is now possible to pre-buffer the next item well ahead of + time (unlike playbin where there would not be a lot of time between + "about-to-finish" emission and the end of the stream). If the stream + format of the next stream is the same as that of the previous + stream, the data will be concatenated via the concat element. + Whether this will result in true gaplessness depends on the + container format and codecs used, there might still be codec-related + gaps between streams with some codecs. + +- tee now does allocation query aggregation, which is important for + zero-copy and efficient data handling, especially for video. Those + who want to drop allocation queries on purpose can use the identity + element's new "drop-allocation" property for that instead. + +- audioconvert now has a "mix-matrix" property, which obsoletes the + audiomixmatrix element. There's also mix matrix support in the audio + conversion and channel mixing API. + +- x264enc: new "insert-vui" property to disable VUI (Video Usability + Information) parameter insertion into the stream, which allows + creation of streams that are compatible with certain legacy hardware + decoders that will refuse to decode in certain combinations of + resolution and VUI parameters; the max. allowed number of B-frames + was also increased from 4 to 16. + +- dvdlpcmdec: has gained support for Blu-Ray audio LPCM. + +- appsrc has gained support for buffer lists (see above) and also seen + some other performance improvements. + +- flvmux has been ported to the GstAggregator base class which means + it can work in defined-latency mode with live input sources and + continue streaming if one of the inputs stops producing data. + +- jpegenc has gained a "snapshot" property just like pngenc to make it + easier to just output a single encoded frame. + +- jpegdec will now handle interlaced MJPEG streams properly and also + handle frames without an End of Image marker better. + +- v4l2: There are now video encoders for VP8, VP9, MPEG4, and H263. + The v4l2 video decoder handles dynamic resolution changes, and the + video4linux device provider now does much faster device probing. The + plugin also no longer uses the libv4l2 library by default, as it has + prevented a lot of interesting use cases like CREATE_BUFS, DMABuf, + usage of TRY_FMT. As the libv4l2 library is totally inactive and not + really maintained, we decided to disable it. This might affect a + small number of cheap/old webcams with custom vendor formats for + which we do not provide conversion in GStreamer. It is possible to + re-enable support for libv4l2 at run-time however, by setting the + environment variable GST_V4L2_USE_LIBV4L2=1. + +- rtspsrc now has support for RTSP protocol version 2.0 as well as + ONVIF audio backchannels (see below for more details). It also + sports a new ["accept-certificate"] signal for "manually" checking a + TLS certificate for validity. It now also prints RTSP/SDP messages + to the gstreamer debug log instead of stdout. + +- shout2send now uses non-blocking I/O and has a configurable network + operations timeout. + +- splitmuxsink has gained a "split-now" action signal and new + "alignment-threshold" and "use-robust-muxing" properties. If robust + muxing is enabled, it will check and set the muxer's reserved space + properties if present. This is primarily for use with mp4mux's + robust muxing mode. + +- qtmux has a new _prefill recording mode_ which sets up a moov header + with the correct sample positions beforehand, which then allows + software like Adobe Premiere and FinalCut Pro to import the files + while they are still being written to. This only works with constant + framerate I-frame only streams, and for now only support for ProRes + video and raw audio is implemented but adding new codecs is just a + matter of defining appropriate maximum frame sizes. + +- qtmux also supports writing of svmi atoms with stereoscopic video + information now. Trak timescales can be configured on a per-stream + basis using the "trak-timescale" property on the sink pads. Various + new formats can be muxed: MPEG layer 1 and 2, AC3 and Opus, as well + as PNG and VP9. + +- souphttpsrc now does connection sharing by default, shares its + SoupSession with other elements in the same pipeline via a + GstContext if possible (session-wide settings are all the defaults). + This allows for connection reuse, cookie sharing, etc. Applications + can also force a context to use. In other news, HTTP headers + received from the server are posted as element messages on the bus + now for easier diagnostics, and it's also possible now to use other + types of proxy servers such as SOCKS4 or SOCKS5 proxies, support for + which is implemented directly in gio. Before only HTTP proxies were + allowed. + +- qtmux, mp4mux and matroskamux will now refuse caps changes of input + streams at runtime. This isn't really supported with these + containers (or would have to be implemented differently with a + considerable effort) and doesn't produce valid and spec-compliant + files that will play everywhere. So if you can't guarantee that the + input caps won't change, use a container format that does support on + the fly caps changes for a stream such as MPEG-TS or use + splitmuxsink which can start a new file when the caps change. What + would happen before is that e.g. rtph264depay or rtph265depay would + simply send new SPS/PPS inband even for AVC format, which would then + get muxed into the container as if nothing changed. Some decoders + will handle this just fine, but that's often more luck than by + design. In any case, it's not right, so we disallow it now. + +- matroskamux had Table of Content (TOC) support now (chapters etc.) + and matroskademux TOC support has been improved. matroskademux has + also seen seeking improvements searching for the right cluster and + position. + +- videocrop now uses GstVideoCropMeta if downstream supports it, which + means cropping can be handled more efficiently without any copying. + +- compositor now has support for _crossfade blending_, which can be + used via the new "crossfade-ratio" property on the sink pads. + +- The avwait element has a new "end-timecode" property and posts + "avwait-status" element messages now whenever avwait starts or stops + passing through data (e.g. because target-timecode and end-timecode + respectively have been reached). + +  +- h265parse and h265parse will try harder to make upstream output the + same caps as downstream requires or prefers, thus avoiding + unnecessary conversion. The parsers also expose chroma format and + bit depth in the caps now. + +- The dtls elements now longer rely on or require the application to + run a GLib main loop that iterates the default main context + (GStreamer plugins should never rely on the application running a + GLib main loop). + +- openh264enc allows to change the encoding bitrate dynamically at + runtime now + +- nvdec is a new plugin for hardware-accelerated video decoding using + the NVIDIA NVDEC API (which replaces the old VDPAU API which is no + longer supported by NVIDIA) + +- The NVIDIA NVENC hardware-accelerated video encoders now support + dynamic bitrate and preset reconfiguration and support the I420 + 4:2:0 video format. It's also possible to configure the gop size via + the new "gop-size" property. + +- The MPEG-TS muxer and demuxer (tsmux, tsdemux) now have support for + JPEG2000 + +- openjpegdec and jpeg2000parse support 2-component images now (gray + with alpha), and jpeg2000parse has gained limited support for + conversion between JPEG2000 stream-formats. (JP2, J2C, JPC) and also + extracts more details such as colorimetry, interlace-mode, + field-order, multiview-mode and chroma siting. + +- The decklink plugin for Blackmagic capture and playback cards have + seen numerous improvements: + +- decklinkaudiosrc and decklinkvideosrc now put hardware reference + timestamp on buffers in form of GstReferenceTimestampMetas. + This can be useful to know on multi-channel cards which frames from + different channels were captured at the same time. + +- decklinkvideosink has gained support for Decklink hardware keying + with two new properties ("keyer-mode" and "keyer-level") to control + the built-in hardware keyer of Decklink cards. + +- decklinkaudiosink has been re-implemented around GstBaseSink instead + of the GstAudioBaseSink base class, since the Decklink APIs don't + fit very well with the GstAudioBaseSink APIs, which used to cause + various problems due to inaccuracies in the clock calculations. + Problems were audio drop-outs and A/V sync going wrong after + pausing/seeking. + +- support for more than 16 devices, without any artificial limit + +- work continued on the msdk plugin for Intel's Media SDK which + enables hardware-accelerated video encoding and decoding on Intel + graphics hardware on Windows or Linux. More tuning options were + added, and more pixel formats and video codecs are supported now. + The encoder now also handles force-key-unit events and can insert + frame-packing SEIs for side-by-side and top-bottom stereoscopic 3D + video. + +- dashdemux can now do adaptive trick play of certain types of DASH + streams, meaning it can do fast-forward/fast-rewind of normal (non-I + frame only) streams even at high speeds without saturating network + bandwidth or exceeding decoder capabilities. It will keep statistics + and skip keyframes or fragments as needed. See Sebastian's blog post + _DASH trick-mode playback in GStreamer_ for more details. It also + supports webvtt subtitle streams now and has seen improvements when + seeking in live streams. + +  +- kmssink has seen lots of fixes and improvements in this cycle, + including: + +- Raspberry Pi (vc4) and Xilinx DRM driver support + +- new "render-rectangle" property that can be used from the command + line as well as "display-width" and "display-height", and + "can-scale" properties + +- GstVideoCropMeta support Plugin and library moves -- this section will be filled in shortly +MPEG-1 audio (mp1, mp2, mp3) decoders and encoders moved to -good + +Following the expiration of the last remaining mp3 patents in most +jurisdictions, and the termination of the mp3 licensing program, as well +as the decision by certain distros to officially start shipping full mp3 +decoding and encoding support, these plugins should now no longer be +problematic for most distributors and have therefore been moved from +-ugly and -bad to gst-plugins-good. Distributors can still disable these +plugins if desired. + +In particular these are: + +- mpg123audiodec: an mp1/mp2/mp3 audio decoder using libmpg123 +- lamemp3enc: an mp3 encoder using LAME +- twolamemp2enc: an mp2 encoder using TwoLAME + +GstAggregator moved from -bad to core + +GstAggregator has been moved from gst-plugins-bad to the base library in +GStreamer and is now stable API. + +GstAggregator is a new base class for mixers and muxers that have to +handle multiple input pads and aggregate streams into one output stream. +It improves upon the existing GstCollectPads API in that it is a proper +base class which was also designed with live streaming in mind. +GstAggregator subclasses will operate in a mode with defined latency if +any of the inputs are live streams. This ensures that the pipeline won't +stall if any of the inputs stop producing data, and that the configured +maximum latency is never exceeded. + +GstAudioAggregator, audiomixer and audiointerleave moved from -bad to -base + +GstAudioAggregator is a new base class for raw audio mixers and muxers +and is based on GstAggregator (see above). It provides defined-latency +mixing of raw audio inputs and ensures that the pipeline won't stall +even if one of the input streams stops producing data. + +As part of the move to stabilise the API there were some last-minute API +changes and clean-ups, but those should mostly affect internal elements. + +It is used by the audiomixer element, which is a replacement for +'adder', which did not handle live inputs very well and did not align +input streams according to running time. audiomixer should behave much +better in that respect and generally behave as one would expected in +most scenarios. + +Similarly, audiointerleave replaces the 'interleave' element which did +not handle live inputs or non-aligned inputs very robustly. + +GstAudioAggregator and its subclases have gained support for input +format conversion, which does not include sample rate conversion though +as that would add additional latency. Furthermore, GAP events are now +handled correctly. + +We hope to move the video equivalents (GstVideoAggregator and +compositor) to -base in the next cycle, i.e. for 1.16. + +GStreamer OpenGL integration library and plugin moved from -bad to -base + +The GStreamer OpenGL integration library and opengl plugin have moved +from gst-plugins-bad to -base and are now part of the stable API canon. +Not all OpenGL elements have been moved; a few had to be left behind in +gst-plugins-bad in the new openglmixers plugin, because they depend on +the GstVideoAggregator base class which we were not able to move in this +cycle. We hope to reunite these elements with the rest of their family +for 1.16 though. + +This is quite a milestone, thanks to everyone who worked to make this +happen! + +Qt QML and GTK plugins moved from -bad to -good + +The Qt QML-based qmlgl plugin has moved to -good and provides a +qmlglsink video sink element as well as a qmlglsrc element. qmlglsink +renders video into a QQuickItem, and qmlglsrc captures a window from a +QML view and feeds it as video into a pipeline for further processing. +Both elements leverage GStreamer's OpenGL integration. In addition to +the move to -good the following features were added: + +- A proxy object is now used for thread-safe access to the QML widget + which prevents crashes in corner case scenarios: QML can destroy the + video widget at any time, so without this we might be left with a + dangling pointer. + +- EGL is now supported with the X11 backend, which works e.g. on + Freescale imx6 + +The GTK+ plugin has also moved from -bad to -good. It includes gtksink +and gtkglsink which both render video into a GtkWidget. gtksink uses +Cairo for rendering the video, which will work everywhere in all +scenarios but involves an extra memory copy, whereas gtkglsink fully +leverages GStreamer's OpenGL integration, but might not work properly in +all scenarios, e.g. where the OpenGL driver does not properly support +multiple sharing contexts in different threads; on Linux Nouveau is +known to be broken in this respect, whilst NVIDIA's proprietary drivers +and most other drivers generally work fine, and the experience with +Intel's driver seems to be fixed; some proprietary embedded Linux +drivers don't work; macOS works). + +GstPhysMemoryAllocator interface moved from -bad to -base + +GstPhysMemoryAllocator is a marker interface for allocators with +physical address backed memory. Plugin removals -- this section will be filled in shortly +- the sunaudio plugin was removed, since it couldn't ever have been + built or used with GStreamer 1.0, but no one even noticed in all + these years. +- the schroedinger-based Dirac encoder/decoder plugin has been + removed, as there is no longer any upstream or anyone else + maintaining it. Seeing that it's quite a fringe codec it seemed best + to simply remove it. -Miscellaneous API additions +API removals -- this section will be filled in shortly - -GstPlayer - -- this section will be filled in shortly +- some MPEG video parser API in the API unstable codecutils library in + gst-plugins-bad was removed after having been deprecated for 5 + years. Miscellaneous changes -- this section will be filled in shortly +- The video support library has gained support for a few new pixel + formats: +- NV16_10LE32: 10-bit variant of NV16, packed into 32bit words (plus 2 + bits padding) +- NV12_10LE32: 10-bit variant of NV12, packed into 32bit words (plus 2 + bits padding) +- GRAY10_LE32: 10-bit grayscale, packed in 32bit words (plus 2 bits + padding) + +- decodebin, playbin and GstDiscoverer have seen stability + improvements in corner cases such as shutdown while still starting + up or shutdown in error cases (hat tip to the oss-fuzz project). + +- floating reference handling was inconsistent and has been cleaned up + across the board, including annotations. This solves various + long-standing memory leaks in language bindings, which e.g. often + caused elements and pads to be leaked. + +- major gobject-introspection annotation improvements for large parts + of the library API, including nullability of return types and + function parameters, correct types (e.g. strings vs. filenames), + ownership transfer, array length parameters, etc. This allows to use + bigger parts of the GStreamer API to be safely used from dynamic + language bindings (e.g. Python, Javascript) and allows static + bindings (e.g. C#, Rust, Vala) to autogenerate more API bindings + without manual intervention. OpenGL integration -- this section will be filled in shortly +- The GStreamer OpenGL integration library has moved to + gst-plugins-base and is now part of our stable API. + +- new MESA3D GBM BACKEND. On devices with working libdrm support, it + is possible to use Mesa3D's GBM library to set up an EGL context + directly on top of KMS. This makes it possible to use the GStreamer + OpenGL elements without a windowing system if a libdrm- and + Mesa3D-supported GPU is present. + +- Prefer wayland display over X11: As most Wayland compositors support + XWayland, the X11 backend would get selected. + +- gldownload can export dmabufs now, and glupload will advertise + dmabuf as caps feature. Tracing framework and debugging improvements -- this section will be filled in shortly +- NEW MEMORY RINGBUFFER BASED DEBUG LOGGER, useful for long-running + applications or to retrieve diagnostics when encountering an error. + The GStreamer debug logging system provides in-depth debug logging + about what is going on inside a pipeline. When enabled, debug logs + are usually written into a file, printed to the terminal, or handed + off to a log handler installed by the application. However, at + higher debug levels the volume of debug output quickly becomes + unmanageable, which poses a problem in disk-space or bandwidth + restricted environments or with long-running pipelines where a + problem might only manifest itself after multiple days. In those + situations, developers are usually only interested in the most + recent debug log output. The new in-memory ringbuffer logger makes + this easy: just installed it with gst_debug_add_ring_buffer_logger() + and retrieve logs with gst_debug_ring_buffer_logger_get_logs() when + needed. It is possible to limit the memory usage per thread and set + a timeout to determine how long messages are kept around. It was + always possible to implement this in the application with a custom + log handler of course, this just provides this functionality as part + of GStreamer. + +  +- 'fakevideosink is a null sink for video data that advertises + video-specific metas ane behaves like a video sink. See above for + more details. + +- gst_util_dump_buffer() prints the content of a buffer to stdout. + +- gst_pad_link_get_name() and gst_state_change_get_name() print pad + link return values and state change transition values as strings. + +- The LATENCY TRACER has seen a few improvements: trace records now + contain timestamps which is useful to plot things over time, and + downstream synchronisation time is now excluded from the measured + values. + +- Miniobject refcount tracing and logging was not entirley + thread-safe, there were duplicates or missing entries at times. This + has now been made reliable. + +- The netsim element, which can be used to simulate network jitter, + packet reordering and packet loss, received new features and + improvements: it can now also simulate network congestion using a + token bucket algorithm. This can be enabled via the "max-kbps" + property. Packet reordering can be disabled now via the + "allow-reordering" property: Reordering of packets is not very + common in networks, and the delay functions will always introduce + reordering if delay > packet-spacing, so by setting + "allow-reordering" to FALSE you guarantee that the packets are in + order, while at the same time introducing delay/jitter to them. By + using the new "delay-distribution" property the use can control how + the delay applied to delayed packets is distributed: This is either + the uniform distribution (as before) or the normal distribution; in + addition there is also the gamma distribution which simulates the + delay on wifi networks better. Tools -- this section will be filled in shortly +- gst-inspect-1.0 now prints pad properties for elements that have pad + subclasses with special properties, such as compositor or + audiomixer. This only works for elements that use the newly-added + GstPadTemplate API API or the + gst_element_class_add_static_pad_template_with_gtype() convenience + function to tell GStreamer about the special pad subclass. + +- gst-launch-1.0 now generates a gstreamer pipeline diagram (.dot + file) whenever SIGHUP is sent to it on Linux/*nix systems. + +- gst-discoverer-1.0 can now analyse live streams such as rtsp:// URIs GStreamer RTSP server -- this section will be filled in shortly +- Initial support for [RTSP protocol version + 2.0][rtsp2-lightning-talk] was added, which is to the best of our + knowledge the first RTSP 2.0 implementation ever! + +- ONVIF audio backchannel support. This is an extension specified by + ONVIF that allows RTSP clients (e.g. a control room operator) to + send audio back to the RTSP server (e.g. an IP camera). + Theoretically this could have been done also by using the RECORD + method of the RTSP protocol, but ONVIF chose not to do that, so the + backchannel is set up alongside the other streams. Format + negotiation needs to be done out of band, if needed. Use the new + ONVIF-specific subclasses GstRTSPOnvifServer and + GstRTSPOnvifMediaFactory to enable this functionality. + +  +- The internal server streaming pipeline is now dynamically + reconfigured on PLAY based on the transports needed. This means that + the server no longer adds the pipeline plumbing for all possible + transports from the start, but only if needed as needed. This + improves performance and memory footprint. + +- rtspclientsink has gained an "accept-certificate" signal for + manually checking a TLS certificate for validity. + +- Fix keep-alive/timeout issue for certain clients using TCP + interleave as transport who don't do keep-alive via some other + method such as periodic RTSP OPTION requests. We now put netaddress + metas on the packets from the TCP interleaved stream, so can map + RTCP packets to the right stream in the server and can handle them + properly. + +- Language bindings improvements: in general there were quite a few + improvements in the gobject-introspection annotations, but we also + extended the permissions API which was not usable from bindings + before. + +- Fix corner case issue where the wrong mount point was found when + there were multiple mount points with a common prefix. GStreamer VAAPI -- this section will be filled in shortly +- this section will be filled in shortly {FIXME!} GStreamer Editing Services and NLE -- this section will be filled in shortly +- this section will be filled in shortly {FIXME!} GStreamer validate -- this section will be filled in shortly +- this section will be filled in shortly {FIXME!} GStreamer Python Bindings -- this section will be filled in shortly +- this section will be filled in shortly {FIXME!} Build and Dependencies -- this section will be filled in shortly +- the new WebRTC support in gst-plugins-bad depends on the GStreamer + elements that ship as part of libnice, and libnice version 1.1.14 is + required. Also the dtls and srtp plugins. + +- gst-plugins-bad no longer depends on the libschroedinger Dirac codec + library. + +- The srtp plugin can now also be built against libsrtp2. + +- some plugins and libraries have moved between modules, see the + _Plugin and_ _library moves_ section above, and their respective + dependencies have moved with them of course, e.g. the GStreamer + OpenGL integration support library and plugin is now in + gst-plugins-base, and mpg123, LAME and twoLAME based audio decoder + and encoder plugins are now in gst-plugins-good. + +- Unify static and dynamic plugin interface and remove plugin specific + static build option: Static and dynamic plugins now have the same + interface. The standard --enable-static/--enable-shared toggle is + sufficient. This allows building static and shared plugins from the + same object files, instead of having to build everything twice. + +- The default plugin entry point has changed. This will only affect + plugins that are recompiled against new GStreamer headers. Binary + plugins using the old entry point will continue to work. However, + plugins that are recompiled must have matching plugin names in + GST_PLUGIN_DEFINE and filenames, as the plugin entry point for + shared plugins is now deduced from the plugin filename. This means + you can no longer have a plugin called foo living in a file called + libfoobar.so or such, the plugin filename needs to match. This might + cause problems with some external third party plugin modules when + they get rebuilt against GStreamer 1.14. + + +Note to packagers and distributors + +A number of libraries, APIs and plugins moved between modules and/or +libraries in different modules between version 1.12.x and 1.14.x, see +the _Plugin and_ _library moves_ section above. Some APIs have seen +minor ABI changes in the course of moving them into the stable APIs +section. + +This means that you should try to ensure that all major GStreamer +modules are synced to the same major version (1.12 or 1.13/1.14) and can +only be upgraded in lockstep, so that your users never end up with a mix +of major versions on their system at the same time, as this may cause +breakages. + +Also, plugins compiled against >= 1.14 headers will not load with +GStreamer <= 1.12 owing to a new plugin entry point (but plugin binaries +built against older GStreamer versions will continue to load with newer +versions of GStreamer of course). + +There is also a small structure size related ABI breakage introduced in +the gst-plugins-bad codecparsers library between version 1.13.90 and +1.13.91. This should "only" affect gstreamer-vaapi, so anyone who ships +the release candidates is advised to upgrade those two modules at the +same time. Platform-specific improvements Android -- this section will be filled in shortly +- ahcsrc (Android camera source) does autofocus now macOS and iOS -- this section will be filled in shortly +- this section will be filled in shortly {FIXME!} Windows -- this section will be filled in shortly +- The GStreamer wasapi plugin was rewritten and should not only be + usable now, but in top shape and suitable for low-latency use cases. + The Windows Audio Session API (WASAPI) is Microsoft's most modern + method for talking with audio devices, and now that the wasapi + plugin is up to scratch it is preferred over the directsound plugin. + The ranks of the wasapisink and wasapisrc elements have been updated + to reflect this. Further improvements include: + +- support for more than 2 channels + +- a new "low-latency" property to enable low-latency operation (which + should always be safe to enable) + +- support for the AudioClient3 API which is only available on Windows + 10: in wasapisink this will be used automatically if available; in + wasapisrc it will have to be enabled explicitly via the + "use-audioclient3" property, as capturing audio with low latency and + without glitches seems to require setting the realtime priority of + the entire pipeline to "critical", which cannot be done from inside + the element, but has to be done in the application. + +- set realtime thread priority to avoid glitches + +- allow opening devices in exclusive mode, which provides much lower + latency compared to shared mode where WASAPI's engine period is + 10ms. This can be activated via the "exclusive" property. + +- There are now GstDeviceProvider implementations for the wasapi and + directsound plugins, so it's now possible to discover both audio + sources and audio sinks on Windows via the GstDeviceMonitor API + +- debug log timestamps are now higher granularity owing to + g_get_monotonic_time() now being used as fallback in + gst_utils_get_timestamp(). Before that, there would sometimes be + 10-20 lines of debug log output sporting the same timestamp. Contributors @@ -184,9 +1038,7 @@ suggestions or helped testing. Bugs fixed in 1.14 -- this section will be filled in shortly - -More than 704 bugs have been fixed during the development of 1.14. +More than 800 bugs have been fixed during the development of 1.14. This list does not include issues that have been cherry-picked into the stable 1.12 branch and fixed there as well, all fixes that ended up in @@ -211,7 +1063,8 @@ the git 1.14 branch, which is a stable branch. Known Issues -- The webrtcdsp element is currently not shipped as part of the +- The webrtcdsp element (which is unrelated to the newly-landed + GStreamer webrtc support) is currently not shipped as part of the Windows binary packages due to a build system issue. @@ -230,6 +1083,7 @@ several 1.15 pre-releases and the new 1.16 stable release in September. ------------------------------------------------------------------------ -_These release notes have been prepared by Tim-Philipp Müller._ +_These release notes have been prepared by Tim-Philipp Müller with_ +_contributions from Sebastian Dröge._ _License: CC BY-SA 4.0_ diff --git a/configure.ac b/configure.ac index 5200331763..49129abfa0 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [13]) -m4_define([gst_vaapi_micro_version], [90]) +m4_define([gst_vaapi_micro_version], [91]) m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1390]) +m4_define([gst_vaapi_lt_current], [1391]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1390]) +m4_define([gst_vaapi_lt_age], [1391]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.13.90]) -m4_define([gst_plugins_base_version], [1.13.90]) -m4_define([gst_plugins_bad_version], [1.13.90]) +m4_define([gst_version], [1.13.91]) +m4_define([gst_plugins_base_version], [1.13.91]) +m4_define([gst_plugins_bad_version], [1.13.91]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 4ff896a927..3f471b985d 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.13.91 + master + + 2018-03-13 + + + + 1.13.90 diff --git a/meson.build b/meson.build index a575f26a9d..6074f5b8fa 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.13.90', + version : '1.13.91', meson_version : '>= 0.36.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From bfa2fbd39bea8928bbfcfe0e914dc6384b2140a5 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Mon, 12 Mar 2018 16:59:01 +0000 Subject: [PATCH 3054/3781] libs: decoder: h264: ensure num_ref_frames is greater than 0 Even if it is the h264parse fault or bad video file, vaapih264dec should set a proper value for VAPictureParameterBufferH264.num_ref_frames as the driver might use it. Also see "info.ref_frames = dpb_size;" in gstvaapidecoder_h264.c::ensure_context https://bugzilla.gnome.org/show_bug.cgi?id=793836 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index a0698659d8..184668c572 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -3857,6 +3857,9 @@ fill_picture (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) COPY_FIELD (sps, bit_depth_luma_minus8); COPY_FIELD (sps, bit_depth_chroma_minus8); COPY_FIELD (sps, num_ref_frames); + if (pic_param->num_ref_frames == 0) + pic_param->num_ref_frames = priv->dpb_size; + #if !VA_CHECK_VERSION(1,0,0) /* Deprecate H.264 baseline profile and FMO support */ COPY_FIELD (pps, num_slice_groups_minus1); From 67ebe1f45a7ded01f27c91a583243770a829b8c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 19 Mar 2018 20:30:28 +0000 Subject: [PATCH 3055/3781] Release 1.14.0 --- ChangeLog | 23 +++++ NEWS | 222 ++++++++++++++++++++++++++++++++----------- configure.ac | 14 +-- gstreamer-vaapi.doap | 10 ++ meson.build | 2 +- 5 files changed, 209 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index b18880de5f..1b1e9287c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,30 @@ +=== release 1.14.0 === + +2018-03-19 20:30:28 +0000 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * configure.ac: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.14.0 + +2018-03-12 16:59:01 +0000 Julien Isorce + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: ensure num_ref_frames is greater than 0 + Even if it is the h264parse fault or bad video file, vaapih264dec + should set a proper value for VAPictureParameterBufferH264.num_ref_frames + as the driver might use it. + Also see "info.ref_frames = dpb_size;" in + gstvaapidecoder_h264.c::ensure_context + https://bugzilla.gnome.org/show_bug.cgi?id=793836 + === release 1.13.91 === 2018-03-13 19:32:05 +0000 Tim-Philipp Müller + * ChangeLog: * NEWS: * configure.ac: * gstreamer-vaapi.doap: diff --git a/NEWS b/NEWS index 407ab98387..64dcb91eaf 100644 --- a/NEWS +++ b/NEWS @@ -3,17 +3,19 @@ GSTREAMER 1.14 RELEASE NOTES -GStreamer 1.14.0 has not been released yet. It is scheduled for release -in early March 2018. +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! -There are unstable pre-releases available for testing and development -purposes. The latest pre-release is version 1.13.91 (rc2) and was -released on 12 March 2018. +As always, this release is again packed with new features, bug fixes and +other improvements. + +GStreamer 1.14.0 was released on 19 March 2018. See https://gstreamer.freedesktop.org/releases/1.14/ for the latest version of this document. -_Last updated: Monday 12 March 2018, 18:00 UTC (log)_ +_Last updated: Monday 19 March 2018, 12:00 UTC (log)_ Introduction @@ -72,6 +74,13 @@ Highlights - Major gobject-introspection annotation improvements for large parts of the library API +- GStreamer C# bindings have been revived and seen many updates and + fixes + +- The externally maintained GStreamer Rust bindings had many usability + improvements and cover most of the API now. Coinciding with the 1.14 + release, a new release with the 1.14 API additions is happening. + Major new features and changes @@ -153,7 +162,6 @@ New Elements pipeline into multiple processes_ or his lightning talk from last year's GStreamer Conference in Prague for all the gory details. -  - proxysink and proxysrc are new elements to pass data from one pipeline to another within the same process, very similar to the existing inter elements, but not limited to raw audio and video @@ -191,12 +199,14 @@ New Elements - The curl plugin has gained a new curlhttpsrc element, which is useful for testing HTTP protocol version 2.0 amongst other things. +- The msdk plugin has gained a MPEG-2 video decoder(msdkmpeg2dec), VP8 + decoder(msdkvp8dec) and a VC1/WMV decoder(msdkvc1dec) + Noteworthy new API - GstPromise provides future/promise-like functionality. This is used in the GStreamer WebRTC implementation. -  - GstReferenceTimestampMeta is a new meta that allows you to attach additional reference timestamps to a buffer. These timestamps don't have to relate to the pipeline clock in any way. Examples of this @@ -204,18 +214,15 @@ Noteworthy new API counter on the capture side or the (local) UNIX timestamp when the media was captured. The decklink elements make use of this. -  - GstVideoRegionOfInterestMeta: it's now possible to attach generic free-form element-specific parameters to a region of interest meta, for example to tell a downstream encoder to use certain codec parameters for a certain region. -  - gst_bus_get_pollfd can be used to obtain a file descriptor for the bus that can be poll()-ed on for new messages. This is useful for integration with non-GLib event loops. -  - gst_get_main_executable_path() can be used by wrapper plugins that need to find things in the directory where the application executable is located. In the same vein, @@ -229,23 +236,19 @@ Noteworthy new API function. gst-inspect-1.0 will use this information to print pad properties. -  - new convenience functions to iterate over element pads without using the GstIterator API: gst_element_foreach_pad(), gst_element_foreach_src_pad(), and gst_element_foreach_sink_pad(). -  - GstBaseSrc and appsrc have gained support for buffer lists: GstBaseSrc subclasses can use gst_base_src_submit_buffer_list(), and applications can use gst_app_src_push_buffer_list() to push a buffer list into appsrc. -  - The GstHarness unit test harness has a couple of new convenience functions to retrieve all pending data in the harness in form of a single chunk of memory. -  - GstAudioStreamAlign is a new helper object for audio elements that handles discontinuity detection and sample alignment. It will align samples after the previous buffer's samples, but keep track of the @@ -254,7 +257,6 @@ Noteworthy new API This simply factors out code that was duplicated in a number of elements into a common helper API. -  - The GstVideoEncoder base class implements Quality of Service (QoS) now. This is disabled by default and must be opted in by setting the "qos" property, which will make the base class gather statistics @@ -265,7 +267,6 @@ Noteworthy new API can just drop them and skip encoding in the hope that the pipeline will catch up. -  - The GstVideoOverlay interface gained a few helper functions for installing and handling a "render-rectangle" property on elements that implement this interface, so that this functionality can also @@ -274,7 +275,6 @@ Noteworthy new API require all implementors to provide it which would not be backwards-compatible. -  - A new base class, GstNonstreamAudioDecoder for non-stream audio decoders was added to gst-plugins-bad. This base-class is meant to be used for audio decoders that require the whole stream to be @@ -283,7 +283,6 @@ Noteworthy new API files (GYM/VGM/etc), MIDI files and others. The new openmptdec element is based on this. -  - Full list of API new in 1.14: - GStreamer core API new in 1.14 - GStreamer base library API new in 1.14 @@ -320,7 +319,6 @@ New RTP features and improvements streams in RED packets, and such streams need to be wrapped and unwrapped in order to use ULPFEC with chrome. -  - a few new buffer flags for FEC support: GST_BUFFER_FLAG_NON_DROPPABLE can be used to mark important buffers, e.g. to flag RTP packets carrying keyframes or codec setup data for @@ -333,11 +331,12 @@ New RTP features and improvements payloaders to make use of these. - rtpbin now has an option for increasing timestamp offsets gradually: - Instant large changes to the internal ts_offset may cause timestamps - to move backwards and also cause visible glitches in media playback. - The new "max-ts-offset-adjustment" and "max-ts-offset" properties - let the application control the rate to apply changes to ts_offset. - There have also been some EOS/BYE handling improvements in rtpbin. + Sudden large changes to the internal ts_offset may cause timestamps + to move backwards and may also cause visible glitches in media + playback. The new "max-ts-offset-adjustment" and "max-ts-offset" + properties let the application control the rate to apply changes to + ts_offset. There have also been some EOS/BYE handling improvements + in rtpbin. - rtpjitterbuffer has a new fast start mode: in many scenarios the jitter buffer will have to wait for the full configured latency @@ -395,10 +394,10 @@ New element features continue streaming if one of the inputs stops producing data. - jpegenc has gained a "snapshot" property just like pngenc to make it - easier to just output a single encoded frame. + easier to output just a single encoded frame. - jpegdec will now handle interlaced MJPEG streams properly and also - handle frames without an End of Image marker better. + handles frames without an End of Image marker better. - v4l2: There are now video encoders for VP8, VP9, MPEG4, and H263. The v4l2 video decoder handles dynamic resolution changes, and the @@ -414,7 +413,7 @@ New element features - rtspsrc now has support for RTSP protocol version 2.0 as well as ONVIF audio backchannels (see below for more details). It also - sports a new ["accept-certificate"] signal for "manually" checking a + sports a new "accept-certificate" signal for "manually" checking a TLS certificate for validity. It now also prints RTSP/SDP messages to the gstreamer debug log instead of stdout. @@ -432,8 +431,9 @@ New element features software like Adobe Premiere and FinalCut Pro to import the files while they are still being written to. This only works with constant framerate I-frame only streams, and for now only support for ProRes - video and raw audio is implemented but adding new codecs is just a - matter of defining appropriate maximum frame sizes. + video and raw audio is implemented. Adding support for additional + codecs is just a matter of defining appropriate maximum frame sizes + though. - qtmux also supports writing of svmi atoms with stereoscopic video information now. Trak timescales can be configured on a per-stream @@ -441,7 +441,7 @@ New element features new formats can be muxed: MPEG layer 1 and 2, AC3 and Opus, as well as PNG and VP9. -- souphttpsrc now does connection sharing by default, shares its +- souphttpsrc now does connection sharing by default: it shares its SoupSession with other elements in the same pipeline via a GstContext if possible (session-wide settings are all the defaults). This allows for connection reuse, cookie sharing, etc. Applications @@ -466,7 +466,7 @@ New element features will handle this just fine, but that's often more luck than by design. In any case, it's not right, so we disallow it now. -- matroskamux had Table of Content (TOC) support now (chapters etc.) +- matroskamux has Table of Content (TOC) support now (chapters etc.) and matroskademux TOC support has been improved. matroskademux has also seen seeking improvements searching for the right cluster and position. @@ -482,7 +482,6 @@ New element features passing through data (e.g. because target-timecode and end-timecode respectively have been reached). -  - h265parse and h265parse will try harder to make upstream output the same caps as downstream requires or prefers, thus avoiding unnecessary conversion. The parsers also expose chroma format and @@ -537,11 +536,18 @@ New element features - work continued on the msdk plugin for Intel's Media SDK which enables hardware-accelerated video encoding and decoding on Intel - graphics hardware on Windows or Linux. More tuning options were - added, and more pixel formats and video codecs are supported now. - The encoder now also handles force-key-unit events and can insert - frame-packing SEIs for side-by-side and top-bottom stereoscopic 3D - video. + graphics hardware on Windows or Linux. Added the video memory, + buffer pool, and context/session sharing support which helps to + improve the performance and resource utilization. Rendernode support + is in place which helps to avoid the constraint of having a running + graphics server as DRM-Master. Encoders are exposing a number rate + control algorithms now. More encoder tuning options like + trellis-quantiztion (h264), slice size control (h264), B-pyramid + prediction(h264), MB-level bitrate control, frame partitioning and + adaptive I/B frame insertion were added, and more pixel formats and + video codecs are supported now. The encoder now also handles + force-key-unit events and can insert frame-packing SEIs for + side-by-side and top-bottom stereoscopic 3D video. - dashdemux can now do adaptive trick play of certain types of DASH streams, meaning it can do fast-forward/fast-rewind of normal (non-I @@ -552,7 +558,6 @@ New element features supports webvtt subtitle streams now and has seen improvements when seeking in live streams. -  - kmssink has seen lots of fixes and improvements in this cycle, including: @@ -662,7 +667,7 @@ all scenarios, e.g. where the OpenGL driver does not properly support multiple sharing contexts in different threads; on Linux Nouveau is known to be broken in this respect, whilst NVIDIA's proprietary drivers and most other drivers generally work fine, and the experience with -Intel's driver seems to be fixed; some proprietary embedded Linux +Intel's driver seems to be mixed; some proprietary embedded Linux drivers don't work; macOS works). GstPhysMemoryAllocator interface moved from -bad to -base @@ -757,7 +762,6 @@ Tracing framework and debugging improvements log handler of course, this just provides this functionality as part of GStreamer. -  - 'fakevideosink is a null sink for video data that advertises video-specific metas ane behaves like a video sink. See above for more details. @@ -786,7 +790,7 @@ Tracing framework and debugging improvements reordering if delay > packet-spacing, so by setting "allow-reordering" to FALSE you guarantee that the packets are in order, while at the same time introducing delay/jitter to them. By - using the new "delay-distribution" property the use can control how + using the new "delay-distribution" property the user can control how the delay applied to delayed packets is distributed: This is either the uniform distribution (as before) or the normal distribution; in addition there is also the gamma distribution which simulates the @@ -810,9 +814,8 @@ Tools GStreamer RTSP server -- Initial support for [RTSP protocol version - 2.0][rtsp2-lightning-talk] was added, which is to the best of our - knowledge the first RTSP 2.0 implementation ever! +- Initial support for RTSP protocol version 2.0 was added, which is to + the best of our knowledge the first RTSP 2.0 implementation ever! - ONVIF audio backchannel support. This is an extension specified by ONVIF that allows RTSP clients (e.g. a control room operator) to @@ -824,7 +827,6 @@ GStreamer RTSP server ONVIF-specific subclasses GstRTSPOnvifServer and GstRTSPOnvifMediaFactory to enable this functionality. -  - The internal server streaming pipeline is now dynamically reconfigured on PLAY based on the transports needed. This means that the server no longer adds the pipeline plumbing for all possible @@ -852,22 +854,125 @@ GStreamer RTSP server GStreamer VAAPI -- this section will be filled in shortly {FIXME!} +- Improve DMABuf's usage, both upstream and dowstream, and + memory:DMABuf caps feature is also negotiated when the dmabuf-based + buffer cannot be mapped onto user-space. + +- VA initialization was fixed when it is used in headless systems. + +- VA display sharing, through GstContext, among the pipeline, has been + improved, adding the possibility to the application share its VA + display (external display) via gst.vaapi.app.Display context. + +- VA display cache was removed. + +- libva's log messages are now redirected into the GStreamer log + handler. + +- Decoders improved their upstream re-negotiation by avoiding to + re-instantiate the internal decoder if stream caps are compatible + with the previous one. + +- When downstream doesn't support GstVideoMeta and the decoded frames + don't have standard strides, they are copied onto system + memory-based buffers. + +- H.264 decoder has a low-latency property, for live streams which + doesn't conform the H.264 specification but still it is required to + push the frames to downstream as soon as possible. + +- As part of the Google Summer of Code 2017 the H.264 decoder drops + MVC and SVC frames when base-only property is enabled. + +- Added support for libva-2.0 (VA-API 1.0). + +- H.264 and H.265 encoders handle Region-Of-Interest metas by adding a + delta-qp for every rectangle within the frame specified by those + metas. + +- Encoders for H.264 and H.265 set the media profile by the downstream + caps. + +- H.264 encoder inserts an AU delimiter for each encoded frame when + aud property is enabled (it is only available for certain drivers + and platforms). + +- H.264 encoder supports for P and B hierarchical prediction modes. + +- All encoders handles a quality-level property, which is a number + from 1 to 8, where a lower number means higher quality, but slower + processing, and vice-versa. + +- VP8 and VP9 encoders support constant bit-rate mode (CBR). + +- VP8, VP9 and H.265 encoders support variable bit-rate mode (VBR). + +- Resurrected GstGLUploadTextureMeta handling for EGL backends. + +- H.265 encoder can configure its number of reference frames via the + refs property. + +- Add H.264 encoder mbbrc property, which controls the macro-block + bitrate as auto, on or off. + +- Add H.264 encoder temporal-levels property, to select the number of + temporal levels to be included. + +- Add to H.264 and H.265 encoders the properties qp-ip and qp-ib, to + handle the QP (quality parameter) difference between the I and P + frames, and the I and B frames, respectively. + +- vaapisink was demoted to marginal rank on Wayland because COGL + cannot display YUV surfaces. GStreamer Editing Services and NLE -- this section will be filled in shortly {FIXME!} +- Handle crossfade in complex scenarios by using the new + compositorpad::crossfade-ratio property + +- Add API allowing to stop using proxies for clips in the timeline + +- Allow management of none square pixel aspect ratios by allowing + application to deal with them in the way they want + +- Misc fixes around the timeline editing API GStreamer validate -- this section will be filled in shortly {FIXME!} +- Handle running scenarios on live pipelines (in the "content sense", + not the GStreamer one) + +- Implement RTSP support with a basic server based on gst-rtsp-server, + and add RTSP 1.0 and 2.0 integration tests + +- Implement a plugin that allows users to implement configurable + tests. It currently can check if a particular element is added a + configurable number of time in the pipeline. In the future that + plugin should allow us to implement specific tests of any kind in a + descriptive way + +- Add a verbosity configuration which behaves in a similare way as the + gst-launch-1.0 verbose flags allowing the informations to be + outputed on any running pipeline when enabling GstValidate. + +- Misc optimization in the launcher, making the tests run much faster. -GStreamer Python Bindings +GStreamer C# bindings -- this section will be filled in shortly {FIXME!} +- Port to the meson build system, autotools support has been removed + +- Use a new GlibSharp version, set as a meson subproject + +- Update wrapped API to GStreamer 1.14 + +- Removed the need for "glue" code + +- Provide a nuget + +- Misc API fixes Build and Dependencies @@ -1058,7 +1163,15 @@ the git 1.14 branch, which is a stable branch. 1.14.0 -1.14.0 is scheduled to be released in early March 2018. +1.14.0 was released on 19 March 2018. + +1.14.1 + +The first 1.14 bug-fix release (1.14.1) is scheduled to be released +around the end of March or beginning of April. + +This release only contains bugfixes and it should be safe to update from +1.14.0. Known Issues @@ -1075,7 +1188,7 @@ unstable development version leading up to the stable 1.16 release. The development of 1.15/1.16 will happen in the git master branch. The plan for the 1.16 development cycle is yet to be confirmed, but it -is expected that feature freeze will be around August 2017 followed by +is expected that feature freeze will be around August 2018 followed by several 1.15 pre-releases and the new 1.16 stable release in September. 1.16 will be backwards-compatible to the stable 1.14, 1.12, 1.10, 1.8, @@ -1084,6 +1197,7 @@ several 1.15 pre-releases and the new 1.16 stable release in September. ------------------------------------------------------------------------ _These release notes have been prepared by Tim-Philipp Müller with_ -_contributions from Sebastian Dröge._ +_contributions from Sebastian Dröge, Sreerenj Balachandran, Thibault +Saunier_ _and Víctor Manuel Jáquez Leal._ _License: CC BY-SA 4.0_ diff --git a/configure.ac b/configure.ac index 49129abfa0..7b5d131c52 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [13]) -m4_define([gst_vaapi_micro_version], [91]) +m4_define([gst_vaapi_minor_version], [14]) +m4_define([gst_vaapi_micro_version], [0]) m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1391]) +m4_define([gst_vaapi_lt_current], [1400]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1391]) +m4_define([gst_vaapi_lt_age], [1400]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.13.91]) -m4_define([gst_plugins_base_version], [1.13.91]) -m4_define([gst_plugins_bad_version], [1.13.91]) +m4_define([gst_version], [1.14.0]) +m4_define([gst_plugins_base_version], [1.14.0]) +m4_define([gst_plugins_bad_version], [1.14.0]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 3f471b985d..97abcc7cfc 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.14.0 + master + + 2018-03-19 + + + + 1.13.91 diff --git a/meson.build b/meson.build index 6074f5b8fa..49139316d4 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.13.91', + version : '1.14.0', meson_version : '>= 0.36.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 966d4d0476a966438812ece0bef8540371c4974c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 20 Mar 2018 10:49:10 +0000 Subject: [PATCH 3056/3781] Back to development --- NEWS | 1125 ++----------------------- RELEASE | 84 ++ configure.ac | 14 +- docs/plugins/inspect/plugin-vaapi.xml | 196 +++++ meson.build | 2 +- 5 files changed, 346 insertions(+), 1075 deletions(-) create mode 100644 RELEASE create mode 100644 docs/plugins/inspect/plugin-vaapi.xml diff --git a/NEWS b/NEWS index 64dcb91eaf..5366a0dfcd 100644 --- a/NEWS +++ b/NEWS @@ -1,21 +1,25 @@ -GSTREAMER 1.14 RELEASE NOTES +GSTREAMER 1.16 RELEASE NOTES -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! +GStreamer 1.16 has not been released yet. It is scheduled for release +around September 2018. -As always, this release is again packed with new features, bug fixes and -other improvements. +1.15.0.1 is the unstable development version that is being developed in +the git master branch and which will eventually result in 1.16. -GStreamer 1.14.0 was released on 19 March 2018. +The plan for the 1.16 development cycle is yet to be confirmed, but it +is expected that feature freeze will be around August 2017 followed by +several 1.15 pre-releases and the new 1.16 stable release in September. -See https://gstreamer.freedesktop.org/releases/1.14/ for the latest +1.16 will be backwards-compatible to the stable 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.16/ for the latest version of this document. -_Last updated: Monday 19 March 2018, 12:00 UTC (log)_ +_Last updated: Tuesday 20 March 2018, 01:30 UTC (log)_ Introduction @@ -30,1165 +34,154 @@ other improvements. Highlights -- WebRTC support: real-time audio/video streaming to and from web - browsers - -- Experimental support for the next-gen royalty-free AV1 video codec - -- Video4Linux: encoding support, stable element names and faster - device probing - -- Support for the Secure Reliable Transport (SRT) video streaming - protocol - -- RTP Forward Error Correction (FEC) support (ULPFEC) - -- RTSP 2.0 support in rtspsrc and gst-rtsp-server - -- ONVIF audio backchannel support in gst-rtsp-server and rtspsrc - -- playbin3 gapless playback and pre-buffering support - -- tee, our stream splitter/duplication element, now does allocation - query aggregation which is important for efficient data handling and - zero-copy - -- QuickTime muxer has a new prefill recording mode that allows file - import in Adobe Premiere and FinalCut Pro while the file is still - being written. - -- rtpjitterbuffer fast-start mode and timestamp offset adjustment - smoothing - -- souphttpsrc connection sharing, which allows for connection reuse, - cookie sharing, etc. - -- nvdec: new plugin for hardware-accelerated video decoding using the - NVIDIA NVDEC API - -- Adaptive DASH trick play support - -- ipcpipeline: new plugin that allows splitting a pipeline across - multiple processes - -- Major gobject-introspection annotation improvements for large parts - of the library API - -- GStreamer C# bindings have been revived and seen many updates and - fixes - -- The externally maintained GStreamer Rust bindings had many usability - improvements and cover most of the API now. Coinciding with the 1.14 - release, a new release with the 1.14 API additions is happening. +- this section will be completed in due course Major new features and changes -WebRTC support +Noteworthy new API -There is now basic support for WebRTC in GStreamer in form of a new -webrtcbin element and a webrtc support library. This allows you to build -applications that set up connections with and stream to and from other -WebRTC peers, whilst leveraging all of the usual GStreamer features such -as hardware-accelerated encoding and decoding, OpenGL integration, -zero-copy and embedded platform support. And it's easy to build and -integrate into your application too! - -WebRTC enables real-time communication of audio, video and data with web -browsers and native apps, and it is supported or about to be support by -recent versions of all major browsers and operating systems. - -GStreamer's new WebRTC implementation uses libnice for Interactive -Connectivity Establishment (ICE) to figure out the best way to -communicate with other peers, punch holes into firewalls, and traverse -NATs. - -The implementation is not complete, but all the basics are there, and -the code sticks fairly close to the PeerConnection API. Where -functionality is missing it should be fairly obvious where it needs to -go. - -For more details, background and example code, check out Nirbheek's blog -post _GStreamer has grown a WebRTC implementation_, as well as Matthew's -_GStreamer WebRTC_ talk from last year's GStreamer Conference in Prague. +- this section will be filled in in due course New Elements -- webrtcbin handles the transport aspects of webrtc connections (see - WebRTC section above for more details) +- this section will be filled in in due course -- New srtsink and srtsrc elements for the Secure Reliable Transport - (SRT) video streaming protocol, which aims to be easy to use whilst - striking a new balance between reliability and latency for low - latency video streaming use cases. More details about SRT and the - implementation in GStreamer in Olivier's blog post _SRT in - GStreamer_. +New element features and additions -- av1enc and av1dec elements providing experimental support for the - next-generation royalty free video AV1 codec, alongside Matroska - support for it. - -- hlssink2 is a rewrite of the existing hlssink element, but unlike - its predecessor hlssink2 takes elementary streams as input and - handles the muxing to MPEG-TS internally. It also leverages - splitmuxsink internally to do the splitting. This allows more - control over the chunk splitting and sizing process and relies less - on the co-operation of an upstream muxer. Different to the old - hlssink it also works with pre-encoded streams and does not require - close interaction with an upstream encoder element. - -- audiolatency is a new element for measuring audio latency end-to-end - and is useful to measure roundtrip latency including both the - GStreamer-internal latency as well as latency added by external - components or circuits. - -- 'fakevideosink is basically a null sink for video data and very - similar to fakesink, only that it will answer allocation queries and - will advertise support for various video-specific things such - GstVideoMeta, GstVideoCropMeta and GstVideoOverlayCompositionMeta - like a normal video sink would. This is useful for throughput - testing and testing the zero-copy path when creating a new pipeline. - -- ipcpipeline: new plugin that allows the splitting of a pipeline into - multiple processes. Usually a GStreamer pipeline runs in a single - process and parallelism is achieved by distributing workloads using - multiple threads. This means that all elements in the pipeline have - access to all the other elements' memory space however, including - that of any libraries used. For security reasons one might therefore - want to put sensitive parts of a pipeline such as DRM and decryption - handling into a separate process to isolate it from the rest of the - pipeline. This can now be achieved with the new ipcpipeline plugin. - Check out George's blog post _ipcpipeline: Splitting a GStreamer - pipeline into multiple processes_ or his lightning talk from last - year's GStreamer Conference in Prague for all the gory details. - -- proxysink and proxysrc are new elements to pass data from one - pipeline to another within the same process, very similar to the - existing inter elements, but not limited to raw audio and video - data. These new proxy elements are very special in how they work - under the hood, which makes them extremely powerful, but also - dangerous if not used with care. The reason for this is that it's - not just data that's passed from sink to src, but these elements - basically establish a two-way wormhole that passes through queries - and events in both directions, which means caps negotiation and - allocation query driven zero-copy can work through this wormhole. - There are scheduling considerations as well: proxysink forwards - everything into the proxysrc pipeline directly from the proxysink - streaming thread. There is a queue element inside proxysrc to - decouple the source thread from the sink thread, but that queue is - not unlimited, so it is entirely possible that the proxysink - pipeline thread gets stuck in the proxysrc pipeline, e.g. when that - pipeline is paused or stops consuming data for some other reason. - This means that one should always shut down down the proxysrc - pipeline before shutting down the proxysink pipeline, for example. - Or at least take care when shutting down pipelines. Usually this is - not a problem though, especially not in live pipelines. For more - information see Nirbheek's blog post _Decoupling GStreamer - Pipelines_, and also check out out the new ipcpipeline plugin for - sending data from one process to another process (see above). - -- lcms is a new LCMS-based ICC color profile correction element - -- openmptdec is a new OpenMPT-based decoder for module music formats, - such as S3M, MOD, XM, IT. It is built on top of a new - GstNonstreamAudioDecoder base class which aims to unify handling of - files which do not operate a streaming model. The wildmidi plugin - has also been revived and is also implemented on top of this new - base class. - -- The curl plugin has gained a new curlhttpsrc element, which is - useful for testing HTTP protocol version 2.0 amongst other things. - -- The msdk plugin has gained a MPEG-2 video decoder(msdkmpeg2dec), VP8 - decoder(msdkvp8dec) and a VC1/WMV decoder(msdkvc1dec) - -Noteworthy new API - -- GstPromise provides future/promise-like functionality. This is used - in the GStreamer WebRTC implementation. - -- GstReferenceTimestampMeta is a new meta that allows you to attach - additional reference timestamps to a buffer. These timestamps don't - have to relate to the pipeline clock in any way. Examples of this - could be an NTP timestamp when the media was captured, a frame - counter on the capture side or the (local) UNIX timestamp when the - media was captured. The decklink elements make use of this. - -- GstVideoRegionOfInterestMeta: it's now possible to attach generic - free-form element-specific parameters to a region of interest meta, - for example to tell a downstream encoder to use certain codec - parameters for a certain region. - -- gst_bus_get_pollfd can be used to obtain a file descriptor for the - bus that can be poll()-ed on for new messages. This is useful for - integration with non-GLib event loops. - -- gst_get_main_executable_path() can be used by wrapper plugins that - need to find things in the directory where the application - executable is located. In the same vein, - GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_RELATIVE_TO_EXE can be used to - signal that plugin dependency paths are relative to the main - executable. - -- pad templates can be told about the GType of the pad subclass of the - pad via newly-added GstPadTemplate API API or the - gst_element_class_add_static_pad_template_with_gtype() convenience - function. gst-inspect-1.0 will use this information to print pad - properties. - -- new convenience functions to iterate over element pads without using - the GstIterator API: gst_element_foreach_pad(), - gst_element_foreach_src_pad(), and gst_element_foreach_sink_pad(). - -- GstBaseSrc and appsrc have gained support for buffer lists: - GstBaseSrc subclasses can use gst_base_src_submit_buffer_list(), and - applications can use gst_app_src_push_buffer_list() to push a buffer - list into appsrc. - -- The GstHarness unit test harness has a couple of new convenience - functions to retrieve all pending data in the harness in form of a - single chunk of memory. - -- GstAudioStreamAlign is a new helper object for audio elements that - handles discontinuity detection and sample alignment. It will align - samples after the previous buffer's samples, but keep track of the - divergence between buffer timestamps and sample position (jitter). - If it exceeds a configurable threshold the alignment will be reset. - This simply factors out code that was duplicated in a number of - elements into a common helper API. - -- The GstVideoEncoder base class implements Quality of Service (QoS) - now. This is disabled by default and must be opted in by setting the - "qos" property, which will make the base class gather statistics - about the real-time performance of the pipeline from downstream - elements (usually sinks that sync the pipeline clock). Subclasses - can then make use of this by checking whether input frames are late - already using gst_video_encoder_get_max_encode_time() If late, they - can just drop them and skip encoding in the hope that the pipeline - will catch up. - -- The GstVideoOverlay interface gained a few helper functions for - installing and handling a "render-rectangle" property on elements - that implement this interface, so that this functionality can also - be used from the command line for testing and debugging purposes. - The property wasn't added to the interface itself as that would - require all implementors to provide it which would not be - backwards-compatible. - -- A new base class, GstNonstreamAudioDecoder for non-stream audio - decoders was added to gst-plugins-bad. This base-class is meant to - be used for audio decoders that require the whole stream to be - loaded first before decoding can start. Examples of this are module - formats (MOD/S3M/XM/IT/etc), C64 SID tunes, video console music - files (GYM/VGM/etc), MIDI files and others. The new openmptdec - element is based on this. - -- Full list of API new in 1.14: -- GStreamer core API new in 1.14 -- GStreamer base library API new in 1.14 -- gst-plugins-base libraries API new in 1.14 -- gst-plugins-bad: no list, mostly GstWebRTC library and new - non-stream audio decoder base class. - -New RTP features and improvements - -- rtpulpfecenc and rtpulpfecdec are new elements that implement - Generic Forward Error Correction (FEC) using Uneven Level Protection - (ULP) as described in RFC 5109. This can be used to protect against - certain types of (non-bursty) packet loss, and important packets - such as those containing codec configuration data or key frames can - be protected with higher redundancy. Equally, packets that are not - particularly important can be given low priority or not be protected - at all. If packets are lost, the receiver can then hopefully restore - the lost packet(s) from the surrounding packets which were received. - This is an alternative to, or rather complementary to, dealing with - packet loss using _retransmission (rtx)_. GStreamer has had - retransmission support for a long time, but Forward Error Correction - allows for different trade-offs: The advantage of Forward Error - Correction is that it doesn't add latency, whereas retransmission - requires at least one more roundtrip to request and hopefully - receive lost packets; Forward Error Correction increases the - required bandwidth however, even in situations where there is no - packet loss at all, so one will typically want to fine-tune the - overhead and mechanisms used based on the characteristics of the - link at the time. - -- New _Redundant Audio Data (RED)_ encoders and decoders for RTP as - per RFC 2198 are also provided (rtpredenc and rtpreddec), mostly for - chrome webrtc compatibility, as chrome will wrap ULPFEC-protected - streams in RED packets, and such streams need to be wrapped and - unwrapped in order to use ULPFEC with chrome. - -- a few new buffer flags for FEC support: - GST_BUFFER_FLAG_NON_DROPPABLE can be used to mark important buffers, - e.g. to flag RTP packets carrying keyframes or codec setup data for - RTP Forward Error Correction purposes, or to prevent still video - frames from being dropped by elements due to QoS. There already is a - GST_BUFFER_FLAG_DROPPABLE. GST_RTP_BUFFER_FLAG_REDUNDANT is used to - signal internally that a packet represents a redundant RTP packet - and used in rtpstorage to hold back the packet and use it only for - recovery from packet loss. Further work is still needed in - payloaders to make use of these. - -- rtpbin now has an option for increasing timestamp offsets gradually: - Sudden large changes to the internal ts_offset may cause timestamps - to move backwards and may also cause visible glitches in media - playback. The new "max-ts-offset-adjustment" and "max-ts-offset" - properties let the application control the rate to apply changes to - ts_offset. There have also been some EOS/BYE handling improvements - in rtpbin. - -- rtpjitterbuffer has a new fast start mode: in many scenarios the - jitter buffer will have to wait for the full configured latency - before it can start outputting packets. The reason for that is that - it often can't know what the sequence number of the first expected - RTP packet is, so it can't know whether a packet earlier than the - earliest packet received will still arrive in future. This behaviour - can now be bypassed by setting the "faststart-min-packets" property - to the number of consecutive packets needed to start, and the jitter - buffer will start output packets as soon as it has N consecutive - packets queued internally. This is particularly useful to get a - first video frame decoded and rendered as quickly as possible. - -- rtpL8pay and rtpL8depay provide RTP payloading and depayloading for - 8-bit raw audio - -New element features - -- playbin3 has gained support or gapless playback via the - "about-to-finish" signal where users can set the uri for the next - item to play. For non-live streams this will be emitted as soon as - the first uri has finished downloading, so with sufficiently large - buffers it is now possible to pre-buffer the next item well ahead of - time (unlike playbin where there would not be a lot of time between - "about-to-finish" emission and the end of the stream). If the stream - format of the next stream is the same as that of the previous - stream, the data will be concatenated via the concat element. - Whether this will result in true gaplessness depends on the - container format and codecs used, there might still be codec-related - gaps between streams with some codecs. - -- tee now does allocation query aggregation, which is important for - zero-copy and efficient data handling, especially for video. Those - who want to drop allocation queries on purpose can use the identity - element's new "drop-allocation" property for that instead. - -- audioconvert now has a "mix-matrix" property, which obsoletes the - audiomixmatrix element. There's also mix matrix support in the audio - conversion and channel mixing API. - -- x264enc: new "insert-vui" property to disable VUI (Video Usability - Information) parameter insertion into the stream, which allows - creation of streams that are compatible with certain legacy hardware - decoders that will refuse to decode in certain combinations of - resolution and VUI parameters; the max. allowed number of B-frames - was also increased from 4 to 16. - -- dvdlpcmdec: has gained support for Blu-Ray audio LPCM. - -- appsrc has gained support for buffer lists (see above) and also seen - some other performance improvements. - -- flvmux has been ported to the GstAggregator base class which means - it can work in defined-latency mode with live input sources and - continue streaming if one of the inputs stops producing data. - -- jpegenc has gained a "snapshot" property just like pngenc to make it - easier to output just a single encoded frame. - -- jpegdec will now handle interlaced MJPEG streams properly and also - handles frames without an End of Image marker better. - -- v4l2: There are now video encoders for VP8, VP9, MPEG4, and H263. - The v4l2 video decoder handles dynamic resolution changes, and the - video4linux device provider now does much faster device probing. The - plugin also no longer uses the libv4l2 library by default, as it has - prevented a lot of interesting use cases like CREATE_BUFS, DMABuf, - usage of TRY_FMT. As the libv4l2 library is totally inactive and not - really maintained, we decided to disable it. This might affect a - small number of cheap/old webcams with custom vendor formats for - which we do not provide conversion in GStreamer. It is possible to - re-enable support for libv4l2 at run-time however, by setting the - environment variable GST_V4L2_USE_LIBV4L2=1. - -- rtspsrc now has support for RTSP protocol version 2.0 as well as - ONVIF audio backchannels (see below for more details). It also - sports a new "accept-certificate" signal for "manually" checking a - TLS certificate for validity. It now also prints RTSP/SDP messages - to the gstreamer debug log instead of stdout. - -- shout2send now uses non-blocking I/O and has a configurable network - operations timeout. - -- splitmuxsink has gained a "split-now" action signal and new - "alignment-threshold" and "use-robust-muxing" properties. If robust - muxing is enabled, it will check and set the muxer's reserved space - properties if present. This is primarily for use with mp4mux's - robust muxing mode. - -- qtmux has a new _prefill recording mode_ which sets up a moov header - with the correct sample positions beforehand, which then allows - software like Adobe Premiere and FinalCut Pro to import the files - while they are still being written to. This only works with constant - framerate I-frame only streams, and for now only support for ProRes - video and raw audio is implemented. Adding support for additional - codecs is just a matter of defining appropriate maximum frame sizes - though. - -- qtmux also supports writing of svmi atoms with stereoscopic video - information now. Trak timescales can be configured on a per-stream - basis using the "trak-timescale" property on the sink pads. Various - new formats can be muxed: MPEG layer 1 and 2, AC3 and Opus, as well - as PNG and VP9. - -- souphttpsrc now does connection sharing by default: it shares its - SoupSession with other elements in the same pipeline via a - GstContext if possible (session-wide settings are all the defaults). - This allows for connection reuse, cookie sharing, etc. Applications - can also force a context to use. In other news, HTTP headers - received from the server are posted as element messages on the bus - now for easier diagnostics, and it's also possible now to use other - types of proxy servers such as SOCKS4 or SOCKS5 proxies, support for - which is implemented directly in gio. Before only HTTP proxies were - allowed. - -- qtmux, mp4mux and matroskamux will now refuse caps changes of input - streams at runtime. This isn't really supported with these - containers (or would have to be implemented differently with a - considerable effort) and doesn't produce valid and spec-compliant - files that will play everywhere. So if you can't guarantee that the - input caps won't change, use a container format that does support on - the fly caps changes for a stream such as MPEG-TS or use - splitmuxsink which can start a new file when the caps change. What - would happen before is that e.g. rtph264depay or rtph265depay would - simply send new SPS/PPS inband even for AVC format, which would then - get muxed into the container as if nothing changed. Some decoders - will handle this just fine, but that's often more luck than by - design. In any case, it's not right, so we disallow it now. - -- matroskamux has Table of Content (TOC) support now (chapters etc.) - and matroskademux TOC support has been improved. matroskademux has - also seen seeking improvements searching for the right cluster and - position. - -- videocrop now uses GstVideoCropMeta if downstream supports it, which - means cropping can be handled more efficiently without any copying. - -- compositor now has support for _crossfade blending_, which can be - used via the new "crossfade-ratio" property on the sink pads. - -- The avwait element has a new "end-timecode" property and posts - "avwait-status" element messages now whenever avwait starts or stops - passing through data (e.g. because target-timecode and end-timecode - respectively have been reached). - -- h265parse and h265parse will try harder to make upstream output the - same caps as downstream requires or prefers, thus avoiding - unnecessary conversion. The parsers also expose chroma format and - bit depth in the caps now. - -- The dtls elements now longer rely on or require the application to - run a GLib main loop that iterates the default main context - (GStreamer plugins should never rely on the application running a - GLib main loop). - -- openh264enc allows to change the encoding bitrate dynamically at - runtime now - -- nvdec is a new plugin for hardware-accelerated video decoding using - the NVIDIA NVDEC API (which replaces the old VDPAU API which is no - longer supported by NVIDIA) - -- The NVIDIA NVENC hardware-accelerated video encoders now support - dynamic bitrate and preset reconfiguration and support the I420 - 4:2:0 video format. It's also possible to configure the gop size via - the new "gop-size" property. - -- The MPEG-TS muxer and demuxer (tsmux, tsdemux) now have support for - JPEG2000 - -- openjpegdec and jpeg2000parse support 2-component images now (gray - with alpha), and jpeg2000parse has gained limited support for - conversion between JPEG2000 stream-formats. (JP2, J2C, JPC) and also - extracts more details such as colorimetry, interlace-mode, - field-order, multiview-mode and chroma siting. - -- The decklink plugin for Blackmagic capture and playback cards have - seen numerous improvements: - -- decklinkaudiosrc and decklinkvideosrc now put hardware reference - timestamp on buffers in form of GstReferenceTimestampMetas. - This can be useful to know on multi-channel cards which frames from - different channels were captured at the same time. - -- decklinkvideosink has gained support for Decklink hardware keying - with two new properties ("keyer-mode" and "keyer-level") to control - the built-in hardware keyer of Decklink cards. - -- decklinkaudiosink has been re-implemented around GstBaseSink instead - of the GstAudioBaseSink base class, since the Decklink APIs don't - fit very well with the GstAudioBaseSink APIs, which used to cause - various problems due to inaccuracies in the clock calculations. - Problems were audio drop-outs and A/V sync going wrong after - pausing/seeking. - -- support for more than 16 devices, without any artificial limit - -- work continued on the msdk plugin for Intel's Media SDK which - enables hardware-accelerated video encoding and decoding on Intel - graphics hardware on Windows or Linux. Added the video memory, - buffer pool, and context/session sharing support which helps to - improve the performance and resource utilization. Rendernode support - is in place which helps to avoid the constraint of having a running - graphics server as DRM-Master. Encoders are exposing a number rate - control algorithms now. More encoder tuning options like - trellis-quantiztion (h264), slice size control (h264), B-pyramid - prediction(h264), MB-level bitrate control, frame partitioning and - adaptive I/B frame insertion were added, and more pixel formats and - video codecs are supported now. The encoder now also handles - force-key-unit events and can insert frame-packing SEIs for - side-by-side and top-bottom stereoscopic 3D video. - -- dashdemux can now do adaptive trick play of certain types of DASH - streams, meaning it can do fast-forward/fast-rewind of normal (non-I - frame only) streams even at high speeds without saturating network - bandwidth or exceeding decoder capabilities. It will keep statistics - and skip keyframes or fragments as needed. See Sebastian's blog post - _DASH trick-mode playback in GStreamer_ for more details. It also - supports webvtt subtitle streams now and has seen improvements when - seeking in live streams. - -- kmssink has seen lots of fixes and improvements in this cycle, - including: - -- Raspberry Pi (vc4) and Xilinx DRM driver support - -- new "render-rectangle" property that can be used from the command - line as well as "display-width" and "display-height", and - "can-scale" properties - -- GstVideoCropMeta support +- this section will be filled in in due course Plugin and library moves -MPEG-1 audio (mp1, mp2, mp3) decoders and encoders moved to -good - -Following the expiration of the last remaining mp3 patents in most -jurisdictions, and the termination of the mp3 licensing program, as well -as the decision by certain distros to officially start shipping full mp3 -decoding and encoding support, these plugins should now no longer be -problematic for most distributors and have therefore been moved from --ugly and -bad to gst-plugins-good. Distributors can still disable these -plugins if desired. - -In particular these are: - -- mpg123audiodec: an mp1/mp2/mp3 audio decoder using libmpg123 -- lamemp3enc: an mp3 encoder using LAME -- twolamemp2enc: an mp2 encoder using TwoLAME - -GstAggregator moved from -bad to core - -GstAggregator has been moved from gst-plugins-bad to the base library in -GStreamer and is now stable API. - -GstAggregator is a new base class for mixers and muxers that have to -handle multiple input pads and aggregate streams into one output stream. -It improves upon the existing GstCollectPads API in that it is a proper -base class which was also designed with live streaming in mind. -GstAggregator subclasses will operate in a mode with defined latency if -any of the inputs are live streams. This ensures that the pipeline won't -stall if any of the inputs stop producing data, and that the configured -maximum latency is never exceeded. - -GstAudioAggregator, audiomixer and audiointerleave moved from -bad to -base - -GstAudioAggregator is a new base class for raw audio mixers and muxers -and is based on GstAggregator (see above). It provides defined-latency -mixing of raw audio inputs and ensures that the pipeline won't stall -even if one of the input streams stops producing data. - -As part of the move to stabilise the API there were some last-minute API -changes and clean-ups, but those should mostly affect internal elements. - -It is used by the audiomixer element, which is a replacement for -'adder', which did not handle live inputs very well and did not align -input streams according to running time. audiomixer should behave much -better in that respect and generally behave as one would expected in -most scenarios. - -Similarly, audiointerleave replaces the 'interleave' element which did -not handle live inputs or non-aligned inputs very robustly. - -GstAudioAggregator and its subclases have gained support for input -format conversion, which does not include sample rate conversion though -as that would add additional latency. Furthermore, GAP events are now -handled correctly. - -We hope to move the video equivalents (GstVideoAggregator and -compositor) to -base in the next cycle, i.e. for 1.16. - -GStreamer OpenGL integration library and plugin moved from -bad to -base - -The GStreamer OpenGL integration library and opengl plugin have moved -from gst-plugins-bad to -base and are now part of the stable API canon. -Not all OpenGL elements have been moved; a few had to be left behind in -gst-plugins-bad in the new openglmixers plugin, because they depend on -the GstVideoAggregator base class which we were not able to move in this -cycle. We hope to reunite these elements with the rest of their family -for 1.16 though. - -This is quite a milestone, thanks to everyone who worked to make this -happen! - -Qt QML and GTK plugins moved from -bad to -good - -The Qt QML-based qmlgl plugin has moved to -good and provides a -qmlglsink video sink element as well as a qmlglsrc element. qmlglsink -renders video into a QQuickItem, and qmlglsrc captures a window from a -QML view and feeds it as video into a pipeline for further processing. -Both elements leverage GStreamer's OpenGL integration. In addition to -the move to -good the following features were added: - -- A proxy object is now used for thread-safe access to the QML widget - which prevents crashes in corner case scenarios: QML can destroy the - video widget at any time, so without this we might be left with a - dangling pointer. - -- EGL is now supported with the X11 backend, which works e.g. on - Freescale imx6 - -The GTK+ plugin has also moved from -bad to -good. It includes gtksink -and gtkglsink which both render video into a GtkWidget. gtksink uses -Cairo for rendering the video, which will work everywhere in all -scenarios but involves an extra memory copy, whereas gtkglsink fully -leverages GStreamer's OpenGL integration, but might not work properly in -all scenarios, e.g. where the OpenGL driver does not properly support -multiple sharing contexts in different threads; on Linux Nouveau is -known to be broken in this respect, whilst NVIDIA's proprietary drivers -and most other drivers generally work fine, and the experience with -Intel's driver seems to be mixed; some proprietary embedded Linux -drivers don't work; macOS works). - -GstPhysMemoryAllocator interface moved from -bad to -base - -GstPhysMemoryAllocator is a marker interface for allocators with -physical address backed memory. +- this section will be filled in in due course Plugin removals -- the sunaudio plugin was removed, since it couldn't ever have been - built or used with GStreamer 1.0, but no one even noticed in all - these years. +- this section will be filled in in due course -- the schroedinger-based Dirac encoder/decoder plugin has been - removed, as there is no longer any upstream or anyone else - maintaining it. Seeing that it's quite a fringe codec it seemed best - to simply remove it. -API removals +Miscellaneous API additions -- some MPEG video parser API in the API unstable codecutils library in - gst-plugins-bad was removed after having been deprecated for 5 - years. +- this section will be filled in in due course + +GstPlayer + +- this section will be filled in in due course Miscellaneous changes -- The video support library has gained support for a few new pixel - formats: -- NV16_10LE32: 10-bit variant of NV16, packed into 32bit words (plus 2 - bits padding) -- NV12_10LE32: 10-bit variant of NV12, packed into 32bit words (plus 2 - bits padding) -- GRAY10_LE32: 10-bit grayscale, packed in 32bit words (plus 2 bits - padding) - -- decodebin, playbin and GstDiscoverer have seen stability - improvements in corner cases such as shutdown while still starting - up or shutdown in error cases (hat tip to the oss-fuzz project). - -- floating reference handling was inconsistent and has been cleaned up - across the board, including annotations. This solves various - long-standing memory leaks in language bindings, which e.g. often - caused elements and pads to be leaked. - -- major gobject-introspection annotation improvements for large parts - of the library API, including nullability of return types and - function parameters, correct types (e.g. strings vs. filenames), - ownership transfer, array length parameters, etc. This allows to use - bigger parts of the GStreamer API to be safely used from dynamic - language bindings (e.g. Python, Javascript) and allows static - bindings (e.g. C#, Rust, Vala) to autogenerate more API bindings - without manual intervention. +- this section will be filled in in due course OpenGL integration -- The GStreamer OpenGL integration library has moved to - gst-plugins-base and is now part of our stable API. - -- new MESA3D GBM BACKEND. On devices with working libdrm support, it - is possible to use Mesa3D's GBM library to set up an EGL context - directly on top of KMS. This makes it possible to use the GStreamer - OpenGL elements without a windowing system if a libdrm- and - Mesa3D-supported GPU is present. - -- Prefer wayland display over X11: As most Wayland compositors support - XWayland, the X11 backend would get selected. - -- gldownload can export dmabufs now, and glupload will advertise - dmabuf as caps feature. +- this section will be filled in in due course Tracing framework and debugging improvements -- NEW MEMORY RINGBUFFER BASED DEBUG LOGGER, useful for long-running - applications or to retrieve diagnostics when encountering an error. - The GStreamer debug logging system provides in-depth debug logging - about what is going on inside a pipeline. When enabled, debug logs - are usually written into a file, printed to the terminal, or handed - off to a log handler installed by the application. However, at - higher debug levels the volume of debug output quickly becomes - unmanageable, which poses a problem in disk-space or bandwidth - restricted environments or with long-running pipelines where a - problem might only manifest itself after multiple days. In those - situations, developers are usually only interested in the most - recent debug log output. The new in-memory ringbuffer logger makes - this easy: just installed it with gst_debug_add_ring_buffer_logger() - and retrieve logs with gst_debug_ring_buffer_logger_get_logs() when - needed. It is possible to limit the memory usage per thread and set - a timeout to determine how long messages are kept around. It was - always possible to implement this in the application with a custom - log handler of course, this just provides this functionality as part - of GStreamer. - -- 'fakevideosink is a null sink for video data that advertises - video-specific metas ane behaves like a video sink. See above for - more details. - -- gst_util_dump_buffer() prints the content of a buffer to stdout. - -- gst_pad_link_get_name() and gst_state_change_get_name() print pad - link return values and state change transition values as strings. - -- The LATENCY TRACER has seen a few improvements: trace records now - contain timestamps which is useful to plot things over time, and - downstream synchronisation time is now excluded from the measured - values. - -- Miniobject refcount tracing and logging was not entirley - thread-safe, there were duplicates or missing entries at times. This - has now been made reliable. - -- The netsim element, which can be used to simulate network jitter, - packet reordering and packet loss, received new features and - improvements: it can now also simulate network congestion using a - token bucket algorithm. This can be enabled via the "max-kbps" - property. Packet reordering can be disabled now via the - "allow-reordering" property: Reordering of packets is not very - common in networks, and the delay functions will always introduce - reordering if delay > packet-spacing, so by setting - "allow-reordering" to FALSE you guarantee that the packets are in - order, while at the same time introducing delay/jitter to them. By - using the new "delay-distribution" property the user can control how - the delay applied to delayed packets is distributed: This is either - the uniform distribution (as before) or the normal distribution; in - addition there is also the gamma distribution which simulates the - delay on wifi networks better. +- this section will be filled in in due course Tools -- gst-inspect-1.0 now prints pad properties for elements that have pad - subclasses with special properties, such as compositor or - audiomixer. This only works for elements that use the newly-added - GstPadTemplate API API or the - gst_element_class_add_static_pad_template_with_gtype() convenience - function to tell GStreamer about the special pad subclass. - -- gst-launch-1.0 now generates a gstreamer pipeline diagram (.dot - file) whenever SIGHUP is sent to it on Linux/*nix systems. - -- gst-discoverer-1.0 can now analyse live streams such as rtsp:// URIs +- this section will be filled in in due course GStreamer RTSP server -- Initial support for RTSP protocol version 2.0 was added, which is to - the best of our knowledge the first RTSP 2.0 implementation ever! - -- ONVIF audio backchannel support. This is an extension specified by - ONVIF that allows RTSP clients (e.g. a control room operator) to - send audio back to the RTSP server (e.g. an IP camera). - Theoretically this could have been done also by using the RECORD - method of the RTSP protocol, but ONVIF chose not to do that, so the - backchannel is set up alongside the other streams. Format - negotiation needs to be done out of band, if needed. Use the new - ONVIF-specific subclasses GstRTSPOnvifServer and - GstRTSPOnvifMediaFactory to enable this functionality. - -- The internal server streaming pipeline is now dynamically - reconfigured on PLAY based on the transports needed. This means that - the server no longer adds the pipeline plumbing for all possible - transports from the start, but only if needed as needed. This - improves performance and memory footprint. - -- rtspclientsink has gained an "accept-certificate" signal for - manually checking a TLS certificate for validity. - -- Fix keep-alive/timeout issue for certain clients using TCP - interleave as transport who don't do keep-alive via some other - method such as periodic RTSP OPTION requests. We now put netaddress - metas on the packets from the TCP interleaved stream, so can map - RTCP packets to the right stream in the server and can handle them - properly. - -- Language bindings improvements: in general there were quite a few - improvements in the gobject-introspection annotations, but we also - extended the permissions API which was not usable from bindings - before. - -- Fix corner case issue where the wrong mount point was found when - there were multiple mount points with a common prefix. +- this section will be filled in in due course GStreamer VAAPI -- Improve DMABuf's usage, both upstream and dowstream, and - memory:DMABuf caps feature is also negotiated when the dmabuf-based - buffer cannot be mapped onto user-space. - -- VA initialization was fixed when it is used in headless systems. - -- VA display sharing, through GstContext, among the pipeline, has been - improved, adding the possibility to the application share its VA - display (external display) via gst.vaapi.app.Display context. - -- VA display cache was removed. - -- libva's log messages are now redirected into the GStreamer log - handler. - -- Decoders improved their upstream re-negotiation by avoiding to - re-instantiate the internal decoder if stream caps are compatible - with the previous one. - -- When downstream doesn't support GstVideoMeta and the decoded frames - don't have standard strides, they are copied onto system - memory-based buffers. - -- H.264 decoder has a low-latency property, for live streams which - doesn't conform the H.264 specification but still it is required to - push the frames to downstream as soon as possible. - -- As part of the Google Summer of Code 2017 the H.264 decoder drops - MVC and SVC frames when base-only property is enabled. - -- Added support for libva-2.0 (VA-API 1.0). - -- H.264 and H.265 encoders handle Region-Of-Interest metas by adding a - delta-qp for every rectangle within the frame specified by those - metas. - -- Encoders for H.264 and H.265 set the media profile by the downstream - caps. - -- H.264 encoder inserts an AU delimiter for each encoded frame when - aud property is enabled (it is only available for certain drivers - and platforms). - -- H.264 encoder supports for P and B hierarchical prediction modes. - -- All encoders handles a quality-level property, which is a number - from 1 to 8, where a lower number means higher quality, but slower - processing, and vice-versa. - -- VP8 and VP9 encoders support constant bit-rate mode (CBR). - -- VP8, VP9 and H.265 encoders support variable bit-rate mode (VBR). - -- Resurrected GstGLUploadTextureMeta handling for EGL backends. - -- H.265 encoder can configure its number of reference frames via the - refs property. - -- Add H.264 encoder mbbrc property, which controls the macro-block - bitrate as auto, on or off. - -- Add H.264 encoder temporal-levels property, to select the number of - temporal levels to be included. - -- Add to H.264 and H.265 encoders the properties qp-ip and qp-ib, to - handle the QP (quality parameter) difference between the I and P - frames, and the I and B frames, respectively. - -- vaapisink was demoted to marginal rank on Wayland because COGL - cannot display YUV surfaces. +- this section will be filled in in due course GStreamer Editing Services and NLE -- Handle crossfade in complex scenarios by using the new - compositorpad::crossfade-ratio property - -- Add API allowing to stop using proxies for clips in the timeline - -- Allow management of none square pixel aspect ratios by allowing - application to deal with them in the way they want - -- Misc fixes around the timeline editing API +- this section will be filled in in due course GStreamer validate -- Handle running scenarios on live pipelines (in the "content sense", - not the GStreamer one) - -- Implement RTSP support with a basic server based on gst-rtsp-server, - and add RTSP 1.0 and 2.0 integration tests - -- Implement a plugin that allows users to implement configurable - tests. It currently can check if a particular element is added a - configurable number of time in the pipeline. In the future that - plugin should allow us to implement specific tests of any kind in a - descriptive way - -- Add a verbosity configuration which behaves in a similare way as the - gst-launch-1.0 verbose flags allowing the informations to be - outputed on any running pipeline when enabling GstValidate. - -- Misc optimization in the launcher, making the tests run much faster. +- this section will be filled in in due course -GStreamer C# bindings +GStreamer Python Bindings -- Port to the meson build system, autotools support has been removed - -- Use a new GlibSharp version, set as a meson subproject - -- Update wrapped API to GStreamer 1.14 - -- Removed the need for "glue" code - -- Provide a nuget - -- Misc API fixes +- this section will be filled in in due course Build and Dependencies -- the new WebRTC support in gst-plugins-bad depends on the GStreamer - elements that ship as part of libnice, and libnice version 1.1.14 is - required. Also the dtls and srtp plugins. - -- gst-plugins-bad no longer depends on the libschroedinger Dirac codec - library. - -- The srtp plugin can now also be built against libsrtp2. - -- some plugins and libraries have moved between modules, see the - _Plugin and_ _library moves_ section above, and their respective - dependencies have moved with them of course, e.g. the GStreamer - OpenGL integration support library and plugin is now in - gst-plugins-base, and mpg123, LAME and twoLAME based audio decoder - and encoder plugins are now in gst-plugins-good. - -- Unify static and dynamic plugin interface and remove plugin specific - static build option: Static and dynamic plugins now have the same - interface. The standard --enable-static/--enable-shared toggle is - sufficient. This allows building static and shared plugins from the - same object files, instead of having to build everything twice. - -- The default plugin entry point has changed. This will only affect - plugins that are recompiled against new GStreamer headers. Binary - plugins using the old entry point will continue to work. However, - plugins that are recompiled must have matching plugin names in - GST_PLUGIN_DEFINE and filenames, as the plugin entry point for - shared plugins is now deduced from the plugin filename. This means - you can no longer have a plugin called foo living in a file called - libfoobar.so or such, the plugin filename needs to match. This might - cause problems with some external third party plugin modules when - they get rebuilt against GStreamer 1.14. - - -Note to packagers and distributors - -A number of libraries, APIs and plugins moved between modules and/or -libraries in different modules between version 1.12.x and 1.14.x, see -the _Plugin and_ _library moves_ section above. Some APIs have seen -minor ABI changes in the course of moving them into the stable APIs -section. - -This means that you should try to ensure that all major GStreamer -modules are synced to the same major version (1.12 or 1.13/1.14) and can -only be upgraded in lockstep, so that your users never end up with a mix -of major versions on their system at the same time, as this may cause -breakages. - -Also, plugins compiled against >= 1.14 headers will not load with -GStreamer <= 1.12 owing to a new plugin entry point (but plugin binaries -built against older GStreamer versions will continue to load with newer -versions of GStreamer of course). - -There is also a small structure size related ABI breakage introduced in -the gst-plugins-bad codecparsers library between version 1.13.90 and -1.13.91. This should "only" affect gstreamer-vaapi, so anyone who ships -the release candidates is advised to upgrade those two modules at the -same time. +- this section will be filled in in due course Platform-specific improvements Android -- ahcsrc (Android camera source) does autofocus now +- this section will be filled in in due course macOS and iOS -- this section will be filled in shortly {FIXME!} +- this section will be filled in in due course Windows -- The GStreamer wasapi plugin was rewritten and should not only be - usable now, but in top shape and suitable for low-latency use cases. - The Windows Audio Session API (WASAPI) is Microsoft's most modern - method for talking with audio devices, and now that the wasapi - plugin is up to scratch it is preferred over the directsound plugin. - The ranks of the wasapisink and wasapisrc elements have been updated - to reflect this. Further improvements include: - -- support for more than 2 channels - -- a new "low-latency" property to enable low-latency operation (which - should always be safe to enable) - -- support for the AudioClient3 API which is only available on Windows - 10: in wasapisink this will be used automatically if available; in - wasapisrc it will have to be enabled explicitly via the - "use-audioclient3" property, as capturing audio with low latency and - without glitches seems to require setting the realtime priority of - the entire pipeline to "critical", which cannot be done from inside - the element, but has to be done in the application. - -- set realtime thread priority to avoid glitches - -- allow opening devices in exclusive mode, which provides much lower - latency compared to shared mode where WASAPI's engine period is - 10ms. This can be activated via the "exclusive" property. - -- There are now GstDeviceProvider implementations for the wasapi and - directsound plugins, so it's now possible to discover both audio - sources and audio sinks on Windows via the GstDeviceMonitor API - -- debug log timestamps are now higher granularity owing to - g_get_monotonic_time() now being used as fallback in - gst_utils_get_timestamp(). Before that, there would sometimes be - 10-20 lines of debug log output sporting the same timestamp. +- this section will be filled in in due course Contributors -Aaron Boxer, Adrián Pardini, Adrien SCH, Akinobu Mita, Alban Bedel, -Alessandro Decina, Alex Ashley, Alicia Boya García, Alistair Buxton, -Alvaro Margulis, Anders Jonsson, Andreas Frisch, Andrejs Vasiljevs, -Andrew Bott, Antoine Jacoutot, Antonio Ospite, Antoni Silvestre, Anton -Obzhirov, Anuj Jaiswal, Arjen Veenhuizen, Arnaud Bonatti, Arun Raghavan, -Ashish Kumar, Aurélien Zanelli, Ayaka, Branislav Katreniak, Branko -Subasic, Brion Vibber, Carlos Rafael Giani, Cassandra Rommel, Chris -Bass, Chris Paulson-Ellis, Christoph Reiter, Claudio Saavedra, Clemens -Lang, Cyril Lashkevich, Daniel van Vugt, Dave Craig, Dave Johnstone, -David Evans, David Schleef, Deepak Srivastava, Dimitrios Katsaros, -Dmitry Zhadinets, Dongil Park, Dustin Spicuzza, Eduard Sinelnikov, -Edward Hervey, Enrico Jorns, Eunhae Choi, Ezequiel Garcia, fengalin, -Filippo Argiolas, Florent Thiéry, Florian Zwoch, Francisco Velazquez, -François Laignel, fvanzile, George Kiagiadakis, Georg Lippitsch, Graham -Leggett, Guillaume Desmottes, Gurkirpal Singh, Gwang Yoon Hwang, Gwenole -Beauchesne, Haakon Sporsheim, Haihua Hu, Håvard Graff, Heekyoung Seo, -Heinrich Fink, Holger Kaelberer, Hoonhee Lee, Hosang Lee, Hyunjun Ko, -Ian Jamison, James Stevenson, Jan Alexander Steffens (heftig), Jan -Schmidt, Jason Lin, Jens Georg, Jeremy Hiatt, Jérôme Laheurte, Jimmy -Ohn, Jochen Henneberg, John Ludwig, John Nikolaides, Jonathan Karlsson, -Josep Torra, Juan Navarro, Juan Pablo Ugarte, Julien Isorce, Jun Xie, -Jussi Kukkonen, Justin Kim, Lasse Laursen, Lubosz Sarnecki, Luc -Deschenaux, Luis de Bethencourt, Marcin Lewandowski, Mario Alfredo -Carrillo Arevalo, Mark Nauwelaerts, Martin Kelly, Matej Knopp, Mathieu -Duponchelle, Matteo Valdina, Matt Fischer, Matthew Waters, Matthieu -Bouron, Matthieu Crapet, Matt Staples, Michael Catanzaro, Michael -Olbrich, Michael Shigorin, Michael Tretter, Michał Dębski, Michał Górny, -Michele Dionisio, Miguel París, Mikhail Fludkov, Munez, Nael Ouedraogo, -Neos3452, Nicholas Panayis, Nick Kallen, Nicola Murino, Nicolas -Dechesne, Nicolas Dufresne, Nirbheek Chauhan, Ognyan Tonchev, Ole André -Vadla Ravnås, Oleksij Rempel, Olivier Crête, Omar Akkila, Orestis -Floros, Patricia Muscalu, Patrick Radizi, Paul Kim, Per-Erik Brodin, -Peter Seiderer, Philip Craig, Philippe Normand, Philippe Renon, Philipp -Zabel, Pierre Pouzol, Piotr Drąg, Ponnam Srinivas, Pratheesh Gangadhar, -Raimo Järvi, Ramprakash Jelari, Ravi Kiran K N, Reynaldo H. Verdejo -Pinochet, Rico Tzschichholz, Robert Rosengren, Roland Peffer, Руслан -Ижбулатов, Sam Hurst, Sam Thursfield, Sangkyu Park, Sanjay NM, Satya -Prakash Gupta, Scott D Phillips, Sean DuBois, Sebastian Cote, Sebastian -Dröge, Sebastian Rasmussen, Sejun Park, Sergey Borovkov, Seungha Yang, -Shakin Chou, Shinya Saito, Simon Himmelbauer, Sky Juan, Song Bing, -Sreerenj Balachandran, Stefan Kost, Stefan Popa, Stefan Sauer, Stian -Selnes, Thiago Santos, Thibault Saunier, Thijs Vermeir, Tim Allen, -Tim-Philipp Müller, Ting-Wei Lan, Tomas Rataj, Tom Bailey, Tonu Jaansoo, -U. Artie Eoff, Umang Jain, Ursula Maplehurst, VaL Doroshchuk, Vasilis -Liaskovitis, Víctor Manuel Jáquez Leal, vijay, Vincent Penquerc'h, -Vineeth T M, Vivia Nikolaidou, Wang Xin-yu (王昕宇), Wei Feng, Wim -Taymans, Wonchul Lee, Xabier Rodriguez Calvar, Xavier Claessens, -XuGuangxin, Yasushi SHOJI, Yi A Wang, Youness Alaoui, +- this section will be filled in in due course ... and many others who have contributed bug reports, translations, sent suggestions or helped testing. -Bugs fixed in 1.14 +Bugs fixed in 1.16 -More than 800 bugs have been fixed during the development of 1.14. +- this section will be filled in in due course + +More than XXX bugs have been fixed during the development of 1.16. This list does not include issues that have been cherry-picked into the -stable 1.12 branch and fixed there as well, all fixes that ended up in -the 1.12 branch are also included in 1.14. +stable 1.16 branch and fixed there as well, all fixes that ended up in +the 1.16 branch are also included in 1.16. This list also does not include issues that have been fixed without a bug report in bugzilla, so the actual number of fixes is much higher. -Stable 1.14 branch +Stable 1.16 branch -After the 1.14.0 release there will be several 1.14.x bug-fix releases +After the 1.16.0 release there will be several 1.16.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.14.x bug-fix releases will be made from -the git 1.14 branch, which is a stable branch. +a bug-fix release usually. The 1.16.x bug-fix releases will be made from +the git 1.16 branch, which is a stable branch. -1.14.0 +1.16.0 -1.14.0 was released on 19 March 2018. - -1.14.1 - -The first 1.14 bug-fix release (1.14.1) is scheduled to be released -around the end of March or beginning of April. - -This release only contains bugfixes and it should be safe to update from -1.14.0. +1.16.0 is scheduled to be released around September 2018. Known Issues -- The webrtcdsp element (which is unrelated to the newly-landed - GStreamer webrtc support) is currently not shipped as part of the +- The webrtcdsp element is currently not shipped as part of the Windows binary packages due to a build system issue. -Schedule for 1.16 +Schedule for 1.18 Our next major feature release will be 1.16, and 1.15 will be the unstable development version leading up to the stable 1.16 release. The development of 1.15/1.16 will happen in the git master branch. The plan for the 1.16 development cycle is yet to be confirmed, but it -is expected that feature freeze will be around August 2018 followed by +is expected that feature freeze will be around August 2017 followed by several 1.15 pre-releases and the new 1.16 stable release in September. 1.16 will be backwards-compatible to the stable 1.14, 1.12, 1.10, 1.8, @@ -1196,8 +189,6 @@ several 1.15 pre-releases and the new 1.16 stable release in September. ------------------------------------------------------------------------ -_These release notes have been prepared by Tim-Philipp Müller with_ -_contributions from Sebastian Dröge, Sreerenj Balachandran, Thibault -Saunier_ _and Víctor Manuel Jáquez Leal._ +_These release notes have been prepared by Tim-Philipp Müller._ _License: CC BY-SA 4.0_ diff --git a/RELEASE b/RELEASE new file mode 100644 index 0000000000..de473f7825 --- /dev/null +++ b/RELEASE @@ -0,0 +1,84 @@ +This is GStreamer gstreamer-vaapi 1.15.0.1. + +GStreamer 1.15 is the development version leading up to the next major +stable version which will be 1.16. + +The 1.15 development series adds new features on top of the 1.14 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.16/ + +Binaries for Android, iOS, Mac OS X and Windows will 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 +http://cgit.freedesktop.org/gstreamer/gstreamer/ + +==== Homepage ==== + +The project's website is https://gstreamer.freedesktop.org/ + +==== Support and Bugs ==== + +We use GNOME's bugzilla for bug reports and feature requests: +http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer + +Please submit patches via bugzilla as well. + +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 is stored in Git, hosted at git.freedesktop.org, and can be cloned +from there (see link above). + +Interested developers of the core library, plugins, and applications should +subscribe to the gstreamer-devel list. diff --git a/configure.ac b/configure.ac index 7b5d131c52..1671428f7c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [14]) +m4_define([gst_vaapi_minor_version], [15]) m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1400]) +m4_define([gst_vaapi_lt_current], [1500]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1400]) +m4_define([gst_vaapi_lt_age], [1500]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.14.0]) -m4_define([gst_plugins_base_version], [1.14.0]) -m4_define([gst_plugins_bad_version], [1.14.0]) +m4_define([gst_version], [1.15.0.1]) +m4_define([gst_plugins_base_version], [1.15.0.1]) +m4_define([gst_plugins_bad_version], [1.15.0.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.0.2]) diff --git a/docs/plugins/inspect/plugin-vaapi.xml b/docs/plugins/inspect/plugin-vaapi.xml new file mode 100644 index 0000000000..8dbe186a8f --- /dev/null +++ b/docs/plugins/inspect/plugin-vaapi.xml @@ -0,0 +1,196 @@ + + vaapi + VA-API based elements + ../../gst/vaapi/.libs/libgstvaapi.so + libgstvaapi.so + 1.15.0.1 + LGPL + gstreamer-vaapi + gstreamer-vaapi + http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer + + + vaapidecodebin + VA-API Decode Bin + Codec/Decoder/Video + A VA-API based bin with a decoder and a postprocessor + Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Victor Jaquez <victorx.jaquez@intel.com> + + + sink + sink + always +
video/mpeg, mpegversion=(int)2, systemstream=(boolean)false; video/mpeg, mpegversion=(int)4; video/x-divx; video/x-xvid; video/x-h263; video/x-h264; video/x-h265; video/x-wmv; video/x-vp8; video/x-vp9
+
+ + src + source + always +
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
+
+
+
+ + vaapih264dec + VA-API H264 decoder + Codec/Decoder/Video + A VA-API based H264 video decoder + Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> + + + sink + sink + always +
video/x-h264
+
+ + src + source + always +
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + vaapih264enc + VA-API H264 encoder + Codec/Encoder/Video + A VA-API based H264 video encoder + Wind Yuan <feng.yuan@intel.com> + + + sink + sink + always +
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
+
+ + src + source + always +
video/x-h264, stream-format=(string){ avc, byte-stream }, alignment=(string)au, profile=(string){ constrained-baseline, baseline, main, high, multiview-high, stereo-high }
+
+
+
+ + vaapijpegdec + VA-API JPEG decoder + Codec/Decoder/Video + A VA-API based JPEG video decoder + Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> + + + sink + sink + always +
image/jpeg
+
+ + src + source + always +
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + vaapimpeg2dec + VA-API MPEG2 decoder + Codec/Decoder/Video + A VA-API based MPEG2 video decoder + Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> + + + sink + sink + always +
video/mpeg, mpegversion=(int)2, systemstream=(boolean)false
+
+ + src + source + always +
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + vaapimpeg2enc + VA-API MPEG-2 encoder + Codec/Encoder/Video + A VA-API based MPEG-2 video encoder + Guangxin Xu <guangxin.xu@intel.com> + + + sink + sink + always +
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
+
+ + src + source + always +
video/mpeg, mpegversion=(int)2, systemstream=(boolean)false
+
+
+
+ + vaapipostproc + VA-API video postprocessing + Filter/Converter/Video;Filter/Converter/Video/Scaler;Filter/Effect/Video;Filter/Effect/Video/Deinterlace + A VA-API video postprocessing filter + Gwenole Beauchesne <gwenole.beauchesne@intel.com> + + + sink + sink + always +
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }
+
+ + src + source + always +
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + vaapisink + VA-API sink + Sink/Video + A VA-API based videosink + Gwenole Beauchesne <gwenole.beauchesne@intel.com> + + + sink + sink + always +
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:VASurface, meta:GstVideoOverlayComposition), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoOverlayComposition), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + vaapivc1dec + VA-API VC1 decoder + Codec/Decoder/Video + A VA-API based VC1 video decoder + Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> + + + sink + sink + always +
video/x-wmv, wmvversion=(int)3, format=(string){ WMV3, WVC1 }
+
+ + src + source + always +
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+
+
\ No newline at end of file diff --git a/meson.build b/meson.build index 49139316d4..95953bd903 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.14.0', + version : '1.15.0.1', meson_version : '>= 0.36.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From fa77b2bf60630bb3fba99d13ea3eb47967939f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 30 Mar 2018 20:39:18 +0200 Subject: [PATCH 3057/3781] vaapiencode: h264: find best profile in those available Instead to look for the best profile in the allowed profiles by downstream, the encoder should look for the base profile in the available profile in VA-API. https://bugzilla.gnome.org/show_bug.cgi?id=794306 --- gst/vaapi/gstvaapiencode_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 96e6ef5818..d4f6433711 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -334,7 +334,7 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) encode->is_avc = stream_format && strcmp (stream_format, "avc") == 0; /* Check for the largest profile that is supported */ - profile = find_best_profile (allowed_caps); + profile = find_best_profile (available_caps); if (profile != GST_VAAPI_PROFILE_UNKNOWN) { GST_INFO ("using %s profile as target decoder constraints", gst_vaapi_utils_h264_get_profile_string (profile)); From 7fa706f05a715027d15ff3f0bbfd362feedf9d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 16 Apr 2018 10:53:47 +0100 Subject: [PATCH 3058/3781] Automatic update of common submodule From 3fa2c9e to ed78bee --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 3fa2c9e372..ed78bee437 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 3fa2c9e372bceec30be91e67fb02b6cb05bed493 +Subproject commit ed78bee437dcbe22e6eef0031d9a29d157c0461f From e19570a8b61942d723d019e7241ede764bba0f47 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Mon, 16 Oct 2017 12:09:08 +0900 Subject: [PATCH 3059/3781] libs: encoder: h265: 16 bit rounding of picture width and height pic_width_in_luma_samples/pic_height_in_luma_samples can be 16-bit rounded instead of 32-bit. In addition, codedbuf_size must be calculated according to this change. https://bugzilla.gnome.org/show_bug.cgi?id=753229 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 87f3a6bc59..a21865033e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2437,8 +2437,8 @@ set_context_info (GstVaapiEncoder * base_encoder) + (encoder->num_bframes > 0 ? 1 : 0) + DEFAULT_SURFACES_COUNT); /* Only YUV 4:2:0 formats are supported for now. */ - base_encoder->codedbuf_size += GST_ROUND_UP_32 (vip->width) * - GST_ROUND_UP_32 (vip->height) * 3 / 2; + base_encoder->codedbuf_size += GST_ROUND_UP_16 (vip->width) * + GST_ROUND_UP_16 (vip->height) * 3 / 2; return GST_VAAPI_ENCODER_STATUS_SUCCESS; } @@ -2456,15 +2456,15 @@ gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) if (luma_width != encoder->luma_width || luma_height != encoder->luma_height) { GST_DEBUG ("resolution: %d %d", GST_VAAPI_ENCODER_WIDTH (encoder), GST_VAAPI_ENCODER_HEIGHT (encoder)); - encoder->luma_width = GST_ROUND_UP_32 (luma_width); - encoder->luma_height = GST_ROUND_UP_32 (luma_height); + encoder->luma_width = GST_ROUND_UP_16 (luma_width); + encoder->luma_height = GST_ROUND_UP_16 (luma_height); encoder->ctu_width = (encoder->luma_width + 31) / 32; encoder->ctu_height = (encoder->luma_height + 31) / 32; encoder->config_changed = TRUE; /* Frame Cropping */ - if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 31) || - (GST_VAAPI_ENCODER_HEIGHT (encoder) & 31)) { + if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) || + (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) { static const guint SubWidthC[] = { 1, 2, 2, 1 }; static const guint SubHeightC[] = { 1, 2, 1, 1 }; encoder->conformance_window_flag = 1; From 1f71b5a57d4dff4cb6ad21d6a55eef77ed6a3dbe Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Fri, 13 Apr 2018 09:28:53 +0200 Subject: [PATCH 3060/3781] wayland: don't poll if there are no pending frames Otherwise the following poll may not return for an arbitrary amount of time. This can happen if another wayland event queue has flushed and read our events. https://bugzilla.gnome.org/show_bug.cgi?id=795224 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 3d77e45668..bd2d89d836 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -185,6 +185,11 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) if (wl_display_flush (wl_display) < 0) goto error; + if (g_atomic_int_get (&priv->num_frames_pending) == 0) { + wl_display_cancel_read (wl_display); + return TRUE; + } + again: if (gst_poll_wait (priv->poll, GST_CLOCK_TIME_NONE) < 0) { int saved_errno = errno; From 1825d939e79af722dea7506855c8575c29d73ea5 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 8 Nov 2017 13:26:38 +0900 Subject: [PATCH 3061/3781] libs: display: wayland: add gst_vaapi_display_wayland_new_with_va_display() Implements new API function so that users could create GstVaapiDisplay with their own VADisplay within a native display as backend. https://bugzilla.gnome.org/show_bug.cgi?id=705821 --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 29 ++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay_wayland.h | 4 +++ 2 files changed, 33 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 13d40a2e6d..b06f3883a4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -350,6 +350,35 @@ gst_vaapi_display_wayland_new_with_display (struct wl_display * wl_display) NULL), 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) +{ + GstVaapiDisplayInfo info = { + .va_display = va_display, + .native_display = wl_display, + }; + + g_return_val_if_fail (wl_display, NULL); + + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_WAYLAND, + NULL), GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, &info); +} + /** * gst_vaapi_display_wayland_get_display: * @display: a #GstVaapiDisplayWayland diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h index fd6fa11d44..7af728f736 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h @@ -41,6 +41,10 @@ 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); From bfac678e9ad6d17c6a8f1a4e493bb97619a569fc Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 8 Nov 2017 13:27:06 +0900 Subject: [PATCH 3062/3781] videocontext: support wl-display in "gst.vaapi.app.Display" Through "gst.vaapi.app.Display" context, users can set their own VADisplay and native display of their backend. So far we support only X11 display, from now we also support Wayland display. Attributes: - wl-display : pointer of struct wl_display . https://bugzilla.gnome.org/show_bug.cgi?id=705821 --- gst/vaapi/gstvaapivideocontext.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 4c5a1d3c1f..afc52681f5 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -31,6 +31,9 @@ #if USE_X11 #include #endif +#if USE_WAYLAND +#include +#endif GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); @@ -103,6 +106,17 @@ gst_vaapi_video_context_get_display (GstContext * context, gboolean app_context, gst_vaapi_display_x11_new_with_va_display (va_display, x11_display); } #endif +#if USE_WAYLAND + if (!display) { + struct wl_display *wl_display = NULL; + if (gst_structure_get (structure, "wl-display", G_TYPE_POINTER, + &wl_display, NULL)) { + display = + gst_vaapi_display_wayland_new_with_va_display (va_display, + wl_display); + } + } +#endif _init_context_debug (); From 5ee46f6751dc03b9981f1a8d9da76b31fa3c1a1f Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Fri, 30 Mar 2018 13:41:39 +0200 Subject: [PATCH 3063/3781] display: drm: Allow finding DRM paths out of the PCI subsystem This removes hard-coded checks on the parent subsystem of potential DRM devices. These checks were set to exlude devices that do not originate from the PCI bus, which is only a valid approach on x86 devices. Other devices may have a DRM device originating from the platform subsystem, so the checks that were previously restricted to PCI are extended to cover platform devices as well. https://bugzilla.gnome.org/show_bug.cgi?id=794840 Signed-off-by: Paul Kocialkowski --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 25 ++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 95becdb873..ef68187aad 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -56,6 +56,7 @@ typedef enum 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) @@ -83,6 +84,7 @@ get_default_device_path (GstVaapiDisplay * display) struct udev_device *device, *parent; struct udev_enumerate *e = NULL; struct udev_list_entry *l; + gint i; int fd; if (!priv->device_path_default) { @@ -111,7 +113,13 @@ get_default_device_path (GstVaapiDisplay * display) syspath = udev_list_entry_get_name (l); device = udev_device_new_from_syspath (udev, syspath); parent = udev_device_get_parent (device); - if (strcmp (udev_device_get_subsystem (parent), "pci") != 0) { + + for (i = 0; allowed_subsystems[i] != NULL; i++) + if (strcmp (udev_device_get_subsystem (parent), + allowed_subsystems[i]) == 0) + break; + + if (allowed_subsystems[i] == NULL) { udev_device_unref (device); continue; } @@ -185,6 +193,7 @@ set_device_path_from_fd (GstVaapiDisplay * display, gint drm_device) struct udev_enumerate *e = NULL; struct udev_list_entry *l; gboolean success = FALSE; + gint i; g_free (priv->device_path); priv->device_path = NULL; @@ -195,10 +204,18 @@ set_device_path_from_fd (GstVaapiDisplay * display, gint drm_device) busid = drmGetBusid (drm_device); if (!busid) goto end; - if (strncmp (busid, "pci:", 4) != 0) + + for (i = 0; allowed_subsystems[i] != NULL; i++) { + busid_length = strlen (allowed_subsystems[i]); + + if (strncmp (busid, allowed_subsystems[i], busid_length) == 0) { + busid += busid_length + 1; + busid_length = strlen (busid); + } + } + + if (allowed_subsystems[i] == NULL) goto end; - busid += 4; - busid_length = strlen (busid); udev = udev_new (); if (!udev) From 3900b4b36f774d297b9f824eff69de1af4dce832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 20 Apr 2018 11:50:55 +0100 Subject: [PATCH 3064/3781] meson: fix miscellaneous meson warnings WARNING: Passed invalid keyword argument "rqeuired". gst-libs/gst/base/meson.build:11: WARNING: Passed invalid keyword argument "version". gst-libs/gst/base/meson.build:11: WARNING: Passed invalid keyword argument "soversion". gst-libs/gst/vaapi/meson.build:223: WARNING: Passed invalid keyword argument "version". gst-libs/gst/vaapi/meson.build:223: WARNING: Passed invalid keyword argument "soversion". --- gst-libs/gst/base/meson.build | 2 -- gst-libs/gst/vaapi/meson.build | 2 -- meson.build | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/gst-libs/gst/base/meson.build b/gst-libs/gst/base/meson.build index a64f9a3ccc..d93738716c 100644 --- a/gst-libs/gst/base/meson.build +++ b/gst-libs/gst/base/meson.build @@ -12,8 +12,6 @@ gstvaapi_baseutils = static_library('gstvaapi-baseutils-@0@'.format(api_version) gstvaapi_baseutils_sources, c_args : gstreamer_vaapi_args, include_directories: [configinc, libsinc], - version : libversion, - soversion : soversion, dependencies : gstvaapi_baseutils_deps, ) diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 4053748a69..102d55cddb 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -224,8 +224,6 @@ gstlibvaapi = static_library('gstlibvaapi-@0@'.format(api_version), gstlibvaapi_sources, c_args : gstreamer_vaapi_args + ['-DIN_LIBGSTVAAPI_CORE', '-DGST_USE_UNSTABLE_API', '-DGST_VAAPI_VERSION_ID="@0@"'.format(gst_version)], include_directories: [configinc, libsinc], - version : libversion, - soversion : soversion, dependencies : gstlibvaapi_deps, ) diff --git a/meson.build b/meson.build index 95953bd903..0b775dac7d 100644 --- a/meson.build +++ b/meson.build @@ -59,7 +59,7 @@ egl_dep = dependency('egl', required: false) gl_dep = dependency('gl', required: false) glesv2_dep = dependency('glesv2', required: false) glesv3_dep = dependency('glesv3', required: false) -libdl_dep = cc.find_library('dl', rqeuired: false) +libdl_dep = cc.find_library('dl', required: false) wayland_client_dep = dependency('wayland-client', required: false) x11_dep = dependency('x11', required: false) xrandr_dep = dependency('xrandr', required: false) From b9b696b07b3d2f42b0ec47baeefee57b9a3eff9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 Apr 2018 16:01:29 +0200 Subject: [PATCH 3065/3781] meson: use get_pkgconfig_variable() Use get_pkgconfig_variable() method, of dependency class, rather than using run_command(). --- meson.build | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index 0b775dac7d..72fa6e5762 100644 --- a/meson.build +++ b/meson.build @@ -88,6 +88,11 @@ USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl USE_WAYLAND = libva_wayland_dep.found() and wayland_client_dep.found() and get_option('with_wayland') != 'no' USE_X11 = libva_x11_dep.found() and x11_dep.found() and get_option('with_x11') != 'no' +driverdir = libva_dep.get_pkgconfig_variable('driverdir') +if driverdir == '' + driverdir = '@0@/@1@/@2@'.format(get_option('prefix'), get_option('libdir'), 'dri') +endif + cdata = configuration_data() cdata.set('GST_API_VERSION_S', '"@0@.@1@"'.format(gst_version_major, gst_version_minor)) cdata.set('PACKAGE', '"gstreamer-vaapi"') @@ -96,6 +101,7 @@ cdata.set('PACKAGE_VERSION', '"@0@"'.format(gst_version)) cdata.set('PACKAGE_NAME', '"GStreamer VA-API Plug-ins"') cdata.set('PACKAGE_STRING', '"GStreamer VA-API Plug-ins @0@"'.format(gst_version)) cdata.set('PACKAGE_BUGREPORT', '"http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer"') +cdata.set('VA_DRIVERS_PATH', '"@0@"'.format(driverdir)) cdata.set10('USE_DRM', USE_DRM) cdata.set10('USE_EGL', USE_EGL) cdata.set10('USE_ENCODERS', USE_ENCODERS) @@ -116,10 +122,6 @@ cdata.set10('HAVE_XRENDER', xrender_dep.found()) cdata.set10('USE_VA_VPP', USE_VPP) cdata.set10('USE_GST_GL_HELPERS', gstgl_dep.found()) cdata.set('GLES_VERSION_MASK', GLES_VERSION_MASK) -runcmd = run_command('pkg-config', '--variable=driverdir', 'libva') -if runcmd.returncode() == 0 - cdata.set('VA_DRIVERS_PATH', '"@0@"'.format(runcmd.stdout().strip())) -endif if libva_dep.version().version_compare('< 0.38.0') check_headers = [ From bfd4b43c1668835dad7d2ef881d00be65189a48c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 25 Apr 2018 11:01:45 +0100 Subject: [PATCH 3066/3781] meson: use -Wl,-Bsymbolic-functions where supported Just like the autotools build. --- meson.build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 72fa6e5762..38eac9daf8 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('gstreamer-vaapi', 'c', version : '1.15.0.1', - meson_version : '>= 0.36.0', + meson_version : '>= 0.46.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) @@ -21,6 +21,10 @@ gst_req = '>= @0@.@1@.0'.format(gst_version_major, gst_version_minor) cc = meson.get_compiler('c') +if cc.has_link_argument('-Wl,-Bsymbolic-functions') + add_project_link_arguments('-Wl,-Bsymbolic-functions', language : 'c') +endif + # Symbol visibility if cc.has_argument('-fvisibility=hidden') add_project_arguments('-fvisibility=hidden', language: 'c') From 9fde93f80c8af99adf892a96a0667b57a6f027af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 24 Apr 2018 10:02:33 +0200 Subject: [PATCH 3067/3781] libs: egl: utils: fix usage of GstGL macros Include gl.h for the required GstGL symbols. https://bugzilla.gnome.org/show_bug.cgi?id=795391 --- gst-libs/gst/vaapi/gstvaapiutils_egl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c index 17a6cd8911..958d1fde0b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -22,8 +22,11 @@ #include "sysdeps.h" #include "gstvaapiutils_egl.h" -#if USE_GST_GL_HELPERS && GST_GL_HAVE_PLATFORM_EGL -# include +#if USE_GST_GL_HELPERS +# include +# if GST_GL_HAVE_PLATFORM_EGL +# include +# endif #endif #define DEBUG 1 From 4af46f00c2a809773388b8e5e17ef9985ad034e9 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 24 Apr 2018 18:12:44 +0900 Subject: [PATCH 3068/3781] libs: egl: utils: mark context as wrapped when it is The returning egl context may be null, so we should check the return value. https://bugzilla.gnome.org/show_bug.cgi?id=795391 --- gst-libs/gst/vaapi/gstvaapiutils_egl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c index 958d1fde0b..0bd02505ec 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -1117,11 +1117,15 @@ egl_context_new_wrapped (EglDisplay * display, EGLContext gl_context) args.display = display; args.config = config; args.gl_parent_context = gl_context; + args.context = NULL; success = egl_display_run (display, (EglContextRunFunc) do_egl_context_new, &args); egl_object_unref (config); if (!success) return NULL; + + if (args.context) + args.context->base.is_wrapped = TRUE; return args.context; } From 785efdbc22f0b403573f45f3de6351c7d4f21e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 25 Apr 2018 17:50:14 +0200 Subject: [PATCH 3069/3781] meson: fix USE_GLES_VERSION_MASK 1. The macro in the code is USE_GLES_VERSION_MASK 2. glesv3 is provided by glesv2 pkg-config, then it's required to check headers https://bugzilla.gnome.org/show_bug.cgi?id=795391 --- meson.build | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/meson.build b/meson.build index 38eac9daf8..a5fa0afe7c 100644 --- a/meson.build +++ b/meson.build @@ -62,17 +62,24 @@ libudev_dep = dependency('libudev', required: false) egl_dep = dependency('egl', required: false) gl_dep = dependency('gl', required: false) glesv2_dep = dependency('glesv2', required: false) -glesv3_dep = dependency('glesv3', required: false) libdl_dep = cc.find_library('dl', required: false) wayland_client_dep = dependency('wayland-client', required: false) x11_dep = dependency('x11', required: false) xrandr_dep = dependency('xrandr', required: false) xrender_dep = dependency('xrender', required: false) -GLES_VERSION_MASK = 0 -GLES_VERSION_MASK += gl_dep.found() ? 1 : 0 -GLES_VERSION_MASK += glesv2_dep.found() ? 4 : 0 -GLES_VERSION_MASK += glesv3_dep.found() ? 8 : 0 +GLES_VERSION_MASK = gl_dep.found() ? 1 : 0 +if glesv2_dep.found() + if (cc.has_header('GLES2/gl2.h', dependencies: glesv2_dep) and + cc.has_header('GLES2/gl2ext.h', dependencies: glesv2_dep)) + GLES_VERSION_MASK += 4 + endif + if (cc.has_header('GLES3/gl3.h', dependencies: glesv2_dep) and + cc.has_header('GLES3/gl3ext.h', dependencies: glesv2_dep) and + cc.has_header('GLES2/gl2ext.h', dependencies: glesv2_dep)) + GLES_VERSION_MASK += 8 + endif +endif USE_ENCODERS = libva_dep.version().version_compare('>= 0.34.0') and get_option('with_encoders') != 'no' USE_H265_DECODER = cc.has_header('va/va_dec_hevc.h', dependencies: libva_dep, prefix: '#include ') @@ -125,7 +132,7 @@ cdata.set10('HAVE_XRANDR', xrandr_dep.found()) cdata.set10('HAVE_XRENDER', xrender_dep.found()) cdata.set10('USE_VA_VPP', USE_VPP) cdata.set10('USE_GST_GL_HELPERS', gstgl_dep.found()) -cdata.set('GLES_VERSION_MASK', GLES_VERSION_MASK) +cdata.set('USE_GLES_VERSION_MASK', GLES_VERSION_MASK) if libva_dep.version().version_compare('< 0.38.0') check_headers = [ From b9c38a295bec1853596997967d29549ad297171b Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 25 Apr 2018 16:24:32 +0900 Subject: [PATCH 3070/3781] plugins: pass members as parameters of gst_gl_ensure_element_data() The parameters of gst_gl_ensure_element_data() have to be not local variable since they are going to be used to see if they're set in gst_element_set_context() inside the API. This is basically a revert of commit 3d56306c https://bugzilla.gnome.org/show_bug.cgi?id=793643 --- gst/vaapi/gstvaapipluginbase.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 08f1e0da15..5fde56c4fe 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1235,11 +1235,15 @@ gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin) GstGLContext *gl_other_context = NULL, *gl_context = NULL; GstGLDisplay *gl_display = NULL; - if (!gst_gl_ensure_element_data (plugin, &gl_display, &gl_other_context)) + if (!gst_gl_ensure_element_data (plugin, + (GstGLDisplay **) & plugin->gl_display, + (GstGLContext **) & plugin->gl_other_context)) goto no_valid_gl_display; + gl_display = (GstGLDisplay *) plugin->gl_display; if (gst_gl_display_get_handle_type (gl_display) == GST_GL_DISPLAY_TYPE_ANY) goto no_valid_gl_display; + gl_other_context = (GstGLContext *) plugin->gl_other_context; GST_INFO_OBJECT (plugin, "creating a new GstGL context"); @@ -1256,15 +1260,14 @@ gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin) } while (!gst_gl_display_add_context (gl_display, gl_context)); GST_OBJECT_UNLOCK (gl_display); - plugin_set_gst_gl (plugin, gl_display, gl_context, gl_other_context); - return GST_OBJECT_CAST (gl_context); /* ERRORS */ no_valid_gl_display: { - gst_object_replace ((GstObject **) & gl_display, NULL); - gst_object_replace ((GstObject **) & gl_other_context, NULL); + GST_INFO_OBJECT (plugin, "No valid GL display found"); + gst_object_replace (&plugin->gl_display, NULL); + gst_object_replace (&plugin->gl_other_context, NULL); return NULL; } #else From 86bf89d16d63923cf763e4e5c1f8796c3abf1238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Apr 2018 15:03:23 +0200 Subject: [PATCH 3071/3781] plugins: GstGL API must use the member variables This commit basically is a revert of commits 8092537 and fc1c415 https://bugzilla.gnome.org/show_bug.cgi?id=793643 --- gst/vaapi/gstvaapipluginbase.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 5fde56c4fe..18c3576754 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -60,21 +60,6 @@ plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) gst_vaapi_display_unref (display); } -#if USE_GST_GL_HELPERS -static void -plugin_set_gst_gl (GstVaapiPluginBase * plugin, GstGLDisplay * gl_display, - GstGLContext * gl_context, GstGLContext * gl_other_context) -{ - gst_object_replace (&plugin->gl_display, NULL); - plugin->gl_display = (GstObject *) gl_display; - - gst_object_replace (&plugin->gl_context, (GstObject *) gl_context); - - gst_object_replace (&plugin->gl_other_context, NULL); - plugin->gl_other_context = (GstObject *) gl_other_context; -} -#endif - /** * gst_vaapi_plugin_base_set_context: * @plugin: a #GstVaapiPluginBase instance @@ -99,14 +84,9 @@ gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, plugin_set_display (plugin, display); } #if USE_GST_GL_HELPERS - { - GstGLDisplay *gl_display = NULL; - GstGLContext *gl_other_context = NULL; - GstElement *el = GST_ELEMENT_CAST (plugin); - - if (gst_gl_handle_set_context (el, context, &gl_display, &gl_other_context)) - plugin_set_gst_gl (plugin, gl_display, NULL, gl_other_context); - } + gst_gl_handle_set_context (GST_ELEMENT_CAST (plugin), context, + (GstGLDisplay **) & plugin->gl_display, + (GstGLContext **) & plugin->gl_other_context); #endif } From 59579a9cb3053e27c4d6495e3c01fd521fccbd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Apr 2018 18:15:47 +0200 Subject: [PATCH 3072/3781] plugin: remove custom GstGL context handling Instead of using our own context handling for looking for GstGL parameters (display, context and other context), this patch changes the logic to use the utility function offered by GstGL. https://bugzilla.gnome.org/show_bug.cgi?id=793643 --- gst/vaapi/gstvaapipluginbase.c | 6 ++--- gst/vaapi/gstvaapipluginutil.c | 35 ++++++++++++++++++++-------- gst/vaapi/gstvaapivideocontext.c | 39 ++++---------------------------- gst/vaapi/gstvaapivideocontext.h | 2 +- 4 files changed, 33 insertions(+), 49 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 18c3576754..d23b519ab9 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1215,10 +1215,8 @@ gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin) GstGLContext *gl_other_context = NULL, *gl_context = NULL; GstGLDisplay *gl_display = NULL; - if (!gst_gl_ensure_element_data (plugin, - (GstGLDisplay **) & plugin->gl_display, - (GstGLContext **) & plugin->gl_other_context)) - goto no_valid_gl_display; + if (!plugin->gl_display) + return NULL; gl_display = (GstGLDisplay *) plugin->gl_display; if (gst_gl_display_get_handle_type (gl_display) == GST_GL_DISPLAY_TYPE_ANY) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 0ff46bc01b..fa25131e48 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -246,9 +246,7 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) static void gst_vaapi_find_gl_context (GstElement * element) { - GstObject *gl_context; GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); - GstPadDirection direction = GST_PAD_UNKNOWN; /* if the element is vaapisink or any vaapi encoder it doesn't need * to know a GstGLContext in order to create an appropriate @@ -257,15 +255,32 @@ gst_vaapi_find_gl_context (GstElement * element) if (GST_IS_VIDEO_SINK (element) || GST_IS_VIDEO_ENCODER (element)) return; - gl_context = NULL; - if (!gst_vaapi_find_gl_local_context (element, &gl_context, &direction)) - gl_context = gst_vaapi_plugin_base_create_gl_context (plugin); + if (!gst_gl_ensure_element_data (plugin, + (GstGLDisplay **) & plugin->gl_display, + (GstGLContext **) & plugin->gl_other_context)) + goto no_valid_gl_display; - if (gl_context) { - gst_vaapi_plugin_base_set_gl_context (plugin, gl_context); - if (direction == GST_PAD_SRC) - gst_vaapi_plugin_base_set_srcpad_can_dmabuf (plugin, gl_context); - gst_object_unref (gl_context); + gst_vaapi_find_gl_local_context (element, &plugin->gl_context); + + if (plugin->gl_context) { + gst_vaapi_plugin_base_set_srcpad_can_dmabuf (plugin, plugin->gl_context); + } else { + GstObject *gl_context; + + gl_context = gst_vaapi_plugin_base_create_gl_context (plugin); + if (gl_context) { + gst_vaapi_plugin_base_set_gl_context (plugin, gl_context); + gst_object_unref (gl_context); + } + } + + /* ERRORS */ +no_valid_gl_display: + { + GST_INFO_OBJECT (plugin, "No valid GL display found"); + gst_object_replace (&plugin->gl_display, NULL); + gst_object_replace (&plugin->gl_other_context, NULL); + return; } } diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index afc52681f5..2528ff3728 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -321,8 +321,6 @@ gst_vaapi_video_context_propagate (GstElement * element, * @element: the #GstElement where the search begins * @gl_context_ptr: the pointer where the GstGL context is going to be * stored - * @direction_ptr: the pointer of the #GstPadDirection where the GstGL - * context was found * * Query the pipeline, downstream and upstream for a GstGL context * @@ -330,42 +328,15 @@ gst_vaapi_video_context_propagate (GstElement * element, **/ gboolean gst_vaapi_find_gl_local_context (GstElement * element, - GstObject ** gl_context_ptr, GstPadDirection * direction_ptr) + GstObject ** gl_context_ptr) { #if USE_GST_GL_HELPERS - GstQuery *query; - GstContext *context; - const GstStructure *s; - GstObject *gl_context; - GstPadDirection direction; + GstGLContext **context_ptr = (GstGLContext **) gl_context_ptr; - g_return_val_if_fail (gl_context_ptr, FALSE); - - direction = GST_PAD_UNKNOWN; - gl_context = NULL; - query = gst_query_new_context ("gst.gl.local_context"); - if (_gst_context_run_query (element, query, GST_PAD_SRC)) { - gst_query_parse_context (query, &context); - if (context) { - s = gst_context_get_structure (context); - gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &gl_context, NULL); - direction = GST_PAD_SRC; - } - } - if (!gl_context && _gst_context_run_query (element, query, GST_PAD_SINK)) { - gst_query_parse_context (query, &context); - if (context) { - s = gst_context_get_structure (context); - gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &gl_context, NULL); - direction = GST_PAD_SINK; - } - } - gst_query_unref (query); - if (gl_context) { - *gl_context_ptr = gl_context; - *direction_ptr = direction; + if (gst_gl_query_local_gl_context (element, GST_PAD_SRC, context_ptr)) + return TRUE; + if (gst_gl_query_local_gl_context (element, GST_PAD_SINK, context_ptr)) return TRUE; - } #endif return FALSE; } diff --git a/gst/vaapi/gstvaapivideocontext.h b/gst/vaapi/gstvaapivideocontext.h index cdac0f9b9c..8577ca452b 100644 --- a/gst/vaapi/gstvaapivideocontext.h +++ b/gst/vaapi/gstvaapivideocontext.h @@ -60,6 +60,6 @@ gst_vaapi_video_context_propagate (GstElement * element, G_GNUC_INTERNAL gboolean gst_vaapi_find_gl_local_context (GstElement * element, - GstObject ** gl_context_ptr, GstPadDirection * direction); + GstObject ** gl_context_ptr); #endif /* GST_VAAPI_VIDEO_CONTEXT_H */ From 2d95089a8d35a4a8ff5b04ec08a151f43196c2b4 Mon Sep 17 00:00:00 2001 From: "Wang,Fei" Date: Sat, 28 Apr 2018 16:10:46 +0800 Subject: [PATCH 3073/3781] vaapih264dec: add constrained and progressive profiles Those profiles have been added in the version 2012-01 and 2011-06 of the AVC spec (A.2.4.1 and A.2.4.2). Both are supported by VAProfileH264High https://bugzilla.gnome.org/show_bug.cgi?id=795624 --- gst/vaapi/gstvaapidecode.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d11b80325e..b4a531b048 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1271,6 +1271,13 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) have_high |= profile == GST_VAAPI_PROFILE_H264_HIGH; } + if (have_high) { + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, "progressive-high"); + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, "constrained-high"); + } + if (base_only && (!have_mvc || !have_svc) && have_high) { if (!have_mvc) { GST_DEBUG ("base_only: force adding MVC profiles in caps"); From 77527d67abe4ac74e51618953f69ae52c68cca06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 5 May 2018 17:57:49 +0200 Subject: [PATCH 3074/3781] libs: remove gstbitwriter Since it is deployed in gstreamer-core, there is no need to use our custom version. https://bugzilla.gnome.org/show_bug.cgi?id=795848 --- gst-libs/gst/Makefile.am | 2 +- gst-libs/gst/base/Makefile.am | 47 --- gst-libs/gst/base/gstbitwriter.c | 278 -------------- gst-libs/gst/base/gstbitwriter.h | 361 ------------------ gst-libs/gst/base/meson.build | 20 - gst-libs/gst/meson.build | 1 - gst-libs/gst/vaapi/Makefile.am | 1 - gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 71 ++-- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 60 +-- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 42 +- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 4 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 8 +- gst-libs/gst/vaapi/gstvaapifeipak_h264.c | 30 +- gst-libs/gst/vaapi/meson.build | 3 +- 14 files changed, 112 insertions(+), 816 deletions(-) delete mode 100644 gst-libs/gst/base/Makefile.am delete mode 100644 gst-libs/gst/base/gstbitwriter.c delete mode 100644 gst-libs/gst/base/gstbitwriter.h delete mode 100644 gst-libs/gst/base/meson.build diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index de02514679..80a5198af9 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = base vaapi +SUBDIRS = vaapi -include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/base/Makefile.am b/gst-libs/gst/base/Makefile.am deleted file mode 100644 index 87358734d8..0000000000 --- a/gst-libs/gst/base/Makefile.am +++ /dev/null @@ -1,47 +0,0 @@ -noinst_LTLIBRARIES = \ - libgstvaapi-baseutils.la \ - $(NULL) - -source_c = \ - gstbitwriter.c \ - $(NULL) - -source_h = \ - gstbitwriter.h \ - $(NULL) - -libgstvaapi_baseutils_cflags = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - -I$(top_builddir)/gst-libs \ - $(GST_BASE_CFLAGS) \ - $(GST_CFLAGS) \ - $(NULL) - -libgstvaapi_baseutils_libs = \ - $(GST_BASE_LIBS) \ - $(GST_LIBS) \ - $(NULL) - -nodist_libgstvaapi_baseutils_la_SOURCES = \ - $(source_c) \ - $(NULL) - -libgstvaapi_baseutils_la_CFLAGS = \ - $(libgstvaapi_baseutils_cflags) \ - $(NULL) - -libgstvaapi_baseutils_la_LIBADD = \ - $(libgstvaapi_baseutils_libs) \ - $(NULL) - -libgstvaapi_baseutils_la_LDFLAGS = \ - $(GST_ALL_LDFLAGS) \ - $(NULL) - -EXTRA_DIST = \ - $(source_c) \ - $(source_h) \ - $(NULL) - --include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/base/gstbitwriter.c b/gst-libs/gst/base/gstbitwriter.c deleted file mode 100644 index 5fbb2faf39..0000000000 --- a/gst-libs/gst/base/gstbitwriter.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * gstbitwriter.c - bitstream writer - * - * Copyright (C) 2013 Intel Corporation - * - * 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 - */ - -#define GST_BIT_WRITER_DISABLE_INLINES - -#include "gstbitwriter.h" - -/** - * gst_bit_writer_init: - * @bitwriter: a #GstBitWriter instance - * @reserved_bits: reserved bits to allocate data - * - * Initializes a #GstBitWriter instance and allocate @reserved_bits - * data inside. - * - * Cleanup function: gst_bit_writer_clear - */ -void -gst_bit_writer_init (GstBitWriter * bitwriter, guint32 reserved_bits) -{ - bitwriter->bit_size = 0; - bitwriter->data = NULL; - bitwriter->bit_capacity = 0; - bitwriter->auto_grow = TRUE; - if (reserved_bits) - _gst_bit_writer_check_space (bitwriter, reserved_bits); -} - -/** - * gst_bit_writer_init_fill: - * @bitwriter: a #GstBitWriter instance - * @data: allocated data - * @bits: size of allocated @data in bits - * - * Initializes a #GstBitWriter instance with alocated @data and @bit outside. - * - * Cleanup function: gst_bit_writer_clear - */ -void -gst_bit_writer_init_fill (GstBitWriter * bitwriter, guint8 * data, guint bits) -{ - bitwriter->bit_size = 0; - bitwriter->data = data; - bitwriter->bit_capacity = bits; - bitwriter->auto_grow = FALSE; -} - -/** - * gst_bit_writer_clear: - * @bitwriter: a #GstBitWriter instance - * @free_data: flag to free #GstBitWriter allocated data - * - * Clear a #GstBitWriter instance and destroy allocated data inside - * if @free_data is %TRUE. - */ -void -gst_bit_writer_clear (GstBitWriter * bitwriter, gboolean free_data) -{ - if (bitwriter->auto_grow && bitwriter->data && free_data) - g_free (bitwriter->data); - - bitwriter->data = NULL; - bitwriter->bit_size = 0; - bitwriter->bit_capacity = 0; -} - -/** - * gst_bit_writer_new: - * @bitwriter: a #GstBitWriter instance - * @reserved_bits: reserved bits to allocate data - * - * Create a #GstBitWriter instance and allocate @reserved_bits data inside. - * - * Free-function: gst_bit_writer_free - * - * Returns: a new #GstBitWriter instance - */ -GstBitWriter * -gst_bit_writer_new (guint32 reserved_bits) -{ - GstBitWriter *ret = g_slice_new0 (GstBitWriter); - - gst_bit_writer_init (ret, reserved_bits); - - return ret; -} - -/** - * gst_bit_writer_new_fill: - * @bitwriter: a #GstBitWriter instance - * @data: allocated data - * @bits: size of allocated @data in bits - * - * Create a #GstBitWriter instance with allocated @data and @bit outside. - * - * Free-function: gst_bit_writer_free - * - * Returns: a new #GstBitWriter instance - */ -GstBitWriter * -gst_bit_writer_new_fill (guint8 * data, guint bits) -{ - GstBitWriter *ret = g_slice_new0 (GstBitWriter); - - gst_bit_writer_init_fill (ret, data, bits); - - return ret; -} - -/** - * gst_bit_writer_free: - * @bitwriter: a #GstBitWriter instance - * @free_data: flag to free @data which is allocated inside - * - * Clear a #GstBitWriter instance and destroy allocated data inside if - * @free_data is %TRUE - */ -void -gst_bit_writer_free (GstBitWriter * writer, gboolean free_data) -{ - g_return_if_fail (writer != NULL); - - gst_bit_writer_clear (writer, free_data); - - g_slice_free (GstBitWriter, writer); -} - -/** - * gst_bit_writer_get_size: - * @bitwriter: a #GstBitWriter instance - * - * Get size of written @data - * - * Returns: size of bits written in @data - */ -guint -gst_bit_writer_get_size (GstBitWriter * bitwriter) -{ - return _gst_bit_writer_get_size_inline (bitwriter); -} - -/** - * gst_bit_writer_get_data: - * @bitwriter: a #GstBitWriter instance - * - * Get written @data pointer - * - * Returns: @data pointer - */ -guint8 * -gst_bit_writer_get_data (GstBitWriter * bitwriter) -{ - return _gst_bit_writer_get_data_inline (bitwriter); -} - -/** - * gst_bit_writer_get_data: - * @bitwriter: a #GstBitWriter instance - * @pos: new position of data end - * - * Set the new postion of data end which should be the new size of @data. - * - * Returns: %TRUE if successful, %FALSE otherwise - */ -gboolean -gst_bit_writer_set_pos (GstBitWriter * bitwriter, guint pos) -{ - return _gst_bit_writer_set_pos_inline (bitwriter, pos); -} - -/** - * gst_bit_writer_put_bits_uint8: - * @bitwriter: a #GstBitWriter instance - * @value: value of #guint8 to write - * @nbits: number of bits to write - * - * Write @nbits bits of @value to #GstBitWriter. - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ - -/** - * gst_bit_writer_put_bits_uint16: - * @bitwriter: a #GstBitWriter instance - * @value: value of #guint16 to write - * @nbits: number of bits to write - * - * Write @nbits bits of @value to #GstBitWriter. - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ - -/** - * gst_bit_writer_put_bits_uint32: - * @bitwriter: a #GstBitWriter instance - * @value: value of #guint32 to write - * @nbits: number of bits to write - * - * Write @nbits bits of @value to #GstBitWriter. - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ - -/** - * gst_bit_writer_put_bits_uint64: - * @bitwriter: a #GstBitWriter instance - * @value: value of #guint64 to write - * @nbits: number of bits to write - * - * Write @nbits bits of @value to #GstBitWriter. - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ - -#define GST_BIT_WRITER_WRITE_BITS(bits) \ -gboolean \ -gst_bit_writer_put_bits_uint##bits (GstBitWriter *bitwriter, guint##bits value, guint nbits) \ -{ \ - return _gst_bit_writer_put_bits_uint##bits##_inline (bitwriter, value, nbits); \ -} - -GST_BIT_WRITER_WRITE_BITS (8) -GST_BIT_WRITER_WRITE_BITS (16) -GST_BIT_WRITER_WRITE_BITS (32) -GST_BIT_WRITER_WRITE_BITS (64) - -#undef GST_BIT_WRITER_WRITE_BITS - -/** - * gst_bit_writer_put_bytes: - * @bitwriter: a #GstBitWriter instance - * @data: pointer of data to write - * @nbytes: number of bytes to write - * - * Write @nbytes bytes of @data to #GstBitWriter. - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ -gboolean -gst_bit_writer_put_bytes (GstBitWriter * bitwriter, - const guint8 * data, guint nbytes) -{ - return _gst_bit_writer_put_bytes_inline (bitwriter, data, nbytes); -} - -/** - * gst_bit_writer_align_bytes: - * @bitwriter: a #GstBitWriter instance - * @trailing_bit: trailing bits of last byte, 0 or 1 - * - * Write trailing bit to align last byte of @data. @trailing_bit can - * only be 1 or 0. - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ -gboolean -gst_bit_writer_align_bytes (GstBitWriter * bitwriter, guint8 trailing_bit) -{ - return _gst_bit_writer_align_bytes_inline (bitwriter, trailing_bit); -} diff --git a/gst-libs/gst/base/gstbitwriter.h b/gst-libs/gst/base/gstbitwriter.h deleted file mode 100644 index 02ceeab9b5..0000000000 --- a/gst-libs/gst/base/gstbitwriter.h +++ /dev/null @@ -1,361 +0,0 @@ -/* - * gstbitwriter.h - bitstream writer - * - * Copyright (C) 2013 Intel Corporation - * - * 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_BIT_WRITER_H -#define GST_BIT_WRITER_H - -#include -#include - -G_BEGIN_DECLS - -#define GST_BIT_WRITER_DATA(writer) ((writer)->data) -#define GST_BIT_WRITER_BIT_SIZE(writer) ((writer)->bit_size) -#define GST_BIT_WRITER(writer) ((GstBitWriter *) (writer)) - -typedef struct _GstBitWriter GstBitWriter; - -/** - * GstBitWriter: - * @data: Allocated @data for bit writer to write - * @bit_size: Size of written @data in bits - * - * Private: - * @bit_capacity: Capacity of the allocated @data - * @auto_grow: @data space can auto grow - * - * A bit writer instance. - */ -struct _GstBitWriter -{ - guint8 *data; - guint bit_size; - - /*< private >*/ - guint bit_capacity; - gboolean auto_grow; - gpointer _gst_reserved[GST_PADDING]; -}; - -GstBitWriter * -gst_bit_writer_new (guint32 reserved_bits) G_GNUC_MALLOC; - -GstBitWriter * -gst_bit_writer_new_fill (guint8 * data, guint bits) G_GNUC_MALLOC; - -void -gst_bit_writer_free (GstBitWriter * writer, gboolean free_data); - -void -gst_bit_writer_init (GstBitWriter * bitwriter, guint32 reserved_bits); - -void -gst_bit_writer_init_fill (GstBitWriter * bitwriter, guint8 * data, guint bits); - -void -gst_bit_writer_clear (GstBitWriter * bitwriter, gboolean free_data); - -guint -gst_bit_writer_get_size (GstBitWriter * bitwriter); - -guint8 * -gst_bit_writer_get_data (GstBitWriter * bitwriter); - -gboolean -gst_bit_writer_set_pos (GstBitWriter * bitwriter, guint pos); - -guint -gst_bit_writer_get_space (GstBitWriter * bitwriter); - -gboolean -gst_bit_writer_put_bits_uint8 (GstBitWriter * bitwriter, - guint8 value, guint nbits); - -gboolean -gst_bit_writer_put_bits_uint16 (GstBitWriter * bitwriter, - guint16 value, guint nbits); - -gboolean -gst_bit_writer_put_bits_uint32 (GstBitWriter * bitwriter, - guint32 value, guint nbits); - -gboolean -gst_bit_writer_put_bits_uint64 (GstBitWriter * bitwriter, - guint64 value, guint nbits); - -gboolean -gst_bit_writer_put_bytes (GstBitWriter * bitwriter, const guint8 * data, - guint nbytes); - -gboolean -gst_bit_writer_align_bytes (GstBitWriter * bitwriter, guint8 trailing_bit); - -static const guint8 _gst_bit_writer_bit_filling_mask[9] = { - 0x00, 0x01, 0x03, 0x07, - 0x0F, 0x1F, 0x3F, 0x7F, - 0xFF -}; - -/* Aligned to 256 bytes */ -#define __GST_BITS_WRITER_ALIGNMENT_MASK 2047 -#define __GST_BITS_WRITER_ALIGNED(bitsize) \ - (((bitsize) + __GST_BITS_WRITER_ALIGNMENT_MASK)&(~__GST_BITS_WRITER_ALIGNMENT_MASK)) - -static inline gboolean -_gst_bit_writer_check_space (GstBitWriter * bitwriter, guint32 bits) -{ - guint32 new_bit_size = bits + bitwriter->bit_size; - guint32 clear_pos; - - g_assert (bitwriter->bit_size <= bitwriter->bit_capacity); - if (new_bit_size <= bitwriter->bit_capacity) - return TRUE; - - if (!bitwriter->auto_grow) - return FALSE; - - /* auto grow space */ - new_bit_size = __GST_BITS_WRITER_ALIGNED (new_bit_size); - g_assert (new_bit_size - && ((new_bit_size & __GST_BITS_WRITER_ALIGNMENT_MASK) == 0)); - clear_pos = ((bitwriter->bit_size + 7) >> 3); - bitwriter->data = g_realloc (bitwriter->data, (new_bit_size >> 3)); - memset (bitwriter->data + clear_pos, 0, (new_bit_size >> 3) - clear_pos); - bitwriter->bit_capacity = new_bit_size; - return TRUE; -} - -#undef __GST_BITS_WRITER_ALIGNMENT_MASK -#undef __GST_BITS_WRITER_ALIGNED - -#define __GST_BIT_WRITER_WRITE_BITS_UNCHECKED(bits) \ -static inline void \ -gst_bit_writer_put_bits_uint##bits##_unchecked( \ - GstBitWriter *bitwriter, \ - guint##bits value, \ - guint nbits \ -) \ -{ \ - guint byte_pos, bit_offset; \ - guint8 *cur_byte; \ - guint fill_bits; \ - \ - byte_pos = (bitwriter->bit_size >> 3); \ - bit_offset = (bitwriter->bit_size & 0x07); \ - cur_byte = bitwriter->data + byte_pos; \ - g_assert (nbits <= bits); \ - g_assert( bit_offset < 8 && \ - bitwriter->bit_size <= bitwriter->bit_capacity); \ - \ - while (nbits) { \ - fill_bits = ((8 - bit_offset) < nbits ? (8 - bit_offset) : nbits); \ - nbits -= fill_bits; \ - bitwriter->bit_size += fill_bits; \ - \ - *cur_byte |= (((value >> nbits) & _gst_bit_writer_bit_filling_mask[fill_bits]) \ - << (8 - bit_offset - fill_bits)); \ - ++cur_byte; \ - bit_offset = 0; \ - } \ - g_assert(cur_byte <= \ - (bitwriter->data + (bitwriter->bit_capacity >> 3))); \ -} - -__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (8) -__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (16) -__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (32) -__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (64) -#undef __GST_BIT_WRITER_WRITE_BITS_UNCHECKED - -static inline guint -gst_bit_writer_get_size_unchecked (GstBitWriter * bitwriter) -{ - return GST_BIT_WRITER_BIT_SIZE (bitwriter); -} - -static inline guint8 * -gst_bit_writer_get_data_unchecked (GstBitWriter * bitwriter) -{ - return GST_BIT_WRITER_DATA (bitwriter); -} - -static inline gboolean -gst_bit_writer_set_pos_unchecked (GstBitWriter * bitwriter, guint pos) -{ - GST_BIT_WRITER_BIT_SIZE (bitwriter) = pos; - return TRUE; -} - -static inline guint -gst_bit_writer_get_space_unchecked (GstBitWriter * bitwriter) -{ - return bitwriter->bit_capacity - bitwriter->bit_size; -} - -static inline void -gst_bit_writer_put_bytes_unchecked (GstBitWriter * bitwriter, - const guint8 * data, guint nbytes) -{ - if ((bitwriter->bit_size & 0x07) == 0) { - memcpy (&bitwriter->data[bitwriter->bit_size >> 3], data, nbytes); - bitwriter->bit_size += (nbytes << 3); - } else { - g_assert (0); - while (nbytes) { - gst_bit_writer_put_bits_uint8_unchecked (bitwriter, *data, 8); - --nbytes; - ++data; - } - } -} - -static inline void -gst_bit_writer_align_bytes_unchecked (GstBitWriter * bitwriter, - guint8 trailing_bit) -{ - guint32 bit_offset, bit_left; - guint8 value = 0; - - bit_offset = (bitwriter->bit_size & 0x07); - if (!bit_offset) - return; - - bit_left = 8 - bit_offset; - if (trailing_bit) - value = _gst_bit_writer_bit_filling_mask[bit_left]; - return gst_bit_writer_put_bits_uint8_unchecked (bitwriter, value, bit_left); -} - -#define __GST_BIT_WRITER_WRITE_BITS_INLINE(bits) \ -static inline gboolean \ -_gst_bit_writer_put_bits_uint##bits##_inline( \ - GstBitWriter *bitwriter, \ - guint##bits value, \ - guint nbits \ -) \ -{ \ - g_return_val_if_fail(bitwriter != NULL, FALSE); \ - g_return_val_if_fail(nbits != 0, FALSE); \ - g_return_val_if_fail(nbits <= bits, FALSE); \ - \ - if (!_gst_bit_writer_check_space(bitwriter, nbits)) \ - return FALSE; \ - gst_bit_writer_put_bits_uint##bits##_unchecked(bitwriter, value, nbits); \ - return TRUE; \ -} - -__GST_BIT_WRITER_WRITE_BITS_INLINE (8) -__GST_BIT_WRITER_WRITE_BITS_INLINE (16) -__GST_BIT_WRITER_WRITE_BITS_INLINE (32) -__GST_BIT_WRITER_WRITE_BITS_INLINE (64) -#undef __GST_BIT_WRITER_WRITE_BITS_INLINE - -static inline guint -_gst_bit_writer_get_size_inline (GstBitWriter * bitwriter) -{ - g_return_val_if_fail (bitwriter != NULL, 0); - - return gst_bit_writer_get_size_unchecked (bitwriter); -} - -static inline guint8 * -_gst_bit_writer_get_data_inline (GstBitWriter * bitwriter) -{ - g_return_val_if_fail (bitwriter != NULL, NULL); - - return gst_bit_writer_get_data_unchecked (bitwriter); -} - -static inline gboolean -_gst_bit_writer_set_pos_inline (GstBitWriter * bitwriter, guint pos) -{ - g_return_val_if_fail (bitwriter != NULL, FALSE); - g_return_val_if_fail (pos <= bitwriter->bit_capacity, FALSE); - - return gst_bit_writer_set_pos_unchecked (bitwriter, pos); -} - -static inline guint -_gst_bit_writer_get_space_inline (GstBitWriter * bitwriter) -{ - g_return_val_if_fail (bitwriter != NULL, 0); - g_return_val_if_fail (bitwriter->bit_size < bitwriter->bit_capacity, 0); - - return gst_bit_writer_get_space_unchecked (bitwriter); -} - -static inline gboolean -_gst_bit_writer_put_bytes_inline (GstBitWriter * bitwriter, - const guint8 * data, guint nbytes) -{ - g_return_val_if_fail (bitwriter != NULL, FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (nbytes, FALSE); - - if (!_gst_bit_writer_check_space (bitwriter, nbytes * 8)) - return FALSE; - - gst_bit_writer_put_bytes_unchecked (bitwriter, data, nbytes); - return TRUE; -} - -static inline gboolean -_gst_bit_writer_align_bytes_inline (GstBitWriter * bitwriter, - guint8 trailing_bit) -{ - g_return_val_if_fail (bitwriter != NULL, FALSE); - g_return_val_if_fail ((trailing_bit == 0 || trailing_bit == 1), FALSE); - g_return_val_if_fail (((bitwriter->bit_size + 7) & (~7)) <= - bitwriter->bit_capacity, FALSE); - - gst_bit_writer_align_bytes_unchecked (bitwriter, trailing_bit); - return TRUE; -} - -#ifndef GST_BIT_WRITER_DISABLE_INLINES -#define gst_bit_writer_get_size(bitwriter) \ - _gst_bit_writer_get_size_inline(bitwriter) -#define gst_bit_writer_get_data(bitwriter) \ - _gst_bit_writer_get_data_inline(bitwriter) -#define gst_bit_writer_set_pos(bitwriter, pos) \ - G_LIKELY (_gst_bit_writer_set_pos_inline (bitwriter, pos)) -#define gst_bit_writer_get_space(bitwriter) \ - _gst_bit_writer_get_space_inline(bitwriter) - -#define gst_bit_writer_put_bits_uint8(bitwriter, value, nbits) \ - G_LIKELY (_gst_bit_writer_put_bits_uint8_inline (bitwriter, value, nbits)) -#define gst_bit_writer_put_bits_uint16(bitwriter, value, nbits) \ - G_LIKELY (_gst_bit_writer_put_bits_uint16_inline (bitwriter, value, nbits)) -#define gst_bit_writer_put_bits_uint32(bitwriter, value, nbits) \ - G_LIKELY (_gst_bit_writer_put_bits_uint32_inline (bitwriter, value, nbits)) -#define gst_bit_writer_put_bits_uint64(bitwriter, value, nbits) \ - G_LIKELY (_gst_bit_writer_put_bits_uint64_inline (bitwriter, value, nbits)) - -#define gst_bit_writer_put_bytes(bitwriter, data, nbytes) \ - G_LIKELY (_gst_bit_writer_put_bytes_inline (bitwriter, data, nbytes)) - -#define gst_bit_writer_align_bytes(bitwriter, trailing_bit) \ - G_LIKELY (_gst_bit_writer_align_bytes_inline(bitwriter, trailing_bit)) -#endif - -G_END_DECLS - -#endif /* GST_BIT_WRITER_H */ diff --git a/gst-libs/gst/base/meson.build b/gst-libs/gst/base/meson.build deleted file mode 100644 index d93738716c..0000000000 --- a/gst-libs/gst/base/meson.build +++ /dev/null @@ -1,20 +0,0 @@ -gstvaapi_baseutils_sources = [ - 'gstbitwriter.c', -] - -gstvaapi_baseutils_headers = [ - 'gstbitwriter.h', -] - -gstvaapi_baseutils_deps = [gstbase_dep] - -gstvaapi_baseutils = static_library('gstvaapi-baseutils-@0@'.format(api_version), - gstvaapi_baseutils_sources, - c_args : gstreamer_vaapi_args, - include_directories: [configinc, libsinc], - dependencies : gstvaapi_baseutils_deps, -) - -gstvaapi_baseutils_dep = declare_dependency(link_with: gstvaapi_baseutils, - include_directories : [libsinc], - dependencies : gstvaapi_baseutils_deps) diff --git a/gst-libs/gst/meson.build b/gst-libs/gst/meson.build index f47f7b1df7..a8719a14c0 100644 --- a/gst-libs/gst/meson.build +++ b/gst-libs/gst/meson.build @@ -1,2 +1 @@ -subdir('base') subdir('vaapi') diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 491208f92c..f8e4992725 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -40,7 +40,6 @@ libgstvaapi_libs = \ $(GST_VIDEO_LIBS) \ $(GST_CODEC_PARSERS_LIBS) \ $(LIBVA_LIBS) \ - $(top_builddir)/gst-libs/gst/base/libgstvaapi-baseutils.la \ $(NULL) libgstvaapi_source_c = \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index a4e65b0067..0acba67a32 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1432,7 +1432,7 @@ add_packed_au_delimiter (GstVaapiEncoderH264 * encoder, guint32 data_bit_size; guint8 *data; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_NONE, GST_H264_NAL_AU_DELIMITER); @@ -1456,14 +1456,14 @@ add_packed_au_delimiter (GstVaapiEncoderH264 * encoder, gst_vaapi_enc_picture_add_packed_header (picture, packed_aud); gst_vaapi_codec_object_replace (&packed_aud, NULL); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write AU Delimiter NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1486,7 +1486,7 @@ add_packed_sequence_header (GstVaapiEncoderH264 * encoder, fill_hrd_params (encoder, &hrd_params); - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS); @@ -1517,14 +1517,14 @@ add_packed_sequence_header (GstVaapiEncoderH264 * encoder, /* store sps data */ _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write SPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1544,7 +1544,7 @@ add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder, fill_hrd_params (encoder, &hrd_params); /* non-base layer, pack one subset sps */ - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS); @@ -1569,14 +1569,14 @@ add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder, /* store subset sps data */ _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write SPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1594,7 +1594,7 @@ add_packed_picture_header (GstVaapiEncoderH264 * encoder, guint32 data_bit_size; guint8 *data; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS); bs_write_pps (&bs, pic_param, encoder->profile); @@ -1616,14 +1616,14 @@ add_packed_picture_header (GstVaapiEncoderH264 * encoder, /* store pps data */ _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write PPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1640,9 +1640,9 @@ add_packed_sei_header (GstVaapiEncoderH264 * encoder, guint8 *data, *buf_period_payload = NULL, *pic_timing_payload = NULL; gboolean need_buf_period, need_pic_timing; - gst_bit_writer_init (&bs_buf_period, 128 * 8); - gst_bit_writer_init (&bs_pic_timing, 128 * 8); - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs_buf_period, 128, FALSE); + gst_bit_writer_init_with_size (&bs_pic_timing, 128, FALSE); + gst_bit_writer_init_with_size (&bs, 128, FALSE); need_buf_period = GST_VAAPI_H264_SEI_BUF_PERIOD & payloadtype; need_pic_timing = GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype; @@ -1705,18 +1705,18 @@ add_packed_sei_header (GstVaapiEncoderH264 * encoder, gst_vaapi_enc_picture_add_packed_header (picture, packed_sei); gst_vaapi_codec_object_replace (&packed_sei, NULL); - gst_bit_writer_clear (&bs_buf_period, TRUE); - gst_bit_writer_clear (&bs_pic_timing, TRUE); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs_buf_period); + gst_bit_writer_reset (&bs_pic_timing); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write SEI NAL unit"); - gst_bit_writer_clear (&bs_buf_period, TRUE); - gst_bit_writer_clear (&bs_pic_timing, TRUE); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs_buf_period); + gst_bit_writer_reset (&bs_pic_timing); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1768,7 +1768,7 @@ add_packed_prefix_nal_header (GstVaapiEncoderH264 * encoder, guint8 *data; guint8 nal_ref_idc, nal_unit_type; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) @@ -1794,7 +1794,7 @@ add_packed_prefix_nal_header (GstVaapiEncoderH264 * encoder, gst_vaapi_enc_slice_add_packed_header (slice, packed_prefix_nal); gst_vaapi_codec_object_replace (&packed_prefix_nal, NULL); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; @@ -1802,7 +1802,7 @@ add_packed_prefix_nal_header (GstVaapiEncoderH264 * encoder, bs_error: { GST_WARNING ("failed to write Prefix NAL unit header"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1821,7 +1821,7 @@ add_packed_slice_header (GstVaapiEncoderH264 * encoder, guint8 *data; guint8 nal_ref_idc, nal_unit_type; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) @@ -1850,14 +1850,14 @@ add_packed_slice_header (GstVaapiEncoderH264 * encoder, gst_vaapi_enc_slice_add_packed_header (slice, packed_slice); gst_vaapi_codec_object_replace (&packed_slice, NULL); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write Slice NAL unit header"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -2944,7 +2944,8 @@ gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder, level_idc = sps_info.data[3]; /* Header */ - gst_bit_writer_init (&bs, (sps_info.size + pps_info.size + 64) * 8); + gst_bit_writer_init_with_size (&bs, (sps_info.size + pps_info.size + 64), + FALSE); WRITE_UINT32 (&bs, configuration_version, 8); WRITE_UINT32 (&bs, profile_idc, 8); WRITE_UINT32 (&bs, profile_comp, 8); @@ -2969,13 +2970,15 @@ gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder, gst_buffer_unmap (encoder->pps_data, &pps_info); gst_buffer_unmap (encoder->sps_data, &sps_info); - buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&bs), - GST_BIT_WRITER_BIT_SIZE (&bs) / 8); + buffer = gst_bit_writer_reset_and_get_buffer (&bs); if (!buffer) goto error_alloc_buffer; + if (gst_buffer_n_memory (buffer) == 0) { + gst_buffer_unref (buffer); + goto error_alloc_buffer; + } *out_buffer_ptr = buffer; - gst_bit_writer_clear (&bs, FALSE); return GST_VAAPI_ENCODER_STATUS_SUCCESS; /* ERRORS */ @@ -2984,7 +2987,7 @@ bs_error: GST_ERROR ("failed to write codec-data"); gst_buffer_unmap (encoder->sps_data, &sps_info); gst_buffer_unmap (encoder->pps_data, &pps_info); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } nal_to_byte_stream_error: @@ -2992,7 +2995,7 @@ nal_to_byte_stream_error: GST_ERROR ("failed to write nal unit"); gst_buffer_unmap (encoder->sps_data, &sps_info); gst_buffer_unmap (encoder->pps_data, &pps_info); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } error_map_sps_buffer: @@ -3009,7 +3012,7 @@ error_map_pps_buffer: error_alloc_buffer: { GST_ERROR ("failed to allocate codec-data buffer"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index a99f780887..769f3d5763 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -1405,7 +1405,7 @@ add_packed_sequence_header (GstVaapiEncoderH264Fei * encoder, fill_hrd_params (encoder, &hrd_params); - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS); @@ -1436,14 +1436,14 @@ add_packed_sequence_header (GstVaapiEncoderH264Fei * encoder, /* store sps data */ _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write SPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1463,7 +1463,7 @@ add_packed_sequence_header_mvc (GstVaapiEncoderH264Fei * encoder, fill_hrd_params (encoder, &hrd_params); /* non-base layer, pack one subset sps */ - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS); @@ -1488,14 +1488,14 @@ add_packed_sequence_header_mvc (GstVaapiEncoderH264Fei * encoder, /* store subset sps data */ _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write SPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1513,7 +1513,7 @@ add_packed_picture_header (GstVaapiEncoderH264Fei * encoder, guint32 data_bit_size; guint8 *data; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS); bs_write_pps (&bs, pic_param, encoder->profile); @@ -1535,14 +1535,14 @@ add_packed_picture_header (GstVaapiEncoderH264Fei * encoder, /* store pps data */ _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write PPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1559,9 +1559,9 @@ add_packed_sei_header (GstVaapiEncoderH264Fei * encoder, guint8 *data, *buf_period_payload = NULL, *pic_timing_payload = NULL; gboolean need_buf_period, need_pic_timing; - gst_bit_writer_init (&bs_buf_period, 128 * 8); - gst_bit_writer_init (&bs_pic_timing, 128 * 8); - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs_buf_period, 128, FALSE); + gst_bit_writer_init_with_size (&bs_pic_timing, 128, FALSE); + gst_bit_writer_init_with_size (&bs, 128, FALSE); need_buf_period = GST_VAAPI_H264_SEI_BUF_PERIOD & payloadtype; need_pic_timing = GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype; @@ -1624,18 +1624,18 @@ add_packed_sei_header (GstVaapiEncoderH264Fei * encoder, gst_vaapi_enc_picture_add_packed_header (picture, packed_sei); gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_sei, NULL); - gst_bit_writer_clear (&bs_buf_period, TRUE); - gst_bit_writer_clear (&bs_pic_timing, TRUE); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs_buf_period); + gst_bit_writer_reset (&bs_pic_timing); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write SEI NAL unit"); - gst_bit_writer_clear (&bs_buf_period, TRUE); - gst_bit_writer_clear (&bs_pic_timing, TRUE); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs_buf_period); + gst_bit_writer_reset (&bs_pic_timing); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1679,7 +1679,7 @@ add_packed_prefix_nal_header (GstVaapiEncoderH264Fei * encoder, guint8 *data; guint8 nal_ref_idc, nal_unit_type; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) @@ -1706,7 +1706,7 @@ add_packed_prefix_nal_header (GstVaapiEncoderH264Fei * encoder, gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_prefix_nal, NULL); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; @@ -1714,7 +1714,7 @@ add_packed_prefix_nal_header (GstVaapiEncoderH264Fei * encoder, bs_error: { GST_WARNING ("failed to write Prefix NAL unit header"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1733,7 +1733,7 @@ add_packed_slice_header (GstVaapiEncoderH264Fei * encoder, guint8 *data; guint8 nal_ref_idc, nal_unit_type; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) @@ -1763,14 +1763,14 @@ add_packed_slice_header (GstVaapiEncoderH264Fei * encoder, gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_slice, NULL); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write Slice NAL unit header"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -2911,7 +2911,8 @@ gst_vaapi_encoder_h264_fei_get_codec_data (GstVaapiEncoder * base_encoder, level_idc = sps_info.data[3]; /* Header */ - gst_bit_writer_init (&bs, (sps_info.size + pps_info.size + 64) * 8); + gst_bit_writer_init_with_size (&bs, (sps_info.size + pps_info.size + 64), + FALSE); WRITE_UINT32 (&bs, configuration_version, 8); WRITE_UINT32 (&bs, profile_idc, 8); WRITE_UINT32 (&bs, profile_comp, 8); @@ -2934,13 +2935,12 @@ gst_vaapi_encoder_h264_fei_get_codec_data (GstVaapiEncoder * base_encoder, gst_buffer_unmap (encoder->pps_data, &pps_info); gst_buffer_unmap (encoder->sps_data, &sps_info); - buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&bs), - GST_BIT_WRITER_BIT_SIZE (&bs) / 8); + buffer = gst_bit_writer_reset_and_get_buffer (&bs); if (!buffer) goto error_alloc_buffer; *out_buffer_ptr = buffer; - gst_bit_writer_clear (&bs, FALSE); + gst_bit_writer_reset (&bs); return GST_VAAPI_ENCODER_STATUS_SUCCESS; /* ERRORS */ @@ -2949,7 +2949,7 @@ bs_error: GST_ERROR ("failed to write codec-data"); gst_buffer_unmap (encoder->sps_data, &sps_info); gst_buffer_unmap (encoder->pps_data, &pps_info); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } error_map_sps_buffer: @@ -2966,7 +2966,7 @@ error_map_pps_buffer: error_alloc_buffer: { GST_ERROR ("failed to allocate codec-data buffer"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index a21865033e..aa838d5ab8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1166,7 +1166,7 @@ add_packed_vps_header (GstVaapiEncoderH265 * encoder, guint32 data_bit_size; guint8 *data; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H265_NAL_VPS); @@ -1190,14 +1190,14 @@ add_packed_vps_header (GstVaapiEncoderH265 * encoder, /* store vps data */ _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write VPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1220,7 +1220,7 @@ add_packed_sequence_header (GstVaapiEncoderH265 * encoder, fill_hrd_params (encoder, &hrd_params); - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H265_NAL_SPS); @@ -1244,14 +1244,14 @@ add_packed_sequence_header (GstVaapiEncoderH265 * encoder, /* store sps data */ _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write SPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1269,7 +1269,7 @@ add_packed_picture_header (GstVaapiEncoderH265 * encoder, guint32 data_bit_size; guint8 *data; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H265_NAL_PPS); bs_write_pps (&bs, pic_param); @@ -1291,14 +1291,14 @@ add_packed_picture_header (GstVaapiEncoderH265 * encoder, /* store pps data */ _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write PPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1339,7 +1339,7 @@ add_packed_slice_header (GstVaapiEncoderH265 * encoder, guint8 *data; guint8 nal_unit_type; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ if (!get_nal_unit_type (picture, &nal_unit_type)) @@ -1362,14 +1362,14 @@ add_packed_slice_header (GstVaapiEncoderH265 * encoder, gst_vaapi_enc_slice_add_packed_header (slice, packed_slice); gst_vaapi_codec_object_replace (&packed_slice, NULL); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write Slice NAL unit header"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -2173,8 +2173,8 @@ gst_vaapi_encoder_h265_get_codec_data (GstVaapiEncoder * base_encoder, goto error_map_pps_buffer; /* Header */ - gst_bit_writer_init (&bs, - (vps_info.size + sps_info.size + pps_info.size + 64) * 8); + gst_bit_writer_init_with_size (&bs, + (vps_info.size + sps_info.size + pps_info.size + 64), FALSE); WRITE_UINT32 (&bs, configuration_version, 8); WRITE_UINT32 (&bs, sps_info.data[4], 8); /* profile_space | tier_flag | profile_idc */ WRITE_UINT32 (&bs, sps_info.data[5], 32); /* profile_compatibility_flag [0-31] */ @@ -2235,13 +2235,15 @@ gst_vaapi_encoder_h265_get_codec_data (GstVaapiEncoder * base_encoder, gst_buffer_unmap (encoder->sps_data, &sps_info); gst_buffer_unmap (encoder->vps_data, &vps_info); - buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&bs), - GST_BIT_WRITER_BIT_SIZE (&bs) / 8); + buffer = gst_bit_writer_reset_and_get_buffer (&bs); if (!buffer) goto error_alloc_buffer; + if (gst_buffer_n_memory (buffer) == 0) { + gst_buffer_unref (buffer); + goto error_alloc_buffer; + } *out_buffer_ptr = buffer; - gst_bit_writer_clear (&bs, FALSE); return GST_VAAPI_ENCODER_STATUS_SUCCESS; /* ERRORS */ @@ -2251,7 +2253,7 @@ bs_error: gst_buffer_unmap (encoder->vps_data, &vps_info); gst_buffer_unmap (encoder->sps_data, &sps_info); gst_buffer_unmap (encoder->pps_data, &pps_info); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } nal_to_byte_stream_error: @@ -2260,7 +2262,7 @@ nal_to_byte_stream_error: gst_buffer_unmap (encoder->vps_data, &vps_info); gst_buffer_unmap (encoder->sps_data, &sps_info); gst_buffer_unmap (encoder->pps_data, &pps_info); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } error_map_vps_buffer: @@ -2282,7 +2284,7 @@ error_map_pps_buffer: error_alloc_buffer: { GST_ERROR ("failed to allocate codec-data buffer"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 5153ad9554..b3f409d6da 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -611,7 +611,7 @@ add_packed_header (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture) guint32 data_bit_size; guint8 *data; - gst_bit_writer_init (&bs, 128 * 8); + 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); @@ -629,7 +629,7 @@ add_packed_header (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture) 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_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index db4751bf12..351ee0f004 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -347,7 +347,7 @@ set_sequence_packed_header (GstVaapiEncoderMpeg2 * encoder, guint32 data_bit_size; guint8 *data; - gst_bit_writer_init (&writer, 128 * 8); + gst_bit_writer_init_with_size (&writer, 128, FALSE); if (encoder->new_gop) gst_bit_writer_write_sps (&writer, seq_param); g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); @@ -365,7 +365,7 @@ set_sequence_packed_header (GstVaapiEncoderMpeg2 * encoder, gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); gst_vaapi_codec_object_replace (&packed_seq, NULL); - gst_bit_writer_clear (&writer, TRUE); + gst_bit_writer_reset (&writer); return TRUE; } @@ -381,7 +381,7 @@ set_picture_packed_header (GstVaapiEncoderMpeg2 * encoder, guint32 data_bit_size; guint8 *data; - gst_bit_writer_init (&writer, 128 * 8); + gst_bit_writer_init_with_size (&writer, 128, FALSE); gst_bit_writer_write_pps (&writer, pic_param); g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer); @@ -398,7 +398,7 @@ set_picture_packed_header (GstVaapiEncoderMpeg2 * encoder, gst_vaapi_enc_picture_add_packed_header (picture, packed_pic); gst_vaapi_codec_object_replace (&packed_pic, NULL); - gst_bit_writer_clear (&writer, TRUE); + gst_bit_writer_reset (&writer); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c index 2eddaa64f5..e58d69d8ec 100644 --- a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c @@ -909,7 +909,7 @@ add_packed_sequence_header (GstVaapiFEIPakH264 * feipak, guint8 *data; fill_hrd_params (feipak, &hrd_params); - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS); /* Set High profile for encoding the MVC base view. Otherwise, some @@ -939,14 +939,14 @@ add_packed_sequence_header (GstVaapiFEIPakH264 * feipak, /* store sps data */ _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write SPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -966,7 +966,7 @@ add_packed_sequence_header_mvc (GstVaapiFEIPakH264 * feipak, fill_hrd_params (feipak, &hrd_params); /* non-base layer, pack one subset sps */ - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS); @@ -992,14 +992,14 @@ add_packed_sequence_header_mvc (GstVaapiFEIPakH264 * feipak, /* store subset sps data */ _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write SPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1017,7 +1017,7 @@ add_packed_picture_header (GstVaapiFEIPakH264 * feipak, guint32 data_bit_size; guint8 *data; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS); bs_write_pps (&bs, pic_param, feipak->profile); @@ -1040,14 +1040,14 @@ add_packed_picture_header (GstVaapiFEIPakH264 * feipak, /* store pps data */ _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write PPS NAL unit"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1091,7 +1091,7 @@ add_packed_prefix_nal_header (GstVaapiFEIPakH264 * feipak, guint8 *data; guint8 nal_ref_idc, nal_unit_type; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) @@ -1117,7 +1117,7 @@ add_packed_prefix_nal_header (GstVaapiFEIPakH264 * feipak, gst_vaapi_enc_slice_add_packed_header (slice, packed_prefix_nal); gst_vaapi_codec_object_replace (&packed_prefix_nal, NULL); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; @@ -1125,7 +1125,7 @@ add_packed_prefix_nal_header (GstVaapiFEIPakH264 * feipak, bs_error: { GST_WARNING ("failed to write Prefix NAL unit header"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } @@ -1144,7 +1144,7 @@ add_packed_slice_header (GstVaapiFEIPakH264 * feipak, guint8 *data; guint8 nal_ref_idc, nal_unit_type; - gst_bit_writer_init (&bs, 128 * 8); + gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) @@ -1174,14 +1174,14 @@ add_packed_slice_header (GstVaapiFEIPakH264 * feipak, gst_vaapi_enc_slice_add_packed_header (slice, packed_slice); gst_vaapi_codec_object_replace (&packed_slice, NULL); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return TRUE; /* ERRORS */ bs_error: { GST_WARNING ("failed to write Slice NAL unit header"); - gst_bit_writer_clear (&bs, TRUE); + gst_bit_writer_reset (&bs); return FALSE; } } diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 102d55cddb..0b9d11c8cf 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -202,8 +202,7 @@ gstlibvaapi_deps = [ gstbase_dep, gstvideo_dep, gstgl_dep, gstcodecparsers_dep, - libva_dep, - gstvaapi_baseutils_dep ] + libva_dep ] if USE_DRM gstlibvaapi_deps += [libva_drm_dep, libdrm_dep, libudev_dep] endif From 9229780b262481697559def0ce4ed52ccd05ceba Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 7 May 2018 07:59:25 -0700 Subject: [PATCH 3075/3781] fix configure.ac regression Fixes regression introduced by 77527d67abe https://bugzilla.gnome.org/show_bug.cgi?id=795885 --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index 1671428f7c..3f58d69b92 100644 --- a/configure.ac +++ b/configure.ac @@ -1097,7 +1097,6 @@ AC_CONFIG_FILES([ docs/plugins/gstreamer-vaapi-plugins-docs.xml gst-libs/Makefile gst-libs/gst/Makefile - gst-libs/gst/base/Makefile gst-libs/gst/vaapi/Makefile gst/Makefile gst/vaapi/Makefile From 423398727854193221e5e8188e1dd14d20f7601e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 18 May 2018 11:09:58 +0200 Subject: [PATCH 3076/3781] libs: decoder: remove unused forward declaration --- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index c80db0f9fe..4d92706f85 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -46,7 +46,6 @@ G_BEGIN_DECLS GST_VAAPI_DECODER_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; -struct _GstVaapiDecoderUnit; /** * GST_VAAPI_PARSER_STATE: From 41ab71a4fa4f220aa6e7ffaac9ccc5c749b068eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 18 May 2018 17:27:46 +0200 Subject: [PATCH 3077/3781] libs: decoder: mpeg4, vc1: remove unused header --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h | 1 - gst-libs/gst/vaapi/gstvaapidecoder_vc1.h | 1 - 2 files changed, 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h index 17537cbe69..3ce4add4e0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h @@ -24,7 +24,6 @@ #define GST_VAAPI_DECODER_MPEG4_H #include -#include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h index 8817eac34b..6127909856 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h @@ -24,7 +24,6 @@ #define GST_VAAPI_DECODER_VC1_H #include -#include G_BEGIN_DECLS From e93232bbf4051e5a37e52628d16b62dbfc25f0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 18 May 2018 18:23:18 +0200 Subject: [PATCH 3078/3781] libs: decoder: h264: use g_clear_pointer() --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 184668c572..6aeb838a85 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1289,14 +1289,11 @@ gst_vaapi_decoder_h264_destroy (GstVaapiDecoder * base_decoder) gst_vaapi_decoder_h264_close (decoder); priv->is_opened = FALSE; - g_free (priv->dpb); - priv->dpb = NULL; + g_clear_pointer (&priv->dpb, g_free); priv->dpb_size_max = priv->dpb_size = 0; - g_free (priv->prev_ref_frames); - priv->prev_ref_frames = NULL; - g_free (priv->prev_frames); - priv->prev_frames = NULL; + g_clear_pointer (&priv->prev_ref_frames, g_free); + g_clear_pointer (&priv->prev_frames, g_free); priv->prev_frames_alloc = 0; for (i = 0; i < G_N_ELEMENTS (priv->pps); i++) @@ -1339,10 +1336,8 @@ gst_vaapi_decoder_h264_reset (GstVaapiDecoder * base_decoder) priv->dpb_size = 0; - g_free (priv->prev_ref_frames); - priv->prev_ref_frames = NULL; - g_free (priv->prev_frames); - priv->prev_frames = NULL; + g_clear_pointer (&priv->prev_ref_frames, g_free); + g_clear_pointer (&priv->prev_frames, g_free); priv->prev_frames_alloc = 0; gst_vaapi_parser_info_h264_replace (&priv->active_pps, NULL); gst_vaapi_parser_info_h264_replace (&priv->active_sps, NULL); From 705b37844e45f3cf37581ae39128b7a488fd4faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 13:27:14 +0200 Subject: [PATCH 3079/3781] plugins: guard GstGL code --- gst/vaapi/gstvaapipluginutil.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index fa25131e48..648c91b9c6 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -246,6 +246,7 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) static void gst_vaapi_find_gl_context (GstElement * element) { +#if USE_GST_GL_HELPERS GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); /* if the element is vaapisink or any vaapi encoder it doesn't need @@ -282,6 +283,7 @@ no_valid_gl_display: gst_object_replace (&plugin->gl_other_context, NULL); return; } +#endif } gboolean From 676e558331408f317d47e731a719de67bbc5cf62 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 1 Jun 2018 15:27:25 +0900 Subject: [PATCH 3080/3781] libs: encoder: h265: increase log2_max_pic_order_cnt range according to spec The specification says, "log2_max_pic_order_cnt_lsb_minus4 shall be in the range of 0 to 12, inclusive." This patch changes the upper limit from 6 to 12. https://bugzilla.gnome.org/show_bug.cgi?id=796179 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index aa838d5ab8..e1814d24b1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -181,8 +181,8 @@ h265_get_log2_max_pic_order_cnt (guint num) } if (ret <= 4) ret = 4; - else if (ret > 10) - ret = 10; + else if (ret > 16) + ret = 16; /* must be greater than 4 */ return ret; } From af3e6a8d16e4419582399880fafe5f34879fb4f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 5 Jun 2018 22:38:37 +0200 Subject: [PATCH 3081/3781] vaapiencode: h264: find profile in available and allowed caps The commit 67e33d3de225d0e006d7bf606e7abb20d4544eab ("vaapiencode: h264: find best profile in those available") changed the code to pick a profile that is actually supported by the hardware. Unfortunately it dropped the downstream constraints. This can cause negotiation failures under certain circumstances. The fix is split in two cases: 1\ the available VA-API caps doesn't intersect with pipeline's allowed caps: * The best allowed profile (pipeline's caps) is set as the encoding target profile (it will be adjusted later by the available profiles and properties) 2\ the available VA-API caps does intersect with pipeline's allowed caps: * The intersected caps are fixed, and its profile is set as the encoding target profile. In this case the is not the best profile, but the minimal one (if VA-API reports the profiles in order). Setting the minimal profile of the intersected caps is better for compatibility. This patch fixes other tests related with caps negotiation, for example, it handles baseline profile, even when VA only supports constrained-baseline. Original-patch-by: Michael Olbrich https://bugzilla.gnome.org/show_bug.cgi?id=794306 --- gst/vaapi/gstvaapiencode_h264.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index d4f6433711..8a980d0737 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -308,7 +308,7 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) const char *stream_format = NULL; GstStructure *structure; guint i, num_structures; - GstVaapiProfile profile; + GstVaapiProfile profile = GST_VAAPI_PROFILE_UNKNOWN; GstCaps *available_caps; available_caps = get_available_caps (encode); @@ -319,7 +319,27 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) } if (!gst_caps_can_intersect (allowed_caps, available_caps)) { GST_INFO_OBJECT (encode, "downstream requested an unsupported profile, " - "but encoder will output a compatible one"); + "but encoder will try to output a compatible one"); + + /* Let's try the best profile in the allowed caps. + * The internal encoder will fail later if it can't handle it */ + profile = find_best_profile (allowed_caps); + + } else { + GstCaps *profile_caps; + const gchar *profile_str; + + profile_caps = gst_caps_intersect (allowed_caps, available_caps); + + /* let's fixate to adjust to minimal profile */ + profile_caps = gst_caps_fixate (profile_caps); + + structure = gst_caps_get_structure (profile_caps, 0); + profile_str = gst_structure_get_string (structure, "profile"); + if (profile_str) + profile = gst_vaapi_utils_h264_get_profile_from_string (profile_str); + + gst_caps_unref (profile_caps); } /* Check whether "stream-format" is avcC mode */ @@ -331,14 +351,14 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) continue; stream_format = gst_structure_get_string (structure, "stream-format"); } - encode->is_avc = stream_format && strcmp (stream_format, "avc") == 0; + encode->is_avc = (g_strcmp0 (stream_format, "avc") == 0); - /* Check for the largest profile that is supported */ - profile = find_best_profile (available_caps); if (profile != GST_VAAPI_PROFILE_UNKNOWN) { GST_INFO ("using %s profile as target decoder constraints", gst_vaapi_utils_h264_get_profile_string (profile)); ret = gst_vaapi_encoder_h264_set_max_profile (encoder, profile); + } else { + ret = FALSE; } gst_caps_unref (allowed_caps); From 28952f534bb9a64c83131a6bb746082cf2fe2d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 5 Jun 2018 15:16:53 +0200 Subject: [PATCH 3082/3781] vaapiencode: h264: log output caps --- gst/vaapi/gstvaapiencode_h264.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 8a980d0737..85a49235b3 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -410,6 +410,8 @@ retry: ret = TRUE; } + GST_INFO_OBJECT (encode, "out caps %" GST_PTR_FORMAT, caps); + if (!ret) GST_LOG ("There is no compatible profile in the requested caps."); From 3056f06e02e9a5839ea599eb61fc2119877c16fd Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 22 May 2018 21:05:54 +0900 Subject: [PATCH 3083/3781] libs: display: remove unused code https://bugzilla.gnome.org/show_bug.cgi?id=796470 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 50 +++------------------------- gst-libs/gst/vaapi/gstvaapidisplay.h | 8 ----- 2 files changed, 4 insertions(+), 54 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 0e80f9ca8e..0be4419ba1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -976,7 +976,7 @@ _set_property (GstVaapiDisplay * display, const GstVaapiProperty * prop, } static void -_gst_vaapi_display_set_property (GObject * object, guint property_id, +gst_vaapi_display_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) { GstVaapiDisplay *display = GST_VAAPI_DISPLAY (object); @@ -1036,7 +1036,7 @@ _get_property (GstVaapiDisplay * display, const GstVaapiProperty * prop, } static void -_gst_vaapi_display_get_property (GObject * object, guint property_id, +gst_vaapi_display_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { GstVaapiDisplay *display = GST_VAAPI_DISPLAY (object); @@ -1072,8 +1072,8 @@ gst_vaapi_display_class_init (GstVaapiDisplayClass * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); object_class->finalize = gst_vaapi_display_finalize; - object_class->set_property = _gst_vaapi_display_set_property; - object_class->get_property = _gst_vaapi_display_get_property; + object_class->set_property = gst_vaapi_display_set_property; + object_class->get_property = gst_vaapi_display_get_property; klass->lock = gst_vaapi_display_lock_default; klass->unlock = gst_vaapi_display_unlock_default; @@ -1722,48 +1722,6 @@ gst_vaapi_display_has_property (GstVaapiDisplay * display, const gchar * name) name) != NULL; } -gboolean -gst_vaapi_display_get_property (GstVaapiDisplay * display, const gchar * name, - GValue * out_value) -{ - const GstVaapiProperty *prop; - - g_return_val_if_fail (display != NULL, FALSE); - g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (out_value != NULL, FALSE); - - if (!ensure_properties (display)) - return FALSE; - - prop = - find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, name); - if (!prop) - return FALSE; - - return _get_property (display, prop, out_value); -} - -gboolean -gst_vaapi_display_set_property (GstVaapiDisplay * display, const gchar * name, - const GValue * value) -{ - const GstVaapiProperty *prop; - - g_return_val_if_fail (display != NULL, FALSE); - g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - - if (!ensure_properties (display)) - return FALSE; - - prop = - find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, name); - if (!prop) - return FALSE; - - return _set_property (display, prop, value); -} - static gboolean get_attribute (GstVaapiDisplay * display, VADisplayAttribType type, gint * value) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 01a2859892..319faaa17a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -233,14 +233,6 @@ gst_vaapi_display_has_subpicture_format (GstVaapiDisplay * display, gboolean gst_vaapi_display_has_property (GstVaapiDisplay * display, const gchar * name); -gboolean -gst_vaapi_display_get_property (GstVaapiDisplay * display, const gchar * name, - GValue * out_value); - -gboolean -gst_vaapi_display_set_property (GstVaapiDisplay * display, const gchar * name, - const GValue * value); - gboolean gst_vaapi_display_get_render_mode (GstVaapiDisplay * display, GstVaapiRenderMode * pmode); From aa77862b62423e96a0c4a2f664e42a147f6decf0 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 22 May 2018 21:13:08 +0900 Subject: [PATCH 3084/3781] libs: display: remove unnecessary legacy code since gobjectification https://bugzilla.gnome.org/show_bug.cgi?id=796470 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 14 +++++-------- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 24 ----------------------- 2 files changed, 5 insertions(+), 33 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 0be4419ba1..39d7540d14 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -52,11 +52,6 @@ GST_DEBUG_CATEGORY (gst_debug_vaapi_display); G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplay, gst_vaapi_display, GST_TYPE_OBJECT, _do_init); -/* Ensure those symbols are actually defined in the resulting libraries */ -#undef gst_vaapi_display_ref -#undef gst_vaapi_display_unref -#undef gst_vaapi_display_replace - typedef struct _GstVaapiConfig GstVaapiConfig; struct _GstVaapiConfig { @@ -1159,7 +1154,7 @@ gst_vaapi_display_new (GstVaapiDisplay * display, /* ERRORS */ error: { - gst_vaapi_display_unref_internal (display); + gst_vaapi_display_unref (display); return NULL; } } @@ -1195,7 +1190,7 @@ gst_vaapi_display_new_with_display (VADisplay va_display) GstVaapiDisplay * gst_vaapi_display_ref (GstVaapiDisplay * display) { - return gst_vaapi_display_ref_internal (display); + return gst_object_ref (display); } /** @@ -1208,7 +1203,7 @@ gst_vaapi_display_ref (GstVaapiDisplay * display) void gst_vaapi_display_unref (GstVaapiDisplay * display) { - gst_vaapi_display_unref_internal (display); + gst_object_unref (display); } /** @@ -1224,7 +1219,8 @@ void gst_vaapi_display_replace (GstVaapiDisplay ** old_display_ptr, GstVaapiDisplay * new_display) { - gst_vaapi_display_replace_internal (old_display_ptr, new_display); + gst_object_replace ((GstObject **) old_display_ptr, + (GstObject *) new_display); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 7f96208f0c..0394a351c9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -203,30 +203,6 @@ GstVaapiDisplay * gst_vaapi_display_new (GstVaapiDisplay * display, GstVaapiDisplayInitType init_type, gpointer init_value); -/* Inline reference counting for core libgstvaapi library */ -#ifdef IN_LIBGSTVAAPI_CORE -#define gst_vaapi_display_ref_internal(display) \ - ((gpointer) gst_object_ref (GST_OBJECT (display))) - -#define gst_vaapi_display_unref_internal(display) \ - gst_object_unref (GST_OBJECT (display)) - -#define gst_vaapi_display_replace_internal(old_display_ptr, new_display) \ - gst_object_replace ((GstObject **)(old_display_ptr), GST_OBJECT (new_display)) - -#undef gst_vaapi_display_ref -#define gst_vaapi_display_ref(display) \ - gst_vaapi_display_ref_internal ((display)) - -#undef gst_vaapi_display_unref -#define gst_vaapi_display_unref(display) \ - gst_vaapi_display_unref_internal ((display)) - -#undef gst_vaapi_display_replace -#define gst_vaapi_display_replace(old_display_ptr, new_display) \ - gst_vaapi_display_replace_internal ((old_display_ptr), (new_display)) -#endif - G_END_DECLS #endif /* GST_VAAPI_DISPLAY_PRIV_H */ From d79bda315326160d8c31a67039cdb436eb9815bd Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Fri, 25 May 2018 16:47:00 +0200 Subject: [PATCH 3085/3781] vaapipostproc: don't copy the GstParentBufferMeta if use_vpp Otherwise a reference to a DMABuf input buffer is kept until the output buffer is deleted. https://bugzilla.gnome.org/show_bug.cgi?id=796399 --- gst/vaapi/gstvaapipostproc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 2b888214c9..df977f15af 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1280,6 +1280,11 @@ gst_vaapipostproc_transform_meta (GstBaseTransform * trans, GstBuffer * outbuf, /* dont' GstVideoCropMeta if use_vpp */ if (meta->info->api == GST_VIDEO_CROP_META_API_TYPE && postproc->use_vpp) return FALSE; + + /* don't copy GstParentBufferMeta if use_vpp */ + if (meta->info->api == GST_PARENT_BUFFER_META_API_TYPE && postproc->use_vpp) + return FALSE; + return TRUE; } From e31248dc28a86e1b4bf88e3098c005aa733c5f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 7 Jun 2018 19:49:02 +0100 Subject: [PATCH 3086/3781] meson: fix build when xrender or xrandr are not available HAVE_XRENDER are defined to 1 or 0, not defined or undefined. --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 10 +++++----- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 7131fe8635..f7517b10fe 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -35,11 +35,11 @@ #include "gstvaapidisplay_x11_priv.h" #include "gstvaapiwindow_x11.h" -#ifdef HAVE_XRANDR +#if HAVE_XRANDR # include #endif -#ifdef HAVE_XRENDER +#if HAVE_XRENDER # include #endif @@ -114,11 +114,11 @@ check_extensions (GstVaapiDisplayX11 * display) GstVaapiDisplayX11Private *const priv = display->priv; int evt_base, err_base; -#ifdef HAVE_XRANDR +#if HAVE_XRANDR priv->use_xrandr = XRRQueryExtension (priv->x11_display, &evt_base, &err_base); #endif -#ifdef HAVE_XRENDER +#if HAVE_XRENDER priv->has_xrender = XRenderQueryExtension (priv->x11_display, &evt_base, &err_base); #endif @@ -260,7 +260,7 @@ gst_vaapi_display_x11_get_size_mm (GstVaapiDisplay * display, width_mm = DisplayWidthMM (priv->x11_display, priv->x11_screen); height_mm = DisplayHeightMM (priv->x11_display, priv->x11_screen); -#ifdef HAVE_XRANDR +#if HAVE_XRANDR /* XXX: fix up physical size if the display is rotated */ if (priv->use_xrandr) { XRRScreenConfiguration *xrr_config = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 44b15c265e..ee90afa0ac 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -279,7 +279,7 @@ gst_vaapi_window_x11_destroy (GstVaapiWindow * window) Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); const Window xid = GST_VAAPI_OBJECT_ID (window); -#ifdef HAVE_XRENDER +#if HAVE_XRENDER GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); if (priv->picture) { @@ -496,7 +496,7 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window, GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) { -#ifdef HAVE_XRENDER +#if HAVE_XRENDER GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index bde150cd52..519048d862 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -27,7 +27,7 @@ #include "gstvaapiwindow_priv.h" -#ifdef HAVE_XRENDER +#if HAVE_XRENDER # include #endif @@ -49,7 +49,7 @@ struct _GstVaapiWindowX11Private { Atom atom_NET_WM_STATE; Atom atom_NET_WM_STATE_FULLSCREEN; -#ifdef HAVE_XRENDER +#if HAVE_XRENDER Picture picture; #endif guint is_mapped:1; From bb8894aaf934b3af4d44cf54e860510fe4d615b3 Mon Sep 17 00:00:00 2001 From: Tianhao Liu Date: Thu, 7 Jun 2018 09:34:11 +0800 Subject: [PATCH 3087/3781] libs: decoder: release VA buffers after vaEndPicture This change is due a problem decoding JPEGs with Intel's media-driver: no image was generated. This patch relases the VA buffers after vaEndPicture() is called, and not before (after vaRenderPicture()). https://bugzilla.gnome.org/show_bug.cgi?id=796505 --- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 20d4f55159..2dd4c27c27 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -304,12 +304,17 @@ gst_vaapi_picture_decode (GstVaapiPicture * picture) 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); } - status = vaEndPicture (va_display, va_context); if (!vaapi_check_status (status, "vaEndPicture()")) return FALSE; return TRUE; From 50470ae89f7abf76ef87530bca93559de1d19b41 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Tue, 24 Apr 2018 18:17:24 +0900 Subject: [PATCH 3088/3781] display: egl: create VaapiDisplayEGL with native EGL display gst_vaapi_display_egl_new_with_native_display() has been broken since it wasn't used. Currently it's needed to call this API to create a display providing the EGL display, so it could avoid duplicated calls to the native display (eg. eglTerminate). Signed-off-by: Victor Jaquez https://bugzilla.gnome.org/show_bug.cgi?id=795391 --- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 41 ++++++++++++++++-------- gst/vaapi/gstvaapipluginutil.c | 41 ++++++++++++++++++------ 2 files changed, 60 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index 884d0090a4..e32090675c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -50,6 +50,7 @@ typedef struct gpointer display; guint display_type; guint gles_version; + gpointer gl_display; } InitParams; static gboolean @@ -97,27 +98,36 @@ static gboolean gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_display, gpointer native_params) { - GstVaapiDisplay *native_display = NULL; + 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; - if (params->display) { - native_display = params->display; - } else { + native_vaapi_display = params->display; + native_egl_display = params->gl_display; + + if (!native_vaapi_display) { #if USE_X11 - native_display = gst_vaapi_display_x11_new (NULL); + 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_display) - native_display = gst_vaapi_display_wayland_new (NULL); + if (!native_vaapi_display) + native_vaapi_display = gst_vaapi_display_wayland_new (NULL); #endif + } else { + /* thus it could be unrefed */ + gst_object_ref (native_vaapi_display); } - if (!native_display) + if (!native_vaapi_display) return FALSE; - gst_vaapi_display_replace (&display->display, native_display); + gst_vaapi_display_replace (&display->display, native_vaapi_display); + gst_object_unref (native_vaapi_display); switch (GST_VAAPI_DISPLAY_GET_CLASS_TYPE (display->display)) { case GST_VAAPI_DISPLAY_TYPE_X11: @@ -130,8 +140,12 @@ gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_display, break; } - egl_display = egl_display_new (GST_VAAPI_DISPLAY_NATIVE (display->display), - gl_platform); + 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; @@ -385,13 +399,14 @@ GstVaapiDisplay * gst_vaapi_display_egl_new_with_native_display (gpointer native_display, GstVaapiDisplayType display_type, guint gles_version) { - InitParams params; + InitParams params = { NULL, }; g_return_val_if_fail (native_display != NULL, NULL); - params.display = native_display; params.display_type = display_type; params.gles_version = gles_version; + params.gl_display = native_display; + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_EGL, NULL), GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, ¶ms); } diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 648c91b9c6..1f3486d038 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -41,6 +41,9 @@ #endif #if USE_GST_GL_HELPERS # include +#if USE_EGL && GST_GL_HAVE_PLATFORM_EGL +# include +#endif #endif #include "gstvaapipluginutil.h" #include "gstvaapipluginbase.h" @@ -140,7 +143,7 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) gpointer native_display = GSIZE_TO_POINTER (gst_gl_display_get_handle (gl_display)); GstGLPlatform platform = gst_gl_context_get_gl_platform (gl_context); - GstVaapiDisplay *display, *out_display; + GstVaapiDisplay *display, *out_display = NULL; GstVaapiDisplayType display_type; switch (gst_gl_display_get_handle_type (gl_display)) { @@ -195,16 +198,25 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) display_type = GST_VAAPI_DISPLAY_TYPE_ANY; break; } - gst_object_unref (gl_display); display = gst_vaapi_create_display_from_handle (display_type, native_display); if (!display) - return NULL; + goto bail; switch (platform) { #if USE_EGL case GST_GL_PLATFORM_EGL:{ guint gles_version; + guintptr egl_handle = 0; +#if GST_GL_HAVE_PLATFORM_EGL + GstGLDisplayEGL *egl_display; + + egl_display = gst_gl_display_egl_from_gl_display (gl_display); + if (egl_display) { + egl_handle = gst_gl_display_get_handle (GST_GL_DISPLAY (egl_display)); + gst_object_unref (egl_display); + } +#endif switch (gst_gl_context_get_gl_api (gl_context)) { case GST_GL_API_GLES1: @@ -217,16 +229,21 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) case GST_GL_API_OPENGL3: gles_version = 0; create_egl_display: - out_display = gst_vaapi_display_egl_new (display, gles_version); + if (egl_handle != 0) { + out_display = + gst_vaapi_display_egl_new_with_native_display + (GSIZE_TO_POINTER (egl_handle), display_type, gles_version); + } else { + out_display = gst_vaapi_display_egl_new (display, gles_version); + } break; default: out_display = NULL; break; } - if (!out_display) { - gst_vaapi_display_unref (display); - return NULL; - } + if (!out_display) + goto bail; + gst_vaapi_display_egl_set_gl_context (GST_VAAPI_DISPLAY_EGL (out_display), GSIZE_TO_POINTER (gst_gl_context_get_gl_context (gl_context))); break; @@ -236,7 +253,13 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) out_display = gst_vaapi_display_ref (display); break; } - gst_vaapi_display_unref (display); + +bail: + if (display) + gst_vaapi_display_unref (display); + + if (gl_display) + gst_object_unref (gl_display); return out_display; #endif GST_ERROR ("unsupported GStreamer version %s", GST_API_VERSION_S); From e62f3d75cfd19d970e13ff363d25d32a5e0c668f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 27 Apr 2018 18:34:37 +0200 Subject: [PATCH 3089/3781] plugins: handle EGL when creating VAAPI display from gl If GstGL reports a EGL platform force to create a EGL display using the native EGL display. https://bugzilla.gnome.org/show_bug.cgi?id=795391 --- gst/vaapi/gstvaapipluginutil.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 1f3486d038..049ab13fce 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -143,7 +143,7 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) gpointer native_display = GSIZE_TO_POINTER (gst_gl_display_get_handle (gl_display)); GstGLPlatform platform = gst_gl_context_get_gl_platform (gl_context); - GstVaapiDisplay *display, *out_display = NULL; + GstVaapiDisplay *display = NULL, *out_display = NULL; GstVaapiDisplayType display_type; switch (gst_gl_display_get_handle_type (gl_display)) { @@ -162,11 +162,18 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) case GST_GL_DISPLAY_TYPE_WAYLAND: display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; break; +#endif +#if USE_EGL + case GST_GL_DISPLAY_TYPE_EGL: + display_type = GST_VAAPI_DISPLAY_TYPE_EGL; + goto egl_display; + break; #endif case GST_GL_DISPLAY_TYPE_ANY:{ /* Derive from the active window */ GstGLWindow *const gl_window = gst_gl_context_get_window (gl_context); const gchar *const gl_window_type = g_getenv ("GST_GL_WINDOW"); + const gchar *const gl_platform_type = g_getenv ("GST_GL_PLATFORM"); display_type = GST_VAAPI_DISPLAY_TYPE_ANY; if (!gl_window) @@ -181,6 +188,10 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) #if USE_WAYLAND if (!display_type && g_strcmp0 (gl_window_type, "wayland") == 0) display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; +#endif +#if USE_EGL + if (!display_type && g_strcmp0 (gl_platform_type, "egl") == 0) + display_type = GST_VAAPI_DISPLAY_TYPE_EGL; #endif } else { #if USE_X11 && GST_GL_HAVE_WINDOW_X11 @@ -189,9 +200,15 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) #elif USE_WAYLAND && GST_GL_HAVE_WINDOW_WAYLAND if (!display_type) display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; +#elif USE_EGL && GST_GL_HAVE_PLATFORM_EGL + if (!display_type) + display_type = GST_VAAPI_DISPLAY_TYPE_EGL; #endif } gst_object_unref (gl_window); + + if (display_type == GST_VAAPI_DISPLAY_TYPE_EGL) + goto egl_display; break; } default: @@ -203,6 +220,7 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) if (!display) goto bail; +egl_display: switch (platform) { #if USE_EGL case GST_GL_PLATFORM_EGL:{ @@ -233,7 +251,7 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) out_display = gst_vaapi_display_egl_new_with_native_display (GSIZE_TO_POINTER (egl_handle), display_type, gles_version); - } else { + } else if (display) { out_display = gst_vaapi_display_egl_new (display, gles_version); } break; From ad974b4c82ff20e2f7c69c59a96e7602266ba384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 27 Apr 2018 18:35:30 +0200 Subject: [PATCH 3090/3781] libs: display: egl: initialize params structure Statically initialise the internal params structure. https://bugzilla.gnome.org/show_bug.cgi?id=795391 --- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index e32090675c..6e83bd3e37 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -365,16 +365,15 @@ gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass) GstVaapiDisplay * gst_vaapi_display_egl_new (GstVaapiDisplay * display, guint gles_version) { - InitParams params; + InitParams params = { + .gles_version = gles_version, + }; if (display) { params.display = display; params.display_type = GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display); - } else { - params.display = NULL; - params.display_type = GST_VAAPI_DISPLAY_TYPE_ANY; } - params.gles_version = gles_version; + return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_EGL, NULL), GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, ¶ms); } @@ -399,14 +398,14 @@ GstVaapiDisplay * gst_vaapi_display_egl_new_with_native_display (gpointer native_display, GstVaapiDisplayType display_type, guint gles_version) { - InitParams params = { NULL, }; + InitParams params = { + .display_type = display_type, + .gl_display = native_display, + .gles_version = gles_version, + }; g_return_val_if_fail (native_display != NULL, NULL); - params.display_type = display_type; - params.gles_version = gles_version; - params.gl_display = native_display; - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_EGL, NULL), GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, ¶ms); } From b0bebebc015dc6cf82df847881a2a2f3b514bc8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 25 May 2018 12:17:21 +0200 Subject: [PATCH 3091/3781] libs: display: resurrect parent private member This is, practically, a revert of commit dcf135e2. The parent logic is useful for the EGL display, which is a decorator of the real windowing subsystem (X11 or Wayland). Thus it is avoided calling vaInitialize() and vaTerminate() twice. https://bugzilla.gnome.org/show_bug.cgi?id=795391 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 15 ++++++++++++--- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 5 +++-- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 1 + 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 39d7540d14..fb65e55987 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -827,7 +827,8 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) } if (priv->display) { - vaTerminate (priv->display); + if (!priv->parent) + vaTerminate (priv->display); priv->display = NULL; } @@ -842,6 +843,8 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) g_free (priv->vendor_string); priv->vendor_string = NULL; + + gst_vaapi_display_replace (&priv->parent, NULL); } static gboolean @@ -888,8 +891,10 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, if (!priv->display) return FALSE; - if (!vaapi_initialize (priv->display)) - return FALSE; + if (!priv->parent) { + if (!vaapi_initialize (priv->display)) + return FALSE; + } GST_INFO_OBJECT (display, "new display addr=%p", display); g_free (priv->display_name); @@ -909,6 +914,8 @@ gst_vaapi_display_lock_default (GstVaapiDisplay * display) { GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + if (priv->parent) + priv = GST_VAAPI_DISPLAY_GET_PRIVATE (priv->parent); g_rec_mutex_lock (&priv->mutex); } @@ -917,6 +924,8 @@ gst_vaapi_display_unlock_default (GstVaapiDisplay * display) { GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + if (priv->parent) + priv = GST_VAAPI_DISPLAY_GET_PRIVATE (priv->parent); g_rec_mutex_unlock (&priv->mutex); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index 6e83bd3e37..27d70743cc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -104,6 +104,7 @@ gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_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; @@ -120,14 +121,14 @@ gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_display, native_vaapi_display = gst_vaapi_display_wayland_new (NULL); #endif } else { - /* thus it could be unrefed */ + /* 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); - gst_object_unref (native_vaapi_display); + priv->parent = native_vaapi_display; switch (GST_VAAPI_DISPLAY_GET_CLASS_TYPE (display->display)) { case GST_VAAPI_DISPLAY_TYPE_X11: diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 0394a351c9..95272a79b0 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -109,6 +109,7 @@ typedef enum _GstVaapiDisplayInitType GstVaapiDisplayInitType; struct _GstVaapiDisplayPrivate { + GstVaapiDisplay *parent; GRecMutex mutex; gchar *display_name; VADisplay display; From 94709d49c6d4c4d595932d3f03a81d41a83d537a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 10 Jun 2018 10:44:35 +0200 Subject: [PATCH 3092/3781] plugins: refactor gst_vaapi_create_display_from_gl_context() gst_vaapi_create_display_from_gl_context() was a spaghetti mess. This path refactors it, in order to make the code readable and easy to follow. https://bugzilla.gnome.org/show_bug.cgi?id=796564 --- gst/vaapi/gstvaapipluginutil.c | 298 ++++++++++++++++++--------------- 1 file changed, 167 insertions(+), 131 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 049ab13fce..ed35b26cbe 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -134,153 +134,189 @@ gst_vaapi_create_display_from_handle (GstVaapiDisplayType display_type, } #endif +#if USE_GST_GL_HELPERS +static GstVaapiDisplayType +gst_vaapi_get_display_type_from_gl (GstGLDisplayType gl_display_type, + GstGLPlatform gl_platform) +{ + switch (gl_display_type) { +#if USE_X11 + case GST_GL_DISPLAY_TYPE_X11:{ +#if USE_GLX + if (gl_platform == GST_GL_PLATFORM_GLX) + return GST_VAAPI_DISPLAY_TYPE_GLX; +#endif +#endif + return GST_VAAPI_DISPLAY_TYPE_X11; + } +#if USE_WAYLAND + case GST_GL_DISPLAY_TYPE_WAYLAND:{ + return GST_VAAPI_DISPLAY_TYPE_WAYLAND; + } +#endif +#if USE_EGL + case GST_GL_DISPLAY_TYPE_EGL:{ + return GST_VAAPI_DISPLAY_TYPE_EGL; + } +#endif + default: + /* unsupported display. Still DRM may work. */ + break; + } + + return GST_VAAPI_DISPLAY_TYPE_ANY; +} + +static GstVaapiDisplayType +gst_vaapi_get_display_type_from_gl_env () +{ + const gchar *const gl_window_type = g_getenv ("GST_GL_WINDOW"); + const gchar *const gl_platform_type = g_getenv ("GST_GL_PLATFORM"); + + if (!gl_window_type) { +#if USE_X11 && GST_GL_HAVE_WINDOW_X11 + return GST_VAAPI_DISPLAY_TYPE_X11; +#elif USE_WAYLAND && GST_GL_HAVE_WINDOW_WAYLAND + return GST_VAAPI_DISPLAY_TYPE_WAYLAND; +#elif USE_EGL && GST_GL_HAVE_PLATFORM_EGL + return GST_VAAPI_DISPLAY_TYPE_EGL; +#endif + } +#if USE_X11 + if (g_strcmp0 (gl_window_type, "x11") == 0) + return GST_VAAPI_DISPLAY_TYPE_X11; +#endif +#if USE_WAYLAND + if (g_strcmp0 (gl_window_type, "wayland") == 0) + return GST_VAAPI_DISPLAY_TYPE_WAYLAND; +#endif +#if USE_EGL + if (g_strcmp0 (gl_platform_type, "egl") == 0) + return GST_VAAPI_DISPLAY_TYPE_EGL; +#endif + + return GST_VAAPI_DISPLAY_TYPE_ANY; +} + +static gint +gst_vaapi_get_gles_version_from_gl_api (GstGLAPI gl_api) +{ + switch (gl_api) { + case GST_GL_API_GLES1: + return 1; + case GST_GL_API_GLES2: + return 2; + case GST_GL_API_OPENGL: + case GST_GL_API_OPENGL3: + return 0; + default: + break; + } + return -1; +} + +static guintptr +gst_vaapi_get_egl_handle_from_gl_display (GstGLDisplay * gl_display) +{ + guintptr egl_handle = 0; + +#if USE_EGL && GST_GL_HAVE_PLATFORM_EGL + GstGLDisplayEGL *egl_display; + egl_display = gst_gl_display_egl_from_gl_display (gl_display); + if (egl_display) { + egl_handle = gst_gl_display_get_handle (GST_GL_DISPLAY (egl_display)); + gst_object_unref (egl_display); + } +#endif + return egl_handle; +} + +static GstVaapiDisplay * +gst_vaapi_create_display_from_egl (GstGLDisplay * gl_display, + GstGLContext * gl_context, GstVaapiDisplayType display_type, + gpointer native_display) +{ + GstGLAPI gl_api; + gint gles_version; + guintptr egl_handler; + GstVaapiDisplay *display = NULL; + + gl_api = gst_gl_context_get_gl_api (gl_context); + gles_version = gst_vaapi_get_gles_version_from_gl_api (gl_api); + if (gles_version == -1) + return NULL; + + egl_handler = gst_vaapi_get_egl_handle_from_gl_display (gl_display); + if (egl_handler != 0) { + gpointer native_display_egl = GSIZE_TO_POINTER (egl_handler); + display = gst_vaapi_display_egl_new_with_native_display (native_display_egl, + display_type, gles_version); + } + + if (!display) { + GstVaapiDisplay *wrapped_display; + + wrapped_display = + gst_vaapi_create_display_from_handle (display_type, native_display); + if (wrapped_display) { + display = gst_vaapi_display_egl_new (wrapped_display, gles_version); + gst_vaapi_display_unref (wrapped_display); + } + } + + if (display) { + gst_vaapi_display_egl_set_gl_context (GST_VAAPI_DISPLAY_EGL (display), + GSIZE_TO_POINTER (gst_gl_context_get_gl_context (gl_context))); + } + + return display; +} +#endif /* USE_GST_GL_HELPERS */ + static GstVaapiDisplay * gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object) { #if USE_GST_GL_HELPERS GstGLContext *const gl_context = GST_GL_CONTEXT (gl_context_object); GstGLDisplay *const gl_display = gst_gl_context_get_display (gl_context); - gpointer native_display = - GSIZE_TO_POINTER (gst_gl_display_get_handle (gl_display)); - GstGLPlatform platform = gst_gl_context_get_gl_platform (gl_context); - GstVaapiDisplay *display = NULL, *out_display = NULL; + GstGLDisplayType gl_display_type; + GstGLPlatform gl_platform; + gpointer native_display; + GstVaapiDisplay *display = NULL; GstVaapiDisplayType display_type; - switch (gst_gl_display_get_handle_type (gl_display)) { -#if USE_X11 - case GST_GL_DISPLAY_TYPE_X11: -#if USE_GLX - if (platform == GST_GL_PLATFORM_GLX) { - display_type = GST_VAAPI_DISPLAY_TYPE_GLX; - break; - } -#endif - display_type = GST_VAAPI_DISPLAY_TYPE_X11; - break; -#endif -#if USE_WAYLAND - case GST_GL_DISPLAY_TYPE_WAYLAND: - display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; - break; -#endif -#if USE_EGL - case GST_GL_DISPLAY_TYPE_EGL: - display_type = GST_VAAPI_DISPLAY_TYPE_EGL; - goto egl_display; - break; -#endif - case GST_GL_DISPLAY_TYPE_ANY:{ - /* Derive from the active window */ - GstGLWindow *const gl_window = gst_gl_context_get_window (gl_context); - const gchar *const gl_window_type = g_getenv ("GST_GL_WINDOW"); - const gchar *const gl_platform_type = g_getenv ("GST_GL_PLATFORM"); + /* Get display type and the native hanler */ + gl_display_type = gst_gl_display_get_handle_type (gl_display); + gl_platform = gst_gl_context_get_gl_platform (gl_context); + display_type = + gst_vaapi_get_display_type_from_gl (gl_display_type, gl_platform); - display_type = GST_VAAPI_DISPLAY_TYPE_ANY; - if (!gl_window) - break; + native_display = GSIZE_TO_POINTER (gst_gl_display_get_handle (gl_display)); + + if (display_type == GST_VAAPI_DISPLAY_TYPE_ANY) { + /* derive type and native_display from the active window */ + GstGLWindow *const gl_window = gst_gl_context_get_window (gl_context); + if (gl_window) native_display = GSIZE_TO_POINTER (gst_gl_window_get_display (gl_window)); - - if (gl_window_type) { -#if USE_X11 - if (!display_type && g_strcmp0 (gl_window_type, "x11") == 0) - display_type = GST_VAAPI_DISPLAY_TYPE_X11; -#endif -#if USE_WAYLAND - if (!display_type && g_strcmp0 (gl_window_type, "wayland") == 0) - display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; -#endif -#if USE_EGL - if (!display_type && g_strcmp0 (gl_platform_type, "egl") == 0) - display_type = GST_VAAPI_DISPLAY_TYPE_EGL; -#endif - } else { -#if USE_X11 && GST_GL_HAVE_WINDOW_X11 - if (!display_type) - display_type = GST_VAAPI_DISPLAY_TYPE_X11; -#elif USE_WAYLAND && GST_GL_HAVE_WINDOW_WAYLAND - if (!display_type) - display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND; -#elif USE_EGL && GST_GL_HAVE_PLATFORM_EGL - if (!display_type) - display_type = GST_VAAPI_DISPLAY_TYPE_EGL; -#endif - } - gst_object_unref (gl_window); - - if (display_type == GST_VAAPI_DISPLAY_TYPE_EGL) - goto egl_display; - break; - } - default: - display_type = GST_VAAPI_DISPLAY_TYPE_ANY; - break; + display_type = gst_vaapi_get_display_type_from_gl_env (); } - display = gst_vaapi_create_display_from_handle (display_type, native_display); - if (!display) - goto bail; - -egl_display: - switch (platform) { -#if USE_EGL - case GST_GL_PLATFORM_EGL:{ - guint gles_version; - guintptr egl_handle = 0; -#if GST_GL_HAVE_PLATFORM_EGL - GstGLDisplayEGL *egl_display; - - egl_display = gst_gl_display_egl_from_gl_display (gl_display); - if (egl_display) { - egl_handle = gst_gl_display_get_handle (GST_GL_DISPLAY (egl_display)); - gst_object_unref (egl_display); - } -#endif - - switch (gst_gl_context_get_gl_api (gl_context)) { - case GST_GL_API_GLES1: - gles_version = 1; - goto create_egl_display; - case GST_GL_API_GLES2: - gles_version = 2; - goto create_egl_display; - case GST_GL_API_OPENGL: - case GST_GL_API_OPENGL3: - gles_version = 0; - create_egl_display: - if (egl_handle != 0) { - out_display = - gst_vaapi_display_egl_new_with_native_display - (GSIZE_TO_POINTER (egl_handle), display_type, gles_version); - } else if (display) { - out_display = gst_vaapi_display_egl_new (display, gles_version); - } - break; - default: - out_display = NULL; - break; - } - if (!out_display) - goto bail; - - gst_vaapi_display_egl_set_gl_context (GST_VAAPI_DISPLAY_EGL (out_display), - GSIZE_TO_POINTER (gst_gl_context_get_gl_context (gl_context))); - break; - } -#endif - default: - out_display = gst_vaapi_display_ref (display); - break; + if (gl_platform == GST_GL_PLATFORM_EGL) { + display = gst_vaapi_create_display_from_egl (gl_display, gl_context, + display_type, native_display); } -bail: - if (display) - gst_vaapi_display_unref (display); + /* Non-EGL and fallback */ + if (!display) { + display = + gst_vaapi_create_display_from_handle (display_type, native_display); + } - if (gl_display) - gst_object_unref (gl_display); - return out_display; + gst_object_unref (gl_display); + + return display; #endif - GST_ERROR ("unsupported GStreamer version %s", GST_API_VERSION_S); + GST_ERROR ("No GstGL support"); return NULL; } From fc3eef9c432c1628cb92ab56e74924cf1182da30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 Apr 2018 18:05:30 +0200 Subject: [PATCH 3093/3781] build: meson: libva gst-uninstall friendly Make gstreamer-vaapi to use libva uninstalled. --- meson.build | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/meson.build b/meson.build index a5fa0afe7c..1d89091a3f 100644 --- a/meson.build +++ b/meson.build @@ -52,11 +52,17 @@ gstcodecparsers_dep = dependency('gstreamer-codecparsers-1.0', version : gst_req gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, fallback : ['gst-plugins-base', 'gstgl_dep'], required: false) gmodule_dep = dependency('gmodule-2.0', required: false) -libva_dep = dependency('libva', version: libva_req) -libva_drm_dep = dependency('libva-drm', version: '>= 0.33.0', required: false) -libva_wayland_dep = dependency('libva-wayland', version: '>= 0.33.0', required: false) -libva_x11_dep = dependency('libva-x11', version: '>= 0.31.0', required: false) + +libva_dep = dependency('libva', version: libva_req, + fallback : ['libva', 'libva_dep']) +libva_drm_dep = dependency('libva-drm', version: '>= 0.33.0', + fallback : ['libva', 'libva_drm_dep'], required: false) +libva_wayland_dep = dependency('libva-wayland', version: '>= 0.33.0', + fallback : ['libva', 'libva_wayland_dep'], required: false) +libva_x11_dep = dependency('libva-x11', version: '>= 0.31.0', + fallback : ['libva', 'libva_x11_dep'], required: false) + libdrm_dep = dependency('libdrm', required: false) libudev_dep = dependency('libudev', required: false) egl_dep = dependency('egl', required: false) @@ -82,16 +88,16 @@ if glesv2_dep.found() endif USE_ENCODERS = libva_dep.version().version_compare('>= 0.34.0') and get_option('with_encoders') != 'no' -USE_H265_DECODER = cc.has_header('va/va_dec_hevc.h', dependencies: libva_dep, prefix: '#include ') -USE_H265_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_hevc.h', dependencies: libva_dep, prefix: '#include ') -USE_JPEG_DECODER = cc.has_header('va/va_dec_jpeg.h', dependencies: libva_dep, prefix: '#include ') -USE_JPEG_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_jpeg.h', dependencies: libva_dep, prefix: '#include ') -USE_VP8_DECODER = cc.has_header('va/va_dec_vp8.h', dependencies: libva_dep, prefix: '#include ') -USE_VP8_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp8.h', dependencies: libva_dep, prefix: '#include ') -USE_VP9_DECODER = cc.has_header('va/va_dec_vp9.h', dependencies: libva_dep, prefix: '#include ') -USE_VP9_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp9.h', dependencies: libva_dep, prefix: '#include ') +USE_H265_DECODER = libva_dep.version().version_compare('>= 0.38.0') +USE_H265_ENCODER = USE_ENCODERS and libva_dep.version().version_compare('>= 0.38.0') +USE_JPEG_DECODER = libva_dep.version().version_compare('>= 0.34.0') +USE_JPEG_ENCODER = USE_ENCODERS and libva_dep.version().version_compare('>= 0.38.0') +USE_VP8_DECODER = libva_dep.version().version_compare('>= 0.36.0') +USE_VP8_ENCODER = USE_ENCODERS and libva_dep.version().version_compare('>= 0.36.0') +USE_VP9_DECODER = libva_dep.version().version_compare('>= 0.39.0') +USE_VP9_ENCODER = USE_ENCODERS and libva_dep.version().version_compare('>= 0.40.0') -USE_VPP = cc.has_header('va/va_vpp.h', dependencies: libva_dep, prefix: '#include ') +USE_VPP = libva_dep.version().version_compare('>= 0.34.0') USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() and get_option('with_drm') != 'no' USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no' @@ -99,7 +105,12 @@ USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl USE_WAYLAND = libva_wayland_dep.found() and wayland_client_dep.found() and get_option('with_wayland') != 'no' USE_X11 = libva_x11_dep.found() and x11_dep.found() and get_option('with_x11') != 'no' -driverdir = libva_dep.get_pkgconfig_variable('driverdir') +if libva_dep.type_name() == 'pkgconfig' + driverdir = libva_dep.get_pkgconfig_variable('driverdir') +else + libva = subproject('libva') + driverdir = libva.get_variable('driverdir') +endif if driverdir == '' driverdir = '@0@/@1@/@2@'.format(get_option('prefix'), get_option('libdir'), 'dri') endif @@ -154,13 +165,11 @@ if libva_dep.version().version_compare('< 0.38.0') if USE_ENCODERS check_headers = [ - ['HAVE_VA_VA_ENC_MPEG2_H', 'va/va_enc_mpeg2.h'], - ['HAVE_VA_VA_ENC_H264_H', 'va/va_enc_h264.h'], + 'HAVE_VA_VA_ENC_MPEG2_H', + 'HAVE_VA_VA_ENC_H264_H', ] foreach h : check_headers - if cc.has_header(h.get(1), dependencies: libva_dep, prefix: '#include ') - cdata.set(h.get(0), 1) - endif + cdata.set(h, 1) endforeach endif endif From 19e4769501d80e54c450ca87314566cf1436f289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 12 Jun 2018 15:13:33 +0200 Subject: [PATCH 3094/3781] plugins: fix compilation gstvaapipluginutil.c:171:1: error: old-style function definition [-Werror=old-style-definition] --- gst/vaapi/gstvaapipluginutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ed35b26cbe..0babf83a31 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -168,7 +168,7 @@ gst_vaapi_get_display_type_from_gl (GstGLDisplayType gl_display_type, } static GstVaapiDisplayType -gst_vaapi_get_display_type_from_gl_env () +gst_vaapi_get_display_type_from_gl_env (void) { const gchar *const gl_window_type = g_getenv ("GST_GL_WINDOW"); const gchar *const gl_platform_type = g_getenv ("GST_GL_PLATFORM"); From d4843848b5b812f99891d66d5efafa1e6f8a38e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 12 Jun 2018 15:53:04 +0200 Subject: [PATCH 3095/3781] Revert "build: meson: libva gst-uninstall friendly" This reverts commit fc3eef9c432c1628cb92ab56e74924cf1182da30. --- meson.build | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/meson.build b/meson.build index 1d89091a3f..a5fa0afe7c 100644 --- a/meson.build +++ b/meson.build @@ -52,17 +52,11 @@ gstcodecparsers_dep = dependency('gstreamer-codecparsers-1.0', version : gst_req gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, fallback : ['gst-plugins-base', 'gstgl_dep'], required: false) gmodule_dep = dependency('gmodule-2.0', required: false) +libva_dep = dependency('libva', version: libva_req) - -libva_dep = dependency('libva', version: libva_req, - fallback : ['libva', 'libva_dep']) -libva_drm_dep = dependency('libva-drm', version: '>= 0.33.0', - fallback : ['libva', 'libva_drm_dep'], required: false) -libva_wayland_dep = dependency('libva-wayland', version: '>= 0.33.0', - fallback : ['libva', 'libva_wayland_dep'], required: false) -libva_x11_dep = dependency('libva-x11', version: '>= 0.31.0', - fallback : ['libva', 'libva_x11_dep'], required: false) - +libva_drm_dep = dependency('libva-drm', version: '>= 0.33.0', required: false) +libva_wayland_dep = dependency('libva-wayland', version: '>= 0.33.0', required: false) +libva_x11_dep = dependency('libva-x11', version: '>= 0.31.0', required: false) libdrm_dep = dependency('libdrm', required: false) libudev_dep = dependency('libudev', required: false) egl_dep = dependency('egl', required: false) @@ -88,16 +82,16 @@ if glesv2_dep.found() endif USE_ENCODERS = libva_dep.version().version_compare('>= 0.34.0') and get_option('with_encoders') != 'no' -USE_H265_DECODER = libva_dep.version().version_compare('>= 0.38.0') -USE_H265_ENCODER = USE_ENCODERS and libva_dep.version().version_compare('>= 0.38.0') -USE_JPEG_DECODER = libva_dep.version().version_compare('>= 0.34.0') -USE_JPEG_ENCODER = USE_ENCODERS and libva_dep.version().version_compare('>= 0.38.0') -USE_VP8_DECODER = libva_dep.version().version_compare('>= 0.36.0') -USE_VP8_ENCODER = USE_ENCODERS and libva_dep.version().version_compare('>= 0.36.0') -USE_VP9_DECODER = libva_dep.version().version_compare('>= 0.39.0') -USE_VP9_ENCODER = USE_ENCODERS and libva_dep.version().version_compare('>= 0.40.0') +USE_H265_DECODER = cc.has_header('va/va_dec_hevc.h', dependencies: libva_dep, prefix: '#include ') +USE_H265_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_hevc.h', dependencies: libva_dep, prefix: '#include ') +USE_JPEG_DECODER = cc.has_header('va/va_dec_jpeg.h', dependencies: libva_dep, prefix: '#include ') +USE_JPEG_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_jpeg.h', dependencies: libva_dep, prefix: '#include ') +USE_VP8_DECODER = cc.has_header('va/va_dec_vp8.h', dependencies: libva_dep, prefix: '#include ') +USE_VP8_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp8.h', dependencies: libva_dep, prefix: '#include ') +USE_VP9_DECODER = cc.has_header('va/va_dec_vp9.h', dependencies: libva_dep, prefix: '#include ') +USE_VP9_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp9.h', dependencies: libva_dep, prefix: '#include ') -USE_VPP = libva_dep.version().version_compare('>= 0.34.0') +USE_VPP = cc.has_header('va/va_vpp.h', dependencies: libva_dep, prefix: '#include ') USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() and get_option('with_drm') != 'no' USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no' @@ -105,12 +99,7 @@ USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl USE_WAYLAND = libva_wayland_dep.found() and wayland_client_dep.found() and get_option('with_wayland') != 'no' USE_X11 = libva_x11_dep.found() and x11_dep.found() and get_option('with_x11') != 'no' -if libva_dep.type_name() == 'pkgconfig' - driverdir = libva_dep.get_pkgconfig_variable('driverdir') -else - libva = subproject('libva') - driverdir = libva.get_variable('driverdir') -endif +driverdir = libva_dep.get_pkgconfig_variable('driverdir') if driverdir == '' driverdir = '@0@/@1@/@2@'.format(get_option('prefix'), get_option('libdir'), 'dri') endif @@ -165,11 +154,13 @@ if libva_dep.version().version_compare('< 0.38.0') if USE_ENCODERS check_headers = [ - 'HAVE_VA_VA_ENC_MPEG2_H', - 'HAVE_VA_VA_ENC_H264_H', + ['HAVE_VA_VA_ENC_MPEG2_H', 'va/va_enc_mpeg2.h'], + ['HAVE_VA_VA_ENC_H264_H', 'va/va_enc_h264.h'], ] foreach h : check_headers - cdata.set(h, 1) + if cc.has_header(h.get(1), dependencies: libva_dep, prefix: '#include ') + cdata.set(h.get(0), 1) + endif endforeach endif endif From 8de7dcfe3cc1e23387ed88a3d4b7726a160b24b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 13 Jun 2018 17:05:40 +0200 Subject: [PATCH 3096/3781] libs: display: redefine gst_vaapi_display_create() The function name was gst_vaapi_display_create_unlocked(), nonetheless it wasn't called unlocked. In order to keep the semantics this patch renames the gst_vaapi_display_create_unlocked() as gst_vaapi_display_create(), removing the previous function gst_vaapi_display_create(). https://bugzilla.gnome.org/show_bug.cgi?id=796470 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index fb65e55987..1fffcbb2d4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -848,7 +848,7 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) } static gboolean -gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, +gst_vaapi_display_create (GstVaapiDisplay * display, GstVaapiDisplayInitType init_type, gpointer data) { GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); @@ -902,13 +902,6 @@ gst_vaapi_display_create_unlocked (GstVaapiDisplay * display, return TRUE; } -static gboolean -gst_vaapi_display_create (GstVaapiDisplay * display, - GstVaapiDisplayInitType init_type, gpointer init_value) -{ - return gst_vaapi_display_create_unlocked (display, init_type, init_value); -} - static void gst_vaapi_display_lock_default (GstVaapiDisplay * display) { From a6881b9b5eb55ef080387fc81cbbfdaf4bb9ec64 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 1 Jun 2018 12:36:51 +0900 Subject: [PATCH 3097/3781] libs: display: replace gst_vaapi_display_new() with gst_vaapi_display_config() Gobjectification for GstVaapiDisplay was almost done by the commit 185da3d1. But still something breaking GObject code convention remains, which is calling gst_vaapi_display_new() in each decendants. This patch replaces it with gst_vaapi_display_config(), defined in private header. https://bugzilla.gnome.org/show_bug.cgi?id=796470 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 21 +++++++++++++--- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 9 ++++--- gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 8 ++++-- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 10 ++++++-- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 26 ++++++++++++++------ gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 14 ++++++++--- 7 files changed, 68 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 1fffcbb2d4..d8579959a6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1143,11 +1143,24 @@ gst_vaapi_display_class_init (GstVaapiDisplayClass * klass) g_object_class_install_properties (object_class, N_PROPERTIES, g_properties); } +/** + * gst_vaapi_display_config: + * @display: instance of #GstVaapiDisplay + * @init_type: type of initialization #GstVaapiDisplayInitType + * @init_value: a pointer to the structure with the initialization + * parameters + * + * Binds @display to the VA layer; otherwise it is just an empty + * structure. + * + * Returns: the configured @display if it was configured correctly; + * otherwise unrefs @display and returns %NULL. + **/ GstVaapiDisplay * -gst_vaapi_display_new (GstVaapiDisplay * display, +gst_vaapi_display_config (GstVaapiDisplay * display, GstVaapiDisplayInitType init_type, gpointer init_value) { - g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (display && GST_VAAPI_IS_DISPLAY (display), NULL); if (!gst_vaapi_display_create (display, init_type, init_value)) goto error; @@ -1156,7 +1169,7 @@ gst_vaapi_display_new (GstVaapiDisplay * display, /* ERRORS */ error: { - gst_vaapi_display_unref (display); + gst_object_unref (display); return NULL; } } @@ -1177,7 +1190,7 @@ gst_vaapi_display_new_with_display (VADisplay va_display) .va_display = va_display, }; - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY, NULL), + return gst_vaapi_display_config (g_object_new (GST_TYPE_VAAPI_DISPLAY, NULL), GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, &info); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index ef68187aad..ea05289e44 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -395,8 +395,8 @@ gst_vaapi_display_drm_new (const gchar * device_path) for (i = 0; i < num_types; i++) { g_drm_device_type = types[i]; - display = - gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_DRM, NULL), + display = g_object_new (GST_TYPE_VAAPI_DISPLAY_DRM, NULL); + display = gst_vaapi_display_config (display, GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) device_path); if (display || device_path) break; @@ -419,9 +419,12 @@ gst_vaapi_display_drm_new (const gchar * device_path) GstVaapiDisplay * gst_vaapi_display_drm_new_with_device (gint device) { + GstVaapiDisplay *display; + g_return_val_if_fail (device >= 0, NULL); - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_DRM, 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)); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index 27d70743cc..fcffecdbcb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -366,6 +366,7 @@ gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass) GstVaapiDisplay * gst_vaapi_display_egl_new (GstVaapiDisplay * display, guint gles_version) { + GstVaapiDisplay *wrapper_display; InitParams params = { .gles_version = gles_version, }; @@ -375,7 +376,8 @@ gst_vaapi_display_egl_new (GstVaapiDisplay * display, guint gles_version) params.display_type = GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display); } - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_EGL, NULL), + 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); } @@ -399,6 +401,7 @@ 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, @@ -407,7 +410,8 @@ gst_vaapi_display_egl_new_with_native_display (gpointer native_display, g_return_val_if_fail (native_display != NULL, NULL); - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_EGL, 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); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 94686c631d..f75ab90f84 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -128,7 +128,10 @@ gst_vaapi_display_glx_class_init (GstVaapiDisplayGLXClass * klass) GstVaapiDisplay * gst_vaapi_display_glx_new (const gchar * display_name) { - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_GLX, NULL), + 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); } @@ -146,8 +149,11 @@ gst_vaapi_display_glx_new (const gchar * display_name) GstVaapiDisplay * gst_vaapi_display_glx_new_with_display (Display * x11_display) { + GstVaapiDisplay *display; + g_return_val_if_fail (x11_display != NULL, NULL); - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_GLX, 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); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 95272a79b0..9a34ba8cd0 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -201,7 +201,7 @@ enum _GstVaapiDisplayInitType }; GstVaapiDisplay * -gst_vaapi_display_new (GstVaapiDisplay * display, +gst_vaapi_display_config (GstVaapiDisplay * display, GstVaapiDisplayInitType init_type, gpointer init_value); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index b06f3883a4..8fde3efbdc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -325,9 +325,11 @@ gst_vaapi_display_wayland_class_init (GstVaapiDisplayWaylandClass * klass) GstVaapiDisplay * gst_vaapi_display_wayland_new (const gchar * display_name) { - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_WAYLAND, - NULL), GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, - (gpointer) 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); } /** @@ -344,10 +346,13 @@ gst_vaapi_display_wayland_new (const gchar * display_name) GstVaapiDisplay * gst_vaapi_display_wayland_new_with_display (struct wl_display * wl_display) { + GstVaapiDisplay *display; + g_return_val_if_fail (wl_display, NULL); - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_WAYLAND, - NULL), GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, wl_display); + 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); } /** @@ -368,6 +373,7 @@ 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, @@ -375,8 +381,14 @@ gst_vaapi_display_wayland_new_with_va_display (VADisplay va_display, g_return_val_if_fail (wl_display, NULL); - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_WAYLAND, - NULL), GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, &info); + 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; } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index f7517b10fe..6a3fdbe748 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -348,7 +348,10 @@ gst_vaapi_display_x11_init (GstVaapiDisplayX11 * display) GstVaapiDisplay * gst_vaapi_display_x11_new (const gchar * display_name) { - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_X11, NULL), + 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); } @@ -366,9 +369,12 @@ gst_vaapi_display_x11_new (const gchar * display_name) GstVaapiDisplay * gst_vaapi_display_x11_new_with_display (Display * x11_display) { + GstVaapiDisplay *display; + g_return_val_if_fail (x11_display, NULL); - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_X11, 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); } @@ -376,6 +382,7 @@ 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, @@ -383,7 +390,8 @@ gst_vaapi_display_x11_new_with_va_display (VADisplay va_display, g_return_val_if_fail (x11_display, NULL); - return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY_X11, 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); } From b1d8c689213838a9221ed160580a7285db3a615c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 13 Jun 2018 18:10:28 +0200 Subject: [PATCH 3098/3781] vaapibufferpool: declare parameter display as object We have neglected to update this code since GstVaapiDisplay turned into a GstObject descendant. https://bugzilla.gnome.org/show_bug.cgi?id=796470 --- gst/vaapi/gstvaapivideobufferpool.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 51539e278c..804d4f6ffc 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -77,7 +77,7 @@ gst_vaapi_video_buffer_pool_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_DISPLAY: - priv->display = gst_vaapi_display_ref (g_value_get_pointer (value)); + priv->display = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -516,10 +516,9 @@ gst_vaapi_video_buffer_pool_class_init (GstVaapiVideoBufferPoolClass * klass) g_object_class_install_property (object_class, PROP_DISPLAY, - g_param_spec_pointer ("display", - "Display", + g_param_spec_object ("display", "Display", "The GstVaapiDisplay to use for this video pool", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + GST_TYPE_VAAPI_DISPLAY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void From fb1c4c52ccd5b258d0968da7752200655c067809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 13 Jun 2018 17:54:23 +0200 Subject: [PATCH 3099/3781] libs: display: remove gst_vaapi_display_unref() Use gst_object_unref() instead. https://bugzilla.gnome.org/show_bug.cgi?id=796470 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 13 ------------- gst-libs/gst/vaapi/gstvaapidisplay.h | 5 +---- gst/vaapi/gstvaapi.c | 4 ++-- gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapiencode.c | 2 +- gst/vaapi/gstvaapipluginbase.c | 4 ++-- gst/vaapi/gstvaapipluginutil.c | 6 +++--- tests/output.c | 4 ++-- tests/simple-encoder.c | 2 +- tests/test-decode.c | 4 ++-- tests/test-display.c | 18 +++++++++--------- tests/test-fei-enc-in.c | 2 +- tests/test-filter.c | 2 +- tests/test-subpicture.c | 2 +- tests/test-surfaces.c | 2 +- tests/test-textures.c | 2 +- tests/test-windows.c | 6 +++--- 17 files changed, 32 insertions(+), 48 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index d8579959a6..9b7dbd11b7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1208,19 +1208,6 @@ gst_vaapi_display_ref (GstVaapiDisplay * display) return gst_object_ref (display); } -/** - * gst_vaapi_display_unref: - * @display: a #GstVaapiDisplay - * - * Atomically decreases the reference count of the @display by one. If - * the reference count reaches zero, the display will be free'd. - */ -void -gst_vaapi_display_unref (GstVaapiDisplay * display) -{ - gst_object_unref (display); -} - /** * gst_vaapi_display_replace: * @old_display_ptr: a pointer to a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 319faaa17a..203c78a6f1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -154,9 +154,6 @@ gst_vaapi_display_new_with_display (VADisplay va_display); GstVaapiDisplay * gst_vaapi_display_ref (GstVaapiDisplay * display); -void -gst_vaapi_display_unref (GstVaapiDisplay * display); - void gst_vaapi_display_replace (GstVaapiDisplay ** old_display_ptr, GstVaapiDisplay * new_display); @@ -258,7 +255,7 @@ void gst_vaapi_display_reset_texture_map (GstVaapiDisplay * display); #ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDisplay, gst_vaapi_display_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDisplay, gst_object_unref) #endif G_END_DECLS diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 9a82454406..7b0066469e 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -244,7 +244,7 @@ plugin_init (GstPlugin * plugin) gst_vaapiencode_register (plugin, display); #endif - gst_vaapi_display_unref (display); + gst_object_unref (display); return TRUE; @@ -258,7 +258,7 @@ error_no_display: } unsupported_driver: { - gst_vaapi_display_unref (display); + gst_object_unref (display); return TRUE; /* return TRUE to avoid get blacklisted */ } } diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b4a531b048..456ec8b1c5 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1085,7 +1085,7 @@ gst_vaapidecode_start (GstVideoDecoder * vdec) success = gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (decode)); if (old_display) - gst_vaapi_display_unref (old_display); + gst_object_unref (old_display); return success; } diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 159cd85947..97cfd0dcbf 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -530,7 +530,7 @@ gst_vaapiencode_open (GstVideoEncoder * venc) GST_VAAPI_PLUGIN_BASE_DISPLAY (encode) = NULL; success = ensure_display (encode); if (old_display) - gst_vaapi_display_unref (old_display); + gst_object_unref (old_display); return success; } diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index d23b519ab9..f1359e5e20 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -57,7 +57,7 @@ plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) plugin->display_type = gst_vaapi_display_get_display_type (display); gst_vaapi_plugin_base_set_display_name (plugin, display_name); } - gst_vaapi_display_unref (display); + gst_object_unref (display); } /** @@ -1313,7 +1313,7 @@ bail: g_array_unref (out_formats); if (surface) gst_vaapi_object_unref (surface); - gst_vaapi_display_unref (display); + gst_object_unref (display); return ret; } diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 0babf83a31..a391978263 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -260,7 +260,7 @@ gst_vaapi_create_display_from_egl (GstGLDisplay * gl_display, gst_vaapi_create_display_from_handle (display_type, native_display); if (wrapped_display) { display = gst_vaapi_display_egl_new (wrapped_display, gles_version); - gst_vaapi_display_unref (wrapped_display); + gst_object_unref (wrapped_display); } } @@ -397,7 +397,7 @@ gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type) return FALSE; gst_vaapi_video_context_propagate (element, display); - gst_vaapi_display_unref (display); + gst_object_unref (display); return TRUE; } @@ -887,7 +887,7 @@ gst_video_info_force_nv12_if_encoded (GstVideoInfo * vinfo) * supported features. * * Returns: a new #GstVaapiDisplay instances. Free with - * gst_vaapi_display_unref () after use. Or %NULL if no VA display is + * gst_object_unref () after use. Or %NULL if no VA display is * available. **/ GstVaapiDisplay * diff --git a/tests/output.c b/tests/output.c index b15dedec77..3469fd39aa 100644 --- a/tests/output.c +++ b/tests/output.c @@ -182,7 +182,7 @@ video_output_create_display (const gchar * display_name) if (display) { if (gst_vaapi_display_get_display (display)) break; - gst_vaapi_display_unref (display); + gst_object_unref (display); display = NULL; } } @@ -203,7 +203,7 @@ video_output_create_display (const gchar * display_name) egl_display = NULL; g_print ("error: unsupported EGL renderering mode\n"); #endif - gst_vaapi_display_unref (display); + gst_object_unref (display); if (!egl_display) return NULL; display = egl_display; diff --git a/tests/simple-encoder.c b/tests/simple-encoder.c index 58b0e8c214..9ae63d87db 100644 --- a/tests/simple-encoder.c +++ b/tests/simple-encoder.c @@ -302,7 +302,7 @@ app_free (App * app) } if (app->display) - gst_vaapi_display_unref (app->display); + gst_object_unref (app->display); if (app->output_file) fclose (app->output_file); diff --git a/tests/test-decode.c b/tests/test-decode.c index 882bfd2e2b..d44ac4388e 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -136,8 +136,8 @@ main (int argc, char *argv[]) gst_vaapi_surface_proxy_unref (proxy); gst_vaapi_decoder_unref (decoder); gst_vaapi_window_unref (window); - gst_vaapi_display_unref (display); - gst_vaapi_display_unref (display2); + gst_object_unref (display); + gst_object_unref (display2); g_free (g_codec_str); video_output_exit (); return 0; diff --git a/tests/test-display.c b/tests/test-display.c index d81e903046..e189ab3272 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -222,7 +222,7 @@ main (int argc, char *argv[]) g_error ("could not create Gst/VA display"); dump_info (display); - gst_vaapi_display_unref (display); + gst_object_unref (display); } g_print ("\n"); @@ -241,7 +241,7 @@ main (int argc, char *argv[]) g_error ("could not create Gst/VA display"); dump_info (display); - gst_vaapi_display_unref (display); + gst_object_unref (display); close (drm_device); } g_print ("\n"); @@ -267,7 +267,7 @@ main (int argc, char *argv[]) g_error ("could not create Gst/VA display"); dump_info (display); - gst_vaapi_display_unref (display); + gst_object_unref (display); close (drm_device); } g_print ("\n"); @@ -299,7 +299,7 @@ main (int argc, char *argv[]) g_error ("could not create Gst/VA display"); dump_info (display); - gst_vaapi_display_unref (display); + gst_object_unref (display); XCloseDisplay (x11_display); } g_print ("\n"); @@ -325,7 +325,7 @@ main (int argc, char *argv[]) g_error ("could not create Gst/VA display"); dump_info (display); - gst_vaapi_display_unref (display); + gst_object_unref (display); XCloseDisplay (x11_display); } g_print ("\n"); @@ -347,7 +347,7 @@ main (int argc, char *argv[]) g_print ("Pixel aspect ratio: %u/%u\n", par_n, par_d); dump_info (display); - gst_vaapi_display_unref (display); + gst_object_unref (display); } g_print ("\n"); @@ -366,7 +366,7 @@ main (int argc, char *argv[]) g_error ("could not create Gst/VA display"); dump_info (display); - gst_vaapi_display_unref (display); + gst_object_unref (display); XCloseDisplay (x11_display); } g_print ("\n"); @@ -393,7 +393,7 @@ main (int argc, char *argv[]) g_error ("could not create Gst/VA display"); dump_info (display); - gst_vaapi_display_unref (display); + gst_object_unref (display); XCloseDisplay (x11_display); } g_print ("\n"); @@ -416,7 +416,7 @@ main (int argc, char *argv[]) g_print ("Pixel aspect ratio: %u/%u\n", par_n, par_d); dump_info (display); - gst_vaapi_display_unref (display); + gst_object_unref (display); } g_print ("\n"); #endif diff --git a/tests/test-fei-enc-in.c b/tests/test-fei-enc-in.c index 2f7d698e4a..10d8de7cb3 100644 --- a/tests/test-fei-enc-in.c +++ b/tests/test-fei-enc-in.c @@ -346,7 +346,7 @@ app_free (App * app) } if (app->display) - gst_vaapi_display_unref (app->display); + gst_object_unref (app->display); if (app->output_file) fclose (app->output_file); diff --git a/tests/test-filter.c b/tests/test-filter.c index 6fdc8b6e95..380ca67b86 100644 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -444,7 +444,7 @@ main (int argc, char *argv[]) gst_vaapi_object_unref (dst_surface); gst_vaapi_object_unref (src_surface); gst_vaapi_window_unref (window); - gst_vaapi_display_unref (display); + gst_object_unref (display); video_output_exit (); g_free (g_src_format_str); g_free (g_crop_rect_str); diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index b842572196..588e7a7b59 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -166,7 +166,7 @@ main (int argc, char *argv[]) gst_vaapi_surface_proxy_unref (proxy); gst_vaapi_decoder_unref (decoder); gst_vaapi_window_unref (window); - gst_vaapi_display_unref (display); + gst_object_unref (display); g_free (g_codec_str); video_output_exit (); return 0; diff --git a/tests/test-surfaces.c b/tests/test-surfaces.c index b58c5cf859..2f9a90fae7 100644 --- a/tests/test-surfaces.c +++ b/tests/test-surfaces.c @@ -98,7 +98,7 @@ main (int argc, char *argv[]) } /* Unref in random order to check objects are correctly refcounted */ - gst_vaapi_display_unref (display); + gst_object_unref (display); gst_vaapi_video_pool_unref (pool); gst_vaapi_object_unref (surface); video_output_exit (); diff --git a/tests/test-textures.c b/tests/test-textures.c index a2d2005f46..97c82df527 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -173,7 +173,7 @@ main (int argc, char *argv[]) glDeleteTextures (1, &texture_id); gst_vaapi_window_unref (window); - gst_vaapi_display_unref (display); + gst_object_unref (display); gst_deinit (); return 0; } diff --git a/tests/test-windows.c b/tests/test-windows.c index aaffb03bba..28b2683a17 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -135,7 +135,7 @@ main (int argc, char *argv[]) } gst_vaapi_object_unref (surface); - gst_vaapi_display_unref (display); + gst_object_unref (display); #endif #if USE_X11 @@ -200,7 +200,7 @@ main (int argc, char *argv[]) } gst_vaapi_object_unref (surface); - gst_vaapi_display_unref (display); + gst_object_unref (display); #endif #if USE_WAYLAND @@ -230,7 +230,7 @@ main (int argc, char *argv[]) } gst_vaapi_object_unref (surface); - gst_vaapi_display_unref (display); + gst_object_unref (display); #endif gst_deinit (); From 6ccd5d6fb2b674fcd82c148918755569616355d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 13 Jun 2018 18:00:18 +0200 Subject: [PATCH 3100/3781] libs: display: remove gst_vaapi_display_ref() Replace it with gst_object_ref() https://bugzilla.gnome.org/show_bug.cgi?id=796470 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 14 -------------- gst-libs/gst/vaapi/gstvaapidisplay.h | 3 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- gst-libs/gst/vaapi/gstvaapifilter.c | 2 +- gst-libs/gst/vaapi/gstvaapiobject.c | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 2 +- gst/vaapi/gstvaapipluginbase.c | 2 +- gst/vaapi/gstvaapivideometa.c | 2 +- tests/test-decode.c | 2 +- 10 files changed, 8 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 9e716db2c9..c7157f9d02 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -500,7 +500,7 @@ gst_vaapi_decoder_init (GstVaapiDecoder * decoder, GstVaapiDisplay * display, gst_video_info_init (&codec_state->info); decoder->user_data = NULL; - decoder->display = gst_vaapi_display_ref (display); + decoder->display = gst_object_ref (display); decoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY (display); decoder->context = NULL; decoder->va_context = VA_INVALID_ID; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 9b7dbd11b7..7c6588afb7 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1194,20 +1194,6 @@ gst_vaapi_display_new_with_display (VADisplay va_display) GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, &info); } -/** - * gst_vaapi_display_ref: - * @display: a #GstVaapiDisplay - * - * Atomically increases the reference count of the given @display by one. - * - * Returns: The same @display argument - */ -GstVaapiDisplay * -gst_vaapi_display_ref (GstVaapiDisplay * display) -{ - return gst_object_ref (display); -} - /** * gst_vaapi_display_replace: * @old_display_ptr: a pointer to a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 203c78a6f1..11e60bdfe8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -151,9 +151,6 @@ struct _GstVaapiDisplayInfo GstVaapiDisplay * gst_vaapi_display_new_with_display (VADisplay va_display); -GstVaapiDisplay * -gst_vaapi_display_ref (GstVaapiDisplay * display); - void gst_vaapi_display_replace (GstVaapiDisplay ** old_display_ptr, GstVaapiDisplay * new_display); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index caddb75478..619aaf5323 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1401,7 +1401,7 @@ gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) #undef CHECK_VTABLE_HOOK - encoder->display = gst_vaapi_display_ref (display); + encoder->display = gst_object_ref (display); encoder->va_display = gst_vaapi_display_get_display (display); encoder->va_context = VA_INVALID_ID; diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 388fff3ded..3a96b82e3a 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1030,7 +1030,7 @@ gst_vaapi_filter_init (GstVaapiFilter * filter, GstVaapiDisplay * display) { VAStatus va_status; - filter->display = gst_vaapi_display_ref (display); + filter->display = gst_object_ref (display); filter->va_display = GST_VAAPI_DISPLAY_VADISPLAY (display); filter->va_config = VA_INVALID_ID; filter->va_context = VA_INVALID_ID; diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 8609ef7791..8130f80427 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -91,7 +91,7 @@ gst_vaapi_object_new (const GstVaapiObjectClass * klass, if (!object) return NULL; - object->display = gst_vaapi_display_ref (display); + object->display = gst_object_ref (display); object->object_id = VA_INVALID_ID; sub_size = object_class->size - sizeof (*object); diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 4ec1736ddf..b27e1db55b 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -60,7 +60,7 @@ gst_vaapi_video_pool_init (GstVaapiVideoPool * pool, GstVaapiDisplay * display, GstVaapiVideoPoolObjectType object_type) { pool->object_type = object_type; - pool->display = gst_vaapi_display_ref (display); + pool->display = gst_object_ref (display); pool->used_objects = NULL; pool->used_count = 0; pool->capacity = 0; diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index f1359e5e20..fad30b10de 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1269,7 +1269,7 @@ ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) out_formats = formats = NULL; surface = NULL; - display = gst_vaapi_display_ref (plugin->display); + display = gst_object_ref (plugin->display); formats = gst_vaapi_display_get_image_formats (display); if (!formats) goto bail; diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index a8ddf0501f..08040a9de1 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -226,7 +226,7 @@ gst_vaapi_video_meta_copy (GstVaapiVideoMeta * meta) copy->buffer = NULL; copy->ref_count = 1; - copy->display = gst_vaapi_display_ref (meta->display); + copy->display = gst_object_ref (meta->display); copy->image_pool = NULL; copy->image = meta->image ? gst_vaapi_object_ref (meta->image) : NULL; copy->proxy = meta->proxy ? gst_vaapi_surface_proxy_copy (meta->proxy) : NULL; diff --git a/tests/test-decode.c b/tests/test-decode.c index d44ac4388e..a85eabad34 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -79,7 +79,7 @@ main (int argc, char *argv[]) if (CHECK_DISPLAY_CACHE) display2 = video_output_create_display (NULL); else - display2 = gst_vaapi_display_ref (display); + display2 = gst_object_ref (display); if (!display2) g_error ("could not create second VA display"); From 076af846545d3a0c1cfd9f9ca1cb679dc30a4923 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 18 May 2018 17:03:57 -0400 Subject: [PATCH 3101/3781] h264dec: Properly set sentinel in ref frame list This ensure that we always have sentinels set in the reference pictures arrays. The code wasn't unsafe, this simply improve the tracing, so instead of printing 32 lines of zeros, va tracer prints proper empty lists. https://bugzilla.gnome.org/show_bug.cgi?id=796169 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 6aeb838a85..cf556cab2c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4199,6 +4199,10 @@ fill_RefPicList (GstVaapiDecoderH264 * decoder, slice_param->num_ref_idx_l0_active_minus1 = 0; slice_param->num_ref_idx_l1_active_minus1 = 0; + /* ensure empty list by default */ + vaapi_init_picture (&slice_param->RefPicList0[0]); + vaapi_init_picture (&slice_param->RefPicList1[0]); + if (GST_H264_IS_B_SLICE (slice_hdr)) num_ref_lists = 2; else if (GST_H264_IS_I_SLICE (slice_hdr)) @@ -4215,7 +4219,7 @@ fill_RefPicList (GstVaapiDecoderH264 * decoder, for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++) vaapi_fill_picture_for_RefPicListX (&slice_param->RefPicList0[i], priv->RefPicList0[i]); - for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++) + if (i < 32) vaapi_init_picture (&slice_param->RefPicList0[i]); if (num_ref_lists < 2) @@ -4227,8 +4231,9 @@ fill_RefPicList (GstVaapiDecoderH264 * decoder, for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++) vaapi_fill_picture_for_RefPicListX (&slice_param->RefPicList1[i], priv->RefPicList1[i]); - for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++) + if (i < 32) vaapi_init_picture (&slice_param->RefPicList1[i]); + return TRUE; } From 72ea2a5bc39809f41d644a25e31c322038dca7de Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 30 May 2018 16:01:36 -0400 Subject: [PATCH 3102/3781] h264dec: Remove false assumption about parity order The decoder was trying to detect earlier that a field was lost base on guessing the parity order. This breaks in streams were the parity order changes. This patch reverts the field order prediction code added by commit 8dd93e9c8. https://bugzilla.gnome.org/show_bug.cgi?id=796169 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 106 ++-------------------- 1 file changed, 7 insertions(+), 99 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index cf556cab2c..4664085b40 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -483,7 +483,6 @@ struct _GstVaapiDecoderH264Private guint decoder_state; GstVaapiStreamAlignH264 stream_alignment; GstVaapiPictureH264 *current_picture; - GstVaapiPictureH264 *missing_picture; GstVaapiParserInfoH264 *sps[GST_H264_MAX_SPS_COUNT]; GstVaapiParserInfoH264 *active_sps; GstVaapiParserInfoH264 *pps[GST_H264_MAX_PPS_COUNT]; @@ -1248,7 +1247,6 @@ gst_vaapi_decoder_h264_close (GstVaapiDecoderH264 * decoder) GstVaapiDecoderH264Private *const priv = &decoder->priv; gst_vaapi_picture_replace (&priv->current_picture, NULL); - gst_vaapi_picture_replace (&priv->missing_picture, NULL); gst_vaapi_parser_info_h264_replace (&priv->prev_slice_pi, NULL); gst_vaapi_parser_info_h264_replace (&priv->prev_pi, NULL); @@ -3079,85 +3077,6 @@ init_picture_refs (GstVaapiDecoderH264 * decoder, mark_picture_refs (decoder, picture); } -static GstVaapiPictureH264 * -fill_picture_first_field_gap (GstVaapiDecoderH264 * decoder, - GstVaapiPictureH264 * f0) -{ - GstVaapiDecoderH264Private *const priv = &decoder->priv; - GstVaapiPictureH264 *f1; - - f1 = gst_vaapi_picture_h264_new_clone (f0); - if (!f1) - goto error_allocate_field; - - gst_vaapi_picture_replace (&priv->missing_picture, f1); - gst_vaapi_picture_unref (f1); - - GST_VAAPI_PICTURE_FLAG_SET (f1, - (GST_VAAPI_PICTURE_FLAG_ONEFIELD | - GST_VAAPI_PICTURE_FLAG_SKIPPED | GST_VAAPI_PICTURE_FLAG_GHOST)); - - gst_vaapi_picture_h264_set_reference (f1, 0, FALSE); - return f1; - - /* ERRORS */ -error_allocate_field: - { - GST_ERROR ("failed to allocate missing field for current frame store"); - return NULL; - } -} - -static gboolean -fill_picture_first_field_gap_done (GstVaapiDecoderH264 * decoder, - GstH264SliceHdr * slice_hdr) -{ - GstVaapiDecoderH264Private *const priv = &decoder->priv; - GstVaapiPictureH264 *const lost_field = priv->missing_picture; - GstH264SliceHdr lost_slice_hdr; - gboolean success = FALSE; - - g_return_val_if_fail (priv->current_picture != NULL, FALSE); - - if (!lost_field) - return TRUE; - - lost_field->frame_num = slice_hdr->frame_num; - lost_field->frame_num_wrap = slice_hdr->frame_num; - - gst_vaapi_picture_h264_set_reference (lost_field, - (GST_VAAPI_PICTURE_FLAGS (priv->current_picture) & - GST_VAAPI_PICTURE_FLAGS_REFERENCE), FALSE); - - lost_slice_hdr = *slice_hdr; - lost_slice_hdr.bottom_field_flag = !lost_slice_hdr.bottom_field_flag; - - init_picture_poc (decoder, lost_field, &lost_slice_hdr); - init_picture_ref_lists (decoder, lost_field); - init_picture_refs_pic_num (decoder, lost_field, &lost_slice_hdr); - if (!exec_ref_pic_marking_sliding_window (decoder)) - goto error_exec_ref_pic_marking; - if (!dpb_add (decoder, lost_field)) - goto error_dpb_add; - success = TRUE; - -cleanup: - gst_vaapi_picture_replace (&priv->missing_picture, NULL); - return success; - - /* ERRORS */ -error_exec_ref_pic_marking: - { - GST_ERROR ("failed to execute reference picture marking process"); - goto cleanup; - } -error_dpb_add: - { - GST_ERROR ("failed to store lost picture into the DPB"); - goto cleanup; - } -} - static GstVaapiPictureH264 * fill_picture_other_field_gap (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * f0) @@ -3458,7 +3377,6 @@ init_picture (GstVaapiDecoderH264 * decoder, GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE); } - fill_picture_first_field_gap_done (decoder, slice_hdr); init_picture_poc (decoder, picture, slice_hdr); return TRUE; } @@ -3993,8 +3911,7 @@ same_field_parity (GstVaapiPictureH264 * field, GstH264SliceHdr * slice_hdr) /* Finds the first field picture corresponding to the supplied picture */ static GstVaapiPictureH264 * -find_first_field (GstVaapiDecoderH264 * decoder, GstVaapiParserInfoH264 * pi, - gboolean fill_gaps) +find_first_field (GstVaapiDecoderH264 * decoder, GstVaapiParserInfoH264 * pi) { GstVaapiDecoderH264Private *const priv = &decoder->priv; GstH264SliceHdr *const slice_hdr = &pi->data.slice_hdr; @@ -4007,37 +3924,29 @@ find_first_field (GstVaapiDecoderH264 * decoder, GstVaapiParserInfoH264 * pi, f0 = fs->buffers[0]; if (!slice_hdr->field_pic_flag) { - if (fill_gaps && !gst_vaapi_frame_store_has_frame (fs)) + if (!gst_vaapi_frame_store_has_frame (fs)) fill_picture_other_field_gap (decoder, f0); return NULL; } /* At this point, the current frame is known to be interlaced */ if (gst_vaapi_frame_store_has_frame (fs)) { - f1 = NULL; - if (fill_gaps && !same_field_parity (f0, slice_hdr)) - f1 = fill_picture_first_field_gap (decoder, f0); - return f1; + return NULL; } /* At this point, the previous frame is interlaced and contains a single field */ if (f0->frame_num == slice_hdr->frame_num) { f1 = f0; - if (fill_gaps && same_field_parity (f0, slice_hdr)) { + if (same_field_parity (f0, slice_hdr)) { fill_picture_other_field_gap (decoder, f0); f1 = NULL; } return f1; } - f1 = NULL; - if (fill_gaps) { - fill_picture_other_field_gap (decoder, f0); - if (!same_field_parity (f0, slice_hdr)) - f1 = fill_picture_first_field_gap (decoder, f0); - } - return f1; + fill_picture_other_field_gap (decoder, f0); + return NULL; } static GstVaapiDecoderStatus @@ -4059,9 +3968,8 @@ decode_picture (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) return status; priv->decoder_state = 0; - gst_vaapi_picture_replace (&priv->missing_picture, NULL); - first_field = find_first_field (decoder, pi, TRUE); + first_field = find_first_field (decoder, pi); if (first_field) { /* Re-use current picture where the first field was decoded */ picture = gst_vaapi_picture_h264_new_field (first_field); From 4f32a72675ca6b8318bbb779e12bfdd38136362c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 24 Jun 2018 13:07:20 +0200 Subject: [PATCH 3103/3781] Update for g_type_class_add_private() deprecation in recent GLib --- gst/vaapi/gstvaapivideobufferpool.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 804d4f6ffc..f6931c41ad 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -32,9 +32,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapivideopool); #define GST_CAT_DEFAULT gst_debug_vaapivideopool -G_DEFINE_TYPE (GstVaapiVideoBufferPool, - gst_vaapi_video_buffer_pool, GST_TYPE_BUFFER_POOL); - enum { PROP_0, @@ -52,9 +49,8 @@ struct _GstVaapiVideoBufferPoolPrivate guint forced_video_meta:1; }; -#define GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER_POOL, \ - GstVaapiVideoBufferPoolPrivate)) +G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiVideoBufferPool, + gst_vaapi_video_buffer_pool, GST_TYPE_BUFFER_POOL); static void gst_vaapi_video_buffer_pool_finalize (GObject * object) @@ -497,8 +493,6 @@ gst_vaapi_video_buffer_pool_class_init (GstVaapiVideoBufferPoolClass * klass) GST_DEBUG_CATEGORY_INIT (gst_debug_vaapivideopool, "vaapivideopool", 0, "VA-API video pool"); - g_type_class_add_private (klass, sizeof (GstVaapiVideoBufferPoolPrivate)); - object_class->finalize = gst_vaapi_video_buffer_pool_finalize; object_class->set_property = gst_vaapi_video_buffer_pool_set_property; object_class->get_property = gst_vaapi_video_buffer_pool_get_property; @@ -524,10 +518,7 @@ gst_vaapi_video_buffer_pool_class_init (GstVaapiVideoBufferPoolClass * klass) static void gst_vaapi_video_buffer_pool_init (GstVaapiVideoBufferPool * pool) { - GstVaapiVideoBufferPoolPrivate *const priv = - GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE (pool); - - pool->priv = priv; + pool->priv = gst_vaapi_video_buffer_pool_get_instance_private (pool); } GstBufferPool * @@ -551,10 +542,9 @@ gst_vaapi_video_buffer_pool_new (GstVaapiDisplay * display) gboolean gst_vaapi_video_buffer_pool_copy_buffer (GstBufferPool * pool) { - GstVaapiVideoBufferPoolPrivate *priv; + GstVaapiVideoBufferPool *va_pool = (GstVaapiVideoBufferPool *) pool; g_return_val_if_fail (GST_VAAPI_IS_VIDEO_BUFFER_POOL (pool), FALSE); - priv = GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE (pool); - return priv->forced_video_meta; + return va_pool->priv->forced_video_meta; } From b4d6a3b11338c188b2c6d47533732c0e0f28c39d Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Mon, 25 Jun 2018 14:20:32 +0200 Subject: [PATCH 3104/3781] pluginutil: downgrade unsupported driver logging On systems with an Nvidia card, this error is output each time the registry is rebuilt, which happens pretty often when using gst-build as a development environment. https://bugzilla.gnome.org/show_bug.cgi?id=796663 --- gst/vaapi/gstvaapipluginutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index a391978263..8632da8136 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -948,7 +948,7 @@ gst_vaapi_driver_is_whitelisted (GstVaapiDisplay * display) return TRUE; } - GST_ERROR ("Unsupported VA driver: %s. Export environment variable " + GST_WARNING ("Unsupported VA driver: %s. Export environment variable " GST_VAAPI_ALL_DRIVERS_ENV " to bypass", vendor); return FALSE; From f5eb4faa5914f3745820e557ac2401a7d738be66 Mon Sep 17 00:00:00 2001 From: Tianhao Liu Date: Wed, 4 Jul 2018 12:51:10 +0800 Subject: [PATCH 3105/3781] libs: encoder: jpeg: set component id and Tqi This change is due a problem encoding JPEGs with Intel's media-driver: green/black image when playback jpeg This patch sets component identifier and quantization table destination selector in frame header to support packing headers by Intel's media-driver that does not accept packed header in AP level. https://bugzilla.gnome.org/show_bug.cgi?id=796705 --- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index b3f409d6da..8491fbca9f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -205,6 +205,7 @@ fill_picture (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) { + guint i; VAEncPictureParameterBufferJPEG *const pic_param = picture->param; memset (pic_param, 0, sizeof (VAEncPictureParameterBufferJPEG)); @@ -224,6 +225,11 @@ fill_picture (GstVaapiEncoderJpeg * encoder, 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; } @@ -437,13 +443,11 @@ generate_frame_hdr (GstJpegFrameHdr * frame_hdr, GstVaapiEncoderJpeg * encoder, frame_hdr->num_components = pic_param->num_components; for (i = 0; i < frame_hdr->num_components; i++) { - frame_hdr->components[i].identifier = i + 1; + 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]; - if (i == 0) - frame_hdr->components[i].quant_table_selector = 0; - else - frame_hdr->components[i].quant_table_selector = 1; + frame_hdr->components[i].quant_table_selector = + pic_param->quantiser_table_selector[i]; } } From 927536b7910041f35d486cab4f676e0c3e242b19 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 18 Jul 2018 13:07:51 -0400 Subject: [PATCH 3106/3781] h264decoder: Don't scan empty buffer gst_adapter_masked_scan_uint32_peek() asserts if size is 0. Don't try and scan in that case. This fixes assertion that would some times happen when the stream is corrupted. https://bugzilla.gnome.org/show_bug.cgi?id=796832 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 4664085b40..277e09a451 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4236,6 +4236,9 @@ decode_slice (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) static inline gint scan_for_start_code (GstAdapter * adapter, guint ofs, guint size, guint32 * scp) { + if (size == 0) + return -1; + return (gint) gst_adapter_masked_scan_uint32_peek (adapter, 0xffffff00, 0x00000100, ofs, size, scp); } From 7c365bdddca24bcd1f3b1d34008a235617a0ee19 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 18 Jul 2018 13:09:42 -0400 Subject: [PATCH 3107/3781] h264decoder: Fail decoding slice if modification process failed This patch chains up failure to executing the modification process. The end result is that we now fail decoding the slice if this process fails. This avoid sending a corrupted state to the accelerator. In some special cases, this could lead to unrecoverable errors. https://bugzilla.gnome.org/show_bug.cgi?id=796832 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 39 ++++++++++++++++------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 277e09a451..b5d84123c8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -36,7 +36,6 @@ #include "gstvaapiobject_priv.h" #include "gstvaapiutils_h264_priv.h" -#define DEBUG 1 #include "gstvaapidebug.h" /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */ @@ -2738,7 +2737,7 @@ find_long_term_reference (GstVaapiDecoderH264 * decoder, return -1; } -static void +static gboolean exec_picture_refs_modification_1 (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr, guint list) { @@ -2752,6 +2751,7 @@ exec_picture_refs_modification_1 (GstVaapiDecoderH264 * decoder, guint i, j, n, num_refs, num_view_ids = 0; gint found_ref_idx; gint32 MaxPicNum, CurrPicNum, picNumPred, picViewIdxPred; + gboolean ret = TRUE; GST_DEBUG ("modification process of reference picture list %u", list); @@ -2920,30 +2920,38 @@ exec_picture_refs_modification_1 (GstVaapiDecoderH264 * decoder, } } -#if DEBUG - for (i = 0; i < num_refs; i++) - if (!ref_list[i]) + for (i = 0; i < num_refs; i++) { + if (!ref_list[i]) { + ret = FALSE; GST_ERROR ("list %u entry %u is empty", list, i); -#endif + } + } + *ref_list_count_ptr = num_refs; + + return ret; } /* 8.2.4.3 - Modification process for reference picture lists */ -static void +static gboolean exec_picture_refs_modification (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { + gboolean ret = TRUE; + GST_DEBUG ("execute ref_pic_list_modification()"); /* RefPicList0 */ if (!GST_H264_IS_I_SLICE (slice_hdr) && !GST_H264_IS_SI_SLICE (slice_hdr) && slice_hdr->ref_pic_list_modification_flag_l0) - exec_picture_refs_modification_1 (decoder, picture, slice_hdr, 0); + ret = exec_picture_refs_modification_1 (decoder, picture, slice_hdr, 0); /* RefPicList1 */ if (GST_H264_IS_B_SLICE (slice_hdr) && slice_hdr->ref_pic_list_modification_flag_l1) - exec_picture_refs_modification_1 (decoder, picture, slice_hdr, 1); + ret = exec_picture_refs_modification_1 (decoder, picture, slice_hdr, 1); + + return ret; } static gboolean @@ -3028,12 +3036,13 @@ init_picture_ref_lists (GstVaapiDecoderH264 * decoder, priv->long_ref_count = long_ref_count; } -static void +static gboolean init_picture_refs (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { GstVaapiDecoderH264Private *const priv = &decoder->priv; guint i, num_refs; + gboolean ret = TRUE; init_picture_ref_lists (decoder, picture); init_picture_refs_pic_num (decoder, picture, slice_hdr); @@ -3053,7 +3062,7 @@ init_picture_refs (GstVaapiDecoderH264 * decoder, break; } - exec_picture_refs_modification (decoder, picture, slice_hdr); + ret = exec_picture_refs_modification (decoder, picture, slice_hdr); switch (slice_hdr->type % 5) { case GST_H264_B_SLICE: @@ -3075,6 +3084,8 @@ init_picture_refs (GstVaapiDecoderH264 * decoder, } mark_picture_refs (decoder, picture); + + return ret; } static GstVaapiPictureH264 * @@ -4222,7 +4233,11 @@ decode_slice (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; } - init_picture_refs (decoder, picture, slice_hdr); + if (!init_picture_refs (decoder, picture, slice_hdr)) { + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (slice)); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + if (!fill_slice (decoder, slice, pi)) { gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (slice)); return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; From 9eaff17c309a5f135a2256b0904f3eb629ac06a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 25 Jul 2018 20:21:51 +0200 Subject: [PATCH 3108/3781] libs: h264: renable the vaapi category for logging h264 log messages were logged in default category because a regression in code. This patch renable the usage of vaapi logging category. This regression was introduced in commit 7c365bdd. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index b5d84123c8..eecf8bbd70 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -36,6 +36,7 @@ #include "gstvaapiobject_priv.h" #include "gstvaapiutils_h264_priv.h" +#define DEBUG 1 #include "gstvaapidebug.h" /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */ From b9ecf3b40da75be0fff4bbaa7391419a1bd7e5b7 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 25 Jul 2018 15:47:49 -0400 Subject: [PATCH 3109/3781] h265decoder: Don't scan empty buffer Same as what we did for H264 decoder, this is to avoid an assertion in the adapter. https://bugzilla.gnome.org/show_bug.cgi?id=796832 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index e9353cf40b..156237bb90 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2572,6 +2572,9 @@ decode_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) static inline gint scan_for_start_code (GstAdapter * adapter, guint ofs, guint size, guint32 * scp) { + if (size == 0) + return -1; + return (gint) gst_adapter_masked_scan_uint32_peek (adapter, 0xffffff00, 0x00000100, ofs, size, scp); } From d07bffb57889aba821af5f24553e714dbdc6593a Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 24 Jul 2018 12:40:00 -0400 Subject: [PATCH 3110/3781] vaapidecoder: Don't error out on decode errors This is problematic on live pipeline where loosing network can cause an important amount of errors. https://bugzilla.gnome.org/show_bug.cgi?id=796832 --- gst/vaapi/gstvaapidecode.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 456ec8b1c5..3e470a8050 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1087,6 +1087,9 @@ gst_vaapidecode_start (GstVideoDecoder * vdec) if (old_display) gst_object_unref (old_display); + /* Disable errors on decode errors */ + gst_video_decoder_set_max_errors (vdec, -1); + return success; } From 06aa82f9899efa55dada5a2372044d5d6e200747 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 25 Jul 2018 13:50:23 -0400 Subject: [PATCH 3111/3781] vaapidecode: Skip unparsable units from adapter If the unit could not be parsed, just skip this nal and keep parsing what is left in the adapter. We need to flush the broken unit in the decoder specific parser because the generic code does not know about units boundary. This increases error resilliance. Before this, the broken unit would stay in the adapter and EOS would be returned. Which stopped the streaming. Just removing the EOS would have lead to the adapter size growing indefinitely. https://bugzilla.gnome.org/show_bug.cgi?id=796863 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 + gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 1 + gst/vaapi/gstvaapidecode.c | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index eecf8bbd70..d20bb377f6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4640,6 +4640,7 @@ gst_vaapi_decoder_h264_parse (GstVaapiDecoder * base_decoder, exit: { + gst_adapter_flush (adapter, unit->size); gst_vaapi_parser_info_h264_unref (pi); return status; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 156237bb90..8e6d2e5763 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2984,6 +2984,7 @@ gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; exit: + gst_adapter_flush (adapter, unit->size); gst_vaapi_parser_info_h265_unref (pi); return status; } diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3e470a8050..cdb907fc6d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1179,7 +1179,8 @@ gst_vaapidecode_parse_frame (GstVideoDecoder * vdec, break; default: GST_ERROR ("parse error %d", status); - ret = GST_FLOW_EOS; + /* just keep parsing, the decoder should have flushed the broken unit */ + ret = GST_VAAPI_DECODE_FLOW_PARSE_DATA; decode->current_frame_size = 0; break; } From 038c62011f009453d1609a4a79aeb4ccd78107eb Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Thu, 14 Sep 2017 14:25:41 +0900 Subject: [PATCH 3112/3781] libs: decoder: h264: reset context when the number of view is increased Usually in case of MVC decoding, dpb size is increasedi if subset sps. That's why it resets context without this patch. But for some media it doesn't increase dpb size. Even in this case we should reset context to deal with MVC decoding. Otherwise, it leads to assert. https://bugzilla.gnome.org/show_bug.cgi?id=787124 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index d20bb377f6..bfd92b194b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1514,6 +1514,7 @@ ensure_context (GstVaapiDecoderH264 * decoder, GstH264SPS * sps) num_views = get_num_views (sps); if (priv->max_views < num_views) { priv->max_views = num_views; + reset_context = TRUE; GST_DEBUG ("maximum number of views changed to %u", num_views); } From 7a120c7a72b91e7a0fdb7cdb84bdb8b3980dff13 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 25 Jul 2018 17:03:19 -0400 Subject: [PATCH 3113/3781] h264decoder: Fail decoding slice with missing inter-view reference Similarly to previous patch, we have no error concealment. As a side effect, it's better to skip slices with missing references then passing NULL pointers to the accelerator. Passing NULL pointer would lead to major visual artifact, a behaviour that is likely undefined. https://bugzilla.gnome.org/show_bug.cgi?id=787124 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 46 +++++++++++++++-------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index bfd92b194b..be02b76f18 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2439,7 +2439,7 @@ is_inter_view_reference_for_next_pictures (GstVaapiDecoderH264 * decoder, } /* H.8.2.1 - Initialization process for inter-view prediction references */ -static void +static gboolean init_picture_refs_mvc_1 (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 ** ref_list, guint * ref_list_count_ptr, guint num_refs, const guint16 * view_ids, guint num_view_ids) @@ -2448,30 +2448,36 @@ init_picture_refs_mvc_1 (GstVaapiDecoderH264 * decoder, n = *ref_list_count_ptr; for (j = 0; j < num_view_ids && n < num_refs; j++) { - GstVaapiPictureH264 *const pic = - find_inter_view_reference (decoder, view_ids[j]); - if (pic) - ref_list[n++] = pic; + GstVaapiPictureH264 *pic; + + if (!(pic = find_inter_view_reference (decoder, view_ids[j]))) + return FALSE; + + ref_list[n++] = pic; } + *ref_list_count_ptr = n; + + return TRUE; } -static inline void +static inline gboolean init_picture_refs_mvc (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr, guint list) { GstVaapiDecoderH264Private *const priv = &decoder->priv; const GstH264SPS *const sps = get_sps (decoder); const GstH264SPSExtMVCView *view; + gboolean ret = TRUE; GST_DEBUG ("initialize reference picture list for inter-view prediction"); if (sps->extension_type != GST_H264_NAL_EXTENSION_MVC) - return; + return TRUE; view = &sps->extension.mvc.view[picture->base.voc]; #define INVOKE_INIT_PICTURE_REFS_MVC(ref_list, view_list) do { \ - init_picture_refs_mvc_1(decoder, \ + ret = init_picture_refs_mvc_1(decoder, \ priv->RefPicList##ref_list, \ &priv->RefPicList##ref_list##_count, \ slice_hdr->num_ref_idx_l##ref_list##_active_minus1 + 1, \ @@ -2491,16 +2497,19 @@ init_picture_refs_mvc (GstVaapiDecoderH264 * decoder, INVOKE_INIT_PICTURE_REFS_MVC (1, non_anchor_ref); } + return ret; + #undef INVOKE_INIT_PICTURE_REFS_MVC } -static void +static gboolean init_picture_refs_p_slice (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { GstVaapiDecoderH264Private *const priv = &decoder->priv; GstVaapiPictureH264 **ref_list; guint i; + gboolean ret = TRUE; GST_DEBUG ("decode reference picture list for P and SP slices"); @@ -2549,17 +2558,20 @@ init_picture_refs_p_slice (GstVaapiDecoderH264 * decoder, if (GST_VAAPI_PICTURE_IS_MVC (picture)) { /* RefPicList0 */ - init_picture_refs_mvc (decoder, picture, slice_hdr, 0); + ret = init_picture_refs_mvc (decoder, picture, slice_hdr, 0); } + + return ret; } -static void +static gboolean init_picture_refs_b_slice (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture, GstH264SliceHdr * slice_hdr) { GstVaapiDecoderH264Private *const priv = &decoder->priv; GstVaapiPictureH264 **ref_list; guint i, n; + gboolean ret = TRUE; GST_DEBUG ("decode reference picture list for B slices"); @@ -2700,11 +2712,13 @@ init_picture_refs_b_slice (GstVaapiDecoderH264 * decoder, if (GST_VAAPI_PICTURE_IS_MVC (picture)) { /* RefPicList0 */ - init_picture_refs_mvc (decoder, picture, slice_hdr, 0); + ret = init_picture_refs_mvc (decoder, picture, slice_hdr, 0); /* RefPicList1 */ - init_picture_refs_mvc (decoder, picture, slice_hdr, 1); + ret = init_picture_refs_mvc (decoder, picture, slice_hdr, 1); } + + return ret; } #undef SORT_REF_LIST @@ -3055,16 +3069,16 @@ init_picture_refs (GstVaapiDecoderH264 * decoder, switch (slice_hdr->type % 5) { case GST_H264_P_SLICE: case GST_H264_SP_SLICE: - init_picture_refs_p_slice (decoder, picture, slice_hdr); + ret = init_picture_refs_p_slice (decoder, picture, slice_hdr); break; case GST_H264_B_SLICE: - init_picture_refs_b_slice (decoder, picture, slice_hdr); + ret = init_picture_refs_b_slice (decoder, picture, slice_hdr); break; default: break; } - ret = exec_picture_refs_modification (decoder, picture, slice_hdr); + ret = ret && exec_picture_refs_modification (decoder, picture, slice_hdr); switch (slice_hdr->type % 5) { case GST_H264_B_SLICE: From 2922439bc2aa5c48859b39343dd6982769275813 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Mon, 27 Aug 2018 20:42:15 -0400 Subject: [PATCH 3114/3781] libs: decoder: h264: Avoid using picture after it has been free In some cases, the found_picture ended up being evicted and freed, which would lead to a use after free when accessing picture->base.poc. In this fix, we take a ref on the picture before calling dpb_evict. https://bugzilla.gnome.org/show_bug.cgi?id=787124 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index be02b76f18..3654e80956 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -942,16 +942,22 @@ dpb_bump (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture) if (found_index < 0) return FALSE; + gst_vaapi_picture_ref (found_picture); + if (picture && picture->base.poc != found_picture->base.poc) dpb_output_other_views (decoder, found_picture, found_picture->base.voc); success = dpb_output (decoder, priv->dpb[found_index]); + dpb_evict (decoder, found_picture, found_index); if (priv->max_views == 1) - return success; + goto done; if (picture && picture->base.poc != found_picture->base.poc) dpb_output_other_views (decoder, found_picture, G_MAXUINT32); + +done: + gst_vaapi_picture_unref (found_picture); return success; } From 2fce126cc7968246ce4d0602052d62b12e4662b9 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Thu, 30 Aug 2018 11:08:07 +0800 Subject: [PATCH 3115/3781] libs: encoder: h265: add low delay B frame support. Low delay B frame provide the function of transforming P frame into low delay B frame which frame type is B, but only reference predictive frames. This can be used when P frame unsupported. Especially for P and B both unsupported, in this case, I and low delay B frame can be encoded in a stream. https://bugzilla.gnome.org/show_bug.cgi?id=796984 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 27 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index e1814d24b1..1348e64b94 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -110,6 +110,7 @@ struct _GstVaapiEncoderH265 guint32 luma_height; GstClockTime cts_offset; gboolean config_changed; + gboolean low_delay_b; /* maximum required size of the decoded picture buffer */ guint32 max_dec_pic_buffering; @@ -1684,6 +1685,9 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, } slice_param->num_ctu_in_slice = cur_slice_ctus; slice_param->slice_type = h265_get_slice_type (picture->type); + if (encoder->low_delay_b && slice_param->slice_type == GST_H265_P_SLICE) { + slice_param->slice_type = GST_H265_B_SLICE; + } slice_param->slice_pic_parameter_set_id = 0; slice_param->slice_fields.bits.num_ref_idx_active_override_flag = @@ -1717,6 +1721,13 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_1[i_ref]->poc; } + } else if (picture->type == GST_VAAPI_PICTURE_TYPE_P + && encoder->low_delay_b) { + for (; i_ref < reflist_0_count; ++i_ref) { + slice_param->ref_pic_list1[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); + slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_0[i_ref]->poc; + } } for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i_ref) { slice_param->ref_pic_list1[i_ref].picture_id = VA_INVALID_SURFACE; @@ -2583,6 +2594,10 @@ gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H265_PROP_MBBRC: encoder->mbbrc = g_value_get_enum (value); break; + case GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B: + encoder->low_delay_b = g_value_get_boolean (value); + break; + default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -2748,6 +2763,18 @@ gst_vaapi_encoder_h265_get_default_properties (void) GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH265:low_delay_b: + * + * Enable low delay b frame, which will change P frame with B frame. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B, + g_param_spec_boolean ("low-delay-b", + "Enable low delay b", + "Transforms P frames into predictive B frames. Enable it when P frames are not supported.", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index 3496742a30..e53881050f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -45,6 +45,7 @@ typedef struct _GstVaapiEncoderH265 GstVaapiEncoderH265; * @GST_VAAPI_ENCODER_H265_PROP_MBBRC: Macroblock level Bitrate Control. * @GST_VAAPI_ENCODER_H265_PROP_QP_IP: Difference of QP between I and P frame. * @GST_VAAPI_ENCODER_H265_PROP_QP_IB: Difference of QP between I and B frame. + * @GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B: use low delay b feature. * in milliseconds (uint). * * The set of H.265 encoder specific configurable properties. @@ -59,6 +60,7 @@ typedef enum { GST_VAAPI_ENCODER_H265_PROP_MBBRC = -8, GST_VAAPI_ENCODER_H265_PROP_QP_IP = -9, GST_VAAPI_ENCODER_H265_PROP_QP_IB = -10, + GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B = -11, } GstVaapiEncoderH265Prop; GstVaapiEncoder * From 5f718b4f93166e5b67ebc5ad4fd400562a55e09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Aug 2018 13:44:44 +0200 Subject: [PATCH 3116/3781] libs: encoder: h265: trivial documentation fix --- gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index e53881050f..2e594f7218 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -42,11 +42,11 @@ typedef struct _GstVaapiEncoderH265 GstVaapiEncoderH265; * @GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES: Number of slices per frame (uint). * @GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES: Maximum number of reference frames. * @GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH: Length of the CPB buffer + * in milliseconds (uint). * @GST_VAAPI_ENCODER_H265_PROP_MBBRC: Macroblock level Bitrate Control. * @GST_VAAPI_ENCODER_H265_PROP_QP_IP: Difference of QP between I and P frame. * @GST_VAAPI_ENCODER_H265_PROP_QP_IB: Difference of QP between I and B frame. * @GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B: use low delay b feature. - * in milliseconds (uint). * * The set of H.265 encoder specific configurable properties. */ From f6d827f6ff5d20350f104a2c8e597fb6feb4ea02 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 31 Aug 2018 14:47:55 +0530 Subject: [PATCH 3117/3781] meson: Sync libversion and osxversion code from other repos gstreamer-vaapi does not build any libraries, only plugins, so this is not used, but sync it just in case someone does add it in the future. --- meson.build | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index a5fa0afe7c..9af89604a3 100644 --- a/meson.build +++ b/meson.build @@ -169,7 +169,9 @@ api_version = '1.0' soversion = 0 # maintaining compatibility with the previous libtool versioning # current = minor * 100 + micro -libversion = '@0@.@1@.0'.format(soversion, gst_version_minor * 100 + gst_version_micro) +curversion = gst_version_minor * 100 + gst_version_micro +libversion = '@0@.@1@.0'.format(soversion, curversion) +osxversion = curversion + 1 plugins_install_dir = '@0@/gstreamer-1.0'.format(get_option('libdir')) From 1f0b2fb9529934a79842f94222995401ad9417db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 30 Aug 2018 18:56:40 +0200 Subject: [PATCH 3118/3781] libs: display: lock at extracting available image formates When running several vaapi elements at the concurrently, at initialization, there is a race condition when extractin the avaible formats for images and subpictures. This patch add a lock when the those arrays are filled. https://bugzilla.gnome.org/show_bug.cgi?id=797039 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 7c6588afb7..ad6ebcbe22 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -649,8 +649,11 @@ ensure_image_formats (GstVaapiDisplay * display) gint i, n; gboolean success = FALSE; - if (priv->image_formats) + GST_VAAPI_DISPLAY_LOCK (display); + if (priv->image_formats) { + GST_VAAPI_DISPLAY_UNLOCK (display); return TRUE; + } priv->image_formats = g_array_new (FALSE, FALSE, sizeof (GstVaapiFormatInfo)); if (!priv->image_formats) @@ -676,6 +679,7 @@ ensure_image_formats (GstVaapiDisplay * display) cleanup: g_free (formats); + GST_VAAPI_DISPLAY_UNLOCK (display); return success; } @@ -690,8 +694,11 @@ ensure_subpicture_formats (GstVaapiDisplay * display) guint i, n; gboolean success = FALSE; - if (priv->subpicture_formats) + GST_VAAPI_DISPLAY_LOCK (display); + if (priv->subpicture_formats) { + GST_VAAPI_DISPLAY_UNLOCK (display); return TRUE; + } priv->subpicture_formats = g_array_new (FALSE, FALSE, sizeof (GstVaapiFormatInfo)); @@ -725,6 +732,7 @@ ensure_subpicture_formats (GstVaapiDisplay * display) cleanup: g_free (formats); g_free (flags); + GST_VAAPI_DISPLAY_UNLOCK (display); return success; } From 2cb795fc774b712249f70e14d8ac5d0e33824e57 Mon Sep 17 00:00:00 2001 From: Matteo Valdina Date: Fri, 31 Aug 2018 20:48:13 -0500 Subject: [PATCH 3119/3781] vaapidecode: sets return value in failure case. In gst_vaapidecode_handle_frame, when there is a decode error there is a code path the returns an uninitialized value. Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=797006 --- gst/vaapi/gstvaapidecode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index cdb907fc6d..423b7c678d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -760,6 +760,7 @@ error_decode: ret = GST_FLOW_NOT_SUPPORTED; break; default: + ret = GST_FLOW_OK; GST_VIDEO_DECODER_ERROR (vdec, 1, STREAM, DECODE, ("Decoding error"), ("Decode error %d", status), ret); break; From 7872d1269594c2e982d26abf6906039966f4c7ce Mon Sep 17 00:00:00 2001 From: Matteo Valdina Date: Fri, 31 Aug 2018 20:56:13 -0500 Subject: [PATCH 3120/3781] vaapidecode: Requests upstream a key unit at parse or decode error. This is done to resume decoding after a parse error or decode error. Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=797006 --- gst/vaapi/gstvaapidecode.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 423b7c678d..86938d97fb 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -763,6 +763,11 @@ error_decode: ret = GST_FLOW_OK; GST_VIDEO_DECODER_ERROR (vdec, 1, STREAM, DECODE, ("Decoding error"), ("Decode error %d", status), ret); + GST_INFO ("requesting upstream a key unit"); + gst_pad_push_event (GST_VIDEO_DECODER_SINK_PAD (decode), + gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE, + FALSE, 0)); + ret = GST_FLOW_OK; break; } gst_video_decoder_drop_frame (vdec, frame); @@ -1179,10 +1184,15 @@ gst_vaapidecode_parse_frame (GstVideoDecoder * vdec, decode->current_frame_size = 0; break; default: - GST_ERROR ("parse error %d", status); + GST_WARNING ("parse error %d", status); /* just keep parsing, the decoder should have flushed the broken unit */ ret = GST_VAAPI_DECODE_FLOW_PARSE_DATA; decode->current_frame_size = 0; + + GST_INFO ("requesting upstream a key unit"); + gst_pad_push_event (GST_VIDEO_DECODER_SINK_PAD (decode), + gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE, + FALSE, 0)); break; } return ret; From 0ca49a10f831631e3d5bde2c2ba0dbf985dddb58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 18 May 2018 16:09:31 +0200 Subject: [PATCH 3121/3781] libs: decoder: refactor decoders as gobject https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 154 +++++++++++++-------- gst-libs/gst/vaapi/gstvaapidecoder.h | 13 +- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 37 ++--- gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 13 +- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 35 +++-- gst-libs/gst/vaapi/gstvaapidecoder_h265.h | 15 +- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 34 +++-- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h | 12 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 35 +++-- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h | 12 +- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 36 ++--- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h | 12 +- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 20 +-- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 34 +++-- gst-libs/gst/vaapi/gstvaapidecoder_vc1.h | 12 +- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 34 +++-- gst-libs/gst/vaapi/gstvaapidecoder_vp8.h | 10 ++ gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 34 +++-- gst-libs/gst/vaapi/gstvaapidecoder_vp9.h | 10 ++ 19 files changed, 365 insertions(+), 197 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index c7157f9d02..ea774d75d2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -38,6 +38,16 @@ #define DEBUG 1 #include "gstvaapidebug.h" +enum +{ + PROP_DISPLAY = 1, + PROP_CAPS, + N_PROPERTIES +}; +static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; + +G_DEFINE_TYPE (GstVaapiDecoder, gst_vaapi_decoder, GST_TYPE_OBJECT); + static void drop_frame (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame); static void @@ -453,14 +463,10 @@ notify_codec_state_changed (GstVaapiDecoder * decoder) decoder->codec_state_changed_data); } -void -gst_vaapi_decoder_finalize (GstVaapiDecoder * decoder) +static void +gst_vaapi_decoder_finalize (GObject * object) { - const GstVaapiDecoderClass *const klass = - GST_VAAPI_DECODER_GET_CLASS (decoder); - - if (klass->destroy) - klass->destroy (decoder); + GstVaapiDecoder *const decoder = GST_VAAPI_DECODER (object); gst_video_codec_state_unref (decoder->codec_state); decoder->codec_state = NULL; @@ -482,16 +488,90 @@ gst_vaapi_decoder_finalize (GstVaapiDecoder * decoder) gst_vaapi_display_replace (&decoder->display, NULL); decoder->va_display = NULL; + + G_OBJECT_CLASS (gst_vaapi_decoder_parent_class)->finalize (object); } -static gboolean -gst_vaapi_decoder_init (GstVaapiDecoder * decoder, GstVaapiDisplay * display, - GstCaps * caps) +static void +gst_vaapi_decoder_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiDecoder *const decoder = GST_VAAPI_DECODER (object); + + switch (property_id) { + case PROP_DISPLAY: + g_assert (decoder->display == NULL); + decoder->display = g_value_dup_object (value); + g_assert (decoder->display != NULL); + decoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY (decoder->display); + break; + case PROP_CAPS:{ + GstCaps *caps = g_value_get_boxed (value); + if (!set_caps (decoder, caps)) { + GST_WARNING_OBJECT (decoder, "failed to set caps %" GST_PTR_FORMAT, + caps); + } + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +gst_vaapi_decoder_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiDecoder *const decoder = GST_VAAPI_DECODER (object); + + switch (property_id) { + case PROP_DISPLAY: + g_value_set_object (value, decoder->display); + break; + case PROP_CAPS: + g_value_set_boxed (value, get_caps (decoder)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +gst_vaapi_decoder_class_init (GstVaapiDecoderClass * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gst_vaapi_decoder_set_property; + object_class->get_property = gst_vaapi_decoder_get_property; + object_class->finalize = gst_vaapi_decoder_finalize; + + /** + * GstVaapiDecoder:display: + * + * #GstVaapiDisplay to be used. + */ + g_properties[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); + + /** + * GstCaps:caps: + * + * #GstCaps the caps describing the media to process. + */ + g_properties[PROP_CAPS] = + g_param_spec_boxed ("caps", "Caps", + "The caps describing the media to process", GST_TYPE_CAPS, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME); + + g_object_class_install_properties (object_class, N_PROPERTIES, g_properties); +} + +static void +gst_vaapi_decoder_init (GstVaapiDecoder * decoder) { - const GstVaapiDecoderClass *const klass = - GST_VAAPI_DECODER_GET_CLASS (decoder); GstVideoCodecState *codec_state; - guint sub_size; parser_state_init (&decoder->parser_state); @@ -499,56 +579,21 @@ gst_vaapi_decoder_init (GstVaapiDecoder * decoder, GstVaapiDisplay * display, codec_state->ref_count = 1; gst_video_info_init (&codec_state->info); - decoder->user_data = NULL; - decoder->display = gst_object_ref (display); - decoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY (display); - decoder->context = NULL; decoder->va_context = VA_INVALID_ID; - decoder->codec = 0; decoder->codec_state = codec_state; - decoder->codec_state_changed_func = NULL; - decoder->codec_state_changed_data = NULL; - decoder->buffers = g_async_queue_new_full ((GDestroyNotify) gst_buffer_unref); decoder->frames = g_async_queue_new_full ((GDestroyNotify) gst_video_codec_frame_unref); - - if (!set_caps (decoder, caps)) - return FALSE; - - sub_size = GST_VAAPI_MINI_OBJECT_CLASS (klass)->size - sizeof (*decoder); - if (sub_size > 0) - memset (((guchar *) decoder) + sizeof (*decoder), 0, sub_size); - - if (klass->create && !klass->create (decoder)) - return FALSE; - return TRUE; } GstVaapiDecoder * -gst_vaapi_decoder_new (const GstVaapiDecoderClass * klass, - GstVaapiDisplay * display, GstCaps * caps) +gst_vaapi_decoder_new (GstVaapiDisplay * display, GstCaps * caps) { - GstVaapiDecoder *decoder; - g_return_val_if_fail (display != NULL, NULL); g_return_val_if_fail (GST_IS_CAPS (caps), NULL); - decoder = (GstVaapiDecoder *) - gst_vaapi_mini_object_new (GST_VAAPI_MINI_OBJECT_CLASS (klass)); - if (!decoder) - return NULL; - - if (!gst_vaapi_decoder_init (decoder, display, caps)) - goto error; - return decoder; - - /* ERRORS */ -error: - { - gst_vaapi_decoder_unref (decoder); - return NULL; - } + return g_object_new (GST_TYPE_VAAPI_DECODER, "display", display, + "caps", caps, NULL); } /** @@ -562,7 +607,7 @@ error: GstVaapiDecoder * gst_vaapi_decoder_ref (GstVaapiDecoder * decoder) { - return gst_vaapi_object_ref (decoder); + return gst_object_ref (decoder); } /** @@ -575,7 +620,7 @@ gst_vaapi_decoder_ref (GstVaapiDecoder * decoder) void gst_vaapi_decoder_unref (GstVaapiDecoder * decoder) { - gst_vaapi_object_unref (decoder); + gst_object_unref (decoder); } /** @@ -591,8 +636,7 @@ void gst_vaapi_decoder_replace (GstVaapiDecoder ** old_decoder_ptr, GstVaapiDecoder * new_decoder) { - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_decoder_ptr, - GST_VAAPI_MINI_OBJECT (new_decoder)); + gst_object_replace ((GstObject **) old_decoder_ptr, GST_OBJECT (new_decoder)); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 8b442b9f41..e0a6059d07 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -32,8 +32,12 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_DECODER \ + (gst_vaapi_decoder_get_type ()) #define GST_VAAPI_DECODER(obj) \ - ((GstVaapiDecoder *)(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, @@ -73,6 +77,9 @@ typedef enum { GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN = -1 } GstVaapiDecoderStatus; +GType +gst_vaapi_decoder_get_type (void) G_GNUC_CONST; + GstVaapiDecoder * gst_vaapi_decoder_ref (GstVaapiDecoder * decoder); @@ -141,6 +148,10 @@ gst_vaapi_decoder_check_status (GstVaapiDecoder * decoder); gboolean gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps); +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoder, gst_vaapi_decoder_unref) +#endif + G_END_DECLS #endif /* GST_VAAPI_DECODER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 3654e80956..dfadad6d38 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -558,6 +558,9 @@ struct _GstVaapiDecoderH264Class GstVaapiDecoderClass parent_class; }; +G_DEFINE_TYPE (GstVaapiDecoderH264, gst_vaapi_decoder_h264, + GST_TYPE_VAAPI_DECODER); + static gboolean exec_ref_pic_marking (GstVaapiDecoderH264 * decoder, GstVaapiPictureH264 * picture); @@ -4710,16 +4713,21 @@ gst_vaapi_decoder_h264_flush (GstVaapiDecoder * base_decoder) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static void +gst_vaapi_decoder_h264_finalize (GObject * object) +{ + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (object); + + gst_vaapi_decoder_h264_destroy (base_decoder); + G_OBJECT_CLASS (gst_vaapi_decoder_h264_parent_class)->finalize (object); +} + static void gst_vaapi_decoder_h264_class_init (GstVaapiDecoderH264Class * klass) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof (GstVaapiDecoderH264); - object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; - decoder_class->create = gst_vaapi_decoder_h264_create; decoder_class->destroy = gst_vaapi_decoder_h264_destroy; decoder_class->reset = gst_vaapi_decoder_h264_reset; @@ -4728,21 +4736,17 @@ gst_vaapi_decoder_h264_class_init (GstVaapiDecoderH264Class * klass) decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame; decoder_class->end_frame = gst_vaapi_decoder_h264_end_frame; decoder_class->flush = gst_vaapi_decoder_h264_flush; - decoder_class->decode_codec_data = gst_vaapi_decoder_h264_decode_codec_data; + + object_class->finalize = gst_vaapi_decoder_h264_finalize; } -static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_h264_class (void) +static void +gst_vaapi_decoder_h264_init (GstVaapiDecoderH264 * decoder) { - static GstVaapiDecoderH264Class g_class; - static gsize g_class_init = FALSE; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_decoder_h264_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS (&g_class); + gst_vaapi_decoder_h264_create (base_decoder); } /** @@ -4830,5 +4834,6 @@ gst_vaapi_decoder_h264_get_low_latency (GstVaapiDecoderH264 * decoder) GstVaapiDecoder * gst_vaapi_decoder_h264_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new (gst_vaapi_decoder_h264_class (), display, caps); + return g_object_new (GST_TYPE_VAAPI_DECODER_H264, "display", display, + "caps", caps, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h index d170638134..999e80b27d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -27,8 +27,12 @@ G_BEGIN_DECLS -#define GST_VAAPI_DECODER_H264(decoder) \ - ((GstVaapiDecoderH264 *)(decoder)) +#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; @@ -48,8 +52,11 @@ typedef enum { 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); +gst_vaapi_decoder_h264_new (GstVaapiDisplay *display, GstCaps *caps); void gst_vaapi_decoder_h264_set_alignment(GstVaapiDecoderH264 *decoder, diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 8e6d2e5763..c7f3abb7c3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -445,6 +445,9 @@ struct _GstVaapiDecoderH265Class GstVaapiDecoderClass parent_class; }; +G_DEFINE_TYPE (GstVaapiDecoderH265, gst_vaapi_decoder_h265, + GST_TYPE_VAAPI_DECODER); + #define RSV_VCL_N10 10 #define RSV_VCL_N12 12 #define RSV_VCL_N14 14 @@ -3032,15 +3035,23 @@ gst_vaapi_decoder_h265_flush (GstVaapiDecoder * base_decoder) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static void +gst_vaapi_decoder_h265_finalize (GObject * object) +{ + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (object); + + gst_vaapi_decoder_h265_destroy (base_decoder); + G_OBJECT_CLASS (gst_vaapi_decoder_h265_parent_class)->finalize (object); +} + static void gst_vaapi_decoder_h265_class_init (GstVaapiDecoderH265Class * klass) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof (GstVaapiDecoderH265); - object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; + object_class->finalize = gst_vaapi_decoder_h265_finalize; + decoder_class->create = gst_vaapi_decoder_h265_create; decoder_class->destroy = gst_vaapi_decoder_h265_destroy; decoder_class->parse = gst_vaapi_decoder_h265_parse; @@ -3051,17 +3062,12 @@ gst_vaapi_decoder_h265_class_init (GstVaapiDecoderH265Class * klass) decoder_class->decode_codec_data = gst_vaapi_decoder_h265_decode_codec_data; } -static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_h265_class (void) +static void +gst_vaapi_decoder_h265_init (GstVaapiDecoderH265 * decoder) { - static GstVaapiDecoderH265Class g_class; - static gsize g_class_init = FALSE; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_decoder_h265_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS (&g_class); + gst_vaapi_decoder_h265_create (base_decoder); } /** @@ -3094,5 +3100,6 @@ gst_vaapi_decoder_h265_set_alignment (GstVaapiDecoderH265 * decoder, GstVaapiDecoder * gst_vaapi_decoder_h265_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new (gst_vaapi_decoder_h265_class (), display, caps); + return g_object_new (GST_TYPE_VAAPI_DECODER_H265, "display", display, + "caps", caps, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.h b/gst-libs/gst/vaapi/gstvaapidecoder_h265.h index 89f0f931bf..619d3008db 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.h @@ -28,8 +28,12 @@ G_BEGIN_DECLS -#define GST_VAAPI_DECODER_H265(decoder) \ - ((GstVaapiDecoderH265 *)(decoder)) +#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; @@ -49,11 +53,14 @@ typedef enum { 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); +gst_vaapi_decoder_h265_new (GstVaapiDisplay *display, GstCaps *caps); void -gst_vaapi_decoder_h265_set_alignment(GstVaapiDecoderH265 *decoder, +gst_vaapi_decoder_h265_set_alignment (GstVaapiDecoderH265 *decoder, GstVaapiStreamAlignH265 alignment); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 51d9aeb1a9..d17b42e511 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -96,6 +96,9 @@ struct _GstVaapiDecoderJpegClass 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) { @@ -844,15 +847,22 @@ gst_vaapi_decoder_jpeg_end_frame (GstVaapiDecoder * 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) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof (GstVaapiDecoderJpeg); - object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; + object_class->finalize = gst_vaapi_decoder_jpeg_finalize; decoder_class->create = gst_vaapi_decoder_jpeg_create; decoder_class->destroy = gst_vaapi_decoder_jpeg_destroy; @@ -862,17 +872,12 @@ gst_vaapi_decoder_jpeg_class_init (GstVaapiDecoderJpegClass * klass) decoder_class->end_frame = gst_vaapi_decoder_jpeg_end_frame; } -static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_jpeg_class (void) +static void +gst_vaapi_decoder_jpeg_init (GstVaapiDecoderJpeg * decoder) { - static GstVaapiDecoderJpegClass g_class; - static gsize g_class_init = FALSE; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_decoder_jpeg_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS (&g_class); + gst_vaapi_decoder_jpeg_create (base_decoder); } /** @@ -888,5 +893,6 @@ gst_vaapi_decoder_jpeg_class (void) GstVaapiDecoder * gst_vaapi_decoder_jpeg_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new (gst_vaapi_decoder_jpeg_class (), display, caps); + return g_object_new (GST_TYPE_VAAPI_DECODER_JPEG, "display", display, + "caps", caps, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h index 76a19cca53..876055ea42 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h @@ -28,10 +28,20 @@ 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); +gst_vaapi_decoder_jpeg_new (GstVaapiDisplay *display, GstCaps *caps); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 8d45910277..618270e6dd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -296,6 +296,9 @@ struct _GstVaapiDecoderMpeg2Class GstVaapiDecoderClass parent_class; }; +G_DEFINE_TYPE (GstVaapiDecoderMpeg2, gst_vaapi_decoder_mpeg2, + GST_TYPE_VAAPI_DECODER); + static void gst_vaapi_decoder_mpeg2_close (GstVaapiDecoderMpeg2 * decoder) { @@ -1564,15 +1567,22 @@ gst_vaapi_decoder_mpeg2_flush (GstVaapiDecoder * base_decoder) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static void +gst_vaapi_decoder_mpeg2_finalize (GObject * object) +{ + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (object); + + gst_vaapi_decoder_mpeg2_destroy (base_decoder); + G_OBJECT_CLASS (gst_vaapi_decoder_mpeg2_parent_class)->finalize (object); +} + static void gst_vaapi_decoder_mpeg2_class_init (GstVaapiDecoderMpeg2Class * klass) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof (GstVaapiDecoderMpeg2); - object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; + object_class->finalize = gst_vaapi_decoder_mpeg2_finalize; decoder_class->create = gst_vaapi_decoder_mpeg2_create; decoder_class->destroy = gst_vaapi_decoder_mpeg2_destroy; @@ -1583,17 +1593,12 @@ gst_vaapi_decoder_mpeg2_class_init (GstVaapiDecoderMpeg2Class * klass) decoder_class->flush = gst_vaapi_decoder_mpeg2_flush; } -static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_mpeg2_class (void) +static void +gst_vaapi_decoder_mpeg2_init (GstVaapiDecoderMpeg2 * decoder) { - static GstVaapiDecoderMpeg2Class g_class; - static gsize g_class_init = FALSE; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_decoder_mpeg2_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS (&g_class); + gst_vaapi_decoder_mpeg2_create (base_decoder); } /** @@ -1609,6 +1614,6 @@ gst_vaapi_decoder_mpeg2_class (void) GstVaapiDecoder * gst_vaapi_decoder_mpeg2_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new (gst_vaapi_decoder_mpeg2_class (), - display, caps); + return g_object_new (GST_TYPE_VAAPI_DECODER_MPEG2, "display", display, + "caps", caps, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h index 0fea920315..a996c59481 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h @@ -28,10 +28,20 @@ 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); +gst_vaapi_decoder_mpeg2_new (GstVaapiDisplay *display, GstCaps *caps); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index bda09b4df0..f7090df335 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -119,6 +119,9 @@ struct _GstVaapiDecoderMpeg4Class GstVaapiDecoderClass parent_class; }; +G_DEFINE_TYPE (GstVaapiDecoderMpeg4, gst_vaapi_decoder_mpeg4, + GST_TYPE_VAAPI_DECODER); + static void gst_vaapi_decoder_mpeg4_close (GstVaapiDecoderMpeg4 * decoder) { @@ -1157,35 +1160,36 @@ gst_vaapi_decoder_mpeg4_decode (GstVaapiDecoder * base_decoder, return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static void +gst_vaapi_decoder_mpeg4_finalize (GObject * object) +{ + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (object); + + gst_vaapi_decoder_mpeg4_destroy (base_decoder); + G_OBJECT_CLASS (gst_vaapi_decoder_mpeg4_parent_class)->finalize (object); +} + static void gst_vaapi_decoder_mpeg4_class_init (GstVaapiDecoderMpeg4Class * klass) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof (GstVaapiDecoderMpeg4); - object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; + object_class->finalize = gst_vaapi_decoder_mpeg4_finalize; decoder_class->create = gst_vaapi_decoder_mpeg4_create; decoder_class->destroy = gst_vaapi_decoder_mpeg4_destroy; decoder_class->parse = gst_vaapi_decoder_mpeg4_parse; decoder_class->decode = gst_vaapi_decoder_mpeg4_decode; - decoder_class->decode_codec_data = gst_vaapi_decoder_mpeg4_decode_codec_data; } -static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_mpeg4_class (void) +static void +gst_vaapi_decoder_mpeg4_init (GstVaapiDecoderMpeg4 * decoder) { - static GstVaapiDecoderMpeg4Class g_class; - static gsize g_class_init = FALSE; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_decoder_mpeg4_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS (&g_class); + gst_vaapi_decoder_mpeg4_create (base_decoder); } /** @@ -1201,6 +1205,6 @@ gst_vaapi_decoder_mpeg4_class (void) GstVaapiDecoder * gst_vaapi_decoder_mpeg4_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new (gst_vaapi_decoder_mpeg4_class (), - display, caps); + return g_object_new (GST_TYPE_VAAPI_DECODER_MPEG4, "display", display, + "caps", caps, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h index 3ce4add4e0..99d918d09a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h @@ -27,10 +27,20 @@ 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); +gst_vaapi_decoder_mpeg4_new (GstVaapiDisplay *display, GstCaps *caps); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 4d92706f85..cdd80782f7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -25,11 +25,10 @@ #ifndef GST_VAAPI_DECODER_PRIV_H #define GST_VAAPI_DECODER_PRIV_H -#include +#include "sysdeps.h" #include #include #include -#include "gstvaapiminiobject.h" G_BEGIN_DECLS @@ -37,13 +36,13 @@ G_BEGIN_DECLS ((GstVaapiDecoder *)(decoder)) #define GST_VAAPI_DECODER_CLASS(klass) \ - ((GstVaapiDecoderClass *)(klass)) + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_DECODER, GstVaapiDecoderClass)) #define GST_VAAPI_IS_DECODER_CLASS(klass) \ - ((klass) != NULL)) + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_DECODER)) #define GST_VAAPI_DECODER_GET_CLASS(obj) \ - GST_VAAPI_DECODER_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_DECODER, GstVaapiDecoderClass)) typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass; @@ -187,7 +186,7 @@ struct _GstVaapiParserState struct _GstVaapiDecoder { /*< private >*/ - GstVaapiMiniObject parent_instance; + GstObject parent_instance; gpointer user_data; GstVaapiDisplay *display; @@ -211,7 +210,7 @@ struct _GstVaapiDecoder struct _GstVaapiDecoderClass { /*< private >*/ - GstVaapiMiniObjectClass parent_class; + GstObjectClass parent_class; gboolean (*create) (GstVaapiDecoder * decoder); void (*destroy) (GstVaapiDecoder * decoder); @@ -231,12 +230,7 @@ struct _GstVaapiDecoderClass G_GNUC_INTERNAL GstVaapiDecoder * -gst_vaapi_decoder_new (const GstVaapiDecoderClass * klass, - GstVaapiDisplay * display, GstCaps * caps); - -G_GNUC_INTERNAL -void -gst_vaapi_decoder_finalize (GstVaapiDecoder * decoder); +gst_vaapi_decoder_new (GstVaapiDisplay * display, GstCaps * caps); G_GNUC_INTERNAL void diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 7fc0244b41..4bd03148ef 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -98,6 +98,9 @@ struct _GstVaapiDecoderVC1Class GstVaapiDecoderClass parent_class; }; +G_DEFINE_TYPE (GstVaapiDecoderVC1, gst_vaapi_decoder_vc1, + GST_TYPE_VAAPI_DECODER); + static GstVaapiDecoderStatus get_status (GstVC1ParserResult result) { @@ -1425,15 +1428,22 @@ gst_vaapi_decoder_vc1_flush (GstVaapiDecoder * base_decoder) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static void +gst_vaapi_decoder_vc1_finalize (GObject * object) +{ + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (object); + + gst_vaapi_decoder_vc1_destroy (base_decoder); + G_OBJECT_CLASS (gst_vaapi_decoder_vc1_parent_class)->finalize (object); +} + static void gst_vaapi_decoder_vc1_class_init (GstVaapiDecoderVC1Class * klass) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof (GstVaapiDecoderVC1); - object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; + object_class->finalize = gst_vaapi_decoder_vc1_finalize; decoder_class->create = gst_vaapi_decoder_vc1_create; decoder_class->destroy = gst_vaapi_decoder_vc1_destroy; @@ -1446,17 +1456,12 @@ gst_vaapi_decoder_vc1_class_init (GstVaapiDecoderVC1Class * klass) decoder_class->decode_codec_data = gst_vaapi_decoder_vc1_decode_codec_data; } -static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_vc1_class (void) +static void +gst_vaapi_decoder_vc1_init (GstVaapiDecoderVC1 * decoder) { - static GstVaapiDecoderVC1Class g_class; - static gsize g_class_init = FALSE; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_decoder_vc1_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS (&g_class); + gst_vaapi_decoder_vc1_create (base_decoder); } /** @@ -1472,5 +1477,6 @@ gst_vaapi_decoder_vc1_class (void) GstVaapiDecoder * gst_vaapi_decoder_vc1_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new (gst_vaapi_decoder_vc1_class (), display, caps); + return g_object_new (GST_TYPE_VAAPI_DECODER_VC1, "display", display, + "caps", caps, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h index 6127909856..6f9474f94c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h @@ -27,10 +27,20 @@ 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); +gst_vaapi_decoder_vc1_new (GstVaapiDisplay *display, GstCaps *caps); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index 1503458001..80a0f9d4b1 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -83,6 +83,9 @@ struct _GstVaapiDecoderVp8Class GstVaapiDecoderClass parent_class; }; +G_DEFINE_TYPE (GstVaapiDecoderVp8, gst_vaapi_decoder_vp8, + GST_TYPE_VAAPI_DECODER); + static GstVaapiDecoderStatus get_status (GstVp8ParserResult result) { @@ -615,15 +618,22 @@ 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) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof (GstVaapiDecoderVp8); - object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; + object_class->finalize = gst_vaapi_decoder_vp8_finalize; decoder_class->create = gst_vaapi_decoder_vp8_create; decoder_class->destroy = gst_vaapi_decoder_vp8_destroy; @@ -634,17 +644,12 @@ gst_vaapi_decoder_vp8_class_init (GstVaapiDecoderVp8Class * klass) decoder_class->flush = gst_vaapi_decoder_vp8_flush; } -static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_vp8_class (void) +static void +gst_vaapi_decoder_vp8_init (GstVaapiDecoderVp8 * decoder) { - static GstVaapiDecoderVp8Class g_class; - static gsize g_class_init = FALSE; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_decoder_vp8_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS (&g_class); + gst_vaapi_decoder_vp8_create (base_decoder); } /** @@ -660,5 +665,6 @@ gst_vaapi_decoder_vp8_class (void) GstVaapiDecoder * gst_vaapi_decoder_vp8_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new (gst_vaapi_decoder_vp8_class (), display, caps); + return g_object_new (GST_TYPE_VAAPI_DECODER_VP8, "display", display, + "caps", caps, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.h b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.h index 43a88fdc85..816f6f02a0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.h @@ -28,8 +28,18 @@ 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); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index c2cc928473..5647e01375 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -87,6 +87,9 @@ struct _GstVaapiDecoderVp9Class GstVaapiDecoderClass parent_class; }; +G_DEFINE_TYPE (GstVaapiDecoderVp9, gst_vaapi_decoder_vp9, + GST_TYPE_VAAPI_DECODER); + static GstVaapiDecoderStatus get_status (GstVp9ParserResult result) { @@ -729,15 +732,22 @@ 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) { - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - object_class->size = sizeof (GstVaapiDecoderVp9); - object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize; + object_class->finalize = gst_vaapi_decoder_vp9_finalize; decoder_class->create = gst_vaapi_decoder_vp9_create; decoder_class->destroy = gst_vaapi_decoder_vp9_destroy; @@ -748,17 +758,12 @@ gst_vaapi_decoder_vp9_class_init (GstVaapiDecoderVp9Class * klass) decoder_class->flush = gst_vaapi_decoder_vp9_flush; } -static inline const GstVaapiDecoderClass * -gst_vaapi_decoder_vp9_class (void) +static void +gst_vaapi_decoder_vp9_init (GstVaapiDecoderVp9 * decoder) { - static GstVaapiDecoderVp9Class g_class; - static gsize g_class_init = FALSE; + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); - if (g_once_init_enter (&g_class_init)) { - gst_vaapi_decoder_vp9_class_init (&g_class); - g_once_init_leave (&g_class_init, TRUE); - } - return GST_VAAPI_DECODER_CLASS (&g_class); + gst_vaapi_decoder_vp9_create (base_decoder); } /** @@ -774,5 +779,6 @@ gst_vaapi_decoder_vp9_class (void) GstVaapiDecoder * gst_vaapi_decoder_vp9_new (GstVaapiDisplay * display, GstCaps * caps) { - return gst_vaapi_decoder_new (gst_vaapi_decoder_vp9_class (), display, caps); + return g_object_new (GST_TYPE_VAAPI_DECODER_VP9, "display", display, + "caps", caps, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.h b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.h index 9d28c5e357..de97534559 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.h @@ -27,8 +27,18 @@ 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); From a75329ca94e1c2ee9bc30384aabde779e938546b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 11:50:17 +0200 Subject: [PATCH 3122/3781] libs: decoder: remove gst_vaapi_decoder_new() https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 10 ---------- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 4 ---- 2 files changed, 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index ea774d75d2..adf2a04e1c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -586,16 +586,6 @@ gst_vaapi_decoder_init (GstVaapiDecoder * decoder) gst_video_codec_frame_unref); } -GstVaapiDecoder * -gst_vaapi_decoder_new (GstVaapiDisplay * display, GstCaps * caps) -{ - g_return_val_if_fail (display != NULL, NULL); - g_return_val_if_fail (GST_IS_CAPS (caps), NULL); - - return g_object_new (GST_TYPE_VAAPI_DECODER, "display", display, - "caps", caps, NULL); -} - /** * gst_vaapi_decoder_ref: * @decoder: a #GstVaapiDecoder diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index cdd80782f7..e512d81343 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -228,10 +228,6 @@ struct _GstVaapiDecoderClass const guchar * buf, guint buf_size); }; -G_GNUC_INTERNAL -GstVaapiDecoder * -gst_vaapi_decoder_new (GstVaapiDisplay * display, GstCaps * caps); - G_GNUC_INTERNAL void gst_vaapi_decoder_set_picture_size (GstVaapiDecoder * decoder, From ad5eb75187f487bc691010933aa3e29849805b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 11:51:14 +0200 Subject: [PATCH 3123/3781] libs: decoder: remove gst_vaapi_decoder_ref() https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 14 -------------- gst-libs/gst/vaapi/gstvaapidecoder.h | 3 --- 2 files changed, 17 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index adf2a04e1c..12124b8974 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -586,20 +586,6 @@ gst_vaapi_decoder_init (GstVaapiDecoder * decoder) gst_video_codec_frame_unref); } -/** - * gst_vaapi_decoder_ref: - * @decoder: a #GstVaapiDecoder - * - * Atomically increases the reference count of the given @decoder by one. - * - * Returns: The same @decoder argument - */ -GstVaapiDecoder * -gst_vaapi_decoder_ref (GstVaapiDecoder * decoder) -{ - return gst_object_ref (decoder); -} - /** * gst_vaapi_decoder_unref: * @decoder: a #GstVaapiDecoder diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index e0a6059d07..acb26493ed 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -80,9 +80,6 @@ typedef enum { GType gst_vaapi_decoder_get_type (void) G_GNUC_CONST; -GstVaapiDecoder * -gst_vaapi_decoder_ref (GstVaapiDecoder * decoder); - void gst_vaapi_decoder_unref (GstVaapiDecoder * decoder); From 4649ac1c382abb8960f40832871548eae2f80de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 11:56:11 +0200 Subject: [PATCH 3124/3781] libs: decoder: remove gst_vaapi_decoder_unref() Replaced by gst_object_unref() in tests https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 13 ------------- gst-libs/gst/vaapi/gstvaapidecoder.h | 5 +---- tests/test-decode.c | 2 +- tests/test-subpicture.c | 2 +- 4 files changed, 3 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 12124b8974..8bc67808f8 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -586,19 +586,6 @@ gst_vaapi_decoder_init (GstVaapiDecoder * decoder) gst_video_codec_frame_unref); } -/** - * gst_vaapi_decoder_unref: - * @decoder: a #GstVaapiDecoder - * - * Atomically decreases the reference count of the @decoder by one. If - * the reference count reaches zero, the decoder will be free'd. - */ -void -gst_vaapi_decoder_unref (GstVaapiDecoder * decoder) -{ - gst_object_unref (decoder); -} - /** * gst_vaapi_decoder_replace: * @old_decoder_ptr: a pointer to a #GstVaapiDecoder diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index acb26493ed..fb4b196d83 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -80,9 +80,6 @@ typedef enum { GType gst_vaapi_decoder_get_type (void) G_GNUC_CONST; -void -gst_vaapi_decoder_unref (GstVaapiDecoder * decoder); - void gst_vaapi_decoder_replace (GstVaapiDecoder ** old_decoder_ptr, GstVaapiDecoder * new_decoder); @@ -146,7 +143,7 @@ gboolean gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps); #ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoder, gst_vaapi_decoder_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoder, gst_object_unref) #endif G_END_DECLS diff --git a/tests/test-decode.c b/tests/test-decode.c index a85eabad34..cc1688bc1c 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -134,7 +134,7 @@ main (int argc, char *argv[]) if (pixmap) gst_vaapi_pixmap_unref (pixmap); gst_vaapi_surface_proxy_unref (proxy); - gst_vaapi_decoder_unref (decoder); + gst_object_unref (decoder); gst_vaapi_window_unref (window); gst_object_unref (display); gst_object_unref (display2); diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index 588e7a7b59..c3298abe71 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -164,7 +164,7 @@ main (int argc, char *argv[]) gst_video_overlay_composition_unref (compo); gst_vaapi_surface_proxy_unref (proxy); - gst_vaapi_decoder_unref (decoder); + gst_object_unref (decoder); gst_vaapi_window_unref (window); gst_object_unref (display); g_free (g_codec_str); From 7a9f7f09c7616d4e1f65d28902e6660e42bdfa1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 13:11:41 +0200 Subject: [PATCH 3125/3781] libs: decoder: h264: remove create() and destroy() callbacks https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index dfadad6d38..f1a7b7046f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4728,8 +4728,6 @@ gst_vaapi_decoder_h264_class_init (GstVaapiDecoderH264Class * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); - decoder_class->create = gst_vaapi_decoder_h264_create; - decoder_class->destroy = gst_vaapi_decoder_h264_destroy; decoder_class->reset = gst_vaapi_decoder_h264_reset; decoder_class->parse = gst_vaapi_decoder_h264_parse; decoder_class->decode = gst_vaapi_decoder_h264_decode; From 3dbddfa682b7a3319d7f1fca42a22be852c93dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 13:13:31 +0200 Subject: [PATCH 3126/3781] libs: decoder: h265: implement reset() callback and remove create() and destroy() and use g_clear_pointer for dpb structure https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index c7f3abb7c3..1066289467 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -987,8 +987,7 @@ gst_vaapi_decoder_h265_destroy (GstVaapiDecoder * base_decoder) guint i; gst_vaapi_decoder_h265_close (decoder); - g_free (priv->dpb); - priv->dpb = NULL; + g_clear_pointer (&priv->dpb, g_free); priv->dpb_count = priv->dpb_size_max = priv->dpb_size = 0; for (i = 0; i < G_N_ELEMENTS (priv->pps); i++) @@ -1018,6 +1017,13 @@ gst_vaapi_decoder_h265_create (GstVaapiDecoder * base_decoder) return TRUE; } +static GstVaapiDecoderStatus +gst_vaapi_decoder_h265_reset (GstVaapiDecoder * base_decoder) +{ + gst_vaapi_decoder_h265_destroy (base_decoder); + gst_vaapi_decoder_h265_create (base_decoder); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} static void fill_profiles (GstVaapiProfile profiles[16], guint * n_profiles_ptr, @@ -3052,8 +3058,7 @@ gst_vaapi_decoder_h265_class_init (GstVaapiDecoderH265Class * klass) object_class->finalize = gst_vaapi_decoder_h265_finalize; - decoder_class->create = gst_vaapi_decoder_h265_create; - decoder_class->destroy = gst_vaapi_decoder_h265_destroy; + decoder_class->reset = gst_vaapi_decoder_h265_reset; decoder_class->parse = gst_vaapi_decoder_h265_parse; decoder_class->decode = gst_vaapi_decoder_h265_decode; decoder_class->start_frame = gst_vaapi_decoder_h265_start_frame; From c1d65cf1a4db3d987e7ab1fd436cfe4911930027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 13:22:07 +0200 Subject: [PATCH 3127/3781] libs: decoder: jpeg: implement reset() callback and remove create() and destroy() callbacks. https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index d17b42e511..9c2d842c10 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -159,6 +159,14 @@ gst_vaapi_decoder_jpeg_create (GstVaapiDecoder * base_decoder) 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 GstVaapiDecoderStatus ensure_context (GstVaapiDecoderJpeg * decoder) { @@ -864,8 +872,7 @@ gst_vaapi_decoder_jpeg_class_init (GstVaapiDecoderJpegClass * klass) object_class->finalize = gst_vaapi_decoder_jpeg_finalize; - decoder_class->create = gst_vaapi_decoder_jpeg_create; - decoder_class->destroy = gst_vaapi_decoder_jpeg_destroy; + 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; From 0374a8c0a5921eaa68a6759e4b76e5fb54822c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 13:22:45 +0200 Subject: [PATCH 3128/3781] libs: decoder: mpeg2: implement reset() callback remove create() and destroy() callbacks https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 618270e6dd..17ebcd4abc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -361,6 +361,14 @@ gst_vaapi_decoder_mpeg2_create (GstVaapiDecoder * base_decoder) return TRUE; } +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg2_reset (GstVaapiDecoder * base_decoder) +{ + gst_vaapi_decoder_mpeg2_destroy (base_decoder); + gst_vaapi_decoder_mpeg2_create (base_decoder); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static inline void copy_quant_matrix (guint8 dst[64], const guint8 src[64]) { @@ -1584,8 +1592,7 @@ gst_vaapi_decoder_mpeg2_class_init (GstVaapiDecoderMpeg2Class * klass) object_class->finalize = gst_vaapi_decoder_mpeg2_finalize; - decoder_class->create = gst_vaapi_decoder_mpeg2_create; - decoder_class->destroy = gst_vaapi_decoder_mpeg2_destroy; + decoder_class->reset = gst_vaapi_decoder_mpeg2_reset; decoder_class->parse = gst_vaapi_decoder_mpeg2_parse; decoder_class->decode = gst_vaapi_decoder_mpeg2_decode; decoder_class->start_frame = gst_vaapi_decoder_mpeg2_start_frame; From 5b3f6eb285bae96e271c0edeebb899f5046f08ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 13:24:13 +0200 Subject: [PATCH 3129/3781] libs: decoder: mpeg4: implement reset() callback remove destroy() and create() callback https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index f7090df335..c8049a1eca 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -183,6 +183,14 @@ gst_vaapi_decoder_mpeg4_create (GstVaapiDecoder * base_decoder) return TRUE; } +static GstVaapiDecoderStatus +gst_vaapi_decoder_mpeg4_reset (GstVaapiDecoder * base_decoder) +{ + gst_vaapi_decoder_mpeg4_destroy (base_decoder); + gst_vaapi_decoder_mpeg4_create (base_decoder); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static inline void copy_quant_matrix (guint8 dst[64], const guint8 src[64]) { @@ -1177,8 +1185,7 @@ gst_vaapi_decoder_mpeg4_class_init (GstVaapiDecoderMpeg4Class * klass) object_class->finalize = gst_vaapi_decoder_mpeg4_finalize; - decoder_class->create = gst_vaapi_decoder_mpeg4_create; - decoder_class->destroy = gst_vaapi_decoder_mpeg4_destroy; + decoder_class->reset = gst_vaapi_decoder_mpeg4_reset; decoder_class->parse = gst_vaapi_decoder_mpeg4_parse; decoder_class->decode = gst_vaapi_decoder_mpeg4_decode; decoder_class->decode_codec_data = gst_vaapi_decoder_mpeg4_decode_codec_data; From 2b207a47cbbe7811894b9df3a7f6d16df1665d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 13:24:39 +0200 Subject: [PATCH 3130/3781] libs: decoder: vc1: implement reset() callback remove destroy() and create() callbacks use g_clear_pointer for rbdu_buffer no cast for enum https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 4bd03148ef..cf05ba320b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -170,8 +170,7 @@ gst_vaapi_decoder_vc1_destroy (GstVaapiDecoder * base_decoder) gst_vaapi_decoder_vc1_close (decoder); if (priv->rbdu_buffer) { - g_free (priv->rbdu_buffer); - priv->rbdu_buffer = NULL; + g_clear_pointer (&priv->rbdu_buffer, g_free); priv->rbdu_buffer_size = 0; } } @@ -186,12 +185,20 @@ gst_vaapi_decoder_vc1_create (GstVaapiDecoder * base_decoder) priv->size_changed = priv->profile_changed = priv->closed_entry = priv->broken_link = FALSE; - priv->profile = (GstVaapiProfile) 0; + priv->profile = GST_VAAPI_PROFILE_UNKNOWN; priv->rndctrl = 0; priv->width = priv->height = 0; return TRUE; } +static GstVaapiDecoderStatus +gst_vaapi_decoder_vc1_reset (GstVaapiDecoder * base_decoder) +{ + gst_vaapi_decoder_vc1_destroy (base_decoder); + gst_vaapi_decoder_vc1_create (base_decoder); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + static GstVaapiDecoderStatus ensure_context (GstVaapiDecoderVC1 * decoder) { @@ -1445,8 +1452,7 @@ gst_vaapi_decoder_vc1_class_init (GstVaapiDecoderVC1Class * klass) object_class->finalize = gst_vaapi_decoder_vc1_finalize; - decoder_class->create = gst_vaapi_decoder_vc1_create; - decoder_class->destroy = gst_vaapi_decoder_vc1_destroy; + decoder_class->reset = gst_vaapi_decoder_vc1_reset; decoder_class->parse = gst_vaapi_decoder_vc1_parse; decoder_class->decode = gst_vaapi_decoder_vc1_decode; decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame; From e493420375bb5ca1d95aaedef5a8b07046552a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 13:25:37 +0200 Subject: [PATCH 3131/3781] libs: decoder: vp8: implement reset() callback remove create() and destroy() callbacks https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index 80a0f9d4b1..dbb8b46398 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -147,6 +147,15 @@ gst_vaapi_decoder_vp8_create (GstVaapiDecoder * base_decoder) 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) { @@ -635,8 +644,7 @@ gst_vaapi_decoder_vp8_class_init (GstVaapiDecoderVp8Class * klass) object_class->finalize = gst_vaapi_decoder_vp8_finalize; - decoder_class->create = gst_vaapi_decoder_vp8_create; - decoder_class->destroy = gst_vaapi_decoder_vp8_destroy; + 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; From 60dad9fa028b99a4cc73f365ebe20f96c67f7d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 13:26:01 +0200 Subject: [PATCH 3132/3781] libs: decoder: vp9: implement reset() callback remove destroy() and create() callback https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 5647e01375..260a35e7ab 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -153,6 +153,15 @@ gst_vaapi_decoder_vp9_create (GstVaapiDecoder * base_decoder) 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) @@ -749,8 +758,7 @@ gst_vaapi_decoder_vp9_class_init (GstVaapiDecoderVp9Class * klass) object_class->finalize = gst_vaapi_decoder_vp9_finalize; - decoder_class->create = gst_vaapi_decoder_vp9_create; - decoder_class->destroy = gst_vaapi_decoder_vp9_destroy; + 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; From a2f923f9e974a12fc71f158783c23fe12dfb2d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 May 2018 13:38:00 +0200 Subject: [PATCH 3133/3781] libs: decoder: remove destoy() and create() callbacks They were all replaced by reset() https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapidecoder.c | 6 +----- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 -- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 8bc67808f8..6c89713678 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -1084,11 +1084,7 @@ gst_vaapi_decoder_reset (GstVaapiDecoder * decoder) if (klass->reset) { ret = klass->reset (decoder); } else { - if (klass->destroy) - klass->destroy (decoder); - if (klass->create) - if (!klass->create (decoder)) - ret = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + GST_WARNING_OBJECT (decoder, "missing reset() implementation"); } if (ret != GST_VAAPI_DECODER_STATUS_SUCCESS) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index e512d81343..10b8d2cf77 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -212,8 +212,6 @@ struct _GstVaapiDecoderClass /*< private >*/ GstObjectClass parent_class; - gboolean (*create) (GstVaapiDecoder * decoder); - void (*destroy) (GstVaapiDecoder * decoder); GstVaapiDecoderStatus (*parse) (GstVaapiDecoder * decoder, GstAdapter * adapter, gboolean at_eos, struct _GstVaapiDecoderUnit * unit); From 99183e01848c79692161247c95993e6b57f07167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 22 May 2018 14:26:48 +0200 Subject: [PATCH 3134/3781] libs: filter: refactor filter as gobject https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapifilter.c | 118 +++++++++++++++++++++------- gst-libs/gst/vaapi/gstvaapifilter.h | 10 +++ 2 files changed, 99 insertions(+), 29 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 3a96b82e3a..86cd82def3 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -33,7 +33,7 @@ #define DEBUG 1 #include "gstvaapidebug.h" -#define GST_VAAPI_FILTER(obj) \ +#define GST_VAAPI_FILTER_CAST(obj) \ ((GstVaapiFilter *)(obj)) typedef struct _GstVaapiFilterOpData GstVaapiFilterOpData; @@ -55,7 +55,7 @@ struct _GstVaapiFilterOpData struct _GstVaapiFilter { /*< private > */ - GstVaapiMiniObject parent_instance; + GstObject parent_instance; GstVaapiDisplay *display; VADisplay va_display; @@ -73,6 +73,15 @@ struct _GstVaapiFilter guint use_target_rect:1; }; +typedef struct _GstVaapiFilterClass GstVaapiFilterClass; +struct _GstVaapiFilterClass +{ + /*< private > */ + GstObjectClass parent_class; +}; + +G_DEFINE_TYPE (GstVaapiFilter, gst_vaapi_filter, GST_TYPE_OBJECT); + /* ------------------------------------------------------------------------- */ /* --- VPP Types --- */ /* ------------------------------------------------------------------------- */ @@ -268,6 +277,11 @@ vpp_get_filter_caps (GstVaapiFilter * filter, VAProcFilterType type, #define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN #define DEFAULT_SCALING GST_VAAPI_SCALE_METHOD_DEFAULT +enum +{ + PROP_DISPLAY = 1, +}; + enum { PROP_0, @@ -1025,28 +1039,26 @@ find_format (GstVaapiFilter * filter, GstVideoFormat format) /* ------------------------------------------------------------------------- */ #if USE_VA_VPP -static gboolean -gst_vaapi_filter_init (GstVaapiFilter * filter, GstVaapiDisplay * display) +static void +gst_vaapi_filter_init (GstVaapiFilter * filter) { - VAStatus va_status; - - filter->display = gst_object_ref (display); - filter->va_display = GST_VAAPI_DISPLAY_VADISPLAY (display); filter->va_config = VA_INVALID_ID; filter->va_context = VA_INVALID_ID; filter->format = DEFAULT_FORMAT; filter->forward_references = g_array_sized_new (FALSE, FALSE, sizeof (VASurfaceID), 4); - if (!filter->forward_references) - return FALSE; filter->backward_references = g_array_sized_new (FALSE, FALSE, sizeof (VASurfaceID), 4); - if (!filter->backward_references) - return FALSE; +} - if (!GST_VAAPI_DISPLAY_HAS_VPP (display)) +static gboolean +gst_vaapi_filter_initialize (GstVaapiFilter * filter) +{ + VAStatus va_status; + + if (!filter->display) return FALSE; va_status = vaCreateConfig (filter->va_display, VAProfileNone, @@ -1062,8 +1074,9 @@ gst_vaapi_filter_init (GstVaapiFilter * filter, GstVaapiDisplay * display) } static void -gst_vaapi_filter_finalize (GstVaapiFilter * filter) +gst_vaapi_filter_finalize (GObject * object) { + GstVaapiFilter *const filter = GST_VAAPI_FILTER (object); guint i; GST_VAAPI_DISPLAY_LOCK (filter->display); @@ -1103,16 +1116,68 @@ gst_vaapi_filter_finalize (GstVaapiFilter * filter) g_array_unref (filter->formats); filter->formats = NULL; } + + G_OBJECT_CLASS (gst_vaapi_filter_parent_class)->finalize (object); } -static inline const GstVaapiMiniObjectClass * -gst_vaapi_filter_class (void) +static void +gst_vaapi_filter_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) { - static const GstVaapiMiniObjectClass GstVaapiFilterClass = { - sizeof (GstVaapiFilter), - (GDestroyNotify) gst_vaapi_filter_finalize - }; - return &GstVaapiFilterClass; + GstVaapiFilter *const filter = GST_VAAPI_FILTER (object); + + switch (property_id) { + case PROP_DISPLAY:{ + GstVaapiDisplay *display = g_value_get_object (value);; + + if (display) { + if (GST_VAAPI_DISPLAY_HAS_VPP (display)) { + filter->display = gst_object_ref (display); + filter->va_display = GST_VAAPI_DISPLAY_VADISPLAY (filter->display); + } else { + GST_WARNING_OBJECT (filter, "VA display doesn't support VPP"); + } + } + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +gst_vaapi_filter_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiFilter *const filter = GST_VAAPI_FILTER (object); + + switch (property_id) { + case PROP_DISPLAY: + g_value_set_object (value, filter->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +gst_vaapi_filter_class_init (GstVaapiFilterClass * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gst_vaapi_filter_set_property; + object_class->get_property = gst_vaapi_filter_get_property; + object_class->finalize = gst_vaapi_filter_finalize; + + /** + * GstVaapiFilter:display: + * + * #GstVaapiDisplay to be used. + */ + 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)); } #endif @@ -1131,12 +1196,8 @@ gst_vaapi_filter_new (GstVaapiDisplay * display) #if USE_VA_VPP GstVaapiFilter *filter; - filter = (GstVaapiFilter *) - gst_vaapi_mini_object_new0 (gst_vaapi_filter_class ()); - if (!filter) - return NULL; - - if (!gst_vaapi_filter_init (filter, display)) + filter = g_object_new (GST_TYPE_VAAPI_FILTER, "display", display, NULL); + if (!gst_vaapi_filter_initialize (filter)) goto error; return filter; @@ -1201,8 +1262,7 @@ gst_vaapi_filter_replace (GstVaapiFilter ** old_filter_ptr, { g_return_if_fail (old_filter_ptr != NULL); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_filter_ptr, - GST_VAAPI_MINI_OBJECT (new_filter)); + gst_object_replace ((GstObject **) old_filter_ptr, GST_OBJECT (new_filter)); } /** diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 667dd69856..358137daa7 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -28,6 +28,13 @@ 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; @@ -167,6 +174,9 @@ 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); From ae46b1a91a5e0f48a4c33c71f04599ca36dc5144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 22 May 2018 14:28:40 +0200 Subject: [PATCH 3135/3781] libs: filter: remove custom ref() and unref() Replacing them by gst_object_ref() and gst_object_unref() https://bugzilla.gnome.org/show_bug.cgi?id=796308 --- gst-libs/gst/vaapi/gstvaapifilter.c | 35 +----------------------- gst-libs/gst/vaapi/gstvaapifilter.h | 6 ---- gst-libs/gst/vaapi/gstvaapisurface_egl.c | 2 +- tests/test-filter.c | 2 +- 4 files changed, 3 insertions(+), 42 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 86cd82def3..62f45c1fea 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1204,7 +1204,7 @@ gst_vaapi_filter_new (GstVaapiDisplay * display) /* ERRORS */ error: { - gst_vaapi_filter_unref (filter); + gst_object_unref (filter); return NULL; } #else @@ -1214,39 +1214,6 @@ error: #endif } -/** - * gst_vaapi_filter_ref: - * @filter: a #GstVaapiFilter - * - * Atomically increases the reference count of the given @filter by one. - * - * Returns: The same @filter argument - */ -GstVaapiFilter * -gst_vaapi_filter_ref (GstVaapiFilter * filter) -{ - g_return_val_if_fail (filter != NULL, NULL); - - return - GST_VAAPI_FILTER (gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT - (filter))); -} - -/** - * gst_vaapi_filter_unref: - * @filter: a #GstVaapiFilter - * - * Atomically decreases the reference count of the @filter by one. If - * the reference count reaches zero, the filter will be free'd. - */ -void -gst_vaapi_filter_unref (GstVaapiFilter * filter) -{ - g_return_if_fail (filter != NULL); - - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (filter)); -} - /** * gst_vaapi_filter_replace: * @old_filter_ptr: a pointer to a #GstVaapiFilter diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 358137daa7..5c97450aa5 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -180,12 +180,6 @@ gst_vaapi_filter_get_type (void) G_GNUC_CONST; GstVaapiFilter * gst_vaapi_filter_new (GstVaapiDisplay * display); -GstVaapiFilter * -gst_vaapi_filter_ref (GstVaapiFilter * filter); - -void -gst_vaapi_filter_unref (GstVaapiFilter * filter); - void gst_vaapi_filter_replace (GstVaapiFilter ** old_filter_ptr, GstVaapiFilter * new_filter); diff --git a/gst-libs/gst/vaapi/gstvaapisurface_egl.c b/gst-libs/gst/vaapi/gstvaapisurface_egl.c index 8ebd80186f..338cfaf989 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_egl.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_egl.c @@ -162,7 +162,7 @@ create_surface_from_egl_image (GstVaapiDisplayEGL * display, goto error_convert_surface; gst_vaapi_object_unref (img_surface); - gst_vaapi_filter_unref (filter); + gst_object_unref (filter); return out_surface; /* ERRORS */ diff --git a/tests/test-filter.c b/tests/test-filter.c index 380ca67b86..8e6b20807c 100644 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -440,7 +440,7 @@ main (int argc, char *argv[]) pause (); - gst_vaapi_filter_unref (filter); + gst_object_unref (filter); gst_vaapi_object_unref (dst_surface); gst_vaapi_object_unref (src_surface); gst_vaapi_window_unref (window); From 148d75c8af116e4128858e75dc393b7f0086cff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 3 Sep 2018 13:56:52 +0200 Subject: [PATCH 3136/3781] libs: filter: add gobject's cleanup function --- gst-libs/gst/vaapi/gstvaapifilter.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 5c97450aa5..98798c9ae7 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -273,4 +273,9 @@ gst_vaapi_filter_get_scaling_default (GstVaapiFilter * filter); gboolean gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter); + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiFilter, gst_object_unref) +#endif + #endif /* GST_VAAPI_FILTER_H */ From 7b077cdcb96864726ccf682bed03384aaa4f7588 Mon Sep 17 00:00:00 2001 From: Jimmy Ohn Date: Wed, 12 Sep 2018 19:06:22 +0900 Subject: [PATCH 3137/3781] libs: use g_clear_pointer() when possible https://bugzilla.gnome.org/show_bug.cgi?id=797131 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 7 ++--- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 11 ++------ gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 28 ++++---------------- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 5 +--- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 22 +++------------ 5 files changed, 14 insertions(+), 59 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index ad6ebcbe22..40b186a533 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -846,11 +846,8 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) klass->close_display (display); } - g_free (priv->display_name); - priv->display_name = NULL; - - g_free (priv->vendor_string); - priv->vendor_string = NULL; + g_clear_pointer (&priv->display_name, g_free); + g_clear_pointer (&priv->vendor_string, g_free); gst_vaapi_display_replace (&priv->parent, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index ea05289e44..f67acc9915 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -304,15 +304,8 @@ gst_vaapi_display_drm_close_display (GstVaapiDisplay * display) priv->drm_device = -1; } - if (priv->device_path) { - g_free (priv->device_path); - priv->device_path = NULL; - } - - if (priv->device_path_default) { - g_free (priv->device_path_default); - priv->device_path_default = NULL; - } + g_clear_pointer (&priv->device_path, g_free); + g_clear_pointer (&priv->device_path_default, g_free); } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 8fde3efbdc..494c41f4dc 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -194,25 +194,10 @@ gst_vaapi_display_wayland_close_display (GstVaapiDisplay * display) GstVaapiDisplayWaylandPrivate *const priv = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); - if (priv->output) { - wl_output_destroy (priv->output); - priv->output = NULL; - } - - if (priv->shell) { - wl_shell_destroy (priv->shell); - priv->shell = NULL; - } - - if (priv->compositor) { - wl_compositor_destroy (priv->compositor); - priv->compositor = NULL; - } - - if (priv->registry) { - wl_registry_destroy (priv->registry); - priv->registry = NULL; - } + g_clear_pointer (&priv->output, wl_output_destroy); + g_clear_pointer (&priv->shell, wl_shell_destroy); + g_clear_pointer (&priv->compositor, wl_compositor_destroy); + g_clear_pointer (&priv->registry, wl_registry_destroy); if (priv->wl_display) { if (!priv->use_foreign_display) @@ -220,10 +205,7 @@ gst_vaapi_display_wayland_close_display (GstVaapiDisplay * display) priv->wl_display = NULL; } - if (priv->display_name) { - g_free (priv->display_name); - priv->display_name = NULL; - } + g_clear_pointer (&priv->display_name, g_free); } static gboolean diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 6a3fdbe748..2ce465aba5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -180,10 +180,7 @@ gst_vaapi_display_x11_close_display (GstVaapiDisplay * display) priv->x11_display = NULL; } - if (priv->display_name) { - g_free (priv->display_name); - priv->display_name = NULL; - } + g_clear_pointer (&priv->display_name, g_free); } static void diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index bd2d89d836..80c274eab9 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -95,10 +95,7 @@ frame_state_free (FrameState * frame) } gst_vaapi_video_pool_replace (&frame->surface_pool, NULL); - if (frame->callback) { - wl_callback_destroy (frame->callback); - frame->callback = NULL; - } + g_clear_pointer (&frame->callback, wl_callback_destroy); g_slice_free (FrameState, frame); } @@ -337,20 +334,9 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) if (priv->event_queue) wl_display_roundtrip_queue (wl_display, priv->event_queue); - if (priv->shell_surface) { - wl_shell_surface_destroy (priv->shell_surface); - priv->shell_surface = NULL; - } - - if (priv->surface) { - wl_surface_destroy (priv->surface); - priv->surface = NULL; - } - - if (priv->event_queue) { - wl_event_queue_destroy (priv->event_queue); - priv->event_queue = NULL; - } + g_clear_pointer (&priv->shell_surface, wl_shell_surface_destroy); + g_clear_pointer (&priv->surface, wl_surface_destroy); + g_clear_pointer (&priv->event_queue, wl_event_queue_destroy); gst_poll_free (priv->poll); From f4f935b6f405cf55b586242e04bb27c11cf090ed Mon Sep 17 00:00:00 2001 From: Wangfei Date: Wed, 19 Sep 2018 10:16:36 +0800 Subject: [PATCH 3138/3781] libs: dec: h265: fix the macros used for IDC profile profile_idc flag in SPS only indicate the IDC profile, which may need some other flags together to get the real profile. https://bugzilla.gnome.org/show_bug.cgi?id=797160 --- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 24199b9102..ef43b3c9b1 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -137,13 +137,13 @@ gst_vaapi_utils_h265_get_profile (guint8 profile_idc) GstVaapiProfile profile; switch (profile_idc) { - case GST_H265_PROFILE_MAIN: + case GST_H265_PROFILE_IDC_MAIN: profile = GST_VAAPI_PROFILE_H265_MAIN; break; - case GST_H265_PROFILE_MAIN_10: + case GST_H265_PROFILE_IDC_MAIN_10: profile = GST_VAAPI_PROFILE_H265_MAIN10; break; - case GST_H265_PROFILE_MAIN_STILL_PICTURE: + case GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE: profile = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; break; default: From 4505acc52294698cac077c514a019d31b786d0dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 13 Sep 2018 12:22:42 +0200 Subject: [PATCH 3139/3781] libs: remove dependency on IN_LIBGSTVAAPI_CORE This conditional code was when libgstvaapi was intended to be library used outside GStreamer. This not the case anymore, thus removing it. https://bugzilla.gnome.org/show_bug.cgi?id=797139 --- gst-libs/gst/vaapi/Makefile.am | 1 - gst-libs/gst/vaapi/gstvaapibufferproxy.c | 19 ++++---- gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h | 25 ---------- gst-libs/gst/vaapi/gstvaapiminiobject.c | 39 +++++++++++++--- gst-libs/gst/vaapi/gstvaapiminiobject.h | 46 ------------------- gst-libs/gst/vaapi/gstvaapiobject.c | 12 ++--- gst-libs/gst/vaapi/gstvaapiobject_priv.h | 34 -------------- gst-libs/gst/vaapi/gstvaapipixmap.c | 16 +++---- gst-libs/gst/vaapi/gstvaapipixmap_priv.h | 25 ---------- gst-libs/gst/vaapi/gstvaapitexture.c | 12 ++--- gst-libs/gst/vaapi/gstvaapitexture_priv.h | 25 ---------- gst-libs/gst/vaapi/gstvaapiwindow.c | 14 ++---- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 25 ---------- gst-libs/gst/vaapi/meson.build | 2 +- 14 files changed, 61 insertions(+), 234 deletions(-) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index f8e4992725..54c138858f 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -21,7 +21,6 @@ noinst_LTLIBRARIES += libgstvaapi-wayland.la endif libgstvaapi_cflags = \ - -DIN_LIBGSTVAAPI_CORE \ -DGST_USE_UNSTABLE_API \ -I$(top_srcdir)/gst-libs \ -I$(top_builddir)/gst-libs \ diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index 44c6126135..b4fc0b7d7c 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -30,11 +30,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -/* Ensure those symbols are actually defined in the resulting libraries */ -#undef gst_vaapi_buffer_proxy_ref -#undef gst_vaapi_buffer_proxy_unref -#undef gst_vaapi_buffer_proxy_replace - guint from_GstVaapiBufferMemoryType (guint type) { @@ -185,7 +180,7 @@ gst_vaapi_buffer_proxy_new (guintptr handle, guint type, gsize size, error_unsupported_mem_type: { GST_ERROR ("unsupported buffer type (%d)", proxy->type); - gst_vaapi_buffer_proxy_unref_internal (proxy); + gst_vaapi_buffer_proxy_unref (proxy); return NULL; } #else @@ -225,13 +220,13 @@ gst_vaapi_buffer_proxy_new_from_object (GstVaapiObject * object, error_unsupported_mem_type: { GST_ERROR ("unsupported buffer type (%d)", proxy->type); - gst_vaapi_buffer_proxy_unref_internal (proxy); + 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_internal (proxy); + gst_vaapi_buffer_proxy_unref (proxy); return NULL; } #else @@ -252,7 +247,8 @@ gst_vaapi_buffer_proxy_ref (GstVaapiBufferProxy * proxy) { g_return_val_if_fail (proxy != NULL, NULL); - return gst_vaapi_buffer_proxy_ref_internal (proxy); + return (GstVaapiBufferProxy *) + gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (proxy)); } /** @@ -267,7 +263,7 @@ gst_vaapi_buffer_proxy_unref (GstVaapiBufferProxy * proxy) { g_return_if_fail (proxy != NULL); - gst_vaapi_buffer_proxy_unref_internal (proxy); + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (proxy)); } /** @@ -285,7 +281,8 @@ gst_vaapi_buffer_proxy_replace (GstVaapiBufferProxy ** old_proxy_ptr, { g_return_if_fail (old_proxy_ptr != NULL); - gst_vaapi_buffer_proxy_replace_internal (old_proxy_ptr, new_proxy); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_proxy_ptr), + GST_VAAPI_MINI_OBJECT (new_proxy)); } /** diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h index 2cbbbf9cf8..39893e687b 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h @@ -87,31 +87,6 @@ G_GNUC_INTERNAL guint to_GstVaapiBufferMemoryType (guint va_type); -/* Inline reference counting for core libgstvaapi library */ -#ifdef IN_LIBGSTVAAPI_CORE -#define gst_vaapi_buffer_proxy_ref_internal(proxy) \ - ((gpointer) gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (proxy))) - -#define gst_vaapi_buffer_proxy_unref_internal(proxy) \ - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (proxy)) - -#define gst_vaapi_buffer_proxy_replace_internal(old_proxy_ptr, new_proxy) \ - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **)(old_proxy_ptr), \ - GST_VAAPI_MINI_OBJECT (new_proxy)) - -#undef gst_vaapi_buffer_proxy_ref -#define gst_vaapi_buffer_proxy_ref(proxy) \ - gst_vaapi_buffer_proxy_ref_internal ((proxy)) - -#undef gst_vaapi_buffer_proxy_unref -#define gst_vaapi_buffer_proxy_unref(proxy) \ - gst_vaapi_buffer_proxy_unref_internal ((proxy)) - -#undef gst_vaapi_buffer_proxy_replace -#define gst_vaapi_buffer_proxy_replace(old_proxy_ptr, new_proxy) \ - gst_vaapi_buffer_proxy_replace_internal ((old_proxy_ptr), (new_proxy)) -#endif - G_END_DECLS #endif /* GST_VAAPI_BUFFER_PROXY_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.c b/gst-libs/gst/vaapi/gstvaapiminiobject.c index f146d0faf3..52052ad3d2 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.c @@ -23,12 +23,7 @@ #include #include "gstvaapiminiobject.h" -/* Ensure those symbols are actually defined in the resulting libraries */ -#undef gst_vaapi_mini_object_ref -#undef gst_vaapi_mini_object_unref -#undef gst_vaapi_mini_object_replace - -void +static void gst_vaapi_mini_object_free (GstVaapiMiniObject * object) { const GstVaapiMiniObjectClass *const klass = object->object_class; @@ -108,6 +103,22 @@ gst_vaapi_mini_object_new0 (const GstVaapiMiniObjectClass * object_class) return object; } +/** + * gst_vaapi_mini_object_ref_internal: + * @object: a #GstVaapiMiniObject + * + * Atomically increases the reference count of the given @object by one. + * This is an internal function that does not do any run-time type check. + * + * Returns: The same @object argument + */ +static inline GstVaapiMiniObject * +gst_vaapi_mini_object_ref_internal (GstVaapiMiniObject * object) +{ + g_atomic_int_inc (&object->ref_count); + return object; +} + /** * gst_vaapi_mini_object_ref: * @object: a #GstVaapiMiniObject @@ -124,6 +135,22 @@ gst_vaapi_mini_object_ref (GstVaapiMiniObject * object) return gst_vaapi_mini_object_ref_internal (object); } +/** + * gst_vaapi_mini_object_unref_internal: + * @object: a #GstVaapiMiniObject + * + * Atomically decreases the reference count of the @object by one. If + * the reference count reaches zero, the object will be free'd. + * + * This is an internal function that does not do any run-time type check. + */ +static inline void +gst_vaapi_mini_object_unref_internal (GstVaapiMiniObject * object) +{ + if (g_atomic_int_dec_and_test (&object->ref_count)) + gst_vaapi_mini_object_free (object); +} + /** * gst_vaapi_mini_object_unref: * @object: a #GstVaapiMiniObject diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.h b/gst-libs/gst/vaapi/gstvaapiminiobject.h index 3f30189121..778fc07b37 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.h @@ -157,52 +157,6 @@ void gst_vaapi_mini_object_replace (GstVaapiMiniObject ** old_object_ptr, GstVaapiMiniObject * new_object); -#ifdef IN_LIBGSTVAAPI_CORE -#undef gst_vaapi_mini_object_ref -#define gst_vaapi_mini_object_ref(object) \ - gst_vaapi_mini_object_ref_internal (object) - -#undef gst_vaapi_mini_object_unref -#define gst_vaapi_mini_object_unref(object) \ - gst_vaapi_mini_object_unref_internal (object) - -G_GNUC_INTERNAL -void -gst_vaapi_mini_object_free (GstVaapiMiniObject * object); - -/** - * gst_vaapi_mini_object_ref_internal: - * @object: a #GstVaapiMiniObject - * - * Atomically increases the reference count of the given @object by one. - * This is an internal function that does not do any run-time type check. - * - * Returns: The same @object argument - */ -static inline GstVaapiMiniObject * -gst_vaapi_mini_object_ref_internal (GstVaapiMiniObject * object) -{ - g_atomic_int_inc (&object->ref_count); - return object; -} - -/** - * gst_vaapi_mini_object_unref_internal: - * @object: a #GstVaapiMiniObject - * - * Atomically decreases the reference count of the @object by one. If - * the reference count reaches zero, the object will be free'd. - * - * This is an internal function that does not do any run-time type check. - */ -static inline void -gst_vaapi_mini_object_unref_internal (GstVaapiMiniObject * object) -{ - if (g_atomic_int_dec_and_test (&object->ref_count)) - gst_vaapi_mini_object_free (object); -} -#endif - G_END_DECLS #endif /* GST_VAAPI_MINI_OBJECT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 8130f80427..db649e0e20 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -36,11 +36,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -/* Ensure those symbols are actually defined in the resulting libraries */ -#undef gst_vaapi_object_ref -#undef gst_vaapi_object_unref -#undef gst_vaapi_object_replace - static void gst_vaapi_object_finalize (GstVaapiObject * object) { @@ -114,7 +109,7 @@ gst_vaapi_object_new (const GstVaapiObjectClass * klass, gpointer gst_vaapi_object_ref (gpointer object) { - return gst_vaapi_object_ref_internal (object); + return gst_vaapi_mini_object_ref (object); } /** @@ -127,7 +122,7 @@ gst_vaapi_object_ref (gpointer object) void gst_vaapi_object_unref (gpointer object) { - gst_vaapi_object_unref_internal (object); + gst_vaapi_mini_object_unref (object); } /** @@ -142,7 +137,8 @@ gst_vaapi_object_unref (gpointer object) void gst_vaapi_object_replace (gpointer old_object_ptr, gpointer new_object) { - gst_vaapi_object_replace_internal (old_object_ptr, new_object); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_object_ptr, + new_object); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 7a18f3bd13..3515595120 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -195,40 +195,6 @@ gpointer gst_vaapi_object_new (const GstVaapiObjectClass * klass, GstVaapiDisplay * display); -/* Inline reference counting for core libgstvaapi library */ -#ifdef IN_LIBGSTVAAPI_CORE -static inline gpointer -gst_vaapi_object_ref_internal (gpointer object) -{ - return gst_vaapi_mini_object_ref (object); -} - -static inline void -gst_vaapi_object_unref_internal (gpointer object) -{ - gst_vaapi_mini_object_unref (object); -} - -static inline void -gst_vaapi_object_replace_internal (gpointer old_object_ptr, gpointer new_object) -{ - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_object_ptr, - new_object); -} - -#undef gst_vaapi_object_ref -#define gst_vaapi_object_ref(object) \ - gst_vaapi_object_ref_internal ((object)) - -#undef gst_vaapi_object_unref -#define gst_vaapi_object_unref(object) \ - gst_vaapi_object_unref_internal ((object)) - -#undef gst_vaapi_object_replace -#define gst_vaapi_object_replace(old_object_ptr, new_object) \ - gst_vaapi_object_replace_internal ((old_object_ptr), (new_object)) -#endif - G_END_DECLS #endif /* GST_VAAPI_OBJECT_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapipixmap.c b/gst-libs/gst/vaapi/gstvaapipixmap.c index 33acb2ea00..ebbfdd5bd4 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap.c +++ b/gst-libs/gst/vaapi/gstvaapipixmap.c @@ -33,11 +33,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -/* Ensure those symbols are actually defined in the resulting libraries */ -#undef gst_vaapi_pixmap_ref -#undef gst_vaapi_pixmap_unref -#undef gst_vaapi_pixmap_replace - static inline GstVaapiPixmap * gst_vaapi_pixmap_new_internal (const GstVaapiPixmapClass * pixmap_class, GstVaapiDisplay * display) @@ -73,7 +68,7 @@ gst_vaapi_pixmap_new (const GstVaapiPixmapClass * pixmap_class, /* ERRORS */ error: { - gst_vaapi_pixmap_unref_internal (pixmap); + gst_vaapi_pixmap_unref (pixmap); return NULL; } } @@ -97,7 +92,7 @@ gst_vaapi_pixmap_new_from_native (const GstVaapiPixmapClass * pixmap_class, /* ERRORS */ error: { - gst_vaapi_pixmap_unref_internal (pixmap); + gst_vaapi_pixmap_unref (pixmap); return NULL; } } @@ -113,7 +108,7 @@ error: GstVaapiPixmap * gst_vaapi_pixmap_ref (GstVaapiPixmap * pixmap) { - return gst_vaapi_pixmap_ref_internal (pixmap); + return gst_vaapi_object_ref (GST_VAAPI_OBJECT (pixmap)); } /** @@ -126,7 +121,7 @@ gst_vaapi_pixmap_ref (GstVaapiPixmap * pixmap) void gst_vaapi_pixmap_unref (GstVaapiPixmap * pixmap) { - gst_vaapi_pixmap_unref_internal (pixmap); + gst_vaapi_object_unref (GST_VAAPI_OBJECT (pixmap)); } /** @@ -142,7 +137,8 @@ void gst_vaapi_pixmap_replace (GstVaapiPixmap ** old_pixmap_ptr, GstVaapiPixmap * new_pixmap) { - gst_vaapi_pixmap_replace_internal (old_pixmap_ptr, new_pixmap); + gst_vaapi_object_replace ((GstVaapiObject **) (old_pixmap_ptr), + GST_VAAPI_OBJECT (new_pixmap)); } /** diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_priv.h b/gst-libs/gst/vaapi/gstvaapipixmap_priv.h index 9dd6bc5133..a99d91f5c2 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_priv.h +++ b/gst-libs/gst/vaapi/gstvaapipixmap_priv.h @@ -108,31 +108,6 @@ GstVaapiPixmap * gst_vaapi_pixmap_new_from_native(const GstVaapiPixmapClass *pixmap_class, GstVaapiDisplay *display, gpointer native_pixmap); -/* Inline reference counting for core libgstvaapi library */ -#ifdef IN_LIBGSTVAAPI_CORE -#define gst_vaapi_pixmap_ref_internal(pixmap) \ - ((gpointer)gst_vaapi_object_ref(GST_VAAPI_OBJECT(pixmap))) - -#define gst_vaapi_pixmap_unref_internal(pixmap) \ - gst_vaapi_object_unref(GST_VAAPI_OBJECT(pixmap)) - -#define gst_vaapi_pixmap_replace_internal(old_pixmap_ptr, new_pixmap) \ - gst_vaapi_object_replace((GstVaapiObject **)(old_pixmap_ptr), \ - GST_VAAPI_OBJECT(new_pixmap)) - -#undef gst_vaapi_pixmap_ref -#define gst_vaapi_pixmap_ref(pixmap) \ - gst_vaapi_pixmap_ref_internal((pixmap)) - -#undef gst_vaapi_pixmap_unref -#define gst_vaapi_pixmap_unref(pixmap) \ - gst_vaapi_pixmap_unref_internal((pixmap)) - -#undef gst_vaapi_pixmap_replace -#define gst_vaapi_pixmap_replace(old_pixmap_ptr, new_pixmap) \ - gst_vaapi_pixmap_replace_internal((old_pixmap_ptr), (new_pixmap)) -#endif - G_END_DECLS #endif /* GST_VAAPI_PIXMAP_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 139822f765..2a2d7a7bcd 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -34,11 +34,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -/* Ensure those symbols are actually defined in the resulting libraries */ -#undef gst_vaapi_texture_ref -#undef gst_vaapi_texture_unref -#undef gst_vaapi_texture_replace - #define GST_VAAPI_TEXTURE_ORIENTATION_FLAGS \ (GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED | \ GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED) @@ -171,7 +166,7 @@ gst_vaapi_texture_new_wrapped (GstVaapiDisplay * display, guint id, GstVaapiTexture * gst_vaapi_texture_ref (GstVaapiTexture * texture) { - return gst_vaapi_texture_ref_internal (texture); + return gst_vaapi_object_ref (GST_VAAPI_OBJECT (texture)); } /** @@ -184,7 +179,7 @@ gst_vaapi_texture_ref (GstVaapiTexture * texture) void gst_vaapi_texture_unref (GstVaapiTexture * texture) { - gst_vaapi_texture_unref_internal (texture); + gst_vaapi_object_unref (GST_VAAPI_OBJECT (texture)); } /** @@ -200,7 +195,8 @@ void gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr, GstVaapiTexture * new_texture) { - gst_vaapi_texture_replace_internal (old_texture_ptr, new_texture); + gst_vaapi_object_replace ((GstVaapiObject **) (old_texture_ptr), + GST_VAAPI_OBJECT (new_texture)); } /** diff --git a/gst-libs/gst/vaapi/gstvaapitexture_priv.h b/gst-libs/gst/vaapi/gstvaapitexture_priv.h index 86befe67cd..3b65236a52 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_priv.h +++ b/gst-libs/gst/vaapi/gstvaapitexture_priv.h @@ -135,31 +135,6 @@ gst_vaapi_texture_new_internal (const GstVaapiTextureClass * klass, GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height); -/* Inline reference counting for core libgstvaapi library */ -#ifdef IN_LIBGSTVAAPI_CORE -#define gst_vaapi_texture_ref_internal(texture) \ - ((gpointer)gst_vaapi_object_ref (GST_VAAPI_OBJECT (texture))) - -#define gst_vaapi_texture_unref_internal(texture) \ - gst_vaapi_object_unref (GST_VAAPI_OBJECT (texture)) - -#define gst_vaapi_texture_replace_internal(old_texture_ptr, new_texture) \ - gst_vaapi_object_replace ((GstVaapiObject **)(old_texture_ptr), \ - GST_VAAPI_OBJECT (new_texture)) - -#undef gst_vaapi_texture_ref -#define gst_vaapi_texture_ref(texture) \ - gst_vaapi_texture_ref_internal ((texture)) - -#undef gst_vaapi_texture_unref -#define gst_vaapi_texture_unref(texture) \ - gst_vaapi_texture_unref_internal ((texture)) - -#undef gst_vaapi_texture_replace -#define gst_vaapi_texture_replace(old_texture_ptr, new_texture) \ - gst_vaapi_texture_replace_internal ((old_texture_ptr), (new_texture)) -#endif - G_END_DECLS #endif /* GST_VAAPI_TEXTURE_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index f3d6ab02fb..db9e1883e4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -36,11 +36,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -/* Ensure those symbols are actually defined in the resulting libraries */ -#undef gst_vaapi_window_ref -#undef gst_vaapi_window_unref -#undef gst_vaapi_window_replace - static void gst_vaapi_window_ensure_size (GstVaapiWindow * window) { @@ -175,7 +170,7 @@ gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, /* ERRORS */ error: { - gst_vaapi_window_unref_internal (window); + gst_vaapi_window_unref (window); return NULL; } } @@ -259,7 +254,7 @@ gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height) GstVaapiWindow * gst_vaapi_window_ref (GstVaapiWindow * window) { - return gst_vaapi_window_ref_internal (window); + return (GstVaapiWindow *) gst_vaapi_object_ref (GST_VAAPI_OBJECT (window)); } /** @@ -272,7 +267,7 @@ gst_vaapi_window_ref (GstVaapiWindow * window) void gst_vaapi_window_unref (GstVaapiWindow * window) { - gst_vaapi_window_unref_internal (window); + gst_vaapi_object_unref (GST_VAAPI_OBJECT (window)); } /** @@ -288,7 +283,8 @@ void gst_vaapi_window_replace (GstVaapiWindow ** old_window_ptr, GstVaapiWindow * new_window) { - gst_vaapi_window_replace_internal (old_window_ptr, new_window); + gst_vaapi_object_replace ((GstVaapiObject **) (old_window_ptr), + GST_VAAPI_OBJECT (new_window)); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index cd0df1a467..10705857a7 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -135,31 +135,6 @@ gst_vaapi_window_vpp_convert_internal (GstVaapiWindow * window, void gst_vaapi_window_class_init (GstVaapiWindowClass * klass); -/* Inline reference counting for core libgstvaapi library */ -#ifdef IN_LIBGSTVAAPI_CORE -#define gst_vaapi_window_ref_internal(window) \ - ((gpointer)gst_vaapi_object_ref(GST_VAAPI_OBJECT(window))) - -#define gst_vaapi_window_unref_internal(window) \ - gst_vaapi_object_unref(GST_VAAPI_OBJECT(window)) - -#define gst_vaapi_window_replace_internal(old_window_ptr, new_window) \ - gst_vaapi_object_replace((GstVaapiObject **)(old_window_ptr), \ - GST_VAAPI_OBJECT(new_window)) - -#undef gst_vaapi_window_ref -#define gst_vaapi_window_ref(window) \ - gst_vaapi_window_ref_internal((window)) - -#undef gst_vaapi_window_unref -#define gst_vaapi_window_unref(window) \ - gst_vaapi_window_unref_internal((window)) - -#undef gst_vaapi_window_replace -#define gst_vaapi_window_replace(old_window_ptr, new_window) \ - gst_vaapi_window_replace_internal((old_window_ptr), (new_window)) -#endif - G_END_DECLS #endif /* GST_VAAPI_WINDOW_PRIV_H */ diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 0b9d11c8cf..5a930c71c1 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -221,7 +221,7 @@ endif gstlibvaapi = static_library('gstlibvaapi-@0@'.format(api_version), gstlibvaapi_sources, - c_args : gstreamer_vaapi_args + ['-DIN_LIBGSTVAAPI_CORE', '-DGST_USE_UNSTABLE_API', '-DGST_VAAPI_VERSION_ID="@0@"'.format(gst_version)], + c_args : gstreamer_vaapi_args + [ '-DGST_USE_UNSTABLE_API', '-DGST_VAAPI_VERSION_ID="@0@"'.format(gst_version)], include_directories: [configinc, libsinc], dependencies : gstlibvaapi_deps, ) From 0e16691b09685fd5f6a470e37c09a06cf8767eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 13 Sep 2018 16:10:13 +0200 Subject: [PATCH 3140/3781] libs: videopool: remove unneeded code The removed code comes frome the bad practice of copy&paste. Better move it as internal function. https://bugzilla.gnome.org/show_bug.cgi?id=797139 --- gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 13 ++++------ gst-libs/gst/vaapi/gstvaapivideopool_priv.h | 24 ------------------- 4 files changed, 7 insertions(+), 34 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c index 7e56f17ee2..d28e7b645b 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c @@ -106,7 +106,7 @@ gst_vaapi_coded_buffer_proxy_new_from_pool (GstVaapiCodedBufferPool * pool) proxy->destroy_func = NULL; proxy->user_data_destroy = NULL; - proxy->pool = gst_vaapi_video_pool_ref (pool); + proxy->pool = gst_vaapi_video_pool_ref (GST_VAAPI_VIDEO_POOL (pool)); proxy->buffer = gst_vaapi_video_pool_get_object (proxy->pool); #if USE_H264_FEI_ENCODER proxy->mv = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index fc72e35873..4e2b686f21 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -164,7 +164,7 @@ gst_vaapi_surface_proxy_new_from_pool (GstVaapiSurfacePool * pool) proxy->parent = NULL; proxy->destroy_func = NULL; - proxy->pool = gst_vaapi_video_pool_ref (pool); + proxy->pool = gst_vaapi_video_pool_ref (GST_VAAPI_VIDEO_POOL (pool)); proxy->surface = gst_vaapi_video_pool_get_object (proxy->pool); if (!proxy->surface) goto error; diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index b27e1db55b..52ed1e812a 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -35,11 +35,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -/* Ensure those symbols are actually defined in the resulting libraries */ -#undef gst_vaapi_video_pool_ref -#undef gst_vaapi_video_pool_unref -#undef gst_vaapi_video_pool_replace - #define GST_VAAPI_VIDEO_POOL_GET_CLASS(obj) \ gst_vaapi_video_pool_get_class (GST_VAAPI_VIDEO_POOL (obj)) @@ -90,7 +85,8 @@ gst_vaapi_video_pool_finalize (GstVaapiVideoPool * pool) GstVaapiVideoPool * gst_vaapi_video_pool_ref (GstVaapiVideoPool * pool) { - return gst_vaapi_video_pool_ref_internal (pool); + return (GstVaapiVideoPool *) + gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (pool)); } /** @@ -103,7 +99,7 @@ gst_vaapi_video_pool_ref (GstVaapiVideoPool * pool) void gst_vaapi_video_pool_unref (GstVaapiVideoPool * pool) { - gst_vaapi_video_pool_unref_internal (pool); + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pool)); } /** @@ -119,7 +115,8 @@ void gst_vaapi_video_pool_replace (GstVaapiVideoPool ** old_pool_ptr, GstVaapiVideoPool * new_pool) { - gst_vaapi_video_pool_replace_internal (old_pool_ptr, new_pool); + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_pool_ptr), + GST_VAAPI_MINI_OBJECT (new_pool)); } /** diff --git a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h index 6e5fa3a950..1d5115a0d7 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool_priv.h +++ b/gst-libs/gst/vaapi/gstvaapivideopool_priv.h @@ -79,30 +79,6 @@ G_GNUC_INTERNAL void gst_vaapi_video_pool_finalize (GstVaapiVideoPool * pool); -/* Internal aliases */ - -#define gst_vaapi_video_pool_ref_internal(pool) \ - ((gpointer)gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (pool))) - -#define gst_vaapi_video_pool_unref_internal(pool) \ - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pool)) - -#define gst_vaapi_video_pool_replace_internal(old_pool_ptr, new_pool) \ - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **)(old_pool_ptr), \ - GST_VAAPI_MINI_OBJECT (new_pool)) - -#undef gst_vaapi_video_pool_ref -#define gst_vaapi_video_pool_ref(pool) \ - gst_vaapi_video_pool_ref_internal ((pool)) - -#undef gst_vaapi_video_pool_unref -#define gst_vaapi_video_pool_unref(pool) \ - gst_vaapi_video_pool_unref_internal ((pool)) - -#undef gst_vaapi_video_pool_replace -#define gst_vaapi_video_pool_replace(old_pool_ptr, new_pool) \ - gst_vaapi_video_pool_replace_internal ((old_pool_ptr), (new_pool)) - G_END_DECLS #endif /* GST_VAAPI_VIDEO_POOL_PRIV_H */ From 9970e15f672d69dcaee9fbb71e4a2cac75ba2a69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 13 Sep 2018 16:34:54 +0200 Subject: [PATCH 3141/3781] libs: parser_frame: change macros for inlined functions https://bugzilla.gnome.org/show_bug.cgi?id=797139 --- gst-libs/gst/vaapi/gstvaapiparser_frame.h | 25 ++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiparser_frame.h b/gst-libs/gst/vaapi/gstvaapiparser_frame.h index b8de9bc0d8..5d20429aab 100644 --- a/gst-libs/gst/vaapi/gstvaapiparser_frame.h +++ b/gst-libs/gst/vaapi/gstvaapiparser_frame.h @@ -72,15 +72,26 @@ void gst_vaapi_parser_frame_append_unit(GstVaapiParserFrame *frame, GstVaapiDecoderUnit *unit); -#define gst_vaapi_parser_frame_ref(frame) \ - gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(frame)) +static inline GstVaapiParserFrame * +gst_vaapi_parser_frame_ref (GstVaapiParserFrame * frame) +{ + return (GstVaapiParserFrame *) + gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (frame)); +} -#define gst_vaapi_parser_frame_unref(frame) \ - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(frame)) +static inline void +gst_vaapi_parser_frame_unref (GstVaapiParserFrame * frame) +{ + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (frame)); +} -#define gst_vaapi_parser_frame_replace(old_frame_p, new_frame) \ - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_frame_p), \ - (GstVaapiMiniObject *)(new_frame)) +static inline void +gst_vaapi_parser_frame_replace(GstVaapiParserFrame * old_frame_p, + GstVaapiParserFrame * new_frame) +{ + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_frame_p, + (GstVaapiMiniObject *) new_frame); +} G_END_DECLS From 0152410c9768dd3422bb59910bc5052ad45c3d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 13 Sep 2018 18:26:27 +0200 Subject: [PATCH 3142/3781] libs: object: separation of internal API and plugins Removed exposed macros GST_VAAPI_OBJECT_DISPLAY() and GST_VAAPI_OBJECT_ID() to plugins, keeping them only for internal library usage. The purpose is readability. https://bugzilla.gnome.org/show_bug.cgi?id=797139 --- gst-libs/gst/vaapi/gstvaapiobject.h | 18 ------------------ gst-libs/gst/vaapi/gstvaapiobject_priv.h | 2 -- gst/vaapi/gstvaapivideometa_texture.c | 6 ++++-- 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h index a9a977d1f1..ad9edc4c91 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiobject.h @@ -35,24 +35,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiObject GstVaapiObject; -/** - * GST_VAAPI_OBJECT_DISPLAY: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the #GstVaapiDisplay the @object is bound to. - */ -#define GST_VAAPI_OBJECT_DISPLAY(object) \ - gst_vaapi_object_get_display (GST_VAAPI_OBJECT (object)) - -/** - * GST_VAAPI_OBJECT_ID: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the #GstVaapiID contained in @object. - */ -#define GST_VAAPI_OBJECT_ID(object) \ - gst_vaapi_object_get_id (GST_VAAPI_OBJECT (object)) - gpointer gst_vaapi_object_ref (gpointer object); diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h index 3515595120..0eb494d472 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiobject_priv.h @@ -71,7 +71,6 @@ G_PASTE(t_n,_class) (void) \ * Macro that evaluates to the #GstVaapiID contained in @object. * This is an internal macro that does not do any run-time type checks. */ -#undef GST_VAAPI_OBJECT_ID #define GST_VAAPI_OBJECT_ID(object) \ (GST_VAAPI_OBJECT (object)->object_id) @@ -82,7 +81,6 @@ G_PASTE(t_n,_class) (void) \ * Macro that evaluates to the #GstVaapiDisplay the @object is bound to. * This is an internal macro that does not do any run-time type check. */ -#undef GST_VAAPI_OBJECT_DISPLAY #define GST_VAAPI_OBJECT_DISPLAY(object) \ (GST_VAAPI_OBJECT (object)->display) diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index b89f9ee80a..e3f5f1b541 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -178,7 +178,8 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, GstVaapiSurfaceProxy *const proxy = gst_vaapi_video_meta_get_surface_proxy (vmeta); GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); - GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface); + GstVaapiDisplay *const dpy = + gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); GstVaapiTexture *texture = NULL; if (!gst_vaapi_display_has_opengl (dpy)) @@ -186,7 +187,8 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, if (meta_texture->texture /* Check whether VA display changed */ - && GST_VAAPI_OBJECT_DISPLAY (meta_texture->texture) == dpy + && gst_vaapi_object_get_display + (GST_VAAPI_OBJECT (meta_texture->texture)) == dpy /* Check whether texture id changed */ && (gst_vaapi_texture_get_id (meta_texture->texture) == texture_id[0])) { texture = meta_texture->texture; From ae2fbf951a2551a359859e264bb61e4042fa5b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 13 Sep 2018 18:11:25 +0200 Subject: [PATCH 3143/3781] libs: remove already include string.h Since sysdeps.h includes string.h there's no need to include it again. --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 1 - gst-libs/gst/vaapi/gstvaapidisplay.c | 1 - gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 1 - gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 1 - gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 1 - gst-libs/gst/vaapi/gstvaapiimage.c | 1 - gst-libs/gst/vaapi/gstvaapiprofile.c | 1 - gst-libs/gst/vaapi/gstvaapisubpicture.c | 1 - gst-libs/gst/vaapi/gstvaapiutils_glx.c | 1 - gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 1 - gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 1 - 18 files changed, 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 06c52e640a..29f1b7a8d5 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -23,7 +23,6 @@ */ #include "sysdeps.h" -#include #include #include "gstvaapicodec_objects.h" #include "gstvaapidecoder_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index f1a7b7046f..fb4c549f06 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -26,7 +26,6 @@ */ #include "sysdeps.h" -#include #include #include #include "gstvaapidecoder_h264.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 1066289467..781df70b02 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -26,7 +26,6 @@ */ #include "sysdeps.h" -#include #include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 9c2d842c10..ae39f1fa3c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -27,7 +27,6 @@ */ #include "sysdeps.h" -#include #include #include "gstvaapicompat.h" #include "gstvaapidecoder_jpeg.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 17ebcd4abc..ffa66b8f80 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -26,7 +26,6 @@ */ #include "sysdeps.h" -#include #include #include #include "gstvaapidecoder_mpeg2.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index c8049a1eca..38420d8a68 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -26,7 +26,6 @@ */ #include "sysdeps.h" -#include #include #include #include "gstvaapidecoder_mpeg4.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 2dd4c27c27..48e9ead9aa 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -23,7 +23,6 @@ */ #include "sysdeps.h" -#include #include #include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index cf05ba320b..0385dd04c2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -26,7 +26,6 @@ */ #include "sysdeps.h" -#include #include #include "gstvaapidecoder_vc1.h" #include "gstvaapidecoder_objects.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 40b186a533..5f2d4a27a3 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -28,7 +28,6 @@ */ #include "sysdeps.h" -#include #include "gstvaapiutils.h" #include "gstvaapivalue.h" #include "gstvaapidisplay.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index f67acc9915..f39b4b74a4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -27,7 +27,6 @@ #define _GNU_SOURCE #include "sysdeps.h" -#include #include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 494c41f4dc..4b6fc1cae6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -27,7 +27,6 @@ */ #include "sysdeps.h" -#include #include "gstvaapidisplay_priv.h" #include "gstvaapidisplay_wayland.h" #include "gstvaapidisplay_wayland_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 2ce465aba5..dbcfee4fe2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -28,7 +28,6 @@ */ #include "sysdeps.h" -#include #include "gstvaapiutils.h" #include "gstvaapidisplay_priv.h" #include "gstvaapidisplay_x11.h" diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 4fb535fcab..797d567bcf 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -28,7 +28,6 @@ */ #include "sysdeps.h" -#include #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapiimage.h" diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 7148a83844..242b7b9d7e 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -28,7 +28,6 @@ */ #include "sysdeps.h" -#include #include #include "gstvaapicompat.h" #include "gstvaapiprofile.h" diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index f39f90a4b0..c8a15020ff 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -28,7 +28,6 @@ */ #include "sysdeps.h" -#include #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapisubpicture.h" diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 714dffbdc8..997db0096e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -24,7 +24,6 @@ #define _GNU_SOURCE 1 /* RTLD_DEFAULT */ #include "sysdeps.h" -#include #include #include #include "gstvaapiutils_glx.h" diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 80c274eab9..e6e33d1e6e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -27,7 +27,6 @@ */ #include "sysdeps.h" -#include #include "gstvaapicompat.h" #include "gstvaapiwindow_wayland.h" #include "gstvaapiwindow_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index ee90afa0ac..ce63f3cfa0 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -28,7 +28,6 @@ */ #include "sysdeps.h" -#include #include #include "gstvaapicompat.h" #include "gstvaapiwindow_x11.h" From e1557fff78dd0ce904bda367c543b4233ed3733e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 13 Sep 2018 18:12:02 +0200 Subject: [PATCH 3144/3781] tests: remove already include string.h Since sysdeps.h includes string.h there's no need to include it again. --- tests/decoder.c | 1 - tests/output.c | 1 - tests/test-decode.c | 1 - tests/test-subpicture.c | 1 - 4 files changed, 4 deletions(-) diff --git a/tests/decoder.c b/tests/decoder.c index 6679cc10c9..1b3ceaea01 100644 --- a/tests/decoder.c +++ b/tests/decoder.c @@ -21,7 +21,6 @@ */ #include "gst/vaapi/sysdeps.h" -#include #include #include #include diff --git a/tests/output.c b/tests/output.c index 3469fd39aa..e1ac5cc628 100644 --- a/tests/output.c +++ b/tests/output.c @@ -21,7 +21,6 @@ */ #include "gst/vaapi/sysdeps.h" -#include #include #if USE_DRM # include diff --git a/tests/test-decode.c b/tests/test-decode.c index cc1688bc1c..81bab85d86 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -23,7 +23,6 @@ */ #include "gst/vaapi/sysdeps.h" -#include #include #include "decoder.h" #include "output.h" diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index c3298abe71..b193e10319 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -21,7 +21,6 @@ */ #include "gst/vaapi/sysdeps.h" -#include #include #include "decoder.h" #include "output.h" From cfbe7cbc4494a857357022a648b5e1ab62174e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 14 Sep 2018 19:30:56 +0200 Subject: [PATCH 3145/3781] libs: utils: no need of include config.h --- gst-libs/gst/vaapi/gstvaapiutils.h | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 82efc31550..680fc17a1b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -25,7 +25,6 @@ #ifndef GST_VAAPI_UTILS_H #define GST_VAAPI_UTILS_H -#include "config.h" #include #include From 00f5fe9ccfc7183eb0f3f02f6efcca06343e70b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 25 Sep 2018 20:28:02 +0200 Subject: [PATCH 3146/3781] tests: don's use sysdeps.h in header --- tests/y4mreader.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/y4mreader.h b/tests/y4mreader.h index 30d754bc4a..e2dbd1094e 100644 --- a/tests/y4mreader.h +++ b/tests/y4mreader.h @@ -19,7 +19,8 @@ * Boston, MA 02110-1301 USA */ -#include "gst/vaapi/sysdeps.h" +#include +#include #include typedef struct _Y4MReader Y4MReader; From fbc5ed1651678cc327638ed604b58c4d045d7985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 26 Sep 2018 18:04:53 +0200 Subject: [PATCH 3147/3781] tests: fix compilation https://bugzilla.gnome.org/show_bug.cgi?id=797204 --- tests/y4mreader.c | 3 +-- tests/y4mreader.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/y4mreader.c b/tests/y4mreader.c index 5fa7dcb190..3fb7873273 100644 --- a/tests/y4mreader.c +++ b/tests/y4mreader.c @@ -20,8 +20,7 @@ */ #include "y4mreader.h" - -#include +#include /* format documentation: * http://wiki.multimedia.cx/index.php?title=YUV4MPEG2 */ diff --git a/tests/y4mreader.h b/tests/y4mreader.h index e2dbd1094e..369efb6f9b 100644 --- a/tests/y4mreader.h +++ b/tests/y4mreader.h @@ -19,7 +19,7 @@ * Boston, MA 02110-1301 USA */ -#include +#include #include #include From 37a756fd919e382942265cc0ead4cfe81a98c66e Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Wed, 26 Sep 2018 19:34:06 +0200 Subject: [PATCH 3148/3781] tests: include sysdeps.h in compilation unit Fixes https://bugzilla.gnome.org/show_bug.cgi?id=797204 Signed-off-by: U. Artie Eoff --- tests/y4mreader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/y4mreader.c b/tests/y4mreader.c index 3fb7873273..76847bb217 100644 --- a/tests/y4mreader.c +++ b/tests/y4mreader.c @@ -19,8 +19,8 @@ * Boston, MA 02110-1301 USA */ +#include "gst/vaapi/sysdeps.h" #include "y4mreader.h" -#include /* format documentation: * http://wiki.multimedia.cx/index.php?title=YUV4MPEG2 */ From 619abbdeb4c674ded188f7bab3ffa5c682702d12 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Thu, 20 Sep 2018 09:57:33 +0800 Subject: [PATCH 3149/3781] libs: dec: h265: add 422 chroma format support. Add main-422-10 profile which support 422 chroma format stream. Currently, this feature is only supported by media-driver in Icelake. https://bugzilla.gnome.org/show_bug.cgi?id=797143 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 3 +- gst-libs/gst/vaapi/gstvaapiprofile.c | 6 ++ gst-libs/gst/vaapi/gstvaapiprofile.h | 3 + gst-libs/gst/vaapi/gstvaapisurface.c | 14 ++++ gst-libs/gst/vaapi/gstvaapiutils.c | 3 + gst-libs/gst/vaapi/gstvaapiutils_h265.c | 20 ++++- gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h | 2 +- gst-libs/gst/vaapi/video-format.c | 43 +++++++---- gst-libs/gst/vaapi/video-format.h | 3 + gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapipluginbase.c | 77 ++++++++++++-------- gst/vaapi/gstvaapipluginutil.h | 2 +- 12 files changed, 128 insertions(+), 50 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 781df70b02..61f508abac 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1053,8 +1053,7 @@ get_profile (GstVaapiDecoderH265 * decoder, GstH265SPS * sps, guint dpb_size) GstVaapiProfile profile, profiles[3]; guint i, n_profiles = 0; - profile = - gst_vaapi_utils_h265_get_profile (sps->profile_tier_level.profile_idc); + profile = gst_vaapi_utils_h265_get_profile (sps); if (!profile) { /* HACK: This is a work-around to identify some main profile streams having wrong profile_idc. * There are some wrongly encoded main profile streams(eg: ENTP_C_LG_3.bin) which doesn't diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 242b7b9d7e..4b540f3f58 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -132,6 +132,10 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { {GST_VAAPI_PROFILE_H265_MAIN10, VAProfileHEVCMain10, "video/x-h265", "main-10"}, #endif +#if VA_CHECK_VERSION(1,2,0) + {GST_VAAPI_PROFILE_H265_MAIN_422_10, VAProfileHEVCMain422_10, + "video/x-h265", "main-422-10"}, +#endif #if VA_CHECK_VERSION(0,38,0) {GST_VAAPI_PROFILE_VP9_0, VAProfileVP9Profile0, "video/x-vp9", "profile0"}, @@ -330,6 +334,8 @@ gst_vaapi_profile_from_codec_data_h265 (GstBuffer * buffer) return GST_VAAPI_PROFILE_H265_MAIN10; case 3: return GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; + case 4: + return GST_VAAPI_PROFILE_H265_MAIN_422_10; } return 0; } diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 1a6fbb81ba..066c189a69 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -131,6 +131,8 @@ typedef enum { * H.265 main 10 profile [A.3.3] * @GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE: * H.265 main still picture profile [A.3.4] + * @GST_VAAPI_PROFILE_H265_MAIN_422_10: + * H.265 main still picture profile [A.3.5] * @GST_VAAPI_PROFILE_VP9_0: * VP9 prfile 0, bitdepth=8, 420 * @GST_VAAPI_PROFILE_VP9_1: @@ -175,6 +177,7 @@ typedef enum { GST_VAAPI_PROFILE_H265_MAIN10 = GST_VAAPI_MAKE_PROFILE(H265,2), GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE = GST_VAAPI_MAKE_PROFILE(H265,3), + GST_VAAPI_PROFILE_H265_MAIN_422_10 = GST_VAAPI_MAKE_PROFILE(H265,4), GST_VAAPI_PROFILE_VP9_0 = GST_VAAPI_MAKE_PROFILE(VP9,1), GST_VAAPI_PROFILE_VP9_1 = GST_VAAPI_MAKE_PROFILE(VP9,2), GST_VAAPI_PROFILE_VP9_2 = GST_VAAPI_MAKE_PROFILE(VP9,3), diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 528dd8c656..4940fff5a5 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -340,6 +340,20 @@ gst_vaapi_surface_new (GstVaapiDisplay * display, if (!surface) return NULL; + /* first try a recent version of vaCreateSurface, and later use as + * fallback its old version */ +#if VA_CHECK_VERSION(0,34,0) + { + GstVideoInfo vi; + GstVideoFormat surface_format; + + surface_format = gst_vaapi_video_format_from_chroma (chroma_type); + gst_video_info_set_format (&vi, surface_format, width, height); + + if (gst_vaapi_surface_create_full (surface, &vi, 0)) + return surface; + } +#endif if (!gst_vaapi_surface_create (surface, chroma_type, width, height)) goto error; return surface; diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 493cc098e8..030f595c0e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -228,6 +228,9 @@ string_of_VAProfile (VAProfile profile) MAP (H264MultiviewHigh); MAP (H264StereoHigh); #endif +#if VA_CHECK_VERSION(1,2,0) + MAP (HEVCMain422_10); +#endif #if VA_CHECK_VERSION(0,37,1) MAP (HEVCMain); MAP (HEVCMain10); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index ef43b3c9b1..532a931f7a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -132,11 +132,11 @@ gst_vaapi_utils_h265_get_profile_score (GstVaapiProfile profile) /** Returns GstVaapiProfile from H.265 profile_idc value */ GstVaapiProfile -gst_vaapi_utils_h265_get_profile (guint8 profile_idc) +gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) { GstVaapiProfile profile; - switch (profile_idc) { + switch (sps->profile_tier_level.profile_idc) { case GST_H265_PROFILE_IDC_MAIN: profile = GST_VAAPI_PROFILE_H265_MAIN; break; @@ -146,6 +146,19 @@ gst_vaapi_utils_h265_get_profile (guint8 profile_idc) case GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE: profile = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; break; + case GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION: + if (sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 0 + && sps->profile_tier_level.max_422chroma_constraint_flag == 1 + && sps->profile_tier_level.max_420chroma_constraint_flag == 0 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 0 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0 + && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { + profile = GST_VAAPI_PROFILE_H265_MAIN_422_10; + break; + } default: g_debug ("unsupported profile_idc value"); profile = GST_VAAPI_PROFILE_UNKNOWN; @@ -170,6 +183,9 @@ gst_vaapi_utils_h265_get_profile_idc (GstVaapiProfile profile) case GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE: profile_idc = GST_H265_PROFILE_MAIN_STILL_PICTURE; break; + case GST_VAAPI_PROFILE_H265_MAIN_422_10: + profile_idc = GST_H265_PROFILE_MAIN_422_10; + break; default: g_debug ("unsupported GstVaapiProfile value"); profile_idc = 0; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h index 9e1b83c9d6..40938c73c2 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h @@ -63,7 +63,7 @@ typedef struct { /* Returns GstVaapiProfile from H.265 profile_idc value */ G_GNUC_INTERNAL GstVaapiProfile -gst_vaapi_utils_h265_get_profile (guint8 profile_idc); +gst_vaapi_utils_h265_get_profile (GstH265SPS * sps); /* Returns H.265 profile_idc value from GstVaapiProfile */ G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 78fb4dab9d..8aef43cbaa 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -274,6 +274,35 @@ gst_vaapi_video_format_get_score (GstVideoFormat format) return m ? (m - &gst_vaapi_video_formats[0]) : G_MAXUINT; } +/** + * gst_vaapi_video_format_from_chroma: + * @chroma_type: a #GstVaapiChromaType + * + * Returns the "preferred" pixel format that matches with + * @chroma_type. + * + * Returns: the preferred pixel format for @chroma_type + **/ +GstVideoFormat +gst_vaapi_video_format_from_chroma (guint chroma_type) +{ + switch (chroma_type) { + case GST_VAAPI_CHROMA_TYPE_YUV422: + return GST_VIDEO_FORMAT_YUY2; + case GST_VAAPI_CHROMA_TYPE_YUV400: + return GST_VIDEO_FORMAT_GRAY8; + case GST_VAAPI_CHROMA_TYPE_YUV420: + case GST_VAAPI_CHROMA_TYPE_RGB32: /* GstVideoGLTextureUploadMeta */ + return GST_VIDEO_FORMAT_NV12; + case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: + return GST_VIDEO_FORMAT_P010_10LE; + case GST_VAAPI_CHROMA_TYPE_YUV444: + return GST_VIDEO_FORMAT_AYUV; + default: + return GST_VIDEO_FORMAT_UNKNOWN; + } +} + /** * gst_vaapi_video_format_get_best_native: * @format: a #GstVideoFormat @@ -293,17 +322,5 @@ gst_vaapi_video_format_get_best_native (GstVideoFormat format) return GST_VIDEO_FORMAT_NV12; chroma_type = gst_vaapi_video_format_get_chroma_type (format); - switch (chroma_type) { - case GST_VAAPI_CHROMA_TYPE_YUV422: - return GST_VIDEO_FORMAT_YUY2; - case GST_VAAPI_CHROMA_TYPE_YUV400: - return GST_VIDEO_FORMAT_GRAY8; - case GST_VAAPI_CHROMA_TYPE_YUV420: - case GST_VAAPI_CHROMA_TYPE_RGB32: /* GstVideoGLTextureUploadMeta */ - return GST_VIDEO_FORMAT_NV12; - case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: - return GST_VIDEO_FORMAT_P010_10LE; - default: - return GST_VIDEO_FORMAT_UNKNOWN; - }; + return gst_vaapi_video_format_from_chroma (chroma_type); } diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index 25e1161120..35f96ec80d 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -53,6 +53,9 @@ gst_vaapi_video_format_get_chroma_type (GstVideoFormat format); guint gst_vaapi_video_format_get_score (GstVideoFormat format); +GstVideoFormat +gst_vaapi_video_format_from_chroma (guint chroma); + GstVideoFormat gst_vaapi_video_format_get_best_native (GstVideoFormat format); diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 86938d97fb..2a1db788ef 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -87,7 +87,7 @@ static const char gst_vaapidecode_src_caps_str[] = #if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" #endif - GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, P010_10LE }") ";" + GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, P010_10LE }") ";" GST_VAAPI_MAKE_DMABUF_CAPS; static GstStaticPadTemplate gst_vaapidecode_src_factory = diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index fad30b10de..33b5b3f798 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1253,51 +1253,70 @@ no_valid_gl_display: #endif } +static GArray * +extract_allowed_surface_formats (GstVaapiDisplay * display, GArray * formats) +{ + guint i; + GArray *out_formats; + + out_formats = + g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), formats->len); + if (!out_formats) + return NULL; + + for (i = 0; i < formats->len; i++) { + const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); + GstVaapiChromaType chroma_type; + GstVaapiSurface *surface; + GstVaapiImage *image; + + if (format == GST_VIDEO_FORMAT_UNKNOWN) + continue; + chroma_type = gst_vaapi_video_format_get_chroma_type (format); + if (chroma_type == 0) + continue; + surface = gst_vaapi_surface_new (display, chroma_type, 64, 64); + if (!surface) + continue; + image = gst_vaapi_image_new (display, format, 64, 64); + if (!image) { + gst_vaapi_object_unref (surface); + continue; + } + + if (gst_vaapi_surface_put_image (surface, image)) + g_array_append_val (out_formats, format); + + gst_vaapi_object_unref (image); + gst_vaapi_object_unref (surface); + } + + if (out_formats->len == 0) { + g_array_unref (out_formats); + return NULL; + } + return out_formats; +} + static gboolean ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) { GArray *formats, *out_formats; - GstVaapiSurface *surface; GstVaapiDisplay *display; - guint i; GstCaps *out_caps; gboolean ret = FALSE; if (plugin->allowed_raw_caps) return TRUE; - out_formats = formats = NULL; - surface = NULL; - + out_formats = NULL; display = gst_object_ref (plugin->display); formats = gst_vaapi_display_get_image_formats (display); if (!formats) goto bail; - - out_formats = - g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), formats->len); + out_formats = extract_allowed_surface_formats (display, formats); if (!out_formats) goto bail; - - surface = - gst_vaapi_surface_new (display, GST_VAAPI_CHROMA_TYPE_YUV420, 64, 64); - if (!surface) - goto bail; - - for (i = 0; i < formats->len; i++) { - const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); - GstVaapiImage *image; - - if (format == GST_VIDEO_FORMAT_UNKNOWN) - continue; - image = gst_vaapi_image_new (display, format, 64, 64); - if (!image) - continue; - if (gst_vaapi_surface_put_image (surface, image)) - g_array_append_val (out_formats, format); - gst_vaapi_object_unref (image); - } - out_caps = gst_vaapi_video_format_new_template_caps_from_list (out_formats); if (!out_caps) goto bail; @@ -1311,8 +1330,6 @@ bail: g_array_unref (formats); if (out_formats) g_array_unref (out_formats); - if (surface) - gst_vaapi_object_unref (surface); gst_object_unref (display); return ret; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 68450ce7d0..b13d7cc518 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -105,7 +105,7 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps, #define GST_VAAPI_MAKE_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, P010_10LE }") + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, P010_10LE }") #define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ From b1b36a44a4b761a81b59f6109fc5272f33b2600c Mon Sep 17 00:00:00 2001 From: Matteo Valdina Date: Mon, 24 Sep 2018 16:54:29 -0500 Subject: [PATCH 3150/3781] libs: h264: Update level table to "Recommendation H.264 (04/17)". MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added level 6, 6.1 and 6.2. Reference Table A-1 – Level limits from T-REC-H.264-201704. https://bugzilla.gnome.org/show_bug.cgi?id=797202 --- gst-libs/gst/vaapi/gstvaapiutils_h264.c | 10 ++++++++-- gst-libs/gst/vaapi/gstvaapiutils_h264.h | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index 19bfae95be..fa09ef4714 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -70,6 +70,9 @@ static const struct map gst_vaapi_h264_level_map[] = { { GST_VAAPI_LEVEL_H264_L5, "5" }, { GST_VAAPI_LEVEL_H264_L5_1, "5.1" }, { GST_VAAPI_LEVEL_H264_L5_2, "5.2" }, + { GST_VAAPI_LEVEL_H264_L6, "6" }, + { GST_VAAPI_LEVEL_H264_L6_1, "6.1" }, + { GST_VAAPI_LEVEL_H264_L6_2, "6.2" }, { 0, NULL } /* *INDENT-ON* */ }; @@ -95,6 +98,9 @@ static const GstVaapiH264LevelLimits gst_vaapi_h264_level_limits[] = { { GST_VAAPI_LEVEL_H264_L5, 50, 589824, 22080, 110400, 135000, 135000, 2 }, { GST_VAAPI_LEVEL_H264_L5_1, 51, 983040, 36864, 184320, 240000, 240000, 2 }, { GST_VAAPI_LEVEL_H264_L5_2, 52, 2073600, 36864, 184320, 240000, 240000, 2 }, + { GST_VAAPI_LEVEL_H264_L6, 60, 4177920, 139264, 696320, 240000, 240000, 2 }, + { GST_VAAPI_LEVEL_H264_L6_1, 61, 8355840, 139264, 696320, 480000, 480000, 2 }, + { GST_VAAPI_LEVEL_H264_L6_2, 62, 16711680, 139264, 696320, 800000, 800000, 2 }, { 0, } }; /* *INDENT-ON* */ @@ -322,7 +328,7 @@ not_found: const gchar * gst_vaapi_utils_h264_get_level_string (GstVaapiLevelH264 level) { - if (level < GST_VAAPI_LEVEL_H264_L1 || level > GST_VAAPI_LEVEL_H264_L5_2) + if (level < GST_VAAPI_LEVEL_H264_L1 || level > GST_VAAPI_LEVEL_H264_L6_2) return NULL; return gst_vaapi_h264_level_map[level - GST_VAAPI_LEVEL_H264_L1].name; } @@ -331,7 +337,7 @@ gst_vaapi_utils_h264_get_level_string (GstVaapiLevelH264 level) const GstVaapiH264LevelLimits * gst_vaapi_utils_h264_get_level_limits (GstVaapiLevelH264 level) { - if (level < GST_VAAPI_LEVEL_H264_L1 || level > GST_VAAPI_LEVEL_H264_L5_2) + if (level < GST_VAAPI_LEVEL_H264_L1 || level > GST_VAAPI_LEVEL_H264_L6_2) return NULL; return &gst_vaapi_h264_level_limits[level - GST_VAAPI_LEVEL_H264_L1]; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.h b/gst-libs/gst/vaapi/gstvaapiutils_h264.h index 057705033d..38d1341957 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.h @@ -45,6 +45,9 @@ G_BEGIN_DECLS * @GST_VAAPI_LEVEL_H264_L5: H.264 level 5. * @GST_VAAPI_LEVEL_H264_L5_1: H.264 level 5.1. * @GST_VAAPI_LEVEL_H264_L5_2: H.264 level 5.2. + * @GST_VAAPI_LEVEL_H264_L6: H.264 level 6. + * @GST_VAAPI_LEVEL_H264_L6_1: H.264 level 6.1. + * @GST_VAAPI_LEVEL_H264_L6_2: H.264 level 6.2. * * The set of all levels for #GstVaapiLevelH264. */ @@ -66,6 +69,9 @@ typedef enum { GST_VAAPI_LEVEL_H264_L5, GST_VAAPI_LEVEL_H264_L5_1, GST_VAAPI_LEVEL_H264_L5_2, + GST_VAAPI_LEVEL_H264_L6, + GST_VAAPI_LEVEL_H264_L6_1, + GST_VAAPI_LEVEL_H264_L6_2, } GstVaapiLevelH264; /* Returns a relative score for the supplied GstVaapiProfile */ From ee27377cb38293f8e4f807ad4d0eaaf6d9740174 Mon Sep 17 00:00:00 2001 From: "Soon, Thean Siew" Date: Thu, 4 Oct 2018 02:20:10 +0800 Subject: [PATCH 3151/3781] vaapipostproc: change the way of handling deinterlace The current vaapipostproc calls driver's video processing pipeline for deinterlacing only if it is Advance deinterlacing. Modify in the way that it always tries with driver's video processing pipeline for deinterlacing, and falls back to software method of appending picture structure meta data only if it fails with driver's method. https://bugzilla.gnome.org/show_bug.cgi?id=797095 --- gst/vaapi/gstvaapipostproc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index df977f15af..66c5e1c4ce 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1314,9 +1314,7 @@ gst_vaapipostproc_transform (GstBaseTransform * trans, GstBuffer * inbuf, ret = GST_FLOW_NOT_SUPPORTED; if (postproc->flags) { /* Use VA/VPP extensions to process this frame */ - if (postproc->has_vpp && - (postproc->flags != GST_VAAPI_POSTPROC_FLAG_DEINTERLACE || - deint_method_is_advanced (postproc->deinterlace_method))) { + if (postproc->has_vpp) { ret = gst_vaapipostproc_process_vpp (trans, buf, outbuf); if (ret != GST_FLOW_NOT_SUPPORTED) goto done; From 5567a3d2cda993eb930dd38664b3fbfbc9294145 Mon Sep 17 00:00:00 2001 From: Matteo Valdina Date: Wed, 26 Sep 2018 14:55:32 -0500 Subject: [PATCH 3152/3781] libs: Move from g_debug to GST_DEBUG. https://bugzilla.gnome.org/show_bug.cgi?id=797202 --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_h264.c | 13 ++++++++----- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 13 ++++++++----- gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c | 13 ++++++++----- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 260a35e7ab..2466b7bb74 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -182,7 +182,7 @@ get_profile (guint profile_idc) profile = GST_VAAPI_PROFILE_VP9_3; break; default: - g_debug ("unsupported profile_idc value"); + GST_DEBUG ("unsupported profile_idc value"); profile = GST_VAAPI_PROFILE_UNKNOWN; break; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index fa09ef4714..0d01253f21 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -25,6 +25,9 @@ #include "gstvaapicompat.h" #include "gstvaapiutils_h264_priv.h" +#define DEBUG 1 +#include "gstvaapidebug.h" + struct map { guint value; @@ -185,7 +188,7 @@ gst_vaapi_utils_h264_get_profile (guint8 profile_idc) profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH; break; default: - g_debug ("unsupported profile_idc value"); + GST_DEBUG ("unsupported profile_idc value"); profile = GST_VAAPI_PROFILE_UNKNOWN; break; } @@ -234,7 +237,7 @@ gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile) profile_idc = GST_H264_PROFILE_STEREO_HIGH; break; default: - g_debug ("unsupported GstVaapiProfile value"); + GST_DEBUG ("unsupported GstVaapiProfile value"); profile_idc = 0; break; } @@ -274,7 +277,7 @@ gst_vaapi_utils_h264_get_level (guint8 level_idc) if (llp->level_idc == level_idc) return llp->level; } - g_debug ("unsupported level_idc value"); + GST_DEBUG ("unsupported level_idc value"); return (GstVaapiLevelH264) 0; } @@ -371,7 +374,7 @@ gst_vaapi_utils_h264_get_chroma_type (guint chroma_format_idc) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; break; default: - g_debug ("unsupported chroma_format_idc value"); + GST_DEBUG ("unsupported chroma_format_idc value"); chroma_type = (GstVaapiChromaType) 0; break; } @@ -398,7 +401,7 @@ gst_vaapi_utils_h264_get_chroma_format_idc (GstVaapiChromaType chroma_type) chroma_format_idc = 3; break; default: - g_debug ("unsupported GstVaapiChromaType value"); + GST_DEBUG ("unsupported GstVaapiChromaType value"); chroma_format_idc = 1; break; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 532a931f7a..080967b0fa 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -25,6 +25,9 @@ #include "gstvaapicompat.h" #include "gstvaapiutils_h265_priv.h" +#define DEBUG 1 +#include "gstvaapidebug.h" + struct map { guint value; @@ -160,7 +163,7 @@ gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) break; } default: - g_debug ("unsupported profile_idc value"); + GST_DEBUG ("unsupported profile_idc value"); profile = GST_VAAPI_PROFILE_UNKNOWN; break; } @@ -187,7 +190,7 @@ gst_vaapi_utils_h265_get_profile_idc (GstVaapiProfile profile) profile_idc = GST_H265_PROFILE_MAIN_422_10; break; default: - g_debug ("unsupported GstVaapiProfile value"); + GST_DEBUG ("unsupported GstVaapiProfile value"); profile_idc = 0; break; } @@ -223,7 +226,7 @@ gst_vaapi_utils_h265_get_level (guint8 level_idc) if (llp->level_idc == level_idc) return llp->level; } - g_debug ("unsupported level_idc value"); + GST_DEBUG ("unsupported level_idc value"); return (GstVaapiLevelH265) 0; } @@ -320,7 +323,7 @@ gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; break; default: - g_debug ("unsupported chroma_format_idc value"); + GST_DEBUG ("unsupported chroma_format_idc value"); chroma_type = (GstVaapiChromaType) 0; break; } @@ -348,7 +351,7 @@ gst_vaapi_utils_h265_get_chroma_format_idc (GstVaapiChromaType chroma_type) chroma_format_idc = 3; break; default: - g_debug ("unsupported GstVaapiChromaType value"); + GST_DEBUG ("unsupported GstVaapiChromaType value"); chroma_format_idc = 1; break; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c index 20f7e1292f..baba0723d8 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c @@ -25,6 +25,9 @@ #include "gstvaapicompat.h" #include "gstvaapiutils_mpeg2_priv.h" +#define DEBUG 1 +#include "gstvaapidebug.h" + struct map { guint value; @@ -124,7 +127,7 @@ gst_vaapi_utils_mpeg2_get_profile (guint8 profile_idc) profile = GST_VAAPI_PROFILE_MPEG2_HIGH; break; default: - g_debug ("unsupported profile_idc value"); + GST_DEBUG ("unsupported profile_idc value"); profile = GST_VAAPI_PROFILE_UNKNOWN; break; } @@ -148,7 +151,7 @@ gst_vaapi_utils_mpeg2_get_profile_idc (GstVaapiProfile profile) profile_idc = GST_MPEG_VIDEO_PROFILE_HIGH; break; default: - g_debug ("unsupported GstVaapiProfile value"); + GST_DEBUG ("unsupported GstVaapiProfile value"); profile_idc = 0; break; } @@ -185,7 +188,7 @@ gst_vaapi_utils_mpeg2_get_level (guint8 level_idc) if (llp->level_idc == level_idc) return llp->level; } - g_debug ("unsupported level_idc value"); + GST_DEBUG ("unsupported level_idc value"); return (GstVaapiLevelMPEG2) 0; } @@ -253,7 +256,7 @@ gst_vaapi_utils_mpeg2_get_chroma_type (guint chroma_format_idc) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; break; default: - g_debug ("unsupported chroma_format_idc value"); + GST_DEBUG ("unsupported chroma_format_idc value"); chroma_type = (GstVaapiChromaType) 0; break; } @@ -277,7 +280,7 @@ gst_vaapi_utils_mpeg2_get_chroma_format_idc (GstVaapiChromaType chroma_type) chroma_format_idc = GST_MPEG_VIDEO_CHROMA_444; break; default: - g_debug ("unsupported GstVaapiChromaType value"); + GST_DEBUG ("unsupported GstVaapiChromaType value"); chroma_format_idc = 1; break; } From 9132090182366d13dd8d0bf4c24a9d98b2c0af96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 9 Oct 2018 17:23:30 +0200 Subject: [PATCH 3153/3781] libs: replace g_warning with GST_WARNING --- gst-libs/gst/vaapi/gstvaapiimage.c | 2 +- gst-libs/gst/vaapi/gstvaapisubpicture.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 797d567bcf..d1d7366852 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -121,7 +121,7 @@ gst_vaapi_image_destroy (GstVaapiImage * image) status = vaDestroyImage (GST_VAAPI_DISPLAY_VADISPLAY (display), image_id); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaDestroyImage()")) - g_warning ("failed to destroy image %" GST_VAAPI_ID_FORMAT, + GST_WARNING ("failed to destroy image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (image_id)); GST_VAAPI_OBJECT_ID (image) = VA_INVALID_ID; } diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index c8a15020ff..7c3f54d41b 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -83,7 +83,7 @@ gst_vaapi_subpicture_destroy (GstVaapiSubpicture * subpicture) subpicture_id); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaDestroySubpicture()")) - g_warning ("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT, + GST_WARNING ("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (subpicture_id)); } GST_VAAPI_OBJECT_ID (subpicture) = VA_INVALID_ID; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 4940fff5a5..f7f948fe52 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -86,7 +86,7 @@ gst_vaapi_surface_destroy (GstVaapiSurface * surface) &surface_id, 1); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaDestroySurfaces()")) - g_warning ("failed to destroy surface %" GST_VAAPI_ID_FORMAT, + GST_WARNING ("failed to destroy surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); GST_VAAPI_OBJECT_ID (surface) = VA_INVALID_SURFACE; } From bcd63f8021158025ec56affc94aa8279daed02c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 9 Oct 2018 17:23:55 +0200 Subject: [PATCH 3154/3781] libs: replace g_error with GST_ERROR And handle those errors rather than halting. --- gst-libs/gst/vaapi/gstvaapiimage.c | 3 ++- gst-libs/gst/vaapi/gstvaapivalue.c | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index d1d7366852..e4cb590579 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -97,8 +97,9 @@ vaapi_image_is_linear (const VAImage * va_image) data_size = 2 * (width * height + 2 * width2 * height2); break; default: - g_error ("FIXME: incomplete formats %" GST_FOURCC_FORMAT, + GST_ERROR ("FIXME: incomplete formats %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (va_image->format.fourcc)); + data_size = G_MAXUINT; break; } return va_image->data_size == data_size; diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 2185e7ea63..d5e192af99 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -31,6 +31,9 @@ #include #include "gstvaapivalue.h" +#define DEBUG 1 +#include "gstvaapidebug.h" + static gpointer default_copy_func (gpointer data) { @@ -185,7 +188,7 @@ build_enum_subset_values_from_mask (GstVaapiEnumSubset * subset, guint32 mask) /* ERRORS */ error_invalid_num_values: { - g_error ("invalid number of static values for `%s'", subset->type_name); + GST_ERROR ("invalid number of static values for `%s'", subset->type_name); return FALSE; } } From 82872f42344506c4f5e31c0a485a68a5f40f98cf Mon Sep 17 00:00:00 2001 From: Wangfei Date: Mon, 1 Oct 2018 09:26:05 +0800 Subject: [PATCH 3155/3781] libs: context: query surface format before context to create surface. Before using context to create surface, the supported surface format should be checked first. https://bugzilla.gnome.org/show_bug.cgi?id=797222 --- gst-libs/gst/vaapi/gstvaapicontext.c | 8 +++-- gst-libs/gst/vaapi/gstvaapisurface.c | 45 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapisurface.h | 4 +++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index afbf8b4b20..dcce889570 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -133,9 +133,13 @@ context_ensure_surfaces (GstVaapiContext * context) GstVaapiSurface *surface; guint i; + if (!ensure_formats (context)) + return FALSE; + for (i = context->surfaces->len; i < num_surfaces; i++) { - surface = gst_vaapi_surface_new (GST_VAAPI_OBJECT_DISPLAY (context), - cip->chroma_type, cip->width, cip->height); + surface = + gst_vaapi_surface_new_from_formats (GST_VAAPI_OBJECT_DISPLAY (context), + cip->chroma_type, cip->width, cip->height, context->formats); if (!surface) return FALSE; gst_vaapi_surface_set_parent_context (surface, context); diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index f7f948fe52..40d98745ca 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -316,6 +316,51 @@ error_unsupported_format: #define gst_vaapi_surface_finalize gst_vaapi_surface_destroy GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSurface, gst_vaapi_surface); +/** + * gst_vaapi_surface_new_from_formats: + * @display: a #GstVaapiDisplay + * @chroma_type: the surface chroma format + * @width: the requested surface width + * @height: the requested surface height + * @formats: the limited format list + * + * Creates a new #GstVaapiSurface with a @chroma_type valid for any + * format in @formats; If there aren't any, the returned surface is + * created forcing the passed @chroma_type. + * + * Return value: the newly allocated #GstVaapiSurface object + */ +GstVaapiSurface * +gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display, + GstVaapiChromaType chroma_type, guint width, guint height, GArray * formats) +{ + GstVaapiSurface *surface; + guint i; + + for (i = 0; i < formats->len; i++) { + GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); + if (format == gst_vaapi_video_format_from_chroma (chroma_type)) + return gst_vaapi_surface_new (display, chroma_type, width, height); + } + + /* Fallback: if there's no format valid for the chroma type let's + * just use the passed chroma */ + surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); + if (!surface) + return NULL; + if (!gst_vaapi_surface_create (surface, chroma_type, width, height)) + goto error; + + return surface; + + /* ERRORS */ +error: + { + gst_vaapi_object_unref (surface); + return NULL; + } +} + /** * gst_vaapi_surface_new: * @display: a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index eaed6f8e60..e9ffeb8de2 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -169,6 +169,10 @@ typedef enum typedef struct _GstVaapiSurface GstVaapiSurface; typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; +GstVaapiSurface * +gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display, + GstVaapiChromaType chroma_type, guint width, guint height, GArray * formts); + GstVaapiSurface * gst_vaapi_surface_new (GstVaapiDisplay * display, GstVaapiChromaType chroma_type, guint width, guint height); From 70726aef009407e9863d94baf92c85164579e417 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Fri, 12 Oct 2018 15:39:53 +0100 Subject: [PATCH 3156/3781] gst: Advertise elements interacting with hardware devices --- docs/plugins/inspect/plugin-vaapi.xml | 14 +++++++------- gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapiencode_h264.c | 2 +- gst/vaapi/gstvaapiencode_h264_fei.c | 2 +- gst/vaapi/gstvaapiencode_h265.c | 2 +- gst/vaapi/gstvaapiencode_jpeg.c | 2 +- gst/vaapi/gstvaapiencode_mpeg2.c | 2 +- gst/vaapi/gstvaapiencode_vp8.c | 2 +- gst/vaapi/gstvaapiencode_vp9.c | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/plugins/inspect/plugin-vaapi.xml b/docs/plugins/inspect/plugin-vaapi.xml index 8dbe186a8f..b6f47f629c 100644 --- a/docs/plugins/inspect/plugin-vaapi.xml +++ b/docs/plugins/inspect/plugin-vaapi.xml @@ -12,7 +12,7 @@ vaapidecodebin VA-API Decode Bin - Codec/Decoder/Video + Codec/Decoder/Video/Hardware A VA-API based bin with a decoder and a postprocessor Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Victor Jaquez <victorx.jaquez@intel.com> @@ -33,7 +33,7 @@ vaapih264dec VA-API H264 decoder - Codec/Decoder/Video + Codec/Decoder/Video/Hardware A VA-API based H264 video decoder Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> @@ -54,7 +54,7 @@ vaapih264enc VA-API H264 encoder - Codec/Encoder/Video + Codec/Encoder/Video/Hardware A VA-API based H264 video encoder Wind Yuan <feng.yuan@intel.com> @@ -75,7 +75,7 @@ vaapijpegdec VA-API JPEG decoder - Codec/Decoder/Video + Codec/Decoder/Video/Hardware A VA-API based JPEG video decoder Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> @@ -96,7 +96,7 @@ vaapimpeg2dec VA-API MPEG2 decoder - Codec/Decoder/Video + Codec/Decoder/Video/Hardware A VA-API based MPEG2 video decoder Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> @@ -174,7 +174,7 @@ vaapivc1dec VA-API VC1 decoder - Codec/Decoder/Video + Codec/Decoder/Video/Hardware A VA-API based VC1 video decoder Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> @@ -193,4 +193,4 @@ - \ No newline at end of file + diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 2a1db788ef..e9275f4b39 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1497,7 +1497,7 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) element_class->set_context = gst_vaapi_base_set_context; gst_element_class_set_static_metadata (element_class, longname, - "Codec/Decoder/Video", description, + "Codec/Decoder/Video/Hardware", description, "Gwenole Beauchesne , " "Halley Zhao , " "Sreerenj Balachandran , " diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 85a49235b3..0249ce5bb1 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -602,7 +602,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) gst_element_class_set_static_metadata (element_class, "VA-API H264 encoder", - "Codec/Encoder/Video", + "Codec/Encoder/Video/Hardware", GST_PLUGIN_DESC, "Wind Yuan "); /* sink pad */ diff --git a/gst/vaapi/gstvaapiencode_h264_fei.c b/gst/vaapi/gstvaapiencode_h264_fei.c index d44f0633ad..5aa448319b 100644 --- a/gst/vaapi/gstvaapiencode_h264_fei.c +++ b/gst/vaapi/gstvaapiencode_h264_fei.c @@ -523,7 +523,7 @@ gst_vaapiencode_h264_fei_class_init (GstVaapiEncodeH264FeiClass * klass) gst_element_class_set_static_metadata (element_class, "VA-API H264 FEI Advanced encoder (Experimental)", - "Codec/Encoder/Video", + "Codec/Encoder/Video/Hardware", GST_PLUGIN_DESC, "Sreerenj Balachandran ," "Yi A Wang "); diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 3a71d0676c..6a9b796f5f 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -423,7 +423,7 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass) gst_element_class_set_static_metadata (element_class, "VA-API H265 encoder", - "Codec/Encoder/Video", + "Codec/Encoder/Video/Hardware", GST_PLUGIN_DESC, "Sreerenj Balachandran "); diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 4e6bbcf668..cf1ea6bcda 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -161,7 +161,7 @@ gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass) gst_element_class_set_static_metadata (element_class, "VA-API JPEG encoder", - "Codec/Encoder/Image", + "Codec/Encoder/Image/Hardware", GST_PLUGIN_DESC, "Sreerenj Balachandran "); diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 4864c90fa7..32bc346e3e 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -165,7 +165,7 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) gst_element_class_set_static_metadata (element_class, "VA-API MPEG-2 encoder", - "Codec/Encoder/Video", + "Codec/Encoder/Video/Hardware", GST_PLUGIN_DESC, "Guangxin Xu "); /* sink pad */ diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 54e63b4b21..cb040f7137 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -161,7 +161,7 @@ gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass) gst_element_class_set_static_metadata (element_class, "VA-API VP8 encoder", - "Codec/Encoder/Video", + "Codec/Encoder/Video/Hardware", GST_PLUGIN_DESC, "Sreerenj Balachandran "); diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index 74767575a2..43aff6dd56 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -161,7 +161,7 @@ gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass) gst_element_class_set_static_metadata (element_class, "VA-API VP9 encoder", - "Codec/Encoder/Video", + "Codec/Encoder/Video/Hardware", GST_PLUGIN_DESC, "Sreerenj Balachandran "); From ecdfc623fd478c4d04f92d0c69dea6fbeeee48a0 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Fri, 12 Oct 2018 16:37:34 +0800 Subject: [PATCH 3157/3781] libs: context: create context first before using it to create surface. In gst_vaapi_context_reset(), if the context has to be destroyed, make sure to create it first before allocating its associated surfaces. This patch fixes a regression introduced in commit 82872f4 because the formats available in the current context now are ensured before creating the context's surfaces. https://bugzilla.gnome.org/show_bug.cgi?id=797277 --- gst-libs/gst/vaapi/gstvaapicontext.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index dcce889570..35d22126f4 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -531,12 +531,12 @@ gst_vaapi_context_reset (GstVaapiContext * 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; - if (reset_config && !(config_create (context) && context_create (context))) - return FALSE; return TRUE; } From 8914ace06a985ce7f731f09889aff38e1340d552 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Mon, 15 Oct 2018 16:05:02 +0100 Subject: [PATCH 3158/3781] vaapipostproc: Add Hardware classifier to metadata --- gst/vaapi/gstvaapipostproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 66c5e1c4ce..d4c18c88a8 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1714,8 +1714,8 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) element_class->set_context = gst_vaapi_base_set_context; gst_element_class_set_static_metadata (element_class, "VA-API video postprocessing", - "Filter/Converter/Video;Filter/Converter/Video/Scaler;" - "Filter/Effect/Video;Filter/Effect/Video/Deinterlace", + "Filter/Converter/Video/Hardware;Filter/Converter/Video/Scaler/Hardware;" + "Filter/Effect/Video/Hardware;Filter/Effect/Video/Deinterlace/Hardware", GST_PLUGIN_DESC, "Gwenole Beauchesne "); /* sink pad */ From ce96f2d1fa5a1a36d98f801a496270ad48224299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 Oct 2018 17:55:24 +0200 Subject: [PATCH 3159/3781] vaapipostproc: fix classification string The classification string is splitted by '/' and then looks for the components. This patch removes the ';' by unifying all the components. --- gst/vaapi/gstvaapipostproc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index d4c18c88a8..7698aea978 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1714,8 +1714,7 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) element_class->set_context = gst_vaapi_base_set_context; gst_element_class_set_static_metadata (element_class, "VA-API video postprocessing", - "Filter/Converter/Video/Hardware;Filter/Converter/Video/Scaler/Hardware;" - "Filter/Effect/Video/Hardware;Filter/Effect/Video/Deinterlace/Hardware", + "Filter/Converter/Effect/Video/Scaler/Deinterlace/Hardware", GST_PLUGIN_DESC, "Gwenole Beauchesne "); /* sink pad */ From d8442e479ea85d79890ec282bf42bd6fdca3ff6c Mon Sep 17 00:00:00 2001 From: Wangfei Date: Sat, 13 Oct 2018 15:00:32 +0800 Subject: [PATCH 3160/3781] libs: context: roi_rc_qp_delta_support should not be checked when CQP. VA_ROI_RC_QP_DELTA_SUPPORT return value will be ignored when the rate control mode is set as CQP. In CQP mode, it shouldn't check roi_rc_qp_delta_support return value from driver backend. https://bugzilla.gnome.org/show_bug.cgi?id=797087 --- gst-libs/gst/vaapi/gstvaapicontext.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 35d22126f4..de9a7e8074 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -320,10 +320,14 @@ config_create (GstVaapiContext * context) 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 || - VA_ROI_RC_QP_DELTA_SUPPORT (roi_config) == 0) { - GST_ERROR ("Mismatched ROI support: number of regions supported: %d" - " ROI delta QP: %d", roi_config->bits.num_roi_regions, + 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; } From 638004875b6b129701227f961db4daffd911fce1 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Wed, 24 Oct 2018 14:18:37 -0400 Subject: [PATCH 3161/3781] libs: dec: h265: support decode for main-10-422 10bit streams. Add 422 10bit yuv format Y210, which can be used to decode main-10-422 10bit streams. Currently, this feature is only supported by media-driver in Icelake. https://bugzilla.gnome.org/show_bug.cgi?id=797264 --- gst-libs/gst/vaapi/gstvaapiimage.c | 1 + gst-libs/gst/vaapi/gstvaapisurface.h | 4 +++- gst-libs/gst/vaapi/gstvaapiutils.c | 10 ++++++++++ gst-libs/gst/vaapi/gstvaapiutils_h265.c | 5 ++++- gst-libs/gst/vaapi/video-format.c | 3 +++ gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapipluginutil.h | 2 +- 7 files changed, 23 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index e4cb590579..0d4878ced6 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -91,6 +91,7 @@ vaapi_image_is_linear (const VAImage * va_image) case VA_FOURCC ('R', 'G', 'B', 'X'): case VA_FOURCC ('X', 'B', 'G', 'R'): case VA_FOURCC ('B', 'G', 'R', 'X'): + case VA_FOURCC ('Y', '2', '1', '0'): data_size = 4 * width * height; break; case VA_FOURCC ('P', '0', '1', '0'): diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index e9ffeb8de2..83e25e0f0c 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -66,6 +66,7 @@ G_BEGIN_DECLS * @GST_VAAPI_CHROMA_TYPE_RGB32: 32-bit RGB chroma format * @GST_VAAPI_CHROMA_TYPE_RGB16: 16-bit RGB chroma format * @GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: YUV 4:2:0 chroma format, more than 8 bits per channel + * @GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: YUV 4:2:2 chroma format, more than 8 bits per channel * * The set of all chroma types for #GstVaapiSurface. */ @@ -79,7 +80,8 @@ typedef enum GST_VAAPI_CHROMA_TYPE_YUV400, GST_VAAPI_CHROMA_TYPE_RGB32, GST_VAAPI_CHROMA_TYPE_RGB16, - GST_VAAPI_CHROMA_TYPE_YUV420_10BPP + GST_VAAPI_CHROMA_TYPE_YUV420_10BPP, + GST_VAAPI_CHROMA_TYPE_YUV422_10BPP, } GstVaapiChromaType; /** diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 030f595c0e..7a01d4d1d4 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -406,6 +406,11 @@ to_GstVaapiChromaType (guint va_rt_format) case VA_RT_FORMAT_YUV420_10BPP: chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; break; +#endif +#if VA_CHECK_VERSION(1,2,0) + case VA_RT_FORMAT_YUV422_10: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_10BPP; + break; #endif default: chroma_type = 0; @@ -454,6 +459,11 @@ from_GstVaapiChromaType (guint chroma_type) case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: format = VA_RT_FORMAT_YUV420_10BPP; break; +#endif +#if VA_CHECK_VERSION(1,2,0) + case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: + format = VA_RT_FORMAT_YUV422_10; + break; #endif default: format = 0; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 080967b0fa..ae36eab556 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -317,7 +317,10 @@ gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; break; case 2: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; + if (luma_bit_depth == 8) + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; + else if (luma_bit_depth > 8) + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_10BPP; break; case 3: chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 8aef43cbaa..e5ff3bf178 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -57,6 +57,7 @@ static const GstVideoFormatMap gst_vaapi_video_formats[] = { DEF_YUV (I420, ('I', '4', '2', '0'), LSB, 12, 420), DEF_YUV (YUY2, ('Y', 'U', 'Y', '2'), LSB, 16, 422), DEF_YUV (UYVY, ('U', 'Y', 'V', 'Y'), LSB, 16, 422), + DEF_YUV (Y210, ('Y', '2', '1', '0'), LSB, 32, 422_10BPP), DEF_YUV (AYUV, ('A', 'Y', 'U', 'V'), LSB, 32, 444), #if G_BYTE_ORDER == G_BIG_ENDIAN DEF_RGB (ARGB, ('A', 'R', 'G', 'B'), MSB, 32, @@ -298,6 +299,8 @@ gst_vaapi_video_format_from_chroma (guint chroma_type) return GST_VIDEO_FORMAT_P010_10LE; case GST_VAAPI_CHROMA_TYPE_YUV444: return GST_VIDEO_FORMAT_AYUV; + case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: + return GST_VIDEO_FORMAT_Y210; default: return GST_VIDEO_FORMAT_UNKNOWN; } diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index e9275f4b39..d735a3b68b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -87,7 +87,7 @@ static const char gst_vaapidecode_src_caps_str[] = #if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" #endif - GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, P010_10LE }") ";" + GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE }") ";" GST_VAAPI_MAKE_DMABUF_CAPS; static GstStaticPadTemplate gst_vaapidecode_src_factory = diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index b13d7cc518..6390a23c08 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -105,7 +105,7 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps, #define GST_VAAPI_MAKE_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, P010_10LE }") + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE }") #define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ From d38d65f00969811f28e616f3a13cb388be766baf Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Mon, 5 Nov 2018 13:00:28 +0800 Subject: [PATCH 3162/3781] Clone the code from gitlab This fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/116 --- .gitmodules | 2 +- gstreamer-vaapi.doap | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 3ff9d95ea0..ace7333ca2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "common"] path = common - url = https://anongit.freedesktop.org/git/gstreamer/common.git + url = https://gitlab.freedesktop.org/git/gstreamer/common.git diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 97abcc7cfc..431454bc94 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -20,8 +20,8 @@ - - + + From f68f45f687c2adcb85b7f33e836f62f6d425063d Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Mon, 5 Nov 2018 05:41:13 +0000 Subject: [PATCH 3163/3781] Update common submodule location Remove the git directory --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index ace7333ca2..0ab838765a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "common"] path = common - url = https://gitlab.freedesktop.org/git/gstreamer/common.git + url = https://gitlab.freedesktop.org/gstreamer/common.git From 5171a3d5b1b3ebe7a26c8b835edeb922186f374a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 2 Nov 2018 16:50:00 +0100 Subject: [PATCH 3164/3781] build: meson: declare headers for libgstvaapi Thus handling its recompilation if needed. --- gst-libs/gst/vaapi/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 5a930c71c1..90787f3c9d 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -220,7 +220,7 @@ if USE_X11 endif gstlibvaapi = static_library('gstlibvaapi-@0@'.format(api_version), - gstlibvaapi_sources, + gstlibvaapi_sources + gstlibvaapi_headers, c_args : gstreamer_vaapi_args + [ '-DGST_USE_UNSTABLE_API', '-DGST_VAAPI_VERSION_ID="@0@"'.format(gst_version)], include_directories: [configinc, libsinc], dependencies : gstlibvaapi_deps, From 254eb9507f5e3c51552bfdf6c4b97650e847d55a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 2 Nov 2018 16:50:47 +0100 Subject: [PATCH 3165/3781] build: meson: build examples --- meson.build | 7 +++- meson_options.txt | 4 ++ tests/elements/meson.build | 24 ++++++++++++ tests/meson.build | 75 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 tests/elements/meson.build create mode 100644 tests/meson.build diff --git a/meson.build b/meson.build index 9af89604a3..f948bb9c16 100644 --- a/meson.build +++ b/meson.build @@ -68,6 +68,9 @@ x11_dep = dependency('x11', required: false) xrandr_dep = dependency('xrandr', required: false) xrender_dep = dependency('xrender', required: false) +# some of the examples can use GTK+-3 +gtk_dep = dependency('gtk+-3.0', version : '>= 3.10', required : get_option('examples')) + GLES_VERSION_MASK = gl_dep.found() ? 1 : 0 if glesv2_dep.found() if (cc.has_header('GLES2/gl2.h', dependencies: glesv2_dep) and @@ -182,7 +185,9 @@ libsinc = include_directories('gst-libs') subdir('gst-libs') subdir('gst') -#subdir('tests') +if not get_option('examples').disabled() + subdir('tests') +endif python3 = import('python3').find_python() run_command(python3, '-c', 'import shutil; shutil.copy("hooks/pre-commit.hook", ".git/hooks/pre-commit")') diff --git a/meson_options.txt b/meson_options.txt index 018f8bc33d..f2b50f866f 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -4,3 +4,7 @@ option('with_x11', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'aut option('with_glx', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') option('with_wayland', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') option('with_egl', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'auto') + +# Common feature options +option('examples', type : 'feature', value : 'auto', yield : true) +option('gtk_doc', type : 'feature', value : 'auto', yield : true, description : 'Build API documentation with gtk-doc') diff --git a/tests/elements/meson.build b/tests/elements/meson.build new file mode 100644 index 0000000000..9fb57f679c --- /dev/null +++ b/tests/elements/meson.build @@ -0,0 +1,24 @@ +examples = [ + 'test-vaapisink', + 'test-vaapipostproc', + 'test-roi', +] + +foreach example : examples + executable(example, '@0@.c'.format(example), + c_args : gstreamer_vaapi_args, + include_directories: [configinc, libsinc], + dependencies : [gst_dep, gstvideo_dep], + install: false) +endforeach + +executable('test-vaapicontext', 'test-vaapicontext.c', + c_args : gstreamer_vaapi_args, + include_directories: [configinc, libsinc], + dependencies : [ gst_dep, + gstvideo_dep, + libva_dep, + x11_dep, + gtk_dep, + libva_x11_dep ], + install: false) diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 0000000000..b7f7c88131 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,75 @@ +libdecutils_sources = [ + 'decoder.c', + 'test-h264.c', + 'test-jpeg.c', + 'test-mpeg2.c', + 'test-mpeg4.c', + 'test-vc1.c', +] + +libdecutils_headers = [ + 'decoder.h', + 'test-h264.h', + 'test-jpeg.h', + 'test-mpeg2.h', + 'test-mpeg4.h', + 'test-vc1.h', +] + +libutils_sources = [ + 'codec.c', + 'image.c', + 'output.c', + 'test-subpicture-data.c', + 'y4mreader.c', +] + +libutils_headers = [ + 'codec.h', + 'image.h', + 'output.h', + 'test-subpicture-data.h', + 'y4mreader.h', +] + +test_examples = [ + 'simple-decoder', + 'test-decode', + 'test-display', + 'test-filter', + 'test-surfaces', + 'test-windows', + 'test-subpicture', +] + +if USE_ENCODERS + test_examples += [ 'simple-encoder' ] +endif +if USE_GLX + test_examples += [ 'test-textures' ] +endif + +libutils = static_library('libutils', + libutils_sources + libutils_headers, + c_args : gstreamer_vaapi_args, + include_directories: [configinc, libsinc], + dependencies : gstlibvaapi_deps, + install: false) + +libdecutils = static_library('libdecutils', + libdecutils_sources + libdecutils_headers, + c_args : gstreamer_vaapi_args, + include_directories: [configinc, libsinc], + dependencies : gstlibvaapi_deps, + install: false) + +foreach example : test_examples + executable(example, '@0@.c'.format(example), + c_args : gstreamer_vaapi_args, + include_directories: [configinc, libsinc], + dependencies : [gst_dep, libva_dep, gstlibvaapi_dep], + link_with: [libutils, libdecutils], + install: false) +endforeach + +subdir('elements') From 2cdcca7aba5311a6d6b037ed103f857cf731a015 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Sat, 3 Nov 2018 15:28:35 +0800 Subject: [PATCH 3166/3781] tests: check return value when using gst_buffer_map. https://bugzilla.gnome.org/show_bug.cgi?id=797366 --- tests/simple-encoder.c | 3 ++- tests/test-fei-enc-in.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/simple-encoder.c b/tests/simple-encoder.c index 9ae63d87db..c94f3b5f95 100644 --- a/tests/simple-encoder.c +++ b/tests/simple-encoder.c @@ -234,7 +234,8 @@ outputs_to_file (GstBuffer * buffer, FILE * file) size_t written; gboolean ret = FALSE; - gst_buffer_map (buffer, &info, GST_MAP_READ); + if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) + return FALSE; if (info.size <= 0 || !info.data) return FALSE; diff --git a/tests/test-fei-enc-in.c b/tests/test-fei-enc-in.c index 10d8de7cb3..d64a9468ff 100644 --- a/tests/test-fei-enc-in.c +++ b/tests/test-fei-enc-in.c @@ -279,7 +279,8 @@ outputs_to_file (GstBuffer * buffer, FILE * file) size_t written; gboolean ret = FALSE; - gst_buffer_map (buffer, &info, GST_MAP_READ); + if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) + return FALSE; if (info.size <= 0 || !info.data) return FALSE; From b26f3d989d2651c7a7c8570bcfb54907adbfaf23 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Sat, 3 Nov 2018 15:06:09 +0800 Subject: [PATCH 3167/3781] libs: encoder: h264/h264fei: remove unuseless code. The variable are set twice, remove previous one. https://bugzilla.gnome.org/show_bug.cgi?id=797365 --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 1 - gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 1 - 2 files changed, 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index 769f3d5763..f899b0588b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -1892,7 +1892,6 @@ fill_sequence (GstVaapiEncoderH264Fei * encoder, GstVaapiEncSequence * sequence) seq_param->level_idc = encoder->level_idc; seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); - seq_param->ip_period = 1 + encoder->num_bframes; seq_param->ip_period = seq_param->intra_period > 1 ? (1 + encoder->num_bframes) : 0; seq_param->bits_per_second = encoder->bitrate_bits; diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index c551e62556..edbab131a3 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -641,7 +641,6 @@ fill_sequence (GstVaapiFeiEncH264 * feienc, GstVaapiEncSequence * sequence) seq_param->level_idc = feienc->level_idc; seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (feienc); seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (feienc); - seq_param->ip_period = 1 + feienc->num_bframes; seq_param->ip_period = seq_param->intra_period > 1 ? (1 + feienc->num_bframes) : 0; seq_param->bits_per_second = feienc->bitrate_bits; From f25a80bf055a652f40ed1c6f7e3a6471f712ac39 Mon Sep 17 00:00:00 2001 From: Junyan He Date: Wed, 17 Oct 2018 18:36:52 +0800 Subject: [PATCH 3168/3781] plugins: Fix build error when GL is enabled while EGL is disabled. gl_platform_type in gst_vaapi_get_display_type_from_gl_env generate unused-variable warning and may block build when Werror enabled. Several functions like gst_vaapi_display_egl_new_with_native_display have no prototype warning and link error when GL is enabled but EGL is disabled. Fix all these warning and link error. https://bugzilla.gnome.org/show_bug.cgi?id=797358 Signed-off-by: Junyan He --- gst/vaapi/gstvaapipluginutil.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 8632da8136..23b3b6a1ee 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -132,9 +132,7 @@ gst_vaapi_create_display_from_handle (GstVaapiDisplayType display_type, } return NULL; } -#endif -#if USE_GST_GL_HELPERS static GstVaapiDisplayType gst_vaapi_get_display_type_from_gl (GstGLDisplayType gl_display_type, GstGLPlatform gl_platform) @@ -171,7 +169,6 @@ static GstVaapiDisplayType gst_vaapi_get_display_type_from_gl_env (void) { const gchar *const gl_window_type = g_getenv ("GST_GL_WINDOW"); - const gchar *const gl_platform_type = g_getenv ("GST_GL_PLATFORM"); if (!gl_window_type) { #if USE_X11 && GST_GL_HAVE_WINDOW_X11 @@ -191,13 +188,17 @@ gst_vaapi_get_display_type_from_gl_env (void) return GST_VAAPI_DISPLAY_TYPE_WAYLAND; #endif #if USE_EGL - if (g_strcmp0 (gl_platform_type, "egl") == 0) - return GST_VAAPI_DISPLAY_TYPE_EGL; + { + const gchar *const gl_platform_type = g_getenv ("GST_GL_PLATFORM"); + if (g_strcmp0 (gl_platform_type, "egl") == 0) + return GST_VAAPI_DISPLAY_TYPE_EGL; + } #endif return GST_VAAPI_DISPLAY_TYPE_ANY; } +#if USE_EGL static gint gst_vaapi_get_gles_version_from_gl_api (GstGLAPI gl_api) { @@ -219,27 +220,27 @@ static guintptr gst_vaapi_get_egl_handle_from_gl_display (GstGLDisplay * gl_display) { guintptr egl_handle = 0; - -#if USE_EGL && GST_GL_HAVE_PLATFORM_EGL GstGLDisplayEGL *egl_display; + egl_display = gst_gl_display_egl_from_gl_display (gl_display); if (egl_display) { egl_handle = gst_gl_display_get_handle (GST_GL_DISPLAY (egl_display)); gst_object_unref (egl_display); } -#endif return egl_handle; } +#endif /* USE_EGL */ static GstVaapiDisplay * gst_vaapi_create_display_from_egl (GstGLDisplay * gl_display, GstGLContext * gl_context, GstVaapiDisplayType display_type, gpointer native_display) { + GstVaapiDisplay *display = NULL; +#if USE_EGL GstGLAPI gl_api; gint gles_version; guintptr egl_handler; - GstVaapiDisplay *display = NULL; gl_api = gst_gl_context_get_gl_api (gl_context); gles_version = gst_vaapi_get_gles_version_from_gl_api (gl_api); @@ -268,7 +269,7 @@ gst_vaapi_create_display_from_egl (GstGLDisplay * gl_display, gst_vaapi_display_egl_set_gl_context (GST_VAAPI_DISPLAY_EGL (display), GSIZE_TO_POINTER (gst_gl_context_get_gl_context (gl_context))); } - +#endif return display; } #endif /* USE_GST_GL_HELPERS */ From 14c283f8918f2d3ed87f628bf218ae596a884d0d Mon Sep 17 00:00:00 2001 From: Junyan He Date: Tue, 6 Nov 2018 14:38:08 +0800 Subject: [PATCH 3169/3781] libs: Modify the video format of endianness. We lack some video format because endianness declare. The video format should not directly relate to endianness. For example, ARGB on big endian should not be simplely seen as BGRA on little endian machine. We should provide endianess convert or format convert help functions if endianness does not match. https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/112 Signed-off-by: Junyan He --- gst-libs/gst/vaapi/video-format.c | 55 +++++++++++++++++-------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index e5ff3bf178..b05d10957f 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -32,6 +32,12 @@ #include "gstvaapisurface.h" #include "video-format.h" +#if G_BYTE_ORDER == G_BIG_ENDIAN +# define VIDEO_VA_ENDIANESS VA_MSB_FIRST +#elif G_BYTE_ORDER == G_LITTLE_ENDIAN +# define VIDEO_VA_ENDIANESS VA_LSB_FIRST +#endif + typedef struct { GstVideoFormat format; @@ -39,47 +45,48 @@ typedef struct VAImageFormat va_format; } GstVideoFormatMap; -#define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP, SUB) \ +#define DEF_YUV(FORMAT, FOURCC, BPP, SUB) \ { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ G_PASTE(GST_VAAPI_CHROMA_TYPE_YUV,SUB), \ - { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, } + { VA_FOURCC FOURCC, VIDEO_VA_ENDIANESS, BPP, }, } -#define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \ +#define DEF_RGB(FORMAT, FOURCC, BPP, DEPTH, R,G,B,A) \ { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ G_PASTE(GST_VAAPI_CHROMA_TYPE_RGB,BPP), \ - { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, } + { VA_FOURCC FOURCC, VIDEO_VA_ENDIANESS, BPP, DEPTH, R,G,B,A }, } /* Image formats, listed in HW order preference */ /* *INDENT-OFF* */ static const GstVideoFormatMap gst_vaapi_video_formats[] = { - DEF_YUV (NV12, ('N', 'V', '1', '2'), LSB, 12, 420), - DEF_YUV (YV12, ('Y', 'V', '1', '2'), LSB, 12, 420), - DEF_YUV (I420, ('I', '4', '2', '0'), LSB, 12, 420), - DEF_YUV (YUY2, ('Y', 'U', 'Y', '2'), LSB, 16, 422), - DEF_YUV (UYVY, ('U', 'Y', 'V', 'Y'), LSB, 16, 422), - DEF_YUV (Y210, ('Y', '2', '1', '0'), LSB, 32, 422_10BPP), - DEF_YUV (AYUV, ('A', 'Y', 'U', 'V'), LSB, 32, 444), -#if G_BYTE_ORDER == G_BIG_ENDIAN - DEF_RGB (ARGB, ('A', 'R', 'G', 'B'), MSB, 32, + /* YUV formats */ + DEF_YUV (NV12, ('N', 'V', '1', '2'), 12, 420), + DEF_YUV (YV12, ('Y', 'V', '1', '2'), 12, 420), + DEF_YUV (I420, ('I', '4', '2', '0'), 12, 420), + DEF_YUV (YUY2, ('Y', 'U', 'Y', '2'), 16, 422), + DEF_YUV (UYVY, ('U', 'Y', 'V', 'Y'), 16, 422), + DEF_YUV (Y210, ('Y', '2', '1', '0'), 32, 422_10BPP), + DEF_YUV (AYUV, ('A', 'Y', 'U', 'V'), 32, 444), + DEF_YUV (GRAY8, ('Y', '8', '0', '0'), 8, 400), + DEF_YUV (P010_10LE, ('P', '0', '1', '0'), 24, 420_10BPP), + /* RGB formats */ + DEF_RGB (ARGB, ('A', 'R', 'G', 'B'), 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), - DEF_RGB (ABGR, ('A', 'B', 'G', 'R'), MSB, 32, + DEF_RGB (ABGR, ('A', 'B', 'G', 'R'), 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), - DEF_RGB (xRGB, ('X', 'R', 'G', 'B'), MSB, 32, + DEF_RGB (xRGB, ('X', 'R', 'G', 'B'), 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), - DEF_RGB (xBGR, ('X', 'B', 'G', 'R'), MSB, 32, + DEF_RGB (xBGR, ('X', 'B', 'G', 'R'), 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), -#elif G_BYTE_ORDER == G_LITTLE_ENDIAN - DEF_RGB (BGRA, ('B', 'G', 'R', 'A'), LSB, 32, + DEF_RGB (BGRA, ('B', 'G', 'R', 'A'), 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), - DEF_RGB (RGBA, ('R', 'G', 'B', 'A'), LSB, 32, + DEF_RGB (RGBA, ('R', 'G', 'B', 'A'), 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), - DEF_RGB (BGRx, ('B', 'G', 'R', 'X'), LSB, 32, + DEF_RGB (BGRx, ('B', 'G', 'R', 'X'), 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), - DEF_RGB (RGBx, ('R', 'G', 'B', 'X'), LSB, 32, + DEF_RGB (RGBx, ('R', 'G', 'B', 'X'), 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), -#endif - DEF_YUV (GRAY8, ('Y', '8', '0', '0'), LSB, 8, 400), - DEF_YUV (P010_10LE, ('P', '0', '1', '0'), LSB, 24, 420_10BPP), + DEF_RGB (ARGB, ('A', 'R', 'G', 'B'), 32, + 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), {0,} }; /* *INDENT-ON* */ From 3f87cc2fff8d5c66641ae4a460be5974cb1a498d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 9 Nov 2018 23:46:53 +0000 Subject: [PATCH 3170/3781] meson: bump meson required to 0.47 for feature options --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index f948bb9c16..1cfb72c52d 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('gstreamer-vaapi', 'c', version : '1.15.0.1', - meson_version : '>= 0.46.0', + meson_version : '>= 0.47.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From de6883f6d005c97c6bb454a0e4aa47ddea1c5d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 9 Nov 2018 23:55:05 +0000 Subject: [PATCH 3171/3781] meson: link with -lm Fixes #117 hopefully. --- gst-libs/gst/vaapi/meson.build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 90787f3c9d..948937f2db 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -202,7 +202,8 @@ gstlibvaapi_deps = [ gstbase_dep, gstvideo_dep, gstgl_dep, gstcodecparsers_dep, - libva_dep ] + libva_dep, + libm ] if USE_DRM gstlibvaapi_deps += [libva_drm_dep, libdrm_dep, libudev_dep] endif From 90d8350820821eaa72b582b3eecbc478ea88b6cc Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 9 Nov 2018 22:03:43 +0800 Subject: [PATCH 3172/3781] libs: Sync the GstVaapiChromaType to VA header file. Add more kinds of chrometype which will be used to describe new video formats. Sync it with 1.4.0 version header file. Alse delete useless GST_VAAPI_CHROMA_TYPE_YUV410 chrome type. Signed-off-by: He Junyan --- gst-libs/gst/vaapi/gstvaapisurface.h | 24 ++++++++++----- gst-libs/gst/vaapi/gstvaapiutils.c | 44 ++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 83e25e0f0c..a80b9dbf3e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -61,12 +61,17 @@ G_BEGIN_DECLS * @GST_VAAPI_CHROMA_TYPE_YUV422: YUV 4:2:2 chroma format * @GST_VAAPI_CHROMA_TYPE_YUV444: YUV 4:4:4 chroma format * @GST_VAAPI_CHROMA_TYPE_YUV411: YUV 4:1:1 chroma format - * @GST_VAAPI_CHROMA_TYPE_YUV410: YUV 4:1:0 chroma format * @GST_VAAPI_CHROMA_TYPE_YUV400: YUV 4:0:0 chroma format (grayscale) - * @GST_VAAPI_CHROMA_TYPE_RGB32: 32-bit RGB chroma format + * @GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: YUV 4:2:0 chroma format, 10 bits per channel + * @GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: YUV 4:2:2 chroma format, 10 bits per channel + * @GST_VAAPI_CHROMA_TYPE_YUV444_10BPP: YUV 4:4:4 chroma format, 10 bits per channel + * @GST_VAAPI_CHROMA_TYPE_YUV420_12BPP: YUV 4:2:0 chroma format, 12 bits per channel + * @GST_VAAPI_CHROMA_TYPE_YUV422_12BPP: YUV 4:2:2 chroma format, 12 bits per channel + * @GST_VAAPI_CHROMA_TYPE_YUV444_12BPP: YUV 4:4:4 chroma format, 12 bits per channel * @GST_VAAPI_CHROMA_TYPE_RGB16: 16-bit RGB chroma format - * @GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: YUV 4:2:0 chroma format, more than 8 bits per channel - * @GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: YUV 4:2:2 chroma format, more than 8 bits per channel + * @GST_VAAPI_CHROMA_TYPE_RGB32: 32-bit RGB chroma format + * @GST_VAAPI_CHROMA_TYPE_RGBP: Planar RGB, 8 bits per colour sample. + * @GST_VAAPI_CHROMA_TYPE_RGB32_10BPP: 32-bit RGB chroma format, 10 bits per colour sample * * The set of all chroma types for #GstVaapiSurface. */ @@ -76,12 +81,17 @@ typedef enum GST_VAAPI_CHROMA_TYPE_YUV422, GST_VAAPI_CHROMA_TYPE_YUV444, GST_VAAPI_CHROMA_TYPE_YUV411, - GST_VAAPI_CHROMA_TYPE_YUV410, GST_VAAPI_CHROMA_TYPE_YUV400, - GST_VAAPI_CHROMA_TYPE_RGB32, - GST_VAAPI_CHROMA_TYPE_RGB16, GST_VAAPI_CHROMA_TYPE_YUV420_10BPP, GST_VAAPI_CHROMA_TYPE_YUV422_10BPP, + GST_VAAPI_CHROMA_TYPE_YUV444_10BPP, + GST_VAAPI_CHROMA_TYPE_YUV420_12BPP, + GST_VAAPI_CHROMA_TYPE_YUV422_12BPP, + GST_VAAPI_CHROMA_TYPE_YUV444_12BPP, + GST_VAAPI_CHROMA_TYPE_RGB16, + GST_VAAPI_CHROMA_TYPE_RGB32, + GST_VAAPI_CHROMA_TYPE_RGBP, + GST_VAAPI_CHROMA_TYPE_RGB32_10BPP, } GstVaapiChromaType; /** diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 7a01d4d1d4..be5b6c852f 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -331,6 +331,14 @@ string_of_va_chroma_format (guint chroma_format) #if VA_CHECK_VERSION(0,38,1) MAP (YUV420_10BPP); #endif +#if VA_CHECK_VERSION(1,2,0) + MAP (YUV422_10); + MAP (YUV444_10); + MAP (YUV420_12); + MAP (YUV422_12); + MAP (YUV444_12); + MAP (RGB32_10); +#endif #undef MAP default: break; @@ -401,6 +409,9 @@ to_GstVaapiChromaType (guint va_rt_format) case VA_RT_FORMAT_RGB16: chroma_type = GST_VAAPI_CHROMA_TYPE_RGB16; break; + case VA_RT_FORMAT_RGBP: + chroma_type = GST_VAAPI_CHROMA_TYPE_RGBP; + break; #endif #if VA_CHECK_VERSION(0,38,1) case VA_RT_FORMAT_YUV420_10BPP: @@ -411,6 +422,21 @@ to_GstVaapiChromaType (guint va_rt_format) case VA_RT_FORMAT_YUV422_10: chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_10BPP; break; + case VA_RT_FORMAT_YUV444_10: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_10BPP; + break; + case VA_RT_FORMAT_YUV420_12: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_12BPP; + break; + case VA_RT_FORMAT_YUV422_12: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_12BPP; + break; + case VA_RT_FORMAT_YUV444_12: + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_12BPP; + break; + case VA_RT_FORMAT_RGB32_10: + chroma_type = GST_VAAPI_CHROMA_TYPE_RGB32_10BPP; + break; #endif default: chroma_type = 0; @@ -454,6 +480,9 @@ from_GstVaapiChromaType (guint chroma_type) case GST_VAAPI_CHROMA_TYPE_RGB16: format = VA_RT_FORMAT_RGB16; break; + case GST_VAAPI_CHROMA_TYPE_RGBP: + format = VA_RT_FORMAT_RGBP; + break; #endif #if VA_CHECK_VERSION(0,38,1) case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: @@ -464,6 +493,21 @@ from_GstVaapiChromaType (guint chroma_type) case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: format = VA_RT_FORMAT_YUV422_10; break; + case GST_VAAPI_CHROMA_TYPE_YUV444_10BPP: + format = VA_RT_FORMAT_YUV444_10; + break; + case GST_VAAPI_CHROMA_TYPE_YUV420_12BPP: + format = VA_RT_FORMAT_YUV420_12; + break; + case GST_VAAPI_CHROMA_TYPE_YUV422_12BPP: + format = VA_RT_FORMAT_YUV422_12; + break; + case GST_VAAPI_CHROMA_TYPE_YUV444_12BPP: + format = VA_RT_FORMAT_YUV444_12; + break; + case GST_VAAPI_CHROMA_TYPE_RGB32_10BPP: + format = VA_RT_FORMAT_RGB32_10; + break; #endif default: format = 0; From b67fc3a51803aca641d8ee7c870690fd10f5d018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 12 Nov 2018 17:43:54 +0100 Subject: [PATCH 3173/3781] Add Gitlab CI configuration This commit adds a .gitlab-ci.yml file, which uses a feature to fetch the config from a centralized repository. The intent is to have all the gstreamer modules use the same configuration. The configuration is currently hosted at the gst-ci repository under the gitlab/ci_template.yml path. Part of https://gitlab.freedesktop.org/gstreamer/gstreamer-project/issues/29 --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000..c61aa7a529 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1 @@ +include: "https://gitlab.freedesktop.org/gstreamer/gst-ci/raw/master/gitlab/ci_template.yml" From 5d0878b48abddff4f646c7fa774dec2b199fdd92 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Wed, 14 Nov 2018 13:52:48 +0800 Subject: [PATCH 3174/3781] libs: dec: h265: support decode for main-444 8bit streams. Add 444 8bit yuv format AYUV, which can be used to decode main-444 8bit streams. Currently, this feature is only supported by media-driver in Icelake. https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/119 --- gst-libs/gst/vaapi/gstvaapiprofile.c | 4 ++++ gst-libs/gst/vaapi/gstvaapiprofile.h | 1 + gst-libs/gst/vaapi/gstvaapiutils.c | 1 + gst-libs/gst/vaapi/gstvaapiutils_h265.c | 14 ++++++++++++++ gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapipluginutil.h | 2 +- 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 4b540f3f58..e72d753fcb 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -135,6 +135,8 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { #if VA_CHECK_VERSION(1,2,0) {GST_VAAPI_PROFILE_H265_MAIN_422_10, VAProfileHEVCMain422_10, "video/x-h265", "main-422-10"}, + {GST_VAAPI_PROFILE_H265_MAIN_444, VAProfileHEVCMain444, + "video/x-h265", "main-444"}, #endif #if VA_CHECK_VERSION(0,38,0) {GST_VAAPI_PROFILE_VP9_0, VAProfileVP9Profile0, @@ -336,6 +338,8 @@ gst_vaapi_profile_from_codec_data_h265 (GstBuffer * buffer) return GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; case 4: return GST_VAAPI_PROFILE_H265_MAIN_422_10; + case 5: + return GST_VAAPI_PROFILE_H265_MAIN_444; } return 0; } diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 066c189a69..ce5ffbac20 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -178,6 +178,7 @@ typedef enum { GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE = GST_VAAPI_MAKE_PROFILE(H265,3), GST_VAAPI_PROFILE_H265_MAIN_422_10 = GST_VAAPI_MAKE_PROFILE(H265,4), + GST_VAAPI_PROFILE_H265_MAIN_444 = GST_VAAPI_MAKE_PROFILE(H265,5), GST_VAAPI_PROFILE_VP9_0 = GST_VAAPI_MAKE_PROFILE(VP9,1), GST_VAAPI_PROFILE_VP9_1 = GST_VAAPI_MAKE_PROFILE(VP9,2), GST_VAAPI_PROFILE_VP9_2 = GST_VAAPI_MAKE_PROFILE(VP9,3), diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index be5b6c852f..414ae129ac 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -230,6 +230,7 @@ string_of_VAProfile (VAProfile profile) #endif #if VA_CHECK_VERSION(1,2,0) MAP (HEVCMain422_10); + MAP (HEVCMain444); #endif #if VA_CHECK_VERSION(0,37,1) MAP (HEVCMain); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index ae36eab556..4f0582fb4f 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -161,6 +161,17 @@ gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { profile = GST_VAAPI_PROFILE_H265_MAIN_422_10; break; + } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 1 + && sps->profile_tier_level.max_422chroma_constraint_flag == 0 + && sps->profile_tier_level.max_420chroma_constraint_flag == 0 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 0 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0 + && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { + profile = GST_VAAPI_PROFILE_H265_MAIN_444; + break; } default: GST_DEBUG ("unsupported profile_idc value"); @@ -189,6 +200,9 @@ gst_vaapi_utils_h265_get_profile_idc (GstVaapiProfile profile) case GST_VAAPI_PROFILE_H265_MAIN_422_10: profile_idc = GST_H265_PROFILE_MAIN_422_10; break; + case GST_VAAPI_PROFILE_H265_MAIN_444: + profile_idc = GST_H265_PROFILE_MAIN_444; + break; default: GST_DEBUG ("unsupported GstVaapiProfile value"); profile_idc = 0; diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d735a3b68b..a4cd0d9828 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -87,7 +87,7 @@ static const char gst_vaapidecode_src_caps_str[] = #if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" #endif - GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE }") ";" + GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV }") ";" GST_VAAPI_MAKE_DMABUF_CAPS; static GstStaticPadTemplate gst_vaapidecode_src_factory = diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 6390a23c08..54546dad79 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -105,7 +105,7 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps, #define GST_VAAPI_MAKE_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE }") + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV }") #define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ From 072f49cdcff4d68b9275fd36e7796cd6f5c4606f Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Mon, 12 Nov 2018 13:39:51 +0100 Subject: [PATCH 3175/3781] vaapiencode: don't start src pad task in set_format Otherwise the task may be restarted during shutdown. Start the task in gst_vaapiencode_handle_frame() instead. --- gst/vaapi/gstvaapiencode.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 97cfd0dcbf..489df0bcaa 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -591,7 +591,6 @@ static gboolean gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); - gboolean ret; g_return_val_if_fail (state->caps != NULL, FALSE); @@ -610,12 +609,6 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) encode->input_state = gst_video_codec_state_ref (state); encode->input_state_changed = TRUE; - ret = gst_pad_start_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode), - (GstTaskFunction) gst_vaapiencode_buffer_loop, encode, NULL); - - if (!ret) - return FALSE; - /* Store some tags */ { GstTagList *tags = gst_tag_list_new_empty (); @@ -650,16 +643,24 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GstVideoCodecFrame * frame) { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); + GstPad *const srcpad = GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode); GstVaapiEncoderStatus status; GstVaapiVideoMeta *meta; GstVaapiSurfaceProxy *proxy; GstFlowReturn ret; GstBuffer *buf; + GstTaskState task_state; #if USE_H264_FEI_ENCODER GstVaapiFeiVideoMeta *feimeta = NULL; GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (venc); #endif + task_state = gst_pad_get_task_state (srcpad); + if (task_state == GST_TASK_STOPPED || task_state == GST_TASK_PAUSED) + if (!gst_pad_start_task (srcpad, + (GstTaskFunction) gst_vaapiencode_buffer_loop, encode, NULL)) + goto error_task_failed; + buf = NULL; ret = gst_vaapi_plugin_base_get_input_buffer (GST_VAAPI_PLUGIN_BASE (encode), frame->input_buffer, &buf); @@ -697,6 +698,13 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, return GST_FLOW_OK; /* ERRORS */ +error_task_failed: + { + GST_ELEMENT_ERROR (venc, RESOURCE, FAILED, + ("Failed to start encoding thread."), (NULL)); + gst_video_codec_frame_unref (frame); + return GST_FLOW_ERROR; + } error_buffer_invalid: { if (buf) From c728fb4ff6c3b4fc9eb9b43fcea4a22bc15fd678 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 20 Nov 2018 16:07:44 +0800 Subject: [PATCH 3176/3781] Close dmabuf_fd Otherwise it will result in resource leak when failed to create dmabuf memory --- gst/vaapi/gstvaapivideomemory.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 3d00e8dd1f..7bacdda2be 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1060,6 +1060,7 @@ error_create_dmabuf_handle: error_create_dmabuf_memory: { GST_ERROR ("failed to create DMABUF memory"); + close (dmabuf_fd); gst_vaapi_buffer_proxy_unref (dmabuf_proxy); return NULL; } From c1de41b8414fe72c7774255520d15f3ba5836208 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Wed, 14 Nov 2018 11:34:20 +0100 Subject: [PATCH 3177/3781] vaapipostproc: add some missing locking gst_vaapi_plugin_base_close() removed the raw caps that are used indirectly in gst_vaapipostproc_transform_caps(). The usage is already protected by the mutex. This is needed when the pipeline is stopped during startup. --- gst/vaapi/gstvaapipostproc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 7698aea978..4577454b5d 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -318,6 +318,7 @@ gst_vaapipostproc_stop (GstBaseTransform * trans) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + g_mutex_lock (&postproc->postproc_lock); ds_reset (&postproc->deinterlace_state); gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (postproc)); @@ -325,6 +326,7 @@ gst_vaapipostproc_stop (GstBaseTransform * trans) gst_video_info_init (&postproc->sinkpad_info); gst_video_info_init (&postproc->srcpad_info); gst_video_info_init (&postproc->filter_pool_info); + g_mutex_unlock (&postproc->postproc_lock); return TRUE; } From 176bbce9750875f8934a361d748b9845d5f1c88e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 14 Nov 2018 13:11:56 +0800 Subject: [PATCH 3178/3781] plugins: modify image check of extract_allowed_surface_formats. The extract_allowed_surface_formats function just check whether we can support some kind of surface/image format pair. We just need to create a surface, create an image with the same video-format and putImage from image to surface. All these operations success, that kind of video-format is supported. The old manner do not work for some kind of video-format. For example, the RGBA kind of format will create a NV12 surface and RGBA image, and the putImage will fail because the format is not same. And so the RGBA format is not supported but actually it is supported. --- gst/vaapi/gstvaapipluginbase.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 33b5b3f798..6192fefdfa 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1266,18 +1266,18 @@ extract_allowed_surface_formats (GstVaapiDisplay * display, GArray * formats) for (i = 0; i < formats->len; i++) { const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); - GstVaapiChromaType chroma_type; GstVaapiSurface *surface; GstVaapiImage *image; + GstVideoInfo vi; if (format == GST_VIDEO_FORMAT_UNKNOWN) continue; - chroma_type = gst_vaapi_video_format_get_chroma_type (format); - if (chroma_type == 0) - continue; - surface = gst_vaapi_surface_new (display, chroma_type, 64, 64); + + gst_video_info_set_format (&vi, format, 64, 64); + surface = gst_vaapi_surface_new_full (display, &vi, 0); if (!surface) continue; + image = gst_vaapi_image_new (display, format, 64, 64); if (!image) { gst_vaapi_object_unref (surface); From d8b3c0495f3a654db81b2953fc04350b17d4a4b5 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 28 Nov 2018 05:56:44 +0200 Subject: [PATCH 3179/3781] Run gst-indent through the files This is required before we enabled an indent test in the CI. https://gitlab.freedesktop.org/gstreamer/gstreamer-project/issues/33 --- gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapisink.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a4cd0d9828..0884fc946a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -766,7 +766,7 @@ error_decode: GST_INFO ("requesting upstream a key unit"); gst_pad_push_event (GST_VIDEO_DECODER_SINK_PAD (decode), gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE, - FALSE, 0)); + FALSE, 0)); ret = GST_FLOW_OK; break; } diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index c57b1261c9..9333f43824 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -452,7 +452,7 @@ gst_vaapisink_x11_pre_start_event_thread (GstVaapiSink * sink) PointerMotionMask | ExposureMask | StructureNotifyMask); if (!sink->foreign_window) - x11_event_mask |= ButtonPressMask | ButtonReleaseMask; + x11_event_mask |= ButtonPressMask | ButtonReleaseMask; if (sink->window) { gst_vaapi_display_lock (GST_VAAPI_DISPLAY (display)); From 5e7988b2d8df8420300e044e753175e59e5dcec0 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Tue, 27 Nov 2018 09:47:44 -0500 Subject: [PATCH 3180/3781] libs: dec: h265: support decode for main-444 10bit streams. Add 444 10bit yuv format Y410, which can be used to decode main-444 10bit streams. Currently, this feature is only supported by media-driver in Icelake. --- gst-libs/gst/vaapi/gstvaapiimage.c | 1 + gst-libs/gst/vaapi/gstvaapiprofile.c | 2 ++ gst-libs/gst/vaapi/gstvaapiprofile.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_h265.c | 16 +++++++++++++++- gst-libs/gst/vaapi/video-format.c | 3 +++ gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapipluginutil.h | 2 +- 7 files changed, 24 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 0d4878ced6..581b5d9077 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -92,6 +92,7 @@ vaapi_image_is_linear (const VAImage * va_image) case VA_FOURCC ('X', 'B', 'G', 'R'): case VA_FOURCC ('B', 'G', 'R', 'X'): case VA_FOURCC ('Y', '2', '1', '0'): + case VA_FOURCC ('Y', '4', '1', '0'): data_size = 4 * width * height; break; case VA_FOURCC ('P', '0', '1', '0'): diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index e72d753fcb..cc87096e76 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -137,6 +137,8 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h265", "main-422-10"}, {GST_VAAPI_PROFILE_H265_MAIN_444, VAProfileHEVCMain444, "video/x-h265", "main-444"}, + {GST_VAAPI_PROFILE_H265_MAIN_444_10, VAProfileHEVCMain444_10, + "video/x-h265", "main-444-10"}, #endif #if VA_CHECK_VERSION(0,38,0) {GST_VAAPI_PROFILE_VP9_0, VAProfileVP9Profile0, diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index ce5ffbac20..f5d566c614 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -179,6 +179,7 @@ typedef enum { GST_VAAPI_MAKE_PROFILE(H265,3), GST_VAAPI_PROFILE_H265_MAIN_422_10 = GST_VAAPI_MAKE_PROFILE(H265,4), GST_VAAPI_PROFILE_H265_MAIN_444 = GST_VAAPI_MAKE_PROFILE(H265,5), + GST_VAAPI_PROFILE_H265_MAIN_444_10 = GST_VAAPI_MAKE_PROFILE(H265,6), GST_VAAPI_PROFILE_VP9_0 = GST_VAAPI_MAKE_PROFILE(VP9,1), GST_VAAPI_PROFILE_VP9_1 = GST_VAAPI_MAKE_PROFILE(VP9,2), GST_VAAPI_PROFILE_VP9_2 = GST_VAAPI_MAKE_PROFILE(VP9,3), diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 4f0582fb4f..a0f3cda4bc 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -172,6 +172,17 @@ gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { profile = GST_VAAPI_PROFILE_H265_MAIN_444; break; + } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 0 + && sps->profile_tier_level.max_422chroma_constraint_flag == 0 + && sps->profile_tier_level.max_420chroma_constraint_flag == 0 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 0 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0 + && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { + profile = GST_VAAPI_PROFILE_H265_MAIN_444_10; + break; } default: GST_DEBUG ("unsupported profile_idc value"); @@ -337,7 +348,10 @@ gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_10BPP; break; case 3: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; + if (luma_bit_depth == 8) + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; + else if (luma_bit_depth > 8) + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_10BPP; break; default: GST_DEBUG ("unsupported chroma_format_idc value"); diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index b05d10957f..f24fb6c822 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -65,6 +65,7 @@ static const GstVideoFormatMap gst_vaapi_video_formats[] = { DEF_YUV (YUY2, ('Y', 'U', 'Y', '2'), 16, 422), DEF_YUV (UYVY, ('U', 'Y', 'V', 'Y'), 16, 422), DEF_YUV (Y210, ('Y', '2', '1', '0'), 32, 422_10BPP), + DEF_YUV (Y410, ('Y', '4', '1', '0'), 32, 444_10BPP), DEF_YUV (AYUV, ('A', 'Y', 'U', 'V'), 32, 444), DEF_YUV (GRAY8, ('Y', '8', '0', '0'), 8, 400), DEF_YUV (P010_10LE, ('P', '0', '1', '0'), 24, 420_10BPP), @@ -308,6 +309,8 @@ gst_vaapi_video_format_from_chroma (guint chroma_type) return GST_VIDEO_FORMAT_AYUV; case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: return GST_VIDEO_FORMAT_Y210; + case GST_VAAPI_CHROMA_TYPE_YUV444_10BPP: + return GST_VIDEO_FORMAT_Y410; default: return GST_VIDEO_FORMAT_UNKNOWN; } diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 0884fc946a..79be36660c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -87,7 +87,7 @@ static const char gst_vaapidecode_src_caps_str[] = #if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" #endif - GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV }") ";" + GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }") ";" GST_VAAPI_MAKE_DMABUF_CAPS; static GstStaticPadTemplate gst_vaapidecode_src_factory = diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 54546dad79..b59bbb041b 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -105,7 +105,7 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps, #define GST_VAAPI_MAKE_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV }") + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }") #define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ From 2b016fdde9ac4609ed87c686ca5f123d268ee3ee Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 5 Dec 2018 17:24:53 -0300 Subject: [PATCH 3181/3781] Automatic update of common submodule From ed78bee to 59cb678 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index ed78bee437..59cb678164 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit ed78bee437dcbe22e6eef0031d9a29d157c0461f +Subproject commit 59cb678164719ff59dcf6c8b93df4617a1075d11 From e73e69a48037502a7db5754f2f52b3e438e1ba05 Mon Sep 17 00:00:00 2001 From: Niels De Graef Date: Mon, 3 Dec 2018 13:56:52 +0100 Subject: [PATCH 3182/3781] Use G_DEFINE_TYPE_WITH_PRIVATE if applicable This gets rid of the strange `do_init` macro and makes the intent a bit more clear. --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 7 ++----- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 7 ++----- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 7 ++----- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index f39b4b74a4..2570754414 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -41,11 +41,8 @@ #define DEBUG_VAAPI_DISPLAY 1 #include "gstvaapidebug.h" -#define _do_init \ - G_ADD_PRIVATE (GstVaapiDisplayDRM); - -G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplayDRM, gst_vaapi_display_drm, - GST_TYPE_VAAPI_DISPLAY, _do_init); +G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiDisplayDRM, gst_vaapi_display_drm, + GST_TYPE_VAAPI_DISPLAY); typedef enum { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 4b6fc1cae6..6147cbab23 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -35,11 +35,8 @@ #define DEBUG_VAAPI_DISPLAY 1 #include "gstvaapidebug.h" -#define _do_init \ - G_ADD_PRIVATE (GstVaapiDisplayWayland); - -G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplayWayland, gst_vaapi_display_wayland, - GST_TYPE_VAAPI_DISPLAY, _do_init); +G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiDisplayWayland, gst_vaapi_display_wayland, + GST_TYPE_VAAPI_DISPLAY); static inline const gchar * get_default_display_name (void) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index dbcfee4fe2..f5fa2fcee3 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -45,11 +45,8 @@ #define DEBUG_VAAPI_DISPLAY 1 #include "gstvaapidebug.h" -#define _do_init \ - G_ADD_PRIVATE (GstVaapiDisplayX11); - -G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplayX11, gst_vaapi_display_x11, - GST_TYPE_VAAPI_DISPLAY, _do_init); +G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiDisplayX11, gst_vaapi_display_x11, + GST_TYPE_VAAPI_DISPLAY); static inline const gchar * get_default_display_name (void) From 1513cf774d75706ed910810319ed971fc36af653 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Sat, 15 Dec 2018 14:48:03 +0800 Subject: [PATCH 3183/3781] libs: enc: h264: set max profile idc with correct profile. Use the highest rank of available profile as the max profile to set max idc value. https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/124 --- gst/vaapi/gstvaapiencode_h264.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 0249ce5bb1..856afd611a 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -38,11 +38,11 @@ * If #GstVaapiEncodeH264:dct8x8 is enabled, then High profile is * used. Otherwise, if #GstVaapiEncodeH264:cabac entropy coding is * enabled or #GstVaapiEncodeH264:max-bframes are allowed, then Main - * Profile is in effect, and otherwise Baseline profile applies. The - * high profile is imposed by default, which is fine for most software - * players and settings, but in some cases (e.g. hardware platforms) a - * more restricted profile/level may be necessary. The recommended way - * to set a profile is to set it in the downstream caps. + * Profile is in effect. The element will alway go with the maximal + * profile available in the caps negotation and otherwise Baseline + * profile applies. But in some cases (e.g. hardware platforms) a more + * restrictedprofile/level may be necessary. The recommended way to + * set a profile is to set it in the downstream caps. * * You can also set parameters to adjust the latency of encoding: * #GstVaapiEncodeH264:quality-level is a number between 1-7, in the @@ -327,17 +327,8 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) } else { GstCaps *profile_caps; - const gchar *profile_str; - profile_caps = gst_caps_intersect (allowed_caps, available_caps); - - /* let's fixate to adjust to minimal profile */ - profile_caps = gst_caps_fixate (profile_caps); - - structure = gst_caps_get_structure (profile_caps, 0); - profile_str = gst_structure_get_string (structure, "profile"); - if (profile_str) - profile = gst_vaapi_utils_h264_get_profile_from_string (profile_str); + profile = find_best_profile (profile_caps); gst_caps_unref (profile_caps); } From 70d6b4002ce9de89516419489e62a0fd87f28a39 Mon Sep 17 00:00:00 2001 From: Wonchul Lee Date: Sat, 15 Dec 2018 09:47:15 +0900 Subject: [PATCH 3184/3781] meson: Add gtk guard --- tests/elements/meson.build | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/elements/meson.build b/tests/elements/meson.build index 9fb57f679c..f64d1cda2c 100644 --- a/tests/elements/meson.build +++ b/tests/elements/meson.build @@ -12,13 +12,15 @@ foreach example : examples install: false) endforeach -executable('test-vaapicontext', 'test-vaapicontext.c', - c_args : gstreamer_vaapi_args, - include_directories: [configinc, libsinc], - dependencies : [ gst_dep, - gstvideo_dep, - libva_dep, - x11_dep, - gtk_dep, - libva_x11_dep ], - install: false) +if gtk_dep.found() + executable('test-vaapicontext', 'test-vaapicontext.c', + c_args : gstreamer_vaapi_args, + include_directories: [configinc, libsinc], + dependencies : [ gst_dep, + gstvideo_dep, + libva_dep, + x11_dep, + gtk_dep, + libva_x11_dep ], + install: false) +endif From 63ea81a98370c4f96e29ac7a523457418d9034c1 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Tue, 18 Dec 2018 10:44:21 +0800 Subject: [PATCH 3185/3781] vaapipostproc: fix csc fail when only change width or height. --- gst/vaapi/gstvaapipostproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 4577454b5d..a2e75e8487 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1068,7 +1068,7 @@ gst_vaapipostproc_update_src_caps (GstVaapiPostproc * postproc, GstCaps * caps, if (GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) != GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info) - && GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) != + || GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) != GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info)) postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SIZE; From 7663fa263c5c0bd3fd26887bc5dbd3e59a8c5ead Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 24 Dec 2018 14:08:42 +0800 Subject: [PATCH 3186/3781] plugins: Add more check for allowed raw caps. The gst_vaapi_plugin_base_get_allowed_raw_caps is used for both sink pad and src pad, which cause some bugs. For sink pad, we need to verify vaPutImage() while for the src pad we need to verify vaGetImage(). For vaapidecoderXXX kind of plugins, the case is more complex. We need to verify whether the decoded result(in some surface, NV12 format most of the time) can be vaGetImage to some raw image format. Add more check to fix all these problems. https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/123 Signed-off-by: He Junyan --- gst/vaapi/gstvaapidecode.c | 5 +- gst/vaapi/gstvaapipluginbase.c | 87 ++++++++++++++++++++++++++-------- gst/vaapi/gstvaapipluginbase.h | 7 ++- gst/vaapi/gstvaapipostproc.c | 2 +- gst/vaapi/gstvaapisink.c | 5 +- 5 files changed, 80 insertions(+), 26 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 79be36660c..b6d917aa7f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -238,8 +238,9 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) out_caps = gst_caps_make_writable (out_caps); gst_caps_append (out_caps, gst_caps_from_string (GST_VAAPI_MAKE_DMABUF_CAPS)); - raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps - (GST_VAAPI_PLUGIN_BASE (decode)); + raw_caps = gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps + (GST_VAAPI_PLUGIN_BASE (decode), + GST_VIDEO_INFO_FORMAT (&decode->decoded_info)); if (!raw_caps) { gst_caps_unref (out_caps); GST_WARNING_OBJECT (decode, "failed to create raw sink caps"); diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 6192fefdfa..c98fe05cd5 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1254,43 +1254,70 @@ no_valid_gl_display: } static GArray * -extract_allowed_surface_formats (GstVaapiDisplay * display, GArray * formats) +extract_allowed_surface_formats (GstVaapiDisplay * display, + GArray * img_formats, GstVideoFormat specified_format, + GstPadDirection direction) { guint i; GArray *out_formats; + GstVaapiSurface *surface = NULL; + + g_assert (direction == GST_PAD_SRC || direction == GST_PAD_SINK); out_formats = - g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), formats->len); + g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), + img_formats->len); if (!out_formats) return NULL; - for (i = 0; i < formats->len; i++) { - const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); - GstVaapiSurface *surface; + for (i = 0; i < img_formats->len; i++) { + const GstVideoFormat img_format = + g_array_index (img_formats, GstVideoFormat, i); GstVaapiImage *image; GstVideoInfo vi; + GstVideoFormat surface_format; + gboolean res; - if (format == GST_VIDEO_FORMAT_UNKNOWN) + if (img_format == GST_VIDEO_FORMAT_UNKNOWN) continue; - gst_video_info_set_format (&vi, format, 64, 64); - surface = gst_vaapi_surface_new_full (display, &vi, 0); - if (!surface) - continue; + surface_format = + (specified_format == GST_VIDEO_FORMAT_UNKNOWN) ? + img_format : specified_format; + if (!surface) { + gst_video_info_set_format (&vi, surface_format, 64, 64); + surface = gst_vaapi_surface_new_full (display, &vi, 0); + if (!surface) + continue; + } - image = gst_vaapi_image_new (display, format, 64, 64); + image = gst_vaapi_image_new (display, img_format, 64, 64); if (!image) { - gst_vaapi_object_unref (surface); + /* Just reuse the surface if the format is specified */ + if (specified_format == GST_VIDEO_FORMAT_UNKNOWN) + gst_vaapi_object_replace (&surface, NULL); + continue; } - if (gst_vaapi_surface_put_image (surface, image)) - g_array_append_val (out_formats, format); + res = FALSE; + if (direction == GST_PAD_SRC) { + res = gst_vaapi_surface_get_image (surface, image); + } else { + res = gst_vaapi_surface_put_image (surface, image); + } + if (res) + g_array_append_val (out_formats, img_format); gst_vaapi_object_unref (image); - gst_vaapi_object_unref (surface); + /* Just reuse the surface if the format is specified */ + if (specified_format == GST_VIDEO_FORMAT_UNKNOWN) + gst_vaapi_object_replace (&surface, NULL); } + if (surface) + gst_vaapi_object_unref (surface); + if (out_formats->len == 0) { g_array_unref (out_formats); return NULL; @@ -1299,7 +1326,8 @@ extract_allowed_surface_formats (GstVaapiDisplay * display, GArray * formats) } static gboolean -ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) +ensure_allowed_raw_caps (GstVaapiPluginBase * plugin, GstVideoFormat format, + GstPadDirection direction) { GArray *formats, *out_formats; GstVaapiDisplay *display; @@ -1314,7 +1342,8 @@ ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) formats = gst_vaapi_display_get_image_formats (display); if (!formats) goto bail; - out_formats = extract_allowed_surface_formats (display, formats); + out_formats = + extract_allowed_surface_formats (display, formats, format, direction); if (!out_formats) goto bail; out_caps = gst_vaapi_video_format_new_template_caps_from_list (out_formats); @@ -1336,7 +1365,7 @@ bail: } /** - * gst_vaapi_plugin_base_get_allowed_raw_caps: + * gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps: * @plugin: a #GstVaapiPluginBase * * Returns the raw #GstCaps allowed by the element. @@ -1344,9 +1373,27 @@ bail: * Returns: the allowed raw #GstCaps or %NULL **/ GstCaps * -gst_vaapi_plugin_base_get_allowed_raw_caps (GstVaapiPluginBase * plugin) +gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps (GstVaapiPluginBase * plugin) { - if (!ensure_allowed_raw_caps (plugin)) + if (!ensure_allowed_raw_caps (plugin, GST_VIDEO_FORMAT_UNKNOWN, GST_PAD_SINK)) + return NULL; + return plugin->allowed_raw_caps; +} + +/** + * gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps: + * @plugin: a #GstVaapiPluginBase + * @format: a #GstVideoFormat, the format we need to check + * + * Returns the raw #GstCaps allowed by the element. + * + * Returns: the allowed raw #GstCaps or %NULL + **/ +GstCaps * +gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps (GstVaapiPluginBase * + plugin, GstVideoFormat format) +{ + if (!ensure_allowed_raw_caps (plugin, format, GST_PAD_SRC)) return NULL; return plugin->allowed_raw_caps; } diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index c0d07496aa..9faa063952 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -251,7 +251,12 @@ gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin); G_GNUC_INTERNAL GstCaps * -gst_vaapi_plugin_base_get_allowed_raw_caps (GstVaapiPluginBase * plugin); +gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps (GstVaapiPluginBase * plugin); + +G_GNUC_INTERNAL +GstCaps * +gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps ( + GstVaapiPluginBase * plugin, GstVideoFormat format); G_GNUC_INTERNAL void diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index a2e75e8487..24d93f69e2 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1094,7 +1094,7 @@ ensure_allowed_sinkpad_caps (GstVaapiPostproc * postproc) return FALSE; } - raw_caps = gst_vaapi_plugin_base_get_allowed_raw_caps + raw_caps = gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps (GST_VAAPI_PLUGIN_BASE (postproc)); if (!raw_caps) { gst_caps_unref (out_caps); diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 9333f43824..c19658332e 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1215,7 +1215,7 @@ gst_vaapisink_start (GstBaseSink * base_sink) /* Ensures possible raw caps earlier to avoid race conditions at * get_caps() */ - if (!gst_vaapi_plugin_base_get_allowed_raw_caps (plugin)) + if (!gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps (plugin)) return FALSE; return TRUE; @@ -1251,7 +1251,8 @@ gst_vaapisink_get_caps_impl (GstBaseSink * base_sink) out_caps = gst_caps_from_string (surface_caps_str); raw_caps = - gst_vaapi_plugin_base_get_allowed_raw_caps (GST_VAAPI_PLUGIN_BASE (sink)); + gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps (GST_VAAPI_PLUGIN_BASE + (sink)); if (!raw_caps) return out_caps; From 7b782be5ddc0aa2ae26674fe16059e914e20b840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 3 Dec 2018 22:05:29 +0100 Subject: [PATCH 3187/3781] libs: filter: use its own debug category --- gst-libs/gst/vaapi/gstvaapifilter.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 62f45c1fea..304272f806 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -30,9 +30,6 @@ #include "gstvaapisurface_priv.h" #include "gstvaapiutils_core.h" -#define DEBUG 1 -#include "gstvaapidebug.h" - #define GST_VAAPI_FILTER_CAST(obj) \ ((GstVaapiFilter *)(obj)) @@ -80,7 +77,16 @@ struct _GstVaapiFilterClass GstObjectClass parent_class; }; -G_DEFINE_TYPE (GstVaapiFilter, gst_vaapi_filter, GST_TYPE_OBJECT); +/* Debug category for VaapiFilter */ +GST_DEBUG_CATEGORY (gst_debug_vaapi_filter); +#define GST_CAT_DEFAULT gst_debug_vaapi_filter + +#define _do_init \ + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_filter, "vaapifilter", 0, \ + "VA-API Filter"); + +G_DEFINE_TYPE_WITH_CODE (GstVaapiFilter, gst_vaapi_filter, GST_TYPE_OBJECT, + _do_init); /* ------------------------------------------------------------------------- */ /* --- VPP Types --- */ From 6c364cb9a7580442054ec6b9f4f1b2e03274a93d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 22 Dec 2018 18:02:38 +0100 Subject: [PATCH 3188/3781] libs: window: refactor as gobject This is another step in the gobjectification of the internal library of gstreamer-vaapi. Now it is the turn of GstVaapiWindow and its derivates. The idea is to minimize the changeset keeping the same design as much as possible. GstVaapiWindow is defined as an abstract class with two properties: the GstVaapiDisplay and the native ID. Thus, many of the GstVaapiObject macros were copied as GstVaapiWindow macros. The function gst_vaapi_window_new_internal() is kept as a decorator of for calling gst_vaapi_window_create() and the possibility of failure. The descendant classes, such as glx, still use the private structures, but through the gobject mechanism. --- gst-libs/gst/vaapi/gstvaapiwindow.c | 163 +++++++++++++---- gst-libs/gst/vaapi/gstvaapiwindow.h | 15 +- gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 17 +- gst-libs/gst/vaapi/gstvaapiwindow_drm.h | 13 +- gst-libs/gst/vaapi/gstvaapiwindow_egl.c | 170 +++++++++-------- gst-libs/gst/vaapi/gstvaapiwindow_egl.h | 15 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 128 +++++++------ gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 14 +- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 91 ++++----- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 88 ++++----- gst-libs/gst/vaapi/gstvaapiwindow_wayland.h | 14 ++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 183 +++++++++---------- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 11 +- gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 14 +- 14 files changed, 529 insertions(+), 407 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index db9e1883e4..61e679ea06 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -36,6 +36,17 @@ #define DEBUG 1 #include "gstvaapidebug.h" + +G_DEFINE_ABSTRACT_TYPE (GstVaapiWindow, gst_vaapi_window, GST_TYPE_OBJECT); + +enum +{ + PROP_DISPLAY = 1, + PROP_NATIVE_ID, + N_PROPERTIES +}; +static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; + static void gst_vaapi_window_ensure_size (GstVaapiWindow * window) { @@ -55,7 +66,7 @@ gst_vaapi_window_ensure_size (GstVaapiWindow * window) static gboolean ensure_filter (GstVaapiWindow * window) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); + GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window); /* Ensure VPP pipeline is built */ if (window->filter) @@ -87,7 +98,7 @@ error_unsupported_format: static gboolean ensure_filter_surface_pool (GstVaapiWindow * window) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); + GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window); if (window->surface_pool) goto ensure_filter; @@ -109,7 +120,7 @@ ensure_filter: static gboolean gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height) { - gst_vaapi_display_get_size (GST_VAAPI_OBJECT_DISPLAY (window), + gst_vaapi_display_get_size (GST_VAAPI_WINDOW_DISPLAY (window), &window->display_width, &window->display_height); if (!GST_VAAPI_WINDOW_GET_CLASS (window)->create (window, &width, &height)) @@ -124,24 +135,101 @@ gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height) } static void -gst_vaapi_window_finalize (GstVaapiWindow * window) +gst_vaapi_window_finalize (GObject * object) { + GstVaapiWindow *const window = GST_VAAPI_WINDOW (object); + gst_vaapi_video_pool_replace (&window->surface_pool, NULL); gst_vaapi_filter_replace (&window->filter, NULL); + gst_vaapi_display_replace (&window->display, NULL); + + G_OBJECT_CLASS (gst_vaapi_window_parent_class)->finalize (object); } -void +static void +gst_vaapi_window_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiWindow *const window = GST_VAAPI_WINDOW (object); + + switch (property_id) { + case PROP_DISPLAY: + g_assert (window->display == NULL); + window->display = g_value_dup_object (value); + g_assert (window->display != NULL); + window->has_vpp = GST_VAAPI_DISPLAY_HAS_VPP (window->display); + break; + case PROP_NATIVE_ID:{ + gulong id = g_value_get_ulong (value); + window->use_foreign_window = (id != GST_VAAPI_ID_INVALID); + GST_VAAPI_WINDOW_ID (window) = window->use_foreign_window ? id : 0; + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gst_vaapi_window_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiWindow *const window = GST_VAAPI_WINDOW (object); + + switch (property_id) { + case PROP_DISPLAY: + g_value_set_object (value, window->display); + break; + case PROP_NATIVE_ID: + g_value_set_ulong (value, window->native_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void gst_vaapi_window_class_init (GstVaapiWindowClass * klass) { - GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); - object_class->finalize = (GstVaapiObjectFinalizeFunc) - gst_vaapi_window_finalize; + object_class->set_property = gst_vaapi_window_set_property; + object_class->get_property = gst_vaapi_window_get_property; + object_class->finalize = gst_vaapi_window_finalize; + + /** + * GstVaapiWindow:display: + * + * #GstVaapiDisplay to be used. + */ + g_properties[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); + + /** + * GstVaapiWindow:native-id: + * + * Native window ID: either XDisplay, EGLDisplay, or drm-fd. + */ + g_properties[PROP_NATIVE_ID] = + g_param_spec_ulong ("native-id", "Native window id", + "Native window ID", 0, G_MAXULONG, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME); + + g_object_class_install_properties (object_class, N_PROPERTIES, g_properties); +} + +static void +gst_vaapi_window_init (GstVaapiWindow * window) +{ } GstVaapiWindow * -gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, - GstVaapiDisplay * display, GstVaapiID id, guint width, guint height) +gst_vaapi_window_new_internal (GType type, GstVaapiDisplay * display, + GstVaapiID id, guint width, guint height) { GstVaapiWindow *window; @@ -153,18 +241,14 @@ gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, g_return_val_if_fail (height > 0, NULL); } - window = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (window_class), - display); - if (!window) - return NULL; + window = g_object_new (type, "display", display, "native-id", id, NULL); - window->use_foreign_window = id != GST_VAAPI_ID_INVALID; - GST_VAAPI_OBJECT_ID (window) = window->use_foreign_window ? id : 0; - window->has_vpp = - GST_VAAPI_DISPLAY_HAS_VPP (GST_VAAPI_OBJECT_DISPLAY (window)); + GST_DEBUG_OBJECT (window, "new window with id = 0x%08lx and size %ux%u", id, + width, height); if (!gst_vaapi_window_create (window, width, height)) goto error; + return window; /* ERRORS */ @@ -234,7 +318,7 @@ gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height) { GstVaapiDisplayClass *dpy_class; - g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY (display), NULL); dpy_class = GST_VAAPI_DISPLAY_GET_CLASS (display); if (G_UNLIKELY (!dpy_class->create_window)) @@ -254,7 +338,7 @@ gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height) GstVaapiWindow * gst_vaapi_window_ref (GstVaapiWindow * window) { - return (GstVaapiWindow *) gst_vaapi_object_ref (GST_VAAPI_OBJECT (window)); + return (GstVaapiWindow *) gst_object_ref (window); } /** @@ -267,7 +351,7 @@ gst_vaapi_window_ref (GstVaapiWindow * window) void gst_vaapi_window_unref (GstVaapiWindow * window) { - gst_vaapi_object_unref (GST_VAAPI_OBJECT (window)); + gst_object_unref (window); } /** @@ -283,8 +367,7 @@ void gst_vaapi_window_replace (GstVaapiWindow ** old_window_ptr, GstVaapiWindow * new_window) { - gst_vaapi_object_replace ((GstVaapiObject **) (old_window_ptr), - GST_VAAPI_OBJECT (new_window)); + gst_object_replace ((GstObject **) old_window_ptr, GST_OBJECT (new_window)); } /** @@ -298,9 +381,9 @@ gst_vaapi_window_replace (GstVaapiWindow ** old_window_ptr, GstVaapiDisplay * gst_vaapi_window_get_display (GstVaapiWindow * window) { - g_return_val_if_fail (window != NULL, NULL); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), NULL); - return GST_VAAPI_OBJECT_DISPLAY (window); + return GST_VAAPI_WINDOW_DISPLAY (window); } /** @@ -313,7 +396,7 @@ gst_vaapi_window_get_display (GstVaapiWindow * window) void gst_vaapi_window_show (GstVaapiWindow * window) { - g_return_if_fail (window != NULL); + g_return_if_fail (GST_VAAPI_IS_WINDOW (window)); GST_VAAPI_WINDOW_GET_CLASS (window)->show (window); window->check_geometry = TRUE; @@ -329,7 +412,7 @@ gst_vaapi_window_show (GstVaapiWindow * window) void gst_vaapi_window_hide (GstVaapiWindow * window) { - g_return_if_fail (window != NULL); + g_return_if_fail (GST_VAAPI_IS_WINDOW (window)); GST_VAAPI_WINDOW_GET_CLASS (window)->hide (window); } @@ -345,7 +428,7 @@ gst_vaapi_window_hide (GstVaapiWindow * window) gboolean gst_vaapi_window_get_fullscreen (GstVaapiWindow * window) { - g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), FALSE); gst_vaapi_window_ensure_size (window); @@ -364,7 +447,7 @@ gst_vaapi_window_set_fullscreen (GstVaapiWindow * window, gboolean fullscreen) { const GstVaapiWindowClass *klass; - g_return_if_fail (window != NULL); + g_return_if_fail (GST_VAAPI_IS_WINDOW (window)); klass = GST_VAAPI_WINDOW_GET_CLASS (window); @@ -386,7 +469,7 @@ gst_vaapi_window_set_fullscreen (GstVaapiWindow * window, gboolean fullscreen) guint gst_vaapi_window_get_width (GstVaapiWindow * window) { - g_return_val_if_fail (window != NULL, 0); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), 0); gst_vaapi_window_ensure_size (window); @@ -404,7 +487,7 @@ gst_vaapi_window_get_width (GstVaapiWindow * window) guint gst_vaapi_window_get_height (GstVaapiWindow * window) { - g_return_val_if_fail (window != NULL, 0); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), 0); gst_vaapi_window_ensure_size (window); @@ -423,7 +506,7 @@ void gst_vaapi_window_get_size (GstVaapiWindow * window, guint * width_ptr, guint * height_ptr) { - g_return_if_fail (window != NULL); + g_return_if_fail (GST_VAAPI_IS_WINDOW (window)); gst_vaapi_window_ensure_size (window); @@ -444,7 +527,7 @@ gst_vaapi_window_get_size (GstVaapiWindow * window, guint * width_ptr, void gst_vaapi_window_set_width (GstVaapiWindow * window, guint width) { - g_return_if_fail (window != NULL); + g_return_if_fail (GST_VAAPI_IS_WINDOW (window)); gst_vaapi_window_set_size (window, width, window->height); } @@ -459,7 +542,7 @@ gst_vaapi_window_set_width (GstVaapiWindow * window, guint width) void gst_vaapi_window_set_height (GstVaapiWindow * window, guint height) { - g_return_if_fail (window != NULL); + g_return_if_fail (GST_VAAPI_IS_WINDOW (window)); gst_vaapi_window_set_size (window, window->width, height); } @@ -475,7 +558,7 @@ gst_vaapi_window_set_height (GstVaapiWindow * window, guint height) void gst_vaapi_window_set_size (GstVaapiWindow * window, guint width, guint height) { - g_return_if_fail (window != NULL); + g_return_if_fail (GST_VAAPI_IS_WINDOW (window)); if (width == window->width && height == window->height) return; @@ -537,7 +620,7 @@ gst_vaapi_window_put_surface (GstVaapiWindow * window, const GstVaapiWindowClass *klass; GstVaapiRectangle src_rect_default, dst_rect_default; - g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), FALSE); g_return_val_if_fail (surface != NULL, FALSE); klass = GST_VAAPI_WINDOW_GET_CLASS (window); @@ -592,7 +675,7 @@ gst_vaapi_window_put_pixmap (GstVaapiWindow * window, const GstVaapiWindowClass *klass; GstVaapiRectangle src_rect_default, dst_rect_default; - g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), FALSE); g_return_val_if_fail (pixmap != NULL, FALSE); klass = GST_VAAPI_WINDOW_GET_CLASS (window); @@ -621,7 +704,7 @@ gst_vaapi_window_put_pixmap (GstVaapiWindow * window, void gst_vaapi_window_reconfigure (GstVaapiWindow * window) { - g_return_if_fail (window != NULL); + g_return_if_fail (GST_VAAPI_IS_WINDOW (window)); window->check_geometry = TRUE; gst_vaapi_window_ensure_size (window); @@ -638,7 +721,7 @@ gst_vaapi_window_unblock (GstVaapiWindow * window) { const GstVaapiWindowClass *klass; - g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), FALSE); klass = GST_VAAPI_WINDOW_GET_CLASS (window); @@ -659,7 +742,7 @@ gst_vaapi_window_unblock_cancel (GstVaapiWindow * window) { const GstVaapiWindowClass *klass; - g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), FALSE); klass = GST_VAAPI_WINDOW_GET_CLASS (window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index c2d895441f..040db6c223 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -25,21 +25,26 @@ #ifndef GST_VAAPI_WINDOW_H #define GST_VAAPI_WINDOW_H -#include +#include #include -#include #include #include #include G_BEGIN_DECLS +#define GST_TYPE_VAAPI_WINDOW (gst_vaapi_window_get_type ()) #define GST_VAAPI_WINDOW(obj) \ - ((GstVaapiWindow *)(obj)) + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW, GstVaapiWindow)) +#define GST_VAAPI_IS_WINDOW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW)) typedef struct _GstVaapiWindow GstVaapiWindow; typedef struct _GstVaapiWindowClass GstVaapiWindowClass; +GType +gst_vaapi_window_get_type (void) G_GNUC_CONST; + GstVaapiWindow * gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height); @@ -105,6 +110,10 @@ gst_vaapi_window_unblock (GstVaapiWindow * window); gboolean gst_vaapi_window_unblock_cancel (GstVaapiWindow * window); +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindow, gst_object_unref) +#endif + G_END_DECLS #endif /* GST_VAAPI_WINDOW_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c index fdbdd2d8c8..78e816340b 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -57,6 +57,8 @@ struct _GstVaapiWindowDRMClass GstVaapiWindowClass parent_instance; }; +G_DEFINE_TYPE (GstVaapiWindowDRM, gst_vaapi_window_drm, GST_TYPE_VAAPI_WINDOW); + static gboolean gst_vaapi_window_drm_show (GstVaapiWindow * window) { @@ -91,7 +93,7 @@ gst_vaapi_window_drm_render (GstVaapiWindow * window, return TRUE; } -void +static void gst_vaapi_window_drm_class_init (GstVaapiWindowDRMClass * klass) { GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); @@ -104,13 +106,10 @@ gst_vaapi_window_drm_class_init (GstVaapiWindowDRMClass * klass) } static void -gst_vaapi_window_drm_finalize (GstVaapiWindowDRM * window) +gst_vaapi_window_drm_init (GstVaapiWindowDRM * window) { } -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowDRM, - gst_vaapi_window_drm, gst_vaapi_window_drm_class_init (&g_class)); - /** * gst_vaapi_window_drm_new: * @display: a #GstVaapiDisplay @@ -132,12 +131,8 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowDRM, GstVaapiWindow * gst_vaapi_window_drm_new (GstVaapiDisplay * display, guint width, guint height) { - GST_DEBUG ("new window, size %ux%u", width, height); - g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_DRM (display), NULL); - return - gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS - (gst_vaapi_window_drm_class ()), display, GST_VAAPI_ID_INVALID, width, - height); + return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_DRM, display, + GST_VAAPI_ID_INVALID, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h index 60e942dda0..7fe0c4ede4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h @@ -23,19 +23,30 @@ #ifndef GST_VAAPI_WINDOW_DRM_H #define GST_VAAPI_WINDOW_DRM_H +#include #include #include G_BEGIN_DECLS +#define GST_TYPE_VAAPI_WINDOW_DRM (gst_vaapi_window_drm_get_type ()) #define GST_VAAPI_WINDOW_DRM(obj) \ - ((GstVaapiWindowDRM *)(obj)) + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW_DRM, GstVaapiWindowDRM)) +#define GST_VAAPI_IS_WINDOW_DRM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW_DRM)) typedef struct _GstVaapiWindowDRM GstVaapiWindowDRM; +GType +gst_vaapi_window_drm_get_type (void) G_GNUC_CONST; + GstVaapiWindow * gst_vaapi_window_drm_new (GstVaapiDisplay * display, guint width, guint height); +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowDRM, gst_object_unref) +#endif + G_END_DECLS #endif /* GST_VAAPI_WINDOW_DRM_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c index 8cabd03e4d..56b4855e1f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c @@ -32,16 +32,16 @@ #include "gstvaapitexture_priv.h" #include "gstvaapidisplay_egl_priv.h" -#define GST_VAAPI_WINDOW_EGL(obj) \ - ((GstVaapiWindowEGL *)(obj)) -#define GST_VAAPI_WINDOW_EGL_CLASS(klass) \ - ((GstVaapiWindowEGLClass *)(klass)) +#define GST_VAAPI_WINDOW_EGL_CAST(obj) \ + ((GstVaapiWindowEGL *)(obj)) + +#define GST_VAAPI_WINDOW_EGL_GET_PROXY(obj) \ + (GST_VAAPI_WINDOW_EGL_CAST(obj)->window) #define GST_VAAPI_WINDOW_EGL_GET_CLASS(obj) \ - GST_VAAPI_WINDOW_EGL_CLASS (GST_VAAPI_WINDOW_GET_CLASS (obj)) + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW_EGL, GstVaapiWindowEGLClass)) -typedef struct _GstVaapiWindowEGL GstVaapiWindowEGL; typedef struct _GstVaapiWindowEGLClass GstVaapiWindowEGLClass; enum @@ -123,6 +123,8 @@ static const gchar *frag_shader_text_rgba = "} \n"; /* *IDENT-ON* */ +G_DEFINE_TYPE (GstVaapiWindowEGL, gst_vaapi_window_egl, GST_TYPE_VAAPI_WINDOW); + static gboolean ensure_texture (GstVaapiWindowEGL * window, guint width, guint height) { @@ -133,7 +135,7 @@ ensure_texture (GstVaapiWindowEGL * window, guint width, guint height) GST_VAAPI_TEXTURE_HEIGHT (window->texture) == height) return TRUE; - texture = gst_vaapi_texture_egl_new (GST_VAAPI_OBJECT_DISPLAY (window), + texture = gst_vaapi_texture_egl_new (GST_VAAPI_WINDOW_DISPLAY (window), GL_TEXTURE_2D, GL_RGBA, width, height); gst_vaapi_texture_replace (&window->texture, texture); gst_vaapi_texture_replace (&texture, NULL); @@ -187,7 +189,8 @@ do_create_objects_unlocked (GstVaapiWindowEGL * window, guint width, EglVTable *egl_vtable; egl_window = egl_window_new (egl_context, - GSIZE_TO_POINTER (GST_VAAPI_OBJECT_ID (window->window))); + GSIZE_TO_POINTER (GST_VAAPI_WINDOW_ID (GST_VAAPI_WINDOW_EGL_GET_PROXY + (window)))); if (!egl_window) return FALSE; window->egl_window = egl_window; @@ -207,36 +210,37 @@ do_create_objects (CreateObjectsArgs * args) args->success = FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); if (egl_context_set_current (args->egl_context, TRUE, &old_cs)) { args->success = do_create_objects_unlocked (window, args->width, args->height, args->egl_context); egl_context_set_current (args->egl_context, FALSE, &old_cs); } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } static gboolean -gst_vaapi_window_egl_create (GstVaapiWindowEGL * window, - guint * width, guint * height) +gst_vaapi_window_egl_create (GstVaapiWindow * window, guint * width, + guint * height) { GstVaapiDisplayEGL *const display = - GST_VAAPI_DISPLAY_EGL (GST_VAAPI_OBJECT_DISPLAY (window)); + GST_VAAPI_DISPLAY_EGL (GST_VAAPI_WINDOW_DISPLAY (window)); const GstVaapiDisplayClass *const native_dpy_class = GST_VAAPI_DISPLAY_GET_CLASS (display->display); CreateObjectsArgs args; g_return_val_if_fail (native_dpy_class != NULL, FALSE); - window->window = + GST_VAAPI_WINDOW_EGL_GET_PROXY (window) = native_dpy_class->create_window (GST_VAAPI_DISPLAY (display->display), GST_VAAPI_ID_INVALID, *width, *height); - if (!window->window) + if (!GST_VAAPI_WINDOW_EGL_GET_PROXY (window)) return FALSE; - gst_vaapi_window_get_size (window->window, width, height); + gst_vaapi_window_get_size (GST_VAAPI_WINDOW_EGL_GET_PROXY (window), width, + height); - args.window = window; + args.window = GST_VAAPI_WINDOW_EGL_CAST (window); args.width = *width; args.height = *height; args.egl_context = GST_VAAPI_DISPLAY_EGL_CONTEXT (display); @@ -256,70 +260,76 @@ static void do_destroy_objects (GstVaapiWindowEGL * window) { EglContext *const egl_context = - GST_VAAPI_DISPLAY_EGL_CONTEXT (GST_VAAPI_OBJECT_DISPLAY (window)); + GST_VAAPI_DISPLAY_EGL_CONTEXT (GST_VAAPI_WINDOW_DISPLAY (window)); EglContextState old_cs; if (!window->egl_window) return; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); if (egl_context_set_current (egl_context, TRUE, &old_cs)) { do_destroy_objects_unlocked (window); egl_context_set_current (egl_context, FALSE, &old_cs); } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } static void -gst_vaapi_window_egl_destroy (GstVaapiWindowEGL * window) +gst_vaapi_window_egl_finalize (GObject * object) { + GstVaapiWindowEGL *const window = GST_VAAPI_WINDOW_EGL (object); + egl_context_run (window->egl_window->context, (EglContextRunFunc) do_destroy_objects, window); gst_vaapi_window_replace (&window->window, NULL); gst_vaapi_texture_replace (&window->texture, NULL); + + G_OBJECT_CLASS (gst_vaapi_window_egl_parent_class)->finalize (object); } static gboolean -gst_vaapi_window_egl_show (GstVaapiWindowEGL * window) +gst_vaapi_window_egl_show (GstVaapiWindow * window) { const GstVaapiWindowClass *const klass = - GST_VAAPI_WINDOW_GET_CLASS (window->window); + GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window)); g_return_val_if_fail (klass->show, FALSE); - return klass->show (window->window); + return klass->show (GST_VAAPI_WINDOW_EGL_GET_PROXY (window)); } static gboolean -gst_vaapi_window_egl_hide (GstVaapiWindowEGL * window) +gst_vaapi_window_egl_hide (GstVaapiWindow * window) { const GstVaapiWindowClass *const klass = - GST_VAAPI_WINDOW_GET_CLASS (window->window); + GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window)); g_return_val_if_fail (klass->hide, FALSE); - return klass->hide (window->window); + return klass->hide (GST_VAAPI_WINDOW_EGL_GET_PROXY (window)); } static gboolean -gst_vaapi_window_egl_get_geometry (GstVaapiWindowEGL * window, - gint * x_ptr, gint * y_ptr, guint * width_ptr, guint * height_ptr) +gst_vaapi_window_egl_get_geometry (GstVaapiWindow * window, gint * x_ptr, + gint * y_ptr, guint * width_ptr, guint * height_ptr) { const GstVaapiWindowClass *const klass = - GST_VAAPI_WINDOW_GET_CLASS (window->window); + GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window)); - return klass->get_geometry ? klass->get_geometry (window->window, - x_ptr, y_ptr, width_ptr, height_ptr) : FALSE; + return klass->get_geometry ? + klass->get_geometry (GST_VAAPI_WINDOW_EGL_GET_PROXY (window), x_ptr, + y_ptr, width_ptr, height_ptr) : FALSE; } static gboolean -gst_vaapi_window_egl_set_fullscreen (GstVaapiWindowEGL * window, +gst_vaapi_window_egl_set_fullscreen (GstVaapiWindow * window, gboolean fullscreen) { const GstVaapiWindowClass *const klass = - GST_VAAPI_WINDOW_GET_CLASS (window->window); + GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window)); - return klass->set_fullscreen ? klass->set_fullscreen (window->window, + return klass->set_fullscreen ? + klass->set_fullscreen (GST_VAAPI_WINDOW_EGL_GET_PROXY (window), fullscreen) : FALSE; } @@ -341,29 +351,29 @@ do_resize_window (ResizeWindowArgs * args) GstVaapiWindowEGL *const window = args->window; EglContextState old_cs; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); if (egl_context_set_current (window->egl_window->context, TRUE, &old_cs)) { args->success = do_resize_window_unlocked (window, args->width, args->height); egl_context_set_current (window->egl_window->context, FALSE, &old_cs); } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } static gboolean -gst_vaapi_window_egl_resize (GstVaapiWindowEGL * window, guint width, - guint height) +gst_vaapi_window_egl_resize (GstVaapiWindow * window, guint width, guint height) { + GstVaapiWindowEGL *const win = GST_VAAPI_WINDOW_EGL_CAST (window); const GstVaapiWindowClass *const klass = - GST_VAAPI_WINDOW_GET_CLASS (window->window); - ResizeWindowArgs args = { window, width, height }; + GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window)); + ResizeWindowArgs args = { win, width, height }; g_return_val_if_fail (klass->resize, FALSE); - if (!klass->resize (window->window, width, height)) + if (!klass->resize (GST_VAAPI_WINDOW_EGL_GET_PROXY (window), width, height)) return FALSE; - return egl_context_run (window->egl_window->context, + return egl_context_run (win->egl_window->context, (EglContextRunFunc) do_resize_window, &args) && args.success; } @@ -472,71 +482,63 @@ do_upload_surface (UploadSurfaceArgs * args) args->success = FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); if (egl_context_set_current (window->egl_window->context, TRUE, &old_cs)) { args->success = do_upload_surface_unlocked (window, args->surface, args->src_rect, args->dst_rect, args->flags); egl_context_set_current (window->egl_window->context, FALSE, &old_cs); } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } static gboolean -gst_vaapi_window_egl_render (GstVaapiWindowEGL * window, - GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, - const GstVaapiRectangle * dst_rect, guint flags) +gst_vaapi_window_egl_render (GstVaapiWindow * window, GstVaapiSurface * surface, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect, + guint flags) { - UploadSurfaceArgs args = { window, surface, src_rect, dst_rect, flags }; + GstVaapiWindowEGL *const win = GST_VAAPI_WINDOW_EGL_CAST (window); + UploadSurfaceArgs args = { win, surface, src_rect, dst_rect, flags }; - return egl_context_run (window->egl_window->context, + return egl_context_run (win->egl_window->context, (EglContextRunFunc) do_upload_surface, &args) && args.success; } static gboolean -gst_vaapi_window_egl_render_pixmap (GstVaapiWindowEGL * window, - GstVaapiPixmap * pixmap, - const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) +gst_vaapi_window_egl_render_pixmap (GstVaapiWindow * window, + GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect, + const GstVaapiRectangle * dst_rect) { const GstVaapiWindowClass *const klass = - GST_VAAPI_WINDOW_GET_CLASS (window->window); + GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window)); if (!klass->render_pixmap) return FALSE; - return klass->render_pixmap (window->window, pixmap, src_rect, dst_rect); + return klass->render_pixmap (GST_VAAPI_WINDOW_EGL_GET_PROXY (window), pixmap, + src_rect, dst_rect); } -void +static void gst_vaapi_window_egl_class_init (GstVaapiWindowEGLClass * klass) { - GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); - object_class->finalize = (GstVaapiObjectFinalizeFunc) - gst_vaapi_window_egl_destroy; + object_class->finalize = gst_vaapi_window_egl_finalize; - window_class->create = (GstVaapiWindowCreateFunc) - gst_vaapi_window_egl_create; - window_class->show = (GstVaapiWindowShowFunc) - gst_vaapi_window_egl_show; - window_class->hide = (GstVaapiWindowHideFunc) - gst_vaapi_window_egl_hide; - window_class->get_geometry = (GstVaapiWindowGetGeometryFunc) - gst_vaapi_window_egl_get_geometry; - window_class->set_fullscreen = (GstVaapiWindowSetFullscreenFunc) - gst_vaapi_window_egl_set_fullscreen; - window_class->resize = (GstVaapiWindowResizeFunc) - gst_vaapi_window_egl_resize; - window_class->render = (GstVaapiWindowRenderFunc) - gst_vaapi_window_egl_render; - window_class->render_pixmap = (GstVaapiWindowRenderPixmapFunc) - gst_vaapi_window_egl_render_pixmap; + window_class->create = gst_vaapi_window_egl_create; + window_class->show = gst_vaapi_window_egl_show; + window_class->hide = gst_vaapi_window_egl_hide; + window_class->get_geometry = gst_vaapi_window_egl_get_geometry; + window_class->set_fullscreen = gst_vaapi_window_egl_set_fullscreen; + window_class->resize = gst_vaapi_window_egl_resize; + window_class->render = gst_vaapi_window_egl_render; + window_class->render_pixmap = gst_vaapi_window_egl_render_pixmap; } -#define gst_vaapi_window_egl_finalize \ - gst_vaapi_window_egl_destroy - -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowEGL, - gst_vaapi_window_egl, gst_vaapi_window_egl_class_init (&g_class)); +static void +gst_vaapi_window_egl_init (GstVaapiWindowEGL * window) +{ +} /** * gst_vaapi_window_egl_new: @@ -553,12 +555,8 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowEGL, GstVaapiWindow * gst_vaapi_window_egl_new (GstVaapiDisplay * display, guint width, guint height) { - GST_DEBUG ("new window, size %ux%u", width, height); - g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL); - return - gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS - (gst_vaapi_window_egl_class ()), display, GST_VAAPI_ID_INVALID, width, - height); + return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_EGL, display, + GST_VAAPI_ID_INVALID, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_egl.h b/gst-libs/gst/vaapi/gstvaapiwindow_egl.h index b2ffa2de1b..820a105737 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_egl.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_egl.h @@ -23,17 +23,30 @@ #ifndef GST_VAAPI_WINDOW_EGL_H #define GST_VAAPI_WINDOW_EGL_H +#include #include #include G_BEGIN_DECLS +#define GST_TYPE_VAAPI_WINDOW_EGL (gst_vaapi_window_egl_get_type ()) #define GST_VAAPI_WINDOW_EGL(obj) \ - ((GstVaapiWindowEGL *)(obj)) + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW_EGL, GstVaapiWindowEGL)) +#define GST_VAAPI_IS_WINDOW_EGL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW_EGL)) + +typedef struct _GstVaapiWindowEGL GstVaapiWindowEGL; + +GType +gst_vaapi_window_egl_get_type (void) G_GNUC_CONST; GstVaapiWindow * gst_vaapi_window_egl_new (GstVaapiDisplay * display, guint width, guint height); +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowEGL, gst_object_unref) +#endif + G_END_DECLS #endif /* GST_VAAPI_WINDOW_EGL_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 27dbb04771..aae17ab208 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -39,14 +39,12 @@ #define DEBUG 1 #include "gstvaapidebug.h" +#define GST_VAAPI_WINDOW_GLX_CAST(obj) ((GstVaapiWindowGLX *)(obj)) #define GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window) \ - (&GST_VAAPI_WINDOW_GLX(window)->priv) - -#define GST_VAAPI_WINDOW_GLX_CLASS(klass) \ - ((GstVaapiWindowGLXClass *)(klass)) + gst_vaapi_window_glx_get_instance_private (GST_VAAPI_WINDOW_GLX_CAST (window)) #define GST_VAAPI_WINDOW_GLX_GET_CLASS(obj) \ - GST_VAAPI_WINDOW_GLX_CLASS(GST_VAAPI_OBJECT_GET_CLASS(obj)) + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW_GLX, GstVaapiWindowGLXClass)) typedef struct _GstVaapiWindowGLXPrivate GstVaapiWindowGLXPrivate; typedef struct _GstVaapiWindowGLXClass GstVaapiWindowGLXClass; @@ -66,8 +64,6 @@ struct _GstVaapiWindowGLX { /*< private > */ GstVaapiWindowX11 parent_instance; - - GstVaapiWindowGLXPrivate priv; }; /** @@ -79,11 +75,11 @@ struct _GstVaapiWindowGLXClass { /*< private > */ GstVaapiWindowX11Class parent_class; - - GstVaapiObjectFinalizeFunc parent_finalize; - GstVaapiWindowResizeFunc parent_resize; }; +G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiWindowGLX, gst_vaapi_window_glx, + GST_TYPE_VAAPI_WINDOW_X11); + /* Fill rectangle coords with capped bounds */ static inline void fill_rect (GstVaapiRectangle * dst_rect, @@ -114,12 +110,12 @@ _gst_vaapi_window_glx_destroy_context (GstVaapiWindow * window) GstVaapiWindowGLXPrivate *const priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); if (priv->gl_context) { gl_destroy_context (priv->gl_context); priv->gl_context = NULL; } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } static gboolean @@ -128,14 +124,14 @@ _gst_vaapi_window_glx_create_context (GstVaapiWindow * window, { GstVaapiWindowGLXPrivate *const priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); GLContextState parent_cs; parent_cs.display = dpy; parent_cs.window = None; parent_cs.context = foreign_context; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); priv->gl_context = gl_create_context (dpy, DefaultScreen (dpy), &parent_cs); if (!priv->gl_context) { GST_DEBUG ("could not create GLX context"); @@ -152,7 +148,7 @@ out_destroy_context: gl_destroy_context (priv->gl_context); priv->gl_context = NULL; end: - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); return priv->gl_context != NULL; } @@ -183,7 +179,7 @@ gst_vaapi_window_glx_ensure_context (GstVaapiWindow * window, if (!_gst_vaapi_window_glx_ensure_context (window, foreign_context)) return FALSE; - priv->gl_context->window = GST_VAAPI_OBJECT_ID (window); + priv->gl_context->window = GST_VAAPI_WINDOW_ID (window); if (!gl_set_current_context (priv->gl_context, &old_cs)) { GST_DEBUG ("could not make newly created GLX context current"); return FALSE; @@ -222,13 +218,13 @@ gst_vaapi_window_glx_destroy_colormap (GstVaapiWindow * window) { GstVaapiWindowGLXPrivate *const priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); if (priv->cmap) { if (!window->use_foreign_window) { - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); XFreeColormap (dpy, priv->cmap); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } priv->cmap = None; } @@ -239,7 +235,7 @@ gst_vaapi_window_glx_create_colormap (GstVaapiWindow * window) { GstVaapiWindowGLXPrivate *const priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); XWindowAttributes wattr; gboolean success = FALSE; @@ -247,20 +243,20 @@ gst_vaapi_window_glx_create_colormap (GstVaapiWindow * window) if (!window->use_foreign_window) { if (!_gst_vaapi_window_glx_ensure_context (window, NULL)) return None; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); x11_trap_errors (); /* XXX: add a GstVaapiDisplayX11:x11-screen property? */ priv->cmap = XCreateColormap (dpy, RootWindow (dpy, DefaultScreen (dpy)), priv->gl_context->visual->visual, AllocNone); success = x11_untrap_errors () == 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } else { - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); x11_trap_errors (); - XGetWindowAttributes (dpy, GST_VAAPI_OBJECT_ID (window), &wattr); + XGetWindowAttributes (dpy, GST_VAAPI_WINDOW_ID (window), &wattr); priv->cmap = wattr.colormap; success = x11_untrap_errors () == 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } if (!success) return None; @@ -279,53 +275,52 @@ gst_vaapi_window_glx_resize (GstVaapiWindow * window, guint width, guint height) { GstVaapiWindowGLXPrivate *const priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); - const GstVaapiWindowGLXClass *const klass = - GST_VAAPI_WINDOW_GLX_GET_CLASS (window); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); + const GstVaapiWindowClass *const parent_klass = + GST_VAAPI_WINDOW_CLASS (gst_vaapi_window_glx_parent_class); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); GLContextState old_cs; - if (!klass->parent_resize (window, width, height)) + if (!parent_klass->resize (window, width, height)) return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); XSync (dpy, False); /* make sure resize completed */ if (gl_set_current_context (priv->gl_context, &old_cs)) { gl_resize (width, height); gl_set_current_context (&old_cs, NULL); } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); return TRUE; } static void -gst_vaapi_window_glx_finalize (GstVaapiWindowGLX * window) +gst_vaapi_window_glx_finalize (GObject * object) { - GstVaapiWindow *const base_window = GST_VAAPI_WINDOW (window); + GstVaapiWindow *const window = GST_VAAPI_WINDOW (object); - _gst_vaapi_window_glx_destroy_context (base_window); - gst_vaapi_window_glx_destroy_colormap (base_window); + _gst_vaapi_window_glx_destroy_context (window); + gst_vaapi_window_glx_destroy_colormap (window); - GST_VAAPI_WINDOW_GLX_GET_CLASS (window)->parent_finalize (GST_VAAPI_OBJECT - (window)); + G_OBJECT_CLASS (gst_vaapi_window_glx_parent_class)->finalize (object); } static void gst_vaapi_window_glx_class_init (GstVaapiWindowGLXClass * klass) { + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); - GstVaapiWindowX11Class *const xwindow_class = - GST_VAAPI_WINDOW_X11_CLASS (klass); - gst_vaapi_window_x11_class_init (xwindow_class); - klass->parent_resize = window_class->resize; - klass->parent_finalize = GST_VAAPI_OBJECT_CLASS (klass)->finalize; + object_class->finalize = gst_vaapi_window_glx_finalize; + window_class->resize = gst_vaapi_window_glx_resize; window_class->get_visual_id = gst_vaapi_window_glx_get_visual_id; window_class->get_colormap = gst_vaapi_window_glx_get_colormap; } -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowGLX, - gst_vaapi_window_glx, gst_vaapi_window_glx_class_init (&g_class)); +static void +gst_vaapi_window_glx_init (GstVaapiWindowGLX * window) +{ +} /** * gst_vaapi_window_glx_new: @@ -346,10 +341,8 @@ gst_vaapi_window_glx_new (GstVaapiDisplay * display, guint width, guint height) g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); - window = - gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS - (gst_vaapi_window_glx_class ()), display, GST_VAAPI_ID_INVALID, width, - height); + window = gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_GLX, display, + GST_VAAPI_ID_INVALID, width, height); if (!window) return NULL; @@ -382,14 +375,11 @@ gst_vaapi_window_glx_new_with_xid (GstVaapiDisplay * display, Window xid) { GstVaapiWindow *window; - GST_DEBUG ("new window from xid 0x%08x", (guint) xid); - g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); g_return_val_if_fail (xid != None, NULL); - window = - gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS - (gst_vaapi_window_glx_class ()), display, xid, 0, 0); + window = gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_GLX, display, + xid, 0, 0); if (!window) return NULL; @@ -416,9 +406,12 @@ error: GLXContext gst_vaapi_window_glx_get_context (GstVaapiWindowGLX * window) { - g_return_val_if_fail (window != NULL, NULL); + GstVaapiWindowGLXPrivate *priv; - return GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window)->gl_context->context; + g_return_val_if_fail (GST_VAAPI_IS_WINDOW_GLX (window), NULL); + + priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); + return priv->gl_context->context; } /** @@ -436,7 +429,7 @@ gst_vaapi_window_glx_get_context (GstVaapiWindowGLX * window) gboolean gst_vaapi_window_glx_set_context (GstVaapiWindowGLX * window, GLXContext ctx) { - g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW_GLX (window), FALSE); return gst_vaapi_window_glx_ensure_context (GST_VAAPI_WINDOW (window), ctx); } @@ -455,12 +448,14 @@ gboolean gst_vaapi_window_glx_make_current (GstVaapiWindowGLX * window) { gboolean success; + GstVaapiWindowGLXPrivate *priv; - g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW_GLX (window), FALSE); - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); - success = gl_set_current_context (window->priv.gl_context, NULL); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); + priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); + success = gl_set_current_context (priv->gl_context, NULL); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); return success; } @@ -475,11 +470,14 @@ gst_vaapi_window_glx_make_current (GstVaapiWindowGLX * window) void gst_vaapi_window_glx_swap_buffers (GstVaapiWindowGLX * window) { - g_return_if_fail (window != NULL); + GstVaapiWindowGLXPrivate *priv; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); - gl_swap_buffers (window->priv.gl_context); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + g_return_if_fail (GST_VAAPI_IS_WINDOW_GLX (window)); + + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); + priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); + gl_swap_buffers (priv->gl_context); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } /** @@ -511,7 +509,7 @@ gst_vaapi_window_glx_put_texture (GstVaapiWindowGLX * window, guint tex_width, tex_height; guint win_width, win_height; - g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW_GLX (window), FALSE); g_return_val_if_fail (texture != NULL, FALSE); gst_vaapi_texture_get_size (texture, &tex_width, &tex_height); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index 5179146011..d7c4252def 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -26,17 +26,25 @@ #define GST_VAAPI_WINDOW_GLX_H #include +#include #include #include #include +#include G_BEGIN_DECLS +#define GST_TYPE_VAAPI_WINDOW_GLX (gst_vaapi_window_glx_get_type ()) #define GST_VAAPI_WINDOW_GLX(obj) \ - ((GstVaapiWindowGLX *)(obj)) + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW_GLX, GstVaapiWindowGLX)) +#define GST_VAAPI_IS_WINDOW_GLX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW_GLX)) typedef struct _GstVaapiWindowGLX GstVaapiWindowGLX; +GType +gst_vaapi_window_glx_get_type (void) G_GNUC_CONST; + GstVaapiWindow * gst_vaapi_window_glx_new (GstVaapiDisplay * display, guint width, guint height); @@ -60,6 +68,10 @@ gst_vaapi_window_glx_put_texture (GstVaapiWindowGLX * window, GstVaapiTexture * texture, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect); +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowGLX, gst_object_unref) +#endif + G_END_DECLS #endif /* GST_VAAPI_WINDOW_GLX_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index 10705857a7..cd21d00cf4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -25,39 +25,41 @@ #ifndef GST_VAAPI_WINDOW_PRIV_H #define GST_VAAPI_WINDOW_PRIV_H -#include "gstvaapiobject_priv.h" +#include "gstvaapidisplay.h" #include "gstvaapifilter.h" #include "gstvaapisurfacepool.h" G_BEGIN_DECLS +#define GST_VAAPI_WINDOW_CAST(window) \ + ((GstVaapiWindow *)(window)) + #define GST_VAAPI_WINDOW_CLASS(klass) \ - ((GstVaapiWindowClass *)(klass)) + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_WINDOW, GstVaapiWindowClass)) + +#define GST_VAAPI_IS_WINDOW_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_WINDOW)) #define GST_VAAPI_WINDOW_GET_CLASS(obj) \ - GST_VAAPI_WINDOW_CLASS(GST_VAAPI_OBJECT_GET_CLASS(obj)) + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW, GstVaapiWindowClass)) -/* GstVaapiWindowClass hooks */ -typedef gboolean (*GstVaapiWindowCreateFunc) (GstVaapiWindow * window, - guint * width, guint * height); -typedef gboolean (*GstVaapiWindowShowFunc) (GstVaapiWindow * window); -typedef gboolean (*GstVaapiWindowHideFunc) (GstVaapiWindow * window); -typedef gboolean (*GstVaapiWindowGetGeometryFunc) (GstVaapiWindow * window, - gint * px, gint * py, guint * pwidth, guint * pheight); -typedef gboolean (*GstVaapiWindowSetFullscreenFunc) (GstVaapiWindow * window, - gboolean fullscreen); -typedef gboolean (*GstVaapiWindowResizeFunc) (GstVaapiWindow * window, - guint width, guint height); -typedef gboolean (*GstVaapiWindowRenderFunc) (GstVaapiWindow * window, - GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, - const GstVaapiRectangle * dst_rect, guint flags); -typedef gboolean (*GstVaapiWindowRenderPixmapFunc) (GstVaapiWindow * window, - GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect, - const GstVaapiRectangle * dst_rect); -typedef guintptr (*GstVaapiWindowGetVisualIdFunc) (GstVaapiWindow * window); -typedef guintptr (*GstVaapiWindowGetColormapFunc) (GstVaapiWindow * window); -typedef gboolean (*GstVaapiWindowSetUnblockFunc) (GstVaapiWindow * window); -typedef gboolean (*GstVaapiWindowSetUnblockCancelFunc) (GstVaapiWindow * window); +#define GST_VAAPI_WINDOW_DISPLAY(window) \ + (GST_VAAPI_WINDOW_CAST (window)->display) + +#define GST_VAAPI_WINDOW_LOCK_DISPLAY(window) \ + GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_WINDOW_DISPLAY (window)) + +#define GST_VAAPI_WINDOW_UNLOCK_DISPLAY(window) \ + GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_WINDOW_DISPLAY (window)) + +#define GST_VAAPI_WINDOW_NATIVE_DISPLAY(window) \ + GST_VAAPI_DISPLAY_NATIVE (GST_VAAPI_WINDOW_DISPLAY (window)) + +#define GST_VAAPI_WINDOW_ID(window) \ + (GST_VAAPI_WINDOW_CAST (window)->native_id) + +#define GST_VAAPI_WINDOW_VADISPLAY(window) \ + GST_VAAPI_DISPLAY_VADISPLAY (GST_VAAPI_WINDOW_DISPLAY (window)) /** * GstVaapiWindow: @@ -67,7 +69,9 @@ typedef gboolean (*GstVaapiWindowSetUnblockCancelFunc) (GstVaapiWindow * window) struct _GstVaapiWindow { /*< private >*/ - GstVaapiObject parent_instance; + GstObject parent_instance; + GstVaapiDisplay *display; + GstVaapiID native_id; /*< protected >*/ guint width; @@ -106,35 +110,36 @@ struct _GstVaapiWindow struct _GstVaapiWindowClass { /*< private >*/ - GstVaapiObjectClass parent_class; + GstObjectClass parent_class; /*< protected >*/ - GstVaapiWindowCreateFunc create; - GstVaapiWindowShowFunc show; - GstVaapiWindowHideFunc hide; - GstVaapiWindowGetGeometryFunc get_geometry; - GstVaapiWindowSetFullscreenFunc set_fullscreen; - GstVaapiWindowResizeFunc resize; - GstVaapiWindowRenderFunc render; - GstVaapiWindowRenderPixmapFunc render_pixmap; - GstVaapiWindowGetVisualIdFunc get_visual_id; - GstVaapiWindowGetColormapFunc get_colormap; - GstVaapiWindowSetUnblockFunc unblock; - GstVaapiWindowSetUnblockCancelFunc unblock_cancel; + gboolean (*create) (GstVaapiWindow * window, guint * width, guint * height); + gboolean (*show) (GstVaapiWindow * window); + gboolean (*hide) (GstVaapiWindow * window); + gboolean (*get_geometry) (GstVaapiWindow * window, gint * px, gint * py, + guint * pwidth, guint * pheight); + gboolean (*set_fullscreen) (GstVaapiWindow * window, gboolean fullscreen); + gboolean (*resize) (GstVaapiWindow * window, guint width, guint height); + gboolean (*render) (GstVaapiWindow * window, GstVaapiSurface * surface, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect, + guint flags); + gboolean (*render_pixmap) (GstVaapiWindow * window, GstVaapiPixmap * pixmap, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect); + guintptr (*get_visual_id) (GstVaapiWindow * window); + guintptr (*get_colormap) (GstVaapiWindow * window); + gboolean (*unblock) (GstVaapiWindow * window); + gboolean (*unblock_cancel) (GstVaapiWindow * window); }; GstVaapiWindow * -gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, - GstVaapiDisplay * display, GstVaapiID handle, guint width, guint height); +gst_vaapi_window_new_internal (GType type, GstVaapiDisplay * display, + GstVaapiID handle, guint width, guint height); GstVaapiSurface * gst_vaapi_window_vpp_convert_internal (GstVaapiWindow * window, GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect, guint flags); -void -gst_vaapi_window_class_init (GstVaapiWindowClass * klass); - G_END_DECLS #endif /* GST_VAAPI_WINDOW_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index e6e33d1e6e..a105a82c65 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -28,6 +28,7 @@ #include "sysdeps.h" #include "gstvaapicompat.h" +#include "gstvaapiobject_priv.h" #include "gstvaapiwindow_wayland.h" #include "gstvaapiwindow_priv.h" #include "gstvaapidisplay_wayland.h" @@ -43,13 +44,10 @@ ((GstVaapiWindowWayland *)(obj)) #define GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(obj) \ - (&GST_VAAPI_WINDOW_WAYLAND_CAST(obj)->priv) - -#define GST_VAAPI_WINDOW_WAYLAND_CLASS(klass) \ - ((GstVaapiWindowWaylandClass *)(klass)) + gst_vaapi_window_wayland_get_instance_private (GST_VAAPI_WINDOW_WAYLAND_CAST (obj)) #define GST_VAAPI_WINDOW_WAYLAND_GET_CLASS(obj) \ - GST_VAAPI_WINDOW_WAYLAND_CLASS (GST_VAAPI_WINDOW_GET_CLASS (obj)) + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW_WAYLAND, GstVaapiWindowWaylandClass)) typedef struct _GstVaapiWindowWaylandPrivate GstVaapiWindowWaylandPrivate; typedef struct _GstVaapiWindowWaylandClass GstVaapiWindowWaylandClass; @@ -123,8 +121,6 @@ struct _GstVaapiWindowWayland { /*< private > */ GstVaapiWindow parent_instance; - - GstVaapiWindowWaylandPrivate priv; }; /** @@ -136,9 +132,11 @@ struct _GstVaapiWindowWaylandClass { /*< private > */ GstVaapiWindowClass parent_class; - GstVaapiObjectFinalizeFunc parent_finalize; }; +G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiWindowWayland, gst_vaapi_window_wayland, + GST_TYPE_VAAPI_WINDOW); + static gboolean gst_vaapi_window_wayland_show (GstVaapiWindow * window) { @@ -161,7 +159,7 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); struct wl_display *const wl_display = - GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); + GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); if (priv->sync_failed) return FALSE; @@ -267,30 +265,30 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window, GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); GstVaapiDisplayWaylandPrivate *const priv_display = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_OBJECT_DISPLAY (window)); + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_WINDOW_DISPLAY (window)); GST_DEBUG ("create window, size %ux%u", *width, *height); g_return_val_if_fail (priv_display->compositor != NULL, FALSE); g_return_val_if_fail (priv_display->shell != NULL, FALSE); - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); priv->event_queue = wl_display_create_queue (priv_display->wl_display); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (!priv->event_queue) return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); priv->surface = wl_compositor_create_surface (priv_display->compositor); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (!priv->surface) return FALSE; wl_proxy_set_queue ((struct wl_proxy *) priv->surface, priv->event_queue); - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); priv->shell_surface = wl_shell_get_shell_surface (priv_display->shell, priv->surface); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (!priv->shell_surface) return FALSE; wl_proxy_set_queue ((struct wl_proxy *) priv->shell_surface, @@ -312,21 +310,22 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window, } static void -gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) +gst_vaapi_window_wayland_finalize (GObject * object) { + GstVaapiWindow *window = GST_VAAPI_WINDOW (object); GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); struct wl_display *const wl_display = - GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); + GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); /* Make sure that the last wl buffer's callback could be called */ - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); if (priv->surface) { wl_surface_attach (priv->surface, NULL, 0, 0); wl_surface_commit (priv->surface); wl_display_flush (wl_display); } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); gst_poll_set_flushing (priv->poll, TRUE); @@ -339,8 +338,7 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) gst_poll_free (priv->poll); - GST_VAAPI_WINDOW_WAYLAND_GET_CLASS (window)->parent_finalize (GST_VAAPI_OBJECT - (window)); + G_OBJECT_CLASS (gst_vaapi_window_wayland_parent_class)->finalize (object); } static gboolean @@ -350,15 +348,15 @@ gst_vaapi_window_wayland_resize (GstVaapiWindow * window, GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); GstVaapiDisplayWaylandPrivate *const priv_display = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_OBJECT_DISPLAY (window)); + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_WINDOW_DISPLAY (window)); GST_DEBUG ("resize window, new size %ux%u", width, height); if (priv->opaque_region) wl_region_destroy (priv->opaque_region); - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); priv->opaque_region = wl_compositor_create_region (priv_display->compositor); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); wl_region_add (priv->opaque_region, 0, 0, width, height); return TRUE; @@ -411,9 +409,9 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); + GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window); struct wl_display *const wl_display = - GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); + GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); struct wl_buffer *buffer; FrameState *frame; guint width, height, va_flags; @@ -434,12 +432,12 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, /* Try to construct a Wayland buffer from VA surface as is (without VPP) */ if (!priv->need_vpp) { - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); va_flags = from_GstVaapiSurfaceRenderFlags (flags); status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), GST_VAAPI_OBJECT_ID (surface), va_flags & (VA_TOP_FIELD | VA_BOTTOM_FIELD), &buffer); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED || status == VA_STATUS_ERROR_UNIMPLEMENTED || status == VA_STATUS_ERROR_INVALID_IMAGE_FORMAT) @@ -463,10 +461,10 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, } } - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), GST_VAAPI_OBJECT_ID (surface), VA_FRAME_PICTURE, &buffer); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (!vaapi_check_status (status, "vaGetSurfaceBufferWl()")) return FALSE; } @@ -492,7 +490,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, } /* XXX: attach to the specified target rectangle */ - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); wl_surface_attach (priv->surface, buffer, 0, 0); wl_surface_damage (priv->surface, 0, 0, width, height); @@ -510,7 +508,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, wl_surface_commit (priv->surface); wl_display_flush (wl_display); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); return TRUE; } @@ -539,14 +537,10 @@ gst_vaapi_window_wayland_unblock_cancel (GstVaapiWindow * window) static void gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass) { - GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); - gst_vaapi_window_class_init (&klass->parent_class); - - klass->parent_finalize = object_class->finalize; - object_class->finalize = (GstVaapiObjectFinalizeFunc) - gst_vaapi_window_wayland_destroy; + object_class->finalize = gst_vaapi_window_wayland_finalize; window_class->create = gst_vaapi_window_wayland_create; window_class->show = gst_vaapi_window_wayland_show; @@ -558,11 +552,10 @@ gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass) window_class->unblock_cancel = gst_vaapi_window_wayland_unblock_cancel; } -#define gst_vaapi_window_wayland_finalize \ - gst_vaapi_window_wayland_destroy - -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowWayland, - gst_vaapi_window_wayland, gst_vaapi_window_wayland_class_init (&g_class)); +static void +gst_vaapi_window_wayland_init (GstVaapiWindowWayland * window) +{ +} /** * gst_vaapi_window_wayland_new: @@ -580,11 +573,8 @@ GstVaapiWindow * gst_vaapi_window_wayland_new (GstVaapiDisplay * display, guint width, guint height) { - GST_DEBUG ("new window, size %ux%u", width, height); - g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_WAYLAND (display), NULL); - return gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS - (gst_vaapi_window_wayland_class ()), display, GST_VAAPI_ID_INVALID, width, - height); + return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_WAYLAND, display, + GST_VAAPI_ID_INVALID, width, height); } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h index ed8f756de7..3e13052afd 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h @@ -24,17 +24,31 @@ #ifndef GST_VAAPI_WINDOW_WAYLAND_H #define GST_VAAPI_WINDOW_WAYLAND_H +#include #include #include G_BEGIN_DECLS +#define GST_TYPE_VAAPI_WINDOW_WAYLAND (gst_vaapi_window_wayland_get_type ()) +#define GST_VAAPI_WINDOW_WAYLAND(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW_WAYLAND, GstVaapiWindowWayland)) +#define GST_VAAPI_IS_WINDOW_WAYLAND(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW_WAYLAND)) + typedef struct _GstVaapiWindowWayland GstVaapiWindowWayland; +GType +gst_vaapi_window_wayland_get_type (void) G_GNUC_CONST; + GstVaapiWindow * gst_vaapi_window_wayland_new (GstVaapiDisplay * display, guint width, guint height); +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowWayland, gst_object_unref) +#endif + G_END_DECLS #endif /* GST_VAAPI_WINDOW_WAYLAND_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index ce63f3cfa0..b2237e71a2 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -43,6 +43,12 @@ #define DEBUG 1 #include "gstvaapidebug.h" +#define GST_VAAPI_WINDOW_X11_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW_X11, GstVaapiWindowX11Class)) + +G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiWindowX11, gst_vaapi_window_x11, + GST_TYPE_VAAPI_WINDOW); + #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ #define _NET_WM_STATE_ADD 1 /* add/set property */ #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ @@ -52,13 +58,13 @@ send_wmspec_change_state (GstVaapiWindow * window, Atom state, gboolean add) { GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); XClientMessageEvent xclient; memset (&xclient, 0, sizeof (xclient)); xclient.type = ClientMessage; - xclient.window = GST_VAAPI_OBJECT_ID (window); + xclient.window = GST_VAAPI_WINDOW_ID (window); xclient.message_type = priv->atom_NET_WM_STATE; xclient.format = 32; @@ -77,15 +83,15 @@ send_wmspec_change_state (GstVaapiWindow * window, Atom state, gboolean add) static void wait_event (GstVaapiWindow * window, int type) { - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - const Window xid = GST_VAAPI_OBJECT_ID (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); + const Window xid = GST_VAAPI_WINDOW_ID (window); XEvent e; Bool got_event; for (;;) { - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); got_event = XCheckTypedWindowEvent (dpy, xid, type, &e); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (got_event) break; g_usleep (10); @@ -96,8 +102,8 @@ static gboolean timed_wait_event (GstVaapiWindow * window, int type, guint64 end_time, XEvent * e) { - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - const Window xid = GST_VAAPI_OBJECT_ID (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); + const Window xid = GST_VAAPI_WINDOW_ID (window); XEvent tmp_event; GTimeVal now; guint64 now_time; @@ -106,17 +112,17 @@ timed_wait_event (GstVaapiWindow * window, int type, guint64 end_time, if (!e) e = &tmp_event; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); got_event = XCheckTypedWindowEvent (dpy, xid, type, e); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (got_event) return TRUE; do { g_usleep (10); - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); got_event = XCheckTypedWindowEvent (dpy, xid, type, e); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (got_event) return TRUE; g_get_current_time (&now); @@ -130,15 +136,15 @@ gst_vaapi_window_x11_show (GstVaapiWindow * window) { GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - const Window xid = GST_VAAPI_OBJECT_ID (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); + const Window xid = GST_VAAPI_WINDOW_ID (window); XWindowAttributes wattr; gboolean has_errors; if (priv->is_mapped) return TRUE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); x11_trap_errors (); if (window->use_foreign_window) { XGetWindowAttributes (dpy, xid, &wattr); @@ -147,17 +153,17 @@ gst_vaapi_window_x11_show (GstVaapiWindow * window) } XMapWindow (dpy, xid); has_errors = x11_untrap_errors () != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (!has_errors) { wait_event (window, MapNotify); if (window->use_foreign_window && !(wattr.your_event_mask & StructureNotifyMask)) { - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); x11_trap_errors (); XSelectInput (dpy, xid, wattr.your_event_mask); has_errors = x11_untrap_errors () != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } priv->is_mapped = TRUE; @@ -172,15 +178,15 @@ gst_vaapi_window_x11_hide (GstVaapiWindow * window) { GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - const Window xid = GST_VAAPI_OBJECT_ID (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); + const Window xid = GST_VAAPI_WINDOW_ID (window); XWindowAttributes wattr; gboolean has_errors; if (!priv->is_mapped) return TRUE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); x11_trap_errors (); if (window->use_foreign_window) { XGetWindowAttributes (dpy, xid, &wattr); @@ -189,17 +195,17 @@ gst_vaapi_window_x11_hide (GstVaapiWindow * window) } XUnmapWindow (dpy, xid); has_errors = x11_untrap_errors () != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (!has_errors) { wait_event (window, UnmapNotify); if (window->use_foreign_window && !(wattr.your_event_mask & StructureNotifyMask)) { - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); x11_trap_errors (); XSelectInput (dpy, xid, wattr.your_event_mask); has_errors = x11_untrap_errors () != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } priv->is_mapped = FALSE; } @@ -212,9 +218,9 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, { GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - Window xid = GST_VAAPI_OBJECT_ID (window); + GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); + Window xid = GST_VAAPI_WINDOW_ID (window); guint vid = 0; Colormap cmap = None; const GstVaapiDisplayClass *display_class; @@ -229,14 +235,14 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, }; priv->has_xrender = - GST_VAAPI_DISPLAY_HAS_XRENDER (GST_VAAPI_OBJECT_DISPLAY (window)); + GST_VAAPI_DISPLAY_HAS_XRENDER (GST_VAAPI_WINDOW_DISPLAY (window)); if (window->use_foreign_window && xid) { - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); XGetWindowAttributes (dpy, xid, &wattr); priv->is_mapped = wattr.map_state == IsViewable; ok = x11_get_geometry (dpy, xid, NULL, NULL, width, height, NULL); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); return ok; } @@ -256,7 +262,7 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, cmap = window_class->get_colormap (window); } - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); XInternAtoms (dpy, (char **) atom_names, G_N_ELEMENTS (atom_names), False, atoms); priv->atom_NET_WM_STATE = atoms[0]; @@ -265,54 +271,54 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, xid = x11_create_window (dpy, *width, *height, vid, cmap); if (xid) XRaiseWindow (dpy, xid); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); GST_DEBUG ("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (xid)); - GST_VAAPI_OBJECT_ID (window) = xid; + GST_VAAPI_WINDOW_ID (window) = xid; return xid != None; } static void -gst_vaapi_window_x11_destroy (GstVaapiWindow * window) +gst_vaapi_window_x11_finalize (GObject * object) { - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - const Window xid = GST_VAAPI_OBJECT_ID (window); + GstVaapiWindow *window = GST_VAAPI_WINDOW (object); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); + const Window xid = GST_VAAPI_WINDOW_ID (window); #if HAVE_XRENDER GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); if (priv->picture) { - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); XRenderFreePicture (dpy, priv->picture); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); priv->picture = None; } #endif if (xid) { if (!window->use_foreign_window) { - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); XDestroyWindow (dpy, xid); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } - GST_VAAPI_OBJECT_ID (window) = None; + GST_VAAPI_WINDOW_ID (window) = None; } - GST_VAAPI_WINDOW_X11_GET_CLASS (window)->parent_finalize (GST_VAAPI_OBJECT - (window)); + G_OBJECT_CLASS (gst_vaapi_window_x11_parent_class)->finalize (object); } static gboolean gst_vaapi_window_x11_get_geometry (GstVaapiWindow * window, gint * px, gint * py, guint * pwidth, guint * pheight) { - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - const Window xid = GST_VAAPI_OBJECT_ID (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); + const Window xid = GST_VAAPI_WINDOW_ID (window); gboolean success; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); success = x11_get_geometry (dpy, xid, px, py, pwidth, pheight, NULL); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); return success; } @@ -322,15 +328,15 @@ gst_vaapi_window_x11_set_fullscreen (GstVaapiWindow * window, { GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - const Window xid = GST_VAAPI_OBJECT_ID (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); + const Window xid = GST_VAAPI_WINDOW_ID (window); XEvent e; guint width, height; gboolean has_errors; GTimeVal now; guint64 end_time; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); x11_trap_errors (); if (fullscreen) { if (!priv->is_mapped) { @@ -357,7 +363,7 @@ gst_vaapi_window_x11_set_fullscreen (GstVaapiWindow * window, } XSync (dpy, False); has_errors = x11_untrap_errors () != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (has_errors) return FALSE; @@ -368,7 +374,7 @@ gst_vaapi_window_x11_set_fullscreen (GstVaapiWindow * window, end_time = DELAY + ((guint64) now.tv_sec * 1000000 + now.tv_usec); while (timed_wait_event (window, ConfigureNotify, end_time, &e)) { if (fullscreen) { - gst_vaapi_display_get_size (GST_VAAPI_OBJECT_DISPLAY (window), + gst_vaapi_display_get_size (GST_VAAPI_WINDOW_DISPLAY (window), &width, &height); if (e.xconfigure.width == width && e.xconfigure.height == height) return TRUE; @@ -387,15 +393,15 @@ gst_vaapi_window_x11_resize (GstVaapiWindow * window, guint width, guint height) { gboolean has_errors; - if (!GST_VAAPI_OBJECT_ID (window)) + if (!GST_VAAPI_WINDOW_ID (window)) return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); x11_trap_errors (); - XResizeWindow (GST_VAAPI_OBJECT_NATIVE_DISPLAY (window), - GST_VAAPI_OBJECT_ID (window), width, height); + XResizeWindow (GST_VAAPI_WINDOW_NATIVE_DISPLAY (window), + GST_VAAPI_WINDOW_ID (window), width, height); has_errors = x11_untrap_errors () != 0; - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); return !has_errors; } @@ -407,10 +413,10 @@ gst_vaapi_window_x11_put_surface (GstVaapiWindow * window, { VAStatus status; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); - status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (window), + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); + status = vaPutSurface (GST_VAAPI_WINDOW_VADISPLAY (window), surface_id, - GST_VAAPI_OBJECT_ID (window), + GST_VAAPI_WINDOW_ID (window), src_rect->x, src_rect->y, src_rect->width, @@ -421,7 +427,7 @@ gst_vaapi_window_x11_put_surface (GstVaapiWindow * window, dst_rect->height, NULL, 0, from_GstVaapiSurfaceRenderFlags (flags) ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); return status; } @@ -498,8 +504,8 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window, #if HAVE_XRENDER GstVaapiWindowX11Private *const priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - const Window win = GST_VAAPI_OBJECT_ID (window); + Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); + const Window win = GST_VAAPI_WINDOW_ID (window); const Pixmap pix = GST_VAAPI_OBJECT_ID (pixmap); Picture picture; XRenderPictFormat *pic_fmt; @@ -509,12 +515,12 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window, /* Ensure Picture for window is created */ if (!priv->picture) { - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); XGetWindowAttributes (dpy, win, &wattr); pic_fmt = XRenderFindVisualFormat (dpy, wattr.visual); if (pic_fmt) priv->picture = XRenderCreatePicture (dpy, win, pic_fmt, 0, NULL); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (!priv->picture) return FALSE; } @@ -529,9 +535,9 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window, fmt = PictStandardARGB32; op = PictOpOver; get_pic_fmt: - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); pic_fmt = XRenderFindStandardFormat (dpy, fmt); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); break; default: pic_fmt = NULL; @@ -540,7 +546,7 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window, if (!pic_fmt) return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); do { const double sx = (double) src_rect->width / dst_rect->width; const double sy = (double) src_rect->height / dst_rect->height; @@ -569,7 +575,7 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window, } while (0); if (picture) XRenderFreePicture (dpy, picture); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); return success; #endif return FALSE; @@ -591,17 +597,13 @@ gst_vaapi_window_x11_render_pixmap (GstVaapiWindow * window, return FALSE; } -void +static void gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass) { - GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); + GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); - gst_vaapi_window_class_init (&klass->parent_class); - - klass->parent_finalize = object_class->finalize; - object_class->finalize = (GstVaapiObjectFinalizeFunc) - gst_vaapi_window_x11_destroy; + object_class->finalize = gst_vaapi_window_x11_finalize; window_class->create = gst_vaapi_window_x11_create; window_class->show = gst_vaapi_window_x11_show; @@ -613,11 +615,10 @@ gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass) window_class->render_pixmap = gst_vaapi_window_x11_render_pixmap; } -#define gst_vaapi_window_x11_finalize \ - gst_vaapi_window_x11_destroy - -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowX11, - gst_vaapi_window_x11, gst_vaapi_window_x11_class_init (&g_class)); +static void +gst_vaapi_window_x11_init (GstVaapiWindowX11 * window) +{ +} /** * gst_vaapi_window_x11_new: @@ -634,14 +635,10 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowX11, GstVaapiWindow * gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height) { - GST_DEBUG ("new window, size %ux%u", width, height); - g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); - return - gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS - (gst_vaapi_window_x11_class ()), display, GST_VAAPI_ID_INVALID, width, - height); + return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_X11, display, + GST_VAAPI_ID_INVALID, width, height); } /** @@ -659,13 +656,11 @@ gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height) GstVaapiWindow * gst_vaapi_window_x11_new_with_xid (GstVaapiDisplay * display, Window xid) { - GST_DEBUG ("new window from xid 0x%08x", (guint) xid); - g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); g_return_val_if_fail (xid != None, NULL); - return gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS - (gst_vaapi_window_x11_class ()), display, xid, 0, 0); + return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_X11, display, + xid, 0, 0); } /** @@ -681,9 +676,9 @@ gst_vaapi_window_x11_new_with_xid (GstVaapiDisplay * display, Window xid) Window gst_vaapi_window_x11_get_xid (GstVaapiWindowX11 * window) { - g_return_val_if_fail (window != NULL, None); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW_X11 (window), None); - return GST_VAAPI_OBJECT_ID (window); + return GST_VAAPI_WINDOW_ID (window); } /** @@ -698,7 +693,7 @@ gst_vaapi_window_x11_get_xid (GstVaapiWindowX11 * window) gboolean gst_vaapi_window_x11_is_foreign_xid (GstVaapiWindowX11 * window) { - g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GST_VAAPI_IS_WINDOW_X11 (window), FALSE); return GST_VAAPI_WINDOW (window)->use_foreign_window; } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index 8b32e33b7d..095a267dc8 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -26,13 +26,17 @@ #define GST_VAAPI_WINDOW_X11_H #include +#include #include #include G_BEGIN_DECLS +#define GST_TYPE_VAAPI_WINDOW_X11 (gst_vaapi_window_x11_get_type ()) #define GST_VAAPI_WINDOW_X11(obj) \ - ((GstVaapiWindowX11 *)(obj)) + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW_X11, GstVaapiWindowX11)) +#define GST_VAAPI_IS_WINDOW_X11(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW_X11)) /** * GST_VAAPI_WINDOW_XWINDOW: @@ -41,10 +45,13 @@ G_BEGIN_DECLS * Macro that evaluates to the underlying X11 #Window of @window */ #define GST_VAAPI_WINDOW_XWINDOW(window) \ - gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(window)) + gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (window)) typedef struct _GstVaapiWindowX11 GstVaapiWindowX11; +GType +gst_vaapi_window_x11_get_type (void) G_GNUC_CONST; + GstVaapiWindow * gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index 519048d862..08bc074b84 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -33,14 +33,12 @@ G_BEGIN_DECLS +#define GST_VAAPI_WINDOW_X11_CAST(obj) ((GstVaapiWindowX11 *)(obj)) #define GST_VAAPI_WINDOW_X11_GET_PRIVATE(obj) \ - (&GST_VAAPI_WINDOW_X11(obj)->priv) - -#define GST_VAAPI_WINDOW_X11_CLASS(klass) \ - ((GstVaapiWindowX11Class *)(klass)) + gst_vaapi_window_x11_get_instance_private (GST_VAAPI_WINDOW_X11_CAST (obj)) #define GST_VAAPI_WINDOW_X11_GET_CLASS(obj) \ - GST_VAAPI_WINDOW_X11_CLASS(GST_VAAPI_WINDOW_GET_CLASS(obj)) + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW_X11, GstVaapiWindowX11Class)) typedef struct _GstVaapiWindowX11Private GstVaapiWindowX11Private; typedef struct _GstVaapiWindowX11Class GstVaapiWindowX11Class; @@ -67,8 +65,6 @@ struct _GstVaapiWindowX11 { /*< private >*/ GstVaapiWindow parent_instance; - - GstVaapiWindowX11Private priv; }; /** @@ -80,12 +76,8 @@ struct _GstVaapiWindowX11Class { /*< private >*/ GstVaapiWindowClass parent_class; - GstVaapiObjectFinalizeFunc parent_finalize; }; -void -gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass); - G_END_DECLS #endif /* GST_VAAPI_WINDOW_X11_PRIV_H */ From 8ef95a7dc22502b78ccd28bddefda29b32918315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 22 Dec 2018 13:25:09 +0100 Subject: [PATCH 3189/3781] libs: window: use its own debug category --- gst-libs/gst/vaapi/gstvaapiwindow.c | 10 +++++++--- gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiwindow_egl.c | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 4 ++-- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 61e679ea06..fdf650fef8 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -33,11 +33,15 @@ #include "gstvaapidisplay_priv.h" #include "gstvaapisurface_priv.h" -#define DEBUG 1 -#include "gstvaapidebug.h" +GST_DEBUG_CATEGORY (gst_debug_vaapi_window); +#define GST_CAT_DEFAULT gst_debug_vaapi_window +#define _do_init \ + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_window, "vaapiwindow", 0, \ + "VA-API Window"); -G_DEFINE_ABSTRACT_TYPE (GstVaapiWindow, gst_vaapi_window, GST_TYPE_OBJECT); +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstVaapiWindow, gst_vaapi_window, + GST_TYPE_OBJECT, _do_init); enum { diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c index 78e816340b..54735b4db8 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -30,8 +30,8 @@ #include "gstvaapiwindow_priv.h" #include "gstvaapidisplay_drm_priv.h" -#define DEBUG 1 -#include "gstvaapidebug.h" +GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapi_window); +#define GST_CAT_DEFAULT gst_debug_vaapi_window typedef struct _GstVaapiWindowDRMClass GstVaapiWindowDRMClass; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c index 56b4855e1f..45f3869160 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c @@ -32,6 +32,8 @@ #include "gstvaapitexture_priv.h" #include "gstvaapidisplay_egl_priv.h" +GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapi_window); +#define GST_CAT_DEFAULT gst_debug_vaapi_window #define GST_VAAPI_WINDOW_EGL_CAST(obj) \ ((GstVaapiWindowEGL *)(obj)) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index aae17ab208..fe823b97b0 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -36,8 +36,8 @@ #include "gstvaapiutils_x11.h" #include "gstvaapiutils_glx.h" -#define DEBUG 1 -#include "gstvaapidebug.h" +GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapi_window); +#define GST_CAT_DEFAULT gst_debug_vaapi_window #define GST_VAAPI_WINDOW_GLX_CAST(obj) ((GstVaapiWindowGLX *)(obj)) #define GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window) \ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index a105a82c65..5b9b4663c0 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -37,8 +37,8 @@ #include "gstvaapifilter.h" #include "gstvaapisurfacepool.h" -#define DEBUG 1 -#include "gstvaapidebug.h" +GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapi_window); +#define GST_CAT_DEFAULT gst_debug_vaapi_window #define GST_VAAPI_WINDOW_WAYLAND_CAST(obj) \ ((GstVaapiWindowWayland *)(obj)) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index b2237e71a2..865b11babe 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -40,8 +40,8 @@ #include "gstvaapiutils.h" #include "gstvaapiutils_x11.h" -#define DEBUG 1 -#include "gstvaapidebug.h" +GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapi_window); +#define GST_CAT_DEFAULT gst_debug_vaapi_window #define GST_VAAPI_WINDOW_X11_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW_X11, GstVaapiWindowX11Class)) From e4ae7d9879b3ee61527e771e4605a234cb37b54d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 22 Dec 2018 18:07:35 +0100 Subject: [PATCH 3190/3781] libs: window: remove custom ref() and unref() Use gst_object_ref() and gst_object_unref() instead. --- gst-libs/gst/vaapi/gstvaapiwindow.c | 29 +------------------------ gst-libs/gst/vaapi/gstvaapiwindow.h | 6 ----- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 4 ++-- tests/test-decode.c | 2 +- tests/test-filter.c | 2 +- tests/test-subpicture.c | 2 +- tests/test-textures.c | 2 +- tests/test-windows.c | 8 +++---- 8 files changed, 11 insertions(+), 44 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index fdf650fef8..ad686f0a15 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -258,7 +258,7 @@ gst_vaapi_window_new_internal (GType type, GstVaapiDisplay * display, /* ERRORS */ error: { - gst_vaapi_window_unref (window); + gst_object_unref (window); return NULL; } } @@ -331,33 +331,6 @@ gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height) height); } -/** - * gst_vaapi_window_ref: - * @window: a #GstVaapiWindow - * - * Atomically increases the reference count of the given @window by one. - * - * Returns: The same @window argument - */ -GstVaapiWindow * -gst_vaapi_window_ref (GstVaapiWindow * window) -{ - return (GstVaapiWindow *) gst_object_ref (window); -} - -/** - * gst_vaapi_window_unref: - * @window: a #GstVaapiWindow - * - * Atomically decreases the reference count of the @window by one. If - * the reference count reaches zero, the window will be free'd. - */ -void -gst_vaapi_window_unref (GstVaapiWindow * window) -{ - gst_object_unref (window); -} - /** * gst_vaapi_window_replace: * @old_window_ptr: a pointer to a #GstVaapiWindow diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 040db6c223..0796d20ddf 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -48,12 +48,6 @@ gst_vaapi_window_get_type (void) G_GNUC_CONST; GstVaapiWindow * gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height); -GstVaapiWindow * -gst_vaapi_window_ref (GstVaapiWindow * window); - -void -gst_vaapi_window_unref (GstVaapiWindow * window); - void gst_vaapi_window_replace (GstVaapiWindow ** old_window_ptr, GstVaapiWindow * new_window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index fe823b97b0..d2003dff56 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -353,7 +353,7 @@ gst_vaapi_window_glx_new (GstVaapiDisplay * display, guint width, guint height) /* ERRORS */ error: { - gst_vaapi_window_unref (window); + gst_object_unref (window); return NULL; } } @@ -390,7 +390,7 @@ gst_vaapi_window_glx_new_with_xid (GstVaapiDisplay * display, Window xid) /* ERRORS */ error: { - gst_vaapi_window_unref (window); + gst_object_unref (window); return NULL; } } diff --git a/tests/test-decode.c b/tests/test-decode.c index 81bab85d86..ef16aa157c 100644 --- a/tests/test-decode.c +++ b/tests/test-decode.c @@ -134,7 +134,7 @@ main (int argc, char *argv[]) gst_vaapi_pixmap_unref (pixmap); gst_vaapi_surface_proxy_unref (proxy); gst_object_unref (decoder); - gst_vaapi_window_unref (window); + gst_object_unref (window); gst_object_unref (display); gst_object_unref (display2); g_free (g_codec_str); diff --git a/tests/test-filter.c b/tests/test-filter.c index 8e6b20807c..ab57775a04 100644 --- a/tests/test-filter.c +++ b/tests/test-filter.c @@ -443,7 +443,7 @@ main (int argc, char *argv[]) gst_object_unref (filter); gst_vaapi_object_unref (dst_surface); gst_vaapi_object_unref (src_surface); - gst_vaapi_window_unref (window); + gst_object_unref (window); gst_object_unref (display); video_output_exit (); g_free (g_src_format_str); diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index b193e10319..ee000560b9 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -164,7 +164,7 @@ main (int argc, char *argv[]) gst_video_overlay_composition_unref (compo); gst_vaapi_surface_proxy_unref (proxy); gst_object_unref (decoder); - gst_vaapi_window_unref (window); + gst_object_unref (window); gst_object_unref (display); g_free (g_codec_str); video_output_exit (); diff --git a/tests/test-textures.c b/tests/test-textures.c index 97c82df527..46e2b91609 100644 --- a/tests/test-textures.c +++ b/tests/test-textures.c @@ -172,7 +172,7 @@ main (int argc, char *argv[]) gst_vaapi_texture_unref (textures[1]); glDeleteTextures (1, &texture_id); - gst_vaapi_window_unref (window); + gst_object_unref (window); gst_object_unref (display); gst_deinit (); return 0; diff --git a/tests/test-windows.c b/tests/test-windows.c index 28b2683a17..4985e350da 100644 --- a/tests/test-windows.c +++ b/tests/test-windows.c @@ -131,7 +131,7 @@ main (int argc, char *argv[]) g_error ("could not render surface"); pause (); - gst_vaapi_window_unref (window); + gst_object_unref (window); } gst_vaapi_object_unref (surface); @@ -161,7 +161,7 @@ main (int argc, char *argv[]) g_error ("could not render surface"); pause (); - gst_vaapi_window_unref (window); + gst_object_unref (window); } g_print ("#\n"); @@ -194,7 +194,7 @@ main (int argc, char *argv[]) g_error ("could not render surface"); pause (); - gst_vaapi_window_unref (window); + gst_object_unref (window); XUnmapWindow (dpy, win); XDestroyWindow (dpy, win); } @@ -226,7 +226,7 @@ main (int argc, char *argv[]) g_error ("could not render surface"); pause (); - gst_vaapi_window_unref (window); + gst_object_unref (window); } gst_vaapi_object_unref (surface); From 920b1ec7a84af24526989108c1e83b17086f639e Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Mon, 24 Dec 2018 12:58:53 +0800 Subject: [PATCH 3191/3781] vaapi: bump the minimum vaapi version requirement to 0.39.0 And reduce unnecessary API version and structures check as well. https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/108 --- configure.ac | 370 +----------------- gst-libs/gst/vaapi/Makefile.am | 41 +- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 25 -- gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h | 2 - gst-libs/gst/vaapi/gstvaapicodec_objects.c | 6 +- gst-libs/gst/vaapi/gstvaapicompat.h | 55 +-- gst-libs/gst/vaapi/gstvaapicontext.c | 2 - gst-libs/gst/vaapi/gstvaapidisplay.c | 2 - gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 2 - gst-libs/gst/vaapi/gstvaapifilter.c | 47 --- gst-libs/gst/vaapi/gstvaapiprofile.c | 18 - gst-libs/gst/vaapi/gstvaapisurface.c | 10 - gst-libs/gst/vaapi/gstvaapiutils.c | 35 -- gst-libs/gst/vaapi/gstvaapiutils_core.c | 2 - gst-libs/gst/vaapi/meson.build | 48 +-- gst/vaapi/Makefile.am | 33 +- gst/vaapi/gstvaapi.c | 15 - gst/vaapi/gstvaapidecode.c | 22 -- gst/vaapi/gstvaapidecodebin.c | 6 - gst/vaapi/gstvaapipluginbase.c | 2 +- gst/vaapi/meson.build | 15 +- meson.build | 58 +-- tests/decoder.c | 2 - tests/simple-decoder.c | 2 - 24 files changed, 42 insertions(+), 778 deletions(-) diff --git a/configure.ac b/configure.ac index 3f58d69b92..a64c294543 100644 --- a/configure.ac +++ b/configure.ac @@ -32,11 +32,7 @@ m4_define([gst_plugins_bad_version], [1.15.0.1]) m4_define([wayland_api_version], [1.0.2]) # VA-API minimum version number -m4_define([va_api_version], [0.30.4]) -m4_define([va_api_enc_version], [0.34.0]) -m4_define([va_api_drm_version], [0.33.0]) -m4_define([va_api_x11_version], [0.31.0]) -m4_define([va_api_wld_version], [0.33.0]) +m4_define([va_api_version], [0.39.0]) # gtk-doc version number # XXX: introspection annotations require gtk-doc >= 1.12 @@ -93,10 +89,6 @@ GTKDOC_REQ=gtkdoc_version dnl *** required versions of VA-API stuff *** VAAPI_REQ=va_api_version -VAAPI_ENC_REQ=va_api_enc_version -VAAPI_DRM_REQ=va_api_drm_version -VAAPI_X11_REQ=va_api_x11_version -VAAPI_WLD_REQ=va_api_wld_version dnl *** autotools stuff **** @@ -513,7 +505,7 @@ AC_DEFINE_UNQUOTED([VA_DRIVERS_PATH], ["$VA_DRIVERS_PATH"], dnl VA/DRM API if test $USE_DRM -eq 1; then - PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= $VAAPI_DRM_REQ], + PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= $VAAPI_REQ], [ saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_DRM_CFLAGS" @@ -524,240 +516,16 @@ fi dnl VA/X11 API if test $USE_X11 -eq 1; then - PKG_CHECK_MODULES(LIBVA_X11, [libva-x11 >= $VAAPI_X11_REQ], + PKG_CHECK_MODULES(LIBVA_X11, [libva-x11 >= $VAAPI_REQ], [], [USE_X11=0]) fi -dnl Check for va_dec_jpeg.h header -saved_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" -AC_CHECK_HEADERS([va/va_dec_jpeg.h], [], [], - [ -#include - ]) -CPPFLAGS="$saved_CPPFLAGS" - -dnl Check for JPEG decoding API (0.32.1+) -USE_JPEG_DECODER=0 -AC_CACHE_CHECK([for JPEG decoding API], - [ac_cv_have_jpeg_decoding_api], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include -#ifdef HAVE_VA_VA_DEC_JPEG_H -# include -#endif - ]], - [[ -VAPictureParameterBufferJPEGBaseline pic_param; -VASliceParameterBufferJPEGBaseline slice_param; -VAHuffmanTableBufferJPEGBaseline huffman_table; -VAIQMatrixBufferJPEGBaseline iq_matrix; - ]]) - ], - [ac_cv_have_jpeg_decoding_api="yes"], - [ac_cv_have_jpeg_decoding_api="no"]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) -AS_IF([test "x$ac_cv_have_jpeg_decoding_api" = "xyes"], [USE_JPEG_DECODER=1]) - -dnl Check for va_dec_vp8.h header -saved_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" -AC_CHECK_HEADERS([va/va_dec_vp8.h], [], [], - [ -#include - ]) -CPPFLAGS="$saved_CPPFLAGS" - -dnl Check for VP8 decoding API (0.34+) -USE_VP8_DECODER=0 -AC_CACHE_CHECK([for VP8 decoding API], - [ac_cv_have_vp8_decoding_api], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include -#ifdef HAVE_VA_VA_DEC_VP8_H -# include -#endif - ]], - [[ -VAPictureParameterBufferVP8 pic_param; -VASliceParameterBufferVP8 slice_param; -VAProbabilityDataBufferVP8 prob_data; -VAIQMatrixBufferVP8 iq_matrix; -slice_param.slice_data_offset = 0; -slice_param.slice_data_flag = 0; - ]]) - ], - [ac_cv_have_vp8_decoding_api="yes"], - [ac_cv_have_vp8_decoding_api="no"]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) -AS_IF([test "x$ac_cv_have_vp8_decoding_api" = "xyes"], [USE_VP8_DECODER=1]) - -dnl Check for va_dec_vp9.h header -saved_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" -AC_CHECK_HEADERS([va/va_dec_vp9.h], [], [], - [ -#include - ]) -CPPFLAGS="$saved_CPPFLAGS" - -dnl Check for VP9 decoding API (0.37+) -USE_VP9_DECODER=0 -AC_CACHE_CHECK([for VP9 decoding API], - [ac_cv_have_vp9_decoding_api], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include -#ifdef HAVE_VA_VA_DEC_VP9_H -# include -#endif - ]], - [[ -VADecPictureParameterBufferVP9 pic_param; -VASliceParameterBufferVP9 slice_param; -VASegmentParameterVP9 seg_param; -slice_param.slice_data_offset = 0; -slice_param.slice_data_flag = 0; - ]]) - ], - [ac_cv_have_vp9_decoding_api="yes"], - [ac_cv_have_vp9_decoding_api="no"]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) -AS_IF([test "x$ac_cv_have_vp9_decoding_api" = "xyes"], [USE_VP9_DECODER=1]) - -dnl Check for va_dec_hevc.h header -saved_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" -AC_CHECK_HEADERS([va/va_dec_hevc.h], [], [], - [ -#include - ]) -CPPFLAGS="$saved_CPPFLAGS" - -dnl Check for HEVC decoding API (0.38+) -USE_H265_DECODER=0 -AC_CACHE_CHECK([for HEVC decoding API], - [ac_cv_have_h265_decoding_api], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include -#ifdef HAVE_VA_VA_DEC_HEVC_H -# include -#endif - ]], - [[ -VAPictureParameterBufferHEVC pic_param; -VASliceParameterBufferHEVC slice_param; -VAIQMatrixBufferHEVC iq_matrix; -slice_param.slice_data_offset = 0; -slice_param.slice_data_flag = 0; - ]]) - ], - [ac_cv_have_h265_decoding_api="yes"], - [ac_cv_have_h265_decoding_api="no"]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) -AS_IF([test "x$ac_cv_have_h265_decoding_api" = "xyes"], [USE_H265_DECODER=1]) - -dnl Check for va_vpp.h header -saved_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" -AC_CHECK_HEADERS([va/va_vpp.h], [], [], - [ -#include - ]) -CPPFLAGS="$saved_CPPFLAGS" - -dnl Check for vpp (video post-processing) support -USE_VA_VPP=0 -AC_CACHE_CHECK([for video post-postprocessing API], - [ac_cv_have_va_vpp_api], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include -#ifdef HAVE_VA_VA_VPP_H -# include -#endif - ]], - [[ -VADisplay va_dpy; -VAContextID vpp_ctx; -VAProcFilterType filters[VAProcFilterCount]; -unsigned int num_filters = VAProcFilterCount; -vaQueryVideoProcFilters(va_dpy, vpp_ctx, filters, &num_filters); - ]]) - ], - [ac_cv_have_va_vpp_api="yes"], - [ac_cv_have_va_vpp_api="no"]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) -AS_IF([test "x$ac_cv_have_va_vpp_api" = "xyes"], [USE_VA_VPP=1]) - dnl Check for encoding support USE_ENCODERS=0 if test "x$enable_encoders" = "xyes"; then - PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_ENC_REQ], - [ - USE_ENCODERS=1 - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - AC_CHECK_HEADERS([va/va_enc_mpeg2.h va/va_enc_h264.h], [], - [USE_ENCODERS=0], - [ -#include - ]) - CPPFLAGS="$saved_CPPFLAGS" - ], [:]) + USE_ENCODERS=1 fi -USE_JPEG_ENCODER=0 -USE_VP8_ENCODER=0 -USE_H265_ENCODER=0 USE_VP9_ENCODER=0 USE_H264_FEI_ENCODER=0 @@ -765,101 +533,7 @@ if test $USE_ENCODERS -eq 1; then saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - dnl Check for JPEG Encoding API (0.37.0+) - AC_CHECK_HEADERS([va/va_enc_jpeg.h], [], [], - [ -#include - ]) - AC_CACHE_CHECK([for JPEG encoding API], - [ac_cv_have_jpeg_encoding_api], - [ - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include -#ifdef HAVE_VA_VA_ENC_JPEG_H -# include -#endif - ]], - [[ -VAEncPictureParameterBufferJPEG pic_param; -VAEncSliceParameterBufferJPEG slice_param; -VAQMatrixBufferJPEG q_matrix; - ]]) - ], - [ac_cv_have_jpeg_encoding_api="yes"], - [ac_cv_have_jpeg_encoding_api="no"]) - LIBS="$saved_LIBS" - ]) - AS_IF([test "x$ac_cv_have_jpeg_encoding_api" = "xyes"], [USE_JPEG_ENCODER=1]) - - dnl Check for VP8 Encoding API - AC_CHECK_HEADERS([va/va_enc_vp8.h], [], [], - [ -#include - ]) - AC_CACHE_CHECK([for VP8 encoding API], - [ac_cv_have_vp8_encoding_api], - [ - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include -#ifdef HAVE_VA_VA_ENC_VP8_H -# include -#endif - ]], - [[ -VAEncSequenceParameterBufferVP8 seq_param; -VAEncPictureParameterBufferVP8 pic_param; -VAQMatrixBufferVP8 q_matrix; - ]]) - ], - [ac_cv_have_vp8_encoding_api="yes"], - [ac_cv_have_vp8_encoding_api="no"]) - LIBS="$saved_LIBS" - ]) - AS_IF([test "x$ac_cv_have_vp8_encoding_api" = "xyes"], [USE_VP8_ENCODER=1]) - - dnl Check for H265/HEVC Encoding API - AC_CHECK_HEADERS([va/va_enc_hevc.h], [], [], - [ -#include - ]) - AC_CACHE_CHECK([for HEVC encoding API], - [ac_cv_have_hevc_encoding_api], - [ - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include -#ifdef HAVE_VA_VA_ENC_HEVC_H -# include -#endif - ]], - [[ -VAEncSequenceParameterBufferHEVC seq_param; -VAEncPictureParameterBufferHEVC pic_param; -VAEncSliceParameterBufferHEVC buf_param; -VAQMatrixBufferHEVC q_matrix; - ]]) - ], - [ac_cv_have_hevc_encoding_api="yes"], - [ac_cv_have_hevc_encoding_api="no"]) - LIBS="$saved_LIBS" - ]) - AS_IF([test "x$ac_cv_have_hevc_encoding_api" = "xyes"], [USE_H265_ENCODER=1]) - - dnl Check for VP9 Encoding API + dnl Check for VP9 Encoding API (0.39.1+) AC_CHECK_HEADERS([va/va_enc_vp9.h], [], [], [ #include @@ -931,7 +605,7 @@ fi dnl VA/Wayland API if test $USE_WAYLAND -eq 1; then - PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= $VAAPI_WLD_REQ], + PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= $VAAPI_REQ], [], [USE_WAYLAND=0]) fi @@ -1019,18 +693,6 @@ AC_DEFINE_UNQUOTED([USE_ENCODERS], [$USE_ENCODERS], [Defined to 1 if video encoders are used]) AM_CONDITIONAL([USE_ENCODERS], [test $USE_ENCODERS -eq 1]) -AC_DEFINE_UNQUOTED([USE_JPEG_ENCODER], [$USE_JPEG_ENCODER], - [Defined to 1 if JPEG encoder is used]) -AM_CONDITIONAL([USE_JPEG_ENCODER], [test $USE_JPEG_ENCODER -eq 1]) - -AC_DEFINE_UNQUOTED([USE_VP8_ENCODER], [$USE_VP8_ENCODER], - [Defined to 1 if VP8 encoder is used]) -AM_CONDITIONAL([USE_VP8_ENCODER], [test $USE_VP8_ENCODER -eq 1]) - -AC_DEFINE_UNQUOTED([USE_H265_ENCODER], [$USE_H265_ENCODER], - [Defined to 1 if H265 encoder is used]) -AM_CONDITIONAL([USE_H265_ENCODER], [test $USE_H265_ENCODER -eq 1]) - AC_DEFINE_UNQUOTED([USE_VP9_ENCODER], [$USE_VP9_ENCODER], [Defined to 1 if VP9 encoder is used]) AM_CONDITIONAL([USE_VP9_ENCODER], [test $USE_VP9_ENCODER -eq 1]) @@ -1039,26 +701,6 @@ AC_DEFINE_UNQUOTED([USE_H264_FEI_ENCODER], [$USE_H264_FEI_ENCODER], [Defined to 1 if H264_FEI encoder is used]) AM_CONDITIONAL([USE_H264_FEI_ENCODER], [test $USE_H264_FEI_ENCODER -eq 1]) -AC_DEFINE_UNQUOTED([USE_VA_VPP], [$USE_VA_VPP], - [Defined to 1 if video post-processing is used]) -AM_CONDITIONAL([USE_VA_VPP], [test $USE_VA_VPP -eq 1]) - -AC_DEFINE_UNQUOTED([USE_JPEG_DECODER], [$USE_JPEG_DECODER], - [Defined to 1 if JPEG decoder is used]) -AM_CONDITIONAL([USE_JPEG_DECODER], [test $USE_JPEG_DECODER -eq 1]) - -AC_DEFINE_UNQUOTED([USE_VP8_DECODER], [$USE_VP8_DECODER], - [Defined to 1 if VP8 decoder is used]) -AM_CONDITIONAL([USE_VP8_DECODER], [test $USE_VP8_DECODER -eq 1]) - -AC_DEFINE_UNQUOTED([USE_VP9_DECODER], [$USE_VP9_DECODER], - [Defined to 1 if VP9 decoder is used]) -AM_CONDITIONAL([USE_VP9_DECODER], [test $USE_VP9_DECODER -eq 1]) - -AC_DEFINE_UNQUOTED([USE_H265_DECODER], [$USE_H265_DECODER], - [Defined to 1 if HEVC decoder is used]) -AM_CONDITIONAL([USE_H265_DECODER], [test $USE_H265_DECODER -eq 1]) - AC_DEFINE_UNQUOTED([USE_DRM], [$USE_DRM], [Defined to 1 if DRM is enabled]) AM_CONDITIONAL([USE_DRM], [test $USE_DRM -eq 1]) diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 54c138858f..976466e01d 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -148,31 +148,23 @@ libgstvaapi_source_priv_h = \ libgstvaapi_jpegdec_source_c = gstvaapidecoder_jpeg.c libgstvaapi_jpegdec_source_h = gstvaapidecoder_jpeg.h -if USE_JPEG_DECODER libgstvaapi_source_c += $(libgstvaapi_jpegdec_source_c) libgstvaapi_source_h += $(libgstvaapi_jpegdec_source_h) -endif libgstvaapi_vp8dec_source_c = gstvaapidecoder_vp8.c libgstvaapi_vp8dec_source_h = gstvaapidecoder_vp8.h -if USE_VP8_DECODER libgstvaapi_source_c += $(libgstvaapi_vp8dec_source_c) libgstvaapi_source_h += $(libgstvaapi_vp8dec_source_h) -endif libgstvaapi_hevcdec_source_c = gstvaapidecoder_h265.c libgstvaapi_hevcdec_source_h = gstvaapidecoder_h265.h -if USE_H265_DECODER libgstvaapi_source_c += $(libgstvaapi_hevcdec_source_c) libgstvaapi_source_h += $(libgstvaapi_hevcdec_source_h) -endif libgstvaapi_vp9dec_source_c = gstvaapidecoder_vp9.c libgstvaapi_vp9dec_source_h = gstvaapidecoder_vp9.h -if USE_VP9_DECODER libgstvaapi_source_c += $(libgstvaapi_vp9dec_source_c) libgstvaapi_source_h += $(libgstvaapi_vp9dec_source_h) -endif libgstvaapi_enc_source_c = \ gstvaapicodedbuffer.c \ @@ -180,8 +172,11 @@ libgstvaapi_enc_source_c = \ gstvaapicodedbufferproxy.c \ gstvaapiencoder.c \ gstvaapiencoder_h264.c \ + gstvaapiencoder_h265.c \ + gstvaapiencoder_jpeg.c \ gstvaapiencoder_mpeg2.c \ gstvaapiencoder_objects.c \ + gstvaapiencoder_vp8.c \ $(NULL) libgstvaapi_enc_source_h = \ @@ -190,7 +185,10 @@ libgstvaapi_enc_source_h = \ gstvaapicodedbufferproxy.h \ gstvaapiencoder.h \ gstvaapiencoder_h264.h \ + gstvaapiencoder_h265.h \ + gstvaapiencoder_jpeg.h \ gstvaapiencoder_mpeg2.h \ + gstvaapiencoder_vp8.h \ $(NULL) libgstvaapi_enc_source_priv_h = \ @@ -207,27 +205,6 @@ libgstvaapi_source_h += $(libgstvaapi_enc_source_h) libgstvaapi_source_priv_h += $(libgstvaapi_enc_source_priv_h) endif -libgstvaapi_jpegenc_source_c = gstvaapiencoder_jpeg.c -libgstvaapi_jpegenc_source_h = gstvaapiencoder_jpeg.h -if USE_JPEG_ENCODER -libgstvaapi_source_c += $(libgstvaapi_jpegenc_source_c) -libgstvaapi_source_h += $(libgstvaapi_jpegenc_source_h) -endif - -libgstvaapi_vp8enc_source_c = gstvaapiencoder_vp8.c -libgstvaapi_vp8enc_source_h = gstvaapiencoder_vp8.h -if USE_VP8_ENCODER -libgstvaapi_source_c += $(libgstvaapi_vp8enc_source_c) -libgstvaapi_source_h += $(libgstvaapi_vp8enc_source_h) -endif - -libgstvaapi_h265enc_source_c = gstvaapiencoder_h265.c -libgstvaapi_h265enc_source_h = gstvaapiencoder_h265.h -if USE_H265_ENCODER -libgstvaapi_source_c += $(libgstvaapi_h265enc_source_c) -libgstvaapi_source_h += $(libgstvaapi_h265enc_source_h) -endif - libgstvaapi_vp9enc_source_c = gstvaapiencoder_vp9.c libgstvaapi_vp9enc_source_h = gstvaapiencoder_vp9.h if USE_VP9_ENCODER @@ -535,12 +512,6 @@ EXTRA_DIST = \ $(libgstvaapi_hevcdec_source_priv_h) \ $(libgstvaapi_vp9dec_source_c) \ $(libgstvaapi_vp9dec_source_h) \ - $(libgstvaapi_jpegenc_source_h) \ - $(libgstvaapi_jpegenc_source_c) \ - $(libgstvaapi_vp8enc_source_h) \ - $(libgstvaapi_vp8enc_source_c) \ - $(libgstvaapi_h265enc_source_h) \ - $(libgstvaapi_h265enc_source_c) \ $(libgstvaapi_vp9enc_source_h) \ $(libgstvaapi_vp9enc_source_c) \ $(libgstvaapi_egl_source_c) \ diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index b4fc0b7d7c..7ec1e294ec 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -36,14 +36,12 @@ from_GstVaapiBufferMemoryType (guint type) guint va_type; switch (type) { -#if VA_CHECK_VERSION(0,36,0) case GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF: va_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; break; case GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF: va_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; break; -#endif default: va_type = 0; break; @@ -57,14 +55,12 @@ to_GstVaapiBufferMemoryType (guint va_type) guint type; switch (va_type) { -#if VA_CHECK_VERSION(0,36,0) case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: type = GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF; break; case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: type = GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF; break; -#endif default: type = 0; break; @@ -72,7 +68,6 @@ to_GstVaapiBufferMemoryType (guint va_type) return type; } -#if VA_CHECK_VERSION (0,36,0) static gboolean gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) { @@ -96,7 +91,6 @@ gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) return TRUE; } -/* VA_CHECK_VERSION (0,36,0) */ static gboolean gst_vaapi_buffer_proxy_release_handle (GstVaapiBufferProxy * proxy) { @@ -117,7 +111,6 @@ gst_vaapi_buffer_proxy_release_handle (GstVaapiBufferProxy * proxy) return TRUE; } -/* VA_CHECK_VERSION (0,36,0) */ static void gst_vaapi_buffer_proxy_finalize (GstVaapiBufferProxy * proxy) { @@ -135,7 +128,6 @@ gst_vaapi_buffer_proxy_finalize (GstVaapiBufferProxy * proxy) gst_vaapi_object_replace (&proxy->parent, NULL); } -/* VA_CHECK_VERSION (0,36,0) */ static inline const GstVaapiMiniObjectClass * gst_vaapi_buffer_proxy_class (void) { @@ -145,13 +137,11 @@ gst_vaapi_buffer_proxy_class (void) }; return &GstVaapiBufferProxyClass; } -#endif GstVaapiBufferProxy * gst_vaapi_buffer_proxy_new (guintptr handle, guint type, gsize size, GDestroyNotify destroy_func, gpointer user_data) { -#if VA_CHECK_VERSION (0,36,0) GstVaapiBufferProxy *proxy; g_return_val_if_fail (handle != 0, NULL); @@ -183,16 +173,12 @@ error_unsupported_mem_type: gst_vaapi_buffer_proxy_unref (proxy); return NULL; } -#else - return NULL; -#endif } GstVaapiBufferProxy * gst_vaapi_buffer_proxy_new_from_object (GstVaapiObject * object, VABufferID buf_id, guint type, GDestroyNotify destroy_func, gpointer data) { -#if VA_CHECK_VERSION (0,36,0) GstVaapiBufferProxy *proxy; g_return_val_if_fail (object != NULL, NULL); @@ -229,9 +215,6 @@ error_acquire_handle: gst_vaapi_buffer_proxy_unref (proxy); return NULL; } -#else - return NULL; -#endif } /** @@ -314,11 +297,7 @@ gst_vaapi_buffer_proxy_get_handle (GstVaapiBufferProxy * proxy) { g_return_val_if_fail (proxy != NULL, 0); -#if VA_CHECK_VERSION (0,36,0) return GST_VAAPI_BUFFER_PROXY_HANDLE (proxy); -#else - return 0; -#endif } /** @@ -334,11 +313,7 @@ gst_vaapi_buffer_proxy_get_size (GstVaapiBufferProxy * proxy) { g_return_val_if_fail (proxy != NULL, 0); -#if VA_CHECK_VERSION (0,36,0) return GST_VAAPI_BUFFER_PROXY_SIZE (proxy); -#else - return 0; -#endif } /** diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h index 39893e687b..d0fb9a231d 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h @@ -68,9 +68,7 @@ struct _GstVaapiBufferProxy { gpointer destroy_data; guint type; VABufferID va_buf; -#if VA_CHECK_VERSION (0,36,0) VABufferInfo va_info; -#endif GstMemory *mem; }; diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index 29f1b7a8d5..e66d2fe7fb 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -177,7 +177,6 @@ gst_vaapi_bitplane_new (GstVaapiDecoder * decoder, guint8 * data, /* --- JPEG Huffman Tables --- */ /* ------------------------------------------------------------------------- */ -#if USE_JPEG_DECODER GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiHuffmanTable, gst_vaapi_huffman_table); void @@ -209,8 +208,7 @@ gst_vaapi_huffman_table_new (GstVaapiDecoder * decoder, return NULL; return GST_VAAPI_HUFFMAN_TABLE_CAST (object); } -#endif -#if USE_VP8_DECODER + GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiProbabilityTable, gst_vaapi_probability_table); @@ -244,5 +242,3 @@ gst_vaapi_probability_table_new (GstVaapiDecoder * decoder, return NULL; return GST_VAAPI_PROBABILITY_TABLE_CAST (object); } - -#endif diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index b87df0ebb8..f75a9eaec1 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -27,16 +27,6 @@ #include -/* Compatibility glue with VA-API < 0.31 */ -#if !VA_CHECK_VERSION(0,31,0) -#undef vaSyncSurface -#define vaSyncSurface(dpy, s) (vaSyncSurface)((dpy), VA_INVALID_ID, (s)) -#undef vaPutImage -#define vaPutImage vaPutImage2 -#undef vaAssociateSubpicture -#define vaAssociateSubpicture vaAssociateSubpicture2 -#endif - #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 @@ -45,50 +35,7 @@ #define VA_ENC_PACKED_HEADER_H264_SEI VAEncPackedHeaderH264_SEI #endif -/* Compatibility glue with VA-API 0.34 */ -#if VA_CHECK_VERSION(0,34,0) -# include -#endif - -#if VA_CHECK_VERSION(0,36,0) +#include #include -#endif - -/* VA-API < 0.37 doesn't include sub core APIs in va.h */ -#if !VA_CHECK_VERSION(0,37,0) -#ifdef HAVE_VA_VA_DEC_HEVC_H -# include -#endif -#ifdef HAVE_VA_VA_DEC_JPEG_H -# include -#endif -#ifdef HAVE_VA_VA_DEC_VP8_H -# include -#endif -#ifdef HAVE_VA_VA_DEC_VP9_H -# include -#endif -#ifdef HAVE_VA_VA_ENC_HEVC_H -# include -#endif -#ifdef HAVE_VA_VA_ENC_H264_H -# include -#endif -#ifdef HAVE_VA_VA_ENC_JPEG_H -# include -#endif -#ifdef HAVE_VA_VA_ENC_MPEG2_H -# include -#endif -#ifdef HAVE_VA_VA_ENC_VP8_H -# include -#endif -#ifdef HAVE_VA_VA_ENC_VP9_H -# include -#endif -#ifdef HAVE_VA_VA_VPP_H -# include -#endif -#endif #endif /* GST_VAAPI_COMPAT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index de9a7e8074..006acb4bf7 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -302,7 +302,6 @@ config_create (GstVaapiContext * context) attrib = &attribs[++attrib_index]; g_assert (attrib_index < G_N_ELEMENTS (attribs)); } -#if VA_CHECK_VERSION(0,37,0) if (cip->profile == GST_VAAPI_PROFILE_JPEG_BASELINE) { attrib->type = VAConfigAttribEncJPEG; if (!context_get_attribute (context, attrib->type, &value)) @@ -311,7 +310,6 @@ config_create (GstVaapiContext * context) attrib = &attribs[++attrib_index]; g_assert (attrib_index < G_N_ELEMENTS (attribs)); } -#endif #if VA_CHECK_VERSION(0,39,1) if (config->roi_capability) { VAConfigAttribValEncROI *roi_config; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 5f2d4a27a3..3d8e39f50c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -532,7 +532,6 @@ ensure_profiles (GstVaapiDisplay * display) g_array_sort (priv->encoders, compare_profiles); /* Video processing API */ -#if USE_VA_VPP status = vaQueryConfigEntrypoints (priv->display, VAProfileNone, entrypoints, &num_entrypoints); if (vaapi_check_status (status, "vaQueryEntrypoints() [VAProfileNone]")) { @@ -541,7 +540,6 @@ ensure_profiles (GstVaapiDisplay * display) priv->has_vpp = TRUE; } } -#endif success = TRUE; cleanup: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index ef72b5906c..f31181e7f9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -289,7 +289,6 @@ gst_vaapi_enc_q_matrix_new (GstVaapiEncoder * encoder, /* --- JPEG Huffman Tables --- */ /* ------------------------------------------------------------------------- */ -#if USE_JPEG_ENCODER GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncHuffmanTable, gst_vaapi_enc_huffman_table); @@ -322,7 +321,6 @@ gst_vaapi_enc_huffman_table_new (GstVaapiEncoder * encoder, return NULL; return GST_VAAPI_ENC_HUFFMAN_TABLE_CAST (object); } -#endif /* ------------------------------------------------------------------------- */ /* --- Encoder Picture --- */ diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 304272f806..5f25b373de 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -125,14 +125,12 @@ gst_vaapi_deinterlace_method_get_type (void) "Disable deinterlacing", "none"}, {GST_VAAPI_DEINTERLACE_METHOD_BOB, "Bob deinterlacing", "bob"}, -#if USE_VA_VPP {GST_VAAPI_DEINTERLACE_METHOD_WEAVE, "Weave deinterlacing", "weave"}, {GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE, "Motion adaptive deinterlacing", "motion-adaptive"}, {GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED, "Motion compensated deinterlacing", "motion-compensated"}, -#endif {0, NULL, NULL}, }; @@ -171,7 +169,6 @@ gst_vaapi_deinterlace_flags_get_type (void) /* --- VPP Helpers --- */ /* ------------------------------------------------------------------------- */ -#if USE_VA_VPP static VAProcFilterType * vpp_get_filters_unlocked (GstVaapiFilter * filter, guint * num_filters_ptr) { @@ -273,13 +270,11 @@ vpp_get_filter_caps (GstVaapiFilter * filter, VAProcFilterType type, GST_VAAPI_DISPLAY_UNLOCK (filter->display); return caps; } -#endif /* ------------------------------------------------------------------------- */ /* --- VPP Operations --- */ /* ------------------------------------------------------------------------- */ -#if USE_VA_VPP #define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN #define DEFAULT_SCALING GST_VAAPI_SCALE_METHOD_DEFAULT @@ -425,7 +420,6 @@ init_properties (void) GST_VAAPI_TYPE_SCALE_METHOD, DEFAULT_SCALING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); -#if VA_CHECK_VERSION(0,36,0) /** * GstVaapiFilter:skin-tone-enhancement: * @@ -435,7 +429,6 @@ init_properties (void) "Skin tone enhancement", "Apply the skin tone enhancement algorithm", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); -#endif } static void @@ -484,12 +477,10 @@ op_data_new (GstVaapiFilterOp op, GParamSpec * pspec) op_data->va_cap_size = sizeof (VAProcFilterCap); op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer); break; -#if VA_CHECK_VERSION(0,36,0) case GST_VAAPI_FILTER_OP_SKINTONE: op_data->va_type = VAProcFilterSkinToneEnhancement; op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer); break; -#endif case GST_VAAPI_FILTER_OP_HUE: op_data->va_subtype = VAProcColorBalanceHue; goto op_colorbalance; @@ -715,14 +706,12 @@ error: return NULL; } } -#endif /* Determine the set of supported VPP operations by the specific filter, or known to this library if filter is NULL */ static GPtrArray * get_operations (GstVaapiFilter * filter) { -#if USE_VA_VPP GPtrArray *ops; if (filter && filter->operations) @@ -732,8 +721,6 @@ get_operations (GstVaapiFilter * filter) if (!ops) return NULL; return filter ? get_operations_ordered (filter, ops) : ops; -#endif - return NULL; } /* Ensure the set of supported VPP operations is cached into the @@ -776,7 +763,6 @@ find_operation (GstVaapiFilter * filter, GstVaapiFilterOp op) } /* Ensure the operation's VA buffer is allocated */ -#if USE_VA_VPP static inline gboolean op_ensure_buffer (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data) { @@ -786,10 +772,8 @@ op_ensure_buffer (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data) VAProcFilterParameterBufferType, op_data->va_buffer_size, NULL, &op_data->va_buffer, NULL); } -#endif /* Update a generic filter (float value) */ -#if USE_VA_VPP static gboolean op_set_generic_unlocked (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, gfloat value) @@ -819,7 +803,6 @@ op_set_generic_unlocked (GstVaapiFilter * filter, vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL); return TRUE; } -#endif static inline gboolean op_set_generic (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, @@ -827,16 +810,13 @@ op_set_generic (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, { gboolean success = FALSE; -#if USE_VA_VPP GST_VAAPI_DISPLAY_LOCK (filter->display); success = op_set_generic_unlocked (filter, op_data, value); GST_VAAPI_DISPLAY_UNLOCK (filter->display); -#endif return success; } /* Update the color balance filter */ -#if USE_VA_VPP static gboolean op_set_color_balance_unlocked (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, gfloat value) @@ -867,7 +847,6 @@ op_set_color_balance_unlocked (GstVaapiFilter * filter, vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL); return TRUE; } -#endif static inline gboolean op_set_color_balance (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, @@ -875,16 +854,13 @@ op_set_color_balance (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, { gboolean success = FALSE; -#if USE_VA_VPP GST_VAAPI_DISPLAY_LOCK (filter->display); success = op_set_color_balance_unlocked (filter, op_data, value); GST_VAAPI_DISPLAY_UNLOCK (filter->display); -#endif return success; } /* Update deinterlace filter */ -#if USE_VA_VPP static gboolean op_set_deinterlace_unlocked (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, GstVaapiDeinterlaceMethod method, @@ -920,7 +896,6 @@ op_set_deinterlace_unlocked (GstVaapiFilter * filter, vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL); return TRUE; } -#endif static inline gboolean op_set_deinterlace (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, @@ -928,16 +903,13 @@ op_set_deinterlace (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, { gboolean success = FALSE; -#if USE_VA_VPP GST_VAAPI_DISPLAY_LOCK (filter->display); success = op_set_deinterlace_unlocked (filter, op_data, method, flags); GST_VAAPI_DISPLAY_UNLOCK (filter->display); -#endif return success; } /* Update skin tone enhancement */ -#if USE_VA_VPP static gboolean op_set_skintone_unlocked (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, gboolean value) @@ -959,7 +931,6 @@ op_set_skintone_unlocked (GstVaapiFilter * filter, vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL); return TRUE; } -#endif static inline gboolean op_set_skintone (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, @@ -967,11 +938,9 @@ op_set_skintone (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, { gboolean success = FALSE; -#if USE_VA_VPP GST_VAAPI_DISPLAY_LOCK (filter->display); success = op_set_skintone_unlocked (filter, op_data, enhance); GST_VAAPI_DISPLAY_UNLOCK (filter->display); -#endif return success; } @@ -1044,7 +1013,6 @@ find_format (GstVaapiFilter * filter, GstVideoFormat format) /* --- Interface --- */ /* ------------------------------------------------------------------------- */ -#if USE_VA_VPP static void gst_vaapi_filter_init (GstVaapiFilter * filter) { @@ -1185,7 +1153,6 @@ gst_vaapi_filter_class_init (GstVaapiFilterClass * klass) "The VA-API display object to use", GST_TYPE_VAAPI_DISPLAY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME)); } -#endif /** * gst_vaapi_filter_new: @@ -1199,7 +1166,6 @@ gst_vaapi_filter_class_init (GstVaapiFilterClass * klass) GstVaapiFilter * gst_vaapi_filter_new (GstVaapiDisplay * display) { -#if USE_VA_VPP GstVaapiFilter *filter; filter = g_object_new (GST_TYPE_VAAPI_FILTER, "display", display, NULL); @@ -1213,11 +1179,6 @@ error: gst_object_unref (filter); return NULL; } -#else - GST_WARNING ("video processing is not supported, " - "please consider an upgrade to VA-API >= 0.34"); - return NULL; -#endif } /** @@ -1327,7 +1288,6 @@ gboolean gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, const GValue * value) { -#if USE_VA_VPP GstVaapiFilterOpData *op_data; g_return_val_if_fail (filter != NULL, FALSE); @@ -1373,7 +1333,6 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, default: break; } -#endif return FALSE; } @@ -1396,7 +1355,6 @@ static GstVaapiFilterStatus gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, GstVaapiSurface * src_surface, GstVaapiSurface * dst_surface, guint flags) { -#if USE_VA_VPP VAProcPipelineParameterBuffer *pipeline_param = NULL; VABufferID pipeline_param_buf_id = VA_INVALID_ID; VABufferID filters[N_PROPERTIES]; @@ -1536,8 +1494,6 @@ error: vaapi_destroy_buffer (filter->va_display, &pipeline_param_buf_id); return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED; } -#endif - return GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_OPERATION; } GstVaapiFilterStatus @@ -1886,11 +1842,8 @@ static inline gfloat op_get_float_default_value (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data) { -#if USE_VA_VPP GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (op_data->pspec); return pspec->default_value; -#endif - return 0.0; } gfloat diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index cc87096e76..1e036c639f 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -89,49 +89,37 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-divx, divxversion=5", "advanced-simple"}, {GST_VAAPI_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple, "video/x-xvid", "advanced-simple"}, -#if VA_CHECK_VERSION(0,30,0) {GST_VAAPI_PROFILE_H263_BASELINE, VAProfileH263Baseline, "video/x-h263, variant=itu, h263version=h263", "baseline"}, -#endif #if !VA_CHECK_VERSION(1,0,0) {GST_VAAPI_PROFILE_H264_BASELINE, VAProfileH264Baseline, "video/x-h264", "baseline"}, #endif -#if VA_CHECK_VERSION(0,31,1) {GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE, VAProfileH264ConstrainedBaseline, "video/x-h264", "constrained-baseline"}, -#endif {GST_VAAPI_PROFILE_H264_MAIN, VAProfileH264Main, "video/x-h264", "main"}, {GST_VAAPI_PROFILE_H264_HIGH, VAProfileH264High, "video/x-h264", "high"}, -#if VA_CHECK_VERSION(0,35,2) {GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH, VAProfileH264MultiviewHigh, "video/x-h264", "multiview-high"}, {GST_VAAPI_PROFILE_H264_STEREO_HIGH, VAProfileH264StereoHigh, "video/x-h264", "stereo-high"}, -#endif {GST_VAAPI_PROFILE_VC1_SIMPLE, VAProfileVC1Simple, "video/x-wmv, wmvversion=3", "simple"}, {GST_VAAPI_PROFILE_VC1_MAIN, VAProfileVC1Main, "video/x-wmv, wmvversion=3", "main"}, {GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced, "video/x-wmv, wmvversion=3, format=(string)WVC1", "advanced"}, -#if VA_CHECK_VERSION(0,32,0) {GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline, "image/jpeg", NULL}, -#endif -#if VA_CHECK_VERSION(0,35,0) {GST_VAAPI_PROFILE_VP8, VAProfileVP8Version0_3, "video/x-vp8", NULL}, -#endif -#if VA_CHECK_VERSION(0,37,0) {GST_VAAPI_PROFILE_H265_MAIN, VAProfileHEVCMain, "video/x-h265", "main"}, {GST_VAAPI_PROFILE_H265_MAIN10, VAProfileHEVCMain10, "video/x-h265", "main-10"}, -#endif #if VA_CHECK_VERSION(1,2,0) {GST_VAAPI_PROFILE_H265_MAIN_422_10, VAProfileHEVCMain422_10, "video/x-h265", "main-422-10"}, @@ -140,18 +128,14 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { {GST_VAAPI_PROFILE_H265_MAIN_444_10, VAProfileHEVCMain444_10, "video/x-h265", "main-444-10"}, #endif -#if VA_CHECK_VERSION(0,38,0) {GST_VAAPI_PROFILE_VP9_0, VAProfileVP9Profile0, "video/x-vp9", "profile0"}, -#endif -#if VA_CHECK_VERSION(0,39,0) {GST_VAAPI_PROFILE_VP9_1, VAProfileVP9Profile1, "video/x-vp9", "profile1"}, {GST_VAAPI_PROFILE_VP9_2, VAProfileVP9Profile2, "video/x-vp9", "profile2"}, {GST_VAAPI_PROFILE_VP9_3, VAProfileVP9Profile3, "video/x-vp9", "profile3"}, -#endif {0,} }; @@ -160,10 +144,8 @@ static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = { {GST_VAAPI_ENTRYPOINT_VLD, VAEntrypointVLD}, {GST_VAAPI_ENTRYPOINT_IDCT, VAEntrypointIDCT}, {GST_VAAPI_ENTRYPOINT_MOCO, VAEntrypointMoComp}, -#if VA_CHECK_VERSION(0,30,0) {GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, VAEntrypointEncSlice}, {GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, VAEntrypointEncPicture}, -#endif #if VA_CHECK_VERSION(0,39,1) {GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP, VAEntrypointEncSliceLP}, #endif diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 40d98745ca..482c9b6348 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -132,7 +132,6 @@ static gboolean gst_vaapi_surface_create_full (GstVaapiSurface * surface, const GstVideoInfo * vip, guint flags) { -#if VA_CHECK_VERSION(0,34,0) GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (vip); VASurfaceID surface_id; @@ -219,16 +218,12 @@ error_unsupported_format: GST_ERROR ("unsupported format %s", gst_vaapi_video_format_to_string (format)); return FALSE; -#else - return FALSE; -#endif } static gboolean gst_vaapi_surface_create_from_buffer_proxy (GstVaapiSurface * surface, GstVaapiBufferProxy * proxy, const GstVideoInfo * vip) { -#if VA_CHECK_VERSION (0,36,0) GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); GstVideoFormat format; VASurfaceID surface_id; @@ -308,9 +303,6 @@ error_unsupported_format: GST_ERROR ("unsupported format %s", gst_vaapi_video_format_to_string (format)); return FALSE; -#else - return FALSE; -#endif } #define gst_vaapi_surface_finalize gst_vaapi_surface_destroy @@ -387,7 +379,6 @@ gst_vaapi_surface_new (GstVaapiDisplay * display, /* first try a recent version of vaCreateSurface, and later use as * fallback its old version */ -#if VA_CHECK_VERSION(0,34,0) { GstVideoInfo vi; GstVideoFormat surface_format; @@ -398,7 +389,6 @@ gst_vaapi_surface_new (GstVaapiDisplay * display, if (gst_vaapi_surface_create_full (surface, &vi, 0)) return surface; } -#endif if (!gst_vaapi_surface_create (surface, chroma_type, width, height)) goto error; return surface; diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 414ae129ac..02a4535061 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -214,42 +214,30 @@ string_of_VAProfile (VAProfile profile) MAP (MPEG4Simple); MAP (MPEG4AdvancedSimple); MAP (MPEG4Main); -#if VA_CHECK_VERSION(0,32,0) MAP (JPEGBaseline); MAP (H263Baseline); MAP (H264ConstrainedBaseline); -#endif #if !VA_CHECK_VERSION(1,0,0) MAP (H264Baseline); #endif MAP (H264Main); MAP (H264High); -#if VA_CHECK_VERSION(0,35,2) MAP (H264MultiviewHigh); MAP (H264StereoHigh); -#endif #if VA_CHECK_VERSION(1,2,0) MAP (HEVCMain422_10); MAP (HEVCMain444); #endif -#if VA_CHECK_VERSION(0,37,1) MAP (HEVCMain); MAP (HEVCMain10); -#endif MAP (VC1Simple); MAP (VC1Main); MAP (VC1Advanced); -#if VA_CHECK_VERSION(0,35,0) MAP (VP8Version0_3); -#endif -#if VA_CHECK_VERSION(0,37,0) MAP (VP9Profile0); -#endif -#if VA_CHECK_VERSION(0,39,0) MAP (VP9Profile1); MAP (VP9Profile2); MAP (VP9Profile3); -#endif #undef MAP default: break; @@ -288,17 +276,8 @@ string_of_VADisplayAttributeType (VADisplayAttribType attribute_type) MAP (Hue); MAP (Saturation); MAP (BackgroundColor); -#if !VA_CHECK_VERSION(0,34,0) - MAP (DirectSurface); -#endif MAP (Rotation); MAP (OutofLoopDeblock); -#if VA_CHECK_VERSION(0,31,1) && !VA_CHECK_VERSION(0,34,0) - MAP (BLEBlackMode); - MAP (BLEWhiteMode); - MAP (BlueStretch); - MAP (SkinColorCorrection); -#endif MAP (CSCMatrix); MAP (BlendColor); MAP (OverlayAutoPaintColorKey); @@ -323,15 +302,11 @@ string_of_va_chroma_format (guint chroma_format) MAP (YUV420); MAP (YUV422); MAP (YUV444); -#if VA_CHECK_VERSION(0,34,0) MAP (YUV400); MAP (RGB16); MAP (RGB32); MAP (RGBP); -#endif -#if VA_CHECK_VERSION(0,38,1) MAP (YUV420_10BPP); -#endif #if VA_CHECK_VERSION(1,2,0) MAP (YUV422_10); MAP (YUV444_10); @@ -397,7 +372,6 @@ to_GstVaapiChromaType (guint va_rt_format) case VA_RT_FORMAT_YUV444: chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; break; -#if VA_CHECK_VERSION(0,34,0) case VA_RT_FORMAT_YUV411: chroma_type = GST_VAAPI_CHROMA_TYPE_YUV411; break; @@ -413,12 +387,9 @@ to_GstVaapiChromaType (guint va_rt_format) case VA_RT_FORMAT_RGBP: chroma_type = GST_VAAPI_CHROMA_TYPE_RGBP; break; -#endif -#if VA_CHECK_VERSION(0,38,1) case VA_RT_FORMAT_YUV420_10BPP: chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; break; -#endif #if VA_CHECK_VERSION(1,2,0) case VA_RT_FORMAT_YUV422_10: chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_10BPP; @@ -468,7 +439,6 @@ from_GstVaapiChromaType (guint chroma_type) case GST_VAAPI_CHROMA_TYPE_YUV444: format = VA_RT_FORMAT_YUV444; break; -#if VA_CHECK_VERSION(0,34,0) case GST_VAAPI_CHROMA_TYPE_YUV411: format = VA_RT_FORMAT_YUV411; break; @@ -484,12 +454,9 @@ from_GstVaapiChromaType (guint chroma_type) case GST_VAAPI_CHROMA_TYPE_RGBP: format = VA_RT_FORMAT_RGBP; break; -#endif -#if VA_CHECK_VERSION(0,38,1) case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: format = VA_RT_FORMAT_YUV420_10BPP; break; -#endif #if VA_CHECK_VERSION(1,2,0) case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: format = VA_RT_FORMAT_YUV422_10; @@ -683,10 +650,8 @@ to_GstVaapiSurfaceStatus (guint va_flags) } /* Check for encoder status */ -#if VA_CHECK_VERSION(0,30,0) if (va_flags & VASurfaceSkipped) flags |= GST_VAAPI_SURFACE_STATUS_SKIPPED; -#endif return flags; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.c b/gst-libs/gst/vaapi/gstvaapiutils_core.c index e1e76b810b..20746667d9 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_core.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.c @@ -92,7 +92,6 @@ gst_vaapi_get_config_attribute (GstVaapiDisplay * display, VAProfile profile, GArray * gst_vaapi_get_surface_formats (GstVaapiDisplay * display, VAConfigID config) { -#if VA_CHECK_VERSION(0,34,0) VASurfaceAttrib *surface_attribs = NULL; guint i, num_surface_attribs = 0; VAStatus va_status; @@ -152,6 +151,5 @@ error: { g_free (surface_attribs); } -#endif return NULL; } diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 948937f2db..4515d5581a 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -6,11 +6,15 @@ gstlibvaapi_sources = [ 'gstvaapidecoder.c', 'gstvaapidecoder_dpb.c', 'gstvaapidecoder_h264.c', + 'gstvaapidecoder_h265.c', + 'gstvaapidecoder_jpeg.c', 'gstvaapidecoder_mpeg2.c', 'gstvaapidecoder_mpeg4.c', 'gstvaapidecoder_objects.c', 'gstvaapidecoder_unit.c', 'gstvaapidecoder_vc1.c', + 'gstvaapidecoder_vp8.c', + 'gstvaapidecoder_vp9.c', 'gstvaapidisplay.c', 'gstvaapifilter.c', 'gstvaapiimage.c', @@ -44,9 +48,12 @@ gstlibvaapi_headers = [ 'gstvaapidecoder.h', 'gstvaapidecoder_h264.h', 'gstvaapidecoder_h265.h', + 'gstvaapidecoder_jpeg.h', 'gstvaapidecoder_mpeg2.h', 'gstvaapidecoder_mpeg4.h', 'gstvaapidecoder_vc1.h', + 'gstvaapidecoder_vp8.h', + 'gstvaapidecoder_vp9.h', 'gstvaapidisplay.h', 'gstvaapifilter.h', 'gstvaapiimage.h', @@ -71,26 +78,6 @@ gstlibvaapi_headers = [ 'video-format.h', ] -if USE_JPEG_DECODER - gstlibvaapi_sources += 'gstvaapidecoder_jpeg.c' - gstlibvaapi_headers += 'gstvaapidecoder_jpeg.h' -endif - -if USE_VP8_DECODER - gstlibvaapi_sources += 'gstvaapidecoder_vp8.c' - gstlibvaapi_headers += 'gstvaapidecoder_vp8.h' -endif - -if USE_H265_DECODER - gstlibvaapi_sources += 'gstvaapidecoder_h265.c' - gstlibvaapi_headers += 'gstvaapidecoder_h265.h' -endif - -if USE_VP9_DECODER - gstlibvaapi_sources += 'gstvaapidecoder_vp9.c' - gstlibvaapi_headers += 'gstvaapidecoder_vp9.h' -endif - if USE_ENCODERS gstlibvaapi_sources += [ 'gstvaapicodedbuffer.c', @@ -98,8 +85,11 @@ if USE_ENCODERS 'gstvaapicodedbufferproxy.c', 'gstvaapiencoder.c', 'gstvaapiencoder_h264.c', + 'gstvaapiencoder_h265.c', + 'gstvaapiencoder_jpeg.c', 'gstvaapiencoder_mpeg2.c', 'gstvaapiencoder_objects.c', + 'gstvaapiencoder_vp8.c', ] gstlibvaapi_headers += [ 'gstvaapicodedbuffer.h', @@ -107,25 +97,13 @@ if USE_ENCODERS 'gstvaapicodedbufferproxy.h', 'gstvaapiencoder.h', 'gstvaapiencoder_h264.h', + 'gstvaapiencoder_h265.h', + 'gstvaapiencoder_jpeg.h', 'gstvaapiencoder_mpeg2.h', + 'gstvaapiencoder_vp8.h', ] endif -if USE_JPEG_ENCODER - gstlibvaapi_sources += 'gstvaapiencoder_jpeg.c' - gstlibvaapi_headers += 'gstvaapiencoder_jpeg.h' -endif - -if USE_VP8_ENCODER - gstlibvaapi_sources += 'gstvaapiencoder_vp8.c' - gstlibvaapi_headers += 'gstvaapiencoder_vp8.h' -endif - -if USE_H265_ENCODER - gstlibvaapi_sources += 'gstvaapiencoder_h265.c' - gstlibvaapi_headers += 'gstvaapiencoder_h265.h' -endif - if USE_VP9_ENCODER gstlibvaapi_sources += 'gstvaapiencoder_vp9.c' gstlibvaapi_headers += 'gstvaapiencoder_vp9.h' diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index b299ac98a2..a829c914e7 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -81,13 +81,19 @@ libgstvaapi_source_h = \ libgstvaapi_enc_source_c = \ gstvaapiencode.c \ gstvaapiencode_h264.c \ + gstvaapiencode_h265.c \ + gstvaapiencode_jpeg.c \ gstvaapiencode_mpeg2.c \ + gstvaapiencode_vp8.c \ $(NULL) libgstvaapi_enc_source_h = \ gstvaapiencode.h \ gstvaapiencode_h264.h \ + gstvaapiencode_h265.h \ + gstvaapiencode_jpeg.h \ gstvaapiencode_mpeg2.h \ + gstvaapiencode_vp8.h \ $(NULL) if USE_ENCODERS @@ -95,27 +101,6 @@ libgstvaapi_source_c += $(libgstvaapi_enc_source_c) libgstvaapi_source_h += $(libgstvaapi_enc_source_h) endif -libgstvaapi_jpegenc_source_c = gstvaapiencode_jpeg.c -libgstvaapi_jpegenc_source_h = gstvaapiencode_jpeg.h -if USE_JPEG_ENCODER -libgstvaapi_source_c += $(libgstvaapi_jpegenc_source_c) -libgstvaapi_source_h += $(libgstvaapi_jpegenc_source_h) -endif - -libgstvaapi_vp8enc_source_c = gstvaapiencode_vp8.c -libgstvaapi_vp8enc_source_h = gstvaapiencode_vp8.h -if USE_VP8_ENCODER -libgstvaapi_source_c += $(libgstvaapi_vp8enc_source_c) -libgstvaapi_source_h += $(libgstvaapi_vp8enc_source_h) -endif - -libgstvaapi_h265enc_source_c = gstvaapiencode_h265.c -libgstvaapi_h265enc_source_h = gstvaapiencode_h265.h -if USE_H265_ENCODER -libgstvaapi_source_c += $(libgstvaapi_h265enc_source_c) -libgstvaapi_source_h += $(libgstvaapi_h265enc_source_h) -endif - libgstvaapi_vp9enc_source_c = gstvaapiencode_vp9.c libgstvaapi_vp9enc_source_h = gstvaapiencode_vp9.h if USE_VP9_ENCODER @@ -168,12 +153,6 @@ libgstvaapi_la_LIBTOOLFLAGS = --tag=disable-static EXTRA_DIST = \ $(libgstvaapi_enc_source_c) \ $(libgstvaapi_enc_source_h) \ - $(libgstvaapi_jpegenc_source_c) \ - $(libgstvaapi_jpegenc_source_h) \ - $(libgstvaapi_vp8enc_source_c) \ - $(libgstvaapi_vp8enc_source_h) \ - $(libgstvaapi_h265enc_source_c) \ - $(libgstvaapi_h265enc_source_h) \ $(libgstvaapi_vp9enc_source_c) \ $(libgstvaapi_vp9enc_source_h) \ $(libgstvaapi_h264feienc_source_c) \ diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 7b0066469e..43571f084c 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -31,18 +31,9 @@ #if USE_ENCODERS #include "gstvaapiencode_h264.h" #include "gstvaapiencode_mpeg2.h" - -#if USE_JPEG_ENCODER #include "gstvaapiencode_jpeg.h" -#endif - -#if USE_VP8_ENCODER #include "gstvaapiencode_vp8.h" -#endif - -#if USE_H265_ENCODER #include "gstvaapiencode_h265.h" -#endif #if USE_VP9_ENCODER #include "gstvaapiencode_vp9.h" @@ -155,18 +146,12 @@ struct _GstVaapiEncoderMap static const GstVaapiEncoderMap vaapi_encode_map[] = { DEF_ENC (H264, h264), DEF_ENC (MPEG2, mpeg2), -#if USE_JPEG_ENCODER DEF_ENC (JPEG, jpeg), -#endif -#if USE_VP8_ENCODER DEF_ENC (VP8, vp8), -#endif #if USE_VP9_ENCODER DEF_ENC (VP9, vp9), #endif -#if USE_H265_ENCODER DEF_ENC (H265, h265), -#endif }; #undef DEF_ENC diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b6d917aa7f..cd3624d8d1 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -70,16 +70,10 @@ static const char gst_vaapidecode_sink_caps_str[] = GST_CAPS_CODEC("video/x-xvid") GST_CAPS_CODEC("video/x-h263") GST_CAPS_CODEC("video/x-h264") -#if USE_H265_DECODER GST_CAPS_CODEC("video/x-h265") -#endif GST_CAPS_CODEC("video/x-wmv") -#if USE_VP8_DECODER GST_CAPS_CODEC("video/x-vp8") -#endif -#if USE_VP9_DECODER GST_CAPS_CODEC("video/x-vp9") -#endif ; static const char gst_vaapidecode_src_caps_str[] = @@ -110,9 +104,7 @@ struct _GstVaapiDecoderMap }; static const GstVaapiDecoderMap vaapi_decode_map[] = { -#if USE_JPEG_DECODER {GST_VAAPI_CODEC_JPEG, GST_RANK_MARGINAL, "jpeg", "image/jpeg", NULL}, -#endif {GST_VAAPI_CODEC_MPEG2, GST_RANK_PRIMARY, "mpeg2", "video/mpeg, mpegversion=2, systemstream=(boolean)false", NULL}, {GST_VAAPI_CODEC_MPEG4, GST_RANK_PRIMARY, "mpeg4", @@ -122,15 +114,9 @@ static const GstVaapiDecoderMap vaapi_decode_map[] = { gst_vaapi_decode_h264_install_properties}, {GST_VAAPI_CODEC_VC1, GST_RANK_PRIMARY, "vc1", "video/x-wmv, wmvversion=3, format={WMV3,WVC1}", NULL}, -#if USE_VP8_DECODER {GST_VAAPI_CODEC_VP8, GST_RANK_PRIMARY, "vp8", "video/x-vp8", NULL}, -#endif -#if USE_VP9_DECODER {GST_VAAPI_CODEC_VP9, GST_RANK_PRIMARY, "vp9", "video/x-vp9", NULL}, -#endif -#if USE_H265_DECODER {GST_VAAPI_CODEC_H265, GST_RANK_PRIMARY, "h265", "video/x-h265", NULL}, -#endif {0 /* the rest */ , GST_RANK_PRIMARY + 1, NULL, gst_vaapidecode_sink_caps_str, NULL}, }; @@ -923,7 +909,6 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) } } break; -#if USE_H265_DECODER case GST_VAAPI_CODEC_H265: decode->decoder = gst_vaapi_decoder_h265_new (dpy, caps); @@ -945,26 +930,19 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) } } break; -#endif case GST_VAAPI_CODEC_WMV3: case GST_VAAPI_CODEC_VC1: decode->decoder = gst_vaapi_decoder_vc1_new (dpy, caps); break; -#if USE_JPEG_DECODER case GST_VAAPI_CODEC_JPEG: decode->decoder = gst_vaapi_decoder_jpeg_new (dpy, caps); break; -#endif -#if USE_VP8_DECODER case GST_VAAPI_CODEC_VP8: decode->decoder = gst_vaapi_decoder_vp8_new (dpy, caps); break; -#endif -#if USE_VP9_DECODER case GST_VAAPI_CODEC_VP9: decode->decoder = gst_vaapi_decoder_vp9_new (dpy, caps); break; -#endif default: decode->decoder = NULL; break; diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 34a6338d3f..5b3f6994ff 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -86,16 +86,10 @@ static const char gst_vaapi_decode_bin_sink_caps_str[] = GST_CAPS_CODEC("video/x-xvid") GST_CAPS_CODEC("video/x-h263") GST_CAPS_CODEC("video/x-h264") -#if USE_H265_DECODER GST_CAPS_CODEC("video/x-h265") -#endif GST_CAPS_CODEC("video/x-wmv") -#if USE_VP8_DECODER GST_CAPS_CODEC("video/x-vp8") -#endif -#if USE_VP9_DECODER GST_CAPS_CODEC("video/x-vp9") -#endif ; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index c98fe05cd5..c7c929e3c7 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1412,7 +1412,7 @@ void gst_vaapi_plugin_base_set_srcpad_can_dmabuf (GstVaapiPluginBase * plugin, GstObject * object) { -#if VA_CHECK_VERSION (0,36,0) && USE_EGL && USE_GST_GL_HELPERS +#if USE_EGL && USE_GST_GL_HELPERS GstGLContext *const gl_context = GST_GL_CONTEXT (object); plugin->srcpad_can_dmabuf = diff --git a/gst/vaapi/meson.build b/gst/vaapi/meson.build index ac2e0146ea..cbd8f88cce 100644 --- a/gst/vaapi/meson.build +++ b/gst/vaapi/meson.build @@ -21,22 +21,13 @@ if USE_ENCODERS vaapi_sources += [ 'gstvaapiencode.c', 'gstvaapiencode_h264.c', + 'gstvaapiencode_h265.c', + 'gstvaapiencode_jpeg.c', 'gstvaapiencode_mpeg2.c', + 'gstvaapiencode_vp8.c', ] endif -if USE_JPEG_ENCODER - vaapi_sources += 'gstvaapiencode_jpeg.c' -endif - -if USE_VP8_ENCODER - vaapi_sources += 'gstvaapiencode_vp8.c' -endif - -if USE_H265_ENCODER - vaapi_sources += 'gstvaapiencode_h265.c' -endif - if USE_VP9_ENCODER vaapi_sources += 'gstvaapiencode_vp9.c' endif diff --git a/meson.build b/meson.build index 1cfb72c52d..070387cdbc 100644 --- a/meson.build +++ b/meson.build @@ -15,7 +15,7 @@ else gst_version_nano = 0 endif -libva_req = ['>= 0.30.4', '!= 0.99.0'] +libva_req = ['>= 0.39.0', '!= 0.99.0'] glib_req = '>= 2.40.0' gst_req = '>= @0@.@1@.0'.format(gst_version_major, gst_version_minor) @@ -54,9 +54,9 @@ gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, gmodule_dep = dependency('gmodule-2.0', required: false) libva_dep = dependency('libva', version: libva_req) -libva_drm_dep = dependency('libva-drm', version: '>= 0.33.0', required: false) -libva_wayland_dep = dependency('libva-wayland', version: '>= 0.33.0', required: false) -libva_x11_dep = dependency('libva-x11', version: '>= 0.31.0', required: false) +libva_drm_dep = dependency('libva-drm', version: libva_req, required: false) +libva_wayland_dep = dependency('libva-wayland', version: libva_req, required: false) +libva_x11_dep = dependency('libva-x11', version: libva_req, required: false) libdrm_dep = dependency('libdrm', required: false) libudev_dep = dependency('libudev', required: false) egl_dep = dependency('egl', required: false) @@ -84,18 +84,9 @@ if glesv2_dep.found() endif endif -USE_ENCODERS = libva_dep.version().version_compare('>= 0.34.0') and get_option('with_encoders') != 'no' -USE_H265_DECODER = cc.has_header('va/va_dec_hevc.h', dependencies: libva_dep, prefix: '#include ') -USE_H265_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_hevc.h', dependencies: libva_dep, prefix: '#include ') -USE_JPEG_DECODER = cc.has_header('va/va_dec_jpeg.h', dependencies: libva_dep, prefix: '#include ') -USE_JPEG_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_jpeg.h', dependencies: libva_dep, prefix: '#include ') -USE_VP8_DECODER = cc.has_header('va/va_dec_vp8.h', dependencies: libva_dep, prefix: '#include ') -USE_VP8_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp8.h', dependencies: libva_dep, prefix: '#include ') -USE_VP9_DECODER = cc.has_header('va/va_dec_vp9.h', dependencies: libva_dep, prefix: '#include ') +USE_ENCODERS = get_option('with_encoders') != 'no' USE_VP9_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp9.h', dependencies: libva_dep, prefix: '#include ') -USE_VPP = cc.has_header('va/va_vpp.h', dependencies: libva_dep, prefix: '#include ') - USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() and get_option('with_drm') != 'no' USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no' USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl_dep.found() and get_option('with_glx') != 'no' @@ -120,54 +111,15 @@ cdata.set10('USE_DRM', USE_DRM) cdata.set10('USE_EGL', USE_EGL) cdata.set10('USE_ENCODERS', USE_ENCODERS) cdata.set10('USE_GLX', USE_GLX) -cdata.set10('USE_H265_DECODER', USE_H265_DECODER) -cdata.set10('USE_H265_ENCODER', USE_H265_ENCODER) -cdata.set10('USE_JPEG_DECODER', USE_JPEG_DECODER) -cdata.set10('USE_JPEG_ENCODER', USE_JPEG_ENCODER) -cdata.set10('USE_VP8_DECODER', USE_VP8_DECODER) -cdata.set10('USE_VP8_ENCODER', USE_VP8_ENCODER) -cdata.set10('USE_VP9_DECODER', USE_VP9_DECODER) cdata.set10('USE_VP9_ENCODER', USE_VP9_ENCODER) cdata.set10('USE_WAYLAND', USE_WAYLAND) cdata.set10('USE_X11', USE_X11) cdata.set10('HAVE_XKBLIB', cc.has_header('X11/XKBlib.h', dependencies: x11_dep)) cdata.set10('HAVE_XRANDR', xrandr_dep.found()) cdata.set10('HAVE_XRENDER', xrender_dep.found()) -cdata.set10('USE_VA_VPP', USE_VPP) cdata.set10('USE_GST_GL_HELPERS', gstgl_dep.found()) cdata.set('USE_GLES_VERSION_MASK', GLES_VERSION_MASK) -if libva_dep.version().version_compare('< 0.38.0') - check_headers = [ - [USE_H265_DECODER, 'HAVE_VA_VA_DEC_HEVC_H'], - [USE_H265_ENCODER, 'HAVE_VA_VA_ENC_HEVC_H'], - [USE_JPEG_DECODER, 'HAVE_VA_VA_DEC_JPEG_H'], - [USE_JPEG_ENCODER, 'HAVE_VA_VA_ENC_JPEG_H'], - [USE_VP8_DECODER, 'HAVE_VA_VA_DEC_VP8_H'], - [USE_VP8_ENCODER, 'HAVE_VA_VA_ENC_VP8_H'], - [USE_VP9_DECODER, 'HAVE_VA_VA_DEC_VP9_H'], - [USE_VP9_ENCODER, 'HAVE_VA_VA_DEC_VP9_H'], - [USE_VPP, 'HAVE_VA_VA_VPP_H'], - ] - foreach h : check_headers - if h.get(0) - cdata.set(h.get(1), 1) - endif - endforeach - - if USE_ENCODERS - check_headers = [ - ['HAVE_VA_VA_ENC_MPEG2_H', 'va/va_enc_mpeg2.h'], - ['HAVE_VA_VA_ENC_H264_H', 'va/va_enc_h264.h'], - ] - foreach h : check_headers - if cc.has_header(h.get(1), dependencies: libva_dep, prefix: '#include ') - cdata.set(h.get(0), 1) - endif - endforeach - endif -endif - api_version = '1.0' soversion = 0 # maintaining compatibility with the previous libtool versioning diff --git a/tests/decoder.c b/tests/decoder.c index 1b3ceaea01..1dfbba2628 100644 --- a/tests/decoder.c +++ b/tests/decoder.c @@ -108,11 +108,9 @@ decoder_new (GstVaapiDisplay * display, const gchar * codec_name) case GST_VAAPI_CODEC_H264: decoder = gst_vaapi_decoder_h264_new (display, caps); break; -#if USE_JPEG_DECODER case GST_VAAPI_CODEC_JPEG: decoder = gst_vaapi_decoder_jpeg_new (display, caps); break; -#endif case GST_VAAPI_CODEC_MPEG2: decoder = gst_vaapi_decoder_mpeg2_new (display, caps); break; diff --git a/tests/simple-decoder.c b/tests/simple-decoder.c index 52aab388e2..34f17d5be3 100644 --- a/tests/simple-decoder.c +++ b/tests/simple-decoder.c @@ -373,11 +373,9 @@ start_decoder (App * app) case GST_VAAPI_CODEC_H264: app->decoder = gst_vaapi_decoder_h264_new (app->display, caps); break; -#if USE_JPEG_DECODER case GST_VAAPI_CODEC_JPEG: app->decoder = gst_vaapi_decoder_jpeg_new (app->display, caps); break; -#endif case GST_VAAPI_CODEC_MPEG2: app->decoder = gst_vaapi_decoder_mpeg2_new (app->display, caps); break; From 77bb3424dc82d3cdc94ce52029b7d9b0b0d1ab69 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Wed, 26 Dec 2018 14:04:08 +0800 Subject: [PATCH 3192/3781] configure: bump the minimum wayland version requirement to 1.11.0 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a64c294543..688551e9a7 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ m4_define([gst_plugins_base_version], [1.15.0.1]) m4_define([gst_plugins_bad_version], [1.15.0.1]) # Wayland minimum version number -m4_define([wayland_api_version], [1.0.2]) +m4_define([wayland_api_version], [1.11.0]) # VA-API minimum version number m4_define([va_api_version], [0.39.0]) From 5b447753da350c2ad71ca4334b864cda60715ccf Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Wed, 26 Dec 2018 14:36:23 +0800 Subject: [PATCH 3193/3781] meson: build h264 fei encoder if possible --- gst-libs/gst/vaapi/meson.build | 17 +++++++++++++++++ gst/vaapi/meson.build | 7 +++++++ meson.build | 2 ++ tests/meson.build | 8 ++++++++ 4 files changed, 34 insertions(+) diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 4515d5581a..6a289af691 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -109,6 +109,23 @@ if USE_VP9_ENCODER gstlibvaapi_headers += 'gstvaapiencoder_vp9.h' endif +if USE_H264_FEI_ENCODER + gstlibvaapi_sources += [ + 'gstvaapifeiutils_h264.c', + 'gstvaapifei_objects.c', + 'gstvaapifeienc_h264.c', + 'gstvaapifeipak_h264.c', + 'gstvaapiencoder_h264_fei.c', + ] + gstlibvaapi_headers += [ + 'gstvaapifeiutils_h264.h', + 'gstvaapifei_objects.h', + 'gstvaapifeienc_h264.h', + 'gstvaapifeipak_h264.h', + 'gstvaapiencoder_h264_fei.h', + ] +endif + if USE_DRM gstlibvaapi_sources += [ 'gstvaapidisplay_drm.c', diff --git a/gst/vaapi/meson.build b/gst/vaapi/meson.build index cbd8f88cce..3bed11cfab 100644 --- a/gst/vaapi/meson.build +++ b/gst/vaapi/meson.build @@ -32,6 +32,13 @@ if USE_VP9_ENCODER vaapi_sources += 'gstvaapiencode_vp9.c' endif +if USE_H264_FEI_ENCODER + vaapi_sources += [ + 'gstvaapifeivideometa.c', + 'gstvaapiencode_h264_fei.c', + ] +endif + gstvaapi = library('gstvaapi', vaapi_sources, c_args : gstreamer_vaapi_args + ['-DGST_USE_UNSTABLE_API'], diff --git a/meson.build b/meson.build index 070387cdbc..06e93cf501 100644 --- a/meson.build +++ b/meson.build @@ -86,6 +86,7 @@ endif USE_ENCODERS = get_option('with_encoders') != 'no' USE_VP9_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp9.h', dependencies: libva_dep, prefix: '#include ') +USE_H264_FEI_ENCODER = USE_ENCODERS and cc.has_header('va/va_fei_h264.h', dependencies: libva_dep, prefix: '#include ') USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() and get_option('with_drm') != 'no' USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no' @@ -112,6 +113,7 @@ cdata.set10('USE_EGL', USE_EGL) cdata.set10('USE_ENCODERS', USE_ENCODERS) cdata.set10('USE_GLX', USE_GLX) cdata.set10('USE_VP9_ENCODER', USE_VP9_ENCODER) +cdata.set10('USE_H264_FEI_ENCODER', USE_H264_FEI_ENCODER) cdata.set10('USE_WAYLAND', USE_WAYLAND) cdata.set10('USE_X11', USE_X11) cdata.set10('HAVE_XKBLIB', cc.has_header('X11/XKBlib.h', dependencies: x11_dep)) diff --git a/tests/meson.build b/tests/meson.build index b7f7c88131..2bc2410e7d 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -45,6 +45,14 @@ test_examples = [ if USE_ENCODERS test_examples += [ 'simple-encoder' ] endif + +if USE_H264_FEI_ENCODER + test_examples += [ + 'test-fei-enc-out', + 'test-fei-enc-in', + ] +endif + if USE_GLX test_examples += [ 'test-textures' ] endif From 14587eb8e86c44a0cacc6c1da99ab9ab15290247 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Fri, 11 Jan 2019 13:48:29 +0800 Subject: [PATCH 3194/3781] vaapipostproc: clean up USE_VA_VPP macro since it already removed from configure file. --- gst-libs/gst/vaapi/gstvaapiutils.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 02a4535061..5fb974fefb 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -756,7 +756,6 @@ from_GstVaapiDeinterlaceMethod (guint value) switch (value) { case GST_VAAPI_DEINTERLACE_METHOD_NONE: return 0; -#if USE_VA_VPP case GST_VAAPI_DEINTERLACE_METHOD_BOB: return VAProcDeinterlacingBob; case GST_VAAPI_DEINTERLACE_METHOD_WEAVE: @@ -765,7 +764,6 @@ from_GstVaapiDeinterlaceMethod (guint value) return VAProcDeinterlacingMotionAdaptive; case GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED: return VAProcDeinterlacingMotionCompensated; -#endif } GST_ERROR ("unsupported GstVaapiDeinterlaceMethod value %d", value); return 0; @@ -777,7 +775,6 @@ from_GstVaapiDeinterlaceFlags (guint flags) { guint va_flags = 0; -#if USE_VA_VPP if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF)) va_flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST; @@ -786,7 +783,6 @@ from_GstVaapiDeinterlaceFlags (guint flags) if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD)) va_flags |= VA_DEINTERLACING_BOTTOM_FIELD; -#endif return va_flags; } From 98c32df8308296ffe480f22f880b302ce234f0de Mon Sep 17 00:00:00 2001 From: Wangfei Date: Tue, 15 Jan 2019 14:33:11 +0800 Subject: [PATCH 3195/3781] vaapipostproc: before set surface proxy, check if it already been created and exist. Fix the deinterlace black frame when playing with glimagesink: gst-launch-1.0 filesrc location=test.264 ! h264parse ! vaapih264dec \ ! vaapipostproc deinterlace-mode=1 deinterlace-method=1 ! glimagesink --- gst/vaapi/gstvaapipostproc.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 24d93f69e2..55e3a5669c 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -723,13 +723,15 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, if (!outbuf_meta) goto error_create_meta; - proxy = - gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL - (postproc->filter_pool)); - if (!proxy) - goto error_create_proxy; - gst_vaapi_video_meta_set_surface_proxy (outbuf_meta, proxy); - gst_vaapi_surface_proxy_unref (proxy); + if (!gst_vaapi_video_meta_get_surface_proxy (outbuf_meta)) { + proxy = + gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL + (postproc->filter_pool)); + if (!proxy) + goto error_create_proxy; + gst_vaapi_video_meta_set_surface_proxy (outbuf_meta, proxy); + gst_vaapi_surface_proxy_unref (proxy); + } if (deint) { deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD : 0); From f50fb8748f02910bdc75e62d91032187a1b73756 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Thu, 6 Dec 2018 10:18:53 +0800 Subject: [PATCH 3196/3781] libs: encoder: h264/h265: fix encode lose frame issue. Instead of dropping all remain frames in reorder_frame_list during flush, keep encoding. https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/97 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder.h | 4 + gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 99 ++++++++++++++++------- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 56 +++++++++++-- 4 files changed, 126 insertions(+), 35 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 619aaf5323..5c3caf024d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -419,7 +419,7 @@ _coded_buffer_proxy_released_notify (GstVaapiEncoder * encoder) } /* Creates a new VA coded buffer object proxy, backed from a pool */ -static GstVaapiCodedBufferProxy * +GstVaapiCodedBufferProxy * gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder) { GstVaapiCodedBufferPool *const pool = diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 974a70a9b2..6be4f13edb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -202,6 +202,10 @@ gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); GArray * gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile); + +GstVaapiCodedBufferProxy * +gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder); + G_END_DECLS #endif /* GST_VAAPI_ENCODER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 0acba67a32..32756bbe47 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1409,6 +1409,26 @@ set_key_frame (GstVaapiEncPicture * picture, set_i_frame (picture, encoder); } +static void +set_frame_num (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiH264ViewReorderPool *reorder_pool = NULL; + + reorder_pool = &encoder->reorder_pools[encoder->view_idx]; + + picture->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); + + if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { + picture->frame_num = 0; + reorder_pool->cur_frame_num = 0; + } + + reorder_pool->prev_frame_is_ref = GST_VAAPI_ENC_PICTURE_IS_REFRENCE (picture); + + if (reorder_pool->prev_frame_is_ref) + ++reorder_pool->cur_frame_num; +} + /* Fills in VA HRD parameters */ static void fill_hrd_params (GstVaapiEncoderH264 * encoder, VAEncMiscParameterHRD * hrd) @@ -2894,24 +2914,69 @@ gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder) GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); GstVaapiH264ViewReorderPool *reorder_pool; GstVaapiEncPicture *pic; + GstVaapiCodedBufferProxy *codedbuf_proxy; guint i; + gboolean p_frame = TRUE; + GstVaapiEncoderStatus status; for (i = 0; i < encoder->num_views; i++) { reorder_pool = &encoder->reorder_pools[i]; + + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = NULL; + if (p_frame) { + pic = (GstVaapiEncPicture *) + g_queue_pop_tail (&reorder_pool->reorder_frame_list); + set_p_frame (pic, encoder); + p_frame = FALSE; + } else { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + set_b_frame (pic, encoder); + } + g_assert (pic); + + set_frame_num (encoder, pic); + + if (GST_CLOCK_TIME_IS_VALID (pic->frame->pts)) + pic->frame->pts += encoder->cts_offset; + + codedbuf_proxy = gst_vaapi_encoder_create_coded_buffer (base_encoder); + if (!codedbuf_proxy) + goto error_create_coded_buffer; + + status = + gst_vaapi_encoder_h264_encode (base_encoder, pic, codedbuf_proxy); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto error_encode; + + gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, + pic, (GDestroyNotify) gst_vaapi_mini_object_unref); + g_async_queue_push (base_encoder->codedbuf_queue, codedbuf_proxy); + base_encoder->num_codedbuf_queued++; + } reorder_pool->frame_index = 0; reorder_pool->cur_frame_num = 0; reorder_pool->cur_present_index = 0; reorder_pool->prev_frame_is_ref = FALSE; - - while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - pic = (GstVaapiEncPicture *) - g_queue_pop_head (&reorder_pool->reorder_frame_list); - gst_vaapi_enc_picture_unref (pic); - } - g_queue_clear (&reorder_pool->reorder_frame_list); } return GST_VAAPI_ENCODER_STATUS_SUCCESS; + +/* ERRORS */ +error_create_coded_buffer: + { + GST_ERROR ("failed to allocate coded buffer"); + gst_vaapi_enc_picture_unref (pic); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_encode: + { + GST_ERROR ("failed to encode frame (status = %d)", status); + gst_vaapi_enc_picture_unref (pic); + gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); + return status; + } } /* Generate "codec-data" buffer */ @@ -3047,26 +3112,6 @@ sort_hierarchical_b (gconstpointer a, gconstpointer b, gpointer user_data) return pic1->temporal_id - pic2->temporal_id; } -static void -set_frame_num (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) -{ - GstVaapiH264ViewReorderPool *reorder_pool = NULL; - - reorder_pool = &encoder->reorder_pools[encoder->view_idx]; - - picture->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); - - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { - picture->frame_num = 0; - reorder_pool->cur_frame_num = 0; - } - - reorder_pool->prev_frame_is_ref = GST_VAAPI_ENC_PICTURE_IS_REFRENCE (picture); - - if (reorder_pool->prev_frame_is_ref) - ++reorder_pool->cur_frame_num; -} - static GstVaapiEncoderStatus gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 1348e64b94..aced90f9ec 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2140,19 +2140,61 @@ gst_vaapi_encoder_h265_flush (GstVaapiEncoder * base_encoder) GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); GstVaapiH265ReorderPool *reorder_pool; GstVaapiEncPicture *pic; + GstVaapiCodedBufferProxy *codedbuf_proxy; + gboolean p_frame = TRUE; + GstVaapiEncoderStatus status; reorder_pool = &encoder->reorder_pool; + + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = NULL; + if (p_frame) { + pic = (GstVaapiEncPicture *) + g_queue_pop_tail (&reorder_pool->reorder_frame_list); + set_p_frame (pic, encoder); + p_frame = FALSE; + } else { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + set_b_frame (pic, encoder); + } + g_assert (pic); + + if (GST_CLOCK_TIME_IS_VALID (pic->frame->pts)) + pic->frame->pts += encoder->cts_offset; + + codedbuf_proxy = gst_vaapi_encoder_create_coded_buffer (base_encoder); + if (!codedbuf_proxy) + goto error_create_coded_buffer; + + status = gst_vaapi_encoder_h265_encode (base_encoder, pic, codedbuf_proxy); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto error_encode; + + gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, + pic, (GDestroyNotify) gst_vaapi_mini_object_unref); + g_async_queue_push (base_encoder->codedbuf_queue, codedbuf_proxy); + base_encoder->num_codedbuf_queued++; + } reorder_pool->frame_index = 0; reorder_pool->cur_present_index = 0; - while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - pic = (GstVaapiEncPicture *) - g_queue_pop_head (&reorder_pool->reorder_frame_list); - gst_vaapi_enc_picture_unref (pic); - } - g_queue_clear (&reorder_pool->reorder_frame_list); - return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +error_create_coded_buffer: + { + GST_ERROR ("failed to allocate coded buffer"); + gst_vaapi_enc_picture_unref (pic); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_encode: + { + GST_ERROR ("failed to encode frame (status = %d)", status); + gst_vaapi_enc_picture_unref (pic); + gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); + return status; + } } /* Generate "codec-data" buffer */ From 220016aa6cf9606f22307d02bd7b4e7cdf46faed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 14 Jan 2019 18:21:30 +0100 Subject: [PATCH 3197/3781] libs: encoder: h264/h265: flush pending ordered pictures In order to flush the pending pictures, a new internal encoder vmethod is used: get_pending_reordered() This method follows an iterator pattern which will return the next picture to encode and push. The base encoder will call this function in a loop when flush() is called. For now, only H.264 and H.265 encoders implement this flushing mechanism. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 52 +++++++++- gst-libs/gst/vaapi/gstvaapiencoder.h | 4 - gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 118 ++++++++++++---------- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 107 +++++++++++--------- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 6 ++ 5 files changed, 179 insertions(+), 108 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 5c3caf024d..d463d6e395 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -419,7 +419,7 @@ _coded_buffer_proxy_released_notify (GstVaapiEncoder * encoder) } /* Creates a new VA coded buffer object proxy, backed from a pool */ -GstVaapiCodedBufferProxy * +static GstVaapiCodedBufferProxy * gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder) { GstVaapiCodedBufferPool *const pool = @@ -597,6 +597,17 @@ error_invalid_buffer: } } +static inline gboolean +_get_pending_reordered (GstVaapiEncoder * encoder, + GstVaapiEncPicture ** picture, gpointer * state) +{ + GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + + if (!klass->get_pending_reordered) + return FALSE; + return klass->get_pending_reordered (encoder, picture, state); +} + /** * gst_vaapi_encoder_flush: * @encoder: a #GstVaapiEncoder @@ -609,8 +620,47 @@ GstVaapiEncoderStatus gst_vaapi_encoder_flush (GstVaapiEncoder * encoder) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + GstVaapiCodedBufferProxy *codedbuf_proxy; + GstVaapiEncPicture *picture; + GstVaapiEncoderStatus status; + gpointer iter = NULL; + + picture = NULL; + while (_get_pending_reordered (encoder, &picture, &iter)) { + if (!picture) + continue; + + codedbuf_proxy = gst_vaapi_encoder_create_coded_buffer (encoder); + if (!codedbuf_proxy) + goto error_create_coded_buffer; + + status = klass->encode (encoder, picture, codedbuf_proxy); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto error_encode; + + gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, + picture, (GDestroyNotify) gst_vaapi_mini_object_unref); + g_async_queue_push (encoder->codedbuf_queue, codedbuf_proxy); + encoder->num_codedbuf_queued++; + } + g_free (iter); return klass->flush (encoder); + + /* ERRORS */ +error_create_coded_buffer: + { + GST_ERROR ("failed to allocate coded buffer"); + gst_vaapi_enc_picture_unref (picture); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_encode: + { + GST_ERROR ("failed to encode frame (status = %d)", status); + gst_vaapi_enc_picture_unref (picture); + gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); + return status; + } } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 6be4f13edb..974a70a9b2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -202,10 +202,6 @@ gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); GArray * gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile); - -GstVaapiCodedBufferProxy * -gst_vaapi_encoder_create_coded_buffer (GstVaapiEncoder * encoder); - G_END_DECLS #endif /* GST_VAAPI_ENCODER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 32756bbe47..42f99be4db 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2908,75 +2908,86 @@ error: } } +struct _PendingIterState +{ + guint cur_view; + GstVaapiPictureType pic_type; +}; + +static gboolean +gst_vaapi_encoder_h264_get_pending_reordered (GstVaapiEncoder * base_encoder, + GstVaapiEncPicture ** picture, gpointer * state) +{ + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); + GstVaapiH264ViewReorderPool *reorder_pool; + GstVaapiEncPicture *pic; + struct _PendingIterState *iter; + + g_return_val_if_fail (state, FALSE); + + if (!*state) { + iter = g_new0 (struct _PendingIterState, 1); + iter->pic_type = GST_VAAPI_PICTURE_TYPE_P; + *state = iter; + } else { + iter = *state; + } + + *picture = NULL; + + if (iter->cur_view >= encoder->num_views) + return FALSE; + + reorder_pool = &encoder->reorder_pools[iter->cur_view]; + if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + iter->cur_view++; + return TRUE; /* perhaps other views has pictures? */ + } + + pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list); + g_assert (pic); + if (iter->pic_type == GST_VAAPI_PICTURE_TYPE_P) { + set_p_frame (pic, encoder); + iter->pic_type = GST_VAAPI_PICTURE_TYPE_B; + } else if (iter->pic_type == GST_VAAPI_PICTURE_TYPE_B) { + set_b_frame (pic, encoder); + } else { + GST_WARNING ("Unhandled pending picture type"); + } + + set_frame_num (encoder, pic); + + if (GST_CLOCK_TIME_IS_VALID (pic->frame->pts)) + pic->frame->pts += encoder->cts_offset; + + *picture = pic; + return TRUE; +} + static GstVaapiEncoderStatus gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder) { GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); GstVaapiH264ViewReorderPool *reorder_pool; GstVaapiEncPicture *pic; - GstVaapiCodedBufferProxy *codedbuf_proxy; guint i; - gboolean p_frame = TRUE; - GstVaapiEncoderStatus status; for (i = 0; i < encoder->num_views; i++) { reorder_pool = &encoder->reorder_pools[i]; - - while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - pic = NULL; - if (p_frame) { - pic = (GstVaapiEncPicture *) - g_queue_pop_tail (&reorder_pool->reorder_frame_list); - set_p_frame (pic, encoder); - p_frame = FALSE; - } else { - pic = (GstVaapiEncPicture *) - g_queue_pop_head (&reorder_pool->reorder_frame_list); - set_b_frame (pic, encoder); - } - g_assert (pic); - - set_frame_num (encoder, pic); - - if (GST_CLOCK_TIME_IS_VALID (pic->frame->pts)) - pic->frame->pts += encoder->cts_offset; - - codedbuf_proxy = gst_vaapi_encoder_create_coded_buffer (base_encoder); - if (!codedbuf_proxy) - goto error_create_coded_buffer; - - status = - gst_vaapi_encoder_h264_encode (base_encoder, pic, codedbuf_proxy); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - goto error_encode; - - gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, - pic, (GDestroyNotify) gst_vaapi_mini_object_unref); - g_async_queue_push (base_encoder->codedbuf_queue, codedbuf_proxy); - base_encoder->num_codedbuf_queued++; - } reorder_pool->frame_index = 0; reorder_pool->cur_frame_num = 0; reorder_pool->cur_present_index = 0; reorder_pool->prev_frame_is_ref = FALSE; + + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&reorder_pool->reorder_frame_list); } return GST_VAAPI_ENCODER_STATUS_SUCCESS; - -/* ERRORS */ -error_create_coded_buffer: - { - GST_ERROR ("failed to allocate coded buffer"); - gst_vaapi_enc_picture_unref (pic); - return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - } -error_encode: - { - GST_ERROR ("failed to encode frame (status = %d)", status); - gst_vaapi_enc_picture_unref (pic); - gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); - return status; - } } /* Generate "codec-data" buffer */ @@ -3511,7 +3522,8 @@ gst_vaapi_encoder_h264_class (void) static const GstVaapiEncoderClass GstVaapiEncoderH264Class = { GST_VAAPI_ENCODER_CLASS_INIT (H264, h264), .set_property = gst_vaapi_encoder_h264_set_property, - .get_codec_data = gst_vaapi_encoder_h264_get_codec_data + .get_codec_data = gst_vaapi_encoder_h264_get_codec_data, + .get_pending_reordered = gst_vaapi_encoder_h264_get_pending_reordered, }; return &GstVaapiEncoderH264Class; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index aced90f9ec..ace2e56b07 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2134,67 +2134,73 @@ error: } } +struct _PendingIterState +{ + GstVaapiPictureType pic_type; +}; + +static gboolean +gst_vaapi_encoder_h265_get_pending_reordered (GstVaapiEncoder * base_encoder, + GstVaapiEncPicture ** picture, gpointer * state) +{ + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); + GstVaapiH265ReorderPool *reorder_pool; + GstVaapiEncPicture *pic; + struct _PendingIterState *iter; + + g_return_val_if_fail (state, FALSE); + + if (!*state) { + iter = g_new0 (struct _PendingIterState, 1); + iter->pic_type = GST_VAAPI_PICTURE_TYPE_P; + *state = iter; + } else { + iter = *state; + } + + *picture = NULL; + + reorder_pool = &encoder->reorder_pool; + if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) + return FALSE; + + pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list); + g_assert (pic); + if (iter->pic_type == GST_VAAPI_PICTURE_TYPE_P) { + set_p_frame (pic, encoder); + iter->pic_type = GST_VAAPI_PICTURE_TYPE_B; + } else if (iter->pic_type == GST_VAAPI_PICTURE_TYPE_B) { + set_b_frame (pic, encoder); + } else { + GST_WARNING ("Unhandled pending picture type"); + } + + if (GST_CLOCK_TIME_IS_VALID (pic->frame->pts)) + pic->frame->pts += encoder->cts_offset; + + *picture = pic; + return TRUE; +} + static GstVaapiEncoderStatus gst_vaapi_encoder_h265_flush (GstVaapiEncoder * base_encoder) { GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); GstVaapiH265ReorderPool *reorder_pool; GstVaapiEncPicture *pic; - GstVaapiCodedBufferProxy *codedbuf_proxy; - gboolean p_frame = TRUE; - GstVaapiEncoderStatus status; reorder_pool = &encoder->reorder_pool; - - while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - pic = NULL; - if (p_frame) { - pic = (GstVaapiEncPicture *) - g_queue_pop_tail (&reorder_pool->reorder_frame_list); - set_p_frame (pic, encoder); - p_frame = FALSE; - } else { - pic = (GstVaapiEncPicture *) - g_queue_pop_head (&reorder_pool->reorder_frame_list); - set_b_frame (pic, encoder); - } - g_assert (pic); - - if (GST_CLOCK_TIME_IS_VALID (pic->frame->pts)) - pic->frame->pts += encoder->cts_offset; - - codedbuf_proxy = gst_vaapi_encoder_create_coded_buffer (base_encoder); - if (!codedbuf_proxy) - goto error_create_coded_buffer; - - status = gst_vaapi_encoder_h265_encode (base_encoder, pic, codedbuf_proxy); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - goto error_encode; - - gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, - pic, (GDestroyNotify) gst_vaapi_mini_object_unref); - g_async_queue_push (base_encoder->codedbuf_queue, codedbuf_proxy); - base_encoder->num_codedbuf_queued++; - } reorder_pool->frame_index = 0; reorder_pool->cur_present_index = 0; - return GST_VAAPI_ENCODER_STATUS_SUCCESS; + while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { + pic = (GstVaapiEncPicture *) + g_queue_pop_head (&reorder_pool->reorder_frame_list); + gst_vaapi_enc_picture_unref (pic); + } + g_queue_clear (&reorder_pool->reorder_frame_list); - /* ERRORS */ -error_create_coded_buffer: - { - GST_ERROR ("failed to allocate coded buffer"); - gst_vaapi_enc_picture_unref (pic); - return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - } -error_encode: - { - GST_ERROR ("failed to encode frame (status = %d)", status); - gst_vaapi_enc_picture_unref (pic); - gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); - return status; - } + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } /* Generate "codec-data" buffer */ @@ -2654,7 +2660,8 @@ gst_vaapi_encoder_h265_class (void) static const GstVaapiEncoderClass GstVaapiEncoderH265Class = { GST_VAAPI_ENCODER_CLASS_INIT (H265, h265), .set_property = gst_vaapi_encoder_h265_set_property, - .get_codec_data = gst_vaapi_encoder_h265_get_codec_data + .get_codec_data = gst_vaapi_encoder_h265_get_codec_data, + .get_pending_reordered = gst_vaapi_encoder_h265_get_pending_reordered, }; return &GstVaapiEncoderH265Class; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index d3253a23cc..843004e4b6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -362,6 +362,12 @@ struct _GstVaapiEncoderClass /* To create a secondary context for a single base encoder */ gboolean (*ensure_secondary_context) (GstVaapiEncoder * encoder); + + /* Iterator that retrieves the pending pictures in the reordered + * list */ + gboolean (*get_pending_reordered) (GstVaapiEncoder * encoder, + GstVaapiEncPicture ** picture, + gpointer * state); }; #define GST_VAAPI_ENCODER_CLASS_HOOK(codec, func) \ From f1877628bb8ca7df4b1445312886d56ac5affd18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 14 Jan 2019 19:35:34 +0100 Subject: [PATCH 3198/3781] libs: encoder: refactor to avoid code duplication gst_vaapi_encoder_put_frame() and gst_vaapi_encoder_flush() duplicates the same code segment where the coded buffer is created, the picture encoded on it and pushed to the async queue. The function gst_vaapi_encoder_encode_and_queue() refactor this. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 81 ++++++++++++++-------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index d463d6e395..62f4099a66 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -479,6 +479,46 @@ gst_vaapi_encoder_create_surface (GstVaapiEncoder * encoder) return proxy; } +/* Create a coded buffer proxy where the picture is going to be + * decoded, the subclass encode vmethod is called and, if it doesn't + * fail, the coded buffer is pushed into the async queue */ +static GstVaapiEncoderStatus +gst_vaapi_encoder_encode_and_queue (GstVaapiEncoder * encoder, + GstVaapiEncPicture * picture) +{ + GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + GstVaapiCodedBufferProxy *codedbuf_proxy; + GstVaapiEncoderStatus status; + + codedbuf_proxy = gst_vaapi_encoder_create_coded_buffer (encoder); + if (!codedbuf_proxy) + goto error_create_coded_buffer; + + status = klass->encode (encoder, picture, codedbuf_proxy); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto error_encode; + + gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, + picture, (GDestroyNotify) gst_vaapi_mini_object_unref); + g_async_queue_push (encoder->codedbuf_queue, codedbuf_proxy); + encoder->num_codedbuf_queued++; + + return status; + + /* ERRORS */ +error_create_coded_buffer: + { + GST_ERROR ("failed to allocate coded buffer"); + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + } +error_encode: + { + GST_ERROR ("failed to encode frame (status = %d)", status); + gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); + return status; + } +} + /** * gst_vaapi_encoder_put_frame: * @encoder: a #GstVaapiEncoder @@ -496,7 +536,6 @@ gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); GstVaapiEncoderStatus status; GstVaapiEncPicture *picture; - GstVaapiCodedBufferProxy *codedbuf_proxy; for (;;) { picture = NULL; @@ -506,19 +545,10 @@ gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder, if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) goto error_reorder_frame; - codedbuf_proxy = gst_vaapi_encoder_create_coded_buffer (encoder); - if (!codedbuf_proxy) - goto error_create_coded_buffer; - - status = klass->encode (encoder, picture, codedbuf_proxy); + status = gst_vaapi_encoder_encode_and_queue (encoder, picture); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) goto error_encode; - gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, - picture, (GDestroyNotify) gst_vaapi_mini_object_unref); - g_async_queue_push (encoder->codedbuf_queue, codedbuf_proxy); - encoder->num_codedbuf_queued++; - /* Try again with any pending reordered frame now available for encoding */ frame = NULL; } @@ -530,17 +560,9 @@ error_reorder_frame: GST_ERROR ("failed to process reordered frames"); return status; } -error_create_coded_buffer: - { - GST_ERROR ("failed to allocate coded buffer"); - gst_vaapi_enc_picture_unref (picture); - return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - } error_encode: { - GST_ERROR ("failed to encode frame (status = %d)", status); gst_vaapi_enc_picture_unref (picture); - gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); return status; } } @@ -620,7 +642,6 @@ GstVaapiEncoderStatus gst_vaapi_encoder_flush (GstVaapiEncoder * encoder) { GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); - GstVaapiCodedBufferProxy *codedbuf_proxy; GstVaapiEncPicture *picture; GstVaapiEncoderStatus status; gpointer iter = NULL; @@ -629,36 +650,18 @@ gst_vaapi_encoder_flush (GstVaapiEncoder * encoder) while (_get_pending_reordered (encoder, &picture, &iter)) { if (!picture) continue; - - codedbuf_proxy = gst_vaapi_encoder_create_coded_buffer (encoder); - if (!codedbuf_proxy) - goto error_create_coded_buffer; - - status = klass->encode (encoder, picture, codedbuf_proxy); + status = gst_vaapi_encoder_encode_and_queue (encoder, picture); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) goto error_encode; - - gst_vaapi_coded_buffer_proxy_set_user_data (codedbuf_proxy, - picture, (GDestroyNotify) gst_vaapi_mini_object_unref); - g_async_queue_push (encoder->codedbuf_queue, codedbuf_proxy); - encoder->num_codedbuf_queued++; } g_free (iter); return klass->flush (encoder); /* ERRORS */ -error_create_coded_buffer: - { - GST_ERROR ("failed to allocate coded buffer"); - gst_vaapi_enc_picture_unref (picture); - return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - } error_encode: { - GST_ERROR ("failed to encode frame (status = %d)", status); gst_vaapi_enc_picture_unref (picture); - gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); return status; } } From 0c39d5dd728cd9dbba6c163044af5baeff0de9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 17 Jan 2019 02:36:52 +0000 Subject: [PATCH 3199/3781] Update docs --- docs/plugins/inspect/plugin-vaapi.xml | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/plugins/inspect/plugin-vaapi.xml b/docs/plugins/inspect/plugin-vaapi.xml index b6f47f629c..62477a0990 100644 --- a/docs/plugins/inspect/plugin-vaapi.xml +++ b/docs/plugins/inspect/plugin-vaapi.xml @@ -3,7 +3,7 @@ VA-API based elements ../../gst/vaapi/.libs/libgstvaapi.so libgstvaapi.so - 1.15.0.1 + 1.15.1 LGPL gstreamer-vaapi gstreamer-vaapi @@ -12,7 +12,7 @@ vaapidecodebin VA-API Decode Bin - Codec/Decoder/Video/Hardware + Codec/Decoder/Video A VA-API based bin with a decoder and a postprocessor Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Victor Jaquez <victorx.jaquez@intel.com> @@ -26,7 +26,7 @@ src source always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
@@ -47,7 +47,7 @@ src source always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
@@ -62,7 +62,7 @@ sink sink always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
src @@ -89,7 +89,7 @@ src source always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
@@ -110,14 +110,14 @@ src source always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
vaapimpeg2enc VA-API MPEG-2 encoder - Codec/Encoder/Video + Codec/Encoder/Video/Hardware A VA-API based MPEG-2 video encoder Guangxin Xu <guangxin.xu@intel.com> @@ -125,7 +125,7 @@ sink sink always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
src @@ -138,7 +138,7 @@ vaapipostproc VA-API video postprocessing - Filter/Converter/Video;Filter/Converter/Video/Scaler;Filter/Effect/Video;Filter/Effect/Video/Deinterlace + Filter/Converter/Effect/Video/Scaler/Deinterlace/Hardware A VA-API video postprocessing filter Gwenole Beauchesne <gwenole.beauchesne@intel.com> @@ -146,13 +146,13 @@ sink sink always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }
src source always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
@@ -167,7 +167,7 @@ sink sink always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:VASurface, meta:GstVideoOverlayComposition), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoOverlayComposition), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:VASurface, meta:GstVideoOverlayComposition), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoOverlayComposition), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
@@ -188,9 +188,9 @@ src source always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
- + \ No newline at end of file From d158e78ef8cb19d089270bbd907f122831e51162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 17 Jan 2019 02:36:52 +0000 Subject: [PATCH 3200/3781] Release 1.15.1 --- ChangeLog | 1404 ++++++++++++++++++++++++++++++++++++++++++ NEWS | 1047 +++++++++++++++++++++++++++++-- RELEASE | 34 +- configure.ac | 14 +- gstreamer-vaapi.doap | 10 + meson.build | 2 +- 6 files changed, 2451 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b1e9287c6..00a7314ed8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,1407 @@ +=== release 1.15.1 === + +2019-01-17 02:36:52 +0000 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * RELEASE: + * configure.ac: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.15.1 + +2019-01-17 02:36:52 +0000 Tim-Philipp Müller + + * docs/plugins/inspect/plugin-vaapi.xml: + Update docs + +2019-01-14 19:35:34 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: refactor to avoid code duplication + gst_vaapi_encoder_put_frame() and gst_vaapi_encoder_flush() duplicates + the same code segment where the coded buffer is created, the picture + encoded on it and pushed to the async queue. + The function gst_vaapi_encoder_encode_and_queue() refactor this. + +2019-01-14 18:21:30 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: h264/h265: flush pending ordered pictures + In order to flush the pending pictures, a new internal encoder vmethod + is used: get_pending_reordered() + This method follows an iterator pattern which will return the next + picture to encode and push. + The base encoder will call this function in a loop when flush() is called. + For now, only H.264 and H.265 encoders implement this flushing mechanism. + +2018-12-06 10:18:53 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h264/h265: fix encode lose frame issue. + Instead of dropping all remain frames in reorder_frame_list during + flush, keep encoding. + https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/97 + +2019-01-15 14:33:11 +0800 Wangfei + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: before set surface proxy, check if it already been created and exist. + Fix the deinterlace black frame when playing with glimagesink: + gst-launch-1.0 filesrc location=test.264 ! h264parse ! vaapih264dec \ + ! vaapipostproc deinterlace-mode=1 deinterlace-method=1 ! glimagesink + +2019-01-11 13:48:29 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiutils.c: + vaapipostproc: clean up USE_VA_VPP macro since it already removed from configure file. + +2018-12-26 14:36:23 +0800 Haihao Xiang + + * gst-libs/gst/vaapi/meson.build: + * gst/vaapi/meson.build: + * meson.build: + * tests/meson.build: + meson: build h264 fei encoder if possible + +2018-12-26 14:04:08 +0800 Haihao Xiang + + * configure.ac: + configure: bump the minimum wayland version requirement to 1.11.0 + +2018-12-24 12:58:53 +0800 Haihao Xiang + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicompat.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils_core.c: + * gst-libs/gst/vaapi/meson.build: + * gst/vaapi/Makefile.am: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/meson.build: + * meson.build: + * tests/decoder.c: + * tests/simple-decoder.c: + vaapi: bump the minimum vaapi version requirement to 0.39.0 + And reduce unnecessary API version and structures check as well. + https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/108 + +2018-12-22 18:07:35 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * tests/test-decode.c: + * tests/test-filter.c: + * tests/test-subpicture.c: + * tests/test-textures.c: + * tests/test-windows.c: + libs: window: remove custom ref() and unref() + Use gst_object_ref() and gst_object_unref() instead. + +2018-12-22 13:25:09 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.c: + * gst-libs/gst/vaapi/gstvaapiwindow_egl.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + libs: window: use its own debug category + +2018-12-22 18:02:38 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.c: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.h: + * gst-libs/gst/vaapi/gstvaapiwindow_egl.c: + * gst-libs/gst/vaapi/gstvaapiwindow_egl.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + libs: window: refactor as gobject + This is another step in the gobjectification of the internal library + of gstreamer-vaapi. Now it is the turn of GstVaapiWindow and its + derivates. + The idea is to minimize the changeset keeping the same design as + much as possible. + GstVaapiWindow is defined as an abstract class with two properties: + the GstVaapiDisplay and the native ID. Thus, many of the + GstVaapiObject macros were copied as GstVaapiWindow macros. + The function gst_vaapi_window_new_internal() is kept as a decorator + of for calling gst_vaapi_window_create() and the possibility of + failure. + The descendant classes, such as glx, still use the private + structures, but through the gobject mechanism. + +2018-12-03 22:05:29 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: filter: use its own debug category + +2018-12-24 14:08:42 +0800 He Junyan + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + plugins: Add more check for allowed raw caps. + The gst_vaapi_plugin_base_get_allowed_raw_caps is used for both sink + pad and src pad, which cause some bugs. For sink pad, we need to verify + vaPutImage() while for the src pad we need to verify vaGetImage(). + For vaapidecoderXXX kind of plugins, the case is more complex. We need + to verify whether the decoded result(in some surface, NV12 format most + of the time) can be vaGetImage to some raw image format. Add more check + to fix all these problems. + https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/123 + Signed-off-by: He Junyan + +2018-12-18 10:44:21 +0800 Wangfei + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix csc fail when only change width or height. + +2018-12-15 09:47:15 +0900 Wonchul Lee + + * tests/elements/meson.build: + meson: Add gtk guard + +2018-12-15 14:48:03 +0800 Wangfei + + * gst/vaapi/gstvaapiencode_h264.c: + libs: enc: h264: set max profile idc with correct profile. + Use the highest rank of available profile as the max profile to + set max idc value. + https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/124 + +2018-12-03 13:56:52 +0100 Niels De Graef + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + Use G_DEFINE_TYPE_WITH_PRIVATE if applicable + This gets rid of the strange `do_init` macro and makes the intent a bit + more clear. + +2018-12-05 17:24:53 -0300 Thibault Saunier + + * common: + Automatic update of common submodule + From ed78bee to 59cb678 + +2018-11-27 09:47:44 -0500 Wangfei + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/video-format.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.h: + libs: dec: h265: support decode for main-444 10bit streams. + Add 444 10bit yuv format Y410, which can be used to decode + main-444 10bit streams. Currently, this feature is only + supported by media-driver in Icelake. + +2018-11-28 05:56:44 +0200 Jordan Petridis + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapisink.c: + Run gst-indent through the files + This is required before we enabled an indent test in the CI. + https://gitlab.freedesktop.org/gstreamer/gstreamer-project/issues/33 + +2018-11-14 13:11:56 +0800 He Junyan + + * gst/vaapi/gstvaapipluginbase.c: + plugins: modify image check of extract_allowed_surface_formats. + The extract_allowed_surface_formats function just check whether + we can support some kind of surface/image format pair. We just + need to create a surface, create an image with the same video-format + and putImage from image to surface. All these operations success, + that kind of video-format is supported. + The old manner do not work for some kind of video-format. For example, + the RGBA kind of format will create a NV12 surface and RGBA image, + and the putImage will fail because the format is not same. And so + the RGBA format is not supported but actually it is supported. + +2018-11-14 11:34:20 +0100 Michael Olbrich + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: add some missing locking + gst_vaapi_plugin_base_close() removed the raw caps that are used indirectly + in gst_vaapipostproc_transform_caps(). The usage is already protected by + the mutex. + This is needed when the pipeline is stopped during startup. + +2018-11-20 16:07:44 +0800 Xiang, Haihao + + * gst/vaapi/gstvaapivideomemory.c: + Close dmabuf_fd + Otherwise it will result in resource leak when failed to create + dmabuf memory + +2018-11-12 13:39:51 +0100 Michael Olbrich + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: don't start src pad task in set_format + Otherwise the task may be restarted during shutdown. Start the task in + gst_vaapiencode_handle_frame() instead. + +2018-11-14 13:52:48 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.h: + libs: dec: h265: support decode for main-444 8bit streams. + Add 444 8bit yuv format AYUV, which can be used to decode + main-444 8bit streams. Currently, this feature is only + supported by media-driver in Icelake. + https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/119 + +2018-11-12 17:43:54 +0100 Víctor Manuel Jáquez Leal + + * .gitlab-ci.yml: + Add Gitlab CI configuration + This commit adds a .gitlab-ci.yml file, which uses a feature + to fetch the config from a centralized repository. The intent is + to have all the gstreamer modules use the same configuration. + The configuration is currently hosted at the gst-ci repository + under the gitlab/ci_template.yml path. + Part of https://gitlab.freedesktop.org/gstreamer/gstreamer-project/issues/29 + +2018-11-09 22:03:43 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: Sync the GstVaapiChromaType to VA header file. + Add more kinds of chrometype which will be used to describe + new video formats. Sync it with 1.4.0 version header file. + Alse delete useless GST_VAAPI_CHROMA_TYPE_YUV410 chrome type. + Signed-off-by: He Junyan + +2018-11-09 23:55:05 +0000 Tim-Philipp Müller + + * gst-libs/gst/vaapi/meson.build: + meson: link with -lm + Fixes #117 hopefully. + +2018-11-09 23:46:53 +0000 Tim-Philipp Müller + + * meson.build: + meson: bump meson required to 0.47 for feature options + +2018-11-06 14:38:08 +0800 Junyan He + + * gst-libs/gst/vaapi/video-format.c: + libs: Modify the video format of endianness. + We lack some video format because endianness declare. + The video format should not directly relate to endianness. For example, + ARGB on big endian should not be simplely seen as BGRA on little endian + machine. We should provide endianess convert or format convert help + functions if endianness does not match. + https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/112 + Signed-off-by: Junyan He + +2018-10-17 18:36:52 +0800 Junyan He + + * gst/vaapi/gstvaapipluginutil.c: + plugins: Fix build error when GL is enabled while EGL is disabled. + gl_platform_type in gst_vaapi_get_display_type_from_gl_env generate + unused-variable warning and may block build when Werror enabled. + Several functions like gst_vaapi_display_egl_new_with_native_display + have no prototype warning and link error when GL is enabled but EGL + is disabled. Fix all these warning and link error. + https://bugzilla.gnome.org/show_bug.cgi?id=797358 + Signed-off-by: Junyan He + +2018-11-03 15:06:09 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + libs: encoder: h264/h264fei: remove unuseless code. + The variable are set twice, remove previous one. + https://bugzilla.gnome.org/show_bug.cgi?id=797365 + +2018-11-03 15:28:35 +0800 Wangfei + + * tests/simple-encoder.c: + * tests/test-fei-enc-in.c: + tests: check return value when using gst_buffer_map. + https://bugzilla.gnome.org/show_bug.cgi?id=797366 + +2018-11-02 16:50:47 +0100 Víctor Manuel Jáquez Leal + + * meson.build: + * meson_options.txt: + * tests/elements/meson.build: + * tests/meson.build: + build: meson: build examples + +2018-11-02 16:50:00 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/meson.build: + build: meson: declare headers for libgstvaapi + Thus handling its recompilation if needed. + +2018-11-05 05:41:13 +0000 Matthew Waters + + * .gitmodules: + Update common submodule location + Remove the git directory + +2018-11-05 13:00:28 +0800 Haihao Xiang + + * .gitmodules: + * gstreamer-vaapi.doap: + Clone the code from gitlab + This fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/116 + +2018-10-24 14:18:37 -0400 Wangfei + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/video-format.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.h: + libs: dec: h265: support decode for main-10-422 10bit streams. + Add 422 10bit yuv format Y210, which can be used to decode + main-10-422 10bit streams. Currently, this feature is only + supported by media-driver in Icelake. + https://bugzilla.gnome.org/show_bug.cgi?id=797264 + +2018-10-13 15:00:32 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapicontext.c: + libs: context: roi_rc_qp_delta_support should not be checked when CQP. + VA_ROI_RC_QP_DELTA_SUPPORT return value will be ignored when the + rate control mode is set as CQP. In CQP mode, it shouldn't check + roi_rc_qp_delta_support return value from driver backend. + https://bugzilla.gnome.org/show_bug.cgi?id=797087 + +2018-10-15 17:55:24 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix classification string + The classification string is splitted by '/' and then looks for the + components. + This patch removes the ';' by unifying all the components. + +2018-10-15 16:05:02 +0100 Philippe Normand + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: Add Hardware classifier to metadata + +2018-10-12 16:37:34 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapicontext.c: + libs: context: create context first before using it to create surface. + In gst_vaapi_context_reset(), if the context has to be destroyed, make + sure to create it first before allocating its associated surfaces. + This patch fixes a regression introduced in commit 82872f4 because + the formats available in the current context now are ensured before + creating the context's surfaces. + https://bugzilla.gnome.org/show_bug.cgi?id=797277 + +2018-10-12 15:39:53 +0100 Philippe Normand + + * docs/plugins/inspect/plugin-vaapi.xml: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264_fei.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiencode_vp9.c: + gst: Advertise elements interacting with hardware devices + +2018-10-01 09:26:05 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + libs: context: query surface format before context to create surface. + Before using context to create surface, the supported surface format + should be checked first. + https://bugzilla.gnome.org/show_bug.cgi?id=797222 + +2018-10-09 17:23:55 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapivalue.c: + libs: replace g_error with GST_ERROR + And handle those errors rather than halting. + +2018-10-09 17:23:30 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + libs: replace g_warning with GST_WARNING + +2018-09-26 14:55:32 -0500 Matteo Valdina + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c: + libs: Move from g_debug to GST_DEBUG. + https://bugzilla.gnome.org/show_bug.cgi?id=797202 + +2018-10-04 02:20:10 +0800 Soon, Thean Siew + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: change the way of handling deinterlace + The current vaapipostproc calls driver's video processing + pipeline for deinterlacing only if it is Advance deinterlacing. + Modify in the way that it always tries with driver's video + processing pipeline for deinterlacing, and falls back to software + method of appending picture structure meta data only if it fails + with driver's method. + https://bugzilla.gnome.org/show_bug.cgi?id=797095 + +2018-09-24 16:54:29 -0500 Matteo Valdina + + * gst-libs/gst/vaapi/gstvaapiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapiutils_h264.h: + libs: h264: Update level table to "Recommendation H.264 (04/17)". + Added level 6, 6.1 and 6.2. Reference Table A-1 – Level limits + from T-REC-H.264-201704. + https://bugzilla.gnome.org/show_bug.cgi?id=797202 + +2018-09-20 09:57:33 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h: + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.h: + libs: dec: h265: add 422 chroma format support. + Add main-422-10 profile which support 422 chroma format stream. + Currently, this feature is only supported by media-driver in Icelake. + https://bugzilla.gnome.org/show_bug.cgi?id=797143 + +2018-09-26 19:34:06 +0200 U. Artie Eoff + + * tests/y4mreader.c: + tests: include sysdeps.h in compilation unit + Fixes https://bugzilla.gnome.org/show_bug.cgi?id=797204 + Signed-off-by: U. Artie Eoff + +2018-09-26 18:04:53 +0200 Víctor Manuel Jáquez Leal + + * tests/y4mreader.c: + * tests/y4mreader.h: + tests: fix compilation + https://bugzilla.gnome.org/show_bug.cgi?id=797204 + +2018-09-25 20:28:02 +0200 Víctor Manuel Jáquez Leal + + * tests/y4mreader.h: + tests: don's use sysdeps.h in header + +2018-09-14 19:30:56 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils.h: + libs: utils: no need of include config.h + +2018-09-13 18:12:02 +0200 Víctor Manuel Jáquez Leal + + * tests/decoder.c: + * tests/output.c: + * tests/test-decode.c: + * tests/test-subpicture.c: + tests: remove already include string.h + Since sysdeps.h includes string.h there's no need to include it again. + +2018-09-13 18:11:25 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + libs: remove already include string.h + Since sysdeps.h includes string.h there's no need to include it again. + +2018-09-13 18:26:27 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst/vaapi/gstvaapivideometa_texture.c: + libs: object: separation of internal API and plugins + Removed exposed macros GST_VAAPI_OBJECT_DISPLAY() and + GST_VAAPI_OBJECT_ID() to plugins, keeping them only for internal + library usage. + The purpose is readability. + https://bugzilla.gnome.org/show_bug.cgi?id=797139 + +2018-09-13 16:34:54 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiparser_frame.h: + libs: parser_frame: change macros for inlined functions + https://bugzilla.gnome.org/show_bug.cgi?id=797139 + +2018-09-13 16:10:13 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapivideopool_priv.h: + libs: videopool: remove unneeded code + The removed code comes frome the bad practice of copy&paste. Better + move it as internal function. + https://bugzilla.gnome.org/show_bug.cgi?id=797139 + +2018-09-13 12:22:42 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapiminiobject.c: + * gst-libs/gst/vaapi/gstvaapiminiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapipixmap.c: + * gst-libs/gst/vaapi/gstvaapipixmap_priv.h: + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/meson.build: + libs: remove dependency on IN_LIBGSTVAAPI_CORE + This conditional code was when libgstvaapi was intended to be library + used outside GStreamer. This not the case anymore, thus removing it. + https://bugzilla.gnome.org/show_bug.cgi?id=797139 + +2018-09-19 10:16:36 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + libs: dec: h265: fix the macros used for IDC profile + profile_idc flag in SPS only indicate the IDC profile, which may + need some other flags together to get the real profile. + https://bugzilla.gnome.org/show_bug.cgi?id=797160 + +2018-09-12 19:06:22 +0900 Jimmy Ohn + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: use g_clear_pointer() when possible + https://bugzilla.gnome.org/show_bug.cgi?id=797131 + +2018-09-03 13:56:52 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.h: + libs: filter: add gobject's cleanup function + +2018-05-22 14:28:40 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst-libs/gst/vaapi/gstvaapisurface_egl.c: + * tests/test-filter.c: + libs: filter: remove custom ref() and unref() + Replacing them by gst_object_ref() and gst_object_unref() + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-22 14:26:48 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + libs: filter: refactor filter as gobject + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 13:38:00 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + libs: decoder: remove destoy() and create() callbacks + They were all replaced by reset() + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 13:26:01 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + libs: decoder: vp9: implement reset() callback + remove destroy() and create() callback + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 13:25:37 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + libs: decoder: vp8: implement reset() callback + remove create() and destroy() callbacks + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 13:24:39 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + libs: decoder: vc1: implement reset() callback + remove destroy() and create() callbacks + use g_clear_pointer for rbdu_buffer + no cast for enum + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 13:24:13 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + libs: decoder: mpeg4: implement reset() callback + remove destroy() and create() callback + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 13:22:45 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + libs: decoder: mpeg2: implement reset() callback + remove create() and destroy() callbacks + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 13:22:07 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + libs: decoder: jpeg: implement reset() callback + and remove create() and destroy() callbacks. + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 13:13:31 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h265: implement reset() callback + and remove create() and destroy() + and use g_clear_pointer for dpb structure + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 13:11:41 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: remove create() and destroy() callbacks + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 11:56:11 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * tests/test-decode.c: + * tests/test-subpicture.c: + libs: decoder: remove gst_vaapi_decoder_unref() + Replaced by gst_object_unref() in tests + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 11:51:14 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + libs: decoder: remove gst_vaapi_decoder_ref() + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-21 11:50:17 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + libs: decoder: remove gst_vaapi_decoder_new() + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-05-18 16:09:31 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h: + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.h: + libs: decoder: refactor decoders as gobject + https://bugzilla.gnome.org/show_bug.cgi?id=796308 + +2018-08-31 20:56:13 -0500 Matteo Valdina + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Requests upstream a key unit at parse or decode error. + This is done to resume decoding after a parse error or decode error. + Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=797006 + +2018-08-31 20:48:13 -0500 Matteo Valdina + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: sets return value in failure case. + In gst_vaapidecode_handle_frame, when there is a decode error + there is a code path the returns an uninitialized value. + Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=797006 + +2018-08-30 18:56:40 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: lock at extracting available image formates + When running several vaapi elements at the concurrently, at + initialization, there is a race condition when extractin the avaible + formats for images and subpictures. + This patch add a lock when the those arrays are filled. + https://bugzilla.gnome.org/show_bug.cgi?id=797039 + +2018-08-31 14:47:55 +0530 Nirbheek Chauhan + + * meson.build: + meson: Sync libversion and osxversion code from other repos + gstreamer-vaapi does not build any libraries, only plugins, so this is + not used, but sync it just in case someone does add it in the future. + +2018-08-29 13:44:44 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + libs: encoder: h265: trivial documentation fix + +2018-08-30 11:08:07 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + libs: encoder: h265: add low delay B frame support. + Low delay B frame provide the function of transforming + P frame into low delay B frame which frame type is B, but + only reference predictive frames. This can be used when P + frame unsupported. Especially for P and B both unsupported, + in this case, I and low delay B frame can be encoded in a + stream. + https://bugzilla.gnome.org/show_bug.cgi?id=796984 + +2018-08-27 20:42:15 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: Avoid using picture after it has been free + In some cases, the found_picture ended up being evicted and freed, which + would lead to a use after free when accessing picture->base.poc. In this + fix, we take a ref on the picture before calling dpb_evict. + https://bugzilla.gnome.org/show_bug.cgi?id=787124 + +2018-07-25 17:03:19 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264decoder: Fail decoding slice with missing inter-view reference + Similarly to previous patch, we have no error concealment. As a side + effect, it's better to skip slices with missing references then passing + NULL pointers to the accelerator. Passing NULL pointer would lead to + major visual artifact, a behaviour that is likely undefined. + https://bugzilla.gnome.org/show_bug.cgi?id=787124 + +2017-09-14 14:25:41 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: reset context when the number of view is increased + Usually in case of MVC decoding, dpb size is increasedi if subset sps. + That's why it resets context without this patch. + But for some media it doesn't increase dpb size. Even in this case we + should reset context to deal with MVC decoding. + Otherwise, it leads to assert. + https://bugzilla.gnome.org/show_bug.cgi?id=787124 + +2018-07-25 13:50:23 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst/vaapi/gstvaapidecode.c: + vaapidecode: Skip unparsable units from adapter + If the unit could not be parsed, just skip this nal and keep parsing + what is left in the adapter. We need to flush the broken unit in the + decoder specific parser because the generic code does not know about + units boundary. This increases error resilliance. + Before this, the broken unit would stay in the adapter and EOS would be + returned. Which stopped the streaming. Just removing the EOS would have + lead to the adapter size growing indefinitely. + https://bugzilla.gnome.org/show_bug.cgi?id=796863 + +2018-07-24 12:40:00 -0400 Nicolas Dufresne + + * gst/vaapi/gstvaapidecode.c: + vaapidecoder: Don't error out on decode errors + This is problematic on live pipeline where loosing network can + cause an important amount of errors. + https://bugzilla.gnome.org/show_bug.cgi?id=796832 + +2018-07-25 15:47:49 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + h265decoder: Don't scan empty buffer + Same as what we did for H264 decoder, this is to avoid an assertion + in the adapter. + https://bugzilla.gnome.org/show_bug.cgi?id=796832 + +2018-07-25 20:21:51 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: h264: renable the vaapi category for logging + h264 log messages were logged in default category because a regression + in code. This patch renable the usage of vaapi logging category. + This regression was introduced in commit 7c365bdd. + +2018-07-18 13:09:42 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264decoder: Fail decoding slice if modification process failed + This patch chains up failure to executing the modification process. The + end result is that we now fail decoding the slice if this process fails. + This avoid sending a corrupted state to the accelerator. In some special + cases, this could lead to unrecoverable errors. + https://bugzilla.gnome.org/show_bug.cgi?id=796832 + +2018-07-18 13:07:51 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264decoder: Don't scan empty buffer + gst_adapter_masked_scan_uint32_peek() asserts if size is 0. Don't + try and scan in that case. This fixes assertion that would some times + happen when the stream is corrupted. + https://bugzilla.gnome.org/show_bug.cgi?id=796832 + +2018-07-04 12:51:10 +0800 Tianhao Liu + + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + libs: encoder: jpeg: set component id and Tqi + This change is due a problem encoding JPEGs with Intel's + media-driver: green/black image when playback jpeg + This patch sets component identifier and quantization table + destination selector in frame header to support packing headers + by Intel's media-driver that does not accept packed header + in AP level. + https://bugzilla.gnome.org/show_bug.cgi?id=796705 + +2018-06-25 14:20:32 +0200 Mathieu Duponchelle + + * gst/vaapi/gstvaapipluginutil.c: + pluginutil: downgrade unsupported driver logging + On systems with an Nvidia card, this error is output each time + the registry is rebuilt, which happens pretty often when + using gst-build as a development environment. + https://bugzilla.gnome.org/show_bug.cgi?id=796663 + +2018-06-24 13:07:20 +0200 Tim-Philipp Müller + + * gst/vaapi/gstvaapivideobufferpool.c: + Update for g_type_class_add_private() deprecation in recent GLib + +2018-05-30 16:01:36 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264dec: Remove false assumption about parity order + The decoder was trying to detect earlier that a field was lost base + on guessing the parity order. This breaks in streams were the parity + order changes. + This patch reverts the field order prediction code added by commit + 8dd93e9c8. + https://bugzilla.gnome.org/show_bug.cgi?id=796169 + +2018-05-18 17:03:57 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264dec: Properly set sentinel in ref frame list + This ensure that we always have sentinels set in the reference + pictures arrays. The code wasn't unsafe, this simply improve the + tracing, so instead of printing 32 lines of zeros, va tracer + prints proper empty lists. + https://bugzilla.gnome.org/show_bug.cgi?id=796169 + +2018-06-13 18:00:18 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideometa.c: + * tests/test-decode.c: + libs: display: remove gst_vaapi_display_ref() + Replace it with gst_object_ref() + https://bugzilla.gnome.org/show_bug.cgi?id=796470 + +2018-06-13 17:54:23 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * tests/output.c: + * tests/simple-encoder.c: + * tests/test-decode.c: + * tests/test-display.c: + * tests/test-fei-enc-in.c: + * tests/test-filter.c: + * tests/test-subpicture.c: + * tests/test-surfaces.c: + * tests/test-textures.c: + * tests/test-windows.c: + libs: display: remove gst_vaapi_display_unref() + Use gst_object_unref() instead. + https://bugzilla.gnome.org/show_bug.cgi?id=796470 + +2018-06-13 18:10:28 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapibufferpool: declare parameter display as object + We have neglected to update this code since GstVaapiDisplay turned + into a GstObject descendant. + https://bugzilla.gnome.org/show_bug.cgi?id=796470 + +2018-06-01 12:36:51 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + libs: display: replace gst_vaapi_display_new() with gst_vaapi_display_config() + Gobjectification for GstVaapiDisplay was almost done by the commit 185da3d1. + But still something breaking GObject code convention remains, which is + calling gst_vaapi_display_new() in each decendants. + This patch replaces it with gst_vaapi_display_config(), defined in private + header. + https://bugzilla.gnome.org/show_bug.cgi?id=796470 + +2018-06-13 17:05:40 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: redefine gst_vaapi_display_create() + The function name was gst_vaapi_display_create_unlocked(), nonetheless + it wasn't called unlocked. In order to keep the semantics this patch + renames the gst_vaapi_display_create_unlocked() as + gst_vaapi_display_create(), removing the previous function + gst_vaapi_display_create(). + https://bugzilla.gnome.org/show_bug.cgi?id=796470 + +2018-06-12 15:53:04 +0200 Víctor Manuel Jáquez Leal + + * meson.build: + Revert "build: meson: libva gst-uninstall friendly" + This reverts commit fc3eef9c432c1628cb92ab56e74924cf1182da30. + +2018-06-12 15:13:33 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: fix compilation + gstvaapipluginutil.c:171:1: error: old-style function definition [-Werror=old-style-definition] + +2018-04-20 18:05:30 +0200 Víctor Manuel Jáquez Leal + + * meson.build: + build: meson: libva gst-uninstall friendly + Make gstreamer-vaapi to use libva uninstalled. + +2018-06-10 10:44:35 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: refactor gst_vaapi_create_display_from_gl_context() + gst_vaapi_create_display_from_gl_context() was a spaghetti mess. + This path refactors it, in order to make the code readable and + easy to follow. + https://bugzilla.gnome.org/show_bug.cgi?id=796564 + +2018-05-25 12:17:21 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + libs: display: resurrect parent private member + This is, practically, a revert of commit dcf135e2. + The parent logic is useful for the EGL display, which is a decorator + of the real windowing subsystem (X11 or Wayland). Thus it is avoided + calling vaInitialize() and vaTerminate() twice. + https://bugzilla.gnome.org/show_bug.cgi?id=795391 + +2018-04-27 18:35:30 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + libs: display: egl: initialize params structure + Statically initialise the internal params structure. + https://bugzilla.gnome.org/show_bug.cgi?id=795391 + +2018-04-27 18:34:37 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: handle EGL when creating VAAPI display from gl + If GstGL reports a EGL platform force to create a EGL display using + the native EGL display. + https://bugzilla.gnome.org/show_bug.cgi?id=795391 + +2018-04-24 18:17:24 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidisplay_egl.c: + * gst/vaapi/gstvaapipluginutil.c: + display: egl: create VaapiDisplayEGL with native EGL display + gst_vaapi_display_egl_new_with_native_display() has been broken since + it wasn't used. + Currently it's needed to call this API to create a display providing + the EGL display, so it could avoid duplicated calls to the native + display (eg. eglTerminate). + Signed-off-by: Victor Jaquez + https://bugzilla.gnome.org/show_bug.cgi?id=795391 + +2018-06-07 09:34:11 +0800 Tianhao Liu + + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + libs: decoder: release VA buffers after vaEndPicture + This change is due a problem decoding JPEGs with Intel's media-driver: + no image was generated. + This patch relases the VA buffers after vaEndPicture() is called, + and not before (after vaRenderPicture()). + https://bugzilla.gnome.org/show_bug.cgi?id=796505 + +2018-06-07 19:49:02 +0100 Tim-Philipp Müller + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + meson: fix build when xrender or xrandr are not available + HAVE_XRENDER are defined to 1 or 0, not defined or undefined. + +2018-05-25 16:47:00 +0200 Michael Olbrich + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: don't copy the GstParentBufferMeta if use_vpp + Otherwise a reference to a DMABuf input buffer is kept until the output + buffer is deleted. + https://bugzilla.gnome.org/show_bug.cgi?id=796399 + +2018-05-22 21:13:08 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + libs: display: remove unnecessary legacy code since gobjectification + https://bugzilla.gnome.org/show_bug.cgi?id=796470 + +2018-05-22 21:05:54 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + libs: display: remove unused code + https://bugzilla.gnome.org/show_bug.cgi?id=796470 + +2018-06-05 15:16:53 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: h264: log output caps + +2018-06-05 22:38:37 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: h264: find profile in available and allowed caps + The commit 67e33d3de225d0e006d7bf606e7abb20d4544eab ("vaapiencode: h264: + find best profile in those available") changed the code to pick a profile + that is actually supported by the hardware. Unfortunately it dropped the + downstream constraints. This can cause negotiation failures under certain + circumstances. + The fix is split in two cases: + 1\ the available VA-API caps doesn't intersect with pipeline's allowed + caps: + * The best allowed profile (pipeline's caps) is set as the encoding + target profile (it will be adjusted later by the available profiles + and properties) + 2\ the available VA-API caps does intersect with pipeline's allowed + caps: + * The intersected caps are fixed, and its profile is set as the + encoding target profile. In this case the is not the best profile, + but the minimal one (if VA-API reports the profiles in order). + Setting the minimal profile of the intersected caps is better for + compatibility. + This patch fixes other tests related with caps negotiation, for + example, it handles baseline profile, even when VA only supports + constrained-baseline. + Original-patch-by: Michael Olbrich + https://bugzilla.gnome.org/show_bug.cgi?id=794306 + +2018-06-01 15:27:25 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: increase log2_max_pic_order_cnt range according to spec + The specification says, + "log2_max_pic_order_cnt_lsb_minus4 shall be in the range of 0 to 12, inclusive." + This patch changes the upper limit from 6 to 12. + https://bugzilla.gnome.org/show_bug.cgi?id=796179 + +2018-05-21 13:27:14 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: guard GstGL code + +2018-05-18 18:23:18 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: use g_clear_pointer() + +2018-05-18 17:27:46 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.h: + libs: decoder: mpeg4, vc1: remove unused header + +2018-05-18 11:09:58 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_priv.h: + libs: decoder: remove unused forward declaration + +2018-05-07 07:59:25 -0700 U. Artie Eoff + + * configure.ac: + fix configure.ac regression + Fixes regression introduced by 77527d67abe + https://bugzilla.gnome.org/show_bug.cgi?id=795885 + +2018-05-05 17:57:49 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/Makefile.am: + * gst-libs/gst/base/Makefile.am: + * gst-libs/gst/base/gstbitwriter.c: + * gst-libs/gst/base/gstbitwriter.h: + * gst-libs/gst/base/meson.build: + * gst-libs/gst/meson.build: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapifeipak_h264.c: + * gst-libs/gst/vaapi/meson.build: + libs: remove gstbitwriter + Since it is deployed in gstreamer-core, there is no need to use + our custom version. + https://bugzilla.gnome.org/show_bug.cgi?id=795848 + +2018-04-28 16:10:46 +0800 Wang,Fei + + * gst/vaapi/gstvaapidecode.c: + vaapih264dec: add constrained and progressive profiles + Those profiles have been added in the version 2012-01 + and 2011-06 of the AVC spec (A.2.4.1 and A.2.4.2). + Both are supported by VAProfileH264High + https://bugzilla.gnome.org/show_bug.cgi?id=795624 + +2018-04-26 18:15:47 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideocontext.h: + plugin: remove custom GstGL context handling + Instead of using our own context handling for looking for GstGL + parameters (display, context and other context), this patch changes + the logic to use the utility function offered by GstGL. + https://bugzilla.gnome.org/show_bug.cgi?id=793643 + +2018-04-26 15:03:23 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: GstGL API must use the member variables + This commit basically is a revert of commits 8092537 and fc1c415 + https://bugzilla.gnome.org/show_bug.cgi?id=793643 + +2018-04-25 16:24:32 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapipluginbase.c: + plugins: pass members as parameters of gst_gl_ensure_element_data() + The parameters of gst_gl_ensure_element_data() have to be not + local variable since they are going to be used to see if they're + set in gst_element_set_context() inside the API. + This is basically a revert of commit 3d56306c + https://bugzilla.gnome.org/show_bug.cgi?id=793643 + +2018-04-25 17:50:14 +0200 Víctor Manuel Jáquez Leal + + * meson.build: + meson: fix USE_GLES_VERSION_MASK + 1. The macro in the code is USE_GLES_VERSION_MASK + 2. glesv3 is provided by glesv2 pkg-config, then it's required to + check headers + https://bugzilla.gnome.org/show_bug.cgi?id=795391 + +2018-04-24 18:12:44 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + libs: egl: utils: mark context as wrapped when it is + The returning egl context may be null, so we should check the + return value. + https://bugzilla.gnome.org/show_bug.cgi?id=795391 + +2018-04-24 10:02:33 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + libs: egl: utils: fix usage of GstGL macros + Include gl.h for the required GstGL symbols. + https://bugzilla.gnome.org/show_bug.cgi?id=795391 + +2018-04-25 11:01:45 +0100 Tim-Philipp Müller + + * meson.build: + meson: use -Wl,-Bsymbolic-functions where supported + Just like the autotools build. + +2018-04-20 16:01:29 +0200 Víctor Manuel Jáquez Leal + + * meson.build: + meson: use get_pkgconfig_variable() + Use get_pkgconfig_variable() method, of dependency class, rather + than using run_command(). + +2018-04-20 11:50:55 +0100 Tim-Philipp Müller + + * gst-libs/gst/base/meson.build: + * gst-libs/gst/vaapi/meson.build: + * meson.build: + meson: fix miscellaneous meson warnings + WARNING: Passed invalid keyword argument "rqeuired". + gst-libs/gst/base/meson.build:11: WARNING: Passed invalid keyword argument "version". + gst-libs/gst/base/meson.build:11: WARNING: Passed invalid keyword argument "soversion". + gst-libs/gst/vaapi/meson.build:223: WARNING: Passed invalid keyword argument "version". + gst-libs/gst/vaapi/meson.build:223: WARNING: Passed invalid keyword argument "soversion". + +2018-03-30 13:41:39 +0200 Paul Kocialkowski + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + display: drm: Allow finding DRM paths out of the PCI subsystem + This removes hard-coded checks on the parent subsystem of potential DRM + devices. These checks were set to exlude devices that do not originate + from the PCI bus, which is only a valid approach on x86 devices. + Other devices may have a DRM device originating from the platform + subsystem, so the checks that were previously restricted to PCI are + extended to cover platform devices as well. + https://bugzilla.gnome.org/show_bug.cgi?id=794840 + Signed-off-by: Paul Kocialkowski + +2017-11-08 13:27:06 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapivideocontext.c: + videocontext: support wl-display in "gst.vaapi.app.Display" + Through "gst.vaapi.app.Display" context, users can set their own + VADisplay and native display of their backend. + So far we support only X11 display, from now we also support Wayland + display. + Attributes: + - wl-display : pointer of struct wl_display . + https://bugzilla.gnome.org/show_bug.cgi?id=705821 + +2017-11-08 13:26:38 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.h: + libs: display: wayland: add gst_vaapi_display_wayland_new_with_va_display() + Implements new API function so that users could create GstVaapiDisplay + with their own VADisplay within a native display as backend. + https://bugzilla.gnome.org/show_bug.cgi?id=705821 + +2018-04-13 09:28:53 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + wayland: don't poll if there are no pending frames + Otherwise the following poll may not return for an arbitrary amount of + time. This can happen if another wayland event queue has flushed and read + our events. + https://bugzilla.gnome.org/show_bug.cgi?id=795224 + +2017-10-16 12:09:08 +0900 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: 16 bit rounding of picture width and height + pic_width_in_luma_samples/pic_height_in_luma_samples can be 16-bit rounded + instead of 32-bit. + In addition, codedbuf_size must be calculated according to this change. + https://bugzilla.gnome.org/show_bug.cgi?id=753229 + +2018-04-16 10:53:47 +0100 Tim-Philipp Müller + + * common: + Automatic update of common submodule + From 3fa2c9e to ed78bee + +2018-03-30 20:39:18 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: h264: find best profile in those available + Instead to look for the best profile in the allowed profiles by + downstream, the encoder should look for the base profile in the + available profile in VA-API. + https://bugzilla.gnome.org/show_bug.cgi?id=794306 + +2018-03-20 10:49:10 +0000 Tim-Philipp Müller + + * NEWS: + * RELEASE: + * configure.ac: + * docs/plugins/inspect/plugin-vaapi.xml: + * meson.build: + Back to development + === release 1.14.0 === 2018-03-19 20:30:28 +0000 Tim-Philipp Müller diff --git a/NEWS b/NEWS index 5366a0dfcd..1e860c47a6 100644 --- a/NEWS +++ b/NEWS @@ -3,23 +3,19 @@ GSTREAMER 1.16 RELEASE NOTES -GStreamer 1.16 has not been released yet. It is scheduled for release -around September 2018. +GStreamer 1.16 has not been released yet. It is scheduled for release in +January/February 2019. -1.15.0.1 is the unstable development version that is being developed in +1.15.x is the unstable development version that is being developed in the git master branch and which will eventually result in 1.16. -The plan for the 1.16 development cycle is yet to be confirmed, but it -is expected that feature freeze will be around August 2017 followed by -several 1.15 pre-releases and the new 1.16 stable release in September. - 1.16 will be backwards-compatible to the stable 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.16/ for the latest version of this document. -_Last updated: Tuesday 20 March 2018, 01:30 UTC (log)_ +_Last updated: Monday 14 January 2019, 13:00 UTC (log)_ Introduction @@ -34,63 +30,705 @@ other improvements. Highlights -- this section will be completed in due course +- GStreamer WebRTC stack gained support for data channels for + peer-to-peer communication based on SCTP, BUNDLE support, as well as + support for multiple TURN servers. + +- AV1 video codec support for Matroska and QuickTime/MP4 containers + and more configuration options and supported input formats for the + AOMedia AV1 encoder + +- Support for Closed Captions and other Ancillary Data in video + +- Spport for planar (non-interleaved) raw audio + +- GstVideoAggregator, compositor and OpenGL mixer elements are now in + -base + +- New alternate fields interlace mode where each buffer carries a + single field + +- WebM and Matroska ContentEncryption support in the Matroska demuxer + +- new WebKit WPE-based web browser source element + +- Video4Linux: HEVC encoding and decoding, JPEG encoding, and improved + dmabuf import/export + +- Hardware-accelerated Nvidia video decoder gained support for VP8/VP9 + decoding, whilst the encoder gained support for H.265/HEVC encoding. + +- Many improvements to the Intel Media SDK based hardware-accelerated + video decoder and encoder plugin (msdk): dmabuf import/export for + zero-copy integration with other components; VP9 decoding; 10-bit + HEVC encoding; video post-processing (vpp) support including + deinterlacing; and the video decoder now handles dynamic resolution + changes. + +- The ASS/SSA subtitle overlay renderer can now handle multiple + subtitles that overlap in time and will show them on screen + simultaneously + +- The Meson build is now feature-complete (*) and it is now the + recommended build system on all platforms. The Autotools build is + scheduled to be removed in the next cycle. + +- The GStreamer Rust bindings and Rust plugins module are now + officially part of upstream GStreamer. + +- Many performance improvements Major new features and changes Noteworthy new API -- this section will be filled in in due course +- GstAggregator has a new "min-upstream-latency" property that forces + a minimum aggregate latency for the input branches of an aggregator. + This is useful for dynamic pipelines where branches with a higher + latency might be added later after the pipeline is already up and + running and where a change in the latency would be disruptive. This + only applies to the case where at least one of the input branches is + live though, it won’t force the aggregator into live mode in the + absence of any live inputs. + +- GstBaseSink gained a "processing-deadline" property and + setter/getter API to configure a processing deadline for live + pipelines. The processing deadline is the acceptable amount of time + to process the media in a live pipeline before it reaches the sink. + This is on top of the systemic latency that is normally reported by + the latency query. This defaults to 20ms and should make pipelines + such as “v4lsrc ! xvimagesink” not claim that all frames are late in + the QoS events. Ideally, this should replace max_lateness for most + applications. + +- RTCP Extended Reports (XR) parsing according to RFC 3611: + Loss/Duplicate RLE, Packet Receipt Times, Receiver Reference Time, + Delay since the last Receiver (DLRR), Statistics Summary, and VoIP + Metrics reports. + +- a new mode for interlaced video was added where each buffer carries + a single field of interlaced video, with buffer flags indicating + whether the field is the top field or bottom field. Top and bottom + fields are expected to alternate in this mode. Caps for this + interlace mode must also carry a format:Interlaced caps feature to + ensure backwards compatibility. + +- The video library has gained support for three new raw pixel + formats: + + - Y410: packed 4:4:4 YUV, 10 bits per channel + - Y210: packed 4:2:2 YUV, 10 bits per channel + - NV12_10LE40: fully-packed 10-bit variant of NV12_10LE32, + i.e. without the padding bits + +- GstRTPSourceMeta is a new meta that can be used to transport + information about the origin of depayloaded or decoded RTP buffers, + e.g. when mixing audio from multiple sources into a single stream. A + new "source-info" property on the RTP depayloader base class + determines whether depayloaders should put this meta on outgoing + buffers. Similarly, the same property on RTP payloaders determines + whether they should use the information from this meta to construct + the CSRCs list on outgoing RTP buffers. + +- gst_sdp_message_from_text() is a convenience constructor to parse + SDPs from a string which is particularly useful for language + bindings. + +Support for Planar (Non-Interleaved) Raw Audio + +Raw audio samples are usually passed around in interleaved form in +GStreamer, which means that if there are multiple audio channels the +samples for each channel are interleaved in memory, e.g. +|LEFT|RIGHT|LEFT|RIGHT|LEFT|RIGHT| for stereo audio. A non-interleaved +or planar arrangement in memory would look like +|LEFT|LEFT|LEFT|RIGHT|RIGHT|RIGHT| instead, possibly with +|LEFT|LEFT|LEFT| and |RIGHT|RIGHT|RIGHT| residing in separate memory +chunks or separated by some padding. + +GStreamer has always had signalling for non-interleaved audio, but it +was never actually properly implemented in any elements. audioconvert +would advertise support for it, but wasn’t actually able to handle it. + +With this release we now have full support for non-interleaved audio as +well, which means more efficient integration with external APIs that +handle audio this way, but also more efficient processing of certain +operations like interleaving multiple 1-channel streams into a +multi-channel stream which can be done without memory copies now. + +New API to support this has been added to the GStreamer Audio support +library: There is now a new GstAudioMeta which describes how data is +laid out inside the buffer, and buffers with non-interleaved audio must +always carry this meta. To access the non-interleaved audio samples you +must map such buffers with gst_audio_buffer_map() which works much like +gst_buffer_map() or gst_video_frame_map() in that it will populate a +little GstAudioBuffer helper structure passed to it with the number of +samples, the number of planes and pointers to the start of each plane in +memory. This function can also be used to map interleaved audio buffers +in which case there will be only one plane of interleaved samples. + +Of course support for this has also been implemented in the various +audio helper and conversion APIs, base classes, and in elements such as +audioconvert, audioresample, audiotestsrc, audiorate. + +Support for Closed Captions and Other Ancillary Data in Video + +The video support library has gained support for detecting and +extracting Ancillary Data from videos as per the SMPTE S291M +specification, including: + +- a VBI (Video Blanking Interval) parser that can detect and extract + Ancillary Data from Vertical Blanking Interval lines of component + signals. This is currently supported for videos in v210 and UYVY + format. + +- a new GstMeta for closed captions: GstVideoCaptionMeta. This + supports the two types of closed captions, CEA-608 and CEA-708, + along with the four different ways they can be transported (other + systems are a superset of those). + +- a VBI (Video Blanking Interval) encoder for writing ancillary data + to the Vertical Blanking Interval lines of component signals. + +The new closedcaption plugin in gst-plugins-bad then makes use of all +this new infrastructure and provides the following elements: + +- cccombiner: a closed caption combiner that takes a closed captions + stream and another stream and adds the closed captions as + GstVideoCaptionMeta to the buffers of the other stream. + +- ccextractor: a closed caption extractor which will take + GstVideoCaptionMeta from input buffers and output them as a separate + closed captions stream. + +- ccconverter: a closed caption converter that can convert between + different formats + +- line21decoder: extract line21 closed captions from SD video streams + +- cc708overlay: decodes CEA 608/708 captions and overlays them on + video + +Additionally, the following elements have also gained Closed Caption +support: + +- qtdemux and qtmux support CEA 608/708 Closed Caption tracks + +- mpegvideoparse extracts Closed Captions from MPEG-2 video streams + +- decklinkvideosink can output closed captions and decklinkvideosrc + can extract closed captions + +- playbin and playbin3 learned how to autoplug CEA 608/708 CC overlay + elements + +The rsclosedcaption plugin in the Rust plugins collection includes a +MacCaption (MCC) file parser and encoder. New Elements -- this section will be filled in in due course +- overlaycomposition: New element that allows applications to draw + GstVideoOverlayCompositions on a stream. The element will emit the + "draw" signal for each video buffer, and the application then + generates an overlay for that frame (or not). This is much more + performant than e.g. cairooverlay for many use cases, e.g. because + pixel format conversions can be avoided or the blitting of the + overlay can be delegated to downstream elements (such as + gloverlaycompositor). It’s particularly useful for cases where only + a small section of the video frame should be drawn on. + +- gloverlaycompositor: New OpenGL-based compositor element that + flattens any overlays from GstVideoOverlayCompositionMetas into the + video stream. + +- glalpha: New element that adds an alpha channel to a video stream. + The values of the alpha channel can either be set to a constant or + can be dynamically calculated via chroma keying. It is similar to + the existing alpha element but based on OpenGL. Calculations are + done in floating point so results may not be identical to the output + of the existing alpha element. + +- rtpfunnel funnels together rtp-streams into a single session. Use + cases include multiplexing and bundle. webrtcbin uses it to + implement BUNDLE support. + +- testsrcbin is a source element that provides an audio and/or video + stream and also announces them using the recently-introduced + GstStream API. This is useful for testing elements such as playbin3 + or uridecodebin3 etc. + +- New closed caption elements: cccombiner, ccextractor, ccconverter, + line21decoder and cc708overlay (see above) + +- wpesrc: new source element acting as a Web Browser based on WebKit + WPE + +- Two new OpenCV-based elements: cameracalibrate and cameraundistort + who can communicate to figure out distortion correction parameters + for a camera and correct for the distortion. + +- new sctp plugin based on usrsctp with sctpenc and sctpdec elements New element features and additions -- this section will be filled in in due course +- playbin3, playbin and playsink have gained a new "text-offset" + property to adjust the positioning of the selected subtitle stream + vis-a-vis the audio and video streams. This uses subtitleoverlay’s + new "subtitle-ts-offset" property. GstPlayer has gained matching API + for this, namely gst_player_get_text_video_offset(). + +- playbin3 buffering improvements: in network playback scenarios there + may be multiple inputs to decodebin3, and buffering will be done + before decodebin3 using queue2 or downloadbuffer elements inside + urisourcebin. Since this is before any parsers or demuxers there may + not be any bitrate information available for the various streams, so + it was difficult to configure the buffering there smartly within + global constraints. This was improved now: The queue2 elements + inside urisourcebin will now use the new bitrate query to figure out + a bitrate estimate for the stream if no bitrate was provided by + upstream, and urisourcebin will use the bitrates of the individual + queues to distribute the globally-set "buffer-size" budget in bytes + to the various queues. urisourcebin also gained "low-watermark" and + "high-watermark" properties which will be proxied to the internal + queues, as well as a read-only "statistics" property which allows + querying of the minimum/maximum/average byte and time levels of the + queues inside the urisourcebin in question. + +- splitmuxsink has gained a couple of new features: + + - new "async-finalize" mode: This mode is useful for muxers or + outputs that can take a long time to finalize a file. Instead of + blocking the whole upstream pipeline while the muxer is doing + its stuff, we can unlink it and spawn a new muxer + sink + combination to continue running normally. This requires us to + receive the muxer and sink (if needed) as factories via the new + "muxer-factory" and "sink-factory" properties, optionally + accompanied by their respective properties structures (set via + the new "muxer-properties" and "sink-properties" properties). + There are also new "muxer-added" and "sink-added" signals in + case custom code has to be called for them to configure them. + + - "split-at-running-time" action signal: When called by the user, + this action signal ends the current file (and starts a new one) + as soon as the given running time is reached. If called multiple + times, running times are queued up and processed in the order + they were given. + + - "split-after" action signal to finish outputting the current GOP + to the current file and then start a new file as soon as the GOP + is finished and a new GOP is opened (unlike the existing + "split-now" which immediately finishes the current file and + writes the current GOP into the next newly-started file). + + - "reset-muxer" property: when unset, the muxer is reset using + flush events instead of setting its state to NULL and back. This + means the muxer can keep state across resets, e.g. mpegtsmux + will keep the continuity counter continuous across segments as + required by hlssink2. + +- qtdemux gained PIFF track encryption box support in addition to the + already-existing PIFF sample encryption support, and also allows + applications to select which encryption system to use via a + "drm-preferred-decryption-system-id" context in case there are + multiple options. + +- qtmux: the "start-gap-threshold" property determines now whether an + edit list will be created to account for small gaps or offsets at + the beginning of a stream in case the start timestamps of tracks + don’t line up perfectly. Previously the threshold was hard-coded to + 1% of the (video) frame duration, now it is 0 by default (so edit + list will be created even for small differences), but fully + configurable. + +- rtpjitterbuffer has improved end-of-stream handling + +- rtpmp4vpay will be prefered over rtpmp4gpay for MPEG-4 video in + autoplugging scenarios now + +- rtspsrc now allows applications to send RTSP SET_PARAMETER and + GET_PARAMETER requests using action signals. + +- rtspsrc also has a small (100ms) configurable teardown delay by + default to try and make sure an RTSP TEARDOWN request gets sent out + when the source element shuts down. This will block the downward + PAUSED to READY state change for a short time, but can be unset + where it’s a problem. Some servers only allow a limited number of + concurren clients, so if no proper TEARDOWN is sent clients may have + problems connecting to the server for a while. + +- souphttpsrc behaves better with low bitrate streams now. Before it + would increase the read block size too quickly which could lead to + it not reading any data from the socket for a very long time with + low bitrate streams that are output live downstream. This could lead + to servers kicking off the client. + +- filesink: do internal buffering to avoid performance regression with + small writes since we bypass libc buffering by using writev() + +- identity: add "eos-after" property and fix "error-after" property + when the element is reused + +- input-selector: lets context queries pass through, so that + e.g. upstream OpenGL elements can use contexts and displays + advertised by downstream elements + +- queue2: avoid ping-pong between 0% and 100% buffering messages if + upstream is pushing buffers larger than one of its limits, plus + performance optimisations + +- opusdec: new "phase-inversion" property to control phase inversion. + When enabled, this will slightly increase stereo quality, but + produces a stream that when downmixed to mono will suffer audio + distortions. + +- The x265enc HEVC encoder also exposes a "key-int-max" property to + configure the maximum allowed GOP size now. + +- decklinkvideosink has seen stability improvements for long-running + pipelines (potential crash due to overflow of leaked clock refcount) + and clock-slaving improvements when performing flushing seeks + (causing stalls in the output timeline), pausing and/or buffering. + +- srtpdec, srtpenc: add support for MKIs which allow multiple keys to + be used with a single SRTP stream + +- The srt Secure Reliable Transport plugin has integrated server and + client elements srt{client,server}{src,sink} into one (srtsrc and + srtsink), since SRT connection mode can be changed by uri + parameters. + +- h264parse and h265parse will handle SEI recovery point messages and + mark recovery points as keyframes as well (in addition to IDR + frames) + +- webrtcbin: "add-turn-server" action signal to pass multiple ICE + relays (TURN servers). + +- The removesilence element has received various new features and + properties, such as a + "threshold"1 property, detecting silence only after minimum silence time/buffers, a“silent”property to control bus message notifications as well as a“squash”` + property. + +- AOMedia AV1 decoder gained support for 10/12bit decoding whilst the + AV1 encoder supports more image formats and subsamplings now and + acquired support for rate control and profile related configuration. + +- The Fraunhofer fdkaac plugin can now be built against the 2.0.0 + version API and has improved multichannel support + +- kmssink now supports unpadded 24-bit RGB and can configure mode + setting from video info, which enables display of multi-planar + formats such as I420 or NV12 with modesetting. It has also gained a + number of new properties: The "restore-crtc" property does what it + says on the tin and is enabled by default. "plane-properties" and + "connector-properties" can be used to pass custom properties to the + DRM. + +- waylandsink has a "fullscreen" property now. Plugin and library moves -- this section will be filled in in due course +- The stereo element was moved from -bad into the existing audiofx + plugin in -good. If you get duplicate type registration warnings + when upgrading, check that you don’t have a stale gststereo plugin + lying about somewhere. + +GstVideoAggregator, compositor, and OpenGL mixer elements moved from -bad to -base + +GstVideoAggregator is a new base class for raw video mixers and muxers +and is based on [GstAggregator][aggregator]. It provides defined-latency +mixing of raw video inputs and ensures that the pipeline won’t stall +even if one of the input streams stops producing data. + +As part of the move to stabilise the API there were some last-minute API +changes and clean-ups, but those should mostly affect internal elements. +Most notably, the "ignore-eos" pad property was renamed to +"repeat-after-eos" and the conversion code was moved to a +GstVideoAggregatorConvertPad subclass to avoid code duplication, make +things less awkward for subclasses like the OpenGL-based video mixer, +and make the API more consistent with the audio aggregator API. + +It is used by the compositor element, which is a replacement for +‘videomixer’ which did not handle live inputs very well. compositor +should behave much better in that respect and generally behave as one +would expected in most scenarios. + +The compositor element has gained support for per-pad blending mode +operators (SOURCE, OVER, ADD) which determines what operator to use for +blending this pad over the previous ones. This can be used to implement +crossfading. + +A number of OpenGL-based video mixer elements (glvideomixer, glmixerbin, +glvideomixerelement, glstereomix, glmosaic) which are built on top of +GstVideoAggregator have also been moved from -bad to -base now. These +elements have been merged into the existing OpenGL plugin, so if you get +duplicate type registration warnings when upgrading, check that you +don’t have a stale gstopenglmixers plugin lying about somewhere. Plugin removals -- this section will be filled in in due course +The following plugins have been removed from gst-plugins-bad: + +- The experimental daala plugin has been removed, since it’s not so + useful now that all effort is focused on AV1 instead, and it had to + be enabled explicitly with --enable-experimental anyway. + +- The spc plugin has been removed. It has been replaced by the gme + plugin. + +- The acmmp3dec and acmenc plugins for Windows have been removed. ACM + is an ancient legacy API and there was no point in keeping them + around for a licensed mp3 decoder now that mp3 patents have expired + and we have a decoder in -good. We also didn’t ship these in our + cerbero-built Windows packages, so it’s unlikely that they’ll be + missed. Miscellaneous API additions -- this section will be filled in in due course +- GstBitwriter: new generic bit writer API to complement the existing + bit reader + +- gst_buffer_new_wrapped_bytes() creates a wrap buffer from a GBytes + +- gst_caps_set_features_simple() sets a caps feature on all the + structures of a GstCaps + +- New GST_QUERY_BITRATE query: This allows determining from downstream + what the expected bitrate of a stream may be which is useful in + queue2 for setting time based limits when upstream does not provide + timing information. tsdemux, qtdemux and matroskademux have basic + support for this query on their sink pads. + +- elements: there is a new “Hardware” class specifier. Elements + interacting with hardware devices should specify this classifier in + their element factory class metadata. This is useful to advertise as + one might need to put such elements into READY state to test if the + hardware is present in the system for example. + +- protection: Add a new definition for unspecified system protection + +- take functions for various mini objects that didn’t have them yet: + gst_query_take(), gst_message_take(), gst_tag_list_take(), + gst_buffer_list_take(). Unlike the various _replace() functions + _take() does not increase the reference count but takes ownership of + the mini object passed. + +- clear functions for various mini object types and GstObject which + unrefs the object or mini object (if non-NULL) and sets the variable + pointed to to NULL: gst_clear_structure(), gst_clear_tag_list(), + gst_clear_query(), gst_clear_message(), gst_clear_event(), + gst_clear_caps(), gst_clear_buffer_list(), gst_clear_buffer(), + gst_clear_mini_object(), gst_clear_object() + +- miniobject: new API gst_mini_object_add_parent() and + gst_mini_object_remove_parent()to set parent pointers on mini objects to ensure correct writability: Every container of miniobjects now needs to store itself as parent in the child object, and remove itself again later. A mini object is then only writable if there is at most one parent, that parent is writable itself, and the reference count of the mini object is 1.GstBuffer(for memories),GstBufferList(for buffers),GstSample(for caps, buffer, bufferlist), andGstVideoOverlayComposition` + were updated accordingly. Without this it was possible to have + e.g. a buffer list with a refcount of 2 used in two places at once + that both modify the same buffer with refcount 1 at the same time + wrongly thinking it is writable even though it’s really not. + +- poll: add API to watch for POLLPRI and stop treating POLLPRI as a + read. This is useful to wait for video4linux events which are + signalled via POLLPRI. + +- sample: new API to update the contents of a GstSample and make it + writable: gst_sample_set_buffer(), gst_sample_set_caps(), + gst_sample_set_segment(), gst_sample_set_info(), plus + gst_sample_is_writable() and gst_sample_make_writable(). This makes + it possible to reuse a sample object and avoid unnecessary memory + allocations, for example in appsink. + +- ClockIDs now keep a weak reference to underlying clock to avoid + crashes in basesink in corner cases where a clock goes away while + the ClockID is still in use, plus some new API + (gst_clock_id_get_clock(), gst_clock_id_uses_clock()) to check the + clock a ClockID is linked to. + +- The GstCheck unit test library gained a + fail_unless_equals_clocktime() convenience macro as well as some new + GstHarness API for for proposing meta APIs from the allocation + query: gst_harness_add_propose_allocation_meta(). ASSERT_CRITICAL() + checks in unit tests are now skipped if GStreamer was compiled with + GST_DISABLE_GLIB_CHECKS. + +- gst_audio_buffer_truncate() convenience function to truncate a raw + audio buffer + + +Miscellaneous performance and memory optimisations + +As always there have been many performance and memory usage improvements +across all components and modules. Some of them (such as dmabuf +import/export) have already been mentioned elsewhere so won’t be +repeated here. + +The following list is only a small snapshot of some of the more +interesting optimisations that haven’t been mentioned in other contexts +yet: + +- The GstVideoEncoder and GstVideoDecoder base classes now release the + STREAM_LOCK when pushing out buffers, which means (multi-threaded) + encoders and decoders can now receive and continue to process input + buffers whilst waiting for downstream elements in the pipeline to + process the buffer that was pushed out. This increases throughput + and reduces processing latency, also and especially for + hardware-accelerated encoder/decoder elements. + +- GstQueueArray has seen a few API additions + (gst_queue_array_peek_nth(), gst_queue_array_set_clear_func(), + gst_queue_array_clear()) so that it can be used in other places like + GstAdapter instead of a GList, which reduces allocations and + improves performance. + +- appsink now reuses the sample object in pull_sample() if possible + +- rtpsession only starts the RTCP thread when it’s actually needed now + +- udpsrc uses a buffer pool now and the GstUdpSrc object structure was + optimised for better cache performance GstPlayer -- this section will be filled in in due course +- API was added to fine-tune the synchronisation offset between + subtitles and video Miscellaneous changes -- this section will be filled in in due course +- As a result of moving to different FFmpeg APIs, encoder and decoder + elements exposed by the GStreamer FFmpeg wrapper plugin (gst-libav) + may have seen possibly incompatible changes to property names and/or + types, and not all properties exposed might be functional. We are + still reviewing the new properties and aim to minimise breaking + changes at least for the most commonly-used properties, so please + report any issues you run into! OpenGL integration -- this section will be filled in in due course +- The OpenGL mixer elements have been moved from -bad to + gst-plugins-base (see above) + +- The Mesa GBM backend now supports headless mode + +- gloverlaycompositor: New OpenGL-based compositor element that + flattens any overlays from GstVideoOverlayCompositionMetas into the + video stream. + +- glalpha: New element that adds an alpha channel to a video stream. + The values of the alpha channel can either be set to a constant or + can be dynamically calculated via chroma keying. It is similar to + the existing alpha element but based on OpenGL. Calculations are + done in floating point so results may not be identical to the output + of the existing alpha element. + +- glupload: Implement direct dmabuf uploader, the idea being that some + GPUs (like the Vivante series) can actually perform the YUV->RGB + conversion internally, so no custom conversion shaders are needed. + To make use of this feature, we need an additional uploader that can + import DMABUF FDs and also directly pass the pixel format, relying + on the GPU to do the conversion. Tracing framework and debugging improvements -- this section will be filled in in due course +- There is now a GDB PRETTY PRINTER FOR VARIOUS GSTREAMER TYPES: For + GstObject pointers the type and name is added, e.g. + 0x5555557e4110 [GstDecodeBin|decodebin0]. For GstMiniObject pointers + the object type is added, e.g. 0x7fffe001fc50 [GstBuffer]. For + GstClockTime and GstClockTimeDiff the time is also printed in human + readable form, e.g. 150116219955 [+0:02:30.116219955]. + +- GDB EXTENSION WITH TWO CUSTOM GDB COMMANDS gst-dot AND gst-print: + + - gst-dot creates dot files that a very close to what + GST_DEBUG_BIN_TO_DOT_FILE() produces, but object properties and + buffer contents such as codec-data in caps are not available. + + - gst-print produces high-level information about a GStreamer + object. This is currently limited to pads for GstElements and + events for the pads. The output may look like this: + + (gdb) gst-print pad.object.parent + GstMatroskaDemux (matroskademux0) { + SinkPad (sink, pull) { + } + SrcPad (video_0, push) { + events: + stream-start: + stream-id: 0463ccb080d00b8689bf569a435c4ff84f9ff753545318ae2328ea0763fd0bec/001:1274058367 + caps: video/x-theora + width: 1920 + height: 800 + pixel-aspect-ratio: 1/1 + framerate: 24/1 + streamheader: < 0x5555557c7d30 [GstBuffer], 0x5555557c7e40 [GstBuffer], 0x7fffe00141d0 [GstBuffer] > + segment: time + rate: 1 + tag: global + container-format: Matroska + } + SrcPad (audio_0, push) { + events: + stream-start: + stream-id: 0463ccb080d00b8689bf569a435c4ff84f9ff753545318ae2328ea0763fd0bec/002:1551204875 + caps: audio/mpeg + mpegversion: 4 + framed: true + stream-format: raw + codec_data: 0x7fffe0014500 [GstBuffer] + level: 2 + base-profile: lc + profile: lc + channels: 2 + rate: 44100 + segment: time + rate: 1 + tag: global + container-format: Matroska + tag: stream + audio-codec: MPEG-4 AAC audio + language-code: en + } + } + +- gst_structure_to_string() now serialises the actual value of + pointers when serialising GstStructures instead of claiming they’re + NULL. This makes debug logging in various places less confusing, + because it’s clear now that structure fields actually hold valid + objects. Such object pointer values will never be deserialised + however. Tools -- this section will be filled in in due course +- gst-inspect-1.0 has coloured output now and will automatically use a + pager if the output does not fit on a page. This only works in a + unix environment and if the output is not piped. If you don’t like + the colours you can disable them by setting the + GST_INSPECT_NO_COLORS=1 environment variable or passing the + --no-colors command line option. GStreamer RTSP server -- this section will be filled in in due course +- Improved backlog handling when using TCP interleaved for data + transport. Before there was a fixed maximum size for backlog + messages, which was prone to deadlocks and made it difficult to + control memory usage with the watch backlog. The RTSP server now + limits queued TCP data messages to one per stream, moving queuing of + the data into the pipeline and leaving the RTSP connection + responsive to RTSP messages in both directions, preventing all those + problems. + +- Initial ULP Forward Error Correction support in rtspclientsink and + for RECORD mode in the server. + +- API to explicitly enable retransmission requests (RTX) + +- Lots of multicast-related fixes + +- rtsp-auth: Add support for parsing .htdigest files GStreamer VAAPI @@ -110,34 +748,350 @@ GStreamer validate GStreamer Python Bindings -- this section will be filled in in due course +- add binding for gst_pad_set_caps() + +- pygobject dependency requirement was bumped to >= 3.8 + +- new audiotestsrc, audioplot, and mixer plugin examples, and a + dynamic pipeline example + + +GStreamer C# Bindings + +- bindings for the GstWebRTC library + + +GStreamer Rust Bindings + +The GStreamer Rust bindings are now officially part of the GStreamer +project and are also maintained in the GStreamer GitLab. + +The releases will generally not be synchronized with the releases of +other GStreamer parts due to dependencies on other projects. + +Also unlike the other GStreamer libraries, the bindings will not commit +to full API stability but instead will follow the approach that is +generally taken by Rust projects, e.g.: + +1) 0.12.X will be completely API compatible with all other 0.12.Y + versions. +2) 0.12.X+1 will contain bugfixes and compatible new feature additions. +3) 0.13.0 will _not_ be backwards compatible with 0.12.X but projects + will be able to stay at 0.12.X without any problems as long as they + don’t need newer features. + +The current stable release is 0.12.2 and the next release series will be +0.13, probably around March 2019. + +At this point the bindings cover most of GStreamer core (except for most +notably GstAllocator and GstMemory), and most parts of the app, audio, +base, check, editing-services, gl, net. pbutils, player, rtsp, +rtsp-server, sdp, video and webrtc libraries. + +Also included is support for creating subclasses of the following types +and writing GStreamer plugins: + +- gst::Element +- gst::Bin and gst::Pipeline +- gst::URIHandler and gst::ChildProxy +- gst::Pad, gst::GhostPad +- gst_base::Aggregator and gst_base::AggregatorPad +- gst_base::BaseSrc and gst_base::BaseSink +- gst_base::BaseTransform + +Changes to 0.12.X since 0.12.0 + +Fixed + +- PTP clock constructor actually creates a PTP instead of NTP clock + +Added + +- Bindings for GStreamer Editing Services +- Bindings for GStreamer Check testing library +- Bindings for the encoding profile API (encodebin) + +- VideoFrame, VideoInfo, AudioInfo, StructureRef implements Send and + Sync now +- VideoFrame has a function to get the raw FFI pointer +- From impls from the Error/Success enums to the combined enums like + FlowReturn +- Bin-to-dot file functions were added to the Bin trait +- gst_base::Adapter implements SendUnique now +- More complete bindings for the gst_video::VideoOverlay interface, + especially + gst_video::is_video_overlay_prepare_window_handle_message() + +Changed + +- All references were updated from GitHub to freedesktop.org GitLab +- Fix various links in the README.md +- Link to the correct location for the documentation +- Remove GitLab badge as that only works with gitlab.com currently + +Changes in git master for 0.13 + +Fixed + +- gst::tag::Album is the album tag now instead of artist sortname + +Added + +- Subclassing infrastructure was moved directly into the bindings, + making the gst-plugin crate deprecated. This involves many API + changes but generally cleans up code and makes it more flexible. + Take a look at the gst-plugins-rs crate for various examples. + +- Bindings for CapsFeatures and Meta +- Bindings for + ParentBufferMeta,VideoMetaandVideoOverlayCompositionMeta` +- Bindings for VideoOverlayComposition and VideoOverlayRectangle +- Bindings for VideoTimeCode + +- UniqueFlowCombiner and UniqueAdapter wrappers that make use of the + Rust compile-time mutability checks and expose more API in a safe + way, and as a side-effect implement Sync and Send now + +- More complete bindings for Allocation Query +- pbutils functions for codec descriptions +- TagList::iter() for iterating over all tags while getting a single + value per tag. The old ::iter_tag_list() function was renamed to + ::iter_generic() and still provides access to each value for a tag +- Bus::iter() and Bus::iter_timed() iterators around the corresponding + ::pop*() functions + +- serde serialization of Value can also handle Buffer now + +- Extensive comments to all examples with explanations +- Transmuxing example showing how to use typefind, multiqueue and + dynamic pads +- basic-tutorial-12 was ported and added + +Changed + +- Rust 1.31 is the minimum supported Rust version now +- Update to latest gir code generator and glib bindings + +- Functions returning e.g. gst::FlowReturn or other “combined” enums + were changed to return split enums like + Result to allow usage of the + standard Rust error handling. + +- MiniObject subclasses are now newtype wrappers around the underlying + GstRc wrapper. This does not change the API in any breaking + way for the current usages, but allows MiniObjects to also be + implemented in other crates and makes sure rustdoc places the + documentation in the right places. + +- BinExt extension trait was renamed to GstBinExt to prevent conflicts + with gtk::Bin if both are imported + +- Buffer::from_slice() can’t possible return None + +- Various clippy warnings + + +GStreamer Rust Plugins + +Like the GStreamer Rust bindings, the Rust plugins are now officially +part of the GStreamer project and are also maintained in the GStreamer +GitLab. + +In the 0.3.x versions this contained infrastructure for writing +GStreamer plugins in Rust, and a set of plugins. + +In git master that infrastructure was moved to the GLib and GStreamer +bindings directly, together with many other improvements that were made +possible by this, so the gst-plugins-rs repository only contains +GStreamer elements now. + +Elements included are: + +- Tutorials plugin: identity, rgb2gray and sinesrc with extensive + comments + +- rsaudioecho, a port of the audiofx element + +- rsfilesrc, rsfilesink + +- rsflvdemux, a FLV demuxer. Not feature-equivalent with flvdemux yet + +- threadshare plugin: ts-appsrc, ts-proxysrc/sink, ts-queue, ts-udpsrc + and ts-tcpclientsrc elements that use a fixed number of threads and + share them between instances. For more background about these + elements see Sebastian’s talk “When adding more threads adds more + problems - Thread-sharing between elements in GStreamer” at the + GStreamer Conference 2017. + +- rshttpsrc, a HTTP source around the hyper/reqwest Rust libraries. + Not feature-equivalent with souphttpsrc yet. + +- togglerecord, an element that allows to start/stop recording at any + time and keeps all audio/video streams in sync. + +- mccparse and mccenc, parsers and encoders for the MCC closed caption + file format. + +Changes to 0.3.X since 0.3.0 + +- All references were updated from GitHub to freedesktop.org GitLab +- Fix various links in the README.md +- Link to the correct location for the documentation + +Changes in git master for 0.4 + +- togglerecord: Switch to parking_lot crate for mutexes/condition + variables for lower overhead +- Merge threadshare plugin here +- New closedcaption plugin with mccparse and mccenc elements +- New identity element for the tutorials plugin + +- Register plugins statically in tests instead of relying on the + plugin loader to find the shared library in a specific place + +- Update to the latest API changes in the GLib and GStreamer bindings +- Update to the latest versions of all crates Build and Dependencies -- this section will be filled in in due course +- The MESON BUILD SYSTEM BUILD IS NOW FEATURE-COMPLETE (*) and it is + now the recommended build system on all platforms and also used by + Cerbero to build GStreamer on all platforms. The Autotools build is + scheduled to be removed in the next cycle. Developers who currently + use gst-uninstalled should move to gst-build. The build option + naming has been cleaned up and made consistent and there are now + feature options to enable/disable plugins and various other features + on a case-by-case basis. (*) with the exception of plugin docs which + will be handled differently in future + +- Symbol export in libraries is now controlled via explicit exports + using symbol visibility or export defines where supported, to ensure + consistency across all platforms. This also allows libraries to have + exports that vary based on detected platform features and configure + options as is the case with the GStreamer OpenGL integration library + for example. A few symbols that had been exported by accident in + earlier versions may no longer be exported. These symbols will not + have had declarations in any public header files then though and + would not have been usable. + +- The GStreamer FFmpeg wrapper plugin (gst-libav) now depends on + FFmpeg 4.x and uses the new FFmpeg 4.x API and stopped relying on + ancient API that was removed with the FFmpeg 4.x release. This means + that it is no longer possible to build this module against an older + system-provided FFmpeg 3.x version. Use the internal FFmpeg 4.x copy + instead if you build using autotools, or use gst-libav 1.14.x + instead which targets the FFmpeg 3.x API and _should_ work fine in + combination with a newer GStreamer. It’s difficult for us to support + both old and new FFmpeg APIs at the same time, apologies for any + inconvenience caused. + +- Hardware-accelerated Nvidia video encoder/decoder plugins nvdec and + nvenc can be built against CUDA Toolkit versions 9 and 10.0 now. The + dynlink interface has been dropped since it’s deprecated in 10.0. + +- The (optional) OpenCV requirement has been bumped to >= 3.0.0 and + the plugin can also be built against OpenCV 4.x now. + +- New sctp plugin based on usrsctp (for WebRTC data channels) -Platform-specific improvements +Platform-specific changes and improvements Android -- this section will be filled in in due course +- The way that GIO modules are named has changed due to upstream GLib + natively adding support for loading static GIO modules. This means + that any GStreamer application using gnutls for SSL/TLS on the + Android or iOS platforms (or any other setup using static libraries) + will fail to link looking for the g_io_module_gnutls_load_static() + function. The new function name is now + g_io_gnutls_load(gpointer data). data can be NULL for a static + library. Look at this commit for the necessary change in the + examples. macOS and iOS -- this section will be filled in in due course +- macOS binaries should be fully relocatable now + +- The way that GIO modules are named has changed due to upstream GLib + natively adding support for loading static GIO modules. This means + that any GStreamer application using gnutls for SSL/TLS on the + Android or iOS platforms (or any other setup using static libraries) + will fail to link looking for the g_io_module_gnutls_load_static() + function. The new function name is now + g_io_gnutls_load(gpointer data). data can be NULL for a static + library. Look at this commit for the necessary change in the + examples. Windows -- this section will be filled in in due course +- The webrtcdsp element is shipped again as part of the Windows binary + packages, the build system issue has been resolved. + +- ‘Inconsistent DLL linkage’ warnings when building with MSVC have + been fixed + +- Hardware-accelerated Nvidia video encoder/decoder plugins nvdec and + nvenc build on Windows now, also with MSVC and using Meson. + +- The ksvideosrc camera capture plugin supports 16-bit grayscale video + now + +- The wasapisrc audio capture element implements loopback recording + from another output device or sink + +- wasapisink recover from low buffer levels in shared mode and some + exclusive mode fixes + +- dshowsrc now implements the GstDeviceMonitor interface Contributors -- this section will be filled in in due course +Aleix Conchillo Flaqué, Alessandro Decina, Alexandru Băluț, Alex Ashley, +Alexey Chernov, Alicia Boya García, Amit Pandya, Andoni Morales +Alastruey, Andreas Frisch, Andre McCurdy, Andy Green, Anthony Violo, +Antoine Jacoutot, Antonio Ospite, Arun Raghavan, Aurelien Jarno, +Aurélien Zanelli, ayaka, Bananahemic, Bastian Köcher, Branko Subasic, +Brendan Shanks, Carlos Rafael Giani, Christoph Reiter, Corentin Noël, +Daeseok Youn, Daniel Drake, Daniel Klamt, Dardo D Kleiner, David Ing, +David Svensson Fors, Devarsh Thakkar, Dimitrios Katsaros, Edward Hervey, +Emilio Pozuelo Monfort, Enrique Ocaña González, Ezequiel Garcia, Fabien +Dessenne, Fabrizio Gennari, Florent Thiéry, Francisco Velazquez, +Freyr666, Garima Gaur, Gary Bisson, George Kiagiadakis, Georg Lippitsch, +Georg Ottinger, Geunsik Lim, Göran Jönsson, Guillaume Desmottes, H1Gdev, +Haihao Xiang, Haihua Hu, Harshad Khedkar, Havard Graff, He Junyan, +Hoonhee Lee, Hosang Lee, Hyunjun Ko, Ingo Randolf, Iñigo Huguet, James +Stevenson, Jan Alexander Steffens, Jan Schmidt, Jerome Laheurte, Jimmy +Ohn, Joakim Johansson, Jochen Henneberg, Johan Bjäreholt, John-Mark +Bell, John Nikolaides, Jonathan Karlsson, Jonny Lamb, Jordan Petridis, +Josep Torra, Joshua M. Doe, Jos van Egmond, Juan Navarro, Jun Xie, +Junyan He, Justin Kim, Kai Kang, Kim Tae Soo, Kirill Marinushkin, Kyrylo +Polezhaiev, Lars Petter Endresen, Linus Svensson, Louis-Francis +Ratté-Boulianne, Luis de Bethencourt, Luz Paz, Lyon Wang, Maciej Wolny, +Marc-André Lureau, Marc Leeman, Marcos Kintschner, Marian Mihailescu, +Marinus Schraal, Mark Nauwelaerts, Marouen Ghodhbane, Martin Kelly, +Matej Knopp, Mathieu Duponchelle, Matteo Valdina, Matthew Waters, +Matthias Fend, memeka, Michael Drake, Michael Gruner, Michael Olbrich, +Michael Tretter, Miguel Paris, Mike Wey, Mikhail Fludkov, Naveen +Cherukuri, Nicola Murino, Nicolas Dufresne, Niels De Graef, Nirbheek +Chauhan, Norbert Wesp, Ognyan Tonchev, Olivier Crête, Omar Akkila, +Patricia Muscalu, Patrick Radizi, Patrik Nilsson, Paul Kocialkowski, Per +Forlin, Peter Körner, Peter Seiderer, Petr Kulhavy, Philippe Normand, +Philippe Renon, Philipp Zabel, Pierre Labastie, Roland Jon, Roman +Sivriver, Rosen Penev, Russel Winder, Sam Gigliotti, Sean-Der, Sebastian +Dröge, Seungha Yang, Sjoerd Simons, Snir Sheriber, Song Bing, Soon, +Thean Siew, Sreerenj Balachandran, Stefan Ringel, Stephane Cerveau, +Stian Selnes, Suhas Nayak, Takeshi Sato, Thiago Santos, Thibault +Saunier, Thomas Bluemel, Tianhao Liu, Tim-Philipp Müller, Tomasz +Andrzejak, Tomislav Tustonić, U. Artie Eoff, Ulf Olsson, Varunkumar +Allagadapa, Víctor Guzmán, Víctor Manuel Jáquez Leal, Vincenzo Bono, +Vineeth T M, Vivia Nikolaidou, Wang Fei, wangzq, Whoopie, Wim Taymans, +Wind Yuan, Wonchul Lee, Xabier Rodriguez Calvar, Xavier Claessens, +Haihao Xiang, Yacine Bandou, Yeongjin Jeong, Yuji Kuwabara, Zeeshan Ali, -... and many others who have contributed bug reports, translations, sent +… and many others who have contributed bug reports, translations, sent suggestions or helped testing. @@ -165,30 +1119,41 @@ the git 1.16 branch, which is a stable branch. 1.16.0 -1.16.0 is scheduled to be released around September 2018. +1.16.0 is scheduled to be released around January/February 2019. Known Issues -- The webrtcdsp element is currently not shipped as part of the - Windows binary packages due to a build system issue. +- possibly breaking/incompatible changes to properties of wrapped + FFmpeg decoders and encoders (see above). + +- The way that GIO modules are named has changed due to upstream GLib + natively adding support for loading static GIO modules. This means + that any GStreamer application using gnutls for SSL/TLS on the + Android or iOS platforms (or any other setup using static libraries) + will fail to link looking for the g_io_module_gnutls_load_static() + function. The new function name is now + g_io_gnutls_load(gpointer data). See Android/iOS sections above for + further details. Schedule for 1.18 -Our next major feature release will be 1.16, and 1.15 will be the -unstable development version leading up to the stable 1.16 release. The -development of 1.15/1.16 will happen in the git master branch. +Our next major feature release will be 1.18, and 1.17 will be the +unstable development version leading up to the stable 1.18 release. The +development of 1.17/1.18 will happen in the git master branch. -The plan for the 1.16 development cycle is yet to be confirmed, but it -is expected that feature freeze will be around August 2017 followed by -several 1.15 pre-releases and the new 1.16 stable release in September. +The plan for the 1.18 development cycle is yet to be confirmed, but it +is expected that feature freeze will be around July 2019 followed by +several 1.17 pre-releases and the new 1.18 stable release in +August/September. -1.16 will be backwards-compatible to the stable 1.14, 1.12, 1.10, 1.8, -1.6, 1.4, 1.2 and 1.0 release series. +1.18 will be backwards-compatible to the stable 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._ +_These release notes have been prepared by Tim-Philipp Müller with_ +_contributions from Sebastian Dröge._ _License: CC BY-SA 4.0_ diff --git a/RELEASE b/RELEASE index de473f7825..b38fad3508 100644 --- a/RELEASE +++ b/RELEASE @@ -1,6 +1,6 @@ -This is GStreamer gstreamer-vaapi 1.15.0.1. +This is GStreamer gstreamer-vaapi 1.15.1. -GStreamer 1.15 is the development version leading up to the next major +GStreamer 1.15 is the development branch leading up to the next major stable version which will be 1.16. The 1.15 development series adds new features on top of the 1.14 series and is @@ -11,8 +11,8 @@ Full release notes will one day be found at: https://gstreamer.freedesktop.org/releases/1.16/ -Binaries for Android, iOS, Mac OS X and Windows will be provided shortly -after the release. +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. @@ -57,7 +57,7 @@ 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 -http://cgit.freedesktop.org/gstreamer/gstreamer/ +https://cgit.freedesktop.org/gstreamer/gstreamer/ ==== Homepage ==== @@ -65,10 +65,16 @@ The project's website is https://gstreamer.freedesktop.org/ ==== Support and Bugs ==== -We use GNOME's bugzilla for bug reports and feature requests: -http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer +We have recently moved from GNOME Bugzilla to GitLab on freedesktop.org +for bug reports and feature requests: -Please submit patches via bugzilla as well. + 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). @@ -77,8 +83,14 @@ There is also a #gstreamer IRC channel on the Freenode IRC network. ==== Developers ==== -GStreamer is stored in Git, hosted at git.freedesktop.org, and can be cloned -from there (see link above). +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. +subscribe to the gstreamer-devel list: + + https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel diff --git a/configure.ac b/configure.ac index 688551e9a7..0bdb5bbbd8 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [15]) -m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [1]) +m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1500]) +m4_define([gst_vaapi_lt_current], [1501]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1500]) +m4_define([gst_vaapi_lt_age], [1501]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.15.0.1]) -m4_define([gst_plugins_base_version], [1.15.0.1]) -m4_define([gst_plugins_bad_version], [1.15.0.1]) +m4_define([gst_version], [1.15.1]) +m4_define([gst_plugins_base_version], [1.15.1]) +m4_define([gst_plugins_bad_version], [1.15.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.11.0]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 431454bc94..e77be06df6 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.15.1 + master + + 2019-01-17 + + + + 1.14.0 diff --git a/meson.build b/meson.build index 06e93cf501..c774acf802 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.15.0.1', + version : '1.15.1', meson_version : '>= 0.47.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From e6943d668aa5960b92ca5d735b914f34ae9a596a Mon Sep 17 00:00:00 2001 From: Wangfei Date: Thu, 17 Jan 2019 10:27:13 +0800 Subject: [PATCH 3201/3781] encoder: h264/h265: set SPS cbr_flag with correct value. The flag only set as 1 when the rate-control mode is CBR. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 23 ++++++++++++++--------- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 14 +++++++++----- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 42f99be4db..c3dfb24b05 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -330,7 +330,7 @@ bs_error: static gboolean bs_write_sps_data (GstBitWriter * bs, const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, - const VAEncMiscParameterHRD * hrd_params) + GstVaapiRateControl rate_control, const VAEncMiscParameterHRD * hrd_params) { guint8 profile_idc; guint32 constraint_set0_flag, constraint_set1_flag; @@ -340,6 +340,7 @@ bs_write_sps_data (GstBitWriter * bs, guint32 b_qpprime_y_zero_transform_bypass = 0; guint32 residual_color_transform_flag = 0; + guint32 cbr_flag = rate_control == GST_VAAPI_RATECONTROL_CBR ? 1 : 0; guint32 pic_height_in_map_units = (seq_param->seq_fields.bits.frame_mbs_only_flag ? seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2); @@ -509,7 +510,7 @@ bs_write_sps_data (GstBitWriter * bs, /* cpb_size_value_minus1[0] */ WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1); /* cbr_flag[0] */ - WRITE_UINT32 (bs, 1, 1); + WRITE_UINT32 (bs, cbr_flag, 1); } /* initial_cpb_removal_delay_length_minus1 */ WRITE_UINT32 (bs, 23, 5); @@ -547,9 +548,9 @@ bs_error: static gboolean bs_write_sps (GstBitWriter * bs, const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, - const VAEncMiscParameterHRD * hrd_params) + GstVaapiRateControl rate_control, const VAEncMiscParameterHRD * hrd_params) { - if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) + if (!bs_write_sps_data (bs, seq_param, profile, rate_control, hrd_params)) return FALSE; /* rbsp_trailing_bits */ @@ -561,12 +562,12 @@ bs_write_sps (GstBitWriter * bs, static gboolean bs_write_subset_sps (GstBitWriter * bs, const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, - guint num_views, guint16 * view_ids, + GstVaapiRateControl rate_control, guint num_views, guint16 * view_ids, const VAEncMiscParameterHRD * hrd_params) { guint32 i, j, k; - if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) + if (!bs_write_sps_data (bs, seq_param, profile, rate_control, hrd_params)) return FALSE; if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH || @@ -1494,6 +1495,7 @@ static gboolean add_packed_sequence_header (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncPackedHeader *packed_seq; GstBitWriter bs; VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 }; @@ -1517,7 +1519,8 @@ add_packed_sequence_header (GstVaapiEncoderH264 * encoder, profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) profile = GST_VAAPI_PROFILE_H264_HIGH; - bs_write_sps (&bs, seq_param, profile, &hrd_params); + bs_write_sps (&bs, seq_param, profile, base_encoder->rate_control, + &hrd_params); g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); @@ -1553,6 +1556,7 @@ static gboolean add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncPackedHeader *packed_seq; GstBitWriter bs; VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; @@ -1568,8 +1572,9 @@ add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder, WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS); - bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views, - encoder->view_ids, &hrd_params); + bs_write_subset_sps (&bs, seq_param, encoder->profile, + base_encoder->rate_control, encoder->num_views, encoder->view_ids, + &hrd_params); g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index ace2e56b07..c2c9f42997 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -349,7 +349,7 @@ static gboolean bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile, - const VAEncMiscParameterHRD * hrd_params) + GstVaapiRateControl rate_control, const VAEncMiscParameterHRD * hrd_params) { guint32 video_parameter_set_id = 0; guint32 max_sub_layers_minus1 = 0; @@ -362,6 +362,7 @@ bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, guint32 sps_extension_flag = 0; guint32 nal_hrd_parameters_present_flag = 0; guint maxNumSubLayers = 1, i; + guint32 cbr_flag = rate_control == GST_VAAPI_RATECONTROL_CBR ? 1 : 0; /* video_parameter_set_id */ WRITE_UINT32 (bs, video_parameter_set_id, 4); @@ -523,7 +524,7 @@ bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, /* cpb_size_value_minus1 */ WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1); /* cbr_flag */ - WRITE_UINT32 (bs, 1, 1); + WRITE_UINT32 (bs, cbr_flag, 1); } } } @@ -548,9 +549,10 @@ static gboolean bs_write_sps (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile, - const VAEncMiscParameterHRD * hrd_params) + GstVaapiRateControl rate_control, const VAEncMiscParameterHRD * hrd_params) { - if (!bs_write_sps_data (bs, encoder, picture, seq_param, profile, hrd_params)) + if (!bs_write_sps_data (bs, encoder, picture, seq_param, profile, + rate_control, hrd_params)) return FALSE; /* rbsp_trailing_bits */ @@ -1209,6 +1211,7 @@ static gboolean add_packed_sequence_header (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) { + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncPackedHeader *packed_seq; GstBitWriter bs; VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 }; @@ -1225,7 +1228,8 @@ add_packed_sequence_header (GstVaapiEncoderH265 * encoder, WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H265_NAL_SPS); - bs_write_sps (&bs, encoder, picture, seq_param, profile, &hrd_params); + bs_write_sps (&bs, encoder, picture, seq_param, profile, + base_encoder->rate_control, &hrd_params); g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); From 92af6b82fa8ef226b3a8a078d1d07005e1920c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 18 Jan 2019 10:33:37 +0100 Subject: [PATCH 3202/3781] libs: window: use G_GSIZE_MODIFIER for window id gsize type is not equal in all platforms, then the 'l' print modifier shall not be used always. This issue was found in Debian builds. --- gst-libs/gst/vaapi/gstvaapiwindow.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index ad686f0a15..260056e223 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -247,8 +247,8 @@ gst_vaapi_window_new_internal (GType type, GstVaapiDisplay * display, window = g_object_new (type, "display", display, "native-id", id, NULL); - GST_DEBUG_OBJECT (window, "new window with id = 0x%08lx and size %ux%u", id, - width, height); + GST_DEBUG_OBJECT (window, "new window with id = 0x%08" G_GSIZE_MODIFIER + "x and size %ux%u", id, width, height); if (!gst_vaapi_window_create (window, width, height)) goto error; From 8bdd1bf5f6a7e5fce4c64ccb773b54810d2d8726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 21 Jan 2019 19:22:58 +0100 Subject: [PATCH 3203/3781] libs: window: remove native-id property native-id property is problematic since the variable that stores it is gsize, which is platform specific, and in some is bigger than unsigned long, and there are not way to handle gsize properties. Also, GST_VAAPI_ID_INVALID is defined in gsize terms, and we would like to keep using it for this scope. This patch removes the native-id property and set it manually in gst_vaapi_window_new_internal(). --- gst-libs/gst/vaapi/gstvaapiwindow.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 260056e223..ed01f5eaf1 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -46,7 +46,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstVaapiWindow, gst_vaapi_window, enum { PROP_DISPLAY = 1, - PROP_NATIVE_ID, N_PROPERTIES }; static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; @@ -163,12 +162,6 @@ gst_vaapi_window_set_property (GObject * object, guint property_id, g_assert (window->display != NULL); window->has_vpp = GST_VAAPI_DISPLAY_HAS_VPP (window->display); break; - case PROP_NATIVE_ID:{ - gulong id = g_value_get_ulong (value); - window->use_foreign_window = (id != GST_VAAPI_ID_INVALID); - GST_VAAPI_WINDOW_ID (window) = window->use_foreign_window ? id : 0; - break; - } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -185,9 +178,6 @@ gst_vaapi_window_get_property (GObject * object, guint property_id, case PROP_DISPLAY: g_value_set_object (value, window->display); break; - case PROP_NATIVE_ID: - g_value_set_ulong (value, window->native_id); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -213,16 +203,6 @@ gst_vaapi_window_class_init (GstVaapiWindowClass * klass) "The VA-API display object to use", GST_TYPE_VAAPI_DISPLAY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME); - /** - * GstVaapiWindow:native-id: - * - * Native window ID: either XDisplay, EGLDisplay, or drm-fd. - */ - g_properties[PROP_NATIVE_ID] = - g_param_spec_ulong ("native-id", "Native window id", - "Native window ID", 0, G_MAXULONG, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME); - g_object_class_install_properties (object_class, N_PROPERTIES, g_properties); } @@ -245,7 +225,12 @@ gst_vaapi_window_new_internal (GType type, GstVaapiDisplay * display, g_return_val_if_fail (height > 0, NULL); } - window = g_object_new (type, "display", display, "native-id", id, NULL); + window = g_object_new (type, "display", display, NULL); + if (!window) + return NULL; + + window->use_foreign_window = id != GST_VAAPI_ID_INVALID; + GST_VAAPI_WINDOW_ID (window) = window->use_foreign_window ? id : 0; GST_DEBUG_OBJECT (window, "new window with id = 0x%08" G_GSIZE_MODIFIER "x and size %ux%u", id, width, height); From 7afe5311cca7e8fd416d0ee6e924cc4034af6a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 24 Jan 2019 21:08:07 +0100 Subject: [PATCH 3204/3781] vaapisink: x11: trap WM_DELETE_WINDOW message Register the WM_DELETE_WINDOW message from window manager and trap it to stop the pipeline cleanly. Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/130 --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 12 ++++++++-- gst/vaapi/gstvaapisink.c | 29 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 865b11babe..217815cdaf 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -226,7 +226,7 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, const GstVaapiDisplayClass *display_class; const GstVaapiWindowClass *window_class; XWindowAttributes wattr; - Atom atoms[2]; + Atom wm_delete, atoms[2]; gboolean ok; static const char *atom_names[2] = { @@ -269,8 +269,16 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, priv->atom_NET_WM_STATE_FULLSCREEN = atoms[1]; xid = x11_create_window (dpy, *width, *height, vid, cmap); - if (xid) + if (xid) { + /* Tell the window manager we'd like delete client messages instead of + * being killed */ + wm_delete = XInternAtom (dpy, "WM_DELETE_WINDOW", True); + if (wm_delete != None) { + (void) XSetWMProtocols (dpy, xid, &wm_delete, 1); + } + XRaiseWindow (dpy, xid); + } GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); GST_DEBUG ("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (xid)); diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index c19658332e..158ade9e03 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -439,6 +439,35 @@ gst_vaapisink_x11_handle_events (GstVaapiSink * sink) } if (do_expose) gst_vaapisink_video_overlay_expose (GST_VIDEO_OVERLAY (sink)); + + /* Handle Display events */ + for (;;) { + gst_vaapi_display_lock (display); + if (XPending (x11_dpy) == 0) { + gst_vaapi_display_unlock (display); + break; + } + XNextEvent (x11_dpy, &e); + gst_vaapi_display_unlock (display); + + switch (e.type) { + case ClientMessage:{ + Atom wm_delete; + + wm_delete = XInternAtom (x11_dpy, "WM_DELETE_WINDOW", False); + if (wm_delete == (Atom) e.xclient.data.l[0]) { + /* Handle window deletion by posting an error on the bus */ + GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, + ("Output window was closed"), (NULL)); + return FALSE; + } + break; + } + default: + break; + } + } + } return TRUE; } From 3fd91adc001231ce0c53a5640084d9574a4cadbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 8 Feb 2019 16:35:39 +0100 Subject: [PATCH 3205/3781] meson: bump the minimum wayland version requirement to 1.11.0 This was missed on commit 77bb3424 --- meson.build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index c774acf802..af372a307c 100644 --- a/meson.build +++ b/meson.build @@ -17,6 +17,7 @@ endif libva_req = ['>= 0.39.0', '!= 0.99.0'] glib_req = '>= 2.40.0' +libwayland_req = '>= 1.11.0' gst_req = '>= @0@.@1@.0'.format(gst_version_major, gst_version_minor) cc = meson.get_compiler('c') @@ -63,7 +64,7 @@ egl_dep = dependency('egl', required: false) gl_dep = dependency('gl', required: false) glesv2_dep = dependency('glesv2', required: false) libdl_dep = cc.find_library('dl', required: false) -wayland_client_dep = dependency('wayland-client', required: false) +wayland_client_dep = dependency('wayland-client', version: libwayland_req, required: false) x11_dep = dependency('x11', required: false) xrandr_dep = dependency('xrandr', required: false) xrender_dep = dependency('xrender', required: false) From 4aae03d3c15e8abb3d8f3e564340d00c56416a45 Mon Sep 17 00:00:00 2001 From: Denis Nagorny Date: Fri, 8 Feb 2019 09:21:28 +0300 Subject: [PATCH 3206/3781] libs: display: lock ensure_profile() Thread safety patch for ensure_profile() function Fixes #133 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 3d8e39f50c..b6d6d61a1d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -463,8 +463,12 @@ ensure_profiles (GstVaapiDisplay * display) VAStatus status; gboolean success = FALSE; - if (priv->has_profiles) + GST_VAAPI_DISPLAY_LOCK (display); + + if (priv->has_profiles) { + GST_VAAPI_DISPLAY_UNLOCK (display); return TRUE; + } priv->decoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig)); if (!priv->decoders) @@ -545,6 +549,7 @@ ensure_profiles (GstVaapiDisplay * display) cleanup: g_free (profiles); g_free (entrypoints); + GST_VAAPI_DISPLAY_UNLOCK (display); return success; } From e980fbf83d46437224465fbb29bbc8f95bae5a58 Mon Sep 17 00:00:00 2001 From: Niels De Graef Date: Mon, 14 Jan 2019 09:58:19 +0100 Subject: [PATCH 3207/3781] libs: wayland: Prefix wl_shell field with `wl_` It will help us to distinguish from other Wayland shells (such as XDG-shell) later on. --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 6147cbab23..9c40c90a7e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -105,7 +105,7 @@ registry_handle_global (void *data, priv->compositor = wl_registry_bind (registry, id, &wl_compositor_interface, 1); else if (strcmp (interface, "wl_shell") == 0) - priv->shell = wl_registry_bind (registry, id, &wl_shell_interface, 1); + priv->wl_shell = wl_registry_bind (registry, id, &wl_shell_interface, 1); else if (strcmp (interface, "wl_output") == 0) { priv->output = wl_registry_bind (registry, id, &wl_output_interface, 1); wl_output_add_listener (priv->output, &output_listener, priv); @@ -142,8 +142,8 @@ gst_vaapi_display_wayland_setup (GstVaapiDisplay * display) return FALSE; } - if (!priv->shell) { - GST_ERROR ("failed to bind shell interface"); + if (!priv->wl_shell) { + GST_ERROR ("failed to bind wl_shell interface"); return FALSE; } return TRUE; @@ -191,7 +191,7 @@ gst_vaapi_display_wayland_close_display (GstVaapiDisplay * display) GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); g_clear_pointer (&priv->output, wl_output_destroy); - g_clear_pointer (&priv->shell, wl_shell_destroy); + g_clear_pointer (&priv->wl_shell, wl_shell_destroy); g_clear_pointer (&priv->compositor, wl_compositor_destroy); g_clear_pointer (&priv->registry, wl_registry_destroy); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index bf6e81c639..54bf9b1c04 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -60,7 +60,7 @@ struct _GstVaapiDisplayWaylandPrivate gchar *display_name; struct wl_display *wl_display; struct wl_compositor *compositor; - struct wl_shell *shell; + struct wl_shell *wl_shell; struct wl_output *output; struct wl_registry *registry; guint width; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 5b9b4663c0..0baa17cdca 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -270,7 +270,7 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window, GST_DEBUG ("create window, size %ux%u", *width, *height); g_return_val_if_fail (priv_display->compositor != NULL, FALSE); - g_return_val_if_fail (priv_display->shell != NULL, FALSE); + g_return_val_if_fail (priv_display->wl_shell != NULL, FALSE); GST_VAAPI_WINDOW_LOCK_DISPLAY (window); priv->event_queue = wl_display_create_queue (priv_display->wl_display); @@ -287,7 +287,7 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window, GST_VAAPI_WINDOW_LOCK_DISPLAY (window); priv->shell_surface = - wl_shell_get_shell_surface (priv_display->shell, priv->surface); + wl_shell_get_shell_surface (priv_display->wl_shell, priv->surface); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (!priv->shell_surface) return FALSE; From 8e695c8fdb41d46d16aa17b52eb6e3a361f3557a Mon Sep 17 00:00:00 2001 From: Niels De Graef Date: Sat, 16 Feb 2019 19:09:50 +0100 Subject: [PATCH 3208/3781] libs: window: wayland: Prefix wl_shell_surface field with `wl_` It will help us to distinguish from other Wayland shell surface (such as XDG-shell) later on. --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 28 ++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 0baa17cdca..f2efb89e23 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -98,7 +98,7 @@ frame_state_free (FrameState * frame) struct _GstVaapiWindowWaylandPrivate { - struct wl_shell_surface *shell_surface; + struct wl_shell_surface *wl_shell_surface; struct wl_surface *surface; struct wl_region *opaque_region; struct wl_event_queue *event_queue; @@ -213,20 +213,20 @@ error: } static void -handle_ping (void *data, struct wl_shell_surface *shell_surface, +handle_ping (void *data, struct wl_shell_surface *wl_shell_surface, uint32_t serial) { - wl_shell_surface_pong (shell_surface, serial); + wl_shell_surface_pong (wl_shell_surface, serial); } static void -handle_configure (void *data, struct wl_shell_surface *shell_surface, +handle_configure (void *data, struct wl_shell_surface *wl_shell_surface, uint32_t edges, int32_t width, int32_t height) { } static void -handle_popup_done (void *data, struct wl_shell_surface *shell_surface) +handle_popup_done (void *data, struct wl_shell_surface *wl_shell_surface) { } @@ -249,9 +249,9 @@ gst_vaapi_window_wayland_set_fullscreen (GstVaapiWindow * window, } if (!fullscreen) - wl_shell_surface_set_toplevel (priv->shell_surface); + wl_shell_surface_set_toplevel (priv->wl_shell_surface); else { - wl_shell_surface_set_fullscreen (priv->shell_surface, + wl_shell_surface_set_fullscreen (priv->wl_shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL); } @@ -286,17 +286,17 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window, wl_proxy_set_queue ((struct wl_proxy *) priv->surface, priv->event_queue); GST_VAAPI_WINDOW_LOCK_DISPLAY (window); - priv->shell_surface = - wl_shell_get_shell_surface (priv_display->wl_shell, priv->surface); + priv->wl_shell_surface = wl_shell_get_shell_surface (priv_display->wl_shell, + priv->surface); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); - if (!priv->shell_surface) + if (!priv->wl_shell_surface) return FALSE; - wl_proxy_set_queue ((struct wl_proxy *) priv->shell_surface, + wl_proxy_set_queue ((struct wl_proxy *) priv->wl_shell_surface, priv->event_queue); - wl_shell_surface_add_listener (priv->shell_surface, + wl_shell_surface_add_listener (priv->wl_shell_surface, &shell_surface_listener, priv); - wl_shell_surface_set_toplevel (priv->shell_surface); + wl_shell_surface_set_toplevel (priv->wl_shell_surface); priv->poll = gst_poll_new (TRUE); gst_poll_fd_init (&priv->pollfd); @@ -332,7 +332,7 @@ gst_vaapi_window_wayland_finalize (GObject * object) if (priv->event_queue) wl_display_roundtrip_queue (wl_display, priv->event_queue); - g_clear_pointer (&priv->shell_surface, wl_shell_surface_destroy); + g_clear_pointer (&priv->wl_shell_surface, wl_shell_surface_destroy); g_clear_pointer (&priv->surface, wl_surface_destroy); g_clear_pointer (&priv->event_queue, wl_event_queue_destroy); From f84394fa4957e1241c62b4e786d2578473b2fb5d Mon Sep 17 00:00:00 2001 From: Niels De Graef Date: Mon, 14 Jan 2019 11:30:48 +0100 Subject: [PATCH 3209/3781] libs: wayland: add support for XDG-shell protocol [wl_shell] is officially [deprecated], so provide support for the XDG-shell protocol should be provided by all desktop-like compositors. (In case they don't, we can of course fall back to wl_shell). Note that the XML file is directly provided by the `wayland-protocols` dependency and generates the protocol marshalling code. [wl_shell]: https://people.freedesktop.org/~whot/wayland-doxygen/wayland/Client/group__iface__wl__shell.html [deprecated]: https://github.com/wayland-project/wayland/commit/698dde195837f3d0844b2725ba4ea8ce9ee7518c --- configure.ac | 7 +- gst-libs/gst/vaapi/Makefile.am | 20 +++ gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 22 ++- .../gst/vaapi/gstvaapidisplay_wayland_priv.h | 3 + gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 152 ++++++++++++++++-- gst-libs/gst/vaapi/meson.build | 18 ++- gst/vaapi/gstvaapisink.c | 15 ++ meson.build | 4 +- 8 files changed, 222 insertions(+), 19 deletions(-) diff --git a/configure.ac b/configure.ac index 0bdb5bbbd8..cf382d7cd8 100644 --- a/configure.ac +++ b/configure.ac @@ -466,13 +466,18 @@ fi dnl Check for Wayland USE_WAYLAND=0 if test "x$enable_wayland" = "xyes"; then - PKG_CHECK_MODULES([WAYLAND], [wayland-client >= $WAYLAND_REQ], + PKG_CHECK_MODULES([WAYLAND], [wayland-client >= $WAYLAND_REQ, wayland-protocols >= 1.15], [ USE_WAYLAND=1 saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $WAYLAND_CFLAGS" AC_CHECK_HEADERS([wayland-client.h], [], [USE_WAYLAND=0]) CPPFLAGS="$saved_CPPFLAGS" + + AC_CHECK_PROGS(WAYLAND_SCANNER, wayland-scanner, [USE_WAYLAND=0]) + + WAYLAND_PROTOCOLS_DATADIR="`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`" + AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, $WAYLAND_PROTOCOLS_DATADIR) ], [:]) fi diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 976466e01d..50ca9738ec 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -314,9 +314,28 @@ libgstvaapi_egl_source_priv_h = \ ogl_compat.h \ $(NULL) +BUILT_SOURCES= +CLEANFILES= + +# Generate the necessary files for XDG-shell +if USE_WAYLAND +xdg_shell_protocol_spec = $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml +xdg_shell_header = xdg-shell-client-protocol.h +xdg_shell_source = xdg-shell-client-protocol.c + +$(xdg_shell_header): $(xdg_shell_protocol_spec) + $(AM_V_GEN) $(WAYLAND_SCANNER) client-header < $< > $@ +$(xdg_shell_source): $(xdg_shell_protocol_spec) + $(AM_V_GEN) $(WAYLAND_SCANNER) private-code < $< > $@ + +BUILT_SOURCES += $(xdg_shell_header) $(xdg_shell_source) +CLEANFILES += $(BUILT_SOURCES) +endif + libgstvaapi_wayland_source_c = \ gstvaapidisplay_wayland.c \ gstvaapiwindow_wayland.c \ + $(xdg_shell_source) \ $(NULL) libgstvaapi_wayland_source_h = \ @@ -327,6 +346,7 @@ libgstvaapi_wayland_source_h = \ libgstvaapi_wayland_source_priv_h = \ gstvaapicompat.h \ gstvaapidisplay_wayland_priv.h \ + $(xdg_shell_header) \ $(NULL) libgstvaapi_la_SOURCES = \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 9c40c90a7e..660c99ec9a 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -94,6 +94,17 @@ static const struct wl_output_listener output_listener = { 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 registry_handle_global (void *data, struct wl_registry *registry, @@ -106,7 +117,11 @@ registry_handle_global (void *data, wl_registry_bind (registry, id, &wl_compositor_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, "wl_output") == 0) { + 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) { priv->output = wl_registry_bind (registry, id, &wl_output_interface, 1); wl_output_add_listener (priv->output, &output_listener, priv); } @@ -142,10 +157,14 @@ gst_vaapi_display_wayland_setup (GstVaapiDisplay * display) 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; } @@ -192,6 +211,7 @@ gst_vaapi_display_wayland_close_display (GstVaapiDisplay * 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->compositor, wl_compositor_destroy); g_clear_pointer (&priv->registry, wl_registry_destroy); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index 54bf9b1c04..b09adfb231 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -24,6 +24,8 @@ #ifndef GST_VAAPI_DISPLAY_WAYLAND_PRIV_H #define GST_VAAPI_DISPLAY_WAYLAND_PRIV_H +#include "xdg-shell-client-protocol.h" + #include #include "gstvaapidisplay_priv.h" @@ -61,6 +63,7 @@ struct _GstVaapiDisplayWaylandPrivate struct wl_display *wl_display; struct wl_compositor *compositor; struct wl_shell *wl_shell; + struct xdg_wm_base *xdg_wm_base; struct wl_output *output; struct wl_registry *registry; guint width; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index f2efb89e23..adb8a75089 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -98,6 +98,8 @@ frame_state_free (FrameState * frame) struct _GstVaapiWindowWaylandPrivate { + struct xdg_surface *xdg_surface; + struct xdg_toplevel *xdg_toplevel; struct wl_shell_surface *wl_shell_surface; struct wl_surface *surface; struct wl_region *opaque_region; @@ -137,10 +139,79 @@ struct _GstVaapiWindowWaylandClass G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiWindowWayland, gst_vaapi_window_wayland, GST_TYPE_VAAPI_WINDOW); +/* Object signals */ +enum +{ + SIZE_CHANGED, + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +static void +handle_xdg_toplevel_configure (void *data, struct xdg_toplevel *xdg_toplevel, + int32_t width, int32_t height, struct wl_array *states) +{ + GstVaapiWindow *window = GST_VAAPI_WINDOW (data); + const uint32_t *state; + + GST_DEBUG ("Got XDG-toplevel::reconfigure, [width x height] = [%d x %d]", + width, height); + + wl_array_for_each (state, states) { + switch (*state) { + case XDG_TOPLEVEL_STATE_FULLSCREEN: + case XDG_TOPLEVEL_STATE_MAXIMIZED: + case XDG_TOPLEVEL_STATE_RESIZING: + case XDG_TOPLEVEL_STATE_ACTIVATED: + break; + } + } + + if (width > 0 && height > 0) { + gst_vaapi_window_set_size (window, width, height); + g_signal_emit (window, signals[SIZE_CHANGED], 0, width, height); + } +} + +static void +handle_xdg_toplevel_close (void *data, struct xdg_toplevel *xdg_toplevel) +{ +} + +static const struct xdg_toplevel_listener xdg_toplevel_listener = { + handle_xdg_toplevel_configure, + handle_xdg_toplevel_close, +}; + static gboolean gst_vaapi_window_wayland_show (GstVaapiWindow * window) { - GST_WARNING ("unimplemented GstVaapiWindowWayland::show()"); + GstVaapiWindowWaylandPrivate *priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + + if (priv->xdg_surface == NULL) { + GST_FIXME ("GstVaapiWindowWayland::show() unimplemented for wl_shell"); + return TRUE; + } + + if (priv->xdg_toplevel != NULL) { + GST_DEBUG ("XDG toplevel already mapped"); + return TRUE; + } + + /* Create a toplevel window out of it */ + priv->xdg_toplevel = xdg_surface_get_toplevel (priv->xdg_surface); + g_return_val_if_fail (priv->xdg_toplevel, FALSE); + xdg_toplevel_set_title (priv->xdg_toplevel, "VA-API Wayland window"); + wl_proxy_set_queue ((struct wl_proxy *) priv->xdg_toplevel, + priv->event_queue); + + xdg_toplevel_add_listener (priv->xdg_toplevel, &xdg_toplevel_listener, + window); + + /* Commit the xdg_surface state as top-level window */ + wl_surface_commit (priv->surface); return TRUE; } @@ -148,7 +219,18 @@ gst_vaapi_window_wayland_show (GstVaapiWindow * window) static gboolean gst_vaapi_window_wayland_hide (GstVaapiWindow * window) { - GST_WARNING ("unimplemented GstVaapiWindowWayland::hide()"); + GstVaapiWindowWaylandPrivate *priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + + if (priv->xdg_surface == NULL) { + GST_FIXME ("GstVaapiWindowWayland::hide() unimplemented for wl_shell"); + return TRUE; + } + + if (priv->xdg_toplevel != NULL) { + g_clear_pointer (&priv->xdg_toplevel, xdg_toplevel_destroy); + wl_surface_commit (priv->surface); + } return TRUE; } @@ -236,6 +318,17 @@ static const struct wl_shell_surface_listener shell_surface_listener = { handle_popup_done }; +static void +handle_xdg_surface_configure (void *data, struct xdg_surface *xdg_surface, + uint32_t serial) +{ + xdg_surface_ack_configure (xdg_surface, serial); +} + +static const struct xdg_surface_listener xdg_surface_listener = { + handle_xdg_surface_configure, +}; + static gboolean gst_vaapi_window_wayland_set_fullscreen (GstVaapiWindow * window, gboolean fullscreen) @@ -248,6 +341,16 @@ gst_vaapi_window_wayland_set_fullscreen (GstVaapiWindow * window, return TRUE; } + /* XDG-shell */ + if (priv->xdg_toplevel != NULL) { + if (fullscreen) + xdg_toplevel_set_fullscreen (priv->xdg_toplevel, NULL); + else + xdg_toplevel_unset_fullscreen (priv->xdg_toplevel); + return TRUE; + } + + /* wl_shell fallback */ if (!fullscreen) wl_shell_surface_set_toplevel (priv->wl_shell_surface); else { @@ -270,7 +373,8 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window, GST_DEBUG ("create window, size %ux%u", *width, *height); g_return_val_if_fail (priv_display->compositor != NULL, FALSE); - g_return_val_if_fail (priv_display->wl_shell != NULL, FALSE); + g_return_val_if_fail (priv_display->xdg_wm_base || priv_display->wl_shell, + FALSE); GST_VAAPI_WINDOW_LOCK_DISPLAY (window); priv->event_queue = wl_display_create_queue (priv_display->wl_display); @@ -285,18 +389,33 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window, return FALSE; wl_proxy_set_queue ((struct wl_proxy *) priv->surface, priv->event_queue); - GST_VAAPI_WINDOW_LOCK_DISPLAY (window); - priv->wl_shell_surface = wl_shell_get_shell_surface (priv_display->wl_shell, - priv->surface); - GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); - if (!priv->wl_shell_surface) - return FALSE; - wl_proxy_set_queue ((struct wl_proxy *) priv->wl_shell_surface, - priv->event_queue); + /* Prefer XDG-shell over deprecated wl_shell (if available) */ + if (priv_display->xdg_wm_base) { + /* Create the XDG surface. We make the toplevel on VaapiWindow::show() */ + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); + priv->xdg_surface = xdg_wm_base_get_xdg_surface (priv_display->xdg_wm_base, + priv->surface); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); + if (!priv->xdg_surface) + return FALSE; + wl_proxy_set_queue ((struct wl_proxy *) priv->xdg_surface, + priv->event_queue); + xdg_surface_add_listener (priv->xdg_surface, &xdg_surface_listener, window); + } else { + /* Fall back to wl_shell */ + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); + priv->wl_shell_surface = wl_shell_get_shell_surface (priv_display->wl_shell, + priv->surface); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); + if (!priv->wl_shell_surface) + return FALSE; + wl_proxy_set_queue ((struct wl_proxy *) priv->wl_shell_surface, + priv->event_queue); - wl_shell_surface_add_listener (priv->wl_shell_surface, - &shell_surface_listener, priv); - wl_shell_surface_set_toplevel (priv->wl_shell_surface); + wl_shell_surface_add_listener (priv->wl_shell_surface, + &shell_surface_listener, priv); + wl_shell_surface_set_toplevel (priv->wl_shell_surface); + } priv->poll = gst_poll_new (TRUE); gst_poll_fd_init (&priv->pollfd); @@ -332,6 +451,7 @@ gst_vaapi_window_wayland_finalize (GObject * object) if (priv->event_queue) wl_display_roundtrip_queue (wl_display, priv->event_queue); + g_clear_pointer (&priv->xdg_surface, xdg_surface_destroy); g_clear_pointer (&priv->wl_shell_surface, wl_shell_surface_destroy); g_clear_pointer (&priv->surface, wl_surface_destroy); g_clear_pointer (&priv->event_queue, wl_event_queue_destroy); @@ -550,6 +670,10 @@ gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass) window_class->set_fullscreen = gst_vaapi_window_wayland_set_fullscreen; window_class->unblock = gst_vaapi_window_wayland_unblock; window_class->unblock_cancel = gst_vaapi_window_wayland_unblock_cancel; + + signals[SIZE_CHANGED] = g_signal_new ("size-changed", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); } static void diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 6a289af691..c5c40f70e1 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -183,10 +183,24 @@ if USE_EGL endif if USE_WAYLAND + # The XDG shell interface needs to be generated first + wayland_protocols_basedir = wayland_protocols_dep.get_pkgconfig_variable('pkgdatadir') + xdg_shell_xml_spec = join_paths(wayland_protocols_basedir, 'stable', 'xdg-shell', 'xdg-shell.xml') + xdg_shell_header = custom_target('vaapi-xdg-shell-client-header', + command: [ wayland_scanner_bin, 'client-header', '@INPUT@', '@OUTPUT@' ], + input: xdg_shell_xml_spec, + output: 'xdg-shell-client-protocol.h') + xdg_shell_code = custom_target('vaapi-xdg-shell-client-code', + command: [ wayland_scanner_bin, 'private-code', '@INPUT@', '@OUTPUT@' ], + input: xdg_shell_xml_spec, + output: 'xdg-shell-client-protocol.c') + gstlibvaapi_sources += [ 'gstvaapidisplay_wayland.c', 'gstvaapiwindow_wayland.c', - ] + xdg_shell_header, + xdg_shell_code, + ] gstlibvaapi_headers += [ 'gstvaapidisplay_wayland.h', 'gstvaapiwindow_wayland.h', @@ -209,7 +223,7 @@ if USE_GLX gstlibvaapi_deps += [libva_x11_dep, x11_dep, gl_dep, libdl_dep] endif if USE_WAYLAND - gstlibvaapi_deps += [libva_wayland_dep, wayland_client_dep] + gstlibvaapi_deps += [libva_wayland_dep, wayland_client_dep, wayland_protocols_dep] endif if USE_X11 gstlibvaapi_deps += [libva_x11_dep, x11_dep, xrandr_dep, xrender_dep] diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 158ade9e03..06d5d67dc8 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -533,6 +533,17 @@ gst_vaapisink_backend_x11 (void) #include #include +static void +on_window_wayland_size_changed (GstVaapiWindowWayland * window, gint width, + gint height, gpointer user_data) +{ + GstVaapiSink *sink = GST_VAAPISINK (user_data); + + GST_DEBUG ("Wayland window size changed to: %dx%d", width, height); + gst_vaapisink_reconfigure_window (sink); + gst_vaapisink_show_frame (GST_VIDEO_SINK_CAST (sink), NULL); +} + static gboolean gst_vaapisink_wayland_create_window (GstVaapiSink * sink, guint width, guint height) @@ -544,6 +555,10 @@ gst_vaapisink_wayland_create_window (GstVaapiSink * sink, guint width, sink->window = gst_vaapi_window_wayland_new (display, width, height); if (!sink->window) return FALSE; + + g_signal_connect_object (sink->window, "size-changed", + G_CALLBACK (on_window_wayland_size_changed), sink, 0); + return TRUE; } diff --git a/meson.build b/meson.build index af372a307c..b32b7745f1 100644 --- a/meson.build +++ b/meson.build @@ -65,6 +65,8 @@ gl_dep = dependency('gl', required: false) glesv2_dep = dependency('glesv2', required: false) libdl_dep = cc.find_library('dl', required: false) wayland_client_dep = dependency('wayland-client', version: libwayland_req, required: false) +wayland_protocols_dep = dependency('wayland-protocols', version: '>= 1.15', required: false) +wayland_scanner_bin = find_program('wayland-scanner', required: false) x11_dep = dependency('x11', required: false) xrandr_dep = dependency('xrandr', required: false) xrender_dep = dependency('xrender', required: false) @@ -92,7 +94,7 @@ USE_H264_FEI_ENCODER = USE_ENCODERS and cc.has_header('va/va_fei_h264.h', depend USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() and get_option('with_drm') != 'no' USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no' USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl_dep.found() and get_option('with_glx') != 'no' -USE_WAYLAND = libva_wayland_dep.found() and wayland_client_dep.found() and get_option('with_wayland') != 'no' +USE_WAYLAND = libva_wayland_dep.found() and wayland_client_dep.found() and wayland_protocols_dep.found() and wayland_scanner_bin.found() and get_option('with_wayland') != 'no' USE_X11 = libva_x11_dep.found() and x11_dep.found() and get_option('with_x11') != 'no' driverdir = libva_dep.get_pkgconfig_variable('driverdir') From 3d9555a86d45565870c684fe00ec8bbb0fed7205 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 13 Feb 2019 10:39:59 -0500 Subject: [PATCH 3210/3781] glx: Stop specifying GLX_DEPTH_SIZE This code is just confused. It's asking for at least as many bits of (z-axis) depth as the root window has bits of (color) depth. For rgb565 or rgb888 this is harmless, but at 10 bits per channel this demands a 30-bit or deeper Z buffer. While some hardware could in principle do a 32-bit Z buffer, Mesa does not expose such fbconfigs (at least on Intel and AMD). We're not actually using the Z buffer, so just stop asking for one. --- common | 2 +- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/common b/common index 59cb678164..3fa2c9e372 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 59cb678164719ff59dcf6c8b93df4617a1075d11 +Subproject commit 3fa2c9e372bceec30be91e67fb02b6cb05bed493 diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 997db0096e..ccd7832bab 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -852,8 +852,6 @@ gl_create_pixmap_object (Display * dpy, guint width, guint height) /* Initialize FBConfig attributes */ for (attr = fbconfig_attrs; *attr != GL_NONE; attr += 2); - *attr++ = GLX_DEPTH_SIZE; - *attr++ = wattr.depth; if (wattr.depth == 32) { *attr++ = GLX_ALPHA_SIZE; *attr++ = 8; From fd6291cc3c1584ccb9447217e9abfb73ca123e5e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 15 Feb 2019 15:19:51 +0800 Subject: [PATCH 3211/3781] libs: Delete the duplicated ARGB video format. Two ARGB formats with the same format information. Should be verbose and delete one. Signed-off-by: He Junyan --- gst-libs/gst/vaapi/video-format.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index f24fb6c822..a2394fa7cf 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -86,8 +86,6 @@ static const GstVideoFormatMap gst_vaapi_video_formats[] = { 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), DEF_RGB (RGBx, ('R', 'G', 'B', 'X'), 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), - DEF_RGB (ARGB, ('A', 'R', 'G', 'B'), 32, - 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), {0,} }; /* *INDENT-ON* */ From ee21fd9053c8bad9830f2b9185ad4ce462aaa581 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 5 Feb 2019 16:59:40 +0800 Subject: [PATCH 3212/3781] vaapivideomemory: Prefer same format for surface and image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We prefer to use the same format between image and surface for gst vaapi allocator. The old way may choose different formats between image and surface. For example, the RGBA image may have a NV12 surface. So we need to do format conversion when we put/get image to surface. Some drivers such as iHD can not support such conversion and always cause a data flow error. There may also have some performance cost for format conversion when put/get images. So we prefer to use the same format for image and surface in the allocator. If the surface can not support that format, we then fallback to find a best one as the surface format. Co-authored-by: Víctor Jáquez --- gst/vaapi/gstvaapivideomemory.c | 212 +++++++++++++++++++++----------- 1 file changed, 143 insertions(+), 69 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 7bacdda2be..e7a74ff27f 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -162,30 +162,6 @@ ensure_image_is_current (GstVaapiVideoMemory * mem) return TRUE; } -static GstVaapiSurface * -new_surface (GstVaapiDisplay * display, const GstVideoInfo * vip, - GstVaapiImageUsageFlags usage_flag) -{ - GstVaapiSurface *surface; - GstVaapiChromaType chroma_type; - - /* Try with explicit format first */ - if (!use_native_formats (usage_flag) && - GST_VIDEO_INFO_FORMAT (vip) != GST_VIDEO_FORMAT_ENCODED) { - surface = gst_vaapi_surface_new_full (display, vip, 0); - if (surface) - return surface; - } - - /* Try to pick something compatible, i.e. with same chroma type */ - chroma_type = - gst_vaapi_video_format_get_chroma_type (GST_VIDEO_INFO_FORMAT (vip)); - if (!chroma_type) - return NULL; - return gst_vaapi_surface_new (display, chroma_type, - GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip)); -} - static GstVaapiSurfaceProxy * new_surface_proxy (GstVaapiVideoMemory * mem) { @@ -743,63 +719,117 @@ error_cannot_map: } } -static inline gboolean -allocator_configure_surface_info (GstVaapiDisplay * display, - GstVaapiVideoAllocator * allocator, GstVaapiImageUsageFlags req_usage_flag) +#ifndef GST_DISABLE_GST_DEBUG +static const gchar * +gst_vaapi_image_usage_flags_to_string (GstVaapiImageUsageFlags usage_flag) { - const GstVideoInfo *vinfo; - GstVideoInfo *sinfo; - GstVaapiSurface *surface = NULL; - GstVideoFormat fmt; + switch (usage_flag) { + case GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS: + return "native uploading"; + case GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER: + return "direct rendering"; + case GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD: + return "direct uploading"; + default: + return "unknown"; + } +} +#endif - vinfo = &allocator->allocation_info; - allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; +static inline gboolean +allocator_configure_surface_try_specified_format (GstVaapiDisplay * display, + const GstVideoInfo * allocation_info, GstVaapiImageUsageFlags usage_flag, + GstVideoInfo * ret_surface_info, GstVaapiImageUsageFlags * ret_usage_flag) +{ + GstVaapiImageUsageFlags rflag; + GstVaapiSurface *surface; + GstVideoInfo sinfo, rinfo; - fmt = gst_vaapi_video_format_get_best_native (GST_VIDEO_INFO_FORMAT (vinfo)); - if (fmt == GST_VIDEO_FORMAT_UNKNOWN) - goto error_invalid_format; - - gst_video_info_set_format (&allocator->surface_info, fmt, - GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); - - /* nothing to configure */ - if (use_native_formats (req_usage_flag) - || GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) - return TRUE; - - surface = new_surface (display, vinfo, req_usage_flag); + /* Try to create a surface with the given allocation info */ + surface = gst_vaapi_surface_new_full (display, allocation_info, 0); if (!surface) - goto error_no_surface; + return FALSE; - sinfo = &allocator->surface_info; - if (!gst_video_info_update_from_surface (sinfo, surface)) - goto bail; - - /* if not the same format, don't use derived images */ - if (GST_VIDEO_INFO_FORMAT (sinfo) != GST_VIDEO_INFO_FORMAT (vinfo)) - goto bail; - - if (use_direct_rendering (req_usage_flag) - && !use_direct_uploading (req_usage_flag)) { - allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; - GST_INFO_OBJECT (allocator, "has direct-rendering for %s surfaces", - GST_VIDEO_INFO_FORMAT_STRING (sinfo)); - } else if (!use_direct_rendering (req_usage_flag) - && use_direct_uploading (req_usage_flag)) { - allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD; - GST_INFO_OBJECT (allocator, "has direct-uploading for %s surfaces", - GST_VIDEO_INFO_FORMAT_STRING (sinfo)); + /* surface created and just native format usage was requested */ + if (use_native_formats (usage_flag)) { + rflag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; + rinfo = *allocation_info; + goto out; } -bail: - if (surface) - gst_vaapi_object_unref (surface); + /* Further checks whether that surface can support direct + * upload/render */ + if (gst_video_info_update_from_surface (&sinfo, surface)) { + if (GST_VIDEO_INFO_FORMAT (&sinfo) == + GST_VIDEO_INFO_FORMAT (allocation_info)) { + /* Set the correct flag */ + if (use_direct_rendering (usage_flag) + && !use_direct_uploading (usage_flag)) { + rflag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER; + } else if (!use_direct_rendering (usage_flag) + && use_direct_uploading (usage_flag)) { + rflag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD; + } else { + g_assert_not_reached (); + } + } else { + /* It shouldn't happen, but still it's possible. Just use + * native. */ + GST_FIXME ("Got a derive image with different format!"); + rflag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; + } + + rinfo = sinfo; + goto out; + } + + /* Can not derive image or not the same format, don't use derived + images, just fallback to use native */ + rflag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; + rinfo = *allocation_info; + +out: + gst_vaapi_object_unref (surface); + + *ret_surface_info = rinfo; + *ret_usage_flag = rflag; + return TRUE; +} + +static inline gboolean +allocator_configure_surface_try_other_format (GstVaapiDisplay * display, + const GstVideoInfo * allocation_info, GstVideoInfo * ret_surface_info) +{ + GstVaapiSurface *surface; + GstVideoFormat fmt; + GstVideoInfo sinfo; + + /* Find a best native surface format if possible */ + fmt = gst_vaapi_video_format_get_best_native + (GST_VIDEO_INFO_FORMAT (allocation_info)); + if (fmt == GST_VIDEO_FORMAT_UNKNOWN + || fmt == GST_VIDEO_INFO_FORMAT (allocation_info)) + goto error_invalid_format; + + /* create a info with "best native" format */ + gst_video_info_set_format (&sinfo, fmt, + GST_VIDEO_INFO_WIDTH (allocation_info), + GST_VIDEO_INFO_HEIGHT (allocation_info)); + + /* try it */ + surface = gst_vaapi_surface_new_full (display, &sinfo, 0); + if (!surface) + goto error_no_surface; + gst_vaapi_object_unref (surface); + + *ret_surface_info = sinfo; return TRUE; /* ERRORS */ error_invalid_format: { - GST_ERROR ("Cannot handle format %s", GST_VIDEO_INFO_FORMAT_STRING (vinfo)); + GST_ERROR ("Cannot handle format %s", + GST_VIDEO_INFO_FORMAT_STRING (allocation_info)); return FALSE; } error_no_surface: @@ -809,6 +839,50 @@ error_no_surface: } } +static inline gboolean +allocator_configure_surface_info (GstVaapiDisplay * display, + GstVaapiVideoAllocator * allocator, GstVaapiImageUsageFlags req_usage_flag) +{ + GstVaapiImageUsageFlags usage_flag; + GstVideoInfo allocation_info, surface_info; + + /* get rid of possible encoded format and assume NV12 */ + allocation_info = allocator->allocation_info; + gst_video_info_force_nv12_if_encoded (&allocation_info); + + /* Step1: Try the specified format and flag. May fallback to native if + direct upload/rendering is unavailable. */ + if (allocator_configure_surface_try_specified_format (display, + &allocation_info, req_usage_flag, &surface_info, &usage_flag)) { + allocator->usage_flag = usage_flag; + allocator->surface_info = surface_info; + goto success; + } + + /* Step2: Try other surface format. Because format is different, + direct upload/rendering is unavailable, always use native */ + if (allocator_configure_surface_try_other_format (display, &allocation_info, + &surface_info)) { + allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; + allocator->surface_info = surface_info; + goto success; + } + + GST_INFO_OBJECT (allocator, "Failed to configure the video format: %s" + " with usage flag: %s", + GST_VIDEO_INFO_FORMAT_STRING (&allocator->allocation_info), + gst_vaapi_image_usage_flags_to_string (req_usage_flag)); + return FALSE; + +success: + GST_DEBUG_OBJECT (allocator, "success to set the surface format %s" + " for video format %s with %s", + GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info), + GST_VIDEO_INFO_FORMAT_STRING (&allocator->allocation_info), + gst_vaapi_image_usage_flags_to_string (allocator->usage_flag)); + return TRUE; +} + static inline gboolean allocator_configure_image_info (GstVaapiDisplay * display, GstVaapiVideoAllocator * allocator) From 00af7732f13ea44cf3d9b225d0d59a2c4c7e2bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 26 Feb 2019 12:01:53 +0000 Subject: [PATCH 3213/3781] Update docs --- docs/plugins/inspect/plugin-vaapi.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/inspect/plugin-vaapi.xml b/docs/plugins/inspect/plugin-vaapi.xml index 62477a0990..042aaa1c2f 100644 --- a/docs/plugins/inspect/plugin-vaapi.xml +++ b/docs/plugins/inspect/plugin-vaapi.xml @@ -3,7 +3,7 @@ VA-API based elements ../../gst/vaapi/.libs/libgstvaapi.so libgstvaapi.so - 1.15.1 + 1.15.2 LGPL gstreamer-vaapi gstreamer-vaapi From 3fa74d78384d23d2608fa16cfde01c8a086d7c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 26 Feb 2019 12:01:53 +0000 Subject: [PATCH 3214/3781] Release 1.15.2 --- ChangeLog | 138 +++++++++++++++++++ NEWS | 307 +++++++++++++++++++++++++++++-------------- RELEASE | 2 +- configure.ac | 12 +- gstreamer-vaapi.doap | 10 ++ meson.build | 2 +- 6 files changed, 367 insertions(+), 104 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00a7314ed8..a3672c8866 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,141 @@ +=== release 1.15.2 === + +2019-02-26 12:01:53 +0000 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * RELEASE: + * configure.ac: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.15.2 + +2019-02-26 12:01:53 +0000 Tim-Philipp Müller + + * docs/plugins/inspect/plugin-vaapi.xml: + Update docs + +2019-02-05 16:59:40 +0800 He Junyan + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: Prefer same format for surface and image + We prefer to use the same format between image and surface for gst + vaapi allocator. The old way may choose different formats between + image and surface. For example, the RGBA image may have a NV12 surface. + So we need to do format conversion when we put/get image to surface. + Some drivers such as iHD can not support such conversion and always + cause a data flow error. There may also have some performance cost + for format conversion when put/get images. + So we prefer to use the same format for image and surface in the + allocator. If the surface can not support that format, we then + fallback to find a best one as the surface format. + Co-authored-by: Víctor Jáquez + +2019-02-15 15:19:51 +0800 He Junyan + + * gst-libs/gst/vaapi/video-format.c: + libs: Delete the duplicated ARGB video format. + Two ARGB formats with the same format information. + Should be verbose and delete one. + Signed-off-by: He Junyan + +2019-02-13 10:39:59 -0500 Adam Jackson + + * common: + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + glx: Stop specifying GLX_DEPTH_SIZE + This code is just confused. It's asking for at least as many bits of + (z-axis) depth as the root window has bits of (color) depth. For rgb565 + or rgb888 this is harmless, but at 10 bits per channel this demands a + 30-bit or deeper Z buffer. While some hardware could in principle do a + 32-bit Z buffer, Mesa does not expose such fbconfigs (at least on Intel + and AMD). + We're not actually using the Z buffer, so just stop asking for one. + +2019-01-14 11:30:48 +0100 Niels De Graef + + * configure.ac: + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/meson.build: + * gst/vaapi/gstvaapisink.c: + * meson.build: + libs: wayland: add support for XDG-shell protocol + [wl_shell] is officially [deprecated], so provide support for the + XDG-shell protocol should be provided by all desktop-like compositors. + (In case they don't, we can of course fall back to wl_shell). + Note that the XML file is directly provided by the `wayland-protocols` + dependency and generates the protocol marshalling code. + [wl_shell]: https://people.freedesktop.org/~whot/wayland-doxygen/wayland/Client/group__iface__wl__shell.html + [deprecated]: https://github.com/wayland-project/wayland/commit/698dde195837f3d0844b2725ba4ea8ce9ee7518c + +2019-02-16 19:09:50 +0100 Niels De Graef + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: window: wayland: Prefix wl_shell_surface field with `wl_` + It will help us to distinguish from other Wayland shell surface + (such as XDG-shell) later on. + +2019-01-14 09:58:19 +0100 Niels De Graef + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: wayland: Prefix wl_shell field with `wl_` + It will help us to distinguish from other Wayland shells (such as + XDG-shell) later on. + +2019-02-08 09:21:28 +0300 Denis Nagorny + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: lock ensure_profile() + Thread safety patch for ensure_profile() function + Fixes #133 + +2019-02-08 16:35:39 +0100 Víctor Manuel Jáquez Leal + + * meson.build: + meson: bump the minimum wayland version requirement to 1.11.0 + This was missed on commit 77bb3424 + +2019-01-24 21:08:07 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst/vaapi/gstvaapisink.c: + vaapisink: x11: trap WM_DELETE_WINDOW message + Register the WM_DELETE_WINDOW message from window manager and + trap it to stop the pipeline cleanly. + Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/130 + +2019-01-21 19:22:58 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + libs: window: remove native-id property + native-id property is problematic since the variable that stores it is + gsize, which is platform specific, and in some is bigger than unsigned + long, and there are not way to handle gsize properties. + Also, GST_VAAPI_ID_INVALID is defined in gsize terms, and we would + like to keep using it for this scope. + This patch removes the native-id property and set it manually in + gst_vaapi_window_new_internal(). + +2019-01-18 10:33:37 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + libs: window: use G_GSIZE_MODIFIER for window id + gsize type is not equal in all platforms, then the 'l' print modifier + shall not be used always. + This issue was found in Debian builds. + +2019-01-17 10:27:13 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + encoder: h264/h265: set SPS cbr_flag with correct value. + The flag only set as 1 when the rate-control mode is CBR. + === release 1.15.1 === 2019-01-17 02:36:52 +0000 Tim-Philipp Müller diff --git a/NEWS b/NEWS index 1e860c47a6..6457a5d996 100644 --- a/NEWS +++ b/NEWS @@ -15,7 +15,7 @@ the git master branch and which will eventually result in 1.16. See https://gstreamer.freedesktop.org/releases/1.16/ for the latest version of this document. -_Last updated: Monday 14 January 2019, 13:00 UTC (log)_ +_Last updated: Monday 25 January 2019, 15:00 UTC (log)_ Introduction @@ -24,8 +24,8 @@ 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 new features, bug fixes and -other improvements. +As always, this release is again packed with many new features, bug +fixes and other improvements. Highlights @@ -40,7 +40,7 @@ Highlights - Support for Closed Captions and other Ancillary Data in video -- Spport for planar (non-interleaved) raw audio +- Support for planar (non-interleaved) raw audio - GstVideoAggregator, compositor and OpenGL mixer elements are now in -base @@ -98,14 +98,17 @@ Noteworthy new API to process the media in a live pipeline before it reaches the sink. This is on top of the systemic latency that is normally reported by the latency query. This defaults to 20ms and should make pipelines - such as “v4lsrc ! xvimagesink” not claim that all frames are late in - the QoS events. Ideally, this should replace max_lateness for most - applications. + such as v4l2src ! xvimagesink not claim that all frames are late in + the QoS events. Ideally, this should replace the "max-lateness" + property for most applications. - RTCP Extended Reports (XR) parsing according to RFC 3611: Loss/Duplicate RLE, Packet Receipt Times, Receiver Reference Time, Delay since the last Receiver (DLRR), Statistics Summary, and VoIP - Metrics reports. + Metrics reports. This only provides the ability to parse such + packets, generation of XR packets is not supported yet and XR + packets are not automatically parsed by rtpbin / rtpsession but must + be actively handled by the application. - a new mode for interlaced video was added where each buffer carries a single field of interlaced video, with buffer flags indicating @@ -146,9 +149,10 @@ or planar arrangement in memory would look like |LEFT|LEFT|LEFT| and |RIGHT|RIGHT|RIGHT| residing in separate memory chunks or separated by some padding. -GStreamer has always had signalling for non-interleaved audio, but it -was never actually properly implemented in any elements. audioconvert -would advertise support for it, but wasn’t actually able to handle it. +GStreamer has always had signalling for non-interleaved audio since +version 1.0, but it was never actually properly implemented in any +elements. audioconvert would advertise support for it, but wasn’t +actually able to handle it correctly. With this release we now have full support for non-interleaved audio as well, which means more efficient integration with external APIs that @@ -177,18 +181,18 @@ The video support library has gained support for detecting and extracting Ancillary Data from videos as per the SMPTE S291M specification, including: -- a VBI (Video Blanking Interval) parser that can detect and extract - Ancillary Data from Vertical Blanking Interval lines of component - signals. This is currently supported for videos in v210 and UYVY - format. +- a VBI (Vertical Blanking Interval) parser that can detect and + extract Ancillary Data from Vertical Blanking Interval lines of + component signals. This is currently supported for videos in v210 + and UYVY format. - a new GstMeta for closed captions: GstVideoCaptionMeta. This supports the two types of closed captions, CEA-608 and CEA-708, along with the four different ways they can be transported (other systems are a superset of those). -- a VBI (Video Blanking Interval) encoder for writing ancillary data - to the Vertical Blanking Interval lines of component signals. +- a VBI (Vertical Blanking Interval) encoder for writing ancillary + data to the Vertical Blanking Interval lines of component signals. The new closedcaption plugin in gst-plugins-bad then makes use of all this new infrastructure and provides the following elements: @@ -222,6 +226,9 @@ support: - playbin and playbin3 learned how to autoplug CEA 608/708 CC overlay elements +- the externally maintained ajavideosrc element for AJA capture cards + has support for extracting closed captions + The rsclosedcaption plugin in the Rust plugins collection includes a MacCaption (MCC) file parser and encoder. @@ -239,7 +246,7 @@ New Elements - gloverlaycompositor: New OpenGL-based compositor element that flattens any overlays from GstVideoOverlayCompositionMetas into the - video stream. + video stream. This element is also always part of glimagesink. - glalpha: New element that adds an alpha channel to a video stream. The values of the alpha channel can either be set to a constant or @@ -248,7 +255,7 @@ New Elements done in floating point so results may not be identical to the output of the existing alpha element. -- rtpfunnel funnels together rtp-streams into a single session. Use +- rtpfunnel funnels together RTP streams into a single session. Use cases include multiplexing and bundle. webrtcbin uses it to implement BUNDLE support. @@ -264,10 +271,12 @@ New Elements WPE - Two new OpenCV-based elements: cameracalibrate and cameraundistort - who can communicate to figure out distortion correction parameters + that can communicate to figure out distortion correction parameters for a camera and correct for the distortion. -- new sctp plugin based on usrsctp with sctpenc and sctpdec elements +- New sctp plugin based on usrsctp with sctpenc and sctpdec elements. + These elements are used inside webrtcbin for implementing data + channels. New element features and additions @@ -348,12 +357,12 @@ New element features and additions - rtspsrc now allows applications to send RTSP SET_PARAMETER and GET_PARAMETER requests using action signals. -- rtspsrc also has a small (100ms) configurable teardown delay by - default to try and make sure an RTSP TEARDOWN request gets sent out - when the source element shuts down. This will block the downward - PAUSED to READY state change for a short time, but can be unset - where it’s a problem. Some servers only allow a limited number of - concurren clients, so if no proper TEARDOWN is sent clients may have +- rtspsrc has a small (100ms) configurable teardown delay by default + to try and make sure an RTSP TEARDOWN request gets sent out when the + source element shuts down. This will block the downward PAUSED to + READY state change for a short time, but can be disabled where it’s + a problem. Some servers only allow a limited number of concurrent + clients, so if no proper TEARDOWN is sent new clients may have problems connecting to the server for a while. - souphttpsrc behaves better with low bitrate streams now. Before it @@ -364,6 +373,7 @@ New element features and additions - filesink: do internal buffering to avoid performance regression with small writes since we bypass libc buffering by using writev() + instead of fwrite() - identity: add "eos-after" property and fix "error-after" property when the element is reused @@ -405,9 +415,9 @@ New element features and additions relays (TURN servers). - The removesilence element has received various new features and - properties, such as a - "threshold"1 property, detecting silence only after minimum silence time/buffers, a“silent”property to control bus message notifications as well as a“squash”` - property. + properties, such as a "threshold" property, detecting silence only + after minimum silence time/buffers, a "silent" property to control + bus message notifications as well as a "squash" property. - AOMedia AV1 decoder gained support for 10/12bit decoding whilst the AV1 encoder supports more image formats and subsamplings now and @@ -430,15 +440,15 @@ Plugin and library moves - The stereo element was moved from -bad into the existing audiofx plugin in -good. If you get duplicate type registration warnings - when upgrading, check that you don’t have a stale gststereo plugin - lying about somewhere. + when upgrading, check that you don’t have a stale stereoplugin lying + about somewhere. GstVideoAggregator, compositor, and OpenGL mixer elements moved from -bad to -base GstVideoAggregator is a new base class for raw video mixers and muxers -and is based on [GstAggregator][aggregator]. It provides defined-latency -mixing of raw video inputs and ensures that the pipeline won’t stall -even if one of the input streams stops producing data. +and is based on GstAggregator. It provides defined-latency mixing of raw +video inputs and ensures that the pipeline won’t stall even if one of +the input streams stops producing data. As part of the move to stabilise the API there were some last-minute API changes and clean-ups, but those should mostly affect internal elements. @@ -456,14 +466,15 @@ would expected in most scenarios. The compositor element has gained support for per-pad blending mode operators (SOURCE, OVER, ADD) which determines what operator to use for blending this pad over the previous ones. This can be used to implement -crossfading. +crossfading and the available operators can be extended in the future as +needed. A number of OpenGL-based video mixer elements (glvideomixer, glmixerbin, glvideomixerelement, glstereomix, glmosaic) which are built on top of GstVideoAggregator have also been moved from -bad to -base now. These elements have been merged into the existing OpenGL plugin, so if you get duplicate type registration warnings when upgrading, check that you -don’t have a stale gstopenglmixers plugin lying about somewhere. +don’t have a stale openglmixers plugin lying about somewhere. Plugin removals @@ -477,11 +488,11 @@ The following plugins have been removed from gst-plugins-bad: plugin. - The acmmp3dec and acmenc plugins for Windows have been removed. ACM - is an ancient legacy API and there was no point in keeping them - around for a licensed mp3 decoder now that mp3 patents have expired - and we have a decoder in -good. We also didn’t ship these in our - cerbero-built Windows packages, so it’s unlikely that they’ll be - missed. + is an ancient legacy API and there was no point in keeping the + plugins around for a licensed MP3 decoder now that the MP3 patents + have expired and we have a decoder in -good. We also didn’t ship + these in our cerbero-built Windows packages, so it’s unlikely that + they’ll be missed. Miscellaneous API additions @@ -506,7 +517,8 @@ Miscellaneous API additions one might need to put such elements into READY state to test if the hardware is present in the system for example. -- protection: Add a new definition for unspecified system protection +- protection: Add a new definition for unspecified system protection, + GST_PROTECTION_UNSPECIFIED_SYSTEM_ID - take functions for various mini objects that didn’t have them yet: gst_query_take(), gst_message_take(), gst_tag_list_take(), @@ -522,11 +534,18 @@ Miscellaneous API additions gst_clear_mini_object(), gst_clear_object() - miniobject: new API gst_mini_object_add_parent() and - gst_mini_object_remove_parent()to set parent pointers on mini objects to ensure correct writability: Every container of miniobjects now needs to store itself as parent in the child object, and remove itself again later. A mini object is then only writable if there is at most one parent, that parent is writable itself, and the reference count of the mini object is 1.GstBuffer(for memories),GstBufferList(for buffers),GstSample(for caps, buffer, bufferlist), andGstVideoOverlayComposition` - were updated accordingly. Without this it was possible to have - e.g. a buffer list with a refcount of 2 used in two places at once - that both modify the same buffer with refcount 1 at the same time - wrongly thinking it is writable even though it’s really not. + gst_mini_object_remove_parent() to set parent pointers on mini + objects to ensure correct writability: Every container of + miniobjects now needs to store itself as parent in the child object, + and remove itself again later. A mini object is then only writable + if there is at most one parent, that parent is writable itself, and + the reference count of the mini object is 1. GstBuffer (for + memories), GstBufferList (for buffers), GstSample (for caps, buffer, + bufferlist), and GstVideoOverlayComposition were updated + accordingly. Without this it was possible to have e.g. a buffer list + with a refcount of 2 used in two places at once that both modify the + same buffer with refcount 1 at the same time wrongly thinking it is + writable even though it’s really not. - poll: add API to watch for POLLPRI and stop treating POLLPRI as a read. This is useful to wait for video4linux events which are @@ -596,7 +615,7 @@ GstPlayer Miscellaneous changes -- As a result of moving to different FFmpeg APIs, encoder and decoder +- As a result of moving to newer FFmpeg APIs, encoder and decoder elements exposed by the GStreamer FFmpeg wrapper plugin (gst-libav) may have seen possibly incompatible changes to property names and/or types, and not all properties exposed might be functional. We are @@ -649,48 +668,48 @@ Tracing framework and debugging improvements object. This is currently limited to pads for GstElements and events for the pads. The output may look like this: - (gdb) gst-print pad.object.parent - GstMatroskaDemux (matroskademux0) { - SinkPad (sink, pull) { + (gdb) gst-print pad.object.parent + GstMatroskaDemux (matroskademux0) { + SinkPad (sink, pull) { + } + SrcPad (video_0, push) { + events: + stream-start: + stream-id: 0463ccb080d00b8689bf569a435c4ff84f9ff753545318ae2328ea0763fd0bec/001:1274058367 + caps: video/x-theora + width: 1920 + height: 800 + pixel-aspect-ratio: 1/1 + framerate: 24/1 + streamheader: < 0x5555557c7d30 [GstBuffer], 0x5555557c7e40 [GstBuffer], 0x7fffe00141d0 [GstBuffer] > + segment: time + rate: 1 + tag: global + container-format: Matroska + } + SrcPad (audio_0, push) { + events: + stream-start: + stream-id: 0463ccb080d00b8689bf569a435c4ff84f9ff753545318ae2328ea0763fd0bec/002:1551204875 + caps: audio/mpeg + mpegversion: 4 + framed: true + stream-format: raw + codec_data: 0x7fffe0014500 [GstBuffer] + level: 2 + base-profile: lc + profile: lc + channels: 2 + rate: 44100 + segment: time + rate: 1 + tag: global + container-format: Matroska + tag: stream + audio-codec: MPEG-4 AAC audio + language-code: en + } } - SrcPad (video_0, push) { - events: - stream-start: - stream-id: 0463ccb080d00b8689bf569a435c4ff84f9ff753545318ae2328ea0763fd0bec/001:1274058367 - caps: video/x-theora - width: 1920 - height: 800 - pixel-aspect-ratio: 1/1 - framerate: 24/1 - streamheader: < 0x5555557c7d30 [GstBuffer], 0x5555557c7e40 [GstBuffer], 0x7fffe00141d0 [GstBuffer] > - segment: time - rate: 1 - tag: global - container-format: Matroska - } - SrcPad (audio_0, push) { - events: - stream-start: - stream-id: 0463ccb080d00b8689bf569a435c4ff84f9ff753545318ae2328ea0763fd0bec/002:1551204875 - caps: audio/mpeg - mpegversion: 4 - framed: true - stream-format: raw - codec_data: 0x7fffe0014500 [GstBuffer] - level: 2 - base-profile: lc - profile: lc - channels: 2 - rate: 44100 - segment: time - rate: 1 - tag: global - container-format: Matroska - tag: stream - audio-codec: MPEG-4 AAC audio - language-code: en - } - } - gst_structure_to_string() now serialises the actual value of pointers when serialising GstStructures instead of claiming they’re @@ -704,10 +723,10 @@ Tools - gst-inspect-1.0 has coloured output now and will automatically use a pager if the output does not fit on a page. This only works in a - unix environment and if the output is not piped. If you don’t like - the colours you can disable them by setting the - GST_INSPECT_NO_COLORS=1 environment variable or passing the - --no-colors command line option. + UNIX environment and if the output is not piped, and on Windows 10 + build 16257 or newer. If you don’t like the colours you can disable + them by setting the GST_INSPECT_NO_COLORS=1 environment variable or + passing the --no-color command line option. GStreamer RTSP server @@ -736,6 +755,29 @@ GStreamer VAAPI - this section will be filled in in due course +GStreamer OMX + +- Add support of NV16 format to video encoders input. + +- Video decoders now handle the ALLOCATION query to tell upstream + about the number of buffers they require. Video encoders will also + use this query to adjust their number of allocated buffers + preventing starvation when using dynamic buffer mode. + +- The OMX_PERFORMANCE debug category has been renamed to OMX_API_TRACE + and can now be used to track a widder variety of interactions + between OMX and GStreamer. + +- Video encoders will now detect frame rate only changes and will + inform OMX about it rather than doing a full format reset. + +- Various Zynq UltraScale+ specific improvements: + - Video encoders are now able to import dmabuf from upstream. + - Support for HEVC range extension profiles and more AVC profiles. + - We can now request video encoders to generate an IDR using the + force key unit event. + + GStreamer Editing Services and NLE - this section will be filled in in due course @@ -858,7 +900,7 @@ Added value per tag. The old ::iter_tag_list() function was renamed to ::iter_generic() and still provides access to each value for a tag - Bus::iter() and Bus::iter_timed() iterators around the corresponding - ::pop*() functions + ::pop\*() functions - serde serialization of Value can also handle Buffer now @@ -995,11 +1037,78 @@ Build and Dependencies - New sctp plugin based on usrsctp (for WebRTC data channels) +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. + +Cerbero has seen a number of improvements: + +- Cerbero has been ported to Python 3 and requires Python 3.5 or newer + now + +- Source tarballs are now protected by checksums in the recipes to + guard against download errors and malicious takeover of projects or + websites. In addition, downloads are only allowed via secure + transports now and plain HTTP, FTP and git:// transports are not + allowed anymore. + +- There is now a new fetch-bootstrap command which downloads sources + required for bootstrapping, with an optional --build-tools-only + argument to match the bootstrap --build-tools-only command. + +- The bootstrap, build, package and bundle-source commands gained a + new --offline switch that ensures that only sources from the cache + are used and never downloaded via the network. This is useful in + combination with the fetch and fetch-bootstrap commands that acquire + sources ahead of time before any build steps are executed. This + allows more control over the sources used and when sources are + updated, and is particularly useful for build environments that + don’t have network access. + +- bootstrap --assume-yes will automatically say ‘yes’ to any + interactive prompts during the bootstrap stage, such as those from + apt-get or yum. + +- bootstrap --system-only will only bootstrap the system without build + tools. + +- Manifest support: The build manifest can be used in continuous + integration (CI) systems to fixate the Git revision of certain + projects so that all builds of a pipeline are on the same reference. + This is used in GStreamer’s gitlab CI for example. It can also be + used in order to re-produce a specific build. To set a manifest, you + can set manifest = 'my_manifest.xml' in your configuration file, or + use the --manifest command line option. The command line option will + take precendence over anything specific in the configuration file. + +- The new build-deps command can be used to build only the + dependencies of a recipe, without the recipe itself. + +- new --list-variants command to list available variants + +- variants can now be set on the command line via the -v option as a + comma-separated list. This overrides any variants set in any + configuration files. + +- new qt5, intelmsdk and nvidia variants for enabling Qt5 and hardware + codec support. See the Enabling Optional Features with Variants + section in the Cerbero documentation for more details how to enable + and use these variants. + +- A new -t / --timestamp command line switch makes commands print + timestamps + Platform-specific changes and improvements Android +- toolchain: update compiler to clang and NDKr18. NDK r18 removed the + armv5 target and only has Android platforms that target at least + armv7 so the armv5 target is not useful anymore. + - The way that GIO modules are named has changed due to upstream GLib natively adding support for loading static GIO modules. This means that any GStreamer application using gnutls for SSL/TLS on the @@ -1010,9 +1119,15 @@ Android library. Look at this commit for the necessary change in the examples. +- various build issues on Android have been fixed. + macOS and iOS -- macOS binaries should be fully relocatable now +- various build issues on iOS have been fixed. + +- the minimum required iOS version is now 9.0. The difference in + adoption between 8.0 and 9.0 is 0.1% and the bump to 9.0 fixes some + build issues. - The way that GIO modules are named has changed due to upstream GLib natively adding support for loading static GIO modules. This means diff --git a/RELEASE b/RELEASE index b38fad3508..ace3c086da 100644 --- a/RELEASE +++ b/RELEASE @@ -1,4 +1,4 @@ -This is GStreamer gstreamer-vaapi 1.15.1. +This is GStreamer gstreamer-vaapi 1.15.2. GStreamer 1.15 is the development branch leading up to the next major stable version which will be 1.16. diff --git a/configure.ac b/configure.ac index cf382d7cd8..056ebfee7b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [15]) -m4_define([gst_vaapi_micro_version], [1]) +m4_define([gst_vaapi_micro_version], [2]) m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1501]) +m4_define([gst_vaapi_lt_current], [1502]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1501]) +m4_define([gst_vaapi_lt_age], [1502]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.15.1]) -m4_define([gst_plugins_base_version], [1.15.1]) -m4_define([gst_plugins_bad_version], [1.15.1]) +m4_define([gst_version], [1.15.2]) +m4_define([gst_plugins_base_version], [1.15.2]) +m4_define([gst_plugins_bad_version], [1.15.2]) # Wayland minimum version number m4_define([wayland_api_version], [1.11.0]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index e77be06df6..8477c7dfd4 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.15.2 + master + + 2019-02-26 + + + + 1.15.1 diff --git a/meson.build b/meson.build index b32b7745f1..5b36d1b6e6 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.15.1', + version : '1.15.2', meson_version : '>= 0.47.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 3e992d8adbb31e07d90f91264cd2605720f9098e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Feb 2019 13:02:10 +0100 Subject: [PATCH 3215/3781] plugin: if any caps in downstream, negotiate raw video When downstream has any caps, vaapi should not shovel vaapi featured buffers, but rather plain raw video, assuming always the worst case scenario (downstream cannot handle featured video memory but raw system memory buffers). This patch query the peer caps without any filter, to know if donwstream just ask for any caps, if so jump to the color space checking, otherwise do the caps intersection and continue with the feature selection algorithm. Fixes: #139 --- gst/vaapi/gstvaapipluginutil.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 23b3b6a1ee..fcbbc324c3 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -638,21 +638,31 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstCaps * allowed_caps, { GstVaapiCapsFeature feature = GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED; guint i, j, num_structures; - GstCaps *out_caps, *caps = NULL; + GstCaps *peer_caps, *out_caps = NULL, *caps = NULL; static const guint feature_list[] = { GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE, GST_VAAPI_CAPS_FEATURE_DMABUF, GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META, GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY, }; - out_caps = gst_pad_peer_query_caps (pad, allowed_caps); - if (!out_caps) + /* query with no filter */ + peer_caps = gst_pad_peer_query_caps (pad, NULL); + if (!peer_caps) + goto cleanup; + if (gst_caps_is_empty (peer_caps)) goto cleanup; - if (gst_caps_is_any (out_caps) || gst_caps_is_empty (out_caps)) - goto cleanup; + /* filter against our allowed caps */ + out_caps = gst_caps_intersect_full (allowed_caps, peer_caps, + GST_CAPS_INTERSECT_FIRST); + /* default feature */ feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY; + + /* if downstream requests caps ANY, system memory is preferred */ + if (gst_caps_is_any (peer_caps)) + goto find_format; + num_structures = gst_caps_get_size (out_caps); for (i = 0; i < num_structures; i++) { GstCapsFeatures *const features = gst_caps_get_features (out_caps, i); @@ -685,13 +695,14 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstCaps * allowed_caps, if (!caps) goto cleanup; +find_format: if (out_format_ptr) { GstVideoFormat out_format; GstStructure *structure; const GValue *format_list; /* if the best feature is SystemMemory, we should use the first - * caps in the peer caps set, which is the preferred by + * caps in the filtered peer caps set, which is the preferred by * downstream. */ if (feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) gst_caps_replace (&caps, out_caps); @@ -713,6 +724,7 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstCaps * allowed_caps, cleanup: gst_caps_replace (&caps, NULL); gst_caps_replace (&out_caps, NULL); + gst_caps_replace (&peer_caps, NULL); return feature; } From a90bf00906ef6663ac0d3701c19043c72835f824 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 1 Mar 2019 12:33:26 +0800 Subject: [PATCH 3216/3781] libs: Fix a typo in comments. Fix a typo in function description of gst_vaapi_surface_pool_new_with_chroma_type. Signed-off-by: He Junyan --- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 661ae18cca..4152fbfdc1 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -177,7 +177,7 @@ error: * @height: the desired height, in pixels * * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the specified - * chroam type and dimensions. The underlying format of the surfaces is + * chroma type and dimensions. The underlying format of the surfaces is * implementation (driver) defined. * * Return value: the newly allocated #GstVaapiVideoPool From e20e48f966f25dc49cc19cc7a2034f3f11c49c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 4 Mar 2019 09:16:17 +0000 Subject: [PATCH 3217/3781] Back to development --- NEWS | 8 ++++---- RELEASE | 2 +- configure.ac | 8 ++++---- docs/plugins/inspect/plugin-vaapi.xml | 2 +- meson.build | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index 6457a5d996..e6f8c3dbe7 100644 --- a/NEWS +++ b/NEWS @@ -4,7 +4,7 @@ GSTREAMER 1.16 RELEASE NOTES GStreamer 1.16 has not been released yet. It is scheduled for release in -January/February 2019. +March 2019. 1.15.x is the unstable development version that is being developed in the git master branch and which will eventually result in 1.16. @@ -15,7 +15,7 @@ the git master branch and which will eventually result in 1.16. See https://gstreamer.freedesktop.org/releases/1.16/ for the latest version of this document. -_Last updated: Monday 25 January 2019, 15:00 UTC (log)_ +_Last updated: Wednesday 27 January 2019, 00:30 UTC (log)_ Introduction @@ -1234,7 +1234,7 @@ the git 1.16 branch, which is a stable branch. 1.16.0 -1.16.0 is scheduled to be released around January/February 2019. +1.16.0 is scheduled to be released in March 2019. Known Issues @@ -1269,6 +1269,6 @@ August/September. ------------------------------------------------------------------------ _These release notes have been prepared by Tim-Philipp Müller with_ -_contributions from Sebastian Dröge._ +_contributions from Sebastian Dröge and Guillaume Desmottes._ _License: CC BY-SA 4.0_ diff --git a/RELEASE b/RELEASE index ace3c086da..9879f0a966 100644 --- a/RELEASE +++ b/RELEASE @@ -1,4 +1,4 @@ -This is GStreamer gstreamer-vaapi 1.15.2. +This is GStreamer gstreamer-vaapi 1.15.2.1. GStreamer 1.15 is the development branch leading up to the next major stable version which will be 1.16. diff --git a/configure.ac b/configure.ac index 056ebfee7b..fe2d30b214 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [15]) m4_define([gst_vaapi_micro_version], [2]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -24,9 +24,9 @@ m4_define([gst_vaapi_lt_age], [1502]) m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.15.2]) -m4_define([gst_plugins_base_version], [1.15.2]) -m4_define([gst_plugins_bad_version], [1.15.2]) +m4_define([gst_version], [1.15.2.1]) +m4_define([gst_plugins_base_version], [1.15.2.1]) +m4_define([gst_plugins_bad_version], [1.15.2.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.11.0]) diff --git a/docs/plugins/inspect/plugin-vaapi.xml b/docs/plugins/inspect/plugin-vaapi.xml index 042aaa1c2f..c0b1bf3964 100644 --- a/docs/plugins/inspect/plugin-vaapi.xml +++ b/docs/plugins/inspect/plugin-vaapi.xml @@ -3,7 +3,7 @@ VA-API based elements ../../gst/vaapi/.libs/libgstvaapi.so libgstvaapi.so - 1.15.2 + 1.15.2.1 LGPL gstreamer-vaapi gstreamer-vaapi diff --git a/meson.build b/meson.build index 5b36d1b6e6..6d8f1f8613 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.15.2', + version : '1.15.2.1', meson_version : '>= 0.47.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From bc8ddef96c0be5cf79924f5ddd4e331744a38b74 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 11 Mar 2019 18:38:36 -0300 Subject: [PATCH 3218/3781] Update common submodule back to 59cb678164719ff59dcf6c8b93df4617a1075d11 It was wrongly changed in 3d9555a86d45565870c684fe00ec8bbb0fed7205 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 3fa2c9e372..59cb678164 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 3fa2c9e372bceec30be91e67fb02b6cb05bed493 +Subproject commit 59cb678164719ff59dcf6c8b93df4617a1075d11 From 9cbdb7b5043f5be2eb3be1774a92d53d829ad67c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 21 Mar 2019 13:31:57 +0000 Subject: [PATCH 3219/3781] meson: use new 'python' module instead of deprecated 'python3' one --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 6d8f1f8613..52f2a881a6 100644 --- a/meson.build +++ b/meson.build @@ -146,5 +146,5 @@ if not get_option('examples').disabled() subdir('tests') endif -python3 = import('python3').find_python() +python3 = import('python').find_installation() run_command(python3, '-c', 'import shutil; shutil.copy("hooks/pre-commit.hook", ".git/hooks/pre-commit")') From 29d42e1600604f55286d31a2544e153117244257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 21 Mar 2019 16:56:34 +0000 Subject: [PATCH 3220/3781] meson: disable compiler warnings for unused vars and args if gst debug system is disabled --- meson.build | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/meson.build b/meson.build index 52f2a881a6..d4876a280d 100644 --- a/meson.build +++ b/meson.build @@ -52,6 +52,24 @@ gstcodecparsers_dep = dependency('gstreamer-codecparsers-1.0', version : gst_req fallback : ['gst-plugins-bad', 'gstcodecparsers_dep']) gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, fallback : ['gst-plugins-base', 'gstgl_dep'], required: false) + +# Disable compiler warnings for unused variables and args if gst debug system is disabled +if gst_dep.type_name() == 'internal' + gst_debug_disabled = not subproject('gstreamer').get_variable('gst_debug') +else + # We can't check that in the case of subprojects as we won't + # be able to build against an internal dependency (which is not built yet) + gst_debug_disabled = cc.has_header_symbol('gst/gstconfig.h', 'GST_DISABLE_GST_DEBUG', dependencies: gst_dep) +endif + +if gst_debug_disabled + message('GStreamer debug system is disabled') + add_project_arguments(cc.get_supported_arguments(['-Wno-unused']), language: 'c') +else + message('GStreamer debug system is enabled') +endif + +# Other deps gmodule_dep = dependency('gmodule-2.0', required: false) libva_dep = dependency('libva', version: libva_req) From acf10ce16454ed3520e1c1d6fa8e3e373555b4d9 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 15 Mar 2019 18:40:21 +0800 Subject: [PATCH 3221/3781] vaapiencode: gobject's prop_id differ from vaapi encoder The vaapi internal encoder's property id are negative, thus they are different from GObject's property ids. gst_vaapi_encoder_set_property() should map to the internal encoder property id, assigned in gst_vaapiencode_default_set_property(). --- gst/vaapi/gstvaapiencode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 489df0bcaa..b64233ff2b 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -181,7 +181,7 @@ gst_vaapiencode_default_set_property (GstVaapiEncode * encode, guint prop_id, g_value_copy (value, &prop_value->value); if (encoder) - return (gst_vaapi_encoder_set_property (encoder, prop_id, + return (gst_vaapi_encoder_set_property (encoder, prop_value->id, value) == GST_VAAPI_ENCODER_STATUS_SUCCESS); return TRUE; From 49f363bca2e6fadbd37e0e69b8c6d062a117c5c3 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Sat, 23 Mar 2019 15:34:03 +0800 Subject: [PATCH 3222/3781] libs: encoder: h265: add low power mode encode. By now, this feature only support by media-driver on Ice Lake platform, more information you can reference: https://github.com/intel/media-driver --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 44 ++++++++++++++++------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index c2c9f42997..3679dafa98 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -44,7 +44,8 @@ /* Supported set of tuning options, within this implementation */ #define SUPPORTED_TUNE_OPTIONS \ - (GST_VAAPI_ENCODER_TUNE_MASK (NONE)) + (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 \ @@ -92,6 +93,7 @@ struct _GstVaapiEncoderH265 GstVaapiProfile profile; GstVaapiTierH265 tier; GstVaapiLevelH265 level; + GstVaapiEntrypoint entrypoint; guint8 profile_idc; guint8 max_profile_idc; guint8 hw_max_profile_idc; @@ -918,7 +920,7 @@ static gboolean ensure_hw_profile (GstVaapiEncoderH265 * encoder) { GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); - GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + GstVaapiEntrypoint entrypoint = encoder->entrypoint; GstVaapiProfile profile, profiles[4]; guint i, num_profiles = 0; @@ -1070,6 +1072,10 @@ ensure_tuning (GstVaapiEncoderH265 * encoder) case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: success = ensure_tuning_high_compression (encoder); break; + case GST_VAAPI_ENCODER_TUNE_LOW_POWER: + encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; + success = TRUE; + break; default: success = TRUE; break; @@ -1525,9 +1531,12 @@ fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) seq_param->seq_fields.bits.sps_temporal_mvp_enabled_flag = encoder->sps_temporal_mvp_enabled_flag = TRUE; - /* Based on 32x32 CTU */ + /* Based on 32x32 CTU (64x64 when using lowpower mode for hardware limitation) */ seq_param->log2_min_luma_coding_block_size_minus3 = 0; - seq_param->log2_diff_max_min_luma_coding_block_size = 2; + if (GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) + seq_param->log2_diff_max_min_luma_coding_block_size = 3; + else + seq_param->log2_diff_max_min_luma_coding_block_size = 2; seq_param->log2_min_transform_block_size_minus2 = 0; seq_param->log2_diff_max_min_transform_block_size = 3; seq_param->max_transform_hierarchy_depth_inter = 3; @@ -1622,9 +1631,10 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, pic_param->pic_fields.bits.sign_data_hiding_enabled_flag = FALSE; pic_param->pic_fields.bits.transform_skip_enabled_flag = TRUE; /* it seems driver requires enablement of cu_qp_delta_enabled_flag - * to modifiy QP values in CBR mode encoding */ - pic_param->pic_fields.bits.cu_qp_delta_enabled_flag = - GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CQP; + * to modifiy QP values in CBR mode or low power encoding */ + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CQP + || GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) + pic_param->pic_fields.bits.cu_qp_delta_enabled_flag = 1; pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag = TRUE; @@ -2048,11 +2058,10 @@ reset_properties (GstVaapiEncoderH265 * encoder) ctu_size = encoder->ctu_width * encoder->ctu_height; g_assert (gst_vaapi_encoder_ensure_num_slices (base_encoder, encoder->profile, - GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, (ctu_size + 1) / 2, - &encoder->num_slices)); + encoder->entrypoint, (ctu_size + 1) / 2, &encoder->num_slices)); gst_vaapi_encoder_ensure_max_num_ref_frames (base_encoder, encoder->profile, - GST_VAAPI_ENTRYPOINT_SLICE_ENCODE); + encoder->entrypoint); if (base_encoder->max_num_ref_frames_1 < 1 && encoder->num_bframes > 0) { GST_WARNING ("Disabling b-frame since the driver doesn't support it"); @@ -2505,6 +2514,8 @@ set_context_info (GstVaapiEncoder * base_encoder) base_encoder->codedbuf_size += GST_ROUND_UP_16 (vip->width) * GST_ROUND_UP_16 (vip->height) * 3 / 2; + base_encoder->context_info.entrypoint = encoder->entrypoint; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } @@ -2523,10 +2534,14 @@ gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) GST_VAAPI_ENCODER_HEIGHT (encoder)); encoder->luma_width = GST_ROUND_UP_16 (luma_width); encoder->luma_height = GST_ROUND_UP_16 (luma_height); - encoder->ctu_width = (encoder->luma_width + 31) / 32; - encoder->ctu_height = (encoder->luma_height + 31) / 32; + if (GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) { + encoder->ctu_width = (encoder->luma_width + 63) / 64; + encoder->ctu_height = (encoder->luma_height + 63) / 64; + } else { + encoder->ctu_width = (encoder->luma_width + 31) / 32; + encoder->ctu_height = (encoder->luma_height + 31) / 32; + } encoder->config_changed = TRUE; - /* Frame Cropping */ if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) || (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) { @@ -2560,6 +2575,9 @@ gst_vaapi_encoder_h265_init (GstVaapiEncoder * base_encoder) GstVaapiH265ReorderPool *reorder_pool; GstVaapiH265RefPool *ref_pool; + /* Default encoding entrypoint */ + encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + encoder->conformance_window_flag = 0; encoder->num_slices = 1; From 871aecb0d4abd0d3c770572f01a66545077655bd Mon Sep 17 00:00:00 2001 From: Wangfei Date: Tue, 26 Mar 2019 14:20:34 +0800 Subject: [PATCH 3223/3781] libs: decoder: jpeg: support dynamic resolution change decode. Add size_changed flag to watch out resolution. if change, reset jpeg decoder's context. --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index ae39f1fa3c..baed198712 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -70,6 +70,7 @@ struct _GstVaapiDecoderJpegPrivate guint decoder_state; guint is_opened:1; guint profile_changed:1; + guint size_changed:1; }; /** @@ -123,6 +124,7 @@ gst_vaapi_decoder_jpeg_close (GstVaapiDecoderJpeg * decoder) priv->height = 0; priv->is_opened = FALSE; priv->profile_changed = TRUE; + priv->size_changed = TRUE; } static gboolean @@ -155,6 +157,7 @@ gst_vaapi_decoder_jpeg_create (GstVaapiDecoder * base_decoder) priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; priv->profile_changed = TRUE; + priv->size_changed = TRUE; return TRUE; } @@ -194,6 +197,12 @@ ensure_context (GstVaapiDecoderJpeg * decoder) priv->profile = profiles[i]; } + if (priv->size_changed) { + GST_DEBUG ("size changed"); + priv->size_changed = FALSE; + reset_context = TRUE; + } + if (reset_context) { GstVaapiContextInfo info; @@ -439,6 +448,10 @@ decode_picture (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg) 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; From 6669a7fc575fbbb6dc82fcbcd4d4491e75049e51 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 29 Mar 2019 13:33:41 +0800 Subject: [PATCH 3224/3781] libs: Change the parameter setting order when encode picture. The order in gst_vaapi_enc_picture_encode when encoding one picture is not very correct. The misc parameters are set before the picture parameters. Some of the misc parameters such as ROI may change the current picture parameters. But the later setting of picture parameter will re-init all picture related parameters and clear the previous setting. The right order should be picture parameter first and then misc parameters. Signed-off-by: He Junyan --- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index f31181e7f9..3227607c17 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -555,6 +555,10 @@ gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture) 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 = @@ -563,10 +567,6 @@ gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture) return FALSE; } - /* Submit Picture parameter */ - if (!do_encode (va_display, va_context, &picture->param_id, &picture->param)) - return FALSE; - /* Submit Slice parameters */ for (i = 0; i < picture->slices->len; i++) { GstVaapiEncSlice *const slice = g_ptr_array_index (picture->slices, i); From 6404bd399d7f322128f1dce2fa03f94764dfb5fe Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 26 Mar 2019 14:54:47 +0800 Subject: [PATCH 3225/3781] libs: encoder: h264: Use gst_param_spec_array for view-ids GValueArray is deprecated. Use GstValueArray instead. gst_param_spec_array can be deserialized from command line using: vaapih264enc view-ids="<(uint)40,(uint)100>" num-views=2 While the g_param_spec_value_array() can not, and always get error: "gst_value_deserialize_g_value_array: unimplemented" Also fixed an out-of-range bug. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 63 ++++++++++++++++------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index c3dfb24b05..928c1c3b15 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -21,9 +21,6 @@ * Boston, MA 02110-1301 USA */ -/* GValueArray has deprecated without providing an alternative in glib >= 2.32 - * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 - */ #define GLIB_DISABLE_DEPRECATION_WARNINGS #include "sysdeps.h" @@ -3440,6 +3437,46 @@ gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder) } } +static void +set_view_ids (GstVaapiEncoderH264 * const encoder, const GValue * value) +{ + guint i, j; + gboolean use_default = TRUE; + guint len = gst_value_array_get_size (value); + + /* Try the user set view IDs */ + if (len > 0) { + if (len != encoder->num_views) { + GST_WARNING ("The view number is %d, but %d view IDs are provided. Just " + "fallback to use default view IDs.", encoder->num_views, len); + goto set_default_ids; + } + + for (i = 0; i < len; i++) { + const GValue *val = gst_value_array_get_value (value, i); + encoder->view_ids[i] = g_value_get_uint (val); + } + + /* check whether duplicated ID */ + for (i = 0; i < len; i++) { + for (j = i + 1; j < len; j++) { + if (encoder->view_ids[i] == encoder->view_ids[j]) { + GST_WARNING ("The view %d and view %d have same view ID %d. Just " + "fallback to use default view IDs.", i, j, encoder->view_ids[i]); + goto set_default_ids; + } + } + } + + use_default = FALSE; + } + +set_default_ids: + if (use_default) + for (i = 0; i < encoder->num_views; i++) + encoder->view_ids[i] = i; +} + static GstVaapiEncoderStatus gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) @@ -3477,23 +3514,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: encoder->num_views = g_value_get_uint (value); break; - case GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS:{ - guint i; - GValueArray *view_ids = g_value_get_boxed (value); - - if (view_ids == NULL) { - for (i = 0; i < MAX_NUM_VIEWS; i++) - encoder->view_ids[i] = i; - } else { - g_assert (view_ids->n_values <= encoder->num_views); - - for (i = 0; i < encoder->num_views; i++) { - GValue *val = g_value_array_get_nth (view_ids, i); - encoder->view_ids[i] = g_value_get_uint (val); - } - } + case GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS: + set_view_ids (encoder, value); break; - } case GST_VAAPI_ENCODER_H264_PROP_AUD: encoder->use_aud = g_value_get_boolean (value); break; @@ -3752,7 +3775,7 @@ gst_vaapi_encoder_h264_get_default_properties (void) */ GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS, - g_param_spec_value_array ("view-ids", + gst_param_spec_array ("view-ids", "View IDs", "Set of View Ids used for MVC encoding", g_param_spec_uint ("view-id-value", "View id value", "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, From 7dc77ebf60edc37bcf7c26e0fbeb6ec963df293e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 29 Mar 2019 18:29:51 +0100 Subject: [PATCH 3226/3781] libs: encoder: h264: simplify the view-ids setting --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 52 +++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 928c1c3b15..d3bda05bcf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3441,40 +3441,40 @@ static void set_view_ids (GstVaapiEncoderH264 * const encoder, const GValue * value) { guint i, j; - gboolean use_default = TRUE; guint len = gst_value_array_get_size (value); - /* Try the user set view IDs */ - if (len > 0) { - if (len != encoder->num_views) { - GST_WARNING ("The view number is %d, but %d view IDs are provided. Just " - "fallback to use default view IDs.", encoder->num_views, len); - goto set_default_ids; - } + if (len == 0) + goto set_default_ids; - for (i = 0; i < len; i++) { - const GValue *val = gst_value_array_get_value (value, i); - encoder->view_ids[i] = g_value_get_uint (val); - } - - /* check whether duplicated ID */ - for (i = 0; i < len; i++) { - for (j = i + 1; j < len; j++) { - if (encoder->view_ids[i] == encoder->view_ids[j]) { - GST_WARNING ("The view %d and view %d have same view ID %d. Just " - "fallback to use default view IDs.", i, j, encoder->view_ids[i]); - goto set_default_ids; - } - } - } - - use_default = FALSE; + if (len != encoder->num_views) { + GST_WARNING ("The view number is %d, but %d view IDs are provided. Just " + "fallback to use default view IDs.", encoder->num_views, len); + goto set_default_ids; } + for (i = 0; i < len; i++) { + const GValue *val = gst_value_array_get_value (value, i); + encoder->view_ids[i] = g_value_get_uint (val); + } + + /* check whether duplicated ID */ + for (i = 0; i < len; i++) { + for (j = i + 1; j < len; j++) { + if (encoder->view_ids[i] == encoder->view_ids[j]) { + GST_WARNING ("The view %d and view %d have same view ID %d. Just " + "fallback to use default view IDs.", i, j, encoder->view_ids[i]); + goto set_default_ids; + } + } + } + + return; + set_default_ids: - if (use_default) + { for (i = 0; i < encoder->num_views; i++) encoder->view_ids[i] = i; + } } static GstVaapiEncoderStatus From f91046bad3a18897ffa76dfab5dfb11ac81fb187 Mon Sep 17 00:00:00 2001 From: Danilo Spinella Date: Sat, 30 Mar 2019 18:29:31 +0100 Subject: [PATCH 3227/3781] vaapipluginutil: Fix #endif for USE_X11 --- gst/vaapi/gstvaapipluginutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index fcbbc324c3..51fdf12e5a 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -143,10 +143,10 @@ gst_vaapi_get_display_type_from_gl (GstGLDisplayType gl_display_type, #if USE_GLX if (gl_platform == GST_GL_PLATFORM_GLX) return GST_VAAPI_DISPLAY_TYPE_GLX; -#endif #endif return GST_VAAPI_DISPLAY_TYPE_X11; } +#endif #if USE_WAYLAND case GST_GL_DISPLAY_TYPE_WAYLAND:{ return GST_VAAPI_DISPLAY_TYPE_WAYLAND; From 539c39fbe13a291e4ca7df8768e8cfea390bef2b Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 1 Apr 2019 12:56:28 +0800 Subject: [PATCH 3228/3781] libs: encoder: h264_fei: Use gst_param_spec_array for view-ids GValueArray is deprecated. Use GstValueArray instead. --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 60 +++++++++++++------ gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 60 +++++++++++++------ gst-libs/gst/vaapi/gstvaapifeipak_h264.c | 58 +++++++++++++----- 3 files changed, 128 insertions(+), 50 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index f899b0588b..b4d41c63c5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -3414,6 +3414,46 @@ gst_vaapi_encoder_h264_fei_finalize (GstVaapiEncoder * base_encoder) } } +static void +set_view_ids (GstVaapiEncoderH264Fei * const encoder, const GValue * value) +{ + guint i, j; + guint len = gst_value_array_get_size (value); + + if (len == 0) + goto set_default_ids; + + if (len != encoder->num_views) { + GST_WARNING ("The view number is %d, but %d view IDs are provided. Just " + "fallback to use default view IDs.", encoder->num_views, len); + goto set_default_ids; + } + + for (i = 0; i < len; i++) { + const GValue *val = gst_value_array_get_value (value, i); + encoder->view_ids[i] = g_value_get_uint (val); + } + + /* check whether duplicated ID */ + for (i = 0; i < len; i++) { + for (j = i + 1; j < len; j++) { + if (encoder->view_ids[i] == encoder->view_ids[j]) { + GST_WARNING ("The view %d and view %d have same view ID %d. Just " + "fallback to use default view IDs.", i, j, encoder->view_ids[i]); + goto set_default_ids; + } + } + } + + return; + +set_default_ids: + { + for (i = 0; i < encoder->num_views; i++) + encoder->view_ids[i] = i; + } +} + static GstVaapiEncoderStatus gst_vaapi_encoder_h264_fei_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) @@ -3448,23 +3488,9 @@ gst_vaapi_encoder_h264_fei_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS: encoder->num_views = g_value_get_uint (value); break; - case GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS:{ - guint i; - GValueArray *view_ids = g_value_get_boxed (value); - - if (view_ids == NULL) { - for (i = 0; i < encoder->num_views; i++) - encoder->view_ids[i] = i; - } else { - g_assert (view_ids->n_values <= encoder->num_views); - - for (i = 0; i < encoder->num_views; i++) { - GValue *val = g_value_array_get_nth (view_ids, i); - encoder->view_ids[i] = g_value_get_uint (val); - } - } + case GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS: + set_view_ids (encoder, value); break; - } case GST_VAAPI_ENCODER_H264_PROP_FEI_DISABLE: encoder->is_fei_disabled = g_value_get_boolean (value); if (!encoder->is_fei_disabled) @@ -4108,7 +4134,7 @@ gst_vaapi_encoder_h264_fei_get_default_properties (void) */ GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS, - g_param_spec_value_array ("view-ids", + gst_param_spec_array ("view-ids", "View IDs", "Set of View Ids used for MVC encoding", g_param_spec_uint ("view-id-value", "View id value", "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index edbab131a3..df88215331 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -1700,6 +1700,46 @@ gst_vaapi_feienc_h264_finalize (GstVaapiEncoder * base_encoder) } } +static void +set_view_ids (GstVaapiFeiEncH264 * const encoder, const GValue * value) +{ + guint i, j; + guint len = gst_value_array_get_size (value); + + if (len == 0) + goto set_default_ids; + + if (len != encoder->num_views) { + GST_WARNING ("The view number is %d, but %d view IDs are provided. Just " + "fallback to use default view IDs.", encoder->num_views, len); + goto set_default_ids; + } + + for (i = 0; i < len; i++) { + const GValue *val = gst_value_array_get_value (value, i); + encoder->view_ids[i] = g_value_get_uint (val); + } + + /* check whether duplicated ID */ + for (i = 0; i < len; i++) { + for (j = i + 1; j < len; j++) { + if (encoder->view_ids[i] == encoder->view_ids[j]) { + GST_WARNING ("The view %d and view %d have same view ID %d. Just " + "fallback to use default view IDs.", i, j, encoder->view_ids[i]); + goto set_default_ids; + } + } + } + + return; + +set_default_ids: + { + for (i = 0; i < encoder->num_views; i++) + encoder->view_ids[i] = i; + } +} + GstVaapiEncoderStatus gst_vaapi_feienc_h264_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) @@ -1731,23 +1771,9 @@ gst_vaapi_feienc_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_FEI_H264_ENC_PROP_NUM_VIEWS: feienc->num_views = g_value_get_uint (value); break; - case GST_VAAPI_FEI_H264_ENC_PROP_VIEW_IDS:{ - guint i; - GValueArray *view_ids = g_value_get_boxed (value); - - if (view_ids == NULL) { - for (i = 0; i < feienc->num_views; i++) - feienc->view_ids[i] = i; - } else { - g_assert (view_ids->n_values <= feienc->num_views); - - for (i = 0; i < feienc->num_views; i++) { - GValue *val = g_value_array_get_nth (view_ids, i); - feienc->view_ids[i] = g_value_get_uint (val); - } - } + case GST_VAAPI_FEI_H264_ENC_PROP_VIEW_IDS: + set_view_ids (feienc, value); break; - } case GST_VAAPI_FEI_H264_ENC_PROP_NUM_REF: feienc->num_ref_frames = g_value_get_uint (value); break; @@ -2156,7 +2182,7 @@ gst_vaapi_feienc_h264_get_default_properties (void) */ GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_FEI_H264_ENC_PROP_VIEW_IDS, - g_param_spec_value_array ("view-ids", + gst_param_spec_array ("view-ids", "View IDs", "Set of View Ids used for MVC encoding", g_param_spec_uint ("view-id-value", "View id value", "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, diff --git a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c index e58d69d8ec..ceb821b256 100644 --- a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c @@ -1799,6 +1799,46 @@ gst_vaapi_feipak_h264_finalize (GstVaapiFEIPakH264 * feipak) } +static void +set_view_ids (GstVaapiFEIPakH264 * feipak, const GValue * value) +{ + guint i, j; + guint len = gst_value_array_get_size (value); + + if (len == 0) + goto set_default_ids; + + if (len != feipak->num_views) { + GST_WARNING ("The view number is %d, but %d view IDs are provided. Just " + "fallback to use default view IDs.", feipak->num_views, len); + goto set_default_ids; + } + + for (i = 0; i < len; i++) { + const GValue *val = gst_value_array_get_value (value, i); + feipak->view_ids[i] = g_value_get_uint (val); + } + + /* check whether duplicated ID */ + for (i = 0; i < len; i++) { + for (j = i + 1; j < len; j++) { + if (feipak->view_ids[i] == feipak->view_ids[j]) { + GST_WARNING ("The view %d and view %d have same view ID %d. Just " + "fallback to use default view IDs.", i, j, feipak->view_ids[i]); + goto set_default_ids; + } + } + } + + return; + +set_default_ids: + { + for (i = 0; i < feipak->num_views; i++) + feipak->view_ids[i] = i; + } +} + GstVaapiEncoderStatus gst_vaapi_feipak_h264_set_property (GstVaapiFEIPakH264 * feipak, gint prop_id, const GValue * value) @@ -1811,23 +1851,9 @@ gst_vaapi_feipak_h264_set_property (GstVaapiFEIPakH264 * feipak, case GST_VAAPI_FEIPAK_H264_PROP_NUM_VIEWS: feipak->num_views = g_value_get_uint (value); break; - case GST_VAAPI_FEIPAK_H264_PROP_VIEW_IDS:{ - guint i; - GValueArray *view_ids = g_value_get_boxed (value); - - if (view_ids == NULL) { - for (i = 0; i < feipak->num_views; i++) - feipak->view_ids[i] = i; - } else { - g_assert (view_ids->n_values <= feipak->num_views); - - for (i = 0; i < feipak->num_views; i++) { - GValue *val = g_value_array_get_nth (view_ids, i); - feipak->view_ids[i] = g_value_get_uint (val); - } - } + case GST_VAAPI_FEIPAK_H264_PROP_VIEW_IDS: + set_view_ids (feipak, value); break; - } default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } From 81203a6098038d347e3ff54a4d1aff321209da10 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Tue, 9 Apr 2019 09:20:23 +0800 Subject: [PATCH 3229/3781] meson: build test-vaapicontext when using X11 x11_dep and libva_x11_dep are optional and meson ignores these dependencies even if they are added into the dependency list. This fixes the error below when libva-x11 is not avaiblabe: cc -Itests/elements/tests@elements@@test-vaapicontext@exe -Itests/elements -I../../gstreamer-vaapi/tests/elements -I. -I../../gstreamer-vaapi/ -Igst-libs -I../../gstreamer-vaapi/gst-libs -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/orc-0.4 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/libdrm -I/usr/include/harfbuzz -I/usr/include/pango-1.0 -I/usr/include/fribidi -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/uuid -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -O2 -g -fvisibility=hidden -fno-strict-aliasing -pthread -DHAVE_CONFIG_H -MD -MQ 'tests/elements/tests@elements@@test-vaapicontext@exe/test-vaapicontext.c.o' -MF 'tests/elements/tests@elements@@test-vaapicontext@exe/test-vaapicontext.c.o.d' -o 'tests/elements/tests@elements@@test-vaapicontext@exe/test-vaapicontext.c.o' -c ../../gstreamer-vaapi/tests/elements/test-vaapicontext.c ../../gstreamer-vaapi/tests/elements/test-vaapicontext.c:29:10: fatal error: va/va_x11.h: No such file or directory #include --- tests/elements/meson.build | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/elements/meson.build b/tests/elements/meson.build index f64d1cda2c..0a61f7d050 100644 --- a/tests/elements/meson.build +++ b/tests/elements/meson.build @@ -12,6 +12,7 @@ foreach example : examples install: false) endforeach +if USE_X11 if gtk_dep.found() executable('test-vaapicontext', 'test-vaapicontext.c', c_args : gstreamer_vaapi_args, @@ -24,3 +25,4 @@ if gtk_dep.found() libva_x11_dep ], install: false) endif +endif From d4bc0cb6da56091945e771bddd52e81f28b11688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 9 Apr 2019 12:42:56 +0200 Subject: [PATCH 3230/3781] libs: encoder: h264,h265: initial and minimal QP can be zero Currently the minimal value for either min_qp and init_qp are 1, but VA documentation specifiy that zero is also valid and means to ignore the quantiser. The default value is not changed though to avoid behaivor changes to users. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index d3bda05bcf..e6947204d8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3623,7 +3623,7 @@ gst_vaapi_encoder_h264_get_default_properties (void) GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H264_PROP_INIT_QP, g_param_spec_uint ("init-qp", - "Initial QP", "Initial quantizer value", 1, 51, 26, + "Initial QP", "Initial quantizer value", 0, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** @@ -3634,7 +3634,7 @@ gst_vaapi_encoder_h264_get_default_properties (void) GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H264_PROP_MIN_QP, g_param_spec_uint ("min-qp", - "Minimum QP", "Minimum quantizer value", 1, 51, 1, + "Minimum QP", "Minimum quantizer value", 0, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index b4d41c63c5..1ed8255afc 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -4050,7 +4050,7 @@ gst_vaapi_encoder_h264_fei_get_default_properties (void) GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H264_FEI_PROP_INIT_QP, g_param_spec_uint ("init-qp", - "Initial QP", "Initial quantizer value", 1, 51, 26, + "Initial QP", "Initial quantizer value", 0, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** @@ -4061,7 +4061,7 @@ gst_vaapi_encoder_h264_fei_get_default_properties (void) GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H264_FEI_PROP_MIN_QP, g_param_spec_uint ("min-qp", - "Minimum QP", "Minimum quantizer value", 1, 51, 1, + "Minimum QP", "Minimum quantizer value", 0, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 3679dafa98..a2e61d80a2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2755,7 +2755,7 @@ gst_vaapi_encoder_h265_get_default_properties (void) GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H265_PROP_INIT_QP, g_param_spec_uint ("init-qp", - "Initial QP", "Initial quantizer value", 1, 51, 26, + "Initial QP", "Initial quantizer value", 0, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** @@ -2766,7 +2766,7 @@ gst_vaapi_encoder_h265_get_default_properties (void) GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_H265_PROP_MIN_QP, g_param_spec_uint ("min-qp", - "Minimum QP", "Minimum quantizer value", 1, 51, 1, + "Minimum QP", "Minimum quantizer value", 0, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** From 5b1fe9c68afcdd956dea6c43db529eb546cc1eb3 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 3 Apr 2019 14:12:23 +0800 Subject: [PATCH 3231/3781] libs: encoder: h264,h265: Set max_qp if min_qp is non-zero. media-driver currently fails to set a correct value of max_qp when min_qp is different to zero, in CBR and VBR mode, generating full quality frames, thus unexpected huge output. This patch sets max_qp to an arbitrary value to avoid this output temporary. Fixes: #144 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 4 ++++ gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 4 ++++ gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index e6947204d8..b87f420e83 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2519,6 +2519,10 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; + /* @FIXME: should not set this value, should be ignored if set to zero * + * https://github.com/intel/media-driver/issues/587 */ + if (encoder->min_qp > 0) + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).max_qp = 51; #if VA_CHECK_VERSION(1,0,0) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).rc_flags.bits.mb_rate_control = diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index 1ed8255afc..7bb95200b9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -2449,6 +2449,10 @@ ensure_misc_params (GstVaapiEncoderH264Fei * encoder, rate_control->window_size = encoder->cpb_length; rate_control->initial_qp = encoder->init_qp; rate_control->min_qp = encoder->min_qp; + /* @FIXME: should not set this value, should be ignored if set to zero * + * https://github.com/intel/media-driver/issues/587 */ + if (rate_control->min_qp > 0) + rate_control->max_qp = 51; rate_control->basic_unit_size = 0; gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index a2e61d80a2..4290ad3713 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1858,6 +1858,10 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; + /* @FIXME: should not set this value, should be ignored if set to zero * + * https://github.com/intel/media-driver/issues/587 */ + if (encoder->min_qp > 0) + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).max_qp = 51; #if VA_CHECK_VERSION(1,0,0) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).rc_flags.bits.mb_rate_control = From 58e74f9440fed4031394be2de6c64d593546716b Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 9 Apr 2019 20:42:04 +0800 Subject: [PATCH 3232/3781] libs: encoder: h265: Recognize the correct level and tier. The current manner can not recognize the correct level and always set the tier to main. Need to add frame rate check to recognize levels such as 4.1, 6.2, etc. We also add a logic to check main and high tier based on bitrate. Fixes: #145 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 51 +++++++++++++---------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 4290ad3713..52d74f5a6f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -998,38 +998,46 @@ ensure_profile (GstVaapiEncoderH265 * encoder) return TRUE; } -/* Derives the minimum tier from the active coding tools */ +/* Derives the level and tier from the currently set limits */ static gboolean -ensure_tier (GstVaapiEncoderH265 * encoder) +ensure_tier_level (GstVaapiEncoderH265 * encoder) { - - encoder->tier = GST_VAAPI_TIER_H265_MAIN; - /* FIXME: Derive proper tier based on upstream caps or limits, coding - * tools etc */ - - return TRUE; -} - -/* Derives the level from the currently set limits */ -static gboolean -ensure_level (GstVaapiEncoderH265 * encoder) -{ - const GstVaapiH265LevelLimits *limits_table; + guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate; guint i, num_limits, PicSizeInSamplesY; + guint LumaSr; + const GstVaapiH265LevelLimits *limits_table; PicSizeInSamplesY = encoder->luma_width * encoder->luma_height; + LumaSr = + gst_util_uint64_scale (PicSizeInSamplesY, + GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder)); limits_table = gst_vaapi_utils_h265_get_level_limits_table (&num_limits); for (i = 0; i < num_limits; i++) { const GstVaapiH265LevelLimits *const limits = &limits_table[i]; - if (PicSizeInSamplesY <= limits->MaxLumaPs) + /* Choose level by luma picture size and luma sample rate */ + if (PicSizeInSamplesY <= limits->MaxLumaPs && LumaSr <= limits->MaxLumaSr) break; - /* FIXME: Add more constraint checking:tier (extracted from caps), - * cpb size, bitrate, num_tile_columns and num_tile_rows */ } + if (i == num_limits) goto error_unsupported_level; + if (bitrate <= limits_table[i].MaxBRTierMain) { + encoder->tier = GST_VAAPI_TIER_H265_MAIN; + } else { + encoder->tier = GST_VAAPI_TIER_H265_HIGH; + if (bitrate > limits_table[i].MaxBRTierHigh) { + GST_INFO ("The bitrate of the stream is %d kbps, larger than" + " %s profile %s level %s tier's max bit rate %d kbps", + bitrate, + gst_vaapi_utils_h265_get_profile_string (encoder->profile), + gst_vaapi_utils_h265_get_level_string (limits_table[i].level), + gst_vaapi_utils_h265_get_tier_string (GST_VAAPI_TIER_H265_HIGH), + limits_table[i].MaxBRTierHigh); + } + } + encoder->level = limits_table[i].level; encoder->level_idc = limits_table[i].level_idc; return TRUE; @@ -1042,6 +1050,7 @@ error_unsupported_level: } } +/* Derives the minimum tier from the active coding tools */ /* Enable "high-compression" tuning options */ static gboolean ensure_tuning_high_compression (GstVaapiEncoderH265 * encoder) @@ -2024,14 +2033,10 @@ ensure_profile_tier_level (GstVaapiEncoderH265 * encoder) if (encoder->profile_idc > encoder->hw_max_profile_idc) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - /* ensure tier */ - if (!ensure_tier (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; - /* Ensure bitrate if not set already and derive the right level to use */ ensure_bitrate (encoder); - if (!ensure_level (encoder)) + if (!ensure_tier_level (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; if (encoder->profile != profile || encoder->level != level From bdfba172d1961dd8a27e7f4b38c1c7807e71b100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 11 Apr 2019 00:40:03 +0100 Subject: [PATCH 3233/3781] Update docs --- docs/plugins/inspect/plugin-vaapi.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/plugins/inspect/plugin-vaapi.xml b/docs/plugins/inspect/plugin-vaapi.xml index c0b1bf3964..4b85e42a13 100644 --- a/docs/plugins/inspect/plugin-vaapi.xml +++ b/docs/plugins/inspect/plugin-vaapi.xml @@ -3,7 +3,7 @@ VA-API based elements ../../gst/vaapi/.libs/libgstvaapi.so libgstvaapi.so - 1.15.2.1 + 1.15.90 LGPL gstreamer-vaapi gstreamer-vaapi @@ -26,7 +26,7 @@ src source always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
@@ -62,7 +62,7 @@ sink sink always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
src @@ -125,7 +125,7 @@ sink sink always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
src @@ -146,13 +146,13 @@ sink sink always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }
src source always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
@@ -167,7 +167,7 @@ sink sink always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:VASurface, meta:GstVideoOverlayComposition), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoOverlayComposition), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:VASurface, meta:GstVideoOverlayComposition), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoOverlayComposition), format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
From 07d43f75ba69456d9486901141ccddef0ac3ff02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 11 Apr 2019 00:40:03 +0100 Subject: [PATCH 3234/3781] Release 1.15.90 --- ChangeLog | 197 +++++++++++++++++++++++++++++++++++++++++++ NEWS | 98 ++++++++++++--------- RELEASE | 2 +- configure.ac | 14 +-- gstreamer-vaapi.doap | 10 +++ meson.build | 2 +- 6 files changed, 272 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index a3672c8866..e11f75adf2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,200 @@ +=== release 1.15.90 === + +2019-04-11 00:40:03 +0100 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * RELEASE: + * configure.ac: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.15.90 + +2019-04-11 00:40:03 +0100 Tim-Philipp Müller + + * docs/plugins/inspect/plugin-vaapi.xml: + Update docs + +2019-04-09 20:42:04 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: Recognize the correct level and tier. + The current manner can not recognize the correct level and always + set the tier to main. Need to add frame rate check to recognize + levels such as 4.1, 6.2, etc. We also add a logic to check main + and high tier based on bitrate. + Fixes: #145 + +2019-04-03 14:12:23 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h264,h265: Set max_qp if min_qp is non-zero. + media-driver currently fails to set a correct value of max_qp when + min_qp is different to zero, in CBR and VBR mode, generating full + quality frames, thus unexpected huge output. + This patch sets max_qp to an arbitrary value to avoid this output + temporary. + Fixes: #144 + +2019-04-09 12:42:56 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h264,h265: initial and minimal QP can be zero + Currently the minimal value for either min_qp and init_qp are 1, + but VA documentation specifiy that zero is also valid and means + to ignore the quantiser. + The default value is not changed though to avoid behaivor changes + to users. + +2019-04-09 09:20:23 +0800 Haihao Xiang + + * tests/elements/meson.build: + meson: build test-vaapicontext when using X11 + x11_dep and libva_x11_dep are optional and meson ignores these + dependencies even if they are added into the dependency list. + This fixes the error below when libva-x11 is not avaiblabe: + cc -Itests/elements/tests@elements@@test-vaapicontext@exe + -Itests/elements -I../../gstreamer-vaapi/tests/elements -I. + -I../../gstreamer-vaapi/ -Igst-libs -I../../gstreamer-vaapi/gst-libs + -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 + -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/orc-0.4 + -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 + -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include + -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ + -I/usr/include/libdrm -I/usr/include/harfbuzz -I/usr/include/pango-1.0 + -I/usr/include/fribidi -I/usr/include/atk-1.0 -I/usr/include/cairo + -I/usr/include/pixman-1 -I/usr/include/uuid -I/usr/include/freetype2 + -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 + -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall + -Winvalid-pch -O2 -g -fvisibility=hidden -fno-strict-aliasing -pthread + -DHAVE_CONFIG_H -MD -MQ + 'tests/elements/tests@elements@@test-vaapicontext@exe/test-vaapicontext.c.o' + -MF + 'tests/elements/tests@elements@@test-vaapicontext@exe/test-vaapicontext.c.o.d' + -o + 'tests/elements/tests@elements@@test-vaapicontext@exe/test-vaapicontext.c.o' + -c ../../gstreamer-vaapi/tests/elements/test-vaapicontext.c + ../../gstreamer-vaapi/tests/elements/test-vaapicontext.c:29:10: fatal + error: va/va_x11.h: No such file or directory + #include + +2019-04-01 12:56:28 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + * gst-libs/gst/vaapi/gstvaapifeipak_h264.c: + libs: encoder: h264_fei: Use gst_param_spec_array for view-ids + GValueArray is deprecated. Use GstValueArray instead. + +2019-03-30 18:29:31 +0100 Danilo Spinella + + * gst/vaapi/gstvaapipluginutil.c: + vaapipluginutil: Fix #endif for USE_X11 + +2019-03-29 18:29:51 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: simplify the view-ids setting + +2019-03-26 14:54:47 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: Use gst_param_spec_array for view-ids + GValueArray is deprecated. Use GstValueArray instead. + gst_param_spec_array can be deserialized from command line using: + vaapih264enc view-ids="<(uint)40,(uint)100>" num-views=2 + While the g_param_spec_value_array() can not, and always get + error: "gst_value_deserialize_g_value_array: unimplemented" + Also fixed an out-of-range bug. + +2019-03-29 13:33:41 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + libs: Change the parameter setting order when encode picture. + The order in gst_vaapi_enc_picture_encode when encoding one + picture is not very correct. The misc parameters are set before + the picture parameters. Some of the misc parameters such as + ROI may change the current picture parameters. But the later + setting of picture parameter will re-init all picture related + parameters and clear the previous setting. The right order + should be picture parameter first and then misc parameters. + Signed-off-by: He Junyan + +2019-03-26 14:20:34 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + libs: decoder: jpeg: support dynamic resolution change decode. + Add size_changed flag to watch out resolution. if change, reset + jpeg decoder's context. + +2019-03-23 15:34:03 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: add low power mode encode. + By now, this feature only support by media-driver on Ice Lake + platform, more information you can reference: + https://github.com/intel/media-driver + +2019-03-15 18:40:21 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: gobject's prop_id differ from vaapi encoder + The vaapi internal encoder's property id are negative, thus they are + different from GObject's property ids. + gst_vaapi_encoder_set_property() should map to the internal encoder + property id, assigned in gst_vaapiencode_default_set_property(). + +2019-03-21 16:56:34 +0000 Tim-Philipp Müller + + * meson.build: + meson: disable compiler warnings for unused vars and args if gst debug system is disabled + +2019-03-21 13:31:57 +0000 Tim-Philipp Müller + + * meson.build: + meson: use new 'python' module instead of deprecated 'python3' one + +2019-03-11 18:38:36 -0300 Thibault Saunier + + * common: + Update common submodule back to 59cb678164719ff59dcf6c8b93df4617a1075d11 + It was wrongly changed in 3d9555a86d45565870c684fe00ec8bbb0fed7205 + +2019-03-04 09:16:17 +0000 Tim-Philipp Müller + + * NEWS: + * RELEASE: + * configure.ac: + * docs/plugins/inspect/plugin-vaapi.xml: + * meson.build: + Back to development + +2019-03-01 12:33:26 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + libs: Fix a typo in comments. + Fix a typo in function description of + gst_vaapi_surface_pool_new_with_chroma_type. + Signed-off-by: He Junyan + +2019-02-27 13:02:10 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugin: if any caps in downstream, negotiate raw video + When downstream has any caps, vaapi should not shovel vaapi featured + buffers, but rather plain raw video, assuming always the worst case + scenario (downstream cannot handle featured video memory but raw + system memory buffers). + This patch query the peer caps without any filter, to know if + donwstream just ask for any caps, if so jump to the color space + checking, otherwise do the caps intersection and continue with the + feature selection algorithm. + Fixes: #139 + === release 1.15.2 === 2019-02-26 12:01:53 +0000 Tim-Philipp Müller diff --git a/NEWS b/NEWS index e6f8c3dbe7..16402a590e 100644 --- a/NEWS +++ b/NEWS @@ -4,7 +4,7 @@ GSTREAMER 1.16 RELEASE NOTES GStreamer 1.16 has not been released yet. It is scheduled for release in -March 2019. +April 2019. 1.15.x is the unstable development version that is being developed in the git master branch and which will eventually result in 1.16. @@ -15,7 +15,7 @@ the git master branch and which will eventually result in 1.16. See https://gstreamer.freedesktop.org/releases/1.16/ for the latest version of this document. -_Last updated: Wednesday 27 January 2019, 00:30 UTC (log)_ +_Last updated: Wednesday 10 April 2019, 00:50 UTC (log)_ Introduction @@ -648,6 +648,15 @@ OpenGL integration import DMABUF FDs and also directly pass the pixel format, relying on the GPU to do the conversion. +- The OpenGL library no longer restores the OpenGL viewport. This is a + performance optimization to not require performing multiple + expensive glGet*() function calls per frame. This affects any + application or plugin use of the following functions and objects: + - glcolorconvert library object (not the element) + - glviewconvert library object (not the element) + - gst_gl_framebuffer_draw_to_texture() + - custom GstGLWindow implementations + Tracing framework and debugging improvements @@ -1164,47 +1173,51 @@ Windows Contributors -Aleix Conchillo Flaqué, Alessandro Decina, Alexandru Băluț, Alex Ashley, -Alexey Chernov, Alicia Boya García, Amit Pandya, Andoni Morales -Alastruey, Andreas Frisch, Andre McCurdy, Andy Green, Anthony Violo, -Antoine Jacoutot, Antonio Ospite, Arun Raghavan, Aurelien Jarno, +Aaron Boxer, Aleix Conchillo Flaqué, Alessandro Decina, Alexandru Băluț, +Alex Ashley, Alexey Chernov, Alicia Boya García, Amit Pandya, Andoni +Morales Alastruey, Andreas Frisch, Andre McCurdy, Andy Green, Anthony +Violo, Antoine Jacoutot, Antonio Ospite, Arun Raghavan, Aurelien Jarno, Aurélien Zanelli, ayaka, Bananahemic, Bastian Köcher, Branko Subasic, -Brendan Shanks, Carlos Rafael Giani, Christoph Reiter, Corentin Noël, -Daeseok Youn, Daniel Drake, Daniel Klamt, Dardo D Kleiner, David Ing, -David Svensson Fors, Devarsh Thakkar, Dimitrios Katsaros, Edward Hervey, -Emilio Pozuelo Monfort, Enrique Ocaña González, Ezequiel Garcia, Fabien -Dessenne, Fabrizio Gennari, Florent Thiéry, Francisco Velazquez, -Freyr666, Garima Gaur, Gary Bisson, George Kiagiadakis, Georg Lippitsch, -Georg Ottinger, Geunsik Lim, Göran Jönsson, Guillaume Desmottes, H1Gdev, -Haihao Xiang, Haihua Hu, Harshad Khedkar, Havard Graff, He Junyan, -Hoonhee Lee, Hosang Lee, Hyunjun Ko, Ingo Randolf, Iñigo Huguet, James -Stevenson, Jan Alexander Steffens, Jan Schmidt, Jerome Laheurte, Jimmy -Ohn, Joakim Johansson, Jochen Henneberg, Johan Bjäreholt, John-Mark -Bell, John Nikolaides, Jonathan Karlsson, Jonny Lamb, Jordan Petridis, -Josep Torra, Joshua M. Doe, Jos van Egmond, Juan Navarro, Jun Xie, +Brendan Shanks, Carlos Rafael Giani, Charlie Turner, Christoph Reiter, +Corentin Noël, Daeseok Youn, Damian Vicino, Dan Kegel, Daniel Drake, +Daniel Klamt, Danilo Spinella, Dardo D Kleiner, David Ing, David +Svensson Fors, Devarsh Thakkar, Dimitrios Katsaros, Edward Hervey, +Emilio Pozuelo Monfort, Enrique Ocaña González, Erlend Eriksen, Ezequiel +Garcia, Fabien Dessenne, Fabrizio Gennari, Florent Thiéry, Francisco +Velazquez, Freyr666, Garima Gaur, Gary Bisson, George Kiagiadakis, Georg +Lippitsch, Georg Ottinger, Geunsik Lim, Göran Jönsson, Guillaume +Desmottes, H1Gdev, Haihao Xiang, Haihua Hu, Harshad Khedkar, Havard +Graff, He Junyan, Hoonhee Lee, Hosang Lee, Hyunjun Ko, Ilya Smelykh, +Ingo Randolf, Iñigo Huguet, Jakub Adam, James Stevenson, Jan Alexander +Steffens, Jan Schmidt, Jerome Laheurte, Jimmy Ohn, Joakim Johansson, +Jochen Henneberg, Johan Bjäreholt, John-Mark Bell, John Bassett, John +Nikolaides, Jonathan Karlsson, Jonny Lamb, Jordan Petridis, Josep Torra, +Joshua M. Doe, Jos van Egmond, Juan Navarro, Julian Bouzas, Jun Xie, Junyan He, Justin Kim, Kai Kang, Kim Tae Soo, Kirill Marinushkin, Kyrylo Polezhaiev, Lars Petter Endresen, Linus Svensson, Louis-Francis -Ratté-Boulianne, Luis de Bethencourt, Luz Paz, Lyon Wang, Maciej Wolny, -Marc-André Lureau, Marc Leeman, Marcos Kintschner, Marian Mihailescu, -Marinus Schraal, Mark Nauwelaerts, Marouen Ghodhbane, Martin Kelly, -Matej Knopp, Mathieu Duponchelle, Matteo Valdina, Matthew Waters, -Matthias Fend, memeka, Michael Drake, Michael Gruner, Michael Olbrich, -Michael Tretter, Miguel Paris, Mike Wey, Mikhail Fludkov, Naveen -Cherukuri, Nicola Murino, Nicolas Dufresne, Niels De Graef, Nirbheek -Chauhan, Norbert Wesp, Ognyan Tonchev, Olivier Crête, Omar Akkila, -Patricia Muscalu, Patrick Radizi, Patrik Nilsson, Paul Kocialkowski, Per -Forlin, Peter Körner, Peter Seiderer, Petr Kulhavy, Philippe Normand, -Philippe Renon, Philipp Zabel, Pierre Labastie, Roland Jon, Roman -Sivriver, Rosen Penev, Russel Winder, Sam Gigliotti, Sean-Der, Sebastian -Dröge, Seungha Yang, Sjoerd Simons, Snir Sheriber, Song Bing, Soon, -Thean Siew, Sreerenj Balachandran, Stefan Ringel, Stephane Cerveau, -Stian Selnes, Suhas Nayak, Takeshi Sato, Thiago Santos, Thibault -Saunier, Thomas Bluemel, Tianhao Liu, Tim-Philipp Müller, Tomasz -Andrzejak, Tomislav Tustonić, U. Artie Eoff, Ulf Olsson, Varunkumar -Allagadapa, Víctor Guzmán, Víctor Manuel Jáquez Leal, Vincenzo Bono, -Vineeth T M, Vivia Nikolaidou, Wang Fei, wangzq, Whoopie, Wim Taymans, -Wind Yuan, Wonchul Lee, Xabier Rodriguez Calvar, Xavier Claessens, -Haihao Xiang, Yacine Bandou, Yeongjin Jeong, Yuji Kuwabara, Zeeshan Ali, +Ratté-Boulianne, Lucas Stach, Luis de Bethencourt, Luz Paz, Lyon Wang, +Maciej Wolny, Marc-André Lureau, Marc Leeman, Marco Trevisan (Treviño), +Marcos Kintschner, Marian Mihailescu, Marinus Schraal, Mark Nauwelaerts, +Marouen Ghodhbane, Martin Kelly, Matej Knopp, Mathieu Duponchelle, +Matteo Valdina, Matthew Waters, Matthias Fend, memeka, Michael Drake, +Michael Gruner, Michael Olbrich, Michael Tretter, Miguel Paris, Mike +Wey, Mikhail Fludkov, Naveen Cherukuri, Nicola Murino, Nicolas Dufresne, +Niels De Graef, Nirbheek Chauhan, Norbert Wesp, Ognyan Tonchev, Olivier +Crête, Omar Akkila, Pat DeSantis, Patricia Muscalu, Patrick Radizi, +Patrik Nilsson, Paul Kocialkowski, Per Forlin, Peter Körner, Peter +Seiderer, Petr Kulhavy, Philippe Normand, Philippe Renon, Philipp Zabel, +Pierre Labastie, Piotr Drąg, Roland Jon, Roman Sivriver, Roman Shpuntov, +Rosen Penev, Russel Winder, Sam Gigliotti, Santiago Carot-Nemesio, +Sean-Der, Sebastian Dröge, Seungha Yang, Shi Yan, Sjoerd Simons, Snir +Sheriber, Song Bing, Soon, Thean Siew, Sreerenj Balachandran, Stefan +Ringel, Stephane Cerveau, Stian Selnes, Suhas Nayak, Takeshi Sato, +Thiago Santos, Thibault Saunier, Thomas Bluemel, Tianhao Liu, +Tim-Philipp Müller, Tobias Ronge, Tomasz Andrzejak, Tomislav Tustonić, +U. Artie Eoff, Ulf Olsson, Varunkumar Allagadapa, Víctor Guzmán, Víctor +Manuel Jáquez Leal, Vincenzo Bono, Vineeth T M, Vivia Nikolaidou, Wang +Fei, wangzq, Whoopie, Wim Taymans, Wind Yuan, Wonchul Lee, Xabier +Rodriguez Calvar, Xavier Claessens, Haihao Xiang, Yacine Bandou, +Yeongjin Jeong, Yuji Kuwabara, Zeeshan Ali, … and many others who have contributed bug reports, translations, sent suggestions or helped testing. @@ -1234,7 +1247,7 @@ the git 1.16 branch, which is a stable branch. 1.16.0 -1.16.0 is scheduled to be released in March 2019. +1.16.0 is scheduled to be released in April 2019. Known Issues @@ -1269,6 +1282,7 @@ August/September. ------------------------------------------------------------------------ _These release notes have been prepared by Tim-Philipp Müller with_ -_contributions from Sebastian Dröge and Guillaume Desmottes._ +_contributions from Sebastian Dröge, Guillaume Desmottes and Matthew +Waters._ _License: CC BY-SA 4.0_ diff --git a/RELEASE b/RELEASE index 9879f0a966..040207484e 100644 --- a/RELEASE +++ b/RELEASE @@ -1,4 +1,4 @@ -This is GStreamer gstreamer-vaapi 1.15.2.1. +This is GStreamer gstreamer-vaapi 1.15.90. GStreamer 1.15 is the development branch leading up to the next major stable version which will be 1.16. diff --git a/configure.ac b/configure.ac index fe2d30b214..cc1f89e8b3 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) m4_define([gst_vaapi_minor_version], [15]) -m4_define([gst_vaapi_micro_version], [2]) -m4_define([gst_vaapi_nano_version], [1]) +m4_define([gst_vaapi_micro_version], [90]) +m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1502]) +m4_define([gst_vaapi_lt_current], [1590]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1502]) +m4_define([gst_vaapi_lt_age], [1590]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.15.2.1]) -m4_define([gst_plugins_base_version], [1.15.2.1]) -m4_define([gst_plugins_bad_version], [1.15.2.1]) +m4_define([gst_version], [1.15.90]) +m4_define([gst_plugins_base_version], [1.15.90]) +m4_define([gst_plugins_bad_version], [1.15.90]) # Wayland minimum version number m4_define([wayland_api_version], [1.11.0]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 8477c7dfd4..e2eb8152ee 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.15.90 + master + + 2019-04-11 + + + + 1.15.2 diff --git a/meson.build b/meson.build index d4876a280d..954c1411b4 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.15.2.1', + version : '1.15.90', meson_version : '>= 0.47.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 39e2fe11ed4a81b286445c58c37ef306a5e42f2f Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Wed, 10 Apr 2019 11:43:33 -0700 Subject: [PATCH 3235/3781] libs: encoder: h265: fill tier in va seq param buf Now that tier is calculated in commit 58e74f9440fe (!68), ensure we fill in the general_tier_flag in the VAEncSequenceParameterBufferHEVC. --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 52d74f5a6f..665beebaba 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1511,9 +1511,7 @@ fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) seq_param->general_profile_idc = encoder->profile_idc; seq_param->general_level_idc = encoder->level_idc; - seq_param->general_tier_flag = 0; /* FIXME: use the tier flag - * extracted from upstream - * caps or calcuted one */ + seq_param->general_tier_flag = encoder->tier; seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); seq_param->intra_idr_period = encoder->idr_period; From e88f349c6fd41b8e7f62d94a3fa5233f78972483 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Thu, 11 Apr 2019 15:05:02 +0800 Subject: [PATCH 3236/3781] plugins: find the preferred format from right caps. When the downstream has any caps, then raw video feature will be used. At this situation, the preferred format should be chose from caps which contains "vide/x-raw" feature instead of from the fist allowed caps. Fixes #142 --- gst/vaapi/gstvaapipluginutil.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 51fdf12e5a..3599b6a063 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -698,17 +698,28 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstCaps * allowed_caps, find_format: if (out_format_ptr) { GstVideoFormat out_format; - GstStructure *structure; + GstStructure *structure = NULL; const GValue *format_list; + GstCapsFeatures *features; - /* if the best feature is SystemMemory, we should use the first - * caps in the filtered peer caps set, which is the preferred by - * downstream. */ - if (feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) + /* if the best feature is SystemMemory, we should choose the + * vidoe/x-raw caps in the filtered peer caps set. If not, use + * the first caps, which is the preferred by downstream. */ + if (feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) { gst_caps_replace (&caps, out_caps); - - /* use the first caps, which is the preferred by downstream. */ - structure = gst_caps_get_structure (caps, 0); + num_structures = gst_caps_get_size (caps); + for (i = 0; i < num_structures; i++) { + structure = gst_caps_get_structure (caps, i); + features = gst_caps_get_features (caps, i); + if (!gst_caps_features_is_any (features) + && gst_caps_features_contains (features, + gst_vaapi_caps_feature_to_string + (GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY))) + break; + } + } else { + structure = gst_caps_get_structure (caps, 0); + } if (!structure) goto cleanup; format_list = gst_structure_get_value (structure, "format"); From 7c0ec687cd29d9c04ec7df929b8e47dbe8b0f1c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 Apr 2019 13:54:15 +0200 Subject: [PATCH 3237/3781] libs: utils: use glib's macros Don't reinvent the wheel. --- gst-libs/gst/vaapi/gstvaapiutils.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 5fb974fefb..6b60395530 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -34,12 +34,8 @@ #define DEBUG 1 #include "gstvaapidebug.h" -#define CONCAT(a, b) CONCAT_(a, b) -#define CONCAT_(a, b) a##b -#define STRINGIFY(x) STRINGIFY_(x) -#define STRINGIFY_(x) #x -#define STRCASEP(p, x) STRCASE(CONCAT(p, x)) -#define STRCASE(x) case x: return STRINGIFY(x) +#define STRCASEP(p, x) STRCASE(G_PASTE(p, x)) +#define STRCASE(x) case x: return G_STRINGIFY(x) #if VA_CHECK_VERSION (0,40,0) static gchar * From 3c86fd12cb9c1199a07edde283f2ea4d0b947a93 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 15 Apr 2019 13:55:26 +0200 Subject: [PATCH 3238/3781] libs: utils: avoid macro evaluation when stringify string_of_va_chroma_format() gets a wrong string format description. For example, the YUV420_10BPP get a string of 0x00000100 as output. It's because VA_RT_FORMAT_xxx values are macro definitions. And STRINGIFY(VA_RT_FORMAT_xxx) will expand to its real value 0x00000XXX. To avoid the macro evaluation, it is changed to show only the color format without VA_RT_FORMAT_ prefix. --- gst-libs/gst/vaapi/gstvaapiutils.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 6b60395530..7f9b9caeee 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -34,9 +34,13 @@ #define DEBUG 1 #include "gstvaapidebug.h" +/* string case an enum */ #define STRCASEP(p, x) STRCASE(G_PASTE(p, x)) #define STRCASE(x) case x: return G_STRINGIFY(x) +/* string case a macro */ +#define STRCASEM(p, x) case G_PASTE(p, x): return G_STRINGIFY(x) + #if VA_CHECK_VERSION (0,40,0) static gchar * strip_msg (const char *message) @@ -294,7 +298,7 @@ string_of_va_chroma_format (guint chroma_format) { switch (chroma_format) { #define MAP(value) \ - STRCASEP(VA_RT_FORMAT_, value) + STRCASEM(VA_RT_FORMAT_, value) MAP (YUV420); MAP (YUV422); MAP (YUV444); From 43542a50ab9c0f8d50f029f87ab04ec3f172a558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 10 Apr 2019 13:25:10 +0200 Subject: [PATCH 3239/3781] build: configure: disable GLX if libva-x11 is not found --- configure.ac | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index cc1f89e8b3..fafcf134e8 100644 --- a/configure.ac +++ b/configure.ac @@ -522,7 +522,10 @@ fi dnl VA/X11 API if test $USE_X11 -eq 1; then PKG_CHECK_MODULES(LIBVA_X11, [libva-x11 >= $VAAPI_REQ], - [], [USE_X11=0]) + [], [ + USE_X11=0 + USE_GLX=0 + ]) fi dnl Check for encoding support From d506dacc6b2ee8f7aab67aa6fd6e1b90e5830679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 10 Apr 2019 13:59:05 +0200 Subject: [PATCH 3240/3781] build: configure: delay USE_GTK conditional until check libva-x11 libva-x11 is used for X11 applications, so it is required to build any GTK application. Later, when Wayland test is added, we should change this. --- configure.ac | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index fafcf134e8..2e4c179aff 100644 --- a/configure.ac +++ b/configure.ac @@ -495,7 +495,7 @@ AS_IF([test $USE_GTK -eq 1], AC_CHECK_HEADERS([gtk/gtk.h], [], [USE_GTK=0]) CPPFLAGS="$saved_CPPFLAGS" ]) -AM_CONDITIONAL([USE_GTK], [test $USE_GTK -eq 1]) +dnl USE_GTK conditional is delayed after being sure to handle X11 dnl --------------------------------------------------------------------------- dnl -- VA-API -- @@ -528,6 +528,9 @@ if test $USE_X11 -eq 1; then ]) fi +dnl export USE_GTK after being sure to handle X11 +AM_CONDITIONAL([USE_GTK], [test $USE_X11 -eq 1 -a $USE_GTK -eq 1]) + dnl Check for encoding support USE_ENCODERS=0 if test "x$enable_encoders" = "xyes"; then From c0485943701176f201cf45d9dea80903f56ee467 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 8 Apr 2019 18:29:35 +0800 Subject: [PATCH 3241/3781] libs: Add RGB565 image format support. --- gst-libs/gst/vaapi/gstvaapiimage.c | 1 + gst-libs/gst/vaapi/video-format.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 581b5d9077..c9198301c9 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -77,6 +77,7 @@ vaapi_image_is_linear (const VAImage * va_image) break; case VA_FOURCC ('Y', 'U', 'Y', '2'): case VA_FOURCC ('U', 'Y', 'V', 'Y'): + case VA_FOURCC ('R', 'G', '1', '6'): data_size = 2 * width * height; break; case VA_FOURCC ('Y', '8', '0', '0'): diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index a2394fa7cf..3238d2531c 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -86,6 +86,8 @@ static const GstVideoFormatMap gst_vaapi_video_formats[] = { 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), DEF_RGB (RGBx, ('R', 'G', 'B', 'X'), 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), + DEF_RGB (RGB16, ('R', 'G', '1', '6'), 16, + 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000), {0,} }; /* *INDENT-ON* */ From 029bb3e504d6f89f2517007129b9d53a95f8f6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 Apr 2019 19:34:05 +0200 Subject: [PATCH 3242/3781] libs: encoder: h264,h265: guard VA version for max_qp property This patch fixes a regression from commit 5b1fe9c6. max_qp, in rate control configuration, appeared in libva release 2.1 (API 1.1), thus it is required to guard the VA API version. Fixes: #150 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 4 ++++ gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 3 +++ 3 files changed, 10 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index b87f420e83..10c407bc52 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2519,10 +2519,13 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; + +#if VA_CHECK_VERSION(1,1,0) /* @FIXME: should not set this value, should be ignored if set to zero * * https://github.com/intel/media-driver/issues/587 */ if (encoder->min_qp > 0) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).max_qp = 51; +#endif #if VA_CHECK_VERSION(1,0,0) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).rc_flags.bits.mb_rate_control = diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index 7bb95200b9..9115281980 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -2449,10 +2449,14 @@ ensure_misc_params (GstVaapiEncoderH264Fei * encoder, rate_control->window_size = encoder->cpb_length; rate_control->initial_qp = encoder->init_qp; rate_control->min_qp = encoder->min_qp; + +#if VA_CHECK_VERSION(1,1,0) /* @FIXME: should not set this value, should be ignored if set to zero * * https://github.com/intel/media-driver/issues/587 */ if (rate_control->min_qp > 0) rate_control->max_qp = 51; +#endif + rate_control->basic_unit_size = 0; gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 665beebaba..01425523f8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1865,10 +1865,13 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; + +#if VA_CHECK_VERSION(1,1,0) /* @FIXME: should not set this value, should be ignored if set to zero * * https://github.com/intel/media-driver/issues/587 */ if (encoder->min_qp > 0) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).max_qp = 51; +#endif #if VA_CHECK_VERSION(1,0,0) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).rc_flags.bits.mb_rate_control = From a9c4a4b9cef2e81b963b9e30ca9cf3b0386292d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 19 Apr 2019 00:38:12 +0100 Subject: [PATCH 3243/3781] Update docs --- docs/plugins/inspect/plugin-vaapi.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/inspect/plugin-vaapi.xml b/docs/plugins/inspect/plugin-vaapi.xml index 4b85e42a13..3f87472348 100644 --- a/docs/plugins/inspect/plugin-vaapi.xml +++ b/docs/plugins/inspect/plugin-vaapi.xml @@ -3,7 +3,7 @@ VA-API based elements ../../gst/vaapi/.libs/libgstvaapi.so libgstvaapi.so - 1.15.90 + 1.16.0 LGPL gstreamer-vaapi gstreamer-vaapi From 2c3480796a6673c638f5b12c7bdf5c0f191120fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 19 Apr 2019 00:38:12 +0100 Subject: [PATCH 3244/3781] Release 1.16.0 --- ChangeLog | 83 ++++++++++++++ NEWS | 262 ++++++++++++++++++++++++++++++------------- RELEASE | 11 +- configure.ac | 14 +-- gstreamer-vaapi.doap | 10 ++ meson.build | 2 +- 6 files changed, 291 insertions(+), 91 deletions(-) diff --git a/ChangeLog b/ChangeLog index e11f75adf2..1088902823 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,86 @@ +=== release 1.16.0 === + +2019-04-19 00:38:12 +0100 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * RELEASE: + * configure.ac: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.16.0 + +2019-04-19 00:38:12 +0100 Tim-Philipp Müller + + * docs/plugins/inspect/plugin-vaapi.xml: + Update docs + +2019-04-15 19:34:05 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h264,h265: guard VA version for max_qp property + This patch fixes a regression from commit 5b1fe9c6. + max_qp, in rate control configuration, appeared in libva release + 2.1 (API 1.1), thus it is required to guard the VA API version. + Fixes: #150 + +2019-04-08 18:29:35 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/video-format.c: + libs: Add RGB565 image format support. + +2019-04-10 13:59:05 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + build: configure: delay USE_GTK conditional until check libva-x11 + libva-x11 is used for X11 applications, so it is required to build + any GTK application. + Later, when Wayland test is added, we should change this. + +2019-04-10 13:25:10 +0200 Víctor Manuel Jáquez Leal + + * configure.ac: + build: configure: disable GLX if libva-x11 is not found + +2019-04-15 13:55:26 +0200 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: avoid macro evaluation when stringify + string_of_va_chroma_format() gets a wrong string format description. + For example, the YUV420_10BPP get a string of 0x00000100 as output. + It's because VA_RT_FORMAT_xxx values are macro definitions. And + STRINGIFY(VA_RT_FORMAT_xxx) will expand to its real value + 0x00000XXX. + To avoid the macro evaluation, it is changed to show only the color + format without VA_RT_FORMAT_ prefix. + +2019-04-15 13:54:15 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: use glib's macros + Don't reinvent the wheel. + +2019-04-11 15:05:02 +0800 Wangfei + + * gst/vaapi/gstvaapipluginutil.c: + plugins: find the preferred format from right caps. + When the downstream has any caps, then raw video feature will + be used. At this situation, the preferred format should be chose + from caps which contains "vide/x-raw" feature instead of from + the fist allowed caps. + Fixes #142 + +2019-04-10 11:43:33 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: fill tier in va seq param buf + Now that tier is calculated in commit 58e74f9440fe (!68), + ensure we fill in the general_tier_flag in the + VAEncSequenceParameterBufferHEVC. + === release 1.15.90 === 2019-04-11 00:40:03 +0100 Tim-Philipp Müller diff --git a/NEWS b/NEWS index 16402a590e..816a3aae85 100644 --- a/NEWS +++ b/NEWS @@ -3,19 +3,12 @@ GSTREAMER 1.16 RELEASE NOTES -GStreamer 1.16 has not been released yet. It is scheduled for release in -April 2019. - -1.15.x is the unstable development version that is being developed in -the git master branch and which will eventually result in 1.16. - -1.16 will be backwards-compatible to the stable 1.14, 1.12, 1.10, 1.8, -1.6, 1.4, 1.2 and 1.0 release series. +GStreamer 1.16.0 was originally released on 19 April 2019. See https://gstreamer.freedesktop.org/releases/1.16/ for the latest version of this document. -_Last updated: Wednesday 10 April 2019, 00:50 UTC (log)_ +_Last updated: Friday 19 April 2019, 00:00 UTC (log)_ Introduction @@ -76,6 +69,10 @@ Highlights - The GStreamer Rust bindings and Rust plugins module are now officially part of upstream GStreamer. +- The GStreamer Editing Services gained a gesdemux element that allows + directly playing back serialized edit list with playbin or + (uri)decodebin + - Many performance improvements @@ -208,7 +205,8 @@ this new infrastructure and provides the following elements: - ccconverter: a closed caption converter that can convert between different formats -- line21decoder: extract line21 closed captions from SD video streams +- line21encoder, line21decoder: inject/extract line21 closed captions + to/from SD video streams - cc708overlay: decodes CEA 608/708 captions and overlays them on video @@ -218,7 +216,11 @@ support: - qtdemux and qtmux support CEA 608/708 Closed Caption tracks -- mpegvideoparse extracts Closed Captions from MPEG-2 video streams +- mpegvideoparse, h264parse extracts Closed Captions from MPEG-2/H.264 + video streams + +- avviddec, avvidenc, x264enc got support for extracting/injecting + Closed Captions - decklinkvideosink can output closed captions and decklinkvideosrc can extract closed captions @@ -265,7 +267,7 @@ New Elements or uridecodebin3 etc. - New closed caption elements: cccombiner, ccextractor, ccconverter, - line21decoder and cc708overlay (see above) + line21encoder, line21decoder and cc708overlay (see above) - wpesrc: new source element acting as a Web Browser based on WebKit WPE @@ -402,6 +404,9 @@ New element features and additions - srtpdec, srtpenc: add support for MKIs which allow multiple keys to be used with a single SRTP stream +- srtpdec, srtpenc: add support for AES-GCM and also add support for + it in gst-rtsp-server and rtspsrc. + - The srt Secure Reliable Transport plugin has integrated server and client elements srt{client,server}{src,sink} into one (srtsrc and srtsink), since SRT connection mode can be changed by uri @@ -434,7 +439,24 @@ New element features and additions "connector-properties" can be used to pass custom properties to the DRM. -- waylandsink has a "fullscreen" property now. +- waylandsink has a "fullscreen" property now and supports the + XDG-Shell protocol. + +- decklinkvideosink, decklinkvideosrc support selecting between + half/full duplex + +- The vulkan plugin gained support for macOS and iOS via MoltenVK in + addition to the existing support for X11 and Wayland + +- imagefreeze has a new num-buffers property to limit the number of + buffers that are produced and to send an EOS event afterwards + +- webrtcbin has a new, introspectable get-transceiver signal in + addition to the old get-transceivers signal that couldn’t be used + from bindings + +- Support for per-element latency information was added to the latency + tracer Plugin and library moves @@ -574,6 +596,18 @@ Miscellaneous API additions - gst_audio_buffer_truncate() convenience function to truncate a raw audio buffer +- GstDiscoverer has support for caching the results of discovery in + the default cache directory. This can be enabled with the use-cache + property and is disabled by default. + +- GstMeta that are attached to GstBuffers are now always stored in the + order in which they were added. + +- Additional support for signalling ONVIF specific features were + added: the SEEK event can store a trickmode-interval now and support + for the Rate-Control and Frames RTSP headers was added to the RTSP + library. + Miscellaneous performance and memory optimisations @@ -677,49 +711,6 @@ Tracing framework and debugging improvements object. This is currently limited to pads for GstElements and events for the pads. The output may look like this: - (gdb) gst-print pad.object.parent - GstMatroskaDemux (matroskademux0) { - SinkPad (sink, pull) { - } - SrcPad (video_0, push) { - events: - stream-start: - stream-id: 0463ccb080d00b8689bf569a435c4ff84f9ff753545318ae2328ea0763fd0bec/001:1274058367 - caps: video/x-theora - width: 1920 - height: 800 - pixel-aspect-ratio: 1/1 - framerate: 24/1 - streamheader: < 0x5555557c7d30 [GstBuffer], 0x5555557c7e40 [GstBuffer], 0x7fffe00141d0 [GstBuffer] > - segment: time - rate: 1 - tag: global - container-format: Matroska - } - SrcPad (audio_0, push) { - events: - stream-start: - stream-id: 0463ccb080d00b8689bf569a435c4ff84f9ff753545318ae2328ea0763fd0bec/002:1551204875 - caps: audio/mpeg - mpegversion: 4 - framed: true - stream-format: raw - codec_data: 0x7fffe0014500 [GstBuffer] - level: 2 - base-profile: lc - profile: lc - channels: 2 - rate: 44100 - segment: time - rate: 1 - tag: global - container-format: Matroska - tag: stream - audio-codec: MPEG-4 AAC audio - language-code: en - } - } - - gst_structure_to_string() now serialises the actual value of pointers when serialising GstStructures instead of claiming they’re NULL. This makes debug logging in various places less confusing, @@ -761,7 +752,35 @@ GStreamer RTSP server GStreamer VAAPI -- this section will be filled in in due course +- Support Wayland’s display for context sharing, so the application + can pass its own wl_display in order to be used for the VAAPI + display creation. + +- A lot of work to support new Intel hardware using media-driver as VA + backend. + +- For non-x86 devices, VAAPI display can instantiate, through DRM, + with no PCI bus. This enables the usage of libva-v4l2-request + driver. + +- Added support for XDG-shell protocol as wl_shell replacement which + is currently deprecated. This change add as dependency + wayland-protocol. + +- GstVaapiFilter, GstVaapiWindow, and GstVaapiDecoder classes now + inherit from GstObject, gaining all the GStreamer’s instrumentation + support. + +- The metadata now specifies the plugin as Hardware class. + +- H264 decoder is more stable with problematic streams. + +- In H265 decoder added support for profiles main-422-10 (P010_10LE), + main-444 (AYUV) and main-444-10 (Y410) + +- JPEG decoder handles dynamic resolution changes. + +- More specification adherence in H264 and H265 encoders. GStreamer OMX @@ -789,12 +808,111 @@ GStreamer OMX GStreamer Editing Services and NLE -- this section will be filled in in due course +- Added a gesdemux element, it is an auto pluggable element that + allows decoding edit list like files supported by GES + +- Added gessrc which wraps a GESTimeline as a standard source element + (implementing the ges protocol handler) + +- Added basic support for videorate::rate property potentially + allowing changing playback speed + +- Layer priority is now fully automatic and they should be moved with + the new ges_timeline_move_layer method, ges_layer_set_priority is + now deprecated. + +- Added a ges_timeline_element_get_layer_priority so we can simply get + all information about GESTimelineElement position in the timeline + +- GESVideoSource now auto orientates the images if it is defined in a + meta (overridable). + +- Added some PyGObject overrides to make the API more pythonic + +- The threading model has been made more explicit with safe guard to + make sure not thread safe APIs are not used from the wrong threads. + It is also now possible to properly handle in what thread the API + should be used. + +- Optimized GESClip and GESTrackElement creation + +- Added a way to compile out the old, unused and deprecated + GESPitiviFormatter + +- Re implemented the timeline editing API making it faster and making + the code much more maintainable + +- Simplified usage of nlecomposition outside GES by removing quirks in + it API usage and removing the need to treat it specially from an + application perspective. + +- ges-launch-1.0: + + - Added support to add titles to the timeline + - Enhance the help auto generating it from the code + +- Deprecate ges_timeline_load_from_uri as loading the timeline should + be done through a project now + +- MANY leaks have been plugged and the unit testsuite is now “leak + free” GStreamer validate -- this section will be filled in in due course +- Added an action type to verify the checksum of the sink last-sample + +- Added an include keyword to validate scenarios + +- Added the notion of variable in scenarios, with the set-vars keyword + +- Started adding support for “performance” like tests by allowing to + define the number of dropped buffers or the minimum buffer frequency + on a specific pad + +- Added a validateflow plugin which allows defining the data flow to + be seen on a particular pad and verifying that following runs match + the expectations + +- Added support for appsrc based test definition so we can instrument + the data pushed into the pipeline from scenarios + +- Added a mockdecryptor allowing adding tests with on encrypted files, + the element will potentially be instrumented with a validate + scenario + +- gst-validate-launcher: + + - Cleaned up output + + - Changed the default for “muting” tests as user doesn’t expect + hundreds of windows to show up when running the testsuite + + - Fixed the outputted xunit files to be compatible with GitLab + + - Added support to run tests on media files in push mode (using + pushfile://) + + - Added support for running inside gst-build + + - Added support for running ssim tests on rendered files + + - Added a way to simply define tests on pipelines through a simple + .json file + + - Added a python app to easily run python testsuite reusing all + the launcher features + + - Added flatpak knowledge so we can print backtrace even when + running from within flatpak + + - Added a way to automatically generated “known issues” + suppressions lines + + - Added a way to rerun tests to check if they are flaky and added + a way to tolerate tests known to be flaky + + - Add a way to output html log files GStreamer Python Bindings @@ -1223,20 +1341,6 @@ Yeongjin Jeong, Yuji Kuwabara, Zeeshan Ali, suggestions or helped testing. -Bugs fixed in 1.16 - -- this section will be filled in in due course - -More than XXX bugs have been fixed during the development of 1.16. - -This list does not include issues that have been cherry-picked into the -stable 1.16 branch and fixed there as well, all fixes that ended up in -the 1.16 branch are also included in 1.16. - -This list also does not include issues that have been fixed without a -bug report in bugzilla, so the actual number of fixes is much higher. - - Stable 1.16 branch After the 1.16.0 release there will be several 1.16.x bug-fix releases @@ -1247,7 +1351,7 @@ the git 1.16 branch, which is a stable branch. 1.16.0 -1.16.0 is scheduled to be released in April 2019. +1.16.0 was released on 19 April 2019. Known Issues @@ -1272,9 +1376,9 @@ unstable development version leading up to the stable 1.18 release. The development of 1.17/1.18 will happen in the git master branch. The plan for the 1.18 development cycle is yet to be confirmed, but it -is expected that feature freeze will be around July 2019 followed by -several 1.17 pre-releases and the new 1.18 stable release in -August/September. +is possible that the next cycle will be a short one in which case +feature freeze would be perhaps around August 2019 with a new 1.18 +stable release in September. 1.18 will be backwards-compatible to the stable 1.16, 1.14, 1.12, 1.10, 1.8, 1.6, 1.4, 1.2 and 1.0 release series. @@ -1282,7 +1386,7 @@ August/September. ------------------------------------------------------------------------ _These release notes have been prepared by Tim-Philipp Müller with_ -_contributions from Sebastian Dröge, Guillaume Desmottes and Matthew -Waters._ +_contributions from Sebastian Dröge, Guillaume Desmottes, Matthew +Waters, _ _Thibault Saunier, and Víctor Manuel Jáquez Leal._ _License: CC BY-SA 4.0_ diff --git a/RELEASE b/RELEASE index 040207484e..af9925f87d 100644 --- a/RELEASE +++ b/RELEASE @@ -1,9 +1,12 @@ -This is GStreamer gstreamer-vaapi 1.15.90. +This is GStreamer gstreamer-vaapi 1.16.0. -GStreamer 1.15 is the development branch leading up to the next major -stable version which will be 1.16. +The GStreamer team is thrilled to announce a new major feature release in the +stable 1.0 API series of your favourite cross-platform multimedia framework! -The 1.15 development series adds new features on top of the 1.14 series and is +As always, this release is again packed with new features, bug fixes and +other improvements. + +The 1.16 release series adds new features on top of the 1.14 series and is part of the API and ABI-stable 1.x release series of the GStreamer multimedia framework. diff --git a/configure.ac b/configure.ac index 2e4c179aff..d76134bc51 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [15]) -m4_define([gst_vaapi_micro_version], [90]) +m4_define([gst_vaapi_minor_version], [16]) +m4_define([gst_vaapi_micro_version], [0]) m4_define([gst_vaapi_nano_version], [0]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1590]) +m4_define([gst_vaapi_lt_current], [1600]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1590]) +m4_define([gst_vaapi_lt_age], [1600]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.15.90]) -m4_define([gst_plugins_base_version], [1.15.90]) -m4_define([gst_plugins_bad_version], [1.15.90]) +m4_define([gst_version], [1.16.0]) +m4_define([gst_plugins_base_version], [1.16.0]) +m4_define([gst_plugins_bad_version], [1.16.0]) # Wayland minimum version number m4_define([wayland_api_version], [1.11.0]) diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index e2eb8152ee..a4b046f540 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.16.0 + master + + 2019-04-19 + + + + 1.15.90 diff --git a/meson.build b/meson.build index 954c1411b4..b1015d091f 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.15.90', + version : '1.16.0', meson_version : '>= 0.47.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 0e83a2ae57f4858c4da232b556419e9decbf44a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 19 Apr 2019 10:43:35 +0100 Subject: [PATCH 3245/3781] Back to development --- RELEASE | 2 +- configure.ac | 14 +++++++------- docs/plugins/inspect/plugin-vaapi.xml | 2 +- meson.build | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/RELEASE b/RELEASE index af9925f87d..ff7af00d86 100644 --- a/RELEASE +++ b/RELEASE @@ -1,4 +1,4 @@ -This is GStreamer gstreamer-vaapi 1.16.0. +This is GStreamer gstreamer-vaapi 1.17.0.1. The GStreamer team is thrilled to announce a new major feature release in the stable 1.0 API series of your favourite cross-platform multimedia framework! diff --git a/configure.ac b/configure.ac index d76134bc51..a0f208bdfd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # gstreamer-vaapi package version number m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [16]) +m4_define([gst_vaapi_minor_version], [17]) m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [0]) +m4_define([gst_vaapi_nano_version], [1]) m4_define([gst_vaapi_version], [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) m4_if(gst_vaapi_nano_version, [0], [], @@ -16,17 +16,17 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 # gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1600]) +m4_define([gst_vaapi_lt_current], [1700]) m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1600]) +m4_define([gst_vaapi_lt_age], [1700]) # glib version number m4_define([glib_version], [2.40]) # gstreamer version number -m4_define([gst_version], [1.16.0]) -m4_define([gst_plugins_base_version], [1.16.0]) -m4_define([gst_plugins_bad_version], [1.16.0]) +m4_define([gst_version], [1.17.0.1]) +m4_define([gst_plugins_base_version], [1.17.0.1]) +m4_define([gst_plugins_bad_version], [1.17.0.1]) # Wayland minimum version number m4_define([wayland_api_version], [1.11.0]) diff --git a/docs/plugins/inspect/plugin-vaapi.xml b/docs/plugins/inspect/plugin-vaapi.xml index 3f87472348..c342f1608b 100644 --- a/docs/plugins/inspect/plugin-vaapi.xml +++ b/docs/plugins/inspect/plugin-vaapi.xml @@ -3,7 +3,7 @@ VA-API based elements ../../gst/vaapi/.libs/libgstvaapi.so libgstvaapi.so - 1.16.0 + 1.17.0.1 LGPL gstreamer-vaapi gstreamer-vaapi diff --git a/meson.build b/meson.build index b1015d091f..b23d25a654 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.16.0', + version : '1.17.0.1', meson_version : '>= 0.47.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From a3ce4446c1687537ff2c98effdeb513614e961ec Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 29 Apr 2019 20:10:39 +0800 Subject: [PATCH 3246/3781] libs: h264encoder: fix a typo of GstVaapiEncoderH264PredictionType --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 10c407bc52..d49886a85e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -111,7 +111,7 @@ typedef enum GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT, GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_P, GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B -} GstVaapiEnoderH264PredictionType; +} GstVaapiEncoderH264PredictionType; static GType gst_vaapi_encoder_h264_prediction_type (void) From aa37f31d54599ab23b2851bfe594edcc0964ea19 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Fri, 19 Apr 2019 15:49:37 -0700 Subject: [PATCH 3247/3781] libs: surface: fix double free when dmabuf export fails Happens if vaAcquireBufferHandle fails. --- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index 8c0f8f93b2..cbd7d71773 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -36,6 +36,7 @@ gst_vaapi_surface_get_drm_buf_handle (GstVaapiSurface * surface, guint type) if (!image) goto error_derive_image; + /* The proxy takes ownership if the image, even creation failure. */ proxy = gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), image->internal_image.buf, type, gst_vaapi_object_unref, image); @@ -52,7 +53,6 @@ error_derive_image: error_alloc_export_buffer: { GST_ERROR ("failed to allocate export buffer proxy"); - gst_vaapi_object_unref (image); return NULL; } } From 838045b9e2d3b14e4dc95270ba8e86025f5cf3f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 2 May 2019 16:00:57 +0200 Subject: [PATCH 3248/3781] vaapipostproc: don't do any color conversion when GL_TEXTURE_UPLOAD https://bugzilla.gnome.org/show_bug.cgi?id=748184 has resurrected with commit 3e992d8a Since gst_vaapi_find_preferred_caps_feature() returns a color format from caps negotiation, different from the default one (NV12), the postproc enables the color transformation. But when GL_TEXTURE_UPLOAD feature is negotiated, no color transformation shall be done. Nonetheless, with commit 3e992d8a the requested format changes firstly, because there's no video sink yet, so ANY caps are negotiated; but later, when there's a video sink and a caps renegotiation, the GL_TEXTURE_UPLOAD is negotiated though the color format conversion still ongoing. It is required to reset that conversion. This patch force default color format when GL_TEXTURE_UPLOAD is selected as preferred, thus avoiding the color conversion. Fixes: #157 --- gst/vaapi/gstvaapipostprocutil.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 1cdc5c4970..2b34196b90 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -709,9 +709,11 @@ _get_preferred_caps (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, /* we don't need to do format conversion if GL_TEXTURE_UPLOAD_META * is negotiated */ - if (f != GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META - && postproc->format != format) + if (f == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) { + postproc->format = DEFAULT_FORMAT; + } else if (postproc->format != format) { postproc->format = format; + } return outcaps; From 9c1f3ad172d0f02ff92e3301b83b01eb77d17882 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 15 Apr 2019 19:58:14 +0800 Subject: [PATCH 3249/3781] lib: decoder: vp9: Set chroma_type by VP9 bit_depth The decoder's surface chroma type should depend on the bit depth of VP9's parser. For 10bits VP9 stream, we need to use P10LE kind 10 bits surface as the decoder result. Fixes #155 --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 2466b7bb74..f164c8c696 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -220,7 +220,16 @@ ensure_context (GstVaapiDecoderVp9 * decoder) info.profile = priv->profile; info.entrypoint = entrypoint; - info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + if (priv->parser->bit_depth == GST_VP9_BIT_DEPTH_8) { + info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; + } else if (priv->parser->bit_depth == GST_VP9_BIT_DEPTH_10) { + info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; + } else { + GST_WARNING ("VP9 with depth %d, bigger than 10BPP not supported now", + priv->parser->bit_depth); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; + } + info.width = priv->width; info.height = priv->height; info.ref_frames = 8; From 2541a33d6c3fccc4bf0f3bcb09dcb28062280dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 3 May 2019 10:31:52 +0200 Subject: [PATCH 3250/3781] libs: encoder: continue if roi meta is NULL Coverity scan bug: If the function actually returns a null value, a null pointer dereference will occur. In gst_vaapi_encoder_ensure_param_roi_regions(): Return value of function which returns null is dereferenced without checking --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 62f4099a66..59f3cb6edf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -329,6 +329,8 @@ gst_vaapi_encoder_ensure_param_roi_regions (GstVaapiEncoder * encoder, roi = (GstVideoRegionOfInterestMeta *) gst_buffer_iterate_meta_filtered (input, &state, GST_VIDEO_REGION_OF_INTEREST_META_API_TYPE); + if (!roi) + continue; /* ignore roi if overflow */ if ((roi->x > G_MAXINT16) || (roi->y > G_MAXINT16) From 2ee518a988018284099c17ef85554a012e46e182 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Fri, 15 Mar 2019 14:29:41 +0800 Subject: [PATCH 3251/3781] vaapiencode: handle DMABuf caps feature in sink pad Add DMABuff caps features in all encoders' sink pad. --- gst/vaapi/gstvaapiencode.c | 3 ++- gst/vaapi/gstvaapiencode_h264.c | 2 ++ gst/vaapi/gstvaapiencode_h264_fei.c | 2 ++ gst/vaapi/gstvaapiencode_h265.c | 2 ++ gst/vaapi/gstvaapiencode_jpeg.c | 2 ++ gst/vaapi/gstvaapiencode_mpeg2.c | 2 ++ gst/vaapi/gstvaapiencode_vp8.c | 2 ++ gst/vaapi/gstvaapiencode_vp9.c | 2 ++ 8 files changed, 16 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index b64233ff2b..af8c77a484 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -379,7 +379,8 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) if (!encode->encoder) return TRUE; - out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS); + out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS ";" + GST_VAAPI_MAKE_DMABUF_CAPS); if (!out_caps) goto failed_create_va_caps; diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 856afd611a..ed19c409a3 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -84,6 +84,8 @@ static const char gst_vaapiencode_h264_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE ";" + GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_h264_fei.c b/gst/vaapi/gstvaapiencode_h264_fei.c index 5aa448319b..caf68b3899 100644 --- a/gst/vaapi/gstvaapiencode_h264_fei.c +++ b/gst/vaapi/gstvaapiencode_h264_fei.c @@ -64,6 +64,8 @@ static const char gst_vaapiencode_h264_fei_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE ";" + GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 6a9b796f5f..268f404d64 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -58,6 +58,8 @@ static const char gst_vaapiencode_h265_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE ";" + GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index cf1ea6bcda..81da4c738b 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -55,6 +55,8 @@ static const char gst_vaapiencode_jpeg_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE ";" + GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 32bc346e3e..3622bbea59 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -57,6 +57,8 @@ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE ";" + GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index cb040f7137..fcaffbb812 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -55,6 +55,8 @@ static const char gst_vaapiencode_vp8_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE ";" + GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index 43aff6dd56..7a69384ec4 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -55,6 +55,8 @@ static const char gst_vaapiencode_vp9_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_CAPS_INTERLACED_FALSE ";" + GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ From d38f0bbb1d9437acc9e751f1926edd870309796d Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 16 Apr 2019 18:33:54 +0800 Subject: [PATCH 3252/3781] libs: Add packed 24 RGB format support. Can not find a suitable chrome_type for this GST_VIDEO_FORMAT_RGB packed 24 format. Just use GST_VAAPI_CHROMA_TYPE_RGB32 as its chrome type. This kind of surface will just be created by new API with fourcc and no old style chrome based creation is available. fixes: #151 --- gst-libs/gst/vaapi/gstvaapiimage.c | 3 +++ gst-libs/gst/vaapi/video-format.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index c9198301c9..f5c3569b60 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -99,6 +99,9 @@ vaapi_image_is_linear (const VAImage * va_image) case VA_FOURCC ('P', '0', '1', '0'): data_size = 2 * (width * height + 2 * width2 * height2); break; + case VA_FOURCC ('R', 'G', '2', '4'): + data_size = 3 * width * height; + break; default: GST_ERROR ("FIXME: incomplete formats %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (va_image->format.fourcc)); diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 3238d2531c..db67cae472 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -88,6 +88,8 @@ static const GstVideoFormatMap gst_vaapi_video_formats[] = { 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), DEF_RGB (RGB16, ('R', 'G', '1', '6'), 16, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000), + DEF_RGB (RGB, ('R', 'G', '2', '4'), 32, + 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), {0,} }; /* *INDENT-ON* */ From a4e2db4c0bd1a81047c657e458cdbbf8cd2d6cd2 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Tue, 7 May 2019 11:03:51 +0800 Subject: [PATCH 3253/3781] libs: decoder: vp9: support 422/444 8bit/10bit chroma type. According to the vp9 sepc, profile 1/3 support 422/440/444 chroma type, so we need to add subsampling_x&subsampling_y to fix it. Here is the relationship between chroma type and profile and subsampling_x&subsampling_y according to vp9 spec: ------------------------------------------ Profile | Bit depth | Chroma subsampling | ------------------------------------------ 0 | 8 | 420 | ------------------------------------------ 1 | 8 | 422,440,444 | ------------------------------------------ 2 | 10, 12 | 420 | ------------------------------------------ 3 | 10, 12 | 422,440,444 | ------------------------------------------ ----------------------------------------------- Subsampling_x | Subsampling_y | Chroma format | ----------------------------------------------- 0 | 0 | 444 | ----------------------------------------------- 0 | 1 | 440 | ----------------------------------------------- 1 | 0 | 422 | ----------------------------------------------- 1 | 1 | 420 | ----------------------------------------------- --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 57 +++++++++++++++++++----- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index f164c8c696..b2a605c398 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -189,11 +189,55 @@ get_profile (guint profile_idc) 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; @@ -220,19 +264,12 @@ ensure_context (GstVaapiDecoderVp9 * decoder) info.profile = priv->profile; info.entrypoint = entrypoint; - if (priv->parser->bit_depth == GST_VP9_BIT_DEPTH_8) { - info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - } else if (priv->parser->bit_depth == GST_VP9_BIT_DEPTH_10) { - info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; - } else { - GST_WARNING ("VP9 with depth %d, bigger than 10BPP not supported now", - priv->parser->bit_depth); - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; - } - 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); From a1ae75b500b489c513758da81115888d8b80f538 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 May 2019 23:39:20 +0800 Subject: [PATCH 3254/3781] libs: encoder: Enable trellis quantization method. The advanced trellis algorithm is supported in VA driver. We add its support as a property named "trellis" of encoder. It only works for H264 now, should be more in future. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 100 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 7 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 3 + gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 6 ++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 8 ++ 5 files changed, 123 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 59f3cb6edf..ecea336f33 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -206,6 +206,21 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) "higher value means lower-quality)", -10, 10, -10, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiEncoder: trellis: + * + * The trellis quantization method the encoder can use. + * Trellis is an improved quantization algorithm. + * + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_PROP_TRELLIS, + g_param_spec_boolean ("trellis", + "Trellis Quantization", + "The Trellis Quantization Method of Encoder", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } @@ -273,6 +288,35 @@ gst_vaapi_encoder_ensure_param_control_rate (GstVaapiEncoder * encoder, return TRUE; } +gboolean +gst_vaapi_encoder_ensure_param_trellis (GstVaapiEncoder * encoder, + GstVaapiEncPicture * picture) +{ +#if VA_CHECK_VERSION(1,0,0) + GstVaapiEncMiscParam *misc; + VAEncMiscParameterQuantization *param; + + if (!encoder->trellis) + return TRUE; + + misc = GST_VAAPI_ENC_QUANTIZATION_MISC_PARAM_NEW (encoder); + if (!misc) + return FALSE; + if (!misc->data) + return FALSE; + + param = (VAEncMiscParameterQuantization *) misc->data; + param->quantization_flags.bits.disable_trellis = 0; + param->quantization_flags.bits.enable_trellis_I = 1; + param->quantization_flags.bits.enable_trellis_B = 1; + param->quantization_flags.bits.enable_trellis_P = 1; + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); +#endif + return TRUE; +} + gboolean gst_vaapi_encoder_ensure_param_roi_regions (GstVaapiEncoder * encoder, GstVaapiEncPicture * picture) @@ -1028,6 +1072,24 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder)); #endif + if (encoder->trellis) { +#if VA_CHECK_VERSION(1,0,0) + guint quantization_method = 0; + if (get_config_attribute (encoder, VAConfigAttribEncQuantization, + &quantization_method) == FALSE + || !(quantization_method & VA_ENC_QUANTIZATION_TRELLIS_SUPPORTED)) { + + GST_INFO ("Trellis Quantization is not supported," + " trellis will be disabled"); + encoder->trellis = FALSE; + } +#else + GST_INFO ("The encode trellis quantization option is not supported" + " in this VAAPI version."); + encoder->trellis = FALSE; +#endif + } + codedbuf_size = encoder->codedbuf_pool ? gst_vaapi_coded_buffer_pool_get_buffer_size (GST_VAAPI_CODED_BUFFER_POOL (encoder)) : 0; @@ -1152,6 +1214,10 @@ set_property (GstVaapiEncoder * encoder, gint prop_id, const GValue * value) encoder->default_roi_value = g_value_get_int (value); status = GST_VAAPI_ENCODER_STATUS_SUCCESS; break; + case GST_VAAPI_ENCODER_PROP_TRELLIS: + status = + gst_vaapi_encoder_set_trellis (encoder, g_value_get_boolean (value)); + break; } return status; @@ -1409,6 +1475,40 @@ error_operation_failed: } } +/** + * gst_vaapi_encoder_set_trellis: + * @encoder: a #GstVaapiEncoder + * @trellis: whether to use trellis quantization + * + * Notifies the @encoder to use the supplied @trellis option. + * + * Note: currently, the tuning option can only be specified before the + * last call to gst_vaapi_encoder_set_codec_state(), which shall occur + * before the first frame is encoded. Afterwards, any change to this + * parameter causes gst_vaapi_encoder_set_tuning() to return + * @GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED. + * + * Return value: a #GstVaapiEncoderStatus + */ +GstVaapiEncoderStatus +gst_vaapi_encoder_set_trellis (GstVaapiEncoder * encoder, gboolean trellis) +{ + g_return_val_if_fail (encoder != NULL, 0); + + if (encoder->trellis != trellis && encoder->num_codedbuf_queued > 0) + goto error_operation_failed; + + encoder->trellis = trellis; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +error_operation_failed: + { + GST_ERROR ("could not change trellis options after encoding started"); + return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; + } +} + /* Initialize default values for configurable properties */ static gboolean gst_vaapi_encoder_init_properties (GstVaapiEncoder * encoder) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 974a70a9b2..8f6e4135a5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -117,6 +117,7 @@ typedef enum { * @GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD: The maximal distance * between two keyframes (uint). * @GST_VAAPI_ENCODER_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). + * @GST_VAAPI_ENCODER_PROP_TRELLIS: Use trellis quantization method (gboolean). * * The set of configurable properties for the encoder. */ @@ -126,7 +127,8 @@ typedef enum { GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, GST_VAAPI_ENCODER_PROP_TUNE, GST_VAAPI_ENCODER_PROP_QUALITY_LEVEL, - GST_VAAPI_ENCODER_PROP_DEFAULT_ROI_VALUE + GST_VAAPI_ENCODER_PROP_DEFAULT_ROI_VALUE, + GST_VAAPI_ENCODER_PROP_TRELLIS } GstVaapiEncoderProp; /** @@ -192,6 +194,9 @@ 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); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index d49886a85e..f20e00e387 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2566,6 +2566,9 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture) } } + if (!gst_vaapi_encoder_ensure_param_trellis (base_encoder, picture)) + return FALSE; + if (!gst_vaapi_encoder_ensure_param_roi_regions (base_encoder, picture)) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index 521cb12ad0..b8302ee815 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -342,6 +342,12 @@ gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture); 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), \ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 843004e4b6..8126220a8b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -289,6 +289,9 @@ struct _GstVaapiEncoder VAEncMiscParameterHRD va_hrd; gint8 default_roi_value; + + /* trellis quantization */ + gboolean trellis; }; struct _GstVaapiEncoderClassData @@ -426,6 +429,11 @@ 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, From b6457e4ce534ac34f9bd401a04a9aba0013f2aa6 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 9 May 2019 00:09:21 +0800 Subject: [PATCH 3255/3781] libs: encoder: Add a missing comment for DEFAULT_ROI_VALUE property. --- gst-libs/gst/vaapi/gstvaapiencoder.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 8f6e4135a5..7c53517d41 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -117,6 +117,8 @@ typedef enum { * @GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD: The maximal distance * between two keyframes (uint). * @GST_VAAPI_ENCODER_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). + * @GST_VAAPI_ENCODER_PROP_DEFAULT_ROI_VALUE: The default delta qp to apply + * to each region of interest. * @GST_VAAPI_ENCODER_PROP_TRELLIS: Use trellis quantization method (gboolean). * * The set of configurable properties for the encoder. From be496a66c5e8f93849c7c206032c179edc88824b Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Wed, 1 May 2019 12:56:55 -0700 Subject: [PATCH 3256/3781] libs: encoder: add target-percentage property Allow users to set the target-percentage for variable rate controls. The default value is 70 (as hard-coded prior). v2: minimum allowed value changed from 0 to 1 v3: target-percentage unchanged if CBR used Resolves #129 --- gst-libs/gst/vaapi/gstvaapiencoder.c | 42 +++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiencoder.h | 7 ++++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 1 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index ecea336f33..8c8742937c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -145,8 +145,6 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) * else minimum bitrate = maximum bitrate * (2 * target percentage -100) / 100 * Target bitrate will be calculated like the following in the driver. * target bitrate = maximum bitrate * target percentage / 100 - * - * Note that target percentage is set as 70 currently in GStreamer VA-API. */ GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, GST_VAAPI_ENCODER_PROP_BITRATE, @@ -155,6 +153,18 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) "The desired bitrate expressed in kbps (0: auto-calculate)", 0, 100 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoder:target-percentage: + * + * The desired target percentage of bitrate for variable rate controls. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_PROP_TARGET_PERCENTAGE, + g_param_spec_uint ("target-percentage", + "Target Percentage", + "The desired target percentage of bitrate for variable rate " + "controls.", 1, 100, 70, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiEncoder:keyframe-period: * @@ -1035,7 +1045,7 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) target_percentage = (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) ? - 100 : 70; + 100 : encoder->target_percentage; /* *INDENT-OFF* */ /* Default values for rate control parameter */ @@ -1199,6 +1209,10 @@ set_property (GstVaapiEncoder * encoder, gint prop_id, const GValue * value) status = gst_vaapi_encoder_set_bitrate (encoder, g_value_get_uint (value)); break; + case GST_VAAPI_ENCODER_PROP_TARGET_PERCENTAGE: + status = gst_vaapi_encoder_set_target_percentage (encoder, + g_value_get_uint (value)); + break; case GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD: status = gst_vaapi_encoder_set_keyframe_period (encoder, g_value_get_uint (value)); @@ -1368,6 +1382,28 @@ gst_vaapi_encoder_set_bitrate (GstVaapiEncoder * encoder, guint bitrate) return GST_VAAPI_ENCODER_STATUS_SUCCESS; } +GstVaapiEncoderStatus +gst_vaapi_encoder_set_target_percentage (GstVaapiEncoder * encoder, + guint target_percentage) +{ + g_return_val_if_fail (encoder != NULL, 0); + + if (encoder->target_percentage != target_percentage + && encoder->num_codedbuf_queued > 0) { + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CBR) { + GST_INFO ("Target percentage is changed to %d on runtime", + target_percentage); + encoder->target_percentage = target_percentage; + return gst_vaapi_encoder_reconfigure_internal (encoder); + } + GST_WARNING ("Target percentage is ignored for CBR rate-control"); + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + } + + encoder->target_percentage = target_percentage; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + /** * gst_vaapi_encoder_set_keyframe_period: * @encoder: a #GstVaapiEncoder diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 7c53517d41..b22fde9e8c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -114,6 +114,8 @@ typedef enum { * GstVaapiEncoderProp: * @GST_VAAPI_ENCODER_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). * @GST_VAAPI_ENCODER_PROP_BITRATE: Bitrate expressed in kbps (uint). + * @GST_VAAPI_ENCODER_PROP_TARGET_PERCENTAGE: Desired target percentage of + * bitrate for variable rate controls. * @GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD: The maximal distance * between two keyframes (uint). * @GST_VAAPI_ENCODER_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). @@ -126,6 +128,7 @@ typedef enum { typedef enum { GST_VAAPI_ENCODER_PROP_RATECONTROL = 1, GST_VAAPI_ENCODER_PROP_BITRATE, + GST_VAAPI_ENCODER_PROP_TARGET_PERCENTAGE, GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, GST_VAAPI_ENCODER_PROP_TUNE, GST_VAAPI_ENCODER_PROP_QUALITY_LEVEL, @@ -180,6 +183,10 @@ gst_vaapi_encoder_set_rate_control (GstVaapiEncoder * encoder, 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); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 8126220a8b..4dd340cab6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -262,6 +262,7 @@ struct _GstVaapiEncoder GstVaapiRateControl rate_control; guint32 rate_control_mask; guint bitrate; /* kbps */ + guint target_percentage; guint keyframe_period; /* Maximum number of reference frames supported From 47d256b24c47de49cfb8051c9b93e3aeec6ee2fd Mon Sep 17 00:00:00 2001 From: Wangfei Date: Mon, 29 Apr 2019 09:52:39 +0800 Subject: [PATCH 3257/3781] libs: h265: dec: Add extension flags setting. Use VAPictureParameterBufferHEVCExtension& VASliceParameterBufferHEVCExtension to pass extension setting from some extension profile clips which may include these information. The hevc extension setting only supported after libva release 2.2.0 (API 1.2.0). --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 181 ++++++++++++++++++++-- 1 file changed, 165 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 61f508abac..6cd61f67a6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -251,15 +251,6 @@ gst_vaapi_picture_h265_create (GstVaapiPictureH265 * picture, return TRUE; } -static inline GstVaapiPictureH265 * -gst_vaapi_picture_h265_new (GstVaapiDecoderH265 * decoder) -{ - return (GstVaapiPictureH265 *) - gst_vaapi_codec_object_new (&GstVaapiPictureH265Class, - GST_VAAPI_CODEC_BASE (decoder), NULL, - sizeof (VAPictureParameterBufferHEVC), NULL, 0, 0); -} - static inline void gst_vaapi_picture_h265_set_reference (GstVaapiPictureH265 * picture, guint reference_flags) @@ -535,6 +526,36 @@ nal_is_ref (guint8 nal_type) return ret; } +static gboolean +is_range_extension_profile (GstVaapiProfile profile) +{ + if (profile == GST_VAAPI_PROFILE_H265_MAIN_422_10 + || profile == GST_VAAPI_PROFILE_H265_MAIN_444 + || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10) + return TRUE; + return FALSE; +} + +static inline GstVaapiPictureH265 * +gst_vaapi_picture_h265_new (GstVaapiDecoderH265 * decoder) +{ + GstVaapiDecoderH265Private *const priv = &decoder->priv; + if (is_range_extension_profile (priv->profile)) { +#if VA_CHECK_VERSION(1,2,0) + return (GstVaapiPictureH265 *) + gst_vaapi_codec_object_new (&GstVaapiPictureH265Class, + GST_VAAPI_CODEC_BASE (decoder), NULL, + sizeof (VAPictureParameterBufferHEVCExtension), NULL, 0, 0); +#endif + return NULL; + } else { + return (GstVaapiPictureH265 *) + gst_vaapi_codec_object_new (&GstVaapiPictureH265Class, + GST_VAAPI_CODEC_BASE (decoder), NULL, + sizeof (VAPictureParameterBufferHEVC), NULL, 0, 0); + } +} + /* Activates the supplied PPS */ static GstH265PPS * ensure_pps (GstVaapiDecoderH265 * decoder, GstH265PPS * pps) @@ -1814,9 +1835,18 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) GstVaapiPicture *const base_picture = &picture->base; GstH265PPS *const pps = get_pps (decoder); GstH265SPS *const sps = get_sps (decoder); - VAPictureParameterBufferHEVC *const pic_param = base_picture->param; + VAPictureParameterBufferHEVC *pic_param = base_picture->param; guint i, n; +#if VA_CHECK_VERSION(1,2,0) + VAPictureParameterBufferHEVCRext *pic_rext_param = NULL; + if (is_range_extension_profile (priv->profile)) { + VAPictureParameterBufferHEVCExtension *param = base_picture->param; + pic_param = ¶m->base; + pic_rext_param = ¶m->rext; + } +#endif + pic_param->pic_fields.value = 0; pic_param->slice_parsing_fields.value = 0; @@ -1928,6 +1958,56 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) /* FIXME: Set correct value as mentioned in va_dec_hevc.h */ pic_param->st_rps_bits = 0; + +#if VA_CHECK_VERSION(1,2,0) + if (pic_rext_param) { + pic_rext_param->range_extension_pic_fields.value = 0; + +#define COPY_REXT_FIELD(s, f) \ + pic_rext_param->f = s.f +#define COPY_REXT_BFM(a, s, f) \ + pic_rext_param->a.bits.f = s.f + + COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params, + transform_skip_rotation_enabled_flag); + COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params, + transform_skip_context_enabled_flag); + COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params, + implicit_rdpcm_enabled_flag); + COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params, + explicit_rdpcm_enabled_flag); + COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params, + extended_precision_processing_flag); + COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params, + intra_smoothing_disabled_flag); + COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params, + high_precision_offsets_enabled_flag); + COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params, + persistent_rice_adaptation_enabled_flag); + COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params, + cabac_bypass_alignment_enabled_flag); + + COPY_REXT_BFM (range_extension_pic_fields, pps->pps_extension_params, + cross_component_prediction_enabled_flag); + COPY_REXT_BFM (range_extension_pic_fields, pps->pps_extension_params, + chroma_qp_offset_list_enabled_flag); + + COPY_REXT_FIELD (pps->pps_extension_params, diff_cu_chroma_qp_offset_depth); + COPY_REXT_FIELD (pps->pps_extension_params, + chroma_qp_offset_list_len_minus1); + COPY_REXT_FIELD (pps->pps_extension_params, log2_sao_offset_scale_luma); + COPY_REXT_FIELD (pps->pps_extension_params, log2_sao_offset_scale_chroma); + COPY_REXT_FIELD (pps->pps_extension_params, + log2_max_transform_skip_block_size_minus2); + + memcpy (pic_rext_param->cb_qp_offset_list, + pps->pps_extension_params.cb_qp_offset_list, + sizeof (pic_rext_param->cb_qp_offset_list)); + memcpy (pic_rext_param->cr_qp_offset_list, + pps->pps_extension_params.cr_qp_offset_list, + sizeof (pic_rext_param->cr_qp_offset_list)); + } +#endif return TRUE; } @@ -2302,13 +2382,22 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, GstVaapiSlice * slice, GstH265SliceHdr * slice_hdr) { GstVaapiDecoderH265Private *const priv = &decoder->priv; - VASliceParameterBufferHEVC *const slice_param = slice->param; + VASliceParameterBufferHEVC *slice_param = slice->param; GstH265PPS *const pps = get_pps (decoder); GstH265SPS *const sps = get_sps (decoder); GstH265PredWeightTable *const w = &slice_hdr->pred_weight_table; gint chroma_weight, chroma_log2_weight_denom; gint i, j; +#if VA_CHECK_VERSION(1,2,0) + VASliceParameterBufferHEVCRext *slice_rext_param = NULL; + if (is_range_extension_profile (priv->profile)) { + VASliceParameterBufferHEVCExtension *param = slice->param; + slice_param = ¶m->base; + slice_rext_param = ¶m->rext; + } +#endif + slice_param->luma_log2_weight_denom = 0; slice_param->delta_chroma_log2_weight_denom = 0; @@ -2333,6 +2422,19 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, memset (slice_param->ChromaOffsetL1, 0, sizeof (slice_param->ChromaOffsetL1)); +#if VA_CHECK_VERSION(1,2,0) + if (slice_rext_param) { + memset (slice_rext_param->luma_offset_l0, 0, + sizeof (slice_rext_param->luma_offset_l0)); + memset (slice_rext_param->luma_offset_l1, 0, + sizeof (slice_rext_param->luma_offset_l1)); + memset (slice_rext_param->ChromaOffsetL0, 0, + sizeof (slice_rext_param->ChromaOffsetL0)); + memset (slice_rext_param->ChromaOffsetL1, 0, + sizeof (slice_rext_param->ChromaOffsetL1)); + } +#endif + slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom; if (sps->chroma_array_type != 0) slice_param->delta_chroma_log2_weight_denom = @@ -2346,6 +2448,10 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, if (slice_hdr->pred_weight_table.luma_weight_l0_flag[i]) { slice_param->delta_luma_weight_l0[i] = w->delta_luma_weight_l0[i]; slice_param->luma_offset_l0[i] = w->luma_offset_l0[i]; +#if VA_CHECK_VERSION(1,2,0) + if (slice_rext_param) + slice_rext_param->luma_offset_l0[i] = w->luma_offset_l0[i]; +#endif } if (slice_hdr->pred_weight_table.chroma_weight_l0_flag[i]) { for (j = 0; j < 2; j++) { @@ -2360,6 +2466,14 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, ((priv->WpOffsetHalfRangeC * chroma_weight) >> chroma_log2_weight_denom)), -priv->WpOffsetHalfRangeC, priv->WpOffsetHalfRangeC - 1); +#if VA_CHECK_VERSION(1,2,0) + if (slice_rext_param) + slice_rext_param->ChromaOffsetL0[i][j] = CLAMP ( + (priv->WpOffsetHalfRangeC + w->delta_chroma_offset_l0[i][j] - + ((priv->WpOffsetHalfRangeC * + chroma_weight) >> chroma_log2_weight_denom)), + -priv->WpOffsetHalfRangeC, priv->WpOffsetHalfRangeC - 1); +#endif } } } @@ -2369,6 +2483,10 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, if (slice_hdr->pred_weight_table.luma_weight_l1_flag[i]) { slice_param->delta_luma_weight_l1[i] = w->delta_luma_weight_l1[i]; slice_param->luma_offset_l1[i] = w->luma_offset_l1[i]; +#if VA_CHECK_VERSION(1,2,0) + if (slice_rext_param) + slice_rext_param->luma_offset_l1[i] = w->luma_offset_l1[i]; +#endif } if (slice_hdr->pred_weight_table.chroma_weight_l1_flag[i]) { for (j = 0; j < 2; j++) { @@ -2385,6 +2503,15 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder, ((priv->WpOffsetHalfRangeC * chroma_weight) >> chroma_log2_weight_denom)), -priv->WpOffsetHalfRangeC, priv->WpOffsetHalfRangeC - 1); +#if VA_CHECK_VERSION(1,2,0) + if (slice_rext_param) + slice_rext_param->ChromaOffsetL1[i][j] = + CLAMP ((priv->WpOffsetHalfRangeC + + w->delta_chroma_offset_l1[i][j] - + ((priv->WpOffsetHalfRangeC * + chroma_weight) >> chroma_log2_weight_denom)), + -priv->WpOffsetHalfRangeC, priv->WpOffsetHalfRangeC - 1); +#endif } } } @@ -2450,8 +2577,18 @@ fill_slice (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture, GstVaapiSlice * slice, GstVaapiParserInfoH265 * pi, GstVaapiDecoderUnit * unit) { - VASliceParameterBufferHEVC *const slice_param = slice->param; GstH265SliceHdr *slice_hdr = &pi->data.slice_hdr; + VASliceParameterBufferHEVC *slice_param = slice->param; + +#if VA_CHECK_VERSION(1,2,0) + GstVaapiDecoderH265Private *const priv = &decoder->priv; + VASliceParameterBufferHEVCRext *slice_rext_param = NULL; + if (is_range_extension_profile (priv->profile)) { + VASliceParameterBufferHEVCExtension *param = slice->param; + slice_param = ¶m->base; + slice_rext_param = ¶m->rext; + } +#endif /* Fill in VASliceParameterBufferH265 */ slice_param->LongSliceFlags.value = 0; @@ -2505,6 +2642,12 @@ fill_slice (GstVaapiDecoderH265 * decoder, slice_param->five_minus_max_num_merge_cand = slice_hdr->five_minus_max_num_merge_cand; +#if VA_CHECK_VERSION(1,2,0) + if (slice_rext_param) + slice_rext_param->slice_ext_flags.bits.cu_chroma_qp_offset_enabled_flag = + slice_hdr->cu_chroma_qp_offset_enabled_flag; +#endif + if (!fill_RefPicList (decoder, picture, slice, slice_hdr)) return FALSE; @@ -2521,7 +2664,7 @@ decode_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) GstVaapiParserInfoH265 *const pi = unit->parsed_info; GstVaapiPictureH265 *const picture = priv->current_picture; GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; - GstVaapiSlice *slice; + GstVaapiSlice *slice = NULL; GstBuffer *const buffer = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer; GstMapInfo map_info; @@ -2554,9 +2697,15 @@ decode_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END) GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_END); - slice = GST_VAAPI_SLICE_NEW (HEVC, decoder, - (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size); - + if (is_range_extension_profile (priv->profile)) { +#if VA_CHECK_VERSION(1,2,0) + slice = GST_VAAPI_SLICE_NEW (HEVCExtension, decoder, + (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size); +#endif + } else { + slice = GST_VAAPI_SLICE_NEW (HEVC, decoder, + (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size); + } gst_buffer_unmap (buffer, &map_info); if (!slice) { GST_ERROR ("failed to allocate slice"); From 0af3e36068a93a68ec6c3c039f28c441bf0af26a Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 May 2019 18:29:10 +0800 Subject: [PATCH 3258/3781] libs: encoder: not call ensure_num_slices inside g_assert g_assert will take no effect when glib's G_DISABLE_ASSERT macro is defined. The function inside the g_assert will take no effect and we will fail to set the correct slice number. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 ++++-- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index f20e00e387..e3c391db15 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2748,6 +2748,7 @@ reset_properties (GstVaapiEncoderH264 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); guint mb_size, i; + gboolean ret; if (encoder->idr_period < base_encoder->keyframe_period) encoder->idr_period = base_encoder->keyframe_period; @@ -2757,8 +2758,9 @@ reset_properties (GstVaapiEncoderH264 * encoder) encoder->qp_i = encoder->init_qp; mb_size = encoder->mb_width * encoder->mb_height; - g_assert (gst_vaapi_encoder_ensure_num_slices (base_encoder, encoder->profile, - encoder->entrypoint, (mb_size + 1) / 2, &encoder->num_slices)); + ret = gst_vaapi_encoder_ensure_num_slices (base_encoder, encoder->profile, + encoder->entrypoint, (mb_size + 1) / 2, &encoder->num_slices); + g_assert (ret); if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 01425523f8..53c22121ca 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2058,6 +2058,7 @@ reset_properties (GstVaapiEncoderH265 * encoder) GstVaapiH265ReorderPool *reorder_pool; GstVaapiH265RefPool *ref_pool; guint ctu_size; + gboolean ret; if (encoder->idr_period < base_encoder->keyframe_period) encoder->idr_period = base_encoder->keyframe_period; @@ -2067,8 +2068,9 @@ reset_properties (GstVaapiEncoderH265 * encoder) encoder->qp_i = encoder->init_qp; ctu_size = encoder->ctu_width * encoder->ctu_height; - g_assert (gst_vaapi_encoder_ensure_num_slices (base_encoder, encoder->profile, - encoder->entrypoint, (ctu_size + 1) / 2, &encoder->num_slices)); + ret = gst_vaapi_encoder_ensure_num_slices (base_encoder, encoder->profile, + encoder->entrypoint, (ctu_size + 1) / 2, &encoder->num_slices); + g_assert (ret); gst_vaapi_encoder_ensure_max_num_ref_frames (base_encoder, encoder->profile, encoder->entrypoint); From b0f5a5976046f34a2f829d55abecf58b675d8261 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 22 Oct 2018 11:48:29 +0200 Subject: [PATCH 3259/3781] docs: Port to hotdoc --- Makefile.am | 4 +- configure.ac | 13 - docs/Makefile.am | 19 - docs/gst_plugins_cache.json | 2748 +++++++++++++++++ docs/index.md | 29 + docs/meson.build | 62 + docs/plugins/Makefile.am | 92 - .../gstreamer-vaapi-plugins-docs.xml.in | 55 - .../gstreamer-vaapi-plugins-sections.txt | 209 -- docs/plugins/gstreamer-vaapi-plugins.types | 0 docs/plugins/inspect/plugin-vaapi.xml | 196 -- docs/plugins/running.xml | 68 - docs/sitemap.txt | 1 + docs/version.entities.in | 2 - gst/vaapi/meson.build | 2 + meson.build | 3 +- meson_options.txt | 3 +- 17 files changed, 2847 insertions(+), 659 deletions(-) delete mode 100644 docs/Makefile.am create mode 100644 docs/gst_plugins_cache.json create mode 100644 docs/index.md create mode 100644 docs/meson.build delete mode 100644 docs/plugins/Makefile.am delete mode 100644 docs/plugins/gstreamer-vaapi-plugins-docs.xml.in delete mode 100644 docs/plugins/gstreamer-vaapi-plugins-sections.txt delete mode 100644 docs/plugins/gstreamer-vaapi-plugins.types delete mode 100644 docs/plugins/inspect/plugin-vaapi.xml delete mode 100644 docs/plugins/running.xml create mode 100644 docs/sitemap.txt delete mode 100644 docs/version.entities.in diff --git a/Makefile.am b/Makefile.am index 609c7e3990..f88b6c8c86 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,9 +6,7 @@ else SUBDIRS_TESTS = endif -SUBDIRS = gst-libs gst $(SUBDIRS_TESTS) m4 common docs - -DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc +SUBDIRS = gst-libs gst $(SUBDIRS_TESTS) m4 common # Extra clean files so that maintainer-clean removes *everything* MAINTAINERCLEANFILES = \ diff --git a/configure.ac b/configure.ac index a0f208bdfd..5e04751a93 100644 --- a/configure.ac +++ b/configure.ac @@ -34,10 +34,6 @@ m4_define([wayland_api_version], [1.11.0]) # VA-API minimum version number m4_define([va_api_version], [0.39.0]) -# gtk-doc version number -# XXX: introspection annotations require gtk-doc >= 1.12 -m4_define([gtkdoc_version], [1.12]) - AC_PREREQ([2.69]) AC_INIT([GStreamer VA-API Plug-ins], [gst_vaapi_version], [http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer], @@ -85,7 +81,6 @@ GST_REQ=gst_version GST_PBREQ=gst_plugins_base_version GST_PBADREQ=gst_plugins_bad_version WAYLAND_REQ=wayland_api_version -GTKDOC_REQ=gtkdoc_version dnl *** required versions of VA-API stuff *** VAAPI_REQ=va_api_version @@ -168,10 +163,6 @@ AC_PROG_CC_STDC dnl check if the compiler supports '-c' and '-o' options AM_PROG_CC_C_O -dnl check for documentation tools -GTK_DOC_CHECK([$GTKDOC_REQ]) -AG_GST_PLUGIN_DOCS([$GTKDOC_REQ]) - dnl *** checks for libraries *** dnl check for libm, for sin() etc. AC_CHECK_LIB([m], [tan]) @@ -744,10 +735,6 @@ AC_CONFIG_FILES([ common/Makefile common/m4/Makefile m4/Makefile - docs/Makefile - docs/version.entities - docs/plugins/Makefile - docs/plugins/gstreamer-vaapi-plugins-docs.xml gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/vaapi/Makefile diff --git a/docs/Makefile.am b/docs/Makefile.am deleted file mode 100644 index dfe9c3a659..0000000000 --- a/docs/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -if ENABLE_GTK_DOC -if ENABLE_PLUGIN_DOCS -PLUGIN_DOCS_DIRS = plugins -else -PLUGIN_DOCS_DIRS = -endif -else -PLUGIN_DOCS_DIRS = plugins -endif - -SUBDIRS = $(PLUGIN_DOCS_DIRS) -DIST_SUBDIRS = plugins - -EXTRA_DIST = version.entities.in - -upload: - @if test "x$(SUBDIRS)" != x; then for a in $(SUBDIRS); do cd $$a; make upload; cd ..; done; fi - --include $(top_srcdir)/git.mk diff --git a/docs/gst_plugins_cache.json b/docs/gst_plugins_cache.json new file mode 100644 index 0000000000..8e6bfd185f --- /dev/null +++ b/docs/gst_plugins_cache.json @@ -0,0 +1,2748 @@ +{ + "vaapi": { + "description": "VA-API based elements", + "elements": { + "vaapidecodebin": { + "author": "Sreerenj Balachandran , Victor Jaquez ", + "classification": "Codec/Decoder/Video", + "description": "A VA-API based bin with a decoder and a postprocessor", + "hierarchy": [ + "GstVaapiDecodeBin", + "GstBin", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Decoder/Video", + "long-name": "VA-API Decode Bin", + "name": "vaapidecodebin", + "pad-templates": { + "sink": { + "caps": "video/mpeg:\n mpegversion: 2\n systemstream: false\nvideo/mpeg:\n mpegversion: 4\nvideo/x-divx:\nvideo/x-xvid:\nvideo/x-h263:\nvideo/x-h264:\nvideo/x-h265:\nvideo/x-wmv:\nvideo/x-vp8:\nvideo/x-vp9:\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "async-handling": { + "blurb": "The bin will handle Asynchronous state changes", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "deinterlace-method": { + "blurb": "Deinterlace method to use", + "construct": false, + "construct-only": false, + "default": "bob (1)", + "enum": true, + "type-name": "GstVaapiDeinterlaceMethod", + "values": [ + { + "desc": "Disable deinterlacing", + "name": "none", + "value": "0" + }, + { + "desc": "Bob deinterlacing", + "name": "bob", + "value": "1" + }, + { + "desc": "Weave deinterlacing", + "name": "weave", + "value": "2" + }, + { + "desc": "Motion adaptive deinterlacing", + "name": "motion-adaptive", + "value": "3" + }, + { + "desc": "Motion compensated deinterlacing", + "name": "motion-compensated", + "value": "4" + } + ], + "writable": true + }, + "disable-vpp": { + "blurb": "Disable Video Post Processing (No support for run time disabling)", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "max-size-buffers": { + "blurb": "Max. number of buffers in the queue (0=disable)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "-1", + "min": "0", + "type-name": "guint", + "writable": true + }, + "max-size-bytes": { + "blurb": "Max. amount of data in the queue (bytes, 0=disable)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "-1", + "min": "0", + "type-name": "guint", + "writable": true + }, + "max-size-time": { + "blurb": "Max. amount of data in the queue (in ns, 0=disable)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "18446744073709551615", + "min": "0", + "type-name": "guint64", + "writable": true + }, + "message-forward": { + "blurb": "Forwards all children messages", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapidecodebin0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + } + }, + "rank": "primary + 2" + }, + "vaapih264dec": { + "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", + "classification": "Codec/Decoder/Video", + "description": "A VA-API based H264 video decoder", + "hierarchy": [ + "GstVaapiDecode_h264", + "GstVideoDecoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Decoder/Video", + "long-name": "VA-API H264 decoder", + "name": "vaapih264dec", + "pad-templates": { + "sink": { + "caps": "video/x-h264:\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "base-only": { + "blurb": "Drop any NAL unit not defined in Annex.A", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "low-latency": { + "blurb": "When enabled, frames will be pushed as soon as they are available. It might violate the H.264 spec.", + "construct": true, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapidecode_h264-0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + } + }, + "rank": "primary" + }, + "vaapih264enc": { + "author": "Wind Yuan ", + "classification": "Codec/Encoder/Video", + "description": "A VA-API based H264 video encoder", + "hierarchy": [ + "GstVaapiEncodeH264", + "GstVaapiEncode", + "GstVideoEncoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Encoder/Video", + "long-name": "VA-API H264 encoder", + "name": "vaapih264enc", + "pad-templates": { + "sink": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-h264:\n stream-format: { (string)avc, (string)byte-stream }\n alignment: au\n profile: { (string)constrained-baseline, (string)baseline, (string)main, (string)high, (string)multiview-high, (string)stereo-high }\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "aud": { + "blurb": "Use AU (Access Unit) delimeter", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "bitrate": { + "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "102400", + "min": "0", + "type-name": "guint", + "writable": true + }, + "cabac": { + "blurb": "Enable CABAC entropy coding mode", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "compliance-mode": { + "blurb": "Tune Encode quality/performance by relaxing specification compliance restrictions", + "construct": false, + "construct-only": false, + "default": "strict (0)", + "enum": true, + "type-name": "GstVaapiEncoderH264ComplianceMode", + "values": [ + { + "desc": "Strict compliance to the H264 Specification ", + "name": "strict", + "value": "0" + }, + { + "desc": "Restrict the allocation size of coded-buffer", + "name": "restrict-buf-alloc", + "value": "1" + } + ], + "writable": true + }, + "cpb-length": { + "blurb": "Length of the CPB buffer in milliseconds", + "construct": false, + "construct-only": false, + "default": "1500", + "max": "10000", + "min": "1", + "type-name": "guint", + "writable": true + }, + "dct8x8": { + "blurb": "Enable adaptive use of 8x8 transforms in I-frames", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "default-roi-delta-qp": { + "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", + "construct": false, + "construct-only": false, + "default": "-10", + "max": "10", + "min": "-10", + "type-name": "gint", + "writable": true + }, + "init-qp": { + "blurb": "Initial quantizer value", + "construct": false, + "construct-only": false, + "default": "26", + "max": "51", + "min": "1", + "type-name": "guint", + "writable": true + }, + "keyframe-period": { + "blurb": "Maximal distance between two keyframes (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "30", + "max": "-1", + "min": "0", + "type-name": "guint", + "writable": true + }, + "max-bframes": { + "blurb": "Number of B-frames between I and P", + "construct": false, + "construct-only": false, + "default": "0", + "max": "10", + "min": "0", + "type-name": "guint", + "writable": true + }, + "mbbrc": { + "blurb": "Macroblock level Bitrate Control", + "construct": false, + "construct-only": false, + "default": "auto (0)", + "enum": true, + "type-name": "GstVaapiEncoderMbbrc", + "values": [ + { + "desc": "Auto", + "name": "auto", + "value": "0" + }, + { + "desc": "On", + "name": "on", + "value": "1" + }, + { + "desc": "Off", + "name": "off", + "value": "2" + } + ], + "writable": true + }, + "min-qp": { + "blurb": "Minimum quantizer value", + "construct": false, + "construct-only": false, + "default": "1", + "max": "51", + "min": "1", + "type-name": "guint", + "writable": true + }, + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapiencodeh264-0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "num-slices": { + "blurb": "Number of slices per frame", + "construct": false, + "construct-only": false, + "default": "1", + "max": "200", + "min": "1", + "type-name": "guint", + "writable": true + }, + "num-views": { + "blurb": "Number of Views for MVC encoding", + "construct": false, + "construct-only": false, + "default": "1", + "max": "10", + "min": "1", + "type-name": "guint", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + }, + "prediction-type": { + "blurb": "Reference Picture Selection Modes", + "construct": false, + "construct-only": false, + "default": "default (0)", + "enum": true, + "type-name": "GstVaapiEncoderH264PredictionType", + "values": [ + { + "desc": "Default encode, prev/next frame as ref ", + "name": "default", + "value": "0" + }, + { + "desc": "Hierarchical P frame encode", + "name": "hierarchical-p", + "value": "1" + }, + { + "desc": "Hierarchical B frame encode", + "name": "hierarchical-b", + "value": "2" + } + ], + "writable": true + }, + "qos": { + "blurb": "Handle Quality-of-Service events from downstream", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "qp-ib": { + "blurb": "Difference of QP between I and B frame (available only on CQP)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "51", + "min": "-51", + "type-name": "gint", + "writable": true + }, + "qp-ip": { + "blurb": "Difference of QP between I and P frame (available only on CQP)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "51", + "min": "-51", + "type-name": "gint", + "writable": true + }, + "quality-level": { + "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", + "construct": false, + "construct-only": false, + "default": "4", + "max": "7", + "min": "1", + "type-name": "guint", + "writable": true + }, + "rate-control": { + "blurb": "Rate control mode", + "construct": false, + "construct-only": false, + "default": "cqp (1)", + "enum": true, + "type-name": "GstVaapiRateControlH264", + "values": [ + { + "desc": "Constant QP", + "name": "cqp", + "value": "1" + }, + { + "desc": "Constant bitrate", + "name": "cbr", + "value": "2" + }, + { + "desc": "Variable bitrate", + "name": "vbr", + "value": "4" + }, + { + "desc": "Variable bitrate - Constrained", + "name": "vbr_constrained", + "value": "5" + } + ], + "writable": true + }, + "refs": { + "blurb": "Number of reference frames", + "construct": false, + "construct-only": false, + "default": "1", + "max": "8", + "min": "1", + "type-name": "guint", + "writable": true + }, + "temporal-levels": { + "blurb": "Number of temporal levels in the encoded stream ", + "construct": false, + "construct-only": false, + "default": "1", + "max": "4", + "min": "1", + "type-name": "guint", + "writable": true + }, + "tune": { + "blurb": "Encoder tuning option", + "construct": false, + "construct-only": false, + "default": "none (0)", + "enum": true, + "type-name": "GstVaapiEncoderTuneH264", + "values": [ + { + "desc": "None", + "name": "none", + "value": "0" + }, + { + "desc": "High compression", + "name": "high-compression", + "value": "1" + }, + { + "desc": "Low power mode", + "name": "low-power", + "value": "3" + } + ], + "writable": true + }, + "view-ids": { + "blurb": "Set of View Ids used for MVC encoding", + "construct": false, + "construct-only": false, + "type-name": "GValueArray", + "writable": true + } + }, + "rank": "primary" + }, + "vaapih265dec": { + "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", + "classification": "Codec/Decoder/Video", + "description": "A VA-API based H265 video decoder", + "hierarchy": [ + "GstVaapiDecode_h265", + "GstVideoDecoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Decoder/Video", + "long-name": "VA-API H265 decoder", + "name": "vaapih265dec", + "pad-templates": { + "sink": { + "caps": "video/x-h265:\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapidecode_h265-0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + } + }, + "rank": "primary" + }, + "vaapih265enc": { + "author": "Sreerenj Balachandran ", + "classification": "Codec/Encoder/Video", + "description": "A VA-API based H265 video encoder", + "hierarchy": [ + "GstVaapiEncodeH265", + "GstVaapiEncode", + "GstVideoEncoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Encoder/Video", + "long-name": "VA-API H265 encoder", + "name": "vaapih265enc", + "pad-templates": { + "sink": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-h265:\n stream-format: { (string)hvc1, (string)byte-stream }\n alignment: au\n profile: { (string)main, (string)main-10 }\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "bitrate": { + "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "102400", + "min": "0", + "type-name": "guint", + "writable": true + }, + "cpb-length": { + "blurb": "Length of the CPB buffer in milliseconds", + "construct": false, + "construct-only": false, + "default": "1500", + "max": "10000", + "min": "1", + "type-name": "guint", + "writable": true + }, + "default-roi-delta-qp": { + "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", + "construct": false, + "construct-only": false, + "default": "-10", + "max": "10", + "min": "-10", + "type-name": "gint", + "writable": true + }, + "init-qp": { + "blurb": "Initial quantizer value", + "construct": false, + "construct-only": false, + "default": "26", + "max": "51", + "min": "1", + "type-name": "guint", + "writable": true + }, + "keyframe-period": { + "blurb": "Maximal distance between two keyframes (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "30", + "max": "-1", + "min": "0", + "type-name": "guint", + "writable": true + }, + "low-delay-b": { + "blurb": "Transforms P frames into predictive B frames. Enable it when P frames are not supported.", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "max-bframes": { + "blurb": "Number of B-frames between I and P", + "construct": false, + "construct-only": false, + "default": "0", + "max": "10", + "min": "0", + "type-name": "guint", + "writable": true + }, + "mbbrc": { + "blurb": "Macroblock level Bitrate Control", + "construct": false, + "construct-only": false, + "default": "auto (0)", + "enum": true, + "type-name": "GstVaapiEncoderMbbrc", + "values": [ + { + "desc": "Auto", + "name": "auto", + "value": "0" + }, + { + "desc": "On", + "name": "on", + "value": "1" + }, + { + "desc": "Off", + "name": "off", + "value": "2" + } + ], + "writable": true + }, + "min-qp": { + "blurb": "Minimum quantizer value", + "construct": false, + "construct-only": false, + "default": "1", + "max": "51", + "min": "1", + "type-name": "guint", + "writable": true + }, + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapiencodeh265-0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "num-slices": { + "blurb": "Number of slices per frame", + "construct": false, + "construct-only": false, + "default": "1", + "max": "200", + "min": "1", + "type-name": "guint", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + }, + "qos": { + "blurb": "Handle Quality-of-Service events from downstream", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "qp-ib": { + "blurb": "Difference of QP between I and B frame (available only on CQP)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "51", + "min": "-51", + "type-name": "gint", + "writable": true + }, + "qp-ip": { + "blurb": "Difference of QP between I and P frame (available only on CQP)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "51", + "min": "-51", + "type-name": "gint", + "writable": true + }, + "quality-level": { + "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", + "construct": false, + "construct-only": false, + "default": "4", + "max": "7", + "min": "1", + "type-name": "guint", + "writable": true + }, + "rate-control": { + "blurb": "Rate control mode", + "construct": false, + "construct-only": false, + "default": "cqp (1)", + "enum": true, + "type-name": "GstVaapiRateControlH265", + "values": [ + { + "desc": "Constant QP", + "name": "cqp", + "value": "1" + }, + { + "desc": "Constant bitrate", + "name": "cbr", + "value": "2" + }, + { + "desc": "Variable bitrate", + "name": "vbr", + "value": "4" + } + ], + "writable": true + }, + "refs": { + "blurb": "Number of reference frames", + "construct": false, + "construct-only": false, + "default": "1", + "max": "3", + "min": "1", + "type-name": "guint", + "writable": true + }, + "tune": { + "blurb": "Encoder tuning option", + "construct": false, + "construct-only": false, + "default": "none (0)", + "enum": true, + "type-name": "GstVaapiEncoderTuneH265", + "values": [ + { + "desc": "None", + "name": "none", + "value": "0" + } + ], + "writable": true + } + }, + "rank": "primary" + }, + "vaapijpegdec": { + "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", + "classification": "Codec/Decoder/Video", + "description": "A VA-API based JPEG video decoder", + "hierarchy": [ + "GstVaapiDecode_jpeg", + "GstVideoDecoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Decoder/Video", + "long-name": "VA-API JPEG decoder", + "name": "vaapijpegdec", + "pad-templates": { + "sink": { + "caps": "image/jpeg:\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapidecode_jpeg0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + } + }, + "rank": "marginal" + }, + "vaapijpegenc": { + "author": "Sreerenj Balachandran ", + "classification": "Codec/Encoder/Image", + "description": "A VA-API based JPEG video encoder", + "hierarchy": [ + "GstVaapiEncodeJpeg", + "GstVaapiEncode", + "GstVideoEncoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Encoder/Image", + "long-name": "VA-API JPEG encoder", + "name": "vaapijpegenc", + "pad-templates": { + "sink": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "image/jpeg:\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "bitrate": { + "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "102400", + "min": "0", + "type-name": "guint", + "writable": true + }, + "default-roi-delta-qp": { + "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", + "construct": false, + "construct-only": false, + "default": "-10", + "max": "10", + "min": "-10", + "type-name": "gint", + "writable": true + }, + "keyframe-period": { + "blurb": "Maximal distance between two keyframes (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "30", + "max": "-1", + "min": "0", + "type-name": "guint", + "writable": true + }, + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapiencodejpeg0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + }, + "qos": { + "blurb": "Handle Quality-of-Service events from downstream", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "quality": { + "blurb": "Quality factor", + "construct": false, + "construct-only": false, + "default": "50", + "max": "100", + "min": "0", + "type-name": "guint", + "writable": true + }, + "quality-level": { + "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", + "construct": false, + "construct-only": false, + "default": "4", + "max": "7", + "min": "1", + "type-name": "guint", + "writable": true + }, + "rate-control": { + "blurb": "Rate control mode", + "construct": false, + "construct-only": false, + "default": "none (0)", + "enum": true, + "type-name": "GstVaapiRateControlJPEG", + "values": [ + { + "desc": "None", + "name": "none", + "value": "0" + } + ], + "writable": true + }, + "tune": { + "blurb": "Encoder tuning option", + "construct": false, + "construct-only": false, + "default": "none (0)", + "enum": true, + "type-name": "GstVaapiEncoderTuneJPEG", + "values": [ + { + "desc": "None", + "name": "none", + "value": "0" + } + ], + "writable": true + } + }, + "rank": "primary" + }, + "vaapimpeg2dec": { + "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", + "classification": "Codec/Decoder/Video", + "description": "A VA-API based MPEG2 video decoder", + "hierarchy": [ + "GstVaapiDecode_mpeg2", + "GstVideoDecoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Decoder/Video", + "long-name": "VA-API MPEG2 decoder", + "name": "vaapimpeg2dec", + "pad-templates": { + "sink": { + "caps": "video/mpeg:\n mpegversion: 2\n systemstream: false\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapidecode_mpeg2-0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + } + }, + "rank": "primary" + }, + "vaapimpeg2enc": { + "author": "Guangxin Xu ", + "classification": "Codec/Encoder/Video", + "description": "A VA-API based MPEG-2 video encoder", + "hierarchy": [ + "GstVaapiEncodeMpeg2", + "GstVaapiEncode", + "GstVideoEncoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Encoder/Video", + "long-name": "VA-API MPEG-2 encoder", + "name": "vaapimpeg2enc", + "pad-templates": { + "sink": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/mpeg:\n mpegversion: 2\n systemstream: false\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "bitrate": { + "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "102400", + "min": "0", + "type-name": "guint", + "writable": true + }, + "default-roi-delta-qp": { + "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", + "construct": false, + "construct-only": false, + "default": "-10", + "max": "10", + "min": "-10", + "type-name": "gint", + "writable": true + }, + "keyframe-period": { + "blurb": "Maximal distance between two keyframes (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "30", + "max": "-1", + "min": "0", + "type-name": "guint", + "writable": true + }, + "max-bframes": { + "blurb": "Number of B-frames between I and P", + "construct": false, + "construct-only": false, + "default": "0", + "max": "16", + "min": "0", + "type-name": "guint", + "writable": true + }, + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapiencodempeg2-0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + }, + "qos": { + "blurb": "Handle Quality-of-Service events from downstream", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "quality-level": { + "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", + "construct": false, + "construct-only": false, + "default": "4", + "max": "7", + "min": "1", + "type-name": "guint", + "writable": true + }, + "quantizer": { + "blurb": "Constant quantizer (if rate-control mode is CQP)", + "construct": false, + "construct-only": false, + "default": "8", + "max": "62", + "min": "2", + "type-name": "guint", + "writable": true + }, + "rate-control": { + "blurb": "Rate control mode", + "construct": false, + "construct-only": false, + "default": "cqp (1)", + "enum": true, + "type-name": "GstVaapiRateControlMPEG2", + "values": [ + { + "desc": "Constant QP", + "name": "cqp", + "value": "1" + }, + { + "desc": "Constant bitrate", + "name": "cbr", + "value": "2" + } + ], + "writable": true + }, + "tune": { + "blurb": "Encoder tuning option", + "construct": false, + "construct-only": false, + "default": "none (0)", + "enum": true, + "type-name": "GstVaapiEncoderTuneMPEG2", + "values": [ + { + "desc": "None", + "name": "none", + "value": "0" + } + ], + "writable": true + } + }, + "rank": "primary" + }, + "vaapipostproc": { + "author": "Gwenole Beauchesne ", + "classification": "Filter/Converter/Video;Filter/Converter/Video/Scaler;Filter/Effect/Video;Filter/Effect/Video/Deinterlace", + "description": "A VA-API video postprocessing filter", + "hierarchy": [ + "GstVaapiPostproc", + "GstBaseTransform", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Filter/Converter/Video;Filter/Converter/Video/Scaler;Filter/Effect/Video;Filter/Effect/Video/Deinterlace", + "long-name": "VA-API video postprocessing", + "name": "vaapipostproc", + "pad-templates": { + "sink": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "brightness": { + "blurb": "The color brightness value", + "construct": false, + "construct-only": false, + "default": "0", + "max": "1", + "min": "-1", + "type-name": "gfloat", + "writable": true + }, + "contrast": { + "blurb": "The color contrast value", + "construct": false, + "construct-only": false, + "default": "1", + "max": "2", + "min": "0", + "type-name": "gfloat", + "writable": true + }, + "deinterlace-method": { + "blurb": "Deinterlace method to use", + "construct": false, + "construct-only": false, + "default": "bob (1)", + "enum": true, + "type-name": "GstVaapiDeinterlaceMethod", + "values": [ + { + "desc": "Disable deinterlacing", + "name": "none", + "value": "0" + }, + { + "desc": "Bob deinterlacing", + "name": "bob", + "value": "1" + }, + { + "desc": "Weave deinterlacing", + "name": "weave", + "value": "2" + }, + { + "desc": "Motion adaptive deinterlacing", + "name": "motion-adaptive", + "value": "3" + }, + { + "desc": "Motion compensated deinterlacing", + "name": "motion-compensated", + "value": "4" + } + ], + "writable": true + }, + "deinterlace-mode": { + "blurb": "Deinterlace mode to use", + "construct": false, + "construct-only": false, + "default": "auto (0)", + "enum": true, + "type-name": "GstVaapiDeinterlaceMode", + "values": [ + { + "desc": "Auto detection", + "name": "auto", + "value": "0" + }, + { + "desc": "Force deinterlacing", + "name": "interlaced", + "value": "1" + }, + { + "desc": "Never deinterlace", + "name": "disabled", + "value": "2" + } + ], + "writable": true + }, + "denoise": { + "blurb": "The level of denoising to apply", + "construct": false, + "construct-only": false, + "default": "0", + "max": "1", + "min": "0", + "type-name": "gfloat", + "writable": true + }, + "force-aspect-ratio": { + "blurb": "When enabled, scaling will respect original aspect ratio", + "construct": false, + "construct-only": false, + "default": "true", + "type-name": "gboolean", + "writable": true + }, + "format": { + "blurb": "The forced output pixel format", + "construct": false, + "construct-only": false, + "default": "encoded (1)", + "enum": true, + "type-name": "GstVideoFormat", + "values": [ + { + "desc": "GST_VIDEO_FORMAT_UNKNOWN", + "name": "unknown", + "value": "0" + }, + { + "desc": "GST_VIDEO_FORMAT_ENCODED", + "name": "encoded", + "value": "1" + }, + { + "desc": "GST_VIDEO_FORMAT_I420", + "name": "i420", + "value": "2" + }, + { + "desc": "GST_VIDEO_FORMAT_YV12", + "name": "yv12", + "value": "3" + }, + { + "desc": "GST_VIDEO_FORMAT_YUY2", + "name": "yuy2", + "value": "4" + }, + { + "desc": "GST_VIDEO_FORMAT_UYVY", + "name": "uyvy", + "value": "5" + }, + { + "desc": "GST_VIDEO_FORMAT_AYUV", + "name": "ayuv", + "value": "6" + }, + { + "desc": "GST_VIDEO_FORMAT_RGBx", + "name": "rgbx", + "value": "7" + }, + { + "desc": "GST_VIDEO_FORMAT_BGRx", + "name": "bgrx", + "value": "8" + }, + { + "desc": "GST_VIDEO_FORMAT_xRGB", + "name": "xrgb", + "value": "9" + }, + { + "desc": "GST_VIDEO_FORMAT_xBGR", + "name": "xbgr", + "value": "10" + }, + { + "desc": "GST_VIDEO_FORMAT_RGBA", + "name": "rgba", + "value": "11" + }, + { + "desc": "GST_VIDEO_FORMAT_BGRA", + "name": "bgra", + "value": "12" + }, + { + "desc": "GST_VIDEO_FORMAT_ARGB", + "name": "argb", + "value": "13" + }, + { + "desc": "GST_VIDEO_FORMAT_ABGR", + "name": "abgr", + "value": "14" + }, + { + "desc": "GST_VIDEO_FORMAT_RGB", + "name": "rgb", + "value": "15" + }, + { + "desc": "GST_VIDEO_FORMAT_BGR", + "name": "bgr", + "value": "16" + }, + { + "desc": "GST_VIDEO_FORMAT_Y41B", + "name": "y41b", + "value": "17" + }, + { + "desc": "GST_VIDEO_FORMAT_Y42B", + "name": "y42b", + "value": "18" + }, + { + "desc": "GST_VIDEO_FORMAT_YVYU", + "name": "yvyu", + "value": "19" + }, + { + "desc": "GST_VIDEO_FORMAT_Y444", + "name": "y444", + "value": "20" + }, + { + "desc": "GST_VIDEO_FORMAT_v210", + "name": "v210", + "value": "21" + }, + { + "desc": "GST_VIDEO_FORMAT_v216", + "name": "v216", + "value": "22" + }, + { + "desc": "GST_VIDEO_FORMAT_NV12", + "name": "nv12", + "value": "23" + }, + { + "desc": "GST_VIDEO_FORMAT_NV21", + "name": "nv21", + "value": "24" + }, + { + "desc": "GST_VIDEO_FORMAT_GRAY8", + "name": "gray8", + "value": "25" + }, + { + "desc": "GST_VIDEO_FORMAT_GRAY16_BE", + "name": "gray16-be", + "value": "26" + }, + { + "desc": "GST_VIDEO_FORMAT_GRAY16_LE", + "name": "gray16-le", + "value": "27" + }, + { + "desc": "GST_VIDEO_FORMAT_v308", + "name": "v308", + "value": "28" + }, + { + "desc": "GST_VIDEO_FORMAT_RGB16", + "name": "rgb16", + "value": "29" + }, + { + "desc": "GST_VIDEO_FORMAT_BGR16", + "name": "bgr16", + "value": "30" + }, + { + "desc": "GST_VIDEO_FORMAT_RGB15", + "name": "rgb15", + "value": "31" + }, + { + "desc": "GST_VIDEO_FORMAT_BGR15", + "name": "bgr15", + "value": "32" + }, + { + "desc": "GST_VIDEO_FORMAT_UYVP", + "name": "uyvp", + "value": "33" + }, + { + "desc": "GST_VIDEO_FORMAT_A420", + "name": "a420", + "value": "34" + }, + { + "desc": "GST_VIDEO_FORMAT_RGB8P", + "name": "rgb8p", + "value": "35" + }, + { + "desc": "GST_VIDEO_FORMAT_YUV9", + "name": "yuv9", + "value": "36" + }, + { + "desc": "GST_VIDEO_FORMAT_YVU9", + "name": "yvu9", + "value": "37" + }, + { + "desc": "GST_VIDEO_FORMAT_IYU1", + "name": "iyu1", + "value": "38" + }, + { + "desc": "GST_VIDEO_FORMAT_ARGB64", + "name": "argb64", + "value": "39" + }, + { + "desc": "GST_VIDEO_FORMAT_AYUV64", + "name": "ayuv64", + "value": "40" + }, + { + "desc": "GST_VIDEO_FORMAT_r210", + "name": "r210", + "value": "41" + }, + { + "desc": "GST_VIDEO_FORMAT_I420_10BE", + "name": "i420-10be", + "value": "42" + }, + { + "desc": "GST_VIDEO_FORMAT_I420_10LE", + "name": "i420-10le", + "value": "43" + }, + { + "desc": "GST_VIDEO_FORMAT_I422_10BE", + "name": "i422-10be", + "value": "44" + }, + { + "desc": "GST_VIDEO_FORMAT_I422_10LE", + "name": "i422-10le", + "value": "45" + }, + { + "desc": "GST_VIDEO_FORMAT_Y444_10BE", + "name": "y444-10be", + "value": "46" + }, + { + "desc": "GST_VIDEO_FORMAT_Y444_10LE", + "name": "y444-10le", + "value": "47" + }, + { + "desc": "GST_VIDEO_FORMAT_GBR", + "name": "gbr", + "value": "48" + }, + { + "desc": "GST_VIDEO_FORMAT_GBR_10BE", + "name": "gbr-10be", + "value": "49" + }, + { + "desc": "GST_VIDEO_FORMAT_GBR_10LE", + "name": "gbr-10le", + "value": "50" + }, + { + "desc": "GST_VIDEO_FORMAT_NV16", + "name": "nv16", + "value": "51" + }, + { + "desc": "GST_VIDEO_FORMAT_NV24", + "name": "nv24", + "value": "52" + }, + { + "desc": "GST_VIDEO_FORMAT_NV12_64Z32", + "name": "nv12-64z32", + "value": "53" + }, + { + "desc": "GST_VIDEO_FORMAT_A420_10BE", + "name": "a420-10be", + "value": "54" + }, + { + "desc": "GST_VIDEO_FORMAT_A420_10LE", + "name": "a420-10le", + "value": "55" + }, + { + "desc": "GST_VIDEO_FORMAT_A422_10BE", + "name": "a422-10be", + "value": "56" + }, + { + "desc": "GST_VIDEO_FORMAT_A422_10LE", + "name": "a422-10le", + "value": "57" + }, + { + "desc": "GST_VIDEO_FORMAT_A444_10BE", + "name": "a444-10be", + "value": "58" + }, + { + "desc": "GST_VIDEO_FORMAT_A444_10LE", + "name": "a444-10le", + "value": "59" + }, + { + "desc": "GST_VIDEO_FORMAT_NV61", + "name": "nv61", + "value": "60" + }, + { + "desc": "GST_VIDEO_FORMAT_P010_10BE", + "name": "p010-10be", + "value": "61" + }, + { + "desc": "GST_VIDEO_FORMAT_P010_10LE", + "name": "p010-10le", + "value": "62" + }, + { + "desc": "GST_VIDEO_FORMAT_IYU2", + "name": "iyu2", + "value": "63" + }, + { + "desc": "GST_VIDEO_FORMAT_VYUY", + "name": "vyuy", + "value": "64" + }, + { + "desc": "GST_VIDEO_FORMAT_GBRA", + "name": "gbra", + "value": "65" + }, + { + "desc": "GST_VIDEO_FORMAT_GBRA_10BE", + "name": "gbra-10be", + "value": "66" + }, + { + "desc": "GST_VIDEO_FORMAT_GBRA_10LE", + "name": "gbra-10le", + "value": "67" + }, + { + "desc": "GST_VIDEO_FORMAT_GBR_12BE", + "name": "gbr-12be", + "value": "68" + }, + { + "desc": "GST_VIDEO_FORMAT_GBR_12LE", + "name": "gbr-12le", + "value": "69" + }, + { + "desc": "GST_VIDEO_FORMAT_GBRA_12BE", + "name": "gbra-12be", + "value": "70" + }, + { + "desc": "GST_VIDEO_FORMAT_GBRA_12LE", + "name": "gbra-12le", + "value": "71" + }, + { + "desc": "GST_VIDEO_FORMAT_I420_12BE", + "name": "i420-12be", + "value": "72" + }, + { + "desc": "GST_VIDEO_FORMAT_I420_12LE", + "name": "i420-12le", + "value": "73" + }, + { + "desc": "GST_VIDEO_FORMAT_I422_12BE", + "name": "i422-12be", + "value": "74" + }, + { + "desc": "GST_VIDEO_FORMAT_I422_12LE", + "name": "i422-12le", + "value": "75" + }, + { + "desc": "GST_VIDEO_FORMAT_Y444_12BE", + "name": "y444-12be", + "value": "76" + }, + { + "desc": "GST_VIDEO_FORMAT_Y444_12LE", + "name": "y444-12le", + "value": "77" + }, + { + "desc": "GST_VIDEO_FORMAT_GRAY10_LE32", + "name": "gray10-le32", + "value": "78" + }, + { + "desc": "GST_VIDEO_FORMAT_NV12_10LE32", + "name": "nv12-10le32", + "value": "79" + }, + { + "desc": "GST_VIDEO_FORMAT_NV16_10LE32", + "name": "nv16-10le32", + "value": "80" + }, + { + "desc": "GST_VIDEO_FORMAT_NV12_10LE40", + "name": "nv12-10le40", + "value": "81" + } + ], + "writable": true + }, + "height": { + "blurb": "Forced output height", + "construct": false, + "construct-only": false, + "default": "0", + "max": "2147483647", + "min": "0", + "type-name": "guint", + "writable": true + }, + "hue": { + "blurb": "The color hue value", + "construct": false, + "construct-only": false, + "default": "0", + "max": "180", + "min": "-180", + "type-name": "gfloat", + "writable": true + }, + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapipostproc0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + }, + "qos": { + "blurb": "Handle Quality-of-Service events", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "saturation": { + "blurb": "The color saturation value", + "construct": false, + "construct-only": false, + "default": "1", + "max": "2", + "min": "0", + "type-name": "gfloat", + "writable": true + }, + "scale-method": { + "blurb": "Scaling method to use", + "construct": false, + "construct-only": false, + "default": "default (0)", + "enum": true, + "type-name": "GstVaapiScaleMethod", + "values": [ + { + "desc": "Default scaling mode", + "name": "default", + "value": "0" + }, + { + "desc": "Fast scaling mode", + "name": "fast", + "value": "1" + }, + { + "desc": "High quality scaling mode", + "name": "hq", + "value": "2" + } + ], + "writable": true + }, + "sharpen": { + "blurb": "The level of sharpening/blurring to apply", + "construct": false, + "construct-only": false, + "default": "0", + "max": "1", + "min": "-1", + "type-name": "gfloat", + "writable": true + }, + "skin-tone-enhancement": { + "blurb": "Apply the skin tone enhancement algorithm", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "width": { + "blurb": "Forced output width", + "construct": false, + "construct-only": false, + "default": "0", + "max": "2147483647", + "min": "0", + "type-name": "guint", + "writable": true + } + }, + "rank": "primary" + }, + "vaapisink": { + "author": "Gwenole Beauchesne ", + "classification": "Sink/Video", + "description": "A VA-API based videosink", + "hierarchy": [ + "GstVaapiSink", + "GstVideoSink", + "GstBaseSink", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Sink/Video", + "long-name": "VA-API sink", + "name": "vaapisink", + "pad-templates": { + "sink": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:VASurface, meta:GstVideoOverlayComposition):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoOverlayComposition):\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "direction": "sink", + "presence": "always" + } + }, + "properties": { + "async": { + "blurb": "Go asynchronously to PAUSED", + "construct": false, + "construct-only": false, + "default": "true", + "type-name": "gboolean", + "writable": true + }, + "blocksize": { + "blurb": "Size in bytes to pull per buffer (0 = default)", + "construct": false, + "construct-only": false, + "default": "4096", + "max": "-1", + "min": "0", + "type-name": "guint", + "writable": true + }, + "brightness": { + "blurb": "The display brightness value", + "construct": true, + "construct-only": false, + "default": "0", + "max": "1", + "min": "-1", + "type-name": "gfloat", + "writable": true + }, + "contrast": { + "blurb": "The display contrast value", + "construct": true, + "construct-only": false, + "default": "1", + "max": "2", + "min": "0", + "type-name": "gfloat", + "writable": true + }, + "display": { + "blurb": "display type to use", + "construct": false, + "construct-only": false, + "default": "any (0)", + "enum": true, + "type-name": "GstVaapiDisplayType", + "values": [ + { + "desc": "Auto detection", + "name": "any", + "value": "0" + }, + { + "desc": "VA/X11 display", + "name": "x11", + "value": "1" + }, + { + "desc": "VA/GLX display", + "name": "glx", + "value": "2" + }, + { + "desc": "VA/EGL display", + "name": "egl", + "value": "5" + }, + { + "desc": "VA/Wayland display", + "name": "wayland", + "value": "3" + }, + { + "desc": "VA/DRM display", + "name": "drm", + "value": "4" + } + ], + "writable": true + }, + "display-name": { + "blurb": "display name to use", + "construct": false, + "construct-only": false, + "default": "NULL", + "type-name": "gchararray", + "writable": true + }, + "enable-last-sample": { + "blurb": "Enable the last-sample property", + "construct": false, + "construct-only": false, + "default": "true", + "type-name": "gboolean", + "writable": true + }, + "force-aspect-ratio": { + "blurb": "When enabled, scaling will respect original aspect ratio", + "construct": false, + "construct-only": false, + "default": "true", + "type-name": "gboolean", + "writable": true + }, + "fullscreen": { + "blurb": "Requests window in fullscreen state", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "hue": { + "blurb": "The display hue value", + "construct": true, + "construct-only": false, + "default": "0", + "max": "180", + "min": "-180", + "type-name": "gfloat", + "writable": true + }, + "last-sample": { + "blurb": "The last sample received in the sink", + "construct": false, + "construct-only": false, + "type-name": "GstSample", + "writable": false + }, + "max-bitrate": { + "blurb": "The maximum bits per second to render (0 = disabled)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "18446744073709551615", + "min": "0", + "type-name": "guint64", + "writable": true + }, + "max-lateness": { + "blurb": "Maximum number of nanoseconds that a buffer can be late before it is dropped (-1 unlimited)", + "construct": false, + "construct-only": false, + "default": "5000000", + "max": "9223372036854775807", + "min": "-1", + "type-name": "gint64", + "writable": true + }, + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapisink0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + }, + "processing-deadline": { + "blurb": "Maximum processing deadline in nanoseconds", + "construct": false, + "construct-only": false, + "default": "15000000", + "max": "18446744073709551615", + "min": "0", + "type-name": "guint64", + "writable": true + }, + "qos": { + "blurb": "Generate Quality-of-Service events upstream", + "construct": false, + "construct-only": false, + "default": "true", + "type-name": "gboolean", + "writable": true + }, + "render-delay": { + "blurb": "Additional render delay of the sink in nanoseconds", + "construct": false, + "construct-only": false, + "default": "0", + "max": "18446744073709551615", + "min": "0", + "type-name": "guint64", + "writable": true + }, + "rotation": { + "blurb": "The display rotation mode", + "construct": false, + "construct-only": false, + "default": "0 (0)", + "enum": true, + "type-name": "GstVaapiRotation", + "values": [ + { + "desc": "Unrotated mode", + "name": "0", + "value": "0" + }, + { + "desc": "Rotated by 90\u00b0, clockwise", + "name": "90", + "value": "90" + }, + { + "desc": "Rotated by 180\u00b0, clockwise", + "name": "180", + "value": "180" + }, + { + "desc": "Rotated by 270\u00b0, clockwise", + "name": "270", + "value": "270" + }, + { + "desc": "Rotated by image-orientating tag\u00b0", + "name": "Automatic", + "value": "360" + } + ], + "writable": true + }, + "saturation": { + "blurb": "The display saturation value", + "construct": true, + "construct-only": false, + "default": "1", + "max": "2", + "min": "0", + "type-name": "gfloat", + "writable": true + }, + "show-preroll-frame": { + "blurb": "Whether to render video frames during preroll", + "construct": true, + "construct-only": false, + "default": "true", + "type-name": "gboolean", + "writable": true + }, + "signal-handoffs": { + "blurb": "Send a signal after rendering the buffer", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "sync": { + "blurb": "Sync on the clock", + "construct": false, + "construct-only": false, + "default": "true", + "type-name": "gboolean", + "writable": true + }, + "throttle-time": { + "blurb": "The time to keep between rendered buffers (0 = disabled)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "18446744073709551615", + "min": "0", + "type-name": "guint64", + "writable": true + }, + "ts-offset": { + "blurb": "Timestamp offset in nanoseconds", + "construct": false, + "construct-only": false, + "default": "0", + "max": "9223372036854775807", + "min": "-9223372036854775808", + "type-name": "gint64", + "writable": true + }, + "view-id": { + "blurb": "ID of the view component of interest to display", + "construct": false, + "construct-only": false, + "default": "-1", + "max": "2147483647", + "min": "-1", + "type-name": "gint", + "writable": true + } + }, + "rank": "primary", + "signals": { + "handoff": { + "args": [ + "GstBuffer" + ], + "retval": "void" + } + } + }, + "vaapivc1dec": { + "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", + "classification": "Codec/Decoder/Video", + "description": "A VA-API based VC1 video decoder", + "hierarchy": [ + "GstVaapiDecode_vc1", + "GstVideoDecoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Decoder/Video", + "long-name": "VA-API VC1 decoder", + "name": "vaapivc1dec", + "pad-templates": { + "sink": { + "caps": "video/x-wmv:\n wmvversion: 3\n format: { WMV3, WVC1 }\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapidecode_vc1-0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + } + }, + "rank": "primary" + }, + "vaapivp8dec": { + "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", + "classification": "Codec/Decoder/Video", + "description": "A VA-API based VP8 video decoder", + "hierarchy": [ + "GstVaapiDecode_vp8", + "GstVideoDecoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Decoder/Video", + "long-name": "VA-API VP8 decoder", + "name": "vaapivp8dec", + "pad-templates": { + "sink": { + "caps": "video/x-vp8:\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapidecode_vp8-0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + } + }, + "rank": "primary" + }, + "vaapivp8enc": { + "author": "Sreerenj Balachandran ", + "classification": "Codec/Encoder/Video", + "description": "A VA-API based VP8 video encoder", + "hierarchy": [ + "GstVaapiEncodeVP8", + "GstVaapiEncode", + "GstVideoEncoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Encoder/Video", + "long-name": "VA-API VP8 encoder", + "name": "vaapivp8enc", + "pad-templates": { + "sink": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-vp8:\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "bitrate": { + "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "102400", + "min": "0", + "type-name": "guint", + "writable": true + }, + "default-roi-delta-qp": { + "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", + "construct": false, + "construct-only": false, + "default": "-10", + "max": "10", + "min": "-10", + "type-name": "gint", + "writable": true + }, + "keyframe-period": { + "blurb": "Maximal distance between two keyframes (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "30", + "max": "-1", + "min": "0", + "type-name": "guint", + "writable": true + }, + "loop-filter-level": { + "blurb": "Controls the deblocking filter strength", + "construct": false, + "construct-only": false, + "default": "0", + "max": "63", + "min": "0", + "type-name": "guint", + "writable": true + }, + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapiencodevp8-0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + }, + "qos": { + "blurb": "Handle Quality-of-Service events from downstream", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "quality-level": { + "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", + "construct": false, + "construct-only": false, + "default": "4", + "max": "7", + "min": "1", + "type-name": "guint", + "writable": true + }, + "rate-control": { + "blurb": "Rate control mode", + "construct": false, + "construct-only": false, + "default": "cqp (1)", + "enum": true, + "type-name": "GstVaapiRateControlVP8", + "values": [ + { + "desc": "Constant QP", + "name": "cqp", + "value": "1" + }, + { + "desc": "Constant bitrate", + "name": "cbr", + "value": "2" + }, + { + "desc": "Variable bitrate", + "name": "vbr", + "value": "4" + } + ], + "writable": true + }, + "sharpness-level": { + "blurb": "Controls the deblocking filter sensitivity", + "construct": false, + "construct-only": false, + "default": "0", + "max": "7", + "min": "0", + "type-name": "guint", + "writable": true + }, + "tune": { + "blurb": "Encoder tuning option", + "construct": false, + "construct-only": false, + "default": "none (0)", + "enum": true, + "type-name": "GstVaapiEncoderTuneVP8", + "values": [ + { + "desc": "None", + "name": "none", + "value": "0" + } + ], + "writable": true + }, + "yac-qi": { + "blurb": "Quantization Table index for Luma AC Coefficients, (in default case, yac_qi=4 for key frames and yac_qi=40 for P frames)", + "construct": false, + "construct-only": false, + "default": "40", + "max": "127", + "min": "0", + "type-name": "guint", + "writable": true + } + }, + "rank": "primary" + }, + "vaapivp9dec": { + "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", + "classification": "Codec/Decoder/Video", + "description": "A VA-API based VP9 video decoder", + "hierarchy": [ + "GstVaapiDecode_vp9", + "GstVideoDecoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Decoder/Video", + "long-name": "VA-API VP9 decoder", + "name": "vaapivp9dec", + "pad-templates": { + "sink": { + "caps": "video/x-vp9:\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapidecode_vp9-0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + } + }, + "rank": "primary" + }, + "vaapivp9enc": { + "author": "Sreerenj Balachandran ", + "classification": "Codec/Encoder/Video", + "description": "A VA-API based VP9 video encoder", + "hierarchy": [ + "GstVaapiEncodeVP9", + "GstVaapiEncode", + "GstVideoEncoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Codec/Encoder/Video", + "long-name": "VA-API VP9 encoder", + "name": "vaapivp9enc", + "pad-templates": { + "sink": { + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/x-vp9:\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "bitrate": { + "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "0", + "max": "102400", + "min": "0", + "type-name": "guint", + "writable": true + }, + "cpb-length": { + "blurb": "Length of the CPB_buffer/window_size in milliseconds", + "construct": false, + "construct-only": false, + "default": "1500", + "max": "10000", + "min": "1", + "type-name": "guint", + "writable": true + }, + "default-roi-delta-qp": { + "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", + "construct": false, + "construct-only": false, + "default": "-10", + "max": "10", + "min": "-10", + "type-name": "gint", + "writable": true + }, + "keyframe-period": { + "blurb": "Maximal distance between two keyframes (0: auto-calculate)", + "construct": false, + "construct-only": false, + "default": "30", + "max": "-1", + "min": "0", + "type-name": "guint", + "writable": true + }, + "loop-filter-level": { + "blurb": "Controls the deblocking filter strength", + "construct": false, + "construct-only": false, + "default": "10", + "max": "63", + "min": "0", + "type-name": "guint", + "writable": true + }, + "name": { + "blurb": "The name of the object", + "construct": true, + "construct-only": false, + "default": "vaapiencodevp9-0", + "hotdoc-fixed-default": true, + "type-name": "gchararray", + "writable": true + }, + "parent": { + "blurb": "The parent of the object", + "construct": false, + "construct-only": false, + "type-name": "GstObject", + "writable": true + }, + "qos": { + "blurb": "Handle Quality-of-Service events from downstream", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, + "quality-level": { + "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", + "construct": false, + "construct-only": false, + "default": "4", + "max": "7", + "min": "1", + "type-name": "guint", + "writable": true + }, + "rate-control": { + "blurb": "Rate control mode", + "construct": false, + "construct-only": false, + "default": "cqp (1)", + "enum": true, + "type-name": "GstVaapiRateControlVP9", + "values": [ + { + "desc": "Constant QP", + "name": "cqp", + "value": "1" + }, + { + "desc": "Constant bitrate", + "name": "cbr", + "value": "2" + }, + { + "desc": "Variable bitrate", + "name": "vbr", + "value": "4" + } + ], + "writable": true + }, + "ref-pic-mode": { + "blurb": "Reference Picture Selection Modes", + "construct": false, + "construct-only": false, + "default": "mode-0 (0)", + "enum": true, + "type-name": "GstVaapiEncoderVP9RefPicMode", + "values": [ + { + "desc": "Use Keyframe(Alt & Gold) and Previousframe(Last) for prediction ", + "name": "mode-0", + "value": "0" + }, + { + "desc": "Use last three frames for prediction (n:Last n-1:Gold n-2:Alt)", + "name": "mode-1", + "value": "1" + } + ], + "writable": true + }, + "sharpness-level": { + "blurb": "Controls the deblocking filter sensitivity", + "construct": false, + "construct-only": false, + "default": "0", + "max": "7", + "min": "0", + "type-name": "guint", + "writable": true + }, + "tune": { + "blurb": "Encoder tuning option", + "construct": false, + "construct-only": false, + "default": "none (0)", + "enum": true, + "type-name": "GstVaapiEncoderTuneVP9", + "values": [ + { + "desc": "None", + "name": "none", + "value": "0" + } + ], + "writable": true + }, + "yac-qi": { + "blurb": "Quantization Table index for Luma AC Coefficients", + "construct": false, + "construct-only": false, + "default": "60", + "max": "255", + "min": "0", + "type-name": "guint", + "writable": true + } + }, + "rank": "primary" + } + }, + "filename": "libgstvaapi.so", + "license": "LGPL", + "package": "gstreamer-vaapi", + "source": "gstreamer-vaapi", + "url": "http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer" + } +} \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000..b95c2a7d70 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,29 @@ +--- +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. diff --git a/docs/meson.build b/docs/meson.build new file mode 100644 index 0000000000..8eca23c98e --- /dev/null +++ b/docs/meson.build @@ -0,0 +1,62 @@ +build_hotdoc = false + +if meson.is_cross_build() + if get_option('doc').enabled() + error('Documentation enabled but building the doc while cross building is not supported yet.') + endif + + message('Documentation not built as building 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_pkg_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', + ) +else + warning('GStreamer plugin inspector for documentation not found, can\'t update the cache') +endif + +hotdoc_p = find_program('hotdoc', required: get_option('doc')) +if not hotdoc_p.found() + message('Hotdoc not found, not building the documentation') + subdir_done() +endif + +build_hotdoc = true +hotdoc = import('hotdoc') +if not hotdoc.has_extensions(required_hotdoc_extensions) + if get_option('doc').enabled() + error('Documentation enabled but gi-extension missing') + endif + + message('@0@ extensions not found, not building documentation'.format(required_hotdoc_extensions)) + subdir_done() +endif + +message('Plugins: @0@'.format(plugins)) +libs_doc = [] +plugins_doc = [hotdoc.generate_doc('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, +)] diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am deleted file mode 100644 index 7701535c7b..0000000000 --- a/docs/plugins/Makefile.am +++ /dev/null @@ -1,92 +0,0 @@ -GST_DOC_SCANOBJ = $(top_srcdir)/common/gstdoc-scangobj - -## Process this file with automake to produce Makefile.in - -# The name of the module, e.g. 'glib'. -MODULE=gstreamer-vaapi -DOC_MODULE=$(MODULE)-plugins - -# for upload-doc.mak -DOC=$(MODULE)-plugins -FORMATS=html -html: html-build.stamp -include $(top_srcdir)/common/upload-doc.mak - -# The top-level SGML file. You can change this if you want to. -DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml - -# The directory containing the source code. Relative to $(srcdir). -# gtk-doc will search all .c & .h files beneath here for inline comments -# documenting the functions and macros. -DOC_SOURCE_DIR = $(top_srcdir)/gst - -# Extra options to supply to gtkdoc-scan. -SCAN_OPTIONS = --deprecated-guards="GST_VAAPI_DISABLE_DEPRECATED" - -# Extra options to supply to gtkdoc-mkdb. -MKDB_OPTIONS = --sgml-mode --source-suffixes=c,h,cc,m - -# Extra options to supply to gtkdoc-fixref. -FIXXREF_OPTIONS=--extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html \ - --extra-dir=$(GST_PREFIX)/share/gtk-doc/html \ - --extra-dir=$(GSTPB_PREFIX)/share/gtk-doc/html - -# Used for dependencies. The docs will be rebuilt if any of these change. -# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h -# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB = $(top_srcdir)/gst/*/*.h -CFILE_GLOB = $(top_srcdir)/gst/*/*.c - -# Header files to ignore when scanning. -IGNORE_HFILES = -EXTRA_HFILES = - -# we add all .h files of elements that have signals/args we want -# sadly this also pulls in the private methods - maybe we should -# move those around in the source ? -# -# also, we should add some stuff here conditionally based on whether -# or not the plugin will actually build -# but I'm not sure about that - it might be this Just Works given that -# the registry won't have the element -# -> it just works (TM) (ensonic) - -# FIXME: not ported yet -# $(top_srcdir)/ext/gnomevfs/gstgnomevfssink.c - -# example code that needs to be converted to xml and placed in xml/ -EXAMPLE_CFILES = - -# Images to copy into HTML directory. -HTML_IMAGES = - -# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). -content_files = running.xml - -# Other files to distribute. -extra_files = - -# CFLAGS and LDFLAGS for compiling scan program. Only needed if your app/lib -# contains GtkObjects/GObjects and you want to document signals and properties. -GTKDOC_CFLAGS = -DGST_USE_UNSTABLE_API $(GST_PLUGINS_BAD_CFLAGS) $(GST_BASE_CFLAGS) -I$(top_builddir) -I$(top_builddir)/gst-libs/ -GTKDOC_LIBS = $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la $(top_builddir)/gst/vaapi/libgstvaapi.la $(GST_BASE_LIBS) - -# If you need to override some of the declarations, place them in this file -# and uncomment this line. -#DOC_OVERRIDES = $(DOC_MODULE)-overrides.txt -DOC_OVERRIDES = - -# This includes the standard gtk-doc make rules, copied by gtkdocize. -include $(top_srcdir)/common/gtk-doc-plugins.mak - -SUBDIRS = - -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES += \ - gstreamer-vaapi-plugins.* \ - *.stamp inspect \ - gstreamer-vaapi-plugins-overrides.txt \ - gstreamer-vaapi-plugins-sections.new \ - $(NULL) - --include $(top_srcdir)/git.mk diff --git a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in b/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in deleted file mode 100644 index 37351d96ce..0000000000 --- a/docs/plugins/gstreamer-vaapi-plugins-docs.xml.in +++ /dev/null @@ -1,55 +0,0 @@ - - -]> - - - GStreamer VA-API Plugins @GST_API_VERSION@ Plugins Reference Manual - - - - gstremaer-vaapi Overview - - - - - gstreamer-vaapi Elements - - - - - - - - - - - - - - - - - - - - - - gstreamer-vaapi Plugins - - - - - Object Hierarchy - - - - - API Index - - - - - diff --git a/docs/plugins/gstreamer-vaapi-plugins-sections.txt b/docs/plugins/gstreamer-vaapi-plugins-sections.txt deleted file mode 100644 index 2833db3d5a..0000000000 --- a/docs/plugins/gstreamer-vaapi-plugins-sections.txt +++ /dev/null @@ -1,209 +0,0 @@ -
- -
-element-vaapijpegdec -vaapijpegdec - -GstVaapiDecode_jpeg -GstVaapiDecode_jpegClass -
- -
-element-vaapimpeg2dec -vaapimpeg2dec - -GstVaapiDecode_mpeg2 -GstVaapiDecode_mpeg2Class -
- -
-element-vaapimpeg4dec -vaapimpeg4dec - -GstVaapiDecode_mpeg4 -GstVaapiDecode_mpeg4Class -
- -
-element-vaapih263dec -vaapih263dec - -GstVaapiDecode_h263 -GstVaapiDecode_h263Class -
- -
-element-vaapih264dec -vaapih264dec - -GstVaapiDecode_h264 -GstVaapiDecode_h264Class -
- -
-element-vaapih265dec -vaapih265dec - -GstVaapiDecode_h265 -GstVaapiDecode_h265Class -
- -
-element-vaapivc1dec -vaapivc1dec - -GstVaapiDecode_vc1 -GstVaapiDecode_vc1Class -
- -
-element-vaapivp8dec -vaapivp8dec - -GstVaapiDecode_vp8 -GstVaapiDecode_vp8Class -
- -
-element-vaapivp9dec -vaapivp9dec - -GstVaapiDecode_vp9 -GstVaapiDecode_vp9Class -
- -
-element-vaapidecodebin -vaapidecodebin - -GST_IS_AUTO_DETECT -GST_IS_AUTO_DETECT_CLASS -GST_TYPE_VAAPI_DECODE_BIN -GST_VAAPI_DECODE_BIN -GST_VAAPI_DECODE_BIN_CLASS -GST_VAAPI_DECODE_BIN_GET_CLASS -GstVaapiDecodeBin -GstVaapiDecodeBinClass -gst_vaapi_decode_bin_get_type -
- -
-element-vaapipostproc -vaapipostproc -GstVaapiDeinterlaceMode - -GST_IS_VAAPIPOSTPROC -GST_IS_VAAPIPOSTPROC_CLASS -GST_TYPE_VAAPIPOSTPROC -GST_VAAPIPOSTPROC -GST_VAAPIPOSTPROC_CLASS -GST_VAAPIPOSTPROC_GET_CLASS -GstVaapiPostproc -GstVaapiPostprocClass -gst_vaapipostproc_get_type -
- -
-element-vaapisink -vaapisink - -GST_IS_VAAPISINK -GST_IS_VAAPISINK_CLASS -GST_TYPE_VAAPISINK -GST_VAAPISINK -GST_VAAPISINK_CLASS -GST_VAAPISINK_GET_CLASS -GstVaapiSink -GstVaapiSinkClass -gst_vaapisink_get_type -
- -
-element-vaapih264enc -vaapih264enc - -GST_IS_VAAPIENCODE_H264 -GST_IS_VAAPIENCODE_H264_CLASS -GST_TYPE_VAAPIENCODE_H264 -GST_VAAPIENCODE_H264 -GST_VAAPIENCODE_H264_CLASS -GST_VAAPIENCODE_H264_GET_CLASS -GstVaapiEncodeH264 -GstVaapiEncodeH264Class -gst_vaapiencode_h264_get_type -
- -
-element-vaapih265enc -vaapih265enc - -GST_IS_VAAPIENCODE_H265 -GST_IS_VAAPIENCODE_H265_CLASS -GST_TYPE_VAAPIENCODE_H265 -GST_VAAPIENCODE_H265 -GST_VAAPIENCODE_H265_CLASS -GST_VAAPIENCODE_H265_GET_CLASS -GstVaapiEncodeH265 -GstVaapiEncodeH265Class -gst_vaapiencode_h265_get_type -
- -
-element-vaapijpegenc -vaapijpegenc - -GST_IS_VAAPIENCODE_JPEG -GST_IS_VAAPIENCODE_JPEG_CLASS -GST_TYPE_VAAPIENCODE_JPEG -GST_VAAPIENCODE_JPEG -GST_VAAPIENCODE_JPEG_CLASS -GST_VAAPIENCODE_JPEG_GET_CLASS -GstVaapiEncodeJpeg -GstVaapiEncodeJpegClass -gst_vaapiencode_jpeg_get_type -
- -
-element-vaapimpeg2enc -vaapimpeg2enc - -GST_IS_VAAPIENCODE_MPEG2 -GST_IS_VAAPIENCODE_MPEG2_CLASS -GST_TYPE_VAAPIENCODE_MPEG2 -GST_VAAPIENCODE_MPEG2 -GST_VAAPIENCODE_MPEG2_CLASS -GST_VAAPIENCODE_MPEG2_GET_CLASS -GstVaapiEncodeMpeg2 -GstVaapiEncodeMpeg2Class -gst_vaapiencode_mpeg2_get_type -
- -
-element-vaapivp8enc -vaapivp8enc - -GST_IS_VAAPIENCODE_VP8 -GST_IS_VAAPIENCODE_VP8_CLASS -GST_TYPE_VAAPIENCODE_VP8 -GST_VAAPIENCODE_VP8 -GST_VAAPIENCODE_VP8_CLASS -GST_VAAPIENCODE_VP8_GET_CLASS -GstVaapiEncodeVP8 -GstVaapiEncodeVP8Class -gst_vaapiencode_vp8_get_type -
- -
-element-vaapivp9enc -vaapivp9enc - -GST_IS_VAAPIENCODE_VP9 -GST_IS_VAAPIENCODE_VP9_CLASS -GST_TYPE_VAAPIENCODE_VP9 -GST_VAAPIENCODE_VP9 -GST_VAAPIENCODE_VP9_CLASS -GST_VAAPIENCODE_VP9_GET_CLASS -GstVaapiEncodeVP9 -GstVaapiEncodeVP9Class -gst_vaapiencode_vp9_get_type -
diff --git a/docs/plugins/gstreamer-vaapi-plugins.types b/docs/plugins/gstreamer-vaapi-plugins.types deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/plugins/inspect/plugin-vaapi.xml b/docs/plugins/inspect/plugin-vaapi.xml deleted file mode 100644 index c342f1608b..0000000000 --- a/docs/plugins/inspect/plugin-vaapi.xml +++ /dev/null @@ -1,196 +0,0 @@ - - vaapi - VA-API based elements - ../../gst/vaapi/.libs/libgstvaapi.so - libgstvaapi.so - 1.17.0.1 - LGPL - gstreamer-vaapi - gstreamer-vaapi - http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer - - - vaapidecodebin - VA-API Decode Bin - Codec/Decoder/Video - A VA-API based bin with a decoder and a postprocessor - Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Victor Jaquez <victorx.jaquez@intel.com> - - - sink - sink - always -
video/mpeg, mpegversion=(int)2, systemstream=(boolean)false; video/mpeg, mpegversion=(int)4; video/x-divx; video/x-xvid; video/x-h263; video/x-h264; video/x-h265; video/x-wmv; video/x-vp8; video/x-vp9
-
- - src - source - always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
-
-
-
- - vaapih264dec - VA-API H264 decoder - Codec/Decoder/Video/Hardware - A VA-API based H264 video decoder - Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> - - - sink - sink - always -
video/x-h264
-
- - src - source - always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - vaapih264enc - VA-API H264 encoder - Codec/Encoder/Video/Hardware - A VA-API based H264 video encoder - Wind Yuan <feng.yuan@intel.com> - - - sink - sink - always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
-
- - src - source - always -
video/x-h264, stream-format=(string){ avc, byte-stream }, alignment=(string)au, profile=(string){ constrained-baseline, baseline, main, high, multiview-high, stereo-high }
-
-
-
- - vaapijpegdec - VA-API JPEG decoder - Codec/Decoder/Video/Hardware - A VA-API based JPEG video decoder - Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> - - - sink - sink - always -
image/jpeg
-
- - src - source - always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - vaapimpeg2dec - VA-API MPEG2 decoder - Codec/Decoder/Video/Hardware - A VA-API based MPEG2 video decoder - Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> - - - sink - sink - always -
video/mpeg, mpegversion=(int)2, systemstream=(boolean)false
-
- - src - source - always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - vaapimpeg2enc - VA-API MPEG-2 encoder - Codec/Encoder/Video/Hardware - A VA-API based MPEG-2 video encoder - Guangxin Xu <guangxin.xu@intel.com> - - - sink - sink - always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive
-
- - src - source - always -
video/mpeg, mpegversion=(int)2, systemstream=(boolean)false
-
-
-
- - vaapipostproc - VA-API video postprocessing - Filter/Converter/Effect/Video/Scaler/Deinterlace/Hardware - A VA-API video postprocessing filter - Gwenole Beauchesne <gwenole.beauchesne@intel.com> - - - sink - sink - always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }
-
- - src - source - always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string)progressive; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ], interlace-mode=(string){ progressive, interleaved, mixed }; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - vaapisink - VA-API sink - Sink/Video - A VA-API based videosink - Gwenole Beauchesne <gwenole.beauchesne@intel.com> - - - sink - sink - always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:VASurface, meta:GstVideoOverlayComposition), format=(string){ ENCODED, NV12, I420, YV12, P010_10LE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoOverlayComposition), format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - vaapivc1dec - VA-API VC1 decoder - Codec/Decoder/Video/Hardware - A VA-API based VC1 video decoder - Gwenole Beauchesne <gwenole.beauchesne@intel.com>, Halley Zhao <halley.zhao@intel.com>, Sreerenj Balachandran <sreerenj.balachandran@intel.com>, Wind Yuan <feng.yuan@intel.com> - - - sink - sink - always -
video/x-wmv, wmvversion=(int)3, format=(string){ WMV3, WVC1 }
-
- - src - source - always -
video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(meta:GstVideoGLTextureUploadMeta), format=(string){ RGBA, BGRA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
-
-
\ No newline at end of file diff --git a/docs/plugins/running.xml b/docs/plugins/running.xml deleted file mode 100644 index f7d98cb021..0000000000 --- a/docs/plugins/running.xml +++ /dev/null @@ -1,68 +0,0 @@ - - -%version-entities; - -]> - - -Running GStreamer VAAPI Applications - - - -Running GStreamer VAAPI Applications - -How to run GStreamer application with VAAPI elements. - - - - -Running GStreamer VAAPI Applications - - -Environment variables - - -GStreamer-VAAPI inspects a few of environment variables to define it usage. - - - - <envar>GST_VAAPI_ALL_DRIVERS</envar> - - -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. - - - - - - <envar>LIBVA_DRIVER_NAME</envar> - - -This environment variable can be set with the drivers name to load. For -example, intel's driver is i915, meanwhile mesa is -gallium. - - - - - - <envar>LIBVA_DRIVERS_PATH</envar> - - -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. - - - - - - - - - diff --git a/docs/sitemap.txt b/docs/sitemap.txt new file mode 100644 index 0000000000..058a2713a4 --- /dev/null +++ b/docs/sitemap.txt @@ -0,0 +1 @@ +gst-index diff --git a/docs/version.entities.in b/docs/version.entities.in deleted file mode 100644 index 286989f56e..0000000000 --- a/docs/version.entities.in +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/gst/vaapi/meson.build b/gst/vaapi/meson.build index 3bed11cfab..76b122cc32 100644 --- a/gst/vaapi/meson.build +++ b/gst/vaapi/meson.build @@ -48,3 +48,5 @@ gstvaapi = library('gstvaapi', install : true, install_dir : plugins_install_dir, ) + +plugins = [gstvaapi] diff --git a/meson.build b/meson.build index b23d25a654..7fc19b796a 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('gstreamer-vaapi', 'c', version : '1.17.0.1', - meson_version : '>= 0.47.0', + meson_version : '>= 0.48.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) @@ -163,6 +163,7 @@ subdir('gst') if not get_option('examples').disabled() subdir('tests') endif +subdir('docs') python3 = import('python').find_installation() run_command(python3, '-c', 'import shutil; shutil.copy("hooks/pre-commit.hook", ".git/hooks/pre-commit")') diff --git a/meson_options.txt b/meson_options.txt index f2b50f866f..24b2c3b044 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -7,4 +7,5 @@ option('with_egl', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'aut # Common feature options option('examples', type : 'feature', value : 'auto', yield : true) -option('gtk_doc', type : 'feature', value : 'auto', yield : true, description : 'Build API documentation with gtk-doc') +option('doc', type : 'feature', value : 'auto', yield: true, + description: 'Enable documentation.') From 4fe9c0535f0a155dda44f8fab45be39ce6d6bed1 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 13 May 2019 19:05:43 -0400 Subject: [PATCH 3260/3781] meson: Fix call to wrong function --- docs/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/meson.build b/docs/meson.build index 8eca23c98e..280cedbb12 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -14,7 +14,7 @@ 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_pkg_variable('libexecdir'), 'gstreamer-' + api_version, 'gst-plugins-doc-cache-generator'), + plugins_cache_generator = find_program(join_paths(gst_dep.get_pkgconfig_variable('libexecdir'), 'gstreamer-' + api_version, 'gst-plugins-doc-cache-generator'), required: false) endif From bc1ca96e67a303eee635ba0c19b810ef5693b31d Mon Sep 17 00:00:00 2001 From: Wangfei Date: Thu, 16 May 2019 10:05:17 +0800 Subject: [PATCH 3261/3781] libs: enc: h265: reset num_ref_idx_l1_active_minus1 when low delay B. When enable low delay B, the reference list 1 will be same with reference list 0, so need reset the num_ref_idx_l1_active_minus1 to num_ref_idx_l0_active_minus1. Fixes: #160 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 53c22121ca..c9f162892d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1721,6 +1721,9 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; else slice_param->num_ref_idx_l1_active_minus1 = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->low_delay_b) + slice_param->num_ref_idx_l1_active_minus1 = + slice_param->num_ref_idx_l0_active_minus1; i_ref = 0; if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { From bd549246d41b6be6630c9d7d5357d3e97fb7c308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 16 May 2019 16:46:43 +0200 Subject: [PATCH 3262/3781] libs: surface: fix documentation format --- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index a80b9dbf3e..844eaf28ce 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -116,7 +116,7 @@ typedef enum } GstVaapiSurfaceStatus; /** - * GstVaapiSurfaceRenderFlags + * GstVaapiSurfaceRenderFlags: * @GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: * selects the top field of the surface * @GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: From 879e1081a0c407607b1c100bac2b8ffac026420a Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Thu, 16 May 2019 09:22:42 -0400 Subject: [PATCH 3263/3781] docs: Update plugin cache Fixes https://gitlab.freedesktop.org/gstreamer/gst-docs/issues/36 --- docs/gst_plugins_cache.json | 146 +++++++++++++++++++++++++++--------- 1 file changed, 110 insertions(+), 36 deletions(-) diff --git a/docs/gst_plugins_cache.json b/docs/gst_plugins_cache.json index 8e6bfd185f..4e15a6181d 100644 --- a/docs/gst_plugins_cache.json +++ b/docs/gst_plugins_cache.json @@ -24,7 +24,7 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", "direction": "src", "presence": "always" } @@ -124,7 +124,7 @@ "blurb": "The name of the object", "construct": true, "construct-only": false, - "default": "vaapidecodebin0", + "default": "NULL", "hotdoc-fixed-default": true, "type-name": "gchararray", "writable": true @@ -151,7 +151,7 @@ "GInitiallyUnowned", "GObject" ], - "klass": "Codec/Decoder/Video", + "klass": "Codec/Decoder/Video/Hardware", "long-name": "VA-API H264 decoder", "name": "vaapih264dec", "pad-templates": { @@ -161,7 +161,7 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } @@ -187,7 +187,7 @@ "blurb": "The name of the object", "construct": true, "construct-only": false, - "default": "vaapidecode_h264-0", + "default": "NULL", "hotdoc-fixed-default": true, "type-name": "gchararray", "writable": true @@ -215,12 +215,12 @@ "GInitiallyUnowned", "GObject" ], - "klass": "Codec/Encoder/Video", + "klass": "Codec/Encoder/Video/Hardware", "long-name": "VA-API H264 encoder", "name": "vaapih264enc", "pad-templates": { "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", "direction": "sink", "presence": "always" }, @@ -312,7 +312,7 @@ "construct-only": false, "default": "26", "max": "51", - "min": "1", + "min": "0", "type-name": "guint", "writable": true }, @@ -368,7 +368,7 @@ "construct-only": false, "default": "1", "max": "51", - "min": "1", + "min": "0", "type-name": "guint", "writable": true }, @@ -376,7 +376,7 @@ "blurb": "The name of the object", "construct": true, "construct-only": false, - "default": "vaapiencodeh264-0", + "default": "NULL", "hotdoc-fixed-default": true, "type-name": "gchararray", "writable": true @@ -513,6 +513,16 @@ "type-name": "guint", "writable": true }, + "target-percentage": { + "blurb": "The desired target percentage of bitrate for variable rate controls.", + "construct": false, + "construct-only": false, + "default": "70", + "max": "100", + "min": "1", + "type-name": "guint", + "writable": true + }, "temporal-levels": { "blurb": "Number of temporal levels in the encoded stream ", "construct": false, @@ -523,6 +533,14 @@ "type-name": "guint", "writable": true }, + "trellis": { + "blurb": "The Trellis Quantization Method of Encoder", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, "tune": { "blurb": "Encoder tuning option", "construct": false, @@ -553,7 +571,7 @@ "blurb": "Set of View Ids used for MVC encoding", "construct": false, "construct-only": false, - "type-name": "GValueArray", + "type-name": "GstValueArray", "writable": true } }, @@ -571,7 +589,7 @@ "GInitiallyUnowned", "GObject" ], - "klass": "Codec/Decoder/Video", + "klass": "Codec/Decoder/Video/Hardware", "long-name": "VA-API H265 decoder", "name": "vaapih265dec", "pad-templates": { @@ -581,7 +599,7 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } @@ -591,7 +609,7 @@ "blurb": "The name of the object", "construct": true, "construct-only": false, - "default": "vaapidecode_h265-0", + "default": "NULL", "hotdoc-fixed-default": true, "type-name": "gchararray", "writable": true @@ -619,12 +637,12 @@ "GInitiallyUnowned", "GObject" ], - "klass": "Codec/Encoder/Video", + "klass": "Codec/Encoder/Video/Hardware", "long-name": "VA-API H265 encoder", "name": "vaapih265enc", "pad-templates": { "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", "direction": "sink", "presence": "always" }, @@ -671,7 +689,7 @@ "construct-only": false, "default": "26", "max": "51", - "min": "1", + "min": "0", "type-name": "guint", "writable": true }, @@ -735,7 +753,7 @@ "construct-only": false, "default": "1", "max": "51", - "min": "1", + "min": "0", "type-name": "guint", "writable": true }, @@ -743,7 +761,7 @@ "blurb": "The name of the object", "construct": true, "construct-only": false, - "default": "vaapiencodeh265-0", + "default": "NULL", "hotdoc-fixed-default": true, "type-name": "gchararray", "writable": true @@ -839,6 +857,24 @@ "type-name": "guint", "writable": true }, + "target-percentage": { + "blurb": "The desired target percentage of bitrate for variable rate controls.", + "construct": false, + "construct-only": false, + "default": "70", + "max": "100", + "min": "1", + "type-name": "guint", + "writable": true + }, + "trellis": { + "blurb": "The Trellis Quantization Method of Encoder", + "construct": false, + "construct-only": false, + "default": "false", + "type-name": "gboolean", + "writable": true + }, "tune": { "blurb": "Encoder tuning option", "construct": false, @@ -851,6 +887,11 @@ "desc": "None", "name": "none", "value": "0" + }, + { + "desc": "Low power mode", + "name": "low-power", + "value": "3" } ], "writable": true @@ -870,7 +911,7 @@ "GInitiallyUnowned", "GObject" ], - "klass": "Codec/Decoder/Video", + "klass": "Codec/Decoder/Video/Hardware", "long-name": "VA-API JPEG decoder", "name": "vaapijpegdec", "pad-templates": { @@ -880,7 +921,7 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } @@ -890,7 +931,7 @@ "blurb": "The name of the object", "construct": true, "construct-only": false, - "default": "vaapidecode_jpeg0", + "default": "NULL", "hotdoc-fixed-default": true, "type-name": "gchararray", "writable": true @@ -1055,7 +1096,7 @@ "GInitiallyUnowned", "GObject" ], - "klass": "Codec/Decoder/Video", + "klass": "Codec/Decoder/Video/Hardware", "long-name": "VA-API MPEG2 decoder", "name": "vaapimpeg2dec", "pad-templates": { @@ -1065,7 +1106,7 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } @@ -1075,7 +1116,7 @@ "blurb": "The name of the object", "construct": true, "construct-only": false, - "default": "vaapidecode_mpeg2-0", + "default": "NULL", "hotdoc-fixed-default": true, "type-name": "gchararray", "writable": true @@ -1255,17 +1296,17 @@ "GInitiallyUnowned", "GObject" ], - "klass": "Filter/Converter/Video;Filter/Converter/Video/Scaler;Filter/Effect/Video;Filter/Effect/Video/Deinterlace", + "klass": "Filter/Converter/Effect/Video/Scaler/Deinterlace/Hardware", "long-name": "VA-API video postprocessing", "name": "vaapipostproc", "pad-templates": { "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\n", "direction": "sink", "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } @@ -1788,6 +1829,31 @@ "desc": "GST_VIDEO_FORMAT_NV12_10LE40", "name": "nv12-10le40", "value": "81" + }, + { + "desc": "GST_VIDEO_FORMAT_Y210", + "name": "y210", + "value": "82" + }, + { + "desc": "GST_VIDEO_FORMAT_Y410", + "name": "y410", + "value": "83" + }, + { + "desc": "GST_VIDEO_FORMAT_VUYA", + "name": "vuya", + "value": "84" + }, + { + "desc": "GST_VIDEO_FORMAT_BGR10A2_LE", + "name": "bgr10a2-le", + "value": "85" + }, + { + "desc": "GST_VIDEO_FORMAT_RGB10A2_LE", + "name": "rgb10a2-le", + "value": "86" } ], "writable": true @@ -1816,7 +1882,7 @@ "blurb": "The name of the object", "construct": true, "construct-only": false, - "default": "vaapipostproc0", + "default": "NULL", "hotdoc-fixed-default": true, "type-name": "gchararray", "writable": true @@ -1921,7 +1987,7 @@ "name": "vaapisink", "pad-templates": { "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:VASurface, meta:GstVideoOverlayComposition):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoOverlayComposition):\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:VASurface, meta:GstVideoOverlayComposition):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoOverlayComposition):\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "sink", "presence": "always" } @@ -2079,7 +2145,7 @@ "blurb": "The name of the object", "construct": true, "construct-only": false, - "default": "vaapisink0", + "default": "NULL", "hotdoc-fixed-default": true, "type-name": "gchararray", "writable": true @@ -2181,6 +2247,14 @@ "type-name": "gboolean", "writable": true }, + "stats": { + "blurb": "Sink Statistics", + "construct": false, + "construct-only": false, + "default": "application/x-gst-base-sink-stats, average-rate=(double)0, dropped=(guint64)0, rendered=(guint64)0;", + "type-name": "GstStructure", + "writable": false + }, "sync": { "blurb": "Sync on the clock", "construct": false, @@ -2220,7 +2294,7 @@ "writable": true } }, - "rank": "primary", + "rank": "marginal", "signals": { "handoff": { "args": [ @@ -2242,7 +2316,7 @@ "GInitiallyUnowned", "GObject" ], - "klass": "Codec/Decoder/Video", + "klass": "Codec/Decoder/Video/Hardware", "long-name": "VA-API VC1 decoder", "name": "vaapivc1dec", "pad-templates": { @@ -2252,7 +2326,7 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } @@ -2262,7 +2336,7 @@ "blurb": "The name of the object", "construct": true, "construct-only": false, - "default": "vaapidecode_vc1-0", + "default": "NULL", "hotdoc-fixed-default": true, "type-name": "gchararray", "writable": true @@ -2739,7 +2813,7 @@ "rank": "primary" } }, - "filename": "libgstvaapi.so", + "filename": "gstvaapi", "license": "LGPL", "package": "gstreamer-vaapi", "source": "gstreamer-vaapi", From 38d25c65c34aef67f90e50f0e35d01f1a72cf6a9 Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Wed, 29 May 2019 01:35:17 +0200 Subject: [PATCH 3264/3781] doc: fix some incorrect gtk-doc links --- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 8 ++++---- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 4 ++-- gst/vaapi/gstvaapidecodebin.c | 2 +- gst/vaapi/gstvaapisink.c | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 0f3f4d9994..741b9b32f6 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -70,7 +70,7 @@ static const int x11_event_mask = (KeyPressMask | KeyReleaseMask * %None, no specific colormap will be bound to the window. Also note * the default background color is black. * - * Return value: the newly created X #Window. + * Return value: the newly created X Window. */ Window x11_create_window (Display * dpy, guint w, guint h, guint vid, Colormap cmap) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index d2003dff56..245235ef81 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -58,7 +58,7 @@ struct _GstVaapiWindowGLXPrivate /** * GstVaapiWindowGLX: * - * An X11 #Window suitable for GLX rendering. + * An X11 Window suitable for GLX rendering. */ struct _GstVaapiWindowGLX { @@ -69,7 +69,7 @@ struct _GstVaapiWindowGLX /** * GstVaapiWindowGLXClass: * - * An X11 #Window suitable for GLX rendering. + * An X11 Window suitable for GLX rendering. */ struct _GstVaapiWindowGLXClass { @@ -361,9 +361,9 @@ error: /** * gst_vaapi_window_glx_new_with_xid: * @display: a #GstVaapiDisplay - * @xid: an X11 #Window id + * @xid: an X11 Window id * - * Creates a #GstVaapiWindow using the X11 #Window @xid. The caller + * Creates a #GstVaapiWindow using the X11 Window @xid. The caller * still owns the window and must call XDestroyWindow() when all * #GstVaapiWindow references are released. Doing so too early can * yield undefined behaviour. diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index adb8a75089..39a5e02605 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -128,7 +128,7 @@ struct _GstVaapiWindowWayland /** * GstVaapiWindowWaylandClass: * - * An Wayland #Window wrapper class. + * An Wayland Window wrapper class. */ struct _GstVaapiWindowWaylandClass { diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 217815cdaf..7d9eea704e 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -652,9 +652,9 @@ gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height) /** * gst_vaapi_window_x11_new_with_xid: * @display: a #GstVaapiDisplay - * @xid: an X11 #Window id + * @xid: an X11 Window id * - * Creates a #GstVaapiWindow using the X11 #Window @xid. The caller + * Creates a #GstVaapiWindow using the X11 Window @xid. The caller * still owns the window and must call XDestroyWindow() when all * #GstVaapiWindow references are released. Doing so too early can * yield undefined behaviour. @@ -675,11 +675,11 @@ gst_vaapi_window_x11_new_with_xid (GstVaapiDisplay * display, Window xid) * gst_vaapi_window_x11_get_xid: * @window: a #GstVaapiWindowX11 * - * Returns the underlying X11 #Window that was created by + * Returns the underlying X11 Window that was created by * gst_vaapi_window_x11_new() or that was bound with * gst_vaapi_window_x11_new_with_xid(). * - * Return value: the underlying X11 #Window bound to @window. + * Return value: the underlying X11 Window bound to @window. */ Window gst_vaapi_window_x11_get_xid (GstVaapiWindowX11 * window) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index 095a267dc8..8626cb98e7 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -42,7 +42,7 @@ G_BEGIN_DECLS * GST_VAAPI_WINDOW_XWINDOW: * @window: a #GstVaapiWindow * - * Macro that evaluates to the underlying X11 #Window of @window + * Macro that evaluates to the underlying X11 Window of @window */ #define GST_VAAPI_WINDOW_XWINDOW(window) \ gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (window)) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index 08bc074b84..06ce2e5858 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -59,7 +59,7 @@ struct _GstVaapiWindowX11Private /** * GstVaapiWindowX11: * - * An X11 #Window wrapper. + * An X11 Window wrapper. */ struct _GstVaapiWindowX11 { @@ -70,7 +70,7 @@ struct _GstVaapiWindowX11 /** * GstVaapiWindowX11Class: * - * An X11 #Window wrapper class. + * An X11 Window wrapper class. */ struct _GstVaapiWindowX11Class { diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 5b3f6994ff..f807223b90 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -30,7 +30,7 @@ * the unregistered vaapidecode, a #GstQueue, and the * #GstVaapiPostproc, if it is available and functional in the setup. * - * It offers the functionality of #GstVaapiDecode and the many options + * It offers the functionality of GstVaapiDecoder and the many options * of #GstVaapiPostproc. * * diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 06d5d67dc8..e820f2c5b2 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -26,7 +26,7 @@ * SECTION:element-vaapisink * @short_description: A VA-API based video sink * - * vaapisink renders video frames to a drawable (X #Window) on a local + * vaapisink renders video frames to a drawable (X Window) on a local * display using the Video Acceleration (VA) API. The element will * create its own internal window and render into it. * From 3ccf3f3334b4aab1fd9eafe772a93873869376dc Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 13 May 2019 16:39:33 -0700 Subject: [PATCH 3265/3781] vaapipostproc: add mirror support Adds vpp mirroring support to vaapipostproc. Use property video-direction. Valid values are identity, horiz or vert. Default is identity (no mirror). Closes #89 v2: Use GstVideoOrientationMethod enum v3: Don't warn for VA_MIRROR_NONE. Use GST_TYPE_VIDEO_ORIENTATION_METHOD type. v4: Query VAAPI caps when setting mirror value instead of during per-frame processing. v5: Return TRUE in warning cases when setting mirror value. --- gst-libs/gst/vaapi/gstvaapifilter.c | 95 +++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 10 +++ gst-libs/gst/vaapi/gstvaapiutils.c | 24 ++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 4 ++ gst/vaapi/gstvaapipostproc.c | 29 +++++++++ gst/vaapi/gstvaapipostproc.h | 8 ++- 6 files changed, 169 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 5f25b373de..f71585189c 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -61,6 +61,7 @@ struct _GstVaapiFilter GPtrArray *operations; GstVideoFormat format; GstVaapiScaleMethod scale_method; + GstVideoOrientationMethod video_direction; GArray *formats; GArray *forward_references; GArray *backward_references; @@ -115,6 +116,17 @@ gst_vaapi_scale_method_get_type (void) return g_type; } +static const gchar * +gst_vaapi_get_video_direction_nick (GstVideoOrientationMethod method) +{ + gpointer const klass = g_type_class_peek (GST_TYPE_VIDEO_ORIENTATION_METHOD); + GEnumValue *const e = g_enum_get_value (klass, method); + + if (e) + return e->value_nick; + return ""; +} + GType gst_vaapi_deinterlace_method_get_type (void) { @@ -277,6 +289,7 @@ vpp_get_filter_caps (GstVaapiFilter * filter, VAProcFilterType type, #define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN #define DEFAULT_SCALING GST_VAAPI_SCALE_METHOD_DEFAULT +#define DEFAULT_VIDEO_DIRECTION GST_VIDEO_ORIENTATION_IDENTITY enum { @@ -297,6 +310,7 @@ enum PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST, PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING, PROP_SCALING = GST_VAAPI_FILTER_OP_SCALING, + PROP_VIDEO_DIRECTION = GST_VAAPI_FILTER_OP_VIDEO_DIRECTION, PROP_SKINTONE = GST_VAAPI_FILTER_OP_SKINTONE, N_PROPERTIES @@ -420,6 +434,18 @@ init_properties (void) GST_VAAPI_TYPE_SCALE_METHOD, DEFAULT_SCALING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFilter:video-direction: + * + * The video-direction to use, expressed as an enum value. See + * #GstVideoOrientationMethod. + */ + g_properties[PROP_VIDEO_DIRECTION] = g_param_spec_enum ("video-direction", + "Video Direction", + "Video direction: rotation and flipping", + GST_TYPE_VIDEO_ORIENTATION_METHOD, + DEFAULT_VIDEO_DIRECTION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** * GstVaapiFilter:skin-tone-enhancement: * @@ -465,6 +491,7 @@ op_data_new (GstVaapiFilterOp op, GParamSpec * pspec) case GST_VAAPI_FILTER_OP_FORMAT: case GST_VAAPI_FILTER_OP_CROP: case GST_VAAPI_FILTER_OP_SCALING: + case GST_VAAPI_FILTER_OP_VIDEO_DIRECTION: op_data->va_type = VAProcFilterNone; break; case GST_VAAPI_FILTER_OP_DENOISE: @@ -1330,6 +1357,9 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, return op_set_skintone (filter, op_data, (value ? g_value_get_boolean (value) : G_PARAM_SPEC_BOOLEAN (op_data->pspec)->default_value)); + case GST_VAAPI_FILTER_OP_VIDEO_DIRECTION: + return gst_vaapi_filter_set_video_direction (filter, value ? + g_value_get_enum (value) : DEFAULT_VIDEO_DIRECTION); default: break; } @@ -1362,6 +1392,7 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, guint i, num_filters = 0; VAStatus va_status; VARectangle src_rect, dst_rect; + guint va_mirror = from_GstVideoOrientationMethod (filter->video_direction); if (!ensure_operations (filter)) return GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED; @@ -1444,6 +1475,10 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, pipeline_param->filters = filters; pipeline_param->num_filters = num_filters; +#if VA_CHECK_VERSION(1,1,0) + pipeline_param->mirror_state = va_mirror; +#endif + // Reference frames for advanced deinterlacing if (filter->forward_references->len > 0) { pipeline_param->forward_references = (VASurfaceID *) @@ -1838,6 +1873,58 @@ gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, gboolean enhance) find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE), enhance); } +/** + * gst_vaapi_filter_set_video_direction: + * @filter: a #GstVaapiFilter + * @method: the video direction (see #GstVideoOrientationMethod) + * + * Applies mirror/rotation to the video processing pipeline. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter, + GstVideoOrientationMethod method) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + switch (method) { + case GST_VIDEO_ORIENTATION_IDENTITY: + break; + case GST_VIDEO_ORIENTATION_HORIZ: + case GST_VIDEO_ORIENTATION_VERT: + { +#if VA_CHECK_VERSION(1,1,0) + VAProcPipelineCaps pipeline_caps; + guint va_mirror = from_GstVideoOrientationMethod (method); + + VAStatus va_status = vaQueryVideoProcPipelineCaps (filter->va_display, + filter->va_context, NULL, 0, &pipeline_caps); + if (!vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()")) + return FALSE; + + if (!(pipeline_caps.mirror_flags & va_mirror)) { + GST_WARNING ("%s video-direction unsupported", + gst_vaapi_get_video_direction_nick (method)); + return TRUE; + } +#else + GST_WARNING ("%s video-direction unsupported", + gst_vaapi_get_video_direction_nick (method)); + return TRUE; +#endif + break; + } + default: + GST_WARNING ("%s video-direction unsupported or unimplemented", + gst_vaapi_get_video_direction_nick (method)); + return TRUE; + } + + filter->video_direction = method; + return TRUE; +} + static inline gfloat op_get_float_default_value (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data) @@ -1915,3 +2002,11 @@ gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter) return FALSE; } + +GstVideoOrientationMethod +gst_vaapi_filter_get_video_direction_default (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return DEFAULT_VIDEO_DIRECTION; +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 98798c9ae7..491f459421 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -48,6 +48,8 @@ typedef struct _GstVaapiFilterOpInfo GstVaapiFilterOpInfo; * @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_SKINTONE: Skin tone enhancement (bool). * * The set of operations that could be applied to the filter. @@ -63,6 +65,7 @@ typedef enum { 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_SKINTONE, } GstVaapiFilterOp; @@ -246,6 +249,10 @@ gboolean gst_vaapi_filter_set_scaling (GstVaapiFilter * filter, GstVaapiScaleMethod method); +gboolean +gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter, + GstVideoOrientationMethod method); + gboolean gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, gboolean enhance); @@ -271,6 +278,9 @@ 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); + gboolean gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter); diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 7f9b9caeee..4e3fc2f161 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -828,3 +828,27 @@ to_GstVaapiScaleMethod (guint flags) } return method; } + +/* VPP: translate GstVideoOrientationMethod into VA mirror flags */ +guint +from_GstVideoOrientationMethod (guint value) +{ + guint va_flags = 0; + + switch (value) { +#if VA_CHECK_VERSION(1,1,0) + case GST_VIDEO_ORIENTATION_IDENTITY: + va_flags = VA_MIRROR_NONE; + break; + case GST_VIDEO_ORIENTATION_HORIZ: + va_flags = VA_MIRROR_HORIZONTAL; + break; + case GST_VIDEO_ORIENTATION_VERT: + va_flags = VA_MIRROR_VERTICAL; + break; +#endif + default: + break; + } + return va_flags; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index 680fc17a1b..cf12051230 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -147,4 +147,8 @@ G_GNUC_INTERNAL guint to_GstVaapiScaleMethod (guint flags); +G_GNUC_INTERNAL +guint +from_GstVideoOrientationMethod (guint value); + #endif /* GST_VAAPI_UTILS_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 55e3a5669c..d89804abb4 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -121,6 +121,7 @@ enum PROP_BRIGHTNESS, PROP_CONTRAST, PROP_SCALE_METHOD, + PROP_VIDEO_DIRECTION, PROP_SKIN_TONE_ENHANCEMENT, }; @@ -593,6 +594,16 @@ update_filter (GstVaapiPostproc * postproc) postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_SCALE); } + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION) { + if (!gst_vaapi_filter_set_video_direction (postproc->filter, + postproc->video_direction)) + return FALSE; + + if (gst_vaapi_filter_get_video_direction_default (postproc->filter) == + postproc->video_direction) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION); + } + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SKINTONE) { if (!gst_vaapi_filter_set_skintone (postproc->filter, postproc->skintone_enhance)) @@ -1613,6 +1624,10 @@ gst_vaapipostproc_set_property (GObject * object, postproc->scale_method = g_value_get_enum (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SCALE; break; + case PROP_VIDEO_DIRECTION: + postproc->video_direction = g_value_get_enum (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION; + break; case PROP_SKIN_TONE_ENHANCEMENT: postproc->skintone_enhance = g_value_get_boolean (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SKINTONE; @@ -1674,6 +1689,9 @@ gst_vaapipostproc_get_property (GObject * object, case PROP_SCALE_METHOD: g_value_set_enum (value, postproc->scale_method); break; + case PROP_VIDEO_DIRECTION: + g_value_set_enum (value, postproc->video_direction); + break; case PROP_SKIN_TONE_ENHANCEMENT: g_value_set_boolean (value, postproc->skintone_enhance); break; @@ -1894,6 +1912,17 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) g_object_class_install_property (object_class, PROP_SCALE_METHOD, filter_op->pspec); + /** + * GstVaapiPostproc:video-direction: + * + * The video-direction to use, expressed as an enum value. See + * #GstVideoDirectionMethod. + */ + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION); + if (filter_op) + g_object_class_install_property (object_class, + PROP_VIDEO_DIRECTION, filter_op->pspec); + /** * GstVaapiPostproc:skin-tone-enhancement: * diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 3c4232c236..9e73002dc1 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -86,6 +86,7 @@ typedef enum * @GST_VAAPI_POSTPROC_FLAG_DEINTERLACE: Deinterlacing. * @GST_VAAPI_POSTPROC_FLAG_SIZE: Video scaling. * @GST_VAAPI_POSTPROC_FLAG_SCALE: Video scaling mode. + * @GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION: Video rotation and flip/mirroring. * @GST_VAAPI_POSTPROC_FLAG_SKINTONE: Skin tone enhancement. * * The set of operations that are to be performed for each frame. @@ -101,6 +102,8 @@ typedef enum GST_VAAPI_POSTPROC_FLAG_CONTRAST = 1 << GST_VAAPI_FILTER_OP_CONTRAST, GST_VAAPI_POSTPROC_FLAG_DEINTERLACE = 1 << GST_VAAPI_FILTER_OP_DEINTERLACING, GST_VAAPI_POSTPROC_FLAG_SCALE = 1 << GST_VAAPI_FILTER_OP_SCALING, + GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION = + 1 << GST_VAAPI_FILTER_OP_VIDEO_DIRECTION, GST_VAAPI_POSTPROC_FLAG_SKINTONE = 1 << GST_VAAPI_FILTER_OP_SKINTONE, /* Additional custom flags */ @@ -160,8 +163,11 @@ struct _GstVaapiPostproc gfloat denoise_level; gfloat sharpen_level; - /* Color balance filter values */ GstVaapiScaleMethod scale_method; + + GstVideoOrientationMethod video_direction; + + /* Color balance filter values */ gfloat hue; gfloat saturation; gfloat brightness; From df3989865ea2050ecdde046f9597931be1ceebe1 Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Wed, 29 May 2019 23:08:22 +0200 Subject: [PATCH 3266/3781] doc: remove xml from comments --- gst-libs/gst/vaapi/gstvaapitypes.h | 7 ++--- gst/vaapi/gstvaapidecodebin.c | 5 ++-- gst/vaapi/gstvaapidecodedoc.c | 44 +++++++++++------------------ gst/vaapi/gstvaapiencode_h264.c | 5 ++-- gst/vaapi/gstvaapiencode_h264_fei.c | 5 ++-- gst/vaapi/gstvaapiencode_h265.c | 5 ++-- gst/vaapi/gstvaapiencode_jpeg.c | 5 ++-- gst/vaapi/gstvaapiencode_mpeg2.c | 5 ++-- gst/vaapi/gstvaapiencode_vp8.c | 5 ++-- gst/vaapi/gstvaapiencode_vp9.c | 5 ++-- gst/vaapi/gstvaapipostproc.c | 5 ++-- gst/vaapi/gstvaapisink.c | 5 ++-- 12 files changed, 40 insertions(+), 61 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index cf486a4153..b958e75a15 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -57,11 +57,10 @@ typedef gsize GstVaapiID; * * Can be used together with #GST_VAAPI_ID_ARGS to properly output an * integer value in a printf()-style text message. - * - * + * + * ``` C * printf("id: %" GST_VAAPI_ID_FORMAT "\n", GST_VAAPI_ID_ARGS(id)); - * - * + * ``` */ #define GST_VAAPI_ID_FORMAT "p" diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index f807223b90..4f0dd52fa5 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -33,12 +33,11 @@ * It offers the functionality of GstVaapiDecoder and the many options * of #GstVaapiPostproc. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 filesrc location=~/big_buck_bunny.mov ! qtdemux ! h264parse ! vaapidecodebin ! vaapisink * ]| - * */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapidecodedoc.c b/gst/vaapi/gstvaapidecodedoc.c index aafe9fa66d..f8dd837f62 100644 --- a/gst/vaapi/gstvaapidecodedoc.c +++ b/gst/vaapi/gstvaapidecodedoc.c @@ -37,12 +37,11 @@ * processed by other elements, but the performance would be rather * bad. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 filesrc location=~/image.jpeg ! jpegparse ! vaapijpegdec ! imagefreeze ! vaapisink * ]| - * */ /** @@ -63,12 +62,11 @@ * processed by other elements, but the performance would be rather * bad. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 filesrc location=~/sample.mpg ! mpegpsdemux ! vaapimpeg2dec ! vaapisink * ]| - * */ /** @@ -89,12 +87,11 @@ * processed by other elements, but the performance would be rather * bad. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 filesrc location=~/sample.mpeg4 ! mpeg4videoparse ! vaapimpeg4dec ! vaapisink * ]| - * */ /** @@ -115,12 +112,11 @@ * processed by other elements, but the performance would be rather * bad. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 filesrc location=~/sample.h263 ! h263parse ! vaapih263dec ! vaapisink * ]| - * */ /** @@ -141,12 +137,11 @@ * processed by other elements, but the performance would be rather * bad. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 filesrc location=~/big_buck_bunny.mov ! qtdemux ! h264parse ! vaapih264dec ! vaapisink * ]| - * */ /** @@ -167,12 +162,11 @@ * processed by other elements, but the performance would be rather * bad. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 filesrc location=./sample.bin ! h265parse ! vaapih265dec ! vaapisink * ]| - * */ /** @@ -193,12 +187,11 @@ * processed by other elements, but the performance would be rather * bad. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 filesrc location=~/elephants_dream.wmv ! asfdemux ! vaapivc1dec ! vaapisink * ]| - * */ /** @@ -219,12 +212,11 @@ * processed by other elements, but the performance would be rather * bad. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 filesrc location=./sample.webm ! matroskademux ! vaapivp8dec ! vaapisink * ]| - * */ /** @@ -245,10 +237,8 @@ * processed by other elements, but the performance would be rather * bad. * - * - * Example launch line + * ## Example launch line * |[ * gst-launch-1.0 filesrc location=./sample.vp9.webm ! ivfparse ! vaapivp9dec ! vaapisink * ]| - * */ diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index ed19c409a3..e861255c8c 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -52,12 +52,11 @@ * you can set #GstVaapiEncodeH264:tune, if your backend supports it, * for low-power mode or high compression. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapih264enc ! h264parse ! mp4mux ! filesink location=test.mp4 * ]| - * */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapiencode_h264_fei.c b/gst/vaapi/gstvaapiencode_h264_fei.c index caf68b3899..6e4d51a88a 100644 --- a/gst/vaapi/gstvaapiencode_h264_fei.c +++ b/gst/vaapi/gstvaapiencode_h264_fei.c @@ -27,12 +27,11 @@ * * Encodes raw video streams into H.264 bitstreams. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! vaapih264feienc fei-mode=ENC_PAK ! filesink location=test.264 * ]| - * */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 268f404d64..fa03fdcefc 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -26,12 +26,11 @@ * * Encodes raw video streams into HEVC bitstreams. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapih265enc ! h265parse ! matroskamux ! filesink location=test.mkv * ]| - * */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 81da4c738b..4d644fa9d2 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -26,12 +26,11 @@ * * Encodes raw images into JPEG images. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 -ev videotestsrc num-buffers=1 ! timeoverlay ! vaapijpegenc ! filesink location=test.jpg * ]| - * */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 3622bbea59..f43ac3f9fe 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -27,12 +27,11 @@ * * Encodes raw video streams into MPEG2 bitstreams. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapimpeg2enc ! matroskamux ! filesink location=test.mkv * ]| - * */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index fcaffbb812..5fee607b0a 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -26,12 +26,11 @@ * * Encodes raw video streams into VP8 bitstreams. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapivp8enc ! matroskamux ! filesink location=test.mkv * ]| - * */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index 7a69384ec4..22c40a6443 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -26,12 +26,11 @@ * * Encodes raw video streams into VP9 bitstreams. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! timeoverlay ! vaapivp9enc ! matroskamux ! filesink location=test.mkv * ]| - * */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index d89804abb4..d6dc762a02 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -27,12 +27,11 @@ * vaapipostproc consists in various postprocessing algorithms to be * applied to VA surfaces. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 videotestsrc ! vaapipostproc ! video/x-raw width=1920, height=1080 ! vaapisink * ]| - * */ #include "gstcompat.h" diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index e820f2c5b2..92f953475c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -30,12 +30,11 @@ * display using the Video Acceleration (VA) API. The element will * create its own internal window and render into it. * - * - * Example launch line + * ## Example launch line + * * |[ * gst-launch-1.0 videotestsrc ! vaapisink * ]| - * */ #include "gstcompat.h" From 53d86ff519e93343636f38b1ff4d38314755fb06 Mon Sep 17 00:00:00 2001 From: Freyr666 Date: Tue, 28 May 2019 12:09:36 +0300 Subject: [PATCH 3267/3781] vaapiencode: Fixes deadlock in gst_vaapiencode_change_state function This fixes a deadlock in gst_vaapiencode_change_state, which was due to srcpad's chain function was locked waiting for available buffers. Since the coded buffers in codedbuf_queue become available after sinkpad consume the encoded frames, Paused -> Ready state change leads to deadlock. Coded buffers are never consumed and marked free, hence gst_vaapiencode_handle_frame waits for available buffers and holds the stream_lock of the srcpad. --- gst/vaapi/gstvaapiencode.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index af8c77a484..7f26016e2f 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -770,6 +770,9 @@ gst_vaapiencode_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: gst_pad_stop_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); + + if (!gst_vaapiencode_drain (encode)) + goto drain_error; break; default: break; @@ -777,6 +780,12 @@ gst_vaapiencode_change_state (GstElement * element, GstStateChange transition) return GST_ELEMENT_CLASS (gst_vaapiencode_parent_class)->change_state (element, transition); + +drain_error: + { + GST_ERROR ("failed to drain pending encoded frames"); + return GST_STATE_CHANGE_FAILURE; + } } static gboolean From e62b321efeb910c7f88724c76049a2a0b98171f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 31 May 2019 13:08:39 +0200 Subject: [PATCH 3268/3781] libs: dec: vp9: clear parser pointer after release Fix an use-after-release of the parser pointer in VP9 decoder. --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index b2a605c398..edb052f9fc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -118,8 +118,7 @@ gst_vaapi_decoder_vp9_close (GstVaapiDecoderVp9 * decoder) for (i = 0; i < GST_VP9_REF_FRAMES; i++) gst_vaapi_picture_replace (&priv->ref_frames[i], NULL); - if (priv->parser) - gst_vp9_parser_free (priv->parser); + g_clear_pointer (&priv->parser, gst_vp9_parser_free); } static gboolean From 8f884aa9bc2b5d2d0ed9442ff334060000df941a Mon Sep 17 00:00:00 2001 From: Niels De Graef Date: Fri, 31 May 2019 23:10:33 +0200 Subject: [PATCH 3269/3781] meson: Bump minimal GLib version to 2.44 This means we can use some newer features and get rid of some boilerplate code using the G_DECLARE_* macros. As discussed on IRC, 2.44 is old enough by now to start depending on it. --- configure.ac | 2 +- meson.build | 2 +- tests/output.c | 5 ----- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 5e04751a93..a7b8bc0ba3 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ m4_define([gst_vaapi_lt_revision], [0]) m4_define([gst_vaapi_lt_age], [1700]) # glib version number -m4_define([glib_version], [2.40]) +m4_define([glib_version], [2.44]) # gstreamer version number m4_define([gst_version], [1.17.0.1]) diff --git a/meson.build b/meson.build index 7fc19b796a..227bcf9236 100644 --- a/meson.build +++ b/meson.build @@ -16,7 +16,7 @@ else endif libva_req = ['>= 0.39.0', '!= 0.99.0'] -glib_req = '>= 2.40.0' +glib_req = '>= 2.44.0' libwayland_req = '>= 1.11.0' gst_req = '>= @0@.@1@.0'.format(gst_version_major, gst_version_minor) diff --git a/tests/output.c b/tests/output.c index e1ac5cc628..b100f0324f 100644 --- a/tests/output.c +++ b/tests/output.c @@ -121,11 +121,6 @@ video_output_init (int *argc, char *argv[], GOptionEntry * options) GOptionContext *ctx; gboolean success; -#if !GLIB_CHECK_VERSION(2,31,0) - if (!g_thread_supported ()) - g_thread_init (NULL); -#endif - ctx = g_option_context_new ("- test options"); if (!ctx) return FALSE; From de51eb00599232d3311e6bc42fc168b04b86a027 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 4 Jun 2019 13:27:50 +0800 Subject: [PATCH 3270/3781] libs: mpeg2 encoder: No packed header for SPS and PPS Dislable passing down packed PPS and PPS to driver if driver does not want it. Fix: #168 --- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 351ee0f004..79dc7f1c11 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -417,8 +417,10 @@ ensure_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) if (!fill_sequence (encoder, sequence)) goto error; - if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - !set_sequence_packed_header (encoder, picture, sequence)) + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_SEQUENCE) + && picture->type == GST_VAAPI_PICTURE_TYPE_I + && !set_sequence_packed_header (encoder, picture, sequence)) goto error; gst_vaapi_enc_picture_set_sequence (picture, sequence); gst_vaapi_codec_object_replace (&sequence, NULL); @@ -442,7 +444,9 @@ ensure_picture (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture, if (!fill_picture (encoder, picture, codedbuf, surface)) return FALSE; - if (!set_picture_packed_header (encoder, picture)) { + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_PICTURE) + && !set_picture_packed_header (encoder, picture)) { GST_ERROR ("set picture packed header failed"); return FALSE; } From ed7277a1b717f410302fddede64334bd483502ca Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 31 May 2019 12:30:03 -0700 Subject: [PATCH 3271/3781] libs: encoder: increase bitrate prop max value There are many profile levels that can support more than 102400 kbps. Thus, increase the max allowed bitrate property value from 102400 kbps to 2048000 kbps (same as msdk encoder plugins). --- gst-libs/gst/vaapi/gstvaapiencoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 8c8742937c..51bcd069a9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -151,7 +151,7 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) g_param_spec_uint ("bitrate", "Bitrate (kbps)", "The desired bitrate expressed in kbps (0: auto-calculate)", - 0, 100 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + 0, 2000 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstVaapiEncoder:target-percentage: From 1f5ad9c7e51c27f7d3067ff7a9cd505b1ea5f55c Mon Sep 17 00:00:00 2001 From: Freyr Date: Thu, 6 Jun 2019 17:24:30 +0300 Subject: [PATCH 3272/3781] libs: encoder: vp8,vp9: reset frame_counter when input frame's format changes When input frame's formate changes, vp{8,9} encoders don't reset their frame counter, hence the newly created frame could become a P-frame, leading to some major troubles (sigabrt in libdrm in case of vp9). This patch adds some frame prediction-related reset logic to the `flush' methods of GstVaapiEncoderVP8 and GstVaapiEncoderVP9 implementations. --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 5 +++++ gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 7ee0a2ef4d..0b8b379048 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -445,6 +445,11 @@ error: 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; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 94c9a5a6ed..4464f41809 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -462,6 +462,10 @@ error: 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; } From 5f4142221512f32f14038950f392a8128af4a995 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 10 Jun 2019 20:39:28 -0700 Subject: [PATCH 3273/3781] vaapivideomemory: allow negotiated info to be removed Allow NULL negotiated_vinfo to be passed into gst_allocator_set_vaapi_negotiated_video_info to allow any previously set info to be removed. --- gst/vaapi/gstvaapivideomemory.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index e7a74ff27f..16bf143342 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1345,7 +1345,8 @@ gst_allocator_set_vaapi_video_info (GstAllocator * allocator, /** * gst_allocator_set_vaapi_negotiated_video_info: * @allocator: a #GstAllocator - * @negotiated_vinfo: the negotiated #GstVideoInfo to store + * @negotiated_vinfo: the negotiated #GstVideoInfo to store. If NULL, then + * removes any previously set value. * * Stores as GObject's qdata the @negotiated_vinfo in the allocator * instance. @@ -1358,11 +1359,13 @@ gst_allocator_set_vaapi_negotiated_video_info (GstAllocator * allocator, const GstVideoInfo * negotiated_vinfo) { g_return_if_fail (allocator && GST_IS_ALLOCATOR (allocator)); - g_return_if_fail (negotiated_vinfo); - g_object_set_qdata_full (G_OBJECT (allocator), NEGOTIATED_VINFO_QUARK, - gst_video_info_copy (negotiated_vinfo), - (GDestroyNotify) gst_video_info_free); + if (negotiated_vinfo) + g_object_set_qdata_full (G_OBJECT (allocator), NEGOTIATED_VINFO_QUARK, + gst_video_info_copy (negotiated_vinfo), + (GDestroyNotify) gst_video_info_free); + else + g_object_set_qdata (G_OBJECT (allocator), NEGOTIATED_VINFO_QUARK, NULL); } /** From a6dfb6e5bee0fd7b7bbeb654e5ef1da2abe73446 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 10 Jun 2019 20:46:30 -0700 Subject: [PATCH 3274/3781] plugins: remove last negotiated video info if caps are same If the allocation caps and negotiated caps are the same, then ensure any previously negotiated video info is also removed. This can occur when multi-resolution video decoding returns to it's original resolution. Fixes #170 --- gst/vaapi/gstvaapipluginbase.c | 48 +++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index c7c929e3c7..1753ad09d2 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -532,7 +532,6 @@ static gboolean ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, GstCaps * caps) { - gboolean different_caps; const GstVideoInfo *image_info; if (!reset_allocator (plugin->srcpad_allocator, vinfo)) @@ -576,30 +575,37 @@ valid_allocator: /* update the size with the one generated by the allocator */ GST_VIDEO_INFO_SIZE (vinfo) = GST_VIDEO_INFO_SIZE (image_info); - /* the received caps are the "allocation caps" which may be - * different from the "negotiation caps". In this case, we should - * indicate the allocator to store the negotiation caps since they - * are the one should be used for frame mapping with GstVideoMeta */ - different_caps = GST_IS_VIDEO_DECODER (plugin) && plugin->srcpad_caps && - !gst_caps_is_strictly_equal (plugin->srcpad_caps, caps); + if (GST_IS_VIDEO_DECODER (plugin)) { + /* the received caps are the "allocation caps" which may be + * different from the "negotiation caps". In this case, we should + * indicate the allocator to store the negotiation caps since they + * are the one should be used for frame mapping with GstVideoMeta */ + gboolean different_caps = plugin->srcpad_caps && + !gst_caps_is_strictly_equal (plugin->srcpad_caps, caps); + const GstVideoInfo *previous_negotiated = + gst_allocator_get_vaapi_negotiated_video_info + (plugin->srcpad_allocator); - if (different_caps) { - guint i; - GstVideoInfo vi = plugin->srcpad_info; + if (different_caps) { + guint i; + GstVideoInfo vi = plugin->srcpad_info; - /* update the planes and the size with the allocator image/surface - * info, but not the resolution */ - for (i = 0; i < GST_VIDEO_INFO_N_PLANES (image_info); i++) { - GST_VIDEO_INFO_PLANE_OFFSET (&vi, i) = - GST_VIDEO_INFO_PLANE_OFFSET (image_info, i); - GST_VIDEO_INFO_PLANE_STRIDE (&vi, i) = - GST_VIDEO_INFO_PLANE_STRIDE (image_info, i); + /* update the planes and the size with the allocator image/surface + * info, but not the resolution */ + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (image_info); i++) { + GST_VIDEO_INFO_PLANE_OFFSET (&vi, i) = + GST_VIDEO_INFO_PLANE_OFFSET (image_info, i); + GST_VIDEO_INFO_PLANE_STRIDE (&vi, i) = + GST_VIDEO_INFO_PLANE_STRIDE (image_info, i); + } + GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (image_info); + gst_allocator_set_vaapi_negotiated_video_info (plugin->srcpad_allocator, + &vi); + } else if (previous_negotiated) { + gst_allocator_set_vaapi_negotiated_video_info (plugin->srcpad_allocator, + NULL); } - GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (image_info); - gst_allocator_set_vaapi_negotiated_video_info (plugin->srcpad_allocator, - &vi); } - return TRUE; /* ERRORS */ From 3b5c7aa688f84294f1daa724b9719f719f3ab9dc Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 22 Jun 2019 00:05:24 +0800 Subject: [PATCH 3275/3781] libs: dec: h265: Fix profile_idc mapping. The old mapping values return by gst_vaapi_utils_h265_get_profile_idc is wrong, though GST_H265_PROFILE_IDC_MAIN and GST_H265_PROFILE_IDC_MAIN_10 happened to be the correct value. We only support Annex A profile_idc (1-4). --- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index a0f3cda4bc..3e71c36fed 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -200,19 +200,18 @@ gst_vaapi_utils_h265_get_profile_idc (GstVaapiProfile profile) switch (profile) { case GST_VAAPI_PROFILE_H265_MAIN: - profile_idc = GST_H265_PROFILE_MAIN; + profile_idc = GST_H265_PROFILE_IDC_MAIN; break; case GST_VAAPI_PROFILE_H265_MAIN10: - profile_idc = GST_H265_PROFILE_MAIN_10; + profile_idc = GST_H265_PROFILE_IDC_MAIN_10; break; case GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE: - profile_idc = GST_H265_PROFILE_MAIN_STILL_PICTURE; + profile_idc = GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE; break; case GST_VAAPI_PROFILE_H265_MAIN_422_10: - profile_idc = GST_H265_PROFILE_MAIN_422_10; - break; + /* Fall through */ case GST_VAAPI_PROFILE_H265_MAIN_444: - profile_idc = GST_H265_PROFILE_MAIN_444; + profile_idc = GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION; break; default: GST_DEBUG ("unsupported GstVaapiProfile value"); From 67ed67515bc1b3b8914364e427deea336c8cd6b9 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Thu, 30 May 2019 09:48:51 -0400 Subject: [PATCH 3276/3781] libs: decoder: jpeg: add support 400/411/422/444 chroma type When create vaapi surface, it is better to use the chroma type get from jpeg file instead of using fixed 420 format. And the correct chroma type can be determined by horizontal_factor/vertical_factor flags that get from jpegparse. --- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 50 ++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiimage.c | 1 + gst-libs/gst/vaapi/video-format.c | 1 + gst/vaapi/gstvaapidecode.c | 2 +- gst/vaapi/gstvaapipluginutil.h | 2 +- 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index baed198712..8e22568e40 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -169,10 +169,55 @@ gst_vaapi_decoder_jpeg_reset (GstVaapiDecoder * 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; @@ -208,10 +253,13 @@ ensure_context (GstVaapiDecoderJpeg * decoder) 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 = 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) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index f5c3569b60..6c10b3b952 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -100,6 +100,7 @@ vaapi_image_is_linear (const VAImage * va_image) data_size = 2 * (width * height + 2 * width2 * height2); break; case VA_FOURCC ('R', 'G', '2', '4'): + case VA_FOURCC ('4', '4', '4', 'P'): data_size = 3 * width * height; break; default: diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index db67cae472..a798cd995d 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -67,6 +67,7 @@ static const GstVideoFormatMap gst_vaapi_video_formats[] = { DEF_YUV (Y210, ('Y', '2', '1', '0'), 32, 422_10BPP), DEF_YUV (Y410, ('Y', '4', '1', '0'), 32, 444_10BPP), DEF_YUV (AYUV, ('A', 'Y', 'U', 'V'), 32, 444), + DEF_YUV (Y444, ('4', '4', '4', 'P'), 24, 444), DEF_YUV (GRAY8, ('Y', '8', '0', '0'), 8, 400), DEF_YUV (P010_10LE, ('P', '0', '1', '0'), 24, 420_10BPP), /* RGB formats */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index cd3624d8d1..5e348f78d2 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -81,7 +81,7 @@ static const char gst_vaapidecode_src_caps_str[] = #if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" #endif - GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }") ";" + GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410, Y444 }") ";" GST_VAAPI_MAKE_DMABUF_CAPS; static GstStaticPadTemplate gst_vaapidecode_src_factory = diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index b59bbb041b..293b40924f 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -105,7 +105,7 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps, #define GST_VAAPI_MAKE_SURFACE_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }") + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410, Y444 }") #define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ From e4bec306b6b5695f1a12bafdb79508011488e693 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Tue, 25 Jun 2019 10:31:20 +0800 Subject: [PATCH 3277/3781] vaapidecode: set initial decode format according surface chroma type For surfaces with different chroma type, it is prefer to initialize a format which chroma type should be same with surface chroma type instead of using fixed NV12. --- gst/vaapi/gstvaapidecode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 5e348f78d2..1bd79c1ec1 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -413,9 +413,14 @@ is_surface_resolution_changed (GstVaapiDecode * decode, surface_format = gst_vaapi_surface_get_format (surface); /* if the VA context delivers a currently unrecognized format - * (ICM3, e.g.), we can assume NV12 "safely" */ + * (ICM3, e.g.), we can assume one according surface chroma + * type. If fail, then use NV12 "safely" */ if (surface_format == GST_VIDEO_FORMAT_UNKNOWN || surface_format == GST_VIDEO_FORMAT_ENCODED) + surface_format = + gst_vaapi_video_format_from_chroma (gst_vaapi_surface_get_chroma_type + (surface)); + if (surface_format == GST_VIDEO_FORMAT_UNKNOWN) surface_format = GST_VIDEO_FORMAT_NV12; } From 9b0f041dedc389765215cb7ae9f9eb7458708cb8 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 25 Jun 2019 19:11:12 +0800 Subject: [PATCH 3278/3781] libs: dec: h265: Consider chroma_bit_depth to choose chrome type For some main-10 stream, sometime the luma is 8 bits while chrome is more than 8 bits, which cause using the wrong NV12 surface as the render target and decoding error. Fix #176 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 29 ++++++++++++++------ gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h | 3 +- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 6cd61f67a6..21dcb4cede 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1144,7 +1144,7 @@ ensure_context (GstVaapiDecoderH265 * decoder, GstH265SPS * sps) chroma_type = gst_vaapi_utils_h265_get_chroma_type (sps->chroma_format_idc, - sps->bit_depth_luma_minus8 + 8); + sps->bit_depth_luma_minus8 + 8, sps->bit_depth_chroma_minus8 + 8); if (!chroma_type) { GST_ERROR ("unsupported chroma_format_idc %u", sps->chroma_format_idc); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 3e71c36fed..5b3bef10f8 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -326,37 +326,48 @@ gst_vaapi_utils_h265_get_level_limits_table (guint * out_length_ptr) /** Returns GstVaapiChromaType from H.265 chroma_format_idc value */ GstVaapiChromaType gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, - guint luma_bit_depth) + guint luma_bit_depth, guint chroma_bit_depth) { GstVaapiChromaType chroma_type = (GstVaapiChromaType) 0; + guint depth = 0; + + if (luma_bit_depth < 8 || chroma_bit_depth < 8 || + luma_bit_depth > 16 || chroma_bit_depth > 16) { + GST_WARNING ("invalid luma_bit_depth or chroma_bit_depth value"); + return chroma_type; + } + + depth = MAX (luma_bit_depth, chroma_bit_depth); switch (chroma_format_idc) { case 0: chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400; break; case 1: - if (luma_bit_depth == 8) + if (depth == 8) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - else if (luma_bit_depth > 8) + else if (depth > 8 && depth <= 10) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; break; case 2: - if (luma_bit_depth == 8) + if (depth == 8) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; - else if (luma_bit_depth > 8) + else if (depth > 8 && depth <= 10) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_10BPP; break; case 3: - if (luma_bit_depth == 8) + if (depth == 8) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; - else if (luma_bit_depth > 8) + else if (depth > 8 && depth <= 10) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_10BPP; break; default: - GST_DEBUG ("unsupported chroma_format_idc value"); - chroma_type = (GstVaapiChromaType) 0; break; } + + if (chroma_type == (GstVaapiChromaType) 0) + GST_DEBUG ("unsupported chroma_format_idc value"); + return chroma_type; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h index 40938c73c2..88f7fda8c9 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h @@ -93,7 +93,8 @@ gst_vaapi_utils_h265_get_level_limits_table (guint * out_length_ptr); /* Returns GstVaapiChromaType from H.265 chroma_format_idc value */ G_GNUC_INTERNAL GstVaapiChromaType -gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, guint luma_bit_depth); +gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, + guint luma_bit_depth, guint chroma_bit_depth); /* Returns H.265 chroma_format_idc value from GstVaapiChromaType */ G_GNUC_INTERNAL From abc2545c60c45ebee48d4902f10be097a8ee3c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 28 Jun 2019 16:32:51 +0200 Subject: [PATCH 3279/3781] Update README --- README | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README b/README index 6a4fed1633..8f12ecb4a2 100644 --- a/README +++ b/README @@ -45,7 +45,7 @@ GStreamer and helper libraries. Features -------- - * VA-API support from 0.29 to 0.38 + * 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 and HEVC ad-hoc encoders @@ -127,12 +127,12 @@ Sources Stable source code releases can be found at: - Git repository for work-in-progress changes is available at: - + GitLab repository for work-in-progress changes is available at: + Reporting Bugs -------------- - Bugs can be reported in the GNOME Bugzilla system at: - + Bugs can be reported in the GStreamer's GitLab system at: + From 958ea067cb9bb45a276cbbd16da919c6e191fbab Mon Sep 17 00:00:00 2001 From: Wang Zhanjun Date: Mon, 24 Jun 2019 16:26:56 -0400 Subject: [PATCH 3280/3781] libs: dec: vp9: do not use display size as decoded size If display size is smaller than current frame size, then the crop size will be set as display size, which either crashes the pipeline or the output MD5 does not match. Rather it should use the actual decoded size. This patch removes the cropping set. For rendering we can use aspect ratio to set display size. Fixes #175 Signed-off-by: Wang Zhanjun Signed-off-by: Xu Guangxin --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index edb052f9fc..a34ee5b941 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -536,12 +536,6 @@ decode_picture (GstVaapiDecoderVp9 * decoder, const guchar * buf, crop_width = frame_hdr->width; crop_height = frame_hdr->height; } - if (frame_hdr->display_size_enabled && - (frame_hdr->width > frame_hdr->display_width - || frame_hdr->height > frame_hdr->display_height)) { - crop_width = frame_hdr->display_width; - crop_height = frame_hdr->display_height; - } if (crop_width || crop_height) { GstVaapiRectangle crop_rect; crop_rect.x = 0; From 1e36478b0f298e37e1c86bf9ce585b20ace69b03 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sat, 29 Jun 2019 00:08:40 +1000 Subject: [PATCH 3281/3781] h264: Update for parse_vui_params parameter removal. Update calls to the h264 parser lib for removal of the parse_vui_params parameter. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index fb4c549f06..f7849694b6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1766,7 +1766,7 @@ parse_sps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) standard but that should get a default value anyway */ sps->log2_max_pic_order_cnt_lsb_minus4 = 0; - result = gst_h264_parser_parse_sps (priv->parser, &pi->nalu, sps, TRUE); + result = gst_h264_parser_parse_sps (priv->parser, &pi->nalu, sps); if (result != GST_H264_PARSER_OK) return get_status (result); @@ -1788,8 +1788,7 @@ parse_subset_sps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) standard but that should get a default value anyway */ sps->log2_max_pic_order_cnt_lsb_minus4 = 0; - result = gst_h264_parser_parse_subset_sps (priv->parser, &pi->nalu, sps, - TRUE); + result = gst_h264_parser_parse_subset_sps (priv->parser, &pi->nalu, sps); if (result != GST_H264_PARSER_OK) return get_status (result); From 66d6754fcebaaf21686e8d74c07121ee3c690371 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Mon, 1 Jul 2019 16:52:00 +0800 Subject: [PATCH 3282/3781] libs: encoder: refine guard of bitrate control mode Remove useless guard of all bitrate control mode's guard except MB which is define in VA-API version 0.39.1. --- gst-libs/gst/vaapi/gstvaapiutils.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 4e3fc2f161..49fb65280d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -328,20 +328,16 @@ string_of_VARateControl (guint rate_control) switch (rate_control) { case VA_RC_NONE: return "None"; -#ifdef VA_RC_CQP case VA_RC_CQP: return "CQP"; -#endif case VA_RC_CBR: return "CBR"; case VA_RC_VCM: return "VCM"; case VA_RC_VBR: return "VBR"; -#ifdef VA_RC_VBR_CONSTRAINED case VA_RC_VBR_CONSTRAINED: return "VBR-Constrained"; -#endif default: break; } @@ -697,21 +693,17 @@ from_GstVaapiRateControl (guint value) switch (value) { case GST_VAAPI_RATECONTROL_NONE: return VA_RC_NONE; -#ifdef VA_RC_CQP case GST_VAAPI_RATECONTROL_CQP: return VA_RC_CQP; -#endif case GST_VAAPI_RATECONTROL_CBR: return VA_RC_CBR; case GST_VAAPI_RATECONTROL_VCM: return VA_RC_VCM; case GST_VAAPI_RATECONTROL_VBR: return VA_RC_VBR; -#ifdef VA_RC_VBR_CONSTRAINED case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: return VA_RC_VBR_CONSTRAINED; -#endif -#ifdef VA_RC_MB +#if VA_CHECK_VERSION(0,39,1) case GST_VAAPI_RATECONTROL_MB: return VA_RC_MB; #endif @@ -726,21 +718,17 @@ to_GstVaapiRateControl (guint value) switch (value) { case VA_RC_NONE: return GST_VAAPI_RATECONTROL_NONE; -#ifdef VA_RC_CQP case VA_RC_CQP: return GST_VAAPI_RATECONTROL_CQP; -#endif case VA_RC_CBR: return GST_VAAPI_RATECONTROL_CBR; case VA_RC_VCM: return GST_VAAPI_RATECONTROL_VCM; case VA_RC_VBR: return GST_VAAPI_RATECONTROL_VBR; -#ifdef VA_RC_VBR_CONSTRAINED case VA_RC_VBR_CONSTRAINED: return GST_VAAPI_RATECONTROL_VBR_CONSTRAINED; -#endif -#ifdef VA_RC_MB +#if VA_CHECK_VERSION(0,39,1) case VA_RC_MB: return GST_VAAPI_RATECONTROL_MB; #endif From b8739a89b0ca2d66c267842cab24e336f7a5c57b Mon Sep 17 00:00:00 2001 From: Wangfei Date: Mon, 1 Jul 2019 17:02:33 +0800 Subject: [PATCH 3283/3781] libs: encoder: Add MB ratecontrol mode to get its string --- gst-libs/gst/vaapi/gstvaapiutils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 49fb65280d..736fafaccb 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -338,6 +338,10 @@ string_of_VARateControl (guint rate_control) return "VBR"; case VA_RC_VBR_CONSTRAINED: return "VBR-Constrained"; +#if VA_CHECK_VERSION(0,39,1) + case VA_RC_MB: + return "MB"; +#endif default: break; } From e592f6b41579515284fd6060bc0463915e90815c Mon Sep 17 00:00:00 2001 From: Wangfei Date: Wed, 22 May 2019 10:47:30 -0400 Subject: [PATCH 3284/3781] libs: encoder: h265: pass diff_cu_qp_delta_depth flag to driver Intel media-driver requires enablement of diff_cu_qp_delta_depth when cu_qp_delta_enabled_flag enabled. Fixes: #177 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index c9f162892d..972dcabc7e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1643,6 +1643,16 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, || GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) pic_param->pic_fields.bits.cu_qp_delta_enabled_flag = 1; + /* XXX: Intel's media-driver, when using low-power mode, requires + * that diff_cu_qp_delta_depth has to be equal to + * log2_diff_max_min_luma_coding_block_size, meaning 3. + * + * For now we assume that on only Intel's media-drivers supports + * H265 low-power */ + if ((GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) && + (pic_param->pic_fields.bits.cu_qp_delta_enabled_flag)) + pic_param->diff_cu_qp_delta_depth = 3; + pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag = TRUE; if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) From f1aa0cc5e0d6450ff55a54a4367222b40af3c6f1 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 1 Jul 2019 15:26:18 -0700 Subject: [PATCH 3285/3781] vaapipostproc: add rotation support Adds vpp rotation support to vaapipostproc. Uses property video-direction. Default is identity (no rotation). Closes #104 --- gst-libs/gst/vaapi/gstvaapifilter.c | 34 +++++++++++++++++++----- gst-libs/gst/vaapi/gstvaapiutils.c | 40 +++++++++++++++++++++++------ gst-libs/gst/vaapi/gstvaapiutils.h | 5 ++-- gst/vaapi/gstvaapipostprocutil.c | 11 ++++++++ 4 files changed, 74 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index f71585189c..1fd9e5acbc 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1392,7 +1392,7 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, guint i, num_filters = 0; VAStatus va_status; VARectangle src_rect, dst_rect; - guint va_mirror = from_GstVideoOrientationMethod (filter->video_direction); + guint va_mirror = 0, va_rotation = 0; if (!ensure_operations (filter)) return GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED; @@ -1475,8 +1475,12 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, pipeline_param->filters = filters; pipeline_param->num_filters = num_filters; + from_GstVideoOrientationMethod (filter->video_direction, &va_mirror, + &va_rotation); + #if VA_CHECK_VERSION(1,1,0) pipeline_param->mirror_state = va_mirror; + pipeline_param->rotation_state = va_rotation; #endif // Reference frames for advanced deinterlacing @@ -1893,20 +1897,38 @@ gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter, break; case GST_VIDEO_ORIENTATION_HORIZ: case GST_VIDEO_ORIENTATION_VERT: + case GST_VIDEO_ORIENTATION_90R: + case GST_VIDEO_ORIENTATION_180: + case GST_VIDEO_ORIENTATION_90L: + case GST_VIDEO_ORIENTATION_UL_LR: + case GST_VIDEO_ORIENTATION_UR_LL: { #if VA_CHECK_VERSION(1,1,0) VAProcPipelineCaps pipeline_caps; - guint va_mirror = from_GstVideoOrientationMethod (method); + guint va_mirror = VA_MIRROR_NONE; + guint va_rotation = VA_ROTATION_NONE; VAStatus va_status = vaQueryVideoProcPipelineCaps (filter->va_display, filter->va_context, NULL, 0, &pipeline_caps); if (!vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()")) return FALSE; - if (!(pipeline_caps.mirror_flags & va_mirror)) { - GST_WARNING ("%s video-direction unsupported", - gst_vaapi_get_video_direction_nick (method)); - return TRUE; + from_GstVideoOrientationMethod (method, &va_mirror, &va_rotation); + + if (va_mirror != VA_MIRROR_NONE) { + if (!(pipeline_caps.mirror_flags & va_mirror)) { + GST_WARNING ("%s video-direction unsupported", + gst_vaapi_get_video_direction_nick (method)); + return TRUE; + } + } + + if (va_rotation != VA_ROTATION_NONE) { + if (!(pipeline_caps.rotation_flags & (1 << va_rotation))) { + GST_WARNING ("%s video-direction unsupported", + gst_vaapi_get_video_direction_nick (method)); + return TRUE; + } } #else GST_WARNING ("%s video-direction unsupported", diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 736fafaccb..54eef61988 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -821,26 +821,50 @@ to_GstVaapiScaleMethod (guint flags) return method; } -/* VPP: translate GstVideoOrientationMethod into VA mirror flags */ -guint -from_GstVideoOrientationMethod (guint value) +/* VPP: translate GstVideoOrientationMethod into VA mirror/rotation flags */ +void +from_GstVideoOrientationMethod (guint value, guint * va_mirror, + guint * va_rotation) { - guint va_flags = 0; + *va_mirror = 0; + *va_rotation = 0; switch (value) { #if VA_CHECK_VERSION(1,1,0) case GST_VIDEO_ORIENTATION_IDENTITY: - va_flags = VA_MIRROR_NONE; + *va_mirror = VA_MIRROR_NONE; + *va_rotation = VA_ROTATION_NONE; break; case GST_VIDEO_ORIENTATION_HORIZ: - va_flags = VA_MIRROR_HORIZONTAL; + *va_mirror = VA_MIRROR_HORIZONTAL; + *va_rotation = VA_ROTATION_NONE; break; case GST_VIDEO_ORIENTATION_VERT: - va_flags = VA_MIRROR_VERTICAL; + *va_mirror = VA_MIRROR_VERTICAL; + *va_rotation = VA_ROTATION_NONE; + break; + case GST_VIDEO_ORIENTATION_90R: + *va_mirror = VA_MIRROR_NONE; + *va_rotation = VA_ROTATION_90; + break; + case GST_VIDEO_ORIENTATION_180: + *va_mirror = VA_MIRROR_NONE; + *va_rotation = VA_ROTATION_180; + break; + case GST_VIDEO_ORIENTATION_90L: + *va_mirror = VA_MIRROR_NONE; + *va_rotation = VA_ROTATION_270; + break; + case GST_VIDEO_ORIENTATION_UL_LR: + *va_mirror = VA_MIRROR_HORIZONTAL; + *va_rotation = VA_ROTATION_90; + break; + case GST_VIDEO_ORIENTATION_UR_LL: + *va_mirror = VA_MIRROR_VERTICAL; + *va_rotation = VA_ROTATION_90; break; #endif default: break; } - return va_flags; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index cf12051230..d45264f5f6 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -148,7 +148,8 @@ guint to_GstVaapiScaleMethod (guint flags); G_GNUC_INTERNAL -guint -from_GstVideoOrientationMethod (guint value); +void +from_GstVideoOrientationMethod (guint value, guint * va_mirror, + guint * va_rotation); #endif /* GST_VAAPI_UTILS_H */ diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 2b34196b90..e07c0f75a7 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -177,6 +177,17 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, from_w = GST_VIDEO_INFO_WIDTH (vinfo); from_h = GST_VIDEO_INFO_HEIGHT (vinfo); + /* compensate for rotation if needed */ + switch (postproc->video_direction) { + case GST_VIDEO_ORIENTATION_90R: + case GST_VIDEO_ORIENTATION_90L: + case GST_VIDEO_ORIENTATION_UL_LR: + case GST_VIDEO_ORIENTATION_UR_LL: + G_PRIMITIVE_SWAP (gint, from_w, from_h); + default: + break; + } + gst_structure_get_int (outs, "width", &w); gst_structure_get_int (outs, "height", &h); From 4e4ca03bc1ba6d9acecf80e115563bcc4885c85d Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 15 Jul 2019 15:33:07 -0700 Subject: [PATCH 3286/3781] vaapipostproc: update PAR when rotating When rotating, swap pixel-aspect-ratio during negotiation. Fixes #181 --- gst/vaapi/gstvaapipostprocutil.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index e07c0f75a7..81f89c431c 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -184,6 +184,7 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, case GST_VIDEO_ORIENTATION_UL_LR: case GST_VIDEO_ORIENTATION_UR_LL: G_PRIMITIVE_SWAP (gint, from_w, from_h); + G_PRIMITIVE_SWAP (gint, from_par_n, from_par_d); default: break; } From daab4c80a3ecdfe6e960de4745dbc933bf85cec4 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Thu, 23 May 2019 10:18:52 -0400 Subject: [PATCH 3287/3781] libs: encoder: vp9: add low power mode encode By now, this feature only support by media-driver on Ice Lake platform, more information you can reference: https://github.com/intel/media-driver --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 4464f41809..085a184718 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -43,7 +43,8 @@ /* Supported set of tuning options, within this implementation */ #define SUPPORTED_TUNE_OPTIONS \ - (GST_VAAPI_ENCODER_TUNE_MASK (NONE)) + (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 \ @@ -102,6 +103,7 @@ struct _GstVaapiEncoderVP9 guint frame_num; GstVaapiSurfaceProxy *ref_list[GST_VP9_REF_FRAMES]; /* reference list */ guint ref_list_idx; /* next free slot in ref_list */ + GstVaapiEntrypoint entrypoint; /* Bitrate contral parameters, CPB = Coded Picture Buffer */ guint bitrate_bits; /* bitrate (bits) */ @@ -161,7 +163,7 @@ static gboolean ensure_hw_profile (GstVaapiEncoderVP9 * encoder) { GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); - GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + GstVaapiEntrypoint entrypoint = encoder->entrypoint; GstVaapiProfile profile, profiles[2]; guint i, num_profiles = 0; @@ -207,6 +209,8 @@ set_context_info (GstVaapiEncoder * base_encoder) base_encoder->codedbuf_size = GST_ROUND_UP_16 (vip->width) * GST_ROUND_UP_16 (vip->height) * 3 / 2; + base_encoder->context_info.entrypoint = encoder->entrypoint; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } @@ -512,6 +516,8 @@ gst_vaapi_encoder_vp9_reconfigure (GstVaapiEncoder * base_encoder) if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; + if (GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) + encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; ensure_control_rate_params (encoder); return set_context_info (base_encoder); } @@ -526,6 +532,7 @@ gst_vaapi_encoder_vp9_init (GstVaapiEncoder * base_encoder) 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])); From 8b8dfb127a7d8d9e84c749b6a4b9c2ed12338e29 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Sat, 18 May 2019 13:24:35 +0800 Subject: [PATCH 3288/3781] libs: encoder: h264,h265: add new property "max-qp" Add new property "max-qp" to allow set the maximum quantisation parameter values. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 32 +++++++++++++++---- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 29 ++++++++++++++--- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h | 4 ++- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 31 ++++++++++++++---- gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 2 ++ 6 files changed, 81 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index e3c391db15..3abd23c870 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -745,6 +745,7 @@ struct _GstVaapiEncoderH264 guint32 ip_period; guint32 init_qp; guint32 min_qp; + guint32 max_qp; guint32 qp_i; guint32 qp_ip; guint32 qp_ib; @@ -2398,9 +2399,9 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, (gint) encoder->min_qp) { slice_param->slice_qp_delta = encoder->min_qp - encoder->init_qp; } - /* TODO: max_qp might be provided as a property in the future */ - if ((gint) encoder->init_qp + slice_param->slice_qp_delta > 51) { - slice_param->slice_qp_delta = 51 - encoder->init_qp; + if ((gint) encoder->init_qp + slice_param->slice_qp_delta > + (gint) encoder->max_qp) { + slice_param->slice_qp_delta = encoder->max_qp - encoder->init_qp; } } slice_param->disable_deblocking_filter_idc = 0; @@ -2521,10 +2522,7 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; #if VA_CHECK_VERSION(1,1,0) - /* @FIXME: should not set this value, should be ignored if set to zero * - * https://github.com/intel/media-driver/issues/587 */ - if (encoder->min_qp > 0) - GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).max_qp = 51; + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).max_qp = encoder->max_qp; #endif #if VA_CHECK_VERSION(1,0,0) @@ -2753,8 +2751,12 @@ reset_properties (GstVaapiEncoderH264 * encoder) if (encoder->idr_period < base_encoder->keyframe_period) encoder->idr_period = base_encoder->keyframe_period; + g_assert (encoder->min_qp <= encoder->max_qp); if (encoder->min_qp > encoder->init_qp) encoder->min_qp = encoder->init_qp; + if (encoder->max_qp < encoder->init_qp) + encoder->max_qp = encoder->init_qp; + encoder->qp_i = encoder->init_qp; mb_size = encoder->mb_width * encoder->mb_height; @@ -3547,6 +3549,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE: encoder->prediction_type = g_value_get_enum (value); break; + case GST_VAAPI_ENCODER_H264_PROP_MAX_QP: + encoder->max_qp = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; @@ -3649,6 +3654,19 @@ gst_vaapi_encoder_h264_get_default_properties (void) "Minimum QP", "Minimum quantizer value", 0, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264:max-qp: + * + * The maximum quantizer value. + * + * Since: 1.18 + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_MAX_QP, + g_param_spec_uint ("max-qp", + "Maximum QP", "Maximum quantizer value", 0, 51, 51, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiEncoderH264:qp-ip: * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index eb262783a7..ab56d29720 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -56,6 +56,7 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * @GST_VAAPI_ENCODER_H264_PROP_QP_IB: Difference of QP between I and B frame. * @GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS: Number of temporal levels * @GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE: Reference picture selection modes + * @GST_VAAPI_ENCODER_H264_PROP_MAX_QP: Maximal quantizer value (uint). * * The set of H.264 encoder specific configurable properties. */ @@ -77,6 +78,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_QP_IB = -15, GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS = -16, GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE = -17, + GST_VAAPI_ENCODER_H264_PROP_MAX_QP = -18, } GstVaapiEncoderH264Prop; GstVaapiEncoder * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index 9115281980..f8be64fa3d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -766,6 +766,7 @@ struct _GstVaapiEncoderH264Fei guint32 idr_period; guint32 init_qp; guint32 min_qp; + guint32 max_qp; guint32 num_slices; guint32 num_bframes; guint32 mb_width; @@ -2175,6 +2176,10 @@ add_slice_headers (GstVaapiEncoderH264Fei * encoder, slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp; if (slice_param->slice_qp_delta > 4) slice_param->slice_qp_delta = 4; + if ((gint) encoder->init_qp + slice_param->slice_qp_delta > + (gint) encoder->max_qp) { + slice_param->slice_qp_delta = encoder->max_qp - encoder->init_qp; + } slice_param->disable_deblocking_filter_idc = 0; slice_param->slice_alpha_c0_offset_div2 = 2; slice_param->slice_beta_offset_div2 = 2; @@ -2451,10 +2456,7 @@ ensure_misc_params (GstVaapiEncoderH264Fei * encoder, rate_control->min_qp = encoder->min_qp; #if VA_CHECK_VERSION(1,1,0) - /* @FIXME: should not set this value, should be ignored if set to zero * - * https://github.com/intel/media-driver/issues/587 */ - if (rate_control->min_qp > 0) - rate_control->max_qp = 51; + rate_control->max_qp = encoder->max_qp; #endif rate_control->basic_unit_size = 0; @@ -2655,10 +2657,13 @@ reset_properties (GstVaapiEncoderH264Fei * encoder) if (encoder->idr_period < base_encoder->keyframe_period) encoder->idr_period = base_encoder->keyframe_period; + g_assert (encoder->min_qp <= encoder->max_qp); if (encoder->min_qp > encoder->init_qp || (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP && encoder->min_qp < encoder->init_qp)) encoder->min_qp = encoder->init_qp; + if (encoder->max_qp < encoder->init_qp) + encoder->max_qp = encoder->init_qp; mb_size = encoder->mb_width * encoder->mb_height; if (encoder->num_slices > (mb_size + 1) / 2) @@ -3565,6 +3570,9 @@ gst_vaapi_encoder_h264_fei_set_property (GstVaapiEncoder * base_encoder, } break; + case GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_QP: + encoder->max_qp = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; @@ -4072,6 +4080,19 @@ gst_vaapi_encoder_h264_fei_get_default_properties (void) "Minimum QP", "Minimum quantizer value", 0, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH264Fei:max-qp: + * + * The maximum quantizer value. + * + * Since: 1.18 + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_QP, + g_param_spec_uint ("max-qp", + "Maximum QP", "Maximum quantizer value", 0, 51, 51, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiEncoderH264Fei:num-slices: * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h index 3622ed29bc..cd69580be3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h @@ -49,6 +49,7 @@ typedef struct _GstVaapiEncoderH264Fei GstVaapiEncoderH264Fei; * in milliseconds (uint). * @GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS: Number of views per frame. * @GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS: View IDs + * @GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_QP: Maximal quantizer value (uint). * * The set of H.264 encoder specific configurable properties. */ @@ -79,7 +80,8 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L0 = -25, GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L1 = -26, GST_VAAPI_ENCODER_H264_PROP_ENABLE_STATS_OUT = -27, - GST_VAAPI_ENCODER_H264_PROP_FEI_MODE = -28 + GST_VAAPI_ENCODER_H264_PROP_FEI_MODE = -28, + GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_QP = -29, } GstVaapiEncoderH264FeiProp; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 972dcabc7e..bcfa08abb3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -101,6 +101,7 @@ struct _GstVaapiEncoderH265 guint32 idr_period; guint32 init_qp; guint32 min_qp; + guint32 max_qp; guint32 qp_i; guint32 qp_ip; guint32 qp_ib; @@ -1780,9 +1781,9 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, (gint) encoder->min_qp) { slice_param->slice_qp_delta = encoder->min_qp - encoder->init_qp; } - /* TODO: max_qp could be provided as a property in the future */ - if ((gint) encoder->init_qp + slice_param->slice_qp_delta > 51) { - slice_param->slice_qp_delta = 51 - encoder->init_qp; + if ((gint) encoder->init_qp + slice_param->slice_qp_delta > + (gint) encoder->max_qp) { + slice_param->slice_qp_delta = encoder->max_qp - encoder->init_qp; } } @@ -1880,10 +1881,7 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp; #if VA_CHECK_VERSION(1,1,0) - /* @FIXME: should not set this value, should be ignored if set to zero * - * https://github.com/intel/media-driver/issues/587 */ - if (encoder->min_qp > 0) - GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).max_qp = 51; + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).max_qp = encoder->max_qp; #endif #if VA_CHECK_VERSION(1,0,0) @@ -2078,6 +2076,9 @@ reset_properties (GstVaapiEncoderH265 * encoder) if (encoder->min_qp > encoder->init_qp) encoder->min_qp = encoder->init_qp; + if (encoder->max_qp < encoder->init_qp) + encoder->max_qp = encoder->init_qp; + encoder->qp_i = encoder->init_qp; ctu_size = encoder->ctu_width * encoder->ctu_height; @@ -2692,6 +2693,9 @@ gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B: encoder->low_delay_b = g_value_get_boolean (value); break; + case GST_VAAPI_ENCODER_H265_PROP_MAX_QP: + encoder->max_qp = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; @@ -2794,6 +2798,19 @@ gst_vaapi_encoder_h265_get_default_properties (void) "Minimum QP", "Minimum quantizer value", 0, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderH265:max-qp: + * + * The maximum quantizer value. + * + * Since: 1.18 + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H265_PROP_MAX_QP, + g_param_spec_uint ("max-qp", + "Maximum QP", "Maximum quantizer value", 0, 51, 51, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiEncoderH265:qp-ip: * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index 2e594f7218..9004e90eb6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -47,6 +47,7 @@ typedef struct _GstVaapiEncoderH265 GstVaapiEncoderH265; * @GST_VAAPI_ENCODER_H265_PROP_QP_IP: Difference of QP between I and P frame. * @GST_VAAPI_ENCODER_H265_PROP_QP_IB: Difference of QP between I and B frame. * @GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B: use low delay b feature. + * @GST_VAAPI_ENCODER_H265_PROP_MAX_QP: Maximal quantizer value (uint). * * The set of H.265 encoder specific configurable properties. */ @@ -61,6 +62,7 @@ typedef enum { GST_VAAPI_ENCODER_H265_PROP_QP_IP = -9, GST_VAAPI_ENCODER_H265_PROP_QP_IB = -10, GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B = -11, + GST_VAAPI_ENCODER_H265_PROP_MAX_QP = -12, } GstVaapiEncoderH265Prop; GstVaapiEncoder * From ec9a2a4b4e2ca5cfb91c633a7dbf70d27c98c039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 31 May 2019 13:12:35 +0200 Subject: [PATCH 3289/3781] vaapidecode: don't error if can't push buffers downtream When the code path goes to push buffers downstream when no surface available in decoder context, and it fails the code bails out with a fatal error. That behavior is wrong, since it shouldn't be fatal. The use case is when the video stream is disabled. This patch just ignores the errors in this situation and demotes the level of a log message. --- gst/vaapi/gstvaapidecode.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1bd79c1ec1..12878d40d0 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -661,7 +661,7 @@ error_cannot_copy: } error_commit_buffer: { - GST_INFO_OBJECT (decode, "downstream element rejected the frame (%s [%d])", + GST_LOG_OBJECT (decode, "downstream element rejected the frame (%s [%d])", gst_flow_get_name (ret), ret); return ret; } @@ -703,7 +703,6 @@ gst_vaapidecode_handle_frame (GstVideoDecoder * vdec, { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstVaapiDecoderStatus status; - GstFlowReturn ret; if (!decode->input_state) goto not_negotiated; @@ -714,9 +713,7 @@ gst_vaapidecode_handle_frame (GstVideoDecoder * vdec, if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { /* Make sure that there are no decoded frames waiting in the output queue. */ - ret = gst_vaapidecode_push_all_decoded_frames (decode); - if (ret != GST_FLOW_OK) - goto error_push_all_decoded_frames; + gst_vaapidecode_push_all_decoded_frames (decode); g_mutex_lock (&decode->surface_ready_mutex); if (gst_vaapi_decoder_check_status (decode->decoder) == @@ -736,15 +733,12 @@ gst_vaapidecode_handle_frame (GstVideoDecoder * vdec, return gst_vaapidecode_push_all_decoded_frames (decode); /* ERRORS */ -error_push_all_decoded_frames: - { - GST_ERROR ("push loop error while decoding %d", ret); - gst_video_decoder_drop_frame (vdec, frame); - return ret; - } error_decode: { - GST_ERROR ("decode error %d", status); + GstFlowReturn ret = GST_FLOW_OK; + + GST_WARNING_OBJECT (decode, "decode error %d", status); + switch (status) { case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: @@ -752,14 +746,12 @@ error_decode: ret = GST_FLOW_NOT_SUPPORTED; break; default: - ret = GST_FLOW_OK; GST_VIDEO_DECODER_ERROR (vdec, 1, STREAM, DECODE, ("Decoding error"), ("Decode error %d", status), ret); - GST_INFO ("requesting upstream a key unit"); + GST_INFO_OBJECT (decode, "requesting upstream a key unit"); gst_pad_push_event (GST_VIDEO_DECODER_SINK_PAD (decode), gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE, FALSE, 0)); - ret = GST_FLOW_OK; break; } gst_video_decoder_drop_frame (vdec, frame); @@ -768,9 +760,8 @@ error_decode: not_negotiated: { GST_ERROR_OBJECT (decode, "not negotiated"); - ret = GST_FLOW_NOT_NEGOTIATED; gst_video_decoder_drop_frame (vdec, frame); - return ret; + return GST_FLOW_NOT_NEGOTIATED; } } From 1fa172f032accc240d0305e6f4d662be5d4ad129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 7 Jun 2019 09:53:08 +0200 Subject: [PATCH 3290/3781] vaapidecodebin: set properties default values --- gst/vaapi/gstvaapidecodebin.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 4f0dd52fa5..8e4cd344da 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -399,7 +399,9 @@ gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) { GstPad *pad, *ghostpad; - vaapidecbin->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; + vaapidecbin->max_size_bytes = DEFAULT_QUEUE_MAX_SIZE_BYTES; + vaapidecbin->max_size_buffers = DEFAULT_QUEUE_MAX_SIZE_BUFFERS; + vaapidecbin->max_size_time = DEFAULT_QUEUE_MAX_SIZE_TIME; vaapidecbin->disable_vpp = (g_getenv ("GST_VAAPI_DISABLE_VPP") != NULL); /* create the decoder */ From 14ea838512dbc15337c5954b99c40b5baf3a4c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 7 Jun 2019 09:54:12 +0200 Subject: [PATCH 3291/3781] vaapidecodebin: set queue's max size buffers to 1 Otherwise the queue will swallow all the available decoder's surfaces reaching a dead-lock. This setting might impact the bin's peformance, but it's a trade-off. --- gst/vaapi/gstvaapidecodebin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 8e4cd344da..021953bf06 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -57,7 +57,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapi_decode_bin); #define GST_CAT_DEFAULT gst_debug_vaapi_decode_bin -#define DEFAULT_QUEUE_MAX_SIZE_BUFFERS 0 +#define DEFAULT_QUEUE_MAX_SIZE_BUFFERS 1 #define DEFAULT_QUEUE_MAX_SIZE_BYTES 0 #define DEFAULT_QUEUE_MAX_SIZE_TIME 0 #define DEFAULT_DEINTERLACE_METHOD GST_VAAPI_DEINTERLACE_METHOD_BOB From f5c9d86f9c3df71f96da6e561f4db61b9f611398 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Mon, 5 Aug 2019 10:51:24 +0800 Subject: [PATCH 3292/3781] libs: Let GST_VAAPI_RATECONTROL_MASK return unsigned int The value return from GST_VAAPI_RATECONTROL_MASK will be used by GST_VAAPI_POPCOUNT32 as its inpput. GST_VAAPI_POPCOUNT32 can only deal with unsigned int. Otherwise there may be an error of out of range of integer if we define few more rate-control mode. --- gst-libs/gst/vaapi/gstvaapitypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index b958e75a15..9ddef3ce97 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -164,7 +164,7 @@ typedef enum { /* Define a mask for GstVaapiRateControl */ #define GST_VAAPI_RATECONTROL_MASK(RC) \ - (1 << G_PASTE(GST_VAAPI_RATECONTROL_,RC)) + (1U << G_PASTE(GST_VAAPI_RATECONTROL_,RC)) G_END_DECLS From 9e0c133a2403d5457de4e1e247f019a430516ac0 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Thu, 18 Jul 2019 13:32:46 +0800 Subject: [PATCH 3293/3781] libs: encoder: h264: support ICQ/QVBR bitrate control mode ICQ is Intelligent Constant Quality. It will use the initial QP vaule of icq-quality-factor to adjust QP at MB level intelligently to improve subjective quality. QVBR is Quality defined VBR. It will use qvbr-quality-factor to adjust QP for each MB to get enough quality picture without waste of bits. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 35 ++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 ++ gst-libs/gst/vaapi/gstvaapitypes.h | 6 ++++ gst-libs/gst/vaapi/gstvaapiutils.c | 25 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapivalue.c | 4 +++ 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 3abd23c870..1f81e402a8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -54,7 +54,9 @@ (GST_VAAPI_RATECONTROL_MASK (CQP) | \ GST_VAAPI_RATECONTROL_MASK (CBR) | \ GST_VAAPI_RATECONTROL_MASK (VBR) | \ - GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) + GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED) | \ + GST_VAAPI_RATECONTROL_MASK (ICQ) | \ + GST_VAAPI_RATECONTROL_MASK (QVBR)) /* Supported set of tuning options, within this implementation */ #define SUPPORTED_TUNE_OPTIONS \ @@ -753,6 +755,7 @@ struct _GstVaapiEncoderH264 guint32 num_bframes; guint32 mb_width; guint32 mb_height; + guint32 quality_factor; gboolean use_cabac; gboolean use_dct8x8; guint temporal_levels; /* Number of temporal levels */ @@ -2514,6 +2517,14 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder) if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; +#if VA_CHECK_VERSION(1,1,0) + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_ICQ) { + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).ICQ_quality_factor = + encoder->quality_factor; + return TRUE; + } +#endif + /* RateControl params */ GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).bits_per_second = encoder->bitrate_bits; @@ -2530,6 +2541,11 @@ ensure_control_rate_params (GstVaapiEncoderH264 * encoder) (guint) encoder->mbbrc; #endif +#if VA_CHECK_VERSION(1,3,0) + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).quality_factor = + encoder->quality_factor; +#endif + /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); @@ -2681,6 +2697,7 @@ ensure_bitrate (GstVaapiEncoderH264 * encoder) case GST_VAAPI_RATECONTROL_CBR: case GST_VAAPI_RATECONTROL_VBR: case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: + case GST_VAAPI_RATECONTROL_QVBR: if (!base_encoder->bitrate) { /* According to the literature and testing, CABAC entropy coding mode could provide for +10% to +18% improvement in general, @@ -3552,6 +3569,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_H264_PROP_MAX_QP: encoder->max_qp = g_value_get_uint (value); break; + case GST_VAAPI_ENCODER_H264_PROP_QUALITY_FACTOR: + encoder->quality_factor = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; @@ -3838,6 +3858,19 @@ gst_vaapi_encoder_h264_get_default_properties (void) gst_vaapi_encoder_h264_compliance_mode_type (), GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT, G_PARAM_READWRITE)); + /** + * GstVaapiEncoderH264:quality_factor: + * + * quality factor used under ICQ/QVBR bitrate control mode. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_H264_PROP_QUALITY_FACTOR, + g_param_spec_uint ("quality-factor", + "Quality factor for ICQ/QVBR", + "quality factor for ICQ/QVBR bitrate control mode" + "(low value means higher-quality, higher value means lower-quality)", + 1, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index ab56d29720..095fc6bc2c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -57,6 +57,7 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; * @GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS: Number of temporal levels * @GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE: Reference picture selection modes * @GST_VAAPI_ENCODER_H264_PROP_MAX_QP: Maximal quantizer value (uint). + * @GST_VAAPI_ENCODER_H264_PROP_QUALITY_FACTOR: Factor for ICQ/QVBR bitrate control mode. * * The set of H.264 encoder specific configurable properties. */ @@ -79,6 +80,7 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS = -16, GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE = -17, GST_VAAPI_ENCODER_H264_PROP_MAX_QP = -18, + GST_VAAPI_ENCODER_H264_PROP_QUALITY_FACTOR = -19, } GstVaapiEncoderH264Prop; GstVaapiEncoder * diff --git a/gst-libs/gst/vaapi/gstvaapitypes.h b/gst-libs/gst/vaapi/gstvaapitypes.h index 9ddef3ce97..7bbcb4db58 100644 --- a/gst-libs/gst/vaapi/gstvaapitypes.h +++ b/gst-libs/gst/vaapi/gstvaapitypes.h @@ -148,6 +148,10 @@ typedef enum { * @GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: Variable bitrate with peak * rate higher than average bitrate * @GST_VAAPI_RATECONTROL_MB: Macroblock based rate control + * @GST_VAAPI_RATECONTROL_ICQ: Intelligent Constant QP, use + * quality_factor to improve subjective quality base on motion + * @GST_VAAPI_RATECONTROL_QVBR: Quality defined VBR, use + * quality_factor to get good enough quality and save bits * * The set of allowed rate control values for #GstVaapiRateControl. * Note: this is only valid for encoders. @@ -160,6 +164,8 @@ typedef enum { GST_VAAPI_RATECONTROL_VBR, GST_VAAPI_RATECONTROL_VBR_CONSTRAINED, GST_VAAPI_RATECONTROL_MB, + GST_VAAPI_RATECONTROL_ICQ, + GST_VAAPI_RATECONTROL_QVBR, } GstVaapiRateControl; /* Define a mask for GstVaapiRateControl */ diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 54eef61988..f3fd4362ba 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -341,6 +341,14 @@ string_of_VARateControl (guint rate_control) #if VA_CHECK_VERSION(0,39,1) case VA_RC_MB: return "MB"; +#endif +#if VA_CHECK_VERSION(1,1,0) + case VA_RC_ICQ: + return "VA_RC_ICQ"; +#endif +#if VA_CHECK_VERSION(1,3,0) + case VA_RC_QVBR: + return "VA_RC_QVBR"; #endif default: break; @@ -710,6 +718,14 @@ from_GstVaapiRateControl (guint value) #if VA_CHECK_VERSION(0,39,1) case GST_VAAPI_RATECONTROL_MB: return VA_RC_MB; +#endif +#if VA_CHECK_VERSION(1,1,0) + case GST_VAAPI_RATECONTROL_ICQ: + return VA_RC_ICQ; +#endif +#if VA_CHECK_VERSION(1,3,0) + case GST_VAAPI_RATECONTROL_QVBR: + return VA_RC_QVBR; #endif } GST_ERROR ("unsupported GstVaapiRateControl value %u", value); @@ -736,6 +752,15 @@ to_GstVaapiRateControl (guint value) case VA_RC_MB: return GST_VAAPI_RATECONTROL_MB; #endif +#if VA_CHECK_VERSION(1,1,0) + case VA_RC_ICQ: + return GST_VAAPI_RATECONTROL_ICQ; +#endif +#if VA_CHECK_VERSION(1,3,0) + case VA_RC_QVBR: + return GST_VAAPI_RATECONTROL_QVBR; +#endif + } GST_ERROR ("unsupported VA-API Rate Control value %u", value); return GST_VAAPI_RATECONTROL_NONE; diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index d5e192af99..65e3e25d29 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -150,6 +150,10 @@ gst_vaapi_rate_control_get_type (void) "Variable bitrate - Constrained", "vbr_constrained"}, {GST_VAAPI_RATECONTROL_MB, "Macroblock based rate control", "mb"}, + {GST_VAAPI_RATECONTROL_ICQ, + "Constant QP - Intelligent", "icq"}, + {GST_VAAPI_RATECONTROL_QVBR, + "Variable bitrate - Quality defined", "qvbr"}, {0, NULL, NULL}, }; From e48b0a90f10ed76f63a9f829e9d54ca97200b2a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 12 Aug 2019 18:41:52 +0200 Subject: [PATCH 3294/3781] vaapivideomemory: demote error message to info The main reason to demote the message's level is because it is not an error, it's a possible output of the trial and there's a code path that handles it. Secondly, it's very annoying when using gallium driver for radeon. --- gst/vaapi/gstvaapivideomemory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 16bf143342..5da1b18e8c 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -709,7 +709,7 @@ bail: /* ERRORS */ error_no_derive_image: { - GST_ERROR ("Cannot create a VA derived image from surface %p", surface); + GST_INFO ("Cannot create a VA derived image from surface %p", surface); return FALSE; } error_cannot_map: From 0afc81312359cd2f1756bd713efa48a161d6d8c2 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 18 Jul 2019 22:01:01 +0800 Subject: [PATCH 3295/3781] libs: encoder: Consider vp9 profiles based on input format. Only support GST_VAAPI_PROFILE_VP9_0 and GST_VAAPI_PROFILE_VP9_2 now. Fix: #184 --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 085a184718..14a161664f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -149,8 +149,20 @@ ensure_bitrate (GstVaapiEncoderVP9 * encoder) static GstVaapiEncoderStatus ensure_profile (GstVaapiEncoderVP9 * encoder) { - /* Always start from "simple" profile for maximum compatibility */ - encoder->profile = GST_VAAPI_PROFILE_VP9_0; + /* + 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 */ + const GstVideoFormat format = + GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); + if (format == GST_VIDEO_FORMAT_P010_10LE) + encoder->profile = GST_VAAPI_PROFILE_VP9_2; + else if (format == GST_VIDEO_FORMAT_NV12) + encoder->profile = GST_VAAPI_PROFILE_VP9_0; + else + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; /* Ensure bitrate if not set already */ ensure_bitrate (encoder); From 5939bf4d81054f302fe9b14af491fed08e58dcb4 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 17 Jul 2019 11:56:45 +0800 Subject: [PATCH 3296/3781] libs: utils: Add missing entries for string_of_VAEntrypoint. --- gst-libs/gst/vaapi/gstvaapiutils.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index f3fd4362ba..b9e09b5d41 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -257,6 +257,11 @@ string_of_VAEntrypoint (VAEntrypoint entrypoint) MAP (IDCT); MAP (MoComp); MAP (Deblocking); + MAP (EncSlice); + MAP (EncPicture); + MAP (EncSliceLP); + MAP (VideoProc); + MAP (FEI); #undef MAP default: break; From e96a435756b78f477bc29c465c62554f26bb8bc3 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 30 May 2019 23:52:51 +0800 Subject: [PATCH 3297/3781] libs: videopool: fix undocumented behavior and counting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gst_vaapi_video_pool_reserve_unlocked() hit an undocumented behavoir because it locks twice the same mutex. Also, n had different meanings in the current code: as an increase value and as a new total of allocated surfaces. This patche removes the undocumented behavoir (usually a deadlock) and fixes the meaning of n as the new total of allocated surfaces. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapivideopool.c | 32 ++++++++++++-------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 52ed1e812a..e431b52d1c 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -328,30 +328,16 @@ gst_vaapi_video_pool_get_size (GstVaapiVideoPool * pool) return size; } -/** - * gst_vaapi_video_pool_reserve: - * @pool: a #GstVaapiVideoPool - * @n: the number of objects to pre-allocate - * - * Pre-allocates up to @n objects in the pool. If @n is less than or - * equal to the number of free and used objects in the pool, this call - * has no effect. Otherwise, it is a request for allocation of - * additional objects. - * - * Return value: %TRUE on success - */ static gboolean gst_vaapi_video_pool_reserve_unlocked (GstVaapiVideoPool * pool, guint n) { guint i, num_allocated; - num_allocated = gst_vaapi_video_pool_get_size (pool) + pool->used_count; - if (n < num_allocated) + num_allocated = g_queue_get_length (&pool->free_objects) + pool->used_count; + if (n <= num_allocated) return TRUE; - if ((n -= num_allocated) > pool->capacity) - n = pool->capacity; - + n = MIN (n, pool->capacity); for (i = num_allocated; i < n; i++) { gpointer object; @@ -365,6 +351,18 @@ gst_vaapi_video_pool_reserve_unlocked (GstVaapiVideoPool * pool, guint n) return TRUE; } +/** + * gst_vaapi_video_pool_reserve: + * @pool: a #GstVaapiVideoPool + * @n: the number of objects to pre-allocate + * + * Pre-allocates up to @n objects in the pool. If @n is less than or + * equal to the number of free and used objects in the pool, this call + * has no effect. Otherwise, it is a request for allocation of + * additional objects. + * + * Return value: %TRUE on success + */ gboolean gst_vaapi_video_pool_reserve (GstVaapiVideoPool * pool, guint n) { From b9a6dcd7f2398a22f14e49000997f22f58d414ee Mon Sep 17 00:00:00 2001 From: Wangfei Date: Fri, 16 Aug 2019 11:02:08 +0800 Subject: [PATCH 3298/3781] libs: h265dec: remove limitation of get iq matrix According hevc spec, scaling_list_data is not related to chroma_format_idc. --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 21dcb4cede..7a5a2e6165 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1296,10 +1296,6 @@ ensure_quant_matrix (GstVaapiDecoderH265 * decoder, } iq_matrix = base_picture->iq_matrix->param; - /* Only supporting 4:2:0 */ - if (sps->chroma_format_idc != 1) - return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; - fill_iq_matrix_4x4 (iq_matrix, scaling_list); fill_iq_matrix_8x8 (iq_matrix, scaling_list); fill_iq_matrix_16x16 (iq_matrix, scaling_list); From a48625d7ff5ff637dd8921899726764cb10d82d9 Mon Sep 17 00:00:00 2001 From: Yan Wang Date: Tue, 6 Aug 2019 19:24:08 +0800 Subject: [PATCH 3299/3781] libs: filter: set all color balance values When set multiple settings of color balance like hue, saturation, brightness and contrast for vaapipostproc, they should be set as parameters of color balance filter, at the same color balance filter calling. Otherwise, multiple color balance filter calling will cause previous setting get reset by the last calling with default value. Fixes #182. Signed-off-by: Yan Wang --- gst-libs/gst/vaapi/gstvaapifilter.c | 100 +++++++++++++++++++++++----- gst-libs/gst/vaapi/gstvaapiutils.c | 11 ++- gst-libs/gst/vaapi/gstvaapiutils.h | 6 ++ 3 files changed, 98 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 1fd9e5acbc..4e3d62694c 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -791,13 +791,20 @@ find_operation (GstVaapiFilter * filter, GstVaapiFilterOp op) /* Ensure the operation's VA buffer is allocated */ static inline gboolean -op_ensure_buffer (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data) +op_ensure_n_elements_buffer (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data, gint op_num) { if (G_LIKELY (op_data->va_buffer != VA_INVALID_ID)) return TRUE; - return vaapi_create_buffer (filter->va_display, filter->va_context, + return vaapi_create_n_elements_buffer (filter->va_display, filter->va_context, VAProcFilterParameterBufferType, op_data->va_buffer_size, NULL, - &op_data->va_buffer, NULL); + &op_data->va_buffer, NULL, op_num); +} + +static inline gboolean +op_ensure_buffer (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data) +{ + return op_ensure_n_elements_buffer (filter, op_data, 1); } /* Update a generic filter (float value) */ @@ -844,6 +851,9 @@ op_set_generic (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, } /* Update the color balance filter */ +#define COLOR_BALANCE_NUM \ + GST_VAAPI_FILTER_OP_CONTRAST - GST_VAAPI_FILTER_OP_HUE + 1 + static gboolean op_set_color_balance_unlocked (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, gfloat value) @@ -851,27 +861,81 @@ op_set_color_balance_unlocked (GstVaapiFilter * filter, VAProcFilterParameterBufferColorBalance *buf; VAProcFilterCapColorBalance *filter_cap; gfloat va_value; + gint i; + GstVaapiFilterOpData *color_data[COLOR_BALANCE_NUM]; + GstVaapiFilterOpData *enabled_data = NULL; - if (!op_data || !op_ensure_buffer (filter, op_data)) + if (!op_data) return FALSE; - op_data->is_enabled = - (value != G_PARAM_SPEC_FLOAT (op_data->pspec)->default_value); - if (!op_data->is_enabled) - return TRUE; + /* collect all the Color Balance operators and find the first + * enabled one */ + for (i = 0; i < COLOR_BALANCE_NUM; i++) { + color_data[i] = find_operation (filter, GST_VAAPI_FILTER_OP_HUE + i); + if (!color_data[i]) + return FALSE; - filter_cap = op_data->va_caps; - if (!op_data_get_value_float (op_data, &filter_cap->range, value, &va_value)) - return FALSE; + if (!enabled_data && color_data[i]->is_enabled) + enabled_data = color_data[i]; + } - buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer); - if (!buf) - return FALSE; + /* If there's no enabled operators let's enable this one. + * + * HACK: This operator will be the only one with an allocated buffer + * which will store all the color balance operators. + */ + if (!enabled_data) { + if (value == G_PARAM_SPEC_FLOAT (op_data->pspec)->default_value) + return TRUE; + + if (!op_ensure_n_elements_buffer (filter, op_data, COLOR_BALANCE_NUM)) + return FALSE; + + enabled_data = op_data; + + buf = vaapi_map_buffer (filter->va_display, enabled_data->va_buffer); + if (!buf) + return FALSE; + + /* Write all the color balance operator values in the buffer. -- + * Use the default value for all the operators except the set + * one. */ + for (i = 0; i < COLOR_BALANCE_NUM; i++) { + buf[i].type = color_data[i]->va_type; + buf[i].attrib = color_data[i]->va_subtype; + + va_value = G_PARAM_SPEC_FLOAT (color_data[i]->pspec)->default_value; + if (color_data[i]->op == op_data->op) { + filter_cap = color_data[i]->va_caps; + /* don't fail, just ignore current value and set default one */ + op_data_get_value_float (color_data[i], &filter_cap->range, value, + &va_value); + } + + buf[i].value = va_value; + } + + enabled_data->is_enabled = 1; + } else { + /* There's already one operator enabled, *in theory* with a + * buffer associated. */ + if (G_UNLIKELY (enabled_data->va_buffer == VA_INVALID_ID)) + return FALSE; + + filter_cap = op_data->va_caps; + if (!op_data_get_value_float (op_data, &filter_cap->range, value, + &va_value)) + return FALSE; + + buf = vaapi_map_buffer (filter->va_display, enabled_data->va_buffer); + if (!buf) + return FALSE; + + buf[op_data->op - GST_VAAPI_FILTER_OP_HUE].value = va_value; + } + + vaapi_unmap_buffer (filter->va_display, enabled_data->va_buffer, NULL); - buf->type = op_data->va_type; - buf->attrib = op_data->va_subtype; - buf->value = va_value; - vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index b9e09b5d41..874b598e9b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -164,12 +164,21 @@ vaapi_unmap_buffer (VADisplay dpy, VABufferID buf_id, gpointer * pbuf) gboolean vaapi_create_buffer (VADisplay dpy, VAContextID ctx, int type, guint size, gconstpointer buf, VABufferID * buf_id_ptr, gpointer * mapped_data) +{ + return vaapi_create_n_elements_buffer (dpy, ctx, type, size, buf, buf_id_ptr, + mapped_data, 1); +} + +gboolean +vaapi_create_n_elements_buffer (VADisplay dpy, VAContextID ctx, int type, + guint size, gconstpointer buf, VABufferID * buf_id_ptr, + gpointer * mapped_data, int num_elements) { VABufferID buf_id; VAStatus status; gpointer data = (gpointer) buf; - status = vaCreateBuffer (dpy, ctx, type, size, 1, data, &buf_id); + status = vaCreateBuffer (dpy, ctx, type, size, num_elements, data, &buf_id); if (!vaapi_check_status (status, "vaCreateBuffer()")) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index d45264f5f6..d83a049bb7 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -54,6 +54,12 @@ gboolean vaapi_create_buffer (VADisplay dpy, VAContextID ctx, int type, guint size, gconstpointer data, VABufferID * buf_id, gpointer * mapped_data); +G_GNUC_INTERNAL +gboolean +vaapi_create_n_elements_buffer (VADisplay dpy, VAContextID ctx, int type, + guint size, gconstpointer data, VABufferID * buf_id, gpointer * mapped_data, + int num_elements); + /** Destroy VA buffer */ G_GNUC_INTERNAL void From d0605827987ed01b6bf632786025bba86844446e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 16 Aug 2019 13:25:06 +0200 Subject: [PATCH 3300/3781] libs: filter: fail if first color balance value is invalid --- gst-libs/gst/vaapi/gstvaapifilter.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 4e3d62694c..357229444f 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -864,6 +864,7 @@ op_set_color_balance_unlocked (GstVaapiFilter * filter, gint i; GstVaapiFilterOpData *color_data[COLOR_BALANCE_NUM]; GstVaapiFilterOpData *enabled_data = NULL; + gboolean ret = TRUE; if (!op_data) return FALSE; @@ -907,9 +908,10 @@ op_set_color_balance_unlocked (GstVaapiFilter * filter, va_value = G_PARAM_SPEC_FLOAT (color_data[i]->pspec)->default_value; if (color_data[i]->op == op_data->op) { filter_cap = color_data[i]->va_caps; - /* don't fail, just ignore current value and set default one */ - op_data_get_value_float (color_data[i], &filter_cap->range, value, - &va_value); + /* fail but ignore current value and set default one */ + if (!op_data_get_value_float (color_data[i], &filter_cap->range, value, + &va_value)) + ret = FALSE; } buf[i].value = va_value; @@ -936,7 +938,7 @@ op_set_color_balance_unlocked (GstVaapiFilter * filter, vaapi_unmap_buffer (filter->va_display, enabled_data->va_buffer, NULL); - return TRUE; + return ret; } static inline gboolean From e4bb8f5895ddb93296ae76a6978cd69cda565e28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 16 Aug 2019 19:51:29 +0200 Subject: [PATCH 3301/3781] libs: encoder: vp9: set VP9_0 profile as default Commit 0afc8131 introduced a regression and only NV12 format were admitted, failing in any other valid color format. This patch sets the profile to GST_VAAPI_PROFILE_VP9_0 by default. --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 14a161664f..38ad4c1402 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -159,10 +159,8 @@ ensure_profile (GstVaapiEncoderVP9 * encoder) GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); if (format == GST_VIDEO_FORMAT_P010_10LE) encoder->profile = GST_VAAPI_PROFILE_VP9_2; - else if (format == GST_VIDEO_FORMAT_NV12) - encoder->profile = GST_VAAPI_PROFILE_VP9_0; else - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + encoder->profile = GST_VAAPI_PROFILE_VP9_0; /* Ensure bitrate if not set already */ ensure_bitrate (encoder); From 47ff72a6d4ada28719446486f98f71481a00c2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 26 Jul 2019 19:09:54 +0200 Subject: [PATCH 3302/3781] libs: filter: check mirror and rotation caps only once This patch locks the display before querying the pipeline caps and stores the mirror and rotation capabilities, thus they are not queried every time the video direction is set. --- gst-libs/gst/vaapi/gstvaapifilter.c | 88 +++++++++++++++-------------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 357229444f..ce1c2a0168 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -69,6 +69,8 @@ struct _GstVaapiFilter GstVaapiRectangle target_rect; guint use_crop_rect:1; guint use_target_rect:1; + guint32 mirror_flags; + guint32 rotation_flags; }; typedef struct _GstVaapiFilterClass GstVaapiFilterClass; @@ -283,6 +285,34 @@ vpp_get_filter_caps (GstVaapiFilter * filter, VAProcFilterType type, return caps; } +static void +vpp_get_pipeline_caps_unlocked (GstVaapiFilter * filter) +{ +#if VA_CHECK_VERSION(1,1,0) + VAProcPipelineCaps pipeline_caps = { 0, }; + + VAStatus va_status = vaQueryVideoProcPipelineCaps (filter->va_display, + filter->va_context, NULL, 0, &pipeline_caps); + + if (vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()")) { + filter->mirror_flags = pipeline_caps.mirror_flags; + filter->rotation_flags = pipeline_caps.rotation_flags; + return; + } +#endif + + filter->mirror_flags = 0; + filter->rotation_flags = 0; +} + +static void +vpp_get_pipeline_caps (GstVaapiFilter * filter) +{ + GST_VAAPI_DISPLAY_LOCK (filter->display); + vpp_get_pipeline_caps_unlocked (filter); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); +} + /* ------------------------------------------------------------------------- */ /* --- VPP Operations --- */ /* ------------------------------------------------------------------------- */ @@ -715,6 +745,8 @@ get_operations_ordered (GstVaapiFilter * filter, GPtrArray * default_ops) filter_caps = NULL; } + vpp_get_pipeline_caps (filter); + if (filter->operations) g_ptr_array_unref (filter->operations); filter->operations = g_ptr_array_ref (ops); @@ -1037,7 +1069,6 @@ op_set_skintone (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, return success; } - static gboolean deint_refs_set (GArray * refs, GstVaapiSurface ** surfaces, guint num_surfaces) { @@ -1958,56 +1989,31 @@ gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter, { g_return_val_if_fail (filter != NULL, FALSE); - switch (method) { - case GST_VIDEO_ORIENTATION_IDENTITY: - break; - case GST_VIDEO_ORIENTATION_HORIZ: - case GST_VIDEO_ORIENTATION_VERT: - case GST_VIDEO_ORIENTATION_90R: - case GST_VIDEO_ORIENTATION_180: - case GST_VIDEO_ORIENTATION_90L: - case GST_VIDEO_ORIENTATION_UL_LR: - case GST_VIDEO_ORIENTATION_UR_LL: - { #if VA_CHECK_VERSION(1,1,0) - VAProcPipelineCaps pipeline_caps; - guint va_mirror = VA_MIRROR_NONE; - guint va_rotation = VA_ROTATION_NONE; + { + guint32 va_mirror = VA_MIRROR_NONE; + guint32 va_rotation = VA_ROTATION_NONE; - VAStatus va_status = vaQueryVideoProcPipelineCaps (filter->va_display, - filter->va_context, NULL, 0, &pipeline_caps); - if (!vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()")) - return FALSE; + from_GstVideoOrientationMethod (method, &va_mirror, &va_rotation); - from_GstVideoOrientationMethod (method, &va_mirror, &va_rotation); - - if (va_mirror != VA_MIRROR_NONE) { - if (!(pipeline_caps.mirror_flags & va_mirror)) { - GST_WARNING ("%s video-direction unsupported", - gst_vaapi_get_video_direction_nick (method)); - return TRUE; - } - } - - if (va_rotation != VA_ROTATION_NONE) { - if (!(pipeline_caps.rotation_flags & (1 << va_rotation))) { - GST_WARNING ("%s video-direction unsupported", - gst_vaapi_get_video_direction_nick (method)); - return TRUE; - } - } -#else + if (va_mirror != VA_MIRROR_NONE && !(filter->mirror_flags & va_mirror)) { GST_WARNING ("%s video-direction unsupported", gst_vaapi_get_video_direction_nick (method)); return TRUE; -#endif - break; } - default: - GST_WARNING ("%s video-direction unsupported or unimplemented", + + if (va_rotation != VA_ROTATION_NONE + && !(filter->rotation_flags & (1 << va_rotation))) { + GST_WARNING ("%s video-direction unsupported", gst_vaapi_get_video_direction_nick (method)); return TRUE; + } } +#else + GST_WARNING ("%s video-direction unsupported", + gst_vaapi_get_video_direction_nick (method)); + return TRUE; +#endif filter->video_direction = method; return TRUE; From c06b58781962c7668f4d5da6c27376dbe2dba54e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 26 Jul 2019 19:46:09 +0200 Subject: [PATCH 3303/3781] vaapipostproc: element warning if video direction is unsupported If the video direction is unsupported by the driver, an element warning is posted in the bus to notify the application. gst_vaapi_enum_type_get_nick() was added in the library thus it can be used elsewhere. It retrives the nick from an enum gtype. --- gst-libs/gst/vaapi/gstvaapifilter.c | 29 +++++------------------------ gst-libs/gst/vaapi/gstvaapivalue.c | 19 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivalue.h | 4 ++++ gst/vaapi/gstvaapipostproc.c | 13 +++++++++++-- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index ce1c2a0168..4f98a62371 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -118,17 +118,6 @@ gst_vaapi_scale_method_get_type (void) return g_type; } -static const gchar * -gst_vaapi_get_video_direction_nick (GstVideoOrientationMethod method) -{ - gpointer const klass = g_type_class_peek (GST_TYPE_VIDEO_ORIENTATION_METHOD); - GEnumValue *const e = g_enum_get_value (klass, method); - - if (e) - return e->value_nick; - return ""; -} - GType gst_vaapi_deinterlace_method_get_type (void) { @@ -1996,23 +1985,15 @@ gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter, from_GstVideoOrientationMethod (method, &va_mirror, &va_rotation); - if (va_mirror != VA_MIRROR_NONE && !(filter->mirror_flags & va_mirror)) { - GST_WARNING ("%s video-direction unsupported", - gst_vaapi_get_video_direction_nick (method)); - return TRUE; - } + if (va_mirror != VA_MIRROR_NONE && !(filter->mirror_flags & va_mirror)) + return FALSE; if (va_rotation != VA_ROTATION_NONE - && !(filter->rotation_flags & (1 << va_rotation))) { - GST_WARNING ("%s video-direction unsupported", - gst_vaapi_get_video_direction_nick (method)); - return TRUE; - } + && !(filter->rotation_flags & (1 << va_rotation))) + return FALSE; } #else - GST_WARNING ("%s video-direction unsupported", - gst_vaapi_get_video_direction_nick (method)); - return TRUE; + return FALSE; #endif filter->video_direction = method; diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 65e3e25d29..5b5c990197 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -215,3 +215,22 @@ gst_vaapi_type_define_enum_subset_from_mask (GstVaapiEnumSubset * subset, } return subset->type; } + +/** + * gst_vaapi_enum_type_get_nick: + * @type: an enum #GType + * @value: the value to get its nick + * + * Returns: (tranfer none); the string associated with + * @value. Otherwise "" + **/ +const gchar * +gst_vaapi_enum_type_get_nick (GType type, gint value) +{ + gpointer const klass = g_type_class_peek (type); + GEnumValue *const e = g_enum_get_value (klass, value); + + if (e) + return e->value_nick; + return ""; +} diff --git a/gst-libs/gst/vaapi/gstvaapivalue.h b/gst-libs/gst/vaapi/gstvaapivalue.h index e7d445a1a2..f462671504 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.h +++ b/gst-libs/gst/vaapi/gstvaapivalue.h @@ -157,6 +157,10 @@ G_PASTE(name,_get_type)(void) \ return gst_vaapi_type_define_enum_subset_from_mask(&subset, MASK); \ } +G_GNUC_INTERNAL +const gchar * +gst_vaapi_enum_type_get_nick (GType type, gint value); + G_END_DECLS #endif /* GST_VAAPI_VALUE_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index d6dc762a02..dab05396ca 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -37,6 +37,8 @@ #include "gstcompat.h" #include +#include + #include "gstvaapipostproc.h" #include "gstvaapipostprocutil.h" #include "gstvaapipluginutil.h" @@ -595,8 +597,15 @@ update_filter (GstVaapiPostproc * postproc) if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION) { if (!gst_vaapi_filter_set_video_direction (postproc->filter, - postproc->video_direction)) - return FALSE; + postproc->video_direction)) { + GST_ELEMENT_WARNING (postproc, LIBRARY, SETTINGS, + ("Unsupported video direction '%s' by driver.", + gst_vaapi_enum_type_get_nick + (GST_TYPE_VIDEO_ORIENTATION_METHOD, postproc->video_direction)), + ("video direction transformation ignored")); + + /* Don't return FALSE because other filters might be set */ + } if (gst_vaapi_filter_get_video_direction_default (postproc->filter) == postproc->video_direction) From bd175f9956e672bd9c9e13604b46f195a809f4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 26 Jul 2019 22:05:29 +0200 Subject: [PATCH 3304/3781] vaapipostproc: update filter before fixate caps It is requiered to know if postproc is capable to change the video direction before fixating the source caps. In order to do it, it'ss required to know if there's a functional VPP, but that's checked at create() vmethod, which occurs after caps fixating. This patch checks for a functional VPP at fixate caps and, if so, checks for the enabled filtes and later do the caps fixations. --- gst/vaapi/gstvaapipostproc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index dab05396ca..5e737e8ec2 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1255,6 +1255,7 @@ gst_vaapipostproc_fixate_caps (GstBaseTransform * trans, { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); GstCaps *outcaps = NULL; + gboolean same_caps, filter_updated = FALSE; GST_DEBUG_OBJECT (trans, "trying to fixate othercaps %" GST_PTR_FORMAT " based on caps %" GST_PTR_FORMAT " in direction %s", othercaps, caps, @@ -1267,11 +1268,18 @@ gst_vaapipostproc_fixate_caps (GstBaseTransform * trans, } g_mutex_lock (&postproc->postproc_lock); + postproc->has_vpp = gst_vaapipostproc_ensure_filter_caps (postproc); + if (check_filter_update (postproc) && update_filter (postproc)) { + /* check again if changed value is default */ + filter_updated = check_filter_update (postproc); + } + outcaps = gst_vaapipostproc_fixate_srccaps (postproc, caps, othercaps); g_mutex_unlock (&postproc->postproc_lock); /* set passthrough according to caps changes or filter changes */ - gst_vaapipostproc_set_passthrough (trans); + same_caps = gst_caps_is_equal (caps, outcaps); + gst_base_transform_set_passthrough (trans, same_caps && !filter_updated); done: GST_DEBUG_OBJECT (trans, "fixated othercaps to %" GST_PTR_FORMAT, outcaps); From b8a333e0c3cbe804311ac25d8054cf0d5f5ae1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 26 Jul 2019 22:09:37 +0200 Subject: [PATCH 3305/3781] vaapipostproc: add missing locks when adding flags --- gst/vaapi/gstvaapipostproc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 5e737e8ec2..4c49097200 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1546,8 +1546,11 @@ gst_vaapipostproc_propose_allocation (GstBaseTransform * trans, goto bail; if (allocation_width != negotiated_width - || allocation_height != negotiated_height) + || allocation_height != negotiated_height) { + g_mutex_lock (&postproc->postproc_lock); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SIZE; + g_mutex_unlock (&postproc->postproc_lock); + } bail: /* Let vaapidecode allocate the video buffers */ @@ -2120,7 +2123,9 @@ gst_vaapipostproc_colorbalance_set_value (GstColorBalance * balance, var = cb_get_value_ptr (postproc, channel, &flags); if (var) { *var = new_val; + g_mutex_lock (&postproc->postproc_lock); postproc->flags |= flags; + g_mutex_unlock (&postproc->postproc_lock); gst_color_balance_value_changed (balance, channel, value); if (check_filter_update (postproc)) gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM (postproc)); From bcb29e839938b3d3898ba475536e9d33ff8f0a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 Jul 2019 21:27:20 +0200 Subject: [PATCH 3306/3781] vaapipostproc: handle image-orientation upstream event Now that vaapipostproc can possible handle video-direction, it should also handle the image-orientation event from upstream if video-direction property is set to auto. --- gst-libs/gst/vaapi/gstvaapifilter.c | 13 ++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 3 ++ gst/vaapi/gstvaapipostproc.c | 71 +++++++++++++++++++++++++++-- gst/vaapi/gstvaapipostproc.h | 1 + gst/vaapi/gstvaapipostprocutil.c | 4 +- 5 files changed, 87 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 4f98a62371..33e37b0c3e 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -2000,6 +2000,19 @@ gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter, return TRUE; } +/** + * gst_vaapi_filter_get_video_direction: + * @filter: a #GstVaapiFilter + * + * Return value: the currently applied video direction (see #GstVideoOrientationMethod) + */ +GstVideoOrientationMethod +gst_vaapi_filter_get_video_direction (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, GST_VIDEO_ORIENTATION_IDENTITY); + return filter->video_direction; +} + static inline gfloat op_get_float_default_value (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 491f459421..45990e0b89 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -253,6 +253,9 @@ 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_skintone (GstVaapiFilter * filter, gboolean enhance); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 4c49097200..401686ab2b 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -596,19 +596,22 @@ update_filter (GstVaapiPostproc * postproc) } if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION) { - if (!gst_vaapi_filter_set_video_direction (postproc->filter, - postproc->video_direction)) { + GstVideoOrientationMethod method = postproc->video_direction; + if (method == GST_VIDEO_ORIENTATION_AUTO) + method = postproc->tag_video_direction; + + if (!gst_vaapi_filter_set_video_direction (postproc->filter, method)) { GST_ELEMENT_WARNING (postproc, LIBRARY, SETTINGS, ("Unsupported video direction '%s' by driver.", gst_vaapi_enum_type_get_nick - (GST_TYPE_VIDEO_ORIENTATION_METHOD, postproc->video_direction)), + (GST_TYPE_VIDEO_ORIENTATION_METHOD, method)), ("video direction transformation ignored")); /* Don't return FALSE because other filters might be set */ } if (gst_vaapi_filter_get_video_direction_default (postproc->filter) == - postproc->video_direction) + method) postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION); } @@ -1568,6 +1571,61 @@ gst_vaapipostproc_decide_allocation (GstBaseTransform * trans, GstQuery * query) query); } +static gboolean +gst_vaapipostproc_sink_event (GstBaseTransform * trans, GstEvent * event) +{ + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + GstTagList *taglist; + gchar *orientation; + gboolean ret; + gboolean do_reconf; + + GST_DEBUG_OBJECT (postproc, "handling %s event", GST_EVENT_TYPE_NAME (event)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_TAG: + gst_event_parse_tag (event, &taglist); + + if (gst_tag_list_get_string (taglist, "image-orientation", &orientation)) { + do_reconf = TRUE; + if (!g_strcmp0 ("rotate-0", orientation)) + postproc->tag_video_direction = GST_VIDEO_ORIENTATION_IDENTITY; + else if (!g_strcmp0 ("rotate-90", orientation)) + postproc->tag_video_direction = GST_VIDEO_ORIENTATION_90R; + else if (!g_strcmp0 ("rotate-180", orientation)) + postproc->tag_video_direction = GST_VIDEO_ORIENTATION_180; + else if (!g_strcmp0 ("rotate-270", orientation)) + postproc->tag_video_direction = GST_VIDEO_ORIENTATION_90L; + else if (!g_strcmp0 ("flip-rotate-0", orientation)) + postproc->tag_video_direction = GST_VIDEO_ORIENTATION_HORIZ; + else if (!g_strcmp0 ("flip-rotate-90", orientation)) + postproc->tag_video_direction = GST_VIDEO_ORIENTATION_UL_LR; + else if (!g_strcmp0 ("flip-rotate-180", orientation)) + postproc->tag_video_direction = GST_VIDEO_ORIENTATION_VERT; + else if (!g_strcmp0 ("flip-rotate-270", orientation)) + postproc->tag_video_direction = GST_VIDEO_ORIENTATION_UR_LL; + else + do_reconf = FALSE; + + g_free (orientation); + + if (do_reconf) { + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION; + gst_base_transform_reconfigure_src (trans); + } + } + break; + default: + break; + } + + ret = + GST_BASE_TRANSFORM_CLASS (gst_vaapipostproc_parent_class)->sink_event + (trans, event); + + return ret; +} + static void gst_vaapipostproc_finalize (GObject * object) { @@ -1749,6 +1807,7 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) trans_class->query = gst_vaapipostproc_query; trans_class->propose_allocation = gst_vaapipostproc_propose_allocation; trans_class->decide_allocation = gst_vaapipostproc_decide_allocation; + trans_class->sink_event = gst_vaapipostproc_sink_event; trans_class->prepare_output_buffer = gst_vaapipostproc_prepare_output_buffer; @@ -2007,6 +2066,10 @@ gst_vaapipostproc_init (GstVaapiPostproc * postproc) postproc->keep_aspect = TRUE; postproc->get_va_surfaces = TRUE; + /* AUTO is not valid for tag_video_direction, this is just to + * ensure we setup the method as sink event tag */ + postproc->tag_video_direction = GST_VIDEO_ORIENTATION_AUTO; + filter_ops = gst_vaapi_filter_get_operations (NULL); if (filter_ops) { for (i = GST_VAAPI_FILTER_OP_HUE; i <= GST_VAAPI_FILTER_OP_CONTRAST; i++) diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 9e73002dc1..0d98923ffe 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -166,6 +166,7 @@ struct _GstVaapiPostproc GstVaapiScaleMethod scale_method; GstVideoOrientationMethod video_direction; + GstVideoOrientationMethod tag_video_direction; /* Color balance filter values */ gfloat hue; diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 81f89c431c..2c576b137d 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -23,6 +23,8 @@ * Boston, MA 02110-1301 USA */ +#include + #include "gstvaapipostprocutil.h" #include "gstvaapipluginutil.h" @@ -178,7 +180,7 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, from_h = GST_VIDEO_INFO_HEIGHT (vinfo); /* compensate for rotation if needed */ - switch (postproc->video_direction) { + switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { case GST_VIDEO_ORIENTATION_90R: case GST_VIDEO_ORIENTATION_90L: case GST_VIDEO_ORIENTATION_UL_LR: From a6aba119b4c5840dd843cc9318b4a12a4d442bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 Jul 2019 21:23:21 +0200 Subject: [PATCH 3307/3781] test-vaapisink: also use vaapipostproc to change orientation --- tests/elements/test-vaapisink.c | 52 +++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/tests/elements/test-vaapisink.c b/tests/elements/test-vaapisink.c index 5bb5c4e10b..41f3fc3e0b 100644 --- a/tests/elements/test-vaapisink.c +++ b/tests/elements/test-vaapisink.c @@ -1,12 +1,19 @@ #include #include #include -#include +#include + +static gboolean use_postproc; +static GOptionEntry g_options[] = { + {"postproc", 'p', 0, G_OPTION_ARG_NONE, &use_postproc, + "use vaapipostproc to rotate rather than vaapisink", NULL}, + {NULL,} +}; typedef struct _CustomData { GstElement *pipeline; - GstElement *video_sink; + GstElement *rotator; GMainLoop *loop; gboolean orient_automatic; } AppData; @@ -18,15 +25,18 @@ send_rotate_event (AppData * data) GstEvent *event; static gint counter = 0; const static gchar *tags[] = { "rotate-90", "rotate-180", "rotate-270", - "rotate-0" + "rotate-0", "flip-rotate-0", "flip-rotate-90", "flip-rotate-180", + "flip-rotate-270", }; event = gst_event_new_tag (gst_tag_list_new (GST_TAG_IMAGE_ORIENTATION, tags[counter++ % G_N_ELEMENTS (tags)], NULL)); /* Send the event */ + g_print ("Sending event %" GST_PTR_FORMAT ": ", event); res = gst_element_send_event (data->pipeline, event); - g_print ("Sending event %p done: %d\n", event, res); + g_print ("%s\n", res ? "ok" : "failed"); + } static void @@ -37,7 +47,13 @@ keyboard_cb (const gchar * key, AppData * data) send_rotate_event (data); break; case 's':{ - g_object_set (G_OBJECT (data->video_sink), "rotation", 360, NULL); + if (use_postproc) { + g_object_set (G_OBJECT (data->rotator), "video-direction", + GST_VIDEO_ORIENTATION_AUTO, NULL); + } else { + /* rotation=360 means auto for vaapisnk */ + g_object_set (G_OBJECT (data->rotator), "rotation", 360, NULL); + } break; } case 'q': @@ -104,25 +120,43 @@ main (int argc, char *argv[]) AppData data; GstStateChangeReturn ret; GIOChannel *io_stdin; + GOptionContext *ctx; GError *err = NULL; guint srcid; /* Initialize GStreamer */ - gst_init (&argc, &argv); + ctx = g_option_context_new ("- test options"); + if (!ctx) + return -1; + g_option_context_add_group (ctx, gst_init_get_option_group ()); + g_option_context_add_main_entries (ctx, g_options, NULL); + if (!g_option_context_parse (ctx, &argc, &argv, NULL)) + return -1; + g_option_context_free (ctx); /* Print usage map */ g_print ("USAGE: Choose one of the following options, then press enter:\n" " 'r' to send image-orientation tag event\n" " 's' to set orient-automatic\n" " 'Q' to quit\n"); - data.pipeline = gst_parse_launch ("videotestsrc ! vaapisink name=sink", &err); + if (use_postproc) { + data.pipeline = + gst_parse_launch ("videotestsrc ! vaapipostproc name=pp ! xvimagesink", + &err); + } else { + data.pipeline = + gst_parse_launch ("videotestsrc ! vaapisink name=sink", &err); + } if (err) { g_printerr ("failed to create pipeline: %s\n", err->message); g_error_free (err); return -1; } - data.video_sink = gst_bin_get_by_name (GST_BIN (data.pipeline), "sink"); + if (use_postproc) + data.rotator = gst_bin_get_by_name (GST_BIN (data.pipeline), "pp"); + else + data.rotator = gst_bin_get_by_name (GST_BIN (data.pipeline), "sink"); srcid = gst_bus_add_watch (GST_ELEMENT_BUS (data.pipeline), bus_msg, &data); /* Add a keyboard watch so we get notified of keystrokes */ @@ -148,7 +182,7 @@ bail: g_main_loop_unref (data.loop); g_io_channel_unref (io_stdin); - gst_object_unref (data.video_sink); + gst_object_unref (data.rotator); gst_object_unref (data.pipeline); return 0; From 6cb3e741fde8dbac822db25f974793c2b724843a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 15 Jul 2019 21:51:46 +0200 Subject: [PATCH 3308/3781] vaapipostproc: handle navigation downstream event When navigation events contains coordiantes those have to be mapped to the new size and/or orientation. --- gst/vaapi/gstvaapipostproc.c | 86 ++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 401686ab2b..ac8bcb29a1 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1571,6 +1571,91 @@ gst_vaapipostproc_decide_allocation (GstBaseTransform * trans, GstQuery * query) query); } +static gboolean +gst_vaapipostproc_src_event (GstBaseTransform * trans, GstEvent * event) +{ + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + gdouble new_x = 0, new_y = 0, x = 0, y = 0; + GstStructure *structure; + gboolean ret; + + GST_DEBUG_OBJECT (postproc, "handling %s event", GST_EVENT_TYPE_NAME (event)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_NAVIGATION: + event = + GST_EVENT (gst_mini_object_make_writable (GST_MINI_OBJECT (event))); + + structure = (GstStructure *) gst_event_get_structure (event); + if (gst_structure_get_double (structure, "pointer_x", &x) && + gst_structure_get_double (structure, "pointer_y", &y)) { + GST_DEBUG_OBJECT (postproc, "converting %fx%f", x, y); + + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SIZE) { + if ((GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) + != GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info)) + && (GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) + != GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info))) { + new_x = + x * GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info) / + GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info); + new_y = + y * GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info) / + GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info); + } + } else if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION) { + switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { + case GST_VIDEO_ORIENTATION_90R: + new_x = y; + new_y = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; + break; + case GST_VIDEO_ORIENTATION_90L: + new_x = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; + new_y = x; + break; + case GST_VIDEO_ORIENTATION_UR_LL: + new_x = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; + new_y = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; + break; + case GST_VIDEO_ORIENTATION_UL_LR: + new_x = y; + new_y = x; + break; + case GST_VIDEO_ORIENTATION_180: + new_x = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; + new_y = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; + break; + case GST_VIDEO_ORIENTATION_HORIZ: + new_x = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; + new_y = y; + break; + case GST_VIDEO_ORIENTATION_VERT: + new_x = x; + new_y = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; + break; + default: + new_x = x; + new_y = y; + break; + } + } + + GST_DEBUG_OBJECT (postproc, "to %fx%f", new_x, new_y); + gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, new_x, + "pointer_y", G_TYPE_DOUBLE, new_y, NULL); + } + break; + default: + break; + } + + ret = + GST_BASE_TRANSFORM_CLASS (gst_vaapipostproc_parent_class)->src_event + (trans, event); + + return ret; +} + static gboolean gst_vaapipostproc_sink_event (GstBaseTransform * trans, GstEvent * event) { @@ -1807,6 +1892,7 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) trans_class->query = gst_vaapipostproc_query; trans_class->propose_allocation = gst_vaapipostproc_propose_allocation; trans_class->decide_allocation = gst_vaapipostproc_decide_allocation; + trans_class->src_event = gst_vaapipostproc_src_event; trans_class->sink_event = gst_vaapipostproc_sink_event; trans_class->prepare_output_buffer = gst_vaapipostproc_prepare_output_buffer; From 1a5e98fcd263456f18e3ee3ad9b7081f44073fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 31 Jul 2019 13:08:43 +0200 Subject: [PATCH 3309/3781] Split the surface attribute retrieval --- gst-libs/gst/vaapi/gstvaapiutils_core.c | 69 +++++++++++++++++-------- 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.c b/gst-libs/gst/vaapi/gstvaapiutils_core.c index 20746667d9..92d886dac3 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_core.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.c @@ -77,6 +77,50 @@ gst_vaapi_get_config_attribute (GstVaapiDisplay * display, VAProfile profile, return TRUE; } +static VASurfaceAttrib * +get_surface_attributes (GstVaapiDisplay * display, VAConfigID config, + guint * num_attribs) +{ + VASurfaceAttrib *surface_attribs = NULL; + guint num_surface_attribs = 0; + VAStatus va_status; + + if (config == VA_INVALID_ID) + goto error; + + GST_VAAPI_DISPLAY_LOCK (display); + va_status = vaQuerySurfaceAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display), + config, NULL, &num_surface_attribs); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()")) + goto error; + + surface_attribs = g_malloc (num_surface_attribs * sizeof (*surface_attribs)); + if (!surface_attribs) + goto error; + + GST_VAAPI_DISPLAY_LOCK (display); + va_status = vaQuerySurfaceAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display), + config, surface_attribs, &num_surface_attribs); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()")) + goto error; + + if (num_attribs) + *num_attribs = num_surface_attribs; + return surface_attribs; + + /* ERRORS */ +error: + { + if (num_attribs) + *num_attribs = -1; + if (surface_attribs) + g_free (surface_attribs); + return NULL; + } +} + /** * gst_vaapi_get_surface_formats: * @display: a #GstVaapiDisplay @@ -92,32 +136,15 @@ gst_vaapi_get_config_attribute (GstVaapiDisplay * display, VAProfile profile, GArray * gst_vaapi_get_surface_formats (GstVaapiDisplay * display, VAConfigID config) { - VASurfaceAttrib *surface_attribs = NULL; + VASurfaceAttrib *surface_attribs; guint i, num_surface_attribs = 0; - VAStatus va_status; GArray *formats; - if (config == VA_INVALID_ID) - return NULL; - - GST_VAAPI_DISPLAY_LOCK (display); - va_status = vaQuerySurfaceAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display), - config, NULL, &num_surface_attribs); - GST_VAAPI_DISPLAY_UNLOCK (display); - if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()")) - return NULL; - - surface_attribs = g_malloc (num_surface_attribs * sizeof (*surface_attribs)); + surface_attribs = + get_surface_attributes (display, config, &num_surface_attribs); if (!surface_attribs) return NULL; - GST_VAAPI_DISPLAY_LOCK (display); - va_status = vaQuerySurfaceAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display), - config, surface_attribs, &num_surface_attribs); - GST_VAAPI_DISPLAY_UNLOCK (display); - if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()")) - return NULL; - formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), num_surface_attribs); if (!formats) @@ -150,6 +177,6 @@ gst_vaapi_get_surface_formats (GstVaapiDisplay * display, VAConfigID config) error: { g_free (surface_attribs); + return NULL; } - return NULL; } From 4ba7c9cae08cfd67cff138250c1ac73364fe6a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 1 Aug 2019 19:13:39 +0200 Subject: [PATCH 3310/3781] libs: utils: add gst_vaapi_config_surface_attributes_get() To extract the surface restrictions per config using a new structure: GstVaapiConfigSurfaceAttributes --- gst-libs/gst/vaapi/gstvaapiutils_core.c | 104 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_core.h | 32 ++++++++ 2 files changed, 136 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.c b/gst-libs/gst/vaapi/gstvaapiutils_core.c index 92d886dac3..f17f5903d3 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_core.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.c @@ -180,3 +180,107 @@ error: return NULL; } } + +/** + * gst_vaapi_config_surface_attribures_get: + * @display: a #GstVaapiDisplay + * @config: a #VAConfigID + * + * Retrieves the possible surface attributes for the supplied config. + * + * Returns: (transfer full): returns a #GstVaapiConfigSurfaceAttributes + **/ +GstVaapiConfigSurfaceAttributes * +gst_vaapi_config_surface_attributes_get (GstVaapiDisplay * display, + VAConfigID config) +{ + VASurfaceAttrib *surface_attribs; + guint i, num_pixel_formats = 0, num_surface_attribs = 0; + GstVaapiConfigSurfaceAttributes *attribs = NULL; + + surface_attribs = + get_surface_attributes (display, config, &num_surface_attribs); + if (!surface_attribs) + return NULL; + + attribs = g_slice_new0 (GstVaapiConfigSurfaceAttributes); + if (!attribs) + goto error; + + for (i = 0; i < num_surface_attribs; i++) { + const VASurfaceAttrib *const attrib = &surface_attribs[i]; + + switch (attrib->type) { + case VASurfaceAttribPixelFormat: + if ((attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) { + GstVideoFormat fmt; + + fmt = gst_vaapi_video_format_from_va_fourcc (attrib->value.value.i); + if (fmt != GST_VIDEO_FORMAT_UNKNOWN) + num_pixel_formats++; + } + break; + case VASurfaceAttribMinWidth: + attribs->min_width = attrib->value.value.i; + break; + case VASurfaceAttribMinHeight: + attribs->min_height = attrib->value.value.i; + break; + case VASurfaceAttribMaxWidth: + attribs->max_width = attrib->value.value.i; + break; + case VASurfaceAttribMaxHeight: + attribs->max_height = attrib->value.value.i; + break; + case VASurfaceAttribMemoryType: + attribs->mem_types = attrib->value.value.i; + break; + default: + break; + } + } + + if (num_pixel_formats == 0) { + attribs->formats = NULL; + } else { + attribs->formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), + num_pixel_formats); + + for (i = 0; i < num_surface_attribs; i++) { + const VASurfaceAttrib *const attrib = &surface_attribs[i]; + GstVideoFormat fmt; + + if (attrib->type != VASurfaceAttribPixelFormat) + continue; + if (!(attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) + continue; + + fmt = gst_vaapi_video_format_from_va_fourcc (attrib->value.value.i); + if (fmt == GST_VIDEO_FORMAT_UNKNOWN) + continue; + g_array_append_val (attribs->formats, fmt); + } + } + + return attribs; + + /* ERRORS */ +error: + { + g_free (surface_attribs); + gst_vaapi_config_surface_attributes_free (attribs); + return NULL; + } +} + +void +gst_vaapi_config_surface_attributes_free (GstVaapiConfigSurfaceAttributes * + attribs) +{ + if (!attribs) + return; + + if (attribs->formats) + g_array_unref (attribs->formats); + g_slice_free (GstVaapiConfigSurfaceAttributes, attribs); +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.h b/gst-libs/gst/vaapi/gstvaapiutils_core.h index 4fdaad5eb0..ae1f1f55f9 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_core.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.h @@ -29,6 +29,30 @@ G_BEGIN_DECLS +typedef struct _GstVaapiConfigSurfaceAttributes GstVaapiConfigSurfaceAttributes; + + +/** + * GstVaapiConfigSurfaceAttributes: + * @min_width: Minimal width in pixels. + * @min_height: Minimal height in pixels. + * @max_width: Maximal width in pixels. + * @max_height: Maximal height in pixels. + * @mem_types: Surface memory type expressed in bit fields. + * @formats: Array of avialable GstVideoFormats of a surface in a VAConfig. + * + * Represents the possible surface attributes for the supplied config. + **/ +struct _GstVaapiConfigSurfaceAttributes +{ + gint min_width; + gint min_height; + gint max_width; + gint max_height; + guint mem_types; + GArray *formats; +}; + /* Gets attribute value for the supplied profile/entrypoint pair (MT-safe) */ G_GNUC_INTERNAL gboolean @@ -40,6 +64,14 @@ G_GNUC_INTERNAL GArray * gst_vaapi_get_surface_formats (GstVaapiDisplay * display, VAConfigID config); +G_GNUC_INTERNAL +GstVaapiConfigSurfaceAttributes * +gst_vaapi_config_surface_attributes_get (GstVaapiDisplay * display, VAConfigID config); + +G_GNUC_INTERNAL +void +gst_vaapi_config_surface_attributes_free (GstVaapiConfigSurfaceAttributes * attribs); + G_END_DECLS #endif /* GST_VAAPI_UTILS_CORE_H */ From 6376e7e2bd357685d0caed35e66284636c4227ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 1 Aug 2019 19:46:17 +0200 Subject: [PATCH 3311/3781] libs: context, filter: use new surface attributes API --- gst-libs/gst/vaapi/gstvaapicontext.c | 32 ++++++++++++++------------ gst-libs/gst/vaapi/gstvaapicontext.h | 3 ++- gst-libs/gst/vaapi/gstvaapifilter.c | 34 ++++++++++++++++------------ 3 files changed, 38 insertions(+), 31 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 006acb4bf7..4fdbbbed13 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -39,7 +39,6 @@ #include "gstvaapisurfaceproxy.h" #include "gstvaapivideopool_priv.h" #include "gstvaapiutils.h" -#include "gstvaapiutils_core.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -51,15 +50,15 @@ #define SCRATCH_SURFACES_COUNT (4) static gboolean -ensure_formats (GstVaapiContext * context) +ensure_attributes (GstVaapiContext * context) { - if (G_LIKELY (context->formats)) + if (G_LIKELY (context->attribs)) return TRUE; - context->formats = - gst_vaapi_get_surface_formats (GST_VAAPI_OBJECT_DISPLAY (context), - context->va_config); - return (context->formats != NULL); + context->attribs = + gst_vaapi_config_surface_attributes_get (GST_VAAPI_OBJECT_DISPLAY + (context), context->va_config); + return (context->attribs != NULL); } static void @@ -119,9 +118,9 @@ context_destroy (GstVaapiContext * context) context->va_config = VA_INVALID_ID; } - if (context->formats) { - g_array_unref (context->formats); - context->formats = NULL; + if (context->attribs) { + gst_vaapi_config_surface_attributes_free (context->attribs); + context->attribs = NULL; } } @@ -133,13 +132,13 @@ context_ensure_surfaces (GstVaapiContext * context) GstVaapiSurface *surface; guint i; - if (!ensure_formats (context)) + if (!ensure_attributes (context)) return FALSE; for (i = context->surfaces->len; i < num_surfaces; i++) { surface = gst_vaapi_surface_new_from_formats (GST_VAAPI_OBJECT_DISPLAY (context), - cip->chroma_type, cip->width, cip->height, context->formats); + cip->chroma_type, cip->width, cip->height, context->attribs->formats); if (!surface) return FALSE; gst_vaapi_surface_set_parent_context (surface, context); @@ -407,7 +406,7 @@ gst_vaapi_context_init (GstVaapiContext * context, context->reset_on_resize = TRUE; gst_vaapi_context_overlay_init (context); - context->formats = NULL; + context->attribs = NULL; } static void @@ -633,7 +632,10 @@ gst_vaapi_context_get_surface_formats (GstVaapiContext * context) { g_return_val_if_fail (context, NULL); - if (!ensure_formats (context)) + if (!ensure_attributes (context)) return NULL; - return g_array_ref (context->formats); + + if (context->attribs->formats) + return g_array_ref (context->attribs->formats); + return NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index a80dbd9f10..002275a526 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -30,6 +30,7 @@ #include "gstvaapiprofile.h" #include "gstvaapidisplay.h" #include "gstvaapisurface.h" +#include "gstvaapiutils_core.h" #include "gstvaapivideopool.h" G_BEGIN_DECLS @@ -115,7 +116,7 @@ struct _GstVaapiContext GPtrArray *overlays[2]; guint overlay_id; gboolean reset_on_resize; - GArray *formats; + GstVaapiConfigSurfaceAttributes *attribs; }; /** diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 33e37b0c3e..82a7cd6838 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -62,7 +62,7 @@ struct _GstVaapiFilter GstVideoFormat format; GstVaapiScaleMethod scale_method; GstVideoOrientationMethod video_direction; - GArray *formats; + GstVaapiConfigSurfaceAttributes *attribs; GArray *forward_references; GArray *backward_references; GstVaapiRectangle crop_rect; @@ -1086,18 +1086,18 @@ deint_refs_clear_all (GstVaapiFilter * filter) } /* ------------------------------------------------------------------------- */ -/* --- Surface Formats --- */ +/* --- Surface Attribs --- */ /* ------------------------------------------------------------------------- */ static gboolean -ensure_formats (GstVaapiFilter * filter) +ensure_attributes (GstVaapiFilter * filter) { - if (G_LIKELY (filter->formats)) + if (G_LIKELY (filter->attribs)) return TRUE; - filter->formats = gst_vaapi_get_surface_formats (filter->display, + filter->attribs = gst_vaapi_config_surface_attributes_get (filter->display, filter->va_config); - return (filter->formats != NULL); + return (filter->attribs != NULL); } static inline gboolean @@ -1111,12 +1111,14 @@ static gboolean find_format (GstVaapiFilter * filter, GstVideoFormat format) { guint i; + GArray *formats; - if (is_special_format (format) || !filter->formats) + formats = filter->attribs->formats; + if (is_special_format (format) || !formats) return FALSE; - for (i = 0; i < filter->formats->len; i++) { - if (g_array_index (filter->formats, GstVideoFormat, i) == format) + for (i = 0; i < formats->len; i++) { + if (g_array_index (formats, GstVideoFormat, i) == format) return TRUE; } return FALSE; @@ -1199,9 +1201,9 @@ gst_vaapi_filter_finalize (GObject * object) filter->backward_references = NULL; } - if (filter->formats) { - g_array_unref (filter->formats); - filter->formats = NULL; + if (filter->attribs) { + gst_vaapi_config_surface_attributes_free (filter->attribs); + filter->attribs = NULL; } G_OBJECT_CLASS (gst_vaapi_filter_parent_class)->finalize (object); @@ -1657,9 +1659,11 @@ gst_vaapi_filter_get_formats (GstVaapiFilter * filter) { g_return_val_if_fail (filter != NULL, NULL); - if (!ensure_formats (filter)) + if (!ensure_attributes (filter)) return NULL; - return g_array_ref (filter->formats); + if (filter->attribs->formats) + return g_array_ref (filter->attribs->formats); + return NULL; } /** @@ -1685,7 +1689,7 @@ gst_vaapi_filter_set_format (GstVaapiFilter * filter, GstVideoFormat format) { g_return_val_if_fail (filter != NULL, FALSE); - if (!ensure_formats (filter)) + if (!ensure_attributes (filter)) return FALSE; if (!is_special_format (format) && !find_format (filter, format)) From 4851959da85e3e91ea7b4ff5f41af15bf8082753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 1 Aug 2019 19:48:21 +0200 Subject: [PATCH 3312/3781] libs: utils: remove unused function gst_vaapi_get_surface_formats() --- gst-libs/gst/vaapi/gstvaapiutils_core.c | 60 ------------------------- gst-libs/gst/vaapi/gstvaapiutils_core.h | 5 --- 2 files changed, 65 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.c b/gst-libs/gst/vaapi/gstvaapiutils_core.c index f17f5903d3..d7aa26003c 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_core.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.c @@ -121,66 +121,6 @@ error: } } -/** - * gst_vaapi_get_surface_formats: - * @display: a #GstVaapiDisplay - * @config: a #VAConfigID - * - * Gets surface formats for the supplied config. - * - * This function will query for all the supported formats for the - * supplied VA @config. - * - * Return value: (transfer full): a #GArray of #GstVideoFormats or %NULL - */ -GArray * -gst_vaapi_get_surface_formats (GstVaapiDisplay * display, VAConfigID config) -{ - VASurfaceAttrib *surface_attribs; - guint i, num_surface_attribs = 0; - GArray *formats; - - surface_attribs = - get_surface_attributes (display, config, &num_surface_attribs); - if (!surface_attribs) - return NULL; - - formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), - num_surface_attribs); - if (!formats) - goto error; - - for (i = 0; i < num_surface_attribs; i++) { - const VASurfaceAttrib *const attrib = &surface_attribs[i]; - GstVideoFormat fmt; - - if (attrib->type != VASurfaceAttribPixelFormat) - continue; - if (!(attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) - continue; - - fmt = gst_vaapi_video_format_from_va_fourcc (attrib->value.value.i); - if (fmt == GST_VIDEO_FORMAT_UNKNOWN) - continue; - g_array_append_val (formats, fmt); - } - - if (formats->len == 0) { - g_array_unref (formats); - formats = NULL; - } - - g_free (surface_attribs); - return formats; - - /* ERRORS */ -error: - { - g_free (surface_attribs); - return NULL; - } -} - /** * gst_vaapi_config_surface_attribures_get: * @display: a #GstVaapiDisplay diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.h b/gst-libs/gst/vaapi/gstvaapiutils_core.h index ae1f1f55f9..d900567bbb 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_core.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.h @@ -59,11 +59,6 @@ gboolean gst_vaapi_get_config_attribute (GstVaapiDisplay * display, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttribType type, guint * out_value_ptr); -/* Gets the available GstVideoFormats of a surface in a VAConfig */ -G_GNUC_INTERNAL -GArray * -gst_vaapi_get_surface_formats (GstVaapiDisplay * display, VAConfigID config); - G_GNUC_INTERNAL GstVaapiConfigSurfaceAttributes * gst_vaapi_config_surface_attributes_get (GstVaapiDisplay * display, VAConfigID config); From 738be524b182e7f5ffa0779cf5ba3f378c798e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 2 Aug 2019 12:46:55 +0200 Subject: [PATCH 3313/3781] libs: move memory types conversions to gstvaapiutils And add more supported memory types by current VA. --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 38 -------------- gst-libs/gst/vaapi/gstvaapibufferproxy.h | 8 ++- gst-libs/gst/vaapi/gstvaapiutils.c | 67 +++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiutils.h | 8 +++ 4 files changed, 80 insertions(+), 41 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index 7ec1e294ec..c177cebcd0 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -30,44 +30,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -guint -from_GstVaapiBufferMemoryType (guint type) -{ - guint va_type; - - switch (type) { - case GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF: - va_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; - break; - case GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF: - va_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; - break; - default: - va_type = 0; - break; - } - return va_type; -} - -guint -to_GstVaapiBufferMemoryType (guint va_type) -{ - guint type; - - switch (va_type) { - case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: - type = GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF; - break; - case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: - type = GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF; - break; - default: - type = 0; - break; - } - return type; -} - static gboolean gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) { diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.h b/gst-libs/gst/vaapi/gstvaapibufferproxy.h index 872af2f7c6..bb80abf4d6 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.h @@ -59,14 +59,20 @@ typedef struct _GstVaapiBufferProxy GstVaapiBufferProxy; /** * GstVaapiBufferMemoryType: - * @GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF: DRM PRIME buffer memory type. + * @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 * diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 874b598e9b..55fcee98ff 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -25,9 +25,10 @@ #include "sysdeps.h" #include "gstvaapicompat.h" #include "gstvaapiutils.h" -#include "gstvaapisurface.h" -#include "gstvaapisubpicture.h" +#include "gstvaapibufferproxy.h" #include "gstvaapifilter.h" +#include "gstvaapisubpicture.h" +#include "gstvaapisurface.h" #include #include @@ -907,3 +908,65 @@ from_GstVideoOrientationMethod (guint value, guint * va_mirror, break; } } + +/** + * from_GstVaapiBufferMemoryType: + * @type: a #GstVaapiBufferMemoryType + * + * Returns: the VA's memory type symbol + **/ +guint +from_GstVaapiBufferMemoryType (guint type) +{ + guint va_type; + + switch (type) { +#if VA_CHECK_VERSION(1,1,0) + case GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF2: + va_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2; + break; +#endif + case GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF: + va_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; + break; + case GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF: + va_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; + break; + case GST_VAAPI_BUFFER_MEMORY_TYPE_V4L2: + va_type = VA_SURFACE_ATTRIB_MEM_TYPE_V4L2; + break; + case GST_VAAPI_BUFFER_MEMORY_TYPE_USER_PTR: + va_type = VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR; + default: + va_type = 0; + break; + } + return va_type; +} + +/** + * to_GstVaapiBufferMemoryType: + * @va_type: a VA's memory type symbol + * + * It will return the first "supported" memory type from @va_type bit + * flag. + * + * Returns: a #GstVaapiBufferMemoryType or 0 if unknown. + **/ +guint +to_GstVaapiBufferMemoryType (guint va_type) +{ +#if VA_CHECK_VERSION(1,1,0) + if ((va_type & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)) + return GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF2; +#endif + if ((va_type & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)) + return GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF; + if ((va_type & VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)) + return GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF; + if ((va_type & VA_SURFACE_ATTRIB_MEM_TYPE_V4L2)) + return GST_VAAPI_BUFFER_MEMORY_TYPE_V4L2; + if ((va_type & VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR)) + return GST_VAAPI_BUFFER_MEMORY_TYPE_USER_PTR; + return 0; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index d83a049bb7..cf19fb30ec 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -158,4 +158,12 @@ void from_GstVideoOrientationMethod (guint value, guint * va_mirror, guint * va_rotation); +G_GNUC_INTERNAL +guint +from_GstVaapiBufferMemoryType (guint type); + +G_GNUC_INTERNAL +guint +to_GstVaapiBufferMemoryType (guint va_type); + #endif /* GST_VAAPI_UTILS_H */ From b1e7f974b2dd90054a35a82a7884e56993dcec8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 2 Aug 2019 16:56:17 +0200 Subject: [PATCH 3314/3781] libs: context: add gst_vaapi_context_get_surface_attributes() This function copies the surface attributes from the context's object to the caller. --- gst-libs/gst/vaapi/gstvaapicontext.c | 33 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapicontext.h | 5 +++++ 2 files changed, 38 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 4fdbbbed13..61573d2089 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -639,3 +639,36 @@ gst_vaapi_context_get_surface_formats (GstVaapiContext * context) 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; +} diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 002275a526..2dcaaf4d76 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -161,6 +161,11 @@ 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_END_DECLS #endif /* GST_VAAPI_CONTEXT_H */ From 4b5459b1b14d42e77f2651dfc3e69e81c7266168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 5 Aug 2019 19:45:49 +0200 Subject: [PATCH 3315/3781] libs: decoder: ref the caps as property --- gst-libs/gst/vaapi/gstvaapidecoder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 6c89713678..5c46702153 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -529,7 +529,7 @@ gst_vaapi_decoder_get_property (GObject * object, guint property_id, g_value_set_object (value, decoder->display); break; case PROP_CAPS: - g_value_set_boxed (value, get_caps (decoder)); + g_value_set_boxed (value, gst_caps_ref (get_caps (decoder))); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -694,7 +694,7 @@ gst_vaapi_decoder_set_codec_state_changed_func (GstVaapiDecoder * decoder, * Retrieves the @decoder caps. The decoder owns the returned caps, so * use gst_caps_ref() whenever necessary. * - * Return value: the @decoder caps + * Returns: (transfer none): the @decoder caps */ GstCaps * gst_vaapi_decoder_get_caps (GstVaapiDecoder * decoder) From f7c1ac036d11b1120664ce79cbdc7d311144fd41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 5 Aug 2019 19:47:30 +0200 Subject: [PATCH 3316/3781] libs: profilecaps: move caps config into a new file Implement all the appending of frame size restrictions in caps, for encoders and decoders, in a new source file. --- gst-libs/gst/vaapi/Makefile.am | 2 + gst-libs/gst/vaapi/gstvaapiprofilecaps.c | 118 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiprofilecaps.h | 42 ++++++++ gst-libs/gst/vaapi/meson.build | 2 + gst/vaapi/gstvaapidecode.c | 10 +- 5 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiprofilecaps.c create mode 100644 gst-libs/gst/vaapi/gstvaapiprofilecaps.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 50ca9738ec..4016933f62 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -63,6 +63,7 @@ libgstvaapi_source_c = \ gstvaapiparser_frame.c \ gstvaapipixmap.c \ gstvaapiprofile.c \ + gstvaapiprofilecaps.c \ gstvaapisubpicture.c \ gstvaapisurface.c \ gstvaapisurface_drm.c \ @@ -97,6 +98,7 @@ libgstvaapi_source_h = \ gstvaapiobject.h \ gstvaapipixmap.h \ gstvaapiprofile.h \ + gstvaapiprofilecaps.h \ gstvaapisubpicture.h \ gstvaapisurface.h \ gstvaapisurface_drm.h \ diff --git a/gst-libs/gst/vaapi/gstvaapiprofilecaps.c b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c new file mode 100644 index 0000000000..b786b77b7a --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c @@ -0,0 +1,118 @@ +/* + * gstvaapiprofilecaps.h - VA config attributes as gstreamer capabilities + * + * Copyright (C) 2019 Igalia, S.L. + * Author: Víctor Jáquez + * + * 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:gstvaapiprofilecaps + * @short_description: VA config attributes as gstreamer capabilities + */ + +#include "sysdeps.h" +#include "gstvaapicompat.h" +#include "gstvaapicontext.h" +#include "gstvaapiprofilecaps.h" +#include "gstvaapiutils.h" + +static gboolean +init_context_info (GstVaapiDisplay * display, GstVaapiContextInfo * cip) +{ + guint value = 0; + + /* XXX: Only try a context from he first RTFormat in config. */ + if (!gst_vaapi_get_config_attribute (display, + gst_vaapi_profile_get_va_profile (cip->profile), + gst_vaapi_entrypoint_get_va_entrypoint (cip->entrypoint), + VAConfigAttribRTFormat, &value)) { + return FALSE; + } + + cip->chroma_type = to_GstVaapiChromaType (value); + return cip->chroma_type != 0; +} + +static GstVaapiContext * +create_context (GstVaapiDisplay * display, GstVaapiContextInfo * cip) +{ + if (!init_context_info (display, cip)) + return NULL; + return gst_vaapi_context_new (display, cip); +} + +static gboolean +append_caps (GstVaapiContext * context, GstStructure * structure) +{ + GstVaapiConfigSurfaceAttributes attribs = { 0, }; + + if (!gst_vaapi_context_get_surface_attributes (context, &attribs)) + return FALSE; + + if (attribs.min_width >= attribs.max_width || + attribs.min_height >= attribs.max_height) + return FALSE; + + gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, attribs.min_width, + attribs.max_width, "height", GST_TYPE_INT_RANGE, attribs.min_height, + attribs.max_height, NULL); + + return TRUE; +} + +/** + * gst_vaapi_decoder_add_profile_caps: + * @display: a #GstVaapiDisplay + * @profile: a #GstVaapiProfile + * @structure: a #GstStructure + * + * Extracts the config's surface attributes, from @profile, in an + * decoder context, and transforms it into a caps formats and appended + * into @structure. + * + * Returns: %TRUE if the capabilities could be extracted and appended + * into @structure; otherwise %FALSE + **/ +gboolean +gst_vaapi_profile_caps_append_decoder (GstVaapiDisplay * display, + GstVaapiProfile profile, GstStructure * structure) +{ + GstVaapiContext *context; + GstVaapiContextInfo cip = { + GST_VAAPI_CONTEXT_USAGE_DECODE, profile, GST_VAAPI_ENTRYPOINT_VLD, 0, + }; + gboolean ret; + + g_return_val_if_fail (display != NULL, FALSE); + g_return_val_if_fail (structure != NULL, FALSE); + + context = create_context (display, &cip); + if (!context) + return FALSE; + + ret = append_caps (context, structure); + gst_vaapi_object_unref (context); + return ret; +} + +gboolean +gst_vaapi_profile_caps_append_encoder (GstVaapiDisplay * display, + GstVaapiProfile profile, GstStructure * structure) +{ + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapiprofilecaps.h b/gst-libs/gst/vaapi/gstvaapiprofilecaps.h new file mode 100644 index 0000000000..e7c7d58fd3 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiprofilecaps.h @@ -0,0 +1,42 @@ +/* + * gstvaapiprofilecaps.h - VA config attributes as gstreamer capabilities + * + * Copyright (C) 2019 Igalia, S.L. + * Author: Víctor Jáquez + * + * 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_PROFILE_CAPS_H +#define GST_VAAPI_PROFILE_CAPS_H + +#include +#include +#include + +G_BEGIN_DECLS + +gboolean +gst_vaapi_profile_caps_append_decoder (GstVaapiDisplay * display, + GstVaapiProfile profile, GstStructure * structure); + +gboolean +gst_vaapi_profile_caps_append_encoder (GstVaapiDisplay * display, + GstVaapiProfile profile, GstStructure * structure); + +G_END_DECLS + +#endif /* GST_VAAPI_PROFILE_CAPS_H */ diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index c5c40f70e1..eb67b75801 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -24,6 +24,7 @@ gstlibvaapi_sources = [ 'gstvaapiparser_frame.c', 'gstvaapipixmap.c', 'gstvaapiprofile.c', + 'gstvaapiprofilecaps.c', 'gstvaapisubpicture.c', 'gstvaapisurface.c', 'gstvaapisurface_drm.c', @@ -61,6 +62,7 @@ gstlibvaapi_headers = [ 'gstvaapiobject.h', 'gstvaapipixmap.h', 'gstvaapiprofile.h', + 'gstvaapiprofilecaps.h', 'gstvaapisubpicture.h', 'gstvaapisurface.h', 'gstvaapisurface_drm.h', diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 12878d40d0..6f58906d92 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -24,6 +24,7 @@ #include "gstcompat.h" #include +#include #include "gstvaapidecode.h" #include "gstvaapidecode_props.h" @@ -1214,15 +1215,14 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) { GstCaps *caps, *allowed_sinkpad_caps; GArray *profiles; + GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode); guint i; gboolean base_only = FALSE; gboolean have_high = FALSE; gboolean have_mvc = FALSE; gboolean have_svc = FALSE; - profiles = - gst_vaapi_display_get_decode_profiles (GST_VAAPI_PLUGIN_BASE_DISPLAY - (decode)); + profiles = gst_vaapi_display_get_decode_profiles (display); if (!profiles) goto error_no_profiles; @@ -1255,6 +1255,8 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) gst_structure_set (structure, "profile", G_TYPE_STRING, profile_name, NULL); + gst_vaapi_profile_caps_append_decoder (display, profile, structure); + allowed_sinkpad_caps = gst_caps_merge (allowed_sinkpad_caps, caps); have_mvc |= is_mvc_profile (profile); have_svc |= is_svc_profile (profile); @@ -1297,6 +1299,8 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) } } decode->allowed_sinkpad_caps = gst_caps_simplify (allowed_sinkpad_caps); + GST_DEBUG_OBJECT (decode, "allowed sink caps %" GST_PTR_FORMAT, + decode->allowed_sinkpad_caps); g_array_unref (profiles); return TRUE; From 1c73dc969c3cfd12db724f908373d62fff242746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 16 Aug 2019 18:07:43 +0200 Subject: [PATCH 3317/3781] libs: profile: add gst_vaapi_profile_get_va_name() gst_vaapi_profile_get_name() returns a proper name for GstCaps. Nonetheless, there are many profiles which don't have a name representation for that realm. gst_vaapi_profile_get_va_name() returns the name of the profile according to its VAProfile name. This new funtion is used in the encoder error message. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 2 +- gst-libs/gst/vaapi/gstvaapiprofile.c | 20 +++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiprofile.h | 3 +++ tests/test-display.c | 2 +- 9 files changed, 29 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 1f81e402a8..06c8478c12 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1145,7 +1145,7 @@ ensure_hw_profile (GstVaapiEncoderH264 * encoder) error_unsupported_profile: { GST_ERROR ("unsupported HW profile %s", - gst_vaapi_profile_get_name (encoder->profile)); + gst_vaapi_profile_get_va_name (encoder->profile)); return FALSE; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index bcfa08abb3..ad4681090e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -954,7 +954,7 @@ ensure_hw_profile (GstVaapiEncoderH265 * encoder) error_unsupported_profile: { GST_ERROR ("unsupported HW profile %s", - gst_vaapi_profile_get_name (encoder->profile)); + gst_vaapi_profile_get_va_name (encoder->profile)); return FALSE; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 8491fbca9f..a3157d4ef1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -164,7 +164,7 @@ ensure_hw_profile (GstVaapiEncoderJpeg * encoder) error_unsupported_profile: { GST_ERROR ("unsupported HW profile %s", - gst_vaapi_profile_get_name (encoder->profile)); + gst_vaapi_profile_get_va_name (encoder->profile)); return FALSE; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 79dc7f1c11..92a021fa6b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -101,7 +101,7 @@ ensure_hw_profile (GstVaapiEncoderMpeg2 * encoder) error_unsupported_profile: { GST_ERROR ("unsupported HW profile %s", - gst_vaapi_profile_get_name (encoder->profile)); + gst_vaapi_profile_get_va_name (encoder->profile)); return FALSE; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 0b8b379048..3c14cdee8d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -109,7 +109,7 @@ ensure_hw_profile (GstVaapiEncoderVP8 * encoder) error_unsupported_profile: { GST_ERROR ("unsupported HW profile %s", - gst_vaapi_profile_get_name (encoder->profile)); + gst_vaapi_profile_get_va_name (encoder->profile)); return FALSE; } } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 38ad4c1402..6d37334c42 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -196,7 +196,7 @@ ensure_hw_profile (GstVaapiEncoderVP9 * encoder) error_unsupported_profile: { GST_ERROR ("unsupported HW profile %s", - gst_vaapi_profile_get_name (encoder->profile)); + gst_vaapi_profile_get_va_name (encoder->profile)); return FALSE; } } diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 1e036c639f..234a98b682 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -31,6 +31,7 @@ #include #include "gstvaapicompat.h" #include "gstvaapiprofile.h" +#include "gstvaapiutils.h" #include "gstvaapiworkarounds.h" typedef struct _GstVaapiCodecMap GstVaapiCodecMap; @@ -242,9 +243,26 @@ gst_vaapi_profile_get_name (GstVaapiProfile profile) } /** - * gst_vaapi_profile_get_media_type_name: + * gst_vaapi_profile_get_va_name: * @profile: a #GstVaapiProfile * + * Returns a string representation for the supplied @profile as VAProfile. + * + * Return value: the statically allocated string representation of + * @profile as VAProfile + */ +const gchar * +gst_vaapi_profile_get_va_name (GstVaapiProfile profile) +{ + const GstVaapiProfileMap *const m = get_profiles_map (profile); + + return m ? string_of_VAProfile (m->va_profile) : NULL; +} + +/** + * gst_vaapi_profile_get_media_type_name: + * @profile: a #GstVaapiProfileo + * * Returns a string representation for the media type of the supplied * @profile. * diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index f5d566c614..8f0039c56b 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -221,6 +221,9 @@ gst_vaapi_profile_from_caps(const GstCaps *caps); const gchar * gst_vaapi_profile_get_name(GstVaapiProfile profile); +const gchar * +gst_vaapi_profile_get_va_name(GstVaapiProfile profile); + const gchar * gst_vaapi_profile_get_media_type_name(GstVaapiProfile profile); diff --git a/tests/test-display.c b/tests/test-display.c index e189ab3272..068c155a24 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -84,7 +84,7 @@ print_profiles (GArray * profiles, const gchar * name) if (!codec_name) continue; - profile_name = gst_vaapi_profile_get_name (profile); + profile_name = gst_vaapi_profile_get_va_name (profile); if (!profile_name) continue; From ab4ba47bbf6ae3370d0e739c1f75a30c4dcd581a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 16 Aug 2019 19:17:48 +0200 Subject: [PATCH 3318/3781] libs: utils: treat va_rt_format as bitwise flag The return value of vaGetConfigAttributes() of VAConfigAttribRTFormat is a bitwise flag with *all* the supported chroma types. Previously it was assumed that the return value was a single value, thus when returning the GST_VAAPI_CHROMA_TYPE_XXX the code was a simple case. But it is wrong. This patch changes the case block with a sequence of ifs testing the bitwise. For now we assume a "priority" list in the testing sequence. --- gst-libs/gst/vaapi/gstvaapiutils.c | 84 +++++++++++------------------- 1 file changed, 31 insertions(+), 53 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 55fcee98ff..461baf3227 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -383,61 +383,39 @@ string_of_VARateControl (guint rate_control) guint to_GstVaapiChromaType (guint va_rt_format) { - guint chroma_type; - - switch (va_rt_format) { - case VA_RT_FORMAT_YUV420: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; - break; - case VA_RT_FORMAT_YUV422: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; - break; - case VA_RT_FORMAT_YUV444: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; - break; - case VA_RT_FORMAT_YUV411: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV411; - break; - case VA_RT_FORMAT_YUV400: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400; - break; - case VA_RT_FORMAT_RGB32: - chroma_type = GST_VAAPI_CHROMA_TYPE_RGB32; - break; - case VA_RT_FORMAT_RGB16: - chroma_type = GST_VAAPI_CHROMA_TYPE_RGB16; - break; - case VA_RT_FORMAT_RGBP: - chroma_type = GST_VAAPI_CHROMA_TYPE_RGBP; - break; - case VA_RT_FORMAT_YUV420_10BPP: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; - break; + if (va_rt_format & VA_RT_FORMAT_YUV420) + return GST_VAAPI_CHROMA_TYPE_YUV420; + if (va_rt_format & VA_RT_FORMAT_YUV422) + return GST_VAAPI_CHROMA_TYPE_YUV422; + if (va_rt_format & VA_RT_FORMAT_YUV444) + return GST_VAAPI_CHROMA_TYPE_YUV444; + if (va_rt_format & VA_RT_FORMAT_YUV411) + return GST_VAAPI_CHROMA_TYPE_YUV411; + if (va_rt_format & VA_RT_FORMAT_YUV400) + return GST_VAAPI_CHROMA_TYPE_YUV400; + if (va_rt_format & VA_RT_FORMAT_RGB32) + return GST_VAAPI_CHROMA_TYPE_RGB32; + if (va_rt_format & VA_RT_FORMAT_RGB16) + return GST_VAAPI_CHROMA_TYPE_RGB16; + if (va_rt_format & VA_RT_FORMAT_RGBP) + return GST_VAAPI_CHROMA_TYPE_RGBP; + if (va_rt_format & VA_RT_FORMAT_YUV420_10BPP) + return GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; #if VA_CHECK_VERSION(1,2,0) - case VA_RT_FORMAT_YUV422_10: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_10BPP; - break; - case VA_RT_FORMAT_YUV444_10: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_10BPP; - break; - case VA_RT_FORMAT_YUV420_12: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_12BPP; - break; - case VA_RT_FORMAT_YUV422_12: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_12BPP; - break; - case VA_RT_FORMAT_YUV444_12: - chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_12BPP; - break; - case VA_RT_FORMAT_RGB32_10: - chroma_type = GST_VAAPI_CHROMA_TYPE_RGB32_10BPP; - break; + if (va_rt_format & VA_RT_FORMAT_YUV422_10) + return GST_VAAPI_CHROMA_TYPE_YUV422_10BPP; + if (va_rt_format & VA_RT_FORMAT_YUV444_10) + return GST_VAAPI_CHROMA_TYPE_YUV444_10BPP; + if (va_rt_format & VA_RT_FORMAT_YUV420_12) + return GST_VAAPI_CHROMA_TYPE_YUV420_12BPP; + if (va_rt_format & VA_RT_FORMAT_YUV422_12) + return GST_VAAPI_CHROMA_TYPE_YUV422_12BPP; + if (va_rt_format & VA_RT_FORMAT_YUV444_12) + return GST_VAAPI_CHROMA_TYPE_YUV444_12BPP; + if (va_rt_format & VA_RT_FORMAT_RGB32_10) + return GST_VAAPI_CHROMA_TYPE_RGB32_10BPP; #endif - default: - chroma_type = 0; - break; - } - return chroma_type; + return 0; } /** From bd3d347fd70fb1587ca06086bc572182e8ff3699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 16 Aug 2019 19:26:36 +0200 Subject: [PATCH 3319/3781] libs: profilecaps: defines gst_vaapi_profile_caps_append_encoder() Previously it was just a boilerplate. Now it is real implementation. --- gst-libs/gst/vaapi/gstvaapiprofilecaps.c | 36 ++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiprofilecaps.h | 3 +- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofilecaps.c b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c index b786b77b7a..83dc712b26 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofilecaps.c +++ b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c @@ -81,7 +81,7 @@ append_caps (GstVaapiContext * context, GstStructure * structure) * @profile: a #GstVaapiProfile * @structure: a #GstStructure * - * Extracts the config's surface attributes, from @profile, in an + * Extracts the config's surface attributes, from @profile, in a * decoder context, and transforms it into a caps formats and appended * into @structure. * @@ -110,9 +110,39 @@ gst_vaapi_profile_caps_append_decoder (GstVaapiDisplay * display, return ret; } +/** + * gst_vaapi_profile_caps_append_encoder: + * @display: a #GstVaapiDisplay + * @profile: a #GstVaapiProfile + * @entrypoint: a #GstVaapiEntryPoint + * @structure: a #GstStructure + * + * Extracts the config's surface attributes, from @profile and + * @entrypoint, in an encoder context, and transforms it into a caps + * formats and appended into @structure. + * + * Returns: %TRUE if the capabilities could be extracted and appended + * into @structure; otherwise %FALSE + **/ gboolean gst_vaapi_profile_caps_append_encoder (GstVaapiDisplay * display, - GstVaapiProfile profile, GstStructure * structure) + GstVaapiProfile profile, GstVaapiEntrypoint entrypoint, + GstStructure * structure) { - return TRUE; + GstVaapiContext *context; + GstVaapiContextInfo cip = { + GST_VAAPI_CONTEXT_USAGE_ENCODE, profile, entrypoint, 0, + }; + gboolean ret; + + g_return_val_if_fail (display != NULL, FALSE); + g_return_val_if_fail (structure != NULL, FALSE); + + context = create_context (display, &cip); + if (!context) + return FALSE; + + ret = append_caps (context, structure); + gst_vaapi_object_unref (context); + return ret; } diff --git a/gst-libs/gst/vaapi/gstvaapiprofilecaps.h b/gst-libs/gst/vaapi/gstvaapiprofilecaps.h index e7c7d58fd3..4333bed9dc 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofilecaps.h +++ b/gst-libs/gst/vaapi/gstvaapiprofilecaps.h @@ -35,7 +35,8 @@ gst_vaapi_profile_caps_append_decoder (GstVaapiDisplay * display, gboolean gst_vaapi_profile_caps_append_encoder (GstVaapiDisplay * display, - GstVaapiProfile profile, GstStructure * structure); + GstVaapiProfile profile, GstVaapiEntrypoint entrypoint, + GstStructure * structure); G_END_DECLS From 3ba3966fc3af5cbf710bfc49514e22f0d3089262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 16 Aug 2019 19:28:27 +0200 Subject: [PATCH 3320/3781] vaapiencode: enhance how the profile is defined This code doesn't define the profile used by the internal encoder, but it used to "predict" which is going to be used and to get the caps restrictions. Before the profile was predicted by checking the donwstream caps, but sometimes they are not defined, setting an unknown profile. In order to enhances this situation, the encoder asks to internal encoder if it has one. If so, it is used. To ask the internal encoder's profile a new accessor function was added: gst_vaapi_encoder_get_profile() --- gst-libs/gst/vaapi/gstvaapiencoder.c | 8 ++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 4 +++ gst/vaapi/gstvaapiencode.c | 43 ++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 51bcd069a9..937eb10a1c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1869,6 +1869,14 @@ gst_vaapi_encoder_ensure_max_num_ref_frames (GstVaapiEncoder * encoder, return TRUE; } +GstVaapiProfile +gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder) +{ + g_return_val_if_fail (encoder, GST_VAAPI_PROFILE_UNKNOWN); + + return encoder->profile; +} + /** Returns a GType for the #GstVaapiEncoderTune set */ GType gst_vaapi_encoder_tune_get_type (void) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index b22fde9e8c..a813dd2168 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -216,6 +216,10 @@ gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); GArray * gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile); + +GstVaapiProfile +gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder); + G_END_DECLS #endif /* GST_VAAPI_ENCODER_H */ diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 7f26016e2f..5bcff26354 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -365,35 +365,54 @@ gst_vaapiencode_buffer_loop (GstVaapiEncode * encode) gst_pad_pause_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); } +static GstVaapiProfile +get_profile (GstVaapiEncode * encode) +{ + GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode); + + if (klass->get_profile) { + GstVaapiProfile profile = GST_VAAPI_PROFILE_UNKNOWN; + GstCaps *allowed = + gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); + + if (allowed) { + if (!gst_caps_is_empty (allowed) && !gst_caps_is_any (allowed)) + profile = klass->get_profile (allowed); + gst_caps_unref (allowed); + } + + if (profile != GST_VAAPI_PROFILE_UNKNOWN) + return profile; + } + + if (encode->encoder) + return gst_vaapi_encoder_get_profile (encode->encoder); + + return GST_VAAPI_PROFILE_UNKNOWN; +} + static gboolean ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) { - GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode); GstCaps *out_caps, *raw_caps = NULL; GArray *formats = NULL; gboolean ret = FALSE; - GstVaapiProfile profile = GST_VAAPI_PROFILE_UNKNOWN; + GstVaapiProfile profile; if (encode->allowed_sinkpad_caps) return TRUE; if (!encode->encoder) return TRUE; + profile = get_profile (encode); + if (profile == GST_VAAPI_PROFILE_UNKNOWN) + return TRUE; + out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS ";" GST_VAAPI_MAKE_DMABUF_CAPS); if (!out_caps) goto failed_create_va_caps; - if (klass->get_profile) { - GstCaps *allowed = - gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); - if (allowed) { - if (!gst_caps_is_empty (allowed) && !gst_caps_is_any (allowed)) - profile = klass->get_profile (allowed); - gst_caps_unref (allowed); - } - } - formats = gst_vaapi_encoder_get_surface_formats (encode->encoder, profile); if (!formats) goto failed_get_formats; From 6f61252f9d28080469eb19252eca8e3d1fc89283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 16 Aug 2019 19:35:58 +0200 Subject: [PATCH 3321/3781] vaapiencode: set frame size restrictions in caps Fixes: #12 --- gst/vaapi/gstvaapiencode.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 5bcff26354..6ca10e3398 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -24,6 +24,7 @@ #include "gstcompat.h" #include #include +#include #include "gstvaapiencode.h" #include "gstvaapipluginutil.h" #include "gstvaapivideometa.h" @@ -391,6 +392,19 @@ get_profile (GstVaapiEncode * encode) return GST_VAAPI_PROFILE_UNKNOWN; } +static GstVaapiEntrypoint +get_entrypoint (GstVaapiEncode * encode, GstVaapiProfile profile) +{ + GstVaapiEncoderTune tune = GST_VAAPI_ENCODER_TUNE_NONE; + + g_object_get (encode, "tune", &tune, NULL); + if (tune == GST_VAAPI_ENCODER_TUNE_LOW_POWER) + return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; + if (profile == GST_VAAPI_PROFILE_JPEG_BASELINE) + return GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; + return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; +} + static gboolean ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) { @@ -398,6 +412,8 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) GArray *formats = NULL; gboolean ret = FALSE; GstVaapiProfile profile; + guint i, size; + GstStructure *structure; if (encode->allowed_sinkpad_caps) return TRUE; @@ -423,6 +439,16 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) out_caps = gst_caps_make_writable (out_caps); gst_caps_append (out_caps, gst_caps_copy (raw_caps)); + + size = gst_caps_get_size (out_caps); + for (i = 0; i < size; i++) { + structure = gst_caps_get_structure (out_caps, i); + if (!structure) + continue; + gst_vaapi_profile_caps_append_encoder (GST_VAAPI_PLUGIN_BASE_DISPLAY + (encode), profile, get_entrypoint (encode, profile), structure); + } + gst_caps_replace (&encode->allowed_sinkpad_caps, out_caps); GST_INFO_OBJECT (encode, "Allowed sink caps %" GST_PTR_FORMAT, encode->allowed_sinkpad_caps); From 13e369aad64260c4f08972db1c6bb3256f2a4352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 18 Aug 2019 13:09:58 +0200 Subject: [PATCH 3322/3781] libs: profilecaps: refactor common code --- gst-libs/gst/vaapi/gstvaapiprofilecaps.c | 36 ++++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofilecaps.c b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c index 83dc712b26..fcd6981fb5 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofilecaps.c +++ b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c @@ -75,6 +75,22 @@ append_caps (GstVaapiContext * context, GstStructure * structure) return TRUE; } +static gboolean +append_caps_with_context_info (GstVaapiDisplay * display, + GstVaapiContextInfo * cip, GstStructure * structure) +{ + GstVaapiContext *context; + gboolean ret; + + context = create_context (display, cip); + if (!context) + return FALSE; + + ret = append_caps (context, structure); + gst_vaapi_object_unref (context); + return ret; +} + /** * gst_vaapi_decoder_add_profile_caps: * @display: a #GstVaapiDisplay @@ -92,22 +108,14 @@ gboolean gst_vaapi_profile_caps_append_decoder (GstVaapiDisplay * display, GstVaapiProfile profile, GstStructure * structure) { - GstVaapiContext *context; GstVaapiContextInfo cip = { GST_VAAPI_CONTEXT_USAGE_DECODE, profile, GST_VAAPI_ENTRYPOINT_VLD, 0, }; - gboolean ret; g_return_val_if_fail (display != NULL, FALSE); g_return_val_if_fail (structure != NULL, FALSE); - context = create_context (display, &cip); - if (!context) - return FALSE; - - ret = append_caps (context, structure); - gst_vaapi_object_unref (context); - return ret; + return append_caps_with_context_info (display, &cip, structure); } /** @@ -129,20 +137,12 @@ gst_vaapi_profile_caps_append_encoder (GstVaapiDisplay * display, GstVaapiProfile profile, GstVaapiEntrypoint entrypoint, GstStructure * structure) { - GstVaapiContext *context; GstVaapiContextInfo cip = { GST_VAAPI_CONTEXT_USAGE_ENCODE, profile, entrypoint, 0, }; - gboolean ret; g_return_val_if_fail (display != NULL, FALSE); g_return_val_if_fail (structure != NULL, FALSE); - context = create_context (display, &cip); - if (!context) - return FALSE; - - ret = append_caps (context, structure); - gst_vaapi_object_unref (context); - return ret; + return append_caps_with_context_info (display, &cip, structure); } From f88d18bebe0b21db2f5a2dce82899046a4c7a0ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 18 Aug 2019 13:53:19 +0200 Subject: [PATCH 3323/3781] vaapipostproc: append frame size restrictions in caps --- gst-libs/gst/vaapi/gstvaapifilter.c | 37 +++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 3 +++ gst/vaapi/gstvaapipostproc.c | 22 ++++++++++++++--- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 82a7cd6838..766b421f34 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1699,6 +1699,43 @@ gst_vaapi_filter_set_format (GstVaapiFilter * filter, GstVideoFormat format) return TRUE; } +/** + * gst_vaapi_filter_append_caps: + * @filter: a #GstVaapiFilter + * @structure: a #GstStructure from #GstCaps + * + * Extracts the config's surface attributes, from @filter's context, + * and transforms it into a caps formats and appended them into + * @structure. + * + * Returns: %TRUE if the capabilities could be extracted and appended + * into @structure; otherwise %FALSE + **/ +gboolean +gst_vaapi_filter_append_caps (GstVaapiFilter * filter, GstStructure * structure) +{ + GstVaapiConfigSurfaceAttributes *attribs; + + g_return_val_if_fail (filter != NULL, FALSE); + g_return_val_if_fail (structure != NULL, FALSE); + + if (!ensure_attributes (filter)) + return FALSE; + + attribs = filter->attribs; + + if (attribs->min_width >= attribs->max_width || + attribs->min_height >= attribs->max_height) + return FALSE; + + gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, attribs->min_width, + attribs->max_width, "height", GST_TYPE_INT_RANGE, attribs->min_height, + attribs->max_height, NULL); + + return TRUE; + +} + /** * gst_vaapi_filter_set_cropping_rectangle: * @filter: a #GstVaapiFilter diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 45990e0b89..3424ba5a6a 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -210,6 +210,9 @@ 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); + gboolean gst_vaapi_filter_set_cropping_rectangle (GstVaapiFilter * filter, const GstVaapiRectangle * rect); diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index ac8bcb29a1..b852e8905a 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1103,6 +1103,7 @@ static gboolean ensure_allowed_sinkpad_caps (GstVaapiPostproc * postproc) { GstCaps *out_caps, *raw_caps; + guint i, num_structures; if (postproc->allowed_sinkpad_caps) return TRUE; @@ -1128,6 +1129,18 @@ ensure_allowed_sinkpad_caps (GstVaapiPostproc * postproc) out_caps = gst_caps_make_writable (out_caps); gst_caps_append (out_caps, gst_caps_copy (raw_caps)); + + num_structures = gst_caps_get_size (out_caps); + for (i = 0; i < num_structures; i++) { + GstStructure *structure; + + structure = gst_caps_get_structure (out_caps, i); + if (!structure) + continue; + + gst_vaapi_filter_append_caps (postproc->filter, structure); + } + postproc->allowed_sinkpad_caps = out_caps; /* XXX: append VA/VPP filters */ @@ -1160,15 +1173,18 @@ expand_allowed_srcpad_caps (GstVaapiPostproc * postproc, GstCaps * caps) GstCapsFeatures *const features = gst_caps_get_features (caps, i); GstStructure *structure; + structure = gst_caps_get_structure (caps, i); + if (!structure) + continue; + + gst_vaapi_filter_append_caps (postproc->filter, structure); + if (gst_caps_features_contains (features, GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META)) { gl_upload_meta_idx = i; continue; } - structure = gst_caps_get_structure (caps, i); - if (!structure) - continue; gst_structure_set_value (structure, "format", &value); } g_value_unset (&value); From e8b52f59f54573b459ce2f00c02a0633923543a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 18 Aug 2019 13:53:53 +0200 Subject: [PATCH 3324/3781] vaapidecode: guard if no structure is available in caps --- gst/vaapi/gstvaapidecode.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6f58906d92..c93dcd6e6c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -325,6 +325,8 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) case GST_VAAPI_CAPS_FEATURE_DMABUF: case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE:{ GstStructure *structure = gst_caps_get_structure (state->caps, 0); + if (!structure) + break; /* Remove chroma-site and colorimetry from src caps, * which is unnecessary on downstream if using VASurface @@ -886,6 +888,9 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) GstStructure *const structure = gst_caps_get_structure (caps, 0); const gchar *str = NULL; + if (!structure) + break; + if ((str = gst_structure_get_string (structure, "alignment"))) { GstVaapiStreamAlignH264 alignment; if (g_strcmp0 (str, "au") == 0) @@ -914,6 +919,9 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) GstStructure *const structure = gst_caps_get_structure (caps, 0); const gchar *str = NULL; + if (!structure) + break; + if ((str = gst_structure_get_string (structure, "alignment"))) { GstVaapiStreamAlignH265 alignment; if (g_strcmp0 (str, "au") == 0) @@ -1249,6 +1257,8 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) if (!caps) continue; structure = gst_caps_get_structure (caps, 0); + if (!structure) + continue; profile_name = gst_vaapi_profile_get_name (profile); if (profile_name) From dae057588befd82fde1c11437a0c74c259a7086a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 20 Aug 2019 16:50:46 +0200 Subject: [PATCH 3325/3781] libs: remove surface's parent context In commit 18031dc6 surface's parent context is not assigned because of circular references. Since then (2013), there's has no issue with subpictures attached to a context, the current only users of this API. This patch cleans up all of related code with the unused surface's parent context. --- gst-libs/gst/vaapi/gstvaapicontext.c | 11 +----- gst-libs/gst/vaapi/gstvaapisurface.c | 46 +---------------------- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- gst-libs/gst/vaapi/gstvaapisurface_priv.h | 10 ----- gst/vaapi/gstvaapipluginutil.c | 2 +- tests/test-subpicture.c | 3 +- 6 files changed, 5 insertions(+), 69 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 61573d2089..a8855e633e 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -34,7 +34,6 @@ #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" #include "gstvaapisurface.h" -#include "gstvaapisurface_priv.h" #include "gstvaapisurfacepool.h" #include "gstvaapisurfaceproxy.h" #include "gstvaapivideopool_priv.h" @@ -61,13 +60,6 @@ ensure_attributes (GstVaapiContext * context) return (context->attribs != NULL); } -static void -unref_surface_cb (GstVaapiSurface * surface) -{ - gst_vaapi_surface_set_parent_context (surface, NULL); - gst_vaapi_object_unref (surface); -} - static inline gboolean context_get_attribute (GstVaapiContext * context, VAConfigAttribType type, guint * out_value_ptr) @@ -141,7 +133,6 @@ context_ensure_surfaces (GstVaapiContext * context) cip->chroma_type, cip->width, cip->height, context->attribs->formats); if (!surface) return FALSE; - gst_vaapi_surface_set_parent_context (surface, context); g_ptr_array_add (context->surfaces, surface); if (!gst_vaapi_video_pool_add_object (context->surfaces_pool, surface)) return FALSE; @@ -163,7 +154,7 @@ context_create_surfaces (GstVaapiContext * context) num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; if (!context->surfaces) { context->surfaces = g_ptr_array_new_full (num_surfaces, - (GDestroyNotify) unref_surface_cb); + (GDestroyNotify) gst_vaapi_object_unref); if (!context->surfaces) return FALSE; } diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 482c9b6348..d17b00e6c4 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -35,7 +35,6 @@ #include "gstvaapicontext.h" #include "gstvaapiimage.h" #include "gstvaapiimage_priv.h" -#include "gstvaapicontext_overlay.h" #include "gstvaapibufferproxy_priv.h" #define DEBUG 1 @@ -78,7 +77,6 @@ gst_vaapi_surface_destroy (GstVaapiSurface * surface) GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); gst_vaapi_surface_destroy_subpictures (surface); - gst_vaapi_surface_set_parent_context (surface, NULL); if (surface_id != VA_INVALID_SURFACE) { GST_VAAPI_DISPLAY_LOCK (display); @@ -619,42 +617,6 @@ gst_vaapi_surface_get_size (GstVaapiSurface * surface, *height_ptr = GST_VAAPI_SURFACE_HEIGHT (surface); } -/** - * gst_vaapi_surface_set_parent_context: - * @surface: a #GstVaapiSurface - * @context: a #GstVaapiContext - * - * Sets new parent context, or clears any parent context if @context - * is %NULL. This function owns an extra reference to the context, - * which will be released when the surface is destroyed. - */ -void -gst_vaapi_surface_set_parent_context (GstVaapiSurface * surface, - GstVaapiContext * context) -{ - g_return_if_fail (surface != NULL); - - surface->parent_context = NULL; -} - -/** - * gst_vaapi_surface_get_parent_context: - * @surface: a #GstVaapiSurface - * - * Retrieves the parent #GstVaapiContext, or %NULL if there is - * none. The surface shall still own a reference to the context. - * i.e. the caller shall not unreference the returned context object. - * - * Return value: the parent context, if any. - */ -GstVaapiContext * -gst_vaapi_surface_get_parent_context (GstVaapiSurface * surface) -{ - g_return_val_if_fail (surface != NULL, NULL); - - return surface->parent_context; -} - /** * gst_vaapi_surface_derive_image: * @surface: a #GstVaapiSurface @@ -1026,8 +988,6 @@ gst_vaapi_surface_query_status (GstVaapiSurface * surface, * gst_vaapi_surface_set_subpictures_from_composition: * @surface: a #GstVaapiSurface * @compostion: a #GstVideoOverlayCompositon - * @propagate_context: a flag specifying whether to apply composition - * to the parent context, if any * * Helper to update the subpictures from #GstVideoOverlayCompositon. Sending * a NULL composition will clear all the current subpictures. Note that this @@ -1037,17 +997,13 @@ gst_vaapi_surface_query_status (GstVaapiSurface * surface, */ gboolean gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface, - GstVideoOverlayComposition * composition, gboolean propagate_context) + GstVideoOverlayComposition * composition) { GstVaapiDisplay *display; guint n, nb_rectangles; g_return_val_if_fail (surface != NULL, FALSE); - if (propagate_context && surface->parent_context) - return gst_vaapi_context_apply_composition (surface->parent_context, - composition); - display = GST_VAAPI_OBJECT_DISPLAY (surface); if (!display) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 844eaf28ce..c62f7bb81a 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -247,7 +247,7 @@ gst_vaapi_surface_query_status (GstVaapiSurface * surface, gboolean gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface, - GstVideoOverlayComposition * composition, gboolean propagate_context); + GstVideoOverlayComposition * composition); void gst_vaapi_surface_set_buffer_proxy (GstVaapiSurface * surface, diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index 4ac1e0c1c5..35ac7fa905 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -47,7 +47,6 @@ struct _GstVaapiSurface guint height; GstVaapiChromaType chroma_type; GPtrArray *subpictures; - GstVaapiContext *parent_context; }; /** @@ -109,15 +108,6 @@ struct _GstVaapiSurfaceClass #define GST_VAAPI_SURFACE_HEIGHT(surface) \ (GST_VAAPI_SURFACE (surface)->height) -G_GNUC_INTERNAL -void -gst_vaapi_surface_set_parent_context (GstVaapiSurface * surface, - GstVaapiContext * context); - -G_GNUC_INTERNAL -GstVaapiContext * -gst_vaapi_surface_get_parent_context (GstVaapiSurface * surface); - G_END_DECLS #endif /* GST_VAAPI_SURFACE_PRIV_H */ diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 3599b6a063..4ef3895351 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -482,7 +482,7 @@ gst_vaapi_apply_composition (GstVaapiSurface * surface, GstBuffer * buffer) if (cmeta) composition = cmeta->overlay; return gst_vaapi_surface_set_subpictures_from_composition (surface, - composition, TRUE); + composition); } gboolean diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c index ee000560b9..804f0a9e32 100644 --- a/tests/test-subpicture.c +++ b/tests/test-subpicture.c @@ -149,8 +149,7 @@ main (int argc, char *argv[]) g_error ("could not create video overlay composition"); gst_video_overlay_rectangle_unref (overlay); - if (!gst_vaapi_surface_set_subpictures_from_composition (surface, compo, - FALSE)) + if (!gst_vaapi_surface_set_subpictures_from_composition (surface, compo)) g_error ("could not create subpictures from video overlay compoition"); gst_vaapi_window_show (window); From b36eea201f8b57993262ea36a6100b736f90cb89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 20 Aug 2019 17:05:14 +0200 Subject: [PATCH 3326/3781] libs: remove context's overlay The context overlay was an optimization to apply a video composition to all the surfaces bound to a context. But since commit 18031dc6 this optimization was disabled, so it is better just get rid of it. --- gst-libs/gst/vaapi/Makefile.am | 2 - gst-libs/gst/vaapi/gstvaapicontext.c | 8 - gst-libs/gst/vaapi/gstvaapicontext_overlay.c | 450 ------------------- gst-libs/gst/vaapi/gstvaapicontext_overlay.h | 52 --- gst-libs/gst/vaapi/meson.build | 1 - 5 files changed, 513 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapicontext_overlay.c delete mode 100644 gst-libs/gst/vaapi/gstvaapicontext_overlay.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 4016933f62..9c76c24ef7 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -45,7 +45,6 @@ libgstvaapi_source_c = \ gstvaapibufferproxy.c \ gstvaapicodec_objects.c \ gstvaapicontext.c \ - gstvaapicontext_overlay.c \ gstvaapidecoder.c \ gstvaapidecoder_dpb.c \ gstvaapidecoder_h264.c \ @@ -121,7 +120,6 @@ libgstvaapi_source_priv_h = \ gstvaapicodec_objects.h \ gstvaapicompat.h \ gstvaapicontext.h \ - gstvaapicontext_overlay.h \ gstvaapidebug.h \ gstvaapidecoder_dpb.h \ gstvaapidecoder_objects.h \ diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index a8855e633e..2be0709bca 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -30,7 +30,6 @@ #include "sysdeps.h" #include "gstvaapicompat.h" #include "gstvaapicontext.h" -#include "gstvaapicontext_overlay.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiobject_priv.h" #include "gstvaapisurface.h" @@ -71,8 +70,6 @@ context_get_attribute (GstVaapiContext * context, VAConfigAttribType type, static void context_destroy_surfaces (GstVaapiContext * context) { - gst_vaapi_context_overlay_reset (context); - if (context->surfaces) { g_ptr_array_unref (context->surfaces); context->surfaces = NULL; @@ -148,9 +145,6 @@ context_create_surfaces (GstVaapiContext * context) GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); guint num_surfaces; - if (!gst_vaapi_context_overlay_reset (context)) - return FALSE; - num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; if (!context->surfaces) { context->surfaces = g_ptr_array_new_full (num_surfaces, @@ -395,7 +389,6 @@ gst_vaapi_context_init (GstVaapiContext * context, context->va_config = VA_INVALID_ID; context->reset_on_resize = TRUE; - gst_vaapi_context_overlay_init (context); context->attribs = NULL; } @@ -405,7 +398,6 @@ gst_vaapi_context_finalize (GstVaapiContext * context) { context_destroy (context); context_destroy_surfaces (context); - gst_vaapi_context_overlay_finalize (context); } GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiContext, gst_vaapi_context); diff --git a/gst-libs/gst/vaapi/gstvaapicontext_overlay.c b/gst-libs/gst/vaapi/gstvaapicontext_overlay.c deleted file mode 100644 index 9059e3b8a9..0000000000 --- a/gst-libs/gst/vaapi/gstvaapicontext_overlay.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * gstvaapicontext_overlay.c - VA context abstraction (overlay composition) - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Author: Gwenole Beauchesne - * Copyright (C) 2011-2014 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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 "gstvaapicontext_overlay.h" -#include "gstvaapiutils.h" -#include "gstvaapiimage.h" -#include "gstvaapisubpicture.h" - -#define DEBUG 1 -#include "gstvaapidebug.h" - -typedef struct _GstVaapiOverlayRectangle GstVaapiOverlayRectangle; -struct _GstVaapiOverlayRectangle -{ - GstVaapiContext *context; - GstVaapiSubpicture *subpicture; - GstVaapiRectangle render_rect; - guint seq_num; - guint layer_id; - GstBuffer *rect_buffer; - GstVideoOverlayRectangle *rect; - guint is_associated:1; -}; - -static inline void -gst_video_overlay_rectangle_replace (GstVideoOverlayRectangle ** old_rect_ptr, - GstVideoOverlayRectangle * new_rect) -{ - gst_mini_object_replace ((GstMiniObject **) old_rect_ptr, - GST_MINI_OBJECT_CAST (new_rect)); -} - -#define overlay_rectangle_ref(overlay) \ - gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(overlay)) - -#define overlay_rectangle_unref(overlay) \ - gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(overlay)) - -#define overlay_rectangle_replace(old_overlay_ptr, new_overlay) \ - gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_overlay_ptr), \ - (GstVaapiMiniObject *)(new_overlay)) - -static void overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay); - -static gboolean -overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay); - -static gboolean -overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay); - -static inline const GstVaapiMiniObjectClass * -overlay_rectangle_class (void) -{ - static const GstVaapiMiniObjectClass GstVaapiOverlayRectangleClass = { - sizeof (GstVaapiOverlayRectangle), - (GDestroyNotify) overlay_rectangle_finalize - }; - return &GstVaapiOverlayRectangleClass; -} - -static GstVaapiOverlayRectangle * -overlay_rectangle_new (GstVideoOverlayRectangle * rect, - GstVaapiContext * context, guint layer_id) -{ - GstVaapiOverlayRectangle *overlay; - GstVaapiRectangle *render_rect; - guint width, height, flags; - gint x, y; - - overlay = (GstVaapiOverlayRectangle *) - gst_vaapi_mini_object_new0 (overlay_rectangle_class ()); - if (!overlay) - return NULL; - - overlay->context = context; - overlay->seq_num = gst_video_overlay_rectangle_get_seqnum (rect); - overlay->layer_id = layer_id; - overlay->rect = gst_video_overlay_rectangle_ref (rect); - - flags = gst_video_overlay_rectangle_get_flags (rect); - gst_buffer_replace (&overlay->rect_buffer, - gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags)); - if (!overlay->rect_buffer) - goto error; - - overlay->subpicture = - gst_vaapi_subpicture_new_from_overlay_rectangle (GST_VAAPI_OBJECT_DISPLAY - (context), rect); - if (!overlay->subpicture) - goto error; - - gst_video_overlay_rectangle_get_render_rectangle (rect, - &x, &y, &width, &height); - render_rect = &overlay->render_rect; - render_rect->x = x; - render_rect->y = y; - render_rect->width = width; - render_rect->height = height; - return overlay; - - /* ERRORS */ -error: - { - overlay_rectangle_unref (overlay); - return NULL; - } -} - -static void -overlay_rectangle_finalize (GstVaapiOverlayRectangle * overlay) -{ - gst_buffer_replace (&overlay->rect_buffer, NULL); - gst_video_overlay_rectangle_unref (overlay->rect); - - if (overlay->subpicture) { - overlay_rectangle_deassociate (overlay); - gst_vaapi_object_unref (overlay->subpicture); - overlay->subpicture = NULL; - } -} - -static gboolean -overlay_rectangle_associate (GstVaapiOverlayRectangle * overlay) -{ - GstVaapiSubpicture *const subpicture = overlay->subpicture; - GPtrArray *const surfaces = overlay->context->surfaces; - guint i, n_associated; - - if (overlay->is_associated) - return TRUE; - - n_associated = 0; - for (i = 0; i < surfaces->len; i++) { - GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i); - if (gst_vaapi_surface_associate_subpicture (surface, subpicture, - NULL, &overlay->render_rect)) - n_associated++; - } - - overlay->is_associated = TRUE; - return n_associated == surfaces->len; -} - -static gboolean -overlay_rectangle_deassociate (GstVaapiOverlayRectangle * overlay) -{ - GstVaapiSubpicture *const subpicture = overlay->subpicture; - GPtrArray *const surfaces = overlay->context->surfaces; - guint i, n_associated; - - if (!overlay->is_associated) - return TRUE; - - n_associated = surfaces->len; - for (i = 0; i < surfaces->len; i++) { - GstVaapiSurface *const surface = g_ptr_array_index (surfaces, i); - if (gst_vaapi_surface_deassociate_subpicture (surface, subpicture)) - n_associated--; - } - - overlay->is_associated = FALSE; - return n_associated == 0; -} - -static gboolean -overlay_rectangle_changed_pixels (GstVaapiOverlayRectangle * overlay, - GstVideoOverlayRectangle * rect) -{ - guint flags; - GstBuffer *buffer; - - if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum (rect)) - return FALSE; - - flags = - to_GstVideoOverlayFormatFlags (gst_vaapi_subpicture_get_flags - (overlay->subpicture)); - - buffer = gst_video_overlay_rectangle_get_pixels_unscaled_raw (rect, flags); - if (!buffer) - return FALSE; - { - const guint n_blocks = gst_buffer_n_memory (buffer); - gsize ofs; - guint i; - - if (buffer == overlay->rect_buffer) - return TRUE; - - if (n_blocks != gst_buffer_n_memory (overlay->rect_buffer)) - return FALSE; - - for (i = 0; i < n_blocks; i++) { - GstMemory *const mem1 = gst_buffer_peek_memory (buffer, i); - GstMemory *const mem2 = gst_buffer_peek_memory (overlay->rect_buffer, i); - if (!gst_memory_is_span (mem1, mem2, &ofs)) - return FALSE; - } - } - return TRUE; -} - -static gboolean -overlay_rectangle_changed_render_rect (GstVaapiOverlayRectangle * overlay, - GstVideoOverlayRectangle * rect) -{ - GstVaapiRectangle *const render_rect = &overlay->render_rect; - guint width, height; - gint x, y; - - gst_video_overlay_rectangle_get_render_rectangle (rect, - &x, &y, &width, &height); - - if (x == render_rect->x && - y == render_rect->y && - width == render_rect->width && height == render_rect->height) - return FALSE; - - render_rect->x = x; - render_rect->y = y; - render_rect->width = width; - render_rect->height = height; - return TRUE; -} - -static inline gboolean -overlay_rectangle_update_global_alpha (GstVaapiOverlayRectangle * overlay, - GstVideoOverlayRectangle * rect) -{ - const guint flags = gst_video_overlay_rectangle_get_flags (rect); - if (!(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)) - return TRUE; - return gst_vaapi_subpicture_set_global_alpha (overlay->subpicture, - gst_video_overlay_rectangle_get_global_alpha (rect)); -} - -static gboolean -overlay_rectangle_update (GstVaapiOverlayRectangle * overlay, - GstVideoOverlayRectangle * rect, gboolean * reassociate_ptr) -{ - if (overlay_rectangle_changed_pixels (overlay, rect)) - return FALSE; - if (overlay_rectangle_changed_render_rect (overlay, rect)) - *reassociate_ptr = TRUE; - if (!overlay_rectangle_update_global_alpha (overlay, rect)) - return FALSE; - gst_video_overlay_rectangle_replace (&overlay->rect, rect); - return TRUE; -} - -static inline GPtrArray * -overlay_new (void) -{ - return g_ptr_array_new_with_free_func ( - (GDestroyNotify) gst_vaapi_mini_object_unref); -} - -static void -overlay_destroy (GPtrArray ** overlay_ptr) -{ - GPtrArray *const overlay = *overlay_ptr; - - if (!overlay) - return; - g_ptr_array_unref (overlay); - *overlay_ptr = NULL; -} - -static void -overlay_clear (GPtrArray * overlay) -{ - if (overlay && overlay->len > 0) - g_ptr_array_remove_range (overlay, 0, overlay->len); -} - -static GstVaapiOverlayRectangle * -overlay_lookup (GPtrArray * overlays, GstVideoOverlayRectangle * rect) -{ - guint i; - - for (i = 0; i < overlays->len; i++) { - GstVaapiOverlayRectangle *const overlay = g_ptr_array_index (overlays, i); - - if (overlay->rect == rect) - return overlay; - } - return NULL; -} - -static gboolean -overlay_reassociate (GPtrArray * overlays) -{ - guint i; - - for (i = 0; i < overlays->len; i++) - overlay_rectangle_deassociate (g_ptr_array_index (overlays, i)); - - for (i = 0; i < overlays->len; i++) { - if (!overlay_rectangle_associate (g_ptr_array_index (overlays, i))) - return FALSE; - } - return TRUE; -} - -static gboolean -overlay_ensure (GPtrArray ** overlay_ptr) -{ - GPtrArray *overlay = *overlay_ptr; - - if (!overlay) { - overlay = overlay_new (); - if (!overlay) - return FALSE; - *overlay_ptr = overlay; - } - return TRUE; -} - -/** Initializes overlay resources */ -gboolean -gst_vaapi_context_overlay_init (GstVaapiContext * context) -{ - if (!overlay_ensure (&context->overlays[0])) - return FALSE; - if (!overlay_ensure (&context->overlays[1])) - return FALSE; - return TRUE; -} - -/** Destroys overlay resources */ -void -gst_vaapi_context_overlay_finalize (GstVaapiContext * context) -{ - overlay_destroy (&context->overlays[0]); - overlay_destroy (&context->overlays[1]); -} - -/** Resets overlay resources to a clean state */ -gboolean -gst_vaapi_context_overlay_reset (GstVaapiContext * context) -{ - guint num_errors = 0; - - if (overlay_ensure (&context->overlays[0])) - overlay_clear (context->overlays[0]); - else - num_errors++; - - if (overlay_ensure (&context->overlays[1])) - overlay_clear (context->overlays[1]); - else - num_errors++; - - context->overlay_id = 0; - return num_errors == 0; -} - -/** - * gst_vaapi_context_apply_composition: - * @context: a #GstVaapiContext - * @composition: a #GstVideoOverlayComposition - * - * Applies video composition planes to all surfaces bound to @context. - * This helper function resets any additional subpictures the user may - * have associated himself. A %NULL @composition will also clear all - * the existing subpictures. - * - * Return value: %TRUE if all composition planes could be applied, - * %FALSE otherwise - */ -gboolean -gst_vaapi_context_apply_composition (GstVaapiContext * context, - GstVideoOverlayComposition * composition) -{ - GPtrArray *curr_overlay, *next_overlay; - guint i, n_rectangles; - gboolean reassociate = FALSE; - - g_return_val_if_fail (context != NULL, FALSE); - - if (!context->surfaces) - return FALSE; - - if (!composition) { - gst_vaapi_context_overlay_reset (context); - return TRUE; - } - - curr_overlay = context->overlays[context->overlay_id]; - next_overlay = context->overlays[context->overlay_id ^ 1]; - overlay_clear (next_overlay); - - n_rectangles = gst_video_overlay_composition_n_rectangles (composition); - for (i = 0; i < n_rectangles; i++) { - GstVideoOverlayRectangle *const rect = - gst_video_overlay_composition_get_rectangle (composition, i); - GstVaapiOverlayRectangle *overlay; - - overlay = overlay_lookup (curr_overlay, rect); - if (overlay && overlay_rectangle_update (overlay, rect, &reassociate)) { - overlay_rectangle_ref (overlay); - if (overlay->layer_id != i) - reassociate = TRUE; - } else { - overlay = overlay_rectangle_new (rect, context, i); - if (!overlay) { - GST_WARNING ("could not create VA overlay rectangle"); - goto error; - } - reassociate = TRUE; - } - g_ptr_array_add (next_overlay, overlay); - } - - overlay_clear (curr_overlay); - context->overlay_id ^= 1; - - if (reassociate && !overlay_reassociate (next_overlay)) - return FALSE; - return TRUE; - - /* ERRORS */ -error: - { - gst_vaapi_context_overlay_reset (context); - return FALSE; - } -} diff --git a/gst-libs/gst/vaapi/gstvaapicontext_overlay.h b/gst-libs/gst/vaapi/gstvaapicontext_overlay.h deleted file mode 100644 index 85440e9d4c..0000000000 --- a/gst-libs/gst/vaapi/gstvaapicontext_overlay.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * gstvaapicontext_overlay.h - VA context abstraction (overlay composition) - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Author: Gwenole Beauchesne - * Copyright (C) 2011-2014 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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_OVERLAY_H -#define GST_VAAPI_CONTEXT_OVERLAY_H - -#include -#include "gstvaapicontext.h" - -G_BEGIN_DECLS - -G_GNUC_INTERNAL -gboolean -gst_vaapi_context_overlay_init (GstVaapiContext * context); - -G_GNUC_INTERNAL -void -gst_vaapi_context_overlay_finalize (GstVaapiContext * context); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_context_overlay_reset (GstVaapiContext * context); - -G_GNUC_INTERNAL -gboolean -gst_vaapi_context_apply_composition (GstVaapiContext * context, - GstVideoOverlayComposition * composition); - -G_END_DECLS - -#endif /* GST_VAAPI_CONTEXT_OVERLAY_H */ diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index eb67b75801..68b60eb8f1 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -2,7 +2,6 @@ gstlibvaapi_sources = [ 'gstvaapibufferproxy.c', 'gstvaapicodec_objects.c', 'gstvaapicontext.c', - 'gstvaapicontext_overlay.c', 'gstvaapidecoder.c', 'gstvaapidecoder_dpb.c', 'gstvaapidecoder_h264.c', From 05927317153719d9120213a8996f4b9ced169f26 Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Fri, 23 Aug 2019 19:10:15 +0200 Subject: [PATCH 3327/3781] docstrings: port ulinks to markdown links --- gst/vaapi/gstvaapidecodedoc.c | 37 ++++++++++------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/gst/vaapi/gstvaapidecodedoc.c b/gst/vaapi/gstvaapidecodedoc.c index f8dd837f62..3deb2c4e0d 100644 --- a/gst/vaapi/gstvaapidecodedoc.c +++ b/gst/vaapi/gstvaapidecodedoc.c @@ -25,9 +25,8 @@ * @short_description: A VA-API based JPEG image decoder * * vaapijpegdec decodes a JPEG image to surfaces suitable for the - * vaapisink or vaapipostproc elements using the installed VA-API - * back-end. + * vaapisink or vaapipostproc elements using the installed + * [VA-API](https://wiki.freedesktop.org/www/Software/vaapi/) back-end. * * In the case of OpenGL based elements, the buffers have the * #GstVideoGLTextureUploadMeta meta, which efficiently copies the @@ -50,9 +49,7 @@ * * vaapimpeg2dec decodes from MPEG2 bitstreams to surfaces suitable * for the vaapisink or vaapipostproc elements using the installed - * VA-API - * back-end. + * [VA-API](https://wiki.freedesktop.org/www/Software/vaapi/) back-end. * * In the case of OpenGL based elements, the buffers have the * #GstVideoGLTextureUploadMeta meta, which efficiently copies the @@ -75,9 +72,7 @@ * * vaapimpeg4dec decodes from MPEG4 bitstreams to surfaces suitable * for the vaapisink or vaapipostproc elements using the installed - * VA-API - * back-end. + * [VA-API](https://wiki.freedesktop.org/www/Software/vaapi/) back-end. * * In the case of OpenGL based elements, the buffers have the * #GstVideoGLTextureUploadMeta meta, which efficiently copies the @@ -100,9 +95,7 @@ * * vaapih263dec decodes from H263 bitstreams to surfaces suitable * for the vaapisink or vaapipostproc elements using the installed - * VA-API - * back-end. + * [VA-API](https://wiki.freedesktop.org/www/Software/vaapi/) back-end. * * In the case of OpenGL based elements, the buffers have the * #GstVideoGLTextureUploadMeta meta, which efficiently copies the @@ -125,9 +118,7 @@ * * vaapih264dec decodes from H264 bitstreams to surfaces suitable * for the vaapisink or vaapipostproc elements using the installed - * VA-API - * back-end. + * [VA-API](https://wiki.freedesktop.org/www/Software/vaapi/) back-end. * * In the case of OpenGL based elements, the buffers have the * #GstVideoGLTextureUploadMeta meta, which efficiently copies the @@ -150,9 +141,7 @@ * * vaapih265dec decodes from H265 bitstreams to surfaces suitable * for the vaapisink or vaapipostproc elements using the installed - * VA-API - * back-end. + * [VA-API](https://wiki.freedesktop.org/www/Software/vaapi/) back-end. * * In the case of OpenGL based elements, the buffers have the * #GstVideoGLTextureUploadMeta meta, which efficiently copies the @@ -175,9 +164,7 @@ * * vaapivc1dec decodes from VC1 bitstreams to surfaces suitable * for the vaapisink or vaapipostproc elements using the installed - * VA-API - * back-end. + * [VA-API](https://wiki.freedesktop.org/www/Software/vaapi/) back-end. * * In the case of OpenGL based elements, the buffers have the * #GstVideoGLTextureUploadMeta meta, which efficiently copies the @@ -200,9 +187,7 @@ * * vaapivp8dec decodes from VP8 bitstreams to surfaces suitable * for the vaapisink or vaapipostproc elements using the installed - * VA-API - * back-end. + * [VA-API](https://wiki.freedesktop.org/www/Software/vaapi/) back-end. * * In the case of OpenGL based elements, the buffers have the * #GstVideoGLTextureUploadMeta meta, which efficiently copies the @@ -225,9 +210,7 @@ * * vaapivp9dec decodes from VP9 bitstreams to surfaces suitable * for the vaapisink or vaapipostproc elements using the installed - * VA-API - * back-end. + * [VA-API](https://wiki.freedesktop.org/www/Software/vaapi/) back-end. * * In the case of OpenGL based elements, the buffers have the * #GstVideoGLTextureUploadMeta meta, which efficiently copies the From 6f8ea02b614768e183f825cd25025e478f63eac2 Mon Sep 17 00:00:00 2001 From: Wangfei Date: Thu, 22 Aug 2019 14:33:54 +0800 Subject: [PATCH 3328/3781] vaapidecode: support transform ROI meta This will benefit the use case like: src ---> encode ---> decode ---> circle ROI ---> sink | | --> analyse to --> get ROI --- gst/vaapi/gstvaapidecode.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index c93dcd6e6c..a677d3796c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1434,6 +1434,22 @@ gst_vaapidecode_sink_event (GstVideoDecoder * vdec, GstEvent * event) return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (vdec, event); } +static gboolean +gst_vaapidecode_transform_meta (GstVideoDecoder * + vdec, GstVideoCodecFrame * frame, GstMeta * meta) +{ + const GstMetaInfo *info = meta->info; + + if (GST_VIDEO_DECODER_CLASS (parent_class)->transform_meta (vdec, frame, + meta)) + return TRUE; + + if (!g_strcmp0 (g_type_name (info->type), "GstVideoRegionOfInterestMeta")) + return TRUE; + + return FALSE; +} + static void gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) { @@ -1470,6 +1486,8 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_query); vdec_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_getcaps); vdec_class->sink_event = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_event); + vdec_class->transform_meta = + GST_DEBUG_FUNCPTR (gst_vaapidecode_transform_meta); map = (GstVaapiDecoderMap *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass), GST_VAAPI_DECODE_PARAMS_QDATA); From 51963b1a7427be9872373b03790a626808f5d781 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 27 Aug 2019 01:30:36 +0800 Subject: [PATCH 3329/3781] libs: util: Fix a memory leak in config_surface_attributes_get --- gst-libs/gst/vaapi/gstvaapiutils_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_core.c b/gst-libs/gst/vaapi/gstvaapiutils_core.c index d7aa26003c..7c98208d42 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_core.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_core.c @@ -202,6 +202,7 @@ gst_vaapi_config_surface_attributes_get (GstVaapiDisplay * display, } } + g_free (surface_attribs); return attribs; /* ERRORS */ From 70cefdd2721729c786a1cb57f0ed9f6497eb027a Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 27 Aug 2019 18:12:45 +0800 Subject: [PATCH 3330/3781] libs: postproc: fix a memory leak point. filter_ops and filter_formats should already have valid value when the function gst_vaapipostproc_ensure_filter_caps re-enter --- gst/vaapi/gstvaapipostproc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index b852e8905a..b1750d0e50 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -246,13 +246,17 @@ gst_vaapipostproc_ensure_filter_caps (GstVaapiPostproc * postproc) if (!gst_vaapipostproc_ensure_filter (postproc)) return FALSE; - postproc->filter_ops = gst_vaapi_filter_get_operations (postproc->filter); - if (!postproc->filter_ops) - return FALSE; + if (!postproc->filter_ops) { + postproc->filter_ops = gst_vaapi_filter_get_operations (postproc->filter); + if (!postproc->filter_ops) + return FALSE; + } - postproc->filter_formats = gst_vaapi_filter_get_formats (postproc->filter); - if (!postproc->filter_formats) - return FALSE; + if (!postproc->filter_formats) { + postproc->filter_formats = gst_vaapi_filter_get_formats (postproc->filter); + if (!postproc->filter_formats) + return FALSE; + } return TRUE; } From 9fe6b621a2eef6d17ae4f662781da9f3b344b8dc Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 28 Aug 2019 12:49:03 -0400 Subject: [PATCH 3331/3781] Classify vaapidecodebin as a hardware decoder --- gst/vaapi/gstvaapidecodebin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 021953bf06..52a102e160 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -245,7 +245,7 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass) element_class->change_state = gst_vaapi_decode_bin_change_state; gst_element_class_set_static_metadata (element_class, "VA-API Decode Bin", - "Codec/Decoder/Video", + "Codec/Decoder/Video/Hardware", GST_PLUGIN_DESC, "Sreerenj Balachandran , " "Victor Jaquez "); From d671197684c7c1196a4bc2250e3d20442d75d96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 29 Aug 2019 12:11:36 +0200 Subject: [PATCH 3332/3781] vaapipostproc: check for filter before appending caps While ensuring the allowed sink pad caps, the filter attributes set the frame size restriction, but it is not ensured, at that moment, that the filter is already instantiaded. In order to silence the glib logs, this patch add only calls gst_vaapi_filter_append_caps() if the filter is instantiated. --- gst/vaapi/gstvaapipostproc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index b1750d0e50..6e53dc2d7c 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1142,7 +1142,8 @@ ensure_allowed_sinkpad_caps (GstVaapiPostproc * postproc) if (!structure) continue; - gst_vaapi_filter_append_caps (postproc->filter, structure); + if (postproc->filter) + gst_vaapi_filter_append_caps (postproc->filter, structure); } postproc->allowed_sinkpad_caps = out_caps; From c4a47f91ba2749fde7c7eb4dbac3172345a874aa Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 27 Jul 2019 00:55:53 +0800 Subject: [PATCH 3333/3781] lib: encoder: gstobjectfy all vaapi encoders. Replace all gstvaapiobject in vaapi encoders with standard gstobject. Let the gstobject common logic to handle all the init and finalize works. But the property install/set/get still use the old way, need to be improved later. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 143 ++++++++++-------- gst-libs/gst/vaapi/gstvaapiencoder.h | 11 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 53 ++++--- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 10 +- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 91 ++++++----- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h | 10 +- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 53 ++++--- gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 10 +- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 44 +++--- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h | 10 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 49 +++--- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 10 +- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 17 +-- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 50 +++--- gst-libs/gst/vaapi/gstvaapiencoder_vp8.h | 10 +- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 47 +++--- gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 10 +- gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 76 +++++----- gst-libs/gst/vaapi/gstvaapifeienc_h264.h | 14 +- 19 files changed, 437 insertions(+), 281 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 937eb10a1c..7451a241bb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -113,9 +113,9 @@ error_allocation_failed: /* Generate the common set of encoder properties */ GPtrArray * -gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) +gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClassData * + cdata) { - const GstVaapiEncoderClassData *const cdata = klass->class_data; GPtrArray *props = NULL; g_assert (cdata->rate_control_get_type != NULL); @@ -462,7 +462,8 @@ void gst_vaapi_encoder_replace (GstVaapiEncoder ** old_encoder_ptr, GstVaapiEncoder * new_encoder) { - gst_vaapi_object_replace (old_encoder_ptr, new_encoder); + gst_object_replace ((GstObject **) old_encoder_ptr, + (GstObject *) new_encoder); } /* Notifies gst_vaapi_encoder_create_coded_buffer() that a new buffer is free */ @@ -1546,16 +1547,17 @@ error_operation_failed: } /* Initialize default values for configurable properties */ -static gboolean -gst_vaapi_encoder_init_properties (GstVaapiEncoder * encoder) +static void +gst_vaapi_encoder_constructed (GObject * object) { + GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); GPtrArray *props; guint i; props = klass->get_default_properties (); if (!props) - return FALSE; + return; encoder->properties = props; for (i = 0; i < props->len; i++) { @@ -1563,37 +1565,23 @@ gst_vaapi_encoder_init_properties (GstVaapiEncoder * encoder) if (gst_vaapi_encoder_set_property (encoder, prop->prop, NULL) != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return FALSE; + return; } - return TRUE; + return; } -/* Base encoder initialization (internal) */ -static gboolean -gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) +G_DEFINE_ABSTRACT_TYPE (GstVaapiEncoder, gst_vaapi_encoder, GST_TYPE_OBJECT); + +enum { - GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); + ENCODER_PROP_DISPLAY = 1, + ENCODER_N_PROPERTIES +}; - g_return_val_if_fail (display != NULL, FALSE); - -#define CHECK_VTABLE_HOOK(FUNC) do { \ - if (!klass->FUNC) \ - goto error_invalid_vtable; \ - } while (0) - - CHECK_VTABLE_HOOK (init); - CHECK_VTABLE_HOOK (finalize); - CHECK_VTABLE_HOOK (get_default_properties); - CHECK_VTABLE_HOOK (reconfigure); - CHECK_VTABLE_HOOK (encode); - CHECK_VTABLE_HOOK (reordering); - CHECK_VTABLE_HOOK (flush); - -#undef CHECK_VTABLE_HOOK - - encoder->display = gst_object_ref (display); - encoder->va_display = gst_vaapi_display_get_display (display); +static void +gst_vaapi_encoder_init (GstVaapiEncoder * encoder) +{ encoder->va_context = VA_INVALID_ID; gst_video_info_init (&encoder->video_info); @@ -1604,30 +1592,13 @@ gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display) encoder->codedbuf_queue = g_async_queue_new_full ((GDestroyNotify) gst_vaapi_coded_buffer_proxy_unref); - if (!encoder->codedbuf_queue) - return FALSE; - - if (!klass->init (encoder)) - return FALSE; - if (!gst_vaapi_encoder_init_properties (encoder)) - return FALSE; - return TRUE; - - /* ERRORS */ -error_invalid_vtable: - { - GST_ERROR ("invalid subclass hook (internal error)"); - return FALSE; - } } /* Base encoder cleanup (internal) */ -void -gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) +static void +gst_vaapi_encoder_finalize (GObject * object) { - GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); - - klass->finalize (encoder); + GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); gst_vaapi_object_replace (&encoder->context, NULL); gst_vaapi_display_replace (&encoder->display, NULL); @@ -1646,6 +1617,8 @@ gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder) g_cond_clear (&encoder->surface_free); g_cond_clear (&encoder->codedbuf_free); g_mutex_clear (&encoder->mutex); + + G_OBJECT_CLASS (gst_vaapi_encoder_parent_class)->finalize (object); } /* Helper function to create new GstVaapiEncoder instances (internal) */ @@ -1653,25 +1626,65 @@ GstVaapiEncoder * gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass, GstVaapiDisplay * display) { - GstVaapiEncoder *encoder; + return NULL; +} - encoder = (GstVaapiEncoder *) - gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS (klass)); - if (!encoder) - return NULL; +static void +encoder_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); - if (!gst_vaapi_encoder_init (encoder, display)) - goto error; - return encoder; - - /* ERRORS */ -error: - { - gst_vaapi_encoder_unref (encoder); - return NULL; + switch (prop_id) { + case ENCODER_PROP_DISPLAY: + g_assert (encoder->display == NULL); + encoder->display = g_value_dup_object (value); + g_assert (encoder->display != NULL); + encoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY (encoder->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } +static void +encoder_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); + + switch (prop_id) { + case ENCODER_PROP_DISPLAY: + g_value_set_object (value, encoder->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = encoder_set_property; + object_class->get_property = encoder_get_property; + object_class->finalize = gst_vaapi_encoder_finalize; + object_class->constructed = gst_vaapi_encoder_constructed; + + /** + * GstVaapiDecoder:display: + * + * #GstVaapiDisplay to be used. + */ + g_object_class_install_property (object_class, ENCODER_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 GstVaapiContext * create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile) { diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index a813dd2168..69eb1c9527 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -29,11 +29,18 @@ G_BEGIN_DECLS -#define GST_VAAPI_ENCODER(encoder) \ - ((GstVaapiEncoder *) (encoder)) +#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; + /** * GstVaapiEncoderStatus: * @GST_VAAPI_ENCODER_STATUS_SUCCESS: Success. diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 06c8478c12..490b0a11f7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3388,10 +3388,17 @@ gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder) return set_context_info (base_encoder); } -static gboolean -gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder) +struct _GstVaapiEncoderH264Class +{ + GstVaapiEncoderClass parent_class; +}; + +G_DEFINE_TYPE (GstVaapiEncoderH264, gst_vaapi_encoder_h264, + GST_TYPE_VAAPI_ENCODER); + +static void +gst_vaapi_encoder_h264_init (GstVaapiEncoderH264 * encoder) { - GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); guint32 i; /* Default encoding entrypoint */ @@ -3428,15 +3435,13 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder) encoder->compliance_mode = GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT; encoder->min_cr = 1; - - return TRUE; } static void -gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder) +gst_vaapi_encoder_h264_finalize (GObject * object) { /*free private buffers */ - GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (object); GstVaapiEncPicture *pic; GstVaapiEncoderH264Ref *ref; guint32 i; @@ -3466,6 +3471,8 @@ gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder) } g_queue_clear (&reorder_pool->reorder_frame_list); } + + G_OBJECT_CLASS (gst_vaapi_encoder_h264_parent_class)->finalize (object); } static void @@ -3581,16 +3588,24 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H264); -static inline const GstVaapiEncoderClass * -gst_vaapi_encoder_h264_class (void) +static void +gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) { - static const GstVaapiEncoderClass GstVaapiEncoderH264Class = { - GST_VAAPI_ENCODER_CLASS_INIT (H264, h264), - .set_property = gst_vaapi_encoder_h264_set_property, - .get_codec_data = gst_vaapi_encoder_h264_get_codec_data, - .get_pending_reordered = gst_vaapi_encoder_h264_get_pending_reordered, - }; - return &GstVaapiEncoderH264Class; + 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_h264_reconfigure; + encoder_class->get_default_properties = + gst_vaapi_encoder_h264_get_default_properties; + encoder_class->reordering = gst_vaapi_encoder_h264_reordering; + encoder_class->encode = gst_vaapi_encoder_h264_encode; + encoder_class->flush = gst_vaapi_encoder_h264_flush; + encoder_class->set_property = gst_vaapi_encoder_h264_set_property; + encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data; + encoder_class->get_pending_reordered = + gst_vaapi_encoder_h264_get_pending_reordered; + object_class->finalize = gst_vaapi_encoder_h264_finalize; } /** @@ -3605,7 +3620,7 @@ gst_vaapi_encoder_h264_class (void) GstVaapiEncoder * gst_vaapi_encoder_h264_new (GstVaapiDisplay * display) { - return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display); + return g_object_new (GST_TYPE_VAAPI_ENCODER_H264, "display", display, NULL); } /** @@ -3622,10 +3637,10 @@ gst_vaapi_encoder_h264_new (GstVaapiDisplay * display) GPtrArray * gst_vaapi_encoder_h264_get_default_properties (void) { - const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h264_class (); + const GstVaapiEncoderClassData *class_data = &g_class_data; GPtrArray *props; - props = gst_vaapi_encoder_properties_get_default (klass); + props = gst_vaapi_encoder_properties_get_default (class_data); if (!props) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 095fc6bc2c..188ffe5902 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -29,10 +29,15 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_ENCODER_H264 \ + (gst_vaapi_encoder_h264_get_type ()) #define GST_VAAPI_ENCODER_H264(encoder) \ - ((GstVaapiEncoderH264 *) (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; /** * GstVaapiEncoderH264Prop: @@ -83,6 +88,9 @@ typedef enum { GST_VAAPI_ENCODER_H264_PROP_QUALITY_FACTOR = -19, } GstVaapiEncoderH264Prop; +GType +gst_vaapi_encoder_h264_get_type (void) G_GNUC_CONST; + GstVaapiEncoder * gst_vaapi_encoder_h264_new (GstVaapiDisplay * display); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index f8be64fa3d..201b27d76e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -3306,11 +3306,17 @@ gst_vaapi_encoder_h264_fei_reconfigure (GstVaapiEncoder * base_encoder) return status; } -static gboolean -gst_vaapi_encoder_h264_fei_init (GstVaapiEncoder * base_encoder) +struct _GstVaapiEncoderH264FeiClass +{ + GstVaapiEncoderClass parent_class; +}; + +G_DEFINE_TYPE (GstVaapiEncoderH264Fei, gst_vaapi_encoder_h264_fei, + GST_TYPE_VAAPI_ENCODER); + +static void +gst_vaapi_encoder_h264_fei_init (GstVaapiEncoderH264Fei * encoder) { - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); guint32 i; /* Default encoding entrypoint */ @@ -3351,16 +3357,14 @@ gst_vaapi_encoder_h264_fei_init (GstVaapiEncoder * base_encoder) ref_pool->max_reflist0_count = 1; ref_pool->max_reflist1_count = 1; } - - return TRUE; } static void -gst_vaapi_encoder_h264_fei_finalize (GstVaapiEncoder * base_encoder) +gst_vaapi_encoder_h264_fei_finalize (GObject * gobject) { /*free private buffers */ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + GstVaapiEncoderH264Fei *const encoder = GST_VAAPI_ENCODER_H264_FEI (gobject); + GstVaapiEncoder *base_encoder = GST_VAAPI_ENCODER (gobject); GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); GstVaapiMiniObject *object = GST_VAAPI_MINI_OBJECT (encoder->feipak); GstVaapiEncPicture *pic; @@ -3425,6 +3429,8 @@ gst_vaapi_encoder_h264_fei_finalize (GstVaapiEncoder * base_encoder) encoder->ref_pool_ptr = NULL; encoder->feienc = NULL; } + + G_OBJECT_CLASS (gst_vaapi_encoder_h264_fei_parent_class)->finalize (gobject); } static void @@ -4001,29 +4007,24 @@ static const GstVaapiEncoderClassData fei_encoder_class_data = { .encoder_tune_mask = SUPPORTED_TUNE_OPTIONS, }; -static inline const GstVaapiEncoderClass * -gst_vaapi_encoder_h264_fei_class (void) +static void +gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) { - static const GstVaapiEncoderClass GstVaapiEncoderH264FeiClass = { - .parent_class = { - .size = sizeof (GstVaapiEncoderH264Fei), - .finalize = (GDestroyNotify) gst_vaapi_encoder_finalize, - } - , - .class_data = &fei_encoder_class_data, - .init = gst_vaapi_encoder_h264_fei_init, - .finalize = gst_vaapi_encoder_h264_fei_finalize, - .reconfigure = gst_vaapi_encoder_h264_fei_reconfigure, - .get_default_properties = gst_vaapi_encoder_h264_fei_get_default_properties, - .reordering = gst_vaapi_encoder_h264_fei_reordering, - .encode = gst_vaapi_encoder_h264_fei_encode, - .flush = gst_vaapi_encoder_h264_fei_flush, - .set_property = gst_vaapi_encoder_h264_fei_set_property, - .get_codec_data = gst_vaapi_encoder_h264_fei_get_codec_data, - .ensure_secondary_context = - gst_vaapi_encoder_h264_fei_ensure_secondary_context, - }; - return &GstVaapiEncoderH264FeiClass; + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass); + + encoder_class->class_data = &fei_encoder_class_data; + encoder_class->reconfigure = gst_vaapi_encoder_h264_fei_reconfigure; + encoder_class->get_default_properties = + gst_vaapi_encoder_h264_fei_get_default_properties; + encoder_class->reordering = gst_vaapi_encoder_h264_fei_reordering; + encoder_class->encode = gst_vaapi_encoder_h264_fei_encode; + encoder_class->flush = gst_vaapi_encoder_h264_fei_flush; + encoder_class->set_property = gst_vaapi_encoder_h264_fei_set_property; + encoder_class->get_codec_data = gst_vaapi_encoder_h264_fei_get_codec_data; + encoder_class->ensure_secondary_context = + gst_vaapi_encoder_h264_fei_ensure_secondary_context; + object_class->finalize = gst_vaapi_encoder_h264_fei_finalize; } /** @@ -4040,10 +4041,10 @@ gst_vaapi_encoder_h264_fei_class (void) GPtrArray * gst_vaapi_encoder_h264_fei_get_default_properties (void) { - const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h264_fei_class (); + const GstVaapiEncoderClassData *class_data = &fei_encoder_class_data; GPtrArray *props; - props = gst_vaapi_encoder_properties_get_default (klass); + props = gst_vaapi_encoder_properties_get_default (class_data); if (!props) return NULL; @@ -4336,31 +4337,41 @@ GstVaapiEncoder * gst_vaapi_encoder_h264_fei_new (GstVaapiDisplay * display) { GstVaapiEncoder *base_encoder; - GstVaapiEncoderH264Fei *feiencoder; - GstVaapiFeiEncH264 *feienc; - GstVaapiFEIPakH264 *feipak; + GstVaapiEncoderH264Fei *feiencoder = NULL; + GstVaapiFeiEncH264 *feienc = NULL; + GstVaapiFEIPakH264 *feipak = NULL; /* create FEIEncoderObject: Default mode of operation in ENC_PAK */ base_encoder = - gst_vaapi_encoder_new (gst_vaapi_encoder_h264_fei_class (), display); + g_object_new (GST_TYPE_VAAPI_ENCODER_H264_FEI, "display", display, NULL); if (!base_encoder) return NULL; feiencoder = GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); /* create an enc object */ - feienc = GST_VAAPI_FEI_H264_ENC (gst_vaapi_feienc_h264_new (display)); + feienc = GST_VAAPI_FEI_ENC_H264 (gst_vaapi_feienc_h264_new (display)); if (!feienc) - return NULL; + goto error; /* create a pak object */ feipak = gst_vaapi_feipak_h264_new (base_encoder, display, base_encoder->va_context); if (!feipak) - return NULL; + goto error; feiencoder->feienc = feienc; feiencoder->feipak = feipak; return base_encoder; + +error: + if (feienc) + g_object_unref (feienc); + if (feipak) + gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & feipak, NULL); + if (feiencoder) + g_object_unref (feiencoder); + + return NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h index cd69580be3..3ea86a7150 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h @@ -30,10 +30,15 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_ENCODER_H264_FEI \ + (gst_vaapi_encoder_h264_fei_get_type ()) #define GST_VAAPI_ENCODER_H264_FEI(encoder) \ - ((GstVaapiEncoderH264Fei *) (encoder)) + (G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_ENCODER_H264_FEI, GstVaapiEncoderH264Fei)) +#define GST_IS_VAAPI_ENCODER_H264_FEI(encoder) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_ENCODER_H264_FEI)) typedef struct _GstVaapiEncoderH264Fei GstVaapiEncoderH264Fei; +typedef struct _GstVaapiEncoderH264FeiClass GstVaapiEncoderH264FeiClass; /** * GstVaapiEncoderH264FeiProp: @@ -85,6 +90,9 @@ typedef enum { } GstVaapiEncoderH264FeiProp; +GType +gst_vaapi_encoder_h264_fei_get_type (void) G_GNUC_CONST; + GstVaapiEncoder * gst_vaapi_encoder_h264_fei_new (GstVaapiDisplay * display); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index ad4681090e..73303b09ca 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2594,10 +2594,9 @@ gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) return set_context_info (base_encoder); } -static gboolean -gst_vaapi_encoder_h265_init (GstVaapiEncoder * base_encoder) +static void +gst_vaapi_encoder_h265_init (GstVaapiEncoderH265 * encoder) { - GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); GstVaapiH265ReorderPool *reorder_pool; GstVaapiH265RefPool *ref_pool; @@ -2620,15 +2619,21 @@ gst_vaapi_encoder_h265_init (GstVaapiEncoder * base_encoder) ref_pool->max_ref_frames = 0; ref_pool->max_reflist0_count = 1; ref_pool->max_reflist1_count = 1; - - return TRUE; } +struct _GstVaapiEncoderH265Class +{ + GstVaapiEncoderClass parent_class; +}; + +G_DEFINE_TYPE (GstVaapiEncoderH265, gst_vaapi_encoder_h265, + GST_TYPE_VAAPI_ENCODER); + static void -gst_vaapi_encoder_h265_finalize (GstVaapiEncoder * base_encoder) +gst_vaapi_encoder_h265_finalize (GObject * object) { /*free private buffers */ - GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (object); GstVaapiEncPicture *pic; GstVaapiEncoderH265Ref *ref; GstVaapiH265RefPool *ref_pool; @@ -2654,6 +2659,8 @@ gst_vaapi_encoder_h265_finalize (GstVaapiEncoder * base_encoder) gst_vaapi_enc_picture_unref (pic); } g_queue_clear (&reorder_pool->reorder_frame_list); + + G_OBJECT_CLASS (gst_vaapi_encoder_h265_parent_class)->finalize (object); } static GstVaapiEncoderStatus @@ -2705,16 +2712,24 @@ gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H265); -static inline const GstVaapiEncoderClass * -gst_vaapi_encoder_h265_class (void) +static void +gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) { - static const GstVaapiEncoderClass GstVaapiEncoderH265Class = { - GST_VAAPI_ENCODER_CLASS_INIT (H265, h265), - .set_property = gst_vaapi_encoder_h265_set_property, - .get_codec_data = gst_vaapi_encoder_h265_get_codec_data, - .get_pending_reordered = gst_vaapi_encoder_h265_get_pending_reordered, - }; - return &GstVaapiEncoderH265Class; + 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_h265_reconfigure; + encoder_class->get_default_properties = + gst_vaapi_encoder_h265_get_default_properties; + encoder_class->reordering = gst_vaapi_encoder_h265_reordering; + encoder_class->encode = gst_vaapi_encoder_h265_encode; + encoder_class->flush = gst_vaapi_encoder_h265_flush; + encoder_class->set_property = gst_vaapi_encoder_h265_set_property; + encoder_class->get_codec_data = gst_vaapi_encoder_h265_get_codec_data; + encoder_class->get_pending_reordered = + gst_vaapi_encoder_h265_get_pending_reordered; + object_class->finalize = gst_vaapi_encoder_h265_finalize; } /** @@ -2729,7 +2744,7 @@ gst_vaapi_encoder_h265_class (void) GstVaapiEncoder * gst_vaapi_encoder_h265_new (GstVaapiDisplay * display) { - return gst_vaapi_encoder_new (gst_vaapi_encoder_h265_class (), display); + return g_object_new (GST_TYPE_VAAPI_ENCODER_H265, "display", display, NULL); } /** @@ -2746,10 +2761,10 @@ gst_vaapi_encoder_h265_new (GstVaapiDisplay * display) GPtrArray * gst_vaapi_encoder_h265_get_default_properties (void) { - const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h265_class (); + const GstVaapiEncoderClassData *class_data = &g_class_data; GPtrArray *props; - props = gst_vaapi_encoder_properties_get_default (klass); + props = gst_vaapi_encoder_properties_get_default (class_data); if (!props) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index 9004e90eb6..e78c2b3fab 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -28,10 +28,15 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_ENCODER_H265 \ + (gst_vaapi_encoder_h265_get_type ()) #define GST_VAAPI_ENCODER_H265(encoder) \ - ((GstVaapiEncoderH265 *) (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; /** * GstVaapiEncoderH265Prop: @@ -65,6 +70,9 @@ typedef enum { GST_VAAPI_ENCODER_H265_PROP_MAX_QP = -12, } GstVaapiEncoderH265Prop; +GType +gst_vaapi_encoder_h265_get_type (void) G_GNUC_CONST; + GstVaapiEncoder * gst_vaapi_encoder_h265_new (GstVaapiDisplay * display); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index a3157d4ef1..44fee30a93 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -743,24 +743,23 @@ gst_vaapi_encoder_jpeg_reconfigure (GstVaapiEncoder * base_encoder) return set_context_info (base_encoder); } -static gboolean -gst_vaapi_encoder_jpeg_init (GstVaapiEncoder * base_encoder) +struct _GstVaapiEncoderJpegClass { - GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (base_encoder); + 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)); - - return TRUE; -} - -static void -gst_vaapi_encoder_jpeg_finalize (GstVaapiEncoder * base_encoder) -{ } static GstVaapiEncoderStatus @@ -781,14 +780,19 @@ gst_vaapi_encoder_jpeg_set_property (GstVaapiEncoder * base_encoder, GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (JPEG); -static inline const GstVaapiEncoderClass * -gst_vaapi_encoder_jpeg_class (void) +static void +gst_vaapi_encoder_jpeg_class_init (GstVaapiEncoderJpegClass * klass) { - static const GstVaapiEncoderClass GstVaapiEncoderJpegClass = { - GST_VAAPI_ENCODER_CLASS_INIT (Jpeg, jpeg), - .set_property = gst_vaapi_encoder_jpeg_set_property, - }; - return &GstVaapiEncoderJpegClass; + 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->get_default_properties = + gst_vaapi_encoder_jpeg_get_default_properties; + encoder_class->reordering = gst_vaapi_encoder_jpeg_reordering; + encoder_class->encode = gst_vaapi_encoder_jpeg_encode; + encoder_class->flush = gst_vaapi_encoder_jpeg_flush; + encoder_class->set_property = gst_vaapi_encoder_jpeg_set_property; } /** @@ -802,7 +806,7 @@ gst_vaapi_encoder_jpeg_class (void) GstVaapiEncoder * gst_vaapi_encoder_jpeg_new (GstVaapiDisplay * display) { - return gst_vaapi_encoder_new (gst_vaapi_encoder_jpeg_class (), display); + return g_object_new (GST_TYPE_VAAPI_ENCODER_JPEG, "display", display, NULL); } /** @@ -819,10 +823,10 @@ gst_vaapi_encoder_jpeg_new (GstVaapiDisplay * display) GPtrArray * gst_vaapi_encoder_jpeg_get_default_properties (void) { - const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_jpeg_class (); + const GstVaapiEncoderClassData *class_data = &g_class_data; GPtrArray *props; - props = gst_vaapi_encoder_properties_get_default (klass); + props = gst_vaapi_encoder_properties_get_default (class_data); if (!props) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h index a18c7e2796..674d2dae55 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h @@ -27,10 +27,15 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_ENCODER_JPEG \ + (gst_vaapi_encoder_jpeg_get_type ()) #define GST_VAAPI_ENCODER_JPEG(encoder) \ - ((GstVaapiEncoderJpeg *) (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; /** * GstVaapiEncoderJpegProp: @@ -42,6 +47,9 @@ typedef enum { GST_VAAPI_ENCODER_JPEG_PROP_QUALITY = -1 } GstVaapiEncoderJpegProp; +GType +gst_vaapi_encoder_jpeg_get_type (void) G_GNUC_CONST; + GstVaapiEncoder * gst_vaapi_encoder_jpeg_new (GstVaapiDisplay * display); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 92a021fa6b..2389083afb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -719,16 +719,19 @@ error: } } -static gboolean -gst_vaapi_encoder_mpeg2_init (GstVaapiEncoder * base_encoder) +struct _GstVaapiEncoderMpeg2Class { - GstVaapiEncoderMpeg2 *const encoder = - GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); + GstVaapiEncoderClass parent_class; +}; +G_DEFINE_TYPE (GstVaapiEncoderMpeg2, gst_vaapi_encoder_mpeg2, + GST_TYPE_VAAPI_ENCODER); + +static void +gst_vaapi_encoder_mpeg2_init (GstVaapiEncoderMpeg2 * encoder) +{ /* re-ordering */ g_queue_init (&encoder->b_frames); - - return TRUE; } static void @@ -762,11 +765,10 @@ push_reference (GstVaapiEncoderMpeg2 * encoder, GstVaapiSurfaceProxy * ref) } static void -gst_vaapi_encoder_mpeg2_finalize (GstVaapiEncoder * base_encoder) +gst_vaapi_encoder_mpeg2_finalize (GObject * object) { /* free private buffers */ - GstVaapiEncoderMpeg2 *const encoder = - GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); + GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2 (object); GstVaapiEncPicture *pic; clear_references (encoder); @@ -776,6 +778,8 @@ gst_vaapi_encoder_mpeg2_finalize (GstVaapiEncoder * base_encoder) gst_vaapi_enc_picture_unref (pic); } g_queue_clear (&encoder->b_frames); + + G_OBJECT_CLASS (gst_vaapi_encoder_mpeg2_parent_class)->finalize (object); } static GstVaapiEncoderStatus @@ -800,14 +804,21 @@ gst_vaapi_encoder_mpeg2_set_property (GstVaapiEncoder * base_encoder, GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (MPEG2); -static inline const GstVaapiEncoderClass * -gst_vaapi_encoder_mpeg2_class (void) +static void +gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass) { - static const GstVaapiEncoderClass GstVaapiEncoderMpeg2Class = { - GST_VAAPI_ENCODER_CLASS_INIT (Mpeg2, mpeg2), - .set_property = gst_vaapi_encoder_mpeg2_set_property, - }; - return &GstVaapiEncoderMpeg2Class; + 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_mpeg2_reconfigure; + encoder_class->get_default_properties = + gst_vaapi_encoder_mpeg2_get_default_properties; + encoder_class->reordering = gst_vaapi_encoder_mpeg2_reordering; + encoder_class->encode = gst_vaapi_encoder_mpeg2_encode; + encoder_class->flush = gst_vaapi_encoder_mpeg2_flush; + encoder_class->set_property = gst_vaapi_encoder_mpeg2_set_property; + object_class->finalize = gst_vaapi_encoder_mpeg2_finalize; } /** @@ -821,7 +832,7 @@ gst_vaapi_encoder_mpeg2_class (void) GstVaapiEncoder * gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display) { - return gst_vaapi_encoder_new (gst_vaapi_encoder_mpeg2_class (), display); + return g_object_new (GST_TYPE_VAAPI_ENCODER_MPEG2, "display", display, NULL); } /** @@ -838,10 +849,10 @@ gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display) GPtrArray * gst_vaapi_encoder_mpeg2_get_default_properties (void) { - const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_mpeg2_class (); + const GstVaapiEncoderClassData *class_data = &g_class_data; GPtrArray *props; - props = gst_vaapi_encoder_properties_get_default (klass); + props = gst_vaapi_encoder_properties_get_default (class_data); if (!props) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h index 923ad1d85a..af61698e5a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -28,10 +28,15 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_ENCODER_MPEG2 \ + (gst_vaapi_encoder_mpeg2_get_type ()) #define GST_VAAPI_ENCODER_MPEG2(encoder) \ - ((GstVaapiEncoderMpeg2 *) (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; /** * GstVaapiEncoderMpeg2Prop: @@ -46,6 +51,9 @@ typedef enum { GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES = -2, } GstVaapiEncoderMpeg2Prop; +GType +gst_vaapi_encoder_mpeg2_get_type (void) G_GNUC_CONST; + GstVaapiEncoder * gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 4dd340cab6..170cedeb3e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -37,10 +37,10 @@ G_BEGIN_DECLS ((GstVaapiEncoder *)(encoder)) #define GST_VAAPI_ENCODER_CLASS(klass) \ - ((GstVaapiEncoderClass *)(klass)) + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_ENCODER, GstVaapiEncoderClass)) #define GST_VAAPI_ENCODER_GET_CLASS(obj) \ - GST_VAAPI_ENCODER_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_ENCODER, GstVaapiEncoderClass)) /** * GST_VAAPI_ENCODER_PACKED_HEADERS: @@ -240,12 +240,12 @@ gst_vaapi_encoder_properties_append (GPtrArray * props, gint prop_id, G_GNUC_INTERNAL GPtrArray * -gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass); +gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClassData *cdata); struct _GstVaapiEncoder { /*< private >*/ - GstVaapiMiniObject parent_instance; + GstObject parent_instance; GPtrArray *properties; GstVaapiDisplay *display; @@ -337,13 +337,10 @@ struct _GstVaapiEncoderClassData struct _GstVaapiEncoderClass { /*< private >*/ - GstVaapiMiniObjectClass parent_class; + GstObjectClass parent_class; const GstVaapiEncoderClassData *class_data; - gboolean (*init) (GstVaapiEncoder * encoder); - void (*finalize) (GstVaapiEncoder * encoder); - GstVaapiEncoderStatus (*reconfigure) (GstVaapiEncoder * encoder); GPtrArray * (*get_default_properties) (void); @@ -399,10 +396,6 @@ GstVaapiEncoder * gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass, GstVaapiDisplay * display); -G_GNUC_INTERNAL -void -gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder); - G_GNUC_INTERNAL GstVaapiSurfaceProxy * gst_vaapi_encoder_create_surface (GstVaapiEncoder * diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 3c14cdee8d..eb4c7ad1e2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -510,24 +510,29 @@ error: } } -static gboolean -gst_vaapi_encoder_vp8_init (GstVaapiEncoder * base_encoder) +struct _GstVaapiEncoderVP8Class { - GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder); + 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; - - return TRUE; } static void -gst_vaapi_encoder_vp8_finalize (GstVaapiEncoder * base_encoder) +gst_vaapi_encoder_vp8_finalize (GObject * object) { - GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder); + GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (object); clear_references (encoder); + G_OBJECT_CLASS (gst_vaapi_encoder_vp8_parent_class)->finalize (object); } static GstVaapiEncoderStatus @@ -554,14 +559,21 @@ gst_vaapi_encoder_vp8_set_property (GstVaapiEncoder * base_encoder, GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (VP8); -static inline const GstVaapiEncoderClass * -gst_vaapi_encoder_vp8_class (void) +static void +gst_vaapi_encoder_vp8_class_init (GstVaapiEncoderVP8Class * klass) { - static const GstVaapiEncoderClass GstVaapiEncoderVP8Class = { - GST_VAAPI_ENCODER_CLASS_INIT (VP8, vp8), - .set_property = gst_vaapi_encoder_vp8_set_property, - }; - return &GstVaapiEncoderVP8Class; + 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->get_default_properties = + gst_vaapi_encoder_vp8_get_default_properties; + encoder_class->reordering = gst_vaapi_encoder_vp8_reordering; + encoder_class->encode = gst_vaapi_encoder_vp8_encode; + encoder_class->flush = gst_vaapi_encoder_vp8_flush; + encoder_class->set_property = gst_vaapi_encoder_vp8_set_property; + object_class->finalize = gst_vaapi_encoder_vp8_finalize; } /** @@ -575,7 +587,7 @@ gst_vaapi_encoder_vp8_class (void) GstVaapiEncoder * gst_vaapi_encoder_vp8_new (GstVaapiDisplay * display) { - return gst_vaapi_encoder_new (gst_vaapi_encoder_vp8_class (), display); + return g_object_new (GST_TYPE_VAAPI_ENCODER_VP8, "display", display, NULL); } /** @@ -592,10 +604,10 @@ gst_vaapi_encoder_vp8_new (GstVaapiDisplay * display) GPtrArray * gst_vaapi_encoder_vp8_get_default_properties (void) { - const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_vp8_class (); + const GstVaapiEncoderClassData *class_data = &g_class_data; GPtrArray *props; - props = gst_vaapi_encoder_properties_get_default (klass); + props = gst_vaapi_encoder_properties_get_default (class_data); if (!props) return NULL; @@ -619,7 +631,9 @@ gst_vaapi_encoder_vp8_get_default_properties (void) GST_VAAPI_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)", + "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)); return props; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h index a48bf460c4..5fa77d862a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h @@ -27,10 +27,15 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_ENCODER_VP8 \ + (gst_vaapi_encoder_vp8_get_type ()) #define GST_VAAPI_ENCODER_VP8(encoder) \ - ((GstVaapiEncoderVP8 *) (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; /** * GstVaapiEncoderVP8Prop: @@ -46,6 +51,9 @@ typedef enum { GST_VAAPI_ENCODER_VP8_PROP_YAC_Q_INDEX = -3 } GstVaapiEncoderVP8Prop; +GType +gst_vaapi_encoder_vp8_get_type (void) G_GNUC_CONST; + GstVaapiEncoder * gst_vaapi_encoder_vp8_new (GstVaapiDisplay * display); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 6d37334c42..d167d11949 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -532,11 +532,18 @@ gst_vaapi_encoder_vp9_reconfigure (GstVaapiEncoder * base_encoder) return set_context_info (base_encoder); } -static gboolean -gst_vaapi_encoder_vp9_init (GstVaapiEncoder * base_encoder) -{ - GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (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; @@ -547,13 +554,6 @@ gst_vaapi_encoder_vp9_init (GstVaapiEncoder * base_encoder) memset (encoder->ref_list, 0, G_N_ELEMENTS (encoder->ref_list) * sizeof (encoder->ref_list[0])); encoder->ref_list_idx = 0; - - return TRUE; -} - -static void -gst_vaapi_encoder_vp9_finalize (GstVaapiEncoder * base_encoder) -{ } static GstVaapiEncoderStatus @@ -586,14 +586,19 @@ gst_vaapi_encoder_vp9_set_property (GstVaapiEncoder * base_encoder, GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (VP9); -static inline const GstVaapiEncoderClass * -gst_vaapi_encoder_vp9_class (void) +static void +gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) { - static const GstVaapiEncoderClass GstVaapiEncoderVP9Class = { - GST_VAAPI_ENCODER_CLASS_INIT (VP9, vp9), - .set_property = gst_vaapi_encoder_vp9_set_property, - }; - return &GstVaapiEncoderVP9Class; + 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->get_default_properties = + gst_vaapi_encoder_vp9_get_default_properties; + encoder_class->reordering = gst_vaapi_encoder_vp9_reordering; + encoder_class->encode = gst_vaapi_encoder_vp9_encode; + encoder_class->flush = gst_vaapi_encoder_vp9_flush; + encoder_class->set_property = gst_vaapi_encoder_vp9_set_property; } /** @@ -607,7 +612,7 @@ gst_vaapi_encoder_vp9_class (void) GstVaapiEncoder * gst_vaapi_encoder_vp9_new (GstVaapiDisplay * display) { - return gst_vaapi_encoder_new (gst_vaapi_encoder_vp9_class (), display); + return g_object_new (GST_TYPE_VAAPI_ENCODER_VP9, "display", display, NULL); } /** @@ -624,10 +629,10 @@ gst_vaapi_encoder_vp9_new (GstVaapiDisplay * display) GPtrArray * gst_vaapi_encoder_vp9_get_default_properties (void) { - const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_vp9_class (); + const GstVaapiEncoderClassData *class_data = &g_class_data; GPtrArray *props; - props = gst_vaapi_encoder_properties_get_default (klass); + props = gst_vaapi_encoder_properties_get_default (class_data); if (!props) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h index 7967a98002..ff690fe2db 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -27,10 +27,15 @@ G_BEGIN_DECLS +#define GST_TYPE_VAAPI_ENCODER_VP9 \ + (gst_vaapi_encoder_vp9_get_type ()) #define GST_VAAPI_ENCODER_VP9(encoder) \ - ((GstVaapiEncoderVP9 *) (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; /** * GstVaapiEncoderVP9Prop: @@ -50,6 +55,9 @@ typedef enum { GST_VAAPI_ENCODER_VP9_PROP_CPB_LENGTH = -5 } GstVaapiEncoderVP9Prop; +GType +gst_vaapi_encoder_vp9_get_type (void) G_GNUC_CONST; + GstVaapiEncoder * gst_vaapi_encoder_vp9_new (GstVaapiDisplay * display); diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index df88215331..c26ad46f96 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -184,7 +184,7 @@ h264_get_cpb_nal_factor (GstVaapiProfile profile) /* --- FEI Enc --- */ /* ------------------------------------------------------------------------- */ -#define GST_VAAPI_FEI_H264_ENC_CAST(feienc) \ +#define GST_VAAPI_FEI_ENC_H264_CAST(feienc) \ ((GstVaapiFeiEncH264 *)(feienc)) struct _GstVaapiFeiEncH264 @@ -1380,7 +1380,7 @@ gst_vaapi_feienc_h264_encode (GstVaapiEncoder * base_encoder, GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiFeiInfoToPakH264 * info_to_pak) { - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; if (!reconstruct || !codedbuf_proxy) @@ -1410,7 +1410,7 @@ error: GstVaapiEncoderStatus gst_vaapi_feienc_h264_flush (GstVaapiEncoder * base_encoder) { - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); GstVaapiH264ViewReorderPool *reorder_pool; GstVaapiEncPicture *pic; guint i; @@ -1444,7 +1444,7 @@ GstVaapiEncoderStatus gst_vaapi_feienc_h264_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) { - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); GstVaapiH264ViewReorderPool *reorder_pool = NULL; GstVaapiEncPicture *picture; gboolean is_idr = FALSE; @@ -1554,7 +1554,7 @@ end: static GstVaapiEncoderStatus set_context_info (GstVaapiEncoder * base_encoder) { - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (feienc); const guint DEFAULT_SURFACES_COUNT = 3; @@ -1601,7 +1601,7 @@ set_context_info (GstVaapiEncoder * base_encoder) GstVaapiEncoderStatus gst_vaapi_feienc_h264_reconfigure (GstVaapiEncoder * base_encoder) { - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (feienc); GstVaapiEncoderStatus status; guint mb_width, mb_height; @@ -1637,10 +1637,17 @@ gst_vaapi_feienc_h264_reconfigure (GstVaapiEncoder * base_encoder) return GST_VAAPI_ENCODER_STATUS_SUCCESS; } -static gboolean -gst_vaapi_feienc_h264_init (GstVaapiEncoder * base_encoder) +struct _GstVaapiFeiEncH264Class +{ + GstVaapiEncoderClass parent_class; +}; + +G_DEFINE_TYPE (GstVaapiFeiEncH264, gst_vaapi_feienc_h264, + GST_TYPE_VAAPI_ENCODER); + +static void +gst_vaapi_feienc_h264_init (GstVaapiFeiEncH264 * feienc) { - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); guint32 i; /* Default encoding entrypoint */ @@ -1672,15 +1679,13 @@ gst_vaapi_feienc_h264_init (GstVaapiEncoder * base_encoder) reorder_pool->cur_frame_num = 0; reorder_pool->cur_present_index = 0; } - - return TRUE; } static void -gst_vaapi_feienc_h264_finalize (GstVaapiEncoder * base_encoder) +gst_vaapi_feienc_h264_finalize (GObject * object) { /*free private buffers */ - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264 (object); GstVaapiEncPicture *pic; guint32 i; @@ -1698,6 +1703,8 @@ gst_vaapi_feienc_h264_finalize (GstVaapiEncoder * base_encoder) } g_queue_clear (&reorder_pool->reorder_frame_list); } + + G_OBJECT_CLASS (gst_vaapi_feienc_h264_parent_class)->finalize (object); } static void @@ -1744,7 +1751,7 @@ GstVaapiEncoderStatus gst_vaapi_feienc_h264_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_H264_ENC_CAST (base_encoder); + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); switch (prop_id) { case GST_VAAPI_FEI_H264_ENC_PROP_MAX_BFRAMES: @@ -1839,27 +1846,22 @@ static const GstVaapiEncoderClassData fei_enc_class_data = { .encoder_tune_mask = SUPPORTED_TUNE_OPTIONS, }; -static inline const GstVaapiEncoderClass * -gst_vaapi_feienc_h264_class (void) +static void +gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) { - static const GstVaapiEncoderClass GstVaapiFeiEncH264Class = { - .parent_class = { - .size = sizeof (GstVaapiFeiEncH264), - .finalize = (GDestroyNotify) gst_vaapi_encoder_finalize, - } - , - .class_data = &fei_enc_class_data, - .init = gst_vaapi_feienc_h264_init, - .finalize = gst_vaapi_feienc_h264_finalize, - .reconfigure = gst_vaapi_feienc_h264_reconfigure, - .get_default_properties = gst_vaapi_feienc_h264_get_default_properties, - .reordering = gst_vaapi_feienc_h264_reordering, - .encode = gst_vaapi_feienc_h264_fake_encode, - .flush = gst_vaapi_feienc_h264_flush, - .set_property = gst_vaapi_feienc_h264_set_property, - .get_codec_data = gst_vaapi_feienc_h264_get_codec_data, - }; - return &GstVaapiFeiEncH264Class; + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass); + + encoder_class->class_data = &fei_enc_class_data; + encoder_class->reconfigure = gst_vaapi_feienc_h264_reconfigure; + encoder_class->get_default_properties = + gst_vaapi_feienc_h264_get_default_properties; + encoder_class->reordering = gst_vaapi_feienc_h264_reordering; + encoder_class->encode = gst_vaapi_feienc_h264_fake_encode; + encoder_class->flush = gst_vaapi_feienc_h264_flush; + encoder_class->set_property = gst_vaapi_feienc_h264_set_property; + encoder_class->get_codec_data = gst_vaapi_feienc_h264_get_codec_data; + object_class->finalize = gst_vaapi_feienc_h264_finalize; } /** @@ -1874,7 +1876,7 @@ gst_vaapi_feienc_h264_class (void) GstVaapiEncoder * gst_vaapi_feienc_h264_new (GstVaapiDisplay * display) { - return gst_vaapi_encoder_new (gst_vaapi_feienc_h264_class (), display); + return g_object_new (GST_TYPE_VAAPI_FEI_ENC_H264, "display", display, NULL); } /** @@ -2071,10 +2073,10 @@ gst_vaapi_feienc_h264_get_fei_properties (GPtrArray * props) GPtrArray * gst_vaapi_feienc_h264_get_default_properties (void) { - const GstVaapiEncoderClass *const klass = gst_vaapi_feienc_h264_class (); + const GstVaapiEncoderClassData *class_data = &fei_enc_class_data; GPtrArray *props; - props = gst_vaapi_encoder_properties_get_default (klass); + props = gst_vaapi_encoder_properties_get_default (class_data); if (!props) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.h b/gst-libs/gst/vaapi/gstvaapifeienc_h264.h index 03766e0df1..ae681d026f 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.h +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.h @@ -29,9 +29,16 @@ #include #include G_BEGIN_DECLS -#define GST_VAAPI_FEI_H264_ENC(feienc) \ - ((GstVaapiFeiEncH264 *) (feienc)) + +#define GST_TYPE_VAAPI_FEI_ENC_H264 \ + (gst_vaapi_feienc_h264_get_type ()) +#define GST_VAAPI_FEI_ENC_H264(encoder) \ + (G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_FEI_ENC_H264, GstVaapiFeiEncH264)) +#define GST_IS_VAAPI_FEI_ENC_H264(encoder) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_FEI_ENC_H264)) + typedef struct _GstVaapiFeiEncH264 GstVaapiFeiEncH264; +typedef struct _GstVaapiFeiEncH264Class GstVaapiFeiEncH264Class; /** * GstVaapiFeiEncH264Prop: @@ -81,6 +88,9 @@ typedef enum GST_VAAPI_FEI_H264_ENC_PROP_ENABLE_STATS_OUT = -27, } GstVaapiFeiEncH264Prop; +GType +gst_vaapi_feienc_h264_get_type (void) G_GNUC_CONST; + GstVaapiEncoder * gst_vaapi_feienc_h264_new (GstVaapiDisplay * display); From 6978eae21a728e1eac9ece5cb7d90e1209279683 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 14:38:49 +0800 Subject: [PATCH 3334/3781] libs: encoder: delete useless gst_vaapi_encoder_new func. GstVaapiEncoder is a abstract gobject and never be created directly. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 8 -------- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 5 ----- 2 files changed, 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 7451a241bb..4c559de9ac 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1621,14 +1621,6 @@ gst_vaapi_encoder_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapi_encoder_parent_class)->finalize (object); } -/* Helper function to create new GstVaapiEncoder instances (internal) */ -GstVaapiEncoder * -gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass, - GstVaapiDisplay * display) -{ - return NULL; -} - static void encoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 170cedeb3e..c2ac51091e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -391,11 +391,6 @@ struct _GstVaapiEncoderClass GST_VAAPI_ENCODER_CLASS_HOOK (codec, encode), \ GST_VAAPI_ENCODER_CLASS_HOOK (codec, flush) -G_GNUC_INTERNAL -GstVaapiEncoder * -gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass, - GstVaapiDisplay * display); - G_GNUC_INTERNAL GstVaapiSurfaceProxy * gst_vaapi_encoder_create_surface (GstVaapiEncoder * From beaf45cc6faf577ba8e4e48febea0c9bcd062561 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 19 Aug 2019 15:38:09 +0800 Subject: [PATCH 3335/3781] libs: encoder: add properties and prop help functions Add all common properties to encoder base class. rate-control and tune are moved to sub class. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 197 ++++++++++++++++++++++++++- 1 file changed, 194 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 4c559de9ac..9a881560c6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1573,12 +1573,121 @@ gst_vaapi_encoder_constructed (GObject * object) G_DEFINE_ABSTRACT_TYPE (GstVaapiEncoder, gst_vaapi_encoder, GST_TYPE_OBJECT); +/** + * GstVaapiEncoderProp: + * @ENCODER_PROP_DISPLAY: The display. + * @ENCODER_PROP_BITRATE: Bitrate expressed in kbps (uint). + * @ENCODER_PROP_TARGET_PERCENTAGE: Desired target percentage of + * bitrate for variable rate controls. + * @ENCODER_PROP_KEYFRAME_PERIOD: The maximal distance + * between two keyframes (uint). + * @ENCODER_PROP_DEFAULT_ROI_VALUE: The default delta qp to apply + * to each region of interest. + * @ENCODER_PROP_TRELLIS: Use trellis quantization method (gboolean). + * + * The set of configurable properties for the encoder. + */ enum { ENCODER_PROP_DISPLAY = 1, + ENCODER_PROP_BITRATE, + ENCODER_PROP_TARGET_PERCENTAGE, + ENCODER_PROP_KEYFRAME_PERIOD, + ENCODER_PROP_QUALITY_LEVEL, + ENCODER_PROP_DEFAULT_ROI_VALUE, + ENCODER_PROP_TRELLIS, ENCODER_N_PROPERTIES }; +static GParamSpec *properties[ENCODER_N_PROPERTIES]; + +__attribute__ ((unused)) + static void + _gst_vaapi_encoder_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); + GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS; + + switch (prop_id) { + case ENCODER_PROP_DISPLAY: + g_assert (encoder->display == NULL); + encoder->display = g_value_dup_object (value); + g_assert (encoder->display != NULL); + encoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY (encoder->display); + break; + case ENCODER_PROP_BITRATE: + status = gst_vaapi_encoder_set_bitrate (encoder, + g_value_get_uint (value)); + break; + case ENCODER_PROP_TARGET_PERCENTAGE: + status = + gst_vaapi_encoder_set_target_percentage (encoder, + g_value_get_uint (value)); + break; + case ENCODER_PROP_KEYFRAME_PERIOD: + status = + gst_vaapi_encoder_set_keyframe_period (encoder, + g_value_get_uint (value)); + break; + case ENCODER_PROP_QUALITY_LEVEL: + status = + gst_vaapi_encoder_set_quality_level (encoder, + g_value_get_uint (value)); + break; + case ENCODER_PROP_DEFAULT_ROI_VALUE: + encoder->default_roi_value = g_value_get_int (value); + status = GST_VAAPI_ENCODER_STATUS_SUCCESS; + break; + case ENCODER_PROP_TRELLIS: + status = + gst_vaapi_encoder_set_trellis (encoder, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + + if (status) + GST_WARNING_OBJECT (encoder, "Failed to set the property:%s, error is %d", + g_param_spec_get_name (pspec), status); +} + +__attribute__ ((unused)) + static void + _gst_vaapi_encoder_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); + + switch (prop_id) { + case ENCODER_PROP_DISPLAY: + g_value_set_object (value, encoder->display); + break; + case ENCODER_PROP_BITRATE: + g_value_set_uint (value, encoder->bitrate); + break; + case ENCODER_PROP_TARGET_PERCENTAGE: + g_value_set_uint (value, encoder->target_percentage); + break; + case ENCODER_PROP_KEYFRAME_PERIOD: + g_value_set_uint (value, encoder->keyframe_period); + break; + case ENCODER_PROP_QUALITY_LEVEL: + g_value_set_uint (value, GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder)); + break; + case ENCODER_PROP_DEFAULT_ROI_VALUE: + g_value_set_int (value, encoder->default_roi_value); + break; + case ENCODER_PROP_TRELLIS: + g_value_set_boolean (value, encoder->trellis); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void gst_vaapi_encoder_init (GstVaapiEncoder * encoder) { @@ -1671,10 +1780,92 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) * * #GstVaapiDisplay to be used. */ - g_object_class_install_property (object_class, ENCODER_PROP_DISPLAY, + properties[ENCODER_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)); + "The VA-API display object to use", GST_TYPE_VAAPI_DISPLAY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME); + + /** + * GstVaapiEncoder:bitrate: + * + * The desired bitrate, expressed in kbps. + * This is available when rate-control is CBR or VBR. + * + * CBR: This applies equally to minimum, maximum and target bitrate in the driver. + * VBR: This applies to maximum bitrate in the driver. + * Minimum bitrate will be calculated like the following in the driver. + * if (target percentage < 50) minimum bitrate = 0 + * else minimum bitrate = maximum bitrate * (2 * target percentage -100) / 100 + * Target bitrate will be calculated like the following in the driver. + * target bitrate = maximum bitrate * target percentage / 100 + */ + properties[ENCODER_PROP_BITRATE] = + g_param_spec_uint ("bitrate", + "Bitrate (kbps)", + "The desired bitrate expressed in kbps (0: auto-calculate)", + 0, 2000 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoder:target-percentage: + * + * The desired target percentage of bitrate for variable rate controls. + */ + properties[ENCODER_PROP_TARGET_PERCENTAGE] = + g_param_spec_uint ("target-percentage", + "Target Percentage", + "The desired target percentage of bitrate for variable rate " + "controls.", 1, 100, 70, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoder:keyframe-period: + * + * The maximal distance between two keyframes. + */ + properties[ENCODER_PROP_KEYFRAME_PERIOD] = + g_param_spec_uint ("keyframe-period", + "Keyframe Period", + "Maximal distance between two keyframes (0: auto-calculate)", 0, + G_MAXUINT32, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoder:quality-level: + * + * The Encoding quality level. + */ + properties[ENCODER_PROP_QUALITY_LEVEL] = + g_param_spec_uint ("quality-level", + "Quality Level", "Encoding Quality Level " + "(lower value means higher-quality/slow-encode, " + " higher value means lower-quality/fast-encode)", + 1, 7, 4, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVapiEncoder:roi-default-delta-qp + * + * Default delta-qp to apply to each Region of Interest + */ + properties[ENCODER_PROP_DEFAULT_ROI_VALUE] = + g_param_spec_int ("default-roi-delta-qp", "Default ROI delta QP", + "The default delta-qp to apply to each Region of Interest" + "(lower value means higher-quality, " + "higher value means lower-quality)", + -10, 10, -10, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoder: trellis: + * + * The trellis quantization method the encoder can use. + * Trellis is an improved quantization algorithm. + * + */ + properties[ENCODER_PROP_TRELLIS] = + g_param_spec_boolean ("trellis", + "Trellis Quantization", + "The Trellis Quantization Method of Encoder", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, ENCODER_N_PROPERTIES, + properties); } static GstVaapiContext * From 3468edc20b0960dea72fad843b7f9a764d80a3fe Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 20 Aug 2019 01:33:40 +0800 Subject: [PATCH 3336/3781] libs: encoder: Add properties for h264 encoder. Install properties for h264 encoder class. Also set the new get/set property functions for gobject class. Still use the old properties way now and this new feature will be enabled later. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 473 +++++++++++++++++++++- 1 file changed, 471 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 490b0a11f7..dd6a3a01a5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3515,8 +3515,64 @@ set_default_ids: } } +/** + * @ENCODER_H264_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). + * @ENCODER_H264_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). + * @ENCODER_H264_PROP_MAX_BFRAMES: Number of B-frames between I + * and P (uint). + * @ENCODER_H264_PROP_INIT_QP: Initial quantizer value (uint). + * @ENCODER_H264_PROP_MIN_QP: Minimal quantizer value (uint). + * @ENCODER_H264_PROP_NUM_SLICES: Number of slices per frame (uint). + * @ENCODER_H264_PROP_CABAC: Enable CABAC entropy coding mode (bool). + * @ENCODER_H264_PROP_DCT8X8: Enable adaptive use of 8x8 + * transforms in I-frames (bool). + * @ENCODER_H264_PROP_CPB_LENGTH: Length of the CPB buffer + * in milliseconds (uint). + * @ENCODER_H264_PROP_NUM_VIEWS: Number of views per frame. + * @ENCODER_H264_PROP_VIEW_IDS: View IDs + * @ENCODER_H264_PROP_AUD: Insert AUD as first NAL per frame. + * @ENCODER_H264_PROP_COMPLIANCE_MODE: Relax Compliance restrictions + * @ENCODER_H264_PROP_NUM_REF_FRAMES: Maximum number of reference frames. + * @ENCODER_H264_PROP_MBBRC: Macroblock level Bitrate Control. + * @ENCODER_H264_PROP_QP_IP: Difference of QP between I and P frame. + * @ENCODER_H264_PROP_QP_IB: Difference of QP between I and B frame. + * @ENCODER_H264_PROP_TEMPORAL_LEVELS: Number of temporal levels + * @ENCODER_H264_PROP_PREDICTION_TYPE: Reference picture selection modes + * @ENCODER_H264_PROP_MAX_QP: Maximal quantizer value (uint). + * @ENCODER_H264_PROP_QUALITY_FACTOR: Factor for ICQ/QVBR bitrate control mode. + * + * The set of H.264 encoder specific configurable properties. + */ +enum +{ + ENCODER_H264_PROP_RATECONTROL = 1, + ENCODER_H264_PROP_TUNE, + ENCODER_H264_PROP_MAX_BFRAMES, + ENCODER_H264_PROP_INIT_QP, + ENCODER_H264_PROP_MIN_QP, + ENCODER_H264_PROP_NUM_SLICES, + ENCODER_H264_PROP_CABAC, + ENCODER_H264_PROP_DCT8X8, + ENCODER_H264_PROP_CPB_LENGTH, + ENCODER_H264_PROP_NUM_VIEWS, + ENCODER_H264_PROP_VIEW_IDS, + ENCODER_H264_PROP_AUD, + ENCODER_H264_PROP_COMPLIANCE_MODE, + ENCODER_H264_PROP_NUM_REF_FRAMES, + ENCODER_H264_PROP_MBBRC, + ENCODER_H264_PROP_QP_IP, + ENCODER_H264_PROP_QP_IB, + ENCODER_H264_PROP_TEMPORAL_LEVELS, + ENCODER_H264_PROP_PREDICTION_TYPE, + ENCODER_H264_PROP_MAX_QP, + ENCODER_H264_PROP_QUALITY_FACTOR, + ENCODER_H264_N_PROPERTIES +}; + +static GParamSpec *properties[ENCODER_H264_N_PROPERTIES]; + static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, +_gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); @@ -3586,6 +3642,166 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, return GST_VAAPI_ENCODER_STATUS_SUCCESS; } +static void +gst_vaapi_encoder_h264_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (object); + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (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_H264_PROP_RATECONTROL: + gst_vaapi_encoder_set_rate_control (base_encoder, + g_value_get_enum (value)); + break; + case ENCODER_H264_PROP_TUNE: + gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value)); + break; + case ENCODER_H264_PROP_MAX_BFRAMES: + encoder->num_bframes = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_INIT_QP: + encoder->init_qp = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_MIN_QP: + encoder->min_qp = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_QP_IP: + encoder->qp_ip = g_value_get_int (value); + break; + case ENCODER_H264_PROP_QP_IB: + encoder->qp_ib = g_value_get_int (value); + break; + case ENCODER_H264_PROP_NUM_SLICES: + encoder->num_slices = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_CABAC: + encoder->use_cabac = g_value_get_boolean (value); + break; + case ENCODER_H264_PROP_DCT8X8: + encoder->use_dct8x8 = g_value_get_boolean (value); + break; + case ENCODER_H264_PROP_CPB_LENGTH: + encoder->cpb_length = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_NUM_VIEWS: + encoder->num_views = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_VIEW_IDS: + set_view_ids (encoder, value); + break; + case ENCODER_H264_PROP_AUD: + encoder->use_aud = g_value_get_boolean (value); + break; + case ENCODER_H264_PROP_COMPLIANCE_MODE: + encoder->compliance_mode = g_value_get_enum (value); + break; + case ENCODER_H264_PROP_NUM_REF_FRAMES: + encoder->num_ref_frames = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_MBBRC: + encoder->mbbrc = g_value_get_enum (value); + break; + case ENCODER_H264_PROP_TEMPORAL_LEVELS: + encoder->temporal_levels = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_PREDICTION_TYPE: + encoder->prediction_type = g_value_get_enum (value); + break; + case ENCODER_H264_PROP_MAX_QP: + encoder->max_qp = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_QUALITY_FACTOR: + encoder->quality_factor = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gst_vaapi_encoder_h264_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (object); + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); + + switch (prop_id) { + case ENCODER_H264_PROP_RATECONTROL: + g_value_set_enum (value, base_encoder->rate_control); + break; + case ENCODER_H264_PROP_TUNE: + g_value_set_enum (value, base_encoder->tune); + break; + case ENCODER_H264_PROP_MAX_BFRAMES: + g_value_set_uint (value, encoder->num_bframes); + break; + case ENCODER_H264_PROP_INIT_QP: + g_value_set_uint (value, encoder->init_qp); + break; + case ENCODER_H264_PROP_MIN_QP: + g_value_set_uint (value, encoder->min_qp); + break; + case ENCODER_H264_PROP_QP_IP: + g_value_set_int (value, encoder->qp_ip); + break; + case ENCODER_H264_PROP_QP_IB: + g_value_set_int (value, encoder->qp_ib); + break; + case ENCODER_H264_PROP_NUM_SLICES: + g_value_set_uint (value, encoder->num_slices); + break; + case ENCODER_H264_PROP_CABAC: + g_value_set_boolean (value, encoder->use_cabac); + break; + case ENCODER_H264_PROP_DCT8X8: + g_value_set_boolean (value, encoder->use_dct8x8); + break; + case ENCODER_H264_PROP_CPB_LENGTH: + g_value_set_uint (value, encoder->cpb_length); + break; + case ENCODER_H264_PROP_NUM_VIEWS: + g_value_set_uint (value, encoder->num_views); + break; + case ENCODER_H264_PROP_VIEW_IDS: + // TODO: + //get_view_ids (encoder, value); + break; + case ENCODER_H264_PROP_AUD: + g_value_set_boolean (value, encoder->use_aud); + break; + case ENCODER_H264_PROP_COMPLIANCE_MODE: + g_value_set_enum (value, encoder->compliance_mode); + break; + case ENCODER_H264_PROP_NUM_REF_FRAMES: + g_value_set_uint (value, encoder->num_ref_frames); + break; + case ENCODER_H264_PROP_MBBRC: + g_value_set_enum (value, encoder->mbbrc); + break; + case ENCODER_H264_PROP_TEMPORAL_LEVELS: + g_value_set_uint (value, encoder->temporal_levels); + break; + case ENCODER_H264_PROP_PREDICTION_TYPE: + g_value_set_enum (value, encoder->prediction_type); + break; + case ENCODER_H264_PROP_MAX_QP: + g_value_set_uint (value, encoder->max_qp); + break; + case ENCODER_H264_PROP_QUALITY_FACTOR: + g_value_set_uint (value, encoder->quality_factor); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H264); static void @@ -3601,11 +3817,264 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) encoder_class->reordering = gst_vaapi_encoder_h264_reordering; encoder_class->encode = gst_vaapi_encoder_h264_encode; encoder_class->flush = gst_vaapi_encoder_h264_flush; - encoder_class->set_property = gst_vaapi_encoder_h264_set_property; + encoder_class->set_property = _gst_vaapi_encoder_h264_set_property; encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data; encoder_class->get_pending_reordered = gst_vaapi_encoder_h264_get_pending_reordered; + + object_class->set_property = gst_vaapi_encoder_h264_set_property; + object_class->get_property = gst_vaapi_encoder_h264_get_property; object_class->finalize = gst_vaapi_encoder_h264_finalize; + + /** + * GstVaapiEncoderH264:rate-control: + * + * The desired rate control mode, expressed as a #GstVaapiRateControl. + */ + properties[ENCODER_H264_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); + + /** + * GstVaapiEncoderH264:tune: + * + * The desired encoder tuning option. + */ + properties[ENCODER_H264_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); + + /** + * GstVaapiEncoderH264:max-bframes: + * + * The number of B-frames between I and P. + */ + properties[ENCODER_H264_PROP_MAX_BFRAMES] = + g_param_spec_uint ("max-bframes", + "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:refs: + * + * The number of reference frames. + * If B frame is encoded, it will add 1 reference frame more. + */ + properties[ENCODER_H264_PROP_NUM_REF_FRAMES] = + g_param_spec_uint ("refs", "Number of Reference Frames", + "Number of reference frames", 1, 8, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:init-qp: + * + * The initial quantizer value. + */ + properties[ENCODER_H264_PROP_INIT_QP] = + g_param_spec_uint ("init-qp", + "Initial QP", "Initial quantizer value", 0, 51, 26, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:min-qp: + * + * The minimum quantizer value. + */ + properties[ENCODER_H264_PROP_MIN_QP] = + g_param_spec_uint ("min-qp", + "Minimum QP", "Minimum quantizer value", 0, 51, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:max-qp: + * + * The maximum quantizer value. + * + * Since: 1.18 + */ + properties[ENCODER_H264_PROP_MAX_QP] = + g_param_spec_uint ("max-qp", + "Maximum QP", "Maximum quantizer value", 0, 51, 51, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:qp-ip: + * + * The difference of QP between I and P Frame. + * This is available only on CQP mode. + */ + properties[ENCODER_H264_PROP_QP_IP] = + g_param_spec_int ("qp-ip", + "Difference of QP between I and P frame", + "Difference of QP between I and P frame (available only on CQP)", + -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:qp-ib: + * + * The difference of QP between I and B Frame. + * This is available only on CQP mode. + */ + properties[ENCODER_H264_PROP_QP_IB] = + g_param_spec_int ("qp-ib", + "Difference of QP between I and B frame", + "Difference of QP between I and B frame (available only on CQP)", + -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:num-slices: + * + * The number of slices per frame. + */ + properties[ENCODER_H264_PROP_NUM_SLICES] = + g_param_spec_uint ("num-slices", + "Number of Slices", + "Number of slices per frame", + 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:cabac: + * + * Enable CABAC entropy coding mode for improved compression ratio, + * at the expense that the minimum target profile is Main. Default + * is CAVLC entropy coding mode. + */ + properties[ENCODER_H264_PROP_CABAC] = + g_param_spec_boolean ("cabac", + "Enable CABAC", + "Enable CABAC entropy coding mode", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:dct8x8: + * + * Enable adaptive use of 8x8 transforms in I-frames. This improves + * the compression ratio by the minimum target profile is High. + * Default is to use 4x4 DCT only. + */ + properties[ENCODER_H264_PROP_DCT8X8] = + g_param_spec_boolean ("dct8x8", + "Enable 8x8 DCT", + "Enable adaptive use of 8x8 transforms in I-frames", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:mbbrc: + * + * Macroblock level bitrate control. + * This is not compatible with Constant QP rate control. + */ + properties[ENCODER_H264_PROP_MBBRC] = + g_param_spec_enum ("mbbrc", + "Macroblock level Bitrate Control", + "Macroblock level Bitrate Control", + GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:temporal-levels: + * + * Number of temporal levels in the encoded stream. + */ + properties[ENCODER_H264_PROP_TEMPORAL_LEVELS] = + g_param_spec_uint ("temporal-levels", + "temporal levels", + "Number of temporal levels in the encoded stream ", + MIN_TEMPORAL_LEVELS, MAX_TEMPORAL_LEVELS, MIN_TEMPORAL_LEVELS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:prediction-type: + * + * Select the referece picture selection modes + */ + properties[ENCODER_H264_PROP_PREDICTION_TYPE] = + g_param_spec_enum ("prediction-type", + "RefPic Selection", + "Reference Picture Selection Modes", + gst_vaapi_encoder_h264_prediction_type (), + GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:cpb-length: + * + * The size of the CPB buffer in milliseconds. + */ + properties[ENCODER_H264_PROP_CPB_LENGTH] = + g_param_spec_uint ("cpb-length", + "CPB Length", "Length of the CPB buffer in milliseconds", + 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:num-views: + * + * The number of views for MVC encoding . + */ + properties[ENCODER_H264_PROP_NUM_VIEWS] = + g_param_spec_uint ("num-views", + "Number of Views", + "Number of Views for MVC encoding", + 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:view-ids: + * + * The view ids for MVC encoding . + */ + properties[ENCODER_H264_PROP_VIEW_IDS] = + gst_param_spec_array ("view-ids", + "View IDs", "Set of View Ids used for MVC encoding", + g_param_spec_uint ("view-id-value", "View id value", + "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:aud: + * + * Use AU (Access Unit) delimeter. + */ + properties[ENCODER_H264_PROP_AUD] = + g_param_spec_boolean ("aud", "AU delimiter", + "Use AU (Access Unit) delimeter", FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:Compliance Mode: + * + * Encode Tuning(Tweaking) with different compliance modes . + * + * + */ + properties[ENCODER_H264_PROP_COMPLIANCE_MODE] = + g_param_spec_enum ("compliance-mode", + "Spec Compliance Mode", + "Tune Encode quality/performance by relaxing specification compliance restrictions", + gst_vaapi_encoder_h264_compliance_mode_type (), + GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT, G_PARAM_READWRITE); + + /** + * GstVaapiEncoderH264:quality_factor: + * + * quality factor used under ICQ/QVBR bitrate control mode. + */ + properties[ENCODER_H264_PROP_QUALITY_FACTOR] = + g_param_spec_uint ("quality-factor", + "Quality factor for ICQ/QVBR", + "quality factor for ICQ/QVBR bitrate control mode" + "(low value means higher-quality, higher value means lower-quality)", + 1, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, ENCODER_H264_N_PROPERTIES, + properties); } /** From 9348ed9e1cf666f4fd7591a1920fadd68991a23d Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 20 Aug 2019 14:12:36 +0800 Subject: [PATCH 3337/3781] libs: encoder: Add properties for h265 encoder. Install properties for h265 encoder class. Also set the new get/set property functions for gobject class. Still use the old properties way now and this new feature will be enabled later. --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 309 +++++++++++++++++++++- 1 file changed, 307 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 73303b09ca..1d99f8ece3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2664,7 +2664,7 @@ gst_vaapi_encoder_h265_finalize (GObject * object) } static GstVaapiEncoderStatus -gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, +_gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); @@ -2710,6 +2710,156 @@ gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, return GST_VAAPI_ENCODER_STATUS_SUCCESS; } +/** + * @ENCODER_H265_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). + * @ENCODER_H265_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). + * @ENCODER_H265_PROP_MAX_BFRAMES: Number of B-frames between I + * and P (uint). + * @ENCODER_H265_PROP_INIT_QP: Initial quantizer value (uint). + * @ENCODER_H265_PROP_MIN_QP: Minimal quantizer value (uint). + * @ENCODER_H265_PROP_NUM_SLICES: Number of slices per frame (uint). + * @ENCODER_H265_PROP_NUM_REF_FRAMES: Maximum number of reference frames. + * @ENCODER_H265_PROP_CPB_LENGTH: Length of the CPB buffer + * in milliseconds (uint). + * @ENCODER_H265_PROP_MBBRC: Macroblock level Bitrate Control. + * @ENCODER_H265_PROP_QP_IP: Difference of QP between I and P frame. + * @ENCODER_H265_PROP_QP_IB: Difference of QP between I and B frame. + * @ENCODER_H265_PROP_LOW_DELAY_B: use low delay b feature. + * @ENCODER_H265_PROP_MAX_QP: Maximal quantizer value (uint). + * + * The set of H.265 encoder specific configurable properties. + */ +enum +{ + ENCODER_H265_PROP_RATECONTROL = 1, + ENCODER_H265_PROP_TUNE, + ENCODER_H265_PROP_MAX_BFRAMES, + ENCODER_H265_PROP_INIT_QP, + ENCODER_H265_PROP_MIN_QP, + ENCODER_H265_PROP_NUM_SLICES, + ENCODER_H265_PROP_NUM_REF_FRAMES, + ENCODER_H265_PROP_CPB_LENGTH, + ENCODER_H265_PROP_MBBRC, + ENCODER_H265_PROP_QP_IP, + ENCODER_H265_PROP_QP_IB, + ENCODER_H265_PROP_LOW_DELAY_B, + ENCODER_H265_PROP_MAX_QP, + ENCODER_H265_N_PROPERTIES +}; + +static GParamSpec *properties[ENCODER_H265_N_PROPERTIES]; + +static void +gst_vaapi_encoder_h265_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (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_H265_PROP_RATECONTROL: + gst_vaapi_encoder_set_rate_control (base_encoder, + g_value_get_enum (value)); + break; + case ENCODER_H265_PROP_TUNE: + gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value)); + break; + case ENCODER_H265_PROP_MAX_BFRAMES: + encoder->num_bframes = g_value_get_uint (value); + break; + case ENCODER_H265_PROP_INIT_QP: + encoder->init_qp = g_value_get_uint (value); + break; + case ENCODER_H265_PROP_MIN_QP: + encoder->min_qp = g_value_get_uint (value); + break; + case ENCODER_H265_PROP_QP_IP: + encoder->qp_ip = g_value_get_int (value); + break; + case ENCODER_H265_PROP_QP_IB: + encoder->qp_ib = g_value_get_int (value); + break; + case ENCODER_H265_PROP_NUM_SLICES: + encoder->num_slices = g_value_get_uint (value); + break; + case ENCODER_H265_PROP_CPB_LENGTH: + encoder->cpb_length = g_value_get_uint (value); + break; + case ENCODER_H265_PROP_NUM_REF_FRAMES: + encoder->num_ref_frames = g_value_get_uint (value); + break; + case ENCODER_H265_PROP_MBBRC: + encoder->mbbrc = g_value_get_enum (value); + break; + case ENCODER_H265_PROP_LOW_DELAY_B: + encoder->low_delay_b = g_value_get_boolean (value); + break; + case ENCODER_H265_PROP_MAX_QP: + encoder->max_qp = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gst_vaapi_encoder_h265_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (object); + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); + + switch (prop_id) { + case ENCODER_H265_PROP_RATECONTROL: + g_value_set_enum (value, base_encoder->rate_control); + break; + case ENCODER_H265_PROP_TUNE: + g_value_set_enum (value, base_encoder->tune); + break; + case ENCODER_H265_PROP_MAX_BFRAMES: + g_value_set_uint (value, encoder->num_bframes); + break; + case ENCODER_H265_PROP_INIT_QP: + g_value_set_uint (value, encoder->init_qp); + break; + case ENCODER_H265_PROP_MIN_QP: + g_value_set_uint (value, encoder->min_qp); + break; + case ENCODER_H265_PROP_QP_IP: + g_value_set_int (value, encoder->qp_ip); + break; + case ENCODER_H265_PROP_QP_IB: + g_value_set_int (value, encoder->qp_ib); + break; + case ENCODER_H265_PROP_NUM_SLICES: + g_value_set_uint (value, encoder->num_slices); + break; + case ENCODER_H265_PROP_CPB_LENGTH: + g_value_set_uint (value, encoder->cpb_length); + break; + case ENCODER_H265_PROP_NUM_REF_FRAMES: + g_value_set_uint (value, encoder->num_ref_frames); + break; + case ENCODER_H265_PROP_MBBRC: + g_value_set_enum (value, encoder->mbbrc); + break; + case ENCODER_H265_PROP_LOW_DELAY_B: + g_value_set_boolean (value, encoder->low_delay_b); + break; + case ENCODER_H265_PROP_MAX_QP: + g_value_set_uint (value, encoder->max_qp); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H265); static void @@ -2725,11 +2875,166 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) encoder_class->reordering = gst_vaapi_encoder_h265_reordering; encoder_class->encode = gst_vaapi_encoder_h265_encode; encoder_class->flush = gst_vaapi_encoder_h265_flush; - encoder_class->set_property = gst_vaapi_encoder_h265_set_property; + encoder_class->set_property = _gst_vaapi_encoder_h265_set_property; encoder_class->get_codec_data = gst_vaapi_encoder_h265_get_codec_data; encoder_class->get_pending_reordered = gst_vaapi_encoder_h265_get_pending_reordered; + + object_class->set_property = gst_vaapi_encoder_h265_set_property; + object_class->get_property = gst_vaapi_encoder_h265_get_property; object_class->finalize = gst_vaapi_encoder_h265_finalize; + + /** + * GstVaapiEncoderH265:rate-control: + * + * The desired rate control mode, expressed as a #GstVaapiRateControl. + */ + properties[ENCODER_H265_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); + + /** + * GstVaapiEncoderH265:tune: + * + * The desired encoder tuning option. + */ + properties[ENCODER_H265_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); + + /** + * GstVaapiEncoderH265:max-bframes: + * + * The number of B-frames between I and P. + */ + properties[ENCODER_H265_PROP_MAX_BFRAMES] = + g_param_spec_uint ("max-bframes", + "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH265:refs: + * + * The number of reference frames. + * If B frame is encoded, it will add 1 reference frame more. + */ + properties[ENCODER_H265_PROP_NUM_REF_FRAMES] = + g_param_spec_uint ("refs", + "Number of Reference Frames", "Number of reference frames", 1, 3, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH265:init-qp: + * + * The initial quantizer value. + */ + properties[ENCODER_H265_PROP_INIT_QP] = + g_param_spec_uint ("init-qp", + "Initial QP", "Initial quantizer value", 0, 51, 26, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH265:min-qp: + * + * The minimum quantizer value. + */ + properties[ENCODER_H265_PROP_MIN_QP] = + g_param_spec_uint ("min-qp", + "Minimum QP", "Minimum quantizer value", 0, 51, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH265:max-qp: + * + * The maximum quantizer value. + * + * Since: 1.18 + */ + properties[ENCODER_H265_PROP_MAX_QP] = + g_param_spec_uint ("max-qp", + "Maximum QP", "Maximum quantizer value", 0, 51, 51, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH265:qp-ip: + * + * The difference of QP between I and P Frame. + * This is available only on CQP mode. + */ + properties[ENCODER_H265_PROP_QP_IP] = + g_param_spec_int ("qp-ip", + "Difference of QP between I and P frame", + "Difference of QP between I and P frame (available only on CQP)", + -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH265:qp-ib: + * + * The difference of QP between I and B Frame. + * This is available only on CQP mode. + */ + properties[ENCODER_H265_PROP_QP_IB] = + g_param_spec_int ("qp-ib", + "Difference of QP between I and B frame", + "Difference of QP between I and B frame (available only on CQP)", + -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /* FIXME: there seems to be issues with multi-slice encoding */ + /** + * GstVaapiEncoderH265:num-slices: + * + * The number of slices per frame. + */ + properties[ENCODER_H265_PROP_NUM_SLICES] = + g_param_spec_uint ("num-slices", + "Number of Slices", + "Number of slices per frame", + 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH265:cpb-length: + * + * The size of the CPB buffer in milliseconds. + */ + properties[ENCODER_H265_PROP_CPB_LENGTH] = + g_param_spec_uint ("cpb-length", + "CPB Length", "Length of the CPB buffer in milliseconds", + 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH265:mbbrc: + * + * Macroblock level bitrate control. + * This is not compatible with Constant QP rate control. + */ + properties[ENCODER_H265_PROP_MBBRC] = + g_param_spec_enum ("mbbrc", + "Macroblock level Bitrate Control", + "Macroblock level Bitrate Control", + GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH265:low_delay_b: + * + * Enable low delay b frame, which will change P frame with B frame. + */ + properties[ENCODER_H265_PROP_LOW_DELAY_B] = + g_param_spec_boolean ("low-delay-b", + "Enable low delay b", + "Transforms P frames into predictive B frames." + " Enable it when P frames are not supported.", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, ENCODER_H265_N_PROPERTIES, + properties); } /** From 8641c27a1330a4119edd71d7dc280f7b83b844cf Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 20 Aug 2019 14:53:06 +0800 Subject: [PATCH 3338/3781] libs: encoder: Add properties for jpeg encoder. Install properties for jpeg encoder class. Also set the new get/set property functions for gobject class. Still use the old properties way now and this new feature will be enabled later. --- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 99 ++++++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 44fee30a93..674164bf76 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -763,7 +763,7 @@ gst_vaapi_encoder_jpeg_init (GstVaapiEncoderJpeg * encoder) } static GstVaapiEncoderStatus -gst_vaapi_encoder_jpeg_set_property (GstVaapiEncoder * base_encoder, +_gst_vaapi_encoder_jpeg_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (base_encoder); @@ -778,11 +778,80 @@ gst_vaapi_encoder_jpeg_set_property (GstVaapiEncoder * base_encoder, return GST_VAAPI_ENCODER_STATUS_SUCCESS; } +/** + * @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; @@ -792,7 +861,33 @@ gst_vaapi_encoder_jpeg_class_init (GstVaapiEncoderJpegClass * klass) encoder_class->reordering = gst_vaapi_encoder_jpeg_reordering; encoder_class->encode = gst_vaapi_encoder_jpeg_encode; encoder_class->flush = gst_vaapi_encoder_jpeg_flush; - encoder_class->set_property = gst_vaapi_encoder_jpeg_set_property; + encoder_class->set_property = _gst_vaapi_encoder_jpeg_set_property; + + 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); + + 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); + + 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_object_class_install_properties (object_class, ENCODER_JPEG_N_PROPERTIES, + properties); } /** From 8212c0552e0ca7842f36b1978244394bc259b3c9 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 20 Aug 2019 14:31:58 +0800 Subject: [PATCH 3339/3781] libs: encoder: Add properties for mpeg2 encoder. Install properties for mpeg2 encoder class. Also set the new get/set property functions for gobject class. Still use the old properties way now and this new feature will be enabled later. --- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 123 ++++++++++++++++++++- 1 file changed, 121 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 2389083afb..3a354b00ba 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -783,7 +783,7 @@ gst_vaapi_encoder_mpeg2_finalize (GObject * object) } static GstVaapiEncoderStatus -gst_vaapi_encoder_mpeg2_set_property (GstVaapiEncoder * base_encoder, +_gst_vaapi_encoder_mpeg2_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { GstVaapiEncoderMpeg2 *const encoder = @@ -802,6 +802,83 @@ gst_vaapi_encoder_mpeg2_set_property (GstVaapiEncoder * base_encoder, return GST_VAAPI_ENCODER_STATUS_SUCCESS; } +/** + * @ENCODER_MPEG2_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). + * @ENCODER_MPEG2_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). + * @ENCODER_MPEG2_PROP_QUANTIZER: Constant quantizer value (uint). + * @ENCODER_MPEG2_PROP_MAX_BFRAMES: Number of B-frames between I + * and P (uint). + * + * The set of MPEG-2 encoder specific configurable properties. + */ +enum +{ + ENCODER_MPEG2_PROP_RATECONTROL = 1, + ENCODER_MPEG2_PROP_TUNE, + ENCODER_MPEG2_PROP_QUANTIZER, + ENCODER_MPEG2_PROP_MAX_BFRAMES, + ENCODER_MPEG2_N_PROPERTIES +}; + +static GParamSpec *properties[ENCODER_MPEG2_N_PROPERTIES]; + +static void +gst_vaapi_encoder_mpeg2_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); + GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2 (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_MPEG2_PROP_RATECONTROL: + gst_vaapi_encoder_set_rate_control (base_encoder, + g_value_get_enum (value)); + break; + case ENCODER_MPEG2_PROP_TUNE: + gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value)); + break; + case ENCODER_MPEG2_PROP_QUANTIZER: + encoder->cqp = g_value_get_uint (value); + break; + case ENCODER_MPEG2_PROP_MAX_BFRAMES: + encoder->ip_period = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gst_vaapi_encoder_mpeg2_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2 (object); + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); + + switch (prop_id) { + case ENCODER_MPEG2_PROP_RATECONTROL: + g_value_set_enum (value, base_encoder->rate_control); + break; + case ENCODER_MPEG2_PROP_TUNE: + g_value_set_enum (value, base_encoder->tune); + break; + case ENCODER_MPEG2_PROP_QUANTIZER: + g_value_set_uint (value, encoder->cqp); + break; + case ENCODER_MPEG2_PROP_MAX_BFRAMES: + g_value_set_uint (value, encoder->ip_period); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (MPEG2); static void @@ -817,8 +894,50 @@ gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass) encoder_class->reordering = gst_vaapi_encoder_mpeg2_reordering; encoder_class->encode = gst_vaapi_encoder_mpeg2_encode; encoder_class->flush = gst_vaapi_encoder_mpeg2_flush; - encoder_class->set_property = gst_vaapi_encoder_mpeg2_set_property; + encoder_class->set_property = _gst_vaapi_encoder_mpeg2_set_property; + + object_class->set_property = gst_vaapi_encoder_mpeg2_set_property; + object_class->get_property = gst_vaapi_encoder_mpeg2_get_property; object_class->finalize = gst_vaapi_encoder_mpeg2_finalize; + + /** + * GstVaapiEncoderMpeg2:rate-control: + * + * The desired rate control mode, expressed as a #GstVaapiRateControl. + */ + properties[ENCODER_MPEG2_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); + + /** + * GstVaapiEncoderMpeg2:tune: + * + * The desired encoder tuning option. + */ + properties[ENCODER_MPEG2_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); + + properties[ENCODER_MPEG2_PROP_QUANTIZER] = + g_param_spec_uint ("quantizer", + "Constant Quantizer", + "Constant quantizer (if rate-control mode is CQP)", + 2, 62, 8, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[ENCODER_MPEG2_PROP_MAX_BFRAMES] = + g_param_spec_uint ("max-bframes", "Max B-Frames", + "Number of B-frames between I and P", 0, 16, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, ENCODER_MPEG2_N_PROPERTIES, + properties); } /** From ba41bcddc66760a6c23b3e40ddcd03828d21044e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 20 Aug 2019 15:01:02 +0800 Subject: [PATCH 3340/3781] libs: encoder: Add properties for vp8 encoder. Install properties for vp8 encoder class. Also set the new get/set property functions for gobject class. Still use the old properties way now and this new feature will be enabled later. --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 125 ++++++++++++++++++++++- 1 file changed, 123 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index eb4c7ad1e2..17b52ef015 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -536,7 +536,7 @@ gst_vaapi_encoder_vp8_finalize (GObject * object) } static GstVaapiEncoderStatus -gst_vaapi_encoder_vp8_set_property (GstVaapiEncoder * base_encoder, +_gst_vaapi_encoder_vp8_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder); @@ -557,6 +557,90 @@ gst_vaapi_encoder_vp8_set_property (GstVaapiEncoder * base_encoder, return GST_VAAPI_ENCODER_STATUS_SUCCESS; } +/** + * @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 @@ -572,8 +656,45 @@ gst_vaapi_encoder_vp8_class_init (GstVaapiEncoderVP8Class * klass) encoder_class->reordering = gst_vaapi_encoder_vp8_reordering; encoder_class->encode = gst_vaapi_encoder_vp8_encode; encoder_class->flush = gst_vaapi_encoder_vp8_flush; - encoder_class->set_property = gst_vaapi_encoder_vp8_set_property; + encoder_class->set_property = _gst_vaapi_encoder_vp8_set_property; + + 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); + + 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); + + 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); + + 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); + + 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_object_class_install_properties (object_class, ENCODER_VP8_N_PROPERTIES, + properties); } /** From 30e79a09400ec85cf1ab671ecc2bac35742d00cc Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 20 Aug 2019 15:29:27 +0800 Subject: [PATCH 3341/3781] libs: encoder: Add properties for vp9 encoder. Install properties for vp9 encoder class. Also set the new get/set property functions for gobject class. Still use the old properties way now and this new feature will be enabled later. --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 166 ++++++++++++++++++++++- 1 file changed, 164 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index d167d11949..16be27804e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -557,7 +557,7 @@ gst_vaapi_encoder_vp9_init (GstVaapiEncoderVP9 * encoder) } static GstVaapiEncoderStatus -gst_vaapi_encoder_vp9_set_property (GstVaapiEncoder * base_encoder, +_gst_vaapi_encoder_vp9_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (base_encoder); @@ -584,11 +584,112 @@ gst_vaapi_encoder_vp9_set_property (GstVaapiEncoder * base_encoder, return GST_VAAPI_ENCODER_STATUS_SUCCESS; } +/** + * @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; @@ -598,7 +699,68 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) encoder_class->reordering = gst_vaapi_encoder_vp9_reordering; encoder_class->encode = gst_vaapi_encoder_vp9_encode; encoder_class->flush = gst_vaapi_encoder_vp9_flush; - encoder_class->set_property = gst_vaapi_encoder_vp9_set_property; + encoder_class->set_property = _gst_vaapi_encoder_vp9_set_property; + + object_class->set_property = gst_vaapi_encoder_vp9_set_property; + object_class->get_property = gst_vaapi_encoder_vp9_get_property; + + 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); + + 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); + + 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); + + 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); + + 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); + + 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); + + /** + * 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_object_class_install_properties (object_class, ENCODER_VP9_N_PROPERTIES, + properties); } /** From a65847b2adf0a3cf1a27fdeb95f2dbb9ead2254b Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 20 Aug 2019 15:58:30 +0800 Subject: [PATCH 3342/3781] libs: encoder: Add properties for h264 fei encoder. Install properties for h264 fei encoder class. Also set the new get/set property functions for gobject class. Still use the old properties way now and this new feature will be enabled later. --- gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 538 +++++++++++++++++++++++ 1 file changed, 538 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index c26ad46f96..a15a192c84 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -1835,6 +1835,256 @@ gst_vaapi_feienc_h264_set_property (GstVaapiEncoder * base_encoder, return GST_VAAPI_ENCODER_STATUS_SUCCESS; } +/** + * @FEI_H264_ENC_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). + * @FEI_H264_ENC_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). + * @FEI_H264_ENC_PROP_MAX_BFRAMES: Number of B-frames between I + * and P (uint). + * @FEI_H264_ENC_PROP_INIT_QP: Initial quantizer value (uint). + * @FEI_H264_ENC_PROP_MIN_QP: Minimal quantizer value (uint). + * @FEI_H264_ENC_PROP_NUM_SLICES: Number of slices per frame (uint). + * @FEI_H264_ENC_PROP_CABAC: Enable CABAC entropy coding mode (bool). + * @FEI_H264_ENC_PROP_DCT8X8: Enable adaptive use of 8x8 + * transforms in I-frames (bool). + * @FEI_H264_ENC_PROP_CPB_LENGTH: Length of the CPB buffer + * in milliseconds (uint). + * @FEI_H264_ENC_PROP_NUM_VIEWS: Number of views per frame. + * @FEI_H264_ENC_PROP_VIEW_IDS: View IDs + * + * The set of FEI Enc specific configurable properties. + */ +enum +{ + FEI_H264_ENC_PROP_RATECONTROL = 1, + FEI_H264_ENC_PROP_TUNE, + FEI_H264_ENC_PROP_MAX_BFRAMES, + FEI_H264_ENC_PROP_INIT_QP, + FEI_H264_ENC_PROP_MIN_QP, + FEI_H264_ENC_PROP_NUM_SLICES, + FEI_H264_ENC_PROP_CABAC, + FEI_H264_ENC_PROP_DCT8X8, + FEI_H264_ENC_PROP_CPB_LENGTH, + FEI_H264_ENC_PROP_NUM_VIEWS, + FEI_H264_ENC_PROP_VIEW_IDS, + FEI_H264_ENC_PROP_NUM_REF, + FEI_H264_ENC_PROP_FEI_ENABLE, + FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0, + FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1, + FEI_H264_ENC_PROP_SEARCH_WINDOW, + FEI_H264_ENC_PROP_LEN_SP, + FEI_H264_ENC_PROP_SEARCH_PATH, + FEI_H264_ENC_PROP_REF_WIDTH, + FEI_H264_ENC_PROP_REF_HEIGHT, + FEI_H264_ENC_PROP_SUBMB_MASK, + FEI_H264_ENC_PROP_SUBPEL_MODE, + FEI_H264_ENC_PROP_INTRA_PART_MASK, + FEI_H264_ENC_PROP_INTRA_SAD, + FEI_H264_ENC_PROP_INTER_SAD, + FEI_H264_ENC_PROP_ADAPT_SEARCH, + FEI_H264_ENC_PROP_MULTI_PRED_L0, + FEI_H264_ENC_PROP_MULTI_PRED_L1, + FEI_H264_ENC_PROP_ENABLE_STATS_OUT, + FEI_H264_ENC_N_PROPERTIES +}; + +static GParamSpec *properties[FEI_H264_ENC_N_PROPERTIES]; + +static void +_gst_vaapi_feienc_h264_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); + + if (base_encoder->num_codedbuf_queued > 0) { + GST_ERROR_OBJECT (object, + "failed to set any property after encoding started"); + return; + } + + switch (prop_id) { + case FEI_H264_ENC_PROP_RATECONTROL: + gst_vaapi_encoder_set_rate_control (base_encoder, + g_value_get_enum (value)); + break; + case FEI_H264_ENC_PROP_TUNE: + gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value)); + break; + case FEI_H264_ENC_PROP_MAX_BFRAMES: + feienc->num_bframes = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_INIT_QP: + feienc->init_qp = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_MIN_QP: + feienc->min_qp = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_NUM_SLICES: + feienc->num_slices = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_CABAC: + feienc->use_cabac = g_value_get_boolean (value); + break; + case FEI_H264_ENC_PROP_DCT8X8: + feienc->use_dct8x8 = g_value_get_boolean (value); + break; + case FEI_H264_ENC_PROP_CPB_LENGTH: + feienc->cpb_length = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_NUM_VIEWS: + feienc->num_views = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_VIEW_IDS: + set_view_ids (feienc, value); + break; + case FEI_H264_ENC_PROP_NUM_REF: + feienc->num_ref_frames = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0: + feienc->num_mv_predictors_l0 = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1: + feienc->num_mv_predictors_l1 = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_SEARCH_WINDOW: + feienc->search_window = g_value_get_enum (value); + break; + case FEI_H264_ENC_PROP_LEN_SP: + feienc->len_sp = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_SEARCH_PATH: + feienc->search_path = g_value_get_enum (value); + break; + case FEI_H264_ENC_PROP_REF_WIDTH: + feienc->ref_width = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_REF_HEIGHT: + feienc->ref_height = g_value_get_uint (value); + break; + case FEI_H264_ENC_PROP_SUBMB_MASK: + feienc->submb_part_mask = g_value_get_flags (value); + break; + case FEI_H264_ENC_PROP_SUBPEL_MODE: + feienc->subpel_mode = g_value_get_enum (value); + break; + case FEI_H264_ENC_PROP_INTRA_PART_MASK: + feienc->intra_part_mask = g_value_get_flags (value); + break; + case FEI_H264_ENC_PROP_INTRA_SAD: + feienc->intra_sad = g_value_get_enum (value); + break; + case FEI_H264_ENC_PROP_INTER_SAD: + feienc->inter_sad = g_value_get_enum (value); + break; + case FEI_H264_ENC_PROP_ADAPT_SEARCH: + feienc->adaptive_search = g_value_get_boolean (value) ? 1 : 0; + break; + case FEI_H264_ENC_PROP_MULTI_PRED_L0: + feienc->multi_predL0 = g_value_get_boolean (value) ? 1 : 0; + break; + case FEI_H264_ENC_PROP_MULTI_PRED_L1: + feienc->multi_predL1 = g_value_get_boolean (value) ? 1 : 0; + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gst_vaapi_feienc_h264_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (object); + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); + + switch (prop_id) { + case FEI_H264_ENC_PROP_RATECONTROL: + g_value_set_enum (value, base_encoder->rate_control); + break; + case FEI_H264_ENC_PROP_TUNE: + g_value_set_enum (value, base_encoder->tune); + break; + case FEI_H264_ENC_PROP_MAX_BFRAMES: + g_value_set_uint (value, feienc->num_bframes); + break; + case FEI_H264_ENC_PROP_INIT_QP: + g_value_set_uint (value, feienc->init_qp); + break; + case FEI_H264_ENC_PROP_MIN_QP: + g_value_set_uint (value, feienc->min_qp); + break; + case FEI_H264_ENC_PROP_NUM_SLICES: + g_value_set_uint (value, feienc->num_slices); + break; + case FEI_H264_ENC_PROP_CABAC: + g_value_set_boolean (value, feienc->use_cabac); + break; + case FEI_H264_ENC_PROP_DCT8X8: + g_value_set_boolean (value, feienc->use_dct8x8); + break; + case FEI_H264_ENC_PROP_CPB_LENGTH: + g_value_set_uint (value, feienc->cpb_length); + break; + case FEI_H264_ENC_PROP_NUM_VIEWS: + g_value_set_uint (value, feienc->num_views); + break; + case FEI_H264_ENC_PROP_VIEW_IDS: + // TODO: + //get_view_ids (feienc, value); + break; + case FEI_H264_ENC_PROP_NUM_REF: + g_value_set_uint (value, feienc->num_ref_frames); + break; + case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0: + g_value_set_uint (value, feienc->num_mv_predictors_l0); + break; + case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1: + g_value_set_uint (value, feienc->num_mv_predictors_l1); + break; + case FEI_H264_ENC_PROP_SEARCH_WINDOW: + g_value_set_enum (value, feienc->search_window); + break; + case FEI_H264_ENC_PROP_LEN_SP: + g_value_set_uint (value, feienc->len_sp); + break; + case FEI_H264_ENC_PROP_SEARCH_PATH: + g_value_set_enum (value, feienc->search_path); + break; + case FEI_H264_ENC_PROP_REF_WIDTH: + g_value_set_uint (value, feienc->ref_width); + break; + case FEI_H264_ENC_PROP_REF_HEIGHT: + g_value_set_uint (value, feienc->ref_height); + break; + case FEI_H264_ENC_PROP_SUBMB_MASK: + g_value_set_flags (value, feienc->submb_part_mask); + break; + case FEI_H264_ENC_PROP_SUBPEL_MODE: + g_value_set_enum (value, feienc->subpel_mode); + break; + case FEI_H264_ENC_PROP_INTRA_PART_MASK: + g_value_set_flags (value, feienc->intra_part_mask); + break; + case FEI_H264_ENC_PROP_INTRA_SAD: + g_value_set_enum (value, feienc->intra_sad); + break; + case FEI_H264_ENC_PROP_INTER_SAD: + g_value_set_enum (value, feienc->inter_sad); + break; + case FEI_H264_ENC_PROP_ADAPT_SEARCH: + g_value_set_boolean (value, feienc->adaptive_search); + break; + case FEI_H264_ENC_PROP_MULTI_PRED_L0: + g_value_set_boolean (value, feienc->multi_predL0); + break; + case FEI_H264_ENC_PROP_MULTI_PRED_L1: + g_value_set_boolean (value, feienc->multi_predL1); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + static const GstVaapiEncoderClassData fei_enc_class_data = { .codec = GST_VAAPI_CODEC_H264, .packed_headers = SUPPORTED_PACKED_HEADERS, @@ -1861,7 +2111,295 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) encoder_class->flush = gst_vaapi_feienc_h264_flush; encoder_class->set_property = gst_vaapi_feienc_h264_set_property; encoder_class->get_codec_data = gst_vaapi_feienc_h264_get_codec_data; + + object_class->set_property = _gst_vaapi_feienc_h264_set_property; + object_class->get_property = gst_vaapi_feienc_h264_get_property; object_class->finalize = gst_vaapi_feienc_h264_finalize; + + /** + * GstVaapiFeiEncH264:rate-control: + * + * The desired rate control mode, expressed as a #GstVaapiRateControl. + */ + properties[FEI_H264_ENC_PROP_RATECONTROL] = + g_param_spec_enum ("rate-control", + "Rate Control", "Rate control mode", + fei_enc_class_data.rate_control_get_type (), + fei_enc_class_data.default_rate_control, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:tune: + * + * The desired encoder tuning option. + */ + properties[FEI_H264_ENC_PROP_TUNE] = + g_param_spec_enum ("tune", + "Encoder Tuning", + "Encoder tuning option", + fei_enc_class_data.encoder_tune_get_type (), + fei_enc_class_data.default_encoder_tune, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:max-bframes: + * + * The number of B-frames between I and P. + */ + properties[FEI_H264_ENC_PROP_MAX_BFRAMES] = + g_param_spec_uint ("max-bframes", + "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:init-qp: + * + * The initial quantizer value. + */ + properties[FEI_H264_ENC_PROP_INIT_QP] = + g_param_spec_uint ("init-qp", + "Initial QP", "Initial quantizer value", 1, 51, 26, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:min-qp: + * + * The minimum quantizer value. + */ + properties[FEI_H264_ENC_PROP_MIN_QP] = + g_param_spec_uint ("min-qp", + "Minimum QP", "Minimum quantizer value", 1, 51, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:num-slices: + * + * The number of slices per frame. + */ + properties[FEI_H264_ENC_PROP_NUM_SLICES] = + g_param_spec_uint ("num-slices", + "Number of Slices", + "Number of slices per frame", + 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:cabac: + * + * Enable CABAC entropy coding mode for improved compression ratio, + * at the expense that the minimum target profile is Main. Default + * is CAVLC entropy coding mode. + */ + properties[FEI_H264_ENC_PROP_CABAC] = + g_param_spec_boolean ("cabac", + "Enable CABAC", + "Enable CABAC entropy coding mode", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:dct8x8: + * + * Enable adaptive use of 8x8 transforms in I-frames. This improves + * the compression ratio by the minimum target profile is High. + * Default is to use 4x4 DCT only. + */ + properties[FEI_H264_ENC_PROP_DCT8X8] = + g_param_spec_boolean ("dct8x8", + "Enable 8x8 DCT", + "Enable adaptive use of 8x8 transforms in I-frames", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:cpb-length: + * + * The size of the CPB buffer in milliseconds. + */ + properties[FEI_H264_ENC_PROP_CPB_LENGTH] = + g_param_spec_uint ("cpb-length", + "CPB Length", "Length of the CPB buffer in milliseconds", + 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:num-views: + * + * The number of views for MVC encoding . + */ + properties[FEI_H264_ENC_PROP_NUM_VIEWS] = + g_param_spec_uint ("num-views", + "Number of Views", + "Number of Views for MVC encoding", + 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFeiEncH264:view-ids: + * + * The view ids for MVC encoding . + */ + properties[FEI_H264_ENC_PROP_VIEW_IDS] = + gst_param_spec_array ("view-ids", + "View IDs", "Set of View Ids used for MVC encoding", + g_param_spec_uint ("view-id-value", "View id value", + "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFeiEncH264:num-ref: + * + * The number of reference frames. + */ + properties[FEI_H264_ENC_PROP_NUM_REF] = + g_param_spec_uint ("num-ref", + "Num Ref", + "reference frame number", + 1, 6, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:num_mv_predictors_l0: + * + * The number of mv predict + */ + properties[FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0] = + g_param_spec_uint ("num-mvpredict-l0", + "Num mv predict l0", + "Indicate how many predictors should be used for l0", + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFeiEncH264:num_mv_predictors_l1: + * + * The number of mv predict + */ + properties[FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1] = + g_param_spec_uint ("num-mvpredict-l1", + "Num mv predict l1", + "Indicate how many predictors should be used for l1", + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFeiEncH264:search-window: + */ + properties[FEI_H264_ENC_PROP_SEARCH_WINDOW] = + g_param_spec_enum ("search-window", + "search window", + "Specify one of the predefined search path", + GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFeiEncH264:len-sp: + */ + properties[FEI_H264_ENC_PROP_LEN_SP] = + g_param_spec_uint ("len-sp", + "len sp", + "This value defines number of search units in search path", + 1, 63, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:search-path: + */ + properties[FEI_H264_ENC_PROP_SEARCH_PATH] = + g_param_spec_enum ("search-path", + "search path", + "Specify search path", + GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, + GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:ref-width: + */ + properties[FEI_H264_ENC_PROP_REF_WIDTH] = + g_param_spec_uint ("ref-width", + "ref width", + "Width of search region in pixel, must be multiple of 4", + 4, 64, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:ref-height: + */ + properties[FEI_H264_ENC_PROP_REF_HEIGHT] = + g_param_spec_uint ("ref-height", + "ref height", + "Height of search region in pixel, must be multiple of 4", + 4, 32, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFeiEncH264:submb-mask: + * Defines the bit-mask for disabling sub-partition + * + */ + properties[FEI_H264_ENC_PROP_SUBMB_MASK] = + g_param_spec_flags ("submbpart-mask", + "submb part mask", + "defines the bit-mask for disabling sub mb partition", + GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, + GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:subpel-mode: + */ + properties[FEI_H264_ENC_PROP_SUBPEL_MODE] = + g_param_spec_enum ("subpel-mode", + "subpel mode", + "Sub pixel precision for motion estimation", + GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, + GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFeiEncH264:intrapart-mask: + */ + properties[FEI_H264_ENC_PROP_INTRA_PART_MASK] = + g_param_spec_flags ("intrapart-mask", + "intra part mask", + "What block and sub-block partitions are disabled for intra MBs", + GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, + GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFeiEncH264:intra-sad: + */ + properties[FEI_H264_ENC_PROP_INTRA_SAD] = + g_param_spec_enum ("intra-sad", + "intra sad", + "Specifies distortion measure adjustments used in the motion search SAD comparison for intra MB", + GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:inter-sad: + */ + properties[FEI_H264_ENC_PROP_INTER_SAD] = + g_param_spec_enum ("inter-sad", + "inter sad", + "Specifies distortion measure adjustments used in the motion search SAD comparison for inter MB", + GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:adaptive-search: + */ + properties[FEI_H264_ENC_PROP_ADAPT_SEARCH] = + g_param_spec_boolean ("adaptive-search", + "adaptive-search", + "Enable adaptive search", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:multi-predL0: + */ + properties[FEI_H264_ENC_PROP_MULTI_PRED_L0] = + g_param_spec_boolean ("multi-predL0", + "multi predL0", + "Enable multi prediction for ref L0 list", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiFeiEncH264:multi-predL0: + */ + properties[FEI_H264_ENC_PROP_MULTI_PRED_L1] = + g_param_spec_boolean ("multi-predL1", + "multi predL1", + "Enable multi prediction for ref L1 list", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, FEI_H264_ENC_N_PROPERTIES, + properties); } /** From 46c8b425dd9e375ee25db5d3ac135a780be4a337 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 20 Aug 2019 17:00:39 +0800 Subject: [PATCH 3343/3781] libs: encoder: Add properties for h264 encoder fei. Install properties for h264 encoder fei class. Also set the new get/set property functions for gobject class. Still use the old properties way now and this new feature will be enabled later. --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 677 +++++++++++++++++- 1 file changed, 675 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index 201b27d76e..dab9d9dbc4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -3474,7 +3474,7 @@ set_default_ids: } static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_fei_set_property (GstVaapiEncoder * base_encoder, +_gst_vaapi_encoder_h264_fei_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) { GstVaapiEncoderH264Fei *const encoder = @@ -3614,6 +3614,310 @@ gst_vaapi_encoder_h264_fei_set_property (GstVaapiEncoder * base_encoder, return GST_VAAPI_ENCODER_STATUS_SUCCESS; } +/** + * @ENCODER_H264_FEI_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). + * @ENCODER_H264_FEI_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). + * @ENCODER_H264_FEI_PROP_MAX_BFRAMES: Number of B-frames between I + * and P (uint). + * @ENCODER_H264_FEI_PROP_INIT_QP: Initial quantizer value (uint). + * @ENCODER_H264_FEI_PROP_MIN_QP: Minimal quantizer value (uint). + * @ENCODER_H264_FEI_PROP_NUM_SLICES: Number of slices per frame (uint). + * @ENCODER_H264_FEI_PROP_CABAC: Enable CABAC entropy coding mode (bool). + * @ENCODER_H264_FEI_PROP_DCT8X8: Enable adaptive use of 8x8 + * transforms in I-frames (bool). + * @ENCODER_H264_FEI_PROP_CPB_LENGTH: Length of the CPB buffer + * in milliseconds (uint). + * @ENCODER_H264_FEI_PROP_NUM_VIEWS: Number of views per frame. + * @ENCODER_H264_FEI_PROP_VIEW_IDS: View IDs + * @ENCODER_H264_FEI_PROP_MAX_QP: Maximal quantizer value (uint). + * + * The set of H.264 encoder specific configurable properties. + */ +enum +{ + ENCODER_H264_FEI_PROP_RATECONTROL = 1, + ENCODER_H264_FEI_PROP_TUNE, + ENCODER_H264_FEI_PROP_MAX_BFRAMES, + ENCODER_H264_FEI_PROP_INIT_QP, + ENCODER_H264_FEI_PROP_MIN_QP, + ENCODER_H264_FEI_PROP_NUM_SLICES, + ENCODER_H264_FEI_PROP_CABAC, + ENCODER_H264_FEI_PROP_DCT8X8, + ENCODER_H264_FEI_PROP_CPB_LENGTH, + ENCODER_H264_FEI_PROP_NUM_VIEWS, + ENCODER_H264_FEI_PROP_VIEW_IDS, + ENCODER_H264_PROP_FEI_DISABLE, + ENCODER_H264_PROP_NUM_MV_PREDICT_L0, + ENCODER_H264_PROP_NUM_MV_PREDICT_L1, + ENCODER_H264_PROP_SEARCH_WINDOW, + ENCODER_H264_PROP_LEN_SP, + ENCODER_H264_PROP_SEARCH_PATH, + ENCODER_H264_PROP_REF_WIDTH, + ENCODER_H264_PROP_REF_HEIGHT, + ENCODER_H264_PROP_SUBMB_MASK, + ENCODER_H264_PROP_SUBPEL_MODE, + ENCODER_H264_PROP_INTRA_PART_MASK, + ENCODER_H264_PROP_INTRA_SAD, + ENCODER_H264_PROP_INTER_SAD, + ENCODER_H264_PROP_ADAPT_SEARCH, + ENCODER_H264_PROP_MULTI_PRED_L0, + ENCODER_H264_PROP_MULTI_PRED_L1, + ENCODER_H264_PROP_ENABLE_STATS_OUT, + ENCODER_H264_PROP_FEI_MODE, + ENCODER_H264_FEI_PROP_MAX_QP, + ENCODER_H264_FEI_N_PROPERTIES +}; + +static GParamSpec *properties[ENCODER_H264_FEI_N_PROPERTIES]; + +static void +gst_vaapi_encoder_h264_fei_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); + GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); + GstVaapiEncoderStatus status; + + switch (prop_id) { + case ENCODER_H264_FEI_PROP_RATECONTROL: + gst_vaapi_encoder_set_rate_control (base_encoder, + g_value_get_enum (value)); + break; + case ENCODER_H264_FEI_PROP_TUNE: + gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value)); + break; + case ENCODER_H264_FEI_PROP_MAX_BFRAMES: + encoder->num_bframes = g_value_get_uint (value); + break; + case ENCODER_H264_FEI_PROP_INIT_QP: + encoder->init_qp = g_value_get_uint (value); + break; + case ENCODER_H264_FEI_PROP_MIN_QP: + encoder->min_qp = g_value_get_uint (value); + break; + case ENCODER_H264_FEI_PROP_NUM_SLICES: + encoder->num_slices = g_value_get_uint (value); + break; + case ENCODER_H264_FEI_PROP_CABAC: + encoder->use_cabac = g_value_get_boolean (value); + break; + case ENCODER_H264_FEI_PROP_DCT8X8: + encoder->use_dct8x8 = g_value_get_boolean (value); + break; + case ENCODER_H264_FEI_PROP_CPB_LENGTH: + encoder->cpb_length = g_value_get_uint (value); + break; + case ENCODER_H264_FEI_PROP_NUM_VIEWS: + encoder->num_views = g_value_get_uint (value); + break; + case ENCODER_H264_FEI_PROP_VIEW_IDS: + set_view_ids (encoder, value); + break; + case ENCODER_H264_PROP_FEI_DISABLE: + encoder->is_fei_disabled = g_value_get_boolean (value); + if (!encoder->is_fei_disabled) + encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI; + break; + case ENCODER_H264_PROP_NUM_MV_PREDICT_L0: + encoder->num_mv_predictors_l0 = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_NUM_MV_PREDICT_L1: + encoder->num_mv_predictors_l1 = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_SEARCH_WINDOW: + encoder->search_window = g_value_get_enum (value); + break; + case ENCODER_H264_PROP_LEN_SP: + encoder->len_sp = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_SEARCH_PATH: + encoder->search_path = g_value_get_enum (value); + break; + case ENCODER_H264_PROP_REF_WIDTH: + encoder->ref_width = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_REF_HEIGHT: + encoder->ref_height = g_value_get_uint (value); + break; + case ENCODER_H264_PROP_SUBMB_MASK: + encoder->submb_part_mask = g_value_get_flags (value); + break; + case ENCODER_H264_PROP_SUBPEL_MODE: + encoder->subpel_mode = g_value_get_enum (value); + break; + case ENCODER_H264_PROP_INTRA_PART_MASK: + encoder->intra_part_mask = g_value_get_flags (value); + break; + case ENCODER_H264_PROP_INTRA_SAD: + encoder->intra_sad = g_value_get_enum (value); + break; + case ENCODER_H264_PROP_INTER_SAD: + encoder->inter_sad = g_value_get_enum (value); + break; + case ENCODER_H264_PROP_ADAPT_SEARCH: + encoder->adaptive_search = g_value_get_boolean (value) ? 1 : 0; + break; + case ENCODER_H264_PROP_MULTI_PRED_L0: + encoder->multi_predL0 = g_value_get_boolean (value) ? 1 : 0; + break; + case ENCODER_H264_PROP_MULTI_PRED_L1: + encoder->multi_predL1 = g_value_get_boolean (value) ? 1 : 0; + break; + case ENCODER_H264_PROP_ENABLE_STATS_OUT: + encoder->is_stats_out_enabled = g_value_get_boolean (value); + break; + case ENCODER_H264_PROP_FEI_MODE: + encoder->fei_mode = g_value_get_flags (value); + if (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC) { + g_warning ("============= ENC only mode selected ============ \n" + "We internally run the PAK stage because, the ENC operation requires the reconstructed output of PAK mode. Right now we have no infrastructure to provide reconstructed surfaces to ENC with out running the PAK \n"); + /*Fixme: Support ENC only mode with out running PAK */ + encoder->fei_mode = GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK; + } else if (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK) { + g_warning ("============ PAK only mode selected ============ \n" + "This mode can work as expected, only if there is a custom user specific upstream element which provides mb_code and mv_vectors. If you are running the pipeline only for verification, We recommand to use the fei-mod ENC+PAK which will run the ENC operation and generate what ever input needed for PAK \n"); + } + + break; + case ENCODER_H264_FEI_PROP_MAX_QP: + encoder->max_qp = g_value_get_uint (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } + + if ((prop_id != ENCODER_H264_PROP_FEI_MODE) && + (prop_id != ENCODER_H264_PROP_FEI_DISABLE) && + (prop_id != ENCODER_H264_PROP_ENABLE_STATS_OUT)) { + + if (enc_base_encoder) { + g_object_set_property ((GObject *) enc_base_encoder, + g_param_spec_get_name (pspec), value); + } + + if ((prop_id == ENCODER_H264_FEI_PROP_MAX_BFRAMES) || + (prop_id == ENCODER_H264_FEI_PROP_VIEW_IDS) || + (prop_id == ENCODER_H264_FEI_PROP_NUM_VIEWS)) { + if (encoder->feipak) { + status = + gst_vaapi_feipak_h264_set_property (encoder->feipak, prop_id, + value); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { + GST_ERROR ("failed to set pak property"); + return; + } + } + } + } +} + +static void +gst_vaapi_encoder_h264_fei_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiEncoderH264Fei *const encoder = + GST_VAAPI_ENCODER_H264_FEI_CAST (object); + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); + + switch (prop_id) { + case ENCODER_H264_FEI_PROP_RATECONTROL: + g_value_set_enum (value, base_encoder->rate_control); + break; + case ENCODER_H264_FEI_PROP_TUNE: + g_value_set_enum (value, base_encoder->tune); + break; + case ENCODER_H264_FEI_PROP_MAX_BFRAMES: + g_value_set_uint (value, encoder->num_bframes); + break; + case ENCODER_H264_FEI_PROP_INIT_QP: + g_value_set_uint (value, encoder->init_qp); + break; + case ENCODER_H264_FEI_PROP_MIN_QP: + g_value_set_uint (value, encoder->min_qp); + break; + case ENCODER_H264_FEI_PROP_NUM_SLICES: + g_value_set_uint (value, encoder->num_slices); + break; + case ENCODER_H264_FEI_PROP_CABAC: + g_value_set_boolean (value, encoder->use_cabac); + break; + case ENCODER_H264_FEI_PROP_DCT8X8: + g_value_set_boolean (value, encoder->use_dct8x8); + break; + case ENCODER_H264_FEI_PROP_CPB_LENGTH: + g_value_set_uint (value, encoder->cpb_length); + break; + case ENCODER_H264_FEI_PROP_NUM_VIEWS: + g_value_set_uint (value, encoder->num_views); + break; + case ENCODER_H264_FEI_PROP_VIEW_IDS: + // TODO: + //get_view_ids (encoder, value); + break; + case ENCODER_H264_PROP_FEI_DISABLE: + g_value_set_boolean (value, encoder->is_fei_disabled); + break; + case ENCODER_H264_PROP_NUM_MV_PREDICT_L0: + g_value_set_uint (value, encoder->num_mv_predictors_l0); + break; + case ENCODER_H264_PROP_NUM_MV_PREDICT_L1: + g_value_set_uint (value, encoder->num_mv_predictors_l1); + break; + case ENCODER_H264_PROP_SEARCH_WINDOW: + g_value_set_enum (value, encoder->search_window); + break; + case ENCODER_H264_PROP_LEN_SP: + g_value_set_uint (value, encoder->len_sp); + break; + case ENCODER_H264_PROP_SEARCH_PATH: + g_value_set_enum (value, encoder->search_path); + break; + case ENCODER_H264_PROP_REF_WIDTH: + g_value_set_uint (value, encoder->ref_width); + break; + case ENCODER_H264_PROP_REF_HEIGHT: + g_value_set_uint (value, encoder->ref_height); + break; + case ENCODER_H264_PROP_SUBMB_MASK: + g_value_set_flags (value, encoder->submb_part_mask); + break; + case ENCODER_H264_PROP_SUBPEL_MODE: + g_value_set_enum (value, encoder->subpel_mode); + break; + case ENCODER_H264_PROP_INTRA_PART_MASK: + g_value_set_flags (value, encoder->intra_part_mask); + break; + case ENCODER_H264_PROP_INTRA_SAD: + g_value_set_enum (value, encoder->intra_sad); + break; + case ENCODER_H264_PROP_INTER_SAD: + g_value_set_enum (value, encoder->inter_sad); + break; + case ENCODER_H264_PROP_ADAPT_SEARCH: + g_value_set_boolean (value, encoder->adaptive_search); + break; + case ENCODER_H264_PROP_MULTI_PRED_L0: + g_value_set_boolean (value, encoder->multi_predL0); + break; + case ENCODER_H264_PROP_MULTI_PRED_L1: + g_value_set_boolean (value, encoder->multi_predL1); + break; + case ENCODER_H264_PROP_ENABLE_STATS_OUT: + g_value_set_boolean (value, encoder->is_stats_out_enabled); + break; + case ENCODER_H264_PROP_FEI_MODE: + g_value_set_flags (value, encoder->fei_mode); + break; + case ENCODER_H264_FEI_PROP_MAX_QP: + g_value_set_uint (value, encoder->max_qp); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} static inline gboolean context_get_attribute (GstVaapiContext * context, VAConfigAttribType type, @@ -4020,11 +4324,380 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) encoder_class->reordering = gst_vaapi_encoder_h264_fei_reordering; encoder_class->encode = gst_vaapi_encoder_h264_fei_encode; encoder_class->flush = gst_vaapi_encoder_h264_fei_flush; - encoder_class->set_property = gst_vaapi_encoder_h264_fei_set_property; + encoder_class->set_property = _gst_vaapi_encoder_h264_fei_set_property; encoder_class->get_codec_data = gst_vaapi_encoder_h264_fei_get_codec_data; encoder_class->ensure_secondary_context = gst_vaapi_encoder_h264_fei_ensure_secondary_context; + + object_class->set_property = gst_vaapi_encoder_h264_fei_set_property; + object_class->get_property = gst_vaapi_encoder_h264_fei_get_property; object_class->finalize = gst_vaapi_encoder_h264_fei_finalize; + + /** + * GstVaapiEncoderH264Fei:rate-control: + * + * The desired rate control mode, expressed as a #GstVaapiRateControl. + */ + properties[ENCODER_H264_FEI_PROP_RATECONTROL] = + g_param_spec_enum ("rate-control", "Rate Control", "Rate control mode", + fei_encoder_class_data.rate_control_get_type (), + fei_encoder_class_data.default_rate_control, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264Fei:tune: + * + * The desired encoder tuning option. + */ + properties[ENCODER_H264_FEI_PROP_TUNE] = + g_param_spec_enum ("tune", + "Encoder Tuning", + "Encoder tuning option", + fei_encoder_class_data.encoder_tune_get_type (), + fei_encoder_class_data.default_encoder_tune, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264Fei:max-bframes: + * + * The number of B-frames between I and P. + */ + properties[ENCODER_H264_FEI_PROP_MAX_BFRAMES] = + g_param_spec_uint ("max-bframes", + "Max B-Frames", "Number of B-frames between I and P", 0, 10, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264Fei:init-qp: + * + * The initial quantizer value. + */ + properties[ENCODER_H264_FEI_PROP_INIT_QP] = + g_param_spec_uint ("init-qp", + "Initial QP", "Initial quantizer value", 0, 51, 26, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264Fei:min-qp: + * + * The minimum quantizer value. + */ + properties[ENCODER_H264_FEI_PROP_MIN_QP] = + g_param_spec_uint ("min-qp", + "Minimum QP", "Minimum quantizer value", 0, 51, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264Fei:max-qp: + * + * The maximum quantizer value. + * + * Since: 1.18 + */ + properties[ENCODER_H264_FEI_PROP_MAX_QP] = + g_param_spec_uint ("max-qp", + "Maximum QP", "Maximum quantizer value", 0, 51, 51, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264Fei:num-slices: + * + * The number of slices per frame. + */ + properties[ENCODER_H264_FEI_PROP_NUM_SLICES] = + g_param_spec_uint ("num-slices", + "Number of Slices", + "Number of slices per frame", + 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264Fei:cabac: + * + * Enable CABAC entropy coding mode for improved compression ratio, + * at the expense that the minimum target profile is Main. Default + * is CAVLC entropy coding mode. + */ + properties[ENCODER_H264_FEI_PROP_CABAC] = + g_param_spec_boolean ("cabac", + "Enable CABAC", + "Enable CABAC entropy coding mode", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264Fei:dct8x8: + * + * Enable adaptive use of 8x8 transforms in I-frames. This improves + * the compression ratio by the minimum target profile is High. + * Default is to use 4x4 DCT only. + */ + properties[ENCODER_H264_FEI_PROP_DCT8X8] = + g_param_spec_boolean ("dct8x8", + "Enable 8x8 DCT", + "Enable adaptive use of 8x8 transforms in I-frames", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264Fei:cpb-length: + * + * The size of the CPB buffer in milliseconds. + */ + properties[ENCODER_H264_FEI_PROP_CPB_LENGTH] = + g_param_spec_uint ("cpb-length", + "CPB Length", "Length of the CPB buffer in milliseconds", + 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264Fei:num-views: + * + * The number of views for MVC encoding . + */ + properties[ENCODER_H264_FEI_PROP_NUM_VIEWS] = + g_param_spec_uint ("num-views", + "Number of Views", + "Number of Views for MVC encoding", + 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiEncoderH264Fei:view-ids: + * + * The view ids for MVC encoding . + */ + properties[ENCODER_H264_FEI_PROP_VIEW_IDS] = + gst_param_spec_array ("view-ids", + "View IDs", "Set of View Ids used for MVC encoding", + g_param_spec_uint ("view-id-value", "View id value", + "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264: disable-fei: + * + * Disable FEI mode Encode: disabling fei will results + * the encoder to use VAEntrypointEncSlice, which means + * vaapi-intel-driver will be using a different media kerenl. + * And most of the properties associated with this element + * will be non functional. + */ + properties[ENCODER_H264_PROP_FEI_DISABLE] = + g_param_spec_boolean ("disable-fei", + "Disable FEI Mode Encode", + "Disable Flexible Encoding Infrasturcture", FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + + /** + * GstVaapiEncoderH264: stats-out: + * + * Enable outputting fei buffers MV, MBCode and Distortion. + * If enabled, encoder will allocate memory for these buffers + * and submit to the driver even for ENC_PAK mode so that + * the output data can be extraced for analysis after the + * complettion of each frame ncode + */ + properties[ENCODER_H264_PROP_ENABLE_STATS_OUT] = + g_param_spec_boolean ("stats-out", + "stats out", + "Enable stats out for fei", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:num_mv_predictors_l0: + * Indicate how many mv predictors should be used for l0 frames. + * Only valid if MVPredictor input has been enabled. + */ + properties[ENCODER_H264_PROP_NUM_MV_PREDICT_L0] = + g_param_spec_uint ("num-mvpredict-l0", + "Num mv predict l0", + "Indicate how many predictors should be used for l0," + "only valid if MVPredictor input enabled", + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiEncoderH264:num_mv_predictors_l1: + * Indicate how many mv predictors should be used for l1 frames. + * Only valid if MVPredictor input has been enabled. + * + */ + properties[ENCODER_H264_PROP_NUM_MV_PREDICT_L1] = + g_param_spec_uint ("num-mvpredict-l1", + "Num mv predict l1", + "Indicate how many predictors should be used for l1," + "only valid if MVPredictor input enabled", + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiEncoderH264:search-window: + * Use predefined Search Window + */ + properties[ENCODER_H264_PROP_SEARCH_WINDOW] = + g_param_spec_enum ("search-window", + "search window", + "Specify one of the predefined search path", + GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, + GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:len-sp: + * Defines the maximum number of Search Units per reference. + */ + properties[ENCODER_H264_PROP_LEN_SP] = + g_param_spec_uint ("len-sp", + "length of search path", + "This value defines number of search units in search path", + 1, 63, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:search-path: + * SearchPath defines the motion search method. + * Zero means full search, 1 indicate diamond search. + */ + properties[ENCODER_H264_PROP_SEARCH_PATH] = + g_param_spec_enum ("search-path", + "search path", + "Specify search path", + GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, + GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:ref-width: + * Specifies the search region width in pixels. + */ + properties[ENCODER_H264_PROP_REF_WIDTH] = + g_param_spec_uint ("ref-width", + "ref width", + "Width of search region in pixel, must be multiple of 4", + 4, 64, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:ref-height: + * Specifies the search region height in pixels. + */ + properties[ENCODER_H264_PROP_REF_HEIGHT] = + g_param_spec_uint ("ref-height", + "ref height", + "Height of search region in pixel, must be multiple of 4", + 4, 32, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiEncoderH264:submb-mask: + * Defines the bit-mask for disabling sub-partition + * + */ + properties[ENCODER_H264_PROP_SUBMB_MASK] = + g_param_spec_flags ("submbpart-mask", + "submb part mask", + "defines the bit-mask for disabling sub mb partition", + GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, + GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:subpel-mode: + * defines the half/quarter pel modes + * 00: integer mode searching + * 01: half-pel mode searching + * 11: quarter-pel mode searching + */ + properties[ENCODER_H264_PROP_SUBPEL_MODE] = + g_param_spec_enum ("subpel-mode", + "subpel mode", + "Sub pixel precision for motion estimation", + GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, + GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiEncoderH264:intrapart-mask: + * Specifies which Luma Intra partition is enabled/disabled + * for intra mode decision + */ + properties[ENCODER_H264_PROP_INTRA_PART_MASK] = + g_param_spec_flags ("intrapart-mask", + "intra part mask", + "Specifies which Luma Intra partition is enabled/disabled for" + "intra mode decision", + GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, + GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:intra-sad: + * Specifies distortion measure adjustments used for + * the motion search SAD comparison. + */ + properties[ENCODER_H264_PROP_INTRA_SAD] = + g_param_spec_enum ("intra-sad", + "intra sad", + "Specifies distortion measure adjustments used" + "in the motion search SAD comparison for intra MB", + GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:inter-sad: + * Specifies distortion measure adjustments used + * in the motion search SAD comparison for inter MB + */ + properties[ENCODER_H264_PROP_INTER_SAD] = + g_param_spec_enum ("inter-sad", + "inter sad", + "Specifies distortion measure adjustments used" + "in the motion search SAD comparison for inter MB", + GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:adaptive-search: + * Defines whether adaptive searching is enabled for IME + */ + properties[ENCODER_H264_PROP_ADAPT_SEARCH] = + g_param_spec_boolean ("adaptive-search", + "adaptive-search", + "Enable adaptive search", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiEncoderH264:multi-predL0: + * When set to 1, neighbor MV will be used as predictor for list L0, + * otherwise no neighbor MV will be used as predictor + */ + properties[ENCODER_H264_PROP_MULTI_PRED_L0] = + g_param_spec_boolean ("multi-predL0", + "multi predL0", + "Enable multi prediction for ref L0 list, when set neighbor MV will be used" + "as predictor, no neighbor MV will be used otherwise", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264:multi-predL1: + * When set to 1, neighbor MV will be used as predictor + * when set to 0, no neighbor MV will be used as predictor. + */ + properties[ENCODER_H264_PROP_MULTI_PRED_L1] = + g_param_spec_boolean ("multi-predL1", + "multi predL1", + "Enable multi prediction for ref L1 list, when set neighbor MV will be used" + "as predictor, no neighbor MV will be used otherwise", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * GstVaapiEncoderH264Fei: fei-mode: + * + * Cose ENC, PAK, ENC_PAK, or ENC+PAK + * ENC: Only the Motion Estimation, no transformation or entropy coding + * PAK: transformation, quantization and entropy coding + * ENC_PAK: default mode, enc an pak are invoked by driver, middleware has + control over ENC input only + * ENC+PAK: enc and pak invoked separately, middleware has control over the ENC input, + ENC output, and PAK input + * Encoding mode which can be used for FEI + */ + properties[ENCODER_H264_PROP_FEI_MODE] = + g_param_spec_flags ("fei-mode", + "FEI Encoding Mode", + "Functional mode of FEI Encoding", + GST_VAAPI_TYPE_FEI_MODE, GST_VAAPI_FEI_MODE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, + ENCODER_H264_FEI_N_PROPERTIES, properties); } /** From bc2f8fd19e924aa0e193708307326acd037691ce Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 30 Aug 2019 18:39:32 +0800 Subject: [PATCH 3344/3781] libs: encoder: add flags to all encoder properties. G_PARAM_CONSTRUCT make all properties init correctly, we do not need to init the properties manually. G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE is a vaapi encoder specific flag, means need to expose the property to according encode class. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 22 +++-- gst-libs/gst/vaapi/gstvaapiencoder.h | 5 + gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 70 ++++++++++---- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 96 +++++++++++++------ gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 43 ++++++--- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 10 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 12 ++- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 18 +++- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 27 ++++-- gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 87 +++++++++++------ 10 files changed, 272 insertions(+), 118 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 9a881560c6..bd56b8af21 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1803,7 +1803,9 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) g_param_spec_uint ("bitrate", "Bitrate (kbps)", "The desired bitrate expressed in kbps (0: auto-calculate)", - 0, 2000 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 0, 2000 * 1024, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoder:target-percentage: @@ -1814,7 +1816,9 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) g_param_spec_uint ("target-percentage", "Target Percentage", "The desired target percentage of bitrate for variable rate " - "controls.", 1, 100, 70, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + "controls.", 1, 100, 70, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoder:keyframe-period: @@ -1825,7 +1829,9 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) g_param_spec_uint ("keyframe-period", "Keyframe Period", "Maximal distance between two keyframes (0: auto-calculate)", 0, - G_MAXUINT32, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_MAXUINT32, 30, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoder:quality-level: @@ -1837,7 +1843,8 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) "Quality Level", "Encoding Quality Level " "(lower value means higher-quality/slow-encode, " " higher value means lower-quality/fast-encode)", - 1, 7, 4, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 7, 4, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVapiEncoder:roi-default-delta-qp @@ -1849,7 +1856,9 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) "The default delta-qp to apply to each Region of Interest" "(lower value means higher-quality, " "higher value means lower-quality)", - -10, 10, -10, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + -10, 10, -10, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoder: trellis: @@ -1862,7 +1871,8 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) g_param_spec_boolean ("trellis", "Trellis Quantization", "The Trellis Quantization Method of Encoder", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 69eb1c9527..98c6bc1ad6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -41,6 +41,11 @@ typedef struct _GstVaapiEncoder GstVaapiEncoder; GType gst_vaapi_encoder_get_type (void) G_GNUC_CONST; +/* This user defined flag is added when the internal encoder + class wants to expose its property gparam spec to the according + encode class. */ +#define G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE (1 << 29) + /** * GstVaapiEncoderStatus: * @GST_VAAPI_ENCODER_STATUS_SUCCESS: Success. diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index dd6a3a01a5..22ac7d239e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3836,7 +3836,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:tune: @@ -3849,7 +3850,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:max-bframes: @@ -3859,7 +3861,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) properties[ENCODER_H264_PROP_MAX_BFRAMES] = g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:refs: @@ -3870,7 +3873,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) properties[ENCODER_H264_PROP_NUM_REF_FRAMES] = g_param_spec_uint ("refs", "Number of Reference Frames", "Number of reference frames", 1, 8, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:init-qp: @@ -3880,7 +3884,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) properties[ENCODER_H264_PROP_INIT_QP] = g_param_spec_uint ("init-qp", "Initial QP", "Initial quantizer value", 0, 51, 26, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:min-qp: @@ -3890,7 +3895,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) properties[ENCODER_H264_PROP_MIN_QP] = g_param_spec_uint ("min-qp", "Minimum QP", "Minimum quantizer value", 0, 51, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:max-qp: @@ -3902,7 +3908,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) properties[ENCODER_H264_PROP_MAX_QP] = g_param_spec_uint ("max-qp", "Maximum QP", "Maximum quantizer value", 0, 51, 51, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:qp-ip: @@ -3914,7 +3921,9 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_int ("qp-ip", "Difference of QP between I and P frame", "Difference of QP between I and P frame (available only on CQP)", - -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + -51, 51, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:qp-ib: @@ -3926,7 +3935,9 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_int ("qp-ib", "Difference of QP between I and B frame", "Difference of QP between I and B frame (available only on CQP)", - -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + -51, 51, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:num-slices: @@ -3937,7 +3948,9 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_uint ("num-slices", "Number of Slices", "Number of slices per frame", - 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 200, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:cabac: @@ -3950,7 +3963,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_boolean ("cabac", "Enable CABAC", "Enable CABAC entropy coding mode", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:dct8x8: @@ -3963,7 +3977,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_boolean ("dct8x8", "Enable 8x8 DCT", "Enable adaptive use of 8x8 transforms in I-frames", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:mbbrc: @@ -3976,7 +3991,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "Macroblock level Bitrate Control", "Macroblock level Bitrate Control", GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:temporal-levels: @@ -3988,7 +4004,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "temporal levels", "Number of temporal levels in the encoded stream ", MIN_TEMPORAL_LEVELS, MAX_TEMPORAL_LEVELS, MIN_TEMPORAL_LEVELS, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:prediction-type: @@ -4001,7 +4018,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "Reference Picture Selection Modes", gst_vaapi_encoder_h264_prediction_type (), GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:cpb-length: @@ -4011,7 +4029,9 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) properties[ENCODER_H264_PROP_CPB_LENGTH] = g_param_spec_uint ("cpb-length", "CPB Length", "Length of the CPB buffer in milliseconds", - 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 10000, DEFAULT_CPB_LENGTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:num-views: @@ -4022,7 +4042,9 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_uint ("num-views", "Number of Views", "Number of Views for MVC encoding", - 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, MAX_NUM_VIEWS, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:view-ids: @@ -4035,7 +4057,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_uint ("view-id-value", "View id value", "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:aud: @@ -4057,9 +4080,12 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) properties[ENCODER_H264_PROP_COMPLIANCE_MODE] = g_param_spec_enum ("compliance-mode", "Spec Compliance Mode", - "Tune Encode quality/performance by relaxing specification compliance restrictions", + "Tune Encode quality/performance by relaxing specification" + " compliance restrictions", gst_vaapi_encoder_h264_compliance_mode_type (), - GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT, G_PARAM_READWRITE); + GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:quality_factor: @@ -4071,7 +4097,9 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "Quality factor for ICQ/QVBR", "quality factor for ICQ/QVBR bitrate control mode" "(low value means higher-quality, higher value means lower-quality)", - 1, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 51, 26, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_H264_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index dab9d9dbc4..dc7b06869b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -4342,7 +4342,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_enum ("rate-control", "Rate Control", "Rate control mode", fei_encoder_class_data.rate_control_get_type (), fei_encoder_class_data.default_rate_control, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:tune: @@ -4355,7 +4356,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Encoder tuning option", fei_encoder_class_data.encoder_tune_get_type (), fei_encoder_class_data.default_encoder_tune, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:max-bframes: @@ -4365,7 +4367,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) properties[ENCODER_H264_FEI_PROP_MAX_BFRAMES] = g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", 0, 10, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:init-qp: @@ -4375,7 +4378,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) properties[ENCODER_H264_FEI_PROP_INIT_QP] = g_param_spec_uint ("init-qp", "Initial QP", "Initial quantizer value", 0, 51, 26, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:min-qp: @@ -4385,7 +4389,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) properties[ENCODER_H264_FEI_PROP_MIN_QP] = g_param_spec_uint ("min-qp", "Minimum QP", "Minimum quantizer value", 0, 51, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:max-qp: @@ -4397,7 +4402,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) properties[ENCODER_H264_FEI_PROP_MAX_QP] = g_param_spec_uint ("max-qp", "Maximum QP", "Maximum quantizer value", 0, 51, 51, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:num-slices: @@ -4408,7 +4414,9 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_uint ("num-slices", "Number of Slices", "Number of slices per frame", - 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 200, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:cabac: @@ -4421,7 +4429,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_boolean ("cabac", "Enable CABAC", "Enable CABAC entropy coding mode", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:dct8x8: @@ -4434,7 +4443,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_boolean ("dct8x8", "Enable 8x8 DCT", "Enable adaptive use of 8x8 transforms in I-frames", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:cpb-length: @@ -4444,7 +4454,9 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) properties[ENCODER_H264_FEI_PROP_CPB_LENGTH] = g_param_spec_uint ("cpb-length", "CPB Length", "Length of the CPB buffer in milliseconds", - 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 10000, DEFAULT_CPB_LENGTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:num-views: @@ -4455,7 +4467,9 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_uint ("num-views", "Number of Views", "Number of Views for MVC encoding", - 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, MAX_NUM_VIEWS, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:view-ids: * @@ -4467,7 +4481,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_uint ("view-id-value", "View id value", "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264: disable-fei: @@ -4482,7 +4497,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_boolean ("disable-fei", "Disable FEI Mode Encode", "Disable Flexible Encoding Infrasturcture", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** @@ -4498,7 +4514,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_boolean ("stats-out", "stats out", "Enable stats out for fei", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:num_mv_predictors_l0: @@ -4510,7 +4527,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Num mv predict l0", "Indicate how many predictors should be used for l0," "only valid if MVPredictor input enabled", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:num_mv_predictors_l1: * Indicate how many mv predictors should be used for l1 frames. @@ -4522,7 +4540,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Num mv predict l1", "Indicate how many predictors should be used for l1," "only valid if MVPredictor input enabled", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:search-window: * Use predefined Search Window @@ -4533,7 +4552,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Specify one of the predefined search path", GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:len-sp: @@ -4543,7 +4563,9 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_uint ("len-sp", "length of search path", "This value defines number of search units in search path", - 1, 63, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 63, 32, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:search-path: @@ -4556,7 +4578,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Specify search path", GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:ref-width: @@ -4566,7 +4589,9 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_uint ("ref-width", "ref width", "Width of search region in pixel, must be multiple of 4", - 4, 64, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 4, 64, 32, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:ref-height: @@ -4576,7 +4601,9 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_uint ("ref-height", "ref height", "Height of search region in pixel, must be multiple of 4", - 4, 32, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 4, 32, 32, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:submb-mask: * Defines the bit-mask for disabling sub-partition @@ -4588,7 +4615,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "defines the bit-mask for disabling sub mb partition", GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:subpel-mode: @@ -4603,7 +4631,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Sub pixel precision for motion estimation", GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:intrapart-mask: * Specifies which Luma Intra partition is enabled/disabled @@ -4616,7 +4645,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "intra mode decision", GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:intra-sad: @@ -4629,7 +4659,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Specifies distortion measure adjustments used" "in the motion search SAD comparison for intra MB", GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:inter-sad: @@ -4642,7 +4673,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Specifies distortion measure adjustments used" "in the motion search SAD comparison for inter MB", GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:adaptive-search: @@ -4652,7 +4684,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_boolean ("adaptive-search", "adaptive-search", "Enable adaptive search", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:multi-predL0: * When set to 1, neighbor MV will be used as predictor for list L0, @@ -4663,7 +4696,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "multi predL0", "Enable multi prediction for ref L0 list, when set neighbor MV will be used" "as predictor, no neighbor MV will be used otherwise", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:multi-predL1: @@ -4675,7 +4709,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "multi predL1", "Enable multi prediction for ref L1 list, when set neighbor MV will be used" "as predictor, no neighbor MV will be used otherwise", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei: fei-mode: @@ -4694,7 +4729,8 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "FEI Encoding Mode", "Functional mode of FEI Encoding", GST_VAAPI_TYPE_FEI_MODE, GST_VAAPI_FEI_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_H264_FEI_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 1d99f8ece3..f17f2b8833 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2894,7 +2894,8 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:tune: @@ -2907,7 +2908,8 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:max-bframes: @@ -2917,7 +2919,8 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) properties[ENCODER_H265_PROP_MAX_BFRAMES] = g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:refs: @@ -2928,7 +2931,8 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) properties[ENCODER_H265_PROP_NUM_REF_FRAMES] = g_param_spec_uint ("refs", "Number of Reference Frames", "Number of reference frames", 1, 3, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:init-qp: @@ -2938,7 +2942,8 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) properties[ENCODER_H265_PROP_INIT_QP] = g_param_spec_uint ("init-qp", "Initial QP", "Initial quantizer value", 0, 51, 26, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:min-qp: @@ -2948,7 +2953,8 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) properties[ENCODER_H265_PROP_MIN_QP] = g_param_spec_uint ("min-qp", "Minimum QP", "Minimum quantizer value", 0, 51, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:max-qp: @@ -2960,7 +2966,8 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) properties[ENCODER_H265_PROP_MAX_QP] = g_param_spec_uint ("max-qp", "Maximum QP", "Maximum quantizer value", 0, 51, 51, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:qp-ip: @@ -2972,7 +2979,9 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_param_spec_int ("qp-ip", "Difference of QP between I and P frame", "Difference of QP between I and P frame (available only on CQP)", - -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + -51, 51, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:qp-ib: @@ -2984,7 +2993,9 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_param_spec_int ("qp-ib", "Difference of QP between I and B frame", "Difference of QP between I and B frame (available only on CQP)", - -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + -51, 51, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /* FIXME: there seems to be issues with multi-slice encoding */ /** @@ -2996,7 +3007,9 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_param_spec_uint ("num-slices", "Number of Slices", "Number of slices per frame", - 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 200, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:cpb-length: @@ -3006,7 +3019,9 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) properties[ENCODER_H265_PROP_CPB_LENGTH] = g_param_spec_uint ("cpb-length", "CPB Length", "Length of the CPB buffer in milliseconds", - 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 10000, DEFAULT_CPB_LENGTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:mbbrc: @@ -3019,7 +3034,8 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) "Macroblock level Bitrate Control", "Macroblock level Bitrate Control", GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:low_delay_b: @@ -3031,7 +3047,8 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) "Enable low delay b", "Transforms P frames into predictive B frames." " Enable it when P frames are not supported.", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_H265_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 674164bf76..2848370c81 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -871,7 +871,8 @@ gst_vaapi_encoder_jpeg_class_init (GstVaapiEncoderJpegClass * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); properties[ENCODER_JPEG_PROP_TUNE] = g_param_spec_enum ("tune", @@ -879,12 +880,15 @@ gst_vaapi_encoder_jpeg_class_init (GstVaapiEncoderJpegClass * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_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); + "Quality factor", 0, 100, 50, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_JPEG_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 3a354b00ba..44c0baca7a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -910,7 +910,8 @@ gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderMpeg2:tune: @@ -923,18 +924,21 @@ gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); properties[ENCODER_MPEG2_PROP_QUANTIZER] = g_param_spec_uint ("quantizer", "Constant Quantizer", "Constant quantizer (if rate-control mode is CQP)", - 2, 62, 8, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 2, 62, 8, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); properties[ENCODER_MPEG2_PROP_MAX_BFRAMES] = g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", 0, 16, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_MPEG2_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 17b52ef015..2af6024d8d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -667,23 +667,29 @@ gst_vaapi_encoder_vp8_class_init (GstVaapiEncoderVP8Class * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_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); + DEFAULT_LOOP_FILTER_LEVEL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_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); + DEFAULT_SHARPNESS_LEVEL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); properties[ENCODER_VP8_PROP_YAC_Q_INDEX] = g_param_spec_uint ("yac-qi", @@ -691,7 +697,9 @@ gst_vaapi_encoder_vp8_class_init (GstVaapiEncoderVP8Class * klass) "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); + 0, 127, DEFAULT_YAC_QI, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_VP8_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 16be27804e..663978670f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -427,8 +427,8 @@ update_ref_list (GstVaapiEncoderVP9 * encoder, GstVaapiEncPicture * picture, gst_vaapi_surface_proxy_unref (ref); break; case GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_1: - gst_vaapi_surface_proxy_replace (&encoder-> - ref_list[encoder->ref_list_idx], ref); + gst_vaapi_surface_proxy_replace (&encoder->ref_list[encoder-> + ref_list_idx], ref); gst_vaapi_surface_proxy_unref (ref); encoder->ref_list_idx = (encoder->ref_list_idx + 1) % GST_VP9_REF_FRAMES; break; @@ -709,7 +709,8 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); properties[ENCODER_VP9_PROP_TUNE] = g_param_spec_enum ("tune", @@ -717,27 +718,32 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_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); + 0, 255, DEFAULT_YAC_QINDEX, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); properties[ENCODER_VP9_PROP_REF_PIC_MODE] = g_param_spec_enum ("ref-pic-mode", @@ -745,7 +751,8 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) "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_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiEncoderVP9:cpb-length: @@ -757,7 +764,9 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) 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); + 1, 10000, DEFAULT_CPB_LENGTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_VP9_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index a15a192c84..0816bf96c2 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -2126,7 +2126,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Rate Control", "Rate control mode", fei_enc_class_data.rate_control_get_type (), fei_enc_class_data.default_rate_control, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:tune: @@ -2139,7 +2140,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Encoder tuning option", fei_enc_class_data.encoder_tune_get_type (), fei_enc_class_data.default_encoder_tune, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:max-bframes: @@ -2149,7 +2151,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) properties[FEI_H264_ENC_PROP_MAX_BFRAMES] = g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:init-qp: @@ -2159,7 +2162,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) properties[FEI_H264_ENC_PROP_INIT_QP] = g_param_spec_uint ("init-qp", "Initial QP", "Initial quantizer value", 1, 51, 26, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:min-qp: @@ -2169,7 +2173,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) properties[FEI_H264_ENC_PROP_MIN_QP] = g_param_spec_uint ("min-qp", "Minimum QP", "Minimum quantizer value", 1, 51, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:num-slices: @@ -2180,7 +2185,9 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("num-slices", "Number of Slices", "Number of slices per frame", - 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 200, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:cabac: @@ -2193,7 +2200,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_boolean ("cabac", "Enable CABAC", "Enable CABAC entropy coding mode", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:dct8x8: @@ -2206,7 +2214,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_boolean ("dct8x8", "Enable 8x8 DCT", "Enable adaptive use of 8x8 transforms in I-frames", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:cpb-length: @@ -2216,7 +2225,9 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) properties[FEI_H264_ENC_PROP_CPB_LENGTH] = g_param_spec_uint ("cpb-length", "CPB Length", "Length of the CPB buffer in milliseconds", - 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 10000, DEFAULT_CPB_LENGTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:num-views: @@ -2227,7 +2238,9 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("num-views", "Number of Views", "Number of Views for MVC encoding", - 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, MAX_NUM_VIEWS, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:view-ids: * @@ -2239,7 +2252,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("view-id-value", "View id value", "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:num-ref: * @@ -2249,7 +2263,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("num-ref", "Num Ref", "reference frame number", - 1, 6, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 6, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:num_mv_predictors_l0: @@ -2260,7 +2275,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("num-mvpredict-l0", "Num mv predict l0", "Indicate how many predictors should be used for l0", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:num_mv_predictors_l1: * @@ -2270,7 +2286,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("num-mvpredict-l1", "Num mv predict l1", "Indicate how many predictors should be used for l1", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:search-window: */ @@ -2280,7 +2297,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Specify one of the predefined search path", GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:len-sp: */ @@ -2288,7 +2306,9 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("len-sp", "len sp", "This value defines number of search units in search path", - 1, 63, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 1, 63, 32, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:search-path: @@ -2299,7 +2319,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Specify search path", GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:ref-width: @@ -2308,7 +2329,9 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("ref-width", "ref width", "Width of search region in pixel, must be multiple of 4", - 4, 64, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 4, 64, 32, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:ref-height: @@ -2317,7 +2340,9 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("ref-height", "ref height", "Height of search region in pixel, must be multiple of 4", - 4, 32, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + 4, 32, 32, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:submb-mask: * Defines the bit-mask for disabling sub-partition @@ -2329,7 +2354,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "defines the bit-mask for disabling sub mb partition", GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:subpel-mode: @@ -2340,7 +2366,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Sub pixel precision for motion estimation", GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:intrapart-mask: */ @@ -2350,7 +2377,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "What block and sub-block partitions are disabled for intra MBs", GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:intra-sad: */ @@ -2359,7 +2387,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "intra sad", "Specifies distortion measure adjustments used in the motion search SAD comparison for intra MB", GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:inter-sad: @@ -2369,7 +2398,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "inter sad", "Specifies distortion measure adjustments used in the motion search SAD comparison for inter MB", GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:adaptive-search: @@ -2378,7 +2408,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_boolean ("adaptive-search", "adaptive-search", "Enable adaptive search", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:multi-predL0: @@ -2387,7 +2418,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_boolean ("multi-predL0", "multi predL0", "Enable multi prediction for ref L0 list", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:multi-predL0: @@ -2396,7 +2428,8 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_boolean ("multi-predL1", "multi predL1", "Enable multi prediction for ref L1 list", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, FEI_H264_ENC_N_PROPERTIES, properties); From 05643dadb5c8c45e347a162c5cdc6f1c8d2d1cb8 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 20 Aug 2019 22:16:35 +0800 Subject: [PATCH 3345/3781] gst: encode: add property help functions for encoder properties. The encoder is a true gstobject now and all the properties are using gobject's properties mechanism. Add help functions to handle the properties between encode and encoder class. The basic idea is mapping the same property between encoder and encode. All the encoder's properties will have the same name, the same type in encode. The set/get property function just forward the property setting/getting to the encoder using the same property name and value. Because the encoder is created on needed, we need to cache the property setting in encode. --- gst/vaapi/gstvaapiencode.c | 197 ++++++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapiencode.h | 17 +++- 2 files changed, 212 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 6ca10e3398..975fe49f30 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -104,7 +104,7 @@ gst_vaapiencode_src_query (GstVideoEncoder * encoder, GstQuery * query) typedef struct { - GstVaapiEncoderProp id; + guint id; GParamSpec *pspec; GValue value; } PropValue; @@ -158,6 +158,47 @@ prop_value_lookup (GstVaapiEncode * encode, guint prop_id) return NULL; } +static PropValue * +prop_value_new_entry (guint id, GParamSpec * pspec, const GValue * value) +{ + PropValue *prop_value; + + if (!pspec) + return NULL; + + prop_value = g_slice_new0 (PropValue); + if (!prop_value) + return NULL; + + prop_value->id = id; + prop_value->pspec = g_param_spec_ref (pspec); + g_value_init (&prop_value->value, pspec->value_type); + + g_assert (g_value_type_compatible (pspec->value_type, G_VALUE_TYPE (value))); + g_value_copy (value, &prop_value->value); + + return prop_value; +} + +static inline PropValue * +prop_value_lookup_entry (GPtrArray * prop_values, guint prop_id) +{ + guint i; + PropValue *prop_value; + + if (prop_values == NULL) + return NULL; + + for (i = 0; i < prop_values->len; i++) { + prop_value = g_ptr_array_index (prop_values, i); + if (prop_value->id == prop_id) + return prop_value; + } + + return NULL; +} + + static gboolean gst_vaapiencode_default_get_property (GstVaapiEncode * encode, guint prop_id, GValue * value) @@ -1007,3 +1048,157 @@ gst_vaapiencode_class_init_properties (GstVaapiEncodeClass * klass) g_ptr_array_unref (props); return TRUE; } + +/* Only used by the drived class */ +void +gst_vaapiencode_set_property_subclass (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (object); + PropValue *prop_value; + + if (prop_id <= PROP_BASE || prop_id >= encode_class->prop_num) { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + return; + } + + /* direct forward the property to encoder */ + if (encode->encoder) { + g_object_set_property ((GObject *) encode->encoder, + g_param_spec_get_name (pspec), value); + return; + } + + if (encode->prop_values) { + /* Delete the same prop already in cache */ + prop_value = prop_value_lookup_entry (encode->prop_values, prop_id); + if (prop_value) + g_ptr_array_remove (encode->prop_values, prop_value); + } else { + encode->prop_values = + g_ptr_array_new_with_free_func ((GDestroyNotify) prop_value_free); + } + + /* The encoder is delay created, we need to cache the property setting */ + prop_value = prop_value_new_entry (prop_id, pspec, value); + g_ptr_array_add (encode->prop_values, prop_value); +} + +/* Only used by the drived class */ +void +gst_vaapiencode_get_property_subclass (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); + GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (object); + PropValue *prop_value = NULL; + + if (prop_id <= PROP_BASE || prop_id >= encode_class->prop_num) { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + return; + } + + /* direct forward the property to encoder */ + if (encode->encoder) { + g_object_get_property ((GObject *) encode->encoder, + g_param_spec_get_name (pspec), value); + return; + } + + if (encode->prop_values) + prop_value = prop_value_lookup_entry (encode->prop_values, prop_id); + + if (prop_value) { + /* In the cache */ + g_value_copy (&prop_value->value, value); + } else { + /* set the default value */ + g_param_value_set_default (pspec, value); + } +} + +/* Called by drived class to install all properties. The encode base class + does not have any property, all the properties of the according encoderXXX + class are installed to encodeXXX class. */ +gboolean +gst_vaapiencode_class_install_properties (GstVaapiEncodeClass * klass, + GObjectClass * encoder_class) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + guint i, n_props, installed; + GParamSpec **specs = NULL; + GParamSpec *pspec; + GParamSpec *new_spec; + GParamFlags flags; + + if (encoder_class) + specs = g_object_class_list_properties (encoder_class, &n_props); + if (!specs) + return FALSE; + + installed = 0; + for (i = 0; i < n_props; i++) { + pspec = specs[i]; + + /* Encoder do not want to expose */ + if (!(pspec->flags & G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE)) + continue; + /* Can only set on encoder init time */ + if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) + continue; + + /* filter out the G_PARAM_CONSTRUCT, the encoder created later, no need + to set the init value in encode. + Also no G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE */ + flags = pspec->flags & (~(G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE | + G_PARAM_CONSTRUCT)); + + if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT) { + GParamSpecUInt *pspecuint = G_PARAM_SPEC_UINT (pspec); + new_spec = g_param_spec_uint (g_param_spec_get_name (pspec), + g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec), + pspecuint->minimum, pspecuint->maximum, + pspecuint->default_value, flags); + } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT) { + GParamSpecInt *pspecint = G_PARAM_SPEC_INT (pspec); + new_spec = g_param_spec_int (g_param_spec_get_name (pspec), + g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec), + pspecint->minimum, pspecint->maximum, pspecint->default_value, flags); + } else if (G_IS_PARAM_SPEC_ENUM (pspec)) { + GParamSpecEnum *pspecenum = G_PARAM_SPEC_ENUM (pspec); + new_spec = g_param_spec_enum (g_param_spec_get_name (pspec), + g_param_spec_get_nick (pspec), + g_param_spec_get_blurb (pspec), + pspec->value_type, pspecenum->default_value, flags); + } else if (G_IS_PARAM_SPEC_BOOLEAN (pspec)) { + GParamSpecBoolean *pspecbool = G_PARAM_SPEC_BOOLEAN (pspec); + new_spec = g_param_spec_boolean (g_param_spec_get_name (pspec), + g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec), + pspecbool->default_value, flags); + } else if (G_IS_PARAM_SPEC_FLAGS (pspec)) { + GParamSpecFlags *pspecflags = G_PARAM_SPEC_FLAGS (pspec); + new_spec = g_param_spec_flags (g_param_spec_get_name (pspec), + g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec), + pspec->value_type, pspecflags->default_value, flags); + } else if (GST_IS_PARAM_SPEC_ARRAY_LIST (pspec)) { + GstParamSpecArray *pspecarray = GST_PARAM_SPEC_ARRAY_LIST (pspec); + new_spec = gst_param_spec_array (g_param_spec_get_name (pspec), + g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec), + pspecarray->element_spec, flags); + } else { + GST_WARNING ("encoder's %s property has a unimplemented" + " type to expose to encode, the encode may lose the %s property", + g_param_spec_get_name (pspec), g_param_spec_get_name (pspec)); + continue; + } + + g_object_class_install_property (object_class, PROP_BASE + 1 + installed, + new_spec); + installed++; + } + + g_free (specs); + klass->prop_num = PROP_BASE + 1 + installed; + return TRUE; +} diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index b63828526c..742de05f7c 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -73,6 +73,7 @@ struct _GstVaapiEncodeClass /*< private >*/ GstVaapiPluginBaseClass parent_class; + guint prop_num; GPtrArray * (*get_properties) (void); gboolean (*get_property) (GstVaapiEncode * encode, guint prop_id, GValue * value); @@ -98,7 +99,6 @@ struct _GstVaapiEncodeClass GstVaapiCodedBufferProxy *proxy); #endif - }; GType @@ -112,6 +112,21 @@ G_GNUC_INTERNAL gboolean gst_vaapiencode_class_init_properties (GstVaapiEncodeClass * encode_class); +G_GNUC_INTERNAL +void +gst_vaapiencode_set_property_subclass (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); + +G_GNUC_INTERNAL +void +gst_vaapiencode_get_property_subclass (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +G_GNUC_INTERNAL +gboolean +gst_vaapiencode_class_install_properties (GstVaapiEncodeClass * klass, + GObjectClass * encoder_class); + G_END_DECLS #endif /* GST_VAAPIENCODE_H */ From 12566804860009a0041bceb8fbf93f4c2597b136 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 20 Aug 2019 23:56:33 +0800 Subject: [PATCH 3346/3781] gst: encode: enable new type of property mechanism. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 29 +++++++++--------- gst/vaapi/gstvaapiencode.c | 18 ++++++------ gst/vaapi/gstvaapiencode_h264.c | 43 +++++---------------------- gst/vaapi/gstvaapiencode_h264_fei.c | 44 +++++----------------------- gst/vaapi/gstvaapiencode_h265.c | 43 +++++---------------------- gst/vaapi/gstvaapiencode_jpeg.c | 43 +++++---------------------- gst/vaapi/gstvaapiencode_mpeg2.c | 43 +++++---------------------- gst/vaapi/gstvaapiencode_vp8.c | 43 +++++---------------------- gst/vaapi/gstvaapiencode_vp9.c | 43 +++++---------------------- 9 files changed, 79 insertions(+), 270 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index bd56b8af21..e3108e4984 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1547,8 +1547,8 @@ error_operation_failed: } /* Initialize default values for configurable properties */ -static void -gst_vaapi_encoder_constructed (GObject * object) +__attribute__ ((unused)) + static void gst_vaapi_encoder_constructed (GObject * object) { GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); @@ -1601,9 +1601,8 @@ enum static GParamSpec *properties[ENCODER_N_PROPERTIES]; -__attribute__ ((unused)) - static void - _gst_vaapi_encoder_set_property (GObject * object, guint prop_id, +static void +_gst_vaapi_encoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); @@ -1653,9 +1652,8 @@ __attribute__ ((unused)) g_param_spec_get_name (pspec), status); } -__attribute__ ((unused)) - static void - _gst_vaapi_encoder_get_property (GObject * object, guint prop_id, +static void +_gst_vaapi_encoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); @@ -1730,8 +1728,9 @@ gst_vaapi_encoder_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapi_encoder_parent_class)->finalize (object); } -static void -encoder_set_property (GObject * object, guint prop_id, +__attribute__ ((unused)) + static void + encoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); @@ -1749,8 +1748,9 @@ encoder_set_property (GObject * object, guint prop_id, } } -static void -encoder_get_property (GObject * object, guint prop_id, +__attribute__ ((unused)) + static void + encoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); @@ -1770,10 +1770,9 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); - object_class->set_property = encoder_set_property; - object_class->get_property = encoder_get_property; + object_class->set_property = _gst_vaapi_encoder_set_property; + object_class->get_property = _gst_vaapi_encoder_get_property; object_class->finalize = gst_vaapi_encoder_finalize; - object_class->constructed = gst_vaapi_encoder_constructed; /** * GstVaapiDecoder:display: diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 975fe49f30..5f09f828a5 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -578,8 +578,6 @@ static gboolean ensure_encoder (GstVaapiEncode * encode) { GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode); - GstVaapiEncoderStatus status; - GPtrArray *const prop_values = encode->prop_values; guint i; g_return_val_if_fail (klass->alloc_encoder, FALSE); @@ -592,15 +590,17 @@ ensure_encoder (GstVaapiEncode * encode) if (!encode->encoder) return FALSE; - if (prop_values) { - for (i = 0; i < prop_values->len; i++) { - PropValue *const prop_value = g_ptr_array_index (prop_values, i); - status = gst_vaapi_encoder_set_property (encode->encoder, prop_value->id, - &prop_value->value); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return FALSE; + if (encode->prop_values && encode->prop_values->len) { + for (i = 0; i < encode->prop_values->len; i++) { + PropValue *const prop_value = g_ptr_array_index (encode->prop_values, i); + g_object_set_property ((GObject *) encode->encoder, + g_param_spec_get_name (prop_value->pspec), &prop_value->value); } + /* clear alll the cache */ + g_ptr_array_unref (encode->prop_values); + encode->prop_values = NULL; } + return TRUE; } diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index e861255c8c..4d452a092c 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -116,7 +116,7 @@ G_DEFINE_TYPE (GstVaapiEncodeH264, gst_vaapiencode_h264, GST_TYPE_VAAPIENCODE); static void gst_vaapiencode_h264_init (GstVaapiEncodeH264 * encode) { - gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); + /* nothing to do here */ } static void @@ -128,36 +128,6 @@ gst_vaapiencode_h264_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapiencode_h264_parent_class)->finalize (object); } -static void -gst_vaapiencode_h264_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->set_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vaapiencode_h264_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->get_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static GstVaapiProfile gst_vaapiencode_h264_get_profile (GstCaps * caps) { @@ -577,15 +547,15 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + gpointer encoder_class; GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encode_debug, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapiencode_h264_finalize; - object_class->set_property = gst_vaapiencode_h264_set_property; - object_class->get_property = gst_vaapiencode_h264_get_property; + object_class->set_property = gst_vaapiencode_set_property_subclass; + object_class->get_property = gst_vaapiencode_get_property_subclass; - encode_class->get_properties = gst_vaapi_encoder_h264_get_default_properties; encode_class->get_profile = gst_vaapiencode_h264_get_profile; encode_class->set_config = gst_vaapiencode_h264_set_config; encode_class->get_caps = gst_vaapiencode_h264_get_caps; @@ -605,5 +575,8 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) gst_element_class_add_static_pad_template (element_class, &gst_vaapiencode_h264_src_factory); - gst_vaapiencode_class_init_properties (encode_class); + encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_H264); + g_assert (encoder_class); + gst_vaapiencode_class_install_properties (encode_class, encoder_class); + g_type_class_unref (encoder_class); } diff --git a/gst/vaapi/gstvaapiencode_h264_fei.c b/gst/vaapi/gstvaapiencode_h264_fei.c index 6e4d51a88a..0b1b74a6f6 100644 --- a/gst/vaapi/gstvaapiencode_h264_fei.c +++ b/gst/vaapi/gstvaapiencode_h264_fei.c @@ -97,7 +97,7 @@ G_DEFINE_TYPE (GstVaapiEncodeH264Fei, gst_vaapiencode_h264_fei, static void gst_vaapiencode_h264_fei_init (GstVaapiEncodeH264Fei * encode) { - gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); + /* nothing to do here */ } static void @@ -106,36 +106,6 @@ gst_vaapiencode_h264_fei_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapiencode_h264_fei_parent_class)->finalize (object); } -static void -gst_vaapiencode_h264_fei_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->set_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vaapiencode_h264_fei_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->get_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - typedef struct { GstVaapiProfile best_profile; @@ -504,16 +474,15 @@ gst_vaapiencode_h264_fei_class_init (GstVaapiEncodeH264FeiClass * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + gpointer encoder_class; GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_fei_encode_debug, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapiencode_h264_fei_finalize; - object_class->set_property = gst_vaapiencode_h264_fei_set_property; - object_class->get_property = gst_vaapiencode_h264_fei_get_property; + object_class->set_property = gst_vaapiencode_set_property_subclass; + object_class->get_property = gst_vaapiencode_get_property_subclass; - encode_class->get_properties = - gst_vaapi_encoder_h264_fei_get_default_properties; encode_class->set_config = gst_vaapiencode_h264_fei_set_config; encode_class->get_caps = gst_vaapiencode_h264_fei_get_caps; encode_class->alloc_encoder = gst_vaapiencode_h264_fei_alloc_encoder; @@ -537,5 +506,8 @@ gst_vaapiencode_h264_fei_class_init (GstVaapiEncodeH264FeiClass * klass) gst_element_class_add_static_pad_template (element_class, &gst_vaapiencode_h264_fei_src_factory); - gst_vaapiencode_class_init_properties (encode_class); + encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_H264_FEI); + g_assert (encoder_class); + gst_vaapiencode_class_install_properties (encode_class, encoder_class); + g_type_class_unref (encoder_class); } diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index fa03fdcefc..ed00a93872 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -90,7 +90,7 @@ G_DEFINE_TYPE (GstVaapiEncodeH265, gst_vaapiencode_h265, GST_TYPE_VAAPIENCODE); static void gst_vaapiencode_h265_init (GstVaapiEncodeH265 * encode) { - gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); + /* nothing to do here */ } static void @@ -99,36 +99,6 @@ gst_vaapiencode_h265_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapiencode_h265_parent_class)->finalize (object); } -static void -gst_vaapiencode_h265_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->set_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vaapiencode_h265_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->get_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static GstVaapiProfile gst_vaapiencode_h265_get_profile (GstCaps * caps) { @@ -407,15 +377,15 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + gpointer encoder_class; GST_DEBUG_CATEGORY_INIT (gst_vaapi_h265_encode_debug, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapiencode_h265_finalize; - object_class->set_property = gst_vaapiencode_h265_set_property; - object_class->get_property = gst_vaapiencode_h265_get_property; + object_class->set_property = gst_vaapiencode_set_property_subclass; + object_class->get_property = gst_vaapiencode_get_property_subclass; - encode_class->get_properties = gst_vaapi_encoder_h265_get_default_properties; encode_class->get_profile = gst_vaapiencode_h265_get_profile; encode_class->set_config = gst_vaapiencode_h265_set_config; encode_class->get_caps = gst_vaapiencode_h265_get_caps; @@ -436,5 +406,8 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass) gst_element_class_add_static_pad_template (element_class, &gst_vaapiencode_h265_src_factory); - gst_vaapiencode_class_init_properties (encode_class); + encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_H265); + g_assert (encoder_class); + gst_vaapiencode_class_install_properties (encode_class, encoder_class); + g_type_class_unref (encoder_class); } diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 4d644fa9d2..0de5cb381b 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -86,7 +86,7 @@ G_DEFINE_TYPE (GstVaapiEncodeJpeg, gst_vaapiencode_jpeg, GST_TYPE_VAAPIENCODE); static void gst_vaapiencode_jpeg_init (GstVaapiEncodeJpeg * encode) { - gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); + /* nothing to do here */ } static void @@ -95,36 +95,6 @@ gst_vaapiencode_jpeg_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapiencode_jpeg_parent_class)->finalize (object); } -static void -gst_vaapiencode_jpeg_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->set_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vaapiencode_jpeg_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->get_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static GstCaps * gst_vaapiencode_jpeg_get_caps (GstVaapiEncode * base_encode) { @@ -148,15 +118,15 @@ gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + gpointer encoder_class; GST_DEBUG_CATEGORY_INIT (gst_vaapi_jpeg_encode_debug, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapiencode_jpeg_finalize; - object_class->set_property = gst_vaapiencode_jpeg_set_property; - object_class->get_property = gst_vaapiencode_jpeg_get_property; + object_class->set_property = gst_vaapiencode_set_property_subclass; + object_class->get_property = gst_vaapiencode_get_property_subclass; - encode_class->get_properties = gst_vaapi_encoder_jpeg_get_default_properties; encode_class->get_caps = gst_vaapiencode_jpeg_get_caps; encode_class->alloc_encoder = gst_vaapiencode_jpeg_alloc_encoder; @@ -174,5 +144,8 @@ gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass) gst_element_class_add_static_pad_template (element_class, &gst_vaapiencode_jpeg_src_factory); - gst_vaapiencode_class_init_properties (encode_class); + encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_JPEG); + g_assert (encoder_class); + gst_vaapiencode_class_install_properties (encode_class, encoder_class); + g_type_class_unref (encoder_class); } diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index f43ac3f9fe..810de09f1f 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -89,7 +89,7 @@ G_DEFINE_TYPE (GstVaapiEncodeMpeg2, gst_vaapiencode_mpeg2, static void gst_vaapiencode_mpeg2_init (GstVaapiEncodeMpeg2 * encode) { - gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); + /* nothing to do here */ } static void @@ -98,36 +98,6 @@ gst_vaapiencode_mpeg2_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapiencode_mpeg2_parent_class)->finalize (object); } -static void -gst_vaapiencode_mpeg2_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->set_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vaapiencode_mpeg2_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->get_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static GstCaps * gst_vaapiencode_mpeg2_get_caps (GstVaapiEncode * base_encode) { @@ -152,15 +122,15 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + gpointer encoder_class; GST_DEBUG_CATEGORY_INIT (gst_vaapi_mpeg2_encode_debug, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapiencode_mpeg2_finalize; - object_class->set_property = gst_vaapiencode_mpeg2_set_property; - object_class->get_property = gst_vaapiencode_mpeg2_get_property; + object_class->set_property = gst_vaapiencode_set_property_subclass; + object_class->get_property = gst_vaapiencode_get_property_subclass; - encode_class->get_properties = gst_vaapi_encoder_mpeg2_get_default_properties; encode_class->get_caps = gst_vaapiencode_mpeg2_get_caps; encode_class->alloc_encoder = gst_vaapiencode_mpeg2_alloc_encoder; @@ -177,5 +147,8 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) gst_element_class_add_static_pad_template (element_class, &gst_vaapiencode_mpeg2_src_factory); - gst_vaapiencode_class_init_properties (encode_class); + encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_MPEG2); + g_assert (encoder_class); + gst_vaapiencode_class_install_properties (encode_class, encoder_class); + g_type_class_unref (encoder_class); } diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 5fee607b0a..64a3879f37 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -86,7 +86,7 @@ G_DEFINE_TYPE (GstVaapiEncodeVP8, gst_vaapiencode_vp8, GST_TYPE_VAAPIENCODE); static void gst_vaapiencode_vp8_init (GstVaapiEncodeVP8 * encode) { - gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); + /* nothing to do here */ } static void @@ -95,36 +95,6 @@ gst_vaapiencode_vp8_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapiencode_vp8_parent_class)->finalize (object); } -static void -gst_vaapiencode_vp8_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->set_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vaapiencode_vp8_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->get_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static GstCaps * gst_vaapiencode_vp8_get_caps (GstVaapiEncode * base_encode) { @@ -148,15 +118,15 @@ gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + gpointer encoder_class; GST_DEBUG_CATEGORY_INIT (gst_vaapi_vp8_encode_debug, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapiencode_vp8_finalize; - object_class->set_property = gst_vaapiencode_vp8_set_property; - object_class->get_property = gst_vaapiencode_vp8_get_property; + object_class->set_property = gst_vaapiencode_set_property_subclass; + object_class->get_property = gst_vaapiencode_get_property_subclass; - encode_class->get_properties = gst_vaapi_encoder_vp8_get_default_properties; encode_class->get_caps = gst_vaapiencode_vp8_get_caps; encode_class->alloc_encoder = gst_vaapiencode_vp8_alloc_encoder; @@ -174,5 +144,8 @@ gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass) gst_element_class_add_static_pad_template (element_class, &gst_vaapiencode_vp8_src_factory); - gst_vaapiencode_class_init_properties (encode_class); + encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_VP8); + g_assert (encoder_class); + gst_vaapiencode_class_install_properties (encode_class, encoder_class); + g_type_class_unref (encoder_class); } diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index 22c40a6443..97d2e13606 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -86,7 +86,7 @@ G_DEFINE_TYPE (GstVaapiEncodeVP9, gst_vaapiencode_vp9, GST_TYPE_VAAPIENCODE); static void gst_vaapiencode_vp9_init (GstVaapiEncodeVP9 * encode) { - gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode)); + /* nothing to do here */ } static void @@ -95,36 +95,6 @@ gst_vaapiencode_vp9_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapiencode_vp9_parent_class)->finalize (object); } -static void -gst_vaapiencode_vp9_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->set_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vaapiencode_vp9_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object); - GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object); - - switch (prop_id) { - default: - if (!encode_class->get_property (base_encode, prop_id, value)) - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static GstCaps * gst_vaapiencode_vp9_get_caps (GstVaapiEncode * base_encode) { @@ -148,15 +118,15 @@ gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + gpointer encoder_class; GST_DEBUG_CATEGORY_INIT (gst_vaapi_vp9_encode_debug, GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); object_class->finalize = gst_vaapiencode_vp9_finalize; - object_class->set_property = gst_vaapiencode_vp9_set_property; - object_class->get_property = gst_vaapiencode_vp9_get_property; + object_class->set_property = gst_vaapiencode_set_property_subclass; + object_class->get_property = gst_vaapiencode_get_property_subclass; - encode_class->get_properties = gst_vaapi_encoder_vp9_get_default_properties; encode_class->get_caps = gst_vaapiencode_vp9_get_caps; encode_class->alloc_encoder = gst_vaapiencode_vp9_alloc_encoder; @@ -174,5 +144,8 @@ gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass) gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_vaapiencode_vp9_src_factory)); - gst_vaapiencode_class_init_properties (encode_class); + encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_VP9); + g_assert (encoder_class); + gst_vaapiencode_class_install_properties (encode_class, encoder_class); + g_type_class_unref (encoder_class); } From eb17703d43a91ea9a7c43e37a3182616a2e0f78f Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 26 Aug 2019 23:16:33 +0800 Subject: [PATCH 3347/3781] libs: encoder: implement get_view_ids for h264 encoder. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 19 +++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 19 +++++++++++++++++-- gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 19 +++++++++++++++++-- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 22ac7d239e..68e60f1c9b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3515,6 +3515,22 @@ set_default_ids: } } +static void +get_view_ids (GstVaapiEncoderH264 * const encoder, GValue * value) +{ + guint i; + GValue id = G_VALUE_INIT; + + g_value_reset (value); + g_value_init (&id, G_TYPE_UINT); + + for (i = 0; i < encoder->num_views; i++) { + g_value_set_uint (&id, encoder->view_ids[i]); + gst_value_array_append_value (value, &id); + } + g_value_unset (&id); +} + /** * @ENCODER_H264_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). * @ENCODER_H264_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). @@ -3770,8 +3786,7 @@ gst_vaapi_encoder_h264_get_property (GObject * object, guint prop_id, g_value_set_uint (value, encoder->num_views); break; case ENCODER_H264_PROP_VIEW_IDS: - // TODO: - //get_view_ids (encoder, value); + get_view_ids (encoder, value); break; case ENCODER_H264_PROP_AUD: g_value_set_boolean (value, encoder->use_aud); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index dc7b06869b..f462f8c4e3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -3473,6 +3473,22 @@ set_default_ids: } } +static void +get_view_ids (GstVaapiEncoderH264Fei * const encoder, GValue * value) +{ + guint i; + GValue id = G_VALUE_INIT; + + g_value_reset (value); + g_value_init (&id, G_TYPE_UINT); + + for (i = 0; i < encoder->num_views; i++) { + g_value_set_uint (&id, encoder->view_ids[i]); + gst_value_array_append_value (value, &id); + } + g_value_unset (&id); +} + static GstVaapiEncoderStatus _gst_vaapi_encoder_h264_fei_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) @@ -3854,8 +3870,7 @@ gst_vaapi_encoder_h264_fei_get_property (GObject * object, guint prop_id, g_value_set_uint (value, encoder->num_views); break; case ENCODER_H264_FEI_PROP_VIEW_IDS: - // TODO: - //get_view_ids (encoder, value); + get_view_ids (encoder, value); break; case ENCODER_H264_PROP_FEI_DISABLE: g_value_set_boolean (value, encoder->is_fei_disabled); diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index 0816bf96c2..24702b6c3e 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -1747,6 +1747,22 @@ set_default_ids: } } +static void +get_view_ids (GstVaapiFeiEncH264 * const encoder, GValue * value) +{ + guint i; + GValue id = G_VALUE_INIT; + + g_value_reset (value); + g_value_init (&id, G_TYPE_UINT); + + for (i = 0; i < encoder->num_views; i++) { + g_value_set_uint (&id, encoder->view_ids[i]); + gst_value_array_append_value (value, &id); + } + g_value_unset (&id); +} + GstVaapiEncoderStatus gst_vaapi_feienc_h264_set_property (GstVaapiEncoder * base_encoder, gint prop_id, const GValue * value) @@ -2029,8 +2045,7 @@ gst_vaapi_feienc_h264_get_property (GObject * object, guint prop_id, g_value_set_uint (value, feienc->num_views); break; case FEI_H264_ENC_PROP_VIEW_IDS: - // TODO: - //get_view_ids (feienc, value); + get_view_ids (feienc, value); break; case FEI_H264_ENC_PROP_NUM_REF: g_value_set_uint (value, feienc->num_ref_frames); From 511a48da5662a2d9a696051d18d6515cbdbd40c9 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 14:53:59 +0800 Subject: [PATCH 3348/3781] libs: encoder: delete the useless constructed func for encoder. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index e3108e4984..a496626d3b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1546,31 +1546,6 @@ error_operation_failed: } } -/* Initialize default values for configurable properties */ -__attribute__ ((unused)) - static void gst_vaapi_encoder_constructed (GObject * object) -{ - GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); - GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); - GPtrArray *props; - guint i; - - props = klass->get_default_properties (); - if (!props) - return; - - encoder->properties = props; - for (i = 0; i < props->len; i++) { - GstVaapiEncoderPropInfo *const prop = g_ptr_array_index (props, i); - - if (gst_vaapi_encoder_set_property (encoder, prop->prop, - NULL) != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return; - } - - return; -} - G_DEFINE_ABSTRACT_TYPE (GstVaapiEncoder, gst_vaapi_encoder, GST_TYPE_OBJECT); /** From fe369fb523a73c0ba15acf7773b8d836ca2a5618 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 14:59:12 +0800 Subject: [PATCH 3349/3781] libs: encoder: delete get_default_properties of H264 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 268 ---------------------- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 3 - 2 files changed, 271 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 68e60f1c9b..294892694f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3827,8 +3827,6 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) encoder_class->class_data = &g_class_data; encoder_class->reconfigure = gst_vaapi_encoder_h264_reconfigure; - encoder_class->get_default_properties = - gst_vaapi_encoder_h264_get_default_properties; encoder_class->reordering = gst_vaapi_encoder_h264_reordering; encoder_class->encode = gst_vaapi_encoder_h264_encode; encoder_class->flush = gst_vaapi_encoder_h264_flush; @@ -4135,272 +4133,6 @@ gst_vaapi_encoder_h264_new (GstVaapiDisplay * display) return g_object_new (GST_TYPE_VAAPI_ENCODER_H264, "display", display, NULL); } -/** - * gst_vaapi_encoder_h264_get_default_properties: - * - * Determines the set of common and H.264 specific encoder properties. - * The caller owns an extra reference to the resulting array of - * #GstVaapiEncoderPropInfo elements, so it shall be released with - * g_ptr_array_unref() after usage. - * - * Return value: the set of encoder properties for #GstVaapiEncoderH264, - * or %NULL if an error occurred. - */ -GPtrArray * -gst_vaapi_encoder_h264_get_default_properties (void) -{ - const GstVaapiEncoderClassData *class_data = &g_class_data; - GPtrArray *props; - - props = gst_vaapi_encoder_properties_get_default (class_data); - if (!props) - return NULL; - - /** - * GstVaapiEncoderH264:max-bframes: - * - * The number of B-frames between I and P. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES, - g_param_spec_uint ("max-bframes", - "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:refs: - * - * The number of reference frames. - * If B frame is encoded, it will add 1 reference frame more. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES, - g_param_spec_uint ("refs", "Number of Reference Frames", - "Number of reference frames", 1, 8, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:init-qp: - * - * The initial quantizer value. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_INIT_QP, - g_param_spec_uint ("init-qp", - "Initial QP", "Initial quantizer value", 0, 51, 26, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:min-qp: - * - * The minimum quantizer value. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_MIN_QP, - g_param_spec_uint ("min-qp", - "Minimum QP", "Minimum quantizer value", 0, 51, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:max-qp: - * - * The maximum quantizer value. - * - * Since: 1.18 - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_MAX_QP, - g_param_spec_uint ("max-qp", - "Maximum QP", "Maximum quantizer value", 0, 51, 51, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:qp-ip: - * - * The difference of QP between I and P Frame. - * This is available only on CQP mode. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_QP_IP, - g_param_spec_int ("qp-ip", - "Difference of QP between I and P frame", - "Difference of QP between I and P frame (available only on CQP)", - -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:qp-ib: - * - * The difference of QP between I and B Frame. - * This is available only on CQP mode. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_QP_IB, - g_param_spec_int ("qp-ib", - "Difference of QP between I and B frame", - "Difference of QP between I and B frame (available only on CQP)", - -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:num-slices: - * - * The number of slices per frame. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES, - g_param_spec_uint ("num-slices", - "Number of Slices", - "Number of slices per frame", - 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:cabac: - * - * Enable CABAC entropy coding mode for improved compression ratio, - * at the expense that the minimum target profile is Main. Default - * is CAVLC entropy coding mode. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_CABAC, - g_param_spec_boolean ("cabac", - "Enable CABAC", - "Enable CABAC entropy coding mode", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:dct8x8: - * - * Enable adaptive use of 8x8 transforms in I-frames. This improves - * the compression ratio by the minimum target profile is High. - * Default is to use 4x4 DCT only. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_DCT8X8, - g_param_spec_boolean ("dct8x8", - "Enable 8x8 DCT", - "Enable adaptive use of 8x8 transforms in I-frames", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:mbbrc: - * - * Macroblock level bitrate control. - * This is not compatible with Constant QP rate control. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_MBBRC, - g_param_spec_enum ("mbbrc", - "Macroblock level Bitrate Control", - "Macroblock level Bitrate Control", - GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:temporal-levels: - * - * Number of temporal levels in the encoded stream. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS, - g_param_spec_uint ("temporal-levels", - "temporal levels", - "Number of temporal levels in the encoded stream ", - MIN_TEMPORAL_LEVELS, MAX_TEMPORAL_LEVELS, MIN_TEMPORAL_LEVELS, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:prediction-type: - * - * Select the referece picture selection modes - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE, - g_param_spec_enum ("prediction-type", - "RefPic Selection", - "Reference Picture Selection Modes", - gst_vaapi_encoder_h264_prediction_type (), - GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:cpb-length: - * - * The size of the CPB buffer in milliseconds. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH, - g_param_spec_uint ("cpb-length", - "CPB Length", "Length of the CPB buffer in milliseconds", - 1, 10000, DEFAULT_CPB_LENGTH, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:num-views: - * - * The number of views for MVC encoding . - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS, - g_param_spec_uint ("num-views", - "Number of Views", - "Number of Views for MVC encoding", - 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:view-ids: - * - * The view ids for MVC encoding . - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS, - gst_param_spec_array ("view-ids", - "View IDs", "Set of View Ids used for MVC encoding", - g_param_spec_uint ("view-id-value", "View id value", - "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:aud: - * - * Use AU (Access Unit) delimeter. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_AUD, - g_param_spec_boolean ("aud", "AU delimiter", - "Use AU (Access Unit) delimeter", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:Compliance Mode: - * - * Encode Tuning(Tweaking) with different compliance modes . - * - * - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE, - g_param_spec_enum ("compliance-mode", - "Spec Compliance Mode", - "Tune Encode quality/performance by relaxing specification compliance restrictions", - gst_vaapi_encoder_h264_compliance_mode_type (), - GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT, G_PARAM_READWRITE)); - - /** - * GstVaapiEncoderH264:quality_factor: - * - * quality factor used under ICQ/QVBR bitrate control mode. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_QUALITY_FACTOR, - g_param_spec_uint ("quality-factor", - "Quality factor for ICQ/QVBR", - "quality factor for ICQ/QVBR bitrate control mode" - "(low value means higher-quality, higher value means lower-quality)", - 1, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - return props; -} - /** * gst_vaapi_encoder_h264_set_max_profile: * @encoder: a #GstVaapiEncoderH264 diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 188ffe5902..93d874b937 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -94,9 +94,6 @@ gst_vaapi_encoder_h264_get_type (void) G_GNUC_CONST; GstVaapiEncoder * gst_vaapi_encoder_h264_new (GstVaapiDisplay * display); -GPtrArray * -gst_vaapi_encoder_h264_get_default_properties (void); - gboolean gst_vaapi_encoder_h264_set_max_profile (GstVaapiEncoderH264 * encoder, GstVaapiProfile profile); From 0ce9f6e637059890b330dcae57fc754342c28d7d Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 30 Aug 2019 19:15:38 +0800 Subject: [PATCH 3350/3781] libs: encoder: delete get_default_properties of H265 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 161 ---------------------- gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 3 - 2 files changed, 164 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index f17f2b8833..4861ad3762 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2870,8 +2870,6 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) encoder_class->class_data = &g_class_data; encoder_class->reconfigure = gst_vaapi_encoder_h265_reconfigure; - encoder_class->get_default_properties = - gst_vaapi_encoder_h265_get_default_properties; encoder_class->reordering = gst_vaapi_encoder_h265_reordering; encoder_class->encode = gst_vaapi_encoder_h265_encode; encoder_class->flush = gst_vaapi_encoder_h265_flush; @@ -3069,165 +3067,6 @@ gst_vaapi_encoder_h265_new (GstVaapiDisplay * display) return g_object_new (GST_TYPE_VAAPI_ENCODER_H265, "display", display, NULL); } -/** - * gst_vaapi_encoder_h265_get_default_properties: - * - * Determines the set of common and H.265 specific encoder properties. - * The caller owns an extra reference to the resulting array of - * #GstVaapiEncoderPropInfo elements, so it shall be released with - * g_ptr_array_unref() after usage. - * - * Return value: the set of encoder properties for #GstVaapiEncoderH265, - * or %NULL if an error occurred. - */ -GPtrArray * -gst_vaapi_encoder_h265_get_default_properties (void) -{ - const GstVaapiEncoderClassData *class_data = &g_class_data; - GPtrArray *props; - - props = gst_vaapi_encoder_properties_get_default (class_data); - if (!props) - return NULL; - - /** - * GstVaapiEncoderH265:max-bframes: - * - * The number of B-frames between I and P. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H265_PROP_MAX_BFRAMES, - g_param_spec_uint ("max-bframes", - "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH265:refs: - * - * The number of reference frames. - * If B frame is encoded, it will add 1 reference frame more. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES, - g_param_spec_uint ("refs", - "Number of Reference Frames", "Number of reference frames", 1, 3, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH265:init-qp: - * - * The initial quantizer value. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H265_PROP_INIT_QP, - g_param_spec_uint ("init-qp", - "Initial QP", "Initial quantizer value", 0, 51, 26, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH265:min-qp: - * - * The minimum quantizer value. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H265_PROP_MIN_QP, - g_param_spec_uint ("min-qp", - "Minimum QP", "Minimum quantizer value", 0, 51, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH265:max-qp: - * - * The maximum quantizer value. - * - * Since: 1.18 - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H265_PROP_MAX_QP, - g_param_spec_uint ("max-qp", - "Maximum QP", "Maximum quantizer value", 0, 51, 51, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH265:qp-ip: - * - * The difference of QP between I and P Frame. - * This is available only on CQP mode. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H265_PROP_QP_IP, - g_param_spec_int ("qp-ip", - "Difference of QP between I and P frame", - "Difference of QP between I and P frame (available only on CQP)", - -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH265:qp-ib: - * - * The difference of QP between I and B Frame. - * This is available only on CQP mode. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H265_PROP_QP_IB, - g_param_spec_int ("qp-ib", - "Difference of QP between I and B frame", - "Difference of QP between I and B frame (available only on CQP)", - -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /* FIXME: there seems to be issues with multi-slice encoding */ - /** - * GstVaapiEncoderH265:num-slices: - * - * The number of slices per frame. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES, - g_param_spec_uint ("num-slices", - "Number of Slices", - "Number of slices per frame", - 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH265:cpb-length: - * - * The size of the CPB buffer in milliseconds. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH, - g_param_spec_uint ("cpb-length", - "CPB Length", "Length of the CPB buffer in milliseconds", - 1, 10000, DEFAULT_CPB_LENGTH, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH265:mbbrc: - * - * Macroblock level bitrate control. - * This is not compatible with Constant QP rate control. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H265_PROP_MBBRC, - g_param_spec_enum ("mbbrc", - "Macroblock level Bitrate Control", - "Macroblock level Bitrate Control", - GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH265:low_delay_b: - * - * Enable low delay b frame, which will change P frame with B frame. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B, - g_param_spec_boolean ("low-delay-b", - "Enable low delay b", - "Transforms P frames into predictive B frames. Enable it when P frames are not supported.", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - return props; -} - /** * gst_vaapi_encoder_h265_set_max_profile: * @encoder: a #GstVaapiEncoderH265 diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index e78c2b3fab..1e18ed9642 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -76,9 +76,6 @@ gst_vaapi_encoder_h265_get_type (void) G_GNUC_CONST; GstVaapiEncoder * gst_vaapi_encoder_h265_new (GstVaapiDisplay * display); -GPtrArray * -gst_vaapi_encoder_h265_get_default_properties (void); - gboolean gst_vaapi_encoder_h265_set_max_profile (GstVaapiEncoderH265 * encoder, GstVaapiProfile profile); From 665a121b51cbde88088dd7d7c36e0727c27cca94 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 15:03:19 +0800 Subject: [PATCH 3351/3781] libs: encoder: delete get_default_properties of JPEG --- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 32 ----------------------- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h | 3 --- 2 files changed, 35 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 2848370c81..816ae0664e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -856,8 +856,6 @@ gst_vaapi_encoder_jpeg_class_init (GstVaapiEncoderJpegClass * klass) encoder_class->class_data = &g_class_data; encoder_class->reconfigure = gst_vaapi_encoder_jpeg_reconfigure; - encoder_class->get_default_properties = - gst_vaapi_encoder_jpeg_get_default_properties; encoder_class->reordering = gst_vaapi_encoder_jpeg_reordering; encoder_class->encode = gst_vaapi_encoder_jpeg_encode; encoder_class->flush = gst_vaapi_encoder_jpeg_flush; @@ -907,33 +905,3 @@ gst_vaapi_encoder_jpeg_new (GstVaapiDisplay * display) { return g_object_new (GST_TYPE_VAAPI_ENCODER_JPEG, "display", display, NULL); } - -/** - * gst_vaapi_encoder_jpeg_get_default_properties: - * - * Determines the set of common and jpeg specific encoder properties. - * The caller owns an extra reference to the resulting array of - * #GstVaapiEncoderPropInfo elements, so it shall be released with - * g_ptr_array_unref() after usage. - * - * Return value: the set of encoder properties for #GstVaapiEncoderJpeg, - * or %NULL if an error occurred. - */ -GPtrArray * -gst_vaapi_encoder_jpeg_get_default_properties (void) -{ - const GstVaapiEncoderClassData *class_data = &g_class_data; - GPtrArray *props; - - props = gst_vaapi_encoder_properties_get_default (class_data); - if (!props) - return NULL; - - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_JPEG_PROP_QUALITY, - g_param_spec_uint ("quality", - "Quality factor", - "Quality factor", - 0, 100, 50, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - return props; -} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h index 674d2dae55..ba082f908e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h @@ -53,8 +53,5 @@ gst_vaapi_encoder_jpeg_get_type (void) G_GNUC_CONST; GstVaapiEncoder * gst_vaapi_encoder_jpeg_new (GstVaapiDisplay * display); -GPtrArray * -gst_vaapi_encoder_jpeg_get_default_properties (void); - G_END_DECLS #endif /*GST_VAAPI_ENCODER_JPEG_H */ From 1ca6a42e27109dfb5049aba14fc10cc98528559c Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 15:03:52 +0800 Subject: [PATCH 3352/3781] libs: encoder: delete get_default_properties of MPEG2 --- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 39 ---------------------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 3 -- 2 files changed, 42 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 44c0baca7a..98cc5f9df4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -889,8 +889,6 @@ gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass) encoder_class->class_data = &g_class_data; encoder_class->reconfigure = gst_vaapi_encoder_mpeg2_reconfigure; - encoder_class->get_default_properties = - gst_vaapi_encoder_mpeg2_get_default_properties; encoder_class->reordering = gst_vaapi_encoder_mpeg2_reordering; encoder_class->encode = gst_vaapi_encoder_mpeg2_encode; encoder_class->flush = gst_vaapi_encoder_mpeg2_flush; @@ -958,43 +956,6 @@ gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display) return g_object_new (GST_TYPE_VAAPI_ENCODER_MPEG2, "display", display, NULL); } -/** - * gst_vaapi_encoder_mpeg2_get_default_properties: - * - * Determines the set of common and MPEG-2 specific encoder properties. - * The caller owns an extra reference to the resulting array of - * #GstVaapiEncoderPropInfo elements, so it shall be released with - * g_ptr_array_unref() after usage. - * - * Return value: the set of encoder properties for #GstVaapiEncoderMpeg2, - * or %NULL if an error occurred. - */ -GPtrArray * -gst_vaapi_encoder_mpeg2_get_default_properties (void) -{ - const GstVaapiEncoderClassData *class_data = &g_class_data; - GPtrArray *props; - - props = gst_vaapi_encoder_properties_get_default (class_data); - if (!props) - return NULL; - - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER, - g_param_spec_uint ("quantizer", - "Constant Quantizer", - "Constant quantizer (if rate-control mode is CQP)", - 2, 62, 8, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES, - g_param_spec_uint ("max-bframes", "Max B-Frames", - "Number of B-frames between I and P", - 0, 16, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - return props; -} - static struct { int code; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h index af61698e5a..dbd1f012c6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -57,9 +57,6 @@ gst_vaapi_encoder_mpeg2_get_type (void) G_GNUC_CONST; GstVaapiEncoder * gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display); -GPtrArray * -gst_vaapi_encoder_mpeg2_get_default_properties (void); - G_END_DECLS #endif /* GST_VAAPI_ENCODER_MPEG2_H */ From c5cf07631d20294793c83daef4942777911c2d09 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 15:06:25 +0800 Subject: [PATCH 3353/3781] libs: encoder: delete get_default_properties of VP8 --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 51 ------------------------ gst-libs/gst/vaapi/gstvaapiencoder_vp8.h | 3 -- 2 files changed, 54 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 2af6024d8d..76c91c6f85 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -651,8 +651,6 @@ gst_vaapi_encoder_vp8_class_init (GstVaapiEncoderVP8Class * klass) encoder_class->class_data = &g_class_data; encoder_class->reconfigure = gst_vaapi_encoder_vp8_reconfigure; - encoder_class->get_default_properties = - gst_vaapi_encoder_vp8_get_default_properties; encoder_class->reordering = gst_vaapi_encoder_vp8_reordering; encoder_class->encode = gst_vaapi_encoder_vp8_encode; encoder_class->flush = gst_vaapi_encoder_vp8_flush; @@ -718,52 +716,3 @@ gst_vaapi_encoder_vp8_new (GstVaapiDisplay * display) { return g_object_new (GST_TYPE_VAAPI_ENCODER_VP8, "display", display, NULL); } - -/** - * gst_vaapi_encoder_vp8_get_default_properties: - * - * Determines the set of common and vp8 specific encoder properties. - * The caller owns an extra reference to the resulting array of - * #GstVaapiEncoderPropInfo elements, so it shall be released with - * g_ptr_array_unref() after usage. - * - * Return value: the set of encoder properties for #GstVaapiEncoderVP8, - * or %NULL if an error occurred. - */ -GPtrArray * -gst_vaapi_encoder_vp8_get_default_properties (void) -{ - const GstVaapiEncoderClassData *class_data = &g_class_data; - GPtrArray *props; - - props = gst_vaapi_encoder_properties_get_default (class_data); - if (!props) - return NULL; - - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_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)); - - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_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)); - - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_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)); - - return props; -} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h index 5fa77d862a..a43373c531 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h @@ -57,8 +57,5 @@ gst_vaapi_encoder_vp8_get_type (void) G_GNUC_CONST; GstVaapiEncoder * gst_vaapi_encoder_vp8_new (GstVaapiDisplay * display); -GPtrArray * -gst_vaapi_encoder_vp8_get_default_properties (void); - G_END_DECLS #endif /*GST_VAAPI_ENCODER_VP8_H */ From f65647ec25f4ef435d64f3736cd7448a80a7b7d4 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 15:07:17 +0800 Subject: [PATCH 3354/3781] libs: encoder: delete get_default_properties of VP9 --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 73 ------------------------ gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 3 - 2 files changed, 76 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 663978670f..30a22bfd7e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -694,8 +694,6 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) encoder_class->class_data = &g_class_data; encoder_class->reconfigure = gst_vaapi_encoder_vp9_reconfigure; - encoder_class->get_default_properties = - gst_vaapi_encoder_vp9_get_default_properties; encoder_class->reordering = gst_vaapi_encoder_vp9_reordering; encoder_class->encode = gst_vaapi_encoder_vp9_encode; encoder_class->flush = gst_vaapi_encoder_vp9_flush; @@ -785,74 +783,3 @@ gst_vaapi_encoder_vp9_new (GstVaapiDisplay * display) { return g_object_new (GST_TYPE_VAAPI_ENCODER_VP9, "display", display, NULL); } - -/** - * gst_vaapi_encoder_vp9_get_default_properties: - * - * Determines the set of common and vp9 specific encoder properties. - * The caller owns an extra reference to the resulting array of - * #GstVaapiEncoderPropInfo elements, so it shall be released with - * g_ptr_array_unref() after usage. - * - * Return value: the set of encoder properties for #GstVaapiEncoderVP9, - * or %NULL if an error occurred. - */ -GPtrArray * -gst_vaapi_encoder_vp9_get_default_properties (void) -{ - const GstVaapiEncoderClassData *class_data = &g_class_data; - GPtrArray *props; - - props = gst_vaapi_encoder_properties_get_default (class_data); - if (!props) - return NULL; - - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_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)); - - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_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)); - - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_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)); - - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_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)); - - /** - * GstVaapiEncoderVP9:cpb-length: - * - * The size of the Coded Picture Buffer , which means - * the window size in milliseconds. - * - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_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)); - - return props; -} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h index ff690fe2db..b2f7424cad 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -61,8 +61,5 @@ gst_vaapi_encoder_vp9_get_type (void) G_GNUC_CONST; GstVaapiEncoder * gst_vaapi_encoder_vp9_new (GstVaapiDisplay * display); -GPtrArray * -gst_vaapi_encoder_vp9_get_default_properties (void); - G_END_DECLS #endif /*GST_VAAPI_ENCODER_VP9_H */ From 8ac7dd556bc557ed7522224f561ad01cad8e95cc Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 15:14:14 +0800 Subject: [PATCH 3355/3781] libs: encoder: delete get_default_properties of H264 Fei --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 415 ------------------ gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h | 3 - 2 files changed, 418 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index f462f8c4e3..c1ef4d3b4f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -47,7 +47,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -GPtrArray *gst_vaapi_encoder_h264_fei_get_default_properties (void); static gboolean gst_vaapi_encoder_h264_fei_ensure_secondary_context (GstVaapiEncoder * base_encoder); @@ -4052,269 +4051,6 @@ cleanup: return success; } -/** - * gst_vaapi_encoder_h264_get_fei_properties: - * - * Determines the set of common and H.264 Fei specific encoder properties. - * The caller owns an extra reference to the resulting array of - * #GstVaapiEncoderPropInfo elements, so it shall be released with - * g_ptr_array_unref() after usage. - * - * Return value: the set of encoder properties for #GstVaapiEncoderH264, - * or %NULL if an error occurred. - */ -static GPtrArray * -gst_vaapi_encoder_h264_get_fei_properties (GPtrArray * props) -{ - /** - * GstVaapiEncoderH264: disable-fei: - * - * Disable FEI mode Encode: disabling fei will results - * the encoder to use VAEntrypointEncSlice, which means - * vaapi-intel-driver will be using a different media kerenl. - * And most of the properties associated with this element - * will be non functional. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_FEI_DISABLE, - g_param_spec_boolean ("disable-fei", - "Disable FEI Mode Encode", - "Disable Flexible Encoding Infrasturcture", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - - /** - * GstVaapiEncoderH264: stats-out: - * - * Enable outputting fei buffers MV, MBCode and Distortion. - * If enabled, encoder will allocate memory for these buffers - * and submit to the driver even for ENC_PAK mode so that - * the output data can be extraced for analysis after the - * complettion of each frame ncode - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_ENABLE_STATS_OUT, - g_param_spec_boolean ("stats-out", - "stats out", - "Enable stats out for fei", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:num_mv_predictors_l0: - * Indicate how many mv predictors should be used for l0 frames. - * Only valid if MVPredictor input has been enabled. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L0, - g_param_spec_uint ("num-mvpredict-l0", - "Num mv predict l0", - "Indicate how many predictors should be used for l0," - "only valid if MVPredictor input enabled", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiEncoderH264:num_mv_predictors_l1: - * Indicate how many mv predictors should be used for l1 frames. - * Only valid if MVPredictor input has been enabled. - * - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L1, - g_param_spec_uint ("num-mvpredict-l1", - "Num mv predict l1", - "Indicate how many predictors should be used for l1," - "only valid if MVPredictor input enabled", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiEncoderH264:search-window: - * Use predefined Search Window - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_SEARCH_WINDOW, - g_param_spec_enum ("search-window", - "search window", - "Specify one of the predefined search path", - GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:len-sp: - * Defines the maximum number of Search Units per reference. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_LEN_SP, - g_param_spec_uint ("len-sp", - "length of search path", - "This value defines number of search units in search path", - 1, 63, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:search-path: - * SearchPath defines the motion search method. - * Zero means full search, 1 indicate diamond search. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_SEARCH_PATH, - g_param_spec_enum ("search-path", - "search path", - "Specify search path", - GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, - GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:ref-width: - * Specifies the search region width in pixels. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_REF_WIDTH, - g_param_spec_uint ("ref-width", - "ref width", - "Width of search region in pixel, must be multiple of 4", - 4, 64, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:ref-height: - * Specifies the search region height in pixels. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_REF_HEIGHT, - g_param_spec_uint ("ref-height", - "ref height", - "Height of search region in pixel, must be multiple of 4", - 4, 32, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiEncoderH264:submb-mask: - * Defines the bit-mask for disabling sub-partition - * - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_SUBMB_MASK, - g_param_spec_flags ("submbpart-mask", - "submb part mask", - "defines the bit-mask for disabling sub mb partition", - GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, - GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:subpel-mode: - * defines the half/quarter pel modes - * 00: integer mode searching - * 01: half-pel mode searching - * 11: quarter-pel mode searching - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_SUBPEL_MODE, - g_param_spec_enum ("subpel-mode", - "subpel mode", - "Sub pixel precision for motion estimation", - GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, - GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiEncoderH264:intrapart-mask: - * Specifies which Luma Intra partition is enabled/disabled - * for intra mode decision - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_INTRA_PART_MASK, - g_param_spec_flags ("intrapart-mask", - "intra part mask", - "Specifies which Luma Intra partition is enabled/disabled for" - "intra mode decision", - GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, - GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:intra-sad: - * Specifies distortion measure adjustments used for - * the motion search SAD comparison. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_INTRA_SAD, - g_param_spec_enum ("intra-sad", - "intra sad", - "Specifies distortion measure adjustments used" - "in the motion search SAD comparison for intra MB", - GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:inter-sad: - * Specifies distortion measure adjustments used - * in the motion search SAD comparison for inter MB - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_INTER_SAD, - g_param_spec_enum ("inter-sad", - "inter sad", - "Specifies distortion measure adjustments used" - "in the motion search SAD comparison for inter MB", - GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:adaptive-search: - * Defines whether adaptive searching is enabled for IME - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_ADAPT_SEARCH, - g_param_spec_boolean ("adaptive-search", - "adaptive-search", - "Enable adaptive search", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiEncoderH264:multi-predL0: - * When set to 1, neighbor MV will be used as predictor for list L0, - * otherwise no neighbor MV will be used as predictor - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L0, - g_param_spec_boolean ("multi-predL0", - "multi predL0", - "Enable multi prediction for ref L0 list, when set neighbor MV will be used" - "as predictor, no neighbor MV will be used otherwise", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264:multi-predL1: - * When set to 1, neighbor MV will be used as predictor - * when set to 0, no neighbor MV will be used as predictor. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L1, - g_param_spec_boolean ("multi-predL1", - "multi predL1", - "Enable multi prediction for ref L1 list, when set neighbor MV will be used" - "as predictor, no neighbor MV will be used otherwise", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264Fei: fei-mode: - * - * Cose ENC, PAK, ENC_PAK, or ENC+PAK - * ENC: Only the Motion Estimation, no transformation or entropy coding - * PAK: transformation, quantization and entropy coding - * ENC_PAK: default mode, enc an pak are invoked by driver, middleware has - control over ENC input only - * ENC+PAK: enc and pak invoked separately, middleware has control over the ENC input, - ENC output, and PAK input - * Encoding mode which can be used for FEI - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_PROP_FEI_MODE, - g_param_spec_flags ("fei-mode", - "FEI Encoding Mode", - "Functional mode of FEI Encoding", - GST_VAAPI_TYPE_FEI_MODE, GST_VAAPI_FEI_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - return props; - -} - static const GstVaapiEncoderClassData fei_encoder_class_data = { .codec = GST_VAAPI_CODEC_H264, .packed_headers = SUPPORTED_PACKED_HEADERS, @@ -4334,8 +4070,6 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) encoder_class->class_data = &fei_encoder_class_data; encoder_class->reconfigure = gst_vaapi_encoder_h264_fei_reconfigure; - encoder_class->get_default_properties = - gst_vaapi_encoder_h264_fei_get_default_properties; encoder_class->reordering = gst_vaapi_encoder_h264_fei_reordering; encoder_class->encode = gst_vaapi_encoder_h264_fei_encode; encoder_class->flush = gst_vaapi_encoder_h264_fei_flush; @@ -4751,155 +4485,6 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) ENCODER_H264_FEI_N_PROPERTIES, properties); } -/** - * gst_vaapi_encoder_h264_fei_get_default_properties: - * - * Determines the set of common and H.264 specific encoder properties. - * The caller owns an extra reference to the resulting array of - * #GstVaapiEncoderPropInfo elements, so it shall be released with - * g_ptr_array_unref() after usage. - * - * Return value: the set of encoder properties for #GstVaapiEncoderH264Fei, - * or %NULL if an error occurred. - */ -GPtrArray * -gst_vaapi_encoder_h264_fei_get_default_properties (void) -{ - const GstVaapiEncoderClassData *class_data = &fei_encoder_class_data; - GPtrArray *props; - - props = gst_vaapi_encoder_properties_get_default (class_data); - if (!props) - return NULL; - - /** - * GstVaapiEncoderH264Fei:max-bframes: - * - * The number of B-frames between I and P. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_BFRAMES, - g_param_spec_uint ("max-bframes", - "Max B-Frames", "Number of B-frames between I and P", 0, 10, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264Fei:init-qp: - * - * The initial quantizer value. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_FEI_PROP_INIT_QP, - g_param_spec_uint ("init-qp", - "Initial QP", "Initial quantizer value", 0, 51, 26, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264Fei:min-qp: - * - * The minimum quantizer value. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_FEI_PROP_MIN_QP, - g_param_spec_uint ("min-qp", - "Minimum QP", "Minimum quantizer value", 0, 51, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264Fei:max-qp: - * - * The maximum quantizer value. - * - * Since: 1.18 - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_QP, - g_param_spec_uint ("max-qp", - "Maximum QP", "Maximum quantizer value", 0, 51, 51, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264Fei:num-slices: - * - * The number of slices per frame. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_SLICES, - g_param_spec_uint ("num-slices", - "Number of Slices", - "Number of slices per frame", - 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264Fei:cabac: - * - * Enable CABAC entropy coding mode for improved compression ratio, - * at the expense that the minimum target profile is Main. Default - * is CAVLC entropy coding mode. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_FEI_PROP_CABAC, - g_param_spec_boolean ("cabac", - "Enable CABAC", - "Enable CABAC entropy coding mode", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264Fei:dct8x8: - * - * Enable adaptive use of 8x8 transforms in I-frames. This improves - * the compression ratio by the minimum target profile is High. - * Default is to use 4x4 DCT only. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_FEI_PROP_DCT8X8, - g_param_spec_boolean ("dct8x8", - "Enable 8x8 DCT", - "Enable adaptive use of 8x8 transforms in I-frames", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264Fei:cpb-length: - * - * The size of the CPB buffer in milliseconds. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_FEI_PROP_CPB_LENGTH, - g_param_spec_uint ("cpb-length", - "CPB Length", "Length of the CPB buffer in milliseconds", - 1, 10000, DEFAULT_CPB_LENGTH, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoderH264Fei:num-views: - * - * The number of views for MVC encoding . - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS, - g_param_spec_uint ("num-views", - "Number of Views", - "Number of Views for MVC encoding", - 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiEncoderH264Fei:view-ids: - * - * The view ids for MVC encoding . - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS, - gst_param_spec_array ("view-ids", - "View IDs", "Set of View Ids used for MVC encoding", - g_param_spec_uint ("view-id-value", "View id value", - "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - props = gst_vaapi_encoder_h264_get_fei_properties (props); - - return props; -} - /** * gst_vaapi_encoder_h264_fei_set_max_profile: * @encoder: a #GstVaapiEncoderH264Fei diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h index 3ea86a7150..38b7a64d2d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h @@ -96,9 +96,6 @@ gst_vaapi_encoder_h264_fei_get_type (void) G_GNUC_CONST; GstVaapiEncoder * gst_vaapi_encoder_h264_fei_new (GstVaapiDisplay * display); -GPtrArray * -gst_vaapi_encoder_h264_fei_get_default_properties (void); - gboolean gst_vaapi_encoder_h264_fei_set_max_profile (GstVaapiEncoderH264Fei * encoder, GstVaapiProfile profile); From 80992191a347a34544502fdb8c8504c2e0a3117e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 15:16:26 +0800 Subject: [PATCH 3356/3781] libs: encoder: delete get_default_properties of feienc --- gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 330 ----------------------- gst-libs/gst/vaapi/gstvaapifeienc_h264.h | 3 - 2 files changed, 333 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index 24702b6c3e..ae6a15a8d0 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -2119,8 +2119,6 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) encoder_class->class_data = &fei_enc_class_data; encoder_class->reconfigure = gst_vaapi_feienc_h264_reconfigure; - encoder_class->get_default_properties = - gst_vaapi_feienc_h264_get_default_properties; encoder_class->reordering = gst_vaapi_feienc_h264_reordering; encoder_class->encode = gst_vaapi_feienc_h264_fake_encode; encoder_class->flush = gst_vaapi_feienc_h264_flush; @@ -2465,334 +2463,6 @@ gst_vaapi_feienc_h264_new (GstVaapiDisplay * display) return g_object_new (GST_TYPE_VAAPI_FEI_ENC_H264, "display", display, NULL); } -/** - * gst_vaapi_feienc_h264_get_fei_properties: - * - * Determines the set of common and H.264 Fei specific feienc properties. - * The caller owns an extra reference to the resulting array of - * #GstVaapiEncoderPropInfo elements, so it shall be released with - * g_ptr_array_unref() after usage. - * - * Return value: the set of feienc properties for #GstVaapiFeiEncH264, - * or %NULL if an error occurred. - */ -static GPtrArray * -gst_vaapi_feienc_h264_get_fei_properties (GPtrArray * props) -{ - /** - * GstVaapiFeiEncH264:num_mv_predictors_l0: - * - * The number of mv predict - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0, - g_param_spec_uint ("num-mvpredict-l0", - "Num mv predict l0", - "Indicate how many predictors should be used for l0", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiFeiEncH264:num_mv_predictors_l1: - * - * The number of mv predict - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1, - g_param_spec_uint ("num-mvpredict-l1", - "Num mv predict l1", - "Indicate how many predictors should be used for l1", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiFeiEncH264:search-window: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_WINDOW, - g_param_spec_enum ("search-window", - "search window", - "Specify one of the predefined search path", - GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiFeiEncH264:len-sp: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_LEN_SP, - g_param_spec_uint ("len-sp", - "len sp", - "This value defines number of search units in search path", - 1, 63, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:search-path: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_PATH, - g_param_spec_enum ("search-path", - "search path", - "Specify search path", - GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, - GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:ref-width: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_REF_WIDTH, - g_param_spec_uint ("ref-width", - "ref width", - "Width of search region in pixel, must be multiple of 4", - 4, 64, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:ref-height: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_REF_HEIGHT, - g_param_spec_uint ("ref-height", - "ref height", - "Height of search region in pixel, must be multiple of 4", - 4, 32, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiFeiEncH264:submb-mask: - * Defines the bit-mask for disabling sub-partition - * - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_SUBMB_MASK, - g_param_spec_flags ("submbpart-mask", - "submb part mask", - "defines the bit-mask for disabling sub mb partition", - GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, - GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:subpel-mode: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_SUBPEL_MODE, - g_param_spec_enum ("subpel-mode", - "subpel mode", - "Sub pixel precision for motion estimation", - GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, - GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiFeiEncH264:intrapart-mask: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_INTRA_PART_MASK, - g_param_spec_flags ("intrapart-mask", - "intra part mask", - "What block and sub-block partitions are disabled for intra MBs", - GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, - GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiFeiEncH264:intra-sad: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_INTRA_SAD, - g_param_spec_enum ("intra-sad", - "intra sad", - "Specifies distortion measure adjustments used in the motion search SAD comparison for intra MB", - GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:inter-sad: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_INTER_SAD, - g_param_spec_enum ("inter-sad", - "inter sad", - "Specifies distortion measure adjustments used in the motion search SAD comparison for inter MB", - GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:adaptive-search: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_ADAPT_SEARCH, - g_param_spec_boolean ("adaptive-search", - "adaptive-search", - "Enable adaptive search", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:multi-predL0: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L0, - g_param_spec_boolean ("multi-predL0", - "multi predL0", - "Enable multi prediction for ref L0 list", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:multi-predL0: - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L1, - g_param_spec_boolean ("multi-predL1", - "multi predL1", - "Enable multi prediction for ref L1 list", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - return props; - -} - -/** - * gst_vaapi_feienc_h264_get_default_properties: - * - * Determines the set of common and H.264 specific feienc properties. - * The caller owns an extra reference to the resulting array of - * #GstVaapiEncoderPropInfo elements, so it shall be released with - * g_ptr_array_unref() after usage. - * - * Return value: the set of feienc properties for #GstVaapiFeiEncH264, - * or %NULL if an error occurred. - */ -GPtrArray * -gst_vaapi_feienc_h264_get_default_properties (void) -{ - const GstVaapiEncoderClassData *class_data = &fei_enc_class_data; - GPtrArray *props; - - props = gst_vaapi_encoder_properties_get_default (class_data); - - if (!props) - return NULL; - - /** - * GstVaapiFeiEncH264:max-bframes: - * - * The number of B-frames between I and P. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_MAX_BFRAMES, - g_param_spec_uint ("max-bframes", - "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:init-qp: - * - * The initial quantizer value. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_INIT_QP, - g_param_spec_uint ("init-qp", - "Initial QP", "Initial quantizer value", 1, 51, 26, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:min-qp: - * - * The minimum quantizer value. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_MIN_QP, - g_param_spec_uint ("min-qp", - "Minimum QP", "Minimum quantizer value", 1, 51, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:num-slices: - * - * The number of slices per frame. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_NUM_SLICES, - g_param_spec_uint ("num-slices", - "Number of Slices", - "Number of slices per frame", - 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:cabac: - * - * Enable CABAC entropy coding mode for improved compression ratio, - * at the expense that the minimum target profile is Main. Default - * is CAVLC entropy coding mode. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_CABAC, - g_param_spec_boolean ("cabac", - "Enable CABAC", - "Enable CABAC entropy coding mode", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:dct8x8: - * - * Enable adaptive use of 8x8 transforms in I-frames. This improves - * the compression ratio by the minimum target profile is High. - * Default is to use 4x4 DCT only. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_DCT8X8, - g_param_spec_boolean ("dct8x8", - "Enable 8x8 DCT", - "Enable adaptive use of 8x8 transforms in I-frames", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:cpb-length: - * - * The size of the CPB buffer in milliseconds. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_CPB_LENGTH, - g_param_spec_uint ("cpb-length", - "CPB Length", "Length of the CPB buffer in milliseconds", - 1, 10000, DEFAULT_CPB_LENGTH, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiFeiEncH264:num-views: - * - * The number of views for MVC encoding . - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_NUM_VIEWS, - g_param_spec_uint ("num-views", - "Number of Views", - "Number of Views for MVC encoding", - 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiFeiEncH264:view-ids: - * - * The view ids for MVC encoding . - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_VIEW_IDS, - gst_param_spec_array ("view-ids", - "View IDs", "Set of View Ids used for MVC encoding", - g_param_spec_uint ("view-id-value", "View id value", - "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstVaapiFeiEncH264:num-ref: - * - * The number of reference frames. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_FEI_H264_ENC_PROP_NUM_REF, - g_param_spec_uint ("num-ref", - "Num Ref", - "reference frame number", - 1, 6, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - props = gst_vaapi_feienc_h264_get_fei_properties (props); - - return props; -} - /** * gst_vaapi_feienc_h264_set_max_profile: * @feienc: a #GstVaapiFeiEncH264 diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.h b/gst-libs/gst/vaapi/gstvaapifeienc_h264.h index ae681d026f..ffeab5d9a6 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.h +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.h @@ -94,9 +94,6 @@ gst_vaapi_feienc_h264_get_type (void) G_GNUC_CONST; GstVaapiEncoder * gst_vaapi_feienc_h264_new (GstVaapiDisplay * display); -GPtrArray * -gst_vaapi_feienc_h264_get_default_properties (void); - gboolean gst_vaapi_feienc_h264_set_max_profile (GstVaapiFeiEncH264 * feienc, GstVaapiProfile profile); From 8ce90bca1e117f36eb2598f7e6f738dd0ccb7371 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 15:19:10 +0800 Subject: [PATCH 3357/3781] libs: encoder: delete 3 useless init macro --- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index c2ac51091e..74699ae065 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -371,26 +371,6 @@ struct _GstVaapiEncoderClass gpointer * state); }; -#define GST_VAAPI_ENCODER_CLASS_HOOK(codec, func) \ - .func = G_PASTE (G_PASTE (G_PASTE (gst_vaapi_encoder_,codec),_), func) - -#define GST_VAAPI_ENCODER_CLASS_INIT_BASE(CODEC) \ - .parent_class = { \ - .size = sizeof (G_PASTE (GstVaapiEncoder, CODEC)), \ - .finalize = (GDestroyNotify) gst_vaapi_encoder_finalize \ - } - -#define GST_VAAPI_ENCODER_CLASS_INIT(CODEC, codec) \ - GST_VAAPI_ENCODER_CLASS_INIT_BASE (CODEC), \ - .class_data = &g_class_data, \ - GST_VAAPI_ENCODER_CLASS_HOOK (codec, init), \ - GST_VAAPI_ENCODER_CLASS_HOOK (codec, finalize), \ - GST_VAAPI_ENCODER_CLASS_HOOK (codec, reconfigure), \ - GST_VAAPI_ENCODER_CLASS_HOOK (codec, get_default_properties), \ - GST_VAAPI_ENCODER_CLASS_HOOK (codec, reordering), \ - GST_VAAPI_ENCODER_CLASS_HOOK (codec, encode), \ - GST_VAAPI_ENCODER_CLASS_HOOK (codec, flush) - G_GNUC_INTERNAL GstVaapiSurfaceProxy * gst_vaapi_encoder_create_surface (GstVaapiEncoder * From 46ce4e30543b8a6edbf3b160d5043094d49b72e8 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 15:31:16 +0800 Subject: [PATCH 3358/3781] plugin: encode: delete gst_vaapiencode_init_properties No need to init the properties got by get_default_properties func now. The properties are inited correctly in internal encoder class. --- gst/vaapi/gstvaapiencode.c | 50 -------------------------------------- gst/vaapi/gstvaapiencode.h | 4 --- 2 files changed, 54 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 5f09f828a5..efe85d8451 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -109,28 +109,6 @@ typedef struct GValue value; } PropValue; -static PropValue * -prop_value_new (GstVaapiEncoderPropInfo * prop) -{ - static const GValue default_value = G_VALUE_INIT; - PropValue *prop_value; - - if (!prop || !prop->pspec) - return NULL; - - prop_value = g_slice_new (PropValue); - if (!prop_value) - return NULL; - - prop_value->id = prop->prop; - prop_value->pspec = g_param_spec_ref (prop->pspec); - - memcpy (&prop_value->value, &default_value, sizeof (prop_value->value)); - g_value_init (&prop_value->value, prop->pspec->value_type); - g_param_value_set_default (prop->pspec, &prop_value->value); - return prop_value; -} - static void prop_value_free (PropValue * prop_value) { @@ -1003,34 +981,6 @@ get_properties (GstVaapiEncodeClass * klass) return klass->get_properties ? klass->get_properties () : NULL; } -gboolean -gst_vaapiencode_init_properties (GstVaapiEncode * encode) -{ - GPtrArray *const props = get_properties (GST_VAAPIENCODE_GET_CLASS (encode)); - guint i; - - /* XXX: use base_init()/base_finalize() to avoid multiple initializations */ - if (!props) - return FALSE; - - encode->prop_values = - g_ptr_array_new_full (props->len, (GDestroyNotify) prop_value_free); - if (!encode->prop_values) { - g_ptr_array_unref (props); - return FALSE; - } - - for (i = 0; i < props->len; i++) { - PropValue *const prop_value = prop_value_new ((GstVaapiEncoderPropInfo *) - g_ptr_array_index (props, i)); - if (!prop_value) - return FALSE; - g_ptr_array_add (encode->prop_values, prop_value); - } - g_ptr_array_unref (props); - return TRUE; -} - gboolean gst_vaapiencode_class_init_properties (GstVaapiEncodeClass * klass) { diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 742de05f7c..a552ac123b 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -104,10 +104,6 @@ struct _GstVaapiEncodeClass GType gst_vaapiencode_get_type (void) G_GNUC_CONST; -G_GNUC_INTERNAL -gboolean -gst_vaapiencode_init_properties (GstVaapiEncode * encode); - G_GNUC_INTERNAL gboolean gst_vaapiencode_class_init_properties (GstVaapiEncodeClass * encode_class); From 2ab5e0ef46b8f76c68eeda9ea20e88c959016592 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 15:43:45 +0800 Subject: [PATCH 3359/3781] plugin: encode: delete set/get_property func in encode class Use standard gobject's property functions to replace the old way. --- gst/vaapi/gstvaapiencode.c | 47 -------------------------------------- gst/vaapi/gstvaapiencode.h | 5 ---- 2 files changed, 52 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index efe85d8451..417323541c 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -125,17 +125,6 @@ prop_value_free (PropValue * prop_value) g_slice_free (PropValue, prop_value); } -static inline PropValue * -prop_value_lookup (GstVaapiEncode * encode, guint prop_id) -{ - GPtrArray *const prop_values = encode->prop_values; - - if (prop_values && - (prop_id >= PROP_BASE && prop_id < PROP_BASE + prop_values->len)) - return g_ptr_array_index (prop_values, prop_id - PROP_BASE); - return NULL; -} - static PropValue * prop_value_new_entry (guint id, GParamSpec * pspec, const GValue * value) { @@ -176,40 +165,6 @@ prop_value_lookup_entry (GPtrArray * prop_values, guint prop_id) return NULL; } - -static gboolean -gst_vaapiencode_default_get_property (GstVaapiEncode * encode, guint prop_id, - GValue * value) -{ - PropValue *const prop_value = prop_value_lookup (encode, prop_id); - - if (prop_value) { - g_value_copy (&prop_value->value, value); - return TRUE; - } - return FALSE; -} - -static gboolean -gst_vaapiencode_default_set_property (GstVaapiEncode * encode, guint prop_id, - const GValue * value) -{ - PropValue *const prop_value = prop_value_lookup (encode, prop_id); - GstVaapiEncoder *encoder = encode->encoder; - - if (prop_value) { - g_value_copy (value, &prop_value->value); - - if (encoder) - return (gst_vaapi_encoder_set_property (encoder, prop_value->id, - value) == GST_VAAPI_ENCODER_STATUS_SUCCESS); - - return TRUE; - } - - return FALSE; -} - static GstFlowReturn gst_vaapiencode_default_alloc_buffer (GstVaapiEncode * encode, GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr) @@ -967,8 +922,6 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) venc_class->flush = GST_DEBUG_FUNCPTR (gst_vaapiencode_flush); venc_class->sink_event = GST_DEBUG_FUNCPTR (gst_vaapiencode_sink_event); - klass->get_property = gst_vaapiencode_default_get_property; - klass->set_property = gst_vaapiencode_default_set_property; klass->alloc_buffer = gst_vaapiencode_default_alloc_buffer; venc_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapiencode_src_query); diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index a552ac123b..64efecb224 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -75,11 +75,6 @@ struct _GstVaapiEncodeClass guint prop_num; GPtrArray * (*get_properties) (void); - gboolean (*get_property) (GstVaapiEncode * encode, - guint prop_id, GValue * value); - gboolean (*set_property) (GstVaapiEncode * encode, - guint prop_id, const GValue * value); - gboolean (*set_config) (GstVaapiEncode * encode); GstCaps * (*get_caps) (GstVaapiEncode * encode); GstVaapiEncoder * (*alloc_encoder) (GstVaapiEncode * encode, From 258719e0ed1ed5a5049747b1bbdf74c8f51b57d9 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 15:52:04 +0800 Subject: [PATCH 3360/3781] plugin: encode: delete useless init_properties. Also delete the get_properties function in encode class. We now use g_object_class_list_properties to get all properties for internal encoder class. --- gst/vaapi/gstvaapiencode.c | 24 ------------------------ gst/vaapi/gstvaapiencode.h | 5 ----- 2 files changed, 29 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 417323541c..ecf25cc9db 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -928,30 +928,6 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) venc_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapiencode_sink_query); } -static inline GPtrArray * -get_properties (GstVaapiEncodeClass * klass) -{ - return klass->get_properties ? klass->get_properties () : NULL; -} - -gboolean -gst_vaapiencode_class_init_properties (GstVaapiEncodeClass * klass) -{ - GObjectClass *const object_class = G_OBJECT_CLASS (klass); - GPtrArray *const props = get_properties (klass); - guint i; - - if (!props) - return FALSE; - - for (i = 0; i < props->len; i++) { - GstVaapiEncoderPropInfo *const prop = g_ptr_array_index (props, i); - g_object_class_install_property (object_class, PROP_BASE + i, prop->pspec); - } - g_ptr_array_unref (props); - return TRUE; -} - /* Only used by the drived class */ void gst_vaapiencode_set_property_subclass (GObject * object, diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 64efecb224..2b8eab6d28 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -74,7 +74,6 @@ struct _GstVaapiEncodeClass GstVaapiPluginBaseClass parent_class; guint prop_num; - GPtrArray * (*get_properties) (void); gboolean (*set_config) (GstVaapiEncode * encode); GstCaps * (*get_caps) (GstVaapiEncode * encode); GstVaapiEncoder * (*alloc_encoder) (GstVaapiEncode * encode, @@ -99,10 +98,6 @@ struct _GstVaapiEncodeClass GType gst_vaapiencode_get_type (void) G_GNUC_CONST; -G_GNUC_INTERNAL -gboolean -gst_vaapiencode_class_init_properties (GstVaapiEncodeClass * encode_class); - G_GNUC_INTERNAL void gst_vaapiencode_set_property_subclass (GObject * object, From 69f7c95a295fd66fcabc57df31d080b82117f0f9 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 15:59:43 +0800 Subject: [PATCH 3361/3781] libs: encoder: delete properties_get_default for base class --- gst-libs/gst/vaapi/gstvaapiencoder.c | 123 ---------------------- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 4 - 2 files changed, 127 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index a496626d3b..d46e573e99 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -111,129 +111,6 @@ error_allocation_failed: } } -/* Generate the common set of encoder properties */ -GPtrArray * -gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClassData * - cdata) -{ - GPtrArray *props = NULL; - - g_assert (cdata->rate_control_get_type != NULL); - - /** - * GstVaapiEncoder:rate-control: - * - * The desired rate control mode, expressed as a #GstVaapiRateControl. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_PROP_RATECONTROL, - g_param_spec_enum ("rate-control", - "Rate Control", "Rate control mode", - cdata->rate_control_get_type (), cdata->default_rate_control, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoder:bitrate: - * - * The desired bitrate, expressed in kbps. - * This is available when rate-control is CBR or VBR. - * - * CBR: This applies equally to minimum, maximum and target bitrate in the driver. - * VBR: This applies to maximum bitrate in the driver. - * Minimum bitrate will be calculated like the following in the driver. - * if (target percentage < 50) minimum bitrate = 0 - * else minimum bitrate = maximum bitrate * (2 * target percentage -100) / 100 - * Target bitrate will be calculated like the following in the driver. - * target bitrate = maximum bitrate * target percentage / 100 - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_PROP_BITRATE, - g_param_spec_uint ("bitrate", - "Bitrate (kbps)", - "The desired bitrate expressed in kbps (0: auto-calculate)", - 0, 2000 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoder:target-percentage: - * - * The desired target percentage of bitrate for variable rate controls. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_PROP_TARGET_PERCENTAGE, - g_param_spec_uint ("target-percentage", - "Target Percentage", - "The desired target percentage of bitrate for variable rate " - "controls.", 1, 100, 70, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoder:keyframe-period: - * - * The maximal distance between two keyframes. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, - g_param_spec_uint ("keyframe-period", - "Keyframe Period", - "Maximal distance between two keyframes (0: auto-calculate)", 0, - G_MAXUINT32, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoder:tune: - * - * The desired encoder tuning option. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_PROP_TUNE, - g_param_spec_enum ("tune", - "Encoder Tuning", - "Encoder tuning option", - cdata->encoder_tune_get_type (), cdata->default_encoder_tune, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVaapiEncoder:quality-level: - * - * The Encoding quality level. - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_PROP_QUALITY_LEVEL, - g_param_spec_uint ("quality-level", - "Quality Level", "Encoding Quality Level " - "(lower value means higher-quality/slow-encode, " - " higher value means lower-quality/fast-encode)", - 1, 7, 4, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstVapiEncoder:roi-default-delta-qp - * - * Default delta-qp to apply to each Region of Interest - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_PROP_DEFAULT_ROI_VALUE, - g_param_spec_int ("default-roi-delta-qp", "Default ROI delta QP", - "The default delta-qp to apply to each Region of Interest" - "(lower value means higher-quality, " - "higher value means lower-quality)", - -10, 10, -10, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - - /** - * GstVaapiEncoder: trellis: - * - * The trellis quantization method the encoder can use. - * Trellis is an improved quantization algorithm. - * - */ - GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, - GST_VAAPI_ENCODER_PROP_TRELLIS, - g_param_spec_boolean ("trellis", - "Trellis Quantization", - "The Trellis Quantization Method of Encoder", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - return props; -} - gboolean gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder, GstVaapiEncPicture * picture) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 74699ae065..19a03192ff 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -238,10 +238,6 @@ GPtrArray * gst_vaapi_encoder_properties_append (GPtrArray * props, gint prop_id, GParamSpec *pspec); -G_GNUC_INTERNAL -GPtrArray * -gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClassData *cdata); - struct _GstVaapiEncoder { /*< private >*/ From 25b6be1780bc4b3bc37a4b86d96f041853153014 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 16:13:19 +0800 Subject: [PATCH 3362/3781] libs: encoder: delete encoder_set_property We no longer need this obsolete set_property function now after switch to standard gobject's property manner. Also delete the old encoder's property enum in the header file. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 160 ++------------------------- gst-libs/gst/vaapi/gstvaapiencoder.h | 30 ----- 2 files changed, 7 insertions(+), 183 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index d46e573e99..87060542fb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -67,8 +67,9 @@ prop_free (GstVaapiEncoderPropData * prop) } /* Helper function to lookup the supplied property specification */ -static GParamSpec * -prop_find_pspec (GstVaapiEncoder * encoder, gint prop_id) +__attribute__ ((unused)) + static GParamSpec *prop_find_pspec (GstVaapiEncoder * encoder, + gint prop_id) { GPtrArray *const props = encoder->properties; guint i; @@ -1045,116 +1046,6 @@ gst_vaapi_encoder_set_codec_state (GstVaapiEncoder * encoder, return gst_vaapi_encoder_reconfigure_internal (encoder); } -/** - * gst_vaapi_encoder_set_property: - * @encoder: a #GstVaapiEncoder - * @prop_id: the id of the property to change - * @value: the new value to set - * - * Update the requested property, designed by @prop_id, with the - * supplied @value. A @NULL value argument resets the property to its - * default value. - * - * Return value: a #GstVaapiEncoderStatus - */ -static GstVaapiEncoderStatus -set_property (GstVaapiEncoder * encoder, gint prop_id, const GValue * value) -{ - GstVaapiEncoderStatus status = - GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - - g_assert (value != NULL); - - /* Handle codec-specific properties */ - if (prop_id < 0) { - GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder); - - if (klass->set_property) { - if (encoder->num_codedbuf_queued > 0) - goto error_operation_failed; - status = klass->set_property (encoder, prop_id, value); - } - return status; - } - - /* Handle common properties */ - switch (prop_id) { - case GST_VAAPI_ENCODER_PROP_RATECONTROL: - status = gst_vaapi_encoder_set_rate_control (encoder, - g_value_get_enum (value)); - break; - case GST_VAAPI_ENCODER_PROP_BITRATE: - status = gst_vaapi_encoder_set_bitrate (encoder, - g_value_get_uint (value)); - break; - case GST_VAAPI_ENCODER_PROP_TARGET_PERCENTAGE: - status = gst_vaapi_encoder_set_target_percentage (encoder, - g_value_get_uint (value)); - break; - case GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD: - status = gst_vaapi_encoder_set_keyframe_period (encoder, - g_value_get_uint (value)); - break; - case GST_VAAPI_ENCODER_PROP_TUNE: - status = gst_vaapi_encoder_set_tuning (encoder, g_value_get_enum (value)); - break; - case GST_VAAPI_ENCODER_PROP_QUALITY_LEVEL: - status = gst_vaapi_encoder_set_quality_level (encoder, - g_value_get_uint (value)); - break; - case GST_VAAPI_ENCODER_PROP_DEFAULT_ROI_VALUE: - encoder->default_roi_value = g_value_get_int (value); - status = GST_VAAPI_ENCODER_STATUS_SUCCESS; - break; - case GST_VAAPI_ENCODER_PROP_TRELLIS: - status = - gst_vaapi_encoder_set_trellis (encoder, g_value_get_boolean (value)); - break; - } - return status; - - /* ERRORS */ -error_operation_failed: - { - GST_ERROR ("could not change codec state after encoding started"); - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; - } -} - -GstVaapiEncoderStatus -gst_vaapi_encoder_set_property (GstVaapiEncoder * encoder, gint prop_id, - const GValue * value) -{ - GstVaapiEncoderStatus status; - GValue default_value = G_VALUE_INIT; - - g_return_val_if_fail (encoder != NULL, - GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER); - - if (!value) { - GParamSpec *const pspec = prop_find_pspec (encoder, prop_id); - if (!pspec) - goto error_invalid_property; - - g_value_init (&default_value, pspec->value_type); - g_param_value_set_default (pspec, &default_value); - value = &default_value; - } - - status = set_property (encoder, prop_id, value); - - if (default_value.g_type) - g_value_unset (&default_value); - return status; - - /* ERRORS */ -error_invalid_property: - { - GST_ERROR ("unsupported property (%d)", prop_id); - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - } -} - /* Determine the supported rate control modes */ static guint get_rate_control_mask (GstVaapiEncoder * encoder) @@ -1454,7 +1345,7 @@ enum static GParamSpec *properties[ENCODER_N_PROPERTIES]; static void -_gst_vaapi_encoder_set_property (GObject * object, guint prop_id, +gst_vaapi_encoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); @@ -1505,7 +1396,7 @@ _gst_vaapi_encoder_set_property (GObject * object, guint prop_id, } static void -_gst_vaapi_encoder_get_property (GObject * object, guint prop_id, +gst_vaapi_encoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); @@ -1580,50 +1471,13 @@ gst_vaapi_encoder_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapi_encoder_parent_class)->finalize (object); } -__attribute__ ((unused)) - static void - encoder_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); - - switch (prop_id) { - case ENCODER_PROP_DISPLAY: - g_assert (encoder->display == NULL); - encoder->display = g_value_dup_object (value); - g_assert (encoder->display != NULL); - encoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY (encoder->display); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -__attribute__ ((unused)) - static void - encoder_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); - - switch (prop_id) { - case ENCODER_PROP_DISPLAY: - g_value_set_object (value, encoder->display); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static void gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); - object_class->set_property = _gst_vaapi_encoder_set_property; - object_class->get_property = _gst_vaapi_encoder_get_property; + object_class->set_property = gst_vaapi_encoder_set_property; + object_class->get_property = gst_vaapi_encoder_get_property; object_class->finalize = gst_vaapi_encoder_finalize; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 98c6bc1ad6..72254c3995 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -122,32 +122,6 @@ typedef enum { GST_VAAPI_ENCODER_MBBRC_OFF = 2, } GstVaapiEncoderMbbrc; -/** - * GstVaapiEncoderProp: - * @GST_VAAPI_ENCODER_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). - * @GST_VAAPI_ENCODER_PROP_BITRATE: Bitrate expressed in kbps (uint). - * @GST_VAAPI_ENCODER_PROP_TARGET_PERCENTAGE: Desired target percentage of - * bitrate for variable rate controls. - * @GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD: The maximal distance - * between two keyframes (uint). - * @GST_VAAPI_ENCODER_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). - * @GST_VAAPI_ENCODER_PROP_DEFAULT_ROI_VALUE: The default delta qp to apply - * to each region of interest. - * @GST_VAAPI_ENCODER_PROP_TRELLIS: Use trellis quantization method (gboolean). - * - * The set of configurable properties for the encoder. - */ -typedef enum { - GST_VAAPI_ENCODER_PROP_RATECONTROL = 1, - GST_VAAPI_ENCODER_PROP_BITRATE, - GST_VAAPI_ENCODER_PROP_TARGET_PERCENTAGE, - GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, - GST_VAAPI_ENCODER_PROP_TUNE, - GST_VAAPI_ENCODER_PROP_QUALITY_LEVEL, - GST_VAAPI_ENCODER_PROP_DEFAULT_ROI_VALUE, - GST_VAAPI_ENCODER_PROP_TRELLIS -} GstVaapiEncoderProp; - /** * GstVaapiEncoderPropInfo: * @prop: the #GstVaapiEncoderProp @@ -184,10 +158,6 @@ GstVaapiEncoderStatus gst_vaapi_encoder_set_codec_state (GstVaapiEncoder * encoder, GstVideoCodecState * state); -GstVaapiEncoderStatus -gst_vaapi_encoder_set_property (GstVaapiEncoder * encoder, gint prop_id, - const GValue * value); - GstVaapiEncoderStatus gst_vaapi_encoder_set_rate_control (GstVaapiEncoder * encoder, GstVaapiRateControl rate_control); From adcb448276456115e36d2b4e3535266251397c42 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 18:17:42 +0800 Subject: [PATCH 3363/3781] libs: encoder: delete EncoderPropInfo related functions --- gst-libs/gst/vaapi/gstvaapiencoder.c | 78 ----------------------- gst-libs/gst/vaapi/gstvaapiencoder.h | 12 ---- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 17 ----- 3 files changed, 107 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 87060542fb..b6ef77c56b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -34,84 +34,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -/* Helper function to create a new encoder property object */ -static GstVaapiEncoderPropData * -prop_new (gint id, GParamSpec * pspec) -{ - GstVaapiEncoderPropData *prop; - - if (!id || !pspec) - return NULL; - - prop = g_slice_new (GstVaapiEncoderPropData); - if (!prop) - return NULL; - - prop->prop = id; - prop->pspec = g_param_spec_ref_sink (pspec); - return prop; -} - -/* Helper function to release a property object and any memory held herein */ -static void -prop_free (GstVaapiEncoderPropData * prop) -{ - if (!prop) - return; - - if (prop->pspec) { - g_param_spec_unref (prop->pspec); - prop->pspec = NULL; - } - g_slice_free (GstVaapiEncoderPropData, prop); -} - -/* Helper function to lookup the supplied property specification */ -__attribute__ ((unused)) - static GParamSpec *prop_find_pspec (GstVaapiEncoder * encoder, - gint prop_id) -{ - GPtrArray *const props = encoder->properties; - guint i; - - if (props) { - for (i = 0; i < props->len; i++) { - GstVaapiEncoderPropInfo *const prop = g_ptr_array_index (props, i); - if (prop->prop == prop_id) - return prop->pspec; - } - } - return NULL; -} - -/* Create a new array of properties, or NULL on error */ -GPtrArray * -gst_vaapi_encoder_properties_append (GPtrArray * props, gint prop_id, - GParamSpec * pspec) -{ - GstVaapiEncoderPropData *prop; - - if (!props) { - props = g_ptr_array_new_with_free_func ((GDestroyNotify) prop_free); - if (!props) - return NULL; - } - - prop = prop_new (prop_id, pspec); - if (!prop) - goto error_allocation_failed; - g_ptr_array_add (props, prop); - return props; - - /* ERRORS */ -error_allocation_failed: - { - GST_ERROR ("failed to allocate encoder property info structure"); - g_ptr_array_unref (props); - return NULL; - } -} - gboolean gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder, GstVaapiEncPicture * picture) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 72254c3995..71502239b7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -122,18 +122,6 @@ typedef enum { GST_VAAPI_ENCODER_MBBRC_OFF = 2, } GstVaapiEncoderMbbrc; -/** - * GstVaapiEncoderPropInfo: - * @prop: the #GstVaapiEncoderProp - * @pspec: the #GParamSpec describing the associated configurable value - * - * A #GstVaapiEncoderProp descriptor. - */ -typedef struct { - const gint prop; - GParamSpec *const pspec; -} GstVaapiEncoderPropInfo; - GType gst_vaapi_encoder_tune_get_type (void) G_GNUC_CONST; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 19a03192ff..5cda1cdea9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -221,23 +221,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass; typedef struct _GstVaapiEncoderClassData GstVaapiEncoderClassData; -/* Private GstVaapiEncoderPropInfo definition */ -typedef struct { - gint prop; - GParamSpec *pspec; -} GstVaapiEncoderPropData; - -#define GST_VAAPI_ENCODER_PROPERTIES_APPEND(props, id, pspec) do { \ - props = gst_vaapi_encoder_properties_append (props, id, pspec); \ - if (!props) \ - return NULL; \ - } while (0) - -G_GNUC_INTERNAL -GPtrArray * -gst_vaapi_encoder_properties_append (GPtrArray * props, gint prop_id, - GParamSpec *pspec); - struct _GstVaapiEncoder { /*< private >*/ From c028d7a4139d8dcc16a3834092c4e541a7241580 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 18:30:07 +0800 Subject: [PATCH 3364/3781] libs: encoder: delete old set_property and property enum in h264 --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 72 ----------------------- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 49 --------------- 2 files changed, 121 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 294892694f..13295a2fd4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3587,77 +3587,6 @@ enum static GParamSpec *properties[ENCODER_H264_N_PROPERTIES]; -static GstVaapiEncoderStatus -_gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder, - gint prop_id, const GValue * value) -{ - GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); - - switch (prop_id) { - case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES: - encoder->num_bframes = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_INIT_QP: - encoder->init_qp = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_MIN_QP: - encoder->min_qp = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_QP_IP: - encoder->qp_ip = g_value_get_int (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_QP_IB: - encoder->qp_ib = g_value_get_int (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES: - encoder->num_slices = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_CABAC: - encoder->use_cabac = g_value_get_boolean (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_DCT8X8: - encoder->use_dct8x8 = g_value_get_boolean (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH: - encoder->cpb_length = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: - encoder->num_views = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS: - set_view_ids (encoder, value); - break; - case GST_VAAPI_ENCODER_H264_PROP_AUD: - encoder->use_aud = g_value_get_boolean (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE: - encoder->compliance_mode = g_value_get_enum (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES: - encoder->num_ref_frames = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_MBBRC: - encoder->mbbrc = g_value_get_enum (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS: - encoder->temporal_levels = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE: - encoder->prediction_type = g_value_get_enum (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_MAX_QP: - encoder->max_qp = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_QUALITY_FACTOR: - encoder->quality_factor = g_value_get_uint (value); - break; - - default: - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - static void gst_vaapi_encoder_h264_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -3830,7 +3759,6 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) encoder_class->reordering = gst_vaapi_encoder_h264_reordering; encoder_class->encode = gst_vaapi_encoder_h264_encode; encoder_class->flush = gst_vaapi_encoder_h264_flush; - encoder_class->set_property = _gst_vaapi_encoder_h264_set_property; encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data; encoder_class->get_pending_reordered = gst_vaapi_encoder_h264_get_pending_reordered; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 93d874b937..31a6f7aeee 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -39,55 +39,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264; typedef struct _GstVaapiEncoderH264Class GstVaapiEncoderH264Class; -/** - * GstVaapiEncoderH264Prop: - * @GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES: Number of B-frames between I - * and P (uint). - * @GST_VAAPI_ENCODER_H264_PROP_INIT_QP: Initial quantizer value (uint). - * @GST_VAAPI_ENCODER_H264_PROP_MIN_QP: Minimal quantizer value (uint). - * @GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES: Number of slices per frame (uint). - * @GST_VAAPI_ENCODER_H264_PROP_CABAC: Enable CABAC entropy coding mode (bool). - * @GST_VAAPI_ENCODER_H264_PROP_DCT8X8: Enable adaptive use of 8x8 - * transforms in I-frames (bool). - * @GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH: Length of the CPB buffer - * in milliseconds (uint). - * @GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS: Number of views per frame. - * @GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS: View IDs - * @GST_VAAPI_ENCODER_H264_PROP_AUD: Insert AUD as first NAL per frame. - * @GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE: Relax Compliance restrictions - * @GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES: Maximum number of reference frames. - * @GST_VAAPI_ENCODER_H264_PROP_MBBRC: Macroblock level Bitrate Control. - * @GST_VAAPI_ENCODER_H264_PROP_QP_IP: Difference of QP between I and P frame. - * @GST_VAAPI_ENCODER_H264_PROP_QP_IB: Difference of QP between I and B frame. - * @GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS: Number of temporal levels - * @GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE: Reference picture selection modes - * @GST_VAAPI_ENCODER_H264_PROP_MAX_QP: Maximal quantizer value (uint). - * @GST_VAAPI_ENCODER_H264_PROP_QUALITY_FACTOR: Factor for ICQ/QVBR bitrate control mode. - * - * The set of H.264 encoder specific configurable properties. - */ -typedef enum { - GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES = -1, - GST_VAAPI_ENCODER_H264_PROP_INIT_QP = -2, - GST_VAAPI_ENCODER_H264_PROP_MIN_QP = -3, - GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES = -4, - GST_VAAPI_ENCODER_H264_PROP_CABAC = -5, - GST_VAAPI_ENCODER_H264_PROP_DCT8X8 = -6, - GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH = -7, - GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS = -8, - GST_VAAPI_ENCODER_H264_PROP_VIEW_IDS = -9, - GST_VAAPI_ENCODER_H264_PROP_AUD = -10, - GST_VAAPI_ENCODER_H264_PROP_COMPLIANCE_MODE = -11, - GST_VAAPI_ENCODER_H264_PROP_NUM_REF_FRAMES = -12, - GST_VAAPI_ENCODER_H264_PROP_MBBRC = -13, - GST_VAAPI_ENCODER_H264_PROP_QP_IP = -14, - GST_VAAPI_ENCODER_H264_PROP_QP_IB = -15, - GST_VAAPI_ENCODER_H264_PROP_TEMPORAL_LEVELS = -16, - GST_VAAPI_ENCODER_H264_PROP_PREDICTION_TYPE = -17, - GST_VAAPI_ENCODER_H264_PROP_MAX_QP = -18, - GST_VAAPI_ENCODER_H264_PROP_QUALITY_FACTOR = -19, -} GstVaapiEncoderH264Prop; - GType gst_vaapi_encoder_h264_get_type (void) G_GNUC_CONST; From c70dbb0b794a321a6accae77990e895df7d6850e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 18:31:56 +0800 Subject: [PATCH 3365/3781] libs: encoder: delete old set_property and property enum in h265 --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 48 ----------------------- gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 32 --------------- 2 files changed, 80 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 4861ad3762..bc7e7296b5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2663,53 +2663,6 @@ gst_vaapi_encoder_h265_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapi_encoder_h265_parent_class)->finalize (object); } -static GstVaapiEncoderStatus -_gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder, - gint prop_id, const GValue * value) -{ - GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder); - - switch (prop_id) { - case GST_VAAPI_ENCODER_H265_PROP_MAX_BFRAMES: - encoder->num_bframes = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H265_PROP_INIT_QP: - encoder->init_qp = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H265_PROP_MIN_QP: - encoder->min_qp = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H265_PROP_QP_IP: - encoder->qp_ip = g_value_get_int (value); - break; - case GST_VAAPI_ENCODER_H265_PROP_QP_IB: - encoder->qp_ib = g_value_get_int (value); - break; - case GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES: - encoder->num_slices = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH: - encoder->cpb_length = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES: - encoder->num_ref_frames = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H265_PROP_MBBRC: - encoder->mbbrc = g_value_get_enum (value); - break; - case GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B: - encoder->low_delay_b = g_value_get_boolean (value); - break; - case GST_VAAPI_ENCODER_H265_PROP_MAX_QP: - encoder->max_qp = g_value_get_uint (value); - break; - - default: - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - /** * @ENCODER_H265_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). * @ENCODER_H265_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). @@ -2873,7 +2826,6 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) encoder_class->reordering = gst_vaapi_encoder_h265_reordering; encoder_class->encode = gst_vaapi_encoder_h265_encode; encoder_class->flush = gst_vaapi_encoder_h265_flush; - encoder_class->set_property = _gst_vaapi_encoder_h265_set_property; encoder_class->get_codec_data = gst_vaapi_encoder_h265_get_codec_data; encoder_class->get_pending_reordered = gst_vaapi_encoder_h265_get_pending_reordered; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index 1e18ed9642..e9ea5e2221 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -38,38 +38,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiEncoderH265 GstVaapiEncoderH265; typedef struct _GstVaapiEncoderH265Class GstVaapiEncoderH265Class; -/** - * GstVaapiEncoderH265Prop: - * @GST_VAAPI_ENCODER_H265_PROP_MAX_BFRAMES: Number of B-frames between I - * and P (uint). - * @GST_VAAPI_ENCODER_H265_PROP_INIT_QP: Initial quantizer value (uint). - * @GST_VAAPI_ENCODER_H265_PROP_MIN_QP: Minimal quantizer value (uint). - * @GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES: Number of slices per frame (uint). - * @GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES: Maximum number of reference frames. - * @GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH: Length of the CPB buffer - * in milliseconds (uint). - * @GST_VAAPI_ENCODER_H265_PROP_MBBRC: Macroblock level Bitrate Control. - * @GST_VAAPI_ENCODER_H265_PROP_QP_IP: Difference of QP between I and P frame. - * @GST_VAAPI_ENCODER_H265_PROP_QP_IB: Difference of QP between I and B frame. - * @GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B: use low delay b feature. - * @GST_VAAPI_ENCODER_H265_PROP_MAX_QP: Maximal quantizer value (uint). - * - * The set of H.265 encoder specific configurable properties. - */ -typedef enum { - GST_VAAPI_ENCODER_H265_PROP_MAX_BFRAMES = -1, - GST_VAAPI_ENCODER_H265_PROP_INIT_QP = -2, - GST_VAAPI_ENCODER_H265_PROP_MIN_QP = -3, - GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES = -4, - GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES = -5, - GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH = -7, - GST_VAAPI_ENCODER_H265_PROP_MBBRC = -8, - GST_VAAPI_ENCODER_H265_PROP_QP_IP = -9, - GST_VAAPI_ENCODER_H265_PROP_QP_IB = -10, - GST_VAAPI_ENCODER_H265_PROP_LOW_DELAY_B = -11, - GST_VAAPI_ENCODER_H265_PROP_MAX_QP = -12, -} GstVaapiEncoderH265Prop; - GType gst_vaapi_encoder_h265_get_type (void) G_GNUC_CONST; From 1b85ce488213901fb3f7379745b3f9ccf7e3af9f Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 18:34:57 +0800 Subject: [PATCH 3366/3781] libs: encoder: delete old set_property and property enum in jpeg --- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 17 ----------------- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h | 10 ---------- 2 files changed, 27 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 816ae0664e..bb920b6ec8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -762,22 +762,6 @@ gst_vaapi_encoder_jpeg_init (GstVaapiEncoderJpeg * encoder) memset (&encoder->huff_tables, 0, sizeof (encoder->huff_tables)); } -static GstVaapiEncoderStatus -_gst_vaapi_encoder_jpeg_set_property (GstVaapiEncoder * base_encoder, - gint prop_id, const GValue * value) -{ - GstVaapiEncoderJpeg *const encoder = GST_VAAPI_ENCODER_JPEG (base_encoder); - - switch (prop_id) { - case GST_VAAPI_ENCODER_JPEG_PROP_QUALITY: - encoder->quality = g_value_get_uint (value); - break; - default: - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - /** * @ENCODER_JPEG_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). * @ENCODER_JPEG_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). @@ -859,7 +843,6 @@ gst_vaapi_encoder_jpeg_class_init (GstVaapiEncoderJpegClass * klass) encoder_class->reordering = gst_vaapi_encoder_jpeg_reordering; encoder_class->encode = gst_vaapi_encoder_jpeg_encode; encoder_class->flush = gst_vaapi_encoder_jpeg_flush; - encoder_class->set_property = _gst_vaapi_encoder_jpeg_set_property; object_class->set_property = gst_vaapi_encoder_jpeg_set_property; object_class->get_property = gst_vaapi_encoder_jpeg_get_property; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h index ba082f908e..375658215e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h @@ -37,16 +37,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiEncoderJpeg GstVaapiEncoderJpeg; typedef struct _GstVaapiEncoderJpegClass GstVaapiEncoderJpegClass; -/** - * GstVaapiEncoderJpegProp: - * @GST_VAAPI_ENCODER_JPEG_PROP_QUALITY: Quality Factor value (uint). - * - * The set of JPEG encoder specific configurable properties. - */ -typedef enum { - GST_VAAPI_ENCODER_JPEG_PROP_QUALITY = -1 -} GstVaapiEncoderJpegProp; - GType gst_vaapi_encoder_jpeg_get_type (void) G_GNUC_CONST; From 3dcd79e439c70b1f7745f6c463921e1b1edb5e0c Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 18:35:59 +0800 Subject: [PATCH 3367/3781] libs: encoder: delete old set_property and property enum in mpeg2 --- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 21 --------------------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 13 ------------- 2 files changed, 34 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 98cc5f9df4..e5e66c62a7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -782,26 +782,6 @@ gst_vaapi_encoder_mpeg2_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapi_encoder_mpeg2_parent_class)->finalize (object); } -static GstVaapiEncoderStatus -_gst_vaapi_encoder_mpeg2_set_property (GstVaapiEncoder * base_encoder, - gint prop_id, const GValue * value) -{ - GstVaapiEncoderMpeg2 *const encoder = - GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder); - - switch (prop_id) { - case GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER: - encoder->cqp = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES: - encoder->ip_period = g_value_get_uint (value); - break; - default: - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - /** * @ENCODER_MPEG2_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). * @ENCODER_MPEG2_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). @@ -892,7 +872,6 @@ gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass) encoder_class->reordering = gst_vaapi_encoder_mpeg2_reordering; encoder_class->encode = gst_vaapi_encoder_mpeg2_encode; encoder_class->flush = gst_vaapi_encoder_mpeg2_flush; - encoder_class->set_property = _gst_vaapi_encoder_mpeg2_set_property; object_class->set_property = gst_vaapi_encoder_mpeg2_set_property; object_class->get_property = gst_vaapi_encoder_mpeg2_get_property; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h index dbd1f012c6..6306bfd4b2 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -38,19 +38,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiEncoderMpeg2 GstVaapiEncoderMpeg2; typedef struct _GstVaapiEncoderMpeg2Class GstVaapiEncoderMpeg2Class; -/** - * GstVaapiEncoderMpeg2Prop: - * @GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER: Constant quantizer value (uint). - * @GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES: Number of B-frames between I - * and P (uint). - * - * The set of MPEG-2 encoder specific configurable properties. - */ -typedef enum { - GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER = -1, - GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES = -2, -} GstVaapiEncoderMpeg2Prop; - GType gst_vaapi_encoder_mpeg2_get_type (void) G_GNUC_CONST; From c92b4f1bb7e93309f8e17694968843cfe9b1e3f6 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 18:36:51 +0800 Subject: [PATCH 3368/3781] libs: encoder: delete old set_property and property enum in vp8 --- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 23 ----------------------- gst-libs/gst/vaapi/gstvaapiencoder_vp8.h | 14 -------------- 2 files changed, 37 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 76c91c6f85..77830de965 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -535,28 +535,6 @@ gst_vaapi_encoder_vp8_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapi_encoder_vp8_parent_class)->finalize (object); } -static GstVaapiEncoderStatus -_gst_vaapi_encoder_vp8_set_property (GstVaapiEncoder * base_encoder, - gint prop_id, const GValue * value) -{ - GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder); - - switch (prop_id) { - case GST_VAAPI_ENCODER_VP8_PROP_LOOP_FILTER_LEVEL: - encoder->loop_filter_level = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_VP8_PROP_SHARPNESS_LEVEL: - encoder->sharpness_level = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_VP8_PROP_YAC_Q_INDEX: - encoder->yac_qi = g_value_get_uint (value); - break; - default: - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - /** * @ENCODER_VP8_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). * @ENCODER_VP8_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). @@ -654,7 +632,6 @@ gst_vaapi_encoder_vp8_class_init (GstVaapiEncoderVP8Class * klass) encoder_class->reordering = gst_vaapi_encoder_vp8_reordering; encoder_class->encode = gst_vaapi_encoder_vp8_encode; encoder_class->flush = gst_vaapi_encoder_vp8_flush; - encoder_class->set_property = _gst_vaapi_encoder_vp8_set_property; object_class->set_property = gst_vaapi_encoder_vp8_set_property; object_class->get_property = gst_vaapi_encoder_vp8_get_property; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h index a43373c531..b798edb4df 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h @@ -37,20 +37,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiEncoderVP8 GstVaapiEncoderVP8; typedef struct _GstVaapiEncoderVP8Class GstVaapiEncoderVP8Class; -/** - * GstVaapiEncoderVP8Prop: - * @GST_VAAPI_ENCODER_VP8_PROP_LOOP_FILTER_LEVEL: Loop Filter Level(uint). - * @GST_VAAPI_ENCODER_VP8_PROP_LOOP_SHARPNESS_LEVEL: Sharpness Level(uint). - * @GST_VAAPI_ENCODER_VP8_PROP_YAC_Q_INDEX: Quantization table index for luma AC(uint). - * - * The set of VP8 encoder specific configurable properties. - */ -typedef enum { - GST_VAAPI_ENCODER_VP8_PROP_LOOP_FILTER_LEVEL = -1, - GST_VAAPI_ENCODER_VP8_PROP_SHARPNESS_LEVEL = -2, - GST_VAAPI_ENCODER_VP8_PROP_YAC_Q_INDEX = -3 -} GstVaapiEncoderVP8Prop; - GType gst_vaapi_encoder_vp8_get_type (void) G_GNUC_CONST; From 617ffd81563301f9c1cc3e9e1028eb4aa701d8fa Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 18:37:58 +0800 Subject: [PATCH 3369/3781] libs: encoder: delete old set_property and property enum in vp9 --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 29 ------------------------ gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 18 --------------- 2 files changed, 47 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 30a22bfd7e..64f899825f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -556,34 +556,6 @@ gst_vaapi_encoder_vp9_init (GstVaapiEncoderVP9 * encoder) encoder->ref_list_idx = 0; } -static GstVaapiEncoderStatus -_gst_vaapi_encoder_vp9_set_property (GstVaapiEncoder * base_encoder, - gint prop_id, const GValue * value) -{ - GstVaapiEncoderVP9 *const encoder = GST_VAAPI_ENCODER_VP9 (base_encoder); - - switch (prop_id) { - case GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL: - encoder->loop_filter_level = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_VP9_PROP_SHARPNESS_LEVEL: - encoder->sharpness_level = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX: - encoder->yac_qi = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE: - encoder->ref_pic_mode = g_value_get_enum (value); - break; - case GST_VAAPI_ENCODER_VP9_PROP_CPB_LENGTH: - encoder->cpb_length = g_value_get_uint (value); - break; - default: - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - /** * @ENCODER_VP9_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). * @ENCODER_VP9_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). @@ -697,7 +669,6 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) encoder_class->reordering = gst_vaapi_encoder_vp9_reordering; encoder_class->encode = gst_vaapi_encoder_vp9_encode; encoder_class->flush = gst_vaapi_encoder_vp9_flush; - encoder_class->set_property = _gst_vaapi_encoder_vp9_set_property; object_class->set_property = gst_vaapi_encoder_vp9_set_property; object_class->get_property = gst_vaapi_encoder_vp9_get_property; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h index b2f7424cad..ece52dac64 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -37,24 +37,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiEncoderVP9 GstVaapiEncoderVP9; typedef struct _GstVaapiEncoderVP9Class GstVaapiEncoderVP9Class; -/** - * GstVaapiEncoderVP9Prop: - * @GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL: Loop Filter Level(uint). - * @GST_VAAPI_ENCODER_VP9_PROP_LOOP_SHARPNESS_LEVEL: Sharpness Level(uint). - * @GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX: Quantization table index for luma AC - * @GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE: Reference picute selection modes - * @GST_VAAPI_ENCODER_VP9_PROP_CPB_LENGTH:Length of CPB buffer in milliseconds - * - * The set of VP9 encoder specific configurable properties. - */ -typedef enum { - GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL = -1, - GST_VAAPI_ENCODER_VP9_PROP_SHARPNESS_LEVEL = -2, - GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX = -3, - GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE = -4, - GST_VAAPI_ENCODER_VP9_PROP_CPB_LENGTH = -5 -} GstVaapiEncoderVP9Prop; - GType gst_vaapi_encoder_vp9_get_type (void) G_GNUC_CONST; From 64f8f62021efbc5a3ff03c290e45669156318699 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 18:39:27 +0800 Subject: [PATCH 3370/3781] libs: encoder: delete old set_property and property enum in h264 fei --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 142 ------------------ gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h | 50 ------ 2 files changed, 192 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index c1ef4d3b4f..bcdc7a53f6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -3488,147 +3488,6 @@ get_view_ids (GstVaapiEncoderH264Fei * const encoder, GValue * value) g_value_unset (&id); } -static GstVaapiEncoderStatus -_gst_vaapi_encoder_h264_fei_set_property (GstVaapiEncoder * base_encoder, - gint prop_id, const GValue * value) -{ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); - GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); - GstVaapiEncoderStatus status; - - switch (prop_id) { - case GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_BFRAMES: - encoder->num_bframes = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_FEI_PROP_INIT_QP: - encoder->init_qp = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_FEI_PROP_MIN_QP: - encoder->min_qp = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_SLICES: - encoder->num_slices = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_FEI_PROP_CABAC: - encoder->use_cabac = g_value_get_boolean (value); - break; - case GST_VAAPI_ENCODER_H264_FEI_PROP_DCT8X8: - encoder->use_dct8x8 = g_value_get_boolean (value); - break; - case GST_VAAPI_ENCODER_H264_FEI_PROP_CPB_LENGTH: - encoder->cpb_length = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS: - encoder->num_views = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS: - set_view_ids (encoder, value); - break; - case GST_VAAPI_ENCODER_H264_PROP_FEI_DISABLE: - encoder->is_fei_disabled = g_value_get_boolean (value); - if (!encoder->is_fei_disabled) - encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI; - break; - case GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L0: - encoder->num_mv_predictors_l0 = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L1: - encoder->num_mv_predictors_l1 = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_SEARCH_WINDOW: - encoder->search_window = g_value_get_enum (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_LEN_SP: - encoder->len_sp = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_SEARCH_PATH: - encoder->search_path = g_value_get_enum (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_REF_WIDTH: - encoder->ref_width = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_REF_HEIGHT: - encoder->ref_height = g_value_get_uint (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_SUBMB_MASK: - encoder->submb_part_mask = g_value_get_flags (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_SUBPEL_MODE: - encoder->subpel_mode = g_value_get_enum (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_INTRA_PART_MASK: - encoder->intra_part_mask = g_value_get_flags (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_INTRA_SAD: - encoder->intra_sad = g_value_get_enum (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_INTER_SAD: - encoder->inter_sad = g_value_get_enum (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_ADAPT_SEARCH: - encoder->adaptive_search = g_value_get_boolean (value) ? 1 : 0; - break; - case GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L0: - encoder->multi_predL0 = g_value_get_boolean (value) ? 1 : 0; - break; - case GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L1: - encoder->multi_predL1 = g_value_get_boolean (value) ? 1 : 0; - break; - case GST_VAAPI_ENCODER_H264_PROP_ENABLE_STATS_OUT: - encoder->is_stats_out_enabled = g_value_get_boolean (value); - break; - case GST_VAAPI_ENCODER_H264_PROP_FEI_MODE: - encoder->fei_mode = g_value_get_flags (value); - if (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC) { - g_warning ("============= ENC only mode selected ============ \n" - "We internally run the PAK stage because, the ENC operation requires the reconstructed output of PAK mode. Right now we have no infrastructure to provide reconstructed surfaces to ENC with out running the PAK \n"); - /*Fixme: Support ENC only mode with out running PAK */ - encoder->fei_mode = GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK; - } else if (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK) { - g_warning ("============ PAK only mode selected ============ \n" - "This mode can work as expected, only if there is a custom user specific upstream element which provides mb_code and mv_vectors. If you are running the pipeline only for verification, We recommand to use the fei-mod ENC+PAK which will run the ENC operation and generate what ever input needed for PAK \n"); - } - - break; - case GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_QP: - encoder->max_qp = g_value_get_uint (value); - break; - - default: - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - } - - if ((prop_id != GST_VAAPI_ENCODER_H264_PROP_FEI_MODE) && - (prop_id != GST_VAAPI_ENCODER_H264_PROP_FEI_DISABLE) && - (prop_id != GST_VAAPI_ENCODER_H264_PROP_ENABLE_STATS_OUT)) { - - if (enc_base_encoder) { - status = - gst_vaapi_feienc_h264_set_property (enc_base_encoder, prop_id, value); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - GST_ERROR ("failed to set enc property"); - return status; - } - } - - if ((prop_id == GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_BFRAMES) || - (prop_id == GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS) || - (prop_id == GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS)) { - if (encoder->feipak) { - status = - gst_vaapi_feipak_h264_set_property (encoder->feipak, prop_id, - value); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - GST_ERROR ("failed to set pak property"); - return status; - } - } - } - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - /** * @ENCODER_H264_FEI_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). * @ENCODER_H264_FEI_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). @@ -4073,7 +3932,6 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) encoder_class->reordering = gst_vaapi_encoder_h264_fei_reordering; encoder_class->encode = gst_vaapi_encoder_h264_fei_encode; encoder_class->flush = gst_vaapi_encoder_h264_fei_flush; - encoder_class->set_property = _gst_vaapi_encoder_h264_fei_set_property; encoder_class->get_codec_data = gst_vaapi_encoder_h264_fei_get_codec_data; encoder_class->ensure_secondary_context = gst_vaapi_encoder_h264_fei_ensure_secondary_context; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h index 38b7a64d2d..b1c08d9fd9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h @@ -40,56 +40,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiEncoderH264Fei GstVaapiEncoderH264Fei; typedef struct _GstVaapiEncoderH264FeiClass GstVaapiEncoderH264FeiClass; -/** - * GstVaapiEncoderH264FeiProp: - * @GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_BFRAMES: Number of B-frames between I - * and P (uint). - * @GST_VAAPI_ENCODER_H264_FEI_PROP_INIT_QP: Initial quantizer value (uint). - * @GST_VAAPI_ENCODER_H264_FEI_PROP_MIN_QP: Minimal quantizer value (uint). - * @GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_SLICES: Number of slices per frame (uint). - * @GST_VAAPI_ENCODER_H264_FEI_PROP_CABAC: Enable CABAC entropy coding mode (bool). - * @GST_VAAPI_ENCODER_H264_FEI_PROP_DCT8X8: Enable adaptive use of 8x8 - * transforms in I-frames (bool). - * @GST_VAAPI_ENCODER_H264_FEI_PROP_CPB_LENGTH: Length of the CPB buffer - * in milliseconds (uint). - * @GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS: Number of views per frame. - * @GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS: View IDs - * @GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_QP: Maximal quantizer value (uint). - * - * The set of H.264 encoder specific configurable properties. - */ -typedef enum { - GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_BFRAMES = -1, - GST_VAAPI_ENCODER_H264_FEI_PROP_INIT_QP = -2, - GST_VAAPI_ENCODER_H264_FEI_PROP_MIN_QP = -3, - GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_SLICES = -4, - GST_VAAPI_ENCODER_H264_FEI_PROP_CABAC = -5, - GST_VAAPI_ENCODER_H264_FEI_PROP_DCT8X8 = -6, - GST_VAAPI_ENCODER_H264_FEI_PROP_CPB_LENGTH = -7, - GST_VAAPI_ENCODER_H264_FEI_PROP_NUM_VIEWS = -8, - GST_VAAPI_ENCODER_H264_FEI_PROP_VIEW_IDS = -9, - GST_VAAPI_ENCODER_H264_PROP_FEI_DISABLE= -11, - GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L0 = -12, - GST_VAAPI_ENCODER_H264_PROP_NUM_MV_PREDICT_L1 = -13, - GST_VAAPI_ENCODER_H264_PROP_SEARCH_WINDOW = -14, - GST_VAAPI_ENCODER_H264_PROP_LEN_SP = -15, - GST_VAAPI_ENCODER_H264_PROP_SEARCH_PATH = -16, - GST_VAAPI_ENCODER_H264_PROP_REF_WIDTH = -17, - GST_VAAPI_ENCODER_H264_PROP_REF_HEIGHT = -18, - GST_VAAPI_ENCODER_H264_PROP_SUBMB_MASK = -19, - GST_VAAPI_ENCODER_H264_PROP_SUBPEL_MODE = -20, - GST_VAAPI_ENCODER_H264_PROP_INTRA_PART_MASK = -21, - GST_VAAPI_ENCODER_H264_PROP_INTRA_SAD = -22, - GST_VAAPI_ENCODER_H264_PROP_INTER_SAD = -23, - GST_VAAPI_ENCODER_H264_PROP_ADAPT_SEARCH = -24, - GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L0 = -25, - GST_VAAPI_ENCODER_H264_PROP_MULTI_PRED_L1 = -26, - GST_VAAPI_ENCODER_H264_PROP_ENABLE_STATS_OUT = -27, - GST_VAAPI_ENCODER_H264_PROP_FEI_MODE = -28, - GST_VAAPI_ENCODER_H264_FEI_PROP_MAX_QP = -29, - -} GstVaapiEncoderH264FeiProp; - GType gst_vaapi_encoder_h264_fei_get_type (void) G_GNUC_CONST; From 6a590052fcc339a9da1811e63768827ecb48035d Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 18:43:30 +0800 Subject: [PATCH 3371/3781] libs: encoder: delete old set_property and property enum feienc264 --- gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 93 +----------------------- gst-libs/gst/vaapi/gstvaapifeienc_h264.h | 52 ------------- 2 files changed, 2 insertions(+), 143 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index ae6a15a8d0..88c10e25e4 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -1763,94 +1763,6 @@ get_view_ids (GstVaapiFeiEncH264 * const encoder, GValue * value) g_value_unset (&id); } -GstVaapiEncoderStatus -gst_vaapi_feienc_h264_set_property (GstVaapiEncoder * base_encoder, - gint prop_id, const GValue * value) -{ - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); - - switch (prop_id) { - case GST_VAAPI_FEI_H264_ENC_PROP_MAX_BFRAMES: - feienc->num_bframes = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_INIT_QP: - feienc->init_qp = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_MIN_QP: - feienc->min_qp = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_NUM_SLICES: - feienc->num_slices = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_CABAC: - feienc->use_cabac = g_value_get_boolean (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_DCT8X8: - feienc->use_dct8x8 = g_value_get_boolean (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_CPB_LENGTH: - feienc->cpb_length = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_NUM_VIEWS: - feienc->num_views = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_VIEW_IDS: - set_view_ids (feienc, value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_NUM_REF: - feienc->num_ref_frames = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0: - feienc->num_mv_predictors_l0 = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1: - feienc->num_mv_predictors_l1 = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_WINDOW: - feienc->search_window = g_value_get_enum (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_LEN_SP: - feienc->len_sp = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_PATH: - feienc->search_path = g_value_get_enum (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_REF_WIDTH: - feienc->ref_width = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_REF_HEIGHT: - feienc->ref_height = g_value_get_uint (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_SUBMB_MASK: - feienc->submb_part_mask = g_value_get_flags (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_SUBPEL_MODE: - feienc->subpel_mode = g_value_get_enum (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_INTRA_PART_MASK: - feienc->intra_part_mask = g_value_get_flags (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_INTRA_SAD: - feienc->intra_sad = g_value_get_enum (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_INTER_SAD: - feienc->inter_sad = g_value_get_enum (value); - break; - case GST_VAAPI_FEI_H264_ENC_PROP_ADAPT_SEARCH: - feienc->adaptive_search = g_value_get_boolean (value) ? 1 : 0; - break; - case GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L0: - feienc->multi_predL0 = g_value_get_boolean (value) ? 1 : 0; - break; - case GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L1: - feienc->multi_predL1 = g_value_get_boolean (value) ? 1 : 0; - break; - default: - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - /** * @FEI_H264_ENC_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). * @FEI_H264_ENC_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). @@ -1906,7 +1818,7 @@ enum static GParamSpec *properties[FEI_H264_ENC_N_PROPERTIES]; static void -_gst_vaapi_feienc_h264_set_property (GObject * object, guint prop_id, +gst_vaapi_feienc_h264_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); @@ -2122,10 +2034,9 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) encoder_class->reordering = gst_vaapi_feienc_h264_reordering; encoder_class->encode = gst_vaapi_feienc_h264_fake_encode; encoder_class->flush = gst_vaapi_feienc_h264_flush; - encoder_class->set_property = gst_vaapi_feienc_h264_set_property; encoder_class->get_codec_data = gst_vaapi_feienc_h264_get_codec_data; - object_class->set_property = _gst_vaapi_feienc_h264_set_property; + object_class->set_property = gst_vaapi_feienc_h264_set_property; object_class->get_property = gst_vaapi_feienc_h264_get_property; object_class->finalize = gst_vaapi_feienc_h264_finalize; diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.h b/gst-libs/gst/vaapi/gstvaapifeienc_h264.h index ffeab5d9a6..046056b70b 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.h +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.h @@ -40,54 +40,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiFeiEncH264 GstVaapiFeiEncH264; typedef struct _GstVaapiFeiEncH264Class GstVaapiFeiEncH264Class; -/** - * GstVaapiFeiEncH264Prop: - * @GST_VAAPI_FEI_H264_ENC_PROP_MAX_BFRAMES: Number of B-frames between I - * and P (uint). - * @GST_VAAPI_FEI_H264_ENC_PROP_INIT_QP: Initial quantizer value (uint). - * @GST_VAAPI_FEI_H264_ENC_PROP_MIN_QP: Minimal quantizer value (uint). - * @GST_VAAPI_FEI_H264_ENC_PROP_NUM_SLICES: Number of slices per frame (uint). - * @GST_VAAPI_FEI_H264_ENC_PROP_CABAC: Enable CABAC entropy coding mode (bool). - * @GST_VAAPI_FEI_H264_ENC_PROP_DCT8X8: Enable adaptive use of 8x8 - * transforms in I-frames (bool). - * @GST_VAAPI_FEI_H264_ENC_PROP_CPB_LENGTH: Length of the CPB buffer - * in milliseconds (uint). - * @GST_VAAPI_FEI_H264_ENC_PROP_NUM_VIEWS: Number of views per frame. - * @GST_VAAPI_FEI_H264_ENC_PROP_VIEW_IDS: View IDs - * - * The set of FEI Enc specific configurable properties. - */ -typedef enum -{ - GST_VAAPI_FEI_H264_ENC_PROP_MAX_BFRAMES = -1, - GST_VAAPI_FEI_H264_ENC_PROP_INIT_QP = -2, - GST_VAAPI_FEI_H264_ENC_PROP_MIN_QP = -3, - GST_VAAPI_FEI_H264_ENC_PROP_NUM_SLICES = -4, - GST_VAAPI_FEI_H264_ENC_PROP_CABAC = -5, - GST_VAAPI_FEI_H264_ENC_PROP_DCT8X8 = -6, - GST_VAAPI_FEI_H264_ENC_PROP_CPB_LENGTH = -7, - GST_VAAPI_FEI_H264_ENC_PROP_NUM_VIEWS = -8, - GST_VAAPI_FEI_H264_ENC_PROP_VIEW_IDS = -9, - GST_VAAPI_FEI_H264_ENC_PROP_NUM_REF = -10, - GST_VAAPI_FEI_H264_ENC_PROP_FEI_ENABLE = -11, - GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0 = -12, - GST_VAAPI_FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1 = -13, - GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_WINDOW = -14, - GST_VAAPI_FEI_H264_ENC_PROP_LEN_SP = -15, - GST_VAAPI_FEI_H264_ENC_PROP_SEARCH_PATH = -16, - GST_VAAPI_FEI_H264_ENC_PROP_REF_WIDTH = -17, - GST_VAAPI_FEI_H264_ENC_PROP_REF_HEIGHT = -18, - GST_VAAPI_FEI_H264_ENC_PROP_SUBMB_MASK = -19, - GST_VAAPI_FEI_H264_ENC_PROP_SUBPEL_MODE = -20, - GST_VAAPI_FEI_H264_ENC_PROP_INTRA_PART_MASK = -21, - GST_VAAPI_FEI_H264_ENC_PROP_INTRA_SAD = -22, - GST_VAAPI_FEI_H264_ENC_PROP_INTER_SAD = -23, - GST_VAAPI_FEI_H264_ENC_PROP_ADAPT_SEARCH = -24, - GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L0 = -25, - GST_VAAPI_FEI_H264_ENC_PROP_MULTI_PRED_L1 = -26, - GST_VAAPI_FEI_H264_ENC_PROP_ENABLE_STATS_OUT = -27, -} GstVaapiFeiEncH264Prop; - GType gst_vaapi_feienc_h264_get_type (void) G_GNUC_CONST; @@ -116,10 +68,6 @@ gst_vaapi_feienc_h264_reordering (GstVaapiEncoder * base_encoder, GstVaapiEncoderStatus gst_vaapi_feienc_h264_reconfigure (GstVaapiEncoder * base_encoder); -GstVaapiEncoderStatus -gst_vaapi_feienc_h264_set_property (GstVaapiEncoder * base_encoder, - gint prop_id, const GValue * value); - gboolean gst_vaapi_feienc_h264_get_profile_and_idc (GstVaapiFeiEncH264 * feienc, GstVaapiProfile * out_profile_ptr, guint8 * out_profile_idc_ptr); From f52d545fd04e969f7b1cee6e439fae9b9495fcfd Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 29 Aug 2019 18:44:36 +0800 Subject: [PATCH 3372/3781] libs: encoder: clean two virtual func in encoder class set_property and get_default_properties functions are no longer needed for encoder class. --- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 5cda1cdea9..560c7af53d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -321,12 +321,6 @@ struct _GstVaapiEncoderClass const GstVaapiEncoderClassData *class_data; GstVaapiEncoderStatus (*reconfigure) (GstVaapiEncoder * encoder); - - GPtrArray * (*get_default_properties) (void); - GstVaapiEncoderStatus (*set_property) (GstVaapiEncoder * encoder, - gint prop_id, - const GValue * value); - GstVaapiEncoderStatus (*reordering) (GstVaapiEncoder * encoder, GstVideoCodecFrame * in, GstVaapiEncPicture ** out); From 6700f642fc3ee7b20bc69c18f160bed60e881691 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 20 Aug 2019 14:22:57 -0700 Subject: [PATCH 3373/3781] vaapipostproc: advertise crop meta is handled Advertise to upstream that vaapipostproc can handle crop meta. When used in conjunction with videocrop plugin, the videocrop plugin will only do in-place transform on the crop meta when vaapipostproc advertises the ability to handle it. This allows vaapipostproc to apply the crop meta on the output buffer using vaapi acceleration. Without this advertisement, the videocrop plugin will crop the output buffer directly via software methods, which is not what we desire. vaapipostproc will not apply the crop meta if downstream advertises crop meta handling; vaapipostproc will just forward the crop meta to downstream. If crop meta is not advertised by downstream, then vaapipostproc will apply the crop meta. Examples: 1. vaapipostproc will forward crop meta to vaapisink gst-launch-1.0 videotestsrc \ ! videocrop left=10 \ ! vaapipostproc \ ! vaapisink 2. vaapipostproc will do the cropping gst-launch-1.0 videotestsrc \ ! videocrop left=10 \ ! vaapipostproc \ ! identity drop-allocation=1 \ ! vaapisink --- gst/vaapi/gstvaapipostproc.c | 88 ++++++++++++++++++++++++++++-------- gst/vaapi/gstvaapipostproc.h | 1 + 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 6e53dc2d7c..a90738ecca 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -672,6 +672,12 @@ replace_to_dumb_buffer_if_required (GstVaapiPostproc * postproc, return TRUE; } +static gboolean +use_vpp_crop (GstVaapiPostproc * postproc) +{ + return !postproc->forward_crop; +} + static GstFlowReturn gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer * outbuf) @@ -698,7 +704,9 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, inbuf_surface = gst_vaapi_video_meta_get_surface (inbuf_meta); crop_meta = gst_buffer_get_video_crop_meta (inbuf); - if (crop_meta) { + if (crop_meta && use_vpp_crop (postproc)) { + GST_DEBUG_OBJECT (postproc, "cropping x=%d,y=%d,w=%d,h=%d", + crop_meta->x, crop_meta->y, crop_meta->width, crop_meta->height); crop_rect = &tmp_rect; crop_rect->x = crop_meta->x; crop_rect->y = crop_meta->y; @@ -860,6 +868,7 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, discont = FALSE; } } + copy_metadata (postproc, outbuf, inbuf); if (deint && deint_refs) @@ -1332,8 +1341,9 @@ gst_vaapipostproc_transform_meta (GstBaseTransform * trans, GstBuffer * outbuf, { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - /* dont' GstVideoCropMeta if use_vpp */ - if (meta->info->api == GST_VIDEO_CROP_META_API_TYPE && postproc->use_vpp) + /* don't copy GstVideoCropMeta if we are using vpp crop */ + if (meta->info->api == GST_VIDEO_CROP_META_API_TYPE + && use_vpp_crop (postproc)) return FALSE; /* don't copy GstParentBufferMeta if use_vpp */ @@ -1401,17 +1411,56 @@ done: return ret; } +static gboolean +ensure_buffer_pool (GstVaapiPostproc * postproc, GstVideoInfo * vi) +{ + GstVaapiVideoPool *pool; + + if (!vi) + return FALSE; + + gst_video_info_change_format (vi, postproc->format, + GST_VIDEO_INFO_WIDTH (vi), GST_VIDEO_INFO_HEIGHT (vi)); + + if (postproc->filter_pool + && !video_info_changed (&postproc->filter_pool_info, vi)) + return TRUE; + postproc->filter_pool_info = *vi; + + pool = + gst_vaapi_surface_pool_new_full (GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc), + &postproc->filter_pool_info, 0); + if (!pool) + return FALSE; + + gst_vaapi_video_pool_replace (&postproc->filter_pool, pool); + gst_vaapi_video_pool_unref (pool); + return TRUE; +} + static GstFlowReturn gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer ** outbuf_ptr) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + const GstVideoCropMeta *crop_meta; + GstVideoInfo info; if (gst_base_transform_is_passthrough (trans)) { *outbuf_ptr = inbuf; return GST_FLOW_OK; } + /* If we are not using vpp crop (i.e. forwarding crop meta to downstream) + * then, ensure our output buffer pool is sized for uncropped output */ + crop_meta = gst_buffer_get_video_crop_meta (inbuf); + if (crop_meta && !use_vpp_crop (postproc)) { + info = postproc->srcpad_info; + info.width += crop_meta->x; + info.height += crop_meta->y; + ensure_buffer_pool (postproc, &info); + } + if (GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME (trans)) { *outbuf_ptr = create_output_dump_buffer (postproc); } else { @@ -1428,27 +1477,11 @@ static gboolean ensure_srcpad_buffer_pool (GstVaapiPostproc * postproc, GstCaps * caps) { GstVideoInfo vi; - GstVaapiVideoPool *pool; if (!gst_video_info_from_caps (&vi, caps)) return FALSE; - gst_video_info_change_format (&vi, postproc->format, - GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); - if (postproc->filter_pool - && !video_info_changed (&postproc->filter_pool_info, &vi)) - return TRUE; - postproc->filter_pool_info = vi; - - pool = - gst_vaapi_surface_pool_new_full (GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc), - &postproc->filter_pool_info, 0); - if (!pool) - return FALSE; - - gst_vaapi_video_pool_replace (&postproc->filter_pool, pool); - gst_vaapi_video_pool_unref (pool); - return TRUE; + return ensure_buffer_pool (postproc, &vi); } static gboolean @@ -1552,6 +1585,10 @@ gst_vaapipostproc_propose_allocation (GstBaseTransform * trans, gint allocation_width, allocation_height; gint negotiated_width, negotiated_height; + /* advertise to upstream that we can handle crop meta */ + if (decide_query) + gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL); + negotiated_width = GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info); negotiated_height = GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info); @@ -1588,6 +1625,16 @@ bail: static gboolean gst_vaapipostproc_decide_allocation (GstBaseTransform * trans, GstQuery * query) { + GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); + + g_mutex_lock (&postproc->postproc_lock); + /* Let downstream handle the crop meta if they support it */ + postproc->forward_crop = (gst_query_find_allocation_meta (query, + GST_VIDEO_CROP_META_API_TYPE, NULL) && + gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)); + GST_DEBUG_OBJECT (postproc, "use_vpp_crop=%d", use_vpp_crop (postproc)); + g_mutex_unlock (&postproc->postproc_lock); + return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (trans), query); } @@ -2172,6 +2219,7 @@ gst_vaapipostproc_init (GstVaapiPostproc * postproc) postproc->field_duration = GST_CLOCK_TIME_NONE; postproc->keep_aspect = TRUE; postproc->get_va_surfaces = TRUE; + postproc->forward_crop = FALSE; /* AUTO is not valid for tag_video_direction, this is just to * ensure we setup the method as sink event tag */ diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 0d98923ffe..6acc59948b 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -175,6 +175,7 @@ struct _GstVaapiPostproc gfloat contrast; gboolean skintone_enhance; + gboolean forward_crop; guint get_va_surfaces:1; guint has_vpp:1; From 9fd020a1177160f5368e62e58daf8194a936eb3a Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Wed, 4 Sep 2019 10:52:51 -0700 Subject: [PATCH 3374/3781] vaapipostproc: handle size and direction together in src events Mapping a pointer event needs to consider both size and video-direction operations together, not just one or the other. This fixes an issue where x,y were not being mapped correctly for 90r, 90l, ur-ll and ul-lr video-direction. In these directions, the WxH are swapped and GST_VAAPI_POSTPROC_FLAG_SIZE is set. Thus, the first condition in the pointer event handling was entered and x,y scale factor were incorrectly computed due to srcpad WxH swap. This also fixes all cases where both video-direction and scaling are enabled at the same time. Test that all pointer events map appropriately: for i in `seq 0 7` do GST_DEBUG=vaapipostproc:5 gst-launch-1.0 -vf videotestsrc \ ! vaapipostproc video-direction=${i} width=300 \ ! vaapisink GST_DEBUG=vaapipostproc:5 gst-launch-1.0 -vf videotestsrc \ ! vaapipostproc video-direction=${i} width=300 height=200 \ ! vaapisink GST_DEBUG=vaapipostproc:5 gst-launch-1.0 -vf videotestsrc \ ! vaapipostproc video-direction=${i} height=200 \ ! vaapisink GST_DEBUG=vaapipostproc:5 gst-launch-1.0 -vf videotestsrc \ ! vaapipostproc video-direction=${i} \ ! vaapisink done --- gst/vaapi/gstvaapipostproc.c | 108 +++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 48 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index a90738ecca..b115de01e7 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1639,11 +1639,33 @@ gst_vaapipostproc_decide_allocation (GstBaseTransform * trans, GstQuery * query) query); } +static void +get_scale_factor (GstVaapiPostproc * const postproc, gdouble * w_factor, + gdouble * h_factor) +{ + gdouble wd = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info); + gdouble hd = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info); + + switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { + case GST_VIDEO_ORIENTATION_90R: + case GST_VIDEO_ORIENTATION_90L: + case GST_VIDEO_ORIENTATION_UR_LL: + case GST_VIDEO_ORIENTATION_UL_LR: + G_PRIMITIVE_SWAP (gdouble, wd, hd); + break; + default: + break; + } + + *w_factor = GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info) / wd; + *h_factor = GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info) / hd; +} + static gboolean gst_vaapipostproc_src_event (GstBaseTransform * trans, GstEvent * event) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - gdouble new_x = 0, new_y = 0, x = 0, y = 0; + gdouble new_x = 0, new_y = 0, x = 0, y = 0, w_factor = 1, h_factor = 1; GstStructure *structure; gboolean ret; @@ -1659,55 +1681,45 @@ gst_vaapipostproc_src_event (GstBaseTransform * trans, GstEvent * event) gst_structure_get_double (structure, "pointer_y", &y)) { GST_DEBUG_OBJECT (postproc, "converting %fx%f", x, y); - if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SIZE) { - if ((GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - != GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info)) - && (GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - != GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info))) { - new_x = - x * GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info) / - GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info); - new_y = - y * GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info) / - GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info); - } - } else if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION) { - switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { - case GST_VIDEO_ORIENTATION_90R: - new_x = y; - new_y = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; - break; - case GST_VIDEO_ORIENTATION_90L: - new_x = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; - new_y = x; - break; - case GST_VIDEO_ORIENTATION_UR_LL: - new_x = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; - new_y = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; - break; - case GST_VIDEO_ORIENTATION_UL_LR: - new_x = y; - new_y = x; - break; - case GST_VIDEO_ORIENTATION_180: - new_x = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; - new_y = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; - break; - case GST_VIDEO_ORIENTATION_HORIZ: - new_x = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; - new_y = y; - break; - case GST_VIDEO_ORIENTATION_VERT: - new_x = x; - new_y = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; - break; - default: - new_x = x; - new_y = y; - break; - } + switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { + case GST_VIDEO_ORIENTATION_90R: + new_x = y; + new_y = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; + break; + case GST_VIDEO_ORIENTATION_90L: + new_x = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; + new_y = x; + break; + case GST_VIDEO_ORIENTATION_UR_LL: + new_x = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; + new_y = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; + break; + case GST_VIDEO_ORIENTATION_UL_LR: + new_x = y; + new_y = x; + break; + case GST_VIDEO_ORIENTATION_180: + new_x = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; + new_y = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; + break; + case GST_VIDEO_ORIENTATION_HORIZ: + new_x = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; + new_y = y; + break; + case GST_VIDEO_ORIENTATION_VERT: + new_x = x; + new_y = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; + break; + default: + new_x = x; + new_y = y; + break; } + get_scale_factor (postproc, &w_factor, &h_factor); + new_x *= w_factor; + new_y *= h_factor; + GST_DEBUG_OBJECT (postproc, "to %fx%f", new_x, new_y); gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, new_x, "pointer_y", G_TYPE_DOUBLE, new_y, NULL); From c6ee20fab319a92a71a9fecf10703f1d211e3fba Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 30 Aug 2019 14:14:30 -0700 Subject: [PATCH 3375/3781] vaapipostproc: fix output buffer WxH for crop meta forwarding Adding crop meta x,y to w,h only compensates for left,top cropping. But we also need to compensate for right,bottom cropping. The video meta contains the appropriate w,h (uncropped) values, so use it instead. Test: gst-launch-1.0 -vf videotestsrc num-buffers=500 \ ! videocrop top=50 bottom=30 left=40 right=20 \ ! vaapipostproc ! vaapisink & \ gst-launch-1.0 -vf videotestsrc num-buffers=500 \ ! videocrop top=50 bottom=30 left=40 right=20 \ ! vaapipostproc ! identity drop-allocation=1 \ ! vaapisink --- gst/vaapi/gstvaapipostproc.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index b115de01e7..724cf978d4 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1443,7 +1443,7 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer ** outbuf_ptr) { GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans); - const GstVideoCropMeta *crop_meta; + const GstVideoMeta *video_meta; GstVideoInfo info; if (gst_base_transform_is_passthrough (trans)) { @@ -1453,11 +1453,17 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, /* If we are not using vpp crop (i.e. forwarding crop meta to downstream) * then, ensure our output buffer pool is sized for uncropped output */ - crop_meta = gst_buffer_get_video_crop_meta (inbuf); - if (crop_meta && !use_vpp_crop (postproc)) { + if (gst_buffer_get_video_crop_meta (inbuf) && !use_vpp_crop (postproc)) { + /* The video meta is required since the caps width/height are smaller, + * which would not result in a usable GstVideoInfo for mapping the + * buffer. */ + video_meta = gst_buffer_get_video_meta (inbuf); + if (!video_meta) + return GST_FLOW_ERROR; + info = postproc->srcpad_info; - info.width += crop_meta->x; - info.height += crop_meta->y; + info.width = video_meta->width; + info.height = video_meta->height; ensure_buffer_pool (postproc, &info); } From 55654f2915081e474a561f0a8700414dc2e188c5 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 30 Aug 2019 17:31:45 -0700 Subject: [PATCH 3376/3781] vaapipostproc: rotate outbuf and crop meta if forwarding When forwarding crop meta to downstream, the output buffer and crop meta need to be rotated, too. Test: for i in 90r 180 90l vert horiz ul-lr ur-ll do gst-launch-1.0 -vf videotestsrc num-buffers=500 \ ! videocrop top=100 bottom=30 left=40 right=20 \ ! vaapipostproc video-direction=$i \ ! vaapisink & \ gst-launch-1.0 -vf videotestsrc num-buffers=500 \ ! videocrop top=100 bottom=30 left=40 right=20 \ ! vaapipostproc video-direction=$i \ ! identity drop-allocation=true \ ! vaapisink done --- gst/vaapi/gstvaapipostproc.c | 69 +++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 724cf978d4..73af3b9f56 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -678,6 +678,56 @@ use_vpp_crop (GstVaapiPostproc * postproc) return !postproc->forward_crop; } +static void +rotate_crop_meta (GstVaapiPostproc * const postproc, const GstVideoMeta * vmeta, + GstVideoCropMeta * crop) +{ + guint tmp; + + /* The video meta is required since the caps width/height are smaller, + * which would not result in a usable GstVideoInfo for mapping the + * buffer. */ + if (!vmeta || !crop) + return; + + switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { + case GST_VIDEO_ORIENTATION_HORIZ: + crop->x = vmeta->width - crop->width - crop->x; + break; + case GST_VIDEO_ORIENTATION_VERT: + crop->y = vmeta->height - crop->height - crop->y; + break; + case GST_VIDEO_ORIENTATION_90R: + tmp = crop->x; + crop->x = vmeta->height - crop->height - crop->y; + crop->y = tmp; + G_PRIMITIVE_SWAP (guint, crop->width, crop->height); + break; + case GST_VIDEO_ORIENTATION_180: + crop->x = vmeta->width - crop->width - crop->x; + crop->y = vmeta->height - crop->height - crop->y; + break; + case GST_VIDEO_ORIENTATION_90L: + tmp = crop->x; + crop->x = crop->y; + crop->y = vmeta->width - crop->width - tmp; + G_PRIMITIVE_SWAP (guint, crop->width, crop->height); + break; + case GST_VIDEO_ORIENTATION_UR_LL: + tmp = crop->x; + crop->x = vmeta->height - crop->height - crop->y; + crop->y = vmeta->width - crop->width - tmp; + G_PRIMITIVE_SWAP (guint, crop->width, crop->height); + break; + case GST_VIDEO_ORIENTATION_UL_LR: + G_PRIMITIVE_SWAP (guint, crop->x, crop->y); + G_PRIMITIVE_SWAP (guint, crop->width, crop->height); + break; + default: + break; + } +} + static GstFlowReturn gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer * outbuf) @@ -713,6 +763,7 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, crop_rect->width = crop_meta->width; crop_rect->height = crop_meta->height; } + if (!crop_rect) crop_rect = (GstVaapiRectangle *) gst_vaapi_video_meta_get_render_rect (inbuf_meta); @@ -871,6 +922,9 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, copy_metadata (postproc, outbuf, inbuf); + rotate_crop_meta (postproc, gst_buffer_get_video_meta (inbuf), + gst_buffer_get_video_crop_meta (outbuf)); + if (deint && deint_refs) ds_add_buffer (ds, inbuf); postproc->use_vpp = TRUE; @@ -1452,7 +1506,8 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, } /* If we are not using vpp crop (i.e. forwarding crop meta to downstream) - * then, ensure our output buffer pool is sized for uncropped output */ + * then, ensure our output buffer pool is sized and rotated for uncropped + * output */ if (gst_buffer_get_video_crop_meta (inbuf) && !use_vpp_crop (postproc)) { /* The video meta is required since the caps width/height are smaller, * which would not result in a usable GstVideoInfo for mapping the @@ -1464,6 +1519,18 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, info = postproc->srcpad_info; info.width = video_meta->width; info.height = video_meta->height; + + /* compensate for rotation if needed */ + switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { + case GST_VIDEO_ORIENTATION_90R: + case GST_VIDEO_ORIENTATION_UL_LR: + case GST_VIDEO_ORIENTATION_90L: + case GST_VIDEO_ORIENTATION_UR_LL: + G_PRIMITIVE_SWAP (guint, info.width, info.height); + default: + break; + } + ensure_buffer_pool (postproc, &info); } From 2f0f5e1ef9e8d1fcf0723f752664591b7263866b Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 8 Jul 2019 14:18:00 -0700 Subject: [PATCH 3377/3781] vaapipostproc: allow cropping via properties Add crop-left, crop-right, crop-top and crop-bottom properties to vaapipostproc. --- gst/vaapi/gstvaapipostproc.c | 128 ++++++++++++++++++++++++++++--- gst/vaapi/gstvaapipostproc.h | 7 ++ gst/vaapi/gstvaapipostprocutil.c | 4 + 3 files changed, 128 insertions(+), 11 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 73af3b9f56..f34e583d5f 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -123,6 +123,10 @@ enum PROP_CONTRAST, PROP_SCALE_METHOD, PROP_VIDEO_DIRECTION, + PROP_CROP_LEFT, + PROP_CROP_RIGHT, + PROP_CROP_TOP, + PROP_CROP_BOTTOM, PROP_SKIN_TONE_ENHANCEMENT, }; @@ -619,6 +623,11 @@ update_filter (GstVaapiPostproc * postproc) postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION); } + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_CROP) + if ((postproc->crop_left | postproc->crop_right | postproc->crop_top + | postproc->crop_bottom) == 0) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_CROP); + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SKINTONE) { if (!gst_vaapi_filter_set_skintone (postproc->filter, postproc->skintone_enhance)) @@ -675,7 +684,8 @@ replace_to_dumb_buffer_if_required (GstVaapiPostproc * postproc, static gboolean use_vpp_crop (GstVaapiPostproc * postproc) { - return !postproc->forward_crop; + return !(postproc->forward_crop + && !(postproc->flags & GST_VAAPI_POSTPROC_FLAG_CROP)); } static void @@ -753,15 +763,20 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf, goto error_invalid_buffer; inbuf_surface = gst_vaapi_video_meta_get_surface (inbuf_meta); - crop_meta = gst_buffer_get_video_crop_meta (inbuf); - if (crop_meta && use_vpp_crop (postproc)) { - GST_DEBUG_OBJECT (postproc, "cropping x=%d,y=%d,w=%d,h=%d", - crop_meta->x, crop_meta->y, crop_meta->width, crop_meta->height); + if (use_vpp_crop (postproc)) { crop_rect = &tmp_rect; - crop_rect->x = crop_meta->x; - crop_rect->y = crop_meta->y; - crop_rect->width = crop_meta->width; - crop_rect->height = crop_meta->height; + crop_rect->x = postproc->crop_left; + crop_rect->y = postproc->crop_top; + crop_rect->width = GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info) + - (postproc->crop_left + postproc->crop_right); + crop_rect->height = GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info) + - (postproc->crop_top + postproc->crop_bottom); + + crop_meta = gst_buffer_get_video_crop_meta (inbuf); + if (crop_meta) { + crop_rect->x += crop_meta->x; + crop_rect->y += crop_meta->y; + } } if (!crop_rect) @@ -1730,8 +1745,13 @@ get_scale_factor (GstVaapiPostproc * const postproc, gdouble * w_factor, break; } - *w_factor = GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info) / wd; - *h_factor = GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info) / hd; + *w_factor = GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info) + - (postproc->crop_left + postproc->crop_right); + *w_factor /= wd; + + *h_factor = GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info) + - (postproc->crop_top + postproc->crop_bottom); + *h_factor /= hd; } static gboolean @@ -1754,6 +1774,7 @@ gst_vaapipostproc_src_event (GstBaseTransform * trans, GstEvent * event) gst_structure_get_double (structure, "pointer_y", &y)) { GST_DEBUG_OBJECT (postproc, "converting %fx%f", x, y); + /* video-direction compensation */ switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { case GST_VIDEO_ORIENTATION_90R: new_x = y; @@ -1789,10 +1810,15 @@ gst_vaapipostproc_src_event (GstBaseTransform * trans, GstEvent * event) break; } + /* scale compensation */ get_scale_factor (postproc, &w_factor, &h_factor); new_x *= w_factor; new_y *= h_factor; + /* crop compensation */ + new_x += postproc->crop_left; + new_y += postproc->crop_top; + GST_DEBUG_OBJECT (postproc, "to %fx%f", new_x, new_y); gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, new_x, "pointer_y", G_TYPE_DOUBLE, new_y, NULL); @@ -1947,6 +1973,22 @@ gst_vaapipostproc_set_property (GObject * object, postproc->skintone_enhance = g_value_get_boolean (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SKINTONE; break; + case PROP_CROP_LEFT: + postproc->crop_left = g_value_get_uint (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CROP; + break; + case PROP_CROP_RIGHT: + postproc->crop_right = g_value_get_uint (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CROP; + break; + case PROP_CROP_TOP: + postproc->crop_top = g_value_get_uint (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CROP; + break; + case PROP_CROP_BOTTOM: + postproc->crop_bottom = g_value_get_uint (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CROP; + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2010,6 +2052,18 @@ gst_vaapipostproc_get_property (GObject * object, case PROP_SKIN_TONE_ENHANCEMENT: g_value_set_boolean (value, postproc->skintone_enhance); break; + case PROP_CROP_LEFT: + g_value_set_uint (value, postproc->crop_left); + break; + case PROP_CROP_RIGHT: + g_value_set_uint (value, postproc->crop_right); + break; + case PROP_CROP_TOP: + g_value_set_uint (value, postproc->crop_top); + break; + case PROP_CROP_BOTTOM: + g_value_set_uint (value, postproc->crop_bottom); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2140,6 +2194,58 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) "Forced output height", 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiPostproc:crop-left: + * + * The number of pixels to crop at left. + */ + g_object_class_install_property + (object_class, + PROP_CROP_LEFT, + g_param_spec_uint ("crop-left", + "Crop Left", + "Pixels to crop at left", + 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiPostproc:crop-right: + * + * The number of pixels to crop at right. + */ + g_object_class_install_property + (object_class, + PROP_CROP_RIGHT, + g_param_spec_uint ("crop-right", + "Crop Right", + "Pixels to crop at right", + 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiPostproc:crop-top: + * + * The number of pixels to crop at top. + */ + g_object_class_install_property + (object_class, + PROP_CROP_TOP, + g_param_spec_uint ("crop-top", + "Crop Top", + "Pixels to crop at top", + 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstVaapiPostproc:crop-bottom: + * + * The number of pixels to crop at bottom. + */ + g_object_class_install_property + (object_class, + PROP_CROP_BOTTOM, + g_param_spec_uint ("crop-bottom", + "Crop Bottom", + "Pixels to crop at bottom", + 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiPostproc:force-aspect-ratio: * diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 6acc59948b..8a8df723ce 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -104,6 +104,7 @@ typedef enum GST_VAAPI_POSTPROC_FLAG_SCALE = 1 << GST_VAAPI_FILTER_OP_SCALING, GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION = 1 << GST_VAAPI_FILTER_OP_VIDEO_DIRECTION, + GST_VAAPI_POSTPROC_FLAG_CROP = 1 << GST_VAAPI_FILTER_OP_CROP, GST_VAAPI_POSTPROC_FLAG_SKINTONE = 1 << GST_VAAPI_FILTER_OP_SKINTONE, /* Additional custom flags */ @@ -168,6 +169,12 @@ struct _GstVaapiPostproc GstVideoOrientationMethod video_direction; GstVideoOrientationMethod tag_video_direction; + /* Cropping */ + guint crop_left; + guint crop_right; + guint crop_top; + guint crop_bottom; + /* Color balance filter values */ gfloat hue; gfloat saturation; diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 2c576b137d..1e09e061d8 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -179,6 +179,10 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, from_w = GST_VIDEO_INFO_WIDTH (vinfo); from_h = GST_VIDEO_INFO_HEIGHT (vinfo); + /* adjust for crop settings */ + from_w -= postproc->crop_left + postproc->crop_right; + from_h -= postproc->crop_top + postproc->crop_bottom; + /* compensate for rotation if needed */ switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { case GST_VIDEO_ORIENTATION_90R: From a90daabb84f983d2fa05ff3159f7ad59aa648b55 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Mon, 15 Apr 2019 16:51:26 +0100 Subject: [PATCH 3378/3781] pluginutil: Remove Mesa from drivers white list The Mesa Gallium driver is poorly tested currently, leading to bad user experience for AMD users. The driver can be added back to the white list at runtime using the GST_VAAPI_ALL_DRIVERS environment variable. --- gst/vaapi/gstvaapipluginutil.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 4ef3895351..8cea2432bc 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -954,7 +954,6 @@ gst_vaapi_driver_is_whitelisted (GstVaapiDisplay * display) guint i; static const gchar *whitelist[] = { "Intel i965 driver", - "mesa gallium", NULL }; From 32bf6f1e092cedac39361c8ccff944e74f7d784e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 5 Sep 2019 14:48:22 +0800 Subject: [PATCH 3379/3781] libs: video-format: Refine the video format mapping. Improve the mapping between va format and gst format. The new map will be generated dynamically, based on the query result of image format in VA driver. Also consider the ambiguity of RGB color format in LSB mode. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 11 + gst-libs/gst/vaapi/video-format.c | 349 ++++++++++++++++++++++----- gst-libs/gst/vaapi/video-format.h | 3 + 3 files changed, 301 insertions(+), 62 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index b6d6d61a1d..2bc08c7d40 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -675,6 +675,11 @@ ensure_image_formats (GstVaapiDisplay * display) for (i = 0; i < n; i++) GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc)); + if (!gst_vaapi_video_format_create_map (formats, n)) { + GST_ERROR ("fail to create map between gst video format and vaImageFormat"); + goto cleanup; + } + append_formats (priv->image_formats, formats, NULL, n); g_array_sort (priv->image_formats, compare_yuv_formats); success = TRUE; @@ -906,6 +911,12 @@ gst_vaapi_display_create (GstVaapiDisplay * display, GST_INFO_OBJECT (display, "new display addr=%p", display); g_free (priv->display_name); priv->display_name = g_strdup (info.display_name); + + if (!ensure_image_formats (display)) { + gst_vaapi_display_destroy (display); + return FALSE; + } + return TRUE; } diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index a798cd995d..b1d2d4b148 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -38,59 +38,128 @@ # define VIDEO_VA_ENDIANESS VA_LSB_FIRST #endif -typedef struct +typedef struct _GstVideoFormatMapMap { GstVideoFormat format; GstVaapiChromaType chroma_type; VAImageFormat va_format; } GstVideoFormatMap; -#define DEF_YUV(FORMAT, FOURCC, BPP, SUB) \ +#define VA_BYTE_ORDER_NOT_CARE 0 + +#define DEF_YUV(BYTE_ORDER, FORMAT, FOURCC, BPP, SUB) \ { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ G_PASTE(GST_VAAPI_CHROMA_TYPE_YUV,SUB), \ - { VA_FOURCC FOURCC, VIDEO_VA_ENDIANESS, BPP, }, } + { VA_FOURCC FOURCC, BYTE_ORDER, BPP, }, } -#define DEF_RGB(FORMAT, FOURCC, BPP, DEPTH, R,G,B,A) \ +#define DEF_RGB(BYTE_ORDER, FORMAT, FOURCC, BPP, DEPTH, R,G,B,A) \ { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ G_PASTE(GST_VAAPI_CHROMA_TYPE_RGB,BPP), \ - { VA_FOURCC FOURCC, VIDEO_VA_ENDIANESS, BPP, DEPTH, R,G,B,A }, } + { VA_FOURCC FOURCC, BYTE_ORDER, BPP, DEPTH, R, G, B, A }, } /* Image formats, listed in HW order preference */ /* *INDENT-OFF* */ -static const GstVideoFormatMap gst_vaapi_video_formats[] = { +static const GstVideoFormatMap gst_vaapi_video_default_formats[] = { + /* LSB and MSB video formats definitions are unclear and ambiguous. + * + * For MSB, there is no ambiguity: same order in define, memory and + * CPU. For example, + * + * RGBA is RGBA in memory and RGBA with channel mask R:0xFF0000 + * G:0x00FF0000 B:0x0000FF00 A:0x000000FF in CPU. + * + * For LSB, CPU's perspective and memory's perspective are + * different. For example, + * + * RGBA in LSB, from CPU's perspective, it's RGBA order in memory, + * but when it is stored in memory, because CPU's little + * endianness, it will be re-ordered, with mask R:0x000000FF + * G:0x0000FF00 B:0x00FF0000 A:0xFF000000. In other words, from + * memory's perspective, RGBA LSB is equal as ABGR MSB. + * + * These definitions are mixed used all over the media system and we + * need to correct the mapping form VA video format to GStreamer + * video format in both manners, especially for RGB format. + */ + /* YUV formats */ - DEF_YUV (NV12, ('N', 'V', '1', '2'), 12, 420), - DEF_YUV (YV12, ('Y', 'V', '1', '2'), 12, 420), - DEF_YUV (I420, ('I', '4', '2', '0'), 12, 420), - DEF_YUV (YUY2, ('Y', 'U', 'Y', '2'), 16, 422), - DEF_YUV (UYVY, ('U', 'Y', 'V', 'Y'), 16, 422), - DEF_YUV (Y210, ('Y', '2', '1', '0'), 32, 422_10BPP), - DEF_YUV (Y410, ('Y', '4', '1', '0'), 32, 444_10BPP), - DEF_YUV (AYUV, ('A', 'Y', 'U', 'V'), 32, 444), - DEF_YUV (Y444, ('4', '4', '4', 'P'), 24, 444), - DEF_YUV (GRAY8, ('Y', '8', '0', '0'), 8, 400), - DEF_YUV (P010_10LE, ('P', '0', '1', '0'), 24, 420_10BPP), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, NV12, ('N', 'V', '1', '2'), 12, 420), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, YV12, ('Y', 'V', '1', '2'), 12, 420), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, I420, ('I', '4', '2', '0'), 12, 420), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, YUY2, ('Y', 'U', 'Y', '2'), 16, 422), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, UYVY, ('U', 'Y', 'V', 'Y'), 16, 422), + + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y444, ('4', '4', '4', 'P'), 24, 444), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, GRAY8, ('Y', '8', '0', '0'), 8, 400), + + DEF_YUV (VA_LSB_FIRST, P010_10LE, ('P', '0', '1', '0'), 24, 420_10BPP), + /* AYUV is a clear defined format by doc */ + DEF_YUV (VA_LSB_FIRST, VUYA, ('A', 'Y', 'U', 'V'), 32, 444), + + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y210, ('Y', '2', '1', '0'), 32, 422_10BPP), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y410, ('Y', '4', '1', '0'), 32, 444_10BPP), + /* RGB formats */ - DEF_RGB (ARGB, ('A', 'R', 'G', 'B'), 32, - 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), - DEF_RGB (ABGR, ('A', 'B', 'G', 'R'), 32, - 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), - DEF_RGB (xRGB, ('X', 'R', 'G', 'B'), 32, - 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), - DEF_RGB (xBGR, ('X', 'B', 'G', 'R'), 32, - 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), - DEF_RGB (BGRA, ('B', 'G', 'R', 'A'), 32, - 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), - DEF_RGB (RGBA, ('R', 'G', 'B', 'A'), 32, - 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), - DEF_RGB (BGRx, ('B', 'G', 'R', 'X'), 32, - 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), - DEF_RGB (RGBx, ('R', 'G', 'B', 'X'), 32, - 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), - DEF_RGB (RGB16, ('R', 'G', '1', '6'), 16, - 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000), - DEF_RGB (RGB, ('R', 'G', '2', '4'), 32, - 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), + DEF_RGB (VA_LSB_FIRST, ARGB, ('A', 'R', 'G', 'B'), 32, 32, 0x0000ff00, + 0x00ff0000, 0xff000000, 0x000000ff), + DEF_RGB (VA_LSB_FIRST, ARGB, ('B', 'G', 'R', 'A'), 32, 32, 0x0000ff00, + 0x00ff0000, 0xff000000, 0x000000ff), + DEF_RGB (VA_MSB_FIRST, ARGB, ('A', 'R', 'G', 'B'), 32, 32, 0x00ff0000, + 0x0000ff00, 0x000000ff, 0xff000000), + + DEF_RGB (VA_LSB_FIRST, xRGB, ('X', 'R', 'G', 'B'), 32, 24, 0x0000ff00, + 0x00ff0000, 0xff000000, 0x00000000), + DEF_RGB (VA_LSB_FIRST, xRGB, ('B', 'G', 'R', 'X'), 32, 24, 0x0000ff00, + 0x00ff0000, 0xff000000, 0x00000000), + DEF_RGB (VA_MSB_FIRST, xRGB, ('X', 'R', 'G', 'B'), 32, 24, 0x00ff0000, + 0x0000ff00, 0x000000ff, 0x00000000), + + DEF_RGB (VA_LSB_FIRST, RGBA, ('R', 'G', 'B', 'A'), 32, 32, 0x000000ff, + 0x0000ff00, 0x00ff0000, 0xff000000), + DEF_RGB (VA_LSB_FIRST, RGBA, ('A', 'B', 'G', 'R'), 32, 32, 0x000000ff, + 0x0000ff00, 0x00ff0000, 0xff000000), + DEF_RGB (VA_MSB_FIRST, RGBA, ('R', 'G', 'B', 'A'), 32, 32, 0xff000000, + 0x00ff0000, 0x0000ff00, 0x000000ff), + + DEF_RGB (VA_LSB_FIRST, RGBx, ('R', 'G', 'B', 'X'), 32, 24, 0x000000ff, + 0x0000ff00, 0x00ff0000, 0x00000000), + DEF_RGB (VA_LSB_FIRST, RGBx, ('X', 'B', 'G', 'R'), 32, 24, 0x000000ff, + 0x0000ff00, 0x00ff0000, 0x00000000), + DEF_RGB (VA_MSB_FIRST, RGBx, ('R', 'G', 'B', 'X'), 32, 24, 0xff000000, + 0x00ff0000, 0x0000ff00, 0x00000000), + + DEF_RGB (VA_LSB_FIRST, ABGR, ('A', 'B', 'G', 'R'), 32, 32, 0xff000000, + 0x00ff0000, 0x0000ff00, 0x000000ff), + DEF_RGB (VA_LSB_FIRST, ABGR, ('R', 'G', 'B', 'A'), 32, 32, 0xff000000, + 0x00ff0000, 0x0000ff00, 0x000000ff), + DEF_RGB (VA_MSB_FIRST, ABGR, ('A', 'B', 'G', 'R'), 32, 32, 0x000000ff, + 0x0000ff00, 0x00ff0000, 0xff000000), + + DEF_RGB (VA_LSB_FIRST, xBGR, ('X', 'B', 'G', 'R'), 32, 24, 0xff000000, + 0x00ff0000, 0x0000ff00, 0x00000000), + DEF_RGB (VA_LSB_FIRST, xBGR, ('R', 'G', 'B', 'X'), 32, 24, 0xff000000, + 0x00ff0000, 0x0000ff00, 0x00000000), + DEF_RGB (VA_MSB_FIRST, xBGR, ('X', 'B', 'G', 'R'), 32, 24, 0x000000ff, + 0x0000ff00, 0x00ff0000, 0x00000000), + + DEF_RGB (VA_LSB_FIRST, BGRA, ('B', 'G', 'R', 'A'), 32, 32, 0x00ff0000, + 0x0000ff00, 0x000000ff, 0xff000000), + DEF_RGB (VA_LSB_FIRST, BGRA, ('A', 'R', 'G', 'B'), 32, 32, 0x00ff0000, + 0x0000ff00, 0x000000ff, 0xff000000), + DEF_RGB (VA_MSB_FIRST, BGRA, ('B', 'G', 'R', 'A'), 32, 32, 0x0000ff00, + 0x00ff0000, 0xff000000, 0x000000ff), + + DEF_RGB (VA_LSB_FIRST, BGRx, ('B', 'G', 'R', 'X'), 32, 24, 0x00ff0000, + 0x0000ff00, 0x000000ff, 0x00000000), + DEF_RGB (VA_LSB_FIRST, BGRx, ('X', 'R', 'G', 'B'), 32, 24, 0x00ff0000, + 0x0000ff00, 0x000000ff, 0x00000000), + DEF_RGB (VA_MSB_FIRST, BGRx, ('B', 'G', 'R', 'X'), 32, 24, 0x0000ff00, + 0x00ff0000, 0xff000000, 0x00000000), + + DEF_RGB (VA_BYTE_ORDER_NOT_CARE, RGB16, ('R', 'G', '1', '6'), 16, 16, + 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000), + DEF_RGB (VA_BYTE_ORDER_NOT_CARE, RGB, ('R', 'G', '2', '4'), 32, 24, + 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), {0,} }; /* *INDENT-ON* */ @@ -98,6 +167,8 @@ static const GstVideoFormatMap gst_vaapi_video_formats[] = { #undef DEF_RGB #undef DEF_YUV +static GArray *gst_vaapi_video_formats_map; + static inline gboolean va_format_is_rgb (const VAImageFormat * va_format) { @@ -113,8 +184,7 @@ va_format_is_yuv (const VAImageFormat * va_format) static inline gboolean va_format_is_same_rgb (const VAImageFormat * fmt1, const VAImageFormat * fmt2) { - return (fmt1->byte_order == fmt2->byte_order && - fmt1->red_mask == fmt2->red_mask && + return (fmt1->red_mask == fmt2->red_mask && fmt1->green_mask == fmt2->green_mask && fmt1->blue_mask == fmt2->blue_mask && fmt1->alpha_mask == fmt2->alpha_mask); @@ -125,21 +195,89 @@ va_format_is_same (const VAImageFormat * fmt1, const VAImageFormat * fmt2) { if (fmt1->fourcc != fmt2->fourcc) return FALSE; + if (fmt1->byte_order != VA_BYTE_ORDER_NOT_CARE && + fmt2->byte_order != VA_BYTE_ORDER_NOT_CARE && + fmt1->byte_order != fmt2->byte_order) + return FALSE; + return va_format_is_rgb (fmt1) ? va_format_is_same_rgb (fmt1, fmt2) : TRUE; } static const GstVideoFormatMap * -get_map (GstVideoFormat format) +get_map_in_default_by_gst_format (GstVideoFormat format) { const GstVideoFormatMap *m; - - for (m = gst_vaapi_video_formats; m->format; m++) { + for (m = gst_vaapi_video_default_formats; m->format; m++) { if (m->format == format) return m; } return NULL; } +static const GstVideoFormatMap * +get_map_in_default_by_va_format (const VAImageFormat * va_format) +{ + const GstVideoFormatMap *m, *n; + + n = NULL; + for (m = gst_vaapi_video_default_formats; m->format; m++) { + if (va_format_is_same (&m->va_format, va_format)) { + /* Should not map to VAImageFormat to same GstVideoFormat */ + g_assert (n == NULL); + n = m; + } + } + return n; +} + +static const GstVideoFormatMap * +get_map_by_gst_format (const GArray * formats, GstVideoFormat format) +{ + const GstVideoFormatMap *entry; + guint i; + + for (i = 0; i < formats->len; i++) { + entry = &g_array_index (formats, GstVideoFormatMap, i); + if (entry->format == format) + return entry; + } + return NULL; +} + +static const GstVideoFormatMap * +get_map_by_va_format (const VAImageFormat * va_format) +{ + const GArray *formats = gst_vaapi_video_formats_map; + const GstVideoFormatMap *entry; + guint i; + + for (i = 0; i < formats->len; i++) { + entry = &g_array_index (formats, GstVideoFormatMap, i); + if (va_format_is_same (&entry->va_format, va_format)) + return entry; + } + return NULL; +} + + +static guint +get_fmt_score_in_default (GstVideoFormat format) +{ + const GstVideoFormatMap *const m = get_map_in_default_by_gst_format (format); + + return m ? (m - &gst_vaapi_video_default_formats[0]) : G_MAXUINT; +} + +static gint +video_format_compare_by_score (gconstpointer a, gconstpointer b) +{ + const GstVideoFormatMap *m1 = (GstVideoFormatMap *) a; + const GstVideoFormatMap *m2 = (GstVideoFormatMap *) b; + + return ((gint) get_fmt_score_in_default (m1->format) - + (gint) get_fmt_score_in_default (m2->format)); +} + /** * gst_vaapi_video_format_to_string: * @format: a #GstVideoFormat @@ -166,8 +304,8 @@ gst_vaapi_video_format_to_string (GstVideoFormat format) gboolean gst_vaapi_video_format_is_rgb (GstVideoFormat format) { - const GstVideoFormatMap *const m = get_map (format); - + const GstVideoFormatMap *const m = + get_map_by_gst_format (gst_vaapi_video_formats_map, format); return m && va_format_is_rgb (&m->va_format); } @@ -182,8 +320,8 @@ gst_vaapi_video_format_is_rgb (GstVideoFormat format) gboolean gst_vaapi_video_format_is_yuv (GstVideoFormat format) { - const GstVideoFormatMap *const m = get_map (format); - + const GstVideoFormatMap *const m = + get_map_by_gst_format (gst_vaapi_video_formats_map, format); return m && va_format_is_yuv (&m->va_format); } @@ -199,12 +337,15 @@ gst_vaapi_video_format_is_yuv (GstVideoFormat format) GstVideoFormat gst_vaapi_video_format_from_va_fourcc (guint32 fourcc) { + const GArray *map = gst_vaapi_video_formats_map; const GstVideoFormatMap *m; + guint i; /* Note: VA fourcc values are now standardized and shall represent a unique format. The associated VAImageFormat is just a hint to determine RGBA component ordering */ - for (m = gst_vaapi_video_formats; m->format; m++) { + for (i = 0; i < map->len; i++) { + m = &g_array_index (map, GstVideoFormatMap, i); if (m->va_format.fourcc == fourcc) return m->format; } @@ -224,13 +365,8 @@ gst_vaapi_video_format_from_va_fourcc (guint32 fourcc) GstVideoFormat gst_vaapi_video_format_from_va_format (const VAImageFormat * va_format) { - const GstVideoFormatMap *m; - - for (m = gst_vaapi_video_formats; m->format; m++) { - if (va_format_is_same (&m->va_format, va_format)) - return m->format; - } - return GST_VIDEO_FORMAT_UNKNOWN; + const GstVideoFormatMap *const m = get_map_by_va_format (va_format); + return m ? m->format : GST_VIDEO_FORMAT_UNKNOWN; } /** @@ -246,8 +382,8 @@ gst_vaapi_video_format_from_va_format (const VAImageFormat * va_format) const VAImageFormat * gst_vaapi_video_format_to_va_format (GstVideoFormat format) { - const GstVideoFormatMap *const m = get_map (format); - + const GstVideoFormatMap *const m = + get_map_by_gst_format (gst_vaapi_video_formats_map, format); return m ? &m->va_format : NULL; } @@ -264,8 +400,8 @@ gst_vaapi_video_format_to_va_format (GstVideoFormat format) guint gst_vaapi_video_format_get_chroma_type (GstVideoFormat format) { - const GstVideoFormatMap *const m = get_map (format); - + const GstVideoFormatMap *const m = + get_map_by_gst_format (gst_vaapi_video_formats_map, format); return m ? m->chroma_type : 0; } @@ -281,9 +417,7 @@ gst_vaapi_video_format_get_chroma_type (GstVideoFormat format) guint gst_vaapi_video_format_get_score (GstVideoFormat format) { - const GstVideoFormatMap *const m = get_map (format); - - return m ? (m - &gst_vaapi_video_formats[0]) : G_MAXUINT; + return get_fmt_score_in_default (format); } /** @@ -336,7 +470,98 @@ gst_vaapi_video_format_get_best_native (GstVideoFormat format) if (format == GST_VIDEO_FORMAT_ENCODED) return GST_VIDEO_FORMAT_NV12; - chroma_type = gst_vaapi_video_format_get_chroma_type (format); return gst_vaapi_video_format_from_chroma (chroma_type); } + +struct ImageFormatsData +{ + VAImageFormat *formats; + guint n; +}; + +static gpointer +video_format_create_map_once (gpointer data) +{ + const GstVideoFormatMap *src_entry, *entry; + guint i; + VAImageFormat *formats = ((struct ImageFormatsData *) data)->formats; + guint n = ((struct ImageFormatsData *) data)->n; + GArray *array = NULL; + + if (formats == NULL || n == 0) + return NULL; + + array = g_array_new (FALSE, TRUE, sizeof (GstVideoFormatMap)); + if (array == NULL) + return NULL; + + for (i = 0; i < n; i++) { + src_entry = get_map_in_default_by_va_format (&formats[i]); + if (src_entry) { + entry = get_map_by_gst_format (array, src_entry->format); + if (entry && !va_format_is_same (&entry->va_format, &formats[i])) { + GST_INFO ("va_format1 with fourcc %" GST_FOURCC_FORMAT + " byte order: %d, BPP: %d, depth %d, red mask 0x%4x," + " green mask 0x%4x, blue mask 0x%4x, alpha mask 0x%4x" + " conflict with va_foramt2 fourcc %" GST_FOURCC_FORMAT + " byte order: %d, BPP: %d, depth %d, red mask 0x%4x," + " green mask 0x%4x, blue mask 0x%4x, alpha mask 0x%4x." + " Both map to the same GST format: %s, which is not" + " allowed, va_format1 will be skipped", + GST_FOURCC_ARGS (entry->va_format.fourcc), + entry->va_format.byte_order, entry->va_format.bits_per_pixel, + entry->va_format.depth, entry->va_format.red_mask, + entry->va_format.green_mask, entry->va_format.blue_mask, + entry->va_format.alpha_mask, + GST_FOURCC_ARGS (formats[i].fourcc), + formats[i].byte_order, formats[i].bits_per_pixel, formats[i].depth, + formats[i].red_mask, formats[i].green_mask, formats[i].blue_mask, + formats[i].alpha_mask, gst_video_format_to_string (entry->format)); + continue; + } + g_array_append_val (array, (*src_entry)); + } + + if (va_format_is_rgb (&formats[i])) { + GST_LOG ("%s to map RGB va_format with fourcc: %" + GST_FOURCC_FORMAT + ", byte order: %d BPP: %d, depth %d, red mask %4x," + " green mask %4x, blue mask %4x, alpha mask %4x to %s gstreamer" + " video format", src_entry ? "succeed" : "failed", + GST_FOURCC_ARGS (formats[i].fourcc), formats[i].byte_order, + formats[i].bits_per_pixel, formats[i].depth, formats[i].red_mask, + formats[i].green_mask, formats[i].blue_mask, formats[i].alpha_mask, + src_entry ? gst_video_format_to_string (src_entry->format) : "any"); + } else { + GST_LOG ("%s to map YUV va format with fourcc: %" + GST_FOURCC_FORMAT ", byte order: %d BPP: %d to %s gstreamer" + " video format", src_entry ? "succeed" : "failed", + GST_FOURCC_ARGS (formats[i].fourcc), formats[i].byte_order, + formats[i].bits_per_pixel, + src_entry ? gst_video_format_to_string (src_entry->format) : "any"); + } + } + + g_array_sort (array, video_format_compare_by_score); + gst_vaapi_video_formats_map = array; + return array; +} + +/** + * gst_vaapi_video_format_new_map: + * @formats: all #VAImageFormat need to map + * @n: the number of VAImageFormat + * + * Return: True if create successfully. + **/ +gboolean +gst_vaapi_video_format_create_map (VAImageFormat * formats, guint n) +{ + static GOnce once = G_ONCE_INIT; + struct ImageFormatsData data = { formats, n }; + + g_once (&once, video_format_create_map_once, &data); + + return once.retval != NULL; +} diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index 35f96ec80d..cef8c504a7 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -59,6 +59,9 @@ gst_vaapi_video_format_from_chroma (guint chroma); GstVideoFormat gst_vaapi_video_format_get_best_native (GstVideoFormat format); +gboolean +gst_vaapi_video_format_create_map (VAImageFormat * formats, guint n); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_FORMAT_H */ From 8d8743a494a69c64c48842ea7a96c66b84c89c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 7 Sep 2019 13:23:01 +0200 Subject: [PATCH 3380/3781] libs: utils: guard the VAEntrypointFEI symbol VAEntrypointFEI appeared in libva 2.0.0 (API version 1.0.0) --- gst-libs/gst/vaapi/gstvaapiutils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 461baf3227..b2cc823483 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -271,7 +271,9 @@ string_of_VAEntrypoint (VAEntrypoint entrypoint) MAP (EncPicture); MAP (EncSliceLP); MAP (VideoProc); +#if VA_CHECK_VERSION(1,0,0) MAP (FEI); +#endif #undef MAP default: break; From 5168611f5564eb1d98ce3e9e0b0a855b6d067eef Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 23 Aug 2019 14:41:06 +0800 Subject: [PATCH 3381/3781] libs: surface: add pointer check for surface_new_from_formats. The command line: gst-launch-1.0 filesrc location=some_name.mjpeg ! jpegparse ! vaapijpegdec ! videoconvert ! video/x-raw,format=I420 ! vaapisink will crash on i965 driver because of no pointer check. We now generate the video format map between GST format and VA format dynamically based on the image format returned by vaQueryImageFormats. i965 driver does to report image format of 444P and Y800 forcc, while the jpeg decoder context VASurfaceAttribPixelFormat use them. We can not recognize these format and pass a NULL pointer to gst_vaapi_surface_new_from_formats. We need to add a pointer check here and let the fallback logic handle this case correctly. Other drivers work well. --- gst-libs/gst/vaapi/gstvaapisurface.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index d17b00e6c4..f092b549e5 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -327,10 +327,12 @@ gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display, GstVaapiSurface *surface; guint i; - for (i = 0; i < formats->len; i++) { - GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); - if (format == gst_vaapi_video_format_from_chroma (chroma_type)) - return gst_vaapi_surface_new (display, chroma_type, width, height); + if (formats) { + for (i = 0; i < formats->len; i++) { + GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); + if (format == gst_vaapi_video_format_from_chroma (chroma_type)) + return gst_vaapi_surface_new (display, chroma_type, width, height); + } } /* Fallback: if there's no format valid for the chroma type let's From b5dd1694205551088bc2d295c79bd6d07f50b1c4 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 9 Sep 2019 18:06:51 +0800 Subject: [PATCH 3382/3781] libs: Add BGR10A2_LE support for color space conversion. Fix: #179 --- gst-libs/gst/vaapi/gstvaapiimage.c | 1 + gst-libs/gst/vaapi/video-format.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 6c10b3b952..a2a626800d 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -94,6 +94,7 @@ vaapi_image_is_linear (const VAImage * va_image) case VA_FOURCC ('B', 'G', 'R', 'X'): case VA_FOURCC ('Y', '2', '1', '0'): case VA_FOURCC ('Y', '4', '1', '0'): + case VA_FOURCC ('A', 'R', '3', '0'): data_size = 4 * width * height; break; case VA_FOURCC ('P', '0', '1', '0'): diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index b1d2d4b148..a22b3095c8 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -160,6 +160,8 @@ static const GstVideoFormatMap gst_vaapi_video_default_formats[] = { 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000), DEF_RGB (VA_BYTE_ORDER_NOT_CARE, RGB, ('R', 'G', '2', '4'), 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), + DEF_RGB (VA_LSB_FIRST, BGR10A2_LE, ('A', 'R', '3', '0'), 32, 30, + 0x3ff00000, 0x000ffc00, 0x000003ff, 0x30000000), {0,} }; /* *INDENT-ON* */ From f0d6263318bbf553d623ac2f155666371f795486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 11 Sep 2019 14:32:22 +0200 Subject: [PATCH 3383/3781] libs: encoders: use GST_PARAM_USER_SHIFT to define internal params This patch makes use of GST_PARAM_USER_SHIFT to define the internal param in encoders to decide which parameters to expose. Thus gstreamer-vaapi will not interfere with any change in GStreamer in the future. Also, the internal symbol was change to GST_VAAPI_PARAM_ENCODER_EXPOSURE to keep the namespacing. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 12 ++-- gst-libs/gst/vaapi/gstvaapiencoder.h | 11 ++-- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 41 +++++++------ gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 60 +++++++++---------- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 26 ++++---- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 6 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 8 +-- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 10 ++-- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 14 ++--- gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 54 ++++++++--------- gst/vaapi/gstvaapiencode.c | 6 +- 11 files changed, 125 insertions(+), 123 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index b6ef77c56b..3e55044284 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1432,7 +1432,7 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) "The desired bitrate expressed in kbps (0: auto-calculate)", 0, 2000 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoder:target-percentage: @@ -1445,7 +1445,7 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) "The desired target percentage of bitrate for variable rate " "controls.", 1, 100, 70, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoder:keyframe-period: @@ -1458,7 +1458,7 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) "Maximal distance between two keyframes (0: auto-calculate)", 0, G_MAXUINT32, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoder:quality-level: @@ -1471,7 +1471,7 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) "(lower value means higher-quality/slow-encode, " " higher value means lower-quality/fast-encode)", 1, 7, 4, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVapiEncoder:roi-default-delta-qp @@ -1485,7 +1485,7 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) "higher value means lower-quality)", -10, 10, -10, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoder: trellis: @@ -1499,7 +1499,7 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) "Trellis Quantization", "The Trellis Quantization Method of Encoder", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 71502239b7..910fb01f7f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -41,10 +41,13 @@ typedef struct _GstVaapiEncoder GstVaapiEncoder; GType gst_vaapi_encoder_get_type (void) G_GNUC_CONST; -/* This user defined flag is added when the internal encoder - class wants to expose its property gparam spec to the according - encode class. */ -#define G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE (1 << 29) +/** + * 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: diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 13295a2fd4..56f90dc119 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3778,7 +3778,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_class_data.rate_control_get_type (), g_class_data.default_rate_control, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:tune: @@ -3792,7 +3792,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_class_data.encoder_tune_get_type (), g_class_data.default_encoder_tune, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:max-bframes: @@ -3803,7 +3803,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:refs: @@ -3815,7 +3815,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_uint ("refs", "Number of Reference Frames", "Number of reference frames", 1, 8, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:init-qp: @@ -3826,7 +3826,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_uint ("init-qp", "Initial QP", "Initial quantizer value", 0, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:min-qp: @@ -3837,7 +3837,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_uint ("min-qp", "Minimum QP", "Minimum quantizer value", 0, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:max-qp: @@ -3850,7 +3850,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_param_spec_uint ("max-qp", "Maximum QP", "Maximum quantizer value", 0, 51, 51, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:qp-ip: @@ -3864,7 +3864,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "Difference of QP between I and P frame (available only on CQP)", -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:qp-ib: @@ -3878,7 +3878,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "Difference of QP between I and B frame (available only on CQP)", -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:num-slices: @@ -3891,7 +3891,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "Number of slices per frame", 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:cabac: @@ -3905,7 +3905,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "Enable CABAC", "Enable CABAC entropy coding mode", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:dct8x8: @@ -3919,7 +3919,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "Enable 8x8 DCT", "Enable adaptive use of 8x8 transforms in I-frames", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:mbbrc: @@ -3933,7 +3933,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "Macroblock level Bitrate Control", GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:temporal-levels: @@ -3946,7 +3946,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "Number of temporal levels in the encoded stream ", MIN_TEMPORAL_LEVELS, MAX_TEMPORAL_LEVELS, MIN_TEMPORAL_LEVELS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:prediction-type: @@ -3960,7 +3960,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) gst_vaapi_encoder_h264_prediction_type (), GST_VAAPI_ENCODER_H264_PREDICTION_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:cpb-length: @@ -3972,7 +3972,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "CPB Length", "Length of the CPB buffer in milliseconds", 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:num-views: @@ -3985,7 +3985,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "Number of Views for MVC encoding", 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:view-ids: @@ -3999,7 +3999,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:aud: @@ -4025,8 +4025,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) " compliance restrictions", gst_vaapi_encoder_h264_compliance_mode_type (), GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_STRICT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:quality_factor: @@ -4040,7 +4039,7 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) "(low value means higher-quality, higher value means lower-quality)", 1, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_H264_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index bcdc7a53f6..12c6493eaf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -3950,7 +3950,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) fei_encoder_class_data.rate_control_get_type (), fei_encoder_class_data.default_rate_control, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:tune: @@ -3964,7 +3964,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) fei_encoder_class_data.encoder_tune_get_type (), fei_encoder_class_data.default_encoder_tune, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:max-bframes: @@ -3975,7 +3975,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", 0, 10, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:init-qp: @@ -3986,7 +3986,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_uint ("init-qp", "Initial QP", "Initial quantizer value", 0, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:min-qp: @@ -3997,7 +3997,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_uint ("min-qp", "Minimum QP", "Minimum quantizer value", 0, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:max-qp: @@ -4010,7 +4010,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) g_param_spec_uint ("max-qp", "Maximum QP", "Maximum quantizer value", 0, 51, 51, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:num-slices: @@ -4023,7 +4023,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Number of slices per frame", 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:cabac: @@ -4037,7 +4037,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Enable CABAC", "Enable CABAC entropy coding mode", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:dct8x8: @@ -4051,7 +4051,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Enable 8x8 DCT", "Enable adaptive use of 8x8 transforms in I-frames", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:cpb-length: @@ -4063,7 +4063,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "CPB Length", "Length of the CPB buffer in milliseconds", 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:num-views: @@ -4076,7 +4076,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Number of Views for MVC encoding", 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei:view-ids: * @@ -4089,7 +4089,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264: disable-fei: @@ -4105,7 +4105,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Disable FEI Mode Encode", "Disable Flexible Encoding Infrasturcture", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** @@ -4122,7 +4122,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "stats out", "Enable stats out for fei", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:num_mv_predictors_l0: @@ -4135,7 +4135,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Indicate how many predictors should be used for l0," "only valid if MVPredictor input enabled", 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:num_mv_predictors_l1: * Indicate how many mv predictors should be used for l1 frames. @@ -4148,7 +4148,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Indicate how many predictors should be used for l1," "only valid if MVPredictor input enabled", 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:search-window: * Use predefined Search Window @@ -4160,7 +4160,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:len-sp: @@ -4172,7 +4172,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "This value defines number of search units in search path", 1, 63, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:search-path: @@ -4186,7 +4186,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:ref-width: @@ -4198,7 +4198,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Width of search region in pixel, must be multiple of 4", 4, 64, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:ref-height: @@ -4210,7 +4210,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Height of search region in pixel, must be multiple of 4", 4, 32, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:submb-mask: * Defines the bit-mask for disabling sub-partition @@ -4223,7 +4223,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:subpel-mode: @@ -4239,7 +4239,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:intrapart-mask: * Specifies which Luma Intra partition is enabled/disabled @@ -4253,7 +4253,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:intra-sad: @@ -4267,7 +4267,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "in the motion search SAD comparison for intra MB", GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:inter-sad: @@ -4281,7 +4281,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "in the motion search SAD comparison for inter MB", GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:adaptive-search: @@ -4292,7 +4292,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "adaptive-search", "Enable adaptive search", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:multi-predL0: * When set to 1, neighbor MV will be used as predictor for list L0, @@ -4304,7 +4304,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Enable multi prediction for ref L0 list, when set neighbor MV will be used" "as predictor, no neighbor MV will be used otherwise", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:multi-predL1: @@ -4317,7 +4317,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Enable multi prediction for ref L1 list, when set neighbor MV will be used" "as predictor, no neighbor MV will be used otherwise", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264Fei: fei-mode: @@ -4337,7 +4337,7 @@ gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) "Functional mode of FEI Encoding", GST_VAAPI_TYPE_FEI_MODE, GST_VAAPI_FEI_MODE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_H264_FEI_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index bc7e7296b5..663c7681be 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2845,7 +2845,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_class_data.rate_control_get_type (), g_class_data.default_rate_control, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:tune: @@ -2859,7 +2859,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_class_data.encoder_tune_get_type (), g_class_data.default_encoder_tune, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:max-bframes: @@ -2870,7 +2870,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:refs: @@ -2882,7 +2882,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_param_spec_uint ("refs", "Number of Reference Frames", "Number of reference frames", 1, 3, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:init-qp: @@ -2893,7 +2893,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_param_spec_uint ("init-qp", "Initial QP", "Initial quantizer value", 0, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:min-qp: @@ -2904,7 +2904,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_param_spec_uint ("min-qp", "Minimum QP", "Minimum quantizer value", 0, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:max-qp: @@ -2917,7 +2917,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_param_spec_uint ("max-qp", "Maximum QP", "Maximum quantizer value", 0, 51, 51, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:qp-ip: @@ -2931,7 +2931,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) "Difference of QP between I and P frame (available only on CQP)", -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:qp-ib: @@ -2945,7 +2945,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) "Difference of QP between I and B frame (available only on CQP)", -51, 51, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /* FIXME: there seems to be issues with multi-slice encoding */ /** @@ -2959,7 +2959,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) "Number of slices per frame", 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:cpb-length: @@ -2971,7 +2971,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) "CPB Length", "Length of the CPB buffer in milliseconds", 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:mbbrc: @@ -2985,7 +2985,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) "Macroblock level Bitrate Control", GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH265:low_delay_b: @@ -2998,7 +2998,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) "Transforms P frames into predictive B frames." " Enable it when P frames are not supported.", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_H265_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index bb920b6ec8..82839081cb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -853,7 +853,7 @@ gst_vaapi_encoder_jpeg_class_init (GstVaapiEncoderJpegClass * klass) g_class_data.rate_control_get_type (), g_class_data.default_rate_control, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); properties[ENCODER_JPEG_PROP_TUNE] = g_param_spec_enum ("tune", @@ -862,14 +862,14 @@ gst_vaapi_encoder_jpeg_class_init (GstVaapiEncoderJpegClass * klass) g_class_data.encoder_tune_get_type (), g_class_data.default_encoder_tune, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + 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 | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_JPEG_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index e5e66c62a7..9574be0243 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -888,7 +888,7 @@ gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass) g_class_data.rate_control_get_type (), g_class_data.default_rate_control, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderMpeg2:tune: @@ -902,20 +902,20 @@ gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass) g_class_data.encoder_tune_get_type (), g_class_data.default_encoder_tune, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); properties[ENCODER_MPEG2_PROP_QUANTIZER] = g_param_spec_uint ("quantizer", "Constant Quantizer", "Constant quantizer (if rate-control mode is CQP)", 2, 62, 8, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); properties[ENCODER_MPEG2_PROP_MAX_BFRAMES] = g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", 0, 16, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_MPEG2_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 77830de965..102b45a4c0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -643,28 +643,28 @@ gst_vaapi_encoder_vp8_class_init (GstVaapiEncoderVP8Class * klass) g_class_data.rate_control_get_type (), g_class_data.default_rate_control, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + 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 | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + 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 | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + 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 | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); properties[ENCODER_VP8_PROP_YAC_Q_INDEX] = g_param_spec_uint ("yac-qi", @@ -674,7 +674,7 @@ gst_vaapi_encoder_vp8_class_init (GstVaapiEncoderVP8Class * klass) " for P frames)", 0, 127, DEFAULT_YAC_QI, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_VP8_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 64f899825f..6c8878b439 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -679,7 +679,7 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) g_class_data.rate_control_get_type (), g_class_data.default_rate_control, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); properties[ENCODER_VP9_PROP_TUNE] = g_param_spec_enum ("tune", @@ -688,7 +688,7 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) g_class_data.encoder_tune_get_type (), g_class_data.default_encoder_tune, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); properties[ENCODER_VP9_PROP_LOOP_FILTER_LEVEL] = g_param_spec_uint ("loop-filter-level", @@ -696,7 +696,7 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) "Controls the deblocking filter strength", 0, 63, DEFAULT_LOOP_FILTER_LEVEL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); properties[ENCODER_VP9_PROP_SHARPNESS_LEVEL] = g_param_spec_uint ("sharpness-level", @@ -704,7 +704,7 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) "Controls the deblocking filter sensitivity", 0, 7, DEFAULT_SHARPNESS_LEVEL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); properties[ENCODER_VP9_PROP_YAC_Q_INDEX] = g_param_spec_uint ("yac-qi", @@ -712,7 +712,7 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) "Quantization Table index for Luma AC Coefficients", 0, 255, DEFAULT_YAC_QINDEX, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); properties[ENCODER_VP9_PROP_REF_PIC_MODE] = g_param_spec_enum ("ref-pic-mode", @@ -721,7 +721,7 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) 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 | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderVP9:cpb-length: @@ -735,7 +735,7 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) "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 | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, ENCODER_VP9_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index 88c10e25e4..67fcfbeed3 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -2051,7 +2051,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) fei_enc_class_data.rate_control_get_type (), fei_enc_class_data.default_rate_control, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:tune: @@ -2065,7 +2065,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) fei_enc_class_data.encoder_tune_get_type (), fei_enc_class_data.default_encoder_tune, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:max-bframes: @@ -2076,7 +2076,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("max-bframes", "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:init-qp: @@ -2087,7 +2087,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("init-qp", "Initial QP", "Initial quantizer value", 1, 51, 26, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:min-qp: @@ -2098,7 +2098,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) g_param_spec_uint ("min-qp", "Minimum QP", "Minimum quantizer value", 1, 51, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:num-slices: @@ -2111,7 +2111,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Number of slices per frame", 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:cabac: @@ -2125,7 +2125,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Enable CABAC", "Enable CABAC entropy coding mode", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:dct8x8: @@ -2139,7 +2139,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Enable 8x8 DCT", "Enable adaptive use of 8x8 transforms in I-frames", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:cpb-length: @@ -2151,7 +2151,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "CPB Length", "Length of the CPB buffer in milliseconds", 1, 10000, DEFAULT_CPB_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:num-views: @@ -2164,7 +2164,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Number of Views for MVC encoding", 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:view-ids: * @@ -2177,7 +2177,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:num-ref: * @@ -2188,7 +2188,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Num Ref", "reference frame number", 1, 6, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:num_mv_predictors_l0: @@ -2200,7 +2200,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Num mv predict l0", "Indicate how many predictors should be used for l0", 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:num_mv_predictors_l1: * @@ -2211,7 +2211,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Num mv predict l1", "Indicate how many predictors should be used for l1", 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:search-window: */ @@ -2222,7 +2222,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:len-sp: */ @@ -2232,7 +2232,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "This value defines number of search units in search path", 1, 63, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:search-path: @@ -2244,7 +2244,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:ref-width: @@ -2255,7 +2255,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Width of search region in pixel, must be multiple of 4", 4, 64, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:ref-height: @@ -2266,7 +2266,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Height of search region in pixel, must be multiple of 4", 4, 32, 32, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:submb-mask: * Defines the bit-mask for disabling sub-partition @@ -2279,7 +2279,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:subpel-mode: @@ -2291,7 +2291,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:intrapart-mask: */ @@ -2302,7 +2302,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:intra-sad: */ @@ -2312,7 +2312,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Specifies distortion measure adjustments used in the motion search SAD comparison for intra MB", GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:inter-sad: @@ -2323,7 +2323,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "Specifies distortion measure adjustments used in the motion search SAD comparison for inter MB", GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:adaptive-search: @@ -2333,7 +2333,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "adaptive-search", "Enable adaptive search", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:multi-predL0: @@ -2343,7 +2343,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "multi predL0", "Enable multi prediction for ref L0 list", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiFeiEncH264:multi-predL0: @@ -2353,7 +2353,7 @@ gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) "multi predL1", "Enable multi prediction for ref L1 list", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE); + GST_VAAPI_PARAM_ENCODER_EXPOSURE); g_object_class_install_properties (object_class, FEI_H264_ENC_N_PROPERTIES, properties); diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index ecf25cc9db..d833f79e48 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -1021,7 +1021,7 @@ gst_vaapiencode_class_install_properties (GstVaapiEncodeClass * klass, pspec = specs[i]; /* Encoder do not want to expose */ - if (!(pspec->flags & G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE)) + if (!(pspec->flags & GST_VAAPI_PARAM_ENCODER_EXPOSURE)) continue; /* Can only set on encoder init time */ if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) @@ -1029,8 +1029,8 @@ gst_vaapiencode_class_install_properties (GstVaapiEncodeClass * klass, /* filter out the G_PARAM_CONSTRUCT, the encoder created later, no need to set the init value in encode. - Also no G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE */ - flags = pspec->flags & (~(G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE | + Also no GST_VAAPI_PARAM_ENCODER_EXPOSURE */ + flags = pspec->flags & (~(GST_VAAPI_PARAM_ENCODER_EXPOSURE | G_PARAM_CONSTRUCT)); if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT) { From 6693be476c42ff841c079a1a1c5d477229cfac28 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 16 Sep 2019 23:28:31 +0800 Subject: [PATCH 3384/3781] libs: h264decoder: do not return error for unhandled NAL unit. Some streams have error data introducing unknown NAL type. There are also kinds of NAL types we do not want to handle. The old manner will set a decoder error when encounter this, which cause a latent crash bug. The decoder may successfully decode the picture and insert it into DPB. But there are error NAL units after the AU which cause the post unit error and make that frame dropped. The later output of the picture still want to ref that frame and crash. No need to set decoder error when can not recognize or handle the NAL unit, just skip it and continue. Fix: #191 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index f7849694b6..b724184423 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -4312,9 +4312,22 @@ decode_unit (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) case GST_H264_NAL_SEI: status = decode_sei (decoder, unit); break; + case GST_H264_NAL_SLICE_DPA: + case GST_H264_NAL_SLICE_DPB: + case GST_H264_NAL_SLICE_DPC: + case GST_H264_NAL_AU_DELIMITER: + case GST_H264_NAL_FILLER_DATA: + case GST_H264_NAL_SPS_EXT: + case GST_H264_NAL_PREFIX_UNIT: + case GST_H264_NAL_DEPTH_SPS: + case GST_H264_NAL_SLICE_AUX: + case GST_H264_NAL_SLICE_DEPTH: + GST_DEBUG ("unsupported NAL unit type %d, just skip", pi->nalu.type); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; default: - GST_WARNING ("unsupported NAL unit type %d", pi->nalu.type); - status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + GST_WARNING ("unknown NAL unit type id %d, skip", pi->nalu.type); + status = GST_VAAPI_DECODER_STATUS_SUCCESS; break; } return status; From 2e8cdac0595a30c22d537b2bbee1c12816d1e1e1 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Wed, 18 Sep 2019 15:29:03 +1000 Subject: [PATCH 3385/3781] egl: don't advertise a wrapped EGLContext as actually wrapped It's not actually wrapped as we create a new EGLContext from the passed in EGLContext. As a result, the created EGLContext was never destroyed. --- gst-libs/gst/vaapi/gstvaapiutils_egl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c index 0bd02505ec..801aef2b8d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -1124,8 +1124,6 @@ egl_context_new_wrapped (EglDisplay * display, EGLContext gl_context) if (!success) return NULL; - if (args.context) - args.context->base.is_wrapped = TRUE; return args.context; } From 499e248d4cac5ac8f230b9cadbf6dd313d23987e Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Wed, 18 Sep 2019 15:30:03 +1000 Subject: [PATCH 3386/3781] egl: Fix racyness in display thread creation Multiple different scenarios could break the display thread creation and end up blocking waiting for thread o be created. Fix them all by correctly waiting for a new boolean to become valid. --- gst-libs/gst/vaapi/gstvaapiutils_egl.c | 9 ++++++++- gst-libs/gst/vaapi/gstvaapiutils_egl.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c index 801aef2b8d..0c2a1f5a11 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -573,6 +573,7 @@ egl_display_thread (gpointer data) EGLint major_version, minor_version; gchar **gl_apis, **gl_api; + g_mutex_lock (&display->mutex); if (!display->base.is_wrapped) { gl_display = display->base.handle.p = egl_get_display_from_native (display->base.handle.u, @@ -609,7 +610,9 @@ egl_display_thread (gpointer data) goto error; display->base.is_valid = TRUE; + display->created = TRUE; g_cond_broadcast (&display->gl_thread_ready); + g_mutex_unlock (&display->mutex); while (!display->gl_thread_cancel) { EglMessage *const msg = @@ -624,17 +627,20 @@ egl_display_thread (gpointer data) egl_object_unref (msg); } } + g_mutex_lock (&display->mutex); done: if (gl_display != EGL_NO_DISPLAY && !display->base.is_wrapped) eglTerminate (gl_display); display->base.handle.p = NULL; g_cond_broadcast (&display->gl_thread_ready); + g_mutex_unlock (&display->mutex); return NULL; /* ERRORS */ error: { + display->created = TRUE; display->base.is_valid = FALSE; goto done; } @@ -656,7 +662,8 @@ egl_display_init (EglDisplay * display) return FALSE; g_mutex_lock (&display->mutex); - g_cond_wait (&display->gl_thread_ready, &display->mutex); + while (!display->created) + g_cond_wait (&display->gl_thread_ready, &display->mutex); g_mutex_unlock (&display->mutex); return display->base.is_valid; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.h b/gst-libs/gst/vaapi/gstvaapiutils_egl.h index 2dcdf6836b..abf3735e7b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.h @@ -122,6 +122,7 @@ struct egl_display_s GCond gl_thread_ready; volatile gboolean gl_thread_cancel; GAsyncQueue *gl_queue; + gboolean created; }; struct egl_config_s From f5e1946036e0e3f43b8981bf11cbc82ee5f5c0e2 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 11 Sep 2019 11:56:35 +0800 Subject: [PATCH 3387/3781] libs: video-format: Make all YUV format available The YUV formats have no ambiguity for drivers, so we can add them all. Some old driver(i965) does not implement full get/put image functions but can use derive image funtions for the YUV format. It does not report that kind of formats correctly in image query, but will derive that YUV format image from surface. The dynamic mapping of YUV format will block that manner. Adding more YUV format mapping has no side effect. So considering the legacy driver conformance, we add all YUV formats mapping statically and dynamic mapping RBG formats Fix: #189 Fix: #190 --- gst-libs/gst/vaapi/video-format.c | 74 +++++++++++++++---------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index a22b3095c8..1463c0e7a9 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -491,41 +491,48 @@ video_format_create_map_once (gpointer data) guint n = ((struct ImageFormatsData *) data)->n; GArray *array = NULL; - if (formats == NULL || n == 0) - return NULL; - array = g_array_new (FALSE, TRUE, sizeof (GstVideoFormatMap)); if (array == NULL) return NULL; - for (i = 0; i < n; i++) { - src_entry = get_map_in_default_by_va_format (&formats[i]); - if (src_entry) { - entry = get_map_by_gst_format (array, src_entry->format); - if (entry && !va_format_is_same (&entry->va_format, &formats[i])) { - GST_INFO ("va_format1 with fourcc %" GST_FOURCC_FORMAT - " byte order: %d, BPP: %d, depth %d, red mask 0x%4x," - " green mask 0x%4x, blue mask 0x%4x, alpha mask 0x%4x" - " conflict with va_foramt2 fourcc %" GST_FOURCC_FORMAT - " byte order: %d, BPP: %d, depth %d, red mask 0x%4x," - " green mask 0x%4x, blue mask 0x%4x, alpha mask 0x%4x." - " Both map to the same GST format: %s, which is not" - " allowed, va_format1 will be skipped", - GST_FOURCC_ARGS (entry->va_format.fourcc), - entry->va_format.byte_order, entry->va_format.bits_per_pixel, - entry->va_format.depth, entry->va_format.red_mask, - entry->va_format.green_mask, entry->va_format.blue_mask, - entry->va_format.alpha_mask, - GST_FOURCC_ARGS (formats[i].fourcc), - formats[i].byte_order, formats[i].bits_per_pixel, formats[i].depth, - formats[i].red_mask, formats[i].green_mask, formats[i].blue_mask, - formats[i].alpha_mask, gst_video_format_to_string (entry->format)); - continue; - } - g_array_append_val (array, (*src_entry)); - } + /* All the YUV format has no ambiguity */ + for (i = 0; i < G_N_ELEMENTS (gst_vaapi_video_default_formats); i++) { + if (va_format_is_yuv (&gst_vaapi_video_default_formats[i].va_format)) + g_array_append_val (array, gst_vaapi_video_default_formats[i]); + } + + if (formats) { + for (i = 0; i < n; i++) { + if (!va_format_is_rgb (&formats[i])) + continue; + + src_entry = get_map_in_default_by_va_format (&formats[i]); + if (src_entry) { + entry = get_map_by_gst_format (array, src_entry->format); + if (entry && !va_format_is_same (&entry->va_format, &formats[i])) { + GST_INFO ("va_format1 with fourcc %" GST_FOURCC_FORMAT + " byte order: %d, BPP: %d, depth %d, red mask 0x%4x," + " green mask 0x%4x, blue mask 0x%4x, alpha mask 0x%4x" + " conflict with va_foramt2 fourcc %" GST_FOURCC_FORMAT + " byte order: %d, BPP: %d, depth %d, red mask 0x%4x," + " green mask 0x%4x, blue mask 0x%4x, alpha mask 0x%4x." + " Both map to the same GST format: %s, which is not" + " allowed, va_format1 will be skipped", + GST_FOURCC_ARGS (entry->va_format.fourcc), + entry->va_format.byte_order, entry->va_format.bits_per_pixel, + entry->va_format.depth, entry->va_format.red_mask, + entry->va_format.green_mask, entry->va_format.blue_mask, + entry->va_format.alpha_mask, + GST_FOURCC_ARGS (formats[i].fourcc), + formats[i].byte_order, formats[i].bits_per_pixel, + formats[i].depth, formats[i].red_mask, formats[i].green_mask, + formats[i].blue_mask, formats[i].alpha_mask, + gst_video_format_to_string (entry->format)); + continue; + } + g_array_append_val (array, (*src_entry)); + } - if (va_format_is_rgb (&formats[i])) { GST_LOG ("%s to map RGB va_format with fourcc: %" GST_FOURCC_FORMAT ", byte order: %d BPP: %d, depth %d, red mask %4x," @@ -535,13 +542,6 @@ video_format_create_map_once (gpointer data) formats[i].bits_per_pixel, formats[i].depth, formats[i].red_mask, formats[i].green_mask, formats[i].blue_mask, formats[i].alpha_mask, src_entry ? gst_video_format_to_string (src_entry->format) : "any"); - } else { - GST_LOG ("%s to map YUV va format with fourcc: %" - GST_FOURCC_FORMAT ", byte order: %d BPP: %d to %s gstreamer" - " video format", src_entry ? "succeed" : "failed", - GST_FOURCC_ARGS (formats[i].fourcc), formats[i].byte_order, - formats[i].bits_per_pixel, - src_entry ? gst_video_format_to_string (src_entry->format) : "any"); } } From 9c46c15e511f5cecf57034d0058f1b6fb540c2b9 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 19 Sep 2019 10:49:11 -0700 Subject: [PATCH 3388/3781] libs: utils: add missing break in switch --- gst-libs/gst/vaapi/gstvaapiutils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index b2cc823483..1169db302c 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -917,6 +917,7 @@ from_GstVaapiBufferMemoryType (guint type) break; case GST_VAAPI_BUFFER_MEMORY_TYPE_USER_PTR: va_type = VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR; + break; default: va_type = 0; break; From 2bfef5a4548a1b1f9cd2ec6a0670db6460b47dca Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 19 Sep 2019 10:56:13 -0700 Subject: [PATCH 3389/3781] libs: encoder: h264_fei: remove dead error condition Found by static analysis. The feipak is always null when we reach the error target. --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index 12c6493eaf..ed392a034e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -4535,8 +4535,6 @@ gst_vaapi_encoder_h264_fei_new (GstVaapiDisplay * display) error: if (feienc) g_object_unref (feienc); - if (feipak) - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & feipak, NULL); if (feiencoder) g_object_unref (feiencoder); From 1ce66e2ed5eeecf0b6c28118dccdd83fdc4f6afb Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 19 Sep 2019 11:17:24 -0700 Subject: [PATCH 3390/3781] libs: encoder: h264_fei: fix potential overflow before widen Found by static analysis. encoder->mb_width * encoder->mb_height is evaluated using 32-bit arithmetic before widen. Thus, cast at least one of these to guint64 to avoid overflow. --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index ed392a034e..ea5c495261 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -2600,7 +2600,7 @@ ensure_bitrate (GstVaapiEncoderH264Fei * encoder) if (!encoder->use_dct8x8) bits_per_mb += (bits_per_mb * 10) / 100; - factor = encoder->mb_width * encoder->mb_height * bits_per_mb; + factor = (guint64) encoder->mb_width * encoder->mb_height * bits_per_mb; base_encoder->bitrate = gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder)) / 1000; From 73ac0c4e502449481f03b7ec7b6282503dfaac6f Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 19 Sep 2019 12:09:20 -0700 Subject: [PATCH 3391/3781] gst: encode: h264_fei: remove useless comparison The expression "len >= 0" is always true since "len" is an unsigned type. And it is clear that the writers intention was not to write "len > 0" since we handle len == 0 in the ensuing "if (len < 3)" conditional block. --- gst/vaapi/gstvaapiencode_h264_fei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode_h264_fei.c b/gst/vaapi/gstvaapiencode_h264_fei.c index 0b1b74a6f6..c09eaea854 100644 --- a/gst/vaapi/gstvaapiencode_h264_fei.c +++ b/gst/vaapi/gstvaapiencode_h264_fei.c @@ -241,7 +241,7 @@ _h264_byte_stream_next_nal (guint8 * buffer, guint32 len, guint32 * nal_size) guint32 flag = 0xFFFFFFFF; guint32 nal_start_len = 0; - g_assert (len >= 0 && buffer && nal_size); + g_assert (buffer && nal_size); if (len < 3) { *nal_size = len; nal_start = (len ? buffer : NULL); From ea35de991444fa17899502298ece7102328e8096 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 24 Sep 2019 01:03:02 +0800 Subject: [PATCH 3392/3781] libs: encoder: correct encoder's ref/unref function. GstVaapiEncoder now is a standard gstobject and need to use gst_object_ref/unref functions. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 3e55044284..ef157e5b97 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -233,7 +233,7 @@ gst_vaapi_encoder_ensure_param_roi_regions (GstVaapiEncoder * encoder, GstVaapiEncoder * gst_vaapi_encoder_ref (GstVaapiEncoder * encoder) { - return gst_vaapi_object_ref (encoder); + return gst_object_ref (encoder); } /** @@ -246,7 +246,7 @@ gst_vaapi_encoder_ref (GstVaapiEncoder * encoder) void gst_vaapi_encoder_unref (GstVaapiEncoder * encoder) { - gst_vaapi_object_unref (encoder); + gst_object_unref (encoder); } /** From 7fb17b1a34da42b7f55e35a4827b5b6729c66761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 23 Sep 2019 19:52:20 +0200 Subject: [PATCH 3393/3781] libs: encoder: remove gst_vaapi_encoder_{ref,unref}() Since GstVaapiEncoder is a descendant of of GstObject, there is no need to keep a custom ref()/unref() methods. This patch deletes them. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 27 --------------------------- gst-libs/gst/vaapi/gstvaapiencoder.h | 6 ------ tests/simple-encoder.c | 2 +- tests/test-fei-enc-in.c | 2 +- 4 files changed, 2 insertions(+), 35 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index ef157e5b97..815660b5b4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -222,33 +222,6 @@ gst_vaapi_encoder_ensure_param_roi_regions (GstVaapiEncoder * encoder, return TRUE; } -/** - * gst_vaapi_encoder_ref: - * @encoder: a #GstVaapiEncoder - * - * Atomically increases the reference count of the given @encoder by one. - * - * Returns: The same @encoder argument - */ -GstVaapiEncoder * -gst_vaapi_encoder_ref (GstVaapiEncoder * encoder) -{ - return gst_object_ref (encoder); -} - -/** - * gst_vaapi_encoder_unref: - * @encoder: a #GstVaapiEncoder - * - * Atomically decreases the reference count of the @encoder by one. If - * the reference count reaches zero, the encoder will be free'd. - */ -void -gst_vaapi_encoder_unref (GstVaapiEncoder * encoder) -{ - gst_object_unref (encoder); -} - /** * gst_vaapi_encoder_replace: * @old_encoder_ptr: a pointer to a #GstVaapiEncoder diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 910fb01f7f..ab4de26218 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -131,12 +131,6 @@ gst_vaapi_encoder_tune_get_type (void) G_GNUC_CONST; GType gst_vaapi_encoder_mbbrc_get_type (void) G_GNUC_CONST; -GstVaapiEncoder * -gst_vaapi_encoder_ref (GstVaapiEncoder * encoder); - -void -gst_vaapi_encoder_unref (GstVaapiEncoder * encoder); - void gst_vaapi_encoder_replace (GstVaapiEncoder ** old_encoder_ptr, GstVaapiEncoder * new_encoder); diff --git a/tests/simple-encoder.c b/tests/simple-encoder.c index c94f3b5f95..97857731f2 100644 --- a/tests/simple-encoder.c +++ b/tests/simple-encoder.c @@ -299,7 +299,7 @@ app_free (App * app) if (app->encoder) { gst_vaapi_encoder_flush (app->encoder); - gst_vaapi_encoder_unref (app->encoder); + gst_object_unref (app->encoder); } if (app->display) diff --git a/tests/test-fei-enc-in.c b/tests/test-fei-enc-in.c index d64a9468ff..9f79c166d5 100644 --- a/tests/test-fei-enc-in.c +++ b/tests/test-fei-enc-in.c @@ -343,7 +343,7 @@ app_free (App * app) if (app->encoder) { gst_vaapi_encoder_flush (app->encoder); - gst_vaapi_encoder_unref (app->encoder); + gst_object_unref (app->encoder); } if (app->display) From f67ec886a3c264d5bc5d39337380e22ee09aafb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 21 Sep 2019 13:39:42 +0200 Subject: [PATCH 3394/3781] libs: decoder: h264, h266: fix g_return_val_if_fail() missuse g_return_val_fail() documentations says: If expr evaluates to FALSE, the current function should be considered to have undefined behaviour (a programmer error). The only correct solution to such an error is to change the module that is calling the current function, so that it avoids this incorrect call. So it was missused in a couple parts of the H264 and H265 internal decoders. This patch changes that to plain conditionals. Also, it was included a couple code-style fixes. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 16 +++++++++++----- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 17 +++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index b724184423..b20e727272 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -369,10 +369,15 @@ gst_vaapi_frame_store_add (GstVaapiFrameStore * fs, field = picture->structure == GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD ? TOP_FIELD : BOTTOM_FIELD; - g_return_val_if_fail (fs->buffers[0]->field_poc[field] == G_MAXINT32, FALSE); + + if (fs->buffers[0]->field_poc[field] != G_MAXINT32) + return FALSE; fs->buffers[0]->field_poc[field] = picture->field_poc[field]; - g_return_val_if_fail (picture->field_poc[!field] == G_MAXINT32, FALSE); + + if (picture->field_poc[!field] != G_MAXINT32) + return FALSE; picture->field_poc[!field] = fs->buffers[0]->field_poc[!field]; + return TRUE; } @@ -744,7 +749,8 @@ dpb_output (GstVaapiDecoderH264 * decoder, GstVaapiFrameStore * fs) for (i = 0; i < fs->num_buffers; i++) { GstVaapiPictureH264 *const pic = fs->buffers[i]; - g_return_val_if_fail (pic != NULL, FALSE); + if (pic == NULL) + return FALSE; pic->output_needed = FALSE; if (!GST_VAAPI_PICTURE_FLAG_IS_SET (pic, GST_VAAPI_PICTURE_FLAG_GHOST)) picture = pic; @@ -3994,8 +4000,8 @@ decode_picture (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) GstVaapiPictureH264 *picture, *first_field; GstVaapiDecoderStatus status; - g_return_val_if_fail (pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); - g_return_val_if_fail (sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); + if (!(pps && sps)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; status = ensure_context (decoder, sps); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 7a5a2e6165..a04c74b8ee 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -676,7 +676,8 @@ dpb_output (GstVaapiDecoderH265 * decoder, GstVaapiFrameStore * fs) g_return_val_if_fail (fs != NULL, FALSE); picture = fs->buffer; - g_return_val_if_fail (picture != NULL, FALSE); + if (!picture) + return FALSE; picture->output_needed = FALSE; return gst_vaapi_picture_output (GST_VAAPI_PICTURE_CAST (picture)); @@ -1630,8 +1631,8 @@ init_picture_refs (GstVaapiDecoderH265 * decoder, { GstVaapiDecoderH265Private *const priv = &decoder->priv; guint32 NumRpsCurrTempList0 = 0, NumRpsCurrTempList1 = 0; - GstVaapiPictureH265 *RefPicListTemp0[16] = { NULL, }, *RefPicListTemp1[16] = { - NULL,}; + GstVaapiPictureH265 *RefPicListTemp0[16] = { NULL, }; + GstVaapiPictureH265 *RefPicListTemp1[16] = { NULL, }; guint i, rIdx = 0; guint num_ref_idx_l0_active_minus1 = 0; guint num_ref_idx_l1_active_minus1 = 0; @@ -2208,9 +2209,9 @@ decode_ref_pic_set (GstVaapiDecoderH265 * decoder, priv->NumPocLtCurr = priv->NumPocLtFoll = 0; } else { GstH265ShortTermRefPicSet *stRefPic = NULL; - gint32 num_lt_pics, pocLt, PocLsbLt[16] = { 0, } - , UsedByCurrPicLt[16] = { - 0,}; + gint32 num_lt_pics, pocLt; + gint32 PocLsbLt[16] = { 0, }; + gint32 UsedByCurrPicLt[16] = { 0, }; gint32 DeltaPocMsbCycleLt[16] = { 0, }; gint numtotalcurr = 0; @@ -2306,8 +2307,8 @@ decode_picture (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) GstVaapiPictureH265 *picture; GstVaapiDecoderStatus status; - g_return_val_if_fail (pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); - g_return_val_if_fail (sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN); + if (!(pps && sps)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; status = ensure_context (decoder, sps); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) From 4c87644914139c22542d0f485d050cca486188a5 Mon Sep 17 00:00:00 2001 From: Yan Wang Date: Thu, 5 Sep 2019 16:40:52 +0800 Subject: [PATCH 3395/3781] vaapipostproc: Use level value for skin-tone-enhancement filter. Currently the parameter of skin-tone-enhancement filter is forced to zero. In fact it could be set different value by the user. So create a new property named as "skin-tone-enhancement-level" for accepting the used defined parameter value. At the same time, skin-tone-enhancement is marked as deprecated. When skin-tone-enhancement-level is set, skin-tone-enhancement will be ignored. --- gst-libs/gst/vaapi/gstvaapifilter.c | 98 ++++++++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapifilter.h | 14 +++++ gst/vaapi/gstvaapipostproc.c | 75 +++++++++++++++++++--- gst/vaapi/gstvaapipostproc.h | 6 ++ 4 files changed, 179 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 766b421f34..64a3ff3dfb 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -330,7 +330,10 @@ enum PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING, PROP_SCALING = GST_VAAPI_FILTER_OP_SCALING, PROP_VIDEO_DIRECTION = GST_VAAPI_FILTER_OP_VIDEO_DIRECTION, +#ifndef GST_REMOVE_DEPRECATED PROP_SKINTONE = GST_VAAPI_FILTER_OP_SKINTONE, +#endif + PROP_SKINTONE_LEVEL = GST_VAAPI_FILTER_OP_SKINTONE_LEVEL, N_PROPERTIES }; @@ -465,6 +468,7 @@ init_properties (void) GST_TYPE_VIDEO_ORIENTATION_METHOD, DEFAULT_VIDEO_DIRECTION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); +#ifndef GST_REMOVE_DEPRECATED /** * GstVaapiFilter:skin-tone-enhancement: * @@ -474,6 +478,18 @@ init_properties (void) "Skin tone enhancement", "Apply the skin tone enhancement algorithm", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); +#endif + + /** + * GstVaapiFilter:skin-tone-enhancement-level: + * + * Apply the skin tone enhancement algorithm with specified value. + */ + g_properties[PROP_SKINTONE_LEVEL] = + g_param_spec_uint ("skin-tone-enhancement-level", + "Skin tone enhancement level", + "Apply the skin tone enhancement algorithm with specified level", 0, 9, 3, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); } static void @@ -523,7 +539,10 @@ op_data_new (GstVaapiFilterOp op, GParamSpec * pspec) op_data->va_cap_size = sizeof (VAProcFilterCap); op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer); break; +#ifndef GST_REMOVE_DEPRECATED case GST_VAAPI_FILTER_OP_SKINTONE: +#endif + case GST_VAAPI_FILTER_OP_SKINTONE_LEVEL: op_data->va_type = VAProcFilterSkinToneEnhancement; op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer); break; @@ -1023,29 +1042,56 @@ op_set_deinterlace (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, return success; } -/* Update skin tone enhancement */ +/* Update skin tone enhancement level */ static gboolean -op_set_skintone_unlocked (GstVaapiFilter * filter, - GstVaapiFilterOpData * op_data, gboolean value) +op_set_skintone_level_unlocked (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data, guint value) { VAProcFilterParameterBuffer *buf; if (!op_data || !op_ensure_buffer (filter, op_data)) return FALSE; - op_data->is_enabled = value; - if (!op_data->is_enabled) - return TRUE; + op_data->is_enabled = 1; buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer); if (!buf) return FALSE; buf->type = op_data->va_type; - buf->value = 0; + buf->value = value; vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL); return TRUE; } +static inline gboolean +op_set_skintone_level (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data, guint value) +{ + gboolean success = FALSE; + + GST_VAAPI_DISPLAY_LOCK (filter->display); + success = op_set_skintone_level_unlocked (filter, op_data, value); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); + return success; +} + +#ifndef GST_REMOVE_DEPRECATED +/* Update skin tone enhancement */ +static gboolean +op_set_skintone_unlocked (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data, gboolean value) +{ + if (!op_data) + return FALSE; + + if (!value) { + op_data->is_enabled = 0; + return TRUE; + } + + return op_set_skintone_level_unlocked (filter, op_data, 3); +} + static inline gboolean op_set_skintone (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, gboolean enhance) @@ -1057,6 +1103,7 @@ op_set_skintone (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, GST_VAAPI_DISPLAY_UNLOCK (filter->display); return success; } +#endif static gboolean deint_refs_set (GArray * refs, GstVaapiSurface ** surfaces, guint num_surfaces) @@ -1441,10 +1488,16 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, case GST_VAAPI_FILTER_OP_SCALING: return gst_vaapi_filter_set_scaling (filter, value ? g_value_get_enum (value) : DEFAULT_SCALING); +#ifndef GST_REMOVE_DEPRECATED case GST_VAAPI_FILTER_OP_SKINTONE: return op_set_skintone (filter, op_data, (value ? g_value_get_boolean (value) : G_PARAM_SPEC_BOOLEAN (op_data->pspec)->default_value)); +#endif + case GST_VAAPI_FILTER_OP_SKINTONE_LEVEL: + return op_set_skintone_level (filter, op_data, + (value ? g_value_get_uint (value) : + G_PARAM_SPEC_UINT (op_data->pspec)->default_value)); case GST_VAAPI_FILTER_OP_VIDEO_DIRECTION: return gst_vaapi_filter_set_video_direction (filter, value ? g_value_get_enum (value) : DEFAULT_VIDEO_DIRECTION); @@ -1985,6 +2038,7 @@ gst_vaapi_filter_set_scaling (GstVaapiFilter * filter, return TRUE; } +#ifndef GST_REMOVE_DEPRECATED /** * gst_vaapi_filter_set_skintone: * @filter: a #GstVaapiFilter @@ -2003,6 +2057,26 @@ gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, gboolean enhance) return op_set_skintone (filter, find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE), enhance); } +#endif + +/** + * gst_vaapi_filter_set_skintone_level: + * @filter: a #GstVaapiFilter + * @value: the value if enable the skin tone enhancement algorithm + * + * Applies the skin tone enhancement algorithm with specifled value. + * + * Return value: %TRUE if the operation is supported, %FALSE + * otherwise. + **/ +gboolean +gst_vaapi_filter_set_skintone_level (GstVaapiFilter * filter, guint value) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return op_set_skintone_level (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE_LEVEL), value); +} /** * gst_vaapi_filter_set_video_direction: @@ -2124,6 +2198,7 @@ gst_vaapi_filter_get_scaling_default (GstVaapiFilter * filter) return DEFAULT_SCALING; } +#ifndef GST_REMOVE_DEPRECATED gboolean gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter) { @@ -2131,6 +2206,15 @@ gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter) return FALSE; } +#endif + +guint +gst_vaapi_filter_get_skintone_level_default (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return 3; +} GstVideoOrientationMethod gst_vaapi_filter_get_video_direction_default (GstVaapiFilter * filter) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 3424ba5a6a..fcd2e45b44 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -51,6 +51,7 @@ typedef struct _GstVaapiFilterOpInfo GstVaapiFilterOpInfo; * @GST_VAAPI_FILTER_OP_VIDEO_DIRECTION: Change video direction * (#GstVideoOrientationMethod). * @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. */ @@ -66,7 +67,10 @@ typedef enum { GST_VAAPI_FILTER_OP_DEINTERLACING, GST_VAAPI_FILTER_OP_SCALING, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION, +#ifndef GST_REMOVE_DEPRECATED GST_VAAPI_FILTER_OP_SKINTONE, +#endif + GST_VAAPI_FILTER_OP_SKINTONE_LEVEL, } GstVaapiFilterOp; /** @@ -259,9 +263,14 @@ gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter, GstVideoOrientationMethod gst_vaapi_filter_get_video_direction (GstVaapiFilter * filter); +#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); @@ -287,8 +296,13 @@ 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); #ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiFilter, gst_object_unref) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index f34e583d5f..51df13b696 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -127,7 +127,10 @@ enum PROP_CROP_RIGHT, PROP_CROP_TOP, PROP_CROP_BOTTOM, +#ifndef GST_REMOVE_DEPRECATED PROP_SKIN_TONE_ENHANCEMENT, +#endif + PROP_SKIN_TONE_ENHANCEMENT_LEVEL, }; #define GST_VAAPI_TYPE_DEINTERLACE_MODE \ @@ -519,7 +522,8 @@ check_filter_update (GstVaapiPostproc * postproc) if (!postproc->has_vpp) return FALSE; - for (i = GST_VAAPI_FILTER_OP_DENOISE; i <= GST_VAAPI_FILTER_OP_SKINTONE; i++) { + for (i = GST_VAAPI_FILTER_OP_DENOISE; + i <= GST_VAAPI_FILTER_OP_SKINTONE_LEVEL; i++) { op_flag = (filter_flag >> i) & 1; if (op_flag) return TRUE; @@ -628,14 +632,33 @@ update_filter (GstVaapiPostproc * postproc) | postproc->crop_bottom) == 0) postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_CROP); - if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SKINTONE) { - if (!gst_vaapi_filter_set_skintone (postproc->filter, - postproc->skintone_enhance)) + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SKINTONE_LEVEL) { + if (!gst_vaapi_filter_set_skintone_level (postproc->filter, + postproc->skintone_value)) return FALSE; - if (gst_vaapi_filter_get_skintone_default (postproc->filter) == - postproc->skintone_enhance) - postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_SKINTONE); + if (gst_vaapi_filter_get_skintone_level_default (postproc->filter) == + postproc->skintone_value) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_SKINTONE_LEVEL); + +#ifndef GST_REMOVE_DEPRECATED + /* + * When use skin tone level property, disable old skin tone property always + */ + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_SKINTONE); +#endif + } else { +#ifndef GST_REMOVE_DEPRECATED + if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SKINTONE) { + if (!gst_vaapi_filter_set_skintone (postproc->filter, + postproc->skintone_enhance)) + return FALSE; + + if (gst_vaapi_filter_get_skintone_default (postproc->filter) == + postproc->skintone_enhance) + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_SKINTONE); + } +#endif } return TRUE; @@ -1969,10 +1992,16 @@ gst_vaapipostproc_set_property (GObject * object, postproc->video_direction = g_value_get_enum (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION; break; +#ifndef GST_REMOVE_DEPRECATED case PROP_SKIN_TONE_ENHANCEMENT: postproc->skintone_enhance = g_value_get_boolean (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SKINTONE; break; +#endif + case PROP_SKIN_TONE_ENHANCEMENT_LEVEL: + postproc->skintone_value = g_value_get_uint (value); + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SKINTONE_LEVEL; + break; case PROP_CROP_LEFT: postproc->crop_left = g_value_get_uint (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CROP; @@ -2049,9 +2078,14 @@ gst_vaapipostproc_get_property (GObject * object, case PROP_VIDEO_DIRECTION: g_value_set_enum (value, postproc->video_direction); break; +#ifndef GST_REMOVE_DEPRECATED case PROP_SKIN_TONE_ENHANCEMENT: g_value_set_boolean (value, postproc->skintone_enhance); break; +#endif + case PROP_SKIN_TONE_ENHANCEMENT_LEVEL: + g_value_set_uint (value, postproc->skintone_value); + break; case PROP_CROP_LEFT: g_value_set_uint (value, postproc->crop_left); break; @@ -2346,6 +2380,7 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) g_object_class_install_property (object_class, PROP_VIDEO_DIRECTION, filter_op->pspec); +#ifndef GST_REMOVE_DEPRECATED /** * GstVaapiPostproc:skin-tone-enhancement: * @@ -2355,6 +2390,17 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) if (filter_op) g_object_class_install_property (object_class, PROP_SKIN_TONE_ENHANCEMENT, filter_op->pspec); +#endif + + /** + * GstVaapiPostproc:skin-tone-enhancement-setting: + * + * Apply the skin tone enhancement algorithm with specified value. + */ + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_SKINTONE_LEVEL); + if (filter_op) + g_object_class_install_property (object_class, + PROP_SKIN_TONE_ENHANCEMENT_LEVEL, filter_op->pspec); g_ptr_array_unref (filter_ops); } @@ -2394,6 +2440,19 @@ cb_set_default_value (GstVaapiPostproc * postproc, GPtrArray * filter_ops, *var = pspec->default_value; } +static void +skintone_set_default_value (GstVaapiPostproc * postproc, GPtrArray * filter_ops) +{ + GstVaapiFilterOpInfo *filter_op; + GParamSpecUInt *pspec; + + filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_SKINTONE_LEVEL); + if (!filter_op) + return; + pspec = G_PARAM_SPEC_UINT (filter_op->pspec); + postproc->skintone_value = pspec->default_value; +} + static void gst_vaapipostproc_init (GstVaapiPostproc * postproc) { @@ -2420,6 +2479,8 @@ gst_vaapipostproc_init (GstVaapiPostproc * postproc) if (filter_ops) { for (i = GST_VAAPI_FILTER_OP_HUE; i <= GST_VAAPI_FILTER_OP_CONTRAST; i++) cb_set_default_value (postproc, filter_ops, i); + + skintone_set_default_value (postproc, filter_ops); g_ptr_array_unref (filter_ops); } diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index 8a8df723ce..c751c8b1c5 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -88,6 +88,7 @@ typedef enum * @GST_VAAPI_POSTPROC_FLAG_SCALE: Video scaling mode. * @GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION: Video rotation and flip/mirroring. * @GST_VAAPI_POSTPROC_FLAG_SKINTONE: Skin tone enhancement. + * @GST_VAAPI_POSTPROC_FLAG_SKINTONE_LEVEL: Skin tone enhancement with value. * * The set of operations that are to be performed for each frame. */ @@ -105,7 +106,11 @@ typedef enum GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION = 1 << GST_VAAPI_FILTER_OP_VIDEO_DIRECTION, GST_VAAPI_POSTPROC_FLAG_CROP = 1 << GST_VAAPI_FILTER_OP_CROP, +#ifndef GST_REMOVE_DEPRECATED GST_VAAPI_POSTPROC_FLAG_SKINTONE = 1 << GST_VAAPI_FILTER_OP_SKINTONE, +#endif + GST_VAAPI_POSTPROC_FLAG_SKINTONE_LEVEL = + 1 << GST_VAAPI_FILTER_OP_SKINTONE_LEVEL, /* Additional custom flags */ GST_VAAPI_POSTPROC_FLAG_CUSTOM = 1 << 20, @@ -182,6 +187,7 @@ struct _GstVaapiPostproc gfloat contrast; gboolean skintone_enhance; + guint skintone_value; gboolean forward_crop; guint get_va_surfaces:1; From 8ec5adcae8102e130649b1b184edab0146be6d01 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 7 Oct 2019 10:23:09 -0700 Subject: [PATCH 3396/3781] add .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..b25c15b81f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ From 85ff86e90d3ebc0023a8113b400295da69309515 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Wed, 2 Oct 2019 12:54:52 -0700 Subject: [PATCH 3397/3781] libs: filter: query param spec for default video-direction Related: #159 --- gst-libs/gst/vaapi/gstvaapifilter.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 64a3ff3dfb..ef8a833d2a 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -308,7 +308,6 @@ vpp_get_pipeline_caps (GstVaapiFilter * filter) #define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN #define DEFAULT_SCALING GST_VAAPI_SCALE_METHOD_DEFAULT -#define DEFAULT_VIDEO_DIRECTION GST_VIDEO_ORIENTATION_IDENTITY enum { @@ -466,7 +465,8 @@ init_properties (void) "Video Direction", "Video direction: rotation and flipping", GST_TYPE_VIDEO_ORIENTATION_METHOD, - DEFAULT_VIDEO_DIRECTION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + GST_VIDEO_ORIENTATION_IDENTITY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); #ifndef GST_REMOVE_DEPRECATED /** @@ -1499,8 +1499,9 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, (value ? g_value_get_uint (value) : G_PARAM_SPEC_UINT (op_data->pspec)->default_value)); case GST_VAAPI_FILTER_OP_VIDEO_DIRECTION: - return gst_vaapi_filter_set_video_direction (filter, value ? - g_value_get_enum (value) : DEFAULT_VIDEO_DIRECTION); + return gst_vaapi_filter_set_video_direction (filter, + (value ? g_value_get_enum (value) : + G_PARAM_SPEC_ENUM (op_data->pspec)->default_value)); default: break; } @@ -2136,6 +2137,14 @@ op_get_float_default_value (GstVaapiFilter * filter, return pspec->default_value; } +static inline gint +op_get_enum_default_value (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data) +{ + GParamSpecEnum *const pspec = G_PARAM_SPEC_ENUM (op_data->pspec); + return pspec->default_value; +} + gfloat gst_vaapi_filter_get_denoising_level_default (GstVaapiFilter * filter) { @@ -2221,5 +2230,6 @@ gst_vaapi_filter_get_video_direction_default (GstVaapiFilter * filter) { g_return_val_if_fail (filter != NULL, FALSE); - return DEFAULT_VIDEO_DIRECTION; + return op_get_enum_default_value (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION)); } From 3d39143825b3a26191d87bc7e78645f2e9e19026 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 7 Oct 2019 09:44:06 -0700 Subject: [PATCH 3398/3781] libs: filter: query param spec for default skin-tone values Related: #159 --- gst-libs/gst/vaapi/gstvaapifilter.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index ef8a833d2a..ce8c87a5db 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -2145,6 +2145,22 @@ op_get_enum_default_value (GstVaapiFilter * filter, return pspec->default_value; } +static inline guint +op_get_uint_default_value (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data) +{ + GParamSpecUInt *const pspec = G_PARAM_SPEC_UINT (op_data->pspec); + return pspec->default_value; +} + +static inline gboolean +op_get_bool_default_value (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data) +{ + GParamSpecBoolean *const pspec = G_PARAM_SPEC_BOOLEAN (op_data->pspec); + return pspec->default_value; +} + gfloat gst_vaapi_filter_get_denoising_level_default (GstVaapiFilter * filter) { @@ -2213,7 +2229,8 @@ gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter) { g_return_val_if_fail (filter != NULL, FALSE); - return FALSE; + return op_get_bool_default_value (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE)); } #endif @@ -2222,7 +2239,8 @@ gst_vaapi_filter_get_skintone_level_default (GstVaapiFilter * filter) { g_return_val_if_fail (filter != NULL, FALSE); - return 3; + return op_get_uint_default_value (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE_LEVEL)); } GstVideoOrientationMethod From 6690031b2bf3b215411944d3e9ffa8cfa7058132 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 7 Oct 2019 09:56:37 -0700 Subject: [PATCH 3399/3781] libs: filter: query param spec for default scale method Related: #159 --- gst-libs/gst/vaapi/gstvaapifilter.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index ce8c87a5db..3e2caf78ea 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -307,7 +307,6 @@ vpp_get_pipeline_caps (GstVaapiFilter * filter) /* ------------------------------------------------------------------------- */ #define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN -#define DEFAULT_SCALING GST_VAAPI_SCALE_METHOD_DEFAULT enum { @@ -453,7 +452,8 @@ init_properties (void) "Scaling Method", "Scaling method to use", GST_VAAPI_TYPE_SCALE_METHOD, - DEFAULT_SCALING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + GST_VAAPI_SCALE_METHOD_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * GstVaapiFilter:video-direction: @@ -1486,8 +1486,9 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, G_PARAM_SPEC_ENUM (op_data->pspec)->default_value), 0); break; case GST_VAAPI_FILTER_OP_SCALING: - return gst_vaapi_filter_set_scaling (filter, value ? - g_value_get_enum (value) : DEFAULT_SCALING); + return gst_vaapi_filter_set_scaling (filter, + (value ? g_value_get_enum (value) : + G_PARAM_SPEC_ENUM (op_data->pspec)->default_value)); #ifndef GST_REMOVE_DEPRECATED case GST_VAAPI_FILTER_OP_SKINTONE: return op_set_skintone (filter, op_data, @@ -2220,7 +2221,8 @@ gst_vaapi_filter_get_scaling_default (GstVaapiFilter * filter) { g_return_val_if_fail (filter != NULL, FALSE); - return DEFAULT_SCALING; + return op_get_enum_default_value (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_SCALING)); } #ifndef GST_REMOVE_DEPRECATED From f232f87f7082957e0ebf470d1df622ccd39a184a Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 7 Oct 2019 11:39:19 -0700 Subject: [PATCH 3400/3781] libs: filter: use macro for returning op default value The code is essentially the same for getting all op default values. Thus, use a macro to help minimize code duplication and [hopefully] encourage using the same mechanism for all default getters. --- gst-libs/gst/vaapi/gstvaapifilter.c | 59 ++++++++++------------------- 1 file changed, 19 insertions(+), 40 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 3e2caf78ea..36ef4d37cb 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -308,6 +308,15 @@ vpp_get_pipeline_caps (GstVaapiFilter * filter) #define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN +#define OP_DATA_DEFAULT_VALUE(type, op_data) \ + g_value_get_##type (g_param_spec_get_default_value (op_data->pspec)) + +#define OP_RET_DEFAULT_VALUE(type, filter, op) \ + do { \ + g_return_val_if_fail (filter != NULL, FALSE); \ + return OP_DATA_DEFAULT_VALUE (type, find_operation (filter, op)); \ + } while (0) + enum { PROP_DISPLAY = 1, @@ -2165,91 +2174,61 @@ op_get_bool_default_value (GstVaapiFilter * filter, gfloat gst_vaapi_filter_get_denoising_level_default (GstVaapiFilter * filter) { - g_return_val_if_fail (filter != NULL, FALSE); - - return op_get_float_default_value (filter, - find_operation (filter, GST_VAAPI_FILTER_OP_DENOISE)); + OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_DENOISE); } gfloat gst_vaapi_filter_get_sharpening_level_default (GstVaapiFilter * filter) { - g_return_val_if_fail (filter != NULL, FALSE); - - return op_get_float_default_value (filter, - find_operation (filter, GST_VAAPI_FILTER_OP_SHARPEN)); + OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_SHARPEN); } gfloat gst_vaapi_filter_get_hue_default (GstVaapiFilter * filter) { - g_return_val_if_fail (filter != NULL, FALSE); - - return op_get_float_default_value (filter, - find_operation (filter, GST_VAAPI_FILTER_OP_HUE)); + OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_HUE); } gfloat gst_vaapi_filter_get_saturation_default (GstVaapiFilter * filter) { - g_return_val_if_fail (filter != NULL, FALSE); - - return op_get_float_default_value (filter, - find_operation (filter, GST_VAAPI_FILTER_OP_SATURATION)); + OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_SATURATION); } gfloat gst_vaapi_filter_get_brightness_default (GstVaapiFilter * filter) { - g_return_val_if_fail (filter != NULL, FALSE); - - return op_get_float_default_value (filter, - find_operation (filter, GST_VAAPI_FILTER_OP_BRIGHTNESS)); + OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_BRIGHTNESS); } gfloat gst_vaapi_filter_get_contrast_default (GstVaapiFilter * filter) { - g_return_val_if_fail (filter != NULL, FALSE); - - return op_get_float_default_value (filter, - find_operation (filter, GST_VAAPI_FILTER_OP_CONTRAST)); + OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_CONTRAST); } GstVaapiScaleMethod gst_vaapi_filter_get_scaling_default (GstVaapiFilter * filter) { - g_return_val_if_fail (filter != NULL, FALSE); - - return op_get_enum_default_value (filter, - find_operation (filter, GST_VAAPI_FILTER_OP_SCALING)); + OP_RET_DEFAULT_VALUE (enum, filter, GST_VAAPI_FILTER_OP_SCALING); } #ifndef GST_REMOVE_DEPRECATED gboolean gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter) { - g_return_val_if_fail (filter != NULL, FALSE); - - return op_get_bool_default_value (filter, - find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE)); + OP_RET_DEFAULT_VALUE (boolean, filter, GST_VAAPI_FILTER_OP_SKINTONE); } #endif guint gst_vaapi_filter_get_skintone_level_default (GstVaapiFilter * filter) { - g_return_val_if_fail (filter != NULL, FALSE); - - return op_get_uint_default_value (filter, - find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE_LEVEL)); + OP_RET_DEFAULT_VALUE (uint, filter, GST_VAAPI_FILTER_OP_SKINTONE_LEVEL); } GstVideoOrientationMethod gst_vaapi_filter_get_video_direction_default (GstVaapiFilter * filter) { - g_return_val_if_fail (filter != NULL, FALSE); - - return op_get_enum_default_value (filter, - find_operation (filter, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION)); + OP_RET_DEFAULT_VALUE (boolean, filter, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION); } From 038b608cdea68a6637a8047e4fb8b46a78e0fc52 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 7 Oct 2019 11:53:23 -0700 Subject: [PATCH 3401/3781] libs: filter: use OP_DATA_DEFAULT_VALUE macro --- gst-libs/gst/vaapi/gstvaapifilter.c | 55 +++++++---------------------- 1 file changed, 12 insertions(+), 43 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 36ef4d37cb..a634cb0152 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -868,8 +868,7 @@ op_set_generic_unlocked (GstVaapiFilter * filter, if (!op_data || !op_ensure_buffer (filter, op_data)) return FALSE; - op_data->is_enabled = - (value != G_PARAM_SPEC_FLOAT (op_data->pspec)->default_value); + op_data->is_enabled = (value != OP_DATA_DEFAULT_VALUE (float, op_data)); if (!op_data->is_enabled) return TRUE; @@ -935,8 +934,10 @@ op_set_color_balance_unlocked (GstVaapiFilter * filter, * which will store all the color balance operators. */ if (!enabled_data) { - if (value == G_PARAM_SPEC_FLOAT (op_data->pspec)->default_value) + /* *INDENT-OFF* */ + if (value == OP_DATA_DEFAULT_VALUE (float, op_data)) return TRUE; + /* *INDENT-ON* */ if (!op_ensure_n_elements_buffer (filter, op_data, COLOR_BALANCE_NUM)) return FALSE; @@ -954,7 +955,7 @@ op_set_color_balance_unlocked (GstVaapiFilter * filter, buf[i].type = color_data[i]->va_type; buf[i].attrib = color_data[i]->va_subtype; - va_value = G_PARAM_SPEC_FLOAT (color_data[i]->pspec)->default_value; + va_value = OP_DATA_DEFAULT_VALUE (float, color_data[i]); if (color_data[i]->op == op_data->op) { filter_cap = color_data[i]->va_caps; /* fail but ignore current value and set default one */ @@ -1481,37 +1482,37 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, case GST_VAAPI_FILTER_OP_SHARPEN: return op_set_generic (filter, op_data, (value ? g_value_get_float (value) : - G_PARAM_SPEC_FLOAT (op_data->pspec)->default_value)); + OP_DATA_DEFAULT_VALUE (float, op_data))); case GST_VAAPI_FILTER_OP_HUE: case GST_VAAPI_FILTER_OP_SATURATION: case GST_VAAPI_FILTER_OP_BRIGHTNESS: case GST_VAAPI_FILTER_OP_CONTRAST: return op_set_color_balance (filter, op_data, (value ? g_value_get_float (value) : - G_PARAM_SPEC_FLOAT (op_data->pspec)->default_value)); + OP_DATA_DEFAULT_VALUE (float, op_data))); case GST_VAAPI_FILTER_OP_DEINTERLACING: return op_set_deinterlace (filter, op_data, (value ? g_value_get_enum (value) : - G_PARAM_SPEC_ENUM (op_data->pspec)->default_value), 0); + OP_DATA_DEFAULT_VALUE (enum, op_data)), 0); break; case GST_VAAPI_FILTER_OP_SCALING: return gst_vaapi_filter_set_scaling (filter, (value ? g_value_get_enum (value) : - G_PARAM_SPEC_ENUM (op_data->pspec)->default_value)); + OP_DATA_DEFAULT_VALUE (enum, op_data))); #ifndef GST_REMOVE_DEPRECATED case GST_VAAPI_FILTER_OP_SKINTONE: return op_set_skintone (filter, op_data, (value ? g_value_get_boolean (value) : - G_PARAM_SPEC_BOOLEAN (op_data->pspec)->default_value)); + OP_DATA_DEFAULT_VALUE (boolean, op_data))); #endif case GST_VAAPI_FILTER_OP_SKINTONE_LEVEL: return op_set_skintone_level (filter, op_data, (value ? g_value_get_uint (value) : - G_PARAM_SPEC_UINT (op_data->pspec)->default_value)); + OP_DATA_DEFAULT_VALUE (uint, op_data))); case GST_VAAPI_FILTER_OP_VIDEO_DIRECTION: return gst_vaapi_filter_set_video_direction (filter, (value ? g_value_get_enum (value) : - G_PARAM_SPEC_ENUM (op_data->pspec)->default_value)); + OP_DATA_DEFAULT_VALUE (enum, op_data))); default: break; } @@ -2139,38 +2140,6 @@ gst_vaapi_filter_get_video_direction (GstVaapiFilter * filter) return filter->video_direction; } -static inline gfloat -op_get_float_default_value (GstVaapiFilter * filter, - GstVaapiFilterOpData * op_data) -{ - GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (op_data->pspec); - return pspec->default_value; -} - -static inline gint -op_get_enum_default_value (GstVaapiFilter * filter, - GstVaapiFilterOpData * op_data) -{ - GParamSpecEnum *const pspec = G_PARAM_SPEC_ENUM (op_data->pspec); - return pspec->default_value; -} - -static inline guint -op_get_uint_default_value (GstVaapiFilter * filter, - GstVaapiFilterOpData * op_data) -{ - GParamSpecUInt *const pspec = G_PARAM_SPEC_UINT (op_data->pspec); - return pspec->default_value; -} - -static inline gboolean -op_get_bool_default_value (GstVaapiFilter * filter, - GstVaapiFilterOpData * op_data) -{ - GParamSpecBoolean *const pspec = G_PARAM_SPEC_BOOLEAN (op_data->pspec); - return pspec->default_value; -} - gfloat gst_vaapi_filter_get_denoising_level_default (GstVaapiFilter * filter) { From 600aba57cfe91ea991c41f75f7ad347621ec4f5a Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Wed, 9 Oct 2019 12:12:18 -0700 Subject: [PATCH 3402/3781] libs: filter: fix default orientation regression Fix regression introduced in f232f87f7082 --- gst-libs/gst/vaapi/gstvaapifilter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index a634cb0152..eabcedf6eb 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -2199,5 +2199,5 @@ gst_vaapi_filter_get_skintone_level_default (GstVaapiFilter * filter) GstVideoOrientationMethod gst_vaapi_filter_get_video_direction_default (GstVaapiFilter * filter) { - OP_RET_DEFAULT_VALUE (boolean, filter, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION); + OP_RET_DEFAULT_VALUE (enum, filter, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION); } From f80dee40c8b688f21173094e2853e080d1575449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 11 Oct 2019 17:13:34 +0200 Subject: [PATCH 3403/3781] build: halt meson configuration if no renderer API We should halt meson configuration if there is no render API installed (either DRM, Wayland or X11). That behavior was already in autotools but missed in meson. This patch brings it back. Fixes: #196 --- meson.build | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/meson.build b/meson.build index 227bcf9236..4ef68813dd 100644 --- a/meson.build +++ b/meson.build @@ -115,6 +115,10 @@ USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl USE_WAYLAND = libva_wayland_dep.found() and wayland_client_dep.found() and wayland_protocols_dep.found() and wayland_scanner_bin.found() and get_option('with_wayland') != 'no' USE_X11 = libva_x11_dep.found() and x11_dep.found() and get_option('with_x11') != 'no' +if not (USE_DRM or USE_X11 or USE_EGL or USE_GLX or USE_WAYLAND) + error('No renderer API found (it is requried either DRM, X11 and/or WAYLAND)') +endif + driverdir = libva_dep.get_pkgconfig_variable('driverdir') if driverdir == '' driverdir = '@0@/@1@/@2@'.format(get_option('prefix'), get_option('libdir'), 'dri') From 58a512b7c5aa671fd264146d3660633bd8cde47e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 11 Oct 2019 17:34:06 +0200 Subject: [PATCH 3404/3781] libs: window: x11: Avoid usage of deprecated API --- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 7d9eea704e..c5bfb8604d 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -105,7 +105,6 @@ timed_wait_event (GstVaapiWindow * window, int type, guint64 end_time, Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); const Window xid = GST_VAAPI_WINDOW_ID (window); XEvent tmp_event; - GTimeVal now; guint64 now_time; Bool got_event; @@ -125,8 +124,7 @@ timed_wait_event (GstVaapiWindow * window, int type, guint64 end_time, GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (got_event) return TRUE; - g_get_current_time (&now); - now_time = (guint64) now.tv_sec * 1000000 + now.tv_usec; + now_time = g_get_real_time (); } while (now_time < end_time); return FALSE; } @@ -341,7 +339,6 @@ gst_vaapi_window_x11_set_fullscreen (GstVaapiWindow * window, XEvent e; guint width, height; gboolean has_errors; - GTimeVal now; guint64 end_time; GST_VAAPI_WINDOW_LOCK_DISPLAY (window); @@ -378,8 +375,7 @@ gst_vaapi_window_x11_set_fullscreen (GstVaapiWindow * window, /* Try to wait for the completion of the fullscreen mode switch */ if (!window->use_foreign_window && priv->is_mapped) { const guint DELAY = 100000; /* 100 ms */ - g_get_current_time (&now); - end_time = DELAY + ((guint64) now.tv_sec * 1000000 + now.tv_usec); + end_time = DELAY + g_get_real_time (); while (timed_wait_event (window, ConfigureNotify, end_time, &e)) { if (fullscreen) { gst_vaapi_display_get_size (GST_VAAPI_WINDOW_DISPLAY (window), From 40bcefcb3ba4c250ac26a4f504cd17b427bc1802 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 10 Oct 2019 15:26:36 -0700 Subject: [PATCH 3405/3781] vaapipostproc: fix off-by-one coord translations When translating navigation x,y coordinates for video-direction, it is necessary to subtract 1 when using the video dimensions to compute the new x,y coordinates. That is, a 100x200 image should map coordinates in x=[0-99],y=[0-199]. This issue was found with unit tests provided in !182. --- gst/vaapi/gstvaapipostproc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 51df13b696..0c899d5bca 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1801,31 +1801,31 @@ gst_vaapipostproc_src_event (GstBaseTransform * trans, GstEvent * event) switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { case GST_VIDEO_ORIENTATION_90R: new_x = y; - new_y = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; + new_y = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - 1 - x; break; case GST_VIDEO_ORIENTATION_90L: - new_x = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; + new_x = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - 1 - y; new_y = x; break; case GST_VIDEO_ORIENTATION_UR_LL: - new_x = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; - new_y = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; + new_x = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - 1 - y; + new_y = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - 1 - x; break; case GST_VIDEO_ORIENTATION_UL_LR: new_x = y; new_y = x; break; case GST_VIDEO_ORIENTATION_180: - new_x = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; - new_y = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; + new_x = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - 1 - x; + new_y = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - 1 - y; break; case GST_VIDEO_ORIENTATION_HORIZ: - new_x = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - x; + new_x = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info) - 1 - x; new_y = y; break; case GST_VIDEO_ORIENTATION_VERT: new_x = x; - new_y = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - y; + new_y = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info) - 1 - y; break; default: new_x = x; From 8af5ef8a0be0e5a6d97b6f8e9c942331d065e30a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 14 Oct 2019 01:01:27 +0100 Subject: [PATCH 3406/3781] Remove autotools build --- .gitmodules | 3 - Makefile.am | 26 -- autogen.sh | 124 ------ common | 1 - configure.ac | 768 --------------------------------- git.mk | 348 --------------- gst-libs/Makefile.am | 3 - gst-libs/gst/Makefile.am | 3 - gst-libs/gst/vaapi/Makefile.am | 545 ----------------------- gst/Makefile.am | 3 - gst/vaapi/Makefile.am | 166 ------- m4/Makefile.am | 3 - tests/Makefile.am | 182 -------- tests/elements/Makefile.am | 50 --- 14 files changed, 2225 deletions(-) delete mode 100644 .gitmodules delete mode 100644 Makefile.am delete mode 100755 autogen.sh delete mode 160000 common delete mode 100644 configure.ac delete mode 100644 git.mk delete mode 100644 gst-libs/Makefile.am delete mode 100644 gst-libs/gst/Makefile.am delete mode 100644 gst-libs/gst/vaapi/Makefile.am delete mode 100644 gst/Makefile.am delete mode 100644 gst/vaapi/Makefile.am delete mode 100644 m4/Makefile.am delete mode 100644 tests/Makefile.am delete mode 100644 tests/elements/Makefile.am diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 0ab838765a..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "common"] - path = common - url = https://gitlab.freedesktop.org/gstreamer/common.git diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index f88b6c8c86..0000000000 --- a/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -ACLOCAL_AMFLAGS = -I m4 -I common/m4 - -if BUILD_EXAMPLES -SUBDIRS_TESTS = tests -else -SUBDIRS_TESTS = -endif - -SUBDIRS = gst-libs gst $(SUBDIRS_TESTS) m4 common - -# Extra clean files so that maintainer-clean removes *everything* -MAINTAINERCLEANFILES = \ - $(GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL) \ - $(GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN) \ - $(GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL) \ - $(srcdir)/autoregen.sh $(srcdir)/INSTALL \ - $(NULL) - -EXTRA_DIST = \ - configure.ac autogen.sh \ - gstreamer-vaapi.doap \ - $(shell find "$(top_srcdir)" -type f -name meson.build ! -path "$(top_srcdir)/$(PACKAGE_TARNAME)-*" ) \ - meson_options.txt - --include $(top_srcdir)/common/release.mak --include $(top_srcdir)/git.mk diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index d88efbb27f..0000000000 --- a/autogen.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/bin/sh -# -# gstreamer-vaapi autogen.sh -# -# Run this to generate all the initial makefiles, etc. -# -# This file has been generated from common/autogen.sh.in via common/update-autogen - - -test -n "$srcdir" || srcdir=`dirname "$0"` -test -n "$srcdir" || srcdir=. - -olddir=`pwd` -cd "$srcdir" - -package=gstreamer-vaapi -srcfile=gstreamer-vaapi.doap - -# Make sure we have common -if test ! -f common/gst-autogen.sh; -then - echo "+ Setting up common submodule" - git submodule init -fi -git submodule update - -# source helper functions -if test ! -f common/gst-autogen.sh; -then - echo There is something wrong with your source tree. - echo You are missing common/gst-autogen.sh - exit 1 -fi -. common/gst-autogen.sh - -# install pre-commit hook for doing clean commits -if test ! \( -x .git/hooks/pre-commit -a -L .git/hooks/pre-commit \); -then - rm -f .git/hooks/pre-commit - if ! ln -s ../../common/hooks/pre-commit.hook .git/hooks/pre-commit 2> /dev/null - then - echo "Failed to create commit hook symlink, copying instead ..." - cp common/hooks/pre-commit.hook .git/hooks/pre-commit - fi -fi - -# GNU gettext automake support doesn't get along with git. -# https://bugzilla.gnome.org/show_bug.cgi?id=661128 -if test -d po ; then - touch -t 200001010000 po/gstreamer-vaapi-1.0.pot -fi - -CONFIGURE_DEF_OPT='--enable-maintainer-mode --enable-gtk-doc' - -if test "x$package" = "xgstreamer"; then - CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --enable-docbook --enable-failing-tests --enable-poisoning" -elif test "x$package" = "xgst-plugins-bad"; then - CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-player-tests" -fi - -autogen_options $@ - -printf "+ check for build tools" -if test -z "$NOCHECK"; then - echo - - printf " checking for autoreconf ... " - echo - which "autoreconf" 2>/dev/null || { - echo "not found! Please install the autoconf package." - exit 1 - } - - printf " checking for pkg-config ... " - echo - which "pkg-config" 2>/dev/null || { - echo "not found! Please install pkg-config." - exit 1 - } -else - echo ": skipped version checks" -fi - -# if no arguments specified then this will be printed -if test -z "$*" && test -z "$NOCONFIGURE"; then - echo "+ checking for autogen.sh options" - echo " This autogen script will automatically run ./configure as:" - echo " ./configure $CONFIGURE_DEF_OPT" - echo " To pass any additional options, please specify them on the $0" - echo " command line." -fi - -toplevel_check $srcfile - -# autopoint -if test -d po && grep ^AM_GNU_GETTEXT_VERSION configure.ac >/dev/null ; then - tool_run "autopoint" "--force" -fi - -# aclocal -if test -f acinclude.m4; then rm acinclude.m4; fi - -autoreconf --force --install || exit 1 - -test -n "$NOCONFIGURE" && { - echo "+ skipping configure stage for package $package, as requested." - echo "+ autogen.sh done." - exit 0 -} - -cd "$olddir" - -echo "+ running configure ... " -test ! -z "$CONFIGURE_DEF_OPT" && echo " default flags: $CONFIGURE_DEF_OPT" -test ! -z "$CONFIGURE_EXT_OPT" && echo " external flags: $CONFIGURE_EXT_OPT" -echo - -echo "$srcdir/configure" $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT -"$srcdir/configure" $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT || { - echo " configure failed" - exit 1 -} - -echo "Now type 'make' to compile $package." diff --git a/common b/common deleted file mode 160000 index 59cb678164..0000000000 --- a/common +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 59cb678164719ff59dcf6c8b93df4617a1075d11 diff --git a/configure.ac b/configure.ac deleted file mode 100644 index a7b8bc0ba3..0000000000 --- a/configure.ac +++ /dev/null @@ -1,768 +0,0 @@ -# gstreamer-vaapi package version number -m4_define([gst_vaapi_major_version], [1]) -m4_define([gst_vaapi_minor_version], [17]) -m4_define([gst_vaapi_micro_version], [0]) -m4_define([gst_vaapi_nano_version], [1]) -m4_define([gst_vaapi_version], - [gst_vaapi_major_version.gst_vaapi_minor_version.gst_vaapi_micro_version]) -m4_if(gst_vaapi_nano_version, [0], [], - [m4_append([gst_vaapi_version], gst_vaapi_nano_version, [.])]) - -# Configure defaults -m4_define([default_glapi], [any]) - -dnl - library source changed -> increment REVISION -dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 -dnl - interfaces added -> increment AGE -dnl - interfaces removed -> AGE = 0 -# gstreamer-vaapi library (libtool) version number -m4_define([gst_vaapi_lt_current], [1700]) -m4_define([gst_vaapi_lt_revision], [0]) -m4_define([gst_vaapi_lt_age], [1700]) - -# glib version number -m4_define([glib_version], [2.44]) - -# gstreamer version number -m4_define([gst_version], [1.17.0.1]) -m4_define([gst_plugins_base_version], [1.17.0.1]) -m4_define([gst_plugins_bad_version], [1.17.0.1]) - -# Wayland minimum version number -m4_define([wayland_api_version], [1.11.0]) - -# VA-API minimum version number -m4_define([va_api_version], [0.39.0]) - -AC_PREREQ([2.69]) -AC_INIT([GStreamer VA-API Plug-ins], [gst_vaapi_version], - [http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer], - [gstreamer-vaapi]) - -dnl define the output header for config -AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_SRCDIR([Makefile.am]) -AC_CONFIG_MACRO_DIR([m4]) -AC_CONFIG_AUX_DIR([build-aux]) - -AG_GST_INIT - -dnl initialize automake -AM_INIT_AUTOMAKE([-Wno-portability 1.14 no-dist-gzip dist-xz tar-ustar subdir-objects]) - -dnl define PACKAGE_VERSION_* variables -AS_VERSION - -dnl check if this is a release version -AS_NANO(GST_GIT="no", GST_GIT="yes") - -dnl AM_MAINTAINER_MODE only provides the option to configure to enable it -AM_MAINTAINER_MODE([enable]) - -dnl use pretty build output by default -AM_SILENT_RULES([yes]) - -dnl our libraries and install dirs use GST_API_VERSION in the filename -dnl to allow side-by-side installation of different API versions -GST_API_VERSION=1.0 -AC_SUBST([GST_API_VERSION]) -AC_DEFINE_UNQUOTED([GST_API_VERSION], ["$GST_API_VERSION"], - [GStreamer API Version]) - -AG_GST_LIBTOOL_PREPARE - -dnl CURRENT, REVISION, AGE -dnl sets GST_LT_LDFLAGS -AS_LIBTOOL(GST, gst_vaapi_lt_current, gst_vaapi_lt_revision, gst_vaapi_lt_age) - -dnl *** required versions of GStreamer stuff *** -GLIB_REQ=glib_version -GST_REQ=gst_version -GST_PBREQ=gst_plugins_base_version -GST_PBADREQ=gst_plugins_bad_version -WAYLAND_REQ=wayland_api_version - -dnl *** required versions of VA-API stuff *** -VAAPI_REQ=va_api_version - -dnl *** autotools stuff **** - -dnl allow for different autotools -AS_AUTOTOOLS_ALTERNATE - -dnl Add parameters for aclocal -AC_SUBST([ACLOCAL_AMFLAGS], ["-I m4 -I common/m4"]) - -dnl *** check for arguments to configure *** - -AG_GST_ARG_DISABLE_FATAL_WARNINGS -AG_GST_ARG_ENABLE_EXTRA_CHECKS -AG_GST_ARG_DEBUG - -AG_GST_ARG_EXAMPLES - -AG_GST_ARG_WITH_PKG_CONFIG_PATH - -AG_GST_SET_PACKAGE_RELEASE_DATETIME_WITH_NANO([$PACKAGE_VERSION_NANO], - ["${srcdir}/gstreamer-vaapi.doap"], - [$PACKAGE_VERSION_MAJOR.$PACKAGE_VERSION_MINOR.$PACKAGE_VERSION_MICRO]) - -AC_ARG_ENABLE([encoders], - AS_HELP_STRING([--enable-encoders], - [enable video encoders @<:@default=yes@:>@]), - [], [enable_encoders="yes"]) - -AC_ARG_ENABLE([drm], - AS_HELP_STRING([--enable-drm], - [enable DRM backend @<:@default=yes@:>@]), - [], [enable_drm="yes"]) - -AC_ARG_ENABLE([x11], - AS_HELP_STRING([--enable-x11], - [enable X11 output @<:@default=yes@:>@]), - [], [enable_x11="yes"]) - -AC_ARG_ENABLE([glx], - AS_HELP_STRING([--enable-glx], - [enable OpenGL/X11 output @<:@default=yes@:>@]), - [], [enable_glx="yes"]) - -AC_ARG_ENABLE([wayland], - AC_HELP_STRING([--enable-wayland], - [enable Wayland output @<:@default=yes@:>@]), - [], [enable_wayland="yes"]) - -AC_ARG_ENABLE([egl], - AS_HELP_STRING([--enable-egl], - [enable EGL output @<:@default=yes@:>@]), - [], [enable_egl="yes"]) - -AC_ARG_WITH([glapi], - AS_HELP_STRING([--with-glapi=APIs], - [build with the specified OpenGL APIs @<:@default=default_glapi@:>@]), - [GLAPI="$with_glapi"], [GLAPI=default_glapi]) - -AC_ARG_WITH([gtk], - [AS_HELP_STRING([--with-gtk], - [compile GTK3 based test apps @<:@default=check@:>@])], - [], [with_gtk="check"]) - -dnl *** checks for platform *** - -dnl * hardware/architecture * - -dnl check CPU type -AG_GST_ARCH - -dnl *** checks for programs *** - -dnl find a compiler -AC_PROG_CC -AC_PROG_CC_STDC - -dnl check if the compiler supports '-c' and '-o' options -AM_PROG_CC_C_O - -dnl *** checks for libraries *** -dnl check for libm, for sin() etc. -AC_CHECK_LIB([m], [tan]) - -dnl Check to see if dlopen/dlsym is in default libraries (like -dnl Solaris, which has it in libc), or if libdl is needed to get it. -AC_CHECK_FUNC([dlopen], [], [ - AC_CHECK_LIB([dl], [dlopen], [DLOPEN_LIBS="-ldl"])]) -AC_SUBST([DLOPEN_LIBS]) - -dnl define LIBDIR so we can inform people where we live -AS_AC_EXPAND([LIBDIR], [$libdir]) -AC_DEFINE_UNQUOTED([LIBDIR], ["$LIBDIR"], [library dir]) - -dnl set location of plugin directory -AG_GST_SET_PLUGINDIR - -dnl *** checks for header files *** - -dnl *** checks for types/defines *** - -dnl *** checks for structures *** - -dnl *** checks for compiler characteristics *** - -dnl *** checks for library functions *** - -dnl *** checks for headers *** - -dnl *** checks for dependency libraries *** - -dnl --------------------------------------------------------------------------- -dnl -- GStreamer -- -dnl --------------------------------------------------------------------------- -dnl GLib is required -AG_GST_GLIB_CHECK([$GLIB_REQ]) - -dnl checks for gstreamer -dnl uninstalled is selected preferentially -- see pkg-config(1) -AG_GST_CHECK_GST([$GST_API_VERSION], [$GST_REQ], [yes]) - -dnl back compatibility -AC_MSG_CHECKING([for GStreamer API version]) -gst_api_version=`$PKG_CONFIG --modversion "gstreamer-$GST_API_VERSION"` -gst_major_version=`echo "$gst_api_version" | cut -d'.' -f1` -gst_minor_version=`echo "$gst_api_version" | cut -d'.' -f2` -GST_VERSION="${gst_major_version}.${gst_minor_version}" -AC_MSG_RESULT([$GST_VERSION]) -AC_DEFINE_UNQUOTED([GST_API_VERSION_S], ["$GST_VERSION"], - [Defined to the string representation of GStreamer version]) - -AG_GST_CHECK_GST_BASE([$GST_API_VERSION], [$GST_REQ], [yes]) -AG_GST_CHECK_GST_PLUGINS_BASE([$GST_API_VERSION], [$GST_PBREQ], [yes]) - -dnl gst_dmabuf_memory_get_fd (gstreamer-allocators) -AG_GST_CHECK_MODULES([GST_ALLOCATORS], - [gstreamer-allocators-$GST_API_VERSION], [$GST_PBREQ], [yes]) - -dnl GstVideoOverlayComposition (gstreamer-video) -AG_GST_CHECK_MODULES([GST_VIDEO], - [gstreamer-video-$GST_API_VERSION], [$GST_PBREQ], [yes]) - -dnl ... GStreamer base utils (gstreamer-pbutils) -AG_GST_CHECK_MODULES([GST_PBUTILS], - [gstreamer-pbutils-$GST_API_VERSION], [$GST_PBREQ], [yes]) - -dnl bitstream parsers (gstreamer-codecparsers) -AG_GST_CHECK_MODULES([GST_CODEC_PARSERS], - [gstreamer-codecparsers-$GST_API_VERSION], [$GST_PBADREQ], [yes]) - -AS_IF([test "x$enable_glx" = "xyes" -o "x$enable_egl" = "xyes"], - [enable_opengl="yes"], [enable_opengl="no"]) - -dnl ... opengl helper libraries -HAVE_GSTGL=0 -if test "x$enable_opengl" = "xyes"; then - PKG_CHECK_MODULES([GST_GL], - [gstreamer-gl-$GST_API_VERSION >= $GST_PBADREQ], - [ - HAVE_GSTGL=1 - AC_CACHE_CHECK([for GStreamer OpenGL helper libraries], - [ac_cv_have_gst_gl_helpers], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GST_GL_CFLAGS $GST_VIDEO_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$saved_LIBS" - AC_CHECK_HEADERS([gst/gl/gl.h], [], [HAVE_GSTGL=0]) - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include - ]], - [[ -GstGLContext gl_context; - ]]) - ], - [ac_cv_have_gst_gl_helpers="yes"], - [ac_cv_have_gst_gl_helpers="no"]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) - ], [:]) -fi -AS_IF([test "x$ac_cv_have_gst_gl_helpers" = "xno"], [HAVE_GSTGL=0]) -AM_CONDITIONAL([USE_GST_GL_HELPERS], [test $HAVE_GSTGL -eq 1]) -AC_DEFINE_UNQUOTED([USE_GST_GL_HELPERS], [$HAVE_GSTGL], - [Defined to 1 if GStreamer OpenGL helper libraries are available]) - -if test "x$enable_egl" = "xyes" -a $HAVE_GSTGL -ne 1; then - AC_MSG_WARN([GStreamer/GL helper libraries not found, disabling EGL support]) - enable_egl="no" -fi - -dnl --------------------------------------------------------------------------- -dnl -- Renderers -- -dnl --------------------------------------------------------------------------- - -dnl Check for DRM/libudev -USE_DRM=0 -if test "x$enable_drm" = "xyes"; then - PKG_CHECK_MODULES([DRM], [libdrm libudev], - [ - USE_DRM=1 - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $DRM_CFLAGS" - AC_CHECK_HEADERS([drm_fourcc.h], [], [USE_DRM=0]) - CPPFLAGS="$saved_CPPFLAGS" - ], [:]) -fi - -dnl Check for X11 -USE_X11=0 -if test "x$enable_x11" = "xyes"; then - PKG_CHECK_MODULES([X11], [x11], - [ - USE_X11=1 - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $X11_CFLAGS" - AC_CHECK_HEADERS([X11/Xlib.h X11/Xutil.h X11/Xatom.h], [], [USE_X11=0]) - CPPFLAGS="$saved_CPPFLAGS" - ], [:]) -fi - -HAVE_XKBLIB=0 -HAVE_XRANDR=0 -HAVE_XRENDER=0 -if test $USE_X11 -eq 1; then - dnl Check for XKB library - HAVE_XKBLIB=1 - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $X11_CFLAGS" - AC_CHECK_HEADERS([X11/XKBlib.h], [], [HAVE_XKBLIB=0]) - CPPFLAGS="$saved_CPPFLAGS" - - dnl Check for XRandR - PKG_CHECK_MODULES([XRANDR], [xrandr], - [ - HAVE_XRANDR=1 - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $XRANDR_CFLAGS" - AC_CHECK_HEADERS([X11/extensions/Xrandr.h], [], [HAVE_XRANDR=0]) - CPPFLAGS="$saved_CPPFLAGS" - ], [:]) - - dnl Check for XRender - PKG_CHECK_MODULES([XRENDER], [xrender], - [ - HAVE_XRENDER=1 - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $XRENDER_CFLAGS" - AC_CHECK_HEADERS([X11/extensions/Xrender.h], [], [HAVE_XRENDER=0]) - CPPFLAGS="$saved_CPPFLAGS" - ], [:]) -fi - -AC_DEFINE_UNQUOTED([HAVE_XKBLIB], [$HAVE_XKBLIB], - [Defined to 1 if the XKB extension exists.]) -AC_DEFINE_UNQUOTED([HAVE_XRANDR], [$HAVE_XRANDR], - [Defined to 1 if the XRandR extension exists.]) -AC_DEFINE_UNQUOTED([HAVE_XRENDER], [$HAVE_XRENDER], - [Defined to 1 if the XRender extension exists.]) - -dnl OpenGL -GLES_VERSION_MASK=0 - -HAVE_GL=0 -HAVE_GLESv2=0 -HAVE_GLESv3=0 -if test "x$enable_opengl" = "xyes"; then - dnl OpenGL - case ",$GLAPI," in - (*,any,*|*,gl,*) - HAVE_GL=1 - PKG_CHECK_MODULES([GL], [gl], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GL_CFLAGS" - AC_CHECK_HEADERS([GL/gl.h GL/glext.h], [], [HAVE_GL=0], - [ -#ifdef HAVE_GL_GL_H -# include -#endif - ]) - CPPFLAGS="$saved_CPPFLAGS" - ], [HAVE_GL=0]) - GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GL "*" 1` - ;; - esac - - dnl OpenGL|ESv2 - case ",$GLAPI," in - (*,any,*|*,gles2,*) - HAVE_GLESv2=1 - PKG_CHECK_MODULES([GLES2], [glesv2], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GLES2_CFLAGS" - AC_CHECK_HEADERS([GLES2/gl2.h GLES2/gl2ext.h], [], [HAVE_GLESv2=0], - [ -#ifdef HAVE_GLES2_GL2_H -# include -#endif - ]) - CPPFLAGS="$saved_CPPFLAGS" - ], [HAVE_GLESv2=0]) - GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GLESv2 "*" 4` - ;; - esac - - dnl OpenGL|ESv3 - case ",$GLAPI," in - (*,any,*|*,gles3,*) - HAVE_GLESv3=1 - PKG_CHECK_MODULES([GLES3], [glesv2], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GLES3_CFLAGS" - AC_CHECK_HEADERS([GLES3/gl3.h GLES3/gl3ext.h GLES2/gl2ext.h], [], - [HAVE_GLESv3=0], - [ -#ifdef HAVE_GLES3_GL3_H -# include -#endif - ]) - CPPFLAGS="$saved_CPPFLAGS" - ], [HAVE_GLESv3=0]) - GLES_VERSION_MASK=`expr $GLES_VERSION_MASK "+" $HAVE_GLESv3 "*" 8` - ;; - esac -fi - -dnl ... GLX -USE_GLX=0 -if test "x$enable_glx" = "xyes" -a $HAVE_GL -eq 1 -a $USE_X11 -eq 1; then - USE_GLX=1 - - saved_CPPFLAGS="$CPPFLAGS" - saved_LIBS="$LIBS" - CPPFLAGS="$CPPFLAGS $GL_CFLAGS" - LIBS="$LIBS $GL_LIBS" - AC_CHECK_HEADERS([GL/glx.h], [], [USE_GLX=0], - [ -#ifdef HAVE_GL_GL_H -# include -#endif - ]) - AC_CHECK_LIB([GL], [glXCreateContext], [], [USE_GLX=0]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" -fi - -dnl ... EGL -USE_EGL=0 -if test "x$enable_egl" = "xyes" -a $GLES_VERSION_MASK -ne 0; then - PKG_CHECK_MODULES([EGL], [egl], - [ - USE_EGL=1 - - saved_CPPFLAGS="$CPPFLAGS" - saved_LIBS="$LIBS" - CPPFLAGS="$CPPFLAGS $EGL_CFLAGS" - LIBS="$LIBS $EGL_LIBS" - AC_CHECK_HEADERS([EGL/egl.h], [], [USE_EGL=0]) - AC_CHECK_LIB([EGL], [eglGetDisplay], [], [USE_EGL=0]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ], [:]) -fi - -dnl Check for Wayland -USE_WAYLAND=0 -if test "x$enable_wayland" = "xyes"; then - PKG_CHECK_MODULES([WAYLAND], [wayland-client >= $WAYLAND_REQ, wayland-protocols >= 1.15], - [ - USE_WAYLAND=1 - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $WAYLAND_CFLAGS" - AC_CHECK_HEADERS([wayland-client.h], [], [USE_WAYLAND=0]) - CPPFLAGS="$saved_CPPFLAGS" - - AC_CHECK_PROGS(WAYLAND_SCANNER, wayland-scanner, [USE_WAYLAND=0]) - - WAYLAND_PROTOCOLS_DATADIR="`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`" - AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, $WAYLAND_PROTOCOLS_DATADIR) - ], [:]) -fi - -dnl Check for GTK for tests -USE_GTK=0 -AS_IF([test "x$BUILD_EXAMPLES" = "xyes" -a $USE_X11 -eq 1], - [AS_CASE([$with_gtk], - [yes], [PKG_CHECK_MODULES([GTK3], [gtk+-3.0], [USE_GTK=1])], - [no], [], - [PKG_CHECK_MODULES([GTK3], [gtk+-3.0], [USE_GTK=1], [USE_GTK=0])])]) -AS_IF([test $USE_GTK -eq 1], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GTK3_CFLAGS" - AC_CHECK_HEADERS([gtk/gtk.h], [], [USE_GTK=0]) - CPPFLAGS="$saved_CPPFLAGS" - ]) -dnl USE_GTK conditional is delayed after being sure to handle X11 - -dnl --------------------------------------------------------------------------- -dnl -- VA-API -- -dnl --------------------------------------------------------------------------- - -dnl Core API -PKG_CHECK_MODULES([LIBVA], [libva >= $VAAPI_REQ libva != 0.99.0]) -VA_VERSION_STR=`$PKG_CONFIG --modversion libva` -VA_DRIVERS_PATH=`$PKG_CONFIG --variable=driverdir libva` -AC_DEFINE_UNQUOTED([VA_DRIVERS_PATH], ["$VA_DRIVERS_PATH"], - [VA drivers path]) - -dnl VA/DRM API -if test $USE_DRM -eq 1; then - PKG_CHECK_MODULES([LIBVA_DRM], [libva-drm >= $VAAPI_REQ], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_DRM_CFLAGS" - AC_CHECK_HEADERS([va/va_drm.h], [], [USE_DRM=0]) - CPPFLAGS="$saved_CPPFLAGS" - ], [USE_DRM=0]) -fi - -dnl VA/X11 API -if test $USE_X11 -eq 1; then - PKG_CHECK_MODULES(LIBVA_X11, [libva-x11 >= $VAAPI_REQ], - [], [ - USE_X11=0 - USE_GLX=0 - ]) -fi - -dnl export USE_GTK after being sure to handle X11 -AM_CONDITIONAL([USE_GTK], [test $USE_X11 -eq 1 -a $USE_GTK -eq 1]) - -dnl Check for encoding support -USE_ENCODERS=0 -if test "x$enable_encoders" = "xyes"; then - USE_ENCODERS=1 -fi - -USE_VP9_ENCODER=0 -USE_H264_FEI_ENCODER=0 - -if test $USE_ENCODERS -eq 1; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - - dnl Check for VP9 Encoding API (0.39.1+) - AC_CHECK_HEADERS([va/va_enc_vp9.h], [], [], - [ -#include - ]) - AC_CACHE_CHECK([for VP9 encoding API], - [ac_cv_have_vp9_encoding_api], - [ - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include -#ifdef HAVE_VA_VA_ENC_VP9_H -# include -#endif - ]], - [[ -VAEncSequenceParameterBufferVP9 seq_param; -VAEncPictureParameterBufferVP9 pic_param; -VAEncSegParamVP9 seg_param; -VAEncMiscParameterTypeVP9PerSegmantParam misc_param; - ]]) - ], - [ac_cv_have_vp9_encoding_api="yes"], - [ac_cv_have_vp9_encoding_api="no"]) - LIBS="$saved_LIBS" - ]) - AS_IF([test "x$ac_cv_have_vp9_encoding_api" = "xyes"], [USE_VP9_ENCODER=1]) - - dnl Check for H264 FEI Encoding API - AC_CHECK_HEADERS([va/va_fei_h264.h], [], [], - [ -#include - ]) - AC_CACHE_CHECK([for H264_FEI encoding API], - [ac_cv_have_h264_fei_encoding_api], - [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS" - saved_LIBS="$LIBS" - LIBS="$LIBS $LIBVA_LIBS" - AC_COMPILE_IFELSE( - [ - AC_LANG_PROGRAM( - [[ -#include -#ifdef HAVE_VA_VA_FEI_H264_H -# include -#endif - ]], - [[ -VAEncMiscParameterFEIFrameControlH264 framectl; -VAEncFEIMBControlH264 mbcntrl; -VAEncFEIMVPredictorH264 mvpred; -VAEncFEIMBCodeH264 mbcode; -VAEncFEIDistortionH264 dist; - ]]) - ], - [ac_cv_have_h264_fei_encoding_api="yes"], - [ac_cv_have_h264_fei_encoding_api="no"]) - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - ]) - AS_IF([test "x$ac_cv_have_h264_fei_encoding_api" = "xyes"], [USE_H264_FEI_ENCODER=1]) - CPPFLAGS="$saved_CPPFLAGS" -fi - -dnl VA/Wayland API -if test $USE_WAYLAND -eq 1; then - PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva-wayland >= $VAAPI_REQ], - [], [USE_WAYLAND=0]) -fi - -dnl *** finalize CFLAGS, LDFLAGS, LIBS - -# set by AG_GST_PARSE_SUBSYSTEM_DISABLES above -dnl make sure it doesn't complain about unused variables if debugging is disabled -AG_GST_CHECK_GST_DEBUG_DISABLED([NO_WARNINGS="-Wno-unused"], [NO_WARNINGS=""]) - -dnl define an ERROR_CFLAGS Makefile variable -dnl FIXME Add -Wredundant-decls again if considered useful and warnings are fixed -AG_GST_SET_ERROR_CFLAGS([$FATAL_WARNINGS], [-Wmissing-declarations -Wmissing-prototypes -Wwrite-strings -Wformat-security -Wold-style-definition -Winit-self -Wmissing-include-dirs -Waddress -Wno-multichar -Wnested-externs $NO_WARNINGS]) - -dnl define correct level for debugging messages -AG_GST_SET_LEVEL_DEFAULT([$GST_GIT]) - -dnl Overview: -dnl GST_OPTION_CFLAGS: common flags for profiling, debugging, errors, ... -dnl GST_*: flags shared by built objects to link against GStreamer -dnl GST_ALL_LDFLAGS: linker flags shared by all -dnl GST_LIB_LDFLAGS: additional linker flags for all libaries -dnl GST_LT_LDFLAGS: library versioning of our libraries -dnl GST_PLUGIN_LDFLAGS: flags to be used for all plugins - -dnl GST_OPTION_CFLAGS -if test "x$USE_DEBUG" = xyes; then - PROFILE_CFLAGS="-g" -fi -AC_SUBST([PROFILE_CFLAGS]) - -if test "x$GST_GIT" = "xyes"; then - DEPRECATED_CFLAGS="-DGST_DISABLE_DEPRECATED" -else - DEPRECATED_CFLAGS="" -fi -AC_SUBST([DEPRECATED_CFLAGS]) - -dnl disable strict aliasing -AS_COMPILER_FLAG([-fno-strict-aliasing], [EXTRA_CFLAGS="-fno-strict-aliasing"]) -AC_SUBST(EXTRA_CFLAGS) - -dnl every flag in GST_OPTION_CFLAGS and GST_OPTION_CXXFLAGS can be overridden -dnl at make time with e.g. make ERROR_CFLAGS="" -GST_OPTION_CFLAGS="\$(WARNING_CFLAGS) \$(ERROR_CFLAGS) \$(DEBUG_CFLAGS) \$(PROFILE_CFLAGS) \$(DEPRECATED_CFLAGS)" -AC_SUBST([GST_OPTION_CFLAGS]) - -dnl FIXME: do we want to rename to GST_ALL_* ? -dnl prefer internal headers to already installed ones -dnl also add builddir include for enumtypes and marshal -dnl add GST_OPTION_CFLAGS, but overridable -GST_CFLAGS="$GST_CFLAGS -DGST_USE_UNSTABLE_API" -GST_CFLAGS="$GST_CFLAGS $EXTRA_CFLAGS $GLIB_EXTRA_CFLAGS \$(GST_OPTION_CFLAGS)" -AC_SUBST([GST_CFLAGS]) - -dnl LDFLAGS really should only contain flags, not libs - they get added before -dnl whatevertarget_LIBS and -L flags here affect the rest of the linking -GST_ALL_LDFLAGS="-no-undefined" -if test "x${enable_Bsymbolic}" = "xyes"; then - GST_ALL_LDFLAGS="$GST_ALL_LDFLAGS -Wl,-Bsymbolic-functions" -fi -AC_SUBST([GST_ALL_LDFLAGS]) - -dnl GST_LIB_LDFLAGS -dnl linker flags shared by all libraries -dnl LDFLAGS modifier defining exported symbols from built libraries -dnl (export _gst_foo but not __gst_foo) -GST_LIB_LDFLAGS="-export-symbols-regex ^_?\(gst_\|Gst\|GST_\).*" -AC_SUBST([GST_LIB_LDFLAGS]) - -dnl this really should only contain flags, not libs - they get added before -dnl whatevertarget_LIBS and -L flags here affect the rest of the linking -GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^[_]*gst_plugin_.*' $GST_ALL_LDFLAGS" -AC_SUBST([GST_PLUGIN_LDFLAGS]) - -dnl --------------------------------------------------------------------------- -dnl -- Generate files and summary -- -dnl --------------------------------------------------------------------------- - -case ":$USE_X11:$USE_GLX:$USE_EGL:$USE_WAYLAND:$USE_DRM:" in -*:1:*) ;; -*) AC_MSG_ERROR([No renderer is enabled]) ;; -esac - -AC_DEFINE_UNQUOTED([USE_ENCODERS], [$USE_ENCODERS], - [Defined to 1 if video encoders are used]) -AM_CONDITIONAL([USE_ENCODERS], [test $USE_ENCODERS -eq 1]) - -AC_DEFINE_UNQUOTED([USE_VP9_ENCODER], [$USE_VP9_ENCODER], - [Defined to 1 if VP9 encoder is used]) -AM_CONDITIONAL([USE_VP9_ENCODER], [test $USE_VP9_ENCODER -eq 1]) - -AC_DEFINE_UNQUOTED([USE_H264_FEI_ENCODER], [$USE_H264_FEI_ENCODER], - [Defined to 1 if H264_FEI encoder is used]) -AM_CONDITIONAL([USE_H264_FEI_ENCODER], [test $USE_H264_FEI_ENCODER -eq 1]) - -AC_DEFINE_UNQUOTED([USE_DRM], [$USE_DRM], - [Defined to 1 if DRM is enabled]) -AM_CONDITIONAL([USE_DRM], [test $USE_DRM -eq 1]) - -AC_DEFINE_UNQUOTED([USE_X11], [$USE_X11], - [Defined to 1 if X11 is enabled]) -AM_CONDITIONAL([USE_X11], [test $USE_X11 -eq 1]) - -AC_DEFINE_UNQUOTED([USE_GLX], [$USE_GLX], - [Defined to 1 if GLX is enabled]) -AM_CONDITIONAL([USE_GLX], [test $USE_GLX -eq 1]) - -AC_DEFINE_UNQUOTED([USE_EGL], [$USE_EGL], - [Defined to 1 if EGL is enabled]) -AM_CONDITIONAL([USE_EGL], [test $USE_EGL -eq 1]) - -AC_DEFINE_UNQUOTED([USE_GLES_VERSION_MASK], [$GLES_VERSION_MASK], - [Defined to the set of enabled OpenGL ES APIs]) - -AC_DEFINE_UNQUOTED([USE_WAYLAND], [$USE_WAYLAND], - [Defined to 1 if WAYLAND is enabled]) -AM_CONDITIONAL([USE_WAYLAND], [test $USE_WAYLAND -eq 1]) - -dnl @TODO hack for egl's dynamic module loading. remove it! -AC_DEFINE_UNQUOTED([GST_VAAPI_MAJOR_VERSION_S], ["0"], - [Defined to the string representation of gstreamer-vaapi major version]) - -AC_CONFIG_FILES([ - Makefile - common/Makefile - common/m4/Makefile - m4/Makefile - gst-libs/Makefile - gst-libs/gst/Makefile - gst-libs/gst/vaapi/Makefile - gst/Makefile - gst/vaapi/Makefile - tests/Makefile - tests/elements/Makefile -]) -AC_OUTPUT - -dnl Print summary -yesno() { - test $1 -eq 1 && echo yes || echo no -} - -VIDEO_OUTPUTS="" -AS_IF([test $USE_DRM -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS drm"]) -AS_IF([test $USE_X11 -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS x11"]) -AS_IF([test $USE_GLX -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS glx"]) -AS_IF([test $USE_EGL -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS egl"]) -AS_IF([test $USE_WAYLAND -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS wayland"]) - -echo -echo $PACKAGE configuration summary: -echo -echo Installation Prefix .............. : ${prefix} -echo GStreamer API version ............ : $GST_VERSION -echo VA-API version ................... : $VA_VERSION_STR -echo Video encoding ................... : $(yesno $USE_ENCODERS) -echo Video outputs .................... : $VIDEO_OUTPUTS -echo diff --git a/git.mk b/git.mk deleted file mode 100644 index 643c2ca9ae..0000000000 --- a/git.mk +++ /dev/null @@ -1,348 +0,0 @@ -# git.mk, a small Makefile to autogenerate .gitignore files -# for autotools-based projects. -# -# Copyright 2009, Red Hat, Inc. -# Copyright 2010,2011,2012,2013 Behdad Esfahbod -# Written by Behdad Esfahbod -# -# Copying and distribution of this file, with or without modification, -# is permitted in any medium without royalty provided the copyright -# notice and this notice are preserved. -# -# The latest version of this file can be downloaded from: -GIT_MK_URL = https://raw.githubusercontent.com/behdad/git.mk/master/git.mk -# -# Bugs, etc, should be reported upstream at: -# https://github.com/behdad/git.mk -# -# To use in your project, import this file in your git repo's toplevel, -# then do "make -f git.mk". This modifies all Makefile.am files in -# your project to -include git.mk. Remember to add that line to new -# Makefile.am files you create in your project, or just rerun the -# "make -f git.mk". -# -# This enables automatic .gitignore generation. If you need to ignore -# more files, add them to the GITIGNOREFILES variable in your Makefile.am. -# But think twice before doing that. If a file has to be in .gitignore, -# chances are very high that it's a generated file and should be in one -# of MOSTLYCLEANFILES, CLEANFILES, DISTCLEANFILES, or MAINTAINERCLEANFILES. -# -# The only case that you need to manually add a file to GITIGNOREFILES is -# when remove files in one of mostlyclean-local, clean-local, distclean-local, -# or maintainer-clean-local make targets. -# -# Note that for files like editor backup, etc, there are better places to -# ignore them. See "man gitignore". -# -# If "make maintainer-clean" removes the files but they are not recognized -# by this script (that is, if "git status" shows untracked files still), send -# me the output of "git status" as well as your Makefile.am and Makefile for -# the directories involved and I'll diagnose. -# -# For a list of toplevel files that should be in MAINTAINERCLEANFILES, see -# Makefile.am.sample in the git.mk git repo. -# -# Don't EXTRA_DIST this file. It is supposed to only live in git clones, -# not tarballs. It serves no useful purpose in tarballs and clutters the -# build dir. -# -# This file knows how to handle autoconf, automake, libtool, gtk-doc, -# gnome-doc-utils, yelp.m4, mallard, intltool, gsettings, dejagnu, appdata, -# appstream. -# -# This makefile provides the following targets: -# -# - all: "make all" will build all gitignore files. -# - gitignore: makes all gitignore files in the current dir and subdirs. -# - .gitignore: make gitignore file for the current dir. -# - gitignore-recurse: makes all gitignore files in the subdirs. -# -# KNOWN ISSUES: -# -# - Recursive configure doesn't work as $(top_srcdir)/git.mk inside the -# submodule doesn't find us. If you have configure.{in,ac} files in -# subdirs, add a proxy git.mk file in those dirs that simply does: -# "include $(top_srcdir)/../git.mk". Add more ..'s to your taste. -# And add those files to git. See vte/gnome-pty-helper/git.mk for -# example. -# - - - -############################################################################### -# Variables user modules may want to add to toplevel MAINTAINERCLEANFILES: -############################################################################### - -# -# Most autotools-using modules should be fine including this variable in their -# toplevel MAINTAINERCLEANFILES: -GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL = \ - $(srcdir)/aclocal.m4 \ - $(srcdir)/autoscan.log \ - $(srcdir)/configure.scan \ - `AUX_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_AUX_DIR:$$1' ./configure.ac); \ - test "x$$AUX_DIR" = "x$(srcdir)/" && AUX_DIR=$(srcdir); \ - for x in \ - ar-lib \ - compile \ - config.guess \ - config.sub \ - depcomp \ - install-sh \ - ltmain.sh \ - missing \ - mkinstalldirs \ - test-driver \ - ylwrap \ - ; do echo "$$AUX_DIR/$$x"; done` \ - `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_HEADERS:$$1' ./configure.ac | \ - head -n 1 | while read f; do echo "$(srcdir)/$$f.in"; done` -# -# All modules should also be fine including the following variable, which -# removes automake-generated Makefile.in files: -GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN = \ - `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_FILES:$$1' ./configure.ac | \ - while read f; do \ - case $$f in Makefile|*/Makefile) \ - test -f "$(srcdir)/$$f.am" && echo "$(srcdir)/$$f.in";; esac; \ - done` -# -# Modules that use libtool and use AC_CONFIG_MACRO_DIR() may also include this, -# though it's harmless to include regardless. -GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL = \ - `MACRO_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_MACRO_DIR:$$1' ./configure.ac); \ - if test "x$$MACRO_DIR" != "x$(srcdir)/"; then \ - for x in \ - libtool.m4 \ - ltoptions.m4 \ - ltsugar.m4 \ - ltversion.m4 \ - lt~obsolete.m4 \ - ; do echo "$$MACRO_DIR/$$x"; done; \ - fi` - - - -############################################################################### -# Default rule is to install ourselves in all Makefile.am files: -############################################################################### - -git-all: git-mk-install - -git-mk-install: - @echo "Installing git makefile" - @any_failed=; \ - find "`test -z "$(top_srcdir)" && echo . || echo "$(top_srcdir)"`" -name Makefile.am | while read x; do \ - if grep 'include .*/git.mk' $$x >/dev/null; then \ - echo "$$x already includes git.mk"; \ - else \ - failed=; \ - echo "Updating $$x"; \ - { cat $$x; \ - echo ''; \ - echo '-include $$(top_srcdir)/git.mk'; \ - } > $$x.tmp || failed=1; \ - if test x$$failed = x; then \ - mv $$x.tmp $$x || failed=1; \ - fi; \ - if test x$$failed = x; then : else \ - echo "Failed updating $$x"; >&2 \ - any_failed=1; \ - fi; \ - fi; done; test -z "$$any_failed" - -git-mk-update: - wget $(GIT_MK_URL) -O $(top_srcdir)/git.mk - -.PHONY: git-all git-mk-install git-mk-update - - - -############################################################################### -# Actual .gitignore generation: -############################################################################### - -$(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk - @echo "git.mk: Generating $@" - @{ \ - if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \ - for x in \ - $(DOC_MODULE)-decl-list.txt \ - $(DOC_MODULE)-decl.txt \ - tmpl/$(DOC_MODULE)-unused.sgml \ - "tmpl/*.bak" \ - $(REPORT_FILES) \ - $(DOC_MODULE).pdf \ - xml html \ - ; do echo "/$$x"; done; \ - FLAVOR=$$(cd $(top_srcdir); $(AUTOCONF) --trace 'GTK_DOC_CHECK:$$2' ./configure.ac); \ - case $$FLAVOR in *no-tmpl*) echo /tmpl;; esac; \ - if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-types"; then \ - echo "/$(DOC_MODULE).types"; \ - fi; \ - if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-sections"; then \ - echo "/$(DOC_MODULE)-sections.txt"; \ - fi; \ - if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ - for x in \ - $(SETUP_FILES) \ - $(DOC_MODULE).types \ - ; do echo "/$$x"; done; \ - fi; \ - fi; \ - if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \ - for lc in $(DOC_LINGUAS); do \ - for x in \ - $(if $(DOC_MODULE),$(DOC_MODULE).xml) \ - $(DOC_PAGES) \ - $(DOC_INCLUDES) \ - ; do echo "/$$lc/$$x"; done; \ - done; \ - for x in \ - $(_DOC_OMF_ALL) \ - $(_DOC_DSK_ALL) \ - $(_DOC_HTML_ALL) \ - $(_DOC_MOFILES) \ - $(DOC_H_FILE) \ - "*/.xml2po.mo" \ - "*/*.omf.out" \ - ; do echo /$$x; done; \ - fi; \ - if test "x$(HELP_ID)" = x -o "x$(HELP_LINGUAS)" = x; then :; else \ - for lc in $(HELP_LINGUAS); do \ - for x in \ - $(HELP_FILES) \ - "$$lc.stamp" \ - "$$lc.mo" \ - ; do echo "/$$lc/$$x"; done; \ - done; \ - fi; \ - if test "x$(gsettings_SCHEMAS)" = x; then :; else \ - for x in \ - $(gsettings_SCHEMAS:.xml=.valid) \ - $(gsettings__enum_file) \ - ; do echo "/$$x"; done; \ - fi; \ - if test "x$(appdata_XML)" = x; then :; else \ - for x in \ - $(appdata_XML:.xml=.valid) \ - ; do echo "/$$x"; done; \ - fi; \ - if test "x$(appstream_XML)" = x; then :; else \ - for x in \ - $(appstream_XML:.xml=.valid) \ - ; do echo "/$$x"; done; \ - fi; \ - if test -f $(srcdir)/po/Makefile.in.in; then \ - for x in \ - po/Makefile.in.in \ - po/Makefile.in.in~ \ - po/Makefile.in \ - po/Makefile \ - po/Makevars.template \ - po/POTFILES \ - po/Rules-quot \ - po/stamp-it \ - po/stamp-po \ - po/.intltool-merge-cache \ - "po/*.gmo" \ - "po/*.header" \ - "po/*.mo" \ - "po/*.sed" \ - "po/*.sin" \ - po/$(GETTEXT_PACKAGE).pot \ - intltool-extract.in \ - intltool-merge.in \ - intltool-update.in \ - ; do echo "/$$x"; done; \ - fi; \ - if test -f $(srcdir)/configure; then \ - for x in \ - autom4te.cache \ - configure \ - config.h \ - stamp-h1 \ - libtool \ - config.lt \ - ; do echo "/$$x"; done; \ - fi; \ - if test "x$(DEJATOOL)" = x; then :; else \ - for x in \ - $(DEJATOOL) \ - ; do echo "/$$x.sum"; echo "/$$x.log"; done; \ - echo /site.exp; \ - fi; \ - if test "x$(am__dirstamp)" = x; then :; else \ - echo "$(am__dirstamp)"; \ - fi; \ - if test "x$(findstring libtool,$(LTCOMPILE))" = x -a "x$(findstring libtool,$(LTCXXCOMPILE))" = x -a "x$(GTKDOC_RUN)" = x; then :; else \ - for x in \ - "*.lo" \ - ".libs" "_libs" \ - ; do echo "$$x"; done; \ - fi; \ - for x in \ - .gitignore \ - $(GITIGNOREFILES) \ - $(CLEANFILES) \ - $(PROGRAMS) $(check_PROGRAMS) $(EXTRA_PROGRAMS) \ - $(LIBRARIES) $(check_LIBRARIES) $(EXTRA_LIBRARIES) \ - $(LTLIBRARIES) $(check_LTLIBRARIES) $(EXTRA_LTLIBRARIES) \ - so_locations \ - $(MOSTLYCLEANFILES) \ - $(TEST_LOGS) \ - $(TEST_LOGS:.log=.trs) \ - $(TEST_SUITE_LOG) \ - $(TESTS:=.test) \ - "*.gcda" \ - "*.gcno" \ - $(DISTCLEANFILES) \ - $(am__CONFIG_DISTCLEAN_FILES) \ - $(CONFIG_CLEAN_FILES) \ - TAGS ID GTAGS GRTAGS GSYMS GPATH tags \ - "*.tab.c" \ - $(MAINTAINERCLEANFILES) \ - $(BUILT_SOURCES) \ - $(patsubst %.vala,%.c,$(filter %.vala,$(SOURCES))) \ - $(filter %_vala.stamp,$(DIST_COMMON)) \ - $(filter %.vapi,$(DIST_COMMON)) \ - $(filter $(addprefix %,$(notdir $(patsubst %.vapi,%.h,$(filter %.vapi,$(DIST_COMMON))))),$(DIST_COMMON)) \ - Makefile \ - Makefile.in \ - "*.orig" \ - "*.rej" \ - "*.bak" \ - "*~" \ - ".*.sw[nop]" \ - ".dirstamp" \ - ; do echo "/$$x"; done; \ - for x in \ - "*.$(OBJEXT)" \ - $(DEPDIR) \ - ; do echo "$$x"; done; \ - } | \ - sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \ - sed 's@/[.]/@/@g' | \ - LC_ALL=C sort | uniq > $@.tmp && \ - mv $@.tmp $@; - -all: $(srcdir)/.gitignore gitignore-recurse-maybe -gitignore: $(srcdir)/.gitignore gitignore-recurse - -gitignore-recurse-maybe: - @for subdir in $(DIST_SUBDIRS); do \ - case " $(SUBDIRS) " in \ - *" $$subdir "*) :;; \ - *) test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir");; \ - esac; \ - done -gitignore-recurse: - @for subdir in $(DIST_SUBDIRS); do \ - test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir"); \ - done - -maintainer-clean: gitignore-clean -gitignore-clean: - -rm -f $(srcdir)/.gitignore - -.PHONY: gitignore-clean gitignore gitignore-recurse gitignore-recurse-maybe diff --git a/gst-libs/Makefile.am b/gst-libs/Makefile.am deleted file mode 100644 index 85cb878323..0000000000 --- a/gst-libs/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = gst - --include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am deleted file mode 100644 index 80a5198af9..0000000000 --- a/gst-libs/gst/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = vaapi - --include $(top_srcdir)/git.mk diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am deleted file mode 100644 index 9c76c24ef7..0000000000 --- a/gst-libs/gst/vaapi/Makefile.am +++ /dev/null @@ -1,545 +0,0 @@ -noinst_LTLIBRARIES = libgstvaapi.la - -if USE_DRM -noinst_LTLIBRARIES += libgstvaapi-drm.la -endif - -if USE_X11 -noinst_LTLIBRARIES += libgstvaapi-x11.la -endif - -if USE_GLX -noinst_LTLIBRARIES += libgstvaapi-glx.la -endif - -if USE_EGL -noinst_LTLIBRARIES += libgstvaapi-egl.la -endif - -if USE_WAYLAND -noinst_LTLIBRARIES += libgstvaapi-wayland.la -endif - -libgstvaapi_cflags = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - -I$(top_builddir)/gst-libs \ - $(GST_BASE_CFLAGS) \ - $(GST_BASEVIDEO_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(GST_CFLAGS) \ - $(GST_CODEC_PARSERS_CFLAGS) \ - $(LIBVA_CFLAGS) \ - $(NULL) - -libgstvaapi_libs = \ - $(GST_BASE_LIBS) \ - $(GST_BASEVIDEO_LIBS) \ - $(GST_LIBS) \ - $(GST_VIDEO_LIBS) \ - $(GST_CODEC_PARSERS_LIBS) \ - $(LIBVA_LIBS) \ - $(NULL) - -libgstvaapi_source_c = \ - gstvaapibufferproxy.c \ - gstvaapicodec_objects.c \ - gstvaapicontext.c \ - gstvaapidecoder.c \ - gstvaapidecoder_dpb.c \ - gstvaapidecoder_h264.c \ - gstvaapidecoder_mpeg2.c \ - gstvaapidecoder_mpeg4.c \ - gstvaapidecoder_objects.c \ - gstvaapidecoder_unit.c \ - gstvaapidecoder_vc1.c \ - gstvaapidisplay.c \ - gstvaapifilter.c \ - gstvaapiimage.c \ - gstvaapiimagepool.c \ - gstvaapiminiobject.c \ - gstvaapiobject.c \ - gstvaapiparser_frame.c \ - gstvaapipixmap.c \ - gstvaapiprofile.c \ - gstvaapiprofilecaps.c \ - gstvaapisubpicture.c \ - gstvaapisurface.c \ - gstvaapisurface_drm.c \ - gstvaapisurfacepool.c \ - gstvaapisurfaceproxy.c \ - gstvaapitexture.c \ - gstvaapitexturemap.c \ - gstvaapiutils.c \ - gstvaapiutils_core.c \ - gstvaapiutils_h264.c \ - gstvaapiutils_h265.c \ - gstvaapiutils_h26x.c \ - gstvaapiutils_mpeg2.c \ - gstvaapivalue.c \ - gstvaapivideopool.c \ - gstvaapiwindow.c \ - video-format.c \ - $(NULL) - -libgstvaapi_source_h = \ - gstvaapibufferproxy.h \ - gstvaapidecoder.h \ - gstvaapidecoder_h264.h \ - gstvaapidecoder_h265.h \ - gstvaapidecoder_mpeg2.h \ - gstvaapidecoder_mpeg4.h \ - gstvaapidecoder_vc1.h \ - gstvaapidisplay.h \ - gstvaapifilter.h \ - gstvaapiimage.h \ - gstvaapiimagepool.h \ - gstvaapiobject.h \ - gstvaapipixmap.h \ - gstvaapiprofile.h \ - gstvaapiprofilecaps.h \ - gstvaapisubpicture.h \ - gstvaapisurface.h \ - gstvaapisurface_drm.h \ - gstvaapisurfacepool.h \ - gstvaapisurfaceproxy.h \ - gstvaapitexture.h \ - gstvaapitexturemap.h \ - gstvaapitypes.h \ - gstvaapiutils_h264.h \ - gstvaapiutils_h265.h \ - gstvaapiutils_mpeg2.h \ - gstvaapivalue.h \ - gstvaapivideopool.h \ - gstvaapiwindow.h \ - video-format.h \ - $(NULL) - -libgstvaapi_source_priv_h = \ - gstvaapibufferproxy_priv.h \ - gstvaapicodec_objects.h \ - gstvaapicompat.h \ - gstvaapicontext.h \ - gstvaapidebug.h \ - gstvaapidecoder_dpb.h \ - gstvaapidecoder_objects.h \ - gstvaapidecoder_priv.h \ - gstvaapidecoder_unit.h \ - gstvaapidisplay_priv.h \ - gstvaapiimage_priv.h \ - gstvaapiminiobject.h \ - gstvaapiobject_priv.h \ - gstvaapiparser_frame.h \ - gstvaapipixmap_priv.h \ - gstvaapisurface_priv.h \ - gstvaapisurfaceproxy_priv.h \ - gstvaapitexture_priv.h \ - gstvaapiutils.h \ - gstvaapiutils_core.h \ - gstvaapiutils_h264_priv.h \ - gstvaapiutils_h265_priv.h \ - gstvaapiutils_h26x_priv.h \ - gstvaapiutils_mpeg2_priv.h \ - gstvaapivideopool_priv.h \ - gstvaapiwindow_priv.h \ - gstvaapiworkarounds.h \ - sysdeps.h \ - $(NULL) - -libgstvaapi_jpegdec_source_c = gstvaapidecoder_jpeg.c -libgstvaapi_jpegdec_source_h = gstvaapidecoder_jpeg.h -libgstvaapi_source_c += $(libgstvaapi_jpegdec_source_c) -libgstvaapi_source_h += $(libgstvaapi_jpegdec_source_h) - -libgstvaapi_vp8dec_source_c = gstvaapidecoder_vp8.c -libgstvaapi_vp8dec_source_h = gstvaapidecoder_vp8.h -libgstvaapi_source_c += $(libgstvaapi_vp8dec_source_c) -libgstvaapi_source_h += $(libgstvaapi_vp8dec_source_h) - -libgstvaapi_hevcdec_source_c = gstvaapidecoder_h265.c -libgstvaapi_hevcdec_source_h = gstvaapidecoder_h265.h -libgstvaapi_source_c += $(libgstvaapi_hevcdec_source_c) -libgstvaapi_source_h += $(libgstvaapi_hevcdec_source_h) - -libgstvaapi_vp9dec_source_c = gstvaapidecoder_vp9.c -libgstvaapi_vp9dec_source_h = gstvaapidecoder_vp9.h -libgstvaapi_source_c += $(libgstvaapi_vp9dec_source_c) -libgstvaapi_source_h += $(libgstvaapi_vp9dec_source_h) - -libgstvaapi_enc_source_c = \ - gstvaapicodedbuffer.c \ - gstvaapicodedbufferpool.c \ - gstvaapicodedbufferproxy.c \ - gstvaapiencoder.c \ - gstvaapiencoder_h264.c \ - gstvaapiencoder_h265.c \ - gstvaapiencoder_jpeg.c \ - gstvaapiencoder_mpeg2.c \ - gstvaapiencoder_objects.c \ - gstvaapiencoder_vp8.c \ - $(NULL) - -libgstvaapi_enc_source_h = \ - gstvaapicodedbuffer.h \ - gstvaapicodedbufferpool.h \ - gstvaapicodedbufferproxy.h \ - gstvaapiencoder.h \ - gstvaapiencoder_h264.h \ - gstvaapiencoder_h265.h \ - gstvaapiencoder_jpeg.h \ - gstvaapiencoder_mpeg2.h \ - gstvaapiencoder_vp8.h \ - $(NULL) - -libgstvaapi_enc_source_priv_h = \ - gstvaapicodedbuffer_priv.h \ - gstvaapicodedbufferproxy_priv.h \ - gstvaapiencoder_mpeg2_priv.h \ - gstvaapiencoder_objects.h \ - gstvaapiencoder_priv.h \ - $(NULL) - -if USE_ENCODERS -libgstvaapi_source_c += $(libgstvaapi_enc_source_c) -libgstvaapi_source_h += $(libgstvaapi_enc_source_h) -libgstvaapi_source_priv_h += $(libgstvaapi_enc_source_priv_h) -endif - -libgstvaapi_vp9enc_source_c = gstvaapiencoder_vp9.c -libgstvaapi_vp9enc_source_h = gstvaapiencoder_vp9.h -if USE_VP9_ENCODER -libgstvaapi_source_c += $(libgstvaapi_vp9enc_source_c) -libgstvaapi_source_h += $(libgstvaapi_vp9enc_source_h) -endif - -libgstvaapi_h264feienc_source_c = \ - gstvaapifeiutils_h264.c \ - gstvaapifei_objects.c \ - gstvaapifeienc_h264.c \ - gstvaapifeipak_h264.c \ - gstvaapiencoder_h264_fei.c \ - $(NULL) -libgstvaapi_h264feienc_source_h = \ - gstvaapifeiutils_h264.h \ - gstvaapifei_objects.h \ - gstvaapifeienc_h264.h \ - gstvaapifeipak_h264.h \ - gstvaapiencoder_h264_fei.h \ - $(NULL) -libgstvaapi_h264feienc_source_priv_h = \ - gstvaapifei_objects_priv.h \ - $(NULL) -if USE_H264_FEI_ENCODER -libgstvaapi_source_c += $(libgstvaapi_h264feienc_source_c) -libgstvaapi_source_h += $(libgstvaapi_h264feienc_source_h) -libgstvaapi_source_priv_h += $(libgstvaapi_h264feienc_source_priv_h) -endif - -libgstvaapi_drm_source_c = \ - gstvaapidisplay_drm.c \ - gstvaapiwindow_drm.c \ - $(NULL) - -libgstvaapi_drm_source_h = \ - gstvaapidisplay_drm.h \ - gstvaapiwindow_drm.h \ - $(NULL) - -libgstvaapi_drm_source_priv_h = \ - gstvaapicompat.h \ - gstvaapidisplay_drm_priv.h \ - $(NULL) - -libgstvaapi_x11_source_c = \ - gstvaapidisplay_x11.c \ - gstvaapipixmap_x11.c \ - gstvaapiutils_x11.c \ - gstvaapiwindow_x11.c \ - $(NULL) - -libgstvaapi_x11_source_h = \ - gstvaapidisplay_x11.h \ - gstvaapipixmap_x11.h \ - gstvaapiwindow_x11.h \ - $(NULL) - -libgstvaapi_x11_source_priv_h = \ - gstvaapicompat.h \ - gstvaapidisplay_x11_priv.h \ - gstvaapiutils_x11.h \ - gstvaapiwindow_x11_priv.h \ - $(NULL) - -libgstvaapi_glx_source_c = \ - gstvaapidisplay_glx.c \ - gstvaapitexture_glx.c \ - gstvaapiutils_glx.c \ - gstvaapiwindow_glx.c \ - $(NULL) - -libgstvaapi_glx_source_h = \ - gstvaapidisplay_glx.h \ - gstvaapitexture.h \ - gstvaapitexture_glx.h \ - gstvaapiwindow_glx.h \ - $(NULL) - -libgstvaapi_glx_source_priv_h = \ - gstvaapicompat.h \ - gstvaapidisplay_glx_priv.h \ - gstvaapiutils.h \ - gstvaapiutils_glx.h \ - $(NULL) - -libgstvaapi_egl_source_c = \ - gstvaapidisplay_egl.c \ - gstvaapisurface_egl.c \ - gstvaapitexture_egl.c \ - gstvaapiutils_egl.c \ - gstvaapiwindow_egl.c \ - $(NULL) - -libgstvaapi_egl_source_h = \ - gstvaapidisplay_egl.h \ - gstvaapisurface_egl.h \ - gstvaapitexture_egl.h \ - gstvaapiwindow_egl.h \ - $(NULL) - -libgstvaapi_egl_source_priv_h = \ - egl_compat.h \ - egl_vtable.h \ - gstvaapidisplay_egl_priv.h \ - gstvaapiutils_egl.h \ - ogl_compat.h \ - $(NULL) - -BUILT_SOURCES= -CLEANFILES= - -# Generate the necessary files for XDG-shell -if USE_WAYLAND -xdg_shell_protocol_spec = $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml -xdg_shell_header = xdg-shell-client-protocol.h -xdg_shell_source = xdg-shell-client-protocol.c - -$(xdg_shell_header): $(xdg_shell_protocol_spec) - $(AM_V_GEN) $(WAYLAND_SCANNER) client-header < $< > $@ -$(xdg_shell_source): $(xdg_shell_protocol_spec) - $(AM_V_GEN) $(WAYLAND_SCANNER) private-code < $< > $@ - -BUILT_SOURCES += $(xdg_shell_header) $(xdg_shell_source) -CLEANFILES += $(BUILT_SOURCES) -endif - -libgstvaapi_wayland_source_c = \ - gstvaapidisplay_wayland.c \ - gstvaapiwindow_wayland.c \ - $(xdg_shell_source) \ - $(NULL) - -libgstvaapi_wayland_source_h = \ - gstvaapidisplay_wayland.h \ - gstvaapiwindow_wayland.h \ - $(NULL) - -libgstvaapi_wayland_source_priv_h = \ - gstvaapicompat.h \ - gstvaapidisplay_wayland_priv.h \ - $(xdg_shell_header) \ - $(NULL) - -libgstvaapi_la_SOURCES = \ - $(libgstvaapi_source_c) \ - $(libgstvaapi_source_priv_h) \ - $(libgstvaapi_source_h) \ - $(NULL) - -libgstvaapi_la_CFLAGS = \ - $(libgstvaapi_cflags) \ - $(NULL) - -libgstvaapi_la_LIBADD = \ - $(libgstvaapi_libs) \ - $(NULL) - -libgstvaapi_la_LDFLAGS = \ - $(GST_ALL_LDFLAGS) \ - $(NULL) - -libgstvaapi_drm_la_SOURCES = \ - $(libgstvaapi_drm_source_c) \ - $(libgstvaapi_drm_source_priv_h) \ - $(libgstvaapi_drm_source_h) \ - $(NULL) - -libgstvaapi_drm_la_CFLAGS = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - $(GLIB_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(UDEV_CFLAGS) \ - $(DRM_CFLAGS) \ - $(LIBVA_DRM_CFLAGS) \ - $(NULL) - -libgstvaapi_drm_la_LIBADD = \ - $(GLIB_LIBS) \ - $(GST_LIBS) \ - $(UDEV_LIBS) \ - $(DRM_LIBS) \ - $(LIBVA_DRM_LIBS) \ - $(NULL) - -libgstvaapi_drm_la_LDFLAGS = \ - $(GST_ALL_LDFLAGS) \ - $(NULL) - -libgstvaapi_x11_la_SOURCES = \ - $(libgstvaapi_x11_source_c) \ - $(libgstvaapi_x11_source_priv_h) \ - $(libgstvaapi_x11_source_h) \ - $(NULL) - -libgstvaapi_x11_la_CFLAGS = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - $(GLIB_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(X11_CFLAGS) \ - $(XRANDR_CFLAGS) \ - $(XRENDER_CFLAGS) \ - $(LIBVA_X11_CFLAGS) \ - $(NULL) - -libgstvaapi_x11_la_LIBADD = \ - $(GLIB_LIBS) \ - $(GST_LIBS) \ - $(X11_LIBS) \ - $(XRANDR_LIBS) \ - $(XRENDER_LIBS) \ - $(LIBVA_X11_LIBS) \ - $(NULL) - -libgstvaapi_x11_la_LDFLAGS = \ - $(GST_ALL_LDFLAGS) \ - $(NULL) - -libgstvaapi_glx_la_SOURCES = \ - $(libgstvaapi_glx_source_c) \ - $(libgstvaapi_glx_source_priv_h) \ - $(libgstvaapi_glx_source_h) \ - $(NULL) - -libgstvaapi_glx_la_CFLAGS = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - $(GLIB_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(GL_CFLAGS) \ - $(LIBVA_X11_CFLAGS) \ - $(NULL) - -libgstvaapi_glx_la_LIBADD = \ - $(GLIB_LIBS) \ - $(GST_LIBS) \ - $(GST_BASE_LIBS) \ - $(GST_VIDEO_LIBS) \ - $(X11_LIBS) \ - $(GL_LIBS) \ - $(LIBVA_X11_LIBS) \ - $(DLOPEN_LIBS) \ - $(NULL) - -libgstvaapi_glx_la_LDFLAGS = \ - $(GST_ALL_LDFLAGS) \ - $(NULL) - -libgstvaapi_egl_la_SOURCES = \ - $(libgstvaapi_egl_source_c) \ - $(libgstvaapi_egl_source_priv_h) \ - $(libgstvaapi_egl_source_h) \ - $(NULL) - -libgstvaapi_egl_la_CFLAGS = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - $(GLIB_CFLAGS) \ - $(GMODULE_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(GST_GL_CFLAGS) \ - $(LIBVA_CFLAGS) \ - $(LIBVA_WAYLAND_CFLAGS) \ - $(EGL_CFLAGS) \ - $(NULL) - -libgstvaapi_egl_la_LIBADD = \ - $(GLIB_LIBS) \ - $(GMODULE_LIBS) \ - $(GST_LIBS) \ - $(GST_BASE_LIBS) \ - $(GST_VIDEO_LIBS) \ - $(GST_GL_LIBS) \ - $(EGL_LIBS) \ - $(NULL) - -libgstvaapi_egl_la_LDFLAGS = \ - $(GST_ALL_LDFLAGS) \ - $(NULL) - -libgstvaapi_wayland_la_SOURCES = \ - $(libgstvaapi_wayland_source_c) \ - $(libgstvaapi_wayland_source_priv_h) \ - $(libgstvaapi_wayland_source_h) \ - $(NULL) - -libgstvaapi_wayland_la_CFLAGS = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - $(GLIB_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(WAYLAND_CFLAGS) \ - $(LIBVA_WAYLAND_CFLAGS) \ - $(NULL) - -libgstvaapi_wayland_la_LIBADD = \ - $(GLIB_LIBS) \ - $(GST_LIBS) \ - $(GST_VIDEO_LIBS) \ - $(WAYLAND_LIBS) \ - $(LIBVA_WAYLAND_LIBS) \ - $(NULL) - -libgstvaapi_wayland_la_LDFLAGS = \ - $(GST_ALL_LDFLAGS) \ - $(NULL) - -EXTRA_DIST = \ - $(libgstvaapi_enc_source_c) \ - $(libgstvaapi_enc_source_h) \ - $(libgstvaapi_enc_source_priv_h) \ - $(libgstvaapi_jpegdec_source_c) \ - $(libgstvaapi_jpegdec_source_h) \ - $(libgstvaapi_vp8dec_source_c) \ - $(libgstvaapi_vp8dec_source_h) \ - $(libgstvaapi_hevcdec_source_c) \ - $(libgstvaapi_hevcdec_source_h) \ - $(libgstvaapi_hevcdec_source_priv_h) \ - $(libgstvaapi_vp9dec_source_c) \ - $(libgstvaapi_vp9dec_source_h) \ - $(libgstvaapi_vp9enc_source_h) \ - $(libgstvaapi_vp9enc_source_c) \ - $(libgstvaapi_egl_source_c) \ - $(libgstvaapi_egl_source_h) \ - $(libgstvaapi_egl_source_priv_h) \ - $(libgstvaapi_h264feienc_source_h) \ - $(libgstvaapi_h264feienc_source_c) \ - $(libgstvaapi_h264feienc_source_priv_h) \ - $(NULL) - --include $(top_srcdir)/git.mk diff --git a/gst/Makefile.am b/gst/Makefile.am deleted file mode 100644 index 80a5198af9..0000000000 --- a/gst/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = vaapi - --include $(top_srcdir)/git.mk diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am deleted file mode 100644 index a829c914e7..0000000000 --- a/gst/vaapi/Makefile.am +++ /dev/null @@ -1,166 +0,0 @@ -plugin_LTLIBRARIES = libgstvaapi.la - -libgstvaapi_CFLAGS = \ - $(LIBVA_CFLAGS) \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - -I$(top_builddir)/gst-libs \ - $(NULL) - -libgstvaapi_LIBS = $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la - -if USE_DRM -libgstvaapi_LIBS +=$(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm.la -endif - -if USE_X11 -libgstvaapi_LIBS += \ - $(X11_LIBS) \ - $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11.la -endif - -if USE_GLX -libgstvaapi_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx.la -endif - -if USE_EGL -libgstvaapi_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl.la -endif - -if USE_WAYLAND -libgstvaapi_CFLAGS += \ - $(WAYLAND_CFLAGS) \ - $(NULL) - -libgstvaapi_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland.la -endif - -if USE_GST_GL_HELPERS -libgstvaapi_CFLAGS += $(GST_GL_CFLAGS) -libgstvaapi_LIBS += $(GST_GL_LIBS) -endif - -libgstvaapi_source_c = \ - gstvaapi.c \ - gstvaapidecode.c \ - gstvaapidecodedoc.c \ - gstvaapipluginbase.c \ - gstvaapipluginutil.c \ - gstvaapipostproc.c \ - gstvaapipostprocutil.c \ - gstvaapisink.c \ - gstvaapivideobuffer.c \ - gstvaapivideocontext.c \ - gstvaapivideometa.c \ - gstvaapidecodebin.c \ - gstvaapivideobufferpool.c \ - gstvaapivideomemory.c \ - gstvaapivideometa_texture.c \ - gstvaapidecode_props.c \ - $(NULL) - -libgstvaapi_source_h = \ - gstcompat.h \ - gstvaapi.h \ - gstvaapidecode.h \ - gstvaapipluginbase.h \ - gstvaapipluginutil.h \ - gstvaapipostproc.h \ - gstvaapipostprocutil.h \ - gstvaapisink.h \ - gstvaapivideobuffer.h \ - gstvaapivideocontext.h \ - gstvaapivideometa.h \ - gstvaapidecodebin.h \ - gstvaapivideobufferpool.h \ - gstvaapivideomemory.h \ - gstvaapivideometa_texture.h \ - gstvaapidecode_props.h \ - $(NULL) - -libgstvaapi_enc_source_c = \ - gstvaapiencode.c \ - gstvaapiencode_h264.c \ - gstvaapiencode_h265.c \ - gstvaapiencode_jpeg.c \ - gstvaapiencode_mpeg2.c \ - gstvaapiencode_vp8.c \ - $(NULL) - -libgstvaapi_enc_source_h = \ - gstvaapiencode.h \ - gstvaapiencode_h264.h \ - gstvaapiencode_h265.h \ - gstvaapiencode_jpeg.h \ - gstvaapiencode_mpeg2.h \ - gstvaapiencode_vp8.h \ - $(NULL) - -if USE_ENCODERS -libgstvaapi_source_c += $(libgstvaapi_enc_source_c) -libgstvaapi_source_h += $(libgstvaapi_enc_source_h) -endif - -libgstvaapi_vp9enc_source_c = gstvaapiencode_vp9.c -libgstvaapi_vp9enc_source_h = gstvaapiencode_vp9.h -if USE_VP9_ENCODER -libgstvaapi_source_c += $(libgstvaapi_vp9enc_source_c) -libgstvaapi_source_h += $(libgstvaapi_vp9enc_source_h) -endif - -libgstvaapi_h264feienc_source_c = \ - gstvaapifeivideometa.c \ - gstvaapiencode_h264_fei.c \ - $(NULL) -libgstvaapi_h264feienc_source_h = \ - gstvaapifeivideometa.h \ - gstvaapiencode_h264_fei.h \ - $(NULL) - -if USE_H264_FEI_ENCODER -libgstvaapi_source_c += $(libgstvaapi_h264feienc_source_c) -libgstvaapi_source_h += $(libgstvaapi_h264feienc_source_h) -endif - -libgstvaapi_la_SOURCES = $(libgstvaapi_source_c) -noinst_HEADERS = $(libgstvaapi_source_h) - -libgstvaapi_la_CFLAGS = \ - $(libgstvaapi_CFLAGS) \ - $(GST_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(GST_PBUTILS_CFLAGS) \ - $(GST_INTERFACES_CFLAGS) \ - $(GST_BASEVIDEO_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) \ - $(GST_ALLOCATORS_CFLAGS) - -libgstvaapi_la_LIBADD = \ - $(libgstvaapi_LIBS) \ - $(GST_LIBS) \ - $(GST_BASE_LIBS) \ - $(GST_VIDEO_LIBS) \ - $(GST_PBUTILS_LIBS) \ - $(GST_INTERFACES_LIBS) \ - $(GST_BASEVIDEO_LIBS) \ - $(GST_PLUGINS_BASE_LIBS) \ - $(GST_ALLOCATORS_LIBS) - -libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstvaapi_la_LIBTOOLFLAGS = --tag=disable-static - -EXTRA_DIST = \ - $(libgstvaapi_enc_source_c) \ - $(libgstvaapi_enc_source_h) \ - $(libgstvaapi_vp9enc_source_c) \ - $(libgstvaapi_vp9enc_source_h) \ - $(libgstvaapi_h264feienc_source_c) \ - $(libgstvaapi_h264feienc_source_h) \ - $(libgstvaapi_egl_source_c) \ - $(libgstvaapi_egl_source_h) \ - $(libgstvaapi_1_2p_source_c) \ - $(libgstvaapi_1_2p_source_h) \ - $(NULL) - --include $(top_srcdir)/git.mk diff --git a/m4/Makefile.am b/m4/Makefile.am deleted file mode 100644 index 398f95103f..0000000000 --- a/m4/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -EXTRA_DIST = $(wildcard *.m4) - --include $(top_srcdir)/git.mk diff --git a/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index 892e3966fc..0000000000 --- a/tests/Makefile.am +++ /dev/null @@ -1,182 +0,0 @@ -noinst_PROGRAMS = \ - simple-decoder \ - test-decode \ - test-display \ - test-filter \ - test-surfaces \ - test-windows \ - test-subpicture \ - $(NULL) - -if USE_ENCODERS -noinst_PROGRAMS += \ - simple-encoder \ - $(NULL) -endif - -if USE_H264_FEI_ENCODER -noinst_PROGRAMS += \ - test-fei-enc-out \ - test-fei-enc-in \ - $(NULL) -endif - -if USE_GLX -noinst_PROGRAMS += \ - test-textures \ - $(NULL) -endif - -TEST_CFLAGS = \ - -DGST_USE_UNSTABLE_API \ - -I$(top_srcdir)/gst-libs \ - -I$(top_builddir)/gst-libs \ - $(LIBVA_CFLAGS) \ - $(GST_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(NULL) - -GST_VAAPI_LIBS = $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi.la -TEST_LIBS = \ - $(LIBVA_LIBS) \ - $(GST_LIBS) \ - $(NULL) - -if USE_DRM -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-drm.la -TEST_CFLAGS += $(LIBVA_DRM_CFLAGS) -TEST_LIBS += $(LIBVA_DRM_LIBS) -endif - -if USE_X11 -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11.la -TEST_CFLAGS += $(X11_CFLAGS) -TEST_LIBS += \ - $(LIBVA_X11_LIBS) \ - $(X11_LIBS) \ - $(NULL) -endif - -if USE_GLX -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx.la -TEST_CFLAGS += $(X11_CFLAGS) $(GL_CFLAGS) -TEST_LIBS += \ - $(LIBVA_GLX_LIBS) \ - $(X11_LIBS) \ - $(GL_LIBS) \ - $(NULL) -endif - -if USE_EGL -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl.la -TEST_CFLAGS += $(EGL_CFLAGS) -TEST_LIBS += \ - $(LIBVA_EGL_LIBS) \ - $(EGL_LIBS) \ - $(NULL) -endif - -if USE_WAYLAND -GST_VAAPI_LIBS += $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland.la -TEST_CFLAGS += $(WAYLAND_CFLAGS) -TEST_LIBS += \ - $(LIBVA_WAYLAND_LIBS) \ - $(WAYLAND_LIBS) \ - $(NULL) -endif - -test_utils_dec_source_c = \ - decoder.c \ - test-h264.c \ - test-jpeg.c \ - test-mpeg2.c \ - test-mpeg4.c \ - test-vc1.c \ - $(NULL) -test_utils_dec_source_h = $(test_utils_dec_source_c:%.c=%.h) test-decode.h - -test_utils_source_c = codec.c image.c output.c -test_utils_source_h = codec.h image.h output.h - -noinst_LTLIBRARIES = libutils.la libutils_dec.la - -libutils_la_SOURCES = $(test_utils_source_c) -libutils_la_CFLAGS = $(TEST_CFLAGS) -libutils_la_LDFLAGS = $(GST_VAAPI_LIBS) - -libutils_dec_la_SOURCES = $(test_utils_dec_source_c) -libutils_dec_la_CFLAGS = $(TEST_CFLAGS) -libutils_dec_la_LDFLAGS = $(GST_VAAPI_LIBS) - -test_decode_SOURCES = test-decode.c -test_decode_CFLAGS = $(TEST_CFLAGS) -test_decode_LDADD = libutils.la libutils_dec.la $(TEST_LIBS) - -test_display_SOURCES = test-display.c -test_display_CFLAGS = $(TEST_CFLAGS) -test_display_LDFLAGS = $(GST_VAAPI_LIBS) -test_display_LDADD = libutils.la $(TEST_LIBS) - -test_filter_SOURCES = test-filter.c -test_filter_CFLAGS = $(TEST_CFLAGS) -test_filter_LDFLAGS = $(GST_VAAPI_LIBS) -test_filter_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) - -test_surfaces_SOURCES = test-surfaces.c -test_surfaces_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) -test_surfaces_LDFLAGS = $(GST_VAAPI_LIBS) -test_surfaces_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) - -test_subpicture_SOURCES = test-subpicture.c test-subpicture-data.c -test_subpicture_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) -test_subpicture_LDADD = libutils.la libutils_dec.la $(TEST_LIBS) \ - $(GST_VIDEO_LIBS) -test_subpicture_LDFLAGS = $(GST_VAAPI_LIBS) - -test_windows_SOURCES = test-windows.c -test_windows_CFLAGS = $(TEST_CFLAGS) -test_windows_LDFLAGS = $(GST_VAAPI_LIBS) -test_windows_LDADD = libutils.la $(TEST_LIBS) - -test_textures_SOURCES = test-textures.c -test_textures_CFLAGS = $(TEST_CFLAGS) -test_textures_LDFLAGS = $(GST_VAAPI_LIBS) -test_textures_LDADD = libutils.la $(TEST_LIBS) - -test_fei_enc_out_SOURCES = test-fei-enc-out.c ../gst/vaapi/gstvaapifeivideometa.h -test_fei_enc_out_CFLAGS = $(TEST_CFLAGS) -test_fei_enc_out_LDFLAGS = $(GST_VAAPI_LIBS) -test_fei_enc_out_LDADD = libutils.la $(TEST_LIBS) - -test_fei_enc_in_sources_c = test-fei-enc-in.c ../gst/vaapi/gstvaapifeivideometa.h y4mreader.c -test_fei_enc_in_sources_h = y4mreader.h -test_fei_enc_in_SOURCES = $(test_fei_enc_in_sources_c) -test_fei_enc_in_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) -test_fei_enc_in_LDFLAGS = $(GST_VAAPI_LIBS) -test_fei_enc_in_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) - -simple_decoder_source_c = simple-decoder.c -simple_decoder_source_h = -simple_decoder_SOURCES = $(simple_decoder_source_c) -simple_decoder_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) -simple_decoder_LDFLAGS = $(GST_VAAPI_LIBS) -simple_decoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) - -simple_encoder_source_c = simple-encoder.c y4mreader.c -simple_encoder_source_h = y4mreader.h -simple_encoder_SOURCES = $(simple_encoder_source_c) -simple_encoder_CFLAGS = $(TEST_CFLAGS) $(GST_VIDEO_CFLAGS) -simple_encoder_LDFLAGS = $(GST_VAAPI_LIBS) -simple_encoder_LDADD = libutils.la $(TEST_LIBS) $(GST_VIDEO_LIBS) - -EXTRA_DIST = \ - test-subpicture-data.h \ - $(simple_decoder_source_h) \ - $(simple_encoder_source_h) \ - $(test_utils_dec_source_h) \ - $(test_utils_source_h) \ - $(NULL) - -SUBDIRS = elements - --include $(top_srcdir)/git.mk diff --git a/tests/elements/Makefile.am b/tests/elements/Makefile.am deleted file mode 100644 index 742d923a67..0000000000 --- a/tests/elements/Makefile.am +++ /dev/null @@ -1,50 +0,0 @@ -noinst_PROGRAMS = \ - test-vaapisink \ - test-vaapipostproc \ - test-roi \ - $(NULL) - -TEST_CFLAGS = \ - -DGST_USE_UNSTABLE_API \ - $(GST_CFLAGS) \ - $(GST_VIDEO_CFLAGS) \ - $(NULL) - -TEST_LIBS = \ - $(GST_LIBS) \ - $(GST_VIDEO_LIBS) \ - $(NULL) - -test_vaapisink_SOURCES = test-vaapisink.c -test_vaapisink_CFLAGS = $(TEST_CFLAGS) -test_vaapisink_LDADD = $(TEST_LIBS) - -test_vaapipostproc_SOURCES = test-vaapipostproc.c -test_vaapipostproc_CFLAGS = $(TEST_CFLAGS) -test_vaapipostproc_LDADD = $(TEST_LIBS) - -test_roi_SOURCES = test-roi.c -test_roi_CFLAGS = $(TEST_CFLAGS) -test_roi_LDADD = $(TEST_LIBS) - -if USE_GTK -noinst_PROGRAMS += test-vaapicontext - -test_vaapicontext_SOURCES = test-vaapicontext.c -test_vaapicontext_CFLAGS = \ - $(TEST_CFLAGS) \ - $(GTK3_CFLAGS) \ - $(X11_CFLAGS) \ - $(LIBVA_CFLAGS) \ - $(LIBVA_X11_CFLAGS) \ - $(NULL) -test_vaapicontext_LDADD = \ - $(TEST_LIBS) \ - $(GTK3_LIBS) \ - $(X11_LIBS) \ - $(LIBVA_LIBS) \ - $(LIBVA_X11_LIBS) \ - $(NULL) -endif - --include $(top_srcdir)/git.mk From 97aabe8784c057a4bee33d6f541ab7d75ca3708e Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 8 Oct 2019 12:19:06 -0700 Subject: [PATCH 3407/3781] tests: move examples and tests to subfolders This makes way for adding unit (check) tests. --- meson.build | 4 +- tests/{elements => examples}/meson.build | 0 tests/{elements => examples}/test-roi.c | 0 .../test-vaapicontext.c | 0 .../test-vaapipostproc.c | 0 tests/{elements => examples}/test-vaapisink.c | 0 tests/{ => internal}/codec.c | 0 tests/{ => internal}/codec.h | 0 tests/{ => internal}/decoder.c | 0 tests/{ => internal}/decoder.h | 0 tests/{ => internal}/image.c | 0 tests/{ => internal}/image.h | 0 tests/internal/meson.build | 81 ++++++++++++++++++ tests/{ => internal}/output.c | 0 tests/{ => internal}/output.h | 0 tests/{ => internal}/simple-decoder.c | 0 tests/{ => internal}/simple-encoder.c | 0 tests/{ => internal}/test-decode.c | 0 tests/{ => internal}/test-decode.h | 0 tests/{ => internal}/test-display.c | 0 tests/{ => internal}/test-fei-enc-in.c | 0 tests/{ => internal}/test-fei-enc-out.c | 0 tests/{ => internal}/test-filter.c | 0 tests/{ => internal}/test-h264.c | 0 tests/{ => internal}/test-h264.h | 0 tests/{ => internal}/test-jpeg.c | 0 tests/{ => internal}/test-jpeg.h | 0 tests/{ => internal}/test-mpeg2.c | 0 tests/{ => internal}/test-mpeg2.h | 0 tests/{ => internal}/test-mpeg4.c | 0 tests/{ => internal}/test-mpeg4.h | 0 tests/{ => internal}/test-subpicture-data.c | 0 tests/{ => internal}/test-subpicture-data.h | 0 tests/{ => internal}/test-subpicture.c | 0 tests/{ => internal}/test-surfaces.c | 0 tests/{ => internal}/test-textures.c | 0 tests/{ => internal}/test-vc1.c | 0 tests/{ => internal}/test-vc1.h | 0 tests/{ => internal}/test-windows.c | 0 tests/{ => internal}/y4mreader.c | 0 tests/{ => internal}/y4mreader.h | 0 tests/meson.build | 85 +------------------ 42 files changed, 85 insertions(+), 85 deletions(-) rename tests/{elements => examples}/meson.build (100%) rename tests/{elements => examples}/test-roi.c (100%) rename tests/{elements => examples}/test-vaapicontext.c (100%) rename tests/{elements => examples}/test-vaapipostproc.c (100%) rename tests/{elements => examples}/test-vaapisink.c (100%) rename tests/{ => internal}/codec.c (100%) rename tests/{ => internal}/codec.h (100%) rename tests/{ => internal}/decoder.c (100%) rename tests/{ => internal}/decoder.h (100%) rename tests/{ => internal}/image.c (100%) rename tests/{ => internal}/image.h (100%) create mode 100644 tests/internal/meson.build rename tests/{ => internal}/output.c (100%) rename tests/{ => internal}/output.h (100%) rename tests/{ => internal}/simple-decoder.c (100%) rename tests/{ => internal}/simple-encoder.c (100%) rename tests/{ => internal}/test-decode.c (100%) rename tests/{ => internal}/test-decode.h (100%) rename tests/{ => internal}/test-display.c (100%) rename tests/{ => internal}/test-fei-enc-in.c (100%) rename tests/{ => internal}/test-fei-enc-out.c (100%) rename tests/{ => internal}/test-filter.c (100%) rename tests/{ => internal}/test-h264.c (100%) rename tests/{ => internal}/test-h264.h (100%) rename tests/{ => internal}/test-jpeg.c (100%) rename tests/{ => internal}/test-jpeg.h (100%) rename tests/{ => internal}/test-mpeg2.c (100%) rename tests/{ => internal}/test-mpeg2.h (100%) rename tests/{ => internal}/test-mpeg4.c (100%) rename tests/{ => internal}/test-mpeg4.h (100%) rename tests/{ => internal}/test-subpicture-data.c (100%) rename tests/{ => internal}/test-subpicture-data.h (100%) rename tests/{ => internal}/test-subpicture.c (100%) rename tests/{ => internal}/test-surfaces.c (100%) rename tests/{ => internal}/test-textures.c (100%) rename tests/{ => internal}/test-vc1.c (100%) rename tests/{ => internal}/test-vc1.h (100%) rename tests/{ => internal}/test-windows.c (100%) rename tests/{ => internal}/y4mreader.c (100%) rename tests/{ => internal}/y4mreader.h (100%) diff --git a/meson.build b/meson.build index 4ef68813dd..827dc275fa 100644 --- a/meson.build +++ b/meson.build @@ -164,9 +164,7 @@ libsinc = include_directories('gst-libs') subdir('gst-libs') subdir('gst') -if not get_option('examples').disabled() - subdir('tests') -endif +subdir('tests') subdir('docs') python3 = import('python').find_installation() diff --git a/tests/elements/meson.build b/tests/examples/meson.build similarity index 100% rename from tests/elements/meson.build rename to tests/examples/meson.build diff --git a/tests/elements/test-roi.c b/tests/examples/test-roi.c similarity index 100% rename from tests/elements/test-roi.c rename to tests/examples/test-roi.c diff --git a/tests/elements/test-vaapicontext.c b/tests/examples/test-vaapicontext.c similarity index 100% rename from tests/elements/test-vaapicontext.c rename to tests/examples/test-vaapicontext.c diff --git a/tests/elements/test-vaapipostproc.c b/tests/examples/test-vaapipostproc.c similarity index 100% rename from tests/elements/test-vaapipostproc.c rename to tests/examples/test-vaapipostproc.c diff --git a/tests/elements/test-vaapisink.c b/tests/examples/test-vaapisink.c similarity index 100% rename from tests/elements/test-vaapisink.c rename to tests/examples/test-vaapisink.c diff --git a/tests/codec.c b/tests/internal/codec.c similarity index 100% rename from tests/codec.c rename to tests/internal/codec.c diff --git a/tests/codec.h b/tests/internal/codec.h similarity index 100% rename from tests/codec.h rename to tests/internal/codec.h diff --git a/tests/decoder.c b/tests/internal/decoder.c similarity index 100% rename from tests/decoder.c rename to tests/internal/decoder.c diff --git a/tests/decoder.h b/tests/internal/decoder.h similarity index 100% rename from tests/decoder.h rename to tests/internal/decoder.h diff --git a/tests/image.c b/tests/internal/image.c similarity index 100% rename from tests/image.c rename to tests/internal/image.c diff --git a/tests/image.h b/tests/internal/image.h similarity index 100% rename from tests/image.h rename to tests/internal/image.h diff --git a/tests/internal/meson.build b/tests/internal/meson.build new file mode 100644 index 0000000000..a118d3843b --- /dev/null +++ b/tests/internal/meson.build @@ -0,0 +1,81 @@ +libdecutils_sources = [ + 'decoder.c', + 'test-h264.c', + 'test-jpeg.c', + 'test-mpeg2.c', + 'test-mpeg4.c', + 'test-vc1.c', +] + +libdecutils_headers = [ + 'decoder.h', + 'test-h264.h', + 'test-jpeg.h', + 'test-mpeg2.h', + 'test-mpeg4.h', + 'test-vc1.h', +] + +libutils_sources = [ + 'codec.c', + 'image.c', + 'output.c', + 'test-subpicture-data.c', + 'y4mreader.c', +] + +libutils_headers = [ + 'codec.h', + 'image.h', + 'output.h', + 'test-subpicture-data.h', + 'y4mreader.h', +] + +test_examples = [ + 'simple-decoder', + 'test-decode', + 'test-display', + 'test-filter', + 'test-surfaces', + 'test-windows', + 'test-subpicture', +] + +if USE_ENCODERS + test_examples += [ 'simple-encoder' ] +endif + +if USE_H264_FEI_ENCODER + test_examples += [ + 'test-fei-enc-out', + 'test-fei-enc-in', + ] +endif + +if USE_GLX + test_examples += [ 'test-textures' ] +endif + +libutils = static_library('libutils', + libutils_sources + libutils_headers, + c_args : gstreamer_vaapi_args, + include_directories: [configinc, libsinc], + dependencies : gstlibvaapi_deps, + install: false) + +libdecutils = static_library('libdecutils', + libdecutils_sources + libdecutils_headers, + c_args : gstreamer_vaapi_args, + include_directories: [configinc, libsinc], + dependencies : gstlibvaapi_deps, + install: false) + +foreach example : test_examples + executable(example, '@0@.c'.format(example), + c_args : gstreamer_vaapi_args, + include_directories: [configinc, libsinc], + dependencies : [gst_dep, libva_dep, gstlibvaapi_dep], + link_with: [libutils, libdecutils], + install: false) +endforeach diff --git a/tests/output.c b/tests/internal/output.c similarity index 100% rename from tests/output.c rename to tests/internal/output.c diff --git a/tests/output.h b/tests/internal/output.h similarity index 100% rename from tests/output.h rename to tests/internal/output.h diff --git a/tests/simple-decoder.c b/tests/internal/simple-decoder.c similarity index 100% rename from tests/simple-decoder.c rename to tests/internal/simple-decoder.c diff --git a/tests/simple-encoder.c b/tests/internal/simple-encoder.c similarity index 100% rename from tests/simple-encoder.c rename to tests/internal/simple-encoder.c diff --git a/tests/test-decode.c b/tests/internal/test-decode.c similarity index 100% rename from tests/test-decode.c rename to tests/internal/test-decode.c diff --git a/tests/test-decode.h b/tests/internal/test-decode.h similarity index 100% rename from tests/test-decode.h rename to tests/internal/test-decode.h diff --git a/tests/test-display.c b/tests/internal/test-display.c similarity index 100% rename from tests/test-display.c rename to tests/internal/test-display.c diff --git a/tests/test-fei-enc-in.c b/tests/internal/test-fei-enc-in.c similarity index 100% rename from tests/test-fei-enc-in.c rename to tests/internal/test-fei-enc-in.c diff --git a/tests/test-fei-enc-out.c b/tests/internal/test-fei-enc-out.c similarity index 100% rename from tests/test-fei-enc-out.c rename to tests/internal/test-fei-enc-out.c diff --git a/tests/test-filter.c b/tests/internal/test-filter.c similarity index 100% rename from tests/test-filter.c rename to tests/internal/test-filter.c diff --git a/tests/test-h264.c b/tests/internal/test-h264.c similarity index 100% rename from tests/test-h264.c rename to tests/internal/test-h264.c diff --git a/tests/test-h264.h b/tests/internal/test-h264.h similarity index 100% rename from tests/test-h264.h rename to tests/internal/test-h264.h diff --git a/tests/test-jpeg.c b/tests/internal/test-jpeg.c similarity index 100% rename from tests/test-jpeg.c rename to tests/internal/test-jpeg.c diff --git a/tests/test-jpeg.h b/tests/internal/test-jpeg.h similarity index 100% rename from tests/test-jpeg.h rename to tests/internal/test-jpeg.h diff --git a/tests/test-mpeg2.c b/tests/internal/test-mpeg2.c similarity index 100% rename from tests/test-mpeg2.c rename to tests/internal/test-mpeg2.c diff --git a/tests/test-mpeg2.h b/tests/internal/test-mpeg2.h similarity index 100% rename from tests/test-mpeg2.h rename to tests/internal/test-mpeg2.h diff --git a/tests/test-mpeg4.c b/tests/internal/test-mpeg4.c similarity index 100% rename from tests/test-mpeg4.c rename to tests/internal/test-mpeg4.c diff --git a/tests/test-mpeg4.h b/tests/internal/test-mpeg4.h similarity index 100% rename from tests/test-mpeg4.h rename to tests/internal/test-mpeg4.h diff --git a/tests/test-subpicture-data.c b/tests/internal/test-subpicture-data.c similarity index 100% rename from tests/test-subpicture-data.c rename to tests/internal/test-subpicture-data.c diff --git a/tests/test-subpicture-data.h b/tests/internal/test-subpicture-data.h similarity index 100% rename from tests/test-subpicture-data.h rename to tests/internal/test-subpicture-data.h diff --git a/tests/test-subpicture.c b/tests/internal/test-subpicture.c similarity index 100% rename from tests/test-subpicture.c rename to tests/internal/test-subpicture.c diff --git a/tests/test-surfaces.c b/tests/internal/test-surfaces.c similarity index 100% rename from tests/test-surfaces.c rename to tests/internal/test-surfaces.c diff --git a/tests/test-textures.c b/tests/internal/test-textures.c similarity index 100% rename from tests/test-textures.c rename to tests/internal/test-textures.c diff --git a/tests/test-vc1.c b/tests/internal/test-vc1.c similarity index 100% rename from tests/test-vc1.c rename to tests/internal/test-vc1.c diff --git a/tests/test-vc1.h b/tests/internal/test-vc1.h similarity index 100% rename from tests/test-vc1.h rename to tests/internal/test-vc1.h diff --git a/tests/test-windows.c b/tests/internal/test-windows.c similarity index 100% rename from tests/test-windows.c rename to tests/internal/test-windows.c diff --git a/tests/y4mreader.c b/tests/internal/y4mreader.c similarity index 100% rename from tests/y4mreader.c rename to tests/internal/y4mreader.c diff --git a/tests/y4mreader.h b/tests/internal/y4mreader.h similarity index 100% rename from tests/y4mreader.h rename to tests/internal/y4mreader.h diff --git a/tests/meson.build b/tests/meson.build index 2bc2410e7d..b27c0dab83 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,83 +1,4 @@ -libdecutils_sources = [ - 'decoder.c', - 'test-h264.c', - 'test-jpeg.c', - 'test-mpeg2.c', - 'test-mpeg4.c', - 'test-vc1.c', -] - -libdecutils_headers = [ - 'decoder.h', - 'test-h264.h', - 'test-jpeg.h', - 'test-mpeg2.h', - 'test-mpeg4.h', - 'test-vc1.h', -] - -libutils_sources = [ - 'codec.c', - 'image.c', - 'output.c', - 'test-subpicture-data.c', - 'y4mreader.c', -] - -libutils_headers = [ - 'codec.h', - 'image.h', - 'output.h', - 'test-subpicture-data.h', - 'y4mreader.h', -] - -test_examples = [ - 'simple-decoder', - 'test-decode', - 'test-display', - 'test-filter', - 'test-surfaces', - 'test-windows', - 'test-subpicture', -] - -if USE_ENCODERS - test_examples += [ 'simple-encoder' ] +if not get_option('examples').disabled() + subdir('examples') + subdir('internal') endif - -if USE_H264_FEI_ENCODER - test_examples += [ - 'test-fei-enc-out', - 'test-fei-enc-in', - ] -endif - -if USE_GLX - test_examples += [ 'test-textures' ] -endif - -libutils = static_library('libutils', - libutils_sources + libutils_headers, - c_args : gstreamer_vaapi_args, - include_directories: [configinc, libsinc], - dependencies : gstlibvaapi_deps, - install: false) - -libdecutils = static_library('libdecutils', - libdecutils_sources + libdecutils_headers, - c_args : gstreamer_vaapi_args, - include_directories: [configinc, libsinc], - dependencies : gstlibvaapi_deps, - install: false) - -foreach example : test_examples - executable(example, '@0@.c'.format(example), - c_args : gstreamer_vaapi_args, - include_directories: [configinc, libsinc], - dependencies : [gst_dep, libva_dep, gstlibvaapi_dep], - link_with: [libutils, libdecutils], - install: false) -endforeach - -subdir('elements') From 7ce24e6ff793dfd8aa710c2cc236002304bc0849 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 8 Oct 2019 12:20:26 -0700 Subject: [PATCH 3408/3781] tests: check: initial unit test support Add minimal unit test toolchain files and a simple vaapipostproc unit test. --- meson.build | 3 ++ meson_options.txt | 1 + tests/check/elements/vaapipostproc.c | 53 ++++++++++++++++++++++++++++ tests/check/meson.build | 33 +++++++++++++++++ tests/meson.build | 4 +++ 5 files changed, 94 insertions(+) create mode 100644 tests/check/elements/vaapipostproc.c create mode 100644 tests/check/meson.build diff --git a/meson.build b/meson.build index 827dc275fa..d1cb310f5a 100644 --- a/meson.build +++ b/meson.build @@ -81,6 +81,9 @@ libudev_dep = dependency('libudev', required: false) egl_dep = dependency('egl', required: false) gl_dep = dependency('gl', required: false) glesv2_dep = dependency('glesv2', required: false) +gstcheck_dep = dependency('gstreamer-check-1.0', version : gst_req, + required : get_option('tests'), + fallback : ['gstreamer', 'gst_check_dep']) libdl_dep = cc.find_library('dl', required: false) wayland_client_dep = dependency('wayland-client', version: libwayland_req, required: false) wayland_protocols_dep = dependency('wayland-protocols', version: '>= 1.15', required: false) diff --git a/meson_options.txt b/meson_options.txt index 24b2c3b044..fd4d92e6e5 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -7,5 +7,6 @@ option('with_egl', type : 'combo', choices : ['yes', 'no', 'auto'], value : 'aut # Common feature options option('examples', type : 'feature', value : 'auto', yield : true) +option('tests', type : 'feature', value : 'auto', yield : true) option('doc', type : 'feature', value : 'auto', yield: true, description: 'Enable documentation.') diff --git a/tests/check/elements/vaapipostproc.c b/tests/check/elements/vaapipostproc.c new file mode 100644 index 0000000000..9190fcfdac --- /dev/null +++ b/tests/check/elements/vaapipostproc.c @@ -0,0 +1,53 @@ +/* + * vaapipostproc.c - GStreamer unit test for the vaapipostproc element + * + * Copyright (C) 2019 Intel Corporation + * Author: U. Artie Eoff + * + * 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 + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +GST_START_TEST (test_make) +{ + GstElement *vaapipostproc; + + vaapipostproc = gst_element_factory_make ("vaapipostproc", "vaapipostproc"); + fail_unless (vaapipostproc != NULL, "Failed to create vaapipostproc element"); + + gst_object_unref (vaapipostproc); +} + +GST_END_TEST; + +static Suite * +vaapipostproc_suite (void) +{ + Suite *s = suite_create ("vaapipostproc"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_make); + + return s; +} + +GST_CHECK_MAIN (vaapipostproc); diff --git a/tests/check/meson.build b/tests/check/meson.build new file mode 100644 index 0000000000..1b2a4a01dd --- /dev/null +++ b/tests/check/meson.build @@ -0,0 +1,33 @@ +tests = [ + [ 'elements/vaapipostproc' ], +] + +test_deps = [gst_dep, gstcheck_dep] +test_defines = [ + '-UG_DISABLE_ASSERT', + '-UG_DISABLE_CAST_CHECKS', + '-DGST_USE_UNSTABLE_API', +] + +pluginsdirs = [] +if gst_dep.type_name() == 'pkgconfig' + pluginsdirs = [gst_dep.get_pkgconfig_variable('pluginsdir')] +endif + +foreach t : tests + fname = '@0@.c'.format(t.get(0)) + test_name = t.get(0).underscorify() + extra_sources = [ ] + extra_deps = [ ] + env = environment() + env.set('CK_DEFAULT_TIMEOUT', '20') + env.set('GST_PLUGIN_SYSTEM_PATH_1_0', '') + env.set('GST_PLUGIN_PATH_1_0', [meson.build_root()] + pluginsdirs) + env.set('GST_REGISTRY', join_paths(meson.current_build_dir(), '@0@.registry'.format(test_name))) + exe = executable(test_name, fname, extra_sources, + include_directories : [configinc, libsinc], + c_args : ['-DHAVE_CONFIG_H=1' ] + test_defines, + dependencies : test_deps + extra_deps, + ) + test(test_name, exe, env: env, timeout: 3 * 60) +endforeach diff --git a/tests/meson.build b/tests/meson.build index b27c0dab83..2b8b8155df 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,3 +1,7 @@ +if not get_option('tests').disabled() and gstcheck_dep.found() + subdir('check') +endif + if not get_option('examples').disabled() subdir('examples') subdir('internal') From 8bcfacdb62829351f461e7d79c6f6d6362daf48e Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Wed, 9 Oct 2019 10:11:54 -0700 Subject: [PATCH 3409/3781] tests: check: vaapipostproc test_crop_mouse_events Test that vaapipostproc properly translates mouse events when cropping. --- tests/check/elements/vaapipostproc.c | 229 +++++++++++++++++++++++++++ tests/check/meson.build | 2 +- 2 files changed, 230 insertions(+), 1 deletion(-) diff --git a/tests/check/elements/vaapipostproc.c b/tests/check/elements/vaapipostproc.c index 9190fcfdac..82b894fbbc 100644 --- a/tests/check/elements/vaapipostproc.c +++ b/tests/check/elements/vaapipostproc.c @@ -25,6 +25,29 @@ #endif #include +#include +#include + +typedef struct +{ + GstElement *pipeline; + GstElement *source; + GstElement *filter; + GstElement *vpp; + GstElement *sink; +} VppTestContext; + +typedef struct +{ + gdouble x; + gdouble y; +} VppTestCoordinate; + +typedef struct +{ + VppTestCoordinate send; + VppTestCoordinate expect; +} VppTestCoordinateParams; GST_START_TEST (test_make) { @@ -38,6 +61,211 @@ GST_START_TEST (test_make) GST_END_TEST; +static void +vpp_test_init_context (VppTestContext * ctx) +{ + GST_INFO ("initing context"); + + ctx->pipeline = gst_pipeline_new ("pipeline"); + fail_unless (ctx->pipeline != NULL); + + ctx->source = gst_element_factory_make ("videotestsrc", "src"); + fail_unless (ctx->source != NULL, "Failed to create videotestsrc element"); + + ctx->filter = gst_element_factory_make ("capsfilter", "filter"); + fail_unless (ctx->filter != NULL, "Failed to create caps filter element"); + + ctx->vpp = gst_element_factory_make ("vaapipostproc", "vpp"); + fail_unless (ctx->vpp != NULL, "Failed to create vaapipostproc element"); + + ctx->sink = gst_element_factory_make ("fakesink", "sink"); + fail_unless (ctx->sink != NULL, "Failed to create fakesink element"); + + gst_bin_add_many (GST_BIN (ctx->pipeline), ctx->source, ctx->filter, ctx->vpp, + ctx->sink, NULL); + gst_element_link_many (ctx->source, ctx->filter, ctx->vpp, ctx->sink, NULL); +} + +static void +vpp_test_deinit_context (VppTestContext * ctx) +{ + GST_INFO ("deiniting context"); + + gst_element_set_state (ctx->pipeline, GST_STATE_NULL); + gst_object_unref (ctx->pipeline); + memset (ctx, 0x00, sizeof (VppTestContext)); +} + +static void +vpp_test_set_crop (VppTestContext * ctx, gint l, gint r, gint t, gint b) +{ + GST_LOG ("%d %d %d %0d", l, r, t, b); + g_object_set (ctx->vpp, "crop-left", l, "crop-right", r, + "crop-top", t, "crop-bottom", b, NULL); +} + +static void +vpp_test_set_dimensions (VppTestContext * ctx, gint w, gint h) +{ + GST_LOG ("%dx%d", w, h); + GstCaps *caps = gst_caps_new_simple ("video/x-raw", + "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL); + g_object_set (ctx->filter, "caps", caps, NULL); + gst_caps_unref (caps); +} + +static GstPadProbeReturn +cb_mouse_event (GstPad * pad, GstPadProbeInfo * info, gpointer data) +{ + VppTestCoordinate *coord = data; + GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info); + + if (GST_EVENT_TYPE (event) == GST_EVENT_NAVIGATION) { + switch (gst_navigation_event_get_type (event)) { + case GST_NAVIGATION_EVENT_MOUSE_MOVE: + gst_navigation_event_parse_mouse_move_event (event, &coord->x, + &coord->y); + break; + case GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS: + case GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE: + gst_navigation_event_parse_mouse_button_event (event, NULL, &coord->x, + &coord->y); + break; + default: + break; + } + } + + return GST_PAD_PROBE_OK; +} + +static void +vpp_test_mouse_events (VppTestContext * ctx, + const VppTestCoordinateParams * const params, const size_t nparams) +{ + GstStructure *structure; + GstEvent *event; + VppTestCoordinate probed; + guint i, j; + + /* probe mouse events propagated up from vaapipostproc */ + GstPad *pad = gst_element_get_static_pad (ctx->source, "src"); + gulong id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM, + (GstPadProbeCallback) cb_mouse_event, &probed, NULL); + + const char *mouse_events[] = { + "mouse-move", + "mouse-button-press", + "mouse-button-release", + }; + + fail_unless (gst_element_set_state (ctx->pipeline, GST_STATE_PAUSED) + != GST_STATE_CHANGE_FAILURE); + fail_unless (gst_element_get_state (ctx->pipeline, NULL, NULL, -1) + == GST_STATE_CHANGE_SUCCESS); + + for (i = 0; i < nparams; ++i) { + for (j = 0; j < G_N_ELEMENTS (mouse_events); ++j) { + probed.x = probed.y = -1; + + GST_LOG ("sending %s event %fx%f", mouse_events[j], params[i].send.x, + params[i].send.y); + structure = gst_structure_new ("application/x-gst-navigation", "event", + G_TYPE_STRING, mouse_events[j], + "pointer_x", G_TYPE_DOUBLE, params[i].send.x, + "pointer_y", G_TYPE_DOUBLE, params[i].send.y, NULL); + event = gst_event_new_navigation (structure); + gst_element_send_event (ctx->pipeline, event); + + GST_LOG ("probed %s event %fx%f", mouse_events[j], probed.x, probed.y); + + fail_unless (params[i].expect.x == probed.x); + fail_unless (params[i].expect.y == probed.y); + } + } + + gst_element_set_state (ctx->pipeline, GST_STATE_NULL); + + gst_pad_remove_probe (pad, id); + gst_object_unref (pad); +} + +static void +vpp_test_crop_mouse_events (VppTestContext * ctx, gint w, gint h, gint l, + gint r, gint t, gint b) +{ + const gdouble xmin = 0.0; + const gdouble ymin = 0.0; + const gdouble xmax = w - (l + r) - 1; + const gdouble ymax = h - (t + b) - 1; + const gdouble xctr = xmax / 2; + const gdouble yctr = ymax / 2; + const gdouble xrand = g_random_double_range (xmin, xmax); + const gdouble yrand = g_random_double_range (ymin, ymax); + + const gdouble e_xmin = xmin + l; + const gdouble e_ymin = ymin + t; + const gdouble e_xmax = xmax + l; + const gdouble e_ymax = ymax + t; + const gdouble e_xctr = xctr + l; + const gdouble e_yctr = yctr + t; + const gdouble e_xrand = xrand + l; + const gdouble e_yrand = yrand + t; + + const VppTestCoordinateParams params[] = { + {{xmin, ymin}, {e_xmin, e_ymin}}, /* left-top */ + {{xmin, yctr}, {e_xmin, e_yctr}}, /* left-center */ + {{xmin, ymax}, {e_xmin, e_ymax}}, /* left-bottom */ + + {{xmax, ymin}, {e_xmax, e_ymin}}, /* right-top */ + {{xmax, yctr}, {e_xmax, e_yctr}}, /* right-center */ + {{xmax, ymax}, {e_xmax, e_ymax}}, /* right-bottom */ + + {{xctr, ymin}, {e_xctr, e_ymin}}, /* center-top */ + {{xctr, yctr}, {e_xctr, e_yctr}}, /* center */ + {{xctr, ymax}, {e_xctr, e_ymax}}, /* center-bottom */ + + {{xrand, yrand}, {e_xrand, e_yrand}}, /* random */ + }; + + vpp_test_set_dimensions (ctx, w, h); + vpp_test_set_crop (ctx, l, r, t, b); + vpp_test_mouse_events (ctx, params, G_N_ELEMENTS (params)); +} + +GST_START_TEST (test_crop_mouse_events) +{ + VppTestContext ctx; + + vpp_test_init_context (&ctx); + + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 1, 0, 0, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 1, 0, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 1, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 1); + vpp_test_crop_mouse_events (&ctx, 160, 160, 63, 0, 0, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 63, 0, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 63, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 63); + vpp_test_crop_mouse_events (&ctx, 160, 160, 63, 0, 0, 1); + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 63, 1, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 1, 63, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 1, 0, 0, 63); + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 32, 0, 0, 128); + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 32, 128, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 128, 32, 0); + vpp_test_crop_mouse_events (&ctx, 160, 160, 128, 0, 0, 32); + vpp_test_crop_mouse_events (&ctx, 160, 160, 1, 1, 1, 1); + vpp_test_crop_mouse_events (&ctx, 160, 160, 63, 63, 63, 63); + vpp_test_crop_mouse_events (&ctx, 160, 160, 64, 64, 64, 64); + + vpp_test_deinit_context (&ctx); +} + +GST_END_TEST; + static Suite * vaapipostproc_suite (void) { @@ -46,6 +274,7 @@ vaapipostproc_suite (void) suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_make); + tcase_add_test (tc_chain, test_crop_mouse_events); return s; } diff --git a/tests/check/meson.build b/tests/check/meson.build index 1b2a4a01dd..7ebe8a8fc5 100644 --- a/tests/check/meson.build +++ b/tests/check/meson.build @@ -2,7 +2,7 @@ tests = [ [ 'elements/vaapipostproc' ], ] -test_deps = [gst_dep, gstcheck_dep] +test_deps = [gst_dep, gstbase_dep, gstvideo_dep, gstcheck_dep] test_defines = [ '-UG_DISABLE_ASSERT', '-UG_DISABLE_CAST_CHECKS', From 1c3b02daf2fed53fa9ca7267d458bd5f6baefe73 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Wed, 9 Oct 2019 15:13:09 -0700 Subject: [PATCH 3410/3781] tests: check: vaapipostproc test_orientation_mouse_events Test that vaapipostproc properly translates mouse events when using video-direction (orientation). --- tests/check/elements/vaapipostproc.c | 106 +++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/tests/check/elements/vaapipostproc.c b/tests/check/elements/vaapipostproc.c index 82b894fbbc..d3a8be7ef3 100644 --- a/tests/check/elements/vaapipostproc.c +++ b/tests/check/elements/vaapipostproc.c @@ -104,6 +104,13 @@ vpp_test_set_crop (VppTestContext * ctx, gint l, gint r, gint t, gint b) "crop-top", t, "crop-bottom", b, NULL); } +static void +vpp_test_set_orientation (VppTestContext * ctx, GstVideoOrientationMethod m) +{ + GST_LOG ("%u", m); + g_object_set (ctx->vpp, "video-direction", m, NULL); +} + static void vpp_test_set_dimensions (VppTestContext * ctx, gint w, gint h) { @@ -178,6 +185,8 @@ vpp_test_mouse_events (VppTestContext * ctx, gst_element_send_event (ctx->pipeline, event); GST_LOG ("probed %s event %fx%f", mouse_events[j], probed.x, probed.y); + GST_LOG ("expect %s event %fx%f", mouse_events[j], params[i].expect.x, + params[i].expect.y); fail_unless (params[i].expect.x == probed.x); fail_unless (params[i].expect.y == probed.y); @@ -266,6 +275,102 @@ GST_START_TEST (test_crop_mouse_events) GST_END_TEST; +static void +vpp_test_orientation_mouse_events (VppTestContext * ctx, gint w, gint h) +{ + size_t i; + const gdouble xmin = 0.0; + const gdouble ymin = 0.0; + const gdouble xmax = w - 1; + const gdouble ymax = h - 1; + const VppTestCoordinateParams params[8][4] = { + /* (0) identity */ + { + {{xmin, ymin}, {xmin, ymin}}, + {{xmax, ymin}, {xmax, ymin}}, + {{xmin, ymax}, {xmin, ymax}}, + {{xmax, ymax}, {xmax, ymax}}, + }, + /* (1) 90 Rotation */ + { + {{ymin, xmin}, {xmin, ymax}}, + {{ymax, xmin}, {xmin, ymin}}, + {{ymin, xmax}, {xmax, ymax}}, + {{ymax, xmax}, {xmax, ymin}}, + }, + /* (2) 180 Rotation */ + { + {{xmin, ymin}, {xmax, ymax}}, + {{xmax, ymin}, {xmin, ymax}}, + {{xmin, ymax}, {xmax, ymin}}, + {{xmax, ymax}, {xmin, ymin}}, + }, + /* (3) 270 Rotation */ + { + {{ymin, xmin}, {xmax, ymin}}, + {{ymax, xmin}, {xmax, ymax}}, + {{ymin, xmax}, {xmin, ymin}}, + {{ymax, xmax}, {xmin, ymax}}, + }, + /* (4) Horizontal Flip */ + { + {{xmin, ymin}, {xmax, ymin}}, + {{xmax, ymin}, {xmin, ymin}}, + {{xmin, ymax}, {xmax, ymax}}, + {{xmax, ymax}, {xmin, ymax}}, + }, + /* (5) Vertical Flip */ + { + {{xmin, ymin}, {xmin, ymax}}, + {{xmax, ymin}, {xmax, ymax}}, + {{xmin, ymax}, {xmin, ymin}}, + {{xmax, ymax}, {xmax, ymin}}, + }, + /* (6) Vertical Flip + 90 Rotation */ + { + {{ymin, xmin}, {xmin, ymin}}, + {{ymax, xmin}, {xmin, ymax}}, + {{ymin, xmax}, {xmax, ymin}}, + {{ymax, xmax}, {xmax, ymax}}, + }, + /* (7) Horizontal Flip + 90 Rotation */ + { + {{ymin, xmin}, {xmax, ymax}}, + {{ymax, xmin}, {xmax, ymin}}, + {{ymin, xmax}, {xmin, ymax}}, + {{ymax, xmax}, {xmin, ymin}}, + }, + }; + + vpp_test_set_dimensions (ctx, w, h); + + for (i = 0; i < 8; ++i) { + vpp_test_set_orientation (ctx, i); + vpp_test_mouse_events (ctx, params[i], 4); + } +} + +GST_START_TEST (test_orientation_mouse_events) +{ + VppTestContext ctx; + + vpp_test_init_context (&ctx); + + vpp_test_orientation_mouse_events (&ctx, 160, 320); + vpp_test_orientation_mouse_events (&ctx, 161, 320); + vpp_test_orientation_mouse_events (&ctx, 160, 321); + vpp_test_orientation_mouse_events (&ctx, 161, 321); + + vpp_test_orientation_mouse_events (&ctx, 320, 160); + vpp_test_orientation_mouse_events (&ctx, 320, 161); + vpp_test_orientation_mouse_events (&ctx, 321, 160); + vpp_test_orientation_mouse_events (&ctx, 321, 161); + + vpp_test_deinit_context (&ctx); +} + +GST_END_TEST; + static Suite * vaapipostproc_suite (void) { @@ -275,6 +380,7 @@ vaapipostproc_suite (void) suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_make); tcase_add_test (tc_chain, test_crop_mouse_events); + tcase_add_test (tc_chain, test_orientation_mouse_events); return s; } From a8be3698406a97a98ce87216275892a110317689 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 6 Nov 2019 22:37:12 +0800 Subject: [PATCH 3411/3781] libs: video-format: change GST_VIDEO_FORMAT_AYUV to VUYA. We only support VUYA format in gst vaapi now, need to correct the mapping. --- gst-libs/gst/vaapi/video-format.c | 2 +- tests/internal/test-windows.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 1463c0e7a9..eac6ac5c8a 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -445,7 +445,7 @@ gst_vaapi_video_format_from_chroma (guint chroma_type) case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: return GST_VIDEO_FORMAT_P010_10LE; case GST_VAAPI_CHROMA_TYPE_YUV444: - return GST_VIDEO_FORMAT_AYUV; + return GST_VIDEO_FORMAT_VUYA; case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: return GST_VIDEO_FORMAT_Y210; case GST_VAAPI_CHROMA_TYPE_YUV444_10BPP: diff --git a/tests/internal/test-windows.c b/tests/internal/test-windows.c index 4985e350da..595be3fe1d 100644 --- a/tests/internal/test-windows.c +++ b/tests/internal/test-windows.c @@ -62,7 +62,7 @@ create_test_surface (GstVaapiDisplay * display, guint width, guint height) GST_VIDEO_FORMAT_NV12, GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_I420, - GST_VIDEO_FORMAT_AYUV, + GST_VIDEO_FORMAT_VUYA, GST_VIDEO_FORMAT_ARGB, GST_VIDEO_FORMAT_BGRA, GST_VIDEO_FORMAT_RGBA, From f16c93a187f6bb682a86a2540ee9158c3ad9d398 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 31 Oct 2019 00:59:34 +0800 Subject: [PATCH 3412/3781] libs: video-format: add GST_VAAPI_FORMATS_ALL GST_VAAPI_FORMATS_ALL collects all declared formats in video-format as a caps template string, and make them available in caps with memory:VASurface feature. Fixes: #199 --- gst-libs/gst/vaapi/video-format.c | 3 +++ gst-libs/gst/vaapi/video-format.h | 5 +++++ gst/vaapi/gstvaapipluginutil.h | 14 +++++++------- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index eac6ac5c8a..023a896633 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -58,6 +58,9 @@ typedef struct _GstVideoFormatMapMap { VA_FOURCC FOURCC, BYTE_ORDER, BPP, DEPTH, R, G, B, A }, } /* Image formats, listed in HW order preference */ +/* XXX: The new added video format must be added to + * GST_VAAPI_FORMATS_ALL in header file to make it available to all + * vaapi element's pad cap template. */ /* *INDENT-OFF* */ static const GstVideoFormatMap gst_vaapi_video_default_formats[] = { /* LSB and MSB video formats definitions are unclear and ambiguous. diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index cef8c504a7..466e115a2d 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -29,6 +29,11 @@ G_BEGIN_DECLS +#define GST_VAAPI_FORMATS_ALL "{ ENCODED, " \ + "NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, " \ + "ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE " \ + "}" + const gchar * gst_vaapi_video_format_to_string (GstVideoFormat format); diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 293b40924f..bba668b7cd 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -103,16 +103,16 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps, # define GST_CAPS_INTERLACED_FALSE \ "interlace-mode = (string)progressive" -#define GST_VAAPI_MAKE_SURFACE_CAPS \ - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ - GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410, Y444 }") +#define GST_VAAPI_MAKE_SURFACE_CAPS \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ + GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, GST_VAAPI_FORMATS_ALL) -#define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \ - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ +#define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "{ RGBA, BGRA }") -#define GST_VAAPI_MAKE_DMABUF_CAPS \ - GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ +#define GST_VAAPI_MAKE_DMABUF_CAPS \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ GST_CAPS_FEATURE_MEMORY_DMABUF, "{ I420, YV12, RGBA }") G_GNUC_INTERNAL From 6fb5387d5b420fd2333b6e3617909aeaf6506dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 27 Nov 2019 01:44:05 +0100 Subject: [PATCH 3413/3781] libs: video-format: remove dead code --- gst-libs/gst/vaapi/video-format.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 023a896633..5302fdf09f 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -32,12 +32,6 @@ #include "gstvaapisurface.h" #include "video-format.h" -#if G_BYTE_ORDER == G_BIG_ENDIAN -# define VIDEO_VA_ENDIANESS VA_MSB_FIRST -#elif G_BYTE_ORDER == G_LITTLE_ENDIAN -# define VIDEO_VA_ENDIANESS VA_LSB_FIRST -#endif - typedef struct _GstVideoFormatMapMap { GstVideoFormat format; From 1168d6d5481a4d3cd83847b0ff7239231c29df5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 3 Nov 2019 17:59:01 +0100 Subject: [PATCH 3414/3781] libs: decoder: h265: skip all pictures prior the first I-frame Don't try to decode until the first I-frame is received within the currently active sequence. i965 H265 decoder don't show any artifact but it crashes. Fixes: #98 --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 24 ++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index a04c74b8ee..5d554fce46 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -334,6 +334,8 @@ typedef enum GST_H265_VIDEO_STATE_GOT_SPS = 1 << 1, GST_H265_VIDEO_STATE_GOT_PPS = 1 << 2, GST_H265_VIDEO_STATE_GOT_SLICE = 1 << 3, + GST_H265_VIDEO_STATE_GOT_I_FRAME = 1 << 4, /* persistent across SPS */ + GST_H265_VIDEO_STATE_GOT_P_SLICE = 1 << 5, /* predictive (all non-intra) */ GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS = (GST_H265_VIDEO_STATE_GOT_SPS | GST_H265_VIDEO_STATE_GOT_PPS), @@ -583,6 +585,11 @@ ensure_sps (GstVaapiDecoderH265 * decoder, GstH265SPS * sps) GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiParserInfoH265 *const pi = priv->sps[sps->id]; + /* Propagate "got I-frame" state to the next SPS unit if the current + * sequence was not ended */ + if (pi && priv->active_sps) + pi->state |= (priv->active_sps->state & GST_H265_VIDEO_STATE_GOT_I_FRAME); + gst_vaapi_parser_info_h265_replace (&priv->active_sps, pi); return pi ? &pi->data.sps : NULL; } @@ -1317,12 +1324,20 @@ static GstVaapiDecoderStatus decode_current_picture (GstVaapiDecoderH265 * decoder) { GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstVaapiParserInfoH265 *const sps_pi = decoder->priv.active_sps; GstVaapiPictureH265 *const picture = priv->current_picture; if (!is_valid_state (priv->decoder_state, GST_H265_VIDEO_STATE_VALID_PICTURE)) { goto drop_frame; } + priv->decoder_state |= sps_pi->state; + if (!(priv->decoder_state & GST_H265_VIDEO_STATE_GOT_I_FRAME)) { + if (priv->decoder_state & GST_H265_VIDEO_STATE_GOT_P_SLICE) + goto drop_frame; + sps_pi->state |= GST_H265_VIDEO_STATE_GOT_I_FRAME; + } + priv->decoder_state = 0; /* FIXME: Use SEI header values */ priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; @@ -1459,6 +1474,8 @@ parse_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) return get_status (result); priv->parser_state |= GST_H265_VIDEO_STATE_GOT_SLICE; + if (!GST_H265_IS_I_SLICE (slice_hdr)) + priv->parser_state |= GST_H265_VIDEO_STATE_GOT_P_SLICE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1548,9 +1565,15 @@ static GstVaapiDecoderStatus decode_sequence_end (GstVaapiDecoderH265 * decoder) { GstVaapiDecoderStatus status; + GstVaapiParserInfoH265 *const sps_pi = decoder->priv.active_sps; GST_DEBUG ("decode sequence-end"); + /* Sequence ended, don't try to propagate "got I-frame" state beyond + * this point */ + if (sps_pi) + sps_pi->state &= ~GST_H265_VIDEO_STATE_GOT_I_FRAME; + status = decode_current_picture (decoder); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) return status; @@ -2718,7 +2741,6 @@ decode_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) gst_vaapi_picture_add_slice (GST_VAAPI_PICTURE_CAST (picture), slice); picture->last_slice_hdr = slice_hdr; - priv->decoder_state |= GST_H265_VIDEO_STATE_GOT_SLICE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 506b6c53c5fb5aa4e90c828bee7a0bd4c292f79e Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Tue, 10 Dec 2019 18:40:42 -0300 Subject: [PATCH 3415/3781] Do not mix declaration and code --- tests/check/elements/vaapipostproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/check/elements/vaapipostproc.c b/tests/check/elements/vaapipostproc.c index d3a8be7ef3..1e892d9ade 100644 --- a/tests/check/elements/vaapipostproc.c +++ b/tests/check/elements/vaapipostproc.c @@ -114,9 +114,9 @@ vpp_test_set_orientation (VppTestContext * ctx, GstVideoOrientationMethod m) static void vpp_test_set_dimensions (VppTestContext * ctx, gint w, gint h) { - GST_LOG ("%dx%d", w, h); GstCaps *caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL); + GST_LOG ("%dx%d", w, h); g_object_set (ctx->filter, "caps", caps, NULL); gst_caps_unref (caps); } From 9d8467dc60c84b94866e3bb67146662c7689eb69 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 11 Dec 2019 14:11:13 +0800 Subject: [PATCH 3416/3781] libs: postproc: Modify src/sink template raw formats We need to provide more precise template caps for postproc's src and sink pads. The GST_VIDEO_FORMATS_ALL make all video formats available which are really superfluous. --- gst/vaapi/gstvaapipostproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 0c899d5bca..82c6b5fce2 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -61,7 +61,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapipostproc); static const char gst_vaapipostproc_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_MODES "; " - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_MODES; /* *INDENT-ON* */ @@ -72,7 +72,7 @@ static const char gst_vaapipostproc_src_caps_str[] = #if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS "; " #endif - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_MODES "; " GST_VAAPI_MAKE_DMABUF_CAPS; /* *INDENT-ON* */ From f4fc37ccc5d4762b15971983fb2920bc78a9a0eb Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 3 Dec 2019 00:52:45 +0800 Subject: [PATCH 3417/3781] libs: decoder: Modify decode src's template raw formats We do not need to maintain a standalone list of decoder's output template for raw formats and that is easy to make mistake(for example, the AYVU is wrong in that list, should be VUYA). Just use GST_VAAPI_FORMATS_ALL to replace the raw formats list for src template. --- gst/vaapi/gstvaapidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index a677d3796c..f4798f28e9 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -82,7 +82,7 @@ static const char gst_vaapidecode_src_caps_str[] = #if (USE_GLX || USE_EGL) GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" #endif - GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410, Y444 }") ";" + GST_VIDEO_CAPS_MAKE(GST_VAAPI_FORMATS_ALL) ";" GST_VAAPI_MAKE_DMABUF_CAPS; static GstStaticPadTemplate gst_vaapidecode_src_factory = From b384593d3d7a6ac5e300768340ecd4def6ed7d51 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 29 Oct 2019 15:13:44 -0700 Subject: [PATCH 3418/3781] plugins: use plugin base macros to access pad specific data Don't access base struct fields directly since the underlying definition can change. Instead, use the accessor macros. --- gst/vaapi/gstvaapidecode.c | 12 ++++++++---- gst/vaapi/gstvaapiencode.c | 2 +- gst/vaapi/gstvaapipluginbase.h | 8 ++++++++ gst/vaapi/gstvaapipostproc.c | 9 +++++---- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f4798f28e9..3acfe4f935 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -499,7 +499,9 @@ is_src_allocator_dmabuf (GstVaapiDecode * decode) if (!GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (plugin)) return FALSE; - return gst_vaapi_is_dmabuf_allocator (plugin->srcpad_allocator); + return + gst_vaapi_is_dmabuf_allocator (GST_VAAPI_PLUGIN_BASE_SRC_PAD_ALLOCATOR + (plugin)); } static GstFlowReturn @@ -596,9 +598,11 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, GstBuffer *sys_buf, *va_buf; va_buf = out_frame->output_buffer; - sys_buf = gst_buffer_new_allocate (plugin->other_srcpad_allocator, - GST_VIDEO_INFO_SIZE (&plugin->srcpad_info), - &plugin->other_allocator_params); + sys_buf = + gst_buffer_new_allocate (GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR + (plugin), + GST_VIDEO_INFO_SIZE (GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO (plugin)), + &GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR_PARAMS (plugin)); if (!sys_buf) goto error_no_sys_buffer; diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index d833f79e48..46b4737d01 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -888,7 +888,7 @@ gst_vaapiencode_init (GstVaapiEncode * encode) GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (encode); gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (encode), GST_CAT_DEFAULT); - gst_pad_use_fixed_caps (plugin->srcpad); + gst_pad_use_fixed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (plugin)); } static void diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 9faa063952..774c4c3b8c 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -85,6 +85,14 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (&GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_info) #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_can_dmabuf) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_BUFFER_POOL(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_buffer_pool) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_ALLOCATOR(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_allocator) +#define GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->other_srcpad_allocator) +#define GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR_PARAMS(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->other_allocator_params) #define GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->copy_output_frame) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 82c6b5fce2..d40f39951d 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -379,7 +379,7 @@ create_output_buffer (GstVaapiPostproc * postproc) GstBuffer *outbuf; GstBufferPool *const pool = - GST_VAAPI_PLUGIN_BASE (postproc)->srcpad_buffer_pool; + GST_VAAPI_PLUGIN_BASE_SRC_PAD_BUFFER_POOL (postproc); GstFlowReturn ret; g_return_val_if_fail (pool != NULL, NULL); @@ -412,9 +412,10 @@ create_output_dump_buffer (GstVaapiPostproc * postproc) { GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (postproc); - return gst_buffer_new_allocate (plugin->other_srcpad_allocator, - GST_VIDEO_INFO_SIZE (&plugin->srcpad_info), - &plugin->other_allocator_params); + return + gst_buffer_new_allocate (GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR (plugin), + GST_VIDEO_INFO_SIZE (GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO (plugin)), + &GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR_PARAMS (plugin)); } static void From ca2942176b5632e07eebac23336954f9aaf1cb26 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 12 Nov 2019 12:21:52 -0800 Subject: [PATCH 3419/3781] plugins: base: manage pad-specific data in a single struct Define a struct (GstVaapiPadPrivate) to encapsulate the pad-specific data (i.e. buffer pool, allocator, info, caps, etc.). Add an interface to retrieve the data struct for a given pad. Finally, update the base plugin to use the data struct throughout the implementation. This will enable us to easily extend the base plugin in the future to allow for N-to-1 pad subclasses (e.g. overlay/ composite). --- gst/vaapi/gstvaapipluginbase.c | 256 ++++++++++++++++++++------------- gst/vaapi/gstvaapipluginbase.h | 59 ++++---- 2 files changed, 195 insertions(+), 120 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 1753ad09d2..73d9e56d41 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -40,6 +40,44 @@ GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE); #define BUFFER_POOL_SINK_MIN_BUFFERS 2 +#define GST_VAAPI_PAD_PRIVATE(pad) \ + (GST_VAAPI_PLUGIN_BASE_GET_CLASS(plugin)->get_vaapi_pad_private(plugin, pad)) + +GstVaapiPadPrivate * +gst_vaapi_pad_private_new (void) +{ + GstVaapiPadPrivate *priv = g_new0 (GstVaapiPadPrivate, 1); + + gst_video_info_init (&priv->info); + + return priv; +} + +void +gst_vaapi_pad_private_reset (GstVaapiPadPrivate * priv) +{ + g_assert (priv); + + gst_caps_replace (&priv->caps, NULL); + gst_video_info_init (&priv->info); + + g_clear_object (&priv->buffer_pool); + g_clear_object (&priv->allocator); + + priv->buffer_size = 0; + priv->caps_is_raw = FALSE; + + g_clear_object (&priv->other_allocator); + priv->can_dmabuf = FALSE; +} + +void +gst_vaapi_pad_private_finalize (GstVaapiPadPrivate * priv) +{ + gst_vaapi_pad_private_reset (priv); + g_free (priv); +} + /* GstVideoContext interface */ static void plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) @@ -125,7 +163,8 @@ static gboolean plugin_update_sinkpad_info_from_buffer (GstVaapiPluginBase * plugin, GstBuffer * buf) { - GstVideoInfo *const vip = &plugin->sinkpad_info; + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); + GstVideoInfo *const vip = &sinkpriv->info; GstVideoMeta *vmeta; guint i; @@ -165,7 +204,8 @@ static gboolean plugin_bind_dma_to_vaapi_buffer (GstVaapiPluginBase * plugin, GstBuffer * inbuf, GstBuffer * outbuf) { - GstVideoInfo *const vip = &plugin->sinkpad_info; + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); + GstVideoInfo *const vip = &sinkpriv->info; GstVaapiVideoMeta *meta; GstVaapiSurface *surface; GstVaapiSurfaceProxy *proxy; @@ -228,11 +268,22 @@ plugin_reset_texture_map (GstVaapiPluginBase * plugin) gst_vaapi_display_reset_texture_map (plugin->display); } +static GstVaapiPadPrivate * +default_get_vaapi_pad_private (GstVaapiPluginBase * plugin, GstPad * pad) +{ + if (plugin->sinkpad == pad) + return plugin->sinkpriv; + + g_assert (plugin->srcpad == pad); + return plugin->srcpriv; +} + void gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) { klass->has_interface = default_has_interface; klass->display_changed = default_display_changed; + klass->get_vaapi_pad_private = default_get_vaapi_pad_private; } void @@ -245,12 +296,16 @@ gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin, /* sink pad */ plugin->sinkpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "sink"); - gst_video_info_init (&plugin->sinkpad_info); + + if (plugin->sinkpad) + plugin->sinkpriv = gst_vaapi_pad_private_new (); /* src pad */ if (!(GST_OBJECT_FLAGS (plugin) & GST_ELEMENT_FLAG_SINK)) plugin->srcpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "src"); - gst_video_info_init (&plugin->srcpad_info); + + if (plugin->srcpad) + plugin->srcpriv = gst_vaapi_pad_private_new (); plugin->enable_direct_rendering = (g_getenv ("GST_VAAPI_ENABLE_DIRECT_RENDERING") != NULL); @@ -261,6 +316,12 @@ gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin) { gst_vaapi_plugin_base_close (plugin); g_free (plugin->display_name); + + if (plugin->sinkpriv) + gst_vaapi_pad_private_finalize (plugin->sinkpriv); + if (plugin->srcpriv) + gst_vaapi_pad_private_finalize (plugin->srcpriv); + if (plugin->sinkpad) gst_object_unref (plugin->sinkpad); if (plugin->srcpad) @@ -300,19 +361,12 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) gst_object_replace (&plugin->gl_display, NULL); gst_object_replace (&plugin->gl_other_context, NULL); - gst_caps_replace (&plugin->sinkpad_caps, NULL); - gst_video_info_init (&plugin->sinkpad_info); - - g_clear_object (&plugin->sinkpad_buffer_pool); - g_clear_object (&plugin->srcpad_buffer_pool); - - g_clear_object (&plugin->sinkpad_allocator); - g_clear_object (&plugin->srcpad_allocator); - g_clear_object (&plugin->other_srcpad_allocator); - - gst_caps_replace (&plugin->srcpad_caps, NULL); - gst_video_info_init (&plugin->srcpad_info); gst_caps_replace (&plugin->allowed_raw_caps, NULL); + + if (plugin->sinkpriv) + gst_vaapi_pad_private_reset (plugin->sinkpriv); + if (plugin->srcpriv) + gst_vaapi_pad_private_reset (plugin->srcpriv); } /** @@ -438,6 +492,7 @@ static gboolean ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, guint * size) { + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); GstVideoInfo vinfo; const GstVideoInfo *image_info; GstVaapiImageUsageFlags usage_flag = @@ -446,7 +501,7 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, if (!gst_video_info_from_caps (&vinfo, caps)) goto error_invalid_caps; - if (!reset_allocator (plugin->sinkpad_allocator, &vinfo)) + if (!reset_allocator (sinkpriv->allocator, &vinfo)) goto bail; /* enable direct upload if upstream requests raw video */ @@ -454,15 +509,14 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD; GST_INFO_OBJECT (plugin, "enabling direct upload in sink allocator"); } - plugin->sinkpad_allocator = + sinkpriv->allocator = gst_vaapi_video_allocator_new (plugin->display, &vinfo, 0, usage_flag); bail: - if (!plugin->sinkpad_allocator) + if (!sinkpriv->allocator) goto error_create_allocator; - image_info = - gst_allocator_get_vaapi_video_info (plugin->sinkpad_allocator, NULL); + image_info = gst_allocator_get_vaapi_video_info (sinkpriv->allocator, NULL); g_assert (image_info); /* allocator ought set its image info */ /* update the size with the one generated by the allocator */ @@ -532,25 +586,25 @@ static gboolean ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, GstCaps * caps) { + GstVaapiPadPrivate *srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad); const GstVideoInfo *image_info; - if (!reset_allocator (plugin->srcpad_allocator, vinfo)) + if (!reset_allocator (srcpriv->allocator, vinfo)) goto valid_allocator; - plugin->srcpad_allocator = NULL; + srcpriv->allocator = NULL; if (caps && gst_caps_is_video_raw (caps)) { GstAllocator *allocator = create_dmabuf_srcpad_allocator (plugin, vinfo, - !plugin->srcpad_can_dmabuf); - plugin->srcpad_allocator = allocator; + !srcpriv->can_dmabuf); + srcpriv->allocator = allocator; } else if (caps && gst_vaapi_caps_feature_contains (caps, GST_VAAPI_CAPS_FEATURE_DMABUF)) { - plugin->srcpad_allocator = - create_dmabuf_srcpad_allocator (plugin, vinfo, FALSE); - if (!plugin->srcpad_allocator) + srcpriv->allocator = create_dmabuf_srcpad_allocator (plugin, vinfo, FALSE); + if (!srcpriv->allocator) goto error_create_allocator; } - if (!plugin->srcpad_allocator) { + if (!srcpriv->allocator) { GstVaapiImageUsageFlags usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; @@ -559,16 +613,15 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); } - plugin->srcpad_allocator = + srcpriv->allocator = gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag); } - if (!plugin->srcpad_allocator) + if (!srcpriv->allocator) goto error_create_allocator; valid_allocator: - image_info = - gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, NULL); + image_info = gst_allocator_get_vaapi_video_info (srcpriv->allocator, NULL); g_assert (image_info); /* both allocators ought set its image * info */ @@ -580,15 +633,14 @@ valid_allocator: * different from the "negotiation caps". In this case, we should * indicate the allocator to store the negotiation caps since they * are the one should be used for frame mapping with GstVideoMeta */ - gboolean different_caps = plugin->srcpad_caps && - !gst_caps_is_strictly_equal (plugin->srcpad_caps, caps); + gboolean different_caps = srcpriv->caps && + !gst_caps_is_strictly_equal (srcpriv->caps, caps); const GstVideoInfo *previous_negotiated = - gst_allocator_get_vaapi_negotiated_video_info - (plugin->srcpad_allocator); + gst_allocator_get_vaapi_negotiated_video_info (srcpriv->allocator); if (different_caps) { guint i; - GstVideoInfo vi = plugin->srcpad_info; + GstVideoInfo vi = srcpriv->info; /* update the planes and the size with the allocator image/surface * info, but not the resolution */ @@ -599,11 +651,9 @@ valid_allocator: GST_VIDEO_INFO_PLANE_STRIDE (image_info, i); } GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (image_info); - gst_allocator_set_vaapi_negotiated_video_info (plugin->srcpad_allocator, - &vi); + gst_allocator_set_vaapi_negotiated_video_info (srcpriv->allocator, &vi); } else if (previous_negotiated) { - gst_allocator_set_vaapi_negotiated_video_info (plugin->srcpad_allocator, - NULL); + gst_allocator_set_vaapi_negotiated_video_info (srcpriv->allocator, NULL); } } return TRUE; @@ -703,6 +753,7 @@ error_pool_config: static gboolean ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) { + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); GstBufferPool *pool; guint size; @@ -713,13 +764,13 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) if (!gst_vaapi_plugin_base_ensure_display (plugin)) return FALSE; - if (plugin->sinkpad_buffer_pool) { - if (gst_vaapi_buffer_pool_caps_is_equal (plugin->sinkpad_buffer_pool, caps)) + if (sinkpriv->buffer_pool) { + if (gst_vaapi_buffer_pool_caps_is_equal (sinkpriv->buffer_pool, caps)) return TRUE; - gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, FALSE); - g_clear_object (&plugin->sinkpad_buffer_pool); - g_clear_object (&plugin->sinkpad_allocator); - plugin->sinkpad_buffer_size = 0; + gst_buffer_pool_set_active (sinkpriv->buffer_pool, FALSE); + g_clear_object (&sinkpriv->buffer_pool); + g_clear_object (&sinkpriv->allocator); + sinkpriv->buffer_size = 0; } if (!ensure_sinkpad_allocator (plugin, caps, &size)) @@ -728,12 +779,12 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, BUFFER_POOL_SINK_MIN_BUFFERS, 0, - GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, plugin->sinkpad_allocator); + GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, sinkpriv->allocator); if (!pool) return FALSE; - plugin->sinkpad_buffer_pool = pool; - plugin->sinkpad_buffer_size = size; + sinkpriv->buffer_pool = pool; + sinkpriv->buffer_size = size; return TRUE; } @@ -752,28 +803,41 @@ gboolean gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, GstCaps * outcaps) { - if (incaps && incaps != plugin->sinkpad_caps) { - if (!gst_video_info_from_caps (&plugin->sinkpad_info, incaps)) - return FALSE; - gst_caps_replace (&plugin->sinkpad_caps, incaps); - plugin->sinkpad_caps_is_raw = !gst_caps_has_vaapi_surface (incaps); + GstVaapiPadPrivate *sinkpriv = NULL; + GstVaapiPadPrivate *srcpriv = NULL; + + if (incaps) { + g_assert (plugin->sinkpad); + sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); } - if (outcaps && outcaps != plugin->srcpad_caps) { - if (!gst_video_info_from_caps (&plugin->srcpad_info, outcaps)) + if (incaps && incaps != sinkpriv->caps) { + if (!gst_video_info_from_caps (&sinkpriv->info, incaps)) return FALSE; - if (plugin->srcpad_buffer_pool - && !gst_vaapi_buffer_pool_caps_is_equal (plugin->srcpad_buffer_pool, + gst_caps_replace (&sinkpriv->caps, incaps); + sinkpriv->caps_is_raw = !gst_caps_has_vaapi_surface (incaps); + } + + if (outcaps) { + g_assert (plugin->srcpad); + srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad); + } + + if (outcaps && outcaps != srcpriv->caps) { + if (!gst_video_info_from_caps (&srcpriv->info, outcaps)) + return FALSE; + if (srcpriv->buffer_pool + && !gst_vaapi_buffer_pool_caps_is_equal (srcpriv->buffer_pool, outcaps)) { - gst_buffer_pool_set_active (plugin->srcpad_buffer_pool, FALSE); - g_clear_object (&plugin->srcpad_buffer_pool); - g_clear_object (&plugin->srcpad_allocator); + gst_buffer_pool_set_active (srcpriv->buffer_pool, FALSE); + g_clear_object (&srcpriv->buffer_pool); + g_clear_object (&srcpriv->allocator); plugin_reset_texture_map (plugin); } - gst_caps_replace (&plugin->srcpad_caps, outcaps); + gst_caps_replace (&srcpriv->caps, outcaps); } - if (!ensure_sinkpad_buffer_pool (plugin, plugin->sinkpad_caps)) + if (incaps && !ensure_sinkpad_buffer_pool (plugin, sinkpriv->caps)) return FALSE; return TRUE; } @@ -791,6 +855,7 @@ gboolean gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, GstQuery * query) { + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); GstCaps *caps = NULL; GstBufferPool *pool = NULL; gboolean need_pool; @@ -806,8 +871,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, if (need_pool) { pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, BUFFER_POOL_SINK_MIN_BUFFERS, 0, - GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, - plugin->sinkpad_allocator); + GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, sinkpriv->allocator); if (!pool) return FALSE; } @@ -825,7 +889,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, gst_query_add_allocation_param (query, allocator, NULL); gst_object_unref (allocator); } - gst_query_add_allocation_param (query, plugin->sinkpad_allocator, NULL); + gst_query_add_allocation_param (query, sinkpriv->allocator, NULL); gst_query_add_allocation_pool (query, pool, size, BUFFER_POOL_SINK_MIN_BUFFERS, 0); @@ -859,6 +923,7 @@ gboolean gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GstQuery * query) { + GstVaapiPadPrivate *srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad); GstCaps *caps = NULL; GstBufferPool *pool; GstVideoInfo vi; @@ -928,10 +993,10 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, * new buffer */ if (i == 0 && g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) != 0) { - if (plugin->other_srcpad_allocator) - gst_object_unref (plugin->other_srcpad_allocator); - plugin->other_srcpad_allocator = allocator; - plugin->other_allocator_params = params; + if (srcpriv->other_allocator) + gst_object_unref (srcpriv->other_allocator); + srcpriv->other_allocator = allocator; + srcpriv->other_allocator_params = params; continue; } @@ -939,9 +1004,9 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GST_DEBUG_OBJECT (plugin, "found vaapi allocator in query %" GST_PTR_FORMAT, allocator); index_allocator = i; - if (plugin->srcpad_allocator) - gst_object_unref (plugin->srcpad_allocator); - plugin->srcpad_allocator = allocator; + if (srcpriv->allocator) + gst_object_unref (srcpriv->allocator); + srcpriv->allocator = allocator; break; } gst_object_unref (allocator); @@ -978,7 +1043,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, size = GST_VIDEO_INFO_SIZE (&vi); /* size might be updated by * allocator */ pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, min, max, - pool_options, plugin->srcpad_allocator); + pool_options, srcpriv->allocator); if (!pool) goto error; } @@ -989,19 +1054,19 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gst_query_add_allocation_pool (query, pool, size, min, max); /* allocator might be updated by ensure_srcpad_allocator() */ - if (plugin->srcpad_allocator) { + if (srcpriv->allocator) { if (index_allocator > 0) { gst_query_set_nth_allocation_param (query, index_allocator, - plugin->srcpad_allocator, NULL); + srcpriv->allocator, NULL); } else { GST_DEBUG_OBJECT (plugin, "adding allocator in query %" GST_PTR_FORMAT, - plugin->srcpad_allocator); - gst_query_add_allocation_param (query, plugin->srcpad_allocator, NULL); + srcpriv->allocator); + gst_query_add_allocation_param (query, srcpriv->allocator, NULL); } } - g_clear_object (&plugin->srcpad_buffer_pool); - plugin->srcpad_buffer_pool = pool; + g_clear_object (&srcpriv->buffer_pool); + srcpriv->buffer_pool = pool; /* if downstream doesn't support GstVideoMeta, and the negotiated * caps are raw video, and the used allocator is the VA-API one, we @@ -1051,6 +1116,7 @@ GstFlowReturn gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, GstBuffer * inbuf, GstBuffer ** outbuf_ptr) { + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); GstVaapiVideoMeta *meta; GstBuffer *outbuf; GstVideoFrame src_frame, out_frame; @@ -1065,18 +1131,18 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, return GST_FLOW_OK; } - if (!plugin->sinkpad_caps_is_raw) + if (!sinkpriv->caps_is_raw) goto error_invalid_buffer; - if (!plugin->sinkpad_buffer_pool) + if (!sinkpriv->buffer_pool) goto error_no_pool; - if (!gst_buffer_pool_is_active (plugin->sinkpad_buffer_pool) && - !gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, TRUE)) + if (!gst_buffer_pool_is_active (sinkpriv->buffer_pool) && + !gst_buffer_pool_set_active (sinkpriv->buffer_pool, TRUE)) goto error_active_pool; outbuf = NULL; - if (gst_buffer_pool_acquire_buffer (plugin->sinkpad_buffer_pool, + if (gst_buffer_pool_acquire_buffer (sinkpriv->buffer_pool, &outbuf, NULL) != GST_FLOW_OK) goto error_create_buffer; @@ -1086,12 +1152,10 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, goto done; } - if (!gst_video_frame_map (&src_frame, &plugin->sinkpad_info, inbuf, - GST_MAP_READ)) + if (!gst_video_frame_map (&src_frame, &sinkpriv->info, inbuf, GST_MAP_READ)) goto error_map_src_buffer; - if (!gst_video_frame_map (&out_frame, &plugin->sinkpad_info, outbuf, - GST_MAP_WRITE)) + if (!gst_video_frame_map (&out_frame, &sinkpriv->info, outbuf, GST_MAP_WRITE)) goto error_map_dst_buffer; success = gst_video_frame_copy (&out_frame, &src_frame); @@ -1419,9 +1483,10 @@ gst_vaapi_plugin_base_set_srcpad_can_dmabuf (GstVaapiPluginBase * plugin, GstObject * object) { #if USE_EGL && USE_GST_GL_HELPERS + GstVaapiPadPrivate *srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad); GstGLContext *const gl_context = GST_GL_CONTEXT (object); - plugin->srcpad_can_dmabuf = + srcpriv->can_dmabuf = (!(gst_gl_context_get_gl_api (gl_context) & GST_GL_API_GLES1) && gst_gl_context_check_feature (gl_context, "EGL_EXT_image_dma_buf_import")); @@ -1458,6 +1523,7 @@ gboolean gst_vaapi_plugin_copy_va_buffer (GstVaapiPluginBase * plugin, GstBuffer * inbuf, GstBuffer * outbuf) { + GstVaapiPadPrivate *srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad); GstVideoMeta *vmeta; GstVideoFrame src_frame, dst_frame; gboolean success; @@ -1473,11 +1539,9 @@ gst_vaapi_plugin_copy_va_buffer (GstVaapiPluginBase * plugin, _init_performance_debug (); GST_CAT_INFO (CAT_PERFORMANCE, "copying VA buffer to system memory buffer"); - if (!gst_video_frame_map (&src_frame, &plugin->srcpad_info, inbuf, - GST_MAP_READ)) + if (!gst_video_frame_map (&src_frame, &srcpriv->info, inbuf, GST_MAP_READ)) return FALSE; - if (!gst_video_frame_map (&dst_frame, &plugin->srcpad_info, outbuf, - GST_MAP_WRITE)) { + if (!gst_video_frame_map (&dst_frame, &srcpriv->info, outbuf, GST_MAP_WRITE)) { gst_video_frame_unmap (&src_frame); return FALSE; } diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 774c4c3b8c..e98b451094 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -35,6 +35,7 @@ G_BEGIN_DECLS typedef struct _GstVaapiPluginBase GstVaapiPluginBase; typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; +typedef struct _GstVaapiPadPrivate GstVaapiPadPrivate; #define GST_VAAPI_PLUGIN_BASE(plugin) \ ((GstVaapiPluginBase *)(plugin)) @@ -73,26 +74,32 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; #define GST_VAAPI_PLUGIN_BASE_SINK_PAD(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad) +#define GST_VAAPI_PLUGIN_BASE_SINK_PAD_PRIVATE(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpriv) #define GST_VAAPI_PLUGIN_BASE_SINK_PAD_CAPS(plugin) \ - (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_caps) + (GST_VAAPI_PLUGIN_BASE_SINK_PAD_PRIVATE(plugin)->caps) #define GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO(plugin) \ - (&GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_info) + (&GST_VAAPI_PLUGIN_BASE_SINK_PAD_PRIVATE(plugin)->info) + #define GST_VAAPI_PLUGIN_BASE_SRC_PAD(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad) +#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->srcpriv) #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS(plugin) \ - (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_caps) + (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->caps) #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO(plugin) \ - (&GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_info) + (&GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->info) #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF(plugin) \ - (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_can_dmabuf) + (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->can_dmabuf) #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_BUFFER_POOL(plugin) \ - (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_buffer_pool) + (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->buffer_pool) #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_ALLOCATOR(plugin) \ - (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_allocator) + (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->allocator) #define GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR(plugin) \ - (GST_VAAPI_PLUGIN_BASE(plugin)->other_srcpad_allocator) + (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->other_allocator) #define GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR_PARAMS(plugin) \ - (GST_VAAPI_PLUGIN_BASE(plugin)->other_allocator_params) + (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->other_allocator_params) + #define GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME(plugin) \ (GST_VAAPI_PLUGIN_BASE(plugin)->copy_output_frame) @@ -116,6 +123,21 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; GST_ELEMENT_CLASS (parent_class)->set_context (element, context); \ } +struct _GstVaapiPadPrivate +{ + GstCaps *caps; + GstVideoInfo info; + GstBufferPool *buffer_pool; + GstAllocator *allocator; + guint buffer_size; + gboolean caps_is_raw; + + gboolean can_dmabuf; + + GstAllocator *other_allocator; + GstAllocationParams other_allocator_params; +}; + struct _GstVaapiPluginBase { /*< private >*/ @@ -131,16 +153,10 @@ struct _GstVaapiPluginBase GstDebugCategory *debug_category; GstPad *sinkpad; - GstCaps *sinkpad_caps; - gboolean sinkpad_caps_is_raw; - GstVideoInfo sinkpad_info; - GstBufferPool *sinkpad_buffer_pool; - guint sinkpad_buffer_size; - GstPad *srcpad; - GstCaps *srcpad_caps; - GstVideoInfo srcpad_info; - GstBufferPool *srcpad_buffer_pool; + + GstVaapiPadPrivate *sinkpriv; + GstVaapiPadPrivate *srcpriv; GstVaapiDisplay *display; GstVaapiDisplayType display_type; @@ -152,14 +168,8 @@ struct _GstVaapiPluginBase GstObject *gl_other_context; GstCaps *allowed_raw_caps; - GstAllocator *sinkpad_allocator; - GstAllocator *srcpad_allocator; - gboolean srcpad_can_dmabuf; gboolean enable_direct_rendering; - - GstAllocator *other_srcpad_allocator; - GstAllocationParams other_allocator_params; gboolean copy_output_frame; }; @@ -177,6 +187,7 @@ struct _GstVaapiPluginBaseClass gboolean (*has_interface) (GstVaapiPluginBase * plugin, GType type); void (*display_changed) (GstVaapiPluginBase * plugin); + GstVaapiPadPrivate * (*get_vaapi_pad_private) (GstVaapiPluginBase * plugin, GstPad * pad); }; G_GNUC_INTERNAL From b1bab9a3178fc627fd1f119b2d88a3ee6e99d67e Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 14 Nov 2019 11:13:51 -0800 Subject: [PATCH 3420/3781] plugins: base: add GstPad param to internal helper functions The base plugin public API function implementations determine which pad should be passed to the internal helper functions. Currently, only the base plugin static sinkpad and static srcpad are supported/used. However, this change enables future API functions to be added that can accept a pad (i.e. request pad) from an element subclass (e.g. a GstVideoAggregator subclass). --- gst/vaapi/gstvaapipluginbase.c | 144 +++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 61 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 73d9e56d41..35714d0a37 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -161,9 +161,9 @@ _set_cached_surface (GstBuffer * buf, GstVaapiSurface * surface) static gboolean plugin_update_sinkpad_info_from_buffer (GstVaapiPluginBase * plugin, - GstBuffer * buf) + GstPad * sinkpad, GstBuffer * buf) { - GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (sinkpad); GstVideoInfo *const vip = &sinkpriv->info; GstVideoMeta *vmeta; guint i; @@ -201,10 +201,10 @@ is_dma_buffer (GstBuffer * buf) } static gboolean -plugin_bind_dma_to_vaapi_buffer (GstVaapiPluginBase * plugin, +plugin_bind_dma_to_vaapi_buffer (GstVaapiPluginBase * plugin, GstPad * sinkpad, GstBuffer * inbuf, GstBuffer * outbuf) { - GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (sinkpad); GstVideoInfo *const vip = &sinkpriv->info; GstVaapiVideoMeta *meta; GstVaapiSurface *surface; @@ -215,7 +215,7 @@ plugin_bind_dma_to_vaapi_buffer (GstVaapiPluginBase * plugin, if (fd < 0) return FALSE; - if (!plugin_update_sinkpad_info_from_buffer (plugin, inbuf)) + if (!plugin_update_sinkpad_info_from_buffer (plugin, sinkpad, inbuf)) goto error_update_sinkpad_info; meta = gst_buffer_get_vaapi_video_meta (outbuf); @@ -489,10 +489,10 @@ reset_allocator (GstAllocator * allocator, GstVideoInfo * vinfo) } static gboolean -ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, - guint * size) +ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstPad * sinkpad, + GstCaps * caps, guint * size) { - GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (sinkpad); GstVideoInfo vinfo; const GstVideoInfo *image_info; GstVaapiImageUsageFlags usage_flag = @@ -583,10 +583,10 @@ create_dmabuf_srcpad_allocator (GstVaapiPluginBase * plugin, } static gboolean -ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, - GstCaps * caps) +ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstPad * srcpad, + GstVideoInfo * vinfo, GstCaps * caps) { - GstVaapiPadPrivate *srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad); + GstVaapiPadPrivate *srcpriv = GST_VAAPI_PAD_PRIVATE (srcpad); const GstVideoInfo *image_info; if (!reset_allocator (srcpriv->allocator, vinfo)) @@ -743,17 +743,18 @@ error_pool_config: /** * ensure_sinkpad_buffer_pool: * @plugin: a #GstVaapiPluginBase - * @caps: the initial #GstCaps for the resulting buffer pool + * @sinkpad: the #GstPad to use for the resulting buffer pool * * Makes sure the sink pad video buffer pool is created with the - * appropriate @caps. + * appropriate caps defined in the @sinkpad. * * Returns: %TRUE if successful, %FALSE otherwise. */ static gboolean -ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) +ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstPad * sinkpad) { - GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (sinkpad); + GstCaps *caps = sinkpriv->caps; GstBufferPool *pool; guint size; @@ -773,7 +774,7 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) sinkpriv->buffer_size = 0; } - if (!ensure_sinkpad_allocator (plugin, caps, &size)) + if (!ensure_sinkpad_allocator (plugin, sinkpad, caps, &size)) return FALSE; pool = @@ -788,6 +789,59 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) return TRUE; } +static gboolean +_set_srcpad_caps (GstVaapiPluginBase * plugin, GstPad * srcpad, GstCaps * caps) +{ + GstVaapiPadPrivate *srcpriv = NULL; + + if (caps) { + g_assert (srcpad); + srcpriv = GST_VAAPI_PAD_PRIVATE (srcpad); + g_assert (srcpriv); + + if (caps != srcpriv->caps) { + if (!gst_video_info_from_caps (&srcpriv->info, caps)) + return FALSE; + if (srcpriv->buffer_pool + && !gst_vaapi_buffer_pool_caps_is_equal (srcpriv->buffer_pool, + caps)) { + gst_buffer_pool_set_active (srcpriv->buffer_pool, FALSE); + g_clear_object (&srcpriv->buffer_pool); + g_clear_object (&srcpriv->allocator); + plugin_reset_texture_map (plugin); + } + gst_caps_replace (&srcpriv->caps, caps); + } + } + + return TRUE; +} + +static gboolean +_set_sinkpad_caps (GstVaapiPluginBase * plugin, GstPad * sinkpad, + GstCaps * caps) +{ + GstVaapiPadPrivate *sinkpriv = NULL; + + if (caps) { + g_assert (sinkpad); + sinkpriv = GST_VAAPI_PAD_PRIVATE (sinkpad); + g_assert (sinkpriv); + + if (caps != sinkpriv->caps) { + if (!gst_video_info_from_caps (&sinkpriv->info, caps)) + return FALSE; + gst_caps_replace (&sinkpriv->caps, caps); + sinkpriv->caps_is_raw = !gst_caps_has_vaapi_surface (caps); + } + + if (!ensure_sinkpad_buffer_pool (plugin, sinkpad)) + return FALSE; + } + + return TRUE; +} + /** * gst_vaapi_plugin_base_set_caps: * @plugin: a #GstVaapiPluginBase @@ -795,7 +849,7 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) * @outcaps: the src pad (output) caps * * Notifies the base plugin object of the new input and output caps, - * obtained from the subclass. + * obtained from the subclass, on the base plugin static pads. * * Returns: %TRUE if the update of caps was successful, %FALSE otherwise. */ @@ -803,43 +857,8 @@ gboolean gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, GstCaps * outcaps) { - GstVaapiPadPrivate *sinkpriv = NULL; - GstVaapiPadPrivate *srcpriv = NULL; - - if (incaps) { - g_assert (plugin->sinkpad); - sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); - } - - if (incaps && incaps != sinkpriv->caps) { - if (!gst_video_info_from_caps (&sinkpriv->info, incaps)) - return FALSE; - gst_caps_replace (&sinkpriv->caps, incaps); - sinkpriv->caps_is_raw = !gst_caps_has_vaapi_surface (incaps); - } - - if (outcaps) { - g_assert (plugin->srcpad); - srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad); - } - - if (outcaps && outcaps != srcpriv->caps) { - if (!gst_video_info_from_caps (&srcpriv->info, outcaps)) - return FALSE; - if (srcpriv->buffer_pool - && !gst_vaapi_buffer_pool_caps_is_equal (srcpriv->buffer_pool, - outcaps)) { - gst_buffer_pool_set_active (srcpriv->buffer_pool, FALSE); - g_clear_object (&srcpriv->buffer_pool); - g_clear_object (&srcpriv->allocator); - plugin_reset_texture_map (plugin); - } - gst_caps_replace (&srcpriv->caps, outcaps); - } - - if (incaps && !ensure_sinkpad_buffer_pool (plugin, sinkpriv->caps)) - return FALSE; - return TRUE; + return _set_sinkpad_caps (plugin, plugin->sinkpad, incaps) + && _set_srcpad_caps (plugin, plugin->srcpad, outcaps); } /** @@ -847,7 +866,8 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, * @plugin: a #GstVaapiPluginBase * @query: the allocation query to configure * - * Proposes allocation parameters to the upstream elements. + * Proposes allocation parameters to the upstream elements on the base plugin + * static sinkpad. * * Returns: %TRUE if successful, %FALSE otherwise. */ @@ -865,7 +885,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, if (!caps) goto error_no_caps; - if (!ensure_sinkpad_allocator (plugin, caps, &size)) + if (!ensure_sinkpad_allocator (plugin, plugin->sinkpad, caps, &size)) return FALSE; if (need_pool) { @@ -915,7 +935,8 @@ error_no_caps: * @feature: the desired #GstVaapiCapsFeature, or zero to find the * preferred one * - * Decides allocation parameters for the downstream elements. + * Decides allocation parameters for the downstream elements on the base + * plugin static srcpad. * * Returns: %TRUE if successful, %FALSE otherwise. */ @@ -1038,7 +1059,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, } if (!pool) { - if (!ensure_srcpad_allocator (plugin, &vi, caps)) + if (!ensure_srcpad_allocator (plugin, plugin->srcpad, &vi, caps)) goto error; size = GST_VIDEO_INFO_SIZE (&vi); /* size might be updated by * allocator */ @@ -1105,7 +1126,7 @@ error: * @inbuf: the sink pad (input) buffer * @outbuf_ptr: the pointer to location to the VA surface backed buffer * - * Acquires the sink pad (input) buffer as a VA surface backed + * Acquires the static sink pad (input) buffer as a VA surface backed * buffer. This is mostly useful for raw YUV buffers, as source * buffers that are already backed as a VA surface are passed * verbatim. @@ -1147,7 +1168,8 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, goto error_create_buffer; if (is_dma_buffer (inbuf)) { - if (!plugin_bind_dma_to_vaapi_buffer (plugin, inbuf, outbuf)) + if (!plugin_bind_dma_to_vaapi_buffer (plugin, plugin->sinkpad, inbuf, + outbuf)) goto error_bind_dma_buffer; goto done; } @@ -1474,7 +1496,7 @@ gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps (GstVaapiPluginBase * * @object: the GL context from gst-gl * * This function will determine if @object supports dmabuf - * importing. + * importing on the base plugin static srcpad. * * Please note that the context @object should come from downstream. **/ From 2cad0e56291c87f1b5e458c62a1e314f7cb2f8c9 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 16 Dec 2019 16:25:02 +0800 Subject: [PATCH 3421/3781] plugin: encode: set sink's raw caps to GST_VAAPI_FORMATS_ALL. Then encode plugin just supports raw formats declared in vaapi video format map. This modification makes the template caps more precise. --- gst/vaapi/gstvaapiencode_h264.c | 2 +- gst/vaapi/gstvaapiencode_h264_fei.c | 2 +- gst/vaapi/gstvaapiencode_h265.c | 2 +- gst/vaapi/gstvaapiencode_jpeg.c | 2 +- gst/vaapi/gstvaapiencode_mpeg2.c | 2 +- gst/vaapi/gstvaapiencode_vp8.c | 2 +- gst/vaapi/gstvaapiencode_vp9.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 4d452a092c..e1d91b67ea 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -82,7 +82,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); static const char gst_vaapiencode_h264_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_h264_fei.c b/gst/vaapi/gstvaapiencode_h264_fei.c index c09eaea854..c45e8d2aa9 100644 --- a/gst/vaapi/gstvaapiencode_h264_fei.c +++ b/gst/vaapi/gstvaapiencode_h264_fei.c @@ -62,7 +62,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_fei_encode_debug); static const char gst_vaapiencode_h264_fei_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index ed00a93872..711f5e1447 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -56,7 +56,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h265_encode_debug); static const char gst_vaapiencode_h265_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 0de5cb381b..d532429ecc 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -53,7 +53,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_jpeg_encode_debug); static const char gst_vaapiencode_jpeg_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 810de09f1f..a01042f6f6 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -55,7 +55,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); static const char gst_vaapiencode_mpeg2_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 64a3879f37..767ec38575 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -53,7 +53,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp8_encode_debug); static const char gst_vaapiencode_vp8_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index 97d2e13606..6fed2382fc 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -53,7 +53,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp9_encode_debug); static const char gst_vaapiencode_vp9_sink_caps_str[] = GST_VAAPI_MAKE_SURFACE_CAPS ", " GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", " + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" GST_VAAPI_MAKE_DMABUF_CAPS "," GST_CAPS_INTERLACED_FALSE; From b55b0538c934df0fcabb5f9955a136ce9468494e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 17 Dec 2019 13:09:58 +0100 Subject: [PATCH 3422/3781] tests: check return calling of gst_navigation_event_parse.* This issue was detected by Coverity. If the function returns an error value, the error value may be mistaken for a normal value. In cb_mouse_event: Value returned from a function is not checked for errors before being used --- tests/check/elements/vaapipostproc.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/check/elements/vaapipostproc.c b/tests/check/elements/vaapipostproc.c index 1e892d9ade..e46304ffff 100644 --- a/tests/check/elements/vaapipostproc.c +++ b/tests/check/elements/vaapipostproc.c @@ -125,18 +125,23 @@ static GstPadProbeReturn cb_mouse_event (GstPad * pad, GstPadProbeInfo * info, gpointer data) { VppTestCoordinate *coord = data; + gdouble x = 0, y = 0; GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info); if (GST_EVENT_TYPE (event) == GST_EVENT_NAVIGATION) { switch (gst_navigation_event_get_type (event)) { case GST_NAVIGATION_EVENT_MOUSE_MOVE: - gst_navigation_event_parse_mouse_move_event (event, &coord->x, - &coord->y); + if (gst_navigation_event_parse_mouse_move_event (event, &x, &y)) { + coord->x = x; + coord->y = y; + } break; case GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS: case GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE: - gst_navigation_event_parse_mouse_button_event (event, NULL, &coord->x, - &coord->y); + if (gst_navigation_event_parse_mouse_button_event (event, NULL, &x, &y)) { + coord->x = x; + coord->y = y; + } break; default: break; @@ -152,7 +157,7 @@ vpp_test_mouse_events (VppTestContext * ctx, { GstStructure *structure; GstEvent *event; - VppTestCoordinate probed; + VppTestCoordinate probed = { 0, }; guint i, j; /* probe mouse events propagated up from vaapipostproc */ From 6ecbb8d100cc3ac71f2d52191c8a6527bc35498d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 17 Dec 2019 13:22:12 +0100 Subject: [PATCH 3423/3781] libs: encoder: h264fei: fix surface leak Issue detected by Coverity If the FEI mode is not handled the created resources should be released and return and error code. The system resource will not be reclaimed and reused, reducing the future availability of the resource. In gst_vaapi_encoder_h264_fei_encode: Leak of memory or pointers to system resources --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index ea5c495261..f5d74a6e10 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -2827,7 +2827,9 @@ gst_vaapi_encoder_h264_fei_encode (GstVaapiEncoder * base_encoder, g_array_free (info_to_pak.h264_slice_headers, TRUE); gst_vaapi_enc_picture_unref (picture2); - + } else { + GST_ERROR ("invalid FEI mode"); + goto error; } return GST_VAAPI_ENCODER_STATUS_SUCCESS; From 47b0932911bc7b7043e16355ba39c722c0289029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 17 Dec 2019 16:49:47 +0100 Subject: [PATCH 3424/3781] libs: encoder: h264fei: don't free memory on stack Issue detected by Coverity `info_to_pak` variable in gst_vaapi_encoder_h264_fei_encode() is declared in the stack, but it is free in gst_vaapi_feienc_h264_encode() as if declared on the heap. This patch initializes the structure and removes the free. A non-heap pointer is placed on the free list, likely causing a crash later. In gst_vaapi_encoder_h264_fei_encode: Free of an address-of expression, which can never be heap allocated. --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 2 +- gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index f5d74a6e10..e0fbe5054d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -2741,7 +2741,7 @@ gst_vaapi_encoder_h264_fei_encode (GstVaapiEncoder * base_encoder, GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; GstVaapiSurfaceProxy *reconstruct = NULL; GstVaapiEncPicture *picture2 = NULL; - GstVaapiFeiInfoToPakH264 info_to_pak; + GstVaapiFeiInfoToPakH264 info_to_pak = { {0} }; reconstruct = gst_vaapi_encoder_create_surface (base_encoder); diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index 67fcfbeed3..ab8642a5b4 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -1403,7 +1403,6 @@ gst_vaapi_feienc_h264_encode (GstVaapiEncoder * base_encoder, return GST_VAAPI_ENCODER_STATUS_SUCCESS; error: - g_slice_free (GstVaapiFeiInfoToPakH264, info_to_pak); return ret; } From d69a4b8c0553d57583772600ceb7a1433e354af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 17 Dec 2019 16:57:41 +0100 Subject: [PATCH 3425/3781] libs: encoder: h264fei: remove unnecessary check Issue detected by Coverity There may be a null pointer dereference, or else the comparison against null is unnecessary. In gst_vaapi_encoder_h264_fei_encode: All paths that lead to this null pointer comparison already dereference the pointer earlier --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index e0fbe5054d..d643a6a67d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -2837,9 +2837,8 @@ gst_vaapi_encoder_h264_fei_encode (GstVaapiEncoder * base_encoder, /* ERRORS */ error: { - if (reconstruct) - gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), - reconstruct); + gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), + reconstruct); if (picture2) gst_vaapi_enc_picture_unref (picture2); return status; From f82cec2ce309af61e3bee41735ed847eb9bd041f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 17 Dec 2019 17:05:22 +0100 Subject: [PATCH 3426/3781] libs: encoder: h264fei: remove unnecessary assert Issue detected by Coverity An unsigned value can never be negative, so this test will always evaluate the same way. In add_slice_headers: An unsigned value can never be less than 0 --- gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index ab8642a5b4..333744bcb7 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -864,7 +864,7 @@ add_slice_headers (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; else slice_param->num_ref_idx_l1_active_minus1 = 0; - g_assert (slice_param->num_ref_idx_l0_active_minus1 >= 0); + g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0); g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0); i_ref = 0; From 4bb41e6ca3973176046f92d7dcd7a4f63f08dd1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 17 Dec 2019 17:09:37 +0100 Subject: [PATCH 3427/3781] libs: encoder: h264fei: remove unnecessary check Issue detected by Coverity `info_to_pack.h264_slice_header` is always allocated by gst_vaapi_feipak_h264_encode(), thus checking it to free it afterwards in doesn't make much sense. But it requires to be free on the error path. There may be a null pointer dereference, or else the comparison against null is unnecessary. In gst_vaapi_encoder_h264_fei_encode: All paths that lead to this null pointer comparison already dereference the pointer earlier --- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index d643a6a67d..eeec20aa3e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -2823,8 +2823,7 @@ gst_vaapi_encoder_h264_fei_encode (GstVaapiEncoder * base_encoder, } /* Free the slice array */ - if (info_to_pak.h264_slice_headers) - g_array_free (info_to_pak.h264_slice_headers, TRUE); + g_array_free (info_to_pak.h264_slice_headers, TRUE); gst_vaapi_enc_picture_unref (picture2); } else { @@ -2841,6 +2840,8 @@ error: reconstruct); if (picture2) gst_vaapi_enc_picture_unref (picture2); + if (info_to_pak.h264_slice_headers) + g_array_free (info_to_pak.h264_slice_headers, TRUE); return status; } } From 61de88e58030e245b596fd10af422615c08cb9a3 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 18 Dec 2019 00:40:58 +0800 Subject: [PATCH 3428/3781] plugin: encode: change the dmabuf caps to all supported formats. The encode's dmabuf caps definition is obsolete, it can support more formats now. Re-define it to include all supported formats in video format map. --- gst/vaapi/gstvaapiencode_h264.c | 2 +- gst/vaapi/gstvaapiencode_h264_fei.c | 2 +- gst/vaapi/gstvaapiencode_h265.c | 2 +- gst/vaapi/gstvaapiencode_jpeg.c | 2 +- gst/vaapi/gstvaapiencode_mpeg2.c | 2 +- gst/vaapi/gstvaapiencode_vp8.c | 2 +- gst/vaapi/gstvaapiencode_vp9.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index e1d91b67ea..018917f866 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -84,7 +84,7 @@ static const char gst_vaapiencode_h264_sink_caps_str[] = GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" - GST_VAAPI_MAKE_DMABUF_CAPS "," + GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_h264_fei.c b/gst/vaapi/gstvaapiencode_h264_fei.c index c45e8d2aa9..5a998afbd6 100644 --- a/gst/vaapi/gstvaapiencode_h264_fei.c +++ b/gst/vaapi/gstvaapiencode_h264_fei.c @@ -64,7 +64,7 @@ static const char gst_vaapiencode_h264_fei_sink_caps_str[] = GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" - GST_VAAPI_MAKE_DMABUF_CAPS "," + GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 711f5e1447..5fb2cfbded 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -58,7 +58,7 @@ static const char gst_vaapiencode_h265_sink_caps_str[] = GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" - GST_VAAPI_MAKE_DMABUF_CAPS "," + GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index d532429ecc..34a0efd000 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -55,7 +55,7 @@ static const char gst_vaapiencode_jpeg_sink_caps_str[] = GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" - GST_VAAPI_MAKE_DMABUF_CAPS "," + GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index a01042f6f6..06b3458ca8 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -57,7 +57,7 @@ static const char gst_vaapiencode_mpeg2_sink_caps_str[] = GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" - GST_VAAPI_MAKE_DMABUF_CAPS "," + GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 767ec38575..001a2f3089 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -55,7 +55,7 @@ static const char gst_vaapiencode_vp8_sink_caps_str[] = GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" - GST_VAAPI_MAKE_DMABUF_CAPS "," + GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index 6fed2382fc..1fd0f8ed2c 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -55,7 +55,7 @@ static const char gst_vaapiencode_vp9_sink_caps_str[] = GST_CAPS_INTERLACED_FALSE "; " GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " GST_CAPS_INTERLACED_FALSE ";" - GST_VAAPI_MAKE_DMABUF_CAPS "," + GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," GST_CAPS_INTERLACED_FALSE; /* *INDENT-ON* */ From a6289308ee6f992fe6530cae3c6592a7a0b12ba3 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 24 Sep 2019 01:01:22 +0800 Subject: [PATCH 3429/3781] libs: context: port to a plain C structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GstVaapiMiniObject is obsolete and we need to replace it. This patch turns GstVaapiContext into a plain C structure with its own reference counting mechanism. Also this patch removes unused overlays attributes. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapicodedbuffer.c | 6 +- gst-libs/gst/vaapi/gstvaapicodedbufferpool.c | 7 +- gst-libs/gst/vaapi/gstvaapicontext.c | 84 +++++++++++++------ gst-libs/gst/vaapi/gstvaapicontext.h | 30 +++---- gst-libs/gst/vaapi/gstvaapidecoder.c | 3 +- gst-libs/gst/vaapi/gstvaapiencoder.c | 7 +- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 2 +- gst-libs/gst/vaapi/gstvaapiprofilecaps.c | 2 +- 8 files changed, 91 insertions(+), 50 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodedbuffer.c b/gst-libs/gst/vaapi/gstvaapicodedbuffer.c index 3680d2d4c8..39e5ec8a81 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbuffer.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbuffer.c @@ -40,8 +40,8 @@ coded_buffer_create (GstVaapiCodedBuffer * buf, guint buf_size, GST_VAAPI_DISPLAY_LOCK (display); success = vaapi_create_buffer (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_OBJECT_ID (context), VAEncCodedBufferType, buf_size, NULL, - &buf_id, NULL); + GST_VAAPI_CONTEXT_ID (context), VAEncCodedBufferType, buf_size, + NULL, &buf_id, NULL); GST_VAAPI_DISPLAY_UNLOCK (display); if (!success) return FALSE; @@ -117,7 +117,7 @@ gst_vaapi_coded_buffer_new (GstVaapiContext * context, guint buf_size) g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (buf_size > 0, NULL); - display = GST_VAAPI_OBJECT_DISPLAY (context); + display = GST_VAAPI_CONTEXT_DISPLAY (context); g_return_val_if_fail (display != NULL, NULL); buf = gst_vaapi_object_new (gst_vaapi_coded_buffer_class (), display); diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c index a46d5016de..3262a946b0 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferpool.c @@ -47,7 +47,7 @@ static void coded_buffer_pool_init (GstVaapiCodedBufferPool * pool, GstVaapiContext * context, gsize buf_size) { - pool->context = gst_vaapi_object_ref (context); + pool->context = gst_vaapi_context_ref (context); pool->buf_size = buf_size; } @@ -55,7 +55,8 @@ static void coded_buffer_pool_finalize (GstVaapiCodedBufferPool * pool) { gst_vaapi_video_pool_finalize (GST_VAAPI_VIDEO_POOL (pool)); - gst_vaapi_object_replace (&pool->context, NULL); + gst_vaapi_context_unref (pool->context); + pool->context = NULL; } static gpointer @@ -106,7 +107,7 @@ gst_vaapi_coded_buffer_pool_new (GstVaapiEncoder * encoder, gsize buf_size) if (!pool) return NULL; - gst_vaapi_video_pool_init (pool, GST_VAAPI_OBJECT_DISPLAY (context), + 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); diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 2be0709bca..358fddeca5 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -31,8 +31,7 @@ #include "gstvaapicompat.h" #include "gstvaapicontext.h" #include "gstvaapidisplay_priv.h" -#include "gstvaapiobject_priv.h" -#include "gstvaapisurface.h" +#include "gstvaapisurface_priv.h" #include "gstvaapisurfacepool.h" #include "gstvaapisurfaceproxy.h" #include "gstvaapivideopool_priv.h" @@ -54,7 +53,7 @@ ensure_attributes (GstVaapiContext * context) return TRUE; context->attribs = - gst_vaapi_config_surface_attributes_get (GST_VAAPI_OBJECT_DISPLAY + gst_vaapi_config_surface_attributes_get (GST_VAAPI_CONTEXT_DISPLAY (context), context->va_config); return (context->attribs != NULL); } @@ -63,7 +62,7 @@ static inline gboolean context_get_attribute (GstVaapiContext * context, VAConfigAttribType type, guint * out_value_ptr) { - return gst_vaapi_get_config_attribute (GST_VAAPI_OBJECT_DISPLAY (context), + return gst_vaapi_get_config_attribute (GST_VAAPI_CONTEXT_DISPLAY (context), context->va_profile, context->va_entrypoint, type, out_value_ptr); } @@ -80,11 +79,11 @@ context_destroy_surfaces (GstVaapiContext * context) static void context_destroy (GstVaapiContext * context) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); + GstVaapiDisplay *const display = GST_VAAPI_CONTEXT_DISPLAY (context); VAContextID context_id; VAStatus status; - context_id = GST_VAAPI_OBJECT_ID (context); + context_id = GST_VAAPI_CONTEXT_ID (context); GST_DEBUG ("context 0x%08x", context_id); if (context_id != VA_INVALID_ID) { @@ -94,7 +93,7 @@ context_destroy (GstVaapiContext * context) GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaDestroyContext()")) GST_WARNING ("failed to destroy context 0x%08x", context_id); - GST_VAAPI_OBJECT_ID (context) = VA_INVALID_ID; + GST_VAAPI_CONTEXT_ID (context) = VA_INVALID_ID; } if (context->va_config != VA_INVALID_ID) { @@ -126,7 +125,7 @@ context_ensure_surfaces (GstVaapiContext * context) for (i = context->surfaces->len; i < num_surfaces; i++) { surface = - gst_vaapi_surface_new_from_formats (GST_VAAPI_OBJECT_DISPLAY (context), + gst_vaapi_surface_new_from_formats (GST_VAAPI_CONTEXT_DISPLAY (context), cip->chroma_type, cip->width, cip->height, context->attribs->formats); if (!surface) return FALSE; @@ -142,7 +141,7 @@ static gboolean context_create_surfaces (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); + GstVaapiDisplay *const display = GST_VAAPI_CONTEXT_DISPLAY (context); guint num_surfaces; num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; @@ -168,7 +167,7 @@ static gboolean context_create (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); + GstVaapiDisplay *const display = GST_VAAPI_CONTEXT_DISPLAY (context); VAContextID context_id; VASurfaceID surface_id; VAStatus status; @@ -203,7 +202,7 @@ context_create (GstVaapiContext * context) goto cleanup; GST_DEBUG ("context 0x%08x", context_id); - GST_VAAPI_OBJECT_ID (context) = context_id; + GST_VAAPI_CONTEXT_ID (context) = context_id; success = TRUE; cleanup: @@ -216,7 +215,7 @@ static gboolean config_create (GstVaapiContext * context) { const GstVaapiContextInfo *const cip = &context->info; - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); + GstVaapiDisplay *const display = GST_VAAPI_CONTEXT_DISPLAY (context); VAConfigAttrib attribs[7], *attrib; VAStatus status; guint value, va_chroma_format, attrib_index; @@ -393,15 +392,6 @@ gst_vaapi_context_init (GstVaapiContext * context, context->attribs = NULL; } -static void -gst_vaapi_context_finalize (GstVaapiContext * context) -{ - context_destroy (context); - context_destroy_surfaces (context); -} - -GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiContext, gst_vaapi_context); - /** * gst_vaapi_context_new: * @display: a #GstVaapiDisplay @@ -421,11 +411,18 @@ gst_vaapi_context_new (GstVaapiDisplay * display, g_return_val_if_fail (cip->profile, NULL); g_return_val_if_fail (cip->entrypoint, NULL); + g_return_val_if_fail (display, NULL); - context = gst_vaapi_object_new (gst_vaapi_context_class (), display); + 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)) @@ -448,7 +445,7 @@ done: /* ERRORS */ error: { - gst_vaapi_object_unref (context); + gst_vaapi_context_unref (context); return NULL; } } @@ -537,7 +534,7 @@ gst_vaapi_context_get_id (GstVaapiContext * context) { g_return_val_if_fail (context != NULL, VA_INVALID_ID); - return GST_VAAPI_OBJECT_ID (context); + return GST_VAAPI_CONTEXT_ID (context); } /** @@ -655,3 +652,42 @@ gst_vaapi_context_get_surface_attributes (GstVaapiContext * context, 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); + } +} diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 2dcaaf4d76..702817146e 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -41,7 +41,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiConfigInfoEncoder GstVaapiConfigInfoEncoder; typedef struct _GstVaapiContextInfo GstVaapiContextInfo; typedef struct _GstVaapiContext GstVaapiContext; -typedef struct _GstVaapiContextClass GstVaapiContextClass; /** * GstVaapiContextUsage: @@ -105,30 +104,23 @@ struct _GstVaapiContextInfo struct _GstVaapiContext { /*< private >*/ - GstVaapiObject parent_instance; + volatile 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; - GPtrArray *overlays[2]; - guint overlay_id; gboolean reset_on_resize; GstVaapiConfigSurfaceAttributes *attribs; }; -/** - * GstVaapiContextClass: - * - * A VA context wrapper class. - */ -struct _GstVaapiContextClass -{ - /*< private >*/ - GstVaapiObjectClass parent_class; -}; +#define GST_VAAPI_CONTEXT_ID(context) (((GstVaapiContext *)(context))->object_id) +#define GST_VAAPI_CONTEXT_DISPLAY(context) (((GstVaapiContext *)(context))->display) G_GNUC_INTERNAL GstVaapiContext * @@ -166,6 +158,16 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 5c46702153..0e9d276426 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -483,7 +483,8 @@ gst_vaapi_decoder_finalize (GObject * object) decoder->frames = NULL; } - gst_vaapi_object_replace (&decoder->context, NULL); + gst_vaapi_context_unref (decoder->context); + decoder->context = NULL; decoder->va_context = VA_INVALID_ID; gst_vaapi_display_replace (&decoder->display, NULL); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 815660b5b4..2d29d04d2f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1345,7 +1345,8 @@ gst_vaapi_encoder_finalize (GObject * object) { GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); - gst_vaapi_object_replace (&encoder->context, NULL); + gst_vaapi_context_unref (encoder->context); + encoder->context = NULL; gst_vaapi_display_replace (&encoder->display, NULL); encoder->va_display = NULL; @@ -1485,7 +1486,7 @@ create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile) GstVaapiContext *ctxt; if (encoder->context) - return gst_vaapi_object_ref (encoder->context); + return gst_vaapi_context_ref (encoder->context); /* if there is no profile, let's figure out one */ if (profile == GST_VAAPI_PROFILE_UNKNOWN) @@ -1506,7 +1507,7 @@ get_profile_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile) if (!ctxt) return NULL; formats = gst_vaapi_context_get_surface_formats (ctxt); - gst_vaapi_object_unref (ctxt); + gst_vaapi_context_unref (ctxt); return formats; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index eeec20aa3e..92111e0b8a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -3798,7 +3798,7 @@ static inline gboolean context_get_attribute (GstVaapiContext * context, VAConfigAttribType type, guint * out_value_ptr) { - return gst_vaapi_get_config_attribute (GST_VAAPI_OBJECT_DISPLAY (context), + return gst_vaapi_get_config_attribute (GST_VAAPI_CONTEXT_DISPLAY (context), context->va_profile, context->va_entrypoint, type, out_value_ptr); } diff --git a/gst-libs/gst/vaapi/gstvaapiprofilecaps.c b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c index fcd6981fb5..7efa6a3297 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofilecaps.c +++ b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c @@ -87,7 +87,7 @@ append_caps_with_context_info (GstVaapiDisplay * display, return FALSE; ret = append_caps (context, structure); - gst_vaapi_object_unref (context); + gst_vaapi_context_unref (context); return ret; } From d56824c05cc3245143dab4fb716902158ec6b7c6 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 18 Dec 2019 12:57:01 +0100 Subject: [PATCH 3430/3781] libs: image: port to GstMiniObject base class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GstVaapiMiniObject and GstVaapiObject are deprecrated. This is the first step to remove them, by porting GstVaapiImage as a GstMiniObject. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiimage.c | 73 +++++++++++++++--------- gst-libs/gst/vaapi/gstvaapiimage.h | 40 +++++++++++++ gst-libs/gst/vaapi/gstvaapiimage_priv.h | 37 +++++++----- gst-libs/gst/vaapi/gstvaapisubpicture.c | 11 ++-- gst-libs/gst/vaapi/gstvaapisurface.c | 9 ++- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 3 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 35 ++++++++++-- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 1 + gst/vaapi/gstvaapipluginbase.c | 2 +- gst/vaapi/gstvaapivideomemory.c | 8 +-- gst/vaapi/gstvaapivideometa.c | 14 +++-- tests/internal/image.c | 6 +- tests/internal/simple-encoder.c | 2 +- tests/internal/test-fei-enc-in.c | 2 +- tests/internal/test-filter.c | 4 +- tests/internal/test-windows.c | 2 +- 16 files changed, 175 insertions(+), 74 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index a2a626800d..9349af44d3 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -32,7 +32,6 @@ #include "gstvaapiutils.h" #include "gstvaapiimage.h" #include "gstvaapiimage_priv.h" -#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -114,15 +113,15 @@ vaapi_image_is_linear (const VAImage * va_image) } static void -gst_vaapi_image_destroy (GstVaapiImage * image) +gst_vaapi_image_free (GstVaapiImage * image) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (image); + GstVaapiDisplay *const display = GST_VAAPI_IMAGE_DISPLAY (image); VAImageID image_id; VAStatus status; _gst_vaapi_image_unmap (image); - image_id = GST_VAAPI_OBJECT_ID (image); + image_id = GST_VAAPI_IMAGE_ID (image); GST_DEBUG ("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (image_id)); if (image_id != VA_INVALID_ID) { @@ -132,14 +131,18 @@ gst_vaapi_image_destroy (GstVaapiImage * image) if (!vaapi_check_status (status, "vaDestroyImage()")) GST_WARNING ("failed to destroy image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (image_id)); - GST_VAAPI_OBJECT_ID (image) = VA_INVALID_ID; + GST_VAAPI_IMAGE_ID (image) = VA_INVALID_ID; } + + gst_vaapi_display_replace (&GST_VAAPI_IMAGE_DISPLAY (image), NULL); + + g_slice_free1 (sizeof (GstVaapiImage), image); } static gboolean _gst_vaapi_image_create (GstVaapiImage * image, GstVideoFormat format) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (image); + GstVaapiDisplay *const display = GST_VAAPI_IMAGE_DISPLAY (image); const VAImageFormat *va_format; VAStatus status; @@ -210,31 +213,44 @@ gst_vaapi_image_create (GstVaapiImage * image, GstVideoFormat format, image->is_linear = vaapi_image_is_linear (&image->image); GST_DEBUG ("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (image_id)); - GST_VAAPI_OBJECT_ID (image) = image_id; + GST_VAAPI_IMAGE_ID (image) = image_id; return TRUE; } static void -gst_vaapi_image_init (GstVaapiImage * image) +gst_vaapi_image_init (GstVaapiImage * image, GstVaapiDisplay * display) { + /* TODO(victor): implement image copy mechanism, it's almost + * there */ + gst_mini_object_init (GST_MINI_OBJECT_CAST (image), 0, + GST_TYPE_VAAPI_IMAGE, NULL, NULL, + (GstMiniObjectFreeFunction) gst_vaapi_image_free); + + GST_VAAPI_IMAGE_DISPLAY (image) = gst_object_ref (display); + GST_VAAPI_IMAGE_ID (image) = VA_INVALID_ID; image->internal_image.image_id = VA_INVALID_ID; image->internal_image.buf = VA_INVALID_ID; image->image.image_id = VA_INVALID_ID; image->image.buf = VA_INVALID_ID; } -static void -gst_vaapi_image_class_init (GstVaapiImageClass * klass) +GST_DEFINE_MINI_OBJECT_TYPE (GstVaapiImage, gst_vaapi_image); + +/** + * gst_vaapi_image_get_display: + * @image: a #GstVaapiImage + * + * Returns the #GstVaapiDisplay this @image is bound to. + * + * Return value: the parent #GstVaapiDisplay object + */ +GstVaapiDisplay * +gst_vaapi_image_get_display (GstVaapiImage * image) { - GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); - - object_class->init = (GstVaapiObjectInitFunc) gst_vaapi_image_init; + g_return_val_if_fail (image != NULL, NULL); + return GST_VAAPI_IMAGE_DISPLAY (image); } -#define gst_vaapi_image_finalize gst_vaapi_image_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiImage, - gst_vaapi_image, gst_vaapi_image_class_init (&g_class)) - /** * gst_vaapi_image_new: * @display: a #GstVaapiDisplay @@ -247,7 +263,8 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiImage, * * Return value: the newly allocated #GstVaapiImage object */ - GstVaapiImage *gst_vaapi_image_new (GstVaapiDisplay * display, +GstVaapiImage * +gst_vaapi_image_new (GstVaapiDisplay * display, GstVideoFormat format, guint width, guint height) { GstVaapiImage *image; @@ -258,10 +275,12 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiImage, GST_DEBUG ("format %s, size %ux%u", gst_vaapi_video_format_to_string (format), width, height); - image = gst_vaapi_object_new (gst_vaapi_image_class (), display); + image = g_slice_new (GstVaapiImage); if (!image) return NULL; + gst_vaapi_image_init (image, display); + if (!gst_vaapi_image_create (image, format, width, height)) goto error; return image; @@ -269,7 +288,7 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiImage, /* ERRORS */ error: { - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); return NULL; } } @@ -300,10 +319,12 @@ gst_vaapi_image_new_with_image (GstVaapiDisplay * display, VAImage * va_image) GST_FOURCC_ARGS (va_image->format.fourcc), va_image->width, va_image->height); - image = gst_vaapi_object_new (gst_vaapi_image_class (), display); + image = g_slice_new (GstVaapiImage); if (!image) return NULL; + gst_vaapi_image_init (image, display); + if (!_gst_vaapi_image_set_image (image, va_image)) goto error; return image; @@ -311,7 +332,7 @@ gst_vaapi_image_new_with_image (GstVaapiDisplay * display, VAImage * va_image) /* ERRORS */ error: { - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); return NULL; } } @@ -329,7 +350,7 @@ gst_vaapi_image_get_id (GstVaapiImage * image) { g_return_val_if_fail (image != NULL, VA_INVALID_ID); - return GST_VAAPI_OBJECT_ID (image); + return GST_VAAPI_IMAGE_ID (image); } /** @@ -385,7 +406,7 @@ _gst_vaapi_image_set_image (GstVaapiImage * image, const VAImage * va_image) image->width = va_image->width; image->height = va_image->height; - GST_VAAPI_OBJECT_ID (image) = va_image->image_id; + GST_VAAPI_IMAGE_ID (image) = va_image->image_id; /* Try to linearize image */ if (!image->is_linear) { @@ -554,7 +575,7 @@ _gst_vaapi_image_map (GstVaapiImage * image, GstVaapiImageRaw * raw_image) if (_gst_vaapi_image_is_mapped (image)) goto map_success; - display = GST_VAAPI_OBJECT_DISPLAY (image); + display = GST_VAAPI_IMAGE_DISPLAY (image); if (!display) return FALSE; @@ -607,7 +628,7 @@ _gst_vaapi_image_unmap (GstVaapiImage * image) if (!_gst_vaapi_image_is_mapped (image)) return TRUE; - display = GST_VAAPI_OBJECT_DISPLAY (image); + display = GST_VAAPI_IMAGE_DISPLAY (image); if (!display) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 6e440ef706..5f8305d5cc 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -59,8 +59,32 @@ G_BEGIN_DECLS */ #define GST_VAAPI_IMAGE_HEIGHT(image) gst_vaapi_image_get_height(image) +/** + * GST_VAAPI_IMAGE_DISPLAY: + * @image: a #GstVaapiImage + * + * Macro that evaluates to the display of @image + */ +#define GST_VAAPI_IMAGE_DISPLAY(image) gst_vaapi_image_get_display(image) + +/** + * GST_VAAPI_IMAGE_ID: + * @image: a #GstVaapiImage + * + * Macro that evaluates to the ID of @image + */ +#define GST_VAAPI_IMAGE_ID(image) gst_vaapi_image_get_id(image) + +#define GST_TYPE_VAAPI_IMAGE (gst_vaapi_image_get_type ()) + typedef struct _GstVaapiImage GstVaapiImage; +GType +gst_vaapi_image_get_type (void) G_GNUC_CONST; + +GstVaapiDisplay * +gst_vaapi_image_get_display (GstVaapiImage * image); + GstVaapiImage * gst_vaapi_image_new( GstVaapiDisplay *display, @@ -72,6 +96,20 @@ gst_vaapi_image_new( GstVaapiImage * gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image); +/** + * gst_vaapi_image_unref: (skip) + * @image: (transfer full): a #GstVaapiImage. + * + * Decreases the refcount of the image. If the refcount reaches 0, the + * image will be freed. + */ +static inline void gst_vaapi_image_unref(GstVaapiImage* image); +static inline void +gst_vaapi_image_unref (GstVaapiImage * image) +{ + gst_mini_object_unref (GST_MINI_OBJECT_CAST (image)); +} + GstVaapiID gst_vaapi_image_get_id(GstVaapiImage *image); @@ -131,6 +169,8 @@ gst_vaapi_image_update_from_buffer( gboolean gst_vaapi_image_copy(GstVaapiImage *dst_image, GstVaapiImage *src_image); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiImage, gst_vaapi_image_unref) + G_END_DECLS #endif /* GST_VAAPI_IMAGE_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiimage_priv.h b/gst-libs/gst/vaapi/gstvaapiimage_priv.h index bed4a9472a..584de56d2a 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiimage_priv.h @@ -26,11 +26,9 @@ #define GST_VAAPI_IMAGE_PRIV_H #include -#include "gstvaapiobject_priv.h" G_BEGIN_DECLS -typedef struct _GstVaapiImageClass GstVaapiImageClass; typedef struct _GstVaapiImageRaw GstVaapiImageRaw; /** @@ -40,7 +38,9 @@ typedef struct _GstVaapiImageRaw GstVaapiImageRaw; */ struct _GstVaapiImage { /*< private >*/ - GstVaapiObject parent_instance; + GstMiniObject mini_object; + GstVaapiDisplay *display; + GstVaapiID object_id; VAImage internal_image; VAImage image; @@ -52,16 +52,6 @@ struct _GstVaapiImage { guint is_linear : 1; }; -/** - * GstVaapiImageClass: - * - * A VA image wrapper class - */ -struct _GstVaapiImageClass { - /*< private >*/ - GstVaapiObjectClass parent_class; -}; - /** * GstVaapiImageRaw: * @@ -107,6 +97,27 @@ struct _GstVaapiImageRaw { #define GST_VAAPI_IMAGE_HEIGHT(image) \ (GST_VAAPI_IMAGE(image)->height) +/** + * GST_VAAPI_IMAGE_DISPLAY: + * @image: a #GstVaapiImage + * + * Macro that evaluates to the @image's display + */ +#undef GST_VAAPI_IMAGE_DISPLAY +#define GST_VAAPI_IMAGE_DISPLAY(image) \ + (GST_VAAPI_IMAGE(image)->display) + +/** + * GST_VAAPI_IMAGE_ID: + * @image: a #GstVaapiImage + * + * Macro that evaluates to the @image's object ID + */ +#undef GST_VAAPI_IMAGE_ID +#define GST_VAAPI_IMAGE_ID(image) \ + (GST_VAAPI_IMAGE(image)->object_id) + + G_GNUC_INTERNAL gboolean gst_vaapi_image_get_raw( diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 7c3f54d41b..56db3784c7 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -88,7 +88,7 @@ gst_vaapi_subpicture_destroy (GstVaapiSubpicture * subpicture) } GST_VAAPI_OBJECT_ID (subpicture) = VA_INVALID_ID; } - gst_vaapi_object_replace (&subpicture->image, NULL); + gst_mini_object_replace ((GstMiniObject **) & subpicture->image, NULL); } static gboolean @@ -101,7 +101,7 @@ gst_vaapi_subpicture_create (GstVaapiSubpicture * subpicture, GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateSubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_OBJECT_ID (image), &subpicture_id); + GST_VAAPI_IMAGE_ID (image), &subpicture_id); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateSubpicture()")) return FALSE; @@ -109,7 +109,8 @@ gst_vaapi_subpicture_create (GstVaapiSubpicture * subpicture, GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (subpicture_id)); GST_VAAPI_OBJECT_ID (subpicture) = subpicture_id; - subpicture->image = gst_vaapi_object_ref (image); + subpicture->image = + (GstVaapiImage *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (image)); return TRUE; } @@ -137,9 +138,9 @@ GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture) g_return_val_if_fail (image != NULL, NULL); GST_DEBUG ("create from image %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (image))); + GST_VAAPI_ID_ARGS (GST_VAAPI_IMAGE_ID (image))); - display = GST_VAAPI_OBJECT_DISPLAY (image); + display = GST_VAAPI_IMAGE_DISPLAY (image); format = GST_VAAPI_IMAGE_FORMAT (image); if (!gst_vaapi_display_has_subpicture_format (display, format, &va_flags)) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index f092b549e5..39c2a6ede9 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -34,7 +34,6 @@ #include "gstvaapisurface_priv.h" #include "gstvaapicontext.h" #include "gstvaapiimage.h" -#include "gstvaapiimage_priv.h" #include "gstvaapibufferproxy_priv.h" #define DEBUG 1 @@ -558,7 +557,7 @@ gst_vaapi_surface_get_format (GstVaapiSurface * surface) GstVaapiImage *const image = gst_vaapi_surface_derive_image (surface); if (image) { surface->format = GST_VAAPI_IMAGE_FORMAT (image); - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); } if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) surface->format = GST_VIDEO_FORMAT_ENCODED; @@ -638,7 +637,7 @@ gst_vaapi_surface_get_size (GstVaapiSurface * surface, * unreferenced when it's no longer needed. The image and image buffer * data structures will be destroyed. However, the surface contents * will remain unchanged until destroyed through the last call to - * gst_vaapi_object_unref(). + * gst_vaapi_image_unref(). * * Return value: the newly allocated #GstVaapiImage object, or %NULL * on failure @@ -702,7 +701,7 @@ gst_vaapi_surface_get_image (GstVaapiSurface * surface, GstVaapiImage * image) if (width != surface->width || height != surface->height) return FALSE; - image_id = GST_VAAPI_OBJECT_ID (image); + image_id = GST_VAAPI_IMAGE_ID (image); if (image_id == VA_INVALID_ID) return FALSE; @@ -746,7 +745,7 @@ gst_vaapi_surface_put_image (GstVaapiSurface * surface, GstVaapiImage * image) if (width != surface->width || height != surface->height) return FALSE; - image_id = GST_VAAPI_OBJECT_ID (image); + image_id = GST_VAAPI_IMAGE_ID (image); if (image_id == VA_INVALID_ID) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index cbd7d71773..a7e33e015f 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -39,7 +39,8 @@ gst_vaapi_surface_get_drm_buf_handle (GstVaapiSurface * surface, guint type) /* The proxy takes ownership if the image, even creation failure. */ proxy = gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), - image->internal_image.buf, type, gst_vaapi_object_unref, image); + image->internal_image.buf, type, (GDestroyNotify) gst_vaapi_image_unref, + image); if (!proxy) goto error_alloc_export_buffer; return proxy; diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index e431b52d1c..daeed76770 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -67,8 +67,19 @@ gst_vaapi_video_pool_init (GstVaapiVideoPool * pool, GstVaapiDisplay * display, void gst_vaapi_video_pool_finalize (GstVaapiVideoPool * pool) { - g_list_free_full (pool->used_objects, gst_vaapi_object_unref); - g_queue_foreach (&pool->free_objects, (GFunc) gst_vaapi_object_unref, NULL); + if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE) { + g_list_free_full (pool->used_objects, + (GDestroyNotify) gst_mini_object_unref); + } else { + g_list_free_full (pool->used_objects, gst_vaapi_object_unref); + } + + if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE) { + g_queue_foreach (&pool->free_objects, (GFunc) gst_mini_object_unref, NULL); + } else { + g_queue_foreach (&pool->free_objects, (GFunc) gst_vaapi_object_unref, NULL); + } + g_queue_clear (&pool->free_objects); gst_vaapi_display_replace (&pool->display, NULL); g_mutex_clear (&pool->mutex); @@ -183,7 +194,12 @@ gst_vaapi_video_pool_get_object_unlocked (GstVaapiVideoPool * pool) ++pool->used_count; pool->used_objects = g_list_prepend (pool->used_objects, object); - return gst_vaapi_object_ref (object); + + if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE) + object = gst_mini_object_ref (GST_MINI_OBJECT_CAST (object)); + else + object = gst_vaapi_object_ref (object); + return object; } gpointer @@ -219,7 +235,11 @@ gst_vaapi_video_pool_put_object_unlocked (GstVaapiVideoPool * pool, if (!elem) return; - gst_vaapi_object_unref (object); + if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE) + gst_mini_object_unref (GST_MINI_OBJECT_CAST (object)); + else + gst_vaapi_object_unref (object); + --pool->used_count; pool->used_objects = g_list_delete_link (pool->used_objects, elem); g_queue_push_tail (&pool->free_objects, object); @@ -251,7 +271,12 @@ static inline gboolean gst_vaapi_video_pool_add_object_unlocked (GstVaapiVideoPool * pool, gpointer object) { - g_queue_push_tail (&pool->free_objects, gst_vaapi_object_ref (object)); + if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE) { + g_queue_push_tail (&pool->free_objects, + gst_mini_object_ref (GST_MINI_OBJECT_CAST (object))); + } else { + g_queue_push_tail (&pool->free_objects, gst_vaapi_object_ref (object)); + } return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index c5bfb8604d..fd3b045118 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -39,6 +39,7 @@ #include "gstvaapisurface_priv.h" #include "gstvaapiutils.h" #include "gstvaapiutils_x11.h" +#include "gstvaapisurface_priv.h" GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapi_window); #define GST_CAT_DEFAULT gst_debug_vaapi_window diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 35714d0a37..db088be9e3 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1401,7 +1401,7 @@ extract_allowed_surface_formats (GstVaapiDisplay * display, if (res) g_array_append_val (out_formats, img_format); - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); /* Just reuse the surface if the format is specified */ if (specified_format == GST_VIDEO_FORMAT_UNKNOWN) gst_vaapi_object_replace (&surface, NULL); diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 5da1b18e8c..c6af52c46b 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -128,7 +128,7 @@ ensure_image (GstVaapiVideoMemory * mem) reset_image_usage (&mem->usage_flag); } else if (gst_vaapi_surface_get_format (mem->surface) != GST_VIDEO_INFO_FORMAT (mem->image_info)) { - gst_vaapi_object_replace (&mem->image, NULL); + gst_mini_object_replace ((GstMiniObject **) & mem->image, NULL); reset_image_usage (&mem->usage_flag); } } @@ -393,7 +393,7 @@ gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem) GST_VAAPI_VIDEO_ALLOCATOR_CAST (GST_MEMORY_CAST (mem)->allocator); if (!use_native_formats (mem->usage_flag)) - gst_vaapi_object_replace (&mem->image, NULL); + gst_mini_object_replace ((GstMiniObject **) & mem->image, NULL); else if (mem->image) { gst_vaapi_video_pool_put_object (allocator->image_pool, mem->image); mem->image = NULL; @@ -703,7 +703,7 @@ gst_video_info_update_from_surface (GstVideoInfo * vip, gst_vaapi_image_unmap (image); bail: - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); return ret; /* ERRORS */ @@ -912,7 +912,7 @@ allocator_configure_image_info (GstVaapiDisplay * display, bail: if (image) - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); return ret; /* ERRORS */ diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index 08040a9de1..3a0d313387 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -78,8 +78,9 @@ set_display (GstVaapiVideoMeta * meta, GstVaapiDisplay * display) static inline void set_image (GstVaapiVideoMeta * meta, GstVaapiImage * image) { - meta->image = gst_vaapi_object_ref (image); - set_display (meta, gst_vaapi_object_get_display (GST_VAAPI_OBJECT (image))); + meta->image = + (GstVaapiImage *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (image)); + set_display (meta, gst_vaapi_image_get_display (image)); } static gboolean @@ -131,7 +132,7 @@ gst_vaapi_video_meta_destroy_image (GstVaapiVideoMeta * meta) if (meta->image) { if (meta->image_pool) gst_vaapi_video_pool_put_object (meta->image_pool, meta->image); - gst_vaapi_object_unref (meta->image); + gst_vaapi_image_unref (meta->image); meta->image = NULL; } gst_vaapi_video_pool_replace (&meta->image_pool, NULL); @@ -228,7 +229,8 @@ gst_vaapi_video_meta_copy (GstVaapiVideoMeta * meta) copy->ref_count = 1; copy->display = gst_object_ref (meta->display); copy->image_pool = NULL; - copy->image = meta->image ? gst_vaapi_object_ref (meta->image) : NULL; + copy->image = meta->image ? (GstVaapiImage *) + gst_mini_object_ref (GST_MINI_OBJECT_CAST (meta->image)) : NULL; copy->proxy = meta->proxy ? gst_vaapi_surface_proxy_copy (meta->proxy) : NULL; copy->converter = meta->converter; copy->render_flags = meta->render_flags; @@ -462,7 +464,7 @@ gst_vaapi_video_meta_get_display (GstVaapiVideoMeta * meta) * * Retrieves the #GstVaapiImage bound to the @meta. The @meta owns * the #GstVaapiImage so the caller is responsible for calling - * gst_vaapi_object_ref() when needed. + * gst_mini_object_ref() when needed. * * Return value: the #GstVaapiImage bound to the @meta, or %NULL if * there is none @@ -526,7 +528,7 @@ gst_vaapi_video_meta_set_image_from_pool (GstVaapiVideoMeta * meta, * * Retrieves the #GstVaapiSurface bound to the @meta. The @meta * owns the #GstVaapiSurface so the caller is responsible for calling - * gst_vaapi_object_ref() when needed. + * gst_mini_object_ref() when needed. * * Return value: the #GstVaapiSurface bound to the @meta, or %NULL if * there is none diff --git a/tests/internal/image.c b/tests/internal/image.c index 1304471000..aba0b14516 100644 --- a/tests/internal/image.c +++ b/tests/internal/image.c @@ -87,7 +87,7 @@ image_generate_full (GstVaapiDisplay * display, return image; error: - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); return NULL; } @@ -321,7 +321,7 @@ image_draw_rectangle (GstVaapiImage * image, if (height > image_height - y) height = image_height - y; - display = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (image)); + display = gst_vaapi_image_get_display (image); if (!display) return FALSE; @@ -374,7 +374,7 @@ image_upload (GstVaapiImage * image, GstVaapiSurface * surface) surface_image = gst_vaapi_surface_derive_image (surface); if (surface_image) { success = gst_vaapi_image_copy (surface_image, image); - gst_vaapi_object_unref (surface_image); + gst_vaapi_image_unref (surface_image); if (success) return TRUE; } diff --git a/tests/internal/simple-encoder.c b/tests/internal/simple-encoder.c index 97857731f2..90b778e35b 100644 --- a/tests/internal/simple-encoder.c +++ b/tests/internal/simple-encoder.c @@ -456,7 +456,7 @@ app_run (App * app) ret = EXIT_SUCCESS; gst_vaapi_video_pool_replace (&pool, NULL); - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); return ret; } diff --git a/tests/internal/test-fei-enc-in.c b/tests/internal/test-fei-enc-in.c index 9f79c166d5..ad67909e2f 100644 --- a/tests/internal/test-fei-enc-in.c +++ b/tests/internal/test-fei-enc-in.c @@ -638,7 +638,7 @@ app_run (App * app) ret = EXIT_SUCCESS; gst_vaapi_video_pool_replace (&pool, NULL); - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); return ret; } diff --git a/tests/internal/test-filter.c b/tests/internal/test-filter.c index ab57775a04..926fe7f566 100644 --- a/tests/internal/test-filter.c +++ b/tests/internal/test-filter.c @@ -117,7 +117,7 @@ create_test_surface (GstVaapiDisplay * display, guint width, guint height, if (!image_upload (image, surface)) goto error_upload_image; - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); return surface; /* ERRORS */ @@ -139,7 +139,7 @@ error_upload_image: goto error_cleanup; error_cleanup: if (image) - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); if (surface) gst_vaapi_object_unref (surface); if (error_ptr) diff --git a/tests/internal/test-windows.c b/tests/internal/test-windows.c index 595be3fe1d..5b185ecb5b 100644 --- a/tests/internal/test-windows.c +++ b/tests/internal/test-windows.c @@ -89,7 +89,7 @@ create_test_surface (GstVaapiDisplay * display, guint width, guint height) if (!gst_vaapi_surface_sync (surface)) g_error ("could not complete image upload"); - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); return surface; } From 6bf33ada4fd5f1a61fc8875b6c1e9ee2bd1957a8 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 18 Dec 2019 18:00:49 +0100 Subject: [PATCH 3431/3781] libs: codedbuffer: port to GstMiniObject MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GstVaapiMiniObject and GstVaapiObject are deprecated. This is the first step to remove them by porting GstVaapiCodedBuffer as a GstMiniBuffer descendant. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapicodedbuffer.c | 54 ++++++++++++------- gst-libs/gst/vaapi/gstvaapicodedbuffer.h | 21 ++++++++ gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h | 29 ++++++---- gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c | 4 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 2 +- gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapifeipak_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 21 +++++--- 14 files changed, 98 insertions(+), 49 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodedbuffer.c b/gst-libs/gst/vaapi/gstvaapicodedbuffer.c index 39e5ec8a81..5d5f3a2ea4 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbuffer.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbuffer.c @@ -34,7 +34,7 @@ static gboolean coded_buffer_create (GstVaapiCodedBuffer * buf, guint buf_size, GstVaapiContext * context) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (buf); + GstVaapiDisplay *const display = GST_VAAPI_CODED_BUFFER_DISPLAY (buf); VABufferID buf_id; gboolean success; @@ -47,56 +47,62 @@ coded_buffer_create (GstVaapiCodedBuffer * buf, guint buf_size, return FALSE; GST_DEBUG ("coded buffer %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (buf_id)); - GST_VAAPI_OBJECT_ID (buf) = buf_id; + GST_VAAPI_CODED_BUFFER_ID (buf) = buf_id; return TRUE; } static void -coded_buffer_destroy (GstVaapiCodedBuffer * buf) +coded_buffer_free (GstVaapiCodedBuffer * buf) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (buf); + GstVaapiDisplay *const display = GST_VAAPI_CODED_BUFFER_DISPLAY (buf); VABufferID buf_id; - buf_id = GST_VAAPI_OBJECT_ID (buf); + 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_OBJECT_ID (buf) = VA_INVALID_ID; + 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_OBJECT_LOCK_DISPLAY (buf); - buf->segment_list = vaapi_map_buffer (GST_VAAPI_OBJECT_VADISPLAY (buf), - GST_VAAPI_OBJECT_ID (buf)); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (buf); + 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_OBJECT_LOCK_DISPLAY (buf); - vaapi_unmap_buffer (GST_VAAPI_OBJECT_VADISPLAY (buf), - GST_VAAPI_OBJECT_ID (buf), (void **) &buf->segment_list); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (buf); + 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); } -/* *INDENT-OFF* */ -#define gst_vaapi_coded_buffer_finalize coded_buffer_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiCodedBuffer, gst_vaapi_coded_buffer) -/* *INDENT-ON* */ +GST_DEFINE_MINI_OBJECT_TYPE (GstVaapiCodedBuffer, gst_vaapi_coded_buffer); /* * gst_vaapi_coded_buffer_new: @@ -120,10 +126,18 @@ gst_vaapi_coded_buffer_new (GstVaapiContext * context, guint buf_size) display = GST_VAAPI_CONTEXT_DISPLAY (context); g_return_val_if_fail (display != NULL, NULL); - buf = gst_vaapi_object_new (gst_vaapi_coded_buffer_class (), display); + 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; @@ -131,7 +145,7 @@ gst_vaapi_coded_buffer_new (GstVaapiContext * context, guint buf_size) /* ERRORS */ error: { - gst_vaapi_object_unref (buf); + gst_vaapi_coded_buffer_unref (buf); return NULL; } } diff --git a/gst-libs/gst/vaapi/gstvaapicodedbuffer.h b/gst-libs/gst/vaapi/gstvaapicodedbuffer.h index 4980e9c3b3..e84f57b88e 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbuffer.h +++ b/gst-libs/gst/vaapi/gstvaapicodedbuffer.h @@ -42,12 +42,33 @@ 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); +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 */ diff --git a/gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h b/gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h index 8d0de4d130..85a6193c52 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h +++ b/gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h @@ -26,15 +26,12 @@ #include #include "gstvaapicodedbuffer.h" -#include "gstvaapiobject_priv.h" G_BEGIN_DECLS #define GST_VAAPI_CODED_BUFFER_CAST(obj) \ ((GstVaapiCodedBuffer *)(obj)) -typedef struct _GstVaapiCodedBufferClass GstVaapiCodedBufferClass; - /** * GstVaapiCodedBuffer: * @@ -43,22 +40,32 @@ typedef struct _GstVaapiCodedBufferClass GstVaapiCodedBufferClass; struct _GstVaapiCodedBuffer { /*< private >*/ - GstVaapiObject parent_instance; + GstMiniObject mini_object; + GstVaapiDisplay *display; + GstVaapiID object_id; + /*< public >*/ GstVaapiContext *context; VACodedBufferSegment *segment_list; }; /** - * GstVaapiCodedBufferClass: + * GST_VAAPI_CODED_BUFFER_DISPLAY: + * @buf: a #GstVaapiCodedBuffer * - * A VA coded buffer object wrapper class. + * Macro that evaluates to the #GstVaapiDisplay of @buf */ -struct _GstVaapiCodedBufferClass -{ - /*< private >*/ - GstVaapiObjectClass parent_class; -}; +#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 * diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c index d28e7b645b..c0adfcbfa0 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c @@ -45,7 +45,7 @@ coded_buffer_proxy_finalize (GstVaapiCodedBufferProxy * proxy) if (proxy->buffer) { if (proxy->pool) gst_vaapi_video_pool_put_object (proxy->pool, proxy->buffer); - gst_vaapi_object_unref (proxy->buffer); + gst_vaapi_coded_buffer_unref (proxy->buffer); proxy->buffer = NULL; } gst_vaapi_video_pool_replace (&proxy->pool, NULL); @@ -115,7 +115,7 @@ gst_vaapi_coded_buffer_proxy_new_from_pool (GstVaapiCodedBufferPool * pool) #endif if (!proxy->buffer) goto error; - gst_vaapi_object_ref (proxy->buffer); + gst_mini_object_ref (GST_MINI_OBJECT_CAST (proxy->buffer)); return proxy; /* ERRORS */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 56f90dc119..f3dcc3df33 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2236,7 +2236,7 @@ fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, for (; i < 16; ++i) { pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID; } - pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf); pic_param->pic_parameter_set_id = encoder->view_idx; pic_param->seq_parameter_set_id = encoder->view_idx ? 1 : 0; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index 92111e0b8a..04927450ca 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -2015,7 +2015,7 @@ fill_picture (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture, for (; i < 16; ++i) { pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID; } - pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf); pic_param->pic_parameter_set_id = encoder->view_idx; pic_param->seq_parameter_set_id = encoder->view_idx ? 1 : 0; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 663c7681be..795075e308 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1613,7 +1613,7 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, pic_param->reference_frames[i].picture_id = VA_INVALID_SURFACE; pic_param->reference_frames[i].flags = 0; } - pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf); /* slice_temporal_mvp_enable_flag == FALSE */ pic_param->collocated_ref_pic_index = 0xFF; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 82839081cb..5691087751 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -214,7 +214,7 @@ fill_picture (GstVaapiEncoderJpeg * encoder, 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_OBJECT_ID (codedbuf); + 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 9574be0243..0aca23ba68 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -269,7 +269,7 @@ fill_picture (GstVaapiEncoderMpeg2 * encoder, pic_param->reconstructed_picture = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); - pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf); pic_param->picture_type = get_va_enc_picture_type (picture->type); pic_param->temporal_reference = picture->frame_num & (1024 - 1); pic_param->vbv_delay = 0xFFFF; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index 102b45a4c0..b91fa43517 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -304,7 +304,7 @@ fill_picture (GstVaapiEncoderVP8 * encoder, memset (pic_param, 0, sizeof (VAEncPictureParameterBufferVP8)); pic_param->reconstructed_frame = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); - pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + 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; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 6c8878b439..07c8154b87 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -344,7 +344,7 @@ fill_picture (GstVaapiEncoderVP9 * encoder, memset (pic_param, 0, sizeof (VAEncPictureParameterBufferVP9)); pic_param->reconstructed_frame = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); - pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf); /* Update Reference Frame list */ if (picture->type == GST_VAAPI_PICTURE_TYPE_I) diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c index 333744bcb7..60f08c412b 100644 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c @@ -766,7 +766,7 @@ fill_picture (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, pic_param->ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID; } - pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf); pic_param->pic_parameter_set_id = feienc->view_idx; pic_param->seq_parameter_set_id = feienc->view_idx ? 1 : 0; diff --git a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c index ceb821b256..575c4f9388 100644 --- a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c +++ b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c @@ -1342,7 +1342,7 @@ fill_picture (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture, pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID; pic_param->ReferenceFrames[i].frame_idx = VA_PICTURE_H264_INVALID; } - pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf); + pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index daeed76770..9e79b951ec 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -67,14 +67,16 @@ gst_vaapi_video_pool_init (GstVaapiVideoPool * pool, GstVaapiDisplay * display, void gst_vaapi_video_pool_finalize (GstVaapiVideoPool * pool) { - if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE) { + if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE + || pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER) { g_list_free_full (pool->used_objects, (GDestroyNotify) gst_mini_object_unref); } else { g_list_free_full (pool->used_objects, gst_vaapi_object_unref); } - if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE) { + if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE + || pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER) { g_queue_foreach (&pool->free_objects, (GFunc) gst_mini_object_unref, NULL); } else { g_queue_foreach (&pool->free_objects, (GFunc) gst_vaapi_object_unref, NULL); @@ -195,10 +197,12 @@ gst_vaapi_video_pool_get_object_unlocked (GstVaapiVideoPool * pool) ++pool->used_count; pool->used_objects = g_list_prepend (pool->used_objects, object); - if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE) + if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE + || pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER) { object = gst_mini_object_ref (GST_MINI_OBJECT_CAST (object)); - else + } else { object = gst_vaapi_object_ref (object); + } return object; } @@ -235,10 +239,12 @@ gst_vaapi_video_pool_put_object_unlocked (GstVaapiVideoPool * pool, if (!elem) return; - if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE) + if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE + || pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER) { gst_mini_object_unref (GST_MINI_OBJECT_CAST (object)); - else + } else { gst_vaapi_object_unref (object); + } --pool->used_count; pool->used_objects = g_list_delete_link (pool->used_objects, elem); @@ -271,7 +277,8 @@ static inline gboolean gst_vaapi_video_pool_add_object_unlocked (GstVaapiVideoPool * pool, gpointer object) { - if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE) { + if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE + || pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER) { g_queue_push_tail (&pool->free_objects, gst_mini_object_ref (GST_MINI_OBJECT_CAST (object))); } else { From af4ff803ffbab9b4d39e6726126f71c80c4f1bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 19 Dec 2019 13:46:09 +0100 Subject: [PATCH 3432/3781] libs: surface: fix internal documentation --- gst-libs/gst/vaapi/gstvaapisurface_priv.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index 35ac7fa905..48fcf43a6e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -61,7 +61,7 @@ struct _GstVaapiSurfaceClass }; /** - * GST_VAAPI_SURFACE_SURFACE_CHROMA_TYPE: + * GST_VAAPI_SURFACE_CHROMA_TYPE: * @surface: a #GstVaapiSurface * * Macro that evaluates to the @surface chroma type. @@ -73,7 +73,7 @@ struct _GstVaapiSurfaceClass (GST_VAAPI_SURFACE (surface)->chroma_type) /** - * GST_VAAPI_SURFACE_SURFACE_FORMAT: + * GST_VAAPI_SURFACE_FORMAT: * @surface: a #GstVaapiSurface * * Macro that evaluates to the @surface format. @@ -85,7 +85,7 @@ struct _GstVaapiSurfaceClass (GST_VAAPI_SURFACE (surface)->format) /** - * GST_VAAPI_SURFACE_SURFACE_WIDTH: + * GST_VAAPI_SURFACE_WIDTH: * @surface: a #GstVaapiSurface * * Macro that evaluates to the @surface width in pixels. @@ -97,7 +97,7 @@ struct _GstVaapiSurfaceClass (GST_VAAPI_SURFACE (surface)->width) /** - * GST_VAAPI_SURFACE_SURFACE_HEIGHT: + * GST_VAAPI_SURFACE_HEIGHT: * @surface: a #GstVaapiSurface * * Macro that evaluates to the @surface height in pixels. From 84cc6f31a56aa9a0fa8774af92c3c0d5f8954e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 19 Dec 2019 14:17:34 +0100 Subject: [PATCH 3433/3781] libs: surface: use macro accessors --- gst-libs/gst/vaapi/gstvaapisurface.c | 46 +++++++++++++++------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 39c2a6ede9..4ca6c6d87d 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -110,10 +110,10 @@ gst_vaapi_surface_create (GstVaapiSurface * surface, if (!vaapi_check_status (status, "vaCreateSurfaces()")) return FALSE; - surface->format = GST_VIDEO_FORMAT_UNKNOWN; - surface->chroma_type = chroma_type; - surface->width = width; - surface->height = height; + GST_VAAPI_SURFACE_FORMAT (surface) = GST_VIDEO_FORMAT_UNKNOWN; + GST_VAAPI_SURFACE_CHROMA_TYPE (surface) = chroma_type; + GST_VAAPI_SURFACE_WIDTH (surface) = width; + GST_VAAPI_SURFACE_HEIGHT (surface) = height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); GST_VAAPI_OBJECT_ID (surface) = surface_id; @@ -201,10 +201,10 @@ gst_vaapi_surface_create_full (GstVaapiSurface * surface, if (!vaapi_check_status (status, "vaCreateSurfaces()")) return FALSE; - surface->format = format; - surface->chroma_type = chroma_type; - surface->width = extbuf.width; - surface->height = extbuf.height; + GST_VAAPI_SURFACE_FORMAT (surface) = format; + GST_VAAPI_SURFACE_CHROMA_TYPE (surface) = chroma_type; + GST_VAAPI_SURFACE_WIDTH (surface) = extbuf.width; + GST_VAAPI_SURFACE_HEIGHT (surface) = extbuf.height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); GST_VAAPI_OBJECT_ID (surface) = surface_id; @@ -286,10 +286,10 @@ gst_vaapi_surface_create_from_buffer_proxy (GstVaapiSurface * surface, if (!vaapi_check_status (status, "vaCreateSurfaces()")) return FALSE; - surface->format = format; - surface->chroma_type = chroma_type; - surface->width = width; - surface->height = height; + GST_VAAPI_SURFACE_FORMAT (surface) = format; + GST_VAAPI_SURFACE_CHROMA_TYPE (surface) = chroma_type; + GST_VAAPI_SURFACE_WIDTH (surface) = width; + GST_VAAPI_SURFACE_HEIGHT (surface) = height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); GST_VAAPI_OBJECT_ID (surface) = surface_id; @@ -553,14 +553,14 @@ gst_vaapi_surface_get_format (GstVaapiSurface * surface) g_return_val_if_fail (surface != NULL, 0); /* Try to determine the underlying VA surface format */ - if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) { + if (GST_VAAPI_SURFACE_FORMAT (surface) == GST_VIDEO_FORMAT_UNKNOWN) { GstVaapiImage *const image = gst_vaapi_surface_derive_image (surface); if (image) { - surface->format = GST_VAAPI_IMAGE_FORMAT (image); + GST_VAAPI_SURFACE_FORMAT (surface) = GST_VAAPI_IMAGE_FORMAT (image); gst_vaapi_image_unref (image); } - if (surface->format == GST_VIDEO_FORMAT_UNKNOWN) - surface->format = GST_VIDEO_FORMAT_ENCODED; + if (GST_VAAPI_SURFACE_FORMAT (surface) == GST_VIDEO_FORMAT_UNKNOWN) + GST_VAAPI_SURFACE_FORMAT (surface) = GST_VIDEO_FORMAT_ENCODED; } return GST_VAAPI_SURFACE_FORMAT (surface); } @@ -698,7 +698,8 @@ gst_vaapi_surface_get_image (GstVaapiSurface * surface, GstVaapiImage * image) width = GST_VAAPI_IMAGE_WIDTH (image); height = GST_VAAPI_IMAGE_HEIGHT (image); - if (width != surface->width || height != surface->height) + if (width != GST_VAAPI_SURFACE_WIDTH (surface) + || height != GST_VAAPI_SURFACE_HEIGHT (surface)) return FALSE; image_id = GST_VAAPI_IMAGE_ID (image); @@ -742,7 +743,8 @@ gst_vaapi_surface_put_image (GstVaapiSurface * surface, GstVaapiImage * image) width = GST_VAAPI_IMAGE_WIDTH (image); height = GST_VAAPI_IMAGE_HEIGHT (image); - if (width != surface->width || height != surface->height) + if (width != GST_VAAPI_SURFACE_WIDTH (surface) + || height != GST_VAAPI_SURFACE_HEIGHT (surface)) return FALSE; image_id = GST_VAAPI_IMAGE_ID (image); @@ -844,8 +846,8 @@ _gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface, dst_rect = &dst_rect_default; dst_rect_default.x = 0; dst_rect_default.y = 0; - dst_rect_default.width = surface->width; - dst_rect_default.height = surface->height; + dst_rect_default.width = GST_VAAPI_SURFACE_WIDTH (surface); + dst_rect_default.height = GST_VAAPI_SURFACE_HEIGHT (surface); } GST_VAAPI_DISPLAY_LOCK (display); @@ -1032,8 +1034,8 @@ gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface, &sub_rect.width, &sub_rect.height); /* ensure that the overlay is not bigger than the surface */ - sub_rect.y = MIN (sub_rect.y, surface->height); - sub_rect.width = MIN (sub_rect.width, surface->width); + sub_rect.y = MIN (sub_rect.y, GST_VAAPI_SURFACE_HEIGHT (surface)); + sub_rect.width = MIN (sub_rect.width, GST_VAAPI_SURFACE_WIDTH (surface)); if (!gst_vaapi_surface_associate_subpicture (surface, subpicture, NULL, &sub_rect)) { From e398f2c24571fdc5c4a8256fddedbee2d26e515f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 19 Dec 2019 18:26:10 +0100 Subject: [PATCH 3434/3781] libs: surface: rename create function names to init There are several internal functions with 'create' name, but they don't create any new structure, but rather it initializes that structure. Renaming those function to reflect better their purpose. --- gst-libs/gst/vaapi/gstvaapisurface.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 4ca6c6d87d..e206229d58 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -91,7 +91,7 @@ gst_vaapi_surface_destroy (GstVaapiSurface * surface) } static gboolean -gst_vaapi_surface_create (GstVaapiSurface * surface, +gst_vaapi_surface_init (GstVaapiSurface * surface, GstVaapiChromaType chroma_type, guint width, guint height) { GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); @@ -126,7 +126,7 @@ error_unsupported_chroma_type: } static gboolean -gst_vaapi_surface_create_full (GstVaapiSurface * surface, +gst_vaapi_surface_init_full (GstVaapiSurface * surface, const GstVideoInfo * vip, guint flags) { GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); @@ -218,7 +218,7 @@ error_unsupported_format: } static gboolean -gst_vaapi_surface_create_from_buffer_proxy (GstVaapiSurface * surface, +gst_vaapi_surface_init_from_buffer_proxy (GstVaapiSurface * surface, GstVaapiBufferProxy * proxy, const GstVideoInfo * vip) { GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); @@ -339,7 +339,7 @@ gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display, surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); if (!surface) return NULL; - if (!gst_vaapi_surface_create (surface, chroma_type, width, height)) + if (!gst_vaapi_surface_init (surface, chroma_type, width, height)) goto error; return surface; @@ -385,10 +385,10 @@ gst_vaapi_surface_new (GstVaapiDisplay * display, surface_format = gst_vaapi_video_format_from_chroma (chroma_type); gst_video_info_set_format (&vi, surface_format, width, height); - if (gst_vaapi_surface_create_full (surface, &vi, 0)) + if (gst_vaapi_surface_init_full (surface, &vi, 0)) return surface; } - if (!gst_vaapi_surface_create (surface, chroma_type, width, height)) + if (!gst_vaapi_surface_init (surface, chroma_type, width, height)) goto error; return surface; @@ -427,7 +427,7 @@ gst_vaapi_surface_new_full (GstVaapiDisplay * display, if (!surface) return NULL; - if (!gst_vaapi_surface_create_full (surface, vip, flags)) + if (!gst_vaapi_surface_init_full (surface, vip, flags)) goto error; return surface; @@ -493,7 +493,7 @@ gst_vaapi_surface_new_from_buffer_proxy (GstVaapiDisplay * display, if (!surface) return NULL; - if (!gst_vaapi_surface_create_from_buffer_proxy (surface, proxy, info)) + if (!gst_vaapi_surface_init_from_buffer_proxy (surface, proxy, info)) goto error; return surface; From 608ce681e5dd51460c2fe5ff0be110fc40a4618a Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 19 Dec 2019 14:19:10 +0100 Subject: [PATCH 3435/3781] libs: surface: port to GstMiniObject MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GstVaapiMiniObject and GstVaapiObject are deprecated. This is the first step to remove them by porting GstVaapiSurface as a GstMiniBuffer descendant. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 27 ++-- gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h | 4 +- gst-libs/gst/vaapi/gstvaapicontext.c | 4 +- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 2 +- gst-libs/gst/vaapi/gstvaapifilter.c | 6 +- gst-libs/gst/vaapi/gstvaapipixmap_x11.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 118 ++++++++++++------ gst-libs/gst/vaapi/gstvaapisurface.h | 27 ++++ gst-libs/gst/vaapi/gstvaapisurface_drm.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface_egl.c | 6 +- gst-libs/gst/vaapi/gstvaapisurface_priv.h | 35 ++++-- gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 10 +- .../gst/vaapi/gstvaapisurfaceproxy_priv.h | 2 +- gst-libs/gst/vaapi/gstvaapitexture_egl.c | 2 +- gst-libs/gst/vaapi/gstvaapitexture_glx.c | 3 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 42 +------ gst-libs/gst/vaapi/gstvaapiwindow.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 6 +- gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 5 +- gst/vaapi/gstvaapipluginbase.c | 8 +- gst/vaapi/gstvaapivideomemory.c | 14 +-- gst/vaapi/gstvaapivideometa.c | 2 +- gst/vaapi/gstvaapivideometa_texture.c | 3 +- tests/internal/image.c | 2 +- tests/internal/test-filter.c | 6 +- tests/internal/test-surfaces.c | 7 +- tests/internal/test-windows.c | 6 +- 28 files changed, 205 insertions(+), 150 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index c177cebcd0..c8fe234b83 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -24,6 +24,7 @@ #include "gstvaapicompat.h" #include "gstvaapibufferproxy.h" #include "gstvaapibufferproxy_priv.h" +#include "gstvaapisurface_priv.h" #include "gstvaapiutils.h" #include "gstvaapiobject_priv.h" @@ -33,6 +34,7 @@ static gboolean gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) { + GstVaapiDisplay *display; const guint mem_type = proxy->va_info.mem_type; VAStatus va_status; @@ -42,10 +44,13 @@ gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) if (!proxy->parent || proxy->va_buf == VA_INVALID_ID) return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (proxy->parent); - va_status = vaAcquireBufferHandle (GST_VAAPI_OBJECT_VADISPLAY (proxy->parent), + /* @XXX(victor): parent might be not a surface */ + display = GST_VAAPI_SURFACE_DISPLAY (GST_VAAPI_SURFACE (proxy->parent)); + + GST_VAAPI_DISPLAY_LOCK (display); + va_status = vaAcquireBufferHandle (GST_VAAPI_DISPLAY_VADISPLAY (display), proxy->va_buf, &proxy->va_info); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (proxy->parent); + GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (va_status, "vaAcquireBufferHandle()")) return FALSE; if (proxy->va_info.mem_type != mem_type) @@ -56,6 +61,7 @@ gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) static gboolean gst_vaapi_buffer_proxy_release_handle (GstVaapiBufferProxy * proxy) { + GstVaapiDisplay *display; VAStatus va_status; if (!proxy->va_info.handle) @@ -64,10 +70,13 @@ gst_vaapi_buffer_proxy_release_handle (GstVaapiBufferProxy * proxy) if (!proxy->parent || proxy->va_buf == VA_INVALID_ID) return FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (proxy->parent); - va_status = vaReleaseBufferHandle (GST_VAAPI_OBJECT_VADISPLAY (proxy->parent), + /* @XXX(victor): parent might be not a surface */ + display = GST_VAAPI_SURFACE_DISPLAY (GST_VAAPI_SURFACE (proxy->parent)); + + GST_VAAPI_DISPLAY_LOCK (display); + va_status = vaReleaseBufferHandle (GST_VAAPI_DISPLAY_VADISPLAY (display), proxy->va_buf); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (proxy->parent); + GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (va_status, "vaReleaseBufferHandle()")) return FALSE; return TRUE; @@ -87,7 +96,7 @@ gst_vaapi_buffer_proxy_finalize (GstVaapiBufferProxy * proxy) if (proxy->destroy_func) proxy->destroy_func (proxy->destroy_data); - gst_vaapi_object_replace (&proxy->parent, NULL); + gst_mini_object_replace ((GstMiniObject **) & proxy->parent, NULL); } static inline const GstVaapiMiniObjectClass * @@ -138,7 +147,7 @@ error_unsupported_mem_type: } GstVaapiBufferProxy * -gst_vaapi_buffer_proxy_new_from_object (GstVaapiObject * object, +gst_vaapi_buffer_proxy_new_from_object (GstMiniObject * object, VABufferID buf_id, guint type, GDestroyNotify destroy_func, gpointer data) { GstVaapiBufferProxy *proxy; @@ -150,7 +159,7 @@ gst_vaapi_buffer_proxy_new_from_object (GstVaapiObject * object, if (!proxy) return NULL; - proxy->parent = gst_vaapi_object_ref (object); + proxy->parent = gst_mini_object_ref (object); proxy->destroy_func = destroy_func; proxy->destroy_data = data; proxy->type = type; diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h index d0fb9a231d..66bfeb4d8e 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h @@ -62,7 +62,7 @@ G_BEGIN_DECLS struct _GstVaapiBufferProxy { /*< private >*/ GstVaapiMiniObject parent_instance; - GstVaapiObject *parent; + GstMiniObject *parent; GDestroyNotify destroy_func; gpointer destroy_data; @@ -74,7 +74,7 @@ struct _GstVaapiBufferProxy { G_GNUC_INTERNAL GstVaapiBufferProxy * -gst_vaapi_buffer_proxy_new_from_object (GstVaapiObject * object, +gst_vaapi_buffer_proxy_new_from_object (GstMiniObject * object, VABufferID buf_id, guint type, GDestroyNotify destroy_func, gpointer data); G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 358fddeca5..b26bb52f2b 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -147,7 +147,7 @@ context_create_surfaces (GstVaapiContext * context) num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; if (!context->surfaces) { context->surfaces = g_ptr_array_new_full (num_surfaces, - (GDestroyNotify) gst_vaapi_object_unref); + (GDestroyNotify) gst_mini_object_unref); if (!context->surfaces) return FALSE; } @@ -188,7 +188,7 @@ context_create (GstVaapiContext * context) GstVaapiSurface *const surface = g_ptr_array_index (context->surfaces, i); if (!surface) goto cleanup; - surface_id = GST_VAAPI_OBJECT_ID (surface); + surface_id = GST_VAAPI_SURFACE_ID (surface); g_array_append_val (surfaces, surface_id); } g_assert (surfaces->len == context->surfaces->len); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c index 04927450ca..838c782ed5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c @@ -3833,7 +3833,7 @@ create_context_for_enc (GstVaapiEncoder * fei_encoder, GstVaapiSurface *const surface = g_ptr_array_index (context->surfaces, i); if (!surface) goto cleanup; - surface_id = GST_VAAPI_OBJECT_ID (surface); + surface_id = GST_VAAPI_SURFACE_ID (surface); g_array_append_val (surfaces, surface_id); } g_assert (surfaces->len == context->surfaces->len); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index 3227607c17..09fcc18ae4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -386,7 +386,7 @@ gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture, if (!picture->surface) return FALSE; - picture->surface_id = GST_VAAPI_OBJECT_ID (picture->surface); + picture->surface_id = GST_VAAPI_SURFACE_ID (picture->surface); if (picture->surface_id == VA_INVALID_ID) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index eabcedf6eb..180804b15f 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1124,7 +1124,7 @@ deint_refs_set (GArray * refs, GstVaapiSurface ** surfaces, guint num_surfaces) return FALSE; for (i = 0; i < num_surfaces; i++) - g_array_append_val (refs, GST_VAAPI_OBJECT_ID (surfaces[i])); + g_array_append_val (refs, GST_VAAPI_SURFACE_ID (surfaces[i])); return TRUE; } @@ -1617,7 +1617,7 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, goto error; memset (pipeline_param, 0, sizeof (*pipeline_param)); - pipeline_param->surface = GST_VAAPI_OBJECT_ID (src_surface); + pipeline_param->surface = GST_VAAPI_SURFACE_ID (src_surface); pipeline_param->surface_region = &src_rect; pipeline_param->surface_color_standard = VAProcColorStandardNone; pipeline_param->output_region = &dst_rect; @@ -1662,7 +1662,7 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, vaapi_unmap_buffer (filter->va_display, pipeline_param_buf_id, NULL); va_status = vaBeginPicture (filter->va_display, filter->va_context, - GST_VAAPI_OBJECT_ID (dst_surface)); + GST_VAAPI_SURFACE_ID (dst_surface)); if (!vaapi_check_status (va_status, "vaBeginPicture()")) goto error; diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c index 9ffccd9d8c..7bdbf5ec67 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c +++ b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c @@ -124,7 +124,7 @@ gst_vaapi_pixmap_x11_render (GstVaapiPixmap * pixmap, GstVaapiSurface * surface, VASurfaceID surface_id; VAStatus status; - surface_id = GST_VAAPI_OBJECT_ID (surface); + surface_id = GST_VAAPI_SURFACE_ID (surface); if (surface_id == VA_INVALID_ID) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index e206229d58..5e2e63f6be 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -34,6 +34,7 @@ #include "gstvaapisurface_priv.h" #include "gstvaapicontext.h" #include "gstvaapiimage.h" +#include "gstvaapiimage_priv.h" #include "gstvaapibufferproxy_priv.h" #define DEBUG 1 @@ -66,13 +67,13 @@ gst_vaapi_surface_destroy_subpictures (GstVaapiSurface * surface) } static void -gst_vaapi_surface_destroy (GstVaapiSurface * surface) +gst_vaapi_surface_free (GstVaapiSurface * surface) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); + GstVaapiDisplay *const display = GST_VAAPI_SURFACE_DISPLAY (surface); VASurfaceID surface_id; VAStatus status; - surface_id = GST_VAAPI_OBJECT_ID (surface); + surface_id = GST_VAAPI_SURFACE_ID (surface); GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); gst_vaapi_surface_destroy_subpictures (surface); @@ -85,16 +86,19 @@ gst_vaapi_surface_destroy (GstVaapiSurface * surface) if (!vaapi_check_status (status, "vaDestroySurfaces()")) GST_WARNING ("failed to destroy surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); - GST_VAAPI_OBJECT_ID (surface) = VA_INVALID_SURFACE; + GST_VAAPI_SURFACE_ID (surface) = VA_INVALID_SURFACE; } gst_vaapi_buffer_proxy_replace (&surface->extbuf_proxy, NULL); + gst_vaapi_display_replace (&GST_VAAPI_SURFACE_DISPLAY (surface), NULL); + + g_slice_free1 (sizeof (GstVaapiSurface), surface); } static gboolean gst_vaapi_surface_init (GstVaapiSurface * surface, GstVaapiChromaType chroma_type, guint width, guint height) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); + GstVaapiDisplay *const display = GST_VAAPI_SURFACE_DISPLAY (surface); VASurfaceID surface_id; VAStatus status; guint va_chroma_format; @@ -116,7 +120,7 @@ gst_vaapi_surface_init (GstVaapiSurface * surface, GST_VAAPI_SURFACE_HEIGHT (surface) = height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); - GST_VAAPI_OBJECT_ID (surface) = surface_id; + GST_VAAPI_SURFACE_ID (surface) = surface_id; return TRUE; /* ERRORS */ @@ -129,7 +133,7 @@ static gboolean gst_vaapi_surface_init_full (GstVaapiSurface * surface, const GstVideoInfo * vip, guint flags) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); + GstVaapiDisplay *const display = GST_VAAPI_SURFACE_DISPLAY (surface); const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (vip); VASurfaceID surface_id; VAStatus status; @@ -207,7 +211,7 @@ gst_vaapi_surface_init_full (GstVaapiSurface * surface, GST_VAAPI_SURFACE_HEIGHT (surface) = extbuf.height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); - GST_VAAPI_OBJECT_ID (surface) = surface_id; + GST_VAAPI_SURFACE_ID (surface) = surface_id; return TRUE; /* ERRORS */ @@ -221,7 +225,7 @@ static gboolean gst_vaapi_surface_init_from_buffer_proxy (GstVaapiSurface * surface, GstVaapiBufferProxy * proxy, const GstVideoInfo * vip) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); + GstVaapiDisplay *const display = GST_VAAPI_SURFACE_DISPLAY (surface); GstVideoFormat format; VASurfaceID surface_id; VAStatus status; @@ -292,7 +296,7 @@ gst_vaapi_surface_init_from_buffer_proxy (GstVaapiSurface * surface, GST_VAAPI_SURFACE_HEIGHT (surface) = height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); - GST_VAAPI_OBJECT_ID (surface) = surface_id; + GST_VAAPI_SURFACE_ID (surface) = surface_id; return TRUE; /* ERRORS */ @@ -302,8 +306,41 @@ error_unsupported_format: return FALSE; } -#define gst_vaapi_surface_finalize gst_vaapi_surface_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSurface, gst_vaapi_surface); +GST_DEFINE_MINI_OBJECT_TYPE (GstVaapiSurface, gst_vaapi_surface); + +static GstVaapiSurface * +gst_vaapi_surface_create (GstVaapiDisplay * display) +{ + GstVaapiSurface *surface = g_slice_new (GstVaapiSurface); + if (!surface) + return NULL; + + gst_mini_object_init (GST_MINI_OBJECT_CAST (surface), 0, + GST_TYPE_VAAPI_SURFACE, NULL, NULL, + (GstMiniObjectFreeFunction) gst_vaapi_surface_free); + + GST_VAAPI_SURFACE_DISPLAY (surface) = gst_object_ref (display); + GST_VAAPI_SURFACE_ID (surface) = VA_INVALID_ID; + surface->extbuf_proxy = NULL; + surface->subpictures = NULL; + + return surface; +} + +/** + * gst_vaapi_surface_get_display: + * @surface: a #GstVaapiSurface + * + * Returns the #GstVaapiDisplay this @surface is bound to. + * + * Return value: the parent #GstVaapiDisplay object + */ +GstVaapiDisplay * +gst_vaapi_surface_get_display (GstVaapiSurface * surface) +{ + g_return_val_if_fail (surface != NULL, NULL); + return GST_VAAPI_SURFACE_DISPLAY (surface); +} /** * gst_vaapi_surface_new_from_formats: @@ -336,7 +373,7 @@ gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display, /* Fallback: if there's no format valid for the chroma type let's * just use the passed chroma */ - surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); + surface = gst_vaapi_surface_create (display); if (!surface) return NULL; if (!gst_vaapi_surface_init (surface, chroma_type, width, height)) @@ -347,7 +384,7 @@ gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display, /* ERRORS */ error: { - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); return NULL; } } @@ -372,7 +409,7 @@ gst_vaapi_surface_new (GstVaapiDisplay * display, GST_DEBUG ("size %ux%u, chroma type 0x%x", width, height, chroma_type); - surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); + surface = gst_vaapi_surface_create (display); if (!surface) return NULL; @@ -395,7 +432,7 @@ gst_vaapi_surface_new (GstVaapiDisplay * display, /* ERRORS */ error: { - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); return NULL; } } @@ -423,7 +460,7 @@ gst_vaapi_surface_new_full (GstVaapiDisplay * display, GST_VIDEO_INFO_HEIGHT (vip), gst_vaapi_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)), flags); - surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); + surface = gst_vaapi_surface_create (display); if (!surface) return NULL; @@ -434,7 +471,7 @@ gst_vaapi_surface_new_full (GstVaapiDisplay * display, /* ERRORS */ error: { - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); return NULL; } } @@ -489,7 +526,7 @@ gst_vaapi_surface_new_from_buffer_proxy (GstVaapiDisplay * display, g_return_val_if_fail (proxy != NULL, NULL); g_return_val_if_fail (info != NULL, NULL); - surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display); + surface = gst_vaapi_surface_create (display); if (!surface) return NULL; @@ -500,7 +537,7 @@ gst_vaapi_surface_new_from_buffer_proxy (GstVaapiDisplay * display, /* ERRORS */ error: { - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); return NULL; } } @@ -518,7 +555,7 @@ gst_vaapi_surface_get_id (GstVaapiSurface * surface) { g_return_val_if_fail (surface != NULL, VA_INVALID_SURFACE); - return GST_VAAPI_OBJECT_ID (surface); + return GST_VAAPI_SURFACE_ID (surface); } /** @@ -652,13 +689,13 @@ gst_vaapi_surface_derive_image (GstVaapiSurface * surface) g_return_val_if_fail (surface != NULL, NULL); - display = GST_VAAPI_OBJECT_DISPLAY (surface); + display = GST_VAAPI_SURFACE_DISPLAY (surface); va_image.image_id = VA_INVALID_ID; va_image.buf = VA_INVALID_ID; GST_VAAPI_DISPLAY_LOCK (display); status = vaDeriveImage (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_OBJECT_ID (surface), &va_image); + GST_VAAPI_SURFACE_ID (surface), &va_image); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaDeriveImage()")) return NULL; @@ -692,7 +729,7 @@ gst_vaapi_surface_get_image (GstVaapiSurface * surface, GstVaapiImage * image) g_return_val_if_fail (surface != NULL, FALSE); g_return_val_if_fail (image != NULL, FALSE); - display = GST_VAAPI_OBJECT_DISPLAY (surface); + display = GST_VAAPI_SURFACE_DISPLAY (surface); if (!display) return FALSE; @@ -708,7 +745,7 @@ gst_vaapi_surface_get_image (GstVaapiSurface * surface, GstVaapiImage * image) GST_VAAPI_DISPLAY_LOCK (display); status = vaGetImage (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_OBJECT_ID (surface), 0, 0, width, height, image_id); + GST_VAAPI_SURFACE_ID (surface), 0, 0, width, height, image_id); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaGetImage()")) return FALSE; @@ -737,7 +774,7 @@ gst_vaapi_surface_put_image (GstVaapiSurface * surface, GstVaapiImage * image) g_return_val_if_fail (surface != NULL, FALSE); g_return_val_if_fail (image != NULL, FALSE); - display = GST_VAAPI_OBJECT_DISPLAY (surface); + display = GST_VAAPI_SURFACE_DISPLAY (surface); if (!display) return FALSE; @@ -753,8 +790,8 @@ gst_vaapi_surface_put_image (GstVaapiSurface * surface, GstVaapiImage * image) GST_VAAPI_DISPLAY_LOCK (display); status = vaPutImage (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_OBJECT_ID (surface), image_id, 0, 0, width, height, - 0, 0, width, height); + GST_VAAPI_SURFACE_ID (surface), image_id, 0, 0, width, height, 0, 0, + width, height); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaPutImage()")) return FALSE; @@ -823,11 +860,11 @@ _gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface, VASurfaceID surface_id; VAStatus status; - display = GST_VAAPI_OBJECT_DISPLAY (surface); + display = GST_VAAPI_SURFACE_DISPLAY (surface); if (!display) return FALSE; - surface_id = GST_VAAPI_OBJECT_ID (surface); + surface_id = GST_VAAPI_SURFACE_ID (surface); if (surface_id == VA_INVALID_SURFACE) return FALSE; @@ -890,7 +927,7 @@ gst_vaapi_surface_deassociate_subpicture (GstVaapiSurface * surface, GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT " was not bound to " "surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (subpicture)), - GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (surface))); + GST_VAAPI_ID_ARGS (GST_VAAPI_SURFACE_ID (surface))); return TRUE; } @@ -907,11 +944,11 @@ _gst_vaapi_surface_deassociate_subpicture (GstVaapiSurface * surface, VASurfaceID surface_id; VAStatus status; - display = GST_VAAPI_OBJECT_DISPLAY (surface); + display = GST_VAAPI_SURFACE_DISPLAY (surface); if (!display) return FALSE; - surface_id = GST_VAAPI_OBJECT_ID (surface); + surface_id = GST_VAAPI_SURFACE_ID (surface); if (surface_id == VA_INVALID_SURFACE) return FALSE; @@ -942,13 +979,13 @@ gst_vaapi_surface_sync (GstVaapiSurface * surface) g_return_val_if_fail (surface != NULL, FALSE); - display = GST_VAAPI_OBJECT_DISPLAY (surface); + display = GST_VAAPI_SURFACE_DISPLAY (surface); if (!display) return FALSE; GST_VAAPI_DISPLAY_LOCK (display); status = vaSyncSurface (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_OBJECT_ID (surface)); + GST_VAAPI_SURFACE_ID (surface)); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaSyncSurface()")) return FALSE; @@ -970,15 +1007,16 @@ gboolean gst_vaapi_surface_query_status (GstVaapiSurface * surface, GstVaapiSurfaceStatus * pstatus) { + GstVaapiDisplay *const display = GST_VAAPI_SURFACE_DISPLAY (surface); VASurfaceStatus surface_status; VAStatus status; g_return_val_if_fail (surface != NULL, FALSE); - GST_VAAPI_OBJECT_LOCK_DISPLAY (surface); - status = vaQuerySurfaceStatus (GST_VAAPI_OBJECT_VADISPLAY (surface), - GST_VAAPI_OBJECT_ID (surface), &surface_status); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (surface); + GST_VAAPI_DISPLAY_LOCK (display); + status = vaQuerySurfaceStatus (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_SURFACE_ID (surface), &surface_status); + GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaQuerySurfaceStatus()")) return FALSE; @@ -1007,7 +1045,7 @@ gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface, g_return_val_if_fail (surface != NULL, FALSE); - display = GST_VAAPI_OBJECT_DISPLAY (surface); + display = GST_VAAPI_SURFACE_DISPLAY (surface); if (!display) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index c62f7bb81a..08e5d7de8b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -178,9 +178,34 @@ typedef enum #define GST_VAAPI_SURFACE(obj) \ ((GstVaapiSurface *)(obj)) +#define GST_TYPE_VAAPI_SURFACE (gst_vaapi_surface_get_type ()) + +#define GST_VAAPI_SURFACE_ID(surface) (gst_vaapi_surface_get_id (surface)) +#define GST_VAAPI_SURFACE_DISPLAY(surface) (gst_vaapi_surface_get_display (surface)) + typedef struct _GstVaapiSurface GstVaapiSurface; typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy; +GType +gst_vaapi_surface_get_type (void) G_GNUC_CONST; + +/** + * gst_vaapi_surface_unref: (skip) + * @surface: (transfer full): a #GstVaapiSurface. + * + * Decreases the refcount of the surface. If the refcount reaches 0, the + * surface will be freed. + */ +static inline void gst_vaapi_surface_unref(GstVaapiSurface* surface); +static inline void +gst_vaapi_surface_unref (GstVaapiSurface * surface) +{ + gst_mini_object_unref (GST_MINI_OBJECT_CAST (surface)); +} + +GstVaapiDisplay * +gst_vaapi_surface_get_display (GstVaapiSurface * surface); + GstVaapiSurface * gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display, GstVaapiChromaType chroma_type, guint width, guint height, GArray * formts); @@ -256,6 +281,8 @@ gst_vaapi_surface_set_buffer_proxy (GstVaapiSurface * surface, GstVaapiBufferProxy * gst_vaapi_surface_peek_buffer_proxy (GstVaapiSurface * surface); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiSurface, gst_vaapi_surface_unref) + G_END_DECLS #endif /* GST_VAAPI_SURFACE_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index a7e33e015f..7587553a21 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -38,7 +38,7 @@ gst_vaapi_surface_get_drm_buf_handle (GstVaapiSurface * surface, guint type) /* The proxy takes ownership if the image, even creation failure. */ proxy = - gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface), + gst_vaapi_buffer_proxy_new_from_object (GST_MINI_OBJECT_CAST (surface), image->internal_image.buf, type, (GDestroyNotify) gst_vaapi_image_unref, image); if (!proxy) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_egl.c b/gst-libs/gst/vaapi/gstvaapisurface_egl.c index 338cfaf989..02997434c7 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_egl.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_egl.c @@ -161,7 +161,7 @@ create_surface_from_egl_image (GstVaapiDisplayEGL * display, if (filter_status != GST_VAAPI_FILTER_STATUS_SUCCESS) goto error_convert_surface; - gst_vaapi_object_unref (img_surface); + gst_vaapi_surface_unref (img_surface); gst_object_unref (filter); return out_surface; @@ -179,8 +179,8 @@ error_create_filter: GST_ERROR ("failed to create video processing filter"); // fall-through error_cleanup: - gst_vaapi_object_replace (&img_surface, NULL); - gst_vaapi_object_replace (&out_surface, NULL); + gst_mini_object_replace ((GstMiniObject **) & img_surface, NULL); + gst_mini_object_replace ((GstMiniObject **) & out_surface, NULL); gst_vaapi_filter_replace (&filter, NULL); return NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h index 48fcf43a6e..f0e8ce78fc 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h @@ -23,14 +23,10 @@ #ifndef GST_VAAPI_SURFACE_PRIV_H #define GST_VAAPI_SURFACE_PRIV_H -#include #include -#include "gstvaapiobject_priv.h" G_BEGIN_DECLS -typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; - /** * GstVaapiSurface: * @@ -39,7 +35,9 @@ typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass; struct _GstVaapiSurface { /*< private >*/ - GstVaapiObject parent_instance; + GstMiniObject mini_object; + GstVaapiDisplay *display; + GstVaapiID object_id; GstVaapiBufferProxy *extbuf_proxy; GstVideoFormat format; @@ -50,15 +48,28 @@ struct _GstVaapiSurface }; /** - * GstVaapiSurfaceClass: + * GST_VAAPI_SURFACE_DISPLAY: + * @surface: a #GstVaapiSurface * - * A VA surface wrapper class. + * Macro that evaluates to the @surface's display. + * + * This is an internal macro that does not do any run-time type check. */ -struct _GstVaapiSurfaceClass -{ - /*< private >*/ - GstVaapiObjectClass parent_class; -}; +#undef GST_VAAPI_SURFACE_DISPLAY +#define GST_VAAPI_SURFACE_DISPLAY(surface) \ + (GST_VAAPI_SURFACE (surface)->display) + +/** + * GST_VAAPI_SURFACE_ID: + * @surface: a #GstVaapiSurface + * + * Macro that evaluates to the @surface's ID. + * + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_SURFACE_ID +#define GST_VAAPI_SURFACE_ID(surface) \ + (GST_VAAPI_SURFACE (surface)->object_id) /** * GST_VAAPI_SURFACE_CHROMA_TYPE: diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index 4e2b686f21..b34afed0d8 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -41,7 +41,7 @@ gst_vaapi_surface_proxy_finalize (GstVaapiSurfaceProxy * proxy) if (proxy->surface) { if (proxy->pool && !proxy->parent) gst_vaapi_video_pool_put_object (proxy->pool, proxy->surface); - gst_vaapi_object_unref (proxy->surface); + gst_vaapi_surface_unref (proxy->surface); proxy->surface = NULL; } gst_vaapi_video_pool_replace (&proxy->pool, NULL); @@ -125,7 +125,8 @@ gst_vaapi_surface_proxy_new (GstVaapiSurface * surface) proxy->parent = NULL; proxy->destroy_func = NULL; proxy->pool = NULL; - proxy->surface = gst_vaapi_object_ref (surface); + proxy->surface = + (GstVaapiSurface *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (surface)); if (!proxy->surface) goto error; gst_vaapi_surface_proxy_init_properties (proxy); @@ -168,7 +169,7 @@ gst_vaapi_surface_proxy_new_from_pool (GstVaapiSurfacePool * pool) proxy->surface = gst_vaapi_video_pool_get_object (proxy->pool); if (!proxy->surface) goto error; - gst_vaapi_object_ref (proxy->surface); + gst_mini_object_ref (GST_MINI_OBJECT_CAST (proxy->surface)); gst_vaapi_surface_proxy_init_properties (proxy); return proxy; @@ -210,7 +211,8 @@ gst_vaapi_surface_proxy_copy (GstVaapiSurfaceProxy * proxy) copy->parent = gst_vaapi_surface_proxy_ref (proxy->parent ? proxy->parent : proxy); copy->pool = proxy->pool ? gst_vaapi_video_pool_ref (proxy->pool) : NULL; - copy->surface = gst_vaapi_object_ref (proxy->surface); + copy->surface = (GstVaapiSurface *) + gst_mini_object_ref (GST_MINI_OBJECT_CAST (proxy->surface)); copy->view_id = proxy->view_id; copy->timestamp = proxy->timestamp; copy->duration = proxy->duration; diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index 1540c7cb46..e43ecbc0e2 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -86,7 +86,7 @@ struct _GstVaapiSurfaceProxy */ #undef GST_VAAPI_SURFACE_PROXY_SURFACE_ID #define GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy) \ - (GST_VAAPI_OBJECT_ID (GST_VAAPI_SURFACE_PROXY (proxy)->surface)) + (GST_VAAPI_SURFACE_ID (GST_VAAPI_SURFACE_PROXY (proxy)->surface)) /** * GST_VAAPI_SURFACE_PROXY_VIEW_ID: diff --git a/gst-libs/gst/vaapi/gstvaapitexture_egl.c b/gst-libs/gst/vaapi/gstvaapitexture_egl.c index efeced4af4..e0eb318375 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_egl.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_egl.c @@ -182,7 +182,7 @@ destroy_objects (GstVaapiTextureEGL * texture) texture->egl_image); texture->egl_image = EGL_NO_IMAGE_KHR; } - gst_vaapi_object_replace (&texture->surface, NULL); + gst_mini_object_replace ((GstMiniObject **) & texture->surface, NULL); gst_vaapi_filter_replace (&texture->filter, NULL); } diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.c b/gst-libs/gst/vaapi/gstvaapitexture_glx.c index b1e641bfbf..dab6ebe848 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_glx.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.c @@ -31,6 +31,7 @@ #include "gstvaapitexture.h" #include "gstvaapitexture_glx.h" #include "gstvaapitexture_priv.h" +#include "gstvaapisurface_priv.h" #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapiutils_glx.h" @@ -344,7 +345,7 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture, }; status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture), - GST_VAAPI_OBJECT_ID (surface), texture->pixo->pixmap, + GST_VAAPI_SURFACE_ID (surface), texture->pixo->pixmap, crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height, 0, 0, base_texture->width, base_texture->height, NULL, 0, from_GstVaapiSurfaceRenderFlags (flags)); diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index 9e79b951ec..faba367752 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -67,21 +67,8 @@ gst_vaapi_video_pool_init (GstVaapiVideoPool * pool, GstVaapiDisplay * display, void gst_vaapi_video_pool_finalize (GstVaapiVideoPool * pool) { - if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE - || pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER) { - g_list_free_full (pool->used_objects, - (GDestroyNotify) gst_mini_object_unref); - } else { - g_list_free_full (pool->used_objects, gst_vaapi_object_unref); - } - - if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE - || pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER) { - g_queue_foreach (&pool->free_objects, (GFunc) gst_mini_object_unref, NULL); - } else { - g_queue_foreach (&pool->free_objects, (GFunc) gst_vaapi_object_unref, NULL); - } - + g_list_free_full (pool->used_objects, (GDestroyNotify) gst_mini_object_unref); + g_queue_foreach (&pool->free_objects, (GFunc) gst_mini_object_unref, NULL); g_queue_clear (&pool->free_objects); gst_vaapi_display_replace (&pool->display, NULL); g_mutex_clear (&pool->mutex); @@ -196,14 +183,7 @@ gst_vaapi_video_pool_get_object_unlocked (GstVaapiVideoPool * pool) ++pool->used_count; pool->used_objects = g_list_prepend (pool->used_objects, object); - - if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE - || pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER) { - object = gst_mini_object_ref (GST_MINI_OBJECT_CAST (object)); - } else { - object = gst_vaapi_object_ref (object); - } - return object; + return gst_mini_object_ref (object); } gpointer @@ -239,13 +219,7 @@ gst_vaapi_video_pool_put_object_unlocked (GstVaapiVideoPool * pool, if (!elem) return; - if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE - || pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER) { - gst_mini_object_unref (GST_MINI_OBJECT_CAST (object)); - } else { - gst_vaapi_object_unref (object); - } - + gst_mini_object_unref (object); --pool->used_count; pool->used_objects = g_list_delete_link (pool->used_objects, elem); g_queue_push_tail (&pool->free_objects, object); @@ -277,13 +251,7 @@ static inline gboolean gst_vaapi_video_pool_add_object_unlocked (GstVaapiVideoPool * pool, gpointer object) { - if (pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_IMAGE - || pool->object_type == GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_CODED_BUFFER) { - g_queue_push_tail (&pool->free_objects, - gst_mini_object_ref (GST_MINI_OBJECT_CAST (object))); - } else { - g_queue_push_tail (&pool->free_objects, gst_vaapi_object_ref (object)); - } + g_queue_push_tail (&pool->free_objects, gst_mini_object_ref (object)); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index ed01f5eaf1..75b9e0e6f3 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -284,7 +284,7 @@ gst_vaapi_window_vpp_convert_internal (GstVaapiWindow * window, error_process_filter: { GST_ERROR ("failed to process surface %" GST_VAAPI_ID_FORMAT " (error %d)", - GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (surface)), status); + GST_VAAPI_ID_ARGS (GST_VAAPI_SURFACE_ID (surface)), status); gst_vaapi_video_pool_put_object (window->surface_pool, vpp_surface); return NULL; } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 39a5e02605..8e091523fb 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -28,7 +28,7 @@ #include "sysdeps.h" #include "gstvaapicompat.h" -#include "gstvaapiobject_priv.h" +#include "gstvaapisurface_priv.h" #include "gstvaapiwindow_wayland.h" #include "gstvaapiwindow_priv.h" #include "gstvaapidisplay_wayland.h" @@ -555,7 +555,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, GST_VAAPI_WINDOW_LOCK_DISPLAY (window); va_flags = from_GstVaapiSurfaceRenderFlags (flags); status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_OBJECT_ID (surface), + GST_VAAPI_SURFACE_ID (surface), va_flags & (VA_TOP_FIELD | VA_BOTTOM_FIELD), &buffer); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED || @@ -583,7 +583,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, GST_VAAPI_WINDOW_LOCK_DISPLAY (window); status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_OBJECT_ID (surface), VA_FRAME_PICTURE, &buffer); + GST_VAAPI_SURFACE_ID (surface), VA_FRAME_PICTURE, &buffer); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); if (!vaapi_check_status (status, "vaGetSurfaceBufferWl()")) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index fd3b045118..bf0b65b323 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -39,7 +39,6 @@ #include "gstvaapisurface_priv.h" #include "gstvaapiutils.h" #include "gstvaapiutils_x11.h" -#include "gstvaapisurface_priv.h" GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapi_window); #define GST_CAT_DEFAULT gst_debug_vaapi_window @@ -449,7 +448,7 @@ gst_vaapi_window_x11_render (GstVaapiWindow * window, GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); gboolean ret = FALSE; - surface_id = GST_VAAPI_OBJECT_ID (surface); + surface_id = GST_VAAPI_SURFACE_ID (surface); if (surface_id == VA_INVALID_ID) return FALSE; @@ -476,7 +475,7 @@ conversion: if (G_LIKELY (vpp_surface)) { GstVaapiRectangle vpp_src_rect; - surface_id = GST_VAAPI_OBJECT_ID (vpp_surface); + surface_id = GST_VAAPI_SURFACE_ID (vpp_surface); vpp_src_rect.x = vpp_src_rect.y = 0; vpp_src_rect.width = GST_VAAPI_SURFACE_WIDTH (vpp_surface); vpp_src_rect.height = GST_VAAPI_SURFACE_HEIGHT (vpp_surface); diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index db088be9e3..eba6efd7b8 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -156,7 +156,7 @@ _set_cached_surface (GstBuffer * buf, GstVaapiSurface * surface) { return gst_mini_object_set_qdata (GST_MINI_OBJECT (buf), g_quark_from_static_string ("GstVaapiDMABufSurface"), surface, - (GDestroyNotify) gst_vaapi_object_unref); + (GDestroyNotify) gst_vaapi_surface_unref); } static gboolean @@ -1387,7 +1387,7 @@ extract_allowed_surface_formats (GstVaapiDisplay * display, if (!image) { /* Just reuse the surface if the format is specified */ if (specified_format == GST_VIDEO_FORMAT_UNKNOWN) - gst_vaapi_object_replace (&surface, NULL); + gst_mini_object_replace ((GstMiniObject **) & surface, NULL); continue; } @@ -1404,11 +1404,11 @@ extract_allowed_surface_formats (GstVaapiDisplay * display, gst_vaapi_image_unref (image); /* Just reuse the surface if the format is specified */ if (specified_format == GST_VIDEO_FORMAT_UNKNOWN) - gst_vaapi_object_replace (&surface, NULL); + gst_mini_object_replace ((GstMiniObject **) & surface, NULL); } if (surface) - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); if (out_formats->len == 0) { g_array_unref (out_formats); diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index c6af52c46b..224a7ed2a3 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -789,7 +789,7 @@ allocator_configure_surface_try_specified_format (GstVaapiDisplay * display, rinfo = *allocation_info; out: - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); *ret_surface_info = rinfo; *ret_usage_flag = rflag; @@ -820,7 +820,7 @@ allocator_configure_surface_try_other_format (GstVaapiDisplay * display, surface = gst_vaapi_surface_new_full (display, &sinfo, 0); if (!surface) goto error_no_surface; - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); *ret_surface_info = sinfo; return TRUE; @@ -1061,7 +1061,7 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, if (needs_surface) { /* The proxy has incremented the surface ref count. */ - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); gst_vaapi_video_meta_set_surface_proxy (meta, proxy); gst_vaapi_surface_proxy_unref (proxy); } @@ -1113,14 +1113,14 @@ error_create_surface: error_create_surface_proxy: { GST_ERROR ("failed to create VA surface proxy"); - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); return NULL; } error_create_dmabuf_proxy: { GST_ERROR ("failed to export VA surface to DMABUF"); if (surface) - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); if (proxy) gst_vaapi_surface_proxy_unref (proxy); return NULL; @@ -1189,7 +1189,7 @@ gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, goto error_no_surface; if (!gst_video_info_update_from_surface (&surface_info, surface)) goto fail; - gst_vaapi_object_replace (&surface, NULL); + gst_mini_object_replace ((GstMiniObject **) & surface, NULL); gst_allocator_set_vaapi_video_info (base_allocator, &surface_info, surface_alloc_flags); @@ -1201,7 +1201,7 @@ gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display, /* ERRORS */ fail: { - gst_vaapi_object_replace (&surface, NULL); + gst_mini_object_replace ((GstMiniObject **) & surface, NULL); gst_object_replace ((GstObject **) & base_allocator, NULL); return NULL; } diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index 3a0d313387..68ee20e005 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -107,7 +107,7 @@ set_surface_proxy (GstVaapiVideoMeta * meta, GstVaapiSurfaceProxy * proxy) return FALSE; meta->proxy = gst_vaapi_surface_proxy_ref (proxy); - set_display (meta, gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface))); + set_display (meta, gst_vaapi_surface_get_display (surface)); return TRUE; } diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index e3f5f1b541..68da63f0a0 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -178,8 +178,7 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, GstVaapiSurfaceProxy *const proxy = gst_vaapi_video_meta_get_surface_proxy (vmeta); GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); - GstVaapiDisplay *const dpy = - gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); + GstVaapiDisplay *const dpy = gst_vaapi_surface_get_display (surface); GstVaapiTexture *texture = NULL; if (!gst_vaapi_display_has_opengl (dpy)) diff --git a/tests/internal/image.c b/tests/internal/image.c index aba0b14516..30256cb72e 100644 --- a/tests/internal/image.c +++ b/tests/internal/image.c @@ -360,7 +360,7 @@ image_upload (GstVaapiImage * image, GstVaapiSurface * surface) GstVaapiSubpicture *subpicture; gboolean success; - display = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface)); + display = gst_vaapi_surface_get_display (surface); if (!display) return FALSE; diff --git a/tests/internal/test-filter.c b/tests/internal/test-filter.c index 926fe7f566..fcdd95c25d 100644 --- a/tests/internal/test-filter.c +++ b/tests/internal/test-filter.c @@ -141,7 +141,7 @@ error_cleanup: if (image) gst_vaapi_image_unref (image); if (surface) - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); if (error_ptr) *error_ptr = error; else @@ -441,8 +441,8 @@ main (int argc, char *argv[]) pause (); gst_object_unref (filter); - gst_vaapi_object_unref (dst_surface); - gst_vaapi_object_unref (src_surface); + gst_vaapi_surface_unref (dst_surface); + gst_vaapi_surface_unref (src_surface); gst_object_unref (window); gst_object_unref (display); video_output_exit (); diff --git a/tests/internal/test-surfaces.c b/tests/internal/test-surfaces.c index 2f9a90fae7..d0fbfaf4dc 100644 --- a/tests/internal/test-surfaces.c +++ b/tests/internal/test-surfaces.c @@ -57,7 +57,7 @@ main (int argc, char *argv[]) g_print ("created surface %" GST_VAAPI_ID_FORMAT "\n", GST_VAAPI_ID_ARGS (surface_id)); - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); pool = gst_vaapi_surface_pool_new (display, GST_VIDEO_FORMAT_ENCODED, width, height); @@ -74,7 +74,8 @@ main (int argc, char *argv[]) } /* Check the pool doesn't return the last free'd surface */ - surface = gst_vaapi_object_ref (surfaces[1]); + surface = (GstVaapiSurface *) + gst_mini_object_ref (GST_MINI_OBJECT_CAST (surfaces[1])); for (i = 0; i < 2; i++) gst_vaapi_video_pool_put_object (pool, surfaces[i]); @@ -100,7 +101,7 @@ main (int argc, char *argv[]) /* Unref in random order to check objects are correctly refcounted */ gst_object_unref (display); gst_vaapi_video_pool_unref (pool); - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); video_output_exit (); return 0; } diff --git a/tests/internal/test-windows.c b/tests/internal/test-windows.c index 5b185ecb5b..b9c9ad1701 100644 --- a/tests/internal/test-windows.c +++ b/tests/internal/test-windows.c @@ -134,7 +134,7 @@ main (int argc, char *argv[]) gst_object_unref (window); } - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); gst_object_unref (display); #endif @@ -199,7 +199,7 @@ main (int argc, char *argv[]) XDestroyWindow (dpy, win); } - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); gst_object_unref (display); #endif @@ -229,7 +229,7 @@ main (int argc, char *argv[]) gst_object_unref (window); } - gst_vaapi_object_unref (surface); + gst_vaapi_surface_unref (surface); gst_object_unref (display); #endif From b2cabe2f5b961e3bea3b4537f86667dd1c493835 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 12 Dec 2019 21:34:21 +0800 Subject: [PATCH 3436/3781] libs: display: refine the profile/entrypoint map. The old way make the one config for each profile/entrypoint pair, which is not very convenient for description the relationship between them. One profile may contain more than one entrypoints to within it, so a set like data structure should be more suitable. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 107 ++++++++++++---------- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 5 +- gst-libs/gst/vaapi/gstvaapiprofile.h | 3 +- 3 files changed, 65 insertions(+), 50 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 2bc08c7d40..bd3334a3d2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -51,11 +51,11 @@ GST_DEBUG_CATEGORY (gst_debug_vaapi_display); G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplay, gst_vaapi_display, GST_TYPE_OBJECT, _do_init); -typedef struct _GstVaapiConfig GstVaapiConfig; -struct _GstVaapiConfig +typedef struct _GstVaapiProfileConfig GstVaapiProfileConfig; +struct _GstVaapiProfileConfig { GstVaapiProfile profile; - GstVaapiEntrypoint entrypoint; + guint32 entrypoints; /* bits map of GstVaapiEntrypoint */ }; typedef struct _GstVaapiProperty GstVaapiProperty; @@ -260,18 +260,18 @@ compare_rgb_formats (gconstpointer a, gconstpointer b) /* Check if configs array contains profile at entrypoint */ static inline gboolean -find_config (GArray * configs, +find_config (GPtrArray * configs, GstVaapiProfile profile, GstVaapiEntrypoint entrypoint) { - GstVaapiConfig *config; + GstVaapiProfileConfig *config; guint i; if (!configs) return FALSE; for (i = 0; i < configs->len; i++) { - config = &g_array_index (configs, GstVaapiConfig, i); - if (config->profile == profile && config->entrypoint == entrypoint) + config = g_ptr_array_index (configs, i); + if (config->profile == profile && (config->entrypoints & (1 << entrypoint))) return TRUE; } return FALSE; @@ -279,21 +279,21 @@ find_config (GArray * configs, /* HACK: append H.263 Baseline profile if MPEG-4:2 Simple profile is supported */ static void -append_h263_config (GArray * configs) +append_h263_config (GArray * configs, GPtrArray * decoders) { - GstVaapiConfig *config, tmp_config; - GstVaapiConfig *mpeg4_simple_config = NULL; - GstVaapiConfig *h263_baseline_config = NULL; + GstVaapiProfileConfig *config, tmp_config; + GstVaapiProfileConfig *mpeg4_simple_config = NULL; + GstVaapiProfileConfig *h263_baseline_config = NULL; guint i; if (!WORKAROUND_H263_BASELINE_DECODE_PROFILE) return; - if (!configs) + if (!decoders) return; - for (i = 0; i < configs->len; i++) { - config = &g_array_index (configs, GstVaapiConfig, i); + for (i = 0; i < decoders->len; i++) { + config = g_ptr_array_index (decoders, i); if (config->profile == GST_VAAPI_PROFILE_MPEG4_SIMPLE) mpeg4_simple_config = config; else if (config->profile == GST_VAAPI_PROFILE_H263_BASELINE) @@ -304,6 +304,8 @@ append_h263_config (GArray * configs) tmp_config = *mpeg4_simple_config; tmp_config.profile = GST_VAAPI_PROFILE_H263_BASELINE; g_array_append_val (configs, tmp_config); + g_ptr_array_add (decoders, &g_array_index (configs, + GstVaapiProfileConfig, configs->len - 1)); } } @@ -311,20 +313,18 @@ append_h263_config (GArray * configs) static gint compare_profiles (gconstpointer a, gconstpointer b) { - const GstVaapiConfig *const config1 = (GstVaapiConfig *) a; - const GstVaapiConfig *const config2 = (GstVaapiConfig *) b; - - if (config1->profile == config2->profile) - return config1->entrypoint - config2->entrypoint; + const GstVaapiProfileConfig *const config1 = (GstVaapiProfileConfig *) a; + const GstVaapiProfileConfig *const config2 = (GstVaapiProfileConfig *) b; + g_assert (config1->profile != config2->profile); return config1->profile - config2->profile; } /* Convert configs array to profiles as GstCaps */ static GArray * -get_profiles (GArray * configs) +get_profiles (GPtrArray * configs) { - GstVaapiConfig *config; + GstVaapiProfileConfig *config; GArray *out_profiles; guint i; @@ -336,7 +336,7 @@ get_profiles (GArray * configs) return NULL; for (i = 0; i < configs->len; i++) { - config = &g_array_index (configs, GstVaapiConfig, i); + config = g_ptr_array_index (configs, i); g_array_append_val (out_profiles, config->profile); } return out_profiles; @@ -470,10 +470,14 @@ ensure_profiles (GstVaapiDisplay * display) return TRUE; } - priv->decoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig)); + priv->codecs = g_array_new (FALSE, FALSE, sizeof (GstVaapiProfileConfig)); + if (!priv->codecs) + goto cleanup; + + priv->decoders = g_ptr_array_new (); if (!priv->decoders) goto cleanup; - priv->encoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig)); + priv->encoders = g_ptr_array_new (); if (!priv->encoders) goto cleanup; priv->has_profiles = TRUE; @@ -502,7 +506,8 @@ ensure_profiles (GstVaapiDisplay * display) } for (i = 0; i < n; i++) { - GstVaapiConfig config; + GstVaapiProfileConfig config; + memset (&config, 0, sizeof (GstVaapiProfileConfig)); config.profile = gst_vaapi_profile (profiles[i]); if (!config.profile) @@ -513,27 +518,30 @@ ensure_profiles (GstVaapiDisplay * display) if (!vaapi_check_status (status, "vaQueryConfigEntrypoints()")) continue; - for (j = 0; j < num_entrypoints; j++) { - config.entrypoint = gst_vaapi_entrypoint (entrypoints[j]); - switch (config.entrypoint) { - case GST_VAAPI_ENTRYPOINT_VLD: - case GST_VAAPI_ENTRYPOINT_IDCT: - case GST_VAAPI_ENTRYPOINT_MOCO: - g_array_append_val (priv->decoders, config); - break; - case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE: - case GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE: - case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP: - case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI: - g_array_append_val (priv->encoders, config); - break; - } - } - } - append_h263_config (priv->decoders); + for (j = 0; j < num_entrypoints; j++) + config.entrypoints |= (1 << gst_vaapi_entrypoint (entrypoints[j])); - g_array_sort (priv->decoders, compare_profiles); - g_array_sort (priv->encoders, compare_profiles); + g_array_append_val (priv->codecs, config); + } + + for (i = 0; i < priv->codecs->len; i++) { + GstVaapiProfileConfig *codec = + &g_array_index (priv->codecs, GstVaapiProfileConfig, i); + if ((codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_VLD) + || (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_IDCT) + || (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_MOCO)) + g_ptr_array_add (priv->decoders, codec); + if ((codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) + || (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE) + || (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) + || (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI)) + g_ptr_array_add (priv->encoders, codec); + } + + append_h263_config (priv->codecs, priv->decoders); + + g_ptr_array_sort (priv->decoders, compare_profiles); + g_ptr_array_sort (priv->encoders, compare_profiles); /* Video processing API */ status = vaQueryConfigEntrypoints (priv->display, VAProfileNone, @@ -817,15 +825,20 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); if (priv->decoders) { - g_array_free (priv->decoders, TRUE); + g_ptr_array_free (priv->decoders, TRUE); priv->decoders = NULL; } if (priv->encoders) { - g_array_free (priv->encoders, TRUE); + g_ptr_array_free (priv->encoders, TRUE); priv->encoders = NULL; } + if (priv->codecs) { + g_array_free (priv->codecs, TRUE); + priv->codecs = NULL; + } + if (priv->image_formats) { g_array_free (priv->image_formats, TRUE); priv->image_formats = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 9a34ba8cd0..0b4e3c3221 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -120,8 +120,9 @@ struct _GstVaapiDisplayPrivate guint height_mm; guint par_n; guint par_d; - GArray *decoders; - GArray *encoders; + GPtrArray *decoders; /* ref element in codecs */ + GPtrArray *encoders; /* ref element in codecs */ + GArray *codecs; GArray *image_formats; GArray *subpicture_formats; GArray *properties; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 8f0039c56b..2833401c0f 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -206,7 +206,8 @@ typedef enum { GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP, - GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI + GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI, + GST_VAAPI_MAX_ENTRYPOINTS } GstVaapiEntrypoint; const gchar * From 4da8dc25508270cc7078fc333a215fb101364531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 20 Dec 2019 08:37:11 +0100 Subject: [PATCH 3437/3781] libs: display: code clean up --- gst-libs/gst/vaapi/gstvaapidisplay.c | 41 ++++++++++++++++------------ gst-libs/gst/vaapi/gstvaapiprofile.h | 3 +- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index bd3334a3d2..cee1fce5f0 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -76,6 +76,8 @@ struct _GstVaapiFormatInfo #define DEFAULT_RENDER_MODE GST_VAAPI_RENDER_MODE_TEXTURE #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 +#define ENTRY_POINT_FLAG(entry) (1U << G_PASTE(GST_VAAPI_ENTRYPOINT_, entry)) + enum { PROP_RENDER_MODE = 1, @@ -260,8 +262,8 @@ compare_rgb_formats (gconstpointer a, gconstpointer b) /* Check if configs array contains profile at entrypoint */ static inline gboolean -find_config (GPtrArray * configs, - GstVaapiProfile profile, GstVaapiEntrypoint entrypoint) +find_config (GPtrArray * configs, GstVaapiProfile profile, + GstVaapiEntrypoint entrypoint) { GstVaapiProfileConfig *config; guint i; @@ -271,7 +273,8 @@ find_config (GPtrArray * configs, for (i = 0; i < configs->len; i++) { config = g_ptr_array_index (configs, i); - if (config->profile == profile && (config->entrypoints & (1 << entrypoint))) + if (config->profile == profile + && (config->entrypoints & (1U << entrypoint))) return TRUE; } return FALSE; @@ -303,6 +306,7 @@ append_h263_config (GArray * configs, GPtrArray * decoders) if (mpeg4_simple_config && !h263_baseline_config) { tmp_config = *mpeg4_simple_config; tmp_config.profile = GST_VAAPI_PROFILE_H263_BASELINE; + tmp_config.entrypoints = ENTRY_POINT_FLAG (VLD); g_array_append_val (configs, tmp_config); g_ptr_array_add (decoders, &g_array_index (configs, GstVaapiProfileConfig, configs->len - 1)); @@ -506,8 +510,7 @@ ensure_profiles (GstVaapiDisplay * display) } for (i = 0; i < n; i++) { - GstVaapiProfileConfig config; - memset (&config, 0, sizeof (GstVaapiProfileConfig)); + GstVaapiProfileConfig config = { 0, }; config.profile = gst_vaapi_profile (profiles[i]); if (!config.profile) @@ -519,23 +522,25 @@ ensure_profiles (GstVaapiDisplay * display) continue; for (j = 0; j < num_entrypoints; j++) - config.entrypoints |= (1 << gst_vaapi_entrypoint (entrypoints[j])); + config.entrypoints |= (1U << gst_vaapi_entrypoint (entrypoints[j])); - g_array_append_val (priv->codecs, config); + priv->codecs = g_array_append_val (priv->codecs, config); } for (i = 0; i < priv->codecs->len; i++) { - GstVaapiProfileConfig *codec = - &g_array_index (priv->codecs, GstVaapiProfileConfig, i); - if ((codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_VLD) - || (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_IDCT) - || (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_MOCO)) - g_ptr_array_add (priv->decoders, codec); - if ((codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) - || (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE) - || (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) - || (codec->entrypoints & 1 << GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI)) - g_ptr_array_add (priv->encoders, codec); + GstVaapiProfileConfig *cfg; + + cfg = &g_array_index (priv->codecs, GstVaapiProfileConfig, i); + + if ((cfg->entrypoints & ENTRY_POINT_FLAG (VLD)) + || (cfg->entrypoints & ENTRY_POINT_FLAG (IDCT)) + || (cfg->entrypoints & ENTRY_POINT_FLAG (MOCO))) + g_ptr_array_add (priv->decoders, cfg); + if ((cfg->entrypoints & ENTRY_POINT_FLAG (SLICE_ENCODE)) + || (cfg->entrypoints & ENTRY_POINT_FLAG (PICTURE_ENCODE)) + || (cfg->entrypoints & ENTRY_POINT_FLAG (SLICE_ENCODE_LP)) + || (cfg->entrypoints & ENTRY_POINT_FLAG (SLICE_ENCODE_FEI))) + g_ptr_array_add (priv->encoders, cfg); } append_h263_config (priv->codecs, priv->decoders); diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 2833401c0f..8f0039c56b 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -206,8 +206,7 @@ typedef enum { GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP, - GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI, - GST_VAAPI_MAX_ENTRYPOINTS + GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI } GstVaapiEntrypoint; const gchar * From 7ce44bc3727abe231769fc7e13f6eb3abc6d9cc6 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 6 Dec 2019 00:21:12 +0800 Subject: [PATCH 3438/3781] plugin: encode: Refine encode's sink caps. The old manner to get the encode's sink caps is not correct. Such as 264 encode, it gets: video/x-raw(memory:VASurface), format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410, Y444 }, width=(int)[ 32, 4096 ], height=(int)[ 32, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, width=(int)[ 32, 4096 ], height=(int)[ 32, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ NV12 }, width=(int)[ 32, 4096 ], height=(int)[ 32, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ] where the formats for memory:VASurface and memory:DMABuf are superfluous. All the "I420, YV12, YUY2, UYVY, Y210, RGBA" can not be really used as input format for encoder. We should get: video/x-raw, format=(string){ NV12 }, width=(int)[ 32, 4096 ], height=(int)[ 32, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:VASurface), format=(string){ NV12 }, width=(int)[ 32, 4096 ], height=(int)[ 32, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), format=(string){ NV12 }, width=(int)[ 32, 4096 ], height=(int)[ 32, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ] as the correct result. --- gst/vaapi/gstvaapiencode.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 46b4737d01..c8a29efa8e 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -382,7 +382,9 @@ get_entrypoint (GstVaapiEncode * encode, GstVaapiProfile profile) static gboolean ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) { - GstCaps *out_caps, *raw_caps = NULL; + GstCaps *out_caps = NULL; + GstCaps *raw_caps = NULL; + GstCaps *va_caps, *dma_caps; GArray *formats = NULL; gboolean ret = FALSE; GstVaapiProfile profile; @@ -398,11 +400,8 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) if (profile == GST_VAAPI_PROFILE_UNKNOWN) return TRUE; - out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS ";" - GST_VAAPI_MAKE_DMABUF_CAPS); - if (!out_caps) - goto failed_create_va_caps; - + /* First get all supported formats, all these formats should be recognized + in video-format map. */ formats = gst_vaapi_encoder_get_surface_formats (encode->encoder, profile); if (!formats) goto failed_get_formats; @@ -411,9 +410,21 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) if (!raw_caps) goto failed_create_raw_caps; - out_caps = gst_caps_make_writable (out_caps); - gst_caps_append (out_caps, gst_caps_copy (raw_caps)); + va_caps = gst_caps_copy (raw_caps); + gst_caps_set_features_simple (va_caps, + gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE)); + dma_caps = gst_caps_copy (raw_caps); + gst_caps_set_features_simple (dma_caps, + gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF)); + + /* collect all caps together. */ + out_caps = raw_caps; + raw_caps = NULL; + gst_caps_append (out_caps, va_caps); + gst_caps_append (out_caps, dma_caps); + + /* Last, set the width/height info to caps */ size = gst_caps_get_size (out_caps); for (i = 0; i < size; i++) { structure = gst_caps_get_structure (out_caps, i); @@ -438,11 +449,6 @@ bail: g_array_unref (formats); return ret; -failed_create_va_caps: - { - GST_WARNING_OBJECT (encode, "failed to create VA/GL sink caps"); - return FALSE; - } failed_get_formats: { GST_WARNING_OBJECT (encode, "failed to get allowed surface formats"); From 18d1c75d1a98123549bb994113df2614655c558b Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 20 Dec 2019 06:38:42 -0800 Subject: [PATCH 3439/3781] plugins: base: do not reset can_dmabuf Don't reset the can_dmabuf field. This restores the close/reset logic that existed prior to commit ca2942176b5632e07eebac23336954f9aaf1cb26 in regards to dmabuf support. Plugins only call gst_vaapi_plugin_base_set_srcpad_can_dmabuf once during startup, but may need to reset the other private fields multiple times during negotiation. Thus, can_dmabuf should be exempt from the resets. Fixes #208 --- gst/vaapi/gstvaapipluginbase.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index eba6efd7b8..7c16778462 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -68,7 +68,6 @@ gst_vaapi_pad_private_reset (GstVaapiPadPrivate * priv) priv->caps_is_raw = FALSE; g_clear_object (&priv->other_allocator); - priv->can_dmabuf = FALSE; } void From 5ad67ea666c96ecd01212caa39ad0b1432e6d726 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sun, 22 Dec 2019 15:22:57 +0800 Subject: [PATCH 3440/3781] libs: encoder: Add NULL pointer check for context when finalize. Context may be NULL if pipeline fail in early stage, and the ensure_context will not be called. Need to add a pointer protection for it. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 2d29d04d2f..3f0e9a7cd0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1345,7 +1345,8 @@ gst_vaapi_encoder_finalize (GObject * object) { GstVaapiEncoder *encoder = GST_VAAPI_ENCODER (object); - gst_vaapi_context_unref (encoder->context); + if (encoder->context) + gst_vaapi_context_unref (encoder->context); encoder->context = NULL; gst_vaapi_display_replace (&encoder->display, NULL); encoder->va_display = NULL; From 3355cd46917bc092f5f237b8154749cfff5c68b6 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sun, 22 Dec 2019 14:35:18 +0800 Subject: [PATCH 3441/3781] plugin: encode: set allowed_sinkpad_caps to empty. We now set encode->allowed_sinkpad_caps to NULL if we fail to get surfaces formats. This causes two problem: 1. gst_video_encoder_proxy_getcaps use NULL as its caps parameter, which changes its behavior. It will use encode's sinkpad template rather than empty caps to do the clip job. So even if we fail to set allowed_sinkpad_caps, gst_video_encoder_proxy_getcaps can still return valid caps. 2. We should just set the allowed_sinkpad_caps once. The NULL point make the ensure_allowed_sinkpad_caps function works again and again. --- gst/vaapi/gstvaapiencode.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index c8a29efa8e..b573e188be 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -441,6 +441,9 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) ret = TRUE; bail: + if (!encode->allowed_sinkpad_caps) + encode->allowed_sinkpad_caps = gst_caps_new_empty (); + if (out_caps) gst_caps_unref (out_caps); if (raw_caps) From c05ce4481540cb74ca6e126f5d16a24d3fcb4732 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sun, 29 Dec 2019 01:13:29 +0800 Subject: [PATCH 3442/3781] libs: pixmap: Fix a pixmap creation crash. We use GST_VAAPI_OBJECT_NATIVE_DISPLAY with wrong parameter for x11 pixmap creation, which causes crash if we run the internal test case of: test-decode --pixmap --- gst-libs/gst/vaapi/gstvaapipixmap_x11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c index 7bdbf5ec67..43a1710def 100644 --- a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c +++ b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c @@ -79,7 +79,7 @@ gst_vaapi_pixmap_x11_create (GstVaapiPixmap * pixmap) { GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11 (GST_VAAPI_OBJECT_DISPLAY (pixmap)); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (display); + Display *const dpy = GST_VAAPI_DISPLAY_NATIVE (display); Window rootwin; Pixmap xid; guint depth; From 4f43d28bebf6803e1bf124c1f1aeef421ac2ffb2 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 27 Dec 2019 18:49:02 +0100 Subject: [PATCH 3443/3781] libs: context: add invalid entrypoint symbol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The symbol GST_VAAPI_ENTRYPOINT_INVALID is just a representation of zero, which was already used as an invalid value tacitly. This patch only makes it explicit. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapicontext.c | 13 ++++++++++--- gst-libs/gst/vaapi/gstvaapiprofile.h | 4 +++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index b26bb52f2b..7c07cce132 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -221,7 +221,8 @@ config_create (GstVaapiContext * context) guint value, va_chroma_format, attrib_index; /* Reset profile and entrypoint */ - if (!cip->profile || !cip->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 = @@ -409,10 +410,12 @@ gst_vaapi_context_new (GstVaapiDisplay * display, { GstVaapiContext *context; - g_return_val_if_fail (cip->profile, NULL); - g_return_val_if_fail (cip->entrypoint, NULL); g_return_val_if_fail (display, NULL); + if (cip->profile == GST_VAAPI_PROFILE_UNKNOWN + || cip->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) + return NULL; + context = g_slice_new (GstVaapiContext); if (!context) return NULL; @@ -470,6 +473,10 @@ gst_vaapi_context_reset (GstVaapiContext * context, 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) { diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 8f0039c56b..72ffd55c5f 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -188,6 +188,7 @@ typedef enum { /** * GstVaapiEntrypoint: + * @GST_VAAPI_ENTRYPOINT_INVALID: Invalid entrypoint * @GST_VAAPI_ENTRYPOINT_VLD: Variable Length Decoding * @GST_VAAPI_ENTRYPOINT_IDCT: Inverse Decrete Cosine Transform * @GST_VAAPI_ENTRYPOINT_MOCO: Motion Compensation @@ -200,7 +201,8 @@ typedef enum { * The set of all entrypoints for #GstVaapiEntrypoint */ typedef enum { - GST_VAAPI_ENTRYPOINT_VLD = 1, + GST_VAAPI_ENTRYPOINT_INVALID, + GST_VAAPI_ENTRYPOINT_VLD, GST_VAAPI_ENTRYPOINT_IDCT, GST_VAAPI_ENTRYPOINT_MOCO, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, From b50f06309afc11da783b977589ab4a708ac87822 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 16 Dec 2019 23:19:46 +0800 Subject: [PATCH 3444/3781] libs: encoder: set context info profile by encoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of init_context_info() setting the passed profile, it is assumed that it has to be set by each encoder. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiencoder.c | 26 +++++++++------------- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 1 + gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 1 + 7 files changed, 23 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 3f0e9a7cd0..ccd804d2de 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -713,21 +713,9 @@ get_default_chroma_type (GstVaapiEncoder * encoder, } static void -init_context_info (GstVaapiEncoder * encoder, GstVaapiContextInfo * cip, - GstVaapiProfile profile) +init_context_info (GstVaapiEncoder * encoder, GstVaapiContextInfo * cip) { - const GstVaapiEncoderClassData *const cdata = - GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; - cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; - cip->profile = profile; - if (cdata->codec == GST_VAAPI_CODEC_JPEG) { - cip->entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; - } else { - if (cip->entrypoint != GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP && - cip->entrypoint != GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI) - cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; - } cip->chroma_type = get_default_chroma_type (encoder, cip); cip->width = 0; cip->height = 0; @@ -744,8 +732,10 @@ set_context_info (GstVaapiEncoder * encoder) GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); guint fei_function = config->fei_function; - init_context_info (encoder, cip, get_profile (encoder)); + g_assert (cip->profile != GST_VAAPI_PROFILE_UNKNOWN); + g_assert (cip->entrypoint != GST_VAAPI_ENTRYPOINT_INVALID); + init_context_info (encoder, cip); cip->chroma_type = gst_vaapi_video_format_get_chroma_type (format); cip->width = GST_VAAPI_ENCODER_WIDTH (encoder); cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); @@ -1483,6 +1473,8 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) static GstVaapiContext * create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile) { + const GstVaapiEncoderClassData *const cdata = + GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; GstVaapiContextInfo cip = { 0, }; GstVaapiContext *ctxt; @@ -1493,7 +1485,11 @@ create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile) if (profile == GST_VAAPI_PROFILE_UNKNOWN) profile = get_profile (encoder); - init_context_info (encoder, &cip, profile); + cip.profile = profile; + cip.entrypoint = (cdata->codec == GST_VAAPI_CODEC_JPEG) ? + GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE : GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + + init_context_info (encoder, &cip); ctxt = gst_vaapi_context_new (encoder->display, &cip); return ctxt; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index f3dcc3df33..abff56a856 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -3346,7 +3346,7 @@ set_context_info (GstVaapiEncoder * base_encoder) GST_VAAPI_ENCODER_H264_COMPLIANCE_MODE_RESTRICT_CODED_BUFFER_ALLOC) base_encoder->codedbuf_size /= encoder->min_cr; - + base_encoder->context_info.profile = base_encoder->profile; base_encoder->context_info.entrypoint = encoder->entrypoint; return GST_VAAPI_ENCODER_STATUS_SUCCESS; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 795075e308..0c14422ae8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2540,6 +2540,7 @@ set_context_info (GstVaapiEncoder * base_encoder) 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; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 5691087751..4c87a8aa38 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -197,6 +197,9 @@ set_context_info (GstVaapiEncoder * base_encoder) 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; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 0aca23ba68..58477d7eec 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -689,6 +689,9 @@ set_context_info (GstVaapiEncoder * base_encoder) base_encoder->codedbuf_size += (GST_ROUND_UP_16 (vip->height) / 16) * MAX_SLICE_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; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index b91fa43517..ce88cfb6f0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -173,6 +173,9 @@ set_context_info (GstVaapiEncoder * base_encoder) 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; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 07c8154b87..9315e3db2f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -219,6 +219,7 @@ set_context_info (GstVaapiEncoder * base_encoder) 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; From 3398c64036dea3781bba843abee998acc80a6c32 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 16 Dec 2019 23:19:46 +0800 Subject: [PATCH 3445/3781] libs: encoder: set entrypoint based on tune automatically Some profile, such as H265_MAIN_444 on new Intel platform, may only support ENTRYPOINT_SLICE_ENCODE_LP entrypoint. This leads two problems: 1. We need to specify the tune mode like `vaapih265enc tune=low-power` every time when we need to use this kind of profile. Or we can not create the encoder context successfully. 2. More seriously, we set the entrypoint to a fixed value in init_context_info() and so the create_test_context_config() can not create the test context for these profile and can not get the supported video formats, either. We now change the entrypoint setting based on the tune option of the encoder. If no tune property provided, we just choose the first available entrypoint. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 57 +++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiencoder.h | 4 ++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 18 +++---- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 12 +++-- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 9 +++- 5 files changed, 82 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index ccd804d2de..a63cb8d18f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1473,8 +1473,6 @@ gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass) static GstVaapiContext * create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile) { - const GstVaapiEncoderClassData *const cdata = - GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; GstVaapiContextInfo cip = { 0, }; GstVaapiContext *ctxt; @@ -1486,8 +1484,15 @@ create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile) profile = get_profile (encoder); cip.profile = profile; - cip.entrypoint = (cdata->codec == GST_VAAPI_CODEC_JPEG) ? - GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE : GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + cip.entrypoint = gst_vaapi_encoder_get_entrypoint (encoder, profile); + if (cip.entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) { + GST_INFO ("can not find %s entrypoint for profile %s to create" + " text context. Ignore this profile", + GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER ? + "the low-power" : "an available", + gst_vaapi_profile_get_va_name (profile)); + return NULL; + } init_context_info (encoder, &cip); ctxt = gst_vaapi_context_new (encoder->display, &cip); @@ -1681,6 +1686,50 @@ gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder) return encoder->profile; } +/* Get the entrypoint based on the tune option. */ +/** + * gst_vaapi_encoder_get_entrypoint: + * @encoder: a #GstVaapiEncoder + * @profile: a #GstVaapiProfile + * + * This function will return the valid entrypoint of the @encoder for + * @profile. If the low-power mode(tune option) is set, only LP + * entrypoints will be considered. If not, the first available entry + * point will be return. + * + * Returns: The #GstVaapiEntrypoint. + **/ +GstVaapiEntrypoint +gst_vaapi_encoder_get_entrypoint (GstVaapiEncoder * encoder, + GstVaapiProfile profile) +{ + /* XXX: The profile may not be the same with encoder->profile */ + + g_return_val_if_fail (encoder, GST_VAAPI_ENTRYPOINT_INVALID); + g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, + GST_VAAPI_ENTRYPOINT_INVALID); + + if (profile == GST_VAAPI_PROFILE_JPEG_BASELINE) + return GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; + + if (GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) { + if (gst_vaapi_display_has_encoder (GST_VAAPI_ENCODER_DISPLAY (encoder), + profile, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)) + return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; + } else { + /* If not set, choose the available one */ + if (gst_vaapi_display_has_encoder (GST_VAAPI_ENCODER_DISPLAY (encoder), + profile, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE)) + return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + + if (gst_vaapi_display_has_encoder (GST_VAAPI_ENCODER_DISPLAY (encoder), + profile, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)) + return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; + } + + return GST_VAAPI_ENTRYPOINT_INVALID; +} + /** Returns a GType for the #GstVaapiEncoderTune set */ GType gst_vaapi_encoder_tune_get_type (void) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index ab4de26218..84ca4aa6dd 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -187,6 +187,10 @@ gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder); +GstVaapiEntrypoint +gst_vaapi_encoder_get_entrypoint (GstVaapiEncoder * encoder, + GstVaapiProfile profile); + G_END_DECLS #endif /* GST_VAAPI_ENCODER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index abff56a856..89a6cc194c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -1301,14 +1301,6 @@ ensure_tuning (GstVaapiEncoderH264 * encoder) case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: success = ensure_tuning_high_compression (encoder); break; - case GST_VAAPI_ENCODER_TUNE_LOW_POWER: - /* Set low-power encode entry point. If hardware doesn't have - * support, it will fail in ensure_hw_profile() in later stage. - * So not duplicating the profile/entrypont query mechanism - * here as a part of optimization */ - encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; - success = TRUE; - break; default: success = TRUE; break; @@ -2738,6 +2730,16 @@ ensure_profile_and_level (GstVaapiEncoderH264 * encoder) if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + /* If set low-power encode entry point and hardware doesn't have + * support, it will fail in ensure_hw_profile() in later stage. */ + encoder->entrypoint = + gst_vaapi_encoder_get_entrypoint (GST_VAAPI_ENCODER_CAST (encoder), + encoder->profile); + if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) { + GST_WARNING ("Cannot find valid entrypoint"); + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + /* Check HW constraints */ if (!ensure_hw_profile_limits (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 0c14422ae8..fcb7bb560d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1082,10 +1082,6 @@ ensure_tuning (GstVaapiEncoderH265 * encoder) case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: success = ensure_tuning_high_compression (encoder); break; - case GST_VAAPI_ENCODER_TUNE_LOW_POWER: - encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; - success = TRUE; - break; default: success = TRUE; break; @@ -2039,6 +2035,14 @@ ensure_profile_tier_level (GstVaapiEncoderH265 * encoder) if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + encoder->entrypoint = + gst_vaapi_encoder_get_entrypoint (GST_VAAPI_ENCODER_CAST (encoder), + encoder->profile); + if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) { + GST_WARNING ("Cannot find valid entrypoint"); + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + /* Check HW constraints */ if (!ensure_hw_profile_limits (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 9315e3db2f..ff679ce32c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -527,8 +527,13 @@ gst_vaapi_encoder_vp9_reconfigure (GstVaapiEncoder * base_encoder) if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; - if (GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) - encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; + encoder->entrypoint = + gst_vaapi_encoder_get_entrypoint (base_encoder, encoder->profile); + if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) { + GST_WARNING ("Cannot find valid entrypoint"); + return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + ensure_control_rate_params (encoder); return set_context_info (base_encoder); } From b4d73433c39e2fadea4a4a43e5d8ce7278832f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 28 Dec 2019 17:42:55 +0100 Subject: [PATCH 3446/3781] libs: encoder: vp9: fix code style --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index ff679ce32c..0c66a29549 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -428,8 +428,8 @@ update_ref_list (GstVaapiEncoderVP9 * encoder, GstVaapiEncPicture * picture, gst_vaapi_surface_proxy_unref (ref); break; case GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_1: - gst_vaapi_surface_proxy_replace (&encoder->ref_list[encoder-> - ref_list_idx], ref); + 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; From a6cf75e8c65542409841a1a45661556c78dcba79 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 30 Dec 2019 14:09:17 +0800 Subject: [PATCH 3447/3781] libs: encoder: get surfaces resolution the same time with formats. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can get all the information about the video format at one shot when we create the test context for getting the supported formats. The current way to get the width and height ranges are inefficient, since it calls the function gst_vaapi_profile_caps_append_encoder() and it creates another temporal context to detect the resolution information. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiencoder.c | 112 +++++++++++++++++---------- gst-libs/gst/vaapi/gstvaapiencoder.h | 5 +- gst/vaapi/gstvaapiencode.c | 45 ++++------- 3 files changed, 92 insertions(+), 70 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index a63cb8d18f..1befb562bf 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1476,12 +1476,7 @@ create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile) GstVaapiContextInfo cip = { 0, }; GstVaapiContext *ctxt; - if (encoder->context) - return gst_vaapi_context_ref (encoder->context); - - /* if there is no profile, let's figure out one */ - if (profile == GST_VAAPI_PROFILE_UNKNOWN) - profile = get_profile (encoder); + g_assert (profile != GST_VAAPI_PROFILE_UNKNOWN); cip.profile = profile; cip.entrypoint = gst_vaapi_encoder_get_entrypoint (encoder, profile); @@ -1499,69 +1494,96 @@ create_test_context_config (GstVaapiEncoder * encoder, GstVaapiProfile profile) return ctxt; } -static GArray * -get_profile_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile) +static gboolean +get_profile_surface_attributes (GstVaapiEncoder * encoder, + GstVaapiProfile profile, GstVaapiConfigSurfaceAttributes * attribs) { - GstVaapiContext *ctxt; - GArray *formats; + GstVaapiContext *ctxt = NULL; + gboolean ret; + + g_return_val_if_fail (attribs != NULL, FALSE); + g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE); ctxt = create_test_context_config (encoder, profile); if (!ctxt) - return NULL; - formats = gst_vaapi_context_get_surface_formats (ctxt); + return FALSE; + + ret = gst_vaapi_context_get_surface_attributes (ctxt, attribs); + if (ret) + attribs->formats = gst_vaapi_context_get_surface_formats (ctxt); + gst_vaapi_context_unref (ctxt); - return formats; + return ret; } static gboolean -merge_profile_surface_formats (GstVaapiEncoder * encoder, - GstVaapiProfile profile, GArray * formats) +merge_profile_surface_attributes (GstVaapiEncoder * encoder, + GstVaapiProfile profile, GstVaapiConfigSurfaceAttributes * attribs) { - GArray *surface_fmts; + GstVaapiConfigSurfaceAttributes attr = { 0, }; guint i, j; GstVideoFormat fmt, sfmt; if (profile == GST_VAAPI_PROFILE_UNKNOWN) return FALSE; - surface_fmts = get_profile_surface_formats (encoder, profile); - if (!surface_fmts) + if (!get_profile_surface_attributes (encoder, profile, &attr)) return FALSE; - for (i = 0; i < surface_fmts->len; i++) { - sfmt = g_array_index (surface_fmts, GstVideoFormat, i); - for (j = 0; j < formats->len; j++) { - fmt = g_array_index (formats, GstVideoFormat, j); + for (i = 0; i < attr.formats->len; i++) { + sfmt = g_array_index (attr.formats, GstVideoFormat, i); + for (j = 0; j < attribs->formats->len; j++) { + fmt = g_array_index (attribs->formats, GstVideoFormat, j); if (fmt == sfmt) break; } - if (j >= formats->len) - g_array_append_val (formats, sfmt); + if (j >= attribs->formats->len) + g_array_append_val (attribs->formats, sfmt); } - g_array_unref (surface_fmts); + g_array_unref (attr.formats); + + attribs->min_width = MIN (attribs->min_width, attr.min_width); + attribs->min_height = MIN (attribs->min_height, attr.min_height); + attribs->max_width = MAX (attribs->max_width, attr.max_width); + attribs->max_height = MAX (attribs->max_height, attr.max_height); + return TRUE; } /** - * gst_vaapi_encoder_get_surface_formats: + * gst_vaapi_encoder_get_surface_attributres: * @encoder: a #GstVaapiEncoder instances + * @profile: a #GstVaapiProfile to test + * @min_width (out): the minimal surface width + * @min_height (out): the minimal surface height + * @max_width (out): the maximal surface width + * @max_height (out): the maximal surface height * - * Fetches the valid surface formats for the current VAConfig + * Fetches the valid surface's attributes for @profile if it is valid, + * Otherwise, it collects surface's attributes for all profiles which + * belong to the current encoder's codec. * - * Returns: a #GArray of valid formats for the current VAConfig + * Returns: a #GArray of valid formats we get or %NULL if failed. **/ GArray * -gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, - GstVaapiProfile profile) +gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder, + GstVaapiProfile profile, gint * min_width, gint * min_height, + gint * max_width, gint * max_height) { const GstVaapiEncoderClassData *const cdata = GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; - GArray *profiles, *formats; + GstVaapiConfigSurfaceAttributes attribs = { + G_MAXINT, G_MAXINT, 1, 1, 0, NULL + }; + GArray *profiles; guint i; - if (profile || encoder->context) - return get_profile_surface_formats (encoder, profile); + if (profile != GST_VAAPI_PROFILE_UNKNOWN) { + if (get_profile_surface_attributes (encoder, profile, &attribs)) + goto success; + return NULL; + } /* no specific context neither specific profile, let's iterate among * the codec's profiles */ @@ -1569,21 +1591,33 @@ gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, if (!profiles) return NULL; - formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat)); + attribs.formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat)); for (i = 0; i < profiles->len; i++) { profile = g_array_index (profiles, GstVaapiProfile, i); if (gst_vaapi_profile_get_codec (profile) == cdata->codec) { - if (!merge_profile_surface_formats (encoder, profile, formats)) { - g_array_unref (formats); - formats = NULL; - break; + if (!merge_profile_surface_attributes (encoder, profile, &attribs)) { + GST_INFO ("Can not get surface formats for profile %s", + gst_vaapi_profile_get_va_name (profile)); + continue; } } } g_array_unref (profiles); - return formats; + if (!attribs.formats) + return NULL; + +success: + if (min_width) + *min_width = attribs.min_width; + if (min_height) + *min_height = attribs.min_height; + if (max_width) + *max_width = attribs.max_width; + if (max_height) + *max_height = attribs.max_height; + return attribs.formats; } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 84ca4aa6dd..1d81baf177 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -181,8 +181,9 @@ GstVaapiEncoderStatus gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); GArray * -gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder, - GstVaapiProfile profile); +gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder, + GstVaapiProfile profile, gint * min_width, gint * min_height, + gint * max_width, gint * max_height); GstVaapiProfile gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder); diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index b573e188be..f19f221388 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -366,19 +366,6 @@ get_profile (GstVaapiEncode * encode) return GST_VAAPI_PROFILE_UNKNOWN; } -static GstVaapiEntrypoint -get_entrypoint (GstVaapiEncode * encode, GstVaapiProfile profile) -{ - GstVaapiEncoderTune tune = GST_VAAPI_ENCODER_TUNE_NONE; - - g_object_get (encode, "tune", &tune, NULL); - if (tune == GST_VAAPI_ENCODER_TUNE_LOW_POWER) - return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; - if (profile == GST_VAAPI_PROFILE_JPEG_BASELINE) - return GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; - return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; -} - static gboolean ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) { @@ -390,6 +377,7 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) GstVaapiProfile profile; guint i, size; GstStructure *structure; + gint min_width, min_height, max_width, max_height; if (encode->allowed_sinkpad_caps) return TRUE; @@ -397,19 +385,28 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) return TRUE; profile = get_profile (encode); - if (profile == GST_VAAPI_PROFILE_UNKNOWN) - return TRUE; /* First get all supported formats, all these formats should be recognized in video-format map. */ - formats = gst_vaapi_encoder_get_surface_formats (encode->encoder, profile); + formats = gst_vaapi_encoder_get_surface_attributes (encode->encoder, profile, + &min_width, &min_height, &max_width, &max_height); if (!formats) - goto failed_get_formats; + goto failed_get_attributes; raw_caps = gst_vaapi_video_format_new_template_caps_from_list (formats); if (!raw_caps) goto failed_create_raw_caps; + /* Set the width/height info to caps */ + size = gst_caps_get_size (raw_caps); + for (i = 0; i < size; i++) { + structure = gst_caps_get_structure (raw_caps, i); + if (!structure) + continue; + gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, min_width, + max_width, "height", GST_TYPE_INT_RANGE, min_height, max_height, NULL); + } + va_caps = gst_caps_copy (raw_caps); gst_caps_set_features_simple (va_caps, gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE)); @@ -424,16 +421,6 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) gst_caps_append (out_caps, va_caps); gst_caps_append (out_caps, dma_caps); - /* Last, set the width/height info to caps */ - size = gst_caps_get_size (out_caps); - for (i = 0; i < size; i++) { - structure = gst_caps_get_structure (out_caps, i); - if (!structure) - continue; - gst_vaapi_profile_caps_append_encoder (GST_VAAPI_PLUGIN_BASE_DISPLAY - (encode), profile, get_entrypoint (encode, profile), structure); - } - gst_caps_replace (&encode->allowed_sinkpad_caps, out_caps); GST_INFO_OBJECT (encode, "Allowed sink caps %" GST_PTR_FORMAT, encode->allowed_sinkpad_caps); @@ -452,9 +439,9 @@ bail: g_array_unref (formats); return ret; -failed_get_formats: +failed_get_attributes: { - GST_WARNING_OBJECT (encode, "failed to get allowed surface formats"); + GST_WARNING_OBJECT (encode, "failed to get surface attributes"); goto bail; } failed_create_raw_caps: From b3570febf7d6a1374d1f516a729861ce39458c66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 2 Jan 2020 18:00:21 +0100 Subject: [PATCH 3448/3781] libs: utils: delete useless gst_vaapi_profile_caps_append_encoder. --- gst-libs/gst/vaapi/gstvaapiprofilecaps.c | 29 ------------------------ gst-libs/gst/vaapi/gstvaapiprofilecaps.h | 5 ---- 2 files changed, 34 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofilecaps.c b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c index 7efa6a3297..a98d0e0df0 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofilecaps.c +++ b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c @@ -117,32 +117,3 @@ gst_vaapi_profile_caps_append_decoder (GstVaapiDisplay * display, return append_caps_with_context_info (display, &cip, structure); } - -/** - * gst_vaapi_profile_caps_append_encoder: - * @display: a #GstVaapiDisplay - * @profile: a #GstVaapiProfile - * @entrypoint: a #GstVaapiEntryPoint - * @structure: a #GstStructure - * - * Extracts the config's surface attributes, from @profile and - * @entrypoint, in an encoder context, and transforms it into a caps - * formats and appended into @structure. - * - * Returns: %TRUE if the capabilities could be extracted and appended - * into @structure; otherwise %FALSE - **/ -gboolean -gst_vaapi_profile_caps_append_encoder (GstVaapiDisplay * display, - GstVaapiProfile profile, GstVaapiEntrypoint entrypoint, - GstStructure * structure) -{ - GstVaapiContextInfo cip = { - GST_VAAPI_CONTEXT_USAGE_ENCODE, profile, entrypoint, 0, - }; - - g_return_val_if_fail (display != NULL, FALSE); - g_return_val_if_fail (structure != NULL, FALSE); - - return append_caps_with_context_info (display, &cip, structure); -} diff --git a/gst-libs/gst/vaapi/gstvaapiprofilecaps.h b/gst-libs/gst/vaapi/gstvaapiprofilecaps.h index 4333bed9dc..24eb82ce2d 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofilecaps.h +++ b/gst-libs/gst/vaapi/gstvaapiprofilecaps.h @@ -33,11 +33,6 @@ gboolean gst_vaapi_profile_caps_append_decoder (GstVaapiDisplay * display, GstVaapiProfile profile, GstStructure * structure); -gboolean -gst_vaapi_profile_caps_append_encoder (GstVaapiDisplay * display, - GstVaapiProfile profile, GstVaapiEntrypoint entrypoint, - GstStructure * structure); - G_END_DECLS #endif /* GST_VAAPI_PROFILE_CAPS_H */ From 196fef9392cd6213a548d1f19be88b971255ee53 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 1 Jan 2020 19:54:13 +0800 Subject: [PATCH 3449/3781] libs: display: fix a resource leak in X11 pixmap format. --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index f5fa2fcee3..a1c82e68fb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -512,6 +512,7 @@ ensure_pix_fmts (GstVaapiDisplayX11 * display) n++; } priv->pixmap_formats->len = n; + XFree (pix_fmts); return TRUE; } From d687e2cb786c5ad13e547d8e954cc3350b644432 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 2 Jan 2020 21:11:44 +0800 Subject: [PATCH 3450/3781] libs: encoder: modify 265 VPS header fields. vps_base_layer_internal_flag and vps_base_layer_available_flag have been clearly defined now. --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index fcb7bb560d..c1d6e1fccb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -289,11 +289,15 @@ bs_write_vps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, guint32 vps_num_layer_sets_minus1 = 0; guint32 vps_timing_info_present_flag = 0; guint32 vps_extension_flag = 0; + guint32 vps_base_layer_internal_flag = 1; + guint32 vps_base_layer_available_flag = 1; /* video_parameter_set_id */ WRITE_UINT32 (bs, video_parameter_set_id, 4); - /* vps_reserved_three_2bits */ - WRITE_UINT32 (bs, 3, 2); + /* vps_base_layer_internal_flag */ + WRITE_UINT32 (bs, vps_base_layer_internal_flag, 1); + /* vps_base_layer_available_flag */ + WRITE_UINT32 (bs, vps_base_layer_available_flag, 1); /* vps_max_layers_minus1 */ WRITE_UINT32 (bs, vps_max_layers_minus1, 6); /* vps_max_sub_layers_minus1 */ From 3cde7db1d36798c7dab16d0dc5790dc1cf81249f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Cerveau?= Date: Mon, 6 Jan 2020 17:41:53 +0100 Subject: [PATCH 3451/3781] doc: fix pipeline typo in vaapipostproc --- gst/vaapi/gstvaapipostproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index d40f39951d..d9d1561928 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -30,7 +30,7 @@ * ## Example launch line * * |[ - * gst-launch-1.0 videotestsrc ! vaapipostproc ! video/x-raw width=1920, height=1080 ! vaapisink + * gst-launch-1.0 videotestsrc ! vaapipostproc ! video/x-raw, width=1920, height=1080 ! vaapisink * ]| */ From 1b7f737ecdd9c64b6792c6577d7ad92dcd25a31e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sun, 5 Jan 2020 19:32:16 +0800 Subject: [PATCH 3452/3781] libs: image: init all image fields correctly. --- gst-libs/gst/vaapi/gstvaapiimage.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 9349af44d3..c67ec1dd8c 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -232,6 +232,10 @@ gst_vaapi_image_init (GstVaapiImage * image, GstVaapiDisplay * display) image->internal_image.buf = VA_INVALID_ID; image->image.image_id = VA_INVALID_ID; image->image.buf = VA_INVALID_ID; + image->image_data = NULL; + image->internal_format = image->format = GST_VIDEO_FORMAT_UNKNOWN; + image->width = image->height = 0; + image->is_linear = FALSE; } GST_DEFINE_MINI_OBJECT_TYPE (GstVaapiImage, gst_vaapi_image); From 894c1da6c770cf3542f90e10da7a105cd5f7faa9 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 14 Nov 2019 11:54:59 -0800 Subject: [PATCH 3453/3781] plugins: base: add GstVideoAggregator subclass support --- gst/vaapi/gstvaapipluginbase.c | 91 ++++++++++++++++++++++++++++------ gst/vaapi/gstvaapipluginbase.h | 29 +++++++++++ 2 files changed, 105 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 7c16778462..e9dd8dec0e 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -841,6 +841,27 @@ _set_sinkpad_caps (GstVaapiPluginBase * plugin, GstPad * sinkpad, return TRUE; } +/** + * gst_vaapi_plugin_base_pad_set_caps: + * @plugin: a #GstVaapiPluginBase + * @sinkpad: the sink pad to set @incaps on + * @incaps: the sink pad (input) caps + * @srcpad: the src pad to set @outcaps on + * @outcaps: the src pad (output) caps + * + * Notifies the base plugin object of the new input and output caps, + * obtained from the subclass on the requested pads. + * + * Returns: %TRUE if the update of caps was successful, %FALSE otherwise. + */ +gboolean +gst_vaapi_plugin_base_pad_set_caps (GstVaapiPluginBase * plugin, + GstPad * sinkpad, GstCaps * incaps, GstPad * srcpad, GstCaps * outcaps) +{ + return _set_sinkpad_caps (plugin, sinkpad, incaps) + && _set_srcpad_caps (plugin, srcpad, outcaps); +} + /** * gst_vaapi_plugin_base_set_caps: * @plugin: a #GstVaapiPluginBase @@ -856,25 +877,26 @@ gboolean gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, GstCaps * outcaps) { - return _set_sinkpad_caps (plugin, plugin->sinkpad, incaps) - && _set_srcpad_caps (plugin, plugin->srcpad, outcaps); + return gst_vaapi_plugin_base_pad_set_caps (plugin, plugin->sinkpad, incaps, + plugin->srcpad, outcaps); } /** - * gst_vaapi_plugin_base_propose_allocation: + * gst_vaapi_plugin_base_pad_propose_allocation: * @plugin: a #GstVaapiPluginBase + * @sinkpad: the sinkpad to configure the allocation query on * @query: the allocation query to configure * - * Proposes allocation parameters to the upstream elements on the base plugin - * static sinkpad. + * Proposes allocation parameters to the upstream elements on the requested + * sinkpad. * * Returns: %TRUE if successful, %FALSE otherwise. */ gboolean -gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, - GstQuery * query) +gst_vaapi_plugin_base_pad_propose_allocation (GstVaapiPluginBase * plugin, + GstPad * sinkpad, GstQuery * query) { - GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (sinkpad); GstCaps *caps = NULL; GstBufferPool *pool = NULL; gboolean need_pool; @@ -884,7 +906,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, if (!caps) goto error_no_caps; - if (!ensure_sinkpad_allocator (plugin, plugin->sinkpad, caps, &size)) + if (!ensure_sinkpad_allocator (plugin, sinkpad, caps, &size)) return FALSE; if (need_pool) { @@ -927,6 +949,24 @@ error_no_caps: } } +/** + * gst_vaapi_plugin_base_propose_allocation: + * @plugin: a #GstVaapiPluginBase + * @query: the allocation query to configure + * + * Proposes allocation parameters to the upstream elements on the base plugin + * static sinkpad. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +gboolean +gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, + GstQuery * query) +{ + return gst_vaapi_plugin_base_pad_propose_allocation (plugin, plugin->sinkpad, + query); +} + /** * gst_vaapi_plugin_base_decide_allocation: * @plugin: a #GstVaapiPluginBase @@ -1120,8 +1160,9 @@ error: } /** - * gst_vaapi_plugin_base_get_input_buffer: + * gst_vaapi_plugin_base_pad_get_input_buffer: * @plugin: a #GstVaapiPluginBase + * @sinkpad: the sink pad to obtain input buffer on * @inbuf: the sink pad (input) buffer * @outbuf_ptr: the pointer to location to the VA surface backed buffer * @@ -1133,10 +1174,10 @@ error: * Returns: #GST_FLOW_OK if the buffer could be acquired */ GstFlowReturn -gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, - GstBuffer * inbuf, GstBuffer ** outbuf_ptr) +gst_vaapi_plugin_base_pad_get_input_buffer (GstVaapiPluginBase * plugin, + GstPad * sinkpad, GstBuffer * inbuf, GstBuffer ** outbuf_ptr) { - GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad); + GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (sinkpad); GstVaapiVideoMeta *meta; GstBuffer *outbuf; GstVideoFrame src_frame, out_frame; @@ -1167,8 +1208,7 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, goto error_create_buffer; if (is_dma_buffer (inbuf)) { - if (!plugin_bind_dma_to_vaapi_buffer (plugin, plugin->sinkpad, inbuf, - outbuf)) + if (!plugin_bind_dma_to_vaapi_buffer (plugin, sinkpad, inbuf, outbuf)) goto error_bind_dma_buffer; goto done; } @@ -1246,6 +1286,27 @@ error_copy_buffer: } } +/** + * gst_vaapi_plugin_base_get_input_buffer: + * @plugin: a #GstVaapiPluginBase + * @inbuf: the sink pad (input) buffer + * @outbuf_ptr: the pointer to location to the VA surface backed buffer + * + * Acquires the static sink pad (input) buffer as a VA surface backed + * buffer. This is mostly useful for raw YUV buffers, as source + * buffers that are already backed as a VA surface are passed + * verbatim. + * + * Returns: #GST_FLOW_OK if the buffer could be acquired + */ +GstFlowReturn +gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, + GstBuffer * inbuf, GstBuffer ** outbuf_ptr) +{ + return gst_vaapi_plugin_base_pad_get_input_buffer (plugin, plugin->sinkpad, + inbuf, outbuf_ptr); +} + /** * gst_vaapi_plugin_base_set_gl_context: * @plugin: a #GstVaapiPluginBase diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index e98b451094..c48f3bbed8 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -138,6 +138,18 @@ struct _GstVaapiPadPrivate GstAllocationParams other_allocator_params; }; +G_GNUC_INTERNAL +GstVaapiPadPrivate * +gst_vaapi_pad_private_new (void); + +G_GNUC_INTERNAL +void +gst_vaapi_pad_private_reset (GstVaapiPadPrivate * priv); + +G_GNUC_INTERNAL +void +gst_vaapi_pad_private_finalize (GstVaapiPadPrivate * priv); + struct _GstVaapiPluginBase { /*< private >*/ @@ -148,6 +160,7 @@ struct _GstVaapiPluginBase GstVideoEncoder encoder; GstBaseTransform transform; GstVideoSink sink; + GstVideoAggregator aggregator; } parent_instance; GstDebugCategory *debug_category; @@ -183,6 +196,7 @@ struct _GstVaapiPluginBaseClass GstVideoEncoderClass encoder; GstBaseTransformClass transform; GstVideoSinkClass sink; + GstVideoAggregatorClass aggregator; } parent_class; gboolean (*has_interface) (GstVaapiPluginBase * plugin, GType type); @@ -239,11 +253,21 @@ gboolean gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, GstCaps * outcaps); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_pad_set_caps (GstVaapiPluginBase *plugin, + GstPad * sinkpad, GstCaps * incaps, GstPad * srcpad, GstCaps * outcaps); + G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, GstQuery * query); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_pad_propose_allocation (GstVaapiPluginBase * plugin, + GstPad * sinkpad, GstQuery * query); + G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, @@ -254,6 +278,11 @@ GstFlowReturn gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, GstBuffer * inbuf, GstBuffer ** outbuf_ptr); +G_GNUC_INTERNAL +GstFlowReturn +gst_vaapi_plugin_base_pad_get_input_buffer (GstVaapiPluginBase * plugin, + GstPad * sinkpad, GstBuffer * inbuf, GstBuffer ** outbuf_ptr); + G_GNUC_INTERNAL void gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, From b76c0a0caf46f69f14316f7cfbad326e4a36cebe Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 14 Nov 2019 12:02:19 -0800 Subject: [PATCH 3454/3781] libs: add a vaapi blend class Support for the VA-API VPP blend functions. --- gst-libs/gst/vaapi/gstvaapiblend.c | 369 +++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiblend.h | 65 +++++ gst-libs/gst/vaapi/meson.build | 2 + 3 files changed, 436 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiblend.c create mode 100644 gst-libs/gst/vaapi/gstvaapiblend.h diff --git a/gst-libs/gst/vaapi/gstvaapiblend.c b/gst-libs/gst/vaapi/gstvaapiblend.c new file mode 100644 index 0000000000..7cf56b00a1 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiblend.c @@ -0,0 +1,369 @@ +/* + * gstvaapiblend.c - Video processing blend + * + * Copyright (C) 2019 Intel Corporation + * Author: U. Artie Eoff + * + * 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); + + 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); + + 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; +#endif + + if (!(blend->flags & VA_BLEND_GLOBAL_ALPHA)) { + GST_WARNING_OBJECT (blend, "VPP does not support global alpha blending"); + return FALSE; + } + + 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)); +} + +/** + * gst_vaapi_blend_process_begin: + * @blend: a #GstVaapiBlend + * @surface: the #GstVaapiSurface output target + * + * Locks the VA display and prepares the VA processing pipeline for rendering. + * + * If this function fails, then the VA display is unlocked before returning. + * + * If this function succeeds, it must be paired with a call to + * #gst_vaapi_blend_process_end to ensure the VA processing pipeline is + * finalized and the VA display is unlocked. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +gboolean +gst_vaapi_blend_process_begin (GstVaapiBlend * blend, GstVaapiSurface * surface) +{ + VAStatus va_status; + + g_return_val_if_fail (blend != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); + + GST_VAAPI_DISPLAY_LOCK (blend->display); + + va_status = vaBeginPicture (GST_VAAPI_DISPLAY_VADISPLAY (blend->display), + blend->va_context, GST_VAAPI_OBJECT_ID (surface)); + + if (!vaapi_check_status (va_status, "vaBeginPicture()")) { + GST_VAAPI_DISPLAY_UNLOCK (blend->display); + return FALSE; + } + + return TRUE; +} + +/** + * gst_vaapi_blend_process_render: + * @blend: a #GstVaapiBlend + * @surface: the source #GstVaapiSurface to send to the VA processing pipeline + * for rendering. + * @crop_rect: the @surface crop extents to process for rendering. + * @target_rect: the extents for which the @surface is rendered within the + * output surface. + * @alpha: the alpha value in the range 0.0 to 1.0, inclusive, for blending + * with the output surface background or with previously rendered surfaces. + * + * Renders the @surface in the currently active VA processing pipeline. + * + * This function must only be called after a successful call to + * #gst_vaapi_blend_process_begin and before calling + * #gst_vaapi_process_end. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +gboolean +gst_vaapi_blend_process_render (GstVaapiBlend * blend, + const GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, + const GstVaapiRectangle * target_rect, gdouble alpha) +{ + VADisplay va_display; + VAStatus va_status; + VAProcPipelineParameterBuffer *param = NULL; + VABufferID id = VA_INVALID_ID; + VARectangle src_rect = { 0, }, dst_rect = { + 0,}; +#if VA_CHECK_VERSION(1,1,0) + VABlendState blend_state; +#endif + + g_return_val_if_fail (blend != NULL, FALSE); + g_return_val_if_fail (surface != NULL, FALSE); + + va_display = GST_VAAPI_DISPLAY_VADISPLAY (blend->display); + + /* Build surface region (source) */ + src_rect.width = GST_VAAPI_SURFACE_WIDTH (surface); + src_rect.height = GST_VAAPI_SURFACE_HEIGHT (surface); + if (crop_rect) { + if ((crop_rect->x + crop_rect->width > src_rect.width) || + (crop_rect->y + crop_rect->height > src_rect.height)) + return FALSE; + + src_rect.x = crop_rect->x; + src_rect.y = crop_rect->y; + src_rect.width = crop_rect->width; + src_rect.height = crop_rect->height; + } + + /* Build output region (target) */ + dst_rect.width = src_rect.width; + dst_rect.height = src_rect.height; + if (target_rect) { + dst_rect.x = target_rect->x; + dst_rect.y = target_rect->y; + dst_rect.width = target_rect->width; + dst_rect.height = target_rect->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_OBJECT_ID (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 = alpha; + param->blend_state = &blend_state; +#endif + + vaapi_unmap_buffer (va_display, id, NULL); + + va_status = vaRenderPicture (va_display, blend->va_context, &id, 1); + if (!vaapi_check_status (va_status, "vaRenderPicture()")) { + vaapi_destroy_buffer (va_display, &id); + return FALSE; + } + + vaapi_destroy_buffer (va_display, &id); + + return TRUE; +} + +/** + * gst_vaapi_blend_process_end: + * @blend: a #GstVaapiBlend + * + * Finalizes all pending render operations in the active VA processing pipeline + * and unlocks the VA display. + * + * This function must always be paired with a call to + * #gst_vaapi_blend_process_begin to ensure the VA display gets unlocked. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +gboolean +gst_vaapi_blend_process_end (GstVaapiBlend * blend) +{ + VAStatus va_status; + + g_return_val_if_fail (blend != NULL, FALSE); + + va_status = vaEndPicture (GST_VAAPI_DISPLAY_VADISPLAY (blend->display), + blend->va_context); + + GST_VAAPI_DISPLAY_UNLOCK (blend->display); + + if (!vaapi_check_status (va_status, "vaEndPicture()")) + return FALSE; + + return TRUE; +} diff --git a/gst-libs/gst/vaapi/gstvaapiblend.h b/gst-libs/gst/vaapi/gstvaapiblend.h new file mode 100644 index 0000000000..60c30c8393 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiblend.h @@ -0,0 +1,65 @@ +/* + * gstvaapiblend.h - Video processing blend + * + * Copyright (C) 2019 Intel Corporation + * Author: U. Artie Eoff + * + * 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 + +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; + +GstVaapiBlend * +gst_vaapi_blend_new (GstVaapiDisplay * display); + +void +gst_vaapi_blend_replace (GstVaapiBlend ** old_blend_ptr, + GstVaapiBlend * new_blend); + +gboolean +gst_vaapi_blend_process_begin (GstVaapiBlend * blend, + GstVaapiSurface * surface); + +gboolean +gst_vaapi_blend_process_render (GstVaapiBlend * blend, + const GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, + const GstVaapiRectangle * target_rect, gdouble alpha); + +gboolean +gst_vaapi_blend_process_end (GstVaapiBlend * blend); + +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 */ diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 68b60eb8f1..83f4a1d5ad 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -1,4 +1,5 @@ gstlibvaapi_sources = [ + 'gstvaapiblend.c', 'gstvaapibufferproxy.c', 'gstvaapicodec_objects.c', 'gstvaapicontext.c', @@ -44,6 +45,7 @@ gstlibvaapi_sources = [ ] gstlibvaapi_headers = [ + 'gstvaapiblend.h', 'gstvaapibufferproxy.h', 'gstvaapidecoder.h', 'gstvaapidecoder_h264.h', From d28ffd73c305a505a0a3621dc3f7befc42be036b Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 14 Nov 2019 12:03:57 -0800 Subject: [PATCH 3455/3781] plugins: add vaapioverlay plugin A plugin similar to the base compositor element but uses VA-API VPP blend functions to accelerate the overlay/compositing. Simple example: gst-launch-1.0 -vf videotestsrc ! vaapipostproc \ ! tee name=testsrc ! queue \ ! vaapioverlay sink_1::xpos=300 sink_1::alpha=0.75 \ name=overlay ! vaapisink testsrc. ! queue ! overlay. --- gst/vaapi/gstvaapi.c | 3 + gst/vaapi/gstvaapioverlay.c | 651 ++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapioverlay.h | 103 ++++++ gst/vaapi/meson.build | 1 + 4 files changed, 758 insertions(+) create mode 100644 gst/vaapi/gstvaapioverlay.c create mode 100644 gst/vaapi/gstvaapioverlay.h diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 43571f084c..8bcf81d2a7 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -24,6 +24,7 @@ #include "gstcompat.h" #include "gstvaapidecode.h" +#include "gstvaapioverlay.h" #include "gstvaapipostproc.h" #include "gstvaapisink.h" #include "gstvaapidecodebin.h" @@ -214,6 +215,8 @@ plugin_init (GstPlugin * plugin) g_array_unref (decoders); } + gst_vaapioverlay_register (plugin, display); + gst_element_register (plugin, "vaapipostproc", GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); diff --git a/gst/vaapi/gstvaapioverlay.c b/gst/vaapi/gstvaapioverlay.c new file mode 100644 index 0000000000..f3baf75e24 --- /dev/null +++ b/gst/vaapi/gstvaapioverlay.c @@ -0,0 +1,651 @@ +/* + * gstvaapioverlay.c - VA-API vpp overlay + * + * Copyright (C) 2019 Intel Corporation + * Author: U. Artie Eoff + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA +*/ + +#include "gstvaapioverlay.h" +#include "gstvaapipluginutil.h" +#include "gstvaapivideobufferpool.h" + +#define GST_PLUGIN_NAME "vaapioverlay" +#define GST_PLUGIN_DESC "A VA-API overlay filter" + +GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapi_overlay); +#ifndef GST_DISABLE_GST_DEBUG +#define GST_CAT_DEFAULT gst_debug_vaapi_overlay +#else +#define GST_CAT_DEFAULT NULL +#endif + +/* Default templates */ +/* *INDENT-OFF* */ +static const char gst_vaapi_overlay_sink_caps_str[] = + GST_VAAPI_MAKE_SURFACE_CAPS ";" + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL); +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static const char gst_vaapi_overlay_src_caps_str[] = + GST_VAAPI_MAKE_SURFACE_CAPS ";" + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL); +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapi_overlay_sink_factory = + GST_STATIC_PAD_TEMPLATE ("sink_%u", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS (gst_vaapi_overlay_sink_caps_str)); +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +static GstStaticPadTemplate gst_vaapi_overlay_src_factory = + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapi_overlay_src_caps_str)); +/* *INDENT-ON* */ + +G_DEFINE_TYPE (GstVaapiOverlaySinkPad, gst_vaapi_overlay_sink_pad, + GST_TYPE_VIDEO_AGGREGATOR_PAD); + +#define DEFAULT_PAD_XPOS 0 +#define DEFAULT_PAD_YPOS 0 +#define DEFAULT_PAD_ALPHA 1.0 + +enum +{ + PROP_PAD_0, + PROP_PAD_XPOS, + PROP_PAD_YPOS, + PROP_PAD_ALPHA, +}; + +static void +gst_vaapi_overlay_sink_pad_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVaapiOverlaySinkPad *pad = GST_VAAPI_OVERLAY_SINK_PAD (object); + + switch (prop_id) { + case PROP_PAD_XPOS: + g_value_set_int (value, pad->xpos); + break; + case PROP_PAD_YPOS: + g_value_set_int (value, pad->ypos); + break; + case PROP_PAD_ALPHA: + g_value_set_double (value, pad->alpha); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_overlay_sink_pad_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVaapiOverlaySinkPad *pad = GST_VAAPI_OVERLAY_SINK_PAD (object); + + switch (prop_id) { + case PROP_PAD_XPOS: + pad->xpos = g_value_get_int (value); + break; + case PROP_PAD_YPOS: + pad->ypos = g_value_get_int (value); + break; + case PROP_PAD_ALPHA: + pad->alpha = g_value_get_double (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_overlay_sink_pad_finalize (GObject * object) +{ + gst_vaapi_pad_private_finalize (GST_VAAPI_OVERLAY_SINK_PAD (object)->priv); + + G_OBJECT_CLASS (gst_vaapi_overlay_sink_pad_parent_class)->finalize (object); +} + +static void +gst_vaapi_overlay_sink_pad_class_init (GstVaapiOverlaySinkPadClass * klass) +{ + GObjectClass *const gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = gst_vaapi_overlay_sink_pad_finalize; + gobject_class->set_property = gst_vaapi_overlay_sink_pad_set_property; + gobject_class->get_property = gst_vaapi_overlay_sink_pad_get_property; + + g_object_class_install_property (gobject_class, PROP_PAD_XPOS, + g_param_spec_int ("xpos", "X Position", "X Position of the picture", + G_MININT, G_MAXINT, DEFAULT_PAD_XPOS, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_PAD_YPOS, + g_param_spec_int ("ypos", "Y Position", "Y Position of the picture", + G_MININT, G_MAXINT, DEFAULT_PAD_YPOS, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_PAD_ALPHA, + g_param_spec_double ("alpha", "Alpha", "Alpha of the picture", 0.0, 1.0, + DEFAULT_PAD_ALPHA, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); +} + +static void +gst_vaapi_overlay_sink_pad_init (GstVaapiOverlaySinkPad * pad) +{ + pad->xpos = DEFAULT_PAD_XPOS; + pad->ypos = DEFAULT_PAD_YPOS; + pad->alpha = DEFAULT_PAD_ALPHA; + pad->priv = gst_vaapi_pad_private_new (); +} + +static void +gst_vaapi_overlay_child_proxy_init (gpointer g_iface, gpointer iface_data); + +G_DEFINE_TYPE_WITH_CODE (GstVaapiOverlay, gst_vaapi_overlay, + GST_TYPE_VIDEO_AGGREGATOR, GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES + G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY, + gst_vaapi_overlay_child_proxy_init)); + +GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT (gst_vaapi_overlay_parent_class); + +static GstPad * +gst_vaapi_overlay_request_new_pad (GstElement * element, GstPadTemplate * templ, + const gchar * req_name, const GstCaps * caps) +{ + GstPad *newpad = GST_PAD (GST_ELEMENT_CLASS + (gst_vaapi_overlay_parent_class)->request_new_pad (element, templ, + req_name, caps)); + + if (!newpad) + GST_DEBUG_OBJECT (element, "could not create/add pad"); + else + gst_child_proxy_child_added (GST_CHILD_PROXY (element), G_OBJECT (newpad), + GST_OBJECT_NAME (newpad)); + + return newpad; +} + +static void +gst_vaapi_overlay_release_pad (GstElement * element, GstPad * pad) +{ + GstVaapiOverlay *const overlay = GST_VAAPI_OVERLAY (element); + + gst_child_proxy_child_removed (GST_CHILD_PROXY (overlay), G_OBJECT (pad), + GST_OBJECT_NAME (pad)); + + GST_ELEMENT_CLASS (gst_vaapi_overlay_parent_class)->release_pad (element, + pad); +} + +static inline gboolean +gst_vaapi_overlay_ensure_display (GstVaapiOverlay * overlay) +{ + return gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (overlay)); +} + +static gboolean +gst_vaapi_overlay_sink_query (GstAggregator * agg, GstAggregatorPad * bpad, + GstQuery * query) +{ + GstVaapiOverlay *const overlay = GST_VAAPI_OVERLAY (agg); + + if (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT) { + if (gst_vaapi_handle_context_query (GST_ELEMENT (overlay), query)) { + GST_DEBUG_OBJECT (overlay, "sharing display %" GST_PTR_FORMAT, + GST_VAAPI_PLUGIN_BASE_DISPLAY (overlay)); + return TRUE; + } + } else if (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION) { + GstCaps *caps; + + gst_query_parse_allocation (query, &caps, NULL); + + if (caps == NULL) + return FALSE; + + if (!gst_vaapi_plugin_base_pad_set_caps + (GST_VAAPI_PLUGIN_BASE (overlay), GST_PAD (bpad), caps, NULL, NULL)) + return FALSE; + } + + return GST_AGGREGATOR_CLASS (gst_vaapi_overlay_parent_class)->sink_query + (agg, bpad, query); +} + +static gboolean +gst_vaapi_overlay_src_query (GstAggregator * agg, GstQuery * query) +{ + GstVaapiOverlay *const overlay = GST_VAAPI_OVERLAY (agg); + + if (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT) { + if (gst_vaapi_handle_context_query (GST_ELEMENT (overlay), query)) { + GST_DEBUG_OBJECT (overlay, "sharing display %" GST_PTR_FORMAT, + GST_VAAPI_PLUGIN_BASE_DISPLAY (overlay)); + return TRUE; + } + } + + return GST_AGGREGATOR_CLASS (gst_vaapi_overlay_parent_class)->src_query + (agg, query); +} + +static gboolean +gst_vaapi_overlay_start (GstAggregator * agg) +{ + GstVaapiOverlay *const overlay = GST_VAAPI_OVERLAY (agg); + + if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (overlay))) + return FALSE; + + if (!gst_vaapi_overlay_ensure_display (overlay)) + return FALSE; + + overlay->blend = + gst_vaapi_blend_new (GST_VAAPI_PLUGIN_BASE_DISPLAY (overlay)); + if (!overlay->blend) + return FALSE; + + return TRUE; +} + +static gboolean +_reset_sinkpad_private (GstElement * element, GstPad * pad, gpointer user_data) +{ + gst_vaapi_pad_private_reset (GST_VAAPI_OVERLAY_SINK_PAD (pad)->priv); + + return TRUE; +} + +static gboolean +gst_vaapi_overlay_stop (GstAggregator * agg) +{ + GstVaapiOverlay *const overlay = GST_VAAPI_OVERLAY (agg); + + gst_vaapi_video_pool_replace (&overlay->blend_pool, NULL); + gst_vaapi_blend_replace (&overlay->blend, NULL); + + gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (overlay)); + + gst_element_foreach_sink_pad (GST_ELEMENT (overlay), _reset_sinkpad_private, + NULL); + + return TRUE; +} + +static void +gst_vaapi_overlay_destroy (GstVaapiOverlay * const overlay) +{ + gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (overlay)); + gst_element_foreach_sink_pad (GST_ELEMENT (overlay), _reset_sinkpad_private, + NULL); +} + +static void +gst_vaapi_overlay_finalize (GObject * object) +{ + GstVaapiOverlay *const overlay = GST_VAAPI_OVERLAY (object); + + gst_vaapi_overlay_destroy (overlay); + gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (overlay)); + + G_OBJECT_CLASS (gst_vaapi_overlay_parent_class)->finalize (object); +} + +static gboolean +gst_vaapi_overlay_propose_allocation (GstAggregator * agg, + GstAggregatorPad * pad, GstQuery * decide_query, GstQuery * query) +{ + return gst_vaapi_plugin_base_pad_propose_allocation + (GST_VAAPI_PLUGIN_BASE (agg), GST_PAD (pad), query); +} + +static gboolean +gst_vaapi_overlay_decide_allocation (GstAggregator * agg, GstQuery * query) +{ + return gst_vaapi_plugin_base_decide_allocation + (GST_VAAPI_PLUGIN_BASE (agg), query); +} + +static gboolean +gst_vaapi_overlay_process_frames (GstVaapiOverlay * overlay) +{ + GList *l; + + for (l = GST_ELEMENT (overlay)->sinkpads; l; l = l->next) { + GstVideoAggregatorPad *vagg_pad = GST_VIDEO_AGGREGATOR_PAD (l->data); + GstVaapiOverlaySinkPad *pad = GST_VAAPI_OVERLAY_SINK_PAD (vagg_pad); + GstVideoFrame *inframe = + gst_video_aggregator_pad_get_prepared_frame (vagg_pad); + GstBuffer *inbuf = NULL; + GstBuffer *buf = gst_video_aggregator_pad_get_current_buffer (vagg_pad); + GstVaapiVideoMeta *inbuf_meta; + GstVaapiRectangle target_rect; + + if (gst_vaapi_plugin_base_pad_get_input_buffer (GST_VAAPI_PLUGIN_BASE + (overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK) + return FALSE; + + /* Current sinkpad may have reached EOS */ + if (!inframe || !inbuf) + continue; + + target_rect.x = pad->xpos; + target_rect.y = pad->ypos; + target_rect.width = GST_VIDEO_FRAME_WIDTH (inframe); + target_rect.height = GST_VIDEO_FRAME_HEIGHT (inframe); + + inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); + + if (!inbuf_meta) { + gst_buffer_unref (inbuf); + return FALSE; + } + + if (!gst_vaapi_blend_process_render (overlay->blend, + gst_vaapi_video_meta_get_surface (inbuf_meta), + gst_vaapi_video_meta_get_render_rect (inbuf_meta), + &target_rect, pad->alpha)) { + gst_buffer_unref (inbuf); + return FALSE; + } + + gst_buffer_unref (inbuf); + } + + return TRUE; +} + +static GstFlowReturn +gst_vaapi_overlay_aggregate_frames (GstVideoAggregator * vagg, + GstBuffer * outbuf) +{ + GstVaapiOverlay *const overlay = GST_VAAPI_OVERLAY (vagg); + GstVaapiVideoMeta *outbuf_meta; + GstVaapiSurface *outbuf_surface; + GstVaapiSurfaceProxy *proxy; + + if (!overlay->blend_pool) { + GstVaapiVideoPool *pool = + gst_vaapi_surface_pool_new_full (GST_VAAPI_PLUGIN_BASE_DISPLAY + (overlay), + GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO (overlay), 0); + if (!pool) + return GST_FLOW_ERROR; + gst_vaapi_video_pool_replace (&overlay->blend_pool, pool); + gst_vaapi_video_pool_unref (pool); + } + + outbuf_meta = gst_buffer_get_vaapi_video_meta (outbuf); + if (!outbuf_meta) + return GST_FLOW_ERROR; + + if (!gst_vaapi_video_meta_get_surface_proxy (outbuf_meta)) { + proxy = gst_vaapi_surface_proxy_new_from_pool + (GST_VAAPI_SURFACE_POOL (overlay->blend_pool)); + if (!proxy) + return GST_FLOW_ERROR; + gst_vaapi_video_meta_set_surface_proxy (outbuf_meta, proxy); + gst_vaapi_surface_proxy_unref (proxy); + } + + outbuf_surface = gst_vaapi_video_meta_get_surface (outbuf_meta); + + if (!gst_vaapi_blend_process_begin (overlay->blend, outbuf_surface)) + return GST_FLOW_ERROR; + + if (!gst_vaapi_overlay_process_frames (overlay)) { + gst_vaapi_blend_process_end (overlay->blend); + return GST_FLOW_ERROR; + } + + if (!gst_vaapi_blend_process_end (overlay->blend)) + return GST_FLOW_ERROR; + + return GST_FLOW_OK; +} + +static GstFlowReturn +gst_vaapi_overlay_create_output_buffer (GstVideoAggregator * vagg, + GstBuffer ** outbuf) +{ + GstVaapiOverlay *const overlay = GST_VAAPI_OVERLAY (vagg); + GstBufferPool *const pool = + GST_VAAPI_PLUGIN_BASE_SRC_PAD_BUFFER_POOL (overlay); + + g_return_val_if_fail (pool != NULL, GST_FLOW_ERROR); + + if (!gst_buffer_pool_is_active (pool) && + !gst_buffer_pool_set_active (pool, TRUE)) { + GST_ERROR_OBJECT (overlay, "failed to activate output video buffer pool"); + return GST_FLOW_ERROR; + } + + *outbuf = NULL; + if ((gst_buffer_pool_acquire_buffer (pool, outbuf, NULL) != GST_FLOW_OK) + || !outbuf) { + GST_ERROR_OBJECT (overlay, "failed to create output video buffer"); + return GST_FLOW_ERROR; + } + + return GST_FLOW_OK; +} + +static gboolean +gst_vaapi_overlay_negotiated_src_caps (GstAggregator * agg, GstCaps * caps) +{ + if (!gst_vaapi_plugin_base_set_caps (GST_VAAPI_PLUGIN_BASE (agg), NULL, caps)) + return FALSE; + + return + GST_AGGREGATOR_CLASS (gst_vaapi_overlay_parent_class)->negotiated_src_caps + (agg, caps); +} + +static GstCaps * +gst_vaapi_overlay_fixate_src_caps (GstAggregator * agg, GstCaps * caps) +{ + GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (agg); + GList *l; + gint best_width = -1, best_height = -1; + gint best_fps_n = -1, best_fps_d = -1; + gdouble best_fps = 0.; + GstCaps *ret = NULL; + GstStructure *s; + + ret = gst_caps_make_writable (caps); + + GST_OBJECT_LOCK (vagg); + for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) { + GstVideoAggregatorPad *vaggpad = l->data; + GstVaapiOverlaySinkPad *pad = GST_VAAPI_OVERLAY_SINK_PAD (vaggpad); + gint this_width, this_height; + gint fps_n, fps_d; + gdouble cur_fps; + + fps_n = GST_VIDEO_INFO_FPS_N (&vaggpad->info); + fps_d = GST_VIDEO_INFO_FPS_D (&vaggpad->info); + + this_width = GST_VIDEO_INFO_WIDTH (&vaggpad->info) + MAX (pad->xpos, 0); + this_height = GST_VIDEO_INFO_HEIGHT (&vaggpad->info) + MAX (pad->ypos, 0); + + if (best_width < this_width) + best_width = this_width; + if (best_height < this_height) + best_height = this_height; + + if (fps_d == 0) + cur_fps = 0.0; + else + gst_util_fraction_to_double (fps_n, fps_d, &cur_fps); + + if (best_fps < cur_fps) { + best_fps = cur_fps; + best_fps_n = fps_n; + best_fps_d = fps_d; + } + } + GST_OBJECT_UNLOCK (vagg); + + if (best_fps_n <= 0 || best_fps_d <= 0 || best_fps == 0.0) { + best_fps_n = 25; + best_fps_d = 1; + best_fps = 25.0; + } + + s = gst_caps_get_structure (ret, 0); + gst_structure_fixate_field_nearest_int (s, "width", best_width); + gst_structure_fixate_field_nearest_int (s, "height", best_height); + gst_structure_fixate_field_nearest_fraction (s, "framerate", best_fps_n, + best_fps_d); + + return gst_caps_fixate (ret); +} + +static GstVaapiPadPrivate * +gst_vaapi_overlay_get_vaapi_pad_private (GstVaapiPluginBase * plugin, + GstPad * pad) +{ + if (GST_IS_VAAPI_OVERLAY_SINK_PAD (pad)) + return GST_VAAPI_OVERLAY_SINK_PAD (pad)->priv; + + g_assert (GST_VAAPI_PLUGIN_BASE_SRC_PAD (plugin) == pad); + return GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE (plugin); +} + +static void +gst_vaapi_overlay_class_init (GstVaapiOverlayClass * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstAggregatorClass *const agg_class = GST_AGGREGATOR_CLASS (klass); + GstVideoAggregatorClass *const vagg_class = + GST_VIDEO_AGGREGATOR_CLASS (klass); + GstVaapiPluginBaseClass *plugin_class = GST_VAAPI_PLUGIN_BASE_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_overlay, + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); + + gst_vaapi_plugin_base_class_init (plugin_class); + plugin_class->get_vaapi_pad_private = + GST_DEBUG_FUNCPTR (gst_vaapi_overlay_get_vaapi_pad_private); + + object_class->finalize = GST_DEBUG_FUNCPTR (gst_vaapi_overlay_finalize); + + agg_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapi_overlay_sink_query); + agg_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapi_overlay_src_query); + agg_class->start = GST_DEBUG_FUNCPTR (gst_vaapi_overlay_start); + agg_class->propose_allocation = + GST_DEBUG_FUNCPTR (gst_vaapi_overlay_propose_allocation); + agg_class->fixate_src_caps = + GST_DEBUG_FUNCPTR (gst_vaapi_overlay_fixate_src_caps); + agg_class->negotiated_src_caps = + GST_DEBUG_FUNCPTR (gst_vaapi_overlay_negotiated_src_caps); + agg_class->decide_allocation = + GST_DEBUG_FUNCPTR (gst_vaapi_overlay_decide_allocation); + agg_class->stop = GST_DEBUG_FUNCPTR (gst_vaapi_overlay_stop); + + vagg_class->aggregate_frames = + GST_DEBUG_FUNCPTR (gst_vaapi_overlay_aggregate_frames); + vagg_class->create_output_buffer = + GST_DEBUG_FUNCPTR (gst_vaapi_overlay_create_output_buffer); + + element_class->request_new_pad = + GST_DEBUG_FUNCPTR (gst_vaapi_overlay_request_new_pad); + element_class->release_pad = + GST_DEBUG_FUNCPTR (gst_vaapi_overlay_release_pad); + element_class->set_context = GST_DEBUG_FUNCPTR (gst_vaapi_base_set_context); + + gst_element_class_add_static_pad_template_with_gtype (element_class, + &gst_vaapi_overlay_sink_factory, GST_TYPE_VAAPI_OVERLAY_SINK_PAD); + + gst_element_class_add_static_pad_template_with_gtype (element_class, + &gst_vaapi_overlay_src_factory, GST_TYPE_AGGREGATOR_PAD); + + gst_element_class_set_static_metadata (element_class, + "VA-API overlay", + "Filter/Editor/Video/Compositor/Hardware", + GST_PLUGIN_DESC, "U. Artie Eoff "); +} + +static void +gst_vaapi_overlay_init (GstVaapiOverlay * overlay) +{ + gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (overlay), GST_CAT_DEFAULT); +} + +/* GstChildProxy implementation */ +static GObject * +gst_vaapi_overlay_child_proxy_get_child_by_index (GstChildProxy * child_proxy, + guint index) +{ + GstVaapiOverlay *overlay = GST_VAAPI_OVERLAY (child_proxy); + GObject *obj = NULL; + + GST_OBJECT_LOCK (overlay); + obj = g_list_nth_data (GST_ELEMENT_CAST (overlay)->sinkpads, index); + if (obj) + gst_object_ref (obj); + GST_OBJECT_UNLOCK (overlay); + + return obj; +} + +static guint +gst_vaapi_overlay_child_proxy_get_children_count (GstChildProxy * child_proxy) +{ + guint count = 0; + GstVaapiOverlay *overlay = GST_VAAPI_OVERLAY (child_proxy); + + GST_OBJECT_LOCK (overlay); + count = GST_ELEMENT_CAST (overlay)->numsinkpads; + GST_OBJECT_UNLOCK (overlay); + + return count; +} + +static void +gst_vaapi_overlay_child_proxy_init (gpointer g_iface, gpointer iface_data) +{ + GstChildProxyInterface *iface = g_iface; + + iface->get_child_by_index = gst_vaapi_overlay_child_proxy_get_child_by_index; + iface->get_children_count = gst_vaapi_overlay_child_proxy_get_children_count; +} + +gboolean +gst_vaapioverlay_register (GstPlugin * plugin, GstVaapiDisplay * display) +{ + GstVaapiBlend *blend = NULL; + + blend = gst_vaapi_blend_new (display); + if (!blend) + return FALSE; + gst_vaapi_blend_replace (&blend, NULL); + + return gst_element_register (plugin, "vaapioverlay", + GST_RANK_PRIMARY, GST_TYPE_VAAPI_OVERLAY); +} diff --git a/gst/vaapi/gstvaapioverlay.h b/gst/vaapi/gstvaapioverlay.h new file mode 100644 index 0000000000..0357cd0fcf --- /dev/null +++ b/gst/vaapi/gstvaapioverlay.h @@ -0,0 +1,103 @@ +/* + * gstvaapioverlay.h - VA-API vpp overlay + * + * Copyright (C) 2019 Intel Corporation + * Author: U. Artie Eoff + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA +*/ + +#ifndef GST_VAAPI_OVERLAY_H +#define GST_VAAPI_OVERLAY_H + +#include "gstvaapipluginbase.h" +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPI_OVERLAY (gst_vaapi_overlay_get_type ()) +#define GST_VAAPI_OVERLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_OVERLAY, GstVaapiOverlay)) +#define GST_VAAPI_OVERLAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_OVERLAY, \ + GstVaapiOverlayClass)) +#define GST_IS_VAAPI_OVERLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_OVERLAY)) +#define GST_IS_VAAPI_OVERLAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_OVERLAY)) +#define GST_VAAPI_OVERLAY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_OVERLAY, \ + GstVaapiOverlayClass)) + +#define GST_TYPE_VAAPI_OVERLAY_SINK_PAD (gst_vaapi_overlay_sink_pad_get_type()) +#define GST_VAAPI_OVERLAY_SINK_PAD(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_OVERLAY_SINK_PAD, \ + GstVaapiOverlaySinkPad)) +#define GST_VAAPI_OVERLAY_SINK_PAD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_OVERLAY_SINK_PAD, \ + GstVaapiOverlaySinkPadClass)) +#define GST_IS_VAAPI_OVERLAY_SINK_PAD(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_OVERLAY_SINK_PAD)) +#define GST_IS_VAAPI_OVERLAY_SINK_PAD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_OVERLAY_SINK_PAD)) + +typedef struct _GstVaapiOverlay GstVaapiOverlay; +typedef struct _GstVaapiOverlayClass GstVaapiOverlayClass; + +typedef struct _GstVaapiOverlaySinkPad GstVaapiOverlaySinkPad; +typedef struct _GstVaapiOverlaySinkPadClass GstVaapiOverlaySinkPadClass; + +struct _GstVaapiOverlay +{ + GstVaapiPluginBase parent_instance; + + GstVaapiBlend *blend; + GstVaapiVideoPool *blend_pool; +}; + +struct _GstVaapiOverlayClass +{ + GstVaapiPluginBaseClass parent_class; +}; + +struct _GstVaapiOverlaySinkPad +{ + GstVideoAggregatorPad parent_instance; + + gint xpos, ypos; + gdouble alpha; + + GstVaapiPadPrivate *priv; +}; + +struct _GstVaapiOverlaySinkPadClass +{ + GstVideoAggregatorPadClass parent_class; +}; + +GType +gst_vaapi_overlay_get_type (void) G_GNUC_CONST; + +GType +gst_vaapi_overlay_sink_pad_get_type (void) G_GNUC_CONST; + +gboolean +gst_vaapioverlay_register (GstPlugin * plugin, GstVaapiDisplay * display); + +G_END_DECLS + +#endif diff --git a/gst/vaapi/meson.build b/gst/vaapi/meson.build index 76b122cc32..c363b00b7e 100644 --- a/gst/vaapi/meson.build +++ b/gst/vaapi/meson.build @@ -2,6 +2,7 @@ vaapi_sources = [ 'gstvaapi.c', 'gstvaapidecode.c', 'gstvaapidecodedoc.c', + 'gstvaapioverlay.c', 'gstvaapipluginbase.c', 'gstvaapipluginutil.c', 'gstvaapipostproc.c', From a3c2c93216f03c9399fb67932e09e428306f0788 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 19 Nov 2019 13:48:22 -0800 Subject: [PATCH 3456/3781] tests: check: add basic vaapioverlay test Add test_overlay_position test to verify sink_1 input is overlayed onto sink_0 input at the appropriate position. --- tests/check/elements/vaapioverlay.c | 213 ++++++++++++++++++++++++++++ tests/check/meson.build | 1 + 2 files changed, 214 insertions(+) create mode 100644 tests/check/elements/vaapioverlay.c diff --git a/tests/check/elements/vaapioverlay.c b/tests/check/elements/vaapioverlay.c new file mode 100644 index 0000000000..d832724a44 --- /dev/null +++ b/tests/check/elements/vaapioverlay.c @@ -0,0 +1,213 @@ +/* + * vaapioverlay.c - GStreamer unit test for the vaapioverlay element + * + * Copyright (C) 2019 Intel Corporation + * Author: U. Artie Eoff + * + * 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 + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +static GMainLoop *main_loop; +static void +message_received (GstBus * bus, GstMessage * message, GstPipeline * bin) +{ + GST_INFO ("bus message from \"%" GST_PTR_FORMAT "\": %" GST_PTR_FORMAT, + GST_MESSAGE_SRC (message), message); + + switch (message->type) { + case GST_MESSAGE_EOS: + g_main_loop_quit (main_loop); + break; + case GST_MESSAGE_WARNING:{ + GError *gerror; + gchar *debug; + + gst_message_parse_warning (message, &gerror, &debug); + gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); + g_error_free (gerror); + g_free (debug); + break; + } + case GST_MESSAGE_ERROR:{ + GError *gerror; + gchar *debug; + + gst_message_parse_error (message, &gerror, &debug); + gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); + g_error_free (gerror); + g_free (debug); + g_main_loop_quit (main_loop); + break; + } + default: + break; + } +} + +static GstBuffer *handoff_buffer = NULL; +static void +on_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad, + gpointer data) +{ + gst_buffer_replace (&handoff_buffer, buffer); +} + +#define TEST_PATTERN_RED 4 +#define TEST_PATTERN_GREEN 5 + +GST_START_TEST (test_overlay_position) +{ + GstElement *bin, *src1, *filter1, *src2, *filter2, *overlay, *sink; + GstBus *bus; + GstPad *pad, *srcpad, *sinkpad; + GstCaps *caps; + GstVideoFrame frame; + GstVideoInfo vinfo; + + /* build pipeline */ + bin = gst_pipeline_new ("pipeline"); + bus = gst_element_get_bus (bin); + gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH); + + src1 = gst_element_factory_make ("videotestsrc", "src1"); + g_object_set (src1, "num-buffers", 1, NULL); + g_object_set (src1, "pattern", TEST_PATTERN_GREEN, NULL); + filter1 = gst_element_factory_make ("capsfilter", "filter1"); + caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "NV12", + "width", G_TYPE_INT, 320, "height", G_TYPE_INT, 240, NULL); + g_object_set (filter1, "caps", caps, NULL); + gst_caps_unref (caps); + + src2 = gst_element_factory_make ("videotestsrc", "src2"); + g_object_set (src2, "num-buffers", 1, NULL); + g_object_set (src2, "pattern", TEST_PATTERN_RED, NULL); + filter2 = gst_element_factory_make ("capsfilter", "filter2"); + caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "NV12", + "width", G_TYPE_INT, 20, "height", G_TYPE_INT, 20, NULL); + g_object_set (filter2, "caps", caps, NULL); + gst_caps_unref (caps); + + overlay = gst_element_factory_make ("vaapioverlay", "overlay"); + sink = gst_element_factory_make ("vaapisink", "sink"); + g_object_set (sink, "signal-handoffs", TRUE, NULL); + g_signal_connect (sink, "handoff", G_CALLBACK (on_handoff), NULL); + + gst_bin_add_many (GST_BIN (bin), src1, filter1, src2, filter2, overlay, + sink, NULL); + gst_element_link (src1, filter1); + gst_element_link (src2, filter2); + gst_element_link (overlay, sink); + + srcpad = gst_element_get_static_pad (filter1, "src"); + sinkpad = gst_element_get_request_pad (overlay, "sink_0"); + g_object_set (sinkpad, "xpos", 0, "ypos", 0, "alpha", 1.0, NULL); + gst_pad_link (srcpad, sinkpad); + gst_object_unref (sinkpad); + gst_object_unref (srcpad); + + srcpad = gst_element_get_static_pad (filter2, "src"); + sinkpad = gst_element_get_request_pad (overlay, "sink_1"); + g_object_set (sinkpad, "xpos", 10, "ypos", 10, "alpha", 1.0, NULL); + gst_pad_link (srcpad, sinkpad); + gst_object_unref (sinkpad); + gst_object_unref (srcpad); + + /* setup and run the main loop */ + main_loop = g_main_loop_new (NULL, FALSE); + g_signal_connect (bus, "message::error", (GCallback) message_received, bin); + g_signal_connect (bus, "message::warning", (GCallback) message_received, bin); + g_signal_connect (bus, "message::eos", (GCallback) message_received, bin); + gst_element_set_state (bin, GST_STATE_PAUSED); + gst_element_get_state (bin, NULL, NULL, GST_CLOCK_TIME_NONE); + gst_element_set_state (bin, GST_STATE_PLAYING); + g_main_loop_run (main_loop); + + /* validate output buffer */ + fail_unless (handoff_buffer != NULL); + pad = gst_element_get_static_pad (sink, "sink"); + caps = gst_pad_get_current_caps (pad); + gst_video_info_from_caps (&vinfo, caps); + gst_caps_unref (caps); + gst_object_unref (pad); + + gst_video_frame_map (&frame, &vinfo, handoff_buffer, GST_MAP_READ); + { + guint i, j, n_planes, plane; + n_planes = GST_VIDEO_FRAME_N_PLANES (&frame); + + for (plane = 0; plane < n_planes; plane++) { + gpointer pd = GST_VIDEO_FRAME_PLANE_DATA (&frame, plane); + gint w = GST_VIDEO_FRAME_COMP_WIDTH (&frame, plane) + * GST_VIDEO_FRAME_COMP_PSTRIDE (&frame, plane); + gint h = GST_VIDEO_FRAME_COMP_HEIGHT (&frame, plane); + gint ps = GST_VIDEO_FRAME_PLANE_STRIDE (&frame, plane); + + for (j = 0; j < h; ++j) { + for (i = 0; i < w; ++i) { + guint8 actual = GST_READ_UINT8 (pd + i); + guint8 expect = 0xff; + if (plane == 0) { + if (i >= 10 && i < 30 && j >= 10 && j < 30) + expect = 0x51; + else + expect = 0x91; + } else { + if (i >= 10 && i < 30 && j >= 5 && j < 15) + expect = (i % 2) ? 0xf0 : 0x5a; + else + expect = (i % 2) ? 0x22 : 0x36; + } + fail_unless (actual == expect, + "Expected 0x%02x but got 0x%02x at (%u,%u,%u)", expect, actual, + plane, i, j); + } + pd += ps; + } + } + } + + /* cleanup */ + gst_buffer_replace (&handoff_buffer, NULL); + gst_element_set_state (bin, GST_STATE_NULL); + g_main_loop_unref (main_loop); + gst_bus_remove_signal_watch (bus); + gst_object_unref (bus); + gst_object_unref (bin); +} + +GST_END_TEST; + +static Suite * +vaapioverlay_suite (void) +{ + Suite *s = suite_create ("vaapioverlay"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_overlay_position); + + return s; +} + +GST_CHECK_MAIN (vaapioverlay); diff --git a/tests/check/meson.build b/tests/check/meson.build index 7ebe8a8fc5..8e631d5737 100644 --- a/tests/check/meson.build +++ b/tests/check/meson.build @@ -1,5 +1,6 @@ tests = [ [ 'elements/vaapipostproc' ], + [ 'elements/vaapioverlay' ], ] test_deps = [gst_dep, gstbase_dep, gstvideo_dep, gstcheck_dep] From db338f131658f7309e55c763b7da7461eaa13327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 22 Dec 2019 17:32:19 +0100 Subject: [PATCH 3457/3781] libs: blend: update to new mini-object API --- gst-libs/gst/vaapi/gstvaapiblend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiblend.c b/gst-libs/gst/vaapi/gstvaapiblend.c index 7cf56b00a1..6a407f35df 100644 --- a/gst-libs/gst/vaapi/gstvaapiblend.c +++ b/gst-libs/gst/vaapi/gstvaapiblend.c @@ -234,7 +234,7 @@ gst_vaapi_blend_process_begin (GstVaapiBlend * blend, GstVaapiSurface * surface) GST_VAAPI_DISPLAY_LOCK (blend->display); va_status = vaBeginPicture (GST_VAAPI_DISPLAY_VADISPLAY (blend->display), - blend->va_context, GST_VAAPI_OBJECT_ID (surface)); + blend->va_context, GST_VAAPI_SURFACE_ID (surface)); if (!vaapi_check_status (va_status, "vaBeginPicture()")) { GST_VAAPI_DISPLAY_UNLOCK (blend->display); @@ -314,7 +314,7 @@ gst_vaapi_blend_process_render (GstVaapiBlend * blend, memset (param, 0, sizeof (*param)); - param->surface = GST_VAAPI_OBJECT_ID (surface); + param->surface = GST_VAAPI_SURFACE_ID (surface); param->surface_region = &src_rect; param->output_region = &dst_rect; param->output_background_color = 0xff000000; From e4b48361701678bdfeed1c64c74a8a8ea80f51da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 6 Jan 2020 14:53:28 +0100 Subject: [PATCH 3458/3781] tests: vaapioverlay: force drm backend --- tests/check/elements/vaapioverlay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/check/elements/vaapioverlay.c b/tests/check/elements/vaapioverlay.c index d832724a44..a8e3dcd162 100644 --- a/tests/check/elements/vaapioverlay.c +++ b/tests/check/elements/vaapioverlay.c @@ -110,7 +110,7 @@ GST_START_TEST (test_overlay_position) overlay = gst_element_factory_make ("vaapioverlay", "overlay"); sink = gst_element_factory_make ("vaapisink", "sink"); - g_object_set (sink, "signal-handoffs", TRUE, NULL); + g_object_set (sink, "display", 4, "signal-handoffs", TRUE, NULL); g_signal_connect (sink, "handoff", G_CALLBACK (on_handoff), NULL); gst_bin_add_many (GST_BIN (bin), src1, filter1, src2, filter2, overlay, From 742d7e17e659c2c87388f21f62ea419aba57247a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 6 Jan 2020 19:39:06 +0100 Subject: [PATCH 3459/3781] test: vaapioverlay: bail test if not available vaapioverlay is only registered if the VA driver support the blend operation. This patch only executes the test if vaapioverlay is available, otherwise the test is bail out without raising an error. --- tests/check/elements/vaapioverlay.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/check/elements/vaapioverlay.c b/tests/check/elements/vaapioverlay.c index a8e3dcd162..7a729873cc 100644 --- a/tests/check/elements/vaapioverlay.c +++ b/tests/check/elements/vaapioverlay.c @@ -85,6 +85,12 @@ GST_START_TEST (test_overlay_position) GstVideoFrame frame; GstVideoInfo vinfo; + /* Check if vaapioverlay is available, since it is only available + * for iHD vaapi driver */ + overlay = gst_element_factory_make ("vaapioverlay", "overlay"); + if (!overlay) + return; + /* build pipeline */ bin = gst_pipeline_new ("pipeline"); bus = gst_element_get_bus (bin); @@ -108,7 +114,6 @@ GST_START_TEST (test_overlay_position) g_object_set (filter2, "caps", caps, NULL); gst_caps_unref (caps); - overlay = gst_element_factory_make ("vaapioverlay", "overlay"); sink = gst_element_factory_make ("vaapisink", "sink"); g_object_set (sink, "display", 4, "signal-handoffs", TRUE, NULL); g_signal_connect (sink, "handoff", G_CALLBACK (on_handoff), NULL); From 9bfc8240b48dd5f40847fd347e69898625d52b19 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 2 Jan 2020 21:02:40 +0800 Subject: [PATCH 3460/3781] libs: encoder: modify 265 SPS header's profile compatibility flag. Make the SPS profile compatibility flags more precisely conform to the HEVC Spec. --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 52 +++++++++++++++++++---- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index c1d6e1fccb..c7bfed9e6e 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -236,19 +236,53 @@ bs_write_profile_tier_level (GstBitWriter * bs, const VAEncSequenceParameterBufferHEVC * seq_param) { guint i; + /* general_profile_space */ WRITE_UINT32 (bs, 0, 2); /* general_tier_flag */ WRITE_UINT32 (bs, seq_param->general_tier_flag, 1); /* general_profile_idc */ WRITE_UINT32 (bs, seq_param->general_profile_idc, 5); - /* general_profile_compatibility_flag[32] */ - for (i = 0; i < 32; i++) { - if (i == 1 || i == 2) - WRITE_UINT32 (bs, 1, 1); - else - WRITE_UINT32 (bs, 0, 1); + + /* general_profile_compatibility_flag[0] */ + WRITE_UINT32 (bs, 0, 1); + /* general_profile_compatibility_flag[1] */ + if (seq_param->general_profile_idc == 1 /* Main profile */ + /* In A.3.4, NOTE: When general_profile_compatibility_flag[ 3 ] is equal + to 1, general_profile_compatibility_flag[ 1 ] and + general_profile_compatibility_flag[ 2 ] should also be equal to 1. */ + || seq_param->general_profile_idc == 3 /* Main Still Picture profile */ + ) { + WRITE_UINT32 (bs, 1, 1); + } else { + WRITE_UINT32 (bs, 0, 1); } + /* general_profile_compatibility_flag[2] */ + if ( + /* In A.3.2, NOTE: When general_profile_compatibility_flag[ 1 ] is equal + to 1, general_profile_compatibility_flag[ 2 ] should also be equal to + 1. */ + seq_param->general_profile_idc == 1 /* Main profile */ + || seq_param->general_profile_idc == 2 /* Main 10 profile */ + /* In A.3.4, NOTE: When general_profile_compatibility_flag[ 3 ] is equal + to 1, general_profile_compatibility_flag[ 1 ] and + general_profile_compatibility_flag[ 2 ] should also be equal to 1. */ + || seq_param->general_profile_idc == 3 /* Main Still Picture profile */ + ) { + WRITE_UINT32 (bs, 1, 1); + } else { + WRITE_UINT32 (bs, 0, 1); + } + /* general_profile_compatibility_flag[3] */ + if (seq_param->general_profile_idc == 3) { + WRITE_UINT32 (bs, 1, 1); + } else { + WRITE_UINT32 (bs, 0, 1); + } + + /* general_profile_compatibility_flag[4~32] */ + WRITE_UINT32 (bs, 0, 28); + /* general_progressive_source_flag */ WRITE_UINT32 (bs, 1, 1); /* general_interlaced_source_flag */ @@ -257,9 +291,11 @@ bs_write_profile_tier_level (GstBitWriter * bs, WRITE_UINT32 (bs, 0, 1); /* general_frame_only_constraint_flag */ WRITE_UINT32 (bs, 1, 1); - /* general_reserved_zero_44bits */ - for (i = 0; i < 44; i++) + /* general_reserved_zero_43bits */ + for (i = 0; i < 43; i++) WRITE_UINT32 (bs, 0, 1); + /* general_inbld_flag */ + WRITE_UINT32 (bs, 0, 1); /* general_level_idc */ WRITE_UINT32 (bs, seq_param->general_level_idc, 8); From 11a8175fffb58e974819ce1de230228821adada5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 29 Dec 2019 17:57:52 +0100 Subject: [PATCH 3461/3781] plugins: add iHD driver in whitelist --- gst/vaapi/gstvaapipluginutil.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 8cea2432bc..dd7cb81553 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -954,6 +954,7 @@ gst_vaapi_driver_is_whitelisted (GstVaapiDisplay * display) guint i; static const gchar *whitelist[] = { "Intel i965 driver", + "Intel iHD driver", NULL }; From 40eceaf64abd0d28ae233f39d10b7526af25fc51 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jan 2020 23:42:21 +0800 Subject: [PATCH 3462/3781] libs: codedbuf: delete a useless field. The context field in GstVaapiCodedBuffer is not inited correctly and is never used, just delete it. --- gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h b/gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h index 85a6193c52..b872b9c8a0 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h +++ b/gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h @@ -45,7 +45,6 @@ struct _GstVaapiCodedBuffer GstVaapiID object_id; /*< public >*/ - GstVaapiContext *context; VACodedBufferSegment *segment_list; }; From ad31d5bb8184f67de6755d4a404ff0aa306f67b2 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 10 Jan 2020 09:26:44 -0800 Subject: [PATCH 3463/3781] plugins: overlay: use proper NULL check on double pointer Check the address of the variable is not NULL, not the address of the pointer. --- gst/vaapi/gstvaapioverlay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapioverlay.c b/gst/vaapi/gstvaapioverlay.c index f3baf75e24..b478d43911 100644 --- a/gst/vaapi/gstvaapioverlay.c +++ b/gst/vaapi/gstvaapioverlay.c @@ -446,7 +446,7 @@ gst_vaapi_overlay_create_output_buffer (GstVideoAggregator * vagg, *outbuf = NULL; if ((gst_buffer_pool_acquire_buffer (pool, outbuf, NULL) != GST_FLOW_OK) - || !outbuf) { + || !*outbuf) { GST_ERROR_OBJECT (overlay, "failed to create output video buffer"); return GST_FLOW_ERROR; } From 3737692dd4f7d50c988d9029905ab8216d692559 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Mon, 13 Jan 2020 15:34:54 +0900 Subject: [PATCH 3464/3781] libs: decoder: Don't unref null object ** (gst-launch-1.0:9789): CRITICAL **: 15:29:09.330: gst_vaapi_context_unref: assertion 'context != NULL' failed --- gst-libs/gst/vaapi/gstvaapidecoder.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 0e9d276426..bec06f5700 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -483,8 +483,10 @@ gst_vaapi_decoder_finalize (GObject * object) decoder->frames = NULL; } - gst_vaapi_context_unref (decoder->context); - decoder->context = NULL; + if (decoder->context) { + gst_vaapi_context_unref (decoder->context); + decoder->context = NULL; + } decoder->va_context = VA_INVALID_ID; gst_vaapi_display_replace (&decoder->display, NULL); From 0a2a25981cd280640be389883cca5f14c09792da Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jan 2020 15:04:18 +0800 Subject: [PATCH 3465/3781] libs: encoder: add a helper function to get all supported profiles --- gst-libs/gst/vaapi/gstvaapiencoder.c | 49 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 3 ++ 2 files changed, 52 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 1befb562bf..b743a5a581 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1764,6 +1764,55 @@ gst_vaapi_encoder_get_entrypoint (GstVaapiEncoder * encoder, return GST_VAAPI_ENTRYPOINT_INVALID; } +/** + * gst_vaapi_encoder_get_available_profiles: + * @encoder: a #GstVaapiEncoder + * + * Collect all supported #GstVaapiProfile of current @encoder's #GstVaapiCodec, + * and return them as a #GArray + * + * Returns: An #GArray of #GstVaapiProfile. + **/ +GArray * +gst_vaapi_encoder_get_available_profiles (GstVaapiEncoder * encoder) +{ + GstVaapiCodec codec; + GArray *all_profiles = NULL; + GArray *profiles = NULL; + GstVaapiProfile profile; + guint i; + + g_return_val_if_fail (encoder != NULL, 0); + + codec = GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data->codec; + + all_profiles = gst_vaapi_display_get_encode_profiles + (GST_VAAPI_ENCODER_DISPLAY (encoder)); + if (!all_profiles) + goto out; + + /* Add all supported profiles belong to current codec */ + profiles = g_array_new (FALSE, FALSE, sizeof (GstVaapiProfile)); + if (!profiles) + goto out; + + for (i = 0; i < all_profiles->len; i++) { + profile = g_array_index (all_profiles, GstVaapiProfile, i); + if (gst_vaapi_profile_get_codec (profile) == codec) + g_array_append_val (profiles, profile); + } + +out: + if (all_profiles) + g_array_unref (all_profiles); + if (profiles && profiles->len == 0) { + g_array_unref (profiles); + profiles = NULL; + } + + return profiles; +} + /** Returns a GType for the #GstVaapiEncoderTune set */ GType gst_vaapi_encoder_tune_get_type (void) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 1d81baf177..fbc81e39e8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -192,6 +192,9 @@ GstVaapiEntrypoint gst_vaapi_encoder_get_entrypoint (GstVaapiEncoder * encoder, GstVaapiProfile profile); +GArray * +gst_vaapi_encoder_get_available_profiles (GstVaapiEncoder * encoder); + G_END_DECLS #endif /* GST_VAAPI_ENCODER_H */ From 67e7e15408dd4077899c533cde2f9e537ff8dc38 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jan 2020 15:07:36 +0800 Subject: [PATCH 3466/3781] plugin: util: add helper function to detect profiles in caps. --- gst/vaapi/gstvaapipluginutil.c | 63 ++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 8 +++++ 2 files changed, 71 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index dd7cb81553..4db9b7792d 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1008,3 +1008,66 @@ gst_vaapi_codecs_has_codec (GArray * codecs, GstVaapiCodec codec) } return FALSE; } + +/** + * gst_vaapi_h26x_encoder_get_profiles_from_caps: + * @caps: a #GstCaps to detect + * @func: a #GstVaapiStrToProfileFunc + * + * This function will detect all profile strings in @caps and + * return the according GstVaapiProfile in array. This can just + * work for h264 and h265 now. + * + * Return: A #GArray of @GstVaapiProfile if succeed, %NULL if fail. + **/ +GArray * +gst_vaapi_h26x_encoder_get_profiles_from_caps (GstCaps * caps, + GstVaapiStrToProfileFunc func) +{ + guint i, j; + GstVaapiProfile profile; + GArray *profiles = NULL; + + if (!caps) + return NULL; + + profiles = g_array_new (FALSE, FALSE, sizeof (GstVaapiProfile)); + if (!profiles) + return NULL; + + for (i = 0; i < gst_caps_get_size (caps); i++) { + GstStructure *const structure = gst_caps_get_structure (caps, i); + const GValue *const value = gst_structure_get_value (structure, "profile"); + + if (value && G_VALUE_HOLDS_STRING (value)) { + const gchar *str = g_value_get_string (value); + if (str) { + profile = func (str); + if (profile != GST_VAAPI_PROFILE_UNKNOWN) + g_array_append_val (profiles, profile); + } + } else if (value && GST_VALUE_HOLDS_LIST (value)) { + const GValue *v; + const gchar *str; + for (j = 0; j < gst_value_list_get_size (value); j++) { + v = gst_value_list_get_value (value, j); + if (!v || !G_VALUE_HOLDS_STRING (v)) + continue; + + str = g_value_get_string (v); + if (str) { + profile = func (str); + if (profile != GST_VAAPI_PROFILE_UNKNOWN) + g_array_append_val (profiles, profile); + } + } + } + } + + if (profiles->len == 0) { + g_array_unref (profiles); + profiles = NULL; + } + + return profiles; +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index bba668b7cd..8ceb7ee167 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -29,6 +29,9 @@ #include #include "gstvaapivideomemory.h" +typedef GstVaapiProfile (*GstVaapiStrToProfileFunc) (const gchar * str); + + G_GNUC_INTERNAL gboolean gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type); @@ -152,4 +155,9 @@ G_GNUC_INTERNAL gboolean gst_vaapi_codecs_has_codec (GArray * codecs, GstVaapiCodec codec); +G_GNUC_INTERNAL +GArray * +gst_vaapi_h26x_encoder_get_profiles_from_caps (GstCaps * caps, + GstVaapiStrToProfileFunc func); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ From 36fd4d5d8ad17abdbb0388c2a23b6b786bb9d75f Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 23 Dec 2019 14:29:08 +0800 Subject: [PATCH 3467/3781] plugin: encode: List all possible profiles to detect input formats. The current get_profile just return one possible profile for the encode, which is not enough. For example, if we want to support HEVC 4:4:4 profile, the input of encode should be VYUA rather than NV12 in HEVC main profile. So the command line: gst-launch-1.0 videotestsrc num-buffers=200 ! capsfilter \ caps=video/x-raw,format=VUYA,width=800,height=600 ! vaapih265enc \ tune=low-power init-qp=30 ! fakesink can not work because vaapih265enc just report NV12 in sink caps, we need to specify the profile obviously like: gst-launch-1.0 videotestsrc num-buffers=200 ! capsfilter \ caps=video/x-raw,format=VUYA,width=800,height=600 ! vaapih265enc \ tune=low-power init-qp=30 ! capsfilter caps=video/x-h265, \ profile=main-444 ! fakesink The encode should have the ability to choose the profile based on input format automatically. If the input video format is VUYA, the main-444 profile should be auto choosed. We modify to let get_allowed_profiles of each encode sub class to return an array of all supported profiles based on downstream's allowed caps, or return NULL if no valid profiles specified by downstream. If no allowed profiles found, all profiles which belong to the current encoder's codec will be the candidates. The function gst_vaapi_encoder_get_surface_attributes collects the surface's attributes for that profile list we just get. So for this case, both NV12 and VUYA should be returned. TODO: some codec like VP9, need to implement the get_profile() function. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 41 ++++++++----------------- gst-libs/gst/vaapi/gstvaapiencoder.h | 2 +- gst/vaapi/gstvaapiencode.c | 45 +++++++++++++++++----------- gst/vaapi/gstvaapiencode.h | 4 ++- gst/vaapi/gstvaapiencode_h264.c | 24 +++++---------- gst/vaapi/gstvaapiencode_h265.c | 24 +++++---------- 6 files changed, 57 insertions(+), 83 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index b743a5a581..e34db34a48 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1554,61 +1554,44 @@ merge_profile_surface_attributes (GstVaapiEncoder * encoder, /** * gst_vaapi_encoder_get_surface_attributres: * @encoder: a #GstVaapiEncoder instances - * @profile: a #GstVaapiProfile to test + * @profiles: a #GArray of #GstVaapiProfile to be test * @min_width (out): the minimal surface width * @min_height (out): the minimal surface height * @max_width (out): the maximal surface width * @max_height (out): the maximal surface height * - * Fetches the valid surface's attributes for @profile if it is valid, - * Otherwise, it collects surface's attributes for all profiles which - * belong to the current encoder's codec. + * Fetches the valid surface's attributes for the specified @profiles * * Returns: a #GArray of valid formats we get or %NULL if failed. **/ GArray * gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder, - GstVaapiProfile profile, gint * min_width, gint * min_height, + GArray * profiles, gint * min_width, gint * min_height, gint * max_width, gint * max_height) { - const GstVaapiEncoderClassData *const cdata = - GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; GstVaapiConfigSurfaceAttributes attribs = { G_MAXINT, G_MAXINT, 1, 1, 0, NULL }; - GArray *profiles; + GstVaapiProfile profile; guint i; - if (profile != GST_VAAPI_PROFILE_UNKNOWN) { - if (get_profile_surface_attributes (encoder, profile, &attribs)) - goto success; - return NULL; - } - - /* no specific context neither specific profile, let's iterate among - * the codec's profiles */ - profiles = gst_vaapi_display_get_encode_profiles (encoder->display); - if (!profiles) - return NULL; - attribs.formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat)); for (i = 0; i < profiles->len; i++) { profile = g_array_index (profiles, GstVaapiProfile, i); - if (gst_vaapi_profile_get_codec (profile) == cdata->codec) { - if (!merge_profile_surface_attributes (encoder, profile, &attribs)) { - GST_INFO ("Can not get surface formats for profile %s", - gst_vaapi_profile_get_va_name (profile)); - continue; - } + g_assert (profile != GST_VAAPI_PROFILE_UNKNOWN); + GST_LOG ("Detect input formats of profile %s", + gst_vaapi_profile_get_va_name (profile)); + + if (!merge_profile_surface_attributes (encoder, profile, &attribs)) { + GST_INFO ("Can not get surface formats for profile %s", + gst_vaapi_profile_get_va_name (profile)); + continue; } } - g_array_unref (profiles); - if (!attribs.formats) return NULL; -success: if (min_width) *min_width = attribs.min_width; if (min_height) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index fbc81e39e8..71da2be16b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -182,7 +182,7 @@ gst_vaapi_encoder_flush (GstVaapiEncoder * encoder); GArray * gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder, - GstVaapiProfile profile, gint * min_width, gint * min_height, + GArray * profiles, gint * min_width, gint * min_height, gint * max_width, gint * max_height); GstVaapiProfile diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index f19f221388..97e8e61bc2 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -340,30 +340,29 @@ gst_vaapiencode_buffer_loop (GstVaapiEncode * encode) gst_pad_pause_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); } -static GstVaapiProfile -get_profile (GstVaapiEncode * encode) +static GArray * +get_profiles (GstVaapiEncode * encode) { GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode); + GArray *profiles = NULL; - if (klass->get_profile) { - GstVaapiProfile profile = GST_VAAPI_PROFILE_UNKNOWN; + if (klass->get_allowed_profiles) { GstCaps *allowed = gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); + GST_LOG_OBJECT (encode, + "Get allowed sink caps from downstream %" GST_PTR_FORMAT, allowed); + if (allowed && !gst_caps_is_empty (allowed) && !gst_caps_is_any (allowed)) + profiles = klass->get_allowed_profiles (encode, allowed); - if (allowed) { - if (!gst_caps_is_empty (allowed) && !gst_caps_is_any (allowed)) - profile = klass->get_profile (allowed); + if (allowed) gst_caps_unref (allowed); - } - if (profile != GST_VAAPI_PROFILE_UNKNOWN) - return profile; + if (profiles) + return profiles; } - if (encode->encoder) - return gst_vaapi_encoder_get_profile (encode->encoder); - - return GST_VAAPI_PROFILE_UNKNOWN; + profiles = gst_vaapi_encoder_get_available_profiles (encode->encoder); + return profiles; } static gboolean @@ -374,7 +373,7 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) GstCaps *va_caps, *dma_caps; GArray *formats = NULL; gboolean ret = FALSE; - GstVaapiProfile profile; + GArray *profiles = NULL; guint i, size; GstStructure *structure; gint min_width, min_height, max_width, max_height; @@ -384,11 +383,14 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) if (!encode->encoder) return TRUE; - profile = get_profile (encode); + /* First, get all possible profiles. */ + profiles = get_profiles (encode); + if (profiles == NULL) + goto failed_get_profiles; - /* First get all supported formats, all these formats should be recognized + /* Then get all supported formats, all these formats should be recognized in video-format map. */ - formats = gst_vaapi_encoder_get_surface_attributes (encode->encoder, profile, + formats = gst_vaapi_encoder_get_surface_attributes (encode->encoder, profiles, &min_width, &min_height, &max_width, &max_height); if (!formats) goto failed_get_attributes; @@ -431,6 +433,8 @@ bail: if (!encode->allowed_sinkpad_caps) encode->allowed_sinkpad_caps = gst_caps_new_empty (); + if (profiles) + g_array_unref (profiles); if (out_caps) gst_caps_unref (out_caps); if (raw_caps) @@ -449,6 +453,11 @@ failed_create_raw_caps: GST_WARNING_OBJECT (encode, "failed to create raw sink caps"); goto bail; } +failed_get_profiles: + { + GST_WARNING_OBJECT (encode, "failed to get supported profiles"); + goto bail; + } } static GstCaps * diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 2b8eab6d28..9f15f1c12c 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -81,7 +81,9 @@ struct _GstVaapiEncodeClass GstFlowReturn (*alloc_buffer) (GstVaapiEncode * encode, GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr); - GstVaapiProfile (*get_profile) (GstCaps * caps); + /* Get all possible profiles based on allowed caps */ + GArray * (*get_allowed_profiles) (GstVaapiEncode * encode, + GstCaps * allowed); #if USE_H264_FEI_ENCODER diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 018917f866..3a119bccbb 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -128,23 +128,12 @@ gst_vaapiencode_h264_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapiencode_h264_parent_class)->finalize (object); } -static GstVaapiProfile -gst_vaapiencode_h264_get_profile (GstCaps * caps) +static GArray * +gst_vaapiencode_h264_get_allowed_profiles (GstVaapiEncode * encode, + GstCaps * allowed) { - guint i; - - for (i = 0; i < gst_caps_get_size (caps); i++) { - GstStructure *const structure = gst_caps_get_structure (caps, i); - const GValue *const value = gst_structure_get_value (structure, "profile"); - - if (value && G_VALUE_HOLDS_STRING (value)) { - const gchar *str = g_value_get_string (value); - if (str) - return gst_vaapi_utils_h264_get_profile_from_string (str); - } - } - - return GST_VAAPI_PROFILE_UNKNOWN; + return gst_vaapi_h26x_encoder_get_profiles_from_caps (allowed, + gst_vaapi_utils_h264_get_profile_from_string); } typedef struct @@ -556,7 +545,8 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) object_class->set_property = gst_vaapiencode_set_property_subclass; object_class->get_property = gst_vaapiencode_get_property_subclass; - encode_class->get_profile = gst_vaapiencode_h264_get_profile; + encode_class->get_allowed_profiles = + gst_vaapiencode_h264_get_allowed_profiles; encode_class->set_config = gst_vaapiencode_h264_set_config; encode_class->get_caps = gst_vaapiencode_h264_get_caps; encode_class->alloc_encoder = gst_vaapiencode_h264_alloc_encoder; diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 5fb2cfbded..a3325e6a4f 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -99,23 +99,12 @@ gst_vaapiencode_h265_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapiencode_h265_parent_class)->finalize (object); } -static GstVaapiProfile -gst_vaapiencode_h265_get_profile (GstCaps * caps) +static GArray * +gst_vaapiencode_h265_get_allowed_profiles (GstVaapiEncode * encode, + GstCaps * allowed) { - guint i; - - for (i = 0; i < gst_caps_get_size (caps); i++) { - GstStructure *const structure = gst_caps_get_structure (caps, i); - const GValue *const value = gst_structure_get_value (structure, "profile"); - - if (value && G_VALUE_HOLDS_STRING (value)) { - const gchar *str = g_value_get_string (value); - if (str) - return gst_vaapi_utils_h265_get_profile_from_string (str); - } - } - - return GST_VAAPI_PROFILE_UNKNOWN; + return gst_vaapi_h26x_encoder_get_profiles_from_caps (allowed, + gst_vaapi_utils_h265_get_profile_from_string); } typedef struct @@ -386,7 +375,8 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass) object_class->set_property = gst_vaapiencode_set_property_subclass; object_class->get_property = gst_vaapiencode_get_property_subclass; - encode_class->get_profile = gst_vaapiencode_h265_get_profile; + encode_class->get_allowed_profiles = + gst_vaapiencode_h265_get_allowed_profiles; encode_class->set_config = gst_vaapiencode_h265_set_config; encode_class->get_caps = gst_vaapiencode_h265_get_caps; encode_class->alloc_encoder = gst_vaapiencode_h265_alloc_encoder; From 1363b53a9f3654f70dc63addaa15337a533c1ca2 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 10 Jan 2020 09:54:30 -0800 Subject: [PATCH 3468/3781] libs: blend: add surface generator API This new API allows the user to call a single method (process) which handles the [display] lock/unlock logic internally for them. This API supersedes the risky begin, render, end API. It eliminates the need for the user to call a lock method (process_begin) before processing the input buffers (process_render) and calling an unlock method (process_end) afterwards. See #219 --- gst-libs/gst/vaapi/gstvaapiblend.c | 98 ++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiblend.h | 19 ++++++ 2 files changed, 117 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiblend.c b/gst-libs/gst/vaapi/gstvaapiblend.c index 6a407f35df..426785eb34 100644 --- a/gst-libs/gst/vaapi/gstvaapiblend.c +++ b/gst-libs/gst/vaapi/gstvaapiblend.c @@ -367,3 +367,101 @@ gst_vaapi_blend_process_end (GstVaapiBlend * blend) return TRUE; } + +static gboolean +gst_vaapi_blend_process_unlocked (GstVaapiBlend * blend, + GstVaapiSurface * output, GstVaapiBlendSurfaceGenerator * generator) +{ + 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 = generator->next (generator); + for (; current; current = generator->next (generator)) { + 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; +} + +gboolean +gst_vaapi_blend_process (GstVaapiBlend * blend, GstVaapiSurface * output, + GstVaapiBlendSurfaceGenerator * generator) +{ + gboolean result; + + g_return_val_if_fail (blend != NULL, FALSE); + g_return_val_if_fail (output != NULL, FALSE); + g_return_val_if_fail (generator != NULL, FALSE); + g_return_val_if_fail (generator->next != NULL, FALSE); + + GST_VAAPI_DISPLAY_LOCK (blend->display); + result = gst_vaapi_blend_process_unlocked (blend, output, generator); + GST_VAAPI_DISPLAY_UNLOCK (blend->display); + + return result; +} diff --git a/gst-libs/gst/vaapi/gstvaapiblend.h b/gst-libs/gst/vaapi/gstvaapiblend.h index 60c30c8393..6119c79468 100644 --- a/gst-libs/gst/vaapi/gstvaapiblend.h +++ b/gst-libs/gst/vaapi/gstvaapiblend.h @@ -35,6 +35,21 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_BLEND)) typedef struct _GstVaapiBlend GstVaapiBlend; +typedef struct _GstVaapiBlendSurface GstVaapiBlendSurface; +typedef struct _GstVaapiBlendSurfaceGenerator GstVaapiBlendSurfaceGenerator; + +struct _GstVaapiBlendSurface +{ + GstVaapiSurface const *surface; + const GstVaapiRectangle *crop; + GstVaapiRectangle target; + gdouble alpha; +}; + +struct _GstVaapiBlendSurfaceGenerator +{ + GstVaapiBlendSurface* (*next)(); +}; GstVaapiBlend * gst_vaapi_blend_new (GstVaapiDisplay * display); @@ -43,6 +58,10 @@ void gst_vaapi_blend_replace (GstVaapiBlend ** old_blend_ptr, GstVaapiBlend * new_blend); +gboolean +gst_vaapi_blend_process (GstVaapiBlend * blend, GstVaapiSurface * output, + GstVaapiBlendSurfaceGenerator * generator); + gboolean gst_vaapi_blend_process_begin (GstVaapiBlend * blend, GstVaapiSurface * surface); From edca6efedee8f69f54bf9ef4e8c4d5ea704adac3 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 10 Jan 2020 10:12:36 -0800 Subject: [PATCH 3469/3781] vaapioverlay: use blend surface generator API See #219 --- gst/vaapi/gstvaapioverlay.c | 105 +++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 43 deletions(-) diff --git a/gst/vaapi/gstvaapioverlay.c b/gst/vaapi/gstvaapioverlay.c index b478d43911..59b1a2892a 100644 --- a/gst/vaapi/gstvaapioverlay.c +++ b/gst/vaapi/gstvaapioverlay.c @@ -66,6 +66,15 @@ static GstStaticPadTemplate gst_vaapi_overlay_src_factory = G_DEFINE_TYPE (GstVaapiOverlaySinkPad, gst_vaapi_overlay_sink_pad, GST_TYPE_VIDEO_AGGREGATOR_PAD); +typedef struct _GstVaapiOverlaySurfaceGenerator GstVaapiOverlaySurfaceGenerator; +struct _GstVaapiOverlaySurfaceGenerator +{ + GstVaapiBlendSurfaceGenerator parent; + GstVaapiOverlay *overlay; + GList *current; + GstVaapiBlendSurface blend_surface; +}; + #define DEFAULT_PAD_XPOS 0 #define DEFAULT_PAD_YPOS 0 #define DEFAULT_PAD_ALPHA 1.0 @@ -330,53 +339,64 @@ gst_vaapi_overlay_decide_allocation (GstAggregator * agg, GstQuery * query) (GST_VAAPI_PLUGIN_BASE (agg), query); } -static gboolean -gst_vaapi_overlay_process_frames (GstVaapiOverlay * overlay) +static GstVaapiBlendSurface * +gst_vaapi_overlay_surface_next (GstVaapiBlendSurfaceGenerator * generator) { - GList *l; + GstVaapiOverlaySurfaceGenerator *ogenerator; + GstVideoAggregatorPad *vagg_pad; + GstVaapiOverlaySinkPad *pad; + GstVideoFrame *inframe; + GstBuffer *inbuf; + GstBuffer *buf; + GstVaapiVideoMeta *inbuf_meta; + GstVaapiBlendSurface *blend_surface; - for (l = GST_ELEMENT (overlay)->sinkpads; l; l = l->next) { - GstVideoAggregatorPad *vagg_pad = GST_VIDEO_AGGREGATOR_PAD (l->data); - GstVaapiOverlaySinkPad *pad = GST_VAAPI_OVERLAY_SINK_PAD (vagg_pad); - GstVideoFrame *inframe = - gst_video_aggregator_pad_get_prepared_frame (vagg_pad); - GstBuffer *inbuf = NULL; - GstBuffer *buf = gst_video_aggregator_pad_get_current_buffer (vagg_pad); - GstVaapiVideoMeta *inbuf_meta; - GstVaapiRectangle target_rect; + ogenerator = (GstVaapiOverlaySurfaceGenerator *) generator; - if (gst_vaapi_plugin_base_pad_get_input_buffer (GST_VAAPI_PLUGIN_BASE - (overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK) - return FALSE; + /* at the end of the generator? */ + if (!ogenerator->current) + return NULL; - /* Current sinkpad may have reached EOS */ - if (!inframe || !inbuf) - continue; + /* get the current video aggregator sinkpad */ + vagg_pad = GST_VIDEO_AGGREGATOR_PAD (ogenerator->current->data); - target_rect.x = pad->xpos; - target_rect.y = pad->ypos; - target_rect.width = GST_VIDEO_FRAME_WIDTH (inframe); - target_rect.height = GST_VIDEO_FRAME_HEIGHT (inframe); + /* increment list pointer */ + ogenerator->current = ogenerator->current->next; - inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); + /* recycle the blend surface from the overlay surface generator */ + blend_surface = &ogenerator->blend_surface; + blend_surface->surface = NULL; - if (!inbuf_meta) { - gst_buffer_unref (inbuf); - return FALSE; - } + inframe = gst_video_aggregator_pad_get_prepared_frame (vagg_pad); + buf = gst_video_aggregator_pad_get_current_buffer (vagg_pad); + pad = GST_VAAPI_OVERLAY_SINK_PAD (vagg_pad); - if (!gst_vaapi_blend_process_render (overlay->blend, - gst_vaapi_video_meta_get_surface (inbuf_meta), - gst_vaapi_video_meta_get_render_rect (inbuf_meta), - &target_rect, pad->alpha)) { - gst_buffer_unref (inbuf); - return FALSE; - } + if (gst_vaapi_plugin_base_pad_get_input_buffer (GST_VAAPI_PLUGIN_BASE + (ogenerator->overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK) + return blend_surface; + /* Current sinkpad may have reached EOS */ + if (!inframe || !inbuf) + return generator->next (generator); + + inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); + + if (!inbuf_meta) { gst_buffer_unref (inbuf); + return blend_surface; } - return TRUE; + blend_surface->surface = gst_vaapi_video_meta_get_surface (inbuf_meta); + blend_surface->crop = gst_vaapi_video_meta_get_render_rect (inbuf_meta); + blend_surface->target.x = pad->xpos; + blend_surface->target.y = pad->ypos; + blend_surface->target.width = GST_VIDEO_FRAME_WIDTH (inframe); + blend_surface->target.height = GST_VIDEO_FRAME_HEIGHT (inframe); + blend_surface->alpha = pad->alpha; + + gst_buffer_unref (inbuf); + + return blend_surface; } static GstFlowReturn @@ -387,6 +407,7 @@ gst_vaapi_overlay_aggregate_frames (GstVideoAggregator * vagg, GstVaapiVideoMeta *outbuf_meta; GstVaapiSurface *outbuf_surface; GstVaapiSurfaceProxy *proxy; + GstVaapiOverlaySurfaceGenerator generator; if (!overlay->blend_pool) { GstVaapiVideoPool *pool = @@ -414,15 +435,13 @@ gst_vaapi_overlay_aggregate_frames (GstVideoAggregator * vagg, outbuf_surface = gst_vaapi_video_meta_get_surface (outbuf_meta); - if (!gst_vaapi_blend_process_begin (overlay->blend, outbuf_surface)) - return GST_FLOW_ERROR; + /* initialize the surface generator */ + generator.parent.next = gst_vaapi_overlay_surface_next; + generator.overlay = overlay; + generator.current = GST_ELEMENT (overlay)->sinkpads; - if (!gst_vaapi_overlay_process_frames (overlay)) { - gst_vaapi_blend_process_end (overlay->blend); - return GST_FLOW_ERROR; - } - - if (!gst_vaapi_blend_process_end (overlay->blend)) + if (!gst_vaapi_blend_process (overlay->blend, outbuf_surface, + (GstVaapiBlendSurfaceGenerator *) & generator)) return GST_FLOW_ERROR; return GST_FLOW_OK; From f97d858237e8ed830ab7515cef8fa103f9ecf107 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 10 Jan 2020 10:14:38 -0800 Subject: [PATCH 3470/3781] libs: blend: remove begin/render/end API This API was risky and is superseded by the surface generator (process) API. Resolves #219 --- gst-libs/gst/vaapi/gstvaapiblend.c | 160 ----------------------------- gst-libs/gst/vaapi/gstvaapiblend.h | 12 --- 2 files changed, 172 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiblend.c b/gst-libs/gst/vaapi/gstvaapiblend.c index 426785eb34..90e92d6b5d 100644 --- a/gst-libs/gst/vaapi/gstvaapiblend.c +++ b/gst-libs/gst/vaapi/gstvaapiblend.c @@ -208,166 +208,6 @@ gst_vaapi_blend_replace (GstVaapiBlend ** old_blend_ptr, gst_object_replace ((GstObject **) old_blend_ptr, GST_OBJECT (new_blend)); } -/** - * gst_vaapi_blend_process_begin: - * @blend: a #GstVaapiBlend - * @surface: the #GstVaapiSurface output target - * - * Locks the VA display and prepares the VA processing pipeline for rendering. - * - * If this function fails, then the VA display is unlocked before returning. - * - * If this function succeeds, it must be paired with a call to - * #gst_vaapi_blend_process_end to ensure the VA processing pipeline is - * finalized and the VA display is unlocked. - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ -gboolean -gst_vaapi_blend_process_begin (GstVaapiBlend * blend, GstVaapiSurface * surface) -{ - VAStatus va_status; - - g_return_val_if_fail (blend != NULL, FALSE); - g_return_val_if_fail (surface != NULL, FALSE); - - GST_VAAPI_DISPLAY_LOCK (blend->display); - - va_status = vaBeginPicture (GST_VAAPI_DISPLAY_VADISPLAY (blend->display), - blend->va_context, GST_VAAPI_SURFACE_ID (surface)); - - if (!vaapi_check_status (va_status, "vaBeginPicture()")) { - GST_VAAPI_DISPLAY_UNLOCK (blend->display); - return FALSE; - } - - return TRUE; -} - -/** - * gst_vaapi_blend_process_render: - * @blend: a #GstVaapiBlend - * @surface: the source #GstVaapiSurface to send to the VA processing pipeline - * for rendering. - * @crop_rect: the @surface crop extents to process for rendering. - * @target_rect: the extents for which the @surface is rendered within the - * output surface. - * @alpha: the alpha value in the range 0.0 to 1.0, inclusive, for blending - * with the output surface background or with previously rendered surfaces. - * - * Renders the @surface in the currently active VA processing pipeline. - * - * This function must only be called after a successful call to - * #gst_vaapi_blend_process_begin and before calling - * #gst_vaapi_process_end. - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ -gboolean -gst_vaapi_blend_process_render (GstVaapiBlend * blend, - const GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, - const GstVaapiRectangle * target_rect, gdouble alpha) -{ - VADisplay va_display; - VAStatus va_status; - VAProcPipelineParameterBuffer *param = NULL; - VABufferID id = VA_INVALID_ID; - VARectangle src_rect = { 0, }, dst_rect = { - 0,}; -#if VA_CHECK_VERSION(1,1,0) - VABlendState blend_state; -#endif - - g_return_val_if_fail (blend != NULL, FALSE); - g_return_val_if_fail (surface != NULL, FALSE); - - va_display = GST_VAAPI_DISPLAY_VADISPLAY (blend->display); - - /* Build surface region (source) */ - src_rect.width = GST_VAAPI_SURFACE_WIDTH (surface); - src_rect.height = GST_VAAPI_SURFACE_HEIGHT (surface); - if (crop_rect) { - if ((crop_rect->x + crop_rect->width > src_rect.width) || - (crop_rect->y + crop_rect->height > src_rect.height)) - return FALSE; - - src_rect.x = crop_rect->x; - src_rect.y = crop_rect->y; - src_rect.width = crop_rect->width; - src_rect.height = crop_rect->height; - } - - /* Build output region (target) */ - dst_rect.width = src_rect.width; - dst_rect.height = src_rect.height; - if (target_rect) { - dst_rect.x = target_rect->x; - dst_rect.y = target_rect->y; - dst_rect.width = target_rect->width; - dst_rect.height = target_rect->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 (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 = alpha; - param->blend_state = &blend_state; -#endif - - vaapi_unmap_buffer (va_display, id, NULL); - - va_status = vaRenderPicture (va_display, blend->va_context, &id, 1); - if (!vaapi_check_status (va_status, "vaRenderPicture()")) { - vaapi_destroy_buffer (va_display, &id); - return FALSE; - } - - vaapi_destroy_buffer (va_display, &id); - - return TRUE; -} - -/** - * gst_vaapi_blend_process_end: - * @blend: a #GstVaapiBlend - * - * Finalizes all pending render operations in the active VA processing pipeline - * and unlocks the VA display. - * - * This function must always be paired with a call to - * #gst_vaapi_blend_process_begin to ensure the VA display gets unlocked. - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ -gboolean -gst_vaapi_blend_process_end (GstVaapiBlend * blend) -{ - VAStatus va_status; - - g_return_val_if_fail (blend != NULL, FALSE); - - va_status = vaEndPicture (GST_VAAPI_DISPLAY_VADISPLAY (blend->display), - blend->va_context); - - GST_VAAPI_DISPLAY_UNLOCK (blend->display); - - if (!vaapi_check_status (va_status, "vaEndPicture()")) - return FALSE; - - return TRUE; -} - static gboolean gst_vaapi_blend_process_unlocked (GstVaapiBlend * blend, GstVaapiSurface * output, GstVaapiBlendSurfaceGenerator * generator) diff --git a/gst-libs/gst/vaapi/gstvaapiblend.h b/gst-libs/gst/vaapi/gstvaapiblend.h index 6119c79468..8fcfbc40b3 100644 --- a/gst-libs/gst/vaapi/gstvaapiblend.h +++ b/gst-libs/gst/vaapi/gstvaapiblend.h @@ -62,18 +62,6 @@ gboolean gst_vaapi_blend_process (GstVaapiBlend * blend, GstVaapiSurface * output, GstVaapiBlendSurfaceGenerator * generator); -gboolean -gst_vaapi_blend_process_begin (GstVaapiBlend * blend, - GstVaapiSurface * surface); - -gboolean -gst_vaapi_blend_process_render (GstVaapiBlend * blend, - const GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, - const GstVaapiRectangle * target_rect, gdouble alpha); - -gboolean -gst_vaapi_blend_process_end (GstVaapiBlend * blend); - GType gst_vaapi_blend_get_type (void) G_GNUC_CONST; From 81f3a7f02bc4e4d6b38214d2816e65c63a2e3435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 14 Jan 2020 18:25:11 +0100 Subject: [PATCH 3471/3781] libs: blend: simplify generator API Instead of using a parent structure that has to be derived by API consumers, this change propse a simplification by using the common pattern of GTK of passing a function pointer and user data which will be passed as its parameter. That user data contains the state and the function will be called to update that state. --- gst-libs/gst/vaapi/gstvaapiblend.c | 14 +++++++------- gst-libs/gst/vaapi/gstvaapiblend.h | 8 ++------ gst/vaapi/gstvaapioverlay.c | 22 ++++++++++------------ 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiblend.c b/gst-libs/gst/vaapi/gstvaapiblend.c index 90e92d6b5d..192865e9fb 100644 --- a/gst-libs/gst/vaapi/gstvaapiblend.c +++ b/gst-libs/gst/vaapi/gstvaapiblend.c @@ -210,7 +210,8 @@ gst_vaapi_blend_replace (GstVaapiBlend ** old_blend_ptr, static gboolean gst_vaapi_blend_process_unlocked (GstVaapiBlend * blend, - GstVaapiSurface * output, GstVaapiBlendSurfaceGenerator * generator) + GstVaapiSurface * output, GstVaapiBlendSurfaceNextFunc next, + gpointer user_data) { VAStatus va_status; VADisplay va_display; @@ -223,8 +224,8 @@ gst_vaapi_blend_process_unlocked (GstVaapiBlend * blend, if (!vaapi_check_status (va_status, "vaBeginPicture()")) return FALSE; - current = generator->next (generator); - for (; current; current = generator->next (generator)) { + current = next (user_data); + for (; current; current = next (user_data)) { VAProcPipelineParameterBuffer *param = NULL; VABufferID id = VA_INVALID_ID; VARectangle src_rect = { 0, }; @@ -290,17 +291,16 @@ gst_vaapi_blend_process_unlocked (GstVaapiBlend * blend, gboolean gst_vaapi_blend_process (GstVaapiBlend * blend, GstVaapiSurface * output, - GstVaapiBlendSurfaceGenerator * generator) + 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 (generator != NULL, FALSE); - g_return_val_if_fail (generator->next != NULL, FALSE); + g_return_val_if_fail (next != NULL, FALSE); GST_VAAPI_DISPLAY_LOCK (blend->display); - result = gst_vaapi_blend_process_unlocked (blend, output, generator); + result = gst_vaapi_blend_process_unlocked (blend, output, next, user_data); GST_VAAPI_DISPLAY_UNLOCK (blend->display); return result; diff --git a/gst-libs/gst/vaapi/gstvaapiblend.h b/gst-libs/gst/vaapi/gstvaapiblend.h index 8fcfbc40b3..8c94128394 100644 --- a/gst-libs/gst/vaapi/gstvaapiblend.h +++ b/gst-libs/gst/vaapi/gstvaapiblend.h @@ -36,7 +36,6 @@ G_BEGIN_DECLS typedef struct _GstVaapiBlend GstVaapiBlend; typedef struct _GstVaapiBlendSurface GstVaapiBlendSurface; -typedef struct _GstVaapiBlendSurfaceGenerator GstVaapiBlendSurfaceGenerator; struct _GstVaapiBlendSurface { @@ -46,10 +45,7 @@ struct _GstVaapiBlendSurface gdouble alpha; }; -struct _GstVaapiBlendSurfaceGenerator -{ - GstVaapiBlendSurface* (*next)(); -}; +typedef GstVaapiBlendSurface* (*GstVaapiBlendSurfaceNextFunc)(gpointer data); GstVaapiBlend * gst_vaapi_blend_new (GstVaapiDisplay * display); @@ -60,7 +56,7 @@ gst_vaapi_blend_replace (GstVaapiBlend ** old_blend_ptr, gboolean gst_vaapi_blend_process (GstVaapiBlend * blend, GstVaapiSurface * output, - GstVaapiBlendSurfaceGenerator * generator); + GstVaapiBlendSurfaceNextFunc next, gpointer user_data); GType gst_vaapi_blend_get_type (void) G_GNUC_CONST; diff --git a/gst/vaapi/gstvaapioverlay.c b/gst/vaapi/gstvaapioverlay.c index 59b1a2892a..37155ee42b 100644 --- a/gst/vaapi/gstvaapioverlay.c +++ b/gst/vaapi/gstvaapioverlay.c @@ -69,7 +69,6 @@ G_DEFINE_TYPE (GstVaapiOverlaySinkPad, gst_vaapi_overlay_sink_pad, typedef struct _GstVaapiOverlaySurfaceGenerator GstVaapiOverlaySurfaceGenerator; struct _GstVaapiOverlaySurfaceGenerator { - GstVaapiBlendSurfaceGenerator parent; GstVaapiOverlay *overlay; GList *current; GstVaapiBlendSurface blend_surface; @@ -340,9 +339,9 @@ gst_vaapi_overlay_decide_allocation (GstAggregator * agg, GstQuery * query) } static GstVaapiBlendSurface * -gst_vaapi_overlay_surface_next (GstVaapiBlendSurfaceGenerator * generator) +gst_vaapi_overlay_surface_next (gpointer data) { - GstVaapiOverlaySurfaceGenerator *ogenerator; + GstVaapiOverlaySurfaceGenerator *generator; GstVideoAggregatorPad *vagg_pad; GstVaapiOverlaySinkPad *pad; GstVideoFrame *inframe; @@ -351,20 +350,20 @@ gst_vaapi_overlay_surface_next (GstVaapiBlendSurfaceGenerator * generator) GstVaapiVideoMeta *inbuf_meta; GstVaapiBlendSurface *blend_surface; - ogenerator = (GstVaapiOverlaySurfaceGenerator *) generator; + generator = (GstVaapiOverlaySurfaceGenerator *) data; /* at the end of the generator? */ - if (!ogenerator->current) + if (!generator->current) return NULL; /* get the current video aggregator sinkpad */ - vagg_pad = GST_VIDEO_AGGREGATOR_PAD (ogenerator->current->data); + vagg_pad = GST_VIDEO_AGGREGATOR_PAD (generator->current->data); /* increment list pointer */ - ogenerator->current = ogenerator->current->next; + generator->current = generator->current->next; /* recycle the blend surface from the overlay surface generator */ - blend_surface = &ogenerator->blend_surface; + blend_surface = &generator->blend_surface; blend_surface->surface = NULL; inframe = gst_video_aggregator_pad_get_prepared_frame (vagg_pad); @@ -372,12 +371,12 @@ gst_vaapi_overlay_surface_next (GstVaapiBlendSurfaceGenerator * generator) pad = GST_VAAPI_OVERLAY_SINK_PAD (vagg_pad); if (gst_vaapi_plugin_base_pad_get_input_buffer (GST_VAAPI_PLUGIN_BASE - (ogenerator->overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK) + (generator->overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK) return blend_surface; /* Current sinkpad may have reached EOS */ if (!inframe || !inbuf) - return generator->next (generator); + return gst_vaapi_overlay_surface_next (generator); inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); @@ -436,12 +435,11 @@ gst_vaapi_overlay_aggregate_frames (GstVideoAggregator * vagg, outbuf_surface = gst_vaapi_video_meta_get_surface (outbuf_meta); /* initialize the surface generator */ - generator.parent.next = gst_vaapi_overlay_surface_next; generator.overlay = overlay; generator.current = GST_ELEMENT (overlay)->sinkpads; if (!gst_vaapi_blend_process (overlay->blend, outbuf_surface, - (GstVaapiBlendSurfaceGenerator *) & generator)) + gst_vaapi_overlay_surface_next, &generator)) return GST_FLOW_ERROR; return GST_FLOW_OK; From d0e14ec3089af20f75e12816368f0807b355af93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 14 Jan 2020 18:46:49 +0100 Subject: [PATCH 3472/3781] vaapioverlay: add minimal documentation --- gst-libs/gst/vaapi/gstvaapiblend.c | 13 +++++++++++++ gst/vaapi/gstvaapioverlay.c | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiblend.c b/gst-libs/gst/vaapi/gstvaapiblend.c index 192865e9fb..57f9fb27fd 100644 --- a/gst-libs/gst/vaapi/gstvaapiblend.c +++ b/gst-libs/gst/vaapi/gstvaapiblend.c @@ -289,6 +289,19 @@ gst_vaapi_blend_process_unlocked (GstVaapiBlend * blend, 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) diff --git a/gst/vaapi/gstvaapioverlay.c b/gst/vaapi/gstvaapioverlay.c index 37155ee42b..5f3f4541ab 100644 --- a/gst/vaapi/gstvaapioverlay.c +++ b/gst/vaapi/gstvaapioverlay.c @@ -20,6 +20,27 @@ * Boston, MA 02110-1301 USA */ +/** + * SECTION:element-vaapioverlay + * @title: vaapioverlay + * @short_description: a VA-API base video compositor + * + * The vaapioverlay element is similar to the base compositor element + * but uses VA-API VPP blend functions to accelerate the + * overlay/compositing. + * + * Currently this element only works with iHD driver. + * + * ## Example launch line + * + * |[ + * gst-launch-1.0 -vf videotestsrc ! vaapipostproc \ + * ! tee name=testsrc ! queue \ + * ! vaapioverlay sink_1::xpos=300 sink_1::alpha=0.75 \ + * name=overlay ! vaapisink testsrc. ! queue ! overlay. + * ]| + */ + #include "gstvaapioverlay.h" #include "gstvaapipluginutil.h" #include "gstvaapivideobufferpool.h" From 889fac3823cc4f6ab5923a71d3e56d25f17df52e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 14 Jan 2020 18:57:31 +0100 Subject: [PATCH 3473/3781] vaapioverlay: unroll the recursive call Recursive functions are elegant but dangerous since they might overflow the stack. It is better to turn them into a list tranversal if possible, as this case. --- gst/vaapi/gstvaapioverlay.c | 60 +++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/gst/vaapi/gstvaapioverlay.c b/gst/vaapi/gstvaapioverlay.c index 5f3f4541ab..7cdb21eb91 100644 --- a/gst/vaapi/gstvaapioverlay.c +++ b/gst/vaapi/gstvaapioverlay.c @@ -374,49 +374,45 @@ gst_vaapi_overlay_surface_next (gpointer data) generator = (GstVaapiOverlaySurfaceGenerator *) data; /* at the end of the generator? */ - if (!generator->current) - return NULL; + while (generator->current) { + /* get the current video aggregator sinkpad */ + vagg_pad = GST_VIDEO_AGGREGATOR_PAD (generator->current->data); - /* get the current video aggregator sinkpad */ - vagg_pad = GST_VIDEO_AGGREGATOR_PAD (generator->current->data); + /* increment list pointer */ + generator->current = generator->current->next; - /* increment list pointer */ - generator->current = generator->current->next; + /* recycle the blend surface from the overlay surface generator */ + blend_surface = &generator->blend_surface; + blend_surface->surface = NULL; - /* recycle the blend surface from the overlay surface generator */ - blend_surface = &generator->blend_surface; - blend_surface->surface = NULL; + inframe = gst_video_aggregator_pad_get_prepared_frame (vagg_pad); + buf = gst_video_aggregator_pad_get_current_buffer (vagg_pad); + pad = GST_VAAPI_OVERLAY_SINK_PAD (vagg_pad); - inframe = gst_video_aggregator_pad_get_prepared_frame (vagg_pad); - buf = gst_video_aggregator_pad_get_current_buffer (vagg_pad); - pad = GST_VAAPI_OVERLAY_SINK_PAD (vagg_pad); + if (gst_vaapi_plugin_base_pad_get_input_buffer (GST_VAAPI_PLUGIN_BASE + (generator->overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK) + return blend_surface; - if (gst_vaapi_plugin_base_pad_get_input_buffer (GST_VAAPI_PLUGIN_BASE - (generator->overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK) - return blend_surface; + /* Current sinkpad may have reached EOS */ + if (!inframe || !inbuf) + continue; - /* Current sinkpad may have reached EOS */ - if (!inframe || !inbuf) - return gst_vaapi_overlay_surface_next (generator); + inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); + if (inbuf_meta) { + blend_surface->surface = gst_vaapi_video_meta_get_surface (inbuf_meta); + blend_surface->crop = gst_vaapi_video_meta_get_render_rect (inbuf_meta); + blend_surface->target.x = pad->xpos; + blend_surface->target.y = pad->ypos; + blend_surface->target.width = GST_VIDEO_FRAME_WIDTH (inframe); + blend_surface->target.height = GST_VIDEO_FRAME_HEIGHT (inframe); + blend_surface->alpha = pad->alpha; + } - inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); - - if (!inbuf_meta) { gst_buffer_unref (inbuf); return blend_surface; } - blend_surface->surface = gst_vaapi_video_meta_get_surface (inbuf_meta); - blend_surface->crop = gst_vaapi_video_meta_get_render_rect (inbuf_meta); - blend_surface->target.x = pad->xpos; - blend_surface->target.y = pad->ypos; - blend_surface->target.width = GST_VIDEO_FRAME_WIDTH (inframe); - blend_surface->target.height = GST_VIDEO_FRAME_HEIGHT (inframe); - blend_surface->alpha = pad->alpha; - - gst_buffer_unref (inbuf); - - return blend_surface; + return NULL; } static GstFlowReturn From 1364070eca040306ea42bfdd59d09c80022d166a Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 14 Jan 2020 11:17:49 -0800 Subject: [PATCH 3474/3781] vaapioverlay: ensure sinkpad has current buffer Use the gst_video_aggregator_pad_has_current_buffer API to check if the current sinkpad has a queued buffer before attempting to obtain a input buffer from the base plugin. If the sinkpad does not have a current buffer, then it is either not producing them yet (e.g. current time < sinkpad start time) or it has reached EOS. Previously, we only handled EOS case. Example: gst-launch-1.0 videotestsrc num-buffers=100 \ ! vaapipostproc ! vaapioverlay name=overlay \ ! vaapisink videotestsrc timestamp-offset=1000000000 \ num-buffers=100 ! video/x-raw,width=160,height=120 \ ! overlay. --- gst/vaapi/gstvaapioverlay.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapioverlay.c b/gst/vaapi/gstvaapioverlay.c index 7cdb21eb91..53efdace2d 100644 --- a/gst/vaapi/gstvaapioverlay.c +++ b/gst/vaapi/gstvaapioverlay.c @@ -385,6 +385,11 @@ gst_vaapi_overlay_surface_next (gpointer data) blend_surface = &generator->blend_surface; blend_surface->surface = NULL; + /* Current sinkpad may not be queueing buffers yet (e.g. timestamp-offset) + * or it may have reached EOS */ + if (!gst_video_aggregator_pad_has_current_buffer (vagg_pad)) + continue; + inframe = gst_video_aggregator_pad_get_prepared_frame (vagg_pad); buf = gst_video_aggregator_pad_get_current_buffer (vagg_pad); pad = GST_VAAPI_OVERLAY_SINK_PAD (vagg_pad); @@ -393,10 +398,6 @@ gst_vaapi_overlay_surface_next (gpointer data) (generator->overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK) return blend_surface; - /* Current sinkpad may have reached EOS */ - if (!inframe || !inbuf) - continue; - inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf); if (inbuf_meta) { blend_surface->surface = gst_vaapi_video_meta_get_surface (inbuf_meta); From 9da5196b5a5c1e8a4c5023f8ba9d8e7dad108cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 28 Dec 2019 19:18:12 +0100 Subject: [PATCH 3475/3781] Remove all FEI related FEI encoders are not actively mantained neither tested, and it is using infrastructure that is changing and FEI is stopping this effort. Also it is required to rethink how FEI can be used in GStreamer. --- gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c | 119 - gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h | 27 - .../gst/vaapi/gstvaapicodedbufferproxy_priv.h | 10 - gst-libs/gst/vaapi/gstvaapicontext.c | 8 - gst-libs/gst/vaapi/gstvaapicontext.h | 2 - gst-libs/gst/vaapi/gstvaapidisplay.c | 3 +- gst-libs/gst/vaapi/gstvaapiencoder.c | 14 - gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c | 4544 ----------------- gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h | 69 - gst-libs/gst/vaapi/gstvaapiencoder_objects.c | 9 - gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 12 - gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 3 - gst-libs/gst/vaapi/gstvaapifei_objects.c | 386 -- gst-libs/gst/vaapi/gstvaapifei_objects.h | 112 - gst-libs/gst/vaapi/gstvaapifei_objects_priv.h | 236 - gst-libs/gst/vaapi/gstvaapifeienc_h264.c | 2452 --------- gst-libs/gst/vaapi/gstvaapifeienc_h264.h | 76 - gst-libs/gst/vaapi/gstvaapifeipak_h264.c | 1915 ------- gst-libs/gst/vaapi/gstvaapifeipak_h264.h | 94 - gst-libs/gst/vaapi/gstvaapifeiutils_h264.c | 222 - gst-libs/gst/vaapi/gstvaapifeiutils_h264.h | 215 - gst-libs/gst/vaapi/gstvaapiprofile.c | 3 - gst-libs/gst/vaapi/gstvaapiprofile.h | 2 - gst-libs/gst/vaapi/gstvaapisurfaceproxy.c | 270 - gst-libs/gst/vaapi/gstvaapisurfaceproxy.h | 44 - .../gst/vaapi/gstvaapisurfaceproxy_priv.h | 9 - gst-libs/gst/vaapi/meson.build | 17 - gst/vaapi/gstvaapi.c | 13 - gst/vaapi/gstvaapiencode.c | 21 - gst/vaapi/gstvaapiencode.h | 17 - gst/vaapi/gstvaapiencode_h264_fei.c | 513 -- gst/vaapi/gstvaapiencode_h264_fei.h | 72 - gst/vaapi/gstvaapifeivideometa.c | 210 - gst/vaapi/gstvaapifeivideometa.h | 80 - gst/vaapi/meson.build | 7 - meson.build | 2 - tests/internal/meson.build | 7 - tests/internal/test-fei-enc-in.c | 680 --- tests/internal/test-fei-enc-out.c | 300 -- 39 files changed, 1 insertion(+), 12794 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c delete mode 100644 gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h delete mode 100644 gst-libs/gst/vaapi/gstvaapifei_objects.c delete mode 100644 gst-libs/gst/vaapi/gstvaapifei_objects.h delete mode 100644 gst-libs/gst/vaapi/gstvaapifei_objects_priv.h delete mode 100644 gst-libs/gst/vaapi/gstvaapifeienc_h264.c delete mode 100644 gst-libs/gst/vaapi/gstvaapifeienc_h264.h delete mode 100644 gst-libs/gst/vaapi/gstvaapifeipak_h264.c delete mode 100644 gst-libs/gst/vaapi/gstvaapifeipak_h264.h delete mode 100644 gst-libs/gst/vaapi/gstvaapifeiutils_h264.c delete mode 100644 gst-libs/gst/vaapi/gstvaapifeiutils_h264.h delete mode 100644 gst/vaapi/gstvaapiencode_h264_fei.c delete mode 100644 gst/vaapi/gstvaapiencode_h264_fei.h delete mode 100644 gst/vaapi/gstvaapifeivideometa.c delete mode 100644 gst/vaapi/gstvaapifeivideometa.h delete mode 100644 tests/internal/test-fei-enc-in.c delete mode 100644 tests/internal/test-fei-enc-out.c diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c index c0adfcbfa0..ececae9c3e 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c @@ -54,19 +54,6 @@ coded_buffer_proxy_finalize (GstVaapiCodedBufferProxy * proxy) /* Notify the user function that the object is now destroyed */ if (proxy->destroy_func) proxy->destroy_func (proxy->destroy_data); - -#if USE_H264_FEI_ENCODER - if (proxy->mbcode) - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mbcode, NULL); - if (proxy->mv) - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mv, NULL); - if (proxy->dist) - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->dist, NULL); -#endif - } static inline const GstVaapiMiniObjectClass * @@ -108,11 +95,6 @@ gst_vaapi_coded_buffer_proxy_new_from_pool (GstVaapiCodedBufferPool * pool) 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 USE_H264_FEI_ENCODER - proxy->mv = NULL; - proxy->mbcode = NULL; - proxy->dist = NULL; -#endif if (!proxy->buffer) goto error; gst_mini_object_ref (GST_MINI_OBJECT_CAST (proxy->buffer)); @@ -272,104 +254,3 @@ gst_vaapi_coded_buffer_proxy_set_user_data (GstVaapiCodedBufferProxy * proxy, coded_buffer_proxy_set_user_data (proxy, user_data, destroy_func); } - -#if USE_H264_FEI_ENCODER - -/** - * gst_vaapi_coded_buffer_proxy_get_fei_mb_code: - * @proxy: a #GstVaapiCodedBufferProxy - * - * Returns the #GstVaapiEncFeiMbCode stored in the @proxy - * - * Return value: the #GstVaapiEncFeiMbcode, or %NULL if none was - * associated with the surface proxy - */ -GstVaapiEncFeiMbCode * -gst_vaapi_coded_buffer_proxy_get_fei_mbcode (GstVaapiCodedBufferProxy * proxy) -{ - g_return_val_if_fail (proxy != NULL, 0); - return proxy->mbcode; -} - -/** - * gst_vaapi_coded_buffer_proxy_get_fei_mv: - * @proxy: a #GstVaapiCodedBufferProxy - * - * Returns the #GstVaapiEncFeiMv stored in the @proxy - * - * Return value: the #GstVaapiEncFeiMv, or %NULL if none was - * associated with the surface proxy - */ -GstVaapiEncFeiMv * -gst_vaapi_coded_buffer_proxy_get_fei_mv (GstVaapiCodedBufferProxy * proxy) -{ - g_return_val_if_fail (proxy != NULL, 0); - return proxy->mv; -} - -/** - * gst_vaapi_coded_buffer_proxy_get_fei_distortion: - * @proxy: a #GstVaapiCodedBufferProxy - * - * Returns the #GstVaapiEncFeiDistortion stored in the @proxy - * - * Return value: the #GstVaapiEncFeiDistortion, or %NULL if none was - * associated with the surface proxy - */ -GstVaapiEncFeiDistortion * -gst_vaapi_coded_buffer_proxy_get_fei_distortion (GstVaapiCodedBufferProxy * - proxy) -{ - g_return_val_if_fail (proxy != NULL, 0); - return proxy->dist; -} - -/** - * gst_vaapi_coded_buffer_proxy_set_fei_mb_code: - * @proxy: #GstVaapiCodedBufferProxy - * @mbcode: the #GstVaapiEncFeiMbCode to be stored in @proxy - * - * Associates the @mbcode with the @proxy - */ -void -gst_vaapi_coded_buffer_proxy_set_fei_mb_code (GstVaapiCodedBufferProxy * proxy, - GstVaapiEncFeiMbCode * mbcode) -{ - g_return_if_fail (proxy != NULL); - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mbcode, (GstVaapiFeiCodecObject *) mbcode); -} - -/** - * gst_vaapi_coded_buffer_proxy_set_fei_mv: - * @proxy: #GstVaapiCodedBufferProxy - * @mv: the #GstVaapiEncFeiMv to be stored in @proxy - * - * Associates the @mv with the @proxy - */ -void -gst_vaapi_coded_buffer_proxy_set_fei_mv (GstVaapiCodedBufferProxy * proxy, - GstVaapiEncFeiMv * mv) -{ - g_return_if_fail (proxy != NULL); - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mv, (GstVaapiFeiCodecObject *) mv); -} - -/** - * gst_vaapi_coded_buffer_proxy_set_fei_distortion: - * @proxy: #GstVaapiSurfaceProxy - * @dist: the #GstVaapiEncFeiDistortion to be stored in @proxy - * - * Associates the @dist with the @proxy - */ -void -gst_vaapi_coded_buffer_proxy_set_fei_distortion (GstVaapiCodedBufferProxy * - proxy, GstVaapiEncFeiDistortion * dist) -{ - g_return_if_fail (proxy != NULL); - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->dist, (GstVaapiFeiCodecObject *) dist); -} - -#endif diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h index 4514db92ff..4968c63075 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h @@ -26,10 +26,6 @@ #include #include -#if USE_H264_FEI_ENCODER -#include -#endif - G_BEGIN_DECLS /** @@ -81,29 +77,6 @@ void gst_vaapi_coded_buffer_proxy_set_user_data (GstVaapiCodedBufferProxy * proxy, gpointer user_data, GDestroyNotify destroy_func); -#if USE_H264_FEI_ENCODER - -GstVaapiEncFeiMbCode * -gst_vaapi_coded_buffer_proxy_get_fei_mbcode (GstVaapiCodedBufferProxy * proxy); - -GstVaapiEncFeiMv * -gst_vaapi_coded_buffer_proxy_get_fei_mv (GstVaapiCodedBufferProxy * proxy); - -GstVaapiEncFeiDistortion * -gst_vaapi_coded_buffer_proxy_get_fei_distortion (GstVaapiCodedBufferProxy * proxy); - -void -gst_vaapi_coded_buffer_proxy_set_fei_mb_code (GstVaapiCodedBufferProxy * proxy, - GstVaapiEncFeiMbCode *mbcode); -void -gst_vaapi_coded_buffer_proxy_set_fei_mv (GstVaapiCodedBufferProxy * proxy, - GstVaapiEncFeiMv *mv); -void -gst_vaapi_coded_buffer_proxy_set_fei_distortion (GstVaapiCodedBufferProxy * proxy, - GstVaapiEncFeiDistortion *dist); - -#endif - G_END_DECLS #endif /* GST_VAAPI_CODED_BUFFER_PROXY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h index bc91a9ccb5..6feb8f9c82 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h @@ -26,10 +26,6 @@ #include "gstvaapicodedbuffer_priv.h" #include "gstvaapiminiobject.h" -#if USE_H264_FEI_ENCODER -#include -#endif - G_BEGIN_DECLS #define GST_VAAPI_CODED_BUFFER_PROXY(proxy) \ @@ -46,12 +42,6 @@ struct _GstVaapiCodedBufferProxy gpointer destroy_data; GDestroyNotify user_data_destroy; gpointer user_data; - -#if USE_H264_FEI_ENCODER - GstVaapiEncFeiMbCode *mbcode; - GstVaapiEncFeiMv *mv; - GstVaapiEncFeiDistortion *dist; -#endif }; /** diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 7c07cce132..69b7b63144 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -317,14 +317,6 @@ config_create (GstVaapiContext * context) attrib = &attribs[++attrib_index]; g_assert (attrib_index < G_N_ELEMENTS (attribs)); } -#endif -#if USE_H264_FEI_ENCODER - if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI) { - attrib->type = (VAConfigAttribType) VAConfigAttribFEIFunctionType; - attrib = &attribs[++attrib_index]; - g_assert (attrib_index < G_N_ELEMENTS (attribs)); - /* FIXME: Query the read-only supported MV predictors */ - } #endif break; } diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 702817146e..26a1dfdc6c 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -62,7 +62,6 @@ typedef enum { * @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. - * @fei_function: The functional mode for FEI Entrypoint (VA_FEI_FUNCTION_*). * * Extra configuration for encoding. */ @@ -72,7 +71,6 @@ struct _GstVaapiConfigInfoEncoder guint packed_headers; gboolean roi_capability; guint roi_num_supported; - guint fei_function; }; /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index cee1fce5f0..b1a6148495 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -538,8 +538,7 @@ ensure_profiles (GstVaapiDisplay * display) g_ptr_array_add (priv->decoders, cfg); if ((cfg->entrypoints & ENTRY_POINT_FLAG (SLICE_ENCODE)) || (cfg->entrypoints & ENTRY_POINT_FLAG (PICTURE_ENCODE)) - || (cfg->entrypoints & ENTRY_POINT_FLAG (SLICE_ENCODE_LP)) - || (cfg->entrypoints & ENTRY_POINT_FLAG (SLICE_ENCODE_FEI))) + || (cfg->entrypoints & ENTRY_POINT_FLAG (SLICE_ENCODE_LP))) g_ptr_array_add (priv->encoders, cfg); } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index e34db34a48..1714707d25 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -730,7 +730,6 @@ set_context_info (GstVaapiEncoder * encoder) GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); - guint fei_function = config->fei_function; g_assert (cip->profile != GST_VAAPI_PROFILE_UNKNOWN); g_assert (cip->entrypoint != GST_VAAPI_ENTRYPOINT_INVALID); @@ -748,7 +747,6 @@ set_context_info (GstVaapiEncoder * encoder) config->packed_headers = get_packed_headers (encoder); config->roi_capability = get_roi_capability (encoder, &config->roi_num_supported); - config->fei_function = fei_function; return TRUE; @@ -827,13 +825,6 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) if (!gst_vaapi_encoder_ensure_context (encoder)) goto error_reset_context; - /* Currently only FEI entrypoint needed this. - * FEI ENC+PAK requires two contexts where the first one is for ENC - * and the second one is for PAK */ - if (klass->ensure_secondary_context - && !klass->ensure_secondary_context (encoder)) - goto error_reset_secondary_context; - #if VA_CHECK_VERSION(0,36,0) if (get_config_attribute (encoder, VAConfigAttribEncQualityRange, &quality_level_max) && quality_level_max > 0) { @@ -888,11 +879,6 @@ error_reset_context: GST_ERROR ("failed to update VA context"); return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; } -error_reset_secondary_context: - { - GST_ERROR ("failed to create/update secondary VA context"); - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; - } } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c deleted file mode 100644 index 838c782ed5..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c +++ /dev/null @@ -1,4544 +0,0 @@ -/* - * gstvaapiencoder_h264_fei.c - H.264 FEI encoder - * - * Copyright (C) 2016-2017 Intel Corporation - * Author: Yi A Wang - * Author: Sreerenj Balachandran - * - * 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 - */ - -/* GValueArray has deprecated without providing an alternative in glib >= 2.32 - * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 - */ -#define GLIB_DISABLE_DEPRECATION_WARNINGS - -#include "sysdeps.h" -#include -#include -#include -#include -#include "gstvaapicompat.h" -#include "gstvaapiencoder_priv.h" -#include "gstvaapiutils_h264_priv.h" -#include "gstvaapicodedbufferproxy_priv.h" -#include "gstvaapisurfaceproxy_priv.h" -#include "gstvaapisurface.h" -#include "gstvaapifeiutils_h264.h" -#include "gstvaapiencoder_h264_fei.h" -#include "gstvaapifeienc_h264.h" -#include "gstvaapifeipak_h264.h" -#include "gstvaapiutils.h" -#include "gstvaapiutils_core.h" -#include "gstvaapifei_objects_priv.h" -#define DEBUG 1 -#include "gstvaapidebug.h" - -static gboolean -gst_vaapi_encoder_h264_fei_ensure_secondary_context (GstVaapiEncoder * - base_encoder); - -/* Define the maximum number of views supported */ -#define MAX_NUM_VIEWS 10 - -/* Define the maximum value for view-id */ -#define MAX_VIEW_ID 1023 - -/* Default CPB length (in milliseconds) */ -#define DEFAULT_CPB_LENGTH 1500 - -/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */ -#define SX_CPB_SIZE 4 - -/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ -#define SX_BITRATE 6 - -/* 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) | \ - GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) - -/* Supported set of tuning options, within this implementation */ -#define SUPPORTED_TUNE_OPTIONS \ - (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \ - GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION) | \ - GST_VAAPI_ENCODER_TUNE_MASK (LOW_POWER)) - -/* Supported set of VA packed headers, within this implementation */ -#define SUPPORTED_PACKED_HEADERS \ - (VA_ENC_PACKED_HEADER_SEQUENCE | \ - VA_ENC_PACKED_HEADER_PICTURE | \ - VA_ENC_PACKED_HEADER_SLICE | \ - VA_ENC_PACKED_HEADER_RAW_DATA | \ - VA_ENC_PACKED_HEADER_MISC) - -#define GST_H264_NAL_REF_IDC_NONE 0 -#define GST_H264_NAL_REF_IDC_LOW 1 -#define GST_H264_NAL_REF_IDC_MEDIUM 2 -#define GST_H264_NAL_REF_IDC_HIGH 3 - -/* only for internal usage, values won't be equal to actual payload type */ -typedef enum -{ - GST_VAAPI_H264_SEI_UNKNOWN = 0, - GST_VAAPI_H264_SEI_BUF_PERIOD = (1 << 0), - GST_VAAPI_H264_SEI_PIC_TIMING = (1 << 1) -} GstVaapiH264SeiPayloadType; - -typedef struct -{ - GstVaapiSurfaceProxy *pic; - guint poc; - guint frame_num; -} GstVaapiEncoderH264FeiRef; - -typedef enum -{ - GST_VAAPI_ENC_H264_REORD_NONE = 0, - GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1, - GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2 -} GstVaapiEncH264ReorderState; - -typedef struct _GstVaapiH264ViewRefPool -{ - GQueue ref_list; - guint max_ref_frames; - guint max_reflist0_count; - guint max_reflist1_count; -} GstVaapiH264ViewRefPool; - -typedef struct _GstVaapiH264ViewReorderPool -{ - GQueue reorder_frame_list; - guint reorder_state; - guint frame_index; - guint frame_count; /* monotonically increasing with in every idr period */ - guint cur_frame_num; - guint cur_present_index; -} GstVaapiH264ViewReorderPool; - -static inline gboolean -_poc_greater_than (guint poc1, guint poc2, guint max_poc) -{ - return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2); -} - -/* Get slice_type value for H.264 specification */ -static guint8 -h264_get_slice_type (GstVaapiPictureType type) -{ - switch (type) { - case GST_VAAPI_PICTURE_TYPE_I: - return GST_H264_I_SLICE; - case GST_VAAPI_PICTURE_TYPE_P: - return GST_H264_P_SLICE; - case GST_VAAPI_PICTURE_TYPE_B: - return GST_H264_B_SLICE; - default: - break; - } - return -1; -} - -/* Get log2_max_frame_num value for H.264 specification */ -static guint -h264_get_log2_max_frame_num (guint num) -{ - guint ret = 0; - - while (num) { - ++ret; - num >>= 1; - } - if (ret <= 4) - ret = 4; - else if (ret > 10) - ret = 10; - /* must be greater than 4 */ - return ret; -} - -/* Determines the cpbBrNalFactor based on the supplied profile */ -static guint -h264_get_cpb_nal_factor (GstVaapiProfile profile) -{ - guint f; - - /* Table A-2 */ - switch (profile) { - case GST_VAAPI_PROFILE_H264_HIGH: - f = 1500; - break; - case GST_VAAPI_PROFILE_H264_HIGH10: - f = 3600; - break; - case GST_VAAPI_PROFILE_H264_HIGH_422: - case GST_VAAPI_PROFILE_H264_HIGH_444: - f = 4800; - break; - case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH: - case GST_VAAPI_PROFILE_H264_STEREO_HIGH: - f = 1500; /* H.10.2.1 (r) */ - break; - default: - f = 1200; - break; - } - return f; -} - -/* ------------------------------------------------------------------------- */ -/* --- H.264 Bitstream Writer --- */ -/* ------------------------------------------------------------------------- */ - -#define WRITE_UINT32(bs, val, nbits) do { \ - if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \ - GST_WARNING ("failed to write uint32, nbits: %d", nbits); \ - goto bs_error; \ - } \ - } while (0) - -#define WRITE_UE(bs, val) do { \ - if (!bs_write_ue (bs, val)) { \ - GST_WARNING ("failed to write ue(v)"); \ - goto bs_error; \ - } \ - } while (0) - -#define WRITE_SE(bs, val) do { \ - if (!bs_write_se (bs, val)) { \ - GST_WARNING ("failed to write se(v)"); \ - goto bs_error; \ - } \ - } while (0) - -/* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */ -static gboolean -bs_write_ue (GstBitWriter * bs, guint32 value) -{ - guint32 size_in_bits = 0; - guint32 tmp_value = ++value; - - while (tmp_value) { - ++size_in_bits; - tmp_value >>= 1; - } - if (size_in_bits > 1 - && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1)) - return FALSE; - if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits)) - return FALSE; - return TRUE; -} - -/* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */ -static gboolean -bs_write_se (GstBitWriter * bs, gint32 value) -{ - guint32 new_val; - - if (value <= 0) - new_val = -(value << 1); - else - new_val = (value << 1) - 1; - - if (!bs_write_ue (bs, new_val)) - return FALSE; - return TRUE; -} - -/* Write the NAL unit header */ -static gboolean -bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc, - guint32 nal_unit_type) -{ - WRITE_UINT32 (bs, 0, 1); - WRITE_UINT32 (bs, nal_ref_idc, 2); - WRITE_UINT32 (bs, nal_unit_type, 5); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write NAL unit header"); - return FALSE; - } -} - -/* Write the MVC NAL unit header extension */ -static gboolean -bs_write_nal_header_mvc_extension (GstBitWriter * bs, - GstVaapiEncPicture * picture, guint32 view_id) -{ - guint32 svc_extension_flag = 0; - guint32 non_idr_flag = 1; - guint32 priority_id = 0; - guint32 temporal_id = 0; - guint32 anchor_pic_flag = 0; - guint32 inter_view_flag = 0; - - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) - non_idr_flag = 0; - - if (picture->type == GST_VAAPI_PICTURE_TYPE_I) - anchor_pic_flag = 1; - /* svc_extension_flag == 0 for mvc stream */ - WRITE_UINT32 (bs, svc_extension_flag, 1); - - WRITE_UINT32 (bs, non_idr_flag, 1); - WRITE_UINT32 (bs, priority_id, 6); - WRITE_UINT32 (bs, view_id, 10); - WRITE_UINT32 (bs, temporal_id, 3); - WRITE_UINT32 (bs, anchor_pic_flag, 1); - WRITE_UINT32 (bs, inter_view_flag, 1); - WRITE_UINT32 (bs, 1, 1); - - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write NAL unit header"); - return FALSE; - } -} - -/* Write the NAL unit trailing bits */ -static gboolean -bs_write_trailing_bits (GstBitWriter * bs) -{ - if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1)) - goto bs_error; - gst_bit_writer_align_bytes_unchecked (bs, 0); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write NAL unit trailing bits"); - return FALSE; - } -} - -/* Write an SPS NAL unit */ -static gboolean -bs_write_sps_data (GstBitWriter * bs, - const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, - const VAEncMiscParameterHRD * hrd_params) -{ - guint8 profile_idc; - guint32 constraint_set0_flag, constraint_set1_flag; - guint32 constraint_set2_flag, constraint_set3_flag; - guint32 gaps_in_frame_num_value_allowed_flag = 0; // ?? - gboolean nal_hrd_parameters_present_flag; - - guint32 b_qpprime_y_zero_transform_bypass = 0; - guint32 residual_color_transform_flag = 0; - guint32 pic_height_in_map_units = - (seq_param->seq_fields.bits.frame_mbs_only_flag ? - seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2); - guint32 mb_adaptive_frame_field = - !seq_param->seq_fields.bits.frame_mbs_only_flag; - guint32 i = 0; - - profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); - constraint_set0_flag = /* A.2.1 (baseline profile constraints) */ - profile == GST_VAAPI_PROFILE_H264_BASELINE || - profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; - constraint_set1_flag = /* A.2.2 (main profile constraints) */ - profile == GST_VAAPI_PROFILE_H264_MAIN || - profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; - constraint_set2_flag = 0; - constraint_set3_flag = 0; - - /* profile_idc */ - WRITE_UINT32 (bs, profile_idc, 8); - /* constraint_set0_flag */ - WRITE_UINT32 (bs, constraint_set0_flag, 1); - /* constraint_set1_flag */ - WRITE_UINT32 (bs, constraint_set1_flag, 1); - /* constraint_set2_flag */ - WRITE_UINT32 (bs, constraint_set2_flag, 1); - /* constraint_set3_flag */ - WRITE_UINT32 (bs, constraint_set3_flag, 1); - /* reserved_zero_4bits */ - WRITE_UINT32 (bs, 0, 4); - /* level_idc */ - WRITE_UINT32 (bs, seq_param->level_idc, 8); - /* seq_parameter_set_id */ - WRITE_UE (bs, seq_param->seq_parameter_set_id); - - if (profile == GST_VAAPI_PROFILE_H264_HIGH || - profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH || - profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { - /* for high profile */ - /* chroma_format_idc = 1, 4:2:0 */ - WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc); - if (3 == seq_param->seq_fields.bits.chroma_format_idc) { - WRITE_UINT32 (bs, residual_color_transform_flag, 1); - } - /* bit_depth_luma_minus8 */ - WRITE_UE (bs, seq_param->bit_depth_luma_minus8); - /* bit_depth_chroma_minus8 */ - WRITE_UE (bs, seq_param->bit_depth_chroma_minus8); - /* b_qpprime_y_zero_transform_bypass */ - WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1); - - /* seq_scaling_matrix_present_flag */ - g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0); - WRITE_UINT32 (bs, - seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1); - -#if 0 - if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) { - for (i = 0; - i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); - i++) { - gst_bit_writer_put_bits_uint8 (bs, - seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1); - if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) { - g_assert (0); - /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */ - } - } - } -#endif - } - - /* log2_max_frame_num_minus4 */ - WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4); - /* pic_order_cnt_type */ - WRITE_UE (bs, seq_param->seq_fields.bits.pic_order_cnt_type); - - if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) { - /* log2_max_pic_order_cnt_lsb_minus4 */ - WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4); - } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { - g_assert (0 && "only POC type 0 is supported"); - WRITE_UINT32 (bs, - seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1); - WRITE_SE (bs, seq_param->offset_for_non_ref_pic); - WRITE_SE (bs, seq_param->offset_for_top_to_bottom_field); - WRITE_UE (bs, seq_param->num_ref_frames_in_pic_order_cnt_cycle); - for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) { - WRITE_SE (bs, seq_param->offset_for_ref_frame[i]); - } - } - - /* num_ref_frames */ - WRITE_UE (bs, seq_param->max_num_ref_frames); - /* gaps_in_frame_num_value_allowed_flag */ - WRITE_UINT32 (bs, gaps_in_frame_num_value_allowed_flag, 1); - - /* pic_width_in_mbs_minus1 */ - WRITE_UE (bs, seq_param->picture_width_in_mbs - 1); - /* pic_height_in_map_units_minus1 */ - WRITE_UE (bs, pic_height_in_map_units - 1); - /* frame_mbs_only_flag */ - WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1); - - if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs - g_assert (0 && "only progressive frames encoding is supported"); - WRITE_UINT32 (bs, mb_adaptive_frame_field, 1); - } - - /* direct_8x8_inference_flag */ - WRITE_UINT32 (bs, 0, 1); - /* frame_cropping_flag */ - WRITE_UINT32 (bs, seq_param->frame_cropping_flag, 1); - - if (seq_param->frame_cropping_flag) { - /* frame_crop_left_offset */ - WRITE_UE (bs, seq_param->frame_crop_left_offset); - /* frame_crop_right_offset */ - WRITE_UE (bs, seq_param->frame_crop_right_offset); - /* frame_crop_top_offset */ - WRITE_UE (bs, seq_param->frame_crop_top_offset); - /* frame_crop_bottom_offset */ - WRITE_UE (bs, seq_param->frame_crop_bottom_offset); - } - - /* vui_parameters_present_flag */ - WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1); - if (seq_param->vui_parameters_present_flag) { - /* aspect_ratio_info_present_flag */ - WRITE_UINT32 (bs, - seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1); - if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { - WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8); - if (seq_param->aspect_ratio_idc == 0xFF) { - WRITE_UINT32 (bs, seq_param->sar_width, 16); - WRITE_UINT32 (bs, seq_param->sar_height, 16); - } - } - - /* overscan_info_present_flag */ - WRITE_UINT32 (bs, 0, 1); - /* video_signal_type_present_flag */ - WRITE_UINT32 (bs, 0, 1); - /* chroma_loc_info_present_flag */ - WRITE_UINT32 (bs, 0, 1); - - /* timing_info_present_flag */ - WRITE_UINT32 (bs, seq_param->vui_fields.bits.timing_info_present_flag, 1); - if (seq_param->vui_fields.bits.timing_info_present_flag) { - WRITE_UINT32 (bs, seq_param->num_units_in_tick, 32); - WRITE_UINT32 (bs, seq_param->time_scale, 32); - WRITE_UINT32 (bs, 1, 1); /* fixed_frame_rate_flag */ - } - - /* nal_hrd_parameters_present_flag */ - nal_hrd_parameters_present_flag = seq_param->bits_per_second > 0; - WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1); - if (nal_hrd_parameters_present_flag) { - /* hrd_parameters */ - /* cpb_cnt_minus1 */ - WRITE_UE (bs, 0); - WRITE_UINT32 (bs, SX_BITRATE - 6, 4); /* bit_rate_scale */ - WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4); /* cpb_size_scale */ - - for (i = 0; i < 1; ++i) { - /* bit_rate_value_minus1[0] */ - WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1); - /* cpb_size_value_minus1[0] */ - WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1); - /* cbr_flag[0] */ - WRITE_UINT32 (bs, 1, 1); - } - /* initial_cpb_removal_delay_length_minus1 */ - WRITE_UINT32 (bs, 23, 5); - /* cpb_removal_delay_length_minus1 */ - WRITE_UINT32 (bs, 23, 5); - /* dpb_output_delay_length_minus1 */ - WRITE_UINT32 (bs, 23, 5); - /* time_offset_length */ - WRITE_UINT32 (bs, 23, 5); - } - - /* vcl_hrd_parameters_present_flag */ - WRITE_UINT32 (bs, 0, 1); - - if (nal_hrd_parameters_present_flag - || 0 /*vcl_hrd_parameters_present_flag */ ) { - /* low_delay_hrd_flag */ - WRITE_UINT32 (bs, 0, 1); - } - /* pic_struct_present_flag */ - WRITE_UINT32 (bs, 1, 1); - /* bs_restriction_flag */ - WRITE_UINT32 (bs, 0, 1); - } - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write SPS NAL unit"); - return FALSE; - } -} - -static gboolean -bs_write_sps (GstBitWriter * bs, - const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, - const VAEncMiscParameterHRD * hrd_params) -{ - if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) - return FALSE; - - /* rbsp_trailing_bits */ - bs_write_trailing_bits (bs); - - return FALSE; -} - -static gboolean -bs_write_subset_sps (GstBitWriter * bs, - const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, - guint num_views, guint16 * view_ids, - const VAEncMiscParameterHRD * hrd_params) -{ - guint32 i, j, k; - - if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) - return FALSE; - - if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH || - profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH) { - guint32 num_views_minus1, num_level_values_signalled_minus1; - - num_views_minus1 = num_views - 1; - g_assert (num_views_minus1 < 1024); - - /* bit equal to one */ - WRITE_UINT32 (bs, 1, 1); - - WRITE_UE (bs, num_views_minus1); - - for (i = 0; i <= num_views_minus1; i++) - WRITE_UE (bs, view_ids[i]); - - for (i = 1; i <= num_views_minus1; i++) { - guint32 num_anchor_refs_l0 = 0; - guint32 num_anchor_refs_l1 = 0; - - WRITE_UE (bs, num_anchor_refs_l0); - for (j = 0; j < num_anchor_refs_l0; j++) - WRITE_UE (bs, 0); - - WRITE_UE (bs, num_anchor_refs_l1); - for (j = 0; j < num_anchor_refs_l1; j++) - WRITE_UE (bs, 0); - } - - for (i = 1; i <= num_views_minus1; i++) { - guint32 num_non_anchor_refs_l0 = 0; - guint32 num_non_anchor_refs_l1 = 0; - - WRITE_UE (bs, num_non_anchor_refs_l0); - for (j = 0; j < num_non_anchor_refs_l0; j++) - WRITE_UE (bs, 0); - - WRITE_UE (bs, num_non_anchor_refs_l1); - for (j = 0; j < num_non_anchor_refs_l1; j++) - WRITE_UE (bs, 0); - } - - /* num level values signalled minus1 */ - num_level_values_signalled_minus1 = 0; - g_assert (num_level_values_signalled_minus1 < 64); - WRITE_UE (bs, num_level_values_signalled_minus1); - - for (i = 0; i <= num_level_values_signalled_minus1; i++) { - guint16 num_applicable_ops_minus1 = 0; - g_assert (num_applicable_ops_minus1 < 1024); - - WRITE_UINT32 (bs, seq_param->level_idc, 8); - WRITE_UE (bs, num_applicable_ops_minus1); - - for (j = 0; j <= num_applicable_ops_minus1; j++) { - guint8 temporal_id = 0; - guint16 num_target_views_minus1 = 1; - - WRITE_UINT32 (bs, temporal_id, 3); - WRITE_UE (bs, num_target_views_minus1); - - for (k = 0; k <= num_target_views_minus1; k++) - WRITE_UE (bs, k); - - WRITE_UE (bs, num_views_minus1); - } - } - - /* mvc_vui_parameters_present_flag */ - WRITE_UINT32 (bs, 0, 1); - } - - /* additional_extension2_flag */ - WRITE_UINT32 (bs, 0, 1); - - /* rbsp_trailing_bits */ - bs_write_trailing_bits (bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write subset SPS NAL unit"); - return FALSE; - } - return FALSE; -} - -/* Write a PPS NAL unit */ -static gboolean -bs_write_pps (GstBitWriter * bs, - const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile) -{ - guint32 num_slice_groups_minus1 = 0; - guint32 pic_init_qs_minus26 = 0; - guint32 redundant_pic_cnt_present_flag = 0; - - /* pic_parameter_set_id */ - WRITE_UE (bs, pic_param->pic_parameter_set_id); - /* seq_parameter_set_id */ - WRITE_UE (bs, pic_param->seq_parameter_set_id); - /* entropy_coding_mode_flag */ - WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1); - /* pic_order_present_flag */ - WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_order_present_flag, 1); - /* slice_groups-1 */ - WRITE_UE (bs, num_slice_groups_minus1); - - if (num_slice_groups_minus1 > 0) { - /*FIXME*/ g_assert (0 && "unsupported arbitrary slice ordering (ASO)"); - } - WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1); - WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1); - WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1); - WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2); - /* pic_init_qp_minus26 */ - WRITE_SE (bs, pic_param->pic_init_qp - 26); - /* pic_init_qs_minus26 */ - WRITE_SE (bs, pic_init_qs_minus26); - /* chroma_qp_index_offset */ - WRITE_SE (bs, pic_param->chroma_qp_index_offset); - - WRITE_UINT32 (bs, - pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1); - WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1); - WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1); - - /* more_rbsp_data */ - if (profile == GST_VAAPI_PROFILE_H264_HIGH - || profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH - || profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { - WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1); - WRITE_UINT32 (bs, - pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1); - if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) { - g_assert (0 && "unsupported scaling lists"); - /* FIXME */ - /* - for (i = 0; i < - (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag)); - i++) { - gst_bit_writer_put_bits_uint8(bs, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1); - } - */ - } - WRITE_SE (bs, pic_param->second_chroma_qp_index_offset); - } - - /* rbsp_trailing_bits */ - bs_write_trailing_bits (bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write PPS NAL unit"); - return FALSE; - } -} - -/* ------------------------------------------------------------------------- */ -/* --- H.264 Encoder --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_ENCODER_H264_FEI_CAST(encoder) \ - ((GstVaapiEncoderH264Fei *)(encoder)) - -struct _GstVaapiEncoderH264Fei -{ - GstVaapiEncoder parent_instance; - GstVaapiFeiEncH264 *feienc; - GstVaapiFEIPakH264 *feipak; - - GstVaapiProfile profile; - GstVaapiLevelH264 level; - GstVaapiEntrypoint entrypoint; - VAConfigID va_config; - guint8 profile_idc; - VABufferID coded_buf; - guint8 max_profile_idc; - guint8 hw_max_profile_idc; - guint8 level_idc; - guint32 idr_period; - guint32 init_qp; - guint32 min_qp; - guint32 max_qp; - guint32 num_slices; - guint32 num_bframes; - guint32 mb_width; - guint32 mb_height; - gboolean use_cabac; - gboolean use_dct8x8; - GstClockTime cts_offset; - gboolean config_changed; - - /* frame, poc */ - guint32 max_frame_num; - guint32 log2_max_frame_num; - guint32 max_pic_order_cnt; - guint32 log2_max_pic_order_cnt; - guint32 idr_num; - guint8 pic_order_cnt_type; - guint8 delta_pic_order_always_zero_flag; - - GstBuffer *sps_data; - GstBuffer *subset_sps_data; - GstBuffer *pps_data; - - guint bitrate_bits; // bitrate (bits) - guint cpb_length; // length of CPB buffer (ms) - guint cpb_length_bits; // length of CPB buffer (bits) - guint num_ref_frames; - - /* MVC */ - gboolean is_mvc; - guint32 view_idx; /* View Order Index (VOIdx) */ - guint32 num_views; - guint16 view_ids[MAX_NUM_VIEWS]; - GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS]; - GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS]; - gpointer ref_pool_ptr; - /*Fei frame level control */ - gboolean is_fei_disabled; - gboolean is_stats_out_enabled; - guint search_window; - guint len_sp; - guint search_path; - guint ref_width; - guint ref_height; - guint submb_part_mask; - guint subpel_mode; - guint intra_part_mask; - guint intra_sad; - guint inter_sad; - guint num_mv_predictors_l0; - guint num_mv_predictors_l1; - guint adaptive_search; - guint multi_predL0; - guint multi_predL1; - guint fei_mode; - -}; - -/* Write a SEI buffering period payload */ -static gboolean -bs_write_sei_buf_period (GstBitWriter * bs, - GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture) -{ - guint initial_cpb_removal_delay = 0; - guint initial_cpb_removal_delay_offset = 0; - guint8 initial_cpb_removal_delay_length = 24; - - /* sequence_parameter_set_id */ - WRITE_UE (bs, encoder->view_idx); - /* NalHrdBpPresentFlag == TRUE */ - /* cpb_cnt_minus1 == 0 */ - - /* decoding should start when the CPB fullness reaches half of cpb size - * initial_cpb_remvoal_delay = (((cpb_length / 2) * 90000) / 1000) */ - initial_cpb_removal_delay = encoder->cpb_length * 45; - - /* initial_cpb_remvoal_dealy */ - WRITE_UINT32 (bs, initial_cpb_removal_delay, - initial_cpb_removal_delay_length); - - /* initial_cpb_removal_delay_offset */ - WRITE_UINT32 (bs, initial_cpb_removal_delay_offset, - initial_cpb_removal_delay_length); - - /* VclHrdBpPresentFlag == FALSE */ - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write Buffering Period SEI message"); - return FALSE; - } -} - -/* Write a SEI picture timing payload */ -static gboolean -bs_write_sei_pic_timing (GstBitWriter * bs, - GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture) -{ - GstVaapiH264ViewReorderPool *reorder_pool = NULL; - guint cpb_removal_delay; - guint dpb_output_delay; - guint8 cpb_removal_delay_length = 24; - guint8 dpb_output_delay_length = 24; - guint pic_struct = 0; - guint clock_timestamp_flag = 0; - - reorder_pool = &encoder->reorder_pools[encoder->view_idx]; - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) - reorder_pool->frame_count = 0; - else - reorder_pool->frame_count++; - - /* clock-tick = no_units_in_tick/time_scale (C-1) - * time_scale = FPS_N * 2 (E.2.1) - * num_units_in_tick = FPS_D (E.2.1) - * frame_duration = clock-tick * 2 - * so removal time for one frame is 2 clock-ticks. - * but adding a tolerance of one frame duration, - * which is 2 more clock-ticks */ - cpb_removal_delay = (reorder_pool->frame_count * 2 + 2); - - if (picture->type == GST_VAAPI_PICTURE_TYPE_B) - dpb_output_delay = 0; - else - dpb_output_delay = picture->poc - reorder_pool->frame_count * 2; - - /* CpbDpbDelaysPresentFlag == 1 */ - WRITE_UINT32 (bs, cpb_removal_delay, cpb_removal_delay_length); - WRITE_UINT32 (bs, dpb_output_delay, dpb_output_delay_length); - - /* pic_struct_present_flag == 1 */ - /* pic_struct */ - WRITE_UINT32 (bs, pic_struct, 4); - /* clock_timestamp_flag */ - WRITE_UINT32 (bs, clock_timestamp_flag, 1); - - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write Picture Timing SEI message"); - return FALSE; - } -} - -/* Write a Slice NAL unit */ -static gboolean -bs_write_slice (GstBitWriter * bs, - const VAEncSliceParameterBufferH264 * slice_param, - GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture) -{ - const VAEncPictureParameterBufferH264 *const pic_param = picture->param; - guint32 field_pic_flag = 0; - guint32 ref_pic_list_modification_flag_l0 = 0; - guint32 ref_pic_list_modification_flag_l1 = 0; - guint32 no_output_of_prior_pics_flag = 0; - guint32 long_term_reference_flag = 0; - guint32 adaptive_ref_pic_marking_mode_flag = 0; - - /* first_mb_in_slice */ - WRITE_UE (bs, slice_param->macroblock_address); - /* slice_type */ - WRITE_UE (bs, slice_param->slice_type); - /* pic_parameter_set_id */ - WRITE_UE (bs, slice_param->pic_parameter_set_id); - /* frame_num */ - WRITE_UINT32 (bs, picture->frame_num, encoder->log2_max_frame_num); - - /* XXX: only frames (i.e. non-interlaced) are supported for now */ - /* frame_mbs_only_flag == 0 */ - - /* idr_pic_id */ - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) - WRITE_UE (bs, slice_param->idr_pic_id); - - /* XXX: only POC type 0 is supported */ - if (!encoder->pic_order_cnt_type) { - WRITE_UINT32 (bs, slice_param->pic_order_cnt_lsb, - encoder->log2_max_pic_order_cnt); - /* bottom_field_pic_order_in_frame_present_flag is FALSE */ - if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag) - WRITE_SE (bs, slice_param->delta_pic_order_cnt_bottom); - } else if (encoder->pic_order_cnt_type == 1 && - !encoder->delta_pic_order_always_zero_flag) { - WRITE_SE (bs, slice_param->delta_pic_order_cnt[0]); - if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag) - WRITE_SE (bs, slice_param->delta_pic_order_cnt[1]); - } - /* redundant_pic_cnt_present_flag is FALSE, no redundant coded pictures */ - - /* only works for B-frames */ - if (slice_param->slice_type == GST_H264_B_SLICE) - WRITE_UINT32 (bs, slice_param->direct_spatial_mv_pred_flag, 1); - - /* not supporting SP slices */ - if (slice_param->slice_type == 0 || slice_param->slice_type == 1) { - WRITE_UINT32 (bs, slice_param->num_ref_idx_active_override_flag, 1); - if (slice_param->num_ref_idx_active_override_flag) { - WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1); - if (slice_param->slice_type == 1) - WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1); - } - } - /* XXX: not supporting custom reference picture list modifications */ - if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4)) - WRITE_UINT32 (bs, ref_pic_list_modification_flag_l0, 1); - if (slice_param->slice_type == 1) - WRITE_UINT32 (bs, ref_pic_list_modification_flag_l1, 1); - - /* we have: weighted_pred_flag == FALSE and */ - /* : weighted_bipred_idc == FALSE */ - if ((pic_param->pic_fields.bits.weighted_pred_flag && - (slice_param->slice_type == 0)) || - ((pic_param->pic_fields.bits.weighted_bipred_idc == 1) && - (slice_param->slice_type == 1))) { - /* XXXX: add pred_weight_table() */ - } - - /* dec_ref_pic_marking() */ - if (slice_param->slice_type == 0 || slice_param->slice_type == 2) { - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { - /* no_output_of_prior_pics_flag = 0 */ - WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1); - /* long_term_reference_flag = 0 */ - WRITE_UINT32 (bs, long_term_reference_flag, 1); - } else { - /* only sliding_window reference picture marking mode is supported */ - /* adpative_ref_pic_marking_mode_flag = 0 */ - WRITE_UINT32 (bs, adaptive_ref_pic_marking_mode_flag, 1); - } - } - - /* cabac_init_idc */ - if (pic_param->pic_fields.bits.entropy_coding_mode_flag && - slice_param->slice_type != 2) - WRITE_UE (bs, slice_param->cabac_init_idc); - /*slice_qp_delta */ - WRITE_SE (bs, slice_param->slice_qp_delta); - - /* XXX: only supporting I, P and B type slices */ - /* no sp_for_switch_flag and no slice_qs_delta */ - - if (pic_param->pic_fields.bits.deblocking_filter_control_present_flag) { - /* disable_deblocking_filter_idc */ - WRITE_UE (bs, slice_param->disable_deblocking_filter_idc); - if (slice_param->disable_deblocking_filter_idc != 1) { - WRITE_SE (bs, slice_param->slice_alpha_c0_offset_div2); - WRITE_SE (bs, slice_param->slice_beta_offset_div2); - } - } - - /* XXX: unsupported arbitrary slice ordering (ASO) */ - /* num_slic_groups_minus1 should be zero */ - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write Slice NAL unit"); - return FALSE; - } -} - -static inline void -_check_sps_pps_status (GstVaapiEncoderH264Fei * encoder, - const guint8 * nal, guint32 size) -{ - guint8 nal_type; - G_GNUC_UNUSED gsize ret; /* FIXME */ - gboolean has_subset_sps; - - g_assert (size); - - has_subset_sps = !encoder->is_mvc || (encoder->subset_sps_data != NULL); - if (encoder->sps_data && encoder->pps_data && has_subset_sps) - return; - - nal_type = nal[0] & 0x1F; - switch (nal_type) { - case GST_H264_NAL_SPS: - encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL); - ret = gst_buffer_fill (encoder->sps_data, 0, nal, size); - g_assert (ret == size); - break; - case GST_H264_NAL_SUBSET_SPS: - encoder->subset_sps_data = gst_buffer_new_allocate (NULL, size, NULL); - ret = gst_buffer_fill (encoder->subset_sps_data, 0, nal, size); - g_assert (ret == size); - break; - case GST_H264_NAL_PPS: - encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL); - ret = gst_buffer_fill (encoder->pps_data, 0, nal, size); - g_assert (ret == size); - break; - default: - break; - } -} - -/* Determines the largest supported profile by the underlying hardware */ -static gboolean -ensure_hw_profile_limits (GstVaapiEncoderH264Fei * encoder) -{ - GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); - GArray *profiles; - guint i, profile_idc, max_profile_idc; - - if (encoder->hw_max_profile_idc) - return TRUE; - - profiles = gst_vaapi_display_get_encode_profiles (display); - if (!profiles) - return FALSE; - - max_profile_idc = 0; - for (i = 0; i < profiles->len; i++) { - const GstVaapiProfile profile = - g_array_index (profiles, GstVaapiProfile, i); - profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); - if (!profile_idc) - continue; - if (max_profile_idc < profile_idc) - max_profile_idc = profile_idc; - } - g_array_unref (profiles); - - encoder->hw_max_profile_idc = max_profile_idc; - return TRUE; -} - -/* Derives the profile supported by the underlying hardware */ -static gboolean -ensure_hw_profile (GstVaapiEncoderH264Fei * encoder) -{ - GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); - GstVaapiEntrypoint entrypoint = encoder->entrypoint; - GstVaapiProfile profile, profiles[4]; - guint i, num_profiles = 0; - - profiles[num_profiles++] = encoder->profile; - switch (encoder->profile) { - case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE: - profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE; - profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN; - // fall-through - case GST_VAAPI_PROFILE_H264_MAIN: - profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; - break; - default: - break; - } - - 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 (0x%08x)", encoder->profile); - return FALSE; - } -} - -/* Check target decoder constraints */ -static gboolean -ensure_profile_limits (GstVaapiEncoderH264Fei * encoder) -{ - GstVaapiProfile profile; - - if (!encoder->max_profile_idc - || encoder->profile_idc <= encoder->max_profile_idc) - return TRUE; - - GST_WARNING ("lowering coding tools to meet target decoder constraints"); - - profile = GST_VAAPI_PROFILE_UNKNOWN; - - /* Try Main profile coding tools */ - if (encoder->max_profile_idc < 100) { - encoder->use_dct8x8 = FALSE; - profile = GST_VAAPI_PROFILE_H264_MAIN; - } - - /* Try Constrained Baseline profile coding tools */ - if (encoder->max_profile_idc < 77) { - encoder->num_bframes = 0; - encoder->use_cabac = FALSE; - profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; - } - - if (profile) { - encoder->profile = profile; - encoder->profile_idc = encoder->max_profile_idc; - } - return TRUE; -} - -/* Derives the minimum profile from the active coding tools */ -static gboolean -ensure_profile (GstVaapiEncoderH264Fei * encoder) -{ - GstVaapiProfile profile; - - /* Always start from "constrained-baseline" profile for maximum - compatibility */ - profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; - - /* Main profile coding tools */ - if (encoder->num_bframes > 0 || encoder->use_cabac) - profile = GST_VAAPI_PROFILE_H264_MAIN; - - /* High profile coding tools */ - if (encoder->use_dct8x8) - profile = GST_VAAPI_PROFILE_H264_HIGH; - - /* MVC profiles coding tools */ - if (encoder->num_views == 2) - profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH; - else if (encoder->num_views > 2) - profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH; - - encoder->profile = profile; - encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); - return TRUE; -} - -/* Derives the level from the currently set limits */ -static gboolean -ensure_level (GstVaapiEncoderH264Fei * encoder) -{ - const guint cpb_factor = h264_get_cpb_nal_factor (encoder->profile); - const GstVaapiH264LevelLimits *limits_table; - guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS; - - PicSizeMbs = encoder->mb_width * encoder->mb_height; - MaxDpbMbs = PicSizeMbs * ((encoder->num_bframes) ? 2 : 1); - MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs, - GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder)); - - limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits); - for (i = 0; i < num_limits; i++) { - const GstVaapiH264LevelLimits *const limits = &limits_table[i]; - if (PicSizeMbs <= limits->MaxFS && - MaxDpbMbs <= limits->MaxDpbMbs && - MaxMBPS <= limits->MaxMBPS && (!encoder->bitrate_bits - || encoder->bitrate_bits <= (limits->MaxBR * cpb_factor)) && - (!encoder->cpb_length_bits || - encoder->cpb_length_bits <= (limits->MaxCPB * cpb_factor))) - break; - } - if (i == num_limits) - goto error_unsupported_level; - - encoder->level = limits_table[i].level; - encoder->level_idc = limits_table[i].level_idc; - return TRUE; - - /* ERRORS */ -error_unsupported_level: - { - GST_ERROR ("failed to find a suitable level matching codec config"); - return FALSE; - } -} - -/* Enable "high-compression" tuning options */ -static gboolean -ensure_tuning_high_compression (GstVaapiEncoderH264Fei * encoder) -{ - guint8 profile_idc; - - if (!ensure_hw_profile_limits (encoder)) - return FALSE; - - profile_idc = encoder->hw_max_profile_idc; - if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc) - profile_idc = encoder->max_profile_idc; - - /* Tuning options to enable Main profile */ - if (profile_idc >= 77 && profile_idc != 88) { - encoder->use_cabac = TRUE; - if (!encoder->num_bframes) - encoder->num_bframes = 1; - } - - /* Tuning options to enable High profile */ - if (profile_idc >= 100) { - encoder->use_dct8x8 = TRUE; - } - return TRUE; -} - -/* Ensure tuning options */ -static gboolean -ensure_tuning (GstVaapiEncoderH264Fei * encoder) -{ - gboolean success; - - switch (GST_VAAPI_ENCODER_TUNE (encoder)) { - case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: - success = ensure_tuning_high_compression (encoder); - break; - case GST_VAAPI_ENCODER_TUNE_LOW_POWER: - /* Set low-power encode entry point. If hardware doesn't have - * support, it will fail in ensure_hw_profile() in later stage. - * So not duplicating the profile/entrypont query mechanism - * here as a part of optimization */ - encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; - success = TRUE; - break; - default: - success = TRUE; - break; - } - return success; -} - -/* Handle new GOP starts */ -static void -reset_gop_start (GstVaapiEncoderH264Fei * encoder) -{ - GstVaapiH264ViewReorderPool *const reorder_pool = - &encoder->reorder_pools[encoder->view_idx]; - - reorder_pool->frame_index = 1; - reorder_pool->cur_frame_num = 0; - reorder_pool->cur_present_index = 0; - ++encoder->idr_num; -} - -/* Marks the supplied picture as a B-frame */ -static void -set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder) -{ - GstVaapiH264ViewReorderPool *const reorder_pool = - &encoder->reorder_pools[encoder->view_idx]; - - g_assert (pic && encoder); - g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); - pic->type = GST_VAAPI_PICTURE_TYPE_B; - pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); -} - -/* Marks the supplied picture as a P-frame */ -static void -set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder) -{ - GstVaapiH264ViewReorderPool *const reorder_pool = - &encoder->reorder_pools[encoder->view_idx]; - - g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); - pic->type = GST_VAAPI_PICTURE_TYPE_P; - pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); -} - -/* Marks the supplied picture as an I-frame */ -static void -set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder) -{ - GstVaapiH264ViewReorderPool *const reorder_pool = - &encoder->reorder_pools[encoder->view_idx]; - - g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); - pic->type = GST_VAAPI_PICTURE_TYPE_I; - pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num); - - g_assert (pic->frame); - GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); -} - -/* Marks the supplied picture as an IDR frame */ -static void -set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264Fei * encoder) -{ - g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); - pic->type = GST_VAAPI_PICTURE_TYPE_I; - pic->frame_num = 0; - pic->poc = 0; - GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR); - - g_assert (pic->frame); - GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); -} - -/* Marks the supplied picture a a key-frame */ -static void -set_key_frame (GstVaapiEncPicture * picture, - GstVaapiEncoderH264Fei * encoder, gboolean is_idr) -{ - if (is_idr) { - reset_gop_start (encoder); - set_idr_frame (picture, encoder); - } else - set_i_frame (picture, encoder); -} - -/* Fills in VA HRD parameters */ -static void -fill_hrd_params (GstVaapiEncoderH264Fei * encoder, VAEncMiscParameterHRD * hrd) -{ - if (encoder->bitrate_bits > 0) { - hrd->buffer_size = encoder->cpb_length_bits; - hrd->initial_buffer_fullness = hrd->buffer_size / 2; - } else { - hrd->buffer_size = 0; - hrd->initial_buffer_fullness = 0; - } -} - -/* Adds the supplied sequence header (SPS) to the list of packed - headers to pass down as-is to the encoder */ -static gboolean -add_packed_sequence_header (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) -{ - GstVaapiEncPackedHeader *packed_seq; - GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 }; - const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; - GstVaapiProfile profile = encoder->profile; - - VAEncMiscParameterHRD hrd_params; - guint32 data_bit_size; - guint8 *data; - - fill_hrd_params (encoder, &hrd_params); - - gst_bit_writer_init_with_size (&bs, 128, FALSE); - WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS); - - /* Set High profile for encoding the MVC base view. Otherwise, some - traditional decoder cannot recognize MVC profile streams with - only the base view in there */ - if (profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH || - profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) - profile = GST_VAAPI_PROFILE_H264_HIGH; - - bs_write_sps (&bs, seq_param, profile, &hrd_params); - - g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); - data = GST_BIT_WRITER_DATA (&bs); - - packed_seq_param.type = VAEncPackedHeaderSequence; - packed_seq_param.bit_length = data_bit_size; - packed_seq_param.has_emulation_bytes = 0; - - packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), - &packed_seq_param, sizeof (packed_seq_param), - data, (data_bit_size + 7) / 8); - g_assert (packed_seq); - - gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_seq, NULL); - - /* store sps data */ - _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_reset (&bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write SPS NAL unit"); - gst_bit_writer_reset (&bs); - return FALSE; - } -} - -static gboolean -add_packed_sequence_header_mvc (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) -{ - GstVaapiEncPackedHeader *packed_seq; - GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; - const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; - VAEncMiscParameterHRD hrd_params; - guint32 data_bit_size; - guint8 *data; - - fill_hrd_params (encoder, &hrd_params); - - /* non-base layer, pack one subset sps */ - gst_bit_writer_init_with_size (&bs, 128, FALSE); - WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS); - - bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views, - encoder->view_ids, &hrd_params); - - g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); - data = GST_BIT_WRITER_DATA (&bs); - - packed_header_param_buffer.type = VAEncPackedHeaderSequence; - packed_header_param_buffer.bit_length = data_bit_size; - packed_header_param_buffer.has_emulation_bytes = 0; - - packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), - &packed_header_param_buffer, sizeof (packed_header_param_buffer), - data, (data_bit_size + 7) / 8); - g_assert (packed_seq); - - gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL); - - /* store subset sps data */ - _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_reset (&bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write SPS NAL unit"); - gst_bit_writer_reset (&bs); - return FALSE; - } -} - -/* Adds the supplied picture header (PPS) to the list of packed - headers to pass down as-is to the encoder */ -static gboolean -add_packed_picture_header (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture) -{ - GstVaapiEncPackedHeader *packed_pic; - GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 }; - const VAEncPictureParameterBufferH264 *const pic_param = picture->param; - guint32 data_bit_size; - guint8 *data; - - gst_bit_writer_init_with_size (&bs, 128, FALSE); - WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS); - bs_write_pps (&bs, pic_param, encoder->profile); - g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); - data = GST_BIT_WRITER_DATA (&bs); - - packed_pic_param.type = VAEncPackedHeaderPicture; - packed_pic_param.bit_length = data_bit_size; - packed_pic_param.has_emulation_bytes = 0; - - packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), - &packed_pic_param, sizeof (packed_pic_param), - data, (data_bit_size + 7) / 8); - g_assert (packed_pic); - - gst_vaapi_enc_picture_add_packed_header (picture, packed_pic); - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_pic, NULL); - - /* store pps data */ - _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_reset (&bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write PPS NAL unit"); - gst_bit_writer_reset (&bs); - return FALSE; - } -} - -static gboolean -add_packed_sei_header (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture, GstVaapiH264SeiPayloadType payloadtype) -{ - GstVaapiEncPackedHeader *packed_sei; - GstBitWriter bs, bs_buf_period, bs_pic_timing; - VAEncPackedHeaderParameterBuffer packed_sei_param = { 0 }; - guint32 data_bit_size; - guint8 buf_period_payload_size = 0, pic_timing_payload_size = 0; - guint8 *data, *buf_period_payload = NULL, *pic_timing_payload = NULL; - gboolean need_buf_period, need_pic_timing; - - gst_bit_writer_init_with_size (&bs_buf_period, 128, FALSE); - gst_bit_writer_init_with_size (&bs_pic_timing, 128, FALSE); - gst_bit_writer_init_with_size (&bs, 128, FALSE); - - need_buf_period = GST_VAAPI_H264_SEI_BUF_PERIOD & payloadtype; - need_pic_timing = GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype; - - if (need_buf_period) { - /* Write a Buffering Period SEI message */ - bs_write_sei_buf_period (&bs_buf_period, encoder, picture); - /* Write byte alignment bits */ - if (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period) % 8 != 0) - bs_write_trailing_bits (&bs_buf_period); - buf_period_payload_size = (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period)) / 8; - buf_period_payload = GST_BIT_WRITER_DATA (&bs_buf_period); - } - - if (need_pic_timing) { - /* Write a Picture Timing SEI message */ - if (GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype) - bs_write_sei_pic_timing (&bs_pic_timing, encoder, picture); - /* Write byte alignment bits */ - if (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing) % 8 != 0) - bs_write_trailing_bits (&bs_pic_timing); - pic_timing_payload_size = (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing)) / 8; - pic_timing_payload = GST_BIT_WRITER_DATA (&bs_pic_timing); - } - - /* Write the SEI message */ - WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_NONE, GST_H264_NAL_SEI); - - if (need_buf_period) { - WRITE_UINT32 (&bs, GST_H264_SEI_BUF_PERIOD, 8); - WRITE_UINT32 (&bs, buf_period_payload_size, 8); - /* Add buffering period sei message */ - gst_bit_writer_put_bytes (&bs, buf_period_payload, buf_period_payload_size); - } - - if (need_pic_timing) { - WRITE_UINT32 (&bs, GST_H264_SEI_PIC_TIMING, 8); - WRITE_UINT32 (&bs, pic_timing_payload_size, 8); - /* Add picture timing sei message */ - gst_bit_writer_put_bytes (&bs, pic_timing_payload, pic_timing_payload_size); - } - - /* rbsp_trailing_bits */ - bs_write_trailing_bits (&bs); - - g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); - data = GST_BIT_WRITER_DATA (&bs); - - packed_sei_param.type = VA_ENC_PACKED_HEADER_H264_SEI; - packed_sei_param.bit_length = data_bit_size; - packed_sei_param.has_emulation_bytes = 0; - - packed_sei = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), - &packed_sei_param, sizeof (packed_sei_param), - data, (data_bit_size + 7) / 8); - g_assert (packed_sei); - - gst_vaapi_enc_picture_add_packed_header (picture, packed_sei); - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_sei, NULL); - - gst_bit_writer_reset (&bs_buf_period); - gst_bit_writer_reset (&bs_pic_timing); - gst_bit_writer_reset (&bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write SEI NAL unit"); - gst_bit_writer_reset (&bs_buf_period); - gst_bit_writer_reset (&bs_pic_timing); - gst_bit_writer_reset (&bs); - return FALSE; - } -} - -static gboolean -get_nal_hdr_attributes (GstVaapiEncPicture * picture, - guint8 * nal_ref_idc, guint8 * nal_unit_type) -{ - switch (picture->type) { - case GST_VAAPI_PICTURE_TYPE_I: - *nal_ref_idc = GST_H264_NAL_REF_IDC_HIGH; - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) - *nal_unit_type = GST_H264_NAL_SLICE_IDR; - else - *nal_unit_type = GST_H264_NAL_SLICE; - break; - case GST_VAAPI_PICTURE_TYPE_P: - *nal_ref_idc = GST_H264_NAL_REF_IDC_MEDIUM; - *nal_unit_type = GST_H264_NAL_SLICE; - break; - case GST_VAAPI_PICTURE_TYPE_B: - *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE; - *nal_unit_type = GST_H264_NAL_SLICE; - break; - default: - return FALSE; - } - return TRUE; -} - -/* Adds the supplied prefix nal header to the list of packed - headers to pass down as-is to the encoder */ -static gboolean -add_packed_prefix_nal_header (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture, GstVaapiEncSlice * slice) -{ - GstVaapiEncPackedHeader *packed_prefix_nal; - GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_prefix_nal_param = { 0 }; - guint32 data_bit_size; - guint8 *data; - guint8 nal_ref_idc, nal_unit_type; - - gst_bit_writer_init_with_size (&bs, 128, FALSE); - WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - - if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) - goto bs_error; - nal_unit_type = GST_H264_NAL_PREFIX_UNIT; - - bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); - bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_idx); - g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); - data = GST_BIT_WRITER_DATA (&bs); - - packed_prefix_nal_param.type = VAEncPackedHeaderRawData; - packed_prefix_nal_param.bit_length = data_bit_size; - packed_prefix_nal_param.has_emulation_bytes = 0; - - packed_prefix_nal = - gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), - &packed_prefix_nal_param, sizeof (packed_prefix_nal_param), data, - (data_bit_size + 7) / 8); - g_assert (packed_prefix_nal); - - gst_vaapi_enc_slice_add_packed_header (slice, packed_prefix_nal); - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_prefix_nal, - NULL); - - gst_bit_writer_reset (&bs); - - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write Prefix NAL unit header"); - gst_bit_writer_reset (&bs); - return FALSE; - } -} - -/* Adds the supplied slice header to the list of packed - headers to pass down as-is to the encoder */ -static gboolean -add_packed_slice_header (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture, GstVaapiEncSlice * slice) -{ - GstVaapiEncPackedHeader *packed_slice; - GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 }; - const VAEncSliceParameterBufferH264 *const slice_param = slice->param; - guint32 data_bit_size; - guint8 *data; - guint8 nal_ref_idc, nal_unit_type; - - gst_bit_writer_init_with_size (&bs, 128, FALSE); - WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - - if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) - goto bs_error; - /* pack nal_unit_header_mvc_extension() for the non base view */ - if (encoder->is_mvc && encoder->view_idx) { - bs_write_nal_header (&bs, nal_ref_idc, GST_H264_NAL_SLICE_EXT); - bs_write_nal_header_mvc_extension (&bs, picture, - encoder->view_ids[encoder->view_idx]); - } else - bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); - - bs_write_slice (&bs, slice_param, encoder, picture); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); - data = GST_BIT_WRITER_DATA (&bs); - - packed_slice_param.type = VAEncPackedHeaderSlice; - packed_slice_param.bit_length = data_bit_size; - packed_slice_param.has_emulation_bytes = 0; - - packed_slice = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), - &packed_slice_param, sizeof (packed_slice_param), - data, (data_bit_size + 7) / 8); - g_assert (packed_slice); - - gst_vaapi_enc_slice_add_packed_header (slice, packed_slice); - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & packed_slice, - NULL); - - gst_bit_writer_reset (&bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write Slice NAL unit header"); - gst_bit_writer_reset (&bs); - return FALSE; - } -} - -/* Reference picture management */ -static void -reference_pic_free (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncoderH264FeiRef * ref) -{ - if (!ref) - return; - if (ref->pic) - gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic); - g_slice_free (GstVaapiEncoderH264FeiRef, ref); -} - -static inline GstVaapiEncoderH264FeiRef * -reference_pic_create (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) -{ - GstVaapiEncoderH264FeiRef *const ref = - g_slice_new0 (GstVaapiEncoderH264FeiRef); - - ref->pic = surface; - ref->frame_num = picture->frame_num; - ref->poc = picture->poc; - return ref; -} - -static gboolean -reference_list_update (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) -{ - GstVaapiEncoderH264FeiRef *ref; - GstVaapiH264ViewRefPool *const ref_pool = - &encoder->ref_pools[encoder->view_idx]; - - if (GST_VAAPI_PICTURE_TYPE_B == picture->type) { - gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface); - return TRUE; - } - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { - while (!g_queue_is_empty (&ref_pool->ref_list)) - reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list)); - } else if (g_queue_get_length (&ref_pool->ref_list) >= - ref_pool->max_ref_frames) { - reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list)); - } - ref = reference_pic_create (encoder, picture, surface); - g_queue_push_tail (&ref_pool->ref_list, ref); - g_assert (g_queue_get_length (&ref_pool->ref_list) <= - ref_pool->max_ref_frames); - return TRUE; -} - -static gboolean -reference_list_init (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture, - GstVaapiEncoderH264FeiRef ** reflist_0, - guint * reflist_0_count, - GstVaapiEncoderH264FeiRef ** reflist_1, guint * reflist_1_count) -{ - GstVaapiEncoderH264FeiRef *tmp; - GstVaapiH264ViewRefPool *const ref_pool = - &encoder->ref_pools[encoder->view_idx]; - GList *iter, *list_0_start = NULL, *list_1_start = NULL; - guint count; - - *reflist_0_count = 0; - *reflist_1_count = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_I) - return TRUE; - - iter = g_queue_peek_tail_link (&ref_pool->ref_list); - for (; iter; iter = g_list_previous (iter)) { - tmp = (GstVaapiEncoderH264FeiRef *) iter->data; - g_assert (tmp && tmp->poc != picture->poc); - if (_poc_greater_than (picture->poc, tmp->poc, encoder->max_pic_order_cnt)) { - list_0_start = iter; - list_1_start = g_list_next (iter); - break; - } - } - - /* order reflist_0 */ - g_assert (list_0_start); - iter = list_0_start; - count = 0; - for (; iter; iter = g_list_previous (iter)) { - reflist_0[count] = (GstVaapiEncoderH264FeiRef *) iter->data; - ++count; - } - *reflist_0_count = count; - - if (picture->type != GST_VAAPI_PICTURE_TYPE_B) - return TRUE; - - /* order reflist_1 */ - count = 0; - iter = list_1_start; - for (; iter; iter = g_list_next (iter)) { - reflist_1[count] = (GstVaapiEncoderH264FeiRef *) iter->data; - ++count; - } - *reflist_1_count = count; - return TRUE; -} - -/* Fills in VA sequence parameter buffer */ -static gboolean -fill_sequence (GstVaapiEncoderH264Fei * encoder, GstVaapiEncSequence * sequence) -{ - VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; - GstVaapiH264ViewRefPool *const ref_pool = - &encoder->ref_pools[encoder->view_idx]; - - memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264)); - seq_param->seq_parameter_set_id = encoder->view_idx; - seq_param->level_idc = encoder->level_idc; - seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); - seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder); - seq_param->ip_period = seq_param->intra_period > 1 ? - (1 + encoder->num_bframes) : 0; - seq_param->bits_per_second = encoder->bitrate_bits; - - seq_param->max_num_ref_frames = ref_pool->max_ref_frames; - seq_param->picture_width_in_mbs = encoder->mb_width; - seq_param->picture_height_in_mbs = encoder->mb_height; - - /*sequence field values */ - seq_param->seq_fields.value = 0; - seq_param->seq_fields.bits.chroma_format_idc = 1; - seq_param->seq_fields.bits.frame_mbs_only_flag = 1; - seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE; - seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE; - /* direct_8x8_inference_flag default false */ - seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE; - g_assert (encoder->log2_max_frame_num >= 4); - seq_param->seq_fields.bits.log2_max_frame_num_minus4 = - encoder->log2_max_frame_num - 4; - /* picture order count */ - encoder->pic_order_cnt_type = seq_param->seq_fields.bits.pic_order_cnt_type = - 0; - g_assert (encoder->log2_max_pic_order_cnt >= 4); - seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = - encoder->log2_max_pic_order_cnt - 4; - - seq_param->bit_depth_luma_minus8 = 0; - seq_param->bit_depth_chroma_minus8 = 0; - - /* not used if pic_order_cnt_type == 0 */ - if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { - encoder->delta_pic_order_always_zero_flag = - seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE; - seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0; - seq_param->offset_for_non_ref_pic = 0; - seq_param->offset_for_top_to_bottom_field = 0; - memset (seq_param->offset_for_ref_frame, 0, - sizeof (seq_param->offset_for_ref_frame)); - } - - /* frame_cropping_flag */ - if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) || - (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) { - static const guint SubWidthC[] = { 1, 2, 2, 1 }; - static const guint SubHeightC[] = { 1, 2, 1, 1 }; - const guint CropUnitX = - SubWidthC[seq_param->seq_fields.bits.chroma_format_idc]; - const guint CropUnitY = - SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] * - (2 - seq_param->seq_fields.bits.frame_mbs_only_flag); - - seq_param->frame_cropping_flag = 1; - seq_param->frame_crop_left_offset = 0; - seq_param->frame_crop_right_offset = - (16 * encoder->mb_width - - GST_VAAPI_ENCODER_WIDTH (encoder)) / CropUnitX; - seq_param->frame_crop_top_offset = 0; - seq_param->frame_crop_bottom_offset = - (16 * encoder->mb_height - - GST_VAAPI_ENCODER_HEIGHT (encoder)) / CropUnitY; - } - - /* VUI parameters are always set, at least for timing_info (framerate) */ - seq_param->vui_parameters_present_flag = TRUE; - if (seq_param->vui_parameters_present_flag) { - seq_param->vui_fields.bits.aspect_ratio_info_present_flag = TRUE; - if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { - const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); - seq_param->aspect_ratio_idc = 0xff; - seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip); - seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip); - } - seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE; - /* if vui_parameters_present_flag is TRUE and sps data belongs to - * subset sps, timing_info_preset_flag should be zero (H.7.4.2.1.1) */ - seq_param->vui_fields.bits.timing_info_present_flag = !encoder->view_idx; - if (seq_param->vui_fields.bits.timing_info_present_flag) { - seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder); - seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2; - } - } - return TRUE; -} - -/* Fills in VA picture parameter buffer */ -static gboolean -fill_picture (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture, - GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) -{ - VAEncPictureParameterBufferH264 *const pic_param = picture->param; - GstVaapiH264ViewRefPool *const ref_pool = - &encoder->ref_pools[encoder->view_idx]; - GstVaapiEncoderH264FeiRef *ref_pic; - GList *reflist; - guint i; - - memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264)); - - /* reference list, */ - pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); - pic_param->CurrPic.TopFieldOrderCnt = picture->poc; - i = 0; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { - for (reflist = g_queue_peek_head_link (&ref_pool->ref_list); - reflist; reflist = g_list_next (reflist)) { - ref_pic = reflist->data; - g_assert (ref_pic && ref_pic->pic && - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID); - - pic_param->ReferenceFrames[i].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); - pic_param->ReferenceFrames[i].TopFieldOrderCnt = ref_pic->poc; - pic_param->ReferenceFrames[i].flags |= - VA_PICTURE_H264_SHORT_TERM_REFERENCE; - pic_param->ReferenceFrames[i].frame_idx = ref_pic->frame_num; - - ++i; - } - g_assert (i <= 16 && i <= ref_pool->max_ref_frames); - } - for (; i < 16; ++i) { - pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID; - } - pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf); - - pic_param->pic_parameter_set_id = encoder->view_idx; - pic_param->seq_parameter_set_id = encoder->view_idx ? 1 : 0; - pic_param->last_picture = 0; /* means last encoding picture */ - pic_param->frame_num = picture->frame_num; - pic_param->pic_init_qp = encoder->init_qp; - pic_param->num_ref_idx_l0_active_minus1 = - (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0); - pic_param->num_ref_idx_l1_active_minus1 = - (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0); - pic_param->chroma_qp_index_offset = 0; - pic_param->second_chroma_qp_index_offset = 0; - - /* set picture fields */ - pic_param->pic_fields.value = 0; - pic_param->pic_fields.bits.idr_pic_flag = - GST_VAAPI_ENC_PICTURE_IS_IDR (picture); - pic_param->pic_fields.bits.reference_pic_flag = - (picture->type != GST_VAAPI_PICTURE_TYPE_B); - pic_param->pic_fields.bits.entropy_coding_mode_flag = encoder->use_cabac; - pic_param->pic_fields.bits.weighted_pred_flag = FALSE; - pic_param->pic_fields.bits.weighted_bipred_idc = 0; - pic_param->pic_fields.bits.constrained_intra_pred_flag = 0; - pic_param->pic_fields.bits.transform_8x8_mode_flag = encoder->use_dct8x8; - /* enable debloking */ - pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; - pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE; - /* bottom_field_pic_order_in_frame_present_flag */ - pic_param->pic_fields.bits.pic_order_present_flag = FALSE; - pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE; - - return TRUE; -} - -/* Adds slice headers to picture */ -static gboolean -add_slice_headers (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture, GstVaapiEncoderH264FeiRef ** reflist_0, - guint reflist_0_count, GstVaapiEncoderH264FeiRef ** reflist_1, - guint reflist_1_count) -{ - VAEncSliceParameterBufferH264 *slice_param; - GstVaapiEncSlice *slice; - guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs; - guint mb_size; - guint last_mb_index; - guint i_slice, i_ref; - - g_assert (picture); - - mb_size = encoder->mb_width * encoder->mb_height; - - g_assert (encoder->num_slices && encoder->num_slices < mb_size); - slice_of_mbs = mb_size / encoder->num_slices; - slice_mod_mbs = mb_size % encoder->num_slices; - last_mb_index = 0; - for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) { - cur_slice_mbs = slice_of_mbs; - if (slice_mod_mbs) { - ++cur_slice_mbs; - --slice_mod_mbs; - } - slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder); - g_assert (slice && slice->param_id != VA_INVALID_ID); - slice_param = slice->param; - - memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264)); - slice_param->macroblock_address = last_mb_index; - slice_param->num_macroblocks = cur_slice_mbs; - slice_param->macroblock_info = VA_INVALID_ID; - slice_param->slice_type = h264_get_slice_type (picture->type); - g_assert ((gint8) slice_param->slice_type != -1); - slice_param->pic_parameter_set_id = encoder->view_idx; - slice_param->idr_pic_id = encoder->idr_num; - slice_param->pic_order_cnt_lsb = picture->poc; - - /* not used if pic_order_cnt_type = 0 */ - slice_param->delta_pic_order_cnt_bottom = 0; - memset (slice_param->delta_pic_order_cnt, 0, - sizeof (slice_param->delta_pic_order_cnt)); - - /* only works for B frames */ - if (slice_param->slice_type == GST_H264_B_SLICE) - slice_param->direct_spatial_mv_pred_flag = TRUE; - /* default equal to picture parameters */ - slice_param->num_ref_idx_active_override_flag = FALSE; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) - slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; - else - slice_param->num_ref_idx_l0_active_minus1 = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0) - slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; - else - slice_param->num_ref_idx_l1_active_minus1 = 0; - g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0); - g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0); - - i_ref = 0; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { - for (; i_ref < reflist_0_count; ++i_ref) { - slice_param->RefPicList0[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); - slice_param->RefPicList0[i_ref].TopFieldOrderCnt = - reflist_0[i_ref]->poc; - slice_param->RefPicList0[i_ref].flags |= - VA_PICTURE_H264_SHORT_TERM_REFERENCE; - slice_param->RefPicList0[i_ref].frame_idx = reflist_0[i_ref]->frame_num; - } - g_assert (i_ref == 1); - } - for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) { - slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE; - } - - i_ref = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { - for (; i_ref < reflist_1_count; ++i_ref) { - slice_param->RefPicList1[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); - slice_param->RefPicList1[i_ref].TopFieldOrderCnt = - reflist_1[i_ref]->poc; - slice_param->RefPicList1[i_ref].flags |= - VA_PICTURE_H264_SHORT_TERM_REFERENCE; - slice_param->RefPicList1[i_ref].frame_idx = reflist_1[i_ref]->frame_num; - } - g_assert (i_ref == 1); - } - for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) { - slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE; - } - - /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */ - slice_param->luma_log2_weight_denom = 0; - slice_param->chroma_log2_weight_denom = 0; - slice_param->luma_weight_l0_flag = FALSE; - memset (slice_param->luma_weight_l0, 0, - sizeof (slice_param->luma_weight_l0)); - memset (slice_param->luma_offset_l0, 0, - sizeof (slice_param->luma_offset_l0)); - slice_param->chroma_weight_l0_flag = FALSE; - memset (slice_param->chroma_weight_l0, 0, - sizeof (slice_param->chroma_weight_l0)); - memset (slice_param->chroma_offset_l0, 0, - sizeof (slice_param->chroma_offset_l0)); - slice_param->luma_weight_l1_flag = FALSE; - memset (slice_param->luma_weight_l1, 0, - sizeof (slice_param->luma_weight_l1)); - memset (slice_param->luma_offset_l1, 0, - sizeof (slice_param->luma_offset_l1)); - slice_param->chroma_weight_l1_flag = FALSE; - memset (slice_param->chroma_weight_l1, 0, - sizeof (slice_param->chroma_weight_l1)); - memset (slice_param->chroma_offset_l1, 0, - sizeof (slice_param->chroma_offset_l1)); - - slice_param->cabac_init_idc = 0; - slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp; - if (slice_param->slice_qp_delta > 4) - slice_param->slice_qp_delta = 4; - if ((gint) encoder->init_qp + slice_param->slice_qp_delta > - (gint) encoder->max_qp) { - slice_param->slice_qp_delta = encoder->max_qp - encoder->init_qp; - } - slice_param->disable_deblocking_filter_idc = 0; - slice_param->slice_alpha_c0_offset_div2 = 2; - slice_param->slice_beta_offset_div2 = 2; - - /* set calculation for next slice */ - last_mb_index += cur_slice_mbs; - - /* add packed Prefix NAL unit before each Coded slice NAL in base view */ - if (encoder->is_mvc && !encoder->view_idx && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & - VA_ENC_PACKED_HEADER_RAW_DATA) - && !add_packed_prefix_nal_header (encoder, picture, slice)) - goto error_create_packed_prefix_nal_hdr; - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & - VA_ENC_PACKED_HEADER_SLICE) - && !add_packed_slice_header (encoder, picture, slice)) - goto error_create_packed_slice_hdr; - - gst_vaapi_enc_picture_add_slice (picture, slice); - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & slice, NULL); - } - g_assert (last_mb_index == mb_size); - return TRUE; - -error_create_packed_slice_hdr: - { - GST_ERROR ("failed to create packed slice header buffer"); - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & slice, NULL); - return FALSE; - } -error_create_packed_prefix_nal_hdr: - { - GST_ERROR ("failed to create packed prefix nal header buffer"); - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & slice, NULL); - return FALSE; - } -} - -/* Generates and submits SPS header accordingly into the bitstream */ -static gboolean -ensure_sequence (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture) -{ - GstVaapiEncSequence *sequence = NULL; - - /* submit an SPS header before every new I-frame, if codec config changed */ - if (!encoder->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I) - return TRUE; - - sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder); - if (!sequence || !fill_sequence (encoder, sequence)) - goto error_create_seq_param; - - /* add subset sps for non-base view and sps for base view */ - if (encoder->is_mvc && encoder->view_idx) { - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & - VA_ENC_PACKED_HEADER_SEQUENCE) - && !add_packed_sequence_header_mvc (encoder, picture, sequence)) - goto error_create_packed_seq_hdr; - } else { - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & - VA_ENC_PACKED_HEADER_SEQUENCE) - && !add_packed_sequence_header (encoder, picture, sequence)) - goto error_create_packed_seq_hdr; - } - - if (sequence) { - gst_vaapi_enc_picture_set_sequence (picture, sequence); - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & sequence, NULL); - } - - if (!encoder->is_mvc || encoder->view_idx > 0) - encoder->config_changed = FALSE; - return TRUE; - - /* ERRORS */ -error_create_seq_param: - { - GST_ERROR ("failed to create sequence parameter buffer (SPS)"); - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & sequence, NULL); - return FALSE; - } -error_create_packed_seq_hdr: - { - GST_ERROR ("failed to create packed sequence header buffer"); - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & sequence, NULL); - return FALSE; - } -} - -/* Generates additional fei control parameters */ -static gboolean -ensure_fei_misc_params (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy) -{ - GstVaapiEncMiscParam *misc = NULL; - GstVaapiSurfaceProxy *surface_proxy = NULL; - - VAEncMiscParameterFEIFrameControlH264 *misc_fei_pic_control_param; - guint mbcode_size = 0; - guint mv_size = 0; - guint dist_size = 0; - gboolean enable_out = FALSE; - - /* fei pic control params */ - misc = GST_VAAPI_ENC_FEI_MISC_PARAM_NEW (H264, encoder); - g_assert (misc); - if (!misc) - return FALSE; - misc_fei_pic_control_param = misc->data; - surface_proxy = picture->proxy; - - enable_out = ((encoder->is_stats_out_enabled && - (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK)) || - (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC)) ? TRUE : FALSE; - - misc_fei_pic_control_param->function = encoder->fei_mode; - misc_fei_pic_control_param->search_path = encoder->search_path; - misc_fei_pic_control_param->num_mv_predictors_l0 = - encoder->num_mv_predictors_l0; - misc_fei_pic_control_param->num_mv_predictors_l1 = - encoder->num_mv_predictors_l1; - misc_fei_pic_control_param->len_sp = encoder->len_sp; - misc_fei_pic_control_param->sub_mb_part_mask = encoder->submb_part_mask; - if (!encoder->use_dct8x8) - misc_fei_pic_control_param->intra_part_mask = encoder->intra_part_mask | 2; - misc_fei_pic_control_param->multi_pred_l0 = encoder->multi_predL0; - misc_fei_pic_control_param->multi_pred_l1 = encoder->multi_predL1; - misc_fei_pic_control_param->sub_pel_mode = encoder->subpel_mode; - misc_fei_pic_control_param->inter_sad = encoder->inter_sad; - misc_fei_pic_control_param->intra_sad = encoder->intra_sad; - misc_fei_pic_control_param->distortion_type = 0; - misc_fei_pic_control_param->repartition_check_enable = 0; - misc_fei_pic_control_param->adaptive_search = encoder->adaptive_search; - misc_fei_pic_control_param->mb_size_ctrl = 0; - misc_fei_pic_control_param->ref_width = encoder->ref_width; - misc_fei_pic_control_param->ref_height = encoder->ref_height; - misc_fei_pic_control_param->search_window = encoder->search_window; - - if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK) || - (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC)) { - - /***** ENC_PAK/ENC input: mv_predictor *****/ - if (surface_proxy->mvpred) { - misc_fei_pic_control_param->mv_predictor = - GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mvpred)->param_id; - misc_fei_pic_control_param->mv_predictor_enable = TRUE; - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & - picture->mvpred, surface_proxy->mvpred); - } else { - misc_fei_pic_control_param->mv_predictor = VA_INVALID_ID; - misc_fei_pic_control_param->mv_predictor_enable = FALSE; - picture->mvpred = NULL; - } - - /***** ENC_PAK/ENC input: qp ******/ - if (surface_proxy->qp) { - misc_fei_pic_control_param->qp = - GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->qp)->param_id; - misc_fei_pic_control_param->mb_qp = TRUE; - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & - picture->qp, surface_proxy->qp); - } else { - misc_fei_pic_control_param->qp = VA_INVALID_ID; - misc_fei_pic_control_param->mb_qp = FALSE; - picture->qp = NULL; - } - - /***** ENC_PAK/ENC input: mb_control ******/ - if (surface_proxy->mbcntrl) { - misc_fei_pic_control_param->mb_ctrl = - GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mbcntrl)->param_id; - misc_fei_pic_control_param->mb_input = TRUE; - gst_vaapi_codec_object_replace ((GstVaapiCodecObject **) & - picture->mbcntrl, surface_proxy->mbcntrl); - } else { - misc_fei_pic_control_param->mb_ctrl = VA_INVALID_ID; - misc_fei_pic_control_param->mb_input = FALSE; - picture->mbcntrl = NULL; - } - } - - if (enable_out) { - - mbcode_size = sizeof (VAEncFEIMBCodeH264) * - encoder->mb_width * encoder->mb_height; - mv_size = sizeof (VAMotionVector) * 16 * - encoder->mb_width * encoder->mb_height; - dist_size = sizeof (VAEncFEIDistortionH264) * - encoder->mb_width * encoder->mb_height; - - /***** ENC_PAK/ENC output: macroblock code buffer *****/ - codedbuf_proxy->mbcode = - gst_vaapi_enc_fei_mb_code_new (GST_VAAPI_ENCODER_CAST (encoder), - NULL, mbcode_size); - misc_fei_pic_control_param->mb_code_data = - GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mbcode)->param_id; - picture->mbcode = gst_vaapi_codec_object_ref (codedbuf_proxy->mbcode); - - /***** ENC_PAK/ENC output: motion vector buffer *****/ - codedbuf_proxy->mv = - gst_vaapi_enc_fei_mv_new (GST_VAAPI_ENCODER_CAST (encoder), NULL, - mv_size); - misc_fei_pic_control_param->mv_data = - GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mv)->param_id; - picture->mv = gst_vaapi_codec_object_ref (codedbuf_proxy->mv); - - /***** ENC_PAK/ENC output: distortion buffer *****/ - codedbuf_proxy->dist = - gst_vaapi_enc_fei_distortion_new (GST_VAAPI_ENCODER_CAST (encoder), - NULL, dist_size); - misc_fei_pic_control_param->distortion = - GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->dist)->param_id; - picture->dist = gst_vaapi_codec_object_ref (codedbuf_proxy->dist); - - } else if (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK) { - - g_assert (surface_proxy->mbcode != NULL); - g_assert (surface_proxy->mv != NULL); - - /***** PAK input: macroblock code buffer *****/ - misc_fei_pic_control_param->mb_code_data = - GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mbcode)->param_id; - picture->mbcode = gst_vaapi_codec_object_ref (surface_proxy->mbcode); - - /***** PAK input: motion vector buffer *****/ - misc_fei_pic_control_param->mv_data = - GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mv)->param_id; - picture->mv = gst_vaapi_codec_object_ref (surface_proxy->mv); - } else { - - codedbuf_proxy->mbcode = picture->mbcode = NULL; - codedbuf_proxy->mv = picture->mv = NULL; - codedbuf_proxy->dist = picture->dist = NULL; - misc_fei_pic_control_param->mb_code_data = VA_INVALID_ID; - misc_fei_pic_control_param->mv_data = VA_INVALID_ID; - misc_fei_pic_control_param->distortion = VA_INVALID_ID; - } - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - return TRUE; -} - -/* Generates additional control parameters */ -static gboolean -ensure_misc_params (GstVaapiEncoderH264Fei * encoder, - GstVaapiEncPicture * picture) -{ - GstVaapiEncMiscParam *misc = NULL; - VAEncMiscParameterRateControl *rate_control; - - /* HRD params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); - g_assert (misc); - if (!misc) - return FALSE; - fill_hrd_params (encoder, misc->data); - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - - /* RateControl params */ - if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR || - GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) { - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); - g_assert (misc); - if (!misc) - return FALSE; - rate_control = misc->data; - memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); - rate_control->bits_per_second = encoder->bitrate_bits; - rate_control->target_percentage = 70; - rate_control->window_size = encoder->cpb_length; - rate_control->initial_qp = encoder->init_qp; - rate_control->min_qp = encoder->min_qp; - -#if VA_CHECK_VERSION(1,1,0) - rate_control->max_qp = encoder->max_qp; -#endif - - rate_control->basic_unit_size = 0; - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - - if (!encoder->view_idx) { - if ((GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & - VA_ENC_PACKED_HEADER_MISC) && - !add_packed_sei_header (encoder, picture, - GST_VAAPI_H264_SEI_BUF_PERIOD | GST_VAAPI_H264_SEI_PIC_TIMING)) - goto error_create_packed_sei_hdr; - - else if (!GST_VAAPI_ENC_PICTURE_IS_IDR (picture) && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & - VA_ENC_PACKED_HEADER_MISC) && - !add_packed_sei_header (encoder, picture, - GST_VAAPI_H264_SEI_PIC_TIMING)) - goto error_create_packed_sei_hdr; - } - - } - return TRUE; - -error_create_packed_sei_hdr: - { - GST_ERROR ("failed to create packed SEI header"); - return FALSE; - } -} - -/* Generates and submits PPS header accordingly into the bitstream */ -static gboolean -ensure_picture (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture, - GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) -{ - GstVaapiCodedBuffer *const codedbuf = - GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); - gboolean res = FALSE; - - res = fill_picture (encoder, picture, codedbuf, surface); - - if (!res) - return FALSE; - - if (picture->type == GST_VAAPI_PICTURE_TYPE_I && - (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & - VA_ENC_PACKED_HEADER_PICTURE) - && !add_packed_picture_header (encoder, picture)) { - GST_ERROR ("set picture packed header failed"); - return FALSE; - } - return TRUE; -} - -/* Generates slice headers */ -static gboolean -ensure_slices (GstVaapiEncoderH264Fei * encoder, GstVaapiEncPicture * picture) -{ - GstVaapiEncoderH264FeiRef *reflist_0[16]; - GstVaapiEncoderH264FeiRef *reflist_1[16]; - GstVaapiH264ViewRefPool *const ref_pool = - &encoder->ref_pools[encoder->view_idx]; - guint reflist_0_count = 0, reflist_1_count = 0; - - g_assert (picture); - - if (picture->type != GST_VAAPI_PICTURE_TYPE_I && - !reference_list_init (encoder, picture, - reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) { - GST_ERROR ("reference list reorder failed"); - return FALSE; - } - - g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames); - if (reflist_0_count > ref_pool->max_reflist0_count) - reflist_0_count = ref_pool->max_reflist0_count; - if (reflist_1_count > ref_pool->max_reflist1_count) - reflist_1_count = ref_pool->max_reflist1_count; - - if (!add_slice_headers (encoder, picture, - reflist_0, reflist_0_count, reflist_1, reflist_1_count)) - return FALSE; - - return TRUE; -} - -/* Normalizes bitrate (and CPB size) for HRD conformance */ -static void -ensure_bitrate_hrd (GstVaapiEncoderH264Fei * encoder) -{ - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - guint bitrate, cpb_size; - - if (!base_encoder->bitrate) { - encoder->bitrate_bits = 0; - return; - } - - /* Round down bitrate. This is a hard limit mandated by the user */ - g_assert (SX_BITRATE >= 6); - bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1); - if (bitrate != encoder->bitrate_bits) { - GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate); - encoder->bitrate_bits = bitrate; - encoder->config_changed = TRUE; - } - - /* Round up CPB size. This is an HRD compliance detail */ - g_assert (SX_CPB_SIZE >= 4); - cpb_size = gst_util_uint64_scale (bitrate, encoder->cpb_length, 1000) & - ~((1U << SX_CPB_SIZE) - 1); - if (cpb_size != encoder->cpb_length_bits) { - GST_DEBUG ("HRD CPB size: %u bits", cpb_size); - encoder->cpb_length_bits = cpb_size; - encoder->config_changed = TRUE; - } -} - -/* Estimates a good enough bitrate if none was supplied */ -static void -ensure_bitrate (GstVaapiEncoderH264Fei * encoder) -{ - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - - /* Default compression: 48 bits per macroblock in "high-compression" mode */ - switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { - case GST_VAAPI_RATECONTROL_CBR: - case GST_VAAPI_RATECONTROL_VBR: - case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: - if (!base_encoder->bitrate) { - /* According to the literature and testing, CABAC entropy coding - mode could provide for +10% to +18% improvement in general, - thus estimating +15% here ; and using adaptive 8x8 transforms - in I-frames could bring up to +10% improvement. */ - guint bits_per_mb = 48; - guint64 factor; - - if (!encoder->use_cabac) - bits_per_mb += (bits_per_mb * 15) / 100; - if (!encoder->use_dct8x8) - bits_per_mb += (bits_per_mb * 10) / 100; - - factor = (guint64) encoder->mb_width * encoder->mb_height * bits_per_mb; - base_encoder->bitrate = - gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder), - GST_VAAPI_ENCODER_FPS_D (encoder)) / 1000; - GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate); - } - break; - default: - base_encoder->bitrate = 0; - break; - } - ensure_bitrate_hrd (encoder); -} - -/* Constructs profile and level information based on user-defined limits */ -static GstVaapiEncoderStatus -ensure_profile_and_level (GstVaapiEncoderH264Fei * encoder) -{ - const GstVaapiProfile profile = encoder->profile; - const GstVaapiLevelH264 level = encoder->level; - - if (!ensure_tuning (encoder)) - GST_WARNING ("Failed to set some of the tuning option as expected! "); - - if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - - /* Check HW constraints */ - if (!ensure_hw_profile_limits (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - if (encoder->profile_idc > encoder->hw_max_profile_idc) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - - /* Ensure bitrate if not set already and derive the right level to use */ - ensure_bitrate (encoder); - if (!ensure_level (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; - - if (encoder->profile != profile || encoder->level != level) { - GST_DEBUG ("selected %s profile at level %s", - gst_vaapi_utils_h264_get_profile_string (encoder->profile), - gst_vaapi_utils_h264_get_level_string (encoder->level)); - encoder->config_changed = TRUE; - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -static void -reset_properties (GstVaapiEncoderH264Fei * encoder) -{ - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); - guint mb_size, i; - - if (encoder->idr_period < base_encoder->keyframe_period) - encoder->idr_period = base_encoder->keyframe_period; - - g_assert (encoder->min_qp <= encoder->max_qp); - if (encoder->min_qp > encoder->init_qp || - (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP && - encoder->min_qp < encoder->init_qp)) - encoder->min_qp = encoder->init_qp; - if (encoder->max_qp < encoder->init_qp) - encoder->max_qp = encoder->init_qp; - - mb_size = encoder->mb_width * encoder->mb_height; - if (encoder->num_slices > (mb_size + 1) / 2) - encoder->num_slices = (mb_size + 1) / 2; - g_assert (encoder->num_slices); - - if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2) - encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2; - - /* Workaround : vaapi-intel-driver doesn't have support for - * B-frame encode when utilizing low-power encode hardware block. - * So Disabling b-frame encoding in low-pwer encode. - * - * Fixme :We should query the VAConfigAttribEncMaxRefFrames - * instead of blindly disabling b-frame support and set b/p frame count, - * buffer pool size etc based on that.*/ - if ((encoder->num_bframes > 0) - && (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)) { - GST_WARNING - ("Disabling b-frame since the driver doesn't supporting it in low-power encode"); - encoder->num_bframes = 0; - } - - if (encoder->num_bframes > 0 && GST_VAAPI_ENCODER_FPS_N (encoder) > 0) - encoder->cts_offset = gst_util_uint64_scale (GST_SECOND, - GST_VAAPI_ENCODER_FPS_D (encoder), GST_VAAPI_ENCODER_FPS_N (encoder)); - else - encoder->cts_offset = 0; - - /* init max_frame_num, max_poc */ - encoder->log2_max_frame_num = - h264_get_log2_max_frame_num (encoder->idr_period); - g_assert (encoder->log2_max_frame_num >= 4); - encoder->max_frame_num = (1 << encoder->log2_max_frame_num); - encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1; - encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt); - encoder->idr_num = 0; - - for (i = 0; i < encoder->num_views; i++) { - GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; - GstVaapiH264ViewReorderPool *const reorder_pool = - &encoder->reorder_pools[i]; - - ref_pool->max_reflist0_count = 1; - ref_pool->max_reflist1_count = encoder->num_bframes > 0; - ref_pool->max_ref_frames = ref_pool->max_reflist0_count - + ref_pool->max_reflist1_count; - - reorder_pool->frame_index = 0; - } -} - -static gboolean -copy_picture_attrib (GstVaapiEncPicture * dst, GstVaapiEncPicture * src) -{ - if (!dst || !src) - return FALSE; - - dst->proxy = src->proxy; - dst->surface = src->surface; - dst->type = src->type; - dst->surface_id = src->surface_id; - dst->frame_num = src->frame_num; - dst->poc = src->poc; - - return TRUE; -} - -static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_fei_encode (GstVaapiEncoder * base_encoder, - GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) -{ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); - GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); - GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; - GstVaapiSurfaceProxy *reconstruct = NULL; - GstVaapiEncPicture *picture2 = NULL; - GstVaapiFeiInfoToPakH264 info_to_pak = { {0} }; - - reconstruct = gst_vaapi_encoder_create_surface (base_encoder); - - g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct)); - - if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK) - || (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC) - || (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK)) { - - if (!ensure_sequence (encoder, picture)) - goto error; - if (!ensure_misc_params (encoder, picture)) - goto error; - if (!encoder->is_fei_disabled - && !ensure_fei_misc_params (encoder, picture, codedbuf)) - goto error; - if (!ensure_picture (encoder, picture, codedbuf, reconstruct)) - goto error; - if (!ensure_slices (encoder, picture)) - goto error; - if (!gst_vaapi_enc_picture_encode (picture)) - goto error; - - if (!reference_list_update (encoder, picture, reconstruct)) - goto error; - - } else if (encoder->fei_mode == - (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) { - /* - * ref pool is managed by pak. - * enc will copy from it. - */ - if (picture->type != GST_VAAPI_PICTURE_TYPE_I - && !gst_vaapi_feipak_h264_get_ref_pool (encoder->feipak, - &encoder->ref_pool_ptr)) { - GST_ERROR ("failed to get pak ref pool"); - status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; - goto error; - } - - if (picture->type != GST_VAAPI_PICTURE_TYPE_I - && !gst_vaapi_feienc_h264_set_ref_pool (encoder->feienc, - encoder->ref_pool_ptr)) { - GST_ERROR ("failed to set enc ref pool"); - status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; - goto error; - } - - status = - gst_vaapi_feienc_h264_encode (enc_base_encoder, picture, reconstruct, - codedbuf, &info_to_pak); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - GST_ERROR ("failed to process enc class encode"); - goto error; - } - - /* duplicate a picture for pak */ - picture2 = GST_VAAPI_ENC_PICTURE_NEW (H264, base_encoder, picture->frame); - if (!picture2) { - GST_WARNING ("create H264 picture failed, frame timestamp:%" - GST_TIME_FORMAT, GST_TIME_ARGS (picture->frame->pts)); - status = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - goto error; - } - if (!copy_picture_attrib (picture2, picture)) { - status = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; - goto error; - } - /* need set picture IDR info for PAK */ - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) - GST_VAAPI_ENC_PICTURE_FLAG_SET (picture2, GST_VAAPI_ENC_PICTURE_FLAG_IDR); - - status = - gst_vaapi_feipak_h264_encode (encoder->feipak, picture2, codedbuf, - reconstruct, &info_to_pak); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - GST_ERROR ("failed to process pak class encode"); - goto error; - } - - /* Free the slice array */ - g_array_free (info_to_pak.h264_slice_headers, TRUE); - - gst_vaapi_enc_picture_unref (picture2); - } else { - GST_ERROR ("invalid FEI mode"); - goto error; - } - - return GST_VAAPI_ENCODER_STATUS_SUCCESS; - - /* ERRORS */ -error: - { - gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), - reconstruct); - if (picture2) - gst_vaapi_enc_picture_unref (picture2); - if (info_to_pak.h264_slice_headers) - g_array_free (info_to_pak.h264_slice_headers, TRUE); - return status; - } -} - -static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_fei_flush (GstVaapiEncoder * base_encoder) -{ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); - GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); - GstVaapiH264ViewReorderPool *reorder_pool; - GstVaapiEncPicture *pic; - GstVaapiEncoderStatus status; - guint i; - - if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK) - || (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK)) { - for (i = 0; i < encoder->num_views; i++) { - reorder_pool = &encoder->reorder_pools[i]; - reorder_pool->frame_index = 0; - reorder_pool->cur_frame_num = 0; - reorder_pool->cur_present_index = 0; - - while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - pic = (GstVaapiEncPicture *) - g_queue_pop_head (&reorder_pool->reorder_frame_list); - gst_vaapi_enc_picture_unref (pic); - } - g_queue_clear (&reorder_pool->reorder_frame_list); - } - } else if (encoder->fei_mode == - (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) { - - status = gst_vaapi_feienc_h264_flush (enc_base_encoder); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - GST_ERROR ("failed to process enc class flush"); - return status; - } - - status = gst_vaapi_feipak_h264_flush (encoder->feipak); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - GST_ERROR ("failed to process pak class flush"); - return status; - } - } else { - g_assert (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC); - } - - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -/* Generate "codec-data" buffer */ -static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_fei_get_codec_data (GstVaapiEncoder * base_encoder, - GstBuffer ** out_buffer_ptr) -{ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); - const guint32 configuration_version = 0x01; - const guint32 nal_length_size = 4; - guint8 profile_idc, profile_comp, level_idc; - GstMapInfo sps_info, pps_info; - GstBitWriter bs; - GstBuffer *buffer; - - if (!encoder->sps_data || !encoder->pps_data) - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER; - if (gst_buffer_get_size (encoder->sps_data) < 4) - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER; - - if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ)) - goto error_map_sps_buffer; - - if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ)) - goto error_map_pps_buffer; - - /* skip sps_data[0], which is the nal_unit_type */ - profile_idc = sps_info.data[1]; - profile_comp = sps_info.data[2]; - level_idc = sps_info.data[3]; - - /* Header */ - gst_bit_writer_init_with_size (&bs, (sps_info.size + pps_info.size + 64), - FALSE); - WRITE_UINT32 (&bs, configuration_version, 8); - WRITE_UINT32 (&bs, profile_idc, 8); - WRITE_UINT32 (&bs, profile_comp, 8); - WRITE_UINT32 (&bs, level_idc, 8); - WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */ - WRITE_UINT32 (&bs, nal_length_size - 1, 2); - WRITE_UINT32 (&bs, 0x07, 3); /* 111 */ - - /* Write SPS */ - WRITE_UINT32 (&bs, 1, 5); /* SPS count = 1 */ - g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - WRITE_UINT32 (&bs, sps_info.size, 16); - gst_bit_writer_put_bytes (&bs, sps_info.data, sps_info.size); - - /* Write PPS */ - WRITE_UINT32 (&bs, 1, 8); /* PPS count = 1 */ - WRITE_UINT32 (&bs, pps_info.size, 16); - gst_bit_writer_put_bytes (&bs, pps_info.data, pps_info.size); - - gst_buffer_unmap (encoder->pps_data, &pps_info); - gst_buffer_unmap (encoder->sps_data, &sps_info); - - buffer = gst_bit_writer_reset_and_get_buffer (&bs); - if (!buffer) - goto error_alloc_buffer; - *out_buffer_ptr = buffer; - - gst_bit_writer_reset (&bs); - return GST_VAAPI_ENCODER_STATUS_SUCCESS; - - /* ERRORS */ -bs_error: - { - GST_ERROR ("failed to write codec-data"); - gst_buffer_unmap (encoder->sps_data, &sps_info); - gst_buffer_unmap (encoder->pps_data, &pps_info); - gst_bit_writer_reset (&bs); - return FALSE; - } -error_map_sps_buffer: - { - GST_ERROR ("failed to map SPS packed header"); - return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - } -error_map_pps_buffer: - { - GST_ERROR ("failed to map PPS packed header"); - gst_buffer_unmap (encoder->sps_data, &sps_info); - return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - } -error_alloc_buffer: - { - GST_ERROR ("failed to allocate codec-data buffer"); - gst_bit_writer_reset (&bs); - return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - } -} - -static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_fei_reordering (GstVaapiEncoder * base_encoder, - GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) -{ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); - GstVaapiH264ViewReorderPool *reorder_pool = NULL; - GstVaapiEncPicture *picture; - gboolean is_idr = FALSE; - - *output = NULL; - - if ((encoder->fei_mode != GST_VAAPI_FEI_MODE_ENC_PAK) - && (encoder->fei_mode != GST_VAAPI_FEI_MODE_PAK)) { - GstVaapiEncoder *enc_base_encoder = - GST_VAAPI_ENCODER_CAST (encoder->feienc); - GstVaapiEncoderStatus status; - - status = gst_vaapi_feienc_h264_reordering (enc_base_encoder, frame, output); - if ((status != GST_VAAPI_ENCODER_STATUS_SUCCESS) && - (status != GST_VAAPI_ENCODER_STATUS_NO_SURFACE)) - GST_ERROR ("failed to process enc reordering"); - - return status; - } - - /* encoding views alternatively for MVC */ - if (encoder->is_mvc) { - /* FIXME: Use first-in-bundle flag on buffers to reset view idx? */ - if (frame) - encoder->view_idx = frame->system_frame_number % encoder->num_views; - else - encoder->view_idx = (encoder->view_idx + 1) % encoder->num_views; - } - reorder_pool = &encoder->reorder_pools[encoder->view_idx]; - - if (!frame) { - if (reorder_pool->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES) - return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; - - /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES - dump B frames from queue, sometime, there may also have P frame or I frame */ - g_assert (encoder->num_bframes > 0); - g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list), - GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN); - picture = g_queue_pop_head (&reorder_pool->reorder_frame_list); - g_assert (picture); - if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; - } - goto end; - } - - /* new frame coming */ - picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame); - if (!picture) { - GST_WARNING ("create H264 picture failed, frame timestamp:%" - GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); - return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - } - ++reorder_pool->cur_present_index; - picture->poc = ((reorder_pool->cur_present_index * 2) % - encoder->max_pic_order_cnt); - - is_idr = (reorder_pool->frame_index == 0 || - reorder_pool->frame_index >= encoder->idr_period); - - /* check key frames */ - if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) || - (reorder_pool->frame_index % - GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == 0) { - ++reorder_pool->cur_frame_num; - ++reorder_pool->frame_index; - - /* b frame enabled, check queue of reorder_frame_list */ - if (encoder->num_bframes - && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - GstVaapiEncPicture *p_pic; - - p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list); - set_p_frame (p_pic, encoder); - g_queue_foreach (&reorder_pool->reorder_frame_list, - (GFunc) set_b_frame, encoder); - ++reorder_pool->cur_frame_num; - set_key_frame (picture, encoder, is_idr); - g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); - picture = p_pic; - reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; - } else { /* no b frames in queue */ - set_key_frame (picture, encoder, is_idr); - g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list)); - if (encoder->num_bframes) - reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; - } - goto end; - } - - /* new p/b frames coming */ - ++reorder_pool->frame_index; - if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES && - g_queue_get_length (&reorder_pool->reorder_frame_list) < - encoder->num_bframes) { - g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); - return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; - } - - ++reorder_pool->cur_frame_num; - set_p_frame (picture, encoder); - - if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) { - g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame, - encoder); - reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; - g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list)); - } - -end: - g_assert (picture); - frame = picture->frame; - if (GST_CLOCK_TIME_IS_VALID (frame->pts)) - frame->pts += encoder->cts_offset; - *output = picture; - - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -static GstVaapiEncoderStatus -set_context_info (GstVaapiEncoder * base_encoder) -{ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); - GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); - const guint DEFAULT_SURFACES_COUNT = 3; - - /* Maximum sizes for common headers (in bits) */ - enum - { - MAX_SPS_HDR_SIZE = 16473, - MAX_VUI_PARAMS_SIZE = 210, - MAX_HRD_PARAMS_SIZE = 4103, - MAX_PPS_HDR_SIZE = 101, - MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402, - }; - - if (!ensure_hw_profile (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - - base_encoder->num_ref_frames = - ((encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT) - * encoder->num_views; - - /* Only YUV 4:2:0 formats are supported for now. This means that we - have a limit of 3200 bits per macroblock. */ - /* XXX: check profile and compute RawMbBits */ - base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) * - GST_ROUND_UP_16 (vip->height) / 256) * 400; - - /* Account for SPS header */ - /* XXX: exclude scaling lists, MVC/SVC extensions */ - base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE + - MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8; - - /* Account for PPS header */ - /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */ - base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8; - - /* Account for slice header */ - base_encoder->codedbuf_size += encoder->num_slices * (4 + - GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); - - base_encoder->context_info.entrypoint = encoder->entrypoint; - - /* Fixme: Add a method to get VA_FEI_FUNCTION_* from GstVaapiFeiMode */ - base_encoder->context_info.config.encoder.fei_function = encoder->fei_mode; - - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -static gboolean -copy_encoder_common_property (GstVaapiEncoder * dst, GstVaapiEncoder * src) -{ - if (!dst || !src) - return FALSE; - - dst->tune = src->tune; - dst->rate_control = src->rate_control; - dst->rate_control_mask = src->rate_control_mask; - dst->bitrate = src->bitrate; - dst->keyframe_period = src->keyframe_period; - - return TRUE; -} - -static GstVaapiEncoderStatus -gst_vaapi_encoder_h264_fei_reconfigure (GstVaapiEncoder * base_encoder) -{ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); - GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder); - GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); - GstVideoInfo *vip_enc = GST_VAAPI_ENCODER_VIDEO_INFO (encoder->feienc); - GstVaapiEncoderStatus status; - guint mb_width, mb_height; - const guint DEFAULT_SURFACES_COUNT = 3; - - if (encoder->fei_mode != (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) { - /* ENC_PAK, ENC and PAK modes doesn't need to care about ENC and PAK - * abstrct objects */ - mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; - mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; - if (mb_width != encoder->mb_width || mb_height != encoder->mb_height) { - GST_DEBUG ("resolution: %dx%d", GST_VAAPI_ENCODER_WIDTH (encoder), - GST_VAAPI_ENCODER_HEIGHT (encoder)); - encoder->mb_width = mb_width; - encoder->mb_height = mb_height; - encoder->config_changed = TRUE; - } - - /* Take number of MVC views from input caps if provided */ - if (GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == - GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME - || GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == - GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME) - encoder->num_views = GST_VIDEO_INFO_VIEWS (vip); - - encoder->is_mvc = encoder->num_views > 1; - - status = ensure_profile_and_level (encoder); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return status; - - reset_properties (encoder); - status = set_context_info (base_encoder); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return status; - - } else { - /* ENC+PAK mode requires two separate objects - for ENC and PAK */ - - /* Maximum sizes for common headers (in bits) */ - enum - { - MAX_SPS_HDR_SIZE = 16473, - MAX_VUI_PARAMS_SIZE = 210, - MAX_HRD_PARAMS_SIZE = 4103, - MAX_PPS_HDR_SIZE = 101, - MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402, - }; - - /* copy encoder-fei common property to feienc */ - if (!copy_encoder_common_property (enc_base_encoder, base_encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; - - /* copy video info to feienc */ - *vip_enc = *vip; - - status = gst_vaapi_feienc_h264_reconfigure (enc_base_encoder); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - GST_ERROR ("failed to process enc reconfigure"); - return status; - } - - if (!gst_vaapi_feienc_h264_get_profile_and_idc (encoder->feienc, - &encoder->profile, &encoder->profile_idc)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; - - base_encoder->profile = enc_base_encoder->profile; - - mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; - mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; - if (mb_width != encoder->mb_width || mb_height != encoder->mb_height) { - GST_DEBUG ("resolution: %dx%d", GST_VAAPI_ENCODER_WIDTH (encoder), - GST_VAAPI_ENCODER_HEIGHT (encoder)); - encoder->mb_width = mb_width; - encoder->mb_height = mb_height; - encoder->config_changed = TRUE; - } - - status = - gst_vaapi_feipak_h264_reconfigure (encoder->feipak, - base_encoder->va_context, encoder->profile, encoder->profile_idc, - encoder->mb_width, encoder->mb_height, encoder->num_views, - encoder->num_slices, encoder->num_ref_frames); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - GST_ERROR ("failed to process pak reconfigure"); - return status; - } - - base_encoder->num_ref_frames = - (encoder->num_ref_frames + DEFAULT_SURFACES_COUNT) * encoder->num_views; - - /* Only YUV 4:2:0 formats are supported for now. This means that we - have a limit of 3200 bits per macroblock. */ - /* XXX: check profile and compute RawMbBits */ - base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) * - GST_ROUND_UP_16 (vip->height) / 256) * 400; - - /* Account for SPS header */ - /* XXX: exclude scaling lists, MVC/SVC extensions */ - base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE + - MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8; - - /* Account for PPS header */ - /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */ - base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8; - - /* Account for slice header */ - base_encoder->codedbuf_size += encoder->num_slices * (4 + - GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); - - base_encoder->context_info.entrypoint = encoder->entrypoint; - - /* ENC+PAK mode use the base encoder context for PAK - * ENC handled separately */ - if (encoder->fei_mode == (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) - base_encoder->context_info.config.encoder.fei_function = - GST_VAAPI_FEI_MODE_PAK; - } - - return status; -} - -struct _GstVaapiEncoderH264FeiClass -{ - GstVaapiEncoderClass parent_class; -}; - -G_DEFINE_TYPE (GstVaapiEncoderH264Fei, gst_vaapi_encoder_h264_fei, - GST_TYPE_VAAPI_ENCODER); - -static void -gst_vaapi_encoder_h264_fei_init (GstVaapiEncoderH264Fei * encoder) -{ - guint32 i; - - /* Default encoding entrypoint */ - encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; - encoder->is_fei_disabled = FALSE; - encoder->is_stats_out_enabled = FALSE; - encoder->fei_mode = GST_VAAPI_FEI_MODE_ENC_PAK; - encoder->search_path = GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT; - encoder->len_sp = GST_VAAPI_FEI_H264_SEARCH_PATH_LENGTH_DEFAULT; - encoder->ref_width = GST_VAAPI_FEI_H264_REF_WIDTH_DEFAULT; - encoder->ref_height = GST_VAAPI_FEI_H264_REF_HEIGHT_DEFAULT; - encoder->intra_part_mask = GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT; - encoder->submb_part_mask = GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT; - /* default num ref frames */ - encoder->num_ref_frames = 1; - /* Multi-view coding information */ - encoder->is_mvc = FALSE; - encoder->num_views = 1; - encoder->view_idx = 0; - memset (encoder->view_ids, 0, sizeof (encoder->view_ids)); - - /* re-ordering list initialize */ - for (i = 0; i < MAX_NUM_VIEWS; i++) { - GstVaapiH264ViewReorderPool *const reorder_pool = - &encoder->reorder_pools[i]; - g_queue_init (&reorder_pool->reorder_frame_list); - reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE; - reorder_pool->frame_index = 0; - reorder_pool->cur_frame_num = 0; - reorder_pool->cur_present_index = 0; - } - - /* reference list info initialize */ - for (i = 0; i < MAX_NUM_VIEWS; i++) { - GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; - g_queue_init (&ref_pool->ref_list); - ref_pool->max_ref_frames = 0; - ref_pool->max_reflist0_count = 1; - ref_pool->max_reflist1_count = 1; - } -} - -static void -gst_vaapi_encoder_h264_fei_finalize (GObject * gobject) -{ - /*free private buffers */ - GstVaapiEncoderH264Fei *const encoder = GST_VAAPI_ENCODER_H264_FEI (gobject); - GstVaapiEncoder *base_encoder = GST_VAAPI_ENCODER (gobject); - GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); - GstVaapiMiniObject *object = GST_VAAPI_MINI_OBJECT (encoder->feipak); - GstVaapiEncPicture *pic; - GstVaapiEncoderH264FeiRef *ref; - guint32 i; - - if ((encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC_PAK) - || (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK)) { - - gst_buffer_replace (&encoder->sps_data, NULL); - gst_buffer_replace (&encoder->subset_sps_data, NULL); - gst_buffer_replace (&encoder->pps_data, NULL); - - /* reference list info de-init */ - for (i = 0; i < MAX_NUM_VIEWS; i++) { - GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i]; - while (!g_queue_is_empty (&ref_pool->ref_list)) { - ref = (GstVaapiEncoderH264FeiRef *) - g_queue_pop_head (&ref_pool->ref_list); - reference_pic_free (encoder, ref); - } - g_queue_clear (&ref_pool->ref_list); - } - - /* re-ordering list initialize */ - for (i = 0; i < MAX_NUM_VIEWS; i++) { - GstVaapiH264ViewReorderPool *const reorder_pool = - &encoder->reorder_pools[i]; - while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - pic = (GstVaapiEncPicture *) - g_queue_pop_head (&reorder_pool->reorder_frame_list); - gst_vaapi_enc_picture_unref (pic); - } - g_queue_clear (&reorder_pool->reorder_frame_list); - } - - } else { - if (encoder->coded_buf != VA_INVALID_ID) { - GST_VAAPI_DISPLAY_LOCK (base_encoder->display); - vaapi_destroy_buffer (base_encoder->va_display, &encoder->coded_buf); - GST_VAAPI_DISPLAY_UNLOCK (base_encoder->display); - encoder->coded_buf = VA_INVALID_ID; - } - - if (enc_base_encoder->va_context != VA_INVALID_ID) { - GST_VAAPI_DISPLAY_LOCK (base_encoder->display); - vaDestroyContext (base_encoder->va_display, enc_base_encoder->va_context); - GST_VAAPI_DISPLAY_UNLOCK (base_encoder->display); - enc_base_encoder->va_context = VA_INVALID_ID; - } - - if (encoder->va_config != VA_INVALID_ID) { - GST_VAAPI_DISPLAY_LOCK (base_encoder->display); - vaDestroyConfig (base_encoder->va_display, encoder->va_config); - GST_VAAPI_DISPLAY_UNLOCK (base_encoder->display); - encoder->va_config = VA_INVALID_ID; - } - - gst_vaapi_encoder_replace (&enc_base_encoder, NULL); - gst_vaapi_mini_object_replace (&object, NULL); - - encoder->ref_pool_ptr = NULL; - encoder->feienc = NULL; - } - - G_OBJECT_CLASS (gst_vaapi_encoder_h264_fei_parent_class)->finalize (gobject); -} - -static void -set_view_ids (GstVaapiEncoderH264Fei * const encoder, const GValue * value) -{ - guint i, j; - guint len = gst_value_array_get_size (value); - - if (len == 0) - goto set_default_ids; - - if (len != encoder->num_views) { - GST_WARNING ("The view number is %d, but %d view IDs are provided. Just " - "fallback to use default view IDs.", encoder->num_views, len); - goto set_default_ids; - } - - for (i = 0; i < len; i++) { - const GValue *val = gst_value_array_get_value (value, i); - encoder->view_ids[i] = g_value_get_uint (val); - } - - /* check whether duplicated ID */ - for (i = 0; i < len; i++) { - for (j = i + 1; j < len; j++) { - if (encoder->view_ids[i] == encoder->view_ids[j]) { - GST_WARNING ("The view %d and view %d have same view ID %d. Just " - "fallback to use default view IDs.", i, j, encoder->view_ids[i]); - goto set_default_ids; - } - } - } - - return; - -set_default_ids: - { - for (i = 0; i < encoder->num_views; i++) - encoder->view_ids[i] = i; - } -} - -static void -get_view_ids (GstVaapiEncoderH264Fei * const encoder, GValue * value) -{ - guint i; - GValue id = G_VALUE_INIT; - - g_value_reset (value); - g_value_init (&id, G_TYPE_UINT); - - for (i = 0; i < encoder->num_views; i++) { - g_value_set_uint (&id, encoder->view_ids[i]); - gst_value_array_append_value (value, &id); - } - g_value_unset (&id); -} - -/** - * @ENCODER_H264_FEI_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). - * @ENCODER_H264_FEI_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). - * @ENCODER_H264_FEI_PROP_MAX_BFRAMES: Number of B-frames between I - * and P (uint). - * @ENCODER_H264_FEI_PROP_INIT_QP: Initial quantizer value (uint). - * @ENCODER_H264_FEI_PROP_MIN_QP: Minimal quantizer value (uint). - * @ENCODER_H264_FEI_PROP_NUM_SLICES: Number of slices per frame (uint). - * @ENCODER_H264_FEI_PROP_CABAC: Enable CABAC entropy coding mode (bool). - * @ENCODER_H264_FEI_PROP_DCT8X8: Enable adaptive use of 8x8 - * transforms in I-frames (bool). - * @ENCODER_H264_FEI_PROP_CPB_LENGTH: Length of the CPB buffer - * in milliseconds (uint). - * @ENCODER_H264_FEI_PROP_NUM_VIEWS: Number of views per frame. - * @ENCODER_H264_FEI_PROP_VIEW_IDS: View IDs - * @ENCODER_H264_FEI_PROP_MAX_QP: Maximal quantizer value (uint). - * - * The set of H.264 encoder specific configurable properties. - */ -enum -{ - ENCODER_H264_FEI_PROP_RATECONTROL = 1, - ENCODER_H264_FEI_PROP_TUNE, - ENCODER_H264_FEI_PROP_MAX_BFRAMES, - ENCODER_H264_FEI_PROP_INIT_QP, - ENCODER_H264_FEI_PROP_MIN_QP, - ENCODER_H264_FEI_PROP_NUM_SLICES, - ENCODER_H264_FEI_PROP_CABAC, - ENCODER_H264_FEI_PROP_DCT8X8, - ENCODER_H264_FEI_PROP_CPB_LENGTH, - ENCODER_H264_FEI_PROP_NUM_VIEWS, - ENCODER_H264_FEI_PROP_VIEW_IDS, - ENCODER_H264_PROP_FEI_DISABLE, - ENCODER_H264_PROP_NUM_MV_PREDICT_L0, - ENCODER_H264_PROP_NUM_MV_PREDICT_L1, - ENCODER_H264_PROP_SEARCH_WINDOW, - ENCODER_H264_PROP_LEN_SP, - ENCODER_H264_PROP_SEARCH_PATH, - ENCODER_H264_PROP_REF_WIDTH, - ENCODER_H264_PROP_REF_HEIGHT, - ENCODER_H264_PROP_SUBMB_MASK, - ENCODER_H264_PROP_SUBPEL_MODE, - ENCODER_H264_PROP_INTRA_PART_MASK, - ENCODER_H264_PROP_INTRA_SAD, - ENCODER_H264_PROP_INTER_SAD, - ENCODER_H264_PROP_ADAPT_SEARCH, - ENCODER_H264_PROP_MULTI_PRED_L0, - ENCODER_H264_PROP_MULTI_PRED_L1, - ENCODER_H264_PROP_ENABLE_STATS_OUT, - ENCODER_H264_PROP_FEI_MODE, - ENCODER_H264_FEI_PROP_MAX_QP, - ENCODER_H264_FEI_N_PROPERTIES -}; - -static GParamSpec *properties[ENCODER_H264_FEI_N_PROPERTIES]; - -static void -gst_vaapi_encoder_h264_fei_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); - GstVaapiEncoder *enc_base_encoder = GST_VAAPI_ENCODER_CAST (encoder->feienc); - GstVaapiEncoderStatus status; - - switch (prop_id) { - case ENCODER_H264_FEI_PROP_RATECONTROL: - gst_vaapi_encoder_set_rate_control (base_encoder, - g_value_get_enum (value)); - break; - case ENCODER_H264_FEI_PROP_TUNE: - gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value)); - break; - case ENCODER_H264_FEI_PROP_MAX_BFRAMES: - encoder->num_bframes = g_value_get_uint (value); - break; - case ENCODER_H264_FEI_PROP_INIT_QP: - encoder->init_qp = g_value_get_uint (value); - break; - case ENCODER_H264_FEI_PROP_MIN_QP: - encoder->min_qp = g_value_get_uint (value); - break; - case ENCODER_H264_FEI_PROP_NUM_SLICES: - encoder->num_slices = g_value_get_uint (value); - break; - case ENCODER_H264_FEI_PROP_CABAC: - encoder->use_cabac = g_value_get_boolean (value); - break; - case ENCODER_H264_FEI_PROP_DCT8X8: - encoder->use_dct8x8 = g_value_get_boolean (value); - break; - case ENCODER_H264_FEI_PROP_CPB_LENGTH: - encoder->cpb_length = g_value_get_uint (value); - break; - case ENCODER_H264_FEI_PROP_NUM_VIEWS: - encoder->num_views = g_value_get_uint (value); - break; - case ENCODER_H264_FEI_PROP_VIEW_IDS: - set_view_ids (encoder, value); - break; - case ENCODER_H264_PROP_FEI_DISABLE: - encoder->is_fei_disabled = g_value_get_boolean (value); - if (!encoder->is_fei_disabled) - encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI; - break; - case ENCODER_H264_PROP_NUM_MV_PREDICT_L0: - encoder->num_mv_predictors_l0 = g_value_get_uint (value); - break; - case ENCODER_H264_PROP_NUM_MV_PREDICT_L1: - encoder->num_mv_predictors_l1 = g_value_get_uint (value); - break; - case ENCODER_H264_PROP_SEARCH_WINDOW: - encoder->search_window = g_value_get_enum (value); - break; - case ENCODER_H264_PROP_LEN_SP: - encoder->len_sp = g_value_get_uint (value); - break; - case ENCODER_H264_PROP_SEARCH_PATH: - encoder->search_path = g_value_get_enum (value); - break; - case ENCODER_H264_PROP_REF_WIDTH: - encoder->ref_width = g_value_get_uint (value); - break; - case ENCODER_H264_PROP_REF_HEIGHT: - encoder->ref_height = g_value_get_uint (value); - break; - case ENCODER_H264_PROP_SUBMB_MASK: - encoder->submb_part_mask = g_value_get_flags (value); - break; - case ENCODER_H264_PROP_SUBPEL_MODE: - encoder->subpel_mode = g_value_get_enum (value); - break; - case ENCODER_H264_PROP_INTRA_PART_MASK: - encoder->intra_part_mask = g_value_get_flags (value); - break; - case ENCODER_H264_PROP_INTRA_SAD: - encoder->intra_sad = g_value_get_enum (value); - break; - case ENCODER_H264_PROP_INTER_SAD: - encoder->inter_sad = g_value_get_enum (value); - break; - case ENCODER_H264_PROP_ADAPT_SEARCH: - encoder->adaptive_search = g_value_get_boolean (value) ? 1 : 0; - break; - case ENCODER_H264_PROP_MULTI_PRED_L0: - encoder->multi_predL0 = g_value_get_boolean (value) ? 1 : 0; - break; - case ENCODER_H264_PROP_MULTI_PRED_L1: - encoder->multi_predL1 = g_value_get_boolean (value) ? 1 : 0; - break; - case ENCODER_H264_PROP_ENABLE_STATS_OUT: - encoder->is_stats_out_enabled = g_value_get_boolean (value); - break; - case ENCODER_H264_PROP_FEI_MODE: - encoder->fei_mode = g_value_get_flags (value); - if (encoder->fei_mode == GST_VAAPI_FEI_MODE_ENC) { - g_warning ("============= ENC only mode selected ============ \n" - "We internally run the PAK stage because, the ENC operation requires the reconstructed output of PAK mode. Right now we have no infrastructure to provide reconstructed surfaces to ENC with out running the PAK \n"); - /*Fixme: Support ENC only mode with out running PAK */ - encoder->fei_mode = GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK; - } else if (encoder->fei_mode == GST_VAAPI_FEI_MODE_PAK) { - g_warning ("============ PAK only mode selected ============ \n" - "This mode can work as expected, only if there is a custom user specific upstream element which provides mb_code and mv_vectors. If you are running the pipeline only for verification, We recommand to use the fei-mod ENC+PAK which will run the ENC operation and generate what ever input needed for PAK \n"); - } - - break; - case ENCODER_H264_FEI_PROP_MAX_QP: - encoder->max_qp = g_value_get_uint (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } - - if ((prop_id != ENCODER_H264_PROP_FEI_MODE) && - (prop_id != ENCODER_H264_PROP_FEI_DISABLE) && - (prop_id != ENCODER_H264_PROP_ENABLE_STATS_OUT)) { - - if (enc_base_encoder) { - g_object_set_property ((GObject *) enc_base_encoder, - g_param_spec_get_name (pspec), value); - } - - if ((prop_id == ENCODER_H264_FEI_PROP_MAX_BFRAMES) || - (prop_id == ENCODER_H264_FEI_PROP_VIEW_IDS) || - (prop_id == ENCODER_H264_FEI_PROP_NUM_VIEWS)) { - if (encoder->feipak) { - status = - gst_vaapi_feipak_h264_set_property (encoder->feipak, prop_id, - value); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) { - GST_ERROR ("failed to set pak property"); - return; - } - } - } - } -} - -static void -gst_vaapi_encoder_h264_fei_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (object); - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); - - switch (prop_id) { - case ENCODER_H264_FEI_PROP_RATECONTROL: - g_value_set_enum (value, base_encoder->rate_control); - break; - case ENCODER_H264_FEI_PROP_TUNE: - g_value_set_enum (value, base_encoder->tune); - break; - case ENCODER_H264_FEI_PROP_MAX_BFRAMES: - g_value_set_uint (value, encoder->num_bframes); - break; - case ENCODER_H264_FEI_PROP_INIT_QP: - g_value_set_uint (value, encoder->init_qp); - break; - case ENCODER_H264_FEI_PROP_MIN_QP: - g_value_set_uint (value, encoder->min_qp); - break; - case ENCODER_H264_FEI_PROP_NUM_SLICES: - g_value_set_uint (value, encoder->num_slices); - break; - case ENCODER_H264_FEI_PROP_CABAC: - g_value_set_boolean (value, encoder->use_cabac); - break; - case ENCODER_H264_FEI_PROP_DCT8X8: - g_value_set_boolean (value, encoder->use_dct8x8); - break; - case ENCODER_H264_FEI_PROP_CPB_LENGTH: - g_value_set_uint (value, encoder->cpb_length); - break; - case ENCODER_H264_FEI_PROP_NUM_VIEWS: - g_value_set_uint (value, encoder->num_views); - break; - case ENCODER_H264_FEI_PROP_VIEW_IDS: - get_view_ids (encoder, value); - break; - case ENCODER_H264_PROP_FEI_DISABLE: - g_value_set_boolean (value, encoder->is_fei_disabled); - break; - case ENCODER_H264_PROP_NUM_MV_PREDICT_L0: - g_value_set_uint (value, encoder->num_mv_predictors_l0); - break; - case ENCODER_H264_PROP_NUM_MV_PREDICT_L1: - g_value_set_uint (value, encoder->num_mv_predictors_l1); - break; - case ENCODER_H264_PROP_SEARCH_WINDOW: - g_value_set_enum (value, encoder->search_window); - break; - case ENCODER_H264_PROP_LEN_SP: - g_value_set_uint (value, encoder->len_sp); - break; - case ENCODER_H264_PROP_SEARCH_PATH: - g_value_set_enum (value, encoder->search_path); - break; - case ENCODER_H264_PROP_REF_WIDTH: - g_value_set_uint (value, encoder->ref_width); - break; - case ENCODER_H264_PROP_REF_HEIGHT: - g_value_set_uint (value, encoder->ref_height); - break; - case ENCODER_H264_PROP_SUBMB_MASK: - g_value_set_flags (value, encoder->submb_part_mask); - break; - case ENCODER_H264_PROP_SUBPEL_MODE: - g_value_set_enum (value, encoder->subpel_mode); - break; - case ENCODER_H264_PROP_INTRA_PART_MASK: - g_value_set_flags (value, encoder->intra_part_mask); - break; - case ENCODER_H264_PROP_INTRA_SAD: - g_value_set_enum (value, encoder->intra_sad); - break; - case ENCODER_H264_PROP_INTER_SAD: - g_value_set_enum (value, encoder->inter_sad); - break; - case ENCODER_H264_PROP_ADAPT_SEARCH: - g_value_set_boolean (value, encoder->adaptive_search); - break; - case ENCODER_H264_PROP_MULTI_PRED_L0: - g_value_set_boolean (value, encoder->multi_predL0); - break; - case ENCODER_H264_PROP_MULTI_PRED_L1: - g_value_set_boolean (value, encoder->multi_predL1); - break; - case ENCODER_H264_PROP_ENABLE_STATS_OUT: - g_value_set_boolean (value, encoder->is_stats_out_enabled); - break; - case ENCODER_H264_PROP_FEI_MODE: - g_value_set_flags (value, encoder->fei_mode); - break; - case ENCODER_H264_FEI_PROP_MAX_QP: - g_value_set_uint (value, encoder->max_qp); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -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 gboolean -create_context_for_enc (GstVaapiEncoder * fei_encoder, - GstVaapiEncoder * enc_encoder) -{ - GstVaapiEncoderH264Fei *const feiencoder = - GST_VAAPI_ENCODER_H264_FEI (fei_encoder); - GstVaapiContext *context = fei_encoder->context; - const GstVaapiContextInfo *const cip = &context->info; - GstVaapiDisplay *const display = fei_encoder->display; - const GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; - guint va_rate_control; - VAConfigAttrib attribs[5], *attrib = attribs; - VASurfaceID surface_id; - VAStatus status; - GArray *surfaces = NULL; - gboolean success = FALSE; - guint i, value, va_chroma_format; - - if (!context->surfaces) - 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); - if (!cip->profile || !cip->entrypoint) - goto cleanup; - - /* 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++; - - /* 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++; - } - - /* Packed headers */ - if (config->packed_headers) { - attrib->type = VAConfigAttribEncPackedHeaders; - attrib->value = VA_ENC_PACKED_HEADER_NONE; - attrib++; - } - - if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI) { - attrib->type = (VAConfigAttribType) VAConfigAttribFEIFunctionType; - attrib->value = VA_FEI_FUNCTION_ENC; - attrib++; - attrib->type = (VAConfigAttribType) VAConfigAttribFEIMVPredictors; - attrib->value = 1; - attrib++; - } - - GST_VAAPI_DISPLAY_LOCK (display); - status = vaCreateConfig (GST_VAAPI_DISPLAY_VADISPLAY (display), - context->va_profile, context->va_entrypoint, attribs, attrib - attribs, - &feiencoder->va_config); - GST_VAAPI_DISPLAY_UNLOCK (display); - if (!vaapi_check_status (status, "vaCreateConfig()")) - goto cleanup; - - GST_VAAPI_DISPLAY_LOCK (display); - status = vaCreateContext (GST_VAAPI_DISPLAY_VADISPLAY (display), - feiencoder->va_config, GST_ROUND_UP_16 (cip->width), - GST_ROUND_UP_16 (cip->height), VA_PROGRESSIVE, - (VASurfaceID *) surfaces->data, surfaces->len, &enc_encoder->va_context); - GST_VAAPI_DISPLAY_UNLOCK (display); - if (!vaapi_check_status (status, "vaCreateContext()")) - goto cleanup; - - success = TRUE; - -cleanup: - if (surfaces) - g_array_free (surfaces, TRUE); - return success; -} - -static const GstVaapiEncoderClassData fei_encoder_class_data = { - .codec = GST_VAAPI_CODEC_H264, - .packed_headers = SUPPORTED_PACKED_HEADERS, - .rate_control_get_type = gst_vaapi_rate_control_get_type, - .default_rate_control = DEFAULT_RATECONTROL, - .rate_control_mask = SUPPORTED_RATECONTROLS, - .encoder_tune_get_type = gst_vaapi_encoder_tune_get_type, - .default_encoder_tune = GST_VAAPI_ENCODER_TUNE_NONE, - .encoder_tune_mask = SUPPORTED_TUNE_OPTIONS, -}; - -static void -gst_vaapi_encoder_h264_fei_class_init (GstVaapiEncoderH264FeiClass * klass) -{ - GObjectClass *const object_class = G_OBJECT_CLASS (klass); - GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass); - - encoder_class->class_data = &fei_encoder_class_data; - encoder_class->reconfigure = gst_vaapi_encoder_h264_fei_reconfigure; - encoder_class->reordering = gst_vaapi_encoder_h264_fei_reordering; - encoder_class->encode = gst_vaapi_encoder_h264_fei_encode; - encoder_class->flush = gst_vaapi_encoder_h264_fei_flush; - encoder_class->get_codec_data = gst_vaapi_encoder_h264_fei_get_codec_data; - encoder_class->ensure_secondary_context = - gst_vaapi_encoder_h264_fei_ensure_secondary_context; - - object_class->set_property = gst_vaapi_encoder_h264_fei_set_property; - object_class->get_property = gst_vaapi_encoder_h264_fei_get_property; - object_class->finalize = gst_vaapi_encoder_h264_fei_finalize; - - /** - * GstVaapiEncoderH264Fei:rate-control: - * - * The desired rate control mode, expressed as a #GstVaapiRateControl. - */ - properties[ENCODER_H264_FEI_PROP_RATECONTROL] = - g_param_spec_enum ("rate-control", "Rate Control", "Rate control mode", - fei_encoder_class_data.rate_control_get_type (), - fei_encoder_class_data.default_rate_control, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264Fei:tune: - * - * The desired encoder tuning option. - */ - properties[ENCODER_H264_FEI_PROP_TUNE] = - g_param_spec_enum ("tune", - "Encoder Tuning", - "Encoder tuning option", - fei_encoder_class_data.encoder_tune_get_type (), - fei_encoder_class_data.default_encoder_tune, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264Fei:max-bframes: - * - * The number of B-frames between I and P. - */ - properties[ENCODER_H264_FEI_PROP_MAX_BFRAMES] = - g_param_spec_uint ("max-bframes", - "Max B-Frames", "Number of B-frames between I and P", 0, 10, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264Fei:init-qp: - * - * The initial quantizer value. - */ - properties[ENCODER_H264_FEI_PROP_INIT_QP] = - g_param_spec_uint ("init-qp", - "Initial QP", "Initial quantizer value", 0, 51, 26, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264Fei:min-qp: - * - * The minimum quantizer value. - */ - properties[ENCODER_H264_FEI_PROP_MIN_QP] = - g_param_spec_uint ("min-qp", - "Minimum QP", "Minimum quantizer value", 0, 51, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264Fei:max-qp: - * - * The maximum quantizer value. - * - * Since: 1.18 - */ - properties[ENCODER_H264_FEI_PROP_MAX_QP] = - g_param_spec_uint ("max-qp", - "Maximum QP", "Maximum quantizer value", 0, 51, 51, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264Fei:num-slices: - * - * The number of slices per frame. - */ - properties[ENCODER_H264_FEI_PROP_NUM_SLICES] = - g_param_spec_uint ("num-slices", - "Number of Slices", - "Number of slices per frame", - 1, 200, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264Fei:cabac: - * - * Enable CABAC entropy coding mode for improved compression ratio, - * at the expense that the minimum target profile is Main. Default - * is CAVLC entropy coding mode. - */ - properties[ENCODER_H264_FEI_PROP_CABAC] = - g_param_spec_boolean ("cabac", - "Enable CABAC", - "Enable CABAC entropy coding mode", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264Fei:dct8x8: - * - * Enable adaptive use of 8x8 transforms in I-frames. This improves - * the compression ratio by the minimum target profile is High. - * Default is to use 4x4 DCT only. - */ - properties[ENCODER_H264_FEI_PROP_DCT8X8] = - g_param_spec_boolean ("dct8x8", - "Enable 8x8 DCT", - "Enable adaptive use of 8x8 transforms in I-frames", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264Fei:cpb-length: - * - * The size of the CPB buffer in milliseconds. - */ - properties[ENCODER_H264_FEI_PROP_CPB_LENGTH] = - g_param_spec_uint ("cpb-length", - "CPB Length", "Length of the CPB buffer in milliseconds", - 1, 10000, DEFAULT_CPB_LENGTH, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264Fei:num-views: - * - * The number of views for MVC encoding . - */ - properties[ENCODER_H264_FEI_PROP_NUM_VIEWS] = - g_param_spec_uint ("num-views", - "Number of Views", - "Number of Views for MVC encoding", - 1, MAX_NUM_VIEWS, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiEncoderH264Fei:view-ids: - * - * The view ids for MVC encoding . - */ - properties[ENCODER_H264_FEI_PROP_VIEW_IDS] = - gst_param_spec_array ("view-ids", - "View IDs", "Set of View Ids used for MVC encoding", - g_param_spec_uint ("view-id-value", "View id value", - "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264: disable-fei: - * - * Disable FEI mode Encode: disabling fei will results - * the encoder to use VAEntrypointEncSlice, which means - * vaapi-intel-driver will be using a different media kerenl. - * And most of the properties associated with this element - * will be non functional. - */ - properties[ENCODER_H264_PROP_FEI_DISABLE] = - g_param_spec_boolean ("disable-fei", - "Disable FEI Mode Encode", - "Disable Flexible Encoding Infrasturcture", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - - /** - * GstVaapiEncoderH264: stats-out: - * - * Enable outputting fei buffers MV, MBCode and Distortion. - * If enabled, encoder will allocate memory for these buffers - * and submit to the driver even for ENC_PAK mode so that - * the output data can be extraced for analysis after the - * complettion of each frame ncode - */ - properties[ENCODER_H264_PROP_ENABLE_STATS_OUT] = - g_param_spec_boolean ("stats-out", - "stats out", - "Enable stats out for fei", - TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264:num_mv_predictors_l0: - * Indicate how many mv predictors should be used for l0 frames. - * Only valid if MVPredictor input has been enabled. - */ - properties[ENCODER_H264_PROP_NUM_MV_PREDICT_L0] = - g_param_spec_uint ("num-mvpredict-l0", - "Num mv predict l0", - "Indicate how many predictors should be used for l0," - "only valid if MVPredictor input enabled", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiEncoderH264:num_mv_predictors_l1: - * Indicate how many mv predictors should be used for l1 frames. - * Only valid if MVPredictor input has been enabled. - * - */ - properties[ENCODER_H264_PROP_NUM_MV_PREDICT_L1] = - g_param_spec_uint ("num-mvpredict-l1", - "Num mv predict l1", - "Indicate how many predictors should be used for l1," - "only valid if MVPredictor input enabled", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiEncoderH264:search-window: - * Use predefined Search Window - */ - properties[ENCODER_H264_PROP_SEARCH_WINDOW] = - g_param_spec_enum ("search-window", - "search window", - "Specify one of the predefined search path", - GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264:len-sp: - * Defines the maximum number of Search Units per reference. - */ - properties[ENCODER_H264_PROP_LEN_SP] = - g_param_spec_uint ("len-sp", - "length of search path", - "This value defines number of search units in search path", - 1, 63, 32, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264:search-path: - * SearchPath defines the motion search method. - * Zero means full search, 1 indicate diamond search. - */ - properties[ENCODER_H264_PROP_SEARCH_PATH] = - g_param_spec_enum ("search-path", - "search path", - "Specify search path", - GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, - GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264:ref-width: - * Specifies the search region width in pixels. - */ - properties[ENCODER_H264_PROP_REF_WIDTH] = - g_param_spec_uint ("ref-width", - "ref width", - "Width of search region in pixel, must be multiple of 4", - 4, 64, 32, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264:ref-height: - * Specifies the search region height in pixels. - */ - properties[ENCODER_H264_PROP_REF_HEIGHT] = - g_param_spec_uint ("ref-height", - "ref height", - "Height of search region in pixel, must be multiple of 4", - 4, 32, 32, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiEncoderH264:submb-mask: - * Defines the bit-mask for disabling sub-partition - * - */ - properties[ENCODER_H264_PROP_SUBMB_MASK] = - g_param_spec_flags ("submbpart-mask", - "submb part mask", - "defines the bit-mask for disabling sub mb partition", - GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, - GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264:subpel-mode: - * defines the half/quarter pel modes - * 00: integer mode searching - * 01: half-pel mode searching - * 11: quarter-pel mode searching - */ - properties[ENCODER_H264_PROP_SUBPEL_MODE] = - g_param_spec_enum ("subpel-mode", - "subpel mode", - "Sub pixel precision for motion estimation", - GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, - GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiEncoderH264:intrapart-mask: - * Specifies which Luma Intra partition is enabled/disabled - * for intra mode decision - */ - properties[ENCODER_H264_PROP_INTRA_PART_MASK] = - g_param_spec_flags ("intrapart-mask", - "intra part mask", - "Specifies which Luma Intra partition is enabled/disabled for" - "intra mode decision", - GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, - GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264:intra-sad: - * Specifies distortion measure adjustments used for - * the motion search SAD comparison. - */ - properties[ENCODER_H264_PROP_INTRA_SAD] = - g_param_spec_enum ("intra-sad", - "intra sad", - "Specifies distortion measure adjustments used" - "in the motion search SAD comparison for intra MB", - GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264:inter-sad: - * Specifies distortion measure adjustments used - * in the motion search SAD comparison for inter MB - */ - properties[ENCODER_H264_PROP_INTER_SAD] = - g_param_spec_enum ("inter-sad", - "inter sad", - "Specifies distortion measure adjustments used" - "in the motion search SAD comparison for inter MB", - GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264:adaptive-search: - * Defines whether adaptive searching is enabled for IME - */ - properties[ENCODER_H264_PROP_ADAPT_SEARCH] = - g_param_spec_boolean ("adaptive-search", - "adaptive-search", - "Enable adaptive search", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiEncoderH264:multi-predL0: - * When set to 1, neighbor MV will be used as predictor for list L0, - * otherwise no neighbor MV will be used as predictor - */ - properties[ENCODER_H264_PROP_MULTI_PRED_L0] = - g_param_spec_boolean ("multi-predL0", - "multi predL0", - "Enable multi prediction for ref L0 list, when set neighbor MV will be used" - "as predictor, no neighbor MV will be used otherwise", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264:multi-predL1: - * When set to 1, neighbor MV will be used as predictor - * when set to 0, no neighbor MV will be used as predictor. - */ - properties[ENCODER_H264_PROP_MULTI_PRED_L1] = - g_param_spec_boolean ("multi-predL1", - "multi predL1", - "Enable multi prediction for ref L1 list, when set neighbor MV will be used" - "as predictor, no neighbor MV will be used otherwise", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiEncoderH264Fei: fei-mode: - * - * Cose ENC, PAK, ENC_PAK, or ENC+PAK - * ENC: Only the Motion Estimation, no transformation or entropy coding - * PAK: transformation, quantization and entropy coding - * ENC_PAK: default mode, enc an pak are invoked by driver, middleware has - control over ENC input only - * ENC+PAK: enc and pak invoked separately, middleware has control over the ENC input, - ENC output, and PAK input - * Encoding mode which can be used for FEI - */ - properties[ENCODER_H264_PROP_FEI_MODE] = - g_param_spec_flags ("fei-mode", - "FEI Encoding Mode", - "Functional mode of FEI Encoding", - GST_VAAPI_TYPE_FEI_MODE, GST_VAAPI_FEI_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - g_object_class_install_properties (object_class, - ENCODER_H264_FEI_N_PROPERTIES, properties); -} - -/** - * gst_vaapi_encoder_h264_fei_set_max_profile: - * @encoder: a #GstVaapiEncoderH264Fei - * @profile: an H.264 #GstVaapiProfile - * - * Notifies the @encoder to use coding tools from the supplied - * @profile at most. - * - * This means that if the minimal profile derived to - * support the specified coding tools is greater than this @profile, - * then an error is returned when the @encoder is configured. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_encoder_h264_fei_set_max_profile (GstVaapiEncoderH264Fei * - encoder, GstVaapiProfile profile) -{ - guint8 profile_idc; - - g_return_val_if_fail (encoder != NULL, FALSE); - g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE); - - if (encoder->fei_mode == (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) { - if (!gst_vaapi_feienc_h264_set_max_profile (encoder->feienc, profile)) - return FALSE; - return TRUE; - } - - if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264) - return FALSE; - - profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); - if (!profile_idc) - return FALSE; - - encoder->max_profile_idc = profile_idc; - return TRUE; -} - -/** - * gst_vaapi_encoder_h264_fei_get_profile_and_level: - * @encoder: a #GstVaapiEncoderH264Fei - * @out_profile_ptr: return location for the #GstVaapiProfile - * @out_level_ptr: return location for the #GstVaapiLevelH264 - * - * Queries the H.264 @encoder for the active profile and level. That - * information is only constructed and valid after the encoder is - * configured, i.e. after the gst_vaapi_encoder_set_codec_state() - * function is called. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_encoder_h264_fei_get_profile_and_level (GstVaapiEncoderH264Fei * - encoder, GstVaapiProfile * out_profile_ptr, - GstVaapiLevelH264 * out_level_ptr) -{ - g_return_val_if_fail (encoder != NULL, FALSE); - - if (!encoder->profile || !encoder->level) - return FALSE; - - if (out_profile_ptr) - *out_profile_ptr = encoder->profile; - if (out_level_ptr) - *out_level_ptr = encoder->level; - return TRUE; -} - -/** - * gst_vaapi_encoder_h264_is_fei_stats_out_enabled - * @encoder: a #GstVaapiEncoderH264 - * - * check if fei output statis is needed - * - * Return value: %TRUE if output statistic is needed - */ -gboolean -gst_vaapi_encoder_h264_is_fei_stats_out_enabled (GstVaapiEncoderH264Fei * - encoder) -{ - return !encoder->is_fei_disabled && encoder->is_stats_out_enabled; -} - -/** - * gst_vaapi_encoder_h264_fei_get_function_mode - * @encoder: a #GstVaapiEncoderH264Fei - * - * return the configured FEI Encoding mode - * - * Return value: a #GstVaapiFeiMode - */ -GstVaapiFeiMode -gst_vaapi_encoder_h264_fei_get_function_mode (GstVaapiEncoderH264Fei * encoder) -{ - return encoder->fei_mode; -} - -/** - * gst_vaapi_encoder_h264_fei_set_function_mode - * @encoder: a #GstVaapiEncoderH264Fei - * - * set the configured FEI Encoding mode - * - */ -void -gst_vaapi_encoder_h264_fei_set_function_mode (GstVaapiEncoderH264Fei * encoder, - guint fei_mode) -{ - encoder->fei_mode = fei_mode; -} - -static gboolean -gst_vaapi_encoder_h264_fei_ensure_secondary_context (GstVaapiEncoder * - base_encoder) -{ - GstVaapiEncoderH264Fei *const feiencoder = - GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); - GstVaapiEncoder *enc_base_encoder = - GST_VAAPI_ENCODER_CAST (feiencoder->feienc); - gboolean success; - - if (feiencoder->fei_mode != (GST_VAAPI_FEI_MODE_ENC | GST_VAAPI_FEI_MODE_PAK)) - return TRUE; - - /* Create separate context for ENC */ - if (!create_context_for_enc (base_encoder, enc_base_encoder)) { - GST_ERROR ("create vacontext for enc failed.\n"); - return FALSE; - } - - /* - * create coded-buf for ENC. - * PAK coded-buf is created by parent encoder. - */ - success = - vaapi_create_buffer (enc_base_encoder->va_display, - enc_base_encoder->va_context, VAEncCodedBufferType, - base_encoder->codedbuf_size, NULL, &feiencoder->coded_buf, NULL); - if (!success) { - g_error ("failed to create coded buf for feienc.\n"); - return FALSE; - } - - return TRUE; -} - -/** - * gst_vaapi_encoder_h264_fei_new: - * @display: a #GstVaapiDisplay - * - * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the - * only supported output stream format is "byte-stream" format. - * - * Return value: the newly allocated #GstVaapiEncoder object - */ -GstVaapiEncoder * -gst_vaapi_encoder_h264_fei_new (GstVaapiDisplay * display) -{ - GstVaapiEncoder *base_encoder; - GstVaapiEncoderH264Fei *feiencoder = NULL; - GstVaapiFeiEncH264 *feienc = NULL; - GstVaapiFEIPakH264 *feipak = NULL; - - /* create FEIEncoderObject: Default mode of operation in ENC_PAK */ - base_encoder = - g_object_new (GST_TYPE_VAAPI_ENCODER_H264_FEI, "display", display, NULL); - if (!base_encoder) - return NULL; - feiencoder = GST_VAAPI_ENCODER_H264_FEI_CAST (base_encoder); - - /* create an enc object */ - feienc = GST_VAAPI_FEI_ENC_H264 (gst_vaapi_feienc_h264_new (display)); - if (!feienc) - goto error; - - /* create a pak object */ - feipak = - gst_vaapi_feipak_h264_new (base_encoder, display, - base_encoder->va_context); - if (!feipak) - goto error; - - feiencoder->feienc = feienc; - feiencoder->feipak = feipak; - - return base_encoder; - -error: - if (feienc) - g_object_unref (feienc); - if (feiencoder) - g_object_unref (feiencoder); - - return NULL; -} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h deleted file mode 100644 index b1c08d9fd9..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * gstvaapiencoder_h264_fei.h - H.264 FEI encoder - * - * Copyright (C) 2016-2017 Intel Corporation - * Author: Yi A Wang - * Author: Sreerenj Balachandran - * - * 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_FEI_H -#define GST_VAAPI_ENCODER_H264_FEI_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_VAAPI_ENCODER_H264_FEI \ - (gst_vaapi_encoder_h264_fei_get_type ()) -#define GST_VAAPI_ENCODER_H264_FEI(encoder) \ - (G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_ENCODER_H264_FEI, GstVaapiEncoderH264Fei)) -#define GST_IS_VAAPI_ENCODER_H264_FEI(encoder) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_ENCODER_H264_FEI)) - -typedef struct _GstVaapiEncoderH264Fei GstVaapiEncoderH264Fei; -typedef struct _GstVaapiEncoderH264FeiClass GstVaapiEncoderH264FeiClass; - -GType -gst_vaapi_encoder_h264_fei_get_type (void) G_GNUC_CONST; - -GstVaapiEncoder * -gst_vaapi_encoder_h264_fei_new (GstVaapiDisplay * display); - -gboolean -gst_vaapi_encoder_h264_fei_set_max_profile (GstVaapiEncoderH264Fei * encoder, - GstVaapiProfile profile); - -gboolean -gst_vaapi_encoder_h264_fei_get_profile_and_level (GstVaapiEncoderH264Fei * encoder, - GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr); - -gboolean -gst_vaapi_encoder_h264_is_fei_stats_out_enabled (GstVaapiEncoderH264Fei * encoder); - -GstVaapiFeiMode -gst_vaapi_encoder_h264_fei_get_function_mode (GstVaapiEncoderH264Fei *encoder); - -void -gst_vaapi_encoder_h264_fei_set_function_mode (GstVaapiEncoderH264Fei * encoder, - guint fei_mode); - -G_END_DECLS - -#endif /*GST_VAAPI_ENCODER_H264_FEI_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c index 09fcc18ae4..af1cf61eb3 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c @@ -349,15 +349,6 @@ gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture) gst_vaapi_codec_object_replace (&picture->sequence, NULL); -#if USE_H264_FEI_ENCODER - gst_vaapi_codec_object_replace (&picture->mvpred, NULL); - gst_vaapi_codec_object_replace (&picture->mbcntrl, NULL); - gst_vaapi_codec_object_replace (&picture->qp, NULL); - gst_vaapi_codec_object_replace (&picture->mbcode, NULL); - gst_vaapi_codec_object_replace (&picture->mv, NULL); - gst_vaapi_codec_object_replace (&picture->dist, NULL); -#endif - gst_vaapi_surface_proxy_replace (&picture->proxy, NULL); picture->surface_id = VA_INVALID_ID; picture->surface = NULL; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index b8302ee815..8037c1842d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -27,10 +27,6 @@ #include #include -#if USE_H264_FEI_ENCODER -#include -#endif - G_BEGIN_DECLS typedef struct _GstVaapiEncPicture GstVaapiEncPicture; @@ -270,14 +266,6 @@ struct _GstVaapiEncPicture guint frame_num; guint poc; guint temporal_id; -#if USE_H264_FEI_ENCODER - GstVaapiEncFeiMbControl *mbcntrl; - GstVaapiEncFeiMvPredictor *mvpred; - GstVaapiEncFeiQp *qp; - GstVaapiEncFeiMbCode *mbcode; - GstVaapiEncFeiMv *mv; - GstVaapiEncFeiDistortion *dist; -#endif }; G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 560c7af53d..0de0bbfafa 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -334,9 +334,6 @@ struct _GstVaapiEncoderClass GstVaapiEncoderStatus (*get_codec_data) (GstVaapiEncoder * encoder, GstBuffer ** codec_data); - /* To create a secondary context for a single base encoder */ - gboolean (*ensure_secondary_context) (GstVaapiEncoder * encoder); - /* Iterator that retrieves the pending pictures in the reordered * list */ gboolean (*get_pending_reordered) (GstVaapiEncoder * encoder, diff --git a/gst-libs/gst/vaapi/gstvaapifei_objects.c b/gst-libs/gst/vaapi/gstvaapifei_objects.c deleted file mode 100644 index fe71dcfb44..0000000000 --- a/gst-libs/gst/vaapi/gstvaapifei_objects.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * gstvaapifei_objects.c - VA FEI objects abstraction - * - * Copyright (C) 2017-2018 Intel Corporation - * Author: Sreerenj Balachandran - * - * 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_priv.h" -#include "gstvaapicompat.h" -#include "gstvaapiutils.h" -#include "gstvaapifei_objects.h" -#include "gstvaapifei_objects_priv.h" -#define DEBUG 1 -#include "gstvaapidebug.h" - -/* ------------------------------------------------------------------------- */ -/* --- Base Codec Object --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_FEI_CODEC_OBJECT_GET_CLASS(object) \ - gst_vaapi_fei_codec_object_get_class(object) - -const GstVaapiFeiCodecObjectClass * -gst_vaapi_fei_codec_object_get_class (GstVaapiFeiCodecObject * object) -{ - return (const GstVaapiFeiCodecObjectClass *) - GST_VAAPI_MINI_OBJECT_GET_CLASS (object); -} - -static gboolean -gst_vaapi_fei_codec_object_create (GstVaapiFeiCodecObject * object, - const GstVaapiFeiCodecObjectConstructorArgs * args) -{ - const GstVaapiFeiCodecObjectClass *klass; - - g_return_val_if_fail (args->param_size > 0, FALSE); - - if (GST_VAAPI_MINI_OBJECT_FLAG_IS_SET (object, - GST_VAAPI_FEI_CODEC_OBJECT_FLAG_CONSTRUCTED)) - return TRUE; - - klass = GST_VAAPI_FEI_CODEC_OBJECT_GET_CLASS (object); - if (!klass->create || !klass->create (object, args)) - return FALSE; - - GST_VAAPI_MINI_OBJECT_FLAG_SET (object, - GST_VAAPI_FEI_CODEC_OBJECT_FLAG_CONSTRUCTED); - return TRUE; -} - -GstVaapiFeiCodecObject * -gst_vaapi_fei_codec_object_new (const GstVaapiFeiCodecObjectClass * - object_class, GstVaapiFeiCodecBase * codec, gconstpointer param, - guint param_size, gconstpointer data, guint data_size, guint flags) -{ - GstVaapiFeiCodecObject *obj; - GstVaapiFeiCodecObjectConstructorArgs args; - - obj = (GstVaapiFeiCodecObject *) - gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS (object_class)); - if (!obj) - return NULL; - - obj = GST_VAAPI_FEI_CODEC_OBJECT (obj); - obj->codec = codec; - - args.param = param; - args.param_size = param_size; - args.data = data; - args.data_size = data_size; - args.flags = flags; - - if (gst_vaapi_fei_codec_object_create (obj, &args)) - return obj; - - gst_vaapi_fei_codec_object_unref (obj); - return NULL; -} - -GstVaapiFeiCodecObject * -gst_vaapi_fei_codec_object_ref (GstVaapiFeiCodecObject * object) -{ - return ((GstVaapiFeiCodecObject *) - gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (object))); -} - -void -gst_vaapi_fei_codec_object_unref (GstVaapiFeiCodecObject * object) -{ - gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (object)); -} - -void -gst_vaapi_fei_codec_object_replace (GstVaapiFeiCodecObject ** old_object_ptr, - GstVaapiFeiCodecObject * new_object) -{ - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_object_ptr), - GST_VAAPI_MINI_OBJECT (new_object)); -} - -/* FeiFixme: map_unlocked and map_lock could be needed */ -gboolean -gst_vaapi_fei_codec_object_map (GstVaapiFeiCodecObject * object, - gpointer * data, guint * size) -{ - g_return_val_if_fail (object != NULL, FALSE); - - /*FeiFixme: explicit map if not yet mapped */ - *data = object->param; - *size = object->param_size; - - return TRUE; -} - -void -gst_vaapi_fei_codec_object_unmap (GstVaapiFeiCodecObject * object) -{ - g_return_if_fail (object != NULL); - vaapi_unmap_buffer (GST_VAAPI_ENCODER_CAST (object->codec)->va_display, - object->param_id, &object->param); -} - -#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 - -/* ------------------------------------------------------------------------- */ -/* --- FEI Mb Code buffer --- */ -/* ------------------------------------------------------------------------- */ - -GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMbCode, - gst_vaapi_enc_fei_mb_code); - -void -gst_vaapi_enc_fei_mb_code_destroy (GstVaapiEncFeiMbCode * fei_mb_code) -{ - GstVaapiFeiCodecObject *object = &fei_mb_code->parent_instance; - vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mb_code), &object->param_id); - object->param = NULL; -} - -gboolean -gst_vaapi_enc_fei_mb_code_create (GstVaapiEncFeiMbCode * - fei_mb_code, const GstVaapiFeiCodecObjectConstructorArgs * args) -{ - GstVaapiFeiCodecObject *object = &fei_mb_code->parent_instance; - object->param_id = VA_INVALID_ID; - return vaapi_create_buffer (GET_VA_DISPLAY (fei_mb_code), - GET_VA_CONTEXT (fei_mb_code), - (VABufferType) VAEncFEIMBCodeBufferType, args->param_size, - args->param, &object->param_id, &object->param); -} - -GstVaapiEncFeiMbCode * -gst_vaapi_enc_fei_mb_code_new (GstVaapiEncoder * encoder, - gconstpointer param, guint param_size) -{ - GstVaapiFeiCodecObject *object; - - object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMbCodeClass, - GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); - if (!object) - return NULL; - object->param_size = param_size; - return GST_VAAPI_ENC_FEI_MB_CODE_CAST (object); -} - -/* ------------------------------------------------------------------------- */ -/* --- FEI MV buffer --- */ -/* ------------------------------------------------------------------------- */ - -GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMv, gst_vaapi_enc_fei_mv); - -void -gst_vaapi_enc_fei_mv_destroy (GstVaapiEncFeiMv * fei_mv) -{ - GstVaapiFeiCodecObject *object = &fei_mv->parent_instance; - vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mv), &object->param_id); - object->param = NULL; -} - -gboolean -gst_vaapi_enc_fei_mv_create (GstVaapiEncFeiMv * - fei_mv, const GstVaapiFeiCodecObjectConstructorArgs * args) -{ - GstVaapiFeiCodecObject *object = &fei_mv->parent_instance; - object->param_id = VA_INVALID_ID; - return vaapi_create_buffer (GET_VA_DISPLAY (fei_mv), - GET_VA_CONTEXT (fei_mv), - (VABufferType) VAEncFEIMVBufferType, args->param_size, - args->param, &object->param_id, &object->param); -} - -GstVaapiEncFeiMv * -gst_vaapi_enc_fei_mv_new (GstVaapiEncoder * encoder, - gconstpointer param, guint param_size) -{ - GstVaapiFeiCodecObject *object; - - object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMvClass, - GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); - if (!object) - return NULL; - object->param_size = param_size; - return GST_VAAPI_ENC_FEI_NEW_MV_CAST (object); -} - -/* ------------------------------------------------------------------------- */ -/* --- FEI Mv predictor buffer --- */ -/* ------------------------------------------------------------------------- */ - -GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMvPredictor, - gst_vaapi_enc_fei_mv_predictor); - -void -gst_vaapi_enc_fei_mv_predictor_destroy (GstVaapiEncFeiMvPredictor * - fei_mv_predictor) -{ - GstVaapiFeiCodecObject *object = &fei_mv_predictor->parent_instance; - vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mv_predictor), &object->param_id); - object->param = NULL; -} - -gboolean -gst_vaapi_enc_fei_mv_predictor_create (GstVaapiEncFeiMvPredictor * - fei_mv_predictor, const GstVaapiFeiCodecObjectConstructorArgs * args) -{ - GstVaapiFeiCodecObject *object = &fei_mv_predictor->parent_instance; - object->param_id = VA_INVALID_ID; - return vaapi_create_buffer (GET_VA_DISPLAY (fei_mv_predictor), - GET_VA_CONTEXT (fei_mv_predictor), - (VABufferType) VAEncFEIMVPredictorBufferType, args->param_size, - args->param, &object->param_id, &object->param); -} - -GstVaapiEncFeiMvPredictor * -gst_vaapi_enc_fei_mv_predictor_new (GstVaapiEncoder * encoder, - gconstpointer param, guint param_size) -{ - GstVaapiFeiCodecObject *object; - - object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMvPredictorClass, - GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); - if (!object) - return NULL; - object->param_size = param_size; - return GST_VAAPI_ENC_FEI_NEW_MV_PREDICTOR_CAST (object); -} - -/* ------------------------------------------------------------------------- */ -/* --- FEI Mb Control buffer --- */ -/* ------------------------------------------------------------------------- */ - -GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiMbControl, - gst_vaapi_enc_fei_mb_control); - -void -gst_vaapi_enc_fei_mb_control_destroy (GstVaapiEncFeiMbControl * fei_mb_control) -{ - GstVaapiFeiCodecObject *object = &fei_mb_control->parent_instance; - vaapi_destroy_buffer (GET_VA_DISPLAY (fei_mb_control), &object->param_id); - object->param = NULL; -} - -gboolean -gst_vaapi_enc_fei_mb_control_create (GstVaapiEncFeiMbControl * - fei_mb_control, const GstVaapiFeiCodecObjectConstructorArgs * args) -{ - GstVaapiFeiCodecObject *object = &fei_mb_control->parent_instance; - object->param_id = VA_INVALID_ID; - return vaapi_create_buffer (GET_VA_DISPLAY (fei_mb_control), - GET_VA_CONTEXT (fei_mb_control), - (VABufferType) VAEncFEIMBControlBufferType, args->param_size, - args->param, &object->param_id, &object->param); -} - -GstVaapiEncFeiMbControl * -gst_vaapi_enc_fei_mb_control_new (GstVaapiEncoder * encoder, - gconstpointer param, guint param_size) -{ - GstVaapiFeiCodecObject *object; - - object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiMbControlClass, - GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); - if (!object) - return NULL; - object->param_size = param_size; - return GST_VAAPI_ENC_FEI_NEW_MB_CONTROL_CAST (object); -} - -/* ------------------------------------------------------------------------- */ -/* --- FEI qp buffer --- */ -/* ------------------------------------------------------------------------- */ - -GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiQp, gst_vaapi_enc_fei_qp); - -void -gst_vaapi_enc_fei_qp_destroy (GstVaapiEncFeiQp * fei_qp) -{ - GstVaapiFeiCodecObject *object = &fei_qp->parent_instance; - vaapi_destroy_buffer (GET_VA_DISPLAY (fei_qp), &object->param_id); - object->param = NULL; -} - -gboolean -gst_vaapi_enc_fei_qp_create (GstVaapiEncFeiQp * fei_qp, - const GstVaapiFeiCodecObjectConstructorArgs * args) -{ - GstVaapiFeiCodecObject *object = &fei_qp->parent_instance; - object->param_id = VA_INVALID_ID; - return vaapi_create_buffer (GET_VA_DISPLAY (fei_qp), - GET_VA_CONTEXT (fei_qp), - (VABufferType) VAEncQPBufferType, args->param_size, - args->param, &object->param_id, &object->param); -} - -GstVaapiEncFeiQp * -gst_vaapi_enc_fei_qp_new (GstVaapiEncoder * encoder, - gconstpointer param, guint param_size) -{ - GstVaapiFeiCodecObject *object; - - object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiQpClass, - GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); - if (!object) - return NULL; - object->param_size = param_size; - return GST_VAAPI_ENC_FEI_NEW_QP_CAST (object); -} - -/* ------------------------------------------------------------------------- */ -/* --- FEI Distortion buffer --- */ -/* ------------------------------------------------------------------------- */ - -GST_VAAPI_FEI_CODEC_DEFINE_TYPE (GstVaapiEncFeiDistortion, - gst_vaapi_enc_fei_distortion); - -void -gst_vaapi_enc_fei_distortion_destroy (GstVaapiEncFeiDistortion * fei_dist) -{ - GstVaapiFeiCodecObject *object = &fei_dist->parent_instance; - vaapi_destroy_buffer (GET_VA_DISPLAY (fei_dist), &object->param_id); - object->param = NULL; -} - -gboolean -gst_vaapi_enc_fei_distortion_create (GstVaapiEncFeiDistortion * fei_dist, - const GstVaapiFeiCodecObjectConstructorArgs * args) -{ - GstVaapiFeiCodecObject *object = &fei_dist->parent_instance; - object->param_id = VA_INVALID_ID; - return vaapi_create_buffer (GET_VA_DISPLAY (fei_dist), - GET_VA_CONTEXT (fei_dist), - (VABufferType) VAEncFEIDistortionBufferType, args->param_size, - args->param, &object->param_id, &object->param); -} - -GstVaapiEncFeiDistortion * -gst_vaapi_enc_fei_distortion_new (GstVaapiEncoder * encoder, - gconstpointer param, guint param_size) -{ - GstVaapiFeiCodecObject *object; - - object = gst_vaapi_fei_codec_object_new (&GstVaapiEncFeiDistortionClass, - GST_VAAPI_FEI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0); - if (!object) - return NULL; - object->param_size = param_size; - return GST_VAAPI_ENC_FEI_NEW_DISTORTION_CAST (object); -} diff --git a/gst-libs/gst/vaapi/gstvaapifei_objects.h b/gst-libs/gst/vaapi/gstvaapifei_objects.h deleted file mode 100644 index 03aef3da63..0000000000 --- a/gst-libs/gst/vaapi/gstvaapifei_objects.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * gstvaapifei_objects.h - VA FEI objects abstraction - * - * Copyright (C) 2017-2018 Intel Corporation - * Author: Sreerenj Balachandran - * - * 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_FEI_OBJECTS_H -#define GST_VAAPI_FEI_OBJECTS_H - -G_BEGIN_DECLS - -#define GST_VAAPI_FEI_CODEC_OBJECT(obj) \ - ((GstVaapiFeiCodecObject *) (obj)) - -typedef struct _GstVaapiFeiCodecObject GstVaapiFeiCodecObject; - -typedef struct _GstVaapiEncFeiMbCode GstVaapiEncFeiMbCode; -typedef struct _GstVaapiEncFeiMv GstVaapiEncFeiMv; -typedef struct _GstVaapiEncFeiMvPredictor GstVaapiEncFeiMvPredictor; -typedef struct _GstVaapiEncFeiMbControl GstVaapiEncFeiMbControl; -typedef struct _GstVaapiEncFeiQp GstVaapiEncFeiQp; -typedef struct _GstVaapiEncFeiDistortion GstVaapiEncFeiDistortion; - -struct _GstVaapiEncoder; - -/* ----------------- Base Codec Object ---------------------------- */ -/* ------------------------------------------------------------------------- */ - -GstVaapiFeiCodecObject * -gst_vaapi_fei_codec_object_ref (GstVaapiFeiCodecObject *object); - -void -gst_vaapi_fei_codec_object_unref (GstVaapiFeiCodecObject *object); - -void -gst_vaapi_fei_codec_object_replace (GstVaapiFeiCodecObject **old_object_ptr, - GstVaapiFeiCodecObject *new_object); - -gboolean -gst_vaapi_fei_codec_object_map (GstVaapiFeiCodecObject *object, - gpointer *data, guint *size); - -void -gst_vaapi_fei_codec_object_unmap (GstVaapiFeiCodecObject *object); - -/* ------------------------------------------------------------------------- */ -/* --- MB Code buffer --- */ -/* ------------------------------------------------------------------------- */ - -GstVaapiEncFeiMbCode * -gst_vaapi_enc_fei_mb_code_new (struct _GstVaapiEncoder * encoder, gconstpointer param, - guint param_size); - -/* ------------------------------------------------------------------------- */ -/* --- MV Buffer --- */ -/* ------------------------------------------------------------------------- */ - -GstVaapiEncFeiMv * -gst_vaapi_enc_fei_mv_new (struct _GstVaapiEncoder * encoder, gconstpointer param, - guint param_size); - -/* ------------------------------------------------------------------------- */ -/* --- MV Predictor Buffer --- */ -/* ------------------------------------------------------------------------- */ - -GstVaapiEncFeiMvPredictor * -gst_vaapi_enc_fei_mv_predictor_new (struct _GstVaapiEncoder * encoder, gconstpointer param, - guint param_size); - -/* ------------------------------------------------------------------------- */ -/* --- MB Control Buffer --- */ -/* ------------------------------------------------------------------------- */ - -GstVaapiEncFeiMbControl * -gst_vaapi_enc_fei_mb_control_new (struct _GstVaapiEncoder * encoder, gconstpointer param, - guint param_size); - -/* ------------------------------------------------------------------------- */ -/* --- QP Buffer --- */ -/* ------------------------------------------------------------------------- */ - -GstVaapiEncFeiQp * -gst_vaapi_enc_fei_qp_new (struct _GstVaapiEncoder * encoder, gconstpointer param, - guint param_size); - -/* ------------------------------------------------------------------------- */ -/* --- Distortion Buffer --- */ -/* ------------------------------------------------------------------------- */ - -GstVaapiEncFeiDistortion * -gst_vaapi_enc_fei_distortion_new (struct _GstVaapiEncoder * encoder, gconstpointer param, - guint param_size); - -G_END_DECLS - -#endif /* GST_VAAPI_FEI_OBJECTS_H */ diff --git a/gst-libs/gst/vaapi/gstvaapifei_objects_priv.h b/gst-libs/gst/vaapi/gstvaapifei_objects_priv.h deleted file mode 100644 index 87978775fa..0000000000 --- a/gst-libs/gst/vaapi/gstvaapifei_objects_priv.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * gstvaapifei_objects_priv.h - VA FEI objects abstraction (priv definitions) - * - * Copyright (C) 2017-2018 Intel Corporation - * Author: Sreerenj Balachandran - * - * 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_FEI_OBJECTS_PRIV_H -#define GST_VAAPI_FEI_OBJECTS_PRIV_H - -#include -#include -#include -#include -G_BEGIN_DECLS - -typedef gpointer GstVaapiFeiCodecBase; -typedef struct _GstVaapiFeiCodecObjectClass GstVaapiFeiCodecObjectClass; - -#define GST_VAAPI_FEI_CODEC_BASE(obj) \ - ((GstVaapiFeiCodecBase *) (obj)) - -enum -{ - GST_VAAPI_FEI_CODEC_OBJECT_FLAG_CONSTRUCTED = (1 << 0), - GST_VAAPI_FEI_CODEC_OBJECT_FLAG_LAST = (1 << 1) -}; - -typedef struct -{ - gconstpointer param; - guint param_size; - gconstpointer data; - guint data_size; - guint flags; -} GstVaapiFeiCodecObjectConstructorArgs; - -typedef gboolean -(*GstVaapiFeiCodecObjectCreateFunc)(GstVaapiFeiCodecObject * object, - const GstVaapiFeiCodecObjectConstructorArgs * args); - -typedef GDestroyNotify GstVaapiFeiCodecObjectDestroyFunc; - -/** - * GstVaapiFeiCodecObject: - * - * A #GstVaapiMiniObject holding the base codec object data - */ -struct _GstVaapiFeiCodecObject -{ - /*< private >*/ - GstVaapiMiniObject parent_instance; - GstVaapiFeiCodecBase *codec; - VABufferID param_id; - gpointer param; - guint param_size; -}; - -/** - * GstVaapiFeiCodecObjectClass: - * - * The #GstVaapiFeiCodecObject base class. - */ -struct _GstVaapiFeiCodecObjectClass -{ - /*< private >*/ - GstVaapiMiniObjectClass parent_class; - - GstVaapiFeiCodecObjectCreateFunc create; -}; - -G_GNUC_INTERNAL -const GstVaapiFeiCodecObjectClass * -gst_vaapi_fei_codec_object_get_class (GstVaapiFeiCodecObject * object) G_GNUC_CONST; - -G_GNUC_INTERNAL -GstVaapiFeiCodecObject * -gst_vaapi_fei_codec_object_new (const GstVaapiFeiCodecObjectClass * object_class, - GstVaapiFeiCodecBase * codec, gconstpointer param, guint param_size, - gconstpointer data, guint data_size, guint flags); - - -/* ------------------------------------------------------------------------- */ -/* --- MB Code Buffer --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_ENC_FEI_MB_CODE_CAST(obj) \ - ((GstVaapiEncFeiMbCode *) (obj)) -/** - * GstVaapiEncFeiMbCode: - * - * A #GstVaapiFeiCodecObject holding a mb code buffer. - */ -struct _GstVaapiEncFeiMbCode -{ - /*< private >*/ - GstVaapiFeiCodecObject parent_instance; -}; - -/* ------------------------------------------------------------------------- */ -/* --- MV Buffer --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_ENC_FEI_NEW_MV_CAST(obj) \ - ((GstVaapiEncFeiMv *) (obj)) -/** - * GstVaapiEncFeiMv: - * - * A #GstVaapiFeiCodecObject holding a mv buffer. - */ -struct _GstVaapiEncFeiMv -{ - /*< private >*/ - GstVaapiFeiCodecObject parent_instance; -}; - -/* ------------------------------------------------------------------------- */ -/* --- MV Predictor Buffer --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_ENC_FEI_NEW_MV_PREDICTOR_CAST(obj) \ - ((GstVaapiEncFeiMvPredictor *) (obj)) -/** - * GstVaapiEncFeiMvPredictor: - * - * A #GstVaapiFeiCodecObject holding a mv predictor buffer. - */ -struct _GstVaapiEncFeiMvPredictor -{ - /*< private >*/ - GstVaapiFeiCodecObject parent_instance; -}; - - -/* ------------------------------------------------------------------------- */ -/* --- MB Control Buffer --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_ENC_FEI_NEW_MB_CONTROL_CAST(obj) \ - ((GstVaapiEncFeiMbControl *) (obj)) -/** - * GstVaapiEncFeiMbControl: - * - * A #GstVaapiFeiCodecObject holding a mb control buffer. - */ -struct _GstVaapiEncFeiMbControl -{ - /*< private >*/ - GstVaapiFeiCodecObject parent_instance; -}; - - -/* ------------------------------------------------------------------------- */ -/* --- QP Buffer --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_ENC_FEI_NEW_QP_CAST(obj) \ - ((GstVaapiEncFeiQp *) (obj)) -/** - * GstVaapiEncFeiQp: - * - * A #GstVaapiFeiCodecObject holding a qp buffer. - */ -struct _GstVaapiEncFeiQp -{ - /*< private >*/ - GstVaapiFeiCodecObject parent_instance; -}; - - -/* ------------------------------------------------------------------------- */ -/* --- Distortion Buffer --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_ENC_FEI_NEW_DISTORTION_CAST(obj) \ - ((GstVaapiEncFeiDistortion *) (obj)) -/** - * GstVaapiEncFeiDistortion: - * - * A #GstVaapiFeiCodecObject holding a distortion buffer. - */ -struct _GstVaapiEncFeiDistortion -{ - /*< private >*/ - GstVaapiFeiCodecObject parent_instance; -}; - - -/* ------------------------------------------------------------------------- */ -/* --- Helpers to create fei objects --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_FEI_CODEC_DEFINE_TYPE(type, prefix) \ -G_GNUC_INTERNAL \ -void \ -G_PASTE (prefix, _destroy) (type *); \ - \ -G_GNUC_INTERNAL \ -gboolean \ -G_PASTE (prefix, _create) (type *, \ - const GstVaapiFeiCodecObjectConstructorArgs * args); \ - \ -static const GstVaapiFeiCodecObjectClass G_PASTE (type, Class) = { \ - .parent_class = { \ - .size = sizeof (type), \ - .finalize = (GstVaapiFeiCodecObjectDestroyFunc) \ - G_PASTE (prefix, _destroy) \ - }, \ - .create = (GstVaapiFeiCodecObjectCreateFunc) \ - G_PASTE (prefix, _create), \ -} - -/* GstVaapiEncFeiMiscParam */ -#define GST_VAAPI_ENC_FEI_MISC_PARAM_NEW(codec, encoder) \ - gst_vaapi_enc_misc_param_new (GST_VAAPI_ENCODER_CAST (encoder), \ - VAEncMiscParameterTypeFEIFrameControl, \ - sizeof (G_PASTE (VAEncMiscParameterFEIFrameControl, codec))) - -G_END_DECLS - -#endif /* GST_VAAPI_FEI_OBJECTS_H */ diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c b/gst-libs/gst/vaapi/gstvaapifeienc_h264.c deleted file mode 100644 index 60f08c412b..0000000000 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.c +++ /dev/null @@ -1,2452 +0,0 @@ -/* - * gstvaapifeienc_h264.c - H264 FEI ENC - * - * Copyright (C) 2016-2018 Intel Corporation - * Author: Leilei Shang - * Author: Sreerenj Balachandran - * - * 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 - */ - -/* GValueArray has deprecated without providing an alternative in glib >= 2.32 - * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 - */ - -#define GLIB_DISABLE_DEPRECATION_WARNINGS - -#include "sysdeps.h" -#include -#include -#include -#include "gstvaapicompat.h" -#include "gstvaapiencoder_priv.h" -#include "gstvaapifeienc_h264.h" -#include "gstvaapiutils_h264_priv.h" -#include "gstvaapicodedbufferproxy_priv.h" -#include "gstvaapisurfaceproxy_priv.h" -#include "gstvaapisurface.h" -#include "gstvaapiutils.h" -#include -#define DEBUG 1 -#include "gstvaapidebug.h" - -/* Define the maximum number of views supported */ -#define MAX_NUM_VIEWS 10 - -/* Define the maximum value for view-id */ -#define MAX_VIEW_ID 1023 - -/* Default CPB length (in milliseconds) */ -#define DEFAULT_CPB_LENGTH 1500 - -/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */ -#define SX_CPB_SIZE 4 - -/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ -#define SX_BITRATE 6 - -/* 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) | \ - GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) - -/* Supported set of tuning options, within this implementation */ -#define SUPPORTED_TUNE_OPTIONS \ - (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \ - GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION) | \ - 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 - -typedef struct -{ - GstVaapiSurfaceProxy *pic; - guint poc; - guint frame_num; -} GstVaapiFeiEncH264Ref; - -typedef enum -{ - GST_VAAPI_ENC_H264_REORD_NONE = 0, - GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1, - GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2 -} GstVaapiEncH264ReorderState; - -typedef struct _GstVaapiH264ViewRefPool -{ - GQueue ref_list; - guint max_ref_frames; - guint max_reflist0_count; - guint max_reflist1_count; -} GstVaapiH264ViewRefPool; - -typedef struct _GstVaapiH264ViewReorderPool -{ - GQueue reorder_frame_list; - guint reorder_state; - guint frame_index; - guint frame_count; /* monotonically increasing with in every idr period */ - guint cur_frame_num; - guint cur_present_index; -} GstVaapiH264ViewReorderPool; - -static inline gboolean -_poc_greater_than (guint poc1, guint poc2, guint max_poc) -{ - return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2); -} - -/* Get slice_type value for H.264 specification */ -static guint8 -h264_get_slice_type (GstVaapiPictureType type) -{ - switch (type) { - case GST_VAAPI_PICTURE_TYPE_I: - return GST_H264_I_SLICE; - case GST_VAAPI_PICTURE_TYPE_P: - return GST_H264_P_SLICE; - case GST_VAAPI_PICTURE_TYPE_B: - return GST_H264_B_SLICE; - default: - break; - } - return -1; -} - -/* Get log2_max_frame_num value for H.264 specification */ -static guint -h264_get_log2_max_frame_num (guint num) -{ - guint ret = 0; - - while (num) { - ++ret; - num >>= 1; - } - if (ret <= 4) - ret = 4; - else if (ret > 10) - ret = 10; - /* must be greater than 4 */ - return ret; -} - -/* Determines the cpbBrNalFactor based on the supplied profile */ -static guint -h264_get_cpb_nal_factor (GstVaapiProfile profile) -{ - guint f; - - /* Table A-2 */ - switch (profile) { - case GST_VAAPI_PROFILE_H264_HIGH: - f = 1500; - break; - case GST_VAAPI_PROFILE_H264_HIGH10: - f = 3600; - break; - case GST_VAAPI_PROFILE_H264_HIGH_422: - case GST_VAAPI_PROFILE_H264_HIGH_444: - f = 4800; - break; - case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH: - case GST_VAAPI_PROFILE_H264_STEREO_HIGH: - f = 1500; /* H.10.2.1 (r) */ - break; - default: - f = 1200; - break; - } - return f; -} - -/* ------------------------------------------------------------------------- */ -/* --- FEI Enc --- */ -/* ------------------------------------------------------------------------- */ - -#define GST_VAAPI_FEI_ENC_H264_CAST(feienc) \ - ((GstVaapiFeiEncH264 *)(feienc)) - -struct _GstVaapiFeiEncH264 -{ - GstVaapiEncoder parent_instance; - - GstVaapiProfile profile; - GstVaapiLevelH264 level; - GstVaapiEntrypoint entrypoint; - guint8 profile_idc; - guint8 max_profile_idc; - guint8 hw_max_profile_idc; - guint8 level_idc; - guint32 idr_period; - guint32 init_qp; - guint32 min_qp; - guint32 num_slices; - guint32 num_bframes; - guint32 mb_width; - guint32 mb_height; - gboolean use_cabac; - gboolean use_dct8x8; - GstClockTime cts_offset; - gboolean config_changed; - - /* frame, poc */ - guint32 max_frame_num; - guint32 log2_max_frame_num; - guint32 max_pic_order_cnt; - guint32 log2_max_pic_order_cnt; - guint32 idr_num; - guint8 pic_order_cnt_type; - guint8 delta_pic_order_always_zero_flag; - - GstBuffer *sps_data; - GstBuffer *subset_sps_data; - GstBuffer *pps_data; - - guint bitrate_bits; // bitrate (bits) - guint cpb_length; // length of CPB buffer (ms) - guint cpb_length_bits; // length of CPB buffer (bits) - guint32 num_ref_frames; // set reference frame num - - /* MVC */ - gboolean is_mvc; - guint32 view_idx; /* View Order Index (VOIdx) */ - guint32 num_views; - guint16 view_ids[MAX_NUM_VIEWS]; - GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS]; - GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS]; - - /*Fei frame level control */ - guint search_window; - guint len_sp; - guint search_path; - guint ref_width; - guint ref_height; - guint submb_part_mask; - guint subpel_mode; - guint intra_part_mask; - guint intra_sad; - guint inter_sad; - guint num_mv_predictors_l0; - guint num_mv_predictors_l1; - guint adaptive_search; - guint multi_predL0; - guint multi_predL1; -}; - -/* Determines the largest supported profile by the underlying hardware */ -static gboolean -ensure_hw_profile_limits (GstVaapiFeiEncH264 * feienc) -{ - GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (feienc); - GArray *profiles; - guint i, profile_idc, max_profile_idc; - - if (feienc->hw_max_profile_idc) - return TRUE; - - profiles = gst_vaapi_display_get_encode_profiles (display); - if (!profiles) - return FALSE; - - max_profile_idc = 0; - for (i = 0; i < profiles->len; i++) { - const GstVaapiProfile profile = - g_array_index (profiles, GstVaapiProfile, i); - profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); - if (!profile_idc) - continue; - if (max_profile_idc < profile_idc) - max_profile_idc = profile_idc; - } - g_array_unref (profiles); - - feienc->hw_max_profile_idc = max_profile_idc; - return TRUE; -} - -/* Derives the profile supported by the underlying hardware */ -static gboolean -ensure_hw_profile (GstVaapiFeiEncH264 * feienc) -{ - GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (feienc); - GstVaapiEntrypoint entrypoint = feienc->entrypoint; - GstVaapiProfile profile, profiles[4]; - guint i, num_profiles = 0; - - profiles[num_profiles++] = feienc->profile; - switch (feienc->profile) { - case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE: - profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE; - profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN; - // fall-through - case GST_VAAPI_PROFILE_H264_MAIN: - profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH; - break; - default: - break; - } - - 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 (feienc)->profile = profile; - return TRUE; - - /* ERRORS */ -error_unsupported_profile: - { - GST_ERROR ("unsupported HW profile (0x%08x)", feienc->profile); - return FALSE; - } -} - -/* Check target decoder constraints */ -static gboolean -ensure_profile_limits (GstVaapiFeiEncH264 * feienc) -{ - GstVaapiProfile profile; - - if (!feienc->max_profile_idc - || feienc->profile_idc <= feienc->max_profile_idc) - return TRUE; - - GST_WARNING ("lowering coding tools to meet target decoder constraints"); - - profile = GST_VAAPI_PROFILE_UNKNOWN; - - /* Try Main profile coding tools */ - if (feienc->max_profile_idc < 100) { - feienc->use_dct8x8 = FALSE; - profile = GST_VAAPI_PROFILE_H264_MAIN; - } - - /* Try Constrained Baseline profile coding tools */ - if (feienc->max_profile_idc < 77) { - feienc->num_bframes = 0; - feienc->use_cabac = FALSE; - profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; - } - - if (profile) { - feienc->profile = profile; - feienc->profile_idc = feienc->max_profile_idc; - } - return TRUE; -} - -/* Derives the minimum profile from the active coding tools */ -static gboolean -ensure_profile (GstVaapiFeiEncH264 * feienc) -{ - GstVaapiProfile profile; - - /* Always start from "constrained-baseline" profile for maximum - compatibility */ - profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; - - /* Main profile coding tools */ - if (feienc->num_bframes > 0 || feienc->use_cabac) - profile = GST_VAAPI_PROFILE_H264_MAIN; - - /* High profile coding tools */ - if (feienc->use_dct8x8) - profile = GST_VAAPI_PROFILE_H264_HIGH; - - /* MVC profiles coding tools */ - if (feienc->num_views == 2) - profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH; - else if (feienc->num_views > 2) - profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH; - - feienc->profile = profile; - feienc->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); - return TRUE; -} - -/* Derives the level from the currently set limits */ -static gboolean -ensure_level (GstVaapiFeiEncH264 * feienc) -{ - const guint cpb_factor = h264_get_cpb_nal_factor (feienc->profile); - const GstVaapiH264LevelLimits *limits_table; - guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS; - - PicSizeMbs = feienc->mb_width * feienc->mb_height; - MaxDpbMbs = PicSizeMbs * ((feienc->num_bframes) ? 2 : 1); - MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs, - GST_VAAPI_ENCODER_FPS_N (feienc), GST_VAAPI_ENCODER_FPS_D (feienc)); - - limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits); - for (i = 0; i < num_limits; i++) { - const GstVaapiH264LevelLimits *const limits = &limits_table[i]; - if (PicSizeMbs <= limits->MaxFS && - MaxDpbMbs <= limits->MaxDpbMbs && - MaxMBPS <= limits->MaxMBPS && (!feienc->bitrate_bits - || feienc->bitrate_bits <= (limits->MaxBR * cpb_factor)) && - (!feienc->cpb_length_bits || - feienc->cpb_length_bits <= (limits->MaxCPB * cpb_factor))) - break; - } - if (i == num_limits) - goto error_unsupported_level; - - feienc->level = limits_table[i].level; - feienc->level_idc = limits_table[i].level_idc; - return TRUE; - - /* ERRORS */ -error_unsupported_level: - { - GST_ERROR ("failed to find a suitable level matching codec config"); - return FALSE; - } -} - -/* Enable "high-compression" tuning options */ -static gboolean -ensure_tuning_high_compression (GstVaapiFeiEncH264 * feienc) -{ - guint8 profile_idc; - - if (!ensure_hw_profile_limits (feienc)) - return FALSE; - - profile_idc = feienc->hw_max_profile_idc; - if (feienc->max_profile_idc && feienc->max_profile_idc < profile_idc) - profile_idc = feienc->max_profile_idc; - - /* Tuning options to enable Main profile */ - if (profile_idc >= 77 && profile_idc != 88) { - feienc->use_cabac = TRUE; - if (!feienc->num_bframes) - feienc->num_bframes = 1; - } - - /* Tuning options to enable High profile */ - if (profile_idc >= 100) { - feienc->use_dct8x8 = TRUE; - } - return TRUE; -} - -/* Ensure tuning options */ -static gboolean -ensure_tuning (GstVaapiFeiEncH264 * feienc) -{ - gboolean success; - - switch (GST_VAAPI_ENCODER_TUNE (feienc)) { - case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: - success = ensure_tuning_high_compression (feienc); - break; - case GST_VAAPI_ENCODER_TUNE_LOW_POWER: - /* Set low-power encode entry point. If hardware doesn't have - * support, it will fail in ensure_hw_profile() in later stage. - * So not duplicating the profile/entrypont query mechanism - * here as a part of optimization */ - feienc->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; - success = TRUE; - break; - default: - success = TRUE; - break; - } - return success; -} - -/* Handle new GOP starts */ -static void -reset_gop_start (GstVaapiFeiEncH264 * feienc) -{ - GstVaapiH264ViewReorderPool *const reorder_pool = - &feienc->reorder_pools[feienc->view_idx]; - - reorder_pool->frame_index = 1; - reorder_pool->cur_frame_num = 0; - reorder_pool->cur_present_index = 0; - ++feienc->idr_num; -} - -/* Marks the supplied picture as a B-frame */ -static void -set_b_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc) -{ - GstVaapiH264ViewReorderPool *const reorder_pool = - &feienc->reorder_pools[feienc->view_idx]; - - g_assert (pic && feienc); - g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); - pic->type = GST_VAAPI_PICTURE_TYPE_B; - pic->frame_num = (reorder_pool->cur_frame_num % feienc->max_frame_num); -} - -/* Marks the supplied picture as a P-frame */ -static void -set_p_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc) -{ - GstVaapiH264ViewReorderPool *const reorder_pool = - &feienc->reorder_pools[feienc->view_idx]; - - g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); - pic->type = GST_VAAPI_PICTURE_TYPE_P; - pic->frame_num = (reorder_pool->cur_frame_num % feienc->max_frame_num); -} - -/* Marks the supplied picture as an I-frame */ -static void -set_i_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc) -{ - GstVaapiH264ViewReorderPool *const reorder_pool = - &feienc->reorder_pools[feienc->view_idx]; - - g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); - pic->type = GST_VAAPI_PICTURE_TYPE_I; - pic->frame_num = (reorder_pool->cur_frame_num % feienc->max_frame_num); - - g_assert (pic->frame); - GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); -} - -/* Marks the supplied picture as an IDR frame */ -static void -set_idr_frame (GstVaapiEncPicture * pic, GstVaapiFeiEncH264 * feienc) -{ - g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE); - pic->type = GST_VAAPI_PICTURE_TYPE_I; - pic->frame_num = 0; - pic->poc = 0; - GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR); - - g_assert (pic->frame); - GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame); -} - -/* Marks the supplied picture a a key-frame */ -static void -set_key_frame (GstVaapiEncPicture * picture, - GstVaapiFeiEncH264 * feienc, gboolean is_idr) -{ - if (is_idr) { - reset_gop_start (feienc); - set_idr_frame (picture, feienc); - } else - set_i_frame (picture, feienc); -} - -/* Fills in VA HRD parameters */ -static void -fill_hrd_params (GstVaapiFeiEncH264 * feienc, VAEncMiscParameterHRD * hrd) -{ - if (feienc->bitrate_bits > 0) { - hrd->buffer_size = feienc->cpb_length_bits; - hrd->initial_buffer_fullness = hrd->buffer_size / 2; - } else { - hrd->buffer_size = 0; - hrd->initial_buffer_fullness = 0; - } -} - -/* Reference list */ -static gboolean -reference_list_init (GstVaapiFeiEncH264 * feienc, - GstVaapiEncPicture * picture, - GstVaapiFeiEncH264Ref ** reflist_0, - guint * reflist_0_count, - GstVaapiFeiEncH264Ref ** reflist_1, guint * reflist_1_count) -{ - GstVaapiFeiEncH264Ref *tmp; - GstVaapiH264ViewRefPool *const ref_pool = - &feienc->ref_pools[feienc->view_idx]; - GList *iter, *list_0_start = NULL, *list_1_start = NULL; - guint count; - - *reflist_0_count = 0; - *reflist_1_count = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_I) - return TRUE; - - iter = g_queue_peek_tail_link (&ref_pool->ref_list); - for (; iter; iter = g_list_previous (iter)) { - tmp = (GstVaapiFeiEncH264Ref *) iter->data; - g_assert (tmp && tmp->poc != picture->poc); - if (_poc_greater_than (picture->poc, tmp->poc, feienc->max_pic_order_cnt)) { - list_0_start = iter; - list_1_start = g_list_next (iter); - break; - } - } - - /* order reflist_0 */ - g_assert (list_0_start); - iter = list_0_start; - count = 0; - for (; iter; iter = g_list_previous (iter)) { - reflist_0[count] = (GstVaapiFeiEncH264Ref *) iter->data; - ++count; - } - *reflist_0_count = count; - - if (picture->type != GST_VAAPI_PICTURE_TYPE_B) - return TRUE; - - /* order reflist_1 */ - count = 0; - iter = list_1_start; - for (; iter; iter = g_list_next (iter)) { - reflist_1[count] = (GstVaapiFeiEncH264Ref *) iter->data; - ++count; - } - *reflist_1_count = count; - return TRUE; -} - -/* Fills in VA sequence parameter buffer */ -static gboolean -fill_sequence (GstVaapiFeiEncH264 * feienc, GstVaapiEncSequence * sequence) -{ - VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; - GstVaapiH264ViewRefPool *const ref_pool = - &feienc->ref_pools[feienc->view_idx]; - - memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264)); - seq_param->seq_parameter_set_id = feienc->view_idx; - seq_param->level_idc = feienc->level_idc; - seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (feienc); - seq_param->intra_idr_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (feienc); - seq_param->ip_period = seq_param->intra_period > 1 ? - (1 + feienc->num_bframes) : 0; - seq_param->bits_per_second = feienc->bitrate_bits; - - seq_param->max_num_ref_frames = ref_pool->max_ref_frames; - seq_param->picture_width_in_mbs = feienc->mb_width; - seq_param->picture_height_in_mbs = feienc->mb_height; - - /*sequence field values */ - seq_param->seq_fields.value = 0; - seq_param->seq_fields.bits.chroma_format_idc = 1; - seq_param->seq_fields.bits.frame_mbs_only_flag = 1; - seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE; - seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE; - /* direct_8x8_inference_flag default false */ - seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE; - g_assert (feienc->log2_max_frame_num >= 4); - seq_param->seq_fields.bits.log2_max_frame_num_minus4 = - feienc->log2_max_frame_num - 4; - /* picture order count */ - feienc->pic_order_cnt_type = seq_param->seq_fields.bits.pic_order_cnt_type = - 0; - g_assert (feienc->log2_max_pic_order_cnt >= 4); - seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = - feienc->log2_max_pic_order_cnt - 4; - - seq_param->bit_depth_luma_minus8 = 0; - seq_param->bit_depth_chroma_minus8 = 0; - - /* not used if pic_order_cnt_type == 0 */ - if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { - feienc->delta_pic_order_always_zero_flag = - seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE; - seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0; - seq_param->offset_for_non_ref_pic = 0; - seq_param->offset_for_top_to_bottom_field = 0; - memset (seq_param->offset_for_ref_frame, 0, - sizeof (seq_param->offset_for_ref_frame)); - } - - /* frame_cropping_flag */ - if ((GST_VAAPI_ENCODER_WIDTH (feienc) & 15) || - (GST_VAAPI_ENCODER_HEIGHT (feienc) & 15)) { - static const guint SubWidthC[] = { 1, 2, 2, 1 }; - static const guint SubHeightC[] = { 1, 2, 1, 1 }; - const guint CropUnitX = - SubWidthC[seq_param->seq_fields.bits.chroma_format_idc]; - const guint CropUnitY = - SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] * - (2 - seq_param->seq_fields.bits.frame_mbs_only_flag); - - seq_param->frame_cropping_flag = 1; - seq_param->frame_crop_left_offset = 0; - seq_param->frame_crop_right_offset = - (16 * feienc->mb_width - GST_VAAPI_ENCODER_WIDTH (feienc)) / CropUnitX; - seq_param->frame_crop_top_offset = 0; - seq_param->frame_crop_bottom_offset = - (16 * feienc->mb_height - - GST_VAAPI_ENCODER_HEIGHT (feienc)) / CropUnitY; - } - - /* VUI parameters are always set, at least for timing_info (framerate) */ - seq_param->vui_parameters_present_flag = TRUE; - if (seq_param->vui_parameters_present_flag) { - seq_param->vui_fields.bits.aspect_ratio_info_present_flag = TRUE; - if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { - const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (feienc); - seq_param->aspect_ratio_idc = 0xff; - seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip); - seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip); - } - seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE; - /* if vui_parameters_present_flag is TRUE and sps data belongs to - * subset sps, timing_info_preset_flag should be zero (H.7.4.2.1.1) */ - seq_param->vui_fields.bits.timing_info_present_flag = !feienc->view_idx; - if (seq_param->vui_fields.bits.timing_info_present_flag) { - seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (feienc); - seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (feienc) * 2; - } - } - - return TRUE; -} - -/* Fills in VA picture parameter buffer */ -static gboolean -fill_picture (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, - GstVaapiSurfaceProxy * surface, GstVaapiCodedBuffer * const codedbuf) -{ - VAEncPictureParameterBufferH264 *const pic_param = picture->param; - GstVaapiH264ViewRefPool *const ref_pool = - &feienc->ref_pools[feienc->view_idx]; - GstVaapiFeiEncH264Ref *ref_pic; - GList *reflist; - guint i; - - memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264)); - - /* reference list, */ - pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); - pic_param->CurrPic.TopFieldOrderCnt = picture->poc; - pic_param->CurrPic.frame_idx = picture->frame_num; - i = 0; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { - for (reflist = g_queue_peek_head_link (&ref_pool->ref_list); - reflist; reflist = g_list_next (reflist)) { - ref_pic = reflist->data; - g_assert (ref_pic && ref_pic->pic && - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID); - - pic_param->ReferenceFrames[i].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); - pic_param->ReferenceFrames[i].TopFieldOrderCnt = ref_pic->poc; - pic_param->ReferenceFrames[i].flags |= - VA_PICTURE_H264_SHORT_TERM_REFERENCE; - pic_param->ReferenceFrames[i].frame_idx = ref_pic->frame_num; - ++i; - } - g_assert (i <= 16 && i <= ref_pool->max_ref_frames); - } - for (; i < 16; ++i) { - pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID; - pic_param->ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID; - } - - pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf); - - pic_param->pic_parameter_set_id = feienc->view_idx; - pic_param->seq_parameter_set_id = feienc->view_idx ? 1 : 0; - pic_param->last_picture = 0; /* means last encoding picture */ - pic_param->frame_num = picture->frame_num; - pic_param->pic_init_qp = feienc->init_qp; - pic_param->num_ref_idx_l0_active_minus1 = - (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0); - pic_param->num_ref_idx_l1_active_minus1 = - (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0); - pic_param->chroma_qp_index_offset = 0; - pic_param->second_chroma_qp_index_offset = 0; - - /* set picture fields */ - pic_param->pic_fields.value = 0; - pic_param->pic_fields.bits.idr_pic_flag = - GST_VAAPI_ENC_PICTURE_IS_IDR (picture); - pic_param->pic_fields.bits.reference_pic_flag = - (picture->type != GST_VAAPI_PICTURE_TYPE_B); - pic_param->pic_fields.bits.entropy_coding_mode_flag = feienc->use_cabac; - pic_param->pic_fields.bits.weighted_pred_flag = FALSE; - pic_param->pic_fields.bits.weighted_bipred_idc = 0; - pic_param->pic_fields.bits.constrained_intra_pred_flag = 0; - pic_param->pic_fields.bits.transform_8x8_mode_flag = feienc->use_dct8x8; - /* enable debloking */ - pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; - pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE; - /* bottom_field_pic_order_in_frame_present_flag */ - pic_param->pic_fields.bits.pic_order_present_flag = FALSE; - pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE; - - return TRUE; -} - -/* Adds slice headers to picture */ -static gboolean -add_slice_headers (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, - GstVaapiFeiEncH264Ref ** reflist_0, guint reflist_0_count, - GstVaapiFeiEncH264Ref ** reflist_1, guint reflist_1_count, - GstVaapiFeiInfoToPakH264 * info_to_pak) -{ - VAEncSliceParameterBufferH264 *slice_param; - GstVaapiEncSlice *slice; - GArray *h264_slice_params; - guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs; - guint mb_size; - guint last_mb_index; - guint i_slice, i_ref; - - g_assert (picture); - - mb_size = feienc->mb_width * feienc->mb_height; - - g_assert (feienc->num_slices && feienc->num_slices < mb_size); - slice_of_mbs = mb_size / feienc->num_slices; - slice_mod_mbs = mb_size % feienc->num_slices; - last_mb_index = 0; - h264_slice_params = - g_array_new (FALSE, TRUE, sizeof (VAEncSliceParameterBufferH264)); - for (i_slice = 0; i_slice < feienc->num_slices; ++i_slice) { - cur_slice_mbs = slice_of_mbs; - if (slice_mod_mbs) { - ++cur_slice_mbs; - --slice_mod_mbs; - } - slice = GST_VAAPI_ENC_SLICE_NEW (H264, feienc); - g_assert (slice && slice->param_id != VA_INVALID_ID); - slice_param = slice->param; - - memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264)); - slice_param->macroblock_address = last_mb_index; - slice_param->num_macroblocks = cur_slice_mbs; - slice_param->macroblock_info = VA_INVALID_ID; - slice_param->slice_type = h264_get_slice_type (picture->type); - g_assert ((gint8) slice_param->slice_type != -1); - slice_param->pic_parameter_set_id = feienc->view_idx; - slice_param->idr_pic_id = feienc->idr_num; - slice_param->pic_order_cnt_lsb = picture->poc; - - /* not used if pic_order_cnt_type = 0 */ - slice_param->delta_pic_order_cnt_bottom = 0; - memset (slice_param->delta_pic_order_cnt, 0, - sizeof (slice_param->delta_pic_order_cnt)); - - /* only works for B frames */ - if (slice_param->slice_type == GST_H264_B_SLICE) - slice_param->direct_spatial_mv_pred_flag = TRUE; - /* default equal to picture parameters */ - slice_param->num_ref_idx_active_override_flag = TRUE; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) - slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; - else - slice_param->num_ref_idx_l0_active_minus1 = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0) - slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; - else - slice_param->num_ref_idx_l1_active_minus1 = 0; - g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0); - g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0); - - i_ref = 0; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { - for (; i_ref < reflist_0_count; ++i_ref) { - slice_param->RefPicList0[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); - slice_param->RefPicList0[i_ref].TopFieldOrderCnt = - reflist_0[i_ref]->poc; - slice_param->RefPicList0[i_ref].flags |= - VA_PICTURE_H264_SHORT_TERM_REFERENCE; - slice_param->RefPicList0[i_ref].frame_idx = reflist_0[i_ref]->frame_num; - } - g_assert (i_ref >= 1); - } - for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) { - slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE; - slice_param->RefPicList0[i_ref].flags = VA_PICTURE_H264_INVALID; - } - - i_ref = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { - for (; i_ref < reflist_1_count; ++i_ref) { - slice_param->RefPicList1[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); - slice_param->RefPicList1[i_ref].TopFieldOrderCnt = - reflist_1[i_ref]->poc; - slice_param->RefPicList1[i_ref].flags |= - VA_PICTURE_H264_SHORT_TERM_REFERENCE; - slice_param->RefPicList1[i_ref].frame_idx = reflist_1[i_ref]->frame_num; - } - g_assert (i_ref == 1); - } - for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) { - slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE; - slice_param->RefPicList1[i_ref].flags = VA_PICTURE_H264_INVALID; - } - - /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */ - slice_param->luma_log2_weight_denom = 0; - slice_param->chroma_log2_weight_denom = 0; - slice_param->luma_weight_l0_flag = FALSE; - memset (slice_param->luma_weight_l0, 0, - sizeof (slice_param->luma_weight_l0)); - memset (slice_param->luma_offset_l0, 0, - sizeof (slice_param->luma_offset_l0)); - slice_param->chroma_weight_l0_flag = FALSE; - memset (slice_param->chroma_weight_l0, 0, - sizeof (slice_param->chroma_weight_l0)); - memset (slice_param->chroma_offset_l0, 0, - sizeof (slice_param->chroma_offset_l0)); - slice_param->luma_weight_l1_flag = FALSE; - memset (slice_param->luma_weight_l1, 0, - sizeof (slice_param->luma_weight_l1)); - memset (slice_param->luma_offset_l1, 0, - sizeof (slice_param->luma_offset_l1)); - slice_param->chroma_weight_l1_flag = FALSE; - memset (slice_param->chroma_weight_l1, 0, - sizeof (slice_param->chroma_weight_l1)); - memset (slice_param->chroma_offset_l1, 0, - sizeof (slice_param->chroma_offset_l1)); - - slice_param->cabac_init_idc = 0; - slice_param->slice_qp_delta = feienc->init_qp - feienc->min_qp; - if (slice_param->slice_qp_delta > 4) - slice_param->slice_qp_delta = 4; - slice_param->disable_deblocking_filter_idc = 0; - slice_param->slice_alpha_c0_offset_div2 = 2; - slice_param->slice_beta_offset_div2 = 2; - - /* set calculation for next slice */ - last_mb_index += cur_slice_mbs; - - g_array_append_val (h264_slice_params, *slice_param); - - gst_vaapi_enc_picture_add_slice (picture, slice); - gst_vaapi_codec_object_replace (&slice, NULL); - } - g_assert (last_mb_index == mb_size); - - info_to_pak->h264_slice_headers = h264_slice_params; - - return TRUE; - -} - -/* Generates and submits SPS header accordingly into the bitstream */ -static gboolean -ensure_sequence (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, - GstVaapiFeiInfoToPakH264 * info_to_pak) -{ - GstVaapiEncSequence *sequence = NULL; - VAEncSequenceParameterBufferH264 *seq_param; - - sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, feienc); - if (!sequence || !fill_sequence (feienc, sequence)) - goto error_create_seq_param; - - seq_param = sequence->param; - info_to_pak->h264_enc_sps = *seq_param; - - if (sequence) { - gst_vaapi_enc_picture_set_sequence (picture, sequence); - gst_vaapi_codec_object_replace (&sequence, NULL); - } - - if (!feienc->is_mvc || feienc->view_idx > 0) - feienc->config_changed = FALSE; - return TRUE; - - /* ERRORS */ -error_create_seq_param: - { - GST_ERROR ("failed to create sequence parameter buffer (SPS)"); - gst_vaapi_codec_object_replace (&sequence, NULL); - return FALSE; - } -} - -/* Generates additional fei control parameters */ -static gboolean -ensure_fei_misc_params (GstVaapiFeiEncH264 * feienc, - GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy) -{ - GstVaapiEncMiscParam *misc = NULL; - GstVaapiSurfaceProxy *surface_proxy = picture->proxy; - VAEncMiscParameterFEIFrameControlH264 *misc_fei_pic_control_param; - guint mbcode_size = 0; - guint mv_size = 0; - guint dist_size = 0; - - /*fei pic control params */ - misc = GST_VAAPI_ENC_FEI_MISC_PARAM_NEW (H264, feienc); - g_assert (misc); - if (!misc) - return FALSE; - misc_fei_pic_control_param = misc->data; - surface_proxy = picture->proxy; - - misc_fei_pic_control_param->function = VA_FEI_FUNCTION_ENC; - misc_fei_pic_control_param->search_path = feienc->search_path; - misc_fei_pic_control_param->num_mv_predictors_l0 = - feienc->num_mv_predictors_l0; - misc_fei_pic_control_param->num_mv_predictors_l1 = - feienc->num_mv_predictors_l1; - misc_fei_pic_control_param->len_sp = feienc->len_sp; - misc_fei_pic_control_param->sub_mb_part_mask = feienc->submb_part_mask; - if (!feienc->use_dct8x8) - misc_fei_pic_control_param->intra_part_mask = feienc->intra_part_mask | 2; - misc_fei_pic_control_param->multi_pred_l0 = feienc->multi_predL0; - misc_fei_pic_control_param->multi_pred_l1 = feienc->multi_predL1; - misc_fei_pic_control_param->sub_pel_mode = feienc->subpel_mode; - misc_fei_pic_control_param->inter_sad = feienc->inter_sad; - misc_fei_pic_control_param->intra_sad = feienc->intra_sad; - misc_fei_pic_control_param->distortion_type = 0; - misc_fei_pic_control_param->repartition_check_enable = 0; - misc_fei_pic_control_param->adaptive_search = feienc->adaptive_search; - misc_fei_pic_control_param->mb_size_ctrl = 0; - misc_fei_pic_control_param->ref_width = feienc->ref_width; - misc_fei_pic_control_param->ref_height = feienc->ref_height; - misc_fei_pic_control_param->search_window = feienc->search_window; - - /***** ENC input: mv_predictor *****/ - if (surface_proxy->mvpred) { - misc_fei_pic_control_param->mv_predictor = - GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mvpred)->param_id; - misc_fei_pic_control_param->mv_predictor_enable = TRUE; - gst_vaapi_codec_object_replace (&picture->mvpred, surface_proxy->mvpred); - } else { - misc_fei_pic_control_param->mv_predictor = VA_INVALID_ID; - misc_fei_pic_control_param->mv_predictor_enable = FALSE; - picture->mvpred = NULL; - } - - /***** ENC input: qp ******/ - if (surface_proxy->qp) { - misc_fei_pic_control_param->qp = - GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->qp)->param_id; - misc_fei_pic_control_param->mb_qp = TRUE; - gst_vaapi_codec_object_replace (&picture->qp, surface_proxy->qp); - } else { - misc_fei_pic_control_param->qp = VA_INVALID_ID; - misc_fei_pic_control_param->mb_qp = FALSE; - picture->qp = NULL; - } - /***** ENC input: mb_control ******/ - if (surface_proxy->mbcntrl) { - misc_fei_pic_control_param->mb_ctrl = - GST_VAAPI_FEI_CODEC_OBJECT (surface_proxy->mbcntrl)->param_id; - misc_fei_pic_control_param->mb_input = TRUE; - gst_vaapi_codec_object_replace (&picture->mbcntrl, surface_proxy->mbcntrl); - } else { - misc_fei_pic_control_param->mb_ctrl = VA_INVALID_ID; - misc_fei_pic_control_param->mb_input = FALSE; - picture->mbcntrl = NULL; - } - - mbcode_size = sizeof (VAEncFEIMBCodeH264) * - feienc->mb_width * feienc->mb_height; - mv_size = sizeof (VAMotionVector) * 16 * feienc->mb_width * feienc->mb_height; - dist_size = sizeof (VAEncFEIDistortionH264) * - feienc->mb_width * feienc->mb_height; - /***** ENC_PAK/ENC output: macroblock code buffer *****/ - codedbuf_proxy->mbcode = - gst_vaapi_enc_fei_mb_code_new (GST_VAAPI_ENCODER_CAST (feienc), - NULL, mbcode_size); - misc_fei_pic_control_param->mb_code_data = - GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mbcode)->param_id; - picture->mbcode = gst_vaapi_codec_object_ref (codedbuf_proxy->mbcode); - - /***** ENC_PAK/ENC output: motion vector buffer *****/ - codedbuf_proxy->mv = - gst_vaapi_enc_fei_mv_new (GST_VAAPI_ENCODER_CAST (feienc), NULL, mv_size); - misc_fei_pic_control_param->mv_data = - GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mv)->param_id; - picture->mv = gst_vaapi_codec_object_ref (codedbuf_proxy->mv); - - /* Fixme: a copy needed in coded_buf proxy */ - /***** ENC_PAK/ENC output: distortion buffer *****/ - picture->dist = - gst_vaapi_enc_fei_distortion_new (GST_VAAPI_ENCODER_CAST (feienc), - NULL, dist_size); - misc_fei_pic_control_param->distortion = - GST_VAAPI_FEI_CODEC_OBJECT (picture->dist)->param_id; - codedbuf_proxy->dist = gst_vaapi_codec_object_ref (picture->dist); - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - return TRUE; -} - -/* Generates additional control parameters */ -static gboolean -ensure_misc_params (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture) -{ - GstVaapiEncMiscParam *misc = NULL; - VAEncMiscParameterRateControl *rate_control; - - /* HRD params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, feienc); - g_assert (misc); - if (!misc) - return FALSE; - fill_hrd_params (feienc, misc->data); - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - - /* RateControl params */ - if (GST_VAAPI_ENCODER_RATE_CONTROL (feienc) == GST_VAAPI_RATECONTROL_CBR || - GST_VAAPI_ENCODER_RATE_CONTROL (feienc) == GST_VAAPI_RATECONTROL_VBR) { - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, feienc); - g_assert (misc); - if (!misc) - return FALSE; - rate_control = misc->data; - memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); - rate_control->bits_per_second = feienc->bitrate_bits; - rate_control->target_percentage = 70; - rate_control->window_size = feienc->cpb_length; - rate_control->initial_qp = feienc->init_qp; - rate_control->min_qp = feienc->min_qp; - rate_control->basic_unit_size = 0; - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - - } - return TRUE; - -} - -/* Generates and submits PPS header accordingly into the bitstream */ -static gboolean -ensure_picture (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, - GstVaapiSurfaceProxy * surface, GstVaapiCodedBufferProxy * codedbuf_proxy, - GstVaapiFeiInfoToPakH264 * info_to_pak) -{ - gboolean res = FALSE; - GstVaapiCodedBuffer *const codedbuf = - GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); - VAEncPictureParameterBufferH264 *const pic_param = picture->param; - - res = fill_picture (feienc, picture, surface, codedbuf); - - if (!res) - return FALSE; - - info_to_pak->h264_enc_pps = *pic_param; - - return TRUE; -} - -/* Generates slice headers */ -static gboolean -ensure_slices (GstVaapiFeiEncH264 * feienc, GstVaapiEncPicture * picture, - GstVaapiFeiInfoToPakH264 * info_to_pak) -{ - GstVaapiFeiEncH264Ref *reflist_0[16]; - GstVaapiFeiEncH264Ref *reflist_1[16]; - GstVaapiH264ViewRefPool *const ref_pool = - &feienc->ref_pools[feienc->view_idx]; - guint reflist_0_count = 0, reflist_1_count = 0; - - g_assert (picture); - - if (picture->type != GST_VAAPI_PICTURE_TYPE_I && - !reference_list_init (feienc, picture, - reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) { - GST_ERROR ("reference list reorder failed"); - return FALSE; - } - - g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames); - if (reflist_0_count > ref_pool->max_reflist0_count) - reflist_0_count = ref_pool->max_reflist0_count; - if (reflist_1_count > ref_pool->max_reflist1_count) - reflist_1_count = ref_pool->max_reflist1_count; - - if (!add_slice_headers (feienc, picture, - reflist_0, reflist_0_count, reflist_1, reflist_1_count, info_to_pak)) - return FALSE; - - return TRUE; -} - -/* Normalizes bitrate (and CPB size) for HRD conformance */ -static void -ensure_bitrate_hrd (GstVaapiFeiEncH264 * feienc) -{ - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (feienc); - guint bitrate, cpb_size; - - if (!base_encoder->bitrate) { - feienc->bitrate_bits = 0; - return; - } - - /* Round down bitrate. This is a hard limit mandated by the user */ - g_assert (SX_BITRATE >= 6); - bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1); - if (bitrate != feienc->bitrate_bits) { - GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate); - feienc->bitrate_bits = bitrate; - feienc->config_changed = TRUE; - } - - /* Round up CPB size. This is an HRD compliance detail */ - g_assert (SX_CPB_SIZE >= 4); - cpb_size = gst_util_uint64_scale (bitrate, feienc->cpb_length, 1000) & - ~((1U << SX_CPB_SIZE) - 1); - if (cpb_size != feienc->cpb_length_bits) { - GST_DEBUG ("HRD CPB size: %u bits", cpb_size); - feienc->cpb_length_bits = cpb_size; - feienc->config_changed = TRUE; - } -} - -/* Estimates a good enough bitrate if none was supplied */ -static void -ensure_bitrate (GstVaapiFeiEncH264 * feienc) -{ - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (feienc); - - /* Default compression: 48 bits per macroblock in "high-compression" mode */ - switch (GST_VAAPI_ENCODER_RATE_CONTROL (feienc)) { - case GST_VAAPI_RATECONTROL_CBR: - case GST_VAAPI_RATECONTROL_VBR: - case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: - if (!base_encoder->bitrate) { - /* According to the literature and testing, CABAC entropy coding - mode could provide for +10% to +18% improvement in general, - thus estimating +15% here ; and using adaptive 8x8 transforms - in I-frames could bring up to +10% improvement. */ - guint bits_per_mb = 48; - if (!feienc->use_cabac) - bits_per_mb += (bits_per_mb * 15) / 100; - if (!feienc->use_dct8x8) - bits_per_mb += (bits_per_mb * 10) / 100; - - base_encoder->bitrate = - feienc->mb_width * feienc->mb_height * bits_per_mb * - GST_VAAPI_ENCODER_FPS_N (feienc) / - GST_VAAPI_ENCODER_FPS_D (feienc) / 1000; - GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate); - } - break; - default: - base_encoder->bitrate = 0; - break; - } - ensure_bitrate_hrd (feienc); -} - -/* Constructs profile and level information based on user-defined limits */ -static GstVaapiEncoderStatus -ensure_profile_and_level (GstVaapiFeiEncH264 * feienc) -{ - const GstVaapiProfile profile = feienc->profile; - const GstVaapiLevelH264 level = feienc->level; - - if (!ensure_tuning (feienc)) - GST_WARNING ("Failed to set some of the tuning option as expected! "); - - if (!ensure_profile (feienc) || !ensure_profile_limits (feienc)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - - /* Check HW constraints */ - if (!ensure_hw_profile_limits (feienc)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - if (feienc->profile_idc > feienc->hw_max_profile_idc) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - - /* Ensure bitrate if not set already and derive the right level to use */ - ensure_bitrate (feienc); - if (!ensure_level (feienc)) - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; - - if (feienc->profile != profile || feienc->level != level) { - GST_DEBUG ("selected %s profile at level %s", - gst_vaapi_utils_h264_get_profile_string (feienc->profile), - gst_vaapi_utils_h264_get_level_string (feienc->level)); - feienc->config_changed = TRUE; - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -static void -reset_properties (GstVaapiFeiEncH264 * feienc) -{ - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (feienc); - guint mb_size, i; - guint max_reflist0_count; - - if (feienc->idr_period < base_encoder->keyframe_period) - feienc->idr_period = base_encoder->keyframe_period; - - if (feienc->min_qp > feienc->init_qp || - (GST_VAAPI_ENCODER_RATE_CONTROL (feienc) == GST_VAAPI_RATECONTROL_CQP && - feienc->min_qp < feienc->init_qp)) - feienc->min_qp = feienc->init_qp; - - mb_size = feienc->mb_width * feienc->mb_height; - if (feienc->num_slices > (mb_size + 1) / 2) - feienc->num_slices = (mb_size + 1) / 2; - g_assert (feienc->num_slices); - - if (feienc->num_bframes > (base_encoder->keyframe_period + 1) / 2) - feienc->num_bframes = (base_encoder->keyframe_period + 1) / 2; - - /* Workaround : vaapi-intel-driver doesn't have support for - * B-frame encode when utilizing low-power encode hardware block. - * So Disabling b-frame encoding in low-pwer encode. - * - * Fixme :We should query the VAConfigAttribEncMaxRefFrames - * instead of blindly disabling b-frame support and set b/p frame count, - * buffer pool size etc based on that.*/ - if ((feienc->num_bframes > 0) - && (feienc->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)) { - GST_WARNING - ("Disabling b-frame since the driver doesn't supporting it in low-power encode"); - feienc->num_bframes = 0; - } - - if (feienc->num_bframes > 0 && GST_VAAPI_ENCODER_FPS_N (feienc) > 0) - feienc->cts_offset = gst_util_uint64_scale (GST_SECOND, - GST_VAAPI_ENCODER_FPS_D (feienc), GST_VAAPI_ENCODER_FPS_N (feienc)); - else - feienc->cts_offset = 0; - - /* init max_frame_num, max_poc */ - feienc->log2_max_frame_num = h264_get_log2_max_frame_num (feienc->idr_period); - g_assert (feienc->log2_max_frame_num >= 4); - feienc->max_frame_num = (1 << feienc->log2_max_frame_num); - feienc->log2_max_pic_order_cnt = feienc->log2_max_frame_num + 1; - feienc->max_pic_order_cnt = (1 << feienc->log2_max_pic_order_cnt); - feienc->idr_num = 0; - - if (feienc->num_bframes > 0) { - if (feienc->num_ref_frames == 1) { - GST_INFO ("num ref frames is modified as 2 as b frame is set"); - feienc->num_ref_frames = 2; - } - max_reflist0_count = feienc->num_ref_frames - 1; - } else { - max_reflist0_count = feienc->num_ref_frames; - } - max_reflist0_count = max_reflist0_count > 5 ? 5 : max_reflist0_count; - - for (i = 0; i < feienc->num_views; i++) { - GstVaapiH264ViewRefPool *const ref_pool = &feienc->ref_pools[i]; - GstVaapiH264ViewReorderPool *const reorder_pool = &feienc->reorder_pools[i]; - - ref_pool->max_reflist0_count = max_reflist0_count; - ref_pool->max_reflist1_count = feienc->num_bframes > 0; - ref_pool->max_ref_frames = ref_pool->max_reflist0_count - + ref_pool->max_reflist1_count; - - reorder_pool->frame_index = 0; - } - -} - -/* only for vaapi encoder framework checking */ -static GstVaapiEncoderStatus -gst_vaapi_feienc_h264_fake_encode (GstVaapiEncoder * base_encoder, - GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) -{ - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -GstVaapiEncoderStatus -gst_vaapi_feienc_h264_encode (GstVaapiEncoder * base_encoder, - GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * reconstruct, - GstVaapiCodedBufferProxy * codedbuf_proxy, - GstVaapiFeiInfoToPakH264 * info_to_pak) -{ - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); - GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; - - if (!reconstruct || !codedbuf_proxy) - return ret; - - if (!ensure_sequence (feienc, picture, info_to_pak)) - goto error; - if (!ensure_misc_params (feienc, picture)) - goto error; - if (!ensure_fei_misc_params (feienc, picture, codedbuf_proxy)) - goto error; - if (!ensure_picture (feienc, picture, reconstruct, codedbuf_proxy, - info_to_pak)) - goto error; - if (!ensure_slices (feienc, picture, info_to_pak)) - goto error; - if (!gst_vaapi_enc_picture_encode (picture)) - goto error; - - return GST_VAAPI_ENCODER_STATUS_SUCCESS; - -error: - return ret; -} - -GstVaapiEncoderStatus -gst_vaapi_feienc_h264_flush (GstVaapiEncoder * base_encoder) -{ - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); - GstVaapiH264ViewReorderPool *reorder_pool; - GstVaapiEncPicture *pic; - guint i; - - for (i = 0; i < feienc->num_views; i++) { - reorder_pool = &feienc->reorder_pools[i]; - reorder_pool->frame_index = 0; - reorder_pool->cur_frame_num = 0; - reorder_pool->cur_present_index = 0; - - while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - pic = (GstVaapiEncPicture *) - g_queue_pop_head (&reorder_pool->reorder_frame_list); - gst_vaapi_enc_picture_unref (pic); - } - g_queue_clear (&reorder_pool->reorder_frame_list); - } - - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -/* Generate "codec-data" buffer */ -static GstVaapiEncoderStatus -gst_vaapi_feienc_h264_get_codec_data (GstVaapiEncoder * base_encoder, - GstBuffer ** out_buffer_ptr) -{ - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -GstVaapiEncoderStatus -gst_vaapi_feienc_h264_reordering (GstVaapiEncoder * base_encoder, - GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) -{ - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); - GstVaapiH264ViewReorderPool *reorder_pool = NULL; - GstVaapiEncPicture *picture; - gboolean is_idr = FALSE; - - *output = NULL; - - /* encoding views alternatively for MVC */ - if (feienc->is_mvc) { - /* FIXME: Use first-in-bundle flag on buffers to reset view idx? */ - if (frame) - feienc->view_idx = frame->system_frame_number % feienc->num_views; - else - feienc->view_idx = (feienc->view_idx + 1) % feienc->num_views; - } - reorder_pool = &feienc->reorder_pools[feienc->view_idx]; - - if (!frame) { - if (reorder_pool->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES) - return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; - - /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES - dump B frames from queue, sometime, there may also have P frame or I frame */ - g_assert (feienc->num_bframes > 0); - g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list), - GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN); - picture = g_queue_pop_head (&reorder_pool->reorder_frame_list); - g_assert (picture); - if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; - } - goto end; - } - - /* new frame coming */ - picture = GST_VAAPI_ENC_PICTURE_NEW (H264, feienc, frame); - if (!picture) { - GST_WARNING ("create H264 picture failed, frame timestamp:%" - GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts)); - return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; - } - ++reorder_pool->cur_present_index; - picture->poc = ((reorder_pool->cur_present_index * 2) % - feienc->max_pic_order_cnt); - - is_idr = (reorder_pool->frame_index == 0 || - reorder_pool->frame_index >= feienc->idr_period); - - /* check key frames */ - if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) || - (reorder_pool->frame_index % - GST_VAAPI_ENCODER_KEYFRAME_PERIOD (feienc)) == 0) { - ++reorder_pool->cur_frame_num; - ++reorder_pool->frame_index; - - /* b frame enabled, check queue of reorder_frame_list */ - if (feienc->num_bframes - && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - GstVaapiEncPicture *p_pic; - - p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list); - set_p_frame (p_pic, feienc); - g_queue_foreach (&reorder_pool->reorder_frame_list, - (GFunc) set_b_frame, feienc); - ++reorder_pool->cur_frame_num; - set_key_frame (picture, feienc, is_idr); - g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); - picture = p_pic; - reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; - } else { /* no b frames in queue */ - set_key_frame (picture, feienc, is_idr); - g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list)); - if (feienc->num_bframes) - reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES; - } - goto end; - } - - /* new p/b frames coming */ - ++reorder_pool->frame_index; - if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES && - g_queue_get_length (&reorder_pool->reorder_frame_list) < - feienc->num_bframes) { - g_queue_push_tail (&reorder_pool->reorder_frame_list, picture); - return GST_VAAPI_ENCODER_STATUS_NO_SURFACE; - } - - ++reorder_pool->cur_frame_num; - set_p_frame (picture, feienc); - - if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) { - g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame, - feienc); - reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES; - g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list)); - } - -end: - g_assert (picture); - frame = picture->frame; - if (GST_CLOCK_TIME_IS_VALID (frame->pts)) - frame->pts += feienc->cts_offset; - *output = picture; - - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -static GstVaapiEncoderStatus -set_context_info (GstVaapiEncoder * base_encoder) -{ - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); - GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (feienc); - const guint DEFAULT_SURFACES_COUNT = 3; - - /* Maximum sizes for common headers (in bits) */ - enum - { - MAX_SPS_HDR_SIZE = 16473, - MAX_VUI_PARAMS_SIZE = 210, - MAX_HRD_PARAMS_SIZE = 4103, - MAX_PPS_HDR_SIZE = 101, - MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402, - }; - - if (!ensure_hw_profile (feienc)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - - base_encoder->num_ref_frames = - (feienc->num_ref_frames + DEFAULT_SURFACES_COUNT) * feienc->num_views; - - /* Only YUV 4:2:0 formats are supported for now. This means that we - have a limit of 3200 bits per macroblock. */ - /* XXX: check profile and compute RawMbBits */ - base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) * - GST_ROUND_UP_16 (vip->height) / 256) * 400; - - /* Account for SPS header */ - /* XXX: exclude scaling lists, MVC/SVC extensions */ - base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE + - MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8; - - /* Account for PPS header */ - /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */ - base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8; - - /* Account for slice header */ - base_encoder->codedbuf_size += feienc->num_slices * (4 + - GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8); - - base_encoder->context_info.entrypoint = feienc->entrypoint; - - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -GstVaapiEncoderStatus -gst_vaapi_feienc_h264_reconfigure (GstVaapiEncoder * base_encoder) -{ - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); - GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (feienc); - GstVaapiEncoderStatus status; - guint mb_width, mb_height; - - mb_width = (GST_VAAPI_ENCODER_WIDTH (feienc) + 15) / 16; - mb_height = (GST_VAAPI_ENCODER_HEIGHT (feienc) + 15) / 16; - if (mb_width != feienc->mb_width || mb_height != feienc->mb_height) { - GST_DEBUG ("resolution: %dx%d", GST_VAAPI_ENCODER_WIDTH (feienc), - GST_VAAPI_ENCODER_HEIGHT (feienc)); - feienc->mb_width = mb_width; - feienc->mb_height = mb_height; - feienc->config_changed = TRUE; - } - - /* Take number of MVC views from input caps if provided */ - if (GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == - GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME - || GST_VIDEO_INFO_MULTIVIEW_MODE (vip) == - GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME) - feienc->num_views = GST_VIDEO_INFO_VIEWS (vip); - - feienc->is_mvc = feienc->num_views > 1; - - status = ensure_profile_and_level (feienc); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return status; - - reset_properties (feienc); - status = set_context_info (base_encoder); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return status; - - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -struct _GstVaapiFeiEncH264Class -{ - GstVaapiEncoderClass parent_class; -}; - -G_DEFINE_TYPE (GstVaapiFeiEncH264, gst_vaapi_feienc_h264, - GST_TYPE_VAAPI_ENCODER); - -static void -gst_vaapi_feienc_h264_init (GstVaapiFeiEncH264 * feienc) -{ - guint32 i; - - /* Default encoding entrypoint */ - feienc->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; - feienc->search_path = GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT; - feienc->len_sp = GST_VAAPI_FEI_H264_SEARCH_PATH_LENGTH_DEFAULT; - feienc->ref_width = GST_VAAPI_FEI_H264_REF_WIDTH_DEFAULT; - feienc->ref_height = GST_VAAPI_FEI_H264_REF_HEIGHT_DEFAULT; - feienc->intra_part_mask = GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT; - feienc->submb_part_mask = GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT; - - /* Multi-view coding information */ - feienc->is_mvc = FALSE; - feienc->num_views = 1; - feienc->view_idx = 0; - - /* default num ref frames */ - feienc->num_ref_frames = 1; - memset (feienc->view_ids, 0, sizeof (feienc->view_ids)); - - feienc->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI; - - /* re-ordering list initialize */ - for (i = 0; i < MAX_NUM_VIEWS; i++) { - GstVaapiH264ViewReorderPool *const reorder_pool = &feienc->reorder_pools[i]; - g_queue_init (&reorder_pool->reorder_frame_list); - reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE; - reorder_pool->frame_index = 0; - reorder_pool->cur_frame_num = 0; - reorder_pool->cur_present_index = 0; - } -} - -static void -gst_vaapi_feienc_h264_finalize (GObject * object) -{ - /*free private buffers */ - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264 (object); - GstVaapiEncPicture *pic; - guint32 i; - - gst_buffer_replace (&feienc->sps_data, NULL); - gst_buffer_replace (&feienc->subset_sps_data, NULL); - gst_buffer_replace (&feienc->pps_data, NULL); - - /* re-ordering list initialize */ - for (i = 0; i < MAX_NUM_VIEWS; i++) { - GstVaapiH264ViewReorderPool *const reorder_pool = &feienc->reorder_pools[i]; - while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) { - pic = (GstVaapiEncPicture *) - g_queue_pop_head (&reorder_pool->reorder_frame_list); - gst_vaapi_enc_picture_unref (pic); - } - g_queue_clear (&reorder_pool->reorder_frame_list); - } - - G_OBJECT_CLASS (gst_vaapi_feienc_h264_parent_class)->finalize (object); -} - -static void -set_view_ids (GstVaapiFeiEncH264 * const encoder, const GValue * value) -{ - guint i, j; - guint len = gst_value_array_get_size (value); - - if (len == 0) - goto set_default_ids; - - if (len != encoder->num_views) { - GST_WARNING ("The view number is %d, but %d view IDs are provided. Just " - "fallback to use default view IDs.", encoder->num_views, len); - goto set_default_ids; - } - - for (i = 0; i < len; i++) { - const GValue *val = gst_value_array_get_value (value, i); - encoder->view_ids[i] = g_value_get_uint (val); - } - - /* check whether duplicated ID */ - for (i = 0; i < len; i++) { - for (j = i + 1; j < len; j++) { - if (encoder->view_ids[i] == encoder->view_ids[j]) { - GST_WARNING ("The view %d and view %d have same view ID %d. Just " - "fallback to use default view IDs.", i, j, encoder->view_ids[i]); - goto set_default_ids; - } - } - } - - return; - -set_default_ids: - { - for (i = 0; i < encoder->num_views; i++) - encoder->view_ids[i] = i; - } -} - -static void -get_view_ids (GstVaapiFeiEncH264 * const encoder, GValue * value) -{ - guint i; - GValue id = G_VALUE_INIT; - - g_value_reset (value); - g_value_init (&id, G_TYPE_UINT); - - for (i = 0; i < encoder->num_views; i++) { - g_value_set_uint (&id, encoder->view_ids[i]); - gst_value_array_append_value (value, &id); - } - g_value_unset (&id); -} - -/** - * @FEI_H264_ENC_PROP_RATECONTROL: Rate control (#GstVaapiRateControl). - * @FEI_H264_ENC_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). - * @FEI_H264_ENC_PROP_MAX_BFRAMES: Number of B-frames between I - * and P (uint). - * @FEI_H264_ENC_PROP_INIT_QP: Initial quantizer value (uint). - * @FEI_H264_ENC_PROP_MIN_QP: Minimal quantizer value (uint). - * @FEI_H264_ENC_PROP_NUM_SLICES: Number of slices per frame (uint). - * @FEI_H264_ENC_PROP_CABAC: Enable CABAC entropy coding mode (bool). - * @FEI_H264_ENC_PROP_DCT8X8: Enable adaptive use of 8x8 - * transforms in I-frames (bool). - * @FEI_H264_ENC_PROP_CPB_LENGTH: Length of the CPB buffer - * in milliseconds (uint). - * @FEI_H264_ENC_PROP_NUM_VIEWS: Number of views per frame. - * @FEI_H264_ENC_PROP_VIEW_IDS: View IDs - * - * The set of FEI Enc specific configurable properties. - */ -enum -{ - FEI_H264_ENC_PROP_RATECONTROL = 1, - FEI_H264_ENC_PROP_TUNE, - FEI_H264_ENC_PROP_MAX_BFRAMES, - FEI_H264_ENC_PROP_INIT_QP, - FEI_H264_ENC_PROP_MIN_QP, - FEI_H264_ENC_PROP_NUM_SLICES, - FEI_H264_ENC_PROP_CABAC, - FEI_H264_ENC_PROP_DCT8X8, - FEI_H264_ENC_PROP_CPB_LENGTH, - FEI_H264_ENC_PROP_NUM_VIEWS, - FEI_H264_ENC_PROP_VIEW_IDS, - FEI_H264_ENC_PROP_NUM_REF, - FEI_H264_ENC_PROP_FEI_ENABLE, - FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0, - FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1, - FEI_H264_ENC_PROP_SEARCH_WINDOW, - FEI_H264_ENC_PROP_LEN_SP, - FEI_H264_ENC_PROP_SEARCH_PATH, - FEI_H264_ENC_PROP_REF_WIDTH, - FEI_H264_ENC_PROP_REF_HEIGHT, - FEI_H264_ENC_PROP_SUBMB_MASK, - FEI_H264_ENC_PROP_SUBPEL_MODE, - FEI_H264_ENC_PROP_INTRA_PART_MASK, - FEI_H264_ENC_PROP_INTRA_SAD, - FEI_H264_ENC_PROP_INTER_SAD, - FEI_H264_ENC_PROP_ADAPT_SEARCH, - FEI_H264_ENC_PROP_MULTI_PRED_L0, - FEI_H264_ENC_PROP_MULTI_PRED_L1, - FEI_H264_ENC_PROP_ENABLE_STATS_OUT, - FEI_H264_ENC_N_PROPERTIES -}; - -static GParamSpec *properties[FEI_H264_ENC_N_PROPERTIES]; - -static void -gst_vaapi_feienc_h264_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (base_encoder); - - if (base_encoder->num_codedbuf_queued > 0) { - GST_ERROR_OBJECT (object, - "failed to set any property after encoding started"); - return; - } - - switch (prop_id) { - case FEI_H264_ENC_PROP_RATECONTROL: - gst_vaapi_encoder_set_rate_control (base_encoder, - g_value_get_enum (value)); - break; - case FEI_H264_ENC_PROP_TUNE: - gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value)); - break; - case FEI_H264_ENC_PROP_MAX_BFRAMES: - feienc->num_bframes = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_INIT_QP: - feienc->init_qp = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_MIN_QP: - feienc->min_qp = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_NUM_SLICES: - feienc->num_slices = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_CABAC: - feienc->use_cabac = g_value_get_boolean (value); - break; - case FEI_H264_ENC_PROP_DCT8X8: - feienc->use_dct8x8 = g_value_get_boolean (value); - break; - case FEI_H264_ENC_PROP_CPB_LENGTH: - feienc->cpb_length = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_NUM_VIEWS: - feienc->num_views = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_VIEW_IDS: - set_view_ids (feienc, value); - break; - case FEI_H264_ENC_PROP_NUM_REF: - feienc->num_ref_frames = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0: - feienc->num_mv_predictors_l0 = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1: - feienc->num_mv_predictors_l1 = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_SEARCH_WINDOW: - feienc->search_window = g_value_get_enum (value); - break; - case FEI_H264_ENC_PROP_LEN_SP: - feienc->len_sp = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_SEARCH_PATH: - feienc->search_path = g_value_get_enum (value); - break; - case FEI_H264_ENC_PROP_REF_WIDTH: - feienc->ref_width = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_REF_HEIGHT: - feienc->ref_height = g_value_get_uint (value); - break; - case FEI_H264_ENC_PROP_SUBMB_MASK: - feienc->submb_part_mask = g_value_get_flags (value); - break; - case FEI_H264_ENC_PROP_SUBPEL_MODE: - feienc->subpel_mode = g_value_get_enum (value); - break; - case FEI_H264_ENC_PROP_INTRA_PART_MASK: - feienc->intra_part_mask = g_value_get_flags (value); - break; - case FEI_H264_ENC_PROP_INTRA_SAD: - feienc->intra_sad = g_value_get_enum (value); - break; - case FEI_H264_ENC_PROP_INTER_SAD: - feienc->inter_sad = g_value_get_enum (value); - break; - case FEI_H264_ENC_PROP_ADAPT_SEARCH: - feienc->adaptive_search = g_value_get_boolean (value) ? 1 : 0; - break; - case FEI_H264_ENC_PROP_MULTI_PRED_L0: - feienc->multi_predL0 = g_value_get_boolean (value) ? 1 : 0; - break; - case FEI_H264_ENC_PROP_MULTI_PRED_L1: - feienc->multi_predL1 = g_value_get_boolean (value) ? 1 : 0; - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -gst_vaapi_feienc_h264_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVaapiFeiEncH264 *const feienc = GST_VAAPI_FEI_ENC_H264_CAST (object); - GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object); - - switch (prop_id) { - case FEI_H264_ENC_PROP_RATECONTROL: - g_value_set_enum (value, base_encoder->rate_control); - break; - case FEI_H264_ENC_PROP_TUNE: - g_value_set_enum (value, base_encoder->tune); - break; - case FEI_H264_ENC_PROP_MAX_BFRAMES: - g_value_set_uint (value, feienc->num_bframes); - break; - case FEI_H264_ENC_PROP_INIT_QP: - g_value_set_uint (value, feienc->init_qp); - break; - case FEI_H264_ENC_PROP_MIN_QP: - g_value_set_uint (value, feienc->min_qp); - break; - case FEI_H264_ENC_PROP_NUM_SLICES: - g_value_set_uint (value, feienc->num_slices); - break; - case FEI_H264_ENC_PROP_CABAC: - g_value_set_boolean (value, feienc->use_cabac); - break; - case FEI_H264_ENC_PROP_DCT8X8: - g_value_set_boolean (value, feienc->use_dct8x8); - break; - case FEI_H264_ENC_PROP_CPB_LENGTH: - g_value_set_uint (value, feienc->cpb_length); - break; - case FEI_H264_ENC_PROP_NUM_VIEWS: - g_value_set_uint (value, feienc->num_views); - break; - case FEI_H264_ENC_PROP_VIEW_IDS: - get_view_ids (feienc, value); - break; - case FEI_H264_ENC_PROP_NUM_REF: - g_value_set_uint (value, feienc->num_ref_frames); - break; - case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0: - g_value_set_uint (value, feienc->num_mv_predictors_l0); - break; - case FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1: - g_value_set_uint (value, feienc->num_mv_predictors_l1); - break; - case FEI_H264_ENC_PROP_SEARCH_WINDOW: - g_value_set_enum (value, feienc->search_window); - break; - case FEI_H264_ENC_PROP_LEN_SP: - g_value_set_uint (value, feienc->len_sp); - break; - case FEI_H264_ENC_PROP_SEARCH_PATH: - g_value_set_enum (value, feienc->search_path); - break; - case FEI_H264_ENC_PROP_REF_WIDTH: - g_value_set_uint (value, feienc->ref_width); - break; - case FEI_H264_ENC_PROP_REF_HEIGHT: - g_value_set_uint (value, feienc->ref_height); - break; - case FEI_H264_ENC_PROP_SUBMB_MASK: - g_value_set_flags (value, feienc->submb_part_mask); - break; - case FEI_H264_ENC_PROP_SUBPEL_MODE: - g_value_set_enum (value, feienc->subpel_mode); - break; - case FEI_H264_ENC_PROP_INTRA_PART_MASK: - g_value_set_flags (value, feienc->intra_part_mask); - break; - case FEI_H264_ENC_PROP_INTRA_SAD: - g_value_set_enum (value, feienc->intra_sad); - break; - case FEI_H264_ENC_PROP_INTER_SAD: - g_value_set_enum (value, feienc->inter_sad); - break; - case FEI_H264_ENC_PROP_ADAPT_SEARCH: - g_value_set_boolean (value, feienc->adaptive_search); - break; - case FEI_H264_ENC_PROP_MULTI_PRED_L0: - g_value_set_boolean (value, feienc->multi_predL0); - break; - case FEI_H264_ENC_PROP_MULTI_PRED_L1: - g_value_set_boolean (value, feienc->multi_predL1); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static const GstVaapiEncoderClassData fei_enc_class_data = { - .codec = GST_VAAPI_CODEC_H264, - .packed_headers = SUPPORTED_PACKED_HEADERS, - .rate_control_get_type = gst_vaapi_rate_control_get_type, - .default_rate_control = DEFAULT_RATECONTROL, - .rate_control_mask = SUPPORTED_RATECONTROLS, - .encoder_tune_get_type = gst_vaapi_encoder_tune_get_type, - .default_encoder_tune = GST_VAAPI_ENCODER_TUNE_NONE, - .encoder_tune_mask = SUPPORTED_TUNE_OPTIONS, -}; - -static void -gst_vaapi_feienc_h264_class_init (GstVaapiFeiEncH264Class * klass) -{ - GObjectClass *const object_class = G_OBJECT_CLASS (klass); - GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass); - - encoder_class->class_data = &fei_enc_class_data; - encoder_class->reconfigure = gst_vaapi_feienc_h264_reconfigure; - encoder_class->reordering = gst_vaapi_feienc_h264_reordering; - encoder_class->encode = gst_vaapi_feienc_h264_fake_encode; - encoder_class->flush = gst_vaapi_feienc_h264_flush; - encoder_class->get_codec_data = gst_vaapi_feienc_h264_get_codec_data; - - object_class->set_property = gst_vaapi_feienc_h264_set_property; - object_class->get_property = gst_vaapi_feienc_h264_get_property; - object_class->finalize = gst_vaapi_feienc_h264_finalize; - - /** - * GstVaapiFeiEncH264:rate-control: - * - * The desired rate control mode, expressed as a #GstVaapiRateControl. - */ - properties[FEI_H264_ENC_PROP_RATECONTROL] = - g_param_spec_enum ("rate-control", - "Rate Control", "Rate control mode", - fei_enc_class_data.rate_control_get_type (), - fei_enc_class_data.default_rate_control, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:tune: - * - * The desired encoder tuning option. - */ - properties[FEI_H264_ENC_PROP_TUNE] = - g_param_spec_enum ("tune", - "Encoder Tuning", - "Encoder tuning option", - fei_enc_class_data.encoder_tune_get_type (), - fei_enc_class_data.default_encoder_tune, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:max-bframes: - * - * The number of B-frames between I and P. - */ - properties[FEI_H264_ENC_PROP_MAX_BFRAMES] = - g_param_spec_uint ("max-bframes", - "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:init-qp: - * - * The initial quantizer value. - */ - properties[FEI_H264_ENC_PROP_INIT_QP] = - g_param_spec_uint ("init-qp", - "Initial QP", "Initial quantizer value", 1, 51, 26, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:min-qp: - * - * The minimum quantizer value. - */ - properties[FEI_H264_ENC_PROP_MIN_QP] = - g_param_spec_uint ("min-qp", - "Minimum QP", "Minimum quantizer value", 1, 51, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:num-slices: - * - * The number of slices per frame. - */ - properties[FEI_H264_ENC_PROP_NUM_SLICES] = - g_param_spec_uint ("num-slices", - "Number of Slices", - "Number of slices per frame", - 1, 200, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:cabac: - * - * Enable CABAC entropy coding mode for improved compression ratio, - * at the expense that the minimum target profile is Main. Default - * is CAVLC entropy coding mode. - */ - properties[FEI_H264_ENC_PROP_CABAC] = - g_param_spec_boolean ("cabac", - "Enable CABAC", - "Enable CABAC entropy coding mode", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:dct8x8: - * - * Enable adaptive use of 8x8 transforms in I-frames. This improves - * the compression ratio by the minimum target profile is High. - * Default is to use 4x4 DCT only. - */ - properties[FEI_H264_ENC_PROP_DCT8X8] = - g_param_spec_boolean ("dct8x8", - "Enable 8x8 DCT", - "Enable adaptive use of 8x8 transforms in I-frames", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:cpb-length: - * - * The size of the CPB buffer in milliseconds. - */ - properties[FEI_H264_ENC_PROP_CPB_LENGTH] = - g_param_spec_uint ("cpb-length", - "CPB Length", "Length of the CPB buffer in milliseconds", - 1, 10000, DEFAULT_CPB_LENGTH, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:num-views: - * - * The number of views for MVC encoding . - */ - properties[FEI_H264_ENC_PROP_NUM_VIEWS] = - g_param_spec_uint ("num-views", - "Number of Views", - "Number of Views for MVC encoding", - 1, MAX_NUM_VIEWS, 1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiFeiEncH264:view-ids: - * - * The view ids for MVC encoding . - */ - properties[FEI_H264_ENC_PROP_VIEW_IDS] = - gst_param_spec_array ("view-ids", - "View IDs", "Set of View Ids used for MVC encoding", - g_param_spec_uint ("view-id-value", "View id value", - "view id values used for mvc encoding", 0, MAX_VIEW_ID, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiFeiEncH264:num-ref: - * - * The number of reference frames. - */ - properties[FEI_H264_ENC_PROP_NUM_REF] = - g_param_spec_uint ("num-ref", - "Num Ref", - "reference frame number", - 1, 6, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:num_mv_predictors_l0: - * - * The number of mv predict - */ - properties[FEI_H264_ENC_PROP_NUM_MV_PREDICT_L0] = - g_param_spec_uint ("num-mvpredict-l0", - "Num mv predict l0", - "Indicate how many predictors should be used for l0", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiFeiEncH264:num_mv_predictors_l1: - * - * The number of mv predict - */ - properties[FEI_H264_ENC_PROP_NUM_MV_PREDICT_L1] = - g_param_spec_uint ("num-mvpredict-l1", - "Num mv predict l1", - "Indicate how many predictors should be used for l1", - 0, 3, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiFeiEncH264:search-window: - */ - properties[FEI_H264_ENC_PROP_SEARCH_WINDOW] = - g_param_spec_enum ("search-window", - "search window", - "Specify one of the predefined search path", - GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiFeiEncH264:len-sp: - */ - properties[FEI_H264_ENC_PROP_LEN_SP] = - g_param_spec_uint ("len-sp", - "len sp", - "This value defines number of search units in search path", - 1, 63, 32, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:search-path: - */ - properties[FEI_H264_ENC_PROP_SEARCH_PATH] = - g_param_spec_enum ("search-path", - "search path", - "Specify search path", - GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH, - GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:ref-width: - */ - properties[FEI_H264_ENC_PROP_REF_WIDTH] = - g_param_spec_uint ("ref-width", - "ref width", - "Width of search region in pixel, must be multiple of 4", - 4, 64, 32, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:ref-height: - */ - properties[FEI_H264_ENC_PROP_REF_HEIGHT] = - g_param_spec_uint ("ref-height", - "ref height", - "Height of search region in pixel, must be multiple of 4", - 4, 32, 32, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiFeiEncH264:submb-mask: - * Defines the bit-mask for disabling sub-partition - * - */ - properties[FEI_H264_ENC_PROP_SUBMB_MASK] = - g_param_spec_flags ("submbpart-mask", - "submb part mask", - "defines the bit-mask for disabling sub mb partition", - GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK, - GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:subpel-mode: - */ - properties[FEI_H264_ENC_PROP_SUBPEL_MODE] = - g_param_spec_enum ("subpel-mode", - "subpel mode", - "Sub pixel precision for motion estimation", - GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE, - GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiFeiEncH264:intrapart-mask: - */ - properties[FEI_H264_ENC_PROP_INTRA_PART_MASK] = - g_param_spec_flags ("intrapart-mask", - "intra part mask", - "What block and sub-block partitions are disabled for intra MBs", - GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK, - GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - /** - * GstVaapiFeiEncH264:intra-sad: - */ - properties[FEI_H264_ENC_PROP_INTRA_SAD] = - g_param_spec_enum ("intra-sad", - "intra sad", - "Specifies distortion measure adjustments used in the motion search SAD comparison for intra MB", - GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:inter-sad: - */ - properties[FEI_H264_ENC_PROP_INTER_SAD] = - g_param_spec_enum ("inter-sad", - "inter sad", - "Specifies distortion measure adjustments used in the motion search SAD comparison for inter MB", - GST_VAAPI_TYPE_FEI_H264_SAD_MODE, GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:adaptive-search: - */ - properties[FEI_H264_ENC_PROP_ADAPT_SEARCH] = - g_param_spec_boolean ("adaptive-search", - "adaptive-search", - "Enable adaptive search", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:multi-predL0: - */ - properties[FEI_H264_ENC_PROP_MULTI_PRED_L0] = - g_param_spec_boolean ("multi-predL0", - "multi predL0", - "Enable multi prediction for ref L0 list", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - /** - * GstVaapiFeiEncH264:multi-predL0: - */ - properties[FEI_H264_ENC_PROP_MULTI_PRED_L1] = - g_param_spec_boolean ("multi-predL1", - "multi predL1", - "Enable multi prediction for ref L1 list", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | - GST_VAAPI_PARAM_ENCODER_EXPOSURE); - - g_object_class_install_properties (object_class, FEI_H264_ENC_N_PROPERTIES, - properties); -} - -/** - * gst_vaapi_feienc_h264_new: - * @display: a #GstVaapiDisplay - * - * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the - * only supported output stream format is "byte-stream" format. - * - * Return value: the newly allocated #GstVaapiEncoder object - */ -GstVaapiEncoder * -gst_vaapi_feienc_h264_new (GstVaapiDisplay * display) -{ - return g_object_new (GST_TYPE_VAAPI_FEI_ENC_H264, "display", display, NULL); -} - -/** - * gst_vaapi_feienc_h264_set_max_profile: - * @feienc: a #GstVaapiFeiEncH264 - * @profile: an H.264 #GstVaapiProfile - * - * Notifies the @feienc to use coding tools from the supplied - * @profile at most. - * - * This means that if the minimal profile derived to - * support the specified coding tools is greater than this @profile, - * then an error is returned when the @feienc is configured. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_feienc_h264_set_max_profile (GstVaapiFeiEncH264 * feienc, - GstVaapiProfile profile) -{ - guint8 profile_idc; - - g_return_val_if_fail (feienc != NULL, FALSE); - g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE); - - if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264) - return FALSE; - - profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); - if (!profile_idc) - return FALSE; - - feienc->max_profile_idc = profile_idc; - return TRUE; -} - -gboolean -gst_vaapi_feienc_h264_set_ref_pool (GstVaapiFeiEncH264 * feienc, - gpointer ref_pool_ptr) -{ - g_return_val_if_fail (feienc != NULL, FALSE); - - if (!ref_pool_ptr) - return FALSE; - - memcpy (&feienc->ref_pools[0], ref_pool_ptr, - sizeof (GstVaapiH264ViewRefPool) * MAX_NUM_VIEWS); - - return TRUE; -} - -/** - * gst_vaapi_feienc_h264_get_profile_and_level - * @feienc: a #GstVaapiFeiEncH264 - * @out_profile_ptr: return location for the #GstVaapiProfile - * @out_profile_idc_ptr: return location for the #GstVaapiLevelH264 - * - * Queries the H.264 @feienc for the active profile and level. That - * information is only constructed and valid after the feienc is - * configured, i.e. after the gst_vaapi_feienc_set_codec_state() - * function is called. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_feienc_h264_get_profile_and_idc (GstVaapiFeiEncH264 * feienc, - GstVaapiProfile * out_profile_ptr, guint8 * out_profile_idc_ptr) -{ - g_return_val_if_fail (feienc != NULL, FALSE); - - if (!feienc->profile || !feienc->profile_idc) - return FALSE; - - if (out_profile_ptr) - *out_profile_ptr = feienc->profile; - if (out_profile_idc_ptr) - *out_profile_idc_ptr = feienc->profile_idc; - return TRUE; -} diff --git a/gst-libs/gst/vaapi/gstvaapifeienc_h264.h b/gst-libs/gst/vaapi/gstvaapifeienc_h264.h deleted file mode 100644 index 046056b70b..0000000000 --- a/gst-libs/gst/vaapi/gstvaapifeienc_h264.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * gstvaapifeienc_h264.h - FEI Enc abstract - * - * Copyright (C) 2016-2018 Intel Corporation - * Author: Leilei Shang - * Author: Sreerenj Balachandran - * - * 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_FEI_H264_ENC_H -#define GST_VAAPI_FEI_H264_ENC_H - -#include -#include -#include -#include -G_BEGIN_DECLS - -#define GST_TYPE_VAAPI_FEI_ENC_H264 \ - (gst_vaapi_feienc_h264_get_type ()) -#define GST_VAAPI_FEI_ENC_H264(encoder) \ - (G_TYPE_CHECK_INSTANCE_CAST ((encoder), GST_TYPE_VAAPI_FEI_ENC_H264, GstVaapiFeiEncH264)) -#define GST_IS_VAAPI_FEI_ENC_H264(encoder) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((encoder), GST_TYPE_VAAPI_FEI_ENC_H264)) - -typedef struct _GstVaapiFeiEncH264 GstVaapiFeiEncH264; -typedef struct _GstVaapiFeiEncH264Class GstVaapiFeiEncH264Class; - -GType -gst_vaapi_feienc_h264_get_type (void) G_GNUC_CONST; - -GstVaapiEncoder * -gst_vaapi_feienc_h264_new (GstVaapiDisplay * display); - -gboolean -gst_vaapi_feienc_h264_set_max_profile (GstVaapiFeiEncH264 * feienc, - GstVaapiProfile profile); - -gboolean -gst_vaapi_feienc_h264_set_ref_pool (GstVaapiFeiEncH264 * feienc, gpointer ref_pool_ptr); - -GstVaapiEncoderStatus -gst_vaapi_feienc_h264_encode (GstVaapiEncoder * base_encoder, - GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * reconstruct, - GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiFeiInfoToPakH264 *info_to_pak); - -GstVaapiEncoderStatus -gst_vaapi_feienc_h264_flush (GstVaapiEncoder * base_encoder); - -GstVaapiEncoderStatus -gst_vaapi_feienc_h264_reordering (GstVaapiEncoder * base_encoder, - GstVideoCodecFrame * frame, GstVaapiEncPicture ** output); - -GstVaapiEncoderStatus -gst_vaapi_feienc_h264_reconfigure (GstVaapiEncoder * base_encoder); - -gboolean -gst_vaapi_feienc_h264_get_profile_and_idc (GstVaapiFeiEncH264 * feienc, - GstVaapiProfile * out_profile_ptr, guint8 * out_profile_idc_ptr); - -G_END_DECLS -#endif /*GST_VAAPI_FEI_H264_ENC_H */ diff --git a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c b/gst-libs/gst/vaapi/gstvaapifeipak_h264.c deleted file mode 100644 index 575c4f9388..0000000000 --- a/gst-libs/gst/vaapi/gstvaapifeipak_h264.c +++ /dev/null @@ -1,1915 +0,0 @@ -/* - * gstvaapifeipak_h264.c - H.264 FEI PAK - * - * Copyright (C) 2012-2016 Intel Corporation - * Author: Chen, Xiaomin - * Author: Sreerenj Balachandran - * - * 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 - */ - -/* GValueArray has deprecated without providing an alternative in glib >= 2.32 - * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 - */ - -#define GLIB_DISABLE_DEPRECATION_WARNINGS - -#include "sysdeps.h" -#include -#include -#include -#include "gstvaapicompat.h" -#include "gstvaapiencoder_priv.h" -#include "gstvaapifeipak_h264.h" -#include "gstvaapiutils_h264_priv.h" -#include "gstvaapicodedbufferproxy_priv.h" -#include "gstvaapisurface.h" -#define DEBUG 1 -#include "gstvaapidebug.h" - -/* Define the maximum number of views supported */ -#define MAX_NUM_VIEWS 10 - -/* Define the maximum value for view-id */ -#define MAX_VIEW_ID 1023 - -/* Default CPB length (in milliseconds) */ -#define DEFAULT_CPB_LENGTH 1500 - -/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */ -#define SX_CPB_SIZE 4 - -/* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */ -#define SX_BITRATE 6 - -/* 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) | \ - GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) - -/* Supported set of tuning options, within this implementation */ -#define SUPPORTED_TUNE_OPTIONS \ - (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \ - GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION) | \ - GST_VAAPI_ENCODER_TUNE_MASK (LOW_POWER)) - -/* Supported set of VA packed headers, within this implementation */ -#define SUPPORTED_PACKED_HEADERS \ - (VA_ENC_PACKED_HEADER_SEQUENCE | \ - VA_ENC_PACKED_HEADER_PICTURE | \ - VA_ENC_PACKED_HEADER_SLICE | \ - VA_ENC_PACKED_HEADER_RAW_DATA) - -#define GST_H264_NAL_REF_IDC_NONE 0 -#define GST_H264_NAL_REF_IDC_LOW 1 -#define GST_H264_NAL_REF_IDC_MEDIUM 2 -#define GST_H264_NAL_REF_IDC_HIGH 3 - -typedef struct -{ - GstVaapiSurfaceProxy *pic; - guint poc; - guint frame_num; -} GstVaapiFEIPakH264Ref; - -typedef enum -{ - GST_VAAPI_FEIPAK_H264_REORD_NONE = 0, - GST_VAAPI_FEIPAK_H264_REORD_DUMP_FRAMES = 1, - GST_VAAPI_FEIPAK_H264_REORD_WAIT_FRAMES = 2 -} GstVaapiFEIPakH264ReorderState; - -typedef struct _GstVaapiH264FEIPakViewRefPool -{ - GQueue ref_list; - guint max_ref_frames; - guint max_reflist0_count; - guint max_reflist1_count; -} GstVaapiH264FEIPakViewRefPool; - -typedef struct _GstVaapiH264FEIPakViewReorderPool -{ - GQueue reorder_frame_list; - guint reorder_state; - guint frame_index; - guint frame_count; /* monotonically increasing with in every idr period */ - guint cur_frame_num; - guint cur_present_index; -} GstVaapiH264FEIPakViewReorderPool; - -/* ------------------------------------------------------------------------- */ -/* --- H.264 FEI PAK --- */ -/* ------------------------------------------------------------------------- */ - -struct _GstVaapiFEIPakH264 -{ - GstVaapiMiniObject parent_instance; - - GstVaapiEncoder *encoder; - - VAEncSequenceParameterBufferH264 h264_sps; - VAEncPictureParameterBufferH264 h264_pps; - GArray *h264_slice_params; - - GstVaapiProfile profile; - GstVaapiEntrypoint entrypoint; - GstVaapiDisplay *display; - VAContextID va_context; - guint8 profile_idc; - guint8 hw_max_profile_idc; - guint32 num_slices; - guint slice_type; - gboolean is_idr; - guint32 num_bframes; - guint32 mb_width; - guint32 mb_height; - gboolean props_reconfigured; - gboolean config_changed; - - guint32 max_pic_order_cnt; - guint32 log2_max_pic_order_cnt; - - GstBuffer *sps_data; - GstBuffer *subset_sps_data; - GstBuffer *pps_data; - guint32 num_ref_frames; // set reference frame num - - /* MVC */ - gboolean is_mvc; - guint32 view_idx; /* View Order Index (VOIdx) */ - guint32 num_views; - guint16 view_ids[MAX_NUM_VIEWS]; - GstVaapiH264FEIPakViewRefPool ref_pools[MAX_NUM_VIEWS]; -}; - -static inline gboolean -_poc_greater_than (guint poc1, guint poc2, guint max_poc) -{ - return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2); -} - -/* ------------------------------------------------------------------------- */ -/* --- H.264 Bitstream Writer --- */ -/* ------------------------------------------------------------------------- */ - -#define WRITE_UINT32(bs, val, nbits) do { \ - if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \ - GST_WARNING ("failed to write uint32, nbits: %d", nbits); \ - goto bs_error; \ - } \ - } while (0) - -#define WRITE_UE(bs, val) do { \ - if (!bs_write_ue (bs, val)) { \ - GST_WARNING ("failed to write ue(v)"); \ - goto bs_error; \ - } \ - } while (0) - -#define WRITE_SE(bs, val) do { \ - if (!bs_write_se (bs, val)) { \ - GST_WARNING ("failed to write se(v)"); \ - goto bs_error; \ - } \ - } while (0) - -/* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */ -static gboolean -bs_write_ue (GstBitWriter * bs, guint32 value) -{ - guint32 size_in_bits = 0; - guint32 tmp_value = ++value; - - while (tmp_value) { - ++size_in_bits; - tmp_value >>= 1; - } - if (size_in_bits > 1 - && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1)) - return FALSE; - if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits)) - return FALSE; - return TRUE; -} - -/* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */ -static gboolean -bs_write_se (GstBitWriter * bs, gint32 value) -{ - guint32 new_val; - - if (value <= 0) - new_val = -(value << 1); - else - new_val = (value << 1) - 1; - - if (!bs_write_ue (bs, new_val)) - return FALSE; - return TRUE; -} - -/* Write the NAL unit header */ -static gboolean -bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc, - guint32 nal_unit_type) -{ - WRITE_UINT32 (bs, 0, 1); - WRITE_UINT32 (bs, nal_ref_idc, 2); - WRITE_UINT32 (bs, nal_unit_type, 5); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write NAL unit header"); - return FALSE; - } -} - -/* Write the MVC NAL unit header extension */ -static gboolean -bs_write_nal_header_mvc_extension (GstBitWriter * bs, - GstVaapiEncPicture * picture, guint32 view_id) -{ - guint32 svc_extension_flag = 0; - guint32 non_idr_flag = 1; - guint32 priority_id = 0; - guint32 temporal_id = 0; - guint32 anchor_pic_flag = 0; - guint32 inter_view_flag = 0; - - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) - non_idr_flag = 0; - - if (picture->type == GST_VAAPI_PICTURE_TYPE_I) - anchor_pic_flag = 1; - /* svc_extension_flag == 0 for mvc stream */ - WRITE_UINT32 (bs, svc_extension_flag, 1); - - WRITE_UINT32 (bs, non_idr_flag, 1); - WRITE_UINT32 (bs, priority_id, 6); - WRITE_UINT32 (bs, view_id, 10); - WRITE_UINT32 (bs, temporal_id, 3); - WRITE_UINT32 (bs, anchor_pic_flag, 1); - WRITE_UINT32 (bs, inter_view_flag, 1); - WRITE_UINT32 (bs, 1, 1); - - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write NAL unit header"); - return FALSE; - } -} - -/* Write the NAL unit trailing bits */ -static gboolean -bs_write_trailing_bits (GstBitWriter * bs) -{ - if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1)) - goto bs_error; - gst_bit_writer_align_bytes_unchecked (bs, 0); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write NAL unit trailing bits"); - return FALSE; - } -} - -/* Write an SPS NAL unit */ -static gboolean -bs_write_sps_data (GstBitWriter * bs, - const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, - const VAEncMiscParameterHRD * hrd_params) -{ - guint8 profile_idc; - guint32 constraint_set0_flag, constraint_set1_flag; - guint32 constraint_set2_flag, constraint_set3_flag; - guint32 gaps_in_frame_num_value_allowed_flag = 0; // ?? - gboolean nal_hrd_parameters_present_flag; - - guint32 b_qpprime_y_zero_transform_bypass = 0; - guint32 residual_color_transform_flag = 0; - guint32 pic_height_in_map_units = - (seq_param->seq_fields.bits.frame_mbs_only_flag ? - seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2); - guint32 mb_adaptive_frame_field = - !seq_param->seq_fields.bits.frame_mbs_only_flag; - guint32 i = 0; - - profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); - constraint_set0_flag = /* A.2.1 (baseline profile constraints) */ - profile == GST_VAAPI_PROFILE_H264_BASELINE || - profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; - constraint_set1_flag = /* A.2.2 (main profile constraints) */ - profile == GST_VAAPI_PROFILE_H264_MAIN || - profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; - constraint_set2_flag = 0; - constraint_set3_flag = 0; - - /* profile_idc */ - WRITE_UINT32 (bs, profile_idc, 8); - /* constraint_set0_flag */ - WRITE_UINT32 (bs, constraint_set0_flag, 1); - /* constraint_set1_flag */ - WRITE_UINT32 (bs, constraint_set1_flag, 1); - /* constraint_set2_flag */ - WRITE_UINT32 (bs, constraint_set2_flag, 1); - /* constraint_set3_flag */ - WRITE_UINT32 (bs, constraint_set3_flag, 1); - /* reserved_zero_4bits */ - WRITE_UINT32 (bs, 0, 4); - /* level_idc */ - WRITE_UINT32 (bs, seq_param->level_idc, 8); - /* seq_parameter_set_id */ - WRITE_UE (bs, seq_param->seq_parameter_set_id); - - if (profile == GST_VAAPI_PROFILE_H264_HIGH || - profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH || - profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { - /* for high profile */ - /* chroma_format_idc = 1, 4:2:0 */ - WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc); - if (3 == seq_param->seq_fields.bits.chroma_format_idc) { - WRITE_UINT32 (bs, residual_color_transform_flag, 1); - } - /* bit_depth_luma_minus8 */ - WRITE_UE (bs, seq_param->bit_depth_luma_minus8); - /* bit_depth_chroma_minus8 */ - WRITE_UE (bs, seq_param->bit_depth_chroma_minus8); - /* b_qpprime_y_zero_transform_bypass */ - WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1); - - /* seq_scaling_matrix_present_flag */ - g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0); - WRITE_UINT32 (bs, - seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1); - -#if 0 - if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) { - for (i = 0; - i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); - i++) { - gst_bit_writer_put_bits_uint8 (bs, - seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1); - if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) { - g_assert (0); - /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */ - } - } - } -#endif - } - - /* log2_max_frame_num_minus4 */ - WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4); - /* pic_order_cnt_type */ - WRITE_UE (bs, seq_param->seq_fields.bits.pic_order_cnt_type); - - if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) { - /* log2_max_pic_order_cnt_lsb_minus4 */ - WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4); - } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) { - g_assert (0 && "only POC type 0 is supported"); - WRITE_UINT32 (bs, - seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1); - WRITE_SE (bs, seq_param->offset_for_non_ref_pic); - WRITE_SE (bs, seq_param->offset_for_top_to_bottom_field); - WRITE_UE (bs, seq_param->num_ref_frames_in_pic_order_cnt_cycle); - for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) { - WRITE_SE (bs, seq_param->offset_for_ref_frame[i]); - } - } - - /* num_ref_frames */ - WRITE_UE (bs, seq_param->max_num_ref_frames); - /* gaps_in_frame_num_value_allowed_flag */ - WRITE_UINT32 (bs, gaps_in_frame_num_value_allowed_flag, 1); - - /* pic_width_in_mbs_minus1 */ - WRITE_UE (bs, seq_param->picture_width_in_mbs - 1); - /* pic_height_in_map_units_minus1 */ - WRITE_UE (bs, pic_height_in_map_units - 1); - /* frame_mbs_only_flag */ - WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1); - - if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs - g_assert (0 && "only progressive frames encoding is supported"); - WRITE_UINT32 (bs, mb_adaptive_frame_field, 1); - } - - /* direct_8x8_inference_flag */ - WRITE_UINT32 (bs, 0, 1); - /* frame_cropping_flag */ - WRITE_UINT32 (bs, seq_param->frame_cropping_flag, 1); - - if (seq_param->frame_cropping_flag) { - /* frame_crop_left_offset */ - WRITE_UE (bs, seq_param->frame_crop_left_offset); - /* frame_crop_right_offset */ - WRITE_UE (bs, seq_param->frame_crop_right_offset); - /* frame_crop_top_offset */ - WRITE_UE (bs, seq_param->frame_crop_top_offset); - /* frame_crop_bottom_offset */ - WRITE_UE (bs, seq_param->frame_crop_bottom_offset); - } - - /* vui_parameters_present_flag */ - WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1); - if (seq_param->vui_parameters_present_flag) { - /* aspect_ratio_info_present_flag */ - WRITE_UINT32 (bs, - seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1); - if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) { - WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8); - if (seq_param->aspect_ratio_idc == 0xFF) { - WRITE_UINT32 (bs, seq_param->sar_width, 16); - WRITE_UINT32 (bs, seq_param->sar_height, 16); - } - } - - /* overscan_info_present_flag */ - WRITE_UINT32 (bs, 0, 1); - /* video_signal_type_present_flag */ - WRITE_UINT32 (bs, 0, 1); - /* chroma_loc_info_present_flag */ - WRITE_UINT32 (bs, 0, 1); - - /* timing_info_present_flag */ - WRITE_UINT32 (bs, seq_param->vui_fields.bits.timing_info_present_flag, 1); - if (seq_param->vui_fields.bits.timing_info_present_flag) { - WRITE_UINT32 (bs, seq_param->num_units_in_tick, 32); - WRITE_UINT32 (bs, seq_param->time_scale, 32); - WRITE_UINT32 (bs, 1, 1); /* fixed_frame_rate_flag */ - } - - /* nal_hrd_parameters_present_flag */ - nal_hrd_parameters_present_flag = seq_param->bits_per_second > 0; - WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1); - if (nal_hrd_parameters_present_flag) { - /* hrd_parameters */ - /* cpb_cnt_minus1 */ - WRITE_UE (bs, 0); - WRITE_UINT32 (bs, SX_BITRATE - 6, 4); /* bit_rate_scale */ - WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4); /* cpb_size_scale */ - - for (i = 0; i < 1; ++i) { - /* bit_rate_value_minus1[0] */ - WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1); - /* cpb_size_value_minus1[0] */ - WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1); - /* cbr_flag[0] */ - WRITE_UINT32 (bs, 1, 1); - } - /* initial_cpb_removal_delay_length_minus1 */ - WRITE_UINT32 (bs, 23, 5); - /* cpb_removal_delay_length_minus1 */ - WRITE_UINT32 (bs, 23, 5); - /* dpb_output_delay_length_minus1 */ - WRITE_UINT32 (bs, 23, 5); - /* time_offset_length */ - WRITE_UINT32 (bs, 23, 5); - } - - /* vcl_hrd_parameters_present_flag */ - WRITE_UINT32 (bs, 0, 1); - - if (nal_hrd_parameters_present_flag - || 0 /*vcl_hrd_parameters_present_flag */ ) { - /* low_delay_hrd_flag */ - WRITE_UINT32 (bs, 0, 1); - } - /* pic_struct_present_flag */ - WRITE_UINT32 (bs, 1, 1); - /* bs_restriction_flag */ - WRITE_UINT32 (bs, 0, 1); - } - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write SPS NAL unit"); - return FALSE; - } -} - -static gboolean -bs_write_sps (GstVaapiFEIPakH264 * feipak, GstBitWriter * bs, - const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, - const VAEncMiscParameterHRD * hrd_params) -{ - if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) - return FALSE; - /* rbsp_trailing_bits */ - bs_write_trailing_bits (bs); - - return FALSE; -} - -static gboolean -bs_write_subset_sps (GstVaapiFEIPakH264 * feipak, GstBitWriter * bs, - const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile, - guint num_views, guint16 * view_ids, - const VAEncMiscParameterHRD * hrd_params) -{ - guint32 i, j, k; - - if (!bs_write_sps_data (bs, seq_param, profile, hrd_params)) - return FALSE; - - if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH || - profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH) { - guint32 num_views_minus1, num_level_values_signalled_minus1; - - num_views_minus1 = num_views - 1; - g_assert (num_views_minus1 < 1024); - - /* bit equal to one */ - WRITE_UINT32 (bs, 1, 1); - - WRITE_UE (bs, num_views_minus1); - - for (i = 0; i <= num_views_minus1; i++) - WRITE_UE (bs, view_ids[i]); - - for (i = 1; i <= num_views_minus1; i++) { - guint32 num_anchor_refs_l0 = 0; - guint32 num_anchor_refs_l1 = 0; - - WRITE_UE (bs, num_anchor_refs_l0); - for (j = 0; j < num_anchor_refs_l0; j++) - WRITE_UE (bs, 0); - - WRITE_UE (bs, num_anchor_refs_l1); - for (j = 0; j < num_anchor_refs_l1; j++) - WRITE_UE (bs, 0); - } - - for (i = 1; i <= num_views_minus1; i++) { - guint32 num_non_anchor_refs_l0 = 0; - guint32 num_non_anchor_refs_l1 = 0; - - WRITE_UE (bs, num_non_anchor_refs_l0); - for (j = 0; j < num_non_anchor_refs_l0; j++) - WRITE_UE (bs, 0); - - WRITE_UE (bs, num_non_anchor_refs_l1); - for (j = 0; j < num_non_anchor_refs_l1; j++) - WRITE_UE (bs, 0); - } - - /* num level values signalled minus1 */ - num_level_values_signalled_minus1 = 0; - g_assert (num_level_values_signalled_minus1 < 64); - WRITE_UE (bs, num_level_values_signalled_minus1); - - for (i = 0; i <= num_level_values_signalled_minus1; i++) { - guint16 num_applicable_ops_minus1 = 0; - g_assert (num_applicable_ops_minus1 < 1024); - - WRITE_UINT32 (bs, seq_param->level_idc, 8); - WRITE_UE (bs, num_applicable_ops_minus1); - - for (j = 0; j <= num_applicable_ops_minus1; j++) { - guint8 temporal_id = 0; - guint16 num_target_views_minus1 = 1; - - WRITE_UINT32 (bs, temporal_id, 3); - WRITE_UE (bs, num_target_views_minus1); - - for (k = 0; k <= num_target_views_minus1; k++) - WRITE_UE (bs, k); - - WRITE_UE (bs, num_views_minus1); - } - } - - /* mvc_vui_parameters_present_flag */ - WRITE_UINT32 (bs, 0, 1); - } - - /* additional_extension2_flag */ - WRITE_UINT32 (bs, 0, 1); - - /* rbsp_trailing_bits */ - bs_write_trailing_bits (bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write subset SPS NAL unit"); - return FALSE; - } - return FALSE; -} - -/* Write a PPS NAL unit */ -static gboolean -bs_write_pps (GstBitWriter * bs, - const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile) -{ - guint32 num_slice_groups_minus1 = 0; - guint32 pic_init_qs_minus26 = 0; - guint32 redundant_pic_cnt_present_flag = 0; - - /* pic_parameter_set_id */ - WRITE_UE (bs, pic_param->pic_parameter_set_id); - /* seq_parameter_set_id */ - WRITE_UE (bs, pic_param->seq_parameter_set_id); - /* entropy_coding_mode_flag */ - WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1); - /* pic_order_present_flag */ - WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_order_present_flag, 1); - /* slice_groups-1 */ - WRITE_UE (bs, num_slice_groups_minus1); - - if (num_slice_groups_minus1 > 0) { - /*FIXME*/ g_assert (0 && "unsupported arbitrary slice ordering (ASO)"); - } - WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1); - WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1); - WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1); - WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2); - /* pic_init_qp_minus26 */ - WRITE_SE (bs, pic_param->pic_init_qp - 26); - /* pic_init_qs_minus26 */ - WRITE_SE (bs, pic_init_qs_minus26); - /* chroma_qp_index_offset */ - WRITE_SE (bs, pic_param->chroma_qp_index_offset); - - WRITE_UINT32 (bs, - pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1); - WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1); - WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1); - - /* more_rbsp_data */ - if (profile == GST_VAAPI_PROFILE_H264_HIGH) { - WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1); - WRITE_UINT32 (bs, - pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1); - if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) { - g_assert (0 && "unsupported scaling lists"); - /* FIXME */ - /* - for (i = 0; i < - (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag)); - i++) { - gst_bit_writer_put_bits_uint8(bs, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1); - } - */ - } - WRITE_SE (bs, pic_param->second_chroma_qp_index_offset); - } - - /* rbsp_trailing_bits */ - bs_write_trailing_bits (bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write PPS NAL unit"); - return FALSE; - } -} - -/* Write a Slice NAL unit */ -static gboolean -bs_write_slice (GstBitWriter * bs, - const VAEncSliceParameterBufferH264 * slice_param, - GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture) -{ - const VAEncPictureParameterBufferH264 *const pic_param = picture->param; - guint32 field_pic_flag = 0; - guint32 ref_pic_list_modification_flag_l0 = 0; - guint32 ref_pic_list_modification_flag_l1 = 0; - guint32 no_output_of_prior_pics_flag = 0; - guint32 long_term_reference_flag = 0; - guint32 adaptive_ref_pic_marking_mode_flag = 0; - - /* first_mb_in_slice */ - WRITE_UE (bs, slice_param->macroblock_address); - /* slice_type */ - WRITE_UE (bs, slice_param->slice_type); - /* pic_parameter_set_id */ - WRITE_UE (bs, slice_param->pic_parameter_set_id); - /* frame_num */ - WRITE_UINT32 (bs, picture->frame_num, - feipak->h264_sps.seq_fields.bits.log2_max_frame_num_minus4 + 4); - - /* XXX: only frames (i.e. non-interlaced) are supported for now */ - /* frame_mbs_only_flag == 0 */ - - /* idr_pic_id */ - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) - WRITE_UE (bs, slice_param->idr_pic_id); - - /* XXX: only POC type 0 is supported */ - if (!feipak->h264_sps.seq_fields.bits.pic_order_cnt_type) { - WRITE_UINT32 (bs, slice_param->pic_order_cnt_lsb, - feipak->h264_sps.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4); - /* bottom_field_pic_order_in_frame_present_flag is FALSE */ - if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag) - WRITE_SE (bs, slice_param->delta_pic_order_cnt_bottom); - } else if (feipak->h264_sps.seq_fields.bits.pic_order_cnt_type == 1 && - !feipak->h264_sps.seq_fields.bits.delta_pic_order_always_zero_flag) { - WRITE_SE (bs, slice_param->delta_pic_order_cnt[0]); - if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag) - WRITE_SE (bs, slice_param->delta_pic_order_cnt[1]); - } - /* redundant_pic_cnt_present_flag is FALSE, no redundant coded pictures */ - - /* only works for B-frames */ - if (slice_param->slice_type == GST_H264_B_SLICE) - WRITE_UINT32 (bs, slice_param->direct_spatial_mv_pred_flag, 1); - - /* not supporting SP slices */ - if (slice_param->slice_type == 0 || slice_param->slice_type == 1) { - WRITE_UINT32 (bs, slice_param->num_ref_idx_active_override_flag, 1); - if (slice_param->num_ref_idx_active_override_flag) { - WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1); - if (slice_param->slice_type == 1) - WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1); - } - } - /* XXX: not supporting custom reference picture list modifications */ - if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4)) - WRITE_UINT32 (bs, ref_pic_list_modification_flag_l0, 1); - if (slice_param->slice_type == 1) - WRITE_UINT32 (bs, ref_pic_list_modification_flag_l1, 1); - - /* we have: weighted_pred_flag == FALSE and */ - /* : weighted_bipred_idc == FALSE */ - if ((pic_param->pic_fields.bits.weighted_pred_flag && - (slice_param->slice_type == 0)) || - ((pic_param->pic_fields.bits.weighted_bipred_idc == 1) && - (slice_param->slice_type == 1))) { - /* XXXX: add pred_weight_table() */ - } - - /* dec_ref_pic_marking() */ - if (slice_param->slice_type == 0 || slice_param->slice_type == 2) { - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { - /* no_output_of_prior_pics_flag = 0 */ - WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1); - /* long_term_reference_flag = 0 */ - WRITE_UINT32 (bs, long_term_reference_flag, 1); - } else { - /* only sliding_window reference picture marking mode is supported */ - /* adpative_ref_pic_marking_mode_flag = 0 */ - WRITE_UINT32 (bs, adaptive_ref_pic_marking_mode_flag, 1); - } - } - - /* cabac_init_idc */ - if (pic_param->pic_fields.bits.entropy_coding_mode_flag && - slice_param->slice_type != 2) - WRITE_UE (bs, slice_param->cabac_init_idc); - /*slice_qp_delta */ - WRITE_SE (bs, slice_param->slice_qp_delta); - - /* XXX: only supporting I, P and B type slices */ - /* no sp_for_switch_flag and no slice_qs_delta */ - - if (pic_param->pic_fields.bits.deblocking_filter_control_present_flag) { - /* disable_deblocking_filter_idc */ - WRITE_UE (bs, slice_param->disable_deblocking_filter_idc); - if (slice_param->disable_deblocking_filter_idc != 1) { - WRITE_SE (bs, slice_param->slice_alpha_c0_offset_div2); - WRITE_SE (bs, slice_param->slice_beta_offset_div2); - } - } - - /* XXX: unsupported arbitrary slice ordering (ASO) */ - /* num_slic_groups_minus1 should be zero */ - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write Slice NAL unit"); - return FALSE; - } -} - -static inline void -_check_sps_pps_status (GstVaapiFEIPakH264 * feipak, - const guint8 * nal, guint32 size) -{ - guint8 nal_type; - G_GNUC_UNUSED gsize ret; /* FIXME */ - gboolean has_subset_sps; - - g_assert (size); - - has_subset_sps = !feipak->is_mvc || (feipak->subset_sps_data != NULL); - if (feipak->sps_data && feipak->pps_data && has_subset_sps) - return; - - nal_type = nal[0] & 0x1F; - switch (nal_type) { - case GST_H264_NAL_SPS: - feipak->sps_data = gst_buffer_new_allocate (NULL, size, NULL); - ret = gst_buffer_fill (feipak->sps_data, 0, nal, size); - g_assert (ret == size); - break; - case GST_H264_NAL_SUBSET_SPS: - feipak->subset_sps_data = gst_buffer_new_allocate (NULL, size, NULL); - ret = gst_buffer_fill (feipak->subset_sps_data, 0, nal, size); - g_assert (ret == size); - break; - case GST_H264_NAL_PPS: - feipak->pps_data = gst_buffer_new_allocate (NULL, size, NULL); - ret = gst_buffer_fill (feipak->pps_data, 0, nal, size); - g_assert (ret == size); - break; - default: - break; - } -} - -/* Determines the largest supported profile by the underlying hardware */ -static gboolean -ensure_hw_profile_limits (GstVaapiFEIPakH264 * feipak) -{ - GstVaapiDisplay *const display = feipak->display; - GArray *profiles; - guint i, profile_idc, max_profile_idc; - - if (feipak->hw_max_profile_idc) - return TRUE; - - profiles = gst_vaapi_display_get_encode_profiles (display); - if (!profiles) - return FALSE; - - max_profile_idc = 0; - for (i = 0; i < profiles->len; i++) { - const GstVaapiProfile profile = - g_array_index (profiles, GstVaapiProfile, i); - profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile); - if (!profile_idc) - continue; - if (max_profile_idc < profile_idc) - max_profile_idc = profile_idc; - } - g_array_unref (profiles); - - feipak->hw_max_profile_idc = max_profile_idc; - return TRUE; -} - -/* Fills in VA HRD parameters */ -static void -fill_hrd_params (GstVaapiFEIPakH264 * feipak, VAEncMiscParameterHRD * hrd) -{ - hrd->buffer_size = 0; - hrd->initial_buffer_fullness = 0; -} - -/* Adds the supplied sequence header (SPS) to the list of packed - headers to pass down as-is to the feipak */ -static gboolean -add_packed_sequence_header (GstVaapiFEIPakH264 * feipak, - GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) -{ - GstVaapiEncPackedHeader *packed_seq; - GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 }; - const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; - GstVaapiProfile profile = feipak->profile; - - VAEncMiscParameterHRD hrd_params; - guint32 data_bit_size; - guint8 *data; - - fill_hrd_params (feipak, &hrd_params); - gst_bit_writer_init_with_size (&bs, 128, FALSE); - WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS); - /* Set High profile for encoding the MVC base view. Otherwise, some - traditional decoder cannot recognize MVC profile streams with - only the base view in there */ - if (profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH || - profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) - profile = GST_VAAPI_PROFILE_H264_HIGH; - - bs_write_sps (feipak, &bs, seq_param, profile, &hrd_params); - g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); - data = GST_BIT_WRITER_DATA (&bs); - - packed_seq_param.type = VAEncPackedHeaderSequence; - packed_seq_param.bit_length = data_bit_size; - packed_seq_param.has_emulation_bytes = 0; - - packed_seq = - gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder), - &packed_seq_param, sizeof (packed_seq_param), data, - (data_bit_size + 7) / 8); - g_assert (packed_seq); - - gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); - gst_vaapi_codec_object_replace (&packed_seq, NULL); - - /* store sps data */ - _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_reset (&bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write SPS NAL unit"); - gst_bit_writer_reset (&bs); - return FALSE; - } -} - -static gboolean -add_packed_sequence_header_mvc (GstVaapiFEIPakH264 * feipak, - GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence) -{ - GstVaapiEncPackedHeader *packed_seq; - GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; - const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; - VAEncMiscParameterHRD hrd_params; - guint32 data_bit_size; - guint8 *data; - - fill_hrd_params (feipak, &hrd_params); - - /* non-base layer, pack one subset sps */ - gst_bit_writer_init_with_size (&bs, 128, FALSE); - WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS); - - bs_write_subset_sps (feipak, &bs, seq_param, feipak->profile, - feipak->num_views, feipak->view_ids, &hrd_params); - - g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); - data = GST_BIT_WRITER_DATA (&bs); - - packed_header_param_buffer.type = VAEncPackedHeaderSequence; - packed_header_param_buffer.bit_length = data_bit_size; - packed_header_param_buffer.has_emulation_bytes = 0; - - packed_seq = - gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder), - &packed_header_param_buffer, sizeof (packed_header_param_buffer), data, - (data_bit_size + 7) / 8); - g_assert (packed_seq); - - gst_vaapi_enc_picture_add_packed_header (picture, packed_seq); - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL); - - /* store subset sps data */ - _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_reset (&bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write SPS NAL unit"); - gst_bit_writer_reset (&bs); - return FALSE; - } -} - -/* Adds the supplied picture header (PPS) to the list of packed - headers to pass down as-is to the feipak */ -static gboolean -add_packed_picture_header (GstVaapiFEIPakH264 * feipak, - GstVaapiEncPicture * picture) -{ - GstVaapiEncPackedHeader *packed_pic; - GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 }; - const VAEncPictureParameterBufferH264 *const pic_param = picture->param; - guint32 data_bit_size; - guint8 *data; - - gst_bit_writer_init_with_size (&bs, 128, FALSE); - WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS); - bs_write_pps (&bs, pic_param, feipak->profile); - g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); - data = GST_BIT_WRITER_DATA (&bs); - - packed_pic_param.type = VAEncPackedHeaderPicture; - packed_pic_param.bit_length = data_bit_size; - packed_pic_param.has_emulation_bytes = 0; - - packed_pic = - gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder), - &packed_pic_param, sizeof (packed_pic_param), data, - (data_bit_size + 7) / 8); - g_assert (packed_pic); - - gst_vaapi_enc_picture_add_packed_header (picture, packed_pic); - gst_vaapi_codec_object_replace (&packed_pic, NULL); - - /* store pps data */ - _check_sps_pps_status (feipak, data + 4, data_bit_size / 8 - 4); - gst_bit_writer_reset (&bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write PPS NAL unit"); - gst_bit_writer_reset (&bs); - return FALSE; - } -} - -static gboolean -get_nal_hdr_attributes (GstVaapiEncPicture * picture, - guint8 * nal_ref_idc, guint8 * nal_unit_type) -{ - switch (picture->type) { - case GST_VAAPI_PICTURE_TYPE_I: - *nal_ref_idc = GST_H264_NAL_REF_IDC_HIGH; - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) - *nal_unit_type = GST_H264_NAL_SLICE_IDR; - else - *nal_unit_type = GST_H264_NAL_SLICE; - break; - case GST_VAAPI_PICTURE_TYPE_P: - *nal_ref_idc = GST_H264_NAL_REF_IDC_MEDIUM; - *nal_unit_type = GST_H264_NAL_SLICE; - break; - case GST_VAAPI_PICTURE_TYPE_B: - *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE; - *nal_unit_type = GST_H264_NAL_SLICE; - break; - default: - return FALSE; - } - return TRUE; -} - -/* Adds the supplied prefix nal header to the list of packed - headers to pass down as-is to the feipak */ -static gboolean -add_packed_prefix_nal_header (GstVaapiFEIPakH264 * feipak, - GstVaapiEncPicture * picture, GstVaapiEncSlice * slice) -{ - GstVaapiEncPackedHeader *packed_prefix_nal; - GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_prefix_nal_param = { 0 }; - guint32 data_bit_size; - guint8 *data; - guint8 nal_ref_idc, nal_unit_type; - - gst_bit_writer_init_with_size (&bs, 128, FALSE); - WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - - if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) - goto bs_error; - nal_unit_type = GST_H264_NAL_PREFIX_UNIT; - - bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); - bs_write_nal_header_mvc_extension (&bs, picture, feipak->view_idx); - g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); - data = GST_BIT_WRITER_DATA (&bs); - - packed_prefix_nal_param.type = VAEncPackedHeaderRawData; - packed_prefix_nal_param.bit_length = data_bit_size; - packed_prefix_nal_param.has_emulation_bytes = 0; - - packed_prefix_nal = - gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder), - &packed_prefix_nal_param, sizeof (packed_prefix_nal_param), data, - (data_bit_size + 7) / 8); - g_assert (packed_prefix_nal); - - gst_vaapi_enc_slice_add_packed_header (slice, packed_prefix_nal); - gst_vaapi_codec_object_replace (&packed_prefix_nal, NULL); - - gst_bit_writer_reset (&bs); - - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write Prefix NAL unit header"); - gst_bit_writer_reset (&bs); - return FALSE; - } -} - -/* Adds the supplied slice header to the list of packed - headers to pass down as-is to the feipak */ -static gboolean -add_packed_slice_header (GstVaapiFEIPakH264 * feipak, - GstVaapiEncPicture * picture, GstVaapiEncSlice * slice) -{ - GstVaapiEncPackedHeader *packed_slice; - GstBitWriter bs; - VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 }; - const VAEncSliceParameterBufferH264 *const slice_param = slice->param; - guint32 data_bit_size; - guint8 *data; - guint8 nal_ref_idc, nal_unit_type; - - gst_bit_writer_init_with_size (&bs, 128, FALSE); - WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ - - if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type)) - goto bs_error; - /* pack nal_unit_header_mvc_extension() for the non base view */ - if (feipak->is_mvc && feipak->view_idx) { - bs_write_nal_header (&bs, nal_ref_idc, GST_H264_NAL_SLICE_EXT); - bs_write_nal_header_mvc_extension (&bs, picture, - feipak->view_ids[feipak->view_idx]); - } else - bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type); - - bs_write_slice (&bs, slice_param, feipak, picture); - data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); - data = GST_BIT_WRITER_DATA (&bs); - - packed_slice_param.type = VAEncPackedHeaderSlice; - packed_slice_param.bit_length = data_bit_size; - packed_slice_param.has_emulation_bytes = 0; - - packed_slice = - gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (feipak->encoder), - &packed_slice_param, sizeof (packed_slice_param), data, - (data_bit_size + 7) / 8); - g_assert (packed_slice); - - gst_vaapi_enc_slice_add_packed_header (slice, packed_slice); - gst_vaapi_codec_object_replace (&packed_slice, NULL); - - gst_bit_writer_reset (&bs); - return TRUE; - - /* ERRORS */ -bs_error: - { - GST_WARNING ("failed to write Slice NAL unit header"); - gst_bit_writer_reset (&bs); - return FALSE; - } -} - -/* Reference picture management */ -static void -reference_pic_free (GstVaapiFEIPakH264 * feipak, GstVaapiFEIPakH264Ref * ref) -{ - if (!ref) - return; - if (ref->pic) - gst_vaapi_surface_proxy_unref (ref->pic); - g_slice_free (GstVaapiFEIPakH264Ref, ref); -} - -static inline GstVaapiFEIPakH264Ref * -reference_pic_create (GstVaapiFEIPakH264 * feipak, - GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) -{ - GstVaapiFEIPakH264Ref *const ref = g_slice_new0 (GstVaapiFEIPakH264Ref); - - ref->pic = surface; - ref->frame_num = picture->frame_num; - ref->poc = picture->poc; - return ref; -} - -static gboolean -reference_list_update (GstVaapiFEIPakH264 * feipak, - GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface) -{ - GstVaapiFEIPakH264Ref *ref; - GstVaapiH264FEIPakViewRefPool *const ref_pool = - &feipak->ref_pools[feipak->view_idx]; - - if (GST_VAAPI_PICTURE_TYPE_B == picture->type) { - gst_vaapi_surface_proxy_unref (surface); - return TRUE; - } - if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) { - while (!g_queue_is_empty (&ref_pool->ref_list)) - reference_pic_free (feipak, g_queue_pop_head (&ref_pool->ref_list)); - } else if (g_queue_get_length (&ref_pool->ref_list) >= - ref_pool->max_ref_frames) { - reference_pic_free (feipak, g_queue_pop_head (&ref_pool->ref_list)); - } - ref = reference_pic_create (feipak, picture, surface); - g_queue_push_tail (&ref_pool->ref_list, ref); - g_assert (g_queue_get_length (&ref_pool->ref_list) <= - ref_pool->max_ref_frames); - return TRUE; -} - -static gboolean -reference_list_init (GstVaapiFEIPakH264 * feipak, - GstVaapiEncPicture * picture, - GstVaapiFEIPakH264Ref ** reflist_0, - guint * reflist_0_count, - GstVaapiFEIPakH264Ref ** reflist_1, guint * reflist_1_count) -{ - GstVaapiFEIPakH264Ref *tmp; - GstVaapiH264FEIPakViewRefPool *const ref_pool = - &feipak->ref_pools[feipak->view_idx]; - GList *iter, *list_0_start = NULL, *list_1_start = NULL; - guint count; - - *reflist_0_count = 0; - *reflist_1_count = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_I) - return TRUE; - - iter = g_queue_peek_tail_link (&ref_pool->ref_list); - for (; iter; iter = g_list_previous (iter)) { - tmp = (GstVaapiFEIPakH264Ref *) iter->data; - g_assert (tmp && tmp->poc != picture->poc); - if (_poc_greater_than (picture->poc, tmp->poc, - 1 << (feipak->h264_sps.seq_fields.bits. - log2_max_pic_order_cnt_lsb_minus4 + 4))) { - list_0_start = iter; - list_1_start = g_list_next (iter); - break; - } - } - - /* order reflist_0 */ - g_assert (list_0_start); - iter = list_0_start; - count = 0; - for (; iter; iter = g_list_previous (iter)) { - reflist_0[count] = (GstVaapiFEIPakH264Ref *) iter->data; - ++count; - } - *reflist_0_count = count; - - if (picture->type != GST_VAAPI_PICTURE_TYPE_B) - return TRUE; - - /* order reflist_1 */ - count = 0; - iter = list_1_start; - for (; iter; iter = g_list_next (iter)) { - reflist_1[count] = (GstVaapiFEIPakH264Ref *) iter->data; - ++count; - } - *reflist_1_count = count; - return TRUE; -} - -/* Fills in VA sequence parameter buffer */ -static gboolean -fill_sequence (GstVaapiFEIPakH264 * feipak, GstVaapiEncSequence * sequence) -{ - VAEncSequenceParameterBufferH264 *const seq_param = sequence->param; - - memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264)); - *seq_param = feipak->h264_sps; - return TRUE; -} - -/* Fills in VA picture parameter buffer */ -static gboolean -fill_picture (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture, - GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface) -{ - VAEncPictureParameterBufferH264 *const pic_param = picture->param; - GstVaapiH264FEIPakViewRefPool *const ref_pool = - &feipak->ref_pools[feipak->view_idx]; - GstVaapiFEIPakH264Ref *ref_pic; - GList *reflist; - guint i; - - memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264)); - *pic_param = feipak->h264_pps; - feipak->is_idr = feipak->h264_pps.pic_fields.bits.idr_pic_flag; - /* reference list, */ - pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface); - pic_param->CurrPic.TopFieldOrderCnt = picture->poc; - pic_param->CurrPic.frame_idx = picture->frame_num; - i = 0; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { - for (reflist = g_queue_peek_head_link (&ref_pool->ref_list); - reflist; reflist = g_list_next (reflist)) { - ref_pic = reflist->data; - g_assert (ref_pic && ref_pic->pic && - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID); - - pic_param->ReferenceFrames[i].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic); - pic_param->ReferenceFrames[i].TopFieldOrderCnt = ref_pic->poc; - pic_param->ReferenceFrames[i].flags |= - VA_PICTURE_H264_SHORT_TERM_REFERENCE; - pic_param->ReferenceFrames[i].frame_idx = ref_pic->frame_num; - ++i; - } - g_assert (i <= 16 && i <= ref_pool->max_ref_frames); - } - for (; i < 16; ++i) { - pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID; - pic_param->ReferenceFrames[i].frame_idx = VA_PICTURE_H264_INVALID; - } - pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf); - - return TRUE; -} - -/* Adds slice headers to picture */ -static gboolean -add_slice_headers (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture, - GstVaapiFEIPakH264Ref ** reflist_0, guint reflist_0_count, - GstVaapiFEIPakH264Ref ** reflist_1, guint reflist_1_count) -{ - VAEncSliceParameterBufferH264 *slice_param; - GstVaapiEncSlice *slice; - guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs; - guint mb_size; - guint last_mb_index; - guint i_slice, i_ref; - GArray *h264_slice_params = feipak->h264_slice_params; - - g_assert (picture); - - mb_size = feipak->mb_width * feipak->mb_height; - - g_assert (feipak->num_slices && feipak->num_slices < mb_size); - slice_of_mbs = mb_size / feipak->num_slices; - slice_mod_mbs = mb_size % feipak->num_slices; - last_mb_index = 0; - for (i_slice = 0; i_slice < feipak->num_slices; ++i_slice) { - cur_slice_mbs = slice_of_mbs; - if (slice_mod_mbs) { - ++cur_slice_mbs; - --slice_mod_mbs; - } - slice = GST_VAAPI_ENC_SLICE_NEW (H264, feipak->encoder); - g_assert (slice && slice->param_id != VA_INVALID_ID); - slice_param = slice->param; - - memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264)); - *slice_param = - g_array_index (h264_slice_params, VAEncSliceParameterBufferH264, - i_slice); - g_assert ((gint8) slice_param->slice_type != -1); - g_assert (slice_param->num_ref_idx_l0_active_minus1 >= 0); - g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0); - - i_ref = 0; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { - for (; i_ref < reflist_0_count; ++i_ref) { - slice_param->RefPicList0[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); - slice_param->RefPicList0[i_ref].TopFieldOrderCnt = - reflist_0[i_ref]->poc; - slice_param->RefPicList0[i_ref].flags |= - VA_PICTURE_H264_SHORT_TERM_REFERENCE; - slice_param->RefPicList0[i_ref].frame_idx = reflist_0[i_ref]->frame_num; - } - g_assert (i_ref >= 1); - } - for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) { - slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE; - slice_param->RefPicList0[i_ref].frame_idx = VA_PICTURE_H264_INVALID; - } - - i_ref = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { - for (; i_ref < reflist_1_count; ++i_ref) { - slice_param->RefPicList1[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); - slice_param->RefPicList1[i_ref].TopFieldOrderCnt = - reflist_1[i_ref]->poc; - slice_param->RefPicList1[i_ref].flags |= - VA_PICTURE_H264_SHORT_TERM_REFERENCE; - slice_param->RefPicList1[i_ref].frame_idx = reflist_1[i_ref]->frame_num; - } - g_assert (i_ref == 1); - } - for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) { - slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE; - slice_param->RefPicList1[i_ref].frame_idx = VA_PICTURE_H264_INVALID; - } - - /* set calculation for next slice */ - last_mb_index += cur_slice_mbs; - - /* add packed Prefix NAL unit before each Coded slice NAL in base view */ - if (feipak->is_mvc && !feipak->view_idx - && !add_packed_prefix_nal_header (feipak, picture, slice)) - goto error_create_packed_prefix_nal_hdr; - if (!add_packed_slice_header (feipak, picture, slice)) - goto error_create_packed_slice_hdr; - - gst_vaapi_enc_picture_add_slice (picture, slice); - gst_vaapi_codec_object_replace (&slice, NULL); - } - g_assert (last_mb_index == mb_size); - return TRUE; - -error_create_packed_slice_hdr: - { - GST_ERROR ("failed to create packed slice header buffer"); - gst_vaapi_codec_object_replace (&slice, NULL); - return FALSE; - } -error_create_packed_prefix_nal_hdr: - { - GST_ERROR ("failed to create packed prefix nal header buffer"); - gst_vaapi_codec_object_replace (&slice, NULL); - return FALSE; - } -} - -/* Generates and submits SPS header accordingly into the bitstream */ -static gboolean -ensure_sequence (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture) -{ - GstVaapiEncSequence *sequence = NULL; - - if (!feipak->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I) - return TRUE; - - sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, feipak->encoder); - if (!sequence || !fill_sequence (feipak, sequence)) - goto error_create_seq_param; - - /* add subset sps for non-base view and sps for base view */ - if (feipak->is_mvc && feipak->view_idx) { - if (!add_packed_sequence_header_mvc (feipak, picture, sequence)) - goto error_create_packed_seq_hdr; - } else { - if (!add_packed_sequence_header (feipak, picture, sequence)) - goto error_create_packed_seq_hdr; - } - - if (sequence) { - gst_vaapi_enc_picture_set_sequence (picture, sequence); - gst_vaapi_codec_object_replace (&sequence, NULL); - } - - if (!feipak->is_mvc || feipak->view_idx > 0) - feipak->config_changed = FALSE; - return TRUE; - - /* ERRORS */ -error_create_seq_param: - { - GST_ERROR ("failed to create sequence parameter buffer (SPS)"); - gst_vaapi_codec_object_replace (&sequence, NULL); - return FALSE; - } -error_create_packed_seq_hdr: - { - GST_ERROR ("failed to create packed sequence header buffer"); - gst_vaapi_codec_object_replace (&sequence, NULL); - return FALSE; - } -} - -/* Generates additional fei control parameters */ -static gboolean -ensure_fei_misc_params (GstVaapiFEIPakH264 * feipak, - GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy) -{ - GstVaapiEncMiscParam *misc = NULL; - VAEncMiscParameterFEIFrameControlH264 *misc_fei_pic_control_param; - - /*fei pic control params */ - misc = GST_VAAPI_ENC_FEI_MISC_PARAM_NEW (H264, feipak->encoder); - g_assert (misc); - if (!misc) - return FALSE; - - misc_fei_pic_control_param = misc->data; - misc_fei_pic_control_param->function = VA_FEI_FUNCTION_PAK; - misc_fei_pic_control_param->mv_predictor = VA_INVALID_ID; - misc_fei_pic_control_param->qp = VA_INVALID_ID; - misc_fei_pic_control_param->mb_ctrl = VA_INVALID_ID; - - g_assert (codedbuf_proxy->mbcode != NULL); - g_assert (codedbuf_proxy->mv != NULL); - - misc_fei_pic_control_param->mb_code_data = - GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mbcode)->param_id; - misc_fei_pic_control_param->mv_data = - GST_VAAPI_FEI_CODEC_OBJECT (codedbuf_proxy->mv)->param_id; - - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - return TRUE; -} - -/* Generates additional control parameters */ -static gboolean -ensure_misc_params (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture) -{ - GstVaapiEncMiscParam *misc = NULL; - - /* HRD params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, feipak->encoder); - g_assert (misc); - if (!misc) - return FALSE; - fill_hrd_params (feipak, misc->data); - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - - return TRUE; -} - -/* Generates and submits PPS header accordingly into the bitstream */ -static gboolean -ensure_picture (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture, - GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) -{ - GstVaapiCodedBuffer *const codedbuf = - GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); - gboolean res = FALSE; - res = fill_picture (feipak, picture, codedbuf, surface); - - if (!res) - return FALSE; - - if (picture->type == GST_VAAPI_PICTURE_TYPE_I - && !add_packed_picture_header (feipak, picture)) { - GST_ERROR ("set picture packed header failed"); - return FALSE; - } - return TRUE; -} - -/* Generates slice headers */ -static gboolean -ensure_slices (GstVaapiFEIPakH264 * feipak, GstVaapiEncPicture * picture) -{ - GstVaapiFEIPakH264Ref *reflist_0[16]; - GstVaapiFEIPakH264Ref *reflist_1[16]; - GstVaapiH264FEIPakViewRefPool *const ref_pool = - &feipak->ref_pools[feipak->view_idx]; - guint reflist_0_count = 0, reflist_1_count = 0; - - g_assert (picture); - - if (picture->type != GST_VAAPI_PICTURE_TYPE_I && - !reference_list_init (feipak, picture, - reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) { - GST_ERROR ("reference list reorder failed"); - return FALSE; - } - - g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames); - if (reflist_0_count > ref_pool->max_reflist0_count) - reflist_0_count = ref_pool->max_reflist0_count; - if (reflist_1_count > ref_pool->max_reflist1_count) - reflist_1_count = ref_pool->max_reflist1_count; - - if (!add_slice_headers (feipak, picture, - reflist_0, reflist_0_count, reflist_1, reflist_1_count)) - return FALSE; - - return TRUE; -} - -/* Constructs profile and level information based on user-defined limits */ -static GstVaapiEncoderStatus -ensure_profile_and_level (GstVaapiFEIPakH264 * feipak) -{ - const GstVaapiProfile profile = feipak->profile; - - /* Check HW constraints */ - if (!ensure_hw_profile_limits (feipak)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - if (feipak->profile_idc > feipak->hw_max_profile_idc) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - - if (feipak->profile != profile) { - feipak->config_changed = TRUE; - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -static void -reset_properties (GstVaapiFEIPakH264 * feipak) -{ - guint i; - guint max_reflist0_count; - if (feipak->num_bframes > 0) { - if (feipak->num_ref_frames == 1) { - GST_INFO ("num ref frames is modified as 2 as b frame is set"); - feipak->num_ref_frames = 2; - } - max_reflist0_count = feipak->num_ref_frames - 1; - } else { - max_reflist0_count = feipak->num_ref_frames; - } - max_reflist0_count = max_reflist0_count > 5 ? 5 : max_reflist0_count; - - for (i = 0; i < feipak->num_views; i++) { - GstVaapiH264FEIPakViewRefPool *const ref_pool = &feipak->ref_pools[i]; - - ref_pool->max_reflist0_count = max_reflist0_count; - ref_pool->max_reflist1_count = feipak->num_bframes > 0; - ref_pool->max_ref_frames = ref_pool->max_reflist0_count - + ref_pool->max_reflist1_count; - - } -} - -GstVaapiEncoderStatus -gst_vaapi_feipak_h264_encode (GstVaapiFEIPakH264 * feipak, - GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf, - GstVaapiSurfaceProxy * surface, GstVaapiFeiInfoToPakH264 * info_to_pak) -{ - GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; - GstVaapiSurfaceProxy *reconstruct = surface; - GstVaapiSurfaceProxy *proxy = picture->proxy; - VAEncSliceParameterBufferH264 slice_header; - - g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct)); - g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (proxy)); - - g_assert (info_to_pak != NULL); - - feipak->h264_sps = info_to_pak->h264_enc_sps; - feipak->h264_pps = info_to_pak->h264_enc_pps; - feipak->h264_slice_params = info_to_pak->h264_slice_headers; - - feipak->mb_width = feipak->h264_sps.picture_width_in_mbs; - feipak->mb_height = feipak->h264_sps.picture_height_in_mbs; - - slice_header = - g_array_index (feipak->h264_slice_params, VAEncSliceParameterBufferH264, - 0); - feipak->slice_type = slice_header.slice_type; - - if (!ensure_sequence (feipak, picture)) - goto error; - if (!ensure_misc_params (feipak, picture)) - goto error; - if (!ensure_fei_misc_params (feipak, picture, codedbuf)) - goto error; - if (!ensure_picture (feipak, picture, codedbuf, reconstruct)) - goto error; - if (!ensure_slices (feipak, picture)) - goto error; - if (!gst_vaapi_enc_picture_encode (picture)) - goto error; - - if (!reference_list_update (feipak, picture, reconstruct)) - goto error; - - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -error: - return ret; -} - -GstVaapiEncoderStatus -gst_vaapi_feipak_h264_flush (GstVaapiFEIPakH264 * feipak) -{ - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -GstVaapiEncoderStatus -gst_vaapi_feipak_h264_reconfigure (GstVaapiFEIPakH264 * feipak, - VAContextID va_context, GstVaapiProfile profile, - guint8 profile_idc, guint mb_width, guint mb_height, - guint32 num_views, guint slices_num, guint32 num_ref_frames) -{ - GstVaapiEncoderStatus status; - - if (mb_width != feipak->mb_width || mb_height != feipak->mb_height) { - feipak->mb_width = mb_width; - feipak->mb_height = mb_height; - feipak->config_changed = TRUE; - } - - feipak->va_context = va_context; - - /* Take number of MVC views from input caps if provided */ - feipak->num_views = num_views; - - feipak->is_mvc = feipak->num_views > 1; - - feipak->profile_idc = profile_idc; - feipak->profile = profile; - feipak->num_slices = slices_num; - feipak->num_ref_frames = num_ref_frames; - - status = ensure_profile_and_level (feipak); - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return status; - - reset_properties (feipak); - - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -static gboolean -gst_vaapi_feipak_h264_init (GstVaapiFEIPakH264 * feipak, - GstVaapiEncoder * encoder, GstVaapiDisplay * display, - VAContextID va_context) -{ - guint32 i; - - feipak->encoder = encoder; - /* Default encoding entrypoint */ - feipak->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI; - - feipak->h264_slice_params = NULL; - - /* Multi-view coding information */ - feipak->is_mvc = FALSE; - feipak->num_views = 1; - feipak->view_idx = 0; - feipak->display = display; - feipak->va_context = va_context; - - feipak->num_bframes = 0; - feipak->is_idr = FALSE; - /* default num ref frames */ - feipak->num_ref_frames = 1; - memset (feipak->view_ids, 0, sizeof (feipak->view_ids)); - - feipak->props_reconfigured = FALSE; - - /* reference list info initialize */ - for (i = 0; i < MAX_NUM_VIEWS; i++) { - GstVaapiH264FEIPakViewRefPool *const ref_pool = &feipak->ref_pools[i]; - g_queue_init (&ref_pool->ref_list); - ref_pool->max_ref_frames = 0; - ref_pool->max_reflist0_count = 1; - ref_pool->max_reflist1_count = 1; - } - - return TRUE; -} - -static void -gst_vaapi_feipak_h264_finalize (GstVaapiFEIPakH264 * feipak) -{ - GstVaapiFEIPakH264Ref *ref; - guint32 i; - - gst_buffer_replace (&feipak->sps_data, NULL); - gst_buffer_replace (&feipak->subset_sps_data, NULL); - gst_buffer_replace (&feipak->pps_data, NULL); - - /* reference list info de-init */ - for (i = 0; i < MAX_NUM_VIEWS; i++) { - GstVaapiH264FEIPakViewRefPool *const ref_pool = &feipak->ref_pools[i]; - while (!g_queue_is_empty (&ref_pool->ref_list)) { - ref = (GstVaapiFEIPakH264Ref *) g_queue_pop_head (&ref_pool->ref_list); - reference_pic_free (feipak, ref); - } - g_queue_clear (&ref_pool->ref_list); - } - -} - -static void -set_view_ids (GstVaapiFEIPakH264 * feipak, const GValue * value) -{ - guint i, j; - guint len = gst_value_array_get_size (value); - - if (len == 0) - goto set_default_ids; - - if (len != feipak->num_views) { - GST_WARNING ("The view number is %d, but %d view IDs are provided. Just " - "fallback to use default view IDs.", feipak->num_views, len); - goto set_default_ids; - } - - for (i = 0; i < len; i++) { - const GValue *val = gst_value_array_get_value (value, i); - feipak->view_ids[i] = g_value_get_uint (val); - } - - /* check whether duplicated ID */ - for (i = 0; i < len; i++) { - for (j = i + 1; j < len; j++) { - if (feipak->view_ids[i] == feipak->view_ids[j]) { - GST_WARNING ("The view %d and view %d have same view ID %d. Just " - "fallback to use default view IDs.", i, j, feipak->view_ids[i]); - goto set_default_ids; - } - } - } - - return; - -set_default_ids: - { - for (i = 0; i < feipak->num_views; i++) - feipak->view_ids[i] = i; - } -} - -GstVaapiEncoderStatus -gst_vaapi_feipak_h264_set_property (GstVaapiFEIPakH264 * feipak, - gint prop_id, const GValue * value) -{ - - switch (prop_id) { - case GST_VAAPI_FEIPAK_H264_PROP_MAX_BFRAMES: - feipak->num_bframes = g_value_get_uint (value); - break; - case GST_VAAPI_FEIPAK_H264_PROP_NUM_VIEWS: - feipak->num_views = g_value_get_uint (value); - break; - case GST_VAAPI_FEIPAK_H264_PROP_VIEW_IDS: - set_view_ids (feipak, value); - break; - default: - return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; - } - return GST_VAAPI_ENCODER_STATUS_SUCCESS; -} - -static inline const GstVaapiMiniObjectClass * -gst_vaapi_feipak_h264_class (void) -{ - static const GstVaapiMiniObjectClass GstVaapiFEIPakH264Class = { - .size = sizeof (GstVaapiFEIPakH264), - .finalize = (GDestroyNotify) gst_vaapi_feipak_h264_finalize - }; - return &GstVaapiFEIPakH264Class; -} - -/** - * gst_vaapi_feipak_h264_new: - * @display: a #GstVaapiDisplay - * - * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the - * only supported output stream format is "byte-stream" format. - * - * Return value: the newly allocated #GstVaapiEncoder object - */ -GstVaapiFEIPakH264 * -gst_vaapi_feipak_h264_new (GstVaapiEncoder * encoder, GstVaapiDisplay * display, - VAContextID va_context) -{ - GstVaapiFEIPakH264 *feipak; - - feipak = (GstVaapiFEIPakH264 *) - gst_vaapi_mini_object_new0 (GST_VAAPI_MINI_OBJECT_CLASS - (gst_vaapi_feipak_h264_class ())); - if (!feipak) - return NULL; - - if (!gst_vaapi_feipak_h264_init (feipak, encoder, display, va_context)) - goto error; - return feipak; - -error: - gst_vaapi_object_unref (feipak); - return NULL; -} - -gboolean -gst_vaapi_feipak_h264_get_ref_pool (GstVaapiFEIPakH264 * feipak, - gpointer * ref_pool_ptr) -{ - g_return_val_if_fail (feipak != NULL, FALSE); - if (!(&feipak->ref_pools[0])) - return FALSE; - - if (ref_pool_ptr) - *ref_pool_ptr = (gpointer) (&feipak->ref_pools[0]); - - return TRUE; -} diff --git a/gst-libs/gst/vaapi/gstvaapifeipak_h264.h b/gst-libs/gst/vaapi/gstvaapifeipak_h264.h deleted file mode 100644 index f257becc1c..0000000000 --- a/gst-libs/gst/vaapi/gstvaapifeipak_h264.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * gstvaapifeipak_h264.h - H.264 FEI PAK - * - * Copyright (C) 2016-2018 Intel Corporation - * Author: Chen Xiaomin - * Author: Sreerenj Balachandran - * - * 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_FEIPAK_H264_H -#define GST_VAAPI_FEIPAK_H264_H - -#include -#include -#include -#include - -G_BEGIN_DECLS - -typedef struct _GstVaapiFEIPakH264 GstVaapiFEIPakH264; - -/** - * GstVaapiEncoderH264Prop: - * @GST_VAAPI_FEIPAK_H264_PROP_MAX_BFRAMES: Number of B-frames between I - * and P (uint). - * @GST_VAAPI_FEIPAK_H264_PROP_INIT_QP: Initial quantizer value (uint). - * @GST_VAAPI_FEIPAK_H264_PROP_MIN_QP: Minimal quantizer value (uint). - * @GST_VAAPI_FEIPAK_H264_PROP_NUM_SLICES: Number of slices per frame (uint). - * @GST_VAAPI_FEIPAK_H264_PROP_CABAC: Enable CABAC entropy coding mode (bool). - * @GST_VAAPI_FEIPAK_H264_PROP_DCT8X8: Enable adaptive use of 8x8 - * transforms in I-frames (bool). - * @GST_VAAPI_FEIPAK_H264_PROP_CPB_LENGTH: Length of the CPB buffer - * in milliseconds (uint). - * @GST_VAAPI_FEIPAK_H264_PROP_NUM_VIEWS: Number of views per frame. - * @GST_VAAPI_FEIPAK_H264_PROP_VIEW_IDS: View IDs - * - * The set of H.264 feipak specific configurable properties. - */ -typedef enum -{ - GST_VAAPI_FEIPAK_H264_PROP_MAX_BFRAMES = -1, - GST_VAAPI_FEIPAK_H264_PROP_INIT_QP = -2, - GST_VAAPI_FEIPAK_H264_PROP_MIN_QP = -3, - GST_VAAPI_FEIPAK_H264_PROP_NUM_SLICES = -4, - GST_VAAPI_FEIPAK_H264_PROP_CABAC = -5, - GST_VAAPI_FEIPAK_H264_PROP_DCT8X8 = -6, - GST_VAAPI_FEIPAK_H264_PROP_CPB_LENGTH = -7, - GST_VAAPI_FEIPAK_H264_PROP_NUM_VIEWS = -8, - GST_VAAPI_FEIPAK_H264_PROP_VIEW_IDS = -9, - GST_VAAPI_FEIPAK_H264_PROP_NUM_REF = -10, -} GstVaapiFEIPakH264Prop; - -GstVaapiEncoderStatus -gst_vaapi_feipak_h264_reconfigure (GstVaapiFEIPakH264 * feipak, - VAContextID va_context, GstVaapiProfile profile, guint8 profile_idc, - guint mb_width, guint mb_height, guint32 num_views, guint slices_num, - guint32 num_ref_frames); - -GstVaapiEncoderStatus -gst_vaapi_feipak_h264_encode (GstVaapiFEIPakH264 * feipak, - GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf, - GstVaapiSurfaceProxy * surface, GstVaapiFeiInfoToPakH264 *info_to_pak); - -GstVaapiEncoderStatus -gst_vaapi_feipak_h264_flush (GstVaapiFEIPakH264 * feipak); - -GstVaapiFEIPakH264 *gst_vaapi_feipak_h264_new (GstVaapiEncoder * encoder, - GstVaapiDisplay * display, VAContextID va_context); - -GstVaapiEncoderStatus -gst_vaapi_feipak_h264_set_property (GstVaapiFEIPakH264 * feipak, - gint prop_id, const GValue * value); - -gboolean -gst_vaapi_feipak_h264_get_ref_pool (GstVaapiFEIPakH264 * feipak, - gpointer * ref_pool_ptr); - -G_END_DECLS - -#endif /*GST_VAAPI_FEIPAK_H264_H */ diff --git a/gst-libs/gst/vaapi/gstvaapifeiutils_h264.c b/gst-libs/gst/vaapi/gstvaapifeiutils_h264.c deleted file mode 100644 index 38411a7268..0000000000 --- a/gst-libs/gst/vaapi/gstvaapifeiutils_h264.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * gstvaapifeiutils_h264_fei.c - Fei related utilities for H264 - * - * Copyright (C) 2016-2018 Intel Corporation - * Author: Wang, Yi - * Author: Sreerenj Balachandran - * - * 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 - -#include "gstvaapifeiutils_h264.h" - -/* FeiFixme: This is common fei modes for all codecs, - * move to a generic header file */ -/* --- GstVaapiFeiMode --- */ -GType -gst_vaapi_fei_mode_get_type (void) -{ - static volatile gsize g_type = 0; - - static const GFlagsValue encoding_mode_values[] = { - {GST_VAAPI_FEI_MODE_ENC, - "ENC Mode", "ENC"}, - {GST_VAAPI_FEI_MODE_PAK, - "PAK Mode", "PAK"}, - {GST_VAAPI_FEI_MODE_ENC_PAK, - "ENC_PAK Mode", "ENC_PAK"}, - {0, NULL, NULL}, - }; - - if (g_once_init_enter (&g_type)) { - GType type = - g_flags_register_static ("GstVaapiFeiMode", encoding_mode_values); - g_once_init_leave (&g_type, type); - } - return g_type; -} - -/* --- GstVaapiFeiH264SearchPath --- */ -GType -gst_vaapi_fei_h264_search_path_get_type (void) -{ - static volatile gsize g_type = 0; - - static const GEnumValue search_path_values[] = { - {GST_VAAPI_FEI_H264_FULL_SEARCH_PATH, - "full search path", "full"}, - {GST_VAAPI_FEI_H264_DIAMOND_SEARCH_PATH, - "diamond search path", "diamond"}, - {0, NULL, NULL}, - }; - - if (g_once_init_enter (&g_type)) { - GType type = g_enum_register_static ("GstVaapiFeiH264SearchPath", - search_path_values); - g_once_init_leave (&g_type, type); - } - return g_type; -} - -/* --- GstVaapiFeiH264SearchWindow --- */ -GType -gst_vaapi_fei_h264_search_window_get_type (void) -{ - static volatile gsize g_type = 0; - - static const GEnumValue search_window_values[] = { - {GST_VAAPI_FEI_H264_SEARCH_WINDOW_NONE, - "not use predefined search window", "none"}, - {GST_VAAPI_FEI_H264_SEARCH_WINDOW_TINY, - "4 SUs 24x24 window diamond search", "tiny"}, - {GST_VAAPI_FEI_H264_SEARCH_WINDOW_SMALL, - "9 SUs 28x28 window diamond search", "small"}, - {GST_VAAPI_FEI_H264_SEARCH_WINDOW_DIAMOND, - "16 SUs 48x40 window diamond search", "diamond"}, - {GST_VAAPI_FEI_H264_SEARCH_WINDOW_LARGE_DIAMOND, - "32 SUs 48x40 window diamond search", "large diamond"}, - {GST_VAAPI_FEI_H264_SEARCH_WINDOW_EXHAUSTIVE, - "48 SUs 48x40 window full search", "exhaustive"}, - {GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_DIAMOND, - "16 SUs 64x32 window diamond search", "horizon diamond"}, - {GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_LARGE_DIAMOND, - "32 SUs 64x32 window diamond search", "horizon large diamond"}, - {GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_EXHAUSTIVE, - "48 SUs 64x32 window full search", "horizon exhaustive"}, - {0, NULL, NULL}, - }; - - if (g_once_init_enter (&g_type)) { - GType type = g_enum_register_static ("GstVaapiFeiH264SearchWindow", - search_window_values); - g_once_init_leave (&g_type, type); - } - return g_type; -} - -/* --- GstVaapiFeiH264SubPelMode --- */ -GType -gst_vaapi_fei_h264_sub_pel_mode_get_type (void) -{ - static volatile gsize g_type = 0; - - static const GEnumValue sub_pel_mode_values[] = { - {GST_VAAPI_FEI_H264_INTEGER_ME, - "integer mode searching", "integer"}, - {GST_VAAPI_FEI_H264_HALF_ME, - "half-pel mode searching", "half"}, - {GST_VAAPI_FEI_H264_QUARTER_ME, - "quarter-pel mode searching", "quarter"}, - {0, NULL, NULL}, - }; - - if (g_once_init_enter (&g_type)) { - GType type = g_enum_register_static ("GstVaapiFeiH264SubPelMode", - sub_pel_mode_values); - g_once_init_leave (&g_type, type); - } - return g_type; -} - -/* --- GstVaapiFeiH264SadMode --- */ -GType -gst_vaapi_fei_h264_sad_mode_get_type (void) -{ - static volatile gsize g_type = 0; - - static const GEnumValue sad_mode_values[] = { - {GST_VAAPI_FEI_H264_SAD_NONE_TRANS, - "none transform adjusted", "none"}, - {GST_VAAPI_FEI_H264_SAD_HAAR_TRANS, - "Haar transform adjusted", "haar"}, - {0, NULL, NULL}, - }; - - if (g_once_init_enter (&g_type)) { - GType type = - g_enum_register_static ("GstVaapiFeiH264SadMode", sad_mode_values); - g_once_init_leave (&g_type, type); - } - return g_type; -} - -/* --- GstVaapiFeiH264IntraPartMask --- */ -GType -gst_vaapi_fei_h264_intra_part_mask_get_type (void) -{ - static volatile gsize g_type = 0; - - static const GFlagsValue intra_part_mask_values[] = { - {GST_VAAPI_FEI_H264_DISABLE_INTRA_NONE, - "enable all intra mode", "enable all"}, - {GST_VAAPI_FEI_H264_DISABLE_INTRA_16x16, - "luma_intra_16x16 disabled", "intra16x16 disabled"}, - {GST_VAAPI_FEI_H264_DISABLE_INTRA_8x8, - "luma_intra_8x8 disabled", "intra8x8 disabled"}, - {GST_VAAPI_FEI_H264_DISABLE_INTRA_4x4, - "luma_intra_4x4 disabled", "intra4x4 disabled"}, - {0, NULL, NULL}, - }; - - if (g_once_init_enter (&g_type)) { - GType type = g_flags_register_static ("GstVaapiFeiH264IntraPartMask", - intra_part_mask_values); - g_once_init_leave (&g_type, type); - } - return g_type; -} - -/* --- GstVaapiFeiH264SubMbPartMask --- */ -GType -gst_vaapi_fei_h264_sub_mb_part_mask_get_type (void) -{ - static volatile gsize g_type = 0; - - static const GFlagsValue sub_mb_part_mask_values[] = { - {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_NONE, - "enable all subpartitions", "enable all"}, - {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_16x16, - "16x16 sub-macroblock disabled", "16x16 submb part disabled"}, - {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x16x8, - "2x(16x8) sub-macroblock within 16x16 disabled", - "16x8 submb part disabled"}, - {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x16, - "2x(8x16) sub-macroblock within 16x16 disabled", - "8x16 submb part disabled"}, - {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_1x8x8, - "1x(8x8) sub-partition for 4x(8x8) within 16x16 disabled", - "8x8 submb part disabled"}, - {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x4, - "2x(8x4) sub-partition for 4x(8x8) within 16x16 disabled", - "8x4 submb part disabled"}, - {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x4x8, - "2x(4x8) sub-partition for 4x(8x8) within 16x16 disabled", - "4x8 submb part disabled"}, - {GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_4x4x4, - "4x(4x4) sub-partition for 4x(8x8) within 16x16 disabled", - "4x4 submb part disabled"}, - {0, NULL, NULL}, - }; - - if (g_once_init_enter (&g_type)) { - GType type = g_flags_register_static ("GstVaapiFeiH264SubMbPartMask", - sub_mb_part_mask_values); - g_once_init_leave (&g_type, type); - } - return g_type; -} diff --git a/gst-libs/gst/vaapi/gstvaapifeiutils_h264.h b/gst-libs/gst/vaapi/gstvaapifeiutils_h264.h deleted file mode 100644 index a0eeb699c9..0000000000 --- a/gst-libs/gst/vaapi/gstvaapifeiutils_h264.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * gstvaapifeiutils_h264.h - FEI related utilities for H264 - * - * Copyright (C) 2016-2018 Intel Corporation - * Author: Wang, Yi - * Author: Sreerenj Balachandran - * - * 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_FEI_UTILS_H264_H -#define GST_VAAPI_FEI_UTILS_H264_H - -#include - -G_BEGIN_DECLS - -typedef struct _GstVaapiFeiInfoToPakH264 GstVaapiFeiInfoToPakH264; - -/* Structure useful for FEI ENC+PAK mode */ -struct _GstVaapiFeiInfoToPakH264 -{ - VAEncSequenceParameterBufferH264 h264_enc_sps; - VAEncPictureParameterBufferH264 h264_enc_pps; - GArray *h264_slice_headers; - guint h264_slice_num; -}; - -/******************* Common FEI enum definition for all codecs ***********/ -/* FeiFixme: This should be a common fei mode for all codecs, - * move to a common header file */ -#define GST_VAAPI_FEI_MODE_DEFAULT GST_VAAPI_FEI_MODE_ENC_PAK -typedef enum -{ - GST_VAAPI_FEI_MODE_ENC = (1 << 0), - GST_VAAPI_FEI_MODE_PAK = (1 << 1), - GST_VAAPI_FEI_MODE_ENC_PAK = (1 << 2) -} GstVaapiFeiMode; -/** -* GST_VAAPI_TYPE_FEI_MODE: -* -* A type that represents the fei encoding mode. -* -* Return value: the #GType of GstVaapiFeiMode -*/ -#define GST_VAAPI_TYPE_FEI_MODE (gst_vaapi_fei_mode_get_type()) - - -/******************* H264 Specific FEI enum definitions ***********/ - -typedef enum -{ - GST_VAAPI_FEI_H264_FULL_SEARCH_PATH = 0, - GST_VAAPI_FEI_H264_DIAMOND_SEARCH_PATH, -} GstVaapiFeiH264SearchPath; - -typedef enum -{ - GST_VAAPI_FEI_H264_SEARCH_WINDOW_NONE = 0, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_TINY, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_SMALL, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_DIAMOND, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_LARGE_DIAMOND, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_EXHAUSTIVE, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_DIAMOND, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_LARGE_DIAMOND, - GST_VAAPI_FEI_H264_SEARCH_WINDOW_HORI_EXHAUSTIVE, -} GstVaapiFeiH264SearchWindow; - -typedef enum -{ - GST_VAAPI_FEI_H264_INTEGER_ME = 0, - GST_VAAPI_FEI_H264_HALF_ME = 1, - GST_VAAPI_FEI_H264_QUARTER_ME = 3, -} GstVaapiFeiH264SubPelMode; - -typedef enum -{ - GST_VAAPI_FEI_H264_SAD_NONE_TRANS = 0, - GST_VAAPI_FEI_H264_SAD_HAAR_TRANS = 2, -} GstVaapiFeiH264SadMode; - -typedef enum -{ - GST_VAAPI_FEI_H264_DISABLE_INTRA_NONE = 0, - GST_VAAPI_FEI_H264_DISABLE_INTRA_16x16 = (1 << 0), - GST_VAAPI_FEI_H264_DISABLE_INTRA_8x8 = (1 << 1), - GST_VAAPI_FEI_H264_DISABLE_INTRA_4x4 = (1 << 2), -} GstVaapiFeiH264IntraPartMask; - -typedef enum -{ - GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_NONE = 0, - GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_16x16 = (1 << 1), - GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x16x8 = (1 << 2), - GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x16 = (1 << 3), - GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_1x8x8 = (1 << 4), - GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x8x4 = (1 << 5), - GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_2x4x8 = (1 << 6), - GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_4x4x4 = (1 << 7), -} GstVaapiFeiH264SubMbPartMask; - -#define GST_VAAPI_FEI_H264_SEARCH_PATH_DEFAULT \ - GST_VAAPI_FEI_H264_FULL_SEARCH_PATH -#define GST_VAAPI_FEI_H264_SEARCH_WINDOW_DEFAULT \ - GST_VAAPI_FEI_H264_SEARCH_WINDOW_NONE -#define GST_VAAPI_FEI_H264_SUB_PEL_MODE_DEFAULT \ - GST_VAAPI_FEI_H264_INTEGER_ME -#define GST_VAAPI_FEI_H264_SAD_MODE_DEFAULT \ - GST_VAAPI_FEI_H264_SAD_NONE_TRANS -#define GST_VAAPI_FEI_H264_INTRA_PART_MASK_DEFAULT \ - GST_VAAPI_FEI_H264_DISABLE_INTRA_NONE -#define GST_VAAPI_FEI_H264_SUB_MB_PART_MASK_DEFAULT \ - GST_VAAPI_FEI_H264_DISABLE_SUB_MB_PART_MASK_NONE -#define GST_VAAPI_FEI_H264_SEARCH_PATH_LENGTH_DEFAULT 32 -#define GST_VAAPI_FEI_H264_REF_WIDTH_DEFAULT 32 -#define GST_VAAPI_FEI_H264_REF_HEIGHT_DEFAULT 32 - -/** -* GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH: -* -* A type that represents the fei control param: search path. -* -* Return value: the #GType of GstVaapiFeiSearchPath -*/ -#define GST_VAAPI_TYPE_FEI_H264_SEARCH_PATH gst_vaapi_fei_h264_search_path_get_type() - -/** -* GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW: -* -* A type that represents the fei control param: search window. -* -* Return value: the #GType of GstVaapiFeiSearchWindow -*/ -#define GST_VAAPI_TYPE_FEI_H264_SEARCH_WINDOW gst_vaapi_fei_h264_search_window_get_type() - -/** -* GST_VAAPI_TYPE_FEI_H264_SAD_MODE: -* -* A type that represents the fei control param: sad mode. -* -* Return value: the #GType of GstVaapiFeiSadMode -*/ -#define GST_VAAPI_TYPE_FEI_H264_SAD_MODE gst_vaapi_fei_h264_sad_mode_get_type() - -/** -* GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK: -* -* A type that represents the fei control param: intra part mask. -* -* Return value: the #GType of GstVaapiFeiIntaPartMask -*/ -#define GST_VAAPI_TYPE_FEI_H264_INTRA_PART_MASK gst_vaapi_fei_h264_intra_part_mask_get_type() - -/** -* GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE: -* -* A type that represents the fei control param: sub pel mode. -* -* Return value: the #GType of GstVaapiFeiSubPelMode -*/ -#define GST_VAAPI_TYPE_FEI_H264_SUB_PEL_MODE gst_vaapi_fei_h264_sub_pel_mode_get_type() - -/** -* GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK: -* -* A type that represents the fei control param: sub maroclock partition mask. -* -* Return value: the #GType of GstVaapiFeiH264SubMbPartMask -*/ -#define GST_VAAPI_TYPE_FEI_H264_SUB_MB_PART_MASK gst_vaapi_fei_h264_sub_mb_part_mask_get_type() - -GType -gst_vaapi_fei_mode_get_type (void) - G_GNUC_CONST; - -GType -gst_vaapi_fei_h264_search_path_get_type (void) - G_GNUC_CONST; - -GType -gst_vaapi_fei_h264_search_window_get_type (void) - G_GNUC_CONST; - -GType -gst_vaapi_fei_h264_sad_mode_get_type (void) - G_GNUC_CONST; - -GType -gst_vaapi_fei_h264_sub_pel_mode_get_type (void) - G_GNUC_CONST; - -GType -gst_vaapi_fei_h264_intra_part_mask_get_type (void) - G_GNUC_CONST; - -GType -gst_vaapi_fei_h264_sub_mb_part_mask_get_type (void) - G_GNUC_CONST; - -G_END_DECLS -#endif /* GST_VAAPI_UTILS_FEI_H264_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 234a98b682..539ac9b315 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -149,9 +149,6 @@ static const GstVaapiEntrypointMap gst_vaapi_entrypoints[] = { {GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, VAEntrypointEncPicture}, #if VA_CHECK_VERSION(0,39,1) {GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP, VAEntrypointEncSliceLP}, -#endif -#if USE_H264_FEI_ENCODER - {GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI, VAEntrypointFEI}, #endif {0,} }; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 72ffd55c5f..b5533ca4c8 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -196,7 +196,6 @@ typedef enum { * @GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE: Encode Picture * @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP: Encode Slice low power/ * high performace varient - * @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI: FEI Encode * * The set of all entrypoints for #GstVaapiEntrypoint */ @@ -208,7 +207,6 @@ typedef enum { GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP, - GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI } GstVaapiEntrypoint; const gchar * diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c index b34afed0d8..729efeb4ef 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c @@ -50,27 +50,6 @@ gst_vaapi_surface_proxy_finalize (GstVaapiSurfaceProxy * proxy) /* Notify the user function that the object is now destroyed */ if (proxy->destroy_func) proxy->destroy_func (proxy->destroy_data); - -#if USE_H264_FEI_ENCODER - if (proxy->mvpred) - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mvpred, NULL); - if (proxy->mbcntrl) - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mbcntrl, NULL); - if (proxy->qp) - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->qp, NULL); - if (proxy->mbcode) - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mbcode, NULL); - if (proxy->mv) - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mv, NULL); - if (proxy->dist) - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->dist, NULL); -#endif } static inline const GstVaapiMiniObjectClass * @@ -90,14 +69,6 @@ gst_vaapi_surface_proxy_init_properties (GstVaapiSurfaceProxy * proxy) proxy->timestamp = GST_CLOCK_TIME_NONE; proxy->duration = GST_CLOCK_TIME_NONE; proxy->has_crop_rect = FALSE; -#if USE_H264_FEI_ENCODER - proxy->mvpred = NULL; - proxy->mbcntrl = NULL; - proxy->qp = NULL; - proxy->mbcode = NULL; - proxy->mv = NULL; - proxy->dist = NULL; -#endif } /** @@ -221,51 +192,6 @@ gst_vaapi_surface_proxy_copy (GstVaapiSurfaceProxy * proxy) if (copy->has_crop_rect) copy->crop_rect = proxy->crop_rect; -#if USE_H264_FEI_ENCODER - - if (proxy->mv) - copy->mv = (GstVaapiEncFeiMv *) - gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT (proxy->mv)); - else - copy->mv = NULL; - - if (proxy->mbcode) - copy->mbcode = (GstVaapiEncFeiMbCode *) - gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT - (proxy->mbcode)); - else - copy->mbcode = NULL; - - if (proxy->mvpred) - copy->mvpred = (GstVaapiEncFeiMvPredictor *) - gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT - (proxy->mvpred)); - else - copy->mvpred = NULL; - - if (proxy->qp) - copy->qp = (GstVaapiEncFeiQp *) - gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT (proxy->qp)); - else - copy->qp = NULL; - - if (proxy->mbcntrl) - copy->mbcntrl = (GstVaapiEncFeiMbControl *) - gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT - (proxy->mbcntrl)); - else - copy->mbcntrl = NULL; - - if (proxy->dist) - copy->dist = (GstVaapiEncFeiDistortion *) - gst_vaapi_fei_codec_object_ref (GST_VAAPI_FEI_CODEC_OBJECT - (proxy->dist)); - else - copy->dist = NULL; - - -#endif - return copy; } @@ -479,199 +405,3 @@ gst_vaapi_surface_proxy_set_crop_rect (GstVaapiSurfaceProxy * proxy, if (proxy->has_crop_rect) proxy->crop_rect = *crop_rect; } - -#if USE_H264_FEI_ENCODER - -/** - * gst_vaapi_surface_proxy_get_fei_mb_code: - * @proxy: a #GstVaapiSurfaceProxy - * - * Returns the #GstVaapiEncFeiMbCode stored in the @proxy - * - * Return value: the #GstVaapiEncFeiMbcode, or %NULL if none was - * associated with the surface proxy - */ -GstVaapiEncFeiMbCode * -gst_vaapi_surface_proxy_get_fei_mb_code (GstVaapiSurfaceProxy * proxy) -{ - g_return_val_if_fail (proxy != NULL, NULL); - return proxy->mbcode; -} - -/** - * gst_vaapi_surface_proxy_get_fei_mv: - * @proxy: a #GstVaapiSurfaceProxy - * - * Returns the #GstVaapiEncFeiMv stored in the @proxy - * - * Return value: the #GstVaapiEncFeiMv, or %NULL if none was - * associated with the surface proxy - */ -GstVaapiEncFeiMv * -gst_vaapi_surface_proxy_get_fei_mv (GstVaapiSurfaceProxy * proxy) -{ - g_return_val_if_fail (proxy != NULL, NULL); - return proxy->mv; -} - -/** - * gst_vaapi_surface_proxy_get_fei_distortion: - * @proxy: a #GstVaapiSurfaceProxy - * - * Returns the #GstVaapiEncFeiDistortion stored in the @proxy - * - * Return value: the #GstVaapiEncFeiDistortion, or %NULL if none was - * associated with the surface proxy - */ -GstVaapiEncFeiDistortion * -gst_vaapi_surface_proxy_get_fei_distortion (GstVaapiSurfaceProxy * proxy) -{ - g_return_val_if_fail (proxy != NULL, NULL); - return proxy->dist; -} - -/** - * gst_vaapi_surface_proxy_get_fei_qp: - * @proxy: a #GstVaapiSurfaceProxy - * - * Returns the #GstVaapiEncFeiQp stored in the @proxy - * - * Return value: the #GstVaapiEncFeiQp, or %NULL if none was - * associated with the surface proxy - */ -GstVaapiEncFeiQp * -gst_vaapi_surface_proxy_get_fei_qp (GstVaapiSurfaceProxy * proxy) -{ - g_return_val_if_fail (proxy != NULL, NULL); - return proxy->qp; -} - -/** - * gst_vaapi_surface_proxy_get_fei_mv_predictor: - * @proxy: a #GstVaapiSurfaceProxy - * - * Returns the #GstVaapiEncFeiMvPredictor stored in the @proxy - * - * Return value: the #GstVaapiEncFeiMvPredictor, or %NULL if none was - * associated with the surface proxy - */ -GstVaapiEncFeiMvPredictor * -gst_vaapi_surface_proxy_get_fei_mv_predictor (GstVaapiSurfaceProxy * proxy) -{ - g_return_val_if_fail (proxy != NULL, NULL); - return proxy->mvpred; -} - -/** - * gst_vaapi_surface_proxy_get_fei_mb_control: - * @proxy: a #GstVaapiSurfaceProxy - * - * Returns the #GstVaapiEncFeiMbControl stored in the @proxy - * - * Return value: the #GstVaapiEncFeiMbControl, or %NULL if none was - * associated with the surface proxy - */ -GstVaapiEncFeiMbControl * -gst_vaapi_surface_proxy_get_fei_mb_control (GstVaapiSurfaceProxy * proxy) -{ - g_return_val_if_fail (proxy != NULL, NULL); - return proxy->mbcntrl; -} - -/** - * gst_vaapi_surface_proxy_set_fei_mb_code: - * @proxy: #GstVaapiSurfaceProxy - * @mbcode: the #GstVaapiEncFeiMbCode to be stored in @proxy - * - * Associates the @mbcode with the @proxy - */ -void -gst_vaapi_surface_proxy_set_fei_mb_code (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiMbCode * mbcode) -{ - g_return_if_fail (proxy != NULL); - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mbcode, (GstVaapiFeiCodecObject *) mbcode); -} - -/** - * gst_vaapi_surface_proxy_set_fei_mv: - * @proxy: #GstVaapiSurfaceProxy - * @mv: the #GstVaapiEncFeiMv to be stored in @proxy - * - * Associates the @mv with the @proxy - */ -void -gst_vaapi_surface_proxy_set_fei_mv (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiMv * mv) -{ - g_return_if_fail (proxy != NULL); - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mv, (GstVaapiFeiCodecObject *) mv); -} - -/** - * gst_vaapi_surface_proxy_set_fei_distortion: - * @proxy: #GstVaapiSurfaceProxy - * @dist: the #GstVaapiEncFeiDistortion to be stored in @proxy - * - * Associates the @dist with the @proxy - */ -void -gst_vaapi_surface_proxy_set_fei_distortion (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiDistortion * dist) -{ - g_return_if_fail (proxy != NULL); - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->dist, (GstVaapiFeiCodecObject *) dist); -} - -/** - * gst_vaapi_surface_proxy_set_fei_qp: - * @proxy: #GstVaapiSurfaceProxy - * @qp: the #GstVaapiEncFeiQp to be stored in @proxy - * - * Associates the @qp with the @proxy - */ -void -gst_vaapi_surface_proxy_set_fei_qp (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiQp * qp) -{ - g_return_if_fail (proxy != NULL); - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->qp, (GstVaapiFeiCodecObject *) qp); -} - -/** - * gst_vaapi_surface_proxy_set_fei_mv_predictor: - * @proxy: #GstVaapiSurfaceProxy - * @mvpred: the #GstVaapiEncFeiMvPredictor to be stored in @proxy - * - * Associates the @mvpred with the @proxy - */ -void -gst_vaapi_surface_proxy_set_fei_mv_predictor (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiMvPredictor * mvpred) -{ - g_return_if_fail (proxy != NULL); - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mvpred, (GstVaapiFeiCodecObject *) mvpred); -} - -/** - * gst_vaapi_surface_proxy_set_fei_mb_control: - * @proxy: #GstVaapiSurfaceProxy - * @mbcntrl: the #GstVaapiEncFeiMbControl to be stored in @proxy - * - * Associates the @mbcntrl with the @proxy - */ -void -gst_vaapi_surface_proxy_set_fei_mb_control (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiMbControl * mbcntrl) -{ - g_return_if_fail (proxy != NULL); - gst_vaapi_fei_codec_object_replace ((GstVaapiFeiCodecObject **) & - proxy->mbcntrl, (GstVaapiFeiCodecObject *) mbcntrl); -} - -#endif diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 5f6c16e584..1dc218c45d 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -28,10 +28,6 @@ #include #include -#if USE_H264_FEI_ENCODER -#include -#endif - G_BEGIN_DECLS /** @@ -156,46 +152,6 @@ void gst_vaapi_surface_proxy_set_crop_rect (GstVaapiSurfaceProxy * proxy, const GstVaapiRectangle * crop_rect); -#if USE_H264_FEI_ENCODER - -GstVaapiEncFeiMbCode * -gst_vaapi_surface_proxy_get_fei_mb_code (GstVaapiSurfaceProxy * proxy); - -GstVaapiEncFeiMv * -gst_vaapi_surface_proxy_get_fei_mv (GstVaapiSurfaceProxy * proxy); - -GstVaapiEncFeiDistortion * -gst_vaapi_surface_proxy_get_fei_distortion (GstVaapiSurfaceProxy * proxy); - -GstVaapiEncFeiQp * -gst_vaapi_surface_proxy_get_fei_qp (GstVaapiSurfaceProxy * proxy); - -GstVaapiEncFeiMvPredictor * -gst_vaapi_surface_proxy_get_fei_mv_predictor (GstVaapiSurfaceProxy * proxy); - -GstVaapiEncFeiMbControl * -gst_vaapi_surface_proxy_get_fei_mb_control (GstVaapiSurfaceProxy * proxy); - -void -gst_vaapi_surface_proxy_set_fei_mb_code (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiMbCode *mbcode); -void -gst_vaapi_surface_proxy_set_fei_mv (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiMv *mv); -void -gst_vaapi_surface_proxy_set_fei_distortion (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiDistortion *dist); -void -gst_vaapi_surface_proxy_set_fei_qp (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiQp *mbcode); -void -gst_vaapi_surface_proxy_set_fei_mv_predictor (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiMvPredictor *mvpred); -void -gst_vaapi_surface_proxy_set_fei_mb_control (GstVaapiSurfaceProxy * proxy, - GstVaapiEncFeiMbControl *mbcntrl); -#endif - G_END_DECLS #endif /* GST_VAAPI_SURFACE_PROXY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index e43ecbc0e2..76bfba89a8 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -48,15 +48,6 @@ struct _GstVaapiSurfaceProxy gpointer destroy_data; GstVaapiRectangle crop_rect; guint has_crop_rect:1; - -#if USE_H264_FEI_ENCODER - GstVaapiEncFeiMvPredictor *mvpred; - GstVaapiEncFeiMbControl *mbcntrl; - GstVaapiEncFeiQp *qp; - GstVaapiEncFeiMbCode *mbcode; - GstVaapiEncFeiMv *mv; - GstVaapiEncFeiDistortion *dist; -#endif }; #define GST_VAAPI_SURFACE_PROXY_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 83f4a1d5ad..2630acd6ca 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -112,23 +112,6 @@ if USE_VP9_ENCODER gstlibvaapi_headers += 'gstvaapiencoder_vp9.h' endif -if USE_H264_FEI_ENCODER - gstlibvaapi_sources += [ - 'gstvaapifeiutils_h264.c', - 'gstvaapifei_objects.c', - 'gstvaapifeienc_h264.c', - 'gstvaapifeipak_h264.c', - 'gstvaapiencoder_h264_fei.c', - ] - gstlibvaapi_headers += [ - 'gstvaapifeiutils_h264.h', - 'gstvaapifei_objects.h', - 'gstvaapifeienc_h264.h', - 'gstvaapifeipak_h264.h', - 'gstvaapiencoder_h264_fei.h', - ] -endif - if USE_DRM gstlibvaapi_sources += [ 'gstvaapidisplay_drm.c', diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 8bcf81d2a7..1c4efff52d 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -39,11 +39,6 @@ #if USE_VP9_ENCODER #include "gstvaapiencode_vp9.h" #endif - -#if USE_H264_FEI_ENCODER -#include "gstvaapiencode_h264_fei.h" -#endif - #endif gboolean _gst_vaapi_has_video_processing = FALSE; @@ -179,14 +174,6 @@ gst_vaapiencode_register (GstPlugin * plugin, GstVaapiDisplay * display) } } -#if USE_H264_FEI_ENCODER - if (gst_vaapi_display_has_encoder (display, - GST_VAAPI_PROFILE_H264_MAIN, GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_FEI)) { - gst_element_register (plugin, "vaapih264feienc", - GST_RANK_SECONDARY, GST_TYPE_VAAPIENCODE_H264_FEI); - } -#endif - g_array_unref (codecs); } #endif diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 97e8e61bc2..ccd33569ba 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -253,9 +253,6 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) GstVaapiEncoderStatus status; GstBuffer *out_buffer; GstFlowReturn ret; -#if USE_H264_FEI_ENCODER - GstVaapiFeiVideoMeta *feimeta = NULL; -#endif status = gst_vaapi_encoder_get_buffer_with_timeout (encode->encoder, &codedbuf_proxy, timeout); @@ -281,14 +278,6 @@ gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) ret = klass->alloc_buffer (encode, GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy), &out_buffer); -#if USE_H264_FEI_ENCODER - if (klass->save_stats_to_meta) { - feimeta = klass->save_stats_to_meta (encode, codedbuf_proxy); - if (feimeta != NULL) - gst_buffer_set_vaapi_fei_video_meta (out_buffer, feimeta); - } -#endif - gst_vaapi_coded_buffer_proxy_replace (&codedbuf_proxy, NULL); if (ret != GST_FLOW_OK) goto error_allocate_buffer; @@ -675,10 +664,6 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GstFlowReturn ret; GstBuffer *buf; GstTaskState task_state; -#if USE_H264_FEI_ENCODER - GstVaapiFeiVideoMeta *feimeta = NULL; - GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (venc); -#endif task_state = gst_pad_get_task_state (srcpad); if (task_state == GST_TASK_STOPPED || task_state == GST_TASK_PAUSED) @@ -703,12 +688,6 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, if (!proxy) goto error_buffer_no_surface_proxy; -#if USE_H264_FEI_ENCODER - feimeta = gst_buffer_get_vaapi_fei_video_meta (buf); - if (feimeta && klass->load_control_data) - klass->load_control_data (encode, feimeta, proxy); -#endif - gst_video_codec_frame_set_user_data (frame, gst_vaapi_surface_proxy_ref (proxy), (GDestroyNotify) gst_vaapi_surface_proxy_unref); diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 9f15f1c12c..176f32e653 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -27,12 +27,6 @@ #include "gstvaapipluginbase.h" #include -#if USE_H264_FEI_ENCODER -#include -#include -#include "gstvaapifeivideometa.h" -#endif - G_BEGIN_DECLS #define GST_TYPE_VAAPIENCODE \ @@ -84,17 +78,6 @@ struct _GstVaapiEncodeClass /* Get all possible profiles based on allowed caps */ GArray * (*get_allowed_profiles) (GstVaapiEncode * encode, GstCaps * allowed); - -#if USE_H264_FEI_ENCODER - - gboolean (*load_control_data) (GstVaapiEncode *encoder, - GstVaapiFeiVideoMeta *feimeta, - GstVaapiSurfaceProxy *proxy); - - GstVaapiFeiVideoMeta* (*save_stats_to_meta) (GstVaapiEncode *base_encode, - GstVaapiCodedBufferProxy *proxy); - -#endif }; GType diff --git a/gst/vaapi/gstvaapiencode_h264_fei.c b/gst/vaapi/gstvaapiencode_h264_fei.c deleted file mode 100644 index 5a998afbd6..0000000000 --- a/gst/vaapi/gstvaapiencode_h264_fei.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * gstvaapiencode_h264_fei.c - VA-API H.264 FEI ncoder - * - * Copyright (C) 2016-2019 Intel Corporation - * Author: Sreerenj Balachandran - * Author: Yi A Wang - * - * 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:element-vaapih264feienc - * @short_description: A VA-API FEI based H.264 video encoder - * - * Encodes raw video streams into H.264 bitstreams. - * - * ## Example launch line - * - * |[ - * gst-launch-1.0 -ev videotestsrc num-buffers=60 ! vaapih264feienc fei-mode=ENC_PAK ! filesink location=test.264 - * ]| - */ - -#include "gstcompat.h" -#include -#include -#include -#include -#include -#include "gstvaapiencode_h264_fei.h" -#include "gstvaapipluginutil.h" -#include "gstvaapivideomemory.h" -#include "gstvaapifeivideometa.h" -#include - -#define GST_VAAPI_ENCODE_FLOW_MEM_ERROR GST_FLOW_CUSTOM_ERROR -#define GST_PLUGIN_NAME "vaapih264feienc" -#define GST_PLUGIN_DESC "A VA-API FEI based advanced H264 video encoder" - -GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_fei_encode_debug); -#define GST_CAT_DEFAULT gst_vaapi_h264_fei_encode_debug - -#define GST_CODEC_CAPS \ - "video/x-h264, " \ - "stream-format = (string) { avc, byte-stream }, " \ - "alignment = (string) au" - -/* *INDENT-OFF* */ -static const char gst_vaapiencode_h264_fei_sink_caps_str[] = - GST_VAAPI_MAKE_SURFACE_CAPS ", " - GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " - GST_CAPS_INTERLACED_FALSE ";" - GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," - GST_CAPS_INTERLACED_FALSE; -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -static const char gst_vaapiencode_h264_fei_src_caps_str[] = - GST_CODEC_CAPS ", " - "profile = (string) { constrained-baseline, baseline, main, high, multiview-high, stereo-high }"; -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_h264_fei_sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_h264_fei_sink_caps_str)); -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_h264_fei_src_factory = - GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_h264_fei_src_caps_str)); -/* *INDENT-ON* */ - -/* h264 encode */ -G_DEFINE_TYPE (GstVaapiEncodeH264Fei, gst_vaapiencode_h264_fei, - GST_TYPE_VAAPIENCODE); - -static void -gst_vaapiencode_h264_fei_init (GstVaapiEncodeH264Fei * encode) -{ - /* nothing to do here */ -} - -static void -gst_vaapiencode_h264_fei_finalize (GObject * object) -{ - G_OBJECT_CLASS (gst_vaapiencode_h264_fei_parent_class)->finalize (object); -} - -typedef struct -{ - GstVaapiProfile best_profile; - guint best_score; -} FindBestProfileData; - -static void -find_best_profile_value (FindBestProfileData * data, const GValue * value) -{ - const gchar *str; - GstVaapiProfile profile; - guint score; - - if (!value || !G_VALUE_HOLDS_STRING (value)) - return; - - str = g_value_get_string (value); - if (!str) - return; - profile = gst_vaapi_utils_h264_get_profile_from_string (str); - if (!profile) - return; - score = gst_vaapi_utils_h264_get_profile_score (profile); - if (score < data->best_score) - return; - data->best_profile = profile; - data->best_score = score; -} - -static GstVaapiProfile -find_best_profile (GstCaps * caps) -{ - FindBestProfileData data; - guint i, j, num_structures, num_values; - - data.best_profile = GST_VAAPI_PROFILE_UNKNOWN; - data.best_score = 0; - - num_structures = gst_caps_get_size (caps); - for (i = 0; i < num_structures; i++) { - GstStructure *const structure = gst_caps_get_structure (caps, i); - const GValue *const value = gst_structure_get_value (structure, "profile"); - - if (!value) - continue; - if (G_VALUE_HOLDS_STRING (value)) - find_best_profile_value (&data, value); - else if (GST_VALUE_HOLDS_LIST (value)) { - num_values = gst_value_list_get_size (value); - for (j = 0; j < num_values; j++) - find_best_profile_value (&data, gst_value_list_get_value (value, j)); - } - } - return data.best_profile; -} - -static gboolean -gst_vaapiencode_h264_fei_set_config (GstVaapiEncode * base_encode) -{ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI (base_encode->encoder); - GstCaps *allowed_caps; - GstVaapiProfile profile; - - /* Check for the largest profile that is supported */ - allowed_caps = - gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (base_encode)); - if (!allowed_caps) - return TRUE; - - profile = find_best_profile (allowed_caps); - gst_caps_unref (allowed_caps); - if (profile) { - GST_INFO ("using %s profile as target decoder constraints", - gst_vaapi_utils_h264_get_profile_string (profile)); - if (!gst_vaapi_encoder_h264_fei_set_max_profile (encoder, profile)) - return FALSE; - } - return TRUE; -} - -static GstCaps * -gst_vaapiencode_h264_fei_get_caps (GstVaapiEncode * base_encode) -{ - GstVaapiEncodeH264Fei *const encode = - GST_VAAPIENCODE_H264_FEI_CAST (base_encode); - GstCaps *caps, *allowed_caps; - - caps = gst_caps_from_string (GST_CODEC_CAPS); - - /* Check whether "stream-format" is avcC mode */ - allowed_caps = - gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); - if (allowed_caps) { - const char *stream_format = NULL; - GstStructure *structure; - guint i, num_structures; - - num_structures = gst_caps_get_size (allowed_caps); - for (i = 0; !stream_format && i < num_structures; i++) { - structure = gst_caps_get_structure (allowed_caps, i); - if (!gst_structure_has_field_typed (structure, "stream-format", - G_TYPE_STRING)) - continue; - stream_format = gst_structure_get_string (structure, "stream-format"); - } - encode->is_avc = stream_format && strcmp (stream_format, "avc") == 0; - gst_caps_unref (allowed_caps); - } - gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, - encode->is_avc ? "avc" : "byte-stream", NULL); - - base_encode->need_codec_data = encode->is_avc; - - /* XXX: update profile and level information */ - return caps; -} - -static GstVaapiEncoder * -gst_vaapiencode_h264_fei_alloc_encoder (GstVaapiEncode * base, - GstVaapiDisplay * display) -{ - return gst_vaapi_encoder_h264_fei_new (display); -} - -/* h264 NAL byte stream operations */ -static guint8 * -_h264_byte_stream_next_nal (guint8 * buffer, guint32 len, guint32 * nal_size) -{ - const guint8 *cur = buffer; - const guint8 *const end = buffer + len; - guint8 *nal_start = NULL; - guint32 flag = 0xFFFFFFFF; - guint32 nal_start_len = 0; - - g_assert (buffer && nal_size); - if (len < 3) { - *nal_size = len; - nal_start = (len ? buffer : NULL); - return nal_start; - } - - /*locate head postion */ - if (!buffer[0] && !buffer[1]) { - if (buffer[2] == 1) { /* 0x000001 */ - nal_start_len = 3; - } else if (!buffer[2] && len >= 4 && buffer[3] == 1) { /* 0x00000001 */ - nal_start_len = 4; - } - } - nal_start = buffer + nal_start_len; - cur = nal_start; - - /*find next nal start position */ - while (cur < end) { - flag = ((flag << 8) | ((*cur++) & 0xFF)); - if ((flag & 0x00FFFFFF) == 0x00000001) { - if (flag == 0x00000001) - *nal_size = cur - 4 - nal_start; - else - *nal_size = cur - 3 - nal_start; - break; - } - } - if (cur >= end) { - *nal_size = end - nal_start; - if (nal_start >= end) { - nal_start = NULL; - } - } - return nal_start; -} - -static inline void -_start_code_to_size (guint8 nal_start_code[4], guint32 nal_size) -{ - nal_start_code[0] = ((nal_size >> 24) & 0xFF); - nal_start_code[1] = ((nal_size >> 16) & 0xFF); - nal_start_code[2] = ((nal_size >> 8) & 0xFF); - nal_start_code[3] = (nal_size & 0xFF); -} - -static gboolean -_h264_convert_byte_stream_to_avc (GstBuffer * buf) -{ - GstMapInfo info; - guint32 nal_size; - guint8 *nal_start_code, *nal_body; - guint8 *frame_end; - - g_assert (buf); - - if (!gst_buffer_map (buf, &info, GST_MAP_READ | GST_MAP_WRITE)) - return FALSE; - - nal_start_code = info.data; - frame_end = info.data + info.size; - nal_size = 0; - - while ((frame_end > nal_start_code) && - (nal_body = _h264_byte_stream_next_nal (nal_start_code, - frame_end - nal_start_code, &nal_size)) != NULL) { - if (!nal_size) - goto error; - - g_assert (nal_body - nal_start_code == 4); - _start_code_to_size (nal_start_code, nal_size); - nal_start_code = nal_body + nal_size; - } - gst_buffer_unmap (buf, &info); - return TRUE; - - /* ERRORS */ -error: - { - gst_buffer_unmap (buf, &info); - return FALSE; - } -} - -static GstFlowReturn -alloc_buffer (GstVaapiEncode * encode, - GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr) -{ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI (encode->encoder); - GstBuffer *buf; - gint32 buf_size; - GstVaapiFeiMode fei_mode; - - g_return_val_if_fail (coded_buf != NULL, GST_FLOW_ERROR); - g_return_val_if_fail (outbuf_ptr != NULL, GST_FLOW_ERROR); - - fei_mode = gst_vaapi_encoder_h264_fei_get_function_mode (encoder); - - if (fei_mode == GST_VAAPI_FEI_MODE_ENC) - buf_size = 4; /* just avoid zero size buffer allocation */ - else - buf_size = gst_vaapi_coded_buffer_get_size (coded_buf); - - if (buf_size <= 0) - goto error_invalid_buffer; - - buf = - gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER_CAST (encode), - buf_size); - if (!buf) - goto error_create_buffer; - - /* There is no encoded output content in ENC only mode */ - if (fei_mode != GST_VAAPI_FEI_MODE_ENC) { - if (!gst_vaapi_coded_buffer_copy_into (buf, coded_buf)) - goto error_copy_buffer; - } - - *outbuf_ptr = buf; - return GST_FLOW_OK; - - /* ERRORS */ -error_invalid_buffer: - { - GST_ERROR ("invalid GstVaapiCodedBuffer size (%d bytes)", buf_size); - return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; - } -error_create_buffer: - { - GST_ERROR ("failed to create output buffer of size %d", buf_size); - return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; - } -error_copy_buffer: - { - GST_ERROR ("failed to copy GstVaapiCodedBuffer data"); - gst_buffer_unref (buf); - return GST_VAAPI_ENCODE_FLOW_MEM_ERROR; - } -} - -static GstFlowReturn -gst_vaapiencode_h264_fei_alloc_buffer (GstVaapiEncode * base_encode, - GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buffer_ptr) -{ - GstVaapiEncodeH264Fei *const encode = - GST_VAAPIENCODE_H264_FEI_CAST (base_encode); - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI (base_encode->encoder); - GstFlowReturn ret; - - g_return_val_if_fail (encoder != NULL, GST_FLOW_ERROR); - - ret = alloc_buffer (base_encode, coded_buf, out_buffer_ptr); - if (ret != GST_FLOW_OK) - return ret; - - if (!encode->is_avc) - return GST_FLOW_OK; - - /* Convert to avcC format */ - if (!_h264_convert_byte_stream_to_avc (*out_buffer_ptr)) - goto error_convert_buffer; - return GST_FLOW_OK; - - /* ERRORS */ -error_convert_buffer: - { - GST_ERROR ("failed to convert from bytestream format to avcC format"); - gst_buffer_replace (out_buffer_ptr, NULL); - return GST_FLOW_ERROR; - } -} - -static gboolean -gst_vaapiencode_h264_load_control_data (GstVaapiEncode * base_encode, - GstVaapiFeiVideoMeta * feimeta, GstVaapiSurfaceProxy * proxy) -{ - if (feimeta != NULL) { - gst_vaapi_surface_proxy_set_fei_mb_code (proxy, feimeta->mbcode); - gst_vaapi_surface_proxy_set_fei_mv (proxy, feimeta->mv); - gst_vaapi_surface_proxy_set_fei_mv_predictor (proxy, feimeta->mvpred); - gst_vaapi_surface_proxy_set_fei_mb_control (proxy, feimeta->mbcntrl); - gst_vaapi_surface_proxy_set_fei_qp (proxy, feimeta->qp); - gst_vaapi_surface_proxy_set_fei_distortion (proxy, feimeta->dist); - } - return TRUE; - -} - -static GstVaapiFeiVideoMeta * -gst_vaapiencode_h264_save_stats_to_meta (GstVaapiEncode * base_encode, - GstVaapiCodedBufferProxy * proxy) -{ - GstVaapiEncoderH264Fei *const encoder = - GST_VAAPI_ENCODER_H264_FEI (base_encode->encoder); - GstVaapiFeiVideoMeta *feimeta = NULL; - GstVaapiEncFeiMbCode *mbcode = NULL; - GstVaapiEncFeiMv *mv = NULL; - GstVaapiEncFeiDistortion *dist = NULL; - - if (!gst_vaapi_encoder_h264_is_fei_stats_out_enabled (encoder)) - return NULL; - - feimeta = gst_vaapi_fei_video_meta_new (); - if (feimeta == NULL) - return NULL; - - mbcode = gst_vaapi_coded_buffer_proxy_get_fei_mbcode (proxy); - if (mbcode) - feimeta->mbcode = (GstVaapiEncFeiMbCode *) - gst_vaapi_fei_codec_object_ref ((GstVaapiFeiCodecObject *) mbcode); - - mv = gst_vaapi_coded_buffer_proxy_get_fei_mv (proxy); - if (mv) - feimeta->mv = (GstVaapiEncFeiMv *) - gst_vaapi_fei_codec_object_ref ((GstVaapiFeiCodecObject *) mv); - - dist = gst_vaapi_coded_buffer_proxy_get_fei_distortion (proxy); - if (dist) - feimeta->dist = (GstVaapiEncFeiDistortion *) - gst_vaapi_fei_codec_object_ref ((GstVaapiFeiCodecObject *) dist); - - return feimeta; -} - -static void -gst_vaapiencode_h264_fei_class_init (GstVaapiEncodeH264FeiClass * klass) -{ - GObjectClass *const object_class = G_OBJECT_CLASS (klass); - GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); - GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); - gpointer encoder_class; - - GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_fei_encode_debug, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - - object_class->finalize = gst_vaapiencode_h264_fei_finalize; - object_class->set_property = gst_vaapiencode_set_property_subclass; - object_class->get_property = gst_vaapiencode_get_property_subclass; - - encode_class->set_config = gst_vaapiencode_h264_fei_set_config; - encode_class->get_caps = gst_vaapiencode_h264_fei_get_caps; - encode_class->alloc_encoder = gst_vaapiencode_h264_fei_alloc_encoder; - encode_class->alloc_buffer = gst_vaapiencode_h264_fei_alloc_buffer; - - encode_class->load_control_data = gst_vaapiencode_h264_load_control_data; - encode_class->save_stats_to_meta = gst_vaapiencode_h264_save_stats_to_meta; - - gst_element_class_set_static_metadata (element_class, - "VA-API H264 FEI Advanced encoder (Experimental)", - "Codec/Encoder/Video/Hardware", - GST_PLUGIN_DESC, - "Sreerenj Balachandran ," - "Yi A Wang "); - - /* sink pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_h264_fei_sink_factory); - - /* src pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_h264_fei_src_factory); - - encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_H264_FEI); - g_assert (encoder_class); - gst_vaapiencode_class_install_properties (encode_class, encoder_class); - g_type_class_unref (encoder_class); -} diff --git a/gst/vaapi/gstvaapiencode_h264_fei.h b/gst/vaapi/gstvaapiencode_h264_fei.h deleted file mode 100644 index 195010786a..0000000000 --- a/gst/vaapi/gstvaapiencode_h264_fei.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * gstvaapiencode_h264i_fei.h - VA-API H.264 FEI encoder - * - * Copyright (C) 2016-2017 Intel Corporation - * Author: Sreerenj Balachandran - * Author: Yi A Wang - * - * 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_VAAPIENCODE_H264_FEI_FEI_H -#define GST_VAAPIENCODE_H264_FEI_FEI_H - -#include -#include "gstvaapiencode.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VAAPIENCODE_H264_FEI \ - (gst_vaapiencode_h264_fei_get_type ()) -#define GST_VAAPIENCODE_H264_FEI_CAST(obj) \ - ((GstVaapiEncodeH264Fei *)(obj)) -#define GST_VAAPIENCODE_H264_FEI(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPIENCODE_H264_FEI, \ - GstVaapiEncodeH264Fei)) -#define GST_VAAPIENCODE_H264_FEI_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPIENCODE_H264_FEI, \ - GstVaapiEncodeH264FeiClass)) -#define GST_VAAPIENCODE_H264_FEI_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPIENCODE_H264_FEI, \ - GstVaapiEncodeH264FeiClass)) -#define GST_IS_VAAPIENCODE_H264_FEI(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_H264_FEI)) -#define GST_IS_VAAPIENCODE_H264_FEI_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_H264_FEI)) - -typedef struct _GstVaapiEncodeH264Fei GstVaapiEncodeH264Fei; -typedef struct _GstVaapiEncodeH264FeiClass GstVaapiEncodeH264FeiClass; - -struct _GstVaapiEncodeH264Fei -{ - /*< private >*/ - GstVaapiEncode parent_instance; - - guint is_avc:1; /* [FALSE]=byte-stream (default); [TRUE]=avcC */ -}; - -struct _GstVaapiEncodeH264FeiClass -{ - /*< private >*/ - GstVaapiEncodeClass parent_class; -}; - -GType -gst_vaapiencode_h264_fei_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* GST_VAAPIENCODE_H264_FEI_FEI_H */ diff --git a/gst/vaapi/gstvaapifeivideometa.c b/gst/vaapi/gstvaapifeivideometa.c deleted file mode 100644 index eafb7d0cd1..0000000000 --- a/gst/vaapi/gstvaapifeivideometa.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * gstvaapifeivideometa.c - Gst VA FEI video meta - * - * Copyright (C) 2016-2017 Intel Corporation - * Author: Yi A Wang - * Author: Sreerenj Balachandran * - * - * 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:gstvaapifeivideometa - * @short_description: VA FEI video meta for GStreamer - */ -#include "gstcompat.h" -#include "gstvaapifeivideometa.h" - -static void -gst_vaapi_fei_video_meta_finalize (GstVaapiFeiVideoMeta * meta) -{ - if (meta->mbcode) - gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT - (meta->mbcode)); - if (meta->mv) - gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT (meta->mv)); - if (meta->mvpred) - gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT - (meta->mvpred)); - if (meta->mbcntrl) - gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT - (meta->mbcntrl)); - if (meta->qp) - gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT (meta->qp)); - if (meta->dist) - gst_vaapi_fei_codec_object_unref (GST_VAAPI_FEI_CODEC_OBJECT (meta->dist)); -} - -static void -gst_vaapi_fei_video_meta_init (GstVaapiFeiVideoMeta * meta) -{ -} - -static inline GstVaapiFeiVideoMeta * -_gst_vaapi_fei_video_meta_create (void) -{ - return g_slice_new0 (GstVaapiFeiVideoMeta); -} - -static inline void -_gst_vaapi_fei_video_meta_destroy (GstVaapiFeiVideoMeta * meta) -{ - g_slice_free1 (sizeof (*meta), meta); -} - -GstVaapiFeiVideoMeta * -gst_vaapi_fei_video_meta_new (void) -{ - GstVaapiFeiVideoMeta *meta; - - meta = _gst_vaapi_fei_video_meta_create (); - if (!meta) - return NULL; - gst_vaapi_fei_video_meta_init (meta); - return meta; -} - -static inline void -_gst_vaapi_fei_video_meta_free (GstVaapiFeiVideoMeta * meta) -{ - g_atomic_int_inc (&meta->ref_count); - - gst_vaapi_fei_video_meta_finalize (meta); - - if (G_LIKELY (g_atomic_int_dec_and_test (&meta->ref_count))) - _gst_vaapi_fei_video_meta_destroy (meta); -} - -/** - * gst_vaapi_fei_video_meta_ref: - * @meta: a #GstVaapiFeiVideoMeta - * - * Atomically increases the reference count of the given @meta by one. - * - * Returns: The same @meta argument - */ -GstVaapiFeiVideoMeta * -gst_vaapi_fei_video_meta_ref (GstVaapiFeiVideoMeta * meta) -{ - g_return_val_if_fail (meta != NULL, NULL); - - g_atomic_int_inc (&meta->ref_count); - return meta; -} - -/** - * gst_vaapi_fei_video_meta_unref: - * @meta: a #GstVaapiFeiVideoMeta - * - * Atomically decreases the reference count of the @meta by one. If - * the reference count reaches zero, the object will be free'd. - */ -void -gst_vaapi_fei_video_meta_unref (GstVaapiFeiVideoMeta * meta) -{ - g_return_if_fail (meta != NULL); - g_return_if_fail (meta->ref_count > 0); - if (g_atomic_int_dec_and_test (&meta->ref_count)) - _gst_vaapi_fei_video_meta_free (meta); -} - - -GType -gst_vaapi_fei_video_meta_api_get_type (void) -{ - static gsize g_type; - static const gchar *tags[] = { "memory", NULL }; - - if (g_once_init_enter (&g_type)) { - GType type = gst_meta_api_type_register ("GstVaapiFeiVideoMetaAPI", tags); - g_once_init_leave (&g_type, type); - } - return g_type; -} - - -#define GST_VAAPI_FEI_VIDEO_META_HOLDER(meta) \ - ((GstVaapiFeiVideoMetaHolder *) (meta)) - -static gboolean -gst_vaapi_fei_video_meta_holder_init (GstVaapiFeiVideoMetaHolder * meta, - gpointer params, GstBuffer * buffer) -{ - meta->meta = NULL; - return TRUE; -} - -static void -gst_vaapi_fei_video_meta_holder_free (GstVaapiFeiVideoMetaHolder * meta, - GstBuffer * buffer) -{ - if (meta->meta) - gst_vaapi_fei_video_meta_unref (meta->meta); -} - - -#define GST_VAAPI_FEI_VIDEO_META_INFO gst_vaapi_fei_video_meta_info_get () -static const GstMetaInfo * -gst_vaapi_fei_video_meta_info_get (void) -{ - static gsize g_meta_info; - - if (g_once_init_enter (&g_meta_info)) { - gsize meta_info = - GPOINTER_TO_SIZE (gst_meta_register (GST_VAAPI_FEI_VIDEO_META_API_TYPE, - "GstVaapiFeiVideoMeta", sizeof (GstVaapiFeiVideoMetaHolder), - (GstMetaInitFunction) gst_vaapi_fei_video_meta_holder_init, - (GstMetaFreeFunction) gst_vaapi_fei_video_meta_holder_free, - NULL)); - g_once_init_leave (&g_meta_info, meta_info); - } - return GSIZE_TO_POINTER (g_meta_info); -} - -GstVaapiFeiVideoMeta * -gst_buffer_get_vaapi_fei_video_meta (GstBuffer * buffer) -{ - GstVaapiFeiVideoMeta *meta; - GstMeta *m; - - g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); - - m = gst_buffer_get_meta (buffer, GST_VAAPI_FEI_VIDEO_META_API_TYPE); - if (!m) - return NULL; - - meta = GST_VAAPI_FEI_VIDEO_META_HOLDER (m)->meta; - if (meta) - meta->buffer = buffer; - return meta; -} - -void -gst_buffer_set_vaapi_fei_video_meta (GstBuffer * buffer, - GstVaapiFeiVideoMeta * meta) -{ - GstMeta *m = NULL; - - g_return_if_fail (GST_IS_BUFFER (buffer)); - g_return_if_fail (GST_VAAPI_IS_FEI_VIDEO_META (meta)); - - m = gst_buffer_add_meta (buffer, GST_VAAPI_FEI_VIDEO_META_INFO, NULL); - - if (m) - GST_VAAPI_FEI_VIDEO_META_HOLDER (m)->meta = - gst_vaapi_fei_video_meta_ref (meta); - return; -} diff --git a/gst/vaapi/gstvaapifeivideometa.h b/gst/vaapi/gstvaapifeivideometa.h deleted file mode 100644 index 09d5f68ea6..0000000000 --- a/gst/vaapi/gstvaapifeivideometa.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * gstvaapifeivideometa.h - Gstreamer/VA video meta - * - * Copyright (C) 2016-2017 Intel Corporation - * Author: Yi A Wang - * Author: Sreerenj Balachandran - * - * 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_FEI_VIDEO_META_H -#define GST_VAAPI_FEI_VIDEO_META_H - -#include -#include -G_BEGIN_DECLS - -typedef struct _GstVaapiFeiVideoMeta GstVaapiFeiVideoMeta; -typedef struct _GstVaapiFeiVideoMetaHolder GstVaapiFeiVideoMetaHolder; - -#define GST_VAAPI_FEI_VIDEO_META(obj) \ - ((GstVaapiFeiVideoMeta *) (obj)) -#define GST_VAAPI_IS_FEI_VIDEO_META(obj) \ - (GST_VAAPI_FEI_VIDEO_META (obj) != NULL) - -struct _GstVaapiFeiVideoMetaHolder -{ - GstMeta base; - GstVaapiFeiVideoMeta *meta; -}; - -struct _GstVaapiFeiVideoMeta { - GstVaapiEncFeiMbCode *mbcode; - GstVaapiEncFeiMv *mv; - GstVaapiEncFeiMvPredictor *mvpred; - GstVaapiEncFeiMbControl *mbcntrl; - GstVaapiEncFeiQp *qp; - GstVaapiEncFeiDistortion *dist; - - GstBuffer *buffer; - gint ref_count; -}; - -#define GST_VAAPI_FEI_VIDEO_META_API_TYPE \ - gst_vaapi_fei_video_meta_api_get_type () - -GType -gst_vaapi_fei_video_meta_api_get_type (void) G_GNUC_CONST; - -GstVaapiFeiVideoMeta * -gst_vaapi_fei_video_meta_new (void); - -GstVaapiFeiVideoMeta * -gst_vaapi_fei_video_meta_ref (GstVaapiFeiVideoMeta * meta); - -void -gst_vaapi_fei_video_meta_unref (GstVaapiFeiVideoMeta * meta); - -GstVaapiFeiVideoMeta * -gst_buffer_get_vaapi_fei_video_meta (GstBuffer * buffer); - -void -gst_buffer_set_vaapi_fei_video_meta (GstBuffer * buffer, GstVaapiFeiVideoMeta * meta); - -G_END_DECLS - -#endif /* GST_VAAPI_FEI_VIDEO_META_H */ diff --git a/gst/vaapi/meson.build b/gst/vaapi/meson.build index c363b00b7e..d8c24c3b68 100644 --- a/gst/vaapi/meson.build +++ b/gst/vaapi/meson.build @@ -33,13 +33,6 @@ if USE_VP9_ENCODER vaapi_sources += 'gstvaapiencode_vp9.c' endif -if USE_H264_FEI_ENCODER - vaapi_sources += [ - 'gstvaapifeivideometa.c', - 'gstvaapiencode_h264_fei.c', - ] -endif - gstvaapi = library('gstvaapi', vaapi_sources, c_args : gstreamer_vaapi_args + ['-DGST_USE_UNSTABLE_API'], diff --git a/meson.build b/meson.build index d1cb310f5a..3ee4fa61bf 100644 --- a/meson.build +++ b/meson.build @@ -110,7 +110,6 @@ endif USE_ENCODERS = get_option('with_encoders') != 'no' USE_VP9_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp9.h', dependencies: libva_dep, prefix: '#include ') -USE_H264_FEI_ENCODER = USE_ENCODERS and cc.has_header('va/va_fei_h264.h', dependencies: libva_dep, prefix: '#include ') USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() and get_option('with_drm') != 'no' USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no' @@ -141,7 +140,6 @@ cdata.set10('USE_EGL', USE_EGL) cdata.set10('USE_ENCODERS', USE_ENCODERS) cdata.set10('USE_GLX', USE_GLX) cdata.set10('USE_VP9_ENCODER', USE_VP9_ENCODER) -cdata.set10('USE_H264_FEI_ENCODER', USE_H264_FEI_ENCODER) cdata.set10('USE_WAYLAND', USE_WAYLAND) cdata.set10('USE_X11', USE_X11) cdata.set10('HAVE_XKBLIB', cc.has_header('X11/XKBlib.h', dependencies: x11_dep)) diff --git a/tests/internal/meson.build b/tests/internal/meson.build index a118d3843b..1afd22be1c 100644 --- a/tests/internal/meson.build +++ b/tests/internal/meson.build @@ -46,13 +46,6 @@ if USE_ENCODERS test_examples += [ 'simple-encoder' ] endif -if USE_H264_FEI_ENCODER - test_examples += [ - 'test-fei-enc-out', - 'test-fei-enc-in', - ] -endif - if USE_GLX test_examples += [ 'test-textures' ] endif diff --git a/tests/internal/test-fei-enc-in.c b/tests/internal/test-fei-enc-in.c deleted file mode 100644 index ad67909e2f..0000000000 --- a/tests/internal/test-fei-enc-in.c +++ /dev/null @@ -1,680 +0,0 @@ -/* - * test-fei-enc-in.c - Test FEI input buffer submission - * - * Copyright (C) 2016 Intel Corporation - * - * Author: Sreerenj Balachandran - * - * 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 - */ -/* sample pipeline: ./test-fei-enc-input -c h264 -o out.264 -e 4 -q 1 sample_i420.y4m */ - -#include -#include -#include -#include -#include -#include -#include "gst/vaapi/sysdeps.h" -#include -#include -#include -#include -#include -#include "output.h" -#include "y4mreader.h" -#include - -static guint g_bitrate = 0; -static gchar *g_codec_str; -static gchar *g_output_file_name; -static char **g_input_files = NULL; -static gchar *input_mv_name = NULL; -static gchar *input_mbmode_name = NULL; -static guint input_mv_size; -static guint input_mbmode_size; -static guint input_qp; -static guint enable_mbcntrl; -static guint enable_mvpred; -static guint fei_mode; - -#define SURFACE_NUM 16 - -#define ENC 1 -#define PAK 2 -#define ENC_PLUS_PAK 3 -#define ENC_PAK 4 - -static GOptionEntry g_options[] = { - {"codec", 'c', 0, G_OPTION_ARG_STRING, &g_codec_str, - "codec to use for video encoding (h264)", NULL}, - {"bitrate", 'b', 0, G_OPTION_ARG_INT, &g_bitrate, - "desired bitrate expressed in kbps", NULL}, - {"output", 'o', 0, G_OPTION_ARG_FILENAME, &g_output_file_name, - "output file name", NULL}, - {"imv", 'v', 0, G_OPTION_ARG_STRING, &input_mv_name, - "pak mv input file", NULL}, - {"imbmode ", 'm', 0, G_OPTION_ARG_STRING, &input_mbmode_name, - "pak mbmode input file", NULL}, - {"imvsize", 's', 0, G_OPTION_ARG_INT, &input_mv_size, - "input stream width", NULL}, - {"imbmodesize", 'd', 0, G_OPTION_ARG_INT, &input_mbmode_size, - "input stream height", NULL}, - {"iqp", 'q', 0, G_OPTION_ARG_INT, &input_qp, - "input qp val (it will get replicated for each macrobock)", NULL}, - {"imbcntrl", 'l', 0, G_OPTION_ARG_INT, &enable_mbcntrl, - "enable macroblock control for each macrobock", NULL}, - {"imbpred", 'p', 0, G_OPTION_ARG_INT, &enable_mvpred, - "enable mv predictor for each macroblock", NULL}, - {"fei-mode", 'e', 0, G_OPTION_ARG_INT, &fei_mode, - "1:ENC 2:PAK 3:ENC+PAK 4:ENC_PAK", NULL}, - - {G_OPTION_REMAINING, ' ', 0, G_OPTION_ARG_FILENAME_ARRAY, &g_input_files, - "input file name", NULL}, - {NULL} -}; - -typedef struct -{ - GstVaapiDisplay *display; - GstVaapiEncoder *encoder; - guint read_frames; - guint encoded_frames; - guint saved_frames; - Y4MReader *parser; - FILE *output_file; - int mv_fd; - int mbmode_fd; - guint input_mv_size; - guint input_mbmode_size; - guint input_stopped:1; - guint encode_failed:1; -} App; - -static inline gchar * -generate_output_filename (const gchar * ext) -{ - gchar *fn; - int i = 0; - - while (1) { - fn = g_strdup_printf ("temp%02d.%s", i, ext); - if (g_file_test (fn, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { - i++; - g_free (fn); - } else { - break; - } - } - - return fn; -} - -static gboolean -parse_options (int *argc, char *argv[]) -{ - GOptionContext *ctx; - gboolean success; - GError *error = NULL; - - ctx = g_option_context_new (" - encoder test options"); - if (!ctx) - return FALSE; - - g_option_context_add_group (ctx, gst_init_get_option_group ()); - g_option_context_add_main_entries (ctx, g_options, NULL); - g_option_context_set_help_enabled (ctx, TRUE); - success = g_option_context_parse (ctx, argc, &argv, &error); - if (!success) { - g_printerr ("Option parsing failed: %s\n", error->message); - g_error_free (error); - goto bail; - } - - if (!g_codec_str) - g_codec_str = g_strdup ("h264"); - if (!g_output_file_name) - g_output_file_name = generate_output_filename (g_codec_str); - -bail: - g_option_context_free (ctx); - return success; -} - -static void -print_yuv_info (App * app) -{ - g_print ("\n"); - g_print ("Encode : %s\n", g_codec_str); - g_print ("Resolution : %dx%d\n", app->parser->width, app->parser->height); - g_print ("Source YUV : %s\n", g_input_files ? g_input_files[0] : "stdin"); - g_print ("Frame Rate : %0.1f fps\n", - 1.0 * app->parser->fps_n / app->parser->fps_d); - g_print ("Coded file : %s\n", g_output_file_name); - g_print ("\n"); -} - -static void -print_num_frame (App * app) -{ - g_print ("\n"); - g_print ("read frames : %d\n", app->read_frames); - g_print ("encoded frames : %d\n", app->encoded_frames); - g_print ("saved frames : %d\n", app->saved_frames); - g_print ("\n"); -} - -static GstVaapiEncoder * -encoder_new (GstVaapiDisplay * display) -{ - GstVaapiEncoder *encoder = NULL; - - if (!g_strcmp0 (g_codec_str, "h264")) { - encoder = gst_vaapi_encoder_h264_fei_new (display); - gst_vaapi_encoder_h264_fei_set_function_mode (GST_VAAPI_ENCODER_H264_FEI - (encoder), fei_mode); - gst_vaapi_encoder_h264_fei_set_max_profile (GST_VAAPI_ENCODER_H264_FEI - (encoder), GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE); - } else - return NULL; - - return encoder; -} - -static inline GstVideoCodecState * -new_codec_state (gint width, gint height, gint fps_n, gint fps_d) -{ - GstVideoCodecState *state; - - state = g_slice_new0 (GstVideoCodecState); - state->ref_count = 1; - gst_video_info_set_format (&state->info, GST_VIDEO_FORMAT_ENCODED, width, - height); - - state->info.fps_n = fps_n; - state->info.fps_d = fps_d; - - return state; -} - -static gboolean -set_format (GstVaapiEncoder * encoder, gint width, gint height, gint fps_n, - gint fps_d) -{ - GstVideoCodecState *in_state; - GstVaapiEncoderStatus status; - - in_state = new_codec_state (width, height, fps_n, fps_d); - status = gst_vaapi_encoder_set_codec_state (encoder, in_state); - g_slice_free (GstVideoCodecState, in_state); - - return (status == GST_VAAPI_ENCODER_STATUS_SUCCESS); -} - -static GstBuffer * -allocate_buffer (GstVaapiCodedBuffer * vbuf) -{ - GstBuffer *buf; - gssize size; - - size = gst_vaapi_coded_buffer_get_size (vbuf); - - if (size <= 0) { - g_warning ("Invalid VA buffer size (%zd)", size); - return NULL; - } - - buf = gst_buffer_new_and_alloc (size); - if (!buf) { - g_warning ("Failed to create output buffer of size %zd", size); - return NULL; - } - - if (!gst_vaapi_coded_buffer_copy_into (buf, vbuf)) { - g_warning ("Failed to copy VA buffer data"); - gst_buffer_unref (buf); - return NULL; - } - - return buf; -} - -static GstVaapiEncoderStatus -get_encoder_buffer (GstVaapiEncoder * encoder, GstBuffer ** buffer) -{ - GstVaapiCodedBufferProxy *proxy = NULL; - GstVaapiEncoderStatus status; - - status = gst_vaapi_encoder_get_buffer_with_timeout (encoder, &proxy, 50000); - if (status < GST_VAAPI_ENCODER_STATUS_SUCCESS) { - g_warning ("Failed to get a buffer from encoder: %d", status); - return status; - } else if (status > GST_VAAPI_ENCODER_STATUS_SUCCESS) { - return status; - } - - *buffer = allocate_buffer (GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (proxy)); - gst_vaapi_coded_buffer_proxy_unref (proxy); - - return status; -} - -static gboolean -outputs_to_file (GstBuffer * buffer, FILE * file) -{ - GstMapInfo info; - size_t written; - gboolean ret = FALSE; - - if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) - return FALSE; - - if (info.size <= 0 || !info.data) - return FALSE; - - written = fwrite (info.data, 1, info.size, file); - if (written < info.size) { - g_warning ("write file error."); - goto bail; - } - - ret = TRUE; - -bail: - gst_buffer_unmap (buffer, &info); - return ret; -} - -static gpointer -get_buffer_thread (gpointer data) -{ - App *app = data; - - GstVaapiEncoderStatus ret; - GstBuffer *obuf; - - while (1) { - obuf = NULL; - ret = get_encoder_buffer (app->encoder, &obuf); - if (app->input_stopped && ret > GST_VAAPI_ENCODER_STATUS_SUCCESS) { - break; /* finished */ - } else if (ret > GST_VAAPI_ENCODER_STATUS_SUCCESS) { /* another chance */ - continue; - } - if (ret < GST_VAAPI_ENCODER_STATUS_SUCCESS) { /* fatal error */ - app->encode_failed = TRUE; - break; - } - - app->encoded_frames++; - g_debug ("encoded frame %d, buffer = %p", app->encoded_frames, obuf); - - if (app->output_file && outputs_to_file (obuf, app->output_file)) - app->saved_frames++; - - gst_buffer_unref (obuf); - } - if (obuf) - gst_buffer_replace (&obuf, NULL); - - return NULL; -} - -static void -app_free (App * app) -{ - g_return_if_fail (app); - - if (app->parser) - y4m_reader_close (app->parser); - - if (app->encoder) { - gst_vaapi_encoder_flush (app->encoder); - gst_object_unref (app->encoder); - } - - if (app->display) - gst_object_unref (app->display); - - if (app->output_file) - fclose (app->output_file); - - g_slice_free (App, app); -} - -static App * -app_new (const gchar * input_fn, const gchar * output_fn) -{ - App *app = g_slice_new0 (App); - if (!app) - return NULL; - app->parser = y4m_reader_open (input_fn); - if (!app->parser) { - g_warning ("Could not parse input stream."); - goto error; - } - - app->output_file = fopen (output_fn, "w"); - if (app->output_file == NULL) { - g_warning ("Could not open file \"%s\" for writing: %s.", output_fn, - g_strerror (errno)); - goto error; - } - - /* if PAK only */ - if (fei_mode == 2) { - if (!input_mv_name || !input_mbmode_name) { - g_warning ("pak only mode need an mv and mbmode files as input"); - assert (0); - } - - if (input_mv_name) - app->mv_fd = open (input_mv_name, O_RDONLY, 0); - if (input_mbmode_name) - app->mbmode_fd = open (input_mbmode_name, O_RDONLY, 0); - - assert (app->mv_fd >= 0); - assert (app->mbmode_fd >= 0); - } - - app->display = video_output_create_display (NULL); - if (!app->display) { - g_warning ("Could not create VA display."); - goto error; - } - - app->encoder = encoder_new (app->display); - if (!app->encoder) { - g_warning ("Could not create encoder."); - goto error; - } - - if (!set_format (app->encoder, app->parser->width, app->parser->height, - app->parser->fps_n, app->parser->fps_d)) { - g_warning ("Could not set format."); - goto error; - } - - return app; - -error: - app_free (app); - return NULL; -} - -static gboolean -upload_frame (GstVaapiEncoder * encoder, GstVaapiSurfaceProxy * proxy) -{ - GstVideoCodecFrame *frame; - GstVaapiEncoderStatus ret; - - frame = g_slice_new0 (GstVideoCodecFrame); - gst_video_codec_frame_set_user_data (frame, - gst_vaapi_surface_proxy_ref (proxy), - (GDestroyNotify) gst_vaapi_surface_proxy_unref); - - ret = gst_vaapi_encoder_put_frame (encoder, frame); - return (ret == GST_VAAPI_ENCODER_STATUS_SUCCESS); -} - -static gboolean -load_frame (App * app, GstVaapiImage * image) -{ - gboolean ret = FALSE; - - if (!gst_vaapi_image_map (image)) - return FALSE; - - ret = y4m_reader_load_image (app->parser, image); - - if (!gst_vaapi_image_unmap (image)) - return FALSE; - - return ret; -} - -static int -app_run (App * app) -{ - GstVaapiImage *image; - GstVaapiVideoPool *pool; - GThread *buffer_thread; - gsize id; - gint i; - - int ret = EXIT_FAILURE; - image = gst_vaapi_image_new (app->display, GST_VIDEO_FORMAT_I420, - app->parser->width, app->parser->height); - - { - GstVideoInfo vi; - gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_ENCODED, - app->parser->width, app->parser->height); - pool = gst_vaapi_surface_pool_new_full (app->display, &vi, 0); - } - buffer_thread = g_thread_new ("get buffer thread", get_buffer_thread, app); - - while (1) { - GstVaapiSurfaceProxy *proxy; - GstVaapiSurface *surface; - gpointer data = NULL; - guint size = 0; - gint rt = 0; - guint mb_width, mb_height, mb_size; - - if (!load_frame (app, image)) - break; - - if (!gst_vaapi_image_unmap (image)) - break; - - proxy = - gst_vaapi_surface_proxy_new_from_pool (GST_VAAPI_SURFACE_POOL (pool)); - if (!proxy) { - g_warning ("Could not get surface proxy from pool."); - break; - } - surface = gst_vaapi_surface_proxy_get_surface (proxy); - if (!surface) { - g_warning ("Could not get surface from proxy."); - break; - } - - if (!gst_vaapi_surface_put_image (surface, image)) { - g_warning ("Could not update surface"); - break; - } - - mb_width = (app->parser->width + 15) >> 4; - mb_height = (app->parser->height + 15) >> 4; - mb_size = mb_width * mb_height; - - /* PAK Only */ - if (fei_mode == PAK) { - GstVaapiEncFeiMbCode *mbcode; - GstVaapiEncFeiMv *mv; - guint mv_size, mbmode_size; - - mv_size = mb_width * mb_height * 128; - mbmode_size = mb_width * mb_height * 64; - - if (input_mv_size) - assert (input_mv_size == mv_size); - - if (input_mbmode_size) - assert (input_mbmode_size == mbmode_size); - - /* Upload mbmode data */ - mbcode = gst_vaapi_enc_fei_mb_code_new (app->encoder, NULL, mbmode_size); - rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT (mbcode), - &data, &size); - assert (rt == 1); - rt = read (app->mbmode_fd, data, mbmode_size); - assert (rt >= 0); - - /* Upload mv data */ - mv = gst_vaapi_enc_fei_mv_new (app->encoder, NULL, mv_size); - rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT (mv), - &data, &size); - assert (rt == 1); - rt = read (app->mv_fd, data, mv_size); - assert (rt >= 0); - - /* assign mv and mbmode buffers to input surface proxy */ - gst_vaapi_surface_proxy_set_fei_mb_code (proxy, mbcode); - gst_vaapi_surface_proxy_set_fei_mv (proxy, mv); - - } else { - /* ENC, ENC+PAK and ENC_PAK */ - - if (input_qp) { - GstVaapiEncFeiQp *qp = NULL; - VAEncQPBufferH264 *pqp = NULL; - guint qp_size = 0; - - qp_size = mb_width * mb_height * sizeof (VAEncQPBufferH264); - - qp = gst_vaapi_enc_fei_qp_new (app->encoder, NULL, qp_size); - rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT (qp), - &data, &size); - assert (rt == 1); - - pqp = (VAEncQPBufferH264 *) data; - for (i = 0; i < mb_size; i++) { - pqp->qp = input_qp; - pqp++; - } - gst_vaapi_surface_proxy_set_fei_qp (proxy, qp); - } - - if (enable_mbcntrl) { - GstVaapiEncFeiMbControl *mbcntrl = NULL; - VAEncFEIMBControlH264 *pmbcntrl = NULL; - guint mbcntrl_size = 0; - - mbcntrl_size = mb_width * mb_height * sizeof (VAEncFEIMBControlH264); - mbcntrl = - gst_vaapi_enc_fei_mb_control_new (app->encoder, NULL, mbcntrl_size); - rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT - (mbcntrl), &data, &size); - assert (rt == 1); - - pmbcntrl = (VAEncFEIMBControlH264 *) data; - for (i = 0; i < mb_size; i++) { - pmbcntrl->force_to_intra = 1; - pmbcntrl->force_to_skip = 0; - pmbcntrl->force_to_nonskip = 0; - pmbcntrl->enable_direct_bias_adjustment = 0; - pmbcntrl->enable_motion_bias_adjustment = 0; - pmbcntrl->ext_mv_cost_scaling_factor = 0; - pmbcntrl->target_size_in_word = 0xff; - pmbcntrl->max_size_in_word = 0xff; - pmbcntrl++; - } - gst_vaapi_surface_proxy_set_fei_mb_control (proxy, mbcntrl); - } - - if (enable_mvpred) { - GstVaapiEncFeiMvPredictor *mvpred = NULL; - VAEncFEIMVPredictorH264 *pmvpred = NULL; - guint mvpred_size = 0, j; - - mvpred_size = mb_width * mb_height * sizeof (VAEncFEIMVPredictorH264); - mvpred = - gst_vaapi_enc_fei_mv_predictor_new (app->encoder, NULL, - mvpred_size); - rt = gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT - (mvpred), &data, &size); - assert (rt == 1); - - pmvpred = (VAEncFEIMVPredictorH264 *) data; - for (i = 0; i < mb_size; i++) { - for (j = 0; i < 4; i++) { - pmvpred->ref_idx[j].ref_idx_l0 = 0; - pmvpred->ref_idx[j].ref_idx_l1 = 0; - - pmvpred->mv[j].mv0[0] = 0x8000; - pmvpred->mv[j].mv0[1] = 0x8000; - pmvpred->mv[j].mv1[0] = 0x8000; - pmvpred->mv[j].mv1[1] = 0x8000; - } - pmvpred++; - } - gst_vaapi_surface_proxy_set_fei_mv_predictor (proxy, mvpred); - } - } - - if (!upload_frame (app->encoder, proxy)) { - g_warning ("put frame failed"); - break; - } - - app->read_frames++; - id = gst_vaapi_surface_get_id (surface); - g_debug ("input frame %d, surface id = %" G_GSIZE_FORMAT, app->read_frames, - id); - - gst_vaapi_surface_proxy_unref (proxy); - } - - app->input_stopped = TRUE; - - g_thread_join (buffer_thread); - - if (!app->encode_failed && feof (app->parser->fp)) - ret = EXIT_SUCCESS; - - gst_vaapi_video_pool_replace (&pool, NULL); - gst_vaapi_image_unref (image); - return ret; -} - -int -main (int argc, char *argv[]) -{ - App *app; - int ret = EXIT_FAILURE; - gchar *input_fn; - - if (!parse_options (&argc, argv)) - return EXIT_FAILURE; - - /* @TODO: iterate all the input files */ - input_fn = g_input_files ? g_input_files[0] : NULL; - if (input_fn && !g_file_test (input_fn, - G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { - g_warning ("input file \"%s\" doesn't exist", input_fn); - goto bail; - } - - app = app_new (input_fn, g_output_file_name); - if (!app) - goto bail; - print_yuv_info (app); - ret = app_run (app); - print_num_frame (app); - - app_free (app); - -bail: - g_free (g_codec_str); - g_free (g_output_file_name); - g_strfreev (g_input_files); - - gst_deinit (); - - return ret; -} diff --git a/tests/internal/test-fei-enc-out.c b/tests/internal/test-fei-enc-out.c deleted file mode 100644 index 3232643452..0000000000 --- a/tests/internal/test-fei-enc-out.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * test-fei-enc-out.c - FEI Encoder Test application to dump output buffers - * - * Copyright (C) 2017 Intel Corporation - * - * 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 - */ - -/* ./test-fei-enc -i sample_320x240.nv12 -f nv12 -w 320 -h 240 -o out.264 -v mv.out -d dist.out -m mbcode.out -e 1 */ - -#include -#include -#include -#include -#include "../gst/vaapi/gstvaapifeivideometa.h" -#include - -int -main (int argc, char *argv[]) -{ - GstElement *pipeline, *filesrc, *videoparse, *enc, *capsfilter, *appsink; - GError *err = NULL; - GstStateChangeReturn ret; - GstSample *sample; - GstVideoFormat raw_format = GST_VIDEO_FORMAT_NV12; - GOptionContext *ctx; - FILE *file = NULL; - FILE *mv_file = NULL; - FILE *dist_file = NULL; - FILE *mbcode_file = NULL; - FILE *fei_stat_file = NULL; - gchar *input_file_name = NULL; - gchar *output_file_name = NULL; - gchar *output_mv_name = NULL; - gchar *output_distortion_name = NULL; - gchar *output_mbcode_name = NULL; - gchar *input_format; - guint input_width; - guint input_height; - guint enc_frame_num = 0; - guint block_size = 0; - guint fei_mode = 1; - guint fei_mode_flag = 0x00000004; - gboolean link_ok = FALSE; - guint mv_buffer_size = 0; - guint mbcode_buffer_size = 0; - guint dist_buffer_size = 0; - gpointer mapped_data = NULL; - guint mapped_data_size = 0; - const gchar *caps_string = "video/x-h264, profile=constrained-baseline"; - GstCaps *filter_caps = NULL; - - GOptionEntry options[] = { - {"input file", 'i', 0, G_OPTION_ARG_STRING, &input_file_name, - "file to encode", NULL}, - {"output file", 'o', 0, G_OPTION_ARG_STRING, &output_file_name, - "encpak output file", NULL}, - {"output mv file", 'v', 0, G_OPTION_ARG_STRING, &output_mv_name, - "encpak mv output file", NULL}, - {"output distortion file", 'd', 0, G_OPTION_ARG_STRING, - &output_distortion_name, - "encpak distortion output file", NULL}, - {"output mbcode file", 'm', 0, G_OPTION_ARG_STRING, &output_mbcode_name, - "encpak mbcode output file", NULL}, - {"format", 'f', 0, G_OPTION_ARG_STRING, &input_format, - "input raw format: nv12 or i420", NULL}, - {"width", 'w', 0, G_OPTION_ARG_INT, &input_width, - "input stream width", NULL}, - {"height", 'h', 0, G_OPTION_ARG_INT, &input_height, - "input stream height", NULL}, - {"frame-num", 'n', 0, G_OPTION_ARG_INT, &enc_frame_num, - "numumber of buffers to be encoded", NULL}, - {"blocksize", 's', 0, G_OPTION_ARG_INT, &block_size, - "single buffer size of input stream", NULL}, - {"fei-mode", 'e', 0, G_OPTION_ARG_INT, &fei_mode, - "1: ENC_PAK 2: ENC+PAK", NULL}, - {NULL} - }; - - ctx = - g_option_context_new - ("encpak with element filesrc, videoparse, vaapih264feienc, appsink"); - g_option_context_add_main_entries (ctx, options, NULL); - g_option_context_add_group (ctx, gst_init_get_option_group ()); - - if (!g_option_context_parse (ctx, &argc, &argv, &err)) { - g_print ("Error intializing: %s\n", err->message); - g_option_context_free (ctx); - g_clear_error (&err); - return -1; - } - - if (input_file_name == NULL || output_file_name == NULL) { - g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL)); - g_option_context_free (ctx); - return -1; - } - - if (!g_strcmp0 (input_format, "nv12")) - raw_format = GST_VIDEO_FORMAT_NV12; - else if (!g_strcmp0 (input_format, "i420")) - raw_format = GST_VIDEO_FORMAT_I420; - else - return -1; - - if (!input_width || !input_height) { - g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL)); - g_option_context_free (ctx); - return -1; - } - - switch (fei_mode) { - case 1: - fei_mode_flag = 0x00000004; - break; - case 2: - fei_mode_flag = 0x00000001 | 0x00000002; - break; - default: - printf ("Unknown fei mode \n"); - g_assert (0); - break; - } - - g_option_context_free (ctx); - - gst_init (&argc, &argv); - - /* create pipeline */ - pipeline = gst_pipeline_new ("pipeline"); - filesrc = gst_element_factory_make ("filesrc", "source"); - videoparse = gst_element_factory_make ("videoparse", "videoparse"); - enc = gst_element_factory_make ("vaapih264feienc", "encpak"); - capsfilter = gst_element_factory_make ("capsfilter", "enccaps"); - appsink = gst_element_factory_make ("appsink", "sink"); - - /* element prop setup */ - g_object_set (G_OBJECT (filesrc), "location", input_file_name, NULL); - g_object_set (G_OBJECT (videoparse), "format", raw_format, - "width", input_width, "height", input_height, NULL); - - if (enc_frame_num != 0) - g_object_set (G_OBJECT (filesrc), "num-buffers", enc_frame_num, NULL); - if (block_size != 0) - g_object_set (G_OBJECT (filesrc), "blocksize", block_size, NULL); - - g_object_set (G_OBJECT (enc), "fei-mode", fei_mode_flag, NULL); - g_object_set (G_OBJECT (enc), "search-window", 5, NULL); - g_object_set (G_OBJECT (enc), "max-bframes", 0, NULL); - - filter_caps = gst_caps_from_string (caps_string); - if (filter_caps) - g_object_set (G_OBJECT (capsfilter), "caps", filter_caps, NULL); - gst_caps_unref (filter_caps); - - gst_bin_add_many (GST_BIN (pipeline), filesrc, videoparse, enc, capsfilter, - appsink, NULL); - - link_ok = - gst_element_link_many (filesrc, videoparse, enc, capsfilter, appsink, - NULL); - if (!link_ok) { - g_print ("filesrc, enc and appsink link fail"); - return -1; - } - - file = fopen (output_file_name, "wb"); - - if (output_mv_name != NULL) - mv_file = fopen (output_mv_name, "wb"); - - if (output_mbcode_name != NULL) - mbcode_file = fopen (output_mbcode_name, "wb"); - - if (output_distortion_name != NULL) - dist_file = fopen (output_distortion_name, "wb"); - - ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); - if (ret == GST_STATE_CHANGE_FAILURE) { - g_printerr ("Unable to set the pipeline to the playing state.\n"); - gst_object_unref (pipeline); - return -1; - } - - /* pull sample from pipeline */ - while (1) { - g_signal_emit_by_name (appsink, "pull-sample", &sample, NULL); - if (sample) { - GstBuffer *buffer = NULL; - GstMapInfo map, info; - GstMemory *mem; - GstVaapiFeiVideoMeta *meta = NULL; - GstMeta *m = NULL; - const GstMetaInfo *meta_info; - GType api; - - g_debug ("appsink received sample.\n"); - buffer = gst_sample_get_buffer (sample); - if (gst_buffer_map (buffer, &map, GST_MAP_READ)) { - mem = gst_buffer_peek_memory (buffer, 0); - if (gst_memory_map (mem, &info, GST_MAP_READ)) - fwrite (info.data, 1, info.size, file); - - gst_memory_unmap (mem, &info); - gst_buffer_unmap (buffer, &map); - } - - meta_info = gst_meta_get_info ("GstVaapiFeiVideoMeta"); - api = meta_info->api; - m = gst_buffer_get_meta (buffer, api); - if (m != NULL) - meta = ((GstVaapiFeiVideoMetaHolder *) (m))->meta; - - if (meta != NULL) { - - if (mv_file != NULL) { - mapped_data = NULL; - mapped_data_size = 0; - if (gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT - (meta->mv), &mapped_data, &mapped_data_size)) { - fwrite (mapped_data, 1, mapped_data_size, mv_file); - gst_vaapi_fei_codec_object_unmap (GST_VAAPI_FEI_CODEC_OBJECT - (meta->mv)); - mv_buffer_size = mapped_data_size; - } - } - - if (mbcode_file != NULL) { - mapped_data = NULL; - mapped_data_size = 0; - if (gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT - (meta->mbcode), &mapped_data, &mapped_data_size)) { - fwrite (mapped_data, 1, mapped_data_size, mbcode_file); - gst_vaapi_fei_codec_object_unmap (GST_VAAPI_FEI_CODEC_OBJECT - (meta->mbcode)); - mbcode_buffer_size = mapped_data_size; - } - } - - if (dist_file != NULL) { - mapped_data = NULL; - mapped_data_size = 0; - if (gst_vaapi_fei_codec_object_map (GST_VAAPI_FEI_CODEC_OBJECT - (meta->dist), &mapped_data, &mapped_data_size)) { - fwrite (mapped_data, 1, mapped_data_size, dist_file); - gst_vaapi_fei_codec_object_unmap (GST_VAAPI_FEI_CODEC_OBJECT - (meta->dist)); - dist_buffer_size = mapped_data_size; - } - } - } - - gst_sample_unref (sample); - } else { - g_print ("appsink finished receive sample.\n"); - break; - } - } - - /* Fixme: Currently assuming the input video has only one resoultion - * which may not be true */ - /* create a status file for dumping size of each fei output buffer */ - if (output_mv_name || output_mbcode_name || output_distortion_name) { - fei_stat_file = fopen ("fei_stat.out", "wb"); - fprintf (fei_stat_file, "Frame_MotionVectorData_Buffer_Size => %d \n", - mv_buffer_size); - fprintf (fei_stat_file, "Frame_MacroblcokCode_Buffer_Size => %d \n", - mbcode_buffer_size); - fprintf (fei_stat_file, "Frame_Distortion_Buffer_Size => %d \n", - dist_buffer_size); - } - - /* free */ - fclose (file); - if (mv_file != NULL) - fclose (mv_file); - if (mbcode_file != NULL) - fclose (mbcode_file); - if (dist_file != NULL) - fclose (dist_file); - if (fei_stat_file) - fclose (fei_stat_file); - - gst_element_set_state (pipeline, GST_STATE_NULL); - gst_object_unref (pipeline); - return 0; -} From 6c7d4450109eb00955a49842dbc32609622b3cc1 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 26 Dec 2019 16:45:51 +0800 Subject: [PATCH 3476/3781] libs: encoder: h265: Set encoder paramters base on entrypoint. When the tune is NONE, we now can choose entrypoint freely. So the GST_VAAPI_ENCODER_TUNE macro may not return the correct current entrypoint. We also delay CTU size calculation after entrypoint has been decided. --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index c7bfed9e6e..9407de96a7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1577,7 +1577,7 @@ fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) /* Based on 32x32 CTU (64x64 when using lowpower mode for hardware limitation) */ seq_param->log2_min_luma_coding_block_size_minus3 = 0; - if (GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) + if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) seq_param->log2_diff_max_min_luma_coding_block_size = 3; else seq_param->log2_diff_max_min_luma_coding_block_size = 2; @@ -1677,7 +1677,7 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, /* it seems driver requires enablement of cu_qp_delta_enabled_flag * to modifiy QP values in CBR mode or low power encoding */ if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CQP - || GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) + || encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) pic_param->pic_fields.bits.cu_qp_delta_enabled_flag = 1; /* XXX: Intel's media-driver, when using low-power mode, requires @@ -1686,7 +1686,7 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, * * For now we assume that on only Intel's media-drivers supports * H265 low-power */ - if ((GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) && + if ((encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) && (pic_param->pic_fields.bits.cu_qp_delta_enabled_flag)) pic_param->diff_cu_qp_delta_depth = 3; @@ -2605,13 +2605,6 @@ gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) GST_VAAPI_ENCODER_HEIGHT (encoder)); encoder->luma_width = GST_ROUND_UP_16 (luma_width); encoder->luma_height = GST_ROUND_UP_16 (luma_height); - if (GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER) { - encoder->ctu_width = (encoder->luma_width + 63) / 64; - encoder->ctu_height = (encoder->luma_height + 63) / 64; - } else { - encoder->ctu_width = (encoder->luma_width + 31) / 32; - encoder->ctu_height = (encoder->luma_height + 31) / 32; - } encoder->config_changed = TRUE; /* Frame Cropping */ if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) || @@ -2634,6 +2627,15 @@ gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; + /* Set ctu size based on entrypoint. */ + if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) { + encoder->ctu_width = (encoder->luma_width + 63) / 64; + encoder->ctu_height = (encoder->luma_height + 63) / 64; + } else { + encoder->ctu_width = (encoder->luma_width + 31) / 32; + encoder->ctu_height = (encoder->luma_height + 31) / 32; + } + reset_properties (encoder); ensure_control_rate_params (encoder); return set_context_info (base_encoder); From c864e20d2cdc80377393062ea764049bb74b9924 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Thu, 16 Jan 2020 09:14:30 +0800 Subject: [PATCH 3477/3781] Add hooks/pre-commit.hook meson.build in gstreamer-vaapi requires hooks/pre-commit.hook Copied and pasted pre-commit.hook from other gstreamer modules to make sure gstreamer-vaapi follows the same code style --- hooks/pre-commit.hook | 83 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100755 hooks/pre-commit.hook diff --git a/hooks/pre-commit.hook b/hooks/pre-commit.hook new file mode 100755 index 0000000000..6f177402b3 --- /dev/null +++ b/hooks/pre-commit.hook @@ -0,0 +1,83 @@ +#!/bin/sh +# +# Check that the code follows a consistent code style +# + +# Check for existence of indent, and error out if not present. +# On some *bsd systems the binary seems to be called gnunindent, +# so check for that first. + +version=`gnuindent --version 2>/dev/null` +if test "x$version" = "x"; then + version=`gindent --version 2>/dev/null` + if test "x$version" = "x"; then + version=`indent --version 2>/dev/null` + if test "x$version" = "x"; then + echo "GStreamer git pre-commit hook:" + echo "Did not find GNU indent, please install it before continuing." + exit 1 + else + INDENT=indent + fi + else + INDENT=gindent + fi +else + INDENT=gnuindent +fi + +case `$INDENT --version` in + GNU*) + ;; + default) + echo "GStreamer git pre-commit hook:" + echo "Did not find GNU indent, please install it before continuing." + echo "(Found $INDENT, but it doesn't seem to be GNU indent)" + exit 1 + ;; +esac + +INDENT_PARAMETERS="--braces-on-if-line \ + --case-brace-indentation0 \ + --case-indentation2 \ + --braces-after-struct-decl-line \ + --line-length80 \ + --no-tabs \ + --cuddle-else \ + --dont-line-up-parentheses \ + --continuation-indentation4 \ + --honour-newlines \ + --tab-size8 \ + --indent-level2 \ + --leave-preprocessor-space" + +echo "--Checking style--" +for file in `git diff-index --cached --name-only HEAD --diff-filter=ACMR| grep "\.c$"` ; do + # nf is the temporary checkout. This makes sure we check against the + # revision in the index (and not the checked out version). + nf=`git checkout-index --temp ${file} | cut -f 1` + newfile=`mktemp /tmp/${nf}.XXXXXX` || exit 1 + $INDENT ${INDENT_PARAMETERS} \ + $nf -o $newfile 2>> /dev/null + # FIXME: Call indent twice as it tends to do line-breaks + # different for every second call. + $INDENT ${INDENT_PARAMETERS} \ + $newfile 2>> /dev/null + diff -u -p "${nf}" "${newfile}" + r=$? + rm "${newfile}" + rm "${nf}" + if [ $r != 0 ] ; then +echo "=================================================================================================" +echo " Code style error in: $file " +echo " " +echo " Please fix before committing. Don't forget to run git add before trying to commit again. " +echo " If the whole file is to be committed, this should work (run from the top-level directory): " +echo " " +echo " gst-indent $file; git add $file; git commit" +echo " " +echo "=================================================================================================" + exit 1 + fi +done +echo "--Checking style pass--" From 1db3ce56a072a8760151ffd5d523e6a04ea9f634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 15 Jan 2020 23:04:08 +0100 Subject: [PATCH 3478/3781] vaapiencode: DMABuf only if PRIME is available Add DMABuf capsfeature in encoders' allowed sinkcaps only if PRIME memory type is available in the VA surface attributes of codec context. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 7 +++++-- gst-libs/gst/vaapi/gstvaapiencoder.h | 2 +- gst-libs/gst/vaapi/gstvaapiprofilecaps.c | 16 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapiprofilecaps.h | 3 +++ gst/vaapi/gstvaapiencode.c | 22 ++++++++++++---------- 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 1714707d25..690caf77e9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1533,6 +1533,7 @@ merge_profile_surface_attributes (GstVaapiEncoder * encoder, attribs->min_height = MIN (attribs->min_height, attr.min_height); attribs->max_width = MAX (attribs->max_width, attr.max_width); attribs->max_height = MAX (attribs->max_height, attr.max_height); + attribs->mem_types &= attr.mem_types; return TRUE; } @@ -1553,10 +1554,10 @@ merge_profile_surface_attributes (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) + gint * max_width, gint * max_height, guint * mem_types) { GstVaapiConfigSurfaceAttributes attribs = { - G_MAXINT, G_MAXINT, 1, 1, 0, NULL + G_MAXINT, G_MAXINT, 1, 1, G_MAXUINT, NULL }; GstVaapiProfile profile; guint i; @@ -1586,6 +1587,8 @@ gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder, *max_width = attribs.max_width; if (max_height) *max_height = attribs.max_height; + if (mem_types) + *mem_types = attribs.mem_types; return attribs.formats; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 71da2be16b..bf89df2732 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -183,7 +183,7 @@ 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); + gint * max_width, gint * max_height, guint * mem_types); GstVaapiProfile gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder); diff --git a/gst-libs/gst/vaapi/gstvaapiprofilecaps.c b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c index a98d0e0df0..0e44393513 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofilecaps.c +++ b/gst-libs/gst/vaapi/gstvaapiprofilecaps.c @@ -117,3 +117,19 @@ gst_vaapi_profile_caps_append_decoder (GstVaapiDisplay * display, return append_caps_with_context_info (display, &cip, structure); } + +/** + * gst_vaapi_mem_type_supports: + * @va_mem_types: memory types from VA surface attributes + * @mem_type: the #GstVaapiBufferMemoryType to test + * + * Test if @va_mem_types handles @mem_type + * + * Returns: %TRUE if @mem_type is supported in @va_mem_types; + * otherwise %FALSE + **/ +gboolean +gst_vaapi_mem_type_supports (guint va_mem_types, guint mem_type) +{ + return ((va_mem_types & from_GstVaapiBufferMemoryType (mem_type)) != 0); +} diff --git a/gst-libs/gst/vaapi/gstvaapiprofilecaps.h b/gst-libs/gst/vaapi/gstvaapiprofilecaps.h index 24eb82ce2d..a33ebc92b7 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofilecaps.h +++ b/gst-libs/gst/vaapi/gstvaapiprofilecaps.h @@ -33,6 +33,9 @@ gboolean gst_vaapi_profile_caps_append_decoder (GstVaapiDisplay * display, GstVaapiProfile profile, GstStructure * structure); +gboolean +gst_vaapi_mem_type_supports (guint va_mem_types, guint mem_type); + G_END_DECLS #endif /* GST_VAAPI_PROFILE_CAPS_H */ diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index ccd33569ba..2cf7582839 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -366,6 +366,7 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) guint i, size; GstStructure *structure; gint min_width, min_height, max_width, max_height; + guint mem_types; if (encode->allowed_sinkpad_caps) return TRUE; @@ -380,7 +381,7 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) /* Then get all supported formats, all these formats should be recognized in video-format map. */ formats = gst_vaapi_encoder_get_surface_attributes (encode->encoder, profiles, - &min_width, &min_height, &max_width, &max_height); + &min_width, &min_height, &max_width, &max_height, &mem_types); if (!formats) goto failed_get_attributes; @@ -398,19 +399,20 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) max_width, "height", GST_TYPE_INT_RANGE, min_height, max_height, NULL); } + out_caps = gst_caps_copy (raw_caps); + va_caps = gst_caps_copy (raw_caps); gst_caps_set_features_simple (va_caps, gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE)); - - dma_caps = gst_caps_copy (raw_caps); - gst_caps_set_features_simple (dma_caps, - gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF)); - - /* collect all caps together. */ - out_caps = raw_caps; - raw_caps = NULL; gst_caps_append (out_caps, va_caps); - gst_caps_append (out_caps, dma_caps); + + if (gst_vaapi_mem_type_supports (mem_types, + GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF)) { + dma_caps = gst_caps_copy (raw_caps); + gst_caps_set_features_simple (dma_caps, + gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF)); + gst_caps_append (out_caps, dma_caps); + } gst_caps_replace (&encode->allowed_sinkpad_caps, out_caps); GST_INFO_OBJECT (encode, "Allowed sink caps %" GST_PTR_FORMAT, From 633ec9834910c848883f0aae97a0580005936b88 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 15 Jan 2020 19:36:00 +0800 Subject: [PATCH 3479/3781] libs: encoder: h265: Consider main-444 profile when encoding. Add support of main-444 profile for parameter setting and packed header generation. --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 73 ++++++++++++++++++++--- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 9407de96a7..991423721f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -233,7 +233,7 @@ bs_error: /* Write profile_tier_level() */ static gboolean bs_write_profile_tier_level (GstBitWriter * bs, - const VAEncSequenceParameterBufferHEVC * seq_param) + const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile) { guint i; @@ -280,8 +280,15 @@ bs_write_profile_tier_level (GstBitWriter * bs, WRITE_UINT32 (bs, 0, 1); } - /* general_profile_compatibility_flag[4~32] */ - WRITE_UINT32 (bs, 0, 28); + /* general_profile_compatibility_flag[4] */ + if (seq_param->general_profile_idc == 4) { /* format range extensions profiles */ + WRITE_UINT32 (bs, 1, 1); + } else { + WRITE_UINT32 (bs, 0, 1); + } + + /* general_profile_compatibility_flag[5~32] */ + WRITE_UINT32 (bs, 0, 27); /* general_progressive_source_flag */ WRITE_UINT32 (bs, 1, 1); @@ -291,9 +298,47 @@ bs_write_profile_tier_level (GstBitWriter * bs, WRITE_UINT32 (bs, 0, 1); /* general_frame_only_constraint_flag */ WRITE_UINT32 (bs, 1, 1); - /* general_reserved_zero_43bits */ - for (i = 0; i < 43; i++) - WRITE_UINT32 (bs, 0, 1); + + /* additional indications specified for general_profile_idc from 4~10 */ + if (seq_param->general_profile_idc == 4) { + /* In A.3.5, Format range extensions profiles. + Just support main444 profile now, may add more profiles when needed. */ + switch (profile) { + case GST_VAAPI_PROFILE_H265_MAIN_444: + /* max_12bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_10bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_8bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_422chroma_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_420chroma_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_monochrome_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* intra_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* one_picture_only_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* lower_bit_rate_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + break; + default: + GST_WARNING ("do not support the profile: %s of range extensions", + gst_vaapi_profile_get_va_name (profile)); + goto bs_error; + } + + /* general_reserved_zero_34bits */ + for (i = 0; i < 34; i++) + WRITE_UINT32 (bs, 0, 1); + } else { + /* general_reserved_zero_43bits */ + for (i = 0; i < 43; i++) + WRITE_UINT32 (bs, 0, 1); + } + /* general_inbld_flag */ WRITE_UINT32 (bs, 0, 1); /* general_level_idc */ @@ -344,7 +389,7 @@ bs_write_vps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, WRITE_UINT32 (bs, 0xffff, 16); /* profile_tier_level */ - bs_write_profile_tier_level (bs, seq_param); + bs_write_profile_tier_level (bs, seq_param, profile); /* vps_sub_layer_ordering_info_present_flag */ WRITE_UINT32 (bs, vps_sub_layer_ordering_info_present_flag, 1); @@ -397,6 +442,7 @@ bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, guint32 video_parameter_set_id = 0; guint32 max_sub_layers_minus1 = 0; guint32 temporal_id_nesting_flag = 1; + guint32 separate_colour_plane_flag = 0; guint32 seq_parameter_set_id = 0; guint32 sps_sub_layer_ordering_info_present_flag = 0; guint32 sps_max_latency_increase_plus1 = 0; @@ -415,12 +461,15 @@ bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, WRITE_UINT32 (bs, temporal_id_nesting_flag, 1); /* profile_tier_level */ - bs_write_profile_tier_level (bs, seq_param); + bs_write_profile_tier_level (bs, seq_param, profile); /* seq_parameter_set_id */ WRITE_UE (bs, seq_parameter_set_id); /* chroma_format_idc = 1, 4:2:0 */ WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc); + if (seq_param->seq_fields.bits.chroma_format_idc == 3) + /* if( chroma_format_idc == 3 ) separate_colour_plane_flag */ + WRITE_UINT32 (bs, separate_colour_plane_flag, 1); /* pic_width_in_luma_samples */ WRITE_UE (bs, seq_param->pic_width_in_luma_samples); /* pic_height_in_luma_samples */ @@ -1561,7 +1610,13 @@ fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) /*sequence field values */ seq_param->seq_fields.value = 0; - seq_param->seq_fields.bits.chroma_format_idc = 1; + seq_param->seq_fields.bits.chroma_format_idc = + gst_vaapi_utils_h265_get_chroma_format_idc + (gst_vaapi_video_format_get_chroma_type (GST_VIDEO_INFO_FORMAT + (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)))); + /* the 4:4:4 chrome format */ + if (seq_param->seq_fields.bits.chroma_format_idc == 3) + seq_param->seq_fields.bits.separate_colour_plane_flag = 0; seq_param->seq_fields.bits.separate_colour_plane_flag = 0; seq_param->seq_fields.bits.bit_depth_luma_minus8 = bits_depth_luma_minus8; seq_param->seq_fields.bits.bit_depth_chroma_minus8 = bits_depth_luma_minus8; From 25422b6766ceb18778067f34e6d6b19da74bed8d Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 22 Jun 2019 00:44:25 +0800 Subject: [PATCH 3480/3781] plugin: encode: Add H265 main-444 profile. Expose the main-444 profile to h265enc caps, when the upstream chooses to use VUYA as input, we choose main 4:4:4 profile to encode the frames. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 3 ++- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 2 ++ gst-libs/gst/vaapi/gstvaapiutils_h265.c | 1 + gst/vaapi/gstvaapiencode_h265.c | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 690caf77e9..771a82b7e6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -677,7 +677,8 @@ is_chroma_type_supported (GstVaapiEncoder * encoder) if (cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420 && cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV422 && - cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420_10BPP) + cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420_10BPP && + cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV444) goto unsupported; if (!get_config_attribute (encoder, VAConfigAttribRTFormat, &format)) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 991423721f..8f5cd91de6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1082,6 +1082,8 @@ ensure_profile (GstVaapiEncoderH265 * encoder) if (format == GST_VIDEO_FORMAT_P010_10LE) profile = GST_VAAPI_PROFILE_H265_MAIN10; + else if (format == GST_VIDEO_FORMAT_VUYA) + profile = GST_VAAPI_PROFILE_H265_MAIN_444; encoder->profile = profile; encoder->profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 5b3bef10f8..2c078e820d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -40,6 +40,7 @@ static const struct map gst_vaapi_h265_profile_map[] = { { GST_VAAPI_PROFILE_H265_MAIN, "main" }, { GST_VAAPI_PROFILE_H265_MAIN10, "main-10" }, { GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE, "main-still-picture" }, + { GST_VAAPI_PROFILE_H265_MAIN_444, "main-444" }, { 0, NULL } /* *INDENT-ON* */ }; diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index a3325e6a4f..67a319c81e 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -65,7 +65,7 @@ static const char gst_vaapiencode_h265_sink_caps_str[] = /* *INDENT-OFF* */ static const char gst_vaapiencode_h265_src_caps_str[] = GST_CODEC_CAPS ", " - "profile = (string) { main, main-10 }"; + "profile = (string) { main, main-10, main-444 }"; /* *INDENT-ON* */ /* *INDENT-OFF* */ From 6eafebc80474cc8a19d5e886b19948dbc52944f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Jan 2020 14:22:48 +0100 Subject: [PATCH 3481/3781] vaapih264enc: fix log message Before the log wasn't processed because wrong instance pointer. --- gst/vaapi/gstvaapiencode_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 3a119bccbb..f623f67b40 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -361,8 +361,6 @@ retry: ret = TRUE; } - GST_INFO_OBJECT (encode, "out caps %" GST_PTR_FORMAT, caps); - if (!ret) GST_LOG ("There is no compatible profile in the requested caps."); @@ -390,6 +388,8 @@ gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) if (profile != GST_VAAPI_PROFILE_UNKNOWN) set_compatible_profile (encode, caps, profile); + GST_INFO_OBJECT (base_encode, "out caps %" GST_PTR_FORMAT, caps); + /* XXX: update level information */ return caps; } From eda173b3b089fc6da88c8fb77b9f9bdacb83dfb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Jan 2020 12:54:21 +0100 Subject: [PATCH 3482/3781] libs: encoder: unref formats array if none The formats array is always created, in order to keep the logic and to avoid broken caps, if this formats array doesn't contain any elements, it has to be unref and the function should return NULL. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 771a82b7e6..edc443ab79 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1577,8 +1577,10 @@ gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder, } } - if (!attribs.formats) + if (attribs.formats->len == 0) { + g_array_unref (attribs.formats); return NULL; + } if (min_width) *min_width = attribs.min_width; From a56ac3bffe707af5a22172097a69ba19f34a8539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Jan 2020 13:18:28 +0100 Subject: [PATCH 3483/3781] vaapih264enc: common fail for gst_vaapiencode_h264_set_config() Add a common fail code path for gst_vaapiencode_h264_set_config(). --- gst/vaapi/gstvaapiencode_h264.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index f623f67b40..2ef1cae3a1 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -261,9 +261,7 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) encode->is_avc = FALSE; } else if (gst_caps_is_empty (allowed_caps)) { GST_INFO_OBJECT (encode, "downstream has EMPTY caps"); - gst_caps_unref (template_caps); - gst_caps_unref (allowed_caps); - return FALSE; + goto fail; } else { const char *stream_format = NULL; GstStructure *structure; @@ -272,11 +270,9 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) GstCaps *available_caps; available_caps = get_available_caps (encode); - if (!available_caps) { - gst_caps_unref (template_caps); - gst_caps_unref (allowed_caps); - return FALSE; - } + if (!available_caps) + goto fail; + if (!gst_caps_can_intersect (allowed_caps, available_caps)) { GST_INFO_OBJECT (encode, "downstream requested an unsupported profile, " "but encoder will try to output a compatible one"); @@ -319,6 +315,13 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) base_encode->need_codec_data = encode->is_avc; return ret; + +fail: + { + gst_caps_unref (template_caps); + gst_caps_unref (allowed_caps); + return FALSE; + } } static void From 8b4d18da0a63769dc4263f0b3dbc800b11eaf428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Jan 2020 12:58:58 +0100 Subject: [PATCH 3484/3781] vaapih264enc: propose new profile caps and fixate it When the available caps doesn't intersect with the allowed caps in the pipeline, a new caps is proposed rather than just expecting to iterate. Later, the intersected caps (profile_caps) is fixated in order to extract the configuration. --- gst/vaapi/gstvaapiencode_h264.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 2ef1cae3a1..1c84094e92 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -265,39 +265,35 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) } else { const char *stream_format = NULL; GstStructure *structure; - guint i, num_structures; GstVaapiProfile profile = GST_VAAPI_PROFILE_UNKNOWN; GstCaps *available_caps; + GstCaps *profile_caps; available_caps = get_available_caps (encode); if (!available_caps) goto fail; if (!gst_caps_can_intersect (allowed_caps, available_caps)) { - GST_INFO_OBJECT (encode, "downstream requested an unsupported profile, " - "but encoder will try to output a compatible one"); + GST_INFO_OBJECT (encode, "downstream may have requested an unsupported " + "profile. Encoder will try to output a compatible one"); /* Let's try the best profile in the allowed caps. * The internal encoder will fail later if it can't handle it */ profile = find_best_profile (allowed_caps); + if (profile == GST_VAAPI_PROFILE_UNKNOWN) + goto fail; + profile_caps = gst_caps_from_string (GST_CODEC_CAPS); + gst_caps_set_simple (profile_caps, "profile", G_TYPE_STRING, + gst_vaapi_profile_get_name (profile), NULL); } else { - GstCaps *profile_caps; profile_caps = gst_caps_intersect (allowed_caps, available_caps); profile = find_best_profile (profile_caps); - - gst_caps_unref (profile_caps); } - /* Check whether "stream-format" is avcC mode */ - num_structures = gst_caps_get_size (allowed_caps); - for (i = 0; !stream_format && i < num_structures; i++) { - structure = gst_caps_get_structure (allowed_caps, i); - if (!gst_structure_has_field_typed (structure, "stream-format", - G_TYPE_STRING)) - continue; - stream_format = gst_structure_get_string (structure, "stream-format"); - } + profile_caps = gst_caps_fixate (profile_caps); + structure = gst_caps_get_structure (profile_caps, 0); + stream_format = gst_structure_get_string (structure, "stream-format"); encode->is_avc = (g_strcmp0 (stream_format, "avc") == 0); if (profile != GST_VAAPI_PROFILE_UNKNOWN) { @@ -308,6 +304,7 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) ret = FALSE; } + gst_caps_unref (profile_caps); gst_caps_unref (allowed_caps); } gst_caps_unref (template_caps); From 38d7297bb62964837ec158fcc4f490e09b59bb23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Jan 2020 13:07:04 +0100 Subject: [PATCH 3485/3781] vaapih264enc: intersect the new proposed caps Instead of just leave to keep the proposed caps, with the best profile in the allowed caps, is its intersected again. --- gst/vaapi/gstvaapiencode_h264.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 1c84094e92..987f72c9ef 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -274,6 +274,8 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) goto fail; if (!gst_caps_can_intersect (allowed_caps, available_caps)) { + GstCaps *tmp_caps; + GST_INFO_OBJECT (encode, "downstream may have requested an unsupported " "profile. Encoder will try to output a compatible one"); @@ -283,9 +285,15 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) if (profile == GST_VAAPI_PROFILE_UNKNOWN) goto fail; - profile_caps = gst_caps_from_string (GST_CODEC_CAPS); - gst_caps_set_simple (profile_caps, "profile", G_TYPE_STRING, + tmp_caps = gst_caps_from_string (GST_CODEC_CAPS); + gst_caps_set_simple (tmp_caps, "profile", G_TYPE_STRING, gst_vaapi_profile_get_name (profile), NULL); + profile_caps = gst_caps_intersect (available_caps, tmp_caps); + gst_caps_unref (tmp_caps); + if (gst_caps_is_empty (profile_caps)) { + gst_caps_unref (profile_caps); + goto fail; + } } else { profile_caps = gst_caps_intersect (allowed_caps, available_caps); profile = find_best_profile (profile_caps); From 209e1b5bf0e13c0059aea4605b916612dbf63718 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 8 Jan 2020 17:16:35 +0100 Subject: [PATCH 3486/3781] libs: encoder: h264: Add gst_vaapi_encoder_h264_supports_avc() AVC output requires packed header support in the driver. --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 8 ++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 89a6cc194c..6e463020c4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -4124,3 +4124,11 @@ gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder, *out_level_ptr = encoder->level; return TRUE; } + +gboolean +gst_vaapi_encoder_h264_supports_avc (GstVaapiEncoderH264 * encoder) +{ + return ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + (VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE)) == + (VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE)); +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 31a6f7aeee..8a0705b461 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -53,6 +53,9 @@ 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_END_DECLS #endif /*GST_VAAPI_ENCODER_H264_H */ From d576963979db4b0d657ff45f1927372425c09546 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 8 Jan 2020 17:37:22 +0100 Subject: [PATCH 3487/3781] vaaph264enc: suppress avc if the driver does not support packed headers Do not negotiate AVC output if the driver does not support it. --- gst/vaapi/gstvaapiencode_h264.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 987f72c9ef..00d04e08bb 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -195,6 +195,9 @@ find_best_profile (GstCaps * caps) static GstCaps * get_available_caps (GstVaapiEncodeH264 * encode) { + GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (encode); + GstVaapiEncoderH264 *const encoder = + GST_VAAPI_ENCODER_H264 (base_encode->encoder); GstCaps *out_caps; GArray *profiles; GstVaapiProfile profile; @@ -232,6 +235,13 @@ get_available_caps (GstVaapiEncodeH264 * encode) g_value_unset (&profile_list); g_value_unset (&profile_v); + if (!gst_vaapi_encoder_h264_supports_avc (encoder)) { + GST_INFO_OBJECT (encode, + "avc requires packed header support, outputting byte-stream"); + gst_caps_set_simple (out_caps, "stream-format", G_TYPE_STRING, + "byte-stream", NULL); + } + encode->available_caps = out_caps; return encode->available_caps; @@ -384,8 +394,23 @@ gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encode->encoder); GstVaapiProfile profile; + GstCaps *available_caps; + GstStructure *structure; + const char *stream_format; GstCaps *caps; + if (encode->is_avc) { + available_caps = get_available_caps (encode); + structure = gst_caps_get_structure (available_caps, 0); + stream_format = gst_structure_get_string (structure, "stream-format"); + if (g_strcmp0 (stream_format, "byte-stream") == 0) { + GST_WARNING_OBJECT (encode, + "downstream prefers avc, but the driver does not support it"); + encode->is_avc = FALSE; + base_encode->need_codec_data = FALSE; + } + } + caps = gst_caps_from_string (GST_CODEC_CAPS); gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, From 5e26efbcf21e0ebfc35bb92f0f522b9e075082c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Jan 2020 13:38:29 +0100 Subject: [PATCH 3488/3781] vaapih264enc: force byte-stream if avc isn't supported Removing the validation in gst_vaapiencode_h264_get_caps() since that ought be handled in gst_vaapiencode_h264_set_config() --- gst/vaapi/gstvaapiencode_h264.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 00d04e08bb..4a3b4acbf7 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -298,6 +298,11 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) tmp_caps = gst_caps_from_string (GST_CODEC_CAPS); gst_caps_set_simple (tmp_caps, "profile", G_TYPE_STRING, gst_vaapi_profile_get_name (profile), NULL); + if (!gst_vaapi_encoder_h264_supports_avc (encoder)) { + gst_caps_set_simple (tmp_caps, "stream-format", G_TYPE_STRING, + "byte-stream", NULL); + } + profile_caps = gst_caps_intersect (available_caps, tmp_caps); gst_caps_unref (tmp_caps); if (gst_caps_is_empty (profile_caps)) { @@ -394,23 +399,8 @@ gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encode->encoder); GstVaapiProfile profile; - GstCaps *available_caps; - GstStructure *structure; - const char *stream_format; GstCaps *caps; - if (encode->is_avc) { - available_caps = get_available_caps (encode); - structure = gst_caps_get_structure (available_caps, 0); - stream_format = gst_structure_get_string (structure, "stream-format"); - if (g_strcmp0 (stream_format, "byte-stream") == 0) { - GST_WARNING_OBJECT (encode, - "downstream prefers avc, but the driver does not support it"); - encode->is_avc = FALSE; - base_encode->need_codec_data = FALSE; - } - } - caps = gst_caps_from_string (GST_CODEC_CAPS); gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, From 3df5bfc06d32089e34397ea2f29e003081417cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Jan 2020 17:12:53 +0100 Subject: [PATCH 3489/3781] libs: encoder: h264: document gst_vaapi_encoder_h264_supports_avc() --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 6e463020c4..f98949a2fe 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -4125,6 +4125,15 @@ gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder, return TRUE; } +/** + * gst_vaapi_encoder_h264_supports_avc: + * @encoder: a #GstVaapiEncoderH264 + * + * Queries the H.264 @encoder if it supports the generation of avC + * stream format. + * + * Returns: %TRUE if @encoder supports avC; %FALSE otherwise + **/ gboolean gst_vaapi_encoder_h264_supports_avc (GstVaapiEncoderH264 * encoder) { From 9f627ef2344f5d9f50d53eafc61c0615b6bf3a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Jan 2020 14:24:37 +0100 Subject: [PATCH 3490/3781] vaapih264enc: update level in src caps And, if downstream requests a specific level, the caps are not negotiated, because there is no mechanism right now to specify a custom level in the internal encoder. --- gst/vaapi/gstvaapiencode_h264.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 4a3b4acbf7..98badf42d9 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -319,7 +319,12 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) stream_format = gst_structure_get_string (structure, "stream-format"); encode->is_avc = (g_strcmp0 (stream_format, "avc") == 0); - if (profile != GST_VAAPI_PROFILE_UNKNOWN) { + if (gst_structure_has_field (structure, "level")) { + /* @TODO(victor): add a mechansim for user set a specific + * level */ + GST_WARNING_OBJECT (encode, "cannot set level configuration"); + ret = FALSE; + } else if (profile != GST_VAAPI_PROFILE_UNKNOWN) { GST_INFO ("using %s profile as target decoder constraints", gst_vaapi_utils_h264_get_profile_string (profile)); ret = gst_vaapi_encoder_h264_set_max_profile (encoder, profile); @@ -346,7 +351,7 @@ fail: static void set_compatible_profile (GstVaapiEncodeH264 * encode, GstCaps * caps, - GstVaapiProfile profile) + GstVaapiProfile profile, GstVaapiLevelH264 level) { GstCaps *allowed_caps, *tmp_caps; gboolean ret = FALSE; @@ -380,7 +385,9 @@ retry: } } else { gst_caps_set_simple (caps, "profile", G_TYPE_STRING, - gst_vaapi_utils_h264_get_profile_string (profile), NULL); + gst_vaapi_utils_h264_get_profile_string (profile), + "level", G_TYPE_STRING, gst_vaapi_utils_h264_get_level_string (level), + NULL); ret = TRUE; } @@ -399,6 +406,7 @@ gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encode->encoder); GstVaapiProfile profile; + GstVaapiLevelH264 level; GstCaps *caps; caps = gst_caps_from_string (GST_CODEC_CAPS); @@ -407,13 +415,11 @@ gst_vaapiencode_h264_get_caps (GstVaapiEncode * base_encode) encode->is_avc ? "avc" : "byte-stream", NULL); /* Update profile determined by encoder */ - gst_vaapi_encoder_h264_get_profile_and_level (encoder, &profile, NULL); + gst_vaapi_encoder_h264_get_profile_and_level (encoder, &profile, &level); if (profile != GST_VAAPI_PROFILE_UNKNOWN) - set_compatible_profile (encode, caps, profile); + set_compatible_profile (encode, caps, profile, level); GST_INFO_OBJECT (base_encode, "out caps %" GST_PTR_FORMAT, caps); - - /* XXX: update level information */ return caps; } From 73159cdc5d82484176e0fac9d410a4045c3856b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 17 Jan 2020 16:19:52 +0100 Subject: [PATCH 3491/3781] vaapih264enc: accept baseline as constrained baseline compatible --- gst/vaapi/gstvaapiencode_h264.c | 8 ++++++++ gst/vaapi/gstvaapipluginutil.c | 2 ++ 2 files changed, 10 insertions(+) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 98badf42d9..72aeac5e22 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -295,6 +295,12 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) if (profile == GST_VAAPI_PROFILE_UNKNOWN) goto fail; + /* if allwed caps request baseline (which is deprecated), the + * encoder will try with constrained baseline which is + * compatible. */ + if (profile == GST_VAAPI_PROFILE_H264_BASELINE) + profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; + tmp_caps = gst_caps_from_string (GST_CODEC_CAPS); gst_caps_set_simple (tmp_caps, "profile", G_TYPE_STRING, gst_vaapi_profile_get_name (profile), NULL); @@ -381,6 +387,8 @@ retry: if (!gst_caps_can_intersect (allowed_caps, tmp_caps)) { if (profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE) { profile = GST_VAAPI_PROFILE_H264_BASELINE; + GST_INFO ("user might requested baseline profile, " + "trying constrained-baseline instead"); goto retry; } } else { diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 4db9b7792d..87ab575747 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1043,6 +1043,8 @@ gst_vaapi_h26x_encoder_get_profiles_from_caps (GstCaps * caps, const gchar *str = g_value_get_string (value); if (str) { profile = func (str); + if (profile == GST_VAAPI_PROFILE_H264_BASELINE) + profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE; if (profile != GST_VAAPI_PROFILE_UNKNOWN) g_array_append_val (profiles, profile); } From 866a9f069d54b6cf55ca9c78a7f69e7c58193d5a Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 28 Jun 2019 15:41:16 -0400 Subject: [PATCH 3492/3781] vaapih264dec: Add a property to assume constrained-baseline When baseline-as-constrained is set, the decoder will expose support for baseline decoding and assume that the baseline content is constrained-baseline. This can be handy to decode streams in hardware that would otherwise not be possible to decode. A lot of baseline content is in fact constrained. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 21 ++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 4 ++++ gst/vaapi/gstvaapidecode.c | 10 ++++++++++ gst/vaapi/gstvaapidecode_props.c | 20 +++++++++++++++++++- gst/vaapi/gstvaapidecode_props.h | 1 + 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index b20e727272..48f72d204d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -537,6 +537,7 @@ struct _GstVaapiDecoderH264Private gboolean force_low_latency; gboolean base_only; + gboolean baseline_as_constrained; }; /** @@ -1473,7 +1474,7 @@ get_profile (GstVaapiDecoderH264 * decoder, GstH264SPS * sps, guint dpb_size) fill_profiles (profiles, &n_profiles, profile); switch (profile) { case GST_VAAPI_PROFILE_H264_BASELINE: - if (sps->constraint_set1_flag) { // A.2.2 (main profile) + if (priv->baseline_as_constrained || sps->constraint_set1_flag) { // A.2.2 (main profile) fill_profiles (profiles, &n_profiles, GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE); fill_profiles (profiles, &n_profiles, GST_VAAPI_PROFILE_H264_MAIN); @@ -4800,6 +4801,24 @@ gst_vaapi_decoder_h264_set_base_only (GstVaapiDecoderH264 * decoder, decoder->priv.base_only = base_only; } +/** + * gst_vaapi_decoder_h264_set_baseline_as_constrained: + * @decoder: a #GstVaapiDecoderH264 + * @baseline_as_constrained: %TRUE to assume all baseline is constrained + * + * This is a small hack that makes the decoder assumes that baseline contents + * is already constrained. This may allow decoding some streams that would + * otherwise fails to negotiation. + */ +void +gst_vaapi_decoder_h264_set_baseline_as_constrained (GstVaapiDecoderH264 * + decoder, gboolean baseline_as_constrained) +{ + g_return_if_fail (decoder != NULL); + + decoder->priv.baseline_as_constrained = baseline_as_constrained; +} + /** * gst_vaapi_decoder_h264_set_low_latency: * @decoder: a #GstVaapiDecoderH264 diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h index 999e80b27d..04386068eb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -73,6 +73,10 @@ void gst_vaapi_decoder_h264_set_base_only(GstVaapiDecoderH264 * decoder, gboolean base_only); +void +gst_vaapi_decoder_h264_set_baseline_as_constrained(GstVaapiDecoderH264 * decoder, + gboolean baseline_as_constrained); + G_END_DECLS #endif /* GST_VAAPI_DECODER_H264_H */ diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 3acfe4f935..db009f815f 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -912,6 +912,9 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) (decode->decoder), priv->is_low_latency); gst_vaapi_decoder_h264_set_base_only (GST_VAAPI_DECODER_H264 (decode->decoder), priv->base_only); + gst_vaapi_decoder_h264_set_baseline_as_constrained + (GST_VAAPI_DECODER_H264 (decode->decoder), + priv->baseline_as_constrained); } } break; @@ -1233,6 +1236,8 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) gboolean have_high = FALSE; gboolean have_mvc = FALSE; gboolean have_svc = FALSE; + GstVaapiDecodeH264Private *priv = + gst_vaapi_decode_h264_get_instance_private (decode); profiles = gst_vaapi_display_get_decode_profiles (display); if (!profiles) @@ -1275,6 +1280,11 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) have_mvc |= is_mvc_profile (profile); have_svc |= is_svc_profile (profile); have_high |= profile == GST_VAAPI_PROFILE_H264_HIGH; + + if (priv && priv->baseline_as_constrained && + profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE) + allowed_sinkpad_caps = + add_h264_profile_in_caps (allowed_sinkpad_caps, "baseline"); } if (have_high) { diff --git a/gst/vaapi/gstvaapidecode_props.c b/gst/vaapi/gstvaapidecode_props.c index e9287b4259..5ab280041f 100644 --- a/gst/vaapi/gstvaapidecode_props.c +++ b/gst/vaapi/gstvaapidecode_props.c @@ -29,7 +29,8 @@ enum { GST_VAAPI_DECODER_H264_PROP_FORCE_LOW_LATENCY = 1, - GST_VAAPI_DECODER_H264_PROP_BASE_ONLY + GST_VAAPI_DECODER_H264_PROP_BASE_ONLY, + GST_VAAPI_DECODER_H264_PROP_BASELINE_AS_CONSTRAINED, }; static gint h264_private_offset; @@ -49,6 +50,9 @@ gst_vaapi_decode_h264_get_property (GObject * object, guint prop_id, case GST_VAAPI_DECODER_H264_PROP_BASE_ONLY: g_value_set_boolean (value, priv->base_only); break; + case GST_VAAPI_DECODER_H264_PROP_BASELINE_AS_CONSTRAINED: + g_value_set_boolean (value, priv->baseline_as_constrained); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -77,6 +81,13 @@ gst_vaapi_decode_h264_set_property (GObject * object, guint prop_id, if (decoder) gst_vaapi_decoder_h264_set_base_only (decoder, priv->base_only); break; + case GST_VAAPI_DECODER_H264_PROP_BASELINE_AS_CONSTRAINED: + priv->baseline_as_constrained = g_value_get_boolean (value); + decoder = GST_VAAPI_DECODER_H264 (GST_VAAPIDECODE (object)->decoder); + if (decoder) + gst_vaapi_decoder_h264_set_baseline_as_constrained (decoder, + priv->baseline_as_constrained); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -103,6 +114,13 @@ gst_vaapi_decode_h264_install_properties (GObjectClass * klass) g_param_spec_boolean ("base-only", "Decode base view only", "Drop any NAL unit not defined in Annex.A", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (klass, + GST_VAAPI_DECODER_H264_PROP_BASELINE_AS_CONSTRAINED, + g_param_spec_boolean ("baseline-as-constrained", + "Baseline as Constrained", + "Assume all baseline content is also constrained.", FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } GstVaapiDecodeH264Private * diff --git a/gst/vaapi/gstvaapidecode_props.h b/gst/vaapi/gstvaapidecode_props.h index b1f2fec600..d644fdedcc 100644 --- a/gst/vaapi/gstvaapidecode_props.h +++ b/gst/vaapi/gstvaapidecode_props.h @@ -34,6 +34,7 @@ struct _GstVaapiDecodeH264Private { gboolean is_low_latency; gboolean base_only; + gboolean baseline_as_constrained; }; void From e25ef7dfc25af0f606d698f7b35e348e19920e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 21 Jan 2020 14:09:33 +0100 Subject: [PATCH 3493/3781] vaapiencode: promote info to warning Let's notify user about using constrained-baseline instead on requested basline profile. --- gst/vaapi/gstvaapiencode_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 72aeac5e22..28656a94c9 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -387,8 +387,8 @@ retry: if (!gst_caps_can_intersect (allowed_caps, tmp_caps)) { if (profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE) { profile = GST_VAAPI_PROFILE_H264_BASELINE; - GST_INFO ("user might requested baseline profile, " - "trying constrained-baseline instead"); + GST_WARNING_OBJECT (GST_VAAPIENCODE_CAST (encode), "user might requested " + "baseline profile, trying constrained-baseline instead"); goto retry; } } else { From 35e5721047b1968a14015e28eed727a43d338e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 22 Jan 2020 20:20:30 +0100 Subject: [PATCH 3494/3781] libs: blend: guard VA_BLEND_GLOBAL_ALPHA --- gst-libs/gst/vaapi/gstvaapiblend.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiblend.c b/gst-libs/gst/vaapi/gstvaapiblend.c index 57f9fb27fd..5b093d4d48 100644 --- a/gst-libs/gst/vaapi/gstvaapiblend.c +++ b/gst-libs/gst/vaapi/gstvaapiblend.c @@ -175,12 +175,14 @@ gst_vaapi_blend_initialize (GstVaapiBlend * blend) (blend->display), blend->va_context, NULL, 0, &pipeline_caps); if (vaapi_check_status (status, "vaQueryVideoProcPipelineCaps()")) blend->flags = pipeline_caps.blend_flags; -#endif 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; } From 78c3afea71568714dbb3c2250337eec5e127ec10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 21 Jan 2020 19:35:02 +0100 Subject: [PATCH 3495/3781] libs: context: add debug category for context --- gst-libs/gst/vaapi/gstvaapicontext.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 69b7b63144..247cb743f7 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -37,15 +37,30 @@ #include "gstvaapivideopool_priv.h" #include "gstvaapiutils.h" -#define DEBUG 1 -#include "gstvaapidebug.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 volatile 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 gboolean ensure_attributes (GstVaapiContext * context) { @@ -84,7 +99,7 @@ context_destroy (GstVaapiContext * context) VAStatus status; context_id = GST_VAAPI_CONTEXT_ID (context); - GST_DEBUG ("context 0x%08x", context_id); + GST_DEBUG ("context 0x%08x / config 0x%08x", context_id, context->va_config); if (context_id != VA_INVALID_ID) { GST_VAAPI_DISPLAY_LOCK (display); @@ -201,7 +216,6 @@ context_create (GstVaapiContext * context) if (!vaapi_check_status (status, "vaCreateContext()")) goto cleanup; - GST_DEBUG ("context 0x%08x", context_id); GST_VAAPI_CONTEXT_ID (context) = context_id; success = TRUE; @@ -404,6 +418,8 @@ gst_vaapi_context_new (GstVaapiDisplay * display, 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; @@ -435,6 +451,8 @@ gst_vaapi_context_new (GstVaapiDisplay * display, goto error; done: + GST_DEBUG ("context 0x%08lx / config 0x%08x", + GST_VAAPI_CONTEXT_ID (context), context->va_config); return context; /* ERRORS */ From 21dd66b5e4106fd075e13826eb7999fc4ca81f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 23 Jan 2020 16:56:44 +0100 Subject: [PATCH 3496/3781] libs: context: select vaCreateSurfaces version according attributes This commit tries to centralize the selection of vaCreateSurfaces version, instead of having fallbacks everywhere. These fallbacks are hacks, added because new drivers use the latest version of vaCreateSurfaces (with surface attributes) [1], meanwhile old drivers (or profiles as JPEG decoder in i965) might rather use the old version. In order to select which method, there's detected hack: each config context has a list of valid formats, in the case of JPEG decoder the list only contains "rare" 4:2:2 formats (ICM3, GRAY8) which aren't handled correctly by the current gstreamer-vaapi code [2]. The hack consist in identify if the format list contains an arbitrary preferred format (which is suposedly well supported by gstreamer-vaapi, mostly NV12). If no prefered colour format is found, the the old version of vaCreateSurfaces is used, and the surfaces wil be mapped into a image with their own color format. 1. https://bugzilla.gnome.org/show_bug.cgi?id=797143 2. https://bugzilla.gnome.org/show_bug.cgi?id=797222 --- gst-libs/gst/vaapi/gstvaapicontext.c | 47 ++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapicontext.h | 1 + gst-libs/gst/vaapi/gstvaapisurface.c | 62 ++-------------------------- gst-libs/gst/vaapi/gstvaapisurface.h | 4 -- 4 files changed, 45 insertions(+), 69 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 247cb743f7..315f9324a4 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -73,6 +73,33 @@ ensure_attributes (GstVaapiContext * context) return (context->attribs != NULL); } +/* looks for the (very arbritrary) preferred format from the requested + * context chroma type, in the context attributes */ +static GstVideoFormat +get_preferred_format (GstVaapiContext * context) +{ + const GstVaapiContextInfo *const cip = &context->info; + GArray *formats; + guint i; + + if (context->preferred_format != GST_VIDEO_FORMAT_UNKNOWN) + return context->preferred_format; + + if (!ensure_attributes (context) || !context->attribs->formats) + return GST_VIDEO_FORMAT_UNKNOWN; + + 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 context->preferred_format; +} + static inline gboolean context_get_attribute (GstVaapiContext * context, VAConfigAttribType type, guint * out_value_ptr) @@ -88,6 +115,9 @@ context_destroy_surfaces (GstVaapiContext * context) 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); } @@ -130,18 +160,22 @@ context_destroy (GstVaapiContext * context) 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; - if (!ensure_attributes (context)) - return FALSE; - + format = get_preferred_format (context); for (i = context->surfaces->len; i < num_surfaces; i++) { - surface = - gst_vaapi_surface_new_from_formats (GST_VAAPI_CONTEXT_DISPLAY (context), - cip->chroma_type, cip->width, cip->height, context->attribs->formats); + if (format != GST_VIDEO_FORMAT_UNKNOWN) { + surface = gst_vaapi_surface_new_with_format (display, format, cip->width, + cip->height); + } 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); @@ -397,6 +431,7 @@ gst_vaapi_context_init (GstVaapiContext * context, context->reset_on_resize = TRUE; context->attribs = NULL; + context->preferred_format = GST_VIDEO_FORMAT_UNKNOWN; } /** diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 26a1dfdc6c..900fc653f9 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -115,6 +115,7 @@ struct _GstVaapiContext GstVaapiVideoPool *surfaces_pool; gboolean reset_on_resize; GstVaapiConfigSurfaceAttributes *attribs; + GstVideoFormat preferred_format; }; #define GST_VAAPI_CONTEXT_ID(context) (((GstVaapiContext *)(context))->object_id) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 5e2e63f6be..6a4cb6a0b1 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -342,53 +342,6 @@ gst_vaapi_surface_get_display (GstVaapiSurface * surface) return GST_VAAPI_SURFACE_DISPLAY (surface); } -/** - * gst_vaapi_surface_new_from_formats: - * @display: a #GstVaapiDisplay - * @chroma_type: the surface chroma format - * @width: the requested surface width - * @height: the requested surface height - * @formats: the limited format list - * - * Creates a new #GstVaapiSurface with a @chroma_type valid for any - * format in @formats; If there aren't any, the returned surface is - * created forcing the passed @chroma_type. - * - * Return value: the newly allocated #GstVaapiSurface object - */ -GstVaapiSurface * -gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display, - GstVaapiChromaType chroma_type, guint width, guint height, GArray * formats) -{ - GstVaapiSurface *surface; - guint i; - - if (formats) { - for (i = 0; i < formats->len; i++) { - GstVideoFormat format = g_array_index (formats, GstVideoFormat, i); - if (format == gst_vaapi_video_format_from_chroma (chroma_type)) - return gst_vaapi_surface_new (display, chroma_type, width, height); - } - } - - /* Fallback: if there's no format valid for the chroma type let's - * just use the passed chroma */ - surface = gst_vaapi_surface_create (display); - if (!surface) - return NULL; - if (!gst_vaapi_surface_init (surface, chroma_type, width, height)) - goto error; - - return surface; - - /* ERRORS */ -error: - { - gst_vaapi_surface_unref (surface); - return NULL; - } -} - /** * gst_vaapi_surface_new: * @display: a #GstVaapiDisplay @@ -399,6 +352,9 @@ error: * Creates a new #GstVaapiSurface with the specified chroma format and * dimensions. * + * NOTE: this method for creating surfaces uses deprecated VA API, + * which is still used by drivers (v.gr. i965 for jpeg decoding). + * * Return value: the newly allocated #GstVaapiSurface object */ GstVaapiSurface * @@ -413,18 +369,6 @@ gst_vaapi_surface_new (GstVaapiDisplay * display, if (!surface) return NULL; - /* first try a recent version of vaCreateSurface, and later use as - * fallback its old version */ - { - GstVideoInfo vi; - GstVideoFormat surface_format; - - surface_format = gst_vaapi_video_format_from_chroma (chroma_type); - gst_video_info_set_format (&vi, surface_format, width, height); - - if (gst_vaapi_surface_init_full (surface, &vi, 0)) - return surface; - } if (!gst_vaapi_surface_init (surface, chroma_type, width, height)) goto error; return surface; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 08e5d7de8b..13de604e44 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -206,10 +206,6 @@ gst_vaapi_surface_unref (GstVaapiSurface * surface) GstVaapiDisplay * gst_vaapi_surface_get_display (GstVaapiSurface * surface); -GstVaapiSurface * -gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display, - GstVaapiChromaType chroma_type, guint width, guint height, GArray * formts); - GstVaapiSurface * gst_vaapi_surface_new (GstVaapiDisplay * display, GstVaapiChromaType chroma_type, guint width, guint height); From 89f202ea2ec9d72d46aa0ee7f077f71e0eb290d6 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 22 Jan 2020 18:50:36 +0100 Subject: [PATCH 3497/3781] vaapivideobufferpool: always update/release the underlying surface proxy gst_vaapi_video_buffer_pool_reset_buffer() is called when the sink releases the last reference on an exported DMA buffer. This should release the underlying surface proxy. To avoid releasing the wrong surface due to a stale surface proxy reference in the buffer's GstVaapiVideoMeta, always update the reference to the correct surface in gst_vaapi_video_buffer_pool_acquire_buffer(). --- gst/vaapi/gstvaapivideobufferpool.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index f6931c41ad..b9e4386627 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -438,6 +438,11 @@ gst_vaapi_video_buffer_pool_acquire_buffer (GstBufferPool * pool, * the one associated with the current surface. */ g_assert (gst_buffer_n_memory (buffer) == 1); + /* Update the underlying surface proxy */ + meta = gst_buffer_get_vaapi_video_meta (buffer); + if (meta) + gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy); + /* Find the cached memory associated with the given surface. */ surface = GST_VAAPI_SURFACE_PROXY_SURFACE (priv_params->proxy); dmabuf_proxy = gst_vaapi_surface_peek_buffer_proxy (surface); @@ -449,13 +454,7 @@ gst_vaapi_video_buffer_pool_acquire_buffer (GstBufferPool * pool, mem = gst_memory_ref (mem); } else { /* The given surface has not been exported yet. */ - meta = gst_buffer_get_vaapi_video_meta (buffer); - if (gst_vaapi_video_meta_get_surface_proxy (meta)) - gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy); - - mem = - gst_vaapi_dmabuf_memory_new (priv->allocator, - gst_buffer_get_vaapi_video_meta (buffer)); + mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta); } /* Attach the GstFdMemory to the output buffer. */ @@ -475,10 +474,16 @@ gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool, GstBuffer * buffer) { GstMemory *const mem = gst_buffer_peek_memory (buffer, 0); + GstVaapiVideoMeta *meta; /* Release the underlying surface proxy */ - if (GST_VAAPI_IS_VIDEO_MEMORY (mem)) + if (GST_VAAPI_IS_VIDEO_MEMORY (mem)) { gst_vaapi_video_memory_reset_surface (GST_VAAPI_VIDEO_MEMORY_CAST (mem)); + } else { + meta = gst_buffer_get_vaapi_video_meta (buffer); + if (meta) + gst_vaapi_video_meta_set_surface_proxy (meta, NULL); + } GST_BUFFER_POOL_CLASS (gst_vaapi_video_buffer_pool_parent_class)->reset_buffer (pool, buffer); From 08158991214c36169d517110065eb51efd7ffdba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 24 Jan 2020 11:55:22 +0100 Subject: [PATCH 3498/3781] vaapivideobufferpool: validate returned meta Validate if the meta returned by gst_buffer_get_vaapi_video_meta() in the acquired buffer is not null. This situation should be very "pathological", but still it is better be safe since that meta might be used later to create a new dma buffer. --- gst/vaapi/gstvaapivideobufferpool.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index b9e4386627..f01773e42f 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -440,8 +440,11 @@ gst_vaapi_video_buffer_pool_acquire_buffer (GstBufferPool * pool, /* Update the underlying surface proxy */ meta = gst_buffer_get_vaapi_video_meta (buffer); - if (meta) - gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy); + if (!meta) { + *out_buffer_ptr = buffer; + return GST_FLOW_ERROR; + } + gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy); /* Find the cached memory associated with the given surface. */ surface = GST_VAAPI_SURFACE_PROXY_SURFACE (priv_params->proxy); From 7a186975cc209f1f4d75e902144563e76ce3a14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 15 Jan 2020 23:07:29 +0100 Subject: [PATCH 3499/3781] plugins: renable Mesa Gallium driver --- gst/vaapi/gstvaapipluginutil.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 87ab575747..e344649e6e 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -955,6 +955,7 @@ gst_vaapi_driver_is_whitelisted (GstVaapiDisplay * display) static const gchar *whitelist[] = { "Intel i965 driver", "Intel iHD driver", + "Mesa Gallium driver", NULL }; From ee3d4c3206327d2a7a666fbeb699a911dfc1700c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 16 Jan 2020 11:49:21 +0100 Subject: [PATCH 3500/3781] libs: display: driver quirks mechanism This mechanism comes from ffmpeg vaapi implementation, where they have their own quirks. A specific driver is identified by a substring present in the vendor string. If that substring is found, a set of bitwise flags are store. These flags can be accessed through the function gst_vaapi_display_has_driver_quirks(). The purpose for this first quirks is to disable the put image try for AMD Gallium driver (see [1]). 1. https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/merge_requests/72 --- gst-libs/gst/vaapi/gstvaapidisplay.c | 83 ++++++++++++++++++----- gst-libs/gst/vaapi/gstvaapidisplay.h | 14 ++++ gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 1 + gst/vaapi/gstvaapipluginbase.c | 7 +- 4 files changed, 87 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index b1a6148495..e4014ad6ba 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -755,6 +755,55 @@ cleanup: return success; } +/* Ensures the VA driver vendor string was copied */ +static gboolean +ensure_vendor_string (GstVaapiDisplay * display) +{ + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + const gchar *vendor_string; + + GST_VAAPI_DISPLAY_LOCK (display); + if (!priv->vendor_string) { + vendor_string = vaQueryVendorString (priv->display); + if (vendor_string) + priv->vendor_string = g_strdup (vendor_string); + } + GST_VAAPI_DISPLAY_UNLOCK (display); + return priv->vendor_string != NULL; +} + +static void +set_driver_quirks (GstVaapiDisplay * display) +{ + GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + guint i; + + /* *INDENT-OFF* */ + static const struct + { + const char *match_string; + guint quirks; + } vaapi_driver_quirks_table[] = { + /* @XXX(victor): is this string enough to identify it */ + { "AMD", GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE }, + }; + /* *INDENT-ON* */ + + if (!ensure_vendor_string (display)) + return; + + for (i = 0; i < G_N_ELEMENTS (vaapi_driver_quirks_table); i++) { + const char *match_str = vaapi_driver_quirks_table[i].match_string; + if (g_strstr_len (priv->vendor_string, strlen (priv->vendor_string), + match_str) != NULL) { + GST_INFO_OBJECT (display, "Matched driver string \"%s\", setting quirks " + "(%#x)", priv->vendor_string, vaapi_driver_quirks_table[i].quirks); + priv->driver_quirks |= vaapi_driver_quirks_table[i].quirks; + break; + } + } +} + static void gst_vaapi_display_calculate_pixel_aspect_ratio (GstVaapiDisplay * display) { @@ -929,6 +978,8 @@ gst_vaapi_display_create (GstVaapiDisplay * display, g_free (priv->display_name); priv->display_name = g_strdup (info.display_name); + set_driver_quirks (display); + if (!ensure_image_formats (display)) { gst_vaapi_display_destroy (display); return FALSE; @@ -2033,23 +2084,6 @@ set_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat v) return TRUE; } -/* Ensures the VA driver vendor string was copied */ -static gboolean -ensure_vendor_string (GstVaapiDisplay * display) -{ - GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - const gchar *vendor_string; - - GST_VAAPI_DISPLAY_LOCK (display); - if (!priv->vendor_string) { - vendor_string = vaQueryVendorString (priv->display); - if (vendor_string) - priv->vendor_string = g_strdup (vendor_string); - } - GST_VAAPI_DISPLAY_UNLOCK (display); - return priv->vendor_string != NULL; -} - /** * gst_vaapi_display_get_vendor_string: * @display: a #GstVaapiDisplay @@ -2119,3 +2153,18 @@ gst_vaapi_display_reset_texture_map (GstVaapiDisplay * display) if ((map = klass->get_texture_map (display))) gst_vaapi_texture_map_reset (map); } + +/** + * gst_vaapi_display_get_driver_quirks: + * @display: a #GstVaapiDisplay + * @quirks: the #GstVaapiDriverQuirks bitwise to check + * + * Returns: %TRUE if @quirks are set in @display's driver + **/ +gboolean +gst_vaapi_display_has_driver_quirks (GstVaapiDisplay * display, guint quirks) +{ + g_return_val_if_fail (display != NULL, FALSE); + + return (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->driver_quirks & quirks); +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 11e60bdfe8..968abf95bb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -87,6 +87,17 @@ G_BEGIN_DECLS 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 + */ +typedef enum +{ + GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE = (1U << 0), +} GstVaapiDriverQuirks; + /** * GstVaapiDisplayType: * @GST_VAAPI_DISPLAY_TYPE_ANY: Automatic detection of the display type. @@ -251,6 +262,9 @@ 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); + #ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDisplay, gst_object_unref) #endif diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index 0b4e3c3221..b8cb2bdc3c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -131,6 +131,7 @@ struct _GstVaapiDisplayPrivate guint has_vpp:1; guint has_profiles:1; guint got_scrres:1; + guint driver_quirks; }; /** diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e9dd8dec0e..e0c1189ec0 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1456,7 +1456,12 @@ extract_allowed_surface_formats (GstVaapiDisplay * display, if (direction == GST_PAD_SRC) { res = gst_vaapi_surface_get_image (surface, image); } else { - res = gst_vaapi_surface_put_image (surface, image); + if (!gst_vaapi_display_has_driver_quirks (display, + GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE)) + res = gst_vaapi_surface_put_image (surface, image); + else + res = TRUE; /* Let's say it's possible to upload + * all formats */ } if (res) g_array_append_val (out_formats, img_format); From 9fa177951ecd05222c0310c0bd6c0fdcb8836f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 27 Jan 2020 18:05:14 +0100 Subject: [PATCH 3501/3781] vaapivideobufferpool: Log messages in proper category. The log messages where logged in the GstBufferPool category because the instance was not properly casted. This fix that situation. --- gst/vaapi/gstvaapivideobufferpool.c | 43 +++++++++++++++-------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index f01773e42f..cbc8a1b313 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -131,8 +131,8 @@ static gboolean gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) { - GstVaapiVideoBufferPoolPrivate *const priv = - GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv; + GstVaapiVideoBufferPool *const base_pool = GST_VAAPI_VIDEO_BUFFER_POOL (pool); + GstVaapiVideoBufferPoolPrivate *const priv = base_pool->priv; GstCaps *caps; GstVideoInfo new_allocation_vinfo; const GstVideoInfo *allocator_vinfo; @@ -143,7 +143,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, guint size, min_buffers, max_buffers; guint surface_alloc_flags; - GST_DEBUG_OBJECT (pool, "config %" GST_PTR_FORMAT, config); + GST_DEBUG_OBJECT (base_pool, "config %" GST_PTR_FORMAT, config); caps = NULL; if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, @@ -214,7 +214,8 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, negotiated_vinfo); } - GST_INFO_OBJECT (pool, "created new allocator %" GST_PTR_FORMAT, allocator); + GST_INFO_OBJECT (base_pool, "created new allocator %" GST_PTR_FORMAT, + allocator); gst_buffer_pool_config_set_allocator (config, allocator, NULL); gst_object_unref (allocator); } @@ -255,7 +256,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, GST_VIDEO_INFO_PLANE_STRIDE (&priv->vmeta_vinfo, i)) { priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; priv->forced_video_meta = TRUE; - GST_INFO_OBJECT (pool, "adding unrequested video meta"); + GST_INFO_OBJECT (base_pool, "adding unrequested video meta"); break; } } @@ -279,32 +280,32 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, /* ERRORS */ error_invalid_config: { - GST_ERROR_OBJECT (pool, "invalid config"); + GST_ERROR_OBJECT (base_pool, "invalid config"); return FALSE; } error_no_caps: { - GST_ERROR_OBJECT (pool, "no caps in config"); + GST_ERROR_OBJECT (base_pool, "no caps in config"); return FALSE; } error_invalid_caps: { - GST_ERROR_OBJECT (pool, "invalid caps %" GST_PTR_FORMAT, caps); + GST_ERROR_OBJECT (base_pool, "invalid caps %" GST_PTR_FORMAT, caps); return FALSE; } error_invalid_allocator: { - GST_ERROR_OBJECT (pool, "no allocator in config"); + GST_ERROR_OBJECT (base_pool, "no allocator in config"); return FALSE; } error_no_vaapi_video_meta_option: { - GST_ERROR_OBJECT (pool, "no GstVaapiVideoMeta option in config"); + GST_ERROR_OBJECT (base_pool, "no GstVaapiVideoMeta option in config"); return FALSE; } error_no_allocator: { - GST_ERROR_OBJECT (pool, "no allocator defined"); + GST_ERROR_OBJECT (base_pool, "no allocator defined"); return FALSE; } } @@ -313,8 +314,8 @@ static GstFlowReturn gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, GstBuffer ** out_buffer_ptr, GstBufferPoolAcquireParams * params) { - GstVaapiVideoBufferPoolPrivate *const priv = - GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv; + GstVaapiVideoBufferPool *const base_pool = GST_VAAPI_VIDEO_BUFFER_POOL (pool); + GstVaapiVideoBufferPoolPrivate *const priv = base_pool->priv; GstVaapiVideoBufferPoolAcquireParams *const priv_params = (GstVaapiVideoBufferPoolAcquireParams *) params; GstVaapiVideoMeta *meta; @@ -378,23 +379,23 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, /* ERRORS */ error_no_allocator: { - GST_ERROR_OBJECT (pool, "no GstAllocator in buffer pool"); + GST_ERROR_OBJECT (base_pool, "no GstAllocator in buffer pool"); return GST_FLOW_ERROR; } error_create_meta: { - GST_ERROR_OBJECT (pool, "failed to allocate vaapi video meta"); + GST_ERROR_OBJECT (base_pool, "failed to allocate vaapi video meta"); return GST_FLOW_ERROR; } error_create_buffer: { - GST_ERROR_OBJECT (pool, "failed to create video buffer"); + GST_ERROR_OBJECT (base_pool, "failed to create video buffer"); gst_vaapi_video_meta_unref (meta); return GST_FLOW_ERROR; } error_create_memory: { - GST_ERROR_OBJECT (pool, "failed to create video memory"); + GST_ERROR_OBJECT (base_pool, "failed to create video memory"); gst_buffer_unref (buffer); gst_vaapi_video_meta_unref (meta); return GST_FLOW_ERROR; @@ -405,8 +406,8 @@ static GstFlowReturn gst_vaapi_video_buffer_pool_acquire_buffer (GstBufferPool * pool, GstBuffer ** out_buffer_ptr, GstBufferPoolAcquireParams * params) { - GstVaapiVideoBufferPoolPrivate *const priv = - GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv; + GstVaapiVideoBufferPool *const base_pool = GST_VAAPI_VIDEO_BUFFER_POOL (pool); + GstVaapiVideoBufferPoolPrivate *const priv = base_pool->priv; GstVaapiVideoBufferPoolAcquireParams *const priv_params = (GstVaapiVideoBufferPoolAcquireParams *) params; GstFlowReturn ret; @@ -462,8 +463,8 @@ gst_vaapi_video_buffer_pool_acquire_buffer (GstBufferPool * pool, /* Attach the GstFdMemory to the output buffer. */ if (mem) { - GST_DEBUG_OBJECT (pool, "assigning memory %p to acquired buffer %p", mem, - buffer); + GST_DEBUG_OBJECT (base_pool, "assigning memory %p to acquired buffer %p", + mem, buffer); gst_buffer_replace_memory (buffer, 0, mem); gst_buffer_unset_flags (buffer, GST_BUFFER_FLAG_TAG_MEMORY); } From 477888272867b112ef1b19f0ee925adae973f92e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 27 Jan 2020 18:40:46 +0100 Subject: [PATCH 3502/3781] vaapivideobufferpool: Reuse internal allocator is possible. Instead of creating a new allocator when upstream requests a different allocator, this patch tries to reuse the internal allocator if it was already initializated. If the stream changes, then either one will be unref and a new allocator is created. --- gst/vaapi/gstvaapivideobufferpool.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index cbc8a1b313..432de6811c 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -162,8 +162,14 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, if (allocator && (g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) != 0 && g_strcmp0 (allocator->mem_type, - GST_VAAPI_DMABUF_ALLOCATOR_NAME) != 0)) - allocator = NULL; + GST_VAAPI_DMABUF_ALLOCATOR_NAME) != 0)) { + /* if pool has already an allocator, try it and ignore the one in + * configuration */ + if (priv->allocator) + allocator = priv->allocator; + else + allocator = NULL; + } /* get the allocator properties */ if (allocator) { From dd3df4589d2414bce092806e7dbe669b15022f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 22 Jan 2020 10:42:35 +0100 Subject: [PATCH 3503/3781] libs: surface: surfacepool: rename variable for clearity In order to be readable, the meaningless 'flags' is renamed to surface_allocation_flags, which is clearer. --- gst-libs/gst/vaapi/gstvaapisurface.c | 19 ++++++++++--------- gst-libs/gst/vaapi/gstvaapisurface.h | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 11 ++++++----- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 6a4cb6a0b1..fac1174eec 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -131,7 +131,7 @@ error_unsupported_chroma_type: static gboolean gst_vaapi_surface_init_full (GstVaapiSurface * surface, - const GstVideoInfo * vip, guint flags) + const GstVideoInfo * vip, guint surface_allocation_flags) { GstVaapiDisplay *const display = GST_VAAPI_SURFACE_DISPLAY (surface); const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (vip); @@ -159,18 +159,18 @@ gst_vaapi_surface_init_full (GstVaapiSurface * surface, extbuf.pixel_format = va_format->fourcc; extbuf.width = GST_VIDEO_INFO_WIDTH (vip); extbuf.height = GST_VIDEO_INFO_HEIGHT (vip); - if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE) { + if (surface_allocation_flags & GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE) { extbuf.flags &= ~VA_SURFACE_EXTBUF_DESC_ENABLE_TILING; extbuf_needed = TRUE; } extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vip); - if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) { + if (surface_allocation_flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) { for (i = 0; i < extbuf.num_planes; i++) extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vip, i); extbuf_needed = TRUE; } - if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS) { + if (surface_allocation_flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS) { for (i = 0; i < extbuf.num_planes; i++) extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vip, i); extbuf_needed = TRUE; @@ -385,7 +385,7 @@ error: * gst_vaapi_surface_new_full: * @display: a #GstVaapiDisplay * @vip: the pointer to a #GstVideoInfo - * @flags: (optional) allocation flags + * @surface_allocation_flags: (optional) allocation flags * * Creates a new #GstVaapiSurface with the specified video information * and optional #GstVaapiSurfaceAllocFlags @@ -395,20 +395,21 @@ error: * supported or failed. */ GstVaapiSurface * -gst_vaapi_surface_new_full (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint flags) +gst_vaapi_surface_new_full (GstVaapiDisplay * display, const GstVideoInfo * vip, + guint surface_allocation_flags) { GstVaapiSurface *surface; GST_DEBUG ("size %ux%u, format %s, flags 0x%08x", GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip), - gst_vaapi_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)), flags); + gst_vaapi_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)), + surface_allocation_flags); surface = gst_vaapi_surface_create (display); if (!surface) return NULL; - if (!gst_vaapi_surface_init_full (surface, vip, flags)) + if (!gst_vaapi_surface_init_full (surface, vip, surface_allocation_flags)) goto error; return surface; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 13de604e44..adc9aa8965 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -212,7 +212,7 @@ gst_vaapi_surface_new (GstVaapiDisplay * display, GstVaapiSurface * gst_vaapi_surface_new_full (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint flags); + const GstVideoInfo * vip, guint surface_allocation_flags); GstVaapiSurface * gst_vaapi_surface_new_with_format (GstVaapiDisplay * display, diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index 4152fbfdc1..c11d7796db 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -51,12 +51,12 @@ struct _GstVaapiSurfacePool static gboolean surface_pool_init (GstVaapiSurfacePool * pool, const GstVideoInfo * vip, - guint flags) + guint surface_allocation_flags) { const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (vip); pool->video_info = *vip; - pool->alloc_flags = flags; + pool->alloc_flags = surface_allocation_flags; if (format == GST_VIDEO_FORMAT_UNKNOWN) return FALSE; @@ -134,7 +134,7 @@ gst_vaapi_surface_pool_new (GstVaapiDisplay * display, GstVideoFormat format, * gst_vaapi_surface_pool_new_full: * @display: a #GstVaapiDisplay * @vip: a #GstVideoInfo - * @flags: (optional) allocation flags + * @surface_allocation_flags: (optional) allocation flags * * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the * specified format and dimensions in @vip. @@ -143,7 +143,7 @@ gst_vaapi_surface_pool_new (GstVaapiDisplay * display, GstVideoFormat format, */ GstVaapiVideoPool * gst_vaapi_surface_pool_new_full (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint flags) + const GstVideoInfo * vip, guint surface_allocation_flags) { GstVaapiVideoPool *pool; @@ -157,7 +157,8 @@ gst_vaapi_surface_pool_new_full (GstVaapiDisplay * display, gst_vaapi_video_pool_init (pool, display, GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE); - if (!surface_pool_init (GST_VAAPI_SURFACE_POOL (pool), vip, flags)) + if (!surface_pool_init (GST_VAAPI_SURFACE_POOL (pool), vip, + surface_allocation_flags)) goto error; return pool; diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 8c5a1efeae..9729a50374 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -42,7 +42,7 @@ gst_vaapi_surface_pool_new (GstVaapiDisplay * display, GstVideoFormat format, GstVaapiVideoPool * gst_vaapi_surface_pool_new_full (GstVaapiDisplay * display, - const GstVideoInfo * vip, guint flags); + const GstVideoInfo * vip, guint surface_allocation_flags); GstVaapiVideoPool * gst_vaapi_surface_pool_new_with_chroma_type (GstVaapiDisplay * display, From bb72efb2e730b29fb8cb36ca1defccb9b963c4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 27 Jan 2020 11:44:49 +0100 Subject: [PATCH 3504/3781] libs: surface: merge two loops into one Merge two loops into one for setting offsets and strides in the external buffer descriptor. --- gst-libs/gst/vaapi/gstvaapisurface.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index fac1174eec..6ee8e17825 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -165,14 +165,14 @@ gst_vaapi_surface_init_full (GstVaapiSurface * surface, } extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vip); - if (surface_allocation_flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) { - for (i = 0; i < extbuf.num_planes; i++) - extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vip, i); - extbuf_needed = TRUE; - } - if (surface_allocation_flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS) { - for (i = 0; i < extbuf.num_planes; i++) - extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vip, i); + if (surface_allocation_flags & (GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES | + GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS)) { + for (i = 0; i < extbuf.num_planes; i++) { + if (surface_allocation_flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) + extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vip, i); + if (surface_allocation_flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS) + extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vip, i); + } extbuf_needed = TRUE; } From 9bb65e4c1030f31b7c21b16f1d7eddbfd6eaade9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 27 Jan 2020 11:49:26 +0100 Subject: [PATCH 3505/3781] libs: surface: initialize VASurfaceAttribExternalBuffers Initialize VASurfaceAttribExternalBuffers using compiler's syntax rather than using memset(). --- gst-libs/gst/vaapi/gstvaapisurface.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 6ee8e17825..6aa3301a49 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -140,7 +140,7 @@ gst_vaapi_surface_init_full (GstVaapiSurface * surface, guint chroma_type, va_chroma_format, i; const VAImageFormat *va_format; VASurfaceAttrib attribs[3], *attrib; - VASurfaceAttribExternalBuffers extbuf; + VASurfaceAttribExternalBuffers extbuf = { 0, }; gboolean extbuf_needed = FALSE; va_format = gst_vaapi_video_format_to_va_format (format); @@ -155,7 +155,6 @@ gst_vaapi_surface_init_full (GstVaapiSurface * surface, if (!va_chroma_format) goto error_unsupported_format; - memset (&extbuf, 0, sizeof (extbuf)); extbuf.pixel_format = va_format->fourcc; extbuf.width = GST_VIDEO_INFO_WIDTH (vip); extbuf.height = GST_VIDEO_INFO_HEIGHT (vip); @@ -232,7 +231,7 @@ gst_vaapi_surface_init_from_buffer_proxy (GstVaapiSurface * surface, guint chroma_type, va_chroma_format; const VAImageFormat *va_format; VASurfaceAttrib attribs[2], *attrib; - VASurfaceAttribExternalBuffers extbuf; + VASurfaceAttribExternalBuffers extbuf = { 0, }; unsigned long extbuf_handle; guint i, width, height; From 67c0bf2cdbe6b61bf7b2de27a2e2eb696dd28e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Jan 2020 11:51:47 +0100 Subject: [PATCH 3506/3781] libs: display: log out vendor string when available This is useful while asking for logs to know the used driver. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index e4014ad6ba..593694d9da 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -767,6 +767,7 @@ ensure_vendor_string (GstVaapiDisplay * display) vendor_string = vaQueryVendorString (priv->display); if (vendor_string) priv->vendor_string = g_strdup (vendor_string); + GST_INFO_OBJECT (display, "vendor: %s", priv->vendor_string); } GST_VAAPI_DISPLAY_UNLOCK (display); return priv->vendor_string != NULL; From ed505f5ed412f8fc52e69bf6f6b62a676d1b3831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Jan 2020 11:52:38 +0100 Subject: [PATCH 3507/3781] vaapivideobufferpool: turn errors into warnings set_config() vmethod should fail gracefully, thus upstream could negotiate another pool if possible. Instead of sending error messages to the bus, let demote the level to warning. --- gst/vaapi/gstvaapivideobufferpool.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 432de6811c..09744f9777 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -286,32 +286,32 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, /* ERRORS */ error_invalid_config: { - GST_ERROR_OBJECT (base_pool, "invalid config"); + GST_WARNING_OBJECT (base_pool, "invalid config"); return FALSE; } error_no_caps: { - GST_ERROR_OBJECT (base_pool, "no caps in config"); + GST_WARNING_OBJECT (base_pool, "no caps in config"); return FALSE; } error_invalid_caps: { - GST_ERROR_OBJECT (base_pool, "invalid caps %" GST_PTR_FORMAT, caps); + GST_WARNING_OBJECT (base_pool, "invalid caps %" GST_PTR_FORMAT, caps); return FALSE; } error_invalid_allocator: { - GST_ERROR_OBJECT (base_pool, "no allocator in config"); + GST_INFO_OBJECT (base_pool, "no allocator in config"); return FALSE; } error_no_vaapi_video_meta_option: { - GST_ERROR_OBJECT (base_pool, "no GstVaapiVideoMeta option in config"); + GST_WARNING_OBJECT (base_pool, "no GstVaapiVideoMeta option in config"); return FALSE; } error_no_allocator: { - GST_ERROR_OBJECT (base_pool, "no allocator defined"); + GST_WARNING_OBJECT (base_pool, "no allocator defined"); return FALSE; } } From 377dd0cc6c8afe90404fa4f8419fb79dc88d601b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Jan 2020 11:54:38 +0100 Subject: [PATCH 3508/3781] vaapivideobufferpool: check for vaapi meta first If the configured meta doesn't request vaapi meta then it is not a vaapi buffer pool. Bail out as soon as possible. --- gst/vaapi/gstvaapivideobufferpool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 09744f9777..d6f47522f3 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -154,6 +154,10 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, if (!gst_video_info_from_caps (&new_allocation_vinfo, caps)) goto error_invalid_caps; + if (!gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) + goto error_no_vaapi_video_meta_option; + allocator = NULL; if (!gst_buffer_pool_config_get_allocator (config, &allocator, NULL)) goto error_invalid_allocator; @@ -198,10 +202,6 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, } } - if (!gst_buffer_pool_config_has_option (config, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) - goto error_no_vaapi_video_meta_option; - /* create a new allocator if needed */ if (!allocator) { if (priv->use_dmabuf_memory) { From 5eca31b5e864157d7012d166cb5685a39cf2bc17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Jan 2020 11:55:28 +0100 Subject: [PATCH 3509/3781] vaapivideobufferpool: add explanation for allocator reconfig --- gst/vaapi/gstvaapivideobufferpool.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index d6f47522f3..a331d4ff61 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -194,6 +194,8 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, && gst_video_info_changed (allocator_vinfo, &new_allocation_vinfo)) { gst_object_replace ((GstObject **) & priv->allocator, NULL); + /* dmabuf allocator can change its parameters: no need to create a + * new one */ if (allocator && priv->use_dmabuf_memory) { gst_allocator_set_vaapi_video_info (allocator, &new_allocation_vinfo, surface_alloc_flags); From 62f3329455b180739492a38a2ac61de22d61eeb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Jan 2020 11:55:39 +0100 Subject: [PATCH 3510/3781] vaapivideobufferpool: reject configuration if allocator isn't vaapi If the requested allocator in set_config() is not a VAAPI valid one, reject the configuration, instead of lying and using a private one. This patch superseeds !254 and !24 --- gst/vaapi/gstvaapivideobufferpool.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index a331d4ff61..d99f306e84 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -166,14 +166,8 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, if (allocator && (g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) != 0 && g_strcmp0 (allocator->mem_type, - GST_VAAPI_DMABUF_ALLOCATOR_NAME) != 0)) { - /* if pool has already an allocator, try it and ignore the one in - * configuration */ - if (priv->allocator) - allocator = priv->allocator; - else - allocator = NULL; - } + GST_VAAPI_DMABUF_ALLOCATOR_NAME) != 0)) + goto error_invalid_allocator; /* get the allocator properties */ if (allocator) { From 7f61ad79389fcd28c82f068701c3fff18bc3e4b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 2 Feb 2020 18:04:35 +0100 Subject: [PATCH 3511/3781] vaapivideobufferpool: dmabuf implies allocator Some code can be optimized since only if the dmabuf allocator is set, the internal flag of dmabuf is TRUE, thus there's no need to evaluate the allocator address. --- gst/vaapi/gstvaapivideobufferpool.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index d99f306e84..013766d8dc 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -190,7 +190,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, /* dmabuf allocator can change its parameters: no need to create a * new one */ - if (allocator && priv->use_dmabuf_memory) { + if (priv->use_dmabuf_memory) { gst_allocator_set_vaapi_video_info (allocator, &new_allocation_vinfo, surface_alloc_flags); } else { @@ -200,14 +200,9 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, /* create a new allocator if needed */ if (!allocator) { - if (priv->use_dmabuf_memory) { - allocator = gst_vaapi_dmabuf_allocator_new (priv->display, - &new_allocation_vinfo, /* FIXME: */ 0, GST_PAD_SRC); - } else { - allocator = gst_vaapi_video_allocator_new (priv->display, - &new_allocation_vinfo, surface_alloc_flags, 0); - } - + /* if no allocator set, let's create a VAAPI one */ + allocator = gst_vaapi_video_allocator_new (priv->display, + &new_allocation_vinfo, surface_alloc_flags, 0); if (!allocator) goto error_no_allocator; From c42938fd53b54e8ead9b5dee452a007908c96888 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 4 Feb 2020 10:27:23 -0800 Subject: [PATCH 3512/3781] libs: display: add vpp color standard quirk for i965 driver The i965 does not properly report supported vpp color standards. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 593694d9da..0a34e1bcc6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -787,6 +787,7 @@ set_driver_quirks (GstVaapiDisplay * display) } vaapi_driver_quirks_table[] = { /* @XXX(victor): is this string enough to identify it */ { "AMD", GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE }, + { "i965", GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD }, }; /* *INDENT-ON* */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 968abf95bb..0f6f136afe 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -92,10 +92,13 @@ typedef struct _GstVaapiDisplay GstVaapiDisplay; * @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. */ typedef enum { GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE = (1U << 0), + GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD = (1U << 1), } GstVaapiDriverQuirks; /** From bc2c483f138087a33750ea40ba1bbff5c6812f35 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 4 Feb 2020 11:32:54 -0800 Subject: [PATCH 3513/3781] libs: utils: map GstVideoColorimetry to VAAPI VPP Fallback to VAProcColorStandardExplicit if there is no 1:1 mapping. --- gst-libs/gst/vaapi/gstvaapiutils.c | 36 ++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 5 +++++ 2 files changed, 41 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 1169db302c..925510d2bc 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -951,3 +951,39 @@ to_GstVaapiBufferMemoryType (guint va_type) return GST_VAAPI_BUFFER_MEMORY_TYPE_USER_PTR; return 0; } + +/** + * from_GstVideoColorimetry: + * @colorimetry: a #GstVideoColorimetry type + * + * VPP: maps the #GstVideoColorimetry type to the VAProcColorStandardType. If + * @colorimetry is NULL or colorimetry->primaries are unknown, then returns + * VAProcColorStandardNone. If there is no 1:1 correlation, then returns + * VAProcColorStandardExplicit. Otherwise, the correlating + * VAProcColorStandardType is returned. + * + * Returns: a VAProcColorStandardType. + **/ +guint +from_GstVideoColorimetry (const GstVideoColorimetry * const colorimetry) +{ + if (!colorimetry + || colorimetry->primaries == GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) + return VAProcColorStandardNone; + if (gst_video_colorimetry_matches (colorimetry, GST_VIDEO_COLORIMETRY_BT709)) + return VAProcColorStandardBT709; + /* NOTE: VAProcColorStandardBT2020 in VAAPI is the same as + * GST_VIDEO_COLORIMETRY_BT2020_10 in gstreamer. */ + if (gst_video_colorimetry_matches (colorimetry, + GST_VIDEO_COLORIMETRY_BT2020_10)) + return VAProcColorStandardBT2020; + if (gst_video_colorimetry_matches (colorimetry, GST_VIDEO_COLORIMETRY_BT601)) + return VAProcColorStandardBT601; + if (gst_video_colorimetry_matches (colorimetry, + GST_VIDEO_COLORIMETRY_SMPTE240M)) + return VAProcColorStandardSMPTE240M; + if (gst_video_colorimetry_matches (colorimetry, GST_VIDEO_COLORIMETRY_SRGB)) + return VAProcColorStandardSRGB; + + return VAProcColorStandardExplicit; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index cf19fb30ec..b2c0867d8c 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -26,6 +26,7 @@ #define GST_VAAPI_UTILS_H #include +#include #include /** calls vaInitialize() redirecting the logging mechanism */ @@ -166,4 +167,8 @@ G_GNUC_INTERNAL guint to_GstVaapiBufferMemoryType (guint va_type); +G_GNUC_INTERNAL +guint +from_GstVideoColorimetry (const GstVideoColorimetry *const colorimetry); + #endif /* GST_VAAPI_UTILS_H */ From 1c7e820805b49a89357de7ef6df975b4a5b42c72 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 30 Jan 2020 09:34:10 -0800 Subject: [PATCH 3514/3781] libs: filter: support vpp input/output color standard Add API function to allow setting the input and output vpp color standard from GstVideoColorimetry. --- gst-libs/gst/vaapi/gstvaapifilter.c | 113 +++++++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapifilter.h | 4 + 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 180804b15f..0dad05d4c4 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -71,6 +71,9 @@ struct _GstVaapiFilter guint use_target_rect:1; guint32 mirror_flags; guint32 rotation_flags; + + GstVideoColorimetry input_colorimetry; + GstVideoColorimetry output_colorimetry; }; typedef struct _GstVaapiFilterClass GstVaapiFilterClass; @@ -1216,6 +1219,10 @@ gst_vaapi_filter_initialize (GstVaapiFilter * filter) NULL, 0, &filter->va_context); if (!vaapi_check_status (va_status, "vaCreateContext() [VPP]")) return FALSE; + + gst_video_colorimetry_from_string (&filter->input_colorimetry, NULL); + gst_video_colorimetry_from_string (&filter->output_colorimetry, NULL); + return TRUE; } @@ -1519,6 +1526,21 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, return FALSE; } +static void +fill_color_standard (GstVideoColorimetry * colorimetry, + VAProcColorStandardType * type, VAProcColorProperties * properties) +{ + *type = from_GstVideoColorimetry (colorimetry); + if (*type == VAProcColorStandardExplicit) { + properties->colour_primaries = + gst_video_color_primaries_to_iso (colorimetry->primaries); + properties->transfer_characteristics = + gst_video_color_transfer_to_iso (colorimetry->transfer); + properties->matrix_coefficients = + gst_video_color_matrix_to_iso (colorimetry->matrix); + } +} + /** * gst_vaapi_filter_process: * @filter: a #GstVaapiFilter @@ -1619,9 +1641,16 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, memset (pipeline_param, 0, sizeof (*pipeline_param)); pipeline_param->surface = GST_VAAPI_SURFACE_ID (src_surface); pipeline_param->surface_region = &src_rect; - pipeline_param->surface_color_standard = VAProcColorStandardNone; + + fill_color_standard (&filter->input_colorimetry, + &pipeline_param->surface_color_standard, + &pipeline_param->input_color_properties); + + fill_color_standard (&filter->output_colorimetry, + &pipeline_param->output_color_standard, + &pipeline_param->output_color_properties); + pipeline_param->output_region = &dst_rect; - pipeline_param->output_color_standard = VAProcColorStandardNone; pipeline_param->output_background_color = 0xff000000; pipeline_param->filter_flags = from_GstVaapiSurfaceRenderFlags (flags) | from_GstVaapiScaleMethod (filter->scale_method); @@ -2201,3 +2230,83 @@ gst_vaapi_filter_get_video_direction_default (GstVaapiFilter * filter) { OP_RET_DEFAULT_VALUE (enum, filter, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION); } + +static gboolean +gst_vaapi_filter_set_colorimetry_unlocked (GstVaapiFilter * filter, + GstVideoColorimetry * input, GstVideoColorimetry * output) +{ + gchar *in_color, *out_color; + + if (input) + filter->input_colorimetry = *input; + else + gst_video_colorimetry_from_string (&filter->input_colorimetry, NULL); + + if (output) + filter->output_colorimetry = *output; + else + gst_video_colorimetry_from_string (&filter->output_colorimetry, NULL); + + in_color = gst_video_colorimetry_to_string (&filter->input_colorimetry); + GST_DEBUG_OBJECT (filter, " input colorimetry '%s'", in_color); + + out_color = gst_video_colorimetry_to_string (&filter->output_colorimetry); + GST_DEBUG_OBJECT (filter, "output colorimetry '%s'", out_color); + + if (!gst_vaapi_display_has_driver_quirks (filter->display, + GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD)) { + VAProcPipelineCaps pipeline_caps = { 0, }; + VAProcColorStandardType type; + guint32 i; + + VAStatus va_status = vaQueryVideoProcPipelineCaps (filter->va_display, + filter->va_context, NULL, 0, &pipeline_caps); + + if (!vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()")) + return FALSE; + + type = from_GstVideoColorimetry (&filter->input_colorimetry); + for (i = 0; i < pipeline_caps.num_input_color_standards; i++) + if (type == pipeline_caps.input_color_standards[i]) + break; + if ((i == pipeline_caps.num_input_color_standards) + && (type != VAProcColorStandardNone)) + GST_WARNING_OBJECT (filter, + "driver does not support '%s' input colorimetry." + " vpp may fail or produce unexpected results.", in_color); + + type = from_GstVideoColorimetry (&filter->output_colorimetry); + for (i = 0; i < pipeline_caps.num_output_color_standards; i++) + if (type == pipeline_caps.output_color_standards[i]) + break; + if ((i == pipeline_caps.num_output_color_standards) + && (type != VAProcColorStandardNone)) + GST_WARNING_OBJECT (filter, + "driver does not support '%s' output colorimetry." + " vpp may fail or produce unexpected results.", out_color); + } else { + GST_WARNING_OBJECT (filter, + "driver does not report the supported input/output colorimetry." + " vpp may fail or produce unexpected results."); + } + + g_free (in_color); + g_free (out_color); + + return TRUE; +} + +gboolean +gst_vaapi_filter_set_colorimetry (GstVaapiFilter * filter, + GstVideoColorimetry * input, GstVideoColorimetry * output) +{ + gboolean result; + + g_return_val_if_fail (filter != NULL, FALSE); + + GST_VAAPI_DISPLAY_LOCK (filter->display); + result = gst_vaapi_filter_set_colorimetry_unlocked (filter, input, output); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); + + return result; +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index fcd2e45b44..02c465b120 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -304,6 +304,10 @@ gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter); guint gst_vaapi_filter_get_skintone_level_default (GstVaapiFilter * filter); +gboolean +gst_vaapi_filter_set_colorimetry (GstVaapiFilter * filter, + GstVideoColorimetry * input, GstVideoColorimetry * output); + #ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiFilter, gst_object_unref) #endif From c01f2e30d6bb531c9c8a27ed0beb34d12c68ad9a Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 30 Jan 2020 09:37:18 -0800 Subject: [PATCH 3515/3781] vaapipostproc: set vpp filter colorimetry Set the input and output colorimetry for vpp filter. --- gst/vaapi/gstvaapipostproc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index d9d1561928..a9378776f6 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1654,7 +1654,11 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, gst_vaapipostproc_set_passthrough (trans); } - ret = TRUE; + ret = gst_vaapi_filter_set_colorimetry (postproc->filter, + &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO + (postproc)), + &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO + (postproc))); done: g_mutex_unlock (&postproc->postproc_lock); From 654e824555552a8baf0a9ccb702208fc6a08985c Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 30 Jan 2020 12:34:07 -0800 Subject: [PATCH 3516/3781] vaapipostproc: do not override explicit srcpad colorimetry If colorimetry has been set by a capsfilter (e.g. vaapipostproc ! video/x-raw,colorimetry=bt709) then don't try to override it. Previously, the aforementioned capsfilter will fail to negotiate if default colorimetry is not the same as the capsfilter (e.g. 4K resolutions). --- gst/vaapi/gstvaapipostprocutil.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 1e09e061d8..a11e555233 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -614,6 +614,10 @@ _set_colorimetry (GstVaapiPostproc * postproc, GstVideoFormat format, gst_video_chroma_to_string (GST_VIDEO_INFO_CHROMA_SITE (&vinfo)), NULL); } + /* if outs structure already specifies colorimetry, use it */ + if (gst_structure_has_field (outs, "colorimetry")) + return TRUE; + /* make sure we set the RGB matrix for RGB formats */ colorimetry = GST_VIDEO_INFO_COLORIMETRY (&vinfo); if (GST_VIDEO_FORMAT_INFO_IS_RGB (vinfo.finfo) && @@ -733,7 +737,7 @@ _get_preferred_caps (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, postproc->format = format; } - return outcaps; + return gst_caps_fixate (outcaps); /* ERRORS */ fixate_failed: From c6d8ee737f01f897940d79528b0452d117c26e24 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 4 Feb 2020 09:57:42 -0800 Subject: [PATCH 3517/3781] vaapipostproc: set srcpad colorimetry unconditionally We always need a srcpad colorimetry for VAAPI VPP operations. Also, check the return value of _set_colorimetry. --- gst/vaapi/gstvaapipostprocutil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index a11e555233..51cf7d7bde 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -719,8 +719,8 @@ _get_preferred_caps (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, goto fixate_failed; _set_multiview_mode (postproc, vinfo, structure); - if (f == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) - _set_colorimetry (postproc, format, structure); + if (!_set_colorimetry (postproc, format, structure)) + goto fixate_failed; if (!_set_interlace_mode (postproc, vinfo, structure)) goto interlace_mode_failed; From 2b6fa1966570b161008565a294bce863dbbd3ab7 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 4 Feb 2020 14:17:43 -0800 Subject: [PATCH 3518/3781] vaapipostproc: use sink resolution to calculate src colorimetry The default output colorimetry is persuaded by the output resolution, which is too naive when doing VPP cropping and/or scaling. For example, scaling 4K(sink)->1080P(src) resolution (i.e. both YUV) results in bt2020(sink)->bt709(src) colorimetry selection and some drivers don't support that mode in vpp. Thus, if output (i.e. downstream) does not specify a colorimetry then we use the input resolution instead of the output resolution to create the default colorimetry. Also, note that we still use the output format since it may be a different color space than the input. As in the example above, this will result in bt2020(sink)->bt2020(src) colorimetry selection and all drivers (afaik) should support that in vpp. --- gst/vaapi/gstvaapipostprocutil.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 51cf7d7bde..94ece02853 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -595,8 +595,8 @@ _set_multiview_mode (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, } static gboolean -_set_colorimetry (GstVaapiPostproc * postproc, GstVideoFormat format, - GstStructure * outs) +_set_colorimetry (GstVaapiPostproc * postproc, GstVideoInfo * sinkinfo, + GstVideoFormat format, GstStructure * outs) { GstVideoInfo vinfo; GstVideoColorimetry colorimetry; @@ -607,7 +607,10 @@ _set_colorimetry (GstVaapiPostproc * postproc, GstVideoFormat format, || !gst_structure_get_int (outs, "height", &height)) return FALSE; - gst_video_info_set_format (&vinfo, format, width, height); + /* Use the sink resolution and the src format to correctly determine the + * default src colorimetry. */ + gst_video_info_set_format (&vinfo, format, GST_VIDEO_INFO_WIDTH (sinkinfo), + GST_VIDEO_INFO_HEIGHT (sinkinfo)); if (GST_VIDEO_INFO_CHROMA_SITE (&vinfo) != GST_VIDEO_CHROMA_SITE_UNKNOWN) { gst_structure_set (outs, "chroma-site", G_TYPE_STRING, @@ -719,7 +722,7 @@ _get_preferred_caps (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, goto fixate_failed; _set_multiview_mode (postproc, vinfo, structure); - if (!_set_colorimetry (postproc, format, structure)) + if (!_set_colorimetry (postproc, vinfo, format, structure)) goto fixate_failed; if (!_set_interlace_mode (postproc, vinfo, structure)) From 33c80bccfe52d2ef45227bbea6d5e094019ec371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 7 Feb 2020 15:28:24 +0100 Subject: [PATCH 3519/3781] vaapidecode: don't remove chroma-site nor colorimetry Since now they can be handled by vaapipostproc. --- gst/vaapi/gstvaapidecode.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index db009f815f..f8ef4ace49 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -327,13 +327,6 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) GstStructure *structure = gst_caps_get_structure (state->caps, 0); if (!structure) break; - - /* Remove chroma-site and colorimetry from src caps, - * which is unnecessary on downstream if using VASurface - */ - gst_structure_remove_fields (structure, "chroma-site", "colorimetry", - NULL); - feature_str = gst_vaapi_caps_feature_to_string (feature); features = gst_caps_features_new (feature_str, NULL); gst_caps_set_features (state->caps, 0, features); From 9542d55efb2680dec81d11e7200f4479cf346427 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 7 Feb 2020 11:20:11 -0800 Subject: [PATCH 3520/3781] libs: utils: map GstVideoColorRange to VAAPI VPP --- gst-libs/gst/vaapi/gstvaapiutils.c | 21 +++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils.h | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 925510d2bc..33c137248a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -987,3 +987,24 @@ from_GstVideoColorimetry (const GstVideoColorimetry * const colorimetry) return VAProcColorStandardExplicit; } + +/** + * from_GstVideoColorRange: + * @value: a #GstVideoColorRange + * + * VPP: maps the #GstVideoColorRange to the VA value. + * + * Returns: the VA color range. + **/ +guint +from_GstVideoColorRange (const GstVideoColorRange value) +{ + switch (value) { + case GST_VIDEO_COLOR_RANGE_0_255: + return VA_SOURCE_RANGE_FULL; + case GST_VIDEO_COLOR_RANGE_16_235: + return VA_SOURCE_RANGE_REDUCED; + default: + return VA_SOURCE_RANGE_UNKNOWN; + } +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h index b2c0867d8c..315913229b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.h +++ b/gst-libs/gst/vaapi/gstvaapiutils.h @@ -171,4 +171,8 @@ G_GNUC_INTERNAL guint from_GstVideoColorimetry (const GstVideoColorimetry *const colorimetry); +G_GNUC_INTERNAL +guint +from_GstVideoColorRange (const GstVideoColorRange value); + #endif /* GST_VAAPI_UTILS_H */ From 5fe553f4c707003899c0bc17e3deb33edd89cb68 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 7 Feb 2020 11:25:31 -0800 Subject: [PATCH 3521/3781] libs: filter: set vpp input/output color range We've always sent VA_SOURCE_RANGE_UNKNOWN to the driver. And, the [iHD] driver essentially computes the same color range as gstreamer when we send VA_SOURCE_RANGE_UNKNOWN for cases were gstreamer computes it automatically. But, if the user wants to make it explicit, we should try to honor it. --- gst-libs/gst/vaapi/gstvaapifilter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 0dad05d4c4..5f41726dcb 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1539,6 +1539,8 @@ fill_color_standard (GstVideoColorimetry * colorimetry, properties->matrix_coefficients = gst_video_color_matrix_to_iso (colorimetry->matrix); } + + properties->color_range = from_GstVideoColorRange (colorimetry->range); } /** From 9d865453e1593cfc993fe277101bfc5ac2f0a179 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Mon, 10 Feb 2020 09:31:15 -0800 Subject: [PATCH 3522/3781] libs: utils: WA: use explicit for sRGB colorimetry Addresses #228 on iHD side. It seems iHD can't handle VAProcColorStandardSRGB in all situations for vpp. But it has no problem when we specify the sRGB parameters via VAProcColorStandardExplicit parameters. --- gst-libs/gst/vaapi/gstvaapiutils.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 33c137248a..2a100ab101 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -982,8 +982,6 @@ from_GstVideoColorimetry (const GstVideoColorimetry * const colorimetry) if (gst_video_colorimetry_matches (colorimetry, GST_VIDEO_COLORIMETRY_SMPTE240M)) return VAProcColorStandardSMPTE240M; - if (gst_video_colorimetry_matches (colorimetry, GST_VIDEO_COLORIMETRY_SRGB)) - return VAProcColorStandardSRGB; return VAProcColorStandardExplicit; } From 0f1b1f40e5fb4bdb9cf4b42390e17dd92bdc7d78 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 11 Feb 2020 00:38:40 -0800 Subject: [PATCH 3523/3781] libs: VA explicit color standard not supported until 1.2.0 VAProcColorStandardExplicit and associated VAProcColorProperties (primaries, transfer and matrix) are not supported until VA-API 1.2.0. Use VAProcColorStandardNone instead of VAProcColorStandardExplicit if VA-API < 1.2.0. Fixes #231 --- gst-libs/gst/vaapi/gstvaapifilter.c | 3 +++ gst-libs/gst/vaapi/gstvaapiutils.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 5f41726dcb..a2f2cb8da1 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1531,6 +1531,8 @@ fill_color_standard (GstVideoColorimetry * colorimetry, VAProcColorStandardType * type, VAProcColorProperties * properties) { *type = from_GstVideoColorimetry (colorimetry); + +#if VA_CHECK_VERSION(1,2,0) if (*type == VAProcColorStandardExplicit) { properties->colour_primaries = gst_video_color_primaries_to_iso (colorimetry->primaries); @@ -1539,6 +1541,7 @@ fill_color_standard (GstVideoColorimetry * colorimetry, properties->matrix_coefficients = gst_video_color_matrix_to_iso (colorimetry->matrix); } +#endif properties->color_range = from_GstVideoColorRange (colorimetry->range); } diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 2a100ab101..a3deff43cf 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -983,7 +983,11 @@ from_GstVideoColorimetry (const GstVideoColorimetry * const colorimetry) GST_VIDEO_COLORIMETRY_SMPTE240M)) return VAProcColorStandardSMPTE240M; +#if VA_CHECK_VERSION(1,2,0) return VAProcColorStandardExplicit; +#else + return VAProcColorStandardNone; +#endif } /** From 96cdebf185f7f549bf7c7827fa4ba592091030a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 11 Feb 2020 11:31:31 +0100 Subject: [PATCH 3524/3781] libs: remove crumbs of libva < 0.39 All these guarded code seem like leftovers of commit 920b1ec7a. This patch completes that missing clean up. --- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 2 -- gst-libs/gst/vaapi/gstvaapidisplay.c | 32 ------------------------ gst-libs/gst/vaapi/gstvaapiencoder.c | 15 ----------- 3 files changed, 49 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 0385dd04c2..32d02b1cca 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -822,9 +822,7 @@ fill_picture (GstVaapiDecoderVC1 * decoder, GstVaapiPicture * picture) pic_param->backward_reference_picture = VA_INVALID_ID; pic_param->inloop_decoded_picture = VA_INVALID_ID; pic_param->sequence_fields.value = 0; -#if VA_CHECK_VERSION(0,32,0) pic_param->sequence_fields.bits.profile = seq_hdr->profile; -#endif pic_param->coded_width = priv->width; pic_param->coded_height = priv->height; pic_param->entrypoint_fields.value = 0; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 0a34e1bcc6..f4413a0866 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -501,11 +501,8 @@ ensure_profiles (GstVaapiDisplay * display) GST_DEBUG ("%d profiles", n); for (i = 0; i < n; i++) { -#if VA_CHECK_VERSION(0,34,0) - /* Introduced in VA/VPP API */ if (profiles[i] == VAProfileNone) continue; -#endif GST_DEBUG (" %s", string_of_VAProfile (profiles[i])); } @@ -602,11 +599,6 @@ ensure_properties (GstVaapiDisplay * display) GST_DEBUG (" %s", string_of_VADisplayAttributeType (attr->type)); switch (attr->type) { -#if !VA_CHECK_VERSION(0,34,0) - case VADisplayAttribDirectSurface: - prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; - break; -#endif case VADisplayAttribRenderMode: prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE; break; @@ -1848,26 +1840,6 @@ get_render_mode_VADisplayAttribRenderMode (GstVaapiDisplay * display, return TRUE; } -static gboolean -get_render_mode_VADisplayAttribDirectSurface (GstVaapiDisplay * display, - GstVaapiRenderMode * pmode) -{ -#if VA_CHECK_VERSION(0,34,0) - /* VADisplayAttribDirectsurface was removed in VA-API >= 0.34.0 */ - return FALSE; -#else - gint direct_surface; - - if (!get_attribute (display, VADisplayAttribDirectSurface, &direct_surface)) - return FALSE; - if (direct_surface) - *pmode = GST_VAAPI_RENDER_MODE_OVERLAY; - else - *pmode = GST_VAAPI_RENDER_MODE_TEXTURE; - return TRUE; -#endif -} - static gboolean get_render_mode_default (GstVaapiDisplay * display, GstVaapiRenderMode * pmode) { @@ -1911,10 +1883,6 @@ gst_vaapi_display_get_render_mode (GstVaapiDisplay * display, if (get_render_mode_VADisplayAttribRenderMode (display, pmode)) return TRUE; - /* Try with direct-surface attribute */ - if (get_render_mode_VADisplayAttribDirectSurface (display, pmode)) - return TRUE; - /* Default: determine from the display type */ return get_render_mode_default (display, pmode); } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index edc443ab79..1184fc809b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -38,7 +38,6 @@ gboolean gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder, GstVaapiEncPicture * picture) { -#if VA_CHECK_VERSION(0,36,0) GstVaapiEncMiscParam *misc; /* quality level param is not supported */ @@ -52,7 +51,6 @@ gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder, sizeof (encoder->va_quality_level)); gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); -#endif return TRUE; } @@ -621,15 +619,6 @@ get_packed_headers (GstVaapiEncoder * encoder) encoder->got_packed_headers = TRUE; encoder->packed_headers = cdata->packed_headers & value; - if (cdata->codec == GST_VAAPI_CODEC_JPEG) { -#if !VA_CHECK_VERSION(0,37,1) - encoder->packed_headers = VA_ENC_PACKED_HEADER_RAW_DATA; - GST_DEBUG ("Hard coding the packed header flag value to " - "VA_ENC_PACKED_HEADER_RAW_DATA. This is a work around for the driver " - "bug"); -#endif - } - return encoder->packed_headers; } @@ -791,9 +780,7 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) GstVaapiVideoPool *pool; guint codedbuf_size, target_percentage; guint fps_d, fps_n; -#if VA_CHECK_VERSION(0,36,0) guint quality_level_max = 0; -#endif fps_d = GST_VIDEO_INFO_FPS_D (vip); fps_n = GST_VIDEO_INFO_FPS_N (vip); @@ -826,7 +813,6 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) if (!gst_vaapi_encoder_ensure_context (encoder)) goto error_reset_context; -#if VA_CHECK_VERSION(0,36,0) if (get_config_attribute (encoder, VAConfigAttribEncQualityRange, &quality_level_max) && quality_level_max > 0) { GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder) = @@ -836,7 +822,6 @@ gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder) } GST_INFO ("Quality level is fixed to %d", GST_VAAPI_ENCODER_QUALITY_LEVEL (encoder)); -#endif if (encoder->trellis) { #if VA_CHECK_VERSION(1,0,0) From 2aec396efd0aa5a939d62c7bc19c7d93c4dcd208 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Fri, 14 Feb 2020 16:17:04 +0800 Subject: [PATCH 3525/3781] libs: h265enc: Set VA_PICTURE_HEVC_INVALID flag for invalid picture --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 8f5cd91de6..2c9b79a6b7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1704,7 +1704,7 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, } for (; i < 15; ++i) { pic_param->reference_frames[i].picture_id = VA_INVALID_SURFACE; - pic_param->reference_frames[i].flags = 0; + pic_param->reference_frames[i].flags = VA_PICTURE_HEVC_INVALID; } pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf); @@ -1839,7 +1839,7 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, } for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i_ref) { slice_param->ref_pic_list0[i_ref].picture_id = VA_INVALID_SURFACE; - slice_param->ref_pic_list0[i_ref].flags = 0; + slice_param->ref_pic_list0[i_ref].flags = VA_PICTURE_HEVC_INVALID; } i_ref = 0; @@ -1859,7 +1859,7 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, } for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i_ref) { slice_param->ref_pic_list1[i_ref].picture_id = VA_INVALID_SURFACE; - slice_param->ref_pic_list1[i_ref].flags = 0; + slice_param->ref_pic_list1[i_ref].flags = VA_PICTURE_HEVC_INVALID; } slice_param->max_num_merge_cand = 5; /* MaxNumMergeCand */ From 5df8cf0cdb999ce516a4b4ac91394d397aef7186 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Sat, 15 Feb 2020 11:44:48 -0800 Subject: [PATCH 3526/3781] libs: utils: guard EncSliceLP for VA-API < 0.39.1 Relates to #234 --- gst-libs/gst/vaapi/gstvaapiutils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index a3deff43cf..ec59ea0008 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -269,7 +269,9 @@ string_of_VAEntrypoint (VAEntrypoint entrypoint) MAP (Deblocking); MAP (EncSlice); MAP (EncPicture); +#if VA_CHECK_VERSION(0,39,1) MAP (EncSliceLP); +#endif MAP (VideoProc); #if VA_CHECK_VERSION(1,0,0) MAP (FEI); From c55309c2ed451454f41488bdbd80b596d7fd6609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 14 Feb 2020 14:45:56 +0100 Subject: [PATCH 3527/3781] libs: video-format: set general vaapi log category Instead of logging in an unspecified category, set the default vaapi. --- gst-libs/gst/vaapi/video-format.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 5302fdf09f..5ebb211ccb 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -32,6 +32,9 @@ #include "gstvaapisurface.h" #include "video-format.h" +#define DEBUG 1 +#include "gst/vaapi/gstvaapidebug.h" + typedef struct _GstVideoFormatMapMap { GstVideoFormat format; From 566af572afc2a91d58d24cc8630b462c86903d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 7 Feb 2020 15:24:18 +0100 Subject: [PATCH 3528/3781] vaapipostproc: demote log message to trace level --- gst/vaapi/gstvaapipostproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index a9378776f6..31c35f0246 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1790,7 +1790,7 @@ gst_vaapipostproc_src_event (GstBaseTransform * trans, GstEvent * event) GstStructure *structure; gboolean ret; - GST_DEBUG_OBJECT (postproc, "handling %s event", GST_EVENT_TYPE_NAME (event)); + GST_TRACE_OBJECT (postproc, "handling %s event", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_NAVIGATION: From c4d8b5c44ca60b2044e3fb9378013f4039c45abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 17 Feb 2020 08:55:36 +0100 Subject: [PATCH 3529/3781] libs: decoder: h265: set parser info state at decoding codec data Commit 1168d6d5 showed up a regression: decode_sps() stores the unit's parser info in sps array. If that parser info comes from decoding codec data, that parser info will have an undefined state which might break ensure_sps(). This patch sets the parser info state, at decoding codec data, with the internal parser state. This is similar with h264 decoder apprach. Original-patch-by: Xu Guangxin --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 5d554fce46..100d553976 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2867,6 +2867,9 @@ gst_vaapi_decoder_h265_decode_codec_data (GstVaapiDecoder * goto cleanup; } + pi->state = priv->parser_state; + pi->flags = 0; + switch (pi->nalu.type) { case GST_H265_NAL_VPS: status = parse_vps (decoder, &unit); From 13c3b8ba5bdb8cad9857447b83741c7a8aa86a93 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Sat, 15 Feb 2020 11:02:49 -0800 Subject: [PATCH 3530/3781] libs: filter: guard all color properties to VA-API 1.2.0 Older VA-API (0.39.0) doesn't have VAProcColorProperties. Thus, guard all colorimetry -> VA-API support to version 1.2.0. Fixes #234 --- gst-libs/gst/vaapi/gstvaapifilter.c | 9 +++++++-- gst-libs/gst/vaapi/gstvaapiutils.c | 6 +++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index a2f2cb8da1..e25b7bc139 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1526,13 +1526,13 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, return FALSE; } +#if VA_CHECK_VERSION(1,2,0) static void fill_color_standard (GstVideoColorimetry * colorimetry, VAProcColorStandardType * type, VAProcColorProperties * properties) { *type = from_GstVideoColorimetry (colorimetry); -#if VA_CHECK_VERSION(1,2,0) if (*type == VAProcColorStandardExplicit) { properties->colour_primaries = gst_video_color_primaries_to_iso (colorimetry->primaries); @@ -1541,10 +1541,10 @@ fill_color_standard (GstVideoColorimetry * colorimetry, properties->matrix_coefficients = gst_video_color_matrix_to_iso (colorimetry->matrix); } -#endif properties->color_range = from_GstVideoColorRange (colorimetry->range); } +#endif /** * gst_vaapi_filter_process: @@ -1647,6 +1647,7 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, pipeline_param->surface = GST_VAAPI_SURFACE_ID (src_surface); pipeline_param->surface_region = &src_rect; +#if VA_CHECK_VERSION(1,2,0) fill_color_standard (&filter->input_colorimetry, &pipeline_param->surface_color_standard, &pipeline_param->input_color_properties); @@ -1654,6 +1655,10 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, fill_color_standard (&filter->output_colorimetry, &pipeline_param->output_color_standard, &pipeline_param->output_color_properties); +#else + pipeline_param->surface_color_standard = VAProcColorStandardNone; + pipeline_param->output_color_standard = VAProcColorStandardNone; +#endif pipeline_param->output_region = &dst_rect; pipeline_param->output_background_color = 0xff000000; diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index ec59ea0008..34ade89da7 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -969,6 +969,7 @@ to_GstVaapiBufferMemoryType (guint va_type) guint from_GstVideoColorimetry (const GstVideoColorimetry * const colorimetry) { +#if VA_CHECK_VERSION(1,2,0) if (!colorimetry || colorimetry->primaries == GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) return VAProcColorStandardNone; @@ -985,7 +986,6 @@ from_GstVideoColorimetry (const GstVideoColorimetry * const colorimetry) GST_VIDEO_COLORIMETRY_SMPTE240M)) return VAProcColorStandardSMPTE240M; -#if VA_CHECK_VERSION(1,2,0) return VAProcColorStandardExplicit; #else return VAProcColorStandardNone; @@ -1003,6 +1003,7 @@ from_GstVideoColorimetry (const GstVideoColorimetry * const colorimetry) guint from_GstVideoColorRange (const GstVideoColorRange value) { +#if VA_CHECK_VERSION(1,2,0) switch (value) { case GST_VIDEO_COLOR_RANGE_0_255: return VA_SOURCE_RANGE_FULL; @@ -1011,4 +1012,7 @@ from_GstVideoColorRange (const GstVideoColorRange value) default: return VA_SOURCE_RANGE_UNKNOWN; } +#else + return 0; +#endif } From 57e792136c0036e39bcf69011324cf05642b6641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 16 Feb 2020 17:19:04 +0100 Subject: [PATCH 3531/3781] libs: blend: filter: handle finalize() if display isn't assigned I've just discovered iHD driver in Skylake doesn't have VideoProc entry point, hence, in this platform, when vaapioverlay is tried to be registered, critical warnings are raised because blend doesn't have a display assigned. As it is possible to have drivers without EntryPointVideoProc it is required to handle it gracefully. This patch does that: only tries to register vaapioverlay if the testing display has VPP and finalize() vmethods, in filter and blend, bail out if display is NULL. --- gst-libs/gst/vaapi/gstvaapiblend.c | 4 ++++ gst-libs/gst/vaapi/gstvaapifilter.c | 4 ++++ gst/vaapi/gstvaapi.c | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiblend.c b/gst-libs/gst/vaapi/gstvaapiblend.c index 5b093d4d48..07a1ab6ed8 100644 --- a/gst-libs/gst/vaapi/gstvaapiblend.c +++ b/gst-libs/gst/vaapi/gstvaapiblend.c @@ -105,6 +105,9 @@ 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) { @@ -123,6 +126,7 @@ gst_vaapi_blend_finalize (GObject * object) gst_vaapi_display_replace (&blend->display, NULL); +bail: G_OBJECT_CLASS (gst_vaapi_blend_parent_class)->finalize (object); } diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index e25b7bc139..891e95af54 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1232,6 +1232,9 @@ gst_vaapi_filter_finalize (GObject * object) GstVaapiFilter *const filter = GST_VAAPI_FILTER (object); guint i; + if (!filter->display) + goto bail; + GST_VAAPI_DISPLAY_LOCK (filter->display); if (filter->operations) { for (i = 0; i < filter->operations->len; i++) { @@ -1255,6 +1258,7 @@ gst_vaapi_filter_finalize (GObject * object) GST_VAAPI_DISPLAY_UNLOCK (filter->display); gst_vaapi_display_replace (&filter->display, NULL); +bail: if (filter->forward_references) { g_array_unref (filter->forward_references); filter->forward_references = NULL; diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 1c4efff52d..324e4badfa 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -202,7 +202,8 @@ plugin_init (GstPlugin * plugin) g_array_unref (decoders); } - gst_vaapioverlay_register (plugin, display); + if (_gst_vaapi_has_video_processing) + gst_vaapioverlay_register (plugin, display); gst_element_register (plugin, "vaapipostproc", GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); From 15e169fbf1d7ea57a122ec0bdbd38d51ba61284f Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sun, 16 Feb 2020 01:25:37 +0800 Subject: [PATCH 3532/3781] videobufferpool: don't reset surface when created internally The bug fixing, in commit 89f202ea, just considers the case when surface's DMABuf is set through gst_buffer_pool_acquire_buffer(), which is typically a decoder's behavior. But vaapipostproc doesn't provide any surface when calling gst_buffer_pool_acquire_buffer(), thus a surface is created when GstMemory is allocated. If the surface proxy in buffer's meta is reset at buffer_pool_reset_buffer(), that surface will be destroyed and it won't be available anymore. But GstBuffers are cached in the buffer pool and they are reused again, hence only those images are rendered repeatedly. Fixes: #232 --- gst/vaapi/gstvaapivideobufferpool.c | 5 ++++- gst/vaapi/gstvaapivideomemory.c | 11 +++++++++++ gst/vaapi/gstvaapivideomemory.h | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 013766d8dc..082cf91e09 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -480,7 +480,10 @@ gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool, /* Release the underlying surface proxy */ if (GST_VAAPI_IS_VIDEO_MEMORY (mem)) { gst_vaapi_video_memory_reset_surface (GST_VAAPI_VIDEO_MEMORY_CAST (mem)); - } else { + } else if (!gst_vaapi_dmabuf_memory_holds_surface (mem)) { + /* If mem holds an internally created surface, don't reset it! + * While surface is passed, we should clear it to avoid wrong + * reference. */ meta = gst_buffer_get_vaapi_video_meta (buffer); if (meta) gst_vaapi_video_meta_set_surface_proxy (meta, NULL); diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 224a7ed2a3..92e7fe9f92 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1007,6 +1007,17 @@ gst_vaapi_buffer_proxy_quark_get (void) return g_quark; } +/* Whether @mem holds an internal VA surface proxy created at + * gst_vaapi_dmabuf_memory_new(). */ +gboolean +gst_vaapi_dmabuf_memory_holds_surface (GstMemory * mem) +{ + g_return_val_if_fail (mem != NULL, FALSE); + + return gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (mem), + GST_VAAPI_BUFFER_PROXY_QUARK) != NULL; +} + GstMemory * gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, GstVaapiVideoMeta * meta) diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index be18bbfe1c..41a05888b0 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -216,6 +216,10 @@ GstMemory * gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta); +G_GNUC_INTERNAL +gboolean +gst_vaapi_dmabuf_memory_holds_surface (GstMemory * mem); + /* ------------------------------------------------------------------------ */ /* --- GstVaapiDmaBufAllocator --- */ /* ------------------------------------------------------------------------ */ From 39f2c932ee8ef2f61e6980db15097053660a5aa4 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 21 Feb 2020 06:54:47 -0800 Subject: [PATCH 3533/3781] vaapipostproc: only set VPP colorimetry when VPP is available If we don't have functional vpp then we should not call gst_vaapi_filter_set_colorimetry. --- gst/vaapi/gstvaapipostproc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 31c35f0246..0fb75b8206 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1654,11 +1654,14 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, gst_vaapipostproc_set_passthrough (trans); } - ret = gst_vaapi_filter_set_colorimetry (postproc->filter, - &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO - (postproc)), - &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO - (postproc))); + if (postproc->has_vpp && !gst_vaapi_filter_set_colorimetry (postproc->filter, + &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO + (postproc)), + &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO + (postproc)))) + goto done; + + ret = TRUE; done: g_mutex_unlock (&postproc->postproc_lock); From 4573d3eefe84c99fc4fda6d2b749abcb72abc7da Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 21 Feb 2020 07:37:50 -0800 Subject: [PATCH 3534/3781] vaapipostproc: do not compensate for crop/direction if no VPP If we do not have functional VPP, then cropping and video direction is non-functional and we should avoid calling any of the gst_vaapi_filter* APIs. --- gst/vaapi/gstvaapipostproc.c | 29 ++++++++++++++++++----------- gst/vaapi/gstvaapipostprocutil.c | 28 +++++++++++++++------------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 0fb75b8206..ad2d75c600 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -718,6 +718,8 @@ rotate_crop_meta (GstVaapiPostproc * const postproc, const GstVideoMeta * vmeta, { guint tmp; + g_return_if_fail (postproc->has_vpp); + /* The video meta is required since the caps width/height are smaller, * which would not result in a usable GstVideoInfo for mapping the * buffer. */ @@ -1559,15 +1561,17 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans, info.width = video_meta->width; info.height = video_meta->height; - /* compensate for rotation if needed */ - switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { - case GST_VIDEO_ORIENTATION_90R: - case GST_VIDEO_ORIENTATION_UL_LR: - case GST_VIDEO_ORIENTATION_90L: - case GST_VIDEO_ORIENTATION_UR_LL: - G_PRIMITIVE_SWAP (guint, info.width, info.height); - default: - break; + if (postproc->has_vpp) { + /* compensate for rotation if needed */ + switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { + case GST_VIDEO_ORIENTATION_90R: + case GST_VIDEO_ORIENTATION_UL_LR: + case GST_VIDEO_ORIENTATION_90L: + case GST_VIDEO_ORIENTATION_UR_LL: + G_PRIMITIVE_SWAP (guint, info.width, info.height); + default: + break; + } } ensure_buffer_pool (postproc, &info); @@ -1765,6 +1769,8 @@ get_scale_factor (GstVaapiPostproc * const postproc, gdouble * w_factor, gdouble wd = GST_VIDEO_INFO_WIDTH (&postproc->srcpad_info); gdouble hd = GST_VIDEO_INFO_HEIGHT (&postproc->srcpad_info); + g_return_if_fail (postproc->has_vpp); + switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { case GST_VIDEO_ORIENTATION_90R: case GST_VIDEO_ORIENTATION_90L: @@ -1801,8 +1807,9 @@ gst_vaapipostproc_src_event (GstBaseTransform * trans, GstEvent * event) GST_EVENT (gst_mini_object_make_writable (GST_MINI_OBJECT (event))); structure = (GstStructure *) gst_event_get_structure (event); - if (gst_structure_get_double (structure, "pointer_x", &x) && - gst_structure_get_double (structure, "pointer_y", &y)) { + if (postproc->has_vpp + && gst_structure_get_double (structure, "pointer_x", &x) + && gst_structure_get_double (structure, "pointer_y", &y)) { GST_DEBUG_OBJECT (postproc, "converting %fx%f", x, y); /* video-direction compensation */ diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c index 94ece02853..715a449e4c 100644 --- a/gst/vaapi/gstvaapipostprocutil.c +++ b/gst/vaapi/gstvaapipostprocutil.c @@ -179,20 +179,22 @@ _fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo, from_w = GST_VIDEO_INFO_WIDTH (vinfo); from_h = GST_VIDEO_INFO_HEIGHT (vinfo); - /* adjust for crop settings */ - from_w -= postproc->crop_left + postproc->crop_right; - from_h -= postproc->crop_top + postproc->crop_bottom; + if (postproc->has_vpp) { + /* adjust for crop settings */ + from_w -= postproc->crop_left + postproc->crop_right; + from_h -= postproc->crop_top + postproc->crop_bottom; - /* compensate for rotation if needed */ - switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { - case GST_VIDEO_ORIENTATION_90R: - case GST_VIDEO_ORIENTATION_90L: - case GST_VIDEO_ORIENTATION_UL_LR: - case GST_VIDEO_ORIENTATION_UR_LL: - G_PRIMITIVE_SWAP (gint, from_w, from_h); - G_PRIMITIVE_SWAP (gint, from_par_n, from_par_d); - default: - break; + /* compensate for rotation if needed */ + switch (gst_vaapi_filter_get_video_direction (postproc->filter)) { + case GST_VIDEO_ORIENTATION_90R: + case GST_VIDEO_ORIENTATION_90L: + case GST_VIDEO_ORIENTATION_UL_LR: + case GST_VIDEO_ORIENTATION_UR_LL: + G_PRIMITIVE_SWAP (gint, from_w, from_h); + G_PRIMITIVE_SWAP (gint, from_par_n, from_par_d); + default: + break; + } } gst_structure_get_int (outs, "width", &w); From 17d82e14e78af901f1cd7f2344e173ad6ae6a8a6 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Fri, 14 Feb 2020 19:53:09 +0800 Subject: [PATCH 3535/3781] libs: h265enc: Set max_transform_hierarchy_depth_{inter, intra} to 2 Intel HW has limitation on max_transform_hierarchy_depth_inter and max_transform_hierarchy_depth_intra (see [1]). We can provide a quirk for other HWs if other HWs may support other values [1] https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol10-hevc.pdf --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 2c9b79a6b7..86ab5f81ca 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1640,8 +1640,14 @@ fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) seq_param->log2_diff_max_min_luma_coding_block_size = 2; seq_param->log2_min_transform_block_size_minus2 = 0; seq_param->log2_diff_max_min_transform_block_size = 3; - seq_param->max_transform_hierarchy_depth_inter = 3; - seq_param->max_transform_hierarchy_depth_intra = 3; + /* + * Intel HW supports up to 2, we can provide a quirk for other HWs in future + * if other HW may support other values + * + * Refer to https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol10-hevc.pdf + */ + seq_param->max_transform_hierarchy_depth_inter = 2; + seq_param->max_transform_hierarchy_depth_intra = 2; seq_param->pcm_sample_bit_depth_luma_minus1 = 0; seq_param->pcm_sample_bit_depth_chroma_minus1 = 0; From 7e7ab6e1f88369074be91e450cb76de5334bda6c Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 21 Feb 2020 00:50:47 +0800 Subject: [PATCH 3536/3781] build: fix meson build error when without x11. meson -Dwith_x11=no build_dir can not success build the project because the glx is still enabled. We need to disable GLX when X11 is disabled. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 3ee4fa61bf..ce4403f1bd 100644 --- a/meson.build +++ b/meson.build @@ -113,9 +113,9 @@ USE_VP9_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp9.h', dependencies USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() and get_option('with_drm') != 'no' USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no' -USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl_dep.found() and get_option('with_glx') != 'no' USE_WAYLAND = libva_wayland_dep.found() and wayland_client_dep.found() and wayland_protocols_dep.found() and wayland_scanner_bin.found() and get_option('with_wayland') != 'no' USE_X11 = libva_x11_dep.found() and x11_dep.found() and get_option('with_x11') != 'no' +USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl_dep.found() and get_option('with_glx') != 'no' and USE_X11 if not (USE_DRM or USE_X11 or USE_EGL or USE_GLX or USE_WAYLAND) error('No renderer API found (it is requried either DRM, X11 and/or WAYLAND)') From b7af4205aa26a1486dd64f39812ae1ad2dd72d63 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 21 Feb 2020 00:58:47 +0800 Subject: [PATCH 3537/3781] test: avoid unused warning for test-display meson -Dwith_x11=yes -Dwith_wayland=no -Dwith_drm=no -Dwith_egl=no -Dwith_glx=no buildir generate unused warnings. --- tests/internal/test-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/internal/test-display.c b/tests/internal/test-display.c index 068c155a24..e9ec12604a 100644 --- a/tests/internal/test-display.c +++ b/tests/internal/test-display.c @@ -205,7 +205,7 @@ int main (int argc, char *argv[]) { GstVaapiDisplay *display; -#if USE_X11 || USE_WAYLAND +#if USE_GLX || USE_WAYLAND guint width, height; guint par_n, par_d; #endif From 3ff51a6e5232ce529777ce5856c2afc12526a9c2 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 22 Feb 2020 16:06:13 +0800 Subject: [PATCH 3538/3781] build: let the build fail if none if X11, wayland or drm. In fact, gst_vaapi_create_test_display only test x11, wayland and drm, no glx and egl entries. So if none of them is enabled, no vaapi element can be detected. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index ce4403f1bd..3a6e93406b 100644 --- a/meson.build +++ b/meson.build @@ -117,7 +117,7 @@ USE_WAYLAND = libva_wayland_dep.found() and wayland_client_dep.found() and wayla USE_X11 = libva_x11_dep.found() and x11_dep.found() and get_option('with_x11') != 'no' USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl_dep.found() and get_option('with_glx') != 'no' and USE_X11 -if not (USE_DRM or USE_X11 or USE_EGL or USE_GLX or USE_WAYLAND) +if not (USE_DRM or USE_X11 or USE_WAYLAND) error('No renderer API found (it is requried either DRM, X11 and/or WAYLAND)') endif From 8c08ef31a5ce6c69ae0502b174ec591c0d0d8d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 24 Jan 2020 22:08:50 +0100 Subject: [PATCH 3539/3781] libs: surface: surfacepool: Add allocation flags in constructors. --- gst-libs/gst/vaapi/gstvaapicontext.c | 4 ++-- gst-libs/gst/vaapi/gstvaapisurface.c | 6 ++++-- gst-libs/gst/vaapi/gstvaapisurface.h | 3 ++- gst-libs/gst/vaapi/gstvaapisurface_egl.c | 2 +- gst-libs/gst/vaapi/gstvaapisurfacepool.c | 13 +++++++++---- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 5 +++-- gst-libs/gst/vaapi/gstvaapiwindow.c | 2 +- tests/internal/test-filter.c | 3 ++- tests/internal/test-surfaces.c | 2 +- 9 files changed, 25 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 315f9324a4..e4839d3e0b 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -171,7 +171,7 @@ context_ensure_surfaces (GstVaapiContext * context) 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); + cip->height, 0); } else { surface = gst_vaapi_surface_new (display, cip->chroma_type, cip->width, cip->height); @@ -204,7 +204,7 @@ context_create_surfaces (GstVaapiContext * context) if (!context->surfaces_pool) { context->surfaces_pool = gst_vaapi_surface_pool_new_with_chroma_type (display, cip->chroma_type, - cip->width, cip->height); + cip->width, cip->height, 0); if (!context->surfaces_pool) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 6aa3301a49..24da248d36 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -426,6 +426,7 @@ error: * @format: the surface format * @width: the requested surface width * @height: the requested surface height + * @surface_allocation_flags: (optional) allocation flags * * Creates a new #GstVaapiSurface with the specified pixel format and * dimensions. @@ -436,12 +437,13 @@ error: */ GstVaapiSurface * gst_vaapi_surface_new_with_format (GstVaapiDisplay * display, - GstVideoFormat format, guint width, guint height) + GstVideoFormat format, guint width, guint height, + guint surface_allocation_flags) { GstVideoInfo vi; gst_video_info_set_format (&vi, format, width, height); - return gst_vaapi_surface_new_full (display, &vi, 0); + return gst_vaapi_surface_new_full (display, &vi, surface_allocation_flags); } /** diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index adc9aa8965..be70ce9ff3 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -216,7 +216,8 @@ gst_vaapi_surface_new_full (GstVaapiDisplay * display, GstVaapiSurface * gst_vaapi_surface_new_with_format (GstVaapiDisplay * display, - GstVideoFormat format, guint width, guint height); + GstVideoFormat format, guint width, guint height, + guint surface_allocation_flags); GstVaapiSurface * gst_vaapi_surface_new_from_buffer_proxy (GstVaapiDisplay * display, diff --git a/gst-libs/gst/vaapi/gstvaapisurface_egl.c b/gst-libs/gst/vaapi/gstvaapisurface_egl.c index 02997434c7..f5aaa746d7 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_egl.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_egl.c @@ -147,7 +147,7 @@ create_surface_from_egl_image (GstVaapiDisplayEGL * display, GST_VAAPI_CHROMA_TYPE_YUV420, width, height); } else { out_surface = gst_vaapi_surface_new_with_format (base_display, - GST_VIDEO_INFO_FORMAT (vip), width, height); + GST_VIDEO_INFO_FORMAT (vip), width, height, 0); } if (!out_surface) goto error_create_surface; diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index c11d7796db..5ad85f0e53 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -108,6 +108,7 @@ gst_vaapi_surface_pool_class (void) * @format: a #GstVideoFormat * @width: the desired width, in pixels * @height: the desired height, in pixels + * @surface_allocation_flags: (optional) allocation flags * * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the specified * format and dimensions. If @format is GST_VIDEO_FORMAT_ENCODED, then @@ -118,7 +119,7 @@ gst_vaapi_surface_pool_class (void) */ GstVaapiVideoPool * gst_vaapi_surface_pool_new (GstVaapiDisplay * display, GstVideoFormat format, - guint width, guint height) + guint width, guint height, guint surface_allocation_flags) { GstVideoInfo vi; @@ -127,7 +128,8 @@ gst_vaapi_surface_pool_new (GstVaapiDisplay * display, GstVideoFormat format, g_return_val_if_fail (height > 0, NULL); gst_video_info_set_format (&vi, format, width, height); - return gst_vaapi_surface_pool_new_full (display, &vi, 0); + return gst_vaapi_surface_pool_new_full (display, &vi, + surface_allocation_flags); } /** @@ -176,6 +178,7 @@ error: * @chroma_type: a #GstVaapiChromatype * @width: the desired width, in pixels * @height: the desired height, in pixels + * @surface_allocation_flags: (optional) allocation flags * * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the specified * chroma type and dimensions. The underlying format of the surfaces is @@ -185,7 +188,8 @@ error: */ GstVaapiVideoPool * gst_vaapi_surface_pool_new_with_chroma_type (GstVaapiDisplay * display, - GstVaapiChromaType chroma_type, guint width, guint height) + GstVaapiChromaType chroma_type, guint width, guint height, + guint surface_allocation_flags) { GstVaapiVideoPool *pool; GstVideoInfo vi; @@ -197,7 +201,8 @@ gst_vaapi_surface_pool_new_with_chroma_type (GstVaapiDisplay * display, gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_ENCODED, width, height); - pool = gst_vaapi_surface_pool_new_full (display, &vi, 0); + pool = + gst_vaapi_surface_pool_new_full (display, &vi, surface_allocation_flags); if (!pool) return NULL; diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 9729a50374..1fa7fe1b2e 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -38,7 +38,7 @@ typedef struct _GstVaapiSurfacePool GstVaapiSurfacePool; GstVaapiVideoPool * gst_vaapi_surface_pool_new (GstVaapiDisplay * display, GstVideoFormat format, - guint width, guint height); + guint width, guint height, guint surface_allocation_flags); GstVaapiVideoPool * gst_vaapi_surface_pool_new_full (GstVaapiDisplay * display, @@ -46,7 +46,8 @@ gst_vaapi_surface_pool_new_full (GstVaapiDisplay * display, GstVaapiVideoPool * gst_vaapi_surface_pool_new_with_chroma_type (GstVaapiDisplay * display, - GstVaapiChromaType chroma_type, guint width, guint height); + GstVaapiChromaType chroma_type, guint width, guint height, + guint surface_allocation_flags); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 75b9e0e6f3..1af8037770 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -109,7 +109,7 @@ ensure_filter_surface_pool (GstVaapiWindow * window) /* Ensure VA surface pool is created */ /* XXX: optimize the surface format to use. e.g. YUY2 */ window->surface_pool = gst_vaapi_surface_pool_new (display, - GST_VIDEO_FORMAT_NV12, window->width, window->height); + GST_VIDEO_FORMAT_NV12, window->width, window->height, 0); if (!window->surface_pool) { GST_WARNING ("failed to create surface pool for conversion"); return FALSE; diff --git a/tests/internal/test-filter.c b/tests/internal/test-filter.c index fcdd95c25d..650af220e6 100644 --- a/tests/internal/test-filter.c +++ b/tests/internal/test-filter.c @@ -106,7 +106,8 @@ create_test_surface (GstVaapiDisplay * display, guint width, guint height, goto error_invalid_format; } - surface = gst_vaapi_surface_new_with_format (display, format, width, height); + surface = + gst_vaapi_surface_new_with_format (display, format, width, height, 0); if (!surface) goto error_create_surface; diff --git a/tests/internal/test-surfaces.c b/tests/internal/test-surfaces.c index d0fbfaf4dc..9f515eedb3 100644 --- a/tests/internal/test-surfaces.c +++ b/tests/internal/test-surfaces.c @@ -60,7 +60,7 @@ main (int argc, char *argv[]) gst_vaapi_surface_unref (surface); pool = gst_vaapi_surface_pool_new (display, GST_VIDEO_FORMAT_ENCODED, - width, height); + width, height, 0); if (!pool) g_error ("could not create Gst/VA surface pool"); From 96fdc3d322c7bf083a1411879863e1717ff2fc32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 24 Jan 2020 19:32:52 +0100 Subject: [PATCH 3540/3781] libs: surface: Add hints to allocation flags. When creating surfaces it is possible to pass to VA hints of its usage, so the driver may do some optimizations. This commit adds the handling of encoding/decoding hints. --- gst-libs/gst/vaapi/gstvaapisurface.c | 23 ++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapisurface.h | 5 +++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 24da248d36..3e92e0eaf9 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -129,6 +129,21 @@ error_unsupported_chroma_type: return FALSE; } +static guint +get_usage_hint (guint alloc_flags) +{ + guint usage_hints = VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC; + + /* XXX(victor): So far, only media-driver uses hints for encoders + * and it doesn't test it as bitwise */ + if (alloc_flags & GST_VAAPI_SURFACE_ALLOC_FLAG_HINT_DECODER) + usage_hints = VA_SURFACE_ATTRIB_USAGE_HINT_DECODER; + else if (alloc_flags & GST_VAAPI_SURFACE_ALLOC_FLAG_HINT_ENCODER) + usage_hints = VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER; + + return usage_hints; +} + static gboolean gst_vaapi_surface_init_full (GstVaapiSurface * surface, const GstVideoInfo * vip, guint surface_allocation_flags) @@ -139,7 +154,7 @@ gst_vaapi_surface_init_full (GstVaapiSurface * surface, VAStatus status; guint chroma_type, va_chroma_format, i; const VAImageFormat *va_format; - VASurfaceAttrib attribs[3], *attrib; + VASurfaceAttrib attribs[4], *attrib; VASurfaceAttribExternalBuffers extbuf = { 0, }; gboolean extbuf_needed = FALSE; @@ -182,6 +197,12 @@ gst_vaapi_surface_init_full (GstVaapiSurface * surface, attrib->value.value.i = va_format->fourcc; attrib++; + attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; + attrib->type = VASurfaceAttribUsageHint; + attrib->value.type = VAGenericValueTypeInteger; + attrib->value.value.i = get_usage_hint (surface_allocation_flags); + attrib++; + if (extbuf_needed) { attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; attrib->type = VASurfaceAttribMemoryType; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index be70ce9ff3..68f99ff2ed 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -165,6 +165,9 @@ typedef enum * the supplied strides information from #GstVideoInfo * @GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS: force allocation with * the supplied offsets information from #GstVideoInfo + * @GST_VAAPI_SURFACE_ALLOC_FLAG_HINT_DECODER: Surface used by video + * decoder + * @GST_VAAPI_SURFACE_ALLOC_FLAG_HINT_ENCODER: Surface used by encoder * * The set of optional allocation flags for gst_vaapi_surface_new_full(). */ @@ -173,6 +176,8 @@ typedef enum GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE = 1 << 0, GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES = 1 << 1, GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS = 1 << 2, + GST_VAAPI_SURFACE_ALLOC_FLAG_HINT_DECODER = 1 << 3, + GST_VAAPI_SURFACE_ALLOC_FLAG_HINT_ENCODER = 1 << 4, } GstVaapiSurfaceAllocFlags; #define GST_VAAPI_SURFACE(obj) \ From dd428cc4a12c2d5c694fcd3303811cf486002c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 27 Jan 2020 18:10:18 +0100 Subject: [PATCH 3541/3781] vaapivideomemory: Store surface allocation flags. Store surface allocation flags passed to the vaapi allocator in GObject's qdata, because it might be used by the vaapivideobufferpool when recreating the allocator given any resolution change. --- gst/vaapi/gstvaapivideomemory.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 92e7fe9f92..c92a418ac9 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -987,6 +987,9 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display, return NULL; } + gst_allocator_set_vaapi_video_info (GST_ALLOCATOR_CAST (allocator), + alloc_info, surface_alloc_flags); + return GST_ALLOCATOR_CAST (allocator); } From fab890ceb522e7f27bd8fc615e6052e22ff8ff4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 27 Jan 2020 18:19:57 +0100 Subject: [PATCH 3542/3781] vaapivideomemory: Try surface with allocation flags. When a vaapi allocator is instantiated, it first try to generate a surface with the specified configuration. This patch adds, in this tried buffer, the requested allocation flags. --- gst/vaapi/gstvaapivideomemory.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index c92a418ac9..4cf741ed90 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -739,14 +739,16 @@ gst_vaapi_image_usage_flags_to_string (GstVaapiImageUsageFlags usage_flag) static inline gboolean allocator_configure_surface_try_specified_format (GstVaapiDisplay * display, const GstVideoInfo * allocation_info, GstVaapiImageUsageFlags usage_flag, - GstVideoInfo * ret_surface_info, GstVaapiImageUsageFlags * ret_usage_flag) + guint surface_alloc_flag, GstVideoInfo * ret_surface_info, + GstVaapiImageUsageFlags * ret_usage_flag) { GstVaapiImageUsageFlags rflag; GstVaapiSurface *surface; GstVideoInfo sinfo, rinfo; /* Try to create a surface with the given allocation info */ - surface = gst_vaapi_surface_new_full (display, allocation_info, 0); + surface = + gst_vaapi_surface_new_full (display, allocation_info, surface_alloc_flag); if (!surface) return FALSE; @@ -841,7 +843,8 @@ error_no_surface: static inline gboolean allocator_configure_surface_info (GstVaapiDisplay * display, - GstVaapiVideoAllocator * allocator, GstVaapiImageUsageFlags req_usage_flag) + GstVaapiVideoAllocator * allocator, GstVaapiImageUsageFlags req_usage_flag, + guint surface_alloc_flags) { GstVaapiImageUsageFlags usage_flag; GstVideoInfo allocation_info, surface_info; @@ -853,7 +856,8 @@ allocator_configure_surface_info (GstVaapiDisplay * display, /* Step1: Try the specified format and flag. May fallback to native if direct upload/rendering is unavailable. */ if (allocator_configure_surface_try_specified_format (display, - &allocation_info, req_usage_flag, &surface_info, &usage_flag)) { + &allocation_info, req_usage_flag, surface_alloc_flags, + &surface_info, &usage_flag)) { allocator->usage_flag = usage_flag; allocator->surface_info = surface_info; goto success; @@ -935,7 +939,8 @@ allocator_params_init (GstVaapiVideoAllocator * allocator, { allocator->allocation_info = *alloc_info; - if (!allocator_configure_surface_info (display, allocator, req_usage_flag)) + if (!allocator_configure_surface_info (display, allocator, req_usage_flag, + surface_alloc_flags)) return FALSE; allocator->surface_pool = gst_vaapi_surface_pool_new_full (display, &allocator->surface_info, surface_alloc_flags); From 164656ee1d3bc12bfbe87a0cc11bd345cd6f654f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 28 Feb 2020 11:33:18 +0100 Subject: [PATCH 3543/3781] Revert "vaapivideomemory: Store surface allocation flags." This reverts commit dd428cc4a12c2d5c694fcd3303811cf486002c9d because it rewrites the buffer size whilst surface allocation flags are stored when allocator_params_init() is called since fab890ce. Fix: #239 --- gst/vaapi/gstvaapivideomemory.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 4cf741ed90..f01a2ef44c 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -992,9 +992,6 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display, return NULL; } - gst_allocator_set_vaapi_video_info (GST_ALLOCATOR_CAST (allocator), - alloc_info, surface_alloc_flags); - return GST_ALLOCATOR_CAST (allocator); } From 13601f4071420ea6ade1aeb0512cfbbbfb62821b Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 25 Feb 2020 12:00:36 -0800 Subject: [PATCH 3544/3781] libs: display: add YUV to/from RGB color primary quirk The intel-media-driver (iHD) can't convert output color primaries when doing YUV to/from RGB CSC. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay.h | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index f4413a0866..045be5b4b5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -780,6 +780,7 @@ set_driver_quirks (GstVaapiDisplay * display) /* @XXX(victor): is this string enough to identify it */ { "AMD", GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE }, { "i965", GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD }, + { "iHD", GST_VAAPI_DRIVER_QUIRK_NO_RGBYUV_VPP_COLOR_PRIMARY }, }; /* *INDENT-ON* */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 0f6f136afe..ecbe0709ab 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -94,11 +94,19 @@ typedef struct _GstVaapiDisplay GstVaapiDisplay; * 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_NO_RGBYUV_VPP_COLOR_PRIMARY: if driver can + * only do CSC from YUV to RGB, and vice-versa without changing the + * color standard primaries. This quirk is initially introduced to + * work around a problem in the intel-media-driver (iHD) reported here: + * https://github.com/intel/media-driver/issues/860. Once the driver + * issue is fixed, we should remove this quirk. Also see this issue: + * https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/238 */ 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_NO_RGBYUV_VPP_COLOR_PRIMARY = (1U << 2), } GstVaapiDriverQuirks; /** From acf90c107000cad626e7873590e5026156db5765 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Tue, 25 Feb 2020 12:05:28 -0800 Subject: [PATCH 3545/3781] libs: filter: handle RGB to/from YUV color primary driver quirk The intel-media-driver (iHD) can't convert output color primaries when doing YUV to/from RGB CSC. Thus, we must keep the output color primaries the same as the input color primaries for this case. fixes #238 --- gst-libs/gst/vaapi/gstvaapifilter.c | 61 +++++++++++++++++++---------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 891e95af54..52ea9e94a3 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1537,19 +1537,51 @@ fill_color_standard (GstVideoColorimetry * colorimetry, { *type = from_GstVideoColorimetry (colorimetry); - if (*type == VAProcColorStandardExplicit) { - properties->colour_primaries = - gst_video_color_primaries_to_iso (colorimetry->primaries); - properties->transfer_characteristics = - gst_video_color_transfer_to_iso (colorimetry->transfer); - properties->matrix_coefficients = - gst_video_color_matrix_to_iso (colorimetry->matrix); - } + properties->colour_primaries = + gst_video_color_primaries_to_iso (colorimetry->primaries); + properties->transfer_characteristics = + gst_video_color_transfer_to_iso (colorimetry->transfer); + properties->matrix_coefficients = + gst_video_color_matrix_to_iso (colorimetry->matrix); properties->color_range = from_GstVideoColorRange (colorimetry->range); } #endif +static void +gst_vaapi_filter_fill_color_standards (GstVaapiFilter * filter, + VAProcPipelineParameterBuffer * pipeline_param) +{ +#if VA_CHECK_VERSION(1,2,0) + fill_color_standard (&filter->input_colorimetry, + &pipeline_param->surface_color_standard, + &pipeline_param->input_color_properties); + + fill_color_standard (&filter->output_colorimetry, + &pipeline_param->output_color_standard, + &pipeline_param->output_color_properties); + + /* Handle RGB <-> YUV color primary driver quirk */ + if (gst_vaapi_display_has_driver_quirks (filter->display, + GST_VAAPI_DRIVER_QUIRK_NO_RGBYUV_VPP_COLOR_PRIMARY)) { + gboolean src_is_rgb = gst_video_colorimetry_matches + (&filter->input_colorimetry, GST_VIDEO_COLORIMETRY_SRGB); + gboolean dst_is_rgb = gst_video_colorimetry_matches + (&filter->output_colorimetry, GST_VIDEO_COLORIMETRY_SRGB); + + if ((!src_is_rgb && dst_is_rgb) || (src_is_rgb && !dst_is_rgb)) { + pipeline_param->output_color_standard = VAProcColorStandardExplicit; + pipeline_param->output_color_properties.colour_primaries = + gst_video_color_primaries_to_iso (filter-> + input_colorimetry.primaries); + } + } +#else + pipeline_param->surface_color_standard = VAProcColorStandardNone; + pipeline_param->output_color_standard = VAProcColorStandardNone; +#endif +} + /** * gst_vaapi_filter_process: * @filter: a #GstVaapiFilter @@ -1651,18 +1683,7 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter, pipeline_param->surface = GST_VAAPI_SURFACE_ID (src_surface); pipeline_param->surface_region = &src_rect; -#if VA_CHECK_VERSION(1,2,0) - fill_color_standard (&filter->input_colorimetry, - &pipeline_param->surface_color_standard, - &pipeline_param->input_color_properties); - - fill_color_standard (&filter->output_colorimetry, - &pipeline_param->output_color_standard, - &pipeline_param->output_color_properties); -#else - pipeline_param->surface_color_standard = VAProcColorStandardNone; - pipeline_param->output_color_standard = VAProcColorStandardNone; -#endif + gst_vaapi_filter_fill_color_standards (filter, pipeline_param); pipeline_param->output_region = &dst_rect; pipeline_param->output_background_color = 0xff000000; From ae0261023af502bf71eb906b59b60f9b73973c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 14 Feb 2020 19:30:54 +0100 Subject: [PATCH 3546/3781] libs: display: iterate all quirks table Instead of break at the fist foud quirk in the table, iterate all over so it would be feasible to add several quirks for one driver per element in array. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 045be5b4b5..a048a42f02 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -791,12 +791,12 @@ set_driver_quirks (GstVaapiDisplay * display) const char *match_str = vaapi_driver_quirks_table[i].match_string; if (g_strstr_len (priv->vendor_string, strlen (priv->vendor_string), match_str) != NULL) { - GST_INFO_OBJECT (display, "Matched driver string \"%s\", setting quirks " - "(%#x)", priv->vendor_string, vaapi_driver_quirks_table[i].quirks); priv->driver_quirks |= vaapi_driver_quirks_table[i].quirks; - break; } } + + GST_INFO_OBJECT (display, "Matched driver string \"%s\", setting quirks " + "(%#x)", priv->vendor_string, priv->driver_quirks); } static void From a8031bcb0e343be48c07abe52c9907dcfa53fdea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 16 Feb 2020 12:21:28 +0100 Subject: [PATCH 3547/3781] libs: display: force RGBA image format for i965 driver Since commit 32bf6f1e GLTextureUpload is broken because i965 doesn't report properly RGBA support. It could be possible to use RGBx but GLTextureUpload only regotiates RGBA. The simplest fix to this regression is adding synthetically the RGBA format in the internal format map. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 29 ++++++++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapidisplay.h | 5 +++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index a048a42f02..ca235d943c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -652,7 +652,7 @@ ensure_image_formats (GstVaapiDisplay * display) GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); VAImageFormat *formats = NULL; VAStatus status; - gint i, n; + gint i, n, max_images; gboolean success = FALSE; GST_VAAPI_DISPLAY_LOCK (display); @@ -666,7 +666,8 @@ ensure_image_formats (GstVaapiDisplay * display) goto cleanup; /* VA image formats */ - formats = g_new (VAImageFormat, vaMaxNumImageFormats (priv->display)); + max_images = vaMaxNumImageFormats (priv->display); + formats = g_new (VAImageFormat, max_images); if (!formats) goto cleanup; @@ -675,6 +676,29 @@ ensure_image_formats (GstVaapiDisplay * display) if (!vaapi_check_status (status, "vaQueryImageFormats()")) goto cleanup; + /* XXX(victor): Force RGBA in i965 display formats. + * + * This is required for GLTextureUploadMeta since it only negotiates + * RGBA, nevertheless i965 driver only reports RGBx breaking back + * compatibility. + * + * Side effects are not expected since it worked before commit + * 32bf6f1e */ + if (gst_vaapi_display_has_driver_quirks (display, + GST_VAAPI_DRIVER_QUIRK_MISSING_RGBA_IMAGE_FORMAT)) { + formats = g_renew (VAImageFormat, formats, max_images + 1); + + formats[n].fourcc = VA_FOURCC_RGBA; + formats[n].byte_order = VA_LSB_FIRST; + formats[n].bits_per_pixel = 32; + formats[n].depth = 32; + formats[n].red_mask = 0x000000ff; + formats[n].green_mask = 0x0000ff00; + formats[n].blue_mask = 0x00ff0000; + formats[n].alpha_mask = 0xff000000; + n++; + } + GST_DEBUG ("%d image formats", n); for (i = 0; i < n; i++) GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc)); @@ -781,6 +805,7 @@ set_driver_quirks (GstVaapiDisplay * display) { "AMD", GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE }, { "i965", GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD }, { "iHD", GST_VAAPI_DRIVER_QUIRK_NO_RGBYUV_VPP_COLOR_PRIMARY }, + { "i965", GST_VAAPI_DRIVER_QUIRK_MISSING_RGBA_IMAGE_FORMAT }, }; /* *INDENT-ON* */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index ecbe0709ab..0d0a1492fe 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -101,12 +101,17 @@ typedef struct _GstVaapiDisplay GstVaapiDisplay; * https://github.com/intel/media-driver/issues/860. Once the driver * issue is fixed, we should remove this quirk. Also see this issue: * https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/238 + * @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 */ 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_NO_RGBYUV_VPP_COLOR_PRIMARY = (1U << 2), + GST_VAAPI_DRIVER_QUIRK_MISSING_RGBA_IMAGE_FORMAT = (1U << 3), } GstVaapiDriverQuirks; /** From bf2299279f61e3bb8ee952a971fd05b0bbd665a6 Mon Sep 17 00:00:00 2001 From: Xu Guangxin Date: Tue, 3 Mar 2020 15:24:32 +0800 Subject: [PATCH 3548/3781] libs: decoder: h265: parser state after update dependent slice If the dependent_slice_segment_flag is true, most slice info derived from last slice. So we need check the slice type after we call populate_dependent_slice_hdr --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 100d553976..0516acf81c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1474,8 +1474,6 @@ parse_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) return get_status (result); priv->parser_state |= GST_H265_VIDEO_STATE_GOT_SLICE; - if (!GST_H265_IS_I_SLICE (slice_hdr)) - priv->parser_state |= GST_H265_VIDEO_STATE_GOT_P_SLICE; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -3147,6 +3145,8 @@ gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder, pi); else populate_dependent_slice_hdr (pi, priv->prev_independent_slice_pi); + if (!GST_H265_IS_I_SLICE (&pi->data.slice_hdr)) + priv->parser_state |= GST_H265_VIDEO_STATE_GOT_P_SLICE; break; default: /* Fix */ From 6e65356017d4f7fda37810daedf8f28b44943efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 5 Mar 2020 13:26:38 +0100 Subject: [PATCH 3549/3781] vaapidecode: unlock stream if caps update fails If caps update fail a dead lock occurs since the stream mutex is not unlocked. --- gst/vaapi/gstvaapidecode.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f8ef4ace49..915cbab5ac 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -472,17 +472,23 @@ gst_vaapidecode_negotiate (GstVaapiDecode * decode) GST_VIDEO_DECODER_STREAM_LOCK (vdec); if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) - return FALSE; + goto caps_negotiation_failed; if (!gst_vaapidecode_update_src_caps (decode)) - return FALSE; + goto caps_negotiation_failed; if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) - return FALSE; + goto caps_negotiation_failed; GST_VIDEO_DECODER_STREAM_UNLOCK (vdec); if (!gst_video_decoder_negotiate (vdec)) return FALSE; return TRUE; + +caps_negotiation_failed: + { + GST_VIDEO_DECODER_STREAM_UNLOCK (vdec); + return FALSE; + } } static gboolean From 385892dd32050c6c27760c0fdeb4748590f49c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 5 Mar 2020 14:18:32 +0100 Subject: [PATCH 3550/3781] vaapidecode: don't set base sink caps twice Base class's sink pad caps are already set when calling set_format(). There's no need to call it again in gst_vaapidecode_negotiate(). --- gst/vaapi/gstvaapidecode.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 915cbab5ac..d5db810793 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -471,8 +471,6 @@ gst_vaapidecode_negotiate (GstVaapiDecode * decode) GST_DEBUG_OBJECT (decode, "input codec state changed: renegotiating"); GST_VIDEO_DECODER_STREAM_LOCK (vdec); - if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL)) - goto caps_negotiation_failed; if (!gst_vaapidecode_update_src_caps (decode)) goto caps_negotiation_failed; if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps)) From da008baac29c3319cc13c0c3b20ce3669820458d Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 5 Mar 2020 13:22:23 -0800 Subject: [PATCH 3551/3781] vaapivideobufferpool: force video meta if sizes are different The strides and offsets could be the same, but the allocation size might be different (e.g. alignment). Thus, ensure we also set the flag to copy from VA memory to system memory when alloc size differs. Fixes #243 --- gst/vaapi/gstvaapivideobufferpool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 082cf91e09..2de92ea581 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -250,7 +250,9 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool, if (GST_VIDEO_INFO_PLANE_OFFSET (&new_allocation_vinfo, i) != GST_VIDEO_INFO_PLANE_OFFSET (&priv->vmeta_vinfo, i) || GST_VIDEO_INFO_PLANE_STRIDE (&new_allocation_vinfo, i) != - GST_VIDEO_INFO_PLANE_STRIDE (&priv->vmeta_vinfo, i)) { + GST_VIDEO_INFO_PLANE_STRIDE (&priv->vmeta_vinfo, i) || + GST_VIDEO_INFO_SIZE (&new_allocation_vinfo) != + GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo)) { priv->options |= GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META; priv->forced_video_meta = TRUE; GST_INFO_OBJECT (base_pool, "adding unrequested video meta"); From 5e612aeb849b678b046e8249657f2fb70b055572 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 7 Feb 2020 23:56:13 +0800 Subject: [PATCH 3552/3781] libs: videopool: fix a condition race for pool allocate. --- gst-libs/gst/vaapi/gstvaapivideopool.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index faba367752..cb3ef3a6d4 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -179,6 +179,13 @@ gst_vaapi_video_pool_get_object_unlocked (GstVaapiVideoPool * pool) g_mutex_lock (&pool->mutex); if (!object) return NULL; + + /* Others already allocated a new one before us during we + release the mutex */ + if (pool->capacity && pool->used_count >= pool->capacity) { + gst_mini_object_unref (object); + return NULL; + } } ++pool->used_count; From 5eb87165987e4bbf566db7b9fd309aa00535b52a Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 9 Mar 2020 01:52:57 +0800 Subject: [PATCH 3553/3781] test: fix a ninja test failure for vaapioverlay. That test case only works with drm display, so the build such as meson -Dwith_x11=yes -Dwith_wayland=no -Dwith_drm=no -Dwith_egl=no -Dwith_glx=no gets a failure when run ninja test. Just enable this test when drm is enabled. --- tests/check/meson.build | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/check/meson.build b/tests/check/meson.build index 8e631d5737..cedd86287f 100644 --- a/tests/check/meson.build +++ b/tests/check/meson.build @@ -1,8 +1,13 @@ tests = [ [ 'elements/vaapipostproc' ], - [ 'elements/vaapioverlay' ], ] +if USE_DRM + tests += [ + [ 'elements/vaapioverlay' ] +] +endif + test_deps = [gst_dep, gstbase_dep, gstvideo_dep, gstcheck_dep] test_defines = [ '-UG_DISABLE_ASSERT', From d6bcbe47e99f17d3f8f7c899a4f822143343403a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 17 Mar 2020 12:47:33 +0100 Subject: [PATCH 3554/3781] plugin: don't error if cannot create display This might generated errors on automatic tools such as CI. Let's rather just raise a warning and let continue. --- gst/vaapi/gstvaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 324e4badfa..71bdacf4d2 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -227,7 +227,7 @@ plugin_init (GstPlugin * plugin) /* ERRORS: */ error_no_display: { - GST_ERROR ("Cannot create a VA display"); + GST_WARNING ("Cannot create a VA display"); /* Avoid blacklisting: failure to create a display could be a * transient condition */ return TRUE; From f303b4a30ff8b9e1b66322eb9da8d1e93be85dd4 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 17 Mar 2020 18:51:19 +0800 Subject: [PATCH 3555/3781] libs: utils: Add HEVC Main444 sting in string_of_VAProfile HEVCMain444_10 is already a supported profile and misses the strings. --- gst-libs/gst/vaapi/gstvaapiutils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 34ade89da7..319eb579f3 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -237,6 +237,7 @@ string_of_VAProfile (VAProfile profile) #if VA_CHECK_VERSION(1,2,0) MAP (HEVCMain422_10); MAP (HEVCMain444); + MAP (HEVCMain444_10); #endif MAP (HEVCMain); MAP (HEVCMain10); From bb380557458a05774ccd22ba93fb7b24b50a61d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 13 Mar 2020 21:49:15 +0100 Subject: [PATCH 3556/3781] libs: remove GstVaapiPixmap GstVaapiPixmap is an abstract base class which only implementation were GstVaapiPixmapX11. This class were used for a special type of rendering in the tests apps, utterly unrelated in GStreamer. Since gstreamer-vaapi is no longer a general-user wrapper for VA-API we should remove this unused API. This removal drops libxrender dependency. --- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 9 - gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 12 - gst-libs/gst/vaapi/gstvaapipixmap.c | 263 ------------------ gst-libs/gst/vaapi/gstvaapipixmap.h | 98 ------- gst-libs/gst/vaapi/gstvaapipixmap_priv.h | 113 -------- gst-libs/gst/vaapi/gstvaapipixmap_x11.c | 251 ----------------- gst-libs/gst/vaapi/gstvaapipixmap_x11.h | 61 ---- gst-libs/gst/vaapi/gstvaapiwindow.c | 54 ---- gst-libs/gst/vaapi/gstvaapiwindow.h | 5 - gst-libs/gst/vaapi/gstvaapiwindow_egl.c | 22 +- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 2 - gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 118 -------- gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 4 - gst-libs/gst/vaapi/meson.build | 6 +- meson.build | 2 - tests/internal/output.c | 16 +- tests/internal/output.h | 9 - tests/internal/simple-decoder.c | 67 +---- tests/internal/test-decode.c | 30 +- 19 files changed, 10 insertions(+), 1132 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapipixmap.c delete mode 100644 gst-libs/gst/vaapi/gstvaapipixmap.h delete mode 100644 gst-libs/gst/vaapi/gstvaapipixmap_priv.h delete mode 100644 gst-libs/gst/vaapi/gstvaapipixmap_x11.c delete mode 100644 gst-libs/gst/vaapi/gstvaapipixmap_x11.h diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index a1c82e68fb..50300b87da 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -38,10 +38,6 @@ # include #endif -#if HAVE_XRENDER -# include -#endif - #define DEBUG_VAAPI_DISPLAY 1 #include "gstvaapidebug.h" @@ -114,10 +110,6 @@ check_extensions (GstVaapiDisplayX11 * display) priv->use_xrandr = XRRQueryExtension (priv->x11_display, &evt_base, &err_base); #endif -#if HAVE_XRENDER - priv->has_xrender = XRenderQueryExtension (priv->x11_display, - &evt_base, &err_base); -#endif } static gboolean @@ -132,7 +124,6 @@ gst_vaapi_display_x11_bind_display (GstVaapiDisplay * base_display, priv->use_foreign_display = TRUE; check_extensions (display); - if (!set_display_name (display, XDisplayString (priv->x11_display))) return FALSE; return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index 9a26e8a40f..2f2cc7afe4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -66,17 +66,6 @@ typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class; #define GST_VAAPI_DISPLAY_XSCREEN(display) \ GST_VAAPI_DISPLAY_X11_PRIVATE(display)->x11_screen -/** - * GST_VAAPI_DISPLAY_HAS_XRENDER: - * @display: a #GstVaapiDisplay - * - * Macro that evaluates to the existence of the XRender extension on - * @display server. - */ -#undef GST_VAAPI_DISPLAY_HAS_XRENDER -#define GST_VAAPI_DISPLAY_HAS_XRENDER(display) \ - (GST_VAAPI_DISPLAY_X11_PRIVATE(display)->has_xrender) - struct _GstVaapiDisplayX11Private { gchar *display_name; @@ -85,7 +74,6 @@ struct _GstVaapiDisplayX11Private GArray *pixmap_formats; guint use_foreign_display:1; // Foreign native_display? guint use_xrandr:1; - guint has_xrender:1; // Has XRender extension? guint synchronous:1; }; diff --git a/gst-libs/gst/vaapi/gstvaapipixmap.c b/gst-libs/gst/vaapi/gstvaapipixmap.c deleted file mode 100644 index ebbfdd5bd4..0000000000 --- a/gst-libs/gst/vaapi/gstvaapipixmap.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * gstvaapipixmap.c - Pixmap abstraction - * - * Copyright (C) 2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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:gstvaapipixmap - * @short_description: Pixmap abstraction - */ - -#include "sysdeps.h" -#include "gstvaapipixmap.h" -#include "gstvaapipixmap_priv.h" -#include "gstvaapisurface_priv.h" - -#define DEBUG 1 -#include "gstvaapidebug.h" - -static inline GstVaapiPixmap * -gst_vaapi_pixmap_new_internal (const GstVaapiPixmapClass * pixmap_class, - GstVaapiDisplay * display) -{ - g_assert (pixmap_class->create != NULL); - g_assert (pixmap_class->render != NULL); - - return gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (pixmap_class), display); -} - -GstVaapiPixmap * -gst_vaapi_pixmap_new (const GstVaapiPixmapClass * pixmap_class, - GstVaapiDisplay * display, GstVideoFormat format, guint width, guint height) -{ - GstVaapiPixmap *pixmap; - - g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN && - format != GST_VIDEO_FORMAT_ENCODED, NULL); - g_return_val_if_fail (width > 0, NULL); - g_return_val_if_fail (height > 0, NULL); - - pixmap = gst_vaapi_pixmap_new_internal (pixmap_class, display); - if (!pixmap) - return NULL; - - pixmap->format = format; - pixmap->width = width; - pixmap->height = height; - if (!pixmap_class->create (pixmap)) - goto error; - return pixmap; - - /* ERRORS */ -error: - { - gst_vaapi_pixmap_unref (pixmap); - return NULL; - } -} - -GstVaapiPixmap * -gst_vaapi_pixmap_new_from_native (const GstVaapiPixmapClass * pixmap_class, - GstVaapiDisplay * display, gpointer native_pixmap) -{ - GstVaapiPixmap *pixmap; - - pixmap = gst_vaapi_pixmap_new_internal (pixmap_class, display); - if (!pixmap) - return NULL; - - GST_VAAPI_OBJECT_ID (pixmap) = GPOINTER_TO_SIZE (native_pixmap); - pixmap->use_foreign_pixmap = TRUE; - if (!pixmap_class->create (pixmap)) - goto error; - return pixmap; - - /* ERRORS */ -error: - { - gst_vaapi_pixmap_unref (pixmap); - return NULL; - } -} - -/** - * gst_vaapi_pixmap_ref: - * @pixmap: a #GstVaapiPixmap - * - * Atomically increases the reference count of the given @pixmap by one. - * - * Returns: The same @pixmap argument - */ -GstVaapiPixmap * -gst_vaapi_pixmap_ref (GstVaapiPixmap * pixmap) -{ - return gst_vaapi_object_ref (GST_VAAPI_OBJECT (pixmap)); -} - -/** - * gst_vaapi_pixmap_unref: - * @pixmap: a #GstVaapiPixmap - * - * Atomically decreases the reference count of the @pixmap by one. If - * the reference count reaches zero, the pixmap will be free'd. - */ -void -gst_vaapi_pixmap_unref (GstVaapiPixmap * pixmap) -{ - gst_vaapi_object_unref (GST_VAAPI_OBJECT (pixmap)); -} - -/** - * gst_vaapi_pixmap_replace: - * @old_pixmap_ptr: a pointer to a #GstVaapiPixmap - * @new_pixmap: a #GstVaapiPixmap - * - * Atomically replaces the pixmap pixmap held in @old_pixmap_ptr with - * @new_pixmap. This means that @old_pixmap_ptr shall reference a - * valid pixmap. However, @new_pixmap can be NULL. - */ -void -gst_vaapi_pixmap_replace (GstVaapiPixmap ** old_pixmap_ptr, - GstVaapiPixmap * new_pixmap) -{ - gst_vaapi_object_replace ((GstVaapiObject **) (old_pixmap_ptr), - GST_VAAPI_OBJECT (new_pixmap)); -} - -/** - * gst_vaapi_pixmap_get_display: - * @pixmap: a #GstVaapiPixmap - * - * Returns the #GstVaapiDisplay this @pixmap is bound to. - * - * Return value: the parent #GstVaapiDisplay object - */ -GstVaapiDisplay * -gst_vaapi_pixmap_get_display (GstVaapiPixmap * pixmap) -{ - g_return_val_if_fail (pixmap != NULL, NULL); - - return GST_VAAPI_OBJECT_DISPLAY (pixmap); -} - -/** - * gst_vaapi_pixmap_get_format: - * @pixmap: a #GstVaapiPixmap - * - * Retrieves the format of a #GstVaapiPixmap. - * - * Return value: the format of the @pixmap - */ -GstVideoFormat -gst_vaapi_pixmap_get_format (GstVaapiPixmap * pixmap) -{ - g_return_val_if_fail (pixmap != NULL, GST_VIDEO_FORMAT_UNKNOWN); - - return GST_VAAPI_PIXMAP_FORMAT (pixmap); -} - -/** - * gst_vaapi_pixmap_get_width: - * @pixmap: a #GstVaapiPixmap - * - * Retrieves the width of a #GstVaapiPixmap. - * - * Return value: the width of the @pixmap, in pixels - */ -guint -gst_vaapi_pixmap_get_width (GstVaapiPixmap * pixmap) -{ - g_return_val_if_fail (pixmap != NULL, 0); - - return GST_VAAPI_PIXMAP_WIDTH (pixmap); -} - -/** - * gst_vaapi_pixmap_get_height: - * @pixmap: a #GstVaapiPixmap - * - * Retrieves the height of a #GstVaapiPixmap - * - * Return value: the height of the @pixmap, in pixels - */ -guint -gst_vaapi_pixmap_get_height (GstVaapiPixmap * pixmap) -{ - g_return_val_if_fail (pixmap != NULL, 0); - - return GST_VAAPI_PIXMAP_HEIGHT (pixmap); -} - -/** - * gst_vaapi_pixmap_get_size: - * @pixmap: a #GstVaapiPixmap - * @width: return location for the width, or %NULL - * @height: return location for the height, or %NULL - * - * Retrieves the dimensions of a #GstVaapiPixmap. - */ -void -gst_vaapi_pixmap_get_size (GstVaapiPixmap * pixmap, guint * width, - guint * height) -{ - g_return_if_fail (pixmap != NULL); - - if (width) - *width = GST_VAAPI_PIXMAP_WIDTH (pixmap); - - if (height) - *height = GST_VAAPI_PIXMAP_HEIGHT (pixmap); -} - -/** - * gst_vaapi_pixmap_put_surface: - * @pixmap: a #GstVaapiPixmap - * @surface: a #GstVaapiSurface - * @crop_rect: the video cropping rectangle, or %NULL if the entire - * surface is to be used. - * @flags: postprocessing flags. See #GstVaapiSurfaceRenderFlags - * - * Renders the whole @surface, or a cropped region defined with - * @crop_rect, into the @pixmap, while scaling to fit the target - * pixmap. The @flags specify how de-interlacing (if needed), color - * space conversion, scaling and other postprocessing transformations - * are performed. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_pixmap_put_surface (GstVaapiPixmap * pixmap, - GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) -{ - GstVaapiRectangle src_rect; - - g_return_val_if_fail (pixmap != NULL, FALSE); - g_return_val_if_fail (surface != NULL, FALSE); - - if (!crop_rect) { - src_rect.x = 0; - src_rect.y = 0; - src_rect.width = GST_VAAPI_SURFACE_WIDTH (surface); - src_rect.height = GST_VAAPI_SURFACE_HEIGHT (surface); - crop_rect = &src_rect; - } - return GST_VAAPI_PIXMAP_GET_CLASS (pixmap)->render (pixmap, surface, - crop_rect, flags); -} diff --git a/gst-libs/gst/vaapi/gstvaapipixmap.h b/gst-libs/gst/vaapi/gstvaapipixmap.h deleted file mode 100644 index 037a72f3ad..0000000000 --- a/gst-libs/gst/vaapi/gstvaapipixmap.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * gstvaapipixmap.h - Pixmap abstraction - * - * Copyright (C) 2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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_PIXMAP_H -#define GST_VAAPI_PIXMAP_H - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_VAAPI_PIXMAP(obj) \ - ((GstVaapiPixmap *)(obj)) - -typedef struct _GstVaapiPixmap GstVaapiPixmap; -typedef struct _GstVaapiPixmapClass GstVaapiPixmapClass; - -/** - * GST_VAAPI_PIXMAP_FORMAT: - * @pixmap: a #GstVaapiPixmap - * - * Macro that evaluates to the format in pixels of the @pixmap. - */ -#define GST_VAAPI_PIXMAP_FORMAT(pixmap) \ - gst_vaapi_pixmap_get_format(GST_VAAPI_PIXMAP(pixmap)) - -/** - * GST_VAAPI_PIXMAP_WIDTH: - * @pixmap: a #GstVaapiPixmap - * - * Macro that evaluates to the width in pixels of the @pixmap. - */ -#define GST_VAAPI_PIXMAP_WIDTH(pixmap) \ - gst_vaapi_pixmap_get_width(GST_VAAPI_PIXMAP(pixmap)) - -/** - * GST_VAAPI_PIXMAP_HEIGHT: - * @pixmap: a #GstVaapiPixmap - * - * Macro that evaluates to the height in pixels of the @pixmap. - */ -#define GST_VAAPI_PIXMAP_HEIGHT(pixmap) \ - gst_vaapi_pixmap_get_height(GST_VAAPI_PIXMAP(pixmap)) - -GstVaapiPixmap * -gst_vaapi_pixmap_ref(GstVaapiPixmap *pixmap); - -void -gst_vaapi_pixmap_unref(GstVaapiPixmap *pixmap); - -void -gst_vaapi_pixmap_replace(GstVaapiPixmap **old_pixmap_ptr, - GstVaapiPixmap *new_pixmap); - -GstVaapiDisplay * -gst_vaapi_pixmap_get_display(GstVaapiPixmap *pixmap); - -GstVideoFormat -gst_vaapi_pixmap_get_format(GstVaapiPixmap *pixmap); - -guint -gst_vaapi_pixmap_get_width(GstVaapiPixmap *pixmap); - -guint -gst_vaapi_pixmap_get_height(GstVaapiPixmap *pixmap); - -void -gst_vaapi_pixmap_get_size(GstVaapiPixmap *pixmap, guint *width, guint *height); - -gboolean -gst_vaapi_pixmap_put_surface(GstVaapiPixmap *pixmap, GstVaapiSurface *surface, - const GstVaapiRectangle *crop_rect, guint flags); - -G_END_DECLS - -#endif /* GST_VAAPI_PIXMAP_H */ diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_priv.h b/gst-libs/gst/vaapi/gstvaapipixmap_priv.h deleted file mode 100644 index a99d91f5c2..0000000000 --- a/gst-libs/gst/vaapi/gstvaapipixmap_priv.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * gstvaapipixmap_priv.h - Pixmap abstraction (private definitions) - * - * Copyright (C) 2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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_PIXMAP_PRIV_H -#define GST_VAAPI_PIXMAP_PRIV_H - -#include "gstvaapiobject_priv.h" - -G_BEGIN_DECLS - -#define GST_VAAPI_PIXMAP_CLASS(klass) \ - ((GstVaapiPixmapClass *)(klass)) - -#define GST_VAAPI_PIXMAP_GET_CLASS(obj) \ - GST_VAAPI_PIXMAP_CLASS(GST_VAAPI_OBJECT_GET_CLASS(obj)) - -/** - * GST_VAAPI_PIXMAP_FORMAT: - * @pixmap: a #GstVaapiPixmap - * - * Macro that evaluates to the format in pixels of the @pixmap. - */ -#undef GST_VAAPI_PIXMAP_FORMAT -#define GST_VAAPI_PIXMAP_FORMAT(pixmap) \ - (GST_VAAPI_PIXMAP(pixmap)->format) - -/** - * GST_VAAPI_PIXMAP_WIDTH: - * @pixmap: a #GstVaapiPixmap - * - * Macro that evaluates to the width in pixels of the @pixmap. - */ -#undef GST_VAAPI_PIXMAP_WIDTH -#define GST_VAAPI_PIXMAP_WIDTH(pixmap) \ - (GST_VAAPI_PIXMAP(pixmap)->width) - -/** - * GST_VAAPI_PIXMAP_HEIGHT: - * @pixmap: a #GstVaapiPixmap - * - * Macro that evaluates to the height in pixels of the @pixmap. - */ -#undef GST_VAAPI_PIXMAP_HEIGHT -#define GST_VAAPI_PIXMAP_HEIGHT(pixmap) \ - (GST_VAAPI_PIXMAP(pixmap)->height) - -/* GstVaapiPixmapClass hooks */ -typedef gboolean (*GstVaapiPixmapCreateFunc) (GstVaapiPixmap *pixmap); -typedef gboolean (*GstVaapiPixmapRenderFunc) (GstVaapiPixmap *pixmap, - GstVaapiSurface *surface, const GstVaapiRectangle *crop_rect, guint flags); - -/** - * GstVaapiPixmap: - * - * Base class for system-dependent pixmaps. - */ -struct _GstVaapiPixmap { - /*< private >*/ - GstVaapiObject parent_instance; - - /*< protected >*/ - GstVideoFormat format; - guint width; - guint height; - guint use_foreign_pixmap : 1; -}; - -/** - * GstVaapiPixmapClass: - * @create: virtual function to create a pixmap with width and height - * @render: virtual function to render a #GstVaapiSurface into a pixmap - * - * Base class for system-dependent pixmaps. - */ -struct _GstVaapiPixmapClass { - /*< private >*/ - GstVaapiObjectClass parent_class; - - /*< protected >*/ - GstVaapiPixmapCreateFunc create; - GstVaapiPixmapRenderFunc render; -}; - -GstVaapiPixmap * -gst_vaapi_pixmap_new(const GstVaapiPixmapClass *pixmap_class, - GstVaapiDisplay *display, GstVideoFormat format, guint width, guint height); - -GstVaapiPixmap * -gst_vaapi_pixmap_new_from_native(const GstVaapiPixmapClass *pixmap_class, - GstVaapiDisplay *display, gpointer native_pixmap); - -G_END_DECLS - -#endif /* GST_VAAPI_PIXMAP_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c b/gst-libs/gst/vaapi/gstvaapipixmap_x11.c deleted file mode 100644 index 43a1710def..0000000000 --- a/gst-libs/gst/vaapi/gstvaapipixmap_x11.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * gstvaapipixmap_x11.c - X11 pixmap abstraction - * - * Copyright (C) 2013-2014 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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:gstvaapipixmap_x11 - * @short_description: X11 pixmap abstraction - */ - -#include "sysdeps.h" -#include "gstvaapicompat.h" -#include "gstvaapipixmap_x11.h" -#include "gstvaapipixmap_priv.h" -#include "gstvaapidisplay_x11.h" -#include "gstvaapidisplay_x11_priv.h" -#include "gstvaapiutils.h" -#include "gstvaapiutils_x11.h" -#include "gstvaapisurface_priv.h" - -#define DEBUG 1 -#include "gstvaapidebug.h" - -typedef struct _GstVaapiPixmapX11Class GstVaapiPixmapX11Class; - -struct _GstVaapiPixmapX11 -{ - GstVaapiPixmap parent_instance; -}; - -struct _GstVaapiPixmapX11Class -{ - GstVaapiPixmapClass parent_class; -}; - -static gboolean -gst_vaapi_pixmap_x11_create_from_xid (GstVaapiPixmap * pixmap, Pixmap xid) -{ - guint depth; - gboolean success; - - if (!xid) - return FALSE; - - GST_VAAPI_OBJECT_LOCK_DISPLAY (pixmap); - success = x11_get_geometry (GST_VAAPI_OBJECT_NATIVE_DISPLAY (pixmap), xid, - NULL, NULL, &pixmap->width, &pixmap->height, &depth); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (pixmap); - if (!success) - return FALSE; - - pixmap->format = - gst_vaapi_display_x11_get_pixmap_format (GST_VAAPI_OBJECT_DISPLAY_X11 - (pixmap), depth); - if (pixmap->format == GST_VIDEO_FORMAT_UNKNOWN) - return FALSE; - return TRUE; -} - -static gboolean -gst_vaapi_pixmap_x11_create (GstVaapiPixmap * pixmap) -{ - GstVaapiDisplayX11 *const display = - GST_VAAPI_DISPLAY_X11 (GST_VAAPI_OBJECT_DISPLAY (pixmap)); - Display *const dpy = GST_VAAPI_DISPLAY_NATIVE (display); - Window rootwin; - Pixmap xid; - guint depth; - - if (pixmap->use_foreign_pixmap) - return gst_vaapi_pixmap_x11_create_from_xid (pixmap, - GST_VAAPI_OBJECT_ID (pixmap)); - - depth = gst_vaapi_display_x11_get_pixmap_depth (display, pixmap->format); - if (!depth) - return FALSE; - - GST_VAAPI_OBJECT_LOCK_DISPLAY (pixmap); - rootwin = RootWindow (dpy, DefaultScreen (dpy)); - xid = XCreatePixmap (dpy, rootwin, pixmap->width, pixmap->height, depth); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (pixmap); - - GST_DEBUG ("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (xid)); - GST_VAAPI_OBJECT_ID (pixmap) = xid; - return xid != None; -} - -static void -gst_vaapi_pixmap_x11_destroy (GstVaapiPixmap * pixmap) -{ - const Pixmap xid = GST_VAAPI_OBJECT_ID (pixmap); - - if (xid) { - if (!pixmap->use_foreign_pixmap) { - GST_VAAPI_OBJECT_LOCK_DISPLAY (pixmap); - XFreePixmap (GST_VAAPI_OBJECT_NATIVE_DISPLAY (pixmap), xid); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (pixmap); - } - GST_VAAPI_OBJECT_ID (pixmap) = None; - } -} - -static gboolean -gst_vaapi_pixmap_x11_render (GstVaapiPixmap * pixmap, GstVaapiSurface * surface, - const GstVaapiRectangle * crop_rect, guint flags) -{ - VASurfaceID surface_id; - VAStatus status; - - surface_id = GST_VAAPI_SURFACE_ID (surface); - if (surface_id == VA_INVALID_ID) - return FALSE; - - GST_VAAPI_OBJECT_LOCK_DISPLAY (pixmap); - status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (pixmap), - surface_id, - GST_VAAPI_OBJECT_ID (pixmap), - crop_rect->x, crop_rect->y, - crop_rect->width, crop_rect->height, - 0, 0, - GST_VAAPI_PIXMAP_WIDTH (pixmap), - GST_VAAPI_PIXMAP_HEIGHT (pixmap), - NULL, 0, from_GstVaapiSurfaceRenderFlags (flags) - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (pixmap); - if (!vaapi_check_status (status, "vaPutSurface() [pixmap]")) - return FALSE; - return TRUE; -} - -void -gst_vaapi_pixmap_x11_class_init (GstVaapiPixmapX11Class * klass) -{ - GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); - GstVaapiPixmapClass *const pixmap_class = GST_VAAPI_PIXMAP_CLASS (klass); - - object_class->finalize = (GstVaapiObjectFinalizeFunc) - gst_vaapi_pixmap_x11_destroy; - - pixmap_class->create = gst_vaapi_pixmap_x11_create; - pixmap_class->render = gst_vaapi_pixmap_x11_render; -} - -#define gst_vaapi_pixmap_x11_finalize \ - gst_vaapi_pixmap_x11_destroy - -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiPixmapX11, - gst_vaapi_pixmap_x11, gst_vaapi_pixmap_x11_class_init (&g_class)) - -/** - * gst_vaapi_pixmap_x11_new: - * @display: a #GstVaapiDisplay - * @format: the requested pixmap format - * @width: the requested pixmap width, in pixels - * @height: the requested windo height, in pixels - * - * Creates a pixmap with the specified @format, @width and - * @height. The pixmap will be attached to the @display. - * - * Return value: the newly allocated #GstVaapiPixmap object - */ - GstVaapiPixmap *gst_vaapi_pixmap_x11_new (GstVaapiDisplay * display, - GstVideoFormat format, guint width, guint height) -{ - GST_DEBUG ("new pixmap, format %s, size %ux%u", - gst_vaapi_video_format_to_string (format), width, height); - - g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); - - return - gst_vaapi_pixmap_new (GST_VAAPI_PIXMAP_CLASS (gst_vaapi_pixmap_x11_class - ()), display, format, width, height); -} - -/** - * gst_vaapi_pixmap_x11_new_with_xid: - * @display: a #GstVaapiDisplay - * @xid: an X11 #Pixmap id - * - * Creates a #GstVaapiPixmap using the X11 Pixmap @xid. The caller - * still owns the pixmap and must call XFreePixmap() when all - * #GstVaapiPixmap references are released. Doing so too early can - * yield undefined behaviour. - * - * Return value: the newly allocated #GstVaapiPixmap object - */ -GstVaapiPixmap * -gst_vaapi_pixmap_x11_new_with_xid (GstVaapiDisplay * display, Pixmap xid) -{ - GST_DEBUG ("new pixmap from xid 0x%08x", (guint) xid); - - g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); - g_return_val_if_fail (xid != None, NULL); - - return - gst_vaapi_pixmap_new_from_native (GST_VAAPI_PIXMAP_CLASS - (gst_vaapi_pixmap_x11_class ()), display, GSIZE_TO_POINTER (xid)); -} - -/** - * gst_vaapi_pixmap_x11_get_xid: - * @pixmap: a #GstVaapiPixmapX11 - * - * Returns the underlying X11 Pixmap that was created by - * gst_vaapi_pixmap_x11_new() or that was bound with - * gst_vaapi_pixmap_x11_new_with_xid(). - * - * Return value: the underlying X11 Pixmap bound to @pixmap. - */ -Pixmap -gst_vaapi_pixmap_x11_get_xid (GstVaapiPixmapX11 * pixmap) -{ - g_return_val_if_fail (pixmap != NULL, None); - - return GST_VAAPI_OBJECT_ID (pixmap); -} - -/** - * gst_vaapi_pixmap_x11_is_foreign_xid: - * @pixmap: a #GstVaapiPixmapX11 - * - * Checks whether the @pixmap XID was created by gst_vaapi_pixmap_x11_new() - * or was bound with gst_vaapi_pixmap_x11_new_with_xid(). - * - * Return value: %TRUE if the underlying X pixmap is owned by the - * caller (foreign pixmap) - */ -gboolean -gst_vaapi_pixmap_x11_is_foreign_xid (GstVaapiPixmapX11 * pixmap) -{ - g_return_val_if_fail (pixmap != NULL, FALSE); - - return GST_VAAPI_PIXMAP (pixmap)->use_foreign_pixmap; -} diff --git a/gst-libs/gst/vaapi/gstvaapipixmap_x11.h b/gst-libs/gst/vaapi/gstvaapipixmap_x11.h deleted file mode 100644 index 814823b16c..0000000000 --- a/gst-libs/gst/vaapi/gstvaapipixmap_x11.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * gstvaapipixmap_x11.h - X11 pixmap abstraction - * - * Copyright (C) 2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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_PIXMAP_X11_H -#define GST_VAAPI_PIXMAP_X11_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_VAAPI_PIXMAP_X11(obj) \ - ((GstVaapiPixmapX11 *)(obj)) - -/** - * GST_VAAPI_PIXMAP_XPIXMAP: - * @pixmap: a #GstVaapiPixmap - * - * Macro that evaluates to the underlying X11 #Pixmap of @pixmap - */ -#define GST_VAAPI_PIXMAP_XPIXMAP(pixmap) \ - gst_vaapi_pixmap_x11_get_xid(GST_VAAPI_PIXMAP_X11(pixmap)) - -typedef struct _GstVaapiPixmapX11 GstVaapiPixmapX11; - -GstVaapiPixmap * -gst_vaapi_pixmap_x11_new(GstVaapiDisplay *display, GstVideoFormat format, - guint width, guint height); - -GstVaapiPixmap * -gst_vaapi_pixmap_x11_new_with_xid(GstVaapiDisplay *display, Pixmap xid); - -Pixmap -gst_vaapi_pixmap_x11_get_xid(GstVaapiPixmapX11 *pixmap); - -gboolean -gst_vaapi_pixmap_x11_is_foreign_xid(GstVaapiPixmapX11 *pixmap); - -G_END_DECLS - -#endif /* GST_VAAPI_PIXMAP_X11_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 1af8037770..35ba42cf7f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -602,60 +602,6 @@ gst_vaapi_window_put_surface (GstVaapiWindow * window, return klass->render (window, surface, src_rect, dst_rect, flags); } -static inline void -get_pixmap_rect (GstVaapiPixmap * pixmap, GstVaapiRectangle * rect) -{ - guint width, height; - - gst_vaapi_pixmap_get_size (pixmap, &width, &height); - rect->x = 0; - rect->y = 0; - rect->width = width; - rect->height = height; -} - -/** - * gst_vaapi_window_put_pixmap: - * @window: a #GstVaapiWindow - * @pixmap: a #GstVaapiPixmap - * @src_rect: the sub-rectangle of the source pixmap to - * extract and process. If %NULL, the entire pixmap will be used. - * @dst_rect: the sub-rectangle of the destination - * window into which the pixmap is rendered. If %NULL, the entire - * window will be used. - * - * Renders the @pixmap region specified by @src_rect into the @window - * region specified by @dst_rect. - * - * Return value: %TRUE on success - */ -gboolean -gst_vaapi_window_put_pixmap (GstVaapiWindow * window, - GstVaapiPixmap * pixmap, - const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) -{ - const GstVaapiWindowClass *klass; - GstVaapiRectangle src_rect_default, dst_rect_default; - - g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), FALSE); - g_return_val_if_fail (pixmap != NULL, FALSE); - - klass = GST_VAAPI_WINDOW_GET_CLASS (window); - if (!klass->render_pixmap) - return FALSE; - - if (!src_rect) { - src_rect = &src_rect_default; - get_pixmap_rect (pixmap, &src_rect_default); - } - - if (!dst_rect) { - dst_rect = &dst_rect_default; - get_window_rect (window, &dst_rect_default); - } - return klass->render_pixmap (window, pixmap, src_rect, dst_rect); -} - /** * gst_vaapi_window_reconfigure: * @window: a #GstVaapiWindow diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 0796d20ddf..a53850107f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -29,7 +29,6 @@ #include #include #include -#include G_BEGIN_DECLS @@ -91,10 +90,6 @@ gst_vaapi_window_put_surface (GstVaapiWindow * window, GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect, guint flags); -gboolean -gst_vaapi_window_put_pixmap (GstVaapiWindow * window, GstVaapiPixmap * pixmap, - const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect); - void gst_vaapi_window_reconfigure (GstVaapiWindow * window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c index 45f3869160..1261fc1c2c 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c @@ -281,8 +281,11 @@ gst_vaapi_window_egl_finalize (GObject * object) { GstVaapiWindowEGL *const window = GST_VAAPI_WINDOW_EGL (object); - egl_context_run (window->egl_window->context, - (EglContextRunFunc) do_destroy_objects, window); + if (window->egl_window) { + egl_context_run (window->egl_window->context, + (EglContextRunFunc) do_destroy_objects, window); + } + gst_vaapi_window_replace (&window->window, NULL); gst_vaapi_texture_replace (&window->texture, NULL); @@ -505,20 +508,6 @@ gst_vaapi_window_egl_render (GstVaapiWindow * window, GstVaapiSurface * surface, (EglContextRunFunc) do_upload_surface, &args) && args.success; } -static gboolean -gst_vaapi_window_egl_render_pixmap (GstVaapiWindow * window, - GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect, - const GstVaapiRectangle * dst_rect) -{ - const GstVaapiWindowClass *const klass = - GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window)); - - if (!klass->render_pixmap) - return FALSE; - return klass->render_pixmap (GST_VAAPI_WINDOW_EGL_GET_PROXY (window), pixmap, - src_rect, dst_rect); -} - static void gst_vaapi_window_egl_class_init (GstVaapiWindowEGLClass * klass) { @@ -534,7 +523,6 @@ gst_vaapi_window_egl_class_init (GstVaapiWindowEGLClass * klass) window_class->set_fullscreen = gst_vaapi_window_egl_set_fullscreen; window_class->resize = gst_vaapi_window_egl_resize; window_class->render = gst_vaapi_window_egl_render; - window_class->render_pixmap = gst_vaapi_window_egl_render_pixmap; } static void diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index cd21d00cf4..09be19c3d4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -123,8 +123,6 @@ struct _GstVaapiWindowClass gboolean (*render) (GstVaapiWindow * window, GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect, guint flags); - gboolean (*render_pixmap) (GstVaapiWindow * window, GstVaapiPixmap * pixmap, - const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect); guintptr (*get_visual_id) (GstVaapiWindow * window); guintptr (*get_colormap) (GstVaapiWindow * window); gboolean (*unblock) (GstVaapiWindow * window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index bf0b65b323..38fed7a12f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -32,8 +32,6 @@ #include "gstvaapicompat.h" #include "gstvaapiwindow_x11.h" #include "gstvaapiwindow_x11_priv.h" -#include "gstvaapipixmap_x11.h" -#include "gstvaapipixmap_priv.h" #include "gstvaapidisplay_x11.h" #include "gstvaapidisplay_x11_priv.h" #include "gstvaapisurface_priv.h" @@ -232,9 +230,6 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, "_NET_WM_STATE_FULLSCREEN", }; - priv->has_xrender = - GST_VAAPI_DISPLAY_HAS_XRENDER (GST_VAAPI_WINDOW_DISPLAY (window)); - if (window->use_foreign_window && xid) { GST_VAAPI_WINDOW_LOCK_DISPLAY (window); XGetWindowAttributes (dpy, xid, &wattr); @@ -291,17 +286,6 @@ gst_vaapi_window_x11_finalize (GObject * object) Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); const Window xid = GST_VAAPI_WINDOW_ID (window); -#if HAVE_XRENDER - GstVaapiWindowX11Private *const priv = - GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - if (priv->picture) { - GST_VAAPI_WINDOW_LOCK_DISPLAY (window); - XRenderFreePicture (dpy, priv->picture); - GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); - priv->picture = None; - } -#endif - if (xid) { if (!window->use_foreign_window) { GST_VAAPI_WINDOW_LOCK_DISPLAY (window); @@ -500,107 +484,6 @@ conversion: return ret; } -static gboolean -gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window, - GstVaapiPixmap * pixmap, - const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) -{ -#if HAVE_XRENDER - GstVaapiWindowX11Private *const priv = - GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); - const Window win = GST_VAAPI_WINDOW_ID (window); - const Pixmap pix = GST_VAAPI_OBJECT_ID (pixmap); - Picture picture; - XRenderPictFormat *pic_fmt; - XWindowAttributes wattr; - int fmt, op; - gboolean success = FALSE; - - /* Ensure Picture for window is created */ - if (!priv->picture) { - GST_VAAPI_WINDOW_LOCK_DISPLAY (window); - XGetWindowAttributes (dpy, win, &wattr); - pic_fmt = XRenderFindVisualFormat (dpy, wattr.visual); - if (pic_fmt) - priv->picture = XRenderCreatePicture (dpy, win, pic_fmt, 0, NULL); - GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); - if (!priv->picture) - return FALSE; - } - - /* Check pixmap format */ - switch (GST_VAAPI_PIXMAP_FORMAT (pixmap)) { - case GST_VIDEO_FORMAT_xRGB: - fmt = PictStandardRGB24; - op = PictOpSrc; - goto get_pic_fmt; - case GST_VIDEO_FORMAT_ARGB: - fmt = PictStandardARGB32; - op = PictOpOver; - get_pic_fmt: - GST_VAAPI_WINDOW_LOCK_DISPLAY (window); - pic_fmt = XRenderFindStandardFormat (dpy, fmt); - GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); - break; - default: - pic_fmt = NULL; - break; - } - if (!pic_fmt) - return FALSE; - - GST_VAAPI_WINDOW_LOCK_DISPLAY (window); - do { - const double sx = (double) src_rect->width / dst_rect->width; - const double sy = (double) src_rect->height / dst_rect->height; - XTransform xform; - - picture = XRenderCreatePicture (dpy, pix, pic_fmt, 0, NULL); - if (!picture) - break; - - xform.matrix[0][0] = XDoubleToFixed (sx); - xform.matrix[0][1] = XDoubleToFixed (0.0); - xform.matrix[0][2] = XDoubleToFixed (src_rect->x); - xform.matrix[1][0] = XDoubleToFixed (0.0); - xform.matrix[1][1] = XDoubleToFixed (sy); - xform.matrix[1][2] = XDoubleToFixed (src_rect->y); - xform.matrix[2][0] = XDoubleToFixed (0.0); - xform.matrix[2][1] = XDoubleToFixed (0.0); - xform.matrix[2][2] = XDoubleToFixed (1.0); - XRenderSetPictureTransform (dpy, picture, &xform); - - XRenderComposite (dpy, op, picture, None, priv->picture, - 0, 0, 0, 0, dst_rect->x, dst_rect->y, - dst_rect->width, dst_rect->height); - XSync (dpy, False); - success = TRUE; - } while (0); - if (picture) - XRenderFreePicture (dpy, picture); - GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); - return success; -#endif - return FALSE; -} - -static gboolean -gst_vaapi_window_x11_render_pixmap (GstVaapiWindow * window, - GstVaapiPixmap * pixmap, - const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) -{ - GstVaapiWindowX11Private *const priv = - GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); - - if (priv->has_xrender) - return gst_vaapi_window_x11_render_pixmap_xrender (window, pixmap, - src_rect, dst_rect); - - /* XXX: only X RENDER extension is supported for now */ - return FALSE; -} - static void gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass) { @@ -616,7 +499,6 @@ gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass) window_class->set_fullscreen = gst_vaapi_window_x11_set_fullscreen; window_class->resize = gst_vaapi_window_x11_resize; window_class->render = gst_vaapi_window_x11_render; - window_class->render_pixmap = gst_vaapi_window_x11_render_pixmap; } static void diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index 06ce2e5858..751647fe7c 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -47,12 +47,8 @@ struct _GstVaapiWindowX11Private { Atom atom_NET_WM_STATE; Atom atom_NET_WM_STATE_FULLSCREEN; -#if HAVE_XRENDER - Picture picture; -#endif guint is_mapped:1; guint fullscreen_on_map:1; - guint has_xrender:1; gboolean need_vpp; }; diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 2630acd6ca..8a8d321a34 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -22,7 +22,6 @@ gstlibvaapi_sources = [ 'gstvaapiminiobject.c', 'gstvaapiobject.c', 'gstvaapiparser_frame.c', - 'gstvaapipixmap.c', 'gstvaapiprofile.c', 'gstvaapiprofilecaps.c', 'gstvaapisubpicture.c', @@ -61,7 +60,6 @@ gstlibvaapi_headers = [ 'gstvaapiimage.h', 'gstvaapiimagepool.h', 'gstvaapiobject.h', - 'gstvaapipixmap.h', 'gstvaapiprofile.h', 'gstvaapiprofilecaps.h', 'gstvaapisubpicture.h', @@ -126,13 +124,11 @@ endif if USE_X11 gstlibvaapi_sources += [ 'gstvaapidisplay_x11.c', - 'gstvaapipixmap_x11.c', 'gstvaapiutils_x11.c', 'gstvaapiwindow_x11.c', ] gstlibvaapi_headers += [ 'gstvaapidisplay_x11.h', - 'gstvaapipixmap_x11.h', 'gstvaapiwindow_x11.h', ] endif @@ -212,7 +208,7 @@ if USE_WAYLAND gstlibvaapi_deps += [libva_wayland_dep, wayland_client_dep, wayland_protocols_dep] endif if USE_X11 - gstlibvaapi_deps += [libva_x11_dep, x11_dep, xrandr_dep, xrender_dep] + gstlibvaapi_deps += [libva_x11_dep, x11_dep, xrandr_dep] endif gstlibvaapi = static_library('gstlibvaapi-@0@'.format(api_version), diff --git a/meson.build b/meson.build index 3a6e93406b..c652ce8cea 100644 --- a/meson.build +++ b/meson.build @@ -90,7 +90,6 @@ wayland_protocols_dep = dependency('wayland-protocols', version: '>= 1.15', requ wayland_scanner_bin = find_program('wayland-scanner', required: false) x11_dep = dependency('x11', required: false) xrandr_dep = dependency('xrandr', required: false) -xrender_dep = dependency('xrender', required: false) # some of the examples can use GTK+-3 gtk_dep = dependency('gtk+-3.0', version : '>= 3.10', required : get_option('examples')) @@ -144,7 +143,6 @@ cdata.set10('USE_WAYLAND', USE_WAYLAND) cdata.set10('USE_X11', USE_X11) cdata.set10('HAVE_XKBLIB', cc.has_header('X11/XKBlib.h', dependencies: x11_dep)) cdata.set10('HAVE_XRANDR', xrandr_dep.found()) -cdata.set10('HAVE_XRENDER', xrender_dep.found()) cdata.set10('USE_GST_GL_HELPERS', gstgl_dep.found()) cdata.set('USE_GLES_VERSION_MASK', GLES_VERSION_MASK) diff --git a/tests/internal/output.c b/tests/internal/output.c index b100f0324f..2182d5ab0d 100644 --- a/tests/internal/output.c +++ b/tests/internal/output.c @@ -29,7 +29,6 @@ #if USE_X11 # include # include -# include #endif #if USE_GLX # include @@ -56,14 +55,12 @@ static const VideoOutputInfo g_video_outputs[] = { #if USE_X11 {"x11", gst_vaapi_display_x11_new, - gst_vaapi_window_x11_new, - gst_vaapi_pixmap_x11_new}, + gst_vaapi_window_x11_new}, #endif #if USE_GLX {"glx", gst_vaapi_display_glx_new, - gst_vaapi_window_glx_new, - gst_vaapi_pixmap_x11_new}, + gst_vaapi_window_glx_new}, #endif #if USE_DRM {"drm", @@ -228,12 +225,3 @@ video_output_create_window (GstVaapiDisplay * display, guint width, gst_vaapi_window_set_fullscreen (window, TRUE); return window; } - -GstVaapiPixmap * -video_output_create_pixmap (GstVaapiDisplay * display, GstVideoFormat format, - guint width, guint height) -{ - if (!g_video_output || !g_video_output->create_pixmap) - return NULL; - return g_video_output->create_pixmap (display, format, width, height); -} diff --git a/tests/internal/output.h b/tests/internal/output.h index 7d109f24f0..69299157f5 100644 --- a/tests/internal/output.h +++ b/tests/internal/output.h @@ -26,21 +26,16 @@ #include #include #include -#include typedef GstVaapiDisplay *(*CreateDisplayFunc)(const gchar *display_name); typedef GstVaapiWindow *(*CreateWindowFunc)(GstVaapiDisplay *display, guint width, guint height); -typedef GstVaapiPixmap *(*CreatePixmapFunc)(GstVaapiDisplay *display, - GstVideoFormat format, guint width, guint height); - typedef struct _VideoOutputInfo VideoOutputInfo; struct _VideoOutputInfo { const gchar *name; CreateDisplayFunc create_display; CreateWindowFunc create_window; - CreatePixmapFunc create_pixmap; }; gboolean @@ -58,8 +53,4 @@ video_output_create_display(const gchar *display_name); GstVaapiWindow * video_output_create_window(GstVaapiDisplay *display, guint width, guint height); -GstVaapiPixmap * -video_output_create_pixmap(GstVaapiDisplay *display, GstVideoFormat format, - guint width, guint height); - #endif /* OUTPUT_H */ diff --git a/tests/internal/simple-decoder.c b/tests/internal/simple-decoder.c index 34f17d5be3..f6b1499886 100644 --- a/tests/internal/simple-decoder.c +++ b/tests/internal/simple-decoder.c @@ -35,12 +35,10 @@ #include #include #include -#include #include "codec.h" #include "output.h" static gchar *g_codec_str; -static gboolean g_use_pixmap; static gboolean g_benchmark; static GOptionEntry g_options[] = { @@ -48,10 +46,6 @@ static GOptionEntry g_options[] = { 0, G_OPTION_ARG_STRING, &g_codec_str, "suggested codec", NULL}, - {"pixmap", 0, - 0, - G_OPTION_ARG_NONE, &g_use_pixmap, - "use render-to-pixmap", NULL}, {"benchmark", 0, 0, G_OPTION_ARG_NONE, &g_benchmark, @@ -100,10 +94,6 @@ typedef struct guint32 frame_duration; guint surface_width; guint surface_height; - GstVaapiPixmap *pixmaps[2]; - guint pixmap_id; - guint pixmap_width; - guint pixmap_height; GstVaapiWindow *window; guint window_width; guint window_height; @@ -434,43 +424,6 @@ ensure_window_size (App * app, GstVaapiSurface * surface) &app->window_width, &app->window_height); } -static gboolean -ensure_pixmaps (App * app, GstVaapiSurface * surface, - const GstVaapiRectangle * crop_rect) -{ - GstVaapiPixmap *pixmaps[G_N_ELEMENTS (app->pixmaps)]; - guint num_pixmaps, i, width, height; - gboolean success = FALSE; - - if (crop_rect) { - width = crop_rect->width; - height = crop_rect->height; - } else - gst_vaapi_surface_get_size (surface, &width, &height); - if (app->pixmap_width == width && app->pixmap_height == height) - return TRUE; - - for (i = 0, num_pixmaps = 0; i < G_N_ELEMENTS (pixmaps); i++) { - GstVaapiPixmap *const pixmap = - video_output_create_pixmap (app->display, GST_VIDEO_FORMAT_xRGB, - width, height); - if (!pixmap) - goto end; - pixmaps[num_pixmaps++] = pixmap; - } - - for (i = 0; i < num_pixmaps; i++) - gst_vaapi_pixmap_replace (&app->pixmaps[i], pixmaps[i]); - app->pixmap_width = width; - app->pixmap_height = height; - success = TRUE; - -end: - for (i = 0; i < num_pixmaps; i++) - gst_vaapi_pixmap_replace (&pixmaps[i], NULL); - return success; -} - static inline void renderer_wait_until (App * app, GstClockTime pts) { @@ -500,8 +453,6 @@ renderer_process (App * app, RenderFrame * rfp) ensure_window_size (app, surface); crop_rect = gst_vaapi_surface_proxy_get_crop_rect (rfp->proxy); - if (g_use_pixmap && !ensure_pixmaps (app, surface, crop_rect)) - SEND_ERROR ("failed to create intermediate pixmaps"); if (!gst_vaapi_surface_sync (surface)) SEND_ERROR ("failed to sync decoded surface"); @@ -509,19 +460,7 @@ renderer_process (App * app, RenderFrame * rfp) if (G_LIKELY (!g_benchmark)) renderer_wait_until (app, rfp->pts); - if (G_UNLIKELY (g_use_pixmap)) { - GstVaapiPixmap *const pixmap = app->pixmaps[app->pixmap_id]; - - if (!gst_vaapi_pixmap_put_surface (pixmap, surface, crop_rect, - GST_VAAPI_PICTURE_STRUCTURE_FRAME)) - SEND_ERROR ("failed to render to pixmap"); - - if (!gst_vaapi_window_put_pixmap (app->window, pixmap, NULL, NULL)) - SEND_ERROR ("failed to render surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS (pixmap)); - - app->pixmap_id = (app->pixmap_id + 1) % G_N_ELEMENTS (app->pixmaps); - } else if (!gst_vaapi_window_put_surface (app->window, surface, + if (!gst_vaapi_window_put_surface (app->window, surface, crop_rect, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) SEND_ERROR ("failed to render surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (gst_vaapi_surface_get_id (surface))); @@ -594,8 +533,6 @@ stop_renderer (App * app) static void app_free (App * app) { - guint i; - if (!app) return; @@ -605,8 +542,6 @@ app_free (App * app) } g_free (app->file_name); - for (i = 0; i < G_N_ELEMENTS (app->pixmaps); i++) - gst_vaapi_pixmap_replace (&app->pixmaps[i], NULL); gst_vaapi_decoder_replace (&app->decoder, NULL); gst_vaapi_window_replace (&app->window, NULL); gst_vaapi_display_replace (&app->display, NULL); diff --git a/tests/internal/test-decode.c b/tests/internal/test-decode.c index ef16aa157c..3940e716aa 100644 --- a/tests/internal/test-decode.c +++ b/tests/internal/test-decode.c @@ -38,17 +38,12 @@ pause (void) } static gchar *g_codec_str; -static gboolean g_use_pixmap; static GOptionEntry g_options[] = { {"codec", 'c', 0, G_OPTION_ARG_STRING, &g_codec_str, "codec to test", NULL}, - {"pixmap", 0, - 0, - G_OPTION_ARG_NONE, &g_use_pixmap, - "use render-to-pixmap", NULL}, {NULL,} }; @@ -57,7 +52,6 @@ main (int argc, char *argv[]) { GstVaapiDisplay *display, *display2; GstVaapiWindow *window; - GstVaapiPixmap *pixmap = NULL; GstVaapiDecoder *decoder; GstVaapiSurfaceProxy *proxy; GstVaapiSurface *surface; @@ -104,34 +98,12 @@ main (int argc, char *argv[]) gst_vaapi_window_show (window); - if (g_use_pixmap) { - guint width, height; - - if (crop_rect) { - width = crop_rect->width; - height = crop_rect->height; - } else - gst_vaapi_surface_get_size (surface, &width, &height); - - pixmap = video_output_create_pixmap (display, GST_VIDEO_FORMAT_xRGB, - width, height); - if (!pixmap) - g_error ("could not create pixmap"); - - if (!gst_vaapi_pixmap_put_surface (pixmap, surface, crop_rect, - GST_VAAPI_PICTURE_STRUCTURE_FRAME)) - g_error ("could not render to pixmap"); - - if (!gst_vaapi_window_put_pixmap (window, pixmap, NULL, NULL)) - g_error ("could not render pixmap"); - } else if (!gst_vaapi_window_put_surface (window, surface, crop_rect, NULL, + if (!gst_vaapi_window_put_surface (window, surface, crop_rect, NULL, GST_VAAPI_PICTURE_STRUCTURE_FRAME)) g_error ("could not render surface"); pause (); - if (pixmap) - gst_vaapi_pixmap_unref (pixmap); gst_vaapi_surface_proxy_unref (proxy); gst_object_unref (decoder); gst_object_unref (window); From 61516dd5e19a13ef6790795e6ab496be935be338 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Mon, 25 Nov 2019 14:16:30 +0800 Subject: [PATCH 3557/3781] vaapijpegenc: Add a quantization quirk for iHD driver iHD driver shifts the value by 50 when calculating quantization for JPEG encoding, so we should add 50 in this plugin for iHD driver too. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay.h | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 28 +++++++++++++++++++---- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index ca235d943c..092885a394 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -806,6 +806,7 @@ set_driver_quirks (GstVaapiDisplay * display) { "i965", GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD }, { "iHD", GST_VAAPI_DRIVER_QUIRK_NO_RGBYUV_VPP_COLOR_PRIMARY }, { "i965", GST_VAAPI_DRIVER_QUIRK_MISSING_RGBA_IMAGE_FORMAT }, + { "iHD", GST_VAAPI_DRIVER_QUIRK_JPEG_ENC_SHIFT_VALUE_BY_50 }, }; /* *INDENT-ON* */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 0d0a1492fe..ef94f741da 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -105,6 +105,8 @@ typedef struct _GstVaapiDisplay GstVaapiDisplay; * 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 */ typedef enum { @@ -112,6 +114,7 @@ typedef enum GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD = (1U << 1), GST_VAAPI_DRIVER_QUIRK_NO_RGBYUV_VPP_COLOR_PRIMARY = (1U << 2), GST_VAAPI_DRIVER_QUIRK_MISSING_RGBA_IMAGE_FORMAT = (1U << 3), + GST_VAAPI_DRIVER_QUIRK_JPEG_ENC_SHIFT_VALUE_BY_50 = (1U << 4), } GstVaapiDriverQuirks; /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 4c87a8aa38..8eda7630a4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -255,7 +255,7 @@ ensure_picture (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture, * is scaling the QM values using the normalized quality factor */ static void generate_scaled_qm (GstJpegQuantTables * quant_tables, - GstJpegQuantTables * scaled_quant_tables, guint quality) + GstJpegQuantTables * scaled_quant_tables, guint quality, guint shift) { guint qt_val, nm_quality, i; nm_quality = quality == 0 ? 1 : quality; @@ -267,11 +267,15 @@ generate_scaled_qm (GstJpegQuantTables * quant_tables, for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) { /* Luma QM */ - qt_val = (quant_tables->quant_tables[0].quant_table[i] * nm_quality) / 100; + 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) / 100; + 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); } @@ -294,10 +298,17 @@ fill_quantization_table (GstVaapiEncoderJpeg * encoder, 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); + encoder->quality, shift); } q_matrix->load_lum_quantiser_matrix = 1; for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) { @@ -507,9 +518,16 @@ bs_write_jpeg_header (GstBitWriter * bs, GstVaapiEncoderJpeg * encoder, /* 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); + encoder->quality, shift); encoder->has_quant_tables = TRUE; } From 861b4cc4b63aab197c2ec60448e80a4e6bd0c37c Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 19 Mar 2020 11:19:18 -0700 Subject: [PATCH 3558/3781] libs: encoder: set VA HRD param before RC param This is a workaround for intel-media-driver bug https://github.com/intel/media-driver/issues/865 The driver will force the RC method to CBR for HEVCe when it parses the HRD param. Thus, any RC method param submitted "prior" to the HRD param will be lost. Therefore, VBR, ICQ and QVBR for HEVCe can't be effectively enabled if the RC method param "precedes" the HRD param. To work around this issue, set the HRD param before the RC method param so the driver will parse the RC method param "after" the HRD param. Afaict, other codecs in the driver (and other drivers) do not appear to be dependent on the order of HRD and RC param submission. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 1184fc809b..bc2584b900 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -63,15 +63,6 @@ gst_vaapi_encoder_ensure_param_control_rate (GstVaapiEncoder * encoder, if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; - /* RateControl params */ - misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); - if (!misc) - return FALSE; - memcpy (misc->data, &GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder), - sizeof (VAEncMiscParameterRateControl)); - gst_vaapi_enc_picture_add_misc_param (picture, misc); - gst_vaapi_codec_object_replace (&misc, NULL); - /* HRD params */ misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); if (!misc) @@ -81,6 +72,15 @@ gst_vaapi_encoder_ensure_param_control_rate (GstVaapiEncoder * encoder, gst_vaapi_enc_picture_add_misc_param (picture, misc); gst_vaapi_codec_object_replace (&misc, NULL); + /* RateControl params */ + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); + if (!misc) + return FALSE; + memcpy (misc->data, &GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder), + sizeof (VAEncMiscParameterRateControl)); + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + /* FrameRate params */ if (GST_VAAPI_ENCODER_VA_FRAME_RATE (encoder).framerate == 0) return TRUE; From a28046a8dfc2e44c709525c52bc2cfd53a421b91 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Wed, 4 Mar 2020 12:35:42 -0800 Subject: [PATCH 3559/3781] libs: encoder: h265: support ICQ/QVBR BRC Enable support for ICQ and QVBR bitrate control. The code is essentially the same for h264 ICQ/QVBR support which was added in commit 9e0c133a2403. --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 40 ++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 86ab5f81ca..3f43297a19 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -40,7 +40,9 @@ #define SUPPORTED_RATECONTROLS \ (GST_VAAPI_RATECONTROL_MASK (CQP) | \ GST_VAAPI_RATECONTROL_MASK (CBR) | \ - GST_VAAPI_RATECONTROL_MASK (VBR)) + GST_VAAPI_RATECONTROL_MASK (VBR) | \ + GST_VAAPI_RATECONTROL_MASK (ICQ) | \ + GST_VAAPI_RATECONTROL_MASK (QVBR)) /* Supported set of tuning options, within this implementation */ #define SUPPORTED_TUNE_OPTIONS \ @@ -111,6 +113,7 @@ struct _GstVaapiEncoderH265 guint32 ctu_height; guint32 luma_width; guint32 luma_height; + guint32 quality_factor; GstClockTime cts_offset; gboolean config_changed; gboolean low_delay_b; @@ -1970,6 +1973,14 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; +#if VA_CHECK_VERSION(1,1,0) + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_ICQ) { + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).ICQ_quality_factor = + encoder->quality_factor; + return TRUE; + } +#endif + /* RateControl params */ GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).bits_per_second = encoder->bitrate_bits; @@ -1988,6 +1999,11 @@ ensure_control_rate_params (GstVaapiEncoderH265 * encoder) (guint) encoder->mbbrc; #endif +#if VA_CHECK_VERSION(1,3,0) + GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).quality_factor = + encoder->quality_factor; +#endif + /* HRD params */ fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder)); @@ -2105,6 +2121,7 @@ ensure_bitrate (GstVaapiEncoderH265 * encoder) switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { case GST_VAAPI_RATECONTROL_CBR: case GST_VAAPI_RATECONTROL_VBR: + case GST_VAAPI_RATECONTROL_QVBR: if (!base_encoder->bitrate) { /* FIXME: Provide better estimation */ /* Using a 1/6 compression ratio */ @@ -2807,6 +2824,7 @@ enum ENCODER_H265_PROP_QP_IB, ENCODER_H265_PROP_LOW_DELAY_B, ENCODER_H265_PROP_MAX_QP, + ENCODER_H265_PROP_QUALITY_FACTOR, ENCODER_H265_N_PROPERTIES }; @@ -2866,6 +2884,9 @@ gst_vaapi_encoder_h265_set_property (GObject * object, guint prop_id, case ENCODER_H265_PROP_MAX_QP: encoder->max_qp = g_value_get_uint (value); break; + case ENCODER_H265_PROP_QUALITY_FACTOR: + encoder->quality_factor = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -2918,6 +2939,9 @@ gst_vaapi_encoder_h265_get_property (GObject * object, guint prop_id, case ENCODER_H265_PROP_MAX_QP: g_value_set_uint (value, encoder->max_qp); break; + case ENCODER_H265_PROP_QUALITY_FACTOR: + g_value_set_uint (value, encoder->quality_factor); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -3110,6 +3134,20 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | GST_VAAPI_PARAM_ENCODER_EXPOSURE); + /** + * GstVaapiEncoderH265:quality_factor: + * + * Quality factor used with ICQ/QVBR bitrate control mode. + */ + properties[ENCODER_H265_PROP_QUALITY_FACTOR] = + g_param_spec_uint ("quality-factor", + "Quality factor for ICQ/QVBR", + "quality factor for ICQ/QBVR bitrate control mode" + " (lower value means higher quality, higher value means lower quality)", + 1, 51, 26, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + GST_VAAPI_PARAM_ENCODER_EXPOSURE); + g_object_class_install_properties (object_class, ENCODER_H265_N_PROPERTIES, properties); } From 532a1e5509952ce018899b50a0412db9bbf8a614 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 18 Mar 2020 16:41:01 +0800 Subject: [PATCH 3560/3781] libs,plugins: decoder: Add -intra profile support for hevc. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In hevc, we can consider the -intra profile a subset of the none -intra profile. The -intra profiles just contain I frames and we definitely can use the none -intra profiles's context to decode them. Signed-off-by: Víctor Manuel Jáquez Leal --- gst-libs/gst/vaapi/gstvaapiprofile.c | 9 ++++ gst-libs/gst/vaapi/gstvaapiutils_h265.c | 55 +++++++++++++++++++++++++ gst/vaapi/gstvaapidecode.c | 31 ++++++++++++-- 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 539ac9b315..3105b90670 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -426,6 +426,15 @@ gst_vaapi_profile_from_caps (const GstCaps * caps) /* HACK: qtdemux does not report profiles for h263 */ profile = m->profile; } + + /* Consider HEVC -intra profiles. Just map them to their + * non-intra profiles */ + if (!profile && profile_str + && strncmp (name, "video/x-h265", namelen) == 0 + && g_str_has_prefix (profile_str, m->profile_str) + && strncmp (profile_str + strlen (m->profile_str), "-intra", 6) == 0) { + profile = m->profile; + } } gst_caps_unref (caps_test); } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 2c078e820d..a276a7ba1f 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -184,6 +184,61 @@ gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { profile = GST_VAAPI_PROFILE_H265_MAIN_444_10; break; + } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 1 + && sps->profile_tier_level.max_422chroma_constraint_flag == 1 + && sps->profile_tier_level.max_420chroma_constraint_flag == 1 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 1 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { + /* Main Intra, recognize it as MAIN */ + profile = GST_VAAPI_PROFILE_H265_MAIN; + break; + } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 0 + && sps->profile_tier_level.max_422chroma_constraint_flag == 1 + && sps->profile_tier_level.max_420chroma_constraint_flag == 1 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 1 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { + /* Main 10 Intra, recognize it as MAIN10 */ + profile = GST_VAAPI_PROFILE_H265_MAIN10; + break; + } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 1 + && sps->profile_tier_level.max_422chroma_constraint_flag == 0 + && sps->profile_tier_level.max_420chroma_constraint_flag == 0 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 1 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { + /* Main 444 Intra, recognize it as MAIN_444 */ + profile = GST_VAAPI_PROFILE_H265_MAIN_444; + break; + } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 0 + && sps->profile_tier_level.max_422chroma_constraint_flag == 0 + && sps->profile_tier_level.max_420chroma_constraint_flag == 0 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 1 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { + /* Main 444_10 Intra, recognize it as MAIN_444_10 */ + profile = GST_VAAPI_PROFILE_H265_MAIN_444_10; + break; + } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 0 + && sps->profile_tier_level.max_422chroma_constraint_flag == 1 + && sps->profile_tier_level.max_420chroma_constraint_flag == 0 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 1 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { + /* Main 422_10 Intra, recognize it as MAIN_422_10 */ + profile = GST_VAAPI_PROFILE_H265_MAIN_422_10; + break; } default: GST_DEBUG ("unsupported profile_idc value"); diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index d5db810793..68de7e9d5b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1267,9 +1267,34 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) continue; profile_name = gst_vaapi_profile_get_name (profile); - if (profile_name) - gst_structure_set (structure, "profile", G_TYPE_STRING, - profile_name, NULL); + if (profile_name) { + /* Add all according -intra profile for HEVC */ + if (profile == GST_VAAPI_PROFILE_H265_MAIN + || profile == GST_VAAPI_PROFILE_H265_MAIN10 + || profile == GST_VAAPI_PROFILE_H265_MAIN_422_10 + || profile == GST_VAAPI_PROFILE_H265_MAIN_444 + || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10) { + GValue list_value = G_VALUE_INIT; + GValue value = G_VALUE_INIT; + gchar *intra_name; + + g_value_init (&list_value, GST_TYPE_LIST); + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, profile_name); + gst_value_list_append_value (&list_value, &value); + + intra_name = g_strdup_printf ("%s-intra", profile_name); + g_value_take_string (&value, intra_name); + gst_value_list_append_value (&list_value, &value); + + gst_structure_set_value (structure, "profile", &list_value); + g_value_unset (&list_value); + g_value_unset (&value); + } else { + gst_structure_set (structure, "profile", G_TYPE_STRING, + profile_name, NULL); + } + } gst_vaapi_profile_caps_append_decoder (display, profile, structure); From 222dc8d7d81f2ada0c57b817282441586a774fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 25 Feb 2020 13:45:05 +0100 Subject: [PATCH 3561/3781] vaapipostproc: deprecate format, width and size parameters Since they should only be controlled by caps negotiation. --- gst/vaapi/gstvaapipostproc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index ad2d75c600..990a9ded06 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -109,9 +109,11 @@ enum { PROP_0, +#ifndef GST_REMOVE_DEPRECATED PROP_FORMAT, PROP_WIDTH, PROP_HEIGHT, +#endif PROP_FORCE_ASPECT_RATIO, PROP_DEINTERLACE_MODE, PROP_DEINTERLACE_METHOD, @@ -1949,6 +1951,7 @@ gst_vaapipostproc_set_property (GObject * object, g_mutex_lock (&postproc->postproc_lock); switch (prop_id) { +#ifndef GST_REMOVE_DEPRECATED case PROP_FORMAT: postproc->format = g_value_get_enum (value); break; @@ -1966,6 +1969,7 @@ gst_vaapipostproc_set_property (GObject * object, do_reconf = (prev_height != postproc->height); break; } +#endif case PROP_FORCE_ASPECT_RATIO: postproc->keep_aspect = g_value_get_boolean (value); break; @@ -2051,6 +2055,7 @@ gst_vaapipostproc_get_property (GObject * object, g_mutex_lock (&postproc->postproc_lock); switch (prop_id) { +#ifndef GST_REMOVE_DEPRECATED case PROP_FORMAT: g_value_set_enum (value, postproc->format); break; @@ -2060,6 +2065,7 @@ gst_vaapipostproc_get_property (GObject * object, case PROP_HEIGHT: g_value_set_uint (value, postproc->height); break; +#endif case PROP_FORCE_ASPECT_RATIO: g_value_set_boolean (value, postproc->keep_aspect); break; @@ -2203,6 +2209,7 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) if (!filter_ops) return; +#ifndef GST_REMOVE_DEPRECATED /** * GstVaapiPostproc:format: * @@ -2242,6 +2249,7 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) "Height", "Forced output height", 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#endif /** * GstVaapiPostproc:crop-left: From 4c9f49437d5aa03a27a6b08173a2c1e1e8858a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 22 Mar 2020 20:59:20 +0100 Subject: [PATCH 3562/3781] build: Add meson's option package-origin. This options is added to synchronize with other gstreamer packages build configuration. Though, to avoid breaking distro configuration it is set, as default, the issues gitlab's url, instead of the used string "Unkown package origin". Also, set_quoted is used for string based cdata. --- meson.build | 16 ++++++++-------- meson_options.txt | 3 +++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/meson.build b/meson.build index c652ce8cea..0aca55e4d5 100644 --- a/meson.build +++ b/meson.build @@ -126,14 +126,14 @@ if driverdir == '' endif cdata = configuration_data() -cdata.set('GST_API_VERSION_S', '"@0@.@1@"'.format(gst_version_major, gst_version_minor)) -cdata.set('PACKAGE', '"gstreamer-vaapi"') -cdata.set('VERSION', '"@0@"'.format(gst_version)) -cdata.set('PACKAGE_VERSION', '"@0@"'.format(gst_version)) -cdata.set('PACKAGE_NAME', '"GStreamer VA-API Plug-ins"') -cdata.set('PACKAGE_STRING', '"GStreamer VA-API Plug-ins @0@"'.format(gst_version)) -cdata.set('PACKAGE_BUGREPORT', '"http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer"') -cdata.set('VA_DRIVERS_PATH', '"@0@"'.format(driverdir)) +cdata.set_quoted('GST_API_VERSION_S', '@0@.@1@'.format(gst_version_major, gst_version_minor)) +cdata.set_quoted('PACKAGE', 'gstreamer-vaapi') +cdata.set_quoted('VERSION', '@0@'.format(gst_version)) +cdata.set_quoted('PACKAGE_VERSION', '@0@'.format(gst_version)) +cdata.set_quoted('PACKAGE_NAME', 'GStreamer VA-API Plug-ins') +cdata.set_quoted('PACKAGE_STRING', 'GStreamer VA-API Plug-ins @0@'.format(gst_version)) +cdata.set_quoted('PACKAGE_BUGREPORT', get_option('package-origin')) +cdata.set_quoted('VA_DRIVERS_PATH', '@0@'.format(driverdir)) cdata.set10('USE_DRM', USE_DRM) cdata.set10('USE_EGL', USE_EGL) cdata.set10('USE_ENCODERS', USE_ENCODERS) diff --git a/meson_options.txt b/meson_options.txt index fd4d92e6e5..ee82b1f990 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -10,3 +10,6 @@ option('examples', type : 'feature', value : 'auto', yield : true) option('tests', type : 'feature', value : 'auto', yield : true) option('doc', type : 'feature', value : 'auto', yield: true, description: 'Enable documentation.') +option('package-origin', type : 'string', + value : '"https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues"', + yield : true, description : 'package origin URL to use in plugins') From b1f859116d91e3b0882c1effe70d0a16f7d34377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 26 Mar 2020 22:40:40 +0100 Subject: [PATCH 3563/3781] vaapivideometa: remove compiler warning --- gst/vaapi/gstvaapivideometa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideometa.c b/gst/vaapi/gstvaapivideometa.c index 68ee20e005..53a48dd90f 100644 --- a/gst/vaapi/gstvaapivideometa.c +++ b/gst/vaapi/gstvaapivideometa.c @@ -432,8 +432,8 @@ gst_vaapi_video_meta_replace (GstVaapiVideoMeta ** old_meta_ptr, if (new_meta) gst_vaapi_video_meta_ref (new_meta); - while (!g_atomic_pointer_compare_and_exchange ((gpointer *) old_meta_ptr, - old_meta, new_meta)) + while (!g_atomic_pointer_compare_and_exchange (old_meta_ptr, old_meta, + new_meta)) old_meta = g_atomic_pointer_get ((gpointer *) old_meta_ptr); if (old_meta) From ecbf070fa4c38c4fefeedca2224bdc7208f299a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 18 Mar 2020 13:28:00 +0100 Subject: [PATCH 3564/3781] libs: extend g_autoptr support --- gst-libs/gst/vaapi/gstvaapidecoder.h | 2 -- gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_h265.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_vc1.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_vp8.h | 2 ++ gst-libs/gst/vaapi/gstvaapidecoder_vp9.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay.h | 2 -- gst-libs/gst/vaapi/gstvaapidisplay_drm.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_egl.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_wayland.h | 2 ++ gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h | 3 +++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_vp8.h | 2 ++ gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 2 ++ gst-libs/gst/vaapi/gstvaapifilter.h | 2 -- gst-libs/gst/vaapi/gstvaapitexturemap.h | 2 ++ gst-libs/gst/vaapi/gstvaapiwindow.h | 2 -- gst-libs/gst/vaapi/gstvaapiwindow_drm.h | 2 -- gst-libs/gst/vaapi/gstvaapiwindow_egl.h | 2 -- gst-libs/gst/vaapi/gstvaapiwindow_glx.h | 2 -- gst-libs/gst/vaapi/gstvaapiwindow_wayland.h | 2 -- gst-libs/gst/vaapi/gstvaapiwindow_x11.h | 2 ++ 30 files changed, 45 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index fb4b196d83..2c5e967ed4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -142,9 +142,7 @@ gst_vaapi_decoder_check_status (GstVaapiDecoder * decoder); gboolean gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps); -#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoder, gst_object_unref) -#endif G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h index 04386068eb..08ce6faa34 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -77,6 +77,8 @@ void gst_vaapi_decoder_h264_set_baseline_as_constrained(GstVaapiDecoderH264 * decoder, gboolean baseline_as_constrained); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoderH264, gst_object_unref) + G_END_DECLS #endif /* GST_VAAPI_DECODER_H264_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.h b/gst-libs/gst/vaapi/gstvaapidecoder_h265.h index 619d3008db..0b5d0922e3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.h @@ -63,6 +63,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h index 876055ea42..5c1b4afc12 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h @@ -43,6 +43,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h index a996c59481..765a80cac7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h @@ -43,6 +43,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h index 99d918d09a..2efd164e0f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h @@ -42,6 +42,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h index 6f9474f94c..034681f608 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.h @@ -42,6 +42,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.h b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.h index 816f6f02a0..9ba26470f0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.h @@ -43,6 +43,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.h b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.h index de97534559..f00ce739d2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.h @@ -42,6 +42,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index ef94f741da..e8f644bcf4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -284,9 +284,7 @@ gst_vaapi_display_reset_texture_map (GstVaapiDisplay * display); gboolean gst_vaapi_display_has_driver_quirks (GstVaapiDisplay * display, guint quirks); -#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDisplay, gst_object_unref) -#endif G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h index 2af4d9f53e..5424b32456 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h @@ -49,6 +49,8 @@ gst_vaapi_display_drm_get_device_path (GstVaapiDisplayDRM * 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.h b/gst-libs/gst/vaapi/gstvaapidisplay_egl.h index ccabf0f83a..07fbf83ff1 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.h @@ -57,6 +57,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index d19a046b81..c4bdcc9ad6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -44,6 +44,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h index 7af728f736..1f9ec30a28 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h @@ -51,6 +51,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 1458ea7ad1..78b6103bb2 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -58,6 +58,8 @@ gst_vaapi_display_x11_set_synchronous (GstVaapiDisplayX11 * display, 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index bf89df2732..6bc9887290 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -195,6 +195,8 @@ gst_vaapi_encoder_get_entrypoint (GstVaapiEncoder * encoder, 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h index 8a0705b461..fc5539f8c5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h @@ -56,6 +56,8 @@ gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder, 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index e9ea5e2221..0944905833 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -52,6 +52,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h index 375658215e..b3b24749f5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h @@ -43,5 +43,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h index 6306bfd4b2..a4384ef6e0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h @@ -44,6 +44,8 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h index b798edb4df..e17c616da9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.h @@ -43,5 +43,7 @@ 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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h index ece52dac64..b66290b7a8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -43,5 +43,7 @@ gst_vaapi_encoder_vp9_get_type (void) G_GNUC_CONST; GstVaapiEncoder * gst_vaapi_encoder_vp9_new (GstVaapiDisplay * display); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiEncoderVP9, gst_object_unref) + G_END_DECLS #endif /*GST_VAAPI_ENCODER_VP9_H */ diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 02c465b120..aacddaf845 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -308,8 +308,6 @@ gboolean gst_vaapi_filter_set_colorimetry (GstVaapiFilter * filter, GstVideoColorimetry * input, GstVideoColorimetry * output); -#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiFilter, gst_object_unref) -#endif #endif /* GST_VAAPI_FILTER_H */ diff --git a/gst-libs/gst/vaapi/gstvaapitexturemap.h b/gst-libs/gst/vaapi/gstvaapitexturemap.h index e74fedf8f5..0e869bb446 100644 --- a/gst-libs/gst/vaapi/gstvaapitexturemap.h +++ b/gst-libs/gst/vaapi/gstvaapitexturemap.h @@ -53,6 +53,8 @@ gst_vaapi_texture_map_reset (GstVaapiTextureMap * map); GType gst_vaapi_texture_map_get_type (void) G_GNUC_CONST; +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiTextureMap, gst_object_unref) + G_END_DECLS #endif /* GST_VAAPI_TEXTURE_MAP_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index a53850107f..563443966f 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -99,9 +99,7 @@ gst_vaapi_window_unblock (GstVaapiWindow * window); gboolean gst_vaapi_window_unblock_cancel (GstVaapiWindow * window); -#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindow, gst_object_unref) -#endif G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h index 7fe0c4ede4..48accb8634 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h @@ -43,9 +43,7 @@ gst_vaapi_window_drm_get_type (void) G_GNUC_CONST; GstVaapiWindow * gst_vaapi_window_drm_new (GstVaapiDisplay * display, guint width, guint height); -#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowDRM, gst_object_unref) -#endif G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_egl.h b/gst-libs/gst/vaapi/gstvaapiwindow_egl.h index 820a105737..ac6db5157a 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_egl.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_egl.h @@ -43,9 +43,7 @@ gst_vaapi_window_egl_get_type (void) G_GNUC_CONST; GstVaapiWindow * gst_vaapi_window_egl_new (GstVaapiDisplay * display, guint width, guint height); -#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowEGL, gst_object_unref) -#endif G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h index d7c4252def..d3ff9a4772 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.h @@ -68,9 +68,7 @@ gst_vaapi_window_glx_put_texture (GstVaapiWindowGLX * window, GstVaapiTexture * texture, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect); -#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowGLX, gst_object_unref) -#endif G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h index 3e13052afd..d4eb427a94 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h @@ -45,9 +45,7 @@ GstVaapiWindow * gst_vaapi_window_wayland_new (GstVaapiDisplay * display, guint width, guint height); -#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowWayland, gst_object_unref) -#endif G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h index 8626cb98e7..672e1ff9a4 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.h @@ -64,6 +64,8 @@ gst_vaapi_window_x11_get_xid (GstVaapiWindowX11 * window); gboolean gst_vaapi_window_x11_is_foreign_xid (GstVaapiWindowX11 * window); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowX11, gst_object_unref) + G_END_DECLS #endif /* GST_VAAPI_WINDOW_X11_H */ From f680a8cba12da81f7bcb97121b888e4f74b27ea4 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Tue, 31 Mar 2020 12:22:31 +0800 Subject: [PATCH 3565/3781] libs: encoder: make sure format array is not NULL when returning TRUE This fixed segfault when running the pipeline below with iHD driver (commit efe5e9a) on ICL gst-launch-1.0 videotestsrc ! vaapivp9enc tune=low-power ! vaapivp9dec ! \ fakesink --- gst-libs/gst/vaapi/gstvaapiencoder.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index bc2584b900..2f97bd9b16 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1481,9 +1481,13 @@ get_profile_surface_attributes (GstVaapiEncoder * encoder, return FALSE; ret = gst_vaapi_context_get_surface_attributes (ctxt, attribs); - if (ret) + if (ret) { attribs->formats = gst_vaapi_context_get_surface_formats (ctxt); + if (!attribs->formats) + ret = FALSE; + } + gst_vaapi_context_unref (ctxt); return ret; } From 80b6e006bc1d269bedcb8426325ee969f5708317 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 2 Apr 2020 15:19:41 +0800 Subject: [PATCH 3566/3781] libs: encoder: fix an inexact trace info in chroma type check. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 2f97bd9b16..5709ba6911 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -681,8 +681,9 @@ is_chroma_type_supported (GstVaapiEncoder * encoder) /* ERRORS */ unsupported: { - GST_ERROR ("We only support YUV 4:2:0 and YUV 4:2:2 for encoding. " - "Please try to use vaapipostproc to convert the input format."); + GST_ERROR ("The encoding format %s is not supported, " + "Please try to use vaapipostproc to convert the input format.", + gst_video_format_to_string (fmt)); return FALSE; } } From 026c01875cb8370568e0a76edfe77e4e25e568f7 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 2 Apr 2020 15:14:15 +0800 Subject: [PATCH 3567/3781] libs: encoder: h265: Support MAIN 4:4:4 10 profile. Using Y410 as the input of the encoder can generate main_444_10 bit streams. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 3 ++- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 25 ++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 ++ gst-libs/gst/vaapi/gstvaapiutils_h265.c | 3 +++ gst/vaapi/gstvaapiencode_h265.c | 2 +- 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 5709ba6911..d989bde6be 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -667,7 +667,8 @@ is_chroma_type_supported (GstVaapiEncoder * encoder) if (cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420 && cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV422 && cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420_10BPP && - cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV444) + cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV444 && + cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV444_10BPP) goto unsupported; if (!get_config_attribute (encoder, VAConfigAttribRTFormat, &format)) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 3f43297a19..8599321d0b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -305,7 +305,8 @@ bs_write_profile_tier_level (GstBitWriter * bs, /* additional indications specified for general_profile_idc from 4~10 */ if (seq_param->general_profile_idc == 4) { /* In A.3.5, Format range extensions profiles. - Just support main444 profile now, may add more profiles when needed. */ + Just support main444 and main444-10 profile now, may add more profiles + when needed. */ switch (profile) { case GST_VAAPI_PROFILE_H265_MAIN_444: /* max_12bit_constraint_flag */ @@ -327,6 +328,26 @@ bs_write_profile_tier_level (GstBitWriter * bs, /* lower_bit_rate_constraint_flag */ WRITE_UINT32 (bs, 1, 1); break; + case GST_VAAPI_PROFILE_H265_MAIN_444_10: + /* max_12bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_10bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_8bit_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_422chroma_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_420chroma_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_monochrome_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* intra_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* one_picture_only_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* lower_bit_rate_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + break; default: GST_WARNING ("do not support the profile: %s of range extensions", gst_vaapi_profile_get_va_name (profile)); @@ -1087,6 +1108,8 @@ ensure_profile (GstVaapiEncoderH265 * encoder) profile = GST_VAAPI_PROFILE_H265_MAIN10; else if (format == GST_VIDEO_FORMAT_VUYA) profile = GST_VAAPI_PROFILE_H265_MAIN_444; + else if (format == GST_VIDEO_FORMAT_Y410) + profile = GST_VAAPI_PROFILE_H265_MAIN_444_10; encoder->profile = profile; encoder->profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile); diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 3105b90670..7f0c94cb79 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -339,6 +339,8 @@ gst_vaapi_profile_from_codec_data_h265 (GstBuffer * buffer) return GST_VAAPI_PROFILE_H265_MAIN_422_10; case 5: return GST_VAAPI_PROFILE_H265_MAIN_444; + case 6: + return GST_VAAPI_PROFILE_H265_MAIN_444_10; } return 0; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index a276a7ba1f..a7e23839ab 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -41,6 +41,7 @@ static const struct map gst_vaapi_h265_profile_map[] = { { GST_VAAPI_PROFILE_H265_MAIN10, "main-10" }, { GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE, "main-still-picture" }, { GST_VAAPI_PROFILE_H265_MAIN_444, "main-444" }, + { GST_VAAPI_PROFILE_H265_MAIN_444_10, "main-444-10" }, { 0, NULL } /* *INDENT-ON* */ }; @@ -267,6 +268,8 @@ gst_vaapi_utils_h265_get_profile_idc (GstVaapiProfile profile) case GST_VAAPI_PROFILE_H265_MAIN_422_10: /* Fall through */ case GST_VAAPI_PROFILE_H265_MAIN_444: + /* Fall through */ + case GST_VAAPI_PROFILE_H265_MAIN_444_10: profile_idc = GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION; break; default: diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 67a319c81e..00fcf585b3 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -65,7 +65,7 @@ static const char gst_vaapiencode_h265_sink_caps_str[] = /* *INDENT-OFF* */ static const char gst_vaapiencode_h265_src_caps_str[] = GST_CODEC_CAPS ", " - "profile = (string) { main, main-10, main-444 }"; + "profile = (string) { main, main-10, main-444, main-444-10 }"; /* *INDENT-ON* */ /* *INDENT-OFF* */ From 5f9e3ceef3aa39fa40a42195dce70f32a76a8376 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 13 Feb 2020 09:00:18 -0800 Subject: [PATCH 3568/3781] libs: filter: HDR10 tone mapping support Add support for HDR10 tone mapping (since VA-API 1.4.0). --- gst-libs/gst/vaapi/gstvaapifilter.c | 174 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 9 ++ 2 files changed, 183 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 52ea9e94a3..f33eb11bb8 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -74,6 +74,10 @@ struct _GstVaapiFilter GstVideoColorimetry input_colorimetry; GstVideoColorimetry output_colorimetry; + +#if VA_CHECK_VERSION(1,4,0) + VAHdrMetaDataHDR10 hdr_meta; +#endif }; typedef struct _GstVaapiFilterClass GstVaapiFilterClass; @@ -340,6 +344,7 @@ enum PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING, PROP_SCALING = GST_VAAPI_FILTER_OP_SCALING, PROP_VIDEO_DIRECTION = GST_VAAPI_FILTER_OP_VIDEO_DIRECTION, + PROP_HDR_TONE_MAP = GST_VAAPI_FILTER_OP_HDR_TONE_MAP, #ifndef GST_REMOVE_DEPRECATED PROP_SKINTONE = GST_VAAPI_FILTER_OP_SKINTONE, #endif @@ -480,6 +485,16 @@ init_properties (void) GST_VIDEO_ORIENTATION_IDENTITY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * GstVaapiFilter:tone-map: + * + * Apply HDR tone mapping + **/ + g_properties[PROP_HDR_TONE_MAP] = g_param_spec_boolean ("hdr-tone-map", + "HDR Tone Mapping", + "Apply HDR tone mapping", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + #ifndef GST_REMOVE_DEPRECATED /** * GstVaapiFilter:skin-tone-enhancement: @@ -535,6 +550,18 @@ op_data_new (GstVaapiFilterOp op, GParamSpec * pspec) op_data->va_buffer = VA_INVALID_ID; switch (op) { + case GST_VAAPI_FILTER_OP_HDR_TONE_MAP: +#if VA_CHECK_VERSION(1,4,0) + /* Only HDR10 tone mapping is supported */ + op_data->va_type = VAProcFilterHighDynamicRangeToneMapping; + op_data->va_subtype = VAProcHighDynamicRangeMetadataHDR10; + op_data->va_cap_size = sizeof (VAProcFilterCapHighDynamicRange); + op_data->va_buffer_size = + sizeof (VAProcFilterParameterBufferHDRToneMapping); + break; +#else + /* fall-through */ +#endif case GST_VAAPI_FILTER_OP_FORMAT: case GST_VAAPI_FILTER_OP_CROP: case GST_VAAPI_FILTER_OP_SCALING: @@ -1118,6 +1145,53 @@ op_set_skintone (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, } #endif +static gboolean +op_set_hdr_tone_map_unlocked (GstVaapiFilter * filter, + GstVaapiFilterOpData * op_data, gboolean value) +{ +#if VA_CHECK_VERSION(1,4,0) + const VAProcFilterCapHighDynamicRange *filter_caps; + guint i; + + if (!op_data) + return !value; + + if (!value) { + op_data->is_enabled = 0; + return TRUE; + } + + if (!op_ensure_buffer (filter, op_data)) + return FALSE; + + for (i = 0, filter_caps = op_data->va_caps; i < op_data->va_num_caps; i++) { + if (filter_caps[i].metadata_type == op_data->va_subtype && + (filter_caps[i].caps_flag & VA_TONE_MAPPING_HDR_TO_SDR)) + break; + } + if (i == op_data->va_num_caps) + return FALSE; + + op_data->is_enabled = 1; + + return TRUE; +#else + return !value; +#endif +} + +static inline gboolean +op_set_hdr_tone_map (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data, + gboolean value) +{ + gboolean success = FALSE; + GST_VAAPI_DISPLAY_LOCK (filter->display); + success = op_set_hdr_tone_map_unlocked (filter, op_data, value); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); + + return success; +} + static gboolean deint_refs_set (GArray * refs, GstVaapiSurface ** surfaces, guint num_surfaces) { @@ -1524,6 +1598,10 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op, return gst_vaapi_filter_set_video_direction (filter, (value ? g_value_get_enum (value) : OP_DATA_DEFAULT_VALUE (enum, op_data))); + case GST_VAAPI_FILTER_OP_HDR_TONE_MAP: + return op_set_hdr_tone_map (filter, op_data, + (value ? g_value_get_boolean (value) : + OP_DATA_DEFAULT_VALUE (boolean, op_data))); default: break; } @@ -2345,3 +2423,99 @@ gst_vaapi_filter_set_colorimetry (GstVaapiFilter * filter, return result; } + +/** + * gst_vaapi_filter_set_hdr_tone_map: + * @filter: a #GstVaapiFilter + * @value: %TRUE to enable hdr tone map algorithm + * + * Applies HDR tone mapping algorithm. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_hdr_tone_map (GstVaapiFilter * filter, gboolean value) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + return op_set_hdr_tone_map (filter, + find_operation (filter, GST_VAAPI_FILTER_OP_HDR_TONE_MAP), value); +} + +static gboolean +gst_vaapi_filter_set_hdr_tone_map_meta_unlocked (GstVaapiFilter * filter, + GstVideoMasteringDisplayInfo * minfo, GstVideoContentLightLevel * linfo) +{ +#if VA_CHECK_VERSION(1,4,0) + GstVaapiFilterOpData *op_data; + VAProcFilterParameterBufferHDRToneMapping *buf; + VAHdrMetaDataHDR10 *meta = &filter->hdr_meta; + + op_data = find_operation (filter, GST_VAAPI_FILTER_OP_HDR_TONE_MAP); + + if (!op_data) + return FALSE; + + meta->display_primaries_x[0] = minfo->display_primaries[1].x; + meta->display_primaries_x[1] = minfo->display_primaries[2].x; + meta->display_primaries_x[2] = minfo->display_primaries[0].x; + + meta->display_primaries_y[0] = minfo->display_primaries[1].y; + meta->display_primaries_y[1] = minfo->display_primaries[2].y; + meta->display_primaries_y[2] = minfo->display_primaries[0].y; + + meta->white_point_x = minfo->white_point.x; + meta->white_point_y = minfo->white_point.y; + + meta->max_display_mastering_luminance = + minfo->max_display_mastering_luminance; + meta->min_display_mastering_luminance = + minfo->min_display_mastering_luminance; + + meta->max_content_light_level = linfo->max_content_light_level; + meta->max_pic_average_light_level = linfo->max_frame_average_light_level; + + buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer); + if (!buf) + return FALSE; + + buf->type = op_data->va_type; + buf->data.metadata_type = op_data->va_subtype; + buf->data.metadata = meta; + buf->data.metadata_size = sizeof (meta); + + vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL); + + return TRUE; +#else + return FALSE; +#endif +} + +/** + * gst_vaapi_filter_set_hdr_tone_map_meta: + * @filter: a #GstVaapiFilter + * @minfo: a #GstVideoMasteringDisplayInfo + * @linfo: a #GstVideoContentLightLevel + * + * Sets the input HDR meta data used for tone mapping. + * + * Return value: %TRUE if the operation is supported, %FALSE otherwise. + */ +gboolean +gst_vaapi_filter_set_hdr_tone_map_meta (GstVaapiFilter * filter, + GstVideoMasteringDisplayInfo * minfo, GstVideoContentLightLevel * linfo) +{ + gboolean status = FALSE; + + g_return_val_if_fail (filter != NULL, FALSE); + g_return_val_if_fail (minfo != NULL, FALSE); + g_return_val_if_fail (linfo != NULL, FALSE); + + GST_VAAPI_DISPLAY_LOCK (filter->display); + status = + gst_vaapi_filter_set_hdr_tone_map_meta_unlocked (filter, minfo, linfo); + GST_VAAPI_DISPLAY_UNLOCK (filter->display); + + return status; +} diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index aacddaf845..27533cbe9a 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -50,6 +50,7 @@ typedef struct _GstVaapiFilterOpInfo GstVaapiFilterOpInfo; * @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). * @@ -67,6 +68,7 @@ typedef enum { 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 @@ -263,6 +265,13 @@ gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter, 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, From 4913d2b59559b06b28de4ae546b1ea4266935b03 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Thu, 13 Feb 2020 09:43:38 -0800 Subject: [PATCH 3569/3781] vaapipostproc: enable HDR10 tone mapping --- gst/vaapi/gstvaapipostproc.c | 125 +++++++++++++++++++++++++++++++++-- gst/vaapi/gstvaapipostproc.h | 16 +++++ 2 files changed, 134 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 990a9ded06..16efffedec 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -129,12 +129,37 @@ enum PROP_CROP_RIGHT, PROP_CROP_TOP, PROP_CROP_BOTTOM, + PROP_HDR_TONE_MAP, #ifndef GST_REMOVE_DEPRECATED PROP_SKIN_TONE_ENHANCEMENT, #endif PROP_SKIN_TONE_ENHANCEMENT_LEVEL, }; +#define GST_VAAPI_TYPE_HDR_TONE_MAP \ + gst_vaapi_hdr_tone_map_get_type() + +static GType +gst_vaapi_hdr_tone_map_get_type (void) +{ + static gsize g_type = 0; + + static const GEnumValue enum_values[] = { + {GST_VAAPI_HDR_TONE_MAP_AUTO, + "Auto detection", "auto"}, + {GST_VAAPI_HDR_TONE_MAP_DISABLED, + "Disable HDR tone mapping", "disabled"}, + {0, NULL, NULL}, + }; + + if (g_once_init_enter (&g_type)) { + const GType type = + g_enum_register_static ("GstVaapiHDRToneMap", enum_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} + #define GST_VAAPI_TYPE_DEINTERLACE_MODE \ gst_vaapi_deinterlace_mode_get_type() @@ -515,6 +540,61 @@ set_best_deint_method (GstVaapiPostproc * postproc, guint flags, return success; } +static gboolean +should_hdr_tone_map (GstVaapiPostproc * const postproc, const GstCaps * caps) +{ + switch (postproc->hdr_tone_map) { + case GST_VAAPI_HDR_TONE_MAP_AUTO: + { + GstVideoMasteringDisplayInfo minfo; + return gst_video_mastering_display_info_from_caps (&minfo, caps); + } + case GST_VAAPI_HDR_TONE_MAP_DISABLED: + return FALSE; + default: + GST_ERROR_OBJECT (postproc, "unhandled \"hdr-tone-map\" option"); + break; + } + return FALSE; +} + +static gboolean +configure_hdr_tone_map (GstVaapiPostproc * const postproc, const GstCaps * caps) +{ + gboolean enable; + + g_return_val_if_fail (postproc->has_vpp, FALSE); + + enable = should_hdr_tone_map (postproc, caps); + + if (!gst_vaapi_filter_set_hdr_tone_map (postproc->filter, enable)) + goto fail_configure_hdr_tone_map; + + if (enable) { + GstVideoMasteringDisplayInfo minfo; + GstVideoContentLightLevel linfo; + + gst_video_mastering_display_info_from_caps (&minfo, caps); + gst_video_content_light_level_from_caps (&linfo, caps); + + if (!gst_vaapi_filter_set_hdr_tone_map_meta (postproc->filter, &minfo, + &linfo)) + goto fail_configure_hdr_tone_map; + + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_HDR_TONE_MAP; + } else { + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_HDR_TONE_MAP); + } + + return TRUE; + +fail_configure_hdr_tone_map: + { + postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_HDR_TONE_MAP); + return FALSE; + } +} + static gboolean check_filter_update (GstVaapiPostproc * postproc) { @@ -1650,6 +1730,21 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, goto done; } + if (postproc->has_vpp) { + if (!gst_vaapi_filter_set_colorimetry (postproc->filter, + &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO + (postproc)), + &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO + (postproc)))) + goto done; + + if (!configure_hdr_tone_map (postproc, + GST_VAAPI_PLUGIN_BASE_SINK_PAD_CAPS (postproc))) + GST_WARNING_OBJECT (postproc, + "Failed to configure HDR tone mapping." + " The driver may not support it."); + } + if (!ensure_srcpad_buffer_pool (postproc, out_caps)) goto done; @@ -1660,13 +1755,6 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps, gst_vaapipostproc_set_passthrough (trans); } - if (postproc->has_vpp && !gst_vaapi_filter_set_colorimetry (postproc->filter, - &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO - (postproc)), - &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO - (postproc)))) - goto done; - ret = TRUE; done: @@ -2037,6 +2125,9 @@ gst_vaapipostproc_set_property (GObject * object, postproc->crop_bottom = g_value_get_uint (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CROP; break; + case PROP_HDR_TONE_MAP: + postproc->hdr_tone_map = g_value_get_enum (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2119,6 +2210,9 @@ gst_vaapipostproc_get_property (GObject * object, case PROP_CROP_BOTTOM: g_value_set_uint (value, postproc->crop_bottom); break; + case PROP_HDR_TONE_MAP: + g_value_set_enum (value, postproc->hdr_tone_map); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2173,6 +2267,22 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) gst_element_class_add_static_pad_template (element_class, &gst_vaapipostproc_src_factory); + /** + * GstVaapiPostproc:hdr-tone-map: + * + * Selects whether HDR tone mapping should not be applied or if it + * should be only applied on content that has the HDR meta on the caps. + */ + g_object_class_install_property + (object_class, + PROP_HDR_TONE_MAP, + g_param_spec_enum ("hdr-tone-map", + "HDR Tone Map", + "Apply HDR tone mapping algorithm", + GST_VAAPI_TYPE_HDR_TONE_MAP, + GST_VAAPI_HDR_TONE_MAP_AUTO, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstVaapiPostproc:deinterlace-mode: * @@ -2487,6 +2597,7 @@ gst_vaapipostproc_init (GstVaapiPostproc * postproc) g_mutex_init (&postproc->postproc_lock); postproc->format = DEFAULT_FORMAT; + postproc->hdr_tone_map = GST_VAAPI_HDR_TONE_MAP_AUTO; postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE; postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; postproc->field_duration = GST_CLOCK_TIME_NONE; diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index c751c8b1c5..9a0d52d5a9 100644 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -49,6 +49,17 @@ typedef struct _GstVaapiPostproc GstVaapiPostproc; typedef struct _GstVaapiPostprocClass GstVaapiPostprocClass; typedef struct _GstVaapiDeinterlaceState GstVaapiDeinterlaceState; +/** + * GstVaapiHDRToneMap: + * @GST_VAAPI_TYPE_HDR_TONE_MAP_AUTO: Auto detect need for hdr tone map. + * @GST_VAAPI_TYPE_HDR_TONE_MAP_DISABLED: Never perform hdr tone map. + */ +typedef enum +{ + GST_VAAPI_HDR_TONE_MAP_AUTO = 0, + GST_VAAPI_HDR_TONE_MAP_DISABLED, +} GstVaapiHDRToneMap; + /** * GstVaapiDeinterlaceMode: * @GST_VAAPI_DEINTERLACE_MODE_AUTO: Auto detect needs for deinterlacing. @@ -87,6 +98,7 @@ typedef enum * @GST_VAAPI_POSTPROC_FLAG_SIZE: Video scaling. * @GST_VAAPI_POSTPROC_FLAG_SCALE: Video scaling mode. * @GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION: Video rotation and flip/mirroring. + * @GST_VAAPI_POSTPROC_FLAG_HDR_TONE_MAP: HDR tone mapping. * @GST_VAAPI_POSTPROC_FLAG_SKINTONE: Skin tone enhancement. * @GST_VAAPI_POSTPROC_FLAG_SKINTONE_LEVEL: Skin tone enhancement with value. * @@ -106,6 +118,7 @@ typedef enum GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION = 1 << GST_VAAPI_FILTER_OP_VIDEO_DIRECTION, GST_VAAPI_POSTPROC_FLAG_CROP = 1 << GST_VAAPI_FILTER_OP_CROP, + GST_VAAPI_POSTPROC_FLAG_HDR_TONE_MAP = 1 << GST_VAAPI_FILTER_OP_HDR_TONE_MAP, #ifndef GST_REMOVE_DEPRECATED GST_VAAPI_POSTPROC_FLAG_SKINTONE = 1 << GST_VAAPI_FILTER_OP_SKINTONE, #endif @@ -159,6 +172,9 @@ struct _GstVaapiPostproc GstCaps *allowed_srcpad_caps; GstVideoInfo srcpad_info; + /* HDR Tone Mapping */ + GstVaapiHDRToneMap hdr_tone_map; + /* Deinterlacing */ GstVaapiDeinterlaceMode deinterlace_mode; GstVaapiDeinterlaceMethod deinterlace_method; From 7701844813e9c1ed559a0014cfa29986d907ae09 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sun, 15 Mar 2020 21:50:24 +0800 Subject: [PATCH 3570/3781] plugin: bufferpool: Delete ACQUIRE_FLAG_NO_ALLOC flag. Delete the GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC flag. In fact, no one is using that flag, and all vaapi buffers should have GstVaapiVideoMeta. --- gst/vaapi/gstvaapivideobufferpool.c | 21 +++++++-------------- gst/vaapi/gstvaapivideobufferpool.h | 14 -------------- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 2de92ea581..874dbcb1d4 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -321,22 +321,15 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, GstMemory *mem; GstBuffer *buffer; - const gboolean alloc_vaapi_video_meta = !params || - !(params->flags & GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC); - if (!priv->allocator) goto error_no_allocator; - if (alloc_vaapi_video_meta) { - meta = gst_vaapi_video_meta_new (priv->display); - if (!meta) - goto error_create_meta; + meta = gst_vaapi_video_meta_new (priv->display); + if (!meta) + goto error_create_meta; + + buffer = gst_vaapi_video_buffer_new (meta); - buffer = gst_vaapi_video_buffer_new (meta); - } else { - meta = NULL; - buffer = gst_vaapi_video_buffer_new_empty (); - } if (!buffer) goto error_create_buffer; @@ -487,8 +480,8 @@ gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool, * While surface is passed, we should clear it to avoid wrong * reference. */ meta = gst_buffer_get_vaapi_video_meta (buffer); - if (meta) - gst_vaapi_video_meta_set_surface_proxy (meta, NULL); + g_assert (meta); + gst_vaapi_video_meta_set_surface_proxy (meta, NULL); } GST_BUFFER_POOL_CLASS (gst_vaapi_video_buffer_pool_parent_class)->reset_buffer diff --git a/gst/vaapi/gstvaapivideobufferpool.h b/gst/vaapi/gstvaapivideobufferpool.h index 98be6f848a..23321fc8f8 100644 --- a/gst/vaapi/gstvaapivideobufferpool.h +++ b/gst/vaapi/gstvaapivideobufferpool.h @@ -56,20 +56,6 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate; #define GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META \ "GstBufferPoolOptionVaapiVideoMeta" -/** - * GstVaapiVideoBufferPoolAcquireFlags: - * @GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC: option to - * request that vaapi video metadata are not initially allocated, - * but are subsequently provided by the user. - * - * The set of #GstVaapiVideoBufferPool specific flags for - * gst_buffer_pool_acquire_buffer(). - */ -typedef enum { - GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC = - GST_BUFFER_POOL_ACQUIRE_FLAG_LAST << 0, -} GstVaapiVideoBufferPoolAcquireFlags; - /** * GstVaapiVideoBufferPoolOption: * @GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META: From ce3bf2c2aef123d2d57e3a99fa532fd960acf499 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sun, 15 Mar 2020 22:07:31 +0800 Subject: [PATCH 3571/3781] plugin: bufferpool: use hashmap to cache dmabuf mem-surface The old way of refer memory by bufferproxy is not a good one, since it make the logic error prone. Now it is established a map between surface-bufferproxy and its GstMemory, caching the memory bound by a surface looked for the specified surface. --- gst/vaapi/gstvaapivideobufferpool.c | 136 ++++++++++++++++++++++------ 1 file changed, 107 insertions(+), 29 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 874dbcb1d4..219b992827 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -47,6 +47,8 @@ struct _GstVaapiVideoBufferPoolPrivate guint options; guint use_dmabuf_memory:1; guint forced_video_meta:1; + /* Map between surface and GstMemory, only DMA */ + GHashTable *dma_mem_map; }; G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiVideoBufferPool, @@ -60,6 +62,8 @@ gst_vaapi_video_buffer_pool_finalize (GObject * object) gst_vaapi_display_replace (&priv->display, NULL); g_clear_object (&priv->allocator); + if (priv->dma_mem_map) + g_hash_table_destroy (priv->dma_mem_map); G_OBJECT_CLASS (gst_vaapi_video_buffer_pool_parent_class)->finalize (object); } @@ -309,6 +313,58 @@ error_no_allocator: } } +static void +vaapi_buffer_pool_cache_dma_mem (GstVaapiVideoBufferPool * pool, + GstVaapiSurfaceProxy * proxy, GstMemory * mem) +{ + GstVaapiVideoBufferPoolPrivate *const priv = pool->priv; + GstVaapiSurface *surface; + + surface = GST_VAAPI_SURFACE_PROXY_SURFACE (proxy); + g_assert (surface); + g_assert (gst_vaapi_surface_peek_buffer_proxy (surface)); + + if (!priv->dma_mem_map) + priv->dma_mem_map = g_hash_table_new_full (g_direct_hash, + g_direct_equal, NULL, (GDestroyNotify) gst_memory_unref); + + if (!g_hash_table_contains (priv->dma_mem_map, surface)) { + g_hash_table_insert (priv->dma_mem_map, surface, gst_memory_ref (mem)); + } else { + g_assert (g_hash_table_lookup (priv->dma_mem_map, surface) == mem); + } +} + +static GstMemory * +vaapi_buffer_pool_lookup_dma_mem (GstVaapiVideoBufferPool * pool, + GstVaapiSurfaceProxy * proxy) +{ + GstVaapiSurface *surface; + GstVaapiVideoBufferPoolPrivate *const priv = pool->priv; + GstVaapiBufferProxy *buf_proxy; + GstMemory *mem; + + g_assert (priv->use_dmabuf_memory); + + if (!priv->dma_mem_map) + return NULL; + + surface = GST_VAAPI_SURFACE_PROXY_SURFACE (proxy); + g_assert (surface); + + buf_proxy = gst_vaapi_surface_peek_buffer_proxy (surface); + /* Have not exported yet */ + if (!buf_proxy) { + g_assert (!g_hash_table_contains (priv->dma_mem_map, surface)); + return NULL; + } + + mem = g_hash_table_lookup (priv->dma_mem_map, surface); + g_assert (mem); + + return gst_memory_ref (mem); +} + static GstFlowReturn gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, GstBuffer ** out_buffer_ptr, GstBufferPoolAcquireParams * params) @@ -336,10 +392,23 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, if (priv_params && priv_params->proxy) gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy); - if (priv->use_dmabuf_memory) - mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta); - else + if (priv->use_dmabuf_memory) { + mem = NULL; + if (priv_params && priv_params->proxy) { + mem = vaapi_buffer_pool_lookup_dma_mem (base_pool, priv_params->proxy); + if (!mem) { + mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta); + if (!mem) + goto error_create_memory; + + vaapi_buffer_pool_cache_dma_mem (base_pool, priv_params->proxy, mem); + } + } else { + mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta); + } + } else { mem = gst_vaapi_video_memory_new (priv->allocator, meta); + } if (!mem) goto error_create_memory; gst_vaapi_video_meta_replace (&meta, NULL); @@ -407,7 +476,6 @@ gst_vaapi_video_buffer_pool_acquire_buffer (GstBufferPool * pool, GstMemory *mem; GstVaapiVideoMeta *meta; GstVaapiSurface *surface; - GstVaapiBufferProxy *dmabuf_proxy; ret = GST_BUFFER_POOL_CLASS @@ -420,15 +488,20 @@ gst_vaapi_video_buffer_pool_acquire_buffer (GstBufferPool * pool, return ret; } - /* The point of the following dance is to attach the right GstMemory to the - * current acquired buffer. Indeed this buffer can contain any of the - * GstFdmemory since this buffer have been popped out from the buffer pool's - * FIFO. So there is no garantee that this matches the current surface. The - * va decoder driver might not even use a FIFO. So there is no way to guess - * on the ordering. In short acquire_current_buffer on the va driver and on - * the buffer pool return none matching data. So we have to manually attach - * the right GstFdMemory to the acquired GstBuffer. The right GstMemory is - * the one associated with the current surface. */ + /* Some pool users, such as decode, needs to acquire a buffer for a + * specified surface (via surface proxy). If not it is a DMABuf, we + * just replace the underlying surface proxy of buffer's + * GstVaapiVideoMeta. But in DMABuf case, the thing is a little bit + * more complicated: + * + * For DMABuf, GstMemory is-a GstFdMemory, which doesn't provide a + * way to change its FD, thus once created it's bound to a + * surface. On the other side, for performace reason, when the + * buffer is released, the buffer and its memory are cached in the + * buffer pool, and at next acquire_buffer() may still reuse a + * buffer and its memory. But the pushed surface by the decoder may + * be different from the one popped by the pool, so we need to + * replace the buffer's memory with the correct one. */ g_assert (gst_buffer_n_memory (buffer) == 1); /* Update the underlying surface proxy */ @@ -439,30 +512,34 @@ gst_vaapi_video_buffer_pool_acquire_buffer (GstBufferPool * pool, } gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy); - /* Find the cached memory associated with the given surface. */ - surface = GST_VAAPI_SURFACE_PROXY_SURFACE (priv_params->proxy); - dmabuf_proxy = gst_vaapi_surface_peek_buffer_proxy (surface); - if (dmabuf_proxy) { - mem = gst_vaapi_buffer_proxy_peek_mem (dmabuf_proxy); - if (mem == gst_buffer_peek_memory (buffer, 0)) - mem = NULL; - else - mem = gst_memory_ref (mem); + mem = vaapi_buffer_pool_lookup_dma_mem (base_pool, priv_params->proxy); + if (mem) { + if (mem == gst_buffer_peek_memory (buffer, 0)) { + gst_memory_unref (mem); + *out_buffer_ptr = buffer; + return GST_FLOW_OK; + } } else { - /* The given surface has not been exported yet. */ + /* Should be an unexported surface */ + surface = GST_VAAPI_SURFACE_PROXY_SURFACE (priv_params->proxy); + g_assert (surface); + g_assert (gst_vaapi_surface_peek_buffer_proxy (surface) == NULL); + gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy); mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta); + if (mem) + vaapi_buffer_pool_cache_dma_mem (base_pool, priv_params->proxy, mem); } - /* Attach the GstFdMemory to the output buffer. */ if (mem) { - GST_DEBUG_OBJECT (base_pool, "assigning memory %p to acquired buffer %p", - mem, buffer); gst_buffer_replace_memory (buffer, 0, mem); gst_buffer_unset_flags (buffer, GST_BUFFER_FLAG_TAG_MEMORY); + *out_buffer_ptr = buffer; + return GST_FLOW_OK; + } else { + gst_buffer_unref (buffer); + *out_buffer_ptr = NULL; + return GST_FLOW_ERROR; } - - *out_buffer_ptr = buffer; - return GST_FLOW_OK; } static void @@ -523,6 +600,7 @@ static void gst_vaapi_video_buffer_pool_init (GstVaapiVideoBufferPool * pool) { pool->priv = gst_vaapi_video_buffer_pool_get_instance_private (pool); + pool->priv->dma_mem_map = NULL; } GstBufferPool * From c80668c337408114a9bc715f13bcea44223a1d8c Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 3 Apr 2020 18:43:52 +0200 Subject: [PATCH 3572/3781] libs: bufferproxy: rename parent memeber as surface --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 20 +++++++++---------- gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h | 4 ++-- gst-libs/gst/vaapi/gstvaapisurface_drm.c | 2 +- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index c8fe234b83..14dc5b49ee 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -41,11 +41,10 @@ gst_vaapi_buffer_proxy_acquire_handle (GstVaapiBufferProxy * proxy) if (proxy->va_info.handle) return TRUE; - if (!proxy->parent || proxy->va_buf == VA_INVALID_ID) + if (!proxy->surface || proxy->va_buf == VA_INVALID_ID) return FALSE; - /* @XXX(victor): parent might be not a surface */ - display = GST_VAAPI_SURFACE_DISPLAY (GST_VAAPI_SURFACE (proxy->parent)); + display = GST_VAAPI_SURFACE_DISPLAY (GST_VAAPI_SURFACE (proxy->surface)); GST_VAAPI_DISPLAY_LOCK (display); va_status = vaAcquireBufferHandle (GST_VAAPI_DISPLAY_VADISPLAY (display), @@ -67,11 +66,10 @@ gst_vaapi_buffer_proxy_release_handle (GstVaapiBufferProxy * proxy) if (!proxy->va_info.handle) return TRUE; - if (!proxy->parent || proxy->va_buf == VA_INVALID_ID) + if (!proxy->surface || proxy->va_buf == VA_INVALID_ID) return FALSE; - /* @XXX(victor): parent might be not a surface */ - display = GST_VAAPI_SURFACE_DISPLAY (GST_VAAPI_SURFACE (proxy->parent)); + display = GST_VAAPI_SURFACE_DISPLAY (GST_VAAPI_SURFACE (proxy->surface)); GST_VAAPI_DISPLAY_LOCK (display); va_status = vaReleaseBufferHandle (GST_VAAPI_DISPLAY_VADISPLAY (display), @@ -96,7 +94,7 @@ gst_vaapi_buffer_proxy_finalize (GstVaapiBufferProxy * proxy) if (proxy->destroy_func) proxy->destroy_func (proxy->destroy_data); - gst_mini_object_replace ((GstMiniObject **) & proxy->parent, NULL); + gst_mini_object_replace ((GstMiniObject **) & proxy->surface, NULL); } static inline const GstVaapiMiniObjectClass * @@ -123,7 +121,7 @@ gst_vaapi_buffer_proxy_new (guintptr handle, guint type, gsize size, if (!proxy) return NULL; - proxy->parent = NULL; + proxy->surface = NULL; proxy->destroy_func = destroy_func; proxy->destroy_data = user_data; proxy->type = type; @@ -147,19 +145,19 @@ error_unsupported_mem_type: } GstVaapiBufferProxy * -gst_vaapi_buffer_proxy_new_from_object (GstMiniObject * object, +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 (object != NULL, NULL); + 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->parent = gst_mini_object_ref (object); + proxy->surface = gst_mini_object_ref (surface); proxy->destroy_func = destroy_func; proxy->destroy_data = data; proxy->type = type; diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h index 66bfeb4d8e..ac929c304e 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h @@ -62,7 +62,7 @@ G_BEGIN_DECLS struct _GstVaapiBufferProxy { /*< private >*/ GstVaapiMiniObject parent_instance; - GstMiniObject *parent; + GstMiniObject *surface; GDestroyNotify destroy_func; gpointer destroy_data; @@ -74,7 +74,7 @@ struct _GstVaapiBufferProxy { G_GNUC_INTERNAL GstVaapiBufferProxy * -gst_vaapi_buffer_proxy_new_from_object (GstMiniObject * object, +gst_vaapi_buffer_proxy_new_from_surface (GstMiniObject * surface, VABufferID buf_id, guint type, GDestroyNotify destroy_func, gpointer data); G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index 7587553a21..cbf12c6741 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -38,7 +38,7 @@ gst_vaapi_surface_get_drm_buf_handle (GstVaapiSurface * surface, guint type) /* The proxy takes ownership if the image, even creation failure. */ proxy = - gst_vaapi_buffer_proxy_new_from_object (GST_MINI_OBJECT_CAST (surface), + gst_vaapi_buffer_proxy_new_from_surface (GST_MINI_OBJECT_CAST (surface), image->internal_image.buf, type, (GDestroyNotify) gst_vaapi_image_unref, image); if (!proxy) From e54671d4b3ca5cfb0e282db33b9c3d7b5aa955d6 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sun, 15 Mar 2020 23:29:05 +0800 Subject: [PATCH 3573/3781] libs,plugin: break surface-bufferproxy circular reference The bufferproxy may reference the surface and the surface may also reference the bufferproxy, producing a circular reference, which might lead to serious resource leak problems. Now make the relationship clearer, the bufferproxy's references is transfered to surface, while bufferproxy just keeps the surface's address without increasing its reference count. The surface can be created through a bufferproxy like in gst_vaapi_surface_new_with_dma_buf_handle(), and the surface might get its bufferproxy via gst_vaapi_surface_get_dma_buf_handle(). In both cases the surface holds a bufferproxy's reference. --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 4 +- gst-libs/gst/vaapi/gstvaapisurface.c | 3 ++ gst-libs/gst/vaapi/gstvaapisurface_drm.c | 49 +++++++++++++++++------- gst-libs/gst/vaapi/gstvaapisurface_drm.h | 4 +- gst/vaapi/gstvaapivideomemory.c | 24 +++++------- 5 files changed, 52 insertions(+), 32 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index 14dc5b49ee..41533cd83e 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -94,7 +94,7 @@ gst_vaapi_buffer_proxy_finalize (GstVaapiBufferProxy * proxy) if (proxy->destroy_func) proxy->destroy_func (proxy->destroy_data); - gst_mini_object_replace ((GstMiniObject **) & proxy->surface, NULL); + proxy->surface = NULL; } static inline const GstVaapiMiniObjectClass * @@ -157,7 +157,7 @@ gst_vaapi_buffer_proxy_new_from_surface (GstMiniObject * surface, if (!proxy) return NULL; - proxy->surface = gst_mini_object_ref (surface); + proxy->surface = surface; proxy->destroy_func = destroy_func; proxy->destroy_data = data; proxy->type = type; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 3e92e0eaf9..5c821f6ba7 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -492,6 +492,7 @@ gst_vaapi_surface_new_from_buffer_proxy (GstVaapiDisplay * display, g_return_val_if_fail (proxy != NULL, NULL); g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (!proxy->surface, NULL); surface = gst_vaapi_surface_create (display); if (!surface) @@ -499,6 +500,8 @@ gst_vaapi_surface_new_from_buffer_proxy (GstVaapiDisplay * display, if (!gst_vaapi_surface_init_from_buffer_proxy (surface, proxy, info)) goto error; + + proxy->surface = GST_MINI_OBJECT_CAST (surface); return surface; /* ERRORS */ diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.c b/gst-libs/gst/vaapi/gstvaapisurface_drm.c index cbf12c6741..833c6ac51b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.c @@ -59,48 +59,69 @@ error_alloc_export_buffer: } /** - * gst_vaapi_surface_get_dma_buf_handle: + * gst_vaapi_surface_peek_dma_buf_handle: * @surface: a #GstVaapiSurface * * If the underlying VA driver implementation supports it, this * function allows for returning a suitable dma_buf (DRM) buffer - * handle as a #GstVaapiBufferProxy instance. The resulting buffer - * handle is live until the last reference to the proxy gets - * released. Besides, any further change to the parent VA @surface may - * fail. + * handle as a #GstVaapiBufferProxy instance. The returned buffer + * proxy does not increase the ref of underlying buffer proxy. * * Return value: the underlying buffer as a #GstVaapiBufferProxy * instance. */ GstVaapiBufferProxy * -gst_vaapi_surface_get_dma_buf_handle (GstVaapiSurface * surface) +gst_vaapi_surface_peek_dma_buf_handle (GstVaapiSurface * surface) { + GstVaapiBufferProxy *buf_proxy; + g_return_val_if_fail (surface != NULL, NULL); - return gst_vaapi_surface_get_drm_buf_handle (surface, + if (surface->extbuf_proxy) + return surface->extbuf_proxy; + + buf_proxy = gst_vaapi_surface_get_drm_buf_handle (surface, GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF); + + if (buf_proxy) { + gst_vaapi_surface_set_buffer_proxy (surface, buf_proxy); + gst_vaapi_buffer_proxy_unref (buf_proxy); + } + + return buf_proxy; } /** - * gst_vaapi_surface_get_gem_buf_handle: + * gst_vaapi_surface_peek_gem_buf_handle: * @surface: a #GstVaapiSurface * * If the underlying VA driver implementation supports it, this * function allows for returning a suitable GEM buffer handle as a - * #GstVaapiBufferProxy instance. The resulting buffer handle is live - * until the last reference to the proxy gets released. Besides, any - * further change to the parent VA @surface may fail. + * #GstVaapiBufferProxy instance. The returned buffer proxy does + * not increase the ref of underlying buffer proxy. * * Return value: the underlying buffer as a #GstVaapiBufferProxy * instance. */ GstVaapiBufferProxy * -gst_vaapi_surface_get_gem_buf_handle (GstVaapiSurface * surface) +gst_vaapi_surface_peek_gem_buf_handle (GstVaapiSurface * surface) { + GstVaapiBufferProxy *buf_proxy; + g_return_val_if_fail (surface != NULL, NULL); - return gst_vaapi_surface_get_drm_buf_handle (surface, + if (surface->extbuf_proxy) + return surface->extbuf_proxy; + + buf_proxy = gst_vaapi_surface_get_drm_buf_handle (surface, GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF); + + if (buf_proxy) { + gst_vaapi_surface_set_buffer_proxy (surface, buf_proxy); + gst_vaapi_buffer_proxy_unref (buf_proxy); + } + + return buf_proxy; } static void @@ -149,6 +170,7 @@ gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, gint fd, return NULL; surface = gst_vaapi_surface_new_from_buffer_proxy (display, proxy, vi); + /* Surface holds proxy's reference */ gst_vaapi_buffer_proxy_unref (proxy); return surface; } @@ -187,6 +209,7 @@ gst_vaapi_surface_new_with_gem_buf_handle (GstVaapiDisplay * display, fill_video_info (&vi, format, width, height, offset, stride); surface = gst_vaapi_surface_new_from_buffer_proxy (display, proxy, &vi); + /* Surface holds proxy's reference */ gst_vaapi_buffer_proxy_unref (proxy); return surface; } diff --git a/gst-libs/gst/vaapi/gstvaapisurface_drm.h b/gst-libs/gst/vaapi/gstvaapisurface_drm.h index 1dd637d8e5..0bc5f846b3 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_drm.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_drm.h @@ -29,10 +29,10 @@ G_BEGIN_DECLS GstVaapiBufferProxy * -gst_vaapi_surface_get_dma_buf_handle (GstVaapiSurface * surface); +gst_vaapi_surface_peek_dma_buf_handle (GstVaapiSurface * surface); GstVaapiBufferProxy * -gst_vaapi_surface_get_gem_buf_handle (GstVaapiSurface * surface); +gst_vaapi_surface_peek_gem_buf_handle (GstVaapiSurface * surface); GstVaapiSurface * gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display, gint fd, diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index f01a2ef44c..48f42ab211 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -1019,8 +1019,9 @@ gst_vaapi_dmabuf_memory_holds_surface (GstMemory * mem) { g_return_val_if_fail (mem != NULL, FALSE); - return gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (mem), - GST_VAAPI_BUFFER_PROXY_QUARK) != NULL; + return + GPOINTER_TO_INT (gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (mem), + GST_VAAPI_BUFFER_PROXY_QUARK)) == TRUE; } GstMemory * @@ -1065,20 +1066,21 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, proxy = gst_vaapi_surface_proxy_new (surface); if (!proxy) goto error_create_surface_proxy; + /* The proxy has incremented the surface ref count. */ + gst_vaapi_surface_unref (surface); } else { /* When exporting existing surfaces that come from decoder's * context. */ surface = GST_VAAPI_SURFACE_PROXY_SURFACE (proxy); } - dmabuf_proxy = gst_vaapi_surface_get_dma_buf_handle (surface); + dmabuf_proxy = gst_vaapi_surface_peek_dma_buf_handle (surface); if (!dmabuf_proxy) goto error_create_dmabuf_proxy; if (needs_surface) { - /* The proxy has incremented the surface ref count. */ - gst_vaapi_surface_unref (surface); gst_vaapi_video_meta_set_surface_proxy (meta, proxy); + /* meta holds the proxy's reference */ gst_vaapi_surface_proxy_unref (proxy); } @@ -1095,17 +1097,9 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator, goto error_create_dmabuf_memory; if (needs_surface) { - /* Just set the GstVaapiBufferProxy (dmabuf_proxy) as qdata and - * forget about it. */ + /* qdata express that memory has an associated surface. */ gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem), - GST_VAAPI_BUFFER_PROXY_QUARK, dmabuf_proxy, - (GDestroyNotify) gst_vaapi_buffer_proxy_unref); - } else { - /* When not allocating the surface from this pool, so when - * exporting from the decoder's VA context, we need to know which - * GstMemory belongs to a provided surface. */ - gst_vaapi_buffer_proxy_set_mem (dmabuf_proxy, mem); - gst_vaapi_surface_set_buffer_proxy (surface, dmabuf_proxy); + GST_VAAPI_BUFFER_PROXY_QUARK, GINT_TO_POINTER (TRUE), NULL); } /* When a VA surface is going to be filled by a VAAPI element From f1d13d1e08148b694caa08353105d4252d239f06 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 4 Apr 2020 13:58:00 +0200 Subject: [PATCH 3574/3781] libs: bufferproxy: remove GstMemory reference Since bufferproxy and surface are not referenced circularly, there's no need to keep, in the buffer proxy, a reference to the GstMemory where it is held. This patch removes that handling. --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 40 ------------------- gst-libs/gst/vaapi/gstvaapibufferproxy.h | 6 --- gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h | 1 - 3 files changed, 47 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index 41533cd83e..492053a59a 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -85,11 +85,6 @@ gst_vaapi_buffer_proxy_finalize (GstVaapiBufferProxy * proxy) { gst_vaapi_buffer_proxy_release_handle (proxy); - if (proxy->mem) { - gst_memory_unref (proxy->mem); - proxy->mem = NULL; - } - /* Notify the user function that the object is now destroyed */ if (proxy->destroy_func) proxy->destroy_func (proxy->destroy_data); @@ -130,7 +125,6 @@ gst_vaapi_buffer_proxy_new (guintptr handle, guint type, gsize size, proxy->va_info.type = VAImageBufferType; proxy->va_info.mem_type = from_GstVaapiBufferMemoryType (proxy->type); proxy->va_info.mem_size = size; - proxy->mem = NULL; if (!proxy->va_info.mem_type) goto error_unsupported_mem_type; return proxy; @@ -162,7 +156,6 @@ gst_vaapi_buffer_proxy_new_from_surface (GstMiniObject * surface, proxy->destroy_data = data; proxy->type = type; proxy->va_buf = buf_id; - proxy->mem = NULL; memset (&proxy->va_info, 0, sizeof (proxy->va_info)); proxy->va_info.mem_type = from_GstVaapiBufferMemoryType (proxy->type); if (!proxy->va_info.mem_type) @@ -303,36 +296,3 @@ gst_vaapi_buffer_proxy_release_data (GstVaapiBufferProxy * proxy) proxy->destroy_data = NULL; } } - -/** - * gst_vaapi_buffer_proxy_set_mem: - * @proxy: a #GstVaapiBufferProxy - * @mem: a #GstMemory - * - * Relates @mem with @proxy, hence we later will know which memory - * correspond to processed surface. - * - * This is useful when a dmabuf-based memory is instantiated and - * associated with a surface. - **/ -void -gst_vaapi_buffer_proxy_set_mem (GstVaapiBufferProxy * proxy, GstMemory * mem) -{ - gst_mini_object_replace ((GstMiniObject **) & proxy->mem, - GST_MINI_OBJECT (mem)); -} - -/** - * gst_vaapi_buffer_proxy_peek_mem: - * @proxy: a #GstVaapiBufferProxy - * - * This is useful when a dmabuf-based memory is instantiated and - * associated with a surface. - * - * Returns: (transfer none): the assigned #GstMemory to the @proxy. - **/ -GstMemory * -gst_vaapi_buffer_proxy_peek_mem (GstVaapiBufferProxy * proxy) -{ - return proxy->mem; -} diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.h b/gst-libs/gst/vaapi/gstvaapibufferproxy.h index bb80abf4d6..4b1cebec24 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.h @@ -101,12 +101,6 @@ gst_vaapi_buffer_proxy_get_size (GstVaapiBufferProxy * proxy); void gst_vaapi_buffer_proxy_release_data (GstVaapiBufferProxy * proxy); -void -gst_vaapi_buffer_proxy_set_mem (GstVaapiBufferProxy * proxy, GstMemory * mem); - -GstMemory * -gst_vaapi_buffer_proxy_peek_mem (GstVaapiBufferProxy * proxy); - G_END_DECLS #endif /* GST_VAAPI_BUFFER_PROXY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h index ac929c304e..d9f518855a 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h @@ -69,7 +69,6 @@ struct _GstVaapiBufferProxy { guint type; VABufferID va_buf; VABufferInfo va_info; - GstMemory *mem; }; G_GNUC_INTERNAL From a53f0834b3767d5c9e721bb0379fdeda254868d1 Mon Sep 17 00:00:00 2001 From: Veerabadhran G Date: Tue, 21 Apr 2020 09:04:51 +0000 Subject: [PATCH 3575/3781] README: Update supported hardware Added the AMD hardware list to the "Hardware Requirements" section. --- README | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README b/README index 8f12ecb4a2..4602b2717b 100644 --- a/README +++ b/README @@ -87,6 +87,9 @@ Hardware requirements * Intel BayTrail, Braswell * Intel Poulsbo (US15W) * Intel Medfield or Cedar Trail + * Hardwares 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 * Hardware supported by Mesa VA gallium state-tracker From 8b7a5a36f1b2769dd6c8cbddb375b8dadf2b9057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 21 Apr 2020 11:16:37 +0200 Subject: [PATCH 3576/3781] build: use join_paths() for driverdir --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 0aca55e4d5..e9e64a1a51 100644 --- a/meson.build +++ b/meson.build @@ -122,7 +122,7 @@ endif driverdir = libva_dep.get_pkgconfig_variable('driverdir') if driverdir == '' - driverdir = '@0@/@1@/@2@'.format(get_option('prefix'), get_option('libdir'), 'dri') + driverdir = join_paths(get_option('prefix'), get_option('libdir'), 'dri') endif cdata = configuration_data() From 336c2b76d1748b6ecab2922d4f387314529881a1 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Sun, 26 Apr 2020 13:30:16 +0800 Subject: [PATCH 3577/3781] vaapipluginutil: Use GST_VAAPI_DISPLAY_TYPE_DRM for Mesa3D GBM We may build this plugin with window system support but run it without window system. Without this patch, the following pipeline will trigger a segfault when running it without window system. gst-launch-1.0 filesrc location=input.264 ! h264parse ! vaapih264dec ! fakesink Part-of: --- gst/vaapi/gstvaapipluginutil.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index e344649e6e..ba89b4a7a6 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -156,6 +156,11 @@ gst_vaapi_get_display_type_from_gl (GstGLDisplayType gl_display_type, case GST_GL_DISPLAY_TYPE_EGL:{ return GST_VAAPI_DISPLAY_TYPE_EGL; } +#endif +#if USE_DRM + case GST_GL_DISPLAY_TYPE_GBM:{ + return GST_VAAPI_DISPLAY_TYPE_DRM; + } #endif default: /* unsupported display. Still DRM may work. */ From d19541775818aee6c85a4c54ddedbd26d647698f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 21 Apr 2020 18:00:26 +0200 Subject: [PATCH 3578/3781] libs: display: drm: use g_strcmp0 to be null safe Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 2570754414..ecc5a14fdf 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -111,7 +111,7 @@ get_default_device_path (GstVaapiDisplay * display) parent = udev_device_get_parent (device); for (i = 0; allowed_subsystems[i] != NULL; i++) - if (strcmp (udev_device_get_subsystem (parent), + if (g_strcmp0 (udev_device_get_subsystem (parent), allowed_subsystems[i]) == 0) break; From 808247a96325f689f88f98708ef8ecd287057022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 26 Apr 2020 12:33:29 +0200 Subject: [PATCH 3579/3781] Update README Part-of: --- README | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/README b/README index 4602b2717b..d214ac797b 100644 --- a/README +++ b/README @@ -3,8 +3,9 @@ VA-API support to GStreamer Copyright (C) 2010-2011 Splitted-Desktop Systems - Copyright (C) 2011-2014 Intel Corporation + Copyright (C) 2011-2020 Intel Corporation Copyright (C) 2011 Collabora Ltd. + Copyright (C) 2015-2020 Igalia, S.L. License @@ -41,6 +42,9 @@ GStreamer and helper libraries. 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 -------- @@ -66,31 +70,18 @@ Features Requirements ------------ -Software requirements - - * GStreamer 1.9.x: - libgstreamer1.0-dev (>= 1.9.x) - libgstreamer-plugins-base1.0-dev (>= 1.9.x) - libgstreamer-plugins-bad1.0-dev (>= 1.9.0) - - * Renderers: - DRM: libva-dev (>= 1.1.0), libdrm-dev, libudev-dev - X11: libva-dev (>= 1.0.1) - GLX: libva-dev (>= 1.0.3) - Wayland: libva-dev (>= 1.1.0), libwayland-dev (>= 1.0.2) - Hardware requirements - * Intel Eaglelake (G45) - * Intel Ironlake, Sandybridge, Ivybridge, Haswell, Broadwell, - Skylake, etc. (HD Graphics) - * Intel BayTrail, Braswell - * Intel Poulsbo (US15W) - * Intel Medfield or Cedar Trail - * Hardwares supported by AMD Radeonsi driver, such as the list below + * 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 - * Hardware supported by Mesa VA gallium state-tracker + * Other hardware supported by Mesa VA gallium state-tracker Usage From f20bd8bfd1c916c979319d134dbfc2ca5ef00167 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 18 Apr 2020 19:32:24 +0800 Subject: [PATCH 3580/3781] libs: texture: Make texture a standard GstMiniObject. We store GstVaapiTextureGLX and GstVaapiTextureEGL's private data in the qdata of miniobject and avoid extending the base texture class. Part-of: --- gst-libs/gst/vaapi/gstvaapitexture.c | 139 +++++++------ gst-libs/gst/vaapi/gstvaapitexture.h | 46 +++-- gst-libs/gst/vaapi/gstvaapitexture_egl.c | 230 +++++++++++----------- gst-libs/gst/vaapi/gstvaapitexture_glx.c | 169 ++++++++-------- gst-libs/gst/vaapi/gstvaapitexture_priv.h | 60 +++--- gst-libs/gst/vaapi/gstvaapitexturemap.c | 2 +- gst-libs/gst/vaapi/gstvaapiwindow_egl.c | 9 +- gst/vaapi/gstvaapivideometa_texture.c | 12 +- tests/internal/test-textures.c | 4 +- 9 files changed, 353 insertions(+), 318 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 2a2d7a7bcd..1fe9e2cf4f 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -38,51 +38,80 @@ (GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED | \ GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED) +#define GST_VAAPI_TEXTURE_PRIVATE_QUARK gst_vaapi_texture_private_quark () +static GQuark +gst_vaapi_texture_private_quark (void) +{ + static gsize g_quark; + + if (g_once_init_enter (&g_quark)) { + gsize quark = (gsize) g_quark_from_static_string ("GstVaapiTexturePrivate"); + g_once_init_leave (&g_quark, quark); + } + return g_quark; +} + +gpointer +gst_vaapi_texture_get_private (GstVaapiTexture * texture) +{ + return gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (texture), + GST_VAAPI_TEXTURE_PRIVATE_QUARK); +} + +void +gst_vaapi_texture_set_private (GstVaapiTexture * texture, gpointer priv, + GDestroyNotify destroy) +{ + gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (texture), + GST_VAAPI_TEXTURE_PRIVATE_QUARK, (gpointer) priv, destroy); +} + static void gst_vaapi_texture_init (GstVaapiTexture * texture, GstVaapiID id, guint target, guint format, guint width, guint height) { texture->is_wrapped = id != GST_VAAPI_ID_INVALID; - GST_VAAPI_OBJECT_ID (texture) = texture->is_wrapped ? id : 0; + GST_VAAPI_TEXTURE_ID (texture) = texture->is_wrapped ? id : 0; texture->gl_target = target; texture->gl_format = format; texture->width = width; texture->height = height; } -static inline gboolean -gst_vaapi_texture_allocate (GstVaapiTexture * texture) +static void +gst_vaapi_texture_free (GstVaapiTexture * texture) { - return GST_VAAPI_TEXTURE_GET_CLASS (texture)->allocate (texture); + gst_vaapi_display_replace (&GST_VAAPI_TEXTURE_DISPLAY (texture), NULL); + g_slice_free1 (sizeof (GstVaapiTexture), texture); } +GST_DEFINE_MINI_OBJECT_TYPE (GstVaapiTexture, gst_vaapi_texture); + GstVaapiTexture * -gst_vaapi_texture_new_internal (const GstVaapiTextureClass * klass, - GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, - guint width, guint height) +gst_vaapi_texture_new_internal (GstVaapiDisplay * display, GstVaapiID id, + guint target, guint format, guint width, guint height) { GstVaapiTexture *texture; + g_return_val_if_fail (display, NULL); g_return_val_if_fail (target != 0, NULL); g_return_val_if_fail (format != 0, NULL); g_return_val_if_fail (width > 0, NULL); g_return_val_if_fail (height > 0, NULL); - texture = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (klass), display); + texture = g_slice_alloc (sizeof (GstVaapiTexture)); if (!texture) return NULL; - gst_vaapi_texture_init (texture, id, target, format, width, height); - if (!gst_vaapi_texture_allocate (texture)) - goto error; - return texture; + gst_mini_object_init (GST_MINI_OBJECT_CAST (texture), 0, + GST_TYPE_VAAPI_TEXTURE, NULL, NULL, + (GstMiniObjectFreeFunction) gst_vaapi_texture_free); - /* ERRORS */ -error: - { - gst_vaapi_object_unref (texture); - return NULL; - } + GST_VAAPI_TEXTURE_DISPLAY (texture) = gst_object_ref (display); + + gst_vaapi_texture_init (texture, id, target, format, width, height); + + return texture; } /** @@ -155,50 +184,6 @@ gst_vaapi_texture_new_wrapped (GstVaapiDisplay * display, guint id, return dpy_class->create_texture (display, id, target, format, width, height); } -/** - * gst_vaapi_texture_ref: - * @texture: a #GstVaapiTexture - * - * Atomically increases the reference count of the given @texture by one. - * - * Returns: The same @texture argument - */ -GstVaapiTexture * -gst_vaapi_texture_ref (GstVaapiTexture * texture) -{ - return gst_vaapi_object_ref (GST_VAAPI_OBJECT (texture)); -} - -/** - * gst_vaapi_texture_unref: - * @texture: a #GstVaapiTexture - * - * Atomically decreases the reference count of the @texture by one. If - * the reference count reaches zero, the texture will be free'd. - */ -void -gst_vaapi_texture_unref (GstVaapiTexture * texture) -{ - gst_vaapi_object_unref (GST_VAAPI_OBJECT (texture)); -} - -/** - * gst_vaapi_texture_replace: - * @old_texture_ptr: a pointer to a #GstVaapiTexture - * @new_texture: a #GstVaapiTexture - * - * Atomically replaces the texture texture held in @old_texture_ptr - * with @new_texture. This means that @old_texture_ptr shall reference - * a valid texture. However, @new_texture can be NULL. - */ -void -gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr, - GstVaapiTexture * new_texture) -{ - gst_vaapi_object_replace ((GstVaapiObject **) (old_texture_ptr), - GST_VAAPI_OBJECT (new_texture)); -} - /** * gst_vaapi_texture_get_id: * @texture: a #GstVaapiTexture @@ -300,6 +285,21 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture, *height_ptr = GST_VAAPI_TEXTURE_HEIGHT (texture); } +/** + * gst_vaapi_texture_get_display: + * @texture: a #GstVaapiTexture + * + * Returns the #GstVaapiDisplay this @texture is bound to. + * + * Return value: the parent #GstVaapiDisplay object + */ +GstVaapiDisplay * +gst_vaapi_texture_get_display (GstVaapiTexture * texture) +{ + g_return_val_if_fail (texture != NULL, NULL); + return GST_VAAPI_TEXTURE_DISPLAY (texture); +} + /** * gst_vaapi_texture_get_orientation_flags: * @texture: a #GstVaapiTexture @@ -313,8 +313,7 @@ gst_vaapi_texture_get_orientation_flags (GstVaapiTexture * texture) { g_return_val_if_fail (texture != NULL, 0); - return GST_VAAPI_TEXTURE_FLAGS (texture) & - GST_VAAPI_TEXTURE_ORIENTATION_FLAGS; + return GST_MINI_OBJECT_FLAGS (texture) & GST_VAAPI_TEXTURE_ORIENTATION_FLAGS; } /** @@ -333,8 +332,8 @@ gst_vaapi_texture_set_orientation_flags (GstVaapiTexture * texture, guint flags) g_return_if_fail (texture != NULL); g_return_if_fail ((flags & ~GST_VAAPI_TEXTURE_ORIENTATION_FLAGS) == 0); - GST_VAAPI_TEXTURE_FLAG_UNSET (texture, GST_VAAPI_TEXTURE_ORIENTATION_FLAGS); - GST_VAAPI_TEXTURE_FLAG_SET (texture, flags); + GST_MINI_OBJECT_FLAG_UNSET (texture, GST_VAAPI_TEXTURE_ORIENTATION_FLAGS); + GST_MINI_OBJECT_FLAG_SET (texture, flags); } /** @@ -343,7 +342,7 @@ gst_vaapi_texture_set_orientation_flags (GstVaapiTexture * texture, guint flags) * @surface: a #GstVaapiSurface * @flags: postprocessing flags. See #GstVaapiTextureRenderFlags * - * Renders the @surface into the àtexture. The @flags specify how + * Renders the @surface into the @texture. The @flags specify how * de-interlacing (if needed), color space conversion, scaling and * other postprocessing transformations are performed. * @@ -353,14 +352,12 @@ gboolean gst_vaapi_texture_put_surface (GstVaapiTexture * texture, GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) { - const GstVaapiTextureClass *klass; GstVaapiRectangle rect; g_return_val_if_fail (texture != NULL, FALSE); g_return_val_if_fail (surface != NULL, FALSE); - klass = GST_VAAPI_TEXTURE_GET_CLASS (texture); - if (!klass) + if (!texture->put_surface) return FALSE; if (!crop_rect) { @@ -369,5 +366,5 @@ gst_vaapi_texture_put_surface (GstVaapiTexture * texture, gst_vaapi_surface_get_size (surface, &rect.width, &rect.height); crop_rect = ▭ } - return klass->put_surface (texture, surface, crop_rect, flags); + return texture->put_surface (texture, surface, crop_rect, flags); } diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 529ae2727e..ef9b58637b 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -33,6 +33,17 @@ G_BEGIN_DECLS #define GST_VAAPI_TEXTURE(obj) \ ((GstVaapiTexture *)(obj)) +#define GST_TYPE_VAAPI_TEXTURE (gst_vaapi_texture_get_type ()) + +/** + * GST_VAAPI_TEXTURE_DISPLAY: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the display associated with the @texture + */ +#define GST_VAAPI_TEXTURE_DISPLAY(texture) \ + gst_vaapi_texture_get_display (GST_VAAPI_TEXTURE (texture)) + /** * GST_VAAPI_TEXTURE_ID: * @texture: a #GstVaapiTexture @@ -94,10 +105,26 @@ typedef struct _GstVaapiTexture GstVaapiTexture; * from the left to the right. */ typedef enum { - GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED = 1 << 31, - GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED = 1 << 30, + GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED = (GST_MINI_OBJECT_FLAG_LAST << 1), + GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED = (GST_MINI_OBJECT_FLAG_LAST << 2), } GstVaapiTextureOrientationFlags; +GType +gst_vaapi_texture_get_type (void) G_GNUC_CONST; + +/** + * gst_vaapi_texture_unref: (skip) + * @texture: (transfer full): a #GstVaapiTexture. + * + * Decreases the refcount of the texture. If the refcount reaches 0, the + * texture will be freed. + */ +static inline void +gst_vaapi_texture_unref (GstVaapiTexture * texture) +{ + gst_mini_object_unref (GST_MINI_OBJECT_CAST (texture)); +} + GstVaapiTexture * gst_vaapi_texture_new (GstVaapiDisplay * display, guint target, guint format, guint width, guint height); @@ -106,19 +133,12 @@ GstVaapiTexture * gst_vaapi_texture_new_wrapped (GstVaapiDisplay * display, guint id, guint target, guint format, guint width, guint height); -GstVaapiTexture * -gst_vaapi_texture_ref (GstVaapiTexture * texture); - -void -gst_vaapi_texture_unref (GstVaapiTexture * texture); - -void -gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr, - GstVaapiTexture * new_texture); - guint gst_vaapi_texture_get_id (GstVaapiTexture * texture); +GstVaapiDisplay * +gst_vaapi_texture_get_display (GstVaapiTexture * texture); + guint gst_vaapi_texture_get_target (GstVaapiTexture * texture); @@ -147,6 +167,8 @@ gst_vaapi_texture_put_surface (GstVaapiTexture * texture, GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiTexture, gst_vaapi_texture_unref) + G_END_DECLS #endif /* GST_VAAPI_TEXTURE_H */ diff --git a/gst-libs/gst/vaapi/gstvaapitexture_egl.c b/gst-libs/gst/vaapi/gstvaapitexture_egl.c index e0eb318375..f392bcefa0 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_egl.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_egl.c @@ -40,48 +40,32 @@ #define DEBUG 1 #include "gstvaapidebug.h" -#define GST_VAAPI_TEXTURE_EGL(texture) \ - ((GstVaapiTextureEGL *) (texture)) - -typedef struct _GstVaapiTextureEGL GstVaapiTextureEGL; -typedef struct _GstVaapiTextureEGLClass GstVaapiTextureEGLClass; +typedef struct _GstVaapiTextureEGLPrivate GstVaapiTextureEGLPrivate; /** - * GstVaapiTextureEGL: + * GstVaapiTextureEGLPrivate: * - * Base object for EGL texture wrapper. + * EGL texture specific fields. */ -struct _GstVaapiTextureEGL +struct _GstVaapiTextureEGLPrivate { /*< private > */ - GstVaapiTexture parent_instance; - + GstVaapiTexture *texture; EglContext *egl_context; EGLImageKHR egl_image; GstVaapiSurface *surface; GstVaapiFilter *filter; }; -/** - * GstVaapiTextureEGLClass: - * - * Base class for EGL texture wrapper. - */ -struct _GstVaapiTextureEGLClass -{ - /*< private > */ - GstVaapiTextureClass parent_class; -}; - typedef struct { - GstVaapiTextureEGL *texture; + GstVaapiTexture *texture; gboolean success; /* result */ } CreateTextureArgs; typedef struct { - GstVaapiTextureEGL *texture; + GstVaapiTexture *texture; GstVaapiSurface *surface; const GstVaapiRectangle *crop_rect; guint flags; @@ -89,32 +73,31 @@ typedef struct } UploadSurfaceArgs; static gboolean -create_objects (GstVaapiTextureEGL * texture, GLuint texture_id) +create_objects (GstVaapiTexture * texture, GLuint texture_id) { - GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture); - EglContext *const ctx = texture->egl_context; + GstVaapiTextureEGLPrivate *const texture_egl = + gst_vaapi_texture_get_private (texture); + EglContext *const ctx = texture_egl->egl_context; EglVTable *const vtable = egl_context_get_vtable (ctx, FALSE); - GLint attribs[3], *attrib; + GLint attribs[3] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; - attrib = attribs; - *attrib++ = EGL_IMAGE_PRESERVED_KHR; - *attrib++ = EGL_TRUE; - *attrib++ = EGL_NONE; - texture->egl_image = vtable->eglCreateImageKHR (ctx->display->base.handle.p, + texture_egl->egl_image = + vtable->eglCreateImageKHR (ctx->display->base.handle.p, ctx->base.handle.p, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer) GSIZE_TO_POINTER (texture_id), attribs); - if (!texture->egl_image) + if (!texture_egl->egl_image) goto error_create_image; - texture->surface = - gst_vaapi_surface_new_with_egl_image (GST_VAAPI_OBJECT_DISPLAY (texture), - texture->egl_image, GST_VIDEO_FORMAT_RGBA, base_texture->width, - base_texture->height); - if (!texture->surface) + texture_egl->surface = + gst_vaapi_surface_new_with_egl_image (GST_VAAPI_TEXTURE_DISPLAY (texture), + texture_egl->egl_image, GST_VIDEO_FORMAT_RGBA, texture->width, + texture->height); + if (!texture_egl->surface) goto error_create_surface; - texture->filter = gst_vaapi_filter_new (GST_VAAPI_OBJECT_DISPLAY (texture)); - if (!texture->filter) + texture_egl->filter = + gst_vaapi_filter_new (GST_VAAPI_TEXTURE_DISPLAY (texture)); + if (!texture_egl->filter) goto error_create_filter; return TRUE; @@ -137,17 +120,18 @@ error_create_filter: } static gboolean -do_create_texture_unlocked (GstVaapiTextureEGL * texture) +do_create_texture_unlocked (GstVaapiTexture * texture) { - GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture); GLuint texture_id; + GstVaapiTextureEGLPrivate *texture_egl = + gst_vaapi_texture_get_private (texture); - if (base_texture->is_wrapped) + if (texture->is_wrapped) texture_id = GST_VAAPI_TEXTURE_ID (texture); else { - texture_id = egl_create_texture (texture->egl_context, - base_texture->gl_target, base_texture->gl_format, - base_texture->width, base_texture->height); + texture_id = egl_create_texture (texture_egl->egl_context, + texture->gl_target, texture->gl_format, + texture->width, texture->height); if (!texture_id) return FALSE; GST_VAAPI_TEXTURE_ID (texture) = texture_id; @@ -158,74 +142,78 @@ do_create_texture_unlocked (GstVaapiTextureEGL * texture) static void do_create_texture (CreateTextureArgs * args) { - GstVaapiTextureEGL *const texture = args->texture; + GstVaapiTexture *const texture = args->texture; + GstVaapiTextureEGLPrivate *texture_egl = + gst_vaapi_texture_get_private (texture); EglContextState old_cs; args->success = FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) { + GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); + if (egl_context_set_current (texture_egl->egl_context, TRUE, &old_cs)) { args->success = do_create_texture_unlocked (texture); - egl_context_set_current (texture->egl_context, FALSE, &old_cs); + egl_context_set_current (texture_egl->egl_context, FALSE, &old_cs); } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); } static void -destroy_objects (GstVaapiTextureEGL * texture) +destroy_objects (GstVaapiTextureEGLPrivate * texture_egl) { - EglContext *const ctx = texture->egl_context; + EglContext *const ctx = texture_egl->egl_context; EglVTable *const vtable = egl_context_get_vtable (ctx, FALSE); - if (texture->egl_image != EGL_NO_IMAGE_KHR) { + if (texture_egl->egl_image != EGL_NO_IMAGE_KHR) { vtable->eglDestroyImageKHR (ctx->display->base.handle.p, - texture->egl_image); - texture->egl_image = EGL_NO_IMAGE_KHR; + texture_egl->egl_image); + texture_egl->egl_image = EGL_NO_IMAGE_KHR; } - gst_mini_object_replace ((GstMiniObject **) & texture->surface, NULL); - gst_vaapi_filter_replace (&texture->filter, NULL); + gst_mini_object_replace ((GstMiniObject **) & texture_egl->surface, NULL); + gst_vaapi_filter_replace (&texture_egl->filter, NULL); } static void -do_destroy_texture_unlocked (GstVaapiTextureEGL * texture) +do_destroy_texture_unlocked (GstVaapiTextureEGLPrivate * texture_egl) { - GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture); - const GLuint texture_id = GST_VAAPI_TEXTURE_ID (texture); + GstVaapiTexture *const base_texture = texture_egl->texture; + const GLuint texture_id = GST_VAAPI_TEXTURE_ID (base_texture); - destroy_objects (texture); + destroy_objects (texture_egl); if (texture_id) { if (!base_texture->is_wrapped) - egl_destroy_texture (texture->egl_context, texture_id); - GST_VAAPI_TEXTURE_ID (texture) = 0; + egl_destroy_texture (texture_egl->egl_context, texture_id); + GST_VAAPI_TEXTURE_ID (base_texture) = 0; } } static void -do_destroy_texture (GstVaapiTextureEGL * texture) +do_destroy_texture (GstVaapiTextureEGLPrivate * texture_egl) { EglContextState old_cs; + GstVaapiTexture *texture = texture_egl->texture; - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) { - do_destroy_texture_unlocked (texture); - egl_context_set_current (texture->egl_context, FALSE, &old_cs); + GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); + if (egl_context_set_current (texture_egl->egl_context, TRUE, &old_cs)) { + do_destroy_texture_unlocked (texture_egl); + egl_context_set_current (texture_egl->egl_context, FALSE, &old_cs); } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); - egl_object_replace (&texture->egl_context, NULL); + GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); + egl_object_replace (&texture_egl->egl_context, NULL); + g_free (texture_egl); } static gboolean -do_upload_surface_unlocked (GstVaapiTextureEGL * texture, +do_upload_surface_unlocked (GstVaapiTextureEGLPrivate * texture_egl, GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) { GstVaapiFilterStatus status; - if (!gst_vaapi_filter_set_cropping_rectangle (texture->filter, crop_rect)) + if (!gst_vaapi_filter_set_cropping_rectangle (texture_egl->filter, crop_rect)) return FALSE; - status = gst_vaapi_filter_process (texture->filter, surface, texture->surface, - flags); + status = gst_vaapi_filter_process (texture_egl->filter, surface, + texture_egl->surface, flags); if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) return FALSE; return TRUE; @@ -234,74 +222,86 @@ do_upload_surface_unlocked (GstVaapiTextureEGL * texture, static void do_upload_surface (UploadSurfaceArgs * args) { - GstVaapiTextureEGL *const texture = args->texture; + GstVaapiTexture *const texture = args->texture; + GstVaapiTextureEGLPrivate *texture_egl = + gst_vaapi_texture_get_private (texture); EglContextState old_cs; args->success = FALSE; - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) { - args->success = do_upload_surface_unlocked (texture, args->surface, + GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); + if (egl_context_set_current (texture_egl->egl_context, TRUE, &old_cs)) { + args->success = do_upload_surface_unlocked (texture_egl, args->surface, args->crop_rect, args->flags); - egl_context_set_current (texture->egl_context, FALSE, &old_cs); + egl_context_set_current (texture_egl->egl_context, FALSE, &old_cs); } - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); } static gboolean -gst_vaapi_texture_egl_create (GstVaapiTextureEGL * texture) +gst_vaapi_texture_egl_create (GstVaapiTexture * texture) { CreateTextureArgs args = { texture }; GstVaapiDisplayEGL *display = - GST_VAAPI_DISPLAY_EGL (GST_VAAPI_OBJECT_DISPLAY (texture)); + GST_VAAPI_DISPLAY_EGL (GST_VAAPI_TEXTURE_DISPLAY (texture)); + GstVaapiTextureEGLPrivate *texture_egl = + gst_vaapi_texture_get_private (texture); if (GST_VAAPI_TEXTURE (texture)->is_wrapped) { if (!gst_vaapi_display_egl_set_current_display (display)) return FALSE; } - egl_object_replace (&texture->egl_context, + egl_object_replace (&texture_egl->egl_context, GST_VAAPI_DISPLAY_EGL_CONTEXT (display)); - return egl_context_run (texture->egl_context, + return egl_context_run (texture_egl->egl_context, (EglContextRunFunc) do_create_texture, &args) && args.success; } static void -gst_vaapi_texture_egl_destroy (GstVaapiTextureEGL * texture) +gst_vaapi_texture_egl_destroy (GstVaapiTextureEGLPrivate * texture_egl) { - egl_context_run (texture->egl_context, - (EglContextRunFunc) do_destroy_texture, texture); + egl_context_run (texture_egl->egl_context, + (EglContextRunFunc) do_destroy_texture, texture_egl); } static gboolean -gst_vaapi_texture_egl_put_surface (GstVaapiTextureEGL * texture, +gst_vaapi_texture_egl_put_surface (GstVaapiTexture * texture, GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) { UploadSurfaceArgs args = { texture, surface, crop_rect, flags }; + GstVaapiTextureEGLPrivate *texture_egl = + gst_vaapi_texture_get_private (texture); - return egl_context_run (texture->egl_context, + return egl_context_run (texture_egl->egl_context, (EglContextRunFunc) do_upload_surface, &args) && args.success; } -static void -gst_vaapi_texture_egl_class_init (GstVaapiTextureEGLClass * klass) +static GstVaapiTexture * +gst_vaapi_texture_egl_new_internal (GstVaapiTexture * texture) { - GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); - GstVaapiTextureClass *const texture_class = GST_VAAPI_TEXTURE_CLASS (klass); + GstVaapiTextureEGLPrivate *texture_egl; - object_class->finalize = (GstVaapiObjectFinalizeFunc) - gst_vaapi_texture_egl_destroy; - texture_class->allocate = (GstVaapiTextureAllocateFunc) - gst_vaapi_texture_egl_create; - texture_class->put_surface = (GstVaapiTexturePutSurfaceFunc) - gst_vaapi_texture_egl_put_surface; + texture->put_surface = gst_vaapi_texture_egl_put_surface; + + texture_egl = g_malloc0 (sizeof (GstVaapiTextureEGLPrivate)); + if (!texture_egl) { + gst_mini_object_unref (GST_MINI_OBJECT_CAST (texture)); + return NULL; + } + texture_egl->texture = texture; + gst_vaapi_texture_set_private (texture, texture_egl, + (GDestroyNotify) gst_vaapi_texture_egl_destroy); + + if (!gst_vaapi_texture_egl_create (texture)) { + gst_mini_object_unref (GST_MINI_OBJECT_CAST (texture)); + return NULL; + } + + return texture; } -#define gst_vaapi_texture_egl_finalize gst_vaapi_texture_egl_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiTextureEGL, - gst_vaapi_texture_egl, gst_vaapi_texture_egl_class_init (&g_class)); - /** * gst_vaapi_texture_egl_new: * @display: a #GstVaapiDisplay @@ -325,11 +325,16 @@ GstVaapiTexture * gst_vaapi_texture_egl_new (GstVaapiDisplay * display, guint target, guint format, guint width, guint height) { + GstVaapiTexture *texture; + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL); - return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS - (gst_vaapi_texture_egl_class ()), display, GST_VAAPI_ID_INVALID, target, - format, width, height); + texture = gst_vaapi_texture_new_internal (display, GST_VAAPI_ID_INVALID, + target, format, width, height); + if (!texture) + return NULL; + + return gst_vaapi_texture_egl_new_internal (texture); } /** @@ -356,10 +361,15 @@ GstVaapiTexture * gst_vaapi_texture_egl_new_wrapped (GstVaapiDisplay * display, guint texture_id, guint target, GLenum format, guint width, guint height) { + GstVaapiTexture *texture; + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL); g_return_val_if_fail (texture_id != GL_NONE, NULL); - return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS - (gst_vaapi_texture_egl_class ()), display, texture_id, target, format, - width, height); + texture = gst_vaapi_texture_new_internal (display, texture_id, + target, format, width, height); + if (!texture) + return texture; + + return gst_vaapi_texture_egl_new_internal (texture); } diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.c b/gst-libs/gst/vaapi/gstvaapitexture_glx.c index dab6ebe848..273afc9bac 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_glx.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.c @@ -45,42 +45,29 @@ #define GST_VAAPI_TEXTURE_GLX(texture) \ ((GstVaapiTextureGLX *)(texture)) -typedef struct _GstVaapiTextureGLX GstVaapiTextureGLX; -typedef struct _GstVaapiTextureGLXClass GstVaapiTextureGLXClass; +typedef struct _GstVaapiTextureGLXPrivate GstVaapiTextureGLXPrivate; /** - * GstVaapiTextureGLX: + * GstVaapiTextureGLXPrivate: * - * Base object for GLX texture wrapper. + * GLX texture specific fields. */ -struct _GstVaapiTextureGLX +struct _GstVaapiTextureGLXPrivate { /*< private > */ - GstVaapiTexture parent_instance; - + GstVaapiTexture *texture; GLContextState *gl_context; GLPixmapObject *pixo; GLFramebufferObject *fbo; }; -/** - * GstVaapiTextureGLXClass: - * - * Base class for GLX texture wrapper. - */ -struct _GstVaapiTextureGLXClass -{ - /*< private > */ - GstVaapiTextureClass parent_class; -}; - static gboolean gst_vaapi_texture_glx_put_surface (GstVaapiTexture * texture, GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags); static void -destroy_objects (GstVaapiTextureGLX * texture) +destroy_objects (GstVaapiTextureGLXPrivate * texture) { GLContextState old_cs; @@ -105,11 +92,12 @@ destroy_objects (GstVaapiTextureGLX * texture) } static void -destroy_texture_unlocked (GstVaapiTexture * texture) +destroy_texture_unlocked (GstVaapiTextureGLXPrivate * texture_glx) { + GstVaapiTexture *texture = texture_glx->texture; const guint texture_id = GST_VAAPI_TEXTURE_ID (texture); - destroy_objects (GST_VAAPI_TEXTURE_GLX (texture)); + destroy_objects (texture_glx); if (texture_id) { if (!texture->is_wrapped) @@ -119,38 +107,45 @@ destroy_texture_unlocked (GstVaapiTexture * texture) } static void -gst_vaapi_texture_glx_destroy (GstVaapiTexture * texture) +gst_vaapi_texture_glx_destroy (GstVaapiTextureGLXPrivate * texture_glx) { - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); - destroy_texture_unlocked (texture); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + GstVaapiTexture *texture = texture_glx->texture; + + GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); + destroy_texture_unlocked (texture_glx); + GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); + + g_free (texture_glx); } static gboolean -create_objects (GstVaapiTextureGLX * texture, guint texture_id) +create_objects (GstVaapiTexture * texture, guint texture_id) { - GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture); - Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (texture); + GstVaapiTextureGLXPrivate *texture_glx = + gst_vaapi_texture_get_private (texture); + Display *const dpy = + GST_VAAPI_DISPLAY_NATIVE (GST_VAAPI_TEXTURE_DISPLAY (texture)); GLContextState old_cs; gboolean success = FALSE; gl_get_current_context (&old_cs); - texture->gl_context = gl_create_context (dpy, DefaultScreen (dpy), &old_cs); - if (!texture->gl_context || - !gl_set_current_context (texture->gl_context, NULL)) + texture_glx->gl_context = + gl_create_context (dpy, DefaultScreen (dpy), &old_cs); + if (!texture_glx->gl_context + || !gl_set_current_context (texture_glx->gl_context, NULL)) return FALSE; - texture->pixo = gl_create_pixmap_object (dpy, - base_texture->width, base_texture->height); - if (!texture->pixo) { + texture_glx->pixo = gl_create_pixmap_object (dpy, + texture->width, texture->height); + if (!texture_glx->pixo) { GST_ERROR ("failed to create GLX pixmap"); goto out_reset_context; } - texture->fbo = gl_create_framebuffer_object (base_texture->gl_target, - texture_id, base_texture->width, base_texture->height); - if (!texture->fbo) { + texture_glx->fbo = gl_create_framebuffer_object (texture->gl_target, + texture_id, texture->width, texture->height); + if (!texture_glx->fbo) { GST_ERROR ("failed to create FBO"); goto out_reset_context; } @@ -175,7 +170,7 @@ create_texture_unlocked (GstVaapiTexture * texture) return FALSE; GST_VAAPI_TEXTURE_ID (texture) = texture_id; } - return create_objects (GST_VAAPI_TEXTURE_GLX (texture), texture_id); + return create_objects (texture, texture_id); } static gboolean @@ -183,29 +178,37 @@ gst_vaapi_texture_glx_create (GstVaapiTexture * texture) { gboolean success; - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); success = create_texture_unlocked (texture); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); return success; } -static void -gst_vaapi_texture_glx_class_init (GstVaapiTextureGLXClass * klass) + +static GstVaapiTexture * +gst_vaapi_texture_glx_new_internal (GstVaapiTexture * texture) { - GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); - GstVaapiTextureClass *const texture_class = GST_VAAPI_TEXTURE_CLASS (klass); + GstVaapiTextureGLXPrivate *texture_glx; - object_class->finalize = (GstVaapiObjectFinalizeFunc) - gst_vaapi_texture_glx_destroy; + texture->put_surface = gst_vaapi_texture_glx_put_surface; - texture_class->allocate = gst_vaapi_texture_glx_create; - texture_class->put_surface = gst_vaapi_texture_glx_put_surface; + texture_glx = g_malloc0 (sizeof (GstVaapiTextureGLXPrivate)); + if (!texture_glx) { + gst_mini_object_unref (GST_MINI_OBJECT_CAST (texture)); + return NULL; + } + texture_glx->texture = texture; + gst_vaapi_texture_set_private (texture, texture_glx, + (GDestroyNotify) gst_vaapi_texture_glx_destroy); + + if (!gst_vaapi_texture_glx_create (texture)) { + gst_mini_object_unref (GST_MINI_OBJECT_CAST (texture)); + return NULL; + } + + return texture; } -#define gst_vaapi_texture_glx_finalize gst_vaapi_texture_glx_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiTextureGLX, - gst_vaapi_texture_glx, gst_vaapi_texture_glx_class_init (&g_class)); - /** * gst_vaapi_texture_glx_new: * @display: a #GstVaapiDisplay @@ -229,11 +232,16 @@ GstVaapiTexture * gst_vaapi_texture_glx_new (GstVaapiDisplay * display, guint target, guint format, guint width, guint height) { + GstVaapiTexture *texture; + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); - return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS - (gst_vaapi_texture_glx_class ()), display, GST_VAAPI_ID_INVALID, target, - format, width, height); + texture = gst_vaapi_texture_new_internal (display, GST_VAAPI_ID_INVALID, + target, format, width, height); + if (!texture) + return NULL; + + return gst_vaapi_texture_glx_new_internal (texture); } /* Can we assume that the vsink/app context API won't change ever? */ @@ -278,6 +286,7 @@ gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display, GLTextureState ts = { 0, }; gboolean success; GstVaapiGLApi gl_api; + GstVaapiTexture *texture; g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); g_return_val_if_fail (texture_id != GL_NONE, NULL); @@ -312,9 +321,12 @@ gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display, g_return_val_if_fail (width > 0, NULL); g_return_val_if_fail (height > 0, NULL); - return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS - (gst_vaapi_texture_glx_class ()), display, texture_id, target, format, - width, height); + texture = gst_vaapi_texture_new_internal (display, texture_id, target, + format, width, height); + if (!texture) + return NULL; + + return gst_vaapi_texture_glx_new_internal (texture); } /** @@ -330,10 +342,11 @@ gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display, * Return value: %TRUE on success */ static gboolean -gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture, +gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * texture, GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags) { - GstVaapiTextureGLX *const texture = GST_VAAPI_TEXTURE_GLX (base_texture); + GstVaapiTextureGLXPrivate *texture_glx = + gst_vaapi_texture_get_private (texture); VAStatus status; GLContextState old_cs; gboolean success = FALSE; @@ -344,19 +357,19 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture, {1.0f, 0.0f}, }; - status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture), - GST_VAAPI_SURFACE_ID (surface), texture->pixo->pixmap, - crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height, - 0, 0, base_texture->width, base_texture->height, - NULL, 0, from_GstVaapiSurfaceRenderFlags (flags)); + status = vaPutSurface (GST_VAAPI_DISPLAY_VADISPLAY (GST_VAAPI_TEXTURE_DISPLAY + (texture)), GST_VAAPI_SURFACE_ID (surface), texture_glx->pixo->pixmap, + crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height, 0, 0, + texture->width, texture->height, NULL, 0, + from_GstVaapiSurfaceRenderFlags (flags)); if (!vaapi_check_status (status, "vaPutSurface() [TFP]")) return FALSE; - if (texture->gl_context && - !gl_set_current_context (texture->gl_context, &old_cs)) + if (texture_glx->gl_context && + !gl_set_current_context (texture_glx->gl_context, &old_cs)) return FALSE; - if (!gl_bind_framebuffer_object (texture->fbo)) { + if (!gl_bind_framebuffer_object (texture_glx->fbo)) { GST_ERROR ("failed to bind FBO"); goto out_reset_context; } @@ -366,12 +379,12 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture, goto out_unbind_fbo; } - if (!gl_bind_pixmap_object (texture->pixo)) { + if (!gl_bind_pixmap_object (texture_glx->pixo)) { GST_ERROR ("could not bind GLX pixmap"); goto out_unbind_fbo; } - flags = GST_VAAPI_TEXTURE_FLAGS (texture); + flags = GST_MINI_OBJECT_FLAGS (texture); txc = g_texcoords[! !(flags & GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED)]; tyc = g_texcoords[! !(flags & GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED)]; @@ -381,25 +394,25 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture, glTexCoord2f (txc[0], tyc[0]); glVertex2i (0, 0); glTexCoord2f (txc[0], tyc[1]); - glVertex2i (0, base_texture->height); + glVertex2i (0, texture->height); glTexCoord2f (txc[1], tyc[1]); - glVertex2i (base_texture->width, base_texture->height); + glVertex2i (texture->width, texture->height); glTexCoord2f (txc[1], tyc[0]); - glVertex2i (base_texture->width, 0); + glVertex2i (texture->width, 0); } glEnd (); - if (!gl_unbind_pixmap_object (texture->pixo)) { + if (!gl_unbind_pixmap_object (texture_glx->pixo)) { GST_ERROR ("failed to release GLX pixmap"); goto out_unbind_fbo; } success = TRUE; out_unbind_fbo: - if (!gl_unbind_framebuffer_object (texture->fbo)) + if (!gl_unbind_framebuffer_object (texture_glx->fbo)) success = FALSE; out_reset_context: - if (texture->gl_context && !gl_set_current_context (&old_cs, NULL)) + if (texture_glx->gl_context && !gl_set_current_context (&old_cs, NULL)) success = FALSE; return success; } @@ -410,9 +423,9 @@ gst_vaapi_texture_glx_put_surface (GstVaapiTexture * texture, { gboolean success; - GST_VAAPI_OBJECT_LOCK_DISPLAY (texture); + GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); success = gst_vaapi_texture_glx_put_surface_unlocked (texture, surface, crop_rect, flags); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture); + GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture)); return success; } diff --git a/gst-libs/gst/vaapi/gstvaapitexture_priv.h b/gst-libs/gst/vaapi/gstvaapitexture_priv.h index 3b65236a52..1b675efa92 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_priv.h +++ b/gst-libs/gst/vaapi/gstvaapitexture_priv.h @@ -26,14 +26,19 @@ #define GST_VAAPI_TEXTURE_PRIV_H #include "gstvaapiobject_priv.h" +#include G_BEGIN_DECLS -#define GST_VAAPI_TEXTURE_CLASS(klass) \ - ((GstVaapiTextureClass *)(klass)) - -#define GST_VAAPI_TEXTURE_GET_CLASS(obj) \ - GST_VAAPI_TEXTURE_CLASS (GST_VAAPI_OBJECT_GET_CLASS (obj)) +/** + * GST_VAAPI_TEXTURE_DISPLAY: + * @texture: a #GstVaapiTexture + * + * Macro that evaluates to the @texture's display. + */ +#undef GST_VAAPI_TEXTURE_DISPLAY +#define GST_VAAPI_TEXTURE_DISPLAY(texture) \ + (GST_VAAPI_TEXTURE (texture)->display) /** * GST_VAAPI_TEXTURE_ID: @@ -43,7 +48,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_TEXTURE_ID #define GST_VAAPI_TEXTURE_ID(texture) \ - (GST_VAAPI_OBJECT_ID (texture)) + (GST_VAAPI_TEXTURE (texture)->object_id) /** * GST_VAAPI_TEXTURE_TARGET: @@ -85,18 +90,9 @@ G_BEGIN_DECLS #define GST_VAAPI_TEXTURE_HEIGHT(texture) \ (GST_VAAPI_TEXTURE (texture)->height) -#define GST_VAAPI_TEXTURE_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS -#define GST_VAAPI_TEXTURE_FLAG_IS_SET GST_VAAPI_MINI_OBJECT_FLAG_IS_SET -#define GST_VAAPI_TEXTURE_FLAG_SET GST_VAAPI_MINI_OBJECT_FLAG_SET -#define GST_VAAPI_TEXTURE_FLAG_UNSET GST_VAAPI_MINI_OBJECT_FLAG_UNSET - /* GstVaapiTextureClass hooks */ -typedef gboolean (*GstVaapiTextureAllocateFunc) (GstVaapiTexture * texture); typedef gboolean (*GstVaapiTexturePutSurfaceFunc) (GstVaapiTexture * texture, - GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, - guint flags); - -typedef struct _GstVaapiTextureClass GstVaapiTextureClass; + GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags); /** * GstVaapiTexture: @@ -105,9 +101,12 @@ typedef struct _GstVaapiTextureClass GstVaapiTextureClass; */ struct _GstVaapiTexture { /*< private >*/ - GstVaapiObject parent_instance; + GstMiniObject mini_object; + GstVaapiDisplay *display; + GstVaapiID object_id; /*< protected >*/ + GstVaapiTexturePutSurfaceFunc put_surface; guint gl_target; guint gl_format; guint width; @@ -115,25 +114,16 @@ struct _GstVaapiTexture { guint is_wrapped:1; }; -/** - * GstVaapiTextureClass: - * @put_surface: virtual function to render a #GstVaapiSurface into a texture - * - * Base class for API-dependent textures. - */ -struct _GstVaapiTextureClass { - /*< private >*/ - GstVaapiObjectClass parent_class; - - /*< protected >*/ - GstVaapiTextureAllocateFunc allocate; - GstVaapiTexturePutSurfaceFunc put_surface; -}; - GstVaapiTexture * -gst_vaapi_texture_new_internal (const GstVaapiTextureClass * klass, - GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, - guint width, guint height); +gst_vaapi_texture_new_internal (GstVaapiDisplay * display, GstVaapiID id, + guint target, guint format, guint width, guint height); + +gpointer +gst_vaapi_texture_get_private (GstVaapiTexture * texture); + +void +gst_vaapi_texture_set_private (GstVaapiTexture * texture, gpointer priv, + GDestroyNotify destroy); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapitexturemap.c b/gst-libs/gst/vaapi/gstvaapitexturemap.c index 0a17bac9fb..1ca7638380 100644 --- a/gst-libs/gst/vaapi/gstvaapitexturemap.c +++ b/gst-libs/gst/vaapi/gstvaapitexturemap.c @@ -62,7 +62,7 @@ gst_vaapi_texture_map_init (GstVaapiTextureMap * map) { map->texture_map = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, - (GDestroyNotify) gst_vaapi_texture_unref); + (GDestroyNotify) gst_mini_object_unref); } static void diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c index 1261fc1c2c..46bb2f9428 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_egl.c @@ -139,8 +139,9 @@ ensure_texture (GstVaapiWindowEGL * window, guint width, guint height) texture = gst_vaapi_texture_egl_new (GST_VAAPI_WINDOW_DISPLAY (window), GL_TEXTURE_2D, GL_RGBA, width, height); - gst_vaapi_texture_replace (&window->texture, texture); - gst_vaapi_texture_replace (&texture, NULL); + gst_mini_object_replace ((GstMiniObject **) & window->texture, + (GstMiniObject *) texture); + gst_mini_object_replace ((GstMiniObject **) & texture, NULL); return window->texture != NULL; } @@ -287,7 +288,7 @@ gst_vaapi_window_egl_finalize (GObject * object) } gst_vaapi_window_replace (&window->window, NULL); - gst_vaapi_texture_replace (&window->texture, NULL); + gst_mini_object_replace ((GstMiniObject **) & window->texture, NULL); G_OBJECT_CLASS (gst_vaapi_window_egl_parent_class)->finalize (object); } @@ -385,7 +386,7 @@ gst_vaapi_window_egl_resize (GstVaapiWindow * window, guint width, guint height) static gboolean do_render_texture (GstVaapiWindowEGL * window, const GstVaapiRectangle * rect) { - const GLuint tex_id = GST_VAAPI_OBJECT_ID (window->texture); + const GLuint tex_id = GST_VAAPI_TEXTURE_ID (window->texture); EglVTable *const vtable = window->egl_vtable; GLfloat x0, y0, x1, y1; GLfloat texcoords[4][2]; diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 68da63f0a0..f840de78b3 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -125,7 +125,7 @@ meta_texture_free (GstVaapiVideoMetaTexture * meta) if (G_UNLIKELY (!meta)) return; - gst_vaapi_texture_replace (&meta->texture, NULL); + gst_mini_object_replace ((GstMiniObject **) & meta->texture, NULL); g_slice_free (GstVaapiVideoMetaTexture, meta); } @@ -164,7 +164,9 @@ meta_texture_copy (GstVaapiVideoMetaTexture * meta) copy->gl_format = meta->gl_format; copy->width = meta->width; copy->height = meta->height; - gst_vaapi_texture_replace (©->texture, meta->texture); + + gst_mini_object_replace ((GstMiniObject **) & copy->texture, + (GstMiniObject *) meta->texture); return copy; } @@ -186,8 +188,7 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, if (meta_texture->texture /* Check whether VA display changed */ - && gst_vaapi_object_get_display - (GST_VAAPI_OBJECT (meta_texture->texture)) == dpy + && GST_VAAPI_TEXTURE_DISPLAY (meta_texture->texture) == dpy /* Check whether texture id changed */ && (gst_vaapi_texture_get_id (meta_texture->texture) == texture_id[0])) { texture = meta_texture->texture; @@ -202,7 +203,8 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, } if (meta_texture->texture != texture) { - gst_vaapi_texture_replace (&meta_texture->texture, texture); + gst_mini_object_replace ((GstMiniObject **) & meta_texture->texture, + (GstMiniObject *) texture); } if (!texture) diff --git a/tests/internal/test-textures.c b/tests/internal/test-textures.c index 46e2b91609..0f7e1e9270 100644 --- a/tests/internal/test-textures.c +++ b/tests/internal/test-textures.c @@ -168,8 +168,8 @@ main (int argc, char *argv[]) gst_vaapi_window_glx_swap_buffers (glx_window); pause (); - gst_vaapi_texture_unref (textures[0]); - gst_vaapi_texture_unref (textures[1]); + gst_mini_object_unref (GST_MINI_OBJECT_CAST (textures[0])); + gst_mini_object_unref (GST_MINI_OBJECT_CAST (textures[1])); glDeleteTextures (1, &texture_id); gst_object_unref (window); From e20d06e64df9546946231a5c0d28430c66156735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 16 May 2020 19:58:25 +0200 Subject: [PATCH 3581/3781] libs: removed duplicated function declarations Some headers had duplicated inlined function declaration. This was for gtkdoc, but now GStreamer uses hotdoc and the internal library documentation is not generated. So let's remove these extra lines. Part-of: --- gst-libs/gst/vaapi/gstvaapicodedbuffer.h | 1 - gst-libs/gst/vaapi/gstvaapiimage.h | 1 - gst-libs/gst/vaapi/gstvaapisurface.h | 1 - 3 files changed, 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodedbuffer.h b/gst-libs/gst/vaapi/gstvaapicodedbuffer.h index e84f57b88e..bee4cc4f5b 100644 --- a/gst-libs/gst/vaapi/gstvaapicodedbuffer.h +++ b/gst-libs/gst/vaapi/gstvaapicodedbuffer.h @@ -54,7 +54,6 @@ gst_vaapi_coded_buffer_get_type (void) G_GNUC_CONST; * 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); static inline void gst_vaapi_coded_buffer_unref (GstVaapiCodedBuffer * buf) { diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 5f8305d5cc..5ab6f74ca3 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -103,7 +103,6 @@ gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image); * Decreases the refcount of the image. If the refcount reaches 0, the * image will be freed. */ -static inline void gst_vaapi_image_unref(GstVaapiImage* image); static inline void gst_vaapi_image_unref (GstVaapiImage * image) { diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index 68f99ff2ed..f702a09e67 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -201,7 +201,6 @@ gst_vaapi_surface_get_type (void) G_GNUC_CONST; * Decreases the refcount of the surface. If the refcount reaches 0, the * surface will be freed. */ -static inline void gst_vaapi_surface_unref(GstVaapiSurface* surface); static inline void gst_vaapi_surface_unref (GstVaapiSurface * surface) { From 5d56ce69277c844d10d54b2dfd278cd44ca79db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 16 May 2020 21:03:32 +0200 Subject: [PATCH 3582/3781] libs: texture: remove unused headers include This is continuation of https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/317 Part-of: --- gst-libs/gst/vaapi/gstvaapitexture.c | 1 + gst-libs/gst/vaapi/gstvaapitexture_priv.h | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 1fe9e2cf4f..9bfc87bb28 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -28,6 +28,7 @@ */ #include "sysdeps.h" +#include "gstvaapidisplay_priv.h" #include "gstvaapitexture.h" #include "gstvaapitexture_priv.h" diff --git a/gst-libs/gst/vaapi/gstvaapitexture_priv.h b/gst-libs/gst/vaapi/gstvaapitexture_priv.h index 1b675efa92..e22df90f7e 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_priv.h +++ b/gst-libs/gst/vaapi/gstvaapitexture_priv.h @@ -25,9 +25,6 @@ #ifndef GST_VAAPI_TEXTURE_PRIV_H #define GST_VAAPI_TEXTURE_PRIV_H -#include "gstvaapiobject_priv.h" -#include - G_BEGIN_DECLS /** From 2b1809e9d384c143487ef6065af0cf0112669b06 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 Apr 2020 21:21:43 +0800 Subject: [PATCH 3583/3781] libs: video-format: add a helper function of get_formats_by_chroma. The function iterates all supported video formats and returns the formats belong to the specified chroma type. Part-of: --- gst-libs/gst/vaapi/video-format.c | 33 +++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/video-format.h | 3 +++ 2 files changed, 36 insertions(+) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 5ebb211ccb..6c1e8e7f5d 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -476,6 +476,39 @@ gst_vaapi_video_format_get_best_native (GstVideoFormat format) return gst_vaapi_video_format_from_chroma (chroma_type); } +/** + * gst_vaapi_video_format_get_formats_by_chroma: + * @chroma: a #GstVaapiChromaType + * + * Get all #GstVideoFormat which belong to #GstVaapiChromaType. + * + * Returns: an array of #GstVideoFormat. + **/ +GArray * +gst_vaapi_video_format_get_formats_by_chroma (guint chroma) +{ + const GstVideoFormatMap *entry; + GArray *formats; + guint i; + + formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat)); + if (!formats) + return NULL; + + for (i = 0; i < gst_vaapi_video_formats_map->len; i++) { + entry = &g_array_index (gst_vaapi_video_formats_map, GstVideoFormatMap, i); + if (entry->chroma_type == chroma) + g_array_append_val (formats, entry->format); + } + + if (formats->len == 0) { + g_array_unref (formats); + return NULL; + } + + return formats; +} + struct ImageFormatsData { VAImageFormat *formats; diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index 466e115a2d..953194e559 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -64,6 +64,9 @@ gst_vaapi_video_format_from_chroma (guint chroma); GstVideoFormat gst_vaapi_video_format_get_best_native (GstVideoFormat format); +GArray * +gst_vaapi_video_format_get_formats_by_chroma (guint chroma); + gboolean gst_vaapi_video_format_create_map (VAImageFormat * formats, guint n); From 3583a4b86cc8a9398939ec84fbee8ca370a54ed1 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 Apr 2020 21:27:32 +0800 Subject: [PATCH 3584/3781] plugin: encode: extract the allowed caps maker as a helper function. Extract all logic about making caps for encode's sink as a standalone helper function. It can be reused. Part-of: --- gst/vaapi/gstvaapiencode.c | 42 ++++-------------------- gst/vaapi/gstvaapipluginutil.c | 59 ++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 5 +++ 3 files changed, 70 insertions(+), 36 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 2cf7582839..7671170d42 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -358,13 +358,9 @@ static gboolean ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) { GstCaps *out_caps = NULL; - GstCaps *raw_caps = NULL; - GstCaps *va_caps, *dma_caps; GArray *formats = NULL; gboolean ret = FALSE; GArray *profiles = NULL; - guint i, size; - GstStructure *structure; gint min_width, min_height, max_width, max_height; guint mem_types; @@ -385,34 +381,10 @@ ensure_allowed_sinkpad_caps (GstVaapiEncode * encode) if (!formats) goto failed_get_attributes; - raw_caps = gst_vaapi_video_format_new_template_caps_from_list (formats); - if (!raw_caps) - goto failed_create_raw_caps; - - /* Set the width/height info to caps */ - size = gst_caps_get_size (raw_caps); - for (i = 0; i < size; i++) { - structure = gst_caps_get_structure (raw_caps, i); - if (!structure) - continue; - gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, min_width, - max_width, "height", GST_TYPE_INT_RANGE, min_height, max_height, NULL); - } - - out_caps = gst_caps_copy (raw_caps); - - va_caps = gst_caps_copy (raw_caps); - gst_caps_set_features_simple (va_caps, - gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE)); - gst_caps_append (out_caps, va_caps); - - if (gst_vaapi_mem_type_supports (mem_types, - GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF)) { - dma_caps = gst_caps_copy (raw_caps); - gst_caps_set_features_simple (dma_caps, - gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF)); - gst_caps_append (out_caps, dma_caps); - } + out_caps = gst_vaapi_build_caps_from_formats (formats, min_width, min_height, + max_width, max_height, mem_types); + if (!out_caps) + goto failed_create_caps; gst_caps_replace (&encode->allowed_sinkpad_caps, out_caps); GST_INFO_OBJECT (encode, "Allowed sink caps %" GST_PTR_FORMAT, @@ -428,8 +400,6 @@ bail: g_array_unref (profiles); if (out_caps) gst_caps_unref (out_caps); - if (raw_caps) - gst_caps_unref (raw_caps); if (formats) g_array_unref (formats); return ret; @@ -439,9 +409,9 @@ failed_get_attributes: GST_WARNING_OBJECT (encode, "failed to get surface attributes"); goto bail; } -failed_create_raw_caps: +failed_create_caps: { - GST_WARNING_OBJECT (encode, "failed to create raw sink caps"); + GST_WARNING_OBJECT (encode, "failed to create sink caps"); goto bail; } failed_get_profiles: diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ba89b4a7a6..ce3179d5aa 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -24,6 +24,7 @@ #include "gstcompat.h" #include "gstvaapivideocontext.h" +#include #if USE_DRM # include #endif @@ -1079,3 +1080,61 @@ gst_vaapi_h26x_encoder_get_profiles_from_caps (GstCaps * caps, return profiles; } + +/** + * gst_vaapi_build_caps_from_formats: + * @formats: an array of supported #GstVideoFormat + * @min_width: the min supported width + * @min_height: the min supported height + * @max_width: the max supported width + * @max_height: the max supported height + * @mem_types: the supported VA mem types + * + * This function generates a #GstCaps based on the information such as + * formats, width and height. + * + * Return: A #GstCaps. + **/ +GstCaps * +gst_vaapi_build_caps_from_formats (GArray * formats, gint min_width, + gint min_height, gint max_width, gint max_height, guint mem_types) +{ + GstCaps *out_caps = NULL; + GstCaps *raw_caps = NULL; + GstCaps *va_caps, *dma_caps; + guint i, size; + GstStructure *structure; + + raw_caps = gst_vaapi_video_format_new_template_caps_from_list (formats); + if (!raw_caps) + return NULL; + + /* Set the width/height info to caps */ + size = gst_caps_get_size (raw_caps); + for (i = 0; i < size; i++) { + structure = gst_caps_get_structure (raw_caps, i); + if (!structure) + continue; + gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, min_width, + max_width, "height", GST_TYPE_INT_RANGE, min_height, max_height, NULL); + } + + out_caps = gst_caps_copy (raw_caps); + + va_caps = gst_caps_copy (raw_caps); + gst_caps_set_features_simple (va_caps, + gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE)); + gst_caps_append (out_caps, va_caps); + + if (gst_vaapi_mem_type_supports (mem_types, + GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF)) { + dma_caps = gst_caps_copy (raw_caps); + gst_caps_set_features_simple (dma_caps, + gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF)); + gst_caps_append (out_caps, dma_caps); + } + + gst_caps_unref (raw_caps); + + return out_caps; +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 8ceb7ee167..99b6e13344 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -160,4 +160,9 @@ GArray * gst_vaapi_h26x_encoder_get_profiles_from_caps (GstCaps * caps, GstVaapiStrToProfileFunc func); +G_GNUC_INTERNAL +GstCaps * +gst_vaapi_build_caps_from_formats (GArray * formats, gint min_width, + gint min_height, gint max_width, gint max_height, guint mem_type); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ From 0e4c7509187c43661474e52f8013816bb5e235cd Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 Apr 2020 21:44:05 +0800 Subject: [PATCH 3585/3781] plugins: util: Add a helper function to detect supported caps. This helper function iterate all profiles and entrypoints belong to the specified codec, query the VAConfigAttribRTFormat and list all possible video formats. This function is used by each codec to get the template sink caps (for encode) or src caps(for decode) at register time, when just all possible formats are listed and no need to be very accurate. So there is no context created for the performance reason. Most codecs just use YUV kinds of formats as the input/output, so we do not include RGB kinds of formats. User can specified more formats in extra_fmts(For example, jpeg may need BGRA) if needed. Part-of: --- gst/vaapi/gstvaapipluginutil.c | 105 +++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 6 ++ 2 files changed, 111 insertions(+) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ce3179d5aa..0e55640f12 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -25,6 +25,7 @@ #include "gstcompat.h" #include "gstvaapivideocontext.h" #include +#include #if USE_DRM # include #endif @@ -1138,3 +1139,107 @@ gst_vaapi_build_caps_from_formats (GArray * formats, gint min_width, return out_caps; } + +/** + * gst_vaapi_build_template_caps_by_codec: + * @display: a #GstVaapiDisplay + * @usage: used for encode, decode or postproc + * @codec: a #GstVaapiCodec specify the codec to detect + * @extra_fmts: a #GArray of extra #GstVideoFormat + * + * Called by vaapi elements to detect the all possible video formats belong to + * the specified codec and build the caps. Only YUV kinds of formats are detected + * because so far almost all codecs use YUV kinds of formats as input/output. + * extra_fmts can specified more formats to be included. + * + * Returns: a built #GstCaps if succeeds, or %NULL if error. + **/ +GstCaps * +gst_vaapi_build_template_caps_by_codec (GstVaapiDisplay * display, + GstVaapiContextUsage usage, GstVaapiCodec codec, GArray * extra_fmts) +{ + GArray *profiles = NULL; + GArray *supported_fmts = NULL; + GstCaps *out_caps = NULL; + guint i, e; + GstVaapiProfile profile; + guint value; + guint chroma; + GstVaapiChromaType gst_chroma; + GstVaapiEntrypoint entrypoint_start, entrypoint_end; + + if (usage == GST_VAAPI_CONTEXT_USAGE_ENCODE) { + profiles = gst_vaapi_display_get_encode_profiles (display); + entrypoint_start = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + entrypoint_end = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP; + } else if (usage == GST_VAAPI_CONTEXT_USAGE_DECODE) { + profiles = gst_vaapi_display_get_decode_profiles (display); + entrypoint_start = GST_VAAPI_ENTRYPOINT_VLD; + entrypoint_end = GST_VAAPI_ENTRYPOINT_MOCO; + } + /* TODO: VPP */ + + if (!profiles) + goto out; + + chroma = 0; + for (i = 0; i < profiles->len; i++) { + profile = g_array_index (profiles, GstVaapiProfile, i); + if (gst_vaapi_profile_get_codec (profile) != codec) + continue; + + for (e = entrypoint_start; e <= entrypoint_end; e++) { + if (!gst_vaapi_get_config_attribute (display, + gst_vaapi_profile_get_va_profile (profile), + gst_vaapi_entrypoint_get_va_entrypoint (e), + VAConfigAttribRTFormat, &value)) + continue; + + chroma |= value; + } + } + + if (!chroma) + goto out; + + for (gst_chroma = GST_VAAPI_CHROMA_TYPE_YUV420; + gst_chroma <= GST_VAAPI_CHROMA_TYPE_YUV444_12BPP; gst_chroma++) { + GArray *fmts; + if (!(chroma & from_GstVaapiChromaType (gst_chroma))) + continue; + + fmts = gst_vaapi_video_format_get_formats_by_chroma (gst_chroma); + if (!fmts) + continue; + + /* One format can not belong to different chroma, no need to merge */ + if (supported_fmts == NULL) { + supported_fmts = fmts; + } else { + for (i = 0; i < fmts->len; i++) + g_array_append_val (supported_fmts, + g_array_index (fmts, GstVideoFormat, i)); + g_array_unref (fmts); + } + } + + if (!supported_fmts) + goto out; + + if (extra_fmts) { + for (i = 0; i < extra_fmts->len; i++) + g_array_append_val (supported_fmts, + g_array_index (extra_fmts, GstVideoFormat, i)); + } + + out_caps = gst_vaapi_build_caps_from_formats (supported_fmts, 1, 1, + G_MAXINT, G_MAXINT, TRUE); + +out: + if (profiles) + g_array_unref (profiles); + if (supported_fmts) + g_array_unref (supported_fmts); + + return out_caps; +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 99b6e13344..abdaf1e95f 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -27,6 +27,7 @@ #include #include +#include #include "gstvaapivideomemory.h" typedef GstVaapiProfile (*GstVaapiStrToProfileFunc) (const gchar * str); @@ -165,4 +166,9 @@ GstCaps * gst_vaapi_build_caps_from_formats (GArray * formats, gint min_width, gint min_height, gint max_width, gint max_height, guint mem_type); +G_GNUC_INTERNAL +GstCaps * +gst_vaapi_build_template_caps_by_codec (GstVaapiDisplay * display, + GstVaapiContextUsage usage, GstVaapiCodec codec, GArray * extra_fmts); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ From 3b3e9872370f8d686864ffaa6b9f28195fb3faa9 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 23 Apr 2020 00:02:02 +0800 Subject: [PATCH 3586/3781] plugin: encode: add a helper macro to register encode type. Part-of: --- gst/vaapi/gstvaapiencode.h | 78 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 176f32e653..0e76bded70 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -44,6 +44,84 @@ G_BEGIN_DECLS #define GST_IS_VAAPIENCODE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE)) +#define GST_VAAPI_ENCODE_REGISTER_TYPE(NAME, CODEC, CLASS, _EXT_FMT_) \ + static GType encode_type = G_TYPE_INVALID; \ + static gpointer gst_vaapiencode_##NAME##_parent_class = NULL; \ + static void \ + gst_vaapiencode_##NAME##_class_init ( \ + GstVaapiEncode##CLASS##Class * klass, gpointer data); \ + static void gst_vaapiencode_##NAME##_class_intern_init (gpointer klass, \ + gpointer data) \ + { \ + gst_vaapiencode_##NAME##_parent_class = \ + g_type_class_peek_parent (klass); \ + gst_vaapiencode_##NAME##_class_init (klass, data); \ + } \ + static void \ + gst_vaapiencode_##NAME##_init (GstVaapiEncode##CLASS * encode); \ + GType \ + gst_vaapiencode_##NAME##_register_type (GstVaapiDisplay * display) \ + { \ + GstCaps *caps; \ + guint i, n; \ + GTypeInfo type_info = { \ + sizeof (GstVaapiEncodeClass), \ + NULL, \ + NULL, \ + (GClassInitFunc) gst_vaapiencode_##NAME##_class_intern_init, \ + NULL, \ + NULL, \ + sizeof (GstVaapiEncode##CLASS), \ + 0, \ + (GInstanceInitFunc) gst_vaapiencode_##NAME##_init, \ + }; \ + GArray *extra_fmts = NULL; \ + GstVideoFormat ext_video_fmts[] = _EXT_FMT_; \ + \ + GST_DEBUG_CATEGORY_INIT (gst_vaapi_##NAME##_encode_debug, \ + GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); \ + \ + if ((n = G_N_ELEMENTS (ext_video_fmts))) { \ + extra_fmts = \ + g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), n); \ + for (i = 0; i < n; i++) \ + g_array_append_val (extra_fmts, ext_video_fmts[i]); \ + } \ + caps = gst_vaapi_build_template_caps_by_codec (display, \ + GST_VAAPI_CONTEXT_USAGE_ENCODE, \ + GST_VAAPI_CODEC_##CODEC, extra_fmts); \ + g_clear_pointer (&extra_fmts, g_array_unref); \ + if (!caps) { \ + GST_ERROR ("failed to get sink caps for " #CODEC \ + " encode, can not register"); \ + return G_TYPE_INVALID; \ + } \ + \ + for (i = 0; i < gst_caps_get_size (caps); i++) { \ + GstStructure *structure = gst_caps_get_structure (caps, i); \ + if (!structure) \ + continue; \ + gst_structure_set (structure, "interlace-mode", G_TYPE_STRING, \ + "progressive", NULL); \ + } \ + GST_DEBUG (#CODEC" encode's sink caps %" GST_PTR_FORMAT, caps); \ + \ + /* class data will be leaked if the element never gets instantiated */ \ + GST_MINI_OBJECT_FLAG_SET (caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED); \ + type_info.class_data = caps; \ + encode_type = g_type_register_static (GST_TYPE_VAAPIENCODE, \ + "GstVaapiEncode"#CLASS, &type_info, 0); \ + \ + return encode_type; \ + } \ + \ + GType \ + gst_vaapiencode_##NAME##_get_type (void) \ + { \ + g_assert (encode_type != G_TYPE_INVALID); \ + return encode_type; \ + } + typedef struct _GstVaapiEncode GstVaapiEncode; typedef struct _GstVaapiEncodeClass GstVaapiEncodeClass; From d674d457ab0031aabb6c75671d50863acb6f6147 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 Apr 2020 22:11:34 +0800 Subject: [PATCH 3587/3781] plugins: encode: Modify sink template of jpeg encode. Use gst_vaapi_detect_codec_caps to get more precise template caps. Also implement gst_vaapiencode_jpeg_register_type, which should be called at plugin register time. Part-of: --- gst/vaapi/gstvaapiencode_jpeg.c | 34 +++++++++------------------------ gst/vaapi/gstvaapiencode_jpeg.h | 3 +++ 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 34a0efd000..e6ae27870f 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -49,29 +49,11 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_jpeg_encode_debug); #define GST_CODEC_CAPS \ "image/jpeg" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_jpeg_sink_caps_str[] = - GST_VAAPI_MAKE_SURFACE_CAPS ", " - GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " - GST_CAPS_INTERLACED_FALSE ";" - GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," - GST_CAPS_INTERLACED_FALSE; -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static const char gst_vaapiencode_jpeg_src_caps_str[] = GST_CODEC_CAPS; /* *INDENT-ON* */ -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_jpeg_sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_jpeg_sink_caps_str)); -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapiencode_jpeg_src_factory = GST_STATIC_PAD_TEMPLATE ("src", @@ -80,8 +62,10 @@ static GstStaticPadTemplate gst_vaapiencode_jpeg_src_factory = GST_STATIC_CAPS (gst_vaapiencode_jpeg_src_caps_str)); /* *INDENT-ON* */ +#define EXTRA_FORMATS { GST_VIDEO_FORMAT_BGRA, } + /* jpeg encode */ -G_DEFINE_TYPE (GstVaapiEncodeJpeg, gst_vaapiencode_jpeg, GST_TYPE_VAAPIENCODE); +GST_VAAPI_ENCODE_REGISTER_TYPE (jpeg, JPEG, Jpeg, EXTRA_FORMATS); static void gst_vaapiencode_jpeg_init (GstVaapiEncodeJpeg * encode) @@ -113,16 +97,14 @@ gst_vaapiencode_jpeg_alloc_encoder (GstVaapiEncode * base, } static void -gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass) +gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass, gpointer data) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + GstCaps *sink_caps = GST_CAPS_CAST (data); gpointer encoder_class; - GST_DEBUG_CATEGORY_INIT (gst_vaapi_jpeg_encode_debug, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - object_class->finalize = gst_vaapiencode_jpeg_finalize; object_class->set_property = gst_vaapiencode_set_property_subclass; object_class->get_property = gst_vaapiencode_get_property_subclass; @@ -137,8 +119,10 @@ gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass) "Sreerenj Balachandran "); /* sink pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_jpeg_sink_factory); + g_assert (sink_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + gst_caps_unref (sink_caps); /* src pad */ gst_element_class_add_static_pad_template (element_class, diff --git a/gst/vaapi/gstvaapiencode_jpeg.h b/gst/vaapi/gstvaapiencode_jpeg.h index ea5a187332..f0bab68bfc 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.h +++ b/gst/vaapi/gstvaapiencode_jpeg.h @@ -64,6 +64,9 @@ struct _GstVaapiEncodeJpegClass GType gst_vaapiencode_jpeg_get_type (void) G_GNUC_CONST; +GType +gst_vaapiencode_jpeg_register_type (GstVaapiDisplay * display); + G_END_DECLS #endif /* GST_VAAPIENCODE_JPEG_H */ From 53a17f9c986e9ffab0eec3d8d8694f825377766b Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 Apr 2020 22:00:38 +0800 Subject: [PATCH 3588/3781] plugins: encode: Modify sink template of h264 encode. Use gst_vaapi_detect_codec_caps to get more precise template caps. Also implement gst_vaapiencode_h264_register_type, which should be called at plugin register time. Part-of: --- gst/vaapi/gstvaapiencode_h264.c | 34 +++++++++------------------------ gst/vaapi/gstvaapiencode_h264.h | 3 +++ 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 28656a94c9..aabe7bcdeb 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -78,30 +78,12 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); "stream-format = (string) { avc, byte-stream }, " \ "alignment = (string) au" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_h264_sink_caps_str[] = - GST_VAAPI_MAKE_SURFACE_CAPS ", " - GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " - GST_CAPS_INTERLACED_FALSE ";" - GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," - GST_CAPS_INTERLACED_FALSE; -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static const char gst_vaapiencode_h264_src_caps_str[] = GST_CODEC_CAPS ", " "profile = (string) { constrained-baseline, baseline, main, high, multiview-high, stereo-high }"; /* *INDENT-ON* */ -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_h264_sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_h264_sink_caps_str)); -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapiencode_h264_src_factory = GST_STATIC_PAD_TEMPLATE ("src", @@ -110,8 +92,10 @@ static GstStaticPadTemplate gst_vaapiencode_h264_src_factory = GST_STATIC_CAPS (gst_vaapiencode_h264_src_caps_str)); /* *INDENT-ON* */ +#define EXTRA_FORMATS {} + /* h264 encode */ -G_DEFINE_TYPE (GstVaapiEncodeH264, gst_vaapiencode_h264, GST_TYPE_VAAPIENCODE); +GST_VAAPI_ENCODE_REGISTER_TYPE (h264, H264, H264, EXTRA_FORMATS); static void gst_vaapiencode_h264_init (GstVaapiEncodeH264 * encode) @@ -568,16 +552,14 @@ error_convert_buffer: } static void -gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) +gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass, gpointer data) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + GstCaps *sink_caps = GST_CAPS_CAST (data); gpointer encoder_class; - GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encode_debug, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - object_class->finalize = gst_vaapiencode_h264_finalize; object_class->set_property = gst_vaapiencode_set_property_subclass; object_class->get_property = gst_vaapiencode_get_property_subclass; @@ -595,8 +577,10 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass) GST_PLUGIN_DESC, "Wind Yuan "); /* sink pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_h264_sink_factory); + g_assert (sink_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + gst_caps_unref (sink_caps); /* src pad */ gst_element_class_add_static_pad_template (element_class, diff --git a/gst/vaapi/gstvaapiencode_h264.h b/gst/vaapi/gstvaapiencode_h264.h index 46a0e8161a..f59797e22a 100644 --- a/gst/vaapi/gstvaapiencode_h264.h +++ b/gst/vaapi/gstvaapiencode_h264.h @@ -68,6 +68,9 @@ struct _GstVaapiEncodeH264Class GType gst_vaapiencode_h264_get_type (void) G_GNUC_CONST; +GType +gst_vaapiencode_h264_register_type (GstVaapiDisplay * display); + G_END_DECLS #endif /* GST_VAAPIENCODE_H264_H */ From 5f5182f9adf0ceb51d523430b5ae5f119058875f Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 Apr 2020 22:03:49 +0800 Subject: [PATCH 3589/3781] plugins: encode: Modify sink template of h265 encode. Use gst_vaapi_detect_codec_caps to get more precise template caps. Also implement gst_vaapiencode_h265_register_type, which should be called at plugin register time. Part-of: --- gst/vaapi/gstvaapiencode_h265.c | 34 +++++++++------------------------ gst/vaapi/gstvaapiencode_h265.h | 2 ++ 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 00fcf585b3..5b97991b10 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -52,30 +52,12 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h265_encode_debug); "stream-format = (string) { hvc1, byte-stream }, " \ "alignment = (string) au" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_h265_sink_caps_str[] = - GST_VAAPI_MAKE_SURFACE_CAPS ", " - GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " - GST_CAPS_INTERLACED_FALSE ";" - GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," - GST_CAPS_INTERLACED_FALSE; -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static const char gst_vaapiencode_h265_src_caps_str[] = GST_CODEC_CAPS ", " "profile = (string) { main, main-10, main-444, main-444-10 }"; /* *INDENT-ON* */ -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_h265_sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_h265_sink_caps_str)); -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapiencode_h265_src_factory = GST_STATIC_PAD_TEMPLATE ("src", @@ -84,8 +66,10 @@ static GstStaticPadTemplate gst_vaapiencode_h265_src_factory = GST_STATIC_CAPS (gst_vaapiencode_h265_src_caps_str)); /* *INDENT-ON* */ +#define EXTRA_FORMATS {} + /* h265 encode */ -G_DEFINE_TYPE (GstVaapiEncodeH265, gst_vaapiencode_h265, GST_TYPE_VAAPIENCODE); +GST_VAAPI_ENCODE_REGISTER_TYPE (h265, H265, H265, EXTRA_FORMATS); static void gst_vaapiencode_h265_init (GstVaapiEncodeH265 * encode) @@ -361,16 +345,14 @@ error_convert_buffer: } static void -gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass) +gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass, gpointer data) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + GstCaps *sink_caps = GST_CAPS_CAST (data); gpointer encoder_class; - GST_DEBUG_CATEGORY_INIT (gst_vaapi_h265_encode_debug, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - object_class->finalize = gst_vaapiencode_h265_finalize; object_class->set_property = gst_vaapiencode_set_property_subclass; object_class->get_property = gst_vaapiencode_get_property_subclass; @@ -389,8 +371,10 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass) "Sreerenj Balachandran "); /* sink pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_h265_sink_factory); + g_assert (sink_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + gst_caps_unref (sink_caps); /* src pad */ gst_element_class_add_static_pad_template (element_class, diff --git a/gst/vaapi/gstvaapiencode_h265.h b/gst/vaapi/gstvaapiencode_h265.h index db567b3946..4371dcfe1a 100644 --- a/gst/vaapi/gstvaapiencode_h265.h +++ b/gst/vaapi/gstvaapiencode_h265.h @@ -65,6 +65,8 @@ struct _GstVaapiEncodeH265Class GType gst_vaapiencode_h265_get_type (void) G_GNUC_CONST; +GType +gst_vaapiencode_h265_register_type (GstVaapiDisplay * display); G_END_DECLS From 7459bee9794c1f91ea17a63804434228adfc294b Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 Apr 2020 22:04:34 +0800 Subject: [PATCH 3590/3781] plugins: encode: Modify sink template of mpeg2 encode. Use gst_vaapi_detect_codec_caps to get more precise template caps. Also implement gst_vaapiencode_mpeg2_register_type, which should be called at plugin register time. Part-of: --- gst/vaapi/gstvaapiencode_mpeg2.c | 36 +++++++++----------------------- gst/vaapi/gstvaapiencode_mpeg2.h | 3 +++ 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index 06b3458ca8..d898533d11 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -51,29 +51,11 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); "video/mpeg, mpegversion = (int) 2, " \ "systemstream = (boolean) false" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_mpeg2_sink_caps_str[] = - GST_VAAPI_MAKE_SURFACE_CAPS ", " - GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " - GST_CAPS_INTERLACED_FALSE ";" - GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," - GST_CAPS_INTERLACED_FALSE; -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static const char gst_vaapiencode_mpeg2_src_caps_str[] = GST_CODEC_CAPS; /* *INDENT-ON* */ -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_mpeg2_sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_mpeg2_sink_caps_str)); -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapiencode_mpeg2_src_factory = GST_STATIC_PAD_TEMPLATE ("src", @@ -82,9 +64,10 @@ static GstStaticPadTemplate gst_vaapiencode_mpeg2_src_factory = GST_STATIC_CAPS (gst_vaapiencode_mpeg2_src_caps_str)); /* *INDENT-ON* */ +#define EXTRA_FORMATS {} + /* mpeg2 encode */ -G_DEFINE_TYPE (GstVaapiEncodeMpeg2, gst_vaapiencode_mpeg2, - GST_TYPE_VAAPIENCODE); +GST_VAAPI_ENCODE_REGISTER_TYPE (mpeg2, MPEG2, Mpeg2, EXTRA_FORMATS); static void gst_vaapiencode_mpeg2_init (GstVaapiEncodeMpeg2 * encode) @@ -117,16 +100,15 @@ gst_vaapiencode_mpeg2_alloc_encoder (GstVaapiEncode * base, } static void -gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) +gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass, + gpointer data) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + GstCaps *sink_caps = GST_CAPS_CAST (data); gpointer encoder_class; - GST_DEBUG_CATEGORY_INIT (gst_vaapi_mpeg2_encode_debug, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - object_class->finalize = gst_vaapiencode_mpeg2_finalize; object_class->set_property = gst_vaapiencode_set_property_subclass; object_class->get_property = gst_vaapiencode_get_property_subclass; @@ -140,8 +122,10 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) GST_PLUGIN_DESC, "Guangxin Xu "); /* sink pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_mpeg2_sink_factory); + g_assert (sink_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + gst_caps_unref (sink_caps); /* src pad */ gst_element_class_add_static_pad_template (element_class, diff --git a/gst/vaapi/gstvaapiencode_mpeg2.h b/gst/vaapi/gstvaapiencode_mpeg2.h index a2038df62a..a8c765914a 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.h +++ b/gst/vaapi/gstvaapiencode_mpeg2.h @@ -69,6 +69,9 @@ struct _GstVaapiEncodeMpeg2Class GType gst_vaapiencode_mpeg2_get_type (void) G_GNUC_CONST; +GType +gst_vaapiencode_mpeg2_register_type (GstVaapiDisplay * display); + G_END_DECLS #endif /* GST_VAAPIENCODE_MPEG2_H */ From 6ffabe2139cc16b66b8a9d330a1f1cda22b89791 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 Apr 2020 22:05:18 +0800 Subject: [PATCH 3591/3781] plugins: encode: Modify sink template of vp8 encode. Use gst_vaapi_detect_codec_caps to get more precise template caps. Also implement gst_vaapiencode_vp8_register_type, which should be called at plugin register time. Part-of: --- gst/vaapi/gstvaapiencode_vp8.c | 34 +++++++++------------------------- gst/vaapi/gstvaapiencode_vp8.h | 3 +++ 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 001a2f3089..320ee178ef 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -49,29 +49,11 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp8_encode_debug); #define GST_CODEC_CAPS \ "video/x-vp8" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_vp8_sink_caps_str[] = - GST_VAAPI_MAKE_SURFACE_CAPS ", " - GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " - GST_CAPS_INTERLACED_FALSE ";" - GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," - GST_CAPS_INTERLACED_FALSE; -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static const char gst_vaapiencode_vp8_src_caps_str[] = GST_CODEC_CAPS; /* *INDENT-ON* */ -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_vp8_sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_vp8_sink_caps_str)); -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapiencode_vp8_src_factory = GST_STATIC_PAD_TEMPLATE ("src", @@ -80,8 +62,10 @@ static GstStaticPadTemplate gst_vaapiencode_vp8_src_factory = GST_STATIC_CAPS (gst_vaapiencode_vp8_src_caps_str)); /* *INDENT-ON* */ +#define EXTRA_FORMATS {} + /* vp8 encode */ -G_DEFINE_TYPE (GstVaapiEncodeVP8, gst_vaapiencode_vp8, GST_TYPE_VAAPIENCODE); +GST_VAAPI_ENCODE_REGISTER_TYPE (vp8, VP8, VP8, EXTRA_FORMATS); static void gst_vaapiencode_vp8_init (GstVaapiEncodeVP8 * encode) @@ -113,16 +97,14 @@ gst_vaapiencode_vp8_alloc_encoder (GstVaapiEncode * base, } static void -gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass) +gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass, gpointer data) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + GstCaps *sink_caps = GST_CAPS_CAST (data); gpointer encoder_class; - GST_DEBUG_CATEGORY_INIT (gst_vaapi_vp8_encode_debug, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - object_class->finalize = gst_vaapiencode_vp8_finalize; object_class->set_property = gst_vaapiencode_set_property_subclass; object_class->get_property = gst_vaapiencode_get_property_subclass; @@ -137,8 +119,10 @@ gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass) "Sreerenj Balachandran "); /* sink pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_vp8_sink_factory); + g_assert (sink_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + gst_caps_unref (sink_caps); /* src pad */ gst_element_class_add_static_pad_template (element_class, diff --git a/gst/vaapi/gstvaapiencode_vp8.h b/gst/vaapi/gstvaapiencode_vp8.h index e71c25505e..1523a9dd75 100644 --- a/gst/vaapi/gstvaapiencode_vp8.h +++ b/gst/vaapi/gstvaapiencode_vp8.h @@ -64,6 +64,9 @@ struct _GstVaapiEncodeVP8Class GType gst_vaapiencode_vp8_get_type (void) G_GNUC_CONST; +GType +gst_vaapiencode_vp8_register_type (GstVaapiDisplay * display); + G_END_DECLS #endif /* GST_VAAPIENCODE_VP8_H */ From 0b57e6e090a78e7527a2c2753501afe655a7bc60 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 Apr 2020 22:05:50 +0800 Subject: [PATCH 3592/3781] plugins: encode: Modify sink template of vp9 encode. Use gst_vaapi_detect_codec_caps to get more precise template caps. Also implement gst_vaapiencode_vp9_register_type, which should be called at plugin register time. Part-of: --- gst/vaapi/gstvaapiencode_vp9.c | 32 ++++++++------------------------ gst/vaapi/gstvaapiencode_vp9.h | 3 +++ 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index 1fd0f8ed2c..d0e527bfee 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -49,29 +49,11 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp9_encode_debug); #define GST_CODEC_CAPS \ "video/x-vp9" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_vp9_sink_caps_str[] = - GST_VAAPI_MAKE_SURFACE_CAPS ", " - GST_CAPS_INTERLACED_FALSE "; " - GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " - GST_CAPS_INTERLACED_FALSE ";" - GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) "," - GST_CAPS_INTERLACED_FALSE; -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static const char gst_vaapiencode_vp9_src_caps_str[] = GST_CODEC_CAPS; /* *INDENT-ON* */ -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_vp9_sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_vp9_sink_caps_str)); -/* *INDENT-ON* */ - /* *INDENT-OFF* */ static GstStaticPadTemplate gst_vaapiencode_vp9_src_factory = GST_STATIC_PAD_TEMPLATE ("src", @@ -80,8 +62,10 @@ static GstStaticPadTemplate gst_vaapiencode_vp9_src_factory = GST_STATIC_CAPS (gst_vaapiencode_vp9_src_caps_str)); /* *INDENT-ON* */ +#define EXTRA_FORMATS {} + /* vp9 encode */ -G_DEFINE_TYPE (GstVaapiEncodeVP9, gst_vaapiencode_vp9, GST_TYPE_VAAPIENCODE); +GST_VAAPI_ENCODE_REGISTER_TYPE (vp9, VP9, VP9, EXTRA_FORMATS); static void gst_vaapiencode_vp9_init (GstVaapiEncodeVP9 * encode) @@ -113,16 +97,14 @@ gst_vaapiencode_vp9_alloc_encoder (GstVaapiEncode * base, } static void -gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass) +gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass, gpointer data) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + GstCaps *sink_caps = GST_CAPS_CAST (data); gpointer encoder_class; - GST_DEBUG_CATEGORY_INIT (gst_vaapi_vp9_encode_debug, - GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC); - object_class->finalize = gst_vaapiencode_vp9_finalize; object_class->set_property = gst_vaapiencode_set_property_subclass; object_class->get_property = gst_vaapiencode_get_property_subclass; @@ -137,8 +119,10 @@ gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass) "Sreerenj Balachandran "); /* sink pad */ + g_assert (sink_caps); gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_vp9_sink_factory)); + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + gst_caps_unref (sink_caps); /* src pad */ gst_element_class_add_pad_template (element_class, diff --git a/gst/vaapi/gstvaapiencode_vp9.h b/gst/vaapi/gstvaapiencode_vp9.h index 09c1fe2a67..8d57bda67b 100644 --- a/gst/vaapi/gstvaapiencode_vp9.h +++ b/gst/vaapi/gstvaapiencode_vp9.h @@ -64,6 +64,9 @@ struct _GstVaapiEncodeVP9Class GType gst_vaapiencode_vp9_get_type (void) G_GNUC_CONST; +GType +gst_vaapiencode_vp9_register_type (GstVaapiDisplay * display); + G_END_DECLS #endif /* GST_VAAPIENCODE_VP9_H */ From 3b118e2c4501a69a2a5f4f37e1b26bf9d19efad4 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 Apr 2020 22:20:35 +0800 Subject: [PATCH 3593/3781] plugin: use register_type to replace get_type for encode init. xxx_register_type will detect the template sink caps and is needed to be called at init time. Part-of: --- gst/vaapi/gstvaapi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 71bdacf4d2..2a34ae6284 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -130,14 +130,14 @@ struct _GstVaapiEncoderMap GstVaapiCodec codec; guint rank; const gchar *name; - GType (*get_type) (void); + GType (*register_type) (GstVaapiDisplay * display); }; #define DEF_ENC(CODEC,codec) \ {GST_VAAPI_CODEC_##CODEC, \ GST_RANK_PRIMARY, \ "vaapi" G_STRINGIFY (codec) "enc", \ - gst_vaapiencode_##codec##_get_type} + gst_vaapiencode_##codec##_register_type} static const GstVaapiEncoderMap vaapi_encode_map[] = { DEF_ENC (H264, h264), @@ -168,7 +168,8 @@ gst_vaapiencode_register (GstPlugin * plugin, GstVaapiDisplay * display) for (j = 0; j < G_N_ELEMENTS (vaapi_encode_map); j++) { if (vaapi_encode_map[j].codec == codec) { gst_element_register (plugin, vaapi_encode_map[j].name, - vaapi_encode_map[j].rank, vaapi_encode_map[j].get_type ()); + vaapi_encode_map[j].rank, + vaapi_encode_map[j].register_type (display)); break; } } From ab475c22d59eacce1dab01a3dcfa7d9e9c00c8f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 16 May 2020 20:49:31 +0200 Subject: [PATCH 3594/3781] libs: use array_unref() rather than array_free() It is more convinience and thread-safe. Part-of: --- gst-libs/gst/vaapi/gstvaapicontext.c | 2 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 35 ++++------------------- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 5 +--- gst-libs/gst/vaapi/gstvaapiparser_frame.c | 2 +- gst-libs/gst/vaapi/gstvaapisurface.c | 3 +- 5 files changed, 10 insertions(+), 37 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index e4839d3e0b..5d5deb6ec2 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -255,7 +255,7 @@ context_create (GstVaapiContext * context) cleanup: if (surfaces) - g_array_free (surfaces, TRUE); + g_array_unref (surfaces); return success; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 092885a394..5b74d8212c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -898,35 +898,12 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) { GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); - if (priv->decoders) { - g_ptr_array_free (priv->decoders, TRUE); - priv->decoders = NULL; - } - - if (priv->encoders) { - g_ptr_array_free (priv->encoders, TRUE); - priv->encoders = NULL; - } - - if (priv->codecs) { - g_array_free (priv->codecs, TRUE); - priv->codecs = NULL; - } - - if (priv->image_formats) { - g_array_free (priv->image_formats, TRUE); - priv->image_formats = NULL; - } - - if (priv->subpicture_formats) { - g_array_free (priv->subpicture_formats, TRUE); - priv->subpicture_formats = NULL; - } - - if (priv->properties) { - g_array_free (priv->properties, TRUE); - priv->properties = NULL; - } + g_clear_pointer (&priv->decoders, g_ptr_array_unref); + g_clear_pointer (&priv->encoders, g_ptr_array_unref); + g_clear_pointer (&priv->codecs, g_array_unref); + g_clear_pointer (&priv->image_formats, g_array_unref); + g_clear_pointer (&priv->subpicture_formats, g_array_unref); + g_clear_pointer (&priv->properties, g_array_unref); if (priv->display) { if (!priv->parent) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 50300b87da..1f2e1cc6d4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -156,10 +156,7 @@ gst_vaapi_display_x11_close_display (GstVaapiDisplay * display) GstVaapiDisplayX11Private *const priv = GST_VAAPI_DISPLAY_X11_PRIVATE (display); - if (priv->pixmap_formats) { - g_array_free (priv->pixmap_formats, TRUE); - priv->pixmap_formats = NULL; - } + g_clear_pointer (&priv->pixmap_formats, g_array_unref); if (priv->x11_display) { if (!priv->use_foreign_display) diff --git a/gst-libs/gst/vaapi/gstvaapiparser_frame.c b/gst-libs/gst/vaapi/gstvaapiparser_frame.c index 4eda63f934..66da510bdc 100644 --- a/gst-libs/gst/vaapi/gstvaapiparser_frame.c +++ b/gst-libs/gst/vaapi/gstvaapiparser_frame.c @@ -60,7 +60,7 @@ free_units (GArray ** units_ptr) &g_array_index (units, GstVaapiDecoderUnit, i); gst_vaapi_decoder_unit_clear (unit); } - g_array_free (units, TRUE); + g_array_unref (units); *units_ptr = NULL; } } diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 5c821f6ba7..64ab118ea9 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -61,8 +61,7 @@ gst_vaapi_surface_destroy_subpictures (GstVaapiSurface * surface) { if (surface->subpictures) { g_ptr_array_foreach (surface->subpictures, destroy_subpicture_cb, surface); - g_ptr_array_free (surface->subpictures, TRUE); - surface->subpictures = NULL; + g_clear_pointer (&surface->subpictures, g_ptr_array_unref); } } From df063989175a7e69ce0538b5f25b128ecb2e4aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 17 May 2020 09:55:42 +0200 Subject: [PATCH 3595/3781] vaapivideopool: Set pooled flag to added metas. So this could hint filters how to use these metas. Had to change the return value for texutre upload meta in order to flag it. Part-of: --- gst/vaapi/gstvaapivideobufferpool.c | 10 ++++++++-- gst/vaapi/gstvaapivideometa_texture.c | 19 +++++++------------ gst/vaapi/gstvaapivideometa_texture.h | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 219b992827..36be263ec7 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -385,6 +385,7 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, goto error_create_meta; buffer = gst_vaapi_video_buffer_new (meta); + GST_META_FLAG_SET (meta, GST_META_FLAG_POOLED); if (!buffer) goto error_create_buffer; @@ -428,10 +429,15 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, vmeta->map = gst_video_meta_map_vaapi_memory; vmeta->unmap = gst_video_meta_unmap_vaapi_memory; } + + GST_META_FLAG_SET (vmeta, GST_META_FLAG_POOLED); } #if (USE_GLX || USE_EGL) - if (priv->options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD) - gst_buffer_add_texture_upload_meta (buffer); + if (priv->options & GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_GL_TEXTURE_UPLOAD) { + GstMeta *tex_meta = gst_buffer_add_texture_upload_meta (buffer); + if (tex_meta) + GST_META_FLAG_SET (tex_meta, GST_META_FLAG_POOLED); + } #endif *out_buffer_ptr = buffer; diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index f840de78b3..b4cf65bf7a 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -218,10 +218,9 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, gst_vaapi_video_meta_get_render_flags (vmeta)); } -gboolean +GstMeta * gst_buffer_add_texture_upload_meta (GstBuffer * buffer) { - GstVideoGLTextureUploadMeta *meta = NULL; GstVaapiVideoMetaTexture *meta_texture; if (!buffer) @@ -234,20 +233,16 @@ gst_buffer_add_texture_upload_meta (GstBuffer * buffer) if (!meta_texture_ensure_info_from_buffer (meta_texture, buffer)) goto error; - meta = gst_buffer_add_video_gl_texture_upload_meta (buffer, - GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, - 1, meta_texture->texture_type, gst_vaapi_texture_upload, - meta_texture, (GBoxedCopyFunc) meta_texture_copy, - (GBoxedFreeFunc) meta_texture_free); - if (!meta) - goto error; - return TRUE; + return (GstMeta *) gst_buffer_add_video_gl_texture_upload_meta (buffer, + GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, 1, + meta_texture->texture_type, gst_vaapi_texture_upload, meta_texture, + (GBoxedCopyFunc) meta_texture_copy, (GBoxedFreeFunc) meta_texture_free); /* ERRORS */ error: { meta_texture_free (meta_texture); - return FALSE; + return NULL; } } @@ -259,6 +254,6 @@ gst_buffer_ensure_texture_upload_meta (GstBuffer * buffer) return meta ? meta_texture_ensure_info_from_buffer (meta->user_data, buffer) : - gst_buffer_add_texture_upload_meta (buffer); + (gst_buffer_add_texture_upload_meta (buffer) != NULL); } #endif diff --git a/gst/vaapi/gstvaapivideometa_texture.h b/gst/vaapi/gstvaapivideometa_texture.h index c334145292..bf369ba897 100644 --- a/gst/vaapi/gstvaapivideometa_texture.h +++ b/gst/vaapi/gstvaapivideometa_texture.h @@ -34,7 +34,7 @@ G_BEGIN_DECLS typedef struct _GstVaapiVideoMetaTexture GstVaapiVideoMetaTexture; G_GNUC_INTERNAL -gboolean +GstMeta * gst_buffer_add_texture_upload_meta (GstBuffer * buffer); G_GNUC_INTERNAL From 6b2f83522f965be0848cd00c2b25458477e9555a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 18 May 2020 18:29:05 +0200 Subject: [PATCH 3596/3781] vaapivideobufferpool: fix meta overwrite commit 7ac2a207 added a regression by erroneously assumed that GstVaapiVideoMeta is actually a GstMeta, which is not. Part-of: --- gst/vaapi/gstvaapivideobufferpool.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 36be263ec7..3ff29acd54 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -385,7 +385,6 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool, goto error_create_meta; buffer = gst_vaapi_video_buffer_new (meta); - GST_META_FLAG_SET (meta, GST_META_FLAG_POOLED); if (!buffer) goto error_create_buffer; From 20ce08aa2304a1d1123897b6c60538d9f2dc9579 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Thu, 21 May 2020 13:42:47 +0800 Subject: [PATCH 3597/3781] vaapiencoder_h264: set direct_spatial_mv_pred_flag to true by default This flag is set to true by default in both MediaSDK and FFmpeg-vaapi, so let's align this plugin with other libraries / softwares. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index f98949a2fe..153c5d909c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2310,7 +2310,7 @@ add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture, sizeof (slice_param->delta_pic_order_cnt)); /* only works for B frames */ - slice_param->direct_spatial_mv_pred_flag = FALSE; + slice_param->direct_spatial_mv_pred_flag = TRUE; /* default equal to picture parameters */ slice_param->num_ref_idx_active_override_flag = reflist_0_count || reflist_1_count; From cab041f9949a22a6d0f58389b9fddd5bb9b3ea74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 21 May 2020 11:37:36 +0200 Subject: [PATCH 3598/3781] README: update VP9 decoder and encoder Part-of: --- README | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README b/README index d214ac797b..5cc959c132 100644 --- a/README +++ b/README @@ -22,13 +22,13 @@ gstreamer-vaapi consists in a collection of VA-API based plugins for GStreamer and helper libraries. * `vaapidec' is used to decode JPEG, MPEG-2, MPEG-4:2, H.264 - AVC, H.264 MVC, VP8, VC-1, WMV3, HEVC videos to VA surfaces, + AVC, H.264 MVC, VP8, VP9, VC-1, WMV3, HEVC videos to VA surfaces, depending on the actual value of and the underlying hardware capabilities. This plugin is also able to implicitly download the decoded surface to raw YUV buffers. * `vaapienc' is used to encode into MPEG-2, H.264 AVC, H.264 - MVC, JPEG, VP8, HEVC videos, depending on the actual value of + MVC, JPEG, VP8, VP9, HEVC videos, depending on the actual value of (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. @@ -52,7 +52,8 @@ 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 and HEVC ad-hoc encoders + * 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 From e68fece3e60678ae8def604aa6eaa6e2a1ab8b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 20 May 2020 10:50:05 +0200 Subject: [PATCH 3599/3781] vaapidecoder: h264: remove baseline as constrained property From now on always the baseline is going to be treated as constrained without need of setting a property. Since the property was added along the development cycle (1.17 / commit 866a9f06) and never released, we assume that it is safe to remove it. Fixes: #252 Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 29 ++++------------------- gst-libs/gst/vaapi/gstvaapidecoder_h264.h | 4 ---- gst/vaapi/gstvaapidecode.c | 10 +++----- gst/vaapi/gstvaapidecode_props.c | 18 -------------- gst/vaapi/gstvaapidecode_props.h | 1 - 5 files changed, 8 insertions(+), 54 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 48f72d204d..4c64d5e42c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -537,7 +537,6 @@ struct _GstVaapiDecoderH264Private gboolean force_low_latency; gboolean base_only; - gboolean baseline_as_constrained; }; /** @@ -1474,11 +1473,11 @@ get_profile (GstVaapiDecoderH264 * decoder, GstH264SPS * sps, guint dpb_size) fill_profiles (profiles, &n_profiles, profile); switch (profile) { case GST_VAAPI_PROFILE_H264_BASELINE: - if (priv->baseline_as_constrained || sps->constraint_set1_flag) { // A.2.2 (main profile) - fill_profiles (profiles, &n_profiles, - GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE); - fill_profiles (profiles, &n_profiles, GST_VAAPI_PROFILE_H264_MAIN); - } + GST_INFO ("Baseline stream to be processed as Constrained-Baseline or " + "Main"); + fill_profiles (profiles, &n_profiles, + GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE); + fill_profiles (profiles, &n_profiles, GST_VAAPI_PROFILE_H264_MAIN); break; case GST_VAAPI_PROFILE_H264_EXTENDED: if (sps->constraint_set1_flag) { // A.2.2 (main profile) @@ -4801,24 +4800,6 @@ gst_vaapi_decoder_h264_set_base_only (GstVaapiDecoderH264 * decoder, decoder->priv.base_only = base_only; } -/** - * gst_vaapi_decoder_h264_set_baseline_as_constrained: - * @decoder: a #GstVaapiDecoderH264 - * @baseline_as_constrained: %TRUE to assume all baseline is constrained - * - * This is a small hack that makes the decoder assumes that baseline contents - * is already constrained. This may allow decoding some streams that would - * otherwise fails to negotiation. - */ -void -gst_vaapi_decoder_h264_set_baseline_as_constrained (GstVaapiDecoderH264 * - decoder, gboolean baseline_as_constrained) -{ - g_return_if_fail (decoder != NULL); - - decoder->priv.baseline_as_constrained = baseline_as_constrained; -} - /** * gst_vaapi_decoder_h264_set_low_latency: * @decoder: a #GstVaapiDecoderH264 diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h index 08ce6faa34..fd3f6c4bd0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.h @@ -73,10 +73,6 @@ void gst_vaapi_decoder_h264_set_base_only(GstVaapiDecoderH264 * decoder, gboolean base_only); -void -gst_vaapi_decoder_h264_set_baseline_as_constrained(GstVaapiDecoderH264 * decoder, - gboolean baseline_as_constrained); - G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiDecoderH264, gst_object_unref) G_END_DECLS diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 68de7e9d5b..4ce62f29d5 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -909,9 +909,6 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) (decode->decoder), priv->is_low_latency); gst_vaapi_decoder_h264_set_base_only (GST_VAAPI_DECODER_H264 (decode->decoder), priv->base_only); - gst_vaapi_decoder_h264_set_baseline_as_constrained - (GST_VAAPI_DECODER_H264 (decode->decoder), - priv->baseline_as_constrained); } } break; @@ -1233,8 +1230,6 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) gboolean have_high = FALSE; gboolean have_mvc = FALSE; gboolean have_svc = FALSE; - GstVaapiDecodeH264Private *priv = - gst_vaapi_decode_h264_get_instance_private (decode); profiles = gst_vaapi_display_get_decode_profiles (display); if (!profiles) @@ -1303,8 +1298,9 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) have_svc |= is_svc_profile (profile); have_high |= profile == GST_VAAPI_PROFILE_H264_HIGH; - if (priv && priv->baseline_as_constrained && - profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE) + /* XXX: artificially adding baseline if constrained_baseline is + * available. */ + if (profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE) allowed_sinkpad_caps = add_h264_profile_in_caps (allowed_sinkpad_caps, "baseline"); } diff --git a/gst/vaapi/gstvaapidecode_props.c b/gst/vaapi/gstvaapidecode_props.c index 5ab280041f..dc52677674 100644 --- a/gst/vaapi/gstvaapidecode_props.c +++ b/gst/vaapi/gstvaapidecode_props.c @@ -30,7 +30,6 @@ enum { GST_VAAPI_DECODER_H264_PROP_FORCE_LOW_LATENCY = 1, GST_VAAPI_DECODER_H264_PROP_BASE_ONLY, - GST_VAAPI_DECODER_H264_PROP_BASELINE_AS_CONSTRAINED, }; static gint h264_private_offset; @@ -50,9 +49,6 @@ gst_vaapi_decode_h264_get_property (GObject * object, guint prop_id, case GST_VAAPI_DECODER_H264_PROP_BASE_ONLY: g_value_set_boolean (value, priv->base_only); break; - case GST_VAAPI_DECODER_H264_PROP_BASELINE_AS_CONSTRAINED: - g_value_set_boolean (value, priv->baseline_as_constrained); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -81,13 +77,6 @@ gst_vaapi_decode_h264_set_property (GObject * object, guint prop_id, if (decoder) gst_vaapi_decoder_h264_set_base_only (decoder, priv->base_only); break; - case GST_VAAPI_DECODER_H264_PROP_BASELINE_AS_CONSTRAINED: - priv->baseline_as_constrained = g_value_get_boolean (value); - decoder = GST_VAAPI_DECODER_H264 (GST_VAAPIDECODE (object)->decoder); - if (decoder) - gst_vaapi_decoder_h264_set_baseline_as_constrained (decoder, - priv->baseline_as_constrained); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -114,13 +103,6 @@ gst_vaapi_decode_h264_install_properties (GObjectClass * klass) g_param_spec_boolean ("base-only", "Decode base view only", "Drop any NAL unit not defined in Annex.A", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (klass, - GST_VAAPI_DECODER_H264_PROP_BASELINE_AS_CONSTRAINED, - g_param_spec_boolean ("baseline-as-constrained", - "Baseline as Constrained", - "Assume all baseline content is also constrained.", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } GstVaapiDecodeH264Private * diff --git a/gst/vaapi/gstvaapidecode_props.h b/gst/vaapi/gstvaapidecode_props.h index d644fdedcc..b1f2fec600 100644 --- a/gst/vaapi/gstvaapidecode_props.h +++ b/gst/vaapi/gstvaapidecode_props.h @@ -34,7 +34,6 @@ struct _GstVaapiDecodeH264Private { gboolean is_low_latency; gboolean base_only; - gboolean baseline_as_constrained; }; void From 593f6650ef0ca751a28ca2631405efaa7bec11a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 25 May 2020 15:46:58 +0200 Subject: [PATCH 3600/3781] libs: decoder: h264: disallow multiple slice group As far as we know there are no VAAPI drivers supporting FMO, which migth be used in baseline streams. This commit is a continuation of https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/328 Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 4c64d5e42c..fad3d0e898 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1832,6 +1832,12 @@ parse_pps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) return get_status (result); priv->parser_state |= GST_H264_VIDEO_STATE_GOT_PPS; + + if (pps->num_slice_groups_minus1 > 0) { + GST_FIXME ("FMO is not supported"); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + return GST_VAAPI_DECODER_STATUS_SUCCESS; } From 3df1018b023e9368036b024e0ce80570258eeb33 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 26 May 2020 02:19:15 +0800 Subject: [PATCH 3601/3781] libs: decoder: h264: Add ref flags for splited field. When split one frame into fields, the second field should also copy the reference flags. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index fad3d0e898..43955cd26d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -397,6 +397,9 @@ gst_vaapi_frame_store_split_fields (GstVaapiFrameStore * fs, gboolean tff) second_field = gst_vaapi_picture_h264_new_field (first_field); if (!second_field) return FALSE; + gst_vaapi_picture_h264_set_reference (second_field, + GST_VAAPI_PICTURE_FLAGS (first_field) & GST_VAAPI_PICTURE_FLAGS_REFERENCE, + FALSE); gst_vaapi_picture_replace (&fs->buffers[fs->num_buffers++], second_field); gst_vaapi_picture_unref (second_field); From 6333c8531663634f72622176f3fb88e6e69a3e62 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 23 May 2020 14:00:58 +0800 Subject: [PATCH 3602/3781] libs: subpicture: Make subpicture a standard GstMiniObject. Part-of: --- gst-libs/gst/vaapi/gstvaapisubpicture.c | 103 ++++++++++++------------ gst-libs/gst/vaapi/gstvaapisubpicture.h | 22 +++++ gst-libs/gst/vaapi/gstvaapisurface.c | 19 ++--- tests/internal/image.c | 2 +- 4 files changed, 84 insertions(+), 62 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index 56db3784c7..aebad7ea08 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -37,8 +37,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass; - /** * GstVaapiSubpicture: * @@ -47,55 +45,56 @@ typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass; struct _GstVaapiSubpicture { /*< private > */ - GstVaapiObject parent_instance; + GstMiniObject mini_object; + GstVaapiDisplay *display; + GstVaapiID object_id; GstVaapiImage *image; guint flags; gfloat global_alpha; }; -/** - * GstVaapiSubpictureClass: - * - * A VA subpicture wrapper class - */ -struct _GstVaapiSubpictureClass -{ - /*< private > */ - GstVaapiObjectClass parent_class; -}; - static void -gst_vaapi_subpicture_destroy (GstVaapiSubpicture * subpicture) +gst_vaapi_subpicture_free_image (GstVaapiSubpicture * subpicture) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (subpicture); + GstVaapiDisplay *const display = subpicture->display; VASubpictureID subpicture_id; VAStatus status; - subpicture_id = GST_VAAPI_OBJECT_ID (subpicture); + subpicture_id = subpicture->object_id; GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (subpicture_id)); if (subpicture_id != VA_INVALID_ID) { - if (display) { - GST_VAAPI_DISPLAY_LOCK (display); - status = vaDestroySubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), - subpicture_id); - GST_VAAPI_DISPLAY_UNLOCK (display); - if (!vaapi_check_status (status, "vaDestroySubpicture()")) - GST_WARNING ("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS (subpicture_id)); - } - GST_VAAPI_OBJECT_ID (subpicture) = VA_INVALID_ID; + GST_VAAPI_DISPLAY_LOCK (display); + status = vaDestroySubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), + subpicture_id); + GST_VAAPI_DISPLAY_UNLOCK (display); + if (!vaapi_check_status (status, "vaDestroySubpicture()")) + GST_WARNING ("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT, + GST_VAAPI_ID_ARGS (subpicture_id)); + subpicture->object_id = VA_INVALID_ID; } - gst_mini_object_replace ((GstMiniObject **) & subpicture->image, NULL); + + if (subpicture->image) + gst_mini_object_replace ((GstMiniObject **) & subpicture->image, NULL); } +static void +gst_vaapi_subpicture_free (GstVaapiSubpicture * subpicture) +{ + gst_vaapi_subpicture_free_image (subpicture); + gst_vaapi_display_replace (&subpicture->display, NULL); + g_slice_free1 (sizeof (GstVaapiSubpicture), subpicture); +} + +GST_DEFINE_MINI_OBJECT_TYPE (GstVaapiSubpicture, gst_vaapi_subpicture); + static gboolean -gst_vaapi_subpicture_create (GstVaapiSubpicture * subpicture, +gst_vaapi_subpicture_bind_image (GstVaapiSubpicture * subpicture, GstVaapiImage * image) { - GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (subpicture); + GstVaapiDisplay *const display = subpicture->display; VASubpictureID subpicture_id; VAStatus status; @@ -108,15 +107,12 @@ gst_vaapi_subpicture_create (GstVaapiSubpicture * subpicture, GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (subpicture_id)); - GST_VAAPI_OBJECT_ID (subpicture) = subpicture_id; + subpicture->object_id = subpicture_id; subpicture->image = (GstVaapiImage *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (image)); return TRUE; } -#define gst_vaapi_subpicture_finalize gst_vaapi_subpicture_destroy -GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture) - /** * gst_vaapi_subpicture_new: * @image: a #GstVaapiImage @@ -127,8 +123,8 @@ GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture) * * Return value: the newly allocated #GstVaapiSubpicture object */ - GstVaapiSubpicture *gst_vaapi_subpicture_new (GstVaapiImage * image, - guint flags) +GstVaapiSubpicture * +gst_vaapi_subpicture_new (GstVaapiImage * image, guint flags) { GstVaapiSubpicture *subpicture; GstVaapiDisplay *display; @@ -147,19 +143,26 @@ GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture) if (flags & ~va_flags) return NULL; - subpicture = gst_vaapi_object_new (gst_vaapi_subpicture_class (), display); + subpicture = g_slice_new (GstVaapiSubpicture); if (!subpicture) return NULL; + gst_mini_object_init (GST_MINI_OBJECT_CAST (subpicture), 0, + GST_TYPE_VAAPI_SUBPICTURE, NULL, NULL, + (GstMiniObjectFreeFunction) gst_vaapi_subpicture_free); + subpicture->display = gst_object_ref (display); + subpicture->object_id = VA_INVALID_ID; + subpicture->flags = flags; subpicture->global_alpha = 1.0f; - if (!gst_vaapi_subpicture_set_image (subpicture, image)) + + if (!gst_vaapi_subpicture_bind_image (subpicture, image)) goto error; return subpicture; /* ERRORS */ error: { - gst_vaapi_object_unref (subpicture); + gst_vaapi_subpicture_unref (subpicture); return NULL; } } @@ -194,12 +197,8 @@ gst_vaapi_subpicture_new_from_overlay_rectangle (GstVaapiDisplay * display, g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rect), NULL); - /* XXX: use gst_vaapi_image_format_from_video() */ -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - format = GST_VIDEO_FORMAT_BGRA; -#else - format = GST_VIDEO_FORMAT_ARGB; -#endif + format = GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB; + if (!gst_vaapi_display_has_subpicture_format (display, format, &hw_flags)) return NULL; @@ -235,12 +234,12 @@ gst_vaapi_subpicture_new_from_overlay_rectangle (GstVaapiDisplay * display, raw_image.stride[0] = stride; if (!gst_vaapi_image_update_from_raw (image, &raw_image, NULL)) { GST_WARNING ("could not update VA image with subtitle data"); - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); return NULL; } subpicture = gst_vaapi_subpicture_new (image, flags); - gst_vaapi_object_unref (image); + gst_vaapi_image_unref (image); gst_video_meta_unmap (vmeta, 0, &map_info); if (!subpicture) return NULL; @@ -266,7 +265,7 @@ gst_vaapi_subpicture_get_id (GstVaapiSubpicture * subpicture) { g_return_val_if_fail (subpicture != NULL, VA_INVALID_ID); - return GST_VAAPI_OBJECT_ID (subpicture); + return subpicture->object_id; } /** @@ -318,8 +317,8 @@ gst_vaapi_subpicture_set_image (GstVaapiSubpicture * subpicture, g_return_val_if_fail (subpicture != NULL, FALSE); g_return_val_if_fail (image != NULL, FALSE); - gst_vaapi_subpicture_destroy (subpicture); - return gst_vaapi_subpicture_create (subpicture, image); + gst_vaapi_subpicture_free_image (subpicture); + return gst_vaapi_subpicture_bind_image (subpicture, image); } /** @@ -364,11 +363,11 @@ gst_vaapi_subpicture_set_global_alpha (GstVaapiSubpicture * subpicture, if (subpicture->global_alpha == global_alpha) return TRUE; - display = GST_VAAPI_OBJECT_DISPLAY (subpicture); + display = subpicture->display; GST_VAAPI_DISPLAY_LOCK (display); status = vaSetSubpictureGlobalAlpha (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_OBJECT_ID (subpicture), global_alpha); + subpicture->object_id, global_alpha); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaSetSubpictureGlobalAlpha()")) return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 7bfef36ed4..8c241b292e 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -52,6 +52,26 @@ typedef enum { GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA = (1 << 1), } GstVaapiSubpictureFlags; +#define GST_TYPE_VAAPI_SUBPICTURE (gst_vaapi_subpicture_get_type ()) + +#define GST_VAAPI_SUBPICTURE_ID(subpicture) (gst_vaapi_subpicture_get_id (subpicture)) + +GType +gst_vaapi_subpicture_get_type (void) G_GNUC_CONST; + +/** + * gst_vaapi_subpicture_unref: (skip) + * @subpicture: (transfer full): a #GstVaapiSubpicture. + * + * Decreases the refcount of the subpicture. If the refcount reaches 0, the + * subpicture will be freed. + */ +static inline void +gst_vaapi_subpicture_unref (GstVaapiSubpicture *subpicture) +{ + gst_mini_object_unref (GST_MINI_OBJECT_CAST (subpicture)); +} + GstVaapiSubpicture * gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags); @@ -81,6 +101,8 @@ gboolean gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture, gfloat global_alpha); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiSubpicture, gst_vaapi_subpicture_unref) + G_END_DECLS #endif /* GST_VAAPI_SUBPICTURE_H */ diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 64ab118ea9..458e4e794b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -53,7 +53,7 @@ static void destroy_subpicture_cb (gpointer subpicture, gpointer surface) { _gst_vaapi_surface_deassociate_subpicture (surface, subpicture); - gst_vaapi_object_unref (subpicture); + gst_vaapi_subpicture_unref (subpicture); } static void @@ -804,7 +804,7 @@ gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface, if (g_ptr_array_remove_fast (surface->subpictures, subpicture)) { success = _gst_vaapi_surface_deassociate_subpicture (surface, subpicture); - gst_vaapi_object_unref (subpicture); + gst_vaapi_subpicture_unref (subpicture); if (!success) return FALSE; } @@ -814,7 +814,8 @@ gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface, if (!success) return FALSE; - g_ptr_array_add (surface->subpictures, gst_vaapi_object_ref (subpicture)); + g_ptr_array_add (surface->subpictures, + gst_mini_object_ref (GST_MINI_OBJECT_CAST (subpicture))); return TRUE; } @@ -858,7 +859,7 @@ _gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface, GST_VAAPI_DISPLAY_LOCK (display); status = vaAssociateSubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_OBJECT_ID (subpicture), &surface_id, 1, + GST_VAAPI_SUBPICTURE_ID (subpicture), &surface_id, 1, src_rect->x, src_rect->y, src_rect->width, src_rect->height, dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height, from_GstVaapiSubpictureFlags (gst_vaapi_subpicture_get_flags @@ -895,13 +896,13 @@ gst_vaapi_surface_deassociate_subpicture (GstVaapiSurface * surface, if (!g_ptr_array_remove_fast (surface->subpictures, subpicture)) { GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT " was not bound to " "surface %" GST_VAAPI_ID_FORMAT, - GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (subpicture)), + GST_VAAPI_ID_ARGS (GST_VAAPI_SUBPICTURE_ID (subpicture)), GST_VAAPI_ID_ARGS (GST_VAAPI_SURFACE_ID (surface))); return TRUE; } success = _gst_vaapi_surface_deassociate_subpicture (surface, subpicture); - gst_vaapi_object_unref (subpicture); + gst_vaapi_subpicture_unref (subpicture); return success; } @@ -923,7 +924,7 @@ _gst_vaapi_surface_deassociate_subpicture (GstVaapiSurface * surface, GST_VAAPI_DISPLAY_LOCK (display); status = vaDeassociateSubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_OBJECT_ID (subpicture), &surface_id, 1); + GST_VAAPI_SUBPICTURE_ID (subpicture), &surface_id, 1); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaDeassociateSubpicture()")) return FALSE; @@ -1047,10 +1048,10 @@ gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface, if (!gst_vaapi_surface_associate_subpicture (surface, subpicture, NULL, &sub_rect)) { GST_WARNING ("could not render overlay rectangle %p", rect); - gst_vaapi_object_unref (subpicture); + gst_vaapi_subpicture_unref (subpicture); return FALSE; } - gst_vaapi_object_unref (subpicture); + gst_vaapi_subpicture_unref (subpicture); } return TRUE; } diff --git a/tests/internal/image.c b/tests/internal/image.c index 30256cb72e..ea532fb831 100644 --- a/tests/internal/image.c +++ b/tests/internal/image.c @@ -395,6 +395,6 @@ image_upload (GstVaapiImage * image, GstVaapiSurface * surface) g_error ("could not associate subpicture to surface"); /* The surface holds a reference to the subpicture. This is safe */ - gst_vaapi_object_unref (subpicture); + gst_vaapi_subpicture_unref (subpicture); return TRUE; } From 2515d4dd2fd2cad1d03c56fc1f7cf854a96657b5 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 23 May 2020 20:48:54 +0800 Subject: [PATCH 3603/3781] libs: surface: return fail immediately if can not create subpicture Part-of: --- gst-libs/gst/vaapi/gstvaapisurface.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index 458e4e794b..0fdafd99f4 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -1036,6 +1036,10 @@ gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface, rect = gst_video_overlay_composition_get_rectangle (composition, n); subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle (display, rect); + if (subpicture == NULL) { + GST_WARNING ("could not create subpicture for rectangle %p", rect); + return FALSE; + } gst_video_overlay_rectangle_get_render_rectangle (rect, (gint *) & sub_rect.x, (gint *) & sub_rect.y, From e41c6bd29895156cfdc4c36bd23826e9e3ac8a67 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 23 May 2020 22:09:17 +0800 Subject: [PATCH 3604/3781] libs: delete all gstvaapiobject related files. Part-of: --- gst-libs/gst/vaapi/gstvaapibufferproxy.c | 1 - gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h | 1 - gst-libs/gst/vaapi/gstvaapicontext.h | 2 - gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_vp8.c | 1 - gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 1 - gst-libs/gst/vaapi/gstvaapiimage.h | 1 - gst-libs/gst/vaapi/gstvaapiobject.c | 206 ------------------ gst-libs/gst/vaapi/gstvaapiobject.h | 61 ------ gst-libs/gst/vaapi/gstvaapiobject_priv.h | 198 ----------------- gst-libs/gst/vaapi/gstvaapiprofile.h | 1 + gst-libs/gst/vaapi/gstvaapisubpicture.c | 1 - gst-libs/gst/vaapi/gstvaapisubpicture.h | 1 - gst-libs/gst/vaapi/gstvaapisurface.h | 1 - .../gst/vaapi/gstvaapisurfaceproxy_priv.h | 1 - gst-libs/gst/vaapi/gstvaapivideopool.c | 1 - gst-libs/gst/vaapi/meson.build | 2 - 22 files changed, 1 insertion(+), 485 deletions(-) delete mode 100644 gst-libs/gst/vaapi/gstvaapiobject.c delete mode 100644 gst-libs/gst/vaapi/gstvaapiobject.h delete mode 100644 gst-libs/gst/vaapi/gstvaapiobject_priv.h diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy.c b/gst-libs/gst/vaapi/gstvaapibufferproxy.c index 492053a59a..71547eea26 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy.c +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy.c @@ -26,7 +26,6 @@ #include "gstvaapibufferproxy_priv.h" #include "gstvaapisurface_priv.h" #include "gstvaapiutils.h" -#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h index d9f518855a..445201deac 100644 --- a/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h @@ -24,7 +24,6 @@ #define GST_VAAPI_BUFFER_PROXY_PRIV_H #include "gstvaapibufferproxy.h" -#include "gstvaapiobject.h" #include "gstvaapiminiobject.h" G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 900fc653f9..820fa63985 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -25,8 +25,6 @@ #ifndef GST_VAAPI_CONTEXT_H #define GST_VAAPI_CONTEXT_H -#include "gstvaapiobject.h" -#include "gstvaapiobject_priv.h" #include "gstvaapiprofile.h" #include "gstvaapidisplay.h" #include "gstvaapisurface.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 43955cd26d..83b05c45e4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -32,7 +32,6 @@ #include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" -#include "gstvaapiobject_priv.h" #include "gstvaapiutils_h264_priv.h" #define DEBUG 1 diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 0516acf81c..739b33c128 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -34,7 +34,6 @@ #include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" -#include "gstvaapiobject_priv.h" #include "gstvaapiutils_h265_priv.h" #define DEBUG 1 diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 8e22568e40..3122f7beeb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -33,7 +33,6 @@ #include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" -#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index ffa66b8f80..3855aa06f9 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -33,7 +33,6 @@ #include "gstvaapidecoder_dpb.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" -#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 38420d8a68..8ecdb324fd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -32,7 +32,6 @@ #include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" -#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 32d02b1cca..d8dcbce6fa 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -33,7 +33,6 @@ #include "gstvaapidecoder_unit.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" -#include "gstvaapiobject_priv.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c index dbb8b46398..b61a0a9261 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp8.c @@ -32,7 +32,6 @@ #include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" -#include "gstvaapiobject_priv.h" #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index a34ee5b941..0f6a300fbd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -31,7 +31,6 @@ #include "gstvaapidecoder_objects.h" #include "gstvaapidecoder_priv.h" #include "gstvaapidisplay_priv.h" -#include "gstvaapiobject_priv.h" #include "gstvaapicompat.h" diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h index 5ab6f74ca3..12ac9f49da 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.h +++ b/gst-libs/gst/vaapi/gstvaapiimage.h @@ -26,7 +26,6 @@ #define GST_VAAPI_IMAGE_H #include -#include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c deleted file mode 100644 index db649e0e20..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * gstvaapiobject.c - Base VA object - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Author: Gwenole Beauchesne - * Copyright (C) 2012-2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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:gstvaapiobject - * @short_description: Base VA object - */ - -#include "sysdeps.h" -#include "gstvaapiobject.h" -#include "gstvaapiobject_priv.h" -#include "gstvaapiminiobject.h" -#include "gstvaapidisplay_priv.h" - -#define DEBUG 1 -#include "gstvaapidebug.h" - -static void -gst_vaapi_object_finalize (GstVaapiObject * object) -{ - const GstVaapiObjectClass *const klass = GST_VAAPI_OBJECT_GET_CLASS (object); - - if (klass->finalize) - klass->finalize (object); - gst_vaapi_display_replace (&object->display, NULL); -} - -void -gst_vaapi_object_class_init (GstVaapiObjectClass * klass, guint size) -{ - GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); - - object_class->size = size; - object_class->finalize = (GDestroyNotify) gst_vaapi_object_finalize; -} - -/** - * gst_vaapi_object_new: - * @klass: The object class - * @display: The #GstVaapiDisplay - * - * Creates a new #GstVaapiObject. The @klass argument shall not be - * %NULL, and it must reference a statically allocated descriptor. - * - * This function zero-initializes the derived object data. Also note - * that this is an internal function that shall not be used outside of - * libgstvaapi libraries. - * - * Returns: The newly allocated #GstVaapiObject - */ -gpointer -gst_vaapi_object_new (const GstVaapiObjectClass * klass, - GstVaapiDisplay * display) -{ - const GstVaapiMiniObjectClass *const object_class = - GST_VAAPI_MINI_OBJECT_CLASS (klass); - GstVaapiObject *object; - guint sub_size; - - g_return_val_if_fail (klass != NULL, NULL); - g_return_val_if_fail (display != NULL, NULL); - - object = (GstVaapiObject *) gst_vaapi_mini_object_new (object_class); - if (!object) - return NULL; - - object->display = gst_object_ref (display); - object->object_id = VA_INVALID_ID; - - sub_size = object_class->size - sizeof (*object); - if (sub_size > 0) - memset (((guchar *) object) + sizeof (*object), 0, sub_size); - - if (klass->init) - klass->init (object); - return object; -} - -/** - * gst_vaapi_object_ref: - * @object: a #GstVaapiObject - * - * Atomically increases the reference count of the given @object by one. - * - * Returns: The same @object argument - */ -gpointer -gst_vaapi_object_ref (gpointer object) -{ - return gst_vaapi_mini_object_ref (object); -} - -/** - * gst_vaapi_object_unref: - * @object: a #GstVaapiObject - * - * Atomically decreases the reference count of the @object by one. If - * the reference count reaches zero, the object will be free'd. - */ -void -gst_vaapi_object_unref (gpointer object) -{ - gst_vaapi_mini_object_unref (object); -} - -/** - * gst_vaapi_object_replace: - * @old_object_ptr: a pointer to a #GstVaapiObject - * @new_object: a #GstVaapiObject - * - * Atomically replaces the object object held in @old_object_ptr with - * @new_object. This means that @old_object_ptr shall reference a - * valid object. However, @new_object can be NULL. - */ -void -gst_vaapi_object_replace (gpointer old_object_ptr, gpointer new_object) -{ - gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) old_object_ptr, - new_object); -} - -/** - * gst_vaapi_object_get_display: - * @object: a #GstVaapiObject - * - * Returns the #GstVaapiDisplay this @object is bound to. - * - * Return value: the parent #GstVaapiDisplay object - */ -GstVaapiDisplay * -gst_vaapi_object_get_display (GstVaapiObject * object) -{ - g_return_val_if_fail (object != NULL, NULL); - - return GST_VAAPI_OBJECT_DISPLAY (object); -} - -/** - * gst_vaapi_object_lock_display: - * @object: a #GstVaapiObject - * - * Locks @object parent display. If display is already locked by - * another thread, the current thread will block until display is - * unlocked by the other thread. - */ -void -gst_vaapi_object_lock_display (GstVaapiObject * object) -{ - g_return_if_fail (object != NULL); - - GST_VAAPI_OBJECT_LOCK_DISPLAY (object); -} - -/** - * gst_vaapi_object_unlock_display: - * @object: a #GstVaapiObject - * - * Unlocks @object parent display. If another thread is blocked in a - * gst_vaapi_object_lock_display() call, it will be woken and can lock - * display itself. - */ -void -gst_vaapi_object_unlock_display (GstVaapiObject * object) -{ - g_return_if_fail (object != NULL); - - GST_VAAPI_OBJECT_UNLOCK_DISPLAY (object); -} - -/** - * gst_vaapi_object_get_id: - * @object: a #GstVaapiObject - * - * Returns the #GstVaapiID contained in the @object. - * - * Return value: the #GstVaapiID of the @object - */ -GstVaapiID -gst_vaapi_object_get_id (GstVaapiObject * object) -{ - g_return_val_if_fail (object != NULL, 0); - - return GST_VAAPI_OBJECT_ID (object); -} diff --git a/gst-libs/gst/vaapi/gstvaapiobject.h b/gst-libs/gst/vaapi/gstvaapiobject.h deleted file mode 100644 index ad9edc4c91..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiobject.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * gstvaapiobject.h - Base VA object - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Author: Gwenole Beauchesne - * Copyright (C) 2012-2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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_OBJECT_H -#define GST_VAAPI_OBJECT_H - -#include -#include - -G_BEGIN_DECLS - -#define GST_VAAPI_OBJECT(obj) \ - ((GstVaapiObject *) (obj)) - -typedef struct _GstVaapiObject GstVaapiObject; - -gpointer -gst_vaapi_object_ref (gpointer object); - -void -gst_vaapi_object_unref (gpointer object); - -void -gst_vaapi_object_replace (gpointer old_object_ptr, gpointer new_object); - -GstVaapiDisplay * -gst_vaapi_object_get_display (GstVaapiObject * object); - -void -gst_vaapi_object_lock_display (GstVaapiObject * object); - -void -gst_vaapi_object_unlock_display (GstVaapiObject * object); - -GstVaapiID -gst_vaapi_object_get_id (GstVaapiObject * object); - -G_END_DECLS - -#endif /* GST_VAAPI_OBJECT_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiobject_priv.h b/gst-libs/gst/vaapi/gstvaapiobject_priv.h deleted file mode 100644 index 0eb494d472..0000000000 --- a/gst-libs/gst/vaapi/gstvaapiobject_priv.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * gstvaapiobject_priv.h - Base VA object (private definitions) - * - * Copyright (C) 2010-2011 Splitted-Desktop Systems - * Author: Gwenole Beauchesne - * Copyright (C) 2012-2013 Intel Corporation - * Author: Gwenole Beauchesne - * - * 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_OBJECT_PRIV_H -#define GST_VAAPI_OBJECT_PRIV_H - -#include -#include "gstvaapiminiobject.h" -#include "gstvaapidisplay_priv.h" - -G_BEGIN_DECLS - -#define GST_VAAPI_OBJECT_CLASS(klass) \ - ((GstVaapiObjectClass *) (klass)) -#define GST_VAAPI_IS_OBJECT_CLASS(klass) \ - ((klass) != NULL) -#define GST_VAAPI_OBJECT_GET_CLASS(object) \ - GST_VAAPI_OBJECT_CLASS (GST_VAAPI_MINI_OBJECT_GET_CLASS (object)) - -typedef struct _GstVaapiObjectClass GstVaapiObjectClass; -typedef void (*GstVaapiObjectInitFunc) (GstVaapiObject * object); -typedef void (*GstVaapiObjectFinalizeFunc) (GstVaapiObject * object); - -#define GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE(TN, t_n, code) \ -static inline const GstVaapiObjectClass * \ -G_PASTE(t_n,_class) (void) \ -{ \ - static G_PASTE(TN,Class) g_class; \ - static gsize g_class_init = FALSE; \ - \ - if (g_once_init_enter (&g_class_init)) { \ - GstVaapiObjectClass * const klass = \ - GST_VAAPI_OBJECT_CLASS (&g_class); \ - gst_vaapi_object_class_init (klass, sizeof(TN)); \ - code; \ - klass->finalize = (GstVaapiObjectFinalizeFunc) \ - G_PASTE(t_n,_finalize); \ - g_once_init_leave (&g_class_init, TRUE); \ - } \ - return GST_VAAPI_OBJECT_CLASS (&g_class); \ -} - -#define GST_VAAPI_OBJECT_DEFINE_CLASS(TN, t_n) \ - GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (TN, t_n, /**/) - -/** - * GST_VAAPI_OBJECT_ID: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the #GstVaapiID contained in @object. - * This is an internal macro that does not do any run-time type checks. - */ -#define GST_VAAPI_OBJECT_ID(object) \ - (GST_VAAPI_OBJECT (object)->object_id) - -/** - * GST_VAAPI_OBJECT_DISPLAY: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the #GstVaapiDisplay the @object is bound to. - * This is an internal macro that does not do any run-time type check. - */ -#define GST_VAAPI_OBJECT_DISPLAY(object) \ - (GST_VAAPI_OBJECT (object)->display) - -/** - * GST_VAAPI_OBJECT_DISPLAY_X11: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the #GstVaapiDisplayX11 the @object is bound to. - * This is an internal macro that does not do any run-time type check - * and requires #include "gstvaapidisplay_x11_priv.h" - */ -#define GST_VAAPI_OBJECT_DISPLAY_X11(object) \ - GST_VAAPI_DISPLAY_X11_CAST (GST_VAAPI_OBJECT_DISPLAY (object)) - -/** - * GST_VAAPI_OBJECT_DISPLAY_GLX: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the #GstVaapiDisplayGLX the @object is bound to. - * This is an internal macro that does not do any run-time type check - * and requires #include "gstvaapidisplay_glx_priv.h". - */ -#define GST_VAAPI_OBJECT_DISPLAY_GLX(object) \ - GST_VAAPI_DISPLAY_GLX_CAST (GST_VAAPI_OBJECT_DISPLAY (object)) - -/** - * GST_VAAPI_OBJECT_DISPLAY_WAYLAND: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the #GstVaapiDisplayWayland the @object is - * bound to. This is an internal macro that does not do any run-time - * type check and requires #include "gstvaapidisplay_wayland_priv.h" - */ -#define GST_VAAPI_OBJECT_DISPLAY_WAYLAND(object) \ - GST_VAAPI_DISPLAY_WAYLAND_CAST (GST_VAAPI_OBJECT_DISPLAY (object)) - -/** - * GST_VAAPI_OBJECT_VADISPLAY: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the #VADisplay of @display. - * This is an internal macro that does not do any run-time type check - * and requires #include "gstvaapidisplay_priv.h". - */ -#define GST_VAAPI_OBJECT_VADISPLAY(object) \ - GST_VAAPI_DISPLAY_VADISPLAY (GST_VAAPI_OBJECT_DISPLAY (object)) - -/** - * GST_VAAPI_OBJECT_NATIVE_DISPLAY: - * @object: a #GstVaapiObject - * - * Macro that evaluates to the underlying native @display object. - * This is an internal macro that does not do any run-time type check. - */ -#define GST_VAAPI_OBJECT_NATIVE_DISPLAY(object) \ - GST_VAAPI_DISPLAY_NATIVE (GST_VAAPI_OBJECT_DISPLAY (object)) - -/** - * GST_VAAPI_OBJECT_LOCK_DISPLAY: - * @object: a #GstVaapiObject - * - * Macro that locks the #GstVaapiDisplay contained in the @object. - * This is an internal macro that does not do any run-time type check. - */ -#define GST_VAAPI_OBJECT_LOCK_DISPLAY(object) \ - GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_OBJECT_DISPLAY (object)) - -/** - * GST_VAAPI_OBJECT_UNLOCK_DISPLAY: - * @object: a #GstVaapiObject - * - * Macro that unlocks the #GstVaapiDisplay contained in the @object. - * This is an internal macro that does not do any run-time type check. - */ -#define GST_VAAPI_OBJECT_UNLOCK_DISPLAY(object) \ - GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_OBJECT_DISPLAY (object)) - -/** - * GstVaapiObject: - * - * VA object base. - */ -struct _GstVaapiObject -{ - /*< private >*/ - GstVaapiMiniObject parent_instance; - - GstVaapiDisplay *display; - GstVaapiID object_id; -}; - -/** - * GstVaapiObjectClass: - * - * VA object base class. - */ -struct _GstVaapiObjectClass -{ - /*< private >*/ - GstVaapiMiniObjectClass parent_class; - - GstVaapiObjectInitFunc init; - GstVaapiObjectFinalizeFunc finalize; -}; - -void -gst_vaapi_object_class_init (GstVaapiObjectClass * klass, guint size); - -gpointer -gst_vaapi_object_new (const GstVaapiObjectClass * klass, - GstVaapiDisplay * display); - -G_END_DECLS - -#endif /* GST_VAAPI_OBJECT_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index b5533ca4c8..96e3cad81c 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -25,6 +25,7 @@ #ifndef GST_VAAPI_PROFILE_H #define GST_VAAPI_PROFILE_H +#include #include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index aebad7ea08..c2ba257b1e 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -31,7 +31,6 @@ #include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapisubpicture.h" -#include "gstvaapiobject_priv.h" #include "gstvaapiimage_priv.h" #define DEBUG 1 diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.h b/gst-libs/gst/vaapi/gstvaapisubpicture.h index 8c241b292e..d61314d586 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.h +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.h @@ -25,7 +25,6 @@ #ifndef GST_VAAPI_SUBPICTURE_H #define GST_VAAPI_SUBPICTURE_H -#include #include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h index f702a09e67..822bb1c9f4 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.h +++ b/gst-libs/gst/vaapi/gstvaapisurface.h @@ -25,7 +25,6 @@ #ifndef GST_VAAPI_SURFACE_H #define GST_VAAPI_SURFACE_H -#include #include #include #include diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h index 76bfba89a8..6abe2a229d 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h @@ -27,7 +27,6 @@ #include "gstvaapiminiobject.h" #include "gstvaapisurfaceproxy.h" -#include "gstvaapiobject_priv.h" #include "gstvaapisurface_priv.h" #define GST_VAAPI_SURFACE_PROXY(obj) \ diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index cb3ef3a6d4..8c9c10e84f 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -30,7 +30,6 @@ #include "sysdeps.h" #include "gstvaapivideopool.h" #include "gstvaapivideopool_priv.h" -#include "gstvaapiobject.h" #define DEBUG 1 #include "gstvaapidebug.h" diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 8a8d321a34..246ac30bbf 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -20,7 +20,6 @@ gstlibvaapi_sources = [ 'gstvaapiimage.c', 'gstvaapiimagepool.c', 'gstvaapiminiobject.c', - 'gstvaapiobject.c', 'gstvaapiparser_frame.c', 'gstvaapiprofile.c', 'gstvaapiprofilecaps.c', @@ -59,7 +58,6 @@ gstlibvaapi_headers = [ 'gstvaapifilter.h', 'gstvaapiimage.h', 'gstvaapiimagepool.h', - 'gstvaapiobject.h', 'gstvaapiprofile.h', 'gstvaapiprofilecaps.h', 'gstvaapisubpicture.h', From 31d85bfb650aafa3fa52ebcfe3c7255a7e6b56e7 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 3 Jun 2020 17:37:48 -0400 Subject: [PATCH 3605/3781] Use gst_type_mark_as_plugin_api() for all non-element plugin types --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 6 ++++++ gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 3 +++ gst-libs/gst/vaapi/gstvaapifilter.c | 4 ++++ gst-libs/gst/vaapi/gstvaapivalue.c | 5 +++++ gst/vaapi/gstvaapipostproc.c | 1 + 6 files changed, 20 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 5b74d8212c..295de3bfdb 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1225,6 +1225,7 @@ gst_vaapi_display_class_init (GstVaapiDisplayClass * klass) "The display contrast value", 0.0, 2.0, 1.0, G_PARAM_READWRITE); g_object_class_install_properties (object_class, N_PROPERTIES, g_properties); + gst_type_mark_as_plugin_api (gst_vaapi_display_type_get_type ()); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 153c5d909c..22ea8b169c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -4045,6 +4045,12 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_object_class_install_properties (object_class, ENCODER_H264_N_PROPERTIES, properties); + + gst_type_mark_as_plugin_api (GST_VAAPI_TYPE_ENCODER_MBBRC); + gst_type_mark_as_plugin_api (gst_vaapi_encoder_h264_prediction_type ()); + gst_type_mark_as_plugin_api (g_class_data.rate_control_get_type ()); + gst_type_mark_as_plugin_api (g_class_data.encoder_tune_get_type ()); + gst_type_mark_as_plugin_api (gst_vaapi_encoder_h264_compliance_mode_type ()); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 8599321d0b..bee501f20b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -3173,6 +3173,9 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_object_class_install_properties (object_class, ENCODER_H265_N_PROPERTIES, properties); + + gst_type_mark_as_plugin_api (g_class_data.rate_control_get_type ()); + gst_type_mark_as_plugin_api (g_class_data.encoder_tune_get_type ()); } /** diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index f33eb11bb8..c0fb1c2541 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -121,6 +121,8 @@ gst_vaapi_scale_method_get_type (void) const GType type = g_enum_register_static ("GstVaapiScaleMethod", enum_values); g_once_init_leave (&g_type, type); + + gst_type_mark_as_plugin_api (type); } return g_type; } @@ -147,6 +149,7 @@ gst_vaapi_deinterlace_method_get_type (void) if (g_once_init_enter (&g_type)) { const GType type = g_enum_register_static ("GstVaapiDeinterlaceMethod", enum_values); + gst_type_mark_as_plugin_api (type); g_once_init_leave (&g_type, type); } return g_type; @@ -170,6 +173,7 @@ gst_vaapi_deinterlace_flags_get_type (void) if (g_once_init_enter (&g_type)) { const GType type = g_enum_register_static ("GstVaapiDeinterlaceFlags", enum_values); + gst_type_mark_as_plugin_api (type); g_once_init_leave (&g_type, type); } return g_type; diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 5b5c990197..c8aa8fcdb9 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -56,6 +56,7 @@ gst_vaapi_point_get_type (void) GType type = g_boxed_type_register_static (g_intern_static_string ("GstVaapiPoint"), default_copy_func, default_free_func); + gst_type_mark_as_plugin_api (type); g_once_init_leave (&g_type, type); } return g_type; @@ -73,6 +74,7 @@ gst_vaapi_rectangle_get_type (void) g_boxed_type_register_static (g_intern_static_string ("GstVaapiRectangle"), default_copy_func, default_free_func); + gst_type_mark_as_plugin_api (type); g_once_init_leave (&g_type, type); } return g_type; @@ -95,6 +97,7 @@ gst_vaapi_render_mode_get_type (void) if (g_once_init_enter (&g_type)) { GType type = g_enum_register_static ("GstVaapiRenderMode", render_modes); + gst_type_mark_as_plugin_api (type); g_once_init_leave (&g_type, type); } return g_type; @@ -123,6 +126,7 @@ gst_vaapi_rotation_get_type (void) if (g_once_init_enter (&g_type)) { GType type = g_enum_register_static ("GstVaapiRotation", rotation_values); + gst_type_mark_as_plugin_api (type); g_once_init_leave (&g_type, type); } return g_type; @@ -160,6 +164,7 @@ gst_vaapi_rate_control_get_type (void) if (g_once_init_enter (&g_type)) { GType type = g_enum_register_static ("GstVaapiRateControl", rate_control_values); + gst_type_mark_as_plugin_api (type); g_once_init_leave (&g_type, type); } return g_type; diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 16efffedec..3fc58c6a7c 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -2315,6 +2315,7 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) DEFAULT_DEINTERLACE_METHOD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + filter_ops = gst_vaapi_filter_get_operations (NULL); if (!filter_ops) return; From 41fee777a6b302a7d77b3a839158f52c8a3835ea Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 3 Jun 2020 17:38:10 -0400 Subject: [PATCH 3606/3781] docs: Update plugin cache with the new format And fix the default URL which should not be inside quotes. --- docs/gst_plugins_cache.json | 2436 ++++++++++------------------------- meson_options.txt | 2 +- 2 files changed, 676 insertions(+), 1762 deletions(-) diff --git a/docs/gst_plugins_cache.json b/docs/gst_plugins_cache.json index 4e15a6181d..e1a07b85f8 100644 --- a/docs/gst_plugins_cache.json +++ b/docs/gst_plugins_cache.json @@ -4,7 +4,6 @@ "elements": { "vaapidecodebin": { "author": "Sreerenj Balachandran , Victor Jaquez ", - "classification": "Codec/Decoder/Video", "description": "A VA-API based bin with a decoder and a postprocessor", "hierarchy": [ "GstVaapiDecodeBin", @@ -14,9 +13,11 @@ "GInitiallyUnowned", "GObject" ], - "klass": "Codec/Decoder/Video", + "interfaces": [ + "GstChildProxy" + ], + "klass": "Codec/Decoder/Video/Hardware", "long-name": "VA-API Decode Bin", - "name": "vaapidecodebin", "pad-templates": { "sink": { "caps": "video/mpeg:\n mpegversion: 2\n systemstream: false\nvideo/mpeg:\n mpegversion: 4\nvideo/x-divx:\nvideo/x-xvid:\nvideo/x-h263:\nvideo/x-h264:\nvideo/x-h265:\nvideo/x-wmv:\nvideo/x-vp8:\nvideo/x-vp9:\n", @@ -24,7 +25,7 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, P012_BE, P012_LE, I420_12BE, I420_12LE, Y212_BE, Y212_LE, I422_12BE, I422_12LE, Y412_BE, Y412_LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40, Y444_16BE, Y444_16LE, P016_BE, P016_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", "direction": "src", "presence": "always" } @@ -35,43 +36,17 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "deinterlace-method": { "blurb": "Deinterlace method to use", "construct": false, "construct-only": false, - "default": "bob (1)", - "enum": true, - "type-name": "GstVaapiDeinterlaceMethod", - "values": [ - { - "desc": "Disable deinterlacing", - "name": "none", - "value": "0" - }, - { - "desc": "Bob deinterlacing", - "name": "bob", - "value": "1" - }, - { - "desc": "Weave deinterlacing", - "name": "weave", - "value": "2" - }, - { - "desc": "Motion adaptive deinterlacing", - "name": "motion-adaptive", - "value": "3" - }, - { - "desc": "Motion compensated deinterlacing", - "name": "motion-compensated", - "value": "4" - } - ], + "default": "none (0)", + "readable": true, + "type": "GstVaapiDeinterlaceMethod", "writable": true }, "disable-vpp": { @@ -79,17 +54,19 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "max-size-buffers": { "blurb": "Max. number of buffers in the queue (0=disable)", "construct": false, "construct-only": false, - "default": "0", + "default": "1", "max": "-1", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "max-size-bytes": { @@ -99,7 +76,8 @@ "default": "0", "max": "-1", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "max-size-time": { @@ -109,7 +87,8 @@ "default": "0", "max": "18446744073709551615", "min": "0", - "type-name": "guint64", + "readable": true, + "type": "guint64", "writable": true }, "message-forward": { @@ -117,23 +96,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", - "writable": true - }, - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "NULL", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", + "readable": true, + "type": "gboolean", "writable": true } }, @@ -141,7 +105,6 @@ }, "vaapih264dec": { "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", - "classification": "Codec/Decoder/Video", "description": "A VA-API based H264 video decoder", "hierarchy": [ "GstVaapiDecode_h264", @@ -153,7 +116,6 @@ ], "klass": "Codec/Decoder/Video/Hardware", "long-name": "VA-API H264 decoder", - "name": "vaapih264dec", "pad-templates": { "sink": { "caps": "video/x-h264:\n", @@ -161,7 +123,7 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } @@ -172,7 +134,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "low-latency": { @@ -180,23 +143,17 @@ "construct": true, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "NULL", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", + "qos": { + "blurb": "Handle Quality-of-Service events from downstream", "construct": false, "construct-only": false, - "type-name": "GstObject", + "default": "true", + "readable": true, + "type": "gboolean", "writable": true } }, @@ -204,7 +161,6 @@ }, "vaapih264enc": { "author": "Wind Yuan ", - "classification": "Codec/Encoder/Video", "description": "A VA-API based H264 video encoder", "hierarchy": [ "GstVaapiEncodeH264", @@ -215,12 +171,14 @@ "GInitiallyUnowned", "GObject" ], + "interfaces": [ + "GstPreset" + ], "klass": "Codec/Encoder/Video/Hardware", "long-name": "VA-API H264 encoder", - "name": "vaapih264enc", "pad-templates": { "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "caps": "video/x-raw:\n format: { NV12, YV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(memory:VASurface):\n format: { NV12, YV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", "direction": "sink", "presence": "always" }, @@ -231,22 +189,15 @@ } }, "properties": { - "aud": { - "blurb": "Use AU (Access Unit) delimeter", - "construct": false, - "construct-only": false, - "default": "false", - "type-name": "gboolean", - "writable": true - }, "bitrate": { "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", "construct": false, "construct-only": false, "default": "0", - "max": "102400", + "max": "2048000", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "cabac": { @@ -254,7 +205,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "compliance-mode": { @@ -262,20 +214,8 @@ "construct": false, "construct-only": false, "default": "strict (0)", - "enum": true, - "type-name": "GstVaapiEncoderH264ComplianceMode", - "values": [ - { - "desc": "Strict compliance to the H264 Specification ", - "name": "strict", - "value": "0" - }, - { - "desc": "Restrict the allocation size of coded-buffer", - "name": "restrict-buf-alloc", - "value": "1" - } - ], + "readable": true, + "type": "GstVaapiEncoderH264ComplianceMode", "writable": true }, "cpb-length": { @@ -285,7 +225,8 @@ "default": "1500", "max": "10000", "min": "1", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "dct8x8": { @@ -293,7 +234,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "default-roi-delta-qp": { @@ -303,7 +245,8 @@ "default": "-10", "max": "10", "min": "-10", - "type-name": "gint", + "readable": true, + "type": "gint", "writable": true }, "init-qp": { @@ -313,7 +256,8 @@ "default": "26", "max": "51", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "keyframe-period": { @@ -323,7 +267,8 @@ "default": "30", "max": "-1", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "max-bframes": { @@ -333,7 +278,19 @@ "default": "0", "max": "10", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", + "writable": true + }, + "max-qp": { + "blurb": "Maximum quantizer value", + "construct": false, + "construct-only": false, + "default": "51", + "max": "51", + "min": "0", + "readable": true, + "type": "guint", "writable": true }, "mbbrc": { @@ -341,25 +298,8 @@ "construct": false, "construct-only": false, "default": "auto (0)", - "enum": true, - "type-name": "GstVaapiEncoderMbbrc", - "values": [ - { - "desc": "Auto", - "name": "auto", - "value": "0" - }, - { - "desc": "On", - "name": "on", - "value": "1" - }, - { - "desc": "Off", - "name": "off", - "value": "2" - } - ], + "readable": true, + "type": "GstVaapiEncoderMbbrc", "writable": true }, "min-qp": { @@ -369,16 +309,8 @@ "default": "1", "max": "51", "min": "0", - "type-name": "guint", - "writable": true - }, - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "NULL", - "hotdoc-fixed-default": true, - "type-name": "gchararray", + "readable": true, + "type": "guint", "writable": true }, "num-slices": { @@ -388,7 +320,8 @@ "default": "1", "max": "200", "min": "1", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "num-views": { @@ -398,14 +331,8 @@ "default": "1", "max": "10", "min": "1", - "type-name": "guint", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", + "readable": true, + "type": "guint", "writable": true }, "prediction-type": { @@ -413,25 +340,8 @@ "construct": false, "construct-only": false, "default": "default (0)", - "enum": true, - "type-name": "GstVaapiEncoderH264PredictionType", - "values": [ - { - "desc": "Default encode, prev/next frame as ref ", - "name": "default", - "value": "0" - }, - { - "desc": "Hierarchical P frame encode", - "name": "hierarchical-p", - "value": "1" - }, - { - "desc": "Hierarchical B frame encode", - "name": "hierarchical-b", - "value": "2" - } - ], + "readable": true, + "type": "GstVaapiEncoderH264PredictionType", "writable": true }, "qos": { @@ -439,7 +349,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "qp-ib": { @@ -449,7 +360,8 @@ "default": "0", "max": "51", "min": "-51", - "type-name": "gint", + "readable": true, + "type": "gint", "writable": true }, "qp-ip": { @@ -459,7 +371,19 @@ "default": "0", "max": "51", "min": "-51", - "type-name": "gint", + "readable": true, + "type": "gint", + "writable": true + }, + "quality-factor": { + "blurb": "quality factor for ICQ/QVBR bitrate control mode(low value means higher-quality, higher value means lower-quality)", + "construct": false, + "construct-only": false, + "default": "26", + "max": "51", + "min": "1", + "readable": true, + "type": "guint", "writable": true }, "quality-level": { @@ -469,7 +393,8 @@ "default": "4", "max": "7", "min": "1", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "rate-control": { @@ -477,30 +402,8 @@ "construct": false, "construct-only": false, "default": "cqp (1)", - "enum": true, - "type-name": "GstVaapiRateControlH264", - "values": [ - { - "desc": "Constant QP", - "name": "cqp", - "value": "1" - }, - { - "desc": "Constant bitrate", - "name": "cbr", - "value": "2" - }, - { - "desc": "Variable bitrate", - "name": "vbr", - "value": "4" - }, - { - "desc": "Variable bitrate - Constrained", - "name": "vbr_constrained", - "value": "5" - } - ], + "readable": true, + "type": "GstVaapiRateControlH264", "writable": true }, "refs": { @@ -510,7 +413,8 @@ "default": "1", "max": "8", "min": "1", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "target-percentage": { @@ -520,7 +424,8 @@ "default": "70", "max": "100", "min": "1", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "temporal-levels": { @@ -530,7 +435,8 @@ "default": "1", "max": "4", "min": "1", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "trellis": { @@ -538,7 +444,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "tune": { @@ -546,32 +453,16 @@ "construct": false, "construct-only": false, "default": "none (0)", - "enum": true, - "type-name": "GstVaapiEncoderTuneH264", - "values": [ - { - "desc": "None", - "name": "none", - "value": "0" - }, - { - "desc": "High compression", - "name": "high-compression", - "value": "1" - }, - { - "desc": "Low power mode", - "name": "low-power", - "value": "3" - } - ], + "readable": true, + "type": "GstVaapiEncoderTuneH264", "writable": true }, "view-ids": { "blurb": "Set of View Ids used for MVC encoding", "construct": false, "construct-only": false, - "type-name": "GstValueArray", + "readable": true, + "type": "GstValueArray", "writable": true } }, @@ -579,7 +470,6 @@ }, "vaapih265dec": { "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", - "classification": "Codec/Decoder/Video", "description": "A VA-API based H265 video decoder", "hierarchy": [ "GstVaapiDecode_h265", @@ -591,7 +481,6 @@ ], "klass": "Codec/Decoder/Video/Hardware", "long-name": "VA-API H265 decoder", - "name": "vaapih265dec", "pad-templates": { "sink": { "caps": "video/x-h265:\n", @@ -599,26 +488,19 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } }, "properties": { - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "NULL", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", + "qos": { + "blurb": "Handle Quality-of-Service events from downstream", "construct": false, "construct-only": false, - "type-name": "GstObject", + "default": "true", + "readable": true, + "type": "gboolean", "writable": true } }, @@ -626,7 +508,6 @@ }, "vaapih265enc": { "author": "Sreerenj Balachandran ", - "classification": "Codec/Encoder/Video", "description": "A VA-API based H265 video encoder", "hierarchy": [ "GstVaapiEncodeH265", @@ -637,17 +518,19 @@ "GInitiallyUnowned", "GObject" ], + "interfaces": [ + "GstPreset" + ], "klass": "Codec/Encoder/Video/Hardware", "long-name": "VA-API H265 encoder", - "name": "vaapih265enc", "pad-templates": { "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "caps": "video/x-raw:\n format: { NV12, YV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(memory:VASurface):\n format: { NV12, YV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", "direction": "sink", "presence": "always" }, "src": { - "caps": "video/x-h265:\n stream-format: { (string)hvc1, (string)byte-stream }\n alignment: au\n profile: { (string)main, (string)main-10 }\n", + "caps": "video/x-h265:\n stream-format: { (string)hvc1, (string)byte-stream }\n alignment: au\n profile: { (string)main, (string)main-10, (string)main-444, (string)main-444-10 }\n", "direction": "src", "presence": "always" } @@ -658,9 +541,10 @@ "construct": false, "construct-only": false, "default": "0", - "max": "102400", + "max": "2048000", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "cpb-length": { @@ -670,7 +554,8 @@ "default": "1500", "max": "10000", "min": "1", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "default-roi-delta-qp": { @@ -680,7 +565,8 @@ "default": "-10", "max": "10", "min": "-10", - "type-name": "gint", + "readable": true, + "type": "gint", "writable": true }, "init-qp": { @@ -690,7 +576,8 @@ "default": "26", "max": "51", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "keyframe-period": { @@ -700,7 +587,8 @@ "default": "30", "max": "-1", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "low-delay-b": { @@ -708,7 +596,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "max-bframes": { @@ -718,7 +607,19 @@ "default": "0", "max": "10", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", + "writable": true + }, + "max-qp": { + "blurb": "Maximum quantizer value", + "construct": false, + "construct-only": false, + "default": "51", + "max": "51", + "min": "0", + "readable": true, + "type": "guint", "writable": true }, "mbbrc": { @@ -726,25 +627,8 @@ "construct": false, "construct-only": false, "default": "auto (0)", - "enum": true, - "type-name": "GstVaapiEncoderMbbrc", - "values": [ - { - "desc": "Auto", - "name": "auto", - "value": "0" - }, - { - "desc": "On", - "name": "on", - "value": "1" - }, - { - "desc": "Off", - "name": "off", - "value": "2" - } - ], + "readable": true, + "type": "GstVaapiEncoderMbbrc", "writable": true }, "min-qp": { @@ -754,16 +638,8 @@ "default": "1", "max": "51", "min": "0", - "type-name": "guint", - "writable": true - }, - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "NULL", - "hotdoc-fixed-default": true, - "type-name": "gchararray", + "readable": true, + "type": "guint", "writable": true }, "num-slices": { @@ -773,14 +649,8 @@ "default": "1", "max": "200", "min": "1", - "type-name": "guint", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", + "readable": true, + "type": "guint", "writable": true }, "qos": { @@ -788,7 +658,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "qp-ib": { @@ -798,7 +669,8 @@ "default": "0", "max": "51", "min": "-51", - "type-name": "gint", + "readable": true, + "type": "gint", "writable": true }, "qp-ip": { @@ -808,7 +680,19 @@ "default": "0", "max": "51", "min": "-51", - "type-name": "gint", + "readable": true, + "type": "gint", + "writable": true + }, + "quality-factor": { + "blurb": "quality factor for ICQ/QBVR bitrate control mode (lower value means higher quality, higher value means lower quality)", + "construct": false, + "construct-only": false, + "default": "26", + "max": "51", + "min": "1", + "readable": true, + "type": "guint", "writable": true }, "quality-level": { @@ -818,7 +702,8 @@ "default": "4", "max": "7", "min": "1", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "rate-control": { @@ -826,25 +711,8 @@ "construct": false, "construct-only": false, "default": "cqp (1)", - "enum": true, - "type-name": "GstVaapiRateControlH265", - "values": [ - { - "desc": "Constant QP", - "name": "cqp", - "value": "1" - }, - { - "desc": "Constant bitrate", - "name": "cbr", - "value": "2" - }, - { - "desc": "Variable bitrate", - "name": "vbr", - "value": "4" - } - ], + "readable": true, + "type": "GstVaapiRateControlH265", "writable": true }, "refs": { @@ -854,7 +722,8 @@ "default": "1", "max": "3", "min": "1", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "target-percentage": { @@ -864,7 +733,8 @@ "default": "70", "max": "100", "min": "1", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "trellis": { @@ -872,7 +742,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "tune": { @@ -880,20 +751,8 @@ "construct": false, "construct-only": false, "default": "none (0)", - "enum": true, - "type-name": "GstVaapiEncoderTuneH265", - "values": [ - { - "desc": "None", - "name": "none", - "value": "0" - }, - { - "desc": "Low power mode", - "name": "low-power", - "value": "3" - } - ], + "readable": true, + "type": "GstVaapiEncoderTuneH265", "writable": true } }, @@ -901,7 +760,6 @@ }, "vaapijpegdec": { "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", - "classification": "Codec/Decoder/Video", "description": "A VA-API based JPEG video decoder", "hierarchy": [ "GstVaapiDecode_jpeg", @@ -913,7 +771,6 @@ ], "klass": "Codec/Decoder/Video/Hardware", "long-name": "VA-API JPEG decoder", - "name": "vaapijpegdec", "pad-templates": { "sink": { "caps": "image/jpeg:\n", @@ -921,172 +778,26 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } }, "properties": { - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "NULL", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", + "qos": { + "blurb": "Handle Quality-of-Service events from downstream", "construct": false, "construct-only": false, - "type-name": "GstObject", + "default": "true", + "readable": true, + "type": "gboolean", "writable": true } }, "rank": "marginal" }, - "vaapijpegenc": { - "author": "Sreerenj Balachandran ", - "classification": "Codec/Encoder/Image", - "description": "A VA-API based JPEG video encoder", - "hierarchy": [ - "GstVaapiEncodeJpeg", - "GstVaapiEncode", - "GstVideoEncoder", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "klass": "Codec/Encoder/Image", - "long-name": "VA-API JPEG encoder", - "name": "vaapijpegenc", - "pad-templates": { - "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", - "direction": "sink", - "presence": "always" - }, - "src": { - "caps": "image/jpeg:\n", - "direction": "src", - "presence": "always" - } - }, - "properties": { - "bitrate": { - "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", - "construct": false, - "construct-only": false, - "default": "0", - "max": "102400", - "min": "0", - "type-name": "guint", - "writable": true - }, - "default-roi-delta-qp": { - "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", - "construct": false, - "construct-only": false, - "default": "-10", - "max": "10", - "min": "-10", - "type-name": "gint", - "writable": true - }, - "keyframe-period": { - "blurb": "Maximal distance between two keyframes (0: auto-calculate)", - "construct": false, - "construct-only": false, - "default": "30", - "max": "-1", - "min": "0", - "type-name": "guint", - "writable": true - }, - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "vaapiencodejpeg0", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", - "writable": true - }, - "qos": { - "blurb": "Handle Quality-of-Service events from downstream", - "construct": false, - "construct-only": false, - "default": "false", - "type-name": "gboolean", - "writable": true - }, - "quality": { - "blurb": "Quality factor", - "construct": false, - "construct-only": false, - "default": "50", - "max": "100", - "min": "0", - "type-name": "guint", - "writable": true - }, - "quality-level": { - "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", - "construct": false, - "construct-only": false, - "default": "4", - "max": "7", - "min": "1", - "type-name": "guint", - "writable": true - }, - "rate-control": { - "blurb": "Rate control mode", - "construct": false, - "construct-only": false, - "default": "none (0)", - "enum": true, - "type-name": "GstVaapiRateControlJPEG", - "values": [ - { - "desc": "None", - "name": "none", - "value": "0" - } - ], - "writable": true - }, - "tune": { - "blurb": "Encoder tuning option", - "construct": false, - "construct-only": false, - "default": "none (0)", - "enum": true, - "type-name": "GstVaapiEncoderTuneJPEG", - "values": [ - { - "desc": "None", - "name": "none", - "value": "0" - } - ], - "writable": true - } - }, - "rank": "primary" - }, "vaapimpeg2dec": { "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", - "classification": "Codec/Decoder/Video", "description": "A VA-API based MPEG2 video decoder", "hierarchy": [ "GstVaapiDecode_mpeg2", @@ -1098,7 +809,6 @@ ], "klass": "Codec/Decoder/Video/Hardware", "long-name": "VA-API MPEG2 decoder", - "name": "vaapimpeg2dec", "pad-templates": { "sink": { "caps": "video/mpeg:\n mpegversion: 2\n systemstream: false\n", @@ -1106,179 +816,19 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } }, "properties": { - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "NULL", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", - "writable": true - } - }, - "rank": "primary" - }, - "vaapimpeg2enc": { - "author": "Guangxin Xu ", - "classification": "Codec/Encoder/Video", - "description": "A VA-API based MPEG-2 video encoder", - "hierarchy": [ - "GstVaapiEncodeMpeg2", - "GstVaapiEncode", - "GstVideoEncoder", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "klass": "Codec/Encoder/Video", - "long-name": "VA-API MPEG-2 encoder", - "name": "vaapimpeg2enc", - "pad-templates": { - "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", - "direction": "sink", - "presence": "always" - }, - "src": { - "caps": "video/mpeg:\n mpegversion: 2\n systemstream: false\n", - "direction": "src", - "presence": "always" - } - }, - "properties": { - "bitrate": { - "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", - "construct": false, - "construct-only": false, - "default": "0", - "max": "102400", - "min": "0", - "type-name": "guint", - "writable": true - }, - "default-roi-delta-qp": { - "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", - "construct": false, - "construct-only": false, - "default": "-10", - "max": "10", - "min": "-10", - "type-name": "gint", - "writable": true - }, - "keyframe-period": { - "blurb": "Maximal distance between two keyframes (0: auto-calculate)", - "construct": false, - "construct-only": false, - "default": "30", - "max": "-1", - "min": "0", - "type-name": "guint", - "writable": true - }, - "max-bframes": { - "blurb": "Number of B-frames between I and P", - "construct": false, - "construct-only": false, - "default": "0", - "max": "16", - "min": "0", - "type-name": "guint", - "writable": true - }, - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "vaapiencodempeg2-0", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", - "writable": true - }, "qos": { "blurb": "Handle Quality-of-Service events from downstream", "construct": false, "construct-only": false, - "default": "false", - "type-name": "gboolean", - "writable": true - }, - "quality-level": { - "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", - "construct": false, - "construct-only": false, - "default": "4", - "max": "7", - "min": "1", - "type-name": "guint", - "writable": true - }, - "quantizer": { - "blurb": "Constant quantizer (if rate-control mode is CQP)", - "construct": false, - "construct-only": false, - "default": "8", - "max": "62", - "min": "2", - "type-name": "guint", - "writable": true - }, - "rate-control": { - "blurb": "Rate control mode", - "construct": false, - "construct-only": false, - "default": "cqp (1)", - "enum": true, - "type-name": "GstVaapiRateControlMPEG2", - "values": [ - { - "desc": "Constant QP", - "name": "cqp", - "value": "1" - }, - { - "desc": "Constant bitrate", - "name": "cbr", - "value": "2" - } - ], - "writable": true - }, - "tune": { - "blurb": "Encoder tuning option", - "construct": false, - "construct-only": false, - "default": "none (0)", - "enum": true, - "type-name": "GstVaapiEncoderTuneMPEG2", - "values": [ - { - "desc": "None", - "name": "none", - "value": "0" - } - ], + "default": "true", + "readable": true, + "type": "gboolean", "writable": true } }, @@ -1286,7 +836,6 @@ }, "vaapipostproc": { "author": "Gwenole Beauchesne ", - "classification": "Filter/Converter/Video;Filter/Converter/Video/Scaler;Filter/Effect/Video;Filter/Effect/Video/Deinterlace", "description": "A VA-API video postprocessing filter", "hierarchy": [ "GstVaapiPostproc", @@ -1296,17 +845,19 @@ "GInitiallyUnowned", "GObject" ], + "interfaces": [ + "GstColorBalance" + ], "klass": "Filter/Converter/Effect/Video/Scaler/Deinterlace/Hardware", "long-name": "VA-API video postprocessing", - "name": "vaapipostproc", "pad-templates": { "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\nvideo/x-raw:\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\n", "direction": "sink", "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: { (string)progressive, (string)interleaved, (string)mixed }\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } @@ -1319,7 +870,8 @@ "default": "0", "max": "1", "min": "-1", - "type-name": "gfloat", + "readable": true, + "type": "gfloat", "writable": true }, "contrast": { @@ -1329,7 +881,52 @@ "default": "1", "max": "2", "min": "0", - "type-name": "gfloat", + "readable": true, + "type": "gfloat", + "writable": true + }, + "crop-bottom": { + "blurb": "Pixels to crop at bottom", + "construct": false, + "construct-only": false, + "default": "0", + "max": "2147483647", + "min": "0", + "readable": true, + "type": "guint", + "writable": true + }, + "crop-left": { + "blurb": "Pixels to crop at left", + "construct": false, + "construct-only": false, + "default": "0", + "max": "2147483647", + "min": "0", + "readable": true, + "type": "guint", + "writable": true + }, + "crop-right": { + "blurb": "Pixels to crop at right", + "construct": false, + "construct-only": false, + "default": "0", + "max": "2147483647", + "min": "0", + "readable": true, + "type": "guint", + "writable": true + }, + "crop-top": { + "blurb": "Pixels to crop at top", + "construct": false, + "construct-only": false, + "default": "0", + "max": "2147483647", + "min": "0", + "readable": true, + "type": "guint", "writable": true }, "deinterlace-method": { @@ -1337,35 +934,8 @@ "construct": false, "construct-only": false, "default": "bob (1)", - "enum": true, - "type-name": "GstVaapiDeinterlaceMethod", - "values": [ - { - "desc": "Disable deinterlacing", - "name": "none", - "value": "0" - }, - { - "desc": "Bob deinterlacing", - "name": "bob", - "value": "1" - }, - { - "desc": "Weave deinterlacing", - "name": "weave", - "value": "2" - }, - { - "desc": "Motion adaptive deinterlacing", - "name": "motion-adaptive", - "value": "3" - }, - { - "desc": "Motion compensated deinterlacing", - "name": "motion-compensated", - "value": "4" - } - ], + "readable": true, + "type": "GstVaapiDeinterlaceMethod", "writable": true }, "deinterlace-mode": { @@ -1373,25 +943,8 @@ "construct": false, "construct-only": false, "default": "auto (0)", - "enum": true, - "type-name": "GstVaapiDeinterlaceMode", - "values": [ - { - "desc": "Auto detection", - "name": "auto", - "value": "0" - }, - { - "desc": "Force deinterlacing", - "name": "interlaced", - "value": "1" - }, - { - "desc": "Never deinterlace", - "name": "disabled", - "value": "2" - } - ], + "readable": true, + "type": "GstVaapiDeinterlaceMode", "writable": true }, "denoise": { @@ -1401,7 +954,8 @@ "default": "0", "max": "1", "min": "0", - "type-name": "gfloat", + "readable": true, + "type": "gfloat", "writable": true }, "force-aspect-ratio": { @@ -1409,7 +963,8 @@ "construct": false, "construct-only": false, "default": "true", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "format": { @@ -1417,445 +972,17 @@ "construct": false, "construct-only": false, "default": "encoded (1)", - "enum": true, - "type-name": "GstVideoFormat", - "values": [ - { - "desc": "GST_VIDEO_FORMAT_UNKNOWN", - "name": "unknown", - "value": "0" - }, - { - "desc": "GST_VIDEO_FORMAT_ENCODED", - "name": "encoded", - "value": "1" - }, - { - "desc": "GST_VIDEO_FORMAT_I420", - "name": "i420", - "value": "2" - }, - { - "desc": "GST_VIDEO_FORMAT_YV12", - "name": "yv12", - "value": "3" - }, - { - "desc": "GST_VIDEO_FORMAT_YUY2", - "name": "yuy2", - "value": "4" - }, - { - "desc": "GST_VIDEO_FORMAT_UYVY", - "name": "uyvy", - "value": "5" - }, - { - "desc": "GST_VIDEO_FORMAT_AYUV", - "name": "ayuv", - "value": "6" - }, - { - "desc": "GST_VIDEO_FORMAT_RGBx", - "name": "rgbx", - "value": "7" - }, - { - "desc": "GST_VIDEO_FORMAT_BGRx", - "name": "bgrx", - "value": "8" - }, - { - "desc": "GST_VIDEO_FORMAT_xRGB", - "name": "xrgb", - "value": "9" - }, - { - "desc": "GST_VIDEO_FORMAT_xBGR", - "name": "xbgr", - "value": "10" - }, - { - "desc": "GST_VIDEO_FORMAT_RGBA", - "name": "rgba", - "value": "11" - }, - { - "desc": "GST_VIDEO_FORMAT_BGRA", - "name": "bgra", - "value": "12" - }, - { - "desc": "GST_VIDEO_FORMAT_ARGB", - "name": "argb", - "value": "13" - }, - { - "desc": "GST_VIDEO_FORMAT_ABGR", - "name": "abgr", - "value": "14" - }, - { - "desc": "GST_VIDEO_FORMAT_RGB", - "name": "rgb", - "value": "15" - }, - { - "desc": "GST_VIDEO_FORMAT_BGR", - "name": "bgr", - "value": "16" - }, - { - "desc": "GST_VIDEO_FORMAT_Y41B", - "name": "y41b", - "value": "17" - }, - { - "desc": "GST_VIDEO_FORMAT_Y42B", - "name": "y42b", - "value": "18" - }, - { - "desc": "GST_VIDEO_FORMAT_YVYU", - "name": "yvyu", - "value": "19" - }, - { - "desc": "GST_VIDEO_FORMAT_Y444", - "name": "y444", - "value": "20" - }, - { - "desc": "GST_VIDEO_FORMAT_v210", - "name": "v210", - "value": "21" - }, - { - "desc": "GST_VIDEO_FORMAT_v216", - "name": "v216", - "value": "22" - }, - { - "desc": "GST_VIDEO_FORMAT_NV12", - "name": "nv12", - "value": "23" - }, - { - "desc": "GST_VIDEO_FORMAT_NV21", - "name": "nv21", - "value": "24" - }, - { - "desc": "GST_VIDEO_FORMAT_GRAY8", - "name": "gray8", - "value": "25" - }, - { - "desc": "GST_VIDEO_FORMAT_GRAY16_BE", - "name": "gray16-be", - "value": "26" - }, - { - "desc": "GST_VIDEO_FORMAT_GRAY16_LE", - "name": "gray16-le", - "value": "27" - }, - { - "desc": "GST_VIDEO_FORMAT_v308", - "name": "v308", - "value": "28" - }, - { - "desc": "GST_VIDEO_FORMAT_RGB16", - "name": "rgb16", - "value": "29" - }, - { - "desc": "GST_VIDEO_FORMAT_BGR16", - "name": "bgr16", - "value": "30" - }, - { - "desc": "GST_VIDEO_FORMAT_RGB15", - "name": "rgb15", - "value": "31" - }, - { - "desc": "GST_VIDEO_FORMAT_BGR15", - "name": "bgr15", - "value": "32" - }, - { - "desc": "GST_VIDEO_FORMAT_UYVP", - "name": "uyvp", - "value": "33" - }, - { - "desc": "GST_VIDEO_FORMAT_A420", - "name": "a420", - "value": "34" - }, - { - "desc": "GST_VIDEO_FORMAT_RGB8P", - "name": "rgb8p", - "value": "35" - }, - { - "desc": "GST_VIDEO_FORMAT_YUV9", - "name": "yuv9", - "value": "36" - }, - { - "desc": "GST_VIDEO_FORMAT_YVU9", - "name": "yvu9", - "value": "37" - }, - { - "desc": "GST_VIDEO_FORMAT_IYU1", - "name": "iyu1", - "value": "38" - }, - { - "desc": "GST_VIDEO_FORMAT_ARGB64", - "name": "argb64", - "value": "39" - }, - { - "desc": "GST_VIDEO_FORMAT_AYUV64", - "name": "ayuv64", - "value": "40" - }, - { - "desc": "GST_VIDEO_FORMAT_r210", - "name": "r210", - "value": "41" - }, - { - "desc": "GST_VIDEO_FORMAT_I420_10BE", - "name": "i420-10be", - "value": "42" - }, - { - "desc": "GST_VIDEO_FORMAT_I420_10LE", - "name": "i420-10le", - "value": "43" - }, - { - "desc": "GST_VIDEO_FORMAT_I422_10BE", - "name": "i422-10be", - "value": "44" - }, - { - "desc": "GST_VIDEO_FORMAT_I422_10LE", - "name": "i422-10le", - "value": "45" - }, - { - "desc": "GST_VIDEO_FORMAT_Y444_10BE", - "name": "y444-10be", - "value": "46" - }, - { - "desc": "GST_VIDEO_FORMAT_Y444_10LE", - "name": "y444-10le", - "value": "47" - }, - { - "desc": "GST_VIDEO_FORMAT_GBR", - "name": "gbr", - "value": "48" - }, - { - "desc": "GST_VIDEO_FORMAT_GBR_10BE", - "name": "gbr-10be", - "value": "49" - }, - { - "desc": "GST_VIDEO_FORMAT_GBR_10LE", - "name": "gbr-10le", - "value": "50" - }, - { - "desc": "GST_VIDEO_FORMAT_NV16", - "name": "nv16", - "value": "51" - }, - { - "desc": "GST_VIDEO_FORMAT_NV24", - "name": "nv24", - "value": "52" - }, - { - "desc": "GST_VIDEO_FORMAT_NV12_64Z32", - "name": "nv12-64z32", - "value": "53" - }, - { - "desc": "GST_VIDEO_FORMAT_A420_10BE", - "name": "a420-10be", - "value": "54" - }, - { - "desc": "GST_VIDEO_FORMAT_A420_10LE", - "name": "a420-10le", - "value": "55" - }, - { - "desc": "GST_VIDEO_FORMAT_A422_10BE", - "name": "a422-10be", - "value": "56" - }, - { - "desc": "GST_VIDEO_FORMAT_A422_10LE", - "name": "a422-10le", - "value": "57" - }, - { - "desc": "GST_VIDEO_FORMAT_A444_10BE", - "name": "a444-10be", - "value": "58" - }, - { - "desc": "GST_VIDEO_FORMAT_A444_10LE", - "name": "a444-10le", - "value": "59" - }, - { - "desc": "GST_VIDEO_FORMAT_NV61", - "name": "nv61", - "value": "60" - }, - { - "desc": "GST_VIDEO_FORMAT_P010_10BE", - "name": "p010-10be", - "value": "61" - }, - { - "desc": "GST_VIDEO_FORMAT_P010_10LE", - "name": "p010-10le", - "value": "62" - }, - { - "desc": "GST_VIDEO_FORMAT_IYU2", - "name": "iyu2", - "value": "63" - }, - { - "desc": "GST_VIDEO_FORMAT_VYUY", - "name": "vyuy", - "value": "64" - }, - { - "desc": "GST_VIDEO_FORMAT_GBRA", - "name": "gbra", - "value": "65" - }, - { - "desc": "GST_VIDEO_FORMAT_GBRA_10BE", - "name": "gbra-10be", - "value": "66" - }, - { - "desc": "GST_VIDEO_FORMAT_GBRA_10LE", - "name": "gbra-10le", - "value": "67" - }, - { - "desc": "GST_VIDEO_FORMAT_GBR_12BE", - "name": "gbr-12be", - "value": "68" - }, - { - "desc": "GST_VIDEO_FORMAT_GBR_12LE", - "name": "gbr-12le", - "value": "69" - }, - { - "desc": "GST_VIDEO_FORMAT_GBRA_12BE", - "name": "gbra-12be", - "value": "70" - }, - { - "desc": "GST_VIDEO_FORMAT_GBRA_12LE", - "name": "gbra-12le", - "value": "71" - }, - { - "desc": "GST_VIDEO_FORMAT_I420_12BE", - "name": "i420-12be", - "value": "72" - }, - { - "desc": "GST_VIDEO_FORMAT_I420_12LE", - "name": "i420-12le", - "value": "73" - }, - { - "desc": "GST_VIDEO_FORMAT_I422_12BE", - "name": "i422-12be", - "value": "74" - }, - { - "desc": "GST_VIDEO_FORMAT_I422_12LE", - "name": "i422-12le", - "value": "75" - }, - { - "desc": "GST_VIDEO_FORMAT_Y444_12BE", - "name": "y444-12be", - "value": "76" - }, - { - "desc": "GST_VIDEO_FORMAT_Y444_12LE", - "name": "y444-12le", - "value": "77" - }, - { - "desc": "GST_VIDEO_FORMAT_GRAY10_LE32", - "name": "gray10-le32", - "value": "78" - }, - { - "desc": "GST_VIDEO_FORMAT_NV12_10LE32", - "name": "nv12-10le32", - "value": "79" - }, - { - "desc": "GST_VIDEO_FORMAT_NV16_10LE32", - "name": "nv16-10le32", - "value": "80" - }, - { - "desc": "GST_VIDEO_FORMAT_NV12_10LE40", - "name": "nv12-10le40", - "value": "81" - }, - { - "desc": "GST_VIDEO_FORMAT_Y210", - "name": "y210", - "value": "82" - }, - { - "desc": "GST_VIDEO_FORMAT_Y410", - "name": "y410", - "value": "83" - }, - { - "desc": "GST_VIDEO_FORMAT_VUYA", - "name": "vuya", - "value": "84" - }, - { - "desc": "GST_VIDEO_FORMAT_BGR10A2_LE", - "name": "bgr10a2-le", - "value": "85" - }, - { - "desc": "GST_VIDEO_FORMAT_RGB10A2_LE", - "name": "rgb10a2-le", - "value": "86" - } - ], + "readable": true, + "type": "GstVideoFormat", + "writable": true + }, + "hdr-tone-map": { + "blurb": "Apply HDR tone mapping algorithm", + "construct": false, + "construct-only": false, + "default": "auto (0)", + "readable": true, + "type": "GstVaapiHDRToneMap", "writable": true }, "height": { @@ -1865,7 +992,8 @@ "default": "0", "max": "2147483647", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "hue": { @@ -1875,23 +1003,8 @@ "default": "0", "max": "180", "min": "-180", - "type-name": "gfloat", - "writable": true - }, - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "NULL", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", + "readable": true, + "type": "gfloat", "writable": true }, "qos": { @@ -1899,7 +1012,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "saturation": { @@ -1909,7 +1023,8 @@ "default": "1", "max": "2", "min": "0", - "type-name": "gfloat", + "readable": true, + "type": "gfloat", "writable": true }, "scale-method": { @@ -1917,25 +1032,8 @@ "construct": false, "construct-only": false, "default": "default (0)", - "enum": true, - "type-name": "GstVaapiScaleMethod", - "values": [ - { - "desc": "Default scaling mode", - "name": "default", - "value": "0" - }, - { - "desc": "Fast scaling mode", - "name": "fast", - "value": "1" - }, - { - "desc": "High quality scaling mode", - "name": "hq", - "value": "2" - } - ], + "readable": true, + "type": "GstVaapiScaleMethod", "writable": true }, "sharpen": { @@ -1945,7 +1043,8 @@ "default": "0", "max": "1", "min": "-1", - "type-name": "gfloat", + "readable": true, + "type": "gfloat", "writable": true }, "skin-tone-enhancement": { @@ -1953,7 +1052,28 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", + "writable": true + }, + "skin-tone-enhancement-level": { + "blurb": "Apply the skin tone enhancement algorithm with specified level", + "construct": false, + "construct-only": false, + "default": "3", + "max": "9", + "min": "0", + "readable": true, + "type": "guint", + "writable": true + }, + "video-direction": { + "blurb": "Video direction: rotation and flipping", + "construct": false, + "construct-only": false, + "default": "identity (0)", + "readable": true, + "type": "GstVideoOrientationMethod", "writable": true }, "width": { @@ -1963,7 +1083,8 @@ "default": "0", "max": "2147483647", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true } }, @@ -1971,7 +1092,6 @@ }, "vaapisink": { "author": "Gwenole Beauchesne ", - "classification": "Sink/Video", "description": "A VA-API based videosink", "hierarchy": [ "GstVaapiSink", @@ -1982,12 +1102,16 @@ "GInitiallyUnowned", "GObject" ], + "interfaces": [ + "GstVideoOverlay", + "GstColorBalance", + "GstNavigation" + ], "klass": "Sink/Video", "long-name": "VA-API sink", - "name": "vaapisink", "pad-templates": { "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:VASurface, meta:GstVideoOverlayComposition):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoOverlayComposition):\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:VASurface, meta:GstVideoOverlayComposition):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoOverlayComposition):\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, P012_BE, P012_LE, I420_12BE, I420_12LE, Y212_BE, Y212_LE, I422_12BE, I422_12LE, Y412_BE, Y412_LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40, Y444_16BE, Y444_16LE, P016_BE, P016_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, P012_BE, P012_LE, I420_12BE, I420_12LE, Y212_BE, Y212_LE, I422_12BE, I422_12LE, Y412_BE, Y412_LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40, Y444_16BE, Y444_16LE, P016_BE, P016_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "sink", "presence": "always" } @@ -1998,7 +1122,8 @@ "construct": false, "construct-only": false, "default": "true", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "blocksize": { @@ -2008,7 +1133,8 @@ "default": "4096", "max": "-1", "min": "0", - "type-name": "guint", + "readable": true, + "type": "guint", "writable": true }, "brightness": { @@ -2018,7 +1144,8 @@ "default": "0", "max": "1", "min": "-1", - "type-name": "gfloat", + "readable": true, + "type": "gfloat", "writable": true }, "contrast": { @@ -2028,7 +1155,8 @@ "default": "1", "max": "2", "min": "0", - "type-name": "gfloat", + "readable": true, + "type": "gfloat", "writable": true }, "display": { @@ -2036,40 +1164,8 @@ "construct": false, "construct-only": false, "default": "any (0)", - "enum": true, - "type-name": "GstVaapiDisplayType", - "values": [ - { - "desc": "Auto detection", - "name": "any", - "value": "0" - }, - { - "desc": "VA/X11 display", - "name": "x11", - "value": "1" - }, - { - "desc": "VA/GLX display", - "name": "glx", - "value": "2" - }, - { - "desc": "VA/EGL display", - "name": "egl", - "value": "5" - }, - { - "desc": "VA/Wayland display", - "name": "wayland", - "value": "3" - }, - { - "desc": "VA/DRM display", - "name": "drm", - "value": "4" - } - ], + "readable": true, + "type": "GstVaapiDisplayType", "writable": true }, "display-name": { @@ -2077,7 +1173,8 @@ "construct": false, "construct-only": false, "default": "NULL", - "type-name": "gchararray", + "readable": true, + "type": "gchararray", "writable": true }, "enable-last-sample": { @@ -2085,7 +1182,8 @@ "construct": false, "construct-only": false, "default": "true", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "force-aspect-ratio": { @@ -2093,7 +1191,8 @@ "construct": false, "construct-only": false, "default": "true", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "fullscreen": { @@ -2101,7 +1200,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "hue": { @@ -2111,14 +1211,16 @@ "default": "0", "max": "180", "min": "-180", - "type-name": "gfloat", + "readable": true, + "type": "gfloat", "writable": true }, "last-sample": { "blurb": "The last sample received in the sink", "construct": false, "construct-only": false, - "type-name": "GstSample", + "readable": true, + "type": "GstSample", "writable": false }, "max-bitrate": { @@ -2128,7 +1230,8 @@ "default": "0", "max": "18446744073709551615", "min": "0", - "type-name": "guint64", + "readable": true, + "type": "guint64", "writable": true }, "max-lateness": { @@ -2138,33 +1241,19 @@ "default": "5000000", "max": "9223372036854775807", "min": "-1", - "type-name": "gint64", - "writable": true - }, - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "NULL", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", + "readable": true, + "type": "gint64", "writable": true }, "processing-deadline": { - "blurb": "Maximum processing deadline in nanoseconds", + "blurb": "Maximum processing time for a buffer in nanoseconds", "construct": false, "construct-only": false, "default": "15000000", "max": "18446744073709551615", "min": "0", - "type-name": "guint64", + "readable": true, + "type": "guint64", "writable": true }, "qos": { @@ -2172,7 +1261,8 @@ "construct": false, "construct-only": false, "default": "true", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "render-delay": { @@ -2182,7 +1272,8 @@ "default": "0", "max": "18446744073709551615", "min": "0", - "type-name": "guint64", + "readable": true, + "type": "guint64", "writable": true }, "rotation": { @@ -2190,35 +1281,8 @@ "construct": false, "construct-only": false, "default": "0 (0)", - "enum": true, - "type-name": "GstVaapiRotation", - "values": [ - { - "desc": "Unrotated mode", - "name": "0", - "value": "0" - }, - { - "desc": "Rotated by 90\u00b0, clockwise", - "name": "90", - "value": "90" - }, - { - "desc": "Rotated by 180\u00b0, clockwise", - "name": "180", - "value": "180" - }, - { - "desc": "Rotated by 270\u00b0, clockwise", - "name": "270", - "value": "270" - }, - { - "desc": "Rotated by image-orientating tag\u00b0", - "name": "Automatic", - "value": "360" - } - ], + "readable": true, + "type": "GstVaapiRotation", "writable": true }, "saturation": { @@ -2228,7 +1292,8 @@ "default": "1", "max": "2", "min": "0", - "type-name": "gfloat", + "readable": true, + "type": "gfloat", "writable": true }, "show-preroll-frame": { @@ -2236,7 +1301,8 @@ "construct": true, "construct-only": false, "default": "true", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "signal-handoffs": { @@ -2244,7 +1310,8 @@ "construct": false, "construct-only": false, "default": "false", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "stats": { @@ -2252,7 +1319,8 @@ "construct": false, "construct-only": false, "default": "application/x-gst-base-sink-stats, average-rate=(double)0, dropped=(guint64)0, rendered=(guint64)0;", - "type-name": "GstStructure", + "readable": true, + "type": "GstStructure", "writable": false }, "sync": { @@ -2260,7 +1328,8 @@ "construct": false, "construct-only": false, "default": "true", - "type-name": "gboolean", + "readable": true, + "type": "gboolean", "writable": true }, "throttle-time": { @@ -2270,7 +1339,8 @@ "default": "0", "max": "18446744073709551615", "min": "0", - "type-name": "guint64", + "readable": true, + "type": "guint64", "writable": true }, "ts-offset": { @@ -2280,7 +1350,8 @@ "default": "0", "max": "9223372036854775807", "min": "-9223372036854775808", - "type-name": "gint64", + "readable": true, + "type": "gint64", "writable": true }, "view-id": { @@ -2290,23 +1361,27 @@ "default": "-1", "max": "2147483647", "min": "-1", - "type-name": "gint", + "readable": true, + "type": "gint", "writable": true } }, - "rank": "marginal", + "rank": "primary", "signals": { "handoff": { "args": [ - "GstBuffer" + { + "name": "arg0", + "type": "GstBuffer" + } ], - "retval": "void" + "return-type": "void", + "when": "last" } } }, "vaapivc1dec": { "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", - "classification": "Codec/Decoder/Video", "description": "A VA-API based VC1 video decoder", "hierarchy": [ "GstVaapiDecode_vc1", @@ -2318,7 +1393,6 @@ ], "klass": "Codec/Decoder/Video/Hardware", "long-name": "VA-API VC1 decoder", - "name": "vaapivc1dec", "pad-templates": { "sink": { "caps": "video/x-wmv:\n wmvversion: 3\n format: { WMV3, WVC1 }\n", @@ -2326,487 +1400,19 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, YUY2, UYVY, Y210, P010_10LE, AYUV, Y410 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } }, "properties": { - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "NULL", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", - "writable": true - } - }, - "rank": "primary" - }, - "vaapivp8dec": { - "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", - "classification": "Codec/Decoder/Video", - "description": "A VA-API based VP8 video decoder", - "hierarchy": [ - "GstVaapiDecode_vp8", - "GstVideoDecoder", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "klass": "Codec/Decoder/Video", - "long-name": "VA-API VP8 decoder", - "name": "vaapivp8dec", - "pad-templates": { - "sink": { - "caps": "video/x-vp8:\n", - "direction": "sink", - "presence": "always" - }, - "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", - "direction": "src", - "presence": "always" - } - }, - "properties": { - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "vaapidecode_vp8-0", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", - "writable": true - } - }, - "rank": "primary" - }, - "vaapivp8enc": { - "author": "Sreerenj Balachandran ", - "classification": "Codec/Encoder/Video", - "description": "A VA-API based VP8 video encoder", - "hierarchy": [ - "GstVaapiEncodeVP8", - "GstVaapiEncode", - "GstVideoEncoder", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "klass": "Codec/Encoder/Video", - "long-name": "VA-API VP8 encoder", - "name": "vaapivp8enc", - "pad-templates": { - "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", - "direction": "sink", - "presence": "always" - }, - "src": { - "caps": "video/x-vp8:\n", - "direction": "src", - "presence": "always" - } - }, - "properties": { - "bitrate": { - "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", - "construct": false, - "construct-only": false, - "default": "0", - "max": "102400", - "min": "0", - "type-name": "guint", - "writable": true - }, - "default-roi-delta-qp": { - "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", - "construct": false, - "construct-only": false, - "default": "-10", - "max": "10", - "min": "-10", - "type-name": "gint", - "writable": true - }, - "keyframe-period": { - "blurb": "Maximal distance between two keyframes (0: auto-calculate)", - "construct": false, - "construct-only": false, - "default": "30", - "max": "-1", - "min": "0", - "type-name": "guint", - "writable": true - }, - "loop-filter-level": { - "blurb": "Controls the deblocking filter strength", - "construct": false, - "construct-only": false, - "default": "0", - "max": "63", - "min": "0", - "type-name": "guint", - "writable": true - }, - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "vaapiencodevp8-0", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", - "writable": true - }, "qos": { "blurb": "Handle Quality-of-Service events from downstream", "construct": false, "construct-only": false, - "default": "false", - "type-name": "gboolean", - "writable": true - }, - "quality-level": { - "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", - "construct": false, - "construct-only": false, - "default": "4", - "max": "7", - "min": "1", - "type-name": "guint", - "writable": true - }, - "rate-control": { - "blurb": "Rate control mode", - "construct": false, - "construct-only": false, - "default": "cqp (1)", - "enum": true, - "type-name": "GstVaapiRateControlVP8", - "values": [ - { - "desc": "Constant QP", - "name": "cqp", - "value": "1" - }, - { - "desc": "Constant bitrate", - "name": "cbr", - "value": "2" - }, - { - "desc": "Variable bitrate", - "name": "vbr", - "value": "4" - } - ], - "writable": true - }, - "sharpness-level": { - "blurb": "Controls the deblocking filter sensitivity", - "construct": false, - "construct-only": false, - "default": "0", - "max": "7", - "min": "0", - "type-name": "guint", - "writable": true - }, - "tune": { - "blurb": "Encoder tuning option", - "construct": false, - "construct-only": false, - "default": "none (0)", - "enum": true, - "type-name": "GstVaapiEncoderTuneVP8", - "values": [ - { - "desc": "None", - "name": "none", - "value": "0" - } - ], - "writable": true - }, - "yac-qi": { - "blurb": "Quantization Table index for Luma AC Coefficients, (in default case, yac_qi=4 for key frames and yac_qi=40 for P frames)", - "construct": false, - "construct-only": false, - "default": "40", - "max": "127", - "min": "0", - "type-name": "guint", - "writable": true - } - }, - "rank": "primary" - }, - "vaapivp9dec": { - "author": "Gwenole Beauchesne , Halley Zhao , Sreerenj Balachandran , Wind Yuan ", - "classification": "Codec/Decoder/Video", - "description": "A VA-API based VP9 video decoder", - "hierarchy": [ - "GstVaapiDecode_vp9", - "GstVideoDecoder", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "klass": "Codec/Decoder/Video", - "long-name": "VA-API VP9 decoder", - "name": "vaapivp9dec", - "pad-templates": { - "sink": { - "caps": "video/x-vp9:\n", - "direction": "sink", - "presence": "always" - }, - "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { I420, YV12, RGBA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", - "direction": "src", - "presence": "always" - } - }, - "properties": { - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "vaapidecode_vp9-0", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", - "writable": true - } - }, - "rank": "primary" - }, - "vaapivp9enc": { - "author": "Sreerenj Balachandran ", - "classification": "Codec/Encoder/Video", - "description": "A VA-API based VP9 video encoder", - "hierarchy": [ - "GstVaapiEncodeVP9", - "GstVaapiEncode", - "GstVideoEncoder", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "klass": "Codec/Encoder/Video", - "long-name": "VA-API VP9 encoder", - "name": "vaapivp9enc", - "pad-templates": { - "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, I420_12BE, I420_12LE, I422_12BE, I422_12LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", - "direction": "sink", - "presence": "always" - }, - "src": { - "caps": "video/x-vp9:\n", - "direction": "src", - "presence": "always" - } - }, - "properties": { - "bitrate": { - "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", - "construct": false, - "construct-only": false, - "default": "0", - "max": "102400", - "min": "0", - "type-name": "guint", - "writable": true - }, - "cpb-length": { - "blurb": "Length of the CPB_buffer/window_size in milliseconds", - "construct": false, - "construct-only": false, - "default": "1500", - "max": "10000", - "min": "1", - "type-name": "guint", - "writable": true - }, - "default-roi-delta-qp": { - "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", - "construct": false, - "construct-only": false, - "default": "-10", - "max": "10", - "min": "-10", - "type-name": "gint", - "writable": true - }, - "keyframe-period": { - "blurb": "Maximal distance between two keyframes (0: auto-calculate)", - "construct": false, - "construct-only": false, - "default": "30", - "max": "-1", - "min": "0", - "type-name": "guint", - "writable": true - }, - "loop-filter-level": { - "blurb": "Controls the deblocking filter strength", - "construct": false, - "construct-only": false, - "default": "10", - "max": "63", - "min": "0", - "type-name": "guint", - "writable": true - }, - "name": { - "blurb": "The name of the object", - "construct": true, - "construct-only": false, - "default": "vaapiencodevp9-0", - "hotdoc-fixed-default": true, - "type-name": "gchararray", - "writable": true - }, - "parent": { - "blurb": "The parent of the object", - "construct": false, - "construct-only": false, - "type-name": "GstObject", - "writable": true - }, - "qos": { - "blurb": "Handle Quality-of-Service events from downstream", - "construct": false, - "construct-only": false, - "default": "false", - "type-name": "gboolean", - "writable": true - }, - "quality-level": { - "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", - "construct": false, - "construct-only": false, - "default": "4", - "max": "7", - "min": "1", - "type-name": "guint", - "writable": true - }, - "rate-control": { - "blurb": "Rate control mode", - "construct": false, - "construct-only": false, - "default": "cqp (1)", - "enum": true, - "type-name": "GstVaapiRateControlVP9", - "values": [ - { - "desc": "Constant QP", - "name": "cqp", - "value": "1" - }, - { - "desc": "Constant bitrate", - "name": "cbr", - "value": "2" - }, - { - "desc": "Variable bitrate", - "name": "vbr", - "value": "4" - } - ], - "writable": true - }, - "ref-pic-mode": { - "blurb": "Reference Picture Selection Modes", - "construct": false, - "construct-only": false, - "default": "mode-0 (0)", - "enum": true, - "type-name": "GstVaapiEncoderVP9RefPicMode", - "values": [ - { - "desc": "Use Keyframe(Alt & Gold) and Previousframe(Last) for prediction ", - "name": "mode-0", - "value": "0" - }, - { - "desc": "Use last three frames for prediction (n:Last n-1:Gold n-2:Alt)", - "name": "mode-1", - "value": "1" - } - ], - "writable": true - }, - "sharpness-level": { - "blurb": "Controls the deblocking filter sensitivity", - "construct": false, - "construct-only": false, - "default": "0", - "max": "7", - "min": "0", - "type-name": "guint", - "writable": true - }, - "tune": { - "blurb": "Encoder tuning option", - "construct": false, - "construct-only": false, - "default": "none (0)", - "enum": true, - "type-name": "GstVaapiEncoderTuneVP9", - "values": [ - { - "desc": "None", - "name": "none", - "value": "0" - } - ], - "writable": true - }, - "yac-qi": { - "blurb": "Quantization Table index for Luma AC Coefficients", - "construct": false, - "construct-only": false, - "default": "60", - "max": "255", - "min": "0", - "type-name": "guint", + "default": "true", + "readable": true, + "type": "gboolean", "writable": true } }, @@ -2815,8 +1421,316 @@ }, "filename": "gstvaapi", "license": "LGPL", + "other-types": { + "GstVaapiDeinterlaceMethod": { + "kind": "enum", + "values": [ + { + "desc": "Disable deinterlacing", + "name": "none", + "value": "0" + }, + { + "desc": "Bob deinterlacing", + "name": "bob", + "value": "1" + }, + { + "desc": "Weave deinterlacing", + "name": "weave", + "value": "2" + }, + { + "desc": "Motion adaptive deinterlacing", + "name": "motion-adaptive", + "value": "3" + }, + { + "desc": "Motion compensated deinterlacing", + "name": "motion-compensated", + "value": "4" + } + ] + }, + "GstVaapiDeinterlaceMode": { + "kind": "enum", + "values": [ + { + "desc": "Auto detection", + "name": "auto", + "value": "0" + }, + { + "desc": "Force deinterlacing", + "name": "interlaced", + "value": "1" + }, + { + "desc": "Never deinterlace", + "name": "disabled", + "value": "2" + } + ] + }, + "GstVaapiDisplayType": { + "kind": "enum", + "values": [ + { + "desc": "Auto detection", + "name": "any", + "value": "0" + }, + { + "desc": "VA/X11 display", + "name": "x11", + "value": "1" + }, + { + "desc": "VA/GLX display", + "name": "glx", + "value": "2" + }, + { + "desc": "VA/EGL display", + "name": "egl", + "value": "5" + }, + { + "desc": "VA/Wayland display", + "name": "wayland", + "value": "3" + }, + { + "desc": "VA/DRM display", + "name": "drm", + "value": "4" + } + ] + }, + "GstVaapiEncoderH264ComplianceMode": { + "kind": "enum", + "values": [ + { + "desc": "Strict compliance to the H264 Specification ", + "name": "strict", + "value": "0" + }, + { + "desc": "Restrict the allocation size of coded-buffer", + "name": "restrict-buf-alloc", + "value": "1" + } + ] + }, + "GstVaapiEncoderH264PredictionType": { + "kind": "enum", + "values": [ + { + "desc": "Default encode, prev/next frame as ref ", + "name": "default", + "value": "0" + }, + { + "desc": "Hierarchical P frame encode", + "name": "hierarchical-p", + "value": "1" + }, + { + "desc": "Hierarchical B frame encode", + "name": "hierarchical-b", + "value": "2" + } + ] + }, + "GstVaapiEncoderMbbrc": { + "kind": "enum", + "values": [ + { + "desc": "Auto", + "name": "auto", + "value": "0" + }, + { + "desc": "On", + "name": "on", + "value": "1" + }, + { + "desc": "Off", + "name": "off", + "value": "2" + } + ] + }, + "GstVaapiEncoderTuneH264": { + "kind": "enum", + "values": [ + { + "desc": "None", + "name": "none", + "value": "0" + }, + { + "desc": "High compression", + "name": "high-compression", + "value": "1" + }, + { + "desc": "Low power mode", + "name": "low-power", + "value": "3" + } + ] + }, + "GstVaapiEncoderTuneH265": { + "kind": "enum", + "values": [ + { + "desc": "None", + "name": "none", + "value": "0" + }, + { + "desc": "Low power mode", + "name": "low-power", + "value": "3" + } + ] + }, + "GstVaapiHDRToneMap": { + "kind": "enum", + "values": [ + { + "desc": "Auto detection", + "name": "auto", + "value": "0" + }, + { + "desc": "Disable HDR tone mapping", + "name": "disabled", + "value": "1" + } + ] + }, + "GstVaapiRateControlH264": { + "kind": "enum", + "values": [ + { + "desc": "Constant QP", + "name": "cqp", + "value": "1" + }, + { + "desc": "Constant bitrate", + "name": "cbr", + "value": "2" + }, + { + "desc": "Variable bitrate", + "name": "vbr", + "value": "4" + }, + { + "desc": "Variable bitrate - Constrained", + "name": "vbr_constrained", + "value": "5" + }, + { + "desc": "Constant QP - Intelligent", + "name": "icq", + "value": "7" + }, + { + "desc": "Variable bitrate - Quality defined", + "name": "qvbr", + "value": "8" + } + ] + }, + "GstVaapiRateControlH265": { + "kind": "enum", + "values": [ + { + "desc": "Constant QP", + "name": "cqp", + "value": "1" + }, + { + "desc": "Constant bitrate", + "name": "cbr", + "value": "2" + }, + { + "desc": "Variable bitrate", + "name": "vbr", + "value": "4" + }, + { + "desc": "Constant QP - Intelligent", + "name": "icq", + "value": "7" + }, + { + "desc": "Variable bitrate - Quality defined", + "name": "qvbr", + "value": "8" + } + ] + }, + "GstVaapiRotation": { + "kind": "enum", + "values": [ + { + "desc": "Unrotated mode", + "name": "0", + "value": "0" + }, + { + "desc": "Rotated by 90°, clockwise", + "name": "90", + "value": "90" + }, + { + "desc": "Rotated by 180°, clockwise", + "name": "180", + "value": "180" + }, + { + "desc": "Rotated by 270°, clockwise", + "name": "270", + "value": "270" + }, + { + "desc": "Rotated by image-orientating tag°", + "name": "Automatic", + "value": "360" + } + ] + }, + "GstVaapiScaleMethod": { + "kind": "enum", + "values": [ + { + "desc": "Default scaling mode", + "name": "default", + "value": "0" + }, + { + "desc": "Fast scaling mode", + "name": "fast", + "value": "1" + }, + { + "desc": "High quality scaling mode", + "name": "hq", + "value": "2" + } + ] + } + }, "package": "gstreamer-vaapi", "source": "gstreamer-vaapi", - "url": "http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer" + "tracers": {}, + "url": "https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues" } } \ No newline at end of file diff --git a/meson_options.txt b/meson_options.txt index ee82b1f990..9c2b5e1644 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -11,5 +11,5 @@ option('tests', type : 'feature', value : 'auto', yield : true) option('doc', type : 'feature', value : 'auto', yield: true, description: 'Enable documentation.') option('package-origin', type : 'string', - value : '"https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues"', + value : 'https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues', yield : true, description : 'package origin URL to use in plugins') From 8e400a56346f4ea7065a95b02185a5de488c35d0 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 3 Jun 2020 18:49:53 -0400 Subject: [PATCH 3607/3781] doc: Fix wrong link to GstVideoDirectionMethod --- gst/vaapi/gstvaapipostproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 3fc58c6a7c..4afb869596 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -2507,7 +2507,7 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass) * GstVaapiPostproc:video-direction: * * The video-direction to use, expressed as an enum value. See - * #GstVideoDirectionMethod. + * #GstVideoDirection. */ filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION); if (filter_op) From 45c2f827465651cc140d57f37898933b46d67b9b Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 3 Jun 2020 18:37:22 -0400 Subject: [PATCH 3608/3781] doc: Require hotdoc >= 0.11.0 --- docs/meson.build | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/meson.build b/docs/meson.build index 280cedbb12..b9ad138640 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -35,6 +35,17 @@ if not hotdoc_p.found() 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) From a2063083a5fc7ce998b06fb876e1b780214cac8a Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 29 May 2020 15:37:24 +0800 Subject: [PATCH 3609/3781] libs: encoder: h265: Fix chrome idc for 444 10 bits GST_VAAPI_CHROMA_TYPE_YUV444_10BPP should also set chroma_format_idc to 3 as GST_VAAPI_CHROMA_TYPE_YUV444 does. Part-of: --- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index a7e23839ab..b24273b0ad 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -448,6 +448,7 @@ gst_vaapi_utils_h265_get_chroma_format_idc (GstVaapiChromaType chroma_type) chroma_format_idc = 2; break; case GST_VAAPI_CHROMA_TYPE_YUV444: + case GST_VAAPI_CHROMA_TYPE_YUV444_10BPP: chroma_format_idc = 3; break; default: From 5c67bdaf63edd6451dafd1c4bf946a825b099fa1 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 29 May 2020 16:40:20 +0800 Subject: [PATCH 3610/3781] libs: encoder: h265: Use correct index for SubWidthC and SubHeightC. We need to use the chroma_format_idc as the index for getting the SubWidthC and SubHeightC values as the spec 6.1(table 6-1) defines. The wrong SubWidthC or SubHeightC make us calculate a wrong right or bottom offset for crop size and generate garbage in output. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index bee501f20b..dd785f4cb8 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2712,17 +2712,22 @@ gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) /* Frame Cropping */ if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) || (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) { + /* 6.1, Table 6-1 */ static const guint SubWidthC[] = { 1, 2, 2, 1 }; static const guint SubHeightC[] = { 1, 2, 1, 1 }; + guint index = gst_vaapi_utils_h265_get_chroma_format_idc + (gst_vaapi_video_format_get_chroma_type (GST_VIDEO_INFO_FORMAT + (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)))); + encoder->conformance_window_flag = 1; encoder->conf_win_left_offset = 0; encoder->conf_win_right_offset = (encoder->luma_width - - GST_VAAPI_ENCODER_WIDTH (encoder)) / SubWidthC[1]; + GST_VAAPI_ENCODER_WIDTH (encoder)) / SubWidthC[index]; encoder->conf_win_top_offset = 0; encoder->conf_win_bottom_offset = (encoder->luma_height - - GST_VAAPI_ENCODER_HEIGHT (encoder)) / SubHeightC[1]; + GST_VAAPI_ENCODER_HEIGHT (encoder)) / SubHeightC[index]; } } From 8486f82d980188ca86d468b6bda0e1d9e2cffdaf Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 3 Apr 2020 14:53:40 +0800 Subject: [PATCH 3611/3781] libs: encoder: h265: Add support for MAIN 4:2:2 10 profile. Using YUY2 as the input of the encoder can generate main 4:2:2 bit streams and using Y210 as the input of the encoder can generate main 4:2:2 10 bit streams. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder.c | 3 ++- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 26 +++++++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 2 ++ gst/vaapi/gstvaapiencode_h265.c | 2 +- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index d989bde6be..ec71fec2b9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -668,7 +668,8 @@ is_chroma_type_supported (GstVaapiEncoder * encoder) cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV422 && cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420_10BPP && cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV444 && - cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV444_10BPP) + cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV444_10BPP && + cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV422_10BPP) goto unsupported; if (!get_config_attribute (encoder, VAConfigAttribRTFormat, &format)) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index dd785f4cb8..c5712efefd 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -305,8 +305,8 @@ bs_write_profile_tier_level (GstBitWriter * bs, /* additional indications specified for general_profile_idc from 4~10 */ if (seq_param->general_profile_idc == 4) { /* In A.3.5, Format range extensions profiles. - Just support main444 and main444-10 profile now, may add more profiles - when needed. */ + Just support main444, main444-10 and main422-10 profile now, may add + more profiles when needed. */ switch (profile) { case GST_VAAPI_PROFILE_H265_MAIN_444: /* max_12bit_constraint_flag */ @@ -348,6 +348,26 @@ bs_write_profile_tier_level (GstBitWriter * bs, /* lower_bit_rate_constraint_flag */ WRITE_UINT32 (bs, 1, 1); break; + case GST_VAAPI_PROFILE_H265_MAIN_422_10: + /* max_12bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_10bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_8bit_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_422chroma_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_420chroma_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_monochrome_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* intra_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* one_picture_only_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* lower_bit_rate_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + break; default: GST_WARNING ("do not support the profile: %s of range extensions", gst_vaapi_profile_get_va_name (profile)); @@ -1110,6 +1130,8 @@ ensure_profile (GstVaapiEncoderH265 * encoder) profile = GST_VAAPI_PROFILE_H265_MAIN_444; else if (format == GST_VIDEO_FORMAT_Y410) profile = GST_VAAPI_PROFILE_H265_MAIN_444_10; + else if (format == GST_VIDEO_FORMAT_Y210 || format == GST_VIDEO_FORMAT_YUY2) + profile = GST_VAAPI_PROFILE_H265_MAIN_422_10; encoder->profile = profile; encoder->profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index b24273b0ad..47da26d68e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -42,6 +42,7 @@ static const struct map gst_vaapi_h265_profile_map[] = { { GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE, "main-still-picture" }, { GST_VAAPI_PROFILE_H265_MAIN_444, "main-444" }, { GST_VAAPI_PROFILE_H265_MAIN_444_10, "main-444-10" }, + { GST_VAAPI_PROFILE_H265_MAIN_422_10, "main-422-10" }, { 0, NULL } /* *INDENT-ON* */ }; @@ -445,6 +446,7 @@ gst_vaapi_utils_h265_get_chroma_format_idc (GstVaapiChromaType chroma_type) chroma_format_idc = 1; break; case GST_VAAPI_CHROMA_TYPE_YUV422: + case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: chroma_format_idc = 2; break; case GST_VAAPI_CHROMA_TYPE_YUV444: diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 5b97991b10..b5a19f6aa3 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -55,7 +55,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h265_encode_debug); /* *INDENT-OFF* */ static const char gst_vaapiencode_h265_src_caps_str[] = GST_CODEC_CAPS ", " - "profile = (string) { main, main-10, main-444, main-444-10 }"; + "profile = (string) { main, main-10, main-444, main-444-10, main-422-10 }"; /* *INDENT-ON* */ /* *INDENT-OFF* */ From 9067d902e21f4922311bc7ae1aa8e558e387dc01 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 13 May 2020 14:53:46 +0800 Subject: [PATCH 3612/3781] libs: profile: Add screen extended main/main10/main444 define. Part-of: --- gst-libs/gst/vaapi/gstvaapiprofile.c | 6 ++++++ gst-libs/gst/vaapi/gstvaapiprofile.h | 6 ++++++ gst-libs/gst/vaapi/gstvaapiutils.c | 3 +++ 3 files changed, 15 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 7f0c94cb79..9a06a5e0ae 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -128,6 +128,12 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h265", "main-444"}, {GST_VAAPI_PROFILE_H265_MAIN_444_10, VAProfileHEVCMain444_10, "video/x-h265", "main-444-10"}, + {GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN, VAProfileHEVCSccMain, + "video/x-h265", "screen-extended-main"}, + {GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10, VAProfileHEVCSccMain10, + "video/x-h265", "screen-extended-main-10"}, + {GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444, VAProfileHEVCSccMain444, + "video/x-h265", "screen-extended-main-444"}, #endif {GST_VAAPI_PROFILE_VP9_0, VAProfileVP9Profile0, "video/x-vp9", "profile0"}, diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 96e3cad81c..affba42be4 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -181,6 +181,12 @@ typedef enum { GST_VAAPI_PROFILE_H265_MAIN_422_10 = GST_VAAPI_MAKE_PROFILE(H265,4), GST_VAAPI_PROFILE_H265_MAIN_444 = GST_VAAPI_MAKE_PROFILE(H265,5), GST_VAAPI_PROFILE_H265_MAIN_444_10 = GST_VAAPI_MAKE_PROFILE(H265,6), + GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN = + GST_VAAPI_MAKE_PROFILE(H265,7), + GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10 = + GST_VAAPI_MAKE_PROFILE(H265,8), + GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444 = + GST_VAAPI_MAKE_PROFILE(H265,9), GST_VAAPI_PROFILE_VP9_0 = GST_VAAPI_MAKE_PROFILE(VP9,1), GST_VAAPI_PROFILE_VP9_1 = GST_VAAPI_MAKE_PROFILE(VP9,2), GST_VAAPI_PROFILE_VP9_2 = GST_VAAPI_MAKE_PROFILE(VP9,3), diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 319eb579f3..9c5c12d8f9 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -238,6 +238,9 @@ string_of_VAProfile (VAProfile profile) MAP (HEVCMain422_10); MAP (HEVCMain444); MAP (HEVCMain444_10); + MAP (HEVCSccMain); + MAP (HEVCSccMain10); + MAP (HEVCSccMain444); #endif MAP (HEVCMain); MAP (HEVCMain10); From 1d9b2cab42c8f1357e353b13a17e6825229e3f99 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 13 May 2020 15:00:53 +0800 Subject: [PATCH 3613/3781] libs: util: H265: recognize the SCC profiles. Part-of: --- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 47da26d68e..c0dd8384da 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -242,6 +242,44 @@ gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) profile = GST_VAAPI_PROFILE_H265_MAIN_422_10; break; } + case GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING: + if (sps->profile_tier_level.max_14bit_constraint_flag == 1 + && sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 1 + && sps->profile_tier_level.max_422chroma_constraint_flag == 1 + && sps->profile_tier_level.max_420chroma_constraint_flag == 1 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 0 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0 + && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { + profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN; + break; + } else if (sps->profile_tier_level.max_14bit_constraint_flag == 1 + && sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 0 + && sps->profile_tier_level.max_422chroma_constraint_flag == 1 + && sps->profile_tier_level.max_420chroma_constraint_flag == 1 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 0 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0 + && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { + profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10; + break; + } else if (sps->profile_tier_level.max_14bit_constraint_flag == 1 + && sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 1 + && sps->profile_tier_level.max_422chroma_constraint_flag == 0 + && sps->profile_tier_level.max_420chroma_constraint_flag == 0 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 0 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0 + && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { + profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444; + break; + } default: GST_DEBUG ("unsupported profile_idc value"); profile = GST_VAAPI_PROFILE_UNKNOWN; From c956d91807958195aca59a9be203e58ded49dfdf Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 13 May 2020 15:46:29 +0800 Subject: [PATCH 3614/3781] libs: decoder: H265: Fill picture and slice SCC parameters. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 89 ++++++++++++++++++++++- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 739b33c128..f6be666ed4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -537,11 +537,24 @@ is_range_extension_profile (GstVaapiProfile profile) return FALSE; } +static gboolean +is_scc_profile (GstVaapiProfile profile) +{ +#if VA_CHECK_VERSION(1,2,0) + if (profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN + || profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10 + || profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444) + return TRUE; +#endif + return FALSE; +} + static inline GstVaapiPictureH265 * gst_vaapi_picture_h265_new (GstVaapiDecoderH265 * decoder) { GstVaapiDecoderH265Private *const priv = &decoder->priv; - if (is_range_extension_profile (priv->profile)) { + if (is_range_extension_profile (priv->profile) + || is_scc_profile (priv->profile)) { #if VA_CHECK_VERSION(1,2,0) return (GstVaapiPictureH265 *) gst_vaapi_codec_object_new (&GstVaapiPictureH265Class, @@ -1857,11 +1870,18 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) #if VA_CHECK_VERSION(1,2,0) VAPictureParameterBufferHEVCRext *pic_rext_param = NULL; + VAPictureParameterBufferHEVCScc *pic_scc_param = NULL; if (is_range_extension_profile (priv->profile)) { VAPictureParameterBufferHEVCExtension *param = base_picture->param; pic_param = ¶m->base; pic_rext_param = ¶m->rext; } + if (is_scc_profile (priv->profile)) { + VAPictureParameterBufferHEVCExtension *param = base_picture->param; + pic_param = ¶m->base; + pic_rext_param = ¶m->rext; + pic_scc_param = ¶m->scc; + } #endif pic_param->pic_fields.value = 0; @@ -2024,6 +2044,56 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) pps->pps_extension_params.cr_qp_offset_list, sizeof (pic_rext_param->cr_qp_offset_list)); } + + if (pic_scc_param) { +#define COPY_SCC_FIELD(s, f) \ + pic_scc_param->f = s->f +#define COPY_SCC_BFM(a, s, f) \ + pic_scc_param->a.bits.f = s->f + + const GstH265PPSSccExtensionParams *pps_scc = + &pps->pps_scc_extension_params; + const GstH265SPSSccExtensionParams *sps_scc = + &sps->sps_scc_extension_params; + guint32 num_comps; + + pic_scc_param->screen_content_pic_fields.value = 0; + + COPY_SCC_BFM (screen_content_pic_fields, pps_scc, + pps_curr_pic_ref_enabled_flag); + COPY_SCC_BFM (screen_content_pic_fields, sps_scc, + palette_mode_enabled_flag); + COPY_SCC_BFM (screen_content_pic_fields, sps_scc, + motion_vector_resolution_control_idc); + COPY_SCC_BFM (screen_content_pic_fields, sps_scc, + intra_boundary_filtering_disabled_flag); + COPY_SCC_BFM (screen_content_pic_fields, pps_scc, + residual_adaptive_colour_transform_enabled_flag); + COPY_SCC_BFM (screen_content_pic_fields, pps_scc, + pps_slice_act_qp_offsets_present_flag); + + COPY_SCC_FIELD (sps_scc, palette_max_size); + COPY_SCC_FIELD (sps_scc, delta_palette_max_predictor_size); + COPY_SCC_FIELD (pps_scc, pps_act_y_qp_offset_plus5); + COPY_SCC_FIELD (pps_scc, pps_act_cb_qp_offset_plus5); + COPY_SCC_FIELD (pps_scc, pps_act_cr_qp_offset_plus3); + + /* firstly use the pps, then sps */ + num_comps = sps->chroma_format_idc ? 3 : 1; + + if (pps_scc->pps_palette_predictor_initializers_present_flag) { + for (n = 0; n < num_comps; n++) + for (i = 0; i < pps_scc->pps_num_palette_predictor_initializer; i++) + pic_scc_param->predictor_palette_entries[n][i] = + (uint16_t) pps_scc->pps_palette_predictor_initializer[n][i]; + } else if (sps_scc->sps_palette_predictor_initializers_present_flag) { + for (n = 0; n < num_comps; n++) + for (i = 0; + i < sps_scc->sps_num_palette_predictor_initializer_minus1 + 1; i++) + pic_scc_param->predictor_palette_entries[n][i] = + (uint16_t) sps_scc->sps_palette_predictor_initializer[n][i]; + } + } #endif return TRUE; } @@ -2600,7 +2670,8 @@ fill_slice (GstVaapiDecoderH265 * decoder, #if VA_CHECK_VERSION(1,2,0) GstVaapiDecoderH265Private *const priv = &decoder->priv; VASliceParameterBufferHEVCRext *slice_rext_param = NULL; - if (is_range_extension_profile (priv->profile)) { + if (is_range_extension_profile (priv->profile) + || is_scc_profile (priv->profile)) { VASliceParameterBufferHEVCExtension *param = slice->param; slice_param = ¶m->base; slice_rext_param = ¶m->rext; @@ -2660,9 +2731,18 @@ fill_slice (GstVaapiDecoderH265 * decoder, slice_hdr->five_minus_max_num_merge_cand; #if VA_CHECK_VERSION(1,2,0) - if (slice_rext_param) + if (slice_rext_param) { slice_rext_param->slice_ext_flags.bits.cu_chroma_qp_offset_enabled_flag = slice_hdr->cu_chroma_qp_offset_enabled_flag; + slice_rext_param->slice_ext_flags.bits.use_integer_mv_flag = + slice_hdr->use_integer_mv_flag; + + slice_rext_param->slice_act_y_qp_offset = slice_hdr->slice_act_y_qp_offset; + slice_rext_param->slice_act_cb_qp_offset = + slice_hdr->slice_act_cb_qp_offset; + slice_rext_param->slice_act_cr_qp_offset = + slice_hdr->slice_act_cr_qp_offset; + } #endif if (!fill_RefPicList (decoder, picture, slice, slice_hdr)) @@ -2714,7 +2794,8 @@ decode_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit) if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END) GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_END); - if (is_range_extension_profile (priv->profile)) { + if (is_range_extension_profile (priv->profile) + || is_scc_profile (priv->profile)) { #if VA_CHECK_VERSION(1,2,0) slice = GST_VAAPI_SLICE_NEW (HEVCExtension, decoder, (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size); From 5f92699a4b6057deeaf1d824e6c8363de3832a88 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 13 May 2020 16:05:59 +0800 Subject: [PATCH 3615/3781] libs: decoder: update reference list for SCC. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 40 ++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index f6be666ed4..015c870e6b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1345,7 +1345,21 @@ decode_current_picture (GstVaapiDecoderH265 * decoder) priv->decoder_state |= sps_pi->state; if (!(priv->decoder_state & GST_H265_VIDEO_STATE_GOT_I_FRAME)) { - if (priv->decoder_state & GST_H265_VIDEO_STATE_GOT_P_SLICE) + const GstH265PPS *pps = get_pps (decoder); + /* 7.4.3.3.3: the picture is an IRAP picture, nuh_layer_id is equal to 0, + and pps_curr_pic_ref_enabled_flag is equal to 0, slice_type shall be + equal to 2(I Slice). + And F.8.3.4: Decoding process for reference picture lists construction + is invoked at the beginning of the decoding process for each P or B + slice. + so if pps_curr_pic_ref_enabled_flag is set, which means the picture can + ref to itself, the IRAP picture may be set to P/B slice, in order to + generate the ref lists. If the slice_type is I, no ref list will be + constructed and no MV data for that slice according to the syntax. + That kind of CVS may start with P/B slice, but in fact it is a intra + frame. */ + if (priv->decoder_state & GST_H265_VIDEO_STATE_GOT_P_SLICE && + !pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag) goto drop_frame; sps_pi->state |= GST_H265_VIDEO_STATE_GOT_I_FRAME; } @@ -1670,6 +1684,7 @@ init_picture_refs (GstVaapiDecoderH265 * decoder, guint num_ref_idx_l0_active_minus1 = 0; guint num_ref_idx_l1_active_minus1 = 0; GstH265RefPicListModification *ref_pic_list_modification; + GstH265PPS *const pps = get_pps (decoder); guint type; memset (priv->RefPicList0, 0, sizeof (GstVaapiPictureH265 *) * 16); @@ -1702,6 +1717,8 @@ init_picture_refs (GstVaapiDecoderH265 * decoder, for (i = 0; i < priv->NumPocLtCurr && rIdx < NumRpsCurrTempList0; rIdx++, i++) RefPicListTemp0[rIdx] = priv->RefPicSetLtCurr[i]; + if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag) + RefPicListTemp0[rIdx++] = picture; } /* construct RefPicList0 (8-9) */ @@ -1710,6 +1727,10 @@ init_picture_refs (GstVaapiDecoderH265 * decoder, ref_pic_list_modification->ref_pic_list_modification_flag_l0 ? RefPicListTemp0[ref_pic_list_modification->list_entry_l0[rIdx]] : RefPicListTemp0[rIdx]; + if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag + && !ref_pic_list_modification->ref_pic_list_modification_flag_l0 + && (NumRpsCurrTempList0 > num_ref_idx_l0_active_minus1 + 1)) + priv->RefPicList0[rIdx++] = picture; priv->RefPicList0_count = rIdx; if (type == GST_H265_B_SLICE) { @@ -1726,6 +1747,8 @@ init_picture_refs (GstVaapiDecoderH265 * decoder, for (i = 0; i < priv->NumPocLtCurr && rIdx < NumRpsCurrTempList1; rIdx++, i++) RefPicListTemp1[rIdx] = priv->RefPicSetLtCurr[i]; + if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag) + RefPicListTemp1[rIdx++] = picture; } /* construct RefPicList1 (8-10) */ @@ -1898,6 +1921,17 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) if (n >= G_N_ELEMENTS (pic_param->ReferenceFrames)) break; } + /* 7.4.3.3.3, the current decoded picture is marked as "used for + long-term reference", no matter TwoVersionsOfCurrDecPicFlag */ + if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag + && n < G_N_ELEMENTS (pic_param->ReferenceFrames) - 1) { + gst_vaapi_picture_h265_set_reference (picture, + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); + vaapi_fill_picture (&pic_param->ReferenceFrames[n++], picture, + picture->structure); + gst_vaapi_picture_h265_set_reference (picture, 0); + } + for (; n < G_N_ELEMENTS (pic_param->ReferenceFrames); n++) vaapi_init_picture (&pic_param->ReferenceFrames[n]); @@ -2277,6 +2311,7 @@ decode_ref_pic_set (GstVaapiDecoderH265 * decoder, GstVaapiDecoderH265Private *const priv = &decoder->priv; GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; GstH265SPS *const sps = get_sps (decoder); + GstH265PPS *const pps = get_pps (decoder); const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); @@ -2297,6 +2332,7 @@ decode_ref_pic_set (GstVaapiDecoderH265 * decoder, memset (priv->PocLtFoll, 0, sizeof (guint) * 16); priv->NumPocStCurrBefore = priv->NumPocStCurrAfter = priv->NumPocStFoll = 0; priv->NumPocLtCurr = priv->NumPocLtFoll = 0; + priv->NumPocTotalCurr = 0; } else { GstH265ShortTermRefPicSet *stRefPic = NULL; gint32 num_lt_pics, pocLt; @@ -2346,6 +2382,8 @@ decode_ref_pic_set (GstVaapiDecoderH265 * decoder, numtotalcurr++; } + if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag) + numtotalcurr++; priv->NumPocTotalCurr = numtotalcurr; /* The variable DeltaPocMsbCycleLt[i] is derived as follows: (7-38) */ From 85bc355019e716d74f6a0d973a0d446b382990f8 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 13 May 2020 18:02:07 +0800 Subject: [PATCH 3616/3781] libs: decoder: H265: Add SCC_MAIN_444_10 profile support. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 6 +++++- gst-libs/gst/vaapi/gstvaapiprofile.c | 5 +++++ gst-libs/gst/vaapi/gstvaapiprofile.h | 2 ++ gst-libs/gst/vaapi/gstvaapiutils.c | 3 +++ gst-libs/gst/vaapi/gstvaapiutils_h265.c | 12 ++++++++++++ 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 015c870e6b..024d71421b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -543,7 +543,11 @@ is_scc_profile (GstVaapiProfile profile) #if VA_CHECK_VERSION(1,2,0) if (profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN || profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10 - || profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444) + || profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444 +#if VA_CHECK_VERSION(1,8,0) + || profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10 +#endif + ) return TRUE; #endif return FALSE; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 9a06a5e0ae..e7bdea003f 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -134,6 +134,11 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h265", "screen-extended-main-10"}, {GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444, VAProfileHEVCSccMain444, "video/x-h265", "screen-extended-main-444"}, +#endif +#if VA_CHECK_VERSION(1,8,0) + {GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10, + VAProfileHEVCSccMain444_10, + "video/x-h265", "screen-extended-main-444-10"}, #endif {GST_VAAPI_PROFILE_VP9_0, VAProfileVP9Profile0, "video/x-vp9", "profile0"}, diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index affba42be4..3d2e42eaf2 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -187,6 +187,8 @@ typedef enum { GST_VAAPI_MAKE_PROFILE(H265,8), GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444 = GST_VAAPI_MAKE_PROFILE(H265,9), + GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10 = + GST_VAAPI_MAKE_PROFILE(H265,10), GST_VAAPI_PROFILE_VP9_0 = GST_VAAPI_MAKE_PROFILE(VP9,1), GST_VAAPI_PROFILE_VP9_1 = GST_VAAPI_MAKE_PROFILE(VP9,2), GST_VAAPI_PROFILE_VP9_2 = GST_VAAPI_MAKE_PROFILE(VP9,3), diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 9c5c12d8f9..1f228e3718 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -241,6 +241,9 @@ string_of_VAProfile (VAProfile profile) MAP (HEVCSccMain); MAP (HEVCSccMain10); MAP (HEVCSccMain444); +#endif +#if VA_CHECK_VERSION(1,8,0) + MAP (HEVCSccMain444_10); #endif MAP (HEVCMain); MAP (HEVCMain10); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index c0dd8384da..7f6c7437b0 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -279,6 +279,18 @@ gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444; break; + } else if (sps->profile_tier_level.max_14bit_constraint_flag == 1 + && sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 1 + && sps->profile_tier_level.max_8bit_constraint_flag == 0 + && sps->profile_tier_level.max_422chroma_constraint_flag == 0 + && sps->profile_tier_level.max_420chroma_constraint_flag == 0 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 0 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0 + && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { + profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10; + break; } default: GST_DEBUG ("unsupported profile_idc value"); From 6c76e81cb6d08d54ae57b112c46541b6116ea9d3 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 5 Mar 2020 12:44:45 +0800 Subject: [PATCH 3617/3781] libs: encoder: Add a helper function to check the tile support. Encoding by tiles separation now is a very common feature for all relative new codecs, such as HEVC, AV1, and VP9. Just make this check as a common helper function of the encoder base class. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder.c | 37 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 5 +++ 2 files changed, 42 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index ec71fec2b9..22b0e248e6 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1679,6 +1679,43 @@ gst_vaapi_encoder_ensure_max_num_ref_frames (GstVaapiEncoder * encoder, return TRUE; } +/** + * gst_vaapi_encoder_ensure_tile_support: + * @encoder: a #GstVaapiEncoder + * @profile: a #GstVaapiProfile + * @entrypoint: a #GstVaapiEntrypoint + * + * This function will query VAConfigAttribEncTileSupport to check + * whether the encoder support tile. + * + * We need to pass the @profile and the @entrypoint, because at the + * moment the encoder base class, still doesn't have them assigned, + * and this function is meant to be called by the derived classes + * while they are configured. + * + * Returns: %TRUE if supported, %FALSE if not. + **/ +gboolean +gst_vaapi_encoder_ensure_tile_support (GstVaapiEncoder * encoder, + GstVaapiProfile profile, GstVaapiEntrypoint entrypoint) +{ + guint tile = 0; + +#if VA_CHECK_VERSION(1,0,1) + VAProfile va_profile; + VAEntrypoint va_entrypoint; + + va_profile = gst_vaapi_profile_get_va_profile (profile); + va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint (entrypoint); + + if (!gst_vaapi_get_config_attribute (encoder->display, va_profile, + va_entrypoint, VAConfigAttribEncTileSupport, &tile)) + return FALSE; +#endif + + return tile > 0; +} + GstVaapiProfile gst_vaapi_encoder_get_profile (GstVaapiEncoder * encoder) { diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 0de0bbfafa..189c3791a7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -384,6 +384,11 @@ 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 */ From bc1c97c7550165b05993e344a2247be2f9497884 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 5 Mar 2020 16:21:24 +0800 Subject: [PATCH 3618/3781] libs: encoder: h265: extract slice creation from add_slice_headers extract slice creation details from add_slice_headers, and let the add_slice_headers just focuses on calculating slice start address and CTU number. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 180 ++++++++++++---------- 1 file changed, 99 insertions(+), 81 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index c5712efefd..8c0de32b41 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1811,6 +1811,97 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, return TRUE; } +static GstVaapiEncSlice * +create_and_fill_one_slice (GstVaapiEncoderH265 * encoder, + GstVaapiEncPicture * picture, + GstVaapiEncoderH265Ref ** reflist_0, guint reflist_0_count, + GstVaapiEncoderH265Ref ** reflist_1, guint reflist_1_count) +{ + VAEncSliceParameterBufferHEVC *slice_param; + GstVaapiEncSlice *slice; + guint i_ref; + + slice = GST_VAAPI_ENC_SLICE_NEW (HEVC, encoder); + g_assert (slice && slice->param_id != VA_INVALID_ID); + slice_param = slice->param; + memset (slice_param, 0, sizeof (VAEncSliceParameterBufferHEVC)); + + slice_param->slice_type = h265_get_slice_type (picture->type); + if (encoder->low_delay_b && slice_param->slice_type == GST_H265_P_SLICE) { + slice_param->slice_type = GST_H265_B_SLICE; + } + slice_param->slice_pic_parameter_set_id = 0; + + slice_param->slice_fields.bits.num_ref_idx_active_override_flag = + reflist_0_count || reflist_1_count; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) + slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; + else + slice_param->num_ref_idx_l0_active_minus1 = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0) + slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; + else + slice_param->num_ref_idx_l1_active_minus1 = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->low_delay_b) + slice_param->num_ref_idx_l1_active_minus1 = + slice_param->num_ref_idx_l0_active_minus1; + + i_ref = 0; + if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { + for (; i_ref < reflist_0_count; ++i_ref) { + slice_param->ref_pic_list0[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); + slice_param->ref_pic_list0[i_ref].pic_order_cnt = reflist_0[i_ref]->poc; + } + } + for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i_ref) { + slice_param->ref_pic_list0[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->ref_pic_list0[i_ref].flags = VA_PICTURE_HEVC_INVALID; + } + + i_ref = 0; + if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + for (; i_ref < reflist_1_count; ++i_ref) { + slice_param->ref_pic_list1[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); + slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_1[i_ref]->poc; + } + } else if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->low_delay_b) { + for (; i_ref < reflist_0_count; ++i_ref) { + slice_param->ref_pic_list1[i_ref].picture_id = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); + slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_0[i_ref]->poc; + } + } + for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i_ref) { + slice_param->ref_pic_list1[i_ref].picture_id = VA_INVALID_SURFACE; + slice_param->ref_pic_list1[i_ref].flags = VA_PICTURE_HEVC_INVALID; + } + + slice_param->max_num_merge_cand = 5; /* MaxNumMergeCand */ + slice_param->slice_qp_delta = encoder->qp_i - encoder->init_qp; + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) { + if (picture->type == GST_VAAPI_PICTURE_TYPE_P) { + slice_param->slice_qp_delta += encoder->qp_ip; + } else if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { + slice_param->slice_qp_delta += encoder->qp_ib; + } + if ((gint) encoder->init_qp + slice_param->slice_qp_delta < + (gint) encoder->min_qp) { + slice_param->slice_qp_delta = encoder->min_qp - encoder->init_qp; + } + if ((gint) encoder->init_qp + slice_param->slice_qp_delta > + (gint) encoder->max_qp) { + slice_param->slice_qp_delta = encoder->max_qp - encoder->init_qp; + } + } + + slice_param->slice_fields.bits.slice_loop_filter_across_slices_enabled_flag = + TRUE; + + return slice; +} + /* Adds slice headers to picture */ static gboolean add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, @@ -1823,7 +1914,7 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, guint ctu_size; guint ctu_width_round_factor; guint last_ctu_index; - guint i_slice, i_ref; + guint i_slice; g_assert (picture); @@ -1842,6 +1933,10 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, --slice_mod_ctus; } + slice = create_and_fill_one_slice (encoder, picture, + reflist_0, reflist_0_count, reflist_1, reflist_1_count); + slice_param = slice->param; + /* Work-around for satisfying the VA-Intel driver. * The driver only support multi slice begin from row start address */ ctu_width_round_factor = @@ -1850,11 +1945,6 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, if ((last_ctu_index + cur_slice_ctus) > ctu_size) cur_slice_ctus = ctu_size - last_ctu_index; - slice = GST_VAAPI_ENC_SLICE_NEW (HEVC, encoder); - g_assert (slice && slice->param_id != VA_INVALID_ID); - slice_param = slice->param; - - memset (slice_param, 0, sizeof (VAEncSliceParameterBufferHEVC)); if (i_slice == 0) { encoder->first_slice_segment_in_pic_flag = TRUE; slice_param->slice_segment_address = 0; @@ -1863,79 +1953,6 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, slice_param->slice_segment_address = last_ctu_index; } slice_param->num_ctu_in_slice = cur_slice_ctus; - slice_param->slice_type = h265_get_slice_type (picture->type); - if (encoder->low_delay_b && slice_param->slice_type == GST_H265_P_SLICE) { - slice_param->slice_type = GST_H265_B_SLICE; - } - slice_param->slice_pic_parameter_set_id = 0; - - slice_param->slice_fields.bits.num_ref_idx_active_override_flag = - reflist_0_count || reflist_1_count; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0) - slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1; - else - slice_param->num_ref_idx_l0_active_minus1 = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0) - slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; - else - slice_param->num_ref_idx_l1_active_minus1 = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->low_delay_b) - slice_param->num_ref_idx_l1_active_minus1 = - slice_param->num_ref_idx_l0_active_minus1; - - i_ref = 0; - if (picture->type != GST_VAAPI_PICTURE_TYPE_I) { - for (; i_ref < reflist_0_count; ++i_ref) { - slice_param->ref_pic_list0[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); - slice_param->ref_pic_list0[i_ref].pic_order_cnt = reflist_0[i_ref]->poc; - } - } - for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i_ref) { - slice_param->ref_pic_list0[i_ref].picture_id = VA_INVALID_SURFACE; - slice_param->ref_pic_list0[i_ref].flags = VA_PICTURE_HEVC_INVALID; - } - - i_ref = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { - for (; i_ref < reflist_1_count; ++i_ref) { - slice_param->ref_pic_list1[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); - slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_1[i_ref]->poc; - } - } else if (picture->type == GST_VAAPI_PICTURE_TYPE_P - && encoder->low_delay_b) { - for (; i_ref < reflist_0_count; ++i_ref) { - slice_param->ref_pic_list1[i_ref].picture_id = - GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); - slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_0[i_ref]->poc; - } - } - for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i_ref) { - slice_param->ref_pic_list1[i_ref].picture_id = VA_INVALID_SURFACE; - slice_param->ref_pic_list1[i_ref].flags = VA_PICTURE_HEVC_INVALID; - } - - slice_param->max_num_merge_cand = 5; /* MaxNumMergeCand */ - slice_param->slice_qp_delta = encoder->qp_i - encoder->init_qp; - if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) { - if (picture->type == GST_VAAPI_PICTURE_TYPE_P) { - slice_param->slice_qp_delta += encoder->qp_ip; - } else if (picture->type == GST_VAAPI_PICTURE_TYPE_B) { - slice_param->slice_qp_delta += encoder->qp_ib; - } - if ((gint) encoder->init_qp + slice_param->slice_qp_delta < - (gint) encoder->min_qp) { - slice_param->slice_qp_delta = encoder->min_qp - encoder->init_qp; - } - if ((gint) encoder->init_qp + slice_param->slice_qp_delta > - (gint) encoder->max_qp) { - slice_param->slice_qp_delta = encoder->max_qp - encoder->init_qp; - } - } - - slice_param->slice_fields.bits. - slice_loop_filter_across_slices_enabled_flag = TRUE; /* set calculation for next slice */ last_ctu_index += cur_slice_ctus; @@ -1951,10 +1968,11 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, gst_vaapi_enc_picture_add_slice (picture, slice); gst_vaapi_codec_object_replace (&slice, NULL); } + if (i_slice < encoder->num_slices) GST_WARNING - ("Using less number of slices than requested, Number of slices per pictures is %d", - i_slice); + ("Using less number of slices than requested, Number of slices per" + " pictures is %d", i_slice); g_assert (last_ctu_index == ctu_size); return TRUE; From 812c9fdea7f6f26e6ae5162d753dc0313e601ac5 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 5 Mar 2020 17:07:28 +0800 Subject: [PATCH 3619/3781] libs: encoder: h265: Add num-tile-cols/rows properties. These properties are used for support of tile encoding. We just support uniform mode of tile encoding, that is, separating picture equally by (num-tile-cols X num-tile-rows). According to HEVC spec A1, the max number of tiles in column is 20 and in rows is 22, so add two constant definitions. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 42 +++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_h265.h | 15 ++++++++ 2 files changed, 57 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 8c0de32b41..1e3d47eb5b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -117,6 +117,8 @@ struct _GstVaapiEncoderH265 GstClockTime cts_offset; gboolean config_changed; gboolean low_delay_b; + guint32 num_tile_cols; + guint32 num_tile_rows; /* maximum required size of the decoded picture buffer */ guint32 max_dec_pic_buffering; @@ -2893,6 +2895,8 @@ enum ENCODER_H265_PROP_LOW_DELAY_B, ENCODER_H265_PROP_MAX_QP, ENCODER_H265_PROP_QUALITY_FACTOR, + ENCODER_H265_PROP_NUM_TILE_COLS, + ENCODER_H265_PROP_NUM_TILE_ROWS, ENCODER_H265_N_PROPERTIES }; @@ -2955,6 +2959,12 @@ gst_vaapi_encoder_h265_set_property (GObject * object, guint prop_id, case ENCODER_H265_PROP_QUALITY_FACTOR: encoder->quality_factor = g_value_get_uint (value); break; + case ENCODER_H265_PROP_NUM_TILE_COLS: + encoder->num_tile_cols = g_value_get_uint (value); + break; + case ENCODER_H265_PROP_NUM_TILE_ROWS: + encoder->num_tile_rows = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -3010,6 +3020,12 @@ gst_vaapi_encoder_h265_get_property (GObject * object, guint prop_id, case ENCODER_H265_PROP_QUALITY_FACTOR: g_value_set_uint (value, encoder->quality_factor); break; + case ENCODER_H265_PROP_NUM_TILE_COLS: + g_value_set_uint (value, encoder->num_tile_cols); + break; + case ENCODER_H265_PROP_NUM_TILE_ROWS: + g_value_set_uint (value, encoder->num_tile_rows); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -3216,6 +3232,32 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | GST_VAAPI_PARAM_ENCODER_EXPOSURE); + /** + * GstVaapiEncoderH265:num-tile-cols: + * + * The number of tile columns when tile encoding is enabled. + */ + properties[ENCODER_H265_PROP_NUM_TILE_COLS] = + g_param_spec_uint ("num-tile-cols", + "number of tile columns", + "the number of columns for tile encoding", 1, + GST_VAAPI_H265_MAX_COL_TILES, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + GST_VAAPI_PARAM_ENCODER_EXPOSURE); + + /** + * GstVaapiEncoderH265:num-tile-rows: + * + * The number of tile rows when tile encoding is enabled. + */ + properties[ENCODER_H265_PROP_NUM_TILE_ROWS] = + g_param_spec_uint ("num-tile-rows", + "number of tile rows", + "the number of rows for tile encoding", 1, + GST_VAAPI_H265_MAX_ROW_TILES, 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + GST_VAAPI_PARAM_ENCODER_EXPOSURE); + g_object_class_install_properties (object_class, ENCODER_H265_N_PROPERTIES, properties); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.h b/gst-libs/gst/vaapi/gstvaapiutils_h265.h index 930da0b61b..e3ac72ea2a 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.h @@ -27,6 +27,21 @@ G_BEGIN_DECLS +/** + * GST_VAAPI_H265_MAX_COL_TILES: + * + * The max tiles in column according to spec A1 + * + */ +#define GST_VAAPI_H265_MAX_COL_TILES 20 +/** + * GST_VAAPI_H265_MAX_ROW_TILES: + * + * The max tiles in row according to spec A1 + * + */ +#define GST_VAAPI_H265_MAX_ROW_TILES 22 + /** * GstVaapiLevelH265: * @GST_VAAPI_LEVEL_H265_L1: H.265 level 1. From 71db3572845a968151b55b79baaa7370b572b621 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 5 Mar 2020 17:29:41 +0800 Subject: [PATCH 3620/3781] libs: encoder: h265: promote level if tile is enabled. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 28 ++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 1e3d47eb5b..37143ea1fd 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -178,6 +178,12 @@ h265_get_slice_type (GstVaapiPictureType type) return -1; } +static gboolean +h265_is_tile_enabled (GstVaapiEncoderH265 * encoder) +{ + return encoder->num_tile_cols * encoder->num_tile_rows > 1; +} + /* Get log2_max_pic_order_cnt value for H.265 specification */ static guint h265_get_log2_max_pic_order_cnt (guint num) @@ -1148,6 +1154,7 @@ ensure_tier_level (GstVaapiEncoderH265 * encoder) guint i, num_limits, PicSizeInSamplesY; guint LumaSr; const GstVaapiH265LevelLimits *limits_table; + const GstVaapiH265LevelLimits *limits; PicSizeInSamplesY = encoder->luma_width * encoder->luma_height; LumaSr = @@ -1156,7 +1163,7 @@ ensure_tier_level (GstVaapiEncoderH265 * encoder) limits_table = gst_vaapi_utils_h265_get_level_limits_table (&num_limits); for (i = 0; i < num_limits; i++) { - const GstVaapiH265LevelLimits *const limits = &limits_table[i]; + limits = &limits_table[i]; /* Choose level by luma picture size and luma sample rate */ if (PicSizeInSamplesY <= limits->MaxLumaPs && LumaSr <= limits->MaxLumaSr) break; @@ -1165,6 +1172,19 @@ ensure_tier_level (GstVaapiEncoderH265 * encoder) if (i == num_limits) goto error_unsupported_level; + /* may need to promote the level by tile setting */ + if (h265_is_tile_enabled (encoder)) { + for (; i < num_limits; i++) { + limits = &limits_table[i]; + if (encoder->num_tile_cols <= limits->MaxTileColumns && + encoder->num_tile_rows <= limits->MaxTileRows) + break; + } + + if (i == num_limits) + goto error_promote_level; + } + if (bitrate <= limits_table[i].MaxBRTierMain) { encoder->tier = GST_VAAPI_TIER_H265_MAIN; } else { @@ -1185,6 +1205,12 @@ ensure_tier_level (GstVaapiEncoderH265 * encoder) return TRUE; /* ERRORS */ +error_promote_level: + { + GST_ERROR ("failed to promote level for num-tile-cols is %d," + " num-tile-rows %d", encoder->num_tile_cols, encoder->num_tile_rows); + return FALSE; + } error_unsupported_level: { GST_ERROR ("failed to find a suitable level matching codec config"); From dbed28d41904a364930268f76bb2cf64d9b58e7b Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 5 Mar 2020 17:40:43 +0800 Subject: [PATCH 3621/3781] libs: encoder: h265: Add tile info to bitstream. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 37143ea1fd..16fb90d720 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -771,6 +771,25 @@ bs_write_pps (GstBitWriter * bs, /* entropy_coding_sync_enabled_flag */ WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_sync_enabled_flag, 1); + + /* tiles info */ + if (pic_param->pic_fields.bits.tiles_enabled_flag) { + WRITE_UE (bs, pic_param->num_tile_columns_minus1); + WRITE_UE (bs, pic_param->num_tile_rows_minus1); + /* uniform_spacing_flag is 1 now */ + WRITE_UINT32 (bs, 1, 1); + /* if (!uniform_spacing_flag) { + for (i = 0; i < num_tile_columns_minus1; i++) + column_width_minus1[i] + ue (v) + for (i = 0; i < num_tile_rows_minus1; i++) + row_height_minus1[i] + ue (v) + } */ + WRITE_UINT32 (bs, + pic_param->pic_fields.bits.loop_filter_across_tiles_enabled_flag, 1); + } + /* pps_loop_filter_across_slices_enabled_flag */ WRITE_UINT32 (bs, pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag, 1); @@ -970,7 +989,12 @@ bs_write_slice (GstBitWriter * bs, WRITE_UINT32 (bs, slice_param->slice_fields.bits. slice_loop_filter_across_slices_enabled_flag, 1); + } + if (pic_param->pic_fields.bits.tiles_enabled_flag + || pic_param->pic_fields.bits.entropy_coding_sync_enabled_flag) { + /* output a num_entry_point_offsets, which should be 0 here */ + WRITE_UE (bs, 0); } /* byte_alignment() */ From 32db615685d30e320e68ce8b2113490aabcfeee3 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 30 Apr 2020 14:19:29 +0800 Subject: [PATCH 3622/3781] libs: display: add a quirk for iHD driver tile encoding. The iHD driver has a requirement that one slice can not span tiles when tile is enabled, which is not required by hevc spec. Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 295de3bfdb..6f6f6f4c06 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -807,6 +807,7 @@ set_driver_quirks (GstVaapiDisplay * display) { "iHD", GST_VAAPI_DRIVER_QUIRK_NO_RGBYUV_VPP_COLOR_PRIMARY }, { "i965", GST_VAAPI_DRIVER_QUIRK_MISSING_RGBA_IMAGE_FORMAT }, { "iHD", GST_VAAPI_DRIVER_QUIRK_JPEG_ENC_SHIFT_VALUE_BY_50 }, + { "iHD", GST_VAAPI_DRIVER_QUIRK_HEVC_ENC_SLICE_NOT_SPAN_TILE }, }; /* *INDENT-ON* */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index e8f644bcf4..9e690cb389 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -107,6 +107,8 @@ typedef struct _GstVaapiDisplay GstVaapiDisplay; * 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. */ typedef enum { @@ -115,6 +117,7 @@ typedef enum GST_VAAPI_DRIVER_QUIRK_NO_RGBYUV_VPP_COLOR_PRIMARY = (1U << 2), 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), } GstVaapiDriverQuirks; /** From cefd1a665f33a65b8cc38a8f90fe3383428813e3 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 5 Mar 2020 17:56:51 +0800 Subject: [PATCH 3623/3781] libs: encoder: h265: Add ensure_tile to calculate tiles. We need consider tiles and slices together, separate tiles uniformly and then assign slices uniformly to each tiles. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 310 ++++++++++++++++++++++ 1 file changed, 310 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 16fb90d720..f48cdaf4e5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -119,6 +119,13 @@ struct _GstVaapiEncoderH265 gboolean low_delay_b; guint32 num_tile_cols; guint32 num_tile_rows; + /* CTUs start address used in stream pack */ + guint32 *tile_slice_address; + /* CTUs in this slice */ + guint32 *tile_slice_ctu_num; + /* map the tile_slice_address to CTU start address in picture, + which is used by VA API. */ + guint32 *tile_slice_address_map; /* maximum required size of the decoded picture buffer */ guint32 max_dec_pic_buffering; @@ -1774,6 +1781,11 @@ fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) return TRUE; } +/* CTUs in each tile column */ +static guint32 tile_ctu_cols[GST_VAAPI_H265_MAX_COL_TILES]; +/* CTUs in each tile row */ +static guint32 tile_ctu_rows[GST_VAAPI_H265_MAX_ROW_TILES]; + /* Fills in VA picture parameter buffer */ static gboolean fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, @@ -2374,6 +2386,299 @@ reset_properties (GstVaapiEncoderH265 * encoder) reorder_pool->frame_index = 0; } +static void +reset_tile (GstVaapiEncoderH265 * encoder) +{ + memset (tile_ctu_cols, 0, sizeof (tile_ctu_cols)); + memset (tile_ctu_rows, 0, sizeof (tile_ctu_rows)); + + if (encoder->tile_slice_address) + g_free (encoder->tile_slice_address); + encoder->tile_slice_address = NULL; + + if (encoder->tile_slice_ctu_num) + g_free (encoder->tile_slice_ctu_num); + encoder->tile_slice_ctu_num = NULL; + + if (encoder->tile_slice_address_map) + g_free (encoder->tile_slice_address_map); + encoder->tile_slice_address_map = NULL; +} + +static void +recalculate_slices_num_by_tile (GstVaapiEncoderH265 * encoder) +{ + GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); + + /* If driver has the requirement that the slice should not span tiles, + we need to increase slice number if needed. */ + if (gst_vaapi_display_has_driver_quirks (display, + GST_VAAPI_DRIVER_QUIRK_HEVC_ENC_SLICE_NOT_SPAN_TILE)) { + if (encoder->num_slices < encoder->num_tile_cols * encoder->num_tile_rows) { + /* encoder->num_slices > 1 means user set it */ + if (encoder->num_slices > 1) + GST_WARNING ("user set num-slices to %d, which is smaller than tile" + " num %d. We should make slice not span tiles, just set the" + " num-slices to tile num here.", + encoder->num_slices, + encoder->num_tile_cols * encoder->num_tile_rows); + else + GST_INFO ("set default slice num to %d, the same as the tile num.", + encoder->num_tile_cols * encoder->num_tile_rows); + encoder->num_slices = encoder->num_tile_cols * encoder->num_tile_rows; + } + } +} + +static GstVaapiEncoderStatus +calculate_slices_start_address (GstVaapiEncoderH265 * encoder) +{ + GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); + guint32 ctu_per_slice; + guint32 left_slices; + gint32 i, j, k; + + /* If driver has the requirement that the slice should not span tiles, + firstly we should scatter slices uniformly into each tile, bigger + tile gets more slices. Then we should assign CTUs within one tile + uniformly to each slice in that tile. */ + if (gst_vaapi_display_has_driver_quirks (display, + GST_VAAPI_DRIVER_QUIRK_HEVC_ENC_SLICE_NOT_SPAN_TILE)) { + guint32 *slices_per_tile = g_malloc (encoder->num_tile_cols * + encoder->num_tile_rows * sizeof (guint32)); + if (!slices_per_tile) + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + + ctu_per_slice = (encoder->ctu_width * encoder->ctu_height + + encoder->num_slices - 1) / encoder->num_slices; + g_assert (ctu_per_slice > 0); + left_slices = encoder->num_slices; + + for (i = 0; i < encoder->num_tile_cols * encoder->num_tile_rows; i++) { + slices_per_tile[i] = 1; + left_slices--; + } + while (left_slices) { + /* Find the biggest CTUs/slices, and assign more. */ + gfloat largest = 0.0f; + k = -1; + for (i = 0; i < encoder->num_tile_cols * encoder->num_tile_rows; i++) { + gfloat f; + f = ((gfloat) (tile_ctu_cols[i % encoder->num_tile_cols] * + tile_ctu_rows[i / encoder->num_tile_cols])) / + (gfloat) slices_per_tile[i]; + g_assert (f >= 1.0f); + if (f > largest) { + k = i; + largest = f; + } + } + + g_assert (k >= 0); + slices_per_tile[k]++; + left_slices--; + } + + /* Assign CTUs in one tile uniformly to each slice. Note: the slice start + address is CTB address in tile scan(see spec 6.5), that is, we accumulate + all CTUs in tile0, then tile1, and tile2..., not from the picture's + perspective. */ + encoder->tile_slice_address[0] = 0; + k = 1; + for (i = 0; i < encoder->num_tile_rows; i++) { + for (j = 0; j < encoder->num_tile_cols; j++) { + guint32 s_num = slices_per_tile[i * encoder->num_tile_cols + j]; + guint32 one_tile_ctus = tile_ctu_cols[j] * tile_ctu_rows[i]; + guint32 s; + + GST_LOG ("Tile(row %d col %d), has CTU in col %d," + " CTU in row is %d, total CTU %d, assigned %d slices", i, j, + tile_ctu_cols[j], tile_ctu_rows[i], one_tile_ctus, s_num); + + g_assert (s_num > 0); + for (s = 0; s < s_num; s++) { + encoder->tile_slice_address[k] = + encoder->tile_slice_address[k - 1] + ((s + + 1) * one_tile_ctus) / s_num - (s * one_tile_ctus) / s_num; + encoder->tile_slice_ctu_num[k - 1] = + encoder->tile_slice_address[k] - encoder->tile_slice_address[k - + 1]; + k++; + } + } + } + + g_assert (k == encoder->num_slices + 1); + /* Calculate the last one */ + encoder->tile_slice_ctu_num[encoder->num_slices - 1] = + encoder->ctu_width * encoder->ctu_height - + encoder->tile_slice_address[encoder->num_slices - 1]; + + g_free (slices_per_tile); + } + /* The easy way, just assign CTUs to each slice uniformly */ + else { + ctu_per_slice = (encoder->ctu_width * encoder->ctu_height + + encoder->num_slices - 1) / encoder->num_slices; + g_assert (ctu_per_slice > 0); + + for (i = 0; i < encoder->num_slices - 1; i++) + encoder->tile_slice_ctu_num[i] = ctu_per_slice; + encoder->tile_slice_ctu_num[encoder->num_slices - 1] = + encoder->ctu_width * encoder->ctu_height - + (encoder->num_slices - 1) * ctu_per_slice; + + encoder->tile_slice_address[0] = 0; + for (i = 1; i <= encoder->num_slices; i++) + encoder->tile_slice_address[i] = encoder->tile_slice_address[i - 1] + + encoder->tile_slice_ctu_num[i - 1]; + } + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + +static GstVaapiEncoderStatus +ensure_tile (GstVaapiEncoderH265 * encoder) +{ + gint32 i, j, k; + guint32 ctu_tile_width_accu[GST_VAAPI_H265_MAX_COL_TILES + 1]; + guint32 ctu_tile_height_accu[GST_VAAPI_H265_MAX_ROW_TILES + 1]; + guint32 num_slices; + GstVaapiEncoderStatus ret; + + reset_tile (encoder); + + if (!h265_is_tile_enabled (encoder)) + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + if (!gst_vaapi_encoder_ensure_tile_support (GST_VAAPI_ENCODER (encoder), + encoder->profile, encoder->entrypoint)) { + GST_ERROR ("The profile:%s, entrypoint:%d does not support tile.", + gst_vaapi_utils_h265_get_profile_string (encoder->profile), + encoder->entrypoint); + return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + } + + if (encoder->num_tile_cols > + gst_vaapi_utils_h265_get_level_limits (encoder->level)->MaxTileColumns) { + GST_ERROR ("num_tile_cols:%d exceeds MaxTileColumns:%d", + encoder->num_tile_cols, + gst_vaapi_utils_h265_get_level_limits (encoder->level)->MaxTileColumns); + return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + } + if (encoder->num_tile_rows > + gst_vaapi_utils_h265_get_level_limits (encoder->level)->MaxTileRows) { + GST_ERROR ("num_tile_rows:%d exceeds MaxTileRows:%d", + encoder->num_tile_rows, + gst_vaapi_utils_h265_get_level_limits (encoder->level)->MaxTileRows); + return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + } + + if (encoder->ctu_width < encoder->num_tile_cols) { + GST_WARNING + ("Only %d CTUs in width, not enough to split into %d tile columns", + encoder->ctu_width, encoder->num_tile_cols); + return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + } + if (encoder->ctu_height < encoder->num_tile_rows) { + GST_WARNING + ("Only %d CTUs in height, not enough to split into %d tile rows", + encoder->ctu_height, encoder->num_tile_rows); + return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + } + + recalculate_slices_num_by_tile (encoder); + + /* ensure not exceed max supported slices */ + num_slices = encoder->num_slices; + gst_vaapi_encoder_ensure_num_slices (GST_VAAPI_ENCODER_CAST (encoder), + encoder->profile, encoder->entrypoint, + (encoder->ctu_width * encoder->ctu_height + 1) / 2, &num_slices); + if (num_slices != encoder->num_slices) { + GST_ERROR ("The tile setting need at least %d slices, but the max" + " slice number is just %d", encoder->num_slices, num_slices); + return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + } + + encoder->tile_slice_address = + /* Add one as sentinel, hold val to calculate ctu_num */ + g_malloc ((encoder->num_slices + 1) * sizeof (guint32)); + if (!encoder->tile_slice_address) + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + encoder->tile_slice_ctu_num = + g_malloc (encoder->num_slices * sizeof (guint32)); + if (!encoder->tile_slice_ctu_num) + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + encoder->tile_slice_address_map = + g_malloc (encoder->ctu_width * encoder->ctu_height * sizeof (guint32)); + if (!encoder->tile_slice_address_map) + return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED; + + /* firstly uniformly separate CTUs into tiles, as the spec 6.5.1 define */ + for (i = 0; i < encoder->num_tile_cols; i++) + tile_ctu_cols[i] = + ((i + 1) * encoder->ctu_width) / encoder->num_tile_cols - + (i * encoder->ctu_width) / encoder->num_tile_cols; + for (i = 0; i < encoder->num_tile_rows; i++) + tile_ctu_rows[i] = + ((i + 1) * encoder->ctu_height) / encoder->num_tile_rows - + (i * encoder->ctu_height) / encoder->num_tile_rows; + + ret = calculate_slices_start_address (encoder); + if (ret != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return ret; + + /* Build the map to specifying the conversion between a CTB address in CTB + raster scan of a picture and a CTB address in tile scan(see spec 6.5.1 + for details). */ + ctu_tile_width_accu[0] = 0; + for (i = 1; i <= encoder->num_tile_cols; i++) + ctu_tile_width_accu[i] = ctu_tile_width_accu[i - 1] + tile_ctu_cols[i - 1]; + ctu_tile_height_accu[0] = 0; + for (i = 1; i <= encoder->num_tile_rows; i++) + ctu_tile_height_accu[i] = + ctu_tile_height_accu[i - 1] + tile_ctu_rows[i - 1]; + + for (k = 0; k < encoder->ctu_width * encoder->ctu_height; k++) { + /* The ctu coordinate in the picture. */ + guint32 x = k % encoder->ctu_width; + guint32 y = k / encoder->ctu_width; + /* The ctu coordinate in the tile mode. */ + guint32 tile_x = 0; + guint32 tile_y = 0; + /* The index of the CTU in the tile mode. */ + guint32 tso = 0; + + for (i = 0; i < encoder->num_tile_cols; i++) + if (x >= ctu_tile_width_accu[i]) + tile_x = i; + g_assert (tile_x <= encoder->num_tile_cols - 1); + + for (j = 0; j < encoder->num_tile_rows; j++) + if (y >= ctu_tile_height_accu[j]) + tile_y = j; + g_assert (tile_y <= encoder->num_tile_rows - 1); + + /* add all ctus in the tiles the same line before us */ + for (i = 0; i < tile_x; i++) + tso += tile_ctu_rows[tile_y] * tile_ctu_cols[i]; + + /* add all ctus in the tiles above us */ + for (j = 0; j < tile_y; j++) + tso += encoder->ctu_width * tile_ctu_rows[j]; + + /* add the ctus inside the same tile before us */ + tso += (y - ctu_tile_height_accu[tile_y]) * tile_ctu_cols[tile_x] + + x - ctu_tile_width_accu[tile_x]; + + g_assert (tso < encoder->ctu_width * encoder->ctu_height); + + encoder->tile_slice_address_map[tso] = k; + } + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; +} + static GstVaapiEncoderStatus gst_vaapi_encoder_h265_encode (GstVaapiEncoder * base_encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf) @@ -2837,6 +3142,9 @@ gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) } reset_properties (encoder); + status = ensure_tile (encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; ensure_control_rate_params (encoder); return set_context_info (base_encoder); } @@ -2907,6 +3215,8 @@ gst_vaapi_encoder_h265_finalize (GObject * object) } g_queue_clear (&reorder_pool->reorder_frame_list); + reset_tile (encoder); + G_OBJECT_CLASS (gst_vaapi_encoder_h265_parent_class)->finalize (object); } From 854fdcb695fe4472f35904296574b6c8942411d0 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 5 Mar 2020 18:12:27 +0800 Subject: [PATCH 3624/3781] libs: encoder: h265: Enable tile in VA command. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 152 ++++++++++++++-------- 1 file changed, 101 insertions(+), 51 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index f48cdaf4e5..5f637fecc1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1872,6 +1872,26 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, pic_param->pic_fields.bits.no_output_of_prior_pics_flag = no_output_of_prior_pics_flag; + /* Setup tile info */ + pic_param->pic_fields.bits.tiles_enabled_flag = + h265_is_tile_enabled (encoder); + if (pic_param->pic_fields.bits.tiles_enabled_flag) { + /* Always set loop filter across tiles enabled now */ + pic_param->pic_fields.bits.loop_filter_across_tiles_enabled_flag = 1; + + pic_param->num_tile_columns_minus1 = encoder->num_tile_cols - 1; + pic_param->num_tile_rows_minus1 = encoder->num_tile_rows - 1; + + /* The VA row_height_minus1 and column_width_minus1 size is 1 smaller + than the MAX_COL_TILES and MAX_ROW_TILES, which means the driver + can deduce the last tile's size based on the picture info. We need + to take care of the array size here. */ + for (i = 0; i < MIN (encoder->num_tile_cols, 19); ++i) + pic_param->column_width_minus1[i] = tile_ctu_cols[i] - 1; + for (i = 0; i < MIN (encoder->num_tile_rows, 21); ++i) + pic_param->row_height_minus1[i] = tile_ctu_rows[i] - 1; + } + return TRUE; } @@ -1982,63 +2002,93 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, g_assert (picture); - ctu_size = encoder->ctu_width * encoder->ctu_height; + if (h265_is_tile_enabled (encoder)) { + for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) { + encoder->first_slice_segment_in_pic_flag = (i_slice == 0); - g_assert (encoder->num_slices && encoder->num_slices < ctu_size); - slice_of_ctus = ctu_size / encoder->num_slices; - slice_mod_ctus = ctu_size % encoder->num_slices; - last_ctu_index = 0; + slice = create_and_fill_one_slice (encoder, picture, reflist_0, + reflist_0_count, reflist_1, reflist_1_count); + slice_param = slice->param; - for (i_slice = 0; - i_slice < encoder->num_slices && (last_ctu_index < ctu_size); ++i_slice) { - cur_slice_ctus = slice_of_ctus; - if (slice_mod_ctus) { - ++cur_slice_ctus; - --slice_mod_ctus; + slice_param->slice_segment_address = + encoder->tile_slice_address_map[encoder->tile_slice_address[i_slice]]; + slice_param->num_ctu_in_slice = encoder->tile_slice_ctu_num[i_slice]; + GST_LOG ("slice %d start tile address is %d, start address is %d," + " CTU num %d", i_slice, encoder->tile_slice_address[i_slice], + slice_param->slice_segment_address, slice_param->num_ctu_in_slice); + + + if (i_slice == encoder->num_slices - 1) + slice_param->slice_fields.bits.last_slice_of_pic_flag = 1; + + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_SLICE) + && !add_packed_slice_header (encoder, picture, slice)) + goto error_create_packed_slice_hdr; + + gst_vaapi_enc_picture_add_slice (picture, slice); + gst_vaapi_codec_object_replace (&slice, NULL); + } + } else { + ctu_size = encoder->ctu_width * encoder->ctu_height; + + g_assert (encoder->num_slices && encoder->num_slices < ctu_size); + slice_of_ctus = ctu_size / encoder->num_slices; + slice_mod_ctus = ctu_size % encoder->num_slices; + last_ctu_index = 0; + + for (i_slice = 0; + i_slice < encoder->num_slices && (last_ctu_index < ctu_size); + ++i_slice) { + cur_slice_ctus = slice_of_ctus; + if (slice_mod_ctus) { + ++cur_slice_ctus; + --slice_mod_ctus; + } + + slice = create_and_fill_one_slice (encoder, picture, reflist_0, + reflist_0_count, reflist_1, reflist_1_count); + slice_param = slice->param; + + /* Work-around for satisfying the VA-Intel driver. + * The driver only support multi slice begin from row start address */ + ctu_width_round_factor = + encoder->ctu_width - (cur_slice_ctus % encoder->ctu_width); + cur_slice_ctus += ctu_width_round_factor; + if ((last_ctu_index + cur_slice_ctus) > ctu_size) + cur_slice_ctus = ctu_size - last_ctu_index; + + if (i_slice == 0) { + encoder->first_slice_segment_in_pic_flag = TRUE; + slice_param->slice_segment_address = 0; + } else { + encoder->first_slice_segment_in_pic_flag = FALSE; + slice_param->slice_segment_address = last_ctu_index; + } + slice_param->num_ctu_in_slice = cur_slice_ctus; + + /* set calculation for next slice */ + last_ctu_index += cur_slice_ctus; + + if ((i_slice == encoder->num_slices - 1) || (last_ctu_index == ctu_size)) + slice_param->slice_fields.bits.last_slice_of_pic_flag = 1; + + if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & + VA_ENC_PACKED_HEADER_SLICE) + && !add_packed_slice_header (encoder, picture, slice)) + goto error_create_packed_slice_hdr; + + gst_vaapi_enc_picture_add_slice (picture, slice); + gst_vaapi_codec_object_replace (&slice, NULL); } - slice = create_and_fill_one_slice (encoder, picture, - reflist_0, reflist_0_count, reflist_1, reflist_1_count); - slice_param = slice->param; - - /* Work-around for satisfying the VA-Intel driver. - * The driver only support multi slice begin from row start address */ - ctu_width_round_factor = - encoder->ctu_width - (cur_slice_ctus % encoder->ctu_width); - cur_slice_ctus += ctu_width_round_factor; - if ((last_ctu_index + cur_slice_ctus) > ctu_size) - cur_slice_ctus = ctu_size - last_ctu_index; - - if (i_slice == 0) { - encoder->first_slice_segment_in_pic_flag = TRUE; - slice_param->slice_segment_address = 0; - } else { - encoder->first_slice_segment_in_pic_flag = FALSE; - slice_param->slice_segment_address = last_ctu_index; - } - slice_param->num_ctu_in_slice = cur_slice_ctus; - - /* set calculation for next slice */ - last_ctu_index += cur_slice_ctus; - - if ((i_slice == encoder->num_slices - 1) || (last_ctu_index == ctu_size)) - slice_param->slice_fields.bits.last_slice_of_pic_flag = 1; - - if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & - VA_ENC_PACKED_HEADER_SLICE) - && !add_packed_slice_header (encoder, picture, slice)) - goto error_create_packed_slice_hdr; - - gst_vaapi_enc_picture_add_slice (picture, slice); - gst_vaapi_codec_object_replace (&slice, NULL); + if (i_slice < encoder->num_slices) + GST_WARNING + ("Using less number of slices than requested, Number of slices per" + " pictures is %d", i_slice); + g_assert (last_ctu_index == ctu_size); } - if (i_slice < encoder->num_slices) - GST_WARNING - ("Using less number of slices than requested, Number of slices per" - " pictures is %d", i_slice); - g_assert (last_ctu_index == ctu_size); - return TRUE; error_create_packed_slice_hdr: From e6e377c720e110792e8d14e76ae610aa285bf6ea Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Sat, 6 Jun 2020 00:42:46 +0200 Subject: [PATCH 3625/3781] plugins: uddate gst_type_mark_as_plugin_api() calls --- gst-libs/gst/vaapi/gstvaapidisplay.c | 2 +- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 11 ++++++----- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 4 ++-- gst-libs/gst/vaapi/gstvaapifilter.c | 6 +++--- gst-libs/gst/vaapi/gstvaapivalue.c | 10 +++++----- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 6f6f6f4c06..840e6c56ac 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -1226,7 +1226,7 @@ gst_vaapi_display_class_init (GstVaapiDisplayClass * klass) "The display contrast value", 0.0, 2.0, 1.0, G_PARAM_READWRITE); g_object_class_install_properties (object_class, N_PROPERTIES, g_properties); - gst_type_mark_as_plugin_api (gst_vaapi_display_type_get_type ()); + gst_type_mark_as_plugin_api (gst_vaapi_display_type_get_type (), 0); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 22ea8b169c..5eec9f6de0 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -4046,11 +4046,12 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) g_object_class_install_properties (object_class, ENCODER_H264_N_PROPERTIES, properties); - gst_type_mark_as_plugin_api (GST_VAAPI_TYPE_ENCODER_MBBRC); - gst_type_mark_as_plugin_api (gst_vaapi_encoder_h264_prediction_type ()); - gst_type_mark_as_plugin_api (g_class_data.rate_control_get_type ()); - gst_type_mark_as_plugin_api (g_class_data.encoder_tune_get_type ()); - gst_type_mark_as_plugin_api (gst_vaapi_encoder_h264_compliance_mode_type ()); + gst_type_mark_as_plugin_api (GST_VAAPI_TYPE_ENCODER_MBBRC, 0); + gst_type_mark_as_plugin_api (gst_vaapi_encoder_h264_prediction_type (), 0); + 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_type_mark_as_plugin_api (gst_vaapi_encoder_h264_compliance_mode_type (), + 0); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 5f637fecc1..e26a67f12c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -3671,8 +3671,8 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) g_object_class_install_properties (object_class, ENCODER_H265_N_PROPERTIES, properties); - gst_type_mark_as_plugin_api (g_class_data.rate_control_get_type ()); - gst_type_mark_as_plugin_api (g_class_data.encoder_tune_get_type ()); + 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); } /** diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index c0fb1c2541..a6e69da7b0 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -122,7 +122,7 @@ gst_vaapi_scale_method_get_type (void) g_enum_register_static ("GstVaapiScaleMethod", enum_values); g_once_init_leave (&g_type, type); - gst_type_mark_as_plugin_api (type); + gst_type_mark_as_plugin_api (type, 0); } return g_type; } @@ -149,7 +149,7 @@ gst_vaapi_deinterlace_method_get_type (void) if (g_once_init_enter (&g_type)) { const GType type = g_enum_register_static ("GstVaapiDeinterlaceMethod", enum_values); - gst_type_mark_as_plugin_api (type); + gst_type_mark_as_plugin_api (type, 0); g_once_init_leave (&g_type, type); } return g_type; @@ -173,7 +173,7 @@ gst_vaapi_deinterlace_flags_get_type (void) if (g_once_init_enter (&g_type)) { const GType type = g_enum_register_static ("GstVaapiDeinterlaceFlags", enum_values); - gst_type_mark_as_plugin_api (type); + gst_type_mark_as_plugin_api (type, 0); g_once_init_leave (&g_type, type); } return g_type; diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index c8aa8fcdb9..1e0121331f 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -56,7 +56,7 @@ gst_vaapi_point_get_type (void) GType type = g_boxed_type_register_static (g_intern_static_string ("GstVaapiPoint"), default_copy_func, default_free_func); - gst_type_mark_as_plugin_api (type); + gst_type_mark_as_plugin_api (type, 0); g_once_init_leave (&g_type, type); } return g_type; @@ -74,7 +74,7 @@ gst_vaapi_rectangle_get_type (void) g_boxed_type_register_static (g_intern_static_string ("GstVaapiRectangle"), default_copy_func, default_free_func); - gst_type_mark_as_plugin_api (type); + gst_type_mark_as_plugin_api (type, 0); g_once_init_leave (&g_type, type); } return g_type; @@ -97,7 +97,7 @@ gst_vaapi_render_mode_get_type (void) if (g_once_init_enter (&g_type)) { GType type = g_enum_register_static ("GstVaapiRenderMode", render_modes); - gst_type_mark_as_plugin_api (type); + gst_type_mark_as_plugin_api (type, 0); g_once_init_leave (&g_type, type); } return g_type; @@ -126,7 +126,7 @@ gst_vaapi_rotation_get_type (void) if (g_once_init_enter (&g_type)) { GType type = g_enum_register_static ("GstVaapiRotation", rotation_values); - gst_type_mark_as_plugin_api (type); + gst_type_mark_as_plugin_api (type, 0); g_once_init_leave (&g_type, type); } return g_type; @@ -164,7 +164,7 @@ gst_vaapi_rate_control_get_type (void) if (g_once_init_enter (&g_type)) { GType type = g_enum_register_static ("GstVaapiRateControl", rate_control_values); - gst_type_mark_as_plugin_api (type); + gst_type_mark_as_plugin_api (type, 0); g_once_init_leave (&g_type, type); } return g_type; From 1c5f32b5cd0ba48f12201565f76aa550733e544a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 9 Jun 2020 21:19:11 +0200 Subject: [PATCH 3626/3781] libs: context: use correct printing modifier GstVaapiID is an alias of gsize, thus its modifier is platform dependant. Part-of: --- gst-libs/gst/vaapi/gstvaapicontext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 5d5deb6ec2..ea6d763218 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -486,7 +486,7 @@ gst_vaapi_context_new (GstVaapiDisplay * display, goto error; done: - GST_DEBUG ("context 0x%08lx / config 0x%08x", + GST_DEBUG ("context 0x%08" G_GSIZE_MODIFIER "x / config 0x%08x", GST_VAAPI_CONTEXT_ID (context), context->va_config); return context; From 72c4a161c09eef669b8f493790a4c991b6c46e8e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 11 Jun 2020 18:15:17 +0800 Subject: [PATCH 3627/3781] plugins: pluginbase: Do not destroy display when _close() When the element's state changes to NULL, it can still receive queries, such as the image formats. The display is needed in such queries but not well protected for MT safe. For example, ensure_allowed_raw_caps() may still use the display while it is disposed by gst_vaapi_plugin_base_close() because of the state change. We can keep the display until the element is destroyed. When the state changes to NULL, and then changes to PAUSED again, the display can be correctly set(if type changes), or leave untouched. Fix: #260 Part-of: --- gst/vaapi/gstvaapipluginbase.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e0c1189ec0..7a06493aef 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -314,6 +314,7 @@ void gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin) { gst_vaapi_plugin_base_close (plugin); + gst_vaapi_display_replace (&plugin->display, NULL); g_free (plugin->display_name); if (plugin->sinkpriv) @@ -339,6 +340,7 @@ gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin) gboolean gst_vaapi_plugin_base_open (GstVaapiPluginBase * plugin) { + gst_caps_replace (&plugin->allowed_raw_caps, NULL); return TRUE; } @@ -355,7 +357,6 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) /* Release vaapi textures first if exist, which refs display object */ plugin_reset_texture_map (plugin); - gst_vaapi_display_replace (&plugin->display, NULL); gst_object_replace (&plugin->gl_context, NULL); gst_object_replace (&plugin->gl_display, NULL); gst_object_replace (&plugin->gl_other_context, NULL); From 4b2f7a188d2fd4353585e00de35a943c5394601a Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Thu, 11 Jun 2020 08:32:05 +0200 Subject: [PATCH 3628/3781] libs: wayland: display: only handle the first output Right now, all outputs are handled. The means that the registry object for all but the last are leaked. As a result the sizes are not used correctly. With two outputs, at first the mode and physical size of the second output are used. If the first output changes the mode, then the physical size of the second output is used in combination with the resolution of the first output. The resulting pixel aspect ratio is incorrect. There seems to be no way to determine on which output the window is shown, so just use the first one to get consistent results. Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 660c99ec9a..8803c294bd 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -122,8 +122,10 @@ registry_handle_global (void *data, 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) { - priv->output = wl_registry_bind (registry, id, &wl_output_interface, 1); - wl_output_add_listener (priv->output, &output_listener, priv); + if (!priv->output) { + priv->output = wl_registry_bind (registry, id, &wl_output_interface, 1); + wl_output_add_listener (priv->output, &output_listener, priv); + } } } From bf7d4bda494dd51cd22ffadcd9dcfda3cdb77305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 19 Jun 2020 15:21:56 +0100 Subject: [PATCH 3629/3781] Update plugin docs and add more plugins Part-of: --- docs/gst_plugins_cache.json | 503 ++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c | 3 + gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 3 + gst-libs/gst/vaapi/gstvaapiencoder_vp8.c | 3 + gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 3 + 5 files changed, 510 insertions(+), 5 deletions(-) diff --git a/docs/gst_plugins_cache.json b/docs/gst_plugins_cache.json index e1a07b85f8..cab02a42f5 100644 --- a/docs/gst_plugins_cache.json +++ b/docs/gst_plugins_cache.json @@ -25,7 +25,7 @@ "presence": "always" }, "src": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, P012_BE, P012_LE, I420_12BE, I420_12LE, Y212_BE, Y212_LE, I422_12BE, I422_12LE, Y412_BE, Y412_LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40, Y444_16BE, Y444_16LE, P016_BE, P016_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(meta:GstVideoGLTextureUploadMeta):\n format: { RGBA, BGRA }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\nvideo/x-raw:\n format: { AYUV64, ARGB64, GBRA_12LE, GBRA_12BE, Y412_LE, Y412_BE, A444_10LE, GBRA_10LE, A444_10BE, GBRA_10BE, A422_10LE, A422_10BE, A420_10LE, A420_10BE, RGB10A2_LE, BGR10A2_LE, Y410, GBRA, ABGR, VUYA, BGRA, AYUV, ARGB, RGBA, A420, Y444_16LE, Y444_16BE, v216, P016_LE, P016_BE, Y444_12LE, GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, Y212_BE, I420_12LE, I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, Y444_10BE, GBR_10BE, r210, I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, Y444, GBR, NV24, xBGR, BGRx, xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, YV12, NV21, NV12, NV12_64Z32, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", "direction": "src", "presence": "always" } @@ -33,69 +33,90 @@ "properties": { "async-handling": { "blurb": "The bin will handle Asynchronous state changes", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "deinterlace-method": { "blurb": "Deinterlace method to use", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "none (0)", + "mutable": "null", "readable": true, "type": "GstVaapiDeinterlaceMethod", "writable": true }, "disable-vpp": { "blurb": "Disable Video Post Processing (No support for run time disabling)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "max-size-buffers": { "blurb": "Max. number of buffers in the queue (0=disable)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1", "max": "-1", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "max-size-bytes": { "blurb": "Max. amount of data in the queue (bytes, 0=disable)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "-1", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "max-size-time": { "blurb": "Max. amount of data in the queue (in ns, 0=disable)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "18446744073709551615", "min": "0", + "mutable": "null", "readable": true, "type": "guint64", "writable": true }, "message-forward": { "blurb": "Forwards all children messages", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true @@ -131,27 +152,36 @@ "properties": { "base-only": { "blurb": "Drop any NAL unit not defined in Annex.A", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "low-latency": { "blurb": "When enabled, frames will be pushed as soon as they are available. It might violate the H.264 spec.", + "conditionally-available": false, "construct": true, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "qos": { "blurb": "Handle Quality-of-Service events from downstream", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "true", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true @@ -191,276 +221,371 @@ "properties": { "bitrate": { "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "2048000", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "cabac": { "blurb": "Enable CABAC entropy coding mode", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "compliance-mode": { "blurb": "Tune Encode quality/performance by relaxing specification compliance restrictions", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "strict (0)", + "mutable": "null", "readable": true, "type": "GstVaapiEncoderH264ComplianceMode", "writable": true }, "cpb-length": { "blurb": "Length of the CPB buffer in milliseconds", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1500", "max": "10000", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "dct8x8": { "blurb": "Enable adaptive use of 8x8 transforms in I-frames", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "default-roi-delta-qp": { "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "-10", "max": "10", "min": "-10", + "mutable": "null", "readable": true, "type": "gint", "writable": true }, "init-qp": { "blurb": "Initial quantizer value", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "26", "max": "51", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "keyframe-period": { "blurb": "Maximal distance between two keyframes (0: auto-calculate)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "30", "max": "-1", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "max-bframes": { "blurb": "Number of B-frames between I and P", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "10", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "max-qp": { "blurb": "Maximum quantizer value", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "51", "max": "51", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "mbbrc": { "blurb": "Macroblock level Bitrate Control", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "auto (0)", + "mutable": "null", "readable": true, "type": "GstVaapiEncoderMbbrc", "writable": true }, - "min-qp": { - "blurb": "Minimum quantizer value", + "min-force-key-unit-interval": { + "blurb": "Minimum interval between force-keyunit requests in nanoseconds", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, + "default": "0", + "max": "18446744073709551615", + "min": "0", + "mutable": "null", + "readable": true, + "type": "guint64", + "writable": true + }, + "min-qp": { + "blurb": "Minimum quantizer value", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, "default": "1", "max": "51", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "num-slices": { "blurb": "Number of slices per frame", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1", "max": "200", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "num-views": { "blurb": "Number of Views for MVC encoding", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1", "max": "10", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "prediction-type": { "blurb": "Reference Picture Selection Modes", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "default (0)", + "mutable": "null", "readable": true, "type": "GstVaapiEncoderH264PredictionType", "writable": true }, "qos": { "blurb": "Handle Quality-of-Service events from downstream", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "qp-ib": { "blurb": "Difference of QP between I and B frame (available only on CQP)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "51", "min": "-51", + "mutable": "null", "readable": true, "type": "gint", "writable": true }, "qp-ip": { "blurb": "Difference of QP between I and P frame (available only on CQP)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "51", "min": "-51", + "mutable": "null", "readable": true, "type": "gint", "writable": true }, "quality-factor": { "blurb": "quality factor for ICQ/QVBR bitrate control mode(low value means higher-quality, higher value means lower-quality)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "26", "max": "51", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "quality-level": { "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "4", "max": "7", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "rate-control": { "blurb": "Rate control mode", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "cqp (1)", + "mutable": "null", "readable": true, "type": "GstVaapiRateControlH264", "writable": true }, "refs": { "blurb": "Number of reference frames", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1", "max": "8", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "target-percentage": { "blurb": "The desired target percentage of bitrate for variable rate controls.", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "70", "max": "100", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "temporal-levels": { "blurb": "Number of temporal levels in the encoded stream ", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1", "max": "4", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "trellis": { "blurb": "The Trellis Quantization Method of Encoder", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "tune": { "blurb": "Encoder tuning option", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "none (0)", + "mutable": "null", "readable": true, "type": "GstVaapiEncoderTuneH264", "writable": true }, "view-ids": { "blurb": "Set of View Ids used for MVC encoding", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, + "mutable": "null", "readable": true, "type": "GstValueArray", "writable": true @@ -786,9 +911,12 @@ "properties": { "qos": { "blurb": "Handle Quality-of-Service events from downstream", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "true", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true @@ -824,9 +952,12 @@ "properties": { "qos": { "blurb": "Handle Quality-of-Service events from downstream", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "true", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true @@ -834,6 +965,199 @@ }, "rank": "primary" }, + "vaapimpeg2enc": { + "author": "Guangxin Xu ", + "description": "A VA-API based MPEG-2 video encoder", + "hierarchy": [ + "GstVaapiEncodeMpeg2", + "GstVaapiEncode", + "GstVideoEncoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "interfaces": [ + "GstPreset" + ], + "klass": "Codec/Encoder/Video/Hardware", + "long-name": "VA-API MPEG-2 encoder", + "pad-templates": { + "sink": { + "caps": "video/x-raw:\n format: { NV12, YV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n\nvideo/x-raw(memory:VASurface):\n format: { NV12, YV12, I420 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n interlace-mode: progressive\n", + "direction": "sink", + "presence": "always" + }, + "src": { + "caps": "video/mpeg:\n mpegversion: 2\n systemstream: false\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "bitrate": { + "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "2048000", + "min": "0", + "mutable": "null", + "readable": true, + "type": "guint", + "writable": true + }, + "default-roi-delta-qp": { + "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "-10", + "max": "10", + "min": "-10", + "mutable": "null", + "readable": true, + "type": "gint", + "writable": true + }, + "keyframe-period": { + "blurb": "Maximal distance between two keyframes (0: auto-calculate)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "30", + "max": "-1", + "min": "0", + "mutable": "null", + "readable": true, + "type": "guint", + "writable": true + }, + "max-bframes": { + "blurb": "Number of B-frames between I and P", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "16", + "min": "0", + "mutable": "null", + "readable": true, + "type": "guint", + "writable": true + }, + "min-force-key-unit-interval": { + "blurb": "Minimum interval between force-keyunit requests in nanoseconds", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "18446744073709551615", + "min": "0", + "mutable": "null", + "readable": true, + "type": "guint64", + "writable": true + }, + "qos": { + "blurb": "Handle Quality-of-Service events from downstream", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": true + }, + "quality-level": { + "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "4", + "max": "7", + "min": "1", + "mutable": "null", + "readable": true, + "type": "guint", + "writable": true + }, + "quantizer": { + "blurb": "Constant quantizer (if rate-control mode is CQP)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "8", + "max": "62", + "min": "2", + "mutable": "null", + "readable": true, + "type": "guint", + "writable": true + }, + "rate-control": { + "blurb": "Rate control mode", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "cqp (1)", + "mutable": "null", + "readable": true, + "type": "GstVaapiRateControlMPEG2", + "writable": true + }, + "target-percentage": { + "blurb": "The desired target percentage of bitrate for variable rate controls.", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "70", + "max": "100", + "min": "1", + "mutable": "null", + "readable": true, + "type": "guint", + "writable": true + }, + "trellis": { + "blurb": "The Trellis Quantization Method of Encoder", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": true + }, + "tune": { + "blurb": "Encoder tuning option", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "none (0)", + "mutable": "null", + "readable": true, + "type": "GstVaapiEncoderTuneMPEG2", + "writable": true + } + }, + "rank": "primary" + }, "vaapipostproc": { "author": "Gwenole Beauchesne ", "description": "A VA-API video postprocessing filter", @@ -865,224 +1189,290 @@ "properties": { "brightness": { "blurb": "The color brightness value", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "1", "min": "-1", + "mutable": "null", "readable": true, "type": "gfloat", "writable": true }, "contrast": { "blurb": "The color contrast value", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1", "max": "2", "min": "0", + "mutable": "null", "readable": true, "type": "gfloat", "writable": true }, "crop-bottom": { "blurb": "Pixels to crop at bottom", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "2147483647", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "crop-left": { "blurb": "Pixels to crop at left", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "2147483647", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "crop-right": { "blurb": "Pixels to crop at right", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "2147483647", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "crop-top": { "blurb": "Pixels to crop at top", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "2147483647", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "deinterlace-method": { "blurb": "Deinterlace method to use", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "bob (1)", + "mutable": "null", "readable": true, "type": "GstVaapiDeinterlaceMethod", "writable": true }, "deinterlace-mode": { "blurb": "Deinterlace mode to use", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "auto (0)", + "mutable": "null", "readable": true, "type": "GstVaapiDeinterlaceMode", "writable": true }, "denoise": { "blurb": "The level of denoising to apply", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "1", "min": "0", + "mutable": "null", "readable": true, "type": "gfloat", "writable": true }, "force-aspect-ratio": { "blurb": "When enabled, scaling will respect original aspect ratio", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "true", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "format": { "blurb": "The forced output pixel format", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "encoded (1)", + "mutable": "null", "readable": true, "type": "GstVideoFormat", "writable": true }, "hdr-tone-map": { "blurb": "Apply HDR tone mapping algorithm", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "auto (0)", + "mutable": "null", "readable": true, "type": "GstVaapiHDRToneMap", "writable": true }, "height": { "blurb": "Forced output height", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "2147483647", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "hue": { "blurb": "The color hue value", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "180", "min": "-180", + "mutable": "null", "readable": true, "type": "gfloat", "writable": true }, "qos": { "blurb": "Handle Quality-of-Service events", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "saturation": { "blurb": "The color saturation value", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1", "max": "2", "min": "0", + "mutable": "null", "readable": true, "type": "gfloat", "writable": true }, "scale-method": { "blurb": "Scaling method to use", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "default (0)", + "mutable": "null", "readable": true, "type": "GstVaapiScaleMethod", "writable": true }, "sharpen": { "blurb": "The level of sharpening/blurring to apply", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "1", "min": "-1", + "mutable": "null", "readable": true, "type": "gfloat", "writable": true }, "skin-tone-enhancement": { "blurb": "Apply the skin tone enhancement algorithm", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "skin-tone-enhancement-level": { "blurb": "Apply the skin tone enhancement algorithm with specified level", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "3", "max": "9", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "video-direction": { "blurb": "Video direction: rotation and flipping", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "identity (0)", + "mutable": "null", "readable": true, "type": "GstVideoOrientationMethod", "writable": true }, "width": { "blurb": "Forced output width", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "2147483647", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true @@ -1111,7 +1501,7 @@ "long-name": "VA-API sink", "pad-templates": { "sink": { - "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:VASurface, meta:GstVideoOverlayComposition):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoOverlayComposition):\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, P012_BE, P012_LE, I420_12BE, I420_12LE, Y212_BE, Y212_LE, I422_12BE, I422_12LE, Y412_BE, Y412_LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40, Y444_16BE, Y444_16LE, P016_BE, P016_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { I420, YV12, YUY2, UYVY, AYUV, VUYA, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, Y210, Y410, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10BE, I420_10LE, I422_10BE, I422_10LE, Y444_10BE, Y444_10LE, GBR, GBR_10BE, GBR_10LE, NV16, NV24, NV12_64Z32, A420_10BE, A420_10LE, A422_10BE, A422_10LE, A444_10BE, A444_10LE, NV61, P010_10BE, P010_10LE, IYU2, VYUY, GBRA, GBRA_10BE, GBRA_10LE, BGR10A2_LE, RGB10A2_LE, GBR_12BE, GBR_12LE, GBRA_12BE, GBRA_12LE, P012_BE, P012_LE, I420_12BE, I420_12LE, Y212_BE, Y212_LE, I422_12BE, I422_12LE, Y412_BE, Y412_LE, Y444_12BE, Y444_12LE, GRAY10_LE32, NV12_10LE32, NV16_10LE32, NV12_10LE40, Y444_16BE, Y444_16LE, P016_BE, P016_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw(memory:VASurface):\n format: { ENCODED, NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:VASurface, meta:GstVideoOverlayComposition):\n format: { ENCODED, NV12, I420, YV12, P010_10LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(meta:GstVideoOverlayComposition):\n format: { AYUV64, ARGB64, GBRA_12LE, GBRA_12BE, Y412_LE, Y412_BE, A444_10LE, GBRA_10LE, A444_10BE, GBRA_10BE, A422_10LE, A422_10BE, A420_10LE, A420_10BE, RGB10A2_LE, BGR10A2_LE, Y410, GBRA, ABGR, VUYA, BGRA, AYUV, ARGB, RGBA, A420, Y444_16LE, Y444_16BE, v216, P016_LE, P016_BE, Y444_12LE, GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, Y212_BE, I420_12LE, I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, Y444_10BE, GBR_10BE, r210, I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, Y444, GBR, NV24, xBGR, BGRx, xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, YV12, NV21, NV12, NV12_64Z32, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { AYUV64, ARGB64, GBRA_12LE, GBRA_12BE, Y412_LE, Y412_BE, A444_10LE, GBRA_10LE, A444_10BE, GBRA_10BE, A422_10LE, A422_10BE, A420_10LE, A420_10BE, RGB10A2_LE, BGR10A2_LE, Y410, GBRA, ABGR, VUYA, BGRA, AYUV, ARGB, RGBA, A420, Y444_16LE, Y444_16BE, v216, P016_LE, P016_BE, Y444_12LE, GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, Y212_BE, I420_12LE, I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, Y444_10BE, GBR_10BE, r210, I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, Y444, GBR, NV24, xBGR, BGRx, xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, YV12, NV21, NV12, NV12_64Z32, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "sink", "presence": "always" } @@ -1119,254 +1509,329 @@ "properties": { "async": { "blurb": "Go asynchronously to PAUSED", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "true", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "blocksize": { "blurb": "Size in bytes to pull per buffer (0 = default)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "4096", "max": "-1", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "brightness": { "blurb": "The display brightness value", + "conditionally-available": false, "construct": true, "construct-only": false, + "controllable": false, "default": "0", "max": "1", "min": "-1", + "mutable": "null", "readable": true, "type": "gfloat", "writable": true }, "contrast": { "blurb": "The display contrast value", + "conditionally-available": false, "construct": true, "construct-only": false, + "controllable": false, "default": "1", "max": "2", "min": "0", + "mutable": "null", "readable": true, "type": "gfloat", "writable": true }, "display": { "blurb": "display type to use", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "any (0)", + "mutable": "null", "readable": true, "type": "GstVaapiDisplayType", "writable": true }, "display-name": { "blurb": "display name to use", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "NULL", + "mutable": "null", "readable": true, "type": "gchararray", "writable": true }, "enable-last-sample": { "blurb": "Enable the last-sample property", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "true", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "force-aspect-ratio": { "blurb": "When enabled, scaling will respect original aspect ratio", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "true", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "fullscreen": { "blurb": "Requests window in fullscreen state", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "hue": { "blurb": "The display hue value", + "conditionally-available": false, "construct": true, "construct-only": false, + "controllable": false, "default": "0", "max": "180", "min": "-180", + "mutable": "null", "readable": true, "type": "gfloat", "writable": true }, "last-sample": { "blurb": "The last sample received in the sink", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, + "mutable": "null", "readable": true, "type": "GstSample", "writable": false }, "max-bitrate": { "blurb": "The maximum bits per second to render (0 = disabled)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "18446744073709551615", "min": "0", + "mutable": "null", "readable": true, "type": "guint64", "writable": true }, "max-lateness": { "blurb": "Maximum number of nanoseconds that a buffer can be late before it is dropped (-1 unlimited)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "5000000", "max": "9223372036854775807", "min": "-1", + "mutable": "null", "readable": true, "type": "gint64", "writable": true }, "processing-deadline": { "blurb": "Maximum processing time for a buffer in nanoseconds", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "15000000", "max": "18446744073709551615", "min": "0", + "mutable": "null", "readable": true, "type": "guint64", "writable": true }, "qos": { "blurb": "Generate Quality-of-Service events upstream", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "true", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "render-delay": { "blurb": "Additional render delay of the sink in nanoseconds", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "18446744073709551615", "min": "0", + "mutable": "null", "readable": true, "type": "guint64", "writable": true }, "rotation": { "blurb": "The display rotation mode", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0 (0)", + "mutable": "null", "readable": true, "type": "GstVaapiRotation", "writable": true }, "saturation": { "blurb": "The display saturation value", + "conditionally-available": false, "construct": true, "construct-only": false, + "controllable": false, "default": "1", "max": "2", "min": "0", + "mutable": "null", "readable": true, "type": "gfloat", "writable": true }, "show-preroll-frame": { "blurb": "Whether to render video frames during preroll", + "conditionally-available": false, "construct": true, "construct-only": false, + "controllable": false, "default": "true", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "signal-handoffs": { "blurb": "Send a signal after rendering the buffer", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "stats": { "blurb": "Sink Statistics", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "application/x-gst-base-sink-stats, average-rate=(double)0, dropped=(guint64)0, rendered=(guint64)0;", + "mutable": "null", "readable": true, "type": "GstStructure", "writable": false }, "sync": { "blurb": "Sync on the clock", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "true", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "throttle-time": { "blurb": "The time to keep between rendered buffers (0 = disabled)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "18446744073709551615", "min": "0", + "mutable": "null", "readable": true, "type": "guint64", "writable": true }, "ts-offset": { "blurb": "Timestamp offset in nanoseconds", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "9223372036854775807", "min": "-9223372036854775808", + "mutable": "null", "readable": true, "type": "gint64", "writable": true }, "view-id": { "blurb": "ID of the view component of interest to display", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "-1", "max": "2147483647", "min": "-1", + "mutable": "null", "readable": true, "type": "gint", "writable": true } }, - "rank": "primary", + "rank": "marginal", "signals": { "handoff": { "args": [ @@ -1408,9 +1873,12 @@ "properties": { "qos": { "blurb": "Handle Quality-of-Service events from downstream", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "true", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true @@ -1597,6 +2065,16 @@ } ] }, + "GstVaapiEncoderTuneMPEG2": { + "kind": "enum", + "values": [ + { + "desc": "None", + "name": "none", + "value": "0" + } + ] + }, "GstVaapiHDRToneMap": { "kind": "enum", "values": [ @@ -1677,6 +2155,21 @@ } ] }, + "GstVaapiRateControlMPEG2": { + "kind": "enum", + "values": [ + { + "desc": "Constant QP", + "name": "cqp", + "value": "1" + }, + { + "desc": "Constant bitrate", + "name": "cbr", + "value": "2" + } + ] + }, "GstVaapiRotation": { "kind": "enum", "values": [ diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c index 8eda7630a4..00d1597c22 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c @@ -894,6 +894,9 @@ gst_vaapi_encoder_jpeg_class_init (GstVaapiEncoderJpegClass * klass) 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); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 58477d7eec..731b03e58b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -922,6 +922,9 @@ gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass) g_object_class_install_properties (object_class, ENCODER_MPEG2_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); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c index ce88cfb6f0..99ffa4615f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp8.c @@ -681,6 +681,9 @@ gst_vaapi_encoder_vp8_class_init (GstVaapiEncoderVP8Class * klass) 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); } /** diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 0c66a29549..e9b711b9e7 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -745,6 +745,9 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) 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); } /** From 41bf465196836158b8eb797c055093315f1bf9bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 19 Jun 2020 19:27:11 +0100 Subject: [PATCH 3630/3781] Release 1.17.1 --- ChangeLog | 3869 +++++++++++++++++++++++++++++++++++++++++- NEWS | 1300 +------------- RELEASE | 15 +- gstreamer-vaapi.doap | 12 +- meson.build | 2 +- 5 files changed, 3909 insertions(+), 1289 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1088902823..92a037ee14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,3820 @@ +=== release 1.17.1 === + +2020-06-19 19:27:11 +0100 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * RELEASE: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.17.1 + +2020-06-19 15:21:56 +0100 Tim-Philipp Müller + + * docs/gst_plugins_cache.json: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + Update plugin docs and add more plugins + Part-of: + +2020-06-11 08:32:05 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + libs: wayland: display: only handle the first output + Right now, all outputs are handled. The means that the registry object for + all but the last are leaked. As a result the sizes are not used correctly. + With two outputs, at first the mode and physical size of the second output + are used. If the first output changes the mode, then the physical size of + the second output is used in combination with the resolution of the first + output. The resulting pixel aspect ratio is incorrect. + There seems to be no way to determine on which output the window is shown, + so just use the first one to get consistent results. + Part-of: + +2020-06-11 18:15:17 +0800 He Junyan + + * gst/vaapi/gstvaapipluginbase.c: + plugins: pluginbase: Do not destroy display when _close() + When the element's state changes to NULL, it can still receive + queries, such as the image formats. The display is needed in such + queries but not well protected for MT safe. + For example, ensure_allowed_raw_caps() may still use the display + while it is disposed by gst_vaapi_plugin_base_close() because of + the state change. + We can keep the display until the element is destroyed. When the + state changes to NULL, and then changes to PAUSED again, the display + can be correctly set(if type changes), or leave untouched. + Fix: #260 + Part-of: + +2020-06-09 21:19:11 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + libs: context: use correct printing modifier + GstVaapiID is an alias of gsize, thus its modifier is platform + dependant. + Part-of: + +2020-06-06 00:42:46 +0200 Mathieu Duponchelle + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapivalue.c: + plugins: uddate gst_type_mark_as_plugin_api() calls + +2020-03-05 18:12:27 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: Enable tile in VA command. + Part-of: + +2020-03-05 17:56:51 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: Add ensure_tile to calculate tiles. + We need consider tiles and slices together, separate tiles uniformly + and then assign slices uniformly to each tiles. + Part-of: + +2020-04-30 14:19:29 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + libs: display: add a quirk for iHD driver tile encoding. + The iHD driver has a requirement that one slice can not span tiles + when tile is enabled, which is not required by hevc spec. + Part-of: + +2020-03-05 17:40:43 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: Add tile info to bitstream. + Part-of: + +2020-03-05 17:29:41 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: promote level if tile is enabled. + Part-of: + +2020-03-05 17:07:28 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.h: + libs: encoder: h265: Add num-tile-cols/rows properties. + These properties are used for support of tile encoding. We just + support uniform mode of tile encoding, that is, separating picture + equally by (num-tile-cols X num-tile-rows). + According to HEVC spec A1, the max number of tiles in column is 20 + and in rows is 22, so add two constant definitions. + Part-of: + +2020-03-05 16:21:24 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: extract slice creation from add_slice_headers + extract slice creation details from add_slice_headers, and let the + add_slice_headers just focuses on calculating slice start address + and CTU number. + Part-of: + +2020-03-05 12:44:45 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: Add a helper function to check the tile support. + Encoding by tiles separation now is a very common feature for all + relative new codecs, such as HEVC, AV1, and VP9. Just make this + check as a common helper function of the encoder base class. + Part-of: + +2020-05-13 18:02:07 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + libs: decoder: H265: Add SCC_MAIN_444_10 profile support. + Part-of: + +2020-05-13 16:05:59 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: update reference list for SCC. + Part-of: + +2020-05-13 15:46:29 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: H265: Fill picture and slice SCC parameters. + Part-of: + +2020-05-13 15:00:53 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + libs: util: H265: recognize the SCC profiles. + Part-of: + +2020-05-13 14:53:46 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: profile: Add screen extended main/main10/main444 define. + Part-of: + +2020-04-03 14:53:40 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst/vaapi/gstvaapiencode_h265.c: + libs: encoder: h265: Add support for MAIN 4:2:2 10 profile. + Using YUY2 as the input of the encoder can generate main 4:2:2 bit + streams and using Y210 as the input of the encoder can generate main + 4:2:2 10 bit streams. + Part-of: + +2020-05-29 16:40:20 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: Use correct index for SubWidthC and SubHeightC. + We need to use the chroma_format_idc as the index for getting the + SubWidthC and SubHeightC values as the spec 6.1(table 6-1) defines. + The wrong SubWidthC or SubHeightC make us calculate a wrong right + or bottom offset for crop size and generate garbage in output. + Part-of: + +2020-05-29 15:37:24 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + libs: encoder: h265: Fix chrome idc for 444 10 bits + GST_VAAPI_CHROMA_TYPE_YUV444_10BPP should also set chroma_format_idc + to 3 as GST_VAAPI_CHROMA_TYPE_YUV444 does. + Part-of: + +2020-06-03 18:37:22 -0400 Thibault Saunier + + * docs/meson.build: + doc: Require hotdoc >= 0.11.0 + +2020-06-03 18:49:53 -0400 Thibault Saunier + + * gst/vaapi/gstvaapipostproc.c: + doc: Fix wrong link to GstVideoDirectionMethod + +2020-06-03 17:38:10 -0400 Thibault Saunier + + * docs/gst_plugins_cache.json: + * meson_options.txt: + docs: Update plugin cache with the new format + And fix the default URL which should not be inside quotes. + +2020-06-03 17:37:48 -0400 Thibault Saunier + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst/vaapi/gstvaapipostproc.c: + Use gst_type_mark_as_plugin_api() for all non-element plugin types + +2020-05-23 22:09:17 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiobject.c: + * gst-libs/gst/vaapi/gstvaapiobject.h: + * gst-libs/gst/vaapi/gstvaapiobject_priv.h: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/meson.build: + libs: delete all gstvaapiobject related files. + Part-of: + +2020-05-23 20:48:54 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapisurface.c: + libs: surface: return fail immediately if can not create subpicture + Part-of: + +2020-05-23 14:00:58 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisubpicture.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * tests/internal/image.c: + libs: subpicture: Make subpicture a standard GstMiniObject. + Part-of: + +2020-05-26 02:19:15 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: Add ref flags for splited field. + When split one frame into fields, the second field should also + copy the reference flags. + Part-of: + +2020-05-25 15:46:58 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: decoder: h264: disallow multiple slice group + As far as we know there are no VAAPI drivers supporting FMO, which + migth be used in baseline streams. + This commit is a continuation of + https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/328 + Part-of: + +2020-05-20 10:50:05 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode_props.c: + * gst/vaapi/gstvaapidecode_props.h: + vaapidecoder: h264: remove baseline as constrained property + From now on always the baseline is going to be treated as constrained without + need of setting a property. + Since the property was added along the development cycle (1.17 / commit + 866a9f06) and never released, we assume that it is safe to remove it. + Fixes: #252 + Part-of: + +2020-05-21 11:37:36 +0200 Víctor Manuel Jáquez Leal + + * README: + README: update VP9 decoder and encoder + Part-of: + +2020-05-21 13:42:47 +0800 Haihao Xiang + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + vaapiencoder_h264: set direct_spatial_mv_pred_flag to true by default + This flag is set to true by default in both MediaSDK and FFmpeg-vaapi, + so let's align this plugin with other libraries / softwares. + Part-of: + +2020-05-18 18:29:05 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: fix meta overwrite + commit 7ac2a207 added a regression by erroneously assumed that + GstVaapiVideoMeta is actually a GstMeta, which is not. + Part-of: + +2020-05-17 09:55:42 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideometa_texture.c: + * gst/vaapi/gstvaapivideometa_texture.h: + vaapivideopool: Set pooled flag to added metas. + So this could hint filters how to use these metas. + Had to change the return value for texutre upload meta in order + to flag it. + Part-of: + +2020-05-16 20:49:31 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapiparser_frame.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + libs: use array_unref() rather than array_free() + It is more convinience and thread-safe. + Part-of: + +2020-04-10 22:20:35 +0800 He Junyan + + * gst/vaapi/gstvaapi.c: + plugin: use register_type to replace get_type for encode init. + xxx_register_type will detect the template sink caps and is needed + to be called at init time. + Part-of: + +2020-04-10 22:05:50 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_vp9.c: + * gst/vaapi/gstvaapiencode_vp9.h: + plugins: encode: Modify sink template of vp9 encode. + Use gst_vaapi_detect_codec_caps to get more precise template caps. + Also implement gst_vaapiencode_vp9_register_type, which should be + called at plugin register time. + Part-of: + +2020-04-10 22:05:18 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiencode_vp8.h: + plugins: encode: Modify sink template of vp8 encode. + Use gst_vaapi_detect_codec_caps to get more precise template caps. + Also implement gst_vaapiencode_vp8_register_type, which should be + called at plugin register time. + Part-of: + +2020-04-10 22:04:34 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_mpeg2.h: + plugins: encode: Modify sink template of mpeg2 encode. + Use gst_vaapi_detect_codec_caps to get more precise template caps. + Also implement gst_vaapiencode_mpeg2_register_type, which should be + called at plugin register time. + Part-of: + +2020-04-10 22:03:49 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_h265.h: + plugins: encode: Modify sink template of h265 encode. + Use gst_vaapi_detect_codec_caps to get more precise template caps. + Also implement gst_vaapiencode_h265_register_type, which should be + called at plugin register time. + Part-of: + +2020-04-10 22:00:38 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264.h: + plugins: encode: Modify sink template of h264 encode. + Use gst_vaapi_detect_codec_caps to get more precise template caps. + Also implement gst_vaapiencode_h264_register_type, which should be + called at plugin register time. + Part-of: + +2020-04-10 22:11:34 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_jpeg.h: + plugins: encode: Modify sink template of jpeg encode. + Use gst_vaapi_detect_codec_caps to get more precise template caps. + Also implement gst_vaapiencode_jpeg_register_type, which should be + called at plugin register time. + Part-of: + +2020-04-23 00:02:02 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.h: + plugin: encode: add a helper macro to register encode type. + Part-of: + +2020-04-10 21:44:05 +0800 He Junyan + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + plugins: util: Add a helper function to detect supported caps. + This helper function iterate all profiles and entrypoints belong + to the specified codec, query the VAConfigAttribRTFormat and list + all possible video formats. + This function is used by each codec to get the template sink caps + (for encode) or src caps(for decode) at register time, when just + all possible formats are listed and no need to be very accurate. + So there is no context created for the performance reason. Most + codecs just use YUV kinds of formats as the input/output, so we do + not include RGB kinds of formats. User can specified more formats + in extra_fmts(For example, jpeg may need BGRA) if needed. + Part-of: + +2020-04-10 21:27:32 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + plugin: encode: extract the allowed caps maker as a helper function. + Extract all logic about making caps for encode's sink as a standalone + helper function. It can be reused. + Part-of: + +2020-04-10 21:21:43 +0800 He Junyan + + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + libs: video-format: add a helper function of get_formats_by_chroma. + The function iterates all supported video formats and returns the + formats belong to the specified chroma type. + Part-of: + +2020-05-16 21:03:32 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture_priv.h: + libs: texture: remove unused headers include + This is continuation of + https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/317 + Part-of: + +2020-05-16 19:58:25 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicodedbuffer.h: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapisurface.h: + libs: removed duplicated function declarations + Some headers had duplicated inlined function declaration. This was + for gtkdoc, but now GStreamer uses hotdoc and the internal library + documentation is not generated. So let's remove these extra lines. + Part-of: + +2020-04-18 19:32:24 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapitexture.c: + * gst-libs/gst/vaapi/gstvaapitexture.h: + * gst-libs/gst/vaapi/gstvaapitexture_egl.c: + * gst-libs/gst/vaapi/gstvaapitexture_glx.c: + * gst-libs/gst/vaapi/gstvaapitexture_priv.h: + * gst-libs/gst/vaapi/gstvaapitexturemap.c: + * gst-libs/gst/vaapi/gstvaapiwindow_egl.c: + * gst/vaapi/gstvaapivideometa_texture.c: + * tests/internal/test-textures.c: + libs: texture: Make texture a standard GstMiniObject. + We store GstVaapiTextureGLX and GstVaapiTextureEGL's private data in + the qdata of miniobject and avoid extending the base texture class. + Part-of: + +2020-04-26 12:33:29 +0200 Víctor Manuel Jáquez Leal + + * README: + Update README + Part-of: + +2020-04-21 18:00:26 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + libs: display: drm: use g_strcmp0 to be null safe + Part-of: + +2020-04-26 13:30:16 +0800 Haihao Xiang + + * gst/vaapi/gstvaapipluginutil.c: + vaapipluginutil: Use GST_VAAPI_DISPLAY_TYPE_DRM for Mesa3D GBM + We may build this plugin with window system support but run it without + window system. Without this patch, the following pipeline will trigger a + segfault when running it without window system. + gst-launch-1.0 filesrc location=input.264 ! h264parse ! vaapih264dec ! fakesink + Part-of: + +2020-04-21 11:16:37 +0200 Víctor Manuel Jáquez Leal + + * meson.build: + build: use join_paths() for driverdir + +2020-04-21 09:04:51 +0000 Veerabadhran G + + * README: + README: Update supported hardware + Added the AMD hardware list to the "Hardware Requirements" section. + +2020-04-04 13:58:00 +0200 He Junyan + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy.h: + * gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h: + libs: bufferproxy: remove GstMemory reference + Since bufferproxy and surface are not referenced circularly, there's + no need to keep, in the buffer proxy, a reference to the GstMemory + where it is held. This patch removes that handling. + +2020-03-15 23:29:05 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + * gst-libs/gst/vaapi/gstvaapisurface_drm.h: + * gst/vaapi/gstvaapivideomemory.c: + libs,plugin: break surface-bufferproxy circular reference + The bufferproxy may reference the surface and the surface may also + reference the bufferproxy, producing a circular reference, which might + lead to serious resource leak problems. + Now make the relationship clearer, the bufferproxy's references is + transfered to surface, while bufferproxy just keeps the surface's + address without increasing its reference count. + The surface can be created through a bufferproxy like in + gst_vaapi_surface_new_with_dma_buf_handle(), and the surface might + get its bufferproxy via gst_vaapi_surface_get_dma_buf_handle(). In + both cases the surface holds a bufferproxy's reference. + +2020-04-03 18:43:52 +0200 He Junyan + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + libs: bufferproxy: rename parent memeber as surface + +2020-03-15 22:07:31 +0800 He Junyan + + * gst/vaapi/gstvaapivideobufferpool.c: + plugin: bufferpool: use hashmap to cache dmabuf mem-surface + The old way of refer memory by bufferproxy is not a good one, since it + make the logic error prone. + Now it is established a map between surface-bufferproxy and its GstMemory, + caching the memory bound by a surface looked for the specified surface. + +2020-03-15 21:50:24 +0800 He Junyan + + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideobufferpool.h: + plugin: bufferpool: Delete ACQUIRE_FLAG_NO_ALLOC flag. + Delete the GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC flag. + In fact, no one is using that flag, and all vaapi buffers should + have GstVaapiVideoMeta. + +2020-02-13 09:43:38 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: enable HDR10 tone mapping + +2020-02-13 09:00:18 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + libs: filter: HDR10 tone mapping support + Add support for HDR10 tone mapping (since VA-API 1.4.0). + +2020-04-02 15:14:15 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst/vaapi/gstvaapiencode_h265.c: + libs: encoder: h265: Support MAIN 4:4:4 10 profile. + Using Y410 as the input of the encoder can generate main_444_10 bit + streams. + +2020-04-02 15:19:41 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: fix an inexact trace info in chroma type check. + +2020-03-31 12:22:31 +0800 Haihao Xiang + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: make sure format array is not NULL when returning TRUE + This fixed segfault when running the pipeline below with iHD driver + (commit efe5e9a) on ICL + gst-launch-1.0 videotestsrc ! vaapivp9enc tune=low-power ! vaapivp9dec ! \ + fakesink + +2020-03-18 13:28:00 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.h: + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vp8.h: + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.h: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.h: + * gst-libs/gst/vaapi/gstvaapidisplay_egl.h: + * gst-libs/gst/vaapi/gstvaapidisplay_glx.h: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.h: + * gst-libs/gst/vaapi/gstvaapidisplay_x11.h: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.h: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.h: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst-libs/gst/vaapi/gstvaapitexturemap.h: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_drm.h: + * gst-libs/gst/vaapi/gstvaapiwindow_egl.h: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + libs: extend g_autoptr support + +2020-03-26 22:40:40 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideometa.c: + vaapivideometa: remove compiler warning + +2020-03-22 20:59:20 +0100 Víctor Manuel Jáquez Leal + + * meson.build: + * meson_options.txt: + build: Add meson's option package-origin. + This options is added to synchronize with other gstreamer packages + build configuration. + Though, to avoid breaking distro configuration it is set, as default, + the issues gitlab's url, instead of the used string + "Unkown package origin". + Also, set_quoted is used for string based cdata. + +2020-02-25 13:45:05 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: deprecate format, width and size parameters + Since they should only be controlled by caps negotiation. + +2020-03-18 16:41:01 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst/vaapi/gstvaapidecode.c: + libs,plugins: decoder: Add -intra profile support for hevc. + In hevc, we can consider the -intra profile a subset of the none + -intra profile. The -intra profiles just contain I frames and we + definitely can use the none -intra profiles's context to decode + them. + Signed-off-by: Víctor Manuel Jáquez Leal + +2020-03-04 12:35:42 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: support ICQ/QVBR BRC + Enable support for ICQ and QVBR bitrate control. + The code is essentially the same for h264 ICQ/QVBR support + which was added in commit 9e0c133a2403. + +2020-03-19 11:19:18 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: set VA HRD param before RC param + This is a workaround for intel-media-driver bug + https://github.com/intel/media-driver/issues/865 + The driver will force the RC method to CBR for HEVCe + when it parses the HRD param. Thus, any RC method + param submitted "prior" to the HRD param will be lost. + Therefore, VBR, ICQ and QVBR for HEVCe can't be + effectively enabled if the RC method param "precedes" + the HRD param. + To work around this issue, set the HRD param before + the RC method param so the driver will parse the RC + method param "after" the HRD param. + Afaict, other codecs in the driver (and other drivers) + do not appear to be dependent on the order of HRD and + RC param submission. + +2019-11-25 14:16:30 +0800 Haihao Xiang + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + vaapijpegenc: Add a quantization quirk for iHD driver + iHD driver shifts the value by 50 when calculating quantization for JPEG + encoding, so we should add 50 in this plugin for iHD driver too. + +2020-03-13 21:49:15 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + * gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h: + * gst-libs/gst/vaapi/gstvaapipixmap.c: + * gst-libs/gst/vaapi/gstvaapipixmap.h: + * gst-libs/gst/vaapi/gstvaapipixmap_priv.h: + * gst-libs/gst/vaapi/gstvaapipixmap_x11.c: + * gst-libs/gst/vaapi/gstvaapipixmap_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_egl.c: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + * gst-libs/gst/vaapi/meson.build: + * meson.build: + * tests/internal/output.c: + * tests/internal/output.h: + * tests/internal/simple-decoder.c: + * tests/internal/test-decode.c: + libs: remove GstVaapiPixmap + GstVaapiPixmap is an abstract base class which only implementation + were GstVaapiPixmapX11. This class were used for a special type of + rendering in the tests apps, utterly unrelated in GStreamer. + Since gstreamer-vaapi is no longer a general-user wrapper for VA-API + we should remove this unused API. + This removal drops libxrender dependency. + +2020-03-17 18:51:19 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: Add HEVC Main444 sting in string_of_VAProfile + HEVCMain444_10 is already a supported profile and misses the strings. + +2020-03-17 12:47:33 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + plugin: don't error if cannot create display + This might generated errors on automatic tools such as CI. Let's + rather just raise a warning and let continue. + +2020-03-09 01:52:57 +0800 He Junyan + + * tests/check/meson.build: + test: fix a ninja test failure for vaapioverlay. + That test case only works with drm display, so the build such as + meson -Dwith_x11=yes -Dwith_wayland=no -Dwith_drm=no -Dwith_egl=no + -Dwith_glx=no + gets a failure when run ninja test. Just enable this test when drm + is enabled. + +2020-02-07 23:56:13 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapivideopool.c: + libs: videopool: fix a condition race for pool allocate. + +2020-03-05 13:22:23 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: force video meta if sizes are different + The strides and offsets could be the same, but the allocation + size might be different (e.g. alignment). Thus, ensure we also + set the flag to copy from VA memory to system memory when alloc + size differs. + Fixes #243 + +2020-03-05 14:18:32 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: don't set base sink caps twice + Base class's sink pad caps are already set when calling set_format(). + There's no need to call it again in gst_vaapidecode_negotiate(). + +2020-03-05 13:26:38 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: unlock stream if caps update fails + If caps update fail a dead lock occurs since the stream mutex is not + unlocked. + +2020-03-03 15:24:32 +0800 Xu Guangxin + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h265: parser state after update dependent slice + If the dependent_slice_segment_flag is true, most slice info derived from last slice. + So we need check the slice type after we call populate_dependent_slice_hdr + +2020-02-16 12:21:28 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + libs: display: force RGBA image format for i965 driver + Since commit 32bf6f1e GLTextureUpload is broken because i965 + doesn't report properly RGBA support. It could be possible to use RGBx + but GLTextureUpload only regotiates RGBA. + The simplest fix to this regression is adding synthetically the RGBA + format in the internal format map. + +2020-02-14 19:30:54 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: iterate all quirks table + Instead of break at the fist foud quirk in the table, iterate all over + so it would be feasible to add several quirks for one driver per + element in array. + +2020-02-25 12:05:28 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: filter: handle RGB to/from YUV color primary driver quirk + The intel-media-driver (iHD) can't convert output color + primaries when doing YUV to/from RGB CSC. Thus, we must + keep the output color primaries the same as the input + color primaries for this case. + fixes #238 + +2020-02-25 12:00:36 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + libs: display: add YUV to/from RGB color primary quirk + The intel-media-driver (iHD) can't convert output color + primaries when doing YUV to/from RGB CSC. + +2020-02-28 11:33:18 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + Revert "vaapivideomemory: Store surface allocation flags." + This reverts commit dd428cc4a12c2d5c694fcd3303811cf486002c9d because + it rewrites the buffer size whilst surface allocation flags are + stored when allocator_params_init() is called since fab890ce. + Fix: #239 + +2020-01-27 18:19:57 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: Try surface with allocation flags. + When a vaapi allocator is instantiated, it first try to generate a + surface with the specified configuration. + This patch adds, in this tried buffer, the requested allocation flags. + +2020-01-27 18:10:18 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: Store surface allocation flags. + Store surface allocation flags passed to the vaapi allocator in + GObject's qdata, because it might be used by the vaapivideobufferpool + when recreating the allocator given any resolution change. + +2020-01-24 19:32:52 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + libs: surface: Add hints to allocation flags. + When creating surfaces it is possible to pass to VA hints of its usage, + so the driver may do some optimizations. + This commit adds the handling of encoding/decoding hints. + +2020-01-24 22:08:50 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurface_egl.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * tests/internal/test-filter.c: + * tests/internal/test-surfaces.c: + libs: surface: surfacepool: Add allocation flags in constructors. + +2020-02-22 16:06:13 +0800 He Junyan + + * meson.build: + build: let the build fail if none if X11, wayland or drm. + In fact, gst_vaapi_create_test_display only test x11, wayland and + drm, no glx and egl entries. So if none of them is enabled, no + vaapi element can be detected. + +2020-02-21 00:58:47 +0800 He Junyan + + * tests/internal/test-display.c: + test: avoid unused warning for test-display + meson -Dwith_x11=yes -Dwith_wayland=no -Dwith_drm=no -Dwith_egl=no + -Dwith_glx=no buildir + generate unused warnings. + +2020-02-21 00:50:47 +0800 He Junyan + + * meson.build: + build: fix meson build error when without x11. + meson -Dwith_x11=no build_dir + can not success build the project because the glx is still enabled. + We need to disable GLX when X11 is disabled. + +2020-02-14 19:53:09 +0800 Haihao Xiang + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: h265enc: Set max_transform_hierarchy_depth_{inter, intra} to 2 + Intel HW has limitation on max_transform_hierarchy_depth_inter and + max_transform_hierarchy_depth_intra (see [1]). We can provide a quirk for + other HWs if other HWs may support other values + [1] https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol10-hevc.pdf + +2020-02-21 07:37:50 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: do not compensate for crop/direction if no VPP + If we do not have functional VPP, then cropping and video + direction is non-functional and we should avoid calling + any of the gst_vaapi_filter* APIs. + +2020-02-21 06:54:47 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: only set VPP colorimetry when VPP is available + If we don't have functional vpp then we should not call + gst_vaapi_filter_set_colorimetry. + +2020-02-16 01:25:37 +0800 He Junyan + + * gst/vaapi/gstvaapivideobufferpool.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + videobufferpool: don't reset surface when created internally + The bug fixing, in commit 89f202ea, just considers the case when + surface's DMABuf is set through gst_buffer_pool_acquire_buffer(), + which is typically a decoder's behavior. But vaapipostproc doesn't + provide any surface when calling gst_buffer_pool_acquire_buffer(), + thus a surface is created when GstMemory is allocated. + If the surface proxy in buffer's meta is reset at + buffer_pool_reset_buffer(), that surface will be destroyed and it + won't be available anymore. But GstBuffers are cached in the buffer + pool and they are reused again, hence only those images are rendered + repeatedly. + Fixes: #232 + +2020-02-16 17:19:04 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiblend.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst/vaapi/gstvaapi.c: + libs: blend: filter: handle finalize() if display isn't assigned + I've just discovered iHD driver in Skylake doesn't have VideoProc + entry point, hence, in this platform, when vaapioverlay is tried to be + registered, critical warnings are raised because blend doesn't have a + display assigned. + As it is possible to have drivers without EntryPointVideoProc it is + required to handle it gracefully. This patch does that: only tries to + register vaapioverlay if the testing display has VPP and finalize() + vmethods, in filter and blend, bail out if display is NULL. + +2020-02-15 11:02:49 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: filter: guard all color properties to VA-API 1.2.0 + Older VA-API (0.39.0) doesn't have VAProcColorProperties. + Thus, guard all colorimetry -> VA-API support to version + 1.2.0. + Fixes #234 + +2020-02-17 08:55:36 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h265: set parser info state at decoding codec data + Commit 1168d6d5 showed up a regression: decode_sps() stores the unit's + parser info in sps array. If that parser info comes from decoding + codec data, that parser info will have an undefined state which might + break ensure_sps(). + This patch sets the parser info state, at decoding codec data, with + the internal parser state. This is similar with h264 decoder apprach. + Original-patch-by: Xu Guangxin + +2020-02-07 15:24:18 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: demote log message to trace level + +2020-02-14 14:45:56 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/video-format.c: + libs: video-format: set general vaapi log category + Instead of logging in an unspecified category, set the default vaapi. + +2020-02-15 11:44:48 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: guard EncSliceLP for VA-API < 0.39.1 + Relates to #234 + +2020-02-14 16:17:04 +0800 Haihao Xiang + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: h265enc: Set VA_PICTURE_HEVC_INVALID flag for invalid picture + +2020-02-11 11:31:31 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vc1.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: remove crumbs of libva < 0.39 + All these guarded code seem like leftovers of commit 920b1ec7a. This + patch completes that missing clean up. + +2020-02-11 00:38:40 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: VA explicit color standard not supported until 1.2.0 + VAProcColorStandardExplicit and associated VAProcColorProperties + (primaries, transfer and matrix) are not supported until + VA-API 1.2.0. + Use VAProcColorStandardNone instead of VAProcColorStandardExplicit + if VA-API < 1.2.0. + Fixes #231 + +2020-02-10 09:31:15 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: WA: use explicit for sRGB colorimetry + Addresses #228 on iHD side. It seems iHD can't handle + VAProcColorStandardSRGB in all situations for vpp. But + it has no problem when we specify the sRGB parameters + via VAProcColorStandardExplicit parameters. + +2020-02-07 11:25:31 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: filter: set vpp input/output color range + We've always sent VA_SOURCE_RANGE_UNKNOWN to the driver. + And, the [iHD] driver essentially computes the same color + range as gstreamer when we send VA_SOURCE_RANGE_UNKNOWN for + cases were gstreamer computes it automatically. But, + if the user wants to make it explicit, we should try + to honor it. + +2020-02-07 11:20:11 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + libs: utils: map GstVideoColorRange to VAAPI VPP + +2020-02-07 15:28:24 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: don't remove chroma-site nor colorimetry + Since now they can be handled by vaapipostproc. + +2020-02-04 14:17:43 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: use sink resolution to calculate src colorimetry + The default output colorimetry is persuaded by the output + resolution, which is too naive when doing VPP cropping + and/or scaling. For example, scaling 4K(sink)->1080P(src) + resolution (i.e. both YUV) results in bt2020(sink)->bt709(src) + colorimetry selection and some drivers don't support that + mode in vpp. + Thus, if output (i.e. downstream) does not specify a + colorimetry then we use the input resolution instead of the + output resolution to create the default colorimetry. Also, + note that we still use the output format since it may be a + different color space than the input. As in the example + above, this will result in bt2020(sink)->bt2020(src) + colorimetry selection and all drivers (afaik) should support + that in vpp. + +2020-02-04 09:57:42 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: set srcpad colorimetry unconditionally + We always need a srcpad colorimetry for VAAPI VPP + operations. + Also, check the return value of _set_colorimetry. + +2020-01-30 12:34:07 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: do not override explicit srcpad colorimetry + If colorimetry has been set by a capsfilter (e.g. + vaapipostproc ! video/x-raw,colorimetry=bt709) then + don't try to override it. Previously, the aforementioned + capsfilter will fail to negotiate if default colorimetry + is not the same as the capsfilter (e.g. 4K resolutions). + +2020-01-30 09:37:18 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: set vpp filter colorimetry + Set the input and output colorimetry for vpp filter. + +2020-01-30 09:34:10 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + libs: filter: support vpp input/output color standard + Add API function to allow setting the input and output vpp + color standard from GstVideoColorimetry. + +2020-02-04 11:32:54 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + libs: utils: map GstVideoColorimetry to VAAPI VPP + Fallback to VAProcColorStandardExplicit if there is no + 1:1 mapping. + +2020-02-04 10:27:23 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + libs: display: add vpp color standard quirk for i965 driver + The i965 does not properly report supported vpp color + standards. + +2020-02-02 18:04:35 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: dmabuf implies allocator + Some code can be optimized since only if the dmabuf allocator is set, + the internal flag of dmabuf is TRUE, thus there's no need to evaluate + the allocator address. + +2020-01-29 11:55:39 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: reject configuration if allocator isn't vaapi + If the requested allocator in set_config() is not a VAAPI valid one, + reject the configuration, instead of lying and using a private one. + This patch superseeds !254 and !24 + +2020-01-29 11:55:28 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: add explanation for allocator reconfig + +2020-01-29 11:54:38 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: check for vaapi meta first + If the configured meta doesn't request vaapi meta then it is not a + vaapi buffer pool. Bail out as soon as possible. + +2020-01-29 11:52:38 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: turn errors into warnings + set_config() vmethod should fail gracefully, thus upstream could + negotiate another pool if possible. + Instead of sending error messages to the bus, let demote the level + to warning. + +2020-01-29 11:51:47 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: log out vendor string when available + This is useful while asking for logs to know the used driver. + +2020-01-27 11:49:26 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface.c: + libs: surface: initialize VASurfaceAttribExternalBuffers + Initialize VASurfaceAttribExternalBuffers using compiler's syntax + rather than using memset(). + +2020-01-27 11:44:49 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface.c: + libs: surface: merge two loops into one + Merge two loops into one for setting offsets and strides in the + external buffer descriptor. + +2020-01-22 10:42:35 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurfacepool.c: + * gst-libs/gst/vaapi/gstvaapisurfacepool.h: + libs: surface: surfacepool: rename variable for clearity + In order to be readable, the meaningless 'flags' is renamed to + surface_allocation_flags, which is clearer. + +2020-01-27 18:40:46 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: Reuse internal allocator is possible. + Instead of creating a new allocator when upstream requests a different + allocator, this patch tries to reuse the internal allocator if it was + already initializated. + If the stream changes, then either one will be unref and a new + allocator is created. + +2020-01-27 18:05:14 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: Log messages in proper category. + The log messages where logged in the GstBufferPool category because + the instance was not properly casted. This fix that situation. + +2020-01-16 11:49:21 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst/vaapi/gstvaapipluginbase.c: + libs: display: driver quirks mechanism + This mechanism comes from ffmpeg vaapi implementation, where they have + their own quirks. + A specific driver is identified by a substring present in the vendor + string. If that substring is found, a set of bitwise flags are store. + These flags can be accessed through the function + gst_vaapi_display_has_driver_quirks(). + The purpose for this first quirks is to disable the put image try for + AMD Gallium driver (see [1]). + 1. https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/merge_requests/72 + +2020-01-15 23:07:29 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: renable Mesa Gallium driver + +2020-01-24 11:55:22 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: validate returned meta + Validate if the meta returned by gst_buffer_get_vaapi_video_meta() in + the acquired buffer is not null. + This situation should be very "pathological", but still it is better + be safe since that meta might be used later to create a new dma + buffer. + +2020-01-22 18:50:36 +0100 Philipp Zabel + + * gst/vaapi/gstvaapivideobufferpool.c: + vaapivideobufferpool: always update/release the underlying surface proxy + gst_vaapi_video_buffer_pool_reset_buffer() is called when the sink + releases the last reference on an exported DMA buffer. This should + release the underlying surface proxy. To avoid releasing the wrong + surface due to a stale surface proxy reference in the buffer's + GstVaapiVideoMeta, always update the reference to the correct surface + in gst_vaapi_video_buffer_pool_acquire_buffer(). + +2020-01-23 16:56:44 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + libs: context: select vaCreateSurfaces version according attributes + This commit tries to centralize the selection of vaCreateSurfaces + version, instead of having fallbacks everywhere. + These fallbacks are hacks, added because new drivers use the latest + version of vaCreateSurfaces (with surface attributes) [1], meanwhile + old drivers (or profiles as JPEG decoder in i965) might rather use the + old version. + In order to select which method, there's detected hack: each config + context has a list of valid formats, in the case of JPEG decoder the + list only contains "rare" 4:2:2 formats (ICM3, GRAY8) which aren't + handled correctly by the current gstreamer-vaapi code [2]. + The hack consist in identify if the format list contains an arbitrary + preferred format (which is suposedly well supported by + gstreamer-vaapi, mostly NV12). If no prefered colour format is found, + the the old version of vaCreateSurfaces is used, and the surfaces wil + be mapped into a image with their own color format. + 1. https://bugzilla.gnome.org/show_bug.cgi?id=797143 + 2. https://bugzilla.gnome.org/show_bug.cgi?id=797222 + +2020-01-21 19:35:02 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + libs: context: add debug category for context + +2020-01-22 20:20:30 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiblend.c: + libs: blend: guard VA_BLEND_GLOBAL_ALPHA + +2020-01-21 14:09:33 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: promote info to warning + Let's notify user about using constrained-baseline instead on + requested basline profile. + +2019-06-28 15:41:16 -0400 Nicolas Dufresne + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h264.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode_props.c: + * gst/vaapi/gstvaapidecode_props.h: + vaapih264dec: Add a property to assume constrained-baseline + When baseline-as-constrained is set, the decoder will expose support + for baseline decoding and assume that the baseline content is + constrained-baseline. This can be handy to decode streams in hardware + that would otherwise not be possible to decode. A lot of baseline + content is in fact constrained. + +2020-01-17 16:19:52 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapipluginutil.c: + vaapih264enc: accept baseline as constrained baseline compatible + +2020-01-17 14:24:37 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapih264enc: update level in src caps + And, if downstream requests a specific level, the caps are not + negotiated, because there is no mechanism right now to specify a + custom level in the internal encoder. + +2020-01-17 17:12:53 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: h264: document gst_vaapi_encoder_h264_supports_avc() + +2020-01-17 13:38:29 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapih264enc: force byte-stream if avc isn't supported + Removing the validation in gst_vaapiencode_h264_get_caps() since that + ought be handled in gst_vaapiencode_h264_set_config() + +2020-01-08 17:37:22 +0100 Philipp Zabel + + * gst/vaapi/gstvaapiencode_h264.c: + vaaph264enc: suppress avc if the driver does not support packed headers + Do not negotiate AVC output if the driver does not support it. + +2020-01-08 17:16:35 +0100 Philipp Zabel + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + libs: encoder: h264: Add gst_vaapi_encoder_h264_supports_avc() + AVC output requires packed header support in the driver. + +2020-01-17 13:07:04 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapih264enc: intersect the new proposed caps + Instead of just leave to keep the proposed caps, with the best profile + in the allowed caps, is its intersected again. + +2020-01-17 12:58:58 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapih264enc: propose new profile caps and fixate it + When the available caps doesn't intersect with the allowed caps in the + pipeline, a new caps is proposed rather than just expecting to + iterate. + Later, the intersected caps (profile_caps) is fixated in order to + extract the configuration. + +2020-01-17 13:18:28 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapih264enc: common fail for gst_vaapiencode_h264_set_config() + Add a common fail code path for gst_vaapiencode_h264_set_config(). + +2020-01-17 12:54:21 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: unref formats array if none + The formats array is always created, in order to keep the logic and + to avoid broken caps, if this formats array doesn't contain any + elements, it has to be unref and the function should return NULL. + +2020-01-17 14:22:48 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapih264enc: fix log message + Before the log wasn't processed because wrong instance pointer. + +2019-06-22 00:44:25 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst/vaapi/gstvaapiencode_h265.c: + plugin: encode: Add H265 main-444 profile. + Expose the main-444 profile to h265enc caps, when the upstream + chooses to use VUYA as input, we choose main 4:4:4 profile to encode + the frames. + +2020-01-15 19:36:00 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: Consider main-444 profile when encoding. + Add support of main-444 profile for parameter setting and packed header + generation. + +2020-01-15 23:04:08 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiprofilecaps.c: + * gst-libs/gst/vaapi/gstvaapiprofilecaps.h: + * gst/vaapi/gstvaapiencode.c: + vaapiencode: DMABuf only if PRIME is available + Add DMABuf capsfeature in encoders' allowed sinkcaps only if PRIME + memory type is available in the VA surface attributes of codec + context. + +2020-01-16 09:14:30 +0800 Haihao Xiang + + * hooks/pre-commit.hook: + Add hooks/pre-commit.hook + meson.build in gstreamer-vaapi requires hooks/pre-commit.hook + Copied and pasted pre-commit.hook from other gstreamer modules to make + sure gstreamer-vaapi follows the same code style + +2019-12-26 16:45:51 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: Set encoder paramters base on entrypoint. + When the tune is NONE, we now can choose entrypoint freely. So the + GST_VAAPI_ENCODER_TUNE macro may not return the correct current + entrypoint. + We also delay CTU size calculation after entrypoint has been decided. + +2019-12-28 19:18:12 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c: + * gst-libs/gst/vaapi/gstvaapicodedbufferproxy.h: + * gst-libs/gst/vaapi/gstvaapicodedbufferproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst-libs/gst/vaapi/gstvaapifei_objects.c: + * gst-libs/gst/vaapi/gstvaapifei_objects.h: + * gst-libs/gst/vaapi/gstvaapifei_objects_priv.h: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.h: + * gst-libs/gst/vaapi/gstvaapifeipak_h264.c: + * gst-libs/gst/vaapi/gstvaapifeipak_h264.h: + * gst-libs/gst/vaapi/gstvaapifeiutils_h264.c: + * gst-libs/gst/vaapi/gstvaapifeiutils_h264.h: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + * gst-libs/gst/vaapi/meson.build: + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264_fei.c: + * gst/vaapi/gstvaapiencode_h264_fei.h: + * gst/vaapi/gstvaapifeivideometa.c: + * gst/vaapi/gstvaapifeivideometa.h: + * gst/vaapi/meson.build: + * meson.build: + * tests/internal/meson.build: + * tests/internal/test-fei-enc-in.c: + * tests/internal/test-fei-enc-out.c: + Remove all FEI related + FEI encoders are not actively mantained neither tested, and it is + using infrastructure that is changing and FEI is stopping this + effort. + Also it is required to rethink how FEI can be used in GStreamer. + +2020-01-14 11:17:49 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapioverlay.c: + vaapioverlay: ensure sinkpad has current buffer + Use the gst_video_aggregator_pad_has_current_buffer API + to check if the current sinkpad has a queued buffer before + attempting to obtain a input buffer from the base plugin. + If the sinkpad does not have a current buffer, then it is + either not producing them yet (e.g. current time < sinkpad + start time) or it has reached EOS. + Previously, we only handled EOS case. + Example: + gst-launch-1.0 videotestsrc num-buffers=100 \ + ! vaapipostproc ! vaapioverlay name=overlay \ + ! vaapisink videotestsrc timestamp-offset=1000000000 \ + num-buffers=100 ! video/x-raw,width=160,height=120 \ + ! overlay. + +2020-01-14 18:57:31 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapioverlay.c: + vaapioverlay: unroll the recursive call + Recursive functions are elegant but dangerous since they might + overflow the stack. It is better to turn them into a list tranversal + if possible, as this case. + +2020-01-14 18:46:49 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiblend.c: + * gst/vaapi/gstvaapioverlay.c: + vaapioverlay: add minimal documentation + +2020-01-14 18:25:11 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiblend.c: + * gst-libs/gst/vaapi/gstvaapiblend.h: + * gst/vaapi/gstvaapioverlay.c: + libs: blend: simplify generator API + Instead of using a parent structure that has to be derived by API + consumers, this change propse a simplification by using the common + pattern of GTK of passing a function pointer and user data which will + be passed as its parameter. That user data contains the state and the + function will be called to update that state. + +2020-01-10 10:14:38 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiblend.c: + * gst-libs/gst/vaapi/gstvaapiblend.h: + libs: blend: remove begin/render/end API + This API was risky and is superseded by the surface + generator (process) API. + Resolves #219 + +2020-01-10 10:12:36 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapioverlay.c: + vaapioverlay: use blend surface generator API + See #219 + +2020-01-10 09:54:30 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiblend.c: + * gst-libs/gst/vaapi/gstvaapiblend.h: + libs: blend: add surface generator API + This new API allows the user to call a single method (process) + which handles the [display] lock/unlock logic internally for + them. + This API supersedes the risky begin, render, end API. + It eliminates the need for the user to call a lock method + (process_begin) before processing the input buffers + (process_render) and calling an unlock method (process_end) + afterwards. + See #219 + +2019-12-23 14:29:08 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + plugin: encode: List all possible profiles to detect input formats. + The current get_profile just return one possible profile for the encode, + which is not enough. For example, if we want to support HEVC 4:4:4 + profile, the input of encode should be VYUA rather than NV12 in HEVC + main profile. So the command line: + gst-launch-1.0 videotestsrc num-buffers=200 ! capsfilter \ + caps=video/x-raw,format=VUYA,width=800,height=600 ! vaapih265enc \ + tune=low-power init-qp=30 ! fakesink + can not work because vaapih265enc just report NV12 in sink caps, we need + to specify the profile obviously like: + gst-launch-1.0 videotestsrc num-buffers=200 ! capsfilter \ + caps=video/x-raw,format=VUYA,width=800,height=600 ! vaapih265enc \ + tune=low-power init-qp=30 ! capsfilter caps=video/x-h265, \ + profile=main-444 ! fakesink + The encode should have the ability to choose the profile based on input + format automatically. If the input video format is VUYA, the main-444 + profile should be auto choosed. + We modify to let get_allowed_profiles of each encode sub class to return + an array of all supported profiles based on downstream's allowed caps, or + return NULL if no valid profiles specified by downstream. + If no allowed profiles found, all profiles which belong to the current + encoder's codec will be the candidates. + The function gst_vaapi_encoder_get_surface_attributes collects the surface's + attributes for that profile list we just get. + So for this case, both NV12 and VUYA should be returned. + TODO: some codec like VP9, need to implement the get_profile() function. + +2020-01-08 15:07:36 +0800 He Junyan + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + plugin: util: add helper function to detect profiles in caps. + +2020-01-08 15:04:18 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + libs: encoder: add a helper function to get all supported profiles + +2020-01-13 15:34:54 +0900 Seungha Yang + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + libs: decoder: Don't unref null object + ** (gst-launch-1.0:9789): CRITICAL **: 15:29:09.330: + gst_vaapi_context_unref: assertion 'context != NULL' failed + +2020-01-10 09:26:44 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapioverlay.c: + plugins: overlay: use proper NULL check on double pointer + Check the address of the variable is not NULL, + not the address of the pointer. + +2020-01-08 23:42:21 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h: + libs: codedbuf: delete a useless field. + The context field in GstVaapiCodedBuffer is not inited correctly + and is never used, just delete it. + +2019-12-29 17:57:52 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + plugins: add iHD driver in whitelist + +2020-01-02 21:02:40 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: modify 265 SPS header's profile compatibility flag. + Make the SPS profile compatibility flags more precisely conform to + the HEVC Spec. + +2020-01-06 19:39:06 +0100 Víctor Manuel Jáquez Leal + + * tests/check/elements/vaapioverlay.c: + test: vaapioverlay: bail test if not available + vaapioverlay is only registered if the VA driver support the blend + operation. + This patch only executes the test if vaapioverlay is available, + otherwise the test is bail out without raising an error. + +2020-01-06 14:53:28 +0100 Víctor Manuel Jáquez Leal + + * tests/check/elements/vaapioverlay.c: + tests: vaapioverlay: force drm backend + +2019-12-22 17:32:19 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiblend.c: + libs: blend: update to new mini-object API + +2019-11-19 13:48:22 -0800 U. Artie Eoff + + * tests/check/elements/vaapioverlay.c: + * tests/check/meson.build: + tests: check: add basic vaapioverlay test + Add test_overlay_position test to verify sink_1 input + is overlayed onto sink_0 input at the appropriate + position. + +2019-11-14 12:03:57 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapioverlay.c: + * gst/vaapi/gstvaapioverlay.h: + * gst/vaapi/meson.build: + plugins: add vaapioverlay plugin + A plugin similar to the base compositor element but + uses VA-API VPP blend functions to accelerate the + overlay/compositing. + Simple example: + gst-launch-1.0 -vf videotestsrc ! vaapipostproc \ + ! tee name=testsrc ! queue \ + ! vaapioverlay sink_1::xpos=300 sink_1::alpha=0.75 \ + name=overlay ! vaapisink testsrc. ! queue ! overlay. + +2019-11-14 12:02:19 -0800 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiblend.c: + * gst-libs/gst/vaapi/gstvaapiblend.h: + * gst-libs/gst/vaapi/meson.build: + libs: add a vaapi blend class + Support for the VA-API VPP blend functions. + +2019-11-14 11:54:59 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: base: add GstVideoAggregator subclass support + +2020-01-05 19:32:16 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiimage.c: + libs: image: init all image fields correctly. + +2020-01-06 17:41:53 +0100 Stéphane Cerveau + + * gst/vaapi/gstvaapipostproc.c: + doc: fix pipeline typo in vaapipostproc + +2020-01-02 21:11:44 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: modify 265 VPS header fields. + vps_base_layer_internal_flag and vps_base_layer_available_flag + have been clearly defined now. + +2020-01-01 19:54:13 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidisplay_x11.c: + libs: display: fix a resource leak in X11 pixmap format. + +2020-01-02 18:00:21 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiprofilecaps.c: + * gst-libs/gst/vaapi/gstvaapiprofilecaps.h: + libs: utils: delete useless gst_vaapi_profile_caps_append_encoder. + +2019-12-30 14:09:17 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst/vaapi/gstvaapiencode.c: + libs: encoder: get surfaces resolution the same time with formats. + We can get all the information about the video format at one shot + when we create the test context for getting the supported formats. + The current way to get the width and height ranges are inefficient, + since it calls the function gst_vaapi_profile_caps_append_encoder() + and it creates another temporal context to detect the resolution + information. + Signed-off-by: Víctor Manuel Jáquez Leal + +2019-12-28 17:42:55 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: vp9: fix code style + +2019-12-16 23:19:46 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: set entrypoint based on tune automatically + Some profile, such as H265_MAIN_444 on new Intel platform, may only + support ENTRYPOINT_SLICE_ENCODE_LP entrypoint. This leads two + problems: + 1. We need to specify the tune mode like `vaapih265enc tune=low-power` + every time when we need to use this kind of profile. Or we can not + create the encoder context successfully. + 2. More seriously, we set the entrypoint to a fixed value in + init_context_info() and so the create_test_context_config() can not + create the test context for these profile and can not get the + supported video formats, either. + We now change the entrypoint setting based on the tune option of the + encoder. If no tune property provided, we just choose the first + available entrypoint. + +2019-12-16 23:19:46 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: set context info profile by encoder + Instead of init_context_info() setting the passed profile, it is + assumed that it has to be set by each encoder. + Signed-off-by: Víctor Manuel Jáquez Leal + +2019-12-27 18:49:02 +0100 He Junyan + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + libs: context: add invalid entrypoint symbol + The symbol GST_VAAPI_ENTRYPOINT_INVALID is just a representation of + zero, which was already used as an invalid value tacitly. This patch + only makes it explicit. + Signed-off-by: Víctor Manuel Jáquez Leal + +2019-12-29 01:13:29 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapipixmap_x11.c: + libs: pixmap: Fix a pixmap creation crash. + We use GST_VAAPI_OBJECT_NATIVE_DISPLAY with wrong parameter for x11 + pixmap creation, which causes crash if we run the internal test case + of: + test-decode --pixmap + +2019-12-22 14:35:18 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.c: + plugin: encode: set allowed_sinkpad_caps to empty. + We now set encode->allowed_sinkpad_caps to NULL if we fail to get + surfaces formats. This causes two problem: + 1. gst_video_encoder_proxy_getcaps use NULL as its caps parameter, + which changes its behavior. It will use encode's sinkpad template + rather than empty caps to do the clip job. So even if we fail to set + allowed_sinkpad_caps, gst_video_encoder_proxy_getcaps can still return + valid caps. + 2. We should just set the allowed_sinkpad_caps once. The NULL point + make the ensure_allowed_sinkpad_caps function works again and again. + +2019-12-22 15:22:57 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: Add NULL pointer check for context when finalize. + Context may be NULL if pipeline fail in early stage, and the + ensure_context will not be called. Need to add a pointer protection + for it. + +2019-12-20 06:38:42 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapipluginbase.c: + plugins: base: do not reset can_dmabuf + Don't reset the can_dmabuf field. This restores the + close/reset logic that existed prior to commit + ca2942176b5632e07eebac23336954f9aaf1cb26 in regards to + dmabuf support. + Plugins only call gst_vaapi_plugin_base_set_srcpad_can_dmabuf + once during startup, but may need to reset the other private + fields multiple times during negotiation. Thus, can_dmabuf + should be exempt from the resets. + Fixes #208 + +2019-12-06 00:21:12 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.c: + plugin: encode: Refine encode's sink caps. + The old manner to get the encode's sink caps is not correct. + Such as 264 encode, it gets: + video/x-raw(memory:VASurface), + format=(string){ ENCODED, NV12, I420, YV12, YUY2, UYVY, Y210, + P010_10LE, AYUV, Y410, Y444 }, width=(int)[ 32, 4096 ], + height=(int)[ 32, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; + video/x-raw(memory:DMABuf), format=(string){ I420, YV12, RGBA }, + width=(int)[ 32, 4096 ], height=(int)[ 32, 4096 ], + framerate=(fraction)[ 0/1, 2147483647/1 ]; + video/x-raw, format=(string){ NV12 }, width=(int)[ 32, 4096 ], + height=(int)[ 32, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ] + where the formats for memory:VASurface and memory:DMABuf are superfluous. + All the "I420, YV12, YUY2, UYVY, Y210, RGBA" can not be really used as + input format for encoder. + We should get: + video/x-raw, format=(string){ NV12 }, width=(int)[ 32, 4096 ], + height=(int)[ 32, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; + video/x-raw(memory:VASurface), format=(string){ NV12 }, + width=(int)[ 32, 4096 ], height=(int)[ 32, 4096 ], + framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(memory:DMABuf), + format=(string){ NV12 }, width=(int)[ 32, 4096 ], + height=(int)[ 32, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ] + as the correct result. + +2019-12-20 08:37:11 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + libs: display: code clean up + +2019-12-12 21:34:21 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay_priv.h: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + libs: display: refine the profile/entrypoint map. + The old way make the one config for each profile/entrypoint pair, + which is not very convenient for description the relationship + between them. One profile may contain more than one entrypoints + to within it, so a set like data structure should be more suitable. + +2019-12-19 14:19:10 +0100 He Junyan + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapipixmap_x11.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + * gst-libs/gst/vaapi/gstvaapisurface_egl.c: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy.c: + * gst-libs/gst/vaapi/gstvaapisurfaceproxy_priv.h: + * gst-libs/gst/vaapi/gstvaapitexture_egl.c: + * gst-libs/gst/vaapi/gstvaapitexture_glx.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideometa.c: + * gst/vaapi/gstvaapivideometa_texture.c: + * tests/internal/image.c: + * tests/internal/test-filter.c: + * tests/internal/test-surfaces.c: + * tests/internal/test-windows.c: + libs: surface: port to GstMiniObject + GstVaapiMiniObject and GstVaapiObject are deprecated. + This is the first step to remove them by porting GstVaapiSurface as + a GstMiniBuffer descendant. + Signed-off-by: Víctor Manuel Jáquez Leal + +2019-12-19 18:26:10 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface.c: + libs: surface: rename create function names to init + There are several internal functions with 'create' name, but they + don't create any new structure, but rather it initializes that + structure. Renaming those function to reflect better their purpose. + +2019-12-19 14:17:34 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface.c: + libs: surface: use macro accessors + +2019-12-19 13:46:09 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + libs: surface: fix internal documentation + +2019-12-18 18:00:49 +0100 He Junyan + + * gst-libs/gst/vaapi/gstvaapicodedbuffer.c: + * gst-libs/gst/vaapi/gstvaapicodedbuffer.h: + * gst-libs/gst/vaapi/gstvaapicodedbuffer_priv.h: + * gst-libs/gst/vaapi/gstvaapicodedbufferproxy.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + * gst-libs/gst/vaapi/gstvaapifeipak_h264.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + libs: codedbuffer: port to GstMiniObject + GstVaapiMiniObject and GstVaapiObject are deprecated. + This is the first step to remove them by porting GstVaapiCodedBuffer + as a GstMiniBuffer descendant. + Signed-off-by: Víctor Manuel Jáquez Leal + +2019-12-18 12:57:01 +0100 He Junyan + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/gstvaapiimage.h: + * gst-libs/gst/vaapi/gstvaapiimage_priv.h: + * gst-libs/gst/vaapi/gstvaapisubpicture.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + * gst-libs/gst/vaapi/gstvaapivideopool.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideometa.c: + * tests/internal/image.c: + * tests/internal/simple-encoder.c: + * tests/internal/test-fei-enc-in.c: + * tests/internal/test-filter.c: + * tests/internal/test-windows.c: + libs: image: port to GstMiniObject base class + GstVaapiMiniObject and GstVaapiObject are deprecrated. This is the + first step to remove them, by porting GstVaapiImage as a + GstMiniObject. + Signed-off-by: Víctor Manuel Jáquez Leal + +2019-09-24 01:01:22 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapicodedbuffer.c: + * gst-libs/gst/vaapi/gstvaapicodedbufferpool.c: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiprofilecaps.c: + libs: context: port to a plain C structure + The GstVaapiMiniObject is obsolete and we need to replace it. This + patch turns GstVaapiContext into a plain C structure with its own + reference counting mechanism. + Also this patch removes unused overlays attributes. + Signed-off-by: Víctor Manuel Jáquez Leal + +2019-12-18 00:40:58 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264_fei.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiencode_vp9.c: + plugin: encode: change the dmabuf caps to all supported formats. + The encode's dmabuf caps definition is obsolete, it can support + more formats now. Re-define it to include all supported formats + in video format map. + +2019-12-17 17:09:37 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + libs: encoder: h264fei: remove unnecessary check + Issue detected by Coverity + `info_to_pack.h264_slice_header` is always allocated by + gst_vaapi_feipak_h264_encode(), thus checking it to free it afterwards + in doesn't make much sense. But it requires to be free on the error + path. + There may be a null pointer dereference, or else the comparison + against null is unnecessary. + In gst_vaapi_encoder_h264_fei_encode: All paths that lead to this null + pointer comparison already dereference the pointer earlier + +2019-12-17 17:05:22 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + libs: encoder: h264fei: remove unnecessary assert + Issue detected by Coverity + An unsigned value can never be negative, so this test will always + evaluate the same way. + In add_slice_headers: An unsigned value can never be less than 0 + +2019-12-17 16:57:41 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + libs: encoder: h264fei: remove unnecessary check + Issue detected by Coverity + There may be a null pointer dereference, or else the comparison + against null is unnecessary. + In gst_vaapi_encoder_h264_fei_encode: All paths that lead to this null + pointer comparison already dereference the pointer earlier + +2019-12-17 16:49:47 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + libs: encoder: h264fei: don't free memory on stack + Issue detected by Coverity + `info_to_pak` variable in gst_vaapi_encoder_h264_fei_encode() is + declared in the stack, but it is free in + gst_vaapi_feienc_h264_encode() as if declared on the heap. + This patch initializes the structure and removes the free. + A non-heap pointer is placed on the free list, likely causing a crash + later. + In gst_vaapi_encoder_h264_fei_encode: Free of an address-of + expression, which can never be heap allocated. + +2019-12-17 13:22:12 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + libs: encoder: h264fei: fix surface leak + Issue detected by Coverity + If the FEI mode is not handled the created resources should be + released and return and error code. + The system resource will not be reclaimed and reused, reducing the + future availability of the resource. + In gst_vaapi_encoder_h264_fei_encode: Leak of memory or pointers to + system resources + +2019-12-17 13:09:58 +0100 Víctor Manuel Jáquez Leal + + * tests/check/elements/vaapipostproc.c: + tests: check return calling of gst_navigation_event_parse.* + This issue was detected by Coverity. + If the function returns an error value, the error value may be mistaken + for a normal value. + In cb_mouse_event: Value returned from a function is not checked for + errors before being used + +2019-12-16 16:25:02 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264_fei.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiencode_vp9.c: + plugin: encode: set sink's raw caps to GST_VAAPI_FORMATS_ALL. + Then encode plugin just supports raw formats declared in vaapi video + format map. This modification makes the template caps more precise. + +2019-11-14 11:13:51 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapipluginbase.c: + plugins: base: add GstPad param to internal helper functions + The base plugin public API function implementations determine + which pad should be passed to the internal helper functions. + Currently, only the base plugin static sinkpad and static + srcpad are supported/used. However, this change enables future + API functions to be added that can accept a pad (i.e. request pad) + from an element subclass (e.g. a GstVideoAggregator subclass). + +2019-11-12 12:21:52 -0800 U. Artie Eoff + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: base: manage pad-specific data in a single struct + Define a struct (GstVaapiPadPrivate) to encapsulate the + pad-specific data (i.e. buffer pool, allocator, info, + caps, etc.). + Add an interface to retrieve the data struct for a given + pad. + Finally, update the base plugin to use the data struct + throughout the implementation. + This will enable us to easily extend the base plugin in the + future to allow for N-to-1 pad subclasses (e.g. overlay/ + composite). + +2019-10-29 15:13:44 -0700 U. Artie Eoff + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapipluginbase.h: + * gst/vaapi/gstvaapipostproc.c: + plugins: use plugin base macros to access pad specific data + Don't access base struct fields directly since the underlying + definition can change. Instead, use the accessor macros. + +2019-12-03 00:52:45 +0800 He Junyan + + * gst/vaapi/gstvaapidecode.c: + libs: decoder: Modify decode src's template raw formats + We do not need to maintain a standalone list of decoder's output + template for raw formats and that is easy to make mistake(for + example, the AYVU is wrong in that list, should be VUYA). + Just use GST_VAAPI_FORMATS_ALL to replace the raw formats list for + src template. + +2019-12-11 14:11:13 +0800 He Junyan + + * gst/vaapi/gstvaapipostproc.c: + libs: postproc: Modify src/sink template raw formats + We need to provide more precise template caps for postproc's src + and sink pads. The GST_VIDEO_FORMATS_ALL make all video formats + available which are really superfluous. + +2019-12-10 18:40:42 -0300 Thibault Saunier + + * tests/check/elements/vaapipostproc.c: + Do not mix declaration and code + +2019-11-03 17:59:01 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h265: skip all pictures prior the first I-frame + Don't try to decode until the first I-frame is received within the + currently active sequence. i965 H265 decoder don't show any artifact + but it crashes. + Fixes: #98 + +2019-11-27 01:44:05 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/video-format.c: + libs: video-format: remove dead code + +2019-10-31 00:59:34 +0800 He Junyan + + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + * gst/vaapi/gstvaapipluginutil.h: + libs: video-format: add GST_VAAPI_FORMATS_ALL + GST_VAAPI_FORMATS_ALL collects all declared formats in video-format + as a caps template string, and make them available in caps with + memory:VASurface feature. + Fixes: #199 + +2019-11-06 22:37:12 +0800 He Junyan + + * gst-libs/gst/vaapi/video-format.c: + * tests/internal/test-windows.c: + libs: video-format: change GST_VIDEO_FORMAT_AYUV to VUYA. + We only support VUYA format in gst vaapi now, need to correct + the mapping. + +2019-10-09 15:13:09 -0700 U. Artie Eoff + + * tests/check/elements/vaapipostproc.c: + tests: check: vaapipostproc test_orientation_mouse_events + Test that vaapipostproc properly translates mouse events + when using video-direction (orientation). + +2019-10-09 10:11:54 -0700 U. Artie Eoff + + * tests/check/elements/vaapipostproc.c: + * tests/check/meson.build: + tests: check: vaapipostproc test_crop_mouse_events + Test that vaapipostproc properly translates mouse events + when cropping. + +2019-10-08 12:20:26 -0700 U. Artie Eoff + + * meson.build: + * meson_options.txt: + * tests/check/elements/vaapipostproc.c: + * tests/check/meson.build: + * tests/meson.build: + tests: check: initial unit test support + Add minimal unit test toolchain files and a simple + vaapipostproc unit test. + +2019-10-08 12:19:06 -0700 U. Artie Eoff + + * meson.build: + * tests/examples/meson.build: + * tests/examples/test-roi.c: + * tests/examples/test-vaapicontext.c: + * tests/examples/test-vaapipostproc.c: + * tests/examples/test-vaapisink.c: + * tests/internal/codec.c: + * tests/internal/codec.h: + * tests/internal/decoder.c: + * tests/internal/decoder.h: + * tests/internal/image.c: + * tests/internal/image.h: + * tests/internal/meson.build: + * tests/internal/output.c: + * tests/internal/output.h: + * tests/internal/simple-decoder.c: + * tests/internal/simple-encoder.c: + * tests/internal/test-decode.c: + * tests/internal/test-decode.h: + * tests/internal/test-display.c: + * tests/internal/test-fei-enc-in.c: + * tests/internal/test-fei-enc-out.c: + * tests/internal/test-filter.c: + * tests/internal/test-h264.c: + * tests/internal/test-h264.h: + * tests/internal/test-jpeg.c: + * tests/internal/test-jpeg.h: + * tests/internal/test-mpeg2.c: + * tests/internal/test-mpeg2.h: + * tests/internal/test-mpeg4.c: + * tests/internal/test-mpeg4.h: + * tests/internal/test-subpicture-data.c: + * tests/internal/test-subpicture-data.h: + * tests/internal/test-subpicture.c: + * tests/internal/test-surfaces.c: + * tests/internal/test-textures.c: + * tests/internal/test-vc1.c: + * tests/internal/test-vc1.h: + * tests/internal/test-windows.c: + * tests/internal/y4mreader.c: + * tests/internal/y4mreader.h: + * tests/meson.build: + tests: move examples and tests to subfolders + This makes way for adding unit (check) tests. + +2019-10-14 01:01:27 +0100 Tim-Philipp Müller + + * .gitmodules: + * Makefile.am: + * autogen.sh: + * common: + * configure.ac: + * git.mk: + * gst-libs/Makefile.am: + * gst-libs/gst/Makefile.am: + * gst-libs/gst/vaapi/Makefile.am: + * gst/Makefile.am: + * gst/vaapi/Makefile.am: + * m4/Makefile.am: + * tests/Makefile.am: + * tests/elements/Makefile.am: + Remove autotools build + +2019-10-10 15:26:36 -0700 U. Artie Eoff + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix off-by-one coord translations + When translating navigation x,y coordinates for + video-direction, it is necessary to subtract 1 + when using the video dimensions to compute the + new x,y coordinates. That is, a 100x200 image + should map coordinates in x=[0-99],y=[0-199]. + This issue was found with unit tests provided + in !182. + +2019-10-11 17:34:06 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + libs: window: x11: Avoid usage of deprecated API + +2019-10-11 17:13:34 +0200 Víctor Manuel Jáquez Leal + + * meson.build: + build: halt meson configuration if no renderer API + We should halt meson configuration if there is no render API + installed (either DRM, Wayland or X11). + That behavior was already in autotools but missed in meson. This patch + brings it back. + Fixes: #196 + +2019-10-09 12:12:18 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: filter: fix default orientation regression + Fix regression introduced in f232f87f7082 + +2019-10-07 11:53:23 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: filter: use OP_DATA_DEFAULT_VALUE macro + +2019-10-07 11:39:19 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: filter: use macro for returning op default value + The code is essentially the same for getting all op default + values. Thus, use a macro to help minimize code duplication + and [hopefully] encourage using the same mechanism for all + default getters. + +2019-10-07 09:56:37 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: filter: query param spec for default scale method + Related: #159 + +2019-10-07 09:44:06 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: filter: query param spec for default skin-tone values + Related: #159 + +2019-10-02 12:54:52 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: filter: query param spec for default video-direction + Related: #159 + +2019-10-07 10:23:09 -0700 U. Artie Eoff + + * .gitignore: + add .gitignore + +2019-09-05 16:40:52 +0800 Yan Wang + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: Use level value for skin-tone-enhancement filter. + Currently the parameter of skin-tone-enhancement filter is forced + to zero. In fact it could be set different value by the user. + So create a new property named as "skin-tone-enhancement-level" + for accepting the used defined parameter value. + At the same time, skin-tone-enhancement is marked as deprecated. + When skin-tone-enhancement-level is set, skin-tone-enhancement + will be ignored. + +2019-09-21 13:39:42 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h264, h266: fix g_return_val_if_fail() missuse + g_return_val_fail() documentations says: + If expr evaluates to FALSE, the current function should be + considered to have undefined behaviour (a programmer error). + The only correct solution to such an error is to change the + module that is calling the current function, so that it avoids + this incorrect call. + So it was missused in a couple parts of the H264 and H265 internal + decoders. This patch changes that to plain conditionals. + Also, it was included a couple code-style fixes. + +2019-09-23 19:52:20 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * tests/simple-encoder.c: + * tests/test-fei-enc-in.c: + libs: encoder: remove gst_vaapi_encoder_{ref,unref}() + Since GstVaapiEncoder is a descendant of of GstObject, there is no + need to keep a custom ref()/unref() methods. This patch deletes them. + +2019-09-24 01:03:02 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: correct encoder's ref/unref function. + GstVaapiEncoder now is a standard gstobject and need to use + gst_object_ref/unref functions. + +2019-09-19 12:09:20 -0700 U. Artie Eoff + + * gst/vaapi/gstvaapiencode_h264_fei.c: + gst: encode: h264_fei: remove useless comparison + The expression "len >= 0" is always true since "len" + is an unsigned type. And it is clear that the writers + intention was not to write "len > 0" since we handle + len == 0 in the ensuing "if (len < 3)" conditional + block. + +2019-09-19 11:17:24 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + libs: encoder: h264_fei: fix potential overflow before widen + Found by static analysis. encoder->mb_width * encoder->mb_height + is evaluated using 32-bit arithmetic before widen. Thus, cast + at least one of these to guint64 to avoid overflow. + +2019-09-19 10:56:13 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + libs: encoder: h264_fei: remove dead error condition + Found by static analysis. The feipak is always null + when we reach the error target. + +2019-09-19 10:49:11 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: add missing break in switch + +2019-09-11 11:56:35 +0800 He Junyan + + * gst-libs/gst/vaapi/video-format.c: + libs: video-format: Make all YUV format available + The YUV formats have no ambiguity for drivers, so we can add them all. + Some old driver(i965) does not implement full get/put image functions + but can use derive image funtions for the YUV format. It does not + report that kind of formats correctly in image query, but will derive + that YUV format image from surface. The dynamic mapping of YUV format + will block that manner. + Adding more YUV format mapping has no side effect. So considering the + legacy driver conformance, we add all YUV formats mapping statically + and dynamic mapping RBG formats + Fix: #189 + Fix: #190 + +2019-09-18 15:30:03 +1000 Matthew Waters + + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.h: + egl: Fix racyness in display thread creation + Multiple different scenarios could break the display thread creation and + end up blocking waiting for thread o be created. Fix them all by + correctly waiting for a new boolean to become valid. + +2019-09-18 15:29:03 +1000 Matthew Waters + + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + egl: don't advertise a wrapped EGLContext as actually wrapped + It's not actually wrapped as we create a new EGLContext from the passed + in EGLContext. As a result, the created EGLContext was never destroyed. + +2019-09-16 23:28:31 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + libs: h264decoder: do not return error for unhandled NAL unit. + Some streams have error data introducing unknown NAL type. There are + also kinds of NAL types we do not want to handle. The old manner will + set a decoder error when encounter this, which cause a latent crash bug. + The decoder may successfully decode the picture and insert it into DPB. + But there are error NAL units after the AU which cause the post unit error + and make that frame dropped. The later output of the picture still want + to ref that frame and crash. + No need to set decoder error when can not recognize or handle the NAL + unit, just skip it and continue. + Fix: #191 + +2019-09-11 14:32:22 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + * gst/vaapi/gstvaapiencode.c: + libs: encoders: use GST_PARAM_USER_SHIFT to define internal params + This patch makes use of GST_PARAM_USER_SHIFT to define the internal + param in encoders to decide which parameters to expose. Thus + gstreamer-vaapi will not interfere with any change in GStreamer in the + future. + Also, the internal symbol was change to + GST_VAAPI_PARAM_ENCODER_EXPOSURE to keep the namespacing. + +2019-09-09 18:06:51 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/video-format.c: + libs: Add BGR10A2_LE support for color space conversion. + Fix: #179 + +2019-08-23 14:41:06 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapisurface.c: + libs: surface: add pointer check for surface_new_from_formats. + The command line: + gst-launch-1.0 filesrc location=some_name.mjpeg ! jpegparse ! + vaapijpegdec ! videoconvert ! video/x-raw,format=I420 ! vaapisink + will crash on i965 driver because of no pointer check. + We now generate the video format map between GST format and VA format + dynamically based on the image format returned by vaQueryImageFormats. + i965 driver does to report image format of 444P and Y800 forcc, while + the jpeg decoder context VASurfaceAttribPixelFormat use them. We can + not recognize these format and pass a NULL pointer to + gst_vaapi_surface_new_from_formats. + We need to add a pointer check here and let the fallback logic handle + this case correctly. + Other drivers work well. + +2019-09-07 13:23:01 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: guard the VAEntrypointFEI symbol + VAEntrypointFEI appeared in libva 2.0.0 (API version 1.0.0) + +2019-09-05 14:48:22 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + libs: video-format: Refine the video format mapping. + Improve the mapping between va format and gst format. The new map + will be generated dynamically, based on the query result of image + format in VA driver. Also consider the ambiguity of RGB color + format in LSB mode. + +2019-04-15 16:51:26 +0100 Philippe Normand + + * gst/vaapi/gstvaapipluginutil.c: + pluginutil: Remove Mesa from drivers white list + The Mesa Gallium driver is poorly tested currently, leading to bad user + experience for AMD users. The driver can be added back to the white list at + runtime using the GST_VAAPI_ALL_DRIVERS environment variable. + +2019-07-08 14:18:00 -0700 U. Artie Eoff + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: allow cropping via properties + Add crop-left, crop-right, crop-top and crop-bottom + properties to vaapipostproc. + +2019-08-30 17:31:45 -0700 U. Artie Eoff + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: rotate outbuf and crop meta if forwarding + When forwarding crop meta to downstream, the output + buffer and crop meta need to be rotated, too. + Test: + for i in 90r 180 90l vert horiz ul-lr ur-ll + do + gst-launch-1.0 -vf videotestsrc num-buffers=500 \ + ! videocrop top=100 bottom=30 left=40 right=20 \ + ! vaapipostproc video-direction=$i \ + ! vaapisink & \ + gst-launch-1.0 -vf videotestsrc num-buffers=500 \ + ! videocrop top=100 bottom=30 left=40 right=20 \ + ! vaapipostproc video-direction=$i \ + ! identity drop-allocation=true \ + ! vaapisink + done + +2019-08-30 14:14:30 -0700 U. Artie Eoff + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: fix output buffer WxH for crop meta forwarding + Adding crop meta x,y to w,h only compensates for left,top + cropping. But we also need to compensate for right,bottom + cropping. + The video meta contains the appropriate w,h (uncropped) + values, so use it instead. + Test: + gst-launch-1.0 -vf videotestsrc num-buffers=500 \ + ! videocrop top=50 bottom=30 left=40 right=20 \ + ! vaapipostproc ! vaapisink & \ + gst-launch-1.0 -vf videotestsrc num-buffers=500 \ + ! videocrop top=50 bottom=30 left=40 right=20 \ + ! vaapipostproc ! identity drop-allocation=1 \ + ! vaapisink + +2019-09-04 10:52:51 -0700 U. Artie Eoff + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: handle size and direction together in src events + Mapping a pointer event needs to consider both size and + video-direction operations together, not just one or the other. + This fixes an issue where x,y were not being mapped correctly + for 90r, 90l, ur-ll and ul-lr video-direction. In these directions, + the WxH are swapped and GST_VAAPI_POSTPROC_FLAG_SIZE is set. Thus, + the first condition in the pointer event handling was entered and + x,y scale factor were incorrectly computed due to srcpad WxH + swap. + This also fixes all cases where both video-direction and scaling + are enabled at the same time. + Test that all pointer events map appropriately: + for i in `seq 0 7` + do + GST_DEBUG=vaapipostproc:5 gst-launch-1.0 -vf videotestsrc \ + ! vaapipostproc video-direction=${i} width=300 \ + ! vaapisink + GST_DEBUG=vaapipostproc:5 gst-launch-1.0 -vf videotestsrc \ + ! vaapipostproc video-direction=${i} width=300 height=200 \ + ! vaapisink + GST_DEBUG=vaapipostproc:5 gst-launch-1.0 -vf videotestsrc \ + ! vaapipostproc video-direction=${i} height=200 \ + ! vaapisink + GST_DEBUG=vaapipostproc:5 gst-launch-1.0 -vf videotestsrc \ + ! vaapipostproc video-direction=${i} \ + ! vaapisink + done + +2019-08-20 14:22:57 -0700 U. Artie Eoff + + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: advertise crop meta is handled + Advertise to upstream that vaapipostproc can handle + crop meta. + When used in conjunction with videocrop plugin, the + videocrop plugin will only do in-place transform on the + crop meta when vaapipostproc advertises the ability to + handle it. This allows vaapipostproc to apply the crop + meta on the output buffer using vaapi acceleration. + Without this advertisement, the videocrop plugin will + crop the output buffer directly via software methods, + which is not what we desire. + vaapipostproc will not apply the crop meta if downstream + advertises crop meta handling; vaapipostproc will just + forward the crop meta to downstream. If crop meta is + not advertised by downstream, then vaapipostproc will + apply the crop meta. + Examples: + 1. vaapipostproc will forward crop meta to vaapisink + gst-launch-1.0 videotestsrc \ + ! videocrop left=10 \ + ! vaapipostproc \ + ! vaapisink + 2. vaapipostproc will do the cropping + gst-launch-1.0 videotestsrc \ + ! videocrop left=10 \ + ! vaapipostproc \ + ! identity drop-allocation=1 \ + ! vaapisink + +2019-08-29 18:44:36 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: clean two virtual func in encoder class + set_property and get_default_properties functions are no longer + needed for encoder class. + +2019-08-29 18:43:30 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.h: + libs: encoder: delete old set_property and property enum feienc264 + +2019-08-29 18:39:27 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h: + libs: encoder: delete old set_property and property enum in h264 fei + +2019-08-29 18:37:58 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.h: + libs: encoder: delete old set_property and property enum in vp9 + +2019-08-29 18:36:51 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.h: + libs: encoder: delete old set_property and property enum in vp8 + +2019-08-29 18:35:59 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + libs: encoder: delete old set_property and property enum in mpeg2 + +2019-08-29 18:34:57 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h: + libs: encoder: delete old set_property and property enum in jpeg + +2019-08-29 18:31:56 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + libs: encoder: delete old set_property and property enum in h265 + +2019-08-29 18:30:07 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + libs: encoder: delete old set_property and property enum in h264 + +2019-08-29 18:17:42 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: delete EncoderPropInfo related functions + +2019-08-29 16:13:19 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + libs: encoder: delete encoder_set_property + We no longer need this obsolete set_property function now after + switch to standard gobject's property manner. + Also delete the old encoder's property enum in the header file. + +2019-08-29 15:59:43 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: delete properties_get_default for base class + +2019-08-29 15:52:04 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + plugin: encode: delete useless init_properties. + Also delete the get_properties function in encode class. We now + use g_object_class_list_properties to get all properties for + internal encoder class. + +2019-08-29 15:43:45 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + plugin: encode: delete set/get_property func in encode class + Use standard gobject's property functions to replace the old way. + +2019-08-29 15:31:16 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + plugin: encode: delete gst_vaapiencode_init_properties + No need to init the properties got by get_default_properties func + now. The properties are inited correctly in internal encoder class. + +2019-08-29 15:19:10 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: delete 3 useless init macro + +2019-08-29 15:16:26 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.h: + libs: encoder: delete get_default_properties of feienc + +2019-08-29 15:14:14 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h: + libs: encoder: delete get_default_properties of H264 Fei + +2019-08-29 15:07:17 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.h: + libs: encoder: delete get_default_properties of VP9 + +2019-08-29 15:06:25 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.h: + libs: encoder: delete get_default_properties of VP8 + +2019-08-29 15:03:52 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + libs: encoder: delete get_default_properties of MPEG2 + +2019-08-29 15:03:19 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h: + libs: encoder: delete get_default_properties of JPEG + +2019-08-30 19:15:38 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + libs: encoder: delete get_default_properties of H265 + +2019-08-29 14:59:12 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + libs: encoder: delete get_default_properties of H264 + +2019-08-29 14:53:59 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: delete the useless constructed func for encoder. + +2019-08-26 23:16:33 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + libs: encoder: implement get_view_ids for h264 encoder. + +2019-08-20 23:56:33 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264_fei.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiencode_vp9.c: + gst: encode: enable new type of property mechanism. + +2019-08-20 22:16:35 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode.h: + gst: encode: add property help functions for encoder properties. + The encoder is a true gstobject now and all the properties are using + gobject's properties mechanism. Add help functions to handle the properties + between encode and encoder class. + The basic idea is mapping the same property between encoder and encode. All + the encoder's properties will have the same name, the same type in encode. + The set/get property function just forward the property setting/getting to + the encoder using the same property name and value. Because the encoder is + created on needed, we need to cache the property setting in encode. + +2019-08-30 18:39:32 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + libs: encoder: add flags to all encoder properties. + G_PARAM_CONSTRUCT make all properties init correctly, we do not + need to init the properties manually. + G_PARAM_FLAG_VAAPI_ENCODER_EXPOSURE is a vaapi encoder specific + flag, means need to expose the property to according encode class. + +2019-08-20 17:00:39 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + libs: encoder: Add properties for h264 encoder fei. + Install properties for h264 encoder fei class. Also set the new get/set + property functions for gobject class. Still use the old properties + way now and this new feature will be enabled later. + +2019-08-20 15:58:30 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + libs: encoder: Add properties for h264 fei encoder. + Install properties for h264 fei encoder class. Also set the new get/set + property functions for gobject class. Still use the old properties + way now and this new feature will be enabled later. + +2019-08-20 15:29:27 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: Add properties for vp9 encoder. + Install properties for vp9 encoder class. Also set the new get/set + property functions for gobject class. Still use the old properties + way now and this new feature will be enabled later. + +2019-08-20 15:01:02 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + libs: encoder: Add properties for vp8 encoder. + Install properties for vp8 encoder class. Also set the new get/set + property functions for gobject class. Still use the old properties + way now and this new feature will be enabled later. + +2019-08-20 14:31:58 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + libs: encoder: Add properties for mpeg2 encoder. + Install properties for mpeg2 encoder class. Also set the new get/set + property functions for gobject class. Still use the old properties + way now and this new feature will be enabled later. + +2019-08-20 14:53:06 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + libs: encoder: Add properties for jpeg encoder. + Install properties for jpeg encoder class. Also set the new get/set + property functions for gobject class. Still use the old properties + way now and this new feature will be enabled later. + +2019-08-20 14:12:36 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: Add properties for h265 encoder. + Install properties for h265 encoder class. Also set the new get/set + property functions for gobject class. Still use the old properties + way now and this new feature will be enabled later. + +2019-08-20 01:33:40 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: Add properties for h264 encoder. + Install properties for h264 encoder class. Also set the new get/set + property functions for gobject class. Still use the old properties + way now and this new feature will be enabled later. + +2019-08-19 15:38:09 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: add properties and prop help functions + Add all common properties to encoder base class. rate-control and + tune are moved to sub class. + +2019-08-29 14:38:49 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: delete useless gst_vaapi_encoder_new func. + GstVaapiEncoder is a abstract gobject and never be created directly. + +2019-07-27 00:55:53 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.h: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.h: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.h: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.c: + * gst-libs/gst/vaapi/gstvaapifeienc_h264.h: + lib: encoder: gstobjectfy all vaapi encoders. + Replace all gstvaapiobject in vaapi encoders with standard gstobject. + Let the gstobject common logic to handle all the init and finalize + works. But the property install/set/get still use the old way, need + to be improved later. + +2019-08-29 12:11:36 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: check for filter before appending caps + While ensuring the allowed sink pad caps, the filter attributes set + the frame size restriction, but it is not ensured, at that moment, + that the filter is already instantiaded. + In order to silence the glib logs, this patch add only calls + gst_vaapi_filter_append_caps() if the filter is instantiated. + +2019-08-28 12:49:03 -0400 Thibault Saunier + + * gst/vaapi/gstvaapidecodebin.c: + Classify vaapidecodebin as a hardware decoder + +2019-08-27 18:12:45 +0800 He Junyan + + * gst/vaapi/gstvaapipostproc.c: + libs: postproc: fix a memory leak point. + filter_ops and filter_formats should already have valid value when + the function gst_vaapipostproc_ensure_filter_caps re-enter + +2019-08-27 01:30:36 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils_core.c: + libs: util: Fix a memory leak in config_surface_attributes_get + +2019-08-22 14:33:54 +0800 Wangfei + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: support transform ROI meta + This will benefit the use case like: + src ---> encode ---> decode ---> circle ROI ---> sink + | | + --> analyse to --> + get ROI + +2019-08-23 19:10:15 +0200 Mathieu Duponchelle + + * gst/vaapi/gstvaapidecodedoc.c: + docstrings: port ulinks to markdown links + +2019-08-20 17:05:14 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext_overlay.c: + * gst-libs/gst/vaapi/gstvaapicontext_overlay.h: + * gst-libs/gst/vaapi/meson.build: + libs: remove context's overlay + The context overlay was an optimization to apply a video composition + to all the surfaces bound to a context. + But since commit 18031dc6 this optimization was disabled, so it is + better just get rid of it. + +2019-08-20 16:50:46 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapisurface.c: + * gst-libs/gst/vaapi/gstvaapisurface.h: + * gst-libs/gst/vaapi/gstvaapisurface_priv.h: + * gst/vaapi/gstvaapipluginutil.c: + * tests/test-subpicture.c: + libs: remove surface's parent context + In commit 18031dc6 surface's parent context is not assigned because of + circular references. Since then (2013), there's has no issue with + subpictures attached to a context, the current only users of this API. + This patch cleans up all of related code with the unused surface's + parent context. + +2019-08-18 13:53:53 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: guard if no structure is available in caps + +2019-08-18 13:53:19 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: append frame size restrictions in caps + +2019-08-18 13:09:58 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiprofilecaps.c: + libs: profilecaps: refactor common code + +2019-08-16 19:35:58 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: set frame size restrictions in caps + Fixes: #12 + +2019-08-16 19:28:27 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst/vaapi/gstvaapiencode.c: + vaapiencode: enhance how the profile is defined + This code doesn't define the profile used by the internal encoder, but + it used to "predict" which is going to be used and to get the caps + restrictions. + Before the profile was predicted by checking the donwstream caps, but + sometimes they are not defined, setting an unknown profile. In order + to enhances this situation, the encoder asks to internal encoder if it + has one. If so, it is used. + To ask the internal encoder's profile a new accessor function was + added: gst_vaapi_encoder_get_profile() + +2019-08-16 19:26:36 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiprofilecaps.c: + * gst-libs/gst/vaapi/gstvaapiprofilecaps.h: + libs: profilecaps: defines gst_vaapi_profile_caps_append_encoder() + Previously it was just a boilerplate. Now it is real implementation. + +2019-08-16 19:17:48 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: treat va_rt_format as bitwise flag + The return value of vaGetConfigAttributes() of VAConfigAttribRTFormat + is a bitwise flag with *all* the supported chroma types. + Previously it was assumed that the return value was a single value, + thus when returning the GST_VAAPI_CHROMA_TYPE_XXX the code was a + simple case. But it is wrong. + This patch changes the case block with a sequence of ifs testing the + bitwise. For now we assume a "priority" list in the testing sequence. + +2019-08-16 18:07:43 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * tests/test-display.c: + libs: profile: add gst_vaapi_profile_get_va_name() + gst_vaapi_profile_get_name() returns a proper name for + GstCaps. Nonetheless, there are many profiles which don't have a name + representation for that realm. + gst_vaapi_profile_get_va_name() returns the name of the profile + according to its VAProfile name. + This new funtion is used in the encoder error message. + +2019-08-05 19:47:30 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/Makefile.am: + * gst-libs/gst/vaapi/gstvaapiprofilecaps.c: + * gst-libs/gst/vaapi/gstvaapiprofilecaps.h: + * gst-libs/gst/vaapi/meson.build: + * gst/vaapi/gstvaapidecode.c: + libs: profilecaps: move caps config into a new file + Implement all the appending of frame size restrictions in caps, for + encoders and decoders, in a new source file. + +2019-08-05 19:45:49 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + libs: decoder: ref the caps as property + +2019-08-02 16:56:17 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + libs: context: add gst_vaapi_context_get_surface_attributes() + This function copies the surface attributes from the context's object + to the caller. + +2019-08-02 12:46:55 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapibufferproxy.c: + * gst-libs/gst/vaapi/gstvaapibufferproxy.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + libs: move memory types conversions to gstvaapiutils + And add more supported memory types by current VA. + +2019-08-01 19:48:21 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils_core.c: + * gst-libs/gst/vaapi/gstvaapiutils_core.h: + libs: utils: remove unused function gst_vaapi_get_surface_formats() + +2019-08-01 19:46:17 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: context, filter: use new surface attributes API + +2019-08-01 19:13:39 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils_core.c: + * gst-libs/gst/vaapi/gstvaapiutils_core.h: + libs: utils: add gst_vaapi_config_surface_attributes_get() + To extract the surface restrictions per config using a new structure: + GstVaapiConfigSurfaceAttributes + +2019-07-31 13:08:43 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiutils_core.c: + Split the surface attribute retrieval + +2019-07-15 21:51:46 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: handle navigation downstream event + When navigation events contains coordiantes those have to be mapped + to the new size and/or orientation. + +2019-07-15 21:23:21 +0200 Víctor Manuel Jáquez Leal + + * tests/elements/test-vaapisink.c: + test-vaapisink: also use vaapipostproc to change orientation + +2019-07-15 21:27:20 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: handle image-orientation upstream event + Now that vaapipostproc can possible handle video-direction, it + should also handle the image-orientation event from upstream if + video-direction property is set to auto. + +2019-07-26 22:09:37 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: add missing locks when adding flags + +2019-07-26 22:05:29 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: update filter before fixate caps + It is requiered to know if postproc is capable to change the video + direction before fixating the source caps. + In order to do it, it'ss required to know if there's a functional VPP, + but that's checked at create() vmethod, which occurs after caps + fixating. + This patch checks for a functional VPP at fixate caps and, if so, + checks for the enabled filtes and later do the caps fixations. + +2019-07-26 19:46:09 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapivalue.h: + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: element warning if video direction is unsupported + If the video direction is unsupported by the driver, an element + warning is posted in the bus to notify the application. + gst_vaapi_enum_type_get_nick() was added in the library thus it can + be used elsewhere. It retrives the nick from an enum gtype. + +2019-07-26 19:09:54 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: filter: check mirror and rotation caps only once + This patch locks the display before querying the pipeline caps and + stores the mirror and rotation capabilities, thus they are not queried + every time the video direction is set. + +2019-08-16 19:51:29 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: vp9: set VP9_0 profile as default + Commit 0afc8131 introduced a regression and only NV12 format were + admitted, failing in any other valid color format. + This patch sets the profile to GST_VAAPI_PROFILE_VP9_0 by default. + +2019-08-16 13:25:06 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + libs: filter: fail if first color balance value is invalid + +2019-08-06 19:24:08 +0800 Yan Wang + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + libs: filter: set all color balance values + When set multiple settings of color balance like hue, saturation, + brightness and contrast for vaapipostproc, they should be set as + parameters of color balance filter, at the same color balance + filter calling. + Otherwise, multiple color balance filter calling will cause + previous setting get reset by the last calling with default value. + Fixes #182. + Signed-off-by: Yan Wang + +2019-08-16 11:02:08 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: h265dec: remove limitation of get iq matrix + According hevc spec, scaling_list_data is not related + to chroma_format_idc. + +2019-05-30 23:52:51 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapivideopool.c: + libs: videopool: fix undocumented behavior and counting + gst_vaapi_video_pool_reserve_unlocked() hit an undocumented behavoir + because it locks twice the same mutex. + Also, n had different meanings in the current code: as an increase + value and as a new total of allocated surfaces. + This patche removes the undocumented behavoir (usually a deadlock) and + fixes the meaning of n as the new total of allocated surfaces. + Signed-off-by: Víctor Manuel Jáquez Leal + +2019-07-17 11:56:45 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: utils: Add missing entries for string_of_VAEntrypoint. + +2019-07-18 22:01:01 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: Consider vp9 profiles based on input format. + Only support GST_VAAPI_PROFILE_VP9_0 and GST_VAAPI_PROFILE_VP9_2 now. + Fix: #184 + +2019-08-12 18:41:52 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: demote error message to info + The main reason to demote the message's level is because it is not an + error, it's a possible output of the trial and there's a code path + that handles it. + Secondly, it's very annoying when using gallium driver for radeon. + +2019-07-18 13:32:46 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapivalue.c: + libs: encoder: h264: support ICQ/QVBR bitrate control mode + ICQ is Intelligent Constant Quality. It will use the initial QP + vaule of icq-quality-factor to adjust QP at MB level intelligently + to improve subjective quality. + QVBR is Quality defined VBR. It will use qvbr-quality-factor to + adjust QP for each MB to get enough quality picture without waste + of bits. + +2019-08-05 10:51:24 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapitypes.h: + libs: Let GST_VAAPI_RATECONTROL_MASK return unsigned int + The value return from GST_VAAPI_RATECONTROL_MASK will be used by + GST_VAAPI_POPCOUNT32 as its inpput. GST_VAAPI_POPCOUNT32 can only + deal with unsigned int. Otherwise there may be an error of out of + range of integer if we define few more rate-control mode. + +2019-06-07 09:54:12 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: set queue's max size buffers to 1 + Otherwise the queue will swallow all the available decoder's surfaces + reaching a dead-lock. + This setting might impact the bin's peformance, but it's a trade-off. + +2019-06-07 09:53:08 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: set properties default values + +2019-05-31 13:12:35 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: don't error if can't push buffers downtream + When the code path goes to push buffers downstream when no surface + available in decoder context, and it fails the code bails out with a + fatal error. + That behavior is wrong, since it shouldn't be fatal. The use case is + when the video stream is disabled. + This patch just ignores the errors in this situation and demotes the + level of a log message. + +2019-05-18 13:24:35 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h264_fei.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + libs: encoder: h264,h265: add new property "max-qp" + Add new property "max-qp" to allow set the maximum quantisation + parameter values. + +2019-05-23 10:18:52 -0400 Wangfei + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: vp9: add low power mode encode + By now, this feature only support by media-driver on Ice Lake + platform, more information you can reference: + https://github.com/intel/media-driver + +2019-07-15 15:33:07 -0700 U. Artie Eoff + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: update PAR when rotating + When rotating, swap pixel-aspect-ratio during + negotiation. + Fixes #181 + +2019-07-01 15:26:18 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: add rotation support + Adds vpp rotation support to vaapipostproc. Uses + property video-direction. Default is identity (no + rotation). + Closes #104 + +2019-05-22 10:47:30 -0400 Wangfei + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: pass diff_cu_qp_delta_depth flag to driver + Intel media-driver requires enablement of diff_cu_qp_delta_depth when + cu_qp_delta_enabled_flag enabled. + Fixes: #177 + +2019-07-01 17:02:33 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: encoder: Add MB ratecontrol mode to get its string + +2019-07-01 16:52:00 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiutils.c: + libs: encoder: refine guard of bitrate control mode + Remove useless guard of all bitrate control mode's guard except MB + which is define in VA-API version 0.39.1. + +2019-06-29 00:08:40 +1000 Jan Schmidt + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264: Update for parse_vui_params parameter removal. + Update calls to the h264 parser lib for removal of the + parse_vui_params parameter. + +2019-06-24 16:26:56 -0400 Wang Zhanjun + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + libs: dec: vp9: do not use display size as decoded size + If display size is smaller than current frame size, then the crop size + will be set as display size, which either crashes the pipeline or the + output MD5 does not match. Rather it should use the actual decoded size. + This patch removes the cropping set. For rendering we can use aspect + ratio to set display size. + Fixes #175 + Signed-off-by: Wang Zhanjun + Signed-off-by: Xu Guangxin + +2019-06-28 16:32:51 +0200 Víctor Manuel Jáquez Leal + + * README: + Update README + +2019-06-25 19:11:12 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265_priv.h: + libs: dec: h265: Consider chroma_bit_depth to choose chrome type + For some main-10 stream, sometime the luma is 8 bits while chrome is more + than 8 bits, which cause using the wrong NV12 surface as the render target + and decoding error. + Fix #176 + +2019-06-25 10:31:20 +0800 Wangfei + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: set initial decode format according surface chroma type + For surfaces with different chroma type, it is prefer to initialize + a format which chroma type should be same with surface chroma type + instead of using fixed NV12. + +2019-05-30 09:48:51 -0400 Wangfei + + * gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c: + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/video-format.c: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.h: + libs: decoder: jpeg: add support 400/411/422/444 chroma type + When create vaapi surface, it is better to use the chroma type get + from jpeg file instead of using fixed 420 format. And the correct + chroma type can be determined by horizontal_factor/vertical_factor + flags that get from jpegparse. + +2019-06-22 00:05:24 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + libs: dec: h265: Fix profile_idc mapping. + The old mapping values return by gst_vaapi_utils_h265_get_profile_idc is + wrong, though GST_H265_PROFILE_IDC_MAIN and GST_H265_PROFILE_IDC_MAIN_10 + happened to be the correct value. + We only support Annex A profile_idc (1-4). + +2019-06-10 20:46:30 -0700 U. Artie Eoff + + * gst/vaapi/gstvaapipluginbase.c: + plugins: remove last negotiated video info if caps are same + If the allocation caps and negotiated caps are the same, + then ensure any previously negotiated video info is also + removed. This can occur when multi-resolution video + decoding returns to it's original resolution. + Fixes #170 + +2019-06-10 20:39:28 -0700 U. Artie Eoff + + * gst/vaapi/gstvaapivideomemory.c: + vaapivideomemory: allow negotiated info to be removed + Allow NULL negotiated_vinfo to be passed into + gst_allocator_set_vaapi_negotiated_video_info to allow + any previously set info to be removed. + +2019-06-06 17:24:30 +0300 Freyr + + * gst-libs/gst/vaapi/gstvaapiencoder_vp8.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: vp8,vp9: reset frame_counter when input frame's format changes + When input frame's formate changes, vp{8,9} encoders don't reset their frame + counter, hence the newly created frame could become a P-frame, leading to some + major troubles (sigabrt in libdrm in case of vp9). This patch adds some frame + prediction-related reset logic to the `flush' methods of GstVaapiEncoderVP8 and + GstVaapiEncoderVP9 implementations. + +2019-05-31 12:30:03 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: increase bitrate prop max value + There are many profile levels that can support + more than 102400 kbps. Thus, increase the max + allowed bitrate property value from 102400 kbps + to 2048000 kbps (same as msdk encoder plugins). + +2019-06-04 13:27:50 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c: + libs: mpeg2 encoder: No packed header for SPS and PPS + Dislable passing down packed PPS and PPS to driver if driver does + not want it. + Fix: #168 + +2019-05-31 23:10:33 +0200 Niels De Graef + + * configure.ac: + * meson.build: + * tests/output.c: + meson: Bump minimal GLib version to 2.44 + This means we can use some newer features and get rid of some + boilerplate code using the G_DECLARE_* macros. + As discussed on IRC, 2.44 is old enough by now to start depending on it. + +2019-05-31 13:08:39 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + libs: dec: vp9: clear parser pointer after release + Fix an use-after-release of the parser pointer in VP9 decoder. + +2019-05-28 12:09:36 +0300 Freyr666 + + * gst/vaapi/gstvaapiencode.c: + vaapiencode: Fixes deadlock in gst_vaapiencode_change_state function + This fixes a deadlock in gst_vaapiencode_change_state, which was due to + srcpad's chain function was locked waiting for available buffers. Since the + coded buffers in codedbuf_queue become available after sinkpad consume the + encoded frames, Paused -> Ready state change leads to deadlock. Coded buffers + are never consumed and marked free, hence gst_vaapiencode_handle_frame waits for + available buffers and holds the stream_lock of the srcpad. + +2019-05-29 23:08:22 +0200 Mathieu Duponchelle + + * gst-libs/gst/vaapi/gstvaapitypes.h: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapidecodedoc.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264_fei.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiencode_vp9.c: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapisink.c: + doc: remove xml from comments + +2019-05-13 16:39:33 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/gstvaapiutils.h: + * gst/vaapi/gstvaapipostproc.c: + * gst/vaapi/gstvaapipostproc.h: + vaapipostproc: add mirror support + Adds vpp mirroring support to vaapipostproc. Use + property video-direction. Valid values are identity, + horiz or vert. Default is identity (no mirror). + Closes #89 + v2: Use GstVideoOrientationMethod enum + v3: Don't warn for VA_MIRROR_NONE. + Use GST_TYPE_VIDEO_ORIENTATION_METHOD type. + v4: Query VAAPI caps when setting mirror value + instead of during per-frame processing. + v5: Return TRUE in warning cases when setting mirror value. + +2019-05-29 01:35:17 +0200 Mathieu Duponchelle + + * gst-libs/gst/vaapi/gstvaapiutils_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_glx.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.c: + * gst-libs/gst/vaapi/gstvaapiwindow_x11.h: + * gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h: + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapisink.c: + doc: fix some incorrect gtk-doc links + +2019-05-16 09:22:42 -0400 Thibault Saunier + + * docs/gst_plugins_cache.json: + docs: Update plugin cache + Fixes https://gitlab.freedesktop.org/gstreamer/gst-docs/issues/36 + +2019-05-16 16:46:43 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface.h: + libs: surface: fix documentation format + +2019-05-16 10:05:17 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: enc: h265: reset num_ref_idx_l1_active_minus1 when low delay B. + When enable low delay B, the reference list 1 will be same with + reference list 0, so need reset the num_ref_idx_l1_active_minus1 + to num_ref_idx_l0_active_minus1. + Fixes: #160 + +2019-05-13 19:05:43 -0400 Thibault Saunier + + * docs/meson.build: + meson: Fix call to wrong function + +2018-10-22 11:48:29 +0200 Thibault Saunier + + * Makefile.am: + * configure.ac: + * docs/Makefile.am: + * docs/gst_plugins_cache.json: + * docs/index.md: + * docs/meson.build: + * docs/plugins/Makefile.am: + * docs/plugins/gstreamer-vaapi-plugins-docs.xml.in: + * docs/plugins/gstreamer-vaapi-plugins-sections.txt: + * docs/plugins/gstreamer-vaapi-plugins.types: + * docs/plugins/inspect/plugin-vaapi.xml: + * docs/plugins/running.xml: + * docs/sitemap.txt: + * docs/version.entities.in: + * gst/vaapi/meson.build: + * meson.build: + * meson_options.txt: + docs: Port to hotdoc + +2019-05-10 18:29:10 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: not call ensure_num_slices inside g_assert + g_assert will take no effect when glib's G_DISABLE_ASSERT macro is + defined. The function inside the g_assert will take no effect and + we will fail to set the correct slice number. + +2019-04-29 09:52:39 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: h265: dec: Add extension flags setting. + Use VAPictureParameterBufferHEVCExtension& + VASliceParameterBufferHEVCExtension to pass extension setting from + some extension profile clips which may include these information. + The hevc extension setting only supported after libva release 2.2.0 + (API 1.2.0). + +2019-05-01 12:56:55 -0700 U. Artie Eoff + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: add target-percentage property + Allow users to set the target-percentage for + variable rate controls. The default value is + 70 (as hard-coded prior). + v2: minimum allowed value changed from 0 to 1 + v3: target-percentage unchanged if CBR used + Resolves #129 + +2019-05-09 00:09:21 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.h: + libs: encoder: Add a missing comment for DEFAULT_ROI_VALUE property. + +2019-05-08 23:39:20 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder.h: + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + * gst-libs/gst/vaapi/gstvaapiencoder_priv.h: + libs: encoder: Enable trellis quantization method. + The advanced trellis algorithm is supported in VA driver. We add + its support as a property named "trellis" of encoder. + It only works for H264 now, should be more in future. + +2019-05-07 11:03:51 +0800 Wangfei + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + libs: decoder: vp9: support 422/444 8bit/10bit chroma type. + According to the vp9 sepc, profile 1/3 support 422/440/444 chroma + type, so we need to add subsampling_x&subsampling_y to fix it. + Here is the relationship between chroma type and profile and + subsampling_x&subsampling_y according to vp9 spec: + ------------------------------------------ + Profile | Bit depth | Chroma subsampling | + ------------------------------------------ + 0 | 8 | 420 | + ------------------------------------------ + 1 | 8 | 422,440,444 | + ------------------------------------------ + 2 | 10, 12 | 420 | + ------------------------------------------ + 3 | 10, 12 | 422,440,444 | + ------------------------------------------ + ----------------------------------------------- + Subsampling_x | Subsampling_y | Chroma format | + ----------------------------------------------- + 0 | 0 | 444 | + ----------------------------------------------- + 0 | 1 | 440 | + ----------------------------------------------- + 1 | 0 | 422 | + ----------------------------------------------- + 1 | 1 | 420 | + ----------------------------------------------- + +2019-04-16 18:33:54 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/video-format.c: + libs: Add packed 24 RGB format support. + Can not find a suitable chrome_type for this GST_VIDEO_FORMAT_RGB + packed 24 format. Just use GST_VAAPI_CHROMA_TYPE_RGB32 as its chrome + type. This kind of surface will just be created by new API with fourcc + and no old style chrome based creation is available. + fixes: #151 + +2019-03-15 14:29:41 +0800 Wangfei + + * gst/vaapi/gstvaapiencode.c: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h264_fei.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiencode_vp9.c: + vaapiencode: handle DMABuf caps feature in sink pad + Add DMABuff caps features in all encoders' sink pad. + +2019-05-03 10:31:52 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + libs: encoder: continue if roi meta is NULL + Coverity scan bug: + If the function actually returns a null value, a null pointer + dereference will occur. + In gst_vaapi_encoder_ensure_param_roi_regions(): Return value of + function which returns null is dereferenced without checking + +2019-04-15 19:58:14 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + lib: decoder: vp9: Set chroma_type by VP9 bit_depth + The decoder's surface chroma type should depend on the bit depth + of VP9's parser. For 10bits VP9 stream, we need to use P10LE kind + 10 bits surface as the decoder result. + Fixes #155 + +2019-05-02 16:00:57 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostprocutil.c: + vaapipostproc: don't do any color conversion when GL_TEXTURE_UPLOAD + https://bugzilla.gnome.org/show_bug.cgi?id=748184 has resurrected + with commit 3e992d8a + Since gst_vaapi_find_preferred_caps_feature() returns a color format + from caps negotiation, different from the default one (NV12), the + postproc enables the color transformation. But when GL_TEXTURE_UPLOAD + feature is negotiated, no color transformation shall be done. + Nonetheless, with commit 3e992d8a the requested format changes + firstly, because there's no video sink yet, so ANY caps are + negotiated; but later, when there's a video sink and a caps + renegotiation, the GL_TEXTURE_UPLOAD is negotiated though the color + format conversion still ongoing. It is required to reset that + conversion. + This patch force default color format when GL_TEXTURE_UPLOAD is + selected as preferred, thus avoiding the color conversion. + Fixes: #157 + +2019-04-19 15:49:37 -0700 Julien Isorce + + * gst-libs/gst/vaapi/gstvaapisurface_drm.c: + libs: surface: fix double free when dmabuf export fails + Happens if vaAcquireBufferHandle fails. + +2019-04-29 20:10:39 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: h264encoder: fix a typo of GstVaapiEncoderH264PredictionType + +2019-04-19 10:43:35 +0100 Tim-Philipp Müller + + * RELEASE: + * configure.ac: + * docs/plugins/inspect/plugin-vaapi.xml: + * meson.build: + Back to development + === release 1.16.0 === 2019-04-19 00:38:12 +0100 Tim-Philipp Müller @@ -14904,8 +18721,6 @@ * configure.ac: Bump version for development. -=== release 0.5.9 === - 2014-07-29 10:31:58 +0200 Gwenole Beauchesne * AUTHORS: @@ -16584,8 +20399,6 @@ * configure.ac: Bump version for development. -=== release 0.5.8 === - 2014-01-24 10:55:39 +0100 Gwenole Beauchesne * debian.upstream/control.in: @@ -18598,8 +22411,6 @@ * configure.ac: Bump version for development. -=== release 0.5.7 === - 2013-11-22 11:28:09 +0100 Gwenole Beauchesne * gst/vaapi/Makefile.am: @@ -19599,8 +23410,6 @@ * configure.ac: Bump version for development. -=== release 0.5.6 === - 2013-08-31 15:47:33 +0200 Gwenole Beauchesne * NEWS: @@ -20147,8 +23956,6 @@ * configure.ac: Bump version for development. -=== release 0.5.5 === - 2013-07-15 17:49:31 +0200 Gwenole Beauchesne * gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c: @@ -20686,8 +24493,6 @@ * configure.ac: Bump version for development. -=== release 0.5.4 === - 2013-06-14 11:47:50 +0200 Gwenole Beauchesne * NEWS: @@ -21234,8 +25039,6 @@ * configure.ac: Bump version for development. -=== release 0.5.3 === - 2013-04-18 19:09:45 +0200 Gwenole Beauchesne * NEWS: @@ -21733,8 +25536,6 @@ * configure.ac: Bump version for development. -=== release 0.5.2 === - 2013-03-28 10:18:51 +0100 Gwenole Beauchesne * NEWS: @@ -22220,8 +26021,6 @@ * configure.ac: Bump version for development. -=== release 0.5.1 === - 2013-01-30 09:37:38 +0100 Gwenole Beauchesne * NEWS: @@ -22686,8 +26485,6 @@ * configure.ac: Bump version for development. -=== release 0.5.0 === - 2013-01-15 09:21:08 +0100 Gwenole Beauchesne * NEWS: @@ -25723,8 +29520,6 @@ * configure.ac: Bump version for development. -=== release 0.3.6 === - 2012-04-02 10:07:33 +0200 Gwenole Beauchesne * configure.ac: @@ -26038,8 +29833,6 @@ bitstream. i.e. the direct slice() information. VA drivers will be fixed accordingly. -=== release 0.3.5 === - 2012-03-02 15:03:57 +0100 Gwenole Beauchesne * gst/vaapi/gstvaapidecode.c: @@ -26213,8 +30006,6 @@ * configure.ac: Bump version for development. -=== release 0.3.4 === - 2012-02-01 23:34:09 +0100 Gwenole Beauchesne * NEWS: @@ -26492,8 +30283,6 @@ * configure.ac: Bump version for development. -=== release 0.3.3 === - 2012-01-16 11:05:31 +0100 Gwenole Beauchesne * NEWS: @@ -26927,8 +30716,6 @@ * configure.ac: Bump version for development. -=== release 0.3.2 === - 2012-01-06 11:20:48 +0100 Gwenole Beauchesne * NEWS: @@ -27056,8 +30843,6 @@ * configure.ac: Bump version for development. -=== release 0.3.1 === - 2012-01-03 13:42:12 +0100 Gwenole Beauchesne * NEWS: @@ -27238,8 +31023,6 @@ * gst-libs/gst/video/gstbasevideoutils.h: Drop unused copy of GstBaseVideoDecoder. -=== release 0.3.0 === - 2011-12-09 11:46:45 +0100 Gwenole Beauchesne * NEWS: @@ -27670,8 +31453,6 @@ * tests/Makefile.am: Fix build with libva headers not in a standard include dir. -=== release 0.2.6 === - 2011-06-14 15:59:08 +0200 Gwenole Beauchesne * configure.ac: @@ -27886,8 +31667,6 @@ * gst-libs/gst/vaapi/gstvaapicompat.h: Fix build with older VA-API 0.29-sds. -=== release 0.2.4 === - 2010-05-18 11:22:54 +0000 gb * gst/vaapisink/gstvaapisink.c: @@ -27921,8 +31700,6 @@ * configure.ac: Bump version for development. -=== release 0.2.3 === - 2010-05-16 21:44:17 +0000 gb * NEWS: @@ -27999,8 +31776,6 @@ * configure.ac: Bump version for development. -=== release 0.2.2 === - 2010-05-13 21:52:22 +0000 gb * NEWS: @@ -28069,8 +31844,6 @@ * gst/vaapisink/gstvaapisink.c: Use XGetGeometry() to retrieve the window size. -=== release 0.2.1 === - 2010-05-12 19:40:30 +0000 gb * gst/vaapisink/gstvaapisink.c: @@ -28221,8 +31994,6 @@ * configure.ac: Bump version for development. -=== release 0.2.0 === - 2010-05-05 12:29:28 +0000 gb * NEWS: @@ -28935,8 +32706,6 @@ * configure.ac: Bump version for development. -=== release 0.1.2 === - 2010-03-30 13:29:34 +0000 gb * configure.ac: @@ -29606,8 +33375,6 @@ * configure.ac: Bump version for development. -=== release 0.1.1 === - 2010-03-23 17:29:47 +0000 gb * gst-libs/gst/vaapi/gstvaapiutils_x11.c: @@ -30137,8 +33904,6 @@ * configure.ac: Bump version for development. -=== release 0.1.0 === - 2010-03-16 14:07:53 +0000 gb * configure.ac: diff --git a/NEWS b/NEWS index 816a3aae85..a4e7232a19 100644 --- a/NEWS +++ b/NEWS @@ -1,14 +1,30 @@ -GSTREAMER 1.16 RELEASE NOTES +GSTREAMER 1.18 RELEASE NOTES -GStreamer 1.16.0 was originally released on 19 April 2019. +THESE RELEASE NOTES ARE A PLACEHOLDER, PLEASE BEAR WITH US WHILE WE +FINISH WRITING UP THE REAL THING. -See https://gstreamer.freedesktop.org/releases/1.16/ for the latest +GStreamer 1.18.0 has not yet been released. It is scheduled for release +in summer 2020 now. + +1.17.x is the unstable development series that is currently being +developed in the git master branch and which will eventually result in +1.18, and 1.17.1 is the current development release in that series. + +The schedule for the 1.18 development cycle is yet to be confirmed, but +it is expected that feature freeze will be in June/July 2020, followed +by several 1.17 pre-releases and then a new 1.18 stable release in +July/August 2020. + +1.18 will be backwards-compatible to the stable 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.18/ for the latest version of this document. -_Last updated: Friday 19 April 2019, 00:00 UTC (log)_ +_Last updated: Thursday 18 June 2020, 16:00 UTC (log)_ Introduction @@ -23,1146 +39,133 @@ fixes and other improvements. Highlights -- GStreamer WebRTC stack gained support for data channels for - peer-to-peer communication based on SCTP, BUNDLE support, as well as - support for multiple TURN servers. - -- AV1 video codec support for Matroska and QuickTime/MP4 containers - and more configuration options and supported input formats for the - AOMedia AV1 encoder - -- Support for Closed Captions and other Ancillary Data in video - -- Support for planar (non-interleaved) raw audio - -- GstVideoAggregator, compositor and OpenGL mixer elements are now in - -base - -- New alternate fields interlace mode where each buffer carries a - single field - -- WebM and Matroska ContentEncryption support in the Matroska demuxer - -- new WebKit WPE-based web browser source element - -- Video4Linux: HEVC encoding and decoding, JPEG encoding, and improved - dmabuf import/export - -- Hardware-accelerated Nvidia video decoder gained support for VP8/VP9 - decoding, whilst the encoder gained support for H.265/HEVC encoding. - -- Many improvements to the Intel Media SDK based hardware-accelerated - video decoder and encoder plugin (msdk): dmabuf import/export for - zero-copy integration with other components; VP9 decoding; 10-bit - HEVC encoding; video post-processing (vpp) support including - deinterlacing; and the video decoder now handles dynamic resolution - changes. - -- The ASS/SSA subtitle overlay renderer can now handle multiple - subtitles that overlap in time and will show them on screen - simultaneously - -- The Meson build is now feature-complete (*) and it is now the - recommended build system on all platforms. The Autotools build is - scheduled to be removed in the next cycle. - -- The GStreamer Rust bindings and Rust plugins module are now - officially part of upstream GStreamer. - -- The GStreamer Editing Services gained a gesdemux element that allows - directly playing back serialized edit list with playbin or - (uri)decodebin - -- Many performance improvements +- FIXME Major new features and changes Noteworthy new API -- GstAggregator has a new "min-upstream-latency" property that forces - a minimum aggregate latency for the input branches of an aggregator. - This is useful for dynamic pipelines where branches with a higher - latency might be added later after the pipeline is already up and - running and where a change in the latency would be disruptive. This - only applies to the case where at least one of the input branches is - live though, it won’t force the aggregator into live mode in the - absence of any live inputs. - -- GstBaseSink gained a "processing-deadline" property and - setter/getter API to configure a processing deadline for live - pipelines. The processing deadline is the acceptable amount of time - to process the media in a live pipeline before it reaches the sink. - This is on top of the systemic latency that is normally reported by - the latency query. This defaults to 20ms and should make pipelines - such as v4l2src ! xvimagesink not claim that all frames are late in - the QoS events. Ideally, this should replace the "max-lateness" - property for most applications. - -- RTCP Extended Reports (XR) parsing according to RFC 3611: - Loss/Duplicate RLE, Packet Receipt Times, Receiver Reference Time, - Delay since the last Receiver (DLRR), Statistics Summary, and VoIP - Metrics reports. This only provides the ability to parse such - packets, generation of XR packets is not supported yet and XR - packets are not automatically parsed by rtpbin / rtpsession but must - be actively handled by the application. - -- a new mode for interlaced video was added where each buffer carries - a single field of interlaced video, with buffer flags indicating - whether the field is the top field or bottom field. Top and bottom - fields are expected to alternate in this mode. Caps for this - interlace mode must also carry a format:Interlaced caps feature to - ensure backwards compatibility. - -- The video library has gained support for three new raw pixel - formats: - - - Y410: packed 4:4:4 YUV, 10 bits per channel - - Y210: packed 4:2:2 YUV, 10 bits per channel - - NV12_10LE40: fully-packed 10-bit variant of NV12_10LE32, - i.e. without the padding bits - -- GstRTPSourceMeta is a new meta that can be used to transport - information about the origin of depayloaded or decoded RTP buffers, - e.g. when mixing audio from multiple sources into a single stream. A - new "source-info" property on the RTP depayloader base class - determines whether depayloaders should put this meta on outgoing - buffers. Similarly, the same property on RTP payloaders determines - whether they should use the information from this meta to construct - the CSRCs list on outgoing RTP buffers. - -- gst_sdp_message_from_text() is a convenience constructor to parse - SDPs from a string which is particularly useful for language - bindings. - -Support for Planar (Non-Interleaved) Raw Audio - -Raw audio samples are usually passed around in interleaved form in -GStreamer, which means that if there are multiple audio channels the -samples for each channel are interleaved in memory, e.g. -|LEFT|RIGHT|LEFT|RIGHT|LEFT|RIGHT| for stereo audio. A non-interleaved -or planar arrangement in memory would look like -|LEFT|LEFT|LEFT|RIGHT|RIGHT|RIGHT| instead, possibly with -|LEFT|LEFT|LEFT| and |RIGHT|RIGHT|RIGHT| residing in separate memory -chunks or separated by some padding. - -GStreamer has always had signalling for non-interleaved audio since -version 1.0, but it was never actually properly implemented in any -elements. audioconvert would advertise support for it, but wasn’t -actually able to handle it correctly. - -With this release we now have full support for non-interleaved audio as -well, which means more efficient integration with external APIs that -handle audio this way, but also more efficient processing of certain -operations like interleaving multiple 1-channel streams into a -multi-channel stream which can be done without memory copies now. - -New API to support this has been added to the GStreamer Audio support -library: There is now a new GstAudioMeta which describes how data is -laid out inside the buffer, and buffers with non-interleaved audio must -always carry this meta. To access the non-interleaved audio samples you -must map such buffers with gst_audio_buffer_map() which works much like -gst_buffer_map() or gst_video_frame_map() in that it will populate a -little GstAudioBuffer helper structure passed to it with the number of -samples, the number of planes and pointers to the start of each plane in -memory. This function can also be used to map interleaved audio buffers -in which case there will be only one plane of interleaved samples. - -Of course support for this has also been implemented in the various -audio helper and conversion APIs, base classes, and in elements such as -audioconvert, audioresample, audiotestsrc, audiorate. - -Support for Closed Captions and Other Ancillary Data in Video - -The video support library has gained support for detecting and -extracting Ancillary Data from videos as per the SMPTE S291M -specification, including: - -- a VBI (Vertical Blanking Interval) parser that can detect and - extract Ancillary Data from Vertical Blanking Interval lines of - component signals. This is currently supported for videos in v210 - and UYVY format. - -- a new GstMeta for closed captions: GstVideoCaptionMeta. This - supports the two types of closed captions, CEA-608 and CEA-708, - along with the four different ways they can be transported (other - systems are a superset of those). - -- a VBI (Vertical Blanking Interval) encoder for writing ancillary - data to the Vertical Blanking Interval lines of component signals. - -The new closedcaption plugin in gst-plugins-bad then makes use of all -this new infrastructure and provides the following elements: - -- cccombiner: a closed caption combiner that takes a closed captions - stream and another stream and adds the closed captions as - GstVideoCaptionMeta to the buffers of the other stream. - -- ccextractor: a closed caption extractor which will take - GstVideoCaptionMeta from input buffers and output them as a separate - closed captions stream. - -- ccconverter: a closed caption converter that can convert between - different formats - -- line21encoder, line21decoder: inject/extract line21 closed captions - to/from SD video streams - -- cc708overlay: decodes CEA 608/708 captions and overlays them on - video - -Additionally, the following elements have also gained Closed Caption -support: - -- qtdemux and qtmux support CEA 608/708 Closed Caption tracks - -- mpegvideoparse, h264parse extracts Closed Captions from MPEG-2/H.264 - video streams - -- avviddec, avvidenc, x264enc got support for extracting/injecting - Closed Captions - -- decklinkvideosink can output closed captions and decklinkvideosrc - can extract closed captions - -- playbin and playbin3 learned how to autoplug CEA 608/708 CC overlay - elements - -- the externally maintained ajavideosrc element for AJA capture cards - has support for extracting closed captions - -The rsclosedcaption plugin in the Rust plugins collection includes a -MacCaption (MCC) file parser and encoder. +- FIXME New Elements -- overlaycomposition: New element that allows applications to draw - GstVideoOverlayCompositions on a stream. The element will emit the - "draw" signal for each video buffer, and the application then - generates an overlay for that frame (or not). This is much more - performant than e.g. cairooverlay for many use cases, e.g. because - pixel format conversions can be avoided or the blitting of the - overlay can be delegated to downstream elements (such as - gloverlaycompositor). It’s particularly useful for cases where only - a small section of the video frame should be drawn on. - -- gloverlaycompositor: New OpenGL-based compositor element that - flattens any overlays from GstVideoOverlayCompositionMetas into the - video stream. This element is also always part of glimagesink. - -- glalpha: New element that adds an alpha channel to a video stream. - The values of the alpha channel can either be set to a constant or - can be dynamically calculated via chroma keying. It is similar to - the existing alpha element but based on OpenGL. Calculations are - done in floating point so results may not be identical to the output - of the existing alpha element. - -- rtpfunnel funnels together RTP streams into a single session. Use - cases include multiplexing and bundle. webrtcbin uses it to - implement BUNDLE support. - -- testsrcbin is a source element that provides an audio and/or video - stream and also announces them using the recently-introduced - GstStream API. This is useful for testing elements such as playbin3 - or uridecodebin3 etc. - -- New closed caption elements: cccombiner, ccextractor, ccconverter, - line21encoder, line21decoder and cc708overlay (see above) - -- wpesrc: new source element acting as a Web Browser based on WebKit - WPE - -- Two new OpenCV-based elements: cameracalibrate and cameraundistort - that can communicate to figure out distortion correction parameters - for a camera and correct for the distortion. - -- New sctp plugin based on usrsctp with sctpenc and sctpdec elements. - These elements are used inside webrtcbin for implementing data - channels. +- FIXME New element features and additions -- playbin3, playbin and playsink have gained a new "text-offset" - property to adjust the positioning of the selected subtitle stream - vis-a-vis the audio and video streams. This uses subtitleoverlay’s - new "subtitle-ts-offset" property. GstPlayer has gained matching API - for this, namely gst_player_get_text_video_offset(). - -- playbin3 buffering improvements: in network playback scenarios there - may be multiple inputs to decodebin3, and buffering will be done - before decodebin3 using queue2 or downloadbuffer elements inside - urisourcebin. Since this is before any parsers or demuxers there may - not be any bitrate information available for the various streams, so - it was difficult to configure the buffering there smartly within - global constraints. This was improved now: The queue2 elements - inside urisourcebin will now use the new bitrate query to figure out - a bitrate estimate for the stream if no bitrate was provided by - upstream, and urisourcebin will use the bitrates of the individual - queues to distribute the globally-set "buffer-size" budget in bytes - to the various queues. urisourcebin also gained "low-watermark" and - "high-watermark" properties which will be proxied to the internal - queues, as well as a read-only "statistics" property which allows - querying of the minimum/maximum/average byte and time levels of the - queues inside the urisourcebin in question. - -- splitmuxsink has gained a couple of new features: - - - new "async-finalize" mode: This mode is useful for muxers or - outputs that can take a long time to finalize a file. Instead of - blocking the whole upstream pipeline while the muxer is doing - its stuff, we can unlink it and spawn a new muxer + sink - combination to continue running normally. This requires us to - receive the muxer and sink (if needed) as factories via the new - "muxer-factory" and "sink-factory" properties, optionally - accompanied by their respective properties structures (set via - the new "muxer-properties" and "sink-properties" properties). - There are also new "muxer-added" and "sink-added" signals in - case custom code has to be called for them to configure them. - - - "split-at-running-time" action signal: When called by the user, - this action signal ends the current file (and starts a new one) - as soon as the given running time is reached. If called multiple - times, running times are queued up and processed in the order - they were given. - - - "split-after" action signal to finish outputting the current GOP - to the current file and then start a new file as soon as the GOP - is finished and a new GOP is opened (unlike the existing - "split-now" which immediately finishes the current file and - writes the current GOP into the next newly-started file). - - - "reset-muxer" property: when unset, the muxer is reset using - flush events instead of setting its state to NULL and back. This - means the muxer can keep state across resets, e.g. mpegtsmux - will keep the continuity counter continuous across segments as - required by hlssink2. - -- qtdemux gained PIFF track encryption box support in addition to the - already-existing PIFF sample encryption support, and also allows - applications to select which encryption system to use via a - "drm-preferred-decryption-system-id" context in case there are - multiple options. - -- qtmux: the "start-gap-threshold" property determines now whether an - edit list will be created to account for small gaps or offsets at - the beginning of a stream in case the start timestamps of tracks - don’t line up perfectly. Previously the threshold was hard-coded to - 1% of the (video) frame duration, now it is 0 by default (so edit - list will be created even for small differences), but fully - configurable. - -- rtpjitterbuffer has improved end-of-stream handling - -- rtpmp4vpay will be prefered over rtpmp4gpay for MPEG-4 video in - autoplugging scenarios now - -- rtspsrc now allows applications to send RTSP SET_PARAMETER and - GET_PARAMETER requests using action signals. - -- rtspsrc has a small (100ms) configurable teardown delay by default - to try and make sure an RTSP TEARDOWN request gets sent out when the - source element shuts down. This will block the downward PAUSED to - READY state change for a short time, but can be disabled where it’s - a problem. Some servers only allow a limited number of concurrent - clients, so if no proper TEARDOWN is sent new clients may have - problems connecting to the server for a while. - -- souphttpsrc behaves better with low bitrate streams now. Before it - would increase the read block size too quickly which could lead to - it not reading any data from the socket for a very long time with - low bitrate streams that are output live downstream. This could lead - to servers kicking off the client. - -- filesink: do internal buffering to avoid performance regression with - small writes since we bypass libc buffering by using writev() - instead of fwrite() - -- identity: add "eos-after" property and fix "error-after" property - when the element is reused - -- input-selector: lets context queries pass through, so that - e.g. upstream OpenGL elements can use contexts and displays - advertised by downstream elements - -- queue2: avoid ping-pong between 0% and 100% buffering messages if - upstream is pushing buffers larger than one of its limits, plus - performance optimisations - -- opusdec: new "phase-inversion" property to control phase inversion. - When enabled, this will slightly increase stereo quality, but - produces a stream that when downmixed to mono will suffer audio - distortions. - -- The x265enc HEVC encoder also exposes a "key-int-max" property to - configure the maximum allowed GOP size now. - -- decklinkvideosink has seen stability improvements for long-running - pipelines (potential crash due to overflow of leaked clock refcount) - and clock-slaving improvements when performing flushing seeks - (causing stalls in the output timeline), pausing and/or buffering. - -- srtpdec, srtpenc: add support for MKIs which allow multiple keys to - be used with a single SRTP stream - -- srtpdec, srtpenc: add support for AES-GCM and also add support for - it in gst-rtsp-server and rtspsrc. - -- The srt Secure Reliable Transport plugin has integrated server and - client elements srt{client,server}{src,sink} into one (srtsrc and - srtsink), since SRT connection mode can be changed by uri - parameters. - -- h264parse and h265parse will handle SEI recovery point messages and - mark recovery points as keyframes as well (in addition to IDR - frames) - -- webrtcbin: "add-turn-server" action signal to pass multiple ICE - relays (TURN servers). - -- The removesilence element has received various new features and - properties, such as a "threshold" property, detecting silence only - after minimum silence time/buffers, a "silent" property to control - bus message notifications as well as a "squash" property. - -- AOMedia AV1 decoder gained support for 10/12bit decoding whilst the - AV1 encoder supports more image formats and subsamplings now and - acquired support for rate control and profile related configuration. - -- The Fraunhofer fdkaac plugin can now be built against the 2.0.0 - version API and has improved multichannel support - -- kmssink now supports unpadded 24-bit RGB and can configure mode - setting from video info, which enables display of multi-planar - formats such as I420 or NV12 with modesetting. It has also gained a - number of new properties: The "restore-crtc" property does what it - says on the tin and is enabled by default. "plane-properties" and - "connector-properties" can be used to pass custom properties to the - DRM. - -- waylandsink has a "fullscreen" property now and supports the - XDG-Shell protocol. - -- decklinkvideosink, decklinkvideosrc support selecting between - half/full duplex - -- The vulkan plugin gained support for macOS and iOS via MoltenVK in - addition to the existing support for X11 and Wayland - -- imagefreeze has a new num-buffers property to limit the number of - buffers that are produced and to send an EOS event afterwards - -- webrtcbin has a new, introspectable get-transceiver signal in - addition to the old get-transceivers signal that couldn’t be used - from bindings - -- Support for per-element latency information was added to the latency - tracer +- FIXME Plugin and library moves -- The stereo element was moved from -bad into the existing audiofx - plugin in -good. If you get duplicate type registration warnings - when upgrading, check that you don’t have a stale stereoplugin lying - about somewhere. - -GstVideoAggregator, compositor, and OpenGL mixer elements moved from -bad to -base - -GstVideoAggregator is a new base class for raw video mixers and muxers -and is based on GstAggregator. It provides defined-latency mixing of raw -video inputs and ensures that the pipeline won’t stall even if one of -the input streams stops producing data. - -As part of the move to stabilise the API there were some last-minute API -changes and clean-ups, but those should mostly affect internal elements. -Most notably, the "ignore-eos" pad property was renamed to -"repeat-after-eos" and the conversion code was moved to a -GstVideoAggregatorConvertPad subclass to avoid code duplication, make -things less awkward for subclasses like the OpenGL-based video mixer, -and make the API more consistent with the audio aggregator API. - -It is used by the compositor element, which is a replacement for -‘videomixer’ which did not handle live inputs very well. compositor -should behave much better in that respect and generally behave as one -would expected in most scenarios. - -The compositor element has gained support for per-pad blending mode -operators (SOURCE, OVER, ADD) which determines what operator to use for -blending this pad over the previous ones. This can be used to implement -crossfading and the available operators can be extended in the future as -needed. - -A number of OpenGL-based video mixer elements (glvideomixer, glmixerbin, -glvideomixerelement, glstereomix, glmosaic) which are built on top of -GstVideoAggregator have also been moved from -bad to -base now. These -elements have been merged into the existing OpenGL plugin, so if you get -duplicate type registration warnings when upgrading, check that you -don’t have a stale openglmixers plugin lying about somewhere. +- FIXME Plugin removals The following plugins have been removed from gst-plugins-bad: -- The experimental daala plugin has been removed, since it’s not so - useful now that all effort is focused on AV1 instead, and it had to - be enabled explicitly with --enable-experimental anyway. - -- The spc plugin has been removed. It has been replaced by the gme - plugin. - -- The acmmp3dec and acmenc plugins for Windows have been removed. ACM - is an ancient legacy API and there was no point in keeping the - plugins around for a licensed MP3 decoder now that the MP3 patents - have expired and we have a decoder in -good. We also didn’t ship - these in our cerbero-built Windows packages, so it’s unlikely that - they’ll be missed. +- FIXME Miscellaneous API additions -- GstBitwriter: new generic bit writer API to complement the existing - bit reader - -- gst_buffer_new_wrapped_bytes() creates a wrap buffer from a GBytes - -- gst_caps_set_features_simple() sets a caps feature on all the - structures of a GstCaps - -- New GST_QUERY_BITRATE query: This allows determining from downstream - what the expected bitrate of a stream may be which is useful in - queue2 for setting time based limits when upstream does not provide - timing information. tsdemux, qtdemux and matroskademux have basic - support for this query on their sink pads. - -- elements: there is a new “Hardware” class specifier. Elements - interacting with hardware devices should specify this classifier in - their element factory class metadata. This is useful to advertise as - one might need to put such elements into READY state to test if the - hardware is present in the system for example. - -- protection: Add a new definition for unspecified system protection, - GST_PROTECTION_UNSPECIFIED_SYSTEM_ID - -- take functions for various mini objects that didn’t have them yet: - gst_query_take(), gst_message_take(), gst_tag_list_take(), - gst_buffer_list_take(). Unlike the various _replace() functions - _take() does not increase the reference count but takes ownership of - the mini object passed. - -- clear functions for various mini object types and GstObject which - unrefs the object or mini object (if non-NULL) and sets the variable - pointed to to NULL: gst_clear_structure(), gst_clear_tag_list(), - gst_clear_query(), gst_clear_message(), gst_clear_event(), - gst_clear_caps(), gst_clear_buffer_list(), gst_clear_buffer(), - gst_clear_mini_object(), gst_clear_object() - -- miniobject: new API gst_mini_object_add_parent() and - gst_mini_object_remove_parent() to set parent pointers on mini - objects to ensure correct writability: Every container of - miniobjects now needs to store itself as parent in the child object, - and remove itself again later. A mini object is then only writable - if there is at most one parent, that parent is writable itself, and - the reference count of the mini object is 1. GstBuffer (for - memories), GstBufferList (for buffers), GstSample (for caps, buffer, - bufferlist), and GstVideoOverlayComposition were updated - accordingly. Without this it was possible to have e.g. a buffer list - with a refcount of 2 used in two places at once that both modify the - same buffer with refcount 1 at the same time wrongly thinking it is - writable even though it’s really not. - -- poll: add API to watch for POLLPRI and stop treating POLLPRI as a - read. This is useful to wait for video4linux events which are - signalled via POLLPRI. - -- sample: new API to update the contents of a GstSample and make it - writable: gst_sample_set_buffer(), gst_sample_set_caps(), - gst_sample_set_segment(), gst_sample_set_info(), plus - gst_sample_is_writable() and gst_sample_make_writable(). This makes - it possible to reuse a sample object and avoid unnecessary memory - allocations, for example in appsink. - -- ClockIDs now keep a weak reference to underlying clock to avoid - crashes in basesink in corner cases where a clock goes away while - the ClockID is still in use, plus some new API - (gst_clock_id_get_clock(), gst_clock_id_uses_clock()) to check the - clock a ClockID is linked to. - -- The GstCheck unit test library gained a - fail_unless_equals_clocktime() convenience macro as well as some new - GstHarness API for for proposing meta APIs from the allocation - query: gst_harness_add_propose_allocation_meta(). ASSERT_CRITICAL() - checks in unit tests are now skipped if GStreamer was compiled with - GST_DISABLE_GLIB_CHECKS. - -- gst_audio_buffer_truncate() convenience function to truncate a raw - audio buffer - -- GstDiscoverer has support for caching the results of discovery in - the default cache directory. This can be enabled with the use-cache - property and is disabled by default. - -- GstMeta that are attached to GstBuffers are now always stored in the - order in which they were added. - -- Additional support for signalling ONVIF specific features were - added: the SEEK event can store a trickmode-interval now and support - for the Rate-Control and Frames RTSP headers was added to the RTSP - library. +- FIXME Miscellaneous performance and memory optimisations As always there have been many performance and memory usage improvements -across all components and modules. Some of them (such as dmabuf -import/export) have already been mentioned elsewhere so won’t be -repeated here. +across all components and modules. Some of them have already been +mentioned elsewhere so won’t be repeated here. The following list is only a small snapshot of some of the more interesting optimisations that haven’t been mentioned in other contexts yet: -- The GstVideoEncoder and GstVideoDecoder base classes now release the - STREAM_LOCK when pushing out buffers, which means (multi-threaded) - encoders and decoders can now receive and continue to process input - buffers whilst waiting for downstream elements in the pipeline to - process the buffer that was pushed out. This increases throughput - and reduces processing latency, also and especially for - hardware-accelerated encoder/decoder elements. - -- GstQueueArray has seen a few API additions - (gst_queue_array_peek_nth(), gst_queue_array_set_clear_func(), - gst_queue_array_clear()) so that it can be used in other places like - GstAdapter instead of a GList, which reduces allocations and - improves performance. - -- appsink now reuses the sample object in pull_sample() if possible - -- rtpsession only starts the RTCP thread when it’s actually needed now - -- udpsrc uses a buffer pool now and the GstUdpSrc object structure was - optimised for better cache performance +- FIXME GstPlayer -- API was added to fine-tune the synchronisation offset between - subtitles and video +- FIXME Miscellaneous changes -- As a result of moving to newer FFmpeg APIs, encoder and decoder - elements exposed by the GStreamer FFmpeg wrapper plugin (gst-libav) - may have seen possibly incompatible changes to property names and/or - types, and not all properties exposed might be functional. We are - still reviewing the new properties and aim to minimise breaking - changes at least for the most commonly-used properties, so please - report any issues you run into! +- FIXME OpenGL integration -- The OpenGL mixer elements have been moved from -bad to - gst-plugins-base (see above) - -- The Mesa GBM backend now supports headless mode - -- gloverlaycompositor: New OpenGL-based compositor element that - flattens any overlays from GstVideoOverlayCompositionMetas into the - video stream. - -- glalpha: New element that adds an alpha channel to a video stream. - The values of the alpha channel can either be set to a constant or - can be dynamically calculated via chroma keying. It is similar to - the existing alpha element but based on OpenGL. Calculations are - done in floating point so results may not be identical to the output - of the existing alpha element. - -- glupload: Implement direct dmabuf uploader, the idea being that some - GPUs (like the Vivante series) can actually perform the YUV->RGB - conversion internally, so no custom conversion shaders are needed. - To make use of this feature, we need an additional uploader that can - import DMABUF FDs and also directly pass the pixel format, relying - on the GPU to do the conversion. - -- The OpenGL library no longer restores the OpenGL viewport. This is a - performance optimization to not require performing multiple - expensive glGet*() function calls per frame. This affects any - application or plugin use of the following functions and objects: - - glcolorconvert library object (not the element) - - glviewconvert library object (not the element) - - gst_gl_framebuffer_draw_to_texture() - - custom GstGLWindow implementations +- FIXME Tracing framework and debugging improvements -- There is now a GDB PRETTY PRINTER FOR VARIOUS GSTREAMER TYPES: For - GstObject pointers the type and name is added, e.g. - 0x5555557e4110 [GstDecodeBin|decodebin0]. For GstMiniObject pointers - the object type is added, e.g. 0x7fffe001fc50 [GstBuffer]. For - GstClockTime and GstClockTimeDiff the time is also printed in human - readable form, e.g. 150116219955 [+0:02:30.116219955]. - -- GDB EXTENSION WITH TWO CUSTOM GDB COMMANDS gst-dot AND gst-print: - - - gst-dot creates dot files that a very close to what - GST_DEBUG_BIN_TO_DOT_FILE() produces, but object properties and - buffer contents such as codec-data in caps are not available. - - - gst-print produces high-level information about a GStreamer - object. This is currently limited to pads for GstElements and - events for the pads. The output may look like this: - -- gst_structure_to_string() now serialises the actual value of - pointers when serialising GstStructures instead of claiming they’re - NULL. This makes debug logging in various places less confusing, - because it’s clear now that structure fields actually hold valid - objects. Such object pointer values will never be deserialised - however. +- FIXME Tools -- gst-inspect-1.0 has coloured output now and will automatically use a - pager if the output does not fit on a page. This only works in a - UNIX environment and if the output is not piped, and on Windows 10 - build 16257 or newer. If you don’t like the colours you can disable - them by setting the GST_INSPECT_NO_COLORS=1 environment variable or - passing the --no-color command line option. +- FIXME GStreamer RTSP server -- Improved backlog handling when using TCP interleaved for data - transport. Before there was a fixed maximum size for backlog - messages, which was prone to deadlocks and made it difficult to - control memory usage with the watch backlog. The RTSP server now - limits queued TCP data messages to one per stream, moving queuing of - the data into the pipeline and leaving the RTSP connection - responsive to RTSP messages in both directions, preventing all those - problems. - -- Initial ULP Forward Error Correction support in rtspclientsink and - for RECORD mode in the server. - -- API to explicitly enable retransmission requests (RTX) - -- Lots of multicast-related fixes - -- rtsp-auth: Add support for parsing .htdigest files +- FIXME GStreamer VAAPI -- Support Wayland’s display for context sharing, so the application - can pass its own wl_display in order to be used for the VAAPI - display creation. - -- A lot of work to support new Intel hardware using media-driver as VA - backend. - -- For non-x86 devices, VAAPI display can instantiate, through DRM, - with no PCI bus. This enables the usage of libva-v4l2-request - driver. - -- Added support for XDG-shell protocol as wl_shell replacement which - is currently deprecated. This change add as dependency - wayland-protocol. - -- GstVaapiFilter, GstVaapiWindow, and GstVaapiDecoder classes now - inherit from GstObject, gaining all the GStreamer’s instrumentation - support. - -- The metadata now specifies the plugin as Hardware class. - -- H264 decoder is more stable with problematic streams. - -- In H265 decoder added support for profiles main-422-10 (P010_10LE), - main-444 (AYUV) and main-444-10 (Y410) - -- JPEG decoder handles dynamic resolution changes. - -- More specification adherence in H264 and H265 encoders. +- FIXME GStreamer OMX -- Add support of NV16 format to video encoders input. - -- Video decoders now handle the ALLOCATION query to tell upstream - about the number of buffers they require. Video encoders will also - use this query to adjust their number of allocated buffers - preventing starvation when using dynamic buffer mode. - -- The OMX_PERFORMANCE debug category has been renamed to OMX_API_TRACE - and can now be used to track a widder variety of interactions - between OMX and GStreamer. - -- Video encoders will now detect frame rate only changes and will - inform OMX about it rather than doing a full format reset. - -- Various Zynq UltraScale+ specific improvements: - - Video encoders are now able to import dmabuf from upstream. - - Support for HEVC range extension profiles and more AVC profiles. - - We can now request video encoders to generate an IDR using the - force key unit event. +- FIXME GStreamer Editing Services and NLE -- Added a gesdemux element, it is an auto pluggable element that - allows decoding edit list like files supported by GES - -- Added gessrc which wraps a GESTimeline as a standard source element - (implementing the ges protocol handler) - -- Added basic support for videorate::rate property potentially - allowing changing playback speed - -- Layer priority is now fully automatic and they should be moved with - the new ges_timeline_move_layer method, ges_layer_set_priority is - now deprecated. - -- Added a ges_timeline_element_get_layer_priority so we can simply get - all information about GESTimelineElement position in the timeline - -- GESVideoSource now auto orientates the images if it is defined in a - meta (overridable). - -- Added some PyGObject overrides to make the API more pythonic - -- The threading model has been made more explicit with safe guard to - make sure not thread safe APIs are not used from the wrong threads. - It is also now possible to properly handle in what thread the API - should be used. - -- Optimized GESClip and GESTrackElement creation - -- Added a way to compile out the old, unused and deprecated - GESPitiviFormatter - -- Re implemented the timeline editing API making it faster and making - the code much more maintainable - -- Simplified usage of nlecomposition outside GES by removing quirks in - it API usage and removing the need to treat it specially from an - application perspective. - -- ges-launch-1.0: - - - Added support to add titles to the timeline - - Enhance the help auto generating it from the code - -- Deprecate ges_timeline_load_from_uri as loading the timeline should - be done through a project now - -- MANY leaks have been plugged and the unit testsuite is now “leak - free” +- FIXME GStreamer validate -- Added an action type to verify the checksum of the sink last-sample - -- Added an include keyword to validate scenarios - -- Added the notion of variable in scenarios, with the set-vars keyword - -- Started adding support for “performance” like tests by allowing to - define the number of dropped buffers or the minimum buffer frequency - on a specific pad - -- Added a validateflow plugin which allows defining the data flow to - be seen on a particular pad and verifying that following runs match - the expectations - -- Added support for appsrc based test definition so we can instrument - the data pushed into the pipeline from scenarios - -- Added a mockdecryptor allowing adding tests with on encrypted files, - the element will potentially be instrumented with a validate - scenario - -- gst-validate-launcher: - - - Cleaned up output - - - Changed the default for “muting” tests as user doesn’t expect - hundreds of windows to show up when running the testsuite - - - Fixed the outputted xunit files to be compatible with GitLab - - - Added support to run tests on media files in push mode (using - pushfile://) - - - Added support for running inside gst-build - - - Added support for running ssim tests on rendered files - - - Added a way to simply define tests on pipelines through a simple - .json file - - - Added a python app to easily run python testsuite reusing all - the launcher features - - - Added flatpak knowledge so we can print backtrace even when - running from within flatpak - - - Added a way to automatically generated “known issues” - suppressions lines - - - Added a way to rerun tests to check if they are flaky and added - a way to tolerate tests known to be flaky - - - Add a way to output html log files +- FIXME GStreamer Python Bindings -- add binding for gst_pad_set_caps() - -- pygobject dependency requirement was bumped to >= 3.8 - -- new audiotestsrc, audioplot, and mixer plugin examples, and a - dynamic pipeline example +- FIXME GStreamer C# Bindings -- bindings for the GstWebRTC library +- FIXME GStreamer Rust Bindings -The GStreamer Rust bindings are now officially part of the GStreamer -project and are also maintained in the GStreamer GitLab. - -The releases will generally not be synchronized with the releases of -other GStreamer parts due to dependencies on other projects. - -Also unlike the other GStreamer libraries, the bindings will not commit -to full API stability but instead will follow the approach that is -generally taken by Rust projects, e.g.: - -1) 0.12.X will be completely API compatible with all other 0.12.Y - versions. -2) 0.12.X+1 will contain bugfixes and compatible new feature additions. -3) 0.13.0 will _not_ be backwards compatible with 0.12.X but projects - will be able to stay at 0.12.X without any problems as long as they - don’t need newer features. - -The current stable release is 0.12.2 and the next release series will be -0.13, probably around March 2019. - -At this point the bindings cover most of GStreamer core (except for most -notably GstAllocator and GstMemory), and most parts of the app, audio, -base, check, editing-services, gl, net. pbutils, player, rtsp, -rtsp-server, sdp, video and webrtc libraries. - -Also included is support for creating subclasses of the following types -and writing GStreamer plugins: - -- gst::Element -- gst::Bin and gst::Pipeline -- gst::URIHandler and gst::ChildProxy -- gst::Pad, gst::GhostPad -- gst_base::Aggregator and gst_base::AggregatorPad -- gst_base::BaseSrc and gst_base::BaseSink -- gst_base::BaseTransform - -Changes to 0.12.X since 0.12.0 - -Fixed - -- PTP clock constructor actually creates a PTP instead of NTP clock - -Added - -- Bindings for GStreamer Editing Services -- Bindings for GStreamer Check testing library -- Bindings for the encoding profile API (encodebin) - -- VideoFrame, VideoInfo, AudioInfo, StructureRef implements Send and - Sync now -- VideoFrame has a function to get the raw FFI pointer -- From impls from the Error/Success enums to the combined enums like - FlowReturn -- Bin-to-dot file functions were added to the Bin trait -- gst_base::Adapter implements SendUnique now -- More complete bindings for the gst_video::VideoOverlay interface, - especially - gst_video::is_video_overlay_prepare_window_handle_message() - -Changed - -- All references were updated from GitHub to freedesktop.org GitLab -- Fix various links in the README.md -- Link to the correct location for the documentation -- Remove GitLab badge as that only works with gitlab.com currently - -Changes in git master for 0.13 - -Fixed - -- gst::tag::Album is the album tag now instead of artist sortname - -Added - -- Subclassing infrastructure was moved directly into the bindings, - making the gst-plugin crate deprecated. This involves many API - changes but generally cleans up code and makes it more flexible. - Take a look at the gst-plugins-rs crate for various examples. - -- Bindings for CapsFeatures and Meta -- Bindings for - ParentBufferMeta,VideoMetaandVideoOverlayCompositionMeta` -- Bindings for VideoOverlayComposition and VideoOverlayRectangle -- Bindings for VideoTimeCode - -- UniqueFlowCombiner and UniqueAdapter wrappers that make use of the - Rust compile-time mutability checks and expose more API in a safe - way, and as a side-effect implement Sync and Send now - -- More complete bindings for Allocation Query -- pbutils functions for codec descriptions -- TagList::iter() for iterating over all tags while getting a single - value per tag. The old ::iter_tag_list() function was renamed to - ::iter_generic() and still provides access to each value for a tag -- Bus::iter() and Bus::iter_timed() iterators around the corresponding - ::pop\*() functions - -- serde serialization of Value can also handle Buffer now - -- Extensive comments to all examples with explanations -- Transmuxing example showing how to use typefind, multiqueue and - dynamic pads -- basic-tutorial-12 was ported and added - -Changed - -- Rust 1.31 is the minimum supported Rust version now -- Update to latest gir code generator and glib bindings - -- Functions returning e.g. gst::FlowReturn or other “combined” enums - were changed to return split enums like - Result to allow usage of the - standard Rust error handling. - -- MiniObject subclasses are now newtype wrappers around the underlying - GstRc wrapper. This does not change the API in any breaking - way for the current usages, but allows MiniObjects to also be - implemented in other crates and makes sure rustdoc places the - documentation in the right places. - -- BinExt extension trait was renamed to GstBinExt to prevent conflicts - with gtk::Bin if both are imported - -- Buffer::from_slice() can’t possible return None - -- Various clippy warnings +- FIXME GStreamer Rust Plugins -Like the GStreamer Rust bindings, the Rust plugins are now officially -part of the GStreamer project and are also maintained in the GStreamer -GitLab. - -In the 0.3.x versions this contained infrastructure for writing -GStreamer plugins in Rust, and a set of plugins. - -In git master that infrastructure was moved to the GLib and GStreamer -bindings directly, together with many other improvements that were made -possible by this, so the gst-plugins-rs repository only contains -GStreamer elements now. - -Elements included are: - -- Tutorials plugin: identity, rgb2gray and sinesrc with extensive - comments - -- rsaudioecho, a port of the audiofx element - -- rsfilesrc, rsfilesink - -- rsflvdemux, a FLV demuxer. Not feature-equivalent with flvdemux yet - -- threadshare plugin: ts-appsrc, ts-proxysrc/sink, ts-queue, ts-udpsrc - and ts-tcpclientsrc elements that use a fixed number of threads and - share them between instances. For more background about these - elements see Sebastian’s talk “When adding more threads adds more - problems - Thread-sharing between elements in GStreamer” at the - GStreamer Conference 2017. - -- rshttpsrc, a HTTP source around the hyper/reqwest Rust libraries. - Not feature-equivalent with souphttpsrc yet. - -- togglerecord, an element that allows to start/stop recording at any - time and keeps all audio/video streams in sync. - -- mccparse and mccenc, parsers and encoders for the MCC closed caption - file format. - -Changes to 0.3.X since 0.3.0 - -- All references were updated from GitHub to freedesktop.org GitLab -- Fix various links in the README.md -- Link to the correct location for the documentation - -Changes in git master for 0.4 - -- togglerecord: Switch to parking_lot crate for mutexes/condition - variables for lower overhead -- Merge threadshare plugin here -- New closedcaption plugin with mccparse and mccenc elements -- New identity element for the tutorials plugin - -- Register plugins statically in tests instead of relying on the - plugin loader to find the shared library in a specific place - -- Update to the latest API changes in the GLib and GStreamer bindings -- Update to the latest versions of all crates +- FIXME Build and Dependencies -- The MESON BUILD SYSTEM BUILD IS NOW FEATURE-COMPLETE (*) and it is - now the recommended build system on all platforms and also used by - Cerbero to build GStreamer on all platforms. The Autotools build is - scheduled to be removed in the next cycle. Developers who currently - use gst-uninstalled should move to gst-build. The build option - naming has been cleaned up and made consistent and there are now - feature options to enable/disable plugins and various other features - on a case-by-case basis. (*) with the exception of plugin docs which - will be handled differently in future +- The Autotools build system has finally been removed in favour of the + Meson build system. Developers who currently use gst-uninstalled + should move to gst-build. -- Symbol export in libraries is now controlled via explicit exports - using symbol visibility or export defines where supported, to ensure - consistency across all platforms. This also allows libraries to have - exports that vary based on detected platform features and configure - options as is the case with the GStreamer OpenGL integration library - for example. A few symbols that had been exported by accident in - earlier versions may no longer be exported. These symbols will not - have had declarations in any public header files then though and - would not have been usable. +- API and plugin documentation are no longer built with gtk_doc. The + gtk_doc documentation has been removed in favour of a new unified + documentation module built with hotdoc. The intention is to + distribute the generated documentation in form of tarballs alongside + releases. -- The GStreamer FFmpeg wrapper plugin (gst-libav) now depends on - FFmpeg 4.x and uses the new FFmpeg 4.x API and stopped relying on - ancient API that was removed with the FFmpeg 4.x release. This means - that it is no longer possible to build this module against an older - system-provided FFmpeg 3.x version. Use the internal FFmpeg 4.x copy - instead if you build using autotools, or use gst-libav 1.14.x - instead which targets the FFmpeg 3.x API and _should_ work fine in - combination with a newer GStreamer. It’s difficult for us to support - both old and new FFmpeg APIs at the same time, apologies for any - inconvenience caused. - -- Hardware-accelerated Nvidia video encoder/decoder plugins nvdec and - nvenc can be built against CUDA Toolkit versions 9 and 10.0 now. The - dynlink interface has been dropped since it’s deprecated in 10.0. - -- The (optional) OpenCV requirement has been bumped to >= 3.0.0 and - the plugin can also be built against OpenCV 4.x now. - -- New sctp plugin based on usrsctp (for WebRTC data channels) +- FIXME Cerbero @@ -1172,221 +175,66 @@ Windows, Android, iOS and macOS. Cerbero has seen a number of improvements: -- Cerbero has been ported to Python 3 and requires Python 3.5 or newer - now - -- Source tarballs are now protected by checksums in the recipes to - guard against download errors and malicious takeover of projects or - websites. In addition, downloads are only allowed via secure - transports now and plain HTTP, FTP and git:// transports are not - allowed anymore. - -- There is now a new fetch-bootstrap command which downloads sources - required for bootstrapping, with an optional --build-tools-only - argument to match the bootstrap --build-tools-only command. - -- The bootstrap, build, package and bundle-source commands gained a - new --offline switch that ensures that only sources from the cache - are used and never downloaded via the network. This is useful in - combination with the fetch and fetch-bootstrap commands that acquire - sources ahead of time before any build steps are executed. This - allows more control over the sources used and when sources are - updated, and is particularly useful for build environments that - don’t have network access. - -- bootstrap --assume-yes will automatically say ‘yes’ to any - interactive prompts during the bootstrap stage, such as those from - apt-get or yum. - -- bootstrap --system-only will only bootstrap the system without build - tools. - -- Manifest support: The build manifest can be used in continuous - integration (CI) systems to fixate the Git revision of certain - projects so that all builds of a pipeline are on the same reference. - This is used in GStreamer’s gitlab CI for example. It can also be - used in order to re-produce a specific build. To set a manifest, you - can set manifest = 'my_manifest.xml' in your configuration file, or - use the --manifest command line option. The command line option will - take precendence over anything specific in the configuration file. - -- The new build-deps command can be used to build only the - dependencies of a recipe, without the recipe itself. - -- new --list-variants command to list available variants - -- variants can now be set on the command line via the -v option as a - comma-separated list. This overrides any variants set in any - configuration files. - -- new qt5, intelmsdk and nvidia variants for enabling Qt5 and hardware - codec support. See the Enabling Optional Features with Variants - section in the Cerbero documentation for more details how to enable - and use these variants. - -- A new -t / --timestamp command line switch makes commands print - timestamps +- FIXME Platform-specific changes and improvements Android -- toolchain: update compiler to clang and NDKr18. NDK r18 removed the - armv5 target and only has Android platforms that target at least - armv7 so the armv5 target is not useful anymore. - -- The way that GIO modules are named has changed due to upstream GLib - natively adding support for loading static GIO modules. This means - that any GStreamer application using gnutls for SSL/TLS on the - Android or iOS platforms (or any other setup using static libraries) - will fail to link looking for the g_io_module_gnutls_load_static() - function. The new function name is now - g_io_gnutls_load(gpointer data). data can be NULL for a static - library. Look at this commit for the necessary change in the - examples. - -- various build issues on Android have been fixed. +- FIXME macOS and iOS -- various build issues on iOS have been fixed. - -- the minimum required iOS version is now 9.0. The difference in - adoption between 8.0 and 9.0 is 0.1% and the bump to 9.0 fixes some - build issues. - -- The way that GIO modules are named has changed due to upstream GLib - natively adding support for loading static GIO modules. This means - that any GStreamer application using gnutls for SSL/TLS on the - Android or iOS platforms (or any other setup using static libraries) - will fail to link looking for the g_io_module_gnutls_load_static() - function. The new function name is now - g_io_gnutls_load(gpointer data). data can be NULL for a static - library. Look at this commit for the necessary change in the - examples. +- FIXME Windows -- The webrtcdsp element is shipped again as part of the Windows binary - packages, the build system issue has been resolved. +- toolchain upgrade -- ‘Inconsistent DLL linkage’ warnings when building with MSVC have - been fixed - -- Hardware-accelerated Nvidia video encoder/decoder plugins nvdec and - nvenc build on Windows now, also with MSVC and using Meson. - -- The ksvideosrc camera capture plugin supports 16-bit grayscale video - now - -- The wasapisrc audio capture element implements loopback recording - from another output device or sink - -- wasapisink recover from low buffer levels in shared mode and some - exclusive mode fixes - -- dshowsrc now implements the GstDeviceMonitor interface +- FIXME Contributors -Aaron Boxer, Aleix Conchillo Flaqué, Alessandro Decina, Alexandru Băluț, -Alex Ashley, Alexey Chernov, Alicia Boya García, Amit Pandya, Andoni -Morales Alastruey, Andreas Frisch, Andre McCurdy, Andy Green, Anthony -Violo, Antoine Jacoutot, Antonio Ospite, Arun Raghavan, Aurelien Jarno, -Aurélien Zanelli, ayaka, Bananahemic, Bastian Köcher, Branko Subasic, -Brendan Shanks, Carlos Rafael Giani, Charlie Turner, Christoph Reiter, -Corentin Noël, Daeseok Youn, Damian Vicino, Dan Kegel, Daniel Drake, -Daniel Klamt, Danilo Spinella, Dardo D Kleiner, David Ing, David -Svensson Fors, Devarsh Thakkar, Dimitrios Katsaros, Edward Hervey, -Emilio Pozuelo Monfort, Enrique Ocaña González, Erlend Eriksen, Ezequiel -Garcia, Fabien Dessenne, Fabrizio Gennari, Florent Thiéry, Francisco -Velazquez, Freyr666, Garima Gaur, Gary Bisson, George Kiagiadakis, Georg -Lippitsch, Georg Ottinger, Geunsik Lim, Göran Jönsson, Guillaume -Desmottes, H1Gdev, Haihao Xiang, Haihua Hu, Harshad Khedkar, Havard -Graff, He Junyan, Hoonhee Lee, Hosang Lee, Hyunjun Ko, Ilya Smelykh, -Ingo Randolf, Iñigo Huguet, Jakub Adam, James Stevenson, Jan Alexander -Steffens, Jan Schmidt, Jerome Laheurte, Jimmy Ohn, Joakim Johansson, -Jochen Henneberg, Johan Bjäreholt, John-Mark Bell, John Bassett, John -Nikolaides, Jonathan Karlsson, Jonny Lamb, Jordan Petridis, Josep Torra, -Joshua M. Doe, Jos van Egmond, Juan Navarro, Julian Bouzas, Jun Xie, -Junyan He, Justin Kim, Kai Kang, Kim Tae Soo, Kirill Marinushkin, Kyrylo -Polezhaiev, Lars Petter Endresen, Linus Svensson, Louis-Francis -Ratté-Boulianne, Lucas Stach, Luis de Bethencourt, Luz Paz, Lyon Wang, -Maciej Wolny, Marc-André Lureau, Marc Leeman, Marco Trevisan (Treviño), -Marcos Kintschner, Marian Mihailescu, Marinus Schraal, Mark Nauwelaerts, -Marouen Ghodhbane, Martin Kelly, Matej Knopp, Mathieu Duponchelle, -Matteo Valdina, Matthew Waters, Matthias Fend, memeka, Michael Drake, -Michael Gruner, Michael Olbrich, Michael Tretter, Miguel Paris, Mike -Wey, Mikhail Fludkov, Naveen Cherukuri, Nicola Murino, Nicolas Dufresne, -Niels De Graef, Nirbheek Chauhan, Norbert Wesp, Ognyan Tonchev, Olivier -Crête, Omar Akkila, Pat DeSantis, Patricia Muscalu, Patrick Radizi, -Patrik Nilsson, Paul Kocialkowski, Per Forlin, Peter Körner, Peter -Seiderer, Petr Kulhavy, Philippe Normand, Philippe Renon, Philipp Zabel, -Pierre Labastie, Piotr Drąg, Roland Jon, Roman Sivriver, Roman Shpuntov, -Rosen Penev, Russel Winder, Sam Gigliotti, Santiago Carot-Nemesio, -Sean-Der, Sebastian Dröge, Seungha Yang, Shi Yan, Sjoerd Simons, Snir -Sheriber, Song Bing, Soon, Thean Siew, Sreerenj Balachandran, Stefan -Ringel, Stephane Cerveau, Stian Selnes, Suhas Nayak, Takeshi Sato, -Thiago Santos, Thibault Saunier, Thomas Bluemel, Tianhao Liu, -Tim-Philipp Müller, Tobias Ronge, Tomasz Andrzejak, Tomislav Tustonić, -U. Artie Eoff, Ulf Olsson, Varunkumar Allagadapa, Víctor Guzmán, Víctor -Manuel Jáquez Leal, Vincenzo Bono, Vineeth T M, Vivia Nikolaidou, Wang -Fei, wangzq, Whoopie, Wim Taymans, Wind Yuan, Wonchul Lee, Xabier -Rodriguez Calvar, Xavier Claessens, Haihao Xiang, Yacine Bandou, -Yeongjin Jeong, Yuji Kuwabara, Zeeshan Ali, +- FIXME … and many others who have contributed bug reports, translations, sent suggestions or helped testing. -Stable 1.16 branch +Stable 1.18 branch -After the 1.16.0 release there will be several 1.16.x bug-fix releases +After the 1.18.0 release there will be several 1.18.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.16.x bug-fix releases will be made from -the git 1.16 branch, which is a stable branch. +a bug-fix release usually. The 1.18.x bug-fix releases will be made from +the git 1.18 branch, which will be a stable branch. -1.16.0 +1.18.0 -1.16.0 was released on 19 April 2019. +1.18.0 has not been released yet. Known Issues -- possibly breaking/incompatible changes to properties of wrapped - FFmpeg decoders and encoders (see above). - -- The way that GIO modules are named has changed due to upstream GLib - natively adding support for loading static GIO modules. This means - that any GStreamer application using gnutls for SSL/TLS on the - Android or iOS platforms (or any other setup using static libraries) - will fail to link looking for the g_io_module_gnutls_load_static() - function. The new function name is now - g_io_gnutls_load(gpointer data). See Android/iOS sections above for - further details. +- FIXME -Schedule for 1.18 +Schedule for 1.20 -Our next major feature release will be 1.18, and 1.17 will be the -unstable development version leading up to the stable 1.18 release. The -development of 1.17/1.18 will happen in the git master branch. +Our next major feature release will be 1.20, and 1.19 will be the +unstable development version leading up to the stable 1.20 release. The +development of 1.19/1.20 will happen in the git master branch. -The plan for the 1.18 development cycle is yet to be confirmed, but it -is possible that the next cycle will be a short one in which case -feature freeze would be perhaps around August 2019 with a new 1.18 -stable release in September. +The plan for the 1.20 development cycle is yet to be confirmed. -1.18 will be backwards-compatible to the stable 1.16, 1.14, 1.12, 1.10, -1.8, 1.6, 1.4, 1.2 and 1.0 release series. +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. ------------------------------------------------------------------------ _These release notes have been prepared by Tim-Philipp Müller with_ -_contributions from Sebastian Dröge, Guillaume Desmottes, Matthew -Waters, _ _Thibault Saunier, and Víctor Manuel Jáquez Leal._ +_contributions from … (FIXME)_ _License: CC BY-SA 4.0_ diff --git a/RELEASE b/RELEASE index ff7af00d86..bec2e6549d 100644 --- a/RELEASE +++ b/RELEASE @@ -1,18 +1,15 @@ -This is GStreamer gstreamer-vaapi 1.17.0.1. +This is GStreamer gstreamer-vaapi 1.17.1. -The GStreamer team is thrilled to announce a new major feature release in the -stable 1.0 API series of your favourite cross-platform multimedia framework! +GStreamer 1.17 is the development branch leading up to the next major +stable version which will be 1.18. -As always, this release is again packed with new features, bug fixes and -other improvements. - -The 1.16 release series adds new features on top of the 1.14 series and is +The 1.17 development series adds new features on top of the 1.16 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.16/ + https://gstreamer.freedesktop.org/releases/1.18/ Binaries for Android, iOS, Mac OS X and Windows will usually be provided shortly after the release. @@ -60,7 +57,7 @@ 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://cgit.freedesktop.org/gstreamer/gstreamer/ +https://gitlab.freedesktop.org/gstreamer/ ==== Homepage ==== diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index a4b046f540..7db1445194 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -14,7 +14,7 @@ - + C @@ -25,6 +25,16 @@ + + + 1.17.1 + master + + 2020-06-19 + + + + 1.16.0 diff --git a/meson.build b/meson.build index e9e64a1a51..4a5c72f736 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.17.0.1', + version : '1.17.1', meson_version : '>= 0.48.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 74ac6ed91f24db754ad9c50ef3d7df688690e087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 20 Jun 2020 00:28:35 +0100 Subject: [PATCH 3631/3781] Back to development --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 4a5c72f736..4b7275414b 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.17.1', + version : '1.17.1.1', meson_version : '>= 0.48.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From eb7152bdefd97be415ae70737fc20a1d223744df Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Fri, 19 Jun 2020 23:34:11 -0400 Subject: [PATCH 3632/3781] doc: Stop documenting properties from parents --- docs/gst_plugins_cache.json | 321 +----------------------------------- 1 file changed, 4 insertions(+), 317 deletions(-) diff --git a/docs/gst_plugins_cache.json b/docs/gst_plugins_cache.json index cab02a42f5..2ffd1d231f 100644 --- a/docs/gst_plugins_cache.json +++ b/docs/gst_plugins_cache.json @@ -31,18 +31,6 @@ } }, "properties": { - "async-handling": { - "blurb": "The bin will handle Asynchronous state changes", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, "deinterlace-method": { "blurb": "Deinterlace method to use", "conditionally-available": false, @@ -108,18 +96,6 @@ "readable": true, "type": "guint64", "writable": true - }, - "message-forward": { - "blurb": "Forwards all children messages", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true } }, "rank": "primary + 2" @@ -173,18 +149,6 @@ "readable": true, "type": "gboolean", "writable": true - }, - "qos": { - "blurb": "Handle Quality-of-Service events from downstream", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true } }, "rank": "primary" @@ -365,20 +329,6 @@ "type": "GstVaapiEncoderMbbrc", "writable": true }, - "min-force-key-unit-interval": { - "blurb": "Minimum interval between force-keyunit requests in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, "min-qp": { "blurb": "Minimum quantizer value", "conditionally-available": false, @@ -433,18 +383,6 @@ "type": "GstVaapiEncoderH264PredictionType", "writable": true }, - "qos": { - "blurb": "Handle Quality-of-Service events from downstream", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, "qp-ib": { "blurb": "Difference of QP between I and B frame (available only on CQP)", "conditionally-available": false, @@ -618,17 +556,7 @@ "presence": "always" } }, - "properties": { - "qos": { - "blurb": "Handle Quality-of-Service events from downstream", - "construct": false, - "construct-only": false, - "default": "true", - "readable": true, - "type": "gboolean", - "writable": true - } - }, + "properties": {}, "rank": "primary" }, "vaapih265enc": { @@ -778,15 +706,6 @@ "type": "guint", "writable": true }, - "qos": { - "blurb": "Handle Quality-of-Service events from downstream", - "construct": false, - "construct-only": false, - "default": "false", - "readable": true, - "type": "gboolean", - "writable": true - }, "qp-ib": { "blurb": "Difference of QP between I and B frame (available only on CQP)", "construct": false, @@ -908,20 +827,7 @@ "presence": "always" } }, - "properties": { - "qos": { - "blurb": "Handle Quality-of-Service events from downstream", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - } - }, + "properties": {}, "rank": "marginal" }, "vaapimpeg2dec": { @@ -949,20 +855,7 @@ "presence": "always" } }, - "properties": { - "qos": { - "blurb": "Handle Quality-of-Service events from downstream", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - } - }, + "properties": {}, "rank": "primary" }, "vaapimpeg2enc": { @@ -1373,18 +1266,6 @@ "type": "gfloat", "writable": true }, - "qos": { - "blurb": "Handle Quality-of-Service events", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "false", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, "saturation": { "blurb": "The color saturation value", "conditionally-available": false, @@ -1507,32 +1388,6 @@ } }, "properties": { - "async": { - "blurb": "Go asynchronously to PAUSED", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "blocksize": { - "blurb": "Size in bytes to pull per buffer (0 = default)", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "4096", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - }, "brightness": { "blurb": "The display brightness value", "conditionally-available": false, @@ -1585,18 +1440,6 @@ "type": "gchararray", "writable": true }, - "enable-last-sample": { - "blurb": "Enable the last-sample property", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, "force-aspect-ratio": { "blurb": "When enabled, scaling will respect original aspect ratio", "conditionally-available": false, @@ -1635,85 +1478,6 @@ "type": "gfloat", "writable": true }, - "last-sample": { - "blurb": "The last sample received in the sink", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "mutable": "null", - "readable": true, - "type": "GstSample", - "writable": false - }, - "max-bitrate": { - "blurb": "The maximum bits per second to render (0 = disabled)", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "max-lateness": { - "blurb": "Maximum number of nanoseconds that a buffer can be late before it is dropped (-1 unlimited)", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "5000000", - "max": "9223372036854775807", - "min": "-1", - "mutable": "null", - "readable": true, - "type": "gint64", - "writable": true - }, - "processing-deadline": { - "blurb": "Maximum processing time for a buffer in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "15000000", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "qos": { - "blurb": "Generate Quality-of-Service events upstream", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "render-delay": { - "blurb": "Additional render delay of the sink in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, "rotation": { "blurb": "The display rotation mode", "conditionally-available": false, @@ -1740,18 +1504,6 @@ "type": "gfloat", "writable": true }, - "show-preroll-frame": { - "blurb": "Whether to render video frames during preroll", - "conditionally-available": false, - "construct": true, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, "signal-handoffs": { "blurb": "Send a signal after rendering the buffer", "conditionally-available": false, @@ -1764,58 +1516,6 @@ "type": "gboolean", "writable": true }, - "stats": { - "blurb": "Sink Statistics", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "application/x-gst-base-sink-stats, average-rate=(double)0, dropped=(guint64)0, rendered=(guint64)0;", - "mutable": "null", - "readable": true, - "type": "GstStructure", - "writable": false - }, - "sync": { - "blurb": "Sync on the clock", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - }, - "throttle-time": { - "blurb": "The time to keep between rendered buffers (0 = disabled)", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "18446744073709551615", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint64", - "writable": true - }, - "ts-offset": { - "blurb": "Timestamp offset in nanoseconds", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "0", - "max": "9223372036854775807", - "min": "-9223372036854775808", - "mutable": "null", - "readable": true, - "type": "gint64", - "writable": true - }, "view-id": { "blurb": "ID of the view component of interest to display", "conditionally-available": false, @@ -1870,20 +1570,7 @@ "presence": "always" } }, - "properties": { - "qos": { - "blurb": "Handle Quality-of-Service events from downstream", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "true", - "mutable": "null", - "readable": true, - "type": "gboolean", - "writable": true - } - }, + "properties": {}, "rank": "primary" } }, From d914f23268fa4a9c9b1d1c5b528e6dcc25b875bb Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Tue, 23 Jun 2020 00:07:57 +0200 Subject: [PATCH 3633/3781] meson: mark plugins cache target as always stale --- docs/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/meson.build b/docs/meson.build index b9ad138640..c6fe4a50d9 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -24,6 +24,7 @@ if plugins_cache_generator.found() 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') From 1c3facd2157549c19ddcb71a64de9f754f1499a0 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Tue, 23 Jun 2020 10:20:46 -0400 Subject: [PATCH 3634/3781] docs: Mark parent classes as plugin API --- docs/gst_plugins_cache.json | 102 ++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode.c | 2 + 2 files changed, 104 insertions(+) diff --git a/docs/gst_plugins_cache.json b/docs/gst_plugins_cache.json index 2ffd1d231f..8dc00b2a81 100644 --- a/docs/gst_plugins_cache.json +++ b/docs/gst_plugins_cache.json @@ -591,210 +591,298 @@ "properties": { "bitrate": { "blurb": "The desired bitrate expressed in kbps (0: auto-calculate)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "2048000", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "cpb-length": { "blurb": "Length of the CPB buffer in milliseconds", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1500", "max": "10000", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "default-roi-delta-qp": { "blurb": "The default delta-qp to apply to each Region of Interest(lower value means higher-quality, higher value means lower-quality)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "-10", "max": "10", "min": "-10", + "mutable": "null", "readable": true, "type": "gint", "writable": true }, "init-qp": { "blurb": "Initial quantizer value", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "26", "max": "51", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "keyframe-period": { "blurb": "Maximal distance between two keyframes (0: auto-calculate)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "30", "max": "-1", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "low-delay-b": { "blurb": "Transforms P frames into predictive B frames. Enable it when P frames are not supported.", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "max-bframes": { "blurb": "Number of B-frames between I and P", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "10", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "max-qp": { "blurb": "Maximum quantizer value", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "51", "max": "51", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "mbbrc": { "blurb": "Macroblock level Bitrate Control", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "auto (0)", + "mutable": "null", "readable": true, "type": "GstVaapiEncoderMbbrc", "writable": true }, "min-qp": { "blurb": "Minimum quantizer value", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1", "max": "51", "min": "0", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "num-slices": { "blurb": "Number of slices per frame", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1", "max": "200", "min": "1", + "mutable": "null", + "readable": true, + "type": "guint", + "writable": true + }, + "num-tile-cols": { + "blurb": "the number of columns for tile encoding", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "1", + "max": "20", + "min": "1", + "mutable": "null", + "readable": true, + "type": "guint", + "writable": true + }, + "num-tile-rows": { + "blurb": "the number of rows for tile encoding", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "1", + "max": "22", + "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "qp-ib": { "blurb": "Difference of QP between I and B frame (available only on CQP)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "51", "min": "-51", + "mutable": "null", "readable": true, "type": "gint", "writable": true }, "qp-ip": { "blurb": "Difference of QP between I and P frame (available only on CQP)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "0", "max": "51", "min": "-51", + "mutable": "null", "readable": true, "type": "gint", "writable": true }, "quality-factor": { "blurb": "quality factor for ICQ/QBVR bitrate control mode (lower value means higher quality, higher value means lower quality)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "26", "max": "51", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "quality-level": { "blurb": "Encoding Quality Level (lower value means higher-quality/slow-encode, higher value means lower-quality/fast-encode)", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "4", "max": "7", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "rate-control": { "blurb": "Rate control mode", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "cqp (1)", + "mutable": "null", "readable": true, "type": "GstVaapiRateControlH265", "writable": true }, "refs": { "blurb": "Number of reference frames", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "1", "max": "3", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "target-percentage": { "blurb": "The desired target percentage of bitrate for variable rate controls.", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "70", "max": "100", "min": "1", + "mutable": "null", "readable": true, "type": "guint", "writable": true }, "trellis": { "blurb": "The Trellis Quantization Method of Encoder", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "false", + "mutable": "null", "readable": true, "type": "gboolean", "writable": true }, "tune": { "blurb": "Encoder tuning option", + "conditionally-available": false, "construct": false, "construct-only": false, + "controllable": false, "default": "none (0)", + "mutable": "null", "readable": true, "type": "GstVaapiEncoderTuneH265", "writable": true @@ -1662,6 +1750,20 @@ } ] }, + "GstVaapiEncode": { + "hierarchy": [ + "GstVaapiEncode", + "GstVideoEncoder", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "interfaces": [ + "GstPreset" + ], + "kind": "object" + }, "GstVaapiEncoderH264ComplianceMode": { "kind": "enum", "values": [ diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 7671170d42..eacf13c3d9 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -882,6 +882,8 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass) venc_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapiencode_src_query); venc_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapiencode_sink_query); + + gst_type_mark_as_plugin_api (GST_TYPE_VAAPIENCODE, 0); } /* Only used by the drived class */ From f6771f9bf334c951c2f6e87f036b462917e5523b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 3 Jul 2020 00:36:40 +0100 Subject: [PATCH 3635/3781] Release 1.17.2 --- ChangeLog | 32 ++++++++++++++++++++++++++++++++ NEWS | 4 ++-- RELEASE | 2 +- gstreamer-vaapi.doap | 10 ++++++++++ meson.build | 2 +- 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 92a037ee14..1eb35927bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +=== release 1.17.2 === + +2020-07-03 00:36:40 +0100 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * RELEASE: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.17.2 + +2020-06-23 10:20:46 -0400 Thibault Saunier + + * docs/gst_plugins_cache.json: + * gst/vaapi/gstvaapiencode.c: + docs: Mark parent classes as plugin API + +2020-06-23 00:07:57 +0200 Mathieu Duponchelle + + * docs/meson.build: + meson: mark plugins cache target as always stale + +2020-06-19 23:34:11 -0400 Thibault Saunier + + * docs/gst_plugins_cache.json: + doc: Stop documenting properties from parents + +2020-06-20 00:28:35 +0100 Tim-Philipp Müller + + * meson.build: + Back to development + === release 1.17.1 === 2020-06-19 19:27:11 +0100 Tim-Philipp Müller diff --git a/NEWS b/NEWS index a4e7232a19..39b682a8c8 100644 --- a/NEWS +++ b/NEWS @@ -11,7 +11,7 @@ in summer 2020 now. 1.17.x is the unstable development series that is currently being developed in the git master branch and which will eventually result in -1.18, and 1.17.1 is the current development release in that series. +1.18, and 1.17.2 is the current development release in that series. The schedule for the 1.18 development cycle is yet to be confirmed, but it is expected that feature freeze will be in June/July 2020, followed @@ -24,7 +24,7 @@ July/August 2020. See https://gstreamer.freedesktop.org/releases/1.18/ for the latest version of this document. -_Last updated: Thursday 18 June 2020, 16:00 UTC (log)_ +_Last updated: Wednesday 1 July 2020, 23:50 UTC (log)_ Introduction diff --git a/RELEASE b/RELEASE index bec2e6549d..e5146b3234 100644 --- a/RELEASE +++ b/RELEASE @@ -1,4 +1,4 @@ -This is GStreamer gstreamer-vaapi 1.17.1. +This is GStreamer gstreamer-vaapi 1.17.2. GStreamer 1.17 is the development branch leading up to the next major stable version which will be 1.18. diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 7db1445194..8994d0cec4 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.17.2 + master + + 2020-07-03 + + + + 1.17.1 diff --git a/meson.build b/meson.build index 4b7275414b..2aa126470e 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.17.1.1', + version : '1.17.2', meson_version : '>= 0.48.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 19903e1afcd58ed070235be333b3123d3a826e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 3 Jul 2020 02:04:14 +0100 Subject: [PATCH 3636/3781] Back to development --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 2aa126470e..4bb27ac5c1 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.17.2', + version : '1.17.2.1', meson_version : '>= 0.48.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From abea5e81c8fb314f1df7f2c37993174a343c2bb2 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 2 Jul 2020 19:19:35 +0800 Subject: [PATCH 3637/3781] libs: encoder: h265: no need to check the high compression tune. The h265 encoder just support tune mode: (0): none - None (3): low-power - Low power mode So, no need to check and set the high compression parameters. And by the way, the current ensure_tuning_high_compression manner of choosing the hightest profile idc as the best compression profile is not correct. Unlike h264, in h265 the higher profile idc number does not mean it has more compression tools, and so it has better compression performance. It may even be un-compatible with the lower profile idc. For example, the SCREEN_CONTENT_CODING profile with idc 9 is not compatible with 3D_MAIN profile with idc 8. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 40 ----------------------- 1 file changed, 40 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index e26a67f12c..dc311464ce 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1249,44 +1249,6 @@ error_unsupported_level: } } -/* Derives the minimum tier from the active coding tools */ -/* Enable "high-compression" tuning options */ -static gboolean -ensure_tuning_high_compression (GstVaapiEncoderH265 * encoder) -{ - guint8 profile_idc; - - if (!ensure_hw_profile_limits (encoder)) - return FALSE; - - profile_idc = encoder->hw_max_profile_idc; - if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc) - profile_idc = encoder->max_profile_idc; - - /* Tuning options */ - if (!encoder->num_bframes) - encoder->num_bframes = 3; - - return TRUE; -} - -/* Ensure tuning options */ -static gboolean -ensure_tuning (GstVaapiEncoderH265 * encoder) -{ - gboolean success; - - switch (GST_VAAPI_ENCODER_TUNE (encoder)) { - case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: - success = ensure_tuning_high_compression (encoder); - break; - default: - success = TRUE; - break; - } - return success; -} - /* Handle new GOP starts */ static void reset_gop_start (GstVaapiEncoderH265 * encoder) @@ -2327,8 +2289,6 @@ ensure_profile_tier_level (GstVaapiEncoderH265 * encoder) const GstVaapiTierH265 tier = encoder->tier; const GstVaapiLevelH265 level = encoder->level; - ensure_tuning (encoder); - if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; From 70800a8319c0c6fe5ab7e951d83fe48101526771 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 4 Jul 2020 21:05:49 +0800 Subject: [PATCH 3638/3781] libs: encoder: h265: fix a bug to get get_profile_tier_level. 0 is a valid value for h265 tier. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index dc311464ce..c40d75fd80 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -3705,7 +3705,8 @@ gst_vaapi_encoder_h265_get_profile_tier_level (GstVaapiEncoderH265 * encoder, { g_return_val_if_fail (encoder != NULL, FALSE); - if (!encoder->profile || !encoder->tier || !encoder->level) + if (!encoder->profile || encoder->tier == GST_VAAPI_TIER_H265_UNKNOWN + || !encoder->level) return FALSE; if (out_profile_ptr) From 0932a450d3f45fbbd581eb88cf0d124ff0157d6f Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 4 Jul 2020 21:08:20 +0800 Subject: [PATCH 3639/3781] libs: encoder: h265: init tier to GST_VAAPI_TIER_H265_UNKNOWN. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index c40d75fd80..1530a27e9b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -3167,6 +3167,7 @@ gst_vaapi_encoder_h265_init (GstVaapiEncoderH265 * encoder) /* Default encoding entrypoint */ encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; + encoder->tier = GST_VAAPI_TIER_H265_UNKNOWN; encoder->conformance_window_flag = 0; encoder->num_slices = 1; From aa7370943dc69273836fa828cb19a86a6a2c6809 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 4 Jul 2020 21:21:57 +0800 Subject: [PATCH 3640/3781] plugins: encode: h265: Add profile,level,tier to output caps. Part-of: --- gst/vaapi/gstvaapiencode_h265.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index b5a19f6aa3..0cb3fddca5 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -176,7 +176,12 @@ static GstCaps * gst_vaapiencode_h265_get_caps (GstVaapiEncode * base_encode) { GstVaapiEncodeH265 *const encode = GST_VAAPIENCODE_H265_CAST (base_encode); + GstVaapiEncoderH265 *const encoder = + GST_VAAPI_ENCODER_H265 (base_encode->encoder); GstCaps *caps, *allowed_caps; + GstVaapiProfile profile = GST_VAAPI_PROFILE_UNKNOWN; + GstVaapiLevelH265 level = 0; + GstVaapiTierH265 tier = GST_VAAPI_TIER_H265_UNKNOWN; caps = gst_caps_from_string (GST_CODEC_CAPS); @@ -204,7 +209,22 @@ gst_vaapiencode_h265_get_caps (GstVaapiEncode * base_encode) base_encode->need_codec_data = encode->is_hvc; - /* XXX: update profile and level information */ + gst_vaapi_encoder_h265_get_profile_tier_level (encoder, + &profile, &tier, &level); + if (profile != GST_VAAPI_PROFILE_UNKNOWN) { + gst_caps_set_simple (caps, "profile", G_TYPE_STRING, + gst_vaapi_utils_h265_get_profile_string (profile), NULL); + + if (level) { + gst_caps_set_simple (caps, "level", G_TYPE_STRING, + gst_vaapi_utils_h265_get_level_string (level), NULL); + + if (tier != GST_VAAPI_TIER_H265_UNKNOWN) + gst_caps_set_simple (caps, "tier", G_TYPE_STRING, + gst_vaapi_utils_h265_get_tier_string (tier), NULL); + } + } + return caps; } From b387081a4d77d3da202da72686ab40fb9c83ee1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 19 Jun 2020 10:44:50 +0200 Subject: [PATCH 3641/3781] libs: decoder: h264, h265: in context at least 16 reference surfaces Registering only stream's DBP size number of surfaces for decoding VA surfaces brings issues for certain streams. This change register all possible number of reference surfaces in a stream, which is 16. Fixes: #94 --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 83b05c45e4..7dd7ed7fee 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1623,7 +1623,7 @@ ensure_context (GstVaapiDecoderH264 * decoder, GstH264SPS * sps) info.chroma_type = priv->chroma_type; info.width = sps->width; info.height = sps->height; - info.ref_frames = dpb_size; + info.ref_frames = 16; if (!gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 024d71421b..cd718f424d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1201,7 +1201,7 @@ ensure_context (GstVaapiDecoderH265 * decoder, GstH265SPS * sps) info.chroma_type = priv->chroma_type; info.width = sps->width; info.height = sps->height; - info.ref_frames = dpb_size; + info.ref_frames = 16; if (!gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; From 13d090b5660a2e2e2c997db44ba9a391101e8bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 6 Jun 2020 18:47:35 +0200 Subject: [PATCH 3642/3781] vaapisink: rank it as secondary iHD doesn't provide a full implemention for rendering surfaces and i965 has problems in wayland. And I suspect this path is followed by other driver implementations. This patch demotes the rank of vaapisink to secondary, so it will not be autoplugged avoiding bad experience of users. Part-of: --- gst/vaapi/gstvaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 2a34ae6284..d4499f6c50 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -212,7 +212,7 @@ plugin_init (GstPlugin * plugin) gst_element_register (plugin, "vaapidecodebin", GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); - rank = GST_RANK_PRIMARY; + rank = GST_RANK_SECONDARY; if (g_getenv ("WAYLAND_DISPLAY")) rank = GST_RANK_MARGINAL; gst_element_register (plugin, "vaapisink", rank, GST_TYPE_VAAPISINK); From d8f0e1b01fe0c2488e225609662051347101f46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 8 Jul 2020 11:57:52 +0200 Subject: [PATCH 3643/3781] plugins: use VA allocator by default on raw caps Instead of using dmabuf allocator in source pad, when raw video caps are negotiated, it uses VA allocator as before, since it is stable in more use cases, for example transcoding, and more backend drivers. Dmabuf allocator is only used when dmabuf caps feature is negotiated. Part-of: --- gst/vaapi/gstvaapipluginbase.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 7a06493aef..5cf1a7b3c9 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -593,11 +593,7 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstPad * srcpad, goto valid_allocator; srcpriv->allocator = NULL; - if (caps && gst_caps_is_video_raw (caps)) { - GstAllocator *allocator = create_dmabuf_srcpad_allocator (plugin, vinfo, - !srcpriv->can_dmabuf); - srcpriv->allocator = allocator; - } else if (caps && gst_vaapi_caps_feature_contains (caps, + if (caps && gst_vaapi_caps_feature_contains (caps, GST_VAAPI_CAPS_FEATURE_DMABUF)) { srcpriv->allocator = create_dmabuf_srcpad_allocator (plugin, vinfo, FALSE); if (!srcpriv->allocator) From 60c183331a9a7126e9b5256c595a87bf42e47885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 8 Jul 2020 17:50:51 +0100 Subject: [PATCH 3644/3781] meson: set release date from .doap file for releases Part-of: --- meson.build | 17 ++++++- .../extract-release-date-from-doap-file.py | 45 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100755 scripts/extract-release-date-from-doap-file.py diff --git a/meson.build b/meson.build index 4bb27ac5c1..e1194e6770 100644 --- a/meson.build +++ b/meson.build @@ -156,7 +156,6 @@ osxversion = curversion + 1 plugins_install_dir = '@0@/gstreamer-1.0'.format(get_option('libdir')) -configure_file(configuration: cdata, output: 'config.h') gstreamer_vaapi_args = ['-DHAVE_CONFIG_H'] configinc = include_directories('.') libsinc = include_directories('gst-libs') @@ -166,5 +165,21 @@ subdir('gst') subdir('tests') subdir('docs') +# Set release date +if gst_version_nano == 0 + extract_release_date = find_program('scripts/extract-release-date-from-doap-file.py') + run_result = run_command(extract_release_date, gst_version, files('gstreamer-vaapi.doap')) + if run_result.returncode() == 0 + release_date = run_result.stdout().strip() + cdata.set_quoted('GST_PACKAGE_RELEASE_DATETIME', release_date) + message('Package release date: ' + release_date) + else + # Error out if our release can't be found in the .doap file + error(run_result.stderr()) + endif +endif + +configure_file(output: 'config.h', configuration: cdata) + python3 = import('python').find_installation() run_command(python3, '-c', 'import shutil; shutil.copy("hooks/pre-commit.hook", ".git/hooks/pre-commit")') diff --git a/scripts/extract-release-date-from-doap-file.py b/scripts/extract-release-date-from-doap-file.py new file mode 100755 index 0000000000..f09b60e9d0 --- /dev/null +++ b/scripts/extract-release-date-from-doap-file.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# +# extract-release-date-from-doap-file.py VERSION DOAP-FILE +# +# Extract release date for the given release version from a DOAP file +# +# Copyright (C) 2020 Tim-Philipp Müller +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301, USA. + +import sys +import xml.etree.ElementTree as ET + +if len(sys.argv) != 3: + sys.exit('Usage: {} VERSION DOAP-FILE'.format(sys.argv[0])) + +release_version = sys.argv[1] +doap_fn = sys.argv[2] + +tree = ET.parse(doap_fn) +root = tree.getroot() + +namespaces = {'doap': 'http://usefulinc.com/ns/doap#'} + +for v in root.findall('doap:release/doap:Version', namespaces=namespaces): + if v.findtext('doap:revision', namespaces=namespaces) == release_version: + release_date = v.findtext('doap:created', namespaces=namespaces) + if release_date: + print(release_date) + sys.exit(0) + +sys.exit('Could not find a release with version {} in {}'.format(release_version, doap_fn)) From ac3e8c7c40874e70c8d1dc94d382307099d6dddf Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 6 Dec 2019 14:21:33 +0800 Subject: [PATCH 3645/3781] libs: decoder: context: remove surfaces binding from context. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vaCreateContext do not need to specify the surfaces for the context creation now. So we do not need to bind any surface to the context anymore. Surfaces should be the resource belong to display and just be used in encoder/decoder context. The previous manner has big limitation for decoder. The context's surface number is decided by dpb size. All the surfaces in dpb will be attached to a gstbuffer and be pushed to down stream, and the decoder need to wait down stream free the surface and go on if not enough surface available. For more and more use cases, this causes deadlock. For example, gst-launch-1.0 filesrc location=a.h264 ! h264parse ! vaapih264dec ! x264enc ! filesink location=./output.h264 will cause deadlock and make the whole pipeline hang. the x264enc encoder need to cache more than dpb size surfaces. The best solution is seperating the surfaces number and the dpb size. dpb and dpb size shoule be virtual concepts maintained by the decoder. And let the surfaces_pool in context maintain the re-use of all surfaces. For encoder, the situation is better, all the surfaces are just used as reference frame and no need to be pushed to down stream. We can just reserve and set the capacity of the surfaces_pool to meet the request. Fix: #147 Fix: #88 Co-Author: Víctor Manuel Jáquez Leal Part-of: --- gst-libs/gst/vaapi/gstvaapicontext.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index ea6d763218..8a361f3f96 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -165,7 +165,7 @@ context_ensure_surfaces (GstVaapiContext * context) const guint num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT; GstVaapiSurface *surface; GstVideoFormat format; - guint i; + guint i, capacity; format = get_preferred_format (context); for (i = context->surfaces->len; i < num_surfaces; i++) { @@ -182,7 +182,9 @@ context_ensure_surfaces (GstVaapiContext * context) if (!gst_vaapi_video_pool_add_object (context->surfaces_pool, surface)) return FALSE; } - gst_vaapi_video_pool_set_capacity (context->surfaces_pool, num_surfaces); + + capacity = cip->usage == GST_VAAPI_CONTEXT_USAGE_DECODE ? 0 : num_surfaces; + gst_vaapi_video_pool_set_capacity (context->surfaces_pool, capacity); return TRUE; } @@ -219,10 +221,12 @@ context_create (GstVaapiContext * context) 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; @@ -240,12 +244,22 @@ context_create (GstVaapiContext * context) 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, - (VASurfaceID *) surfaces->data, surfaces->len, &context_id); + surfaces_data, num_surfaces, &context_id); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateContext()")) goto cleanup; @@ -627,6 +641,8 @@ 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); } From a4c4314be6f44ca02b1690d04ec6e550681db4be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 8 Jul 2020 17:48:57 +0200 Subject: [PATCH 3646/3781] Revert "vaapidecode: drop non-keyframe in reverse playback" Since the number of surfaces are not bounded to decoder context, this hack is no longer needed. This reverts commit 19c0c8a97385ce119440c4aad2d689fc79297435. Part-of: --- gst/vaapi/gstvaapidecode.c | 30 ------------------------------ gst/vaapi/gstvaapidecode.h | 1 - 2 files changed, 31 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4ce62f29d5..4441392502 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -613,14 +613,6 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, } } - if (decode->in_segment.rate < 0.0 - && !GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME (vdec) - && !GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (out_frame)) { - GST_TRACE_OBJECT (decode, "drop frame in reverse playback"); - gst_video_decoder_release_frame (GST_VIDEO_DECODER (decode), out_frame); - return GST_FLOW_OK; - } - ret = gst_video_decoder_finish_frame (vdec, out_frame); if (ret != GST_FLOW_OK) goto error_commit_buffer; @@ -1445,27 +1437,6 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) return ret; } -static gboolean -gst_vaapidecode_sink_event (GstVideoDecoder * vdec, GstEvent * event) -{ - GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEGMENT: - { - /* Keep segment event to refer to rate so that - * vaapidecode can handle reverse playback - */ - gst_event_copy_segment (event, &decode->in_segment); - break; - } - default: - break; - } - - return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (vdec, event); -} - static gboolean gst_vaapidecode_transform_meta (GstVideoDecoder * vdec, GstVideoCodecFrame * frame, GstMeta * meta) @@ -1517,7 +1488,6 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) vdec_class->src_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_src_query); vdec_class->sink_query = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_query); vdec_class->getcaps = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_getcaps); - vdec_class->sink_event = GST_DEBUG_FUNCPTR (gst_vaapidecode_sink_event); vdec_class->transform_meta = GST_DEBUG_FUNCPTR (gst_vaapidecode_transform_meta); diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index 8c841901dd..b7c4160c53 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -54,7 +54,6 @@ struct _GstVaapiDecode { guint display_height; GstVideoCodecState *input_state; - GstSegment in_segment; gboolean do_renego; }; From 2a93455137a4c769125a08b6b8201cd3a33c2696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 8 Jul 2020 17:33:32 +0200 Subject: [PATCH 3647/3781] vaapidecode: Remove NO_SURFACE error handling Since surfaces are not bounded to decoding context it makes no sense to keep the surface semaphore. This patch removes the handling of this error. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder.c | 18 --------------- gst-libs/gst/vaapi/gstvaapidecoder.h | 3 --- gst/vaapi/gstvaapidecode.c | 34 ---------------------------- gst/vaapi/gstvaapidecode.h | 2 -- tests/internal/simple-decoder.c | 27 +--------------------- 5 files changed, 1 insertion(+), 83 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index bec06f5700..0b60b87755 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -305,10 +305,6 @@ decode_step (GstVaapiDecoder * decoder) gboolean got_frame; guint got_unit_size, input_size; - status = gst_vaapi_decoder_check_status (decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; - /* Fill adapter with all buffers we have in the queue */ for (;;) { buffer = pop_buffer (decoder); @@ -1002,15 +998,6 @@ gst_vaapi_decoder_push_frame (GstVaapiDecoder * decoder, push_frame (decoder, frame); } -GstVaapiDecoderStatus -gst_vaapi_decoder_check_status (GstVaapiDecoder * decoder) -{ - if (decoder->context && - gst_vaapi_context_get_surface_count (decoder->context) < 1) - return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE; - return GST_VAAPI_DECODER_STATUS_SUCCESS; -} - GstVaapiDecoderStatus gst_vaapi_decoder_parse (GstVaapiDecoder * decoder, GstVideoCodecFrame * base_frame, GstAdapter * adapter, gboolean at_eos, @@ -1034,8 +1021,6 @@ gst_vaapi_decoder_parse (GstVaapiDecoder * decoder, GstVaapiDecoderStatus gst_vaapi_decoder_decode (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame) { - GstVaapiDecoderStatus status; - g_return_val_if_fail (decoder != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); g_return_val_if_fail (frame != NULL, @@ -1043,9 +1028,6 @@ gst_vaapi_decoder_decode (GstVaapiDecoder * decoder, GstVideoCodecFrame * frame) g_return_val_if_fail (frame->user_data != NULL, GST_VAAPI_DECODER_STATUS_ERROR_INVALID_PARAMETER); - status = gst_vaapi_decoder_check_status (decoder); - if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) - return status; return do_decode (decoder, frame); } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index 2c5e967ed4..b9bca4b2c0 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -136,9 +136,6 @@ gst_vaapi_decoder_flush (GstVaapiDecoder * decoder); GstVaapiDecoderStatus gst_vaapi_decoder_reset (GstVaapiDecoder * decoder); -GstVaapiDecoderStatus -gst_vaapi_decoder_check_status (GstVaapiDecoder * decoder); - gboolean gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps); diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4441392502..50407d83af 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -375,15 +375,6 @@ gst_vaapidecode_update_src_caps (GstVaapiDecode * decode) return TRUE; } -static void -gst_vaapidecode_release (GstVaapiDecode * decode) -{ - g_mutex_lock (&decode->surface_ready_mutex); - g_cond_signal (&decode->surface_ready); - g_mutex_unlock (&decode->surface_ready_mutex); - gst_object_unref (decode); -} - /* check whether the decoded surface size has changed */ static gboolean is_surface_resolution_changed (GstVaapiDecode * decode, @@ -541,9 +532,6 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, return GST_FLOW_ERROR; } - gst_vaapi_surface_proxy_set_destroy_notify (proxy, - (GDestroyNotify) gst_vaapidecode_release, gst_object_ref (decode)); - if (is_src_allocator_dmabuf (decode)) { vaapi_params.proxy = gst_vaapi_surface_proxy_ref (proxy); params = (GstBufferPoolAcquireParams *) & vaapi_params; @@ -706,18 +694,6 @@ gst_vaapidecode_handle_frame (GstVideoDecoder * vdec, /* Decode current frame */ for (;;) { status = gst_vaapi_decoder_decode (decode->decoder, frame); - if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { - /* Make sure that there are no decoded frames waiting in the - output queue. */ - gst_vaapidecode_push_all_decoded_frames (decode); - - g_mutex_lock (&decode->surface_ready_mutex); - if (gst_vaapi_decoder_check_status (decode->decoder) == - GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) - g_cond_wait (&decode->surface_ready, &decode->surface_ready_mutex); - g_mutex_unlock (&decode->surface_ready_mutex); - continue; - } if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto error_decode; break; @@ -987,8 +963,6 @@ gst_vaapidecode_destroy (GstVaapiDecode * decode) gst_vaapidecode_purge (decode); gst_vaapi_decoder_replace (&decode->decoder, NULL); - - gst_vaapidecode_release (gst_object_ref (decode)); } static gboolean @@ -1016,11 +990,6 @@ gst_vaapidecode_reset (GstVaapiDecode * decode, GstCaps * caps, static void gst_vaapidecode_finalize (GObject * object) { - GstVaapiDecode *const decode = GST_VAAPIDECODE (object); - - g_cond_clear (&decode->surface_ready); - g_mutex_clear (&decode->surface_ready_mutex); - gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (object)); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -1537,9 +1506,6 @@ gst_vaapidecode_init (GstVaapiDecode * decode) gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (decode), GST_CAT_DEFAULT); - g_mutex_init (&decode->surface_ready_mutex); - g_cond_init (&decode->surface_ready); - gst_video_decoder_set_packetized (vdec, FALSE); } diff --git a/gst/vaapi/gstvaapidecode.h b/gst/vaapi/gstvaapidecode.h index b7c4160c53..77ab3ce709 100644 --- a/gst/vaapi/gstvaapidecode.h +++ b/gst/vaapi/gstvaapidecode.h @@ -43,8 +43,6 @@ struct _GstVaapiDecode { GstCaps *srcpad_caps; GstVideoInfo decoded_info; GstVaapiDecoder *decoder; - GMutex surface_ready_mutex; - GCond surface_ready; GstCaps *allowed_sinkpad_caps; GstCaps *allowed_srcpad_caps; guint current_frame_size; diff --git a/tests/internal/simple-decoder.c b/tests/internal/simple-decoder.c index f6b1499886..134b845145 100644 --- a/tests/internal/simple-decoder.c +++ b/tests/internal/simple-decoder.c @@ -86,7 +86,6 @@ typedef struct GstVaapiDecoder *decoder; GThread *decoder_thread; volatile gboolean decoder_thread_cancel; - GCond decoder_ready; GAsyncQueue *decoder_queue; GstVaapiCodec codec; guint fps_n; @@ -219,14 +218,6 @@ get_error_string (AppError error) return str; } -static void -decoder_release (App * app) -{ - g_mutex_lock (&app->mutex); - g_cond_signal (&app->decoder_ready); - g_mutex_unlock (&app->mutex); -} - static gpointer decoder_thread (gpointer data) { @@ -237,8 +228,7 @@ decoder_thread (gpointer data) RenderFrame *rfp; GstBuffer *buffer; GstClockTime pts; - gboolean got_surface, got_eos = FALSE; - gint64 end_time; + gboolean got_eos = FALSE; guint ofs; g_print ("Decoder thread started\n"); @@ -266,12 +256,9 @@ decoder_thread (gpointer data) SEND_ERROR ("failed to push buffer to decoder"); gst_buffer_replace (&buffer, NULL); - get_surface: status = gst_vaapi_decoder_get_surface (app->decoder, &proxy); switch (status) { case GST_VAAPI_DECODER_STATUS_SUCCESS: - gst_vaapi_surface_proxy_set_destroy_notify (proxy, - (GDestroyNotify) decoder_release, app); rfp = render_frame_new (); if (!rfp) SEND_ERROR ("failed to allocate render frame"); @@ -290,16 +277,6 @@ decoder_thread (gpointer data) goto send_eos; got_eos = TRUE; break; - case GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE: - end_time = g_get_monotonic_time () + G_TIME_SPAN_SECOND; - g_mutex_lock (&app->mutex); - got_surface = g_cond_wait_until (&app->decoder_ready, &app->mutex, - end_time); - g_mutex_unlock (&app->mutex); - if (got_surface) - goto get_surface; - SEND_ERROR ("failed to acquire a surface within one second"); - break; default: SEND_ERROR ("%s", get_decoder_status_string (status)); break; @@ -550,7 +527,6 @@ app_free (App * app) g_async_queue_unref (app->decoder_queue); app->decoder_queue = NULL; } - g_cond_clear (&app->decoder_ready); if (app->timer) { g_timer_destroy (app->timer); @@ -574,7 +550,6 @@ app_new (void) g_mutex_init (&app->mutex); g_cond_init (&app->event_cond); - g_cond_init (&app->decoder_ready); g_cond_init (&app->render_ready); app_set_framerate (app, 60, 1); From b1832223ffb72360e01fe30cdf0b88423b0455b2 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sun, 12 Jul 2020 20:34:31 +0800 Subject: [PATCH 3648/3781] libs: profile: The VP9 profiles' name should be just "0,1,2,3" Part-of: --- gst-libs/gst/vaapi/gstvaapiprofile.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index e7bdea003f..dc9b07ffbc 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -141,13 +141,13 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h265", "screen-extended-main-444-10"}, #endif {GST_VAAPI_PROFILE_VP9_0, VAProfileVP9Profile0, - "video/x-vp9", "profile0"}, + "video/x-vp9", "0"}, {GST_VAAPI_PROFILE_VP9_1, VAProfileVP9Profile1, - "video/x-vp9", "profile1"}, + "video/x-vp9", "1"}, {GST_VAAPI_PROFILE_VP9_2, VAProfileVP9Profile2, - "video/x-vp9", "profile2"}, + "video/x-vp9", "2"}, {GST_VAAPI_PROFILE_VP9_3, VAProfileVP9Profile3, - "video/x-vp9", "profile3"}, + "video/x-vp9", "3"}, {0,} }; From f1c44411f31a09ebbf2a51d9ba514294af4e93af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 13 Jul 2020 11:06:18 +0200 Subject: [PATCH 3649/3781] vaapidecodebin: don't force NV12 since P010_10LE is now possible Part-of: --- gst/vaapi/gstvaapidecodebin.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 52a102e160..7edf39722c 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -313,9 +313,8 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin) GST_INFO_OBJECT (vaapidecbin, "enabling VPP"); - /* capsfilter to avoid negotiation with vaapidecode */ - caps = gst_caps_from_string - ("video/x-raw(memory:VASurface), format=(string)NV12"); + /* capsfilter to force memory:VASurface */ + caps = gst_caps_from_string ("video/x-raw(memory:VASurface)"); if (!caps) goto error_cannot_set_caps; capsfilter = gst_element_factory_make ("capsfilter", NULL); From 26afaab523acf62567edde3374b97ec16a86993b Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 17 Jul 2020 00:45:53 +0800 Subject: [PATCH 3650/3781] plugin: decode: correct ensure_allowed_sinkpad_caps's caps. The decode allowed caps returned by ensure_allowed_sinkpad_caps() contains all profiles of the whole VAAPI, like: image/jpeg, width=(int)[ 0, 1638 4 ], height=(int)[ 0, 16384 ]; video/mpeg, mpegversion=(int)2, profile=(string){ simple, main }, width=(int)[ 0, 2048 ], height=(int)[ 0, 2048 ]; video/x-h264, profile=(string){ main, high, constrained-baseline }, width=(int)[ 0, 4096 ], height=(int)[ 0, 4096 ]; video/x-h264, profile=(string){ constrained-high, progressive-high, baseline }; video/x-h265, profile=(string){ main, main-intra }, width=(int)[ 0, 8192 ], height=(int)[ 0, 8192 ]; video/x-vp8, width=(int)[ 0, 4096 ], height=(int)[ 0, 4096 ]; video/x-wmv, wmvversion=(int)3, format=(string)WVC1, profile=(string)advanced, width=(int)[ 0, 3840 ], height=(int)[ 0, 3840 ]; video/x-wmv, wmvversion=(int)3, profile=(string){ simple, main }, width=(int)[ 0, 3840 ], height=(int)[ 0, 3840 ] Which is verbose and may have latent problems. It should only contains the profiles belong to its codec type. For example, h265 should only return: video/x-h265, profile=(string){ main, main-intra }, width=(int)[ 0, 8192 ], height=(int)[ 0, 8192 ] Part-of: --- gst/vaapi/gstvaapidecode.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 50407d83af..f953584155 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1184,6 +1184,7 @@ static gboolean gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) { GstCaps *caps, *allowed_sinkpad_caps; + GstPad *const sinkpad = GST_VIDEO_DECODER_SINK_PAD (decode); GArray *profiles; GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode); guint i; @@ -1301,7 +1302,13 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) add_h264_profile_in_caps (allowed_sinkpad_caps, "scalable-high"); } } - decode->allowed_sinkpad_caps = gst_caps_simplify (allowed_sinkpad_caps); + + caps = gst_pad_get_pad_template_caps (sinkpad); + decode->allowed_sinkpad_caps = + gst_caps_intersect (allowed_sinkpad_caps, caps); + gst_caps_unref (caps); + decode->allowed_sinkpad_caps = + gst_caps_simplify (decode->allowed_sinkpad_caps); GST_DEBUG_OBJECT (decode, "allowed sink caps %" GST_PTR_FORMAT, decode->allowed_sinkpad_caps); From 7d3a19baceed25403e631fd6316c9a605d51ec10 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 9 Jul 2020 23:07:38 +0800 Subject: [PATCH 3651/3781] video-format: Add P012_LE format. It can be used as HEVC YUV_4:2:0 12bits stream's decoder output, and also can be used as the input format for encoding HEVC YUV_4:2:0 12bits stream. Part-of: --- gst-libs/gst/vaapi/gstvaapiimage.c | 1 + gst-libs/gst/vaapi/video-format.c | 1 + 2 files changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index c67ec1dd8c..34baf40385 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -97,6 +97,7 @@ vaapi_image_is_linear (const VAImage * va_image) data_size = 4 * width * height; break; case VA_FOURCC ('P', '0', '1', '0'): + case VA_FOURCC ('P', '0', '1', '2'): data_size = 2 * (width * height + 2 * width2 * height2); break; case VA_FOURCC ('R', 'G', '2', '4'): diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 6c1e8e7f5d..5b22054ed6 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -93,6 +93,7 @@ static const GstVideoFormatMap gst_vaapi_video_default_formats[] = { DEF_YUV (VA_BYTE_ORDER_NOT_CARE, GRAY8, ('Y', '8', '0', '0'), 8, 400), DEF_YUV (VA_LSB_FIRST, P010_10LE, ('P', '0', '1', '0'), 24, 420_10BPP), + DEF_YUV (VA_LSB_FIRST, P012_LE, ('P', '0', '1', '2'), 24, 420_12BPP), /* AYUV is a clear defined format by doc */ DEF_YUV (VA_LSB_FIRST, VUYA, ('A', 'Y', 'U', 'V'), 32, 444), From f82850c6d387ba8e3a50465f564dffe0106f0523 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 14 Jul 2020 18:13:56 +0800 Subject: [PATCH 3652/3781] libs: decoder: H265: Add MAIN_12 profile supporting. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 3 ++- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 ++ gst-libs/gst/vaapi/gstvaapiprofile.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_h265.c | 24 +++++++++++++++++++++++ gst-libs/gst/vaapi/video-format.c | 2 ++ gst/vaapi/gstvaapidecode.c | 3 ++- 6 files changed, 33 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index cd718f424d..dc81c6accc 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -532,7 +532,8 @@ is_range_extension_profile (GstVaapiProfile profile) { if (profile == GST_VAAPI_PROFILE_H265_MAIN_422_10 || profile == GST_VAAPI_PROFILE_H265_MAIN_444 - || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10) + || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10 + || profile == GST_VAAPI_PROFILE_H265_MAIN12) return TRUE; return FALSE; } diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index dc9b07ffbc..e1980e0148 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -128,6 +128,8 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h265", "main-444"}, {GST_VAAPI_PROFILE_H265_MAIN_444_10, VAProfileHEVCMain444_10, "video/x-h265", "main-444-10"}, + {GST_VAAPI_PROFILE_H265_MAIN12, VAProfileHEVCMain12, + "video/x-h265", "main-12"}, {GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN, VAProfileHEVCSccMain, "video/x-h265", "screen-extended-main"}, {GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10, VAProfileHEVCSccMain10, diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 3d2e42eaf2..c3080f4ee3 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -189,6 +189,7 @@ typedef enum { GST_VAAPI_MAKE_PROFILE(H265,9), GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10 = GST_VAAPI_MAKE_PROFILE(H265,10), + GST_VAAPI_PROFILE_H265_MAIN12 = GST_VAAPI_MAKE_PROFILE(H265,11), GST_VAAPI_PROFILE_VP9_0 = GST_VAAPI_MAKE_PROFILE(VP9,1), GST_VAAPI_PROFILE_VP9_1 = GST_VAAPI_MAKE_PROFILE(VP9,2), GST_VAAPI_PROFILE_VP9_2 = GST_VAAPI_MAKE_PROFILE(VP9,3), diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 7f6c7437b0..06597bfc35 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -241,6 +241,27 @@ gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) /* Main 422_10 Intra, recognize it as MAIN_422_10 */ profile = GST_VAAPI_PROFILE_H265_MAIN_422_10; break; + } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 0 + && sps->profile_tier_level.max_8bit_constraint_flag == 0 + && sps->profile_tier_level.max_422chroma_constraint_flag == 1 + && sps->profile_tier_level.max_420chroma_constraint_flag == 1 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 0 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { + profile = GST_VAAPI_PROFILE_H265_MAIN12; + break; + } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 + && sps->profile_tier_level.max_10bit_constraint_flag == 0 + && sps->profile_tier_level.max_8bit_constraint_flag == 0 + && sps->profile_tier_level.max_422chroma_constraint_flag == 1 + && sps->profile_tier_level.max_420chroma_constraint_flag == 1 + && sps->profile_tier_level.max_monochrome_constraint_flag == 0 + && sps->profile_tier_level.intra_constraint_flag == 1 + && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { + /* Main 12 Intra, recognize it as MAIN12 */ + profile = GST_VAAPI_PROFILE_H265_MAIN12; + break; } case GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING: if (sps->profile_tier_level.max_14bit_constraint_flag == 1 @@ -458,6 +479,8 @@ gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; else if (depth > 8 && depth <= 10) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; + else if (depth > 10 && depth <= 12) + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_12BPP; break; case 2: if (depth == 8) @@ -493,6 +516,7 @@ gst_vaapi_utils_h265_get_chroma_format_idc (GstVaapiChromaType chroma_type) break; case GST_VAAPI_CHROMA_TYPE_YUV420: case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: + case GST_VAAPI_CHROMA_TYPE_YUV420_12BPP: chroma_format_idc = 1; break; case GST_VAAPI_CHROMA_TYPE_YUV422: diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 5b22054ed6..7fb1b1a5b6 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -445,6 +445,8 @@ gst_vaapi_video_format_from_chroma (guint chroma_type) return GST_VIDEO_FORMAT_NV12; case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: return GST_VIDEO_FORMAT_P010_10LE; + case GST_VAAPI_CHROMA_TYPE_YUV420_12BPP: + return GST_VIDEO_FORMAT_P012_LE; case GST_VAAPI_CHROMA_TYPE_YUV444: return GST_VIDEO_FORMAT_VUYA; case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index f953584155..2796ab147b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1230,7 +1230,8 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) || profile == GST_VAAPI_PROFILE_H265_MAIN10 || profile == GST_VAAPI_PROFILE_H265_MAIN_422_10 || profile == GST_VAAPI_PROFILE_H265_MAIN_444 - || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10) { + || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10 + || profile == GST_VAAPI_PROFILE_H265_MAIN12) { GValue list_value = G_VALUE_INIT; GValue value = G_VALUE_INIT; gchar *intra_name; From 2da3314534ae9c279c0a647fe4e935104b0882bc Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 21 Jul 2020 22:05:08 +0800 Subject: [PATCH 3653/3781] plugin: util: Add the missing DMA buffer input in template caps. We pass the wrong parameter to gst_vaapi_build_caps_from_formats() and lose the DMA feature in caps. Part-of: --- gst/vaapi/gstvaapipluginutil.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 0e55640f12..c558138a3b 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1233,7 +1233,8 @@ gst_vaapi_build_template_caps_by_codec (GstVaapiDisplay * display, } out_caps = gst_vaapi_build_caps_from_formats (supported_fmts, 1, 1, - G_MAXINT, G_MAXINT, TRUE); + G_MAXINT, G_MAXINT, + from_GstVaapiBufferMemoryType (GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF)); out: if (profiles) From e962069dbe15fb7cfedced1b325de6dc758bf190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 21 Jul 2020 20:14:57 +0200 Subject: [PATCH 3654/3781] vaapidecode: merge common profiles before setting size range The synthetic profiles, such as H264 baseline, H265 intra, etc. are added at the end of processing all available VA profiles. This generated an non-optimal caps for negotiation, since the synthetic profiles don't have frame size ranges. This patch adds those possible synthetic profiles when the associated profile is processed, with its frame size ranges. Now allowed sink caps are simpler. Part-of: --- gst/vaapi/gstvaapidecode.c | 142 +++++++++++++++------------------ gst/vaapi/gstvaapipluginutil.c | 31 +++++++ gst/vaapi/gstvaapipluginutil.h | 4 + 3 files changed, 100 insertions(+), 77 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 2796ab147b..0f631e707c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1170,14 +1170,18 @@ is_svc_profile (GstVaapiProfile profile) || profile == GST_VAAPI_PROFILE_H264_SCALABLE_HIGH; } - -static GstCaps * -add_h264_profile_in_caps (GstCaps * caps, const gchar * profile_name) +static void +find_mvc_and_svc (GArray * profiles, gboolean * have_mvc, gboolean * have_svc) { - GstCaps *caps_new = - gst_caps_new_simple ("video/x-h264", "profile", G_TYPE_STRING, - profile_name, NULL); - return gst_caps_merge (caps_new, caps); + guint i; + + for (i = 0; i < profiles->len; i++) { + const GstVaapiProfile profile = + g_array_index (profiles, GstVaapiProfile, i); + + *have_mvc |= is_mvc_profile (profile); + *have_svc |= is_svc_profile (profile); + } } static gboolean @@ -1189,7 +1193,6 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode); guint i; gboolean base_only = FALSE; - gboolean have_high = FALSE; gboolean have_mvc = FALSE; gboolean have_svc = FALSE; @@ -1205,6 +1208,8 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) g_object_get (decode, "base-only", &base_only, NULL); } + find_mvc_and_svc (profiles, &have_mvc, &have_svc); + for (i = 0; i < profiles->len; i++) { const GstVaapiProfile profile = g_array_index (profiles, GstVaapiProfile, i); @@ -1224,84 +1229,67 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) continue; profile_name = gst_vaapi_profile_get_name (profile); - if (profile_name) { - /* Add all according -intra profile for HEVC */ - if (profile == GST_VAAPI_PROFILE_H265_MAIN - || profile == GST_VAAPI_PROFILE_H265_MAIN10 - || profile == GST_VAAPI_PROFILE_H265_MAIN_422_10 - || profile == GST_VAAPI_PROFILE_H265_MAIN_444 - || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10 - || profile == GST_VAAPI_PROFILE_H265_MAIN12) { - GValue list_value = G_VALUE_INIT; - GValue value = G_VALUE_INIT; - gchar *intra_name; + if (!profile_name) + continue; - g_value_init (&list_value, GST_TYPE_LIST); - g_value_init (&value, G_TYPE_STRING); - g_value_set_string (&value, profile_name); - gst_value_list_append_value (&list_value, &value); + /* Add all according -intra profile for HEVC */ + if (profile == GST_VAAPI_PROFILE_H265_MAIN + || profile == GST_VAAPI_PROFILE_H265_MAIN10 + || profile == GST_VAAPI_PROFILE_H265_MAIN_422_10 + || profile == GST_VAAPI_PROFILE_H265_MAIN_444 + || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10 + || profile == GST_VAAPI_PROFILE_H265_MAIN12) { + gchar *profiles[3], *intra_name; - intra_name = g_strdup_printf ("%s-intra", profile_name); - g_value_take_string (&value, intra_name); - gst_value_list_append_value (&list_value, &value); + intra_name = g_strdup_printf ("%s-intra", profile_name); - gst_structure_set_value (structure, "profile", &list_value); - g_value_unset (&list_value); - g_value_unset (&value); - } else { - gst_structure_set (structure, "profile", G_TYPE_STRING, - profile_name, NULL); + profiles[0] = (gchar *) profile_name; + profiles[1] = intra_name; + profiles[2] = NULL; + + gst_vaapi_structure_set_profiles (structure, profiles); + g_free (intra_name); + + } else if (profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE) { + /* XXX: artificially adding baseline if constrained_baseline is + * available. */ + gchar *profiles[] = { (gchar *) profile_name, "baseline", NULL }; + + gst_vaapi_structure_set_profiles (structure, profiles); + } else if (profile == GST_VAAPI_PROFILE_H264_HIGH) { + gchar *profiles[11] = { (gchar *) profile_name, "progressive-high", + "constrained-high" + }; + gint i = 3; + + if (base_only && !have_mvc) { + GST_DEBUG ("base_only: force adding MVC profiles in caps"); + + profiles[i++] = "multiview-high"; + profiles[i++] = "stereo-high"; } + + if (base_only && !have_svc) { + GST_DEBUG ("base_only: force adding SVC profiles in caps"); + + profiles[i++] = "scalable-constrained-baseline"; + profiles[i++] = "scalable-baseline"; + profiles[i++] = "scalable-high-intra"; + profiles[i++] = "scalable-constrained-high"; + profiles[i++] = "scalable-high"; + } + + profiles[i++] = NULL; + + gst_vaapi_structure_set_profiles (structure, profiles); + } else { + gst_structure_set (structure, "profile", G_TYPE_STRING, + profile_name, NULL); } gst_vaapi_profile_caps_append_decoder (display, profile, structure); allowed_sinkpad_caps = gst_caps_merge (allowed_sinkpad_caps, caps); - have_mvc |= is_mvc_profile (profile); - have_svc |= is_svc_profile (profile); - have_high |= profile == GST_VAAPI_PROFILE_H264_HIGH; - - /* XXX: artificially adding baseline if constrained_baseline is - * available. */ - if (profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE) - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "baseline"); - } - - if (have_high) { - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "progressive-high"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "constrained-high"); - } - - if (base_only && (!have_mvc || !have_svc) && have_high) { - if (!have_mvc) { - GST_DEBUG ("base_only: force adding MVC profiles in caps"); - - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "multiview-high"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "stereo-high"); - } - - if (!have_svc) { - GST_DEBUG ("base_only: force adding SVC profiles in caps"); - - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, - "scalable-constrained-baseline"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "scalable-baseline"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, - "scalable-high-intra"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, - "scalable-constrained-high"); - allowed_sinkpad_caps = - add_h264_profile_in_caps (allowed_sinkpad_caps, "scalable-high"); - } } caps = gst_pad_get_pad_template_caps (sinkpad); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index c558138a3b..ece8a683b7 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1244,3 +1244,34 @@ out: return out_caps; } + +/** + * gst_vaapi_structure_set_profiles: + * @st: a #GstStructure + * @list: a %NULL-terminated array of strings + * + * The @list of profiles are set in @st + **/ +void +gst_vaapi_structure_set_profiles (GstStructure * st, gchar ** list) +{ + guint i; + GValue vlist = G_VALUE_INIT; + GValue value = G_VALUE_INIT; + + g_value_init (&vlist, GST_TYPE_LIST); + g_value_init (&value, G_TYPE_STRING); + + for (i = 0; list[i]; i++) { + g_value_set_string (&value, list[i]); + gst_value_list_append_value (&vlist, &value); + } + + if (i == 1) + gst_structure_set_value (st, "profile", &value); + else if (i > 1) + gst_structure_set_value (st, "profile", &vlist); + + g_value_unset (&value); + g_value_unset (&vlist); +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index abdaf1e95f..cad6b8719e 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -171,4 +171,8 @@ GstCaps * gst_vaapi_build_template_caps_by_codec (GstVaapiDisplay * display, GstVaapiContextUsage usage, GstVaapiCodec codec, GArray * extra_fmts); +G_GNUC_INTERNAL +void +gst_vaapi_structure_set_profiles (GstStructure * st, gchar ** list); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ From 617dba38697b395b5c8b8e766507b68e7f1f1a70 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 7 Jul 2020 17:16:41 +0800 Subject: [PATCH 3655/3781] plugins: utils: rename build_template_caps_by_codec. Rename the function build_template_caps_by_codec() to the name of build_template_raw_caps_by_codec(). It can be used to collect all raw video formats for encode's sink and decode's src. Part-of: --- gst/vaapi/gstvaapiencode.h | 2 +- gst/vaapi/gstvaapipluginutil.c | 4 ++-- gst/vaapi/gstvaapipluginutil.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 0e76bded70..4bbea84892 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -87,7 +87,7 @@ G_BEGIN_DECLS for (i = 0; i < n; i++) \ g_array_append_val (extra_fmts, ext_video_fmts[i]); \ } \ - caps = gst_vaapi_build_template_caps_by_codec (display, \ + caps = gst_vaapi_build_template_raw_caps_by_codec (display, \ GST_VAAPI_CONTEXT_USAGE_ENCODE, \ GST_VAAPI_CODEC_##CODEC, extra_fmts); \ g_clear_pointer (&extra_fmts, g_array_unref); \ diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index ece8a683b7..027a288eec 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1141,7 +1141,7 @@ gst_vaapi_build_caps_from_formats (GArray * formats, gint min_width, } /** - * gst_vaapi_build_template_caps_by_codec: + * gst_vaapi_build_template_raw_caps_by_codec: * @display: a #GstVaapiDisplay * @usage: used for encode, decode or postproc * @codec: a #GstVaapiCodec specify the codec to detect @@ -1155,7 +1155,7 @@ gst_vaapi_build_caps_from_formats (GArray * formats, gint min_width, * Returns: a built #GstCaps if succeeds, or %NULL if error. **/ GstCaps * -gst_vaapi_build_template_caps_by_codec (GstVaapiDisplay * display, +gst_vaapi_build_template_raw_caps_by_codec (GstVaapiDisplay * display, GstVaapiContextUsage usage, GstVaapiCodec codec, GArray * extra_fmts) { GArray *profiles = NULL; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index cad6b8719e..f5814d3424 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -168,7 +168,7 @@ gst_vaapi_build_caps_from_formats (GArray * formats, gint min_width, G_GNUC_INTERNAL GstCaps * -gst_vaapi_build_template_caps_by_codec (GstVaapiDisplay * display, +gst_vaapi_build_template_raw_caps_by_codec (GstVaapiDisplay * display, GstVaapiContextUsage usage, GstVaapiCodec codec, GArray * extra_fmts); G_GNUC_INTERNAL From 53d5302cde75190e109c684028183b09e37d823a Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jul 2020 18:30:00 +0800 Subject: [PATCH 3656/3781] plugin: util: add helper function build_template_coded_caps_by_codec() Like build_template_raw_caps_by_codec(), this function can detect and build the caps for specified codec based on the query of the profiles. The result is coded caps such as video/x-h265, video/x-h264. The result can be used as the template of encode's src or decode's sink. Part-of: --- gst/vaapi/gstvaapipluginutil.c | 74 ++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.h | 8 +++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 027a288eec..86de800d36 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1275,3 +1275,77 @@ gst_vaapi_structure_set_profiles (GstStructure * st, gchar ** list) g_value_unset (&value); g_value_unset (&vlist); } + +/** + * gst_vaapi_build_template_coded_caps_by_codec: + * @display: a #GstVaapiDisplay + * @usage: used for encode or decode + * @codec: a #GstVaapiCodec specify the codec to detect + * @caps_str: a string of basic caps + * + * Called by vaapi elements to detect the all possible profiles belong to the + * specified codec and build the caps based on the basic caps description. + * + * Returns: a built #GstCaps if succeeds, or %NULL if error. + **/ +GstCaps * +gst_vaapi_build_template_coded_caps_by_codec (GstVaapiDisplay * display, + GstVaapiContextUsage usage, GstVaapiCodec codec, const char *caps_str, + GstVaapiProfileToStrFunc func) +{ + GValue v_profiles = G_VALUE_INIT; + GValue v_profile = G_VALUE_INIT; + GstCaps *caps = NULL; + guint i, num; + GArray *profiles = NULL; + GstVaapiProfile profile; + const gchar *str; + + caps = gst_caps_from_string (caps_str); + if (!caps) + goto out; + + if (!func) + goto out; + + /* If no profiles, just ignore the profile field. */ + if (usage == GST_VAAPI_CONTEXT_USAGE_ENCODE) { + profiles = gst_vaapi_display_get_encode_profiles (display); + } else if (usage == GST_VAAPI_CONTEXT_USAGE_DECODE) { + profiles = gst_vaapi_display_get_decode_profiles (display); + } + if (!profiles || profiles->len == 0) + goto out; + + num = 0; + g_value_init (&v_profiles, GST_TYPE_LIST); + g_value_init (&v_profile, G_TYPE_STRING); + + for (i = 0; i < profiles->len; i++) { + profile = g_array_index (profiles, GstVaapiProfile, i); + if (gst_vaapi_profile_get_codec (profile) != codec) + continue; + + str = func (profile); + if (!str) + continue; + + g_value_set_string (&v_profile, str); + num++; + gst_value_list_append_value (&v_profiles, &v_profile); + } + + if (num == 1) { + gst_caps_set_value (caps, "profile", &v_profile); + } else if (num > 1) { + gst_caps_set_value (caps, "profile", &v_profiles); + } + +out: + g_value_unset (&v_profile); + g_value_unset (&v_profiles); + if (profiles) + g_array_unref (profiles); + + return caps; +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index f5814d3424..db069cb9c5 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -31,7 +31,7 @@ #include "gstvaapivideomemory.h" typedef GstVaapiProfile (*GstVaapiStrToProfileFunc) (const gchar * str); - +typedef const gchar * (*GstVaapiProfileToStrFunc) (GstVaapiProfile profile); G_GNUC_INTERNAL gboolean @@ -175,4 +175,10 @@ G_GNUC_INTERNAL void gst_vaapi_structure_set_profiles (GstStructure * st, gchar ** list); +G_GNUC_INTERNAL +GstCaps * +gst_vaapi_build_template_coded_caps_by_codec (GstVaapiDisplay * display, + GstVaapiContextUsage usage, GstVaapiCodec codec, const char *caps_str, + GstVaapiProfileToStrFunc func); + #endif /* GST_VAAPI_PLUGIN_UTIL_H */ From e260e9cd90cc40c6528454ef84382f2699e2d520 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jul 2020 18:46:58 +0800 Subject: [PATCH 3657/3781] plugin: encode: Store the coded caps in type's init data. Part-of: --- gst/vaapi/gstvaapiencode.h | 28 ++++++++++++++++++++++++++-- gst/vaapi/gstvaapiencode_h264.c | 5 +++-- gst/vaapi/gstvaapiencode_h265.c | 5 +++-- gst/vaapi/gstvaapiencode_jpeg.c | 4 ++-- gst/vaapi/gstvaapiencode_mpeg2.c | 6 ++++-- gst/vaapi/gstvaapiencode_vp8.c | 4 ++-- gst/vaapi/gstvaapiencode_vp9.c | 4 ++-- 7 files changed, 42 insertions(+), 14 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 4bbea84892..9e8d8c2eb7 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -44,7 +44,15 @@ G_BEGIN_DECLS #define GST_IS_VAAPIENCODE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE)) -#define GST_VAAPI_ENCODE_REGISTER_TYPE(NAME, CODEC, CLASS, _EXT_FMT_) \ +typedef struct _GstVaapiEncodeInitData GstVaapiEncodeInitData; +struct _GstVaapiEncodeInitData +{ + GstCaps *sink_caps; + GstCaps *src_caps; +}; + +#define GST_VAAPI_ENCODE_REGISTER_TYPE(NAME, CODEC, CLASS, _EXT_FMT_, FUN) \ + static GstVaapiEncodeInitData encode_init_data = { NULL, NULL }; \ static GType encode_type = G_TYPE_INVALID; \ static gpointer gst_vaapiencode_##NAME##_parent_class = NULL; \ static void \ @@ -108,7 +116,23 @@ G_BEGIN_DECLS \ /* class data will be leaked if the element never gets instantiated */ \ GST_MINI_OBJECT_FLAG_SET (caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED); \ - type_info.class_data = caps; \ + encode_init_data.sink_caps = caps; \ + \ + caps = gst_vaapi_build_template_coded_caps_by_codec (display, \ + GST_VAAPI_CONTEXT_USAGE_ENCODE, \ + GST_VAAPI_CODEC_##CODEC, GST_CODEC_CAPS, \ + FUN); \ + if (!caps) { \ + GST_ERROR ("failed to get src caps for " #CODEC \ + " encode, can not register"); \ + gst_caps_unref (encode_init_data.sink_caps); \ + return G_TYPE_INVALID; \ + } \ + GST_DEBUG (#CODEC" encode's src caps %" GST_PTR_FORMAT, caps); \ + /* class data will be leaked if the element never gets instantiated */ \ + GST_MINI_OBJECT_FLAG_SET (caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED); \ + encode_init_data.src_caps = caps; \ + type_info.class_data = &encode_init_data; \ encode_type = g_type_register_static (GST_TYPE_VAAPIENCODE, \ "GstVaapiEncode"#CLASS, &type_info, 0); \ \ diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index aabe7bcdeb..9eaa722616 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -95,7 +95,8 @@ static GstStaticPadTemplate gst_vaapiencode_h264_src_factory = #define EXTRA_FORMATS {} /* h264 encode */ -GST_VAAPI_ENCODE_REGISTER_TYPE (h264, H264, H264, EXTRA_FORMATS); +GST_VAAPI_ENCODE_REGISTER_TYPE (h264, H264, H264, EXTRA_FORMATS, + gst_vaapi_utils_h264_get_profile_string); static void gst_vaapiencode_h264_init (GstVaapiEncodeH264 * encode) @@ -557,7 +558,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass, gpointer data) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); - GstCaps *sink_caps = GST_CAPS_CAST (data); + GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_h264_finalize; diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 0cb3fddca5..2cb5061097 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -69,7 +69,8 @@ static GstStaticPadTemplate gst_vaapiencode_h265_src_factory = #define EXTRA_FORMATS {} /* h265 encode */ -GST_VAAPI_ENCODE_REGISTER_TYPE (h265, H265, H265, EXTRA_FORMATS); +GST_VAAPI_ENCODE_REGISTER_TYPE (h265, H265, H265, EXTRA_FORMATS, + gst_vaapi_utils_h265_get_profile_string); static void gst_vaapiencode_h265_init (GstVaapiEncodeH265 * encode) @@ -370,7 +371,7 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass, gpointer data) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); - GstCaps *sink_caps = GST_CAPS_CAST (data); + GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_h265_finalize; diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index e6ae27870f..57b0a8eb8e 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -65,7 +65,7 @@ static GstStaticPadTemplate gst_vaapiencode_jpeg_src_factory = #define EXTRA_FORMATS { GST_VIDEO_FORMAT_BGRA, } /* jpeg encode */ -GST_VAAPI_ENCODE_REGISTER_TYPE (jpeg, JPEG, Jpeg, EXTRA_FORMATS); +GST_VAAPI_ENCODE_REGISTER_TYPE (jpeg, JPEG, Jpeg, EXTRA_FORMATS, NULL); static void gst_vaapiencode_jpeg_init (GstVaapiEncodeJpeg * encode) @@ -102,7 +102,7 @@ gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass, gpointer data) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); - GstCaps *sink_caps = GST_CAPS_CAST (data); + GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_jpeg_finalize; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index d898533d11..ee0c116aa2 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -37,6 +37,7 @@ #include "gstcompat.h" #include #include +#include #include "gstvaapiencode_mpeg2.h" #include "gstvaapipluginutil.h" #include "gstvaapivideomemory.h" @@ -67,7 +68,8 @@ static GstStaticPadTemplate gst_vaapiencode_mpeg2_src_factory = #define EXTRA_FORMATS {} /* mpeg2 encode */ -GST_VAAPI_ENCODE_REGISTER_TYPE (mpeg2, MPEG2, Mpeg2, EXTRA_FORMATS); +GST_VAAPI_ENCODE_REGISTER_TYPE (mpeg2, MPEG2, Mpeg2, EXTRA_FORMATS, + gst_vaapi_utils_mpeg2_get_profile_string); static void gst_vaapiencode_mpeg2_init (GstVaapiEncodeMpeg2 * encode) @@ -106,7 +108,7 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass, GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); - GstCaps *sink_caps = GST_CAPS_CAST (data); + GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_mpeg2_finalize; diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 320ee178ef..96146b9d54 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -65,7 +65,7 @@ static GstStaticPadTemplate gst_vaapiencode_vp8_src_factory = #define EXTRA_FORMATS {} /* vp8 encode */ -GST_VAAPI_ENCODE_REGISTER_TYPE (vp8, VP8, VP8, EXTRA_FORMATS); +GST_VAAPI_ENCODE_REGISTER_TYPE (vp8, VP8, VP8, EXTRA_FORMATS, NULL); static void gst_vaapiencode_vp8_init (GstVaapiEncodeVP8 * encode) @@ -102,7 +102,7 @@ gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass, gpointer data) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); - GstCaps *sink_caps = GST_CAPS_CAST (data); + GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_vp8_finalize; diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index d0e527bfee..baf6c07d8f 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -65,7 +65,7 @@ static GstStaticPadTemplate gst_vaapiencode_vp9_src_factory = #define EXTRA_FORMATS {} /* vp9 encode */ -GST_VAAPI_ENCODE_REGISTER_TYPE (vp9, VP9, VP9, EXTRA_FORMATS); +GST_VAAPI_ENCODE_REGISTER_TYPE (vp9, VP9, VP9, EXTRA_FORMATS, NULL); static void gst_vaapiencode_vp9_init (GstVaapiEncodeVP9 * encode) @@ -102,7 +102,7 @@ gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass, gpointer data) GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); - GstCaps *sink_caps = GST_CAPS_CAST (data); + GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_vp9_finalize; From 47fec28895d71e11c2e2a404c7e51749acf95549 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jul 2020 18:57:26 +0800 Subject: [PATCH 3658/3781] plugin: encode: h264: Use the dynamically built src template caps. Part-of: --- gst/vaapi/gstvaapiencode_h264.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 9eaa722616..7fa36acd3d 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -78,20 +78,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug); "stream-format = (string) { avc, byte-stream }, " \ "alignment = (string) au" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_h264_src_caps_str[] = - GST_CODEC_CAPS ", " - "profile = (string) { constrained-baseline, baseline, main, high, multiview-high, stereo-high }"; -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_h264_src_factory = - GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_h264_src_caps_str)); -/* *INDENT-ON* */ - #define EXTRA_FORMATS {} /* h264 encode */ @@ -242,7 +228,7 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) gboolean ret = TRUE; template_caps = - gst_static_pad_template_get_caps (&gst_vaapiencode_h264_src_factory); + gst_pad_get_pad_template_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); allowed_caps = gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); @@ -559,6 +545,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass, gpointer data) GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; + GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_h264_finalize; @@ -584,8 +571,10 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass, gpointer data) gst_caps_unref (sink_caps); /* src pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_h264_src_factory); + g_assert (src_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_H264); g_assert (encoder_class); From 95706691bd129eddd17a40440530e5e38ce08a70 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jul 2020 18:59:18 +0800 Subject: [PATCH 3659/3781] plugin: encode: h265: Use the dynamically built src template caps. Part-of: --- gst/vaapi/gstvaapiencode_h265.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 2cb5061097..46799e680a 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -52,20 +52,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h265_encode_debug); "stream-format = (string) { hvc1, byte-stream }, " \ "alignment = (string) au" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_h265_src_caps_str[] = - GST_CODEC_CAPS ", " - "profile = (string) { main, main-10, main-444, main-444-10, main-422-10 }"; -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_h265_src_factory = - GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_h265_src_caps_str)); -/* *INDENT-ON* */ - #define EXTRA_FORMATS {} /* h265 encode */ @@ -372,6 +358,7 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass, gpointer data) GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; + GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_h265_finalize; @@ -398,8 +385,10 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass, gpointer data) gst_caps_unref (sink_caps); /* src pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_h265_src_factory); + g_assert (src_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_H265); g_assert (encoder_class); From f321c1b84df4ac5ab9a1c2e9ad7779f2e42f5eb2 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jul 2020 19:00:39 +0800 Subject: [PATCH 3660/3781] plugin: encode: mpeg2: Use the dynamically built src template caps. Part-of: --- gst/vaapi/gstvaapiencode_mpeg2.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index ee0c116aa2..f8d161a2b5 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -52,19 +52,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); "video/mpeg, mpegversion = (int) 2, " \ "systemstream = (boolean) false" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_mpeg2_src_caps_str[] = - GST_CODEC_CAPS; -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_mpeg2_src_factory = - GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_mpeg2_src_caps_str)); -/* *INDENT-ON* */ - #define EXTRA_FORMATS {} /* mpeg2 encode */ @@ -109,6 +96,7 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass, GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; + GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_mpeg2_finalize; @@ -130,8 +118,10 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass, gst_caps_unref (sink_caps); /* src pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_mpeg2_src_factory); + g_assert (src_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_MPEG2); g_assert (encoder_class); From adff28f8d26e7e138dacf067157965ae45bc394e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jul 2020 19:02:23 +0800 Subject: [PATCH 3661/3781] plugin: encode: jpeg: Use the dynamically built src template caps. Part-of: --- gst/vaapi/gstvaapiencode_jpeg.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index 57b0a8eb8e..ee406a8517 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -49,19 +49,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_jpeg_encode_debug); #define GST_CODEC_CAPS \ "image/jpeg" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_jpeg_src_caps_str[] = - GST_CODEC_CAPS; -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_jpeg_src_factory = - GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_jpeg_src_caps_str)); -/* *INDENT-ON* */ - #define EXTRA_FORMATS { GST_VIDEO_FORMAT_BGRA, } /* jpeg encode */ @@ -103,6 +90,7 @@ gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass, gpointer data) GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; + GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_jpeg_finalize; @@ -125,8 +113,10 @@ gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass, gpointer data) gst_caps_unref (sink_caps); /* src pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_jpeg_src_factory); + g_assert (src_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_JPEG); g_assert (encoder_class); From f3540c101ccaa23654db0000ad0ddeb1bed206f4 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jul 2020 19:02:45 +0800 Subject: [PATCH 3662/3781] plugin: encode: vp8: Use the dynamically built src template caps. Part-of: --- gst/vaapi/gstvaapiencode_vp8.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 96146b9d54..01c41288f8 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -49,19 +49,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp8_encode_debug); #define GST_CODEC_CAPS \ "video/x-vp8" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_vp8_src_caps_str[] = - GST_CODEC_CAPS; -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_vp8_src_factory = - GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_vp8_src_caps_str)); -/* *INDENT-ON* */ - #define EXTRA_FORMATS {} /* vp8 encode */ @@ -103,6 +90,7 @@ gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass, gpointer data) GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; + GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_vp8_finalize; @@ -125,8 +113,10 @@ gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass, gpointer data) gst_caps_unref (sink_caps); /* src pad */ - gst_element_class_add_static_pad_template (element_class, - &gst_vaapiencode_vp8_src_factory); + g_assert (src_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_VP8); g_assert (encoder_class); From f7e0303b9c276b18ea3ebbfc68bbef3954ad6394 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jul 2020 19:03:14 +0800 Subject: [PATCH 3663/3781] plugin: encode: vp9: Use the dynamically built src template caps. Part-of: --- gst/vaapi/gstvaapiencode_vp9.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index baf6c07d8f..def4ba2ffc 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -49,19 +49,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp9_encode_debug); #define GST_CODEC_CAPS \ "video/x-vp9" -/* *INDENT-OFF* */ -static const char gst_vaapiencode_vp9_src_caps_str[] = - GST_CODEC_CAPS; -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -static GstStaticPadTemplate gst_vaapiencode_vp9_src_factory = - GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (gst_vaapiencode_vp9_src_caps_str)); -/* *INDENT-ON* */ - #define EXTRA_FORMATS {} /* vp9 encode */ @@ -103,6 +90,7 @@ gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass, gpointer data) GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; + GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_vp9_finalize; @@ -125,8 +113,10 @@ gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass, gpointer data) gst_caps_unref (sink_caps); /* src pad */ + g_assert (src_caps); gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_vaapiencode_vp9_src_factory)); + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_VP9); g_assert (encoder_class); From e911c1ff02a44e16c9dbce0fc4b2541b9d3ad6f2 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 9 Jul 2020 13:49:29 +0800 Subject: [PATCH 3664/3781] plugin: encode: Add static caps for template documentation. Part-of: --- gst/vaapi/gstvaapiencode.h | 12 ++++++++++++ gst/vaapi/gstvaapiencode_h264.c | 17 +++++++++++++---- gst/vaapi/gstvaapiencode_h265.c | 17 +++++++++++++---- gst/vaapi/gstvaapiencode_jpeg.c | 17 +++++++++++++---- gst/vaapi/gstvaapiencode_mpeg2.c | 17 +++++++++++++---- gst/vaapi/gstvaapiencode_vp8.c | 17 +++++++++++++---- gst/vaapi/gstvaapiencode_vp9.c | 17 +++++++++++++---- 7 files changed, 90 insertions(+), 24 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 9e8d8c2eb7..9c3fc1b062 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -51,6 +51,18 @@ struct _GstVaapiEncodeInitData GstCaps *src_caps; }; +/* *INDENT-OFF* */ +#define GST_VAAPI_ENCODE_STATIC_SINK_CAPS \ + GST_VAAPI_MAKE_SURFACE_CAPS ", " \ + GST_CAPS_INTERLACED_FALSE "; " \ + GST_VIDEO_CAPS_MAKE (GST_VAAPI_FORMATS_ALL) ", " \ + GST_CAPS_INTERLACED_FALSE ";" \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \ + GST_CAPS_FEATURE_MEMORY_DMABUF, \ + GST_VAAPI_FORMATS_ALL) "," \ + GST_CAPS_INTERLACED_FALSE +/* *INDENT-ON* */ + #define GST_VAAPI_ENCODE_REGISTER_TYPE(NAME, CODEC, CLASS, _EXT_FMT_, FUN) \ static GstVaapiEncodeInitData encode_init_data = { NULL, NULL }; \ static GType encode_type = G_TYPE_INVALID; \ diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index 7fa36acd3d..f69c033477 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -546,6 +546,8 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass, gpointer data) GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; + GstPadTemplate *templ; + GstCaps *static_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_h264_finalize; @@ -566,14 +568,21 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass, gpointer data) /* sink pad */ g_assert (sink_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + static_caps = gst_caps_from_string (GST_VAAPI_ENCODE_STATIC_SINK_CAPS); + templ = + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (sink_caps); /* src pad */ g_assert (src_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + static_caps = gst_caps_from_string (GST_CODEC_CAPS); + templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_H264); diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 46799e680a..e693c908a2 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -359,6 +359,8 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass, gpointer data) GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; + GstPadTemplate *templ; + GstCaps *static_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_h265_finalize; @@ -380,14 +382,21 @@ gst_vaapiencode_h265_class_init (GstVaapiEncodeH265Class * klass, gpointer data) /* sink pad */ g_assert (sink_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + static_caps = gst_caps_from_string (GST_VAAPI_ENCODE_STATIC_SINK_CAPS); + templ = + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (sink_caps); /* src pad */ g_assert (src_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + static_caps = gst_caps_from_string (GST_CODEC_CAPS); + templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_H265); diff --git a/gst/vaapi/gstvaapiencode_jpeg.c b/gst/vaapi/gstvaapiencode_jpeg.c index ee406a8517..667a18421b 100644 --- a/gst/vaapi/gstvaapiencode_jpeg.c +++ b/gst/vaapi/gstvaapiencode_jpeg.c @@ -91,6 +91,8 @@ gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass, gpointer data) GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; + GstPadTemplate *templ; + GstCaps *static_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_jpeg_finalize; @@ -108,14 +110,21 @@ gst_vaapiencode_jpeg_class_init (GstVaapiEncodeJpegClass * klass, gpointer data) /* sink pad */ g_assert (sink_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + static_caps = gst_caps_from_string (GST_VAAPI_ENCODE_STATIC_SINK_CAPS); + templ = + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (sink_caps); /* src pad */ g_assert (src_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + static_caps = gst_caps_from_string (GST_CODEC_CAPS); + templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_JPEG); diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c index f8d161a2b5..0701a102a5 100644 --- a/gst/vaapi/gstvaapiencode_mpeg2.c +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -97,6 +97,8 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass, GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; + GstPadTemplate *templ; + GstCaps *static_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_mpeg2_finalize; @@ -113,14 +115,21 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass, /* sink pad */ g_assert (sink_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + static_caps = gst_caps_from_string (GST_VAAPI_ENCODE_STATIC_SINK_CAPS); + templ = + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (sink_caps); /* src pad */ g_assert (src_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + static_caps = gst_caps_from_string (GST_CODEC_CAPS); + templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_MPEG2); diff --git a/gst/vaapi/gstvaapiencode_vp8.c b/gst/vaapi/gstvaapiencode_vp8.c index 01c41288f8..a8f0d34134 100644 --- a/gst/vaapi/gstvaapiencode_vp8.c +++ b/gst/vaapi/gstvaapiencode_vp8.c @@ -91,6 +91,8 @@ gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass, gpointer data) GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; + GstPadTemplate *templ; + GstCaps *static_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_vp8_finalize; @@ -108,14 +110,21 @@ gst_vaapiencode_vp8_class_init (GstVaapiEncodeVP8Class * klass, gpointer data) /* sink pad */ g_assert (sink_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + static_caps = gst_caps_from_string (GST_VAAPI_ENCODE_STATIC_SINK_CAPS); + templ = + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (sink_caps); /* src pad */ g_assert (src_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + static_caps = gst_caps_from_string (GST_CODEC_CAPS); + templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_VP8); diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index def4ba2ffc..053bf53d98 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -91,6 +91,8 @@ gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass, gpointer data) GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); GstCaps *sink_caps = ((GstVaapiEncodeInitData *) data)->sink_caps; GstCaps *src_caps = ((GstVaapiEncodeInitData *) data)->src_caps; + GstPadTemplate *templ; + GstCaps *static_caps; gpointer encoder_class; object_class->finalize = gst_vaapiencode_vp9_finalize; @@ -108,14 +110,21 @@ gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass, gpointer data) /* sink pad */ g_assert (sink_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps)); + static_caps = gst_caps_from_string (GST_VAAPI_ENCODE_STATIC_SINK_CAPS); + templ = + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (sink_caps); /* src pad */ g_assert (src_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps)); + static_caps = gst_caps_from_string (GST_CODEC_CAPS); + templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps); + gst_pad_template_set_documentation_caps (templ, static_caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (static_caps); gst_caps_unref (src_caps); encoder_class = g_type_class_ref (GST_TYPE_VAAPI_ENCODER_VP9); From 5b05e28a55f573492e9b1c5bc981d388bdfe9fbf Mon Sep 17 00:00:00 2001 From: Marc Leeman Date: Fri, 24 Jul 2020 12:54:31 +0200 Subject: [PATCH 3665/3781] postproc: reconfigure after changing cropping values Part-of: --- gst/vaapi/gstvaapipostproc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 4afb869596..62e0ddac5a 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -2110,21 +2110,37 @@ gst_vaapipostproc_set_property (GObject * object, postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SKINTONE_LEVEL; break; case PROP_CROP_LEFT: + { + guint prev_crop_left = postproc->crop_left; postproc->crop_left = g_value_get_uint (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CROP; + do_reconf = (prev_crop_left != postproc->crop_left); break; + } case PROP_CROP_RIGHT: + { + guint prev_crop_right = postproc->crop_right; postproc->crop_right = g_value_get_uint (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CROP; + do_reconf = (prev_crop_right != postproc->crop_right); break; + } case PROP_CROP_TOP: + { + guint prev_crop_top = postproc->crop_top; postproc->crop_top = g_value_get_uint (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CROP; + do_reconf = (prev_crop_top != postproc->crop_top); break; + } case PROP_CROP_BOTTOM: + { + guint prev_crop_bottom = postproc->crop_bottom; postproc->crop_bottom = g_value_get_uint (value); postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CROP; + do_reconf = (prev_crop_bottom != postproc->crop_bottom); break; + } case PROP_HDR_TONE_MAP: postproc->hdr_tone_map = g_value_get_enum (value); break; From ee7677211add3dbb8ada038c415373827ecb0721 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 15 Apr 2020 16:26:55 +0800 Subject: [PATCH 3666/3781] libs: encoder: h265: Deprecate the low-delay-b property. In HEVC, P and B definitions are different from AVC: P frames have just one reference list and so 1 MV, while B frames have two reference lists and so 2 MVs. No matter B or P, ist reference lists can contain forward/backward reference. So P and B can both have bi-directions dependency, the difference is just their reference list number (i.e. MV number). This is different from the AVC. The *low delay b mode* refers to a special HEVC mode, in which the stream just contain I and B frames, without P frames, and all B frames only have forward direction dependencies (i.e. all inter frames have 2 reference lists but no backward reference in both lists). This is similar to AVC I/P mode, but changing the P to the forward dependent B. The `low-delay-b` property is now just used to simply convert all P frames to B frames when driver does not support P frames (so both reference lists have the same references frames). This is a little different from the meaning of low delay b mode (the two ref lists may have the different reference frames). And the driver now can report whether it supports P frames correctly, so there is no need to use this property and deprecate it. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 31 ++++++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 1530a27e9b..a4fd43bf3f 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -116,7 +116,8 @@ struct _GstVaapiEncoderH265 guint32 quality_factor; GstClockTime cts_offset; gboolean config_changed; - gboolean low_delay_b; + /* Always need two reference lists for inter frame */ + gboolean no_p_frame; guint32 num_tile_cols; guint32 num_tile_rows; /* CTUs start address used in stream pack */ @@ -1873,7 +1874,7 @@ create_and_fill_one_slice (GstVaapiEncoderH265 * encoder, memset (slice_param, 0, sizeof (VAEncSliceParameterBufferHEVC)); slice_param->slice_type = h265_get_slice_type (picture->type); - if (encoder->low_delay_b && slice_param->slice_type == GST_H265_P_SLICE) { + if (encoder->no_p_frame && slice_param->slice_type == GST_H265_P_SLICE) { slice_param->slice_type = GST_H265_B_SLICE; } slice_param->slice_pic_parameter_set_id = 0; @@ -1888,7 +1889,7 @@ create_and_fill_one_slice (GstVaapiEncoderH265 * encoder, slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1; else slice_param->num_ref_idx_l1_active_minus1 = 0; - if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->low_delay_b) + if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->no_p_frame) slice_param->num_ref_idx_l1_active_minus1 = slice_param->num_ref_idx_l0_active_minus1; @@ -1912,7 +1913,7 @@ create_and_fill_one_slice (GstVaapiEncoderH265 * encoder, GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic); slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_1[i_ref]->poc; } - } else if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->low_delay_b) { + } else if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->no_p_frame) { for (; i_ref < reflist_0_count; ++i_ref) { slice_param->ref_pic_list1[i_ref].picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic); @@ -1979,7 +1980,6 @@ add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, " CTU num %d", i_slice, encoder->tile_slice_address[i_slice], slice_param->slice_segment_address, slice_param->num_ctu_in_slice); - if (i_slice == encoder->num_slices - 1) slice_param->slice_fields.bits.last_slice_of_pic_flag = 1; @@ -3171,6 +3171,7 @@ gst_vaapi_encoder_h265_init (GstVaapiEncoderH265 * encoder) encoder->conformance_window_flag = 0; encoder->num_slices = 1; + encoder->no_p_frame = FALSE; /* re-ordering list initialize */ reorder_pool = &encoder->reorder_pool; @@ -3263,7 +3264,9 @@ enum ENCODER_H265_PROP_MBBRC, ENCODER_H265_PROP_QP_IP, ENCODER_H265_PROP_QP_IB, +#ifndef GST_REMOVE_DEPRECATED ENCODER_H265_PROP_LOW_DELAY_B, +#endif ENCODER_H265_PROP_MAX_QP, ENCODER_H265_PROP_QUALITY_FACTOR, ENCODER_H265_PROP_NUM_TILE_COLS, @@ -3321,9 +3324,19 @@ gst_vaapi_encoder_h265_set_property (GObject * object, guint prop_id, case ENCODER_H265_PROP_MBBRC: encoder->mbbrc = g_value_get_enum (value); break; +#ifndef GST_REMOVE_DEPRECATED case ENCODER_H265_PROP_LOW_DELAY_B: - encoder->low_delay_b = g_value_get_boolean (value); +#if !VA_CHECK_VERSION(1,9,0) + encoder->no_p_frame = g_value_get_boolean (value); +#else + if (g_value_get_boolean (value) == TRUE) { + GST_WARNING ("Deprecate low-delay-b property. Driver now already" + " has the ability to detect whether supporting P frames. this" + " value should not be set manually and will take no effect."); + } +#endif break; +#endif case ENCODER_H265_PROP_MAX_QP: encoder->max_qp = g_value_get_uint (value); break; @@ -3382,9 +3395,11 @@ gst_vaapi_encoder_h265_get_property (GObject * object, guint prop_id, case ENCODER_H265_PROP_MBBRC: g_value_set_enum (value, encoder->mbbrc); break; +#ifndef GST_REMOVE_DEPRECATED case ENCODER_H265_PROP_LOW_DELAY_B: - g_value_set_boolean (value, encoder->low_delay_b); + g_value_set_boolean (value, encoder->no_p_frame); break; +#endif case ENCODER_H265_PROP_MAX_QP: g_value_set_uint (value, encoder->max_qp); break; @@ -3576,6 +3591,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | GST_VAAPI_PARAM_ENCODER_EXPOSURE); +#ifndef GST_REMOVE_DEPRECATED /** * GstVaapiEncoderH265:low_delay_b: * @@ -3588,6 +3604,7 @@ gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass) " Enable it when P frames are not supported.", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | GST_VAAPI_PARAM_ENCODER_EXPOSURE); +#endif /** * GstVaapiEncoderH265:quality_factor: From a73e6b7dac00789b6eb829479cb8d7080f4c6528 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 1 Jul 2020 14:50:51 +0800 Subject: [PATCH 3667/3781] libs: encoder: h265: set no P frame automatically. The double reference lists may be required by drivers and there should be no P frames in the of stream. The old way of converting P frames to B frames is by setting `low-delay-b` property, which is unconvenient and has bad user experience, since most of the users do not know when to set this property, and if it is not set correctly, the encoding pipeline fails or even hangs on some platforms. VA driver now provides a attribute to query whether both reference lists must be un-NULL for a profile/entrypoint pair. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 51 ++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index a4fd43bf3f..0e0a766d05 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2323,7 +2323,46 @@ ensure_profile_tier_level (GstVaapiEncoderH265 * encoder) return GST_VAAPI_ENCODER_STATUS_SUCCESS; } -static void +static gboolean +check_ref_list (GstVaapiEncoderH265 * encoder) +{ +#if VA_CHECK_VERSION(1,9,0) + /* Some driver require both r0 and r1 list are non NULL, i.e. no p frame + in the stream. The traditional P frame can be converted to B frame with + forward dependency only. The new B frame has only forward reference in + both r0 and r1 list, which conforms to H265 spec. This can get some gain + because there are 2 MVs for each frame and can generate better motion + estimation. */ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (encoder); + guint value = 0; + VAProfile va_profile = gst_vaapi_profile_get_va_profile (encoder->profile); + VAEntrypoint va_entrypoint = + gst_vaapi_entrypoint_get_va_entrypoint (encoder->entrypoint); + + encoder->no_p_frame = FALSE; + if (gst_vaapi_get_config_attribute (base_encoder->display, va_profile, + va_entrypoint, VAConfigAttribPredictionDirection, &value)) { + gboolean double_ref_list = + ((value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) != 0); + if (double_ref_list) { + GST_INFO ("driver does not support P frame, we need to convert P" + " frame to forward dependency B frame."); + encoder->no_p_frame = double_ref_list; + } + } + + if (encoder->no_p_frame == TRUE && base_encoder->max_num_ref_frames_1 < 1) { + GST_WARNING ("P frame should be converted to forward dependent B," + " but reference list 1 is disabled here. Should be an invalid" + " setting or a driver error."); + return FALSE; + } +#endif + + return TRUE; +} + +static GstVaapiEncoderStatus reset_properties (GstVaapiEncoderH265 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); @@ -2350,6 +2389,9 @@ reset_properties (GstVaapiEncoderH265 * encoder) gst_vaapi_encoder_ensure_max_num_ref_frames (base_encoder, encoder->profile, encoder->entrypoint); + if (!check_ref_list (encoder)) + return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN; + if (base_encoder->max_num_ref_frames_1 < 1 && encoder->num_bframes > 0) { GST_WARNING ("Disabling b-frame since the driver doesn't support it"); encoder->num_bframes = 0; @@ -2394,6 +2436,8 @@ reset_properties (GstVaapiEncoderH265 * encoder) reorder_pool = &encoder->reorder_pool; reorder_pool->frame_index = 0; + + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } static void @@ -3151,7 +3195,10 @@ gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder) encoder->ctu_height = (encoder->luma_height + 31) / 32; } - reset_properties (encoder); + status = reset_properties (encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + return status; + status = ensure_tile (encoder); if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return status; From 9ccb0c57fa86b8b71b6185a4cf75ee957a6881f4 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Mon, 6 Jul 2020 09:59:40 +0200 Subject: [PATCH 3668/3781] libs: window: wayland: wait for configure before committing the first buffer Committing the first buffer for a surface must not be done before ack_configure() has been sent for the xdg_surface. With weston, the commit will fail with "error 3: xdg_surface has never been configured". Wait in gst_vaapi_window_wayland_show() until configure is done to avoid this. Part-of: --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 8e091523fb..abf492f419 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -111,6 +111,7 @@ struct _GstVaapiWindowWaylandPrivate guint fullscreen_on_show:1; guint sync_failed:1; volatile guint num_frames_pending; + gint configure_pending; gboolean need_vpp; }; @@ -184,6 +185,8 @@ static const struct xdg_toplevel_listener xdg_toplevel_listener = { handle_xdg_toplevel_close, }; +static gboolean gst_vaapi_window_wayland_sync (GstVaapiWindow * window); + static gboolean gst_vaapi_window_wayland_show (GstVaapiWindow * window) { @@ -200,6 +203,8 @@ gst_vaapi_window_wayland_show (GstVaapiWindow * window) return TRUE; } + g_atomic_int_set (&priv->configure_pending, 1); + g_atomic_int_inc (&priv->num_frames_pending); /* Create a toplevel window out of it */ priv->xdg_toplevel = xdg_surface_get_toplevel (priv->xdg_surface); g_return_val_if_fail (priv->xdg_toplevel, FALSE); @@ -213,7 +218,7 @@ gst_vaapi_window_wayland_show (GstVaapiWindow * window) /* Commit the xdg_surface state as top-level window */ wl_surface_commit (priv->surface); - return TRUE; + return gst_vaapi_window_wayland_sync (window); } static gboolean @@ -322,7 +327,13 @@ static void handle_xdg_surface_configure (void *data, struct xdg_surface *xdg_surface, uint32_t serial) { + GstVaapiWindow *window = GST_VAAPI_WINDOW (data); + GstVaapiWindowWaylandPrivate *priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + xdg_surface_ack_configure (xdg_surface, serial); + if (g_atomic_int_compare_and_exchange (&priv->configure_pending, 1, 0)) + g_atomic_int_dec_and_test (&priv->num_frames_pending); } static const struct xdg_surface_listener xdg_surface_listener = { From bef64a6420541bda22851da5652f04c0bef00a6e Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Wed, 22 Jul 2020 09:36:18 +0200 Subject: [PATCH 3669/3781] libs: display: wayland: add basic dmabuf protocol support This is just the basic infrastructure. Hook up the interface and collect all supported formats. Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 43 +++++++++++++++++++ .../gst/vaapi/gstvaapidisplay_wayland_priv.h | 10 +++++ gst-libs/gst/vaapi/meson.build | 11 +++++ 3 files changed, 64 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 8803c294bd..7dfe857802 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -105,6 +105,42 @@ 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, @@ -126,6 +162,10 @@ registry_handle_global (void *data, 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); } } @@ -217,6 +257,8 @@ gst_vaapi_display_wayland_close_display (GstVaapiDisplay * display) 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); @@ -294,6 +336,7 @@ gst_vaapi_display_wayland_init (GstVaapiDisplayWayland * display) display->priv = priv; priv->event_fd = -1; + priv->dmabuf_formats = g_array_new (FALSE, FALSE, sizeof (GstDRMFormat)); } static void diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index b09adfb231..6822d822ea 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -25,6 +25,7 @@ #define GST_VAAPI_DISPLAY_WAYLAND_PRIV_H #include "xdg-shell-client-protocol.h" +#include "linux-dmabuf-unstable-v1-client-protocol.h" #include #include "gstvaapidisplay_priv.h" @@ -57,6 +58,13 @@ typedef struct _GstVaapiDisplayWaylandClass GstVaapiDisplayWaylandClass; #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; @@ -65,7 +73,9 @@ struct _GstVaapiDisplayWaylandPrivate struct wl_shell *wl_shell; struct xdg_wm_base *xdg_wm_base; struct wl_output *output; + struct zwp_linux_dmabuf_v1 *dmabuf; struct wl_registry *registry; + GArray *dmabuf_formats; guint width; guint height; guint phys_width; diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 246ac30bbf..bcf261fd11 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -174,12 +174,23 @@ if USE_WAYLAND command: [ wayland_scanner_bin, 'private-code', '@INPUT@', '@OUTPUT@' ], input: xdg_shell_xml_spec, output: 'xdg-shell-client-protocol.c') + dmabuf_xml_spec = join_paths(wayland_protocols_basedir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unstable-v1.xml') + dmabuf_header = custom_target('vaapi-dmabuf-client-header', + command: [ wayland_scanner_bin, 'client-header', '@INPUT@', '@OUTPUT@' ], + input: dmabuf_xml_spec, + output: 'linux-dmabuf-unstable-v1-client-protocol.h') + dmabuf_code = custom_target('vaapi-dmabuf-client-code', + command: [ wayland_scanner_bin, 'private-code', '@INPUT@', '@OUTPUT@' ], + input: dmabuf_xml_spec, + output: 'linux-dmabuf-unstable-v1-client-protocol.c') gstlibvaapi_sources += [ 'gstvaapidisplay_wayland.c', 'gstvaapiwindow_wayland.c', xdg_shell_header, xdg_shell_code, + dmabuf_header, + dmabuf_code, ] gstlibvaapi_headers += [ 'gstvaapidisplay_wayland.h', From 856b9d59808dee22673be096470e70bfdad19ae9 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Sun, 28 Jun 2020 17:42:29 +0200 Subject: [PATCH 3670/3781] video-format: add DRM formats to the mapping table This will be needed for the DMABuf protocol support to map DRM formats to vaapi and gstreamer formats. Part-of: --- gst-libs/gst/vaapi/video-format.c | 156 ++++++++++++++++++++++-------- gst-libs/gst/vaapi/video-format.h | 6 ++ 2 files changed, 121 insertions(+), 41 deletions(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 7fb1b1a5b6..fe466794ed 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -35,22 +35,35 @@ #define DEBUG 1 #include "gst/vaapi/gstvaapidebug.h" +#if USE_DRM +#include +#endif + typedef struct _GstVideoFormatMapMap { GstVideoFormat format; + uint32_t drm_format; GstVaapiChromaType chroma_type; VAImageFormat va_format; } GstVideoFormatMap; #define VA_BYTE_ORDER_NOT_CARE 0 -#define DEF_YUV(BYTE_ORDER, FORMAT, FOURCC, BPP, SUB) \ +#if USE_DRM +#define MAKE_DRM_FORMAT(DRM_FORMAT) G_PASTE(DRM_FORMAT_,DRM_FORMAT) +#else +#define MAKE_DRM_FORMAT(DRM_FORMAT) 0 +#endif + +#define DEF_YUV(BYTE_ORDER, FORMAT, DRM_FORMAT, FOURCC, BPP, SUB) \ { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ + MAKE_DRM_FORMAT(DRM_FORMAT), \ G_PASTE(GST_VAAPI_CHROMA_TYPE_YUV,SUB), \ { VA_FOURCC FOURCC, BYTE_ORDER, BPP, }, } -#define DEF_RGB(BYTE_ORDER, FORMAT, FOURCC, BPP, DEPTH, R,G,B,A) \ +#define DEF_RGB(BYTE_ORDER, FORMAT, DRM, FOURCC, BPP, DEPTH, R,G,B,A) \ { G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \ + MAKE_DRM_FORMAT(DRM), \ G_PASTE(GST_VAAPI_CHROMA_TYPE_RGB,BPP), \ { VA_FOURCC FOURCC, BYTE_ORDER, BPP, DEPTH, R, G, B, A }, } @@ -83,85 +96,85 @@ static const GstVideoFormatMap gst_vaapi_video_default_formats[] = { */ /* YUV formats */ - DEF_YUV (VA_BYTE_ORDER_NOT_CARE, NV12, ('N', 'V', '1', '2'), 12, 420), - DEF_YUV (VA_BYTE_ORDER_NOT_CARE, YV12, ('Y', 'V', '1', '2'), 12, 420), - DEF_YUV (VA_BYTE_ORDER_NOT_CARE, I420, ('I', '4', '2', '0'), 12, 420), - DEF_YUV (VA_BYTE_ORDER_NOT_CARE, YUY2, ('Y', 'U', 'Y', '2'), 16, 422), - DEF_YUV (VA_BYTE_ORDER_NOT_CARE, UYVY, ('U', 'Y', 'V', 'Y'), 16, 422), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, NV12, NV12, ('N', 'V', '1', '2'), 12, 420), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, YV12, YVU420, ('Y', 'V', '1', '2'), 12, 420), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, I420, YUV420, ('I', '4', '2', '0'), 12, 420), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, YUY2, YUYV, ('Y', 'U', 'Y', '2'), 16, 422), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, UYVY, UYVY, ('U', 'Y', 'V', 'Y'), 16, 422), - DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y444, ('4', '4', '4', 'P'), 24, 444), - DEF_YUV (VA_BYTE_ORDER_NOT_CARE, GRAY8, ('Y', '8', '0', '0'), 8, 400), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y444, YUV444, ('4', '4', '4', 'P'), 24, 444), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, GRAY8, INVALID, ('Y', '8', '0', '0'), 8, 400), - DEF_YUV (VA_LSB_FIRST, P010_10LE, ('P', '0', '1', '0'), 24, 420_10BPP), - DEF_YUV (VA_LSB_FIRST, P012_LE, ('P', '0', '1', '2'), 24, 420_12BPP), + DEF_YUV (VA_LSB_FIRST, P010_10LE, P010, ('P', '0', '1', '0'), 24, 420_10BPP), + DEF_YUV (VA_LSB_FIRST, P012_LE, P012, ('P', '0', '1', '2'), 24, 420_10BPP), /* AYUV is a clear defined format by doc */ - DEF_YUV (VA_LSB_FIRST, VUYA, ('A', 'Y', 'U', 'V'), 32, 444), + DEF_YUV (VA_LSB_FIRST, VUYA, AYUV, ('A', 'Y', 'U', 'V'), 32, 444), - DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y210, ('Y', '2', '1', '0'), 32, 422_10BPP), - DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y410, ('Y', '4', '1', '0'), 32, 444_10BPP), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y210, Y210, ('Y', '2', '1', '0'), 32, 422_10BPP), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y410, Y410, ('Y', '4', '1', '0'), 32, 444_10BPP), /* RGB formats */ - DEF_RGB (VA_LSB_FIRST, ARGB, ('A', 'R', 'G', 'B'), 32, 32, 0x0000ff00, + DEF_RGB (VA_LSB_FIRST, ARGB, BGRA8888, ('A', 'R', 'G', 'B'), 32, 32, 0x0000ff00, 0x00ff0000, 0xff000000, 0x000000ff), - DEF_RGB (VA_LSB_FIRST, ARGB, ('B', 'G', 'R', 'A'), 32, 32, 0x0000ff00, + DEF_RGB (VA_LSB_FIRST, ARGB, BGRA8888, ('B', 'G', 'R', 'A'), 32, 32, 0x0000ff00, 0x00ff0000, 0xff000000, 0x000000ff), - DEF_RGB (VA_MSB_FIRST, ARGB, ('A', 'R', 'G', 'B'), 32, 32, 0x00ff0000, + DEF_RGB (VA_MSB_FIRST, ARGB, BGRA8888, ('A', 'R', 'G', 'B'), 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), - DEF_RGB (VA_LSB_FIRST, xRGB, ('X', 'R', 'G', 'B'), 32, 24, 0x0000ff00, + DEF_RGB (VA_LSB_FIRST, xRGB, BGRX8888, ('X', 'R', 'G', 'B'), 32, 24, 0x0000ff00, 0x00ff0000, 0xff000000, 0x00000000), - DEF_RGB (VA_LSB_FIRST, xRGB, ('B', 'G', 'R', 'X'), 32, 24, 0x0000ff00, + DEF_RGB (VA_LSB_FIRST, xRGB, BGRX8888, ('B', 'G', 'R', 'X'), 32, 24, 0x0000ff00, 0x00ff0000, 0xff000000, 0x00000000), - DEF_RGB (VA_MSB_FIRST, xRGB, ('X', 'R', 'G', 'B'), 32, 24, 0x00ff0000, + DEF_RGB (VA_MSB_FIRST, xRGB, BGRX8888, ('X', 'R', 'G', 'B'), 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), - DEF_RGB (VA_LSB_FIRST, RGBA, ('R', 'G', 'B', 'A'), 32, 32, 0x000000ff, + DEF_RGB (VA_LSB_FIRST, RGBA, ABGR8888, ('R', 'G', 'B', 'A'), 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), - DEF_RGB (VA_LSB_FIRST, RGBA, ('A', 'B', 'G', 'R'), 32, 32, 0x000000ff, + DEF_RGB (VA_LSB_FIRST, RGBA, ABGR8888, ('A', 'B', 'G', 'R'), 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), - DEF_RGB (VA_MSB_FIRST, RGBA, ('R', 'G', 'B', 'A'), 32, 32, 0xff000000, + DEF_RGB (VA_MSB_FIRST, RGBA, ABGR8888, ('R', 'G', 'B', 'A'), 32, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff), - DEF_RGB (VA_LSB_FIRST, RGBx, ('R', 'G', 'B', 'X'), 32, 24, 0x000000ff, + DEF_RGB (VA_LSB_FIRST, RGBx, XBGR8888, ('R', 'G', 'B', 'X'), 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), - DEF_RGB (VA_LSB_FIRST, RGBx, ('X', 'B', 'G', 'R'), 32, 24, 0x000000ff, + DEF_RGB (VA_LSB_FIRST, RGBx, XBGR8888, ('X', 'B', 'G', 'R'), 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), - DEF_RGB (VA_MSB_FIRST, RGBx, ('R', 'G', 'B', 'X'), 32, 24, 0xff000000, + DEF_RGB (VA_MSB_FIRST, RGBx, XBGR8888, ('R', 'G', 'B', 'X'), 32, 24, 0xff000000, 0x00ff0000, 0x0000ff00, 0x00000000), - DEF_RGB (VA_LSB_FIRST, ABGR, ('A', 'B', 'G', 'R'), 32, 32, 0xff000000, + DEF_RGB (VA_LSB_FIRST, ABGR, RGBA8888, ('A', 'B', 'G', 'R'), 32, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff), - DEF_RGB (VA_LSB_FIRST, ABGR, ('R', 'G', 'B', 'A'), 32, 32, 0xff000000, + DEF_RGB (VA_LSB_FIRST, ABGR, RGBA8888, ('R', 'G', 'B', 'A'), 32, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff), - DEF_RGB (VA_MSB_FIRST, ABGR, ('A', 'B', 'G', 'R'), 32, 32, 0x000000ff, + DEF_RGB (VA_MSB_FIRST, ABGR, RGBA8888, ('A', 'B', 'G', 'R'), 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000), - DEF_RGB (VA_LSB_FIRST, xBGR, ('X', 'B', 'G', 'R'), 32, 24, 0xff000000, + DEF_RGB (VA_LSB_FIRST, xBGR, RGBX8888, ('X', 'B', 'G', 'R'), 32, 24, 0xff000000, 0x00ff0000, 0x0000ff00, 0x00000000), - DEF_RGB (VA_LSB_FIRST, xBGR, ('R', 'G', 'B', 'X'), 32, 24, 0xff000000, + DEF_RGB (VA_LSB_FIRST, xBGR, RGBX8888, ('R', 'G', 'B', 'X'), 32, 24, 0xff000000, 0x00ff0000, 0x0000ff00, 0x00000000), - DEF_RGB (VA_MSB_FIRST, xBGR, ('X', 'B', 'G', 'R'), 32, 24, 0x000000ff, + DEF_RGB (VA_MSB_FIRST, xBGR, RGBX8888, ('X', 'B', 'G', 'R'), 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000), - DEF_RGB (VA_LSB_FIRST, BGRA, ('B', 'G', 'R', 'A'), 32, 32, 0x00ff0000, + DEF_RGB (VA_LSB_FIRST, BGRA, ARGB8888, ('B', 'G', 'R', 'A'), 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), - DEF_RGB (VA_LSB_FIRST, BGRA, ('A', 'R', 'G', 'B'), 32, 32, 0x00ff0000, + DEF_RGB (VA_LSB_FIRST, BGRA, ARGB8888, ('A', 'R', 'G', 'B'), 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000), - DEF_RGB (VA_MSB_FIRST, BGRA, ('B', 'G', 'R', 'A'), 32, 32, 0x0000ff00, + DEF_RGB (VA_MSB_FIRST, BGRA, ARGB8888, ('B', 'G', 'R', 'A'), 32, 32, 0x0000ff00, 0x00ff0000, 0xff000000, 0x000000ff), - DEF_RGB (VA_LSB_FIRST, BGRx, ('B', 'G', 'R', 'X'), 32, 24, 0x00ff0000, + DEF_RGB (VA_LSB_FIRST, BGRx, XRGB8888, ('B', 'G', 'R', 'X'), 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), - DEF_RGB (VA_LSB_FIRST, BGRx, ('X', 'R', 'G', 'B'), 32, 24, 0x00ff0000, + DEF_RGB (VA_LSB_FIRST, BGRx, XRGB8888, ('X', 'R', 'G', 'B'), 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), - DEF_RGB (VA_MSB_FIRST, BGRx, ('B', 'G', 'R', 'X'), 32, 24, 0x0000ff00, + DEF_RGB (VA_MSB_FIRST, BGRx, XRGB8888, ('B', 'G', 'R', 'X'), 32, 24, 0x0000ff00, 0x00ff0000, 0xff000000, 0x00000000), - DEF_RGB (VA_BYTE_ORDER_NOT_CARE, RGB16, ('R', 'G', '1', '6'), 16, 16, + DEF_RGB (VA_BYTE_ORDER_NOT_CARE, RGB16, RGB565, ('R', 'G', '1', '6'), 16, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000), - DEF_RGB (VA_BYTE_ORDER_NOT_CARE, RGB, ('R', 'G', '2', '4'), 32, 24, + DEF_RGB (VA_BYTE_ORDER_NOT_CARE, RGB, RGB888, ('R', 'G', '2', '4'), 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000), - DEF_RGB (VA_LSB_FIRST, BGR10A2_LE, ('A', 'R', '3', '0'), 32, 30, + DEF_RGB (VA_LSB_FIRST, BGR10A2_LE, ARGB2101010, ('A', 'R', '3', '0'), 32, 30, 0x3ff00000, 0x000ffc00, 0x000003ff, 0x30000000), {0,} }; @@ -603,3 +616,64 @@ gst_vaapi_video_format_create_map (VAImageFormat * formats, guint n) return once.retval != NULL; } + +/** + * gst_vaapi_drm_format_from_va_fourcc: + * @fourcc: a FOURCC value + * + * Converts a VA fourcc into the corresponding DRM_FORMAT_*. If no + * matching fourcc was found, then DRM_FORMAT_INVALID is returned. + * + * Return value: the DRM_FORMAT_* corresponding to the VA @fourcc + * + * Since: 1.18 + */ +guint +gst_vaapi_drm_format_from_va_fourcc (guint32 fourcc) +{ +#if USE_DRM + const GArray *map = gst_vaapi_video_formats_map; + const GstVideoFormatMap *m; + guint i; + + /* Note: VA fourcc values are now standardized and shall represent + a unique format. The associated VAImageFormat is just a hint to + determine RGBA component ordering */ + for (i = 0; i < map->len; i++) { + m = &g_array_index (map, GstVideoFormatMap, i); + if (m->va_format.fourcc == fourcc) + return m->drm_format; + } + return DRM_FORMAT_INVALID; +#else + return 0; +#endif +} + +/** + * gst_vaapi_video_format_from_drm_format: + * @drm_format: a DRM format value + * + * Converts a DRM_FORMAT_* to the corresponding GstVideoFormat. If no + * matching fourcc was found, then DRM_FORMAT_INVALID is returned. + * + * Return value: GstVideoFormat corresponding to the @drm_format + * + * Since: 1.18 + */ +GstVideoFormat +gst_vaapi_video_format_from_drm_format (guint drm_format) +{ +#if USE_DRM + const GArray *map = gst_vaapi_video_formats_map; + const GstVideoFormatMap *m; + guint i; + + for (i = 0; i < map->len; i++) { + m = &g_array_index (map, GstVideoFormatMap, i); + if (m->drm_format == drm_format) + return m->format; + } +#endif + return GST_VIDEO_FORMAT_UNKNOWN; +} diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index 953194e559..9af180b1d9 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -70,6 +70,12 @@ gst_vaapi_video_format_get_formats_by_chroma (guint chroma); gboolean gst_vaapi_video_format_create_map (VAImageFormat * formats, guint n); +guint +gst_vaapi_drm_format_from_va_fourcc (guint32 fourcc); + +GstVideoFormat +gst_vaapi_video_format_from_drm_format (guint drm_format); + G_END_DECLS #endif /* GST_VAAPI_VIDEO_FORMAT_H */ From 72d32a91d25e2b6ca5e2508f8a46c0dca25d172f Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Tue, 21 Jul 2020 10:03:19 +0200 Subject: [PATCH 3671/3781] libs: window: allow choosing the format for the vpp pool Signed-off-by: Michael Olbrich Part-of: --- gst-libs/gst/vaapi/gstvaapiwindow.c | 18 +++++++++++++++++- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 6 ++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 35ba42cf7f..19085408f7 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -98,6 +98,19 @@ error_unsupported_format: } } +void +gst_vaapi_window_set_vpp_format_internal (GstVaapiWindow * window, + GstVideoFormat format, guint flags) +{ + if (window->surface_pool_format == format && + window->surface_pool_flags == flags) + return; + + gst_vaapi_video_pool_replace (&window->surface_pool, NULL); + window->surface_pool_format = format; + window->surface_pool_flags = flags; +} + static gboolean ensure_filter_surface_pool (GstVaapiWindow * window) { @@ -109,7 +122,8 @@ ensure_filter_surface_pool (GstVaapiWindow * window) /* Ensure VA surface pool is created */ /* XXX: optimize the surface format to use. e.g. YUY2 */ window->surface_pool = gst_vaapi_surface_pool_new (display, - GST_VIDEO_FORMAT_NV12, window->width, window->height, 0); + window->surface_pool_format, window->width, window->height, + window->surface_pool_flags); if (!window->surface_pool) { GST_WARNING ("failed to create surface pool for conversion"); return FALSE; @@ -229,6 +243,8 @@ gst_vaapi_window_new_internal (GType type, GstVaapiDisplay * display, if (!window) return NULL; + window->surface_pool_format = GST_VIDEO_FORMAT_NV12; + window->use_foreign_window = id != GST_VAAPI_ID_INVALID; GST_VAAPI_WINDOW_ID (window) = window->use_foreign_window ? id : 0; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index 09be19c3d4..a0b0582775 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -83,6 +83,8 @@ struct _GstVaapiWindow guint check_geometry:1; /* for conversion */ + GstVideoFormat surface_pool_format; + guint surface_pool_flags; GstVaapiVideoPool *surface_pool; GstVaapiFilter *filter; gboolean has_vpp; @@ -138,6 +140,10 @@ gst_vaapi_window_vpp_convert_internal (GstVaapiWindow * window, GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect, guint flags); +void +gst_vaapi_window_set_vpp_format_internal (GstVaapiWindow * window, + GstVideoFormat format, guint flags); + G_END_DECLS #endif /* GST_VAAPI_WINDOW_PRIV_H */ From afe49e9fdb3b071e693c1cbf268510b89d1cea2e Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Wed, 22 Jul 2020 10:01:41 +0200 Subject: [PATCH 3672/3781] libs: window: wayland: use dmabuf protocol if available Currently vaGetSurfaceBufferWl() is used to create wayland buffers. Unfortunately this is not implemented by the 'media-driver' and Mesa VA-API drivers. And the implementation provided by 'intel-vaapi-driver' is not compatible with a Wayland server that uses the iris Mesa driver. So create the Wayland buffers manually with the zwp_linux_dmabuf_v1 wayland protocol. Formats and modifiers supported by the Wayland server are taken into account. If necessary, VPP is enabled to convert the buffer into a supported format. Fall back to vaGetSurfaceBufferWl() if creating buffers via dambuf protocol fails. Part-of: --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 345 +++++++++++++++++--- 1 file changed, 306 insertions(+), 39 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index abf492f419..b1b32e601c 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -37,6 +37,8 @@ #include "gstvaapifilter.h" #include "gstvaapisurfacepool.h" +#include + GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapi_window); #define GST_CAT_DEFAULT gst_debug_vaapi_window @@ -113,6 +115,7 @@ struct _GstVaapiWindowWaylandPrivate volatile guint num_frames_pending; gint configure_pending; gboolean need_vpp; + gboolean dmabuf_broken; }; /** @@ -532,6 +535,299 @@ static const struct wl_buffer_listener frame_buffer_listener = { frame_release_callback }; +typedef enum +{ + GST_VAAPI_DMABUF_SUCCESS, + GST_VAAPI_DMABUF_BAD_FLAGS, + GST_VAAPI_DMABUF_BAD_FORMAT, + GST_VAAPI_DMABUF_BAD_MODIFIER, + GST_VAAPI_DMABUF_NOT_SUPPORTED, + GST_VAAPI_DMABUF_FLUSH, + +} GstVaapiDmabufStatus; + +#define DRM_FORMAT_MOD_INVALID 0xffffffffffffff + +static GstVaapiDmabufStatus +dmabuf_format_supported (GstVaapiDisplayWaylandPrivate * const priv_display, + guint format, guint64 modifier) +{ + GArray *formats = priv_display->dmabuf_formats; + gboolean linear = FALSE; + gint i; + + for (i = 0; i < formats->len; i++) { + GstDRMFormat fmt = g_array_index (formats, GstDRMFormat, i); + if (fmt.format == format && (fmt.modifier == modifier || + (fmt.modifier == DRM_FORMAT_MOD_INVALID && modifier == 0))) + return GST_VAAPI_DMABUF_SUCCESS; + if (fmt.format == format && (fmt.modifier == 0 || + fmt.modifier == DRM_FORMAT_MOD_INVALID)) + linear = TRUE; + } + if (linear) + return GST_VAAPI_DMABUF_BAD_MODIFIER; + else + return GST_VAAPI_DMABUF_BAD_FORMAT; +} + +GstVideoFormat +check_format (GstVaapiDisplay * const display, gint index, + GstVideoFormat expect) +{ + GstVaapiDisplayWaylandPrivate *const priv_display = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); + GArray *formats = priv_display->dmabuf_formats; + GstDRMFormat fmt = g_array_index (formats, GstDRMFormat, index); + GstVideoFormat format = gst_vaapi_video_format_from_drm_format (fmt.format); + GstVaapiSurface *surface; + + /* unkown formats should be filtered out in the display */ + g_assert (format != GST_VIDEO_FORMAT_UNKNOWN); + + if ((expect != GST_VIDEO_FORMAT_UNKNOWN) && (format != expect)) + return GST_VIDEO_FORMAT_UNKNOWN; + + surface = gst_vaapi_surface_new_with_format (display, format, 64, 64, + fmt.modifier == 0 ? GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE : 0); + if (!surface) + return GST_VIDEO_FORMAT_UNKNOWN; + + gst_vaapi_surface_unref (surface); + + return format; +} + +GstVideoFormat +choose_next_format (GstVaapiDisplay * const display, gint * next_index) +{ + GstVaapiDisplayWaylandPrivate *const priv_display = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); + GArray *formats = priv_display->dmabuf_formats; + GstVideoFormat format; + gint i; + + if (*next_index < 0) { + *next_index = 0; + /* try GST_VIDEO_FORMAT_RGBA first */ + for (i = 0; i < formats->len; i++) { + format = check_format (display, i, GST_VIDEO_FORMAT_RGBA); + if (format != GST_VIDEO_FORMAT_UNKNOWN) + return format; + } + } + + for (i = *next_index; i < formats->len; i++) { + format = check_format (display, i, GST_VIDEO_FORMAT_UNKNOWN); + if (format != GST_VIDEO_FORMAT_UNKNOWN) { + *next_index = i + 1; + return format; + } + } + *next_index = formats->len; + return GST_VIDEO_FORMAT_UNKNOWN; +} + +static GstVaapiDmabufStatus +dmabuf_buffer_from_surface (GstVaapiWindow * window, GstVaapiSurface * surface, + const GstVaapiRectangle * rect, guint va_flags, + struct wl_buffer **out_buffer) +{ + GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window); + GstVaapiDisplayWaylandPrivate *const priv_display = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display); + struct zwp_linux_buffer_params_v1 *params; + struct wl_buffer *buffer = NULL; + VADRMPRIMESurfaceDescriptor desc; + VAStatus status; + GstVaapiDmabufStatus ret; + guint format, i, j, plane = 0; + + if (!priv_display->dmabuf) + return GST_VAAPI_DMABUF_NOT_SUPPORTED; + + if ((va_flags & (VA_TOP_FIELD | VA_BOTTOM_FIELD)) != VA_FRAME_PICTURE) + return GST_VAAPI_DMABUF_BAD_FLAGS; + + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); + status = vaExportSurfaceHandle (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_SURFACE_ID (surface), VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, + VA_EXPORT_SURFACE_SEPARATE_LAYERS | VA_EXPORT_SURFACE_READ_ONLY, &desc); + /* Try again with composed layers, in case the format is supported there */ + if (status == VA_STATUS_ERROR_INVALID_SURFACE) + status = vaExportSurfaceHandle (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_SURFACE_ID (surface), VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, + VA_EXPORT_SURFACE_COMPOSED_LAYERS | VA_EXPORT_SURFACE_READ_ONLY, &desc); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); + + if (!vaapi_check_status (status, "vaExportSurfaceHandle()")) { + if (status == VA_STATUS_ERROR_UNIMPLEMENTED) + return GST_VAAPI_DMABUF_NOT_SUPPORTED; + else + return GST_VAAPI_DMABUF_BAD_FORMAT; + } + + format = gst_vaapi_drm_format_from_va_fourcc (desc.fourcc); + params = zwp_linux_dmabuf_v1_create_params (priv_display->dmabuf); + for (i = 0; i < desc.num_layers; i++) { + for (j = 0; j < desc.layers[i].num_planes; ++j) { + gint object = desc.layers[i].object_index[j]; + guint64 modifier = desc.objects[object].drm_format_modifier; + + ret = dmabuf_format_supported (priv_display, format, modifier); + if (ret != GST_VAAPI_DMABUF_SUCCESS) { + GST_DEBUG ("skipping unsupported format/modifier %s/0x%" + G_GINT64_MODIFIER "x", gst_video_format_to_string + (gst_vaapi_video_format_from_drm_format (format)), modifier); + goto out; + } + + zwp_linux_buffer_params_v1_add (params, + desc.objects[object].fd, plane, desc.layers[i].offset[j], + desc.layers[i].pitch[j], modifier >> 32, + modifier & G_GUINT64_CONSTANT (0xffffffff)); + plane++; + } + } + + buffer = zwp_linux_buffer_params_v1_create_immed (params, rect->width, + rect->height, format, 0); + + if (!buffer) + ret = GST_VAAPI_DMABUF_NOT_SUPPORTED; + +out: + zwp_linux_buffer_params_v1_destroy (params); + + for (i = 0; i < desc.num_objects; i++) + close (desc.objects[i].fd); + + *out_buffer = buffer; + return ret; +} + +static gboolean +buffer_from_surface (GstVaapiWindow * window, GstVaapiSurface ** surf, + const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect, + guint flags, struct wl_buffer **buffer) +{ + GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window); + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + GstVaapiSurface *surface; + GstVaapiDmabufStatus ret; + guint va_flags; + VAStatus status; + gint format_index = -1; + + va_flags = from_GstVaapiSurfaceRenderFlags (flags); + +again: + surface = *surf; + if (priv->need_vpp) { + GstVaapiSurface *vpp_surface = NULL; + if (window->has_vpp) { + GST_LOG ("VPP: %s <%d, %d, %d, %d> -> %s <%d, %d, %d, %d>", + gst_video_format_to_string (gst_vaapi_surface_get_format (surface)), + src_rect->x, src_rect->y, src_rect->width, src_rect->height, + gst_video_format_to_string (window->surface_pool_format), + dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height); + vpp_surface = gst_vaapi_window_vpp_convert_internal (window, surface, + src_rect, dst_rect, flags); + } + if (G_UNLIKELY (!vpp_surface)) { + /* Not all formats are supported as destination format during VPP. + So try again with the next format if VPP fails. */ + GstVideoFormat format = choose_next_format (display, &format_index); + if ((format != GST_VIDEO_FORMAT_UNKNOWN) && window->has_vpp) { + GST_DEBUG ("VPP failed. Try again with format %s", + gst_video_format_to_string (format)); + gst_vaapi_window_set_vpp_format_internal (window, format, 0); + goto again; + } else { + GST_WARNING ("VPP failed. No supported format found."); + priv->dmabuf_broken = TRUE; + } + } else { + surface = vpp_surface; + va_flags = VA_FRAME_PICTURE; + } + } + if (!priv->dmabuf_broken) { + ret = dmabuf_buffer_from_surface (window, surface, dst_rect, va_flags, + buffer); + switch (ret) { + case GST_VAAPI_DMABUF_SUCCESS: + goto out; + case GST_VAAPI_DMABUF_BAD_FLAGS: + /* FIXME: how should this be handed? */ + break; + case GST_VAAPI_DMABUF_BAD_FORMAT:{ + /* The Wayland server does not accept the current format or + vaExportSurfaceHandle() failed. Try again with a different format */ + GstVideoFormat format = choose_next_format (display, &format_index); + if ((format != GST_VIDEO_FORMAT_UNKNOWN) && window->has_vpp) { + GST_DEBUG ("Failed to export buffer. Try again with format %s", + gst_video_format_to_string (format)); + priv->need_vpp = TRUE; + gst_vaapi_window_set_vpp_format_internal (window, format, 0); + goto again; + } + if (window->has_vpp) + GST_WARNING ("Failed to export buffer and VPP not supported."); + else + GST_WARNING ("Failed to export buffer. No supported format found."); + priv->dmabuf_broken = TRUE; + break; + } + case GST_VAAPI_DMABUF_BAD_MODIFIER: + /* The format is supported by the Wayland server but not with the + current modifier. Try linear instead. */ + if (window->has_vpp) { + GST_DEBUG ("Modifier rejected by the server. Try linear instead."); + priv->need_vpp = TRUE; + gst_vaapi_window_set_vpp_format_internal (window, + gst_vaapi_surface_get_format (surface), + GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); + goto again; + } + GST_WARNING ("Modifier rejected by the server and VPP not supported."); + priv->dmabuf_broken = TRUE; + break; + case GST_VAAPI_DMABUF_NOT_SUPPORTED: + GST_DEBUG ("DMABuf protocol not supported"); + priv->dmabuf_broken = TRUE; + break; + case GST_VAAPI_DMABUF_FLUSH: + return FALSE; + } + } + + /* DMABuf is not available or does not work. Fall back to the old API. + There is no format negotiation so stick with NV12 */ + gst_vaapi_window_set_vpp_format_internal (window, GST_VIDEO_FORMAT_NV12, 0); + + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); + status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), + GST_VAAPI_SURFACE_ID (surface), + va_flags & (VA_TOP_FIELD | VA_BOTTOM_FIELD), buffer); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); + + if (window->has_vpp && !priv->need_vpp && + (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED || + status == VA_STATUS_ERROR_UNIMPLEMENTED || + status == VA_STATUS_ERROR_INVALID_IMAGE_FORMAT)) { + priv->need_vpp = TRUE; + goto again; + } + if (!vaapi_check_status (status, "vaGetSurfaceBufferWl()")) + return FALSE; + +out: + *surf = surface; + return TRUE; +} + static gboolean gst_vaapi_window_wayland_render (GstVaapiWindow * window, GstVaapiSurface * surface, @@ -540,19 +836,18 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); - GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window); struct wl_display *const wl_display = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); struct wl_buffer *buffer; FrameState *frame; - guint width, height, va_flags; - VAStatus status; + guint width, height; + gboolean ret; /* Check that we don't need to crop source VA surface */ gst_vaapi_surface_get_size (surface, &width, &height); if (src_rect->x != 0 || src_rect->y != 0) priv->need_vpp = TRUE; - if (src_rect->width != width || src_rect->height != height) + if (src_rect->width != width) priv->need_vpp = TRUE; /* Check that we don't render to a subregion of this window */ @@ -561,43 +856,15 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, if (dst_rect->width != window->width || dst_rect->height != window->height) priv->need_vpp = TRUE; - /* Try to construct a Wayland buffer from VA surface as is (without VPP) */ - if (!priv->need_vpp) { - GST_VAAPI_WINDOW_LOCK_DISPLAY (window); - va_flags = from_GstVaapiSurfaceRenderFlags (flags); - status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_SURFACE_ID (surface), - va_flags & (VA_TOP_FIELD | VA_BOTTOM_FIELD), &buffer); - GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); - if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED || - status == VA_STATUS_ERROR_UNIMPLEMENTED || - status == VA_STATUS_ERROR_INVALID_IMAGE_FORMAT) - priv->need_vpp = TRUE; - else if (!vaapi_check_status (status, "vaGetSurfaceBufferWl()")) - return FALSE; - } + ret = buffer_from_surface (window, &surface, src_rect, dst_rect, flags, + &buffer); + if (!ret) + return FALSE; - /* Try to construct a Wayland buffer with VPP */ + /* if need_vpp is set then the vpp happend */ if (priv->need_vpp) { - if (window->has_vpp) { - GstVaapiSurface *const vpp_surface = - gst_vaapi_window_vpp_convert_internal (window, surface, src_rect, - dst_rect, flags); - if (G_UNLIKELY (!vpp_surface)) - priv->need_vpp = FALSE; - else { - surface = vpp_surface; - width = window->width; - height = window->height; - } - } - - GST_VAAPI_WINDOW_LOCK_DISPLAY (window); - status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), - GST_VAAPI_SURFACE_ID (surface), VA_FRAME_PICTURE, &buffer); - GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); - if (!vaapi_check_status (status, "vaGetSurfaceBufferWl()")) - return FALSE; + width = window->width; + height = window->height; } /* Wait for the previous frame to complete redraw */ From f04dd7f33100ead30d98e5c76d42ee24290fa771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 7 Feb 2020 16:50:52 +0100 Subject: [PATCH 3673/3781] vaapidecode: reorder src caps template Since negotiation depends on caps order, first is VA, then DMABuf, later GLUploadTexture (deprecated) and finally raw. Also, for decoders, the possible available color formats for DMABuf is extended to all the possible VA color formats. Part-of: --- gst/vaapi/gstvaapidecode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 0f631e707c..c1be7ba40b 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -78,12 +78,12 @@ static const char gst_vaapidecode_sink_caps_str[] = ; static const char gst_vaapidecode_src_caps_str[] = - GST_VAAPI_MAKE_SURFACE_CAPS ";" + GST_VAAPI_MAKE_SURFACE_CAPS "; " + GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_VAAPI_FORMATS_ALL) " ;" #if (USE_GLX || USE_EGL) - GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";" + GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS "; " #endif - GST_VIDEO_CAPS_MAKE(GST_VAAPI_FORMATS_ALL) ";" - GST_VAAPI_MAKE_DMABUF_CAPS; + GST_VIDEO_CAPS_MAKE(GST_VAAPI_FORMATS_ALL); static GstStaticPadTemplate gst_vaapidecode_src_factory = GST_STATIC_PAD_TEMPLATE( From 634fefab5df3caf98586cb4314ecd2deb0a59eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 22 Jan 2020 17:41:28 +0100 Subject: [PATCH 3674/3781] vaapidecode: build allowed srcpad caps from va context Instead of generating allowed srcpad caps with generic information, now it takes the size an formats limits from the decoder's context. This is possible since srcpad caps are generated after the internal decoder is created. The patch replaces gst_vaapi_decoder_get_surface_formats() with gst_vaapi_decoder_get_suface_attributes(). From these attributes, formats are only used for VASurface memory caps feature. For system memory caps feature, the old gst_vaapi_plugin_get_allowed_srcpad_caps() is still used, since i965 jpeg decoder cannot deliver mappable format for gstreamer. And for the other caps features (dmabuf and texture upload) the same static list are used. This patch also adds DMABuf caps feature only if the context supports that memory type. Nonetheless, we keep the pre-defined formats since they are the subset of common derive formats formats supported either by amd/gallium and both intel drivers, since, when exporting the fd through vaAcquireBufferHandle()/ vaReleaseBufferHandle(), the formats of the derivable image cannot be retriebable from the driver. Later we'll use the attribute formats for the DMABuf feature too, when the code be ported to vaExportSurfaceHandle(). Finally, the allowed srcpad caps are removed if the internal decoder is destroyed, since context attribues will change. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder.c | 65 +++++++++++----- gst-libs/gst/vaapi/gstvaapidecoder.h | 8 +- gst/vaapi/gstvaapidecode.c | 107 +++++++++++++++++++++------ 3 files changed, 135 insertions(+), 45 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 0b60b87755..093fcc0573 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -1124,24 +1124,6 @@ gst_vaapi_decoder_decode_codec_data (GstVaapiDecoder * decoder) return status; } -/** - * gst_vaapi_decoder_get_surface_formats: - * @decoder: a #GstVaapiDecoder - * - * Retrieves an array of #GstVideoFormat which the output surfaces of - * the @decoder can handle. - * - * Return value: (transfer full): a #GArray of #GstVideoFormat or - * %NULL - */ -GArray * -gst_vaapi_decoder_get_surface_formats (GstVaapiDecoder * decoder) -{ - if (decoder && decoder->context) - return gst_vaapi_context_get_surface_formats (decoder->context); - return NULL; -} - /** * gst_vaapi_decoder_update_caps: * @decoder: a #GstVaapiDecoder @@ -1189,3 +1171,50 @@ gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps) return FALSE; } + +/** + * gst_vaapi_decoder_get_surface_attributres: + * @decoder: a #GstVaapiDecoder instances + * @min_width (out): the minimal surface width + * @min_height (out): the minimal surface height + * @max_width (out): the maximal surface width + * @max_height (out): the maximal surface height + * + * Fetches the valid surface's attributes for the current context. + * + * Returns: a #GArray of valid formats we get or %NULL if failed. + **/ +GArray * +gst_vaapi_decoder_get_surface_attributes (GstVaapiDecoder * decoder, + gint * min_width, gint * min_height, gint * max_width, gint * max_height, + guint * mem_types) +{ + gboolean ret; + GstVaapiConfigSurfaceAttributes attribs = { 0, }; + + g_return_val_if_fail (decoder != NULL, FALSE); + + if (!decoder->context) + return NULL; + + ret = gst_vaapi_context_get_surface_attributes (decoder->context, &attribs); + if (ret) + attribs.formats = gst_vaapi_context_get_surface_formats (decoder->context); + + if (attribs.formats->len == 0) { + g_array_unref (attribs.formats); + return NULL; + } + + if (min_width) + *min_width = attribs.min_width; + if (min_height) + *min_height = attribs.min_height; + if (max_width) + *max_width = attribs.max_width; + if (max_height) + *max_height = attribs.max_height; + if (mem_types) + *mem_types = attribs.mem_types; + return attribs.formats; +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h index b9bca4b2c0..2c55e2e1fb 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder.h @@ -103,9 +103,6 @@ gst_vaapi_decoder_set_codec_state_changed_func (GstVaapiDecoder * decoder, GstCaps * gst_vaapi_decoder_get_caps (GstVaapiDecoder * decoder); -GArray * -gst_vaapi_decoder_get_surface_formats (GstVaapiDecoder * decoder); - gboolean gst_vaapi_decoder_put_buffer (GstVaapiDecoder * decoder, GstBuffer * buf); @@ -139,6 +136,11 @@ 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 diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index c1be7ba40b..5e348ea967 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -197,10 +197,33 @@ gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps) return TRUE; } +static inline void +caps_set_width_and_height_range (GstCaps * caps, gint min_width, + gint min_height, gint max_width, gint max_height) +{ + guint size, i; + GstStructure *structure; + + /* Set the width/height info to caps */ + size = gst_caps_get_size (caps); + for (i = 0; i < size; i++) { + structure = gst_caps_get_structure (caps, i); + if (!structure) + continue; + gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, min_width, + max_width, "height", GST_TYPE_INT_RANGE, min_height, max_height, + "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + } +} + static gboolean gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) { - GstCaps *out_caps, *raw_caps; + GstCaps *out_caps, *raw_caps, *va_caps, *dma_caps, *gltexup_caps, *base_caps; + GArray *formats; + gint min_width, min_height, max_width, max_height; + guint mem_types; + gboolean ret = FALSE; if (decode->allowed_srcpad_caps) return TRUE; @@ -208,40 +231,74 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)) return FALSE; - /* Create VA caps */ - out_caps = gst_caps_from_string (GST_VAAPI_MAKE_SURFACE_CAPS); - if (!out_caps) { - GST_WARNING_OBJECT (decode, "failed to create VA/GL source caps"); + if (!decode->decoder) return FALSE; - } -#if (USE_GLX || USE_EGL) - if (!GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (decode) && - gst_vaapi_display_has_opengl (GST_VAAPI_PLUGIN_BASE_DISPLAY (decode))) { - out_caps = gst_caps_make_writable (out_caps); - gst_caps_append (out_caps, - gst_caps_from_string (GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS)); - } -#endif - out_caps = gst_caps_make_writable (out_caps); - gst_caps_append (out_caps, gst_caps_from_string (GST_VAAPI_MAKE_DMABUF_CAPS)); + + out_caps = base_caps = raw_caps = va_caps = dma_caps = gltexup_caps = NULL; + + formats = gst_vaapi_decoder_get_surface_attributes (decode->decoder, + &min_width, &min_height, &max_width, &max_height, &mem_types); + if (!formats) + return FALSE; + + base_caps = gst_vaapi_video_format_new_template_caps_from_list (formats); + if (!base_caps) + goto bail; + caps_set_width_and_height_range (base_caps, min_width, min_height, max_width, + max_height); raw_caps = gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps (GST_VAAPI_PLUGIN_BASE (decode), GST_VIDEO_INFO_FORMAT (&decode->decoded_info)); - if (!raw_caps) { - gst_caps_unref (out_caps); - GST_WARNING_OBJECT (decode, "failed to create raw sink caps"); - return FALSE; - } + if (!raw_caps) + goto bail; + raw_caps = gst_caps_copy (raw_caps); + caps_set_width_and_height_range (raw_caps, min_width, min_height, + max_width, max_height); + + va_caps = gst_caps_copy (base_caps); + gst_caps_set_features_simple (va_caps, + gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE)); + + if (GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (decode) + && gst_vaapi_mem_type_supports (mem_types, + GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF)) { + dma_caps = gst_caps_from_string (GST_VAAPI_MAKE_DMABUF_CAPS); + caps_set_width_and_height_range (dma_caps, min_width, min_height, max_width, + max_height); + } +#if (USE_GLX || USE_EGL) + if (!GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (decode) + && gst_vaapi_display_has_opengl (GST_VAAPI_PLUGIN_BASE_DISPLAY (decode))) { + gltexup_caps = gst_caps_from_string (GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS); + if (gltexup_caps) { + caps_set_width_and_height_range (base_caps, min_width, min_height, + max_width, max_height); + } + } +#endif + + out_caps = va_caps; + if (dma_caps) + gst_caps_append (out_caps, dma_caps); + if (gltexup_caps) + gst_caps_append (out_caps, gltexup_caps); + if (raw_caps) + gst_caps_append (out_caps, raw_caps); - out_caps = gst_caps_make_writable (out_caps); - gst_caps_append (out_caps, gst_caps_copy (raw_caps)); decode->allowed_srcpad_caps = out_caps; GST_INFO_OBJECT (decode, "allowed srcpad caps: %" GST_PTR_FORMAT, decode->allowed_srcpad_caps); - return TRUE; + ret = TRUE; + +bail: + if (formats) + g_array_unref (formats); + if (base_caps) + gst_caps_unref (base_caps); + return ret; } static GstCaps * @@ -963,6 +1020,8 @@ gst_vaapidecode_destroy (GstVaapiDecode * decode) gst_vaapidecode_purge (decode); gst_vaapi_decoder_replace (&decode->decoder, NULL); + /* srcpad caps are decoder's context dependant */ + gst_caps_replace (&decode->allowed_srcpad_caps, NULL); } static gboolean From 88f3b6b44dc7f19445f504782a2842f2153ffa6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 7 Feb 2020 17:10:45 +0100 Subject: [PATCH 3675/3781] vaapidecode: use allowed srcpad caps for caps query Instead of using just the template caps use the current allowed srcpad caps, which is created considering the current decoder context. Part-of: --- gst/vaapi/gstvaapidecode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 5e348ea967..017c878e8a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1433,10 +1433,9 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CAPS:{ GstCaps *caps, *filter = NULL; - GstPad *pad = GST_VIDEO_DECODER_SRC_PAD (vdec); gst_query_parse_caps (query, &filter); - caps = gst_pad_get_pad_template_caps (pad); + caps = gst_vaapidecode_get_allowed_srcpad_caps (GST_VAAPIDECODE (vdec)); if (filter) { GstCaps *tmp = caps; From 7c2f5f1dd865381f45f97bd1c1c71fcc5ec1bdd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 18 May 2020 17:32:27 +0200 Subject: [PATCH 3676/3781] vaapidecode: dma caps only use reported color format This fix pipelines without vaapipostproc after vaapi decoder, such as gst-launch-1.0 filesrc location=~/file.mp4 ! parsebin ! vaapih264dec ! glimagesink On EGL platforms, so DMABuf is used. Part-of: --- gst/vaapi/gstvaapidecode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 017c878e8a..4d9add3e1d 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -263,9 +263,9 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) if (GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (decode) && gst_vaapi_mem_type_supports (mem_types, GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF)) { - dma_caps = gst_caps_from_string (GST_VAAPI_MAKE_DMABUF_CAPS); - caps_set_width_and_height_range (dma_caps, min_width, min_height, max_width, - max_height); + dma_caps = gst_caps_copy (base_caps); + gst_caps_set_features_simple (va_caps, + gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF)); } #if (USE_GLX || USE_EGL) if (!GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (decode) From 525abc6d1e3e655f74a9dc1c295053a480ad71cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 28 Jul 2020 12:22:40 +0200 Subject: [PATCH 3677/3781] build: request libdrm >= 2.4.98 and fallback Fixes: #270 Part-of: --- meson.build | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index e1194e6770..34dd4aed80 100644 --- a/meson.build +++ b/meson.build @@ -18,6 +18,7 @@ endif libva_req = ['>= 0.39.0', '!= 0.99.0'] glib_req = '>= 2.44.0' libwayland_req = '>= 1.11.0' +libdrm_req = '>= 2.4.98' gst_req = '>= @0@.@1@.0'.format(gst_version_major, gst_version_minor) cc = meson.get_compiler('c') @@ -76,7 +77,8 @@ libva_dep = dependency('libva', version: libva_req) libva_drm_dep = dependency('libva-drm', version: libva_req, required: false) libva_wayland_dep = dependency('libva-wayland', version: libva_req, required: false) libva_x11_dep = dependency('libva-x11', version: libva_req, required: false) -libdrm_dep = dependency('libdrm', required: false) +libdrm_dep = dependency('libdrm', version: libdrm_req, required: false, + fallback: ['libdrm', 'ext_libdrm']) libudev_dep = dependency('libudev', required: false) egl_dep = dependency('egl', required: false) gl_dep = dependency('gl', required: false) From ecd1ca81a7098bcb16a71e9c2f574ac29b8e9166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 28 Jul 2020 20:00:09 +0200 Subject: [PATCH 3678/3781] vaapidecode: always merge profile caps in sink caps This commit fixes a regression of e962069d, where if the profile's caps doesn't have a caps profile, it's ignored. This patch add a conditional jump if the caps doesn't have a profile field to merge it. Fixes: #271 Part-of: --- gst/vaapi/gstvaapidecode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4d9add3e1d..59ec6e958c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1289,7 +1289,7 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) profile_name = gst_vaapi_profile_get_name (profile); if (!profile_name) - continue; + goto merge_caps; /* Add all according -intra profile for HEVC */ if (profile == GST_VAAPI_PROFILE_H265_MAIN @@ -1346,8 +1346,8 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) profile_name, NULL); } + merge_caps: gst_vaapi_profile_caps_append_decoder (display, profile, structure); - allowed_sinkpad_caps = gst_caps_merge (allowed_sinkpad_caps, caps); } From 83d48837d25aa7876e559bf39e3314d21691f0c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Jul 2020 12:02:50 +0200 Subject: [PATCH 3679/3781] libs: context: change function to internal code style Instead of a getter the function `get_preferred_format()` to `ensure_preferred_format()` which aligns to the code style. Part-of: --- gst-libs/gst/vaapi/gstvaapicontext.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 8a361f3f96..5283a13b30 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -73,20 +73,22 @@ ensure_attributes (GstVaapiContext * context) return (context->attribs != NULL); } -/* looks for the (very arbritrary) preferred format from the requested - * context chroma type, in the context attributes */ -static GstVideoFormat -get_preferred_format (GstVaapiContext * context) +/* 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 context->preferred_format; + return; if (!ensure_attributes (context) || !context->attribs->formats) - return GST_VIDEO_FORMAT_UNKNOWN; + return; formats = context->attribs->formats; for (i = 0; i < formats->len; i++) { @@ -97,7 +99,7 @@ get_preferred_format (GstVaapiContext * context) } } - return context->preferred_format; + return; } static inline gboolean @@ -167,7 +169,8 @@ context_ensure_surfaces (GstVaapiContext * context) GstVideoFormat format; guint i, capacity; - format = get_preferred_format (context); + 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, From 6022d97edfd71e3a7cb391464f0275fde88a63ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Jul 2020 10:17:31 +0200 Subject: [PATCH 3680/3781] libs: display, context: handle broken jpeg decoder for i965 driver JPEG decoding in i965 driver is pretty much broken, and the driver is deprecated which mean authors only accept trivial fixes. Surfaces for JPEG decoder context in i965 only handle IMC3[1] color format which is not a common format in GStreamer. It can export it to I420 at mapping raw bytes, but DMABuf exporting is problematic. This patch artificially adds NV12 to the context format list when it's JPEG decoder for i965 and force the usage of old VA-API for surface creation without specifying color format. Also it artificially disables the DMABuf announcement. 1. https://docs.microsoft.com/en-us/windows/win32/medfound/recommended-8-bit-yuv-formats-for-video-rendering#420-formats-16-bits-per-pixel Part-of: --- gst-libs/gst/vaapi/gstvaapicontext.c | 26 +++++++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay.h | 3 +++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 5283a13b30..52fd751b51 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -61,6 +61,17 @@ _init_vaapi_context_debug (void) #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) { @@ -70,7 +81,17 @@ ensure_attributes (GstVaapiContext * context) context->attribs = gst_vaapi_config_surface_attributes_get (GST_VAAPI_CONTEXT_DISPLAY (context), context->va_config); - return (context->attribs != NULL); + + 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 @@ -87,6 +108,9 @@ ensure_preferred_format (GstVaapiContext * context) 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; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 840e6c56ac..3a6841d042 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -808,6 +808,7 @@ set_driver_quirks (GstVaapiDisplay * display) { "i965", GST_VAAPI_DRIVER_QUIRK_MISSING_RGBA_IMAGE_FORMAT }, { "iHD", GST_VAAPI_DRIVER_QUIRK_JPEG_ENC_SHIFT_VALUE_BY_50 }, { "iHD", GST_VAAPI_DRIVER_QUIRK_HEVC_ENC_SLICE_NOT_SPAN_TILE }, + { "i965", GST_VAAPI_DRIVER_QUIRK_JPEG_DEC_BROKEN_FORMATS }, }; /* *INDENT-ON* */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 9e690cb389..3eca38aaa5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -109,6 +109,8 @@ typedef struct _GstVaapiDisplay GstVaapiDisplay; * 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 { @@ -118,6 +120,7 @@ typedef enum 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; /** From ed55dd8df1dd0dbed1f20e0c5dd96f68e0bf2ddf Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 6 Jul 2020 23:35:12 +0800 Subject: [PATCH 3681/3781] libs: utils: vpx: Add utils vpx to handle VP8/9 misc things. Part-of: --- gst-libs/gst/vaapi/gstvaapiutils_vpx.c | 88 ++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_vpx.h | 40 ++++++++++++ gst-libs/gst/vaapi/meson.build | 2 + 3 files changed, 130 insertions(+) create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_vpx.c create mode 100644 gst-libs/gst/vaapi/gstvaapiutils_vpx.h diff --git a/gst-libs/gst/vaapi/gstvaapiutils_vpx.c b/gst-libs/gst/vaapi/gstvaapiutils_vpx.c new file mode 100644 index 0000000000..2882c2f0e7 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_vpx.c @@ -0,0 +1,88 @@ +/* + * gstvaapiutils_vpx.c - vpx related utilities + * + * Copyright (C) 2020 Intel Corporation + * Author: He Junyan + * + * 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 "gstvaapiutils_vpx.h" + +struct map +{ + guint value; + const gchar *name; +}; + +/* Profile string map */ +static const struct map gst_vaapi_vp9_profile_map[] = { + /* *INDENT-OFF* */ + { GST_VAAPI_PROFILE_VP9_0, "0" }, + { GST_VAAPI_PROFILE_VP9_1, "1" }, + { GST_VAAPI_PROFILE_VP9_2, "2" }, + { GST_VAAPI_PROFILE_VP9_3, "3" }, + { 0, NULL } + /* *INDENT-ON* */ +}; + +/* Lookup name in map */ +static const struct map * +map_lookup_name (const struct map *m, const gchar * name) +{ + g_return_val_if_fail (m != NULL, NULL); + + if (!name) + return NULL; + + for (; m->name != NULL; m++) { + if (strcmp (m->name, name) == 0) + return m; + } + return NULL; +} + +/* Lookup value in map */ +static const struct map * +map_lookup_value (const struct map *m, guint value) +{ + g_return_val_if_fail (m != NULL, NULL); + + for (; m->name != NULL; m++) { + if (m->value == value) + return m; + } + return NULL; +} + +/** Returns GstVaapiProfile from a string representation */ +GstVaapiProfile +gst_vaapi_utils_vp9_get_profile_from_string (const gchar * str) +{ + const struct map *const m = map_lookup_name (gst_vaapi_vp9_profile_map, str); + + return m ? (GstVaapiProfile) m->value : GST_VAAPI_PROFILE_UNKNOWN; +} + +/** Returns a string representation for the supplied VP9 profile */ +const gchar * +gst_vaapi_utils_vp9_get_profile_string (GstVaapiProfile profile) +{ + const struct map *const m = + map_lookup_value (gst_vaapi_vp9_profile_map, profile); + + return m ? m->name : NULL; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_vpx.h b/gst-libs/gst/vaapi/gstvaapiutils_vpx.h new file mode 100644 index 0000000000..a83510ce7e --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiutils_vpx.h @@ -0,0 +1,40 @@ +/* + * gstvaapiutils_vpx.h - vpx related utilities + * + * Copyright (C) 2020 Intel Corporation + * Author: He Junyan + * + * 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_UTILS_VPX_H +#define GST_VAAPI_UTILS_VPX_H + +#include + +G_BEGIN_DECLS + +/** Returns GstVaapiProfile from a string representation */ +GstVaapiProfile +gst_vaapi_utils_vp9_get_profile_from_string (const gchar * str); + +/** Returns a string representation for the supplied VP9 profile */ +const gchar * +gst_vaapi_utils_vp9_get_profile_string (GstVaapiProfile profile); + +G_END_DECLS + +#endif /* GST_VAAPI_UTILS_VPX_H */ diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index bcf261fd11..527414f1ad 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -36,6 +36,7 @@ gstlibvaapi_sources = [ 'gstvaapiutils_h265.c', 'gstvaapiutils_h26x.c', 'gstvaapiutils_mpeg2.c', + 'gstvaapiutils_vpx.c', 'gstvaapivalue.c', 'gstvaapivideopool.c', 'gstvaapiwindow.c', @@ -71,6 +72,7 @@ gstlibvaapi_headers = [ 'gstvaapiutils_h264.h', 'gstvaapiutils_h265.h', 'gstvaapiutils_mpeg2.h', + 'gstvaapiutils_vpx.h', 'gstvaapivalue.h', 'gstvaapivideopool.h', 'gstvaapiwindow.h', From b86489eb8c13dece2bd389838e2eeea250fa2ff5 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 8 Jul 2020 16:30:17 +0800 Subject: [PATCH 3682/3781] plugin: util: rename h26x_encoder_get_profiles_from_caps(). Change its name to encoder_get_profiles_from_caps(). Other codecs such as VP9 also needs to use this function. Part-of: --- gst/vaapi/gstvaapiencode_h264.c | 2 +- gst/vaapi/gstvaapiencode_h265.c | 2 +- gst/vaapi/gstvaapipluginutil.c | 7 +++---- gst/vaapi/gstvaapipluginutil.h | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index f69c033477..ccadbf23ae 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -103,7 +103,7 @@ static GArray * gst_vaapiencode_h264_get_allowed_profiles (GstVaapiEncode * encode, GstCaps * allowed) { - return gst_vaapi_h26x_encoder_get_profiles_from_caps (allowed, + return gst_vaapi_encoder_get_profiles_from_caps (allowed, gst_vaapi_utils_h264_get_profile_from_string); } diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index e693c908a2..c94d746068 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -74,7 +74,7 @@ static GArray * gst_vaapiencode_h265_get_allowed_profiles (GstVaapiEncode * encode, GstCaps * allowed) { - return gst_vaapi_h26x_encoder_get_profiles_from_caps (allowed, + return gst_vaapi_encoder_get_profiles_from_caps (allowed, gst_vaapi_utils_h265_get_profile_from_string); } diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index 86de800d36..aa48531499 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1018,18 +1018,17 @@ gst_vaapi_codecs_has_codec (GArray * codecs, GstVaapiCodec codec) } /** - * gst_vaapi_h26x_encoder_get_profiles_from_caps: + * gst_vaapi_encoder_get_profiles_from_caps: * @caps: a #GstCaps to detect * @func: a #GstVaapiStrToProfileFunc * * This function will detect all profile strings in @caps and - * return the according GstVaapiProfile in array. This can just - * work for h264 and h265 now. + * return the according GstVaapiProfile in array. * * Return: A #GArray of @GstVaapiProfile if succeed, %NULL if fail. **/ GArray * -gst_vaapi_h26x_encoder_get_profiles_from_caps (GstCaps * caps, +gst_vaapi_encoder_get_profiles_from_caps (GstCaps * caps, GstVaapiStrToProfileFunc func) { guint i, j; diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index db069cb9c5..5ae79b8927 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -158,7 +158,7 @@ gst_vaapi_codecs_has_codec (GArray * codecs, GstVaapiCodec codec); G_GNUC_INTERNAL GArray * -gst_vaapi_h26x_encoder_get_profiles_from_caps (GstCaps * caps, +gst_vaapi_encoder_get_profiles_from_caps (GstCaps * caps, GstVaapiStrToProfileFunc func); G_GNUC_INTERNAL From 35c3de234cec95db9ef620aa72e2587a764ba451 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 7 Jul 2020 00:46:23 +0800 Subject: [PATCH 3683/3781] plugins: encode: vp9: Implement vp9's allowed_profiles() func. Part-of: --- gst/vaapi/gstvaapiencode_vp9.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index 053bf53d98..4538462003 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -36,6 +36,7 @@ #include "gstcompat.h" #include #include +#include #include "gstvaapiencode_vp9.h" #include "gstvaapipluginutil.h" #include "gstvaapivideomemory.h" @@ -52,7 +53,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_vp9_encode_debug); #define EXTRA_FORMATS {} /* vp9 encode */ -GST_VAAPI_ENCODE_REGISTER_TYPE (vp9, VP9, VP9, EXTRA_FORMATS, NULL); +GST_VAAPI_ENCODE_REGISTER_TYPE (vp9, VP9, VP9, EXTRA_FORMATS, + gst_vaapi_utils_vp9_get_profile_string); static void gst_vaapiencode_vp9_init (GstVaapiEncodeVP9 * encode) @@ -66,6 +68,14 @@ gst_vaapiencode_vp9_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapiencode_vp9_parent_class)->finalize (object); } +static GArray * +gst_vaapiencode_vp9_get_allowed_profiles (GstVaapiEncode * encode, + GstCaps * allowed) +{ + return gst_vaapi_encoder_get_profiles_from_caps (allowed, + gst_vaapi_utils_vp9_get_profile_from_string); +} + static GstCaps * gst_vaapiencode_vp9_get_caps (GstVaapiEncode * base_encode) { @@ -99,6 +109,7 @@ gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass, gpointer data) object_class->set_property = gst_vaapiencode_set_property_subclass; object_class->get_property = gst_vaapiencode_get_property_subclass; + encode_class->get_allowed_profiles = gst_vaapiencode_vp9_get_allowed_profiles; encode_class->get_caps = gst_vaapiencode_vp9_get_caps; encode_class->alloc_encoder = gst_vaapiencode_vp9_alloc_encoder; From 7acc3c4db87bab6677f96df4d73eb7abce17264b Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sun, 12 Jul 2020 19:42:40 +0800 Subject: [PATCH 3684/3781] libs: profile: h265: Fix return value of from_codec_data_h265. profile_from_codec_data_h265() returns wrong GstVaapiProfile for h265. The codec data of caps contain the profile IDC, but the mapping between profile IDC and GstVaapiProfile is wrong. Part-of: --- gst-libs/gst/vaapi/gstvaapiprofile.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index e1980e0148..05480dffc1 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -341,6 +341,9 @@ gst_vaapi_profile_from_codec_data_h265 (GstBuffer * buffer) if (buf[1] & 0xc0) /* general_profile_space = 0 */ return 0; + /* We may not recognize the exactly correct profile, which needs more + info such as depth, chroma and constraint_flag. We just return the + first one that belongs to that profile IDC. */ switch (buf[1] & 0x1f) { /* HEVCProfileIndication */ case 1: return GST_VAAPI_PROFILE_H265_MAIN; @@ -350,10 +353,8 @@ gst_vaapi_profile_from_codec_data_h265 (GstBuffer * buffer) return GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; case 4: return GST_VAAPI_PROFILE_H265_MAIN_422_10; - case 5: - return GST_VAAPI_PROFILE_H265_MAIN_444; - case 6: - return GST_VAAPI_PROFILE_H265_MAIN_444_10; + case 9: + return GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN; } return 0; } From cf3b0120cb349e954230266c095fa71c12353488 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 29 Jul 2020 14:22:18 +0800 Subject: [PATCH 3685/3781] libs: profile: Use get_codec_from_caps to get codec type. There is no need to get a profile from the caps and then convert that profile into codec type. We can get the codec type by caps's name easily. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder.c | 13 ++------- gst-libs/gst/vaapi/gstvaapiprofile.c | 42 ++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiprofile.h | 3 ++ gst/vaapi/gstvaapidecode.c | 8 +----- gst/vaapi/gstvaapiencode.c | 5 ++-- 5 files changed, 50 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 093fcc0573..192d71aab2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -420,14 +420,9 @@ set_caps (GstVaapiDecoder * decoder, const GstCaps * caps) { GstVideoCodecState *const codec_state = decoder->codec_state; GstStructure *const structure = gst_caps_get_structure (caps, 0); - GstVaapiProfile profile; const GValue *v_codec_data; - profile = gst_vaapi_profile_from_caps (caps); - if (!profile) - return FALSE; - - decoder->codec = gst_vaapi_profile_get_codec (profile); + decoder->codec = gst_vaapi_get_codec_from_caps (caps); if (!decoder->codec) return FALSE; @@ -1142,7 +1137,6 @@ gboolean gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps) { GstCaps *decoder_caps; - GstVaapiProfile profile; GstVaapiCodec codec; g_return_val_if_fail (decoder != NULL, FALSE); @@ -1155,10 +1149,7 @@ gst_vaapi_decoder_update_caps (GstVaapiDecoder * decoder, GstCaps * caps) if (gst_caps_is_always_compatible (caps, decoder_caps)) return set_caps (decoder, caps); - profile = gst_vaapi_profile_from_caps (caps); - if (profile == GST_VAAPI_PROFILE_UNKNOWN) - return FALSE; - codec = gst_vaapi_profile_get_codec (profile); + codec = gst_vaapi_get_codec_from_caps (caps); if (codec == 0) return FALSE; if (codec == decoder->codec) { diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 05480dffc1..cbf2db5703 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -457,6 +457,48 @@ gst_vaapi_profile_from_caps (const GstCaps * caps) return profile ? profile : best_profile; } +/** + * gst_vaapi_get_codec_from_caps: + * @caps: a #GstCaps + * + * Converts @caps into the corresponding #GstVaapiCodec. If we can + * not recognize the #GstVaapiCodec, then zero is returned. + * + * Return value: the #GstVaapiCodec describing the @caps + */ +GstVaapiCodec +gst_vaapi_get_codec_from_caps (const GstCaps * caps) +{ + GstStructure *structure; + const gchar *name; + gsize namelen; + const GstVaapiProfileMap *m; + GstVaapiProfile profile; + + if (!caps) + return 0; + + structure = gst_caps_get_structure (caps, 0); + if (!structure) + return 0; + + name = gst_structure_get_name (structure); + namelen = strlen (name); + + profile = GST_VAAPI_PROFILE_UNKNOWN; + for (m = gst_vaapi_profiles; m->profile; m++) { + if (strncmp (name, m->media_str, namelen) == 0) { + profile = m->profile; + break; + } + } + + if (profile == GST_VAAPI_PROFILE_UNKNOWN) + return 0; + + return gst_vaapi_profile_get_codec (profile); +} + /** * gst_vaapi_profile_get_va_profile: * @profile: a #GstVaapiProfile diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index c3080f4ee3..3ba23f69c4 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -228,6 +228,9 @@ gst_vaapi_profile(VAProfile profile); GstVaapiProfile gst_vaapi_profile_from_caps(const GstCaps *caps); +GstVaapiCodec +gst_vaapi_get_codec_from_caps (const GstCaps *caps); + const gchar * gst_vaapi_profile_get_name(GstVaapiProfile profile); diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 59ec6e958c..afe2dd2730 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -881,12 +881,6 @@ gst_vaapidecode_ensure_display (GstVaapiDecode * decode) return gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (decode)); } -static inline guint -gst_vaapi_codec_from_caps (GstCaps * caps) -{ - return gst_vaapi_profile_get_codec (gst_vaapi_profile_from_caps (caps)); -} - static gboolean gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) { @@ -896,7 +890,7 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) return FALSE; dpy = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode); - switch (gst_vaapi_codec_from_caps (caps)) { + switch (gst_vaapi_get_codec_from_caps (caps)) { case GST_VAAPI_CODEC_MPEG2: decode->decoder = gst_vaapi_decoder_mpeg2_new (dpy, caps); break; diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index eacf13c3d9..a970f827b1 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -611,9 +611,8 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_ENCODER, encoder, NULL); - if ((codec = - gst_vaapi_codec_get_name (gst_vaapi_profile_get_codec - (gst_vaapi_profile_from_caps (state->caps))))) + if ((codec = gst_vaapi_codec_get_name + (gst_vaapi_get_codec_from_caps (state->caps)))) gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_CODEC, codec, NULL); From 80b1e53cccfe91e96c17d2015918b565b4315eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Jul 2020 13:39:44 +0200 Subject: [PATCH 3686/3781] vaapipluginutil: simplify gst_vaapi_find_preferred_caps_feature() Generalize the way how the preferred color format is chosen. Also use new GStreamre API as syntatic sugar. Part-of: --- gst/vaapi/gstvaapipluginutil.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index aa48531499..f5eb6d56be 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -683,7 +683,7 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstCaps * allowed_caps, caps = gst_caps_new_full (gst_structure_copy (structure), NULL); if (!caps) continue; - gst_caps_set_features (caps, 0, gst_caps_features_copy (features)); + gst_caps_set_features_simple (caps, gst_caps_features_copy (features)); for (j = 0; j < G_N_ELEMENTS (feature_list); j++) { if (gst_vaapi_caps_feature_contains (caps, feature_list[j]) @@ -699,33 +699,23 @@ gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstCaps * allowed_caps, break; } - if (!caps) - goto cleanup; - find_format: + if (!caps) + caps = gst_caps_ref (out_caps); + if (out_format_ptr) { GstVideoFormat out_format; GstStructure *structure = NULL; const GValue *format_list; - GstCapsFeatures *features; - /* if the best feature is SystemMemory, we should choose the - * vidoe/x-raw caps in the filtered peer caps set. If not, use - * the first caps, which is the preferred by downstream. */ - if (feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) { - gst_caps_replace (&caps, out_caps); - num_structures = gst_caps_get_size (caps); - for (i = 0; i < num_structures; i++) { + num_structures = gst_caps_get_size (caps); + for (i = 0; i < num_structures; i++) { + GstCapsFeatures *const features = gst_caps_get_features (caps, i); + if (gst_caps_features_contains (features, + gst_vaapi_caps_feature_to_string (feature))) { structure = gst_caps_get_structure (caps, i); - features = gst_caps_get_features (caps, i); - if (!gst_caps_features_is_any (features) - && gst_caps_features_contains (features, - gst_vaapi_caps_feature_to_string - (GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY))) - break; + break; } - } else { - structure = gst_caps_get_structure (caps, 0); } if (!structure) goto cleanup; From daecc5bfa1e7141e504cd021fd7a63a518be7aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 8 Apr 2020 19:41:09 +0200 Subject: [PATCH 3687/3781] vaapipostproc: early return if fixate srcpad caps fails Part-of: --- gst/vaapi/gstvaapipostproc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 62e0ddac5a..5f7d9cd8bc 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1486,13 +1486,16 @@ gst_vaapipostproc_fixate_caps (GstBaseTransform * trans, outcaps = gst_vaapipostproc_fixate_srccaps (postproc, caps, othercaps); g_mutex_unlock (&postproc->postproc_lock); + if (!outcaps) + goto done; /* set passthrough according to caps changes or filter changes */ same_caps = gst_caps_is_equal (caps, outcaps); gst_base_transform_set_passthrough (trans, same_caps && !filter_updated); done: - GST_DEBUG_OBJECT (trans, "fixated othercaps to %" GST_PTR_FORMAT, outcaps); + if (outcaps) + GST_DEBUG_OBJECT (trans, "fixated othercaps to %" GST_PTR_FORMAT, outcaps); gst_caps_unref (othercaps); return outcaps; From 579aa4cab1910d87c548b195dead6583b3704529 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 2 Jul 2020 23:33:31 +0800 Subject: [PATCH 3688/3781] libs: encoder: h265: No need to check hw_max_profile. In h265, higher profile idc number does not mean better compression performance and may be not compatible with the lower profile idc. So, it is not suitable to find the heighest idc for hw to ensure the compatibility. On the other side, when the entrypoint of the selected profile is valid, it means the hw really support this profile, no need to check it again. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 38 ----------------------- 1 file changed, 38 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 0e0a766d05..17e7a4d138 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -98,7 +98,6 @@ struct _GstVaapiEncoderH265 GstVaapiEntrypoint entrypoint; guint8 profile_idc; guint8 max_profile_idc; - guint8 hw_max_profile_idc; guint8 level_idc; guint32 idr_period; guint32 init_qp; @@ -1058,37 +1057,6 @@ _check_vps_sps_pps_status (GstVaapiEncoderH265 * encoder, } } -/* Determines the largest supported profile by the underlying hardware */ -static gboolean -ensure_hw_profile_limits (GstVaapiEncoderH265 * encoder) -{ - GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); - GArray *profiles; - guint i, profile_idc, max_profile_idc; - - if (encoder->hw_max_profile_idc) - return TRUE; - - profiles = gst_vaapi_display_get_encode_profiles (display); - if (!profiles) - return FALSE; - - max_profile_idc = 0; - for (i = 0; i < profiles->len; i++) { - const GstVaapiProfile profile = - g_array_index (profiles, GstVaapiProfile, i); - profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile); - if (!profile_idc) - continue; - if (max_profile_idc < profile_idc) - max_profile_idc = profile_idc; - } - g_array_unref (profiles); - - encoder->hw_max_profile_idc = max_profile_idc; - return TRUE; -} - /* Derives the profile supported by the underlying hardware */ static gboolean ensure_hw_profile (GstVaapiEncoderH265 * encoder) @@ -2300,12 +2268,6 @@ ensure_profile_tier_level (GstVaapiEncoderH265 * encoder) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } - /* Check HW constraints */ - if (!ensure_hw_profile_limits (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - if (encoder->profile_idc > encoder->hw_max_profile_idc) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - /* Ensure bitrate if not set already and derive the right level to use */ ensure_bitrate (encoder); From 3554f06235aaee322eaf7f8187ed6c67123e745d Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 3 Jul 2020 00:53:31 +0800 Subject: [PATCH 3689/3781] libs: encoder: h265: modify set_max_profile to set_allowed_profiles. In h265, bigger profile idc may not be compatible with the small profile idc. And more important, there are multi profiles with the same profile idc. Such as main-422-10, main-444 and main-444-10, they all have profile idc 4. So recording the max profile idc is not enough, the encoder needs to know all allowed profiles when deciding the real profile. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 45 +++++++++++------------ gst-libs/gst/vaapi/gstvaapiencoder_h265.h | 4 +- gst/vaapi/gstvaapiencode_h265.c | 2 +- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 17e7a4d138..4cc274cd4d 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -97,7 +97,7 @@ struct _GstVaapiEncoderH265 GstVaapiLevelH265 level; GstVaapiEntrypoint entrypoint; guint8 profile_idc; - guint8 max_profile_idc; + GArray *allowed_profiles; guint8 level_idc; guint32 idr_period; guint32 init_qp; @@ -1104,11 +1104,17 @@ error_unsupported_profile: static gboolean ensure_profile_limits (GstVaapiEncoderH265 * encoder) { + gint i; - if (!encoder->max_profile_idc - || encoder->profile_idc <= encoder->max_profile_idc) + if (!encoder->allowed_profiles) return TRUE; + for (i = 0; i < encoder->allowed_profiles->len; i++) { + if (encoder->profile == + g_array_index (encoder->allowed_profiles, GstVaapiProfile, i)) + return TRUE; + } + GST_WARNING ("Needs to lower coding tools to meet target decoder constraints"); GST_WARNING ("Only supporting Main profile, reset profile to Main"); @@ -3195,6 +3201,8 @@ gst_vaapi_encoder_h265_init (GstVaapiEncoderH265 * encoder) ref_pool->max_ref_frames = 0; ref_pool->max_reflist0_count = 1; ref_pool->max_reflist1_count = 1; + + encoder->allowed_profiles = NULL; } struct _GstVaapiEncoderH265Class @@ -3238,6 +3246,9 @@ gst_vaapi_encoder_h265_finalize (GObject * object) reset_tile (encoder); + if (encoder->allowed_profiles) + g_array_unref (encoder->allowed_profiles); + G_OBJECT_CLASS (gst_vaapi_encoder_h265_parent_class)->finalize (object); } @@ -3678,36 +3689,22 @@ gst_vaapi_encoder_h265_new (GstVaapiDisplay * display) } /** - * gst_vaapi_encoder_h265_set_max_profile: + * gst_vaapi_encoder_h265_set_allowed_profiles: * @encoder: a #GstVaapiEncoderH265 - * @profile: an H.265 #GstVaapiProfile + * @profiles: a #GArray of all allowed #GstVaapiProfile. * - * Notifies the @encoder to use coding tools from the supplied - * @profile at most. - * - * This means that if the minimal profile derived to - * support the specified coding tools is greater than this @profile, - * then an error is returned when the @encoder is configured. + * Set the all allowed profiles for the encoder. * * Return value: %TRUE on success */ gboolean -gst_vaapi_encoder_h265_set_max_profile (GstVaapiEncoderH265 * encoder, - GstVaapiProfile profile) +gst_vaapi_encoder_h265_set_allowed_profiles (GstVaapiEncoderH265 * encoder, + GArray * profiles) { - guint8 profile_idc; - g_return_val_if_fail (encoder != NULL, FALSE); - g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE); + g_return_val_if_fail (profiles, FALSE); - if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H265) - return FALSE; - - profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile); - if (!profile_idc) - return FALSE; - - encoder->max_profile_idc = profile_idc; + encoder->allowed_profiles = g_array_ref (profiles); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h index 0944905833..60da074a1c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.h @@ -45,8 +45,8 @@ GstVaapiEncoder * gst_vaapi_encoder_h265_new (GstVaapiDisplay * display); gboolean -gst_vaapi_encoder_h265_set_max_profile (GstVaapiEncoderH265 * encoder, - GstVaapiProfile profile); +gst_vaapi_encoder_h265_set_allowed_profiles (GstVaapiEncoderH265 * encoder, + GArray * profiles); gboolean gst_vaapi_encoder_h265_get_profile_tier_level (GstVaapiEncoderH265 * encoder, diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index c94d746068..9ee8855e3b 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -153,7 +153,7 @@ gst_vaapiencode_h265_set_config (GstVaapiEncode * base_encode) if (profile) { GST_INFO ("using %s profile as target decoder constraints", gst_vaapi_utils_h265_get_profile_string (profile)); - if (!gst_vaapi_encoder_h265_set_max_profile (encoder, profile)) + if (!gst_vaapi_encoder_h265_set_allowed_profiles (encoder, NULL)) return FALSE; } return TRUE; From 38db4bc15e06c34ff99638a87ec5e80086ee6d3d Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 3 Jul 2020 01:28:28 +0800 Subject: [PATCH 3690/3781] plugins: encode: h265: collect all allowed profiles to encoder. We should collect all allowed profiles and pass them to the inside encoder, rather than just calculate the max profile idc. Part-of: --- gst/vaapi/gstvaapiencode_h265.c | 74 ++++----------------------------- 1 file changed, 9 insertions(+), 65 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index 9ee8855e3b..baedcea1d8 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -78,85 +78,29 @@ gst_vaapiencode_h265_get_allowed_profiles (GstVaapiEncode * encode, gst_vaapi_utils_h265_get_profile_from_string); } -typedef struct -{ - GstVaapiProfile best_profile; - guint best_score; -} FindBestProfileData; - -static void -find_best_profile_value (FindBestProfileData * data, const GValue * value) -{ - const gchar *str; - GstVaapiProfile profile; - guint score; - - if (!value || !G_VALUE_HOLDS_STRING (value)) - return; - - str = g_value_get_string (value); - if (!str) - return; - profile = gst_vaapi_utils_h265_get_profile_from_string (str); - if (!profile) - return; - score = gst_vaapi_utils_h265_get_profile_score (profile); - if (score < data->best_score) - return; - data->best_profile = profile; - data->best_score = score; -} - -static GstVaapiProfile -find_best_profile (GstCaps * caps) -{ - FindBestProfileData data; - guint i, j, num_structures, num_values; - - data.best_profile = GST_VAAPI_PROFILE_UNKNOWN; - data.best_score = 0; - - num_structures = gst_caps_get_size (caps); - for (i = 0; i < num_structures; i++) { - GstStructure *const structure = gst_caps_get_structure (caps, i); - const GValue *const value = gst_structure_get_value (structure, "profile"); - - if (!value) - continue; - if (G_VALUE_HOLDS_STRING (value)) - find_best_profile_value (&data, value); - else if (GST_VALUE_HOLDS_LIST (value)) { - num_values = gst_value_list_get_size (value); - for (j = 0; j < num_values; j++) - find_best_profile_value (&data, gst_value_list_get_value (value, j)); - } - } - return data.best_profile; -} - static gboolean gst_vaapiencode_h265_set_config (GstVaapiEncode * base_encode) { GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encode->encoder); GstCaps *allowed_caps; - GstVaapiProfile profile; + GArray *profiles; + gboolean ret = TRUE; - /* Check for the largest profile that is supported */ allowed_caps = gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (base_encode)); if (!allowed_caps) return TRUE; - profile = find_best_profile (allowed_caps); + profiles = gst_vaapi_encoder_get_profiles_from_caps (allowed_caps, + gst_vaapi_utils_h265_get_profile_from_string); gst_caps_unref (allowed_caps); - if (profile) { - GST_INFO ("using %s profile as target decoder constraints", - gst_vaapi_utils_h265_get_profile_string (profile)); - if (!gst_vaapi_encoder_h265_set_allowed_profiles (encoder, NULL)) - return FALSE; + if (profiles) { + ret = gst_vaapi_encoder_h265_set_allowed_profiles (encoder, profiles); + g_array_unref (profiles); } - return TRUE; + + return ret; } static GstCaps * From 65c8718f5e99d8a7cdd647ad79878c1ba44f1827 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 29 Jul 2020 22:32:55 +0800 Subject: [PATCH 3691/3781] libs: display: Add a helper function to get profiles by codec. Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay.c | 38 +++++++++++++++++++++++----- gst-libs/gst/vaapi/gstvaapidisplay.h | 4 +++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 3a6841d042..439144108f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -326,7 +326,7 @@ compare_profiles (gconstpointer a, gconstpointer b) /* Convert configs array to profiles as GstCaps */ static GArray * -get_profiles (GPtrArray * configs) +get_profiles (GPtrArray * configs, GstVaapiCodec codec) { GstVaapiProfileConfig *config; GArray *out_profiles; @@ -341,7 +341,8 @@ get_profiles (GPtrArray * configs) for (i = 0; i < configs->len; i++) { config = g_ptr_array_index (configs, i); - g_array_append_val (out_profiles, config->profile); + if (!codec || (codec == gst_vaapi_profile_get_codec (config->profile))) + g_array_append_val (out_profiles, config->profile); } return out_profiles; } @@ -1560,7 +1561,7 @@ gst_vaapi_display_has_video_processing (GstVaapiDisplay * display) * reference to the resulting array of #GstVaapiProfile elements, so * it shall be released with g_array_unref() after usage. * - * Return value: a newly allocated #GArray, or %NULL or error or if + * Return value: a newly allocated #GArray, or %NULL if error or if * decoding is not supported at all */ GArray * @@ -1570,7 +1571,7 @@ gst_vaapi_display_get_decode_profiles (GstVaapiDisplay * display) if (!ensure_profiles (display)) return NULL; - return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders); + return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders, 0); } /** @@ -1604,7 +1605,7 @@ gst_vaapi_display_has_decoder (GstVaapiDisplay * display, * reference to the resulting array of #GstVaapiProfile elements, so * it shall be released with g_array_unref() after usage. * - * Return value: a newly allocated #GArray, or %NULL or error or if + * Return value: a newly allocated #GArray, or %NULL if error or if * encoding is not supported at all */ GArray * @@ -1614,7 +1615,32 @@ gst_vaapi_display_get_encode_profiles (GstVaapiDisplay * display) if (!ensure_profiles (display)) return NULL; - return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders); + return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders, 0); +} + +/** + * gst_vaapi_display_get_encode_profiles_by_codec: + * @display: a #GstVaapiDisplay + * @codec: a #GstVaapiCodec + * + * Gets the supported profiles which belongs to @codec for encoding. + * The caller owns an extra reference to the resulting array of + * #GstVaapiProfile elements, so it shall be released with g_array_unref() + * after usage. + * + * Return value: a newly allocated #GArray, or %NULL if error or if + * no encoding profile is found specified by the @codec. + */ +GArray * +gst_vaapi_display_get_encode_profiles_by_codec (GstVaapiDisplay * display, + GstVaapiCodec codec) +{ + g_return_val_if_fail (display != NULL, NULL); + + if (!ensure_profiles (display)) + return NULL; + return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders, + codec); } /** diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 3eca38aaa5..07ecc82f49 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -242,6 +242,10 @@ gst_vaapi_display_has_decoder (GstVaapiDisplay * display, 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); From 2bb6e8c813fb674c6fa11b24a7580d4f1b7f8c3a Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 29 Jul 2020 22:05:41 +0800 Subject: [PATCH 3692/3781] plugins: encode: h265: set all allowed profiles to encoder. We should collect all allowed profiles and pass them to the inside encoder, rather than just calculate the max profile idc. The allowed profiles should also be supported by the HW. Part-of: --- gst/vaapi/gstvaapiencode_h265.c | 70 +++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h265.c b/gst/vaapi/gstvaapiencode_h265.c index baedcea1d8..b0ed4138d3 100644 --- a/gst/vaapi/gstvaapiencode_h265.c +++ b/gst/vaapi/gstvaapiencode_h265.c @@ -83,23 +83,77 @@ gst_vaapiencode_h265_set_config (GstVaapiEncode * base_encode) { GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encode->encoder); - GstCaps *allowed_caps; - GArray *profiles; + GstCaps *allowed_caps = NULL; + GstCaps *template_caps = NULL; + GArray *profiles = NULL; + GArray *profiles_hw = NULL; + GArray *profiles_allowed = NULL; + GstVaapiProfile profile; gboolean ret = TRUE; + guint i, j; + profiles_hw = gst_vaapi_display_get_encode_profiles_by_codec + (GST_VAAPI_PLUGIN_BASE_DISPLAY (base_encode), GST_VAAPI_CODEC_H265); + if (!profiles_hw) { + ret = FALSE; + goto out; + } + + template_caps = + gst_pad_get_pad_template_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD + (base_encode)); allowed_caps = gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (base_encode)); - if (!allowed_caps) - return TRUE; + if (!allowed_caps || allowed_caps == template_caps) { + ret = gst_vaapi_encoder_h265_set_allowed_profiles (encoder, profiles_hw); + goto out; + } else if (gst_caps_is_empty (allowed_caps)) { + ret = FALSE; + goto out; + } profiles = gst_vaapi_encoder_get_profiles_from_caps (allowed_caps, gst_vaapi_utils_h265_get_profile_from_string); - gst_caps_unref (allowed_caps); - if (profiles) { - ret = gst_vaapi_encoder_h265_set_allowed_profiles (encoder, profiles); - g_array_unref (profiles); + if (!profiles) { + ret = FALSE; + goto out; } + profiles_allowed = g_array_new (FALSE, FALSE, sizeof (GstVaapiProfile)); + if (!profiles_allowed) { + ret = FALSE; + goto out; + } + + for (i = 0; i < profiles->len; i++) { + profile = g_array_index (profiles, GstVaapiProfile, i); + for (j = 0; j < profiles_hw->len; j++) { + GstVaapiProfile p = g_array_index (profiles_hw, GstVaapiProfile, j); + if (p == profile) { + g_array_append_val (profiles_allowed, profile); + break; + } + } + } + if (profiles_allowed->len == 0) { + ret = FALSE; + goto out; + } + + ret = gst_vaapi_encoder_h265_set_allowed_profiles (encoder, profiles_allowed); + +out: + if (allowed_caps) + gst_caps_unref (allowed_caps); + if (template_caps) + gst_caps_unref (template_caps); + if (profiles) + g_array_unref (profiles); + if (profiles_hw) + g_array_unref (profiles_hw); + if (profiles_allowed) + g_array_unref (profiles_allowed); + return ret; } From 7a9a99d0c40df6540bdd9e441a2895b2c0cbc84b Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 3 Jul 2020 19:28:28 +0800 Subject: [PATCH 3693/3781] libs: encoder: h265: choose the profile based on allowed list. We can decide the profile in ensure_profile(), based on allowed list passed by the encode. We also need to check whether the entrypoint is available. Once it is decided, no need to check the hw entrypoint them again. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 141 ++++++++++------------ 1 file changed, 63 insertions(+), 78 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 4cc274cd4d..49745e4650 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -1057,95 +1057,84 @@ _check_vps_sps_pps_status (GstVaapiEncoderH265 * encoder, } } -/* Derives the profile supported by the underlying hardware */ static gboolean -ensure_hw_profile (GstVaapiEncoderH265 * encoder) +is_profile_allowed (GstVaapiEncoderH265 * encoder, GstVaapiProfile profile) { - GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); - GstVaapiEntrypoint entrypoint = encoder->entrypoint; - GstVaapiProfile profile, profiles[4]; - guint i, num_profiles = 0; + guint i; - profiles[num_profiles++] = encoder->profile; - switch (encoder->profile) { - case GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE: - profiles[num_profiles++] = GST_VAAPI_PROFILE_H265_MAIN; - // fall-through - case GST_VAAPI_PROFILE_H265_MAIN: - profiles[num_profiles++] = GST_VAAPI_PROFILE_H265_MAIN10; - break; - default: - break; - } - - 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; - } -} - -/* Check target decoder constraints */ -static gboolean -ensure_profile_limits (GstVaapiEncoderH265 * encoder) -{ - gint i; - - if (!encoder->allowed_profiles) + if (encoder->allowed_profiles == NULL) return TRUE; - for (i = 0; i < encoder->allowed_profiles->len; i++) { - if (encoder->profile == + for (i = 0; i < encoder->allowed_profiles->len; i++) + if (profile == g_array_index (encoder->allowed_profiles, GstVaapiProfile, i)) return TRUE; - } - GST_WARNING - ("Needs to lower coding tools to meet target decoder constraints"); - GST_WARNING ("Only supporting Main profile, reset profile to Main"); - - encoder->profile = GST_VAAPI_PROFILE_H265_MAIN; - encoder->profile_idc = - gst_vaapi_utils_h265_get_profile_idc (encoder->profile); - - return TRUE; + return FALSE; } -/* Derives the minimum profile from the active coding tools */ +/* Derives the profile from the active coding tools. */ static gboolean ensure_profile (GstVaapiEncoderH265 * encoder) { GstVaapiProfile profile; const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); + guint depth, chrome; + GstVaapiProfile profile_candidates[3]; + guint num, i; - /* Always start from "Main" profile for maximum - compatibility */ - profile = GST_VAAPI_PROFILE_H265_MAIN; + g_assert (GST_VIDEO_FORMAT_INFO_IS_YUV (gst_video_format_get_info (format))); + depth = GST_VIDEO_FORMAT_INFO_DEPTH (gst_video_format_get_info (format), 0); + chrome = gst_vaapi_utils_h265_get_chroma_format_idc + (gst_vaapi_video_format_get_chroma_type (format)); - if (format == GST_VIDEO_FORMAT_P010_10LE) - profile = GST_VAAPI_PROFILE_H265_MAIN10; - else if (format == GST_VIDEO_FORMAT_VUYA) - profile = GST_VAAPI_PROFILE_H265_MAIN_444; - else if (format == GST_VIDEO_FORMAT_Y410) - profile = GST_VAAPI_PROFILE_H265_MAIN_444_10; - else if (format == GST_VIDEO_FORMAT_Y210 || format == GST_VIDEO_FORMAT_YUY2) - profile = GST_VAAPI_PROFILE_H265_MAIN_422_10; + num = 0; + + if (chrome == 3) { + /* 4:4:4 */ + if (depth == 8) + profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_444; + if (depth <= 10) + profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_444_10; + } else if (chrome == 2) { + /* 4:2:2 */ + profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_422_10; + } else if (chrome == 1 || chrome == 0) { + /* 4:2:0 or 4:0:0 */ + if (depth == 8) + profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN; + if (depth <= 10) + profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN10; + /* Always add STILL_PICTURE as a candidate. */ + profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; + } + + if (num == 0) { + GST_ERROR ("Fail to find a profile for format %s.", + gst_video_format_to_string (format)); + return FALSE; + } + + profile = GST_VAAPI_PROFILE_UNKNOWN; + for (i = 0; i < num; i++) { + if (!is_profile_allowed (encoder, profile_candidates[i])) + continue; + /* If we can get valid entrypoint, hw must support this profile. */ + if (gst_vaapi_encoder_get_entrypoint (GST_VAAPI_ENCODER_CAST (encoder), + profile_candidates[i]) == GST_VAAPI_ENTRYPOINT_INVALID) + continue; + + profile = profile_candidates[i]; + break; + } + + if (profile == GST_VAAPI_PROFILE_UNKNOWN) { + GST_ERROR ("Fail to find a supported profile %sfor format %s.", + GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER ? + "in low power mode " : "", gst_video_format_to_string (format)); + return FALSE; + } encoder->profile = profile; encoder->profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile); @@ -2263,16 +2252,13 @@ ensure_profile_tier_level (GstVaapiEncoderH265 * encoder) const GstVaapiTierH265 tier = encoder->tier; const GstVaapiLevelH265 level = encoder->level; - if (!ensure_profile (encoder) || !ensure_profile_limits (encoder)) + if (!ensure_profile (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; encoder->entrypoint = gst_vaapi_encoder_get_entrypoint (GST_VAAPI_ENCODER_CAST (encoder), encoder->profile); - if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) { - GST_WARNING ("Cannot find valid entrypoint"); - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - } + g_assert (encoder->entrypoint != GST_VAAPI_ENTRYPOINT_INVALID); /* Ensure bitrate if not set already and derive the right level to use */ ensure_bitrate (encoder); @@ -3096,8 +3082,7 @@ set_context_info (GstVaapiEncoder * base_encoder) base_encoder->codedbuf_size += encoder->num_slices * (4 + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE + MAX_SHORT_TERM_REFPICSET_SIZE) / 8); - if (!ensure_hw_profile (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + GST_VAAPI_ENCODER_CAST (encoder)->profile = encoder->profile; base_encoder->num_ref_frames = (encoder->num_ref_frames + (encoder->num_bframes > 0 ? 1 : 0) + DEFAULT_SURFACES_COUNT); From 6ab488475a399f3f34bc5dedb7e4828099ccc1e5 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 31 Jul 2020 15:27:38 +0800 Subject: [PATCH 3694/3781] libs: decoder: fix a crash issue when get_surface_formats. Some context does not report any valid format that we can support. For example, the HEVC 444 12 bits decoder context, all the formats it reports is not supported now, which make the formats list a NULL array. We should check that pointer before we use it. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 192d71aab2..ed702310ba 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -1192,6 +1192,8 @@ gst_vaapi_decoder_get_surface_attributes (GstVaapiDecoder * decoder, if (ret) attribs.formats = gst_vaapi_context_get_surface_formats (decoder->context); + if (!attribs.formats) + return NULL; if (attribs.formats->len == 0) { g_array_unref (attribs.formats); return NULL; From 99ac072673c12e3f81cc2e774bb2536ace2508c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 25 May 2020 17:02:26 +0200 Subject: [PATCH 3695/3781] plugins: add gst_vaapi_caps_set_width_and_height_range() This utility function is called internally by gst_vaapi_build_caps_from_formats() and can be used outside. This function sets frame size and framerates ranges. Also gst_vaapi_build_caps_from_formats() is simplified. Part-of: --- gst/vaapi/gstvaapidecode.c | 35 +++++-------------------- gst/vaapi/gstvaapipluginutil.c | 48 ++++++++++++++++++++-------------- gst/vaapi/gstvaapipluginutil.h | 5 ++++ 3 files changed, 40 insertions(+), 48 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index afe2dd2730..7563a2f4b8 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -197,25 +197,6 @@ gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps) return TRUE; } -static inline void -caps_set_width_and_height_range (GstCaps * caps, gint min_width, - gint min_height, gint max_width, gint max_height) -{ - guint size, i; - GstStructure *structure; - - /* Set the width/height info to caps */ - size = gst_caps_get_size (caps); - for (i = 0; i < size; i++) { - structure = gst_caps_get_structure (caps, i); - if (!structure) - continue; - gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, min_width, - max_width, "height", GST_TYPE_INT_RANGE, min_height, max_height, - "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); - } -} - static gboolean gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) { @@ -234,7 +215,7 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) if (!decode->decoder) return FALSE; - out_caps = base_caps = raw_caps = va_caps = dma_caps = gltexup_caps = NULL; + dma_caps = gltexup_caps = NULL; formats = gst_vaapi_decoder_get_surface_attributes (decode->decoder, &min_width, &min_height, &max_width, &max_height, &mem_types); @@ -244,8 +225,8 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) base_caps = gst_vaapi_video_format_new_template_caps_from_list (formats); if (!base_caps) goto bail; - caps_set_width_and_height_range (base_caps, min_width, min_height, max_width, - max_height); + gst_vaapi_caps_set_width_and_height_range (base_caps, min_width, min_height, + max_width, max_height); raw_caps = gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps (GST_VAAPI_PLUGIN_BASE (decode), @@ -253,7 +234,7 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) if (!raw_caps) goto bail; raw_caps = gst_caps_copy (raw_caps); - caps_set_width_and_height_range (raw_caps, min_width, min_height, + gst_vaapi_caps_set_width_and_height_range (raw_caps, min_width, min_height, max_width, max_height); va_caps = gst_caps_copy (base_caps); @@ -272,8 +253,8 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) && gst_vaapi_display_has_opengl (GST_VAAPI_PLUGIN_BASE_DISPLAY (decode))) { gltexup_caps = gst_caps_from_string (GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS); if (gltexup_caps) { - caps_set_width_and_height_range (base_caps, min_width, min_height, - max_width, max_height); + gst_vaapi_caps_set_width_and_height_range (base_caps, min_width, + min_height, max_width, max_height); } } #endif @@ -283,9 +264,7 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) gst_caps_append (out_caps, dma_caps); if (gltexup_caps) gst_caps_append (out_caps, gltexup_caps); - if (raw_caps) - gst_caps_append (out_caps, raw_caps); - + gst_caps_append (out_caps, gst_caps_copy (raw_caps)); decode->allowed_srcpad_caps = out_caps; GST_INFO_OBJECT (decode, "allowed srcpad caps: %" GST_PTR_FORMAT, diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index f5eb6d56be..b98f305fc6 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -1071,6 +1071,25 @@ gst_vaapi_encoder_get_profiles_from_caps (GstCaps * caps, return profiles; } +void +gst_vaapi_caps_set_width_and_height_range (GstCaps * caps, gint min_width, + gint min_height, gint max_width, gint max_height) +{ + guint size, i; + GstStructure *structure; + + /* Set the width/height info to caps */ + size = gst_caps_get_size (caps); + for (i = 0; i < size; i++) { + structure = gst_caps_get_structure (caps, i); + if (!structure) + continue; + gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, min_width, + max_width, "height", GST_TYPE_INT_RANGE, min_height, max_height, + "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + } +} + /** * gst_vaapi_build_caps_from_formats: * @formats: an array of supported #GstVideoFormat @@ -1089,42 +1108,31 @@ GstCaps * gst_vaapi_build_caps_from_formats (GArray * formats, gint min_width, gint min_height, gint max_width, gint max_height, guint mem_types) { - GstCaps *out_caps = NULL; - GstCaps *raw_caps = NULL; - GstCaps *va_caps, *dma_caps; - guint i, size; - GstStructure *structure; + GstCaps *out_caps, *raw_caps, *va_caps, *dma_caps; + + dma_caps = NULL; raw_caps = gst_vaapi_video_format_new_template_caps_from_list (formats); if (!raw_caps) return NULL; - - /* Set the width/height info to caps */ - size = gst_caps_get_size (raw_caps); - for (i = 0; i < size; i++) { - structure = gst_caps_get_structure (raw_caps, i); - if (!structure) - continue; - gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, min_width, - max_width, "height", GST_TYPE_INT_RANGE, min_height, max_height, NULL); - } - - out_caps = gst_caps_copy (raw_caps); + gst_vaapi_caps_set_width_and_height_range (raw_caps, min_width, min_height, + max_width, max_height); va_caps = gst_caps_copy (raw_caps); gst_caps_set_features_simple (va_caps, gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE)); - gst_caps_append (out_caps, va_caps); if (gst_vaapi_mem_type_supports (mem_types, GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF)) { dma_caps = gst_caps_copy (raw_caps); gst_caps_set_features_simple (dma_caps, gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF)); - gst_caps_append (out_caps, dma_caps); } - gst_caps_unref (raw_caps); + out_caps = va_caps; + if (dma_caps) + gst_caps_append (out_caps, dma_caps); + gst_caps_append (out_caps, raw_caps); return out_caps; } diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 5ae79b8927..236ccd3a0e 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -161,6 +161,11 @@ GArray * gst_vaapi_encoder_get_profiles_from_caps (GstCaps * caps, GstVaapiStrToProfileFunc func); +G_GNUC_INTERNAL +void +gst_vaapi_caps_set_width_and_height_range (GstCaps * caps, gint min_width, + gint min_height, gint max_width, gint max_height); + G_GNUC_INTERNAL GstCaps * gst_vaapi_build_caps_from_formats (GArray * formats, gint min_width, From 5902e5bfdbd800948962b19a229e7d1af258761f Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 30 Jul 2020 23:37:10 +0800 Subject: [PATCH 3696/3781] video-format: Add the missing P012_LE into GST_VAAPI_FORMATS_ALL. Part-of: --- gst-libs/gst/vaapi/video-format.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index 9af180b1d9..9f23959b84 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -30,7 +30,7 @@ G_BEGIN_DECLS #define GST_VAAPI_FORMATS_ALL "{ ENCODED, " \ - "NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, VUYA, Y210, Y410, " \ + "NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, P012_LE, VUYA, Y210, Y410, " \ "ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE " \ "}" From 07aadb82fba079d0a3250607d9a41f9a43a84798 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Thu, 11 Jun 2020 08:25:57 +0200 Subject: [PATCH 3697/3781] libs: display: always call close_display() All close_display() have their own checks for use_foreign_display and only destroy locally created objects in that case. Without this objects other than the actuall foreign display itself are leaked. Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 439144108f..5e8a135dca 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -900,6 +900,7 @@ static void gst_vaapi_display_destroy (GstVaapiDisplay * display) { GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); + GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS (display); g_clear_pointer (&priv->decoders, g_ptr_array_unref); g_clear_pointer (&priv->encoders, g_ptr_array_unref); @@ -914,11 +915,8 @@ gst_vaapi_display_destroy (GstVaapiDisplay * display) priv->display = NULL; } - if (!priv->use_foreign_display) { - GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS (display); - if (klass->close_display) - klass->close_display (display); - } + if (klass->close_display) + klass->close_display (display); g_clear_pointer (&priv->display_name, g_free); g_clear_pointer (&priv->vendor_string, g_free); From 3d1cf3a6da1b00c6bc36a5bec5efb109db22808a Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Fri, 19 Jun 2020 21:54:52 +0200 Subject: [PATCH 3698/3781] doc: libs: wayland: add 'transfer full' to the returnvalye of gst_vaapi_window_wayland_new Part-of: --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index b1b32e601c..4a0338baaa 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -969,7 +969,7 @@ gst_vaapi_window_wayland_init (GstVaapiWindowWayland * window) * will be attached to the @display and remains invisible to the user * until gst_vaapi_window_show() is called. * - * Return value: the newly allocated #GstVaapiWindow object + * Return value (transfer full): the newly allocated #GstVaapiWindow object */ GstVaapiWindow * gst_vaapi_window_wayland_new (GstVaapiDisplay * display, From 40364c2c098e2a8f3013f61e2eaf1c5a7b10a613 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Fri, 19 Jun 2020 09:11:20 +0200 Subject: [PATCH 3699/3781] libs: wayland: implement video overlay API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Wayland sub-surfaces API is used to embed the video into an application window. See Appendix A. Wayland Protocol Specification as the following. """ The aim of sub-surfaces is to offload some of the compositing work within a window from clients to the compositor. A prime example is a video player with decorations and video in separate wl_surface objects. This should allow the compositor to pass YUV video buffer processing to dedicated overlay hardware when possible. """ Added new method gst_vaapi_window_wayland_new_with_surface() Original-Patch-By: Víctor Manuel Jáquez Leal Zhao Halley changzhix.wei@intel.com Hyunjun Ko Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 4 + .../gst/vaapi/gstvaapidisplay_wayland_priv.h | 1 + gst-libs/gst/vaapi/gstvaapiwindow.c | 2 + gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 86 +++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiwindow_wayland.h | 4 + 5 files changed, 89 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 7dfe857802..e6e3f39460 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -151,6 +151,9 @@ registry_handle_global (void *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) { @@ -254,6 +257,7 @@ gst_vaapi_display_wayland_close_display (GstVaapiDisplay * 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); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index 6822d822ea..a4e9992ed4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -72,6 +72,7 @@ struct _GstVaapiDisplayWaylandPrivate 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; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 19085408f7..01514038df 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -544,10 +544,12 @@ gst_vaapi_window_set_size (GstVaapiWindow * window, guint width, guint height) if (!GST_VAAPI_WINDOW_GET_CLASS (window)->resize (window, width, height)) return; + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); gst_vaapi_video_pool_replace (&window->surface_pool, NULL); window->width = width; window->height = height; + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); } static inline void diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 4a0338baaa..4cf76a15d0 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -40,6 +40,7 @@ #include GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapi_window); +GST_DEBUG_CATEGORY_EXTERN (gst_debug_vaapi); #define GST_CAT_DEFAULT gst_debug_vaapi_window #define GST_VAAPI_WINDOW_WAYLAND_CAST(obj) \ @@ -104,6 +105,7 @@ struct _GstVaapiWindowWaylandPrivate struct xdg_toplevel *xdg_toplevel; struct wl_shell_surface *wl_shell_surface; struct wl_surface *surface; + struct wl_subsurface *video_subsurface; struct wl_region *opaque_region; struct wl_event_queue *event_queue; FrameState *last_frame; @@ -350,6 +352,9 @@ gst_vaapi_window_wayland_set_fullscreen (GstVaapiWindow * window, GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + if (window->use_foreign_window) + return TRUE; + if (!priv->is_shown) { priv->fullscreen_on_show = fullscreen; return TRUE; @@ -403,8 +408,34 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window, return FALSE; wl_proxy_set_queue ((struct wl_proxy *) priv->surface, priv->event_queue); - /* Prefer XDG-shell over deprecated wl_shell (if available) */ - if (priv_display->xdg_wm_base) { + if (window->use_foreign_window) { + struct wl_surface *wl_surface; + + if (priv_display->subcompositor) { + if (GST_VAAPI_SURFACE_ID (window) == VA_INVALID_ID) { + GST_ERROR ("Invalid window"); + return FALSE; + } + + wl_surface = (struct wl_surface *) GST_VAAPI_WINDOW_ID (window); + GST_VAAPI_WINDOW_LOCK_DISPLAY (window); + priv->video_subsurface = + wl_subcompositor_get_subsurface (priv_display->subcompositor, + priv->surface, wl_surface); + GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); + if (!priv->video_subsurface) + return FALSE; + + wl_proxy_set_queue ((struct wl_proxy *) priv->video_subsurface, + priv->event_queue); + + wl_subsurface_set_desync (priv->video_subsurface); + } else { + GST_ERROR ("Wayland server does not support subsurfaces"); + window->use_foreign_window = FALSE; + } + /* Prefer XDG-shell over deprecated wl_shell (if available) */ + } else if (priv_display->xdg_wm_base) { /* Create the XDG surface. We make the toplevel on VaapiWindow::show() */ GST_VAAPI_WINDOW_LOCK_DISPLAY (window); priv->xdg_surface = xdg_wm_base_get_xdg_surface (priv_display->xdg_wm_base, @@ -467,6 +498,7 @@ gst_vaapi_window_wayland_finalize (GObject * object) g_clear_pointer (&priv->xdg_surface, xdg_surface_destroy); g_clear_pointer (&priv->wl_shell_surface, wl_shell_surface_destroy); + g_clear_pointer (&priv->video_subsurface, wl_subsurface_destroy); g_clear_pointer (&priv->surface, wl_surface_destroy); g_clear_pointer (&priv->event_queue, wl_event_queue_destroy); @@ -484,6 +516,9 @@ gst_vaapi_window_wayland_resize (GstVaapiWindow * window, GstVaapiDisplayWaylandPrivate *const priv_display = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_WINDOW_DISPLAY (window)); + if (window->use_foreign_window) + return TRUE; + GST_DEBUG ("resize window, new size %ux%u", width, height); if (priv->opaque_region) @@ -630,8 +665,7 @@ choose_next_format (GstVaapiDisplay * const display, gint * next_index) static GstVaapiDmabufStatus dmabuf_buffer_from_surface (GstVaapiWindow * window, GstVaapiSurface * surface, - const GstVaapiRectangle * rect, guint va_flags, - struct wl_buffer **out_buffer) + guint va_flags, struct wl_buffer **out_buffer) { GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window); GstVaapiDisplayWaylandPrivate *const priv_display = @@ -690,8 +724,8 @@ dmabuf_buffer_from_surface (GstVaapiWindow * window, GstVaapiSurface * surface, } } - buffer = zwp_linux_buffer_params_v1_create_immed (params, rect->width, - rect->height, format, 0); + buffer = zwp_linux_buffer_params_v1_create_immed (params, window->width, + window->height, format, 0); if (!buffer) ret = GST_VAAPI_DMABUF_NOT_SUPPORTED; @@ -754,8 +788,7 @@ again: } } if (!priv->dmabuf_broken) { - ret = dmabuf_buffer_from_surface (window, surface, dst_rect, va_flags, - buffer); + ret = dmabuf_buffer_from_surface (window, surface, va_flags, buffer); switch (ret) { case GST_VAAPI_DMABUF_SUCCESS: goto out; @@ -843,6 +876,11 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, guint width, height; gboolean ret; + /* Skip rendering without valid window size. This can happen with a foreign + window if the render rectangle is not yet set. */ + if (window->width == 0 || window->height == 0) + return TRUE; + /* Check that we don't need to crop source VA surface */ gst_vaapi_surface_get_size (surface, &width, &height); if (src_rect->x != 0 || src_rect->y != 0) @@ -856,6 +894,11 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, if (dst_rect->width != window->width || dst_rect->height != window->height) priv->need_vpp = TRUE; + /* Check that the surface has the correct size for the window */ + if (dst_rect->width != src_rect->width || + dst_rect->height != src_rect->height) + priv->need_vpp = TRUE; + ret = buffer_from_surface (window, &surface, src_rect, dst_rect, flags, &buffer); if (!ret) @@ -980,3 +1023,30 @@ gst_vaapi_window_wayland_new (GstVaapiDisplay * display, return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_WAYLAND, display, GST_VAAPI_ID_INVALID, width, height); } + +/** + * gst_vaapi_window_wayland_new_with_surface: + * @display: a #GstVaapiDisplay + * @wl_surface: a Wayland surface pointer + * + * Creates a window with the specified @wl_surface. The window + * will be attached to the @display and remains invisible to the user + * until gst_vaapi_window_show() is called. + * + * Return value (transfer full): the newly allocated #GstVaapiWindow object + * + * Since: 1.18 + */ +GstVaapiWindow * +gst_vaapi_window_wayland_new_with_surface (GstVaapiDisplay * display, + guintptr wl_surface) +{ + g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_WAYLAND (display), NULL); + g_return_val_if_fail (wl_surface, NULL); + + GST_CAT_DEBUG (gst_debug_vaapi, "new window from surface 0x%" + G_GINTPTR_MODIFIER "x", wl_surface); + + return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_WAYLAND, display, + wl_surface, 0, 0); +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h index d4eb427a94..016f582516 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.h @@ -45,6 +45,10 @@ GstVaapiWindow * gst_vaapi_window_wayland_new (GstVaapiDisplay * display, guint width, guint height); +GstVaapiWindow * +gst_vaapi_window_wayland_new_with_surface (GstVaapiDisplay * display, + guintptr wl_surface); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowWayland, gst_object_unref) G_END_DECLS From a5f37a21ec4c56e0237793c51f441c1de1c0bf08 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Wed, 8 Nov 2017 13:23:39 +0900 Subject: [PATCH 3700/3781] vaapisink: implements gst_vaapisink_wayland_create_window_from_handle() Implements gst_vaapisink_wayland_create_window_from_handle() to support using external wl_surface. Part-of: --- gst/vaapi/gstvaapisink.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 92f953475c..c1f56bf0e8 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -561,11 +561,31 @@ gst_vaapisink_wayland_create_window (GstVaapiSink * sink, guint width, return TRUE; } +static gboolean +gst_vaapisink_wayland_create_window_from_handle (GstVaapiSink * sink, + guintptr window) +{ + GstVaapiDisplay *display; + + if (!gst_vaapisink_ensure_display (sink)) + return FALSE; + display = GST_VAAPI_PLUGIN_BASE_DISPLAY (sink); + + if (sink->window == NULL || (guintptr) sink->window != window) { + gst_vaapi_window_replace (&sink->window, NULL); + sink->window = gst_vaapi_window_wayland_new_with_surface (display, window); + } + + return sink->window != NULL; +} + static const inline GstVaapiSinkBackend * gst_vaapisink_backend_wayland (void) { static const GstVaapiSinkBackend GstVaapiSinkBackendWayland = { .create_window = gst_vaapisink_wayland_create_window, + .create_window_from_handle = + gst_vaapisink_wayland_create_window_from_handle, .render_surface = gst_vaapisink_render_surface, }; return &GstVaapiSinkBackendWayland; From a362d99e9e3bb705f4c4fd1e1e3aa869d86ec342 Mon Sep 17 00:00:00 2001 From: Hyunjun Ko Date: Fri, 19 Jun 2020 09:21:16 +0200 Subject: [PATCH 3701/3781] libs: window: implements gst_vaapi_window_set_render_rectangle Implements new vmethod gst_vaapi_window_set_render_rectangle, which is doing set the information of the rendered rectangle set by user. This is necessary on wayland at least to get exact information of external surface. And vaapisink calls this when gst_video_overlay_set_render_rectangle is called. Part-of: --- gst-libs/gst/vaapi/gstvaapiwindow.c | 26 +++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiwindow.h | 4 ++++ gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 1 + gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 12 ++++++++++ gst/vaapi/gstvaapisink.c | 6 +++++ 5 files changed, 49 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.c b/gst-libs/gst/vaapi/gstvaapiwindow.c index 01514038df..7fd4502f95 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow.c @@ -413,6 +413,32 @@ gst_vaapi_window_get_fullscreen (GstVaapiWindow * window) return window->is_fullscreen; } +/** + * gst_vaapi_window_set_render_rectangle: + * @window: a #GstVaapiWindow + * @x: the horizontal offset of the render area inside the window + * @y: the vertical offset of the render area inside the window + * @width: the width of the render area inside the window + * @height: the height of the render area inside the window + * + * Set information of the render area. + * + * Since: 1.18 + */ +void +gst_vaapi_window_set_render_rectangle (GstVaapiWindow * window, gint x, gint y, + gint width, gint height) +{ + const GstVaapiWindowClass *klass; + + g_return_if_fail (window != NULL); + + klass = GST_VAAPI_WINDOW_GET_CLASS (window); + + if (klass->set_render_rect) + klass->set_render_rect (window, x, y, width, height); +} + /** * gst_vaapi_window_set_fullscreen: * @window: a #GstVaapiWindow diff --git a/gst-libs/gst/vaapi/gstvaapiwindow.h b/gst-libs/gst/vaapi/gstvaapiwindow.h index 563443966f..c1628f79c8 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow.h @@ -85,6 +85,10 @@ gst_vaapi_window_set_height (GstVaapiWindow * window, guint height); void gst_vaapi_window_set_size (GstVaapiWindow * window, guint width, guint height); +void +gst_vaapi_window_set_render_rectangle (GstVaapiWindow * window, gint x, gint y, + gint width, gint height); + gboolean gst_vaapi_window_put_surface (GstVaapiWindow * window, GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index a0b0582775..168e002c0c 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -129,6 +129,7 @@ struct _GstVaapiWindowClass guintptr (*get_colormap) (GstVaapiWindow * window); gboolean (*unblock) (GstVaapiWindow * window); gboolean (*unblock_cancel) (GstVaapiWindow * window); + void (*set_render_rect) (GstVaapiWindow * window, gint x, gint y, gint width, gint height); }; GstVaapiWindow * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 4cf76a15d0..0f596e59a3 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -531,6 +531,17 @@ gst_vaapi_window_wayland_resize (GstVaapiWindow * window, return TRUE; } +void +gst_vaapi_window_wayland_set_render_rect (GstVaapiWindow * window, gint x, + gint y, gint width, gint height) +{ + GstVaapiWindowWaylandPrivate *const priv = + GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + + if (priv->video_subsurface) + wl_subsurface_set_position (priv->video_subsurface, x, y); +} + static inline gboolean frame_done (FrameState * frame) { @@ -991,6 +1002,7 @@ gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass) window_class->set_fullscreen = gst_vaapi_window_wayland_set_fullscreen; window_class->unblock = gst_vaapi_window_wayland_unblock; window_class->unblock_cancel = gst_vaapi_window_wayland_unblock_cancel; + window_class->set_render_rect = gst_vaapi_window_wayland_set_render_rect; signals[SIZE_CHANGED] = g_signal_new ("size-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index c1f56bf0e8..2d7824e962 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -633,6 +633,12 @@ gst_vaapisink_video_overlay_set_render_rectangle (GstVideoOverlay * overlay, display_rect->width = width; display_rect->height = height; + if (gst_vaapisink_ensure_render_rect (sink, width, height) && sink->window) { + gst_vaapi_window_set_render_rectangle (sink->window, x, y, width, height); + gst_vaapi_window_set_size (sink->window, width, height); + gst_vaapisink_reconfigure_window (sink); + } + GST_DEBUG ("render rect (%d,%d):%ux%u", display_rect->x, display_rect->y, display_rect->width, display_rect->height); From 9eb25ab849a83ba248915e901e398c03b585d726 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Fri, 19 Jun 2020 21:26:52 +0200 Subject: [PATCH 3702/3781] libs: wayland: update the opaque region in set_render_rect gst_vaapi_window_wayland_set_render_rect() may be called from an arbitrary thread. That thread may be responsible for making the window visible. At that point another thread will block in gst_vaapi_window_wayland_sync() because the frame callback will not be called until the window is visible. If that happens, then acquiring the display lock in gst_vaapi_window_wayland_set_render_rect() would result in a deadlock. Cache the size of the opaque rectangle separately and create the opaque region right before applying it to the surface. Part-of: --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 46 ++++++++++++++------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 0f596e59a3..a7abe53728 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -106,7 +106,6 @@ struct _GstVaapiWindowWaylandPrivate struct wl_shell_surface *wl_shell_surface; struct wl_surface *surface; struct wl_subsurface *video_subsurface; - struct wl_region *opaque_region; struct wl_event_queue *event_queue; FrameState *last_frame; GstPoll *poll; @@ -118,6 +117,8 @@ struct _GstVaapiWindowWaylandPrivate gint configure_pending; gboolean need_vpp; gboolean dmabuf_broken; + GMutex opaque_mutex; + gint opaque_width, opaque_height; }; /** @@ -465,6 +466,8 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window, priv->poll = gst_poll_new (TRUE); gst_poll_fd_init (&priv->pollfd); + g_mutex_init (&priv->opaque_mutex); + if (priv->fullscreen_on_show) gst_vaapi_window_wayland_set_fullscreen (window, TRUE); @@ -507,26 +510,29 @@ gst_vaapi_window_wayland_finalize (GObject * object) G_OBJECT_CLASS (gst_vaapi_window_wayland_parent_class)->finalize (object); } -static gboolean -gst_vaapi_window_wayland_resize (GstVaapiWindow * window, +static void +gst_vaapi_window_wayland_update_opaque_region (GstVaapiWindow * window, guint width, guint height) { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); - GstVaapiDisplayWaylandPrivate *const priv_display = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_WINDOW_DISPLAY (window)); + g_mutex_lock (&priv->opaque_mutex); + priv->opaque_width = width; + priv->opaque_height = height; + g_mutex_unlock (&priv->opaque_mutex); +} + +static gboolean +gst_vaapi_window_wayland_resize (GstVaapiWindow * window, + guint width, guint height) +{ if (window->use_foreign_window) return TRUE; GST_DEBUG ("resize window, new size %ux%u", width, height); - if (priv->opaque_region) - wl_region_destroy (priv->opaque_region); - GST_VAAPI_WINDOW_LOCK_DISPLAY (window); - priv->opaque_region = wl_compositor_create_region (priv_display->compositor); - GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window); - wl_region_add (priv->opaque_region, 0, 0, width, height); + gst_vaapi_window_wayland_update_opaque_region (window, width, height); return TRUE; } @@ -540,6 +546,8 @@ gst_vaapi_window_wayland_set_render_rect (GstVaapiWindow * window, gint x, if (priv->video_subsurface) wl_subsurface_set_position (priv->video_subsurface, x, y); + + gst_vaapi_window_wayland_update_opaque_region (window, width, height); } static inline gboolean @@ -880,6 +888,8 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + GstVaapiDisplayWaylandPrivate *const priv_display = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_WINDOW_DISPLAY (window)); struct wl_display *const wl_display = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window); struct wl_buffer *buffer; @@ -946,11 +956,17 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, wl_surface_attach (priv->surface, buffer, 0, 0); wl_surface_damage (priv->surface, 0, 0, width, height); - if (priv->opaque_region) { - wl_surface_set_opaque_region (priv->surface, priv->opaque_region); - wl_region_destroy (priv->opaque_region); - priv->opaque_region = NULL; + g_mutex_lock (&priv->opaque_mutex); + if (priv->opaque_width > 0) { + struct wl_region *opaque_region; + opaque_region = wl_compositor_create_region (priv_display->compositor); + wl_region_add (opaque_region, 0, 0, width, height); + wl_surface_set_opaque_region (priv->surface, opaque_region); + wl_region_destroy (opaque_region); + priv->opaque_width = 0; + priv->opaque_height = 0; } + g_mutex_unlock (&priv->opaque_mutex); wl_proxy_set_queue ((struct wl_proxy *) buffer, priv->event_queue); wl_buffer_add_listener (buffer, &frame_buffer_listener, frame); From 672b2dd991ddc2f7487fdc500ef194524f4c716b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 29 Nov 2017 11:11:39 +0100 Subject: [PATCH 3703/3781] test: vaapicontext: add PLAY and NULL buttons They only appear when only one sink is instanciated and their purpose is to test the NULL-PLAY use case in context sharing. Part-of: --- tests/examples/test-vaapicontext.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/examples/test-vaapicontext.c b/tests/examples/test-vaapicontext.c index 0085ca968b..355d2ceebe 100644 --- a/tests/examples/test-vaapicontext.c +++ b/tests/examples/test-vaapicontext.c @@ -205,6 +205,24 @@ bus_sync_handler (GstBus * bus, GstMessage * msg, gpointer data) return GST_BUS_PASS; } +static void +play_cb (GtkButton * button, gpointer data) +{ + AppData *app = data; + + gst_element_set_state (app->pipeline, GST_STATE_PLAYING); +} + +static void +null_cb (GtkButton * button, gpointer data) +{ + AppData *app = data; + + gst_element_set_state (app->pipeline, GST_STATE_NULL); + app->va_display = NULL; +} + + static void realize_cb (GtkWidget * widget, gpointer data) { @@ -283,6 +301,16 @@ build_ui (AppData * app) gtk_box_pack_start (GTK_BOX (bbox), create_rotate_button (app, "sink2"), TRUE, TRUE, 0); + } else { + GtkWidget *button; + + button = gtk_button_new_with_label ("PLAYING"); + gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, TRUE, 0); + g_signal_connect (button, "clicked", G_CALLBACK (play_cb), app); + + button = gtk_button_new_with_label ("NULL"); + gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, TRUE, 0); + g_signal_connect (button, "clicked", G_CALLBACK (null_cb), app); } gtk_widget_show_all (mainwin); From 283fceac0b048fe95c6a15b2690d818ece2a519e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 1 Dec 2017 20:18:28 +0100 Subject: [PATCH 3704/3781] test: vaapicontext: use playbin to test files Part-of: --- tests/examples/test-vaapicontext.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/examples/test-vaapicontext.c b/tests/examples/test-vaapicontext.c index 355d2ceebe..ed5b45041e 100644 --- a/tests/examples/test-vaapicontext.c +++ b/tests/examples/test-vaapicontext.c @@ -35,12 +35,12 @@ static gboolean g_multisink; static gchar *g_filepath; +static GstElement *g_vaapisink; static GOptionEntry g_options[] = { {"multi", 'm', 0, G_OPTION_ARG_NONE, &g_multisink, "test multiple vaapisink", NULL}, - {"file", 'f', 0, G_OPTION_ARG_STRING, &g_filepath, - "file path to play (only mp4/h264)", NULL}, + {"file", 'f', 0, G_OPTION_ARG_STRING, &g_filepath, "file path to play", NULL}, {NULL,} }; @@ -258,11 +258,14 @@ create_rotate_button (AppData * app, const gchar * name) GstElement *sink; sink = gst_bin_get_by_name (GST_BIN (app->pipeline), name); + if (!sink && !g_strcmp0 (name, "sink1")) + sink = g_vaapisink; g_assert (sink); rotate = gtk_button_new_with_label ("Rotate"); g_signal_connect (rotate, "clicked", G_CALLBACK (button_rotate_cb), sink); - gst_object_unref (sink); + if (sink != g_vaapisink) + gst_object_unref (sink); return rotate; } @@ -344,8 +347,8 @@ main (gint argc, gchar ** argv) app.pipeline = gst_parse_launch ("videotestsrc ! vaapih264enc ! " "vaapidecodebin ! vaapisink name=sink1", &error); } else { - app.pipeline = gst_parse_launch ("filesrc name=src ! qtdemux ! h264parse ! " - "vaapidecodebin ! vaapisink name=sink1", &error); + app.pipeline = gst_element_factory_make ("playbin", NULL); + g_assert (app.pipeline); } if (error) { @@ -355,12 +358,10 @@ main (gint argc, gchar ** argv) } if (!g_multisink && g_filepath) { - GstElement *src; - - src = gst_bin_get_by_name (GST_BIN (app.pipeline), "src"); - g_assert (src); - g_object_set (src, "location", g_filepath, NULL); - gst_object_unref (src); + g_vaapisink = gst_element_factory_make ("vaapisink", "sink1"); + g_assert (g_vaapisink); + g_object_set (app.pipeline, "uri", g_filepath, "video-sink", g_vaapisink, + NULL); } build_ui (&app); From 24be7b8aaec7dd427652236b8d4f4af4e35024be Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Fri, 19 Jun 2020 09:23:52 +0200 Subject: [PATCH 3705/3781] test: vaapicontext: support wayland display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Wayland, The whole gtk window is one Wayland surface. So gtk_widget_get_window() must be called on the top-level widget. For any other widget the following gdk_window_ensure_native() may create a new top-level Wayland surface that is never visible. As a result, the coordinates passed to gst_video_overlay_set_render_rectangle() must be relativ to the top-level window. Otherwise the video is placed incorrectly. Original-Patch-By: Víctor Manuel Jáquez Leal Part-of: --- tests/examples/meson.build | 3 +- tests/examples/test-vaapicontext.c | 146 ++++++++++++++++++++++------- 2 files changed, 116 insertions(+), 33 deletions(-) diff --git a/tests/examples/meson.build b/tests/examples/meson.build index 0a61f7d050..e7b1dee58c 100644 --- a/tests/examples/meson.build +++ b/tests/examples/meson.build @@ -12,7 +12,7 @@ foreach example : examples install: false) endforeach -if USE_X11 +if USE_X11 and USE_WAYLAND if gtk_dep.found() executable('test-vaapicontext', 'test-vaapicontext.c', c_args : gstreamer_vaapi_args, @@ -22,6 +22,7 @@ if gtk_dep.found() libva_dep, x11_dep, gtk_dep, + libva_wayland_dep, libva_x11_dep ], install: false) endif diff --git a/tests/examples/test-vaapicontext.c b/tests/examples/test-vaapicontext.c index ed5b45041e..5b4679560a 100644 --- a/tests/examples/test-vaapicontext.c +++ b/tests/examples/test-vaapicontext.c @@ -23,14 +23,17 @@ #include #include + #include -#include -#include #ifdef GDK_WINDOWING_X11 +#include #include -#else -#error "X11 is not supported in GTK+" +#include +#endif +#ifdef GDK_WINDOWING_WAYLAND +#include +#include #endif static gboolean g_multisink; @@ -51,6 +54,8 @@ typedef struct _CustomData GstElement *pipeline; guintptr videoarea_handle[2]; GstObject *gstvaapidisplay; + GtkWidget *video_widget[2]; + GstVideoOverlay *overlay[2]; } AppData; static void @@ -71,26 +76,35 @@ button_rotate_cb (GtkWidget * widget, GstElement * elem) g_object_set (elem, "rotation", tags[counter++ % G_N_ELEMENTS (tags)], NULL); } -static Display * -get_x11_window_display (AppData * app) +static gpointer +get_native_display (AppData * app, gboolean * is_x11) { -#if defined(GDK_WINDOWING_X11) GdkDisplay *gdk_display; - Display *x11_display; gdk_display = gtk_widget_get_display (app->main_window); - x11_display = gdk_x11_display_get_xdisplay (gdk_display); - return x11_display; + +#if defined(GDK_WINDOWING_X11) + if (GDK_IS_X11_DISPLAY (gdk_display)) { + *is_x11 = TRUE; + return gdk_x11_display_get_xdisplay (gdk_display); + } else #endif - g_error ("Running in a non-X11 environment"); +#ifdef GDK_WINDOWING_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display)) { + *is_x11 = FALSE; + return gdk_wayland_display_get_wl_display (gdk_display); + } else +#endif + g_error ("Running in a non supported environment"); } static VADisplay -ensure_va_display (AppData * app) +ensure_va_display (AppData * app, gpointer native_display, gboolean is_x11) { if (app->va_display) return app->va_display; - app->va_display = vaGetDisplay (get_x11_window_display (app)); + app->va_display = is_x11 ? + vaGetDisplay (native_display) : vaGetDisplayWl (native_display); /* There's no need to call vaInitialize() since element does it * internally */ return app->va_display; @@ -102,23 +116,43 @@ create_vaapi_app_display_context (AppData * app, gboolean new_va_display) GstContext *context; GstStructure *s; VADisplay va_display; - Display *x11_display; + gpointer native_display = NULL; + const gchar *name = NULL; + gboolean is_x11; - x11_display = get_x11_window_display (app); + native_display = get_native_display (app, &is_x11); - if (new_va_display) - va_display = vaGetDisplay (x11_display); - else - va_display = ensure_va_display (app); + if (new_va_display) { + va_display = is_x11 ? + vaGetDisplay (native_display) : vaGetDisplayWl (native_display); + } else + va_display = ensure_va_display (app, native_display, is_x11); + + name = is_x11 ? "x11-display" : "wl-display"; context = gst_context_new ("gst.vaapi.app.Display", FALSE); s = gst_context_writable_structure (context); gst_structure_set (s, "va-display", G_TYPE_POINTER, va_display, NULL); - gst_structure_set (s, "x11-display", G_TYPE_POINTER, x11_display, NULL); + gst_structure_set (s, name, G_TYPE_POINTER, native_display, NULL); return context; } +static void +get_allocation (GtkWidget * widget, GtkAllocation * allocation) +{ + GdkDisplay *display = gdk_display_get_default (); + + gtk_widget_get_allocation (widget, allocation); + + /* On Wayland the whole gtk window is one surface and the video is a + * subsurface of the top-level surface. So the position must be relative + * to the top-level window not relative to the parent widget */ + if (GDK_IS_WAYLAND_DISPLAY (display)) + gtk_widget_translate_coordinates (widget, gtk_widget_get_toplevel (widget), + 0, 0, &allocation->x, &allocation->y); +} + static GstBusSyncReply bus_sync_handler (GstBus * bus, GstMessage * msg, gpointer data) { @@ -158,15 +192,23 @@ bus_sync_handler (GstBus * bus, GstMessage * msg, gpointer data) break; } case GST_MESSAGE_ELEMENT:{ + GstVideoOverlay *overlay; + GtkAllocation allocation; + guint i; + if (!gst_is_video_overlay_prepare_window_handle_message (msg)) break; - if (g_strcmp0 (GST_MESSAGE_SRC_NAME (msg), "sink2") == 0) - gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY - (GST_MESSAGE_SRC (msg)), app->videoarea_handle[1]); - else - gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY - (GST_MESSAGE_SRC (msg)), app->videoarea_handle[0]); + overlay = GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (msg)); + + i = (g_strcmp0 (GST_MESSAGE_SRC_NAME (msg), "sink2") == 0) ? 1 : 0; + + app->overlay[i] = overlay; + get_allocation (app->video_widget[i], &allocation); + gst_video_overlay_set_window_handle (overlay, app->videoarea_handle[i]); + gtk_widget_queue_draw_area (app->video_widget[i], 0, 0, allocation.width, + allocation.height); + break; } case GST_MESSAGE_HAVE_CONTEXT:{ @@ -228,16 +270,53 @@ realize_cb (GtkWidget * widget, gpointer data) { AppData *app = data; GdkWindow *window; + GdkDisplay *display; static guint counter = 0; -#if defined(GDK_WINDOWING_X11) - window = gtk_widget_get_window (widget); + display = gdk_display_get_default (); + +#ifdef GDK_WINDOWING_WAYLAND + /* On wayland gtk_widget_get_window() only works correctly for the + * toplevel widget. Otherwise a new wayland surface is created but + * never used and the video remains invisible. */ + if (GDK_IS_WAYLAND_DISPLAY (display)) + window = gtk_widget_get_window (app->main_window); + else +#endif + window = gtk_widget_get_window (widget); if (!gdk_window_ensure_native (window)) - g_error ("Couldn't create native window needed for GstXOverlay!"); + g_error ("Couldn't create native window needed for GstOverlay!"); - app->videoarea_handle[counter++ % 2] = GDK_WINDOW_XID (window); +#ifdef GDK_WINDOWING_X11 + if (GDK_IS_X11_DISPLAY (display)) { + app->videoarea_handle[counter++ % 2] = GDK_WINDOW_XID (window); + } else #endif +#ifdef GDK_WINDOWING_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (display)) { + app->videoarea_handle[counter++ % 2] = + (guintptr) gdk_wayland_window_get_wl_surface (window); + } else +#endif + g_error ("Unsupported GDK backend"); +} + +static void +draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) +{ + AppData *app = data; + GtkAllocation allocation; + + get_allocation (widget, &allocation); + + gst_println ("draw_cb x %d, y %d, w %d, h %d\n", + allocation.x, allocation.y, allocation.width, allocation.height); + + if (app->overlay[0]) { + gst_video_overlay_set_render_rectangle (app->overlay[0], allocation.x, + allocation.y, allocation.width, allocation.height); + } } static GtkWidget * @@ -248,6 +327,7 @@ create_video_box (AppData * app) video_area = gtk_drawing_area_new (); gtk_widget_set_size_request (video_area, 640, 480); g_signal_connect (video_area, "realize", G_CALLBACK (realize_cb), app); + g_signal_connect (video_area, "draw", G_CALLBACK (draw_cb), app); return video_area; } @@ -288,7 +368,8 @@ build_ui (AppData * app) gtk_box_pack_start (GTK_BOX (vbox), pane, TRUE, TRUE, 0); /* first video box */ - gtk_paned_pack1 (GTK_PANED (pane), create_video_box (app), TRUE, TRUE); + app->video_widget[0] = create_video_box (app); + gtk_paned_pack1 (GTK_PANED (pane), app->video_widget[0], TRUE, TRUE); /* rotate buttons */ bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); @@ -300,7 +381,8 @@ build_ui (AppData * app) if (g_multisink) { /* second video box */ - gtk_paned_pack2 (GTK_PANED (pane), create_video_box (app), TRUE, TRUE); + app->video_widget[1] = create_video_box (app); + gtk_paned_pack2 (GTK_PANED (pane), app->video_widget[1], TRUE, TRUE); gtk_box_pack_start (GTK_BOX (bbox), create_rotate_button (app, "sink2"), TRUE, TRUE, 0); From d11ba513bb7f717c45a35dd742b02fe0b2f23383 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Thu, 18 Jun 2020 20:25:18 +0200 Subject: [PATCH 3706/3781] test: vaapicontext: fix draw callback with multiple videos The callback is called for both windows. So make sure that gst_video_overlay_set_render_rectangle() is called for the correct one. Otherwise, the left video will be randomly moved behind the right video. Part-of: --- tests/examples/test-vaapicontext.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/examples/test-vaapicontext.c b/tests/examples/test-vaapicontext.c index 5b4679560a..98760dc585 100644 --- a/tests/examples/test-vaapicontext.c +++ b/tests/examples/test-vaapicontext.c @@ -307,14 +307,17 @@ draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) { AppData *app = data; GtkAllocation allocation; + int i; + + i = (widget == app->video_widget[0]) ? 0 : 1; get_allocation (widget, &allocation); - gst_println ("draw_cb x %d, y %d, w %d, h %d\n", + gst_println ("draw_cb[%d] x %d, y %d, w %d, h %d\n", i, allocation.x, allocation.y, allocation.width, allocation.height); - if (app->overlay[0]) { - gst_video_overlay_set_render_rectangle (app->overlay[0], allocation.x, + if (app->overlay[i]) { + gst_video_overlay_set_render_rectangle (app->overlay[i], allocation.x, allocation.y, allocation.width, allocation.height); } } From 887ba40e658cf8a02ce23af6e3f359eca5cda518 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Fri, 31 Jul 2020 11:07:23 +0200 Subject: [PATCH 3707/3781] libs: window: wayland: destroy all wayland buffers during finalize Some buffers and the associated FrameState state may still be pending at that point. If the wayland connection is shared, then messages for the buffer may still arrive. However, the associated event queue is already deleted. So the result is a crash. With a private connection the associated memory is leaked instead. Part-of: --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 48 +++++++++++++-------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index a7abe53728..caf1dc63a8 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -61,6 +61,7 @@ struct _FrameState GstVaapiWindow *window; GstVaapiSurface *surface; GstVaapiVideoPool *surface_pool; + struct wl_buffer *buffer; struct wl_callback *callback; gboolean done; }; @@ -82,23 +83,6 @@ frame_state_new (GstVaapiWindow * window) return frame; } -static void -frame_state_free (FrameState * frame) -{ - if (!frame) - return; - - if (frame->surface) { - if (frame->surface_pool) - gst_vaapi_video_pool_put_object (frame->surface_pool, frame->surface); - frame->surface = NULL; - } - gst_vaapi_video_pool_replace (&frame->surface_pool, NULL); - - g_clear_pointer (&frame->callback, wl_callback_destroy); - g_slice_free (FrameState, frame); -} - struct _GstVaapiWindowWaylandPrivate { struct xdg_surface *xdg_surface; @@ -107,6 +91,7 @@ struct _GstVaapiWindowWaylandPrivate struct wl_surface *surface; struct wl_subsurface *video_subsurface; struct wl_event_queue *event_queue; + GList *frames; FrameState *last_frame; GstPoll *poll; GstPollFD pollfd; @@ -155,6 +140,29 @@ enum static guint signals[N_SIGNALS]; +static void +frame_state_free (FrameState * frame) +{ + GstVaapiWindowWaylandPrivate *priv; + + if (!frame) + return; + + priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); + priv->frames = g_list_remove (priv->frames, frame); + + if (frame->surface) { + if (frame->surface_pool) + gst_vaapi_video_pool_put_object (frame->surface_pool, frame->surface); + frame->surface = NULL; + } + gst_vaapi_video_pool_replace (&frame->surface_pool, NULL); + + g_clear_pointer (&frame->callback, wl_callback_destroy); + wl_buffer_destroy (frame->buffer); + g_slice_free (FrameState, frame); +} + static void handle_xdg_toplevel_configure (void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states) @@ -499,6 +507,9 @@ gst_vaapi_window_wayland_finalize (GObject * object) if (priv->event_queue) wl_display_roundtrip_queue (wl_display, priv->event_queue); + while (priv->frames) + frame_state_free ((FrameState *) priv->frames->data); + g_clear_pointer (&priv->xdg_surface, xdg_surface_destroy); g_clear_pointer (&priv->wl_shell_surface, wl_shell_surface_destroy); g_clear_pointer (&priv->video_subsurface, wl_subsurface_destroy); @@ -581,7 +592,6 @@ frame_release_callback (void *data, struct wl_buffer *wl_buffer) if (!frame->done) if (!frame_done (frame)) GST_INFO ("cannot remove last frame because it didn't match or empty"); - wl_buffer_destroy (wl_buffer); frame_state_free (frame); } @@ -971,8 +981,10 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, wl_proxy_set_queue ((struct wl_proxy *) buffer, priv->event_queue); wl_buffer_add_listener (buffer, &frame_buffer_listener, frame); + frame->buffer = buffer; frame->callback = wl_surface_frame (priv->surface); wl_callback_add_listener (frame->callback, &frame_callback_listener, frame); + priv->frames = g_list_append (priv->frames, frame); wl_surface_commit (priv->surface); wl_display_flush (wl_display); From 89580cc2308cb8bd9d3cc6c673a2e0064b09e064 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 4 Aug 2020 21:15:01 +0300 Subject: [PATCH 3708/3781] gstvaapiminiobject.c: fix clang 10 warnings the typesystem checks in g_atomic_pointer_compare_and_exchange seem to trigger some false positives with clang 10 similar to gstreamer!584 Part-of: --- gst-libs/gst/vaapi/gstvaapiminiobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.c b/gst-libs/gst/vaapi/gstvaapiminiobject.c index 52052ad3d2..7b18983245 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.c @@ -193,7 +193,7 @@ gst_vaapi_mini_object_replace (GstVaapiMiniObject ** old_object_ptr, gst_vaapi_mini_object_ref_internal (new_object); while (!g_atomic_pointer_compare_and_exchange ((gpointer *) old_object_ptr, - old_object, new_object)) + (gpointer) old_object, new_object)) old_object = g_atomic_pointer_get ((gpointer *) old_object_ptr); if (old_object) From 6e97062d35d3da4b91e9280f8ae2fb8e710e22c6 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 31 Jul 2020 19:17:39 +0800 Subject: [PATCH 3709/3781] video format: Fix P012_LE's chrome type typo. Part-of: --- gst-libs/gst/vaapi/video-format.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index fe466794ed..310cbeffaf 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -106,7 +106,7 @@ static const GstVideoFormatMap gst_vaapi_video_default_formats[] = { DEF_YUV (VA_BYTE_ORDER_NOT_CARE, GRAY8, INVALID, ('Y', '8', '0', '0'), 8, 400), DEF_YUV (VA_LSB_FIRST, P010_10LE, P010, ('P', '0', '1', '0'), 24, 420_10BPP), - DEF_YUV (VA_LSB_FIRST, P012_LE, P012, ('P', '0', '1', '2'), 24, 420_10BPP), + DEF_YUV (VA_LSB_FIRST, P012_LE, P012, ('P', '0', '1', '2'), 24, 420_12BPP), /* AYUV is a clear defined format by doc */ DEF_YUV (VA_LSB_FIRST, VUYA, AYUV, ('A', 'Y', 'U', 'V'), 32, 444), From 55769a16c769511e870444c0bb9b29e982bab0e2 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 31 Jul 2020 18:22:46 +0800 Subject: [PATCH 3710/3781] libs: encoder: H265: Enable Main 12 profile support. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder.c | 3 ++- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 29 ++++++++++++++++++++--- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 3 +++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 22b0e248e6..83d26f0f1b 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -669,7 +669,8 @@ is_chroma_type_supported (GstVaapiEncoder * encoder) cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420_10BPP && cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV444 && cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV444_10BPP && - cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV422_10BPP) + cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV422_10BPP && + cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420_12BPP) goto unsupported; if (!get_config_attribute (encoder, VAConfigAttribRTFormat, &format)) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 49745e4650..85951daad5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -383,6 +383,26 @@ bs_write_profile_tier_level (GstBitWriter * bs, /* lower_bit_rate_constraint_flag */ WRITE_UINT32 (bs, 1, 1); break; + case GST_VAAPI_PROFILE_H265_MAIN12: + /* max_12bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_10bit_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_8bit_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_422chroma_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_420chroma_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_monochrome_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* intra_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* one_picture_only_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* lower_bit_rate_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + break; default: GST_WARNING ("do not support the profile: %s of range extensions", gst_vaapi_profile_get_va_name (profile)); @@ -1081,7 +1101,7 @@ ensure_profile (GstVaapiEncoderH265 * encoder) const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); guint depth, chrome; - GstVaapiProfile profile_candidates[3]; + GstVaapiProfile profile_candidates[4]; guint num, i; g_assert (GST_VIDEO_FORMAT_INFO_IS_YUV (gst_video_format_get_info (format))); @@ -1106,8 +1126,11 @@ ensure_profile (GstVaapiEncoderH265 * encoder) profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN; if (depth <= 10) profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN10; - /* Always add STILL_PICTURE as a candidate. */ - profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; + if (depth <= 12) + profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN12; + /* Always add STILL_PICTURE as a candidate for Main and Main10. */ + if (depth <= 10) + profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; } if (num == 0) { diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 06597bfc35..b0efbf297d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -43,6 +43,7 @@ static const struct map gst_vaapi_h265_profile_map[] = { { GST_VAAPI_PROFILE_H265_MAIN_444, "main-444" }, { GST_VAAPI_PROFILE_H265_MAIN_444_10, "main-444-10" }, { GST_VAAPI_PROFILE_H265_MAIN_422_10, "main-422-10" }, + { GST_VAAPI_PROFILE_H265_MAIN12, "main-12" }, { 0, NULL } /* *INDENT-ON* */ }; @@ -342,6 +343,8 @@ gst_vaapi_utils_h265_get_profile_idc (GstVaapiProfile profile) case GST_VAAPI_PROFILE_H265_MAIN_444: /* Fall through */ case GST_VAAPI_PROFILE_H265_MAIN_444_10: + /* Fall through */ + case GST_VAAPI_PROFILE_H265_MAIN12: profile_idc = GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION; break; default: From 34b1d195b7360fba6d70adb12072f1d25d377c8a Mon Sep 17 00:00:00 2001 From: Xu Guangxin Date: Thu, 6 Aug 2020 12:51:27 +0800 Subject: [PATCH 3711/3781] h264dec: mark remaining frames as unreference before exec_picture_refs_modification 8.2.4.2 required this. Some clips will crash if we do not fill the reference list like this. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 7dd7ed7fee..fd57a3f0b4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -3099,8 +3099,6 @@ init_picture_refs (GstVaapiDecoderH264 * decoder, break; } - ret = ret && exec_picture_refs_modification (decoder, picture, slice_hdr); - switch (slice_hdr->type % 5) { case GST_H264_B_SLICE: num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1; @@ -3120,6 +3118,8 @@ init_picture_refs (GstVaapiDecoderH264 * decoder, break; } + ret = ret && exec_picture_refs_modification (decoder, picture, slice_hdr); + mark_picture_refs (decoder, picture); return ret; From 3e9a6f80aadc911e390c1212a689427b4bb8dcfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 7 Aug 2020 16:41:49 +0200 Subject: [PATCH 3712/3781] build: update for gl pkg-config file split Part-of: --- gst-libs/gst/vaapi/meson.build | 7 ++++--- gst/vaapi/meson.build | 3 ++- meson.build | 27 ++++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index 527414f1ad..aadd4fd4c8 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -203,6 +203,7 @@ endif gstlibvaapi_deps = [ gstbase_dep, gstvideo_dep, gstgl_dep, + gstglproto_dep, gstcodecparsers_dep, libva_dep, libm ] @@ -210,16 +211,16 @@ if USE_DRM gstlibvaapi_deps += [libva_drm_dep, libdrm_dep, libudev_dep] endif if USE_EGL - gstlibvaapi_deps += [egl_dep, gmodule_dep] + gstlibvaapi_deps += [egl_dep, gmodule_dep, gstglegl_dep] endif if USE_GLX gstlibvaapi_deps += [libva_x11_dep, x11_dep, gl_dep, libdl_dep] endif if USE_WAYLAND - gstlibvaapi_deps += [libva_wayland_dep, wayland_client_dep, wayland_protocols_dep] + gstlibvaapi_deps += [libva_wayland_dep, gstglwayland_dep, wayland_client_dep, wayland_protocols_dep] endif if USE_X11 - gstlibvaapi_deps += [libva_x11_dep, x11_dep, xrandr_dep] + gstlibvaapi_deps += [libva_x11_dep, x11_dep, xrandr_dep, gstglx11_dep] endif gstlibvaapi = static_library('gstlibvaapi-@0@'.format(api_version), diff --git a/gst/vaapi/meson.build b/gst/vaapi/meson.build index d8c24c3b68..4265759227 100644 --- a/gst/vaapi/meson.build +++ b/gst/vaapi/meson.build @@ -38,7 +38,8 @@ gstvaapi = library('gstvaapi', c_args : gstreamer_vaapi_args + ['-DGST_USE_UNSTABLE_API'], include_directories : [configinc, libsinc], dependencies : [gstbase_dep, gstvideo_dep, gstallocators_dep, gstpbutils_dep, - libva_dep, gstlibvaapi_dep, gstgl_dep, libm], + libva_dep, gstlibvaapi_dep, gstgl_dep, gstglproto_dep, gstglx11_dep, gstglegl_dep, + gstglwayland_dep, libm], install : true, install_dir : plugins_install_dir, ) diff --git a/meson.build b/meson.build index 34dd4aed80..ae916ef8a8 100644 --- a/meson.build +++ b/meson.build @@ -53,6 +53,10 @@ gstcodecparsers_dep = dependency('gstreamer-codecparsers-1.0', version : gst_req fallback : ['gst-plugins-bad', 'gstcodecparsers_dep']) gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, fallback : ['gst-plugins-base', 'gstgl_dep'], required: false) +gstglproto_dep = dependency('', required : false) +gstglx11_dep = dependency('', required : false) +gstglwayland_dep = dependency('', required : false) +gstglegl_dep = dependency('', required : false) # Disable compiler warnings for unused variables and args if gst debug system is disabled if gst_dep.type_name() == 'internal' @@ -116,12 +120,33 @@ USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() a USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no' USE_WAYLAND = libva_wayland_dep.found() and wayland_client_dep.found() and wayland_protocols_dep.found() and wayland_scanner_bin.found() and get_option('with_wayland') != 'no' USE_X11 = libva_x11_dep.found() and x11_dep.found() and get_option('with_x11') != 'no' -USE_GLX = libva_x11_dep.found() and x11_dep.found() and gl_dep.found() and libdl_dep.found() and get_option('with_glx') != 'no' and USE_X11 +USE_GLX = gl_dep.found() and libdl_dep.found() and get_option('with_glx') != 'no' and USE_X11 if not (USE_DRM or USE_X11 or USE_WAYLAND) error('No renderer API found (it is requried either DRM, X11 and/or WAYLAND)') endif +if gstgl_dep.found() + gstglproto_dep = dependency('gstreamer-gl-prototypes-1.0', version : gst_req, + fallback : ['gst-plugins-base', 'gstglproto_dep'], required: true) + # Behind specific checks because meson fails at optional dependencies with a + # fallback to the same subproject. On the first failure, meson will never + # check the system again even if the fallback never existed. + # Last checked with meson 0.54.3 + if USE_X11 + gstglx11_dep = dependency('gstreamer-gl-x11-1.0', version : gst_req, + fallback : ['gst-plugins-base', 'gstglx11_dep'], required: true) + endif + if USE_WAYLAND + gstglwayland_dep = dependency('gstreamer-gl-wayland-1.0', version : gst_req, + fallback : ['gst-plugins-base', 'gstglwayland_dep'], required: true) + endif + if USE_EGL + gstglegl_dep = dependency('gstreamer-gl-egl-1.0', version : gst_req, + fallback : ['gst-plugins-base', 'gstglegl_dep'], required: true) + endif +endif + driverdir = libva_dep.get_pkgconfig_variable('driverdir') if driverdir == '' driverdir = join_paths(get_option('prefix'), get_option('libdir'), 'dri') From 30290115affc43078b2844cfd165d464bbcc335e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 10 Jul 2020 17:05:38 +0800 Subject: [PATCH 3713/3781] libs: util: h265: use common parser API to get vaapi profiles. We can reuse H265 parser's API to recognize the correct profile and then just need to convert them to VAAPI profiles. Part-of: --- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 221 ++++++------------------ 1 file changed, 50 insertions(+), 171 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index b0efbf297d..b912075789 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -141,185 +141,64 @@ gst_vaapi_utils_h265_get_profile_score (GstVaapiProfile profile) GstVaapiProfile gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) { - GstVaapiProfile profile; + GstVaapiProfile vaapi_profile; + GstH265Profile profile; - switch (sps->profile_tier_level.profile_idc) { - case GST_H265_PROFILE_IDC_MAIN: - profile = GST_VAAPI_PROFILE_H265_MAIN; + g_return_val_if_fail (sps != NULL, GST_VAAPI_PROFILE_UNKNOWN); + + profile = gst_h265_profile_tier_level_get_profile (&sps->profile_tier_level); + switch (profile) { + case GST_H265_PROFILE_MAIN: + /* Main Intra, recognize it as MAIN */ + case GST_H265_PROFILE_MAIN_INTRA: + vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN; break; - case GST_H265_PROFILE_IDC_MAIN_10: - profile = GST_VAAPI_PROFILE_H265_MAIN10; + case GST_H265_PROFILE_MAIN_10: + /* Main 10 Intra, recognize it as MAIN10 */ + case GST_H265_PROFILE_MAIN_10_INTRA: + vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN10; break; - case GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE: - profile = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; + case GST_H265_PROFILE_MAIN_12: + /* Main 12 Intra, recognize it as MAIN_12 */ + case GST_H265_PROFILE_MAIN_12_INTRA: + vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN12; + break; + case GST_H265_PROFILE_MAIN_STILL_PICTURE: + vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; + break; + case GST_H265_PROFILE_MAIN_422_10: + /* Main 422_10 Intra, recognize it as MAIN_422_10 */ + case GST_H265_PROFILE_MAIN_422_10_INTRA: + vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_422_10; + break; + case GST_H265_PROFILE_MAIN_444: + /* Main 444 Intra, recognize it as MAIN_444 */ + case GST_H265_PROFILE_MAIN_444_INTRA: + vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_444; + break; + case GST_H265_PROFILE_MAIN_444_10: + /* Main 444_10 Intra, recognize it as MAIN_444_10 */ + case GST_H265_PROFILE_MAIN_444_10_INTRA: + vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_444_10; + break; + case GST_H265_PROFILE_SCREEN_EXTENDED_MAIN: + vaapi_profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN; + break; + case GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10: + vaapi_profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10; + break; + case GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444: + vaapi_profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444; + break; + case GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10: + vaapi_profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10; break; - case GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION: - if (sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 0 - && sps->profile_tier_level.max_422chroma_constraint_flag == 1 - && sps->profile_tier_level.max_420chroma_constraint_flag == 0 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 0 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0 - && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { - profile = GST_VAAPI_PROFILE_H265_MAIN_422_10; - break; - } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 1 - && sps->profile_tier_level.max_422chroma_constraint_flag == 0 - && sps->profile_tier_level.max_420chroma_constraint_flag == 0 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 0 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0 - && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { - profile = GST_VAAPI_PROFILE_H265_MAIN_444; - break; - } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 0 - && sps->profile_tier_level.max_422chroma_constraint_flag == 0 - && sps->profile_tier_level.max_420chroma_constraint_flag == 0 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 0 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0 - && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { - profile = GST_VAAPI_PROFILE_H265_MAIN_444_10; - break; - } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 1 - && sps->profile_tier_level.max_422chroma_constraint_flag == 1 - && sps->profile_tier_level.max_420chroma_constraint_flag == 1 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 1 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { - /* Main Intra, recognize it as MAIN */ - profile = GST_VAAPI_PROFILE_H265_MAIN; - break; - } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 0 - && sps->profile_tier_level.max_422chroma_constraint_flag == 1 - && sps->profile_tier_level.max_420chroma_constraint_flag == 1 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 1 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { - /* Main 10 Intra, recognize it as MAIN10 */ - profile = GST_VAAPI_PROFILE_H265_MAIN10; - break; - } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 1 - && sps->profile_tier_level.max_422chroma_constraint_flag == 0 - && sps->profile_tier_level.max_420chroma_constraint_flag == 0 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 1 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { - /* Main 444 Intra, recognize it as MAIN_444 */ - profile = GST_VAAPI_PROFILE_H265_MAIN_444; - break; - } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 0 - && sps->profile_tier_level.max_422chroma_constraint_flag == 0 - && sps->profile_tier_level.max_420chroma_constraint_flag == 0 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 1 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { - /* Main 444_10 Intra, recognize it as MAIN_444_10 */ - profile = GST_VAAPI_PROFILE_H265_MAIN_444_10; - break; - } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 0 - && sps->profile_tier_level.max_422chroma_constraint_flag == 1 - && sps->profile_tier_level.max_420chroma_constraint_flag == 0 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 1 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { - /* Main 422_10 Intra, recognize it as MAIN_422_10 */ - profile = GST_VAAPI_PROFILE_H265_MAIN_422_10; - break; - } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 0 - && sps->profile_tier_level.max_8bit_constraint_flag == 0 - && sps->profile_tier_level.max_422chroma_constraint_flag == 1 - && sps->profile_tier_level.max_420chroma_constraint_flag == 1 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 0 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { - profile = GST_VAAPI_PROFILE_H265_MAIN12; - break; - } else if (sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 0 - && sps->profile_tier_level.max_8bit_constraint_flag == 0 - && sps->profile_tier_level.max_422chroma_constraint_flag == 1 - && sps->profile_tier_level.max_420chroma_constraint_flag == 1 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 1 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0) { - /* Main 12 Intra, recognize it as MAIN12 */ - profile = GST_VAAPI_PROFILE_H265_MAIN12; - break; - } - case GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING: - if (sps->profile_tier_level.max_14bit_constraint_flag == 1 - && sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 1 - && sps->profile_tier_level.max_422chroma_constraint_flag == 1 - && sps->profile_tier_level.max_420chroma_constraint_flag == 1 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 0 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0 - && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { - profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN; - break; - } else if (sps->profile_tier_level.max_14bit_constraint_flag == 1 - && sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 0 - && sps->profile_tier_level.max_422chroma_constraint_flag == 1 - && sps->profile_tier_level.max_420chroma_constraint_flag == 1 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 0 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0 - && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { - profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10; - break; - } else if (sps->profile_tier_level.max_14bit_constraint_flag == 1 - && sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 1 - && sps->profile_tier_level.max_422chroma_constraint_flag == 0 - && sps->profile_tier_level.max_420chroma_constraint_flag == 0 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 0 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0 - && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { - profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444; - break; - } else if (sps->profile_tier_level.max_14bit_constraint_flag == 1 - && sps->profile_tier_level.max_12bit_constraint_flag == 1 - && sps->profile_tier_level.max_10bit_constraint_flag == 1 - && sps->profile_tier_level.max_8bit_constraint_flag == 0 - && sps->profile_tier_level.max_422chroma_constraint_flag == 0 - && sps->profile_tier_level.max_420chroma_constraint_flag == 0 - && sps->profile_tier_level.max_monochrome_constraint_flag == 0 - && sps->profile_tier_level.intra_constraint_flag == 0 - && sps->profile_tier_level.one_picture_only_constraint_flag == 0 - && sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) { - profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10; - break; - } default: GST_DEBUG ("unsupported profile_idc value"); - profile = GST_VAAPI_PROFILE_UNKNOWN; + vaapi_profile = GST_VAAPI_PROFILE_UNKNOWN; break; } - return profile; + return vaapi_profile; } /** Returns H.265 profile_idc value from GstVaapiProfile */ From a50b466fc72d69146c7009b9ed1d931a66e1014b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 12 Aug 2020 17:50:50 +0200 Subject: [PATCH 3714/3781] vaapidecode: expose raw src caps with same chroma The try-and-error approach for getting the possible image formats from a surface has brought several problems in different drivers, from crashes to drop in performance. Instead of that we change the algorithm to determine the possible image formats based in the surface chroma: only those available image formats with same chroma are exposed as possible raw caps. Do this is important to avoid performance degrading in raw sinks which doesn't handle NV12 but it does YV12 or I420. Part-of: --- gst/vaapi/gstvaapidecode.c | 50 +++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 7563a2f4b8..b92edd1785 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -200,6 +200,7 @@ gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps) static gboolean gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) { + GstVaapiDisplay *const display = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode); GstCaps *out_caps, *raw_caps, *va_caps, *dma_caps, *gltexup_caps, *base_caps; GArray *formats; gint min_width, min_height, max_width, max_height; @@ -209,7 +210,7 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) if (decode->allowed_srcpad_caps) return TRUE; - if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (decode)) + if (!display) return FALSE; if (!decode->decoder) @@ -228,14 +229,41 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) gst_vaapi_caps_set_width_and_height_range (base_caps, min_width, min_height, max_width, max_height); - raw_caps = gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps - (GST_VAAPI_PLUGIN_BASE (decode), - GST_VIDEO_INFO_FORMAT (&decode->decoded_info)); - if (!raw_caps) - goto bail; - raw_caps = gst_caps_copy (raw_caps); - gst_vaapi_caps_set_width_and_height_range (raw_caps, min_width, min_height, - max_width, max_height); + { + GArray *img_formats = gst_vaapi_display_get_image_formats (display); + GstVideoFormat decoded_format = + GST_VIDEO_INFO_FORMAT (&decode->decoded_info); + + if (!img_formats) + img_formats = g_array_ref (formats); + + if (decoded_format != GST_VIDEO_FORMAT_UNKNOWN) { + guint decoded_chroma = + gst_vaapi_video_format_get_chroma_type (decoded_format); + GArray *new_img_formats = + g_array_new (FALSE, FALSE, sizeof (GstVideoFormat)); + gint i; + + for (i = 0; i < img_formats->len; i++) { + const GstVideoFormat fmt = + g_array_index (img_formats, GstVideoFormat, i); + if (gst_vaapi_video_format_get_chroma_type (fmt) == decoded_chroma) + g_array_append_val (new_img_formats, fmt); + } + + if (new_img_formats->len == 0) { + g_clear_pointer (&new_img_formats, g_array_unref); + } else { + g_clear_pointer (&img_formats, g_array_unref); + img_formats = new_img_formats; + } + } + + raw_caps = gst_vaapi_video_format_new_template_caps_from_list (img_formats); + gst_vaapi_caps_set_width_and_height_range (raw_caps, min_width, min_height, + max_width, max_height); + g_array_unref (img_formats); + } va_caps = gst_caps_copy (base_caps); gst_caps_set_features_simple (va_caps, @@ -447,6 +475,10 @@ is_surface_resolution_changed (GstVaapiDecode * decode, surface_format = GST_VIDEO_FORMAT_NV12; } + /* reset allowed source caps since they are dependant of the decoded + * surface format */ + gst_caps_replace (&decode->allowed_srcpad_caps, NULL); + gst_video_info_set_format (vinfo, surface_format, surface_width, surface_height); From 089ef59c374c1940273a4fa309c08bd7e02ffcd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 12 Aug 2020 18:48:59 +0200 Subject: [PATCH 3715/3781] plugins: remove gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps() Since nobody uses it, just remove it. Thus extract_allowed_surface_formats() is refactored to attend only gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps(). Now a surface is created when the image chorma is different from the previous one. And if the driver has the quirk, it outputs all the supported image formats without trying them. Part-of: --- gst/vaapi/gstvaapipluginbase.c | 77 ++++++++++------------------------ gst/vaapi/gstvaapipluginbase.h | 5 --- 2 files changed, 21 insertions(+), 61 deletions(-) diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 5cf1a7b3c9..72b28b86a7 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1404,14 +1404,19 @@ no_valid_gl_display: static GArray * extract_allowed_surface_formats (GstVaapiDisplay * display, - GArray * img_formats, GstVideoFormat specified_format, - GstPadDirection direction) + GArray * img_formats) { guint i; GArray *out_formats; + guint surface_chroma = 0; GstVaapiSurface *surface = NULL; - g_assert (direction == GST_PAD_SRC || direction == GST_PAD_SINK); + /* let's assume all the formats are possible to download */ + if (gst_vaapi_display_has_driver_quirks (display, + GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE)) { + out_formats = g_array_ref (img_formats); + goto bail; + } out_formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), @@ -1424,54 +1429,34 @@ extract_allowed_surface_formats (GstVaapiDisplay * display, g_array_index (img_formats, GstVideoFormat, i); GstVaapiImage *image; GstVideoInfo vi; - GstVideoFormat surface_format; - gboolean res; + guint img_chroma; if (img_format == GST_VIDEO_FORMAT_UNKNOWN) continue; - surface_format = - (specified_format == GST_VIDEO_FORMAT_UNKNOWN) ? - img_format : specified_format; - if (!surface) { - gst_video_info_set_format (&vi, surface_format, 64, 64); + img_chroma = gst_vaapi_video_format_get_chroma_type (img_format); + if (img_chroma != surface_chroma) { + if (surface) + gst_vaapi_surface_unref (surface); + gst_video_info_set_format (&vi, img_format, 64, 64); surface = gst_vaapi_surface_new_full (display, &vi, 0); if (!surface) continue; + surface_chroma = img_chroma; } image = gst_vaapi_image_new (display, img_format, 64, 64); - if (!image) { - /* Just reuse the surface if the format is specified */ - if (specified_format == GST_VIDEO_FORMAT_UNKNOWN) - gst_mini_object_replace ((GstMiniObject **) & surface, NULL); - + if (!image) continue; - } - - res = FALSE; - if (direction == GST_PAD_SRC) { - res = gst_vaapi_surface_get_image (surface, image); - } else { - if (!gst_vaapi_display_has_driver_quirks (display, - GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE)) - res = gst_vaapi_surface_put_image (surface, image); - else - res = TRUE; /* Let's say it's possible to upload - * all formats */ - } - if (res) + if (gst_vaapi_surface_put_image (surface, image)) g_array_append_val (out_formats, img_format); - gst_vaapi_image_unref (image); - /* Just reuse the surface if the format is specified */ - if (specified_format == GST_VIDEO_FORMAT_UNKNOWN) - gst_mini_object_replace ((GstMiniObject **) & surface, NULL); } if (surface) gst_vaapi_surface_unref (surface); +bail: if (out_formats->len == 0) { g_array_unref (out_formats); return NULL; @@ -1480,8 +1465,7 @@ extract_allowed_surface_formats (GstVaapiDisplay * display, } static gboolean -ensure_allowed_raw_caps (GstVaapiPluginBase * plugin, GstVideoFormat format, - GstPadDirection direction) +ensure_allowed_raw_caps (GstVaapiPluginBase * plugin) { GArray *formats, *out_formats; GstVaapiDisplay *display; @@ -1496,8 +1480,7 @@ ensure_allowed_raw_caps (GstVaapiPluginBase * plugin, GstVideoFormat format, formats = gst_vaapi_display_get_image_formats (display); if (!formats) goto bail; - out_formats = - extract_allowed_surface_formats (display, formats, format, direction); + out_formats = extract_allowed_surface_formats (display, formats); if (!out_formats) goto bail; out_caps = gst_vaapi_video_format_new_template_caps_from_list (out_formats); @@ -1529,25 +1512,7 @@ bail: GstCaps * gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps (GstVaapiPluginBase * plugin) { - if (!ensure_allowed_raw_caps (plugin, GST_VIDEO_FORMAT_UNKNOWN, GST_PAD_SINK)) - return NULL; - return plugin->allowed_raw_caps; -} - -/** - * gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps: - * @plugin: a #GstVaapiPluginBase - * @format: a #GstVideoFormat, the format we need to check - * - * Returns the raw #GstCaps allowed by the element. - * - * Returns: the allowed raw #GstCaps or %NULL - **/ -GstCaps * -gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps (GstVaapiPluginBase * - plugin, GstVideoFormat format) -{ - if (!ensure_allowed_raw_caps (plugin, format, GST_PAD_SRC)) + if (!ensure_allowed_raw_caps (plugin)) return NULL; return plugin->allowed_raw_caps; } diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index c48f3bbed8..94aa296f25 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -301,11 +301,6 @@ G_GNUC_INTERNAL GstCaps * gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps (GstVaapiPluginBase * plugin); -G_GNUC_INTERNAL -GstCaps * -gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps ( - GstVaapiPluginBase * plugin, GstVideoFormat format); - G_GNUC_INTERNAL void gst_vaapi_plugin_base_set_srcpad_can_dmabuf (GstVaapiPluginBase * plugin, From 992d9e3a20662b11654ac37e46419c363d49bce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 26 May 2020 16:18:32 +0200 Subject: [PATCH 3716/3781] libs: filter: gst_vaapi_filter_get_memory_types() Part-of: --- gst-libs/gst/vaapi/gstvaapifilter.c | 18 ++++++++++++++++++ gst-libs/gst/vaapi/gstvaapifilter.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index a6e69da7b0..9af76831c2 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1947,6 +1947,24 @@ gst_vaapi_filter_append_caps (GstVaapiFilter * filter, GstStructure * structure) } +/** + * gst_vaapi_filter_get_memory_types: + * @filter: a #GstVaapiFilter + * + * Gets the surface's memory types available in @filter's context. + * + * Returns: surface's memory types available in @filter context. + **/ +guint +gst_vaapi_filter_get_memory_types (GstVaapiFilter * filter) +{ + g_return_val_if_fail (filter != NULL, FALSE); + + if (!ensure_attributes (filter)) + return 0; + return filter->attribs->mem_types; +} + /** * gst_vaapi_filter_set_cropping_rectangle: * @filter: a #GstVaapiFilter diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h index 27533cbe9a..fcc968f076 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.h +++ b/gst-libs/gst/vaapi/gstvaapifilter.h @@ -219,6 +219,9 @@ 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); From 7a3b25884c0837cfbd8cd9bd72108fc77a5e6773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 9 Jul 2019 19:17:48 +0200 Subject: [PATCH 3717/3781] libs: egl: surface: export EGLImage as DMABuf if GEM not supported This code path is used when frames are rendered as textures through GstVideoGLTextureUploadMeta with EGL, mainly under Wayland. Originally the EGLImage was exported as GEM, which was handled by Intel drivers, but Gallium ones cannot create VA surfaces from GEM buffers, only DMABuf. This patch checks the memory types supported by VA driver to choose the render the EGLImages from GEM or DMABuf, because GEM is still better where supported. DMABuf is well handled either by intel-vaapi-driver and gallium. Fixes: #137 Part-of: --- gst-libs/gst/vaapi/egl_vtable.h | 21 ++++ gst-libs/gst/vaapi/gstvaapisurface_egl.c | 148 +++++++++++++++++------ gst-libs/gst/vaapi/gstvaapisurface_egl.h | 3 +- gst-libs/gst/vaapi/gstvaapitexture_egl.c | 14 ++- 4 files changed, 145 insertions(+), 41 deletions(-) diff --git a/gst-libs/gst/vaapi/egl_vtable.h b/gst-libs/gst/vaapi/egl_vtable.h index 89c5d029a0..53b3acc9fd 100644 --- a/gst-libs/gst/vaapi/egl_vtable.h +++ b/gst-libs/gst/vaapi/egl_vtable.h @@ -130,6 +130,26 @@ 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) @@ -137,6 +157,7 @@ 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() diff --git a/gst-libs/gst/vaapi/gstvaapisurface_egl.c b/gst-libs/gst/vaapi/gstvaapisurface_egl.c index f5aaa746d7..e311ae9bc9 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_egl.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_egl.c @@ -21,13 +21,23 @@ */ #include "sysdeps.h" + #include "gstvaapisurface_egl.h" -#include "gstvaapisurface_drm.h" -#include "gstvaapisurface_priv.h" -#include "gstvaapiimage_priv.h" + #include "gstvaapibufferproxy_priv.h" +#include "gstvaapicompat.h" #include "gstvaapidisplay_egl_priv.h" #include "gstvaapifilter.h" +#include "gstvaapiimage_priv.h" +#include "gstvaapisurface_drm.h" +#include "gstvaapisurface_priv.h" + +#if USE_DRM +#include +#else +#define DRM_FORMAT_MOD_LINEAR 0ULL +#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1) +#endif typedef struct { @@ -36,46 +46,102 @@ typedef struct GstVideoFormat format; guint width; guint height; + guint mem_types; GstVaapiSurface *surface; /* result */ } CreateSurfaceWithEGLImageArgs; static GstVaapiSurface * do_create_surface_with_egl_image_unlocked (GstVaapiDisplayEGL * display, - EGLImageKHR image, GstVideoFormat format, guint width, guint height) + EGLImageKHR image, GstVideoFormat format, guint width, guint height, + guint mem_types) { GstVaapiDisplay *const base_display = GST_VAAPI_DISPLAY_CAST (display); EglContext *const ctx = GST_VAAPI_DISPLAY_EGL_CONTEXT (display); EglVTable *vtable; - gsize size, offset[GST_VIDEO_MAX_PLANES]; - gint name, stride[GST_VIDEO_MAX_PLANES]; if (!ctx || !(vtable = egl_context_get_vtable (ctx, FALSE))) return NULL; - memset (offset, 0, sizeof (offset)); - memset (stride, 0, sizeof (stride)); + if ((mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM) + && vtable->has_EGL_MESA_drm_image) { + gsize size, offset[GST_VIDEO_MAX_PLANES] = { 0, }; + gint name, stride[GST_VIDEO_MAX_PLANES] = { 0, }; - if (!vtable->has_EGL_MESA_drm_image) - goto error_mission_extension; + /* EGL_MESA_drm_image extension */ + if (!vtable->eglExportDRMImageMESA (ctx->display->base.handle.p, image, + &name, NULL, &stride[0])) + goto error_export_image_gem_buf; - /* EGL_MESA_drm_image extension */ - if (!vtable->eglExportDRMImageMESA (ctx->display->base.handle.p, image, - &name, NULL, &stride[0])) - goto error_export_image_gem_buf; + size = height * stride[0]; + /* + * XXX: The below surface creation may fail on Intel due to: + * https://github.com/01org/intel-vaapi-driver/issues/222 + * A permanent fix for that problem will be released in intel-vaapi-driver + * version 1.8.4 and later, and also in 1.8.3-1ubuntu1. + * However if you don't have that fix then a simple workaround is to + * uncomment this line of code: + * size = GST_ROUND_UP_32 (height) * stride[0]; + */ - size = height * stride[0]; - /* - * XXX: The below surface creation may fail on Intel due to: - * https://github.com/01org/intel-vaapi-driver/issues/222 - * A permanent fix for that problem will be released in intel-vaapi-driver - * version 1.8.4 and later, and also in 1.8.3-1ubuntu1. - * However if you don't have that fix then a simple workaround is to - * uncomment this line of code: - * size = GST_ROUND_UP_32 (height) * stride[0]; - */ + return gst_vaapi_surface_new_with_gem_buf_handle (base_display, name, size, + format, width, height, offset, stride); + } - return gst_vaapi_surface_new_with_gem_buf_handle (base_display, name, size, - format, width, height, offset, stride); + if ((mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME) + && vtable->has_EGL_MESA_image_dma_buf_export) { + int fourcc, num_planes, fd; + EGLint offset = 0; + EGLint stride = 0; + EGLuint64KHR modifier; + GstVideoInfo vi; + + if (!vtable->eglExportDMABUFImageQueryMESA (ctx->display->base.handle.p, + image, &fourcc, &num_planes, &modifier)) + goto error_export_dma_buf_image_query; + + /* Don't allow multi-plane dmabufs */ + if (num_planes != 1) + goto error_bad_parameters; + + /* FIXME: We don't support modifiers */ + if (modifier != DRM_FORMAT_MOD_LINEAR && modifier != DRM_FORMAT_MOD_INVALID) + goto error_bad_parameters; + + /* fix color format if needed */ + if (fourcc == GST_MAKE_FOURCC ('A', 'B', '2', '4')) + format = gst_vaapi_video_format_from_va_fourcc (VA_FOURCC_RGBA); + else if (fourcc == GST_MAKE_FOURCC ('A', 'R', '2', '4')) + format = gst_vaapi_video_format_from_va_fourcc (VA_FOURCC_BGRA); + + if (!vtable->eglExportDMABUFImageMESA (ctx->display->base.handle.p, image, + &fd, &stride, &offset)) + goto error_export_dma_buf_image; + + gst_video_info_set_format (&vi, format, width, height); + GST_VIDEO_INFO_PLANE_OFFSET (&vi, 0) = offset; + GST_VIDEO_INFO_PLANE_STRIDE (&vi, 0) = stride; + + return gst_vaapi_surface_new_with_dma_buf_handle (base_display, fd, &vi); + } +#ifndef GST_DISABLE_GST_DEBUG + { + GString *str = g_string_new (NULL); + + if (mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_VA) + g_string_append (str, "VA "); + if (mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_V4L2) + g_string_append (str, "V4L2 "); + if (mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR) + g_string_append (str, "PTR "); + if (mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) + g_string_append (str, "PRIME_2 "); + + GST_ERROR ("missing EGL extensions for memory types: %s", str->str); + g_string_free (str, TRUE); + } +#endif + + return NULL; /* ERRORS */ error_export_image_gem_buf: @@ -83,10 +149,19 @@ error_export_image_gem_buf: GST_ERROR ("failed to export EGL image to GEM buffer"); return NULL; } - -error_mission_extension: +error_export_dma_buf_image_query: { - GST_ERROR ("missing EGL_MESA_drm_image extension"); + GST_ERROR ("failed to query EGL image for dmabuf export"); + return NULL; + } +error_bad_parameters: + { + GST_ERROR ("multi-planed nor non-linear dmabufs are not supported"); + return NULL; + } +error_export_dma_buf_image: + { + GST_ERROR ("missing EGL_MESA_image_dma_buf_export extension"); return NULL; } } @@ -96,17 +171,17 @@ do_create_surface_with_egl_image (CreateSurfaceWithEGLImageArgs * args) { GST_VAAPI_DISPLAY_LOCK (args->display); args->surface = do_create_surface_with_egl_image_unlocked (args->display, - args->image, args->format, args->width, args->height); + args->image, args->format, args->width, args->height, args->mem_types); GST_VAAPI_DISPLAY_UNLOCK (args->display); } // Creates VA surface with EGLImage buffer as backing storage (internal) static inline GstVaapiSurface * create_surface_with_egl_image (GstVaapiDisplayEGL * display, EGLImageKHR image, - GstVideoFormat format, guint width, guint height) + GstVideoFormat format, guint width, guint height, guint mem_types) { CreateSurfaceWithEGLImageArgs args = - { display, image, format, width, height }; + { display, image, format, width, height, mem_types }; if (!egl_context_run (GST_VAAPI_DISPLAY_EGL_CONTEXT (display), (EglContextRunFunc) do_create_surface_with_egl_image, &args)) @@ -127,7 +202,7 @@ create_surface_from_egl_image (GstVaapiDisplayEGL * display, GstVaapiFilterStatus filter_status; img_surface = create_surface_with_egl_image (display, image, format, - width, height); + width, height, 0); if (!img_surface) return NULL; @@ -240,6 +315,7 @@ error_invalid_display: * @format: the EGL @image format * @width: the EGL @image width in pixels * @height: the EGL @image height in pixels + * @mem_types: the supported memory types * * Creates a new #GstVaapiSurface bound to an external EGL image. * @@ -252,7 +328,8 @@ error_invalid_display: */ GstVaapiSurface * gst_vaapi_surface_new_with_egl_image (GstVaapiDisplay * base_display, - EGLImageKHR image, GstVideoFormat format, guint width, guint height) + EGLImageKHR image, GstVideoFormat format, guint width, guint height, + guint mem_types) { GstVaapiDisplayEGL *display; @@ -264,7 +341,8 @@ gst_vaapi_surface_new_with_egl_image (GstVaapiDisplay * base_display, display = GST_VAAPI_DISPLAY_EGL (base_display); if (!display || !GST_VAAPI_IS_DISPLAY_EGL (display)) goto error_invalid_display; - return create_surface_with_egl_image (display, image, format, width, height); + return create_surface_with_egl_image (display, image, format, width, height, + mem_types); /* ERRORS */ error_invalid_display: diff --git a/gst-libs/gst/vaapi/gstvaapisurface_egl.h b/gst-libs/gst/vaapi/gstvaapisurface_egl.h index 70c8df8b77..71cb150aff 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_egl.h +++ b/gst-libs/gst/vaapi/gstvaapisurface_egl.h @@ -36,7 +36,8 @@ gst_vaapi_surface_new_from_egl_image (GstVaapiDisplay * display, GstVaapiSurface * gst_vaapi_surface_new_with_egl_image (GstVaapiDisplay * display, - EGLImageKHR image, GstVideoFormat format, guint width, guint height); + EGLImageKHR image, GstVideoFormat format, guint width, guint height, + guint mem_types); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapitexture_egl.c b/gst-libs/gst/vaapi/gstvaapitexture_egl.c index f392bcefa0..49edcc883f 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_egl.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_egl.c @@ -80,6 +80,14 @@ create_objects (GstVaapiTexture * texture, GLuint texture_id) EglContext *const ctx = texture_egl->egl_context; EglVTable *const vtable = egl_context_get_vtable (ctx, FALSE); GLint attribs[3] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; + guint mem_types; + + texture_egl->filter = + gst_vaapi_filter_new (GST_VAAPI_TEXTURE_DISPLAY (texture)); + if (!texture_egl->filter) + goto error_create_filter; + + mem_types = gst_vaapi_filter_get_memory_types (texture_egl->filter); texture_egl->egl_image = vtable->eglCreateImageKHR (ctx->display->base.handle.p, @@ -91,14 +99,10 @@ create_objects (GstVaapiTexture * texture, GLuint texture_id) texture_egl->surface = gst_vaapi_surface_new_with_egl_image (GST_VAAPI_TEXTURE_DISPLAY (texture), texture_egl->egl_image, GST_VIDEO_FORMAT_RGBA, texture->width, - texture->height); + texture->height, mem_types); if (!texture_egl->surface) goto error_create_surface; - texture_egl->filter = - gst_vaapi_filter_new (GST_VAAPI_TEXTURE_DISPLAY (texture)); - if (!texture_egl->filter) - goto error_create_filter; return TRUE; /* ERRORS */ From ae6d4f3969d27848a45494eb3038119941117ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 14 Aug 2020 10:42:51 +0200 Subject: [PATCH 3718/3781] vaapiencode: h264: ignore level without breaking negotiation Since commit 9f627ef2 if the user sets level in the encoder src caps the caps negotiation is rejected. But since the same commit the same encoder set the autoconfigured level in caps. Some change in the base class might fixed the operation order so now the caps are set and later negotiated. This patch removes the level check. Fixes: #273 Part-of: --- gst/vaapi/gstvaapiencode_h264.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/gst/vaapi/gstvaapiencode_h264.c b/gst/vaapi/gstvaapiencode_h264.c index ccadbf23ae..d58faafa15 100644 --- a/gst/vaapi/gstvaapiencode_h264.c +++ b/gst/vaapi/gstvaapiencode_h264.c @@ -296,12 +296,7 @@ gst_vaapiencode_h264_set_config (GstVaapiEncode * base_encode) stream_format = gst_structure_get_string (structure, "stream-format"); encode->is_avc = (g_strcmp0 (stream_format, "avc") == 0); - if (gst_structure_has_field (structure, "level")) { - /* @TODO(victor): add a mechansim for user set a specific - * level */ - GST_WARNING_OBJECT (encode, "cannot set level configuration"); - ret = FALSE; - } else if (profile != GST_VAAPI_PROFILE_UNKNOWN) { + if (profile != GST_VAAPI_PROFILE_UNKNOWN) { GST_INFO ("using %s profile as target decoder constraints", gst_vaapi_utils_h264_get_profile_string (profile)); ret = gst_vaapi_encoder_h264_set_max_profile (encoder, profile); From 3540dcf4d98120c0596eabbec3025dfce322585a Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sun, 16 Aug 2020 01:57:15 +0800 Subject: [PATCH 3719/3781] plugin: allocator: No need to ref allocator when create mem. We do not need to ref the allocator when creating GstVaapiVideoMemory kind memory, and then release it in _free(). The framework already does it for us. Part-of: --- gst/vaapi/gstvaapivideomemory.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 48f42ab211..abf9715777 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -367,7 +367,7 @@ gst_vaapi_video_memory_new (GstAllocator * base_allocator, vip = &allocator->image_info; gst_memory_init (&mem->parent_instance, GST_MEMORY_FLAG_NO_SHARE, - gst_object_ref (allocator), NULL, GST_VIDEO_INFO_SIZE (vip), 0, + base_allocator, NULL, GST_VIDEO_INFO_SIZE (vip), 0, 0, GST_VIDEO_INFO_SIZE (vip)); mem->proxy = NULL; @@ -607,7 +607,6 @@ gst_vaapi_video_allocator_free (GstAllocator * allocator, GstMemory * base_mem) gst_vaapi_video_memory_reset_image (mem); gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); gst_vaapi_video_meta_replace (&mem->meta, NULL); - gst_object_unref (GST_MEMORY_CAST (mem)->allocator); g_mutex_clear (&mem->lock); g_slice_free (GstVaapiVideoMemory, mem); } From 5c21736903be91c713bc96ee337f884a70dbab93 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 17 Aug 2020 19:26:43 +0800 Subject: [PATCH 3720/3781] plugin: decode: Fix two mem leaks because of caps. Part-of: --- gst/vaapi/gstvaapidecode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b92edd1785..b777847c6a 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -292,7 +292,7 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) gst_caps_append (out_caps, dma_caps); if (gltexup_caps) gst_caps_append (out_caps, gltexup_caps); - gst_caps_append (out_caps, gst_caps_copy (raw_caps)); + gst_caps_append (out_caps, raw_caps); decode->allowed_srcpad_caps = out_caps; GST_INFO_OBJECT (decode, "allowed srcpad caps: %" GST_PTR_FORMAT, @@ -1360,6 +1360,7 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) decode->allowed_sinkpad_caps = gst_caps_intersect (allowed_sinkpad_caps, caps); gst_caps_unref (caps); + gst_caps_unref (allowed_sinkpad_caps); decode->allowed_sinkpad_caps = gst_caps_simplify (decode->allowed_sinkpad_caps); GST_DEBUG_OBJECT (decode, "allowed sink caps %" GST_PTR_FORMAT, From c080ee6dc97b4cf5769876fe92285e5308c4bdc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 17 Aug 2020 11:43:53 +0200 Subject: [PATCH 3721/3781] libs: surface: egl: guard memory type Part-of: --- gst-libs/gst/vaapi/gstvaapisurface_egl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapisurface_egl.c b/gst-libs/gst/vaapi/gstvaapisurface_egl.c index e311ae9bc9..362ac168c0 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface_egl.c +++ b/gst-libs/gst/vaapi/gstvaapisurface_egl.c @@ -133,8 +133,10 @@ do_create_surface_with_egl_image_unlocked (GstVaapiDisplayEGL * display, g_string_append (str, "V4L2 "); if (mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR) g_string_append (str, "PTR "); +#if VA_CHECK_VERSION(1,1,0) if (mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) g_string_append (str, "PRIME_2 "); +#endif GST_ERROR ("missing EGL extensions for memory types: %s", str->str); g_string_free (str, TRUE); From 0320e7a3b6cc755ea3c958b9fc5608aa00d4e8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 20 Aug 2020 16:16:25 +0100 Subject: [PATCH 3722/3781] Release 1.17.90 --- ChangeLog | 922 +++++++++++++++++++++++++++++++++++++++++++ NEWS | 49 +-- RELEASE | 2 +- gstreamer-vaapi.doap | 10 + meson.build | 2 +- 5 files changed, 943 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1eb35927bb..10306fcf64 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,925 @@ +=== release 1.17.90 === + +2020-08-20 16:16:25 +0100 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * RELEASE: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.17.90 + +2020-08-17 11:43:53 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapisurface_egl.c: + libs: surface: egl: guard memory type + Part-of: + +2020-08-17 19:26:43 +0800 He Junyan + + * gst/vaapi/gstvaapidecode.c: + plugin: decode: Fix two mem leaks because of caps. + Part-of: + +2020-08-16 01:57:15 +0800 He Junyan + + * gst/vaapi/gstvaapivideomemory.c: + plugin: allocator: No need to ref allocator when create mem. + We do not need to ref the allocator when creating GstVaapiVideoMemory + kind memory, and then release it in _free(). The framework already + does it for us. + Part-of: + +2020-08-14 10:42:51 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapiencode_h264.c: + vaapiencode: h264: ignore level without breaking negotiation + Since commit 9f627ef2 if the user sets level in the encoder src caps + the caps negotiation is rejected. + But since the same commit the same encoder set the autoconfigured + level in caps. Some change in the base class might fixed the operation + order so now the caps are set and later negotiated. + This patch removes the level check. + Fixes: #273 + Part-of: + +2019-07-09 19:17:48 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/egl_vtable.h: + * gst-libs/gst/vaapi/gstvaapisurface_egl.c: + * gst-libs/gst/vaapi/gstvaapisurface_egl.h: + * gst-libs/gst/vaapi/gstvaapitexture_egl.c: + libs: egl: surface: export EGLImage as DMABuf if GEM not supported + This code path is used when frames are rendered as textures through + GstVideoGLTextureUploadMeta with EGL, mainly under Wayland. + Originally the EGLImage was exported as GEM, which was handled by + Intel drivers, but Gallium ones cannot create VA surfaces from + GEM buffers, only DMABuf. + This patch checks the memory types supported by VA driver to choose + the render the EGLImages from GEM or DMABuf, because GEM is still + better where supported. + DMABuf is well handled either by intel-vaapi-driver and gallium. + Fixes: #137 + Part-of: + +2020-05-26 16:18:32 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapifilter.h: + libs: filter: gst_vaapi_filter_get_memory_types() + Part-of: + +2020-08-12 18:48:59 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapipluginbase.h: + plugins: remove gst_vaapi_plugin_base_get_allowed_srcpad_raw_caps() + Since nobody uses it, just remove it. + Thus extract_allowed_surface_formats() is refactored to attend only + gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps(). + Now a surface is created when the image chorma is different from the + previous one. And if the driver has the quirk, it outputs all the + supported image formats without trying them. + Part-of: + +2020-08-12 17:50:50 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: expose raw src caps with same chroma + The try-and-error approach for getting the possible image formats from + a surface has brought several problems in different drivers, from + crashes to drop in performance. + Instead of that we change the algorithm to determine the possible + image formats based in the surface chroma: only those available image + formats with same chroma are exposed as possible raw caps. + Do this is important to avoid performance degrading in raw sinks + which doesn't handle NV12 but it does YV12 or I420. + Part-of: + +2020-07-10 17:05:38 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + libs: util: h265: use common parser API to get vaapi profiles. + We can reuse H265 parser's API to recognize the correct profile and + then just need to convert them to VAAPI profiles. + Part-of: + +2020-08-07 16:41:49 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/meson.build: + * gst/vaapi/meson.build: + * meson.build: + build: update for gl pkg-config file split + Part-of: + +2020-08-06 12:51:27 +0800 Xu Guangxin + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + h264dec: mark remaining frames as unreference before exec_picture_refs_modification + 8.2.4.2 required this. Some clips will crash if we do not fill the reference list like this. + Part-of: + +2020-07-31 18:22:46 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + libs: encoder: H265: Enable Main 12 profile support. + Part-of: + +2020-07-31 19:17:39 +0800 He Junyan + + * gst-libs/gst/vaapi/video-format.c: + video format: Fix P012_LE's chrome type typo. + Part-of: + +2020-08-04 21:15:01 +0300 Jordan Petridis + + * gst-libs/gst/vaapi/gstvaapiminiobject.c: + gstvaapiminiobject.c: fix clang 10 warnings + the typesystem checks in g_atomic_pointer_compare_and_exchange + seem to trigger some false positives with clang 10 + similar to gstreamer!584 + Part-of: + +2020-07-31 11:07:23 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: window: wayland: destroy all wayland buffers during finalize + Some buffers and the associated FrameState state may still be pending at + that point. If the wayland connection is shared, then messages for the + buffer may still arrive. However, the associated event queue is already + deleted. So the result is a crash. + With a private connection the associated memory is leaked instead. + Part-of: + +2020-06-18 20:25:18 +0200 Michael Olbrich + + * tests/examples/test-vaapicontext.c: + test: vaapicontext: fix draw callback with multiple videos + The callback is called for both windows. So make sure that + gst_video_overlay_set_render_rectangle() is called for the correct one. + Otherwise, the left video will be randomly moved behind the right video. + Part-of: + +2020-06-19 09:23:52 +0200 Michael Olbrich + + * tests/examples/meson.build: + * tests/examples/test-vaapicontext.c: + test: vaapicontext: support wayland display + On Wayland, The whole gtk window is one Wayland surface. So + gtk_widget_get_window() must be called on the top-level widget. + For any other widget the following gdk_window_ensure_native() may create a + new top-level Wayland surface that is never visible. + As a result, the coordinates passed to + gst_video_overlay_set_render_rectangle() must be relativ to the top-level + window. Otherwise the video is placed incorrectly. + Original-Patch-By: Víctor Manuel Jáquez Leal + Part-of: + +2017-12-01 20:18:28 +0100 Víctor Manuel Jáquez Leal + + * tests/examples/test-vaapicontext.c: + test: vaapicontext: use playbin to test files + Part-of: + +2017-11-29 11:11:39 +0100 Víctor Manuel Jáquez Leal + + * tests/examples/test-vaapicontext.c: + test: vaapicontext: add PLAY and NULL buttons + They only appear when only one sink is instanciated and their purpose + is to test the NULL-PLAY use case in context sharing. + Part-of: + +2020-06-19 21:26:52 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: wayland: update the opaque region in set_render_rect + gst_vaapi_window_wayland_set_render_rect() may be called from an arbitrary + thread. That thread may be responsible for making the window visible. + At that point another thread will block in gst_vaapi_window_wayland_sync() + because the frame callback will not be called until the window is visible. + If that happens, then acquiring the display lock in + gst_vaapi_window_wayland_set_render_rect() would result in a deadlock. + Cache the size of the opaque rectangle separately and create the opaque + region right before applying it to the surface. + Part-of: + +2020-06-19 09:21:16 +0200 Hyunjun Ko + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow.h: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst/vaapi/gstvaapisink.c: + libs: window: implements gst_vaapi_window_set_render_rectangle + Implements new vmethod gst_vaapi_window_set_render_rectangle, + which is doing set the information of the rendered rectangle set by + user. + This is necessary on wayland at least to get exact information of + external surface. + And vaapisink calls this when gst_video_overlay_set_render_rectangle is + called. + Part-of: + +2017-11-08 13:23:39 +0900 Hyunjun Ko + + * gst/vaapi/gstvaapisink.c: + vaapisink: implements gst_vaapisink_wayland_create_window_from_handle() + Implements gst_vaapisink_wayland_create_window_from_handle() to support + using external wl_surface. + Part-of: + +2020-06-19 09:11:20 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.h: + libs: wayland: implement video overlay API + The Wayland sub-surfaces API is used to embed the video into an application + window. + See Appendix A. Wayland Protocol Specification as the following. + """ + The aim of sub-surfaces is to offload some of the compositing work + within a window from clients to the compositor. A prime example is + a video player with decorations and video in separate wl_surface + objects. + This should allow the compositor to pass YUV video buffer processing to + dedicated overlay hardware when possible. + """ + Added new method gst_vaapi_window_wayland_new_with_surface() + Original-Patch-By: Víctor Manuel Jáquez Leal + Zhao Halley + changzhix.wei@intel.com + Hyunjun Ko + Part-of: + +2020-06-19 21:54:52 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + doc: libs: wayland: add 'transfer full' to the returnvalye of gst_vaapi_window_wayland_new + Part-of: + +2020-06-11 08:25:57 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + libs: display: always call close_display() + All close_display() have their own checks for use_foreign_display and only + destroy locally created objects in that case. + Without this objects other than the actuall foreign display itself are + leaked. + Part-of: + +2020-07-30 23:37:10 +0800 He Junyan + + * gst-libs/gst/vaapi/video-format.h: + video-format: Add the missing P012_LE into GST_VAAPI_FORMATS_ALL. + Part-of: + +2020-05-25 17:02:26 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + plugins: add gst_vaapi_caps_set_width_and_height_range() + This utility function is called internally by + gst_vaapi_build_caps_from_formats() and can be used outside. + This function sets frame size and framerates ranges. + Also gst_vaapi_build_caps_from_formats() is simplified. + Part-of: + +2020-07-31 15:27:38 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + libs: decoder: fix a crash issue when get_surface_formats. + Some context does not report any valid format that we can support. + For example, the HEVC 444 12 bits decoder context, all the formats + it reports is not supported now, which make the formats list a NULL + array. We should check that pointer before we use it. + Part-of: + +2020-07-03 19:28:28 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: choose the profile based on allowed list. + We can decide the profile in ensure_profile(), based on allowed list + passed by the encode. We also need to check whether the entrypoint is + available. Once it is decided, no need to check the hw entrypoint + them again. + Part-of: + +2020-07-29 22:05:41 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_h265.c: + plugins: encode: h265: set all allowed profiles to encoder. + We should collect all allowed profiles and pass them to the inside + encoder, rather than just calculate the max profile idc. + The allowed profiles should also be supported by the HW. + Part-of: + +2020-07-29 22:32:55 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + libs: display: Add a helper function to get profiles by codec. + Part-of: + +2020-07-03 01:28:28 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_h265.c: + plugins: encode: h265: collect all allowed profiles to encoder. + We should collect all allowed profiles and pass them to the inside + encoder, rather than just calculate the max profile idc. + Part-of: + +2020-07-03 00:53:31 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.h: + * gst/vaapi/gstvaapiencode_h265.c: + libs: encoder: h265: modify set_max_profile to set_allowed_profiles. + In h265, bigger profile idc may not be compatible with the small profile + idc. And more important, there are multi profiles with the same profile + idc. Such as main-422-10, main-444 and main-444-10, they all have profile + idc 4. + So recording the max profile idc is not enough, the encoder needs to know + all allowed profiles when deciding the real profile. + Part-of: + +2020-07-02 23:33:31 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: No need to check hw_max_profile. + In h265, higher profile idc number does not mean better compression + performance and may be not compatible with the lower profile idc. + So, it is not suitable to find the heighest idc for hw to ensure the + compatibility. + On the other side, when the entrypoint of the selected profile is valid, + it means the hw really support this profile, no need to check it again. + Part-of: + +2020-04-08 19:41:09 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipostproc.c: + vaapipostproc: early return if fixate srcpad caps fails + Part-of: + +2020-07-29 13:39:44 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginutil.c: + vaapipluginutil: simplify gst_vaapi_find_preferred_caps_feature() + Generalize the way how the preferred color format is chosen. Also + use new GStreamre API as syntatic sugar. + Part-of: + +2020-07-29 14:22:18 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapiencode.c: + libs: profile: Use get_codec_from_caps to get codec type. + There is no need to get a profile from the caps and then convert + that profile into codec type. We can get the codec type by caps's + name easily. + Part-of: + +2020-07-12 19:42:40 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + libs: profile: h265: Fix return value of from_codec_data_h265. + profile_from_codec_data_h265() returns wrong GstVaapiProfile for h265. + The codec data of caps contain the profile IDC, but the mapping between + profile IDC and GstVaapiProfile is wrong. + Part-of: + +2020-07-07 00:46:23 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_vp9.c: + plugins: encode: vp9: Implement vp9's allowed_profiles() func. + Part-of: + +2020-07-08 16:30:17 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + plugin: util: rename h26x_encoder_get_profiles_from_caps(). + Change its name to encoder_get_profiles_from_caps(). Other codecs such + as VP9 also needs to use this function. + Part-of: + +2020-07-06 23:35:12 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils_vpx.c: + * gst-libs/gst/vaapi/gstvaapiutils_vpx.h: + * gst-libs/gst/vaapi/meson.build: + libs: utils: vpx: Add utils vpx to handle VP8/9 misc things. + Part-of: + +2020-07-29 10:17:31 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + libs: display, context: handle broken jpeg decoder for i965 driver + JPEG decoding in i965 driver is pretty much broken, and the driver is + deprecated which mean authors only accept trivial fixes. + Surfaces for JPEG decoder context in i965 only handle IMC3[1] color + format which is not a common format in GStreamer. It can export it to + I420 at mapping raw bytes, but DMABuf exporting is problematic. + This patch artificially adds NV12 to the context format list when it's + JPEG decoder for i965 and force the usage of old VA-API for surface + creation without specifying color format. Also it artificially + disables the DMABuf announcement. + 1. https://docs.microsoft.com/en-us/windows/win32/medfound/recommended-8-bit-yuv-formats-for-video-rendering#420-formats-16-bits-per-pixel + Part-of: + +2020-07-29 12:02:50 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapicontext.c: + libs: context: change function to internal code style + Instead of a getter the function `get_preferred_format()` to + `ensure_preferred_format()` which aligns to the code style. + Part-of: + +2020-07-28 20:00:09 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: always merge profile caps in sink caps + This commit fixes a regression of e962069d, where if the profile's + caps doesn't have a caps profile, it's ignored. + This patch add a conditional jump if the caps doesn't have a profile + field to merge it. + Fixes: #271 + Part-of: + +2020-07-28 12:22:40 +0200 Víctor Manuel Jáquez Leal + + * meson.build: + build: request libdrm >= 2.4.98 and fallback + Fixes: #270 + Part-of: + +2020-05-18 17:32:27 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: dma caps only use reported color format + This fix pipelines without vaapipostproc after vaapi decoder, such as + gst-launch-1.0 filesrc location=~/file.mp4 ! parsebin ! vaapih264dec ! glimagesink + On EGL platforms, so DMABuf is used. + Part-of: + +2020-02-07 17:10:45 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: use allowed srcpad caps for caps query + Instead of using just the template caps use the current allowed + srcpad caps, which is created considering the current decoder + context. + Part-of: + +2020-01-22 17:41:28 +0100 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst/vaapi/gstvaapidecode.c: + vaapidecode: build allowed srcpad caps from va context + Instead of generating allowed srcpad caps with generic information, + now it takes the size an formats limits from the decoder's context. + This is possible since srcpad caps are generated after the internal + decoder is created. + The patch replaces gst_vaapi_decoder_get_surface_formats() with + gst_vaapi_decoder_get_suface_attributes(). + From these attributes, formats are only used for VASurface memory + caps feature. For system memory caps feature, the old + gst_vaapi_plugin_get_allowed_srcpad_caps() is still used, since + i965 jpeg decoder cannot deliver mappable format for gstreamer. + And for the other caps features (dmabuf and texture upload) the + same static list are used. + This patch also adds DMABuf caps feature only if the context + supports that memory type. Nonetheless, we keep the pre-defined + formats since they are the subset of common derive formats formats + supported either by amd/gallium and both intel drivers, since, + when exporting the fd through vaAcquireBufferHandle()/ + vaReleaseBufferHandle(), the formats of the derivable image cannot + be retriebable from the driver. Later we'll use the attribute + formats for the DMABuf feature too, when the code be ported to + vaExportSurfaceHandle(). + Finally, the allowed srcpad caps are removed if the internal decoder + is destroyed, since context attribues will change. + Part-of: + +2020-02-07 16:50:52 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + vaapidecode: reorder src caps template + Since negotiation depends on caps order, first is VA, then DMABuf, + later GLUploadTexture (deprecated) and finally raw. + Also, for decoders, the possible available color formats for DMABuf + is extended to all the possible VA color formats. + Part-of: + +2020-07-22 10:01:41 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: window: wayland: use dmabuf protocol if available + Currently vaGetSurfaceBufferWl() is used to create wayland buffers. + Unfortunately this is not implemented by the 'media-driver' and Mesa VA-API + drivers. And the implementation provided by 'intel-vaapi-driver' is not + compatible with a Wayland server that uses the iris Mesa driver. + So create the Wayland buffers manually with the zwp_linux_dmabuf_v1 wayland + protocol. Formats and modifiers supported by the Wayland server are taken + into account. If necessary, VPP is enabled to convert the buffer into a + supported format. + Fall back to vaGetSurfaceBufferWl() if creating buffers via dambuf protocol + fails. + Part-of: + +2020-07-21 10:03:19 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapiwindow.c: + * gst-libs/gst/vaapi/gstvaapiwindow_priv.h: + libs: window: allow choosing the format for the vpp pool + Signed-off-by: Michael Olbrich + Part-of: + +2020-06-28 17:42:29 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + video-format: add DRM formats to the mapping table + This will be needed for the DMABuf protocol support to map DRM formats to + vaapi and gstreamer formats. + Part-of: + +2020-07-22 09:36:18 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapidisplay_wayland.c: + * gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h: + * gst-libs/gst/vaapi/meson.build: + libs: display: wayland: add basic dmabuf protocol support + This is just the basic infrastructure. Hook up the interface and collect + all supported formats. + Part-of: + +2020-07-06 09:59:40 +0200 Michael Olbrich + + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + libs: window: wayland: wait for configure before committing the first buffer + Committing the first buffer for a surface must not be done before + ack_configure() has been sent for the xdg_surface. + With weston, the commit will fail with "error 3: xdg_surface has never been + configured". + Wait in gst_vaapi_window_wayland_show() until configure is done to avoid + this. + Part-of: + +2020-07-01 14:50:51 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: set no P frame automatically. + The double reference lists may be required by drivers and there should + be no P frames in the of stream. The old way of converting P frames to + B frames is by setting `low-delay-b` property, which is unconvenient + and has bad user experience, since most of the users do not know when + to set this property, and if it is not set correctly, the encoding + pipeline fails or even hangs on some platforms. VA driver now provides + a attribute to query whether both reference lists must be un-NULL for + a profile/entrypoint pair. + Part-of: + +2020-04-15 16:26:55 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: Deprecate the low-delay-b property. + In HEVC, P and B definitions are different from AVC: P frames have + just one reference list and so 1 MV, while B frames have two reference + lists and so 2 MVs. No matter B or P, ist reference lists can contain + forward/backward reference. So P and B can both have bi-directions + dependency, the difference is just their reference list + number (i.e. MV number). This is different from the AVC. + The *low delay b mode* refers to a special HEVC mode, in which the + stream just contain I and B frames, without P frames, and all B frames + only have forward direction dependencies (i.e. all inter frames have 2 + reference lists but no backward reference in both lists). This is + similar to AVC I/P mode, but changing the P to the forward dependent + B. + The `low-delay-b` property is now just used to simply convert all P + frames to B frames when driver does not support P frames (so both + reference lists have the same references frames). This is a little + different from the meaning of low delay b mode (the two ref lists may + have the different reference frames). And the driver now can report + whether it supports P frames correctly, so there is no need to use + this property and deprecate it. + Part-of: + +2020-07-24 12:54:31 +0200 Marc Leeman + + * gst/vaapi/gstvaapipostproc.c: + postproc: reconfigure after changing cropping values + Part-of: + +2020-07-09 13:49:29 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiencode_vp9.c: + plugin: encode: Add static caps for template documentation. + Part-of: + +2020-07-08 19:03:14 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_vp9.c: + plugin: encode: vp9: Use the dynamically built src template caps. + Part-of: + +2020-07-08 19:02:45 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_vp8.c: + plugin: encode: vp8: Use the dynamically built src template caps. + Part-of: + +2020-07-08 19:02:23 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_jpeg.c: + plugin: encode: jpeg: Use the dynamically built src template caps. + Part-of: + +2020-07-08 19:00:39 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_mpeg2.c: + plugin: encode: mpeg2: Use the dynamically built src template caps. + Part-of: + +2020-07-08 18:59:18 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_h265.c: + plugin: encode: h265: Use the dynamically built src template caps. + Part-of: + +2020-07-08 18:57:26 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_h264.c: + plugin: encode: h264: Use the dynamically built src template caps. + Part-of: + +2020-07-08 18:46:58 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapiencode_h264.c: + * gst/vaapi/gstvaapiencode_h265.c: + * gst/vaapi/gstvaapiencode_jpeg.c: + * gst/vaapi/gstvaapiencode_mpeg2.c: + * gst/vaapi/gstvaapiencode_vp8.c: + * gst/vaapi/gstvaapiencode_vp9.c: + plugin: encode: Store the coded caps in type's init data. + Part-of: + +2020-07-08 18:30:00 +0800 He Junyan + + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + plugin: util: add helper function build_template_coded_caps_by_codec() + Like build_template_raw_caps_by_codec(), this function can detect and + build the caps for specified codec based on the query of the profiles. + The result is coded caps such as video/x-h265, video/x-h264. The result + can be used as the template of encode's src or decode's sink. + Part-of: + +2020-07-07 17:16:41 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.h: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + plugins: utils: rename build_template_caps_by_codec. + Rename the function build_template_caps_by_codec() to the name of + build_template_raw_caps_by_codec(). It can be used to collect all + raw video formats for encode's sink and decode's src. + Part-of: + +2020-07-21 20:14:57 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapipluginutil.c: + * gst/vaapi/gstvaapipluginutil.h: + vaapidecode: merge common profiles before setting size range + The synthetic profiles, such as H264 baseline, H265 intra, etc. are + added at the end of processing all available VA profiles. This + generated an non-optimal caps for negotiation, since the synthetic + profiles don't have frame size ranges. + This patch adds those possible synthetic profiles when the associated + profile is processed, with its frame size ranges. + Now allowed sink caps are simpler. + Part-of: + +2020-07-21 22:05:08 +0800 He Junyan + + * gst/vaapi/gstvaapipluginutil.c: + plugin: util: Add the missing DMA buffer input in template caps. + We pass the wrong parameter to gst_vaapi_build_caps_from_formats() + and lose the DMA feature in caps. + Part-of: + +2020-07-14 18:13:56 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/video-format.c: + * gst/vaapi/gstvaapidecode.c: + libs: decoder: H265: Add MAIN_12 profile supporting. + Part-of: + +2020-07-09 23:07:38 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/video-format.c: + video-format: Add P012_LE format. + It can be used as HEVC YUV_4:2:0 12bits stream's decoder output, and + also can be used as the input format for encoding HEVC YUV_4:2:0 12bits + stream. + Part-of: + +2020-07-17 00:45:53 +0800 He Junyan + + * gst/vaapi/gstvaapidecode.c: + plugin: decode: correct ensure_allowed_sinkpad_caps's caps. + The decode allowed caps returned by ensure_allowed_sinkpad_caps() + contains all profiles of the whole VAAPI, like: + image/jpeg, width=(int)[ 0, 1638 4 ], height=(int)[ 0, 16384 ]; + video/mpeg, mpegversion=(int)2, profile=(string){ simple, main }, + width=(int)[ 0, 2048 ], height=(int)[ 0, 2048 ]; video/x-h264, + profile=(string){ main, high, constrained-baseline }, width=(int)[ 0, + 4096 ], height=(int)[ 0, 4096 ]; video/x-h264, profile=(string){ + constrained-high, progressive-high, baseline }; video/x-h265, + profile=(string){ main, main-intra }, width=(int)[ 0, 8192 ], + height=(int)[ 0, 8192 ]; video/x-vp8, width=(int)[ 0, 4096 ], + height=(int)[ 0, 4096 ]; video/x-wmv, wmvversion=(int)3, + format=(string)WVC1, profile=(string)advanced, width=(int)[ 0, 3840 ], + height=(int)[ 0, 3840 ]; video/x-wmv, wmvversion=(int)3, + profile=(string){ simple, main }, width=(int)[ 0, 3840 ], + height=(int)[ 0, 3840 ] + Which is verbose and may have latent problems. It should only contains + the profiles belong to its codec type. For example, h265 should only + return: + video/x-h265, profile=(string){ main, main-intra }, + width=(int)[ 0, 8192 ], height=(int)[ 0, 8192 ] + Part-of: + +2020-07-13 11:06:18 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + vaapidecodebin: don't force NV12 since P010_10LE is now possible + Part-of: + +2020-07-12 20:34:31 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiprofile.c: + libs: profile: The VP9 profiles' name should be just "0,1,2,3" + Part-of: + +2020-07-08 17:33:32 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder.c: + * gst-libs/gst/vaapi/gstvaapidecoder.h: + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + * tests/internal/simple-decoder.c: + vaapidecode: Remove NO_SURFACE error handling + Since surfaces are not bounded to decoding context it makes no sense + to keep the surface semaphore. This patch removes the handling of + this error. + Part-of: + +2020-07-08 17:48:57 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + * gst/vaapi/gstvaapidecode.h: + Revert "vaapidecode: drop non-keyframe in reverse playback" + Since the number of surfaces are not bounded to decoder context, + this hack is no longer needed. + This reverts commit 19c0c8a97385ce119440c4aad2d689fc79297435. + Part-of: + +2019-12-06 14:21:33 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapicontext.c: + libs: decoder: context: remove surfaces binding from context. + The vaCreateContext do not need to specify the surfaces for the + context creation now. So we do not need to bind any surface to the + context anymore. Surfaces should be the resource belong to display + and just be used in encoder/decoder context. + The previous manner has big limitation for decoder. The context's + surface number is decided by dpb size. All the surfaces in dpb will + be attached to a gstbuffer and be pushed to down stream, and the + decoder need to wait down stream free the surface and go on if not + enough surface available. For more and more use cases, this causes + deadlock. For example, + gst-launch-1.0 filesrc location=a.h264 ! h264parse ! vaapih264dec + ! x264enc ! filesink location=./output.h264 + will cause deadlock and make the whole pipeline hang. + the x264enc encoder need to cache more than dpb size surfaces. + The best solution is seperating the surfaces number and the dpb size. + dpb and dpb size shoule be virtual concepts maintained by the decoder. + And let the surfaces_pool in context maintain the re-use of all surfaces. + For encoder, the situation is better, all the surfaces are just used + as reference frame and no need to be pushed to down stream. We can + just reserve and set the capacity of the surfaces_pool to meet the + request. + Fix: #147 + Fix: #88 + Co-Author: Víctor Manuel Jáquez Leal + Part-of: + +2020-07-08 17:50:51 +0100 Tim-Philipp Müller + + * meson.build: + * scripts/extract-release-date-from-doap-file.py: + meson: set release date from .doap file for releases + Part-of: + +2020-07-08 11:57:52 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapipluginbase.c: + plugins: use VA allocator by default on raw caps + Instead of using dmabuf allocator in source pad, when raw video caps + are negotiated, it uses VA allocator as before, since it is stable + in more use cases, for example transcoding, and more backend drivers. + Dmabuf allocator is only used when dmabuf caps feature is negotiated. + Part-of: + +2020-06-06 18:47:35 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + vaapisink: rank it as secondary + iHD doesn't provide a full implemention for rendering surfaces and + i965 has problems in wayland. And I suspect this path is followed + by other driver implementations. + This patch demotes the rank of vaapisink to secondary, so it will + not be autoplugged avoiding bad experience of users. + Part-of: + +2020-06-19 10:44:50 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h264, h265: in context at least 16 reference surfaces + Registering only stream's DBP size number of surfaces for decoding VA + surfaces brings issues for certain streams. This change register all + possible number of reference surfaces in a stream, which is 16. + Fixes: #94 + +2020-07-04 21:21:57 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_h265.c: + plugins: encode: h265: Add profile,level,tier to output caps. + Part-of: + +2020-07-04 21:08:20 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: init tier to GST_VAAPI_TIER_H265_UNKNOWN. + Part-of: + +2020-07-04 21:05:49 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: fix a bug to get get_profile_tier_level. + 0 is a valid value for h265 tier. + Part-of: + +2020-07-02 19:19:35 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + libs: encoder: h265: no need to check the high compression tune. + The h265 encoder just support tune mode: + (0): none - None + (3): low-power - Low power mode + So, no need to check and set the high compression parameters. + And by the way, the current ensure_tuning_high_compression manner + of choosing the hightest profile idc as the best compression profile + is not correct. Unlike h264, in h265 the higher profile idc number + does not mean it has more compression tools, and so it has better + compression performance. It may even be un-compatible with the lower + profile idc. For example, the SCREEN_CONTENT_CODING profile with idc + 9 is not compatible with 3D_MAIN profile with idc 8. + Part-of: + +2020-07-03 02:04:14 +0100 Tim-Philipp Müller + + * meson.build: + Back to development + === release 1.17.2 === 2020-07-03 00:36:40 +0100 Tim-Philipp Müller diff --git a/NEWS b/NEWS index 39b682a8c8..c216f07fea 100644 --- a/NEWS +++ b/NEWS @@ -1,22 +1,14 @@ +GStreamer 1.18 Release Notes - -GSTREAMER 1.18 RELEASE NOTES - - -THESE RELEASE NOTES ARE A PLACEHOLDER, PLEASE BEAR WITH US WHILE WE -FINISH WRITING UP THE REAL THING. +These release notes are a placeholder, please bear with us while we +finish writing up the real thing. GStreamer 1.18.0 has not yet been released. It is scheduled for release -in summer 2020 now. +in late August / early September 2020. 1.17.x is the unstable development series that is currently being developed in the git master branch and which will eventually result in -1.18, and 1.17.2 is the current development release in that series. - -The schedule for the 1.18 development cycle is yet to be confirmed, but -it is expected that feature freeze will be in June/July 2020, followed -by several 1.17 pre-releases and then a new 1.18 stable release in -July/August 2020. +1.18, and 1.17.90 is the current 1.18 pre-release in that series. 1.18 will be backwards-compatible to the stable 1.16, 1.14, 1.12, 1.10, 1.8, 1.6, 1.4, 1.2 and 1.0 release series. @@ -24,8 +16,7 @@ July/August 2020. See https://gstreamer.freedesktop.org/releases/1.18/ for the latest version of this document. -_Last updated: Wednesday 1 July 2020, 23:50 UTC (log)_ - +Last updated: Wednesday 20 August 2020, 11:00 UTC (log) Introduction @@ -36,12 +27,10 @@ framework! As always, this release is again packed with many new features, bug fixes and other improvements. - Highlights - FIXME - Major new features and changes Noteworthy new API @@ -66,12 +55,10 @@ The following plugins have been removed from gst-plugins-bad: - FIXME - Miscellaneous API additions - FIXME - Miscellaneous performance and memory optimisations As always there have been many performance and memory usage improvements @@ -88,7 +75,6 @@ GstPlayer - FIXME - Miscellaneous changes - FIXME @@ -97,62 +83,50 @@ OpenGL integration - FIXME - Tracing framework and debugging improvements - FIXME - Tools - FIXME - GStreamer RTSP server - FIXME - GStreamer VAAPI - FIXME - GStreamer OMX - FIXME - GStreamer Editing Services and NLE - FIXME - GStreamer validate - FIXME - GStreamer Python Bindings - FIXME - GStreamer C# Bindings - FIXME - GStreamer Rust Bindings - FIXME - GStreamer Rust Plugins - FIXME - Build and Dependencies - The Autotools build system has finally been removed in favour of the @@ -177,7 +151,6 @@ Cerbero has seen a number of improvements: - FIXME - Platform-specific changes and improvements Android @@ -194,7 +167,6 @@ Windows - FIXME - Contributors - FIXME @@ -202,7 +174,6 @@ Contributors … and many others who have contributed bug reports, translations, sent suggestions or helped testing. - Stable 1.18 branch After the 1.18.0 release there will be several 1.18.x bug-fix releases @@ -215,12 +186,10 @@ the git 1.18 branch, which will be a stable branch. 1.18.0 has not been released yet. - Known Issues - FIXME - Schedule for 1.20 Our next major feature release will be 1.20, and 1.19 will be the @@ -234,7 +203,7 @@ The plan for the 1.20 development cycle is yet to be confirmed. ------------------------------------------------------------------------ -_These release notes have been prepared by Tim-Philipp Müller with_ -_contributions from … (FIXME)_ +These release notes have been prepared by Tim-Philipp Müller with +contributions from … (FIXME) -_License: CC BY-SA 4.0_ +License: CC BY-SA 4.0 diff --git a/RELEASE b/RELEASE index e5146b3234..baefb99fe5 100644 --- a/RELEASE +++ b/RELEASE @@ -1,4 +1,4 @@ -This is GStreamer gstreamer-vaapi 1.17.2. +This is GStreamer gstreamer-vaapi 1.17.90. GStreamer 1.17 is the development branch leading up to the next major stable version which will be 1.18. diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 8994d0cec4..6ead4e4113 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.17.90 + master + + 2020-08-20 + + + + 1.17.2 diff --git a/meson.build b/meson.build index ae916ef8a8..b4351707c3 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.17.2.1', + version : '1.17.90', meson_version : '>= 0.48.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From f822366f92fa7c95ac18af37072a122673846277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 22 Aug 2020 12:53:12 +0200 Subject: [PATCH 3723/3781] Revert "libs: decoder: h264, h265: in context at least 16 reference surfaces" This reverts commit b387081a4d77d3da202da72686ab40fb9c83ee1e as discussed in https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/commit/b387081a4d77d3da202da72686ab40fb9c83ee1e --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 2 +- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index fd57a3f0b4..8c3b9b09bd 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -1623,7 +1623,7 @@ ensure_context (GstVaapiDecoderH264 * decoder, GstH264SPS * sps) info.chroma_type = priv->chroma_type; info.width = sps->width; info.height = sps->height; - info.ref_frames = 16; + info.ref_frames = dpb_size; if (!gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index dc81c6accc..6ec0f5ca0a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1202,7 +1202,7 @@ ensure_context (GstVaapiDecoderH265 * decoder, GstH265SPS * sps) info.chroma_type = priv->chroma_type; info.width = sps->width; info.height = sps->height; - info.ref_frames = 16; + info.ref_frames = dpb_size; if (!gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info)) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; From 69fbe8c84c9d8351a75e25c096e13381bb4edbbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 7 Sep 2020 12:15:43 +0300 Subject: [PATCH 3724/3781] Update for gst_video_transfer_function_*() function renaming Part-of: --- gst-libs/gst/vaapi/gstvaapifilter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index 9af76831c2..e3be777ad5 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1622,7 +1622,7 @@ fill_color_standard (GstVideoColorimetry * colorimetry, properties->colour_primaries = gst_video_color_primaries_to_iso (colorimetry->primaries); properties->transfer_characteristics = - gst_video_color_transfer_to_iso (colorimetry->transfer); + gst_video_transfer_function_to_iso (colorimetry->transfer); properties->matrix_coefficients = gst_video_color_matrix_to_iso (colorimetry->matrix); From de6fb60929252d6ee066aa06e25302a3f4a9856e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 8 Sep 2020 00:09:51 +0100 Subject: [PATCH 3725/3781] Release 1.18.0 --- .gitlab-ci.yml | 2 +- ChangeLog | 25 + NEWS | 2117 ++++++++++++++++++++++++++++++++++++++++-- RELEASE | 13 +- gstreamer-vaapi.doap | 10 + meson.build | 2 +- 6 files changed, 2101 insertions(+), 68 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c61aa7a529..944ad035e4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1 +1 @@ -include: "https://gitlab.freedesktop.org/gstreamer/gst-ci/raw/master/gitlab/ci_template.yml" +include: "https://gitlab.freedesktop.org/gstreamer/gst-ci/raw/1.18/gitlab/ci_template.yml" diff --git a/ChangeLog b/ChangeLog index 10306fcf64..8eab5c1a49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +=== release 1.18.0 === + +2020-09-08 00:09:51 +0100 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * RELEASE: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.18.0 + +2020-09-07 12:15:43 +0300 Sebastian Dröge + + * gst-libs/gst/vaapi/gstvaapifilter.c: + Update for gst_video_transfer_function_*() function renaming + Part-of: + +2020-08-22 12:53:12 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + Revert "libs: decoder: h264, h265: in context at least 16 reference surfaces" + This reverts commit b387081a4d77d3da202da72686ab40fb9c83ee1e as discussed in + https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/commit/b387081a4d77d3da202da72686ab40fb9c83ee1e + === release 1.17.90 === 2020-08-20 16:16:25 +0100 Tim-Philipp Müller diff --git a/NEWS b/NEWS index c216f07fea..dba9c7c471 100644 --- a/NEWS +++ b/NEWS @@ -1,22 +1,11 @@ GStreamer 1.18 Release Notes -These release notes are a placeholder, please bear with us while we -finish writing up the real thing. - -GStreamer 1.18.0 has not yet been released. It is scheduled for release -in late August / early September 2020. - -1.17.x is the unstable development series that is currently being -developed in the git master branch and which will eventually result in -1.18, and 1.17.90 is the current 1.18 pre-release in that series. - -1.18 will be backwards-compatible to the stable 1.16, 1.14, 1.12, 1.10, -1.8, 1.6, 1.4, 1.2 and 1.0 release series. +GStreamer 1.18.0 was originally released on 7 September 2020. See https://gstreamer.freedesktop.org/releases/1.18/ for the latest version of this document. -Last updated: Wednesday 20 August 2020, 11:00 UTC (log) +Last updated: Monday 7 September 2020, 10:30 UTC (log) Introduction @@ -29,37 +18,1052 @@ fixes and other improvements. Highlights -- FIXME +- GstTranscoder: new high level API for applications to transcode + media files from one format to another + +- High Dynamic Range (HDR) video information representation and + signalling enhancements + +- Instant playback rate change support + +- Active Format Description (AFD) and Bar Data support + +- ONVIF trick modes support in both GStreamer RTSP server and client + +- Hardware-accelerated video decoding on Windows via DXVA2 / + Direct3D11 + +- Microsoft Media Foundation plugin for video capture and + hardware-accelerated video encoding on Windows + +- qmlgloverlay: New overlay element that renders a QtQuick scene over + the top of an input video stream + +- New imagesequencesrc element to easily create a video stream from a + sequence of jpeg or png images + +- dashsink: Add new sink to produce DASH content + +- dvbsubenc: DVB Subtitle encoder element + +- TV broadcast compliant MPEG-TS muxing with constant bitrate muxing + and SCTE-35 support + +- rtmp2: new RTMP client source and sink element implementation + +- svthevcenc: new SVT-HEVC-based H.265 video encoder + +- vaapioverlay compositor element using VA-API + +- rtpmanager support for Google’s Transport-Wide Congestion Control + (twcc) RTP extension + +- splitmuxsink and splitmuxsrc gained support for auxiliary video + streams + +- webrtcbin now contains some initial support for renegotiation + involving stream addition and removal + +- New RTP source and sink elements to easily set up RTP streaming via + rtp:// URIs + +- New Audio Video Transport Protocol (AVTP) plugin for Time-Sensitive + Applications + +- Support for the Video Services Forum’s Reliable Internet Stream + Transport (RIST) TR-06-1 Simple Profile + +- Universal Windows Platform (UWP) support + +- rpicamsrc element for capturing from the Raspberry Pi camera + +- RTSP Server TCP interleaved backpressure handling improvements as + well as support for Scale/Speed headers + +- GStreamer Editing Services gained support for nested timelines, + per-clip speed rate control and the OpenTimelineIO format. + +- Autotools build system has been removed in favour of Meson Major new features and changes -Noteworthy new API +Noteworthy new features and API -- FIXME +Instant playback rate changes -New Elements +Changing the playback rate as quickly as possible so far always required +a flushing seek. This generally works, but has the disadvantage of +flushing all data from the playback pipeline and requiring the demuxer +or parser to do a full-blown seek including resetting its internal state +and resetting the position of the data source. It might also require +considerable decoding effort to get to the right position to resume +playback from at the higher rate. -- FIXME +This release adds a new mechanism to achieve quasi-instant rate changes +in certain playback pipelines without interrupting the flow of data in +the pipeline. This is activated by sending a seek with the +GST_SEEK_FLAG_INSTANT_RATE_CHANGE flag and start_type = stop_type = +GST_SEEK_TYPE_NONE. This flag does not work for all pipelines, in which +case it is necessary to fall back to sending a full flushing seek to +change the playback rate. When using this flag, the seek event is only +allowed to change the current rate and can modify the trickmode flags +(e.g. keyframe only or not), but it is not possible to change the +current playback position, playback direction or do a flush. + +This is particularly useful for streaming use cases like HLS or DASH +where the streaming download should not be interrupted when changing +rate. + +Instant rate changing is handled in the pipeline in a specific sequence +which is detailed in the seeking design docs. Most elements don’t need +to worry about this, only elements that sync to the clock need some +special handling which is implemented in the GstBaseSink base class, so +should be taken care of automatically in most normal playback pipelines +and sink elements. + +See Jan’s GStreamer Conference 2019 talk “Changing Playback Rate +Instantly” for more information. + +You can try this feature by passing the -i command line option to +gst-play-1.0. It is supported at least by qtdemux, tsdemux, hlsdemux, +and dashdemux. + +Google Transport-Wide Congestion Control + +rtpmanager now supports the parsing and generating of RTCP messages for +the Google Transport-Wide Congestion Control RTP Extension, as described +in: +https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01. + +This “just” provides the required plumbing/infrastructure, it does not +actually make effect any actual congestion control on the sender side, +but rather provides information for applications to use to make such +decisions. + +See Håvard’s “Google Transport-Wide Congestion Control” talk for more +information about this feature. + +GstTranscoder: a new high-level transcoding API for applications + +The new GstTranscoder library, along with transcodebin and +uritranscodebin elements, provides high level API for applications to +transcode media files from one format to another. Watch Thibault’s talk +“GstTranscoder: A High Level API to Quickly Implement Transcoding +Capabilities in your Applications” for more information. + +This also comes with a gst-transcoder-1.0 command line utility to +transcode one URI into another URI based on the specified encoding +profile. + +Active Format Description (AFD) and Bar Data support + +The GstVideo Ancillary Data API has gained support for Active Format +Description (AFD) and Bar data. + +This includes various two new buffer metas: GstVideoAFDMeta and +GstVideoBarMeta. + +GStreamer now also parses and extracts AFD/Bar data in the h264/h265 +video parsers, and supports both capturing them and outputting them in +the decklink elements. See Aaron’s lightning talk at the GStreamer +Conference for more background. + +ONVIF trick modes support in both GStreamer RTSP server and client + +- Support for the various trick modes described in section 6 of the + ONVIF streaming spec has been implemented in both gst-rtsp-server + and rtspsrc. +- Various new properties in rtspsrc must be set to take advantage of + the ONVIF support +- Examples are available here: test-onvif-server.c and + test-onvif-client.c +- Watch Mathieu Duponchelle’s talk “Implementing a Trickmode Player + with ONVIF, RTSP and GStreamer” for more information and a live + demo. + +GStreamer Codecs library with decoder base classes + +This introduces a new library in gst-plugins-bad which contains a set of +base classes that handle bitstream parsing and state tracking for the +purpose of decoding different codecs. Currently H264, H265, VP8 and VP9 +are supported. These bases classes are meant primarily for internal use +in GStreamer and are used in various decoder elements in connection with +low level decoding APIs like DXVA, NVDEC, VAAPI and V4L2 State Less +decoders. The new library is named gstreamer-codecs-1.0 / +libgstcodecs-1.0 and is not yet guaranteed to be API stable across major +versions. + +MPEG-TS muxing improvements + +The GStreamer MPEG-TS muxer has seen major improvements on various +fronts in this cycle: + +- It has been ported to the GstAggregator base class which means it + can work in defined-latency mode with live input sources and + continue streaming if one of the inputs stops producing data. + +- atscmux, a new ATSC-specific tsmux subclass + +- Constant Bit Rate (CBR) muxing support via the new bitrate property + which allows setting the target bitrate in bps. If this is set the + muxer will insert null packets as padding to achieve the desired + multiplex-wide constant bitrate. + +- compliance fixes for TV broadcasting use cases (esp. ATSC). See + Jan’s talk “TV Broadcast compliant MPEG-TS” for details. + +- Streams can now be added and removed at runtime: Until now, any + streams in tsmux had to be present when the element started + outputting its first buffer. Now they can appear at any point during + the stream, or even disappear and reappear later using the same PID. + +- new pcr-interval property allows applications to configure the + desired interval instead of hardcoding it + +- basic SCTE-35 support. This is enabled by setting the scte-35-pid + property on the muxer. Sending SCTE-35 commands is then done by + creating the appropriate SCTE-35 GstMpegtsSection and sending them + on the muxer. + +- MPEG-2 AAC handling improvements + +New elements + +- New qmlgloverlay element for rendering a QtQuick scene over the top + of a video stream. qmlgloverlay requires that Qt support adopting an + external OpenGL context and is known to work on X11 and Windows. + Wayland is known not to work due to limitations within Qt. Check out + the example to see how it works. + +- The clocksync element is a generic element that can be placed in a + pipeline to synchronise passing buffers to the clock at that point. + This is similar to identity sync=true, but because it isn’t + GstBaseTransform-based, it can process GstBufferLists without + breaking them into separate GstBuffers. It is also more discoverable + than the identity option. Note that you do not need to insert this + element into your pipeline to make GStreamer sync to the pipeline + clock, this is usually handled automatically by the elements in the + pipeline (sources and sinks mostly). This element is useful to feed + non-live input such as local files into elements that expect live + input such as webrtcbin.` + +- New imagesequencesrc element to easily create a video stream from a + sequence of JPEG or PNG images (or any other encoding where the type + can be detected), basically a multifilesrc made specifically for + image sequences. + +- rpicamsrc element for capturing raw or encoded video (H.264, MJPEG) + from the Raspberry Pi camera. This works much like the popular + raspivid command line utility but outputs data nicely timestamped + and formatted in order to integrate nicely with other GStreamer + elements. Also comes with a device provider so applications can + discover the camera if available. + +- aatv and cacatv video filters that transform video ASCII art style + +- avtp: new Audio Video Transport Protocol (AVTP) plugin for Linux. + See Andre Guedes’ talk “Audio/Video Bridging (AVB) support in + GStreamer” for more details. + +- clockselect: a pipeline element that enables clock selection/forcing + via gst-launch pipeline syntax. + +- dashsink: Add new sink to produce DASH content. See Stéphane’s talk + or blog post for details. + +- dvbsubenc: a DVB subtitle encoder element + +- microdns: a libmicrodns-based mdns device provider to discover RTSP + cameras on the local network + +- mlaudiosink: new audio sink element for the Magic Leap platform, + accompanied by an MLSDK implementation in the amc plugin + +- msdkvp9enc: VP9 encoder element for the Intel MediaSDK + +- rist: new plugin implementing support for the Video Services Forum’s + Reliable Internet Stream Transport (RIST) TR-06-1 Simple Profile. + See Nicolas’ blog post “GStreamer support for the RIST + Specification” for more details. + +- rtmp2: new RTMP client source and sink elements with fully + asynchronous network operations, better robustness and additional + features such as handling ping and stats messages, and adobe-style + authentication. The new rtmp2src and rtmp2sink elements should be + API-compatible with the old rtmpsrc / rtmpsink elements and should + work as drop-in replacements. + +- new RTP source and sink elements to easily set up RTP streaming via + rtp:// URIs: The rtpsink and rtpsrc elements add an URI interface so + that streams can be decoded with decodebin using rtp:// URIs. These + can be used as follows: ``` gst-launch-1.0 videotestsrc ! x264enc ! + rtph264pay config-interval=3 ! rtpsink uri=rtp://239.1.1.1:1234 + + gst-launch-1.0 videotestsrc ! x264enc ! rtph264pay config-interval=1 + ! rtpsink uri=rtp://239.1.2.3:5000 gst-launch-1.0 rtpsrc + uri=rtp://239.1.2.3:5000?encoding-name=H264 ! rtph264depay ! + avdec_h264 ! videoconvert ! xvimagesink + + gst-launch-1.0 videotestsrc ! avenc_mpeg4 ! rtpmp4vpay + config-interval=1 ! rtpsink uri=rtp://239.1.2.3:5000 gst-launch-1.0 + rtpsrc uri=rtp://239.1.2.3:5000?encoding-name=MP4V-ES ! rtpmp4vdepay + ! avdec_mpeg4 ! videoconvert ! xvimagesink ``` + +- svthevcenc: new SVT-HEVC-based H.265 video encoder + +- switchbin: new helper element which chooses between a set of + processing chains (paths) based on input caps, and changes the + active chain if new caps arrive. Paths are child objects, which are + accessed by the GstChildProxy interface. See the switchbin + documentation for a usage example. + +- vah264dec: new experimental va plugin with an element for H.264 + decoding with VA-API using GStreamer’s new stateless decoder + infrastructure (see Linux section below). + +- v4l2codecs: introduce an V4L2 CODECs Accelerator supporting the new + CODECs uAPI in the Linux kernel (see Linux section below) + +- zxing new plugin to detect QR codes and barcodes, based on libzxing + +- also see the Rust plugins section below which contains plenty of new + exciting plugins written in Rust! New element features and additions -- FIXME +GStreamer core + +- filesink: Add a new “full” buffer mode. Previously the default and + full modes were the same. Now the default mode is like before: it + accumulates all buffers in a buffer list until the threshold is + reached and then writes them all out, potentially in multiple + writes. The new full mode works by always copying memory to a single + memory area and writing everything out with a single write once the + threshold is reached. + +- multiqueue: Add stats property and + current-level-{buffers, bytes, time} pad properties to query the + current levels of the corresponding internal queue. + +Plugins Base + +- alsa: implement a device provider + +- alsasrc: added use-driver-timestamp property to force use of + pipeline timestamps (and disable driver timestamps) if so desired + +- audioconvert: fix changing the mix-matrix property at runtime + +- appsrc: added support for segment forwarding or custom GstSegments + via GstSample, enabled via the handle-segment-change property. This + only works for segments in TIME format for now. + +- compositor: various performance optimisations, checkerboard drawing + fixes, and support for VUYA format + +- encodebin: Fix and refactor smart encoding; ensure that a single + segment is pushed into encoders; improve force-key-unit event + handling. + +- opusenc: Add low delay option (audio-type=restricted-lowdelay) to + disable the SILK layer and achieve only 5ms delay. + +- opusdec: add stats property to retrieve various decoder statistics. + +- uridecodebin3: Let decodebin3 do its stream selection if no one + answers + +- decodebin3: Avoid overriding explicit user selection of streams + +- playbin: add flag to force use of software decoders over any + hardware decoders that might also be available + +- playbin3, playbin: propagate sink context + +- rawvideoparse: Fix tiling support, allow setting colorimetry + +- subparse: output plain utf8 text instead of pango-markup formatted + text if downstream requires it, useful for interop with elements + that only accept utf8-formatted subtitles such as muxers or closed + caption converters. + +- tcpserversrc, tcpclientsrc: add stats property with TCP connection + stats (some are only available on Linux though) + +- timeoverlay: add show-times-as-dates, datetime-format and + datetime-epoch properties to display times with dates + +- videorate: Fix changing rate property during playback; reverse + playback fixes; update QoS events taking into account our rate + +- videoscale: pass through and transform size sensitive metas instead + of just dropping them + +Plugins Good + +- avidemux can handle H.265 video now. Our advice remains to + immediately cease all contact and communication with anyone who + hands you H.265 video in an AVI container, however. + +- avimux: Add support for S24LE and S32LE raw audio and v210 raw video + formats; support more than 2 channels of raw audio. + +- souphttpsrc: disable session sharing and cookie jar when the cookies + property is set; correctly handle seeks past the end of the content + +- deinterlace: new YADIF deinterlace method which should provide + better quality than the existing methods and is LGPL licensed; + alternate fields are supported as input to the deinterlacer as well + now, and there were also fixes for switching the deinterlace mode on + the fly. + +- flvmux: in streamable mode allow adding new pads even if the initial + header has already been written. Old clients will only process the + initial stream, new clients will get a header with the new streams. + The skip-backwards-streams property can be used to force flvmux to + skip and drop a few buffers rather than produce timestamps that go + backward and confuse librtmp-based clients. There’s also better + handling for timestamp rollover when streaming for a long time. + +- imagefreeze: Add live mode, which can be enabled via the new is-live + property. In this mode frames will only be output in PLAYING state + according to the negotiated framerate, skipping frames if the output + can’t keep up (e.g. because it’s blocked downstream). This makes it + possible to actually use imagefreeze in live pipelines without + having to manually ensure somehow that it starts outputting at the + current running time and without still risking to fall behind + without recovery. + +- matroskademux, qtdemux: Provide audio lead-in for some lossy formats + when doing accurate seeks, to make sure we can actually decode + samples at the desired position. This is especially important for + non-linear audio/video editing use-cases. + +- matroskademux, matroskamux: Handle interlaced field order (tff, bff) + +- matroskamux: + + - new offset-to-zero property to offset all streams to start at + zero. This takes the timestamp of the earliest stream and + offsets it so that it starts at 0. Some software (VLC, + ffmpeg-based) does not properly handle Matroska files that start + at timestamps much bigger than zero, which could happen with + live streams. + - added a creation-time property to explicitly set the creation + time to write into the file headers. Useful when remuxing, for + example, but also for live feeds where the DateUTC header can be + set a UTC timestamp corresponding to the beginning of the file. + - the muxer now also always waits for caps on sparse streams, and + warns if caps arrive after the header has already been sent, + otherwise the subtitle track might be silently absent in the + final file. This might affect applications that send sparse data + into matroskamux via an appsrc element, which will usually not + send out the initial caps before it sends out the first buffer. + +- pulseaudio: device provider improvements: fix discovery of + newly-added devices and hide the alsa device provider if we provide + alsa devices + +- qtdemux: raw audio handling improvements, support for AC4 audio, and + key-units trickmode interval support + +- qtmux: + + - was ported to the GstAggregator base class which allows for + better handling of live inputs, but might entail minor + behavioural changes for sparse inputs if inputs are not live. + - has also gained a force-create-timecode-trak property to create + a timecode trak in non-mov flavors, which may not be supported + by Apple but is supported by other software such as Final Cut + Pro X + - also a force-chunks property to force the creation of chunks + even in single-stream files, which is required for Apple ProRes + certification. + - also supports 8k resolutions in prefill mode with ProRes. + +- rtpbin gained a request-jitterbuffer signal which allows + applications to plug in their own jitterbuffer implementation such + as the threadsharing jitterbuffer from the Rust plugins, for + example. + +- rtprtxsend: add clock-rate-map property to allow generic RTP input + caps without a clock-rate whilst still supporting the max-size-time + property for bundled streams. + +- rtpssrcdemux: introduce max-streams property to guard against + attacks where the sender changes SSRC for every RTP packet. + +- rtph264pay, rtph264pay: implement STAP-A and various aggregation + modes controled by the new aggegrate-mode property: none to not + aggregate NAL units (as before), zero-latency to aggregate NAL units + until a VCL or suffix unit is included, or max to aggregate all NAL + units with the same timestamp (which adds one frame of latency). The + default has been kept at none for backwards compatibility reasons + and because various RTP/RTSP implementions don’t handle aggregation + well. For WebRTC use cases this should be set to zero-latency, + however. + +- rtpmp4vpay: add support for config-interval=-1 to resend headers + with each IDR keyframe, like other video payloaders. + +- rtpvp8depay: Add wait-for-keyframe property for waiting until the + next keyframe after packet loss. Useful if the video stream was not + encoded with error resilience enabled, in which case packet loss + tends to cause very bad artefacts when decoding, and waiting for the + next keyframe instead improves user experience considerably. + +- splitmuxsink and splitmuxsrc can now handle auxiliary video streams + in addition to the primary video stream. The primary video stream is + still used to select fragment cut points at keyframe boundaries. + Auxilliary video streams may be broken up at any packet - so + fragments may not start with a keyframe for those streams. + +- splitmuxsink: + + - new muxer-preset and sink-preset properties for setting + muxer/sink presets + - a new start-index property to set the initial fragment id + - and a new muxer-pad-map property which explicitly maps + splitmuxsink pads to the muxer pads they should connect to, + overriding the implicit logic that tries to match pads but + yields arbitrary names. + - Also includes the actual sink element in the fragment-opened and + fragment-closed element messages now, which is especially useful + for sinks without a location property or when finalisation of + the fragments is done asynchronously. + +- videocrop: add support for Y444, Y41B and Y42B pixel formats + +- vp8enc, vp9enc: change default value of VP8E_SET_STATIC_THRESHOLD + from 0 to 1 which matches what Google WebRTC does and results in + lower CPU usage; also added a new bit-per-pixel property to select a + better default bitrate + +- v4l2: add support for ABGR, xBGR, RGBA, and RGBx formats and for + handling interlaced video in alternate fields interlace mode (one + field per buffer instead of one frame per picture with both fields + interleaved) + +- v4l2: Profile and level probing support for H264, H265, MPEG-4, + MPEG-2, VP8, and VP9 video encoders and decoders + +Plugins Ugly + +- asfdemux: extract more metadata: disc number and disc count + +- x264enc: + + - respect YouTube bitrate recommendation when user sets the + YouTube profile preset + - separate high-10 video formats from 8-bit formats to improve + depth negotiation and only advertise suitable input raw formats + for the desired output depth + - forward downstream colorimetry and chroma-site restrictions to + upstream elements + - support more color primaries/mappings + +Plugins Bad + +- av1enc: add threads, row-mt and tile-{columns,rows} properties for + this AOMedia AV1 encoder + +- ccconverter: implement support for CDP framerate conversions + +- ccextractor: Add remove-caption-meta property to remove caption + metas from the outgoing video buffers + +- decklink: add support for 2K DCI video modes, widescreen NTSC/PAL, + and for parsing/outputting AFD/Bar data. Also implement a simple + device provider for Decklink devices. + +- dtlsrtpenc: add rtp-sync property which synchronises RTP streams to + the pipeline clock before passing them to funnel for merging with + RTCP. + +- fdkaac: also decode MPEG-2 AAC; encoder now supports more + multichannel/surround sound layouts + +- hlssink2: add action signals for custom playlist/fragment handling: + Instead of always going through the file system API we allow the + application to modify the behaviour. For the playlist itself and + fragments, the application can provide a GOutputStream. In addition + the sink notifies the application whenever a fragment can be + deleted. + +- interlace: can now output data in alternate fields mode; added field + switching mode for 2:2 field pattern + +- iqa: Add a mode property to enable strict mode that checks that all + the input streams have the exact same number of frames; also + implement the child proxy interface + +- mpeg2enc: add disable-encode-retries property for lower CPU usage + +- mpeg4videoparse: allow re-sending codec config at IDR via + config-interval=-1 + +- mpegtsparse: new alignment property to determine number of TS + packets per output buffer, useful for feeding an MPEG-TS stream for + sending via udpsink. This can be used in combination with the + split-on-rai property that makes sure to start a new output buffer + for any TS packet with the Random Access Indicator set. Also set + delta unit buffer flag on non-random-access buffers. + +- mpegdemux: add an ignore-scr property to ignore the SCR in + non-compliant MPEG-PS streams with a broken SCR, which will work as + long as PTS/DTS in the PES header is consistently increasing. + +- tsdemux: + + - add an ignore-pcr property to ignore MPEG-TS streams with broken + PCR streams on which we can’t reliably recover correct + timestamps. + - new latency property to allow applications to lower the + advertised worst-case latency of 700ms if they know their + streams support this (must have timestamps in higher frequency + than required by the spec) + - support for AC4 audio + +- msdk - Intel Media SDK plugin for hardware-accelerated video + decoding and encoding on Windows and Linux: + + - mappings for more video formats: Y210, Y410, P012_LE, Y212_LE + - encoders now support bitrate changes and input format changes in + playing state + - msdkh264enc, msdkh265enc: add support for CEA708 closed caption + insertion + - msdkh264enc, msdkh265enc: set Region of Interest (ROI) region + from ROI metas + - msdkh264enc, msdkh265enc: new tune property to enable low-power + mode + - msdkh265enc: add support 12-bit 4:2:0 encoding and 8-bit 4:2:2 + encoding and VUYA, Y210, and Y410 as input formats + - msdkh265enc: add support for screen content coding extension + - msdkh265dec: add support for main-12/main-12-intra, + main-422-10/main-422-10-intra 10bit, + main-422-10/main-422-10-intra 8bit, + main-422-12/main-422-12-intra, main-444-10/main-444-10-intra, + main-444-12/main-444-12-intra, and main-444 profiles + - msdkvp9dec: add support for 12-bit 4:4:4 + - msdkvpp: add support for Y410 and Y210 formats, cropping via + properties, and a new video-direction property. + +- mxf: Add support for CEA-708 CDP from S436 essence tracks. mxfdemux + can now handle Apple ProRes + +- nvdec: add H264 + H265 stateless codec implementation nvh264sldec + and nvh265sldec with fewer features but improved latency. You can + set the environment variable GST_USE_NV_STATELESS_CODEC=h264 to use + the stateless decoder variant as nvh264dec instead of the “normal” + NVDEC decoder implementation. + +- nvdec: add support for 12-bit 4:4:4/4:2:0 and 10-bit 4:2:0 decoding + +- nvenc: + + - add more rate-control options, support for B-frame encoding (if + device supports it), an aud property to toggle Access Unit + Delimiter insertion, and qp-{min,max,const}-{i,p,b} properties. + - the weighted-pred property enables weighted prediction. + - support for more input formats, namely 8-bit and 10-bit RGB + formats (BGRA, RGBA, RGB10A2, BGR10A2) and YV12 and VUYA. + - on-the-fly resolution changes are now supported as well. + - in case there are multiple GPUs on the system, there are also + per-GPU elements registered now, since different devices will + have different capabilities. + - nvh265enc can now support 10-bit YUV 4:4:4 encoding and 8-bit + 4:4:4 / 10-bit 4:2:0 formats up to 8K resolution (with some + devices). In case of HDR content HDR related SEI nals will be + inserted automatically. + +- openjpeg: enable multi-threaded decoding and add support for + sub-frame encoding (for lower latency) + +- rtponviftimestamp: add opt-out “drop-out-of-segment” property + +- spanplc: new stats property + +- srt: add support for IPv6 and for using hostnames instead of IP + addresses; add streamid property, but also allow passing the id via + the stream URI; add wait-for-connection property to srtsink + +- timecodestamper: this element was rewritten with an updated API + (properties); it has gained many new properties, seeking support and + support for linear timecode (LTC) from an audio stream. + +- uvch264src now comes with a device provider to advertise available + camera sources that support this interface (mostly Logitech C920s) + +- wpe: Add software rendering support and support for mouse scroll + events + +- x265enc: support more 8/10/12 bits 4:2:0, 4:2:2 and 4:4:4 profiles; + add support for mastering display info and content light level + encoding SEIs + +gst-libav + +- Add mapping for SpeedHQ video codec used by NDI + +- Add mapping for aptX and aptX-HD + +- avivf_mux: support VP9 and AV1 + +- avvidenc: shift output buffer timestamps and output segment by 1h + just like x264enc does, to allow for negative DTS. + +- avviddec: Limit default number of decoder threads on systems with + more than 16 cores, as the number of threads used in avdec has a + direct impact on the latency of the decoder, which is of as many + frames as threads, so a large numbers of threads can make for + latency levels that can be problematic in some applications. + +- avviddec: Add thread-type property that allows applications to + specify the preferred multithreading method (auto, frame, slice). + Note that thread-type=frame may introduce additional latency + especially in live pipelines, since it introduces a decoding delay + of number of thread frames. Plugin and library moves -- FIXME +- There were no plugin moves or library moves in this cycle. + +- The rpicamsrc element was moved into -good from an external + repository on github. Plugin removals -The following plugins have been removed from gst-plugins-bad: +The following elements or plugins have been removed: -- FIXME +- The yadif video deinterlacing plugin from gst-plugins-bad, which was + one of the few GPL licensed plugins, has been removed in favour of + deinterlace method=yadif. + +- The avdec_cdgraphics CD Graphics video decoder element from + gst-libav was never usable in GStreamer and we now have a cdgdec + element written in Rust in gst-plugins-rs to replace it. + +- The VDPAU plugin has been unmaintained and unsupported for a very + long time and does not have the feature set we expect from + hardware-accelerated video decoders. It’s been superseded by the + nvcodec plugin leveraging NVIDIA’s NVDEC API. Miscellaneous API additions -- FIXME +GStreamer core -Miscellaneous performance and memory optimisations +- gst_task_resume(): This new API allows resuming a task if it was + paused, while leaving it in stopped state if it was stopped or not + started yet. This can be useful for callback-based driver workflows, + where you basically want to pause and resume the task when buffers + are notified while avoiding the race with a gst_task_stop() coming + from another thread. + +- info: add printf extensions GST_TIMEP_FORMAT and GST_STIMEP_FORMAT + for printing GstClockTime/GstClockTimeDiff pointers, which is much + more convenient to use in debug log statements than the usual + GST_TIME_FORMAT-followed-by-GST_TIME_ARGS dance. Also add an + explicit GST_STACK_TRACE_SHOW_NONE enum value. + +- gst_element_get_current_clock_time() and + gst_element_get_current_running_time(): new helper functions for + getting an element clock’s time, and the clock time minus base time, + respectively. Useful when adding additional input branches to + elements such as compositor, audiomixer, flvmux, interleave or + input-selector to determine initial pad offsets and such. + +- seeking: Add GST_SEEK_FLAG_TRICKMODE_FORWARD_PREDICTED to just skip + B-frames during trick mode, showing both keyframes + P-frame, and + add support for it in h264parse and h265parse. + +- elementfactory: add GST_ELEMENT_FACTORY_TYPE_HARDWARE to allow + elements to advertise that they are hardware-based or interact with + hardware. This has multiple applications: + + - it makes it possible to easily differentiate hardware and + software based element implementations such as audio or video + encoders and decoders. This is useful in order to force the use + of software decoders for specific use cases, or to check if a + selected decoder is actually hardware-accelerated or not. + - elements interacting with hardware and their respective drivers + typically don’t know the actually supported capabilities until + the element is set into at least READY state and can open a + device handle and probe the hardware. + +- gst_uri_from_string_escaped(): identical to gst_uri_from_string() + except that the userinfo and fragment components of the URI will not + be unescaped while parsing. This is needed for correctly parsing + usernames or passwords with : in them . + +- paramspecs: new GstParamSpec flag GST_PARAM_CONDITIONALLY_AVAILABLE + to indicate that a property might not always exist. + +- gst_bin_iterate_all_by_element_factory_name() finds elements in a + bin by factory name + +- pad: gst_pad_get_single_internal_link() is a new convenience + function to return the single internal link of a pad, which is + useful e.g. to retrieve the output pad of a new multiqueue request + pad. + +- datetime: Add constructors to create datetimes with timestamps in + microseconds, gst_date_time_new_from_unix_epoch_local_time_usecs() + and gst_date_time_new_from_unix_epoch_utc_usecs(). + +- gst_debug_log_get_lines() gets debug log lines formatted in the same + way the default log handler would print them + +- GstSystemClock: Add GST_CLOCK_TYPE_TAI as GStreamer abstraction for + CLOCK_TAI, to support transmission offloading features where network + packets are timestamped with the time they are deemed to be actually + transmitted. Useful in combination with the new AVTP plugin. + +- miscellaneous utility functions: gst_clear_uri(), + gst_structure_take(). + +- harness: Added gst_harness_pull_until_eos() + +- GstBaseSrc: + + - gst_base_src_new_segment() allows subclasses to update the + segment to be used at runtime from the ::create() function. This + deprecates gst_base_src_new_seamless_segment() + - gst_base_src_negotiate() allows subclasses to trigger format + renegotiation at runtime from inside the ::create() or ::alloc() + function + +- GstBaseSink: new stats property and gst_base_sink_get_stats() method + to retrieve various statistics such as average frame rate and + dropped/rendered buffers. + +- GstBaseTransform: gst_base_transform_reconfigure() is now public + API, useful for subclasses that need to completely re-implement the + ::submit_input_buffer() virtual method + +- GstAggregator: + + - gst_aggregator_update_segment() allows subclasses to update the + output segment at runtime. Subclasses should use this function + rather than push a segment event onto the source pad directly. + - new sample selection API: + - subclasses should now call gst_aggregator_selected_samples() + from their ::aggregate() implementation to signal that they + have selected the next samples they will aggregate + - GstAggregator will then emit the samples-selected signal + where handlers can then look up samples per pad via + gst_aggregator_peek_next_sample(). + - This is useful for example to atomically update input pad + properties in mixer subclasses such as compositor. + Applications can now update properties with precise control + of when these changes will take effect, and for which input + buffer(s). + - gst_aggregator_finish_buffer_list() allows subclasses to push + out a buffer list, improving efficiency in some cases. + - a ::negotiate() virtual method was added, for consistency with + other base classes and to allow subclasses to completely + override the negotiation behaviour. + - the new ::sink_event_pre_queue() and ::sink_query_pre_queue() + virtual methods allow subclasses to intercept or handle + serialized events and queries before they’re queued up + internally. + +GStreamer Plugins Base Libraries + +Audio library + +- audioaggregator, audiomixer: new output-buffer-duration-fraction + property which allows use cases such as keeping the buffers output + by compositor on one branch and audiomixer on another perfectly + aligned, by requiring the compositor to output a n/d frame rate, and + setting output-buffer-duration-fraction to d/n on the audiomixer. + +- GstAudioDecoder: new max-errors property so applications can + configure at what point the decoder should error out, or tell it to + just keep going + +- gst_audio_make_raw_caps() and gst_audio_formats_raw() are + bindings-friendly versions of the GST_AUDIO_CAPS_MAKE() C macro. + +- gst_audio_info_from_caps() now handles encoded audio formats as well + +PbUtils library + +- GstEncodingProfile: + - Do not restrict number of similar profiles in a container + - add GstValue serialization function +- codec utils now support more H.264/H.265 profiles/levels and have + improved extension handling + +RTP library + +- rtpbasepayloader: Add scale-rtptime property for scaling RTP + timestamp according to the segment rate (equivalent to RTSP speed + parameter). This is useful for ONVIF trickmodes via RTSP. + +- rtpbasepayload: add experimental property for embedding twcc + sequencenumbers for Transport-Wide Congestion Control (gated behind + the GST_RTP_ENABLE_EXPERIMENTAL_TWCC_PROPERTY environment + variable) - more generic API for enabling this is expected to land + in the next development cycle. + +- rtcpbuffer: add RTPFB_TYPE_TWCC for Transport-Wide Congestion + Control + +- rtpbuffer: add + gst_rtp_buffer_get_extension_onebyte_header_from_bytes()``, so that one can parse theGBytes` + returned by gst_rtp_buffer_get_extension_bytes() + +- rtpbasedepayload: Add max-reorder property to make the + previously-hardcoded value when to consider a sender to have + restarted configurable. In some scenarios it’s particularly useful + to set max-reorder=0 to disable the behaviour that the depayloader + will drop packets: when max-reorder is set to 0 all + reordered/duplicate packets are considered coming from a restarted + sender. + +RTSP library + +- add gst_rtsp_url_get_request_uri_with_control() to create request + uri combined with control url + +- GstRTSPConnection: add the possibility to limit the Content-Length + for RTSP messages via + gst_rtsp_connection_set_content_length_limit(). The same + functionality is also exposed in gst-rtsp-server. + +SDP library + +- add support for parsing the extmap attribute from caps and storing + inside caps The extmap attribute allows mapping RTP extension header + IDs to well-known RTP extension header specifications. See RFC8285 + for details. + +Tags library + +- update to latest iso-code and support more languages + +- add tags for acoustid id & acoustid fingerprint, plus MusicBrainz ID + handling fixes + +Video library + +- High Dynamic Range (HDR) video information representation and + signalling enhancements: + + - New APIs for HDR video information representation and + signalling: + - GstVideoMasteringDisplayInfo: display color volume info as + per SMPTE ST 2086 + - GstVideoContentLightLevel: content light level specified in + CEA-861.3, Appendix A. + - plus functions to serialise/deserialise and add them to or + parse them from caps + - gst_video_color_{matrix,primaries,transfer}_{to,from}_iso(): + new utilility functions for conversion from/to ISO/IEC + 23001-8 + - add ARIB STD-B67 transfer chracteristic function + - add SMPTE ST 2084 support and BT 2100 colorimetry + - define bt2020-10 transfer characteristics for clarity: + bt707, bt2020-10, and bt2020-12 transfer characteristics are + functionally identical but have their own unique values in + the specification. + - h264parse, h265parse: Parse mastering display info and content + light level from SEIs. + - matroskademux: parse HDR metadata + - matroskamux: Write MasteringMetadata and Max{CLL,FALL}. Enable + muxing with HDR meta data if upstream provided it + - avviddec: Extract HDR information if any and map bt2020-10, PQ + and HLG transfer functions + +- added bt601 transfer function (for completeness) + +- support for more pixel formats: + + - Y412 (packed 12 bits 4:4:4:4) + - Y212 (packed 12 bits 4:2:2) + - P012 (semi-planar 4:2:0) + - P016_{LE,BE} (semi-planar 16 bits 4:2:0) + - Y444_16{LE,BE} (planar 16 bits 4:4:4) + - RGB10A2_LE (packed 10-bit RGB with 2-bit alpha channel) + - NV12_32L32 (NV12 with 32x32 tiles in linear order) + - NV12_4L4 (NV12 with 4x4 tiles in linear order) + +- GstVideoDecoder: + + - new max-errors property so applications can configure at what + point the decoder should error out, or tell it to just keep + going + + - new qos property to disable dropping frames because of QoS, and + post QoS messages on the bus when dropping frames. This is + useful for example in a scenario where the decoded video is + tee-ed off to go into a live sink that syncs to the clock in one + branch, and an encoding and save to file pipeline in the other + branch. In that case one wouldn’t want QoS events from the video + sink make the decoder drop frames because that would also leave + gaps in the encoding branch then. + +- GstVideoEncoder: + + - gst_video_encoder_finish_subframe() is new API to push out + subframes (e.g. slices), so encoders can split the encoding into + subframes, which can be useful to reduce the overall end-to-end + latency as we no longer need to wait for the full frame to be + encoded to start decoding or sending out the data. + - new min-force-key-unit-interval property allows configuring the + minimum interval between force-key-unit requests and prevents a + big bitrate increase if a lot of key-units are requested in a + short period of time (as might happen in live streaming RTP + pipelines when packet loss is detected). + - various force-key-unit event handling fixes + +- GstVideoAggregator, compositor, glvideomixer: expose + max-last-buffer-repeat property on pads. This can be used to have a + compositor display either the background or a stream on a lower + zorder after a live input stream freezes for a certain amount of + time, for example because of network issues. + +- gst_video_format_info_component() is new API to find out which + components are packed into a given plane, which is useful to prevent + us from assuming a 1-1 mapping between planes and components. + +- gst_video_make_raw_caps() and gst_video_formats_raw() are + bindings-friendly versions of the GST_VIDEO_CAPS_MAKE() C macro. + +- video-blend: Add support for blending on top of 16 bit per component + formats, which makes sure we can support every currently supported + raw video format for blending subtitles or logos on top of video. + +- GST_VIDEO_BUFFER_IS_TOP_FIELD() and + GST_VIDEO_BUFFER_IS_BOTTOM_FIELD() convenience macros to check + whether the video buffer contains only the top field or bottom field + of an interlaced picture. + +- GstVideoMeta now includes an alignment field with the + GstVideoAlignment so buffer producers can explicitly specify the + exact geometry of the planes, allowing users to easily know the + padded size and height of each plane. Default values will be used if + this is not set. + + Use gst_video_meta_set_alignment() to set the alignment and + gst_video_meta_get_plane_size() or gst_video_meta_get_plane_height() + to compute the plane sizes or plane heights based on the information + in the video meta. + +- gst_video_info_align_full() works like gst_video_info_align() but + also retrieves the plane sizes. + +MPEG-TS library + +- support for SCTE-35 sections + +- extend support for ATSC tables: + + - System Time Table (STT) + - Master Guide Table (MGT) + - Rating Region Table (RRT) + +Miscellaneous performance, latency and memory optimisations As always there have been many performance and memory usage improvements across all components and modules. Some of them have already been @@ -69,63 +1073,654 @@ The following list is only a small snapshot of some of the more interesting optimisations that haven’t been mentioned in other contexts yet: -- FIXME +- caps negotiation, structure and GValue performance optimizations -GstPlayer +- systemclock: clock waiting performance improvements (moved from + GstPoll to GCond for waiting), especially on Windows. -- FIXME +- rtpsession: add support for buffer lists on the recv path for better + performance with higher packet rate streams. -Miscellaneous changes +- rtpjitterbuffer: internal timer handling has been rewritten for + better performance, see Nicolas’ talk “Revisiting RTP Jitter Buffer + Timers” for more details. -- FIXME +- H.264/H.265 parsers and RTP payloaders/depayloaders have been + optimised for latency to make sure data is processed and pushed out + as quickly as possible + +- video-scaler: correctness and performance improvements, esp. for + interlaced formats and GBRA + +- GstVideoEncoder has gained new API to push out subframes + (e.g. slices), so encoders can split the encoding into subframes, + which can be useful to reduce the overall end-to-end latency as we + no longer need to wait for the full frame to be encoded to start + decoding or sending out the data. + + This is complemented by the new GST_VIDEO_BUFFER_FLAG_MARKER which + is a video-specific buffer flag to mark the end of a video frame, so + elements can know that they have received all data for a frame + without waiting for the beginning of the next frame. This is similar + to how the RTP marker flag is used in many RTP video mappings. + + The video encoder base class now also releases the internal stream + lock before pushing out data, so as to not block the input side of + things from processing more data in the meantime. + +Miscellaneous other changes and enhancements + +- it is now possible to modify the initial rank of plugin features + without modifying the source code or writing code to do so + programmatically via the GST_PLUGIN_FEATURE_RANK environment + variable. Users can adjust the rank of plugin(s) by passing a + comma-separated list of feature:rank pairs where rank can be a + numerical value or one of NONE, MARGINAL, SECONDARY, PRIMARY, and + MAX. Example: GST_PLUGIN_FEATURE_RANK=myh264dec:MAX,avdec_h264:NONE + sets the rank of the myh264dec element feature to the maximum and + that of avdec_h264 to 0 (none), thus ensuring that myh264dec is + prefered as H264 decoder in an autoplugging context. + +- GstDeviceProvider now does a static probe on start as fallback for + providers that don’t support dynamic probing to make things easier + for users + +WebRTC + +- webrtcbin now contains initial support for renegotiation involving + stream addition and removal. There are a number of caveats to this + initial renegotiation support and many complex scenarios are known + to require some work. + +- webrtcbin now exposes the internal ICE object for advanced + configuration options. Using the internal ICE object, it is possible + to toggle UDP or TCP connection usage as well as provide local + network addresses. + +- Fix a number of call flows within webrtcbin’s GstPromise handling + where a promise was never replied to. This has been fixed and now a + promise will always receive a reply. + +- webrtcbin now exposes a latency property for configuring the + internal rtpjitterbuffer latency and buffering when receiving + streams. + +- webrtcbin now only synchronises the RTP part of a stream, allowing + RTCP messages to skip synchronisation entirely. + +- Fixed most of the webrtcbin state properties (connection-state, + ice-connection-state, signaling-state, but not ice-gathering-state + as that requires newer API in libnice and will be fixed in the next + release series) to advance through the state values correctly. Also + implemented DTLS connection states in the DTLS elements so that + peer-connection-state is not always new. + +- webrtcbin now accounts for the a=ice-lite attribute in a remote SDP + offer and will configure the internal ICE implementation + accordingly. + +- webrtcbin will now resolve .local candidate addresses using the + system DNS resolver. .local candidate addresses are now produced by + web browsers to help protect the privacy of users. + +- webrtcbin will now add candidates found in the SDP to the internal + ICE agent. This was previously unsupported and required using the + add-ice-candidate signal manually from the application. + +- webrtcbin will now correctly parse a TURN URI that contains a + username or password with a : in it. + +- The GStreamer WebRTC library gained a GstWebRTCDataChannel object + roughly matching the interface exposed by the WebRTC specification + to allow for easier binding generation and use of data channels. OpenGL integration -- FIXME +GStreamer OpenGL bindings/build related changes + +- The GStreamer OpenGL library (libgstgl) now ships pkg-config files + for platform-specific API where libgstgl provides a public + integration interface and a pkg-config file for a dependency on the + detected OpenGL headers. The new list of pkg-config files in + addition to the original gstreamer-gl-1.0 are gstreamer-gl-x11-1.0, + gstreamer-gl-wayland-1.0, gstreamer-gl-egl-1.0, and + gstreamer-gl-prototypes-1.0 (for OpenGL headers when including + gst/gl/gstglfuncs.h). + +- GStreamer OpenGL now ships some platform-specific introspection data + for platforms that have a public interface. This should allow for + easier integration with bindings involving platform specific + functionality. The new introspection data files are named + GstGLX11-1.0, GstGLWayland-1.0, and GstGLEGL-1.0. + +GStreamer OpenGL Features + +- The iOS implementation no longer accesses UIKit objects off the main + thread fixing a loud warning message when used in iOS applications. + +- Support for mouse and keyboard handling using the GstNavigation + interface was added for the wayland implementation complementing the + already existing support for the X11 and Windows implementations. + +- A new helper base class for source elements, GstGLBaseSrc is + provided to ease writing source elements producing OpenGL video + frames. + +- Support for some more 12-bit and 16-bit video formats (Y412_LE, + Y412_BE, Y212_LE, Y212_BE, P012_LE, P012_BE, P016, NV16, NV61) was + added to glcolorconvert. + +- glupload can now import dma-buf’s into external-oes textures. + +- A new display type for EGLDevice-based systems was added. It is + currently opt-in by using either the GST_GL_PLATFORM=egl-device + environment variable or manual construction + (gst_gl_display_egl_device_new*()) due to compatibility issues with + some platforms. + +- Support was added for WinRT/UWP using the ANGLE project for running + OpenGL-based pipelines within a UWP application. + +- Various elements now support changing the GstGLDisplay to be used at + runtime in simple cases. This is primarily helpful for changing or + adding an OpenGL-based video sink that must share an OpenGL context + with an external source to an already running pipeline. + +GStreamer Vulkan integration + +- There is now a GStreamer Vulkan library to provide integration + points and helpers with applications and external GStreamer Vulkan + based elements. The structure of the library is modelled similarly + to the already existing GStreamer OpenGL library. Please note that + the API is still unstable and may change in future releases, + particularly around memory handling. The GStreamer Vulkan library + contains objects for sharing the vkInstance, vkDevice, vkQueue, + vkImage, VkMemory, etc with other elements and/or the application as + well as some helper objects for using Vulkan in an application or + element. + +- Added support for building and running on/for the Android and + Windows systems to complement the existing XCB, Wayland, MacOS, and + iOS implementations. + +- XCB gained support for mouse/keyboard events using the GstNavigation + API. + +- New vulkancolorconvert element for converting between color formats. + vulkancolorconvert can currently convert to/from all 8-bit RGBA + formats as well as 8-bit RGBA formats to/from the YUV formats AYUV, + NV12, and YUY2. + +- New vulkanviewconvert element for converting between stereo view + layouts. vulkanviewconvert can currently convert between all of the + single memory formats (side-by-side, top-bottom, column-interleaved, + row-interleaved, checkerboard, left, right, mono). + +- New vulkanimageidentity element for a blit from the input vulkan + image/s to a new vulkan image/s. + +- The vulkansink element can now scale the input image to the output + window/surface size where that information is available. + +- The vulkanupload element can now configure a transfer from system + memory to VulkanImage-based memory. Previously, this required two + vulkanupload elements. Tracing framework and debugging improvements -- FIXME +- gst_tracing_get_active_tracers() returns a list of active tracer + objects. This can be used to interact with tracers at runtime using + GObject API such as action signals. This has been implemented in the + leaks tracer for snapshotting and retrieving leaked/active objects + at runtime. + +- The leaks tracer can now be interacted with programmatically at + runtime via GObject action signals: + + - get-live-object returns a list of live (allocated) traced + objects + - log-live-objects logs a list of live objects into the debug log. + This is the same as sending the SIGUSR1 signal on unix systems, + but works on all operating systems including Windows. + - activity-start-tracking, activity-get-checkpoint, + activity-log-checkpoint, activity-stop-tracking: add support for + tracking and checkpointing objects, similar to what was + previously available via SIGUSR2 on unix systems, but works on + all operating systems including Windows. + +- various GStreamer gdb debug helper improvements: + + - new ‘gst-pipeline-tree’ command + - more gdb helper functions: gst_element_pad(), gst_pipeline() and + gst_bin_get() + - support for queries and buffers + - print more info for segment events, print event seqnums, object + pointers and structures + - improve gst-print command to show more pad and element + information Tools -- FIXME +gst-launch-1.0 + +- now prints the pipeline position and duration if available when the + pipeline is advancing. This is hopefully more user-friendly and + gives visual feedback on the terminal that the pipeline is actually + up and running. This can be disabled with the --no-position command + line option. + +- the parse-launch pipeline syntax now has support for presets: + use@preset=" after an element to load a preset. + +gst-inspect-1.0 + +- new --color command line option to force coloured output even if not + connected to a tty + +gst-tester-1.0 (new) + +- gst-tester-1.0 is a new tool for plugin developers to launch + .validatetest files with TAP compatible output, meaning it can + easily and cleanly be integrated with the meson test harness. It + allows you to use gst-validate (from the gst-devtools module) to + write integration tests in any GStreamer repository whilst keeping + the tests as close as possible to the code. The tool transparently + handles gst-validate being installed or not: if it is not installed + those integration tests will simply be skipped. + +gst-play-1.0 + +- interactive keyboard controls now also work on Windows + +gst-transcoder-1.0 (new) + +- gst-transcoder-1.0 is a new command line tool to transcode one URI + into another URI based on the specified encoding profile using the + new GstTranscoder API (see above). GStreamer RTSP server -- FIXME +- Fix issue where the first few packets (i.e. keyframes) could + sometimes be dropped if the rtsp media pipeline had a live input. + This was a regression from GStreamer 1.14. There are more fixes + pending for that which will hopefully land in 1.18.1. + +- Fix backpressure handling when sending data in TCP interleave mode + where RTSP requests and responses and RTP/RTCP packets flow over the + same RTSP TCP connection: The previous implementation would at some + point stop sending data to other clients when a single client + stopped consuming data or did not consume data fast enough. This + obviously created problems for shared media, where the same stream + from a single producer pipeline is sent to multiple clients. Instead + we now manage a backlog in the server’s stream-transport component + and remove slow clients once this backlog exceeds a maximum duration + (which is currently hardcoded). + +- Onvif Streaming Specification trick modes support (see section at + the beginning) + +- Scale/Speed header support: Speed will deliver the data at the + requested speed, which means increasing the data bandwidth for + speeds > 1.0. Scale will attempt to do the same without affecting + the overall bandwidth requirement vis-a-vis normal playback speed + (e.g. it might drop data for fast-forward playback). + +- rtspclientsink: send buffer lists in one go for better performance GStreamer VAAPI -- FIXME +- A lot of work was done adding support for media-driver (iHD), the + new VAAPI driver for Intel, mostly for Gen9 onwards. + +- Available color formats and frame sizes are now detected at run-time + according to the context configuration. + +- Gallium drivers have been re-enabled in the allowed drivers list + +- Improved the mapping between VA formats and GStreamer formats by + generating a mapping table at run-time since even among different + drivers the mapping might be different, particularly for RGB with + little endianness. + +- The experimental Flexible Encoding Infrastructure (FEI) elements + have been removed since they were not really actively maintained or + tested. + +- Enhanced the juggling of DMABuf buffers and VASurface metas + +- New vaapioverlay element: a compositor element using VA VPP blend + capabilities to accelerate overlaying and compositing. Example + pipeline: + + gst-launch-1.0 -vf videotestsrc ! vaapipostproc ! tee name=testsrc ! queue \ + ! vaapioverlay sink_1::xpos=300 sink_1::alpha=0.75 name=overlay ! vaapisink \ + testsrc. ! queue ! overlay. + +vaapipostproc + +- added video-orientation support, supporting frame mirroring and + rotation + +- added cropping support, either via properties (crop-left, + crop-right, crop-bottom and crop-top) or buffer meta. + +- new skin-tone-enhancenment-level property which is the iHD + replacement of the i965 driver’s sink-tone-level. Both are + incompatible with each other, so both were kept. + +- handle video colorimetry + +- support HDR10 tone mapping + +vaapisink + +- resurrected wayland backend for non-weston compositors by extracting + the DMABuf from the VASurface and rendering it. + +- merged the video overlay API for wayland. Now applications can + define the “window” to render on. + +- demoted the vaapisink element to secondary rank since libva + considers rendering as a second-class feature. + +VAAPI Encoders + +- new common target-percentage property which is the desired target + percentage of bitrate for variable rate control. + +- encoders now extract their caps from the driver at registration + time. + +- vaapivp9enc: added support for low power mode and support for + profile 2 (profile 0 by default) + +- vaapih264enc: new max-qp property that sets the maximum quantization + value. Support for ICQ and QBVR bitrate control mode, adding a + quality-factor property for these modes. Support baseline profile as + constrained-baseline + +- vaapih265enc: + + - support for main-444 and main-12 encoding profiles. + - new max-qp property that sets the maximum quantization value. + - support for ICQ and QBVR bitrate control mode, adding a + quality-factor property for these modes. + - handle SCC profiles. + - num-tile-cols and num-tile-row properties to specify the number + of tiles to use. + - the low-delay-b property was deprecated and is now determined + automatically. + - improved profile selection through caps. + +VAAPI Decoders + +- Decoder surfaces are not bound to their context any longer and can + thus be created and used dynamically, removing the deadlock + headache. + +- Reverse playback is now fluid + +- Forward Region-of-Interest (ROI) metas downstream + +- GLTextureUploadMeta uses DMABuf when GEM is not available. Now + Gallium drivers can use this meta for rendering with EGL. + +- vaapivp9dec: support for 4:2:2 and 4:4:4 chroma type streams + +- vaapih265dec: skip all pictures prior to the first I-frame. Enable + passing range extension flags to the driver. Handle SCC profiles. + +- vaapijpegdec: support for 4:0:0, 4:1:1, 4:2:2 and 4:4:4 chroma types + pictures + +- vaapih264dec: handle baseline streams as constrained-baseline if + possible and make it more tolerant when encountering unknown NALs GStreamer OMX -- FIXME +- omxvideoenc: use new video encoder subframe API to push out slices + as soon as they’re ready + +- omxh264enc, omxh265enc: negotiate subframe mode via caps. To enable + it, force downstream caps to video/x-h264,alignment=nal or + video/x-h265,alignment=nal. + +- omxh264enc: Add ref-frames property + +- Zynq ultrascale+ specific video encoder/decoder improvements: + + - GRAY8 format support + - support for alternate fields interlacing mode + - video encoder: look-ahead, long-term-ref, and long-term-freq + properties GStreamer Editing Services and NLE -- FIXME +- Added nested timelines and subproject support so that GES projects + can be used as clips, potentially serializing nested projects in the + main file or referencing external project files. + +- Implemented an OpenTimelineIO GES formatter. This means GES and + GStreamer can now load and save projects in all the formats + supported by otio. + +- Implemented a GESMarkerList object which allow setting timed + metadata on any GES object. + +- Fixed audio rendering issues during clip transition by ensuring that + a single segment is pushed into encoders. + +- The GESUriClipAsset API is now MT safe. + +- Added ges_meta_container_register_static_meta() to allow fixing a + type for a specific metadata without actually setting a value. + +- The framepositioner element now handles resizing the project and + keeps the same positioning when the aspect ratio is not changed . + +- Reworked the documentation, making it more comprehensive and much + more detailed. + +- Added APIs to retrieve natural size and framerate of a clip (for + example in the case of URIClip it is the framerate/size of the + underlying file). + +- ges_container_edit() is now deprecated and GESTimelineElement gained + the ges_timeline_element_edit() method so the editing API is now + usable from any element in the timeline. + +- GESProject::loading was added so applications can be notified about + when a new timeline starts loading. + +- Implemented the GstStream API in GESTimeline. + +- Added a way to add a timeoverlay inside the test source (potentially + with timecodes). + +- Added APIs to convert times to frame numbers and vice versa: + + - ges_timeline_get_frame_time() + + - ges_timeline_get_frame_at() + + - ges_clip_asset_get_frame_time() + + - ges_clip_get_timeline_time_from_source_frame() + + Quite a few validate tests have been implemented to check the + behavior for various demuxer/codec formats + +- Added ges_layer_set_active_for_tracks() which allows muting layers + for the specified tracks + +- Deprecated GESImageSource and GESMultiFileSource now that we have + imagesequencesrc which handles the imagesequence “protocol” + +- Stopped exposing ‘deinterlacing’ children properties for clip types + where they do not make sense. + +- Added support for simple time remapping effects GStreamer validate -- FIXME +- Introduced the concept of “Test files” allowing to implement “all + included” test cases, meaning that inside the file the following can + be defined: + + - The application arguments + - The validate configurations + - The validate scenario + + This replaces the previous big dictionary file in + gst-validate-launcher to implement specific test cases. + + We set several variables inside the files (as well as inside + scenarios and config files) to make them relocatable. + + The file format has been enhanced so it is easier to read and write, + for example line ending with a coma or (curly) brackets can now be + used as continuation marker so you do not need to add \ at the end + of lines to write a structure on several lines. + +- Support the imagesequence “protocol” and added integration tests for + it. + +- Added action types to allow the scenario to run the Test Clock for + better reproducibility of tests. + +- Support generating tests to check that seeking is frame accurate + (base on ssim). + +- Added ways to record buffers checksum (in different ways) in the + validateflow module. + +- Added vp9 encoding tests. + +- Enhanced seeking action types implementation to allow support for + segment seeks. + +- Output improvements: + + - Logs are now in markdown formats (and bat is used to dump them + if available). + - File format issues in scenarios/configs/tests files are nicely + reported with the line numbers now. GStreamer Python Bindings -- FIXME +- Python 2.x is no longer supported + +- Support mapping buffers without any memcpy: + + - Added a ContextManager to make the API more pythonic + + with buf.map(Gst.MapFlags.READ | Gst.MapFlags.WRITE) as info: + info.data[42] = 0 + +- Added high-level helper API for constructing pipelines: + + - Gst.Bin.make_and_add(factory_name, instance_name=None) + - Gst.Element.link_many(element, ...) GStreamer C# Bindings -- FIXME +- Bind gst_buffer_new_wrapped() manually to fix memory handling. -GStreamer Rust Bindings +- Fix gst_promise_new_with_change_func() where bindgen didn’t properly + detect the func as a closure. -- FIXME +- Declare GstVideoOverlayComposition and GstVideoOverlayRectangle as + opaque type and subclasses of Gst.MiniObject. This changes the API + but without this all usage will cause memory corruption or simply + not work. -GStreamer Rust Plugins +- on Windows, look for gstreamer, glib and gobject DLLs using the MSVC + naming convention (i.e. gstvideo-1.0-0.dll instead of + libgstvideo-1.0-0.dll). -- FIXME + The names of these DLLs have to be hardcoded in the bindings, and + most C# users will probably be using the Microsoft toolchain anyway. + + This means that the MSVC compiler is now required to build the + bindings, MingW will no longer work out of the box. + +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 new GStreamer 1.18 API, so there’s +absolutely no excuse why your next GStreamer application can’t be +written in Rust anymore. + +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. + +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 @@ -135,11 +1730,67 @@ Build and Dependencies - API and plugin documentation are no longer built with gtk_doc. The gtk_doc documentation has been removed in favour of a new unified - documentation module built with hotdoc. The intention is to - distribute the generated documentation in form of tarballs alongside - releases. + documentation module built with hotdoc (also see “Documentation + improvements” section below). Distributors should use the + documentation release tarball instead of trying to package hotdoc + and building the documentation from scratch. -- FIXME +- gst-plugins-bad now includes an internal copy of libusrsctp, as + there are problems in usrsctp with global shared state, lack of API + stability guarantees, and the absence of any kind of release + process. We also can’t rely on distros shipping a version with the + fixes we need. Both firefox and Chrome bundle their own copies too. + It is still possible to build against an external copy of usrsctp if + so desired. + +- nvcodec no longer needs the NVIDIA NVDEC/NVENC SDKs available at + build time, only at runtime. This allows distributions to ship this + plugin by default and it will just start to work when the required + run-time SDK libraries are installed by the user, without users + needing to build and install the plugin from source. + +- the gst-editing-services tarball is now named gst-editing-services + for consistency (used to be gstreamer-editing-services). + +- the gst-validate tarball has been superseded by the gst-devtools + tarball for consistency with the git module name. + +gst-build + +gst-build is a meta-module and serves primarily as our uninstalled +development environment. It makes it easy to build most of GStreamer, +but unlike Cerbero it only comes with a limited number of external +dependencies that can be built as subprojects if they are not found on +the system. + +gst-build is based on Meson and replaces the old autotools +gst-uninstalled script. + +- The ‘uninstalled’ target has been renamed to ‘devenv’ + +- Experimental gstreamer-full library containing all built plugins and + their deps when building with -Ddefault_library=static. A monolithic + library is easier to distribute, and may be required in some + environments. GStreamer core, GLib and GObject are always included, + but external dependencies are still dynamically linked. The + gst-full-libraries meson option allows adding other GStreamer + libraries to the gstreamer-full build. This is an experiment for now + and its behaviour or API may still change in future releases. + +- Add glib-networking as a subproject when glib is a subproject and + load gio modules in the devenv, tls option control whether to use + openssl or gnutls. + +- git-worktree: Allow multiple worktrees for subproject branches + +- Guard against meson being run from inside the uninstalled devenv, as + this might have unexpected consequences. + +- our ffmpeg and x264 meson ports have been updated to the latest + stable version (you might need to update the subprojects checkout + manually though, or just remove the checkouts so meson checks out + the latest version again; improvements for this are pending in + meson, but not merged yet). Cerbero @@ -147,29 +1798,373 @@ 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. -Cerbero has seen a number of improvements: +General improvements -- FIXME +- Recipe build steps are done in parallel wherever possible. This + leads to massive improvements in overall build time. +- Several recipes were ported to Meson, which improved build times +- Moved from using both GnuTLS and OpenSSL to only OpenSSL +- Moved from yasm to nasm for all assembly compilation +- Support zsh when running the cerbero shell command +- Numerous version upgrades for dependencies +- Default to xz for tarball binary packages. bz2 can be selected with + the --compress-method option to package. +- Added boolean variant for controlling the optimization level: + -v optimization +- Ship .pc pkgconfig files for all plugins in the binary packages +- CMake and nasm will only be built by Cerbero if the system versions + are unusable +- The nvcodec variant was removed and the nvcodec plugin is built by + default now (as it no longer requires the SDK to be installed at + build time, only at runtime) + +macOS / iOS + +- Minimum iOS SDK version bumped to 11.0 +- Minimum macOS SDK version bumped to 10.11 +- No longer need to manually add support for newer iOS SDK versions +- Added Vulkan elements via MoltenVK +- Build times were improved by code-signing all build tools +- macOS framework ships all gstreamer libraries instead of an outdated + subset +- Ship pkg-config in the macOS framework package +- fontconfig: Fix EXC_BAD_ACCESS crash on iOS ARM64 +- Improved App Store compatibility by setting LC_VERSION_MIN_MACOSX, + fixing relocations, and improved bitcode support + +Windows + +- MinGW-GCC toolchain was updated to 8.2. It uses the Universal CRT + instead of MSVCRT which eliminates cross-CRT issues in the Visual + Studio build. +- Require Windows 7 or newer for running binaries produced by Cerbero +- Require Windows x86_64 for running Cerbero to build binary packages +- Cerbero no longer uses C:/gstreamer/1.0 as a prefix when building. + That prefix is reserved for use by the MSI installers. +- Several recipes can now be buit with Visual Studio instead of MinGW. + Ported to meson: opus, libsrtp, harfbuzz, cairo, openh264, libsoup, + libusrsctp. Existing build system: libvpx, openssl. +- Support building using Visual Studio for 32-bit x86. Previously we + only supported building for 32-bit x86 using the MinGW toolchain. +- Fixed annoying msgmerge popups in the middle of cerbero builds +- Added configuration options vs_install_path and vs_install_version + for specifying custom search locations for older Visual Studio + versions that do not support vswhere. You can set these in + ~/.cerbero/cerbero.cbc where ~ is the MSYS homedir, not your Windows + homedir. +- New Windows-specific plugins: d3d11, mediafoundation, wasapi2 +- Numerous compatibility and reliability fixes when running Cerbero on + Windows, especially non-English locales +- proxy-libintl now exports the same symbols as gettext, which makes + it a drop-in replacement +- New mapping variant for selecting the Visual Studio CRT to use: + -v vscrt=. Valid values are md, mdd, and auto (default). A + separate prefix is used when building with either md (release) or + mdd (debug), and the outputted package will have +debug in the + filename. This variant is also used for selecting the correct Qt + libraries (debug vs release) to use when building with -v qt5 on + Windows. +- Support cross-compile on Windows to Windows ARM64 and ARMv7 +- Support cross-compile on Windows to the Universal Windows Platform + (UWP). Only the subset of plugins that can be built entirely with + Visual Studio will be selected in this case. To do so, use the + config/cross-uwp-universal.cbc configuration, which will build + ARM64, x86, and x86_64 binaries linked to the release CRT, with + optimizations enabled, and debugging turned on. You can combine this + with -v vscrt=mdd to produce binaries linked to the debug CRT. You + can turn off optimizations with the -v nooptimization variant. + +Windows MSI installer + +- Require Windows 7 or newer for running GStreamer +- Fixed some issues with shipping of pkg-config in the Windows + installers +- Plugin PDB debug files are now shipped in the development package, + not the runtime package +- Ship installers for 32-bit binaries built with Visual Studio +- Ship debug and release “universal” (ARM64, X86, and X86_64) tarballs + built for the Universal Windows Platform +- Windows MSI installers now install into separate prefixes when + building with MSVC and MinGW. Previously both would be installed + into C:/gstreamer/1.0/x86 or C:/gstreamer/1.0/x86_64. Now, the + installation prefixes are: + + ---------------------------------------------------------------------------------------------------------------- + Target Path Build options + --------------------------- ------------------------------------ ----------------------------------------------- + MinGW 32-bit C:/gstreamer/1.0/mingw_x86 -c config/win32.cbc + + MinGW 64-bit C:/gstreamer/1.0/mingw_x86_64 -c config/win64.cbc + + MSVC 32-bit C:/gstreamer/1.0/msvc_x86 -c config/win32.cbc -v visualstudio + + MSVC 64-bit C:/gstreamer/1.0/msvc_x86_64 -c config/win64.cbc -v visualstudio + + MSVC 32-bit (debug) C:/gstreamer/1.0/msvc-debug_x86 -c config/win32.cbc -v visualstudio,vscrt=mdd + + MSVC 64-bit (debug) C:/gstreamer/1.0/msvc-debug_x86_64 -c config/win64.cbc -v visualstudio,vscrt=mdd + ---------------------------------------------------------------------------------------------------------------- + +Note: UWP binary packages are tarballs, not MSI installers. + +Linux + +- Support creating MSI installers using WiX when cross-compiling to + Windows +- Support running cross-windows binaries with Wine when using the + shell and runit cerbero commands +- Added bash-completion support inside the cerbero shell on Linux +- Require a system-wide installation of openssl on Linux +- Added variant -v vaapi to build gstreamer-vaapi and the new gstva + plugin +- Debian packaging was disabled because it does not work. Help in + fixing this is appreciated. +- Trimmed the list of packages needed for bootstrap on Linux + +Android + +- Updated to NDK r21 +- Support Vulkan +- Support Qt 5.14+ binary package layout Platform-specific changes and improvements Android -- FIXME +- opensles: Remove hard-coded buffer-/latency-time values and allow + openslessink to handle 48kHz streams. + +- photography interface and camera source: Add additional settings + relevant to Android such as: Exposure mode property, extra colour + tone values (aqua, emboss, sketch, neon), extra scene modes + (backlight, flowers, AR, HDR), and missing virtual methods for + exposure mode, analog gain, lens focus, colour temperature, min & + max exposure time. Add new effects and scene modes to Camera + parameters. macOS and iOS -- FIXME +- vtdec can now output to Vulkan-backed memory for zerocopy support + with the Vulkan elements. Windows -- toolchain upgrade +- d3d11videosink: new Direct3D11-based video sink with support for + HDR10 rendering if supported. -- FIXME +- Hardware-accelerated video decoding on Windows via DXVA2 / + Direct3D11 using native Windows APIs rather than per-vendor SDKs + (like MSDK for Intel or NVCODEC for NVidia). Plus modern Direct3D11 + integration rather than the almost 20-year old Direct3D9 from + Windows XP times used in d3dvideosink. Formats supported for + decoding are H.264, H.265, VP8, and VP9, and zero-copy operation + should be supported in combination with the new d3d11videosink. See + Seungha’s blog post “Windows DXVA2 (via Direct3D 11) Support in + GStreamer 1.17” for more details. + +- Microsoft Media Foundation plugin for hardware-accelerated video + encoding on Windows using native Windows APIs rather than per-vendor + SDKs. Formats supported for encoding are H.264, H.265 and VP9. Also + includes audio encoders for AAC and MP3. See Seungha’s blog post + “Bringing Microsoft Media Foundation to GStreamer” for some more + details about this. + +- new mfvideosrc video capture source element using the latest Windows + APIs rather than ancient APIs used by ksvideosrc/winks. ksvideosrc + should be considered deprecated going forward. + +- d3d11: add d3d11convert, a color space conversion and rescaling + element using shaders, and introduce d3d11upload and d3d11download + elements that work just like glupload and gldownload but for D3D11. + +- Universal Windows Platform (UWP) support, including official + GStreamer binary packages for it. Check out Nirbheek’s latest blog + post “GStreamer 1.18 supports the Universal Windows Platform” for + more details. + +- systemclock correctness and reliability fixes, and also don’t start + the system clock at 0 any longer (which shouldn’t make any + difference to anyone, as absolute clock time values are supposed to + be meaningless in themselves, only the rate of increase matters). + +- toolchain specific plugin registry: the registry cache is now named + differently for MSVC and MinGW toolchains/packages, which should + avoid problems when switching between binaries built with a + different toolchain. + +- new wasapi2 plugin mainly to support UWP applications. The core + logic of this plugin is almost identical to existing wasapi plugin, + but the main target is Windows 10 and UWP. This plugin uses WinRT + APIs, so will likely not work on Windows 8 or older. Unlike the + existing wasapi plugin, this plugin supports automatic stream + routing (auto fallback when device was removed) and device level + mute/volume control. Exclusive streaming mode is not supported, + however, and loopback features are not implemented yet. It is also + only possible to build this plugin with MSVC and the Windows 10 SDK, + it can’t be cross-compiled with the MingW toolchain. + +- new dxgiscreencapsrc element which uses the Desktop Duplication API + to capture the desktop screen at high speed. This is only supported + on Windows 8 or later. Compared to the existing elements + dxgiscreencapsrc offers much better performance, works in High DPI + environments and draws an accurate mouse cursor. + +- d3dvideosink was downgraded to secondary rank, d3d11videosink is + preferred now. Support OverlayComposition for GPU overlay + compositing of subtitles and logos. + +- debug log output fixes, esp. with a non-UTF8 locale/codepage + +- speex, jack: fixed crashes on Windows caused by cross-CRT issues + +- gst-play-1.0 interactive keyboard controls now also work on Windows + +Linux + +- kmssink: Add support for P010 and P016 formats + +- vah264dec: new experimental va plugin with an element for H.264 + decoding with VA-API. This novel approach, different from + gstreamer-vaapi, uses the gstcodecs library for decoder state + handling, which it is hoped will make for cleaner code because it + uses VA-API without further layers or wrappers. Check out Víctor’s + blog post “New VA-API H.264 decoder in gst-plugins-bad” for the full + lowdown and the limitations of this new plugin, and how to give it a + spin. + +- v4l2codecs: introduce a V4L2 CODECs Accelerator. This plugin will + support the new CODECs uAPI in the Linux kernel, which consists of + an accelerator interface similar to DXVA, NVDEC, VDPAU and VAAPI. So + far H.264 and VP8 are supported. This is used on certain embedded + systems such as i.mx8m, rk3288, rk3399, Allwinner H-series SoCs. + +Documentation improvements + +- unified documentation containing tutorials, API docs, plugin docs, + etc. all under one roof, shipped in form of a documentation release + tarball containing both devhelp and html documentation. + +- all documentation is now generated using hotdoc, gtk-doc is no + longer used. Distributors should use the above-mentioned + documentation release tarball instead of trying to package hotdoc + and building the documentation from scratch. + +- there is now documentation for wrapper plugins like gst-libav and + frei0r, as well as tracer plugins. + +- for more info, check out Thibault’s “GStreamer Documentation” + lightning talk from the 2019 GStreamer Conference. + +- new API for plugins to support the documentation system: + + - new GParamSpecFlag GST_PARAM_DOC_SHOW_DEFAULT to make + gst-inspect-1.0 (and the documentation) show the paramspec’s + default value rather than the actually set value as default + - GstPadTemplate getter and setter for “documentation caps”, + gst_pad_template_set_documentation_caps() and + gst_pad_template_get_documentation_caps(): This can be used in + elements where the caps of pad templates are dynamically + generated and/or dependent on the environment, to override the + caps shown in the documentation (usually to advertise the full + set of possible caps). + - gst_type_mark_as_plugin_api() for marking types as plugin API, + used for plugin-internal types like enums, flags, pad + subclasses, boxed types, and such. + +Possibly Breaking Changes + +- GstVideo: the canonical list of raw video formats (for use in caps) + has been reordered, so video elements such as videotestsrc or + videoconvert might negotiate to a different format now than before. + The new format might be a higher-quality format or require more + processing overhead, which might affect pipeline performance. + +- mpegtsdemux used to wrongly advertise H.264 and H.265 video + elementary streams as alignment=nal. This has now been fixed and + changed to alignment=none, which means an h264parse or h265parse + element is now required after tsdemux for some pipelines where there + wasn’t one before, e.g. in transmuxing scenarios (tsdemux ! tsmux). + Pipelines without such a parser may now fail to link or error out at + runtime. As parsers after demuxers and before muxers have been + generally required for a long time now it is hoped that this will + only affect a small number of applications or pipelines. + +- The Android opensles audio source and sink used to have hard-coded + buffer-/latency-time values of 20ms. This is no longer needed with + newer Android versions and has now been removed. This means a higher + or lower value might now be negotiated by default, which can affect + pipeline performance and latency. + +Known Issues + +- None in particular Contributors -- FIXME +Aaron Boxer, Adam Duskett, Adam x Nilsson, Adrian Negreanu, Akinobu +Mita, Alban Browaeys, Alcaro, Alexander Lapajne, Alexandru Băluț, Alex +Ashley, Alex Hoenig, Alicia Boya García, Alistair Buxton, Ali Yousuf, +Ambareesh “Amby” Balaji, Amr Mahdi, Andoni Morales Alastruey, Andreas +Frisch, Andre Guedes, Andrew Branson, Andrey Sazonov, Antonio Ospite, +aogun, Arun Raghavan, Askar Safin, AsociTon, A. Wilcox, Axel Mårtensson, +Ayush Mittal, Bastian Bouchardon, Benjamin Otte, Bilal Elmoussaoui, +Brady J. Garvin, Branko Subasic, Camilo Celis Guzman, Carlos Rafael +Giani, Charlie Turner, Cheng-Chang Wu, Chris Ayoup, Chris Lord, +Christoph Reiter, cketti, Damian Hobson-Garcia, Daniel Klamt, Daniel +Molkentin, Danny Smith, David Bender, David Gunzinger, David Ing, David +Svensson Fors, David Trussel, Debarshi Ray, Derek Lesho, Devarsh +Thakkar, dhilshad, Dimitrios Katsaros, Dmitriy Purgin, Dmitry Shusharin, +Dominique Leuenberger, Dong Il Park, Doug Nazar, dudengke, Dylan McCall, +Dylan Yip, Ederson de Souza, Edward Hervey, Eero Nurkkala, Eike Hein, +ekwange, Eric Marks, Fabian Greffrath, Fabian Orccon, Fabio D’Urso, +Fabrice Bellet, Fabrice Fontaine, Fanchao L, Felix Yan, Fernando +Herrrera, Francisco Javier Velázquez-García, Freyr, Fuwei Tang, Gaurav +Kalra, George Kiagiadakis, Georgii Staroselskii, Georg Lippitsch, Georg +Ottinger, gla, Göran Jönsson, Gordon Hart, Gregor Boirie, Guillaume +Desmottes, Guillermo Rodríguez, Haakon Sporsheim, Haihao Xiang, Haihua +Hu, Havard Graff, Håvard Graff, Heinrich Kruger, He Junyan, Henry +Wilkes, Hosang Lee, Hou Qi, Hu Qian, Hyunjun Ko, ibauer, Ignacio Casal +Quinteiro, Ilya Smelykh, Jake Barnes, Jakub Adam, James Cowgill, James +Westman, Jan Alexander Steffens, Jan Schmidt, Jan Tojnar, Javier Celaya, +Jeffy Chen, Jennifer Berringer, Jens Göpfert, Jérôme Laheurte, Jim +Mason, Jimmy Ohn, J. Kim, Joakim Johansson, Jochen Henneberg, Johan +Bjäreholt, Johan Sternerup, John Bassett, Jonas Holmberg, Jonas Larsson, +Jonathan Matthew, Jordan Petridis, Jose Antonio Santos Cadenas, Josep +Torra, Jose Quaresma, Josh Matthews, Joshua M. Doe, Juan Navarro, +Juergen Werner, Julian Bouzas, Julien Isorce, Jun-ichi OKADA, Justin +Chadwell, Justin Kim, Keri Henare, Kevin JOLY, Kevin King, Kevin Song, +Knut Andre Tidemann, Kristofer Björkström, krivoguzovVlad, Kyrylo +Polezhaiev, Lenny Jorissen, Linus Svensson, Loïc Le Page, Loïc Minier, +Lucas Stach, Ludvig Rappe, Luka Blaskovic, luke.lin, Luke Yelavich, +Marcin Kolny, Marc Leeman, Marco Felsch, Marcos Kintschner, Marek +Olejnik, Mark Nauwelaerts, Markus Ebner, Martin Liska, Martin Theriault, +Mart Raudsepp, Matej Knopp, Mathieu Duponchelle, Mats Lindestam, Matthew +Read, Matthew Waters, Matus Gajdos, Maxim Paymushkin, Maxim P. +Dementiev, Michael Bunk, Michael Gruner, Michael Olbrich, Miguel París +Díaz, Mikhail Fludkov, Milian Wolff, Millan Castro, Muhammet Ilendemli, +Nacho García, Nayana Topolsky, Nian Yan, Nicola Murino, Nicolas +Dufresne, Nicolas Pernas Maradei, Niels De Graef, Nikita Bobkov, Niklas +Hambüchen, Nirbheek Chauhan, Ognyan Tonchev, okuoku, Oleksandr +Kvl,Olivier Crête, Ondřej Hruška, Pablo Marcos Oltra, Patricia Muscalu, +Peter Seiderer, Peter Workman, Philippe Normand, Philippe Renon, Philipp +Zabel, Pieter Willem Jordaan, Piotr Drąg, Ralf Sippl, Randy Li, Rasmus +Thomsen, Ratchanan Srirattanamet, Raul Tambre, Ray Tiley, Richard +Kreckel, Rico Tzschichholz, R Kh, Robert Rosengren, Robert Tiemann, +Roman Shpuntov, Roman Sivriver, Ruben Gonzalez, Rubén Gonzalez, +rubenrua, Ryan Huang, Sam Gigliotti, Santiago Carot-Nemesio, Saunier +Thibault, Scott Kanowitz, Sebastian Dröge, Sebastiano Barrera, Seppo +Yli-Olli, Sergey Nazaryev, Seungha Yang, Shinya Saito, Silvio +Lazzeretti, Simon Arnling Bååth, Siwon Kang, sohwan.park, Song Bing, +Soohyun Lee, Srimanta Panda, Stefano Buora, Stefan Sauer, Stéphane +Cerveau, Stian Selnes, Sumaid Syed, Swayamjeet, Thiago Santos, Thibault +Saunier, Thomas Bluemel, Thomas Coldrick, Thor Andreassen, Tim-Philipp +Müller, Ting-Wei Lan, Tobias Ronge, trilene, Tulio Beloqui, U. Artie +Eoff, VaL Doroshchuk, Varunkumar Allagadapa, Vedang Patel, Veerabadhran +G, Víctor Manuel Jáquez Leal, Vivek R, Vivia Nikolaidou, Wangfei, Wang +Zhanjun, Wim Taymans, Wonchul Lee, Xabier Rodriguez Calvar, Xavier +Claessens, Xidorn Quan, Xu Guangxin, Yan Wang, Yatin Maan, Yeongjin +Jeong, yychao, Zebediah Figura, Zeeshan Ali, Zeid Bekli, Zhiyuan Sraf, +Zoltán Imets, … and many others who have contributed bug reports, translations, sent suggestions or helped testing. @@ -184,11 +2179,7 @@ the git 1.18 branch, which will be a stable branch. 1.18.0 -1.18.0 has not been released yet. - -Known Issues - -- FIXME +1.18.0 was released on 7 September 2020. Schedule for 1.20 @@ -196,7 +2187,9 @@ Our next major feature release will be 1.20, and 1.19 will be the unstable development version leading up to the stable 1.20 release. The development of 1.19/1.20 will happen in the git master branch. -The plan for the 1.20 development cycle is yet to be confirmed. +The plan for the 1.20 development cycle is yet to be confirmed, but it +is now expected that feature freeze will take place some time in January +2021, with the first 1.20 stable release around February/March 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. @@ -204,6 +2197,8 @@ The plan for the 1.20 development cycle is yet to be confirmed. ------------------------------------------------------------------------ These release notes have been prepared by Tim-Philipp Müller with -contributions from … (FIXME) +contributions from Mathieu Duponchelle, Matthew Waters, Nirbheek +Chauhan, Sebastian Dröge, Thibault Saunier, and Víctor Manuel Jáquez +Leal. License: CC BY-SA 4.0 diff --git a/RELEASE b/RELEASE index baefb99fe5..9c9bd3eeb5 100644 --- a/RELEASE +++ b/RELEASE @@ -1,13 +1,16 @@ -This is GStreamer gstreamer-vaapi 1.17.90. +This is GStreamer gstreamer-vaapi 1.18.0. -GStreamer 1.17 is the development branch leading up to the next major -stable version which will be 1.18. +The GStreamer team is thrilled to announce a new major feature release +of your favourite cross-platform multimedia framework! -The 1.17 development series adds new features on top of the 1.16 series and is +As always, this release is again packed with new features, bug fixes and +other improvements. + +The 1.18 release series adds new features on top of the 1.16 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: +Full release notes can be found at: https://gstreamer.freedesktop.org/releases/1.18/ diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 6ead4e4113..f988ce0447 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.18.0 + master + + 2020-09-08 + + + + 1.17.90 diff --git a/meson.build b/meson.build index b4351707c3..4092e9fce6 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.17.90', + version : '1.18.0', meson_version : '>= 0.48.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From ff5b20456175798567a0bf644db51c4f01ad2980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 8 Sep 2020 16:59:07 +0100 Subject: [PATCH 3726/3781] Back to development --- meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 4092e9fce6..638d9252de 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('gstreamer-vaapi', 'c', - version : '1.18.0', - meson_version : '>= 0.48.0', + version : '1.19.0.1', + meson_version : '>= 0.54', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 0818af088b8418b4d69ed1fa745f6958d13cb9d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 8 Sep 2020 17:31:02 +0100 Subject: [PATCH 3727/3781] ci: include template from gst-ci master branch again --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 944ad035e4..c61aa7a529 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1 +1 @@ -include: "https://gitlab.freedesktop.org/gstreamer/gst-ci/raw/1.18/gitlab/ci_template.yml" +include: "https://gitlab.freedesktop.org/gstreamer/gst-ci/raw/master/gitlab/ci_template.yml" From 629154642f99fad7eb5bb8750979f4a64c10166d Mon Sep 17 00:00:00 2001 From: Marc Leeman Date: Tue, 1 Sep 2020 09:31:33 +0200 Subject: [PATCH 3728/3781] vaapisink: when updating the caps, reset rotation When an element upstream changes settings (e.g. crop), new caps are sent to vaapisink. When vaapisink was rotating the image, it needs to re-evaluate if the sink needs to rotate the image. Part-of: --- gst/vaapi/gstvaapisink.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index 2d7824e962..e722b71307 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -1401,6 +1401,9 @@ gst_vaapisink_set_caps (GstBaseSink * base_sink, GstCaps * caps) update_colorimetry (sink, &GST_VIDEO_INFO_COLORIMETRY (vip)); gst_caps_replace (&sink->caps, caps); + /* Reset the rotation to the default when new caps are coming in. This + * forces re-evaluating if the rotation needs to be done */ + sink->rotation = DEFAULT_ROTATION; gst_vaapisink_ensure_colorbalance (sink); gst_vaapisink_ensure_rotation (sink, FALSE); From 6305acc9d381a11f6fcc9a820db2db5235a13e19 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 15 Sep 2020 00:11:30 +0800 Subject: [PATCH 3729/3781] plugins: decode: fix a DMA caps typo in ensure_allowed_srcpad_caps. Part-of: --- gst/vaapi/gstvaapidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b777847c6a..9e8aa26415 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -273,7 +273,7 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) && gst_vaapi_mem_type_supports (mem_types, GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF)) { dma_caps = gst_caps_copy (base_caps); - gst_caps_set_features_simple (va_caps, + gst_caps_set_features_simple (dma_caps, gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF)); } #if (USE_GLX || USE_EGL) From 27427c00c0c4f240ff0cce877eb52759292cd89c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sun, 20 Sep 2020 09:56:40 +0200 Subject: [PATCH 3730/3781] decoder: don't reply src caps query with allowed if pad is fixed If the pad is already fixed the caps query have to be reply with the current fixed caps. Otherwise the query has to be replied with the autogeneratd src caps. This path fix this by falling back to the normal caps query processing if the pad is already fixed. Otherwise it will fetch the allowed src pad caps. Part-of: --- gst/vaapi/gstvaapidecode.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9e8aa26415..329c0e65c6 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1437,26 +1437,32 @@ gst_vaapidecode_src_query (GstVideoDecoder * vdec, GstQuery * query) GstElement *const element = GST_ELEMENT (vdec); switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_CAPS:{ - GstCaps *caps, *filter = NULL; - - gst_query_parse_caps (query, &filter); - caps = gst_vaapidecode_get_allowed_srcpad_caps (GST_VAAPIDECODE (vdec)); - - if (filter) { - GstCaps *tmp = caps; - caps = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (tmp); - } - - gst_query_set_caps_result (query, caps); - gst_caps_unref (caps); - break; - } case GST_QUERY_CONTEXT:{ ret = gst_vaapi_handle_context_query (element, query); break; } + case GST_QUERY_CAPS:{ + GstCaps *caps, *filter = NULL; + gboolean fixed_caps; + + fixed_caps = GST_PAD_IS_FIXED_CAPS (GST_VIDEO_DECODER_SRC_PAD (vdec)); + if (!fixed_caps) { + gst_query_parse_caps (query, &filter); + caps = gst_vaapidecode_get_allowed_srcpad_caps (GST_VAAPIDECODE (vdec)); + + if (filter) { + GstCaps *tmp = caps; + caps = + gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (tmp); + } + + gst_query_set_caps_result (query, caps); + gst_caps_unref (caps); + break; + } + /* else jump to default */ + } default:{ ret = GST_VIDEO_DECODER_CLASS (parent_class)->src_query (vdec, query); break; From 08b4aaa7fa821d163d5f35aead668be8053686b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 19 Oct 2020 13:42:53 +0200 Subject: [PATCH 3731/3781] libs: decoder: vp9: avoid reference rewriting The removed code set all the reference frames to the current frame it is a key one, but later, all the reference frames were rewritten with the decoded picture buffers or VA_INVALID_SURFACE if they were not available. Basically, all this time the first reference frame assignment has been ignored, and it's not described by the spec, and this patch removes that code. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 0f6a300fbd..134a031760 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -303,11 +303,7 @@ vaapi_fill_ref_frames (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture, GstVaapiDecoderVp9Private *const priv = &decoder->priv; guint i; - if (frame_hdr->frame_type == GST_VP9_KEY_FRAME) { - for (i = 0; i < G_N_ELEMENTS (priv->ref_frames); i++) - pic_param->reference_frames[i] = picture->surface_id; - - } else { + 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 = @@ -321,6 +317,7 @@ vaapi_fill_ref_frames (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture, 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; From 865a46b193e7e83030f2c73e8366e4240ae26551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 19 Oct 2020 13:46:44 +0200 Subject: [PATCH 3732/3781] libs: decoder: vp9: 0xff segment pred probs if no temporal update According to the spec (6.2.11 Segmentation params syntax) segmentation_pred_prob[i] ast to be 0xff if not temporal_update. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_vp9.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c index 134a031760..3862cc26c2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c @@ -383,8 +383,14 @@ fill_picture (GstVaapiDecoderVp9 * decoder, GstVaapiPicture * picture) memcpy (pic_param->mb_segment_tree_probs, parser->mb_segment_tree_probs, sizeof (parser->mb_segment_tree_probs)); - memcpy (pic_param->segment_pred_probs, parser->segment_pred_probs, - sizeof (parser->segment_pred_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; } From d72f8180295088690ead7fd1c2ed6d0294c74e51 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 17 Sep 2020 15:35:11 +0800 Subject: [PATCH 3733/3781] libs: utils: h265: Use get_profile_from_sps to get profile. We now use gst_h265_get_profile_from_sps() to replace the old way of gst_h265_profile_tier_level_get_profile() to get more precise profile. The new function consider the unstandard cases and give a more suitable profile decision. Part-of: --- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index b912075789..189f256e6b 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -146,7 +146,7 @@ gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) g_return_val_if_fail (sps != NULL, GST_VAAPI_PROFILE_UNKNOWN); - profile = gst_h265_profile_tier_level_get_profile (&sps->profile_tier_level); + profile = gst_h265_get_profile_from_sps (sps); switch (profile) { case GST_H265_PROFILE_MAIN: /* Main Intra, recognize it as MAIN */ From ed9a70839787dfbaf252d43804805c3f06d93ae4 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 17 Sep 2020 16:47:43 +0800 Subject: [PATCH 3734/3781] libs: decoder: h265: fill missing predictor_palette_size field. The predictor_palette_size of VAPictureParameterBufferHEVCScc is forgotten and need to be filled when streams have palettes. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 6ec0f5ca0a..fcbe5ce71b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -2121,11 +2121,15 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) num_comps = sps->chroma_format_idc ? 3 : 1; if (pps_scc->pps_palette_predictor_initializers_present_flag) { + pic_scc_param->predictor_palette_size = + pps_scc->pps_num_palette_predictor_initializer; for (n = 0; n < num_comps; n++) for (i = 0; i < pps_scc->pps_num_palette_predictor_initializer; i++) pic_scc_param->predictor_palette_entries[n][i] = (uint16_t) pps_scc->pps_palette_predictor_initializer[n][i]; } else if (sps_scc->sps_palette_predictor_initializers_present_flag) { + pic_scc_param->predictor_palette_size = + sps_scc->sps_num_palette_predictor_initializer_minus1 + 1; for (n = 0; n < num_comps; n++) for (i = 0; i < sps_scc->sps_num_palette_predictor_initializer_minus1 + 1; i++) From 92b30ffa1a2f3b6559d834fcfb96314a05a173d6 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 30 Jul 2020 23:13:10 +0800 Subject: [PATCH 3735/3781] video-format: Add Y412_LE format. It can be used as HEVC YUV_4:4:4 12bits stream's decoder output, and also can be used as the input format for encoding HEVC YUV_4:4:4 12bits stream. Part-of: --- gst-libs/gst/vaapi/gstvaapiimage.c | 3 +++ gst-libs/gst/vaapi/video-format.c | 1 + gst-libs/gst/vaapi/video-format.h | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index 34baf40385..ef35a0b2cf 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -104,6 +104,9 @@ vaapi_image_is_linear (const VAImage * va_image) case VA_FOURCC ('4', '4', '4', 'P'): data_size = 3 * width * height; break; + case VA_FOURCC ('Y', '4', '1', '2'): + data_size = 8 * width * height; + break; default: GST_ERROR ("FIXME: incomplete formats %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (va_image->format.fourcc)); diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index 310cbeffaf..d189b6fd49 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -112,6 +112,7 @@ static const GstVideoFormatMap gst_vaapi_video_default_formats[] = { DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y210, Y210, ('Y', '2', '1', '0'), 32, 422_10BPP), DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y410, Y410, ('Y', '4', '1', '0'), 32, 444_10BPP), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y412_LE, Y412, ('Y', '4', '1', '2'), 32, 444_12BPP), /* RGB formats */ DEF_RGB (VA_LSB_FIRST, ARGB, BGRA8888, ('A', 'R', 'G', 'B'), 32, 32, 0x0000ff00, diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index 9f23959b84..1882164b31 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -30,7 +30,7 @@ G_BEGIN_DECLS #define GST_VAAPI_FORMATS_ALL "{ ENCODED, " \ - "NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, P012_LE, VUYA, Y210, Y410, " \ + "NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, P012_LE, VUYA, Y210, Y410, Y412_LE, " \ "ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE " \ "}" From 8af9b4674882fed0100c5f553f458da2c9e16ce9 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 30 Jul 2020 23:21:06 +0800 Subject: [PATCH 3736/3781] libs: decoder: H265: Add MAIN_444_12 profile supporting. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 3 ++- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 ++ gst-libs/gst/vaapi/gstvaapiprofile.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_h265.c | 8 ++++++++ gst-libs/gst/vaapi/video-format.c | 2 ++ gst/vaapi/gstvaapidecode.c | 3 ++- 6 files changed, 17 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index fcbe5ce71b..992c0c023c 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -533,7 +533,8 @@ is_range_extension_profile (GstVaapiProfile profile) if (profile == GST_VAAPI_PROFILE_H265_MAIN_422_10 || profile == GST_VAAPI_PROFILE_H265_MAIN_444 || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10 - || profile == GST_VAAPI_PROFILE_H265_MAIN12) + || profile == GST_VAAPI_PROFILE_H265_MAIN12 + || profile == GST_VAAPI_PROFILE_H265_MAIN_444_12) return TRUE; return FALSE; } diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index cbf2db5703..0a53897286 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -130,6 +130,8 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h265", "main-444-10"}, {GST_VAAPI_PROFILE_H265_MAIN12, VAProfileHEVCMain12, "video/x-h265", "main-12"}, + {GST_VAAPI_PROFILE_H265_MAIN_444_12, VAProfileHEVCMain444_12, + "video/x-h265", "main-444-12"}, {GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN, VAProfileHEVCSccMain, "video/x-h265", "screen-extended-main"}, {GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10, VAProfileHEVCSccMain10, diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 3ba23f69c4..38ec59ab71 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -190,6 +190,7 @@ typedef enum { GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10 = GST_VAAPI_MAKE_PROFILE(H265,10), GST_VAAPI_PROFILE_H265_MAIN12 = GST_VAAPI_MAKE_PROFILE(H265,11), + GST_VAAPI_PROFILE_H265_MAIN_444_12 = GST_VAAPI_MAKE_PROFILE(H265,12), GST_VAAPI_PROFILE_VP9_0 = GST_VAAPI_MAKE_PROFILE(VP9,1), GST_VAAPI_PROFILE_VP9_1 = GST_VAAPI_MAKE_PROFILE(VP9,2), GST_VAAPI_PROFILE_VP9_2 = GST_VAAPI_MAKE_PROFILE(VP9,3), diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 189f256e6b..44973a01d2 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -181,6 +181,11 @@ gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) case GST_H265_PROFILE_MAIN_444_10_INTRA: vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_444_10; break; + case GST_H265_PROFILE_MAIN_444_12: + /* Main 444_12 Intra, recognize it as MAIN_444_12 */ + case GST_H265_PROFILE_MAIN_444_12_INTRA: + vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_444_12; + break; case GST_H265_PROFILE_SCREEN_EXTENDED_MAIN: vaapi_profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN; break; @@ -375,6 +380,8 @@ gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444; else if (depth > 8 && depth <= 10) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_10BPP; + else if (depth > 10 && depth <= 12) + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_12BPP; break; default: break; @@ -407,6 +414,7 @@ gst_vaapi_utils_h265_get_chroma_format_idc (GstVaapiChromaType chroma_type) break; case GST_VAAPI_CHROMA_TYPE_YUV444: case GST_VAAPI_CHROMA_TYPE_YUV444_10BPP: + case GST_VAAPI_CHROMA_TYPE_YUV444_12BPP: chroma_format_idc = 3; break; default: diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index d189b6fd49..fc81407fcd 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -467,6 +467,8 @@ gst_vaapi_video_format_from_chroma (guint chroma_type) return GST_VIDEO_FORMAT_Y210; case GST_VAAPI_CHROMA_TYPE_YUV444_10BPP: return GST_VIDEO_FORMAT_Y410; + case GST_VAAPI_CHROMA_TYPE_YUV444_12BPP: + return GST_VIDEO_FORMAT_Y412_LE; default: return GST_VIDEO_FORMAT_UNKNOWN; } diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 329c0e65c6..4be8118e26 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1302,7 +1302,8 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) || profile == GST_VAAPI_PROFILE_H265_MAIN_422_10 || profile == GST_VAAPI_PROFILE_H265_MAIN_444 || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10 - || profile == GST_VAAPI_PROFILE_H265_MAIN12) { + || profile == GST_VAAPI_PROFILE_H265_MAIN12 + || profile == GST_VAAPI_PROFILE_H265_MAIN_444_12) { gchar *profiles[3], *intra_name; intra_name = g_strdup_printf ("%s-intra", profile_name); From ec68ec518bc780d394efaa368281a034a71851de Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 31 Jul 2020 14:38:42 +0800 Subject: [PATCH 3737/3781] video-format: Add Y212_LE format. It can be used as HEVC YUV_4:2:2 12bits stream's decoder output, and also can be used as the input format for encoding HEVC YUV_4:2:2 12bits stream. Part-of: --- gst-libs/gst/vaapi/gstvaapiimage.c | 1 + gst-libs/gst/vaapi/video-format.c | 1 + gst-libs/gst/vaapi/video-format.h | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index ef35a0b2cf..18389adf7b 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -94,6 +94,7 @@ vaapi_image_is_linear (const VAImage * va_image) case VA_FOURCC ('Y', '2', '1', '0'): case VA_FOURCC ('Y', '4', '1', '0'): case VA_FOURCC ('A', 'R', '3', '0'): + case VA_FOURCC ('Y', '2', '1', '2'): data_size = 4 * width * height; break; case VA_FOURCC ('P', '0', '1', '0'): diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index fc81407fcd..dc32d5f6e6 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -112,6 +112,7 @@ static const GstVideoFormatMap gst_vaapi_video_default_formats[] = { DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y210, Y210, ('Y', '2', '1', '0'), 32, 422_10BPP), DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y410, Y410, ('Y', '4', '1', '0'), 32, 444_10BPP), + DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y212_LE, Y212, ('Y', '2', '1', '2'), 32, 422_12BPP), DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y412_LE, Y412, ('Y', '4', '1', '2'), 32, 444_12BPP), /* RGB formats */ diff --git a/gst-libs/gst/vaapi/video-format.h b/gst-libs/gst/vaapi/video-format.h index 1882164b31..22e14fbfd8 100644 --- a/gst-libs/gst/vaapi/video-format.h +++ b/gst-libs/gst/vaapi/video-format.h @@ -30,7 +30,7 @@ G_BEGIN_DECLS #define GST_VAAPI_FORMATS_ALL "{ ENCODED, " \ - "NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, P012_LE, VUYA, Y210, Y410, Y412_LE, " \ + "NV12, YV12, I420, YUY2, UYVY, Y444, GRAY8, P010_10LE, P012_LE, VUYA, Y210, Y410, Y212_LE, Y412_LE, " \ "ARGB, xRGB, RGBA, RGBx, ABGR, xBGR, BGRA, BGRx, RGB16, RGB, BGR10A2_LE " \ "}" From d94b8644283b62d64124ea7b607ccc1c7878263e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 17 Jul 2020 18:00:30 +0800 Subject: [PATCH 3738/3781] libs: decoder: H265: Add MAIN_422_12 profile supporting. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 3 ++- gst-libs/gst/vaapi/gstvaapiprofile.c | 2 ++ gst-libs/gst/vaapi/gstvaapiprofile.h | 1 + gst-libs/gst/vaapi/gstvaapiutils_h265.c | 8 ++++++++ gst-libs/gst/vaapi/video-format.c | 2 ++ gst/vaapi/gstvaapidecode.c | 3 ++- 6 files changed, 17 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 992c0c023c..e725995e7f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -534,7 +534,8 @@ is_range_extension_profile (GstVaapiProfile profile) || profile == GST_VAAPI_PROFILE_H265_MAIN_444 || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10 || profile == GST_VAAPI_PROFILE_H265_MAIN12 - || profile == GST_VAAPI_PROFILE_H265_MAIN_444_12) + || profile == GST_VAAPI_PROFILE_H265_MAIN_444_12 + || profile == GST_VAAPI_PROFILE_H265_MAIN_422_12) return TRUE; return FALSE; } diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 0a53897286..5a2e1c0526 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -132,6 +132,8 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-h265", "main-12"}, {GST_VAAPI_PROFILE_H265_MAIN_444_12, VAProfileHEVCMain444_12, "video/x-h265", "main-444-12"}, + {GST_VAAPI_PROFILE_H265_MAIN_422_12, VAProfileHEVCMain422_12, + "video/x-h265", "main-422-12"}, {GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN, VAProfileHEVCSccMain, "video/x-h265", "screen-extended-main"}, {GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10, VAProfileHEVCSccMain10, diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 38ec59ab71..3255fe53b3 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -191,6 +191,7 @@ typedef enum { GST_VAAPI_MAKE_PROFILE(H265,10), GST_VAAPI_PROFILE_H265_MAIN12 = GST_VAAPI_MAKE_PROFILE(H265,11), GST_VAAPI_PROFILE_H265_MAIN_444_12 = GST_VAAPI_MAKE_PROFILE(H265,12), + GST_VAAPI_PROFILE_H265_MAIN_422_12 = GST_VAAPI_MAKE_PROFILE(H265,13), GST_VAAPI_PROFILE_VP9_0 = GST_VAAPI_MAKE_PROFILE(VP9,1), GST_VAAPI_PROFILE_VP9_1 = GST_VAAPI_MAKE_PROFILE(VP9,2), GST_VAAPI_PROFILE_VP9_2 = GST_VAAPI_MAKE_PROFILE(VP9,3), diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index 44973a01d2..e94f9937d5 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -171,6 +171,11 @@ gst_vaapi_utils_h265_get_profile (GstH265SPS * sps) case GST_H265_PROFILE_MAIN_422_10_INTRA: vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_422_10; break; + case GST_H265_PROFILE_MAIN_422_12: + /* Main 422_12 Intra, recognize it as MAIN_422_12 */ + case GST_H265_PROFILE_MAIN_422_12_INTRA: + vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_422_12; + break; case GST_H265_PROFILE_MAIN_444: /* Main 444 Intra, recognize it as MAIN_444 */ case GST_H265_PROFILE_MAIN_444_INTRA: @@ -374,6 +379,8 @@ gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc, chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422; else if (depth > 8 && depth <= 10) chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_10BPP; + else if (depth > 10 && depth <= 12) + chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_12BPP; break; case 3: if (depth == 8) @@ -410,6 +417,7 @@ gst_vaapi_utils_h265_get_chroma_format_idc (GstVaapiChromaType chroma_type) break; case GST_VAAPI_CHROMA_TYPE_YUV422: case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: + case GST_VAAPI_CHROMA_TYPE_YUV422_12BPP: chroma_format_idc = 2; break; case GST_VAAPI_CHROMA_TYPE_YUV444: diff --git a/gst-libs/gst/vaapi/video-format.c b/gst-libs/gst/vaapi/video-format.c index dc32d5f6e6..dad7570c2e 100644 --- a/gst-libs/gst/vaapi/video-format.c +++ b/gst-libs/gst/vaapi/video-format.c @@ -470,6 +470,8 @@ gst_vaapi_video_format_from_chroma (guint chroma_type) return GST_VIDEO_FORMAT_Y410; case GST_VAAPI_CHROMA_TYPE_YUV444_12BPP: return GST_VIDEO_FORMAT_Y412_LE; + case GST_VAAPI_CHROMA_TYPE_YUV422_12BPP: + return GST_VIDEO_FORMAT_Y212_LE; default: return GST_VIDEO_FORMAT_UNKNOWN; } diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4be8118e26..7e60240814 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -1303,7 +1303,8 @@ gst_vaapidecode_ensure_allowed_sinkpad_caps (GstVaapiDecode * decode) || profile == GST_VAAPI_PROFILE_H265_MAIN_444 || profile == GST_VAAPI_PROFILE_H265_MAIN_444_10 || profile == GST_VAAPI_PROFILE_H265_MAIN12 - || profile == GST_VAAPI_PROFILE_H265_MAIN_444_12) { + || profile == GST_VAAPI_PROFILE_H265_MAIN_444_12 + || profile == GST_VAAPI_PROFILE_H265_MAIN_422_12) { gchar *profiles[3], *intra_name; intra_name = g_strdup_printf ("%s-intra", profile_name); From ba58557c140f5bb2155e1b73252ea779de23130b Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 30 Nov 2020 18:00:30 +0800 Subject: [PATCH 3739/3781] libs: decoder: H265: Fix a typo in scc reference setting. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index e725995e7f..ad2588857b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -1737,7 +1737,7 @@ init_picture_refs (GstVaapiDecoderH265 * decoder, if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag && !ref_pic_list_modification->ref_pic_list_modification_flag_l0 && (NumRpsCurrTempList0 > num_ref_idx_l0_active_minus1 + 1)) - priv->RefPicList0[rIdx++] = picture; + priv->RefPicList0[num_ref_idx_l0_active_minus1] = picture; priv->RefPicList0_count = rIdx; if (type == GST_H265_B_SLICE) { From 973b879f95588581d860ade43a348d7cd73a9346 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 11 Jul 2020 23:09:59 +0800 Subject: [PATCH 3740/3781] libs: encoder: vp9: Add allowed_profiles. We need the allowed_profiles to store the allowed profiles in down stream's caps. Command line like: vaapivp9enc ! capsfilter caps=video/x-vp9,profile="{ (string)1, \ (string)3 }" We need to store GST_VAAPI_PROFILE_VP9_1 and GST_VAAPI_PROFILE_VP9_3 in this list. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 34 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 4 +++ 2 files changed, 38 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index e9b711b9e7..fcad2e6934 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -104,6 +104,7 @@ struct _GstVaapiEncoderVP9 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) */ @@ -560,6 +561,19 @@ gst_vaapi_encoder_vp9_init (GstVaapiEncoderVP9 * encoder) 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); } /** @@ -678,6 +692,7 @@ gst_vaapi_encoder_vp9_class_init (GstVaapiEncoderVP9Class * klass) 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", @@ -763,3 +778,22 @@ 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; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h index b66290b7a8..6459c01b33 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -43,6 +43,10 @@ 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 From ff829c660be288ee09846ad28493db64aea58c09 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 11 Jul 2020 23:17:02 +0800 Subject: [PATCH 3741/3781] libs: util: vpx: add get_chroma_format_idc for VP9 Part-of: --- gst-libs/gst/vaapi/gstvaapiutils_vpx.c | 31 ++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiutils_vpx.h | 3 +++ 2 files changed, 34 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_vpx.c b/gst-libs/gst/vaapi/gstvaapiutils_vpx.c index 2882c2f0e7..d6bdd8161d 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_vpx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_vpx.c @@ -21,6 +21,7 @@ */ #include "gstvaapiutils_vpx.h" +#include "gstvaapisurface.h" struct map { @@ -86,3 +87,33 @@ gst_vaapi_utils_vp9_get_profile_string (GstVaapiProfile profile) return m ? m->name : NULL; } + +/** Returns VP9 chroma_format_idc value from GstVaapiChromaType */ +guint +gst_vaapi_utils_vp9_get_chroma_format_idc (guint chroma_type) +{ + guint chroma_format_idc; + + switch (chroma_type) { + case GST_VAAPI_CHROMA_TYPE_YUV400: + chroma_format_idc = 0; + break; + case GST_VAAPI_CHROMA_TYPE_YUV420: + case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP: + chroma_format_idc = 1; + break; + case GST_VAAPI_CHROMA_TYPE_YUV422: + case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP: + chroma_format_idc = 2; + break; + case GST_VAAPI_CHROMA_TYPE_YUV444: + case GST_VAAPI_CHROMA_TYPE_YUV444_10BPP: + chroma_format_idc = 3; + break; + default: + GST_DEBUG ("unsupported GstVaapiChromaType value"); + chroma_format_idc = 1; + break; + } + return chroma_format_idc; +} diff --git a/gst-libs/gst/vaapi/gstvaapiutils_vpx.h b/gst-libs/gst/vaapi/gstvaapiutils_vpx.h index a83510ce7e..acead5a529 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_vpx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_vpx.h @@ -35,6 +35,9 @@ gst_vaapi_utils_vp9_get_profile_from_string (const gchar * str); const gchar * gst_vaapi_utils_vp9_get_profile_string (GstVaapiProfile profile); +guint +gst_vaapi_utils_vp9_get_chroma_format_idc (guint chroma_type); + G_END_DECLS #endif /* GST_VAAPI_UTILS_VPX_H */ From a639528217672e80d6a1965fd7cbd2b1e26a2845 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 11 Jul 2020 23:22:55 +0800 Subject: [PATCH 3742/3781] libs: encoder: vp9: Improve the manner to decide the profile. We should decide the VP9 encoder's profile based on the chroma and depth of the input format, then make sure it is included in the allowed list. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 64 +++++++++++++++++++++--- 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index fcad2e6934..01b572c739 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -28,6 +28,7 @@ #include "gstvaapiencoder_vp9.h" #include "gstvaapicodedbufferproxy_priv.h" #include "gstvaapisurface.h" +#include "gstvaapiutils_vpx.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -146,26 +147,73 @@ ensure_bitrate (GstVaapiEncoderVP9 * encoder) } } -/* Derives the profile that suits best to the configuration */ +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 */ - const GstVideoFormat format = - GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); - if (format == GST_VIDEO_FORMAT_P010_10LE) - encoder->profile = GST_VAAPI_PROFILE_VP9_2; - else - encoder->profile = GST_VAAPI_PROFILE_VP9_0; + 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; } From 1725e47700f1bbeee54e45b98432bfbd4357b720 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 11 Jul 2020 23:27:21 +0800 Subject: [PATCH 3743/3781] libs: encoder: vp9: no need to ensure_hw_profile. Once we decide the profile and can get the valid entrypoint for that profile, hw must already support this profile/entrypoint pair. No need to check it again in set_context_info(). Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 38 ++---------------------- 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 01b572c739..bb338452c1 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -217,39 +217,6 @@ ensure_profile (GstVaapiEncoderVP9 * encoder) return GST_VAAPI_ENCODER_STATUS_SUCCESS; } -/* Derives the profile supported by the underlying hardware */ -static gboolean -ensure_hw_profile (GstVaapiEncoderVP9 * encoder) -{ - GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder); - GstVaapiEntrypoint entrypoint = encoder->entrypoint; - 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) { @@ -259,8 +226,7 @@ set_context_info (GstVaapiEncoder * base_encoder) /* FIXME: Maximum sizes for common headers (in bytes) */ - if (!ensure_hw_profile (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + GST_VAAPI_ENCODER_CAST (encoder)->profile = encoder->profile; base_encoder->num_ref_frames = 3 + DEFAULT_SURFACES_COUNT; @@ -579,7 +545,7 @@ gst_vaapi_encoder_vp9_reconfigure (GstVaapiEncoder * base_encoder) encoder->entrypoint = gst_vaapi_encoder_get_entrypoint (base_encoder, encoder->profile); if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_INVALID) { - GST_WARNING ("Cannot find valid entrypoint"); + GST_WARNING ("Cannot find valid profile/entrypoint pair"); return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } From 33ef4ec817f5094381f8fb4fa2682e08e4583409 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 11 Jul 2020 23:39:40 +0800 Subject: [PATCH 3744/3781] plugin: encode: vp9: Add the profile into output caps. Part-of: --- gst/vaapi/gstvaapiencode_vp9.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index 4538462003..c1cfb778bc 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -80,8 +80,14 @@ static GstCaps * gst_vaapiencode_vp9_get_caps (GstVaapiEncode * base_encode) { GstCaps *caps; + GstVaapiProfile profile; + const gchar *profile_str; caps = gst_caps_from_string (GST_CODEC_CAPS); + profile = gst_vaapi_encoder_get_profile (base_encode->encoder); + profile_str = gst_vaapi_utils_vp9_get_profile_string (profile); + if (profile_str) + gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile_str, NULL); return caps; } From eb9be73299c9c3129b4141b60e71c9aefe0f6c07 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 11 Jul 2020 23:37:29 +0800 Subject: [PATCH 3745/3781] plugin: encode: vp9: Implement the set_config(). We store the allowed profiles list to encoder in set_config(). Part-of: --- gst/vaapi/gstvaapiencode_vp9.c | 80 ++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/gst/vaapi/gstvaapiencode_vp9.c b/gst/vaapi/gstvaapiencode_vp9.c index c1cfb778bc..a7cf7c278c 100644 --- a/gst/vaapi/gstvaapiencode_vp9.c +++ b/gst/vaapi/gstvaapiencode_vp9.c @@ -99,6 +99,85 @@ gst_vaapiencode_vp9_alloc_encoder (GstVaapiEncode * base, return gst_vaapi_encoder_vp9_new (display); } +static gboolean +gst_vaapiencode_vp9_set_config (GstVaapiEncode * base_encode) +{ + GstVaapiEncoderVP9 *const encoder = + GST_VAAPI_ENCODER_VP9 (base_encode->encoder); + GstCaps *allowed_caps = NULL; + GstCaps *template_caps = NULL; + GArray *profiles = NULL; + GArray *profiles_hw = NULL; + GArray *profiles_allowed = NULL; + GstVaapiProfile profile; + gboolean ret = TRUE; + guint i, j; + + profiles_hw = gst_vaapi_display_get_encode_profiles_by_codec + (GST_VAAPI_PLUGIN_BASE_DISPLAY (base_encode), GST_VAAPI_CODEC_VP9); + if (!profiles_hw) { + ret = FALSE; + goto out; + } + + template_caps = + gst_pad_get_pad_template_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD + (base_encode)); + allowed_caps = + gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (base_encode)); + if (!allowed_caps || allowed_caps == template_caps) { + ret = gst_vaapi_encoder_vp9_set_allowed_profiles (encoder, profiles_hw); + goto out; + } else if (gst_caps_is_empty (allowed_caps)) { + ret = FALSE; + goto out; + } + + profiles = gst_vaapi_encoder_get_profiles_from_caps (allowed_caps, + gst_vaapi_utils_vp9_get_profile_from_string); + if (!profiles) { + ret = FALSE; + goto out; + } + + profiles_allowed = g_array_new (FALSE, FALSE, sizeof (GstVaapiProfile)); + if (!profiles_allowed) { + ret = FALSE; + goto out; + } + + for (i = 0; i < profiles->len; i++) { + profile = g_array_index (profiles, GstVaapiProfile, i); + for (j = 0; j < profiles_hw->len; j++) { + GstVaapiProfile p = g_array_index (profiles_hw, GstVaapiProfile, j); + if (p == profile) { + g_array_append_val (profiles_allowed, profile); + break; + } + } + } + if (profiles_allowed->len == 0) { + ret = FALSE; + goto out; + } + + ret = gst_vaapi_encoder_vp9_set_allowed_profiles (encoder, profiles_allowed); + +out: + if (allowed_caps) + gst_caps_unref (allowed_caps); + if (template_caps) + gst_caps_unref (template_caps); + if (profiles) + g_array_unref (profiles); + if (profiles_hw) + g_array_unref (profiles_hw); + if (profiles_allowed) + g_array_unref (profiles_allowed); + + return ret; +} + static void gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass, gpointer data) { @@ -118,6 +197,7 @@ gst_vaapiencode_vp9_class_init (GstVaapiEncodeVP9Class * klass, gpointer data) encode_class->get_allowed_profiles = gst_vaapiencode_vp9_get_allowed_profiles; encode_class->get_caps = gst_vaapiencode_vp9_get_caps; encode_class->alloc_encoder = gst_vaapiencode_vp9_alloc_encoder; + encode_class->set_config = gst_vaapiencode_vp9_set_config; gst_element_class_set_static_metadata (element_class, "VA-API VP9 encoder", From dfc730165c53e0cbcee96fd81e4564f4e7baa819 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 25 Jun 2020 16:25:21 +0800 Subject: [PATCH 3746/3781] libs: encoder: H265: Add screen content coding extensions support. In scc mode, the I frame can ref to itself and it needs the L0 reference list enabled. So we should set the I frame to P_SLICE type. We do not need to change the ref_pic_list0/1 passed to VA driver, just need to enable the VAEncPictureParameterBufferHEVC->pps_curr_pic_ref_enabled_flag to notify the driver consider the current frame as reference. For bits conformance, the NumRpsCurrTempList0 should be incremented by one to include the current picture as the reference frame. We manually do it when packing the slice header. Command line like: gst-launch-1.0 videotestsrc num-buffers=10 ! \ capsfilter caps=video/x-raw,format=NV12, framerate=30/1,width=640,height=360 ! \ vaapih265enc ! capsfilter caps=video/x-h265,profile="{ (string)screen-extended-main }" ! \ filesink location=out.265 Can be used to specify that the encoder should use SCC profiles. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 271 +++++++++++++++++++++- gst-libs/gst/vaapi/gstvaapiutils_h265.c | 13 ++ 2 files changed, 274 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 85951daad5..46db870c3c 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -185,6 +185,18 @@ h265_get_slice_type (GstVaapiPictureType type) return -1; } +static gboolean +h265_is_scc (GstVaapiEncoderH265 * encoder) +{ + if (encoder->profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN || + encoder->profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10 || + encoder->profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444 || + encoder->profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10) + return TRUE; + + return FALSE; +} + static gboolean h265_is_tile_enabled (GstVaapiEncoderH265 * encoder) { @@ -305,8 +317,18 @@ bs_write_profile_tier_level (GstBitWriter * bs, WRITE_UINT32 (bs, 0, 1); } - /* general_profile_compatibility_flag[5~32] */ - WRITE_UINT32 (bs, 0, 27); + /* general_profile_compatibility_flag[5~8] */ + WRITE_UINT32 (bs, 0, 4); + + /* general_profile_compatibility_flag[9] */ + if (seq_param->general_profile_idc == 9) { /* screen content coding profiles */ + WRITE_UINT32 (bs, 1, 1); + } else { + WRITE_UINT32 (bs, 0, 1); + } + + /* general_profile_compatibility_flag[10~32] */ + WRITE_UINT32 (bs, 0, 22); /* general_progressive_source_flag */ WRITE_UINT32 (bs, 1, 1); @@ -412,6 +434,107 @@ bs_write_profile_tier_level (GstBitWriter * bs, /* general_reserved_zero_34bits */ for (i = 0; i < 34; i++) WRITE_UINT32 (bs, 0, 1); + } else if (seq_param->general_profile_idc == 9) { + /* In A.3.7, Screen content coding extensions profiles. */ + switch (profile) { + case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN: + /* max_12bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_10bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_8bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_422chroma_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_420chroma_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_monochrome_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* intra_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* one_picture_only_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* lower_bit_rate_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* general_max_14bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + break; + case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10: + /* max_12bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_10bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_8bit_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_422chroma_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_420chroma_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_monochrome_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* intra_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* one_picture_only_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* lower_bit_rate_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* general_max_14bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + break; + case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444: + /* max_12bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_10bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_8bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_422chroma_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_420chroma_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_monochrome_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* intra_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* one_picture_only_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* lower_bit_rate_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* general_max_14bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + break; + case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10: + /* max_12bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_10bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* max_8bit_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_422chroma_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_420chroma_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* max_monochrome_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* intra_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* one_picture_only_constraint_flag */ + WRITE_UINT32 (bs, 0, 1); + /* lower_bit_rate_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + /* general_max_14bit_constraint_flag */ + WRITE_UINT32 (bs, 1, 1); + break; + default: + GST_WARNING ("do not support the profile: %s of screen" + " content coding extensions", + gst_vaapi_profile_get_va_name (profile)); + goto bs_error; + } + + /* general_reserved_zero_33bits */ + for (i = 0; i < 33; i++) + WRITE_UINT32 (bs, 0, 1); } else { /* general_reserved_zero_43bits */ for (i = 0; i < 43; i++) @@ -703,8 +826,40 @@ bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, /* bitstream_restriction_flag */ WRITE_UINT32 (bs, seq_param->vui_fields.bits.bitstream_restriction_flag, 1); } - /* sps_extension_flag */ - WRITE_UINT32 (bs, sps_extension_flag, 1); + + if (h265_is_scc (encoder)) { + /* sps_extension_flag */ + WRITE_UINT32 (bs, 1, 1); + /* sps_range_extension_flag */ + WRITE_UINT32 (bs, 0, 1); + /* sps_multilayer_extension_flag */ + WRITE_UINT32 (bs, 0, 1); + /* sps_3d_extension_flag */ + WRITE_UINT32 (bs, 0, 1); + /* sps_scc_extension_flag */ + WRITE_UINT32 (bs, 1, 1); + /* sps_extension_4bits */ + WRITE_UINT32 (bs, 0, 4); + + /* sps_scc_extension() */ + /* sps_curr_pic_ref_enabled_flag */ + WRITE_UINT32 (bs, 1, 1); + /* palette_mode_enabled_flag */ + WRITE_UINT32 (bs, 1, 1); + /* palette_max_size */ + WRITE_UE (bs, 64); + /* delta_palette_max_predictor_size */ + WRITE_UE (bs, 32); + /* sps_palette_predictor_initializers_present_flag */ + WRITE_UINT32 (bs, 0, 1); + /* motion_vector_resolution_control_idc */ + WRITE_UINT32 (bs, 0, 2); + /* intra_boundary_filtering_disabled_flag */ + WRITE_UINT32 (bs, 0, 1); + } else { + /* sps_extension_flag */ + WRITE_UINT32 (bs, sps_extension_flag, 1); + } return TRUE; @@ -734,7 +889,7 @@ bs_write_sps (GstBitWriter * bs, GstVaapiEncoderH265 * encoder, /* Write a PPS NAL unit */ static gboolean -bs_write_pps (GstBitWriter * bs, +bs_write_pps (GstBitWriter * bs, gboolean is_scc, const VAEncPictureParameterBufferHEVC * pic_param) { guint32 pic_parameter_set_id = 0; @@ -831,8 +986,39 @@ bs_write_pps (GstBitWriter * bs, WRITE_UE (bs, pic_param->log2_parallel_merge_level_minus2); /* slice_segment_header_extension_present_flag */ WRITE_UINT32 (bs, slice_segment_header_extension_present_flag, 1); - /* pps_extension_flag */ - WRITE_UINT32 (bs, pps_extension_flag, 1); + + if (is_scc) { +#if VA_CHECK_VERSION(1,8,0) + /* pps_extension_flag */ + WRITE_UINT32 (bs, 1, 1); + /* pps_range_extension_flag */ + WRITE_UINT32 (bs, 0, 1); + /* pps_multilayer_extension_flag */ + WRITE_UINT32 (bs, 0, 1); + /* pps_3d_extension_flag */ + WRITE_UINT32 (bs, 0, 1); + /* pps_scc_extension_flag */ + WRITE_UINT32 (bs, 1, 1); + /* pps_extension_4bits */ + WRITE_UINT32 (bs, 0, 4); + + /* pps_scc_extension() */ + /* pps_curr_pic_ref_enabled_flag */ + WRITE_UINT32 (bs, + pic_param->scc_fields.bits.pps_curr_pic_ref_enabled_flag, 1); + /* residual_adaptive_colour_transform_enabled_flag */ + WRITE_UINT32 (bs, 0, 1); + /* pps_palette_predictor_initializers_present_flag */ + WRITE_UINT32 (bs, 0, 1); +#else + /* SCC profile should not be selected. */ + g_assert_not_reached (); + return FALSE; +#endif + } else { + /* pps_extension_flag */ + WRITE_UINT32 (bs, pps_extension_flag, 1); + } /* rbsp_trailing_bits */ bs_write_trailing_bits (bs); @@ -863,6 +1049,11 @@ bs_write_slice (GstBitWriter * bs, guint8 num_ref_idx_active_override_flag = slice_param->slice_fields.bits.num_ref_idx_active_override_flag; + if (h265_is_scc (encoder)) { + /* If scc, need to add the current picture itself. */ + num_ref_idx_active_override_flag = 1; + } + /* first_slice_segment_in_pic_flag */ WRITE_UINT32 (bs, encoder->first_slice_segment_in_pic_flag, 1); @@ -985,7 +1176,20 @@ bs_write_slice (GstBitWriter * bs, /* num_ref_idx_active_override_flag */ WRITE_UINT32 (bs, num_ref_idx_active_override_flag, 1); if (num_ref_idx_active_override_flag) { - WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1); + if (h265_is_scc (encoder)) { + if (picture->type == GST_VAAPI_PICTURE_TYPE_I) { + g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0); + /* Let num_ref_idx_l0_active_minus1 = 0 and + NumRpsCurrTempList0 = 1 to include current picture itself */ + WRITE_UE (bs, 0); + } else { + /* For scc, need to add 1 for current picture itself when + calculating NumRpsCurrTempList0. */ + WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1 + 1); + } + } else { + WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1); + } if (slice_param->slice_type == GST_H265_B_SLICE) WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1); } @@ -1101,7 +1305,7 @@ ensure_profile (GstVaapiEncoderH265 * encoder) const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); guint depth, chrome; - GstVaapiProfile profile_candidates[4]; + GstVaapiProfile profile_candidates[6]; guint num, i; g_assert (GST_VIDEO_FORMAT_INFO_IS_YUV (gst_video_format_get_info (format))); @@ -1117,6 +1321,15 @@ ensure_profile (GstVaapiEncoderH265 * encoder) profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_444; if (depth <= 10) profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_444_10; +#if VA_CHECK_VERSION(1,8,0) + /* Consider SCREEN_EXTENDED_MAIN_444 and SCREEN_EXTENDED_MAIN_444_10 */ + if (depth == 8) + profile_candidates[num++] = + GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444; + if (depth <= 10) + profile_candidates[num++] = + GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10; +#endif } else if (chrome == 2) { /* 4:2:2 */ profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_422_10; @@ -1131,6 +1344,14 @@ ensure_profile (GstVaapiEncoderH265 * encoder) /* Always add STILL_PICTURE as a candidate for Main and Main10. */ if (depth <= 10) profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE; +#if VA_CHECK_VERSION(1,8,0) + /* Consider SCREEN_EXTENDED_MAIN and SCREEN_EXTENDED_MAIN_10 */ + if (depth == 8) + profile_candidates[num++] = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN; + if (depth <= 10) + profile_candidates[num++] = + GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10; +#endif } if (num == 0) { @@ -1436,7 +1657,7 @@ add_packed_picture_header (GstVaapiEncoderH265 * encoder, gst_bit_writer_init_with_size (&bs, 128, FALSE); WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */ bs_write_nal_header (&bs, GST_H265_NAL_PPS); - bs_write_pps (&bs, pic_param); + bs_write_pps (&bs, h265_is_scc (encoder), pic_param); g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); data = GST_BIT_WRITER_DATA (&bs); @@ -1727,6 +1948,17 @@ fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence) seq_param->vui_time_scale = GST_VAAPI_ENCODER_FPS_N (encoder); } } + + if (h265_is_scc (encoder)) { +#if VA_CHECK_VERSION(1,8,0) + seq_param->scc_fields.bits.palette_mode_enabled_flag = 1; +#else + /* SCC profile should not be selected. */ + g_assert_not_reached (); + return FALSE; +#endif + } + return TRUE; } @@ -1841,6 +2073,16 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, pic_param->row_height_minus1[i] = tile_ctu_rows[i] - 1; } + if (h265_is_scc (encoder)) { +#if VA_CHECK_VERSION(1,8,0) + pic_param->scc_fields.bits.pps_curr_pic_ref_enabled_flag = 1; +#else + /* SCC profile should not be selected. */ + g_assert_not_reached (); + return FALSE; +#endif + } + return TRUE; } @@ -1862,7 +2104,16 @@ create_and_fill_one_slice (GstVaapiEncoderH265 * encoder, slice_param->slice_type = h265_get_slice_type (picture->type); if (encoder->no_p_frame && slice_param->slice_type == GST_H265_P_SLICE) { slice_param->slice_type = GST_H265_B_SLICE; + } else if (h265_is_scc (encoder) && + slice_param->slice_type == GST_H265_I_SLICE) { + /* In scc mode, the I frame can ref to itself and so need the L0 + reference list enabled. Just set the I frame to P_SLICE type + and leaving all reference unchanged. So all ref_pic_list0's + picture is invalid, the only ref is itself enabled by + pic_param->scc_fields.bits.pps_curr_pic_ref_enabled_flag. */ + slice_param->slice_type = GST_H265_P_SLICE; } + slice_param->slice_pic_parameter_set_id = 0; slice_param->slice_fields.bits.num_ref_idx_active_override_flag = diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h265.c b/gst-libs/gst/vaapi/gstvaapiutils_h265.c index e94f9937d5..a419af8ec2 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h265.c @@ -44,6 +44,10 @@ static const struct map gst_vaapi_h265_profile_map[] = { { GST_VAAPI_PROFILE_H265_MAIN_444_10, "main-444-10" }, { GST_VAAPI_PROFILE_H265_MAIN_422_10, "main-422-10" }, { GST_VAAPI_PROFILE_H265_MAIN12, "main-12" }, + { GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN, "screen-extended-main" }, + { GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10, "screen-extended-main-10" }, + { GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444, "screen-extended-main-444" }, + { GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10, "screen-extended-main-444-10"}, { 0, NULL } /* *INDENT-ON* */ }; @@ -236,6 +240,15 @@ gst_vaapi_utils_h265_get_profile_idc (GstVaapiProfile profile) case GST_VAAPI_PROFILE_H265_MAIN12: profile_idc = GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION; break; + case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN: + /* Fall through */ + case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10: + /* Fall through */ + case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444: + /* Fall through */ + case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10: + profile_idc = GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING; + break; default: GST_DEBUG ("unsupported GstVaapiProfile value"); profile_idc = 0; From 5997093ba1415452f94e8c3c97444a5be299a37c Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 9 Dec 2020 00:04:33 +0800 Subject: [PATCH 3747/3781] libs: encoder: H264: Fix one assert in get_pending_reordered(). gst_vaapi_encoder_h264_get_pending_reordered() does not consider the case for HIERARCHICAL_B mode. The pipeline: gst-launch-1.0 videotestsrc num-buffers=48 ! vaapih264enc prediction-type=2 \ keyframe-period=32 ! fakesink get a assert: ERROR:../gst-libs/gst/vaapi/gstvaapiencoder_h264.c:1996:reflist1_init_hierarchical_b: assertion failed: (count != 0) The last few B frames are not fetched in correct order when HIERARCHICAL_B is enabled. We also fix a latent bug for normal mode. The g_queue_pop_tail() of B frames make the last several frames encoded in reverse order. The NAL of last few frames come in reverse order in the bit stream, though it can still output the correct image. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 57 ++++++++++++++--------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index 5eec9f6de0..c36fa829fb 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -2943,6 +2943,23 @@ error: } } +/* reorder_list sorting for hierarchical-b encode */ +static gint +sort_hierarchical_b (gconstpointer a, gconstpointer b, gpointer user_data) +{ + GstVaapiEncPicture *pic1 = (GstVaapiEncPicture *) a; + GstVaapiEncPicture *pic2 = (GstVaapiEncPicture *) b; + + if (pic1->type != GST_VAAPI_PICTURE_TYPE_B) + return 1; + if (pic2->type != GST_VAAPI_PICTURE_TYPE_B) + return -1; + if (pic1->temporal_id == pic2->temporal_id) + return pic1->poc - pic2->poc; + else + return pic1->temporal_id - pic2->temporal_id; +} + struct _PendingIterState { guint cur_view; @@ -2955,7 +2972,7 @@ gst_vaapi_encoder_h264_get_pending_reordered (GstVaapiEncoder * base_encoder, { GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder); GstVaapiH264ViewReorderPool *reorder_pool; - GstVaapiEncPicture *pic; + GstVaapiEncPicture *pic = NULL; struct _PendingIterState *iter; g_return_val_if_fail (state, FALSE); @@ -2979,13 +2996,28 @@ gst_vaapi_encoder_h264_get_pending_reordered (GstVaapiEncoder * base_encoder, return TRUE; /* perhaps other views has pictures? */ } - pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list); - g_assert (pic); if (iter->pic_type == GST_VAAPI_PICTURE_TYPE_P) { + pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list); + g_assert (pic); set_p_frame (pic, encoder); + + g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame, + encoder); + /* sort the queued list of frames for hierarchical-b based on + * temporal level where each frame belongs */ + if (encoder->prediction_type == + GST_VAAPI_ENCODER_H264_PREDICTION_HIERARCHICAL_B) { + pic->temporal_id = 0; + GST_VAAPI_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_REFERENCE); + + g_queue_sort (&reorder_pool->reorder_frame_list, sort_hierarchical_b, + NULL); + } + iter->pic_type = GST_VAAPI_PICTURE_TYPE_B; } else if (iter->pic_type == GST_VAAPI_PICTURE_TYPE_B) { - set_b_frame (pic, encoder); + pic = g_queue_pop_head (&reorder_pool->reorder_frame_list); + g_assert (pic); } else { GST_WARNING ("Unhandled pending picture type"); } @@ -3141,23 +3173,6 @@ get_temporal_id (GstVaapiEncoderH264 * encoder, guint32 display_order) return 0; } -/* reorder_list sorting for hierarchical-b encode */ -static gint -sort_hierarchical_b (gconstpointer a, gconstpointer b, gpointer user_data) -{ - GstVaapiEncPicture *pic1 = (GstVaapiEncPicture *) a; - GstVaapiEncPicture *pic2 = (GstVaapiEncPicture *) b; - - if (pic1->type != GST_VAAPI_PICTURE_TYPE_B) - return 1; - if (pic2->type != GST_VAAPI_PICTURE_TYPE_B) - return -1; - if (pic1->temporal_id == pic2->temporal_id) - return pic1->poc - pic2->poc; - else - return pic1->temporal_id - pic2->temporal_id; -} - static GstVaapiEncoderStatus gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder, GstVideoCodecFrame * frame, GstVaapiEncPicture ** output) From 5bee089331cfe6e579f75f482b2501737cfbecdc Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 8 Dec 2020 13:34:35 +0800 Subject: [PATCH 3748/3781] plugins: encode: unlock the stream lock before _flush() The current encoder will hang when EOS comes. When we call the gst_vaapi_encoder_encode_and_queue(), we should release the stream lock, just like what we do in gst_vaapiencode_handle_frame(). The deadlock happens when: The input thread holding the stream lock is using gst_vaapi_encoder_create_coded_buffer() to acquire a coded buffer, while the output thread which holding the coded buffer resource is acquiring the stream lock in _push_frame() to push the data to down stream element. Part-of: --- gst/vaapi/gstvaapiencode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index a970f827b1..b17a81e50d 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -565,7 +565,10 @@ gst_vaapiencode_drain (GstVaapiEncode * encode) if (!encode->encoder) return TRUE; + GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); status = gst_vaapi_encoder_flush (encode->encoder); + GST_VIDEO_ENCODER_STREAM_LOCK (encode); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return FALSE; gst_vaapiencode_purge (encode); @@ -722,10 +725,12 @@ gst_vaapiencode_finish (GstVideoEncoder * venc) if (!encode->encoder) return GST_FLOW_NOT_NEGOTIATED; + GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); + status = gst_vaapi_encoder_flush (encode->encoder); - GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); gst_pad_stop_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); + GST_VIDEO_ENCODER_STREAM_LOCK (encode); while (status == GST_VAAPI_ENCODER_STATUS_SUCCESS && ret == GST_FLOW_OK) From a16849b4ed03557b2f03cc1458cd297ef6aeda71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 12 Dec 2020 10:30:41 +0100 Subject: [PATCH 3749/3781] vaapi: use gst_clear_object instead of g_clear_object Part-of: --- gst/vaapi/gstvaapidecodebin.c | 6 +++--- gst/vaapi/gstvaapipluginbase.c | 18 +++++++++--------- gst/vaapi/gstvaapivideobufferpool.c | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 7edf39722c..7358506989 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -411,7 +411,7 @@ gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) /* create the queue */ vaapidecbin->queue = gst_element_factory_make ("queue", "vaapi-queue"); if (!vaapidecbin->queue) { - g_clear_object (&vaapidecbin->decoder); + gst_clear_object (&vaapidecbin->decoder); post_missing_element_message (vaapidecbin, "queue"); return; } @@ -420,8 +420,8 @@ gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin) vaapidecbin->queue, NULL); if (!gst_element_link (vaapidecbin->decoder, vaapidecbin->queue)) { - g_clear_object (&vaapidecbin->decoder); - g_clear_object (&vaapidecbin->queue); + gst_clear_object (&vaapidecbin->decoder); + gst_clear_object (&vaapidecbin->queue); g_critical ("failed to link decoder and queue"); return; } diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 72b28b86a7..3a8664ba1a 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -61,13 +61,13 @@ gst_vaapi_pad_private_reset (GstVaapiPadPrivate * priv) gst_caps_replace (&priv->caps, NULL); gst_video_info_init (&priv->info); - g_clear_object (&priv->buffer_pool); - g_clear_object (&priv->allocator); + gst_clear_object (&priv->buffer_pool); + gst_clear_object (&priv->allocator); priv->buffer_size = 0; priv->caps_is_raw = FALSE; - g_clear_object (&priv->other_allocator); + gst_clear_object (&priv->other_allocator); } void @@ -765,8 +765,8 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstPad * sinkpad) if (gst_vaapi_buffer_pool_caps_is_equal (sinkpriv->buffer_pool, caps)) return TRUE; gst_buffer_pool_set_active (sinkpriv->buffer_pool, FALSE); - g_clear_object (&sinkpriv->buffer_pool); - g_clear_object (&sinkpriv->allocator); + gst_clear_object (&sinkpriv->buffer_pool); + gst_clear_object (&sinkpriv->allocator); sinkpriv->buffer_size = 0; } @@ -802,8 +802,8 @@ _set_srcpad_caps (GstVaapiPluginBase * plugin, GstPad * srcpad, GstCaps * caps) && !gst_vaapi_buffer_pool_caps_is_equal (srcpriv->buffer_pool, caps)) { gst_buffer_pool_set_active (srcpriv->buffer_pool, FALSE); - g_clear_object (&srcpriv->buffer_pool); - g_clear_object (&srcpriv->allocator); + gst_clear_object (&srcpriv->buffer_pool); + gst_clear_object (&srcpriv->allocator); plugin_reset_texture_map (plugin); } gst_caps_replace (&srcpriv->caps, caps); @@ -1085,7 +1085,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) { GST_INFO_OBJECT (plugin, "ignoring non-VAAPI pool: %" GST_PTR_FORMAT, pool); - g_clear_object (&pool); + gst_clear_object (&pool); } } } else { @@ -1122,7 +1122,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, } } - g_clear_object (&srcpriv->buffer_pool); + gst_clear_object (&srcpriv->buffer_pool); srcpriv->buffer_pool = pool; /* if downstream doesn't support GstVideoMeta, and the negotiated diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 3ff29acd54..d6c3ccd906 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -61,7 +61,7 @@ gst_vaapi_video_buffer_pool_finalize (GObject * object) GST_VAAPI_VIDEO_BUFFER_POOL (object)->priv; gst_vaapi_display_replace (&priv->display, NULL); - g_clear_object (&priv->allocator); + gst_clear_object (&priv->allocator); if (priv->dma_mem_map) g_hash_table_destroy (priv->dma_mem_map); From 46c1f3875a6e998b3d85ab4f938fd846e616252a Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 27 Aug 2020 21:39:35 +0800 Subject: [PATCH 3750/3781] libs: codecobject: Add number of elements when create codec object. One slice data may need several slice parameter buffers at one time. Part-of: --- gst-libs/gst/vaapi/gstvaapicodec_objects.c | 17 ++++++++++++++--- gst-libs/gst/vaapi/gstvaapicodec_objects.h | 8 ++++++++ gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 20 +++++++++++++++++--- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 11 +++++++++++ 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c index e66d2fe7fb..1bdd93b24e 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.c +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c @@ -68,9 +68,10 @@ gst_vaapi_codec_object_create (GstVaapiCodecObject * object, } GstVaapiCodecObject * -gst_vaapi_codec_object_new (const GstVaapiCodecObjectClass * object_class, - GstVaapiCodecBase * codec, gconstpointer param, guint param_size, - gconstpointer data, guint data_size, guint flags) +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; @@ -85,6 +86,7 @@ gst_vaapi_codec_object_new (const GstVaapiCodecObjectClass * object_class, args.param = param; args.param_size = param_size; + args.param_num = param_num; args.data = data; args.data_size = data_size; args.flags = flags; @@ -96,6 +98,15 @@ gst_vaapi_codec_object_new (const GstVaapiCodecObjectClass * object_class, 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 diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h index 2d081bde44..ab30dab7d5 100644 --- a/gst-libs/gst/vaapi/gstvaapicodec_objects.h +++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h @@ -59,6 +59,7 @@ typedef struct { gconstpointer param; guint param_size; + guint param_num; gconstpointer data; guint data_size; guint flags; @@ -105,6 +106,13 @@ 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))) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 48e9ead9aa..8139e1406b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -457,9 +457,10 @@ gst_vaapi_slice_create (GstVaapiSlice * slice, if (!success) return FALSE; - success = vaapi_create_buffer (GET_VA_DISPLAY (slice), GET_VA_CONTEXT (slice), - VASliceParameterBufferType, args->param_size, args->param, - &slice->param_id, &slice->param); + 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; @@ -480,3 +481,16 @@ gst_vaapi_slice_new (GstVaapiDecoder * decoder, 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); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index c4c4f8586f..16ef2550e6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -260,6 +260,12 @@ 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 --- */ /* ------------------------------------------------------------------------- */ @@ -273,6 +279,11 @@ gst_vaapi_slice_new (GstVaapiDecoder * decoder, gconstpointer param, 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 */ From 0a34b6882e4480b22bcde4ce1236a9d6725a6da8 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 27 Aug 2020 21:46:41 +0800 Subject: [PATCH 3751/3781] libs: decoder: AV1: Add the av1 decoder support. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_av1.c | 1290 ++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_av1.h | 47 + gst-libs/gst/vaapi/gstvaapiprofile.c | 7 + gst-libs/gst/vaapi/gstvaapiprofile.h | 9 + gst-libs/gst/vaapi/gstvaapiutils.c | 4 + gst-libs/gst/vaapi/meson.build | 5 + gst/vaapi/gstvaapidecode.c | 12 +- meson.build | 2 + 8 files changed, 1375 insertions(+), 1 deletion(-) create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_av1.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_av1.h diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_av1.c b/gst-libs/gst/vaapi/gstvaapidecoder_av1.c new file mode 100644 index 0000000000..5d5610c707 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_av1.c @@ -0,0 +1,1290 @@ +/* + * gstvaapidecoder_av1.c - AV1 decoder + * + * Copyright (C) 2019-2020 Intel Corporation + * Author: Junyan He + * + * 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_av1 + * @short_description: AV1 decoder + */ + +#include "sysdeps.h" +#include +#include "gstvaapidecoder_av1.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_AV1_CAST(decoder) ((GstVaapiDecoderAV1 *)(decoder)) + +typedef struct _GstVaapiDecoderAV1Private GstVaapiDecoderAV1Private; +typedef struct _GstVaapiDecoderAV1Class GstVaapiDecoderAV1Class; +typedef struct _GstVaapiPictureAV1 GstVaapiPictureAV1; + +struct _GstVaapiDecoderAV1Private +{ + GstVaapiProfile profile; + guint width; + guint height; + gboolean reset_context; + GstVaapiPictureAV1 *current_picture; + gboolean annex_b; + GstAV1Parser *parser; + GstAV1SequenceHeaderOBU *seq_header; + GstVaapiPictureAV1 *ref_frames[GST_AV1_NUM_REF_FRAMES]; +}; + +/** + * GstVaapiDecoderAV1: + * + * A decoder based on AV1. + */ +struct _GstVaapiDecoderAV1 +{ + /*< private > */ + GstVaapiDecoder parent_instance; + GstVaapiDecoderAV1Private priv; +}; + +/** + * GstVaapiDecoderAV1Class: + * + * A decoder class based on AV1. + */ +struct _GstVaapiDecoderAV1Class +{ + /*< private > */ + GstVaapiDecoderClass parent_class; +}; + +G_DEFINE_TYPE (GstVaapiDecoderAV1, gst_vaapi_decoder_av1, + GST_TYPE_VAAPI_DECODER); + +/* ------------------------------------------------------------------------- */ +/* --- AV1 Parser Info --- */ +/* ------------------------------------------------------------------------- */ +typedef struct _GstVaapiParserInfoAV1 GstVaapiParserInfoAV1; +struct _GstVaapiParserInfoAV1 +{ + GstVaapiMiniObject parent_instance; + GstAV1OBU obu; + union + { + GstAV1SequenceHeaderOBU seq_header; + GstAV1MetadataOBU metadata; + GstAV1FrameHeaderOBU frame_header; + GstAV1TileListOBU tile_list; + GstAV1TileGroupOBU tile_group; + GstAV1FrameOBU frame; + }; + /* The offset between input data and real OBU data */ + gint data_offset; +}; + +static void +parser_info_av1_finalize (GstVaapiParserInfoAV1 * pi) +{ +} + +static inline const GstVaapiMiniObjectClass * +parser_info_av1_class (void) +{ + static const GstVaapiMiniObjectClass GstVaapiParserInfoAV1Class = { + .size = sizeof (GstVaapiParserInfoAV1), + .finalize = (GDestroyNotify) parser_info_av1_finalize + }; + return &GstVaapiParserInfoAV1Class; +} + +static inline GstVaapiParserInfoAV1 * +parser_info_av1_new (GstAV1OBU * obu) +{ + GstVaapiParserInfoAV1 *pi = (GstVaapiParserInfoAV1 *) + gst_vaapi_mini_object_new (parser_info_av1_class ()); + + if (pi) + pi->obu = *obu; + + return pi; +} + +/* ------------------------------------------------------------------------- */ +/* --- AV1 Picture --- */ +/* ------------------------------------------------------------------------- */ +struct _GstVaapiPictureAV1 +{ + GstVaapiPicture base; + /* When apply_grain enabled, recon proxy is different from the display + proxy, otherwise the same. */ + GstVaapiSurfaceProxy *recon_proxy; + GstAV1FrameHeaderOBU frame_header; + gboolean cloned; +}; + +GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiPictureAV1, gst_vaapi_picture_av1); + +void +gst_vaapi_picture_av1_destroy (GstVaapiPictureAV1 * picture) +{ + if (picture->recon_proxy) { + gst_vaapi_surface_proxy_unref (picture->recon_proxy); + picture->recon_proxy = NULL; + } + gst_vaapi_picture_destroy (GST_VAAPI_PICTURE (picture)); +} + +gboolean +gst_vaapi_picture_av1_create (GstVaapiPictureAV1 * picture, + const GstVaapiCodecObjectConstructorArgs * args) +{ + if (!gst_vaapi_picture_create (GST_VAAPI_PICTURE (picture), args)) + return FALSE; + + picture->recon_proxy = gst_vaapi_surface_proxy_ref (picture->base.proxy); + g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE_ID (picture->recon_proxy) == + picture->base.surface_id); + + return TRUE; +} + +static inline GstVaapiPictureAV1 * +gst_vaapi_picture_av1_new (GstVaapiDecoderAV1 * decoder) +{ + GstVaapiPictureAV1 *picture; + + picture = (GstVaapiPictureAV1 *) + gst_vaapi_codec_object_new (&GstVaapiPictureAV1Class, + GST_VAAPI_CODEC_BASE (decoder), NULL, + sizeof (VADecPictureParameterBufferAV1), NULL, 0, 0); + + if (picture) + picture->cloned = FALSE; + + return picture; +} + +static const gchar * +av1_obu_name (GstAV1OBUType type) +{ + switch (type) { + case GST_AV1_OBU_SEQUENCE_HEADER: + return "sequence header"; + case GST_AV1_OBU_TEMPORAL_DELIMITER: + return "temporal delimiter"; + case GST_AV1_OBU_FRAME_HEADER: + return "frame header"; + case GST_AV1_OBU_TILE_GROUP: + return "tile group"; + case GST_AV1_OBU_METADATA: + return "metadata"; + case GST_AV1_OBU_FRAME: + return "frame"; + case GST_AV1_OBU_REDUNDANT_FRAME_HEADER: + return "redundant frame header"; + case GST_AV1_OBU_TILE_LIST: + return "tile list"; + case GST_AV1_OBU_PADDING: + return "padding"; + default: + return "unknown"; + } + + return NULL; +} + +static GstVaapiChromaType +av1_get_chroma_type (GstVaapiProfile profile, + GstAV1SequenceHeaderOBU * seq_header) +{ + /* 6.4.1: + seq_profile Bit depth Monochrome support Chroma subsampling + 0 8 or 10 Yes YUV 4:2:0 + 1 8 or 10 No YUV 4:4:4 + 2 8 or 10 Yes YUV 4:2:2 + 2 12 Yes YUV 4:2:0,YUV 4:2:2,YUV 4:4:4 + */ + + /* TODO: consider Monochrome case. Just return 4:2:0 for Monochrome now. */ + switch (profile) { + case GST_VAAPI_PROFILE_AV1_0: + if (seq_header->bit_depth == 8) { + return GST_VAAPI_CHROMA_TYPE_YUV420; + } else if (seq_header->bit_depth == 10) { + return GST_VAAPI_CHROMA_TYPE_YUV420_10BPP; + } + break; + case GST_VAAPI_PROFILE_AV1_1: + if (seq_header->bit_depth == 8) { + return GST_VAAPI_CHROMA_TYPE_YUV444; + } else if (seq_header->bit_depth == 10) { + return GST_VAAPI_CHROMA_TYPE_YUV444_10BPP; + } + break; + default: + break; + } + + GST_WARNING ("can not decide chrome type."); + return 0; +} + +static GstVaapiProfile +av1_get_profile (guint profile_idc) +{ + GstVaapiProfile profile; + + switch (profile_idc) { + case GST_AV1_PROFILE_0: + profile = GST_VAAPI_PROFILE_AV1_0; + break; + case GST_AV1_PROFILE_1: + profile = GST_VAAPI_PROFILE_AV1_1; + break; + default: + GST_INFO ("unsupported av1 profile_idc value %d", profile_idc); + profile = GST_VAAPI_PROFILE_UNKNOWN; + break; + } + return profile; +} + +static GstVaapiDecoderStatus +av1_decode_seqeunce (GstVaapiDecoderAV1 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderAV1Private *const priv = &decoder->priv; + GstVaapiProfile profile; + GstVaapiParserInfoAV1 *const pi = unit->parsed_info; + + profile = av1_get_profile (pi->seq_header.seq_profile); + if (profile == GST_VAAPI_PROFILE_UNKNOWN) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + + if (!gst_vaapi_display_has_decoder (GST_VAAPI_DECODER_DISPLAY (decoder), + profile, GST_VAAPI_ENTRYPOINT_VLD)) { + GST_WARNING ("not supported av1 profile %s", + gst_vaapi_profile_get_va_name (profile)); + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + + if (profile != priv->profile) { + GST_DEBUG ("new av1 profile %s", gst_vaapi_profile_get_va_name (profile)); + /* We delay the context creation to when we know the frame resolution */ + priv->reset_context = TRUE; + priv->profile = profile; + } + + /* update the sequence */ + if (priv->seq_header) + g_slice_free (GstAV1SequenceHeaderOBU, priv->seq_header); + priv->seq_header = g_slice_dup (GstAV1SequenceHeaderOBU, &pi->seq_header); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +av1_decoder_ensure_context (GstVaapiDecoderAV1 * decoder) +{ + GstVaapiDecoderAV1Private *const priv = &decoder->priv; + GstVaapiContextInfo info; + + if (priv->reset_context) { + if (priv->current_picture) + gst_vaapi_picture_replace (&priv->current_picture, NULL); + + info.profile = priv->profile; + info.entrypoint = GST_VAAPI_ENTRYPOINT_VLD; + info.width = priv->width; + info.height = priv->height; + info.chroma_type = av1_get_chroma_type (info.profile, priv->seq_header); + if (!info.chroma_type) + return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT; + + info.ref_frames = GST_AV1_NUM_REF_FRAMES + 2; + + priv->reset_context = FALSE; + if (!gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info)) { + GST_WARNING ("can not make av1 decoder context with profile %s," + " width %d, height %d", gst_vaapi_profile_get_va_name (info.profile), + info.width, info.height); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + } + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static void +av1_fill_segment_info (VADecPictureParameterBufferAV1 * pic_param, + GstAV1FrameHeaderOBU * frame_header) +{ + guint i, j; + uint8_t feature_mask; + +#define COPY_SEG_FIELD(FP, FS) \ + pic_param->seg_info.segment_info_fields.bits.FP = \ + (frame_header)->segmentation_params.FS + + COPY_SEG_FIELD (enabled, segmentation_enabled); + COPY_SEG_FIELD (update_map, segmentation_update_map); + COPY_SEG_FIELD (temporal_update, segmentation_temporal_update); + COPY_SEG_FIELD (update_data, segmentation_update_data); + for (i = 0; i < GST_AV1_MAX_SEGMENTS; i++) + for (j = 0; j < GST_AV1_SEG_LVL_MAX; j++) + pic_param->seg_info.feature_data[i][j] = + frame_header->segmentation_params.feature_data[i][j]; + + for (i = 0; i < GST_AV1_MAX_SEGMENTS; i++) { + feature_mask = 0; + for (j = 0; j < GST_AV1_SEG_LVL_MAX; j++) { + if (frame_header->segmentation_params.feature_enabled[i][j]) + feature_mask |= 1 << j; + } + pic_param->seg_info.feature_mask[i] = feature_mask; + } +#undef COPY_SEG_FIELD +} + +static void +av1_fill_film_grain_info (VADecPictureParameterBufferAV1 * pic_param, + GstAV1FrameHeaderOBU * frame_header) +{ + guint i; + + if (!frame_header->film_grain_params.apply_grain) + return; + +#define COPY_FILM_GRAIN_FIELD(FP) \ + pic_param->SUB_FIELD.FP = (frame_header)->film_grain_params.FP +#define SUB_FIELD film_grain_info.film_grain_info_fields.bits + + COPY_FILM_GRAIN_FIELD (apply_grain); + COPY_FILM_GRAIN_FIELD (chroma_scaling_from_luma); + COPY_FILM_GRAIN_FIELD (grain_scaling_minus_8); + COPY_FILM_GRAIN_FIELD (ar_coeff_lag); + COPY_FILM_GRAIN_FIELD (ar_coeff_shift_minus_6); + COPY_FILM_GRAIN_FIELD (grain_scale_shift); + COPY_FILM_GRAIN_FIELD (overlap_flag); + COPY_FILM_GRAIN_FIELD (clip_to_restricted_range); +#undef SUB_FIELD + + pic_param->film_grain_info.grain_seed = + frame_header->film_grain_params.grain_seed; + + pic_param->film_grain_info.num_y_points = + frame_header->film_grain_params.num_y_points; + for (i = 0; i < frame_header->film_grain_params.num_y_points; i++) { + pic_param->film_grain_info.point_y_value[i] = + frame_header->film_grain_params.point_y_value[i]; + pic_param->film_grain_info.point_y_scaling[i] = + frame_header->film_grain_params.point_y_scaling[i]; + } + + pic_param->film_grain_info.num_cb_points = + frame_header->film_grain_params.num_cb_points; + for (i = 0; i < frame_header->film_grain_params.num_cb_points; i++) { + pic_param->film_grain_info.point_cb_value[i] = + frame_header->film_grain_params.point_cb_value[i]; + pic_param->film_grain_info.point_cb_scaling[i] = + frame_header->film_grain_params.point_cb_scaling[i]; + } + + pic_param->film_grain_info.num_cr_points = + frame_header->film_grain_params.num_cr_points; + for (i = 0; i < frame_header->film_grain_params.num_cr_points; i++) { + pic_param->film_grain_info.point_cr_value[i] = + frame_header->film_grain_params.point_cr_value[i]; + pic_param->film_grain_info.point_cr_scaling[i] = + frame_header->film_grain_params.point_cr_scaling[i]; + } + + + if (pic_param->film_grain_info.num_y_points) { + for (i = 0; i < 24; i++) { + pic_param->film_grain_info.ar_coeffs_y[i] = + frame_header->film_grain_params.ar_coeffs_y_plus_128[i] - 128; + } + } + if (frame_header->film_grain_params.chroma_scaling_from_luma + || pic_param->film_grain_info.num_cb_points) { + for (i = 0; i < GST_AV1_MAX_NUM_POS_LUMA; i++) { + pic_param->film_grain_info.ar_coeffs_cb[i] = + frame_header->film_grain_params.ar_coeffs_cb_plus_128[i] - 128; + } + } + if (frame_header->film_grain_params.chroma_scaling_from_luma + || pic_param->film_grain_info.num_cr_points) { + for (i = 0; i < GST_AV1_MAX_NUM_POS_LUMA; i++) { + pic_param->film_grain_info.ar_coeffs_cr[i] = + frame_header->film_grain_params.ar_coeffs_cr_plus_128[i] - 128; + } + } +#define SUB_FIELD film_grain_info + COPY_FILM_GRAIN_FIELD (cb_mult); + COPY_FILM_GRAIN_FIELD (cb_luma_mult); + COPY_FILM_GRAIN_FIELD (cb_offset); + COPY_FILM_GRAIN_FIELD (cr_mult); + COPY_FILM_GRAIN_FIELD (cr_luma_mult); + COPY_FILM_GRAIN_FIELD (cr_offset); +#undef SUB_FIELD +#undef COPY_FILM_GRAIN_FIELD +} + +static void +av1_fill_loop_filter_info (VADecPictureParameterBufferAV1 * pic_param, + GstAV1FrameHeaderOBU * frame_header) +{ + guint i; + + pic_param->superres_scale_denominator = frame_header->superres_denom; + pic_param->interp_filter = frame_header->interpolation_filter; + pic_param->filter_level[0] = + frame_header->loop_filter_params.loop_filter_level[0]; + pic_param->filter_level[1] = + frame_header->loop_filter_params.loop_filter_level[1]; + pic_param->filter_level_u = + frame_header->loop_filter_params.loop_filter_level[2]; + pic_param->filter_level_v = + frame_header->loop_filter_params.loop_filter_level[3]; + pic_param->loop_filter_info_fields.bits.sharpness_level = + frame_header->loop_filter_params.loop_filter_sharpness; + pic_param->loop_filter_info_fields.bits.mode_ref_delta_enabled = + frame_header->loop_filter_params.loop_filter_delta_enabled; + pic_param->loop_filter_info_fields.bits.mode_ref_delta_update = + frame_header->loop_filter_params.loop_filter_delta_update; + + for (i = 0; i < GST_AV1_TOTAL_REFS_PER_FRAME; i++) + pic_param->ref_deltas[i] = + frame_header->loop_filter_params.loop_filter_ref_deltas[i]; + for (i = 0; i < 2; i++) + pic_param->mode_deltas[i] = + frame_header->loop_filter_params.loop_filter_mode_deltas[i]; + + pic_param->mode_control_fields.bits.delta_lf_present_flag = + frame_header->loop_filter_params.delta_lf_present; + pic_param->mode_control_fields.bits.log2_delta_lf_res = + frame_header->loop_filter_params.delta_lf_res; + pic_param->mode_control_fields.bits.delta_lf_multi = + frame_header->loop_filter_params.delta_lf_multi; +} + +static void +av1_fill_quantization_info (VADecPictureParameterBufferAV1 * pic_param, + GstAV1FrameHeaderOBU * frame_header) +{ + pic_param->base_qindex = frame_header->quantization_params.base_q_idx; + pic_param->y_dc_delta_q = frame_header->quantization_params.delta_q_y_dc; + pic_param->u_dc_delta_q = frame_header->quantization_params.delta_q_u_dc; + pic_param->u_ac_delta_q = frame_header->quantization_params.delta_q_u_ac; + pic_param->v_dc_delta_q = frame_header->quantization_params.delta_q_v_dc; + pic_param->v_ac_delta_q = frame_header->quantization_params.delta_q_v_ac; + + pic_param->qmatrix_fields.bits.using_qmatrix = + frame_header->quantization_params.using_qmatrix; + if (pic_param->qmatrix_fields.bits.using_qmatrix) { + pic_param->qmatrix_fields.bits.qm_y = + frame_header->quantization_params.qm_y; + pic_param->qmatrix_fields.bits.qm_u = + frame_header->quantization_params.qm_u; + pic_param->qmatrix_fields.bits.qm_v = + frame_header->quantization_params.qm_v; + } else { + pic_param->qmatrix_fields.bits.qm_y = 0; + pic_param->qmatrix_fields.bits.qm_u = 0; + pic_param->qmatrix_fields.bits.qm_v = 0; + } + + pic_param->mode_control_fields.bits.delta_q_present_flag = + frame_header->quantization_params.delta_q_present; + pic_param->mode_control_fields.bits.log2_delta_q_res = + frame_header->quantization_params.delta_q_res; +} + +static void +av1_fill_cdef_info (VADecPictureParameterBufferAV1 * pic_param, + GstAV1FrameHeaderOBU * frame_header, guint8 num_planes) +{ + guint8 sec_strength; + guint i; + + pic_param->cdef_damping_minus_3 = frame_header->cdef_params.cdef_damping - 3; + pic_param->cdef_bits = frame_header->cdef_params.cdef_bits; + for (i = 0; i < GST_AV1_CDEF_MAX; i++) { + sec_strength = frame_header->cdef_params.cdef_y_sec_strength[i]; + g_assert (sec_strength <= 4); + /* may need to minus 1 in order to merge with primary value. */ + if (sec_strength == 4) + sec_strength--; + + pic_param->cdef_y_strengths[i] = + ((frame_header->cdef_params.cdef_y_pri_strength[i] & 0xf) << 2) | + (sec_strength & 0x03); + } + if (num_planes > 1) { + for (i = 0; i < GST_AV1_CDEF_MAX; i++) { + sec_strength = frame_header->cdef_params.cdef_uv_sec_strength[i]; + g_assert (sec_strength <= 4); + /* may need to minus 1 in order to merge with primary value. */ + if (sec_strength == 4) + sec_strength--; + + pic_param->cdef_uv_strengths[i] = + ((frame_header->cdef_params.cdef_uv_pri_strength[i] & 0xf) << 2) | + (sec_strength & 0x03); + } + } else { + for (i = 0; i < GST_AV1_CDEF_MAX; i++) { + pic_param->cdef_uv_strengths[i] = 0; + } + } +} + +static void +av1_fill_loop_restoration_info (VADecPictureParameterBufferAV1 * pic_param, + GstAV1FrameHeaderOBU * frame_header) +{ + pic_param->loop_restoration_fields.bits.yframe_restoration_type = + frame_header->loop_restoration_params.frame_restoration_type[0]; + pic_param->loop_restoration_fields.bits.cbframe_restoration_type = + frame_header->loop_restoration_params.frame_restoration_type[1]; + pic_param->loop_restoration_fields.bits.crframe_restoration_type = + frame_header->loop_restoration_params.frame_restoration_type[2]; + pic_param->loop_restoration_fields.bits.lr_unit_shift = + frame_header->loop_restoration_params.lr_unit_shift; + pic_param->loop_restoration_fields.bits.lr_uv_shift = + frame_header->loop_restoration_params.lr_uv_shift; +} + +static void +av1_fill_global_motion_info (VADecPictureParameterBufferAV1 * pic_param, + GstAV1FrameHeaderOBU * frame_header) +{ + guint i, j; + + for (i = 0; i < 7; i++) { + pic_param->wm[i].wmtype = + frame_header->global_motion_params.gm_type[GST_AV1_REF_LAST_FRAME + i]; + + for (j = 0; j < 6; j++) + pic_param->wm[i].wmmat[j] = + frame_header->global_motion_params.gm_params + [GST_AV1_REF_LAST_FRAME + i][j]; + + pic_param->wm[i].wmmat[6] = 0; + pic_param->wm[i].wmmat[7] = 0; + + pic_param->wm[i].invalid = + frame_header->global_motion_params.invalid[GST_AV1_REF_LAST_FRAME + i]; + } +} + +static gboolean +av1_fill_picture_frame_header (GstVaapiDecoderAV1 * decoder, + GstVaapiPictureAV1 * picture, GstAV1FrameHeaderOBU * frame_header) +{ + GstVaapiDecoderAV1Private *priv = &decoder->priv; + VADecPictureParameterBufferAV1 *pic_param = + GST_VAAPI_PICTURE (picture)->param; + GstAV1SequenceHeaderOBU *seq_header = priv->seq_header; + guint i; + + pic_param->profile = seq_header->seq_profile; + pic_param->order_hint_bits_minus_1 = seq_header->order_hint_bits_minus_1; + + if (seq_header->bit_depth == 8) + pic_param->bit_depth_idx = 0; + else if (seq_header->bit_depth == 10) + pic_param->bit_depth_idx = 1; + else if (seq_header->bit_depth == 12) + pic_param->bit_depth_idx = 2; + else + g_assert (0); + + pic_param->matrix_coefficients = seq_header->color_config.matrix_coefficients; + +#define COPY_SEQ_FIELD(FP, FS) \ + pic_param->seq_info_fields.fields.FP = (seq_header)->FS + + COPY_SEQ_FIELD (still_picture, still_picture); + COPY_SEQ_FIELD (use_128x128_superblock, use_128x128_superblock); + COPY_SEQ_FIELD (enable_filter_intra, enable_filter_intra); + COPY_SEQ_FIELD (enable_intra_edge_filter, enable_intra_edge_filter); + COPY_SEQ_FIELD (enable_interintra_compound, enable_interintra_compound); + COPY_SEQ_FIELD (enable_masked_compound, enable_masked_compound); + COPY_SEQ_FIELD (enable_dual_filter, enable_dual_filter); + COPY_SEQ_FIELD (enable_order_hint, enable_order_hint); + COPY_SEQ_FIELD (enable_jnt_comp, enable_jnt_comp); + COPY_SEQ_FIELD (enable_cdef, enable_cdef); + COPY_SEQ_FIELD (mono_chrome, color_config.mono_chrome); + COPY_SEQ_FIELD (color_range, color_config.color_range); + COPY_SEQ_FIELD (subsampling_x, color_config.subsampling_x); + COPY_SEQ_FIELD (subsampling_y, color_config.subsampling_y); + COPY_SEQ_FIELD (film_grain_params_present, film_grain_params_present); +#undef COPY_SEQ_FIELD + + if (frame_header->film_grain_params.apply_grain) { + g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE_ID (picture->recon_proxy) != + GST_VAAPI_PICTURE (picture)->surface_id); + pic_param->current_frame = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (picture->recon_proxy); + pic_param->current_display_picture = + GST_VAAPI_PICTURE (picture)->surface_id; + } else { + pic_param->current_frame = GST_VAAPI_PICTURE (picture)->surface_id; + pic_param->current_display_picture = + GST_VAAPI_PICTURE (picture)->surface_id; + } + + pic_param->frame_width_minus1 = frame_header->upscaled_width - 1; + pic_param->frame_height_minus1 = frame_header->frame_height - 1; + + for (i = 0; i < GST_AV1_NUM_REF_FRAMES; i++) { + if (priv->ref_frames[i]) + pic_param->ref_frame_map[i] = + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (priv->ref_frames[i]->recon_proxy); + else + pic_param->ref_frame_map[i] = VA_INVALID_SURFACE; + } + for (i = 0; i < GST_AV1_REFS_PER_FRAME; i++) { + pic_param->ref_frame_idx[i] = frame_header->ref_frame_idx[i]; + } + pic_param->primary_ref_frame = frame_header->primary_ref_frame; + pic_param->order_hint = frame_header->order_hint; + + av1_fill_segment_info (pic_param, frame_header); + av1_fill_film_grain_info (pic_param, frame_header); + + pic_param->tile_cols = frame_header->tile_info.tile_cols; + pic_param->tile_rows = frame_header->tile_info.tile_rows; + for (i = 0; i < 63; i++) { + pic_param->width_in_sbs_minus_1[i] = + frame_header->tile_info.width_in_sbs_minus_1[i]; + pic_param->height_in_sbs_minus_1[i] = + frame_header->tile_info.height_in_sbs_minus_1[i]; + } + + pic_param->context_update_tile_id = + frame_header->tile_info.context_update_tile_id; + +#define COPY_PIC_FIELD(FIELD) \ + pic_param->pic_info_fields.bits.FIELD = (frame_header)->FIELD + + COPY_PIC_FIELD (frame_type); + COPY_PIC_FIELD (show_frame); + COPY_PIC_FIELD (showable_frame); + COPY_PIC_FIELD (error_resilient_mode); + COPY_PIC_FIELD (disable_cdf_update); + COPY_PIC_FIELD (allow_screen_content_tools); + COPY_PIC_FIELD (force_integer_mv); + COPY_PIC_FIELD (allow_intrabc); + COPY_PIC_FIELD (use_superres); + COPY_PIC_FIELD (allow_high_precision_mv); + COPY_PIC_FIELD (is_motion_mode_switchable); + COPY_PIC_FIELD (use_ref_frame_mvs); + COPY_PIC_FIELD (disable_frame_end_update_cdf); + pic_param->pic_info_fields.bits.uniform_tile_spacing_flag = + frame_header->tile_info.uniform_tile_spacing_flag; + COPY_PIC_FIELD (allow_warped_motion); +#undef COPY_PIC_FIELD + + av1_fill_loop_filter_info (pic_param, frame_header); + av1_fill_quantization_info (pic_param, frame_header); + + pic_param->mode_control_fields.bits.tx_mode = frame_header->tx_mode; + pic_param->mode_control_fields.bits.reference_select = + frame_header->reference_select; + pic_param->mode_control_fields.bits.reduced_tx_set_used = + frame_header->reduced_tx_set; + pic_param->mode_control_fields.bits.skip_mode_present = + frame_header->skip_mode_present; + + av1_fill_cdef_info (pic_param, frame_header, seq_header->num_planes); + av1_fill_loop_restoration_info (pic_param, frame_header); + av1_fill_global_motion_info (pic_param, frame_header); + + return TRUE; +} + +static GstVaapiDecoderStatus +av1_decode_frame_header (GstVaapiDecoderAV1 * decoder, + GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderAV1Private *const priv = &decoder->priv; + GstVaapiParserInfoAV1 *const pi = unit->parsed_info; + GstAV1FrameHeaderOBU *frame_header = NULL; + GstVaapiDecoderStatus ret = GST_VAAPI_DECODER_STATUS_SUCCESS; + GstVaapiPictureAV1 *picture = NULL; + + if (pi->obu.obu_type == GST_AV1_OBU_FRAME_HEADER) { + frame_header = &pi->frame_header; + } else { + g_assert (pi->obu.obu_type == GST_AV1_OBU_FRAME); + frame_header = &pi->frame.frame_header; + } + + if (frame_header->show_existing_frame) { + GstVaapiPictureAV1 *to_show_picture = NULL; + + to_show_picture = priv->ref_frames[frame_header->frame_to_show_map_idx]; + if (to_show_picture == NULL) { + GST_ERROR ("frame_to_show_map_idx point to a invalid picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (gst_av1_parser_reference_frame_loading (priv->parser, + &to_show_picture->frame_header) != GST_AV1_PARSER_OK) { + GST_ERROR ("load frame to show ref frame failed"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + picture = (GstVaapiPictureAV1 *) + gst_vaapi_picture_new_clone (GST_VAAPI_PICTURE_CAST (to_show_picture)); + if (!picture) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE; + gst_vaapi_surface_proxy_replace (&picture->recon_proxy, + to_show_picture->recon_proxy); + picture->cloned = TRUE; + GST_VAAPI_PICTURE_FLAG_UNSET (picture, GST_VAAPI_PICTURE_FLAG_SKIPPED); + + picture->frame_header = to_show_picture->frame_header; + /* only update references if the frame_to_show_map_idx is a KEY FRAME */ + if (picture->frame_header.frame_type == GST_AV1_KEY_FRAME) { + picture->frame_header = to_show_picture->frame_header; + g_assert (picture->frame_header.refresh_frame_flags == + ((1 << GST_AV1_NUM_REF_FRAMES) - 1)); + } else { + /* Just set to no update ref */ + picture->frame_header.refresh_frame_flags = 0; + } + } else { + /* Resolution changed */ + if (priv->width != priv->seq_header->max_frame_width_minus_1 + 1 || + priv->height != priv->seq_header->max_frame_height_minus_1 + 1) { + priv->reset_context = TRUE; + priv->width = priv->seq_header->max_frame_width_minus_1 + 1; + priv->height = priv->seq_header->max_frame_height_minus_1 + 1; + GST_INFO ("change the resolution to %dx%d", priv->width, priv->height); + } + + ret = av1_decoder_ensure_context (decoder); + if (ret != GST_VAAPI_DECODER_STATUS_SUCCESS) + return ret; + + picture = gst_vaapi_picture_av1_new (decoder); + if (!picture) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE; + + if (frame_header->upscaled_width != priv->width || + frame_header->frame_height != priv->height) { + GstVaapiRectangle crop_rect; + + if (frame_header->upscaled_width > priv->width) { + GST_WARNING ("Frame width is %d, bigger than sequence max width %d", + frame_header->upscaled_width, priv->width); + gst_vaapi_codec_object_unref (picture); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + if (frame_header->frame_height > priv->height) { + GST_WARNING ("Frame height is %d, bigger than sequence max height %d", + frame_header->frame_height, priv->height); + gst_vaapi_codec_object_unref (picture); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + crop_rect.x = 0; + crop_rect.y = 0; + crop_rect.width = frame_header->upscaled_width; + crop_rect.height = frame_header->frame_height; + gst_vaapi_picture_set_crop_rect (GST_VAAPI_PICTURE (picture), &crop_rect); + } + + if (frame_header->film_grain_params.apply_grain) { + GstVaapiSurfaceProxy *recon_proxy = gst_vaapi_context_get_surface_proxy + (GST_VAAPI_DECODER (decoder)->context); + if (!recon_proxy) { + gst_vaapi_codec_object_unref (picture); + return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE; + } + gst_vaapi_surface_proxy_replace (&picture->recon_proxy, recon_proxy); + } + + picture->frame_header = *frame_header; + + /* this frame will not show this time */ + if (!frame_header->show_frame) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_SKIPPED); + + GST_VAAPI_PICTURE (picture)->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; + GST_VAAPI_PICTURE (picture)->type = + frame_header->frame_is_intra ? GST_VAAPI_PICTURE_TYPE_I : + GST_VAAPI_PICTURE_TYPE_P; + + if (!av1_fill_picture_frame_header (decoder, picture, frame_header)) { + gst_vaapi_codec_object_unref (picture); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + } + + gst_vaapi_picture_replace (&priv->current_picture, picture); + gst_vaapi_picture_unref (picture); + + return ret; +} + +static GstVaapiDecoderStatus +av1_decode_tile_data (GstVaapiDecoderAV1 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderAV1Private *const priv = &decoder->priv; + GstVaapiPictureAV1 *picture = priv->current_picture; + GstVaapiParserInfoAV1 *const pi = unit->parsed_info; + GstAV1TileGroupOBU *tile_group = &pi->tile_group; + guint32 i; + GstVaapiSlice *slice; + GstBuffer *const buffer = + GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer; + GstMapInfo map_info; + + if (!picture) { + GST_WARNING ("Decode the tile date without a picture"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) { + GST_ERROR ("failed to map buffer"); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + slice = GST_VAAPI_SLICE_NEW_N_PARAMS (AV1, decoder, + map_info.data + pi->data_offset + unit->offset, pi->obu.obu_size, + (tile_group->tg_end - tile_group->tg_start + 1)); + gst_buffer_unmap (buffer, &map_info); + if (!slice) { + GST_ERROR ("failed to allocate slice"); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + for (i = 0; i < tile_group->tg_end - tile_group->tg_start + 1; i++) { + VASliceParameterBufferAV1 *const slice_param = + slice->param + i * sizeof (VASliceParameterBufferAV1); + + slice_param->slice_data_size = + tile_group->entry[tile_group->tg_start + i].tile_size; + slice_param->slice_data_offset = + tile_group->entry[tile_group->tg_start + i].tile_offset; + slice_param->tile_row = + tile_group->entry[tile_group->tg_start + i].tile_row; + slice_param->tile_column = + tile_group->entry[tile_group->tg_start + i].tile_col; + slice_param->slice_data_flag = 0; + } + + gst_vaapi_picture_add_slice (GST_VAAPI_PICTURE_CAST (picture), slice); + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +av1_decode_unit (GstVaapiDecoderAV1 * decoder, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderStatus ret = GST_VAAPI_DECODER_STATUS_SUCCESS; + GstVaapiParserInfoAV1 *const pi = unit->parsed_info; + + GST_DEBUG ("begin to decode the unit of %s", av1_obu_name (pi->obu.obu_type)); + + switch (pi->obu.obu_type) { + case GST_AV1_OBU_SEQUENCE_HEADER: + ret = av1_decode_seqeunce (decoder, unit); + break; + case GST_AV1_OBU_FRAME_HEADER: + ret = av1_decode_frame_header (decoder, unit); + break; + case GST_AV1_OBU_FRAME: + ret = av1_decode_frame_header (decoder, unit); + if (ret != GST_VAAPI_DECODER_STATUS_SUCCESS) + break; + /* fall through */ + case GST_AV1_OBU_TILE_GROUP: + ret = av1_decode_tile_data (decoder, unit); + break; + case GST_AV1_OBU_METADATA: + case GST_AV1_OBU_REDUNDANT_FRAME_HEADER: + case GST_AV1_OBU_PADDING: + /* Not handled */ + ret = GST_VAAPI_DECODER_STATUS_SUCCESS; + break; + default: + GST_WARNING ("can not handle obu type %s", + av1_obu_name (pi->obu.obu_type)); + ret = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + return ret; +} + +static GstVaapiDecoderStatus +av1_decode_current_picture (GstVaapiDecoderAV1 * decoder) +{ + GstVaapiDecoderAV1Private *priv = &decoder->priv; + GstVaapiPicture *const picture = (GstVaapiPicture *) priv->current_picture; + + g_assert (picture); + + if (!gst_vaapi_picture_decode (picture)) + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +av1_decoder_update_state (GstVaapiDecoderAV1 * decoder, + GstVaapiPictureAV1 * picture) +{ + GstVaapiDecoderAV1Private *priv = &decoder->priv; + GstAV1ParserResult ret; + guint i; + + /* This is a show_existing_frame case, only update key frame */ + if (picture->cloned && picture->frame_header.frame_type != GST_AV1_KEY_FRAME) + return GST_VAAPI_DECODER_STATUS_SUCCESS; + + ret = gst_av1_parser_reference_frame_update (priv->parser, + &picture->frame_header); + if (ret != GST_AV1_PARSER_OK) { + GST_ERROR ("failed to update the reference."); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + for (i = 0; i < GST_AV1_NUM_REF_FRAMES; i++) { + if ((picture->frame_header.refresh_frame_flags >> i) & 1) { + if (picture) { + GST_LOG ("reference frame %p to ref slot:%d", picture, i); + gst_vaapi_picture_replace (&priv->ref_frames[i], picture); + } else { + GST_ERROR ("we miss some reference frame for ref slot:%d", i); + gst_vaapi_picture_replace (&priv->ref_frames[i], NULL); + } + } + } + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static void +av1_decoder_reset (GstVaapiDecoderAV1 * decoder) +{ + GstVaapiDecoderAV1Private *priv = &decoder->priv; + guint i; + + priv->profile = GST_VAAPI_PROFILE_UNKNOWN; + priv->width = 0; + priv->height = 0; + priv->annex_b = FALSE; + priv->reset_context = FALSE; + + if (priv->current_picture) + gst_vaapi_picture_replace (&priv->current_picture, NULL); + + if (priv->seq_header) { + g_slice_free (GstAV1SequenceHeaderOBU, priv->seq_header); + priv->seq_header = NULL; + } + + for (i = 0; i < GST_AV1_NUM_REF_FRAMES; i++) + gst_vaapi_picture_replace (&priv->ref_frames[i], NULL); +} + +static gboolean +av1_is_picture_end (GstVaapiParserInfoAV1 * pi) +{ + GstAV1TileGroupOBU *tile_group = NULL; + + if (pi->obu.obu_type == GST_AV1_OBU_FRAME) { + tile_group = &pi->frame.tile_group; + } else if (pi->obu.obu_type == GST_AV1_OBU_TILE_GROUP) { + tile_group = &pi->tile_group; + } + g_assert (tile_group); + + if (tile_group->tg_end == tile_group->num_tiles - 1) + return TRUE; + + return FALSE; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_av1_reset (GstVaapiDecoder * base_decoder) +{ + GstVaapiDecoderAV1 *const decoder = GST_VAAPI_DECODER_AV1 (base_decoder); + GstVaapiDecoderAV1Private *priv = &decoder->priv; + + av1_decoder_reset (decoder); + gst_av1_parser_reset (priv->parser, FALSE); + + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_av1_parse (GstVaapiDecoder * base_decoder, + GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderAV1 *const decoder = GST_VAAPI_DECODER_AV1 (base_decoder); + GstVaapiDecoderAV1Private *const priv = &decoder->priv; + GstVaapiParserInfoAV1 *pi; + GstAV1Parser *parser = priv->parser; + guchar *buf; + guint buf_size, flags; + GstAV1OBU obu; + GstAV1ParserResult av1_ret; + GstVaapiDecoderStatus ret = GST_VAAPI_DECODER_STATUS_SUCCESS; + guint32 consumed; + + buf_size = gst_adapter_available (adapter); + if (!buf_size) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + /* no need to do unmap here */ + buf = (guchar *) gst_adapter_map (adapter, buf_size); + if (!buf) + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + + av1_ret = + gst_av1_parser_identify_one_obu (parser, buf, buf_size, &obu, &consumed); + if (av1_ret == GST_AV1_PARSER_DROP) { + GST_LOG ("just discard a %s obu with size %d, consumed %d", + av1_obu_name (obu.obu_type), obu.obu_size, consumed); + gst_adapter_flush (adapter, consumed); + return GST_VAAPI_DECODER_STATUS_SUCCESS; + } else if (av1_ret == GST_AV1_PARSER_NO_MORE_DATA) { + return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; + } else if (av1_ret == GST_AV1_PARSER_BITSTREAM_ERROR) { + GST_WARNING_OBJECT (decoder, "parse error, an invalid bitstream"); + gst_adapter_flush (adapter, consumed); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } else if (av1_ret != GST_AV1_PARSER_OK) { + GST_WARNING_OBJECT (decoder, "parse error, unknown error"); + gst_adapter_flush (adapter, consumed); + return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + } + + GST_DEBUG ("get one %s obu with size %d, consumed %d", + av1_obu_name (obu.obu_type), obu.obu_size, consumed); + + pi = parser_info_av1_new (&obu); + if (!pi) { + gst_adapter_flush (adapter, consumed); + return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED; + } + + gst_vaapi_decoder_unit_set_parsed_info (unit, pi, + (GDestroyNotify) gst_vaapi_mini_object_unref); + + flags = 0; + av1_ret = GST_AV1_PARSER_OK; + switch (pi->obu.obu_type) { + case GST_AV1_OBU_TEMPORAL_DELIMITER: + av1_ret = gst_av1_parser_parse_temporal_delimiter_obu (parser, &pi->obu); + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + break; + case GST_AV1_OBU_SEQUENCE_HEADER: + av1_ret = gst_av1_parser_parse_sequence_header_obu (parser, &pi->obu, + &pi->seq_header); + break; + case GST_AV1_OBU_REDUNDANT_FRAME_HEADER: + av1_ret = gst_av1_parser_parse_frame_header_obu (parser, &pi->obu, + &pi->frame_header); + break; + case GST_AV1_OBU_FRAME_HEADER: + av1_ret = gst_av1_parser_parse_frame_header_obu (parser, &pi->obu, + &pi->frame_header); + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + if (pi->frame_header.show_existing_frame) { + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + } + break; + case GST_AV1_OBU_FRAME: + av1_ret = gst_av1_parser_parse_frame_obu (parser, &obu, &pi->frame); + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + pi->data_offset = obu.data - buf; + if (av1_is_picture_end (pi)) + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + break; + case GST_AV1_OBU_METADATA: + av1_ret = gst_av1_parser_parse_metadata_obu (parser, &obu, &pi->metadata); + break; + case GST_AV1_OBU_TILE_GROUP: + av1_ret = gst_av1_parser_parse_tile_group_obu (parser, &obu, + &pi->tile_group); + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + pi->data_offset = obu.data - buf; + if (av1_is_picture_end (pi)) + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + break; + case GST_AV1_OBU_TILE_LIST: + av1_ret = + gst_av1_parser_parse_tile_list_obu (parser, &obu, &pi->tile_list); + flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE; + flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END; + break; + case GST_AV1_OBU_PADDING: + break; + default: + GST_WARNING_OBJECT (decoder, "an unrecognized obu type %d", obu.obu_type); + av1_ret = GST_AV1_PARSER_BITSTREAM_ERROR; + break; + } + + if (av1_ret != GST_AV1_PARSER_OK) { + /* Should not get NO_MORE_DATA, the obu size is already known */ + GST_WARNING_OBJECT (decoder, "parse %s obu error", + av1_obu_name (pi->obu.obu_type)); + gst_adapter_flush (adapter, consumed); + gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pi)); + return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; + } + + unit->size = consumed; + unit->offset = pi->obu.data - buf; + GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags); + + return ret; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_av1_decode (GstVaapiDecoder * base_decoder, + GstVaapiDecoderUnit * unit) +{ + GstVaapiDecoderAV1 *const decoder = GST_VAAPI_DECODER_AV1 (base_decoder); + GstVaapiDecoderStatus status; + + status = av1_decode_unit (decoder, unit); + + return status; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_av1_start_frame (GstVaapiDecoder * base_decoder, + GstVaapiDecoderUnit * base_unit) +{ + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_av1_end_frame (GstVaapiDecoder * base_decoder) +{ + GstVaapiDecoderAV1 *const decoder = GST_VAAPI_DECODER_AV1 (base_decoder); + GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS; + GstVaapiDecoderAV1Private *priv = &decoder->priv; + + if (!priv->current_picture->cloned) + status = av1_decode_current_picture (decoder); + + /* update state anyway */ + av1_decoder_update_state (decoder, priv->current_picture); + + if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) + goto out; + + if (!gst_vaapi_picture_output (GST_VAAPI_PICTURE (priv->current_picture))) + status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + +out: + gst_vaapi_picture_replace (&priv->current_picture, NULL); + return status; +} + +static GstVaapiDecoderStatus +gst_vaapi_decoder_av1_flush (GstVaapiDecoder * base_decoder) +{ + return GST_VAAPI_DECODER_STATUS_SUCCESS; +} + +static void +gst_vaapi_decoder_av1_finalize (GObject * object) +{ + GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (object); + GstVaapiDecoderAV1 *const decoder = GST_VAAPI_DECODER_AV1 (base_decoder); + GstVaapiDecoderAV1Private *priv = &decoder->priv; + + av1_decoder_reset (decoder); + if (decoder->priv.parser) + gst_av1_parser_free (decoder->priv.parser); + priv->parser = NULL; + + G_OBJECT_CLASS (gst_vaapi_decoder_av1_parent_class)->finalize (object); +} + +static void +gst_vaapi_decoder_av1_class_init (GstVaapiDecoderAV1Class * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass); + + object_class->finalize = gst_vaapi_decoder_av1_finalize; + + decoder_class->reset = gst_vaapi_decoder_av1_reset; + decoder_class->parse = gst_vaapi_decoder_av1_parse; + decoder_class->decode = gst_vaapi_decoder_av1_decode; + decoder_class->start_frame = gst_vaapi_decoder_av1_start_frame; + decoder_class->end_frame = gst_vaapi_decoder_av1_end_frame; + decoder_class->flush = gst_vaapi_decoder_av1_flush; +} + +static void +gst_vaapi_decoder_av1_init (GstVaapiDecoderAV1 * decoder) +{ + guint i; + GstVaapiDecoderAV1Private *priv = &decoder->priv; + + priv->profile = GST_VAAPI_PROFILE_UNKNOWN; + priv->width = 0; + priv->height = 0; + priv->annex_b = FALSE; + priv->reset_context = FALSE; + priv->current_picture = NULL; + priv->seq_header = NULL; + + for (i = 0; i < GST_AV1_NUM_REF_FRAMES; i++) + priv->ref_frames[i] = NULL; + + priv->parser = gst_av1_parser_new (); +} + +/** + * gst_vaapi_decoder_av1_new: + * @display: a #GstVaapiDisplay + * @caps: a #GstCaps holding codec information + * + * Creates a new #GstVaapiDecoder for AV1 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_av1_new (GstVaapiDisplay * display, GstCaps * caps) +{ + return g_object_new (GST_TYPE_VAAPI_DECODER_AV1, "display", display, + "caps", caps, NULL); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_av1.h b/gst-libs/gst/vaapi/gstvaapidecoder_av1.h new file mode 100644 index 0000000000..8604093edf --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidecoder_av1.h @@ -0,0 +1,47 @@ +/* + * gstvaapidecoder_av1.h - AV1 decoder + * + * Copyright (C) 2019-2020 Intel Corporation + * Author: Junyan He + * + * 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 + +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 */ diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.c b/gst-libs/gst/vaapi/gstvaapiprofile.c index 5a2e1c0526..35d95c8927 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.c +++ b/gst-libs/gst/vaapi/gstvaapiprofile.c @@ -71,6 +71,7 @@ static const GstVaapiCodecMap gst_vaapi_codecs[] = { {GST_VAAPI_CODEC_VP8, "vp8"}, {GST_VAAPI_CODEC_H265, "h265"}, {GST_VAAPI_CODEC_VP9, "vp9"}, + {GST_VAAPI_CODEC_AV1, "av1"}, {0,} }; @@ -154,6 +155,12 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = { "video/x-vp9", "2"}, {GST_VAAPI_PROFILE_VP9_3, VAProfileVP9Profile3, "video/x-vp9", "3"}, +#if VA_CHECK_VERSION(1,8,0) + {GST_VAAPI_PROFILE_AV1_0, VAProfileAV1Profile0, + "video/x-av1", "0"}, + {GST_VAAPI_PROFILE_AV1_1, VAProfileAV1Profile1, + "video/x-av1", "1"}, +#endif {0,} }; diff --git a/gst-libs/gst/vaapi/gstvaapiprofile.h b/gst-libs/gst/vaapi/gstvaapiprofile.h index 3255fe53b3..8fc98c1c59 100644 --- a/gst-libs/gst/vaapi/gstvaapiprofile.h +++ b/gst-libs/gst/vaapi/gstvaapiprofile.h @@ -42,6 +42,7 @@ G_BEGIN_DECLS * @GST_VAAPI_CODEC_JPEG: JPEG (ITU-T 81) * @GST_VAAPI_CODEC_H265: H.265 aka MPEG-H Part 2 (ITU-T H.265) * @GST_VAAPI_CODEC_VP9: VP9 (libvpx) + * @GST_VAAPI_CODEC_AV1: AV1 (aom) * * The set of all codecs for #GstVaapiCodec. */ @@ -57,6 +58,7 @@ typedef enum { GST_VAAPI_CODEC_VP8 = GST_MAKE_FOURCC('V','P','8',0), GST_VAAPI_CODEC_H265 = GST_MAKE_FOURCC('2','6','5',0), GST_VAAPI_CODEC_VP9 = GST_MAKE_FOURCC('V','P','9',0), + GST_VAAPI_CODEC_AV1 = GST_MAKE_FOURCC('A','V','1',0), } GstVaapiCodec; /** @@ -142,6 +144,10 @@ typedef enum { * VP9 prfile 2, bitdepth=10/12, 420 * @GST_VAAPI_PROFILE_VP9_3: * VP9 prfile 3 bitdepth=10/12, 422/444/440/RGB + * @GST_VAAPI_PROFILE_AV1_0: + * AV1 prfile 0, bitdepth=8/10, 420/400 + * @GST_VAAPI_PROFILE_AV1_1: + * AV1 prfile 1 bitdepth=8/10, 444 * * The set of all profiles for #GstVaapiProfile. */ @@ -196,6 +202,9 @@ typedef enum { GST_VAAPI_PROFILE_VP9_1 = GST_VAAPI_MAKE_PROFILE(VP9,2), GST_VAAPI_PROFILE_VP9_2 = GST_VAAPI_MAKE_PROFILE(VP9,3), GST_VAAPI_PROFILE_VP9_3 = GST_VAAPI_MAKE_PROFILE(VP9,4), + + GST_VAAPI_PROFILE_AV1_0 = GST_VAAPI_MAKE_PROFILE(AV1,1), + GST_VAAPI_PROFILE_AV1_1 = GST_VAAPI_MAKE_PROFILE(AV1,2), } GstVaapiProfile; /** diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 1f228e3718..46bb65ef0e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -255,6 +255,10 @@ string_of_VAProfile (VAProfile profile) MAP (VP9Profile1); MAP (VP9Profile2); MAP (VP9Profile3); +#if VA_CHECK_VERSION(1,8,0) + MAP (AV1Profile0); + MAP (AV1Profile1); +#endif #undef MAP default: break; diff --git a/gst-libs/gst/vaapi/meson.build b/gst-libs/gst/vaapi/meson.build index aadd4fd4c8..d4353a4361 100644 --- a/gst-libs/gst/vaapi/meson.build +++ b/gst-libs/gst/vaapi/meson.build @@ -110,6 +110,11 @@ if USE_VP9_ENCODER gstlibvaapi_headers += 'gstvaapiencoder_vp9.h' endif +if USE_AV1_DECODER + gstlibvaapi_sources += 'gstvaapidecoder_av1.c' + gstlibvaapi_headers += 'gstvaapidecoder_av1.h' +endif + if USE_DRM gstlibvaapi_sources += [ 'gstvaapidisplay_drm.c', diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 7e60240814..76d1bc47ce 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -44,6 +44,9 @@ #include #include #include +#if USE_AV1_DECODER +#include +#endif #define GST_PLUGIN_NAME "vaapidecode" #define GST_PLUGIN_DESC "A VA-API based video decoder" @@ -75,6 +78,7 @@ static const char gst_vaapidecode_sink_caps_str[] = GST_CAPS_CODEC("video/x-wmv") GST_CAPS_CODEC("video/x-vp8") GST_CAPS_CODEC("video/x-vp9") + GST_CAPS_CODEC("video/x-av1") ; static const char gst_vaapidecode_src_caps_str[] = @@ -118,6 +122,7 @@ static const GstVaapiDecoderMap vaapi_decode_map[] = { {GST_VAAPI_CODEC_VP8, GST_RANK_PRIMARY, "vp8", "video/x-vp8", NULL}, {GST_VAAPI_CODEC_VP9, GST_RANK_PRIMARY, "vp9", "video/x-vp9", NULL}, {GST_VAAPI_CODEC_H265, GST_RANK_PRIMARY, "h265", "video/x-h265", NULL}, + {GST_VAAPI_CODEC_AV1, GST_RANK_PRIMARY, "av1", "video/x-av1", NULL}, {0 /* the rest */ , GST_RANK_PRIMARY + 1, NULL, gst_vaapidecode_sink_caps_str, NULL}, }; @@ -979,6 +984,11 @@ gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps) case GST_VAAPI_CODEC_VP9: decode->decoder = gst_vaapi_decoder_vp9_new (dpy, caps); break; +#if USE_AV1_DECODER + case GST_VAAPI_CODEC_AV1: + decode->decoder = gst_vaapi_decoder_av1_new (dpy, caps); + break; +#endif default: decode->decoder = NULL; break; @@ -1547,7 +1557,7 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) "Gwenole Beauchesne , " "Halley Zhao , " "Sreerenj Balachandran , " - "Wind Yuan "); + "Wind Yuan , Junyan He "); g_free (longname); g_free (description); diff --git a/meson.build b/meson.build index 638d9252de..8a8347cd90 100644 --- a/meson.build +++ b/meson.build @@ -115,6 +115,7 @@ endif USE_ENCODERS = get_option('with_encoders') != 'no' USE_VP9_ENCODER = USE_ENCODERS and cc.has_header('va/va_enc_vp9.h', dependencies: libva_dep, prefix: '#include ') +USE_AV1_DECODER = cc.has_header('va/va_dec_av1.h', dependencies: libva_dep, prefix: '#include ') USE_DRM = libva_drm_dep.found() and libdrm_dep.found() and libudev_dep.found() and get_option('with_drm') != 'no' USE_EGL = gmodule_dep.found() and egl_dep.found() and GLES_VERSION_MASK != 0 and get_option('with_egl') != 'no' @@ -166,6 +167,7 @@ cdata.set10('USE_EGL', USE_EGL) cdata.set10('USE_ENCODERS', USE_ENCODERS) cdata.set10('USE_GLX', USE_GLX) cdata.set10('USE_VP9_ENCODER', USE_VP9_ENCODER) +cdata.set10('USE_AV1_DECODER', USE_AV1_DECODER) cdata.set10('USE_WAYLAND', USE_WAYLAND) cdata.set10('USE_X11', USE_X11) cdata.set10('HAVE_XKBLIB', cc.has_header('X11/XKBlib.h', dependencies: x11_dep)) From 5523b75550111a6eae828c3053a5015bef233090 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 22 Dec 2020 23:43:52 +0800 Subject: [PATCH 3752/3781] libs: decoder: Add decode_with_surface_id for AV1 film_grain. The AV1 film_graim feature needs two surfaces the same time for decoding. One is for recon surface which will be used as reference later, and the other one is for display. The GstVaapiPicture should contain the surface for display, while the vaBeginPicture() need the recon surface as the target. We add a gst_vaapi_picture_decode_with_surface_id API to handle this kind of requirement. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_av1.c | 6 ++++-- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 17 ++++++++++++++--- gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 5 +++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_av1.c b/gst-libs/gst/vaapi/gstvaapidecoder_av1.c index 5d5610c707..062b310be6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_av1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_av1.c @@ -945,11 +945,13 @@ static GstVaapiDecoderStatus av1_decode_current_picture (GstVaapiDecoderAV1 * decoder) { GstVaapiDecoderAV1Private *priv = &decoder->priv; - GstVaapiPicture *const picture = (GstVaapiPicture *) priv->current_picture; + GstVaapiPictureAV1 *const picture = + (GstVaapiPictureAV1 *) priv->current_picture; g_assert (picture); - if (!gst_vaapi_picture_decode (picture)) + if (!gst_vaapi_picture_decode_with_surface_id (GST_VAAPI_PICTURE (picture), + GST_VAAPI_SURFACE_PROXY_SURFACE_ID (picture->recon_proxy))) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; return GST_VAAPI_DECODER_STATUS_SUCCESS; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index 8139e1406b..159625f8c2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -242,7 +242,8 @@ do_decode (VADisplay dpy, VAContextID ctx, VABufferID * buf_id, void **buf_ptr) } gboolean -gst_vaapi_picture_decode (GstVaapiPicture * picture) +gst_vaapi_picture_decode_with_surface_id (GstVaapiPicture * picture, + VASurfaceID surface_id) { GstVaapiIqMatrix *iq_matrix; GstVaapiBitPlane *bitplane; @@ -254,13 +255,14 @@ gst_vaapi_picture_decode (GstVaapiPicture * picture) 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", picture->surface_id); + GST_DEBUG ("decode picture 0x%08x", surface_id); - status = vaBeginPicture (va_display, va_context, picture->surface_id); + status = vaBeginPicture (va_display, va_context, surface_id); if (!vaapi_check_status (status, "vaBeginPicture()")) return FALSE; @@ -319,6 +321,15 @@ gst_vaapi_picture_decode (GstVaapiPicture * picture) 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) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index 16ef2550e6..cc301d17e4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -196,6 +196,11 @@ 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); From 5e3fde85692221d42d93ec98fffa0d6f1aa308f7 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 9 Jan 2021 16:05:48 +0800 Subject: [PATCH 3753/3781] decoder: AV1: Fix a static analysis problem of update_state(). No need to check the picture pointer after we have already dereferenced it. Fix: #298 Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_av1.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_av1.c b/gst-libs/gst/vaapi/gstvaapidecoder_av1.c index 062b310be6..a4faf5d22e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_av1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_av1.c @@ -978,13 +978,8 @@ av1_decoder_update_state (GstVaapiDecoderAV1 * decoder, for (i = 0; i < GST_AV1_NUM_REF_FRAMES; i++) { if ((picture->frame_header.refresh_frame_flags >> i) & 1) { - if (picture) { - GST_LOG ("reference frame %p to ref slot:%d", picture, i); - gst_vaapi_picture_replace (&priv->ref_frames[i], picture); - } else { - GST_ERROR ("we miss some reference frame for ref slot:%d", i); - gst_vaapi_picture_replace (&priv->ref_frames[i], NULL); - } + GST_LOG ("reference frame %p to ref slot:%d", picture, i); + gst_vaapi_picture_replace (&priv->ref_frames[i], picture); } } From 4ccb37fe37dbb939cc148b4dfb596119c3cfa05e Mon Sep 17 00:00:00 2001 From: "Ung, Teng En" Date: Mon, 21 Dec 2020 05:36:29 +0000 Subject: [PATCH 3754/3781] vaapipostproc: Added gstreamer BT2020 color standard support. Part-of: --- gst-libs/gst/vaapi/gstvaapiutils.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index 46bb65ef0e..b4b680aa05 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -989,7 +989,9 @@ from_GstVideoColorimetry (const GstVideoColorimetry * const colorimetry) /* NOTE: VAProcColorStandardBT2020 in VAAPI is the same as * GST_VIDEO_COLORIMETRY_BT2020_10 in gstreamer. */ if (gst_video_colorimetry_matches (colorimetry, - GST_VIDEO_COLORIMETRY_BT2020_10)) + GST_VIDEO_COLORIMETRY_BT2020_10) || + gst_video_colorimetry_matches (colorimetry, + GST_VIDEO_COLORIMETRY_BT2020)) return VAProcColorStandardBT2020; if (gst_video_colorimetry_matches (colorimetry, GST_VIDEO_COLORIMETRY_BT601)) return VAProcColorStandardBT601; From a354c14e58f9afc6548668f5d6ed9bcc1a1d35f7 Mon Sep 17 00:00:00 2001 From: "Ung, Teng En" Date: Mon, 21 Dec 2020 05:42:00 +0000 Subject: [PATCH 3755/3781] vaapipostproc: Remove YUV to/from RGB color primary quirk since iHD driver has fixed in https://github.com/intel/media-driver/commit/a39fe9bc051a8c3efa8f35122a1585981ec7f816. Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay.c | 1 - gst-libs/gst/vaapi/gstvaapidisplay.h | 8 -------- gst-libs/gst/vaapi/gstvaapifilter.c | 16 ---------------- 3 files changed, 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 5e8a135dca..26c216e7e8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -805,7 +805,6 @@ set_driver_quirks (GstVaapiDisplay * display) /* @XXX(victor): is this string enough to identify it */ { "AMD", GST_VAAPI_DRIVER_QUIRK_NO_CHECK_SURFACE_PUT_IMAGE }, { "i965", GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD }, - { "iHD", GST_VAAPI_DRIVER_QUIRK_NO_RGBYUV_VPP_COLOR_PRIMARY }, { "i965", GST_VAAPI_DRIVER_QUIRK_MISSING_RGBA_IMAGE_FORMAT }, { "iHD", GST_VAAPI_DRIVER_QUIRK_JPEG_ENC_SHIFT_VALUE_BY_50 }, { "iHD", GST_VAAPI_DRIVER_QUIRK_HEVC_ENC_SLICE_NOT_SPAN_TILE }, diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 07ecc82f49..2ca9bd31f4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -94,13 +94,6 @@ typedef struct _GstVaapiDisplay GstVaapiDisplay; * 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_NO_RGBYUV_VPP_COLOR_PRIMARY: if driver can - * only do CSC from YUV to RGB, and vice-versa without changing the - * color standard primaries. This quirk is initially introduced to - * work around a problem in the intel-media-driver (iHD) reported here: - * https://github.com/intel/media-driver/issues/860. Once the driver - * issue is fixed, we should remove this quirk. Also see this issue: - * https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/issues/238 * @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: @@ -116,7 +109,6 @@ 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_NO_RGBYUV_VPP_COLOR_PRIMARY = (1U << 2), 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), diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index e3be777ad5..a9443e40fd 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -1642,22 +1642,6 @@ gst_vaapi_filter_fill_color_standards (GstVaapiFilter * filter, fill_color_standard (&filter->output_colorimetry, &pipeline_param->output_color_standard, &pipeline_param->output_color_properties); - - /* Handle RGB <-> YUV color primary driver quirk */ - if (gst_vaapi_display_has_driver_quirks (filter->display, - GST_VAAPI_DRIVER_QUIRK_NO_RGBYUV_VPP_COLOR_PRIMARY)) { - gboolean src_is_rgb = gst_video_colorimetry_matches - (&filter->input_colorimetry, GST_VIDEO_COLORIMETRY_SRGB); - gboolean dst_is_rgb = gst_video_colorimetry_matches - (&filter->output_colorimetry, GST_VIDEO_COLORIMETRY_SRGB); - - if ((!src_is_rgb && dst_is_rgb) || (src_is_rgb && !dst_is_rgb)) { - pipeline_param->output_color_standard = VAProcColorStandardExplicit; - pipeline_param->output_color_properties.colour_primaries = - gst_video_color_primaries_to_iso (filter-> - input_colorimetry.primaries); - } - } #else pipeline_param->surface_color_standard = VAProcColorStandardNone; pipeline_param->output_color_standard = VAProcColorStandardNone; From a0a8b8785e599f32175bd09415d6fdcd134d9cfa Mon Sep 17 00:00:00 2001 From: "Ung, Teng En" Date: Mon, 11 Jan 2021 09:57:03 +0800 Subject: [PATCH 3756/3781] vaapipostproc: fix code style. Part-of: --- gst-libs/gst/vaapi/gstvaapiutils.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c index b4b680aa05..ebec319478 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils.c +++ b/gst-libs/gst/vaapi/gstvaapiutils.c @@ -990,8 +990,7 @@ from_GstVideoColorimetry (const GstVideoColorimetry * const colorimetry) * GST_VIDEO_COLORIMETRY_BT2020_10 in gstreamer. */ if (gst_video_colorimetry_matches (colorimetry, GST_VIDEO_COLORIMETRY_BT2020_10) || - gst_video_colorimetry_matches (colorimetry, - GST_VIDEO_COLORIMETRY_BT2020)) + gst_video_colorimetry_matches (colorimetry, GST_VIDEO_COLORIMETRY_BT2020)) return VAProcColorStandardBT2020; if (gst_video_colorimetry_matches (colorimetry, GST_VIDEO_COLORIMETRY_BT601)) return VAProcColorStandardBT601; From c4e76d6fc57b792164356da57a20bbe23b8b7270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Wed, 20 Jan 2021 10:42:09 +0100 Subject: [PATCH 3757/3781] glx: Iterate over FBConfig and select 8 bit color size Texture upload mechanism used by gstreamer-vaapi relies on 8 bpc. In latest mesa versions the first fbconfig might not be 8 bit, so iterate over it to find the correct config with supported values. This also adds 8 bit alpha size to the framebuffer configuration which is required to get it working properly. Part-of: --- gst-libs/gst/vaapi/gstvaapiutils_glx.c | 40 ++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index ccd7832bab..f73106c242 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -301,9 +301,17 @@ gl_create_context (Display * dpy, int screen, GLContextState * parent) GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, + GLX_ALPHA_SIZE, 8, None }; + const GLint rgba_colors[4] = { + GLX_RED_SIZE, + GLX_GREEN_SIZE, + GLX_BLUE_SIZE, + GLX_ALPHA_SIZE + }; + cs = malloc (sizeof (*cs)); if (!cs) goto error; @@ -333,11 +341,38 @@ gl_create_context (Display * dpy, int screen, GLContextState * parent) if (!fbconfigs) goto error; - /* Find out a GLXFBConfig compatible with the parent context */ + /* Find out a 8 bit GLXFBConfig compatible with the parent context */ for (n = 0; n < n_fbconfigs; n++) { + gboolean sizes_correct = FALSE; + int cn; + status = glXGetFBConfigAttrib (parent->display, fbconfigs[n], GLX_FBCONFIG_ID, &val); - if (status == Success && val == fbconfig_id) + if (status != Success) + goto error; + if (val != fbconfig_id) + continue; + + /* Iterate over RGBA sizes in fbconfig */ + for (cn = 0; cn < 4; cn++) { + int size = 0; + + status = glXGetFBConfigAttrib (parent->display, + fbconfigs[n], rgba_colors[cn], &size); + if (status != Success) + goto error; + + /* Last check is for alpha + * and alpha is optional */ + if (cn == 3) { + if (size == 0 || size == 8) { + sizes_correct = TRUE; + break; + } + } else if (size != 8) + break; + } + if (sizes_correct) break; } if (n == n_fbconfigs) @@ -809,6 +844,7 @@ gl_create_pixmap_object (Display * dpy, guint width, guint height) GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, + GLX_ALPHA_SIZE, 8, GL_NONE, }; From 23967fc02bf1d9a1ecaf06704d024bdc8904e295 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Mon, 25 Jan 2021 14:45:47 +0800 Subject: [PATCH 3758/3781] libs: display: drm: fix set_device_path_from_fd drmGetBusid() (GET_UNIQUE ioctl) won't return a valid bus id when drmSetInterfaceVersion() (SET_VERSION ioctl) hasn't been called(see[1]), so we can't get the right device path. Running test-display will get the error below: ** (test-display:18630): ERROR **: 10:26:00.434: could not create Gst/VA display Calling drmSetInterfaceVersion() before drmGetBusid() can't fix this issue because a special permission is required for SET_VERSION ioctl. This patch retrieves the device path from file descriptor via g_file_read_link() [1] https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/drm_ioctl.c#L48-L104 Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 79 +++++++----------------- 1 file changed, 23 insertions(+), 56 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index ecc5a14fdf..d575ffd992 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -41,6 +41,16 @@ #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); @@ -182,14 +192,9 @@ set_device_path_from_fd (GstVaapiDisplay * display, gint drm_device) { GstVaapiDisplayDRMPrivate *const priv = GST_VAAPI_DISPLAY_DRM_PRIVATE (display); - const gchar *busid, *path, *str; - gsize busid_length, path_length; - struct udev *udev = NULL; - struct udev_device *device; - struct udev_enumerate *e = NULL; - struct udev_list_entry *l; gboolean success = FALSE; - gint i; + gchar fd_name[MAXPATHLEN]; + GError *error = NULL; g_free (priv->device_path); priv->device_path = NULL; @@ -197,61 +202,23 @@ set_device_path_from_fd (GstVaapiDisplay * display, gint drm_device) if (drm_device < 0) goto end; - busid = drmGetBusid (drm_device); - if (!busid) + 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; - - for (i = 0; allowed_subsystems[i] != NULL; i++) { - busid_length = strlen (allowed_subsystems[i]); - - if (strncmp (busid, allowed_subsystems[i], busid_length) == 0) { - busid += busid_length + 1; - busid_length = strlen (busid); - } } - if (allowed_subsystems[i] == NULL) - goto end; - - udev = udev_new (); - if (!udev) - goto end; - - e = udev_enumerate_new (udev); - if (!e) - goto end; - - udev_enumerate_add_match_subsystem (e, "drm"); - udev_enumerate_scan_devices (e); - udev_list_entry_foreach (l, udev_enumerate_get_list_entry (e)) { - path = udev_list_entry_get_name (l); - str = strstr (path, busid); - if (!str || str <= path || str[-1] != '/') - continue; - - path_length = strlen (path); - if (str + busid_length >= path + path_length) - continue; - if (strncmp (&str[busid_length], "/drm/card", 9) != 0 && - strncmp (&str[busid_length], "/drm/renderD", 12) != 0) - continue; - - device = udev_device_new_from_syspath (udev, path); - if (!device) - continue; - - path = udev_device_get_devnode (device); - priv->device_path = g_strdup (path); - udev_device_unref (device); - break; + 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; } - success = TRUE; end: - if (e) - udev_enumerate_unref (e); - if (udev) - udev_unref (udev); return success; } From 85284f4aacc9cfc059c59aa033166fedc247e117 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Wed, 13 Jan 2021 14:43:20 +0800 Subject: [PATCH 3759/3781] libs: display: drm: allow user specify a drm device via an env variable Currently the default drm device is always used on a system with multiple drm devices. This patch allows user to specify the required drm device via GST_VAAPI_DRM_DEVICE env variable Example: GST_VAAPI_DRM_DEVICE=/dev/dri/renderD129 gst-launch-1.0 videotestsrc ! vaapih264enc ! fakesink Part-of: --- docs/index.md | 5 +++++ gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 22 +++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/docs/index.md b/docs/index.md index b95c2a7d70..dcdf204c7d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -27,3 +27,8 @@ example, intel's driver is `i915`, meanwhile mesa is `gallium`. 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. diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index d575ffd992..7f4d3996d6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -337,15 +337,27 @@ GstVaapiDisplay * gst_vaapi_display_drm_new (const gchar * device_path) { GstVaapiDisplay *display; - guint types[2], i, num_types = 0; + guint types[3], i, num_types = 0; + gpointer device_paths[3]; g_mutex_lock (&g_drm_device_type_lock); - if (device_path) + if (device_path) { + device_paths[num_types] = (gpointer) device_path; types[num_types++] = 0; - else if (g_drm_device_type) + } else if (g_drm_device_type) { + device_paths[num_types] = (gpointer) device_path; types[num_types++] = g_drm_device_type; - else { + } else { + const gchar *user_choice = g_getenv ("GST_VAAPI_DRM_DEVICE"); + + if (user_choice && g_str_has_prefix (user_choice, "/dev/dri/")) { + device_paths[num_types] = (gpointer) user_choice; + types[num_types++] = 0; + } + + 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; } @@ -353,7 +365,7 @@ gst_vaapi_display_drm_new (const gchar * device_path) 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, (gpointer) device_path); + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, device_paths[i]); if (display || device_path) break; } From 4ff4bcd725290c8f1a52e791496f164c3090ecaa Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Wed, 27 Jan 2021 12:05:44 +0800 Subject: [PATCH 3760/3781] libs: display: drm: support gst.vaapi.app.Display context for drm backend Attributes for drm backend: - va-display : ponter of VADisplay - drm-device-fd : the DRM device file descriptor Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 34 ++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidisplay_drm.h | 3 +++ gst/vaapi/gstvaapivideocontext.c | 12 +++++++++ 3 files changed, 49 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 7f4d3996d6..c4e5001d13 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -396,6 +396,40 @@ gst_vaapi_display_drm_new_with_device (gint device) 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 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h index 5424b32456..199c6eae7d 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h @@ -39,6 +39,9 @@ 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); diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index 2528ff3728..bd3db01d92 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -34,6 +34,9 @@ #if USE_WAYLAND #include #endif +#if USE_DRM +#include +#endif GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); @@ -117,6 +120,15 @@ gst_vaapi_video_context_get_display (GstContext * context, gboolean app_context, } } #endif +#if USE_DRM + if (!display) { + gint fd = -1; + if (gst_structure_get (structure, "drm-device-fd", G_TYPE_INT, &fd, + NULL)) { + display = gst_vaapi_display_drm_new_with_va_display (va_display, fd); + } + } +#endif _init_context_debug (); From 18f530978be95f39aaf53fe9dd7dea70149365a7 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 4 Feb 2021 15:05:55 +0800 Subject: [PATCH 3761/3781] plugins: postproc: Fix a problem of propose_allocation when passthrough. We should query the downstream element to answer a precise allocation query when the passthrough mode is enabled. The current way still decides the allocation by the postproc itself. The pipeline such as: gst-launch-1.0 -v filesrc location=xxx.264 ! h264parse ! vaapih264dec ! \ vaapipostproc ! fakevideosink silent=false sync=true will lose some info such as the GST_VIDEO_META_API_TYPE. Part-of: --- gst/vaapi/gstvaapipostproc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 5f7d9cd8bc..052ee4fa3c 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -1801,6 +1801,13 @@ gst_vaapipostproc_propose_allocation (GstBaseTransform * trans, gint allocation_width, allocation_height; gint negotiated_width, negotiated_height; + /* passthrough query, we just bypass to the peer */ + if (decide_query == NULL) { + return GST_BASE_TRANSFORM_CLASS + (gst_vaapipostproc_parent_class)->propose_allocation (trans, + decide_query, query); + } + /* advertise to upstream that we can handle crop meta */ if (decide_query) gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL); From e1f6c37b46997a8244690b4c85d7f7fcd5307373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Goulpi=C3=A9?= Date: Wed, 24 Feb 2021 17:41:02 +0100 Subject: [PATCH 3762/3781] gstvaapiencoder_h264: add ENCODER_EXPOSURE on aud propertie MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit forgot during the following mainline commit: https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/commit/bc2f8fd19e924aa0e193708307326acd037691ce# Signed-off-by: Paul Goulpié --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index c36fa829fb..ad56cca2c4 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -4026,7 +4026,8 @@ gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass) properties[ENCODER_H264_PROP_AUD] = g_param_spec_boolean ("aud", "AU delimiter", "Use AU (Access Unit) delimeter", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | + GST_VAAPI_PARAM_ENCODER_EXPOSURE); /** * GstVaapiEncoderH264:Compliance Mode: From d270654c48c19afc3234e126269bf613540b44d8 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Fri, 19 Mar 2021 17:42:36 +1100 Subject: [PATCH 3763/3781] gst: don't use volatile to mean atomic volatile is not sufficient to provide atomic guarantees and real atomics should be used instead. GCC 11 has started warning about using volatile with atomic operations. https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1719 Discovered in https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/868 Part-of: --- gst-libs/gst/vaapi/gstvaapicontext.c | 2 +- gst-libs/gst/vaapi/gstvaapicontext.h | 2 +- gst-libs/gst/vaapi/gstvaapiencoder.c | 4 ++-- gst-libs/gst/vaapi/gstvaapifilter.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiminiobject.c | 2 +- gst-libs/gst/vaapi/gstvaapiminiobject.h | 2 +- gst-libs/gst/vaapi/gstvaapitexture_glx.c | 2 +- gst-libs/gst/vaapi/gstvaapiutils_egl.c | 4 ++-- gst-libs/gst/vaapi/gstvaapiutils_egl.h | 2 +- gst-libs/gst/vaapi/gstvaapivalue.c | 10 +++++----- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 2 +- gst/vaapi/gstvaapipluginbase.c | 2 +- gst/vaapi/gstvaapisink.c | 6 +++--- gst/vaapi/gstvaapisink.h | 2 +- gst/vaapi/gstvaapivideocontext.c | 2 +- gst/vaapi/gstvaapivideomemory.c | 4 ++-- tests/internal/simple-decoder.c | 12 ++++++------ 17 files changed, 32 insertions(+), 32 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c index 52fd751b51..88cd1105f3 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.c +++ b/gst-libs/gst/vaapi/gstvaapicontext.c @@ -51,7 +51,7 @@ static void _init_vaapi_context_debug (void) { #ifndef GST_DISABLE_GST_DEBUG - static volatile gsize _init = 0; + static gsize _init = 0; if (g_once_init_enter (&_init)) { GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_context, "vaapicontext", 0, diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h index 820fa63985..7117722b4f 100644 --- a/gst-libs/gst/vaapi/gstvaapicontext.h +++ b/gst-libs/gst/vaapi/gstvaapicontext.h @@ -100,7 +100,7 @@ struct _GstVaapiContextInfo struct _GstVaapiContext { /*< private >*/ - volatile gint ref_count; + gint ref_count; GstVaapiDisplay *display; GstVaapiID object_id; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 83d26f0f1b..6c103acec9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -1822,7 +1822,7 @@ out: GType gst_vaapi_encoder_tune_get_type (void) { - static volatile gsize g_type = 0; + static gsize g_type = 0; static const GEnumValue encoder_tune_values[] = { /* *INDENT-OFF* */ @@ -1850,7 +1850,7 @@ gst_vaapi_encoder_tune_get_type (void) GType gst_vaapi_encoder_mbbrc_get_type (void) { - static volatile gsize g_type = 0; + static gsize g_type = 0; if (g_once_init_enter (&g_type)) { static const GEnumValue encoder_mbbrc_values[] = { diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index a9443e40fd..e0b3cd5fad 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -38,7 +38,7 @@ struct _GstVaapiFilterOpData { GstVaapiFilterOp op; GParamSpec *pspec; - volatile gint ref_count; + gint ref_count; guint va_type; guint va_subtype; gpointer va_caps; @@ -550,7 +550,7 @@ op_data_new (GstVaapiFilterOp op, GParamSpec * pspec) op_data->op = op; op_data->pspec = pspec; - op_data->ref_count = 1; + g_atomic_int_set (&op_data->ref_count, 1); op_data->va_buffer = VA_INVALID_ID; switch (op) { diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.c b/gst-libs/gst/vaapi/gstvaapiminiobject.c index 7b18983245..30586b04be 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.c @@ -70,7 +70,7 @@ gst_vaapi_mini_object_new (const GstVaapiMiniObjectClass * object_class) return NULL; object->object_class = object_class; - object->ref_count = 1; + g_atomic_int_set (&object->ref_count, 1); object->flags = 0; return object; } diff --git a/gst-libs/gst/vaapi/gstvaapiminiobject.h b/gst-libs/gst/vaapi/gstvaapiminiobject.h index 778fc07b37..52f28636de 100644 --- a/gst-libs/gst/vaapi/gstvaapiminiobject.h +++ b/gst-libs/gst/vaapi/gstvaapiminiobject.h @@ -120,7 +120,7 @@ struct _GstVaapiMiniObject { /*< private >*/ gconstpointer object_class; - volatile gint ref_count; + gint ref_count; guint flags; }; diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.c b/gst-libs/gst/vaapi/gstvaapitexture_glx.c index 273afc9bac..76f450add6 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_glx.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.c @@ -249,7 +249,7 @@ GstVaapiGLApi gl_get_curent_api_once () { static GstVaapiGLApi cur_api = GST_VAAPI_GL_API_NONE; - static volatile gsize _init = 0; + static gsize _init = 0; if (g_once_init_enter (&_init)) { cur_api = gl_get_current_api (NULL, NULL); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.c b/gst-libs/gst/vaapi/gstvaapiutils_egl.c index 0c2a1f5a11..99ae37d291 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.c @@ -614,7 +614,7 @@ egl_display_thread (gpointer data) g_cond_broadcast (&display->gl_thread_ready); g_mutex_unlock (&display->mutex); - while (!display->gl_thread_cancel) { + while (!g_atomic_int_get (&display->gl_thread_cancel)) { EglMessage *const msg = g_async_queue_timeout_pop (display->gl_queue, 100000); @@ -671,7 +671,7 @@ egl_display_init (EglDisplay * display) static void egl_display_finalize (EglDisplay * display) { - display->gl_thread_cancel = TRUE; + g_atomic_int_set (&display->gl_thread_cancel, TRUE); g_thread_join (display->gl_thread); g_cond_clear (&display->gl_thread_ready); g_mutex_clear (&display->mutex); diff --git a/gst-libs/gst/vaapi/gstvaapiutils_egl.h b/gst-libs/gst/vaapi/gstvaapiutils_egl.h index abf3735e7b..20b553eab8 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_egl.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_egl.h @@ -120,7 +120,7 @@ struct egl_display_s GMutex mutex; GThread *gl_thread; GCond gl_thread_ready; - volatile gboolean gl_thread_cancel; + gboolean gl_thread_cancel; GAsyncQueue *gl_queue; gboolean created; }; diff --git a/gst-libs/gst/vaapi/gstvaapivalue.c b/gst-libs/gst/vaapi/gstvaapivalue.c index 1e0121331f..62e440b63a 100644 --- a/gst-libs/gst/vaapi/gstvaapivalue.c +++ b/gst-libs/gst/vaapi/gstvaapivalue.c @@ -50,7 +50,7 @@ default_free_func (gpointer data) GType gst_vaapi_point_get_type (void) { - static volatile gsize g_type = 0; + static gsize g_type = 0; if (g_once_init_enter (&g_type)) { GType type = @@ -67,7 +67,7 @@ gst_vaapi_point_get_type (void) GType gst_vaapi_rectangle_get_type (void) { - static volatile gsize g_type = 0; + static gsize g_type = 0; if (g_once_init_enter (&g_type)) { GType type = @@ -85,7 +85,7 @@ gst_vaapi_rectangle_get_type (void) GType gst_vaapi_render_mode_get_type (void) { - static volatile gsize g_type = 0; + static gsize g_type = 0; static const GEnumValue render_modes[] = { {GST_VAAPI_RENDER_MODE_OVERLAY, @@ -108,7 +108,7 @@ gst_vaapi_render_mode_get_type (void) GType gst_vaapi_rotation_get_type (void) { - static volatile gsize g_type = 0; + static gsize g_type = 0; static const GEnumValue rotation_values[] = { {GST_VAAPI_ROTATION_0, @@ -137,7 +137,7 @@ gst_vaapi_rotation_get_type (void) GType gst_vaapi_rate_control_get_type (void) { - static volatile gsize g_type = 0; + static gsize g_type = 0; static const GEnumValue rate_control_values[] = { {GST_VAAPI_RATECONTROL_NONE, diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index caf1dc63a8..394a089bb5 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -98,7 +98,7 @@ struct _GstVaapiWindowWaylandPrivate guint is_shown:1; guint fullscreen_on_show:1; guint sync_failed:1; - volatile guint num_frames_pending; + guint num_frames_pending; gint configure_pending; gboolean need_vpp; gboolean dmabuf_broken; diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 3a8664ba1a..a670e976e5 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -1546,7 +1546,7 @@ static void _init_performance_debug (void) { #ifndef GST_DISABLE_GST_DEBUG - static volatile gsize _init = 0; + static gsize _init = 0; if (g_once_init_enter (&_init)) { GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE"); diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index e722b71307..9b5ae9825c 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -976,7 +976,7 @@ static gpointer gst_vaapisink_event_thread (GstVaapiSink * sink) { GST_OBJECT_LOCK (sink); - while (!sink->event_thread_cancel) { + while (!g_atomic_int_get (&sink->event_thread_cancel)) { GST_OBJECT_UNLOCK (sink); sink->backend->handle_events (sink); g_usleep (G_USEC_PER_SEC / 20); @@ -1001,7 +1001,7 @@ gst_vaapisink_set_event_handling (GstVaapiSink * sink, gboolean handle_events) if (sink->backend->pre_start_event_thread) sink->backend->pre_start_event_thread (sink); - sink->event_thread_cancel = FALSE; + g_atomic_int_set (&sink->event_thread_cancel, FALSE); sink->event_thread = g_thread_try_new ("vaapisink-events", (GThreadFunc) gst_vaapisink_event_thread, sink, NULL); } else if (!handle_events && sink->event_thread) { @@ -1012,7 +1012,7 @@ gst_vaapisink_set_event_handling (GstVaapiSink * sink, gboolean handle_events) /* Grab thread and mark it as NULL */ thread = sink->event_thread; sink->event_thread = NULL; - sink->event_thread_cancel = TRUE; + g_atomic_int_set (&sink->event_thread_cancel, TRUE); } GST_OBJECT_UNLOCK (sink); diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 1fb6e832c2..525f422164 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -99,7 +99,7 @@ struct _GstVaapiSink guint color_standard; gint32 view_id; GThread *event_thread; - volatile gboolean event_thread_cancel; + gboolean event_thread_cancel; /* Color balance values */ guint cb_changed; diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index bd3db01d92..ae3af85dc1 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -44,7 +44,7 @@ static void _init_context_debug (void) { #ifndef GST_DISABLE_GST_DEBUG - static volatile gsize _init = 0; + static gsize _init = 0; if (g_once_init_enter (&_init)) { GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"); diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index abf9715777..750385a493 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -47,7 +47,7 @@ static void _init_performance_debug (void) { #ifndef GST_DISABLE_GST_DEBUG - static volatile gsize _init = 0; + static gsize _init = 0; if (g_once_init_enter (&_init)) { GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE"); @@ -60,7 +60,7 @@ static void _init_vaapi_video_memory_debug (void) { #ifndef GST_DISABLE_GST_DEBUG - static volatile gsize _init = 0; + static gsize _init = 0; if (g_once_init_enter (&_init)) { GST_DEBUG_CATEGORY_INIT (gst_debug_vaapivideomemory, "vaapivideomemory", 0, diff --git a/tests/internal/simple-decoder.c b/tests/internal/simple-decoder.c index 134b845145..7575276729 100644 --- a/tests/internal/simple-decoder.c +++ b/tests/internal/simple-decoder.c @@ -85,7 +85,7 @@ typedef struct GstVaapiDisplay *display; GstVaapiDecoder *decoder; GThread *decoder_thread; - volatile gboolean decoder_thread_cancel; + gboolean decoder_thread_cancel; GAsyncQueue *decoder_queue; GstVaapiCodec codec; guint fps_n; @@ -97,7 +97,7 @@ typedef struct guint window_width; guint window_height; GThread *render_thread; - volatile gboolean render_thread_cancel; + gboolean render_thread_cancel; GCond render_ready; RenderFrame *last_frame; GError *error; @@ -241,7 +241,7 @@ decoder_thread (gpointer data) pts = g_get_monotonic_time (); ofs = 0; - while (!app->decoder_thread_cancel) { + while (!g_atomic_int_get (&app->decoder_thread_cancel)) { if (G_UNLIKELY (ofs == app->file_size)) buffer = NULL; else { @@ -376,7 +376,7 @@ stop_decoder (App * app) { g_timer_stop (app->timer); - app->decoder_thread_cancel = TRUE; + g_atomic_int_set (&app->decoder_thread_cancel, TRUE); g_thread_join (app->decoder_thread); g_print ("Decoder thread stopped\n"); return TRUE; @@ -462,7 +462,7 @@ renderer_thread (gpointer data) g_print ("Render thread started\n"); - while (!app->render_thread_cancel) { + while (!g_atomic_int_get (&app->render_thread_cancel)) { rfp = g_async_queue_timeout_pop (app->decoder_queue, 1000000); if (rfp && !renderer_process (app, rfp)) break; @@ -497,7 +497,7 @@ start_renderer (App * app) static gboolean stop_renderer (App * app) { - app->render_thread_cancel = TRUE; + g_atomic_int_set (&app->render_thread_cancel, TRUE); g_thread_join (app->render_thread); g_print ("Render thread stopped\n"); From 993d46bb2ff28169b269e4a9f951539cc2da6f24 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 22 Mar 2021 13:41:13 +0800 Subject: [PATCH 3764/3781] decoder: H265: Enable cu_qp_delta_enabled_flag when ROI If ROI is enabled, the CUs within the ROI region may have different QP from the other part of the picture. This needs us to enable the cu_qp_delta_enabled_flag even in the CQP mode. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder.c | 6 +++++- gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 1 + gst-libs/gst/vaapi/gstvaapiencoder_objects.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 6c103acec9..8ab33ca545 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -193,6 +193,8 @@ gst_vaapi_encoder_ensure_param_roi_regions (GstVaapiEncoder * encoder, g_quark_to_string (roi->roi_type), roi->id, roi->x, roi->y, roi->w, roi->h); + picture->has_roi = TRUE; + region_roi[i].roi_rectangle.x = roi->x; region_roi[i].roi_rectangle.y = roi->y; region_roi[i].roi_rectangle.width = roi->w; @@ -214,7 +216,9 @@ gst_vaapi_encoder_ensure_param_roi_regions (GstVaapiEncoder * encoder, } } - gst_vaapi_enc_picture_add_misc_param (picture, misc); + if (picture->has_roi) + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); #endif return TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 46db870c3c..caec85f041 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -2033,6 +2033,7 @@ fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture, /* it seems driver requires enablement of cu_qp_delta_enabled_flag * to modifiy QP values in CBR mode or low power encoding */ if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CQP + || picture->has_roi || encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) pic_param->pic_fields.bits.cu_qp_delta_enabled_flag = 1; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h index 8037c1842d..49f271dcd9 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h @@ -266,6 +266,7 @@ struct _GstVaapiEncPicture guint frame_num; guint poc; guint temporal_id; + gboolean has_roi; }; G_GNUC_INTERNAL From 0193751ce844776ef1823f99aff053ee423f7004 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Fri, 2 Apr 2021 15:43:45 +0800 Subject: [PATCH 3765/3781] libs: display: drm: don't fallback to default device if explicitly specified device can't load/init Otherwise user will be misled that the specified device is using This fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/issues/305 Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index c4e5001d13..1fc376a520 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -350,15 +350,15 @@ gst_vaapi_display_drm_new (const gchar * device_path) } else { const gchar *user_choice = g_getenv ("GST_VAAPI_DRM_DEVICE"); - if (user_choice && g_str_has_prefix (user_choice, "/dev/dri/")) { + 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; } - - 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++) { From 722d6bb625ca825b7d15142fe5e4343ed7d5a6c8 Mon Sep 17 00:00:00 2001 From: Zhang yuankun Date: Fri, 23 Apr 2021 11:02:05 +0800 Subject: [PATCH 3766/3781] libs: encoder: VP9: fix > 4k encode fail issue The VP9 spec defines the MAX_TILE_WIDTH_B64(64), which is the maximum width of a tile in units of superblocks. So the max width of one tile should not be larger than 64x64=4096. When the width exceeds 4k, we need to split it into multiple tiles in columns. The current vp9 encoder does not handle this correctly. The command such as: gst-launch-1.0 videotestsrc ! video/x-raw,width=7680,height=4320 ! \ vaapivp9enc ! fakesink will crash. Part-of: --- gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index bb338452c1..bd47c0d644 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -33,6 +33,8 @@ #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 @@ -356,6 +358,7 @@ fill_picture (GstVaapiEncoderVP9 * encoder, 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)); @@ -399,6 +402,14 @@ fill_picture (GstVaapiEncoderVP9 * encoder, 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; From 2080979d102a34dbb8710d36ea45374cadf38d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Laignel?= Date: Wed, 21 Apr 2021 10:55:45 +0200 Subject: [PATCH 3767/3781] Use gst_element_request_pad_simple... Instead of the deprecated gst_element_get_request_pad. Part-of: --- tests/check/elements/vaapioverlay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/check/elements/vaapioverlay.c b/tests/check/elements/vaapioverlay.c index 7a729873cc..b218759b1f 100644 --- a/tests/check/elements/vaapioverlay.c +++ b/tests/check/elements/vaapioverlay.c @@ -125,14 +125,14 @@ GST_START_TEST (test_overlay_position) gst_element_link (overlay, sink); srcpad = gst_element_get_static_pad (filter1, "src"); - sinkpad = gst_element_get_request_pad (overlay, "sink_0"); + sinkpad = gst_element_request_pad_simple (overlay, "sink_0"); g_object_set (sinkpad, "xpos", 0, "ypos", 0, "alpha", 1.0, NULL); gst_pad_link (srcpad, sinkpad); gst_object_unref (sinkpad); gst_object_unref (srcpad); srcpad = gst_element_get_static_pad (filter2, "src"); - sinkpad = gst_element_get_request_pad (overlay, "sink_1"); + sinkpad = gst_element_request_pad_simple (overlay, "sink_1"); g_object_set (sinkpad, "xpos", 10, "ypos", 10, "alpha", 1.0, NULL); gst_pad_link (srcpad, sinkpad); gst_object_unref (sinkpad); From b3d9c5bf803d282b0581eec338c3ae2ecfe0a4e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 20 May 2021 10:28:05 +0200 Subject: [PATCH 3768/3781] plugins: Demote rank of vaapipostproc and vaapioverlay. Since almost all video filters have rank NONE, these both elements should be NONE too. This is useful for autovideoconvert and other bins, and users might force to use these by setting the environment variable GST_PLUGIN_FEATURE_RANK. Part-of: --- gst/vaapi/gstvaapi.c | 2 +- gst/vaapi/gstvaapioverlay.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index d4499f6c50..3532624839 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -207,7 +207,7 @@ plugin_init (GstPlugin * plugin) gst_vaapioverlay_register (plugin, display); gst_element_register (plugin, "vaapipostproc", - GST_RANK_PRIMARY, GST_TYPE_VAAPIPOSTPROC); + GST_RANK_NONE, GST_TYPE_VAAPIPOSTPROC); gst_element_register (plugin, "vaapidecodebin", GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); diff --git a/gst/vaapi/gstvaapioverlay.c b/gst/vaapi/gstvaapioverlay.c index 53efdace2d..c70b01a103 100644 --- a/gst/vaapi/gstvaapioverlay.c +++ b/gst/vaapi/gstvaapioverlay.c @@ -681,6 +681,6 @@ gst_vaapioverlay_register (GstPlugin * plugin, GstVaapiDisplay * display) return FALSE; gst_vaapi_blend_replace (&blend, NULL); - return gst_element_register (plugin, "vaapioverlay", - GST_RANK_PRIMARY, GST_TYPE_VAAPI_OVERLAY); + return gst_element_register (plugin, "vaapioverlay", GST_RANK_NONE, + GST_TYPE_VAAPI_OVERLAY); } From 7a25c5d4ec95aefeca6515ac023b23c5dd330194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 23 Apr 2021 19:01:54 +0200 Subject: [PATCH 3769/3781] vaapi: Demote vaapidecodebin to rank NONE. One of the main reasons of vaapidecodebin was because it mitigated the possible surface exhaustion. But that problem is currently solved. Nowadays, vaapidecodebin brings more problems than it solves. Thus this patch demotes vaapidecodebin to NONE rank while bumping PRIMARY + 1 the most common decoders. Part-of: --- gst/vaapi/gstvaapi.c | 2 +- gst/vaapi/gstvaapidecode.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 3532624839..56ee703f04 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -210,7 +210,7 @@ plugin_init (GstPlugin * plugin) GST_RANK_NONE, GST_TYPE_VAAPIPOSTPROC); gst_element_register (plugin, "vaapidecodebin", - GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); + GST_RANK_NONE, GST_TYPE_VAAPI_DECODE_BIN); rank = GST_RANK_SECONDARY; if (g_getenv ("WAYLAND_DISPLAY")) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 76d1bc47ce..4e8d35fbfc 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -115,14 +115,14 @@ static const GstVaapiDecoderMap vaapi_decode_map[] = { {GST_VAAPI_CODEC_MPEG4, GST_RANK_PRIMARY, "mpeg4", "video/mpeg, mpegversion=4", NULL}, {GST_VAAPI_CODEC_H263, GST_RANK_PRIMARY, "h263", "video/x-h263", NULL}, - {GST_VAAPI_CODEC_H264, GST_RANK_PRIMARY, "h264", "video/x-h264", + {GST_VAAPI_CODEC_H264, GST_RANK_PRIMARY + 1, "h264", "video/x-h264", gst_vaapi_decode_h264_install_properties}, - {GST_VAAPI_CODEC_VC1, GST_RANK_PRIMARY, "vc1", + {GST_VAAPI_CODEC_VC1, GST_RANK_PRIMARY + 1, "vc1", "video/x-wmv, wmvversion=3, format={WMV3,WVC1}", NULL}, - {GST_VAAPI_CODEC_VP8, GST_RANK_PRIMARY, "vp8", "video/x-vp8", NULL}, - {GST_VAAPI_CODEC_VP9, GST_RANK_PRIMARY, "vp9", "video/x-vp9", NULL}, - {GST_VAAPI_CODEC_H265, GST_RANK_PRIMARY, "h265", "video/x-h265", NULL}, - {GST_VAAPI_CODEC_AV1, GST_RANK_PRIMARY, "av1", "video/x-av1", NULL}, + {GST_VAAPI_CODEC_VP8, GST_RANK_PRIMARY + 1, "vp8", "video/x-vp8", NULL}, + {GST_VAAPI_CODEC_VP9, GST_RANK_PRIMARY + 1, "vp9", "video/x-vp9", NULL}, + {GST_VAAPI_CODEC_H265, GST_RANK_PRIMARY + 1, "h265", "video/x-h265", NULL}, + {GST_VAAPI_CODEC_AV1, GST_RANK_PRIMARY + 1, "av1", "video/x-av1", NULL}, {0 /* the rest */ , GST_RANK_PRIMARY + 1, NULL, gst_vaapidecode_sink_caps_str, NULL}, }; From 5e67efbf27715b8704512fbb7a25dc621ae034fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 1 Jun 2021 00:16:31 +0100 Subject: [PATCH 3770/3781] Release 1.19.1 --- ChangeLog | 479 ++++++++++ NEWS | 2056 ++---------------------------------------- RELEASE | 15 +- gstreamer-vaapi.doap | 10 + meson.build | 2 +- 5 files changed, 570 insertions(+), 1992 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8eab5c1a49..182a2ed27b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,486 @@ +=== release 1.19.1 === + +2021-06-01 00:16:31 +0100 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * RELEASE: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.19.1 + +2021-04-23 19:01:54 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + vaapi: Demote vaapidecodebin to rank NONE. + One of the main reasons of vaapidecodebin was because it mitigated the + possible surface exhaustion. But that problem is currently + solved. Nowadays, vaapidecodebin brings more problems than it + solves. Thus this patch demotes vaapidecodebin to NONE rank while + bumping PRIMARY + 1 the most common decoders. + Part-of: + +2021-05-20 10:28:05 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapioverlay.c: + plugins: Demote rank of vaapipostproc and vaapioverlay. + Since almost all video filters have rank NONE, these both elements + should be NONE too. + This is useful for autovideoconvert and other bins, and users might + force to use these by setting the environment variable + GST_PLUGIN_FEATURE_RANK. + Part-of: + +2021-04-21 10:55:45 +0200 François Laignel + + * tests/check/elements/vaapioverlay.c: + Use gst_element_request_pad_simple... + Instead of the deprecated gst_element_get_request_pad. + Part-of: + +2021-04-23 11:02:05 +0800 Zhang yuankun + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: VP9: fix > 4k encode fail issue + The VP9 spec defines the MAX_TILE_WIDTH_B64(64), which is the maximum + width of a tile in units of superblocks. So the max width of one tile + should not be larger than 64x64=4096. When the width exceeds 4k, we + need to split it into multiple tiles in columns. The current vp9 encoder + does not handle this correctly. + The command such as: + gst-launch-1.0 videotestsrc ! video/x-raw,width=7680,height=4320 ! \ + vaapivp9enc ! fakesink + will crash. + Part-of: + +2021-04-02 15:43:45 +0800 Haihao Xiang + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + libs: display: drm: don't fallback to default device if explicitly specified device can't load/init + Otherwise user will be misled that the specified device is using + This fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/issues/305 + Part-of: + +2021-03-22 13:41:13 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiencoder_objects.h: + decoder: H265: Enable cu_qp_delta_enabled_flag when ROI + If ROI is enabled, the CUs within the ROI region may have different + QP from the other part of the picture. This needs us to enable the + cu_qp_delta_enabled_flag even in the CQP mode. + Part-of: + +2021-03-19 17:42:36 +1100 Matthew Waters + + * gst-libs/gst/vaapi/gstvaapicontext.c: + * gst-libs/gst/vaapi/gstvaapicontext.h: + * gst-libs/gst/vaapi/gstvaapiencoder.c: + * gst-libs/gst/vaapi/gstvaapifilter.c: + * gst-libs/gst/vaapi/gstvaapiminiobject.c: + * gst-libs/gst/vaapi/gstvaapiminiobject.h: + * gst-libs/gst/vaapi/gstvaapitexture_glx.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.c: + * gst-libs/gst/vaapi/gstvaapiutils_egl.h: + * gst-libs/gst/vaapi/gstvaapivalue.c: + * gst-libs/gst/vaapi/gstvaapiwindow_wayland.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapisink.c: + * gst/vaapi/gstvaapisink.h: + * gst/vaapi/gstvaapivideocontext.c: + * gst/vaapi/gstvaapivideomemory.c: + * tests/internal/simple-decoder.c: + gst: don't use volatile to mean atomic + volatile is not sufficient to provide atomic guarantees and real atomics + should be used instead. GCC 11 has started warning about using volatile + with atomic operations. + https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1719 + Discovered in https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/868 + Part-of: + +2021-02-24 17:41:02 +0100 Paul Goulpié + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + gstvaapiencoder_h264: add ENCODER_EXPOSURE on aud propertie + forgot during the following mainline commit: https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/commit/bc2f8fd19e924aa0e193708307326acd037691ce# + Signed-off-by: Paul Goulpié + +2021-02-04 15:05:55 +0800 He Junyan + + * gst/vaapi/gstvaapipostproc.c: + plugins: postproc: Fix a problem of propose_allocation when passthrough. + We should query the downstream element to answer a precise allocation + query when the passthrough mode is enabled. + The current way still decides the allocation by the postproc itself. The + pipeline such as: + gst-launch-1.0 -v filesrc location=xxx.264 ! h264parse ! vaapih264dec ! \ + vaapipostproc ! fakevideosink silent=false sync=true + will lose some info such as the GST_VIDEO_META_API_TYPE. + Part-of: + +2021-01-27 12:05:44 +0800 Haihao Xiang + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.h: + * gst/vaapi/gstvaapivideocontext.c: + libs: display: drm: support gst.vaapi.app.Display context for drm backend + Attributes for drm backend: + - va-display : ponter of VADisplay + - drm-device-fd : the DRM device file descriptor + Part-of: + +2021-01-13 14:43:20 +0800 Haihao Xiang + + * docs/index.md: + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + libs: display: drm: allow user specify a drm device via an env variable + Currently the default drm device is always used on a system with + multiple drm devices. This patch allows user to specify the required + drm device via GST_VAAPI_DRM_DEVICE env variable + Example: + GST_VAAPI_DRM_DEVICE=/dev/dri/renderD129 gst-launch-1.0 videotestsrc ! + vaapih264enc ! fakesink + Part-of: + +2021-01-25 14:45:47 +0800 Haihao Xiang + + * gst-libs/gst/vaapi/gstvaapidisplay_drm.c: + libs: display: drm: fix set_device_path_from_fd + drmGetBusid() (GET_UNIQUE ioctl) won't return a valid bus id when + drmSetInterfaceVersion() (SET_VERSION ioctl) hasn't been called(see[1]), + so we can't get the right device path. Running test-display will get the + error below: + ** (test-display:18630): ERROR **: 10:26:00.434: could not create Gst/VA + display + Calling drmSetInterfaceVersion() before drmGetBusid() can't fix this + issue because a special permission is required for SET_VERSION ioctl. + This patch retrieves the device path from file descriptor via + g_file_read_link() + [1] https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/drm_ioctl.c#L48-L104 + Part-of: + +2021-01-20 10:42:09 +0100 Rafał Dzięgiel + + * gst-libs/gst/vaapi/gstvaapiutils_glx.c: + glx: Iterate over FBConfig and select 8 bit color size + Texture upload mechanism used by gstreamer-vaapi relies on 8 bpc. + In latest mesa versions the first fbconfig might not be 8 bit, so iterate + over it to find the correct config with supported values. + This also adds 8 bit alpha size to the framebuffer configuration which is + required to get it working properly. + Part-of: + +2021-01-11 09:57:03 +0800 Ung, Teng En + + * gst-libs/gst/vaapi/gstvaapiutils.c: + vaapipostproc: fix code style. + Part-of: + +2020-12-21 05:42:00 +0000 Ung, Teng En + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst-libs/gst/vaapi/gstvaapidisplay.h: + * gst-libs/gst/vaapi/gstvaapifilter.c: + vaapipostproc: Remove YUV to/from RGB color primary quirk since iHD driver has fixed in https://github.com/intel/media-driver/commit/a39fe9bc051a8c3efa8f35122a1585981ec7f816. + Part-of: + +2020-12-21 05:36:29 +0000 Ung, Teng En + + * gst-libs/gst/vaapi/gstvaapiutils.c: + vaapipostproc: Added gstreamer BT2020 color standard support. + Part-of: + +2021-01-09 16:05:48 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_av1.c: + decoder: AV1: Fix a static analysis problem of update_state(). + No need to check the picture pointer after we have already dereferenced it. + Fix: #298 + Part-of: + +2020-12-22 23:43:52 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_av1.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + libs: decoder: Add decode_with_surface_id for AV1 film_grain. + The AV1 film_graim feature needs two surfaces the same time for + decoding. One is for recon surface which will be used as reference + later, and the other one is for display. The GstVaapiPicture should + contain the surface for display, while the vaBeginPicture() need + the recon surface as the target. + We add a gst_vaapi_picture_decode_with_surface_id API to handle this + kind of requirement. + Part-of: + +2020-08-27 21:46:41 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_av1.c: + * gst-libs/gst/vaapi/gstvaapidecoder_av1.h: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapiutils.c: + * gst-libs/gst/vaapi/meson.build: + * gst/vaapi/gstvaapidecode.c: + * meson.build: + libs: decoder: AV1: Add the av1 decoder support. + Part-of: + +2020-08-27 21:39:35 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapicodec_objects.c: + * gst-libs/gst/vaapi/gstvaapicodec_objects.h: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.c: + * gst-libs/gst/vaapi/gstvaapidecoder_objects.h: + libs: codecobject: Add number of elements when create codec object. + One slice data may need several slice parameter buffers at one time. + Part-of: + +2020-12-12 10:30:41 +0100 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecodebin.c: + * gst/vaapi/gstvaapipluginbase.c: + * gst/vaapi/gstvaapivideobufferpool.c: + vaapi: use gst_clear_object instead of g_clear_object + Part-of: + +2020-12-08 13:34:35 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.c: + plugins: encode: unlock the stream lock before _flush() + The current encoder will hang when EOS comes. When we call the + gst_vaapi_encoder_encode_and_queue(), we should release the stream + lock, just like what we do in gst_vaapiencode_handle_frame(). + The deadlock happens when: The input thread holding the stream lock + is using gst_vaapi_encoder_create_coded_buffer() to acquire a coded + buffer, while the output thread which holding the coded buffer resource + is acquiring the stream lock in _push_frame() to push the data to + down stream element. + Part-of: + +2020-12-09 00:04:33 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h264.c: + libs: encoder: H264: Fix one assert in get_pending_reordered(). + gst_vaapi_encoder_h264_get_pending_reordered() does not consider the + case for HIERARCHICAL_B mode. The pipeline: + gst-launch-1.0 videotestsrc num-buffers=48 ! vaapih264enc prediction-type=2 \ + keyframe-period=32 ! fakesink + get a assert: + ERROR:../gst-libs/gst/vaapi/gstvaapiencoder_h264.c:1996:reflist1_init_hierarchical_b: + assertion failed: (count != 0) + The last few B frames are not fetched in correct order when HIERARCHICAL_B + is enabled. + We also fix a latent bug for normal mode. The g_queue_pop_tail() of B frames + make the last several frames encoded in reverse order. The NAL of last few + frames come in reverse order in the bit stream, though it can still output + the correct image. + Part-of: + +2020-06-25 16:25:21 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + libs: encoder: H265: Add screen content coding extensions support. + In scc mode, the I frame can ref to itself and it needs the L0 reference + list enabled. So we should set the I frame to P_SLICE type. We do not need + to change the ref_pic_list0/1 passed to VA driver, just need to enable the + VAEncPictureParameterBufferHEVC->pps_curr_pic_ref_enabled_flag to notify + the driver consider the current frame as reference. For bits conformance, + the NumRpsCurrTempList0 should be incremented by one to include the current + picture as the reference frame. We manually do it when packing the slice header. + Command line like: + gst-launch-1.0 videotestsrc num-buffers=10 ! \ + capsfilter caps=video/x-raw,format=NV12, framerate=30/1,width=640,height=360 ! \ + vaapih265enc ! capsfilter caps=video/x-h265,profile="{ (string)screen-extended-main }" ! \ + filesink location=out.265 + Can be used to specify that the encoder should use SCC profiles. + Part-of: + +2020-07-11 23:37:29 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_vp9.c: + plugin: encode: vp9: Implement the set_config(). + We store the allowed profiles list to encoder in set_config(). + Part-of: + +2020-07-11 23:39:40 +0800 He Junyan + + * gst/vaapi/gstvaapiencode_vp9.c: + plugin: encode: vp9: Add the profile into output caps. + Part-of: + +2020-07-11 23:27:21 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: vp9: no need to ensure_hw_profile. + Once we decide the profile and can get the valid entrypoint for + that profile, hw must already support this profile/entrypoint pair. + No need to check it again in set_context_info(). + Part-of: + +2020-07-11 23:22:55 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + libs: encoder: vp9: Improve the manner to decide the profile. + We should decide the VP9 encoder's profile based on the chroma and + depth of the input format, then make sure it is included in the + allowed list. + Part-of: + +2020-07-11 23:17:02 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils_vpx.c: + * gst-libs/gst/vaapi/gstvaapiutils_vpx.h: + libs: util: vpx: add get_chroma_format_idc for VP9 + Part-of: + +2020-07-11 23:09:59 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.c: + * gst-libs/gst/vaapi/gstvaapiencoder_vp9.h: + libs: encoder: vp9: Add allowed_profiles. + We need the allowed_profiles to store the allowed profiles in down + stream's caps. + Command line like: + vaapivp9enc ! capsfilter caps=video/x-vp9,profile="{ (string)1, \ + (string)3 }" + We need to store GST_VAAPI_PROFILE_VP9_1 and GST_VAAPI_PROFILE_VP9_3 + in this list. + Part-of: + +2020-11-30 18:00:30 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: H265: Fix a typo in scc reference setting. + Part-of: + +2020-07-17 18:00:30 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/video-format.c: + * gst/vaapi/gstvaapidecode.c: + libs: decoder: H265: Add MAIN_422_12 profile supporting. + Part-of: + +2020-07-31 14:38:42 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + video-format: Add Y212_LE format. + It can be used as HEVC YUV_4:2:2 12bits stream's decoder output, and + also can be used as the input format for encoding HEVC YUV_4:2:2 12bits + stream. + Part-of: + +2020-07-30 23:21:06 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + * gst-libs/gst/vaapi/gstvaapiprofile.c: + * gst-libs/gst/vaapi/gstvaapiprofile.h: + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + * gst-libs/gst/vaapi/video-format.c: + * gst/vaapi/gstvaapidecode.c: + libs: decoder: H265: Add MAIN_444_12 profile supporting. + Part-of: + +2020-07-30 23:13:10 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiimage.c: + * gst-libs/gst/vaapi/video-format.c: + * gst-libs/gst/vaapi/video-format.h: + video-format: Add Y412_LE format. + It can be used as HEVC YUV_4:4:4 12bits stream's decoder output, and + also can be used as the input format for encoding HEVC YUV_4:4:4 12bits + stream. + Part-of: + +2020-09-17 16:47:43 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h265.c: + libs: decoder: h265: fill missing predictor_palette_size field. + The predictor_palette_size of VAPictureParameterBufferHEVCScc is + forgotten and need to be filled when streams have palettes. + Part-of: + +2020-09-17 15:35:11 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils_h265.c: + libs: utils: h265: Use get_profile_from_sps to get profile. + We now use gst_h265_get_profile_from_sps() to replace the old way + of gst_h265_profile_tier_level_get_profile() to get more precise + profile. The new function consider the unstandard cases and give + a more suitable profile decision. + Part-of: + +2020-10-19 13:46:44 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + libs: decoder: vp9: 0xff segment pred probs if no temporal update + According to the spec (6.2.11 Segmentation params syntax) + segmentation_pred_prob[i] ast to be 0xff if not temporal_update. + Part-of: + +2020-10-19 13:42:53 +0200 Víctor Manuel Jáquez Leal + + * gst-libs/gst/vaapi/gstvaapidecoder_vp9.c: + libs: decoder: vp9: avoid reference rewriting + The removed code set all the reference frames to the current frame it is a key + one, but later, all the reference frames were rewritten with the decoded picture + buffers or VA_INVALID_SURFACE if they were not available. + Basically, all this time the first reference frame assignment has been ignored, + and it's not described by the spec, and this patch removes that code. + Part-of: + +2020-09-20 09:56:40 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapidecode.c: + decoder: don't reply src caps query with allowed if pad is fixed + If the pad is already fixed the caps query have to be reply with the + current fixed caps. Otherwise the query has to be replied with the + autogeneratd src caps. + This path fix this by falling back to the normal caps query processing + if the pad is already fixed. Otherwise it will fetch the allowed src + pad caps. + Part-of: + +2020-09-15 00:11:30 +0800 He Junyan + + * gst/vaapi/gstvaapidecode.c: + plugins: decode: fix a DMA caps typo in ensure_allowed_srcpad_caps. + Part-of: + +2020-09-01 09:31:33 +0200 Marc Leeman + + * gst/vaapi/gstvaapisink.c: + vaapisink: when updating the caps, reset rotation + When an element upstream changes settings (e.g. crop), new caps are sent + to vaapisink. When vaapisink was rotating the image, it needs to + re-evaluate if the sink needs to rotate the image. + Part-of: + +2020-09-08 17:31:02 +0100 Tim-Philipp Müller + + * .gitlab-ci.yml: + ci: include template from gst-ci master branch again + +2020-09-08 16:59:07 +0100 Tim-Philipp Müller + + * meson.build: + Back to development + === release 1.18.0 === 2020-09-08 00:09:51 +0100 Tim-Philipp Müller + * .gitlab-ci.yml: * ChangeLog: * NEWS: * RELEASE: diff --git a/NEWS b/NEWS index dba9c7c471..cc6c3b4a8e 100644 --- a/NEWS +++ b/NEWS @@ -1,11 +1,23 @@ -GStreamer 1.18 Release Notes +GStreamer 1.20 Release Notes -GStreamer 1.18.0 was originally released on 7 September 2020. +GStreamer 1.20 has not been released yet. It is scheduled for release +around July 2021. -See https://gstreamer.freedesktop.org/releases/1.18/ for the latest +1.19.x is the unstable development version that is being developed in +the git master branch and which will eventually result in 1.20, and +1.19.1 is the current development release in that series + +It is expected that feature freeze will be around June/July 2021, +followed by several 1.19 pre-releases and the new 1.20 stable release +around July 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: Monday 7 September 2020, 10:30 UTC (log) +Last updated: Sunday 30 May 2021, 16:00 UTC (log) Introduction @@ -18,1639 +30,87 @@ fixes and other improvements. Highlights -- GstTranscoder: new high level API for applications to transcode - media files from one format to another - -- High Dynamic Range (HDR) video information representation and - signalling enhancements - -- Instant playback rate change support - -- Active Format Description (AFD) and Bar Data support - -- ONVIF trick modes support in both GStreamer RTSP server and client - -- Hardware-accelerated video decoding on Windows via DXVA2 / - Direct3D11 - -- Microsoft Media Foundation plugin for video capture and - hardware-accelerated video encoding on Windows - -- qmlgloverlay: New overlay element that renders a QtQuick scene over - the top of an input video stream - -- New imagesequencesrc element to easily create a video stream from a - sequence of jpeg or png images - -- dashsink: Add new sink to produce DASH content - -- dvbsubenc: DVB Subtitle encoder element - -- TV broadcast compliant MPEG-TS muxing with constant bitrate muxing - and SCTE-35 support - -- rtmp2: new RTMP client source and sink element implementation - -- svthevcenc: new SVT-HEVC-based H.265 video encoder - -- vaapioverlay compositor element using VA-API - -- rtpmanager support for Google’s Transport-Wide Congestion Control - (twcc) RTP extension - -- splitmuxsink and splitmuxsrc gained support for auxiliary video - streams - -- webrtcbin now contains some initial support for renegotiation - involving stream addition and removal - -- New RTP source and sink elements to easily set up RTP streaming via - rtp:// URIs - -- New Audio Video Transport Protocol (AVTP) plugin for Time-Sensitive - Applications - -- Support for the Video Services Forum’s Reliable Internet Stream - Transport (RIST) TR-06-1 Simple Profile - -- Universal Windows Platform (UWP) support - -- rpicamsrc element for capturing from the Raspberry Pi camera - -- RTSP Server TCP interleaved backpressure handling improvements as - well as support for Scale/Speed headers - -- GStreamer Editing Services gained support for nested timelines, - per-clip speed rate control and the OpenTimelineIO format. - -- Autotools build system has been removed in favour of Meson +- this section will be completed in due course Major new features and changes Noteworthy new features and API -Instant playback rate changes - -Changing the playback rate as quickly as possible so far always required -a flushing seek. This generally works, but has the disadvantage of -flushing all data from the playback pipeline and requiring the demuxer -or parser to do a full-blown seek including resetting its internal state -and resetting the position of the data source. It might also require -considerable decoding effort to get to the right position to resume -playback from at the higher rate. - -This release adds a new mechanism to achieve quasi-instant rate changes -in certain playback pipelines without interrupting the flow of data in -the pipeline. This is activated by sending a seek with the -GST_SEEK_FLAG_INSTANT_RATE_CHANGE flag and start_type = stop_type = -GST_SEEK_TYPE_NONE. This flag does not work for all pipelines, in which -case it is necessary to fall back to sending a full flushing seek to -change the playback rate. When using this flag, the seek event is only -allowed to change the current rate and can modify the trickmode flags -(e.g. keyframe only or not), but it is not possible to change the -current playback position, playback direction or do a flush. - -This is particularly useful for streaming use cases like HLS or DASH -where the streaming download should not be interrupted when changing -rate. - -Instant rate changing is handled in the pipeline in a specific sequence -which is detailed in the seeking design docs. Most elements don’t need -to worry about this, only elements that sync to the clock need some -special handling which is implemented in the GstBaseSink base class, so -should be taken care of automatically in most normal playback pipelines -and sink elements. - -See Jan’s GStreamer Conference 2019 talk “Changing Playback Rate -Instantly” for more information. - -You can try this feature by passing the -i command line option to -gst-play-1.0. It is supported at least by qtdemux, tsdemux, hlsdemux, -and dashdemux. - -Google Transport-Wide Congestion Control - -rtpmanager now supports the parsing and generating of RTCP messages for -the Google Transport-Wide Congestion Control RTP Extension, as described -in: -https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01. - -This “just” provides the required plumbing/infrastructure, it does not -actually make effect any actual congestion control on the sender side, -but rather provides information for applications to use to make such -decisions. - -See Håvard’s “Google Transport-Wide Congestion Control” talk for more -information about this feature. - -GstTranscoder: a new high-level transcoding API for applications - -The new GstTranscoder library, along with transcodebin and -uritranscodebin elements, provides high level API for applications to -transcode media files from one format to another. Watch Thibault’s talk -“GstTranscoder: A High Level API to Quickly Implement Transcoding -Capabilities in your Applications” for more information. - -This also comes with a gst-transcoder-1.0 command line utility to -transcode one URI into another URI based on the specified encoding -profile. - -Active Format Description (AFD) and Bar Data support - -The GstVideo Ancillary Data API has gained support for Active Format -Description (AFD) and Bar data. - -This includes various two new buffer metas: GstVideoAFDMeta and -GstVideoBarMeta. - -GStreamer now also parses and extracts AFD/Bar data in the h264/h265 -video parsers, and supports both capturing them and outputting them in -the decklink elements. See Aaron’s lightning talk at the GStreamer -Conference for more background. - -ONVIF trick modes support in both GStreamer RTSP server and client - -- Support for the various trick modes described in section 6 of the - ONVIF streaming spec has been implemented in both gst-rtsp-server - and rtspsrc. -- Various new properties in rtspsrc must be set to take advantage of - the ONVIF support -- Examples are available here: test-onvif-server.c and - test-onvif-client.c -- Watch Mathieu Duponchelle’s talk “Implementing a Trickmode Player - with ONVIF, RTSP and GStreamer” for more information and a live - demo. - -GStreamer Codecs library with decoder base classes - -This introduces a new library in gst-plugins-bad which contains a set of -base classes that handle bitstream parsing and state tracking for the -purpose of decoding different codecs. Currently H264, H265, VP8 and VP9 -are supported. These bases classes are meant primarily for internal use -in GStreamer and are used in various decoder elements in connection with -low level decoding APIs like DXVA, NVDEC, VAAPI and V4L2 State Less -decoders. The new library is named gstreamer-codecs-1.0 / -libgstcodecs-1.0 and is not yet guaranteed to be API stable across major -versions. - -MPEG-TS muxing improvements - -The GStreamer MPEG-TS muxer has seen major improvements on various -fronts in this cycle: - -- It has been ported to the GstAggregator base class which means it - can work in defined-latency mode with live input sources and - continue streaming if one of the inputs stops producing data. - -- atscmux, a new ATSC-specific tsmux subclass - -- Constant Bit Rate (CBR) muxing support via the new bitrate property - which allows setting the target bitrate in bps. If this is set the - muxer will insert null packets as padding to achieve the desired - multiplex-wide constant bitrate. - -- compliance fixes for TV broadcasting use cases (esp. ATSC). See - Jan’s talk “TV Broadcast compliant MPEG-TS” for details. - -- Streams can now be added and removed at runtime: Until now, any - streams in tsmux had to be present when the element started - outputting its first buffer. Now they can appear at any point during - the stream, or even disappear and reappear later using the same PID. - -- new pcr-interval property allows applications to configure the - desired interval instead of hardcoding it - -- basic SCTE-35 support. This is enabled by setting the scte-35-pid - property on the muxer. Sending SCTE-35 commands is then done by - creating the appropriate SCTE-35 GstMpegtsSection and sending them - on the muxer. - -- MPEG-2 AAC handling improvements +- this section will be filled in in due course New elements -- New qmlgloverlay element for rendering a QtQuick scene over the top - of a video stream. qmlgloverlay requires that Qt support adopting an - external OpenGL context and is known to work on X11 and Windows. - Wayland is known not to work due to limitations within Qt. Check out - the example to see how it works. - -- The clocksync element is a generic element that can be placed in a - pipeline to synchronise passing buffers to the clock at that point. - This is similar to identity sync=true, but because it isn’t - GstBaseTransform-based, it can process GstBufferLists without - breaking them into separate GstBuffers. It is also more discoverable - than the identity option. Note that you do not need to insert this - element into your pipeline to make GStreamer sync to the pipeline - clock, this is usually handled automatically by the elements in the - pipeline (sources and sinks mostly). This element is useful to feed - non-live input such as local files into elements that expect live - input such as webrtcbin.` - -- New imagesequencesrc element to easily create a video stream from a - sequence of JPEG or PNG images (or any other encoding where the type - can be detected), basically a multifilesrc made specifically for - image sequences. - -- rpicamsrc element for capturing raw or encoded video (H.264, MJPEG) - from the Raspberry Pi camera. This works much like the popular - raspivid command line utility but outputs data nicely timestamped - and formatted in order to integrate nicely with other GStreamer - elements. Also comes with a device provider so applications can - discover the camera if available. - -- aatv and cacatv video filters that transform video ASCII art style - -- avtp: new Audio Video Transport Protocol (AVTP) plugin for Linux. - See Andre Guedes’ talk “Audio/Video Bridging (AVB) support in - GStreamer” for more details. - -- clockselect: a pipeline element that enables clock selection/forcing - via gst-launch pipeline syntax. - -- dashsink: Add new sink to produce DASH content. See Stéphane’s talk - or blog post for details. - -- dvbsubenc: a DVB subtitle encoder element - -- microdns: a libmicrodns-based mdns device provider to discover RTSP - cameras on the local network - -- mlaudiosink: new audio sink element for the Magic Leap platform, - accompanied by an MLSDK implementation in the amc plugin - -- msdkvp9enc: VP9 encoder element for the Intel MediaSDK - -- rist: new plugin implementing support for the Video Services Forum’s - Reliable Internet Stream Transport (RIST) TR-06-1 Simple Profile. - See Nicolas’ blog post “GStreamer support for the RIST - Specification” for more details. - -- rtmp2: new RTMP client source and sink elements with fully - asynchronous network operations, better robustness and additional - features such as handling ping and stats messages, and adobe-style - authentication. The new rtmp2src and rtmp2sink elements should be - API-compatible with the old rtmpsrc / rtmpsink elements and should - work as drop-in replacements. - -- new RTP source and sink elements to easily set up RTP streaming via - rtp:// URIs: The rtpsink and rtpsrc elements add an URI interface so - that streams can be decoded with decodebin using rtp:// URIs. These - can be used as follows: ``` gst-launch-1.0 videotestsrc ! x264enc ! - rtph264pay config-interval=3 ! rtpsink uri=rtp://239.1.1.1:1234 - - gst-launch-1.0 videotestsrc ! x264enc ! rtph264pay config-interval=1 - ! rtpsink uri=rtp://239.1.2.3:5000 gst-launch-1.0 rtpsrc - uri=rtp://239.1.2.3:5000?encoding-name=H264 ! rtph264depay ! - avdec_h264 ! videoconvert ! xvimagesink - - gst-launch-1.0 videotestsrc ! avenc_mpeg4 ! rtpmp4vpay - config-interval=1 ! rtpsink uri=rtp://239.1.2.3:5000 gst-launch-1.0 - rtpsrc uri=rtp://239.1.2.3:5000?encoding-name=MP4V-ES ! rtpmp4vdepay - ! avdec_mpeg4 ! videoconvert ! xvimagesink ``` - -- svthevcenc: new SVT-HEVC-based H.265 video encoder - -- switchbin: new helper element which chooses between a set of - processing chains (paths) based on input caps, and changes the - active chain if new caps arrive. Paths are child objects, which are - accessed by the GstChildProxy interface. See the switchbin - documentation for a usage example. - -- vah264dec: new experimental va plugin with an element for H.264 - decoding with VA-API using GStreamer’s new stateless decoder - infrastructure (see Linux section below). - -- v4l2codecs: introduce an V4L2 CODECs Accelerator supporting the new - CODECs uAPI in the Linux kernel (see Linux section below) - -- zxing new plugin to detect QR codes and barcodes, based on libzxing - -- also see the Rust plugins section below which contains plenty of new - exciting plugins written in Rust! +- this section will be filled in in due course New element features and additions -GStreamer core - -- filesink: Add a new “full” buffer mode. Previously the default and - full modes were the same. Now the default mode is like before: it - accumulates all buffers in a buffer list until the threshold is - reached and then writes them all out, potentially in multiple - writes. The new full mode works by always copying memory to a single - memory area and writing everything out with a single write once the - threshold is reached. - -- multiqueue: Add stats property and - current-level-{buffers, bytes, time} pad properties to query the - current levels of the corresponding internal queue. - -Plugins Base - -- alsa: implement a device provider - -- alsasrc: added use-driver-timestamp property to force use of - pipeline timestamps (and disable driver timestamps) if so desired - -- audioconvert: fix changing the mix-matrix property at runtime - -- appsrc: added support for segment forwarding or custom GstSegments - via GstSample, enabled via the handle-segment-change property. This - only works for segments in TIME format for now. - -- compositor: various performance optimisations, checkerboard drawing - fixes, and support for VUYA format - -- encodebin: Fix and refactor smart encoding; ensure that a single - segment is pushed into encoders; improve force-key-unit event - handling. - -- opusenc: Add low delay option (audio-type=restricted-lowdelay) to - disable the SILK layer and achieve only 5ms delay. - -- opusdec: add stats property to retrieve various decoder statistics. - -- uridecodebin3: Let decodebin3 do its stream selection if no one - answers - -- decodebin3: Avoid overriding explicit user selection of streams - -- playbin: add flag to force use of software decoders over any - hardware decoders that might also be available - -- playbin3, playbin: propagate sink context - -- rawvideoparse: Fix tiling support, allow setting colorimetry - -- subparse: output plain utf8 text instead of pango-markup formatted - text if downstream requires it, useful for interop with elements - that only accept utf8-formatted subtitles such as muxers or closed - caption converters. - -- tcpserversrc, tcpclientsrc: add stats property with TCP connection - stats (some are only available on Linux though) - -- timeoverlay: add show-times-as-dates, datetime-format and - datetime-epoch properties to display times with dates - -- videorate: Fix changing rate property during playback; reverse - playback fixes; update QoS events taking into account our rate - -- videoscale: pass through and transform size sensitive metas instead - of just dropping them - -Plugins Good - -- avidemux can handle H.265 video now. Our advice remains to - immediately cease all contact and communication with anyone who - hands you H.265 video in an AVI container, however. - -- avimux: Add support for S24LE and S32LE raw audio and v210 raw video - formats; support more than 2 channels of raw audio. - -- souphttpsrc: disable session sharing and cookie jar when the cookies - property is set; correctly handle seeks past the end of the content - -- deinterlace: new YADIF deinterlace method which should provide - better quality than the existing methods and is LGPL licensed; - alternate fields are supported as input to the deinterlacer as well - now, and there were also fixes for switching the deinterlace mode on - the fly. - -- flvmux: in streamable mode allow adding new pads even if the initial - header has already been written. Old clients will only process the - initial stream, new clients will get a header with the new streams. - The skip-backwards-streams property can be used to force flvmux to - skip and drop a few buffers rather than produce timestamps that go - backward and confuse librtmp-based clients. There’s also better - handling for timestamp rollover when streaming for a long time. - -- imagefreeze: Add live mode, which can be enabled via the new is-live - property. In this mode frames will only be output in PLAYING state - according to the negotiated framerate, skipping frames if the output - can’t keep up (e.g. because it’s blocked downstream). This makes it - possible to actually use imagefreeze in live pipelines without - having to manually ensure somehow that it starts outputting at the - current running time and without still risking to fall behind - without recovery. - -- matroskademux, qtdemux: Provide audio lead-in for some lossy formats - when doing accurate seeks, to make sure we can actually decode - samples at the desired position. This is especially important for - non-linear audio/video editing use-cases. - -- matroskademux, matroskamux: Handle interlaced field order (tff, bff) - -- matroskamux: - - - new offset-to-zero property to offset all streams to start at - zero. This takes the timestamp of the earliest stream and - offsets it so that it starts at 0. Some software (VLC, - ffmpeg-based) does not properly handle Matroska files that start - at timestamps much bigger than zero, which could happen with - live streams. - - added a creation-time property to explicitly set the creation - time to write into the file headers. Useful when remuxing, for - example, but also for live feeds where the DateUTC header can be - set a UTC timestamp corresponding to the beginning of the file. - - the muxer now also always waits for caps on sparse streams, and - warns if caps arrive after the header has already been sent, - otherwise the subtitle track might be silently absent in the - final file. This might affect applications that send sparse data - into matroskamux via an appsrc element, which will usually not - send out the initial caps before it sends out the first buffer. - -- pulseaudio: device provider improvements: fix discovery of - newly-added devices and hide the alsa device provider if we provide - alsa devices - -- qtdemux: raw audio handling improvements, support for AC4 audio, and - key-units trickmode interval support - -- qtmux: - - - was ported to the GstAggregator base class which allows for - better handling of live inputs, but might entail minor - behavioural changes for sparse inputs if inputs are not live. - - has also gained a force-create-timecode-trak property to create - a timecode trak in non-mov flavors, which may not be supported - by Apple but is supported by other software such as Final Cut - Pro X - - also a force-chunks property to force the creation of chunks - even in single-stream files, which is required for Apple ProRes - certification. - - also supports 8k resolutions in prefill mode with ProRes. - -- rtpbin gained a request-jitterbuffer signal which allows - applications to plug in their own jitterbuffer implementation such - as the threadsharing jitterbuffer from the Rust plugins, for - example. - -- rtprtxsend: add clock-rate-map property to allow generic RTP input - caps without a clock-rate whilst still supporting the max-size-time - property for bundled streams. - -- rtpssrcdemux: introduce max-streams property to guard against - attacks where the sender changes SSRC for every RTP packet. - -- rtph264pay, rtph264pay: implement STAP-A and various aggregation - modes controled by the new aggegrate-mode property: none to not - aggregate NAL units (as before), zero-latency to aggregate NAL units - until a VCL or suffix unit is included, or max to aggregate all NAL - units with the same timestamp (which adds one frame of latency). The - default has been kept at none for backwards compatibility reasons - and because various RTP/RTSP implementions don’t handle aggregation - well. For WebRTC use cases this should be set to zero-latency, - however. - -- rtpmp4vpay: add support for config-interval=-1 to resend headers - with each IDR keyframe, like other video payloaders. - -- rtpvp8depay: Add wait-for-keyframe property for waiting until the - next keyframe after packet loss. Useful if the video stream was not - encoded with error resilience enabled, in which case packet loss - tends to cause very bad artefacts when decoding, and waiting for the - next keyframe instead improves user experience considerably. - -- splitmuxsink and splitmuxsrc can now handle auxiliary video streams - in addition to the primary video stream. The primary video stream is - still used to select fragment cut points at keyframe boundaries. - Auxilliary video streams may be broken up at any packet - so - fragments may not start with a keyframe for those streams. - -- splitmuxsink: - - - new muxer-preset and sink-preset properties for setting - muxer/sink presets - - a new start-index property to set the initial fragment id - - and a new muxer-pad-map property which explicitly maps - splitmuxsink pads to the muxer pads they should connect to, - overriding the implicit logic that tries to match pads but - yields arbitrary names. - - Also includes the actual sink element in the fragment-opened and - fragment-closed element messages now, which is especially useful - for sinks without a location property or when finalisation of - the fragments is done asynchronously. - -- videocrop: add support for Y444, Y41B and Y42B pixel formats - -- vp8enc, vp9enc: change default value of VP8E_SET_STATIC_THRESHOLD - from 0 to 1 which matches what Google WebRTC does and results in - lower CPU usage; also added a new bit-per-pixel property to select a - better default bitrate - -- v4l2: add support for ABGR, xBGR, RGBA, and RGBx formats and for - handling interlaced video in alternate fields interlace mode (one - field per buffer instead of one frame per picture with both fields - interleaved) - -- v4l2: Profile and level probing support for H264, H265, MPEG-4, - MPEG-2, VP8, and VP9 video encoders and decoders - -Plugins Ugly - -- asfdemux: extract more metadata: disc number and disc count - -- x264enc: - - - respect YouTube bitrate recommendation when user sets the - YouTube profile preset - - separate high-10 video formats from 8-bit formats to improve - depth negotiation and only advertise suitable input raw formats - for the desired output depth - - forward downstream colorimetry and chroma-site restrictions to - upstream elements - - support more color primaries/mappings - -Plugins Bad - -- av1enc: add threads, row-mt and tile-{columns,rows} properties for - this AOMedia AV1 encoder - -- ccconverter: implement support for CDP framerate conversions - -- ccextractor: Add remove-caption-meta property to remove caption - metas from the outgoing video buffers - -- decklink: add support for 2K DCI video modes, widescreen NTSC/PAL, - and for parsing/outputting AFD/Bar data. Also implement a simple - device provider for Decklink devices. - -- dtlsrtpenc: add rtp-sync property which synchronises RTP streams to - the pipeline clock before passing them to funnel for merging with - RTCP. - -- fdkaac: also decode MPEG-2 AAC; encoder now supports more - multichannel/surround sound layouts - -- hlssink2: add action signals for custom playlist/fragment handling: - Instead of always going through the file system API we allow the - application to modify the behaviour. For the playlist itself and - fragments, the application can provide a GOutputStream. In addition - the sink notifies the application whenever a fragment can be - deleted. - -- interlace: can now output data in alternate fields mode; added field - switching mode for 2:2 field pattern - -- iqa: Add a mode property to enable strict mode that checks that all - the input streams have the exact same number of frames; also - implement the child proxy interface - -- mpeg2enc: add disable-encode-retries property for lower CPU usage - -- mpeg4videoparse: allow re-sending codec config at IDR via - config-interval=-1 - -- mpegtsparse: new alignment property to determine number of TS - packets per output buffer, useful for feeding an MPEG-TS stream for - sending via udpsink. This can be used in combination with the - split-on-rai property that makes sure to start a new output buffer - for any TS packet with the Random Access Indicator set. Also set - delta unit buffer flag on non-random-access buffers. - -- mpegdemux: add an ignore-scr property to ignore the SCR in - non-compliant MPEG-PS streams with a broken SCR, which will work as - long as PTS/DTS in the PES header is consistently increasing. - -- tsdemux: - - - add an ignore-pcr property to ignore MPEG-TS streams with broken - PCR streams on which we can’t reliably recover correct - timestamps. - - new latency property to allow applications to lower the - advertised worst-case latency of 700ms if they know their - streams support this (must have timestamps in higher frequency - than required by the spec) - - support for AC4 audio - -- msdk - Intel Media SDK plugin for hardware-accelerated video - decoding and encoding on Windows and Linux: - - - mappings for more video formats: Y210, Y410, P012_LE, Y212_LE - - encoders now support bitrate changes and input format changes in - playing state - - msdkh264enc, msdkh265enc: add support for CEA708 closed caption - insertion - - msdkh264enc, msdkh265enc: set Region of Interest (ROI) region - from ROI metas - - msdkh264enc, msdkh265enc: new tune property to enable low-power - mode - - msdkh265enc: add support 12-bit 4:2:0 encoding and 8-bit 4:2:2 - encoding and VUYA, Y210, and Y410 as input formats - - msdkh265enc: add support for screen content coding extension - - msdkh265dec: add support for main-12/main-12-intra, - main-422-10/main-422-10-intra 10bit, - main-422-10/main-422-10-intra 8bit, - main-422-12/main-422-12-intra, main-444-10/main-444-10-intra, - main-444-12/main-444-12-intra, and main-444 profiles - - msdkvp9dec: add support for 12-bit 4:4:4 - - msdkvpp: add support for Y410 and Y210 formats, cropping via - properties, and a new video-direction property. - -- mxf: Add support for CEA-708 CDP from S436 essence tracks. mxfdemux - can now handle Apple ProRes - -- nvdec: add H264 + H265 stateless codec implementation nvh264sldec - and nvh265sldec with fewer features but improved latency. You can - set the environment variable GST_USE_NV_STATELESS_CODEC=h264 to use - the stateless decoder variant as nvh264dec instead of the “normal” - NVDEC decoder implementation. - -- nvdec: add support for 12-bit 4:4:4/4:2:0 and 10-bit 4:2:0 decoding - -- nvenc: - - - add more rate-control options, support for B-frame encoding (if - device supports it), an aud property to toggle Access Unit - Delimiter insertion, and qp-{min,max,const}-{i,p,b} properties. - - the weighted-pred property enables weighted prediction. - - support for more input formats, namely 8-bit and 10-bit RGB - formats (BGRA, RGBA, RGB10A2, BGR10A2) and YV12 and VUYA. - - on-the-fly resolution changes are now supported as well. - - in case there are multiple GPUs on the system, there are also - per-GPU elements registered now, since different devices will - have different capabilities. - - nvh265enc can now support 10-bit YUV 4:4:4 encoding and 8-bit - 4:4:4 / 10-bit 4:2:0 formats up to 8K resolution (with some - devices). In case of HDR content HDR related SEI nals will be - inserted automatically. - -- openjpeg: enable multi-threaded decoding and add support for - sub-frame encoding (for lower latency) - -- rtponviftimestamp: add opt-out “drop-out-of-segment” property - -- spanplc: new stats property - -- srt: add support for IPv6 and for using hostnames instead of IP - addresses; add streamid property, but also allow passing the id via - the stream URI; add wait-for-connection property to srtsink - -- timecodestamper: this element was rewritten with an updated API - (properties); it has gained many new properties, seeking support and - support for linear timecode (LTC) from an audio stream. - -- uvch264src now comes with a device provider to advertise available - camera sources that support this interface (mostly Logitech C920s) - -- wpe: Add software rendering support and support for mouse scroll - events - -- x265enc: support more 8/10/12 bits 4:2:0, 4:2:2 and 4:4:4 profiles; - add support for mastering display info and content light level - encoding SEIs - -gst-libav - -- Add mapping for SpeedHQ video codec used by NDI - -- Add mapping for aptX and aptX-HD - -- avivf_mux: support VP9 and AV1 - -- avvidenc: shift output buffer timestamps and output segment by 1h - just like x264enc does, to allow for negative DTS. - -- avviddec: Limit default number of decoder threads on systems with - more than 16 cores, as the number of threads used in avdec has a - direct impact on the latency of the decoder, which is of as many - frames as threads, so a large numbers of threads can make for - latency levels that can be problematic in some applications. - -- avviddec: Add thread-type property that allows applications to - specify the preferred multithreading method (auto, frame, slice). - Note that thread-type=frame may introduce additional latency - especially in live pipelines, since it introduces a decoding delay - of number of thread frames. +- this section will be filled in in due course Plugin and library moves -- There were no plugin moves or library moves in this cycle. +- this section will be filled in in due course -- The rpicamsrc element was moved into -good from an external - repository on github. +- There were no plugin moves or library moves in this cycle. Plugin removals The following elements or plugins have been removed: -- The yadif video deinterlacing plugin from gst-plugins-bad, which was - one of the few GPL licensed plugins, has been removed in favour of - deinterlace method=yadif. - -- The avdec_cdgraphics CD Graphics video decoder element from - gst-libav was never usable in GStreamer and we now have a cdgdec - element written in Rust in gst-plugins-rs to replace it. - -- The VDPAU plugin has been unmaintained and unsupported for a very - long time and does not have the feature set we expect from - hardware-accelerated video decoders. It’s been superseded by the - nvcodec plugin leveraging NVIDIA’s NVDEC API. +- this section will be filled in in due course Miscellaneous API additions -GStreamer core - -- gst_task_resume(): This new API allows resuming a task if it was - paused, while leaving it in stopped state if it was stopped or not - started yet. This can be useful for callback-based driver workflows, - where you basically want to pause and resume the task when buffers - are notified while avoiding the race with a gst_task_stop() coming - from another thread. - -- info: add printf extensions GST_TIMEP_FORMAT and GST_STIMEP_FORMAT - for printing GstClockTime/GstClockTimeDiff pointers, which is much - more convenient to use in debug log statements than the usual - GST_TIME_FORMAT-followed-by-GST_TIME_ARGS dance. Also add an - explicit GST_STACK_TRACE_SHOW_NONE enum value. - -- gst_element_get_current_clock_time() and - gst_element_get_current_running_time(): new helper functions for - getting an element clock’s time, and the clock time minus base time, - respectively. Useful when adding additional input branches to - elements such as compositor, audiomixer, flvmux, interleave or - input-selector to determine initial pad offsets and such. - -- seeking: Add GST_SEEK_FLAG_TRICKMODE_FORWARD_PREDICTED to just skip - B-frames during trick mode, showing both keyframes + P-frame, and - add support for it in h264parse and h265parse. - -- elementfactory: add GST_ELEMENT_FACTORY_TYPE_HARDWARE to allow - elements to advertise that they are hardware-based or interact with - hardware. This has multiple applications: - - - it makes it possible to easily differentiate hardware and - software based element implementations such as audio or video - encoders and decoders. This is useful in order to force the use - of software decoders for specific use cases, or to check if a - selected decoder is actually hardware-accelerated or not. - - elements interacting with hardware and their respective drivers - typically don’t know the actually supported capabilities until - the element is set into at least READY state and can open a - device handle and probe the hardware. - -- gst_uri_from_string_escaped(): identical to gst_uri_from_string() - except that the userinfo and fragment components of the URI will not - be unescaped while parsing. This is needed for correctly parsing - usernames or passwords with : in them . - -- paramspecs: new GstParamSpec flag GST_PARAM_CONDITIONALLY_AVAILABLE - to indicate that a property might not always exist. - -- gst_bin_iterate_all_by_element_factory_name() finds elements in a - bin by factory name - -- pad: gst_pad_get_single_internal_link() is a new convenience - function to return the single internal link of a pad, which is - useful e.g. to retrieve the output pad of a new multiqueue request - pad. - -- datetime: Add constructors to create datetimes with timestamps in - microseconds, gst_date_time_new_from_unix_epoch_local_time_usecs() - and gst_date_time_new_from_unix_epoch_utc_usecs(). - -- gst_debug_log_get_lines() gets debug log lines formatted in the same - way the default log handler would print them - -- GstSystemClock: Add GST_CLOCK_TYPE_TAI as GStreamer abstraction for - CLOCK_TAI, to support transmission offloading features where network - packets are timestamped with the time they are deemed to be actually - transmitted. Useful in combination with the new AVTP plugin. - -- miscellaneous utility functions: gst_clear_uri(), - gst_structure_take(). - -- harness: Added gst_harness_pull_until_eos() - -- GstBaseSrc: - - - gst_base_src_new_segment() allows subclasses to update the - segment to be used at runtime from the ::create() function. This - deprecates gst_base_src_new_seamless_segment() - - gst_base_src_negotiate() allows subclasses to trigger format - renegotiation at runtime from inside the ::create() or ::alloc() - function - -- GstBaseSink: new stats property and gst_base_sink_get_stats() method - to retrieve various statistics such as average frame rate and - dropped/rendered buffers. - -- GstBaseTransform: gst_base_transform_reconfigure() is now public - API, useful for subclasses that need to completely re-implement the - ::submit_input_buffer() virtual method - -- GstAggregator: - - - gst_aggregator_update_segment() allows subclasses to update the - output segment at runtime. Subclasses should use this function - rather than push a segment event onto the source pad directly. - - new sample selection API: - - subclasses should now call gst_aggregator_selected_samples() - from their ::aggregate() implementation to signal that they - have selected the next samples they will aggregate - - GstAggregator will then emit the samples-selected signal - where handlers can then look up samples per pad via - gst_aggregator_peek_next_sample(). - - This is useful for example to atomically update input pad - properties in mixer subclasses such as compositor. - Applications can now update properties with precise control - of when these changes will take effect, and for which input - buffer(s). - - gst_aggregator_finish_buffer_list() allows subclasses to push - out a buffer list, improving efficiency in some cases. - - a ::negotiate() virtual method was added, for consistency with - other base classes and to allow subclasses to completely - override the negotiation behaviour. - - the new ::sink_event_pre_queue() and ::sink_query_pre_queue() - virtual methods allow subclasses to intercept or handle - serialized events and queries before they’re queued up - internally. - -GStreamer Plugins Base Libraries - -Audio library - -- audioaggregator, audiomixer: new output-buffer-duration-fraction - property which allows use cases such as keeping the buffers output - by compositor on one branch and audiomixer on another perfectly - aligned, by requiring the compositor to output a n/d frame rate, and - setting output-buffer-duration-fraction to d/n on the audiomixer. - -- GstAudioDecoder: new max-errors property so applications can - configure at what point the decoder should error out, or tell it to - just keep going - -- gst_audio_make_raw_caps() and gst_audio_formats_raw() are - bindings-friendly versions of the GST_AUDIO_CAPS_MAKE() C macro. - -- gst_audio_info_from_caps() now handles encoded audio formats as well - -PbUtils library - -- GstEncodingProfile: - - Do not restrict number of similar profiles in a container - - add GstValue serialization function -- codec utils now support more H.264/H.265 profiles/levels and have - improved extension handling - -RTP library - -- rtpbasepayloader: Add scale-rtptime property for scaling RTP - timestamp according to the segment rate (equivalent to RTSP speed - parameter). This is useful for ONVIF trickmodes via RTSP. - -- rtpbasepayload: add experimental property for embedding twcc - sequencenumbers for Transport-Wide Congestion Control (gated behind - the GST_RTP_ENABLE_EXPERIMENTAL_TWCC_PROPERTY environment - variable) - more generic API for enabling this is expected to land - in the next development cycle. - -- rtcpbuffer: add RTPFB_TYPE_TWCC for Transport-Wide Congestion - Control - -- rtpbuffer: add - gst_rtp_buffer_get_extension_onebyte_header_from_bytes()``, so that one can parse theGBytes` - returned by gst_rtp_buffer_get_extension_bytes() - -- rtpbasedepayload: Add max-reorder property to make the - previously-hardcoded value when to consider a sender to have - restarted configurable. In some scenarios it’s particularly useful - to set max-reorder=0 to disable the behaviour that the depayloader - will drop packets: when max-reorder is set to 0 all - reordered/duplicate packets are considered coming from a restarted - sender. - -RTSP library - -- add gst_rtsp_url_get_request_uri_with_control() to create request - uri combined with control url - -- GstRTSPConnection: add the possibility to limit the Content-Length - for RTSP messages via - gst_rtsp_connection_set_content_length_limit(). The same - functionality is also exposed in gst-rtsp-server. - -SDP library - -- add support for parsing the extmap attribute from caps and storing - inside caps The extmap attribute allows mapping RTP extension header - IDs to well-known RTP extension header specifications. See RFC8285 - for details. - -Tags library - -- update to latest iso-code and support more languages - -- add tags for acoustid id & acoustid fingerprint, plus MusicBrainz ID - handling fixes - -Video library - -- High Dynamic Range (HDR) video information representation and - signalling enhancements: - - - New APIs for HDR video information representation and - signalling: - - GstVideoMasteringDisplayInfo: display color volume info as - per SMPTE ST 2086 - - GstVideoContentLightLevel: content light level specified in - CEA-861.3, Appendix A. - - plus functions to serialise/deserialise and add them to or - parse them from caps - - gst_video_color_{matrix,primaries,transfer}_{to,from}_iso(): - new utilility functions for conversion from/to ISO/IEC - 23001-8 - - add ARIB STD-B67 transfer chracteristic function - - add SMPTE ST 2084 support and BT 2100 colorimetry - - define bt2020-10 transfer characteristics for clarity: - bt707, bt2020-10, and bt2020-12 transfer characteristics are - functionally identical but have their own unique values in - the specification. - - h264parse, h265parse: Parse mastering display info and content - light level from SEIs. - - matroskademux: parse HDR metadata - - matroskamux: Write MasteringMetadata and Max{CLL,FALL}. Enable - muxing with HDR meta data if upstream provided it - - avviddec: Extract HDR information if any and map bt2020-10, PQ - and HLG transfer functions - -- added bt601 transfer function (for completeness) - -- support for more pixel formats: - - - Y412 (packed 12 bits 4:4:4:4) - - Y212 (packed 12 bits 4:2:2) - - P012 (semi-planar 4:2:0) - - P016_{LE,BE} (semi-planar 16 bits 4:2:0) - - Y444_16{LE,BE} (planar 16 bits 4:4:4) - - RGB10A2_LE (packed 10-bit RGB with 2-bit alpha channel) - - NV12_32L32 (NV12 with 32x32 tiles in linear order) - - NV12_4L4 (NV12 with 4x4 tiles in linear order) - -- GstVideoDecoder: - - - new max-errors property so applications can configure at what - point the decoder should error out, or tell it to just keep - going - - - new qos property to disable dropping frames because of QoS, and - post QoS messages on the bus when dropping frames. This is - useful for example in a scenario where the decoded video is - tee-ed off to go into a live sink that syncs to the clock in one - branch, and an encoding and save to file pipeline in the other - branch. In that case one wouldn’t want QoS events from the video - sink make the decoder drop frames because that would also leave - gaps in the encoding branch then. - -- GstVideoEncoder: - - - gst_video_encoder_finish_subframe() is new API to push out - subframes (e.g. slices), so encoders can split the encoding into - subframes, which can be useful to reduce the overall end-to-end - latency as we no longer need to wait for the full frame to be - encoded to start decoding or sending out the data. - - new min-force-key-unit-interval property allows configuring the - minimum interval between force-key-unit requests and prevents a - big bitrate increase if a lot of key-units are requested in a - short period of time (as might happen in live streaming RTP - pipelines when packet loss is detected). - - various force-key-unit event handling fixes - -- GstVideoAggregator, compositor, glvideomixer: expose - max-last-buffer-repeat property on pads. This can be used to have a - compositor display either the background or a stream on a lower - zorder after a live input stream freezes for a certain amount of - time, for example because of network issues. - -- gst_video_format_info_component() is new API to find out which - components are packed into a given plane, which is useful to prevent - us from assuming a 1-1 mapping between planes and components. - -- gst_video_make_raw_caps() and gst_video_formats_raw() are - bindings-friendly versions of the GST_VIDEO_CAPS_MAKE() C macro. - -- video-blend: Add support for blending on top of 16 bit per component - formats, which makes sure we can support every currently supported - raw video format for blending subtitles or logos on top of video. - -- GST_VIDEO_BUFFER_IS_TOP_FIELD() and - GST_VIDEO_BUFFER_IS_BOTTOM_FIELD() convenience macros to check - whether the video buffer contains only the top field or bottom field - of an interlaced picture. - -- GstVideoMeta now includes an alignment field with the - GstVideoAlignment so buffer producers can explicitly specify the - exact geometry of the planes, allowing users to easily know the - padded size and height of each plane. Default values will be used if - this is not set. - - Use gst_video_meta_set_alignment() to set the alignment and - gst_video_meta_get_plane_size() or gst_video_meta_get_plane_height() - to compute the plane sizes or plane heights based on the information - in the video meta. - -- gst_video_info_align_full() works like gst_video_info_align() but - also retrieves the plane sizes. - -MPEG-TS library - -- support for SCTE-35 sections - -- extend support for ATSC tables: - - - System Time Table (STT) - - Master Guide Table (MGT) - - Rating Region Table (RRT) +- this section will be filled in in due course Miscellaneous performance, latency and memory optimisations -As always there have been many performance and memory usage improvements -across all components and modules. Some of them have already been -mentioned elsewhere so won’t be repeated here. - -The following list is only a small snapshot of some of the more -interesting optimisations that haven’t been mentioned in other contexts -yet: - -- caps negotiation, structure and GValue performance optimizations - -- systemclock: clock waiting performance improvements (moved from - GstPoll to GCond for waiting), especially on Windows. - -- rtpsession: add support for buffer lists on the recv path for better - performance with higher packet rate streams. - -- rtpjitterbuffer: internal timer handling has been rewritten for - better performance, see Nicolas’ talk “Revisiting RTP Jitter Buffer - Timers” for more details. - -- H.264/H.265 parsers and RTP payloaders/depayloaders have been - optimised for latency to make sure data is processed and pushed out - as quickly as possible - -- video-scaler: correctness and performance improvements, esp. for - interlaced formats and GBRA - -- GstVideoEncoder has gained new API to push out subframes - (e.g. slices), so encoders can split the encoding into subframes, - which can be useful to reduce the overall end-to-end latency as we - no longer need to wait for the full frame to be encoded to start - decoding or sending out the data. - - This is complemented by the new GST_VIDEO_BUFFER_FLAG_MARKER which - is a video-specific buffer flag to mark the end of a video frame, so - elements can know that they have received all data for a frame - without waiting for the beginning of the next frame. This is similar - to how the RTP marker flag is used in many RTP video mappings. - - The video encoder base class now also releases the internal stream - lock before pushing out data, so as to not block the input side of - things from processing more data in the meantime. +- this section will be filled in in due course Miscellaneous other changes and enhancements -- it is now possible to modify the initial rank of plugin features - without modifying the source code or writing code to do so - programmatically via the GST_PLUGIN_FEATURE_RANK environment - variable. Users can adjust the rank of plugin(s) by passing a - comma-separated list of feature:rank pairs where rank can be a - numerical value or one of NONE, MARGINAL, SECONDARY, PRIMARY, and - MAX. Example: GST_PLUGIN_FEATURE_RANK=myh264dec:MAX,avdec_h264:NONE - sets the rank of the myh264dec element feature to the maximum and - that of avdec_h264 to 0 (none), thus ensuring that myh264dec is - prefered as H264 decoder in an autoplugging context. - -- GstDeviceProvider now does a static probe on start as fallback for - providers that don’t support dynamic probing to make things easier - for users - -WebRTC - -- webrtcbin now contains initial support for renegotiation involving - stream addition and removal. There are a number of caveats to this - initial renegotiation support and many complex scenarios are known - to require some work. - -- webrtcbin now exposes the internal ICE object for advanced - configuration options. Using the internal ICE object, it is possible - to toggle UDP or TCP connection usage as well as provide local - network addresses. - -- Fix a number of call flows within webrtcbin’s GstPromise handling - where a promise was never replied to. This has been fixed and now a - promise will always receive a reply. - -- webrtcbin now exposes a latency property for configuring the - internal rtpjitterbuffer latency and buffering when receiving - streams. - -- webrtcbin now only synchronises the RTP part of a stream, allowing - RTCP messages to skip synchronisation entirely. - -- Fixed most of the webrtcbin state properties (connection-state, - ice-connection-state, signaling-state, but not ice-gathering-state - as that requires newer API in libnice and will be fixed in the next - release series) to advance through the state values correctly. Also - implemented DTLS connection states in the DTLS elements so that - peer-connection-state is not always new. - -- webrtcbin now accounts for the a=ice-lite attribute in a remote SDP - offer and will configure the internal ICE implementation - accordingly. - -- webrtcbin will now resolve .local candidate addresses using the - system DNS resolver. .local candidate addresses are now produced by - web browsers to help protect the privacy of users. - -- webrtcbin will now add candidates found in the SDP to the internal - ICE agent. This was previously unsupported and required using the - add-ice-candidate signal manually from the application. - -- webrtcbin will now correctly parse a TURN URI that contains a - username or password with a : in it. - -- The GStreamer WebRTC library gained a GstWebRTCDataChannel object - roughly matching the interface exposed by the WebRTC specification - to allow for easier binding generation and use of data channels. - -OpenGL integration - -GStreamer OpenGL bindings/build related changes - -- The GStreamer OpenGL library (libgstgl) now ships pkg-config files - for platform-specific API where libgstgl provides a public - integration interface and a pkg-config file for a dependency on the - detected OpenGL headers. The new list of pkg-config files in - addition to the original gstreamer-gl-1.0 are gstreamer-gl-x11-1.0, - gstreamer-gl-wayland-1.0, gstreamer-gl-egl-1.0, and - gstreamer-gl-prototypes-1.0 (for OpenGL headers when including - gst/gl/gstglfuncs.h). - -- GStreamer OpenGL now ships some platform-specific introspection data - for platforms that have a public interface. This should allow for - easier integration with bindings involving platform specific - functionality. The new introspection data files are named - GstGLX11-1.0, GstGLWayland-1.0, and GstGLEGL-1.0. - -GStreamer OpenGL Features - -- The iOS implementation no longer accesses UIKit objects off the main - thread fixing a loud warning message when used in iOS applications. - -- Support for mouse and keyboard handling using the GstNavigation - interface was added for the wayland implementation complementing the - already existing support for the X11 and Windows implementations. - -- A new helper base class for source elements, GstGLBaseSrc is - provided to ease writing source elements producing OpenGL video - frames. - -- Support for some more 12-bit and 16-bit video formats (Y412_LE, - Y412_BE, Y212_LE, Y212_BE, P012_LE, P012_BE, P016, NV16, NV61) was - added to glcolorconvert. - -- glupload can now import dma-buf’s into external-oes textures. - -- A new display type for EGLDevice-based systems was added. It is - currently opt-in by using either the GST_GL_PLATFORM=egl-device - environment variable or manual construction - (gst_gl_display_egl_device_new*()) due to compatibility issues with - some platforms. - -- Support was added for WinRT/UWP using the ANGLE project for running - OpenGL-based pipelines within a UWP application. - -- Various elements now support changing the GstGLDisplay to be used at - runtime in simple cases. This is primarily helpful for changing or - adding an OpenGL-based video sink that must share an OpenGL context - with an external source to an already running pipeline. - -GStreamer Vulkan integration - -- There is now a GStreamer Vulkan library to provide integration - points and helpers with applications and external GStreamer Vulkan - based elements. The structure of the library is modelled similarly - to the already existing GStreamer OpenGL library. Please note that - the API is still unstable and may change in future releases, - particularly around memory handling. The GStreamer Vulkan library - contains objects for sharing the vkInstance, vkDevice, vkQueue, - vkImage, VkMemory, etc with other elements and/or the application as - well as some helper objects for using Vulkan in an application or - element. - -- Added support for building and running on/for the Android and - Windows systems to complement the existing XCB, Wayland, MacOS, and - iOS implementations. - -- XCB gained support for mouse/keyboard events using the GstNavigation - API. - -- New vulkancolorconvert element for converting between color formats. - vulkancolorconvert can currently convert to/from all 8-bit RGBA - formats as well as 8-bit RGBA formats to/from the YUV formats AYUV, - NV12, and YUY2. - -- New vulkanviewconvert element for converting between stereo view - layouts. vulkanviewconvert can currently convert between all of the - single memory formats (side-by-side, top-bottom, column-interleaved, - row-interleaved, checkerboard, left, right, mono). - -- New vulkanimageidentity element for a blit from the input vulkan - image/s to a new vulkan image/s. - -- The vulkansink element can now scale the input image to the output - window/surface size where that information is available. - -- The vulkanupload element can now configure a transfer from system - memory to VulkanImage-based memory. Previously, this required two - vulkanupload elements. +- this section will be filled in in due course Tracing framework and debugging improvements -- gst_tracing_get_active_tracers() returns a list of active tracer - objects. This can be used to interact with tracers at runtime using - GObject API such as action signals. This has been implemented in the - leaks tracer for snapshotting and retrieving leaked/active objects - at runtime. - -- The leaks tracer can now be interacted with programmatically at - runtime via GObject action signals: - - - get-live-object returns a list of live (allocated) traced - objects - - log-live-objects logs a list of live objects into the debug log. - This is the same as sending the SIGUSR1 signal on unix systems, - but works on all operating systems including Windows. - - activity-start-tracking, activity-get-checkpoint, - activity-log-checkpoint, activity-stop-tracking: add support for - tracking and checkpointing objects, similar to what was - previously available via SIGUSR2 on unix systems, but works on - all operating systems including Windows. - -- various GStreamer gdb debug helper improvements: - - - new ‘gst-pipeline-tree’ command - - more gdb helper functions: gst_element_pad(), gst_pipeline() and - gst_bin_get() - - support for queries and buffers - - print more info for segment events, print event seqnums, object - pointers and structures - - improve gst-print command to show more pad and element - information +- this section will be filled in in due course Tools -gst-launch-1.0 - -- now prints the pipeline position and duration if available when the - pipeline is advancing. This is hopefully more user-friendly and - gives visual feedback on the terminal that the pipeline is actually - up and running. This can be disabled with the --no-position command - line option. - -- the parse-launch pipeline syntax now has support for presets: - use@preset=" after an element to load a preset. - -gst-inspect-1.0 - -- new --color command line option to force coloured output even if not - connected to a tty - -gst-tester-1.0 (new) - -- gst-tester-1.0 is a new tool for plugin developers to launch - .validatetest files with TAP compatible output, meaning it can - easily and cleanly be integrated with the meson test harness. It - allows you to use gst-validate (from the gst-devtools module) to - write integration tests in any GStreamer repository whilst keeping - the tests as close as possible to the code. The tool transparently - handles gst-validate being installed or not: if it is not installed - those integration tests will simply be skipped. - -gst-play-1.0 - -- interactive keyboard controls now also work on Windows - -gst-transcoder-1.0 (new) - -- gst-transcoder-1.0 is a new command line tool to transcode one URI - into another URI based on the specified encoding profile using the - new GstTranscoder API (see above). +- this section will be filled in in due course GStreamer RTSP server -- Fix issue where the first few packets (i.e. keyframes) could - sometimes be dropped if the rtsp media pipeline had a live input. - This was a regression from GStreamer 1.14. There are more fixes - pending for that which will hopefully land in 1.18.1. - -- Fix backpressure handling when sending data in TCP interleave mode - where RTSP requests and responses and RTP/RTCP packets flow over the - same RTSP TCP connection: The previous implementation would at some - point stop sending data to other clients when a single client - stopped consuming data or did not consume data fast enough. This - obviously created problems for shared media, where the same stream - from a single producer pipeline is sent to multiple clients. Instead - we now manage a backlog in the server’s stream-transport component - and remove slow clients once this backlog exceeds a maximum duration - (which is currently hardcoded). - -- Onvif Streaming Specification trick modes support (see section at - the beginning) - -- Scale/Speed header support: Speed will deliver the data at the - requested speed, which means increasing the data bandwidth for - speeds > 1.0. Scale will attempt to do the same without affecting - the overall bandwidth requirement vis-a-vis normal playback speed - (e.g. it might drop data for fast-forward playback). - -- rtspclientsink: send buffer lists in one go for better performance +- this section will be filled in in due course GStreamer VAAPI -- A lot of work was done adding support for media-driver (iHD), the - new VAAPI driver for Intel, mostly for Gen9 onwards. - -- Available color formats and frame sizes are now detected at run-time - according to the context configuration. - -- Gallium drivers have been re-enabled in the allowed drivers list - -- Improved the mapping between VA formats and GStreamer formats by - generating a mapping table at run-time since even among different - drivers the mapping might be different, particularly for RGB with - little endianness. - -- The experimental Flexible Encoding Infrastructure (FEI) elements - have been removed since they were not really actively maintained or - tested. - -- Enhanced the juggling of DMABuf buffers and VASurface metas - -- New vaapioverlay element: a compositor element using VA VPP blend - capabilities to accelerate overlaying and compositing. Example - pipeline: - - gst-launch-1.0 -vf videotestsrc ! vaapipostproc ! tee name=testsrc ! queue \ - ! vaapioverlay sink_1::xpos=300 sink_1::alpha=0.75 name=overlay ! vaapisink \ - testsrc. ! queue ! overlay. - -vaapipostproc - -- added video-orientation support, supporting frame mirroring and - rotation - -- added cropping support, either via properties (crop-left, - crop-right, crop-bottom and crop-top) or buffer meta. - -- new skin-tone-enhancenment-level property which is the iHD - replacement of the i965 driver’s sink-tone-level. Both are - incompatible with each other, so both were kept. - -- handle video colorimetry - -- support HDR10 tone mapping - -vaapisink - -- resurrected wayland backend for non-weston compositors by extracting - the DMABuf from the VASurface and rendering it. - -- merged the video overlay API for wayland. Now applications can - define the “window” to render on. - -- demoted the vaapisink element to secondary rank since libva - considers rendering as a second-class feature. - -VAAPI Encoders - -- new common target-percentage property which is the desired target - percentage of bitrate for variable rate control. - -- encoders now extract their caps from the driver at registration - time. - -- vaapivp9enc: added support for low power mode and support for - profile 2 (profile 0 by default) - -- vaapih264enc: new max-qp property that sets the maximum quantization - value. Support for ICQ and QBVR bitrate control mode, adding a - quality-factor property for these modes. Support baseline profile as - constrained-baseline - -- vaapih265enc: - - - support for main-444 and main-12 encoding profiles. - - new max-qp property that sets the maximum quantization value. - - support for ICQ and QBVR bitrate control mode, adding a - quality-factor property for these modes. - - handle SCC profiles. - - num-tile-cols and num-tile-row properties to specify the number - of tiles to use. - - the low-delay-b property was deprecated and is now determined - automatically. - - improved profile selection through caps. - -VAAPI Decoders - -- Decoder surfaces are not bound to their context any longer and can - thus be created and used dynamically, removing the deadlock - headache. - -- Reverse playback is now fluid - -- Forward Region-of-Interest (ROI) metas downstream - -- GLTextureUploadMeta uses DMABuf when GEM is not available. Now - Gallium drivers can use this meta for rendering with EGL. - -- vaapivp9dec: support for 4:2:2 and 4:4:4 chroma type streams - -- vaapih265dec: skip all pictures prior to the first I-frame. Enable - passing range extension flags to the driver. Handle SCC profiles. - -- vaapijpegdec: support for 4:0:0, 4:1:1, 4:2:2 and 4:4:4 chroma types - pictures - -- vaapih264dec: handle baseline streams as constrained-baseline if - possible and make it more tolerant when encountering unknown NALs +- this section will be filled in in due course GStreamer OMX -- omxvideoenc: use new video encoder subframe API to push out slices - as soon as they’re ready - -- omxh264enc, omxh265enc: negotiate subframe mode via caps. To enable - it, force downstream caps to video/x-h264,alignment=nal or - video/x-h265,alignment=nal. - -- omxh264enc: Add ref-frames property - -- Zynq ultrascale+ specific video encoder/decoder improvements: - - - GRAY8 format support - - support for alternate fields interlacing mode - - video encoder: look-ahead, long-term-ref, and long-term-freq - properties +- this section will be filled in in due course GStreamer Editing Services and NLE -- Added nested timelines and subproject support so that GES projects - can be used as clips, potentially serializing nested projects in the - main file or referencing external project files. - -- Implemented an OpenTimelineIO GES formatter. This means GES and - GStreamer can now load and save projects in all the formats - supported by otio. - -- Implemented a GESMarkerList object which allow setting timed - metadata on any GES object. - -- Fixed audio rendering issues during clip transition by ensuring that - a single segment is pushed into encoders. - -- The GESUriClipAsset API is now MT safe. - -- Added ges_meta_container_register_static_meta() to allow fixing a - type for a specific metadata without actually setting a value. - -- The framepositioner element now handles resizing the project and - keeps the same positioning when the aspect ratio is not changed . - -- Reworked the documentation, making it more comprehensive and much - more detailed. - -- Added APIs to retrieve natural size and framerate of a clip (for - example in the case of URIClip it is the framerate/size of the - underlying file). - -- ges_container_edit() is now deprecated and GESTimelineElement gained - the ges_timeline_element_edit() method so the editing API is now - usable from any element in the timeline. - -- GESProject::loading was added so applications can be notified about - when a new timeline starts loading. - -- Implemented the GstStream API in GESTimeline. - -- Added a way to add a timeoverlay inside the test source (potentially - with timecodes). - -- Added APIs to convert times to frame numbers and vice versa: - - - ges_timeline_get_frame_time() - - - ges_timeline_get_frame_at() - - - ges_clip_asset_get_frame_time() - - - ges_clip_get_timeline_time_from_source_frame() - - Quite a few validate tests have been implemented to check the - behavior for various demuxer/codec formats - -- Added ges_layer_set_active_for_tracks() which allows muting layers - for the specified tracks - -- Deprecated GESImageSource and GESMultiFileSource now that we have - imagesequencesrc which handles the imagesequence “protocol” - -- Stopped exposing ‘deinterlacing’ children properties for clip types - where they do not make sense. - -- Added support for simple time remapping effects +- this section will be filled in in due course GStreamer validate -- Introduced the concept of “Test files” allowing to implement “all - included” test cases, meaning that inside the file the following can - be defined: - - - The application arguments - - The validate configurations - - The validate scenario - - This replaces the previous big dictionary file in - gst-validate-launcher to implement specific test cases. - - We set several variables inside the files (as well as inside - scenarios and config files) to make them relocatable. - - The file format has been enhanced so it is easier to read and write, - for example line ending with a coma or (curly) brackets can now be - used as continuation marker so you do not need to add \ at the end - of lines to write a structure on several lines. - -- Support the imagesequence “protocol” and added integration tests for - it. - -- Added action types to allow the scenario to run the Test Clock for - better reproducibility of tests. - -- Support generating tests to check that seeking is frame accurate - (base on ssim). - -- Added ways to record buffers checksum (in different ways) in the - validateflow module. - -- Added vp9 encoding tests. - -- Enhanced seeking action types implementation to allow support for - segment seeks. - -- Output improvements: - - - Logs are now in markdown formats (and bat is used to dump them - if available). - - File format issues in scenarios/configs/tests files are nicely - reported with the line numbers now. +- this section will be filled in in due course GStreamer Python Bindings -- Python 2.x is no longer supported - -- Support mapping buffers without any memcpy: - - - Added a ContextManager to make the API more pythonic - - with buf.map(Gst.MapFlags.READ | Gst.MapFlags.WRITE) as info: - info.data[42] = 0 - -- Added high-level helper API for constructing pipelines: - - - Gst.Bin.make_and_add(factory_name, instance_name=None) - - Gst.Element.link_many(element, ...) +- this section will be filled in in due course GStreamer C# Bindings -- Bind gst_buffer_new_wrapped() manually to fix memory handling. - -- Fix gst_promise_new_with_change_func() where bindgen didn’t properly - detect the func as a closure. - -- Declare GstVideoOverlayComposition and GstVideoOverlayRectangle as - opaque type and subclasses of Gst.MiniObject. This changes the API - but without this all usage will cause memory corruption or simply - not work. - -- on Windows, look for gstreamer, glib and gobject DLLs using the MSVC - naming convention (i.e. gstvideo-1.0-0.dll instead of - libgstvideo-1.0-0.dll). - - The names of these DLLs have to be hardcoded in the bindings, and - most C# users will probably be using the Microsoft toolchain anyway. - - This means that the MSVC compiler is now required to build the - bindings, MingW will no longer work out of the box. +- 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 new GStreamer 1.18 API, so there’s -absolutely no excuse why your next GStreamer application can’t be -written in Rust anymore. +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. @@ -1659,6 +119,8 @@ 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 @@ -1724,73 +186,11 @@ Generic Rust plugins Build and Dependencies -- The Autotools build system has finally been removed in favour of the - Meson build system. Developers who currently use gst-uninstalled - should move to gst-build. - -- API and plugin documentation are no longer built with gtk_doc. The - gtk_doc documentation has been removed in favour of a new unified - documentation module built with hotdoc (also see “Documentation - improvements” section below). Distributors should use the - documentation release tarball instead of trying to package hotdoc - and building the documentation from scratch. - -- gst-plugins-bad now includes an internal copy of libusrsctp, as - there are problems in usrsctp with global shared state, lack of API - stability guarantees, and the absence of any kind of release - process. We also can’t rely on distros shipping a version with the - fixes we need. Both firefox and Chrome bundle their own copies too. - It is still possible to build against an external copy of usrsctp if - so desired. - -- nvcodec no longer needs the NVIDIA NVDEC/NVENC SDKs available at - build time, only at runtime. This allows distributions to ship this - plugin by default and it will just start to work when the required - run-time SDK libraries are installed by the user, without users - needing to build and install the plugin from source. - -- the gst-editing-services tarball is now named gst-editing-services - for consistency (used to be gstreamer-editing-services). - -- the gst-validate tarball has been superseded by the gst-devtools - tarball for consistency with the git module name. +- this section will be filled in in due course gst-build -gst-build is a meta-module and serves primarily as our uninstalled -development environment. It makes it easy to build most of GStreamer, -but unlike Cerbero it only comes with a limited number of external -dependencies that can be built as subprojects if they are not found on -the system. - -gst-build is based on Meson and replaces the old autotools -gst-uninstalled script. - -- The ‘uninstalled’ target has been renamed to ‘devenv’ - -- Experimental gstreamer-full library containing all built plugins and - their deps when building with -Ddefault_library=static. A monolithic - library is easier to distribute, and may be required in some - environments. GStreamer core, GLib and GObject are always included, - but external dependencies are still dynamically linked. The - gst-full-libraries meson option allows adding other GStreamer - libraries to the gstreamer-full build. This is an experiment for now - and its behaviour or API may still change in future releases. - -- Add glib-networking as a subproject when glib is a subproject and - load gio modules in the devenv, tls option control whether to use - openssl or gnutls. - -- git-worktree: Allow multiple worktrees for subproject branches - -- Guard against meson being run from inside the uninstalled devenv, as - this might have unexpected consequences. - -- our ffmpeg and x264 meson ports have been updated to the latest - stable version (you might need to update the subprojects checkout - manually though, or just remove the checkouts so meson checks out - the latest version again; improvements for this are pending in - meson, but not merged yet). +- this section will be filled in in due course Cerbero @@ -1800,405 +200,97 @@ Windows, Android, iOS and macOS. General improvements -- Recipe build steps are done in parallel wherever possible. This - leads to massive improvements in overall build time. -- Several recipes were ported to Meson, which improved build times -- Moved from using both GnuTLS and OpenSSL to only OpenSSL -- Moved from yasm to nasm for all assembly compilation -- Support zsh when running the cerbero shell command -- Numerous version upgrades for dependencies -- Default to xz for tarball binary packages. bz2 can be selected with - the --compress-method option to package. -- Added boolean variant for controlling the optimization level: - -v optimization -- Ship .pc pkgconfig files for all plugins in the binary packages -- CMake and nasm will only be built by Cerbero if the system versions - are unusable -- The nvcodec variant was removed and the nvcodec plugin is built by - default now (as it no longer requires the SDK to be installed at - build time, only at runtime) +- this section will be filled in in due course macOS / iOS -- Minimum iOS SDK version bumped to 11.0 -- Minimum macOS SDK version bumped to 10.11 -- No longer need to manually add support for newer iOS SDK versions -- Added Vulkan elements via MoltenVK -- Build times were improved by code-signing all build tools -- macOS framework ships all gstreamer libraries instead of an outdated - subset -- Ship pkg-config in the macOS framework package -- fontconfig: Fix EXC_BAD_ACCESS crash on iOS ARM64 -- Improved App Store compatibility by setting LC_VERSION_MIN_MACOSX, - fixing relocations, and improved bitcode support +- this section will be filled in in due course Windows -- MinGW-GCC toolchain was updated to 8.2. It uses the Universal CRT - instead of MSVCRT which eliminates cross-CRT issues in the Visual - Studio build. -- Require Windows 7 or newer for running binaries produced by Cerbero -- Require Windows x86_64 for running Cerbero to build binary packages -- Cerbero no longer uses C:/gstreamer/1.0 as a prefix when building. - That prefix is reserved for use by the MSI installers. -- Several recipes can now be buit with Visual Studio instead of MinGW. - Ported to meson: opus, libsrtp, harfbuzz, cairo, openh264, libsoup, - libusrsctp. Existing build system: libvpx, openssl. -- Support building using Visual Studio for 32-bit x86. Previously we - only supported building for 32-bit x86 using the MinGW toolchain. -- Fixed annoying msgmerge popups in the middle of cerbero builds -- Added configuration options vs_install_path and vs_install_version - for specifying custom search locations for older Visual Studio - versions that do not support vswhere. You can set these in - ~/.cerbero/cerbero.cbc where ~ is the MSYS homedir, not your Windows - homedir. -- New Windows-specific plugins: d3d11, mediafoundation, wasapi2 -- Numerous compatibility and reliability fixes when running Cerbero on - Windows, especially non-English locales -- proxy-libintl now exports the same symbols as gettext, which makes - it a drop-in replacement -- New mapping variant for selecting the Visual Studio CRT to use: - -v vscrt=. Valid values are md, mdd, and auto (default). A - separate prefix is used when building with either md (release) or - mdd (debug), and the outputted package will have +debug in the - filename. This variant is also used for selecting the correct Qt - libraries (debug vs release) to use when building with -v qt5 on - Windows. -- Support cross-compile on Windows to Windows ARM64 and ARMv7 -- Support cross-compile on Windows to the Universal Windows Platform - (UWP). Only the subset of plugins that can be built entirely with - Visual Studio will be selected in this case. To do so, use the - config/cross-uwp-universal.cbc configuration, which will build - ARM64, x86, and x86_64 binaries linked to the release CRT, with - optimizations enabled, and debugging turned on. You can combine this - with -v vscrt=mdd to produce binaries linked to the debug CRT. You - can turn off optimizations with the -v nooptimization variant. +- this section will be filled in in due course Windows MSI installer -- Require Windows 7 or newer for running GStreamer -- Fixed some issues with shipping of pkg-config in the Windows - installers -- Plugin PDB debug files are now shipped in the development package, - not the runtime package -- Ship installers for 32-bit binaries built with Visual Studio -- Ship debug and release “universal” (ARM64, X86, and X86_64) tarballs - built for the Universal Windows Platform -- Windows MSI installers now install into separate prefixes when - building with MSVC and MinGW. Previously both would be installed - into C:/gstreamer/1.0/x86 or C:/gstreamer/1.0/x86_64. Now, the - installation prefixes are: - - ---------------------------------------------------------------------------------------------------------------- - Target Path Build options - --------------------------- ------------------------------------ ----------------------------------------------- - MinGW 32-bit C:/gstreamer/1.0/mingw_x86 -c config/win32.cbc - - MinGW 64-bit C:/gstreamer/1.0/mingw_x86_64 -c config/win64.cbc - - MSVC 32-bit C:/gstreamer/1.0/msvc_x86 -c config/win32.cbc -v visualstudio - - MSVC 64-bit C:/gstreamer/1.0/msvc_x86_64 -c config/win64.cbc -v visualstudio - - MSVC 32-bit (debug) C:/gstreamer/1.0/msvc-debug_x86 -c config/win32.cbc -v visualstudio,vscrt=mdd - - MSVC 64-bit (debug) C:/gstreamer/1.0/msvc-debug_x86_64 -c config/win64.cbc -v visualstudio,vscrt=mdd - ---------------------------------------------------------------------------------------------------------------- - -Note: UWP binary packages are tarballs, not MSI installers. +- this section will be filled in in due course Linux -- Support creating MSI installers using WiX when cross-compiling to - Windows -- Support running cross-windows binaries with Wine when using the - shell and runit cerbero commands -- Added bash-completion support inside the cerbero shell on Linux -- Require a system-wide installation of openssl on Linux -- Added variant -v vaapi to build gstreamer-vaapi and the new gstva - plugin -- Debian packaging was disabled because it does not work. Help in - fixing this is appreciated. -- Trimmed the list of packages needed for bootstrap on Linux +- this section will be filled in in due course Android -- Updated to NDK r21 -- Support Vulkan -- Support Qt 5.14+ binary package layout +- this section will be filled in in due course Platform-specific changes and improvements Android -- opensles: Remove hard-coded buffer-/latency-time values and allow - openslessink to handle 48kHz streams. - -- photography interface and camera source: Add additional settings - relevant to Android such as: Exposure mode property, extra colour - tone values (aqua, emboss, sketch, neon), extra scene modes - (backlight, flowers, AR, HDR), and missing virtual methods for - exposure mode, analog gain, lens focus, colour temperature, min & - max exposure time. Add new effects and scene modes to Camera - parameters. +- this section will be filled in in due course macOS and iOS -- vtdec can now output to Vulkan-backed memory for zerocopy support - with the Vulkan elements. +- this section will be filled in in due course Windows -- d3d11videosink: new Direct3D11-based video sink with support for - HDR10 rendering if supported. - -- Hardware-accelerated video decoding on Windows via DXVA2 / - Direct3D11 using native Windows APIs rather than per-vendor SDKs - (like MSDK for Intel or NVCODEC for NVidia). Plus modern Direct3D11 - integration rather than the almost 20-year old Direct3D9 from - Windows XP times used in d3dvideosink. Formats supported for - decoding are H.264, H.265, VP8, and VP9, and zero-copy operation - should be supported in combination with the new d3d11videosink. See - Seungha’s blog post “Windows DXVA2 (via Direct3D 11) Support in - GStreamer 1.17” for more details. - -- Microsoft Media Foundation plugin for hardware-accelerated video - encoding on Windows using native Windows APIs rather than per-vendor - SDKs. Formats supported for encoding are H.264, H.265 and VP9. Also - includes audio encoders for AAC and MP3. See Seungha’s blog post - “Bringing Microsoft Media Foundation to GStreamer” for some more - details about this. - -- new mfvideosrc video capture source element using the latest Windows - APIs rather than ancient APIs used by ksvideosrc/winks. ksvideosrc - should be considered deprecated going forward. - -- d3d11: add d3d11convert, a color space conversion and rescaling - element using shaders, and introduce d3d11upload and d3d11download - elements that work just like glupload and gldownload but for D3D11. - -- Universal Windows Platform (UWP) support, including official - GStreamer binary packages for it. Check out Nirbheek’s latest blog - post “GStreamer 1.18 supports the Universal Windows Platform” for - more details. - -- systemclock correctness and reliability fixes, and also don’t start - the system clock at 0 any longer (which shouldn’t make any - difference to anyone, as absolute clock time values are supposed to - be meaningless in themselves, only the rate of increase matters). - -- toolchain specific plugin registry: the registry cache is now named - differently for MSVC and MinGW toolchains/packages, which should - avoid problems when switching between binaries built with a - different toolchain. - -- new wasapi2 plugin mainly to support UWP applications. The core - logic of this plugin is almost identical to existing wasapi plugin, - but the main target is Windows 10 and UWP. This plugin uses WinRT - APIs, so will likely not work on Windows 8 or older. Unlike the - existing wasapi plugin, this plugin supports automatic stream - routing (auto fallback when device was removed) and device level - mute/volume control. Exclusive streaming mode is not supported, - however, and loopback features are not implemented yet. It is also - only possible to build this plugin with MSVC and the Windows 10 SDK, - it can’t be cross-compiled with the MingW toolchain. - -- new dxgiscreencapsrc element which uses the Desktop Duplication API - to capture the desktop screen at high speed. This is only supported - on Windows 8 or later. Compared to the existing elements - dxgiscreencapsrc offers much better performance, works in High DPI - environments and draws an accurate mouse cursor. - -- d3dvideosink was downgraded to secondary rank, d3d11videosink is - preferred now. Support OverlayComposition for GPU overlay - compositing of subtitles and logos. - -- debug log output fixes, esp. with a non-UTF8 locale/codepage - -- speex, jack: fixed crashes on Windows caused by cross-CRT issues - -- gst-play-1.0 interactive keyboard controls now also work on Windows +- this section will be filled in in due course Linux -- kmssink: Add support for P010 and P016 formats - -- vah264dec: new experimental va plugin with an element for H.264 - decoding with VA-API. This novel approach, different from - gstreamer-vaapi, uses the gstcodecs library for decoder state - handling, which it is hoped will make for cleaner code because it - uses VA-API without further layers or wrappers. Check out Víctor’s - blog post “New VA-API H.264 decoder in gst-plugins-bad” for the full - lowdown and the limitations of this new plugin, and how to give it a - spin. - -- v4l2codecs: introduce a V4L2 CODECs Accelerator. This plugin will - support the new CODECs uAPI in the Linux kernel, which consists of - an accelerator interface similar to DXVA, NVDEC, VDPAU and VAAPI. So - far H.264 and VP8 are supported. This is used on certain embedded - systems such as i.mx8m, rk3288, rk3399, Allwinner H-series SoCs. +- this section will be filled in in due course Documentation improvements -- unified documentation containing tutorials, API docs, plugin docs, - etc. all under one roof, shipped in form of a documentation release - tarball containing both devhelp and html documentation. - -- all documentation is now generated using hotdoc, gtk-doc is no - longer used. Distributors should use the above-mentioned - documentation release tarball instead of trying to package hotdoc - and building the documentation from scratch. - -- there is now documentation for wrapper plugins like gst-libav and - frei0r, as well as tracer plugins. - -- for more info, check out Thibault’s “GStreamer Documentation” - lightning talk from the 2019 GStreamer Conference. - -- new API for plugins to support the documentation system: - - - new GParamSpecFlag GST_PARAM_DOC_SHOW_DEFAULT to make - gst-inspect-1.0 (and the documentation) show the paramspec’s - default value rather than the actually set value as default - - GstPadTemplate getter and setter for “documentation caps”, - gst_pad_template_set_documentation_caps() and - gst_pad_template_get_documentation_caps(): This can be used in - elements where the caps of pad templates are dynamically - generated and/or dependent on the environment, to override the - caps shown in the documentation (usually to advertise the full - set of possible caps). - - gst_type_mark_as_plugin_api() for marking types as plugin API, - used for plugin-internal types like enums, flags, pad - subclasses, boxed types, and such. +- this section will be filled in in due course Possibly Breaking Changes -- GstVideo: the canonical list of raw video formats (for use in caps) - has been reordered, so video elements such as videotestsrc or - videoconvert might negotiate to a different format now than before. - The new format might be a higher-quality format or require more - processing overhead, which might affect pipeline performance. - -- mpegtsdemux used to wrongly advertise H.264 and H.265 video - elementary streams as alignment=nal. This has now been fixed and - changed to alignment=none, which means an h264parse or h265parse - element is now required after tsdemux for some pipelines where there - wasn’t one before, e.g. in transmuxing scenarios (tsdemux ! tsmux). - Pipelines without such a parser may now fail to link or error out at - runtime. As parsers after demuxers and before muxers have been - generally required for a long time now it is hoped that this will - only affect a small number of applications or pipelines. - -- The Android opensles audio source and sink used to have hard-coded - buffer-/latency-time values of 20ms. This is no longer needed with - newer Android versions and has now been removed. This means a higher - or lower value might now be negotiated by default, which can affect - pipeline performance and latency. +- this section will be filled in in due course Known Issues -- None in particular +- 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 -Aaron Boxer, Adam Duskett, Adam x Nilsson, Adrian Negreanu, Akinobu -Mita, Alban Browaeys, Alcaro, Alexander Lapajne, Alexandru Băluț, Alex -Ashley, Alex Hoenig, Alicia Boya García, Alistair Buxton, Ali Yousuf, -Ambareesh “Amby” Balaji, Amr Mahdi, Andoni Morales Alastruey, Andreas -Frisch, Andre Guedes, Andrew Branson, Andrey Sazonov, Antonio Ospite, -aogun, Arun Raghavan, Askar Safin, AsociTon, A. Wilcox, Axel Mårtensson, -Ayush Mittal, Bastian Bouchardon, Benjamin Otte, Bilal Elmoussaoui, -Brady J. Garvin, Branko Subasic, Camilo Celis Guzman, Carlos Rafael -Giani, Charlie Turner, Cheng-Chang Wu, Chris Ayoup, Chris Lord, -Christoph Reiter, cketti, Damian Hobson-Garcia, Daniel Klamt, Daniel -Molkentin, Danny Smith, David Bender, David Gunzinger, David Ing, David -Svensson Fors, David Trussel, Debarshi Ray, Derek Lesho, Devarsh -Thakkar, dhilshad, Dimitrios Katsaros, Dmitriy Purgin, Dmitry Shusharin, -Dominique Leuenberger, Dong Il Park, Doug Nazar, dudengke, Dylan McCall, -Dylan Yip, Ederson de Souza, Edward Hervey, Eero Nurkkala, Eike Hein, -ekwange, Eric Marks, Fabian Greffrath, Fabian Orccon, Fabio D’Urso, -Fabrice Bellet, Fabrice Fontaine, Fanchao L, Felix Yan, Fernando -Herrrera, Francisco Javier Velázquez-García, Freyr, Fuwei Tang, Gaurav -Kalra, George Kiagiadakis, Georgii Staroselskii, Georg Lippitsch, Georg -Ottinger, gla, Göran Jönsson, Gordon Hart, Gregor Boirie, Guillaume -Desmottes, Guillermo Rodríguez, Haakon Sporsheim, Haihao Xiang, Haihua -Hu, Havard Graff, Håvard Graff, Heinrich Kruger, He Junyan, Henry -Wilkes, Hosang Lee, Hou Qi, Hu Qian, Hyunjun Ko, ibauer, Ignacio Casal -Quinteiro, Ilya Smelykh, Jake Barnes, Jakub Adam, James Cowgill, James -Westman, Jan Alexander Steffens, Jan Schmidt, Jan Tojnar, Javier Celaya, -Jeffy Chen, Jennifer Berringer, Jens Göpfert, Jérôme Laheurte, Jim -Mason, Jimmy Ohn, J. Kim, Joakim Johansson, Jochen Henneberg, Johan -Bjäreholt, Johan Sternerup, John Bassett, Jonas Holmberg, Jonas Larsson, -Jonathan Matthew, Jordan Petridis, Jose Antonio Santos Cadenas, Josep -Torra, Jose Quaresma, Josh Matthews, Joshua M. Doe, Juan Navarro, -Juergen Werner, Julian Bouzas, Julien Isorce, Jun-ichi OKADA, Justin -Chadwell, Justin Kim, Keri Henare, Kevin JOLY, Kevin King, Kevin Song, -Knut Andre Tidemann, Kristofer Björkström, krivoguzovVlad, Kyrylo -Polezhaiev, Lenny Jorissen, Linus Svensson, Loïc Le Page, Loïc Minier, -Lucas Stach, Ludvig Rappe, Luka Blaskovic, luke.lin, Luke Yelavich, -Marcin Kolny, Marc Leeman, Marco Felsch, Marcos Kintschner, Marek -Olejnik, Mark Nauwelaerts, Markus Ebner, Martin Liska, Martin Theriault, -Mart Raudsepp, Matej Knopp, Mathieu Duponchelle, Mats Lindestam, Matthew -Read, Matthew Waters, Matus Gajdos, Maxim Paymushkin, Maxim P. -Dementiev, Michael Bunk, Michael Gruner, Michael Olbrich, Miguel París -Díaz, Mikhail Fludkov, Milian Wolff, Millan Castro, Muhammet Ilendemli, -Nacho García, Nayana Topolsky, Nian Yan, Nicola Murino, Nicolas -Dufresne, Nicolas Pernas Maradei, Niels De Graef, Nikita Bobkov, Niklas -Hambüchen, Nirbheek Chauhan, Ognyan Tonchev, okuoku, Oleksandr -Kvl,Olivier Crête, Ondřej Hruška, Pablo Marcos Oltra, Patricia Muscalu, -Peter Seiderer, Peter Workman, Philippe Normand, Philippe Renon, Philipp -Zabel, Pieter Willem Jordaan, Piotr Drąg, Ralf Sippl, Randy Li, Rasmus -Thomsen, Ratchanan Srirattanamet, Raul Tambre, Ray Tiley, Richard -Kreckel, Rico Tzschichholz, R Kh, Robert Rosengren, Robert Tiemann, -Roman Shpuntov, Roman Sivriver, Ruben Gonzalez, Rubén Gonzalez, -rubenrua, Ryan Huang, Sam Gigliotti, Santiago Carot-Nemesio, Saunier -Thibault, Scott Kanowitz, Sebastian Dröge, Sebastiano Barrera, Seppo -Yli-Olli, Sergey Nazaryev, Seungha Yang, Shinya Saito, Silvio -Lazzeretti, Simon Arnling Bååth, Siwon Kang, sohwan.park, Song Bing, -Soohyun Lee, Srimanta Panda, Stefano Buora, Stefan Sauer, Stéphane -Cerveau, Stian Selnes, Sumaid Syed, Swayamjeet, Thiago Santos, Thibault -Saunier, Thomas Bluemel, Thomas Coldrick, Thor Andreassen, Tim-Philipp -Müller, Ting-Wei Lan, Tobias Ronge, trilene, Tulio Beloqui, U. Artie -Eoff, VaL Doroshchuk, Varunkumar Allagadapa, Vedang Patel, Veerabadhran -G, Víctor Manuel Jáquez Leal, Vivek R, Vivia Nikolaidou, Wangfei, Wang -Zhanjun, Wim Taymans, Wonchul Lee, Xabier Rodriguez Calvar, Xavier -Claessens, Xidorn Quan, Xu Guangxin, Yan Wang, Yatin Maan, Yeongjin -Jeong, yychao, Zebediah Figura, Zeeshan Ali, Zeid Bekli, Zhiyuan Sraf, -Zoltán Imets, +- 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.18 branch +Stable 1.20 branch -After the 1.18.0 release there will be several 1.18.x bug-fix releases +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.18.x bug-fix releases will be made from -the git 1.18 branch, which will be a stable branch. +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.18.0 +1.20.0 -1.18.0 was released on 7 September 2020. +1.20.0 is scheduled to be released around July 2021. -Schedule for 1.20 +Schedule for 1.22 -Our next major feature release will be 1.20, and 1.19 will be the -unstable development version leading up to the stable 1.20 release. The -development of 1.19/1.20 will happen in the git master branch. +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 master branch. -The plan for the 1.20 development cycle is yet to be confirmed, but it -is now expected that feature freeze will take place some time in January -2021, with the first 1.20 stable release around February/March 2021. +The plan for the 1.22 development cycle is yet to be confirmed, but it +is hoped that feature freeze will take place some time in December 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. +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 Mathieu Duponchelle, Matthew Waters, Nirbheek -Chauhan, Sebastian Dröge, Thibault Saunier, and Víctor Manuel Jáquez -Leal. +contributions from … License: CC BY-SA 4.0 diff --git a/RELEASE b/RELEASE index 9c9bd3eeb5..ab30ecdf37 100644 --- a/RELEASE +++ b/RELEASE @@ -1,18 +1,15 @@ -This is GStreamer gstreamer-vaapi 1.18.0. +This is GStreamer gstreamer-vaapi 1.19.1. -The GStreamer team is thrilled to announce a new major feature release -of your favourite cross-platform multimedia framework! +GStreamer 1.19 is the development branch leading up to the next major +stable version which will be 1.20. -As always, this release is again packed with new features, bug fixes and -other improvements. - -The 1.18 release series adds new features on top of the 1.16 series and is +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 can be found at: +Full release notes will one day be found at: - https://gstreamer.freedesktop.org/releases/1.18/ + https://gstreamer.freedesktop.org/releases/1.20/ Binaries for Android, iOS, Mac OS X and Windows will usually be provided shortly after the release. diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index f988ce0447..1f2c4c191e 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.19.1 + master + + 2021-06-01 + + + + 1.18.0 diff --git a/meson.build b/meson.build index 8a8347cd90..99faec1ceb 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.19.0.1', + version : '1.19.1', meson_version : '>= 0.54', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From f3dcdfbd606d0c4cd1e7e12872d21d36919c043e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 1 Jun 2021 15:29:16 +0100 Subject: [PATCH 3771/3781] Back to development --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 99faec1ceb..5c4a8dfa65 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.19.1', + version : '1.19.1.1', meson_version : '>= 0.54', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) From 26143333899382035e66f0360019c67d4a252e78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 22 May 2021 18:54:49 +0100 Subject: [PATCH 3772/3781] Use g_memdup2() where available and add fallback for older GLib versions Alloc size is based on existing allocations and struct sizes. g_memdup() is deprecated since GLib 2.68 and we want to avoid deprecation warnings with recent versions of GLib. Part-of: --- gst-libs/gst/vaapi/gstvaapifilter.c | 2 +- meson.build | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c index e0b3cd5fad..675c481b3f 100644 --- a/gst-libs/gst/vaapi/gstvaapifilter.c +++ b/gst-libs/gst/vaapi/gstvaapifilter.c @@ -671,7 +671,7 @@ op_data_ensure_caps (GstVaapiFilterOpData * op_data, gpointer filter_caps, return FALSE; } - op_data->va_caps = g_memdup (filter_cap, op_data->va_cap_size * va_num_caps); + op_data->va_caps = g_memdup2 (filter_cap, op_data->va_cap_size * va_num_caps); if (!op_data->va_caps) return FALSE; diff --git a/meson.build b/meson.build index 5c4a8dfa65..85ca246954 100644 --- a/meson.build +++ b/meson.build @@ -208,6 +208,10 @@ if gst_version_nano == 0 endif endif +if gmodule_dep.version().version_compare('< 2.67.4') + cdata.set('g_memdup2(ptr,sz)', '(G_LIKELY(((guint64)(sz)) < G_MAXUINT)) ? g_memdup(ptr,sz) : (g_abort(),NULL)') +endif + configure_file(output: 'config.h', configuration: cdata) python3 = import('python').find_installation() From 9f02c3fa4ccf66d0258608ce9eda3051706a835e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 11 May 2021 16:59:07 +0800 Subject: [PATCH 3773/3781] Decoder: H264: Add the support for frame packing arrangement SEI message. Frame packing arrangement SEI message is an alternative simple stereo 3D manner for AVC. We need to recognize that SEI message and report the correct 3D caps. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 166 +++++++++++++++++++++- 1 file changed, 161 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 8c3b9b09bd..01b1797eb4 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -46,6 +46,7 @@ typedef struct _GstVaapiFrameStore GstVaapiFrameStore; typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass; typedef struct _GstVaapiParserInfoH264 GstVaapiParserInfoH264; typedef struct _GstVaapiPictureH264 GstVaapiPictureH264; +typedef struct _GstVaapiStereo3DInfo GstVaapiStereo3DInfo; // Used for field_poc[] #define TOP_FIELD 0 @@ -460,6 +461,24 @@ gst_vaapi_frame_store_has_inter_view (GstVaapiFrameStore * fs) gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_fs_p), \ (GstVaapiMiniObject *)(new_fs)) +/* ------------------------------------------------------------------------- */ +/* --- H.264 3D Info --- */ +/* ------------------------------------------------------------------------- */ +/** + * GstVaapiStereo3DInfo: + * @mode: the #GstVideoMultiviewMode. + * @flags: the #GstVideoMultiviewFlags. + * @id: the id number. + * @repetition_period: 0 means once, 1 means always, >1 compare with poc. + */ +struct _GstVaapiStereo3DInfo +{ + GstVideoMultiviewMode mode; + GstVideoMultiviewFlags flags; + guint id; + guint repetition_period; +}; + /* ------------------------------------------------------------------------- */ /* --- H.264 Decoder --- */ /* ------------------------------------------------------------------------- */ @@ -539,6 +558,8 @@ struct _GstVaapiDecoderH264Private gboolean force_low_latency; gboolean base_only; + + GstVaapiStereo3DInfo stereo_info; }; /** @@ -1332,6 +1353,8 @@ gst_vaapi_decoder_h264_create (GstVaapiDecoder * base_decoder) priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME; priv->progressive_sequence = TRUE; priv->top_field_first = FALSE; + priv->stereo_info.mode = GST_VIDEO_MULTIVIEW_MODE_MONO; + priv->stereo_info.flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE; return TRUE; } @@ -1555,11 +1578,15 @@ ensure_context (GstVaapiDecoderH264 * decoder, GstH264SPS * sps) if (reset_context) { switch (num_views) { case 1: - /* Frame-packed mode details should be copied from the parser - * if we set NONE */ - gst_vaapi_decoder_set_multiview_mode (base_decoder, - num_views, GST_VIDEO_MULTIVIEW_MODE_NONE, - GST_VIDEO_MULTIVIEW_FLAGS_NONE); + /* Frame-packed mode details should be used if we got */ + if (priv->stereo_info.mode != GST_VIDEO_MULTIVIEW_MODE_NONE) { + gst_vaapi_decoder_set_multiview_mode (base_decoder, + 2, priv->stereo_info.mode, priv->stereo_info.flags); + } else { + gst_vaapi_decoder_set_multiview_mode (base_decoder, + num_views, GST_VIDEO_MULTIVIEW_MODE_NONE, + GST_VIDEO_MULTIVIEW_FLAGS_NONE); + } break; case 2: /* Assume stereo */ if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) { @@ -1964,6 +1991,132 @@ decode_pps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) return GST_VAAPI_DECODER_STATUS_SUCCESS; } +static gboolean +decode_sei_frame_packing (GstVaapiDecoderH264 * decoder, + const GstH264FramePacking * frame_packing) +{ + GstVaapiDecoderH264Private *const priv = &decoder->priv; + GstVideoMultiviewMode saved_mode = priv->stereo_info.mode; + GstVideoMultiviewFlags saved_flags = priv->stereo_info.flags; + gboolean left = TRUE; + gboolean frame_revert = FALSE; + + /* Only IDs from 0->255 and 512->2^31-1 are valid. Ignore others */ + if ((frame_packing->frame_packing_id >= 256 && + frame_packing->frame_packing_id < 512) || + (frame_packing->frame_packing_id >= (1U << 31))) + return FALSE; + + if (frame_packing->frame_packing_cancel_flag) { + if (priv->stereo_info.id == frame_packing->frame_packing_id) + priv->stereo_info = (GstVaapiStereo3DInfo) { + GST_VIDEO_MULTIVIEW_MODE_MONO, GST_VIDEO_MULTIVIEW_FLAGS_NONE, 256, 0}; + return TRUE; + } + + if (frame_packing->frame_packing_repetition_period != 1) { + GST_WARNING ("SEI: repetition_period != 1 is not unsupported"); + return FALSE; + } + + if (frame_packing->frame_packing_type > GST_H264_FRAME_PACKING_NONE) { + GST_WARNING ("SEI: unsupported frame_packing_type %d", + frame_packing->frame_packing_type); + return FALSE; + } + + if (frame_packing->content_interpretation_type >= 3) { + GST_WARNING ("SEI: unsupported content_interpretation_type %d", + frame_packing->frame_packing_type); + return FALSE; + } + + /* TODO: frame frame0/1_grid_position_x/y are ignored now. */ + + priv->stereo_info = (GstVaapiStereo3DInfo) { + GST_VIDEO_MULTIVIEW_MODE_MONO, GST_VIDEO_MULTIVIEW_FLAGS_NONE, 256, 0}; + + switch (frame_packing->frame_packing_type) { + case GST_H264_FRAME_PACKING_CHECKERBOARD_INTERLEAVING: + priv->stereo_info.mode = GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD; + break; + case GST_H264_FRAME_PACKING_COLUMN_INTERLEAVING: + priv->stereo_info.mode = GST_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED; + break; + case GST_H264_FRAME_PACKING_ROW_INTERLEAVING: + priv->stereo_info.mode = GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED; + break; + case GST_H264_FRAME_PACKING_SIDE_BY_SIDE: + if (frame_packing->quincunx_sampling_flag) { + priv->stereo_info.mode = GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE_QUINCUNX; + } else { + priv->stereo_info.mode = GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE; + } + break; + case GST_H264_FRMAE_PACKING_TOP_BOTTOM: + priv->stereo_info.mode = GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM; + break; + case GST_H264_FRAME_PACKING_TEMPORAL_INTERLEAVING: + priv->stereo_info.mode = GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME; + break; + default: + priv->stereo_info.mode = GST_VIDEO_MULTIVIEW_MODE_MONO; + break; + } + + /* Spec does not describe multi-IDs case, we just keep one valid */ + priv->stereo_info.id = frame_packing->frame_packing_id; + priv->stereo_info.repetition_period = + frame_packing->frame_packing_repetition_period; + + if (frame_packing->content_interpretation_type == 2) + frame_revert = TRUE; + + if (frame_packing->frame_packing_type == + GST_H264_FRAME_PACKING_TEMPORAL_INTERLEAVING) { + if (frame_packing->current_frame_is_frame0_flag) { + left = TRUE; + } else { + left = FALSE; + } + + if (frame_revert) + left = !left; + } + + if (!left) + priv->stereo_info.flags |= GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST; + + if (frame_packing->frame_packing_type == GST_H264_FRAME_PACKING_SIDE_BY_SIDE + && frame_packing->spatial_flipping_flag) { + if (frame_packing->frame0_flipped_flag != + ((priv->stereo_info.flags & + GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST) != 0)) { + priv->stereo_info.flags |= GST_VIDEO_MULTIVIEW_FLAGS_LEFT_FLOPPED; + } else { + priv->stereo_info.flags |= GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_FLOPPED; + } + } + if (frame_packing->frame_packing_type == GST_H264_FRMAE_PACKING_TOP_BOTTOM + && frame_packing->spatial_flipping_flag != + ((priv->stereo_info.flags & + GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST) != 0)) { + if (frame_packing->frame0_flipped_flag) { + priv->stereo_info.flags |= GST_VIDEO_MULTIVIEW_FLAGS_LEFT_FLIPPED; + } else { + priv->stereo_info.flags |= GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_FLIPPED; + } + } + + if (saved_mode != priv->stereo_info.mode + || saved_flags != priv->stereo_info.flags) { + gst_vaapi_decoder_set_multiview_mode (GST_VAAPI_DECODER_CAST (decoder), + 2, priv->stereo_info.mode, priv->stereo_info.flags); + } + + return TRUE; +} + static GstVaapiDecoderStatus decode_sei (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) { @@ -1984,6 +2137,9 @@ decode_sei (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit) priv->pic_structure = pic_timing->pic_struct; break; } + case GST_H264_SEI_FRAME_PACKING: + decode_sei_frame_packing (decoder, &sei->payload.frame_packing); + break; default: break; } From 310ffc17a8406359af60762f42b5a66cc14f8c3f Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 3 Jun 2021 22:12:04 +0800 Subject: [PATCH 3774/3781] libs: encoder: mpeg2: Add highP level for 1080@50p/60p. The MPEG2 spec has amendment 3 to introduce a new level highP, which is used for 1080@50p/60p streams. We need to add this level to avoid encoding failure because of the level check. Fix: #306 Part-of: --- gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c | 8 ++++++-- gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c index baba0723d8..04993c8a4e 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c @@ -51,6 +51,7 @@ static const struct map gst_vaapi_mpeg2_level_map[] = { { GST_VAAPI_LEVEL_MPEG2_MAIN, "main" }, { GST_VAAPI_LEVEL_MPEG2_HIGH_1440, "high-1440" }, { GST_VAAPI_LEVEL_MPEG2_HIGH, "high" }, + { GST_VAAPI_LEVEL_MPEG2_HIGHP, "highP" }, { 0, NULL } /* *INDENT-ON* */ }; @@ -67,6 +68,9 @@ static const GstVaapiMPEG2LevelLimits gst_vaapi_mpeg2_level_limits[] = { 0x06, 1440, 1152, 60, 47001600, 60000, 7340032 }, { GST_VAAPI_LEVEL_MPEG2_HIGH, 0x04, 1920, 1152, 60, 62668800, 80000, 9781248 }, + /* Amendment 3: New level for 1080@50p/60p */ + { GST_VAAPI_LEVEL_MPEG2_HIGHP, + 0x02, 1920, 1152, 60, 125337600, 80000, 9781248 }, { 0, } }; /* *INDENT-ON* */ @@ -215,7 +219,7 @@ gst_vaapi_utils_mpeg2_get_level_from_string (const gchar * str) const gchar * gst_vaapi_utils_mpeg2_get_level_string (GstVaapiLevelMPEG2 level) { - if (level < GST_VAAPI_LEVEL_MPEG2_LOW || level > GST_VAAPI_LEVEL_MPEG2_HIGH) + if (level < GST_VAAPI_LEVEL_MPEG2_LOW || level > GST_VAAPI_LEVEL_MPEG2_HIGHP) return NULL; return gst_vaapi_mpeg2_level_map[level - GST_VAAPI_LEVEL_MPEG2_LOW].name; } @@ -225,7 +229,7 @@ gst_vaapi_utils_mpeg2_get_level_string (GstVaapiLevelMPEG2 level) const GstVaapiMPEG2LevelLimits * gst_vaapi_utils_mpeg2_get_level_limits (GstVaapiLevelMPEG2 level) { - if (level < GST_VAAPI_LEVEL_MPEG2_LOW || level > GST_VAAPI_LEVEL_MPEG2_HIGH) + if (level < GST_VAAPI_LEVEL_MPEG2_LOW || level > GST_VAAPI_LEVEL_MPEG2_HIGHP) return NULL; return &gst_vaapi_mpeg2_level_limits[level - GST_VAAPI_LEVEL_MPEG2_LOW]; } diff --git a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h index 64e38d1cb2..997011df53 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h @@ -33,6 +33,7 @@ G_BEGIN_DECLS * @GST_VAAPI_LEVEL_MPEG2_MAIN: Main level. * @GST_VAAPI_LEVEL_MPEG2_HIGH_1440: High-1440 level. * @GST_VAAPI_LEVEL_MPEG2_HIGH: High level. + * @GST_VAAPI_LEVEL_MPEG2_HIGHP: HighP level. * * The set of all levels for #GstVaapiLevelMPEG2. */ @@ -41,6 +42,7 @@ typedef enum { GST_VAAPI_LEVEL_MPEG2_MAIN, GST_VAAPI_LEVEL_MPEG2_HIGH_1440, GST_VAAPI_LEVEL_MPEG2_HIGH, + GST_VAAPI_LEVEL_MPEG2_HIGHP, } GstVaapiLevelMPEG2; /* Returns a relative score for the supplied GstVaapiProfile */ From d152ab1d3734e285f3b79ad61bd5facb2364a3af Mon Sep 17 00:00:00 2001 From: He Junyan Date: Tue, 29 Jun 2021 15:09:13 +0800 Subject: [PATCH 3775/3781] libs: decoder: av1: Clean the film_grain_info field. We need to clean all film_grain_info fields when the film grain feature is not enabled. It may have random data because the picture parameter buffer is not cleaned. Part-of: --- gst-libs/gst/vaapi/gstvaapidecoder_av1.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_av1.c b/gst-libs/gst/vaapi/gstvaapidecoder_av1.c index a4faf5d22e..eff62e635d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_av1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_av1.c @@ -372,9 +372,10 @@ av1_fill_film_grain_info (VADecPictureParameterBufferAV1 * pic_param, { guint i; - if (!frame_header->film_grain_params.apply_grain) + if (!frame_header->film_grain_params.apply_grain) { + memset (&pic_param->film_grain_info, 0, sizeof (VAFilmGrainStructAV1)); return; - + } #define COPY_FILM_GRAIN_FIELD(FP) \ pic_param->SUB_FIELD.FP = (frame_header)->film_grain_params.FP #define SUB_FIELD film_grain_info.film_grain_info_fields.bits From 677d1e01051e2ee47439cff7cc7f527bb71afbb8 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 23 Jun 2021 16:23:00 +0800 Subject: [PATCH 3776/3781] plugins: encode: fix a deadlock because of _drain() We call gst_vaapiencode_drain() in gst_vaapiencode_change_state(), whose context does not hold the stream lock of the encoder. The current gst_vaapiencode_drain inside unlock/lock pair adds a extra lock count to the stream lock of encoder and causes hang later. We just remove the gst_vaapiencode_drain() and expand its logic correctly according to the lock/unlock context. Part-of: --- gst/vaapi/gstvaapiencode.c | 49 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index b17a81e50d..e86d55b9e1 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -557,29 +557,11 @@ set_codec_state (GstVaapiEncode * encode, GstVideoCodecState * state) return TRUE; } -static gboolean -gst_vaapiencode_drain (GstVaapiEncode * encode) -{ - GstVaapiEncoderStatus status; - - if (!encode->encoder) - return TRUE; - - GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); - status = gst_vaapi_encoder_flush (encode->encoder); - GST_VIDEO_ENCODER_STREAM_LOCK (encode); - - if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) - return FALSE; - gst_vaapiencode_purge (encode); - - return TRUE; -} - static gboolean gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); + GstVaapiEncoderStatus status; g_return_val_if_fail (state->caps != NULL, FALSE); @@ -590,9 +572,14 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) state->caps, NULL)) return FALSE; - if (!gst_vaapiencode_drain (encode)) + GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); + status = gst_vaapi_encoder_flush (encode->encoder); + GST_VIDEO_ENCODER_STREAM_LOCK (encode); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return FALSE; + gst_vaapiencode_purge (encode); + if (encode->input_state) gst_video_codec_state_unref (encode->input_state); encode->input_state = gst_video_codec_state_ref (state); @@ -745,13 +732,19 @@ static GstStateChangeReturn gst_vaapiencode_change_state (GstElement * element, GstStateChange transition) { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (element); + GstVaapiEncoderStatus status; switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: gst_pad_stop_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode)); - if (!gst_vaapiencode_drain (encode)) - goto drain_error; + status = gst_vaapi_encoder_flush (encode->encoder); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) + goto flush_error; + + GST_VIDEO_ENCODER_STREAM_LOCK (encode); + gst_vaapiencode_purge (encode); + GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); break; default: break; @@ -760,9 +753,9 @@ gst_vaapiencode_change_state (GstElement * element, GstStateChange transition) GST_ELEMENT_CLASS (gst_vaapiencode_parent_class)->change_state (element, transition); -drain_error: +flush_error: { - GST_ERROR ("failed to drain pending encoded frames"); + GST_ERROR ("failed to flush pending encoded frames"); return GST_STATE_CHANGE_FAILURE; } } @@ -808,15 +801,21 @@ static gboolean gst_vaapiencode_flush (GstVideoEncoder * venc) { GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); + GstVaapiEncoderStatus status; if (!encode->encoder) return FALSE; GST_LOG_OBJECT (encode, "flushing"); - if (!gst_vaapiencode_drain (encode)) + GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); + status = gst_vaapi_encoder_flush (encode->encoder); + GST_VIDEO_ENCODER_STREAM_LOCK (encode); + if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) return FALSE; + gst_vaapiencode_purge (encode); + gst_vaapi_encoder_replace (&encode->encoder, NULL); if (!ensure_encoder (encode)) return FALSE; From e0a56f339193e057415bfaf7cfea5106e5e97590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 9 Jul 2021 11:01:14 +0200 Subject: [PATCH 3777/3781] Revert "vaapi: Demote vaapidecodebin to rank NONE." This reverts commit 7a25c5d4ec95aefeca6515ac023b23c5dd330194. Part-of: --- gst/vaapi/gstvaapi.c | 2 +- gst/vaapi/gstvaapidecode.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 56ee703f04..3532624839 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -210,7 +210,7 @@ plugin_init (GstPlugin * plugin) GST_RANK_NONE, GST_TYPE_VAAPIPOSTPROC); gst_element_register (plugin, "vaapidecodebin", - GST_RANK_NONE, GST_TYPE_VAAPI_DECODE_BIN); + GST_RANK_PRIMARY + 2, GST_TYPE_VAAPI_DECODE_BIN); rank = GST_RANK_SECONDARY; if (g_getenv ("WAYLAND_DISPLAY")) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4e8d35fbfc..76d1bc47ce 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -115,14 +115,14 @@ static const GstVaapiDecoderMap vaapi_decode_map[] = { {GST_VAAPI_CODEC_MPEG4, GST_RANK_PRIMARY, "mpeg4", "video/mpeg, mpegversion=4", NULL}, {GST_VAAPI_CODEC_H263, GST_RANK_PRIMARY, "h263", "video/x-h263", NULL}, - {GST_VAAPI_CODEC_H264, GST_RANK_PRIMARY + 1, "h264", "video/x-h264", + {GST_VAAPI_CODEC_H264, GST_RANK_PRIMARY, "h264", "video/x-h264", gst_vaapi_decode_h264_install_properties}, - {GST_VAAPI_CODEC_VC1, GST_RANK_PRIMARY + 1, "vc1", + {GST_VAAPI_CODEC_VC1, GST_RANK_PRIMARY, "vc1", "video/x-wmv, wmvversion=3, format={WMV3,WVC1}", NULL}, - {GST_VAAPI_CODEC_VP8, GST_RANK_PRIMARY + 1, "vp8", "video/x-vp8", NULL}, - {GST_VAAPI_CODEC_VP9, GST_RANK_PRIMARY + 1, "vp9", "video/x-vp9", NULL}, - {GST_VAAPI_CODEC_H265, GST_RANK_PRIMARY + 1, "h265", "video/x-h265", NULL}, - {GST_VAAPI_CODEC_AV1, GST_RANK_PRIMARY + 1, "av1", "video/x-av1", NULL}, + {GST_VAAPI_CODEC_VP8, GST_RANK_PRIMARY, "vp8", "video/x-vp8", NULL}, + {GST_VAAPI_CODEC_VP9, GST_RANK_PRIMARY, "vp9", "video/x-vp9", NULL}, + {GST_VAAPI_CODEC_H265, GST_RANK_PRIMARY, "h265", "video/x-h265", NULL}, + {GST_VAAPI_CODEC_AV1, GST_RANK_PRIMARY, "av1", "video/x-av1", NULL}, {0 /* the rest */ , GST_RANK_PRIMARY + 1, NULL, gst_vaapidecode_sink_caps_str, NULL}, }; From c27c158cb2efe285f6fcf909cb49e8a0ac88c568 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 14 May 2021 11:49:01 +0800 Subject: [PATCH 3778/3781] plugins: video memory: Add a GST_MAP_VAAPI flag to peek the surface. Just like what we do in VA plugins, the GST_MAP_VAAPI can directly peek the surface of the VA buffers. The old flag 0 just peek the surface proxy, which may not be convenient for the users who do not want to include our headers. Part-of: --- gst/vaapi/gstvaapivideomemory.c | 16 ++++++++++++++-- gst/vaapi/gstvaapivideomemory.h | 2 ++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index 750385a493..8c1f5887dc 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -378,6 +378,7 @@ gst_vaapi_video_memory_new (GstAllocator * base_allocator, mem->meta = meta ? gst_vaapi_video_meta_ref (meta) : NULL; mem->map_type = 0; mem->map_count = 0; + mem->map_surface_id = VA_INVALID_ID; mem->usage_flag = allocator->usage_flag; g_mutex_init (&mem->lock); @@ -437,8 +438,9 @@ gst_vaapi_video_memory_map (GstMemory * base_mem, gsize maxsize, guint flags) g_mutex_lock (&mem->lock); if (mem->map_count == 0) { - switch (flags & GST_MAP_READWRITE) { + switch (flags & (GST_MAP_READWRITE | GST_MAP_VAAPI)) { case 0: + case GST_MAP_VAAPI: // No flags set: return a GstVaapiSurfaceProxy gst_vaapi_surface_proxy_replace (&mem->proxy, gst_vaapi_video_meta_get_surface_proxy (mem->meta)); @@ -462,7 +464,16 @@ gst_vaapi_video_memory_map (GstMemory * base_mem, gsize maxsize, guint flags) case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: if (!mem->proxy) goto error_no_surface_proxy; - data = mem->proxy; + + if (flags == GST_MAP_VAAPI) { + mem->map_surface_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (mem->proxy); + if (mem->map_surface_id == VA_INVALID_ID) + goto error_no_current_surface; + + data = &mem->map_surface_id; + } else { + data = mem->proxy; + } break; case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR: if (!mem->image) @@ -515,6 +526,7 @@ gst_vaapi_video_memory_unmap_full (GstMemory * base_mem, GstMapInfo * info) if (mem->map_count == 1) { switch (mem->map_type) { case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE: + mem->map_surface_id = VA_INVALID_ID; gst_vaapi_surface_proxy_replace (&mem->proxy, NULL); break; case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR: diff --git a/gst/vaapi/gstvaapivideomemory.h b/gst/vaapi/gstvaapivideomemory.h index 41a05888b0..23d68ad7be 100644 --- a/gst/vaapi/gstvaapivideomemory.h +++ b/gst/vaapi/gstvaapivideomemory.h @@ -128,6 +128,7 @@ struct _GstVaapiVideoMemory GstVaapiVideoMeta *meta; guint map_type; gint map_count; + VASurfaceID map_surface_id; GstVaapiImageUsageFlags usage_flag; GMutex lock; }; @@ -157,6 +158,7 @@ gst_vaapi_video_memory_sync (GstVaapiVideoMemory * mem); /* ------------------------------------------------------------------------ */ /* --- GstVaapiVideoAllocator --- */ /* ------------------------------------------------------------------------ */ +#define GST_MAP_VAAPI (GST_MAP_FLAG_LAST << 1) #define GST_VAAPI_VIDEO_ALLOCATOR_CAST(allocator) \ ((GstVaapiVideoAllocator *) (allocator)) From 7809c58664519e8af2266fbb1da8dd93e78b5bc3 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 14 May 2021 12:04:04 +0800 Subject: [PATCH 3779/3781] Display: Add a property to export the VA display handle. Just like what we do in VA plugins. The display can be seen as a generic gst object and we can add a property to get the internal VA handle. Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay.c | 15 +++++++++++++++ gst/vaapi/gstvaapivideocontext.c | 3 +++ 2 files changed, 18 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 26c216e7e8..878761af83 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -86,6 +86,7 @@ enum PROP_SATURATION, PROP_BRIGHTNESS, PROP_CONTRAST, + PROP_VA_DISPLAY, N_PROPERTIES }; @@ -1123,6 +1124,11 @@ gst_vaapi_display_get_property (GObject * object, guint property_id, GstVaapiDisplay *display = GST_VAAPI_DISPLAY (object); const GstVaapiProperty *prop; + if (property_id == PROP_VA_DISPLAY) { + g_value_set_pointer (value, gst_vaapi_display_get_display (display)); + return; + } + if (!ensure_properties (display)) return; @@ -1224,6 +1230,15 @@ gst_vaapi_display_class_init (GstVaapiDisplayClass * klass) "contrast", "The display contrast value", 0.0, 2.0, 1.0, G_PARAM_READWRITE); + /** + * GstVaapiDisplay:va-display: + * + * The VA display handle, expressed as a #VADisplay. + */ + g_properties[PROP_VA_DISPLAY] = + g_param_spec_pointer ("va-display", "VADisplay", + "VA Display handler", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, N_PROPERTIES, g_properties); gst_type_mark_as_plugin_api (gst_vaapi_display_type_get_type (), 0); } diff --git a/gst/vaapi/gstvaapivideocontext.c b/gst/vaapi/gstvaapivideocontext.c index ae3af85dc1..cc2967b833 100644 --- a/gst/vaapi/gstvaapivideocontext.c +++ b/gst/vaapi/gstvaapivideocontext.c @@ -64,6 +64,9 @@ gst_vaapi_video_context_set_display (GstContext * context, structure = gst_context_writable_structure (context); gst_structure_set (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, GST_TYPE_VAAPI_DISPLAY, display, NULL); + /* The outside user may access it as a generic Gobject. */ + gst_structure_set (structure, "gst.vaapi.Display.GObject", + GST_TYPE_OBJECT, display, NULL); } GstContext * From bd8c0b33e7b9bf4fbe9104f3f529cea3519788c7 Mon Sep 17 00:00:00 2001 From: Zhang Yuankun Date: Thu, 26 Aug 2021 15:06:53 +0800 Subject: [PATCH 3780/3781] vaapi: decoder: modify the condition to judge whether dma buffer is supported It seems "GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (decode)" will return false even if this platform support the mem_type dma buffer. And media-driver will return GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF2 on Gen12(such as TGL). Without this patch, The command such as: gst-launch-1.0 videotestsrc num-buffers=100 ! video/x-raw, format=I420 ! \ x264enc ! h264parse ! vaapih264dec ! video/x-raw\(memory:DMABuf\) ! fakesink will return not-negotiated. Signed-off-by: Zhang Yuankun Part-of: --- gst/vaapi/gstvaapidecode.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 76d1bc47ce..10be755904 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -274,9 +274,10 @@ gst_vaapidecode_ensure_allowed_srcpad_caps (GstVaapiDecode * decode) gst_caps_set_features_simple (va_caps, gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE)); - if (GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (decode) - && gst_vaapi_mem_type_supports (mem_types, - GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF)) { + if (gst_vaapi_mem_type_supports (mem_types, + GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF) || + gst_vaapi_mem_type_supports (mem_types, + GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF2)) { dma_caps = gst_caps_copy (base_caps); gst_caps_set_features_simple (dma_caps, gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF)); From c3ddb29cb2860374f9efbed495af7b0eead08312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 23 Sep 2021 01:35:54 +0100 Subject: [PATCH 3781/3781] Release 1.19.2 --- ChangeLog | 111 +++++++++++++++++++++++++++++++++++++++++++ NEWS | 25 +++++----- RELEASE | 2 +- gstreamer-vaapi.doap | 10 ++++ meson.build | 2 +- 5 files changed, 137 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 182a2ed27b..b04e5478d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,114 @@ +=== release 1.19.2 === + +2021-09-23 01:35:54 +0100 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * RELEASE: + * gstreamer-vaapi.doap: + * meson.build: + Release 1.19.2 + +2021-08-26 15:06:53 +0800 Zhang Yuankun + + * gst/vaapi/gstvaapidecode.c: + vaapi: decoder: modify the condition to judge whether dma buffer is supported + It seems "GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF (decode)" will + return false even if this platform support the mem_type dma buffer. + And media-driver will return GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF2 + on Gen12(such as TGL). + Without this patch, The command such as: + gst-launch-1.0 videotestsrc num-buffers=100 ! video/x-raw, format=I420 ! \ + x264enc ! h264parse ! vaapih264dec ! video/x-raw\(memory:DMABuf\) ! fakesink + will return not-negotiated. + Signed-off-by: Zhang Yuankun + Part-of: + +2021-05-14 12:04:04 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidisplay.c: + * gst/vaapi/gstvaapivideocontext.c: + Display: Add a property to export the VA display handle. + Just like what we do in VA plugins. The display can be seen as a + generic gst object and we can add a property to get the internal + VA handle. + Part-of: + +2021-05-14 11:49:01 +0800 He Junyan + + * gst/vaapi/gstvaapivideomemory.c: + * gst/vaapi/gstvaapivideomemory.h: + plugins: video memory: Add a GST_MAP_VAAPI flag to peek the surface. + Just like what we do in VA plugins, the GST_MAP_VAAPI can directly + peek the surface of the VA buffers. The old flag 0 just peek the + surface proxy, which may not be convenient for the users who do not + want to include our headers. + Part-of: + +2021-07-09 11:01:14 +0200 Víctor Manuel Jáquez Leal + + * gst/vaapi/gstvaapi.c: + * gst/vaapi/gstvaapidecode.c: + Revert "vaapi: Demote vaapidecodebin to rank NONE." + This reverts commit 7a25c5d4ec95aefeca6515ac023b23c5dd330194. + Part-of: + +2021-06-23 16:23:00 +0800 He Junyan + + * gst/vaapi/gstvaapiencode.c: + plugins: encode: fix a deadlock because of _drain() + We call gst_vaapiencode_drain() in gst_vaapiencode_change_state(), + whose context does not hold the stream lock of the encoder. The + current gst_vaapiencode_drain inside unlock/lock pair adds a extra + lock count to the stream lock of encoder and causes hang later. + We just remove the gst_vaapiencode_drain() and expand its logic + correctly according to the lock/unlock context. + Part-of: + +2021-06-29 15:09:13 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_av1.c: + libs: decoder: av1: Clean the film_grain_info field. + We need to clean all film_grain_info fields when the film grain + feature is not enabled. It may have random data because the picture + parameter buffer is not cleaned. + Part-of: + +2021-06-03 22:12:04 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2.c: + * gst-libs/gst/vaapi/gstvaapiutils_mpeg2.h: + libs: encoder: mpeg2: Add highP level for 1080@50p/60p. + The MPEG2 spec has amendment 3 to introduce a new level highP, which + is used for 1080@50p/60p streams. We need to add this level to avoid + encoding failure because of the level check. + Fix: #306 + Part-of: + +2021-05-11 16:59:07 +0800 He Junyan + + * gst-libs/gst/vaapi/gstvaapidecoder_h264.c: + Decoder: H264: Add the support for frame packing arrangement SEI message. + Frame packing arrangement SEI message is an alternative simple stereo 3D + manner for AVC. We need to recognize that SEI message and report the correct + 3D caps. + Part-of: + +2021-05-22 18:54:49 +0100 Tim-Philipp Müller + + * gst-libs/gst/vaapi/gstvaapifilter.c: + * meson.build: + Use g_memdup2() where available and add fallback for older GLib versions + Alloc size is based on existing allocations and struct sizes. + g_memdup() is deprecated since GLib 2.68 and we want to avoid + deprecation warnings with recent versions of GLib. + Part-of: + +2021-06-01 15:29:16 +0100 Tim-Philipp Müller + + * meson.build: + Back to development + === release 1.19.1 === 2021-06-01 00:16:31 +0100 Tim-Philipp Müller diff --git a/NEWS b/NEWS index cc6c3b4a8e..0e581c39b8 100644 --- a/NEWS +++ b/NEWS @@ -1,15 +1,15 @@ GStreamer 1.20 Release Notes GStreamer 1.20 has not been released yet. It is scheduled for release -around July 2021. +around October/November 2021. 1.19.x is the unstable development version that is being developed in -the git master branch and which will eventually result in 1.20, and -1.19.1 is the current development release in that series +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 around June/July 2021, -followed by several 1.19 pre-releases and the new 1.20 stable release -around July 2021. +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. @@ -17,7 +17,7 @@ around July 2021. See https://gstreamer.freedesktop.org/releases/1.20/ for the latest version of this document. -Last updated: Sunday 30 May 2021, 16:00 UTC (log) +Last updated: Wednesday 22 September 2021, 18:00 UTC (log) Introduction @@ -247,6 +247,10 @@ Documentation improvements 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 @@ -274,16 +278,15 @@ the git 1.20 branch, which will be a stable branch. 1.20.0 -1.20.0 is scheduled to be released around July 2021. +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 master branch. +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, but it -is hoped that feature freeze will take place some time in December 2021. +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. diff --git a/RELEASE b/RELEASE index ab30ecdf37..89a24e6fa7 100644 --- a/RELEASE +++ b/RELEASE @@ -1,4 +1,4 @@ -This is GStreamer gstreamer-vaapi 1.19.1. +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. diff --git a/gstreamer-vaapi.doap b/gstreamer-vaapi.doap index 1f2c4c191e..8f8deb02ba 100644 --- a/gstreamer-vaapi.doap +++ b/gstreamer-vaapi.doap @@ -25,6 +25,16 @@ + + + 1.19.2 + master + + 2021-09-23 + + + + 1.19.1 diff --git a/meson.build b/meson.build index 85ca246954..d069f4089c 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gstreamer-vaapi', 'c', - version : '1.19.1.1', + version : '1.19.2', meson_version : '>= 0.54', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ])